From 1c95310a66a7ffc832062a5cae4fa4cafc94d1d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 5 Jan 2024 19:55:32 +0100 Subject: [PATCH 001/392] `fungible::Unbalanced::decrease_balance`: Handle `precision` properly (#2823) --- prdoc/pr_2823.prdoc | 11 ++++++++ .../balances/src/tests/fungible_tests.rs | 27 ++++++++++++++++++- .../src/traits/tokens/fungible/regular.rs | 11 ++++++-- 3 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 prdoc/pr_2823.prdoc diff --git a/prdoc/pr_2823.prdoc b/prdoc/pr_2823.prdoc new file mode 100644 index 00000000000..64a309969ef --- /dev/null +++ b/prdoc/pr_2823.prdoc @@ -0,0 +1,11 @@ +title: "`fungible::Unbalanced::decrease_balance`: Handle `precision` properly" + +doc: + - audience: Runtime Dev + description: | + `fungible::Unbalanced::decrease_balance` will now handle `precision` properly. This means when + passing `Exact`, it will ensure that the available balance is bigger or equal to the `amount` + that should be deducted. + +crates: + - name: "frame-support" diff --git a/substrate/frame/balances/src/tests/fungible_tests.rs b/substrate/frame/balances/src/tests/fungible_tests.rs index 8bf0509d8f7..52fbe10bede 100644 --- a/substrate/frame/balances/src/tests/fungible_tests.rs +++ b/substrate/frame/balances/src/tests/fungible_tests.rs @@ -146,7 +146,7 @@ fn unbalanced_trait_decrease_balance_works_2() { assert_eq!(Balances::total_balance_on_hold(&1337), 60); assert_noop!( Balances::decrease_balance(&1337, 40, Exact, Expendable, Polite), - Error::::InsufficientBalance + TokenError::FundsUnavailable ); assert_eq!(Balances::decrease_balance(&1337, 39, Exact, Expendable, Polite), Ok(39)); assert_eq!(>::balance(&1337), 1); @@ -468,3 +468,28 @@ fn emit_events_with_changing_freezes() { assert_eq!(events(), [RuntimeEvent::Balances(crate::Event::Thawed { who: 1, amount: 15 })]); }); } + +#[test] +fn withdraw_precision_exact_works() { + ExtBuilder::default() + .existential_deposit(1) + .monied(true) + .build_and_execute_with(|| { + assert_ok!(Balances::set_freeze(&TestId::Foo, &1, 10)); + assert_eq!(Balances::account(&1).free, 10); + assert_eq!(Balances::account(&1).frozen, 10); + + // `BestEffort` will not reduce anything + assert_ok!(>::withdraw( + &1, 5, BestEffort, Preserve, Polite + )); + + assert_eq!(Balances::account(&1).free, 10); + assert_eq!(Balances::account(&1).frozen, 10); + + assert_noop!( + >::withdraw(&1, 5, Exact, Preserve, Polite), + TokenError::FundsUnavailable + ); + }); +} diff --git a/substrate/frame/support/src/traits/tokens/fungible/regular.rs b/substrate/frame/support/src/traits/tokens/fungible/regular.rs index aece73777d2..87c6ef68d77 100644 --- a/substrate/frame/support/src/traits/tokens/fungible/regular.rs +++ b/substrate/frame/support/src/traits/tokens/fungible/regular.rs @@ -181,9 +181,16 @@ pub trait Unbalanced: Inspect { ) -> Result { let old_balance = Self::balance(who); let free = Self::reducible_balance(who, preservation, force); - if let BestEffort = precision { - amount = amount.min(free); + match precision { + BestEffort => { + amount = amount.min(free); + }, + Exact => + if free < amount { + return Err(TokenError::FundsUnavailable.into()) + }, } + let new_balance = old_balance.checked_sub(&amount).ok_or(TokenError::FundsUnavailable)?; if let Some(dust) = Self::write_balance(who, new_balance)? { Self::handle_dust(Dust(dust)); -- GitLab From cea7024de18fcc9e8e56ea19f704f1309724f015 Mon Sep 17 00:00:00 2001 From: Tsvetomir Dimitrov Date: Fri, 5 Jan 2024 21:31:56 +0200 Subject: [PATCH 002/392] Fix clippy warnings (#2861) Fix some issues reported by clippy --- .../parachain/pallets/outbound-queue/src/test.rs | 4 ++-- bridges/snowbridge/parachain/pallets/system/src/lib.rs | 2 -- .../snowbridge/parachain/runtime/tests/src/test_cases.rs | 8 ++++---- .../tests/people/people-rococo/src/tests/reap_identity.rs | 2 +- .../people/people-westend/src/tests/reap_identity.rs | 2 +- .../runtimes/coretime/coretime-rococo/src/weights/mod.rs | 1 - .../runtimes/coretime/coretime-westend/src/weights/mod.rs | 1 - .../runtimes/people/people-rococo/src/weights/mod.rs | 1 - .../runtimes/people/people-westend/src/weights/mod.rs | 1 - polkadot/node/subsystem-bench/src/core/keyring.rs | 1 - polkadot/node/subsystem-bench/src/core/mock/mod.rs | 1 - 11 files changed, 8 insertions(+), 16 deletions(-) diff --git a/bridges/snowbridge/parachain/pallets/outbound-queue/src/test.rs b/bridges/snowbridge/parachain/pallets/outbound-queue/src/test.rs index 0028d75e7b7..454a91d5df5 100644 --- a/bridges/snowbridge/parachain/pallets/outbound-queue/src/test.rs +++ b/bridges/snowbridge/parachain/pallets/outbound-queue/src/test.rs @@ -110,7 +110,7 @@ fn process_message_fails_on_max_nonce_reached() { channel_id, command: mock_message(sibling_id).command, }; - let versioned_queued_message: VersionedQueuedMessage = message.try_into().unwrap(); + let versioned_queued_message: VersionedQueuedMessage = message.into(); let encoded = versioned_queued_message.encode(); let mut meter = WeightMeter::with_limit(Weight::MAX); @@ -134,7 +134,7 @@ fn process_message_fails_on_overweight_message() { channel_id, command: mock_message(sibling_id).command, }; - let versioned_queued_message: VersionedQueuedMessage = message.try_into().unwrap(); + let versioned_queued_message: VersionedQueuedMessage = message.into(); let encoded = versioned_queued_message.encode(); let mut meter = WeightMeter::with_limit(Weight::from_parts(1, 1)); assert_noop!( diff --git a/bridges/snowbridge/parachain/pallets/system/src/lib.rs b/bridges/snowbridge/parachain/pallets/system/src/lib.rs index 0042093ee66..e5077abd921 100644 --- a/bridges/snowbridge/parachain/pallets/system/src/lib.rs +++ b/bridges/snowbridge/parachain/pallets/system/src/lib.rs @@ -79,8 +79,6 @@ use xcm_executor::traits::ConvertLocation; #[cfg(feature = "runtime-benchmarks")] use frame_support::traits::OriginTrait; -pub use pallet::*; - pub type BalanceOf = <::Token as Inspect<::AccountId>>::Balance; pub type AccountIdOf = ::AccountId; diff --git a/bridges/snowbridge/parachain/runtime/tests/src/test_cases.rs b/bridges/snowbridge/parachain/runtime/tests/src/test_cases.rs index 19e45f7a15a..e5a45cdc92b 100644 --- a/bridges/snowbridge/parachain/runtime/tests/src/test_cases.rs +++ b/bridges/snowbridge/parachain/runtime/tests/src/test_cases.rs @@ -12,11 +12,11 @@ use parachains_runtimes_test_utils::{ }; use sp_core::H160; use sp_runtime::SaturatedConversion; -use xcm::latest::prelude::*; +use xcm::{ + latest::prelude::*, + v3::Error::{self, Barrier}, +}; use xcm_executor::XcmExecutor; -// Re-export test_case from `parachains-runtimes-test-utils` -pub use parachains_runtimes_test_utils::test_cases::change_storage_constant_by_governance_works; -use xcm::v3::Error::{self, Barrier}; type RuntimeHelper = parachains_runtimes_test_utils::RuntimeHelper; diff --git a/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/reap_identity.rs b/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/reap_identity.rs index 31144588ef4..81bd7620e46 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/reap_identity.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/reap_identity.rs @@ -88,7 +88,7 @@ impl Identity { }; let (github, discord) = additional .as_ref() - .and_then(|vec| vec.get(0)) + .and_then(|vec| vec.first()) .map(|(g, d)| (g.clone(), d.clone())) .unwrap_or((Data::None, Data::None)); Self { diff --git a/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/reap_identity.rs b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/reap_identity.rs index c704af281b3..6de2562b278 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/reap_identity.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/reap_identity.rs @@ -88,7 +88,7 @@ impl Identity { }; let (github, discord) = additional .as_ref() - .and_then(|vec| vec.get(0)) + .and_then(|vec| vec.first()) .map(|(g, d)| (g.clone(), d.clone())) .unwrap_or((Data::None, Data::None)); Self { diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/mod.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/mod.rs index 7b17d84ac34..f1050b3ae63 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/mod.rs @@ -37,5 +37,4 @@ pub mod xcm; pub use block_weights::constants::BlockExecutionWeight; pub use extrinsic_weights::constants::ExtrinsicBaseWeight; -pub use paritydb_weights::constants::ParityDbWeight; pub use rocksdb_weights::constants::RocksDbWeight; diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/mod.rs index 6bc733844e6..28e708f0e2a 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/mod.rs @@ -36,5 +36,4 @@ pub mod xcm; pub use block_weights::constants::BlockExecutionWeight; pub use extrinsic_weights::constants::ExtrinsicBaseWeight; -pub use paritydb_weights::constants::ParityDbWeight; pub use rocksdb_weights::constants::RocksDbWeight; diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/mod.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/mod.rs index 67e203cfaf5..3396a8caea0 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/mod.rs @@ -36,5 +36,4 @@ pub mod xcm; pub use block_weights::constants::BlockExecutionWeight; pub use extrinsic_weights::constants::ExtrinsicBaseWeight; -pub use paritydb_weights::constants::ParityDbWeight; pub use rocksdb_weights::constants::RocksDbWeight; diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/mod.rs index 67e203cfaf5..3396a8caea0 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/mod.rs @@ -36,5 +36,4 @@ pub mod xcm; pub use block_weights::constants::BlockExecutionWeight; pub use extrinsic_weights::constants::ExtrinsicBaseWeight; -pub use paritydb_weights::constants::ParityDbWeight; pub use rocksdb_weights::constants::RocksDbWeight; diff --git a/polkadot/node/subsystem-bench/src/core/keyring.rs b/polkadot/node/subsystem-bench/src/core/keyring.rs index 2d9aa348a92..68e78069a91 100644 --- a/polkadot/node/subsystem-bench/src/core/keyring.rs +++ b/polkadot/node/subsystem-bench/src/core/keyring.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -pub use sp_core::sr25519; use sp_core::{ sr25519::{Pair, Public}, Pair as PairT, diff --git a/polkadot/node/subsystem-bench/src/core/mock/mod.rs b/polkadot/node/subsystem-bench/src/core/mock/mod.rs index d59642e9605..76fd581c3fb 100644 --- a/polkadot/node/subsystem-bench/src/core/mock/mod.rs +++ b/polkadot/node/subsystem-bench/src/core/mock/mod.rs @@ -23,7 +23,6 @@ pub mod network_bridge; pub mod runtime_api; pub use av_store::*; -pub use network_bridge::*; pub use runtime_api::*; pub struct AlwaysSupportsParachains {} -- GitLab From 930c1519281ac7ec54dba2224f5cdea1d3959b5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 5 Jan 2024 21:43:26 +0100 Subject: [PATCH 003/392] `cumulus-primitives-parachain-inherent`: Split into two crates (#2803) This splits `cumulus-primitives-parachain-inherent` into two crates, the previous `cumulus-primitives-parachain-inherent` and a new `cumulus-client-parachain-inherent`. The idea behind this is to move the `create_at` logic into the client crate. This removes quite a lot of unrelated dependencies from the runtime std build and thus, makes the compilation faster. On my Laptop the compilation is goes down by one minute for `asset-hub-rococo-runtime`. I also assume that the full build of the entire workspace probably can be speed-up a little bit, because more stuff can be compiled in parallel. --------- Co-authored-by: command-bot <> --- Cargo.lock | 35 +++++++++++++----- Cargo.toml | 1 + cumulus/client/consensus/aura/Cargo.toml | 2 +- cumulus/client/consensus/aura/src/collator.rs | 4 +- cumulus/client/parachain-inherent/Cargo.toml | 30 +++++++++++++++ .../parachain-inherent/src/lib.rs} | 28 ++++---------- .../parachain-inherent/src/mock.rs | 5 ++- cumulus/polkadot-parachain/Cargo.toml | 2 +- cumulus/polkadot-parachain/src/service.rs | 2 +- .../primitives/parachain-inherent/Cargo.toml | 14 ------- .../primitives/parachain-inherent/src/lib.rs | 37 ++++++++++++++----- cumulus/test/service/Cargo.toml | 2 +- cumulus/test/service/src/bench_utils.rs | 2 +- cumulus/test/service/src/lib.rs | 2 +- prdoc/pr_2803.prdoc | 19 ++++++++++ 15 files changed, 122 insertions(+), 63 deletions(-) create mode 100644 cumulus/client/parachain-inherent/Cargo.toml rename cumulus/{primitives/parachain-inherent/src/client_side.rs => client/parachain-inherent/src/lib.rs} (91%) rename cumulus/{primitives => client}/parachain-inherent/src/mock.rs (97%) create mode 100644 prdoc/pr_2803.prdoc diff --git a/Cargo.lock b/Cargo.lock index 466fa26d434..bc80c77ae60 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3626,9 +3626,9 @@ dependencies = [ "cumulus-client-collator", "cumulus-client-consensus-common", "cumulus-client-consensus-proposer", + "cumulus-client-parachain-inherent", "cumulus-primitives-aura", "cumulus-primitives-core", - "cumulus-primitives-parachain-inherent", "cumulus-relay-chain-interface", "futures", "parity-scale-codec", @@ -3760,6 +3760,29 @@ dependencies = [ "url", ] +[[package]] +name = "cumulus-client-parachain-inherent" +version = "0.1.0" +dependencies = [ + "async-trait", + "cumulus-primitives-core", + "cumulus-primitives-parachain-inherent", + "cumulus-relay-chain-interface", + "cumulus-test-relay-sproof-builder", + "parity-scale-codec", + "sc-client-api", + "scale-info", + "sp-api", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-state-machine", + "sp-std 8.0.0", + "sp-storage 13.0.0", + "sp-trie", + "tracing", +] + [[package]] name = "cumulus-client-pov-recovery" version = "0.1.0" @@ -4033,20 +4056,14 @@ version = "0.1.0" dependencies = [ "async-trait", "cumulus-primitives-core", - "cumulus-relay-chain-interface", - "cumulus-test-relay-sproof-builder", "parity-scale-codec", - "sc-client-api", "scale-info", - "sp-api", "sp-core", "sp-inherents", "sp-runtime", "sp-state-machine", "sp-std 8.0.0", - "sp-storage 13.0.0", "sp-trie", - "tracing", ] [[package]] @@ -4303,11 +4320,11 @@ dependencies = [ "cumulus-client-cli", "cumulus-client-consensus-common", "cumulus-client-consensus-relay-chain", + "cumulus-client-parachain-inherent", "cumulus-client-pov-recovery", "cumulus-client-service", "cumulus-pallet-parachain-system", "cumulus-primitives-core", - "cumulus-primitives-parachain-inherent", "cumulus-relay-chain-inprocess-interface", "cumulus-relay-chain-interface", "cumulus-relay-chain-minimal-node", @@ -13033,10 +13050,10 @@ dependencies = [ "cumulus-client-consensus-common", "cumulus-client-consensus-proposer", "cumulus-client-consensus-relay-chain", + "cumulus-client-parachain-inherent", "cumulus-client-service", "cumulus-primitives-aura", "cumulus-primitives-core", - "cumulus-primitives-parachain-inherent", "cumulus-relay-chain-interface", "frame-benchmarking", "frame-benchmarking-cli", diff --git a/Cargo.toml b/Cargo.toml index a1983a5efd5..231aab8dee9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,6 +57,7 @@ members = [ "cumulus/client/consensus/proposer", "cumulus/client/consensus/relay-chain", "cumulus/client/network", + "cumulus/client/parachain-inherent", "cumulus/client/pov-recovery", "cumulus/client/relay-chain-inprocess-interface", "cumulus/client/relay-chain-interface", diff --git a/cumulus/client/consensus/aura/Cargo.toml b/cumulus/client/consensus/aura/Cargo.toml index 4c20911c645..d022fe4df7e 100644 --- a/cumulus/client/consensus/aura/Cargo.toml +++ b/cumulus/client/consensus/aura/Cargo.toml @@ -41,9 +41,9 @@ substrate-prometheus-endpoint = { path = "../../../../substrate/utils/prometheus cumulus-client-consensus-common = { path = "../common" } cumulus-relay-chain-interface = { path = "../../relay-chain-interface" } cumulus-client-consensus-proposer = { path = "../proposer" } +cumulus-client-parachain-inherent = { path = "../../../client/parachain-inherent" } cumulus-primitives-aura = { path = "../../../primitives/aura" } cumulus-primitives-core = { path = "../../../primitives/core" } -cumulus-primitives-parachain-inherent = { path = "../../../primitives/parachain-inherent" } cumulus-client-collator = { path = "../../collator" } # Polkadot diff --git a/cumulus/client/consensus/aura/src/collator.rs b/cumulus/client/consensus/aura/src/collator.rs index 83f82aff96b..db0799235bc 100644 --- a/cumulus/client/consensus/aura/src/collator.rs +++ b/cumulus/client/consensus/aura/src/collator.rs @@ -30,10 +30,10 @@ use cumulus_client_consensus_common::{ self as consensus_common, ParachainBlockImportMarker, ParachainCandidate, }; use cumulus_client_consensus_proposer::ProposerInterface; +use cumulus_client_parachain_inherent::{ParachainInherentData, ParachainInherentDataProvider}; use cumulus_primitives_core::{ relay_chain::Hash as PHash, DigestItem, ParachainBlockData, PersistedValidationData, }; -use cumulus_primitives_parachain_inherent::ParachainInherentData; use cumulus_relay_chain_interface::RelayChainInterface; use polkadot_node_primitives::{Collation, MaybeCompressedPoV}; @@ -124,7 +124,7 @@ where parent_hash: Block::Hash, timestamp: impl Into>, ) -> Result<(ParachainInherentData, InherentData), Box> { - let paras_inherent_data = ParachainInherentData::create_at( + let paras_inherent_data = ParachainInherentDataProvider::create_at( relay_parent, &self.relay_client, validation_data, diff --git a/cumulus/client/parachain-inherent/Cargo.toml b/cumulus/client/parachain-inherent/Cargo.toml new file mode 100644 index 00000000000..b6d477519ec --- /dev/null +++ b/cumulus/client/parachain-inherent/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "cumulus-client-parachain-inherent" +version = "0.1.0" +authors.workspace = true +edition.workspace = true +description = "Inherent that needs to be present in every parachain block. Contains messages and a relay chain storage-proof." +license = "Apache-2.0" + +[dependencies] +async-trait = "0.1.73" +codec = { package = "parity-scale-codec", version = "3.0.0", features = ["derive"] } +scale-info = { version = "2.10.0", features = ["derive"] } +tracing = { version = "0.1.37" } + +# Substrate +sc-client-api = { path = "../../../substrate/client/api" } +sp-api = { path = "../../../substrate/primitives/api" } +sp-core = { path = "../../../substrate/primitives/core" } +sp-inherents = { path = "../../../substrate/primitives/inherents" } +sp-runtime = { path = "../../../substrate/primitives/runtime" } +sp-state-machine = { path = "../../../substrate/primitives/state-machine" } +sp-std = { path = "../../../substrate/primitives/std" } +sp-storage = { path = "../../../substrate/primitives/storage" } +sp-trie = { path = "../../../substrate/primitives/trie" } + +# Cumulus +cumulus-primitives-core = { path = "../../primitives/core" } +cumulus-primitives-parachain-inherent = { path = "../../primitives/parachain-inherent" } +cumulus-relay-chain-interface = { path = "../relay-chain-interface" } +cumulus-test-relay-sproof-builder = { path = "../../test/relay-sproof-builder" } diff --git a/cumulus/primitives/parachain-inherent/src/client_side.rs b/cumulus/client/parachain-inherent/src/lib.rs similarity index 91% rename from cumulus/primitives/parachain-inherent/src/client_side.rs rename to cumulus/client/parachain-inherent/src/lib.rs index 52987d2da44..57353638e19 100644 --- a/cumulus/primitives/parachain-inherent/src/client_side.rs +++ b/cumulus/client/parachain-inherent/src/lib.rs @@ -16,7 +16,6 @@ //! Client side code for generating the parachain inherent. -use crate::ParachainInherentData; use codec::Decode; use cumulus_primitives_core::{ relay_chain::{self, Hash as PHash, HrmpChannelId}, @@ -24,6 +23,11 @@ use cumulus_primitives_core::{ }; use cumulus_relay_chain_interface::RelayChainInterface; +mod mock; + +pub use cumulus_primitives_parachain_inherent::{ParachainInherentData, INHERENT_IDENTIFIER}; +pub use mock::{MockValidationDataInherentDataProvider, MockXcmConfig}; + const LOG_TARGET: &str = "parachain-inherent"; /// Collect the relevant relay chain state in form of a proof for putting it into the validation @@ -132,7 +136,9 @@ async fn collect_relay_storage_proof( .ok() } -impl ParachainInherentData { +pub struct ParachainInherentDataProvider; + +impl ParachainInherentDataProvider { /// Create the [`ParachainInherentData`] at the given `relay_parent`. /// /// Returns `None` if the creation failed. @@ -178,21 +184,3 @@ impl ParachainInherentData { }) } } - -#[async_trait::async_trait] -impl sp_inherents::InherentDataProvider for ParachainInherentData { - async fn provide_inherent_data( - &self, - inherent_data: &mut sp_inherents::InherentData, - ) -> Result<(), sp_inherents::Error> { - inherent_data.put_data(crate::INHERENT_IDENTIFIER, &self) - } - - async fn try_handle_error( - &self, - _: &sp_inherents::InherentIdentifier, - _: &[u8], - ) -> Option> { - None - } -} diff --git a/cumulus/primitives/parachain-inherent/src/mock.rs b/cumulus/client/parachain-inherent/src/mock.rs similarity index 97% rename from cumulus/primitives/parachain-inherent/src/mock.rs rename to cumulus/client/parachain-inherent/src/mock.rs index e40cb49acdd..7af10a661e0 100644 --- a/cumulus/primitives/parachain-inherent/src/mock.rs +++ b/cumulus/client/parachain-inherent/src/mock.rs @@ -19,6 +19,7 @@ use codec::Decode; use cumulus_primitives_core::{ relay_chain, InboundDownwardMessage, InboundHrmpMessage, ParaId, PersistedValidationData, }; +use cumulus_primitives_parachain_inherent::MessageQueueChain; use sc_client_api::{Backend, StorageProvider}; use sp_core::twox_128; use sp_inherents::{InherentData, InherentDataProvider}; @@ -168,7 +169,7 @@ impl> InherentDataProvider // Process the downward messages and set up the correct head let mut downward_messages = Vec::new(); - let mut dmq_mqc = crate::MessageQueueChain(self.xcm_config.starting_dmq_mqc_head); + let mut dmq_mqc = MessageQueueChain::new(self.xcm_config.starting_dmq_mqc_head); for msg in &self.raw_downward_messages { let wrapped = InboundDownwardMessage { sent_at: relay_parent_number, msg: msg.clone() }; @@ -188,7 +189,7 @@ impl> InherentDataProvider // Now iterate again, updating the heads as we go for (para_id, messages) in &horizontal_messages { - let mut channel_mqc = crate::MessageQueueChain( + let mut channel_mqc = MessageQueueChain::new( *self .xcm_config .starting_hrmp_mqc_heads diff --git a/cumulus/polkadot-parachain/Cargo.toml b/cumulus/polkadot-parachain/Cargo.toml index 34243f473e8..02d53486710 100644 --- a/cumulus/polkadot-parachain/Cargo.toml +++ b/cumulus/polkadot-parachain/Cargo.toml @@ -102,10 +102,10 @@ cumulus-client-consensus-aura = { path = "../client/consensus/aura" } cumulus-client-consensus-relay-chain = { path = "../client/consensus/relay-chain" } cumulus-client-consensus-common = { path = "../client/consensus/common" } cumulus-client-consensus-proposer = { path = "../client/consensus/proposer" } +cumulus-client-parachain-inherent = { path = "../client/parachain-inherent" } cumulus-client-service = { path = "../client/service" } cumulus-primitives-aura = { path = "../primitives/aura" } cumulus-primitives-core = { path = "../primitives/core" } -cumulus-primitives-parachain-inherent = { path = "../primitives/parachain-inherent" } cumulus-relay-chain-interface = { path = "../client/relay-chain-interface" } color-print = "0.3.4" diff --git a/cumulus/polkadot-parachain/src/service.rs b/cumulus/polkadot-parachain/src/service.rs index d5c12017859..81d0c9d3980 100644 --- a/cumulus/polkadot-parachain/src/service.rs +++ b/cumulus/polkadot-parachain/src/service.rs @@ -1085,7 +1085,7 @@ where let relay_chain_interface = relay_chain_interface.clone(); async move { let parachain_inherent = - cumulus_primitives_parachain_inherent::ParachainInherentData::create_at( + cumulus_client_parachain_inherent::ParachainInherentDataProvider::create_at( relay_parent, &relay_chain_interface, &validation_data, diff --git a/cumulus/primitives/parachain-inherent/Cargo.toml b/cumulus/primitives/parachain-inherent/Cargo.toml index f914af11751..42a425ea176 100644 --- a/cumulus/primitives/parachain-inherent/Cargo.toml +++ b/cumulus/primitives/parachain-inherent/Cargo.toml @@ -13,23 +13,17 @@ workspace = true async-trait = { version = "0.1.74", optional = true } codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -tracing = { version = "0.1.37", optional = true } # Substrate -sc-client-api = { path = "../../../substrate/client/api", optional = true } -sp-api = { path = "../../../substrate/primitives/api", optional = true } sp-core = { path = "../../../substrate/primitives/core", default-features = false } sp-inherents = { path = "../../../substrate/primitives/inherents", default-features = false } sp-runtime = { path = "../../../substrate/primitives/runtime", optional = true } sp-state-machine = { path = "../../../substrate/primitives/state-machine", optional = true } sp-std = { path = "../../../substrate/primitives/std", default-features = false } -sp-storage = { path = "../../../substrate/primitives/storage", optional = true } sp-trie = { path = "../../../substrate/primitives/trie", default-features = false } # Cumulus cumulus-primitives-core = { path = "../core", default-features = false } -cumulus-relay-chain-interface = { path = "../../client/relay-chain-interface", optional = true } -cumulus-test-relay-sproof-builder = { path = "../../test/relay-sproof-builder", optional = true } [features] default = ["std"] @@ -37,17 +31,9 @@ std = [ "async-trait", "codec/std", "cumulus-primitives-core/std", - "cumulus-relay-chain-interface", - "cumulus-test-relay-sproof-builder", - "sc-client-api", "scale-info/std", - "sp-api", "sp-core/std", "sp-inherents/std", - "sp-runtime", - "sp-state-machine", "sp-std/std", - "sp-storage", "sp-trie/std", - "tracing", ] diff --git a/cumulus/primitives/parachain-inherent/src/lib.rs b/cumulus/primitives/parachain-inherent/src/lib.rs index f98c748e82f..75a56693958 100644 --- a/cumulus/primitives/parachain-inherent/src/lib.rs +++ b/cumulus/primitives/parachain-inherent/src/lib.rs @@ -19,11 +19,11 @@ //! The [`ParachainInherentData`] is the data that is passed by the collator to the parachain //! runtime. The runtime will use this data to execute messages from other parachains/the relay //! chain or to read data from the relay chain state. When the parachain is validated by a parachain -//! validator on the relay chain, this data is checked for correctnes. If the data passed by the +//! validator on the relay chain, this data is checked for correctness. If the data passed by the //! collator to the runtime isn't correct, the parachain candidate is considered invalid. //! -//! Use [`ParachainInherentData::create_at`] to create the [`ParachainInherentData`] at a given -//! relay chain block to include it in a parachain block. +//! To create a [`ParachainInherentData`] for a specific relay chain block, there exists the +//! `ParachainInherentDataExt` trait in `cumulus-client-parachain-inherent` that helps with this. #![cfg_attr(not(feature = "std"), no_std)] @@ -36,13 +36,6 @@ use scale_info::TypeInfo; use sp_inherents::InherentIdentifier; use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; -#[cfg(feature = "std")] -mod client_side; -#[cfg(feature = "std")] -mod mock; -#[cfg(feature = "std")] -pub use mock::{MockValidationDataInherentDataProvider, MockXcmConfig}; - /// The identifier for the parachain inherent. pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"sysi1337"; @@ -68,6 +61,25 @@ pub struct ParachainInherentData { pub horizontal_messages: BTreeMap>, } +#[cfg(feature = "std")] +#[async_trait::async_trait] +impl sp_inherents::InherentDataProvider for ParachainInherentData { + async fn provide_inherent_data( + &self, + inherent_data: &mut sp_inherents::InherentData, + ) -> Result<(), sp_inherents::Error> { + inherent_data.put_data(INHERENT_IDENTIFIER, &self) + } + + async fn try_handle_error( + &self, + _: &sp_inherents::InherentIdentifier, + _: &[u8], + ) -> Option> { + None + } +} + /// This struct provides ability to extend a message queue chain (MQC) and compute a new head. /// /// MQC is an instance of a [hash chain] applied to a message queue. Using a hash chain it's @@ -84,6 +96,11 @@ pub struct ParachainInherentData { pub struct MessageQueueChain(RelayHash); impl MessageQueueChain { + /// Create a new instance initialized to `hash`. + pub fn new(hash: RelayHash) -> Self { + Self(hash) + } + /// Extend the hash chain with an HRMP message. This method should be used only when /// this chain is tracking HRMP. pub fn extend_hrmp(&mut self, horizontal_message: &InboundHrmpMessage) -> &mut Self { diff --git a/cumulus/test/service/Cargo.toml b/cumulus/test/service/Cargo.toml index 03040e7a2b6..09403ef1853 100644 --- a/cumulus/test/service/Cargo.toml +++ b/cumulus/test/service/Cargo.toml @@ -71,9 +71,9 @@ cumulus-client-cli = { path = "../../client/cli" } parachains-common = { path = "../../parachains/common" } cumulus-client-consensus-common = { path = "../../client/consensus/common" } cumulus-client-consensus-relay-chain = { path = "../../client/consensus/relay-chain" } +cumulus-client-parachain-inherent = { path = "../../client/parachain-inherent" } cumulus-client-service = { path = "../../client/service" } cumulus-primitives-core = { path = "../../primitives/core" } -cumulus-primitives-parachain-inherent = { path = "../../primitives/parachain-inherent" } cumulus-relay-chain-inprocess-interface = { path = "../../client/relay-chain-inprocess-interface" } cumulus-relay-chain-interface = { path = "../../client/relay-chain-interface" } cumulus-test-runtime = { path = "../runtime" } diff --git a/cumulus/test/service/src/bench_utils.rs b/cumulus/test/service/src/bench_utils.rs index 1894835caec..4ace894b392 100644 --- a/cumulus/test/service/src/bench_utils.rs +++ b/cumulus/test/service/src/bench_utils.rs @@ -19,8 +19,8 @@ use codec::Encode; use sc_block_builder::BlockBuilderBuilder; use crate::{construct_extrinsic, Client as TestClient}; +use cumulus_client_parachain_inherent::ParachainInherentData; use cumulus_primitives_core::{relay_chain::AccountId, PersistedValidationData}; -use cumulus_primitives_parachain_inherent::ParachainInherentData; use cumulus_test_relay_sproof_builder::RelayStateSproofBuilder; use cumulus_test_runtime::{ BalancesCall, GluttonCall, NodeBlock, SudoCall, UncheckedExtrinsic, WASM_BINARY, diff --git a/cumulus/test/service/src/lib.rs b/cumulus/test/service/src/lib.rs index eca65dd4ca0..1de3af1bc9d 100644 --- a/cumulus/test/service/src/lib.rs +++ b/cumulus/test/service/src/lib.rs @@ -447,7 +447,7 @@ where let relay_chain_interface = relay_chain_interface_for_closure.clone(); async move { let parachain_inherent = - cumulus_primitives_parachain_inherent::ParachainInherentData::create_at( + cumulus_client_parachain_inherent::ParachainInherentDataProvider::create_at( relay_parent, &relay_chain_interface, &validation_data, diff --git a/prdoc/pr_2803.prdoc b/prdoc/pr_2803.prdoc new file mode 100644 index 00000000000..1ddd3dd677a --- /dev/null +++ b/prdoc/pr_2803.prdoc @@ -0,0 +1,19 @@ +title: "cumulus-primitives-parachain-inherent: Split into two crates" + +doc: + - audience: Node Dev + description: | + This splits `cumulus-primitives-parachain-inherent` into two crates. The new crate is called + `cumulus-client-parachain-inherent`. This is done to improve the compile time for runtimes, + as they are not required anymore to pull in half of the node side at compile time. + + To migrate your code you need to change + `cumulus_primitives_parachain_inherent::ParachainInherentData::create_at` to + `cumulus_client_parachain_inherent::ParachainInherentDataProvider::create_at`. + Any other code should be compatible. The mocking code also moved to the new client crate and + you may need to adapt your imports accordingly. Generally, replacing the old crate with the new + crate fix most compile errors resulting from this pull request. + +crates: + - name: "cumulus-primitives-parachain-inherent" + - name: "cumulus-client-parachain-inherent" -- GitLab From 2e4b8996c4924fc39f85198019039cf0987f89ec Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Sat, 6 Jan 2024 12:18:38 +0100 Subject: [PATCH 004/392] Kitchensink chain: Add BEEFY support (#2856) Related to https://github.com/paritytech/polkadot-sdk/issues/2787 Adding BEEFY support to the kitchensink chain in order to be able to extend the current warp sync zombienet tests with BEEFY enabled --- Cargo.lock | 9 + polkadot/runtime/rococo/src/lib.rs | 13 -- polkadot/runtime/westend/src/lib.rs | 13 -- substrate/bin/node/cli/Cargo.toml | 4 + substrate/bin/node/cli/src/chain_spec.rs | 54 +++++- substrate/bin/node/cli/src/service.rs | 167 ++++++++++++++---- .../cli/tests/res/default_genesis_config.json | 4 + substrate/bin/node/rpc/Cargo.toml | 2 + substrate/bin/node/rpc/src/lib.rs | 28 ++- substrate/bin/node/runtime/Cargo.toml | 8 + substrate/bin/node/runtime/src/lib.rs | 76 +++++++- substrate/bin/node/testing/src/genesis.rs | 13 +- substrate/bin/node/testing/src/keyring.rs | 20 +-- .../primitives/consensus/beefy/src/mmr.rs | 2 +- 14 files changed, 320 insertions(+), 93 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bc80c77ae60..23a0bf8fd35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7048,6 +7048,8 @@ dependencies = [ "pallet-babe", "pallet-bags-list", "pallet-balances", + "pallet-beefy", + "pallet-beefy-mmr", "pallet-bounties", "pallet-broker", "pallet-child-bounties", @@ -7121,6 +7123,7 @@ dependencies = [ "sp-authority-discovery", "sp-block-builder", "sp-consensus-babe", + "sp-consensus-beefy", "sp-consensus-grandpa", "sp-core", "sp-genesis-builder", @@ -8619,6 +8622,8 @@ dependencies = [ "sc-client-api", "sc-consensus-babe", "sc-consensus-babe-rpc", + "sc-consensus-beefy", + "sc-consensus-beefy-rpc", "sc-consensus-grandpa", "sc-consensus-grandpa-rpc", "sc-mixnet", @@ -19091,6 +19096,7 @@ dependencies = [ "jsonrpsee", "kitchensink-runtime", "log", + "mmr-gadget", "nix 0.26.2", "node-primitives", "node-rpc", @@ -19121,6 +19127,7 @@ dependencies = [ "sc-client-db", "sc-consensus", "sc-consensus-babe", + "sc-consensus-beefy", "sc-consensus-epochs", "sc-consensus-grandpa", "sc-consensus-slots", @@ -19152,6 +19159,7 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-consensus-babe", + "sp-consensus-beefy", "sp-consensus-grandpa", "sp-core", "sp-externalities 0.19.0", @@ -19160,6 +19168,7 @@ dependencies = [ "sp-keyring", "sp-keystore", "sp-mixnet", + "sp-mmr-primitives", "sp-runtime", "sp-state-machine", "sp-statement-store", diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 4d0e537f6db..67caa347bc3 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -1237,19 +1237,6 @@ impl pallet_mmr::Config for Runtime { } parameter_types! { - /// Version of the produced MMR leaf. - /// - /// The version consists of two parts; - /// - `major` (3 bits) - /// - `minor` (5 bits) - /// - /// `major` should be updated only if decoding the previous MMR Leaf format from the payload - /// is not possible (i.e. backward incompatible change). - /// `minor` should be updated if fields are added to the previous MMR Leaf, which given SCALE - /// encoding does not prevent old leafs from being decoded. - /// - /// Hence we expect `major` to be changed really rarely (think never). - /// See [`MmrLeafVersion`] type documentation for more details. pub LeafVersion: MmrLeafVersion = MmrLeafVersion::new(0, 0); } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index fb54bec509b..e0b9fd0fb53 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -342,19 +342,6 @@ mod mmr { } parameter_types! { - /// Version of the produced MMR leaf. - /// - /// The version consists of two parts; - /// - `major` (3 bits) - /// - `minor` (5 bits) - /// - /// `major` should be updated only if decoding the previous MMR Leaf format from the payload - /// is not possible (i.e. backward incompatible change). - /// `minor` should be updated if fields are added to the previous MMR Leaf, which given SCALE - /// encoding does not prevent old leafs from being decoded. - /// - /// Hence we expect `major` to be changed really rarely (think never). - /// See [`MmrLeafVersion`] type documentation for more details. pub LeafVersion: MmrLeafVersion = MmrLeafVersion::new(0, 0); } diff --git a/substrate/bin/node/cli/Cargo.toml b/substrate/bin/node/cli/Cargo.toml index a01c35a3b63..35d632865ee 100644 --- a/substrate/bin/node/cli/Cargo.toml +++ b/substrate/bin/node/cli/Cargo.toml @@ -52,6 +52,7 @@ rand = "0.8" # primitives sp-authority-discovery = { path = "../../../primitives/authority-discovery" } sp-consensus-babe = { path = "../../../primitives/consensus/babe" } +beefy-primitives = { package = "sp-consensus-beefy", path = "../../../primitives/consensus/beefy" } grandpa-primitives = { package = "sp-consensus-grandpa", path = "../../../primitives/consensus/grandpa" } sp-api = { path = "../../../primitives/api" } sp-core = { path = "../../../primitives/core" } @@ -64,6 +65,7 @@ sp-consensus = { path = "../../../primitives/consensus/common" } sp-transaction-storage-proof = { path = "../../../primitives/transaction-storage-proof" } sp-io = { path = "../../../primitives/io" } sp-mixnet = { path = "../../../primitives/mixnet" } +sp-mmr-primitives = { path = "../../../primitives/merkle-mountain-range" } sp-statement-store = { path = "../../../primitives/statement-store" } # client dependencies @@ -79,7 +81,9 @@ sc-network-sync = { path = "../../../client/network/sync" } sc-network-statement = { path = "../../../client/network/statement" } sc-consensus-slots = { path = "../../../client/consensus/slots" } sc-consensus-babe = { path = "../../../client/consensus/babe" } +beefy = { package = "sc-consensus-beefy", path = "../../../client/consensus/beefy" } grandpa = { package = "sc-consensus-grandpa", path = "../../../client/consensus/grandpa" } +mmr-gadget = { path = "../../../client/merkle-mountain-range" } sc-rpc = { path = "../../../client/rpc" } sc-basic-authorship = { path = "../../../client/basic-authorship" } sc-service = { path = "../../../client/service", default-features = false } diff --git a/substrate/bin/node/cli/src/chain_spec.rs b/substrate/bin/node/cli/src/chain_spec.rs index 3559348d188..b6e8fb8a14e 100644 --- a/substrate/bin/node/cli/src/chain_spec.rs +++ b/substrate/bin/node/cli/src/chain_spec.rs @@ -18,6 +18,7 @@ //! Substrate chain configurations. +use beefy_primitives::ecdsa_crypto::AuthorityId as BeefyId; use grandpa_primitives::AuthorityId as GrandpaId; use kitchensink_runtime::{ constants::currency::*, wasm_binary_unwrap, Block, MaxNominations, SessionKeys, StakerStatus, @@ -73,23 +74,37 @@ fn session_keys( im_online: ImOnlineId, authority_discovery: AuthorityDiscoveryId, mixnet: MixnetId, + beefy: BeefyId, ) -> SessionKeys { - SessionKeys { grandpa, babe, im_online, authority_discovery, mixnet } + SessionKeys { grandpa, babe, im_online, authority_discovery, mixnet, beefy } } fn configure_accounts_for_staging_testnet() -> ( - Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId, AuthorityDiscoveryId, MixnetId)>, + Vec<( + AccountId, + AccountId, + GrandpaId, + BabeId, + ImOnlineId, + AuthorityDiscoveryId, + MixnetId, + BeefyId, + )>, AccountId, Vec, ) { #[rustfmt::skip] - // stash, controller, session-key + // stash, controller, session-key, beefy id // generated with secret: // for i in 1 2 3 4 ; do for j in stash controller; do subkey inspect "$secret"/fir/$j/$i; done; done // // and // - // for i in 1 2 3 4 ; do for j in session; do subkey --ed25519 inspect "$secret"//fir//$j//$i; done; done + // for i in 1 2 3 4 ; do for j in session; do subkey inspect --scheme ed25519 "$secret"//fir//$j//$i; done; done + // + // and + // + // for i in 1 2 3 4 ; do for j in session; do subkey inspect --scheme ecdsa "$secret"//fir//$j//$i; done; done let initial_authorities: Vec<( AccountId, @@ -99,6 +114,7 @@ fn configure_accounts_for_staging_testnet() -> ( ImOnlineId, AuthorityDiscoveryId, MixnetId, + BeefyId, )> = vec![ ( // 5Fbsd6WXDGiLTxunqeK5BATNiocfCqu9bS1yArVjCgeBLkVy @@ -120,6 +136,9 @@ fn configure_accounts_for_staging_testnet() -> ( // 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8 array_bytes::hex2array_unchecked("6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106") .unchecked_into(), + // 5DMLFcDdLLQbw696YfHaWBpQR99HwR456ycSCfr6L7KXGYK8 + array_bytes::hex2array_unchecked("035560fafa241739869360aa4b32bc98953172ceb41a19c6cc1a27962fb3d1ecec") + .unchecked_into(), ), ( // 5ERawXCzCWkjVq3xz1W5KGNtVx2VdefvZ62Bw1FEuZW4Vny2 @@ -141,6 +160,9 @@ fn configure_accounts_for_staging_testnet() -> ( // 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ array_bytes::hex2array_unchecked("482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e") .unchecked_into(), + // 5FYk11kNtB4178wLKJ2RNoUzzcjgRUciFe3SJDVZXhqX4dzG + array_bytes::hex2array_unchecked("02da1ab255ed888ee3e19b73d335fc13160b3eb10456c2d17c6a8ea7de403d2445") + .unchecked_into(), ), ( // 5DyVtKWPidondEu8iHZgi6Ffv9yrJJ1NDNLom3X9cTDi98qp @@ -162,6 +184,9 @@ fn configure_accounts_for_staging_testnet() -> ( // 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH array_bytes::hex2array_unchecked("482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a") .unchecked_into(), + // 5GQx4FToRBPqfani6o7owFJE1UstiviqbPP7HPWyvtXWWukn + array_bytes::hex2array_unchecked("036a818b3f59579c5fbbe4fede64f49dbf090ba883eb2a175d5ca90e5adb5f0b3e") + .unchecked_into(), ), ( // 5HYZnKWe5FVZQ33ZRJK1rG3WaLMztxWrrNDb1JRwaHHVWyP9 @@ -183,6 +208,9 @@ fn configure_accounts_for_staging_testnet() -> ( // 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x array_bytes::hex2array_unchecked("00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378") .unchecked_into(), + // 5FCu2pY928VVHPgnNVJssvxFJZECyNe1CyH3WTG79Wisx58B + array_bytes::hex2array_unchecked("020ce02b963548f9f8ade8765f7a4a06638c17819c78422a1cc35b647873583eef") + .unchecked_into(), ), ]; @@ -234,7 +262,8 @@ where /// Helper function to generate stash, controller and session key from seed. pub fn authority_keys_from_seed( seed: &str, -) -> (AccountId, AccountId, GrandpaId, BabeId, ImOnlineId, AuthorityDiscoveryId, MixnetId) { +) -> (AccountId, AccountId, GrandpaId, BabeId, ImOnlineId, AuthorityDiscoveryId, MixnetId, BeefyId) +{ ( get_account_id_from_seed::(&format!("{}//stash", seed)), get_account_id_from_seed::(seed), @@ -243,6 +272,7 @@ pub fn authority_keys_from_seed( get_from_seed::(seed), get_from_seed::(seed), get_from_seed::(seed), + get_from_seed::(seed), ) } @@ -255,12 +285,22 @@ fn configure_accounts( ImOnlineId, AuthorityDiscoveryId, MixnetId, + BeefyId, )>, initial_nominators: Vec, endowed_accounts: Option>, stash: Balance, ) -> ( - Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId, AuthorityDiscoveryId, MixnetId)>, + Vec<( + AccountId, + AccountId, + GrandpaId, + BabeId, + ImOnlineId, + AuthorityDiscoveryId, + MixnetId, + BeefyId, + )>, Vec, usize, Vec<(AccountId, AccountId, Balance, StakerStatus)>, @@ -326,6 +366,7 @@ pub fn testnet_genesis( ImOnlineId, AuthorityDiscoveryId, MixnetId, + BeefyId, )>, initial_nominators: Vec, root_key: AccountId, @@ -351,6 +392,7 @@ pub fn testnet_genesis( x.4.clone(), x.5.clone(), x.6.clone(), + x.7.clone(), ), ) }) diff --git a/substrate/bin/node/cli/src/service.rs b/substrate/bin/node/cli/src/service.rs index 4f8c6198cdc..5e6e794f732 100644 --- a/substrate/bin/node/cli/src/service.rs +++ b/substrate/bin/node/cli/src/service.rs @@ -63,6 +63,8 @@ type FullBackend = sc_service::TFullBackend; type FullSelectChain = sc_consensus::LongestChain; type FullGrandpaBlockImport = grandpa::GrandpaBlockImport; +type FullBeefyBlockImport = + beefy::import::BeefyBlockImport; /// The transaction pool type definition. pub type TransactionPool = sc_transaction_pool::FullPool; @@ -165,9 +167,14 @@ pub fn new_partial( sc_rpc::SubscriptionTaskExecutor, ) -> Result, sc_service::Error>, ( - sc_consensus_babe::BabeBlockImport, + sc_consensus_babe::BabeBlockImport< + Block, + FullClient, + FullBeefyBlockImport, + >, grandpa::LinkHalf, sc_consensus_babe::BabeLink, + beefy::BeefyVoterLinks, ), grandpa::SharedVoterState, Option, @@ -222,9 +229,17 @@ pub fn new_partial( )?; let justification_import = grandpa_block_import.clone(); + let (beefy_block_import, beefy_voter_links, beefy_rpc_links) = + beefy::beefy_block_import_and_links( + grandpa_block_import, + backend.clone(), + client.clone(), + config.prometheus_registry().cloned(), + ); + let (block_import, babe_link) = sc_consensus_babe::block_import( sc_consensus_babe::configuration(&*client)?, - grandpa_block_import, + beefy_block_import, client.clone(), )?; @@ -253,7 +268,7 @@ pub fn new_partial( offchain_tx_pool_factory: OffchainTransactionPoolFactory::new(transaction_pool.clone()), })?; - let import_setup = (block_import, grandpa_link, babe_link); + let import_setup = (block_import, grandpa_link, babe_link, beefy_voter_links); let statement_store = sc_statement_store::Store::new_shared( &config.data_path, @@ -268,7 +283,7 @@ pub fn new_partial( let (mixnet_api, mixnet_api_backend) = mixnet_config.map(sc_mixnet::Api::new).unzip(); let (rpc_extensions_builder, rpc_setup) = { - let (_, grandpa_link, _) = &import_setup; + let (_, grandpa_link, _, _) = &import_setup; let justification_stream = grandpa_link.justification_stream(); let shared_authority_set = grandpa_link.shared_authority_set().clone(); @@ -288,31 +303,41 @@ pub fn new_partial( let rpc_backend = backend.clone(); let rpc_statement_store = statement_store.clone(); - let rpc_extensions_builder = move |deny_unsafe, subscription_executor| { - let deps = node_rpc::FullDeps { - client: client.clone(), - pool: pool.clone(), - select_chain: select_chain.clone(), - chain_spec: chain_spec.cloned_box(), - deny_unsafe, - babe: node_rpc::BabeDeps { - keystore: keystore.clone(), - babe_worker_handle: babe_worker_handle.clone(), - }, - grandpa: node_rpc::GrandpaDeps { - shared_voter_state: shared_voter_state.clone(), - shared_authority_set: shared_authority_set.clone(), - justification_stream: justification_stream.clone(), - subscription_executor, - finality_provider: finality_proof_provider.clone(), - }, - statement_store: rpc_statement_store.clone(), - backend: rpc_backend.clone(), - mixnet_api: mixnet_api.as_ref().cloned(), - }; + let rpc_extensions_builder = + move |deny_unsafe, subscription_executor: node_rpc::SubscriptionTaskExecutor| { + let deps = node_rpc::FullDeps { + client: client.clone(), + pool: pool.clone(), + select_chain: select_chain.clone(), + chain_spec: chain_spec.cloned_box(), + deny_unsafe, + babe: node_rpc::BabeDeps { + keystore: keystore.clone(), + babe_worker_handle: babe_worker_handle.clone(), + }, + grandpa: node_rpc::GrandpaDeps { + shared_voter_state: shared_voter_state.clone(), + shared_authority_set: shared_authority_set.clone(), + justification_stream: justification_stream.clone(), + subscription_executor: subscription_executor.clone(), + finality_provider: finality_proof_provider.clone(), + }, + beefy: node_rpc::BeefyDeps { + beefy_finality_proof_stream: beefy_rpc_links + .from_voter_justif_stream + .clone(), + beefy_best_block_stream: beefy_rpc_links + .from_voter_best_beefy_stream + .clone(), + subscription_executor, + }, + statement_store: rpc_statement_store.clone(), + backend: rpc_backend.clone(), + mixnet_api: mixnet_api.as_ref().cloned(), + }; - node_rpc::create_full(deps).map_err(Into::into) - }; + node_rpc::create_full(deps).map_err(Into::into) + }; (rpc_extensions_builder, shared_voter_state2) }; @@ -358,10 +383,24 @@ pub fn new_full_base( mixnet_config: Option, disable_hardware_benchmarks: bool, with_startup_data: impl FnOnce( - &sc_consensus_babe::BabeBlockImport, + &sc_consensus_babe::BabeBlockImport< + Block, + FullClient, + FullBeefyBlockImport, + >, &sc_consensus_babe::BabeLink, ), ) -> Result { + let is_offchain_indexing_enabled = config.offchain_worker.indexing_enabled; + let role = config.role.clone(); + let force_authoring = config.force_authoring; + let backoff_authoring_blocks = + Some(sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging::default()); + let name = config.network.node_name.clone(); + let enable_grandpa = !config.disable_grandpa; + let prometheus_registry = config.prometheus_registry().cloned(); + let enable_offchain_worker = config.offchain_worker.enabled; + let hwbench = (!disable_hardware_benchmarks) .then_some(config.database.path().map(|database_path| { let _ = std::fs::create_dir_all(&database_path); @@ -391,6 +430,24 @@ pub fn new_full_base( grandpa::grandpa_peers_set_config(grandpa_protocol_name.clone()); net_config.add_notification_protocol(grandpa_protocol_config); + let beefy_gossip_proto_name = + beefy::gossip_protocol_name(&genesis_hash, config.chain_spec.fork_id()); + // `beefy_on_demand_justifications_handler` is given to `beefy-gadget` task to be run, + // while `beefy_req_resp_cfg` is added to `config.network.request_response_protocols`. + let (beefy_on_demand_justifications_handler, beefy_req_resp_cfg) = + beefy::communication::request_response::BeefyJustifsRequestHandler::new( + &genesis_hash, + config.chain_spec.fork_id(), + client.clone(), + prometheus_registry.clone(), + ); + + let (beefy_notification_config, beefy_notification_service) = + beefy::communication::beefy_peers_set_config(beefy_gossip_proto_name.clone()); + + net_config.add_notification_protocol(beefy_notification_config); + net_config.add_request_response_protocol(beefy_req_resp_cfg); + let (statement_handler_proto, statement_config) = sc_network_statement::StatementHandlerPrototype::new( genesis_hash, @@ -442,15 +499,6 @@ pub fn new_full_base( task_manager.spawn_handle().spawn("mixnet", None, mixnet); } - let role = config.role.clone(); - let force_authoring = config.force_authoring; - let backoff_authoring_blocks = - Some(sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging::default()); - let name = config.network.node_name.clone(); - let enable_grandpa = !config.disable_grandpa; - let prometheus_registry = config.prometheus_registry().cloned(); - let enable_offchain_worker = config.offchain_worker.enabled; - let rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams { config, backend: backend.clone(), @@ -488,7 +536,7 @@ pub fn new_full_base( } } - let (block_import, grandpa_link, babe_link) = import_setup; + let (block_import, grandpa_link, babe_link, beefy_links) = import_setup; (with_startup_data)(&block_import, &babe_link); @@ -582,6 +630,47 @@ pub fn new_full_base( // need a keystore, regardless of which protocol we use below. let keystore = if role.is_authority() { Some(keystore_container.keystore()) } else { None }; + // beefy is enabled if its notification service exists + let network_params = beefy::BeefyNetworkParams { + network: network.clone(), + sync: sync_service.clone(), + gossip_protocol_name: beefy_gossip_proto_name, + justifications_protocol_name: beefy_on_demand_justifications_handler.protocol_name(), + notification_service: beefy_notification_service, + _phantom: core::marker::PhantomData::, + }; + let beefy_params = beefy::BeefyParams { + client: client.clone(), + backend: backend.clone(), + payload_provider: beefy_primitives::mmr::MmrRootProvider::new(client.clone()), + runtime: client.clone(), + key_store: keystore.clone(), + network_params, + min_block_delta: 8, + prometheus_registry: prometheus_registry.clone(), + links: beefy_links, + on_demand_justifications_handler: beefy_on_demand_justifications_handler, + }; + + let beefy_gadget = beefy::start_beefy_gadget::<_, _, _, _, _, _, _>(beefy_params); + // BEEFY is part of consensus, if it fails we'll bring the node down with it to make sure it + // is noticed. + task_manager + .spawn_essential_handle() + .spawn_blocking("beefy-gadget", None, beefy_gadget); + // When offchain indexing is enabled, MMR gadget should also run. + if is_offchain_indexing_enabled { + task_manager.spawn_essential_handle().spawn_blocking( + "mmr-gadget", + None, + mmr_gadget::MmrGadget::start( + client.clone(), + backend.clone(), + sp_mmr_primitives::INDEXING_PREFIX.to_vec(), + ), + ); + } + let grandpa_config = grandpa::Config { // FIXME #1578 make this available through chainspec gossip_duration: std::time::Duration::from_millis(333), diff --git a/substrate/bin/node/cli/tests/res/default_genesis_config.json b/substrate/bin/node/cli/tests/res/default_genesis_config.json index caf12a443d3..1465a6497ca 100644 --- a/substrate/bin/node/cli/tests/res/default_genesis_config.json +++ b/substrate/bin/node/cli/tests/res/default_genesis_config.json @@ -45,6 +45,10 @@ "grandpa": { "authorities": [] }, + "beefy": { + "authorities": [], + "genesisBlock": 1 + }, "treasury": {}, "sudo": { "key": null diff --git a/substrate/bin/node/rpc/Cargo.toml b/substrate/bin/node/rpc/Cargo.toml index a4a361fadbc..66bd6e9a0a5 100644 --- a/substrate/bin/node/rpc/Cargo.toml +++ b/substrate/bin/node/rpc/Cargo.toml @@ -24,6 +24,8 @@ sc-chain-spec = { path = "../../../client/chain-spec" } sc-client-api = { path = "../../../client/api" } sc-consensus-babe = { path = "../../../client/consensus/babe" } sc-consensus-babe-rpc = { path = "../../../client/consensus/babe/rpc" } +sc-consensus-beefy = { path = "../../../client/consensus/beefy" } +sc-consensus-beefy-rpc = { path = "../../../client/consensus/beefy/rpc" } sc-consensus-grandpa = { path = "../../../client/consensus/grandpa" } sc-consensus-grandpa-rpc = { path = "../../../client/consensus/grandpa/rpc" } sc-mixnet = { path = "../../../client/mixnet" } diff --git a/substrate/bin/node/rpc/src/lib.rs b/substrate/bin/node/rpc/src/lib.rs index acc58777e91..4646524a25b 100644 --- a/substrate/bin/node/rpc/src/lib.rs +++ b/substrate/bin/node/rpc/src/lib.rs @@ -37,10 +37,13 @@ use jsonrpsee::RpcModule; use node_primitives::{AccountId, Balance, Block, BlockNumber, Hash, Nonce}; use sc_client_api::AuxStore; use sc_consensus_babe::BabeWorkerHandle; +use sc_consensus_beefy::communication::notification::{ + BeefyBestBlockStream, BeefyVersionedFinalityProofStream, +}; use sc_consensus_grandpa::{ FinalityProofProvider, GrandpaJustificationStream, SharedAuthoritySet, SharedVoterState, }; -use sc_rpc::SubscriptionTaskExecutor; +pub use sc_rpc::SubscriptionTaskExecutor; pub use sc_rpc_api::DenyUnsafe; use sc_transaction_pool_api::TransactionPool; use sp_api::ProvideRuntimeApi; @@ -72,6 +75,16 @@ pub struct GrandpaDeps { pub finality_provider: Arc>, } +/// Dependencies for BEEFY +pub struct BeefyDeps { + /// Receives notifications about finality proof events from BEEFY. + pub beefy_finality_proof_stream: BeefyVersionedFinalityProofStream, + /// Receives notifications about best block events from BEEFY. + pub beefy_best_block_stream: BeefyBestBlockStream, + /// Executor to drive the subscription manager in the BEEFY RPC handler. + pub subscription_executor: SubscriptionTaskExecutor, +} + /// Full client dependencies. pub struct FullDeps { /// The client instance to use. @@ -88,6 +101,8 @@ pub struct FullDeps { pub babe: BabeDeps, /// GRANDPA specific dependencies. pub grandpa: GrandpaDeps, + /// BEEFY specific dependencies. + pub beefy: BeefyDeps, /// Shared statement store reference. pub statement_store: Arc, /// The backend used by the node. @@ -106,6 +121,7 @@ pub fn create_full( deny_unsafe, babe, grandpa, + beefy, statement_store, backend, mixnet_api, @@ -133,6 +149,7 @@ where use mmr_rpc::{Mmr, MmrApiServer}; use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; use sc_consensus_babe_rpc::{Babe, BabeApiServer}; + use sc_consensus_beefy_rpc::{Beefy, BeefyApiServer}; use sc_consensus_grandpa_rpc::{Grandpa, GrandpaApiServer}; use sc_rpc::{ dev::{Dev, DevApiServer}, @@ -205,5 +222,14 @@ where io.merge(mixnet)?; } + io.merge( + Beefy::::new( + beefy.beefy_finality_proof_stream, + beefy.beefy_best_block_stream, + beefy.subscription_executor, + )? + .into_rpc(), + )?; + Ok(io) } diff --git a/substrate/bin/node/runtime/Cargo.toml b/substrate/bin/node/runtime/Cargo.toml index 5f77f72af49..93695912c52 100644 --- a/substrate/bin/node/runtime/Cargo.toml +++ b/substrate/bin/node/runtime/Cargo.toml @@ -34,6 +34,7 @@ primitive-types = { version = "0.12.0", default-features = false, features = ["c # primitives sp-authority-discovery = { path = "../../../primitives/authority-discovery", default-features = false, features = ["serde"] } sp-consensus-babe = { path = "../../../primitives/consensus/babe", default-features = false, features = ["serde"] } +sp-consensus-beefy = { path = "../../../primitives/consensus/beefy", default-features = false } sp-consensus-grandpa = { path = "../../../primitives/consensus/grandpa", default-features = false, features = ["serde"] } sp-block-builder = { path = "../../../primitives/block-builder", default-features = false } sp-genesis-builder = { default-features = false, path = "../../../primitives/genesis-builder" } @@ -72,6 +73,8 @@ pallet-authorship = { path = "../../../frame/authorship", default-features = fal pallet-babe = { path = "../../../frame/babe", default-features = false } pallet-bags-list = { path = "../../../frame/bags-list", default-features = false } pallet-balances = { path = "../../../frame/balances", default-features = false } +pallet-beefy = { path = "../../../frame/beefy", default-features = false } +pallet-beefy-mmr = { path = "../../../frame/beefy-mmr", default-features = false } pallet-bounties = { path = "../../../frame/bounties", default-features = false } pallet-broker = { path = "../../../frame/broker", default-features = false } pallet-child-bounties = { path = "../../../frame/child-bounties", default-features = false } @@ -170,6 +173,8 @@ std = [ "pallet-babe/std", "pallet-bags-list/std", "pallet-balances/std", + "pallet-beefy-mmr/std", + "pallet-beefy/std", "pallet-bounties/std", "pallet-broker/std", "pallet-child-bounties/std", @@ -241,6 +246,7 @@ std = [ "sp-authority-discovery/std", "sp-block-builder/std", "sp-consensus-babe/std", + "sp-consensus-beefy/std", "sp-consensus-grandpa/std", "sp-core/std", "sp-genesis-builder/std", @@ -349,6 +355,8 @@ try-runtime = [ "pallet-babe/try-runtime", "pallet-bags-list/try-runtime", "pallet-balances/try-runtime", + "pallet-beefy-mmr/try-runtime", + "pallet-beefy/try-runtime", "pallet-bounties/try-runtime", "pallet-broker/try-runtime", "pallet-child-bounties/try-runtime", diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 4d409a791ba..6e7bfb4f4b4 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -75,6 +75,10 @@ use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo}; use pallet_tx_pause::RuntimeCallNameOf; use sp_api::impl_runtime_apis; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; +use sp_consensus_beefy::{ + ecdsa_crypto::{AuthorityId as BeefyId, Signature as BeefySignature}, + mmr::MmrLeafVersion, +}; use sp_consensus_grandpa::AuthorityId as GrandpaId; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; use sp_inherents::{CheckInherentsResult, InherentData}; @@ -131,7 +135,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); /// Max size for serialized extrinsic params for this testing runtime. /// This is a quite arbitrary but empirically battle tested value. #[cfg(test)] -pub const CALL_PARAMS_MAX_SIZE: usize = 208; +pub const CALL_PARAMS_MAX_SIZE: usize = 244; /// Wasm binary unwrapped. If built with `SKIP_WASM_BUILD`, the function panics. #[cfg(feature = "std")] @@ -602,6 +606,7 @@ impl_opaque_keys! { pub im_online: ImOnline, pub authority_discovery: AuthorityDiscovery, pub mixnet: Mixnet, + pub beefy: Beefy, } } @@ -1573,6 +1578,17 @@ impl pallet_mmr::Config for Runtime { type WeightInfo = (); } +parameter_types! { + pub LeafVersion: MmrLeafVersion = MmrLeafVersion::new(0, 0); +} + +impl pallet_beefy_mmr::Config for Runtime { + type LeafVersion = LeafVersion; + type BeefyAuthorityToMerkleLeaf = pallet_beefy_mmr::BeefyEcdsaToEthereum; + type LeafExtra = Vec; + type BeefyDataProvider = (); +} + parameter_types! { pub const LotteryPalletId: PalletId = PalletId(*b"py/lotto"); pub const MaxCalls: u32 = 10; @@ -2077,6 +2093,11 @@ construct_runtime!( AssetConversionTxPayment: pallet_asset_conversion_tx_payment, ElectionProviderMultiPhase: pallet_election_provider_multi_phase, Staking: pallet_staking, + Beefy: pallet_beefy::{Pallet, Call, Storage, Config, ValidateUnsigned}, + // MMR leaf construction must be before session in order to have leaf contents + // refer to block consistently. see substrate issue #11797 for details. + Mmr: pallet_mmr::{Pallet, Storage}, + MmrLeaf: pallet_beefy_mmr::{Pallet, Storage}, Session: pallet_session, Democracy: pallet_democracy, Council: pallet_collective::, @@ -2106,7 +2127,6 @@ construct_runtime!( Tips: pallet_tips, Assets: pallet_assets::, PoolAssets: pallet_assets::, - Mmr: pallet_mmr, Lottery: pallet_lottery, Nis: pallet_nis, Uniques: pallet_uniques, @@ -2202,6 +2222,22 @@ type EventRecord = frame_system::EventRecord< ::Hash, >; +parameter_types! { + pub const BeefySetIdSessionEntries: u32 = BondingDuration::get() * SessionsPerEra::get(); +} + +impl pallet_beefy::Config for Runtime { + type BeefyId = BeefyId; + type MaxAuthorities = MaxAuthorities; + type MaxNominators = ConstU32<0>; + type MaxSetIdSessionEntries = BeefySetIdSessionEntries; + type OnNewValidatorSet = MmrLeaf; + type WeightInfo = (); + type KeyOwnerProof = >::Proof; + type EquivocationReportSystem = + pallet_beefy::EquivocationReportSystem; +} + /// MMR helper types. mod mmr { use super::Runtime; @@ -2656,6 +2692,42 @@ impl_runtime_apis! { } } + #[api_version(3)] + impl sp_consensus_beefy::BeefyApi for Runtime { + fn beefy_genesis() -> Option { + Beefy::genesis_block() + } + + fn validator_set() -> Option> { + Beefy::validator_set() + } + + fn submit_report_equivocation_unsigned_extrinsic( + equivocation_proof: sp_consensus_beefy::EquivocationProof< + BlockNumber, + BeefyId, + BeefySignature, + >, + key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof, + ) -> Option<()> { + let key_owner_proof = key_owner_proof.decode()?; + + Beefy::submit_unsigned_equivocation_report( + equivocation_proof, + key_owner_proof, + ) + } + + fn generate_key_ownership_proof( + _set_id: sp_consensus_beefy::ValidatorSetId, + authority_id: BeefyId, + ) -> Option { + Historical::prove((sp_consensus_beefy::KEY_TYPE, authority_id)) + .map(|p| p.encode()) + .map(sp_consensus_beefy::OpaqueKeyOwnershipProof::new) + } + } + impl pallet_mmr::primitives::MmrApi< Block, mmr::Hash, diff --git a/substrate/bin/node/testing/src/genesis.rs b/substrate/bin/node/testing/src/genesis.rs index eecbf64775b..6ec21fbe093 100644 --- a/substrate/bin/node/testing/src/genesis.rs +++ b/substrate/bin/node/testing/src/genesis.rs @@ -24,7 +24,7 @@ use kitchensink_runtime::{ GrandpaConfig, IndicesConfig, RuntimeGenesisConfig, SessionConfig, SocietyConfig, StakerStatus, StakingConfig, BABE_GENESIS_EPOCH_CONFIG, }; -use sp_keyring::{Ed25519Keyring, Sr25519Keyring}; +use sp_keyring::Ed25519Keyring; use sp_runtime::Perbill; /// Create genesis runtime configuration for tests. @@ -52,13 +52,9 @@ pub fn config_endowed(extra_endowed: Vec) -> RuntimeGenesisConfig { balances: BalancesConfig { balances: endowed }, session: SessionConfig { keys: vec![ - (alice(), dave(), to_session_keys(&Ed25519Keyring::Alice, &Sr25519Keyring::Alice)), - (bob(), eve(), to_session_keys(&Ed25519Keyring::Bob, &Sr25519Keyring::Bob)), - ( - charlie(), - ferdie(), - to_session_keys(&Ed25519Keyring::Charlie, &Sr25519Keyring::Charlie), - ), + (alice(), dave(), session_keys_from_seed(Ed25519Keyring::Alice.into())), + (bob(), eve(), session_keys_from_seed(Ed25519Keyring::Bob.into())), + (charlie(), ferdie(), session_keys_from_seed(Ed25519Keyring::Charlie.into())), ], }, staking: StakingConfig { @@ -79,6 +75,7 @@ pub fn config_endowed(extra_endowed: Vec) -> RuntimeGenesisConfig { ..Default::default() }, grandpa: GrandpaConfig { authorities: vec![], _config: Default::default() }, + beefy: Default::default(), im_online: Default::default(), authority_discovery: Default::default(), democracy: Default::default(), diff --git a/substrate/bin/node/testing/src/keyring.rs b/substrate/bin/node/testing/src/keyring.rs index 9940077c9da..6c885cc039a 100644 --- a/substrate/bin/node/testing/src/keyring.rs +++ b/substrate/bin/node/testing/src/keyring.rs @@ -20,8 +20,10 @@ use codec::Encode; use kitchensink_runtime::{CheckedExtrinsic, SessionKeys, SignedExtra, UncheckedExtrinsic}; +use node_cli::chain_spec::get_from_seed; use node_primitives::{AccountId, Balance, Nonce}; -use sp_keyring::{AccountKeyring, Ed25519Keyring, Sr25519Keyring}; +use sp_core::{ecdsa, ed25519, sr25519}; +use sp_keyring::AccountKeyring; use sp_runtime::generic::Era; /// Alice's account id. @@ -55,16 +57,14 @@ pub fn ferdie() -> AccountId { } /// Convert keyrings into `SessionKeys`. -pub fn to_session_keys( - ed25519_keyring: &Ed25519Keyring, - sr25519_keyring: &Sr25519Keyring, -) -> SessionKeys { +pub fn session_keys_from_seed(seed: &str) -> SessionKeys { SessionKeys { - grandpa: ed25519_keyring.to_owned().public().into(), - babe: sr25519_keyring.to_owned().public().into(), - im_online: sr25519_keyring.to_owned().public().into(), - authority_discovery: sr25519_keyring.to_owned().public().into(), - mixnet: sr25519_keyring.to_owned().public().into(), + grandpa: get_from_seed::(seed).into(), + babe: get_from_seed::(seed).into(), + im_online: get_from_seed::(seed).into(), + authority_discovery: get_from_seed::(seed).into(), + mixnet: get_from_seed::(seed).into(), + beefy: get_from_seed::(seed).into(), } } diff --git a/substrate/primitives/consensus/beefy/src/mmr.rs b/substrate/primitives/consensus/beefy/src/mmr.rs index 9ac1624ca75..1b9a45f8687 100644 --- a/substrate/primitives/consensus/beefy/src/mmr.rs +++ b/substrate/primitives/consensus/beefy/src/mmr.rs @@ -66,7 +66,7 @@ pub struct MmrLeaf { /// An MMR leaf versioning scheme. /// -/// Version is a single byte that constist of two components: +/// Version is a single byte that consists of two components: /// - `major` - 3 bits /// - `minor` - 5 bits /// -- GitLab From 204fe7ffd7be54cdefb24db69be1f830acc47031 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 7 Jan 2024 11:42:37 +0100 Subject: [PATCH 005/392] Bump the known_good_semver group with 4 updates (#2865) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the known_good_semver group with 4 updates: [serde](https://github.com/serde-rs/serde), [serde_json](https://github.com/serde-rs/json), [clap](https://github.com/clap-rs/clap) and [syn](https://github.com/dtolnay/syn). Updates `serde` from 1.0.194 to 1.0.195
Release notes

Sourced from serde's releases.

v1.0.195

  • Prevent remote definitions of tuple struct or tuple variant from triggering dead_code warning (#2671)
Commits
  • 03eec42 Release 1.0.195
  • 196f311 Merge pull request #2671 from dtolnay/deadremote
  • 38d9e0b Revert "Add FIXME to fix dead_code warning when using serde(remote)"
  • 6502b31 Fix new dead_code warning in tuple struct and tuple variant remote defs
  • 6f1a8c3 Add FIXME to fix dead_code warning when using serde(remote)
  • d883c94 Work around dead_code warning in tests
  • 961fa59 Merge pull request #2670 from serde-rs/exhaustive
  • 8bc71de Fill in omitted patterns for GenericArguments match
  • 7c65a9d Pick up changes to non_exhaustive_omitted_patterns lint
  • See full diff in compare view

Updates `serde_json` from 1.0.110 to 1.0.111
Release notes

Sourced from serde_json's releases.

v1.0.111

  • Improve floating point parsing performance on loongarch64 (#1100, thanks @​heiher)
Commits

Updates `clap` from 4.4.12 to 4.4.13
Release notes

Sourced from clap's releases.

v4.4.13

[4.4.13] - 2024-01-04

Documentation

  • Fix link to structopt migration guide
Changelog

Sourced from clap's changelog.

[4.4.13] - 2024-01-04

Documentation

  • Fix link to structopt migration guide
Commits
  • 2ab48b2 chore: Release
  • 7a06a8c docs: Update changelog
  • cca190e docs: Correct link to StructOpt migration guide
  • 5c31f45 Merge pull request #5281 from Manishearth/safety-docs
  • ddae7e6 Correct safety docs
  • 48d28aa chore: Release
  • 748ce18 docs: Update changelog
  • adbe6ec Merge pull request #5278 from henry-hsieh/fix-nosort
  • 2b48858 fix: Skip nosort option below bash 4.4
  • 777b744 Merge pull request #5277 from clap-rs/renovate/actions-setup-python-5.x
  • Additional commits viewable in compare view

Updates `syn` from 2.0.47 to 2.0.48
Release notes

Sourced from syn's releases.

2.0.48

  • Improve error message on unexpected token after else (#1578)
Commits
  • 5e16fc2 Release 2.0.48
  • dc40084 Merge pull request #1578 from dtolnay/elseblock
  • 82fcefc Fix error message on unexpected token after 'else'
  • e8a5c68 Merge pull request #1576 from dtolnay/exhaustive
  • 97b1df6 Pick up changes to non_exhaustive_omitted_patterns lint
  • See full diff in compare view

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 188 +++++++++--------- .../pallets/ethereum-beacon-client/Cargo.toml | 8 +- .../pallets/inbound-queue/Cargo.toml | 2 +- .../pallets/outbound-queue/Cargo.toml | 2 +- .../parachain/primitives/beacon/Cargo.toml | 2 +- .../parachain/primitives/core/Cargo.toml | 2 +- .../parachain/primitives/ethereum/Cargo.toml | 4 +- .../parachain/primitives/router/Cargo.toml | 2 +- .../parachain/runtime/tests/Cargo.toml | 2 +- cumulus/client/cli/Cargo.toml | 2 +- .../relay-chain-rpc-interface/Cargo.toml | 4 +- .../parachain-system/proc-macro/Cargo.toml | 2 +- cumulus/parachain-template/node/Cargo.toml | 6 +- .../pallets/template/Cargo.toml | 2 +- .../assets/asset-hub-rococo/Cargo.toml | 2 +- .../assets/asset-hub-westend/Cargo.toml | 2 +- .../bridges/bridge-hub-rococo/Cargo.toml | 2 +- .../bridges/bridge-hub-westend/Cargo.toml | 2 +- .../collectives-westend/Cargo.toml | 2 +- .../people/people-rococo/Cargo.toml | 2 +- .../people/people-westend/Cargo.toml | 2 +- .../parachains/testing/penpal/Cargo.toml | 2 +- .../emulated/chains/relays/rococo/Cargo.toml | 2 +- .../emulated/chains/relays/westend/Cargo.toml | 2 +- .../emulated/common/Cargo.toml | 2 +- .../bridge-hubs/bridge-hub-rococo/Cargo.toml | 2 +- .../bridge-hubs/bridge-hub-westend/Cargo.toml | 2 +- .../coretime/coretime-rococo/Cargo.toml | 2 +- .../coretime/coretime-westend/Cargo.toml | 2 +- .../runtimes/people/people-rococo/Cargo.toml | 2 +- .../runtimes/people/people-westend/Cargo.toml | 2 +- cumulus/polkadot-parachain/Cargo.toml | 6 +- cumulus/test/service/Cargo.toml | 6 +- polkadot/cli/Cargo.toml | 2 +- polkadot/node/gum/proc-macro/Cargo.toml | 2 +- polkadot/node/malus/Cargo.toml | 2 +- polkadot/node/primitives/Cargo.toml | 2 +- polkadot/node/service/Cargo.toml | 4 +- polkadot/node/subsystem-bench/Cargo.toml | 4 +- polkadot/node/test/service/Cargo.toml | 2 +- .../node/zombienet-backchannel/Cargo.toml | 2 +- polkadot/parachain/Cargo.toml | 2 +- .../test-parachains/adder/collator/Cargo.toml | 2 +- .../undying/collator/Cargo.toml | 2 +- polkadot/primitives/Cargo.toml | 2 +- polkadot/runtime/common/Cargo.toml | 4 +- polkadot/runtime/parachains/Cargo.toml | 4 +- polkadot/runtime/rococo/Cargo.toml | 4 +- polkadot/runtime/test-runtime/Cargo.toml | 4 +- polkadot/runtime/westend/Cargo.toml | 4 +- polkadot/utils/generate-bags/Cargo.toml | 2 +- .../remote-ext-tests/bags-list/Cargo.toml | 2 +- polkadot/xcm/Cargo.toml | 2 +- polkadot/xcm/pallet-xcm/Cargo.toml | 2 +- polkadot/xcm/procedural/Cargo.toml | 2 +- substrate/bin/minimal/node/Cargo.toml | 4 +- substrate/bin/node-template/node/Cargo.toml | 4 +- .../bin/node-template/runtime/Cargo.toml | 2 +- substrate/bin/node/bench/Cargo.toml | 6 +- substrate/bin/node/cli/Cargo.toml | 10 +- substrate/bin/node/inspect/Cargo.toml | 2 +- substrate/bin/node/runtime/Cargo.toml | 2 +- .../bin/utils/chain-spec-builder/Cargo.toml | 4 +- substrate/bin/utils/subkey/Cargo.toml | 2 +- substrate/client/chain-spec/Cargo.toml | 4 +- substrate/client/chain-spec/derive/Cargo.toml | 2 +- substrate/client/cli/Cargo.toml | 6 +- .../client/consensus/babe/rpc/Cargo.toml | 4 +- substrate/client/consensus/beefy/Cargo.toml | 2 +- .../client/consensus/beefy/rpc/Cargo.toml | 4 +- substrate/client/consensus/grandpa/Cargo.toml | 4 +- .../client/consensus/grandpa/rpc/Cargo.toml | 2 +- substrate/client/keystore/Cargo.toml | 2 +- .../merkle-mountain-range/rpc/Cargo.toml | 4 +- substrate/client/network/Cargo.toml | 4 +- substrate/client/rpc-api/Cargo.toml | 4 +- substrate/client/rpc-servers/Cargo.toml | 2 +- substrate/client/rpc-spec-v2/Cargo.toml | 2 +- substrate/client/rpc/Cargo.toml | 2 +- substrate/client/service/Cargo.toml | 4 +- substrate/client/storage-monitor/Cargo.toml | 2 +- substrate/client/sync-state-rpc/Cargo.toml | 4 +- substrate/client/sysinfo/Cargo.toml | 4 +- substrate/client/telemetry/Cargo.toml | 4 +- substrate/client/tracing/Cargo.toml | 2 +- .../client/tracing/proc-macro/Cargo.toml | 2 +- substrate/client/transaction-pool/Cargo.toml | 2 +- .../client/transaction-pool/api/Cargo.toml | 4 +- substrate/frame/beefy-mmr/Cargo.toml | 2 +- substrate/frame/beefy/Cargo.toml | 2 +- substrate/frame/benchmarking/Cargo.toml | 2 +- .../frame/contracts/proc-macro/Cargo.toml | 2 +- substrate/frame/conviction-voting/Cargo.toml | 2 +- substrate/frame/democracy/Cargo.toml | 2 +- .../solution-type/Cargo.toml | 2 +- .../solution-type/fuzzer/Cargo.toml | 2 +- substrate/frame/message-queue/Cargo.toml | 2 +- substrate/frame/mixnet/Cargo.toml | 2 +- substrate/frame/offences/Cargo.toml | 2 +- substrate/frame/referenda/Cargo.toml | 2 +- substrate/frame/remark/Cargo.toml | 2 +- substrate/frame/staking/Cargo.toml | 2 +- .../frame/staking/reward-curve/Cargo.toml | 2 +- .../frame/state-trie-migration/Cargo.toml | 2 +- substrate/frame/support/Cargo.toml | 4 +- substrate/frame/support/procedural/Cargo.toml | 2 +- .../frame/support/procedural/tools/Cargo.toml | 2 +- .../procedural/tools/derive/Cargo.toml | 2 +- substrate/frame/support/test/Cargo.toml | 2 +- .../frame/support/test/pallet/Cargo.toml | 2 +- substrate/frame/system/Cargo.toml | 2 +- substrate/frame/tips/Cargo.toml | 2 +- .../frame/transaction-payment/Cargo.toml | 4 +- .../asset-tx-payment/Cargo.toml | 4 +- .../frame/transaction-storage/Cargo.toml | 2 +- substrate/frame/treasury/Cargo.toml | 2 +- .../primitives/api/proc-macro/Cargo.toml | 2 +- .../primitives/application-crypto/Cargo.toml | 2 +- substrate/primitives/arithmetic/Cargo.toml | 2 +- .../primitives/consensus/babe/Cargo.toml | 2 +- .../primitives/consensus/beefy/Cargo.toml | 2 +- .../primitives/consensus/grandpa/Cargo.toml | 2 +- .../primitives/consensus/sassafras/Cargo.toml | 2 +- substrate/primitives/core/Cargo.toml | 4 +- .../core/hashing/proc-macro/Cargo.toml | 2 +- substrate/primitives/debug-derive/Cargo.toml | 2 +- .../primitives/genesis-builder/Cargo.toml | 2 +- .../merkle-mountain-range/Cargo.toml | 2 +- .../primitives/npos-elections/Cargo.toml | 2 +- .../npos-elections/fuzzer/Cargo.toml | 2 +- substrate/primitives/rpc/Cargo.toml | 4 +- .../runtime-interface/proc-macro/Cargo.toml | 2 +- substrate/primitives/runtime/Cargo.toml | 4 +- substrate/primitives/staking/Cargo.toml | 2 +- substrate/primitives/storage/Cargo.toml | 2 +- .../primitives/test-primitives/Cargo.toml | 2 +- substrate/primitives/version/Cargo.toml | 2 +- .../primitives/version/proc-macro/Cargo.toml | 2 +- substrate/primitives/weights/Cargo.toml | 2 +- .../ci/node-template-release/Cargo.toml | 2 +- substrate/test-utils/client/Cargo.toml | 4 +- substrate/test-utils/runtime/Cargo.toml | 4 +- .../utils/frame/benchmarking-cli/Cargo.toml | 6 +- .../frame/frame-utilities-cli/Cargo.toml | 2 +- .../generate-bags/node-runtime/Cargo.toml | 2 +- .../frame/remote-externalities/Cargo.toml | 2 +- .../rpc/state-trie-migration-rpc/Cargo.toml | 2 +- .../utils/frame/try-runtime/cli/Cargo.toml | 6 +- 148 files changed, 294 insertions(+), 294 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 23a0bf8fd35..2e2e1dfdb0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -191,7 +191,7 @@ checksum = "c0391754c09fab4eae3404d19d0d297aa1c670c1775ab51d8a5312afeca23157" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -206,7 +206,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", "syn-solidity", "tiny-keccak", ] @@ -1227,7 +1227,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -1244,7 +1244,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -1426,7 +1426,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -2639,9 +2639,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.12" +version = "4.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfab8ba68f3668e89f6ff60f5b205cea56aa7b769451a59f34b8682f51c056d" +checksum = "52bdc885e4cacc7f7c9eedc1ef6da641603180c783c41a15c264944deeaab642" dependencies = [ "clap_builder", "clap_derive 4.4.7", @@ -2675,7 +2675,7 @@ version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "586a385f7ef2f8b4d86bddaa0c094794e7ccbfe5ffef1f434fe928143fc783a5" dependencies = [ - "clap 4.4.12", + "clap 4.4.13", ] [[package]] @@ -2700,7 +2700,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -3413,7 +3413,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.4.12", + "clap 4.4.13", "criterion-plot", "futures", "is-terminal", @@ -3576,7 +3576,7 @@ dependencies = [ name = "cumulus-client-cli" version = "0.1.0" dependencies = [ - "clap 4.4.12", + "clap 4.4.13", "parity-scale-codec", "sc-chain-spec", "sc-cli", @@ -3933,7 +3933,7 @@ dependencies = [ "proc-macro-crate 2.0.1", "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -4315,7 +4315,7 @@ name = "cumulus-test-service" version = "0.1.0" dependencies = [ "async-trait", - "clap 4.4.12", + "clap 4.4.13", "criterion 0.5.1", "cumulus-client-cli", "cumulus-client-consensus-common", @@ -4438,7 +4438,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -4478,7 +4478,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -4495,7 +4495,7 @@ checksum = "50c49547d73ba8dcfd4ad7325d64c6d5391ff4224d498fc39a6f3f49825a530d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -4703,7 +4703,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -4764,7 +4764,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.47", + "syn 2.0.48", "termcolor", "toml 0.7.8", "walkdir", @@ -4992,7 +4992,7 @@ checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -5003,7 +5003,7 @@ checksum = "c2ad8cef1d801a4686bfd8919f0b30eac4c8e48968c437a6405ded4fb5272d2b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -5171,7 +5171,7 @@ dependencies = [ "fs-err", "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -5499,7 +5499,7 @@ dependencies = [ "Inflector", "array-bytes 6.1.0", "chrono", - "clap 4.4.12", + "clap 4.4.13", "comfy-table", "frame-benchmarking", "frame-support", @@ -5565,7 +5565,7 @@ dependencies = [ "quote", "scale-info", "sp-arithmetic", - "syn 2.0.47", + "syn 2.0.48", "trybuild", ] @@ -5591,7 +5591,7 @@ dependencies = [ name = "frame-election-solution-type-fuzzer" version = "2.0.0-alpha.5" dependencies = [ - "clap 4.4.12", + "clap 4.4.13", "frame-election-provider-solution-type", "frame-election-provider-support", "frame-support", @@ -5718,7 +5718,7 @@ dependencies = [ "quote", "regex", "sp-core-hashing", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -5729,7 +5729,7 @@ dependencies = [ "proc-macro-crate 2.0.1", "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -5738,7 +5738,7 @@ version = "3.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -5971,7 +5971,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -7906,7 +7906,7 @@ dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -7920,7 +7920,7 @@ dependencies = [ "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -7931,7 +7931,7 @@ checksum = "9ea73aa640dc01d62a590d48c0c3521ed739d53b27f919b25c3551e233481654" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -7942,7 +7942,7 @@ checksum = "ef9d79ae96aaba821963320eb2b6e34d17df1e5a83d8a1985c29cc5be59577b3" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -8107,7 +8107,7 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" name = "minimal-node" version = "4.0.0-dev" dependencies = [ - "clap 4.4.12", + "clap 4.4.13", "frame", "futures", "futures-timer", @@ -8571,7 +8571,7 @@ name = "node-bench" version = "0.9.0-dev" dependencies = [ "array-bytes 6.1.0", - "clap 4.4.12", + "clap 4.4.13", "derive_more", "fs_extra", "futures", @@ -8648,7 +8648,7 @@ dependencies = [ name = "node-runtime-generate-bags" version = "3.0.0" dependencies = [ - "clap 4.4.12", + "clap 4.4.13", "generate-bags", "kitchensink-runtime", ] @@ -8657,7 +8657,7 @@ dependencies = [ name = "node-template" version = "4.0.0-dev" dependencies = [ - "clap 4.4.12", + "clap 4.4.13", "frame-benchmarking", "frame-benchmarking-cli", "frame-system", @@ -8701,7 +8701,7 @@ dependencies = [ name = "node-template-release" version = "3.0.0" dependencies = [ - "clap 4.4.12", + "clap 4.4.13", "flate2", "fs_extra", "glob", @@ -9676,7 +9676,7 @@ version = "4.0.0-dev" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -10837,7 +10837,7 @@ dependencies = [ "proc-macro2", "quote", "sp-runtime", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -11243,7 +11243,7 @@ dependencies = [ name = "parachain-template-node" version = "0.1.0" dependencies = [ - "clap 4.4.12", + "clap 4.4.13", "color-print", "cumulus-client-cli", "cumulus-client-collator", @@ -11948,7 +11948,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -11989,7 +11989,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -12202,7 +12202,7 @@ name = "polkadot-cli" version = "1.1.0" dependencies = [ "cfg-if", - "clap 4.4.12", + "clap 4.4.13", "frame-benchmarking-cli", "futures", "log", @@ -13043,7 +13043,7 @@ dependencies = [ "async-trait", "bridge-hub-rococo-runtime", "bridge-hub-westend-runtime", - "clap 4.4.12", + "clap 4.4.13", "collectives-westend-runtime", "color-print", "contracts-rococo-runtime", @@ -13553,7 +13553,7 @@ version = "1.0.0" dependencies = [ "assert_matches", "async-trait", - "clap 4.4.12", + "clap 4.4.13", "clap-num", "color-eyre", "colored", @@ -13630,7 +13630,7 @@ version = "1.0.0" dependencies = [ "assert_matches", "async-trait", - "clap 4.4.12", + "clap 4.4.13", "color-eyre", "futures", "futures-timer", @@ -13777,7 +13777,7 @@ dependencies = [ name = "polkadot-voter-bags" version = "1.0.0" dependencies = [ - "clap 4.4.12", + "clap 4.4.13", "generate-bags", "sp-io", "westend-runtime", @@ -13802,7 +13802,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26501292b2cb980cbeaac3304f0fc4480ff1bac2473045453d7333d775658b6a" dependencies = [ "polkavm-derive-impl", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -13814,7 +13814,7 @@ dependencies = [ "polkavm-common 0.2.0", "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -14003,7 +14003,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c64d9ba0963cdcea2e1b2230fbae2bab30eb25a174be395c41e764bfb65dd62" dependencies = [ "proc-macro2", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -14095,7 +14095,7 @@ checksum = "9b698b0b09d40e9b7c1a47b132d66a8b54bcd20583d9b6d06e4535e383b4405c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -14167,7 +14167,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -14585,7 +14585,7 @@ checksum = "7f7473c2cfcf90008193dd0e3e16599455cb601a9fce322b5bb55de799664925" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -14654,7 +14654,7 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" name = "remote-ext-tests-bags-list" version = "1.0.0" dependencies = [ - "clap 4.4.12", + "clap 4.4.13", "frame-system", "log", "pallet-bags-list-remote-tests", @@ -15434,7 +15434,7 @@ dependencies = [ "proc-macro-crate 2.0.1", "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -15444,7 +15444,7 @@ dependencies = [ "array-bytes 6.1.0", "bip39", "chrono", - "clap 4.4.12", + "clap 4.4.13", "fdlimit", "futures", "futures-timer", @@ -16588,7 +16588,7 @@ dependencies = [ name = "sc-storage-monitor" version = "0.1.0" dependencies = [ - "clap 4.4.12", + "clap 4.4.13", "fs4", "log", "sc-client-db", @@ -16690,7 +16690,7 @@ dependencies = [ "proc-macro-crate 2.0.1", "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -17075,9 +17075,9 @@ checksum = "f97841a747eef040fcd2e7b3b9a220a7205926e60488e673d9e4926d27772ce5" [[package]] name = "serde" -version = "1.0.194" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] @@ -17102,13 +17102,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.194" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -17133,9 +17133,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.110" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fbd975230bada99c8bb618e0c365c2eefa219158d5c6c29610fd09ff1833257" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" dependencies = [ "itoa", "ryu", @@ -17198,7 +17198,7 @@ checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -17988,7 +17988,7 @@ dependencies = [ "proc-macro-crate 2.0.1", "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -18323,7 +18323,7 @@ version = "9.0.0" dependencies = [ "quote", "sp-core-hashing", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -18381,7 +18381,7 @@ version = "8.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -18391,7 +18391,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk#82912acb33a9030c0ef3bf5 dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -18550,7 +18550,7 @@ dependencies = [ name = "sp-npos-elections-fuzzer" version = "2.0.0-alpha.5" dependencies = [ - "clap 4.4.12", + "clap 4.4.13", "honggfuzz", "rand 0.8.5", "sp-npos-elections", @@ -18664,7 +18664,7 @@ dependencies = [ "proc-macro-crate 2.0.1", "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -18676,7 +18676,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -18947,7 +18947,7 @@ dependencies = [ "proc-macro2", "quote", "sp-version", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -19071,7 +19071,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" name = "staging-chain-spec-builder" version = "2.0.0" dependencies = [ - "clap 4.4.12", + "clap 4.4.13", "log", "sc-chain-spec", "serde_json", @@ -19084,7 +19084,7 @@ version = "3.0.0-dev" dependencies = [ "array-bytes 6.1.0", "assert_cmd", - "clap 4.4.12", + "clap 4.4.13", "clap_complete", "criterion 0.4.0", "frame-benchmarking", @@ -19193,7 +19193,7 @@ dependencies = [ name = "staging-node-inspect" version = "0.9.0-dev" dependencies = [ - "clap 4.4.12", + "clap 4.4.13", "parity-scale-codec", "sc-cli", "sc-client-api", @@ -19398,7 +19398,7 @@ dependencies = [ name = "subkey" version = "3.0.0" dependencies = [ - "clap 4.4.12", + "clap 4.4.13", "sc-cli", ] @@ -19440,7 +19440,7 @@ dependencies = [ name = "substrate-frame-cli" version = "4.0.0-dev" dependencies = [ - "clap 4.4.12", + "clap 4.4.13", "frame-support", "frame-system", "sc-cli", @@ -19786,9 +19786,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.47" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1726efe18f42ae774cc644f330953a5e7b3c3003d3edcecf18850fe9d4dd9afb" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -19804,7 +19804,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -19918,7 +19918,7 @@ dependencies = [ name = "test-parachain-adder-collator" version = "1.0.0" dependencies = [ - "clap 4.4.12", + "clap 4.4.13", "futures", "futures-timer", "log", @@ -19966,7 +19966,7 @@ dependencies = [ name = "test-parachain-undying-collator" version = "1.0.0" dependencies = [ - "clap 4.4.12", + "clap 4.4.13", "futures", "futures-timer", "log", @@ -20055,7 +20055,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -20216,7 +20216,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -20422,7 +20422,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -20464,7 +20464,7 @@ dependencies = [ "proc-macro-crate 2.0.1", "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -20617,7 +20617,7 @@ version = "0.10.0-dev" dependencies = [ "assert_cmd", "async-trait", - "clap 4.4.12", + "clap 4.4.13", "frame-remote-externalities", "frame-try-runtime", "hex", @@ -21000,7 +21000,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", "wasm-bindgen-shared", ] @@ -21034,7 +21034,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -22002,7 +22002,7 @@ dependencies = [ "proc-macro2", "quote", "staging-xcm", - "syn 2.0.47", + "syn 2.0.48", "trybuild", ] @@ -22122,7 +22122,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] @@ -22142,7 +22142,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.47", + "syn 2.0.48", ] [[package]] diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/Cargo.toml b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/Cargo.toml index 2f6eb2c91c0..db3be5f91b8 100644 --- a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/Cargo.toml +++ b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/Cargo.toml @@ -11,8 +11,8 @@ license = "Apache-2.0" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -serde = { version = "1.0.194", optional = true } -serde_json = { version = "1.0.110", optional = true } +serde = { version = "1.0.195", optional = true } +serde_json = { version = "1.0.111", optional = true } codec = { version = "3.6.1", package = "parity-scale-codec", default-features = false, features = ["derive"] } scale-info = { version = "2.9.0", default-features = false, features = ["derive"] } ssz_rs = { version = "0.9.0", default-features = false } @@ -40,11 +40,11 @@ pallet-timestamp = { path = "../../../../../substrate/frame/timestamp", default- [dev-dependencies] rand = "0.8.5" sp-keyring = { path = "../../../../../substrate/primitives/keyring" } -serde_json = "1.0.110" +serde_json = "1.0.111" hex-literal = "0.4.1" pallet-timestamp = { path = "../../../../../substrate/frame/timestamp" } sp-io = { path = "../../../../../substrate/primitives/io" } -serde = "1.0.194" +serde = "1.0.195" [features] default = ["std"] diff --git a/bridges/snowbridge/parachain/pallets/inbound-queue/Cargo.toml b/bridges/snowbridge/parachain/pallets/inbound-queue/Cargo.toml index 91a773f4471..6a5ea6f8222 100644 --- a/bridges/snowbridge/parachain/pallets/inbound-queue/Cargo.toml +++ b/bridges/snowbridge/parachain/pallets/inbound-queue/Cargo.toml @@ -11,7 +11,7 @@ license = "Apache-2.0" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -serde = { version = "1.0.194", optional = true } +serde = { version = "1.0.195", optional = true } codec = { version = "3.6.1", package = "parity-scale-codec", default-features = false, features = ["derive"] } scale-info = { version = "2.9.0", default-features = false, features = ["derive"] } hex-literal = { version = "0.4.1", optional = true } diff --git a/bridges/snowbridge/parachain/pallets/outbound-queue/Cargo.toml b/bridges/snowbridge/parachain/pallets/outbound-queue/Cargo.toml index 90a45745f4a..f99fcc72e19 100644 --- a/bridges/snowbridge/parachain/pallets/outbound-queue/Cargo.toml +++ b/bridges/snowbridge/parachain/pallets/outbound-queue/Cargo.toml @@ -11,7 +11,7 @@ license = "Apache-2.0" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -serde = { version = "1.0.194", features = ["alloc", "derive"], default-features = false } +serde = { version = "1.0.195", features = ["alloc", "derive"], default-features = false } codec = { version = "3.6.1", package = "parity-scale-codec", default-features = false, features = ["derive"] } scale-info = { version = "2.9.0", default-features = false, features = ["derive"] } hex-literal = { version = "0.4.1", optional = true } diff --git a/bridges/snowbridge/parachain/primitives/beacon/Cargo.toml b/bridges/snowbridge/parachain/primitives/beacon/Cargo.toml index f0a00f51229..eb717325e8a 100644 --- a/bridges/snowbridge/parachain/primitives/beacon/Cargo.toml +++ b/bridges/snowbridge/parachain/primitives/beacon/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" license = "Apache-2.0" [dependencies] -serde = { version = "1.0.194", optional = true, features = ["derive"] } +serde = { version = "1.0.195", optional = true, features = ["derive"] } hex = { version = "0.4", default-features = false } codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false } scale-info = { version = "2.9.0", default-features = false, features = ["derive"] } diff --git a/bridges/snowbridge/parachain/primitives/core/Cargo.toml b/bridges/snowbridge/parachain/primitives/core/Cargo.toml index f8cdfb1f1e9..706c508363d 100644 --- a/bridges/snowbridge/parachain/primitives/core/Cargo.toml +++ b/bridges/snowbridge/parachain/primitives/core/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" license = "Apache-2.0" [dependencies] -serde = { version = "1.0.194", optional = true, features = ["alloc", "derive"], default-features = false } +serde = { version = "1.0.195", optional = true, features = ["alloc", "derive"], default-features = false } codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false } scale-info = { version = "2.9.0", default-features = false, features = ["derive"] } hex-literal = { version = "0.4.1" } diff --git a/bridges/snowbridge/parachain/primitives/ethereum/Cargo.toml b/bridges/snowbridge/parachain/primitives/ethereum/Cargo.toml index d957b589aca..3624044f86a 100644 --- a/bridges/snowbridge/parachain/primitives/ethereum/Cargo.toml +++ b/bridges/snowbridge/parachain/primitives/ethereum/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" license = "Apache-2.0" [dependencies] -serde = { version = "1.0.194", optional = true, features = ["derive"] } +serde = { version = "1.0.195", optional = true, features = ["derive"] } serde-big-array = { version = "0.3.2", optional = true, features = ["const-generics"] } codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } scale-info = { version = "2.9.0", default-features = false, features = ["derive"] } @@ -28,7 +28,7 @@ ethabi = { git = "https://github.com/snowfork/ethabi-decode.git", package = "eth [dev-dependencies] wasm-bindgen-test = "0.3.19" rand = "0.8.5" -serde_json = "1.0.110" +serde_json = "1.0.111" [features] default = ["std"] diff --git a/bridges/snowbridge/parachain/primitives/router/Cargo.toml b/bridges/snowbridge/parachain/primitives/router/Cargo.toml index 0ee6fd9bd3d..40ae12920e7 100644 --- a/bridges/snowbridge/parachain/primitives/router/Cargo.toml +++ b/bridges/snowbridge/parachain/primitives/router/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" license = "Apache-2.0" [dependencies] -serde = { version = "1.0.194", optional = true, features = ["derive"] } +serde = { version = "1.0.195", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false } scale-info = { version = "2.9.0", default-features = false, features = ["derive"] } log = { version = "0.4.20", default-features = false } diff --git a/bridges/snowbridge/parachain/runtime/tests/Cargo.toml b/bridges/snowbridge/parachain/runtime/tests/Cargo.toml index 7002feae24a..9b5000b56cd 100644 --- a/bridges/snowbridge/parachain/runtime/tests/Cargo.toml +++ b/bridges/snowbridge/parachain/runtime/tests/Cargo.toml @@ -11,7 +11,7 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = hex-literal = { version = "0.4.1" } log = { version = "0.4.20", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", optional = true, features = ["derive"] } +serde = { version = "1.0.195", optional = true, features = ["derive"] } smallvec = "1.11.0" # Substrate diff --git a/cumulus/client/cli/Cargo.toml b/cumulus/client/cli/Cargo.toml index 3a4eed54f3f..1bf25f3963a 100644 --- a/cumulus/client/cli/Cargo.toml +++ b/cumulus/client/cli/Cargo.toml @@ -10,7 +10,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0" workspace = true [dependencies] -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0" } url = "2.4.0" diff --git a/cumulus/client/relay-chain-rpc-interface/Cargo.toml b/cumulus/client/relay-chain-rpc-interface/Cargo.toml index 9caf1f6b5e4..515c8ead32a 100644 --- a/cumulus/client/relay-chain-rpc-interface/Cargo.toml +++ b/cumulus/client/relay-chain-rpc-interface/Cargo.toml @@ -37,8 +37,8 @@ jsonrpsee = { version = "0.16.2", features = ["ws-client"] } tracing = "0.1.37" async-trait = "0.1.74" url = "2.4.0" -serde_json = "1.0.110" -serde = "1.0.194" +serde_json = "1.0.111" +serde = "1.0.195" schnellru = "0.2.1" smoldot = { version = "0.11.0", default_features = false, features = ["std"] } smoldot-light = { version = "0.9.0", default_features = false, features = ["std"] } diff --git a/cumulus/pallets/parachain-system/proc-macro/Cargo.toml b/cumulus/pallets/parachain-system/proc-macro/Cargo.toml index cdc5514122e..2861a51d13c 100644 --- a/cumulus/pallets/parachain-system/proc-macro/Cargo.toml +++ b/cumulus/pallets/parachain-system/proc-macro/Cargo.toml @@ -13,7 +13,7 @@ workspace = true proc-macro = true [dependencies] -syn = "2.0.43" +syn = "2.0.48" proc-macro2 = "1.0.64" quote = "1.0.33" proc-macro-crate = "2.0.1" diff --git a/cumulus/parachain-template/node/Cargo.toml b/cumulus/parachain-template/node/Cargo.toml index 865f310cd12..52c6ee7050d 100644 --- a/cumulus/parachain-template/node/Cargo.toml +++ b/cumulus/parachain-template/node/Cargo.toml @@ -14,13 +14,13 @@ publish = false workspace = true [dependencies] -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } log = "0.4.20" codec = { package = "parity-scale-codec", version = "3.0.0" } -serde = { version = "1.0.194", features = ["derive"] } +serde = { version = "1.0.195", features = ["derive"] } jsonrpsee = { version = "0.16.2", features = ["server"] } futures = "0.3.28" -serde_json = "1.0.110" +serde_json = "1.0.111" # Local parachain-template-runtime = { path = "../runtime" } diff --git a/cumulus/parachain-template/pallets/template/Cargo.toml b/cumulus/parachain-template/pallets/template/Cargo.toml index 64464257dd1..b8d95b5cf78 100644 --- a/cumulus/parachain-template/pallets/template/Cargo.toml +++ b/cumulus/parachain-template/pallets/template/Cargo.toml @@ -24,7 +24,7 @@ frame-support = { path = "../../../../substrate/frame/support", default-features frame-system = { path = "../../../../substrate/frame/system", default-features = false } [dev-dependencies] -serde = { version = "1.0.194" } +serde = { version = "1.0.195" } # Substrate sp-core = { path = "../../../../substrate/primitives/core", default-features = false } diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/Cargo.toml b/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/Cargo.toml index 4993eafb641..ecd0059057a 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/Cargo.toml @@ -11,7 +11,7 @@ publish = false workspace = true [dependencies] -serde_json = "1.0.110" +serde_json = "1.0.111" # Substrate sp-core = { path = "../../../../../../../../substrate/primitives/core", default-features = false } diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-westend/Cargo.toml b/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-westend/Cargo.toml index 73c69ecaa0b..b49b16bf855 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-westend/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-westend/Cargo.toml @@ -11,7 +11,7 @@ publish = false workspace = true [dependencies] -serde_json = "1.0.110" +serde_json = "1.0.111" # Substrate sp-core = { path = "../../../../../../../../substrate/primitives/core", default-features = false } diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/Cargo.toml index 5e5448864ff..d923f7388a2 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/Cargo.toml @@ -11,7 +11,7 @@ publish = false workspace = true [dependencies] -serde_json = "1.0.110" +serde_json = "1.0.111" # Substrate sp-core = { path = "../../../../../../../../substrate/primitives/core", default-features = false } diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/Cargo.toml b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/Cargo.toml index 62bd17c3b43..8fcf4fe5e80 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/Cargo.toml @@ -11,7 +11,7 @@ publish = false workspace = true [dependencies] -serde_json = "1.0.110" +serde_json = "1.0.111" # Substrate sp-core = { path = "../../../../../../../../substrate/primitives/core", default-features = false } diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/collectives/collectives-westend/Cargo.toml b/cumulus/parachains/integration-tests/emulated/chains/parachains/collectives/collectives-westend/Cargo.toml index 91b45f00f8f..f3fd5da3cfc 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/collectives/collectives-westend/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/collectives/collectives-westend/Cargo.toml @@ -11,7 +11,7 @@ publish = false workspace = true [dependencies] -serde_json = "1.0.110" +serde_json = "1.0.111" # Substrate sp-core = { path = "../../../../../../../../substrate/primitives/core", default-features = false } diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/people/people-rococo/Cargo.toml b/cumulus/parachains/integration-tests/emulated/chains/parachains/people/people-rococo/Cargo.toml index a4aeab3651e..2f22d9b7a84 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/people/people-rococo/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/people/people-rococo/Cargo.toml @@ -8,7 +8,7 @@ description = "People Rococo emulated chain" publish = false [dependencies] -serde_json = "1.0.110" +serde_json = "1.0.111" # Substrate sp-core = { path = "../../../../../../../../substrate/primitives/core", default-features = false } diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/people/people-westend/Cargo.toml b/cumulus/parachains/integration-tests/emulated/chains/parachains/people/people-westend/Cargo.toml index 57d102edd6e..dba6e6f6d4d 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/people/people-westend/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/people/people-westend/Cargo.toml @@ -8,7 +8,7 @@ description = "People Westend emulated chain" publish = false [dependencies] -serde_json = "1.0.110" +serde_json = "1.0.111" # Substrate sp-core = { path = "../../../../../../../../substrate/primitives/core", default-features = false } diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/Cargo.toml b/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/Cargo.toml index a9f031a2318..170d0b1a0b4 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/Cargo.toml @@ -11,7 +11,7 @@ publish = false workspace = true [dependencies] -serde_json = "1.0.110" +serde_json = "1.0.111" # Substrate sp-core = { path = "../../../../../../../../substrate/primitives/core", default-features = false } diff --git a/cumulus/parachains/integration-tests/emulated/chains/relays/rococo/Cargo.toml b/cumulus/parachains/integration-tests/emulated/chains/relays/rococo/Cargo.toml index f906c6672e0..2e8ea60efd6 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/relays/rococo/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/chains/relays/rococo/Cargo.toml @@ -11,7 +11,7 @@ publish = false workspace = true [dependencies] -serde_json = "1.0.110" +serde_json = "1.0.111" # Substrate sp-core = { path = "../../../../../../../substrate/primitives/core", default-features = false } diff --git a/cumulus/parachains/integration-tests/emulated/chains/relays/westend/Cargo.toml b/cumulus/parachains/integration-tests/emulated/chains/relays/westend/Cargo.toml index 9abbfc4c559..61174e2751b 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/relays/westend/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/chains/relays/westend/Cargo.toml @@ -11,7 +11,7 @@ publish = false workspace = true [dependencies] -serde_json = "1.0.110" +serde_json = "1.0.111" # Substrate sp-core = { path = "../../../../../../../substrate/primitives/core", default-features = false } diff --git a/cumulus/parachains/integration-tests/emulated/common/Cargo.toml b/cumulus/parachains/integration-tests/emulated/common/Cargo.toml index 75cd6ea700c..8277b3d734f 100644 --- a/cumulus/parachains/integration-tests/emulated/common/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/common/Cargo.toml @@ -12,7 +12,7 @@ workspace = true [dependencies] codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false } paste = "1.0.14" -serde_json = "1.0.110" +serde_json = "1.0.111" # Substrate grandpa = { package = "sc-consensus-grandpa", path = "../../../../../substrate/client/consensus/grandpa" } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml index b03dee2b9d4..6bb20b5ee35 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml @@ -21,7 +21,7 @@ log = { version = "0.4.20", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = [ "derive", ] } -serde = { version = "1.0.194", optional = true, features = ["derive"] } +serde = { version = "1.0.195", optional = true, features = ["derive"] } smallvec = "1.11.0" # Substrate diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml index 64e1967af92..dd02faefc1c 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml @@ -17,7 +17,7 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = hex-literal = { version = "0.4.1" } log = { version = "0.4.20", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", optional = true, features = ["derive"] } +serde = { version = "1.0.195", optional = true, features = ["derive"] } smallvec = "1.11.0" # Substrate diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml index 3e830db2276..0af44045da4 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml @@ -17,7 +17,7 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = hex-literal = "0.4.1" log = { version = "0.4.20", default-features = false } scale-info = { version = "2.9.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", optional = true, features = ["derive"] } +serde = { version = "1.0.195", optional = true, features = ["derive"] } smallvec = "1.11.0" # Substrate diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml b/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml index ea5eed062f7..02e130613f9 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml @@ -17,7 +17,7 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = hex-literal = "0.4.1" log = { version = "0.4.20", default-features = false } scale-info = { version = "2.9.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", optional = true, features = ["derive"] } +serde = { version = "1.0.195", optional = true, features = ["derive"] } smallvec = "1.11.0" # Substrate diff --git a/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml b/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml index a79f355e606..5086697b0f1 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml @@ -15,7 +15,7 @@ enumflags2 = { version = "0.7.7" } hex-literal = { version = "0.4.1" } log = { version = "0.4.20", default-features = false } scale-info = { version = "2.9.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", optional = true, features = ["derive"] } +serde = { version = "1.0.195", optional = true, features = ["derive"] } smallvec = "1.11.0" # Substrate diff --git a/cumulus/parachains/runtimes/people/people-westend/Cargo.toml b/cumulus/parachains/runtimes/people/people-westend/Cargo.toml index 78642059753..38386779a0e 100644 --- a/cumulus/parachains/runtimes/people/people-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/people/people-westend/Cargo.toml @@ -15,7 +15,7 @@ enumflags2 = { version = "0.7.7" } hex-literal = { version = "0.4.1" } log = { version = "0.4.20", default-features = false } scale-info = { version = "2.9.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", optional = true, features = ["derive"] } +serde = { version = "1.0.195", optional = true, features = ["derive"] } smallvec = "1.11.0" # Substrate diff --git a/cumulus/polkadot-parachain/Cargo.toml b/cumulus/polkadot-parachain/Cargo.toml index 02d53486710..a9b48a7984b 100644 --- a/cumulus/polkadot-parachain/Cargo.toml +++ b/cumulus/polkadot-parachain/Cargo.toml @@ -16,13 +16,13 @@ path = "src/main.rs" [dependencies] async-trait = "0.1.74" -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0" } futures = "0.3.28" hex-literal = "0.4.1" log = "0.4.20" -serde = { version = "1.0.194", features = ["derive"] } -serde_json = "1.0.110" +serde = { version = "1.0.195", features = ["derive"] } +serde_json = "1.0.111" # Local rococo-parachain-runtime = { path = "../parachains/runtimes/testing/rococo-parachain" } diff --git a/cumulus/test/service/Cargo.toml b/cumulus/test/service/Cargo.toml index 09403ef1853..b5294ec038a 100644 --- a/cumulus/test/service/Cargo.toml +++ b/cumulus/test/service/Cargo.toml @@ -14,13 +14,13 @@ path = "src/main.rs" [dependencies] async-trait = "0.1.74" -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0" } criterion = { version = "0.5.1", features = ["async_tokio"] } jsonrpsee = { version = "0.16.2", features = ["server"] } rand = "0.8.5" -serde = { version = "1.0.194", features = ["derive"] } -serde_json = "1.0.110" +serde = { version = "1.0.195", features = ["derive"] } +serde_json = "1.0.111" tokio = { version = "1.32.0", features = ["macros"] } tracing = "0.1.37" url = "2.4.0" diff --git a/polkadot/cli/Cargo.toml b/polkadot/cli/Cargo.toml index 3244608af2a..0b47da4d45c 100644 --- a/polkadot/cli/Cargo.toml +++ b/polkadot/cli/Cargo.toml @@ -19,7 +19,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] cfg-if = "1.0" -clap = { version = "4.4.12", features = ["derive"], optional = true } +clap = { version = "4.4.13", features = ["derive"], optional = true } log = "0.4.17" thiserror = "1.0.48" futures = "0.3.21" diff --git a/polkadot/node/gum/proc-macro/Cargo.toml b/polkadot/node/gum/proc-macro/Cargo.toml index e9a21914d56..174077f480a 100644 --- a/polkadot/node/gum/proc-macro/Cargo.toml +++ b/polkadot/node/gum/proc-macro/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] proc-macro = true [dependencies] -syn = { version = "2.0.43", features = ["extra-traits", "full"] } +syn = { version = "2.0.48", features = ["extra-traits", "full"] } quote = "1.0.28" proc-macro2 = "1.0.56" proc-macro-crate = "2.0.1" diff --git a/polkadot/node/malus/Cargo.toml b/polkadot/node/malus/Cargo.toml index 64657afc51a..f555cbd5dac 100644 --- a/polkadot/node/malus/Cargo.toml +++ b/polkadot/node/malus/Cargo.toml @@ -43,7 +43,7 @@ assert_matches = "1.5" async-trait = "0.1.74" sp-keystore = { path = "../../../substrate/primitives/keystore" } sp-core = { path = "../../../substrate/primitives/core" } -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" gum = { package = "tracing-gum", path = "../gum" } diff --git a/polkadot/node/primitives/Cargo.toml b/polkadot/node/primitives/Cargo.toml index 924d56c5bba..74152b5b7da 100644 --- a/polkadot/node/primitives/Cargo.toml +++ b/polkadot/node/primitives/Cargo.toml @@ -24,7 +24,7 @@ polkadot-parachain-primitives = { path = "../../parachain", default-features = f schnorrkel = "0.11.4" thiserror = "1.0.48" bitvec = { version = "1.0.0", default-features = false, features = ["alloc"] } -serde = { version = "1.0.194", features = ["derive"] } +serde = { version = "1.0.195", features = ["derive"] } [target.'cfg(not(target_os = "unknown"))'.dependencies] zstd = { version = "0.12.4", default-features = false } diff --git a/polkadot/node/service/Cargo.toml b/polkadot/node/service/Cargo.toml index 2f440abeb11..da3f0319377 100644 --- a/polkadot/node/service/Cargo.toml +++ b/polkadot/node/service/Cargo.toml @@ -85,8 +85,8 @@ is_executable = "1.0.1" gum = { package = "tracing-gum", path = "../gum" } log = "0.4.17" schnellru = "0.2.1" -serde = { version = "1.0.194", features = ["derive"] } -serde_json = "1.0.110" +serde = { version = "1.0.195", features = ["derive"] } +serde_json = "1.0.111" thiserror = "1.0.48" kvdb = "0.13.0" kvdb-rocksdb = { version = "0.19.0", optional = true } diff --git a/polkadot/node/subsystem-bench/Cargo.toml b/polkadot/node/subsystem-bench/Cargo.toml index d9e68b901e3..73405a3bc3b 100644 --- a/polkadot/node/subsystem-bench/Cargo.toml +++ b/polkadot/node/subsystem-bench/Cargo.toml @@ -31,7 +31,7 @@ async-trait = "0.1.74" sp-keystore = { path = "../../../substrate/primitives/keystore" } sc-keystore = { path = "../../../substrate/client/keystore" } sp-core = { path = "../../../substrate/primitives/core" } -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" gum = { package = "tracing-gum", path = "../gum" } @@ -52,7 +52,7 @@ itertools = "0.11.0" polkadot-primitives-test-helpers = { path = "../../primitives/test-helpers" } prometheus_endpoint = { package = "substrate-prometheus-endpoint", path = "../../../substrate/utils/prometheus" } prometheus = { version = "0.13.0", default-features = false } -serde = "1.0.194" +serde = "1.0.195" serde_yaml = "0.9" paste = "1.0.14" orchestra = { version = "0.3.3", default-features = false, features = ["futures_channel"] } diff --git a/polkadot/node/test/service/Cargo.toml b/polkadot/node/test/service/Cargo.toml index f8c35900dbe..f0410853799 100644 --- a/polkadot/node/test/service/Cargo.toml +++ b/polkadot/node/test/service/Cargo.toml @@ -14,7 +14,7 @@ futures = "0.3.21" hex = "0.4.3" gum = { package = "tracing-gum", path = "../../gum" } rand = "0.8.5" -serde_json = "1.0.110" +serde_json = "1.0.111" tempfile = "3.2.0" tokio = "1.24.2" diff --git a/polkadot/node/zombienet-backchannel/Cargo.toml b/polkadot/node/zombienet-backchannel/Cargo.toml index 7f44a98b6a9..82c6f2532ca 100644 --- a/polkadot/node/zombienet-backchannel/Cargo.toml +++ b/polkadot/node/zombienet-backchannel/Cargo.toml @@ -22,4 +22,4 @@ reqwest = { version = "0.11", features = ["rustls-tls"], default-features = fals thiserror = "1.0.48" gum = { package = "tracing-gum", path = "../gum" } serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0.110" +serde_json = "1.0.111" diff --git a/polkadot/parachain/Cargo.toml b/polkadot/parachain/Cargo.toml index 52858d3ed70..418fe0e6117 100644 --- a/polkadot/parachain/Cargo.toml +++ b/polkadot/parachain/Cargo.toml @@ -24,7 +24,7 @@ derive_more = "0.99.11" bounded-collections = { version = "0.1.8", default-features = false, features = ["serde"] } # all optional crates. -serde = { version = "1.0.194", default-features = false, features = ["alloc", "derive"] } +serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive"] } [features] default = ["std"] diff --git a/polkadot/parachain/test-parachains/adder/collator/Cargo.toml b/polkadot/parachain/test-parachains/adder/collator/Cargo.toml index f7ba527f6b4..a6517608b26 100644 --- a/polkadot/parachain/test-parachains/adder/collator/Cargo.toml +++ b/polkadot/parachain/test-parachains/adder/collator/Cargo.toml @@ -16,7 +16,7 @@ path = "src/main.rs" [dependencies] parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" log = "0.4.17" diff --git a/polkadot/parachain/test-parachains/undying/collator/Cargo.toml b/polkadot/parachain/test-parachains/undying/collator/Cargo.toml index a9f6e366cd6..d34a855ab9d 100644 --- a/polkadot/parachain/test-parachains/undying/collator/Cargo.toml +++ b/polkadot/parachain/test-parachains/undying/collator/Cargo.toml @@ -16,7 +16,7 @@ path = "src/main.rs" [dependencies] parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" log = "0.4.17" diff --git a/polkadot/primitives/Cargo.toml b/polkadot/primitives/Cargo.toml index 56fa14bcb7d..2552b9abc40 100644 --- a/polkadot/primitives/Cargo.toml +++ b/polkadot/primitives/Cargo.toml @@ -14,7 +14,7 @@ bitvec = { version = "1.0.0", default-features = false, features = ["alloc", "se hex-literal = "0.4.1" parity-scale-codec = { version = "3.6.1", default-features = false, features = ["bit-vec", "derive"] } scale-info = { version = "2.10.0", default-features = false, features = ["bit-vec", "derive", "serde"] } -serde = { version = "1.0.194", default-features = false, features = ["alloc", "derive"] } +serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive"] } application-crypto = { package = "sp-application-crypto", path = "../../substrate/primitives/application-crypto", default-features = false, features = ["serde"] } inherents = { package = "sp-inherents", path = "../../substrate/primitives/inherents", default-features = false } diff --git a/polkadot/runtime/common/Cargo.toml b/polkadot/runtime/common/Cargo.toml index fc2f3e2eb5a..f05963091dd 100644 --- a/polkadot/runtime/common/Cargo.toml +++ b/polkadot/runtime/common/Cargo.toml @@ -16,7 +16,7 @@ parity-scale-codec = { version = "3.6.1", default-features = false, features = [ log = { version = "0.4.17", default-features = false } rustc-hex = { version = "2.1.0", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", default-features = false, features = ["alloc"] } +serde = { version = "1.0.195", default-features = false, features = ["alloc"] } serde_derive = { version = "1.0.117" } static_assertions = "1.1.0" @@ -69,7 +69,7 @@ pallet-babe = { path = "../../../substrate/frame/babe" } pallet-treasury = { path = "../../../substrate/frame/treasury" } sp-keystore = { path = "../../../substrate/primitives/keystore" } sp-keyring = { path = "../../../substrate/primitives/keyring" } -serde_json = "1.0.110" +serde_json = "1.0.111" libsecp256k1 = "0.7.0" test-helpers = { package = "polkadot-primitives-test-helpers", path = "../../primitives/test-helpers" } diff --git a/polkadot/runtime/parachains/Cargo.toml b/polkadot/runtime/parachains/Cargo.toml index 65e76ccce31..dcfb7108dd2 100644 --- a/polkadot/runtime/parachains/Cargo.toml +++ b/polkadot/runtime/parachains/Cargo.toml @@ -16,7 +16,7 @@ parity-scale-codec = { version = "3.6.1", default-features = false, features = [ log = { version = "0.4.17", default-features = false } rustc-hex = { version = "2.1.0", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", default-features = false, features = ["alloc", "derive"] } +serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive"] } derive_more = "0.99.17" bitflags = "1.3.2" @@ -68,7 +68,7 @@ test-helpers = { package = "polkadot-primitives-test-helpers", path = "../../pri sp-tracing = { path = "../../../substrate/primitives/tracing" } thousands = "0.2.0" assert_matches = "1" -serde_json = "1.0.110" +serde_json = "1.0.111" [features] default = ["std"] diff --git a/polkadot/runtime/rococo/Cargo.toml b/polkadot/runtime/rococo/Cargo.toml index cdedf965f9a..992cc0b708a 100644 --- a/polkadot/runtime/rococo/Cargo.toml +++ b/polkadot/runtime/rococo/Cargo.toml @@ -14,7 +14,7 @@ workspace = true parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive", "max-encoded-len"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } log = { version = "0.4.17", default-features = false } -serde = { version = "1.0.194", default-features = false } +serde = { version = "1.0.195", default-features = false } serde_derive = { version = "1.0.117", optional = true } static_assertions = "1.1.0" smallvec = "1.8.0" @@ -111,7 +111,7 @@ keyring = { package = "sp-keyring", path = "../../../substrate/primitives/keyrin remote-externalities = { package = "frame-remote-externalities", path = "../../../substrate/utils/frame/remote-externalities" } sp-trie = { path = "../../../substrate/primitives/trie" } separator = "0.4.1" -serde_json = "1.0.110" +serde_json = "1.0.111" sp-tracing = { path = "../../../substrate/primitives/tracing", default-features = false } tokio = { version = "1.24.2", features = ["macros"] } diff --git a/polkadot/runtime/test-runtime/Cargo.toml b/polkadot/runtime/test-runtime/Cargo.toml index 582124fe3ea..9778ff82439 100644 --- a/polkadot/runtime/test-runtime/Cargo.toml +++ b/polkadot/runtime/test-runtime/Cargo.toml @@ -16,7 +16,7 @@ parity-scale-codec = { version = "3.6.1", default-features = false, features = [ log = { version = "0.4.17", default-features = false } rustc-hex = { version = "2.1.0", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", default-features = false } +serde = { version = "1.0.195", default-features = false } serde_derive = { version = "1.0.117", optional = true } smallvec = "1.8.0" @@ -74,7 +74,7 @@ hex-literal = "0.4.1" tiny-keccak = { version = "2.0.2", features = ["keccak"] } keyring = { package = "sp-keyring", path = "../../../substrate/primitives/keyring" } sp-trie = { path = "../../../substrate/primitives/trie" } -serde_json = "1.0.110" +serde_json = "1.0.111" [build-dependencies] substrate-wasm-builder = { path = "../../../substrate/utils/wasm-builder" } diff --git a/polkadot/runtime/westend/Cargo.toml b/polkadot/runtime/westend/Cargo.toml index 02db976e28a..8e442d0f853 100644 --- a/polkadot/runtime/westend/Cargo.toml +++ b/polkadot/runtime/westend/Cargo.toml @@ -16,7 +16,7 @@ parity-scale-codec = { version = "3.6.1", default-features = false, features = [ scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } log = { version = "0.4.17", default-features = false } rustc-hex = { version = "2.1.0", default-features = false } -serde = { version = "1.0.194", default-features = false } +serde = { version = "1.0.195", default-features = false } serde_derive = { version = "1.0.117", optional = true } smallvec = "1.8.0" @@ -119,7 +119,7 @@ xcm-builder = { package = "staging-xcm-builder", path = "../../xcm/xcm-builder", hex-literal = "0.4.1" tiny-keccak = { version = "2.0.2", features = ["keccak"] } keyring = { package = "sp-keyring", path = "../../../substrate/primitives/keyring" } -serde_json = "1.0.110" +serde_json = "1.0.111" remote-externalities = { package = "frame-remote-externalities", path = "../../../substrate/utils/frame/remote-externalities" } tokio = { version = "1.24.2", features = ["macros"] } sp-tracing = { path = "../../../substrate/primitives/tracing", default-features = false } diff --git a/polkadot/utils/generate-bags/Cargo.toml b/polkadot/utils/generate-bags/Cargo.toml index 179be5c4ac1..8ec828ba072 100644 --- a/polkadot/utils/generate-bags/Cargo.toml +++ b/polkadot/utils/generate-bags/Cargo.toml @@ -10,7 +10,7 @@ description = "CLI to generate voter bags for Polkadot runtimes" workspace = true [dependencies] -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } generate-bags = { path = "../../../substrate/utils/frame/generate-bags" } sp-io = { path = "../../../substrate/primitives/io" } diff --git a/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml b/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml index a4ffed0a5ce..8ee277e64b5 100644 --- a/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml +++ b/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml @@ -18,6 +18,6 @@ sp-tracing = { path = "../../../../substrate/primitives/tracing" } frame-system = { path = "../../../../substrate/frame/system" } sp-core = { path = "../../../../substrate/primitives/core" } -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } log = "0.4.17" tokio = { version = "1.24.2", features = ["macros"] } diff --git a/polkadot/xcm/Cargo.toml b/polkadot/xcm/Cargo.toml index 4d04a002fe0..89e3728a361 100644 --- a/polkadot/xcm/Cargo.toml +++ b/polkadot/xcm/Cargo.toml @@ -18,7 +18,7 @@ log = { version = "0.4.17", default-features = false } parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive", "max-encoded-len"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive", "serde"] } sp-weights = { path = "../../substrate/primitives/weights", default-features = false, features = ["serde"] } -serde = { version = "1.0.194", default-features = false, features = ["alloc", "derive"] } +serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive"] } schemars = { version = "0.8.13", default-features = true, optional = true } xcm-procedural = { path = "procedural" } environmental = { version = "1.1.4", default-features = false } diff --git a/polkadot/xcm/pallet-xcm/Cargo.toml b/polkadot/xcm/pallet-xcm/Cargo.toml index a4d0bb01b2b..b3e57d1d091 100644 --- a/polkadot/xcm/pallet-xcm/Cargo.toml +++ b/polkadot/xcm/pallet-xcm/Cargo.toml @@ -13,7 +13,7 @@ workspace = true bounded-collections = { version = "0.1.8", default-features = false } codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", optional = true, features = ["derive"] } +serde = { version = "1.0.195", optional = true, features = ["derive"] } log = { version = "0.4.17", default-features = false } frame-support = { path = "../../../substrate/frame/support", default-features = false } diff --git a/polkadot/xcm/procedural/Cargo.toml b/polkadot/xcm/procedural/Cargo.toml index 6ebae40f4a3..74990f873ab 100644 --- a/polkadot/xcm/procedural/Cargo.toml +++ b/polkadot/xcm/procedural/Cargo.toml @@ -16,7 +16,7 @@ proc-macro = true [dependencies] proc-macro2 = "1.0.56" quote = "1.0.28" -syn = "2.0.43" +syn = "2.0.48" Inflector = "0.11.4" [dev-dependencies] diff --git a/substrate/bin/minimal/node/Cargo.toml b/substrate/bin/minimal/node/Cargo.toml index 64851d5b352..42eced506c4 100644 --- a/substrate/bin/minimal/node/Cargo.toml +++ b/substrate/bin/minimal/node/Cargo.toml @@ -20,11 +20,11 @@ targets = ["x86_64-unknown-linux-gnu"] name = "minimal-node" [dependencies] -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } futures = { version = "0.3.21", features = ["thread-pool"] } futures-timer = "3.0.1" jsonrpsee = { version = "0.16.2", features = ["server"] } -serde_json = "1.0.110" +serde_json = "1.0.111" sc-cli = { path = "../../../client/cli" } sc-executor = { path = "../../../client/executor" } diff --git a/substrate/bin/node-template/node/Cargo.toml b/substrate/bin/node-template/node/Cargo.toml index 30468a2093c..6a600364c4d 100644 --- a/substrate/bin/node-template/node/Cargo.toml +++ b/substrate/bin/node-template/node/Cargo.toml @@ -20,9 +20,9 @@ targets = ["x86_64-unknown-linux-gnu"] name = "node-template" [dependencies] -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } futures = { version = "0.3.21", features = ["thread-pool"] } -serde_json = "1.0.110" +serde_json = "1.0.111" sc-cli = { path = "../../../client/cli" } sp-core = { path = "../../../primitives/core" } diff --git a/substrate/bin/node-template/runtime/Cargo.toml b/substrate/bin/node-template/runtime/Cargo.toml index d274eaa7a09..a7b93a230ca 100644 --- a/substrate/bin/node-template/runtime/Cargo.toml +++ b/substrate/bin/node-template/runtime/Cargo.toml @@ -42,7 +42,7 @@ sp-std = { path = "../../../primitives/std", default-features = false } sp-storage = { path = "../../../primitives/storage", default-features = false } sp-transaction-pool = { path = "../../../primitives/transaction-pool", default-features = false } sp-version = { path = "../../../primitives/version", default-features = false, features = ["serde"] } -serde_json = { version = "1.0.110", default-features = false, features = ["alloc"] } +serde_json = { version = "1.0.111", default-features = false, features = ["alloc"] } sp-genesis-builder = { default-features = false, path = "../../../primitives/genesis-builder" } # Used for the node template's RPCs diff --git a/substrate/bin/node/bench/Cargo.toml b/substrate/bin/node/bench/Cargo.toml index 52b2d94453d..e90b7070396 100644 --- a/substrate/bin/node/bench/Cargo.toml +++ b/substrate/bin/node/bench/Cargo.toml @@ -16,7 +16,7 @@ workspace = true [dependencies] array-bytes = "6.1" -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } log = "0.4.17" node-primitives = { path = "../primitives" } node-testing = { path = "../testing" } @@ -24,8 +24,8 @@ kitchensink-runtime = { path = "../runtime" } sc-client-api = { path = "../../../client/api" } sp-runtime = { path = "../../../primitives/runtime" } sp-state-machine = { path = "../../../primitives/state-machine" } -serde = "1.0.194" -serde_json = "1.0.110" +serde = "1.0.195" +serde_json = "1.0.111" derive_more = { version = "0.99.17", default-features = false, features = ["display"] } kvdb = "0.13.0" kvdb-rocksdb = "0.19.0" diff --git a/substrate/bin/node/cli/Cargo.toml b/substrate/bin/node/cli/Cargo.toml index 35d632865ee..3a80dc4e0cc 100644 --- a/substrate/bin/node/cli/Cargo.toml +++ b/substrate/bin/node/cli/Cargo.toml @@ -41,9 +41,9 @@ crate-type = ["cdylib", "rlib"] [dependencies] # third-party dependencies array-bytes = "6.1" -clap = { version = "4.4.12", features = ["derive"], optional = true } +clap = { version = "4.4.13", features = ["derive"], optional = true } codec = { package = "parity-scale-codec", version = "3.6.1" } -serde = { version = "1.0.194", features = ["derive"] } +serde = { version = "1.0.195", features = ["derive"] } jsonrpsee = { version = "0.16.2", features = ["server"] } futures = "0.3.21" log = "0.4.17" @@ -116,7 +116,7 @@ sc-cli = { path = "../../../client/cli", optional = true } frame-benchmarking-cli = { path = "../../../utils/frame/benchmarking-cli", optional = true } node-inspect = { package = "staging-node-inspect", path = "../inspect", optional = true } try-runtime-cli = { path = "../../../utils/frame/try-runtime/cli", optional = true } -serde_json = "1.0.110" +serde_json = "1.0.111" [dev-dependencies] sc-keystore = { path = "../../../client/keystore" } @@ -158,13 +158,13 @@ sp-consensus-babe = { path = "../../../primitives/consensus/babe" } sp-externalities = { path = "../../../primitives/externalities" } sp-keyring = { path = "../../../primitives/keyring" } sp-runtime = { path = "../../../primitives/runtime" } -serde_json = "1.0.110" +serde_json = "1.0.111" scale-info = { version = "2.10.0", features = ["derive", "serde"] } sp-trie = { path = "../../../primitives/trie" } sp-state-machine = { path = "../../../primitives/state-machine" } [build-dependencies] -clap = { version = "4.4.12", optional = true } +clap = { version = "4.4.13", optional = true } clap_complete = { version = "4.0.2", optional = true } node-inspect = { package = "staging-node-inspect", path = "../inspect", optional = true } frame-benchmarking-cli = { path = "../../../utils/frame/benchmarking-cli", optional = true } diff --git a/substrate/bin/node/inspect/Cargo.toml b/substrate/bin/node/inspect/Cargo.toml index f3f531a4db1..d14cc8ff760 100644 --- a/substrate/bin/node/inspect/Cargo.toml +++ b/substrate/bin/node/inspect/Cargo.toml @@ -15,7 +15,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.6.1" } thiserror = "1.0" sc-cli = { path = "../../../client/cli" } diff --git a/substrate/bin/node/runtime/Cargo.toml b/substrate/bin/node/runtime/Cargo.toml index 93695912c52..4bb5fed2b09 100644 --- a/substrate/bin/node/runtime/Cargo.toml +++ b/substrate/bin/node/runtime/Cargo.toml @@ -26,7 +26,7 @@ codec = { package = "parity-scale-codec", version = "3.6.1", default-features = scale-info = { version = "2.10.0", default-features = false, features = ["derive", "serde"] } static_assertions = "1.1.0" log = { version = "0.4.17", default-features = false } -serde_json = { version = "1.0.110", default-features = false, features = ["alloc", "arbitrary_precision"] } +serde_json = { version = "1.0.111", default-features = false, features = ["alloc", "arbitrary_precision"] } # pallet-asset-conversion: turn on "num-traits" feature primitive-types = { version = "0.12.0", default-features = false, features = ["codec", "num-traits", "scale-info"] } diff --git a/substrate/bin/utils/chain-spec-builder/Cargo.toml b/substrate/bin/utils/chain-spec-builder/Cargo.toml index 0a1b1345a15..3848ef91588 100644 --- a/substrate/bin/utils/chain-spec-builder/Cargo.toml +++ b/substrate/bin/utils/chain-spec-builder/Cargo.toml @@ -23,8 +23,8 @@ name = "chain-spec-builder" crate-type = ["rlib"] [dependencies] -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } log = "0.4.17" sc-chain-spec = { path = "../../../client/chain-spec" } -serde_json = "1.0.110" +serde_json = "1.0.111" sp-tracing = { version = "10.0.0", path = "../../../primitives/tracing" } diff --git a/substrate/bin/utils/subkey/Cargo.toml b/substrate/bin/utils/subkey/Cargo.toml index 57613cb718c..d4ecfda3735 100644 --- a/substrate/bin/utils/subkey/Cargo.toml +++ b/substrate/bin/utils/subkey/Cargo.toml @@ -20,5 +20,5 @@ path = "src/main.rs" name = "subkey" [dependencies] -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } sc-cli = { path = "../../../client/cli" } diff --git a/substrate/client/chain-spec/Cargo.toml b/substrate/client/chain-spec/Cargo.toml index 6943c5d94ac..8af9e1b4758 100644 --- a/substrate/client/chain-spec/Cargo.toml +++ b/substrate/client/chain-spec/Cargo.toml @@ -18,8 +18,8 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } memmap2 = "0.5.0" -serde = { version = "1.0.194", features = ["derive"] } -serde_json = "1.0.110" +serde = { version = "1.0.195", features = ["derive"] } +serde_json = "1.0.111" sc-client-api = { path = "../api" } sc-chain-spec-derive = { path = "derive" } sc-executor = { path = "../executor" } diff --git a/substrate/client/chain-spec/derive/Cargo.toml b/substrate/client/chain-spec/derive/Cargo.toml index b8dcd5e5665..8f8c2c0de2d 100644 --- a/substrate/client/chain-spec/derive/Cargo.toml +++ b/substrate/client/chain-spec/derive/Cargo.toml @@ -21,4 +21,4 @@ proc-macro = true proc-macro-crate = "2.0.1" proc-macro2 = "1.0.56" quote = "1.0.28" -syn = "2.0.43" +syn = "2.0.48" diff --git a/substrate/client/cli/Cargo.toml b/substrate/client/cli/Cargo.toml index 56bc0dd2504..526db17fa32 100644 --- a/substrate/client/cli/Cargo.toml +++ b/substrate/client/cli/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] array-bytes = "6.1" chrono = "0.4.31" -clap = { version = "4.4.12", features = ["derive", "string", "wrap_help"] } +clap = { version = "4.4.13", features = ["derive", "string", "wrap_help"] } fdlimit = "0.3.0" futures = "0.3.21" itertools = "0.10.3" @@ -29,8 +29,8 @@ parity-scale-codec = "3.6.1" rand = "0.8.5" regex = "1.6.0" rpassword = "7.0.0" -serde = "1.0.194" -serde_json = "1.0.110" +serde = "1.0.195" +serde_json = "1.0.111" thiserror = "1.0.48" bip39 = "2.0.0" tokio = { version = "1.22.0", features = ["parking_lot", "rt-multi-thread", "signal"] } diff --git a/substrate/client/consensus/babe/rpc/Cargo.toml b/substrate/client/consensus/babe/rpc/Cargo.toml index ef053a0ab26..753f8fbc821 100644 --- a/substrate/client/consensus/babe/rpc/Cargo.toml +++ b/substrate/client/consensus/babe/rpc/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] jsonrpsee = { version = "0.16.2", features = ["client-core", "macros", "server"] } futures = "0.3.21" -serde = { version = "1.0.194", features = ["derive"] } +serde = { version = "1.0.195", features = ["derive"] } thiserror = "1.0" sc-consensus-babe = { path = ".." } sc-consensus-epochs = { path = "../../epochs" } @@ -33,7 +33,7 @@ sp-keystore = { path = "../../../../primitives/keystore" } sp-runtime = { path = "../../../../primitives/runtime" } [dev-dependencies] -serde_json = "1.0.110" +serde_json = "1.0.111" tokio = "1.22.0" sc-consensus = { path = "../../common" } sc-keystore = { path = "../../../keystore" } diff --git a/substrate/client/consensus/beefy/Cargo.toml b/substrate/client/consensus/beefy/Cargo.toml index 77c1baa053a..c54452faebe 100644 --- a/substrate/client/consensus/beefy/Cargo.toml +++ b/substrate/client/consensus/beefy/Cargo.toml @@ -43,7 +43,7 @@ tokio = "1.22.0" [dev-dependencies] -serde = "1.0.194" +serde = "1.0.195" tempfile = "3.1.0" sc-block-builder = { path = "../../block-builder" } sc-network-test = { path = "../../network/test" } diff --git a/substrate/client/consensus/beefy/rpc/Cargo.toml b/substrate/client/consensus/beefy/rpc/Cargo.toml index 921ced61cca..198d3d81642 100644 --- a/substrate/client/consensus/beefy/rpc/Cargo.toml +++ b/substrate/client/consensus/beefy/rpc/Cargo.toml @@ -17,7 +17,7 @@ futures = "0.3.21" jsonrpsee = { version = "0.16.2", features = ["client-core", "macros", "server"] } log = "0.4" parking_lot = "0.12.1" -serde = { version = "1.0.194", features = ["derive"] } +serde = { version = "1.0.195", features = ["derive"] } thiserror = "1.0" sc-consensus-beefy = { path = ".." } sp-consensus-beefy = { path = "../../../../primitives/consensus/beefy" } @@ -26,7 +26,7 @@ sp-core = { path = "../../../../primitives/core" } sp-runtime = { path = "../../../../primitives/runtime" } [dev-dependencies] -serde_json = "1.0.110" +serde_json = "1.0.111" sc-rpc = { path = "../../../rpc", features = ["test-helpers"] } substrate-test-runtime-client = { path = "../../../../test-utils/runtime/client" } tokio = { version = "1.22.0", features = ["macros"] } diff --git a/substrate/client/consensus/grandpa/Cargo.toml b/substrate/client/consensus/grandpa/Cargo.toml index d0c024f64fa..a6aacd56485 100644 --- a/substrate/client/consensus/grandpa/Cargo.toml +++ b/substrate/client/consensus/grandpa/Cargo.toml @@ -28,7 +28,7 @@ log = "0.4.17" parity-scale-codec = { version = "3.6.1", features = ["derive"] } parking_lot = "0.12.1" rand = "0.8.5" -serde_json = "1.0.110" +serde_json = "1.0.111" thiserror = "1.0" fork-tree = { path = "../../../utils/fork-tree" } prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../../utils/prometheus" } @@ -56,7 +56,7 @@ sp-runtime = { path = "../../../primitives/runtime" } [dev-dependencies] assert_matches = "1.3.0" finality-grandpa = { version = "0.16.2", features = ["derive-codec", "test-helpers"] } -serde = "1.0.194" +serde = "1.0.195" tokio = "1.22.0" sc-network = { path = "../../network" } sc-network-test = { path = "../../network/test" } diff --git a/substrate/client/consensus/grandpa/rpc/Cargo.toml b/substrate/client/consensus/grandpa/rpc/Cargo.toml index a6d0f39c0cd..9cfc9616cbc 100644 --- a/substrate/client/consensus/grandpa/rpc/Cargo.toml +++ b/substrate/client/consensus/grandpa/rpc/Cargo.toml @@ -18,7 +18,7 @@ futures = "0.3.16" jsonrpsee = { version = "0.16.2", features = ["client-core", "macros", "server"] } log = "0.4.8" parity-scale-codec = { version = "3.6.1", features = ["derive"] } -serde = { version = "1.0.194", features = ["derive"] } +serde = { version = "1.0.195", features = ["derive"] } thiserror = "1.0" sc-client-api = { path = "../../../api" } sc-consensus-grandpa = { path = ".." } diff --git a/substrate/client/keystore/Cargo.toml b/substrate/client/keystore/Cargo.toml index 45c7f774e2e..8fa6221ff19 100644 --- a/substrate/client/keystore/Cargo.toml +++ b/substrate/client/keystore/Cargo.toml @@ -19,7 +19,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] array-bytes = "6.1" parking_lot = "0.12.1" -serde_json = "1.0.110" +serde_json = "1.0.111" thiserror = "1.0" sp-application-crypto = { path = "../../primitives/application-crypto" } sp-core = { path = "../../primitives/core" } diff --git a/substrate/client/merkle-mountain-range/rpc/Cargo.toml b/substrate/client/merkle-mountain-range/rpc/Cargo.toml index e38ef061a71..8eb48d65f81 100644 --- a/substrate/client/merkle-mountain-range/rpc/Cargo.toml +++ b/substrate/client/merkle-mountain-range/rpc/Cargo.toml @@ -17,7 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "3.6.1" } jsonrpsee = { version = "0.16.2", features = ["client-core", "macros", "server"] } -serde = { version = "1.0.194", features = ["derive"] } +serde = { version = "1.0.195", features = ["derive"] } sp-api = { path = "../../../primitives/api" } sp-blockchain = { path = "../../../primitives/blockchain" } sp-core = { path = "../../../primitives/core" } @@ -26,4 +26,4 @@ sp-runtime = { path = "../../../primitives/runtime" } anyhow = "1" [dev-dependencies] -serde_json = "1.0.110" +serde_json = "1.0.111" diff --git a/substrate/client/network/Cargo.toml b/substrate/client/network/Cargo.toml index ab2d02fd80e..f2e6f54547b 100644 --- a/substrate/client/network/Cargo.toml +++ b/substrate/client/network/Cargo.toml @@ -36,8 +36,8 @@ parking_lot = "0.12.1" partial_sort = "0.2.0" pin-project = "1.0.12" rand = "0.8.5" -serde = { version = "1.0.194", features = ["derive"] } -serde_json = "1.0.110" +serde = { version = "1.0.195", features = ["derive"] } +serde_json = "1.0.111" smallvec = "1.11.0" thiserror = "1.0" tokio = { version = "1.22.0", features = ["macros", "sync"] } diff --git a/substrate/client/rpc-api/Cargo.toml b/substrate/client/rpc-api/Cargo.toml index 7978148c3c8..062d25408a1 100644 --- a/substrate/client/rpc-api/Cargo.toml +++ b/substrate/client/rpc-api/Cargo.toml @@ -18,8 +18,8 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "3.6.1" } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", features = ["derive"] } -serde_json = "1.0.110" +serde = { version = "1.0.195", features = ["derive"] } +serde_json = "1.0.111" thiserror = "1.0" sc-chain-spec = { path = "../chain-spec" } sc-mixnet = { path = "../mixnet" } diff --git a/substrate/client/rpc-servers/Cargo.toml b/substrate/client/rpc-servers/Cargo.toml index addbbab92d4..60d999863ca 100644 --- a/substrate/client/rpc-servers/Cargo.toml +++ b/substrate/client/rpc-servers/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] jsonrpsee = { version = "0.16.2", features = ["server"] } log = "0.4.17" -serde_json = "1.0.110" +serde_json = "1.0.111" tokio = { version = "1.22.0", features = ["parking_lot"] } prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus" } tower-http = { version = "0.4.0", features = ["cors"] } diff --git a/substrate/client/rpc-spec-v2/Cargo.toml b/substrate/client/rpc-spec-v2/Cargo.toml index 9ee18b59489..ba32308e678 100644 --- a/substrate/client/rpc-spec-v2/Cargo.toml +++ b/substrate/client/rpc-spec-v2/Cargo.toml @@ -42,7 +42,7 @@ log = "0.4.17" futures-util = { version = "0.3.19", default-features = false } [dev-dependencies] -serde_json = "1.0.110" +serde_json = "1.0.111" tokio = { version = "1.22.0", features = ["macros"] } substrate-test-runtime-client = { path = "../../test-utils/runtime/client" } substrate-test-runtime = { path = "../../test-utils/runtime" } diff --git a/substrate/client/rpc/Cargo.toml b/substrate/client/rpc/Cargo.toml index 5da79442544..47425c6d354 100644 --- a/substrate/client/rpc/Cargo.toml +++ b/substrate/client/rpc/Cargo.toml @@ -21,7 +21,7 @@ futures = "0.3.21" jsonrpsee = { version = "0.16.2", features = ["server"] } log = "0.4.17" parking_lot = "0.12.1" -serde_json = "1.0.110" +serde_json = "1.0.111" sc-block-builder = { path = "../block-builder" } sc-chain-spec = { path = "../chain-spec" } sc-client-api = { path = "../api" } diff --git a/substrate/client/service/Cargo.toml b/substrate/client/service/Cargo.toml index adfd8d45b24..576a8aac8e4 100644 --- a/substrate/client/service/Cargo.toml +++ b/substrate/client/service/Cargo.toml @@ -37,8 +37,8 @@ log = "0.4.17" futures-timer = "3.0.1" exit-future = "0.2.0" pin-project = "1.0.12" -serde = "1.0.194" -serde_json = "1.0.110" +serde = "1.0.195" +serde_json = "1.0.111" sc-keystore = { path = "../keystore" } sp-runtime = { path = "../../primitives/runtime" } sp-trie = { path = "../../primitives/trie" } diff --git a/substrate/client/storage-monitor/Cargo.toml b/substrate/client/storage-monitor/Cargo.toml index 8019682f3f1..37259b9234a 100644 --- a/substrate/client/storage-monitor/Cargo.toml +++ b/substrate/client/storage-monitor/Cargo.toml @@ -12,7 +12,7 @@ homepage = "https://substrate.io" workspace = true [dependencies] -clap = { version = "4.4.12", features = ["derive", "string"] } +clap = { version = "4.4.13", features = ["derive", "string"] } log = "0.4.17" fs4 = "0.7.0" sc-client-db = { path = "../db", default-features = false } diff --git a/substrate/client/sync-state-rpc/Cargo.toml b/substrate/client/sync-state-rpc/Cargo.toml index 6c78ff7e5e1..b3de9585ab4 100644 --- a/substrate/client/sync-state-rpc/Cargo.toml +++ b/substrate/client/sync-state-rpc/Cargo.toml @@ -17,8 +17,8 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "3.6.1" } jsonrpsee = { version = "0.16.2", features = ["client-core", "macros", "server"] } -serde = { version = "1.0.194", features = ["derive"] } -serde_json = "1.0.110" +serde = { version = "1.0.195", features = ["derive"] } +serde_json = "1.0.111" thiserror = "1.0.48" sc-chain-spec = { path = "../chain-spec" } sc-client-api = { path = "../api" } diff --git a/substrate/client/sysinfo/Cargo.toml b/substrate/client/sysinfo/Cargo.toml index 9dfb44f6ab2..18ac161f1ee 100644 --- a/substrate/client/sysinfo/Cargo.toml +++ b/substrate/client/sysinfo/Cargo.toml @@ -24,8 +24,8 @@ rand = "0.8.5" rand_pcg = "0.3.1" derive_more = "0.99" regex = "1" -serde = { version = "1.0.194", features = ["derive"] } -serde_json = "1.0.110" +serde = { version = "1.0.195", features = ["derive"] } +serde_json = "1.0.111" sc-telemetry = { path = "../telemetry" } sp-core = { path = "../../primitives/core" } sp-io = { path = "../../primitives/io" } diff --git a/substrate/client/telemetry/Cargo.toml b/substrate/client/telemetry/Cargo.toml index 096ed71fb47..ba597ef898e 100644 --- a/substrate/client/telemetry/Cargo.toml +++ b/substrate/client/telemetry/Cargo.toml @@ -25,7 +25,7 @@ parking_lot = "0.12.1" pin-project = "1.0.12" sc-utils = { path = "../utils" } rand = "0.8.5" -serde = { version = "1.0.194", features = ["derive"] } -serde_json = "1.0.110" +serde = { version = "1.0.195", features = ["derive"] } +serde_json = "1.0.111" thiserror = "1.0.48" wasm-timer = "0.2.5" diff --git a/substrate/client/tracing/Cargo.toml b/substrate/client/tracing/Cargo.toml index fef7cc11157..fe288474ac9 100644 --- a/substrate/client/tracing/Cargo.toml +++ b/substrate/client/tracing/Cargo.toml @@ -26,7 +26,7 @@ log = { version = "0.4.17" } parking_lot = "0.12.1" regex = "1.6.0" rustc-hash = "1.1.0" -serde = "1.0.194" +serde = "1.0.195" thiserror = "1.0.48" tracing = "0.1.29" tracing-log = "0.1.3" diff --git a/substrate/client/tracing/proc-macro/Cargo.toml b/substrate/client/tracing/proc-macro/Cargo.toml index d6fd53fe1db..ff43f1ccb90 100644 --- a/substrate/client/tracing/proc-macro/Cargo.toml +++ b/substrate/client/tracing/proc-macro/Cargo.toml @@ -21,4 +21,4 @@ proc-macro = true proc-macro-crate = "2.0.1" proc-macro2 = "1.0.56" quote = { version = "1.0.28", features = ["proc-macro"] } -syn = { version = "2.0.43", features = ["extra-traits", "full", "parsing", "proc-macro"] } +syn = { version = "2.0.48", features = ["extra-traits", "full", "parsing", "proc-macro"] } diff --git a/substrate/client/transaction-pool/Cargo.toml b/substrate/client/transaction-pool/Cargo.toml index a3608c4ee39..8832c0bf508 100644 --- a/substrate/client/transaction-pool/Cargo.toml +++ b/substrate/client/transaction-pool/Cargo.toml @@ -23,7 +23,7 @@ futures-timer = "3.0.2" linked-hash-map = "0.5.4" log = "0.4.17" parking_lot = "0.12.1" -serde = { version = "1.0.194", features = ["derive"] } +serde = { version = "1.0.195", features = ["derive"] } thiserror = "1.0.48" prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus" } sc-client-api = { path = "../api" } diff --git a/substrate/client/transaction-pool/api/Cargo.toml b/substrate/client/transaction-pool/api/Cargo.toml index 93ee1a708bb..2522739cf88 100644 --- a/substrate/client/transaction-pool/api/Cargo.toml +++ b/substrate/client/transaction-pool/api/Cargo.toml @@ -16,11 +16,11 @@ async-trait = "0.1.74" codec = { package = "parity-scale-codec", version = "3.6.1" } futures = "0.3.21" log = "0.4.17" -serde = { version = "1.0.194", features = ["derive"] } +serde = { version = "1.0.195", features = ["derive"] } thiserror = "1.0.48" sp-blockchain = { path = "../../../primitives/blockchain" } sp-core = { path = "../../../primitives/core", default-features = false } sp-runtime = { path = "../../../primitives/runtime", default-features = false } [dev-dependencies] -serde_json = "1.0.110" +serde_json = "1.0.111" diff --git a/substrate/frame/beefy-mmr/Cargo.toml b/substrate/frame/beefy-mmr/Cargo.toml index cc240a05b65..f43e12d3ee7 100644 --- a/substrate/frame/beefy-mmr/Cargo.toml +++ b/substrate/frame/beefy-mmr/Cargo.toml @@ -16,7 +16,7 @@ array-bytes = { version = "6.1", optional = true } codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } log = { version = "0.4.17", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", optional = true } +serde = { version = "1.0.195", optional = true } binary-merkle-tree = { path = "../../utils/binary-merkle-tree", default-features = false } frame-support = { path = "../support", default-features = false } frame-system = { path = "../system", default-features = false } diff --git a/substrate/frame/beefy/Cargo.toml b/substrate/frame/beefy/Cargo.toml index 07e3d0d7e10..999e32ab450 100644 --- a/substrate/frame/beefy/Cargo.toml +++ b/substrate/frame/beefy/Cargo.toml @@ -15,7 +15,7 @@ workspace = true codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } log = { version = "0.4.17", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = ["derive", "serde"] } -serde = { version = "1.0.194", optional = true } +serde = { version = "1.0.195", optional = true } frame-support = { path = "../support", default-features = false } frame-system = { path = "../system", default-features = false } pallet-authorship = { path = "../authorship", default-features = false } diff --git a/substrate/frame/benchmarking/Cargo.toml b/substrate/frame/benchmarking/Cargo.toml index 6fc49c2ec1e..42001c2d08c 100644 --- a/substrate/frame/benchmarking/Cargo.toml +++ b/substrate/frame/benchmarking/Cargo.toml @@ -21,7 +21,7 @@ linregress = { version = "0.5.1", optional = true } log = { version = "0.4.17", default-features = false } paste = "1.0" scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", optional = true } +serde = { version = "1.0.195", optional = true } frame-support = { path = "../support", default-features = false } frame-support-procedural = { path = "../support/procedural", default-features = false } frame-system = { path = "../system", default-features = false } diff --git a/substrate/frame/contracts/proc-macro/Cargo.toml b/substrate/frame/contracts/proc-macro/Cargo.toml index 14733256466..1c9802f6fde 100644 --- a/substrate/frame/contracts/proc-macro/Cargo.toml +++ b/substrate/frame/contracts/proc-macro/Cargo.toml @@ -20,7 +20,7 @@ proc-macro = true [dependencies] proc-macro2 = "1.0.56" quote = "1.0.28" -syn = { version = "2.0.43", features = ["full"] } +syn = { version = "2.0.48", features = ["full"] } [dev-dependencies] diff --git a/substrate/frame/conviction-voting/Cargo.toml b/substrate/frame/conviction-voting/Cargo.toml index 7cd25562435..78f524e3e66 100644 --- a/substrate/frame/conviction-voting/Cargo.toml +++ b/substrate/frame/conviction-voting/Cargo.toml @@ -22,7 +22,7 @@ codec = { package = "parity-scale-codec", version = "3.6.1", default-features = "max-encoded-len", ] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", features = ["derive"], optional = true } +serde = { version = "1.0.195", features = ["derive"], optional = true } frame-benchmarking = { path = "../benchmarking", default-features = false, optional = true } frame-support = { path = "../support", default-features = false } frame-system = { path = "../system", default-features = false } diff --git a/substrate/frame/democracy/Cargo.toml b/substrate/frame/democracy/Cargo.toml index d17aba0d424..cecb1df60d7 100644 --- a/substrate/frame/democracy/Cargo.toml +++ b/substrate/frame/democracy/Cargo.toml @@ -20,7 +20,7 @@ codec = { package = "parity-scale-codec", version = "3.6.1", default-features = "derive", ] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", features = ["derive"], optional = true } +serde = { version = "1.0.195", features = ["derive"], optional = true } frame-benchmarking = { path = "../benchmarking", default-features = false, optional = true } frame-support = { path = "../support", default-features = false } frame-system = { path = "../system", default-features = false } diff --git a/substrate/frame/election-provider-support/solution-type/Cargo.toml b/substrate/frame/election-provider-support/solution-type/Cargo.toml index 212ce2e4f15..74f43310418 100644 --- a/substrate/frame/election-provider-support/solution-type/Cargo.toml +++ b/substrate/frame/election-provider-support/solution-type/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] proc-macro = true [dependencies] -syn = { version = "2.0.43", features = ["full", "visit"] } +syn = { version = "2.0.48", features = ["full", "visit"] } quote = "1.0.28" proc-macro2 = "1.0.56" proc-macro-crate = "2.0.1" diff --git a/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml b/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml index 4de44889382..e21b9536727 100644 --- a/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml +++ b/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml @@ -16,7 +16,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } honggfuzz = "0.5" rand = { version = "0.8", features = ["small_rng", "std"] } diff --git a/substrate/frame/message-queue/Cargo.toml b/substrate/frame/message-queue/Cargo.toml index 4b9215f6657..e3ab370727e 100644 --- a/substrate/frame/message-queue/Cargo.toml +++ b/substrate/frame/message-queue/Cargo.toml @@ -14,7 +14,7 @@ workspace = true [dependencies] codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", optional = true, features = ["derive"] } +serde = { version = "1.0.195", optional = true, features = ["derive"] } log = { version = "0.4.17", default-features = false } environmental = { version = "1.1.4", default-features = false } diff --git a/substrate/frame/mixnet/Cargo.toml b/substrate/frame/mixnet/Cargo.toml index b562c5cc056..ea8b1b00e49 100644 --- a/substrate/frame/mixnet/Cargo.toml +++ b/substrate/frame/mixnet/Cargo.toml @@ -22,7 +22,7 @@ frame-support = { default-features = false, path = "../support" } frame-system = { default-features = false, path = "../system" } log = { version = "0.4.17", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", default-features = false, features = ["derive"] } +serde = { version = "1.0.195", default-features = false, features = ["derive"] } sp-application-crypto = { default-features = false, path = "../../primitives/application-crypto" } sp-arithmetic = { default-features = false, path = "../../primitives/arithmetic" } sp-io = { default-features = false, path = "../../primitives/io" } diff --git a/substrate/frame/offences/Cargo.toml b/substrate/frame/offences/Cargo.toml index 46e9757a97c..cda247325ef 100644 --- a/substrate/frame/offences/Cargo.toml +++ b/substrate/frame/offences/Cargo.toml @@ -19,7 +19,7 @@ targets = ["x86_64-unknown-linux-gnu"] codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } log = { version = "0.4.17", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", optional = true } +serde = { version = "1.0.195", optional = true } frame-support = { path = "../support", default-features = false } frame-system = { path = "../system", default-features = false } pallet-balances = { path = "../balances", default-features = false } diff --git a/substrate/frame/referenda/Cargo.toml b/substrate/frame/referenda/Cargo.toml index 8edced5c520..d38be0d283e 100644 --- a/substrate/frame/referenda/Cargo.toml +++ b/substrate/frame/referenda/Cargo.toml @@ -21,7 +21,7 @@ codec = { package = "parity-scale-codec", version = "3.6.1", default-features = "derive", ] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", features = ["derive"], optional = true } +serde = { version = "1.0.195", features = ["derive"], optional = true } sp-arithmetic = { path = "../../primitives/arithmetic", default-features = false } frame-benchmarking = { path = "../benchmarking", default-features = false, optional = true } frame-support = { path = "../support", default-features = false } diff --git a/substrate/frame/remark/Cargo.toml b/substrate/frame/remark/Cargo.toml index e1899bac2aa..1570d2dba27 100644 --- a/substrate/frame/remark/Cargo.toml +++ b/substrate/frame/remark/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", optional = true } +serde = { version = "1.0.195", optional = true } frame-benchmarking = { path = "../benchmarking", default-features = false, optional = true } frame-support = { path = "../support", default-features = false } frame-system = { path = "../system", default-features = false } diff --git a/substrate/frame/staking/Cargo.toml b/substrate/frame/staking/Cargo.toml index 7e1ad492aa0..7e933ed951e 100644 --- a/substrate/frame/staking/Cargo.toml +++ b/substrate/frame/staking/Cargo.toml @@ -16,7 +16,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -serde = { version = "1.0.194", default-features = false, features = ["alloc", "derive"] } +serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive"] } codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = [ "derive", ] } diff --git a/substrate/frame/staking/reward-curve/Cargo.toml b/substrate/frame/staking/reward-curve/Cargo.toml index fcf2faeee53..0e13d4550f4 100644 --- a/substrate/frame/staking/reward-curve/Cargo.toml +++ b/substrate/frame/staking/reward-curve/Cargo.toml @@ -21,7 +21,7 @@ proc-macro = true proc-macro-crate = "2.0.1" proc-macro2 = "1.0.56" quote = "1.0.28" -syn = { version = "2.0.43", features = ["full", "visit"] } +syn = { version = "2.0.48", features = ["full", "visit"] } [dev-dependencies] sp-runtime = { path = "../../../primitives/runtime" } diff --git a/substrate/frame/state-trie-migration/Cargo.toml b/substrate/frame/state-trie-migration/Cargo.toml index 4f4960e05c4..e27d4c46926 100644 --- a/substrate/frame/state-trie-migration/Cargo.toml +++ b/substrate/frame/state-trie-migration/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false } log = { version = "0.4.17", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", optional = true } +serde = { version = "1.0.195", optional = true } thousands = { version = "0.2.0", optional = true } zstd = { version = "0.12.4", default-features = false, optional = true } frame-benchmarking = { path = "../benchmarking", default-features = false, optional = true } diff --git a/substrate/frame/support/Cargo.toml b/substrate/frame/support/Cargo.toml index 20a2c2e93e0..5c0c4091468 100644 --- a/substrate/frame/support/Cargo.toml +++ b/substrate/frame/support/Cargo.toml @@ -17,7 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] array-bytes = { version = "6.1", default-features = false } -serde = { version = "1.0.194", default-features = false, features = ["alloc", "derive"] } +serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive"] } codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive", "max-encoded-len"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } frame-metadata = { version = "16.0.0", default-features = false, features = ["current"] } @@ -46,7 +46,7 @@ sp-core-hashing-proc-macro = { path = "../../primitives/core/hashing/proc-macro" k256 = { version = "0.13.1", default-features = false, features = ["ecdsa"] } environmental = { version = "1.1.4", default-features = false } sp-genesis-builder = { path = "../../primitives/genesis-builder", default-features = false } -serde_json = { version = "1.0.110", default-features = false, features = ["alloc"] } +serde_json = { version = "1.0.111", default-features = false, features = ["alloc"] } docify = "0.2.6" static_assertions = "1.1.0" diff --git a/substrate/frame/support/procedural/Cargo.toml b/substrate/frame/support/procedural/Cargo.toml index 7c8b3f009d7..5e47f0dfeb0 100644 --- a/substrate/frame/support/procedural/Cargo.toml +++ b/substrate/frame/support/procedural/Cargo.toml @@ -24,7 +24,7 @@ cfg-expr = "0.15.5" itertools = "0.10.3" proc-macro2 = "1.0.56" quote = "1.0.28" -syn = { version = "2.0.43", features = ["full"] } +syn = { version = "2.0.48", features = ["full"] } frame-support-procedural-tools = { path = "tools" } macro_magic = { version = "0.5.0", features = ["proc_support"] } proc-macro-warning = { version = "1.0.0", default-features = false } diff --git a/substrate/frame/support/procedural/tools/Cargo.toml b/substrate/frame/support/procedural/tools/Cargo.toml index 4b75088c314..3305f2f5d51 100644 --- a/substrate/frame/support/procedural/tools/Cargo.toml +++ b/substrate/frame/support/procedural/tools/Cargo.toml @@ -18,5 +18,5 @@ targets = ["x86_64-unknown-linux-gnu"] proc-macro-crate = "2.0.1" proc-macro2 = "1.0.56" quote = "1.0.28" -syn = { version = "2.0.43", features = ["extra-traits", "full", "visit"] } +syn = { version = "2.0.48", features = ["extra-traits", "full", "visit"] } frame-support-procedural-tools-derive = { path = "derive" } diff --git a/substrate/frame/support/procedural/tools/derive/Cargo.toml b/substrate/frame/support/procedural/tools/derive/Cargo.toml index eeaeab9b829..d2d34d47714 100644 --- a/substrate/frame/support/procedural/tools/derive/Cargo.toml +++ b/substrate/frame/support/procedural/tools/derive/Cargo.toml @@ -20,4 +20,4 @@ proc-macro = true [dependencies] proc-macro2 = "1.0.56" quote = { version = "1.0.28", features = ["proc-macro"] } -syn = { version = "2.0.43", features = ["extra-traits", "full", "parsing", "proc-macro"] } +syn = { version = "2.0.48", features = ["extra-traits", "full", "parsing", "proc-macro"] } diff --git a/substrate/frame/support/test/Cargo.toml b/substrate/frame/support/test/Cargo.toml index bdc3622ad97..eac2dafbf00 100644 --- a/substrate/frame/support/test/Cargo.toml +++ b/substrate/frame/support/test/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] static_assertions = "1.1.0" -serde = { version = "1.0.194", default-features = false, features = ["derive"] } +serde = { version = "1.0.195", default-features = false, features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } frame-metadata = { version = "16.0.0", default-features = false, features = ["current"] } diff --git a/substrate/frame/support/test/pallet/Cargo.toml b/substrate/frame/support/test/pallet/Cargo.toml index 26628fb2bbe..48adbcab582 100644 --- a/substrate/frame/support/test/pallet/Cargo.toml +++ b/substrate/frame/support/test/pallet/Cargo.toml @@ -17,7 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", default-features = false, features = ["derive"] } +serde = { version = "1.0.195", default-features = false, features = ["derive"] } frame-support = { path = "../..", default-features = false } frame-system = { path = "../../../system", default-features = false } sp-runtime = { path = "../../../../primitives/runtime", default-features = false } diff --git a/substrate/frame/system/Cargo.toml b/substrate/frame/system/Cargo.toml index adc7b0faeb0..b0bab4ec756 100644 --- a/substrate/frame/system/Cargo.toml +++ b/substrate/frame/system/Cargo.toml @@ -20,7 +20,7 @@ cfg-if = "1.0" codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } log = { version = "0.4.17", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = ["derive", "serde"] } -serde = { version = "1.0.194", default-features = false, features = ["alloc", "derive"] } +serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive"] } frame-support = { path = "../support", default-features = false } sp-core = { path = "../../primitives/core", default-features = false, features = ["serde"] } sp-io = { path = "../../primitives/io", default-features = false } diff --git a/substrate/frame/tips/Cargo.toml b/substrate/frame/tips/Cargo.toml index 1d86c3d098b..2516e0e993d 100644 --- a/substrate/frame/tips/Cargo.toml +++ b/substrate/frame/tips/Cargo.toml @@ -19,7 +19,7 @@ targets = ["x86_64-unknown-linux-gnu"] codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } log = { version = "0.4.17", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", features = ["derive"], optional = true } +serde = { version = "1.0.195", features = ["derive"], optional = true } frame-benchmarking = { path = "../benchmarking", default-features = false, optional = true } frame-support = { path = "../support", default-features = false } frame-system = { path = "../system", default-features = false } diff --git a/substrate/frame/transaction-payment/Cargo.toml b/substrate/frame/transaction-payment/Cargo.toml index 923b1d30a92..d52e8e11c82 100644 --- a/substrate/frame/transaction-payment/Cargo.toml +++ b/substrate/frame/transaction-payment/Cargo.toml @@ -20,7 +20,7 @@ codec = { package = "parity-scale-codec", version = "3.6.1", default-features = "derive", ] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", optional = true } +serde = { version = "1.0.195", optional = true } frame-support = { path = "../support", default-features = false } frame-system = { path = "../system", default-features = false } sp-core = { path = "../../primitives/core", default-features = false } @@ -29,7 +29,7 @@ sp-runtime = { path = "../../primitives/runtime", default-features = false } sp-std = { path = "../../primitives/std", default-features = false } [dev-dependencies] -serde_json = "1.0.110" +serde_json = "1.0.111" pallet-balances = { path = "../balances" } [features] diff --git a/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml b/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml index 324ae27dac7..0cd0cea59e6 100644 --- a/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml +++ b/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml @@ -30,10 +30,10 @@ frame-benchmarking = { path = "../../benchmarking", default-features = false, op # Other dependencies codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", optional = true } +serde = { version = "1.0.195", optional = true } [dev-dependencies] -serde_json = "1.0.110" +serde_json = "1.0.111" sp-storage = { path = "../../../primitives/storage", default-features = false } diff --git a/substrate/frame/transaction-storage/Cargo.toml b/substrate/frame/transaction-storage/Cargo.toml index faa9189ec63..26f9f64fe35 100644 --- a/substrate/frame/transaction-storage/Cargo.toml +++ b/substrate/frame/transaction-storage/Cargo.toml @@ -19,7 +19,7 @@ targets = ["x86_64-unknown-linux-gnu"] array-bytes = { version = "6.1", optional = true } codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", optional = true } +serde = { version = "1.0.195", optional = true } frame-benchmarking = { path = "../benchmarking", default-features = false, optional = true } frame-support = { path = "../support", default-features = false } frame-system = { path = "../system", default-features = false } diff --git a/substrate/frame/treasury/Cargo.toml b/substrate/frame/treasury/Cargo.toml index 120955c6f3b..01eb7c55a0a 100644 --- a/substrate/frame/treasury/Cargo.toml +++ b/substrate/frame/treasury/Cargo.toml @@ -23,7 +23,7 @@ codec = { package = "parity-scale-codec", version = "3.6.1", default-features = docify = "0.2.0" impl-trait-for-tuples = "0.2.2" scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", features = ["derive"], optional = true } +serde = { version = "1.0.195", features = ["derive"], optional = true } frame-benchmarking = { path = "../benchmarking", default-features = false, optional = true } frame-support = { path = "../support", default-features = false } frame-system = { path = "../system", default-features = false } diff --git a/substrate/primitives/api/proc-macro/Cargo.toml b/substrate/primitives/api/proc-macro/Cargo.toml index 84c93aecd2e..e16f4fb7bf5 100644 --- a/substrate/primitives/api/proc-macro/Cargo.toml +++ b/substrate/primitives/api/proc-macro/Cargo.toml @@ -20,7 +20,7 @@ proc-macro = true [dependencies] quote = "1.0.28" -syn = { version = "2.0.43", features = ["extra-traits", "fold", "full", "visit"] } +syn = { version = "2.0.48", features = ["extra-traits", "fold", "full", "visit"] } proc-macro2 = "1.0.56" blake2 = { version = "0.10.4", default-features = false } proc-macro-crate = "2.0.1" diff --git a/substrate/primitives/application-crypto/Cargo.toml b/substrate/primitives/application-crypto/Cargo.toml index b4491a98476..d8aa2689aa2 100644 --- a/substrate/primitives/application-crypto/Cargo.toml +++ b/substrate/primitives/application-crypto/Cargo.toml @@ -21,7 +21,7 @@ targets = ["x86_64-unknown-linux-gnu"] sp-core = { path = "../core", default-features = false } codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", default-features = false, optional = true, features = ["alloc", "derive"] } +serde = { version = "1.0.195", default-features = false, optional = true, features = ["alloc", "derive"] } sp-std = { path = "../std", default-features = false } sp-io = { path = "../io", default-features = false } diff --git a/substrate/primitives/arithmetic/Cargo.toml b/substrate/primitives/arithmetic/Cargo.toml index 3f44fe6594f..47d2902e267 100644 --- a/substrate/primitives/arithmetic/Cargo.toml +++ b/substrate/primitives/arithmetic/Cargo.toml @@ -24,7 +24,7 @@ codec = { package = "parity-scale-codec", version = "3.6.1", default-features = integer-sqrt = "0.1.2" num-traits = { version = "0.2.17", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", default-features = false, features = ["alloc", "derive"], optional = true } +serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive"], optional = true } static_assertions = "1.1.0" sp-std = { path = "../std", default-features = false } diff --git a/substrate/primitives/consensus/babe/Cargo.toml b/substrate/primitives/consensus/babe/Cargo.toml index 751866f035f..e48b4b4817b 100644 --- a/substrate/primitives/consensus/babe/Cargo.toml +++ b/substrate/primitives/consensus/babe/Cargo.toml @@ -19,7 +19,7 @@ targets = ["x86_64-unknown-linux-gnu"] async-trait = { version = "0.1.74", optional = true } codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", default-features = false, features = ["alloc", "derive"], optional = true } +serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive"], optional = true } sp-api = { path = "../../api", default-features = false } sp-application-crypto = { path = "../../application-crypto", default-features = false } sp-consensus-slots = { path = "../slots", default-features = false } diff --git a/substrate/primitives/consensus/beefy/Cargo.toml b/substrate/primitives/consensus/beefy/Cargo.toml index 68e0db2f5f6..93a9be17747 100644 --- a/substrate/primitives/consensus/beefy/Cargo.toml +++ b/substrate/primitives/consensus/beefy/Cargo.toml @@ -17,7 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", default-features = false, optional = true, features = ["alloc", "derive"] } +serde = { version = "1.0.195", default-features = false, optional = true, features = ["alloc", "derive"] } sp-api = { path = "../../api", default-features = false } sp-application-crypto = { path = "../../application-crypto", default-features = false } sp-core = { path = "../../core", default-features = false } diff --git a/substrate/primitives/consensus/grandpa/Cargo.toml b/substrate/primitives/consensus/grandpa/Cargo.toml index 495a37aef69..be22f5b23df 100644 --- a/substrate/primitives/consensus/grandpa/Cargo.toml +++ b/substrate/primitives/consensus/grandpa/Cargo.toml @@ -21,7 +21,7 @@ codec = { package = "parity-scale-codec", version = "3.6.1", default-features = grandpa = { package = "finality-grandpa", version = "0.16.2", default-features = false, features = ["derive-codec"] } log = { version = "0.4.17", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", features = ["alloc", "derive"], default-features = false, optional = true } +serde = { version = "1.0.195", features = ["alloc", "derive"], default-features = false, optional = true } sp-api = { path = "../../api", default-features = false } sp-application-crypto = { path = "../../application-crypto", default-features = false } sp-core = { path = "../../core", default-features = false } diff --git a/substrate/primitives/consensus/sassafras/Cargo.toml b/substrate/primitives/consensus/sassafras/Cargo.toml index 3db7bdbcee1..6d44bc6c5a8 100644 --- a/substrate/primitives/consensus/sassafras/Cargo.toml +++ b/substrate/primitives/consensus/sassafras/Cargo.toml @@ -20,7 +20,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] scale-codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", default-features = false, features = ["derive"], optional = true } +serde = { version = "1.0.195", default-features = false, features = ["derive"], optional = true } sp-api = { path = "../../api", default-features = false } sp-application-crypto = { path = "../../application-crypto", default-features = false, features = ["bandersnatch-experimental"] } sp-consensus-slots = { path = "../slots", default-features = false } diff --git a/substrate/primitives/core/Cargo.toml b/substrate/primitives/core/Cargo.toml index 1dbb5761ea8..73de8057d80 100644 --- a/substrate/primitives/core/Cargo.toml +++ b/substrate/primitives/core/Cargo.toml @@ -19,7 +19,7 @@ targets = ["x86_64-unknown-linux-gnu"] codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive", "max-encoded-len"] } scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } log = { version = "0.4.17", default-features = false } -serde = { version = "1.0.194", optional = true, default-features = false, features = ["alloc", "derive"] } +serde = { version = "1.0.195", optional = true, default-features = false, features = ["alloc", "derive"] } bounded-collections = { version = "0.1.8", default-features = false } primitive-types = { version = "0.12.0", default-features = false, features = ["codec", "scale-info"] } impl-serde = { version = "0.4.0", default-features = false, optional = true } @@ -63,7 +63,7 @@ bandersnatch_vrfs = { git = "https://github.com/w3f/ring-vrf", rev = "e9782f9", [dev-dependencies] criterion = "0.4.0" -serde_json = "1.0.110" +serde_json = "1.0.111" lazy_static = "1.4.0" regex = "1.6.0" sp-core-hashing-proc-macro = { path = "hashing/proc-macro" } diff --git a/substrate/primitives/core/hashing/proc-macro/Cargo.toml b/substrate/primitives/core/hashing/proc-macro/Cargo.toml index 1ffbb4d1aaf..5c215bc7799 100644 --- a/substrate/primitives/core/hashing/proc-macro/Cargo.toml +++ b/substrate/primitives/core/hashing/proc-macro/Cargo.toml @@ -20,5 +20,5 @@ proc-macro = true [dependencies] quote = "1.0.28" -syn = { version = "2.0.43", features = ["full", "parsing"] } +syn = { version = "2.0.48", features = ["full", "parsing"] } sp-core-hashing = { path = "..", default-features = false } diff --git a/substrate/primitives/debug-derive/Cargo.toml b/substrate/primitives/debug-derive/Cargo.toml index bd1e0d12d6e..b7a65d658cf 100644 --- a/substrate/primitives/debug-derive/Cargo.toml +++ b/substrate/primitives/debug-derive/Cargo.toml @@ -20,7 +20,7 @@ proc-macro = true [dependencies] quote = "1.0.28" -syn = "2.0.43" +syn = "2.0.48" proc-macro2 = "1.0.56" [features] diff --git a/substrate/primitives/genesis-builder/Cargo.toml b/substrate/primitives/genesis-builder/Cargo.toml index 886ddb4ffd3..42d6c8c3d65 100644 --- a/substrate/primitives/genesis-builder/Cargo.toml +++ b/substrate/primitives/genesis-builder/Cargo.toml @@ -19,7 +19,7 @@ targets = ["x86_64-unknown-linux-gnu"] sp-api = { path = "../api", default-features = false } sp-runtime = { path = "../runtime", default-features = false } sp-std = { path = "../std", default-features = false } -serde_json = { version = "1.0.110", default-features = false, features = ["alloc"] } +serde_json = { version = "1.0.111", default-features = false, features = ["alloc"] } [features] default = ["std"] diff --git a/substrate/primitives/merkle-mountain-range/Cargo.toml b/substrate/primitives/merkle-mountain-range/Cargo.toml index e6143ff6c42..c0d69a2c4f5 100644 --- a/substrate/primitives/merkle-mountain-range/Cargo.toml +++ b/substrate/primitives/merkle-mountain-range/Cargo.toml @@ -19,7 +19,7 @@ codec = { package = "parity-scale-codec", version = "3.6.1", default-features = scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } log = { version = "0.4.17", default-features = false } mmr-lib = { package = "ckb-merkle-mountain-range", version = "0.5.2", default-features = false } -serde = { version = "1.0.194", features = ["alloc", "derive"], default-features = false, optional = true } +serde = { version = "1.0.195", features = ["alloc", "derive"], default-features = false, optional = true } sp-api = { path = "../api", default-features = false } sp-core = { path = "../core", default-features = false } sp-debug-derive = { path = "../debug-derive", default-features = false } diff --git a/substrate/primitives/npos-elections/Cargo.toml b/substrate/primitives/npos-elections/Cargo.toml index 04c4a475b7a..5d7e8704f4c 100644 --- a/substrate/primitives/npos-elections/Cargo.toml +++ b/substrate/primitives/npos-elections/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", default-features = false, features = ["alloc", "derive"], optional = true } +serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive"], optional = true } sp-arithmetic = { path = "../arithmetic", default-features = false } sp-core = { path = "../core", default-features = false } sp-runtime = { path = "../runtime", default-features = false } diff --git a/substrate/primitives/npos-elections/fuzzer/Cargo.toml b/substrate/primitives/npos-elections/fuzzer/Cargo.toml index 9ea80d5030e..29dfa809fbe 100644 --- a/substrate/primitives/npos-elections/fuzzer/Cargo.toml +++ b/substrate/primitives/npos-elections/fuzzer/Cargo.toml @@ -17,7 +17,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } honggfuzz = "0.5" rand = { version = "0.8", features = ["small_rng", "std"] } sp-npos-elections = { path = ".." } diff --git a/substrate/primitives/rpc/Cargo.toml b/substrate/primitives/rpc/Cargo.toml index 5ff2db981da..07bb3bf7293 100644 --- a/substrate/primitives/rpc/Cargo.toml +++ b/substrate/primitives/rpc/Cargo.toml @@ -17,8 +17,8 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] rustc-hash = "1.1.0" -serde = { version = "1.0.194", features = ["derive"] } +serde = { version = "1.0.195", features = ["derive"] } sp-core = { path = "../core" } [dev-dependencies] -serde_json = "1.0.110" +serde_json = "1.0.111" diff --git a/substrate/primitives/runtime-interface/proc-macro/Cargo.toml b/substrate/primitives/runtime-interface/proc-macro/Cargo.toml index 0b0291b1bd3..b58e6a7b725 100644 --- a/substrate/primitives/runtime-interface/proc-macro/Cargo.toml +++ b/substrate/primitives/runtime-interface/proc-macro/Cargo.toml @@ -24,4 +24,4 @@ proc-macro-crate = "2.0.1" proc-macro2 = "1.0.56" quote = "1.0.28" expander = "2.0.0" -syn = { version = "2.0.43", features = ["extra-traits", "fold", "full", "visit"] } +syn = { version = "2.0.48", features = ["extra-traits", "fold", "full", "visit"] } diff --git a/substrate/primitives/runtime/Cargo.toml b/substrate/primitives/runtime/Cargo.toml index 988a98a2df0..448aad39ec9 100644 --- a/substrate/primitives/runtime/Cargo.toml +++ b/substrate/primitives/runtime/Cargo.toml @@ -25,7 +25,7 @@ log = { version = "0.4.17", default-features = false } paste = "1.0" rand = { version = "0.8.5", optional = true } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", default-features = false, features = ["alloc", "derive"], optional = true } +serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive"], optional = true } sp-application-crypto = { path = "../application-crypto", default-features = false } sp-arithmetic = { path = "../arithmetic", default-features = false } sp-core = { path = "../core", default-features = false } @@ -38,7 +38,7 @@ simple-mermaid = { git = "https://github.com/kianenigma/simple-mermaid.git", rev [dev-dependencies] rand = "0.8.5" -serde_json = "1.0.110" +serde_json = "1.0.111" zstd = { version = "0.12.4", default-features = false } sp-api = { path = "../api" } sp-state-machine = { path = "../state-machine" } diff --git a/substrate/primitives/staking/Cargo.toml b/substrate/primitives/staking/Cargo.toml index c10dd00a730..5ffe6fbeaf5 100644 --- a/substrate/primitives/staking/Cargo.toml +++ b/substrate/primitives/staking/Cargo.toml @@ -16,7 +16,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -serde = { version = "1.0.194", default-features = false, features = ["alloc", "derive"], optional = true } +serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive"], optional = true } codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } impl-trait-for-tuples = "0.2.2" diff --git a/substrate/primitives/storage/Cargo.toml b/substrate/primitives/storage/Cargo.toml index 1689c874aba..32f59b04a12 100644 --- a/substrate/primitives/storage/Cargo.toml +++ b/substrate/primitives/storage/Cargo.toml @@ -20,7 +20,7 @@ targets = ["x86_64-unknown-linux-gnu"] codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } impl-serde = { version = "0.4.0", optional = true, default-features = false } ref-cast = "1.0.0" -serde = { version = "1.0.194", default-features = false, features = ["alloc", "derive"], optional = true } +serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive"], optional = true } sp-debug-derive = { path = "../debug-derive", default-features = false } sp-std = { path = "../std", default-features = false } diff --git a/substrate/primitives/test-primitives/Cargo.toml b/substrate/primitives/test-primitives/Cargo.toml index 48aa27a68b2..3649217cf74 100644 --- a/substrate/primitives/test-primitives/Cargo.toml +++ b/substrate/primitives/test-primitives/Cargo.toml @@ -17,7 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", default-features = false, features = ["derive"], optional = true } +serde = { version = "1.0.195", default-features = false, features = ["derive"], optional = true } sp-application-crypto = { path = "../application-crypto", default-features = false } sp-core = { path = "../core", default-features = false } sp-runtime = { path = "../runtime", default-features = false } diff --git a/substrate/primitives/version/Cargo.toml b/substrate/primitives/version/Cargo.toml index 8d49d974d83..1ceda4e700f 100644 --- a/substrate/primitives/version/Cargo.toml +++ b/substrate/primitives/version/Cargo.toml @@ -21,7 +21,7 @@ codec = { package = "parity-scale-codec", version = "3.6.1", default-features = impl-serde = { version = "0.4.0", default-features = false, optional = true } parity-wasm = { version = "0.45", optional = true } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", default-features = false, features = ["alloc", "derive"], optional = true } +serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive"], optional = true } thiserror = { version = "1.0.48", optional = true } sp-core-hashing-proc-macro = { path = "../core/hashing/proc-macro" } sp-runtime = { path = "../runtime", default-features = false } diff --git a/substrate/primitives/version/proc-macro/Cargo.toml b/substrate/primitives/version/proc-macro/Cargo.toml index a71dce56eec..adf70dbd166 100644 --- a/substrate/primitives/version/proc-macro/Cargo.toml +++ b/substrate/primitives/version/proc-macro/Cargo.toml @@ -22,7 +22,7 @@ proc-macro = true codec = { package = "parity-scale-codec", version = "3.6.1", features = ["derive"] } proc-macro2 = "1.0.56" quote = "1.0.28" -syn = { version = "2.0.43", features = ["extra-traits", "fold", "full", "visit"] } +syn = { version = "2.0.48", features = ["extra-traits", "fold", "full", "visit"] } [dev-dependencies] sp-version = { path = ".." } diff --git a/substrate/primitives/weights/Cargo.toml b/substrate/primitives/weights/Cargo.toml index 45c15fb3b9b..d89182b6642 100644 --- a/substrate/primitives/weights/Cargo.toml +++ b/substrate/primitives/weights/Cargo.toml @@ -19,7 +19,7 @@ targets = ["x86_64-unknown-linux-gnu"] bounded-collections = { version = "0.1.4", default-features = false } codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.194", default-features = false, optional = true, features = ["alloc", "derive"] } +serde = { version = "1.0.195", default-features = false, optional = true, features = ["alloc", "derive"] } smallvec = "1.11.0" sp-arithmetic = { path = "../arithmetic", default-features = false } sp-debug-derive = { path = "../debug-derive", default-features = false } diff --git a/substrate/scripts/ci/node-template-release/Cargo.toml b/substrate/scripts/ci/node-template-release/Cargo.toml index 7ca84c17005..32210de73e6 100644 --- a/substrate/scripts/ci/node-template-release/Cargo.toml +++ b/substrate/scripts/ci/node-template-release/Cargo.toml @@ -14,7 +14,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } flate2 = "1.0" fs_extra = "1.3" glob = "0.3" diff --git a/substrate/test-utils/client/Cargo.toml b/substrate/test-utils/client/Cargo.toml index 71f2c6a136e..79071e19e28 100644 --- a/substrate/test-utils/client/Cargo.toml +++ b/substrate/test-utils/client/Cargo.toml @@ -20,8 +20,8 @@ array-bytes = "6.1" async-trait = "0.1.74" codec = { package = "parity-scale-codec", version = "3.6.1" } futures = "0.3.21" -serde = "1.0.194" -serde_json = "1.0.110" +serde = "1.0.195" +serde_json = "1.0.111" sc-client-api = { path = "../../client/api" } sc-client-db = { path = "../../client/db", default-features = false, features = [ "test-helpers", diff --git a/substrate/test-utils/runtime/Cargo.toml b/substrate/test-utils/runtime/Cargo.toml index 294d3b7aa62..1eb50771a2c 100644 --- a/substrate/test-utils/runtime/Cargo.toml +++ b/substrate/test-utils/runtime/Cargo.toml @@ -61,8 +61,8 @@ sp-consensus = { path = "../../primitives/consensus/common" } substrate-test-runtime-client = { path = "client" } sp-tracing = { path = "../../primitives/tracing" } json-patch = { version = "1.0.0", default-features = false } -serde = { version = "1.0.194", features = ["alloc", "derive"], default-features = false } -serde_json = { version = "1.0.110", default-features = false, features = ["alloc"] } +serde = { version = "1.0.195", features = ["alloc", "derive"], default-features = false } +serde_json = { version = "1.0.111", default-features = false, features = ["alloc"] } [build-dependencies] substrate-wasm-builder = { path = "../../utils/wasm-builder", optional = true } diff --git a/substrate/utils/frame/benchmarking-cli/Cargo.toml b/substrate/utils/frame/benchmarking-cli/Cargo.toml index aea4789b82f..02cb6ebc303 100644 --- a/substrate/utils/frame/benchmarking-cli/Cargo.toml +++ b/substrate/utils/frame/benchmarking-cli/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] array-bytes = "6.1" chrono = "0.4" -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.6.1" } comfy-table = { version = "7.0.1", default-features = false } handlebars = "4.2.2" @@ -29,8 +29,8 @@ linked-hash-map = "0.5.4" log = "0.4.17" rand = { version = "0.8.5", features = ["small_rng"] } rand_pcg = "0.3.1" -serde = "1.0.194" -serde_json = "1.0.110" +serde = "1.0.195" +serde_json = "1.0.111" thiserror = "1.0.48" thousands = "0.2.0" frame-benchmarking = { path = "../../../frame/benchmarking" } diff --git a/substrate/utils/frame/frame-utilities-cli/Cargo.toml b/substrate/utils/frame/frame-utilities-cli/Cargo.toml index d6297f890a4..96c43aee070 100644 --- a/substrate/utils/frame/frame-utilities-cli/Cargo.toml +++ b/substrate/utils/frame/frame-utilities-cli/Cargo.toml @@ -14,7 +14,7 @@ readme = "README.md" workspace = true [dependencies] -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } frame-support = { path = "../../../frame/support" } frame-system = { path = "../../../frame/system" } sc-cli = { path = "../../../client/cli" } diff --git a/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml b/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml index 747f25fecec..07e74a59a6b 100644 --- a/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml +++ b/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml @@ -17,4 +17,4 @@ kitchensink-runtime = { path = "../../../../bin/node/runtime" } generate-bags = { path = ".." } # third-party -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } diff --git a/substrate/utils/frame/remote-externalities/Cargo.toml b/substrate/utils/frame/remote-externalities/Cargo.toml index c7af146fc3d..ba0e8e869cc 100644 --- a/substrate/utils/frame/remote-externalities/Cargo.toml +++ b/substrate/utils/frame/remote-externalities/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] jsonrpsee = { version = "0.16.2", features = ["http-client"] } codec = { package = "parity-scale-codec", version = "3.6.1" } log = "0.4.17" -serde = "1.0.194" +serde = "1.0.195" sp-core = { path = "../../../primitives/core" } sp-state-machine = { path = "../../../primitives/state-machine" } sp-io = { path = "../../../primitives/io" } diff --git a/substrate/utils/frame/rpc/state-trie-migration-rpc/Cargo.toml b/substrate/utils/frame/rpc/state-trie-migration-rpc/Cargo.toml index c387bc47842..6cd99e5a6fe 100644 --- a/substrate/utils/frame/rpc/state-trie-migration-rpc/Cargo.toml +++ b/substrate/utils/frame/rpc/state-trie-migration-rpc/Cargo.toml @@ -32,4 +32,4 @@ sc-rpc-api = { path = "../../../../client/rpc-api" } sp-runtime = { path = "../../../../primitives/runtime" } [dev-dependencies] -serde_json = "1.0.110" +serde_json = "1.0.111" diff --git a/substrate/utils/frame/try-runtime/cli/Cargo.toml b/substrate/utils/frame/try-runtime/cli/Cargo.toml index f90cdd1af8e..4f09a34fae7 100644 --- a/substrate/utils/frame/try-runtime/cli/Cargo.toml +++ b/substrate/utils/frame/try-runtime/cli/Cargo.toml @@ -38,12 +38,12 @@ frame-try-runtime = { path = "../../../../frame/try-runtime", optional = true } substrate-rpc-client = { path = "../../rpc/client" } async-trait = "0.1.74" -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.13", features = ["derive"] } hex = { version = "0.4.3", default-features = false } log = "0.4.17" parity-scale-codec = "3.6.1" -serde = "1.0.194" -serde_json = "1.0.110" +serde = "1.0.195" +serde_json = "1.0.111" zstd = { version = "0.12.4", default-features = false } [dev-dependencies] -- GitLab From 745c02c59a6c0e828752286b411e80043d9436ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sun, 7 Jan 2024 16:49:34 +0100 Subject: [PATCH 006/392] pallet-contracts-fixtures: Only build RISCV when the feature is enabled (#2870) This disables building the RISCV fixtures by default. They still require a custom build rustc version. When there are actual tests for RISCV, the feature can be enabled in CI. Also fixes some unwraps that assume again that people are using rustup... --- substrate/frame/contracts/fixtures/Cargo.toml | 4 ++++ substrate/frame/contracts/fixtures/build.rs | 14 ++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/substrate/frame/contracts/fixtures/Cargo.toml b/substrate/frame/contracts/fixtures/Cargo.toml index 565adc6f6e8..58f20f0b8f5 100644 --- a/substrate/frame/contracts/fixtures/Cargo.toml +++ b/substrate/frame/contracts/fixtures/Cargo.toml @@ -23,3 +23,7 @@ toml = "0.8.2" twox-hash = "1.6.3" polkavm-linker = "0.3.0" anyhow = "1.0.0" + +[features] +# Enable experimental RISCV fixtures build +riscv-experimental = [] diff --git a/substrate/frame/contracts/fixtures/build.rs b/substrate/frame/contracts/fixtures/build.rs index de95d199b44..84eb4219c25 100644 --- a/substrate/frame/contracts/fixtures/build.rs +++ b/substrate/frame/contracts/fixtures/build.rs @@ -16,7 +16,7 @@ // limitations under the License. //! Compile contracts to wasm and RISC-V binaries. -use anyhow::{bail, format_err, Context, Result}; +use anyhow::{bail, Context, Result}; use parity_wasm::elements::{deserialize_file, serialize_to_file, Internal}; use std::{ env, fs, @@ -91,6 +91,7 @@ impl Entry { } /// Return the name of the RISC-V polkavm file. + #[cfg(feature = "riscv-experimental")] fn out_riscv_filename(&self) -> String { format!("{}.polkavm", self.name()) } @@ -231,6 +232,7 @@ fn post_process_wasm(input_path: &Path, output_path: &Path) -> Result<()> { } /// Build contracts for RISC-V. +#[cfg(feature = "riscv-experimental")] fn invoke_riscv_build(current_dir: &Path) -> Result<()> { let encoded_rustflags = ["-Crelocation-model=pie", "-Clink-arg=--emit-relocs", "-Clink-arg=-Tmemory.ld"] @@ -241,10 +243,10 @@ fn invoke_riscv_build(current_dir: &Path) -> Result<()> { let build_res = Command::new(env::var("CARGO")?) .current_dir(current_dir) .env_clear() - .env("PATH", env::var("PATH").unwrap()) + .env("PATH", env::var("PATH").unwrap_or_default()) .env("CARGO_ENCODED_RUSTFLAGS", encoded_rustflags) .env("RUSTUP_TOOLCHAIN", "rve-nightly") - .env("RUSTUP_HOME", env::var("RUSTUP_HOME").unwrap()) + .env("RUSTUP_HOME", env::var("RUSTUP_HOME").unwrap_or_default()) .args(["build", "--release", "--target=riscv32em-unknown-none-elf"]) .output() .expect("failed to execute process"); @@ -265,12 +267,13 @@ fn invoke_riscv_build(current_dir: &Path) -> Result<()> { bail!("Failed to build contracts"); } /// Post-process the compiled wasm contracts. +#[cfg(feature = "riscv-experimental")] fn post_process_riscv(input_path: &Path, output_path: &Path) -> Result<()> { let mut config = polkavm_linker::Config::default(); config.set_strip(true); let orig = fs::read(input_path).with_context(|| format!("Failed to read {:?}", input_path))?; let linked = polkavm_linker::program_from_elf(config, orig.as_ref()) - .map_err(|err| format_err!("Failed to link polkavm program: {}", err))?; + .map_err(|err| anyhow::format_err!("Failed to link polkavm program: {}", err))?; fs::write(output_path, linked.as_bytes()).map_err(Into::into) } @@ -283,6 +286,7 @@ fn write_output(build_dir: &Path, out_dir: &Path, entries: Vec) -> Result &out_dir.join(&wasm_output), )?; + #[cfg(feature = "riscv-experimental")] post_process_riscv( &build_dir.join("target/riscv32em-unknown-none-elf/release").join(entry.name()), &out_dir.join(entry.out_riscv_filename()), @@ -335,6 +339,8 @@ fn main() -> Result<()> { )?; invoke_wasm_build(tmp_dir_path)?; + + #[cfg(feature = "riscv-experimental")] invoke_riscv_build(tmp_dir_path)?; write_output(tmp_dir_path, &out_dir, entries)?; -- GitLab From 82327494bc9e73f35ca024750e41ac6749d2b498 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 12:31:19 +0000 Subject: [PATCH 007/392] Bump proc-macro-crate from 2.0.1 to 3.0.0 (#2876) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [proc-macro-crate](https://github.com/bkchr/proc-macro-crate) from 2.0.1 to 3.0.0.
Release notes

Sourced from proc-macro-crate's releases.

v3.0.0

What's Changed

Full Changelog: https://github.com/bkchr/proc-macro-crate/compare/v2.0.1...v3.0.0

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=proc-macro-crate&package-manager=cargo&previous-version=2.0.1&new-version=3.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 40 ++++++++++++------- .../parachain-system/proc-macro/Cargo.toml | 2 +- polkadot/node/gum/proc-macro/Cargo.toml | 2 +- substrate/client/chain-spec/derive/Cargo.toml | 2 +- .../client/tracing/proc-macro/Cargo.toml | 2 +- .../solution-type/Cargo.toml | 2 +- .../frame/staking/reward-curve/Cargo.toml | 2 +- .../frame/support/procedural/tools/Cargo.toml | 2 +- .../primitives/api/proc-macro/Cargo.toml | 2 +- .../runtime-interface/proc-macro/Cargo.toml | 2 +- 10 files changed, 34 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e2e1dfdb0e..7a718610bd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3930,7 +3930,7 @@ dependencies = [ name = "cumulus-pallet-parachain-system-proc-macro" version = "0.1.0" dependencies = [ - "proc-macro-crate 2.0.1", + "proc-macro-crate 3.0.0", "proc-macro2", "quote", "syn 2.0.48", @@ -5560,7 +5560,7 @@ dependencies = [ "frame-election-provider-support", "frame-support", "parity-scale-codec", - "proc-macro-crate 2.0.1", + "proc-macro-crate 3.0.0", "proc-macro2", "quote", "scale-info", @@ -5726,7 +5726,7 @@ name = "frame-support-procedural-tools" version = "4.0.0-dev" dependencies = [ "frame-support-procedural-tools-derive", - "proc-macro-crate 2.0.1", + "proc-macro-crate 3.0.0", "proc-macro2", "quote", "syn 2.0.48", @@ -10833,7 +10833,7 @@ dependencies = [ name = "pallet-staking-reward-curve" version = "4.0.0-dev" dependencies = [ - "proc-macro-crate 2.0.1", + "proc-macro-crate 3.0.0", "proc-macro2", "quote", "sp-runtime", @@ -14049,12 +14049,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a" +checksum = "6b2685dd208a3771337d8d386a89840f0f43cd68be8dae90a5f8c2384effc9cd" dependencies = [ - "toml_datetime", - "toml_edit 0.20.2", + "toml_edit 0.21.0", ] [[package]] @@ -15431,7 +15430,7 @@ dependencies = [ name = "sc-chain-spec-derive" version = "4.0.0-dev" dependencies = [ - "proc-macro-crate 2.0.1", + "proc-macro-crate 3.0.0", "proc-macro2", "quote", "syn 2.0.48", @@ -16687,7 +16686,7 @@ dependencies = [ name = "sc-tracing-proc-macro" version = "4.0.0-dev" dependencies = [ - "proc-macro-crate 2.0.1", + "proc-macro-crate 3.0.0", "proc-macro2", "quote", "syn 2.0.48", @@ -17985,7 +17984,7 @@ dependencies = [ "assert_matches", "blake2 0.10.6", "expander 2.0.0", - "proc-macro-crate 2.0.1", + "proc-macro-crate 3.0.0", "proc-macro2", "quote", "syn 2.0.48", @@ -18661,7 +18660,7 @@ version = "11.0.0" dependencies = [ "Inflector", "expander 2.0.0", - "proc-macro-crate 2.0.1", + "proc-macro-crate 3.0.0", "proc-macro2", "quote", "syn 2.0.48", @@ -20327,9 +20326,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", ] @@ -20360,6 +20359,17 @@ dependencies = [ "winnow", ] +[[package]] +name = "toml_edit" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +dependencies = [ + "indexmap 2.0.0", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.4.13" @@ -20461,7 +20471,7 @@ version = "1.0.0" dependencies = [ "assert_matches", "expander 2.0.0", - "proc-macro-crate 2.0.1", + "proc-macro-crate 3.0.0", "proc-macro2", "quote", "syn 2.0.48", diff --git a/cumulus/pallets/parachain-system/proc-macro/Cargo.toml b/cumulus/pallets/parachain-system/proc-macro/Cargo.toml index 2861a51d13c..bbef5d05579 100644 --- a/cumulus/pallets/parachain-system/proc-macro/Cargo.toml +++ b/cumulus/pallets/parachain-system/proc-macro/Cargo.toml @@ -16,7 +16,7 @@ proc-macro = true syn = "2.0.48" proc-macro2 = "1.0.64" quote = "1.0.33" -proc-macro-crate = "2.0.1" +proc-macro-crate = "3.0.0" [features] default = ["std"] diff --git a/polkadot/node/gum/proc-macro/Cargo.toml b/polkadot/node/gum/proc-macro/Cargo.toml index 174077f480a..1f9c5b1b918 100644 --- a/polkadot/node/gum/proc-macro/Cargo.toml +++ b/polkadot/node/gum/proc-macro/Cargo.toml @@ -19,7 +19,7 @@ proc-macro = true syn = { version = "2.0.48", features = ["extra-traits", "full"] } quote = "1.0.28" proc-macro2 = "1.0.56" -proc-macro-crate = "2.0.1" +proc-macro-crate = "3.0.0" expander = "2.0.0" [dev-dependencies] diff --git a/substrate/client/chain-spec/derive/Cargo.toml b/substrate/client/chain-spec/derive/Cargo.toml index 8f8c2c0de2d..f9e291f897c 100644 --- a/substrate/client/chain-spec/derive/Cargo.toml +++ b/substrate/client/chain-spec/derive/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] proc-macro = true [dependencies] -proc-macro-crate = "2.0.1" +proc-macro-crate = "3.0.0" proc-macro2 = "1.0.56" quote = "1.0.28" syn = "2.0.48" diff --git a/substrate/client/tracing/proc-macro/Cargo.toml b/substrate/client/tracing/proc-macro/Cargo.toml index ff43f1ccb90..c293c1834e8 100644 --- a/substrate/client/tracing/proc-macro/Cargo.toml +++ b/substrate/client/tracing/proc-macro/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] proc-macro = true [dependencies] -proc-macro-crate = "2.0.1" +proc-macro-crate = "3.0.0" proc-macro2 = "1.0.56" quote = { version = "1.0.28", features = ["proc-macro"] } syn = { version = "2.0.48", features = ["extra-traits", "full", "parsing", "proc-macro"] } diff --git a/substrate/frame/election-provider-support/solution-type/Cargo.toml b/substrate/frame/election-provider-support/solution-type/Cargo.toml index 74f43310418..04400147790 100644 --- a/substrate/frame/election-provider-support/solution-type/Cargo.toml +++ b/substrate/frame/election-provider-support/solution-type/Cargo.toml @@ -21,7 +21,7 @@ proc-macro = true syn = { version = "2.0.48", features = ["full", "visit"] } quote = "1.0.28" proc-macro2 = "1.0.56" -proc-macro-crate = "2.0.1" +proc-macro-crate = "3.0.0" [dev-dependencies] parity-scale-codec = "3.6.1" diff --git a/substrate/frame/staking/reward-curve/Cargo.toml b/substrate/frame/staking/reward-curve/Cargo.toml index 0e13d4550f4..35bf240907a 100644 --- a/substrate/frame/staking/reward-curve/Cargo.toml +++ b/substrate/frame/staking/reward-curve/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] proc-macro = true [dependencies] -proc-macro-crate = "2.0.1" +proc-macro-crate = "3.0.0" proc-macro2 = "1.0.56" quote = "1.0.28" syn = { version = "2.0.48", features = ["full", "visit"] } diff --git a/substrate/frame/support/procedural/tools/Cargo.toml b/substrate/frame/support/procedural/tools/Cargo.toml index 3305f2f5d51..6d1b9507797 100644 --- a/substrate/frame/support/procedural/tools/Cargo.toml +++ b/substrate/frame/support/procedural/tools/Cargo.toml @@ -15,7 +15,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -proc-macro-crate = "2.0.1" +proc-macro-crate = "3.0.0" proc-macro2 = "1.0.56" quote = "1.0.28" syn = { version = "2.0.48", features = ["extra-traits", "full", "visit"] } diff --git a/substrate/primitives/api/proc-macro/Cargo.toml b/substrate/primitives/api/proc-macro/Cargo.toml index e16f4fb7bf5..eff66d3fb29 100644 --- a/substrate/primitives/api/proc-macro/Cargo.toml +++ b/substrate/primitives/api/proc-macro/Cargo.toml @@ -23,7 +23,7 @@ quote = "1.0.28" syn = { version = "2.0.48", features = ["extra-traits", "fold", "full", "visit"] } proc-macro2 = "1.0.56" blake2 = { version = "0.10.4", default-features = false } -proc-macro-crate = "2.0.1" +proc-macro-crate = "3.0.0" expander = "2.0.0" Inflector = "0.11.4" diff --git a/substrate/primitives/runtime-interface/proc-macro/Cargo.toml b/substrate/primitives/runtime-interface/proc-macro/Cargo.toml index b58e6a7b725..869cad06e56 100644 --- a/substrate/primitives/runtime-interface/proc-macro/Cargo.toml +++ b/substrate/primitives/runtime-interface/proc-macro/Cargo.toml @@ -20,7 +20,7 @@ proc-macro = true [dependencies] Inflector = "0.11.4" -proc-macro-crate = "2.0.1" +proc-macro-crate = "3.0.0" proc-macro2 = "1.0.56" quote = "1.0.28" expander = "2.0.0" -- GitLab From a97a6f2095bd35eb9d7e5f11d04f62e065386c78 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Mon, 8 Jan 2024 13:35:12 +0100 Subject: [PATCH 008/392] rpc: add `rpc v2 chainSpec` to polkadot (#2859) The [chainSpec RPC API from the v2 spec](https://paritytech.github.io/json-rpc-interface-spec/api/chainSpec.html) was only added to substrate-node and should be added to polkadot as well /cc @lexnv --- Cargo.lock | 1 + .../runtime_vs_smart_contract.rs | 21 ++++++++++++------- .../node/core/candidate-validation/src/lib.rs | 6 +++--- .../core/candidate-validation/src/tests.rs | 2 +- polkadot/rpc/Cargo.toml | 1 + polkadot/rpc/src/lib.rs | 6 ++++++ substrate/bin/node-template/node/src/rpc.rs | 7 +++++++ .../client/consensus/beefy/src/import.rs | 2 +- substrate/client/consensus/beefy/src/lib.rs | 2 +- .../src/protocol/notifications/behaviour.rs | 2 +- substrate/frame/contracts/fixtures/build.rs | 6 +++--- .../src/construct_runtime/expand/task.rs | 2 +- substrate/frame/system/src/tests.rs | 2 +- substrate/primitives/core/src/address_uri.rs | 2 +- substrate/primitives/core/src/crypto.rs | 4 ++-- .../utils/wasm-builder/src/wasm_project.rs | 2 +- 16 files changed, 45 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7a718610bd3..5fba3e62037 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13200,6 +13200,7 @@ dependencies = [ "sc-consensus-grandpa", "sc-consensus-grandpa-rpc", "sc-rpc", + "sc-rpc-spec-v2", "sc-sync-state-rpc", "sc-transaction-pool-api", "sp-api", diff --git a/docs/sdk/src/reference_docs/runtime_vs_smart_contract.rs b/docs/sdk/src/reference_docs/runtime_vs_smart_contract.rs index 16db44d8be4..099512cf4ee 100644 --- a/docs/sdk/src/reference_docs/runtime_vs_smart_contract.rs +++ b/docs/sdk/src/reference_docs/runtime_vs_smart_contract.rs @@ -32,14 +32,21 @@ //! //! ## Comparative Table //! -//! | Aspect | Runtime | Smart Contracts | +//! | Aspect | Runtime +//! | Smart Contracts | //! |-----------------------|-------------------------------------------------------------------------|----------------------------------------------------------------------| -//! | **Design Philosophy** | Core logic of a blockchain, allowing broad and deep customization. | Designed for DApps deployed on the blockchain runtime.| -//! | **Development Complexity** | Requires in-depth knowledge of Rust and Substrate. Suitable for complex blockchain architectures. | Easier to develop with knowledge of Smart Contract languages like Solidity or [ink!](https://use.ink/). | -//! | **Upgradeability and Flexibility** | Offers comprehensive upgradeability with migration logic and on-chain governance, allowing modifications to the entire blockchain logic without hard forks. | Less flexible in upgrade migrations but offers more straightforward deployment and iteration. | -//! | **Performance and Efficiency** | More efficient, optimized for specific needs of the blockchain. | Can be less efficient due to its generic nature (e.g. the overhead of a virtual machine). | -//! | **Security Considerations** | Security flaws can affect the entire blockchain. | Security risks usually localized to the individual contract. | -//! | **Weighing and Metering** | Operations can be weighed, allowing for precise benchmarking. | Execution is metered, allowing for measurement of resource consumption. | +//! | **Design Philosophy** | Core logic of a blockchain, allowing broad and deep customization. +//! | Designed for DApps deployed on the blockchain runtime.| | **Development Complexity** | Requires in-depth knowledge of Rust and Substrate. Suitable for complex blockchain architectures. | Easier to develop with knowledge of Smart Contract languages like Solidity or [ink!](https://use.ink/). | +//! | **Upgradeability and Flexibility** | Offers comprehensive upgradeability with migration logic +//! and on-chain governance, allowing modifications to the entire blockchain logic without hard +//! forks. | Less flexible in upgrade migrations but offers more straightforward deployment and +//! iteration. | | **Performance and Efficiency** | More efficient, optimized for specific needs of +//! the blockchain. | Can be less efficient due to its generic nature (e.g. the overhead of a +//! virtual machine). | | **Security Considerations** | Security flaws can affect the entire +//! blockchain. | Security risks usually localized to the individual +//! contract. | | **Weighing and Metering** | Operations can be weighed, allowing for precise +//! benchmarking. | Execution is metered, allowing for measurement of resource +//! consumption. | //! //! We will now explore these differences in more detail. //! diff --git a/polkadot/node/core/candidate-validation/src/lib.rs b/polkadot/node/core/candidate-validation/src/lib.rs index 5c4e449b2c9..18c27968915 100644 --- a/polkadot/node/core/candidate-validation/src/lib.rs +++ b/polkadot/node/core/candidate-validation/src/lib.rs @@ -773,21 +773,21 @@ trait ValidationBackend { if num_death_retries_left > 0 { num_death_retries_left -= 1; } else { - break; + break }, Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::JobError(_))) => if num_job_error_retries_left > 0 { num_job_error_retries_left -= 1; } else { - break; + break }, Err(ValidationError::Internal(_)) => if num_internal_retries_left > 0 { num_internal_retries_left -= 1; } else { - break; + break }, Ok(_) | Err(ValidationError::Invalid(_) | ValidationError::Preparation(_)) => break, diff --git a/polkadot/node/core/candidate-validation/src/tests.rs b/polkadot/node/core/candidate-validation/src/tests.rs index 11078580465..f646f853549 100644 --- a/polkadot/node/core/candidate-validation/src/tests.rs +++ b/polkadot/node/core/candidate-validation/src/tests.rs @@ -726,7 +726,7 @@ fn candidate_validation_retry_on_error_helper( ExecutorParams::default(), exec_kind, &Default::default(), - )); + )) } #[test] diff --git a/polkadot/rpc/Cargo.toml b/polkadot/rpc/Cargo.toml index 8c582c623ba..dcb7a13f6f3 100644 --- a/polkadot/rpc/Cargo.toml +++ b/polkadot/rpc/Cargo.toml @@ -21,6 +21,7 @@ sp-consensus = { path = "../../substrate/primitives/consensus/common" } sp-consensus-babe = { path = "../../substrate/primitives/consensus/babe" } sc-chain-spec = { path = "../../substrate/client/chain-spec" } sc-rpc = { path = "../../substrate/client/rpc" } +sc-rpc-spec-v2 = { path = "../../substrate/client/rpc-spec-v2" } sc-consensus-babe = { path = "../../substrate/client/consensus/babe" } sc-consensus-babe-rpc = { path = "../../substrate/client/consensus/babe/rpc" } sc-consensus-beefy = { path = "../../substrate/client/consensus/beefy" } diff --git a/polkadot/rpc/src/lib.rs b/polkadot/rpc/src/lib.rs index bf9daddba50..4455efd3b53 100644 --- a/polkadot/rpc/src/lib.rs +++ b/polkadot/rpc/src/lib.rs @@ -121,6 +121,7 @@ where use sc_consensus_babe_rpc::{Babe, BabeApiServer}; use sc_consensus_beefy_rpc::{Beefy, BeefyApiServer}; use sc_consensus_grandpa_rpc::{Grandpa, GrandpaApiServer}; + use sc_rpc_spec_v2::chain_spec::{ChainSpec, ChainSpecApiServer}; use sc_sync_state_rpc::{SyncState, SyncStateApiServer}; use substrate_state_trie_migration_rpc::{StateMigration, StateMigrationApiServer}; @@ -134,6 +135,11 @@ where finality_provider, } = grandpa; + let chain_name = chain_spec.name().to_string(); + let genesis_hash = client.hash(0).ok().flatten().expect("Genesis block exists; qed"); + let properties = chain_spec.properties(); + + io.merge(ChainSpec::new(chain_name, genesis_hash, properties).into_rpc())?; io.merge(StateMigration::new(client.clone(), backend.clone(), deny_unsafe).into_rpc())?; io.merge(System::new(client.clone(), pool.clone(), deny_unsafe).into_rpc())?; io.merge(TransactionPayment::new(client.clone()).into_rpc())?; diff --git a/substrate/bin/node-template/node/src/rpc.rs b/substrate/bin/node-template/node/src/rpc.rs index f4f1540f732..246391adcbb 100644 --- a/substrate/bin/node-template/node/src/rpc.rs +++ b/substrate/bin/node-template/node/src/rpc.rs @@ -53,5 +53,12 @@ where // to call into the runtime. // `module.merge(YourRpcTrait::into_rpc(YourRpcStruct::new(ReferenceToClient, ...)))?;` + // You probably want to enable the `rpc v2 chainSpec` API as well + // + // let chain_name = chain_spec.name().to_string(); + // let genesis_hash = client.block_hash(0).ok().flatten().expect("Genesis block exists; qed"); + // let properties = chain_spec.properties(); + // module.merge(ChainSpec::new(chain_name, genesis_hash, properties).into_rpc())?; + Ok(module) } diff --git a/substrate/client/consensus/beefy/src/import.rs b/substrate/client/consensus/beefy/src/import.rs index 5bbf07fba70..6eced17b58f 100644 --- a/substrate/client/consensus/beefy/src/import.rs +++ b/substrate/client/consensus/beefy/src/import.rs @@ -148,7 +148,7 @@ where // The block is imported as part of some chain sync. // The voter doesn't need to process it now. // It will be detected and processed as part of the voter state init. - return Ok(inner_import_result); + return Ok(inner_import_result) }, } diff --git a/substrate/client/consensus/beefy/src/lib.rs b/substrate/client/consensus/beefy/src/lib.rs index 51e82b6a811..2e2e22288e3 100644 --- a/substrate/client/consensus/beefy/src/lib.rs +++ b/substrate/client/consensus/beefy/src/lib.rs @@ -398,7 +398,7 @@ where header = wait_for_parent_header(backend.blockchain(), header, HEADER_SYNC_DELAY).await?; } - return Ok(state); + return Ok(state) } // No valid voter-state persisted, re-initialize from pallet genesis. diff --git a/substrate/client/network/src/protocol/notifications/behaviour.rs b/substrate/client/network/src/protocol/notifications/behaviour.rs index cdbf2a71b93..9ad41e376e8 100644 --- a/substrate/client/network/src/protocol/notifications/behaviour.rs +++ b/substrate/client/network/src/protocol/notifications/behaviour.rs @@ -1037,7 +1037,7 @@ impl Notifications { peerset_rejected, incoming_index, }; - return self.report_reject(index).map_or((), |_| ()); + return self.report_reject(index).map_or((), |_| ()) } trace!( diff --git a/substrate/frame/contracts/fixtures/build.rs b/substrate/frame/contracts/fixtures/build.rs index 84eb4219c25..34e44c5db11 100644 --- a/substrate/frame/contracts/fixtures/build.rs +++ b/substrate/frame/contracts/fixtures/build.rs @@ -105,7 +105,7 @@ fn collect_entries(contracts_dir: &Path, out_dir: &Path) -> Vec { .filter_map(|file| { let path = file.expect("file exists; qed").path(); if path.extension().map_or(true, |ext| ext != "rs") { - return None; + return None } let entry = Entry::new(path); @@ -307,7 +307,7 @@ fn find_workspace_root(current_dir: &Path) -> Option { let cargo_toml_contents = std::fs::read_to_string(current_dir.join("Cargo.toml")).ok()?; if cargo_toml_contents.contains("[workspace]") { - return Some(current_dir); + return Some(current_dir) } } @@ -325,7 +325,7 @@ fn main() -> Result<()> { let entries = collect_entries(&contracts_dir, &out_dir); if entries.is_empty() { - return Ok(()); + return Ok(()) } let tmp_dir = tempfile::tempdir()?; diff --git a/substrate/frame/support/procedural/src/construct_runtime/expand/task.rs b/substrate/frame/support/procedural/src/construct_runtime/expand/task.rs index bd952202bbb..6531c0e9e07 100644 --- a/substrate/frame/support/procedural/src/construct_runtime/expand/task.rs +++ b/substrate/frame/support/procedural/src/construct_runtime/expand/task.rs @@ -31,7 +31,7 @@ pub fn expand_outer_task( let mut task_paths = Vec::new(); for decl in pallet_decls { if decl.find_part("Task").is_none() { - continue; + continue } let variant_name = &decl.name; diff --git a/substrate/frame/system/src/tests.rs b/substrate/frame/system/src/tests.rs index 053cec24f89..e437e7f9f39 100644 --- a/substrate/frame/system/src/tests.rs +++ b/substrate/frame/system/src/tests.rs @@ -828,7 +828,7 @@ fn last_runtime_upgrade_spec_version_usage() { // a runtime upgrade in the pipeline of being applied, you should use the spec version // of this upgrade. if System::last_runtime_upgrade_spec_version() > 1337 { - return Weight::zero(); + return Weight::zero() } // Do the migration. diff --git a/substrate/primitives/core/src/address_uri.rs b/substrate/primitives/core/src/address_uri.rs index 862747c9a4b..211d47c0093 100644 --- a/substrate/primitives/core/src/address_uri.rs +++ b/substrate/primitives/core/src/address_uri.rs @@ -184,7 +184,7 @@ impl<'a> AddressUri<'a> { Error::in_pass(initial_input, initial_input_len - input.len()) } else { Error::in_phrase(initial_input, initial_input_len - input.len()) - }); + }) } } diff --git a/substrate/primitives/core/src/crypto.rs b/substrate/primitives/core/src/crypto.rs index 1f3ae744533..2da38d44be4 100644 --- a/substrate/primitives/core/src/crypto.rs +++ b/substrate/primitives/core/src/crypto.rs @@ -434,7 +434,7 @@ impl + AsRef<[u8]> + Public + Derive> Ss58Codec for T { fn from_string(s: &str) -> Result { let cap = AddressUri::parse(s)?; if cap.pass.is_some() { - return Err(PublicError::PasswordNotAllowed); + return Err(PublicError::PasswordNotAllowed) } let s = cap.phrase.unwrap_or(DEV_ADDRESS); let addr = if let Some(stripped) = s.strip_prefix("0x") { @@ -454,7 +454,7 @@ impl + AsRef<[u8]> + Public + Derive> Ss58Codec for T { fn from_string_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> { let cap = AddressUri::parse(s)?; if cap.pass.is_some() { - return Err(PublicError::PasswordNotAllowed); + return Err(PublicError::PasswordNotAllowed) } let (addr, v) = Self::from_ss58check_with_version(cap.phrase.unwrap_or(DEV_ADDRESS))?; if cap.paths.is_empty() { diff --git a/substrate/utils/wasm-builder/src/wasm_project.rs b/substrate/utils/wasm-builder/src/wasm_project.rs index 5bf44c2c9b2..2126a49bd7f 100644 --- a/substrate/utils/wasm-builder/src/wasm_project.rs +++ b/substrate/utils/wasm-builder/src/wasm_project.rs @@ -935,7 +935,7 @@ fn generate_rerun_if_changed_instructions( while let Some(dependency) = dependencies.pop() { // Ignore all dev dependencies if dependency.kind == DependencyKind::Development { - continue; + continue } let path_or_git_dep = -- GitLab From dbff87c268f18bdd8ef01a09f61ce910f2a5ab33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 8 Jan 2024 12:45:17 +0000 Subject: [PATCH 009/392] Return latest known relay chain block number in `on_initialize` etc (#2862) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This changes `RelaychainDataProvider` to return the latest known relay chain block number in `on_initialize` et all, aka when the `validation_data` wasn't yet set by the inherent. --------- Co-authored-by: Dónal Murray --- cumulus/pallets/parachain-system/src/lib.rs | 53 +++++++-------------- prdoc/pr_2862.prdoc | 11 +++++ 2 files changed, 29 insertions(+), 35 deletions(-) create mode 100644 prdoc/pr_2862.prdoc diff --git a/cumulus/pallets/parachain-system/src/lib.rs b/cumulus/pallets/parachain-system/src/lib.rs index ba8aff0e369..5a0fa57fb17 100644 --- a/cumulus/pallets/parachain-system/src/lib.rs +++ b/cumulus/pallets/parachain-system/src/lib.rs @@ -1683,20 +1683,33 @@ pub trait RelaychainStateProvider { } /// Implements [`BlockNumberProvider`] that returns relay chain block number fetched from validation -/// data. When validation data is not available (e.g. within on_initialize), 0 will be returned. +/// data. +/// +/// When validation data is not available (e.g. within `on_initialize`), it will fallback to use +/// [`Pallet::last_relay_block_number()`]. /// /// **NOTE**: This has been deprecated, please use [`RelaychainDataProvider`] #[deprecated = "Use `RelaychainDataProvider` instead"] -pub struct RelaychainBlockNumberProvider(sp_std::marker::PhantomData); +pub type RelaychainBlockNumberProvider = RelaychainDataProvider; -#[allow(deprecated)] -impl BlockNumberProvider for RelaychainBlockNumberProvider { +/// Implements [`BlockNumberProvider`] and [`RelaychainStateProvider`] that returns relevant relay +/// data fetched from validation data. +/// +/// NOTE: When validation data is not available (e.g. within `on_initialize`): +/// +/// - [`current_relay_chain_state`](Self::current_relay_chain_state): Will return the default value +/// of [`RelayChainState`]. +/// - [`current_block_number`](Self::current_block_number): Will return +/// [`Pallet::last_relay_block_number()`]. +pub struct RelaychainDataProvider(sp_std::marker::PhantomData); + +impl BlockNumberProvider for RelaychainDataProvider { type BlockNumber = relay_chain::BlockNumber; fn current_block_number() -> relay_chain::BlockNumber { Pallet::::validation_data() .map(|d| d.relay_parent_number) - .unwrap_or_default() + .unwrap_or_else(|| Pallet::::last_relay_block_number()) } #[cfg(feature = "runtime-benchmarks")] @@ -1739,33 +1752,3 @@ impl RelaychainStateProvider for RelaychainDataProvider { ValidationData::::put(validation_data) } } - -/// Implements [`BlockNumberProvider`] and [`RelaychainStateProvider`] that returns relevant relay -/// data fetched from validation data. -/// NOTE: When validation data is not available (e.g. within on_initialize), default values will be -/// returned. -pub struct RelaychainDataProvider(sp_std::marker::PhantomData); - -impl BlockNumberProvider for RelaychainDataProvider { - type BlockNumber = relay_chain::BlockNumber; - - fn current_block_number() -> relay_chain::BlockNumber { - Pallet::::validation_data() - .map(|d| d.relay_parent_number) - .unwrap_or_default() - } - - #[cfg(feature = "runtime-benchmarks")] - fn set_block_number(block: Self::BlockNumber) { - let mut validation_data = Pallet::::validation_data().unwrap_or_else(|| - // PersistedValidationData does not impl default in non-std - PersistedValidationData { - parent_head: vec![].into(), - relay_parent_number: Default::default(), - max_pov_size: Default::default(), - relay_parent_storage_root: Default::default(), - }); - validation_data.relay_parent_number = block; - ValidationData::::put(validation_data) - } -} diff --git a/prdoc/pr_2862.prdoc b/prdoc/pr_2862.prdoc new file mode 100644 index 00000000000..fa136b5d98a --- /dev/null +++ b/prdoc/pr_2862.prdoc @@ -0,0 +1,11 @@ +title: Return latest known relay chain block number in `on_initialize` etc. + +doc: + - audience: Runtime Dev + description: | + `RelaychainDataProvider` and `RelaychainBlockNumberProvider` will now return the latest known + relay chain block number in `on_initialize`, aka when `validation_data` wasn't yet set by + the inherent. + +crates: + - name: "cumulus-pallet-parachain-system" -- GitLab From 5daef5d086b16a02fcff5873898c42249ecd5d33 Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Mon, 8 Jan 2024 14:11:31 +0100 Subject: [PATCH 010/392] Contracts rename riscv-experimental and enable ci tests (#2879) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Keep feature name short s/riscv-experimental/riscv - Add to feature to CI build --------- Co-authored-by: Bastian Köcher --- .gitlab/pipeline/test.yml | 2 +- substrate/frame/contracts/fixtures/Cargo.toml | 5 ++--- substrate/frame/contracts/fixtures/build.rs | 10 +++++----- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.gitlab/pipeline/test.yml b/.gitlab/pipeline/test.yml index 359d5b4dbcd..00d2b22c810 100644 --- a/.gitlab/pipeline/test.yml +++ b/.gitlab/pipeline/test.yml @@ -29,7 +29,7 @@ test-linux-stable: --locked \ --release \ --no-fail-fast \ - --features try-runtime,experimental,ci-only-tests \ + --features try-runtime,experimental,riscv,ci-only-tests \ --partition count:${CI_NODE_INDEX}/${CI_NODE_TOTAL} # Upload tests results to Elasticsearch - echo "Upload test results to Elasticsearch" diff --git a/substrate/frame/contracts/fixtures/Cargo.toml b/substrate/frame/contracts/fixtures/Cargo.toml index 58f20f0b8f5..36bc3974f5e 100644 --- a/substrate/frame/contracts/fixtures/Cargo.toml +++ b/substrate/frame/contracts/fixtures/Cargo.toml @@ -21,9 +21,8 @@ parity-wasm = "0.45.0" tempfile = "3.8.1" toml = "0.8.2" twox-hash = "1.6.3" -polkavm-linker = "0.3.0" +polkavm-linker = { version = "0.3.0", optional = true } anyhow = "1.0.0" [features] -# Enable experimental RISCV fixtures build -riscv-experimental = [] +riscv = ["polkavm-linker"] diff --git a/substrate/frame/contracts/fixtures/build.rs b/substrate/frame/contracts/fixtures/build.rs index 34e44c5db11..125ee7f3722 100644 --- a/substrate/frame/contracts/fixtures/build.rs +++ b/substrate/frame/contracts/fixtures/build.rs @@ -91,7 +91,7 @@ impl Entry { } /// Return the name of the RISC-V polkavm file. - #[cfg(feature = "riscv-experimental")] + #[cfg(feature = "riscv")] fn out_riscv_filename(&self) -> String { format!("{}.polkavm", self.name()) } @@ -232,7 +232,7 @@ fn post_process_wasm(input_path: &Path, output_path: &Path) -> Result<()> { } /// Build contracts for RISC-V. -#[cfg(feature = "riscv-experimental")] +#[cfg(feature = "riscv")] fn invoke_riscv_build(current_dir: &Path) -> Result<()> { let encoded_rustflags = ["-Crelocation-model=pie", "-Clink-arg=--emit-relocs", "-Clink-arg=-Tmemory.ld"] @@ -267,7 +267,7 @@ fn invoke_riscv_build(current_dir: &Path) -> Result<()> { bail!("Failed to build contracts"); } /// Post-process the compiled wasm contracts. -#[cfg(feature = "riscv-experimental")] +#[cfg(feature = "riscv")] fn post_process_riscv(input_path: &Path, output_path: &Path) -> Result<()> { let mut config = polkavm_linker::Config::default(); config.set_strip(true); @@ -286,7 +286,7 @@ fn write_output(build_dir: &Path, out_dir: &Path, entries: Vec) -> Result &out_dir.join(&wasm_output), )?; - #[cfg(feature = "riscv-experimental")] + #[cfg(feature = "riscv")] post_process_riscv( &build_dir.join("target/riscv32em-unknown-none-elf/release").join(entry.name()), &out_dir.join(entry.out_riscv_filename()), @@ -340,7 +340,7 @@ fn main() -> Result<()> { invoke_wasm_build(tmp_dir_path)?; - #[cfg(feature = "riscv-experimental")] + #[cfg(feature = "riscv")] invoke_riscv_build(tmp_dir_path)?; write_output(tmp_dir_path, &out_dir, entries)?; -- GitLab From 1914775bd4a2254dd3f70d8de1d70c1635e83489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 8 Jan 2024 15:45:15 +0000 Subject: [PATCH 011/392] Make `simple-mermaid` optional (#2878) This prevents it leaking `std` into `no_std` builds. Closes: https://github.com/paritytech/polkadot-sdk/issues/2866 --- substrate/frame/Cargo.toml | 3 ++- substrate/primitives/runtime/Cargo.toml | 3 ++- .../primitives/runtime/src/generic/unchecked_extrinsic.rs | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/substrate/frame/Cargo.toml b/substrate/frame/Cargo.toml index 083d098b22a..81642ce14a1 100644 --- a/substrate/frame/Cargo.toml +++ b/substrate/frame/Cargo.toml @@ -48,7 +48,7 @@ frame-executive = { default-features = false, path = "../frame/executive", optio frame-system-rpc-runtime-api = { default-features = false, path = "../frame/system/rpc/runtime-api", optional = true } docify = "0.2.0" -simple-mermaid = { git = "https://github.com/kianenigma/simple-mermaid.git", rev = "e48b187bcfd5cc75111acd9d241f1bd36604344b" } +simple-mermaid = { git = "https://github.com/kianenigma/simple-mermaid.git", rev = "e48b187bcfd5cc75111acd9d241f1bd36604344b", optional = true } log = { version = "0.4.20", default-features = false } [dev-dependencies] @@ -78,6 +78,7 @@ std = [ "log/std", "parity-scale-codec/std", "scale-info/std", + "simple-mermaid", "sp-api?/std", "sp-arithmetic/std", "sp-block-builder?/std", diff --git a/substrate/primitives/runtime/Cargo.toml b/substrate/primitives/runtime/Cargo.toml index 448aad39ec9..f347a6cfe6d 100644 --- a/substrate/primitives/runtime/Cargo.toml +++ b/substrate/primitives/runtime/Cargo.toml @@ -34,7 +34,7 @@ sp-std = { path = "../std", default-features = false } sp-weights = { path = "../weights", default-features = false } docify = { version = "0.2.6" } -simple-mermaid = { git = "https://github.com/kianenigma/simple-mermaid.git", rev = "e48b187bcfd5cc75111acd9d241f1bd36604344b" } +simple-mermaid = { git = "https://github.com/kianenigma/simple-mermaid.git", rev = "e48b187bcfd5cc75111acd9d241f1bd36604344b", optional = true } [dev-dependencies] rand = "0.8.5" @@ -57,6 +57,7 @@ std = [ "rand", "scale-info/std", "serde/std", + "simple-mermaid", "sp-api/std", "sp-application-crypto/std", "sp-arithmetic/std", diff --git a/substrate/primitives/runtime/src/generic/unchecked_extrinsic.rs b/substrate/primitives/runtime/src/generic/unchecked_extrinsic.rs index 6ac381babee..f066de2323d 100644 --- a/substrate/primitives/runtime/src/generic/unchecked_extrinsic.rs +++ b/substrate/primitives/runtime/src/generic/unchecked_extrinsic.rs @@ -57,7 +57,7 @@ type UncheckedSignaturePayload = (Address, Signature, /// could in principle be any other interaction. Transactions are either signed or unsigned. A /// sensible transaction pool should ensure that only transactions that are worthwhile are /// considered for block-building. -#[doc = simple_mermaid::mermaid!("../../../../../docs/mermaid/extrinsics.mmd")] +#[cfg_attr(feature = "std", doc = simple_mermaid::mermaid!("../../../../../docs/mermaid/extrinsics.mmd"))] /// This type is by no means enforced within Substrate, but given its genericness, it is highly /// likely that for most use-cases it will suffice. Thus, the encoding of this type will dictate /// exactly what bytes should be sent to a runtime to transact with it. -- GitLab From 4fdab499c487c7762425dd7e4e888e7ba71a4990 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 8 Jan 2024 18:41:02 +0000 Subject: [PATCH 012/392] Coretime Zombienet test (#2867) This adds a Zombienet test for Coretime. Requires: https://github.com/paritytech/polkadot-sdk/pull/2862 --------- Co-authored-by: Javier Viola Co-authored-by: Javier Viola <363911+pepoviola@users.noreply.github.com> --- .gitlab/pipeline/zombienet/polkadot.yml | 8 +++++ .../coretime/coretime-rococo/Cargo.toml | 2 ++ .../coretime/coretime-rococo/build.rs | 10 +++++- .../coretime/coretime-rococo/src/coretime.rs | 15 ++++++-- .../coretime/coretime-rococo/src/lib.rs | 8 +++++ .../src/chain_spec/coretime.rs | 34 ++++++++++++------- .../runtime/parachains/src/coretime/mod.rs | 15 +++++--- .../smoke/0004-configure-broker.js | 33 +++++++++--------- .../smoke/0004-configure-relay.js | 23 +++++++++++-- .../smoke/0004-coretime-smoke-test.toml | 33 +++++------------- .../smoke/0004-coretime-smoke-test.zndsl | 8 ++--- 11 files changed, 118 insertions(+), 71 deletions(-) diff --git a/.gitlab/pipeline/zombienet/polkadot.yml b/.gitlab/pipeline/zombienet/polkadot.yml index 6b89648c4e3..c246d98a048 100644 --- a/.gitlab/pipeline/zombienet/polkadot.yml +++ b/.gitlab/pipeline/zombienet/polkadot.yml @@ -185,6 +185,14 @@ zombienet-polkadot-smoke-0003-deregister-register-validator: --local-dir="${LOCAL_DIR}/smoke" --test="0003-deregister-register-validator-smoke.zndsl" +zombienet-polkadot-smoke-0004-coretime-smoke-test: + extends: + - .zombienet-polkadot-common + script: + - /home/nonroot/zombie-net/scripts/ci/run-test-local-env-manager.sh + --local-dir="${LOCAL_DIR}/smoke" + --test="0004-coretime-smoke-test.zndsl" + zombienet-polkadot-misc-0001-parachains-paritydb: extends: - .zombienet-polkadot-common diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml index 0af44045da4..c4544f525a2 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml @@ -194,3 +194,5 @@ try-runtime = [ ] experimental = ["pallet-aura/experimental"] + +fast-runtime = [] diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/build.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/build.rs index 60f8a125129..28dacd20cf3 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/build.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/build.rs @@ -19,7 +19,15 @@ fn main() { .with_current_project() .export_heap_base() .import_memory() - .build() + .build(); + + substrate_wasm_builder::WasmBuilder::new() + .with_current_project() + .set_file_name("fast_runtime_binary.rs") + .enable_feature("fast-runtime") + .import_memory() + .export_heap_base() + .build(); } #[cfg(not(feature = "std"))] diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs index a85d67f7b4c..f8a5dc6398a 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs @@ -17,6 +17,7 @@ use crate::*; use codec::{Decode, Encode}; use cumulus_pallet_parachain_system::RelaychainDataProvider; +use cumulus_primitives_core::relay_chain; use frame_support::{ parameter_types, traits::{ @@ -51,11 +52,16 @@ enum CoretimeProviderCalls { #[codec(index = 1)] RequestCoreCount(CoreIndex), #[codec(index = 2)] - RequestRevenueInfoAt(BlockNumber), + RequestRevenueInfoAt(relay_chain::BlockNumber), #[codec(index = 3)] CreditAccount(AccountId, Balance), #[codec(index = 4)] - AssignCore(CoreIndex, BlockNumber, Vec<(CoreAssignment, PartsOf57600)>, Option), + AssignCore( + CoreIndex, + relay_chain::BlockNumber, + Vec<(CoreAssignment, PartsOf57600)>, + Option, + ), } parameter_types! { @@ -181,7 +187,7 @@ impl CoretimeInterface for CoretimeAllocator { }, Instruction::Transact { origin_kind: OriginKind::Native, - require_weight_at_most: Weight::from_parts(1000000000, 200000), + require_weight_at_most: Weight::from_parts(1_000_000_000, 200000), call: assign_core_call.encode().into(), }, ]); @@ -215,6 +221,9 @@ impl pallet_broker::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; type OnRevenue = CreditToCollatorPot; + #[cfg(feature = "fast-runtime")] + type TimeslicePeriod = ConstU32<10>; + #[cfg(not(feature = "fast-runtime"))] type TimeslicePeriod = ConstU32<80>; type MaxLeasedCores = ConstU32<50>; type MaxReservedCores = ConstU32<10>; diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index 95709117578..0f01c2d7416 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -21,6 +21,14 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +/// Provides the `WASM_BINARY` build with `fast-runtime` feature enabled. +/// +/// This is for example useful for local test chains. +#[cfg(feature = "std")] +pub mod fast_runtime_binary { + include!(concat!(env!("OUT_DIR"), "/fast_runtime_binary.rs")); +} + mod coretime; mod weights; pub mod xcm_config; diff --git a/cumulus/polkadot-parachain/src/chain_spec/coretime.rs b/cumulus/polkadot-parachain/src/chain_spec/coretime.rs index 958336c03b5..fbce4e5bc21 100644 --- a/cumulus/polkadot-parachain/src/chain_spec/coretime.rs +++ b/cumulus/polkadot-parachain/src/chain_spec/coretime.rs @@ -20,7 +20,7 @@ use sc_chain_spec::{ChainSpec, ChainType}; use std::{borrow::Cow, str::FromStr}; /// Collects all supported Coretime configurations. -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Copy)] pub enum CoretimeRuntimeType { // Live Rococo, @@ -85,13 +85,13 @@ impl CoretimeRuntimeType { &include_bytes!("../../../parachains/chain-specs/coretime-rococo.json")[..], )?)), CoretimeRuntimeType::RococoLocal => - Ok(Box::new(rococo::local_config(self, "rococo-local"))), + Ok(Box::new(rococo::local_config(*self, "rococo-local"))), CoretimeRuntimeType::RococoDevelopment => - Ok(Box::new(rococo::local_config(self, "rococo-dev"))), + Ok(Box::new(rococo::local_config(*self, "rococo-dev"))), CoretimeRuntimeType::WestendLocal => - Ok(Box::new(westend::local_config(self, "westend-local"))), + Ok(Box::new(westend::local_config(*self, "westend-local"))), CoretimeRuntimeType::WestendDevelopment => - Ok(Box::new(westend::local_config(self, "westend-dev"))), + Ok(Box::new(westend::local_config(*self, "westend-dev"))), } } } @@ -114,6 +114,7 @@ pub mod rococo { get_account_id_from_seed, get_collator_keys_from_seed, Extensions, SAFE_XCM_VERSION, }; use parachains_common::{AccountId, AuraId, Balance}; + use sc_chain_spec::ChainType; use sp_core::sr25519; pub(crate) const CORETIME_ROCOCO: &str = "coretime-rococo"; @@ -121,24 +122,31 @@ pub mod rococo { pub(crate) const CORETIME_ROCOCO_DEVELOPMENT: &str = "coretime-rococo-dev"; const CORETIME_ROCOCO_ED: Balance = parachains_common::rococo::currency::EXISTENTIAL_DEPOSIT; - pub fn local_config(runtime_type: &CoretimeRuntimeType, relay_chain: &str) -> GenericChainSpec { + pub fn local_config(runtime_type: CoretimeRuntimeType, relay_chain: &str) -> GenericChainSpec { // Rococo defaults let mut properties = sc_chain_spec::Properties::new(); properties.insert("ss58Format".into(), 42.into()); properties.insert("tokenSymbol".into(), "ROC".into()); properties.insert("tokenDecimals".into(), 12.into()); - let chain_type = runtime_type.clone().into(); + let chain_type = runtime_type.into(); let chain_name = format!("Coretime Rococo {}", chain_type_name(&chain_type)); let para_id = super::CORETIME_PARA_ID; - GenericChainSpec::builder( + let wasm_binary = if matches!(chain_type, ChainType::Local | ChainType::Development) { + coretime_rococo_runtime::fast_runtime_binary::WASM_BINARY + .expect("WASM binary was not built, please build it!") + } else { coretime_rococo_runtime::WASM_BINARY - .expect("WASM binary was not built, please build it!"), + .expect("WASM binary was not built, please build it!") + }; + + GenericChainSpec::builder( + wasm_binary, Extensions { relay_chain: relay_chain.to_string(), para_id: para_id.into() }, ) .with_name(&chain_name) - .with_id(runtime_type.clone().into()) + .with_id(runtime_type.into()) .with_chain_type(chain_type) .with_genesis_config_patch(genesis( // initial collators. @@ -209,14 +217,14 @@ pub mod westend { pub(crate) const CORETIME_WESTEND_DEVELOPMENT: &str = "coretime-westend-dev"; const CORETIME_WESTEND_ED: Balance = parachains_common::westend::currency::EXISTENTIAL_DEPOSIT; - pub fn local_config(runtime_type: &CoretimeRuntimeType, relay_chain: &str) -> GenericChainSpec { + pub fn local_config(runtime_type: CoretimeRuntimeType, relay_chain: &str) -> GenericChainSpec { // westend defaults let mut properties = sc_chain_spec::Properties::new(); properties.insert("ss58Format".into(), 42.into()); properties.insert("tokenSymbol".into(), "WND".into()); properties.insert("tokenDecimals".into(), 12.into()); - let chain_type = runtime_type.clone().into(); + let chain_type = runtime_type.into(); let chain_name = format!("Coretime Westend {}", chain_type_name(&chain_type)); let para_id = super::CORETIME_PARA_ID; @@ -226,7 +234,7 @@ pub mod westend { Extensions { relay_chain: relay_chain.to_string(), para_id: para_id.into() }, ) .with_name(&chain_name) - .with_id(runtime_type.clone().into()) + .with_id(runtime_type.into()) .with_chain_type(chain_type) .with_genesis_config_patch(genesis( // initial collators. diff --git a/polkadot/runtime/parachains/src/coretime/mod.rs b/polkadot/runtime/parachains/src/coretime/mod.rs index 8da6ccf07ca..60bd8f81193 100644 --- a/polkadot/runtime/parachains/src/coretime/mod.rs +++ b/polkadot/runtime/parachains/src/coretime/mod.rs @@ -27,7 +27,8 @@ use pallet_broker::{CoreAssignment, CoreIndex as BrokerCoreIndex}; use primitives::{CoreIndex, Id as ParaId}; use sp_arithmetic::traits::SaturatedConversion; use xcm::v3::{ - send_xcm, Instruction, Junction, Junctions, MultiLocation, OriginKind, SendXcm, Xcm, + send_xcm, Instruction, Junction, Junctions, MultiLocation, OriginKind, SendXcm, WeightLimit, + Xcm, }; use crate::{ @@ -220,9 +221,13 @@ impl Pallet { let new_core_count = notification.new_config.coretime_cores; if new_core_count != old_core_count { let core_count: u16 = new_core_count.saturated_into(); - let message = Xcm(vec![mk_coretime_call( - crate::coretime::CoretimeCalls::NotifyCoreCount(core_count), - )]); + let message = Xcm(vec![ + Instruction::UnpaidExecution { + weight_limit: WeightLimit::Unlimited, + check_origin: None, + }, + mk_coretime_call(crate::coretime::CoretimeCalls::NotifyCoreCount(core_count)), + ]); if let Err(err) = send_xcm::( MultiLocation { parents: 0, @@ -247,7 +252,7 @@ fn mk_coretime_call(call: crate::coretime::CoretimeCalls) -> Instruction<()> { origin_kind: OriginKind::Superuser, // Largest call is set_lease with 1526 byte: // Longest call is reserve() with 31_000_000 - require_weight_at_most: Weight::from_parts(100_000_000, 20_000), + require_weight_at_most: Weight::from_parts(110_000_000, 20_000), call: BrokerRuntimePallets::Broker(call).encode().into(), } } diff --git a/polkadot/zombienet_tests/smoke/0004-configure-broker.js b/polkadot/zombienet_tests/smoke/0004-configure-broker.js index a4939ffe1cb..889861f5c52 100644 --- a/polkadot/zombienet_tests/smoke/0004-configure-broker.js +++ b/polkadot/zombienet_tests/smoke/0004-configure-broker.js @@ -13,29 +13,30 @@ async function run(nodeName, networkInfo, _jsArgs) { const calls = [ // Default broker configuration api.tx.broker.configure({ - advanceNotice: 2, + advanceNotice: 5, interludeLength: 1, leadinLength: 1, - regionLength: 3, + regionLength: 1, idealBulkProportion: 100, limitCoresOffered: null, renewalBump: 10, contributionTimeout: 5, }), - // Make reservation for ParaId 100 (adder-a) every other block - // and ParaId 101 (adder-b) every other block. - api.tx.broker.reserve([ - { - mask: [255, 0, 255, 0, 255, 0, 255, 0, 255, 0], - assignment: { Task: 100 }, - }, - { - mask: [0, 255, 0, 255, 0, 255, 0, 255, 0, 255], - assignment: { Task: 101 }, - }, - ]), - // Start sale with 1 core starting at 1 planck - api.tx.broker.startSales(1, 1), + // We need MOARE cores. + api.tx.broker.requestCoreCount(2), + // Set a lease for the broker chain itself. + api.tx.broker.setLease( + 1005, + 1000, + ), + // Set a lease for parachain 100 + api.tx.broker.setLease( + 100, + 1000, + ), + // Start sale to make the broker "work", but we don't offer any cores + // as we have fixed leases only anyway. + api.tx.broker.startSales(1, 0), ]; const sudo_batch = api.tx.sudo.sudo(api.tx.utility.batch(calls)); diff --git a/polkadot/zombienet_tests/smoke/0004-configure-relay.js b/polkadot/zombienet_tests/smoke/0004-configure-relay.js index 9ca23d86a56..724d1b537a3 100644 --- a/polkadot/zombienet_tests/smoke/0004-configure-relay.js +++ b/polkadot/zombienet_tests/smoke/0004-configure-relay.js @@ -1,18 +1,37 @@ const assert = require("assert"); async function run(nodeName, networkInfo, _jsArgs) { - const { wsUri, userDefinedTypes } = networkInfo.nodesByName[nodeName]; + const init = networkInfo.nodesByName[nodeName]; + let wsUri = init.wsUri; + let userDefinedTypes = init.userDefinedTypes; const api = await zombie.connect(wsUri, userDefinedTypes); + const sec = networkInfo.nodesByName["collator-para-100"]; + wsUri = sec.wsUri; + userDefinedTypes = sec.userDefinedTypes; + + const api_collator = await zombie.connect(wsUri, userDefinedTypes); + await zombie.util.cryptoWaitReady(); + // Get the genesis header and the validation code of parachain 100 + const genesis_header = await api_collator.rpc.chain.getHeader(); + const validation_code = await api_collator.rpc.state.getStorage("0x3A636F6465"); + // account to submit tx const keyring = new zombie.Keyring({ type: "sr25519" }); const alice = keyring.addFromUri("//Alice"); const calls = [ api.tx.configuration.setCoretimeCores({ new: 1 }), - api.tx.coretime.assignCore(0, 20,[[ { task: 1005 }, 57600 ]], null) + api.tx.coretime.assignCore(0, 20,[[ { task: 1005 }, 57600 ]], null), + api.tx.registrar.forceRegister( + alice.address, + 0, + 100, + genesis_header.toHex(), + validation_code.toHex(), + ) ]; const sudo_batch = api.tx.sudo.sudo(api.tx.utility.batch(calls)); diff --git a/polkadot/zombienet_tests/smoke/0004-coretime-smoke-test.toml b/polkadot/zombienet_tests/smoke/0004-coretime-smoke-test.toml index 3bcd0bee3c7..0bdb58fa1ef 100644 --- a/polkadot/zombienet_tests/smoke/0004-coretime-smoke-test.toml +++ b/polkadot/zombienet_tests/smoke/0004-coretime-smoke-test.toml @@ -8,7 +8,7 @@ command = "polkadot" [[relaychain.nodes]] name = "alice" - args = ["-lruntime=debug,parachain=trace" ] + args = ["-lruntime=debug,xcm=trace" ] [[relaychain.nodes]] name = "bob" @@ -24,35 +24,18 @@ chain = "coretime-rococo-local" [parachains.collator] name = "coretime-collator" - image = "{{COL_IMAGE}}" + image = "{{CUMULUS_IMAGE}}" command = "polkadot-parachain" - args = [ "-lruntime=debug,parachain=trace" ] + args = [ "-lruntime=debug,xcm=trace" ] [[parachains]] id = 100 add_to_genesis = false -register_para = true -onboard_as_parachain = false - - [parachains.collator] - name = "adder-a" - image = "{{COL_IMAGE}}" - command = "adder-collator" - args = [ "-lruntime=debug,parachain=trace" ] - -[[parachains]] -id = 101 -add_to_genesis = false -register_para = true +register_para = false onboard_as_parachain = false [parachains.collator] - name = "adder-b" - image = "{{COL_IMAGE}}" - command = "adder-collator" - args = [ "-lruntime=debug,parachain=trace" ] - -[types.Header] -number = "u64" -parent_hash = "Hash" -post_state = "Hash" + name = "collator-para-100" + image = "{{CUMULUS_IMAGE}}" + command = "polkadot-parachain" + args = ["-lruntime=debug,parachain=trace,aura=trace", "--force-authoring"] diff --git a/polkadot/zombienet_tests/smoke/0004-coretime-smoke-test.zndsl b/polkadot/zombienet_tests/smoke/0004-coretime-smoke-test.zndsl index 45e000e0bf8..cfb1ce7d982 100644 --- a/polkadot/zombienet_tests/smoke/0004-coretime-smoke-test.zndsl +++ b/polkadot/zombienet_tests/smoke/0004-coretime-smoke-test.zndsl @@ -5,15 +5,11 @@ Creds: config alice: is up coretime-collator: is up -alice: reports block height is at least 3 within 30 seconds # configure relay chain alice: js-script ./0004-configure-relay.js with "" return is 0 within 600 secs -# Wait 2 sessions. The parachain doesn't start block production immediately. -alice: log line contains "New session detected session_index=2" within 600 seconds - # configure broker chain coretime-collator: js-script ./0004-configure-broker.js with "" return is 0 within 600 secs -# TODO: Fix this -# alice: parachain 100 block height is at least 10 within 600 seconds +# Ensure that parachain 100 got onboarded +alice: parachain 100 block height is at least 5 within 900 seconds -- GitLab From a02b53475b9fe2567ae05ad4e03c81f4f3d6b463 Mon Sep 17 00:00:00 2001 From: ordian Date: Mon, 8 Jan 2024 20:58:30 +0100 Subject: [PATCH 013/392] backport to master: Handling of disabled validators in backing subsystem (#1259) (#2764) #1259 was merged into a feature branch, but we've decided to merge node-side changes for disabling straight into master. This is a dependency of #1841 and #2637. --------- Co-authored-by: Tsvetomir Dimitrov --- polkadot/node/core/backing/src/lib.rs | 87 ++++- polkadot/node/core/backing/src/tests/mod.rs | 329 +++++++++++++++++- .../src/tests/prospective_parachains.rs | 20 ++ polkadot/node/core/provisioner/src/lib.rs | 59 +--- polkadot/node/subsystem-util/src/lib.rs | 80 ++++- polkadot/node/subsystem-util/src/vstaging.rs | 56 +++ prdoc/pr_2764.prdoc | 16 + 7 files changed, 574 insertions(+), 73 deletions(-) create mode 100644 polkadot/node/subsystem-util/src/vstaging.rs create mode 100644 prdoc/pr_2764.prdoc diff --git a/polkadot/node/core/backing/src/lib.rs b/polkadot/node/core/backing/src/lib.rs index 434051f1b00..ba25ebb192e 100644 --- a/polkadot/node/core/backing/src/lib.rs +++ b/polkadot/node/core/backing/src/lib.rs @@ -118,6 +118,7 @@ use statement_table::{ }, Config as TableConfig, Context as TableContextTrait, Table, }; +use util::vstaging::get_disabled_validators_with_fallback; mod error; @@ -383,6 +384,21 @@ struct TableContext { validator: Option, groups: HashMap>, validators: Vec, + disabled_validators: Vec, +} + +impl TableContext { + // Returns `true` if the provided `ValidatorIndex` is in the disabled validators list + pub fn validator_is_disabled(&self, validator_idx: &ValidatorIndex) -> bool { + self.disabled_validators + .iter() + .any(|disabled_val_idx| *disabled_val_idx == *validator_idx) + } + + // Returns `true` if the local validator is in the disabled validators list + pub fn local_validator_is_disabled(&self) -> Option { + self.validator.as_ref().map(|v| v.disabled()) + } } impl TableContextTrait for TableContext { @@ -1010,21 +1026,33 @@ async fn construct_per_relay_parent_state( let minimum_backing_votes = try_runtime_api!(request_min_backing_votes(parent, session_index, ctx.sender()).await); + // TODO: https://github.com/paritytech/polkadot-sdk/issues/1940 + // Once runtime ver `DISABLED_VALIDATORS_RUNTIME_REQUIREMENT` is released remove this call to + // `get_disabled_validators_with_fallback`, add `request_disabled_validators` call to the + // `try_join!` above and use `try_runtime_api!` to get `disabled_validators` + let disabled_validators = get_disabled_validators_with_fallback(ctx.sender(), parent) + .await + .map_err(Error::UtilError)?; + let signing_context = SigningContext { parent_hash: parent, session_index }; - let validator = - match Validator::construct(&validators, signing_context.clone(), keystore.clone()) { - Ok(v) => Some(v), - Err(util::Error::NotAValidator) => None, - Err(e) => { - gum::warn!( - target: LOG_TARGET, - err = ?e, - "Cannot participate in candidate backing", - ); + let validator = match Validator::construct( + &validators, + &disabled_validators, + signing_context.clone(), + keystore.clone(), + ) { + Ok(v) => Some(v), + Err(util::Error::NotAValidator) => None, + Err(e) => { + gum::warn!( + target: LOG_TARGET, + err = ?e, + "Cannot participate in candidate backing", + ); - return Ok(None) - }, - }; + return Ok(None) + }, + }; let mut groups = HashMap::new(); let n_cores = cores.len(); @@ -1054,7 +1082,7 @@ async fn construct_per_relay_parent_state( } } - let table_context = TableContext { groups, validators, validator }; + let table_context = TableContext { validator, groups, validators, disabled_validators }; let table_config = TableConfig { allow_multiple_seconded: match mode { ProspectiveParachainsMode::Enabled { .. } => true, @@ -1726,6 +1754,19 @@ async fn kick_off_validation_work( background_validation_tx: &mpsc::Sender<(Hash, ValidatedCandidateCommand)>, attesting: AttestingData, ) -> Result<(), Error> { + // Do nothing if the local validator is disabled or not a validator at all + match rp_state.table_context.local_validator_is_disabled() { + Some(true) => { + gum::info!(target: LOG_TARGET, "We are disabled - don't kick off validation"); + return Ok(()) + }, + Some(false) => {}, // we are not disabled - move on + None => { + gum::debug!(target: LOG_TARGET, "We are not a validator - don't kick off validation"); + return Ok(()) + }, + } + let candidate_hash = attesting.candidate.hash(); if rp_state.issued_statements.contains(&candidate_hash) { return Ok(()) @@ -1783,6 +1824,16 @@ async fn maybe_validate_and_import( }, }; + // Don't import statement if the sender is disabled + if rp_state.table_context.validator_is_disabled(&statement.validator_index()) { + gum::debug!( + target: LOG_TARGET, + sender_validator_idx = ?statement.validator_index(), + "Not importing statement because the sender is disabled" + ); + return Ok(()) + } + let res = import_statement(ctx, rp_state, &mut state.per_candidate, &statement).await; // if we get an Error::RejectedByProspectiveParachains, @@ -1944,6 +1995,13 @@ async fn handle_second_message( Some(r) => r, }; + // Just return if the local validator is disabled. If we are here the local node should be a + // validator but defensively use `unwrap_or(false)` to continue processing in this case. + if rp_state.table_context.local_validator_is_disabled().unwrap_or(false) { + gum::warn!(target: LOG_TARGET, "Local validator is disabled. Don't validate and second"); + return Ok(()) + } + // Sanity check that candidate is from our assignment. if Some(candidate.descriptor().para_id) != rp_state.assignment { gum::debug!( @@ -1990,6 +2048,7 @@ async fn handle_statement_message( ) -> Result<(), Error> { let _timer = metrics.time_process_statement(); + // Validator disabling is handled in `maybe_validate_and_import` match maybe_validate_and_import(ctx, state, relay_parent, statement).await { Err(Error::ValidationFailed(_)) => Ok(()), Err(e) => Err(e), diff --git a/polkadot/node/core/backing/src/tests/mod.rs b/polkadot/node/core/backing/src/tests/mod.rs index c12be72556e..1957f4e19c5 100644 --- a/polkadot/node/core/backing/src/tests/mod.rs +++ b/polkadot/node/core/backing/src/tests/mod.rs @@ -41,7 +41,7 @@ use sp_keyring::Sr25519Keyring; use sp_keystore::Keystore; use sp_tracing as _; use statement_table::v2::Misbehavior; -use std::collections::HashMap; +use std::{collections::HashMap, time::Duration}; mod prospective_parachains; @@ -77,6 +77,7 @@ struct TestState { signing_context: SigningContext, relay_parent: Hash, minimum_backing_votes: u32, + disabled_validators: Vec, } impl TestState { @@ -148,6 +149,7 @@ impl Default for TestState { signing_context, relay_parent, minimum_backing_votes: LEGACY_MIN_BACKING_VOTES, + disabled_validators: Vec::new(), } } } @@ -293,6 +295,26 @@ async fn test_startup(virtual_overseer: &mut VirtualOverseer, test_state: &TestS tx.send(Ok(test_state.minimum_backing_votes)).unwrap(); } ); + + // Check that subsystem job issues a request for the runtime version. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::Version(tx)) + ) if parent == test_state.relay_parent => { + tx.send(Ok(RuntimeApiRequest::DISABLED_VALIDATORS_RUNTIME_REQUIREMENT)).unwrap(); + } + ); + + // Check that subsystem job issues a request for the disabled validators. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::DisabledValidators(tx)) + ) if parent == test_state.relay_parent => { + tx.send(Ok(test_state.disabled_validators.clone())).unwrap(); + } + ); } async fn assert_validation_requests( @@ -1420,6 +1442,7 @@ fn candidate_backing_reorders_votes() { let table_context = TableContext { validator: None, + disabled_validators: Vec::new(), groups: validator_groups, validators: validator_public.clone(), }; @@ -1957,3 +1980,307 @@ fn new_leaf_view_doesnt_clobber_old() { virtual_overseer }); } + +// Test that a disabled local validator doesn't do any work on `CandidateBackingMessage::Second` +#[test] +fn disabled_validator_doesnt_distribute_statement_on_receiving_second() { + let mut test_state = TestState::default(); + test_state.disabled_validators.push(ValidatorIndex(0)); + + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + test_startup(&mut virtual_overseer, &test_state).await; + + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); + + let pov_hash = pov.hash(); + let candidate = TestCandidateBuilder { + para_id: test_state.chain_ids[0], + relay_parent: test_state.relay_parent, + pov_hash, + head_data: expected_head_data.clone(), + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + persisted_validation_data_hash: pvd.hash(), + validation_code: validation_code.0.clone(), + } + .build(); + + let second = CandidateBackingMessage::Second( + test_state.relay_parent, + candidate.to_plain(), + pvd.clone(), + pov.clone(), + ); + + virtual_overseer.send(FromOrchestra::Communication { msg: second }).await; + + // Ensure backing subsystem is not doing any work + assert_matches!(virtual_overseer.recv().timeout(Duration::from_secs(1)).await, None); + + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::stop_work(test_state.relay_parent), + ))) + .await; + virtual_overseer + }); +} + +// Test that a disabled local validator doesn't do any work on `CandidateBackingMessage::Statement` +#[test] +fn disabled_validator_doesnt_distribute_statement_on_receiving_statement() { + let mut test_state = TestState::default(); + test_state.disabled_validators.push(ValidatorIndex(0)); + + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + test_startup(&mut virtual_overseer, &test_state).await; + + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); + + let pov_hash = pov.hash(); + let candidate = TestCandidateBuilder { + para_id: test_state.chain_ids[0], + relay_parent: test_state.relay_parent, + pov_hash, + head_data: expected_head_data.clone(), + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + persisted_validation_data_hash: pvd.hash(), + validation_code: validation_code.0.clone(), + } + .build(); + + let public2 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[2].to_seed()), + ) + .expect("Insert key into keystore"); + + let signed = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Seconded(candidate.clone(), pvd.clone()), + &test_state.signing_context, + ValidatorIndex(2), + &public2.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let statement = CandidateBackingMessage::Statement(test_state.relay_parent, signed.clone()); + + virtual_overseer.send(FromOrchestra::Communication { msg: statement }).await; + + // Ensure backing subsystem is not doing any work + assert_matches!(virtual_overseer.recv().timeout(Duration::from_secs(1)).await, None); + + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::stop_work(test_state.relay_parent), + ))) + .await; + virtual_overseer + }); +} + +// Test that a validator doesn't do any work on receiving a `CandidateBackingMessage::Statement` +// from a disabled validator +#[test] +fn validator_ignores_statements_from_disabled_validators() { + let mut test_state = TestState::default(); + test_state.disabled_validators.push(ValidatorIndex(2)); + + test_harness(test_state.keystore.clone(), |mut virtual_overseer| async move { + test_startup(&mut virtual_overseer, &test_state).await; + + let pov = PoV { block_data: BlockData(vec![42, 43, 44]) }; + let pvd = dummy_pvd(); + let validation_code = ValidationCode(vec![1, 2, 3]); + + let expected_head_data = test_state.head_data.get(&test_state.chain_ids[0]).unwrap(); + + let pov_hash = pov.hash(); + let candidate = TestCandidateBuilder { + para_id: test_state.chain_ids[0], + relay_parent: test_state.relay_parent, + pov_hash, + head_data: expected_head_data.clone(), + erasure_root: make_erasure_root(&test_state, pov.clone(), pvd.clone()), + persisted_validation_data_hash: pvd.hash(), + validation_code: validation_code.0.clone(), + } + .build(); + let candidate_commitments_hash = candidate.commitments.hash(); + + let public2 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[2].to_seed()), + ) + .expect("Insert key into keystore"); + + let signed_2 = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Seconded(candidate.clone(), pvd.clone()), + &test_state.signing_context, + ValidatorIndex(2), + &public2.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let statement_2 = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_2.clone()); + + virtual_overseer.send(FromOrchestra::Communication { msg: statement_2 }).await; + + // Ensure backing subsystem is not doing any work + assert_matches!(virtual_overseer.recv().timeout(Duration::from_secs(1)).await, None); + + // Now send a statement from a honest validator and make sure it gets processed + let public3 = Keystore::sr25519_generate_new( + &*test_state.keystore, + ValidatorId::ID, + Some(&test_state.validators[3].to_seed()), + ) + .expect("Insert key into keystore"); + + let signed_3 = SignedFullStatementWithPVD::sign( + &test_state.keystore, + StatementWithPVD::Seconded(candidate.clone(), pvd.clone()), + &test_state.signing_context, + ValidatorIndex(3), + &public3.into(), + ) + .ok() + .flatten() + .expect("should be signed"); + + let statement_3 = + CandidateBackingMessage::Statement(test_state.relay_parent, signed_3.clone()); + + virtual_overseer.send(FromOrchestra::Communication { msg: statement_3 }).await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::ValidationCodeByHash(hash, tx)) + ) if hash == validation_code.hash() => { + tx.send(Ok(Some(validation_code.clone()))).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionIndexForChild(tx)) + ) => { + tx.send(Ok(1u32.into())).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::SessionExecutorParams(sess_idx, tx)) + ) if sess_idx == 1 => { + tx.send(Ok(Some(ExecutorParams::default()))).unwrap(); + } + ); + + // Sending a `Statement::Seconded` for our assignment will start + // validation process. The first thing requested is the PoV. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityDistribution( + AvailabilityDistributionMessage::FetchPoV { + relay_parent, + tx, + .. + } + ) if relay_parent == test_state.relay_parent => { + tx.send(pov.clone()).unwrap(); + } + ); + + // The next step is the actual request to Validation subsystem + // to validate the `Seconded` candidate. + let expected_pov = pov; + let expected_validation_code = validation_code; + assert_matches!( + virtual_overseer.recv().await, + AllMessages::CandidateValidation( + CandidateValidationMessage::ValidateFromExhaustive { + validation_data, + validation_code, + candidate_receipt, + pov, + executor_params: _, + exec_kind, + response_sender, + } + ) if validation_data == pvd && + validation_code == expected_validation_code && + *pov == expected_pov && &candidate_receipt.descriptor == candidate.descriptor() && + exec_kind == PvfExecKind::Backing && + candidate_commitments_hash == candidate_receipt.commitments_hash => + { + response_sender.send(Ok( + ValidationResult::Valid(CandidateCommitments { + head_data: expected_head_data.clone(), + upward_messages: Default::default(), + horizontal_messages: Default::default(), + new_validation_code: None, + processed_downward_messages: 0, + hrmp_watermark: 0, + }, test_state.validation_data.clone()), + )).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::AvailabilityStore( + AvailabilityStoreMessage::StoreAvailableData { candidate_hash, tx, .. } + ) if candidate_hash == candidate.hash() => { + tx.send(Ok(())).unwrap(); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::StatementDistribution( + StatementDistributionMessage::Share(hash, _stmt) + ) => { + assert_eq!(test_state.relay_parent, hash); + } + ); + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::Provisioner( + ProvisionerMessage::ProvisionableData( + _, + ProvisionableData::BackedCandidate(candidate_receipt) + ) + ) => { + assert_eq!(candidate_receipt, candidate.to_plain()); + } + ); + + virtual_overseer + .send(FromOrchestra::Signal(OverseerSignal::ActiveLeaves( + ActiveLeavesUpdate::stop_work(test_state.relay_parent), + ))) + .await; + virtual_overseer + }); +} diff --git a/polkadot/node/core/backing/src/tests/prospective_parachains.rs b/polkadot/node/core/backing/src/tests/prospective_parachains.rs index e7c29e11bb4..578f21bef66 100644 --- a/polkadot/node/core/backing/src/tests/prospective_parachains.rs +++ b/polkadot/node/core/backing/src/tests/prospective_parachains.rs @@ -195,6 +195,26 @@ async fn activate_leaf( tx.send(Ok(test_state.minimum_backing_votes)).unwrap(); } ); + + // Check that subsystem job issues a request for the runtime version. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::Version(tx)) + ) if parent == hash => { + tx.send(Ok(RuntimeApiRequest::DISABLED_VALIDATORS_RUNTIME_REQUIREMENT)).unwrap(); + } + ); + + // Check that the subsystem job issues a request for the disabled validators. + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::DisabledValidators(tx)) + ) if parent == hash => { + tx.send(Ok(Vec::new())).unwrap(); + } + ); } } diff --git a/polkadot/node/core/provisioner/src/lib.rs b/polkadot/node/core/provisioner/src/lib.rs index 8893bdc6549..3970b857261 100644 --- a/polkadot/node/core/provisioner/src/lib.rs +++ b/polkadot/node/core/provisioner/src/lib.rs @@ -29,13 +29,13 @@ use polkadot_node_subsystem::{ jaeger, messages::{ CandidateBackingMessage, ChainApiMessage, ProspectiveParachainsMessage, ProvisionableData, - ProvisionerInherentData, ProvisionerMessage, RuntimeApiMessage, RuntimeApiRequest, + ProvisionerInherentData, ProvisionerMessage, RuntimeApiRequest, }, overseer, ActivatedLeaf, ActiveLeavesUpdate, FromOrchestra, OverseerSignal, PerLeafSpan, - RuntimeApiError, SpawnedSubsystem, SubsystemError, + SpawnedSubsystem, SubsystemError, }; use polkadot_node_subsystem_util::{ - request_availability_cores, request_persisted_validation_data, + has_required_runtime, request_availability_cores, request_persisted_validation_data, runtime::{prospective_parachains_mode, ProspectiveParachainsMode}, TimeoutExt, }; @@ -856,56 +856,3 @@ fn bitfields_indicate_availability( 3 * availability.count_ones() >= 2 * availability.len() } - -// If we have to be absolutely precise here, this method gets the version of the `ParachainHost` -// api. For brevity we'll just call it 'runtime version'. -async fn has_required_runtime( - sender: &mut impl overseer::ProvisionerSenderTrait, - relay_parent: Hash, - required_runtime_version: u32, -) -> bool { - gum::trace!(target: LOG_TARGET, ?relay_parent, "Fetching ParachainHost runtime api version"); - - let (tx, rx) = oneshot::channel(); - sender - .send_message(RuntimeApiMessage::Request(relay_parent, RuntimeApiRequest::Version(tx))) - .await; - - match rx.await { - Result::Ok(Ok(runtime_version)) => { - gum::trace!( - target: LOG_TARGET, - ?relay_parent, - ?runtime_version, - ?required_runtime_version, - "Fetched ParachainHost runtime api version" - ); - runtime_version >= required_runtime_version - }, - Result::Ok(Err(RuntimeApiError::Execution { source: error, .. })) => { - gum::trace!( - target: LOG_TARGET, - ?relay_parent, - ?error, - "Execution error while fetching ParachainHost runtime api version" - ); - false - }, - Result::Ok(Err(RuntimeApiError::NotSupported { .. })) => { - gum::trace!( - target: LOG_TARGET, - ?relay_parent, - "NotSupported error while fetching ParachainHost runtime api version" - ); - false - }, - Result::Err(_) => { - gum::trace!( - target: LOG_TARGET, - ?relay_parent, - "Cancelled error while fetching ParachainHost runtime api version" - ); - false - }, - } -} diff --git a/polkadot/node/subsystem-util/src/lib.rs b/polkadot/node/subsystem-util/src/lib.rs index a5f3e9d4a0c..1fe52767df6 100644 --- a/polkadot/node/subsystem-util/src/lib.rs +++ b/polkadot/node/subsystem-util/src/lib.rs @@ -55,6 +55,7 @@ use sp_core::ByteArray; use sp_keystore::{Error as KeystoreError, KeystorePtr}; use std::time::Duration; use thiserror::Error; +use vstaging::get_disabled_validators_with_fallback; pub use metered; pub use polkadot_node_network_protocol::MIN_GOSSIP_PEERS; @@ -79,6 +80,9 @@ pub mod inclusion_emulator; /// Convenient and efficient runtime info access. pub mod runtime; +/// Helpers for working with unreleased runtime calls +pub mod vstaging; + /// Nested message sending /// /// Useful for having mostly synchronous code, with submodules spawning short lived asynchronous @@ -92,6 +96,8 @@ mod determine_new_blocks; #[cfg(test)] mod tests; +const LOG_TARGET: &'static str = "parachain::subsystem-util"; + /// Duration a job will wait after sending a stop signal before hard-aborting. pub const JOB_GRACEFUL_STOP_DURATION: Duration = Duration::from_secs(1); /// Capacity of channels to and from individual jobs @@ -157,6 +163,62 @@ where rx } +/// Verifies if `ParachainHost` runtime api is at least at version `required_runtime_version`. This +/// method is used to determine if a given runtime call is supported by the runtime. +pub async fn has_required_runtime( + sender: &mut Sender, + relay_parent: Hash, + required_runtime_version: u32, +) -> bool +where + Sender: SubsystemSender, +{ + gum::trace!(target: LOG_TARGET, ?relay_parent, "Fetching ParachainHost runtime api version"); + + let (tx, rx) = oneshot::channel(); + sender + .send_message(RuntimeApiMessage::Request(relay_parent, RuntimeApiRequest::Version(tx))) + .await; + + match rx.await { + Result::Ok(Ok(runtime_version)) => { + gum::trace!( + target: LOG_TARGET, + ?relay_parent, + ?runtime_version, + ?required_runtime_version, + "Fetched ParachainHost runtime api version" + ); + runtime_version >= required_runtime_version + }, + Result::Ok(Err(RuntimeApiError::Execution { source: error, .. })) => { + gum::trace!( + target: LOG_TARGET, + ?relay_parent, + ?error, + "Execution error while fetching ParachainHost runtime api version" + ); + false + }, + Result::Ok(Err(RuntimeApiError::NotSupported { .. })) => { + gum::trace!( + target: LOG_TARGET, + ?relay_parent, + "NotSupported error while fetching ParachainHost runtime api version" + ); + false + }, + Result::Err(_) => { + gum::trace!( + target: LOG_TARGET, + ?relay_parent, + "Cancelled error while fetching ParachainHost runtime api version" + ); + false + }, + } +} + /// Construct specialized request functions for the runtime. /// /// These would otherwise get pretty repetitive. @@ -378,6 +440,7 @@ pub struct Validator { signing_context: SigningContext, key: ValidatorId, index: ValidatorIndex, + disabled: bool, } impl Validator { @@ -399,7 +462,12 @@ impl Validator { let validators = validators?; - Self::construct(&validators, signing_context, keystore) + // TODO: https://github.com/paritytech/polkadot-sdk/issues/1940 + // When `DisabledValidators` is released remove this and add a + // `request_disabled_validators` call here + let disabled_validators = get_disabled_validators_with_fallback(sender, parent).await?; + + Self::construct(&validators, &disabled_validators, signing_context, keystore) } /// Construct a validator instance without performing runtime fetches. @@ -407,13 +475,16 @@ impl Validator { /// This can be useful if external code also needs the same data. pub fn construct( validators: &[ValidatorId], + disabled_validators: &[ValidatorIndex], signing_context: SigningContext, keystore: KeystorePtr, ) -> Result { let (key, index) = signing_key_and_index(validators, &keystore).ok_or(Error::NotAValidator)?; - Ok(Validator { signing_context, key, index }) + let disabled = disabled_validators.iter().any(|d: &ValidatorIndex| *d == index); + + Ok(Validator { signing_context, key, index, disabled }) } /// Get this validator's id. @@ -426,6 +497,11 @@ impl Validator { self.index } + /// Get the enabled/disabled state of this validator + pub fn disabled(&self) -> bool { + self.disabled + } + /// Get the current signing context. pub fn signing_context(&self) -> &SigningContext { &self.signing_context diff --git a/polkadot/node/subsystem-util/src/vstaging.rs b/polkadot/node/subsystem-util/src/vstaging.rs new file mode 100644 index 00000000000..3efd3b61f93 --- /dev/null +++ b/polkadot/node/subsystem-util/src/vstaging.rs @@ -0,0 +1,56 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Contains helpers for staging runtime calls. +//! +//! This module is intended to contain common boiler plate code handling unreleased runtime API +//! calls. + +use polkadot_node_subsystem_types::messages::{RuntimeApiMessage, RuntimeApiRequest}; +use polkadot_overseer::SubsystemSender; +use polkadot_primitives::{Hash, ValidatorIndex}; + +use crate::{has_required_runtime, request_disabled_validators, Error}; + +const LOG_TARGET: &'static str = "parachain::subsystem-util-vstaging"; + +// TODO: https://github.com/paritytech/polkadot-sdk/issues/1940 +/// Returns disabled validators list if the runtime supports it. Otherwise logs a debug messages and +/// returns an empty vec. +/// Once runtime ver `DISABLED_VALIDATORS_RUNTIME_REQUIREMENT` is released remove this function and +/// replace all usages with `request_disabled_validators` +pub async fn get_disabled_validators_with_fallback>( + sender: &mut Sender, + relay_parent: Hash, +) -> Result, Error> { + let disabled_validators = if has_required_runtime( + sender, + relay_parent, + RuntimeApiRequest::DISABLED_VALIDATORS_RUNTIME_REQUIREMENT, + ) + .await + { + request_disabled_validators(relay_parent, sender) + .await + .await + .map_err(Error::Oneshot)?? + } else { + gum::debug!(target: LOG_TARGET, "Runtime doesn't support `DisabledValidators` - continuing with an empty disabled validators set"); + vec![] + }; + + Ok(disabled_validators) +} diff --git a/prdoc/pr_2764.prdoc b/prdoc/pr_2764.prdoc new file mode 100644 index 00000000000..adfa4f47c93 --- /dev/null +++ b/prdoc/pr_2764.prdoc @@ -0,0 +1,16 @@ +title: Validator disabling in Backing. + +doc: + - audience: Node Operator + description: | + Once a validator has been disabled for misbehavior, it will no longer + sign backing statements in the current era. + +migrations: + db: [] + runtime: [] + +crates: + - name: polkadot-node-core-backing + +host_functions: [] -- GitLab From 0ff3f4d3af0036bbae624011b720bfd5e93ce91b Mon Sep 17 00:00:00 2001 From: ordian Date: Tue, 9 Jan 2024 07:44:19 +0100 Subject: [PATCH 014/392] dispute-coordinator: disabling in participation (#2637) Closes #2225. - [x] tests - [x] fix todos - [x] fix duplicates - [x] make the check part of `potential_spam` - [x] fix a bug with votes insertion - [x] guide changes - [x] docs --------- Co-authored-by: Tsvetomir Dimitrov --- polkadot/node/core/backing/src/lib.rs | 7 +- .../core/dispute-coordinator/src/import.rs | 27 +- .../dispute-coordinator/src/initialized.rs | 155 ++- .../node/core/dispute-coordinator/src/lib.rs | 15 +- .../src/participation/tests.rs | 1 - .../core/dispute-coordinator/src/tests.rs | 987 +++++++++++++++--- polkadot/node/subsystem-util/src/lib.rs | 18 +- .../node/subsystem-util/src/runtime/mod.rs | 28 +- polkadot/node/subsystem-util/src/vstaging.rs | 6 +- polkadot/primitives/src/v6/mod.rs | 21 +- .../src/node/disputes/dispute-coordinator.md | 22 + prdoc/pr_2637.prdoc | 18 + 12 files changed, 1135 insertions(+), 170 deletions(-) create mode 100644 prdoc/pr_2637.prdoc diff --git a/polkadot/node/core/backing/src/lib.rs b/polkadot/node/core/backing/src/lib.rs index ba25ebb192e..98bbd6232ad 100644 --- a/polkadot/node/core/backing/src/lib.rs +++ b/polkadot/node/core/backing/src/lib.rs @@ -1030,9 +1030,10 @@ async fn construct_per_relay_parent_state( // Once runtime ver `DISABLED_VALIDATORS_RUNTIME_REQUIREMENT` is released remove this call to // `get_disabled_validators_with_fallback`, add `request_disabled_validators` call to the // `try_join!` above and use `try_runtime_api!` to get `disabled_validators` - let disabled_validators = get_disabled_validators_with_fallback(ctx.sender(), parent) - .await - .map_err(Error::UtilError)?; + let disabled_validators = + get_disabled_validators_with_fallback(ctx.sender(), parent).await.map_err(|e| { + Error::UtilError(TryFrom::try_from(e).expect("the conversion is infallible; qed")) + })?; let signing_context = SigningContext { parent_hash: parent, session_index }; let validator = match Validator::construct( diff --git a/polkadot/node/core/dispute-coordinator/src/import.rs b/polkadot/node/core/dispute-coordinator/src/import.rs index 98c12bd509b..278561d5d00 100644 --- a/polkadot/node/core/dispute-coordinator/src/import.rs +++ b/polkadot/node/core/dispute-coordinator/src/import.rs @@ -52,6 +52,8 @@ pub struct CandidateEnvironment<'a> { executor_params: &'a ExecutorParams, /// Validator indices controlled by this node. controlled_indices: HashSet, + /// Indices of disabled validators at the `relay_parent`. + disabled_indices: HashSet, } #[overseer::contextbounds(DisputeCoordinator, prefix = self::overseer)] @@ -66,6 +68,16 @@ impl<'a> CandidateEnvironment<'a> { session_index: SessionIndex, relay_parent: Hash, ) -> Option> { + let disabled_indices = runtime_info + .get_disabled_validators(ctx.sender(), relay_parent) + .await + .unwrap_or_else(|err| { + gum::info!(target: LOG_TARGET, ?err, "Failed to get disabled validators"); + Vec::new() + }) + .into_iter() + .collect(); + let (session, executor_params) = match runtime_info .get_session_info_by_index(ctx.sender(), relay_parent, session_index) .await @@ -76,7 +88,7 @@ impl<'a> CandidateEnvironment<'a> { }; let controlled_indices = find_controlled_validator_indices(keystore, &session.validators); - Some(Self { session_index, session, executor_params, controlled_indices }) + Some(Self { session_index, session, executor_params, controlled_indices, disabled_indices }) } /// Validators in the candidate's session. @@ -103,6 +115,11 @@ impl<'a> CandidateEnvironment<'a> { pub fn controlled_indices(&'a self) -> &'a HashSet { &self.controlled_indices } + + /// Indices of disabled validators at the `relay_parent`. + pub fn disabled_indices(&'a self) -> &'a HashSet { + &self.disabled_indices + } } /// Whether or not we already issued some statement about a candidate. @@ -344,6 +361,14 @@ impl CandidateVoteState { &self.votes.candidate_receipt } + /// Returns true if all the invalid votes are from disabled validators. + pub fn invalid_votes_all_disabled( + &self, + mut is_disabled: impl FnMut(&ValidatorIndex) -> bool, + ) -> bool { + self.votes.invalid.keys().all(|i| is_disabled(i)) + } + /// Extract `CandidateVotes` for handling import of new statements. fn into_old_state(self) -> (CandidateVotes, CandidateVoteState<()>) { let CandidateVoteState { votes, own_vote, dispute_status, byzantine_threshold_against } = diff --git a/polkadot/node/core/dispute-coordinator/src/initialized.rs b/polkadot/node/core/dispute-coordinator/src/initialized.rs index d9cd4e39d3c..a1bcc1f0170 100644 --- a/polkadot/node/core/dispute-coordinator/src/initialized.rs +++ b/polkadot/node/core/dispute-coordinator/src/initialized.rs @@ -17,7 +17,7 @@ //! Dispute coordinator subsystem in initialized state (after first active leaf is received). use std::{ - collections::{BTreeMap, VecDeque}, + collections::{BTreeMap, HashSet, VecDeque}, sync::Arc, }; @@ -47,6 +47,7 @@ use polkadot_primitives::{ DisputeStatementSet, Hash, ScrapedOnChainVotes, SessionIndex, ValidDisputeStatementKind, ValidatorId, ValidatorIndex, }; +use schnellru::{LruMap, UnlimitedCompact}; use crate::{ db, @@ -92,6 +93,9 @@ pub struct InitialData { pub(crate) struct Initialized { keystore: Arc, runtime_info: RuntimeInfo, + /// We have the onchain state of disabled validators as well as the offchain + /// state that is based on the lost disputes. + offchain_disabled_validators: OffchainDisabledValidators, /// This is the highest `SessionIndex` seen via `ActiveLeavesUpdate`. It doesn't matter if it /// was cached successfully or not. It is used to detect ancient disputes. highest_session_seen: SessionIndex, @@ -130,10 +134,12 @@ impl Initialized { let (participation_sender, participation_receiver) = mpsc::channel(1); let participation = Participation::new(participation_sender, metrics.clone()); + let offchain_disabled_validators = OffchainDisabledValidators::default(); Self { keystore, runtime_info, + offchain_disabled_validators, highest_session_seen, gaps_in_cache, spam_slots, @@ -319,13 +325,16 @@ impl Initialized { self.runtime_info.pin_block(session_idx, new_leaf.unpin_handle); // Fetch the last `DISPUTE_WINDOW` number of sessions unless there are no gaps // in cache and we are not missing too many `SessionInfo`s - let mut lower_bound = session_idx.saturating_sub(DISPUTE_WINDOW.get() - 1); - if !self.gaps_in_cache && self.highest_session_seen > lower_bound { - lower_bound = self.highest_session_seen + 1 - } + let prune_up_to = session_idx.saturating_sub(DISPUTE_WINDOW.get() - 1); + let fetch_lower_bound = + if !self.gaps_in_cache && self.highest_session_seen > prune_up_to { + self.highest_session_seen + 1 + } else { + prune_up_to + }; // There is a new session. Perform a dummy fetch to cache it. - for idx in lower_bound..=session_idx { + for idx in fetch_lower_bound..=session_idx { if let Err(err) = self .runtime_info .get_session_info_by_index(ctx.sender(), new_leaf.hash, idx) @@ -344,11 +353,9 @@ impl Initialized { self.highest_session_seen = session_idx; - db::v1::note_earliest_session( - overlay_db, - session_idx.saturating_sub(DISPUTE_WINDOW.get() - 1), - )?; - self.spam_slots.prune_old(session_idx.saturating_sub(DISPUTE_WINDOW.get() - 1)); + db::v1::note_earliest_session(overlay_db, prune_up_to)?; + self.spam_slots.prune_old(prune_up_to); + self.offchain_disabled_validators.prune_old(prune_up_to); }, Ok(_) => { /* no new session => nothing to cache */ }, Err(err) => { @@ -978,11 +985,13 @@ impl Initialized { Some(env) => env, }; + let n_validators = env.validators().len(); + gum::trace!( target: LOG_TARGET, ?candidate_hash, ?session, - num_validators = ?env.session_info().validators.len(), + ?n_validators, "Number of validators" ); @@ -1084,18 +1093,42 @@ impl Initialized { target: LOG_TARGET, ?candidate_hash, ?session, - num_validators = ?env.session_info().validators.len(), + ?n_validators, "Import result ready" ); + let new_state = import_result.new_state(); + let byzantine_threshold = polkadot_primitives::byzantine_threshold(n_validators); + // combine on-chain with off-chain disabled validators + // process disabled validators in the following order: + // - on-chain disabled validators + // - prioritized order of off-chain disabled validators + // deduplicate the list and take at most `byzantine_threshold` validators + let disabled_validators = { + let mut d: HashSet = HashSet::new(); + for v in env + .disabled_indices() + .iter() + .cloned() + .chain(self.offchain_disabled_validators.iter(session)) + { + if d.len() == byzantine_threshold { + break + } + d.insert(v); + } + d + }; + let is_included = self.scraper.is_candidate_included(&candidate_hash); let is_backed = self.scraper.is_candidate_backed(&candidate_hash); let own_vote_missing = new_state.own_vote_missing(); let is_disputed = new_state.is_disputed(); let is_confirmed = new_state.is_confirmed(); - let potential_spam = is_potential_spam(&self.scraper, &new_state, &candidate_hash); - // We participate only in disputes which are not potential spam. + let potential_spam = is_potential_spam(&self.scraper, &new_state, &candidate_hash, |v| { + disabled_validators.contains(v) + }); let allow_participation = !potential_spam; gum::trace!( @@ -1106,6 +1139,7 @@ impl Initialized { ?candidate_hash, confirmed = ?new_state.is_confirmed(), has_invalid_voters = ?!import_result.new_invalid_voters().is_empty(), + n_disabled_validators = ?disabled_validators.len(), "Is spam?" ); @@ -1337,6 +1371,10 @@ impl Initialized { ); } } + for validator_index in new_state.votes().invalid.keys() { + self.offchain_disabled_validators + .insert_against_valid(session, *validator_index); + } self.metrics.on_concluded_valid(); } if import_result.is_freshly_concluded_against() { @@ -1356,6 +1394,14 @@ impl Initialized { ); } } + for (validator_index, (kind, _sig)) in new_state.votes().valid.raw() { + let is_backer = kind.is_backing(); + self.offchain_disabled_validators.insert_for_invalid( + session, + *validator_index, + is_backer, + ); + } self.metrics.on_concluded_invalid(); } @@ -1591,3 +1637,82 @@ fn determine_undisputed_chain( Ok(last) } + +#[derive(Default)] +struct OffchainDisabledValidators { + // Ideally, we want to use the top `byzantine_threshold` offenders here based on the amount of + // stake slashed. However, given that slashing might be applied with a delay, we want to have + // some list of offenders as soon as disputes conclude offchain. This list only approximates + // the top offenders and only accounts for lost disputes. But that should be good enough to + // prevent spam attacks. + per_session: BTreeMap, +} + +struct LostSessionDisputes { + // We separate lost disputes to prioritize "for invalid" offenders. And among those, we + // prioritize backing votes the most. There's no need to limit the size of these sets, as they + // are already limited by the number of validators in the session. We use `LruMap` to ensure + // the iteration order prioritizes most recently disputes lost over older ones in case we reach + // the limit. + backers_for_invalid: LruMap, + for_invalid: LruMap, + against_valid: LruMap, +} + +impl Default for LostSessionDisputes { + fn default() -> Self { + Self { + backers_for_invalid: LruMap::new(UnlimitedCompact), + for_invalid: LruMap::new(UnlimitedCompact), + against_valid: LruMap::new(UnlimitedCompact), + } + } +} + +impl OffchainDisabledValidators { + fn prune_old(&mut self, up_to_excluding: SessionIndex) { + // split_off returns everything after the given key, including the key. + let mut relevant = self.per_session.split_off(&up_to_excluding); + std::mem::swap(&mut relevant, &mut self.per_session); + } + + fn insert_for_invalid( + &mut self, + session_index: SessionIndex, + validator_index: ValidatorIndex, + is_backer: bool, + ) { + let entry = self.per_session.entry(session_index).or_default(); + if is_backer { + entry.backers_for_invalid.insert(validator_index, ()); + } else { + entry.for_invalid.insert(validator_index, ()); + } + } + + fn insert_against_valid( + &mut self, + session_index: SessionIndex, + validator_index: ValidatorIndex, + ) { + self.per_session + .entry(session_index) + .or_default() + .against_valid + .insert(validator_index, ()); + } + + /// Iterate over all validators that are offchain disabled. + /// The order of iteration prioritizes `for_invalid` offenders (and backers among those) over + /// `against_valid` offenders. And most recently lost disputes over older ones. + /// NOTE: the iterator might contain duplicates. + fn iter(&self, session_index: SessionIndex) -> impl Iterator + '_ { + self.per_session.get(&session_index).into_iter().flat_map(|e| { + e.backers_for_invalid + .iter() + .chain(e.for_invalid.iter()) + .chain(e.against_valid.iter()) + .map(|(i, _)| *i) + }) + } +} diff --git a/polkadot/node/core/dispute-coordinator/src/lib.rs b/polkadot/node/core/dispute-coordinator/src/lib.rs index 5067d3673da..c3038fc0953 100644 --- a/polkadot/node/core/dispute-coordinator/src/lib.rs +++ b/polkadot/node/core/dispute-coordinator/src/lib.rs @@ -370,8 +370,10 @@ impl DisputeCoordinatorSubsystem { }, }; let vote_state = CandidateVoteState::new(votes, &env, now); - - let potential_spam = is_potential_spam(&scraper, &vote_state, candidate_hash); + let onchain_disabled = env.disabled_indices(); + let potential_spam = is_potential_spam(&scraper, &vote_state, candidate_hash, |v| { + onchain_disabled.contains(v) + }); let is_included = scraper.is_candidate_included(&vote_state.votes().candidate_receipt.hash()); @@ -462,17 +464,20 @@ async fn wait_for_first_leaf(ctx: &mut Context) -> Result( +pub fn is_potential_spam( scraper: &ChainScraper, - vote_state: &CandidateVoteState, + vote_state: &CandidateVoteState, candidate_hash: &CandidateHash, + is_disabled: impl FnMut(&ValidatorIndex) -> bool, ) -> bool { let is_disputed = vote_state.is_disputed(); let is_included = scraper.is_candidate_included(candidate_hash); let is_backed = scraper.is_candidate_backed(candidate_hash); let is_confirmed = vote_state.is_confirmed(); + let all_invalid_votes_disabled = vote_state.invalid_votes_all_disabled(is_disabled); + let ignore_disabled = !is_confirmed && all_invalid_votes_disabled; - is_disputed && !is_included && !is_backed && !is_confirmed + (is_disputed && !is_included && !is_backed && !is_confirmed) || ignore_disabled } /// Tell dispute-distribution to send all our votes. diff --git a/polkadot/node/core/dispute-coordinator/src/participation/tests.rs b/polkadot/node/core/dispute-coordinator/src/participation/tests.rs index 012df51d0cd..367454115f0 100644 --- a/polkadot/node/core/dispute-coordinator/src/participation/tests.rs +++ b/polkadot/node/core/dispute-coordinator/src/participation/tests.rs @@ -372,7 +372,6 @@ fn cannot_participate_if_cannot_recover_validation_code() { let mut participation = Participation::new(sender, Metrics::default()); activate_leaf(&mut ctx, &mut participation, 10).await.unwrap(); participate(&mut ctx, &mut participation).await.unwrap(); - recover_available_data(&mut ctx_handle).await; assert_matches!( diff --git a/polkadot/node/core/dispute-coordinator/src/tests.rs b/polkadot/node/core/dispute-coordinator/src/tests.rs index da449773fe8..af384256c4f 100644 --- a/polkadot/node/core/dispute-coordinator/src/tests.rs +++ b/polkadot/node/core/dispute-coordinator/src/tests.rs @@ -257,7 +257,7 @@ impl TestState { session: SessionIndex, block_number: BlockNumber, candidate_events: Vec, - ) { + ) -> Hash { assert!(block_number > 0); let block_header = Header { @@ -282,6 +282,8 @@ impl TestState { self.handle_sync_queries(virtual_overseer, block_hash, session, candidate_events) .await; + + block_hash } /// Returns any sent `DisputeMessage`s. @@ -406,6 +408,19 @@ impl TestState { )) => { tx.send(Ok(Vec::new())).unwrap(); }, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _new_leaf, + RuntimeApiRequest::Version(tx), + )) => { + tx.send(Ok(RuntimeApiRequest::DISABLED_VALIDATORS_RUNTIME_REQUIREMENT)) + .unwrap(); + }, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _new_leaf, + RuntimeApiRequest::DisabledValidators(tx), + )) => { + tx.send(Ok(Vec::new())).unwrap(); + }, AllMessages::ChainApi(ChainApiMessage::Ancestors { hash, k, response_channel }) => { let target_header = self .headers @@ -628,15 +643,19 @@ async fn participation_with_distribution( } fn make_valid_candidate_receipt() -> CandidateReceipt { - let mut candidate_receipt = dummy_candidate_receipt_bad_sig(dummy_hash(), dummy_hash()); - candidate_receipt.commitments_hash = CandidateCommitments::default().hash(); - candidate_receipt + make_another_valid_candidate_receipt(dummy_hash()) } fn make_invalid_candidate_receipt() -> CandidateReceipt { dummy_candidate_receipt_bad_sig(Default::default(), Some(Default::default())) } +fn make_another_valid_candidate_receipt(relay_parent: Hash) -> CandidateReceipt { + let mut candidate_receipt = dummy_candidate_receipt_bad_sig(relay_parent, dummy_hash()); + candidate_receipt.commitments_hash = CandidateCommitments::default().hash(); + candidate_receipt +} + // Generate a `CandidateBacked` event from a `CandidateReceipt`. The rest is dummy data. fn make_candidate_backed_event(candidate_receipt: CandidateReceipt) -> CandidateEvent { CandidateEvent::CandidateBacked( @@ -740,6 +759,7 @@ fn too_many_unconfirmed_statements_are_considered_spam() { .await; gum::trace!("After sending `ImportStatements`"); + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; handle_approval_vote_request(&mut virtual_overseer, &candidate_hash1, HashMap::new()) .await; @@ -875,6 +895,7 @@ fn approval_vote_import_works() { .into_iter() .collect(); + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; handle_approval_vote_request(&mut virtual_overseer, &candidate_hash1, approval_votes) .await; @@ -982,6 +1003,7 @@ fn dispute_gets_confirmed_via_participation() { }) .await; gum::debug!("After First import!"); + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; handle_approval_vote_request(&mut virtual_overseer, &candidate_hash1, HashMap::new()) .await; @@ -1131,6 +1153,7 @@ fn dispute_gets_confirmed_at_byzantine_threshold() { }, }) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; handle_approval_vote_request(&mut virtual_overseer, &candidate_hash1, HashMap::new()) .await; @@ -1255,6 +1278,7 @@ fn backing_statements_import_works_and_no_spam() { }, }) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; assert_matches!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); { @@ -1387,6 +1411,7 @@ fn conflicting_votes_lead_to_dispute_participation() { }, }) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) .await; @@ -1506,6 +1531,7 @@ fn positive_votes_dont_trigger_participation() { }, }) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; { let (tx, rx) = oneshot::channel(); @@ -1616,6 +1642,7 @@ fn wrong_validator_index_is_ignored() { }, }) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; { let (tx, rx) = oneshot::channel(); @@ -1693,6 +1720,7 @@ fn finality_votes_ignore_disputed_candidates() { }, }) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) .await; @@ -1769,14 +1797,10 @@ fn supermajority_valid_dispute_may_be_finalized() { let candidate_receipt = make_valid_candidate_receipt(); let candidate_hash = candidate_receipt.hash(); + let candidate_events = vec![make_candidate_backed_event(candidate_receipt.clone())]; test_state - .activate_leaf_at_session( - &mut virtual_overseer, - session, - 1, - vec![make_candidate_backed_event(candidate_receipt.clone())], - ) + .activate_leaf_at_session(&mut virtual_overseer, session, 1, candidate_events) .await; let supermajority_threshold = @@ -1805,6 +1829,7 @@ fn supermajority_valid_dispute_may_be_finalized() { }, }) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) .await; @@ -1942,6 +1967,7 @@ fn concluded_supermajority_for_non_active_after_time() { }, }) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) .await; @@ -2058,6 +2084,7 @@ fn concluded_supermajority_against_non_active_after_time() { }, }) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) .await; assert_matches!(confirmation_rx.await.unwrap(), @@ -2173,6 +2200,7 @@ fn resume_dispute_without_local_statement() { }, }) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) .await; @@ -2217,13 +2245,23 @@ fn resume_dispute_without_local_statement() { let candidate_receipt = make_valid_candidate_receipt(); let candidate_hash = candidate_receipt.hash(); - participation_with_distribution( + participation_full_happy_path( &mut virtual_overseer, - &candidate_hash, candidate_receipt.commitments_hash, ) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; + + assert_matches!( + virtual_overseer.recv().await, + AllMessages::DisputeDistribution( + DisputeDistributionMessage::SendDispute(msg) + ) => { + assert_eq!(msg.candidate_receipt().hash(), candidate_hash); + } + ); + let mut statements = Vec::new(); // Getting votes for supermajority. Should already have two valid votes. for i in vec![3, 4, 5, 6, 7] { @@ -2328,6 +2366,7 @@ fn resume_dispute_with_local_statement() { }) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) .await; @@ -2425,6 +2464,7 @@ fn resume_dispute_without_local_statement_or_local_key() { }, }) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; handle_approval_vote_request( &mut virtual_overseer, &candidate_hash, @@ -2516,6 +2556,7 @@ fn issue_local_statement_does_cause_distribution_but_not_duplicate_participation }) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); // Initiate dispute locally: @@ -2556,7 +2597,7 @@ fn issue_local_statement_does_cause_distribution_but_not_duplicate_participation } #[test] -fn own_approval_vote_gets_distributed_on_dispute() { +fn participation_with_onchain_disabling_unconfirmed() { test_harness(|mut test_state, mut virtual_overseer| { Box::pin(async move { let session = 1; @@ -2565,126 +2606,116 @@ fn own_approval_vote_gets_distributed_on_dispute() { let candidate_receipt = make_valid_candidate_receipt(); let candidate_hash = candidate_receipt.hash(); + let events = vec![make_candidate_included_event(candidate_receipt.clone())]; test_state - .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .activate_leaf_at_session(&mut virtual_overseer, session, 1, events) .await; - let statement = test_state.issue_approval_vote_with_index( - ValidatorIndex(0), - candidate_hash, - session, - ); - - // Import our approval vote: - virtual_overseer - .send(FromOrchestra::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_receipt: candidate_receipt.clone(), - session, - statements: vec![(statement, ValidatorIndex(0))], - pending_confirmation: None, - }, - }) - .await; + let backer_index = ValidatorIndex(1); + let disabled_index = ValidatorIndex(2); - // Trigger dispute: let (valid_vote, invalid_vote) = generate_opposing_votes_pair( &test_state, - ValidatorIndex(2), - ValidatorIndex(1), + backer_index, + disabled_index, candidate_hash, session, - VoteType::Explicit, + VoteType::Backing, ) .await; let (pending_confirmation, confirmation_rx) = oneshot::channel(); + let pending_confirmation = Some(pending_confirmation); + + // Scenario 1: unconfirmed dispute with onchain disabled validator against. + // Expectation: we import the vote, but do not participate. virtual_overseer .send(FromOrchestra::Communication { msg: DisputeCoordinatorMessage::ImportStatements { candidate_receipt: candidate_receipt.clone(), session, statements: vec![ - (invalid_vote, ValidatorIndex(1)), - (valid_vote, ValidatorIndex(2)), + (valid_vote, backer_index), + (invalid_vote, disabled_index), ], - pending_confirmation: Some(pending_confirmation), + pending_confirmation, }, }) .await; + + handle_disabled_validators_queries(&mut virtual_overseer, vec![disabled_index]).await; handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) .await; assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); - // Dispute distribution should get notified now (without participation, as we already - // have an approval vote): - assert_matches!( - overseer_recv(&mut virtual_overseer).await, - AllMessages::DisputeDistribution( - DisputeDistributionMessage::SendDispute(msg) - ) => { - assert_eq!(msg.session_index(), session); - assert_eq!(msg.candidate_receipt(), &candidate_receipt); - } - ); - - // No participation should occur: - assert_matches!(virtual_overseer.recv().timeout(TEST_TIMEOUT).await, None); - - virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; - assert!(virtual_overseer.try_recv().await.is_none()); - - test_state - }) - }); -} - -#[test] -fn negative_issue_local_statement_only_triggers_import() { - test_harness(|mut test_state, mut virtual_overseer| { - Box::pin(async move { - let session = 1; - - test_state.handle_resume_sync(&mut virtual_overseer, session).await; + // we should not participate due to disabled indices on chain + assert!(virtual_overseer.recv().timeout(TEST_TIMEOUT).await.is_none()); - let candidate_receipt = make_invalid_candidate_receipt(); - let candidate_hash = candidate_receipt.hash(); + // Scenario 2: unconfirmed dispute with non-disabled validator against. + // Expectation: even if the dispute is unconfirmed, we should participate + // once we receive an invalid vote from a non-disabled validator. + let non_disabled_index = ValidatorIndex(3); + let vote = test_state.issue_explicit_statement_with_index( + non_disabled_index, + candidate_hash, + session, + false, + ); + let statements = vec![(vote, non_disabled_index)]; - test_state - .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) - .await; + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + let pending_confirmation = Some(pending_confirmation); virtual_overseer .send(FromOrchestra::Communication { - msg: DisputeCoordinatorMessage::IssueLocalStatement( + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), session, - candidate_hash, - candidate_receipt.clone(), - false, - ), + statements, + pending_confirmation, + }, }) .await; - // Assert that subsystem is not participating. - assert!(virtual_overseer.recv().timeout(TEST_TIMEOUT).await.is_none()); + assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); - virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; - assert!(virtual_overseer.try_recv().await.is_none()); + participation_with_distribution( + &mut virtual_overseer, + &candidate_hash, + candidate_receipt.commitments_hash, + ) + .await; - let backend = DbBackend::new( - test_state.db.clone(), - test_state.config.column_config(), - Metrics::default(), - ); + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; - let votes = backend.load_candidate_votes(session, &candidate_hash).unwrap().unwrap(); - assert_eq!(votes.invalid.len(), 1); - assert_eq!(votes.valid.len(), 0); + assert_eq!(rx.await.unwrap().len(), 1); - let disputes = backend.load_recent_disputes().unwrap(); - assert_eq!(disputes, None); + // check if we have participated (cast a vote) + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 2); // 3+1 => we have participated + assert_eq!(votes.invalid.len(), 2); + } + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); test_state }) @@ -2692,7 +2723,7 @@ fn negative_issue_local_statement_only_triggers_import() { } #[test] -fn redundant_votes_ignored() { +fn participation_with_onchain_disabling_confirmed() { test_harness(|mut test_state, mut virtual_overseer| { Box::pin(async move { let session = 1; @@ -2701,63 +2732,95 @@ fn redundant_votes_ignored() { let candidate_receipt = make_valid_candidate_receipt(); let candidate_hash = candidate_receipt.hash(); + let events = vec![make_candidate_included_event(candidate_receipt.clone())]; test_state - .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .activate_leaf_at_session(&mut virtual_overseer, session, 1, events) .await; - let valid_vote = test_state.issue_backing_statement_with_index( - ValidatorIndex(1), - candidate_hash, - session, - ); + let backer_index = ValidatorIndex(1); + let disabled_index = ValidatorIndex(2); - let valid_vote_2 = test_state.issue_backing_statement_with_index( - ValidatorIndex(1), + // Scenario 1: confirmed dispute with disabled validator + // Expectation: we import the vote and participate. + let mut statements = Vec::new(); + + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + backer_index, + disabled_index, candidate_hash, session, - ); + VoteType::Backing, + ) + .await; - assert!(valid_vote.validator_signature() != valid_vote_2.validator_signature()); + statements.push((valid_vote, backer_index)); + statements.push((invalid_vote, disabled_index)); - let (tx, rx) = oneshot::channel(); - virtual_overseer - .send(FromOrchestra::Communication { - msg: DisputeCoordinatorMessage::ImportStatements { - candidate_receipt: candidate_receipt.clone(), - session, - statements: vec![(valid_vote.clone(), ValidatorIndex(1))], - pending_confirmation: Some(tx), - }, - }) - .await; + // now import enough votes for dispute confirmation + for i in vec![3, 4] { + let vote = test_state.issue_explicit_statement_with_index( + ValidatorIndex(i), + candidate_hash, + session, + true, + ); - rx.await.unwrap(); + statements.push((vote, ValidatorIndex(i as _))); + } + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + let pending_confirmation = Some(pending_confirmation); - let (tx, rx) = oneshot::channel(); virtual_overseer .send(FromOrchestra::Communication { msg: DisputeCoordinatorMessage::ImportStatements { candidate_receipt: candidate_receipt.clone(), session, - statements: vec![(valid_vote_2, ValidatorIndex(1))], - pending_confirmation: Some(tx), + statements, + pending_confirmation, }, }) .await; - rx.await.unwrap(); + handle_disabled_validators_queries(&mut virtual_overseer, vec![]).await; + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); - let backend = DbBackend::new( - test_state.db.clone(), - test_state.config.column_config(), - Metrics::default(), - ); + participation_with_distribution( + &mut virtual_overseer, + &candidate_hash, + candidate_receipt.commitments_hash, + ) + .await; - let votes = backend.load_candidate_votes(session, &candidate_hash).unwrap().unwrap(); - assert_eq!(votes.invalid.len(), 0); - assert_eq!(votes.valid.len(), 1); - assert_eq!(&votes.valid[0].2, valid_vote.validator_signature()); + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert_eq!(rx.await.unwrap().len(), 1); + + // check if we have participated (cast a vote) + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 4); // 3+1 => we have participated + assert_eq!(votes.invalid.len(), 1); + } virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; assert!(virtual_overseer.try_recv().await.is_none()); @@ -2768,9 +2831,7 @@ fn redundant_votes_ignored() { } #[test] -/// Make sure no disputes are recorded when there are no opposing votes, even if we reached -/// supermajority. -fn no_onesided_disputes() { +fn participation_with_offchain_disabling() { test_harness(|mut test_state, mut virtual_overseer| { Box::pin(async move { let session = 1; @@ -2779,13 +2840,641 @@ fn no_onesided_disputes() { let candidate_receipt = make_valid_candidate_receipt(); let candidate_hash = candidate_receipt.hash(); + let events = vec![make_candidate_included_event(candidate_receipt.clone())]; + + let block_hash = test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 3, events) + .await; + + let another_candidate_receipt = make_another_valid_candidate_receipt(block_hash); + let another_candidate_hash = another_candidate_receipt.hash(); + let another_events = + vec![make_candidate_included_event(another_candidate_receipt.clone())]; + test_state - .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .activate_leaf_at_session(&mut virtual_overseer, session, 4, another_events) .await; + // import enough votes for supermajority to conclude the dispute let mut statements = Vec::new(); - for index in 1..10 { - statements.push(( + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(1), + ValidatorIndex(2), + candidate_hash, + session, + VoteType::Backing, + ) + .await; + + statements.push((valid_vote, ValidatorIndex(1))); + statements.push((invalid_vote, ValidatorIndex(2))); + + for i in vec![3, 4, 5, 6, 7, 8] { + let vote = test_state.issue_explicit_statement_with_index( + ValidatorIndex(i), + candidate_hash, + session, + true, + ); + + statements.push((vote, ValidatorIndex(i as _))); + } + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + let pending_confirmation = Some(pending_confirmation); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements, + pending_confirmation, + }, + }) + .await; + + handle_disabled_validators_queries(&mut virtual_overseer, vec![]).await; + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + + assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + + participation_with_distribution( + &mut virtual_overseer, + &candidate_hash, + candidate_receipt.commitments_hash, + ) + .await; + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert_eq!(rx.await.unwrap().len(), 1); + + // check if we have participated (cast a vote) + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 8); // 8 => we have participated + assert_eq!(votes.invalid.len(), 1); + } + + // now create another dispute + // Validator 2 should be disabled offchain now + + let mut statements = Vec::new(); + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(1), + ValidatorIndex(2), + another_candidate_hash, + session, + VoteType::Backing, + ) + .await; + + statements.push((valid_vote, ValidatorIndex(1))); + statements.push((invalid_vote, ValidatorIndex(2))); + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + let pending_confirmation = Some(pending_confirmation); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: another_candidate_receipt.clone(), + session, + statements, + pending_confirmation, + }, + }) + .await; + + // let's disable validators 3, 4 on chain, but this should not affect this import + let disabled_validators = vec![ValidatorIndex(3), ValidatorIndex(4)]; + handle_disabled_validators_queries(&mut virtual_overseer, disabled_validators).await; + handle_approval_vote_request( + &mut virtual_overseer, + &another_candidate_hash, + HashMap::new(), + ) + .await; + assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + + // we should not participate since due to offchain disabling + assert!(virtual_overseer.recv().timeout(TEST_TIMEOUT).await.is_none()); + + // now import enough votes for dispute confirmation + // even though all of these votes are from (on chain) disabled validators + let mut statements = Vec::new(); + for i in vec![3, 4] { + let vote = test_state.issue_explicit_statement_with_index( + ValidatorIndex(i), + another_candidate_hash, + session, + true, + ); + + statements.push((vote, ValidatorIndex(i as _))); + } + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + let pending_confirmation = Some(pending_confirmation); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: another_candidate_receipt.clone(), + session, + statements, + pending_confirmation, + }, + }) + .await; + + assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + + participation_with_distribution( + &mut virtual_overseer, + &another_candidate_hash, + another_candidate_receipt.commitments_hash, + ) + .await; + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert_eq!(rx.await.unwrap().len(), 2); + + // check if we have participated (cast a vote) + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, another_candidate_hash)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 4); // 3+1 => we have participated + assert_eq!(votes.invalid.len(), 1); + } + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +// Once the onchain disabling reaches the byzantine threshold, +// offchain disabling will no longer take any effect. +#[test] +fn participation_with_disabling_limits() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + let events = vec![make_candidate_included_event(candidate_receipt.clone())]; + + let block_hash = test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 3, events) + .await; + + let another_candidate_receipt = make_another_valid_candidate_receipt(block_hash); + let another_candidate_hash = another_candidate_receipt.hash(); + let another_events = + vec![make_candidate_included_event(another_candidate_receipt.clone())]; + + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 4, another_events) + .await; + + // import enough votes for supermajority to conclude the dispute + let mut statements = Vec::new(); + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(1), + ValidatorIndex(2), + candidate_hash, + session, + VoteType::Backing, + ) + .await; + + statements.push((valid_vote, ValidatorIndex(1))); + statements.push((invalid_vote, ValidatorIndex(2))); + + for i in vec![3, 4, 5, 6, 7, 8] { + let vote = test_state.issue_explicit_statement_with_index( + ValidatorIndex(i), + candidate_hash, + session, + true, + ); + + statements.push((vote, ValidatorIndex(i as _))); + } + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + let pending_confirmation = Some(pending_confirmation); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements, + pending_confirmation, + }, + }) + .await; + + handle_disabled_validators_queries(&mut virtual_overseer, vec![]).await; + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + + assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + + participation_with_distribution( + &mut virtual_overseer, + &candidate_hash, + candidate_receipt.commitments_hash, + ) + .await; + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert_eq!(rx.await.unwrap().len(), 1); + + // check if we have participated (cast a vote) + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, candidate_hash)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 8); // 8 => we have participated + assert_eq!(votes.invalid.len(), 1); + } + + // now create another dispute + // validator 2 should be disabled offchain now + // but due to the byzantine threshold of onchain disabling + // this validator will be considered enabled + + let mut statements = Vec::new(); + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(1), + ValidatorIndex(2), + another_candidate_hash, + session, + VoteType::Backing, + ) + .await; + + statements.push((valid_vote, ValidatorIndex(1))); + statements.push((invalid_vote, ValidatorIndex(2))); + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + let pending_confirmation = Some(pending_confirmation); + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: another_candidate_receipt.clone(), + session, + statements, + pending_confirmation, + }, + }) + .await; + + // let's disable validators 3, 4, 5 on chain, reaching the byzantine threshold + let disabled_validators = vec![ValidatorIndex(3), ValidatorIndex(4), ValidatorIndex(5)]; + handle_disabled_validators_queries(&mut virtual_overseer, disabled_validators).await; + handle_approval_vote_request( + &mut virtual_overseer, + &another_candidate_hash, + HashMap::new(), + ) + .await; + assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + + participation_with_distribution( + &mut virtual_overseer, + &another_candidate_hash, + another_candidate_receipt.commitments_hash, + ) + .await; + + { + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ActiveDisputes(tx), + }) + .await; + + assert_eq!(rx.await.unwrap().len(), 2); + + // check if we have participated (cast a vote) + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::QueryCandidateVotes( + vec![(session, another_candidate_hash)], + tx, + ), + }) + .await; + + let (_, _, votes) = rx.await.unwrap().get(0).unwrap().clone(); + assert_eq!(votes.valid.raw().len(), 2); // 2 => we have participated + assert_eq!(votes.invalid.len(), 1); + } + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +fn own_approval_vote_gets_distributed_on_dispute() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .await; + + let statement = test_state.issue_approval_vote_with_index( + ValidatorIndex(0), + candidate_hash, + session, + ); + + // Import our approval vote: + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![(statement, ValidatorIndex(0))], + pending_confirmation: None, + }, + }) + .await; + + // Trigger dispute: + let (valid_vote, invalid_vote) = generate_opposing_votes_pair( + &test_state, + ValidatorIndex(2), + ValidatorIndex(1), + candidate_hash, + session, + VoteType::Explicit, + ) + .await; + + let (pending_confirmation, confirmation_rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![ + (invalid_vote, ValidatorIndex(1)), + (valid_vote, ValidatorIndex(2)), + ], + pending_confirmation: Some(pending_confirmation), + }, + }) + .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; + handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) + .await; + + assert_eq!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); + + // Dispute distribution should get notified now (without participation, as we already + // have an approval vote): + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::DisputeDistribution( + DisputeDistributionMessage::SendDispute(msg) + ) => { + assert_eq!(msg.session_index(), session); + assert_eq!(msg.candidate_receipt(), &candidate_receipt); + } + ); + + // No participation should occur: + assert_matches!(virtual_overseer.recv().timeout(TEST_TIMEOUT).await, None); + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +fn negative_issue_local_statement_only_triggers_import() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_invalid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .await; + + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::IssueLocalStatement( + session, + candidate_hash, + candidate_receipt.clone(), + false, + ), + }) + .await; + + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; + // Assert that subsystem is not participating. + assert!(virtual_overseer.recv().timeout(TEST_TIMEOUT).await.is_none()); + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); + + let backend = DbBackend::new( + test_state.db.clone(), + test_state.config.column_config(), + Metrics::default(), + ); + + let votes = backend.load_candidate_votes(session, &candidate_hash).unwrap().unwrap(); + assert_eq!(votes.invalid.len(), 1); + assert_eq!(votes.valid.len(), 0); + + let disputes = backend.load_recent_disputes().unwrap(); + assert_eq!(disputes, None); + + test_state + }) + }); +} + +#[test] +fn redundant_votes_ignored() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .await; + + let valid_vote = test_state.issue_backing_statement_with_index( + ValidatorIndex(1), + candidate_hash, + session, + ); + + let valid_vote_2 = test_state.issue_backing_statement_with_index( + ValidatorIndex(1), + candidate_hash, + session, + ); + + assert!(valid_vote.validator_signature() != valid_vote_2.validator_signature()); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![(valid_vote.clone(), ValidatorIndex(1))], + pending_confirmation: Some(tx), + }, + }) + .await; + + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; + rx.await.unwrap(); + + let (tx, rx) = oneshot::channel(); + virtual_overseer + .send(FromOrchestra::Communication { + msg: DisputeCoordinatorMessage::ImportStatements { + candidate_receipt: candidate_receipt.clone(), + session, + statements: vec![(valid_vote_2, ValidatorIndex(1))], + pending_confirmation: Some(tx), + }, + }) + .await; + + rx.await.unwrap(); + + let backend = DbBackend::new( + test_state.db.clone(), + test_state.config.column_config(), + Metrics::default(), + ); + + let votes = backend.load_candidate_votes(session, &candidate_hash).unwrap().unwrap(); + assert_eq!(votes.invalid.len(), 0); + assert_eq!(votes.valid.len(), 1); + assert_eq!(&votes.valid[0].2, valid_vote.validator_signature()); + + virtual_overseer.send(FromOrchestra::Signal(OverseerSignal::Conclude)).await; + assert!(virtual_overseer.try_recv().await.is_none()); + + test_state + }) + }); +} + +#[test] +/// Make sure no disputes are recorded when there are no opposing votes, even if we reached +/// supermajority. +fn no_onesided_disputes() { + test_harness(|mut test_state, mut virtual_overseer| { + Box::pin(async move { + let session = 1; + + test_state.handle_resume_sync(&mut virtual_overseer, session).await; + + let candidate_receipt = make_valid_candidate_receipt(); + let candidate_hash = candidate_receipt.hash(); + test_state + .activate_leaf_at_session(&mut virtual_overseer, session, 1, Vec::new()) + .await; + + let mut statements = Vec::new(); + for index in 1..10 { + statements.push(( test_state.issue_backing_statement_with_index( ValidatorIndex(index), candidate_hash, @@ -2806,6 +3495,7 @@ fn no_onesided_disputes() { }, }) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; assert_matches!(confirmation_rx.await, Ok(ImportStatementsResult::ValidImport)); // We should not have any active disputes now. @@ -2869,6 +3559,7 @@ fn refrain_from_participation() { }) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) .await; @@ -2961,6 +3652,7 @@ fn participation_for_included_candidates() { }) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) .await; @@ -3049,6 +3741,7 @@ fn local_participation_in_dispute_for_backed_candidate() { }) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) .await; @@ -3190,6 +3883,7 @@ fn participation_requests_reprioritized_for_newly_included() { }) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; // Handle corresponding messages to unblock import // we need to handle `ApprovalVotingMessage::GetApprovalSignaturesForCandidate` for // import @@ -3343,6 +4037,7 @@ fn informs_chain_selection_when_dispute_concluded_against() { }, }) .await; + handle_disabled_validators_queries(&mut virtual_overseer, Vec::new()).await; handle_approval_vote_request(&mut virtual_overseer, &candidate_hash, HashMap::new()) .await; assert_matches!(confirmation_rx.await.unwrap(), @@ -3655,3 +4350,27 @@ fn session_info_small_jump_works() { }) }); } + +async fn handle_disabled_validators_queries( + virtual_overseer: &mut VirtualOverseer, + disabled_validators: Vec, +) { + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _new_leaf, + RuntimeApiRequest::Version(tx), + )) => { + tx.send(Ok(RuntimeApiRequest::DISABLED_VALIDATORS_RUNTIME_REQUIREMENT)).unwrap(); + } + ); + assert_matches!( + virtual_overseer.recv().await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _new_leaf, + RuntimeApiRequest::DisabledValidators(tx), + )) => { + tx.send(Ok(disabled_validators)).unwrap(); + } + ); +} diff --git a/polkadot/node/subsystem-util/src/lib.rs b/polkadot/node/subsystem-util/src/lib.rs index 1fe52767df6..f13beb3502f 100644 --- a/polkadot/node/subsystem-util/src/lib.rs +++ b/polkadot/node/subsystem-util/src/lib.rs @@ -141,6 +141,20 @@ impl From for Error { } } +impl TryFrom for Error { + type Error = (); + + fn try_from(e: crate::runtime::Error) -> Result { + use crate::runtime::Error; + + match e { + Error::RuntimeRequestCanceled(e) => Ok(Self::Oneshot(e)), + Error::RuntimeRequest(e) => Ok(Self::RuntimeApi(e)), + Error::NoSuchSession(_) | Error::NoExecutorParams(_) => Err(()), + } + } +} + /// A type alias for Runtime API receivers. pub type RuntimeApiReceiver = oneshot::Receiver>; @@ -465,7 +479,9 @@ impl Validator { // TODO: https://github.com/paritytech/polkadot-sdk/issues/1940 // When `DisabledValidators` is released remove this and add a // `request_disabled_validators` call here - let disabled_validators = get_disabled_validators_with_fallback(sender, parent).await?; + let disabled_validators = get_disabled_validators_with_fallback(sender, parent) + .await + .map_err(|e| Error::try_from(e).expect("the conversion is infallible; qed"))?; Self::construct(&validators, &disabled_validators, signing_context, keystore) } diff --git a/polkadot/node/subsystem-util/src/runtime/mod.rs b/polkadot/node/subsystem-util/src/runtime/mod.rs index 0e44423b4e3..481625acb32 100644 --- a/polkadot/node/subsystem-util/src/runtime/mod.rs +++ b/polkadot/node/subsystem-util/src/runtime/mod.rs @@ -43,7 +43,7 @@ use crate::{ request_from_runtime, request_key_ownership_proof, request_on_chain_votes, request_session_executor_params, request_session_index_for_child, request_session_info, request_submit_report_dispute_lost, request_unapplied_slashes, request_validation_code_by_hash, - request_validator_groups, + request_validator_groups, vstaging::get_disabled_validators_with_fallback, }; /// Errors that can happen on runtime fetches. @@ -75,6 +75,11 @@ pub struct RuntimeInfo { /// overseer seems sensible. session_index_cache: LruMap, + /// In the happy case, we do not query disabled validators at all. In the worst case, we can + /// query it order of `n_cores` times `n_validators` per block, so caching it here seems + /// sensible. + disabled_validators_cache: LruMap>, + /// Look up cached sessions by `SessionIndex`. session_info_cache: LruMap, @@ -129,6 +134,7 @@ impl RuntimeInfo { Self { session_index_cache: LruMap::new(ByLength::new(cfg.session_cache_lru_size.max(10))), session_info_cache: LruMap::new(ByLength::new(cfg.session_cache_lru_size)), + disabled_validators_cache: LruMap::new(ByLength::new(100)), pinned_blocks: LruMap::new(ByLength::new(cfg.session_cache_lru_size)), keystore: cfg.keystore, } @@ -180,6 +186,26 @@ impl RuntimeInfo { self.get_session_info_by_index(sender, relay_parent, session_index).await } + /// Get the list of disabled validators at the relay parent. + pub async fn get_disabled_validators( + &mut self, + sender: &mut Sender, + relay_parent: Hash, + ) -> Result> + where + Sender: SubsystemSender, + { + match self.disabled_validators_cache.get(&relay_parent).cloned() { + Some(result) => Ok(result), + None => { + let disabled_validators = + get_disabled_validators_with_fallback(sender, relay_parent).await?; + self.disabled_validators_cache.insert(relay_parent, disabled_validators.clone()); + Ok(disabled_validators) + }, + } + } + /// Get `ExtendedSessionInfo` by session index. /// /// `request_session_info` still requires the parent to be passed in, so we take the parent diff --git a/polkadot/node/subsystem-util/src/vstaging.rs b/polkadot/node/subsystem-util/src/vstaging.rs index 3efd3b61f93..3e807eff538 100644 --- a/polkadot/node/subsystem-util/src/vstaging.rs +++ b/polkadot/node/subsystem-util/src/vstaging.rs @@ -23,7 +23,7 @@ use polkadot_node_subsystem_types::messages::{RuntimeApiMessage, RuntimeApiReque use polkadot_overseer::SubsystemSender; use polkadot_primitives::{Hash, ValidatorIndex}; -use crate::{has_required_runtime, request_disabled_validators, Error}; +use crate::{has_required_runtime, request_disabled_validators, runtime}; const LOG_TARGET: &'static str = "parachain::subsystem-util-vstaging"; @@ -35,7 +35,7 @@ const LOG_TARGET: &'static str = "parachain::subsystem-util-vstaging"; pub async fn get_disabled_validators_with_fallback>( sender: &mut Sender, relay_parent: Hash, -) -> Result, Error> { +) -> Result, runtime::Error> { let disabled_validators = if has_required_runtime( sender, relay_parent, @@ -46,7 +46,7 @@ pub async fn get_disabled_validators_with_fallback bool { - match *self { - Self::Valid(ValidDisputeStatementKind::BackingSeconded(_)) | - Self::Valid(ValidDisputeStatementKind::BackingValid(_)) => true, - Self::Valid(ValidDisputeStatementKind::Explicit) | - Self::Valid(ValidDisputeStatementKind::ApprovalChecking) | - Self::Valid(ValidDisputeStatementKind::ApprovalCheckingMultipleCandidates(_)) | + match self { + Self::Valid(s) => s.is_backing(), Self::Invalid(_) => false, } } @@ -1374,6 +1370,19 @@ pub enum ValidDisputeStatementKind { ApprovalCheckingMultipleCandidates(Vec), } +impl ValidDisputeStatementKind { + /// Whether the statement is from the backing phase. + pub fn is_backing(&self) -> bool { + match self { + ValidDisputeStatementKind::BackingSeconded(_) | + ValidDisputeStatementKind::BackingValid(_) => true, + ValidDisputeStatementKind::Explicit | + ValidDisputeStatementKind::ApprovalChecking | + ValidDisputeStatementKind::ApprovalCheckingMultipleCandidates(_) => false, + } + } +} + /// Different kinds of statements of invalidity on a candidate. #[derive(Encode, Decode, Copy, Clone, PartialEq, RuntimeDebug, TypeInfo)] pub enum InvalidDisputeStatementKind { diff --git a/polkadot/roadmap/implementers-guide/src/node/disputes/dispute-coordinator.md b/polkadot/roadmap/implementers-guide/src/node/disputes/dispute-coordinator.md index a9cb2741b08..e0738e219d1 100644 --- a/polkadot/roadmap/implementers-guide/src/node/disputes/dispute-coordinator.md +++ b/polkadot/roadmap/implementers-guide/src/node/disputes/dispute-coordinator.md @@ -13,6 +13,7 @@ In particular the dispute-coordinator is responsible for: - Ensuring backing votes will never get overridden by explicit votes. - Coordinating actual participation in a dispute, ensuring that the node participates in any justified dispute in a way that ensures resolution of disputes on the network even in the case of many disputes raised (flood/DoS scenario). +- Ensuring disabled validators are not able to spam disputes. - Ensuring disputes resolve, even for candidates on abandoned forks as much as reasonably possible, to rule out "free tries" and thus guarantee our gambler's ruin property. - Providing an API for chain selection, so we can prevent finalization of any chain which has included candidates for @@ -243,6 +244,9 @@ if any of the following holds true: - The dispute is already confirmed: Meaning that 1/3+1 nodes already participated, as this suggests in our threat model that there was at least one honest node that already voted, so the dispute must be genuine. +In addition to that, we only participate in a non-confirmed dispute if at least one vote against the candidate is from +a non-disabled validator. + Note: A node might be out of sync with the chain and we might only learn about a block, including a candidate, after we learned about the dispute. This means, we have to re-evaluate participation decisions on block import! @@ -301,6 +305,7 @@ conditions are satisfied: - the candidate under dispute was not seen included nor backed on any chain - the dispute is not confirmed - we haven't cast a vote for the dispute +- at least one vote against the candidate is from a non-disabled validator Whenever any vote on a dispute is imported these conditions are checked. If the dispute is found not to be potential spam, then spam slots for the disputed candidate hash are cleared. This decrements the spam count for every validator @@ -318,6 +323,23 @@ approval-voting), but we also don't import them until a dispute already conclude opposing votes, so there must be an explicit `invalid` vote in the import. Only a third of the validators can be malicious, so spam disk usage is limited to `2*vote_size*n/3*NUM_SPAM_SLOTS`, with `n` being the number of validators. +### Disabling + +Once a validator has committed an offence (e.g. losing a dispute), it is considered disabled for the rest of the era. +In addition to using the on-chain state of disabled validators, we also keep track of validators who lost a dispute +off-chain. The reason for this is a dispute can be raised for a candidate in a previous era, which means that a +validator that is going to be slashed for it might not even be in the current active set. That means it can't be +disabled on-chain. We need a way to prevent someone from disputing all valid candidates in the previous era. We do this +by keeping track of the validators who lost a dispute in the past few sessions and use that list in addition to the +on-chain disabled validators state. In addition to past session misbehavior, this also heps in case a slash is delayed. + +When we receive a dispute statements set, we do the following: +1. Take the on-chain state of disabled validators at the relay parent block. +1. Take a list of those who lost a dispute in that session in the order that prioritizes the biggest and newest offence. +1. Combine the two lists and take the first byzantine threshold validators from it. +1. If the dispute is unconfimed, check if all votes against the candidate are from disabled validators. +If so, we don't participate in the dispute, but record the votes. + ### Backing Votes Backing votes are in some way special. For starters they are the only valid votes that are guaranteed to exist for any diff --git a/prdoc/pr_2637.prdoc b/prdoc/pr_2637.prdoc new file mode 100644 index 00000000000..a7ab4f93222 --- /dev/null +++ b/prdoc/pr_2637.prdoc @@ -0,0 +1,18 @@ +title: Validator disabling in Dispute Participation. + +doc: + - audience: Node Operator + description: | + Once a validator has been disabled for misbehavior, other validators + should no longer participate in disputes initiated by it. + This feature is needed to ensure robust spam protection against + malicious actors. + +migrations: + db: [] + runtime: [] + +crates: + - name: polkadot-node-core-dispute-coordinator + +host_functions: [] -- GitLab From d288c81b968d9d375168eb2a0dde68b1f6ebc8a8 Mon Sep 17 00:00:00 2001 From: Muharem Date: Tue, 9 Jan 2024 19:36:39 +0800 Subject: [PATCH 015/392] pallet-core-fellowship: import an unimported member on approve (#2883) To align with the documentation of the approve call, we import an unimported member on approval. No changes have been made to the benchmarks as they already cover the worst-case scenario. --- prdoc/pr_2883.prdoc | 9 +++++++ substrate/frame/core-fellowship/src/lib.rs | 26 ++++++++++++++------ substrate/frame/core-fellowship/src/tests.rs | 8 ++++++ 3 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 prdoc/pr_2883.prdoc diff --git a/prdoc/pr_2883.prdoc b/prdoc/pr_2883.prdoc new file mode 100644 index 00000000000..e2817d16a03 --- /dev/null +++ b/prdoc/pr_2883.prdoc @@ -0,0 +1,9 @@ +title: "pallet-core-fellowship: import an unimported on approve" + +doc: + - audience: Runtime User + description: | + To align with the documentation of the approve call, we import an untracked member on approval. + +crates: + - name: "pallet-core-fellowship" diff --git a/substrate/frame/core-fellowship/src/lib.rs b/substrate/frame/core-fellowship/src/lib.rs index 2042f68e714..ee16ae07ce6 100644 --- a/substrate/frame/core-fellowship/src/lib.rs +++ b/substrate/frame/core-fellowship/src/lib.rs @@ -382,7 +382,11 @@ pub mod pallet { ensure!(at_rank > 0, Error::::InvalidRank); let rank = T::Members::rank_of(&who).ok_or(Error::::Unranked)?; ensure!(rank == at_rank, Error::::UnexpectedRank); - let mut member = Member::::get(&who).ok_or(Error::::NotTracked)?; + let mut member = if let Some(m) = Member::::get(&who) { + m + } else { + Self::import_member(who.clone(), rank) + }; member.last_proof = frame_system::Pallet::::block_number(); Member::::insert(&who, &member); @@ -518,13 +522,7 @@ pub mod pallet { let who = ensure_signed(origin)?; ensure!(!Member::::contains_key(&who), Error::::AlreadyInducted); let rank = T::Members::rank_of(&who).ok_or(Error::::Unranked)?; - - let now = frame_system::Pallet::::block_number(); - Member::::insert( - &who, - MemberStatus { is_active: true, last_promotion: 0u32.into(), last_proof: now }, - ); - Self::deposit_event(Event::::Imported { who, rank }); + let _ = Self::import_member(who, rank); Ok(Pays::No.into()) } @@ -548,6 +546,18 @@ pub mod pallet { Self::deposit_event(e); } } + + fn import_member(who: T::AccountId, rank: RankOf) -> MemberStatusOf { + let now = frame_system::Pallet::::block_number(); + let status = MemberStatus { + is_active: true, + last_promotion: BlockNumberFor::::zero(), + last_proof: now, + }; + Member::::insert(&who, status.clone()); + Self::deposit_event(Event::::Imported { who, rank }); + status + } } impl, I: 'static> GetSalary, T::AccountId, T::Balance> for Pallet { diff --git a/substrate/frame/core-fellowship/src/tests.rs b/substrate/frame/core-fellowship/src/tests.rs index c9098f2171f..6d9cebbf921 100644 --- a/substrate/frame/core-fellowship/src/tests.rs +++ b/substrate/frame/core-fellowship/src/tests.rs @@ -378,3 +378,11 @@ fn active_changing_get_salary_works() { } }); } + +#[test] +fn approve_imports_not_tracked_member() { + new_test_ext().execute_with(|| { + set_rank(10, 5); + assert_ok!(CoreFellowship::approve(signed(5), 10, 5)); + }); +} -- GitLab From 06fa111f58b0172c9f4ba7c209c8b6945787faeb Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Tue, 9 Jan 2024 12:43:53 +0100 Subject: [PATCH 016/392] Contracts: Bump polkavm (#2884) bump polkavm-x deps to 0.4.0 --- .gitlab-ci.yml | 2 +- Cargo.lock | 26 +++++++------------ substrate/frame/contracts/fixtures/Cargo.toml | 2 +- .../frame/contracts/fixtures/build/Cargo.toml | 2 +- substrate/frame/contracts/uapi/Cargo.toml | 7 +++-- 5 files changed, 16 insertions(+), 23 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dc4b3cf162e..2289341a357 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -21,7 +21,7 @@ workflow: - if: $CI_COMMIT_BRANCH variables: - CI_IMAGE: !reference [.ci-unified, variables, CI_IMAGE] + CI_IMAGE: "docker.io/paritytech/ci-unified:bullseye-1.74.0-2023-11-01-v20240108" # BUILDAH_IMAGE is defined in group variables BUILDAH_COMMAND: "buildah --storage-driver overlay2" RELENG_SCRIPTS_BRANCH: "master" diff --git a/Cargo.lock b/Cargo.lock index 5fba3e62037..d4d3b2f6404 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13786,21 +13786,15 @@ dependencies = [ [[package]] name = "polkavm-common" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01363cf0a778e8d93eff31e8a03bc59992cba35faa419ea4f3e80146b69195ba" - -[[package]] -name = "polkavm-common" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88e869d66a254db6c7069992f240626416aba8e87d65c00e4be443135babfe82" +checksum = "fecd2caacfc4a7ee34243758dd7348859e6dec73f5e5df059890f5742ee46f0e" [[package]] name = "polkavm-derive" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26501292b2cb980cbeaac3304f0fc4480ff1bac2473045453d7333d775658b6a" +checksum = "db65a500d4adf574893c726ae365e37e4fbb7f2cbd403f6eaa1b665457456adc" dependencies = [ "polkavm-derive-impl", "syn 2.0.48", @@ -13808,11 +13802,11 @@ dependencies = [ [[package]] name = "polkavm-derive-impl" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "903e16ad3ed768f35e6f40acff2e8aaf6afb9f2889b0a8982dd43dcbee29db2d" +checksum = "c99f4e7a9ff434ef9c885b874c99d824c3a5693bf5e3e8569bb1d2245a8c1b7f" dependencies = [ - "polkavm-common 0.2.0", + "polkavm-common", "proc-macro2", "quote", "syn 2.0.48", @@ -13820,15 +13814,15 @@ dependencies = [ [[package]] name = "polkavm-linker" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f8719d37effca6df1cecf5c816d84ab09b7d18e960511f61c254a7581fa50c3" +checksum = "550738c1b49b9279fa19d8ebed81f551b911b869227a20a190f85f6db45d5d0e" dependencies = [ "gimli 0.28.0", "hashbrown 0.14.3", "log", "object 0.32.2", - "polkavm-common 0.3.0", + "polkavm-common", "rustc-demangle", ] diff --git a/substrate/frame/contracts/fixtures/Cargo.toml b/substrate/frame/contracts/fixtures/Cargo.toml index 36bc3974f5e..5ffac43d9de 100644 --- a/substrate/frame/contracts/fixtures/Cargo.toml +++ b/substrate/frame/contracts/fixtures/Cargo.toml @@ -21,7 +21,7 @@ parity-wasm = "0.45.0" tempfile = "3.8.1" toml = "0.8.2" twox-hash = "1.6.3" -polkavm-linker = { version = "0.3.0", optional = true } +polkavm-linker = { version = "0.4.0", optional = true } anyhow = "1.0.0" [features] diff --git a/substrate/frame/contracts/fixtures/build/Cargo.toml b/substrate/frame/contracts/fixtures/build/Cargo.toml index 7fd42b887e7..70bf0ba94fe 100644 --- a/substrate/frame/contracts/fixtures/build/Cargo.toml +++ b/substrate/frame/contracts/fixtures/build/Cargo.toml @@ -10,7 +10,7 @@ edition = "2021" [dependencies] uapi = { package = 'pallet-contracts-uapi', path = "", default-features = false } common = { package = 'pallet-contracts-fixtures-common', path = "" } -polkavm-derive = '0.2.0' +polkavm-derive = '0.4.0' [profile.release] opt-level = 3 diff --git a/substrate/frame/contracts/uapi/Cargo.toml b/substrate/frame/contracts/uapi/Cargo.toml index d3f6fc06269..eb12c4361f1 100644 --- a/substrate/frame/contracts/uapi/Cargo.toml +++ b/substrate/frame/contracts/uapi/Cargo.toml @@ -8,9 +8,8 @@ homepage = "https://substrate.io" repository.workspace = true description = "Exposes all the host functions that a contract can import." -# [lints] -# TODO: uncomment when rve toolchain is updated to rust 1.74 or greater. -# workspace = true +[lints] +workspace = true [dependencies] paste = { version = "1.0", default-features = false } @@ -22,7 +21,7 @@ scale = { package = "parity-scale-codec", version = "3.6.1", default-features = ], optional = true } [target.'cfg(target_arch = "riscv32")'.dependencies] -polkavm-derive = '0.2.0' +polkavm-derive = '0.4.0' [features] default = ["scale"] -- GitLab From 69e2ae6df0df48ba6e65fa6d186d702f5b999ef2 Mon Sep 17 00:00:00 2001 From: Alexander Samusev <41779041+alvicsam@users.noreply.github.com> Date: Tue, 9 Jan 2024 16:01:26 +0100 Subject: [PATCH 017/392] [ci] Revert reference to ci image (#2890) --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2289341a357..dc4b3cf162e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -21,7 +21,7 @@ workflow: - if: $CI_COMMIT_BRANCH variables: - CI_IMAGE: "docker.io/paritytech/ci-unified:bullseye-1.74.0-2023-11-01-v20240108" + CI_IMAGE: !reference [.ci-unified, variables, CI_IMAGE] # BUILDAH_IMAGE is defined in group variables BUILDAH_COMMAND: "buildah --storage-driver overlay2" RELENG_SCRIPTS_BRANCH: "master" -- GitLab From 3811629a698482116281295c0d440e0355144a76 Mon Sep 17 00:00:00 2001 From: Clara van Staden Date: Tue, 9 Jan 2024 17:37:46 +0200 Subject: [PATCH 018/392] Snowbridge Rococo deployment updates (#2792) - Includes the introduction of the `fast-runtime` feature, which cleans up our features - Updates beacon client fork versions config to Sepolia's versions - Cleanup of AgentIdOf --------- Co-authored-by: Ron Co-authored-by: claravanstaden --- bridges/snowbridge/parachain/README.md | 192 ++- .../pallets/ethereum-beacon-client/Cargo.toml | 4 +- .../src/benchmarking/fixtures.rs | 1215 ----------------- .../src/benchmarking/fixtures_mainnet.rs | 1215 +++++++++++++++++ .../src/benchmarking/fixtures_minimal.rs | 248 ++++ .../src/benchmarking/mod.rs | 22 +- .../ethereum-beacon-client/src/config/mod.rs | 4 +- .../pallets/ethereum-beacon-client/src/lib.rs | 2 +- .../ethereum-beacon-client/src/mock.rs | 216 +-- .../ethereum-beacon-client/src/tests.rs | 29 +- .../execution-header-update.mainnet.json | 50 + .../finalized-header-update.mainnet.json | 38 + .../fixtures/initial-checkpoint.mainnet.json | 542 ++++++++ .../next-finalized-header-update.mainnet.json | 38 + .../next-sync-committee-update.mainnet.json | 563 ++++++++ .../sync-committee-update.mainnet.json | 563 ++++++++ .../pallets/outbound-queue/src/lib.rs | 11 +- .../pallets/outbound-queue/src/types.rs | 46 +- .../parachain/runtime/tests/Cargo.toml | 4 +- .../parachain/scripts/verify-pallets-build.sh | 3 + .../assets/asset-hub-rococo/src/lib.rs | 1 + .../bridge-hubs/bridge-hub-rococo/Cargo.toml | 7 +- .../src/bridge_to_ethereum_config.rs | 7 +- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 30 +- .../bridge-hub-rococo/src/xcm_config.rs | 18 +- cumulus/polkadot-parachain/Cargo.toml | 3 + 26 files changed, 3544 insertions(+), 1527 deletions(-) delete mode 100644 bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/fixtures.rs create mode 100644 bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/fixtures_mainnet.rs create mode 100755 bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/fixtures_minimal.rs create mode 100755 bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/execution-header-update.mainnet.json create mode 100755 bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/finalized-header-update.mainnet.json create mode 100755 bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/initial-checkpoint.mainnet.json create mode 100755 bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/next-finalized-header-update.mainnet.json create mode 100755 bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/next-sync-committee-update.mainnet.json create mode 100755 bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/sync-committee-update.mainnet.json diff --git a/bridges/snowbridge/parachain/README.md b/bridges/snowbridge/parachain/README.md index ddcbedab0c6..a38910da316 100644 --- a/bridges/snowbridge/parachain/README.md +++ b/bridges/snowbridge/parachain/README.md @@ -1,155 +1,127 @@ -# Parachain modules +# Snowbridge · +[![codecov](https://codecov.io/gh/Snowfork/snowbridge/branch/main/graph/badge.svg?token=9hvgSws4rN)] +(https://codecov.io/gh/Snowfork/snowbridge) +![GitHub](https://img.shields.io/github/license/Snowfork/snowbridge) -## Configuration +Snowbridge is a trustless bridge between Polkadot and Ethereum. For documentation, visit https://docs.snowbridge.network. -Note: This section is not necessary for local development, as there are scripts to auto-configure the parachain in the -[test directory](https://github.com/Snowfork/snowbridge/blob/main/web/packages/test). +## Components -For a fully operational chain, further configuration of the initial chain spec is required. The specific configuration will -depend heavily on your environment, so this guide will remain high-level. +### Parachain -After completing a release build of the parachain, build an initial spec for the snowbase runtime: +Polkadot parachain and our pallets. See [parachain/README.md](https://github.com/Snowfork/snowbridge/blob/main/parachain/README.md). -```bash -target/release/snowbridge build-spec --chain snowbase --disable-default-bootnode > spec.json -``` +### Contracts -Now edit the spec and configure the following: -1. Recently finalized ethereum header and difficulty for the ethereum light client -2. Contract addresses for the Ether, Erc20, and Dot apps. -3. Authorized principal for the basic channel +Ethereum contracts and unit tests. See [contracts/README.md](https://github.com/Snowfork/snowbridge/blob/main/contracts/README.md) -For an example configuration, consult the [setup script](https://github.com/Snowfork/snowbridge/blob/main/web/packages/test/scripts/start-services.sh) -for our local development stack. Specifically the `start_polkadot_launch` bash function. +### Relayer -## Tests +Off-chain relayer services for relaying messages between Polkadot and Ethereum. See +[relayer/README.md](https://github.com/Snowfork/snowbridge/blob/main/relayer/README.md) -To run the parachain tests locally, use `cargo test --workspace`. For the full suite of tests, use -`cargo test --workspace --features runtime-benchmarks`. +### Local Testnet -Optionally exclude the top-level and runtime crates: +Scripts to provision a local testnet, running the above services to bridge between local deployments of Polkadot and +Ethereum. See [web/packages/test/README.md](https://github.com/Snowfork/snowbridge/blob/main/web/packages/test/README.md). -```bash -cargo test --workspace \ - --features runtime-benchmarks \ - --exclude snowbridge \ - --exclude snowbridge-runtime \ - --exclude snowblink-runtime \ - --exclude snowbase-runtime -``` +### Smoke Tests -### Updating test data for inbound channel unit tests +Integration tests for our local testnet. See [smoketest/README.md](https://github.com/Snowfork/snowbridge/blob/main/smoketest/README.md). -To regenerate the test data, use a test with multiple `submit` calls in `ethereum/test/test_basic_outbound_channel.js`, eg. -"should increment nonces correctly". +## Development -Add the following preamble: +We use the Nix package manager to provide a reproducible and maintainable developer environment. -```javascript -const rlp = require("rlp"); -const contract = BasicOutboundChannel; -const signature = 'Message(address,address,uint64,uint64,bytes)'; -``` +After [installing nix](https://nixos.org/download.html) Nix, enable [flakes](https://nixos.wiki/wiki/Flakes): -For each encoded log you want to create, find a transaction object `tx` returned from a `submit` call and run this: - -```javascript -const rawLog = tx.receipt.rawLogs[0]; -const encodedLog = rlp.encode([rawLog.address, rawLog.topics, rawLog.data]).toString("hex"); -console.log(`encodedLog: ${encodedLog}`); -const iface = new ethers.utils.Interface(contract.abi); -const decodedEventLog = iface.decodeEventLog( - signature, - rawLog.data, - rawLog.topics, -); -console.log(`decoded rawLog.data: ${JSON.stringify(decodedEventLog)}`); +```sh +mkdir -p ~/.config/nix +echo 'experimental-features = nix-command flakes' >> ~/.config/nix/nix.conf ``` -Place the `encodedLog` string in the `message.data` field in the test data. Use the `decoded rawLog.data` field to -update the comments with the decoded log data. - -## Generating pallet weights from benchmarks +Then activate a developer shell in the root of our repo, where +[`flake.nix`](https://github.com/Snowfork/snowbridge/blob/main/flake.nix) is located: -Build the parachain with the runtime benchmark flags for the chosen runtime: +```sh +nix develop +``` -```bash -runtime=snowbase -cargo build \ - --release \ - --no-default-features \ - --features "$runtime-native,rococo-native,runtime-benchmarks,$runtime-runtime-benchmarks" \ - --bin snowbridge +Also make sure to run this initialization script once: +```sh +scripts/init.sh ``` -List available pallets and their benchmarks: +### Support for code editors -```bash -./target/release/snowbridge benchmark pallet --chain $runtime --list -``` +To ensure your code editor (such as VS Code) can execute tools in the nix shell, startup your editor within the +interactive shell. -Run a benchmark for a pallet, generating weights: - -```bash -target/release/snowbridge benchmark pallet \ - --chain=$runtime \ - --execution=wasm \ - --wasm-execution=compiled \ - --pallet=basic_channel_inbound \ - --extra \ - --extrinsic=* \ - --repeat=20 \ - --steps=50 \ - --output=pallets/basic-channel/src/inbound/weights.rs \ - --template=templates/module-weight-template.hbs -``` +Example for VS Code: -## Generating beacon test fixtures and benchmarking data +```sh +nix develop +code . +``` -### Minimal Spec +### Custom shells -To generate `minimal` test data and benchmarking data, make sure to start the local E2E setup to spin up a local beacon -node instance to connect to: +The developer shell is bash by default. To preserve your existing shell: -```bash -cd web/packages/test -./scripts/start-services.sh +```sh +nix develop --command $SHELL ``` -Wait for output `Testnet has been initialized`. +### Automatic developer shells -In a separate terminal, from the `snowbridge` directory, run: +To automatically enter the developer shell whenever you open the project, install +[`direnv`](https://direnv.net/docs/installation.html) and use the template `.envrc`: -```bash -mage -d relayer build && relayer/build/snowbridge-relay generate-beacon-data --spec "minimal" && cd parachain && -cargo +nightly fmt -- --config-path rustfmt.toml && cd - +```sh +cp .envrc.example .envrc +direnv allow ``` -### Mainnet Spec +### Upgrading the Rust toolchain + +Sometimes we would like to upgrade rust toolchain. First update `parachain/rust-toolchain.toml` as required and then +update `flake.lock` running +```sh +nix flake lock --update-input rust-overlay +``` -We only use the mainnet spec for generating fixtures for pallet weight benchmarks. +## Troubleshooting -To generate the data we can connect to the Lodestar Goerli public node. The script already connects to the Lodestar node, -so no need to start up additional services. In the event of the Lodestar node not being available, you can start up your -own stack with these commands: +Check the contents of all `.envrc` files. -```bash -cd web/packages/test -./scripts/start-goerli.sh +Remove untracked files: +```sh +git clean -idx ``` -From the `snowbridge` directory, run: +Ensure that the current Rust toolchain is the one selected in `scripts/init.sh`. -```bash -mage -d relayer build && relayer/build/snowbridge-relay generate-beacon-data --spec "mainnet" && cd parachain && -cargo +nightly fmt -- --config-path rustfmt.toml && cd - +Ensure submodules are up-to-date: +```sh +git submodule update ``` -### Benchmarking tests +Check untracked files & directories: +```sh +git clean -ndx | awk '{print $3}' +``` +After removing `node_modules` directories (eg. with `git clean above`), clear the pnpm cache: +```sh +pnpm store prune +``` -To run the benchmark tests +Check Nix config in `~/.config/nix/nix.conf`. -```bash -cd parachain/pallets/ethereum-beacon-client -cargo test --release --features runtime-benchmarks +Run a pure developer shell (note that this removes access to your local tools): +```sh +nix develop -i --pure-eval ``` + +## Security + +The security policy and procedures can be found in SECURITY.md. diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/Cargo.toml b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/Cargo.toml index db3be5f91b8..9f8749c89da 100644 --- a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/Cargo.toml +++ b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/Cargo.toml @@ -77,7 +77,6 @@ std = [ 'frame-benchmarking/std', ] runtime-benchmarks = [ - "beacon-spec-mainnet", "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", @@ -92,4 +91,5 @@ try-runtime = [ "pallet-timestamp?/try-runtime", "sp-runtime/try-runtime", ] -beacon-spec-mainnet = [] +beacon-spec-minimal = [] +fast-runtime = ["beacon-spec-minimal"] diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/fixtures.rs b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/fixtures.rs deleted file mode 100644 index b50be81360a..00000000000 --- a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/fixtures.rs +++ /dev/null @@ -1,1215 +0,0 @@ -// Generated, do not edit! -// See README.md for instructions to generate -use crate::{CheckpointUpdate, ExecutionHeaderUpdate, Update}; -use hex_literal::hex; -use primitives::{ - updates::AncestryProof, BeaconHeader, ExecutionPayloadHeader, NextSyncCommitteeUpdate, - SyncAggregate, SyncCommittee, -}; -use sp_core::U256; -use sp_std::{boxed::Box, vec}; - -pub fn make_checkpoint() -> Box { - Box::new(CheckpointUpdate { - header: BeaconHeader { - slot: 5809344, - proposer_index: 101696, - parent_root: hex!("ea7ce4ad810829cf37a2235b1126c82aecfc5955a1647ec83640cf3f7db91bd2").into(), - state_root: hex!("56f6363d3604e61a907c774edf0bddf6477a8d410f026414bc420f751de1f092").into(), - body_root: hex!("8c799aeef815cbc4499e0b46723623105afb177a5c522ecda3415ad9fb259e6c").into(), - }, - current_sync_committee: SyncCommittee { - pubkeys: [ - hex!("adf5a4907639db7bdcbecbc295b57d8950b0abe34ab17798686643427023c4f3983550d1496f81a27e52b070e4f4e6ee").into(), - hex!("91b036b30405531cacebf5d4f7e939b44438bb9942123ee55b44453e32febfbf2c846e0e4fb08190b01a000d072dcaa7").into(), - hex!("a86e70f00161ec6c4b780b4fc631c8dbae979f1e6c9ed037dd0745833ed6e3e18831478eb4753861f339293c0508f4d4").into(), - hex!("84196b1f39fba1fb7570074e7dd2768ed5c28db7f91a6374e413c8fc82f97738af771f90496526088bfa1ee2c01ee299").into(), - hex!("b9a230fc12d85281cbfcc7f5e6b13ab17b3dcbf0adf256d031c01acb30734d061683d40fd62175da73a621440bb04367").into(), - hex!("80b8be5a3d6f39aa7362c5feee9f89b75d1e5c2b485ea9a776c60fd60dba611e9bf5ca8b2528f42651b3dad212acfe77").into(), - hex!("ac8fcfc40028d04bdbea87b4b335781e35e10f881bfeb07b94c538eb37a43b18b1a04aad3dbe80bbff6e128017251f2e").into(), - hex!("b0b2136cc729b7de8868c02de6247ff2a68694296c78f088ce967219f08cfb7be9e1830e2630b10ca650c715d85d89f3").into(), - hex!("a70627c99777970eb9bf3268bac06bdc41c2ead41b1b76d30e7fd2aefe83319461d03aaf7ab93150343be9fbd2e48e7d").into(), - hex!("9599aae109d31ddc9028c428a148ea9ebffdb5ab6a684895dbd3772c1baf947c8a255e4c7ebaedae2a9e046219d80d76").into(), - hex!("8652e099adb88b2a25ab64fb01314e24cf26dbc4ae110d7fd73d74a0e0a4fea2ce2ce87cb1ddb7c0b9fb50cc6afa2153").into(), - hex!("83ba74c6e31073865eaed3c38a8e885ee715f03cfd6e36929655b6aa790d8f676c4ac4ae27f963e311d00923357eb087").into(), - hex!("86b05425d880027fbde9be3ea526283c5b958ccb31eff997d9d7b5e3b70e2d011ed95f891248082e870d55704a471deb").into(), - hex!("a4eeb958121bc5be5b1a68b73faa83b19272ef2f2cb627431be08e9844ef9d4548b4208670754d0954e5b012e3933859").into(), - hex!("87b0119e4c54aa2b4f8260f9ace7722788578bc6d822361d011e751caf13be5ca94b7d5842df5c16e52bfb4d658a405a").into(), - hex!("b696ec7f5dc82655cf027f5827fff3ce39195c1ee4ea9fba1808880cdea16d6086fb583edfbf66608e4f33211ddf9f27").into(), - hex!("a69bafcb3af59786acf009cc31e245009156a7e4fd2af98cdf2b7e63c39aff2baba08a338cdac93e94f6132b2cfe7a7c").into(), - hex!("8aa0aebb24b8c62168b255b6041474e8abf0d589a7467bc4712d910a9c2d470432d251e336a80dded27c0e9eea43aebd").into(), - hex!("a08d6976d3579411080957dfa2ca9487b1c4d8dbcdf640c1fea0a46f2c0228c2ddadf0553781c3e0dc5c7503b1bf29a0").into(), - hex!("a4abccfcfce6754e4d6c5c8bbad6668a55dc555ba99189936385e4dafa0435b323b813ce69f76e24299b5842c244139a").into(), - hex!("b89e4fd2dfb46c2af6df73f7185693ac535b67ab31f2805b1c24f400e0068cb32aff164b53668512f5895883189f7c02").into(), - hex!("b7c221a5884d10048bf9dd8611fb5231ce444fb756e59dd60d18a2332e889c014b27d739ed6012ff86056c04f36a87f1").into(), - hex!("a82875d66a4da52d6eac9dcd9ba9c728332253ad4b83acf1601a34efdd0c398eaad4acd1a948203d1bbd4a17d01a7b56").into(), - hex!("8c0a8ec162b3d48ee6a0f39620432cd67a1eb33a6d6f7bf1aada4f24c7498cf2e2b2476898f14c875f5efcf439aa0bce").into(), - hex!("a4b5d6451ae5baba3984bfbd5eef59543bf7c923662ea182cec6bb29aded9afd4c89e618ff756b5290506e0bf5a7e690").into(), - hex!("80664b43e3bd2f6e8eeb81a46cdca4f571499f3f0c77eb007ceb33c5b3dc18348a68cedc19d9967117f21a6c1ea29060").into(), - hex!("9174e46939c6915c757e793c9a02e46ed49d869216b720d0924b9697d94098182cad2cc6d4caf4cf140445377f1b4c80").into(), - hex!("b6e25cc134e089d306c648228d84aeee9516c8a276a2d37b54b458314b8f8980d49614550e821aac31000a5e7d518fca").into(), - hex!("ab1ab623a70f1e33cdbee356530a6f8fd9d00b2f9d8f94c0854816e5dd2bb8b258b5fb7a89ebc0725d8ebb74395847b6").into(), - hex!("8e75ea6f0678abfe1a7a9201c9fde992451327d61290fd803b3a1cdf2f7537fd7c23e0e06af5bb886a28928d0baba1c5").into(), - hex!("b41f4d4421de7b94eb9bc61602d08d77dc3f5f5d025e04f44c1426f14e8f707031b9e1d3a6e92c200f54166b2040f0a0").into(), - hex!("a8fa0c61435b851f9bda4da8dae0d544984ba5c0fef338eb6896b9c08306c3e2aec0a6c2028da319f210387320df4f73").into(), - hex!("a884af449df4cbd39e161de10f9d1f645eedfae0d259ddd84347733836fded047ca079916d365ef3d93fb354c8c795a6").into(), - hex!("936970bdeffc92f32915d141ccd8334df7966a3cafecb6d33fab9f477c389179f612cd6e368b615a98112d71756756aa").into(), - hex!("88dfe631c1e16ec3634e06a83a857ce9c909cb5b05d40490e6d02e553dd3bf213f0e178d31b4d913a4796b7226ab3ba2").into(), - hex!("a0c8357b4fb9c4431bc88e6336c2218590a7cb351ef4405a80aa6d352912f0b3110f3a09eef337bfe98da6b0841c6214").into(), - hex!("a7def54e08e2cea7def767d1108bc5c24d64e2dbdea9d07f0c8c63e60eec2db4e095b4a84bf6a4822103560b0497d1e7").into(), - hex!("80991c4f933985d9662d2e047187f244dcbb79606410aeb66ab250b2fdb9bd9daa392339e9b16d0d07648e847b02f942").into(), - hex!("b63fe559e2b4580238a0b0ce52ab8258838c2b64c1922c56b64cd65be2f88c140cb4e6ce96932e92f1ae06b20ee9e613").into(), - hex!("926ece3480c5c1f24f03d8289dcac7d3b202fcda277dd4453294dffc2953d91c842653a9e272b76fe2cebe1de3aba63d").into(), - hex!("930d29990821d26a748018bb6998488d5de811c8ed506c213c0ba346c8011e2d7c2235aa427a320129c1d016948eabf1").into(), - hex!("ae4e3fcd6c99a8f320dd4d160704db6baaae9aaa885f5d792212ea03cf06a459eb4a2730da9161ddd72a5e6544744e81").into(), - hex!("a01ae9d4f0008efdc5203abfdd0807ee7cc58c49cc5946d0b991ea2e069a224f0d99ea714b4d5cc464deb57372790660").into(), - hex!("ab17902ab255c575a133ed47fbafd62f898748ef6fc33455a2adcb2d4ea72c31255a9cd0c545d2ad8007a5a694f13371").into(), - hex!("86e2384e0469ab8ea9c5628d619d10336b3c0f334969dbc3335dfd72ed9899639fccfb5d1d9d6667a0dba20651584100").into(), - hex!("88ededd6ef3502be7c3c1b018cd814d4a8f98a7cf9521fe9cce6faaa6056315e22828397435b57d15e996fd15d7d700a").into(), - hex!("affa898a30a0dd2ccbe8d46c5a69dc1a8696b311094ac00e8ef6d398f6f132edb2d823004bc7895ac53bc09b6fb1059c").into(), - hex!("ac9f5bc3e2045a1eb356d88f2a62781fdb5775349c9bbdd9417b7bb7a9132a1cd42bf4986fcdc706eabbce45ab9f1cc9").into(), - hex!("986e3813ade7b9533ccfdcd76ea17490bc3dc62c8a596c8d07b246c28d7dea465c4dadda05111d2793d72d317c7c2833").into(), - hex!("ad4fbc51581cd520bcd0b88379ec0482c94b2ac344ce48a5facc1cf3e026edb088ce5cba5113f2c31f630a1fb37c5214").into(), - hex!("b499bfe19a22900c46bc0af1925887bfdd62455a3b85144e44b9a0a3756548c72b4f5c61f21c15f5e70b627d9f53a9c4").into(), - hex!("a5f40fcbe99b494c6acdd65ec3516d5a4a784ffc501e686764bf655c1f2f4bf784bac6b85e961d6a5ae513555a638323").into(), - hex!("a44c695e5490bca1cdc6b69fa80d6540239e42ae1765bff39285d1798696574c409e27c288b3b57196cf7c1753366969").into(), - hex!("a1ec5d9b8e55803477fbdc454d9c5cc605ead24147e5b04a03f80558a14f1e08bd6557f3fd11dab06a2816d32138cd43").into(), - hex!("98957c2e0a82210e2329b60dac05dd8b219ca00b18206227b725d011bb2f8b0dc1a79149a7d49a9a5505301b1b3847c5").into(), - hex!("ac8df8b1b596039c24c185108c89ef4da384e92c957c84bdefdab923e4be7c0e9480d837e1ff2e6269828b86b0b9f6c2").into(), - hex!("9358e3a48d4938b189059c3696169d31339851a1f4205dfe4de423ad4b96e7015c0dccb8bcebb64c1c357b65d5da6914").into(), - hex!("af1ab721df52d8b106449aaed05761b637c38f4c5513062afa55a09b94c8b088fe98cf430be4633b4f2f818da545b37e").into(), - hex!("8b8c063568a13f6522fc66285ab116a06d5e226a72f5a00fb321dd9b7d0bdb53a6b46ac17a1c9faf468c19b128c84488").into(), - hex!("b537f79bf008cd16711390c188c52d8dcf23cc41990c82005de2b0ff1fa09de85d3c34328ad9124e108ec252ec667f70").into(), - hex!("b9e8cf06d584197093d4b4b1e1f745786bb1f9772c0a771b321ae2dccac167ea79632138d60d8ed6dbbba2accd0a3c11").into(), - hex!("a674106b2c965c708b98a9f28a3f511f5dd8dfe7b2b9ca64a29152c7fd8de428316638d5091412e22e50406c372d9950").into(), - hex!("900a4953af5a28ca5b6f789a0dab9a03e3e5b9a0e866465d371b871fc59ecba31b524b0fc414eb7467d4384ca1e4ab5c").into(), - hex!("8b12a6114f8e0947995d72fee19e9204a4b552a85743d5320c1942bd2294d52a2d6d346f5e930ed788fc929069733297").into(), - hex!("a118f4b631a0bfc00df74a94930d69075b83be0bfec2affdf5e1ca4762d40592132108a7d2088891e7fe078c84ea9d9c").into(), - hex!("b074d18f84787d245018a2dabe2f0a51bf2f3786a802317122982a598f7f953339468e0392665c3f3a6b8fb17cd8f72c").into(), - hex!("8e6230b8186009b765ae6b176eb7dbcf503139472c0c2c5574e3d608a49932f0b852e744d2e215c58512ed2b4e8178da").into(), - hex!("98cd13f8400ecc9db458cb81840ed6467795f54f25680931881808909cc661230716fcf8b3fc2b18f4c12d30c32d9e20").into(), - hex!("b861f89275776bd640bc7d0d347df31e784292fa14ec468a6b0e8d64a9b077b6bdae1bdbc56385bf8f5676ba62002606").into(), - hex!("80ac9088ce82fd7a90c91b24e5e91636ed76844303a3b1105bc284b4e9a860acca3207d1804200a55eeb3ef45ba97558").into(), - hex!("940bc07a53373f075128b6c12f59120bc7368289d5a960c55d52abb68e8444f6f830b07850d31a9ed137f5357b38406c").into(), - hex!("b8c5919657811270976eb45b9f3f09be798fbcf6b34ce7443fb36207816b6a84d2b945a6e6522480c2feed12ca980df9").into(), - hex!("8294e6ce7d7d3b77bf48252eb97cca47a5b9dff1b8c97f8b7af8034b938864f38bad932bfe44a9bf4df81e394aee7ef2").into(), - hex!("8d9075a2c42c1cf51e082ab1a57a66670f0e81af2a651aacac5aaaf3876711aabbc0c96e44d883e6ad8a91a81be22940").into(), - hex!("882aea71e4512d5c41b5fd6509ede0fa35a49fff9648d277b531364613342711b2c7520a5f8d58ff31b7fc9407f968fc").into(), - hex!("8a34a824cbac06cd99fc68f36ae09c6adf2d472fcbd378cda61b838c29ca9750a7f7d63d9b61d1f30deda1ce048ffd42").into(), - hex!("a4f027b5466de4fd633cba98d2c8c78db10f91c8bee76c32ca5a80c5e87ffaf19df84e675f31bb6c14ee733ac3d4a33b").into(), - hex!("b990db2d743b389132d4d8281701b348bfc52f707e6553f309e4f59706871142e6b8e3d081057a5c43243911148318bc").into(), - hex!("a4500c88a58971460c33a404a65260a9e21c4a345601d1686ecc352ab088b2bd93d30930383901fd2d042dd037286761").into(), - hex!("a4de9078286cde237b4ff2da52a0fc1b8fe7b931ac35b3033dca0b87b5c86e58bec951a66a7308fc951ebb70fd0d0bfd").into(), - hex!("a9adb6dbff69b115be1cb37d5ee3a95d8c9f466f059128b6ab197d4119f6c0f87d1cf4d14d4beb2a43f7913700c1d909").into(), - hex!("a8a33f167e473eb2ace3bedc1cac2281bc9f522a0fdf6a9eb365859b9116067e07b7c380e8ea4dd33a4fbe23e2412be5").into(), - hex!("88c3785f853a192c50c38040ed52c413084dd069729cb14d806223f8a51aef40c21648d1e03bbbca031ce811e1b708ce").into(), - hex!("a7db446f88ef0d018675c0e7be0e9655d098529ce4b4c92ad809ed9f588c3f6c6dd98267ae0efb1659dc16a29e1feac0").into(), - hex!("916fb4b864ef46a2f8f570364cdf02c93d8432d8155e7ad1a15777d7f5d5fab94797257d0943aed5f16033528a4290b9").into(), - hex!("b9b7ae2ec02b0694d7828a69bbd1fd6e9070cc217319dc4e8fc854e48f5ce6e133fb0d5492e2f87e7cb8d3d557f17037").into(), - hex!("8cc36ade2b8039ffd41459272091d9cc4c46a49a187e18e9e3b283136831724313ee6eb5954c34acf9ecf7d79c30dcfe").into(), - hex!("b89a28db91eb06f191731a927445ca64cb685a206f4d77f335f510eab3a4973eb1d199525aa12df17f97cb4e079bc35a").into(), - hex!("87fb2881b92d5d9a2555080afe033512fd93306bd25f4a841d034c0fd9685ae09ecd29d27523e8f18664cdf2127ae6bc").into(), - hex!("aaf63cd83256de5b8558bdfd7f5fa44b3b3cd767983484ee482241286f82c6f51c1de99e2c03c8c99e6d4a27b7379cc1").into(), - hex!("89b52eb17e1c2868a3da6727e6f122046739c99cbb6aa7e30f65d7e649d09540b7ba77ea3efad77be597e48f7abe7643").into(), - hex!("88d097674b763a770872f17266f38200a4034347756c5ece6f11fb841e82447a75f6f3279ba8ab54e668b2072c6596ef").into(), - hex!("8de58933f07ac60ae919adb4be0becfb5e6f7330708a39cbc4c988c79033f0ffb365ae2a6308c234c218f0e45ec1ce6b").into(), - hex!("a4ec080db7716a0eae593b0ca91a16273abf534b8d153232e4b7d613c9fd21081bc8442d6e57a6e8e026c66c93bf0289").into(), - hex!("b680857b566466d1fb92d78a09b75d93753c275249dd05a17702e48560e4df5c7f9ca68370847250fd001433972c8b0e").into(), - hex!("84ec67623fc58128f4504b071b53e3c0fc60ed07318febc8d450035567691e2e58468b6799e5f3d93536100bb4b5f3f0").into(), - hex!("b22ce364b11e164d3df52050d59085c29c398556617277349637290b193727e3942064693ba1d7bda313905908a071d5").into(), - hex!("876198b5734f1ab5f7ec0231110e9cbe59d116ccc410678d5e0108fae42bab5dcc7cd15df200bc71f471ecbeb0e80d68").into(), - hex!("b081fc87056c34a8a78cc34f308502c5b6509adb0b344e83227b997aade90d6f0f1b8e5302601ca3217ecf9dcfa24ddb").into(), - hex!("8fe71e517db52831a0c4adb83fc6524817b9a358fc6bf58c03c91d4125482921936391e54c767ad2f13071e0e5ea266d").into(), - hex!("91212d83807ca11b030e5ab72ec85a8d13d468c714fc97c20b5d0569c382ee270d2ca486c88354994ee54f02dacbea50").into(), - hex!("b022bf24d2ea893125f3a89186f444aa5f301333f0667eb5862586a5eea8233c90202064eaf9363f7b367a6dda15d45b").into(), - hex!("b1f45fa596a32d3fe267c830eb042432eec6b79efcd5c84ea835d7108bd4290fb64749ebdf7e7e51e6138fedb3cd2eb8").into(), - hex!("8567d2366c584d975bea34d4f9e2ce62a62765125326c5e56b5cda08fd2f2e7f769db47eb514d2d9324b645879c82a66").into(), - hex!("b4816fa77c76e1f75e6fa903a4c0c031ac7a5f5ccb5f553b4eed83bb34067480804c0f6f308f8d0fd723dbe2198b0608").into(), - hex!("a9ceeea8878d799fbb6d52dc4112ae712429b9213f72b284698d68ea6827432f34e51daae1727b5402916a836567f611").into(), - hex!("984c8ca226df18ec574e0fabd6dc9ab3a2e1b319c4b6ab5b19872239833dcf447ee5d720305b2385d65facd297704809").into(), - hex!("b02fc16b3530532a2373776e2512421d6d2e42f3fd3c3e71393706d74ef9324571c8c1ba7b9caf65dedfff2bad946d71").into(), - hex!("849faa2060a75d08850b54e06376f252d9cb4add3e740225ee37d23e29f80cb9f98188a7eaf6a381af4b4bcc9874b792").into(), - hex!("b5331ab6646a8be3bc37c5fec56a597b914683402828dd4098b189f245c638e063c933a542c0122f063f98a9468687b7").into(), - hex!("868d8214f26e14e71ae0bd514275ae9442760af72269790228e733005293019984d3d463c2bb82936193dfae8c267fa3").into(), - hex!("a88c6c4af4b9d285997c9b5cca7e22ab9b8e5873ff36455bab6a6dd4518e966079524f8c35391811f16eca421f588694").into(), - hex!("a6f508524a938fb49a7da70251fc8300192882a3fe784f0bc51027ef2193d90c75d0d0720f2f5be634d81f38f3d85b8b").into(), - hex!("80a923acf2aa0349b4852f47edec37cd47bd74447f2f91c110ed092d015887a6625d5f1fd1f5d00c994edbff1435956c").into(), - hex!("84ed9f1ee0db4c9ae55492fd07fdd44851a6d0209da5b521435229b1b45d57c3b835af627122756ad0e63e915c15909c").into(), - hex!("b4c4c1e6fdc418bd29cbe8082fd774f678dc28a51896a51349c888ec98124b7a522baf70b820ae0729696624f3695af0").into(), - hex!("a8cdde029503aa3e23776a67952b2bc954fc0dc06f07a78bc94e6408edf381bdadc29efe4e5340a9b7efe99a3f3b3687").into(), - hex!("ab02a92f5ee21035e6e3e40a026d8d5680f98afdbf82dc037dfa30a87a1c101387a0085da8474989b24196ff494aa618").into(), - hex!("986c88a5d0bc6ff4127e34e0a5fefc1290936ec88d1765e776e199601f9660a8425c1fc6defff07fb81576461d0ed7bc").into(), - hex!("abe2259e880aa8b587ac9a31f794895bb18ff1bbed378a70fa09388e5a6a7343c072401c856bdd92fc2f60ca11056aea").into(), - hex!("8c04c98815c0c1f281c8783ff8098b0d806039a39fb2f4642a08f821c02506bc7c80ba7a1f4b225ecda9971ee3a22121").into(), - hex!("87b7bb0cce6244aa1a540941f0ff5ae4126fd4c62bd98d34993380a35e1c9a9f43b561506e5eafc1ddb8aef131403590").into(), - hex!("93cdf5f956e8b40ca0e31cf559937b997897c137a411930ca28075899abb6c08dd6aad5b2bfd5c09f07613a6854b3be5").into(), - hex!("83ebb284e03b4414694522caedabb391062ba9ec373e94427feff071644df91635ef498dcd9351ae259c5b15d6edbb38").into(), - hex!("80747223ba06d6465e26a354b79c42ec0624d33cdf015da7bcfb31f7009d92aaf6321f4a921f6b38e0a394a412edcefa").into(), - hex!("967b4b10a341abc5c01ffd413103c6468e3efa32c8ddc7e8622fd3ab2a765a420e0be3c81e1da05679becc5bd03e59f6").into(), - hex!("8a01b90d551f26c265b9987c67b641d15bd3b8e5af5c25472037645da05d9d54c0e59bab32578eeb3c1c5889f4fd9aa1").into(), - hex!("b6b38e40e3fbb31b257ecc18dcfff2fd850a41c2cfa5a642b0c383cc1a86b2b9adbcb22130665f544f1d9fdf87e92dd2").into(), - hex!("b490529e0da56e7e4d4cb2f79b704576c8b6569e9960dafef059dac0144b29ec337f4beb515465a57414d8965268a3dd").into(), - hex!("8a3b14616bb721543bfe007f1a042e76ef068a6e4f8964d68dbb7a733ea92dfe4e51f4008aabaa01a8a3566b00d083ae").into(), - hex!("8b82dbd0d0592d45d6309c795beb42274b74d844cfc393b34cb6992e3b25ea8f62f777124584eedf482949bb999ca5c3").into(), - hex!("918226266d7f02b2081edba64ca4b70339b7a63ef9194cd77a214620bc25618495cb4335c0c3621c75f821e685af3f1e").into(), - hex!("a61f56310689b9f383b45e8c8c647bd7150fc6dc3be96afb464b0c67c6f8c73ac9941bc8a5b0e2093255c204646c94af").into(), - hex!("abe204f55b8dd101bbd554561c1a7b50c01b31c967f6cea18dc898a10021eadca3c314f6b7afcc2251682717540d2100").into(), - hex!("a0cc3fbc4a05e3b5f93f4df85b92c1bed221f21700d8faaf84e99954cf6994d0052c8ba8ab894503b5515bdd1460ac5b").into(), - hex!("a5e5e175726b31163e13447e360f835ca64c3883901fb1fdc275b487106b39fdf43b83ee8f3985dc85157b94aaf8c389").into(), - hex!("b34106e71862b290f7bb47e5492417b07b541fdba23ed474f29d666cfb50bb5a3ea137ab717a41ff769af53ab385a3d6").into(), - hex!("aab726a0317c365aa15ef9527e5101b1a90cdd60888b733cdbd61dffac3374f995206abd154d099b2dfa03dbe666d503").into(), - hex!("b3fe9956454604b2aa1d51480ae96182ad1a8af64e80adbba1034619090c23d0d7ddb4163f400399d5946babada2f5a1").into(), - hex!("831a0d4008865576d9d0200dbe80eeafa7e6e6d442a46ebf949f39e32ad311995535a261795a7e27f2b23a6d506b7a33").into(), - hex!("8d7fe284c9ea1a2dce6ac70e3f225994f65ba9791520fecf5359b80f7c32c1e45e75b8b787ccf24b83c79301e046bb4d").into(), - hex!("b00df7ea640dcdaec66317924090f49380edc5c669ef1249ec8a24a3436b4bb41be0edd4cb0d04bc6ffd540ac8efad18").into(), - hex!("aa55d72470c024627edff24f9a19ae958d6b382bab6a24581183f762d736ac10f189ec3f34a7a41516f81696352f16c8").into(), - hex!("99e172cdb14a23161b5e8aa80121d98e69506ae0ab956912eb2ed959b73ee901852f263cb65798554ec0ee35089b4c03").into(), - hex!("84ce8ec6a7debf3cb2e53afff7d1f68bf75b7b209938192c7675286b17489d7996ecd9514c5233af0a17390b9982d805").into(), - hex!("943cddf3f5a6dc04f425aaca25be44438aabc7a661476761de596fcef5746f9d83c361da3fe1f21227ee5b9bf9a3ac76").into(), - hex!("aa81e66cb01e77c5db882792e9d896c83aa418b12c3b5201e1937ba5b74bf5fda974c82f6f40e3ca48bae72ed93437db").into(), - hex!("83bee12657fb462a5988ee26e2d0ef8b11e5fcec108724f6135e95913d7f4ec338031b697b24fd7a650cbeb088b26733").into(), - hex!("ac0070705c447e635b8df509de9ae03ea9b0314fc58b3befe14c316cb7b70ceaed081aad115a2126ecaef630c6bbab0f").into(), - hex!("a1c9c3b6f28c14ba91cf063153c50253d82440b81dd8ef938e181ef4116ede0b0ec62844e1d7e8b387668ddb8644852c").into(), - hex!("b41811ee8e385836fd709081a9a65a33ae1571bf943937615e97d49aeec3289624882915a5f5b6ee98601e752bac1212").into(), - hex!("a59cfa6d60f5c3b62197d3058a9b42c66bb841ee5d67ae34ad452dc70974de0a56a770c4ee5905c0d214c3d81a5269fd").into(), - hex!("ac47ff714d42056df3962cb4494019c977fb6200cdeabfa3ba85ec7d7d70c7d3ff4aa05e26aeae6ec6a3afa460244ea7").into(), - hex!("83c0ff348f1d018485c18417037016ec592c249830fa649b27754dfa70b94a549a42eada20ab1c4de2a5a513d742186c").into(), - hex!("ac5ddeddc94d18cbbad0e1889a2b64e91b3f927d3eb666ba018807f1e4e1451a43498ebacf12fd370b62c5386e36fedc").into(), - hex!("91606f0315fadbc42b1b27ff35b5601196a7a8beec3d5c76643e38ef28f0aef0aba9123bac7ceff0b297ca53727edbd5").into(), - hex!("af9cd077736f17c89ab4fd21fa2cee63b16f67277e9c5d54663f6d5a7abc3141f3045558899da70419b1e92ce88eba86").into(), - hex!("ab0757213aa3fcdc326925e0dadc2206f43c53f7abaf34a077f1cb29427261b4bd9981dbd1e33fedbd77fe00bbdaf8bd").into(), - hex!("8c97d256f9d4e0f309522f3899c5f74fd7e8c4dab6adf4886e7b058b323e294229fafce28871fd39e5c43f28c670b8a0").into(), - hex!("86eb85ad6fb7a3d5cd9aa5b22fd648fe9db688fe663c835abec75a6bfb67af0df0421d24203083aeb8ccda06dfb230c9").into(), - hex!("afa2dd3712eb94c9097135a69573c1f373ee0d7916f4ccec5a62445726aa4c1548bca45038e1a44ab7c8b7e3ea22dd6a").into(), - hex!("91e82407c442937af665ff8952d8b7ce3d68ebf807166aaf0fd710b76c65b39283e511b3314297ab0f2a9c8a2d76ffbe").into(), - hex!("a52cdd05f6e254c6da7a00c9210e33a49658f035b78bc7f15b527fce20c3893d3f7dc27a616eb3e107da060df251b082").into(), - hex!("81e6ddbaad6a18404832d2923697ea8df8dc3b39e53390269f197b976b5edbad074639e1e7bb25ae87b00681973fa021").into(), - hex!("a776979b38184661cc36ae9bf99b98cfb64babe37b16ed7e16e33e2187af71d9f62af4fab2bf0671baf3172727741d79").into(), - hex!("9395a004323f4ae604518224292a1fdb359fe9d4ec2a2262f13fb33d90a9dc50040d03fa6315a5ab2db043e7e16fb971").into(), - hex!("81bfad9e94c00fc810c4e63042fed6dc54c7c48637064376d5a4df8c8d6be3c2eed335640bf45bb8df99327a7e070d06").into(), - hex!("b6b38236ea973f91eff175206c4328cb97335bc8e498d9c9a2040468885f7d8464a8a1168929cdcc4c59513885e1589c").into(), - hex!("aa14a7baeb7b6d0048bdb8c772de512001174f764b37396c6481bff5aad30abd6143e4654a3d80406f8d08948ff8145f").into(), - hex!("a7297d6c09873e481c04f2e9e9a07567d78da504d2929c8b9d8ecae1c4d919611e061caa632776a8716b20e031cfd203").into(), - hex!("a0942935f58ef26a111d77b1c4598207eb6e3414c106b286f1c4dd344b3e70d3a46595ebb657e43f0e71dfff3b532382").into(), - hex!("95dca5de041e96f8c64f945817ab1ad62414b3002073b18331e288878c7a889774468d3c24f04e0714958ebd79ebe71c").into(), - hex!("b64f58f4eea309ea03c60f6ee66107fbe45c5ba81b8ea397a515435a179ee86bd098cb9acab4f374d29c8a388152fc6b").into(), - hex!("a70fe2ce7cfbdc22183a1a81c779c6071199768ad9b39ad0727ced4fcea5fc79e9833279ce93e1ef16cfc6dc0ef4f15a").into(), - hex!("8169d05ef0406b661022af53dde8ccd7315b3e35065c568673bfe5e59828480312a8ad418ad431beee12e7882d11142e").into(), - hex!("8148070a20eba3b61bd168e00ae8262d698263a8f22ee01ed6d46d154a08708a85533f54935bf92ee6ab0c04569eb3ac").into(), - hex!("b5e4f8b8a011c9cde6a9338d7c751ce2828fcf41b40e140ecf543150a5b4859f87836461d0ea2ed7cd0e6bfb8febdfc7").into(), - hex!("aab7b0022a1791339fbf567e771c43e9a2a46fcfed394b7216b556aacdebc259e5fc599eca66b12c23467b2443fa9c76").into(), - hex!("a843e5929fa14bbdb5f370d28547a7b585443f4d2fdf8e7237fcbb93a5220d62c8033665996f36288127a2bb4822f357").into(), - hex!("92a5abe1a8d508193c88827f93156e84199b14731a68b0b434663e5b9ce8e6e3005ccefb3ad8330c56fc0898eb9334d2").into(), - hex!("948c5a4bce25157f5f779fcdd89bfb4747a6178d464d15148742920aa2ab7fc63d6989b586152e1e79eced93f8686206").into(), - hex!("8702f3fccf470a294946970f8ecfed499f5ab3df799601f872d7be3d9227ff78a764550fd1a97ab25b7be96d366c82e5").into(), - hex!("85c5f99e913f1cb67a30807386b5292c841b51e959a13912fef2e0f4ba84ab3b1c483dd5fd33e80774de19695b622888").into(), - hex!("8a903e39b9b46dcaaca4fc968b298430b982ed3916f8ad533ceef5131dd507f1188fbe856c80bedc7bf34799743fa86c").into(), - hex!("a91ecd938c2a399b97576c43c5d1621fe748732090e360fa1e3ddd145438f9569d39a7be9d032b435a5d14ca4c905d15").into(), - hex!("aba9def4db5bbf2ba185c134f7734feeef976573e20d76aee476bfaa2af389ba5576a1476aae2d42d5470a46ca3f58ba").into(), - hex!("91d3529480d066817c0111bbd92714a40472ed6c877df358de98f0258f79fb8ccd54a4fa8bab3b9cc15bfabeb620c196").into(), - hex!("8cbce4e674d90185c47225c587dac654428427cef8a563cb89aee6fdc2ae6f12a8b11be46c779ed9afe38ea97d7d71ec").into(), - hex!("ac684cedfa58b2adbb6a13a94aa8398ef4a14970f5a43a344986cab68fff7fd48f7bcdc0506026eb0a2867efe86f283b").into(), - hex!("a21a2f8df2b811550d6e115c095d4d6781a84ba25b7f4017adb318776ba7452f48ed8b83a6a94aa68d83f2226a4c0549").into(), - hex!("a0d96e01d937144627c695aa4256f1d1a16c708894ce854f5ac656585e6852a43c39080909e7029b6611ef519d9983b2").into(), - hex!("a2f32ffa61e370d087058cd3ffc534da6a917f75ed5de568938885cf5220d474c930ba9bfdce91e031aab3b3167ad362").into(), - hex!("aa6a7c0162520c6706ab0f6188b718c1909a4aa12e71afc1c2d40e51fe44f667db0e7f1f0cdd81594447e267720f2dae").into(), - hex!("b4f16474ec3f37765e8750729f3245167b82472ec454329c9183a5d5ec939041d85b83523d11f2b895e2d15586f81422").into(), - hex!("917af7d2995b6466baaea2b3eaee5f76508d0c117d0452bca6a07ecb87c0cf595161abd5bd31a904e05684e55475a4ce").into(), - hex!("93dc25ff6a8ed93fa40d198a97955d40a5f29e50fc6fa6dbad34582478d3d1bbac0ec5789f11a92a738e533939c281ba").into(), - hex!("a41c824ff14ff5ee486a6130dc6cb01043e59f71e234390d464c95ac49ceda8b5400079ed4edecbb59be2083d8f06da7").into(), - hex!("850da042d678ac0aa31dfe0eca861ce17cc306188f260195fd10f940c67d42c9431cb68a64d27232e989c9c23a6e3d1a").into(), - hex!("a3e223f30d9782fa1fae634497c64fc58bc8289e48a67c8517621918e2b921cba1e90b2b01f838ea36071ed89bf64ed3").into(), - hex!("809001b01c33bf49a97ab6fbdf708fb224879c71679a2b335cfbb3cb4aba3201a32113de289878606c9feca057d9faea").into(), - hex!("a10ee1706f4c49a9cb2fee4ec6a0dbdc883fe40d4e1cd7a0388f49edf1f5f23a38e6075fa5fb54fd8e77ac3742266a6c").into(), - hex!("8c96e17529d7051f09f93faca150f5313e4d7f32235a4af6d12270780d6c14418749489a2674c728095a56585e0ed924").into(), - hex!("a9a7bf56eb25c9bda003a70128117adca9c33c6bb24bb4c381ac405e014d9c75aed0d704d801b9feacdf81c3b7f0040f").into(), - hex!("ad53d11d31bb9ea53bd23d673fb26211ee39ff4442e9efa1259bddae866e97bf07b0f9ca44e166b3b85d19b5865b1612").into(), - hex!("95e86d1427c8abd87e7f966c2ff9468d0bc3f76175bda677acea5113b5bd0d7631972c4172220e3a72e0dad1496bc14a").into(), - hex!("b8894228542dfbbc6eb65c9adf6549eb4ade838701356e7d672c095b1f997be5bbf3ff19474ee99e81320efeb04cd529").into(), - hex!("88bc36d6d90424e86374499e330ce5afeb63164fe81fcb4d56c5c997e07093a37df33437389879895c8b2cccac28ed0e").into(), - hex!("8ec1d43488aebb9544ae0a12ac7311bf873bee05caafca5176e26d681b881ef6b5e3ae5d9853b33577cc21d3acfa1e82").into(), - hex!("aec567db9a542eacf68cf4b7b9682ffe0b385dfd192296f8d8cd9e1db9d7da0b4a4a0d0ec2419825177413faad458cfa").into(), - hex!("ae242e9e2c7ff2c0898f92e7e9742ee5e19376ab97195c4eea0487490068199d0fd7ea08b832c43e208336b5c77d1947").into(), - hex!("93447c215479b68442636384d29fd5b4815cff904668e909c67fdcef1cf5d594219371f62edf189d6e54f04872705947").into(), - hex!("87f993a564e69e132c6cc4874fefd83bb5032b98bda5eaa8fe9e1713baaf08486aea21eac3231028715e846e33a3fa23").into(), - hex!("a9c4eade07d3d51bf733d8357005e08a5f86cb44c3dc6b66dccbdbb67cb5727bb456d6092418275f34b59063b3fd64eb").into(), - hex!("8939e3cc9c1dd203d8079aa4ac0d40d2e1b85bd876616bc6b589b0bd187701fcc36c52d79ec7f14b5e54fff459c99028").into(), - hex!("978122dfec6fabe4f737a3c9326f2f721cc212455001ca7e09b65b70ec1ada1ae26d451632f31f648cbc65a3337250c2").into(), - hex!("8d1eeed7fb1902deaf7d6dec7c86807c4aa8ea1d7130d6caf01d65e36f6a30e3442a97ad6918e67d2e17fff4ebe7a97c").into(), - hex!("a16203ba484b5b02a1b210d487a54c3da41b3815c307a30fdbcda0c3f5f2205e16bc7232e1b8d57d5f58718ed4941ec1").into(), - hex!("89b4e7bdd90323c53aa502a9839f57133ab0cbae1cb133fd0beb54f4d7785988eab89eb0bcdf61bf62a29b341befb883").into(), - hex!("b75550a71a4144a4f23ee27d86c10c44e8e57c118ff4f9a2685762a98a3770a6c2d1fd9229f9792dd4e784e8b2eb675c").into(), - hex!("9171ea1599ae47b04ffc307dfe5e49da0f48835cda926355606ddff47b18ce3c224828ddb942e63dd8153c273105125a").into(), - hex!("8e0e78d069f4d51b9b0c370100a9d10e395b8f88d009e33ed7fc4959bf140176cc316843c76d2a741a3471d56ced5db4").into(), - hex!("aad6b97330e76b22781e78ebb2fb2e92148d74546cddc7348e7a7f0563b986a7553907c8946258cc343a15a8918f7491").into(), - hex!("a9e8e436356d44c945d8248d249e20f5c50bd147de94418d4f04e1f67be2319e4d2a7291981378a1e457874dc91a9948").into(), - hex!("800b092bbe1f56e78d766c510dfe42f0d6670335f5931b3f821c77689fc11a502d7c82d2d887ab21caf312f8e5a037f7").into(), - hex!("aa8b05f90da0056b7659c26171df70c748d7a8fb52bfda42b7d129df386de331c1fef9d5ad1b19f0452cafbb813c3ec6").into(), - hex!("a6bb8153637b097a905342895ec1c927faa92ef8d59af86e43864ffeb6b8caa3f5b025079ccfa83214332aa4f6b71a9d").into(), - hex!("8244cab3e6f39492c8fda490a363dcbd8af265dd3a158c2af0e66182b48fc2b49f473b402bbf0951b42da5bb669504e8").into(), - hex!("8696508e20c144ef2cd954fe420c60f8432529b97a865a52de5292215c448984dd591170d88c286d7bf5a1cf8b94ae53").into(), - hex!("abb5b057c6b91d51df313b4690b15a218dfac6a30a05041c5cf451f515062eb02c54ee6cf6ff2df7640d15ddc7a95dc9").into(), - hex!("ada583911773366a4ca0b5d407520a590e4f3c6628c6d050f2641655d1654809b886807c1efeee9e9ca187b79b7676c8").into(), - hex!("9730edb86b7161715296bd5267bba55d3bd956dc9f4c640df92cc8aaeed8ab2dc1ff74988ec2122f6c3ea57b6e30dd91").into(), - hex!("8da42bb48c6f17c0e96b5edb71ed5e937c9aa65af142234e3ce61403df7f6ef05a4309e92469eaf68d83afc5bd800373").into(), - hex!("b3cb17866a99dfd048c4ad6024823841eb6602c7e4728340f1167b8af3c810926f0eb3e1a0f51ed6fba4a80743660db0").into(), - hex!("af121178dfa05ac08a2acd56f895f444e56968b703ec6b6cfae1e836d78afe6f51021d4a415aed89913df49bffe27ec6").into(), - hex!("958d5dad1aabe840881f29617dcd2f759f220974515507b0a63b3487b4cbfec69be7d22f4f7f45d693101177ab205303").into(), - hex!("ae6160e53c2c9ce5495bd0f0476703684d854048f2a8bdfeb6cd1e93fda36e44d879531f213feb1dce706d35f9fbb04d").into(), - hex!("8dca41a5808d3c75f41919cbe65a226355df9ebc7c1a2d2263d654bc66d1f5786ffba84a1670a7369258bc92d6bd68e6").into(), - hex!("81585a607df11d0a5dd778adfa1eca440a49e37b21677fe88709142243f5ffb2205e703366de53fbdbe3d7ded093e834").into(), - hex!("a80b1f358d284d3d8b18ef9f101d4f0d84c2ff99342e7150a55bb2f54ee231e333ffa930487a86e97f460696348e897b").into(), - hex!("a4a1f79af8ca4a5c5b44b05828449002c92c313c8bdc33465c099ce8f74c3d575ffcf0ac1ec5d29e80ff96b07f08636d").into(), - hex!("8797e455d44ad2721ce7de2fb8125af1bc4c0757d9c2fae25394e44b8952dc5fa597e0cf5d2b1c2ce996e380597a1db6").into(), - hex!("acd840fe9ed7f38ceb48d65c9f9f02fba4df0fd871efb58b35547c9b526e6e2416195d2c131a04408df7298db50a76aa").into(), - hex!("a9ae67c2d2bfe04d64bd4def66509c108f9ce85394da48d97407535c1aec05df39e3f7c66203f72bc65fa72c18bfa77d").into(), - hex!("abb785c66a7aa06200bec1960c572d61a9cf2c283404601259ba720a506b3831391e998346ee73392a3f7f12915b6f6b").into(), - hex!("8a453eb657c2a85bf93193d47ec26102c4d3adb666a7e1f05f1991782319bbfe104cea57ae1f4379cd115ff711be67fc").into(), - hex!("96c7151e34ed488a06946059722dd9d1b5a2ad2fec96b545ed662a3d0fc23bce6973d93dd2932128d95b0686f9208fc5").into(), - hex!("b5f39ed29d3f85e56e21ec2bce47b04ba16d72a9fad492815b485a93065f2a83dd46f92d74274f815c84792278a67cf0").into(), - hex!("ac9449a216a875c2f288e34443a94a521f8e9de28f70b729f393a483359ffd3ef8537b8a798b8c9a259ca390f9fa9751").into(), - hex!("b15584e841de0e25a301bc3378e89baee55989d9610c513b79748e7c51c484f7bb1d9adb33f3b63d52d36918514aed2a").into(), - hex!("b4dcbabb43cf694b024d36734baf824830304257d959f6300ce17f892a23000e036c4d3d59d7d1198bf4f6ad5ff07e57").into(), - hex!("b8a1f0a8ae246442517606f34ca4029deb727cab005c9952ee9858dd99497ba8a0e3311bd43aeee35275db74c7bbc52d").into(), - hex!("b1c443db1b5a00a87a399880ccbff4481f5742423c47d38b175527e84b32fd66110791c117fdb70782d75c476683f9fd").into(), - hex!("8e018c4b2b4cf1f1a417d00b13fc51ccebcd09a502bb14795b8274585d2e30d71c2c7a9b9f56a717f0676e685e65e907").into(), - hex!("871ea4444c7080995472fc8bc08f9091f9f706e9cfc49eeea5357867badd837649f059163835a7ad7263cf03fd13b198").into(), - hex!("88b67b5819119372e0fd7f97ba1eef877cc32d4be465001c35096adfa18e1811bec1620849a608de8420126fee9c37e5").into(), - hex!("9060dc7f55fdfc237799a2814a6bfe2d2f539ab76c38a9b1206890323bb4eb7b1ce011ea4fa552b412bbf6c67a95f025").into(), - hex!("8bd156a3a54bffe373fea65ecb2ffb12c96f04e07eee582200a0ade24d543bd6523ae5eb8a710c1de1912b2b4712fa0e").into(), - hex!("a8c3fb552f1a8c6cc2714b97d0cb8b2b6028bc3aa4571a7e3e33f46eb4c150771556c7884d575ce8fb7b62a5770ed2aa").into(), - hex!("a808f5a34beb7d62d23405a64d27ee5d7bf83cd880caf7bd4a615b84f22e1dbf11eab129d9cc9ad90d4e1dcd68613f0a").into(), - hex!("ae56febedf59fe99e79e87d7fe7aea5989493833a52f2e6012fd3400c69a6dde951fba50e0c280779d530d74452d63f3").into(), - hex!("8ed5f6de4a3ba85c6c857068bad6432e96c6054ea38ef07391b914c052c2262856d19403a590e8df63c6dec99da35b68").into(), - hex!("89c01fd1f37d826b9ef3b73e2b1aa5f4b4f86a263b2822cff0153fd2b945bbcf16eb3868ce66910073bf86b222becfc1").into(), - hex!("97b3ef6e0bfd3c399ec959d22d29fa9a79fe8746eec49e1675afbf7a955d02db2e89190ebf43118b65a7dc2db0c4d72d").into(), - hex!("a95700745f0ecbb1e794f4db9788af60df4772b5ffc8f5f693f213ce6230810df31716382dccd5a832ced7f34945d144").into(), - hex!("87d0a6a8cdc36fbd788bf744a443b632369fa0cd983d2b60e20856533ed6451d8476b9b3cff39ed0f75de94ad5c7aa48").into(), - hex!("a14c6f6463aadc8d1d2985b601bae8e74de54954ee7e3aa918837064a98efa5ab736628446582ccd13bd458ec2d50b1b").into(), - hex!("8b68ec274484c910f1a73a8cf8a8a149ff2942ac9de6e73641619fdd9e778e9c0fe6198745f049fa9fed9e56287da0b6").into(), - hex!("b77e981a03493852e7ebd6efecaa647c69ce6d46b2190bb2d08f0eede4addda776fda92e9d943ba57331bc985cc8e112").into(), - hex!("9870ea49ed03991dc1a4f47fc978618d549b4f0ddea01d91e7c409db775c91cb2a58c0c0c57eb73e7b6d3418f850b0e6").into(), - hex!("a518fea50400ae263ab9cea0180079d0d353bdb7cd440cb4d2156b9628e487b704630d931bcab742e0f3d7230821ae91").into(), - hex!("861ba1b761d0ce92972f28b7a65cbf6026bdf7427774fe78ff1f45c67f9083fe94fd2c42f47082b6fba722abb648c61c").into(), - hex!("83d257a40e8418407c80851e2f14d0bc47c3b9ce9e2de53b5c6cd99f31dd25dc200fa90c822060d47c4225d61560706e").into(), - hex!("881f7f674959e4176731ecaf6e2c9b490e70c07abceef15707dba8c9aa3cfa2293a96bc9d5455f769642c9717a4fe949").into(), - hex!("835116735f8e21064c497fb0dcfc929004ae5eea1f3e6863ad0b227c820d36255230090812da0800e03af9fde4354a13").into(), - hex!("98d9c12ede55af8067af5b62b89002c66e3b6556ee201ecbaf585fe5026f997fda75105068d62fe5d2403c6c64c314d8").into(), - hex!("ab359e8e0ef4cbaa9830e2aab892db7cd7ddaaea54cf455c2ca24f10ca337f989641ea33fdb1772ed90a988083405cb6").into(), - hex!("ae9ded9c9fc4e812dcab3d8a1c74ea264eab2df0715c7107ec1ec336c0bb5f3761ac9580ca18109278be5cff837f754e").into(), - hex!("b373013674404122f39dd6fc29abef1b2634e2bf650b42c15d5a2f7d762eed98166be26372e8dc6bddeaff84cc2aaf4b").into(), - hex!("b34adf4c3acadd7e11a9d61f7df20cb2520cdbf2d16c217f39e3afbdf2180abe59d37115910b77a504b81a6000b982c4").into(), - hex!("8161d446296d39d0c27a3db1bcbf0619e0c49739c655af49f49ea8403374afa4f98aaf530413848b7d4b53eabc16864a").into(), - hex!("8256cd8e3c9354ffbb59818f0b24db969a7765d64c2fcedf591ce65f619237d6eabd110293bff42b388c9965ff6d51a5").into(), - hex!("a1c562787d2ba1cb64dba278080fccb1c6538ccb00b94db34b62ed1cd863792f8acc4df78d181badc38dd9bda544e395").into(), - hex!("94ad66b4066f53ff299dc4bde2bdc23a891959903174e8ec08dd79f163c6f4661b3eb3458a786bd8f3fa153c806e793a").into(), - hex!("ad1a50bcfaa5641422c6f10d31316035eaf061ad1fc0a36c8835e078d3fa6efbe6dde4bdb28158d9b7aa74fd9241523d").into(), - hex!("a5952780f78fd6afd9c31226a23d307be72aefe0bd99c32a139c3909b1ff1769e2441dd2c03f33cf98df25c76178e492").into(), - hex!("954100f83b800dfb89721ac06728c3d5e8a8edb7e1b56513a63c2b49dd44b9930edd897fecd262984301cb6df23a338d").into(), - hex!("85de42b8de3cc88181a50e9aae696d92e66cabcc7b86425f846dfac138d26eda7cbc420cfd10f5d2681b63bcf411afcc").into(), - hex!("abeda3b142d621f94f829ed4174d042461e95d978be206fd31f8661263bb7a87c648aeff8bf640ec173a77ab0970a93c").into(), - hex!("af99434f06a13d9c5ee7195ce58beea07940949b686b4ce06727bbbdfa1621c608c891227e2f026bcb58c60a6e925533").into(), - hex!("96e97ce1ed97b8afbbf282bfbdbdb4f863a6931cc781e9d7938617310ded35dcf043c2320507e91e94f470f0cbb98621").into(), - hex!("8693fe1860981505e4540b79ee7a7ef33b26535cde6e9aa019bd1e0d26f359a2d26f0341b7c1634eff1f5859ed3a8625").into(), - hex!("a94e940bc2d8f826c23bcce8fc4e49e29c5f918180f566a67395d33cd573e6dfb149490de1ae75068feaedfe6cce0e40").into(), - hex!("9697d6be370d808a49563e062c2b3a0b347281e00839dc3dc0ed888c623f346a42094fbe2489d0487049f2fe47887cb5").into(), - hex!("b06d4cc8e83acc4121bd278784061f6fd391b3ac378fc6ef46ca2158207f5c0d33a51d3dcc4a499aa48e5b27539c4a16").into(), - hex!("972aa57628ce57381aef9710ebb7cb7a8db28b1b64d7db8be38936479f39772c60d766b0c5dcb79676e9330d0406761e").into(), - hex!("ad2164467404544aabb70605a56e9b0f7887491a1691302b2bedf271b50cb6f1bea1b9637214aa3624f5d8f854359607").into(), - hex!("a9da2595107e9db07c56a59d2af529b036c50033ff43c282e2da551bed8faa96eca744881e600b6406569675643046cf").into(), - hex!("8680660eb867978df2474b25e225fd7536b88e9e73f0188c0dbe835677de701fd402916d8e3d17fe652c7ac6d2fa0330").into(), - hex!("b721e239f50bbc7af5578b75c8befa439474bc4e6ea8d35d1006ed54c6d81c718fa675901df591a69b4cc30899974362").into(), - hex!("a8af30765f1b00ad51a32d856a2b2f97831843878a1668a43e66b65b8d0bd4a2e2826fef5ca5bf140050dd81eaa6174d").into(), - hex!("82baad156e89d7b3da9ded4516603ec9aec36e3a0a9bdd0ded604e4fcc0ba10179f9517fc8372d3743cce5e676c8cd17").into(), - hex!("b3392745016dfafca36a7af4be273c5fb4170b71938d6b93691d7a3bc8791bda537ef001d19ffcf7b393a89c898b8b14").into(), - hex!("92f83c901eccb742618313ee2f5ca571406bbfb1d077ebffb92d52ca962403d34a24f9d333c3a155bb9a72a0fc2eda34").into(), - hex!("9792598e2f303896010e35bf670dc2f3799cbe6f0c66379030b0ea01b44ebf24b9257841ab80d2d6a401fc56bb722e68").into(), - hex!("ad1a3c9c5d699ebe4f1b2727dc94b290c84f44c9ffb38d5498b14fcfc5914f4ef4d1d57853e036ca11e42396808556cb").into(), - hex!("90729c7ec4250613062a4ffbcba5829743ba7fd03a4e3407c2ae00b4513c21f3ebd68d10759ac4dfda5544e77b2ac306").into(), - hex!("840add692580be7aea866045826baa4a07804f8e3f56593a2af6fe317046d7d0fae181632f4009ae0d64dfacd4600c4a").into(), - hex!("b1be58941fe077aa8721b020f34d3ad94d1d5083244c276b7f3e6f4c918517f8c5c8d5c1376178bf27cb35ed76699e6f").into(), - hex!("97ba3e3be55d17113fb63abdc808d89fe205d75fc1ac808ebb78ea1b7570f7a014fae099cbc4b2a4b2ec884977405f80").into(), - hex!("a2c57bf9373db5382465ce924bf7dc4e62f406c187a39ab456a7387ed9231ce059d197f8701af9ce2d6cc772367ecfde").into(), - hex!("a62ba8b81b9f8d40fad7fa1d7e8e49ee547f170889b5d6a2be9e2ad2ab0b265b4197fbbfd3b17803a6e727d41cba83a1").into(), - hex!("a94559a51d438b194fea96975a4571a118105479fbb7a37abc7d676fc8b8d2ca30c66b25b7727dcd297384773ddca074").into(), - hex!("957f9be0f15d8eecf621eb0978267c3fc85607f31c501179d9c83864ed9a9e5d526aae278af3767632bf56a20eca62d1").into(), - hex!("b89928c19d1101486d4299c493db5bb72f56f8bc24b71bb54eedf84284452250427b179dddd7fcfc0f521fbba09d0c5e").into(), - hex!("97dda9cbf61015b296307e510295be258045a1de9de52117f0aa28de48e27ffd24ff711f9187936293babe89da226fa1").into(), - hex!("a66b4064c5b1ee95a35a93209c89206b352e0666abd1b5c95eed3c382210334fedad7d531b9939cdb2fc649c4369236c").into(), - hex!("89d85e413030dc45194b2676a1f2a76801920535ccd909277af1ac87fd9b0d16d94d8c62a421c9d95e7a053cc4c3e0bb").into(), - hex!("b8f0350e1ff988bf23846f2d64e40b35a370d1c5d1f9dca4021508205611f788fe5485e966ff2bb6fe8acc1540a2e751").into(), - hex!("aef9ed7229aaadb1ac4344e5b4d0eaf9b89b20d50d8ae8dae24294ec3c0f2f68dee3186dce35d46020d8d1b2626a29e3").into(), - hex!("b9362f34ead1b0cef1fa9b35b76b644a323ff71c48f375c27e22c6878cdf778b1a3125445cc8cffb6c8b9a3ed046c3d5").into(), - hex!("b69c578e2223f3727b7b5e99f3926eb7424869b356541feecda54a0882e4a009b182c358052d788c2a7e776768ce2b7f").into(), - hex!("a9ab536cca003598d88f76cd0d666b1738802c7452201f5d99ba4fd82b6d7da3c9ad8c4707445d6cb4b2c43de7ba06b8").into(), - hex!("a02648e465634db73fd49bbcdb23cb6feed9688eaf4c5678799734d49f2d4cec9cdddf598114896de961ebdc07436884").into(), - hex!("8253283df9690e171af958f2a3cc37e0b2cd67768f2362bd604ba5c5db8d3500c0d7d6cdee982165eaece63bd016f2c5").into(), - hex!("a06d8256d22ef3891a751716449f97d374e27bedbb9dbd0f1c9528307787e4d9ab9450002bead2922c31fd4ccab9abc9").into(), - hex!("a3bcf7d7c1f1c5a2bdde1e0f4cd3cc6dfa061156534aacd6318d8192c27218b6e34e734a118a282b0d5fdf639e704c21").into(), - hex!("b5577e876cb3de8196b485ae828362419c2f7f8ca9c8f38b1254059873fbe53b57110be543c864bbcf8b485f63925169").into(), - hex!("8410e1b1ab99cf1868fa4494dc75129f42a5e633448e64321cb379175cf6eb704ad6863e3a6475f9cd3cd3f1fcd4b49e").into(), - hex!("b6b21b346d709d4897da4c535556d599486878f5c574bca2823ff9d382fea2f45e8d03aa0fc5a5d623098f1b67c77a60").into(), - hex!("92951386b734171accd57b66afad7ddd0ffdebbd9da835e273b11f96639aefa6259a1387fe3947f9f7eacdcfcbb54b65").into(), - hex!("837cca28b3bb00034d619a3b667b06b66d7cd351ee2c161014b4c33692c705e0fca1352c1e5a7fe8ee00515f4b9c9658").into(), - hex!("95589319552ee815c1e1b053cc4452f9ba600142c37bd700feb3c27468c769e45e6307d7c0a3f366440cdb4d3b997d1c").into(), - hex!("87ed23d8d5fd6aa0922565367ab405e666996e7b918795da299c204cb6d1e51a9c6ff1760dc3fde555b0900e677a9b9a").into(), - hex!("88564f50eb215320ad93b979c617cafcda9122ea02f113029702df1f39116e00b35e0beb0c70bb7d7f2d9b4bf68a1419").into(), - hex!("adce6ad54e5d24a2da5a04751151034245184bd7e61998ddfed673fddbe4e3d069b580e833b3bd4509c30a2e6a81f528").into(), - hex!("80800ca4fa6d0f3ea555ac7d37e54e7776f640f76fe89cd7f172c74723cdb3324da01314c6f66c4fc404c393aa8c7841").into(), - hex!("a16f473cbc9070881b9dd63be9f99670ca571822a67520cba885b2636137731b440561f83e199713ecdd51d4dd542997").into(), - hex!("a08c0625cbaaaba847a63ab4a96206bbcc7bfeb659505d0b6b0e58d22f00aadec41f8cd62ceb116258b78063f26796ea").into(), - hex!("a358200c83ff15fe3fef7a1610bfacdf86d55452258e7f4701082f993c8bd5d234b4d86f96d444e96c01367503663886").into(), - hex!("97278525e5e590ab6cc4fa4a1bac4ed7164a65887b29e658bdb2146008b02907488565dcea09e761f6922118d9933ed3").into(), - hex!("b4e76e4cf2c711a7f3be5b404f076b9d2272e15ea7c61fa4b7a14c5608c352a92fe6674a25dc493a6bc9e864ff4b4a85").into(), - hex!("a4612d268cffd31d092892268e6b4f9f564f0036bfee4f200d270a61a8e5e239996d288d28d6f281d8446a88da56cb55").into(), - hex!("81a70c88fd7d99165b41ee12883ae529458758650fd13001c86f8fc6ce5f8f9b69ce3a133e310619692faa1580dd5d67").into(), - hex!("a87124cbaafc8ee5418639ff27795003a43ac18d07a60fb8a1c155c5fece0f8b25525166ba697e07a5f2d47af6cf0bec").into(), - hex!("90807f573a322aac9d1cd546100e49cb8c771f3d32c89da1890c1c819d90b1dc668c2374249a093c0863d5988c358d4d").into(), - hex!("90cb26b40d10f193da22975b0507f04de6cd9d002e33226852cb40d948d1814009a39332c75f1067e8192b0c9230ce63").into(), - hex!("aefbe25ad8bef226d434b970bda8a47bce8269ad69cf91e02e04208a74055ea79a3a7dbc988981b79bcb9298af467e62").into(), - hex!("b4932ab425f4abad270b32b6f66066cd01fd6f18cf8c84dde99d21c9c2676d58be4f9ea5ebbc454c9d9f921c0333cff5").into(), - hex!("ad19368c70cd241b1a90e5b46f34c44351d298e2fc9ee5906596b20f5aa9e592e878afe8924aea112be60c07648fef8c").into(), - hex!("8b2d2953b4603b73bfb1edda8313cf07f6d9d16b0272d90bc46816677b602b4a7e6fcb36c4f69335918f1ba4ec95dec3").into(), - hex!("ac64d362f730c790ee3f9311990d9ffa3b99d4952ea74f63d141360d2edb7fd0b70d94e5865504af3caa94b63e34ff4f").into(), - hex!("b71ad17d1cdf6be4b7f0bf7d3fca689d5a69a7426dbedfc137bb162142d26e079f49c99797316e2a577225d881e31a04").into(), - hex!("8dd692a01ecd819981ea31f39a5950bac2af0deafb35323358736bc59f8fc69f58c865ed9cfe239ee34d6f80bceb562b").into(), - hex!("b2ae1f2d871d48b6157aa9d74c24e3fa3f09d6c40f421de9c545de5ecdc44d44d6c4a7caff315694d8173974b92c6119").into(), - hex!("8c934a58d5d2c06221c10c14f08f17265e918c6f7f158f6989acca4b1bdf3db58952e5500f930af02ac3e6e44133669e").into(), - hex!("9466e7c328d12ad5439ac01c994825a94665091aa00e212a75c4ffd39f4473a62c160d63e568b534dd7d5577ad266544").into(), - hex!("8e35a84ca6f167c75f98728000b5df8d9c5611080d2dda8c49f8d4afd2196da349cda481fdad8a0e7dad1cebf4b82446").into(), - hex!("8ec436a9690744a1c6a31fa796bfc8f054ea5efb1c8d6a70e9094dbdc32bc199a7c1b29216d706616029525883a9e342").into(), - hex!("87cadc50459a643648f5995ff7ac751c24454040f788e218c4894854ac658fc64c2ea0a8cae4973056ea11f7bb0e5a26").into(), - hex!("aa5a2d8278dffefc43d598186f1119bf1a6d2343143f4874aee24d3869fd4b58401e8bb220f2a228416c89c1f5344af4").into(), - hex!("a36f48c232cba1daae013418421fac6278bca09ee3816eb46cc4059254f1e7672dcecd6eebc9bc0896e96cfa0d8b485b").into(), - hex!("937f8e28abdb3859575cff574517975b96ad41dddd4efb23af86429b01ecbfea553be6cce336d170116752118368e05b").into(), - hex!("aaeb4e5c7f67ee23b1976b2e86f2897ced033e79012532599d130cdbe29d8cd551d9451794741d2ede8564af9070f07c").into(), - hex!("884d9608b7556dbddd0ed13bbe04a5bd9f2bda0bd090d47550f7362bd769a3b3dfa890191c64e44378792d97ee4df5f3").into(), - hex!("a8276ce24aabe42cab32ba7d77c2ef2ca84b3a3e3d750f8d0385f9027f0e009365c78196638dadde186bf44b780fff53").into(), - hex!("9148c5c797b4a6438360072c463008df8b17978335f36d4972b4f826861e8a175265a9eb00c56f47d3892783dcbd080d").into(), - hex!("a7e5100f51c611f010b2601d340ad7aa65bab89c8aeecb181e76185f3a739892f8b172e5cd2c108d5aed8f5cc91cb6e7").into(), - hex!("87c46e67d6643c07e0e318dcb22032753c624e646e4871be4098005100b306f3cfb25b6d81c718e83b42b92841c577d3").into(), - hex!("8bf429c735133cb05edd9b8943b5d4040e83191553452e69b3a1fd06edf2a9eefe8e280cdda811795e1da33e41e58345").into(), - hex!("800ce4d6c257a365e5d8e1bcde67a38c04ff723e38b0926af8b9fc352545317beb40621497aaac8d0e5da291c0208630").into(), - hex!("a5c795afa0ce78cbc11de13c8f58d0bd9ca5b8665d5d8d28513a0d8666f9336b0dc3295557801ba253983fc99f45ce3c").into(), - hex!("99e3e4a8e16ed2ea44aae56b537ca9b159d57e987b0511b6d34767744b04700ff287d431dcc6c67d7cba5748b3580899").into(), - hex!("ac88e78183973e9730ff0c88dd62eb23e2794067ac2574a1c8deed85a4aa6229ee620668dd16084c8f168b2555f04cb9").into(), - hex!("a9c4fa68984527577c6da60dfff110163f35ab7393b852c053d73485155fa1536d9701f660a08b160bf49a647ce3cf92").into(), - hex!("902c3138ff660230158ff69c33911cbe958d29178a54cbd13480addd948b19b0b97f6b235df2beeadb7f7e1803b8cbad").into(), - hex!("a6169eabbed09e08a0d290f9075c62ca4b14e1f7adc53545abae49858b3d5d7fd6cf8d8ba2ee1bf13f36f79ee4092935").into(), - hex!("85a0d7387b1db5635f17899bbadddc0fe6b11976385e12ea4272a8f61d81004406604c8f04f10ce928fb6b547d3bc654").into(), - hex!("a39e5f2112944a7ee31fdccaca927e4f4bbefed1274a134e8a038307820c1d14a6260e25ca5a3af0589f8faa8f516c5c").into(), - hex!("b5c86d0482a417bc94b42f8478de06918b36c5f45d0695275da2a3e773088268cc127ac1380f912307b6455dd0b16d07").into(), - hex!("b8b5e32afc4cf0fb92251b422ef9b757130455150c49ce51f6d6d95d895dafa25649363660608bbe7507d787db9d643c").into(), - hex!("b11f3856f691d84d49fdbeb4f33c45c37dd401a2bb71bbf946f3ddc53a57ce5c4da583f76cf4467d43034a61e1dc88fe").into(), - hex!("a56d1de276b2d0a4482e17cd358455aa19a47bd25c7fc97af8457ebc37781358cbf8a7eec9427881550a8db1bbf51771").into(), - hex!("9508c85488f15d2772522dd1e991f41da1f3af7e3527e098d5408ea96f11f4150415ac68ba0a3031e95528664b261de3").into(), - hex!("a28e129c656bc44d0b6892103b7d7c0d15ef1f1ce583e90e2c644c3016ab348ae26a662652c953a3c447272e52b007a5").into(), - hex!("a68dcb67d0cb585cf22f753602c46c7ccffff246b106db9c56248ecc5e94a036009bde23864879af62a4ede81d040c56").into(), - hex!("b9725383c63b2a522f4d976ad6be14a35b9e80145e058baa622238500f1a2ffd6869cde87fdb984654b2e57615bde3ee").into(), - hex!("90248e4cf47ec8b00ee874ac98227759a3f7ce4819e44176dd9b1acaa6270d144d3d707a35e0cbdd7ae23b15537a20e2").into(), - hex!("81327abb95401fc2fe0b1c2d27d7d9972811a63e12be0173fe8311678ff1fb097d73fa32cb85f13935e1a4b7fc59113a").into(), - hex!("a31bd2dfc9ddfa9ac748968b532a41a26007b23cda258fdacb3b0abb751cd7ce2eccecab2d5e3781fedfe0d8da027481").into(), - hex!("809b28c11c1abbf53f2dc005d30403937d9826960b24f4de857a9470067add08d49345586d7e58bb1107d232b3b47bbf").into(), - hex!("b0597958b75e64fe5c6e56ef803284b3b7420fd537e5625c75af3aef814a87a5ff01951261c2c7b27e374466658711d8").into(), - hex!("ad8fdb91216db4fa779774324162fd5bd7ff9a999030c42d9f90248bc328221aae315ef8617c9ba623091adaa0556074").into(), - hex!("8668991c8bffca4cbfc06f3429961c595d85803a262105907361758d677920796be70d2cf820f0b1caaef708d924e676").into(), - hex!("ab22ff4c2ec9e683d2d1ecf57f7af9b3aab1cd289e22b1b66f37dc3779e83e35211f7d4919dc3ef0babf876d491e0bff").into(), - hex!("b8696c811af5d3360951d7bcc9ba4e82e17a125501e91ff74b915de28a8cc217c6fb05d90985fea7ee431e519e494d9e").into(), - hex!("845c0bc4769c428fb30e63c8e4631f22e69f934b0e6089431ddda2c232172a4980cdb6f650563992667a0790f1a3870d").into(), - hex!("b4113cfe79b6b198b517ab5d14900a7189ba78b7ef85d04551e18fe1ce6a69564377fb86a0e11627cb794d1f416fbeb1").into(), - hex!("aa6848837b26df24b04198b0b09b77d7b59d26dd3b20f7843352f2436c046e9975af2985e64fbd6267d897e728a9e721").into(), - hex!("861456839cb76a9490dbe055559e3dfe3bcdc41646aa656d8aaabeb4c0e39a1b370a4f0107b78f900614e3fa09b46bb5").into(), - hex!("ad6a8ca9a21b7874f8b115024a7f079f5a1dac3b165267b33a59d1c8de2065bce4552369c930e9a949d0b07110a71452").into(), - hex!("aa83179de1682892257c57774844b040299789430a262c8b44dcbd81f8062deaa731ff4bebab1a815d3148ec719f4cb0").into(), - hex!("895549691861582abd102fc19a4ed269b335010aeef45ae9ae6b0d9c6d26f26c31371086ddeda626e76f7f07dc622fc6").into(), - hex!("a94e590989e81d269b5246f22a9c97b604af58352c70100f8a20454fecf36d19e601dc1201342841ab231dcefc461f2a").into(), - hex!("82541b5b7a392456d1936373396012b086c370e6dde41f6d4409d35373d1586d3c7119f6f0d1e38bce9cae67c97fcdd8").into(), - hex!("8b89fecfe83adce613e75a52e785ffc90847c09ed779ebef4d29048bbac04b58e27311461c25d4e68cc0e6778228b037").into(), - hex!("b3eeb09bc9ace8a62b71747711bbfa308b746c86ca87297cf2a8e768765a86ed1add2e1acd2925cf05537dffd4dbec50").into(), - hex!("a5364dc8221a37d73250f8498d9b6e163babfcb01e1fdef8ae570538e128b562a0ed8b353235159c3781ada8506ada33").into(), - hex!("ad0d54f0f67d0231ca0ab54ae881386b055c169fd7415c12e511e5ddc5d4b1beba0e1a157211996c7ab61f6e94cacd64").into(), - hex!("b4b978f7f9b084c089923e73a593a24d5aa22600c879eb03645a19ffe8b36cb8ae040378a378ebcb4a5b73331a2064e5").into(), - hex!("b3d79038de0c62c667ab4213524679934b33de22111626c258bf8fd8e16134425549dc7e3dee15239c32bcf122f5bbcc").into(), - hex!("af7a243eb665d9b2c37033363b252c42bc2c202c266ee125b5676b6f9f94ee5d46d3e2ca217f107719051de511625dfd").into(), - hex!("9726a0d607674fbde3fa5c346806c4083e092921c303ec86bf5a16e4b760d031a24585ab407b9b1b0692d12276912961").into(), - hex!("85a8eb7ff82937e2ccddf2f049af9d871c653de4d71ab36b198bbc7bfef2e32eb3f22462dd01affbce13813332193262").into(), - hex!("a8889fa7291017a3363a5e14cee8cb24c273be4aeb74c4b0e1e375f70060dbc9ba296b291e154eaa56703b8e3f7e85a3").into(), - hex!("a789cbc52c5468bf404fc1b19651ef6a805d96ab8a8991407e149a68d10d1f67d1d4b380c08f8be1faea8d1b32bb8c1a").into(), - hex!("9535392a86b73ac66ff8ac1ee0549d266a9e25e1db542b077d136d26710282529f34c43dd94ee77aa97c647e0e05356a").into(), - hex!("a1ae9d5fd0ca16021e0a33fa116eb5b94991aae02efc6f116e073def47253fe2d1f2438275f09f204cec0610ad523ff3").into(), - hex!("b5c6c5b37943e99bed4e63c9215bea95fc365a576a9f8f0b9da8d5ceb5f9da881a273f5692b0913a3bb922772923c07e").into(), - hex!("b3b0144fb027e0c7f1a0c4c703cc5e1c09422be38de4e10010c28bfac358a6c834df6794e5007ecc4c8d866ffb9a8725").into(), - hex!("aaea409068fd2cb94a7c6fe031ed47c7c5b366a33905d12a107799aea57a052b9bfbb1c4f88b1b3775d5bef7d6204b73").into(), - hex!("a10cea5af8405d807b66ad492a1aab8618324ec3d9d01181ce29512e38f03bfaf556251dc490b3d1e80576bbecb27dbb").into(), - hex!("b700d4046b0be98b3cdfb8a2eeee52df68bcc1c5550d1c17205664b0d896028bddaf5dd38482645e76f643ad9d2ea9ae").into(), - hex!("ac9163d5f57a2d1def901e74c1b07f4d14b1e9a5c362d3b082c45389ae8add929a1dfb0baf14f64790f86cddbdcaa32d").into(), - hex!("8e3b79b19d49d77844e3401c01984af7211268bdf6609919c9867a83cbbea21870ff108143795a85fbdb2c15a2d127f1").into(), - hex!("b9db73eeeafbeee4edc52c1fcac7de6d8acd22a8d3d1c4cf760a81dfb6cc91ee454385044301fb2253588f23f3a24079").into(), - hex!("b268631698668059d8eb44d50d532c9d8c49953ea2029d6a2d0eaf69713afc85c42d989cdd3bc0a479ad77cbad24fc0a").into(), - hex!("95f74950a24d82ba9a9df5d839d17d7ff830a5dff38663630efad5abe9c58724802d5bef891ca2b3b81923b55a94c6f4").into(), - hex!("969297c612c35347019f5bc80d2887a3c95c8ffbb011f5cefac63a1f51e48dc84d961aed56afc353791589a45c871cfe").into(), - hex!("98743e9521e5fb6a643c086a00423fea51b8ad2e55bbeadf791ede16eae64f9fa45c41101c6cbe4a8e96c692fc57c030").into(), - hex!("9374001ac3a8673e337b078da1b72090bf2450a5f53f6a600f4cd43ea4b5fe86a73d14bd0103b110f23e417dcb4c2e47").into(), - hex!("a91bd42a87f28a6fed7fac68b5306e5382a93fde2bc9aa5c48b747ab774f9c557343cafb46dcd4e93df5aa95ed832410").into(), - hex!("8fcdec0a825737ee2c61401014287079e729a8b8e49337e99b34c25dd9da570a1fefc532a0cf6ce1bec80be2d9ff46e8").into(), - hex!("8197cd84016cb41e4287d29b3a0fe8d221868e5993aef8c15c1578e038f9c43e93bc26dfc67fbef919322178223d0b9e").into(), - hex!("a4607e2b6ff802a4e497c53b206972d35520c78f14f7d4d78514333e90b2a8852603bf223f1c9eee3793008f87cd8fc3").into(), - hex!("a72b6185e451b3be2c140fb3f48225927e7c052805682e3de9b2c826997419084bf1e2034aef0c5d364b0004b3b7807c").into(), - hex!("aa99a2cd46884d2ecae4257c1db8fe1ef6b0cc1a0c25dcefb53540ae91ea7bc8955b8acfc6d96ef47fc3a5733f2f28e0").into(), - hex!("878ea42dbda59fb6f839f0b65eec295f2d543541f4fd576a60d104b94b49b1a1ac6e9a15ed3274e6305de3f35ce1e3a1").into(), - hex!("ab2f77f6036200b4ffd3192b8d06dfdae4eaed4e1105b27e64ae2e120c909095e59f4dbbc44e818afdffc7f9ea1f42be").into(), - hex!("a37e3fd9b1337734cdaf34111762403db11b1aa0324937a17e053242a9099b3db0d396b485ca996f91117c64623915bd").into(), - hex!("97c65c28a6a81690d4d6ff17d5cd3be0e15ab9cafe66e6f7b8da66ead8beec561c3abbc79af52a8986d576363f14cd27").into(), - hex!("ae138b3020373ca238d5dd780862fa28a2c3e05903366cdc0fd7a142db3d18eda63b8d049abed37f1fcb25f6cdedbd67").into(), - hex!("a800bf90b4e7aa7b5b00fbe6b5f45067e0d7ef2b1ed9a626211e07b66b12ddaf90ed05d369f8da13ecfd8cb499f192a1").into(), - hex!("96565fc4ef721f754b6f53db97d32ef5e5c3cc0f55928eba3eb341f4962b815381178763ef05c21c1247124d592b4449").into(), - hex!("b4896f9e2f88c990fab764a4e006f3f39ba6bdd0e1c75fc8dab2973544e052ce63f8c61a6ab213c85f6799d988a6fd61").into(), - hex!("87aa22b60a13edcede78e629d54714436a8d7d1e6e232d4df6047213b4a91e61e5feb38216e0ebb209f1dd8d7e4f5f9d").into(), - hex!("ac4d5e8bb39a2564f3bff053e2058f261209cf14e65f7dc540070d40dad7ec4f5fa81efe6274aeab8691b85a774307c5").into(), - hex!("8b13673c306988222f09ad896a75a6232ef3bfd2f6c37c2d751668466d45511542fe982ca5720c6518891830674e2cfd").into(), - hex!("afeaafa07eaf14f248d2a34e4f86064c5bccd92d3a6c0ace1ae827dd59111e9b3cf2722a270234eb5aa633c12e140354").into(), - hex!("aa31119422a52a7a5ba90f4e0b5676434b4f05289ea3143e8a2162e32b1e19b582a586da796ad9876d0991274f3363a8").into(), - hex!("82c78ac9f2018540eea744c003a76cd7bc8984103e941c680a4a833a7c81defdd28165256890d534aaca2991dfd856b7").into(), - hex!("b4a99846af0ffe14d0f820a574d42571e0186cd078840ebdf0684c806c08eac1d6afb2f7f9f9dbfee19c2ea12af5307a").into(), - hex!("93cd10366714618a7e8d4edf3c93a9bd30a280f765cb93071a279eb5bc4fe8dcff8d91a1efe8fe697d1cb5e760a07fd0").into(), - hex!("b17dd2a8817471efd91b60ee31bb5f7c2848bb40251dafc0e2250cdeec3202cbfc7a8af6d7f5c3300a53a73bb4a11b54").into(), - hex!("b396d11ed53f287ecab591707ec5ecd0c5d34a67854783dbf263fe2614c707a2226231fd8dbd6bb1ca0760f06f2fe7d9").into(), - hex!("9982a0fbdde6ad91f35e64de34183e4e7f7df6cf422912f3dde0cd16394f0f172dc32c4f68f2a09647fed32894471fb6").into(), - hex!("ac5889086fbfd2f2570191b5d92659fd17283509477f442dae81a8491b8641a5f63e275659e6592ebd0e62a8c7a9bdb2").into(), - hex!("8fd6151866cc75461b69b4685ac4efb5a21c10d5b3291617bee4ff300d90fa2290319967faa2b7189c090d3b60994fbf").into(), - hex!("adb4459e4e6410606a74742d6e48f7b84f30ecc8e849b6af9b4b617236dedf1707ec388a97523f18ec7e047743fa7151").into(), - hex!("a9fd9329ea3b6fb77dc577e2c891eb66c61a575ab75a66dcd897f1127e8bd9ad8d3eb9059c7f6a8b08199913b83e5ba7").into(), - hex!("b94cfafbd3ef7673023ea37996084acb3109ffbccd210184aaf8ce8d29bf36390bdbbf2870b0970e66831d28e90b248b").into(), - hex!("922404dd76801113ba23df87ba689e5cb609c94930370576d0d16e99a489de0fb079fb273159b8b07fc58bfe4f787c70").into(), - hex!("8c6005451c02b18458c3f069a521aafb44fab40f4260a60da6b9bb5f920e91990a868aafa4b6b071a899d3bc51fac72e").into(), - hex!("b0cf68badbb39413649b3171281ebfbabbcda1123549a4c6c09dbd4dc0427b51d555056c79f38840c52cf920dfa2c8d5").into(), - hex!("a08a09c8dac1f7bbbff2b7ea96899b64fed53e971569171224e675399467daea6870e48fddcf47179d3c7eab4cfde3ad").into(), - hex!("881c89cfce577898ad367abc2cf5989c647bf8904be5e061e632256b3750b0aedaf4d30c17f994358aecd069b62cff09").into(), - hex!("81674253d6664d414f667b10f6e8edc32af0a67b2b99d3e4657991f8a8b1dbf260447871c1c680d92f99abdf3da2d035").into(), - hex!("92e34adb15141ea58b2b481f9dd69e2584f512531bab13779fe99e18d48b6ab039bb28d9f444d517298e11464ebde4da").into(), - hex!("81ee1554da84a0a487e52c57528b69cd79f1b6530418354095ab976207e368379ae2fe0a4a340d209f13ac9783cd6d5f").into(), - hex!("839c0316ca07242ab52b76f55049f2da3e83f021591b0bba295677d80d4b407f88b0d207f3ecbe7eb85f19eba5d152c2").into(), - hex!("88b0ad748a61db5eb96016d9bf16bb05ffc4cf5ef56569397e9395f454fc1f731b48dcd8b3368163c36a3fb41577286f").into(), - hex!("b94fac438903b1e6cd11135b8fd35b91b61a0354addf8ead5cae4fc853ebb5be68bfb9901d8b4d3bdf58224675b6d675").into(), - hex!("a015eb1a7e1b814625b13c1b1bca7f738e80be5972f3a3a27cd9b21b033f16e4b5934bab69e38a6edb8d03e84e8725ef").into(), - hex!("83ef4eb739353f7679b27d3679551b2a0eb1bd4d372def5c0e8e5922a9ce7138dae4b62d5c147e6439a551d3ebb1e1cd").into(), - hex!("95907a3b288f3d4199434590340293881b94322e82f7fe9c186da3fdad7881b9a92cdcc5fc29d4124b1d05886bc9ec2c").into(), - hex!("868078f74e35b72a894d72f93d45333e423b1aec6d7e3cd7550254ed6a156957d4c5919489a84986f6134be8334bdf4e").into(), - hex!("8f089ffa10d8ff27470b8f6fcff49a69bd06ef3f88faee54a6bc8ea0dca6bb799199bdcd9a9e7686c43302cbadb584a0").into(), - hex!("980f4614de867eed7571cb3100f9566542b90d2b4110806dbad64249944cf3e4e484d03543107fdff0e91634d5193530").into(), - hex!("abab8578ecc6096bf063da248b376bd9e76a8b9364000a98c85813ada835017ffe693f908aa789cf09ca3020f3bbb9b8").into(), - hex!("a2beaf5eb12232e44bd251aaef3e007989794ad1df7a5f41ce1e6d862ff0607db47cacd4b04d684dc22d3640f6b8aa16").into(), - hex!("8f57e3d8d68264b5a07c9fc2399db0dfdd079abac46e1023373c22377612d3b005053e0df490d2435110c9fc2791b8ec").into(), - hex!("af7d2c45de945cb09adeaa1898fe0b026b5a5c5de2ac21f3b2c298d82fe4ae253d859c47f71def164a77b542905bfc73").into(), - hex!("93b026c1b083d82b3bd52d0004985f374acc81f754f7dd4e563a9ca5b20780f7872925a03e48d2154c526723b6d3fa88").into(), - hex!("b8a11c00250f9e148086818aad4dda9d69480b378ef5ca9e2fe85dfbb709d2a919067d9abd2eafdb5202cd334081b5a2").into(), - hex!("a7026b1a57d9d64f2526bc42c771cacf43a718725c2d0dd889b1af12481e3112bb5357e6434b3e83754b067bd5d533f8").into(), - hex!("84771640879d9628fea0ae1106a45bb8a383ca0a9a110093355395968b4d5af9e4a34201024a187d3a31b78a839af6ea").into(), - hex!("b99e5eda7144057e439ae752c2d879345ebba19e83c35785743d6fc1646069b0258ebb1ef62fdd43493498ed08a8de15").into(), - hex!("b2a17e5253f695a61697469df96f3182a62faf0b5d10c150f833543e7b3f5979506a068ddaebf310fe86efaf3adf13e5").into(), - hex!("8ce51f0a8ffbcfdddead1a94f45a42ec4f9e8770c0ca33b58207b8db06f3004c05e88f5b31896e1b7d3c79ff571426b7").into(), - hex!("a775ae2c3c59968d0add4c446c5f20e92f92eebb704016ea45a47c5496945b7d0935b4d8ea315990e6f58ec33d00aa9c").into(), - hex!("93bac2d2038c87f111c8000e721e4637b04ff8c3b7b1e8a9f02cae40e465a1b2928aa226af73ed643a4c21f3fec436f2").into(), - hex!("ae050b3f4784f2c12c902fd1881f6bb940806c0a9d7cceeeafd194dcd49cfa48acb10a09c55ea47b508d5d16702800db").into(), - hex!("a8c6680208271473433781cafde59a4aca2496d58c85f48ebaf447a0c175e784c4a1351d94b5d1a64c78bcf8c84f8f2e").into(), - hex!("8f9f71c20844682e17bfc30d745ee2848bd8782b05572ea64f9b9bdb2c24b3d1953bae317d79e267982c42f3f3aa60f9").into(), - hex!("abc4ec57e1625bcf3c10754a07a2047d359e503b05e2524175b48d5844756ea21f626a65a08f4f7b32cfb0646cc68fc8").into(), - hex!("abaccbb39d4fc4c252997503604764731889f5bd66382c90477df2f2d413f86892f7efdbee0e3a908b3cd69321d3db78").into(), - hex!("906a87855cc2b3765774d3e8c7daa62630fa7ba761ee2a0bfc5594380dc1d9b62740d1190fb882ffaf17c0d869356261").into(), - hex!("afd0ed291ba237f8b626698e3c54b8a84341628a524b897e53aad5231aa01977990c55215a677e9adf4319a98e81bef2").into(), - hex!("89512dacd42d13f5618f1979d9afd93c06247de2e1e9ab6625b5bc9efe24439189a564ea220c4ce2795f059064f5f5d5").into(), - hex!("90238fe2ab6b623ecc990ef8d2849d26229db5f3c8587cf06501e459c7742d81653c7dee45da82f5946e041f129a8df3").into(), - hex!("a420b197f4863782fbd676bdf1808ff1c6f49a506d525952c575c10a32cf63afef22f977d4b7d6258334c498f36e7f95").into(), - hex!("b7d8fe926876d1d01529eb6e30a78db47b6693af3171b2014bd18180066609cca9036e35953ebad7355362fa671d903d").into(), - hex!("a4b7dc0ae7e7d8c8eb65081427f5d41a122bcad56456dbcf4a4e83e188af1e3d80dc7f450766b8e87ed8b28ca6c5c479").into(), - hex!("8d3e1060196b4e8e827052c2ed782aa554540f21690b67d39db46fcf088d10f67f2b6e0d98689e7497e8029bc8f355bc").into(), - hex!("861657c4e2a48891939b49706791a03f63d092643cb491adfefb3cfa7d86ecacccaf86e4a1382444e466a61e29a12bf4").into(), - hex!("92f1c5b122943341854ab7d5c4603e083019344e2252da5664c676ffdd564345d7e28e2a5692dcaadc4371a95ea2a142").into(), - hex!("86100ccc2ee10dedee28a3ffa0bbaccc1ecb19d36a99e6deef1f2373c1c1c3dcb8b8fbec5809304d883c5d60f617d875").into(), - hex!("97c06ca658fe3ec45a6573bde07b3a95d80cff213c9f4eb8933c8dbaf147262291a5ebd55b0e58a4686c4971cdc45671").into(), - hex!("b13e9055709868f723014736b1fde59c05899bbf2aa6d4591d724c35c15ebe6d215e37fcb1e7b8585abab0b2ba309c00").into(), - hex!("8ce0532b968d8d770eb611131978a253e7940ceb627b7364b3a4dd517f26c31bee51c134a5b1297362f6f9b6d714ef33").into(), - hex!("92edce89bea01fdb25da5d0f903de2fee626681cec3db418a9161286a2e95bbb90ef2ccd8dad434b51776f85d982700a").into(), - hex!("aefc7dea295547984ab42a64f2f59ba2ae8220712778a71530623351a44372ddd1018cd8d4951934ae0fa39653ad6aae").into(), - hex!("ab297f28266bd5ed104c1b55088f114592e80aa098a0865e5543e12c6392b0f94b5cd4e0b6f375d1a0d0809d80c1fca0").into(), - ], - aggregate_pubkey: hex!("81a5778df2e724c98b4ef79ff33b9c5fa3ea265de81d49de5c4ab3be2165d32fe15c59c982f758c3b9c522ca5e659fce").into(), - }, - current_sync_committee_branch: vec![ - hex!("1da42c54eb912009030c084b700d2e0031c0a0e5759b0cc593601b99764a725c").into(), - hex!("0c960bd59f4a61104153da676eb38ebae603e9cbb55b0f6677cc1df0d535d60e").into(), - hex!("1682c67e0936255e351f8be6ccbdf048db06a80749aa900bd4265af1c366bd52").into(), - hex!("d95bb6af7d6be07e5d7d27337ab9b54d5bf725ac37671b9483434d22d724bb92").into(), - hex!("3abb1af4e9c3acb052119a42c2d4222d99e8b5b958c520a03526a8177b921cf5").into(), - ], - validators_root: hex!("043db0d9a83813551ee2f33450d23797757d430911a9320530ad8a0eabc43efb").into(), - block_roots_root: hex!("ed6ca045637c1c7dd54fbef547b8b1aa3f5b9fa8f0bfa5df26142a0c4237e617").into(), - block_roots_branch: vec![ - hex!("620abd1a8757614facfd9d2fa43795281bccd4055bc9b12e5cb3742a16a9f9cb").into(), - hex!("14c793be544d5fe1993a1b25d39f4b69e832e914c3d470745276a25d982df4f5").into(), - hex!("46aea5f0a7d66cffbd55e676b915be97cbf3dc6281146cdf4952047214ff74bd").into(), - hex!("0ccefa47e43d03e26def9fa07bacd91a5a2a20c6c5dec2ea090f71f91ac99282").into(), - hex!("f03f3d7a52241ab959560beb9b748a8ab93e2b7221c8070561a12a5fba8d4434").into(), - ], - }) -} - -pub fn make_sync_committee_update() -> Box { - Box::new(Update { - attested_header: BeaconHeader { - slot: 5808573, - proposer_index: 430716, - parent_root: hex!("0be3932fbc9ebdf3220e2195d87653f283d9f999946e53f6a9f6172b6f532779").into(), - state_root: hex!("cdfacee5c92a351843fdc4591ccf16c4f040d0276add8421f08dbd5c71035a1f").into(), - body_root: hex!("3d248ca71ec98250b8dcdeab1207806406f1434c11874655af56925da6bd88da").into(), - }, - sync_aggregate: SyncAggregate{ - sync_committee_bits: hex!("ffabbff6fcdefbebaefffff9e37dfffebff57f7bffe3efbdfef1f7f987751dd176f3b3ff7bfa3fedff5fdf7f7afff7ff777bef5f9f7fe75f97fffe7dfdfffbdf"), - sync_committee_signature: hex!("b405701a0227b7c40805504a66069fb5ef99cdd84f1e295c9b4a4eccbe4d93718740efa9f8eca62f563dbc73021c00e914a69b00a9ebaa906e78f26c1cb8088af916096801c787f18f493b1479fd43f1f5b28d15af827a1e580713fa82bfa1d7").into(), - }, - signature_slot: 5808575, - next_sync_committee_update: Some(NextSyncCommitteeUpdate { - next_sync_committee: SyncCommittee { - pubkeys: [ - hex!("8e9fbd36b3cbaaefc176cf46336592e2b59a51e3035d095da9e1df9d2fb5aac5e47ad05d27784ca675442abb875a6559").into(), - hex!("b4c6164c5ea19f3da5a76a2435db598bb012ea34cc8fb6d749f1588463e5c39d29cb3d45ceae0543372246549b17deaa").into(), - hex!("a89c780da1a713e86b149d63312aa840e865dd926565f0ee9d9627d363eadadf5a4bd5f79d8039f2e2927ed7fa60209f").into(), - hex!("aeff2bd9faa0201abd7dd681ff97888c0ae71d84e71590f424facb2e37b5759f07d338dcbb695ad6ffd08d903c0f92ec").into(), - hex!("b89cfb61a59cdcb61e9f3ed76cb5cf13c907bdf6b2622e16d140743c5021d45cb6d91ee94331130b876efd984575948e").into(), - hex!("a2c889cc5195532bcb5c83d035cd6881b889ffb9d0536843d3fb6f7b1c093a927162add5ab6ca5f06e7c3ec4ca4522e5").into(), - hex!("b5966a6d047ef679a9613114149530facbfc7b4bee6ab23a60853f45de034435b624ad0126ac6c7d6a12b1be93177e0d").into(), - hex!("99249360fc064fc2778b37b107d834eecd5eae29e8f10a45d946f11fe358db065242482935224226e83f518fa6916962").into(), - hex!("8c3548aa879d974c5542e59ea43bb34db91f92c7d21eca5e3e4fb9d01364c21e8e2341eeaba1d22da67f1f455644afe6").into(), - hex!("828b95590a46cdc4756fc1a7b7d7c4031637494938521b74a3740a970ff532b88ffcb5333197088f6700925dcab5c42a").into(), - hex!("ae2e6ae80c16831c02170dd273ff6808e4379a8baf00e707d497eec6cb50b5a1f132eddf053f243765a54695ca35c443").into(), - hex!("a7bfac686f7b307d794fb1740a05cb1a6ef14b06150e64353a0b6544e7b0c5e3a7c8985d257c5bd74e411c0cc8424479").into(), - hex!("b3671a59e2d425ef0ed109932402ff7dfeec72cee39c1840cade48a13f3ff36bd0f9b3931d0651fddd214a2dcaf7bf89").into(), - hex!("b56c962ab20fae058c256e37ba4091d7a9e5d3c602e3eaa2d90df65fd5a11ab68f245a5a6e53262335c6dd4f3e0e51f6").into(), - hex!("a8be83de4b06ebd8c14bce332a1175a4c651fdddd4a58ec85bf4c68cbce83a50dfff8c26070d104556883af678693076").into(), - hex!("b4b33b7013c6af21797478b14b1dc81fb7c5661fa2471d8cb4eeaa62a62f795aa9be2cfb65ff6b957cb7f89487a587af").into(), - hex!("991a42351791da02bf6c1a9ca8248901657d6f2a95225e4827ac3171b5247cd31f9465c9ab1c2b78e268c82b61db1f36").into(), - hex!("88a38e70998cbed82ae7f9c192e06df8abdd35278efb25a1112246d46a3d3f0bddee41f5c492949f15e651ed7fdd6a15").into(), - hex!("87dcb7f13c6af7f7d102c643db0406ac7fb06fbe1fc647f436ea839e75561b27beabdd6133da332383bf22ed4f83fb9f").into(), - hex!("a441e2c51448b6b2ddb38dab213d9ae3d1fe70e91e1feb0f98590b5fb6f3c18ec0adccc221fc44ba027511c52e5fa626").into(), - hex!("ae5f4dc4266016943cbe1db6538619c430639a1179d246cb820adf8edcbe55e9f79471134d06365b0d459b280aa2282c").into(), - hex!("8165bbc59ef3b15f29379a7ef90d8b3610590c662207ea7c49267f36b5b62af3d48008d182ec3384ca7c1063bd25b284").into(), - hex!("8cdc4e6a238afc55406920620fa90f696403afc1797562b424c26e679096950e7f42b8d8327ab0d7573608056364fa4c").into(), - hex!("a1f4c958f7bd1182cd4ef88561eb534c9ea3563d149a276fc256645be0b2e86a3d642ac17261696ada39a04a866973fc").into(), - hex!("b19e5ca1ef1d4fbac5633cd29e9510116bafb3229749e0e4444caf9819fabf9c4c805b5966c02446c1eb0029b3c1293a").into(), - hex!("a4682af7e19328a145a1a5c43ad3e14648b90f664c6139eabe1a13da9b763ef23947dc3ea2054af7d0b7018f7498df51").into(), - hex!("999ae1a8f2e0cad6a0378e7e0a67c8a6ef4a824043b34e67074d05ceee93cb7b49d3c3acc961f1aab69b45f89d12180f").into(), - hex!("94a9f1686e91ec733799b569e3b0313db64f3a219b48482e2a56c21016e800d4373c2f8b876a923e0753a464e5fe4684").into(), - hex!("b4936942d807ad09cbaead9f56ca124617fd1fda2ff5cd94fffbbdf5ff2b295867acd1e41599928ae455d597ea45cfb0").into(), - hex!("a74166db86410c9722e657cdd0f4d1da86a4f83168e2bd9ac71850bbfd9471e1ed88a6476b75ae5ddb42afc62a9ac121").into(), - hex!("a97909c10241e046dc707ff9d822c385dd68be297d6b54c84fbdc18f5a1dbb3350e93496698d6304ad1d6bfd34b4a041").into(), - hex!("b6d9b775129b048a6c577656ac2de15135c2bf1a3c7c8140ce20a990274e42d7b602ebe932855c1d03373797ea0bec63").into(), - hex!("b59f975937cfc8eb510c1da0a7fff1960c46b9235550cd6decb514805439f08b8f18d88ae0373bbf50b028a08612d552").into(), - hex!("8af01facbaefb24cc4c11e13c64445600b1d716be66908964ef79e12c0eded04e1d23295444818f024e55df2aa911034").into(), - hex!("b79607bbe31f159b208a0d1b2f95cc5373631908292126b8b75fc44b22a8bcc9550de7b51ada33e5596d0f17d5f4e48a").into(), - hex!("a1a474a66940bbf6e601b6c6e63103de2d5eb76d7ad3d39dbd74149658a14e31143a9723327a73bf72eaa75dea42c3c8").into(), - hex!("ada18b62cf80098f36921cb0c2f85200fa362721c4673546f8554e2f5fc8639f2ffb2cac68e888af7ead8c660b0db13a").into(), - hex!("9198582e8aebc174dd168c6cf20836a21cbb6baeffacf9f933850d8e0fe0619ac1ebb99fa6fe902c75927531c108ee5f").into(), - hex!("b8a44b23d29cc5ae1f00d5384fd06f31b73ef1a7ffe334b59db668c924aef2cdf60c3070a44a12b52a14ba185198035f").into(), - hex!("a688064e0b3fb3baca87d711b29419a02c06e6a1dd764af31574dd84fe870c8ef614d4c2d42fc9508711dc05fe373776").into(), - hex!("b86c167a1c6738bfef1feb7eef8f553898f69a933876acf675596fc2e39f0a8c83ac37df69dffb669fcba4e3f1caab92").into(), - hex!("a32d52f3e9acea45dfe9ce6c577dea8200e68d6ca39eab5d6fd24c508d2028f533b8b04f1a4fca7965315ee5dc5e2809").into(), - hex!("8ec96bf235d5e9bf36382d79b4bd1be8a8e2b23a9f7f9e02ab6d708e96a1c12fa81eb236f02b0180a0cb9f3c1bc28cc4").into(), - hex!("a0261a76664fe2fcebe1501e18eac7bce32b947db7bccb7b746757ba51cabbc8bb385600a99b248887edeb84f82a6f49").into(), - hex!("a44313f945a1d462376e03fafe6d7a9659dd81046460f45ff8914732ed268b2430ff632aa0d368828c2076144bdc8595").into(), - hex!("a55fbee79559e1fa7b85718306185e3769a92052cceb600283d0236accc6ba2343799c1856609faeb7c685dd504384e5").into(), - hex!("8a3d4ea2eea81742fcbde7a1bea5ffda55c58b5e4618ace17773057932b7216b96ad4a117d9054de18f71b3345a0076d").into(), - hex!("aeaa0984232b1fd5607a1a67051d42df3ffe71363639e5130de243cea84c87554e6597f3f07952b7d40d19b6e18957ad").into(), - hex!("986c868f8f25db957f44a39bc209f1ff8e98e9bff52236b2473b8ba977d0b7e90d146ec86a518a581c5de796290d505d").into(), - hex!("b1cb0755c54e0619c8306636e926930605f15901c01e36822131dde1538b063d0dc485a97534ef1e12f2f0febd1092c5").into(), - hex!("93cf415d4d7ea309b85bfba7ebefc0d1ea91b8e93fa351262d9eb34b728c7a516ef0904cb2b3549db2b3b3f788b147af").into(), - hex!("97359ca81e9fa330f4c0a3b4de96ff45391c2f83247d1f73a6884bd123d34edc66a4d3f29718f5543350204488ee51f3").into(), - hex!("8348c9b229787630ce26a41e7c016adeef5dd3ec1f124081baf9db4ebc1a3f3a37b40d94183ea9eedf9a458a2e65fb41").into(), - hex!("a4c6b13c7dd27497917bc9a4c4a91b953b88c819e147087b125c93657ad082971152d384e8c512f48cfe07a69f54fd95").into(), - hex!("88008b395718646492ab944a9139b95251214c42e90720c703b19b99afc971824bb87c2a4d40202cfbb62bd2ee30c15c").into(), - hex!("946969ae721cdb08dab293a638387dca6045e230cd7c7b7237c75e123355db9b8e444089633d0977dbb6e42a729ab4ea").into(), - hex!("83435817ddeeb242c37d31877a55194f208f4cab406b10a4a0605a54a19745f3517a880dcab8a5a4422c0e19e2ea8a2f").into(), - hex!("94fd0a0f870a6ed2e6a4f53f5dff5b5adc1a6943203da6a34c73694702733c991e146f8c7108ff35d563fb67f55a106b").into(), - hex!("89bc609d5223c73afbca46a8c3cc271990a8bac5191f1ef6a2c88d7984adff00d67bcfcdb3958c259e17d5cba62beb28").into(), - hex!("b39077093900919b51e68f647d11e0f78359be69c405fde5735ce6839f739081437b899f33c6c9e6c86d4bcfed059186").into(), - hex!("a0a6f9f588e336c14b91a9c0c56085830611df85ce6e99d759c72a4dbae500b47dbe736287f6b2d65b448a2a0e6ca237").into(), - hex!("8222a17ad961ad325b819bd0625e079a471e597adb89f2170cb490c40f6b8b1a08b2e23a1abec02011452d589b183702").into(), - hex!("8b77ca7fa195450ab3399f88341a9d323e8b9b7b9b2ca30985d97ebb287e1f9b7e0279f22ab3a2dad682d7906f6c8d59").into(), - hex!("b6b8389382d3336bc5ffdc752bc699a6bb0057dda7879901c7633787a2b412fb7852fc896ce95cd09a9b98c76bef1b1b").into(), - hex!("970a20613047ad84b61ede90efc41a91ef7259a5fa79ba23964ea907fba1fd88d2710b69fe5bcb0d75ed9fb68d02e557").into(), - hex!("8843dcb71117b6044b1c7eccb5010d0a2f93775a98909bf23c1773ac9eb1c0f43aba26dad08ea7823da593c38a30598a").into(), - hex!("b5b147bf651ef9696ed3ebcfc3ce226b2748a4c4e7cbfbf12b3ff5f1f0b2ee1372477e1d7d8aef8d9ce3ec602a63d01d").into(), - hex!("95433edd328aa9223f521daf6d78ab272fb83150bac78ef6639cbc032de8834049d4992af0828946eca69f359987584d").into(), - hex!("b2f4d2154ac750245e966f62b92022a136ed0313964ddf534ff3e9b4456cf58bfe429ac83b718bb38db5a4fbafab23ab").into(), - hex!("b6b1f2a3a99496dab156c6159b8c98990501894b5b0cf200c792bc462263cb0aaac570f5a785aecf367a0531ac2a87e2").into(), - hex!("9985e3ae265653082f068b8ac4c09d10b2543f920a19911cddf18ac53a7f921da86f11836f51f2adfb26c7bf4ad51efe").into(), - hex!("90c31f4985c7481e5939766dd080f6ee01ac7a4fedb9954b9d1fa8fa1cb0e6e7185a1e31d8503542f1d409ed2f550e88").into(), - hex!("830736923cdcbf7de3ae650768482845ed9b45c4dc9928d66481c76ead9b27427a96989389c8583a153851ab957d67a9").into(), - hex!("82312631f5b301fd3ecd8b0a6e83b130b6e997a5a1e6255e883c590efa00b0ac3bee45c15308efe824aa665c8d7a365b").into(), - hex!("b8ed7b3c092f7bb05aca8cc4c2041161426908e8db349cdd2064e95044f9e7649cd569039e0ef0a94e006094113d0e22").into(), - hex!("b1d6e5344b74a67699cda807ad4883369a77d79335cb8eded6e0ad9b64c8661b7ddb47ce4308ff69f947fc173f496ac0").into(), - hex!("922f0a2f84e476e6fc00c196eb913ebfaa6b205fa8ce8c8453330a58956872eb2e4ec0087b398eb51819ea2d0aae6b21").into(), - hex!("8c729483a3d2ea34337d9c6260944da7e2ea8646de66d39617924681189c79672b0ccdb63525cb4635e3cce1d8f72f13").into(), - hex!("a00af936fe87caf17f5b365f59d019f8438a62b8f174510d863da59097986011a9e76319d4125ceb64f1d83defd822c4").into(), - hex!("96d33c3832bf0af5900a20c067bd45dbf3f0ecdc086eb065afea6c44f117eaf9ae8841848578d2915452e61bad014803").into(), - hex!("8a16c15a161a1e898bf06a23f62a9ec042c5b9e875cbd54d62e11be181647cf09e6a0bc65fd62017ae150525c16ee746").into(), - hex!("b4a0443c452085bb77b5790be42005178dec8f9085e2f1b963d55de6978cb608b7ebb42e4a84f24350c768c2e78d22c4").into(), - hex!("9168aa07b4e29c67723f4b87a025fbe6876f13c69505520b4dd6b387f16530a886bfae5e5304539564debabc059589fc").into(), - hex!("9504db9c5ece4ac0b703ccf751503665746bd580f11106df3c8a903ae7a5c9b0520dd16c89671967e2aa12775af4f67a").into(), - hex!("a776127d4e2e46c7dee8559ac56b266e7eaaa26eb8db0a7f4df0c66fa1564a349f414c9091d1e4c3e7ba96938916c769").into(), - hex!("a85785ed5832dfa8c9a5dd9d20523591f04536712c19a38c2c1496ce9c8787cf37964d739f83d9979db5574ed524d557").into(), - hex!("a4ba9a3312c2c253394891714719d2cb369eea993353b07f9a6efe3ecbd245f08d69f3e1302d6ee312e743c05ae85cf0").into(), - hex!("8329604134885c08173b14b7c68b74ceceb3694a0a3f7997f566ba94bb3fb2ad3f78ab3d02c496858bfc95655f072e7f").into(), - hex!("8e3f5485c98cc317653375ceb44636054a3202045bea6e9f6faac128e115de7a658a49a6432858db7b4b14fccbb93f7c").into(), - hex!("a706c82514d19152bc4097f8602f792a4917f5cb409c42dd42a5e4f2ebd1bec8318019934ed6d19cb43123293bf4ec98").into(), - hex!("ae14d5f32cb99bf3eb0d844157f12b836963be0d6f91b776f973a66701924c1ad9c3496540db4292580e6be871486486").into(), - hex!("a45ee325452d4bb2c60ef5be60b7d601158ca1cfeef0734727562b94ef8f72190005567e2007e8940f8cc538838f1147").into(), - hex!("b8f1fcdabf33ba011c86487a082b19fb146de932a469b19518cda2ac046c319059382cb8ab3715f8025573ab53c5cdd6").into(), - hex!("a613f3dd6c8361893be08f816c640cdea4d57d3207704774eeea8818edf102cba7ff7b06c4c5d0fcf0873b09f72d1ef4").into(), - hex!("aaeab877b1d16a4db6e47a8a864e073c4742e0a84e46ae8dea1a0eed0d2cc9f23adce9e0c8d88464ec0c059df99a9583").into(), - hex!("8fed26ca2cc519a44ae38398d856c3f75d1ea6cd02dd36dab004188f3ef2167cd67d279580f37176dd70c1a0ab08d72c").into(), - hex!("ae18905c02f96e110f40d3bd99ab26bf28e0af939c6945966fd5e3ff440e54bcee56d667a0a21d8326f88e5c22e42506").into(), - hex!("97d803614adb6571f4ea11833d0d9ca8221e7fc99a960c637d4990a72727ed2713da874bf156dbaa70bd4c2f668681fa").into(), - hex!("aa86c3bf79ebf46e1cee54f517b7bdced4c7a96d3ab27405e7d68dba92ee6fc7fc91a107f3cca85096f0d2581cb4039e").into(), - hex!("b75cdcde1702b5bd6be180dc8ea26e5534da77b1c7bf711c8447a565a63d073474f0270d78dcec78ecf5baaea1f75d1b").into(), - hex!("a36e810e50d283e8ef625cf684c1fd333a0373e5b0a9d81ba40cabb76299af93c536285c5d7239e86ec56905245ed2b8").into(), - hex!("a16b6b41e5c31901f3c0fc2a7dd8c084fb508947314c4bf4b6fb338d95ff2cf49fdc5de1d6b9acddb1b096b835df6ad0").into(), - hex!("8b580da99256b1d0d7a90dc46a98ce5132fb3928d416f2df5ed1769544692482ec8f2ad5f57871041d8c78d00c949a0f").into(), - hex!("945dc91cffe575f06b4b01fdcd580da57403469a21db6ffaa77ae06d31b8a2aa9957e26db1bf89554611f51f10c8f73e").into(), - hex!("8c55c4000195fd1155ea608f586a327cccd1221036ffd29eb9903f8f28009083203f18480b35cf82e0390a5ffef4bfb9").into(), - hex!("87cec982094c85f6c1e402b74b52f7c0495ab4a2d3f2309734aa0bd2bfdbc88b8bdd9556664015c7d9fe2f138dd7c807").into(), - hex!("8fc576e4f9057d82e2fd2270a787c596bce5fedbdb9f6d612c2caeb1a778450d8c1f6e86dd011a45f3fe7f201e520438").into(), - hex!("a43eb1acf0de695d478a661a71128ce9c58923e3adfb62728a2e9f185c9f46877db645398546a300b75f2c849f5ab14c").into(), - hex!("b57be020fd23d3fcd6057997099fdd648dae32cb750e8d058b62a5e902ee5ca27771d762020cba2985884ffcfded3500").into(), - hex!("ad3ad1089c8232280e9fa2f6c314ae57758cfbc3a0663ad9517e35b74b19e49345e03d1d33d0d7b69d736501ec5b3f4e").into(), - hex!("aed7faac2e65c10b52d7b3009eef010a624c7f57a5c76c55afd310345707bc8959ad619101b9c1ee4bde44152697c537").into(), - hex!("a6b177c7f945cde42c5389f7258689aefe1b6ee0b243f9901c6e60ef1bebbea9bc297689cda0c93aac9b28c7d70d0022").into(), - hex!("b079f925c29da333461adc949ff4daf19d0500f516d95e3a4c3dc2e2f5ce26ba0f08b2473c03b6974146b239532deade").into(), - hex!("8c573c73d603c8ed73ac3eedacd8ffef4c18425699e30d46be2dbbeb3590380b0fb713daf3ff3cf7544da502dcf35cfe").into(), - hex!("a39331c8acd40377f020611ac9f3a758832e0a644a5cca318c01e654696fc607e299b744c0cc2ecee2bca755c9aa3581").into(), - hex!("8e71e261664d5a6094ee912fa7e3e866ebb5c4c610062fb5fd733359d0e5a5d806a3370155ec3b04e83cf7a2d7c4a0d0").into(), - hex!("ab048af1200dfb67b4fb6bc8bbcd8344547e57942f7397c06988c9c42cce53784a0282fc13bc878635a3317b8f306a81").into(), - hex!("b32fc2da89d3a3541a61338e6b0c5a7f477a23bbb9a7c63b1087f36c49b6d9a42d4720708af496d82c56e1e6836f5cb4").into(), - hex!("97d0e8f961033e4aaf96a75f585d16eca691dd05f4a5477e8d3a0fd97d02555d67b29d314b5d150dc0de3b72810338fa").into(), - hex!("8223bb67c99eda58237a765c8fb426871a1a9e02e6e91d956b16e57b8dbc30c0edeb76abb30ecb2f4139a19922a4c62a").into(), - hex!("8d9ec5c0575500e433a4bc66d196d404b8619ea38b0dcaa036e1c1453eb23c6949509243531ce59318c22db6e33ee1ef").into(), - hex!("933ac0e3e6acc7a238fb5495835a591db77c39e27f4034dfaea20bce7c072ff6bb6f59a9823a07a76a431905afa2dbbc").into(), - hex!("99f3cab4e8005fdb6bb44900a4f166ef0c2c48dad85c0a127c4d854bca4ad32a2954a586734ee0e57f3317e5b81923cc").into(), - hex!("8f01dc4011ea394a9f7a73b7f246bb00472632fe715314525f1db2cc6158b22dad22d1371e7d0b2d5e72cc408f07cb25").into(), - hex!("96e702adba7420e819338f6f8740946289bca6f24a5f14a5bdc727d1cd66bb7d2a573cdec8ef1333ca39685c33f6e7b0").into(), - hex!("890ab24865a2652a8fb96ced381530192d072cad275c19539cd74e03c001321216a0999ba83c8f3a162bed003dcbaae1").into(), - hex!("96e2f1ed5f78c0b018cb388447bb85b33da331a5a306ce4e216d1070beb7c3900f979ef128e85180c56958c0d729ecdc").into(), - hex!("8ef642d5a1fa4b32fd69f7f57886d1d9447ddd9a8425a03f15633cd688e41054d5243ad6f352a5a3fea2be2f3cb7bede").into(), - hex!("84a3177be656623fe280f91e2acddba52c068cf8a37bd79b9b4186ef199bad65f52cf3e47b581f1964c9987f088fabd2").into(), - hex!("8b913725eb48feaaed46b2e3ddc0cc414aeb433dfa584155e2eaf29020f6f1fa0e801b85bee4bd28831b5cc66944f411").into(), - hex!("88d802c75d422a713c19a600cfc9cd843ca41e35722e21a0614c3195ea84752337ee30991d860fa75a57ce3f614e0a50").into(), - hex!("b43cf4b09d02b20073903bf152f569a43864095622a472656d8a96efebfe3a20dca86871268ffc528a194bd951662d71").into(), - hex!("ac1c65ef79ad0e56184bcdf0680dde5547bd01b95d7e9c3c71671c71683709cdf7fb988440c3bfcb847c26f198b94f81").into(), - hex!("abebe453b3f2430a9287d0d5fc043f7ee434b33feac6b7dab58d5deed7568e0730d59f94b1883e3d43f3c2934d3f40c8").into(), - hex!("84e0acddddd0c202eaabfca7cbf88774ae374e841899942a2353064f132c6205ee378277b2703744a8bea9bc16449537").into(), - hex!("a69865f8a3f66ff4e548ce29a212041bcacdc85410b8467f0515842062b3204fb1b7616e45fb5f46a5619808fb390dbb").into(), - hex!("a55b426b402e9b27fadf87b27cabe5375c6941b22597dea75586eb9dcb699d925db77250b1d755512aefbd4eab0a2e4d").into(), - hex!("8047da13f072c9e848d33a0f397ecf3e783e7dd507ded7a4de25327fe89c183c8dd1da3d419b48f53d93537bc2c1a8e3").into(), - hex!("94a9345e464b9b28798c608115438f1eaaa60a56abad028729dddea3c856f7f871031b4f100626f8bb7a06d88f7cc6c8").into(), - hex!("aac8cc93a4bf5b383080738021fc56cf732988622fe0d493540545b19a6a54cdfe9f8cd2d2dcbd572bdde0d1f8cbb101").into(), - hex!("80f24fae3c8d202e8072092342f8b046dc9edfa1234c86e9f06cdd7fd2a1dc0f81ad69886a8c219f53a94b9a75cf6b78").into(), - hex!("88ac9c1d5c036f14566203d8e18421cdd21b2305cbd20f9857e4edd09e002ba0bb5c89b039cba417b353c6f2f63c50de").into(), - hex!("a45c8ac231d0ddca06f1bf03eeed331e9b524ecafa74642e4c4591cead603d4228cbb0701af58770100964fc880ff85f").into(), - hex!("88767dcda5fc82e5ee515639992868790ad56d2a4fdf1bd1ba1c5be51b381c149fc9db23b93488b54adc89fd4c48dcf9").into(), - hex!("b23e34136c22ac73157c7c5cc8a9491b0b5bc968c95a9c104b402cad9de598e323ada4cc527555157cbecadf48faf87e").into(), - hex!("99910638bfe8b9974a1bb7efed279de750deb046bc21a9655da4ea81a1aa807f2b76aa2a64d773b1b23af283ba3878f0").into(), - hex!("a05869387ea3b4c8f7403d85ec788499a993482538e0e2078d016f00d67571d1342187ae088c788dea518bdf295da88d").into(), - hex!("a7dd1735f178d53908e29db85ba6166640da8c8bc6f717e0da9bf74c547bb98a512266cf737937201cbf6d14bd9420ca").into(), - hex!("87f5b096a1263b51df28417fb423604879b18c4d0a8a48630f70e0f95226bd51a252d8be362df801680344330857fb5c").into(), - hex!("b1a5a549e27b8256c388465be3017dd123a7d257fdb49b2bb409c6430b6056cb8125bf88b5f196bc9e02567a6728c7e8").into(), - hex!("b70862d190351d6bec9c618057e407b43864a0dcf860b31ab6617f75e1ea02de49ff338a45af53783cbf10400c878a32").into(), - hex!("b27a654ece8541b9bf9c6ae0047969ebb69c4687a43030b1c412991dfaf349e2d3caeb6b7ae3d72ff0e2d758a04510fc").into(), - hex!("81368aaa4489c992a6ef3b55df26ece993958df2e40f04a95ca514fda56c2fb98f11d61faedd31860b89e89eab965f0d").into(), - hex!("94e14e03de977732b7c7faa60ec8180e77233a43d513a37c443be4fa0bac64308d6a1929de075b5d51efaa9bbd6855f7").into(), - hex!("b2e26d7b979f93e8dd55eea5a0f4985bb254128963a939ca07fbc33bf83ad7796e9426660b2f35088d7aa5fa0cda2ec2").into(), - hex!("850aee846e93c5204c1906a2782da71c0ff9e2d1962a778dac77561846e6f9290ab10daf72f189df0a57c1548bd4e6cb").into(), - hex!("aabcd7f870c299cabe4dad1857b3b6cc3b9fde2b525e9d8ec0fc1f497cd199108971173e61cdd5937c45758cbf7b9403").into(), - hex!("ac069d7ff2633fc73bb0b7607d9c27305a4e15c189c8da396d6685798c12ef179bb44cffeeb7435667fb03a799eee5cc").into(), - hex!("99e3eb82b955b2411d1b81d946e5ef6b9c6957ae0e368f4a9c279a0541c3a46e289fbff526a1f9db4aa21b92d13bc9e9").into(), - hex!("b5bc3dd1e05a66a1d775ae0ad159df19c7188f2c73a8553525855ab34617c7f080e217732003e09b29a5b36b12ba564e").into(), - hex!("aa631a69aa4a9c14de2c49fde83453633d17bb258a2b7ada723bc8e71ef22c617ebdf8ba64c72675440b35d419d0f836").into(), - hex!("8f42bb48587cafbb3936adc495e82981d7fd81d8c0233a4e4d44f9df72f8439a9a0228d6cf9d156ea608caffab8d9eaa").into(), - hex!("94e079215b8d187d546f33d5384673215ee65c70d3bd0778f67c11665af5fb025b4302518a0db6266996c136ee90d4e8").into(), - hex!("b3dcb504b50dc58ee7f2e2f78ca884d5fc081b570d1177b884c92bd34272ececf2a9319cb1cfb9df011d4db3ad266e42").into(), - hex!("a5e5b55940e379e6c0fe7c6ac9ab86f3836f261942e3933087f1e1deecd280af9afd95d1bfb384976d5947d5069531e9").into(), - hex!("b1a36c3a0a79836817a2890ac53c6768ed3965bf5d1663e2df69b1bba60910e84dcd4f917991812b305367786edfa288").into(), - hex!("a8d07cbfbbf31d113b80d3a1f82ec7c29c4d78007efb66b5592255acebbd8e1b0c8b927a866c79211d5d4994648153ca").into(), - hex!("acad1228fd1ffbc118ada45a27f33ea02a09455d0c295510da693d741ca3b5725af41b99967ea6d429f604736a4fac81").into(), - hex!("b201ad414928e315aa00dc60b89c7a15464d5e97c30b551a462d02c35e327d2ef3244a98a402f9e055a2f9af6e970733").into(), - hex!("861689f35fb72780dc0be92c140dec07857290495baf3137bd2e83ace2f268f205ffc58edfb0e09f323ea5f14d0ce10d").into(), - hex!("89138730c80c30dea01abfebbed79bbe6016b4924193d9c2e8bfaeef30616bcd92f0eb24d5345bfb005bcfea989fd8d3").into(), - hex!("b78092afc3f16397d2eaeb5bdd7fc6c01ef516a71102124febc0cb443f4446c18037ae75c7c1d0c8177454b092922ace").into(), - hex!("a739cb664cdefe7a2f38333fff13bacaca129d718a043fae1a1b7c4251a77319b44589429dcb9ad113f24e11d3b75024").into(), - hex!("879996d4bed3d3235c0f73ac8f3f612eecb6aef6756896920e0229f5deb1d91feff95734e6b4143ba89badb5cc1f0cf2").into(), - hex!("a213d854a0496d74526b3c37a48d6f610452b44202424a419acf206df1cf76f7357ff5c0899e45adb565535bb09c29c1").into(), - hex!("8afa04d66a3e8a2759ff088395cd98597883b3ca6d8811703f5fc74b822ce4e56e1dddeea2c099fb3e0f6648f990f1e9").into(), - hex!("8a2e7ca192972af2b77660b07aa612811fff94c951532e3fb6829e8031355363f4aeed0f9e02b845f00cc9ad4b744c4c").into(), - hex!("8f0757fa7ab1eabf429802c3811caad65833e763029c3aaaa43ce921abeb277d7dfd06e0e58d36e494871ab9bb090668").into(), - hex!("91c0c0b0564fd95db51c73637fad622e6769206bfa03e41474a4e68369d10de7da5d1bd2b5d226f0564cc1ee8c3e9074").into(), - hex!("82b35466d835a6f13080628ce407cfe495cbeee26a5168de9e595a122ae3757f2eb0a64a71ff1ef6ef26c8cc97ec1f52").into(), - hex!("80d11c7a711fd2dbfedc76fe018fca09295d5a3146df92496ba01063e5e098198cd9c52d3802e6cd033f64b3c651b67e").into(), - hex!("8607de2cda6838c70f262dadb21409649900c27a5bf3505ce2166ef6f616f4b7119aa3e3f3c62c1a508662d7d68e8f0e").into(), - hex!("a1c14cbb653115b6225f53e3e6ef8e25f87cf47315b25dea5e658493121ca22733d3fd2781920dfa3a04271d58970749").into(), - hex!("aa876cfb3d572bc1f84a5579dfe8df82a9177b441492382e8ef6528e28e46ce59fce9a82d42c1c2000b28cff06596d18").into(), - hex!("8742ee128452ee98f21360f903c0a57e600d622d4ac793f32d6732f5fc315f757bac89b0f39a4ddcf4b8668cd02f3e78").into(), - hex!("a2e04418db55c0d9163a1bc242e6d43230a943ead121bf8a5f50c109e4ecf0fd99e5b126a4fe2ae9b0a248e613b54f7e").into(), - hex!("841b7c0ab57c2cfb1a180a9b0a2875a7675624f0e5c779f01f3f92a1ea547cd1164485f54bc433d71c7b054a6fdfff15").into(), - hex!("9855f3506dabfea5a133ad49557c3c9e1c7b6965215cd940bce4bfa90e98d9c62999feb29da0af8768b99f5f82c64489").into(), - hex!("a65939fb29f1d913e36be1f877c8b9a3549ec17313c4354b1834cf7ca9ae220af26a72cdfdbc59567bcd7e4152d90930").into(), - hex!("b64edc36e0bcd48cb350350fce955609ae51f5bd197cb7d42b04a2ec7f8dbf236b2a3b23a6e0778d57796433f0e6e9df").into(), - hex!("9379a72a722c1a5c8399acf72ebadb7ab1c5a2e18137cd3850b211dfef907850399b6151ae7bdb590a6eb04387ce0c31").into(), - hex!("b621023f0d3c731f49a48378c3709a0c051fa1e3f8788d27169a76dc35d46cd6095b32d7e91794c35f4af8d75f950411").into(), - hex!("a82421a53687a444a065ff1e11c439cb7342a3edf496f2ccc04f56fc6630bcd79ccce1437479a6e7d6dce918d3d45181").into(), - hex!("857fb59242e6687e940fc114df3c06af5a89d85c762140b1e4b0f8cbcae9d604f435377d7a2d153a65e0dec099e3e8f3").into(), - hex!("95e6a571cbd7c7a58c1c599cb4c837c9f31757a6ee4ed6740e9d55c350baa847ce6d081023b43b397a3798c6843baf13").into(), - hex!("adc1e1f8523fc6e3d683dc0ca15ebdbf471de635f25fa7be6fde9907bd3fad130baafd7d21b43fa04738d4c19448d788").into(), - hex!("85f8ff5b661f9e529421f7e5f831db1919ba3170a59673546db695c3af8a82cb1ca352e07e6c801ef9fe6f501d5896ad").into(), - hex!("937b374871e35266c2815e4d0ad72dc2b6c756e840ec36fdb90a71ecdd4afe13f6064ef36b9d1590a39a7be2156fd728").into(), - hex!("ad4aa9b451187905652222dedfe6135111ce4eeebcca74ecc74f3464a07831754eb0072abfb96adc23d0c5c33a1d9f16").into(), - hex!("815bc7c9c7c84396bd0de5c71b78f2be5fddbbca3f600f341a21533ae6dcfef8bb94f4340ec2a90f40ab091efe4cc6e7").into(), - hex!("90bef1fc273005610cd79161686b25d88ed2ff2abe18f16a4054fa05dbcbaa339825616c117f55ab26d12bdf2e414f70").into(), - hex!("b96e51c2d2bd0fd78c4d3b9873d217eb76642c329a9ef293010fcadb45ef2f9ee3a9c34b0365e344d33c464c08a0f51c").into(), - hex!("94c4048c3fe7dfe736458ee16566027290f93b1f052c3cfaf28f5c33c32af6b9cc960d86181d54361dcc10aca9f81a58").into(), - hex!("aeaad402961126722aa5033c6bc7735d4cddf35ededaa08073ab1a8412e5d1d06e95c58c7a95409edf1566ae904d795d").into(), - hex!("93d019b814d00d5eb6e7545e6480da089fa48ba34f0a961c704db12e34a144818c306cdc4f31320e542c75eb0f1ca96a").into(), - hex!("a3c21f7864512c38a58f02c0c83993ce6294329b074b801404e4f941d21e4e7e5eaeccd41da8ac423c967b7230b2a505").into(), - hex!("80c26a2aff26da9d8d739496b5a63da6d8d35544c71b7b05b41ce4cbda89e6d32e85fb1e38a215aa01dc64cb43e089e0").into(), - hex!("8c5e66d7668ab7e0de06ebab4a4ffd13f24e4458610e64a972a1e1f15356f6e745cf36b8cde658d03817f2749616fe84").into(), - hex!("a1260c9a6727d6d4a4c147e0c7ba91c5e2a47b5a08a07a3ba0eaf9b50360b6919495b4aca5f85e8fb2e4ef1c307286c2").into(), - hex!("9150fbf49242afc6ab7f865d4a92e7013eabab432b341710232e0fd971eb2b214a3da5b82617a8b7defacbe060538ea6").into(), - hex!("ab44ddafebcba5a0fc1002f3bedf595f3245ae07c9184d640154968e4993d85087efa8a173a670d07eba1c00d3ed1c5f").into(), - hex!("91580bd78343a09b62e31bdef63dfa9e0c874d7b39eb8a4300388ab053f262e118f790392f73d4fcf7714b521690d94a").into(), - hex!("ad4b8eb477ff8e573a911a1a4c1ba027088828cde7907e193ccc4b853aea74c66d19ea99c3779f6ce4d505ad83f2174e").into(), - hex!("a5791ba6dd8534607100f405b2f104c987336d5c47a544ed571d0babc6dd88a634296773faacfc3fdc13a5f7ab0f0cc6").into(), - hex!("ada0d1c948bd8f66442cb4b9cdc3a5368ab6c585cd8be766b468864a8fbd60535e454943731d4121ca134743d05221d8").into(), - hex!("a83556f376d8cc4a26b53223b11426da96bdad5351c2fd451ea053346b334eafef9773e3486928b9d407d3e13d5dcdd0").into(), - hex!("83be01b65302a31c5ba09c8329f683904943cc8017cc8975272d7d284b6a15a3313e27887e4de9110f64445581747ec9").into(), - hex!("8acd831b27588a99743c5d4f61e6f0610faa530d6259f187aeade29f1c9d5956f1c01a5faed8be8924fe1e8d9de03571").into(), - hex!("b17e88d1fc760f3d6633f5b48411b7237e276e2fca621d3db4619da62993bdeb3c12cfe7d130a92e4d3a14693d1b87eb").into(), - hex!("b769850bf9b77a1958d5eb932f99807cb695eedafd476d99131e3d7340cb845a33cb2cc7b640a0f3b14901b506802ff8").into(), - hex!("89e7eb7cc852326b6e18cf5c720c4e44c474d254de9e912d22510aa4cc1952b5e5c40b46a4907be375b89bd57d9f1152").into(), - hex!("af7ec9a4b836709701fb497f69dbcd0d94bf986fb6894f48c67014bc8b0ca947da71722d87de0371923f5bf2ec82ec64").into(), - hex!("8d3ff45719a7fc5254e91c710d956a16b8e8435fc4c8f68d1a47672335246bba9627d7058510d25417b7eed5ece5c110").into(), - hex!("a99a7b987f7050c230ab1adfa50a30b4f3782cd31467ff9c2a749182a1974a36a6a375ed5b0909d1e627b32ce0245ef5").into(), - hex!("a0bea35f339b54d82e345204fd4b75d41af3bd08d33b223211e496ef7fcdd8e327dc5a9ecb6fcb7de134b3eaa43d30f5").into(), - hex!("9419df6b2bd022fb6c79566f932c37828ca7a5a1a9efb64f470d7ec06e0d6b0b0147cba88814581a0773c80cf3d21033").into(), - hex!("948b0cd553cafa57de03279b83fa4f28cdbd0ec4e2219e25fad53c9d3d28c619ede568ad6e095a155d117caadfa87551").into(), - hex!("b21383b264f67c8c66011a79e20a4d739d1f8fc258562e6351eb1e1c5b83e42090f1525886ff4b65875868ae17a8faa1").into(), - hex!("aca93939c30eeac8fc83c82ff6ba3549ff38121115a60b7fc94b7d64e1f36f65e932bd8f3bbf2bcba986c9309861fcfa").into(), - hex!("a728507043b7e86c0bf19cbd81a45e1ac98d2edcea4c7faa3381df13f6352232b711b03829e3eddb7770213866dde7ff").into(), - hex!("ae0bafa42eece82975171e94b14e7063a09bbcd44cea6b7da4b820cd5d984be4c00a2e9e5137b0d34603e1ac914f889b").into(), - hex!("b63cf4b55c4a62c50c356cc2721ae5a89244ba9aef2c9f5c93762837fb14197479435f593947c8943ac77e6a2ade0208").into(), - hex!("acb5cdbe2cc7c44ad3980f9ba74b0a97f36add3fbb4e9b513c62157c14812aa73fac68be8c30170c39d1aee626f5a1b8").into(), - hex!("b14ddfe1c42321feb8ffd76ac041814f3d690fc16ff47b23ffcc247e8722d50ae001b6df4e1af6cd7c67c8799c8a1907").into(), - hex!("abe60d6024a9d6874df7e59b4bbd7e1e55da22adba1d16320fbfa2b68e8db995997ce6f81f8809e96c40f548ba005787").into(), - hex!("a23307e2ee6d96561452294a9265cf0eb1d6f86b30c7ec48066cbbe889eb7f0d64819225293496db709a1fd60dde7e5f").into(), - hex!("8bbd00e149a9fd5eaca24581821c3dca114e008c3e92a36db536944f6b5e5e983628f155c2319cba9a8a2a26d3885add").into(), - hex!("954fcbe0655b82bfc15679237d98c3759a49ffd0eb7f5da1827711814b92e0a4be2c0b7a96fc16ee3e31099c993ce6ef").into(), - hex!("a9bb0a14061ab4de136605e94899a41c3585ed190b2a97f529e911f02ff389652049616b408aaaea81d38f08a8f6c533").into(), - hex!("b58fa12cd0b69ac2e5c50b543bb15abcc3a0c96cc9cebfff34c4f7dc83bb5ece69d881348860385456eb6198ecc640ad").into(), - hex!("b73597c5ffd3a812e8a553bd3ad2216282fe7c1203120624b86cacb8a7421ea6807e29fac3383cfd61d632db8e3af5d8").into(), - hex!("ad153b873be0eaa71ad3b0191067874e085164f8428b89c7d2e01af0802169a9afa1775ca0f9491350db9e6c7c6581e9").into(), - hex!("8a7fcbfc564fd1af76df52ac5802a7342aff25d745307d2b9cf29c4470273686d9877b4588754af0e1bbbbe0310c3fdb").into(), - hex!("84553c8b77c7e5c81bfb1413cfcda7f8fd95c78c011c19189784be6a5e7352248b3b30cf5c80d9262de6c35ae6d4f1a5").into(), - hex!("8866da76cc8ca6522c3d41c950ea7fd67d448e1d567ecfd0cb916912d597b754807f7489f5e3bea7b4110cc8088ded24").into(), - hex!("84adaf9a79d5c3bc8dc7e669ccc5d4964254d0fc32bc535e54c5e4a4f45aa3c409c11eadd4fb21f4c831329087adef06").into(), - hex!("a77ce1ee4f8feed6ffa0c5cb8fb7fe0f95a03117e746b56b5e8178d27a1582804e84a86aac1cbab53aadffd9f84c0bd4").into(), - hex!("863321bf40995482cff032854ad5017bd885baaa6ec4ef47ab6bc713640b1e258eb40797ba049fe677937e3ff7a2ba2b").into(), - hex!("a46fb6fad471bb923cc38748253f887b53153ccad475240bf7244c1f9f568ade931b0522911348d64460021639bd831a").into(), - hex!("86604e383195be9c40ab728db426af87698d0e34157edaecc357544037d66d40e558cbfef7b005f8db3c9faf541f2c6d").into(), - hex!("abb7d323687c1d0ecfe89d411d9a81d05d009b84e652af437cee40e89bd2657641cbacf28120fe93deb0a1d3b410fbd4").into(), - hex!("a8d2488d99e04b79057739e6e0522b38a0f68a21bc190696c38d96f0e58a9395e3b9011e54d2cf7e8fd0b380e753f2ea").into(), - hex!("a36fd6a64f64f40ece0babcca8926dfc005cb1d90e4adcaa9c01ff3bff8d73cc0f95bdcb4f09d7e3b5d761ad5c3c065a").into(), - hex!("9699c0c5b1695416470c302f3097e93b94004f42369be26afdf04aad49bed67851d50f14c44efc0a90e311ecb27b3387").into(), - hex!("929e6ba1338579c1cbe76f1b075c0fd9725adfa97ab8b821aeee75133a874426414fbfb5cde7f7f8b74fbd8b27bbf7db").into(), - hex!("ae874a087a61c3ba4bdc2a582cdeace6d321f81683636440943dd860c783344d4133196197a108f6f473bb1e75c597ae").into(), - hex!("95bb2da076a9fc25e96affc7e4adf71496dd5802d7443cb5a77e3d52ef544aaf939c0884169df547000b3afc55cc208d").into(), - hex!("b0b63d1993f601c8aa96448183ff560f291903e649192e2e34e796bb66a31f9d0edd0f03ba4f1d299fcfb1e931abbf39").into(), - hex!("84cc92f8897d0bc0efee72d62ec3a8c07b7c72e00913860623982bba412307c2c42069ed90dd996bc56ffd0573b607f4").into(), - hex!("8ae9804b99addebafd3672785d4402a583c97821087589b7a129961b6131fb18c2fa60d606cef4f636b6cbe46b5d6415").into(), - hex!("8f4c85506e99d383b103217077c70571ad8b9046d039174df6d9f1902f8b85143754969bcec37519a1340c79046f1c32").into(), - hex!("81a5a0214a381d72657e1142a781fa8db0d849e1e012babe4c912a1edebc5dbfc265bc7fbfdf8b6ccbefb55eb0fcbf86").into(), - hex!("82c0e11c9016d95501a97e551b8b926fa317f02fb6764cdf0981796e6e23cbf13e48d46bacc875681900fe8c1741cd27").into(), - hex!("a00912f7bf9abb33f1624dbeb5a960ed32addb4d6bbf9770b6d82d514eabdc339f751e41c8f4461e560141b53f086f8c").into(), - hex!("8d905bcf245556e52587f92957459a41b9974b5d8b8d2baf2d8a98edcac2a77fc8b1eb70024e1e28d5c7a190d9f2a77c").into(), - hex!("b8e19d883289d97b0174cebb92d12a8c6ab16e4a8f0db9d7b67ccb9bdf97f070352e6b24c2decd89e7894099445d8b96").into(), - hex!("89cee93ceec6e742aff71ff60085f04e9550ef5568012b4ef0aceec9928c677f9711ea553499db812bf80eb5df021396").into(), - hex!("89d58564c0215295070329974e51e528ee4d9cb197b089755a86451098bc2f347be8be5b0cc06240315f75222ba2e9a7").into(), - hex!("a312cf33dd49ba6488ee13200193f06a5801407a15fc79956f977586a27a4b2d4cebf0da22f6c1100ce2a0d08730a383").into(), - hex!("acb541c487eb8fb4034ca6208f542c5adec863f1346dfd50fcc0ba1c6866e43f0071c8cbdd62ce6a2498e16e80855fff").into(), - hex!("98022eb774377f49b90f41439cc6703fa152d1d38c0e0c78eed49cbc54670369cb2b7acbbc37dac6617e57e527e41b83").into(), - hex!("8f00d44e73473d7b96a686d1d3b0848095d0514b70128c22ccc4141219dc3f5d2ddc3345cc506ce0e747ba358289bcc6").into(), - hex!("911e37896367a3e8603eaf995480bbb62229a3758a608c4822410e46de45a1048ee6f67c2039aba9fc95281ba5476623").into(), - hex!("80a349a605d2968fbe362e40672b33eface969c975ef75a8fe82ee7ace1d0b5034b7af8667650e813876a8a7484414c8").into(), - hex!("8b00779d873c6976d8b01afc94734fcf943c1819ab1c46e512e0c43469cd08b93158caea1cde84d13a48f27407048748").into(), - hex!("99030a66c4afac7e3753abb669cdf576cf96e21b1d698135148ba133e2d8fe97b4875d770e6246597461958224f653c7").into(), - hex!("8766f592d757c09f617090eb8f226016073a992990e16fd64a705c0c3104b202d36de18ccadcdb3dac5d68afc2495b4c").into(), - hex!("961cce69a7a39c20500c96332d2ce4cdeb3d844082edd527fd1694cf499b30bd33f06da66047d3849b49f4c2ccc8bcf3").into(), - hex!("8bd5dee639c3ef32712931295cc5bd0a8820192aafd35d1f1f9a24130bf208b7cc3f2ae99d6fce02dcac4c8225564d5f").into(), - hex!("a89ba310a62330e7396ae361da7a74a596e4a8be02496c8f4b3c860ac5c3cacdfcf4790d00b2ffa75fa900db2bdb15fe").into(), - hex!("89bebf6f59151404989f282a567c378f2f5a04d85225e23e22e0963da27673f3c7e8990dfb526a1133a988811cd03f45").into(), - hex!("81e9ec6ed189c12ca8d4fe32e21c60834d7938f739545c7dd76303ce347b69beba9eb14ab780c00cfe3804c5756417ba").into(), - hex!("8bbbd7b584948e34852a26d18b9dbb46f2974fb68bc8317ba5a168094a74bbe2304e1dc438777ccf92117831f7986c84").into(), - hex!("8ffbf94991bddefde2bf0ccb115b00d7b19a6a448f093816b9db0c65a43a27519a52ac7b88e6e37a7f33d384d42b05e7").into(), - hex!("b62267be83a54451ace1b8e2b54994990d2e1d619e040c2075cf1906c25089dcbc08ed8c2f2f8f62953b822f163324fd").into(), - hex!("af6d55c342e0e7f0bc3ec547ebb4688a884b59410aca90ad6d8730b4fd3543952fe2476e2db871618d12901fbbd2b91b").into(), - hex!("9027b69f6e5d550acb459f8b4b9e3f05cf291c104594cd244b224eeb8cac419800ebfd5255d87e0dde31bba662e20134").into(), - hex!("8bd160918bfd8049878826f443fa416fe32bd018262b1b4802e015ffb0049197c34d730c5ecba951a93986cca1e23825").into(), - hex!("b82f2bf2bea66697c4b5ed6d340ba74bbe0dce84b2d23904270f3500507318ccca0dbc967a69c4379bd12766708dcbd8").into(), - hex!("b4d00a38be54fe5ba5984af648c9092b133f21b22e56ea106442421c03c26d282b81d31ef8d22ebf92c0c26f86d27512").into(), - hex!("857d95d8aab25f91e7cbe0ea70a3159723566192c1d6dc0e68c2b19565a865a0daeceb4b1c733f75b0dc9cbfe246d870").into(), - hex!("b222a1f3f2d05912987902a861796f43cde8124f7dc398170beb76b6434e7095a8e2d5de54b2692490cb0c325cef8956").into(), - hex!("b016f69dc65c3e72e77d43334863db2c364f3697c552d4bc0730f45cc32fab5f60a5dc0f9f2f6df409fe3e2ba3f2f3a2").into(), - hex!("931b966d70e048570c463bfe7ce7decaea3ad80d0540ca079ddb10958398ea27df85de2fb2b7c238d0763d6293d34b4c").into(), - hex!("aaa3cacaf65a90a6a8e8fcbb98b673160e5f410b28b08a8733444cd71de9e807e00b146ae35fff05160a786eba6793c7").into(), - hex!("8effa24ae2c3cc12aef32e737faf7985c03e2ccd984cdf740f31aac7a93ac295be7fafa3a4d47812d9e0fa5bc2b3472c").into(), - hex!("ae8f1044330885e22c376ba50926ca10177799628b1c3f6b731113126ace5faa7756ca80fda0c535ddc77d051632266e").into(), - hex!("8a6613706dce5417736438d9bc779e29646a0b12fb1c5b5e118aeffbe72d37ce71ef78d3da4f2cc8c1f3bb47f8721cd8").into(), - hex!("8a435b4d265a01f7de575ee8893105de8be608a370c2f1870b7b097bf3635abbdfaf164ac1c704a6c9b31d7baf48028a").into(), - hex!("ab842c0851dc81e247a42806ff83a2e23b86147d884cfc828cbd1f3abc7fee929657bb49a2910975be746f97d0bb7c7b").into(), - hex!("81966af3ed4bba12f6895bcc1e2d4af8a0b313f45446f4f2e966494460f77015d2c9e65eaf396653f8f55e50413e7986").into(), - hex!("b61357419b1d65649e79ccef51d68d1e7c746d77c7f32692b6ff315d9dacefdee2a527816ac3118e5c80e00212725c87").into(), - hex!("b3a0c1e36006ab666e4d4e98c78df5630abcc76e86b3c13c342efbb64c2f669d12a98e797429871c12a7171f7a751422").into(), - hex!("93601527015bc30178505d37cea121f19145e366be178e42c9ea7380ae34053c45938a3b4d8ef852ff8701764bf74a52").into(), - hex!("998a446e7b4dbd7a7a2055f437859dd3ddb44c52d3dad9250f085d797c821ed91a17dd13d00f532c5f0f2321c5b3eb9e").into(), - hex!("af35c5f4bb11a87ee3f626007cacfee4ca892851459cb9cb2e127e92c9c274f9082c905165758976f9c7bbaeb984acf6").into(), - hex!("a0df73b065667fa0f6a4894aba39b3e4aac620fb1a8a3be96c94423231917c3a7d75f04383b40cd802909d9cf018b0d1").into(), - hex!("85c9c5a5302b706af5af436c07d1a1a952ee1cf4a0cccf002f514473fcf85d05bc4c23b5da2d6d0b5d0aa503f7e41a65").into(), - hex!("abd1ffa853de61d8b26e6eb6c7eba5636967c155233a6d73fdddd361379ec51a74c242715b6ad0033a6343157aee7ebb").into(), - hex!("ae45b130af61f3e76012da75b19d46a786e0c21ca7c6b5bde193b2203d6d8b7b8afad25a198e8c920c69954d3d6bdc14").into(), - hex!("93729120899ef573f6f276a1ba861a400a35efff7a2074400bb6b5df818e3fc1f353cd5a8e4ce122a2bbd8f5b30126dc").into(), - hex!("b34615b2cf8912c51c02264008e0cd78b79c87b87d56db810d899490bc438d446f734ca958c7c291aff68e3211ec8c5c").into(), - hex!("a1ca372d158fd7eee15091582c6c1b9ac9854959677ee25e5786a94cf8c1d15b64f0019aef20331d9675e1f1ce41fd6c").into(), - hex!("a4bd66cf90f38233b579b8698f5655f077bdb1d626e1d36ceebc67cf7ab8ee8e129cbdc307895bf0fb6e34a4aeeffc68").into(), - hex!("ae06f6db3a3ea3a21193f6c6231db42d18fa3aa06a8295741bab35589dcb1d51256838dca01356d580e8c423c45ddbe9").into(), - hex!("b70b5f0cf21cb98c70996a9eb6e4b3562732505299149bbebef821477ff406dba3979a2526b9969213b9ba75e35de3f8").into(), - hex!("95cf5980f21a58f4604ffb99c8651752f724faacaa216f8c7cbe400774deda53f26aaa15fc6415e936f52ce13cec6ecb").into(), - hex!("933c0e5bbb358f5f83cf9e60c67ea8fdcc0b7a203fe5b07131e3bd69295c507880a1e542ab2a6a8d182866f7c6b14a8e").into(), - hex!("a8baa60ce583afcf85e4756dbb0a4871b330ee70f7872c3e36ac4d43f2587fbbdfa2a13162ceb7efdf897bb96fd2d97f").into(), - hex!("a127b3828c422ff51a067d482fb67074d45fd0a86bea5066c7f6dfa83f4b82b4584646518e898ff725cf5de055c6b236").into(), - hex!("871ef5a7f50e5ae528eb16bc30ceb64b97d111896d34fb4a65c93c8d0498eb7032033eb663f7b169a8af4b96e7acbe21").into(), - hex!("80d0bb10037029f0d8f8c9b9b46f0d0ff32b2198af44a4f84c8c0ace60f2b39f8f8d284308769c6075e9425d6229905b").into(), - hex!("b882ecbb78c758c951fe53b434af25b594e602dd783787f09ed077b79f7dd7851fed769a1593f5a5b938ea2171987d3c").into(), - hex!("ad41cb47b16077f73cbbc157527a17c936efa78a59d1f36e3c0dad67cd19fdc60cb772556018029611aa46643084f024").into(), - hex!("82ad3ad7a706ec19b39b0c8cf75d061ea3a1966dab04643f5b9d711e6651b45f0cd22ce5048cb51e4e118b305bdf231b").into(), - hex!("8286a4970b8db361abd04e5d197849dd335b7074f9c3fb91dfd19b7f43d2a3ae9e114b0cb6342463986d32d262c34d79").into(), - hex!("a844f14ffc4c99989a6c666dcdcc135c2fda96914220b1c565215d5c2c3102f5413b7edf9b25882a02a19aa78c2bc545").into(), - hex!("8e758f3b03fab7f5d0993e78674efe3f9cc211e268c12d23911fc01ae7a4c8f879a393e3fcde0c05c10106a59b59ab72").into(), - hex!("a973caa021aca6f0470460b84df9324ed894a441435a53c4f0c48fed4359242ee71fb3a0e4cf438839ed838f37e5c02e").into(), - hex!("ae17c713f10747282798487f02d25d2d8e7459ed436d90a895617afb9299ee81994ed68ef87ecdc0660b7565c323f0e8").into(), - hex!("978e68aa5f44daf9cfb9220147ff509ffde89d121d08d982a0fabae9f07cb3145c2312ad200f2f0dc051820fc54d07c0").into(), - hex!("844e58a9e35ce1005fd5785f56fdc9b3f7e8e073f48fa40da19a5e9e84aca00b8743c5407920cb554e926873092015c8").into(), - hex!("b296da231b6ca9d5535432c81f7d0c20a71cbd32d357740d1543e1e3910ea5d32b005938f9273af96e401637180f4606").into(), - hex!("8aee25d881e7ba99fa6aa2fc65ebd44aa498d31ecffc595ac8cab010f6cfdaca308f56e616ae51d7e2c2e15864eda0bc").into(), - hex!("a04298e32052d7f91096285c73d67cfb3f3f5463abb3d7caf3108d8d77aedf9896c359986ae598bf9602dc90e6eb3178").into(), - hex!("8c336e463dd98ecccefc55fa366ac70a2fcaf60acba2f2171490642a6f616a1c6b72601bfc3533a5f49ba02dd1e39fa1").into(), - hex!("b00b383ef5d68f0939c0538c7564614401283c6923dab4db4c72a05a88e05bb576ac374eda61c024345227bf45161e05").into(), - hex!("9273a1a6c9cbbc8d5a46498b7658f6125e955cbf19f0461d1372ea9de200688e4f7376b23b132b41cfd672fb42ec48b1").into(), - hex!("a7f04c0377207a6bb5d96e2e6cb9f7696d5dba2acc3dcd6021ecdb3d121a558999b2b3d92497f72f28f39a551b2fbfcb").into(), - hex!("8d530cf98af85dbd0bb7b1f2fdc24d499b19a941ef431bc7f37ca9328a4f6ceb0660eb87edbb1a5d868d3141fe6c51f5").into(), - hex!("ae88acd7fddf35c72c3ad1c507f8dc185546d8acdd92d70f00991f50afd67809167ad3171c7e45976456fca033f0a95b").into(), - hex!("8df71ffbc265a4bf475ac7ebdd5eba137f4c3b585075ea8957757661b3f11e7a92888094e85c8863ed53d91df45e37a7").into(), - hex!("917737cb24287f30c899dd88853ee3b9be54ea707ef38f1545ef9e436865be1399fd2de4d2c04e3fa5b4a3205f4305ac").into(), - hex!("837e57594b1b71fd9f25f27967b721df500e3d7c72f22e90f4315e10fabbef027ec1db0dd9863b817071fe3c9413a5af").into(), - hex!("94b9c2155509b2189883d2237cd37c9ed19c3a22203e9e2b045184aed072e406e93eb7b5c3fbfb85eeca4c5e630e4ed7").into(), - hex!("b022c75923080450ffe5ecb8e01972785628ec2027b6bf3dc2b09c92ba8ba55222965767c21a240705ed5af6e9d92695").into(), - hex!("b993e15339e28a472b3c98bec723ddeb7728822571ef1fb1c2a1607a4023f37d663b615c7855426170d9ad8f6a971617").into(), - hex!("b34db4df6a97056021b088c53cfa7cedc8e585f907a67d1ee8412a50d84e5e3d347011fb99d5d71b111c88f5efd44610").into(), - hex!("b582bbdd7e0d2ccabe94e6d193d1b8dcad1932d1e96ae8e1a295cc05b381646f682f1f66cb90ddcfcd7735b335ea0242").into(), - hex!("b289c068f7c988a69173d347361047211c302abfafbac1d87259388b5197274f5ee90d56228093a42eec32039e490868").into(), - hex!("88e84114e8e536051ef5197ad181f96ce13fcd5627f18964bf4bb2f461c6638033ba363800326e494e43aeee94c62125").into(), - hex!("80d16c3e8717274533ff3b764984479b3bc709f11ef5129644dfcbb5d8bdedc7a8cb2e539a4524bb0fd4d977ffd25fb0").into(), - hex!("9405d059e30017152eca6d6d86366a7a5570501d78c3869d638a2b8a0bdc8c5bce9f0b46764e78680e2fd41697af9d52").into(), - hex!("ae23483a1d25f8b9a5adea9527560cce5552994b3964ffde2fdda0ce7b6156e1d76e698d7314b0820976776baee37b63").into(), - hex!("8d8395fa4ff7ad0ae3be3d3c446cab058890cf7a07d0a2825e22396cc938cf2d7a986745be5e3c1758c5ca0dc29c0ea3").into(), - hex!("8c5899cfb437a72d99085d8abf54eeb345d7da59ef93978b0cd9207853dc491451939f4b1a7bf317c87504ce949713b2").into(), - hex!("816ca0740bce43365bb20e41c3d0c88cad587e4c743b2c0cac9dc966aa8de220da347d65392a9b750a2001499027e3c5").into(), - hex!("b3d23c55cec1d18bedd276d1454f93ad28c72d921dd6600d8102710770f52b79ee8cf445f6781c2ca095c9a25d41489f").into(), - hex!("95d541d6196c1221dfa5ff213dc3e658649a3cd4afc8e738631fc7b6914bf0dca74f41cf382fab364dcb0d2d6ed489ae").into(), - hex!("a1ab2fd361b973027f6ee6a9f8f2c081cb5d7199d69e36c280c7f9c3e99b1cfc994ad7f68ac0cd78c61bb419251fa14e").into(), - hex!("ad36ebc0cf82369457b665dfb2f8444fd2add0b49658cef2c800ab0297bade2c0249bb124f3d321536933128c1149c92").into(), - hex!("8f917e000d7688a0f508777b8db7c0ace39677c4458d7e50d8c9dc59d32faba4abdedfce3af26cf3d04c020e526ab597").into(), - hex!("aa994238e432c51896efdfa240f75fe40f1b1a7b624ff0aba66a35f827b9bf1197de3cdc0bbd9d0147304061ced0325f").into(), - hex!("943da065ec673dd41351270747e40c1f5a8dbd7ba259c501349ed754ffb91c56747a78c392cb4b78a796d748044798d7").into(), - hex!("b0c45ed1457710daa48edf2e61ba59988a8257ddf902318c6bb00be7a4ad8235b46180f7353d9f0c0f747a4cf219d1fc").into(), - hex!("81b56da0943d2940fc8041a51c74dd03f6dcd8a705ef2ec3b685395e313224861f29de31205d45e944e437179f19398d").into(), - hex!("aadd5eb1be98f3fc7e93925e46062353576ef2ee81421fe3f6850701728b8f74637d66cbcd344364565b0893d8bdcc9f").into(), - hex!("a5dd3dc1e172c899f4ed17fbdb842bea7d7f3f0d6b284af9749e25acbfbb2f9c1afb1848490bb22da9ddfeef30232323").into(), - hex!("84ba149e940db1663271eb16e920442bfeb035fc601a7389f85c78ce7bf27b13b5c1a5625d8b45dbbf199caf2d753bf9").into(), - hex!("b5634eb31a68f45a2aa17e8eae7752d8a58673fcc9efad34118b0f3db7415edfdc27166e6d809406da0bd26a0ae1371c").into(), - hex!("a2ad4aa94a40f1c159c7588ebdd77b80edbcfd95e867ec6991f711d39b4dc911cfb6da6075db23bc090218976e9ffa38").into(), - hex!("8de6002f3e789b014254b32161b5595257eb01ace67a8cd9657235e2d04f7ffce6ae0d059488bd9dc070c32b5b7b3fb3").into(), - hex!("a5f659b41f35fe6a9f43d1f72c803da876ee4aa5b879fbe5d5e93be38dcd5f10716122d83afd003b79b8120d83358884").into(), - hex!("a64e6b71dc6ab9eeb17d50e1d2516c5ae63680b50a6077fd870780aebffca70a8b7f8627e23731b79b3866813a20af0d").into(), - hex!("b0003260e70f86eeba286d3d9f6d73bf15f084e7240d9aeee38a1173ea5c47fd9a9637384204001873732e6a407edadf").into(), - hex!("8d4df6703cc9f1d0760c67ae6b20928ffeb6b13d67bc406b8a534ecb07d6ef415a106ed992b50267677f7d114f9d69c3").into(), - hex!("8cb982f382ac327918387c16c73de1ec5ff979923f1110b9660836ddc2f5f742aaf970700f7b27fb2fdacb126d341353").into(), - hex!("b6988aa5e4043e278c01c83a9774175b1188bc2d78b96817a7fb406f86aa4395b7eb666267e819a5a0615803f840171c").into(), - hex!("b69c70007de643e3fbaf7b557bcaaacb67288ef6ff616c9c89dee0cedd33a76396a90cb44207225568870c7c5601438c").into(), - hex!("971102768c0dba73925cfff2053b1cd8fa88f5c21aeba2cf3a78ac853818bb4a85cff714134879e5c7d7c7994cff20a7").into(), - hex!("b00b8d49b1f1fc0e792e257b0c3c33ab554fe231aaa6366f5aac11ff35051ae23cd2a5c6b9eecb3ad00e840c78d6a587").into(), - hex!("a34bf3b6d9659f1a89e40e3b35afe741a670a3a9305278a52d479535f4b5973b23b10ccdfa194cb2937f150beca3535f").into(), - hex!("a84c4fd757d86613a4bfe72cc9d7864c2c236b9463e365441360686e19f7f772ebb6c07a24c680462ffb1f3939c870d9").into(), - hex!("b3c34a2470e32395bd9c8789905166ba77b7b7d27cb504b8647dfb4fa6d65884afb2f120d83afd876b4a00cb104347a5").into(), - hex!("b9d18f57a669686eb8ec08555972e54505b7d487dfea7105afc76333138d5f934b9b5f9a3a7896481782fad5328bdbda").into(), - hex!("a23f65babfef6a2442833441200291028ebf56031d7154a4d7d0fa18acd4b7bd78dc34b85924c3073eb5be7733ac10f5").into(), - hex!("80948f3e12ffccd88605cd4d67abb83014c35d8d1a3254f6c546aa7197f810cdd06eb49b99f424187df218c8e8d7254e").into(), - hex!("b24ac23a86e23a16f4f04ed683ebaa51ccc6d2d038674e36d00a14fb71d46c433373a8a0bb75a0afd3c2f9605dd4867f").into(), - hex!("b002aef96f1702f4e3c92b00aa2976b57b77ed97a4d64619c6db676b286c6e633eca63fb232cec0d533a803660c20147").into(), - hex!("9867492f550c1f12276a201717bb4c420bffe904d55008655f929368b664e0293c1dabe9b5a5a71ad884a12686c1d9de").into(), - hex!("96b702733a7ef38b23e45999a04bacebe414a01bb41792cd9aff566fc23610d02e069c85c6fd4173846a40657a958e78").into(), - hex!("8e588db21f84245d034d7427055996f109133b9b3aa095472b879bd180052657da20a48513c1f625c339be90a64878e8").into(), - hex!("b6821bb1a130460ed1936d34cc189980d8fae8c5debc5149d47e90aad69ed3b143a3a00de5959e21ada73a06b3e8c9d1").into(), - hex!("a751ae06c6d699b5593f5928910e1ef3634dedd460ccd3f23d74f5f61a3950392aa66149ae366c048c6c7ece968c2d9c").into(), - hex!("86835cbe686b81fe7e096af5ac8c24f7cfffe2ce2b993626a606e42f6356c0d7c3d4ea19d110aa1a7b7f7ec5e68808f1").into(), - hex!("93719cea4911ce7e436f7b3ea77b9cfb83a1db903cb38f1de3b04d0a69a0f06bbc4f9acd3b313d46113009a917dd5996").into(), - hex!("b0d240c09c137a742d77edf11a7257030ef8b1a785b810de104fb24b22535cf0d62bc54f544b027d532f16b43a2df7e9").into(), - hex!("9376f46ab931f5c58b1be49c529ace24fade089af1af43b339721321a273169c5bb668250b2c2b0aa16aa522e6675bdd").into(), - hex!("82636e68d0d59d20dafd7486176b62ca2d5dd0275c8fff552fbb974565ef2406ff56cff5c43a5b9e383e0b09737de446").into(), - hex!("8f300fd7f29640aeb759d09735f9ac36d1035248c35ff38a165d2d931058268a055971b4fd4dd9d467960180cd255dba").into(), - hex!("a7d5f4e2b01dccd9cd7cbf566b5ab604efdaf9b682bb4ecae1b7801c2f93425350620e91ec807b0a110971c316e68cc1").into(), - hex!("8952700221cb45e3ab933ec20978d9c9c7b873784299b86d0c2d9998bb6b1d1efc1ee3bcd00c5148b2fd9473838ce067").into(), - hex!("b787e77d194e4dfb89968f4e289e97195c2674adba0a3e7d5582cefacdedf93a0e5f27d9d144aab68aaba878fd640414").into(), - hex!("8466c67bed3fbc30e46639de92c422f06bc80df658340a47299ad7798cae412c976fa6ae6bc0a32ce655b93b08cbeaf5").into(), - hex!("ab5d78cf76e16fcfc0491886fc1c95a492ccc67fd31060eb183b89bf59ed6e2d349324f9734c504e74c360272a22f369").into(), - hex!("a4f9f8539f9f89dc5a2c8296af591277c2d308275234729dee23e35e3d541919d1aa9a260780899615e2a895ad8fe703").into(), - hex!("94ed2cf23c5d28497b506515597ab71120f4ca42f7ebc5a4e87b798353eb70590923eaaf163bc550bf312bd6bb2c0b05").into(), - hex!("a78f064aa69402af33f1c9c1bcf04634384ad8528aaf8d28ce1d1a04804bdf93a8b49baddd6870eedf642e566d091af7").into(), - hex!("86796909d2dd3010e8d46c3d99a3c0efcbd4e986e581ef5be4c7810ed8b92268bbdac1dbf1b24d6805df6642f53f0b58").into(), - hex!("a6b555b50ec3b60e9768f407b84c5fd8a055150c17f78f2d5a3b0daa13f2c692e5041184bfc8919280c230c57adc9ddd").into(), - hex!("b4f9b0a0242ded4dc0a4903f16d270f21f2e15668b3abd45f79e1b465bf50074d232f905c6de6f2727a0a9ef039f7681").into(), - hex!("930b7dd8666a35358c6a0a42c600dbe8ad5d9682dfc641474fbd8fba90ddaac7d3ed5f5395f297dd571051ac2d603333").into(), - hex!("abba3bdcee368688a8e53d56627b915148fcab59717174fe8136c85bc24e8d15046da09b31c0c7c9a5bac1016bbfafb5").into(), - hex!("ac199e71110e15ebfb3e58b8ac14f1de8ebd3e0894f273f84783ef3fa4fd16ce6bfa5d41421e884e258fe8e2dce68075").into(), - hex!("a53eaed94fe550c07375ff5ed9706d69563bdba724a4022cf7c639737c97683f036400dcb87268184a9877eb116bd479").into(), - hex!("86e8269c1b368228438de5aa4065ab9d2888de7599b00d5382ebba8fb0600cf357de27e20edaa50127e213c7f6be1f6f").into(), - hex!("8f8d9b9b03b178d370a9e918dd54264f83c4ed20824be79427cbc973a9acf3d74637e5c35080192bb67e64390299c19a").into(), - hex!("a230cbc17aa669c2a9b02e736d20519d93a6fa1b6ed452e065fa78a0fb4b3a0f55fcbc5e719db6417353ef0798f70b43").into(), - hex!("b4e28c30e57cd33fdeb257cee66389365f4a1b9847f94e8b0552c65adff5719e51d50ec8bba36a71ec24641ce4fc6338").into(), - hex!("91799f066e16f9a07a419d3e425c959052f8ad1aee0e2f613d3b023829fb1946c81b16e8b733ed03ca924d03481bafcb").into(), - hex!("8ad935420f026b166233ad387c58857eafdd2fcd4efe55ce1bce9ffd668b8997555927fcec88b04de795129a10263d1e").into(), - hex!("a098f20bf1ae2510f1955c586c7115a29c64bd22a086a2f2a7ff5e08349bf24086504a1e5e1fa82b3aa73a097bcd948f").into(), - hex!("909a3d2e7bb5538bd89c446aa53f1f05a1ec17c88d793a310866cdda6e5d836d53fbb80afbf8baa8aa49db3836c912e8").into(), - hex!("89e64879667f34f1127cfacbd9a3337fa28c0227bac5c5ac907d6ad9c3a853472f4f7cf093e3b735968229398bc7c94b").into(), - hex!("b6ea32c4d640f9b7de841575a00003c1b25d0a845eb54b065129c271790bf602cc39761316c4e9dfc1644ae3ff4b05e1").into(), - hex!("80ef23a1cf6f50f96d5b4645bc79ed4c958f1394da9e5cda0cdaca3815ac8435a8d3a690ed19665b7cd1bef8bf7b0366").into(), - hex!("8b7346d1f30de7e50e3d3b32b441ba5681335d25ae6025623e1469466addc5515415a29ecfed987e07bd6a85ec1eabbc").into(), - hex!("99277ae52f7f2f193549739a704aa2f756c2ddff68b9848040ccacc675fa12d62c9fc1318daecba514089537a4e7b83a").into(), - hex!("94d392e29a3a1b8ce63c52288fdcd3f95f80bdd2a600626e2ce3517162e69b9c0eb36bae6786701ba12e23a33b8f90b4").into(), - hex!("8f270be40047911a4cd5997668bd6d62c90780882451c544ea4bdebe061a9e61bafa1d8bb8af62e0ce4fd73611a7f34d").into(), - hex!("a841f7229fd0490a853523edbd12a5dc6772bd607afd0516c582a813a10fd74d19f480d02b3e7b7b6256896620905976").into(), - hex!("aaf65a2e4e6a3d903ccb51a063d64688590a3ae54c7df3c5e8820d88533a6f10b81b130ab476c9f16c660a81f66dd3bf").into(), - hex!("b3683ebb70696339844ccac03925ec85c8dc06959608527a1744c23a67a805e71b5a91610fc6fbe0f667d054b4087e37").into(), - hex!("b042a5614245184e5a4620cd3a67c51811fcc0a0dff63ac06dc8030f01d8343ff0bd39ab3cdc3c09e4f3c1503ed35e62").into(), - hex!("8a343ff96dfae2c2e62558db3cc424b3c055e2cf84b53f63bf49c95d98ad0b372517df7afdb189007b7db725a3fbd567").into(), - hex!("a3a81a2b37160a371ceee3d07194a70e58041a3e6f75f47c4d8e2c619cae3f44b2de5703e3b80fbae9778e284927170a").into(), - hex!("b9554f94b7c611c2b3f63df5ac0f920d1eaff7b424bc8e857b94c354aa1d3c02a4348510099750e0af3e16dcd0f9a245").into(), - hex!("8678aae32f5bfb9dc249a39eb5d0638bd45d48d2b5b7be32b5e1c2be7b8d29d7198a15e2c24fa7813f060309f2493843").into(), - hex!("85f020a228f8952986c979028dbf2c2e8e59191970ea5e4cff6e6bb46251138d9edd90a211ccd53fd395db8addfb6d71").into(), - hex!("8b0801e8ea30467063d68caa5d3315809b3f21c7429f256fc2a10f7e173f0e1d1bbcf59e025b9e44238a53ef1b8318d9").into(), - hex!("a4d3fbad305853d8057c09bb10fdea9234ff90d51ad0c21342248895d77ead5a8c104c554e6008677e396b55d4efdea5").into(), - hex!("a7f12f870c5a3e2332f10cc2db7dc26ce58a94ff60ebc28f3ae06e820e6514d80c5133563225011213e53f51f748413e").into(), - hex!("a94ed25fba32b4302fff40e2c55e06b6fa4b9820635beb0b43df61010ab5cdaf944199bc73c4827214ae1f57bd75e70a").into(), - hex!("8607e973bc67d217ea67104eb538fcaabdcefcaa7da981ae0322916f7a74229b47f18820458823e7ef160f69f5363dbe").into(), - hex!("a83206fcc995ca57583c5952bef2027503308472bd712c536050217a391bf0fa9617d956ff6c913c2566cbc515cb291a").into(), - hex!("b9110bd697c294a0905503490d17d5536ac1782514bcbdd6f67e8fbb75c0922b39cb7f742d28cbf5356e4f1885b060c2").into(), - hex!("96e1d2b723a458f6b8cd4a8b2a83f33fc7931901cac1fe2169ffbf7c1ac8b4d8547165af3dc61c2b37ab88d3e81f940b").into(), - hex!("92cddef13af28962b7e281d5c0552ee5135b7a401944c9ab31d617b072cf00365e24dd87f86f6618b202d51c25f63fd6").into(), - hex!("a751e27a646ac1f3c828cb88585aeae6899d0940252973329b0589b05714bdc1cd271bf745d482f670f4ccbcd9a60d98").into(), - hex!("861fc00a2edf468353c6012a89ab7cddeaf964ee387e5eac48037eddc536df3d097c69a689f09bdad189384719d50e0e").into(), - hex!("a7dda298ac153aaa6a59785ed7b6900362b1220588a29b44764cc45834859bba0f5b9f8f17bba97fb49fa2c7ed4eb65f").into(), - hex!("a6b679d47e1ea1469e5dc14e1eba97ba2a0f2cec0a9a0983ca086f917298c93af45de60765aa2cb3759ed62c9eb5e4dc").into(), - hex!("b95b1f4472f8f69ee010d36db46c268c59cbd13864c63ce9e6a4755ad00c2db04c951e312b88060e8411018cf655e76a").into(), - hex!("935883b9eca730ef868329a67fe99ed5363b0384e7e6f97147d4c80a76d9b2d8ae6783e80d103149a8a3fbfd51f9f6be").into(), - hex!("ace980d1e3c76dcf78bbb87f3ca9bd0bba7897fcf9e24b27e00fa22855b1b4ac224137361ef6817c94fcc81fc3d3a3de").into(), - hex!("a614b6f113d74d4dd6dea66125b11195212031fd7d3da825b24739e5107cae653fb89c34527b399c43340064a9744a6e").into(), - hex!("83c27783856f9af7491ec9fd34be730600afa59484cae9d3981685cadb869dbd05555a07b93db7d0f361c9ae8e0bfe73").into(), - hex!("850f1389e21bec1c8785d17316a09af9355d32b75d02d9ad72791cfc5a411595a367ba9eb641c5b7acd6be1ee21579ea").into(), - hex!("b810405c7415c49bce0f7893aecde90da33b71684668877c5d6cdbe82161f9cd7eaa2d68597140e39fff8b9cd67424e5").into(), - hex!("a5923930d34526d70e083f4633de4766f04df901ca3adba4a462d03423b609d9813b78a2fcaa2d770a5abc27c260c39e").into(), - hex!("a6ec439bff50a4bef8d0cd47c52e92cf00846ca3fe97cf88e5b6d7800ea22d0ebcac49d9ecd123d4c156642f8bb4389f").into(), - hex!("97b7d3fbd11886976291a24e9e7d6f4974345e06024121eaf57097057c103b6f548d1f523416cd6b465e8109aa0be911").into(), - hex!("b45f04e0d4c17df2815a6fea2b04fd7cc2cbb8e6789084e224db3c1d00db1c6f1d325a63df25ee4a9a992553dab420b2").into(), - hex!("a91dc563b48b4cc210119ff55bec2957e8be50aa25928147d0434a9ea4088e98ba1f17c2050e713d2891a3c741ea6c6c").into(), - hex!("a12256c39f3b17c0540d2d3442b732b2485ae9da240a1ef47782549dc7e84f7a9c9240ff59a73fad228a3c01fe953169").into(), - hex!("aebc98b50533d844fe3149735750c10eab861e765aa7820e3d54fb66089ce15409206bb58d3aae5ef22a29ac5207c702").into(), - hex!("b023d0e4fc2eba4c60cedae9d2ffa79cdcd5c79279fa41baa94f536c17d746a6aa76e8fe203fb1678da126c4343eed8b").into(), - hex!("a673262367bde5d1775961c7d9aa26d9859c59600536130f9adc8f99f81f0106d2eab2c5ac3912476affcab3821fecdd").into(), - hex!("8008298954370c0c3026fd71fb48fc619caa394c9ea17273284a903b07de1d385336fad69c8ab6fe6692774d5fabcfc1").into(), - hex!("a98a824454bc0fba41a6543ba11ec6879c979e97c87e3f7f3a228ba995e33bcae9378740f925800b81d3627f2af36c51").into(), - hex!("a29c667540db41eb7ce06d74ad91c7ddeb3e1f019a028b8ed4ee705d8d079d6f7d36f1b64fd4b9b807f0dc1ab3d65d2d").into(), - hex!("86c32be8a7155f26696c1e541096ab43b3836315490a4bdad867b973ebfa8ac414e4074819b9639348a048bd6fc4bdee").into(), - hex!("a0de748319bb0c53c03f172c9aebc4f7538dfce6ffdd362d24ffdd111448277a8a705832e94f65c61aa635a5f40b6f0b").into(), - hex!("970de7621ef90cb3921f747ce1cf9d389f322cebc286c339395714a6d40167fe26e04e1fc3116d3b7bea1c99bfedf0fb").into(), - hex!("841ae6b0bdd22718fd917ca4a871d39cf6811b9a460b99422fb324235b2c51b460e48159d7e1bc1778de3513b7ab1f29").into(), - hex!("86764a78587892407b311892c4c4e70890bd757d3f72a832257f411646e9298eb4f042ec1c929cc6ffcf539dda90fe7e").into(), - hex!("b33008c5025d35243e91b6749e7d7934bd8334e5f58e88db907715435a28f02d018b09127fb0302d1ee68d7f97391040").into(), - hex!("b5ea29ebc8107525894d9872ac88b4c9662fd18d87316565a8b013529b478f17f6c1c0ddf6482db6ede54d27c0e80782").into(), - hex!("9576def9e5dd8673d3dec2090536672d44368b78b2c2f70dd9e36a9d0e5889cd9e2a47b77ebda94388ac75679257b829").into(), - hex!("823dd44b4635bf095786e47f836c4af02d4dea848bc1cd823876266341d56496e09bec8612413c302fb34c3383a55e0e").into(), - hex!("b6a32b13f8b1339b0591b9db343696aab77a0c2ff181d2069ff39581da8904499d619c26e6e44209b7791c3aa2fb7aa2").into(), - hex!("b9b3262a97049e236e29afc4a7c6d2e2253f437e013b90bd0882d35d46d7a67e1344b3dc822fcae27717a9887d842a81").into(), - hex!("8a94e08cda133175049eb2cddae936b16c477db54a749b8d3378233034f56fdea99520755ec8eb355b738af61138d9a2").into(), - hex!("a55933f63c4cce4d99d8df4fe6dc9d9a3054379ed2560bb2a9147f9e456925ab29f7b1f14321ab2501d67dd759f5ef36").into(), - hex!("8b5a713fb50a2aa0671f1405876b0a829a5c1f7c9915906bcad26de7e2011f8eb2e2b7a1cbf94c19685edf8b364f242d").into(), - hex!("97cd2419d4aaabe457b1efa6d2e557a0c4d8725e57e33018626fb31395ed78555b79cf90da49975360a497049004b20c").into(), - hex!("90d640d0c949a73543b476e0b634d442c0bbe0f4d3f1f4f99d19fd8d37d3b99c4bb3c5c08ee77c24f0af6dc7c29ce658").into(), - hex!("8f65263c9ac0026d9a536360c8b01b40243cc27a7896fada367372ba82ffcf2c758bba9f92c96fdd66956b25d7162903").into(), - hex!("ac50c7c4b3201f2c98e812e83452ded2e2dfbeb4c1910b873978c4b5b443b34dde042b13cb4943759cefe1a546bd8197").into(), - hex!("a07a157ebb964282729ab09205f5a2df132b5a0103233dca67dd55215b84e66423c576c6e0b055bf85c6a27025fe1aba").into(), - hex!("b89462ff76b35af9a1f23bbeb7f3b6e2f72f4d96aaa30fcce820573654895c76d813f27dea9251c96ea9e3f1726da99e").into(), - hex!("a81866a83434f91d464a93a50c4906224f3108777f731a1d363d16f769795be8ffd23c25f0e051d8c43a55b665c15bda").into(), - hex!("a974e15a6315d56d612f5e8d70171b01baba976ae1602265cdb74e1f5cf3a48c94e8b90bf1d343f3f56f8f9ece604ecb").into(), - hex!("97ad199e4ba05c97c5aa90cc6e63ed86f78fbea35b9f56f5107df643efe40647d1ac7e50cf6e1de8b4ede8e2225e090c").into(), - hex!("a67c3822c0e5902355fe053c3c41765146018dd90de0df89c6ae230826056e91cad2a28f06859b8ea899486ddbdbe6fa").into(), - hex!("a5dd8329edde8fdb8f82fb71637c7a4d1e13c51ab2b24cc98b80952575e821fe31c3e7de5a566f8a98e0243cebc6d1d5").into(), - hex!("b7070e8349dbd4359414c0d909de10a472c4a7fc4827804b3e1980b1cd8f468d21d4c6163c234c05f05534e423f6199b").into(), - hex!("a1acc31ccbb89ba6ba5be3ffc26ef83a28c3b0f76be71f87ef618f9f8171c8afdbc5f05c521c67171ea9fde1bad7a9dc").into(), - hex!("a86d620245d119b34f55c6145a65937e5ed5281803675e120d8c2de05eabc08f85eb8d8c877aebf535663518c4fe2f88").into(), - hex!("885317798c5b49430d50d5c5eb527540b0b704794d88d510b2511e9fea2de299d8f2cf2ae2e96196a9c0925ab1f30da1").into(), - hex!("8a5c37ad34f1867fc9fdd3303ffb86fb0d98ce27fd6739078949c070b44081349368302d7c910fd3d886165b5fbd3304").into(), - hex!("a1935e801664a3f51c22e616d25fbecb3f3be76b936e4d2dc28a4bbe79d002ddf01b94cdf9e18d07f2e2c4bccdfd76a9").into(), - hex!("b3d13a611ada38fb6c802e6f7e09d03703e9e7bf82424ded2774d6493dc0c7d8965e7839ff4d3f9fe00a1e8fb20bf13c").into(), - hex!("84f6edb320cf92e147ba3ba8b2470c57dd107b80ea8083219d3c91b77fba7b20b6774ae7ace26924c02c9a2247842bcc").into(), - hex!("86546f16627c3b875790b604aeb19c925f6d32db27c2ebf405df0324095fab1f8b748fd94b6c2b5a2dfeaf748a565b3f").into(), - hex!("b95563cebc351d8237e5f9b8ab984976e84ebf7e16c62102629cbda06c86b013c6a973d007d72a870883408b8343fd1f").into(), - hex!("8d5eff4d3238446be0f805b8f387fd57f298dfcadba88a0d87234bbede46d0ef833beb0f2ede7a51fa84a808393757b4").into(), - hex!("862179dd50e7a0fa7906248c0f3671d8d3b25504e30276da74a36edfebc8c92a04abc9dc3cba8c1b34005beb06cceca3").into(), - hex!("b12bf5775e3f9ae29da6b127ffe2892d5dec12f9c1bc21426c225220cb0d5fca5c6376afb5bf5f112f79c6563694007d").into(), - hex!("957cd40aa0864b86bc64420a184988be4489c0f0a3363f39571e71a7443ac6815a1b8ce4862c736be8441108dd78101b").into(), - hex!("8f31cdb655b66e1f8ad877639f71524aa78c09acc24aa493bd6f6be383c295f51a6e70f2573081cf87cd41ef55f5428d").into(), - hex!("a8f304c1f2faa78683d409dbb0c11e26583fdfe845f2557e378c56acc9baaa88cce25442733edcdd0da70f3e5557e53b").into(), - ], - aggregate_pubkey: hex!("870e9dfe2c909b7116a9a4180da4fb6ac4865f9304adc4c36dde6f82338c43352b58dfb494e6095bfade1dbf86e7f939").into(), - }, - next_sync_committee_branch: vec![ - hex!("d138fae7ec85d4d5ebd8d7375b3f39f4bf0d05439e6920a44bcc977e62ee0dfa").into(), - hex!("a6baa91932e6f9d9fec678e9fd75a140c8e74bd87f11d37093839826b95ceeec").into(), - hex!("926c0348ccc4c44119ca84e50911ac22078ab704b0784ebc593155da5c5adb53").into(), - hex!("c4a04575645ebf0cf5b3317a092e595adf49dd93669424c2a5efef700ed082a1").into(), - hex!("81a062566009887529ffc6350f713cd2aa30460c13173fe9ffcdbde71fd69f8b").into(), - ], - }), - finalized_header: BeaconHeader{ - slot: 5808479, - proposer_index: 218610, - parent_root: hex!("ac0c3b35e7e21d11d0563f98fb16bbfb0460aef2ee5fe39ea209aed66694601e").into(), - state_root: hex!("c66e3a4f1718ce82f35c898e8df8080c540aca493a535a2f6170a13b550faef3").into(), - body_root: hex!("207806f82ac8c5bdb6793dc61f31ce91dd06a7fe3a143d29b6579975c64d1d9c").into(), - }, - finality_branch: vec![ - hex!("0bc5020000000000000000000000000000000000000000000000000000000000").into(), - hex!("8c04962a994aadff4d3042da73e167e666323757db5b0234a497c7ddba058ded").into(), - hex!("95901d6dae3edaab0f29f2c6155edbc4eb3980b6816339a464fb51b91fafdb7a").into(), - hex!("926c0348ccc4c44119ca84e50911ac22078ab704b0784ebc593155da5c5adb53").into(), - hex!("c4a04575645ebf0cf5b3317a092e595adf49dd93669424c2a5efef700ed082a1").into(), - hex!("81a062566009887529ffc6350f713cd2aa30460c13173fe9ffcdbde71fd69f8b").into(), - ], - block_roots_root: hex!("93a5736680a9dfe23df1f8a6098c0671c583dae469847e25da3532b3649ae11b").into(), - block_roots_branch: vec![ - hex!("31a647639bd26edd8e3976b4475933d18d7d238210881f57570b7b4030133da0").into(), - hex!("0a3392c5febec2f099f93c5465c68f4f1630927d0326ad84c8d0b318364dcd82").into(), - hex!("986071ec073d43597d67a6595f7f6fc807ef1042c6821fda41ff80aa2717536f").into(), - hex!("732f545955de627e65c46201f053569dceab609948147690136bc64e060f38b4").into(), - hex!("2e7c74db495877af1e95da27113e89757ea475e8d672d319e655810ec64d4ba2").into(), - ], - }) -} - -pub fn make_finalized_header_update() -> Box { - Box::new(Update { - attested_header: BeaconHeader { - slot: 5809441, - proposer_index: 169069, - parent_root: hex!("a4d2fbf3ee62f32589738f386559a1e2358f4f54aff5f7eaea61144d3d9c00d1").into(), - state_root: hex!("4aad4183bc21fc96c90f8e043049f8c1d5ed205c6880c89cd99f2e080ef85138").into(), - body_root: hex!("406c96c6adad01df901df3625cbd622f1d541249b05c768ccc4db5643d973141").into(), - }, - sync_aggregate: SyncAggregate{ - sync_committee_bits: hex!("7fabbff6fcdefbebaefffff9e37dfffebff57f7bf3e3efbcfef1f7f987551dd176f3b3ff7bfa3fedff5fdf7f7afff5ff777bef5f9f7fe65f97fffe7dfdfffbdd"), - sync_committee_signature: hex!("84dc756c452ec9a3ba01cc98d03cf5471b871e9f3f77ddfe72ddf6d5d318ec3de9e5c1508e47ed362300cd45a144655a076d50073c24a67591b0454d2a4632bc01e97eab80f937a8288131a31ab76f400ba9c26a19df176c7e67b724f70407c3").into(), - }, - signature_slot: 5809445, - next_sync_committee_update: None, - finalized_header: BeaconHeader { - slot: 5809375, - proposer_index: 170923, - parent_root: hex!("87fed31787712fa6e802b9f296c1eb0b0ac5bc77f6945d4478c4d25bd7160d1a").into(), - state_root: hex!("246ac89e1854bada03be1da64081954e008238de219088609ddf45efc8000346").into(), - body_root: hex!("ffe0fdbdc2bf57bebdd084fce3820a13801095d236a2fb8f3a64c9d7cf94f8b9").into(), - }, - finality_branch: vec![ - hex!("27c5020000000000000000000000000000000000000000000000000000000000").into(), - hex!("8c04962a994aadff4d3042da73e167e666323757db5b0234a497c7ddba058ded").into(), - hex!("95901d6dae3edaab0f29f2c6155edbc4eb3980b6816339a464fb51b91fafdb7a").into(), - hex!("34e68ed57efdf18c5d2f455e77fa8b2a5be95bb827bdf7f7f6648103688d84b7").into(), - hex!("fc1d45f882aa66020a92c55da663ab9758581a020eb7336173fe84ef861bbdf9").into(), - hex!("7d1745c42ec44d4b2493a55dafdb770f6d38eb4a7ad68ae0264949cb7432e4a7").into(), - ], - block_roots_root: hex!("9e5aeee5467301f3a44d1ab664cebd198519423e73e2118ad046d9bae217f497").into(), - block_roots_branch: vec![ - hex!("ef671e41918c36e23a3673407050b420366022886dcce1b707622de97a695121").into(), - hex!("707cb79caeaf310c10ce1c177312e48b2331164c8327d2635203148c4d974f09").into(), - hex!("1fd802c27384482fdaacfa7406072f6f96ff5428f003af748068d1965cc36981").into(), - hex!("8a31cc13bddabda4f79d948e5e3d70806f638b61d89c87b40aa7131af43c18a8").into(), - hex!("70eb43218a3a6f619f1d0dc7f173fc9c3323fa7e3824ae6cd79af2f7d19634ad").into(), - ] - }) -} - -pub fn make_execution_header_update() -> Box { - Box::new(ExecutionHeaderUpdate { - header: BeaconHeader { - slot: 5809374, - proposer_index: 130336, - parent_root: hex!("2bb54c61560a80d1cfb0528e8ea207dfb9d55ab49238523e21609a9ee3b8a9b5").into(), - state_root: hex!("0116ea76f5c36373dfc8e039811eba86c8e8e16cfe9f0614376559b6585741a7").into(), - body_root: hex!("9a10b47e30bc11fc2ee1e21943a8382d727444f646f09664192236458b555ffe").into(), - }, - ancestry_proof: Some(AncestryProof { - header_branch: vec![ - hex!("eca009f3262f75b055e6c919e2c0a2c017f017e581a825a2618a2a76926a264e").into(), - hex!("a647371a5590630186dd47b9b8571f27e39a77b4aac1f763fabefe104bf94985").into(), - hex!("9a414690540e4c87ff5171b619b3ab6ff1115c21f247196989f5a0a9085b59a1").into(), - hex!("1bf7ae16fcde0833c6e97a83b72aef31a0b5ca055b87f86602b9b4aa193f557c").into(), - hex!("588d993d05b59bf3352f0f5ebb4cd3ec97ca3e41800da675996741e8fca374c0").into(), - hex!("fdfc6280944bb0a18c9cd0afa9f4a255719a4650233f19de478399276f198c92").into(), - hex!("1d96235b47c604f029b9ab7eb913b13b3c0c2df7f79e3301341b1ec38ea44e4c").into(), - hex!("3ee3af17ce8f5a4946d30b6bce7d6e7580b3981cd2af92246401e2326224f6d1").into(), - hex!("b53b5450e070adf02f4bb9d7c65dd131d07ae2218340eec95ac8aa5e5cdd82aa").into(), - hex!("4d7c09715a1f25574afa1dc3dd7bb44e4c1a723b9360c893b8510f675f85227a").into(), - hex!("38c159fc38dedc1e4f399a3f773ab4376fc40b126634b40d172d5daa6602cf94").into(), - hex!("9faac6fa44ed19fcf530f77b7090dd50dd17aeedabe763931ab7567276025a75").into(), - hex!("c6549c1b0f0027ac373164437e7010b955fbae1a0e78485408ec33ca906beb2d").into(), - ], - finalized_block_root: hex!("f6e721e4e65d9565091a557705285ec6db0a3a3072317317719ec8ad563859a3").into(), - }), - execution_header: ExecutionPayloadHeader { - parent_hash: hex!("6d51d7c94763813ffefa234097a51c6fd7009424d2991695f7bd6203157c86f9").into(), - fee_recipient: hex!("000095e79eac4d76aab57cb2c1f091d553b36ca0").into(), - state_root: hex!("fe9f753520a7b5c0263bbf4fdba728f69e9cf861ce1883aa13de5da30ff75d74").into(), - receipts_root: hex!("cf6ab47d8fc336155b18abfa2d965aae57d9d35a2fcf5cfc992b8dcd136958cb").into(), - logs_bloom: hex!("8427414fce71480d7e70cdbac68dd6f77608c05cf349c34c87ad3256e8dde9e3f9c52131945876c03b6e83ea5970536428283a180eb40efcc5fd834ce424f0dbf622dbba6cfda7945cc1f93a1b6e7ae448c598b4f45f7cfa933fe9808d835cb86e8a38261a031448e262f8e4f2dc4c3254c460e5faae4b518438c1330012154a1ba33ab7d85c8acaa9c47dc582fd003a771c9b09aa16c34d4f0c01fbb3f8c0a28e11d2eafb4e73b75a18e182eac7c021706832a9a785836d31f651efacf88a329334e5b3def3bf1871573dc3553f415f298a9457f7837a31302937a4178be1339cdbb83af329ae7e88d8ab6cba62f018be139896ecbc7ac11ef24b0b4ae343e9").into(), - prev_randao: hex!("5a76eff974d26bf74dc3003fac473ab4abc541be26bd61f124a1818a70ea0b3e").into(), - block_number: 9143323, - gas_limit: 30000000, - gas_used: 28165724, - timestamp: 1686220488, - extra_data: hex!("").into(), - base_fee_per_gas: U256::from(2267_u64), - block_hash: hex!("e4a67cdb1512f29ad9b331e7a37cf8e376222eafa58e72cee7771ad582cc0610").into(), - transactions_root: hex!("bd7eaeb676c14c37bbf0b6f3db2ce021a04a41dbf002f6c7df3bb61639ac7287").into(), - withdrawals_root: hex!("8647d3ecaaf62e1d087c5ab54a23f1d64f477b7ddd16fff458847181d89fc432").into(), - }, - execution_branch: vec![ - hex!("795608ac1294bcc663127b8428513ba4a5ffe952ff72f8322dca23628f13d716").into(), - hex!("336488033fe5f3ef4ccc12af07b9370b92e553e35ecb4a337a1b1c0e4afe1e0e").into(), - hex!("db56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71").into(), - hex!("2a8f5c65655edeb2800f248f2e14044fc651061d0c00c8e8b627cb21ba421fb4").into(), - ], - }) -} diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/fixtures_mainnet.rs b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/fixtures_mainnet.rs new file mode 100644 index 00000000000..4b88d887091 --- /dev/null +++ b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/fixtures_mainnet.rs @@ -0,0 +1,1215 @@ +// Generated, do not edit! +// See README.md for instructions to generate +use crate::{CheckpointUpdate, ExecutionHeaderUpdate, Update}; +use hex_literal::hex; +use primitives::{ + updates::AncestryProof, BeaconHeader, ExecutionPayloadHeader, NextSyncCommitteeUpdate, + SyncAggregate, SyncCommittee, +}; +use sp_core::U256; +use sp_std::{boxed::Box, vec}; + +pub fn make_checkpoint() -> Box { + Box::new(CheckpointUpdate { + header: BeaconHeader { + slot: 4058624, + proposer_index: 631, + parent_root: hex!("4abadda13b61df8d40fcb061d1ec15d0fb7bc5144252bb54c57b41893b642bf3").into(), + state_root: hex!("6fe9fa01a04dcdeaa64eba04a72fa6dbadc8596dc5ec1fff2ef343520fe722e1").into(), + body_root: hex!("6cd83df0ee7669e06e64496a1d2be083bc3bb9f2da17e9b1e62979d200328106").into(), + }, + current_sync_committee: SyncCommittee { + pubkeys: [ + hex!("a13bf1fc1826b61cceefcc941c5a4865cefdfa6c91e5223308fa6a0aa6e7b13a0499a63edf5d9fff48fdeae83e38dcbf").into(), + hex!("b3285148b91dab139b053442bdd14d627ba1e1250fe469f0f2df854b6e6ff4a18671ae3879ec9f7d8091f99f092162e9").into(), + hex!("b00d95908e72c6051478a422eb2231b5f797c2fa5c696ed1e6b9c9996ba1d8236f512443f18c01ce63312c38fa383fd4").into(), + hex!("a866633b4293e726accf6e97ac90c1898cac83e8531a25b50ae99f0ecb477a692e6a5f2488447ccd83ed869ab5abc406").into(), + hex!("a308ed8737b3a9346ff20dc9f112efccc193472e6fde6aa218ceae11e288bbd2c35fa45c1d8bb238696a96767cd68b46").into(), + hex!("81534e2a182da0c6831479c7e722953d267ba9c63a204ac96a178b1dc90d0a6ba8737002688ba5f102eda5669249f114").into(), + hex!("87c5670e16a84e27529677881dbedc5c1d6ebb4e4ff58c13ece43d21d5b42dc89470f41059bfa6ebcf18167f97ddacaa").into(), + hex!("b37334c41a3456b73b61d0eb0777260af9c2e400bbec0e0c0fdb45c39ce0dd19f021d9760f35da801f20486c6be30e9e").into(), + hex!("ab73a043ccdfe63437a339e6ee96ef1241264e04dd4d917f6d6bc99396006de54e1e156d38596ba3d15cb1aaa329f8f5").into(), + hex!("8983fdebbeba6e3cc3ee1c9feb24faaeee712356975e359b0ddca3f7c9c7448132d665f54a4629002252d3fcf375f7b0").into(), + hex!("a03c1e287ccc4d457f5e71e9dc769294835945561e6f236ac7de210d2e614eee8a85e21dfb46e2143c68de22ccee8660").into(), + hex!("8e6b888197010ebadd216da35b9716daa8675d93b3c33a96a19fd9ca42624f6b430b2ff115cd0f5b717341605dda24bf").into(), + hex!("8fb51e3ef3c1047ae7c527dc24dc8824b2655faff2c4c78da1fcedde48b531d19abaf517363bf30605a87336b8642073").into(), + hex!("893272a63650b08e5b8f9b3f17f8547b456192ad649c168bafd7166b4c08c5adf795c508b88fd2425f7be8334592afb2").into(), + hex!("a90c42266ca0a65976fb4dc18465b0a44a63ed3b2747cae74e46e3ccf158f98384e2e86c852e7c5556b083b3ded9d243").into(), + hex!("b67c621d9b6313a9f6744dfcdd77d4e9cb4bd413fb5e3199cdcd7f675fc39f1ba492860749bfddf98f4088756e844a98").into(), + hex!("a9760afaa51002be0948acf7aebd90ec4e60e0dba8456e445aea93408a0468b62bb6da4984b92f8f6061561c9d56f4c4").into(), + hex!("981b2d7c56ff38f1d02c5d7a7f8bfe71daaf94d48c3bc93e8083a0a23c1ae1ff05f90312deb09b35d4513c1ffa573d86").into(), + hex!("9515dedf061e654d58a43e4e525a63ad2a6274ea6f20b1d624a6ba7d3062ed68a0226eee6951ab8464906c52ba5556b0").into(), + hex!("901f724ee1891ca876e5551bd8f4ad4da422576c618465f63d65700c2dd7953496d83abe148c6a4875a46a5a36c218cf").into(), + hex!("a8d152e5d94b75cb9e249230db21af31de4d4f3d4ef60ccbf2212babf69aed2a38435a993ee2f13cca410ad55a4875ab").into(), + hex!("875ebfe737cea438e967d70ceaffb4360cce28ecc76c8c4ee612c47fb6b3e89af03c66981571066107323f49a6242772").into(), + hex!("a798a0371e8cc4dc42ccd79934b0db5a3a59f18a0ae09f2eb172596428fcb3f00312e783d6fd21cbc1610317f44e08cb").into(), + hex!("99c629c9cd603a9344b04d22d2bcc06cf45ebf62d97f968df19c73c7a50f4f6a2a2cc7fb633f509f961edfb94fbab94e").into(), + hex!("854410e6fb856da8b997ebf28ae2415ce6e1f9f6a4579fad15b5df61709c924a925397b33fe67c89ffad6143a39d756a").into(), + hex!("a3969926aa2e52f1a48ac53074b764648b4c71bd43430944679628463cd68398f700d874c14503b53756be451c8ba284").into(), + hex!("8ee8873de7cd28a54ba2c63a80b63399effed76b154e96ed26e7c0668b9f2476e298688b6a00c4b2ab9d020a897695d7").into(), + hex!("ad54241ba3de6a4426c788690d3f78d2eb678814edc49d3fb988d7fc752e43512972567bb384bcc1b18d083d15e376da").into(), + hex!("942bee9ee880ac5e2f8ba35518b60890a211974d273b2ae415d34ce842803de7d29a4d26f6ee79c09e910559bdcac6d3").into(), + hex!("96b478b1e5e49d4ea3fd97c4846ae0f781dcc9f9ff61ee022ca92c3d8dfba89c513c46e8bb38b73e6b678a79b9b12177").into(), + hex!("aad9577501d7f3a5dbac329f2c1fe711710869cc825740f365488fc55a278d687bb72423560f7cb2cbd60546a82ea1e6").into(), + hex!("8aa3d9dad1c122b9aed75e3cc94b3a9dab160fa4cad92ebab68a58c0151a5d93f0f6b40b86fba00e63d45bd29a93b982").into(), + hex!("a12fc78b8d3334a3eb7b535cd5e648bb030df645cda4e90272a1fc3b368ee43975051bbecc3275d6b1e4600cc07239b0").into(), + hex!("ab01a7b13c967620d98de736b8ff23d856daa26d5cd8576993ee02a5d694332c0464ed018ebffcd5c71bab5cada850ce").into(), + hex!("96cf5760c79cfc830d1d5bd6df6cfd67596bef24e22eed52cee04c290ad418add74e77965ea5748b7f0fb34ee4f43232").into(), + hex!("9443e6ba4400fb3370c573cd7e33f05e1475f9cf1d6adb905bee3aff8f1452d8d384c8a72c9110070f35c6aad940bba6").into(), + hex!("95c60b5561e53cfc26d620be90f84199ffd6dd9687c1be3a547048e7cba10a0be9bb6da000e7521cbd488d0901d48ee9").into(), + hex!("ab69cf79750436d310dc3c5e96c2b97003f4394f31dfa8a9ac420595dc7b4d96dad5787d93347ba2bc6f196c241a3dbf").into(), + hex!("9145ee1fb6e84114c903819db94fa5a72bcbc15fcb8a7fd8eefba23b156cc46309281dcf78b48a2847b3754f7d7d7a79").into(), + hex!("b118f77f99ac947df97e7682f0fb446175185b842380af4ee7394531e4f93002c72b41a57a7c1b923a4f24b10924c84f").into(), + hex!("a4aabd1890ebf35423565dbff3477a09eea4e35f5a26ed449eab38e0a21fb89e9ddfe3a2003cddc457db648a1b5891a3").into(), + hex!("8ff5d2e6c98b1fea70cb36ea8ed497fd1233b9418948ac58c6c379ed35fb10f8253ef188c909d5e77e81b5b8e2a4ad17").into(), + hex!("a23f076306c120dccf69d7d2ac7f83a377a72d35bf448f88feff8b6dba9307fdabf34452e30b87407b2258b9edfd1174").into(), + hex!("87d2217eb05d657aba7b048cf3c661b463e78e51135a5b937e71975ff5102e596434720f02349c73415decb88418cb0d").into(), + hex!("8bb51b380a8a52d61a94e7b382ff6ce601260fa9b8c5d616764a3df719b382ec43aec9266444a16951e102d8b1fb2f38").into(), + hex!("b0053550040ab3a3996cba5caf9ad5718867b5f5df273ed8c6520761571f03a94e50b5f8a6a8c42d725383cce97d3cae").into(), + hex!("ae50f93230983a82e732903d6ed50a506d678f35b6b4a4b3686a92b12aeb9d34cb095e8562b0900125bbced0359b37de").into(), + hex!("8bfa106ada4914419bf1d8900c5981dd5b90c3023196d7e918d62879fc3a575bd0a25f939366f7fd2240df6108b069ec").into(), + hex!("b3a5497365bd40a81202b8a94a5e28a8a039cc2e639d73de289294cbda2c0e987c1f9468daba09ea4390f8e4e806f3c8").into(), + hex!("b4f583e10aa9af79b4ebd647e0fffe1c720112727e5ffac4313f236737491fceeee194537786c561cd5777b453e5b03c").into(), + hex!("826be957cf66db958028fa95655b54b2337f78fb6ef26bd29e2e3a64b130b90521333f31d132c04779e4b23a6b6cd951").into(), + hex!("aace45334070c51cc8b3579598d4cd8cda2153bba51f56e3b1fe5e135c83ef70503c322756b9cad9d3cd28f1ecfc8227").into(), + hex!("94bb68c8180496472262455fd6ab338697810825fa4e82fc673f3ac2dacfd29ee539ac0bfe97eb39d4ef118db875bab6").into(), + hex!("b560c33950a355119845f63defb355807e56773f636fb836f7746155fad070e384fc1091b8e5c057e4cbc7da9275ecf7").into(), + hex!("820cc2ac3eed5bce7dc72df2aa3214e71690b91445d8bb1634c0488a671e3669028efbe1eae52f7132bde29b16a020b7").into(), + hex!("9244703338879e3ea00663dcde8f11095de3e38df9277d8c2acc26e72021c222ae40bcc91228789fdf0b69acc3144783").into(), + hex!("8d474636a638e7b398566a39b3f939a314f1cf88e64d81db0f556ca60951ec1dca1b93e3906a6654ed9ba06f2c31d4ea").into(), + hex!("889a5cf9315383bf64dfe88e562d772213c256b0eed15ce27c41c3767c048afe06410d7675e5d59a2302993e7dc45d83").into(), + hex!("b544c692b046aad8b6f5c2e3493bc8f638659795f06327fff1e9f4ffc8e9f7abdbf4b7f6fcdfb8fe19654d8fa7d68170").into(), + hex!("aefc682f8784b18d36202a069269be7dba8ab67ae3543838e6d473fbc5713d103abcc8da1729a288503b786baac182d3").into(), + hex!("a0f2092ac34d2363614fb2f57fc7b72db247eb1fa53f395881ce6b4aacd6fb920d6dc59507701d487288102e4c4fa389").into(), + hex!("b33de3de106be61481ccb7f07a7a63cf4d1674010e462388fb8ab5ea08f444ed7a277905207e0b3aa2f00bb9efca984f").into(), + hex!("84173aeaf3d96368dc7ca1ad5e5575da279113567e5815a364a0356a720c5e08cb58ca1fdd891924f4871d3eaae5de40").into(), + hex!("b6d6482ad7b9b412ffbefbbdcc28eb3d091b1291f54f77bdd53c4ac85f705c454940f466dc272dde7b03c26f0cd6ecb3").into(), + hex!("a2053719da2b7501dab42011ae144b3c8d72bd17493181bf3ae79a678068dc3ee2f19d29a60b5a323692c3f684f96392").into(), + hex!("8296f8caf58316af535def398a43357e48cb3b1e674b857eba1bd1b970da3dd045e22fe6d17dee4e9117f62ece3ec31c").into(), + hex!("84faf4d90edaa6cc837e5e04dc67761084ae24e410345f21923327c9cb5494ffa51b504c89bee168c11250edbdcbe194").into(), + hex!("879aea8f09dec92f354e31aa479d00cb77457d363de2d9a51ddf7d734061b6f83d6345cf33dbef22004cd23dd6c4b760").into(), + hex!("b8fca0f7bc276f03c526d42df9f88c19b8dc630ad1299689e2d52cd4717bbe5425479b13bdf6e6337c48832e4cd34bb5").into(), + hex!("b2a01dc47dd98f089f28eee67ba2f789153516b7d3b47127f430f542869ec42dd8fd4dc83cfbe625c5c40a2d2d0633ea").into(), + hex!("a19f2ce14e09ece5972fe5af1c1778b86d2ab6e825eccdb0ac368bb246cfe53433327abfe0c6fa00e0553863d0a8128e").into(), + hex!("95d1f944b0c53eb3e9fcd5632713602bbb9195b87a172a370ae2df98504612a55f3968615a39b569ce6a0fe9fb559be7").into(), + hex!("ae36ab11be96f8c8fcfd75382bb7f4727511596bc08c25814d22f2b894952489d08396b458f7884d6b3c0adb69856a6d").into(), + hex!("824d0dc002e158adef06fc38d79b01553be5a3903566029cf0beddb2248b11da40e66feb168e8e3e2a63ea033a75f382").into(), + hex!("8f9f85ae6377414fcf8297ed45a736210cd3803f54f33116b0f290b853dc61e99ea08f3c422ed9bc6bdc2f42ab4f56ba").into(), + hex!("86c53fc078846c3d9bc47682506f8285ba4551475921fd388b96291741970c34b8de4210202e40d2de4acb6e2892072b").into(), + hex!("853184f246d098139230962e511585368b44d46a115c5f06ccaeef746773951bead595fb6246c69975496bac61b42a4f").into(), + hex!("b91b4260e2884bae9778fe29a2c1e4525e4663ec004159def5d47320de304c96d2a33ad7a670e05acf90cbba3efdd4d9").into(), + hex!("83492e27e07e35c0836aee6bee95d040b8d3e82db6f94a3917d07797800f7200f5dbc6c9596c6c3c70f8f470b65a9b6e").into(), + hex!("b1bb33607d10ea8c954064ecb00c1f02b446355ef73763a122f43b9ea42cd5650b54c5c9d1cfa81d4a421d17a0a451aa").into(), + hex!("99cb1728157a1b7cdd9607cf15911bbcb56b64d52fb0d0117b457853a81ec55913f977850f26e188fa2652579efe9ddf").into(), + hex!("8b7cb5b8de09a6dfceddcbaa498bc65f86297bcf95d107880c08854ed2289441a67721340285cfe1749c62e8ef0f3c58").into(), + hex!("b97447233c8b97a8654749a840f12dab6764209c3a033154e045c76e0c8ed93b89788aac5cd1e24ed4a18c36de3fbf60").into(), + hex!("b4790910e2cbef848448f24f63e9dd4a1b122cf65feecf152d5fde282ad6fcc6ea3f9cc23178baf85612020795e4b13a").into(), + hex!("81fc724846b5781f3736795c32b217458bb29972af36cc4483dd98ab91680d3d9bc18842db2661487d3a85430dc9e326").into(), + hex!("a154892ff23b284040e623bba940a6a1ef1207b8b089fc699cb152b00bcce220464502cfa1dfb5a2f62e6f3960cdf349").into(), + hex!("af3f765fd293c253072b33a780ed68933f78d7e079d9a2079b6232755bedf6ebcbce9ba65c01f695602fa8ee17899867").into(), + hex!("97578474be98726192cb0eac3cb9195a54c7315e9c619d5c44c56b3f98671636c383416f73605d4ea7ca9fbeff8dd699").into(), + hex!("917c4fd52538d34c26ccdd816e54ebea09517712aa74cec68a2e3d759c6a69b5ccb4089ad1e0b988e916b2ce9f5c8918").into(), + hex!("8cf3c29531a17489a5f8232d56c5251ffddc95be3ff7ff61472e19fb38c5eaec841ef3b1ee36756b3dd8ff71ae199982").into(), + hex!("96d4b9b411319e531bab6af55c13f0adb1dd6b4286784ff807f283e7990dc368c16d536fc5db3d992deb4b0278914e6f").into(), + hex!("8903f7e0c9764ce844b15d84feea04406dc66b195a5f82ff4027f27361e11cf368538137d139368f5a6f42876b04f056").into(), + hex!("a4047173b5906c9b4292aaee1e91d9080ae74b1d3eb990449ed1f96bf22c3ee80f4915361e5bf7dccce24ae1618dae77").into(), + hex!("a4c4b96071e7bc92e41defba3507ddf423d93f3a94271b1f9812dfc4660e4c9fd24e0dd7aef324c46deb8d7a7c97eaa4").into(), + hex!("8289b65d6245fde8a768ce48d7c4cc7d861880ff5ff1b110db6b7e1ffbfdc5eadff0b172ba79fd426458811f2b7095eb").into(), + hex!("ab4119eef94133198adb684b81f5e90070d3ca8f578c4c6c3d07de592a9af4e9fa18314db825f4c31cea1e2c7c62ed87").into(), + hex!("a3ffc3dad920d41ec3f4c39743ef571bcabb4430465d9aa811d0f0a7daa12bee4ed256527d16a6e937bf709ebb560ebd").into(), + hex!("8553748da4e0b695967e843277d0f6efeb8ba24b44aa9fa3230f4b731caec6ed5e87d3a2fcd31d8ee206e2e4414d6cf4").into(), + hex!("b15e1b4ac64bafbc4fdfead9aeff126bf102fdd125c1c914f7979680ec1715fbeccf3dc35c77d284421ec1371ed8bc32").into(), + hex!("9377aab082c8ae33b26519d6a8c3f586c7c7fccc96ec29a6f698b67d72d9266ad07378ba90d18e8c86a2ec77ecc7f137").into(), + hex!("b71c11828ecad7731136cb1f5b80392a4add8d62f8866a781fdde797a201ebf6d483b2348aacbea2061a5108933b757d").into(), + hex!("86793899ef71740ab2ec221d0085701f7909251b1cf59a276c8d629492f9ef15fc0b471beedc446a25b777391ab00718").into(), + hex!("8100b48ac2785477a123a7967bfcea8bacef59391680a411692880098a08771ff9786bd3b8dfb034cae00d5a7665621c").into(), + hex!("8b027c14affe47f83ee59b504d83b2fd2d9303de2c03ee59d169bb199d9f4bd6533d7f8c812dd7a6f1e8155e3e185689").into(), + hex!("9615800f8c95f95bf25055ae079b964e0a64fa0176cc98da272662014f57e7cd2745929daf838df0094b9f54be18b415").into(), + hex!("951aa38464912a29df2101c60771d6de7fadb63f2db3f13527f8bdacb66e9e8a97aaac7b81b19e3d1025b54e2c8facff").into(), + hex!("a0e68d24f784fcb2b71acc2d5871285623c829d0e939146b145e04908b904468a67c07a2f156e6b17bf531adc5777c4b").into(), + hex!("86a533b02ae929f67c301649a2d58651b98cdffe731b63fa32aa1013c271634bbb088c0d02865913c11bbb1bf57c0e12").into(), + hex!("81f145ebb9a5674a5b052d0e9059acc8f8ab612dd9f54d43ff620202606e19a86a9b284dc6480d555a030e5fefee8c50").into(), + hex!("a698b04227e8593a6fed6a1f6f6d1eafe186b9e73f87e42e7997f264d97225165c3f76e929a3c562ec93ee2babe953ed").into(), + hex!("b3180ded54610b1b3a2db7db539197ced6a75e9bb381d1f4b802ca7cd450f5418522ad2bee3df1956ed63ff1ffe95dc1").into(), + hex!("86fa3d4b60e8282827115c50b1b49b29a371b52aa9c9b8f83cd5268b535859f86e1a60aade6bf4f52e234777bea30bda").into(), + hex!("97d076617cf0a64ab3d1f030cfd72a303b6b252c0a7b96157ff7fc8af5970f00d14492c46e8f6f37caafe837d0dc95c7").into(), + hex!("ac2c98a0ab3f9d041fc115d9be4a6c77bd2219bb4b851cbee0d9257a4de5791251735b5b8fad09c55d16eb0d97080eff").into(), + hex!("ace7fda25c2fb7c18710603c16a0ff0f963352d1582a42a20c9f5603c66f485df8383465c35c31e8379b4cb2ec15b4c4").into(), + hex!("a07b35ec8d6849e95cbd89645283050882209617a3bb53eae0149d78a60dbf8c1626d7af498e363025896febdba86ee7").into(), + hex!("b2fc4478830f2ae4234569346d80b59899247c609b75bd2190a896498539e1f30dca5edbad69f0224918d09f0d7eb332").into(), + hex!("84926cf2265981e5531d90d8f2da1041cb73bdb1a7e11eb8ab21dbe94fefad5bbd674f6cafbcaa597480567edf0b2029").into(), + hex!("b5f32034d0f66bcbccefe2a177a60f31132d98c0899aa1ffff5ebf807546ff3104103077b1435fa6587bfe3e67ac0266").into(), + hex!("938206740a33d82ffda3e01598216324731335d367965aa0b740486d60ba2e86a4ecd546851046a61a4b0fc88295b5cb").into(), + hex!("ad2b1ab32161e37ee553e3787f05f9281073d7ef7d0ae035daa353bc83da8ef8c76c99ad2928463c7c708f7404020476").into(), + hex!("94f4720c194e7ea4232048b0af18b8a920fde7b82869e2abcc7e14a9906530be1ef61132884bb159df019e66d83a0315").into(), + hex!("a26dd9b28564c3d95679aca03e3432ac26e287f80e870714c5946b05538b3cb43bba7b85c16bceb5430e81b7a04c1b1d").into(), + hex!("8ef0930db046c45ca5c69d565d54681d2b6d249e27092736aee582b29de3aac3fd96e1066a57cadd851b4e5334261594").into(), + hex!("92096ebf98ebac5c82345d3ef0db0f5a14af23ceea73279087426b281d6701997fe131fe65a7df7d624b4ff91d997ae8").into(), + hex!("81c850f419cf426223fc976032883d87daed6d8a505f652e363a10c7387c8946abee55cf9f71a9181b066f1cde353993").into(), + hex!("97070a33393a7c9ce99c51a7811b41d477d57086e7255f7647fd369de9d40baed63ce1ea23ad82b6412e79f364c2d9a3").into(), + hex!("a99cde5c7c85ae291c74c893e598cc0e6eb2dda2a81dbb504a638eb21dd2c41d6e5caf7baa29e3c1c32e94dca0d791f1").into(), + hex!("937ccbf8cd19b82af2755b4856cfcca3d791e33ae37e4881982ea89d3b21d205a9402d754fac63037243e699484d21f6").into(), + hex!("ad7dca7640444f1268f03b67544815d4366c6a4a2f0d25ee78f3361c63095416216fd31aa0bcce7448cdd7ba73a6344e").into(), + hex!("84991ca8ef255610ebc6aff6d66ea413a768e4d3a7764750fd02b5cd4735d41df399b36e87647fc83cf73421a39d09e9").into(), + hex!("91215fc3f7243638733fe293dab7029e0c4275550102acf5f1638773cf8f8ef2c53ffa5bdfc1b602c269a2b5ab164b7a").into(), + hex!("aa6cfb3a25f4d06c3ce1e8fd87496a74a5b951ab72557472a181a2e278c5e982d290dd4facf40bd2f4f8be62263dadb0").into(), + hex!("ac9f29ad08aaf27581fe1f12e210ad4ac6011507fe3100763a4120f9e439f3c6d191f3fb55aadf58bd865cfd4406c68e").into(), + hex!("87c6cb9ca628d4081000bc6c71425b95570291eb32ef2cf62416bd1ce3666eb2ce54accd69f79d506cefbfe6feb5a1da").into(), + hex!("93042dd42e56671155bb40d85d9d56f42caf27bd965c6a7a7948b39089dba8487d4d5fd30522dba6ba392964e3ffd590").into(), + hex!("a76adeddf2454d131c91d5e2e3a464ef5d3c40ee6a2ab95e70ef2e49e0920d24f9b09276250ed7b29851affbdbc7885a").into(), + hex!("92a488068e1b70bf01e6e417f81e1dc3bcec71d51e7eabbc53b6736e8afdb8b67d191940fe09c55783be9210e1cbd73c").into(), + hex!("8180ffffb5abe78c38f2a42a3b7f1a408a6d70d3f698d047d5f1eef3018068256110fcb9fb028c8bdccbc22c0a4c3a20").into(), + hex!("a50ab79cf3f6777a45f28d1b5cdad2c7ea718c60efeeb4c828d6307b29ef319445e6a9f98aa90f351c78b496575150c1").into(), + hex!("a4632399c1a813e41fb2055ef293466098ea7752a9d3722d019aa01620f8c5ecdc5954f176c6c0901a770cbe6990eb11").into(), + hex!("83bf5055d6332009c060fd50b8dc698d42b764b079c90a1fad8a83101f8dd1cc27acb27dc9d1c25ac8d3db4107471b4a").into(), + hex!("8c432e044af778fb5e5e5677dbd29cd52d6574a66b09b0cd6e2a5812e71c91559c3f257587bfc557b4b072a822973a60").into(), + hex!("8368a0f17c8427beb71dbf11a09a2fe8495a33f08c29c74a9a996a88aa01c0a09f9555abeb1ef1592cab99a9e05875cf").into(), + hex!("a8795e7f4c4c5d025ead0077c3aa374daaf9858f1025c0d3024d72f5d6c03355ae6ac7418bf0757fe49c220acff89f7f").into(), + hex!("a6d9f67ca319ea9de50c3fed513269b83fa067977adfd1e9d9ee07ad61b2ac1de64a39d7b6897ab55870cf982fe481dd").into(), + hex!("86b3a4ea9b1fde00cce79d5ae480353d60cb6ddce363c535bbbc3e41a4b8e39fcf2978eb430091ae1b10420d43193971").into(), + hex!("90fb5cac22a22fb8a6b619f1eacd95873be974d4d5d1f7080e523bb9b4b2644eda7340d780bd1ea8ce36407ca0410fea").into(), + hex!("b5036d4c241685bcd67156e4ab0eba42b97f639947d54b17af2c88fbcc5fc57359c7df4bc7f8df955a524fb1501a6fda").into(), + hex!("b1c56f028f31f0ff86bdf55788703b4d809becaf3e4d9d349f1b660a07d2f15e127eb72a0e2a5a2742313785a3de43a5").into(), + hex!("a3e909196f447e492200cc67000c5d7f0f585fb98e966cf9bf08257597fea8d92a90ceb054d4b5553d561330b5d0c89a").into(), + hex!("87cac423d0847ee3547f45ac5babf53bddb154814e291f368cbb62ddd4f2c6f18d77a1c39fddb482befe1a0e77d5b7fd").into(), + hex!("8605b88ce23190b1fa9d389b15e6907417239a72b97673d1479c4ccb8f4515c7921d14537775c74e738a9c3f122b1443").into(), + hex!("87587504e819bc7f0349705a05c15e8504fd6b2c25c3fd264096cdb7aaa22d8078da776215925d9d775a7f9355b6f0c0").into(), + hex!("afba279768f0f928b864645aa4e491e9c949bf3dab57efa24eeaa1a9a7d4d5a53c840019354068e64c65a2f5889b8f3c").into(), + hex!("86b1cdd26ea9a3ae04d31a0b34aa3edc9e8d038437152214d195381173e79e4ccf7f8f0ce9801086724a1c927c20e4c8").into(), + hex!("812d3ded3a3c9e58eecf13a29bb4cc13b01b2a0af322423a29bb0e4f6d9021d1d87ac4af7a2a6b88d34f44a8bc1b3c55").into(), + hex!("a988cfed9f481bc98beb5fc188ed3f6893a3ebba27c3ebace669792f6abf0997727023c3b6930a6421224f5b257b8b49").into(), + hex!("a38c974b57da968f0c4611f5d85d8014fd48594c8cd763ef2f721cfd2c738e828d41ff029e3591d7447e3125641db8ef").into(), + hex!("880b4ef2b278e1b2cccf36a3b5b7fbce94f106ed9fa2820cb9099a7a540a57e9fdeef5c0fb0a743049828fc2b8c46163").into(), + hex!("96e7d1bbd42195360267c2a324b4d9bccad3231ed8a7f070278472a90371867e2ef2c29c9979a1ec6e194893afd992df").into(), + hex!("a92beb343caf6a945990adcf84302c55d1fccdef96c34a21f2c00d3e206a9b2c6c6b412f66e5d4fafe26ef6446cde705").into(), + hex!("aa48afa77d5a81cd967b285c0035e941ca6d783493e1840d7cbc0f2829a114ace9146a8fbe31ecbd8e63e9b3c216a8c5").into(), + hex!("893a2d97ae067202c8401f626ab3938b135110105b719b94b8d54b56e9158665e96d8096effe9b15c5a40c6701b83c41").into(), + hex!("b614910b247c6ade31001b0435686c3026b425b9bff80b6c23df81c55968633349e1408a9a5a9398a7d5d6ed5d9d3835").into(), + hex!("991c660e4d476ad92aa32ef2c5b27669ab84026eeb5ca70af69bbbcd8ebc0a8fec17843423306edc78b4436629d55c25").into(), + hex!("b926a21f555c296603dc9e24e176243199a533914f48994b20abca16f19c30cfd0baf319268139fe3f83ce69afdc324d").into(), + hex!("8e70e4867d2731901d603928d72bbeb34b2e0339a4f5cf06e7a771640717421b4ea039c61dde951582a28c2ff152ff70").into(), + hex!("95aafa379cc6a2b4bdd0cad30b7f0a47839952af41f584219ec201c6c4d54610eb2c04b67b29080acb8cecc5e7543fbc").into(), + hex!("8465bd8be9bd9c2c6116d4ae44ec6618c109cb9aaee2d241e7a6ed906d398ef15a6fc18bc8b1d3398184241405954bba").into(), + hex!("b455f751232de0a48440d09983f4f4718b6169907979c9f282acf7177ab5b1f338fe1f2acd8d0bee4b4aad61d0340839").into(), + hex!("970df2314849c27daa16c6845f95b7be178c034d795b00a5b6757cc2f43c4c8d8c2e4d082bec28d58dd4de0cb5718d61").into(), + hex!("8d52413f981bc611427ad0534d25e914113d0ebcd6960aab6421608bec6648b89ae4b2ca2153c57d3cf4f1f37212aa5c").into(), + hex!("b7ac87da14b783914ab2e914fb7b536893b7a650cdc5baa1f3b4aca9da77b93a3336671335250e6467a8cd4aa8dc61e9").into(), + hex!("b37a2ec9dec3d7d9cbc911fa1e5310a47d23a841d02c8b99a923991c73fc0185d130a494748c64f2b5a4c07bcd06920e").into(), + hex!("86108b661fb2c363adcca84c114c83346413df748b959015c018452cfac14890bf585dc0a646d68727cc3cdfd2b61897").into(), + hex!("8421044f794a1bcb497de6d8705f57faaba7f70632f99982e1c66b7e7403a4fb10d9ef5fb2877b66da72fd556fd6ffb0").into(), + hex!("84d2eb008578aebd6f01254b7e46584c1524e6fd7a5a2ae5fa0ea560865ca50d52290cf2d12dd20b042f402e62181b4d").into(), + hex!("8d6bed5f6b3f47b1428f00c306df550784cd24212ebac7e6384a0b1226ab50129c0341d0a10d990bd59b229869e7665a").into(), + hex!("80e30cabe1b6b4c3454bc8632b9ba068a0bcfd20ce5b6d44c8b1e2e39cbe84792fd96c51cf45cf9855c847dc92ce9437").into(), + hex!("b7e74ab2b379ceb9e660087ee2160dafe1e36926dfab1d321a001a9c5adde6c60cd48c6da146d8adfa2bd33162eeaf1a").into(), + hex!("a2b1ea43f51460b3cb83657b4e296944658945d3ad6ae7b392e60f40829ba1da6a812d89f0380474578cbd0ab09801ac").into(), + hex!("91ead7dacf43905eb5d4b179af29f945479ed074126bad3b5a2bbc1663af5f664fe53a36684e9389ab5819e53f1344fc").into(), + hex!("927c030d5a69f0908c08f95715f7a8d1e33bed5e95fc4cfb17f7743cb0262755b1e6b56d409adcfb7351b2706c964d3b").into(), + hex!("883f38af3b2c1d50f6e7c515a5e02468d76890f6e669f7acd2df89365862fa65877095deb001b4e2868bc5b59439dbb1").into(), + hex!("a0ebae60a998907a19baa396ae5a82bfe6aa22cf71bfca4e1b4df7d297bd9367bbeb2463bda37aa852ad8fd51803e482").into(), + hex!("8ae80eeaed3fc456f8a25c2176bd09f52a2546d45d77a70f48a9e30aa29e35ff561c510ae1f64e476e4a0f330b9fdbdd").into(), + hex!("a7be457b8bc1bfde4865a35b7b1826118edba213b0f0d3cf5d877267cc1559cabe61cefb1e300142a978c29676036179").into(), + hex!("af51da717d2a45ab96fad5d9317ea867ec4c6a411af6fabd72e568230099a04c036a0f114158815b1a75da6474dc892a").into(), + hex!("b549cef11bf7c8bcf4bb11e5cdf5a289fc4bf145826e96a446fb4c729a2c839a4d8d38629cc599eda7efa05f3cf3425b").into(), + hex!("8d264fbfeeebb6c4df37ff02224e75e245e508f53fb3446192cd786ecf10d0f704c4fc2e53e7f7318ae1407e46fc0fb8").into(), + hex!("ac3195143035cdb4ddcd5f93c150035d327addee5503ea2087b1a10b2f73b02453ddd1a94d8e7d883e365f9f0e3c38c9").into(), + hex!("acbb398ea9d782388c834cf7b3d95b9ff80ee2a8d072acae8f9979595910849e657889b994531c949d2601b3ce7b235d").into(), + hex!("811e6a5478f708495addbb1445a2ef23e39ee90287f3a23ecd3d57d4b844e4f85b828bae8fa0f1893dfcc456f86f7889").into(), + hex!("8cde690247d4831dfe312145ae879f4e53cb26641b3a3bb9eb4d590c56c11ece3cfe77180bd809468df5cddaea4f5ab1").into(), + hex!("b42578df29a9eb23bed91db6a1698df49654d2bc1b0d7973b2a7e300e9cf32e0e6ac464d463d4d26e394e7598239c4bf").into(), + hex!("97ffcbf88b668cde86b2839c7f14d19cb7f634a4cf05d977e65f3cd0e8051b2670e521ae74edc572d88201cff225e38a").into(), + hex!("a322b5d2a6e3cb98b8aaa4c068e097188affef5dec2f08c3e9ce29e73687340d4e5a743a8be5f10e138f9cabbe0c7211").into(), + hex!("a076ea1084b7a1a33115ef62d6524f36e7820579868763a6ed1f8bce468f150cbfbf0ed04be2487aaa34100d828b0db6").into(), + hex!("944259a56e3b4f745996289912740281bde47e22705f142c2a483ffd701e780f51a01b177d2494dc8db9e69157f45d44").into(), + hex!("91cb79d52951d1b901e4a686bf4ad587e31db57ea5af6ffeb93eeafae3929879c386ddec860f803c2dc61055437e6bee").into(), + hex!("91efdbcaad9931312d7c41d24de977f94d7f3f7b88090a1f72d9a097a1e30cc805c5ea16180f463022d9b26b8863f958").into(), + hex!("b26f5ed09f7d5bb640ec94ddd1df0b76466f69a943b4699f53d45296d5d6b8010bb61477539bc377d1a673d89074d22f").into(), + hex!("80822499f96a1a8c0048f01f389dfcaaa5d8269c332dbb507fe46f270bcfd5f67c53f827fd867221592dbde77b6b37ab").into(), + hex!("8860ba25d5530cb8585975d8013a1c2d5b0f0f96066044fdc43ed13488ae44e379c624ff6993a18cb6e037809d7985e7").into(), + hex!("999d1c44e14184349064415ae28a149b3b11aba5baab6792744378d14df554a3625fac82038eaca920064822294dd513").into(), + hex!("a62c2e7c692403e874a16e08e46a067e19dd561993ca07ff79cecb53c753763b3e49d372638c96c0a8c921bfa0798a0c").into(), + hex!("a1c84730a5c41dcab9a5ef9e1508a48213dbc69b00c8f814baf3f5e676355fc0b432d58a23ad542b55b527a3909b3af6").into(), + hex!("a1c0c317e6e352e16e25c140820b927161ce5d2c4c2e10bca3057ba4d46b4f42ad7aba20de86dad9fc6368ea92695268").into(), + hex!("85c216e314eb7bd8ba02e092c90e132bc4bafb21c6a0fbe058b0dd4272cb76f183b83c6783fc321786065ff78c95f952").into(), + hex!("8e8f63ec8f4f1f7fcc61f893b671710c3c17f9d2d26c5c6ca40e671bd4b252bc0cc1655e6780d2ddcf2915d8f623b9a4").into(), + hex!("aaeb0005d77e120ef764f1764967833cba61f2b30b0e9fed1d3f0c90b5ad6588646b8153bdf1d66707ac2e59fd4a2671").into(), + hex!("92ff79402d5005d463006e0a6991eaacc3136c4823487d912cc7eec1fe9f61caf24cd10022afdab5f6b4f85bfb3eee4f").into(), + hex!("a32a5bd9b7bec31dd138c44d8365186b9323afbba359550414a01e1cdb529426bfa0b6f7daaf3536e9402821faa80003").into(), + hex!("845982c2672fdd44b33d2e56ad676e704c02f756b09e8765bea42b924c14724484567b55f0db42ac20cb70a7f5201c14").into(), + hex!("89cd9f6ae7d9a9ff2b4db916ba3af9fe700fcfbd16577bf73a965af938e8cf633020466b0298d3c31300360aa6851af2").into(), + hex!("8fa2d7b22af8e6b82679ebdfa13efdcb34289a554653ea6c1b16efb9f957f7fe64df787e7b03d8cdc8a732b91c916bd1").into(), + hex!("94f327bc57ed1ce88ce4504b4810cc8af5bd21a7e07b280a7866ce08e39b6cf7a6560bf73a5f10671271624cd7893970").into(), + hex!("90f4476224b64c2a5333198a4300ece8b3a59ae315469b23fd98dadcdceaaf38642d2076e9cd0bfacc515306f807819f").into(), + hex!("ae0db78548261216ad7d6a7ed4e6089ee17b3fa311494b2f2c559e215cd3de7e5f3a781a49dcff428a8a61c2a4f49a19").into(), + hex!("a83371f44e007c708dc4bcafa7bd3581f9080a4583c9be88624265014fd92f060127e628de5af3c442a25f049c7e7766").into(), + hex!("b471c72bd2971353f4b44248b8e6cf5316812861a88ccfc20fd0d89a5e010428c387228b2f6f14c12f79e31afc9d0753").into(), + hex!("8962afddcb1a26cc8ccd3c993109e79a4dd747ca473b8b5ef93d9c2e71d29623b834ac945074acf118248e3ae7878a6c").into(), + hex!("aa0940e4e5586e79a3d97397c8aff3d112c6f759d2efac29366acc5b5c6a7cfef8d50516bf309da8b787de265dc8deda").into(), + hex!("a211120e1bb3b10138df1fa58efb009a298b8771f884b82bb3de15822b1252124a68f3980f96122a775fb96f05ddc3d5").into(), + hex!("a1047401598b1e6e2613d746bb4689e0406eccdbadf319a6609a3261cd09deec215d90eba6d0ddc50dd3787d60104e7f").into(), + hex!("96791b2b8066b155de0b57a2e4b814bc9b6b7c5a1db3d2475a2183b09f9dcd9c6f273e2b0c922a23d1cf049a6ce602a3").into(), + hex!("91013e0d537fb085a49bf1aa3b727239b3e2c1d74c0f52050ff066982d23d5ee6104e70b533047b685e8b1529a0f14dc").into(), + hex!("aa65c11071be23c9bddaa5203f3166e5cf043efe5fb8f4b26f8a9cabe71db701a450e79eb001c401da5752755d9cf1af").into(), + hex!("8645cc44d180c18a6d8f57ba57bae05879451997533cfe558cad4d3d586caec877e348915e32a09ee73483283c4df744").into(), + hex!("8eafbb7002f5bc4cea23e7b1ba1ec10558de447c7b3e209b77f4df7b042804a07bb27c85d76aea591fa5693542c070de").into(), + hex!("919c81bd1f3d9918e121e4793690f9ddd96c925ae928536322d4b98132f21979c1f34731d393f0ae6e0871af4355a8ad").into(), + hex!("98181e9291622f3f3f72937c3828cee9a1661ca522250dfbbe1c39cda23b23be5b6e970faf400c6c7f15c9ca1d563868").into(), + hex!("8f44c43b80a3c5f488118859fab054745cfe5b0824821944b82fcf870fda6d93489ea9ca4220c24db2f4ad09c6080cb7").into(), + hex!("a683d4865ddcc099f7b698153007b92f853b80f49b3be75163ea8cd1f8ff584b43a68e68de3ae61cda8ad4b41f355c87").into(), + hex!("942772b7c7c47d4e5957ccf1d6f1450070930af3e2b7eaab0dd7699372445df0cc910e6c0efcf501887dd1adabdaee23").into(), + hex!("805c06e565ee67cab0cbccb92b6656fdb240b430766eade3c6b0a0b1b93c840e2b4f028601451dca135c783239463880").into(), + hex!("84d3e2a06e16ced26094b356a16a4fb6aad50ad9ab23ef804a5852a33ef0bff76f3c5fbf7beb062376c2e669cb598679").into(), + hex!("803df08aa745cc3c0a799f3a91bb6ed423cd520c9d255d36c21bed1a0c3b12e8cad32f54da09dadca97683e9548fba91").into(), + hex!("aa2c3ef95b8d4265f01666129646004b6950d3e8ce74b4ca12aa3b90fbb445079a569178df772c272463a44d48922b8f").into(), + hex!("b0a4c136fb93594913ffcebba98ee1cdf7bc60ad175af0bc2fb1afe7314524bbb85f620dd101e9af765588b7b4bf51d0").into(), + hex!("93e4c18896f3ebbbf3cdb5ca6b346e1a76bee6897f927f081d477993eefbc54bbdfaddc871a90d5e96bc445e1cfce24e").into(), + hex!("89019e9550648962420984e9fd03597a854ae824567d9aa6cd5db01a4616b4e1477230f2d1362a2d307e2425a3eeb898").into(), + hex!("861b710d5ec8ce873e921655a2ca877429e34d432643f65d50e8b2669929be40a9ce11c6353b0ada1fe115e45396b2b7").into(), + hex!("88554c83648ea97dac83d806cd81d92531980346b208d281fba489da15a0084fd4d9a00591d1ca67aad3c5793685d55f").into(), + hex!("851fcadebee06930186f35293feefd40d7daedec9b94e6fe5967536c2c0e4cc68f58d3f5fbc76f1e77b90c9580074f98").into(), + hex!("b96a11048c7c327709d52e72e6f6ed0b7653329a374ea341ad909311b5b303e5629d6dcf11dcdb195e8c7592ceefac21").into(), + hex!("836075979eaf386ff6cb459cfd48fed171ae812b0ac3b38dc24dd8ca905cac1c600be717d4a0defa0a854f40cfaf8c33").into(), + hex!("90fc170529bcc0b80c46a53fffd8323fd2cc5cfa9b75ea4d36db21bd1f198335ad2bfa87f8990cf9cd9fd7989ecca718").into(), + hex!("b7eb6a49bf8f942dd8c37c41c1b35df43e4536e07ca9f4c1cfbbf8a8c03f84c54c1a0d8e901c49de526900aeac0f922f").into(), + hex!("af6911edd6c7ad30f905a0a3f78634808832fdeb4206b006934822d673bcced8e378779261b3c4b772b34b8871987f57").into(), + hex!("a74d240d0d7ea0afe68813fab55388d77e75eca0519d21771dcb7170cedb11dc14b237b26c5ae1f7f728b52e5ec0f02d").into(), + hex!("a7b86e4f1366da44fd59a3ee68018a99c23ba3588789463bd88b0177a9b94030b58cb879a506e64421af966f261eaa86").into(), + hex!("ad8d94e46cc02a1c0ad27105e8f672ec15b8296051801f1918d0bd470625686e8e8a0abde8f6852b846ee8d9132b26bc").into(), + hex!("980508c4d1e655cc6200f89a884b3a25c0c05708a3e4a101205c4fd901c3e20a943071a6300bb2614be41a139d4ef1df").into(), + hex!("b0173651b4ba0590b1d2f0265183f3729b5bb09893523ca12c4936120cbe5ef0d9b98733734407d99fdc766792ff10ac").into(), + hex!("abf72ec0280d56971e599b3be7915f5f224c0ccde2c440237e67b95489f0c9154ace04b7763db228473715f68053f071").into(), + hex!("b404beebf60026ca6843f2953cfcdee494d495c8e2d18865147102ef29a8f0ee470961d2246fe5a450c622d20ca51d53").into(), + hex!("89461cb2dadf51d6f1208b0965c8eabec895d7b19b7d90d3c6e49dbe75a75c30fd26db3dfb169dd46a4342280225032a").into(), + hex!("a61cb5b148cb7ff34775dead8efa7d54d7141182356bf614070dfaa710ebf07a4dfb684dad151db60c0f8261c30a4f40").into(), + hex!("83a798f47a4f62dcb8b531d463b0fd4a876d47a8ca990710290549255033c909de709471b4e823a60bf94d8baf8b5acf").into(), + hex!("a23431589f3a25070a188deead9adb0ed423d6b00af267f3f125cdd4391c1527909b5cfa88130dc4b67915f5002128fa").into(), + hex!("8d77e65ba6250fe18c54ce70d0ba4571a7d3e68a8b169055cd208e4434b35a4297e154775c73e7dfba511faadb2598c5").into(), + hex!("90e5db75f3787b819df471712f87b6f3281437090f5db7a2c21b07164446292a414c687e41de2d1ca00786b093239c64").into(), + hex!("b382fa28670a5e14dc954b2db8ace250c73df71ab095304bd8ee28f455ab26cc54f82775a831428e110d1a3a2af709bb").into(), + hex!("a58d2fb1c2612d28c54fafa7f2e1e6c336c24435abdb53e1be9dce9aebecbf7468a348b872549535ac18aa003f83ea87").into(), + hex!("9545f94c4e9056e360dd999985f8ad06210556fa6f07cff77136a2460605afb0ff1fb1d1a2abe4a4e319fd6c29fff80f").into(), + hex!("93121aa60f904a48e624e00f5410cf8c8925d2b0719f90c20e00cba584626f833de7c8a18dbfa6a07df24b916156bfc0").into(), + hex!("aa3446aac25f6c23ea16e8f7d19c58d187746ef3c2ac7d8fdf9bdc329409a07589ec8eebafbe2b156e7ba60addc15af8").into(), + hex!("b964f50011f03135e993739e2e63a71933ba4583040b3af96c7e2dce874226518f7b68f622c4a1d78b9c3ec671d33ad7").into(), + hex!("8cb5cb7cba886af58acadc5a4348524b1395a39dc51196316d759a9b72d9fc0fe45b706e264393a13ff911f0d15de45c").into(), + hex!("b50c306f78143b37986e68efa10dbe1fb047d58562e9b5c5439b341dd8f1896c7ae586afac0a3213759784a905c1caaa").into(), + hex!("97825edba8410e8bcb85c5943628c02ea95ee7595f559c030b94395c0d1d0d84c38eca199fce9c1992e572b5029b124c").into(), + hex!("b0922acd6da2a95b36de6d0755316594a7e2e32ea774792dc314e8c3cd76d9f1d69df38231e166e24bd42c664f4fbac7").into(), + hex!("ae5ea228c1b91ef23c245928186fbafa1275ff1817535018d7d2d913abff0fd76bf41fd04a96d816f2f1891bd16e9264").into(), + hex!("b106c6d13ca17a4c8ea599306e84918127cf2de21027ac3fe5a57d35cf6f3b1d7671c70b866f6e02168ae4e7adb56860").into(), + hex!("a044cd5a3b727dc1cb59875e4025718375d12e706fffcdb48874e51a675dc2cabb209670192e408cdced5aeac65192e4").into(), + hex!("ab1cc44983e46a6ea2430aa6616ab28614f43624665e3e6ae31a9357c0c5434f34e56c720906e184327693cc4ebe1fa2").into(), + hex!("890def696fc04bbb9e9ed87a2a4965b896a9ae127bc0e1cc515549b88ddbcbc02647e983561cab691f7d25cf7c7eb254").into(), + hex!("a86be58fef115445b909dffac6f51da3fe9214afd9c31fd564bb8f39b1dc3cb895b1222f2c63226b54b60b278ec45edb").into(), + hex!("8757e9a6a2dac742ab66011c53fa76edb5ebc3c2fbd9a7265529a3e5608b5c24b4482fed095725e9b8fed5a8319c17a4").into(), + hex!("a7e0ddbae16e4491822684c0da3affecbbd17ef96c5c491ac093c6eb4e162fc7854c367535e296fd3d6265c2ed1210bb").into(), + hex!("941fe0dabcdb3225a625af70a132bc1e24ccab1f8331dde87db3e26cbee710b12b85535e46b55de7f5d1c67a52ddd5c8").into(), + hex!("a24d05b51c7c128bb49979cbd9019e6618545d95275a44b5c3d1d03e71bf2ebffdf43fff50c30846ec27d279043cef4e").into(), + hex!("b526f40d519e7a8f2c81b69f71b3e2ef079028004c0448ba0608296c2787972491ec6d05ed6a8fbd5ef2da76325a93cb").into(), + hex!("87ca4fa85a257adf7e21af302437e0fa094e09efced2d7ebab6cf848e6a77ae7bfc7cf76079117f6ed6eded9d79ce9cb").into(), + hex!("9276e8051bed8f5dbfc6b35765aac577dd9351d9d6ac1bb14496bd98091005b9a4737b213e347336413743f681f5043b").into(), + hex!("a7741c52498e0a24db3ce7699882de8f462a2b3ed5e9f77dc7200cbdf46b6cdd923b1128759909d6dddd64700c4c20c5").into(), + hex!("ab5b363ed9551e32042e43495a456e394cbc6d53b15d37a8859850162608bdf36d3d4564b88fdbaf36ff391bb4090b8c").into(), + hex!("838ff6630dc3908a04c51fb44a29eca5a0d88330f48c1d0dd68b8890411a394fd728f14215482b03477d33f39645dceb").into(), + hex!("997d3b82e4753f1fc3fc2595cfe25b22ac1956d89c0950767c6b9de20623d310b1d84aaa72ab967ef1ea6d397e13524b").into(), + hex!("85416cf3eef63d5530062d6f031aeddad101c7f1aea3bccb826c73f8a25d5d963caefd789a6b9832bd4ed459f268ae64").into(), + hex!("9194bc45e11d7276ed1c9ef3ad5a33d6a27372f5568563ca8ee213e2e7029dee404ab5acbaecaef698129798d35fd895").into(), + hex!("a4828a003513ab887082390262a932a7e8c5e25431824b7b4cc10fccba73265c0e5ee5b315ccef13906d971644913806").into(), + hex!("b907ec84b6ae5729d36e2acd585a350acacdeef148bcc5dc4a91edb57505526462bd4371574865541d8bb0d786a29b2f").into(), + hex!("aa5d1c1f0a7f6b9b3c3734f85864aa60bddad5121450218d76d82edefd2602685a820965c56d7eefe789d5115cb41e01").into(), + hex!("ad28fe70a8606f87bcb5d6f44e1fca499c24bcee791971f599ffef1f403dc7aec2ab6ebed73c1f8750a9b0ff8f69a1e6").into(), + hex!("a641eaa149c366de228a2833907ad60eea423dd3edf47e76042fdf6f5dc47a5b5fc1f1b92c8b96c70e6d8a68d3b8896c").into(), + hex!("abac08f4df786b2d524f758bca43b403b724d12601dc0a8362b7a2779d55b060c6682a5618fffea2e4def169fcbd2bfb").into(), + hex!("8658a15df961c25648fd444bdf48a8f7bb382d9212c0c65d56bf9cdb61aab3bd86604c687fb682260dbc0ad2dc84bf01").into(), + hex!("ac7983d50ec447b65e62ed38054d8e8242c31b40030f630098ce0a4e93536da9179c3f3ae0b34a0b02aad427a97ee60d").into(), + hex!("b8877a00a24b0ffcb2bd3fce8a8ba327d8ee2e98d85531cb61fec21fd49cd1696491cd51024a9c3820cf06a77cacf04b").into(), + hex!("ae075b66e5f211c2149c45b211d1297bbc1d9e6497cb3315363c492a9a51ae5b9d0a28bfecd755d68553736901ac6606").into(), + hex!("afdc091a224486e7bfac169e6a7b4e008d2d04144508a337fd93b6f4d385ee3f0d927b1f5c1cd79a15e0fd6078e45dd4").into(), + hex!("b75c28941ee3f91b3535b4eaa0fb17b59ca65b5256601a1f6d0cf2bb4d66837fd16e51d6942856679012a5730a66e519").into(), + hex!("84a6edac5ac68a7ca837c46d5ada8fab136748b6c3a3b9165dbbc231ec386b15328e4ef7d69a15d4cf354135348a4ee4").into(), + hex!("b01ee30d120b97e7b60ea89b9b6c537cdf20b6e36337e70d289ed5949355dd32679dc0a747525d6f2076f5be051d3a89").into(), + hex!("a80deb10bba4bc7e729145e4caf009a39f5c69388a2a86eaba3de275b441d5217d615554a610466a33cfe0bbe09ef355").into(), + hex!("8d6e3df29419bd0da1deba52c1feebe37744108685b49ca703e1b76fb4d612e3959d3b60b822506e5c0aac50b2f5eee2").into(), + hex!("a373408beb5e4e0d3ebd5ca3843fe39bb56b77a5d3d2121d4a7a87f9add3ec7376388e9d4b8da0ba69164850cb4b077d").into(), + hex!("ae0beb452af7479134a7fbc31a5f59d248e8a67d4c7f73a0e30a51db9cd33a1da3f0ae947fa7e5983aea1343e7daf06a").into(), + hex!("aa103a329b699d4102f948101ce5fae27226419f75d866d235da8956f11367e71db5c0a179dd63007ed53f7eec333aaa").into(), + hex!("a094cca9d120d92c0e92ce740bc774a89667c6f796b438b0d98df0b7aef0935d8c915d5b0dad4b53e383dc9f095c29fa").into(), + hex!("a4d88467136b99d6e55603b3665b6da0f7fb27c7759687f7e6977b6230272773d7b95049d999538c008f310c05ed948a").into(), + hex!("a23710308d8e25a0bb1db53c8598e526235c5e91e4605e402f6a25c126687d9de146b75c39a31c69ab76bab514320e05").into(), + hex!("a36d6952c2d7f88bf28032a76ed46c4dabbf1901a46efc50deb798d1b44adf7e0210fbdf2473a1ba408b5c98d76943e5").into(), + hex!("ab45f5b756ec6e0b98d0d4301c87675a0a1f0b1178b8a9780c1ab23e482cd821834835afa1de890962212159e464b10a").into(), + hex!("b800be1788175a01a9228b0d3e7eb4302484a2654eb2a86c0f0900b593da0a436ef031ac230e2b05e968b33e90a342ce").into(), + hex!("8cc8d279ec08d0a5a2a09ad07fabb0122eb65f48da2571d83f86efa2c1c5bc51b04ae94b145f0a8ef19a3988638b9380").into(), + hex!("b4cd409256819e8e4627edbba90ec40b7da17a57f95749104d90db0364f5007b1accc816f4d51a0dbe5ffbcb737cb37e").into(), + hex!("99365fe5ab8ea8bd768ae7181a6ba49b79d240f512ce309b02f09d465fea276298ff55b5b9cb5b4162a901b390606024").into(), + hex!("ad77fcac9753efba7a9d9ef8ff4ec9889aa4b9e43ba185e5df6bf6574a5cf9b9ad3f0f3ef2bcbea660c7eef869ce76c8").into(), + hex!("ad2456725ac3aeb0e4ca5c0502a8abb4dbd8a8897d9d91e673fea6a0cffd64d907b714b662d73c0877b98d4ab3ce6a89").into(), + hex!("ac8436e33619e2907659741d66082acbda32612d245fcc8ae31e55f99703fac1a15657342fa66751d3be44fc35d71c36").into(), + hex!("b0eecd04c8d09fd364f9ca724036995c16ba6830d6c13a480b30eb2118c66c019cfdc9dacce6bfd8215abe025733e43d").into(), + hex!("9439b663e4104d64433be7d49d0beaae263f20cfac0b5af402a59412056094bd71f0450bc52a294fc759ca8a3fddfee9").into(), + hex!("b72de0187809aaea904652d81dcabd38295e7988e3b98d5279c1b6d097b05e35ca381d4e32083d2cf24ca73cc8289d2b").into(), + hex!("93706f8d7daca7c3b339538fb7087ddbf09c733662b55c35f2a71073f4a17c91741955d4d549c2ee6c22eaa84193c1ad").into(), + hex!("926dc729e135f1f0bff4662ee3d6823a64597fe189b763ada34f246e77705fd4e062d85506a338e9fa98c4d225a3b27a").into(), + hex!("93f03495d53c781be8b76e37e68b64aa260523004eff6455ddc8a8552af39854e5181f8c5365812b1f65926534fba5dd").into(), + hex!("9834f66e5c946c3a8241ca2bbde046a7e88072124911d5d15c037a95b61e82b88b5c2058fa4a3721537dee39dee5da18").into(), + hex!("92ec1aeb2aa24c51cd5f724972c8b6095e77b237d83f93ed34ca0bc91a1dbf1ad95adccc59e0f0abbfef33f331f3298c").into(), + hex!("94402d05dbe02a7505da715c5b26438880d086e3130dce7d6c59a9cca1943fe88c44771619303ec71736774b3cc5b1f6").into(), + hex!("8368bb9b9bb2e17730c42ed1100eb870c88a8431601312aa8cb1e738cdb9ca2704dfd432cf1703c0db043259819631dc").into(), + hex!("a35189a105401f0cfba4b43be21723486c04659e5a01e67c43e8f9911030810b878beee696f04f63d314ccfe97ebb790").into(), + hex!("93ccd8c5f82374e0bef6562e16576f742d79b6f400e3485ef36e148088b61fbd882c3d2bb38ab0b43fa1dac77f31d543").into(), + hex!("b85d9a426a23ca9ee582bc16c203a9352dcc5f85440e46979de80eb572384479b697dc964cafd9457d9f34eeb77bb72a").into(), + hex!("aefb70e89dbf4456e077690509afcdcabf975416ff2fa16777fdf90b3abd3f5dcd865c43f1ebe6f8a669edc7f3bd6ad8").into(), + hex!("8eb03001ac9e22c6956a682ed458e650785c36d23ddbcd51ac4d9cc991325c02519ff1958987a08eb29ff56ff6e2c293").into(), + hex!("ab4a1ffef7e001723c71f5d28f3dd030a06c42d91773733d117247bbf9c01cd66fca2cff8c6ce04c4bfb68dfcdd851f2").into(), + hex!("a9ef845ab489f61dbfdcd71abcc29fc38f3494a00243b9c20b9cd0dd9e8a0f23304df84939b9652cdf5542d9b3ee085e").into(), + hex!("b5726aee939d8aee0d50bf15565f99e6d0c4df7388073b4534f581f572ad55893c5566eab1a7e22db8feeb8a90175b7d").into(), + hex!("9953a7cbc152f101a60e3e381f2af17ebe7401e16ef6462d132b8f0f6c6a18837914a1299d1605f9f289b9561112f4bb").into(), + hex!("a0c9b944a338325f5efb675c9c12619fb43c8e25e80d38d6140e31d5070573b1a0ed9bb52576e4f22f37d0292d36a648").into(), + hex!("8bfd6a173a56b73480cc950ef266a18933ecafc86915a7453ded09efd8a0cf4466101f1373f05d48eae3e7fc5c0f7f54").into(), + hex!("983fc1ddf17f9756c9cecc00b39bb2ad432587a5c6d1c3296a383b9f539c9afe84c6c818447a709c0b686ba26ce5ea3e").into(), + hex!("94bbc6b2742d21eff4fae77c720313015dd4bbcc5add8146bf1c4b89e32f6f5df46ca770e1f385fdd29dc5c7b9653361").into(), + hex!("b26b4d483bca73d3f3a976bb595a0e40f9a42094e0febbad3a1874934be1939a1b362ee4ea14a4f5cbfa9b1392796a12").into(), + hex!("8dbe8fcbcc414eb352245c52549973f73d987012de9d5f2b2f55dfdc43cf8cc9ea6b147abf149817f80f9e15aea566c6").into(), + hex!("9604da21e23c994a0a875ad5e0d279c79210f7a7de5c9699fac4aebbd76d39b703eeec5dd5efc9ad6b9dc58936089ddc").into(), + hex!("8934e9a3feababa12ed142daa30e91bd6d28b432d182ac625501fe1dc82f973c67f0fe82d39c9b1da3613bb8bfe2f77b").into(), + hex!("85f2ed3ffb03e50c8f22553b8e6349be6244d893aa37a7c6dbd221e9e121579e5a04466e60d6b4d3567bc747b1fc1e9f").into(), + hex!("ab0ad421f6fd056687b4fa5e99dff97bd08840b7c4e00435eb9da80e0d7d071a447a22f8e5c1c5e93a9c729e5b875a1e").into(), + hex!("841d77b358c4567396925040dffe17b3b82c6f199285ac621b2a95aa401ddb2bc6f07ebd5fa500af01f64d3bb44de2df").into(), + hex!("83f21dfe0272a5a8682c3c7814c5e0e4db6a9098f1fa80fda725f77ea81fdfd2fa36b0c8db013503a89bd035f86306fa").into(), + hex!("95c98e3b6b62f84edf7f297cae93ee5f82593478877f92fb5bf43fd4422c3c78e37d48c1ee7ca474f807ab3e848d4496").into(), + hex!("81c3a8c00cfe4e82f3d8cb48de7d4926d5ec2f7689f9cb85c1886a23758bc107a4bc6e978601c3519156a169d0bf6779").into(), + hex!("8e956ca6050684b113a6c09d575996a9c99cc0bf61c6fb5c9eaae57b453838821cc604cf8adb70111de2c5076ae9d456").into(), + hex!("83474776ef2341051b781a8feaf971915b4a1034fa30a9232c4bf4b1bd0b57bc069c72c79510acef92e75da6f6b8843d").into(), + hex!("b41780d9d67e9e8b81b1f62d25c0c72ecfda659d2bfe6825edb70ecd0e0724250ac364e7be521cdc112ba638f16360d4").into(), + hex!("842ba3c847c99532bf3a9339380e84839326d39d404f9c2994821eaf265185c1ac87d3dc04a7f851df4961e540330323").into(), + hex!("af17532b35bcb373ce1deebce1c84abe34f88a412082b97795b0c73570cb6b88ea4ba52e7f5eb5ca181277cdba7a2d6d").into(), + hex!("b9574edb9567f07f85c7c2e6ca6c02d90ad7c7b87d49796f1e2fb7240ad071fb755cf13ca8678668a56217c62df168eb").into(), + hex!("82212706111fb1cf5def02b5b0eb7ae9e6ea42b4c7a2b9fcacb7aec928326edb9ac940850dd933f2822f6cf519de0d50").into(), + hex!("9579973ee2559da09b327c62b1cc0177f2859872885dca709e24dcfbb9bdf9224a6d26869aafce498f44c0e6bd8a996c").into(), + hex!("a102c2ade15ea2f2b0cbc7dbd8c1171de0c8092fc4ecef84b5fd2bae7424aea8be1629f851c75e4d1d0e96104e54bfbc").into(), + hex!("a5d7e847ce7793386e17fe525f82aabb790d5417c3c6e3f6312f8e5ff52efa8b345c1ff60c4c9bf7636f5ff17b7a0061").into(), + hex!("b4b80d7fbdb1dbf1567dfb30d8e814e63de670839a8f6ff434fe171416599fef831b8e978d6498851b8a81e0bc8dfb85").into(), + hex!("b6e6277b86cd5284299ced867d37ab98090ac44a94deef6898aeadd177e64605440c15b9609c07e71fe54c95b61873b0").into(), + hex!("8135a0633082e4465090d6930b770340e82366bc5c37be6ef6dd105f85acf63361e17de8b5fcab4c82e9f9b4029954b7").into(), + hex!("864d5d9858cd881eecb0dde5e3e0c6c5de623cd9ef619e87b82fd25c5edf45a1a025b1dc763c27c5f4d520fd564b464a").into(), + hex!("8784a8fa62e0ce23283386175007bb781a8ec91b06fd94f22a20cd869929de37259847a94a0f22078ab14bb74709fac6").into(), + hex!("8adb748d5fa5c22ce4c76a1debf394b00d58add9f4e08524cf9c503f95981b36b8d0cb2dfaef0d59d07768e555733ecc").into(), + hex!("b76cb8cb446eb3cb4f682a5cd884f6c93086a8bf626c5b5c557a06499de9c13315618d48a0c5693512a3dc143a799c07").into(), + hex!("b2af1f7ece1fd640c205a09614122d69d5d2e81a7618bedefd6dbb91c7f432679be4ced1e6dddd3de323bd44991931c5").into(), + hex!("b950b457c34bfdfdd9d6da9628d41749ccae03659518a04b56487bf1b4c0681b719ec5230c0b0fd5dd710894df6aa2f8").into(), + hex!("b21785008910a949804d1291e7533752641d31beae3cb518806488f81d58c38a5efe5ed9534ac692e68c3121e2f9d97d").into(), + hex!("a9b120a77d70c1cbc0178a12d97a78b2dd0b98d0584e8e780b937800ceb18c90eaa1f0a83c5b50e34cae1c20468f004f").into(), + hex!("998c9ee20d33f96a2388b1df642aa602bc8900ba335e8810baab17060c1eace4bc5203672c257b9ae750008b707b0aa1").into(), + hex!("a7d1676816e81a752267d309014de1772b571b109c2901dc7c9810f45417faa18c81965c114be489ed178e54ac3687a1").into(), + hex!("b409f87f0632aae9bc081345b17a50a767ba4198f9ac9d352246fb3bebd29ed53c9d6f148c2f318c2eb12846b0aac4cb").into(), + hex!("b40a3bae2b08c13db00f993db49e2042be99cde3d6f4f03d9991e42297933d6049394c659e31f316fcb081b60461dabf").into(), + hex!("8c1de4264e04ff7e8282faf81c0bfb5943656451be52170211cb7adf4ff21bccbb789400735579c622f69982fcb8e9c6").into(), + hex!("8085c60b6b12ac8a5be8a7e24977663125c34827842aa3b2730854ab199dd0d2eaa93084c9599f0939be8db6758b198b").into(), + hex!("972cfaefda96f5edfe0614c01533b76153118712c1c02c505008204a5be2aa438675d97f43384199517b1c08c7c9fdb2").into(), + hex!("a1e47798a782a024da340d6d6a1b1e5e15a0f2d8668adf349ca375086964414a563cc1eea3226ae637f87e78c0a630b3").into(), + hex!("8171f20c020faae112bb92ca213c1df5b1050151496c70db5c5319212bada83b120d515bd7d8b24736090c574e1b7203").into(), + hex!("afe779a9ca4edc032fed08ee0dd069be277d7663e898dceaba6001399b0b77bbce653c9dc90f27137b4278d754c1551a").into(), + hex!("a5a07bf219432e9c80c38596c93560b49c7de287f31e30b7a06fcb4d15982add4a24085adbc5b753c462be989c64c96d").into(), + hex!("9210be290176d7e8a5005d27e7ed825067b1c678b174bc8180f92b5c03b6c3d1822356edba84f460caf6bf5275cd7efb").into(), + hex!("a95bec86a7c8417a8df3a0158199327ba0924d3b7dd94cd7c1ef8489b10270ae64b8537ed39cd3699a48942bfc80c35d").into(), + hex!("ad9725114b01152fff134c1a8ccb8d171b8cd11685ef6815b76f442d757d130bab9ef4c9845e66f4aa0237ee2b525c20").into(), + hex!("8018499ef720e28759133033833edfe17ed23e42f99058bb79fe844ddee823cfdc43916be2dc9724d18f9726e6f1b409").into(), + hex!("809c7a08fbef7caf4c137cd639f2e47a8ca60d13bca3990eac51ac2a9e4442cd1a1473bebb63c61d595b586525d7b027").into(), + hex!("9793a74fa578ace75b083578277a1ae8766d41a5c508b0f1135fb97dff1d0826002393a7276b18cbc4b3c5671360ce0b").into(), + hex!("a6d7e65bf9f889532090ae4f9067bb63f15b21f05f22c2540ff1bb5b0b5d98f205e150b1b1690e9aa13d0dee37222143").into(), + hex!("99c935fe18699bca9852200c292690a2b834bac508890c4ee9af1aa6999a8d590bf6a3a274bb55d5a73f1b7095d10f37").into(), + hex!("860f5649c5299211728a36722a142bf1aa7cbbfbd225b671d427c67546375de96832c06709c73b7a51439b091249d34f").into(), + hex!("9104ac7ad13b441c6b2234a319e1c54e7f172c9a3efcb8c5fab0ac1d388b01895a9a208f59910bc00fb998b0adab1bc3").into(), + hex!("a3b109249ac2900806f0f39338da72d4f2cc6d1ac403b59834b46da5705cf436af8499fa83717f954edb32312397c8d9").into(), + hex!("b9893f7a47af457a9efd90ddc0c0ef383ab34e9c1284e617c126965cd9f0de5c54ee8b7b5208ff190366fe445e9c1325").into(), + hex!("b77416ea9a6b819e63ae427057d5741788bd6301b02d180083c7aa662200f5ebed14a486efae63c3de81572fe0d92a9c").into(), + hex!("8b20a852fc8f0b7cdbbd808c04a0cfd2fbccbdc0cb2361434f0d96341c8bde6155695977768d563b95746dcb4339fe2c").into(), + hex!("96b15806d9009962fa07f8c32e92e3bc30be4ded0645ab9f486962a1b317e313830992179826d746ea26d4d906bdb7b6").into(), + hex!("b0d69b3861ca6791632ec8a87114b463e0da571bc076c22a8f0d9e88a1a5eaef24683f3efa8f34900d0112412e3dc4fa").into(), + hex!("b01a30d439def99e676c097e5f4b2aa249aa4d184eaace81819a698cb37d33f5a24089339916ee0acb539f0e62936d83").into(), + hex!("b19ca6e55f349bbb2dc3e429520ff5b2e817972470794f35c1aac8c118b37a694cfcc875b6d72225343799825d2f5c39").into(), + hex!("b7ea5e0d3cfcf0570204b0371d69df1ab8f1fdc4e58688ecd2b884399644f7d318d660c23bd4d6d60d44a43aa9cf656d").into(), + hex!("a778da56ddfe4a383816b43b027464d7a28689fc4a6b35b36883d3f36d9c41f0177bdbfc8f258afe8da90f02d3b64fea").into(), + hex!("910fd030feb5538f538e5ba74b9bd017d889ed6d2a797be9c26d2be8caeba7a473006102de27e87755742ba34e445bca").into(), + hex!("b49593ea6040ce82cfb5aa2881a4b0c42b78aa9fc8467d79c8e4a8ae4ee7355842841c8e1cc0558362047ed80de44fd3").into(), + hex!("b07447c7e87459315fcbda3fb86fef27f98373b1246e2ce367e26afd87f6d698a438501fdc13cc5de9eef8d545aab768").into(), + hex!("8a9f7e8d45f11c4bfb0921c6008f3c79ff923452bcfa7769beb3222f1f37dcb861be979e6eae187f06cf26af05e8ee5b").into(), + hex!("8ebfbcaccddd2489c4a29a374a2babc26987c3312607eadb2c4b0a53a17de97107c54eab34def09144b3098c082c286b").into(), + hex!("93be3d4363659fb6fbf3e4c91ac25524f486450a3937bc210c2043773131f81018dbc042f40be623192fbdd174369be2").into(), + hex!("8cf8412bd48b21b008f0207b1f430ed96bc6512c3712dffbbecb66e493e33698c051b27a2998c5bddd89d6c373d02d06").into(), + hex!("a5562fbaa952d4dcfe234023f969fa691307a8dfa46de1b2dcff73d3791d56b1c52d3b949365911fdff6dde44c08e855").into(), + hex!("a8c167b93023b60e2050e704fcaca8951df180b2ae17bfb6af464533395ece7ed9d9ec200fd08b27b6f04dafa3a7a0bd").into(), + hex!("93e4d7740847caeeaca68e0b8f9a81b9475435108861506e3d3ccd3d716e05ced294ac30743eb9f45496acd6438b255d").into(), + hex!("8016d3229030424cfeff6c5b813970ea193f8d012cfa767270ca9057d58eddc556e96c14544bf4c038dbed5f24aa8da0").into(), + hex!("ab7eff4ef8696db334bce564bc273af0412bb4de547056326dff2037e1eca7abde039a51953948dd61d3d15925cd92f6").into(), + hex!("a3f9dcc48290883d233100b69404b0b05cf34df5f6e6f6833a17cc7b23a2612b85c39df03c1e6e3cd380f259402c6120").into(), + hex!("8b476b3b065a3b95a3d11ec60a749c2258ddcc5885bfb50b8a086d3fd1e49ff73e1dde733b8981c3d2d206aa0c87b09b").into(), + hex!("af3e694ad71684f7214f86bed85149db039971e1c362119b979a135255aa226128802e58e2caaeaf8d89304371dd0440").into(), + hex!("aa19a75f21a14ad5f170e336a0bd07e0c98b9f5d71f91e784d1dc28a5f5eb6870a4eb35bb41edcf9e6efe982ae5c2c5b").into(), + hex!("b9528983419ab5766596683faebb3592982a76b68593f810186b4e5f94f6de60830739ad8dcc164c601d575b84bd2700").into(), + hex!("88e7a12a90428bb45bcf4b01442c11607433211fc2f9bee9545304eb66e0b4b5339360160bc782e185391385da7c5ad7").into(), + hex!("a4c4df0e29db19ab4c82dd6ca8570b337d15b59c7d84577a7a444a8f762ff16ff5ab3e4203a1d6b60a23ff949a93ea81").into(), + hex!("8f11ee58ef82b1bbd2240d3f548d8681e22bed5ce118d605bed4523b4bb39899ac78e15337daab92666750dfcaf32aff").into(), + hex!("8d3cba4d10f94bd3406a341c903ad144cfcfe6b61678d5c03084a56b4413bc30bd20d7a9fd5d839dbb565cc9b2aa99fe").into(), + hex!("ab8a8769c754008a7976b6799e81d7bfe97413d0a79b90715703c1f8f567675463ec93aabee59277121fc4df88b5c7a9").into(), + hex!("b201b0546f19c5db88df9c684cf55ed623bdb43927d06051bd595497df741feb1485961f64e8d3d1811d9e2e9e1e54ad").into(), + hex!("a04016e9e13ad845763cfe44af4e29fecf920b4aa42f581715fc34fb9ca27776feee45c82093c7274839eef1838b10c4").into(), + hex!("8f84cba7ceb7652023fc8ebde4b00ecde1f550935bab12feb630d6f49517b4148f3cde184bf55d4f6ec99a849fc6f862").into(), + hex!("a2248409026f35c3da8bc4d5c02315066df8fca44ff5a358cc42b5c88bdf6866dc133617c697bff004b1ef20ec4b5748").into(), + hex!("a52c5a63b55a8001b6b67c5db4fd5e95923052f03618369312896ed9892d99354aebc0dee8c3b365bafa29e211a5c3f9").into(), + hex!("8c9fefe233d0d657349b7efcdc368f5aaead27071d224af780874751e7d241f6b88f7650fbb4133043b24bbebc12aa48").into(), + hex!("86ceb649a337a5a79c17b496993ca07fa93b38a582367ca04f3dfec5cef8f268d4e8080e5a76b150f5be1b177ef6984e").into(), + hex!("87dcb537e38cefa32e629ae669da42e809b5afcabdeeef244b72ce057fc18584a1e8c3f073d5d33775232707f0cc59ca").into(), + hex!("a020404547407be6d42856780a1b9cf46b5bc48122902880909bdcf45b204c083f3b03447c6e90d97fd241975566e9bf").into(), + hex!("a1beb9f673409ec678020ea4dcbe65177aa18e2932ceb9cfb33fccb94b9a8ccb664f71647d58b3c8b2bdbbffbc02d5f7").into(), + hex!("ae47b31c5b62b38ee886ee04945649054369018dd6543c91f0138464af489a32c1fea339e0e0cbe82e3e8b9f2ef3918c").into(), + hex!("b18c41c0f827f6d8656d3fb93c90b663eb2eac034923972f8842cb30e96c32842b3fbc1127930e1ba4322d5b6641f04d").into(), + hex!("a6d6ef51a361df2e8f1d993980e4df93dbbb32248a8608e3e2b724093936f013edabb2e3374842b7cce9630e57c7e4dd").into(), + hex!("a49da42c27d019a21cc6489ada7b712b98c4ede28ba25dbcfa916acef48446a2baf73e03a48be763378a09774d4a03fc").into(), + hex!("8b62902fb2855300580e94830a4bc825d997ede33bf356fe3b7c08d6a8bd85a37879433fc6bee58f9b44ca280f4e8dfd").into(), + hex!("af9d13103868c854821ba518907b067cfba025d739125f1e9cce0a04fffc3a2a1f25506c1209a0cfe1d6c1572c229ff0").into(), + hex!("8910f41db6952c25dfbf6b6b5ba252a2d999c51537d35a0d86b7688bb54dcb6f11eb755a5dce366113dfb2f6b56802b7").into(), + hex!("b551d1ce88cbf4ffbdcb0113a6e319513bd676d0078dd4e6a6f23ad336c1d0fb47a4e427bdedbe0fc8f152353971f81d").into(), + hex!("b8876bda1e709ab16e1347a1107852a7898a334a84af978de39920790b4d82eb0739cbfc34da1c7154dd6e9f7674759c").into(), + hex!("a7d9ae9621dd1f3da3cd2d435e891cc3579c4c0d60d6a4565cac86c315cea21a9ad883559fe7b897ae6e05f1aa989ad9").into(), + hex!("aac995a41c14d379853ef18ffc854ad62ad77061ca9bdf5029cab3d6c2630de114e777a7fc3322455939d5205ed59c55").into(), + hex!("999cec6a31d9b2f280017ddd59138014829fa34cab58e6c35a5014ec364b84712441e7a2f717cf2f0de8d5451e250924").into(), + hex!("b1f43b498cba1797f9793dc794a437500c3c44a8a4b59f9125a4d358afa304fc05b88ac31ed40b6eb68f0396b60cb7cd").into(), + hex!("93ba2e000bdb7269818d390bc4232992d280e69abebe2db2ecb6fcb1390d323238c9793574509bc1fa34051ac1928f07").into(), + hex!("a64808a2d15c30460651c200a09b50fc83e9d84d87abc156d06cee73b76fbd74e6d64424cb5bb83d3f16b21bdb7ae9d2").into(), + hex!("a75bcd04fcb44ce5cbab7eef6649155ec0bef46202e4eb86c88b4ced65e111f764ee7fb37e9f68e38067040fedf715ee").into(), + hex!("b95fc0ec39596deee2c4363f57bb4786f5bb8dfb345c1e5b14e2927be482615971d0d81f9a88b3389fac7079b3cb2f46").into(), + hex!("aef456af90354ff88039d2dde02b0f5a6790aa762b23e0a9da8c6ec92c3b8b3320687bb21666608b4a22615843afd1ef").into(), + hex!("b38be9ada17ced704a34a7498c4fd6ba2503f6bd886b693d4712267847efa887a26e7da5d60f8bc5014b92bca8b3a12d").into(), + hex!("991a7c93f06d50ec6a4340c6751b73eb5825bad02a954e44e1e2d424af928819ebbb590c6129ce35b3f1e908e2152f33").into(), + hex!("84888f2efd897a2aca04e34505774f6f4d62a02a5ae93f71405f2d3b326366b4038854458fd6553d12da6d4891788e59").into(), + hex!("941e2e3ba414a371a11c3fe92cabf688ff363da6230ec7c83ac7303f652a19ebc89cc494427c456d0c2ae84c72053f73").into(), + hex!("925f3bb79c89a759cbf1fabdaa4d332dfe1b2d146c9b782fe4a9f85fee522834e05c4c0df8915f8f7b5389604ba66c19").into(), + hex!("941c8962debd2756f92a6a0451a2bf7fbc01f32ed03d0823dffd4a61186628a4c3c7c482b18589ff65e4c449fa35c2a4").into(), + hex!("88ce41025aa153a94f91f22e7b96f9342b5e0e1d76274fc70c4df7d08f66d9f7ac86e55a1c6e77693b8b01b2b38bf900").into(), + hex!("8f142bde50abe4dac8e059003db41610436d5ca60d2dfe2660ecaa5f9628aeb8b5d443e1b57662076f77363c89a1479d").into(), + hex!("b2affe048c187d311a185503d8958cacbe03796edf79bc32e8533941004d9178bd2e376e627e1ba61ed43850c0c455cf").into(), + hex!("8f7bbaaac458bada6d852fe665c87c646133bab16c0d5136c3dc922095b9d647d93a9de7671cb7bfd4cbd138ae0709d1").into(), + hex!("b76f598fd5c28d742bc1a81af84f35f1284d62239989f1025e9eba9bece2d746a52f246f9bb6bcfde888b9f7b67fc4f6").into(), + hex!("a4c665a3e4e25a7af51e433c978573841bfa2c75c075e17dd1f43b2f0369249f3d3a46ff51051e8ce7da528b0fa98d16").into(), + hex!("81e0992e7c1c54c21cac32e36b90b25e1e5b72aac99c953c3c4d019eced64d7e316cbc0840204a4a51a4ad17d8b1d508").into(), + hex!("96d7a69eaf2761bf0e5ebcd607b134d5dedba8e262ca1d6d3e8fbf23e6419a8ce1bbe4cd23b9e4b5f80db54a802a9795").into(), + hex!("b2235bdf60dde5d0d78c72cb69e6e09153b0154efdbab97e1bc91f18d3cec4f660a80311fe6a1acd419a448ab65b18f1").into(), + hex!("838d5eee51f5d65c9ed1632d042bb7f88161f3789e6bb461318c5400eaf6728e7ba0f92c18e1a994aa4743145c96164b").into(), + hex!("acfbac397ae2ff23b31bb27b90788fd0fd51a50f8e8c9f4b31be8499194252014f0b1972b204aeb9c2836a20beb3c868").into(), + hex!("ad85789bb62b60e9768bd330a31a16f711b6018445af6a47646f318f12df8d4d256ad00d1ed7c3afa4e98fef73c6c610").into(), + hex!("b2349265be33d90aaf51362d015ce47c5ffe33e9e6e018c8c6e39336d9327ccdd13d25e792eb33b43ed89a162f6ac2fd").into(), + hex!("aa458aaca6ecb43b6e45ea72d02682e5a7dc8dc22782669a0628e1638e73999319f011803f4ec8cf072467bf2c49c629").into(), + hex!("b9e6c9f2562e90bd3008669a42151538b70faf028cc5bbc09fd6ab3febc626df911fcc65744a2ad793ecaf3f91a1f701").into(), + hex!("a37185bd96faa526dfd3ddaff89b1eb29ceb4597bfc7e346bff9d6b3225b9ca87cbce0db94f05243c7232ead5f6607e8").into(), + hex!("824fde65f1ff4f1f83207d0045137070e0facc8e70070422369a3b72bbf486a9387375c5ef33f4cb6c658a04c3f2bd7e").into(), + hex!("b0ed68167a67490bd7d7d49e83341606d6e6fdd99b82e46747c2190d270719f81c5f5f8733646c246260f438a695aa3a").into(), + hex!("a87c2f13f2a824b7e2c39cfb63ca7b94ae6a11ade0c6b8e83f5092b933fa8b6157a5d2f09c23081f49d35cc85f5db36c").into(), + hex!("88f5e795cb36ab22bdcff01caca0e9d04db463c3d88cf656c3a0e0f5ac864b7092c738758b4c8f3b65e31995c6aaf267").into(), + hex!("ac66f3a7041586ac1576e33598f01921e16d99afbf4249c3350f0ee1654de98bd37a61c243eb6a18a942db529e36af0d").into(), + hex!("aca69a4095567331a665e2841210655636a3273d7b7590e021925fe50757617898e1883532f9cfd46428c2e3d854f9f7").into(), + hex!("946d585d7aa452d37a8c89d404757c3cce2adf2410e18613483c19199abd88f7a12e206f87a43f6009e42f4e31ed20c0").into(), + hex!("9722c1079db7e2e1c49756288a02302b43b8fd92d5671585ac1ea7491123742a2744a526c12c9a0b4c4a80f26342a3a6").into(), + hex!("b80e8516598c59dddcf13fdb7a42d8f5a52c84e01bd6a39880f4acaefe8e4b8f09cc1b1a2423cd5121f4952201f20078").into(), + hex!("85bca2f86423a09014b562f7dc613246bedffdcb3aa41fee02270c13e6b00c8d6704dcbfbafc5997df6a90c7fc08c29f").into(), + hex!("a36dad4f7cba9f4cc843fe40f6240e1973a4c412cae29b4a68712598523cfaecb05272fc47d30772bf06906b5a26e282").into(), + hex!("a3d8610c2522d330df02511710e52b1d9bdc9f2b156deca12b1bf754266caeac4f449ed965d9863558df43ce9ae65a44").into(), + hex!("b3e313e79d905a3cc9cc8a86bd4dba7286fb641c2f93706adb3b932443e32eff2cbed695beeb26d93101c53d5f49d7db").into(), + hex!("88d8a32231ff2bfc39f1f9d39ccf638727b4ead866660b1b8bfbdf59c5ab4d76efddd76930eff49ea0af048b2e396b6c").into(), + hex!("a90d9502a9785e55c199630456fcb1e794bbeb0f5f8c022e66f238a0789998b126cf9911fd0b7d463b7706dc6f9ec128").into(), + hex!("8c627caf25eae6764501b9eff35aa90bd4f24952cad712aae20344579e83ecd104ad1f7915edc4f9023b17fddbdb4cd7").into(), + hex!("87d4b20bbe2dcd4f65f4e1087f58532d5140b39a5288e1a63fc0b7e97a6a56946eafdd90ba09300c3d1fef6356ac6b7c").into(), + hex!("a18f4464cf5cebade8ee280fa00e0917cbf1743aeb0dacc748ab68773b909e30dc60f40fdef3041b5f082e650985f7a6").into(), + hex!("a6ae4fd03fbb4e2150795f75a241ab3a95c622b4615f553bab342a1803b86b1c1a2fc93bd92ee12786bf2de22d455786").into(), + hex!("a89bc7548ea245ce9556eeee3fba98a3256f87499f54a7c5eec0c43b9fb4ef2fe8f6810867ed0df814a88ee100c245af").into(), + hex!("97f1a7370b4f5acf83b466f519da361c366915f560385dd7eff9d53700ad81b25c9862bc71d35428e82372a5ae555ea0").into(), + hex!("825359cfe68ad6a75578a94be6419179e0aa088170b6c20fc5c249dc3be7a260d687c93d8d8a343c7c72c2ed6a716de3").into(), + hex!("aa9b9cc039d147677aedd1e47ad9013fcc0da0164070ff7305b18e5786c7fac0471368637a3adbb78f3af174a5c1592a").into(), + hex!("a61687511b627bde7b3977e9a34cb7fddc2aaa509a7b99b6b6c7b97133845c721e1e69f99758698d82cca265d8703610").into(), + hex!("8853c582e86cf916750d670a621246a63c7fd78f68c556642053bcdfa7937de58885d728209736b7d5521b591387e9a7").into(), + hex!("82b8c013f24fe64b8e0337ae8b6a682cae336b8404eafc1404744f80f765efdb8b2873d1d3f31141e8dfe4d93346ac56").into(), + hex!("866ec39b9eda580d96bc2bff76af5cd4887b6788675149ab33bfefe38db82ad01b8d64c6b60704210918f3564cde1110").into(), + hex!("81337ebe90d6942d8b61922ea880c4d28ebc745ddc10a1acc85b745a15c6c8754af1a73b1b3483b6a5024b783510b35c").into(), + hex!("807c510df25c0ba10d4aa06a462e02f050c69a977c64c071401ab74f9ac1e60788aa504743b4cc1982da835ff9ac2541").into(), + hex!("96b1c82b85cdb8a7026fd3431bea9cd008f0261ee7f4179f4e69a399872837ab836a14e2dd45f5448d54800a4ae7c7f2").into(), + hex!("a48b1031ca2f5a5acb4dbdd0e9a2b4e9add5ccfc0b17d94818273c8df11e825193fade364e0aec10f1ff91d57d03a52f").into(), + ], + aggregate_pubkey: hex!("a825959280c88c6716f6df807204feb84d745dfbee3cb3474ce81a1ef0c4cd142e5ca962a0335e68b7b4266769d631b8").into(), + }, + current_sync_committee_branch: vec![ + hex!("bcfe80e1d24fbdad7bc058b011403a4c26cb56967654494cde51517f888023f4").into(), + hex!("4710ae46156553fee6231622052f7fb2f6945cdb59a5501cef824b1925c87445").into(), + hex!("6df62e05ef3e1ac92c659c3a519b8fa651d1b649c2b46fda58c48cdeffe8337c").into(), + hex!("d26ff22ef5958a707a8d98eb1ffaaf1f9f412e816c04b79f5434cb1792ccf608").into(), + hex!("90d5e61f0af673ab4d8b3ab0b978d05142a8295a163b198e6dea9d8c8f1c6d89").into(), + ], + validators_root: hex!("d8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078").into(), + block_roots_root: hex!("5078f286fa90b88a09dcccd4ac72f6c3615b77c0ab3132508cb8c0c07b20282d").into(), + block_roots_branch: vec![ + hex!("558b658b1230e225ac3adce3daf0b066ed0484b4a768d55b74ba81579ca0e5d0").into(), + hex!("2cbb27d38065ff3f230247af918e67d1998b67bc7e2ce6c244bab7146e16b8ad").into(), + hex!("c63bfc96585f424385e3b4b39ce46e957017b716c54d105eb7e07c841d1d4309").into(), + hex!("e662b38f57427b58c46b09980db3856f17e56b60b36bd5471823b0f2cc1b6467").into(), + hex!("8b3bd99618b1e50cf284b4c3b03d0cc272312bce377d585eded77154aa5580a5").into(), + ], + }) +} + +pub fn make_sync_committee_update() -> Box { + Box::new(Update { + attested_header: BeaconHeader { + slot: 4055104, + proposer_index: 1862, + parent_root: hex!("5f44df1f70338aca4b3046f9e5b144bda8b27276320ca000077389d0aba35317").into(), + state_root: hex!("9daecfedc819b45231bf93819a73efd4304ca79528032fae2e852ebbe514cfdf").into(), + body_root: hex!("a33f5cdc6732684e6f248e5a7636c7e7bf705f0bf709098a46ba15c660b4fc65").into(), + }, + sync_aggregate: SyncAggregate{ + sync_committee_bits: hex!("ffffffffff7bfdfffff7fffff1effffef7f9ffbdfdffffffdffbfffbbf7ffffffffffefdf7ffbeffdffef7bfffffffffffbffffffffffbffffffffffffffdfda"), + sync_committee_signature: hex!("880f147850ac0a94130b81f94203e2f69d512c929df8b954b6adc20cb1e8598aafadf366c074b590c0905d584dd980af18e0c8a837bbcadf6b4438507aa46ef95879c0acd9c2d273ccb13d93e4938e9c601f0dd466f53369ae94e1287955cae6").into(), + }, + signature_slot: 4055105, + next_sync_committee_update: Some(NextSyncCommitteeUpdate { + next_sync_committee: SyncCommittee { + pubkeys: [ + hex!("aedc2d47fa2662be6ab58ddd3682bd5e53f508162968fce8326c75f92fb3c1a25c4d4d0e6904f9b6cb1ccbaaa9dc28d8").into(), + hex!("8097b13908662d245820f3b045d8c2c665fe9a054e9c661323924ec86dfa713b36b0c787ad4dfdeb979318810e687a48").into(), + hex!("98aebd4bf15916512508a5fe89d814d5d76423c562cd3f0a0af504c8cde53be30f4df00e3ba0229cbf8528e198a0df11").into(), + hex!("86bba46d0031989d0f1baccea4174fc3fa0d595e60d35a464e86c33c233e2d6def84fced7a00f59afe397cf4fb5b67c5").into(), + hex!("845982c2672fdd44b33d2e56ad676e704c02f756b09e8765bea42b924c14724484567b55f0db42ac20cb70a7f5201c14").into(), + hex!("926dc729e135f1f0bff4662ee3d6823a64597fe189b763ada34f246e77705fd4e062d85506a338e9fa98c4d225a3b27a").into(), + hex!("b930ecc2a26183240f8da107e80979b59da4e05f090316d982815ed6151d7750490b85273187ec4e07eb221813a4f279").into(), + hex!("81564bee5a3bd09476f658cf7719326c353485e2f4fea58d110071c5dddd3cabc349a8d1ecea45d589ed4479952a2ba2").into(), + hex!("a66d5b1cf24a38a598a45d16818d04e1c1331f8535591e7b9d3d13e390bfb466a0180098b4656131e087b72bf10be172").into(), + hex!("b9b9b6113301bd2b409b71afa1ab9e31d22f84f8cb03badaa408e1d37032350094124e533de766622d7975a047fade6c").into(), + hex!("8eb3b3e3135720036c1120c4e8b8d405b00d002f2bdbe601a06f2c2fffb940a9966d18636ee34fc003dfef547d8f3b76").into(), + hex!("898deb30ede570d391266c81132a78239083aa9e27a9068e26a3bc14ff6468c3f2423484efb2f808b4996c16bfee0932").into(), + hex!("a90d9502a9785e55c199630456fcb1e794bbeb0f5f8c022e66f238a0789998b126cf9911fd0b7d463b7706dc6f9ec128").into(), + hex!("ae8af784224b434b4dfa9ae94481da4c425602097936623e8abb875f25deb907aa7530bce357786a26ed64ef53d5e6b3").into(), + hex!("b544c692b046aad8b6f5c2e3493bc8f638659795f06327fff1e9f4ffc8e9f7abdbf4b7f6fcdfb8fe19654d8fa7d68170").into(), + hex!("ac5c01c51dac6ee1cb365c9b03f09906d9b7b9b4d1b73c44d9e8e06823025d7070f242898a975420bc87d6372382cab8").into(), + hex!("a4632399c1a813e41fb2055ef293466098ea7752a9d3722d019aa01620f8c5ecdc5954f176c6c0901a770cbe6990eb11").into(), + hex!("85f7ae1a7a7c793c408750ddec2d7f58b985fc3cdf9fcf6b2192bc57092b8a271b2fb6ced0639baaffe0bec3203e568b").into(), + hex!("aaeb466f4316874c2107a0de38dafafa65ce50039c20723e8797815238011426f4e77e29fc573e7c6d2df85c1bbfefdd").into(), + hex!("a8fd63da16dd6a4aa1532568058d7f12831698134049c156a2d20264df6539318f65ec1e1a733e0f03a9845076bb8df8").into(), + hex!("93600f65c090814cee5cbd5f22f98e79c69e63510501a0be6a74b111e4c52441133fc1c198c7bf235f9005aeacf1d441").into(), + hex!("a69f0a66173645ebda4f0be19235c620c1a1024c66f90e76715068804b0d86a23dc68b60bca5a3e685cce2501d76de97").into(), + hex!("ac6e7e9960207138d5b4b6a7f061756c01cc4a830e5988423d344f23544ed0eaa790aed63a22df375768f670cc9b9bd4").into(), + hex!("93042dd42e56671155bb40d85d9d56f42caf27bd965c6a7a7948b39089dba8487d4d5fd30522dba6ba392964e3ffd590").into(), + hex!("85bca2f86423a09014b562f7dc613246bedffdcb3aa41fee02270c13e6b00c8d6704dcbfbafc5997df6a90c7fc08c29f").into(), + hex!("9550072f64a48cb86bfa224d492be9a91e5a6c9def04b6a290b7a19d96981937d5a2c35de6515d1881bcb167f6e3d661").into(), + hex!("8d797819318cdf7b26405d1a327d80d4c289e56f830b28d4e303bcb019aeb0b3d69bfed58adcde8a2445dd5281b86af1").into(), + hex!("90c04eb3f3679cd630434418cb3a225a73254887692429960bd45b1613f85b2c14723cd8c7f1e875588ed82b7f5576b7").into(), + hex!("9953a7cbc152f101a60e3e381f2af17ebe7401e16ef6462d132b8f0f6c6a18837914a1299d1605f9f289b9561112f4bb").into(), + hex!("a9300a33927335f482dd0e44d0d57704ebeb278f732ae8301073cb7d5e457f02a0cb03268de71d284b8c23fb96947469").into(), + hex!("88554c83648ea97dac83d806cd81d92531980346b208d281fba489da15a0084fd4d9a00591d1ca67aad3c5793685d55f").into(), + hex!("9131874b09aa95ba186bcaa9e040fabc811b9c7b905b7dc79e902cf2bb5816d7ee39b0b55be609f22bc8c538760b2037").into(), + hex!("8368bb9b9bb2e17730c42ed1100eb870c88a8431601312aa8cb1e738cdb9ca2704dfd432cf1703c0db043259819631dc").into(), + hex!("b49379bbb9f954d2ef5574199607bc6b3aa2cc3b48dcc3745cc77406bba2a394929844fec1b87c4ce65cd0ca0f83062d").into(), + hex!("876afcd045c8a18967923733a3a43757652289b0974cd348238a693f30bb57f38664ecb97877a5e5f7d0185039a2bf54").into(), + hex!("8db19f6dd3789df179ab606508ca7e3da7967ad4340f630bda83df54c197d6bd3a14980c87fe10cbced7678c0c300ef1").into(), + hex!("997a91da55801acb6134d067ad65a9a44ead0b53d3871bb97b46ec36149d25e712d7230d38605479796190abd3d134b7").into(), + hex!("ab1abf9cf630d6cbcac0c503df44603142ac81acd647784ae0e8fc97800ef04378bc9d7f2087f959ad4bbbeec65b8dfe").into(), + hex!("95718b06017ba9d45894867fd67148645d25d9db2229aa89971f444641ba9db4c5c6f0785f3b25cf2cd7fadaa6adc5eb").into(), + hex!("8ec38c68afdfb6ba019204039c2fb49a35467058f561f626fa87314d705fd615a7b9966576052be1b3690028d3c5c7bc").into(), + hex!("a5d72ac4cdcd847d67cb5a68c6141cde99a91303ca84165bbdc6fd7f643422faec783de60739e1b2753088280c90a68b").into(), + hex!("a778da56ddfe4a383816b43b027464d7a28689fc4a6b35b36883d3f36d9c41f0177bdbfc8f258afe8da90f02d3b64fea").into(), + hex!("a2ab566033062b6481eb7e4bbc64ed022407f56aa8dddc1aade76aa54a30ce3256052ce99218b66e6265f70837137a10").into(), + hex!("b9c347c1c350fb7ef6ee9ca6780cf0604f30e3a74e9d0234bca6b3e7faed26148f2b736d9fbff6b04f5b947fda458e8c").into(), + hex!("815f53751f6d3e7d76c489f3c98d2b49214938cac8c2b417e2d17bb13446c285fa76fd32a97e9c4564a68f4faa069ad2").into(), + hex!("b3f1319ae34ad1d59207288f01d3d7b7e1bad7733fb4a819a09b011d72a4d736bd3c7afeb74cf56da0e00cf712042ad2").into(), + hex!("abbfb501071148e98b6aa56308197356fd993c93e27fd58987eca82036c1ae0ea89f9fb1a06c82851234643904c58453").into(), + hex!("a0899189bba608887c6cb729580e570ecce9ca7107865ebd30def867afaaa250bac407c30dbee11b7ef6cd423269a8fd").into(), + hex!("88e7a12a90428bb45bcf4b01442c11607433211fc2f9bee9545304eb66e0b4b5339360160bc782e185391385da7c5ad7").into(), + hex!("82714b00a822c30b317ffc1d4ba163990cc1ffe5769f91906a7f71ad1f62b39865a5314433a4ab2ba762b1d62b01003e").into(), + hex!("a3a930dd70aeeaff0f2e3790927d5425db40467ee106261615de5fcb937bb1621be213ccd8b3a14d96c5908bedc2e421").into(), + hex!("b2902161b565dd5b8e8c54187b26f01741a39ea8bc1120598661bd367cf8fc73e21eda2f0f6f9ba2270c80a59ff5985e").into(), + hex!("b77cdf45f39bf85ab3e8c8afa602f159de8352188aba5378957d468315a2d2326daef83d8ac6b227f1e7a514488afbc6").into(), + hex!("a9e573274f5a131d6c7641bc0576a2621b6466a5bf2cecb21058160a854b1b9e0be176da2b6b9b3ed562fc36c5f09119").into(), + hex!("876561bba29e656b7122f1cb51a02dff1ac7d470217d8a4799c01e61816c4660eea91843a5a42502ddf842d2daeb0586").into(), + hex!("a0ebae60a998907a19baa396ae5a82bfe6aa22cf71bfca4e1b4df7d297bd9367bbeb2463bda37aa852ad8fd51803e482").into(), + hex!("84a6edac5ac68a7ca837c46d5ada8fab136748b6c3a3b9165dbbc231ec386b15328e4ef7d69a15d4cf354135348a4ee4").into(), + hex!("8b476b3b065a3b95a3d11ec60a749c2258ddcc5885bfb50b8a086d3fd1e49ff73e1dde733b8981c3d2d206aa0c87b09b").into(), + hex!("b48490c5a3bc9e66cdc78994f7c73e0f2724fec8a304b4147799e5142396df155ef7c42065ed6d2c0393d138fb4d2a0b").into(), + hex!("849ddbdc3ac55ff22a3b2f4bc51892fed694490ab4dd342165ac38c725c8b38921eaefe3c443962925fc3726aa41e236").into(), + hex!("b49c45d9da4aaa64967c28f1fd77b7f709f5a331b58823eb1613856fd8f92635135981830a287e8dbda3a0e0fc481c5b").into(), + hex!("93ccd8c5f82374e0bef6562e16576f742d79b6f400e3485ef36e148088b61fbd882c3d2bb38ab0b43fa1dac77f31d543").into(), + hex!("81522576ae4ec9358f1a16934cd1c1116de609634e68f552924a972101eb7215f037ab8e0582d7b13541537d55554d31").into(), + hex!("aad60e58a19598c5013b37e2e4adc6721eaa7e6e184960d1dc4e6f012246abbb58a047c0679064d5eaaaaff02de881e5").into(), + hex!("b4f034f2b53ff9989e8a0f12c1484c58ed7942432a429af58a6659feaf23f7d2bf20ff7b9a7e0a28a2e09c9a730681d8").into(), + hex!("88b2c68b425269850c1a4f4608aca194da5c641adeb99e2f7fb92e34b8245dff066e73bde072be60f7f2c3d3d13de3b6").into(), + hex!("a749ab53fc2662a0796489be84fcfa59bb723ff748bd8980df0cb4b3d1e2943845b0d7c67576fa0a33c8b0ff8a86932d").into(), + hex!("abd7248ae069d3a3a45b0ef4dd5d7d54b62994e578ea20bdd3b7876596673953b94c5b109a6e4b953b517544b915368f").into(), + hex!("a49da42c27d019a21cc6489ada7b712b98c4ede28ba25dbcfa916acef48446a2baf73e03a48be763378a09774d4a03fc").into(), + hex!("b3c36fa39f668bbc3fec028875a820057dbf96f727bb423280da96d5d50e885d23bc23fb73457bf79089691ce7663a7b").into(), + hex!("8dca376df4847cb8fc2e54a31894c820860c30b5e123b76670a37435e950f53312f089a8e9bd713f68f59fd1bf09202f").into(), + hex!("95d1f944b0c53eb3e9fcd5632713602bbb9195b87a172a370ae2df98504612a55f3968615a39b569ce6a0fe9fb559be7").into(), + hex!("8c9fefe233d0d657349b7efcdc368f5aaead27071d224af780874751e7d241f6b88f7650fbb4133043b24bbebc12aa48").into(), + hex!("a2ee6c29efa982e9b9abd3c5e4f14b99d5d0369d7bfc3c8edae1ab927398dc8a147a89e127b3324d7f4e3a7494c5d811").into(), + hex!("b7ea5e0d3cfcf0570204b0371d69df1ab8f1fdc4e58688ecd2b884399644f7d318d660c23bd4d6d60d44a43aa9cf656d").into(), + hex!("a07826925f401a7b4222d869bb8794b5714ef2fc66fba2b1170fcac98bed4ba85d976cf9ee268be8a349ae99e17ac075").into(), + hex!("b0a47515752c15e4dbeaf9ee27fab3b5c0db82f5c685e8f716fd7d8764164944340430fe3db1a5679e6ffea5a16dd919").into(), + hex!("b7de6d7a4afb05984dce153e5570b104338265e45c8f0156f4d45c458f47add234a479e01c02d3c1817c170b5b65b100").into(), + hex!("acd4d1e11f81f4833353b09d4473ec8b15b8ff31dbf39e97654f5338a26c4020306d51018f1f4b9c4efdb92992408a6e").into(), + hex!("80e09f3bf3ea87d48e04b53d8f3b43b7e53d61f445f8c8a5a35472b84f6bb4f58f17d9832f5881bb44fc06156151e5c5").into(), + hex!("98d6d46f603afebcbc561c130e416d5a588a7e6c1f17f89ed6e30538b7f8dbf4b3c75b8a3331425c4ca21e03fe8b57f3").into(), + hex!("ab671eb947490c43fd05e42a787344b21af89babb705393c82748eaa0cfcf80bee498d275a1eaf1d647ca3b2923d76ea").into(), + hex!("80e1dbf3296bdfa98aeec1a7560682165d13bc628061bd3257f345aa1ba13f8bd1bea14f117af562be22118f5a8265af").into(), + hex!("aef456af90354ff88039d2dde02b0f5a6790aa762b23e0a9da8c6ec92c3b8b3320687bb21666608b4a22615843afd1ef").into(), + hex!("a5a07bf219432e9c80c38596c93560b49c7de287f31e30b7a06fcb4d15982add4a24085adbc5b753c462be989c64c96d").into(), + hex!("84d2eb008578aebd6f01254b7e46584c1524e6fd7a5a2ae5fa0ea560865ca50d52290cf2d12dd20b042f402e62181b4d").into(), + hex!("b8e5226ad3515627ae6840235f5f7b7ecd54e8f01079c324d126ec852f6665ebb77168b3f2b3b51580e04a6ff602d5b3").into(), + hex!("8c1de4264e04ff7e8282faf81c0bfb5943656451be52170211cb7adf4ff21bccbb789400735579c622f69982fcb8e9c6").into(), + hex!("90bfbe37ac3992432e68c95c0d4342a9712126d1f50089239c9f4f6c0c202b54334e08604d245b97dc8e8f6706f6992c").into(), + hex!("b0a771b9a0dd7e352d46c8efcc1834e610dd097711bf7117678a99d386890c93b9b901872d4dcacb6dcbcf3aea0883ea").into(), + hex!("a4eb903990bee2374b14fa66fc262d6821669537e9ba241c87b4b5c9e2b89b32fff4bfc28ab8471ef52e8eebc3e743d1").into(), + hex!("a6b74c706b33d3cae9b7adc5c7502ac98f7bf94a14d579d2bf77b613ae555634ad6fe631ba36dc14bf44526436355e24").into(), + hex!("8296f8caf58316af535def398a43357e48cb3b1e674b857eba1bd1b970da3dd045e22fe6d17dee4e9117f62ece3ec31c").into(), + hex!("a129c9cf33df42b5a98ad98be9d940207ae154c715d3bde701b7160dfe45304679fb0481a4f9dde242c22a9849fc2d9c").into(), + hex!("858b6f1bd3e68fc536bdf1f4bd96db032994eb76e71571e2d85af73b898478b82f9ab432732b0beebc0864ad8025ae33").into(), + hex!("8658a15df961c25648fd444bdf48a8f7bb382d9212c0c65d56bf9cdb61aab3bd86604c687fb682260dbc0ad2dc84bf01").into(), + hex!("a8d152e5d94b75cb9e249230db21af31de4d4f3d4ef60ccbf2212babf69aed2a38435a993ee2f13cca410ad55a4875ab").into(), + hex!("95757096c132e7f6c096d7b93a5a0d2594d5e609b9f13c4a9f878e95a389fa1a111b185dc1fd8f7d98b737dcf8d2af60").into(), + hex!("a22542a4a2ebde18cc6aa29d5dace8b4f6720703f519610dcf01e671018392aff15728e3764730840272c9cfb074b612").into(), + hex!("8f90e72a54e6894d511061957162e753010812346afd4d90cfedb678b99ba1aacf2b6bd0e49b4b0e684da8082a048619").into(), + hex!("b2affe048c187d311a185503d8958cacbe03796edf79bc32e8533941004d9178bd2e376e627e1ba61ed43850c0c455cf").into(), + hex!("b549d272a7f3180826a978d747507e4dc80d82784abb655cfcd3a69cc72e7d58c70febea1ce002a89852a8f934ea70fb").into(), + hex!("a9ef845ab489f61dbfdcd71abcc29fc38f3494a00243b9c20b9cd0dd9e8a0f23304df84939b9652cdf5542d9b3ee085e").into(), + hex!("aa744c552b5fc41e1ac6ca53184df87a1b7e54d73500751a6903674041f5f36af25711e7bc8a6fbba975dc247ddad52d").into(), + hex!("a802b9ffbd4f01b877791aba27da972be4bacacc64a1f45687be4af01b84bd4b83fe2ba1ea78e29d7683f6c777ab2543").into(), + hex!("b44d2d9510516c0abb4fc101241cf0e0223b179fb70686519628c27f0ef56381232961bc79a30f592ef093ffecbc4486").into(), + hex!("a684a09add047c0fe648d9c5618500d1816047168e055e8ac8c952c3544a462cc095b32fab07d939947a58fcb4ec7ba7").into(), + hex!("b5eb31e5cba0193e74968099ace5808dfc457c6f404f270fdc4949b60daa7607ba1811abab1bb19fccdad61d489b6657").into(), + hex!("a10f19657a9bc5a5c16ebab9f9fddc3f1d812749cd5d80cb331f51de651873ff899e0670f1b079b29a194572de387a17").into(), + hex!("af61f03e3ceef5bef36afa29ba2edc7a3b01ca26cec2589edbc9d124dd46e41410e0e3afbae959c83a6f839bbcf8049a").into(), + hex!("8e6bbfe492ecbbb8dc8889d3dcd7037a58db605bc6bb79131a72a9b9c1bad630e75f5e5e0c1bc407e73f3d13b116739f").into(), + hex!("983fc1ddf17f9756c9cecc00b39bb2ad432587a5c6d1c3296a383b9f539c9afe84c6c818447a709c0b686ba26ce5ea3e").into(), + hex!("8d52413f981bc611427ad0534d25e914113d0ebcd6960aab6421608bec6648b89ae4b2ca2153c57d3cf4f1f37212aa5c").into(), + hex!("ae075b66e5f211c2149c45b211d1297bbc1d9e6497cb3315363c492a9a51ae5b9d0a28bfecd755d68553736901ac6606").into(), + hex!("a02f7fec0661394399a82b2e3151009160b3f5392017ba579b301ed42c85100c295acbfed46b6c58a9d71796ed0930e6").into(), + hex!("a3a7196fecd25e9cc7cac79c35365676e48c7be1493df255676adff2209c0719f2190ceff3ce008d08efa07c244c11a6").into(), + hex!("a5fe3dfb5031517bb8db0d5ade1e9f438e84bcf23221de003b03d2a2f4ea97629e81c79abc3769bdb8c69a512c189b91").into(), + hex!("8cd9d7e953c7ae07ee785d68a999e702565960d376692d9ea468556ad141229b1f3bc97926818c078901f73ecc578e93").into(), + hex!("81d6fc2f01633e8eab3ba4d72588e14f45b00e68ab887bdd4ec5e8558965db21189310df973837106216777b07fc0805").into(), + hex!("b75ac3d5b3dad1edf40a9f6b5d8923a81872832eb3a38e515539cec871a353b07cb477f6d55cf15ba2815a70458aac32").into(), + hex!("94d3c9406dc6dd7241a726355643d706e46b35f1ffe4509ac43e97c64c07592821156ba02ec9a78978e66709995a0ac8").into(), + hex!("a3b109249ac2900806f0f39338da72d4f2cc6d1ac403b59834b46da5705cf436af8499fa83717f954edb32312397c8d9").into(), + hex!("8336744d8ef3a3bb3e9ed3d6b83e08cafffc76b7438adedd3a7358b32acec0e73a4635aa3166362ab4e158e68576255d").into(), + hex!("99b74edbac662fff69ba412de466a427a928ce2363c9e59dddd664f6fa50f2e1dd3d464701b01784aa224b3d96dedea3").into(), + hex!("b397ed7134f447d9bf1c511bf92f2d27d7b6d425b8b411365fbef696cff95c2175461cf5dd83d93bb700e50ebb99b949").into(), + hex!("a3e1fe11f38d3954a7f48c8b68ff956ea0b6f8a3e603fd258c9406ec2b685ff48241db5257179ea020a83c31dc963854").into(), + hex!("949cf015ce50e27cf5c2ff1b8e2e066679905ac91164e3423d3fb7e05c64429e77e432db0f549acb99f91fb134b6edad").into(), + hex!("a1c0c317e6e352e16e25c140820b927161ce5d2c4c2e10bca3057ba4d46b4f42ad7aba20de86dad9fc6368ea92695268").into(), + hex!("8d6e3df29419bd0da1deba52c1feebe37744108685b49ca703e1b76fb4d612e3959d3b60b822506e5c0aac50b2f5eee2").into(), + hex!("a15e0cb96a463ab81e661ca44c619b71a159680bbc04707ea5a5867ff38b15416e3abe55d2fabdab9aede1f157dd37e1").into(), + hex!("b6d6482ad7b9b412ffbefbbdcc28eb3d091b1291f54f77bdd53c4ac85f705c454940f466dc272dde7b03c26f0cd6ecb3").into(), + hex!("8391e3ad6ec2686bdc686671d579edac2d5efa8cf0923577df28fe0735e4d5103173d44452816e3c2b2a7fcc1fcc20d9").into(), + hex!("818202d7cb60e4148c71633ccbe1ce311de7b7ff93a1988e86ba29cc58037189f0f275b3323a6719dc9bdcfbc49c35c3").into(), + hex!("a7c0fcc422c6da878926cc6763ae6ec685a5d8fd1afe61269957be6bfb3f1705a8e4c6e6d85bd15636521f5a2ceb3a00").into(), + hex!("8f7bbaaac458bada6d852fe665c87c646133bab16c0d5136c3dc922095b9d647d93a9de7671cb7bfd4cbd138ae0709d1").into(), + hex!("b6e9fe9fa3d4c833c3beae7f798f30f07e3cdf6f6c8eb8e2b70cad51b37af2549dc9f2e7f97f194e5897d4dedb904a45").into(), + hex!("b455f751232de0a48440d09983f4f4718b6169907979c9f282acf7177ab5b1f338fe1f2acd8d0bee4b4aad61d0340839").into(), + hex!("8aadfcf3562f1c357068323352cb1745349a27a7362358d869e617c2410db747149b993ee9e881e252ecdd42fd75f351").into(), + hex!("91bf4c32fa8888d3829d3c33e12550d2ecb70762d5eeecd044d4902e4a7f8b7a2592cf6cb7736eb6bd9d312f85c2777c").into(), + hex!("859426bf6211e68924eefdb26cdc168ac0deab291aaff7036163997bff34d45809932f91e12d113784c05553ca773b15").into(), + hex!("81730b4bc5f755e5b99c321a6996c65e57ea2ebe6c0e4e404ed30920194fd76db65304635ad054a8b25bfd982cead47a").into(), + hex!("b26f5ed09f7d5bb640ec94ddd1df0b76466f69a943b4699f53d45296d5d6b8010bb61477539bc377d1a673d89074d22f").into(), + hex!("aa65c11071be23c9bddaa5203f3166e5cf043efe5fb8f4b26f8a9cabe71db701a450e79eb001c401da5752755d9cf1af").into(), + hex!("a019370ca799c2c98a605850910cf43531bfb616393039fdfc370848feedd3339b2427b750ccc91952b03a09f690e9ed").into(), + hex!("8f84cba7ceb7652023fc8ebde4b00ecde1f550935bab12feb630d6f49517b4148f3cde184bf55d4f6ec99a849fc6f862").into(), + hex!("838733220d1559c800cf1714db8a43a67a0c0d1d3a9fc1e2cdcf615d20406501e5146fe8b59bf64f4c5daa1a6d74f15c").into(), + hex!("9708cfcc9ff95cf23f544119e17518a338575018f153b1ef50118da0681304919a226b2089a417c2ab7b4320dffafc2a").into(), + hex!("a988cfed9f481bc98beb5fc188ed3f6893a3ebba27c3ebace669792f6abf0997727023c3b6930a6421224f5b257b8b49").into(), + hex!("812d3ded3a3c9e58eecf13a29bb4cc13b01b2a0af322423a29bb0e4f6d9021d1d87ac4af7a2a6b88d34f44a8bc1b3c55").into(), + hex!("b2baa7eba496ac4ef60ad8ef27a9677f9507820d95a1c572d322621c4d0226b36146bfc3a9ca1645d123acbd945de3f4").into(), + hex!("89ab1e5c2565f154f92c9b3554160832d176613f1a2f872b6ed62ed925a33fb0b40b71b7443eaaa15099ab24693c8d13").into(), + hex!("8982534f2c343dda20cccf5a9c8bf98240bba5f4e8eb2206e63a1847097deadb6bf0d24b358014d564c5ef1d0448c43e").into(), + hex!("a1e47798a782a024da340d6d6a1b1e5e15a0f2d8668adf349ca375086964414a563cc1eea3226ae637f87e78c0a630b3").into(), + hex!("847b58626f306ef2d785e3fe1b6515f98d9f72037eea0604d92e891a0219142fec485323bec4e93a4ee132af61026b80").into(), + hex!("8368a0f17c8427beb71dbf11a09a2fe8495a33f08c29c74a9a996a88aa01c0a09f9555abeb1ef1592cab99a9e05875cf").into(), + hex!("b38e558a5e62ad196be361651264f5c28ced6ab7c2229d7e33fb04b7f4e441e9dcb82b463b118e73e05055dcc9ce64b6").into(), + hex!("8018499ef720e28759133033833edfe17ed23e42f99058bb79fe844ddee823cfdc43916be2dc9724d18f9726e6f1b409").into(), + hex!("aa9b9cc039d147677aedd1e47ad9013fcc0da0164070ff7305b18e5786c7fac0471368637a3adbb78f3af174a5c1592a").into(), + hex!("a5c0e42851b769d2d822e39222e708068455aae3bdf782975b59d3201e67a58fd66e16d380558bf2086bcab890a92dd5").into(), + hex!("af3f765fd293c253072b33a780ed68933f78d7e079d9a2079b6232755bedf6ebcbce9ba65c01f695602fa8ee17899867").into(), + hex!("8a0192ef0903d7a5ed2e5614a715901f2554b324ee72390974dc90727ff08dafa580041a21a8e6c48a3e08e1b042afab").into(), + hex!("907c827a4fb5f698bf0e6f10ca07741c5b8e3ecb26aa53f938ba34ceb50c01be80c4afc5ac4358a5fda88eadea0cbe73").into(), + hex!("a35ee5c2d7800489723c78008b495e1742f0542dbb487172ef438f60424c81aa41c2397095821248066140662133f6f4").into(), + hex!("b1925ee53c9228cf80e2f5ac0117008a91e98d878f69bf03d00d873ef45f4351cb6988772d89d4ccddb40778d11e0dd6").into(), + hex!("95aafa379cc6a2b4bdd0cad30b7f0a47839952af41f584219ec201c6c4d54610eb2c04b67b29080acb8cecc5e7543fbc").into(), + hex!("8f44c43b80a3c5f488118859fab054745cfe5b0824821944b82fcf870fda6d93489ea9ca4220c24db2f4ad09c6080cb7").into(), + hex!("af861bb21f84c3e7cab55370839d18ac24c475a9e833607fcd7e65c773ee9d64bea203ee9e8fd9d337f1cd28d5ca0d90").into(), + hex!("8f6fde2ebbd7682c69026069cfe93aa5410071f05de9ccd7070c8c3299a6539b39b3798f01a0b4e9b1330510bdb51de7").into(), + hex!("a35d9d6d5dd5428cce7616842203b5fa3721cb4b20f50c0113f138604954fe0cf214ca3d065b578f921054b9efe823df").into(), + hex!("8d562d6c0e0d8325032e1fbf836022c82a8f600a6fbb56c553ee5d1fac0f052c7ce2504c0fd48c9fa6494a6bff63c9fc").into(), + hex!("b02ce594310f1eb8acc92bb80de524a43e663e12fb64fc28291ff207f9d8ae761631416410c3c8f4d6890b8b7e6ed24d").into(), + hex!("a258f8c0eff666c2bb70e505544c3d10d6b258310e4fb2206fd0999f69bfb739a1e232d1e810e7206f490f6c44f6934a").into(), + hex!("a8a77936ca91df3b2ee7394ea821f2bfe91c6ad8193f44651466c170b6ecca97ab356fa7d947ebb4b767e8967092f143").into(), + hex!("88ad79a0320a896415e15b827a89969b4590d4dfa269b662bdc8f4633618f67b249f7e35a35884b131772d08025bfc32").into(), + hex!("a3c66439724d737d20a640bceed8671b20cf6795671b6d442ed1ea5eda6723ae559396c24f44e982ba7751dcc6adef5c").into(), + hex!("8d0e6475acfa2b904e7d53bc7acd070a2ee4894ff5720a20e560e9ecb7872ea442a51cf2f2eee4bef66604a5c08ad9eb").into(), + hex!("804c021152c3304853941847e80480fdaceba3b9676fbe018268cf77d1a1856966c2f9686bb4d4aa0c4118a7e85f83cc").into(), + hex!("a6565a060dc98e2bfab26b59aff2e494777654015c3292653ecdcefbeeebd2ce9091a4f3d1da10f0a4061f81d721f6ec").into(), + hex!("8d5de60e934ea0471d9e0a46489f21e03abb9722f5b3633631a9a099b9524beac5d67716969c83d824498796d9c106b7").into(), + hex!("8c5a9f6eb0a3ea95e75362b06e5cd23968447a212cf22e1419c984d74432c51d290b717f80e8ed3e76b1232216f99758").into(), + hex!("918ebb73eef984d0ce28083306626d04817038056aab4a82ff9ac8176ffdfbf3173c0b05e936daf553248b323fe54f56").into(), + hex!("8f9aededb605db4e499d3c383b0984b1322007c748dea18dc2f1c73da104a5c0bece6bb41d83abdfac594954801b6b62").into(), + hex!("adb198f70a7f1969ed0958be4a9a60dcc1806bced79c63692b9aad6c5648ffea1fed60b24bf4b1862e817cf229e93e83").into(), + hex!("b118f77f99ac947df97e7682f0fb446175185b842380af4ee7394531e4f93002c72b41a57a7c1b923a4f24b10924c84f").into(), + hex!("944f722d9a4879b5997dc3a3b06299182d8f68d767229220a2c9e369c00539a7a076c95f998bea86595e8ec9f1b957bb").into(), + hex!("b7270f33011db1bad18e076a162d6e53d9123808609773eb46e3a4ac69c84c257407907bd5d05b6eb5e926b8d8c6d884").into(), + hex!("b09c0a505457c6b473fc7b2d634222905b36a6ffcc015dbdffa3bd62218c94e891615e77f28e6e18dd8474be8c156695").into(), + hex!("97d076617cf0a64ab3d1f030cfd72a303b6b252c0a7b96157ff7fc8af5970f00d14492c46e8f6f37caafe837d0dc95c7").into(), + hex!("b405520ef829a2a3b8947f1687ab56a7af4026c1a6f99f59aa192bc4f3b12a2de407862ff74ba1b2c51889b8d6b090c7").into(), + hex!("8bb045e7482b7abe670d72eb2f7afe4207b5a3d488364ff7bb4266f8784ea41893553a4bf7d01e78c99ed9008e2c13bb").into(), + hex!("b2df29442b469c8e9e85a03cb8ea6544598efe3e35109b14c8101a0d2da5837a0427d5559f4e48ae302dec73464fec04").into(), + hex!("99daf03fa434a482d9aa4d090884c99b7208c1f5380b9acbf304e1bc33d3d6902afa5d248d20ccf03795e26901356ede").into(), + hex!("b60df25a7ac1ad14aef7e8809c4bfc190b715f94f14b0534cc2e4015ff6c322883cbdc5309e05d67dca4bc641c69725a").into(), + hex!("b46a818f3e492e231d8fa8de8848c16f0d648a2e0d1c816adf9306a8596fdf45922e59cbf745430570a19e54f45e28f7").into(), + hex!("b3ca2ab7d64b71e40693bd3e2288a1f78741a139403c783d259cb9dc9c29f16c00796b6302cdcea4a4314e132b4f9d1c").into(), + hex!("af3d3dffbe55842dfb4417295a6ed1a82d26a579199494b305445215045785759be4cb57dc870c7ddaffbc101a854a92").into(), + hex!("b21785008910a949804d1291e7533752641d31beae3cb518806488f81d58c38a5efe5ed9534ac692e68c3121e2f9d97d").into(), + hex!("ab7eff4ef8696db334bce564bc273af0412bb4de547056326dff2037e1eca7abde039a51953948dd61d3d15925cd92f6").into(), + hex!("8bb4d08318386c91a0136d980a42da18c05743a5c52a861ce52a436e66a8ebe472dac7f7461db32ea5da59a23e9bd6c9").into(), + hex!("a1c84730a5c41dcab9a5ef9e1508a48213dbc69b00c8f814baf3f5e676355fc0b432d58a23ad542b55b527a3909b3af6").into(), + hex!("948f808c6b8e3e109a999657ef966e1e02c96a7aae6eecaf912344e1c7bf7ea51c911cecd3cea2b41ff55acc31df9454").into(), + hex!("8d264fbfeeebb6c4df37ff02224e75e245e508f53fb3446192cd786ecf10d0f704c4fc2e53e7f7318ae1407e46fc0fb8").into(), + hex!("8d47a7c2c62b459b91e8f67e9841b34a282ceb11e2c4b0549883b627c8526d9e0ebd7333ba70630bc0ec2478114b6ae8").into(), + hex!("a4348ad30c12bb7dd03dd014cca599c3499ddf348e7795b0392a18f998289979478374e374a8297b5b6c427441e2b5af").into(), + hex!("92ec1aeb2aa24c51cd5f724972c8b6095e77b237d83f93ed34ca0bc91a1dbf1ad95adccc59e0f0abbfef33f331f3298c").into(), + hex!("941f73b2138b4347ecafcc7b8c3d03f2a54dc49f580394ed08f22b0878ee7cb63d42978f1d320c09e7dbc67648c06f8c").into(), + hex!("a308ed8737b3a9346ff20dc9f112efccc193472e6fde6aa218ceae11e288bbd2c35fa45c1d8bb238696a96767cd68b46").into(), + hex!("8eb03001ac9e22c6956a682ed458e650785c36d23ddbcd51ac4d9cc991325c02519ff1958987a08eb29ff56ff6e2c293").into(), + hex!("80637db55287f891baa0e865d2423191b9a575620bc4493ea76166d47b99fd89ad8625c21f446b01e3ae17292c78f7ef").into(), + hex!("a5b3da08aad945effdb645c797a0a8bfa828c9d658df2783a214597acebda3ffc07ee48d0ce1147d77540b557d9ada91").into(), + hex!("8d5e0b8cde1f62cc8f15d9f596e31de09c221da91b10335b92ef1155802e742442def161223333573158723f3408bbd3").into(), + hex!("931923f0c1f75a197e6244d67525b524ceb07510a6aae8cb3d56167cc1aacc76d26fadfa1bdfc55d8439c6ee4d4d8174").into(), + hex!("963a298fc8876b702424a697929c7a1938d298075e38b616c8711f1c7116f74868113a7617e0b4783fc00f88c614e72d").into(), + hex!("91ead7dacf43905eb5d4b179af29f945479ed074126bad3b5a2bbc1663af5f664fe53a36684e9389ab5819e53f1344fc").into(), + hex!("b8a6c999068c13fb71a99d75eabadf7edd2d32e28607baf001a0aeec412fdd3575602c68d3feb4d743b90396705e37f3").into(), + hex!("938bbaa0ba14597067ff4c0a7cfc1529c44160d6f61cfad12246526d84fb7a1ba964d3bbb065a348cf7a98356ee15234").into(), + hex!("80e44d3577f12cabaed7074feeb57162ff80b61f86cce8f41d1d1250bc455070b09f6ea9d0c263b7b4824701480f4c14").into(), + hex!("8d74f4c192561ce3acf87ffadc523294197831f2c9ff764734baa61cbad179f8c59ef81c437faaf0480f2b1f0ba1d4c8").into(), + hex!("a0133deca5ae8f1100df8db69920b2d0c31aa21bd3849dbaf4c264eaeaec8937ab8f982770ce1ea17e0e258910a56d02").into(), + hex!("b6a25d493d708b035b853f1f7a6628d8e0b205d2678293f763d7ea4da11d298539533b22b43ed2e5f708648556f3094e").into(), + hex!("a58c3a4ba86d0d6b81c8411bb73a528b4f3bc2debac0e0208f788c080a3a96541d57c927143c165f595070afe14b0517").into(), + hex!("a52c15840b89d92897d1e140b2b8468a88886c5e1092861e598b3a433b340ded5b35b3d632a9879820fd56f20ca3a68b").into(), + hex!("8c122bea78deee98f00a86184ded61c10c97335bd672dadddc8224a1da21a325e221f8a7cfd4e723608ebcd85a2f19fe").into(), + hex!("87a51e0011dd0488009baac9c611fbde01878f9cf1584ea407599742bb32ef10586d9040dae3e9800a125de54f80c047").into(), + hex!("98181e9291622f3f3f72937c3828cee9a1661ca522250dfbbe1c39cda23b23be5b6e970faf400c6c7f15c9ca1d563868").into(), + hex!("b01a30d439def99e676c097e5f4b2aa249aa4d184eaace81819a698cb37d33f5a24089339916ee0acb539f0e62936d83").into(), + hex!("830e70476c6093d8b9c621ddf0468a7890942589cae744300416639a8b3bc59a57a7e1150b8207b6ab83dafcc5b65d3c").into(), + hex!("83ca733849830cb8fc2ef469e7e464fd94def561ce49ff0aa352a6ecd0e52c7aefcd69ab59f3d1ed2d5b8536d0a7895d").into(), + hex!("b76cb8cb446eb3cb4f682a5cd884f6c93086a8bf626c5b5c557a06499de9c13315618d48a0c5693512a3dc143a799c07").into(), + hex!("8b027c14affe47f83ee59b504d83b2fd2d9303de2c03ee59d169bb199d9f4bd6533d7f8c812dd7a6f1e8155e3e185689").into(), + hex!("8e6b888197010ebadd216da35b9716daa8675d93b3c33a96a19fd9ca42624f6b430b2ff115cd0f5b717341605dda24bf").into(), + hex!("b6652440bd01316523feefceb460158cd9ba268dd8dbe860a0271f0176230f057767597e4197885ba907318ca202ba06").into(), + hex!("a0b3dff15982a38a2f56d8c6cfc5c5543c045bf2db24571d23387ccab42abe2756f34d5f0bf6a426bbad3c358b8bdb00").into(), + hex!("a8b593de2c6c90392325b2d7a6cb3f54ec441b33ed584076cc9da4ec6012e3aaf02cec64cc1fd222df32bf1c452cc024").into(), + hex!("96b478b1e5e49d4ea3fd97c4846ae0f781dcc9f9ff61ee022ca92c3d8dfba89c513c46e8bb38b73e6b678a79b9b12177").into(), + hex!("946d585d7aa452d37a8c89d404757c3cce2adf2410e18613483c19199abd88f7a12e206f87a43f6009e42f4e31ed20c0").into(), + hex!("8c432e044af778fb5e5e5677dbd29cd52d6574a66b09b0cd6e2a5812e71c91559c3f257587bfc557b4b072a822973a60").into(), + hex!("ad2cdae4ce412c92c6d0e6d7401639eecb9e31de949b5e6c09941aeafb89753a00ea1eb79fa70b54699acbfa31eda6b7").into(), + hex!("b504cb87a024fd71b7ee7bed2833115567461d1ae8902cccd26809005c4a56078617ec5d3fa5b29a1c5954adc3867a26").into(), + hex!("b8876bda1e709ab16e1347a1107852a7898a334a84af978de39920790b4d82eb0739cbfc34da1c7154dd6e9f7674759c").into(), + hex!("973dcf44ab60f55f5d10a8753ea16db9faedd839466a130729538f3a0724f00f74b3ca1de16987d7c6e24e9467f62bc7").into(), + hex!("94df5fe87661101a89b49091a3d4de89331cdbd88531ebb08a95f2629886ee53b3dcbcc26bb6bc68b443303d8d397141").into(), + hex!("a92beb343caf6a945990adcf84302c55d1fccdef96c34a21f2c00d3e206a9b2c6c6b412f66e5d4fafe26ef6446cde705").into(), + hex!("b298aa927713c86adfe0de1a8d6f4083b718c8be27156da9fd11abd8edb3a54a926ad487801eb39cfc9363a0a3be0d44").into(), + hex!("b34d4d2e15079e7e80fdba30cddf4fc0e6c9a61f7ab06a6ea0a4e55fd5bf632c6d72e021d6264d935439d321de883bb6").into(), + hex!("b4a86fb5b0049718caead1bc036833a2caeb88e1afadbbbcb0cd021d95e1f33fcc916f0b97fc1b9226c37050e3463796").into(), + hex!("b6cec65e5268818c82c0a4a029b02f8d23de98b68730a445119fee670118eb34027c23c987fac950f9b0151631328a4e").into(), + hex!("880b4ef2b278e1b2cccf36a3b5b7fbce94f106ed9fa2820cb9099a7a540a57e9fdeef5c0fb0a743049828fc2b8c46163").into(), + hex!("ab2053c376c6bd113b89fdb2ae3b8401aa891135345885730c61cac7813f69ea7d906c531be752e28657f73af92d1f4e").into(), + hex!("8fa2d7b22af8e6b82679ebdfa13efdcb34289a554653ea6c1b16efb9f957f7fe64df787e7b03d8cdc8a732b91c916bd1").into(), + hex!("8e825c03c8409a3302266dc5f47fbfc381dfbafbadc37bd8d40f079ca8963d4c5ae6ef0d0ba6aef2d4688736f5f6bb45").into(), + hex!("a40ef3d2291d8782540961ce285054678b3d322d3cf7fc154207228c290708b1abfc37a4d7762dab3dfea582a112444a").into(), + hex!("8dbe8fcbcc414eb352245c52549973f73d987012de9d5f2b2f55dfdc43cf8cc9ea6b147abf149817f80f9e15aea566c6").into(), + hex!("a7e8775e04214e3b9898ffb9625dc8bcd1b683e333acdceddb8ca6db241df08a7b80e9d476a711b8b7d66aefca81e9cd").into(), + hex!("8b6ed54668f78a4a7624683b9bf3abf2bb0b6dccffccd8c0967df6297dadaf51732800fb9832b069437a6bf82ed7e6ae").into(), + hex!("9437ce85146202d3815df7f341a182678665dfb74b96006dc9d6acc16110d00b4a02717b702a765566457710ff5a7280").into(), + hex!("86a790072efa2cafa97be4b6b31f8c533f3b20cf3922fc0285fd403da436e4c49c65c5f08d77bfe823526c67bb58fab6").into(), + hex!("8ee8873de7cd28a54ba2c63a80b63399effed76b154e96ed26e7c0668b9f2476e298688b6a00c4b2ab9d020a897695d7").into(), + hex!("975c3261f0f32d59473e588f89593be38f5694cfa09394a861e4330b7800fb2528ea832106a928c54c76a303d49140e2").into(), + hex!("b5222582ed6604b9856a48039bd643340f4bf1bf0fc805e8453a9eb7630d6cea1452d28536706d6fa3ec16617617991c").into(), + hex!("b75c28941ee3f91b3535b4eaa0fb17b59ca65b5256601a1f6d0cf2bb4d66837fd16e51d6942856679012a5730a66e519").into(), + hex!("97b510f9f46bdf77a002b2403d8e42b6d6ad5329ea080940844429763ad3efd592652789c8d3d4fac0903c705f533cf7").into(), + hex!("a3fd9d8bbdc98394883022299fd9793e0c4f374d8e40d6ce89b2869d3173cb6a5476371d6095dad068ff217729f60af4").into(), + hex!("a57d5de556853484b1d88808d2529450238bc467376ded84cfd7b4a1ba258f6d43b5958220f962c57b033abcef1d5158").into(), + hex!("8465bd8be9bd9c2c6116d4ae44ec6618c109cb9aaee2d241e7a6ed906d398ef15a6fc18bc8b1d3398184241405954bba").into(), + hex!("ab1cc44983e46a6ea2430aa6616ab28614f43624665e3e6ae31a9357c0c5434f34e56c720906e184327693cc4ebe1fa2").into(), + hex!("aafe14dd3b680f096010788226d8413ca628feedad79a2bc78cb04d47c6ad910f7f46ca87b8f8281744625d8f42d5eea").into(), + hex!("86a533b02ae929f67c301649a2d58651b98cdffe731b63fa32aa1013c271634bbb088c0d02865913c11bbb1bf57c0e12").into(), + hex!("b28df3e04bde4ec373171401dbd0546f4cb6fa8e9a4a8019aadc653d4e05e0b5b9a64417715dd87f6df9e7b3145f6659").into(), + hex!("ac63fc758c1a3bc5cbff0f5e0b5a07a5aa801363b129d4e0360165c7dc1057ec37b0d808e9fd6b179e2c1e66bbc6090e").into(), + hex!("93f941b4fe6c05621e7a651b87669eefd60b6e8a4a8e630a51fa3fee27417b9eebce39f80a5bade9ca779133ad8388f6").into(), + hex!("96d7a69eaf2761bf0e5ebcd607b134d5dedba8e262ca1d6d3e8fbf23e6419a8ce1bbe4cd23b9e4b5f80db54a802a9795").into(), + hex!("8b62902fb2855300580e94830a4bc825d997ede33bf356fe3b7c08d6a8bd85a37879433fc6bee58f9b44ca280f4e8dfd").into(), + hex!("b043156fcd02b75dbe940c763fa8e8a7c7f6d74c1d5395db5ce544af3b6097eab61686950535a810aa95889ced12f74d").into(), + hex!("8614a7599c8d97aa9ca63b876f677977cf0daa969ff2a9a153f297a4a46e08fa5d91492995de94dc32cf009ce6bb5b5f").into(), + hex!("81351fd284d6d07092875f366bc5e53bfd7944b81eece85eab71a00443d1d2a9fc0337aaf34c980f6778dd211caa9f64").into(), + hex!("8c722aaf5d5dad1845056bf5e56dbff0f8b501f4846610f99da01130a49c96db9962bfd9be20670658cf276cc308be08").into(), + hex!("8effe3fb27c9f76bbd78687b743b52e6f3330eddc81bc9006ca81fd640f149d73630af578694f4530833c2151522dcc1").into(), + hex!("a3d327f48eb34998a3b19a745bca3fade6a71360022c9180efb60d5a6f4126c3f4dfa498f45b9a626ca567fdd66ffbff").into(), + hex!("a59a59db246f981e9c8e54aba52898c714d9787fef8969a6d8677fe6dec82950ff22a1364393b579f3e596cdf5bcd7b1").into(), + hex!("a15ebe9ab6de62a4d1ff30b7fc58acfb14ea54d7fa513cbcb045af3070db22bf9c1e987fa26c0c54356b9e38fa412626").into(), + hex!("b58396bce7d32ba6c70adbd37156d859e153c1932d2b0c7c874a1182ba831439e80d6fc6d7d88a870e193f515aef2264").into(), + hex!("b666dae42ea858c9b7d903ea3ca5279f619c71ac6e3fda7469e2bbba08c7e8e12d6a3c35ff2c6383673b1b7c21db5e0e").into(), + hex!("8eaaa21c8955f15bbcfd5756421a045e7b4825576379cc6229fe9751f7a7738b90be19ba52261db01c1e13af955675b0").into(), + hex!("8027bc62b59f9f15613e38da74ccc71fc3eaee26f096d187c613068195ce6eb64176013f2d86b00c4b0b6a7c11b9a9e5").into(), + hex!("8275eb1a7356f403d4e67a5a70d49e0e1ad13f368ab12527f8a84e71944f71dd0d725352157dbf09732160ec99f7b3b0").into(), + hex!("b8c41c09c228da62a548e49cfa107630166ac5c1469abf6d8aab55938ed1d142d5ddbc4f1043eed9496e9002cac99945").into(), + hex!("912750d2f1b21756662a400236f797b8ba76c73e5af95941a8c6ef9427838c4826715c80942cf8cb7ed01566bc490754").into(), + hex!("862af7dbb38ad7293a4e598cb52a8ac84dacee3d9bf007b5cb6a18a1acead0aa33f6dba796ce630e632c97aeb7100d68").into(), + hex!("890def696fc04bbb9e9ed87a2a4965b896a9ae127bc0e1cc515549b88ddbcbc02647e983561cab691f7d25cf7c7eb254").into(), + hex!("b835ffaf54c8b878d3c4262ca2bf5e6be2c691adced622b35d998ed72e1467ba907f4fde8d64ce43b43a8196f48e55db").into(), + hex!("a6d7e65bf9f889532090ae4f9067bb63f15b21f05f22c2540ff1bb5b0b5d98f205e150b1b1690e9aa13d0dee37222143").into(), + hex!("8ebfbcaccddd2489c4a29a374a2babc26987c3312607eadb2c4b0a53a17de97107c54eab34def09144b3098c082c286b").into(), + hex!("900b9972180a2c8753f5ff49fdd2cfe18c700d9927b3c3e16deb6376ad6ee665c698be72d4837b94911a0b4c183cb140").into(), + hex!("aa9679c01ecf1f1452c54688e01cb25bf157bde6b09b1ed460b8c175d65eba439c7ad4b7c1d72415f5622f3fbc068dc8").into(), + hex!("887a4277ee8754733f3692a90416eeac1ebee52ff23173a827f0ba569bd84efd806eb9139049f66cc577e370d3f0962d").into(), + hex!("951b27456e2af80436608aadec54ebd03bda37fa58452631da63bc5ff3eecb5ffb73d356b19f6c9c4225fcb0da8fda20").into(), + hex!("9104b5af82dbca914370eadb5518b26bee7ed7edeca74b741585ba8b249204e2c998bd47a02cef4335e236f8efafef94").into(), + hex!("8757e9a6a2dac742ab66011c53fa76edb5ebc3c2fbd9a7265529a3e5608b5c24b4482fed095725e9b8fed5a8319c17a4").into(), + hex!("a7acf82999de75f231fd80770bcb0f4c720d6b1e4a2558fa1ce854382fda92beb89fea5b5d229dad85fafee7a9e98329").into(), + hex!("8fb74891a8642f25a55b5eda5818367aac2fdf9663ad1e3dbc0166b484c0cda581b243cc75131167f1afa9caaf6705a0").into(), + hex!("897d7a19b70dcef1af006df3365981d73068c81f18017f32fb9966599481496efd5f6caceef943b31c52750c46d9590d").into(), + hex!("87ac804ccfe7f1fa156b8666664a397236832569f8945e11d4688a9e43ada4d4104efb3fda750f48ef655a29357c5e7d").into(), + hex!("af18cf1e3d094b4d8423da072f98b3023d296f6a1f2a35d500f02bde522bb81dc65e9741c5bc74f7d5613bd78ce6bc03").into(), + hex!("9752561179783f336937757b619b2fdcb9dfce05aa3c4fce6d582dc966182eb85ab4ccb63e7e1736a7c5fad9d33cccd2").into(), + hex!("89e19b665ce7f6617884afaf854e88bb7b501ecdd195a5662c79802d721f5340eca8c48341ad1d6c78f519f82e5a9836").into(), + hex!("94402d05dbe02a7505da715c5b26438880d086e3130dce7d6c59a9cca1943fe88c44771619303ec71736774b3cc5b1f6").into(), + hex!("a76adeddf2454d131c91d5e2e3a464ef5d3c40ee6a2ab95e70ef2e49e0920d24f9b09276250ed7b29851affbdbc7885a").into(), + hex!("8934e9a3feababa12ed142daa30e91bd6d28b432d182ac625501fe1dc82f973c67f0fe82d39c9b1da3613bb8bfe2f77b").into(), + hex!("a5c11337eb91ce0e9b6d61bbdadea0a063beee1bc471cc02dc1d81c5dd2095315c400cbc6c33d23c77e98bba6bdf5439").into(), + hex!("92d00e64ed711951aeb852908aeb6fd379ea516872dd512384b1e773ef078e52e6d618beb202d437d2a46bcb78087f7a").into(), + hex!("97f1a7370b4f5acf83b466f519da361c366915f560385dd7eff9d53700ad81b25c9862bc71d35428e82372a5ae555ea0").into(), + hex!("95614544f65808f096c8297d7cf45b274fc9b2b1bd63f8c3a95d84393f1d0784d18cacb59a7ddd2caf2764b675fba272").into(), + hex!("8d474636a638e7b398566a39b3f939a314f1cf88e64d81db0f556ca60951ec1dca1b93e3906a6654ed9ba06f2c31d4ea").into(), + hex!("b87e5f481b938ac8a481b775cc58be2a06604549e3c810fc4734bab76099e5c617f0243c4c140cb7dd6d36a6dc2286bf").into(), + hex!("806efb61d1c948efc10dbf9bef30197d1c269e5e7fcf20a84367b26223d33fade413a0bbf4e33f0d1f1a00967289015e").into(), + hex!("880b99e77a6efb26c0a69583abb8e1e09a5307ac037962ddf752407cacaf8f46b5a67faf9126bdbcb9b75abf854f1c89").into(), + hex!("82ffe4de0e474109c9d99ad861f90afd33c99eae86ea7930551be40f08f0a6b44cad094cdfc9ed7dd165065b390579d0").into(), + hex!("941cd102228aa81ef99506313a4492a17c506e7169808c6b14dd330164e9e8b71b757cbe6e1bb02184372a8c26f7ad1f").into(), + hex!("ae96dc808c316a677977831bad1e529ef965dadb5d6aea25ab008fe7bb1543e596e33052cfbe4279fa060201199d2c34").into(), + hex!("a2053719da2b7501dab42011ae144b3c8d72bd17493181bf3ae79a678068dc3ee2f19d29a60b5a323692c3f684f96392").into(), + hex!("b17171939519d90e243d41839c3c5ce7ac7e6a978e4a7e56b2c8e6a2b1b587c7eacea47f2e31a55d88555d252c810ebd").into(), + hex!("a958987c2b3c84df8176b600f5b75a8badef9653c71eff967e76648937def38826eaab4027a639f4f300b20019166250").into(), + hex!("854aafa329e2b2563355641eba95f2aba5b33d443ab16f5e342048f97d97c4e2812ff27c6f4180b8110272f3151be690").into(), + hex!("94d4a1e3a3d28a948f14d1507372701ac6fc884a4905405a63663e170831578a2719714ef56f920baa0ca27954823e39").into(), + hex!("826be957cf66db958028fa95655b54b2337f78fb6ef26bd29e2e3a64b130b90521333f31d132c04779e4b23a6b6cd951").into(), + hex!("8261f7e644b929d18197b3a5dcbba5897e03dea3f6270a7218119bd6ec3955591f369b693daff58133b62a07f4031394").into(), + hex!("84926cf2265981e5531d90d8f2da1041cb73bdb1a7e11eb8ab21dbe94fefad5bbd674f6cafbcaa597480567edf0b2029").into(), + hex!("8fb51e3ef3c1047ae7c527dc24dc8824b2655faff2c4c78da1fcedde48b531d19abaf517363bf30605a87336b8642073").into(), + hex!("8ba45888012549a343983c43cea12a0c268d2f7884fcf563d98e8c0e08686064a9231ae83680f225e46d021a4e7959bb").into(), + hex!("973ab82026d360e2cf5676d883906186bc61b43f60767ca58f11d0995e40780b163961e6e096299ccf1c86175203abde").into(), + hex!("b77416ea9a6b819e63ae427057d5741788bd6301b02d180083c7aa662200f5ebed14a486efae63c3de81572fe0d92a9c").into(), + hex!("820cc2ac3eed5bce7dc72df2aa3214e71690b91445d8bb1634c0488a671e3669028efbe1eae52f7132bde29b16a020b7").into(), + hex!("a6b434ac201b511dceeed63b731111d2b985934884f07d65c9d7642075b581604e8a66afc7164fbc0eb556282e8d83d2").into(), + hex!("b81821a79c9148b41d24d85dc997336a1e1719da0e31e42af30812b97a5af31708ca3e7bc2e803c3751cff23af5c509d").into(), + hex!("a013cc5e3fbb47951637426581c1d72764556798f93e413e1317849efd60f3ecb64c762f92544201eb5d6cfb68233050").into(), + hex!("b5f32034d0f66bcbccefe2a177a60f31132d98c0899aa1ffff5ebf807546ff3104103077b1435fa6587bfe3e67ac0266").into(), + hex!("86ca8ed7c475d33455fae4242b05b1b3576e6ec05ac512ca7d3f9c8d44376e909c734c25cd0e33f0f6b4857d40452024").into(), + hex!("b781956110d24e4510a8b5500b71529f8635aa419a009d314898e8c572a4f923ba643ae94bdfdf9224509177aa8e6b73").into(), + hex!("a3f9dcc48290883d233100b69404b0b05cf34df5f6e6f6833a17cc7b23a2612b85c39df03c1e6e3cd380f259402c6120").into(), + hex!("a104d4bad69f1720307ed12363d1ec97952acfe09d9e3650034c33f3f20c763271ebe0d5b50b1d3bd15c469f4573b09d").into(), + hex!("94bbc6b2742d21eff4fae77c720313015dd4bbcc5add8146bf1c4b89e32f6f5df46ca770e1f385fdd29dc5c7b9653361").into(), + hex!("951aa38464912a29df2101c60771d6de7fadb63f2db3f13527f8bdacb66e9e8a97aaac7b81b19e3d1025b54e2c8facff").into(), + hex!("919b5187af7dae210f151dc64a9cbd396d1ae04acadebf542a7123004efc7ce00d6e14c170d876fbc64dc1b5d141a5f4").into(), + hex!("88e1e459ee5aeb8b36ed004f6d03da296101106fbe1b18f9bbf63e92321db51670c34050fd3b7dc56a4bad76403823ee").into(), + hex!("86b3ec14a8ffb811a0ecc3771f600d8b08c098537d100fba66def19e7ee4d1c397a311977bf37e6cd2d47a8a2ee8c223").into(), + hex!("898c4873bd356ba8015f6f686d57088fa8f79f38a187a0ef177a6a5f2bc470f263454ee63d0863b62fca37e5a0292987").into(), + hex!("b471c72bd2971353f4b44248b8e6cf5316812861a88ccfc20fd0d89a5e010428c387228b2f6f14c12f79e31afc9d0753").into(), + hex!("8b7cb5b8de09a6dfceddcbaa498bc65f86297bcf95d107880c08854ed2289441a67721340285cfe1749c62e8ef0f3c58").into(), + hex!("983cb6bbfe83bce8326e699e83fca01ea2958c09808c703cac97a0ea777e5a5f3f5bba9169a47732de7459a3c7af47d2").into(), + hex!("8235a3f09078dd34ce2fc17cc625e061298713b113dda12d354b3d2ba80e11c443b1dd59c9eb5a29513a909645ae97d4").into(), + hex!("8bb51b380a8a52d61a94e7b382ff6ce601260fa9b8c5d616764a3df719b382ec43aec9266444a16951e102d8b1fb2f38").into(), + hex!("9579973ee2559da09b327c62b1cc0177f2859872885dca709e24dcfbb9bdf9224a6d26869aafce498f44c0e6bd8a996c").into(), + hex!("842ba3c847c99532bf3a9339380e84839326d39d404f9c2994821eaf265185c1ac87d3dc04a7f851df4961e540330323").into(), + hex!("99dad12f78e1a554f2163afc50aa26ee2a3067fc30f9c2382975d7da40c738313eaae7adbc2521f34c1c708f3a7475b7").into(), + hex!("b96e3ff8bdae47aa13067c29318b1e96a7fe3941869c17ce6662183b7b064bf261e1cea03e2a4643c993728a2606b5b5").into(), + hex!("955bc897171aa65d0159aa6e5d51855833f83d8bd5e65f93ad26c27781171783f3988a12bf987472edb39994bd071ea5").into(), + hex!("a59249e4dfb674dfdc648ae00b4226f85f8374076ecfccb43dfde2b9b299bb880943181e8b908ddeba2411843e288085").into(), + hex!("ac2955c1d48354e1f95f1b36e085b9ea9829e8de4f2a3e2418a403cb1286e2599ba00a6b82609dd489eda370218dcf4c").into(), + hex!("b2eedff11e346518fa54e161be1d45db77136b724d497e337a55edfc896417de3a180bf90dd5f9d92c19db48e8574760").into(), + hex!("976eb5543e043b88d87fda18634470911dfe0e0cabab874ca38c1009e64d43026d9637d39dcd777bc7f809bbfc3e2110").into(), + hex!("8ea5f88a79f4eb9e7c0b6b29f8ef2d1cc4c15ed0ed798ab11a13d28b17ab99278d16cd59c3fa8217776c6dfae3aedf88").into(), + hex!("b7f146a357e02a63cd79ca47bf93998b193ce1174446953f12fa751f85dc2a54c9ed00c01a9308509152b3bad21d7230").into(), + hex!("87fd7e26a0749350ebdcd7c5d30e4b969a76bda530c831262fc98b36be932a4d025310f695d5b210ead89ee70eb7e53b").into(), + hex!("b9445bafb56298082c43ccbdabac4b0bf5c2f0a60a3f9e65916af4108d773d62ffc898a35b0b8efb72ea846e214faa02").into(), + hex!("b106c6d13ca17a4c8ea599306e84918127cf2de21027ac3fe5a57d35cf6f3b1d7671c70b866f6e02168ae4e7adb56860").into(), + hex!("9276e8051bed8f5dbfc6b35765aac577dd9351d9d6ac1bb14496bd98091005b9a4737b213e347336413743f681f5043b").into(), + hex!("aefc682f8784b18d36202a069269be7dba8ab67ae3543838e6d473fbc5713d103abcc8da1729a288503b786baac182d3").into(), + hex!("97578474be98726192cb0eac3cb9195a54c7315e9c619d5c44c56b3f98671636c383416f73605d4ea7ca9fbeff8dd699").into(), + hex!("99c34f9bd0fcb18b3d931e562988cf91886a417f8678f22651bf3cf138df2bbec3f675de90f62dda769e0eda03d72b7e").into(), + hex!("a0047e03c89a95248543618e6b7ca2c7aad7acda3c9f85771ec5c93fa898c651e8b2ea3b6b799d8cd592290a986cdd7d").into(), + hex!("993726e0b1c2277b97b83c80192e14b67977bf21b6ebcde2bda30261aa1897251cd2e277cfcb6193517f1eb156d2fe86").into(), + hex!("974a5180e55eab23d4c973fbee6ad1010335161ecdb849fe6520b34c1f96530a4faff80bd738fe281019b79d968c472c").into(), + hex!("8f1d90034f998018c3f4b5947b40b139fcead2e40aa80fdec6a4337c60e9d5ff1923dda7f0b5b1731ff16f55027d41bf").into(), + hex!("a7d9ae9621dd1f3da3cd2d435e891cc3579c4c0d60d6a4565cac86c315cea21a9ad883559fe7b897ae6e05f1aa989ad9").into(), + hex!("800f6be579b31ea950a50be65f7de8f678b23b7466579c01ac26ebf9c19599fb2b446da40ad4fc92c6109fcd6793303f").into(), + hex!("86fa3d4b60e8282827115c50b1b49b29a371b52aa9c9b8f83cd5268b535859f86e1a60aade6bf4f52e234777bea30bda").into(), + hex!("a80ac2a197002879ef4db6e2b1e1b9c239e4f6c0f0abf1cc9b9b7bf3da7e078a21893c01eaaab236a7e8618ac146b4a6").into(), + hex!("b4bf70468eff528bf8815a8d07080a7e98d1b03da1b499573e0dbbd9846408654535657062e7a87a54773d5493fc5079").into(), + hex!("ae0e15a09238508b769de83b30582cc224b31cd854d04fdb7b8008d5d8d936dbdd3f4a70fff560a8be634c141772561b").into(), + hex!("936f7e20c96b97548fef667aa9fa9e6cfdc578f392774586abe124e7afc36be3a484735e88cc0d6de6d69cf4548b1227").into(), + hex!("8163eea18eacc062e71bb9f7406c58ebe1ce42a8b93656077dd781c2772e37775fe20e8d5b980dd52fdad98b72f10b71").into(), + hex!("86a6560763e95ba0b4c3aa16efd240b1873813386871681d075266511063b2f5077779a4fe49ffc35e1f320b613b8c94").into(), + hex!("b156d9d22722bb6e3b75b3b885b64642fa510ba7e6057657cd61bac43fb9c284d05bb09e2d4b78a2a4ddada85da9c702").into(), + hex!("9779ca2759dbed8081f0cbbfffcb3b842ba335e3ae48a60c5e5c77c7a2a0623e4c415ec3a023cc4e216885fcbac3ce52").into(), + hex!("b8137fd57ce7d3cfaf8bdbaa28704734d567d0e7a2d87fb84716722c524bb93acb2c1284249027f3c87bccc264c01f4e").into(), + hex!("8cf06b34e7021e9401eb705dde411ecf7e7e7185f8c0b0aeed949097df31812a9fdd4db7d18f9383a8a5a8d2d58fa176").into(), + hex!("8c65aa29a9ee9066b81cf24cf9e0beca3e8e8926e3df22d5ff1236297e158cc8bc7970a2c7016009cc4efa8f14b14347").into(), + hex!("ac7e49f2059e99ff65505742978f8d61a03f73f40141a2bd46fde5a2346f36ce5366e01ed7f0b7e807a5ce0730e9eaa9").into(), + hex!("a1c25eb9b73723982be78180770aa63c5f7b23c2e54a2ed7e75a860c4512d273008066f1124ac8a43c60fe1e2a8bf03c").into(), + hex!("9310722e360a5652737362f6b9cb6e9c3969a0c9bb79b488b3c7d19d9e8c42ebd841df346258ded2e393895c99b413cf").into(), + hex!("893272a63650b08e5b8f9b3f17f8547b456192ad649c168bafd7166b4c08c5adf795c508b88fd2425f7be8334592afb2").into(), + hex!("b576c49c2a7b7c3445bbf9ba8eac10e685cc3760d6819de43b7d1e20769772bcab9f557df96f28fd24409ac8c84d05c4").into(), + hex!("af17532b35bcb373ce1deebce1c84abe34f88a412082b97795b0c73570cb6b88ea4ba52e7f5eb5ca181277cdba7a2d6d").into(), + hex!("8b8813bd2c07001a4d745cd6d9491bc2c4a9177512459a75dc2a0fa989680d173de638f76f887de3303a266b1ede9480").into(), + hex!("ab73a043ccdfe63437a339e6ee96ef1241264e04dd4d917f6d6bc99396006de54e1e156d38596ba3d15cb1aaa329f8f5").into(), + hex!("b67146b202afec0132ac0070c005cf664081e860339f8f4d45ac3e630dda05560936e646673e652d08cecd8d18fc64da").into(), + hex!("a750404e9d4b1a48f767d2b6aa699200c92c3b8102597f8c5c1dbaaf08112a0587c05801dfebb3612fb6dfd76ddc9ccb").into(), + hex!("b0d4231814e40e53ab4eed8333d418a6e2e4bd3910148b610dec5f91961df1ad63f4661d533137a503d809ea1ad576fa").into(), + hex!("81fc724846b5781f3736795c32b217458bb29972af36cc4483dd98ab91680d3d9bc18842db2661487d3a85430dc9e326").into(), + hex!("a5cf6f4fd67aecb845eebc8d7304c98c69806d774d4c468350f7f82ff0f5baeecc56837705e39432a8d246aa2a7075ed").into(), + hex!("a71d2c8374776f773bad4de6edfc5f3ff1ea41f06eb807787d3fba5b1f0f741aae63503dbca533e7d4d7d46ab8e4988a").into(), + hex!("825359cfe68ad6a75578a94be6419179e0aa088170b6c20fc5c249dc3be7a260d687c93d8d8a343c7c72c2ed6a716de3").into(), + hex!("b6aeb7a9b934a54e811921494f271d5d717924c561cd7a23ab3ef3dd3e86184d211c53c418f0746cdb3a12a26a334fc8").into(), + hex!("8c6fc89428c74f0c025e980c5a1e576deadf8685f57136e50600175fa2d19389c853d532bb45a3e22b4a879fab1fcb0d").into(), + hex!("ae95ddcf3db88f6b107dcf5d8aa907b2035e0250f7d664027656146395a794349d08a6a306ce7317b728ca83f70f3eaf").into(), + hex!("8c03fb67dd8c11034bd03c74a53a3d55a75a5752ea390bd2e7f74090bf30c271541b83c984d495871d32c98018088939").into(), + hex!("b8d68610fdee190ec5a1f4be4c4f750b00ad78d3e9c96b576c6913eab9e7a81e1d6d6a675ee3c6efac5d02ed4b3c093a").into(), + hex!("87d4b20bbe2dcd4f65f4e1087f58532d5140b39a5288e1a63fc0b7e97a6a56946eafdd90ba09300c3d1fef6356ac6b7c").into(), + hex!("83e264b1d3d4622826ab98d06f28bbbd03014cc55a41aaf3f2a30eec50430877d62b28c9d6d4be98cb83e1e20f3b13db").into(), + hex!("97ffcbf88b668cde86b2839c7f14d19cb7f634a4cf05d977e65f3cd0e8051b2670e521ae74edc572d88201cff225e38a").into(), + hex!("91efdbcaad9931312d7c41d24de977f94d7f3f7b88090a1f72d9a097a1e30cc805c5ea16180f463022d9b26b8863f958").into(), + hex!("a4b507a4bc2bc424297bf8968bf385fae3acc686cff4b7933b4f5b6ef3149995393d5331dbac4b629e8adce01a91a4cc").into(), + hex!("a76a26c30d8abbbd4bf982bb8bd2066a2ec823a5eb6fbe37c664e67efbe2f72d8ce2d00223b900699149f8441bff5ada").into(), + hex!("b3a5497365bd40a81202b8a94a5e28a8a039cc2e639d73de289294cbda2c0e987c1f9468daba09ea4390f8e4e806f3c8").into(), + hex!("a09b2a07d861e01645accfb088f7f9ad524186bd439712775459a60f8a1fbbd43ee084e4d6e23ffce06daa189cd1e654").into(), + hex!("a41cf5d678a007044005d62f5368b55958b733e3fdde302ba699842b1c4ecc000036eda22174a8e0c6d3e7ef93663659").into(), + hex!("a698b04227e8593a6fed6a1f6f6d1eafe186b9e73f87e42e7997f264d97225165c3f76e929a3c562ec93ee2babe953ed").into(), + hex!("8bc66e370296649989a27117c17fbc705d5ac2bda37c5dad0e4990d44fcc40d3e1872945f8b11195538af97961b5c496").into(), + hex!("8bff10f91b8c0abb6c9542588da17fa0118ffda4c82626a754887e333d7d69661b3ae4e400da15c49565f8d10a77d0d7").into(), + hex!("ac715c7b3d794860a61d9c7bd224a2b14a6023f696afa30345aad2ce0a6ea6dbc142f34af1ffe7f783542851a28e8ece").into(), + hex!("91c5e0b9146fe5403fcc309b8c0eede5933b0ab1de71ab02fac6614753caac5d1097369bdeed3a101f62bbcae258e927").into(), + hex!("8553748da4e0b695967e843277d0f6efeb8ba24b44aa9fa3230f4b731caec6ed5e87d3a2fcd31d8ee206e2e4414d6cf4").into(), + hex!("ac722bd742374f925185ea7d4d62d7510b2d8a6ebf5c750af6ce83e2d8a28c95a3e298870ec8254ab2d1d0aa2a063c60").into(), + hex!("b083c4cefb555576bb37b71f30532822cb4b1e1998e35cb00ffb80ca14e2853193c16a6756417853d4a74d625744dd76").into(), + hex!("85745bd84c92ddfc55df11fe134cf70e3c340aa1c7cdd6188a03308cf3a840f4f19629f9730b2e6426424989ff03000d").into(), + hex!("845b4531dee808b583645f56fa98cbdecce3ea100db60524b64f68e29866173791f01137714f4dc7fb8612f7f7943263").into(), + hex!("93f03495d53c781be8b76e37e68b64aa260523004eff6455ddc8a8552af39854e5181f8c5365812b1f65926534fba5dd").into(), + hex!("801c126abff96fe9b042be8869d2907d0c6963a79901f9db46577a445418b7465a1f4b346933d433e539536a9a2df01c").into(), + hex!("952cf6782b0ad3e85625391cc5f486a16bb5b1f8ea20defcb6857bd7d068dcd2701bc7ed5c3b773a869180d9042f772b").into(), + hex!("b3b6eccb2ec8509b4eea8392877887180841ab5794c512b2447be5df7165466d7e293696deaabf063173e5f2238ce763").into(), + hex!("b63fd45023f850985813a3f54eceaccb523d98d4c2ba77310a21f396e19a47c4f655f906783b4891de32b61a05dc7933").into(), + hex!("a113b889be5dcc859a7f50421614a51516b3aadc60489a8c52f668e035c59d61640da74ba1a608856db4ff1fa1fe2dfd").into(), + hex!("87fec026beda4217b0a2014a2e86f5920e6113b54ac79ab727da2666f57ff8a9bc3a21b327ad7e091a07720a30c507c9").into(), + hex!("a3ee8fd53158dad3b6d9757033abf2f3d1d78a4da4022643920c233711ff5378ac4a94eadcaf0416fdcca525391d0c64").into(), + hex!("8d6bed5f6b3f47b1428f00c306df550784cd24212ebac7e6384a0b1226ab50129c0341d0a10d990bd59b229869e7665a").into(), + hex!("b549cef11bf7c8bcf4bb11e5cdf5a289fc4bf145826e96a446fb4c729a2c839a4d8d38629cc599eda7efa05f3cf3425b").into(), + hex!("982691766a549df56436acd0fe76da78132e027515f27174c10d117bfcc20ed73fc31f5465bd7a22a101094fe913e221").into(), + hex!("985af1d441b93fa2a86c86b6d7b70b16973d3971e4e89e093b65f0ae626d702202336869af8e3af3923e287547d5384b").into(), + hex!("994b7baecc8bb68d270a3a88c58e4054afdbd713b4472f9522b27c1762c637ef8f013d745ce9d1dc8fc4d986d4c9338c").into(), + hex!("827dabda84c7f7b1adc0f5ca0fccf0729e9d7f78e1ffa7c5e9c4f66610ff0ab776c880b00c77137cf7abe14df977febc").into(), + hex!("acd17cba1203748b55bd9d7b940a16bb7c02988c93007a80b87e0bdb049b91f5ecce577e3e4ea68a0abe998a72cd300d").into(), + hex!("989fa046d04b41fc95a04dabb7ab8b64e84afaa85c0aa49e1c6878d7b2814094402d62ae42dfbf3ac72e6770ee0926a8").into(), + hex!("99dc48a054f448792523dcdeec819e1b928b1bd66f60f457261f0554f8532eedd7152792df70ae5316ab2f9c02a57cdc").into(), + hex!("ab33c65587ecb3278325948c706aed26547e47ed2b4bc027e9119bb37bec67ddf5489fbc30304ef6c80699c10662d392").into(), + hex!("ae89e41d8cfbf26057a4078f8a5146978e658801b08814190cbce017d79beaeb71558231a72bde726fa592fb0828c01c").into(), + hex!("a9901df92e2d3abbb25f3bf4b913692c4cd57da327b01c8ee2362c02fbefcf66cdb792c17a81dcbde3c9b9dba313e4a1").into(), + hex!("8ee41011424da5e2ecea941cbf069ea32420749f2519434d3d8f9725ac789753404687a6745cffe4bd5dfc8fec71a719").into(), + hex!("8cfcdfa192b17321be4e447204e1a49ecaadca70a3b5dd96b0c70ab64d1a927d1f8c11a7e596367e5fa34e2307af86fc").into(), + hex!("b8a0003e949cf994b1bb25e270cb61358200c93b1c6f611a041cf8536e2e0de59342453c5a8d13c6d4cc95ed8ce058f3").into(), + hex!("adc806dfa5fbf8ce659aab56fe6cfe0b9162ddd5874b6dcf6d658bd2a626379baeb7df80d765846fa16ad6aad0320540").into(), + hex!("a83b036b01e12cadd7260b00a750093388666aff6d9b639e2ce7dfc771504ef8b2090da28ec4613988f2ec553d1d749e").into(), + hex!("825aca3d3dfa1d0b914e59fc3eeab6afcc5dc7e30fccd4879c592da4ea9a4e8a7a1057fc5b3faab12086e587126aa443").into(), + hex!("845a4a09941f48677e6c03699770f9a56ba72695089e432a6f232294dd8da6d34e394116a9a87f3b0902c78332af9439").into(), + hex!("b2f168afc35ed9b308ab86c8c4aaf1dcd6833ce09153bb5e124dad198b006e86a941832d387b1bd34b63c261c6b88678").into(), + hex!("a094cca9d120d92c0e92ce740bc774a89667c6f796b438b0d98df0b7aef0935d8c915d5b0dad4b53e383dc9f095c29fa").into(), + hex!("956ecb233b3529b2d9cb80ae49e48667f2a3120e4a0d7131d1e9ec36db3a59dc2ef2a579cbb99d6f14880ca83f02b64c").into(), + hex!("906cde18b34f777027d0c64b16c94c9d8f94250449d353e94972d42c94dd4d915aa1b6c73a581da2986e09f336af9673").into(), + hex!("824c8a1399ab199498f84e4baa49ff2c905cf94d6ac176e27ec5e2c7985140dbaa9cc6303d906a07ab5d8e19adf25d8a").into(), + hex!("889a5cf9315383bf64dfe88e562d772213c256b0eed15ce27c41c3767c048afe06410d7675e5d59a2302993e7dc45d83").into(), + hex!("95791fb6b08443445b8757906f3a2b1a8414a9016b5f8059c577752b701d6dc1fe9b784bac1fa57a1446b7adfd11c868").into(), + hex!("99049e9a23c59bb5e8df27976b9e09067d66e4a248926d28171d6c3fdd1ab338944a8b428b2eaae5e491932c68711c7c").into(), + hex!("95c810431c8d4af4aa2b889f9ab3d87892c65a3df793f2bfd35df5cfdb604ca0129010fa9f8acae594700bece707d67f").into(), + hex!("841d77b358c4567396925040dffe17b3b82c6f199285ac621b2a95aa401ddb2bc6f07ebd5fa500af01f64d3bb44de2df").into(), + hex!("90c402a39cd1237c1c91ff04548d6af806663cbc57ff338ed309419c44121108d1fbe23f3166f61e4ab7502e728e31fd").into(), + hex!("968d44188e2d9d1508b0659e96d6dabd0b46aa22df8d182e977c7f59e13aa05d5da09f293f14f6f2ee1b996071cd2f25").into(), + hex!("8ae9585caa3c73e679fe9b00f2c691732f7b7ca096e22d88c475a89d4d55cb9fba3cd0fe0cedd64ce75c591211664955").into(), + hex!("94b81d5ad72efb4dd60867e71afcd8e87e1f24bf958d42fc07db66f6185a1e610987ab9ceef63109a36fe5544a0cf826").into(), + hex!("8499a8c3d67d1f6eccf1c69274393dc498cff862ea8e6c11ffb8107ae190d258ddc1d294f2a8f050488df0212063ece2").into(), + hex!("921109a390e4d7fbc94dff3228db755f71cb00df70a1d48f92d1a6352f5169025bb68bcd04d96ac72f40000cc140f863").into(), + hex!("b464d763e5ef724ab7ee13a60015df5c9a7809a79188ff6a7e0d5e5400febd42ad7330406a59704a44a08f2289d659c8").into(), + hex!("96f1a36134e0d4137a7fe8bbb354f50aaa67f28f194ae2fdbe8be3eb24596678d8c9287765ee90c1f2778d0d607931e0").into(), + hex!("b031d93b8f119211af76cfafee7c157d3759b2167ee1495d79ad5f83647d38248b4345917309ef1a10ecaa579af34760").into(), + hex!("88a7dc337d89324f025f686f37d21240c7da9a1cb802259ea8d8a83e246dcc2adceca7ca3534bc7bf8f3ae1cbeafb5c0").into(), + hex!("b30e022b8a563655074e08e123b5f96956bbf0fe221cc629c5fedd2764a66b475916ceb98867f935b4a47212e53ae9f3").into(), + hex!("ab6e3180dae399d41243f23545e5e6d118844f9b8edba502a3503fd1162ed826f9fc610889a1d685d374b6c21e86067d").into(), + hex!("96cf5760c79cfc830d1d5bd6df6cfd67596bef24e22eed52cee04c290ad418add74e77965ea5748b7f0fb34ee4f43232").into(), + hex!("a5817c74a394b0359a4376ef7e9e8f7dfa6a7829602da225074fb392b715e1fd52c50cae0f128a7006f28b22f233fbf5").into(), + hex!("a50ab79cf3f6777a45f28d1b5cdad2c7ea718c60efeeb4c828d6307b29ef319445e6a9f98aa90f351c78b496575150c1").into(), + hex!("8b300dea07e73dd2f07b05d477e51f8424589f6b2fa6f461240e1322a3a7ab5bf227b74544bb5d66a297702cdbf6c6bf").into(), + hex!("b13b5cb86dc8b8fe87125f1a51fe98db36bdde4f600401408b75059a44e70b1bbfefd874e539691f3f1bf6f54db883c8").into(), + hex!("8d06205cd66703ce6776b38b98c32b27f45c7b3f65ea2d05e2b702c24d553f51c69bf0b17e8db7382475e3d370d2e8d6").into(), + hex!("a11a7496c712734aec80738e30d2bf245758b34245076149854eb209fa6403be8bb0d4e515becc881b7f3610749260c0").into(), + hex!("9615800f8c95f95bf25055ae079b964e0a64fa0176cc98da272662014f57e7cd2745929daf838df0094b9f54be18b415").into(), + hex!("b19ca6e55f349bbb2dc3e429520ff5b2e817972470794f35c1aac8c118b37a694cfcc875b6d72225343799825d2f5c39").into(), + hex!("a650864b7eb6769aaf0625c254891447351e702e40d2be34dfd25f3b5367370de354318d8935ba18db7929270455ae6a").into(), + hex!("a649208372f44f32eb1cd895de458ca1b8be782746356f08ac8ef629429d0780a0799fcff85736e19aead0b79bfff261").into(), + hex!("89461cb2dadf51d6f1208b0965c8eabec895d7b19b7d90d3c6e49dbe75a75c30fd26db3dfb169dd46a4342280225032a").into(), + hex!("b5d6f664ec92e5343792d5d6b629919c5fd8cfb874677df2264daf02bcd9d12facf9b859d5402839c9022396e20d260b").into(), + hex!("a7179d338fe5a0e4669364a364e17f8d00cb6c59a80a069afd5f4f14510df2eee90c07826553e4f7fe46d28f72b2903e").into(), + hex!("8ded37d67b5368619a090266e9b5585fbff60319a90a4244a3c3342641f5bfa5130998dd97d7a42505cd896c29255530").into(), + hex!("a3fd63e87a00b48ba46a646a26187ae6dcb16779721973ada13a545853e2e51b5e4df04630d670884ad4a2304cc60c67").into(), + hex!("92761b7e31f0c758b3b1f5b43a194b25aabec668101946eb6511132863d3afb9d18f833d43a8338d0e7bc78d8689e523").into(), + hex!("ab8a8769c754008a7976b6799e81d7bfe97413d0a79b90715703c1f8f567675463ec93aabee59277121fc4df88b5c7a9").into(), + hex!("b354d0d1bd942f79002a2eaf37eb99dab650170e7040c13c824803ed7c1670dc910ccae13bbe58bde003829b140b45ea").into(), + hex!("b9eed89e003894ad2cc9d9b93a45247e1367ac69a00b0ed5e3280c1188b4cb90eb870d449b83a852a798bd02f9d0c813").into(), + hex!("b900a55013d0427e5da6b21611d6ae3e648f54f794cb099b2d2beebae0a957477a94dc415e8ec5e68e9029ce50d43843").into(), + hex!("afbf44071c2c905f7c8ef396eaed7f13deb7a91719cb5e8b9226aaceb876d81a10076383edc6216bc2f5c38a480b2957").into(), + hex!("80bdb82b7d583bf1e41653966b0ba3b4fec0e7df2ff08e3fa06fd9064bca0364263e075e1582741a5243bde786c9c32e").into(), + hex!("a841fe9ff26db21ade698f6dbfba025d90ae9f81f02af9e008fa0a429b993fb04d06acb93e40a9f81c78f73334555a17").into(), + hex!("8cd49711b42af58a5aae75a38fea9ddc5e4183c467a3159b5b0629f01ba548513c577456d34c861911e85782e52c3b1b").into(), + hex!("a322b5d2a6e3cb98b8aaa4c068e097188affef5dec2f08c3e9ce29e73687340d4e5a743a8be5f10e138f9cabbe0c7211").into(), + hex!("942772b7c7c47d4e5957ccf1d6f1450070930af3e2b7eaab0dd7699372445df0cc910e6c0efcf501887dd1adabdaee23").into(), + hex!("9834f66e5c946c3a8241ca2bbde046a7e88072124911d5d15c037a95b61e82b88b5c2058fa4a3721537dee39dee5da18").into(), + hex!("a90cc5b9c4d84f36962d0d55d5bc123dbe5ec5f4fe7b6bf0d009028b3cf14e36c11bc5365391cb4ae548d5eb04fe371b").into(), + hex!("a7c2174eea2b66b2a71cc8095fae39c423a353c7d5020ec2d0551317a66202fcf082c6119ba768755523fff49791bb4e").into(), + hex!("ab92b2a177dfa55d202a653532f0e04d1339ca301aebe6a0e8419bf45be3e573b6b9ae4d3d822cc8279367a3d2c39b06").into(), + hex!("8a9ad977988eb8d98d9f549e4fd2305348a34e6874674bcd6e467c793bba6d7a2f3c20fa44aabbf7151ca53ecb1612f6").into(), + hex!("a7d1676816e81a752267d309014de1772b571b109c2901dc7c9810f45417faa18c81965c114be489ed178e54ac3687a1").into(), + hex!("a575be185551c40eb8edbdb21a0df381c801b6e99467fcf5882dd7cb34916960ce47ac732c1920ad3218f497b690cef4").into(), + hex!("b50c306f78143b37986e68efa10dbe1fb047d58562e9b5c5439b341dd8f1896c7ae586afac0a3213759784a905c1caaa").into(), + hex!("b31e89b4a034c1b73d43b3d63ea3bddea682a6a5327eff389c70b13e9e72185b0327682a0cb1ff3c4a4f8ba08b13d898").into(), + ], + aggregate_pubkey: hex!("948a4b8d91bd29969cd4470b1bc24d34586d38e73d5be71c98a9894899471a5f708747563276b4b6d2716fdb72860267").into(), + }, + next_sync_committee_branch: vec![ + hex!("cb3fea582872d90706ddc6d029bac0d791ea75d43c3ab04f056f62a11b89d27b").into(), + hex!("f26b4bb68eb7e6906c8ef4a9958398a48e4450bf9c8a462fafa4fde51cd5628f").into(), + hex!("690925f92c1d322d2ff2a5636539094825dfd2c9bf7538fe111b2358e03a71de").into(), + hex!("51d977e358166401c7cd3f6185468c1a8c69a4c3d8577535dd583bc427692e02").into(), + hex!("88d2089aaf2f6fd8f6e4ae499c6fe33cc34289eb9310780861e772204f07b670").into(), + ], + }), + finalized_header: BeaconHeader{ + slot: 4055040, + proposer_index: 854, + parent_root: hex!("8adf3b288deb17566a553fa7a06a2f63f4ac4cea4868af4d89ddca41f73ae9b9").into(), + state_root: hex!("595e9ebaaa23f027672b4d2a33173a22b2839baac709c7f8e66d3219f492ee9f").into(), + body_root: hex!("acf37b466d4f6b5d1db5b6ffe5d77c13972d116c2b0809de924427fd597d391a").into(), + }, + finality_branch: vec![ + hex!("00ef010000000000000000000000000000000000000000000000000000000000").into(), + hex!("3d4be5d019ba15ea3ef304a83b8a067f2e79f46a3fac8069306a6c814a0a35eb").into(), + hex!("a2e2a28c0bb0ad56c25f3c461a4bfe4f3b3b894bc0105a62e85f43a4ae1adc3f").into(), + hex!("690925f92c1d322d2ff2a5636539094825dfd2c9bf7538fe111b2358e03a71de").into(), + hex!("51d977e358166401c7cd3f6185468c1a8c69a4c3d8577535dd583bc427692e02").into(), + hex!("88d2089aaf2f6fd8f6e4ae499c6fe33cc34289eb9310780861e772204f07b670").into(), + ], + block_roots_root: hex!("7054ba439f83e9b2223911e25fad48eb28f5c362d94c0de2455a45436cc93897").into(), + block_roots_branch: vec![ + hex!("c99a842c81d0b956eef988dbcd90499457d61f942375c6cbf67262909b708db5").into(), + hex!("5d32345aeb10aa3ede4be021d2231dac47cc2074f74b72466f0b042e69adf70f").into(), + hex!("b69608a2377956c1a39c3423d3399ccfb12307623c9df6358f5fcfca64a80102").into(), + hex!("cefd9b668e49ece82bd4b0ee2f1efc88ecaf0d9af464fb622735663aaf106c4c").into(), + hex!("c113ad1c971779b15c64772ab69cd775edfb926a60447974913bb6f58fbd12fb").into(), + ], + }) +} + +pub fn make_finalized_header_update() -> Box { + Box::new(Update { + attested_header: BeaconHeader { + slot: 4058720, + proposer_index: 1088, + parent_root: hex!("37c7398a391c71da07258b48f41d4caaaf891fdf558e110b9c25db716fa8ff55").into(), + state_root: hex!("6cf68a66c993f1c27f499e054a5fbd7c0e625c34ea0057fda9691c561e990002").into(), + body_root: hex!("109e4c0c647d42dba0c8c6569997c51b5bcfc1a33475b1433ded6353f48423ff").into(), + }, + sync_aggregate: SyncAggregate{ + sync_committee_bits: hex!("ffffffffff7bfdfffff7fffff1effffef7f9ffbdfdffffffdffbfffbbf7ffffffffffefdf7ffbeffdffef7bfffffffffffbffffffffffbffffffffffffffdfda"), + sync_committee_signature: hex!("b5727bad1db101b6f0fd7ec4cb79b43dae90366fe0cae31a62439388eb03ebd75732cee3bde51f814203a4c0f5b23898120cd0870f0e662bdf0f85a048b534d9a906e6d32a65df019059d34f724221075734ec2849c09679febecf6929934f09").into(), + }, + signature_slot: 4058721, + next_sync_committee_update: None, + finalized_header: BeaconHeader { + slot: 4058656, + proposer_index: 810, + parent_root: hex!("bb6cfda1e02c3117d9fa41c1e1594ce0645352a073ad8b474f83c148e0d9954f").into(), + state_root: hex!("f938f0f0cba85234afbaace20545134c70b35e6ff9f74d944b0fea309109f3cf").into(), + body_root: hex!("cf6a7a6f653cb64b2b910278a478339b34eb08abf00e0766d10c7a8fe9bdb139").into(), + }, + finality_branch: vec![ + hex!("71ef010000000000000000000000000000000000000000000000000000000000").into(), + hex!("3d4be5d019ba15ea3ef304a83b8a067f2e79f46a3fac8069306a6c814a0a35eb").into(), + hex!("a2e2a28c0bb0ad56c25f3c461a4bfe4f3b3b894bc0105a62e85f43a4ae1adc3f").into(), + hex!("aa2bad8cf9b0433d3d79bc5b95c067048b018d1d2ffd0c66db6e7cf86e0a314e").into(), + hex!("027f238235d07ac9757543c19deabe1d553d6fc110e8bea4b037b1fab263b4dc").into(), + hex!("7dfa1cc1907e8927295f78a770bf86b28f5c2bddcac38beb3b4beb265ff5608f").into(), + ], + block_roots_root: hex!("4a5a57fb0769443f6472f59dbb78d7a9a69ff61d09aa89d5da645d634ec46a14").into(), + block_roots_branch: vec![ + hex!("a09ad7f3afd681bb6fd54abba339549f3b601beedea79a5b7d448b1cf1e1613e").into(), + hex!("acdfd4d5eba154f118a84af7a2d17ba6100fcd9c24fc235e927f584a5b56e32f").into(), + hex!("36ca106eac009ed605e680415b105b3a6591830c38034511f300aae44802235f").into(), + hex!("171561a9e1afb413132d0f4d3cbbd810766c151be32ec9f2d609f40aef9e2588").into(), + hex!("7cd963eba3fb57ee5ce37ee4b621d24fc14d642e32f48dc48ade528e11458ab9").into(), + ] + }) +} + +pub fn make_execution_header_update() -> Box { + Box::new(ExecutionHeaderUpdate { + header: BeaconHeader { + slot: 4058654, + proposer_index: 1039, + parent_root: hex!("758fa0a54047c0221b3107423e78b8910514ba7a0c4250401dac77108dce2ff8").into(), + state_root: hex!("53c79320b4b7649e39a9f07903f4fc68a7cfe7a81cb2e30293dd7b00ee13f69a").into(), + body_root: hex!("a76a7f037f12ee070dcb273d9787b13ff0cf17420a39564a101789318a157ec3").into(), + }, + ancestry_proof: Some(AncestryProof { + header_branch: vec![ + hex!("bb6cfda1e02c3117d9fa41c1e1594ce0645352a073ad8b474f83c148e0d9954f").into(), + hex!("b44967bd8ff799126cad993ff7369f7a28d60281304d0c7c058e6721b6ce4c61").into(), + hex!("0009710ef2467f95542c2e8e7a7249282c08f62aedbe7d21ae4a7af04e1a890d").into(), + hex!("7bc5dc20638cfe1cfd5d2547c3efbed4cfb533c76c27d41f723ed876ab9edc3a").into(), + hex!("6dcd59a8a041cf2591921417cb8133f0ff5af9bfe1f1ab491e75a751adc9c9e1").into(), + hex!("3f25a2852042c7bf2c421bf16c0b9373c1d27ccb1eca4088f8191712481261be").into(), + hex!("d1f9cfe1f04031459e5c45f47b2a49c780cabb8ca5b8d76461db2b88c337ed76").into(), + hex!("8c37e3119bf7d3cb8208e832669261b0eda1b3c7b11d321760ba1c0649f61416").into(), + hex!("1783d3b7041ecb78d9e1f913b82bd335229ca1f2cc5d3cc8dd28c94152e887b4").into(), + hex!("e39fc366c951c7cb2100308b0a9417581c46812a7d7e89f516c19863f7686f96").into(), + hex!("3c29b6d9b8715dbe5d6831364229efc91ad56ae69e93cb119d5ef4bdc53fcb37").into(), + hex!("3cf6fe5e8d91dbaa77e6befa81e04fb25a3e089317d83ff35fc8adfbbf2aab5a").into(), + hex!("b41c97cf3b1b4b5bf2999dfb1b3eaeac5c1b12205e9ab0809988e3779d119047").into(), + ], + finalized_block_root: hex!("b4802863fc1d32778211ce6aac8109c73c516a003213f4f5333c80472d08fe4e").into(), + }), + execution_header: ExecutionPayloadHeader { + parent_hash: hex!("9cffcba69c88a619483e13864704dde5db80e05f8d49018f615395ce09cd24ab").into(), + fee_recipient: hex!("ff58d746a67c2e42bcc07d6b3f58406e8837e883").into(), + state_root: hex!("6a4aafc93626778475a416721104229035e91f0db788d0099b57e756cd272f0a").into(), + receipts_root: hex!("e1ce670bdcf9acf4c62fee845cd7e81eabbb6db9ddbff56130020c6cf999a45d").into(), + logs_bloom: hex!("a000980408008000328c1458805c005048b84812c134200090b40428568108a0648090105085100301844800090802484420800d020282019002040d083004031a20420240a4a8900a43296938c040802040220170860210910020036b8c482228c004440300021c82c0400110402a10800582424001c00000828310210020a18130504020790dca716194100880ea5501149104002bc05e189080901c4001010e0a040658a410072021230a5224265030082404000aa11f28162e216636000408842103d41010760972060060000500c20130b000000065401483200081a84934f020020120009618002269c884724616040000840e18080300024490000230").into(), + prev_randao: hex!("5d9ac7ea788ecb534e98bc9079fa0bef199011dadadedaee5dc40e2cd702d664").into(), + block_number: 5025098, + gas_limit: 30000000, + gas_used: 13802943, + timestamp: 1704437448, + extra_data: hex!("476f65726c69205365706f6c69612d4265706f6c696120513966").into(), + base_fee_per_gas: U256::from(19959019915_u64), + block_hash: hex!("795021134c2b7f9c00b498ff7b0971dbbe061561868f702d8ca68a05e5eb5a99").into(), + transactions_root: hex!("3cb7c92fde5d511cc90cd67e375c4388794f4c01e375e8e8a06d003b5593fd12").into(), + withdrawals_root: hex!("5f5155fd8e5cd24b7ecb1e039792b0caff01dfda2990786d9ffc88325b5d1ea8").into(), + }, + execution_branch: vec![ + hex!("85ff3d1c2bc3dcdd5543bcd29a1224c6a8c24875224fbb1e3b69f0515ffaacda").into(), + hex!("336488033fe5f3ef4ccc12af07b9370b92e553e35ecb4a337a1b1c0e4afe1e0e").into(), + hex!("db56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71").into(), + hex!("fe1fa7acd413c54ebd394126ade19fc624ad9e4c60792d54ff3d60b07076b76d").into(), + ], + }) +} diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/fixtures_minimal.rs b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/fixtures_minimal.rs new file mode 100755 index 00000000000..b9476a0fb08 --- /dev/null +++ b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/fixtures_minimal.rs @@ -0,0 +1,248 @@ +// Generated, do not edit! +// See README.md for instructions to generate +use crate::{CheckpointUpdate, ExecutionHeaderUpdate, Update}; +use hex_literal::hex; +use primitives::{ + updates::AncestryProof, BeaconHeader, ExecutionPayloadHeader, NextSyncCommitteeUpdate, + SyncAggregate, SyncCommittee, +}; +use sp_core::U256; +use sp_std::{boxed::Box, vec}; + +pub fn make_checkpoint() -> Box { + Box::new(CheckpointUpdate { + header: BeaconHeader { + slot: 152, + proposer_index: 7, + parent_root: hex!("7ecd45ee8bbacb20c6818eb46740b0f8d2fbd5af964e0dd844d3aa49ca75ce26").into(), + state_root: hex!("0859c78c54a2ecf1af0aecc05f3c8ba9274d1df500bfc4e6a7194c0235f55def").into(), + body_root: hex!("561bec3e5b200ee1bf6b60b5858ca2d7766ac9327b46355c070afafae8fca2ba").into(), + }, + current_sync_committee: SyncCommittee { + pubkeys: [ + hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into(), + hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into(), + hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into(), + hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into(), + hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into(), + hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into(), + hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into(), + hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into(), + hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into(), + hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into(), + hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into(), + hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into(), + hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into(), + hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into(), + hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into(), + hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into(), + hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into(), + hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into(), + hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into(), + hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into(), + hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into(), + hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into(), + hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into(), + hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into(), + hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into(), + hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into(), + hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into(), + hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into(), + hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into(), + hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into(), + hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into(), + hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into(), + ], + aggregate_pubkey: hex!("8fe11476a05750c52618deb79918e2e674f56dfbf12dbce55ae4386d108e8a1e83c6326f5957e2ef19137582ce270dc6").into(), + }, + current_sync_committee_branch: vec![ + hex!("c6dd41df7b4978b7ee7479dcbfdbfa9fb56d1464afe9806bfd6f527e9d1c69a4").into(), + hex!("b3824f305318071010d4f4d9505f9fc102cdd57f1c03cf4540e471b157f98e3f").into(), + hex!("66677299731d34be9d4dea7c0e89d8eae81b8dffa3c6218152484a063b1064a1").into(), + hex!("ef53c2b02cdb7f44fb37ea75f4c48c5086604a26be9635f88b1138f961f87773").into(), + hex!("1a3f86a88fb2ec99cb1d7b0f35227c0f646490773bac523c30fc7eccf87c0f84").into(), + ], + validators_root: hex!("270d43e74ce340de4bca2b1936beca0f4f5408d9e78aec4850920baf659d5b69").into(), + block_roots_root: hex!("8ad7487f0e79a6cf67ce49916f74e5b272be9e38ea5f8a6a588eaa89ea7f858e").into(), + block_roots_branch: vec![ + hex!("90683050cb3f3b04b2a89c206365747bef4c42154feb5d3f4198dfd48b2067ae").into(), + hex!("34f521b45630273930475b8a4350fe2c71c804878ebcd89064eb1dc24a85e468").into(), + hex!("81e166eaeaff5df2d3a5df306c78af075106cbf63c2f1b50ab67eec2dbb0f5ce").into(), + hex!("857526b3bf20de3ec6e57565dd593304f83e47541cc18d7c2d5b4c9f2724ba14").into(), + hex!("1b4bedd5ecc523599da000387f5e33ffe5324b8e234c43ee702de8ccc88d713f").into(), + ], + }) +} + +pub fn make_sync_committee_update() -> Box { + Box::new(Update { + attested_header: BeaconHeader { + slot: 144, + proposer_index: 2, + parent_root: hex!("74e7da3093f79414b5ab593d1c12ba63767db7f4af62672fa1be641331c338e0").into(), + state_root: hex!("92a08dc74f6af7bfcd428aa1677d58f36fefc159c0134b312c186a69fcd00496").into(), + body_root: hex!("51506a8230d40d065a29ad01197c983b9b5d4b9abd26d3c48773941f4e6f482d").into(), + }, + sync_aggregate: SyncAggregate{ + sync_committee_bits: hex!("ffffffff"), + sync_committee_signature: hex!("92cbff711040bcc4a81616edbadbe712ea3ac4939c3d3121a4561b4b3950e2e5b09809606b79fdad2ce20fdef413120a04f02dc65149ca9b6ecab2a94ac4087062df4ab03e161ae56fa6fee4ba40af29c3b4327e21e846f98144cab30684d197").into(), + }, + signature_slot: 145, + next_sync_committee_update: Some(NextSyncCommitteeUpdate { + next_sync_committee: SyncCommittee { + pubkeys: [ + hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into(), + hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into(), + hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into(), + hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into(), + hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into(), + hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into(), + hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into(), + hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into(), + hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into(), + hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into(), + hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into(), + hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into(), + hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into(), + hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into(), + hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into(), + hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into(), + hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into(), + hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into(), + hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into(), + hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into(), + hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into(), + hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into(), + hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into(), + hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into(), + hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into(), + hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into(), + hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into(), + hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into(), + hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into(), + hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into(), + hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into(), + hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into(), + ], + aggregate_pubkey: hex!("8fe11476a05750c52618deb79918e2e674f56dfbf12dbce55ae4386d108e8a1e83c6326f5957e2ef19137582ce270dc6").into(), + }, + next_sync_committee_branch: vec![ + hex!("c243f5286cbf6c3c5f58ef6e1734a737bf96cfc0adbf2ee88d4a996f8dfc7097").into(), + hex!("6ae16cb8ea57014c75a9469485bc024bb1e64676656cb069753bf091e58de88f").into(), + hex!("1afa3c77cd75040c1bbbc5d1b7c07e65eeee44fbc659b64ccd55b4ba579038ae").into(), + hex!("89b14216f60859ae366de066eeff4c7b69f8b5738c5b70cdfab4b3a976f9f12f").into(), + hex!("b7d8fa1e64e6d6339a7c68a81e20daab65804777b93a04236fa503b575c2f1a9").into(), + ], + }), + finalized_header: BeaconHeader{ + slot: 128, + proposer_index: 3, + parent_root: hex!("3774d6a479fc6f71ccaff3f8a1881c424b0319e96a7da15f87e3b750ba50dae5").into(), + state_root: hex!("85937007c564046bcc147d53b1d2d78941e2787ec059bee191420369a7f80447").into(), + body_root: hex!("c8f31c33ffaeef2d534363b7ef9ec391f90c17bc5bbe439cf0dcf0de8eeb4d7d").into(), + }, + finality_branch: vec![ + hex!("1000000000000000000000000000000000000000000000000000000000000000").into(), + hex!("10c726fac935bf9657cc7476d3cfa7bedec5983dcfb59e8a7df6d0a619e108d7").into(), + hex!("c2374959a44ad09eb825ada636c430d530e656d7f06dccbcf2ca8b6dc834b188").into(), + hex!("1afa3c77cd75040c1bbbc5d1b7c07e65eeee44fbc659b64ccd55b4ba579038ae").into(), + hex!("89b14216f60859ae366de066eeff4c7b69f8b5738c5b70cdfab4b3a976f9f12f").into(), + hex!("b7d8fa1e64e6d6339a7c68a81e20daab65804777b93a04236fa503b575c2f1a9").into(), + ], + block_roots_root: hex!("b10da1bbb1c0dcb01637b9e3dcb710d1013dc42a002bd837d5b4effa0ac995c9").into(), + block_roots_branch: vec![ + hex!("9c62693fd336e4b3ca61d3cbe9caeb85f1f1b59ef50aeddfce53dc7321d6058b").into(), + hex!("364947a6574f4acc97888e1fddb5ec718859d54cd7e3db98cda8db4dbea82ded").into(), + hex!("10a61d26b0c1b5b89cf5b82b965f772a1b6ae852fbd13a986c5c63bf12b99244").into(), + hex!("506ed8ca9908af4b5acb4cfdec6dd968acf38346c16385abca360c9976411c3e").into(), + hex!("ada571922caf3dde48e19f1482df8d17dd6bb05e525c016c8cf6796a5d7f4a00").into(), + ], + }) +} + +pub fn make_finalized_header_update() -> Box { + Box::new(Update { + attested_header: BeaconHeader { + slot: 184, + proposer_index: 5, + parent_root: hex!("13548d0b72ef2b352ba73a53274ad02e9310d8417d4782bf9cdad877da549595").into(), + state_root: hex!("cbd5e841afef5103a613bb9a89199d39c40751af1af7cabadfa8e1fd49c4be09").into(), + body_root: hex!("c9b5074ac3043ae2ad6da067b0787d61b6f1611b560ef80860ce62564534a53a").into(), + }, + sync_aggregate: SyncAggregate{ + sync_committee_bits: hex!("ffffffff"), + sync_committee_signature: hex!("80628825caef48ef13b4ffda96fcee74743609fe3537b7cd0ca8bc25c8a540b96dfbe23bdd0a60a8db70b2c48f090c1d03a25923207a193724d98e140db90ab692cd00ec2b4d3c0c4cbff13b4ab343e0c896e15cba08f9d82c392b1c982a8115").into(), + }, + signature_slot: 185, + next_sync_committee_update: None, + finalized_header: BeaconHeader { + slot: 168, + proposer_index: 1, + parent_root: hex!("bb8245e89f5d7d9191c559425b8522487d98b8f2c9b814a158656eaf06caaa06").into(), + state_root: hex!("98b4d1141cfc324ce7095417d81b28995587e9a50ebb4872254187155e6b160c").into(), + body_root: hex!("c1a089291dbc744be622356dcbdd65fe053dcb908056511e5148f73a3d5c8a7e").into(), + }, + finality_branch: vec![ + hex!("1500000000000000000000000000000000000000000000000000000000000000").into(), + hex!("10c726fac935bf9657cc7476d3cfa7bedec5983dcfb59e8a7df6d0a619e108d7").into(), + hex!("c2374959a44ad09eb825ada636c430d530e656d7f06dccbcf2ca8b6dc834b188").into(), + hex!("97a3662f859b89f96d7c6ce03496c353df5f6c225455f3f2c5edde329f5a94d1").into(), + hex!("4c4720ad9a38628c6774dbd1180d026aceb0be3cb0085d531b1e09faf014328a").into(), + hex!("c3d59497774f8f1c13fda9f9c6b4f773efabbac8a24d914dc7cf02874d5f5658").into(), + ], + block_roots_root: hex!("dff54b382531f4af2cb6e5b27ea905cc8e19b48f3ae8e02955f859e6bfd37e42").into(), + block_roots_branch: vec![ + hex!("8f957e090dec42d80c118d24c0e841681e82d3b330707729cb939d538c208fb7").into(), + hex!("4d33691095103fbf0df53ae0ea14378d721356b54592019050fc532bfef42d0c").into(), + hex!("bc9b31cd5d18358bff3038fab52101cfd5c56c75539449d988c5a789200fb264").into(), + hex!("7d57e424243eeb39169edccf9dab962ba8d80a9575179799bbd509c95316d8df").into(), + hex!("c07eeb9da14bcedb7dd225a68b92f578ef0b86187724879e5171d5de8a00be3a").into(), + ] + }) +} + +pub fn make_execution_header_update() -> Box { + Box::new(ExecutionHeaderUpdate { + header: BeaconHeader { + slot: 166, + proposer_index: 7, + parent_root: hex!("da28a205118aaf4aa69a3fb4eb7a565541b7172cc77771ec886b54b6f5bc10f3").into(), + state_root: hex!("179a6249c3e86ebcc9c71a0fc604a825a5fb5dd1602177681c54dc7e09af4265").into(), + body_root: hex!("e1290e50d64f043594bcac66824b04eb3047ae4174188e40106235183f47074c").into(), + }, + ancestry_proof: Some(AncestryProof { + header_branch: vec![ + hex!("bb8245e89f5d7d9191c559425b8522487d98b8f2c9b814a158656eaf06caaa06").into(), + hex!("ab498fef414d709fcac589217246527b82c25706fa800f21d543c83a0ccc59a2").into(), + hex!("de054acbf636cf9f1692137f78179381b5b0328b49fbc4d324eb8e897b41f52c").into(), + hex!("c472fde1df644788c92208467ff5aad686ce55bab1570917e8de1922296666fd").into(), + hex!("11a71c67676c72696c452d875318501cd50968106f72fb611bfe5952285516f8").into(), + hex!("6d2bd2b6cd84ddadc89df27f3f7f9141bb88c742a30123c77eefebef9d5f6667").into(), + ], + finalized_block_root: hex!("be7d9cc4483ed0065fc7c32e2a783ca3782d8dbd7bfe899fd7c0bcee82f11629").into(), + }), + execution_header: ExecutionPayloadHeader { + parent_hash: hex!("96b27b6e0919c19a70c4a2f7136fd59d2e63a3ba0453a86775add3f2dd681cea").into(), + fee_recipient: hex!("0000000000000000000000000000000000000000").into(), + state_root: hex!("b847ee60946ebdb5bd92c22385da44b8a9aea4c6779f1a1402cc06e22b76fb4a").into(), + receipts_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(), + logs_bloom: hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into(), + prev_randao: hex!("e6c6665aa502e12dd8f5937da2eb7f7fe7a78bc9a900c9321412b8ddd4d72325").into(), + block_number: 166, + gas_limit: 68022694, + gas_used: 0, + timestamp: 1704700423, + extra_data: hex!("d983010d05846765746888676f312e32312e318664617277696e").into(), + base_fee_per_gas: U256::from(7_u64), + block_hash: hex!("1871ded7b2b8b4b5b358c904104704811b15aeefc24e49daa2a1a68176d6553a").into(), + transactions_root: hex!("7ffe241ea60187fdb0187bfa22de35d1f9bed7ab061d9401fd47e34a54fbede1").into(), + withdrawals_root: hex!("28ba1834a3a7b657460ce79fa3a1d909ab8828fd557659d4d0554a9bdbc0ec30").into(), + }, + execution_branch: vec![ + hex!("276d006ecfe51451787321ef00417b194e90b35d4106bd7d51372f39918a4531").into(), + hex!("336488033fe5f3ef4ccc12af07b9370b92e553e35ecb4a337a1b1c0e4afe1e0e").into(), + hex!("db56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71").into(), + hex!("6b8ff91d1be713c644ef9b3e5b77323897930c342fd12615c0d2142bee5cd1d7").into(), + ], + }) +} diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/mod.rs b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/mod.rs index cba22fc86c9..807d4de14ee 100644 --- a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/mod.rs +++ b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/mod.rs @@ -1,18 +1,21 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork use super::*; - -mod fixtures; mod util; use crate::Pallet as EthereumBeaconClient; use frame_benchmarking::v2::*; use frame_system::RawOrigin; -use fixtures::{ - make_checkpoint, make_execution_header_update, make_finalized_header_update, - make_sync_committee_update, -}; +#[cfg(feature = "beacon-spec-minimal")] +mod fixtures_minimal; +#[cfg(feature = "beacon-spec-minimal")] +use fixtures_minimal::*; + +#[cfg(not(feature = "beacon-spec-minimal"))] +mod fixtures_mainnet; +#[cfg(not(feature = "beacon-spec-minimal"))] +use fixtures_mainnet::*; use primitives::{ fast_aggregate_verify, prepare_aggregate_pubkey, prepare_aggregate_signature, @@ -148,6 +151,13 @@ mod benchmarks { Ok(()) } + #[cfg(feature = "beacon-spec-minimal")] + impl_benchmark_test_suite!( + EthereumBeaconClient, + crate::mock::minimal::new_tester(), + crate::mock::minimal::Test + ); + #[cfg(not(feature = "beacon-spec-minimal"))] impl_benchmark_test_suite!( EthereumBeaconClient, crate::mock::mainnet::new_tester(), diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/config/mod.rs b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/config/mod.rs index 6b959ebfec9..d20743b846e 100644 --- a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/config/mod.rs +++ b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/config/mod.rs @@ -6,10 +6,10 @@ use static_assertions::const_assert; pub mod mainnet; pub mod minimal; -#[cfg(not(feature = "beacon-spec-mainnet"))] +#[cfg(feature = "beacon-spec-minimal")] pub use minimal::*; -#[cfg(feature = "beacon-spec-mainnet")] +#[cfg(not(feature = "beacon-spec-minimal"))] pub use mainnet::*; // Generalized Indices diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/lib.rs b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/lib.rs index fdda200251a..53877ea58fe 100644 --- a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/lib.rs +++ b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/lib.rs @@ -28,7 +28,7 @@ pub mod weights; #[cfg(any(test, feature = "fuzzing"))] pub mod mock; -#[cfg(all(test, not(feature = "beacon-spec-mainnet")))] +#[cfg(test)] mod tests; #[cfg(feature = "runtime-benchmarks")] diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/mock.rs b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/mock.rs index 4d1d14a1015..b25e8b0e813 100644 --- a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/mock.rs +++ b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/mock.rs @@ -1,22 +1,127 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork use crate as ethereum_beacon_client; +use crate::config; use frame_support::parameter_types; +use hex_literal::hex; use pallet_timestamp; -use primitives::{Fork, ForkVersions}; +use primitives::{CompactExecutionHeader, Fork, ForkVersions}; +use snowbridge_core::inbound::{Log, Proof}; use sp_core::H256; use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; +use std::{fs::File, path::PathBuf}; -#[cfg(not(feature = "beacon-spec-mainnet"))] +fn load_fixture(basename: String) -> Result +where + T: for<'de> serde::Deserialize<'de>, +{ + let filepath: PathBuf = + [env!("CARGO_MANIFEST_DIR"), "tests", "fixtures", &basename].iter().collect(); + serde_json::from_reader(File::open(filepath).unwrap()) +} + +pub fn load_execution_header_update_fixture() -> primitives::ExecutionHeaderUpdate { + #[cfg(feature = "beacon-spec-minimal")] + const SPEC: &str = "minimal"; + #[cfg(not(feature = "beacon-spec-minimal"))] + const SPEC: &str = "mainnet"; + let basename = format!("execution-header-update.{}.json", SPEC); + load_fixture(basename).unwrap() +} + +pub fn load_checkpoint_update_fixture( +) -> primitives::CheckpointUpdate<{ config::SYNC_COMMITTEE_SIZE }> { + #[cfg(feature = "beacon-spec-minimal")] + const SPEC: &str = "minimal"; + #[cfg(not(feature = "beacon-spec-minimal"))] + const SPEC: &str = "mainnet"; + let basename = format!("initial-checkpoint.{}.json", SPEC); + load_fixture(basename).unwrap() +} + +pub fn load_sync_committee_update_fixture( +) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { + #[cfg(feature = "beacon-spec-minimal")] + const SPEC: &str = "minimal"; + #[cfg(not(feature = "beacon-spec-minimal"))] + const SPEC: &str = "mainnet"; + let basename = format!("sync-committee-update.{}.json", SPEC); + load_fixture(basename).unwrap() +} + +pub fn load_finalized_header_update_fixture( +) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { + #[cfg(feature = "beacon-spec-minimal")] + const SPEC: &str = "minimal"; + #[cfg(not(feature = "beacon-spec-minimal"))] + const SPEC: &str = "mainnet"; + let basename = format!("finalized-header-update.{}.json", SPEC); + load_fixture(basename).unwrap() +} + +pub fn load_next_sync_committee_update_fixture( +) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { + #[cfg(feature = "beacon-spec-minimal")] + const SPEC: &str = "minimal"; + #[cfg(not(feature = "beacon-spec-minimal"))] + const SPEC: &str = "mainnet"; + let basename = format!("next-sync-committee-update.{}.json", SPEC); + load_fixture(basename).unwrap() +} + +pub fn load_next_finalized_header_update_fixture( +) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { + #[cfg(feature = "beacon-spec-minimal")] + const SPEC: &str = "minimal"; + #[cfg(not(feature = "beacon-spec-minimal"))] + const SPEC: &str = "mainnet"; + let basename = format!("next-finalized-header-update.{}.json", SPEC); + load_fixture(basename).unwrap() +} + +pub fn get_message_verification_payload() -> (Log, Proof) { + ( + Log { + address: hex!("ee9170abfbf9421ad6dd07f6bdec9d89f2b581e0").into(), + topics: vec![ + hex!("1b11dcf133cc240f682dab2d3a8e4cd35c5da8c9cf99adac4336f8512584c5ad").into(), + hex!("00000000000000000000000000000000000000000000000000000000000003e8").into(), + hex!("0000000000000000000000000000000000000000000000000000000000000001").into(), + ], + data: hex!("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004b000f000000000000000100d184c103f7acc340847eee82a0b909e3358bc28d440edffa1352b13227e8ee646f3ea37456dec701345772617070656420457468657210574554481235003511000000000000000000000000000000000000000000").into(), + }, + Proof { + block_hash: hex!("05aaa60b0f27cce9e71909508527264b77ee14da7b5bf915fcc4e32715333213").into(), + tx_index: 0, + data: (vec![ + hex!("cf0d1c1ba57d1e0edfb59786c7e30c2b7e12bd54612b00cd21c4eaeecedf44fb").to_vec(), + hex!("d21fc4f68ab05bc4dcb23c67008e92c4d466437cdd6ed7aad0c008944c185510").to_vec(), + hex!("b9890f91ca0d77aa2a4adfaf9b9e40c94cac9e638b6d9797923865872944b646").to_vec(), + ], vec![ + hex!("f90131a0b601337b3aa10a671caa724eba641e759399979856141d3aea6b6b4ac59b889ba00c7d5dd48be9060221a02fb8fa213860b4c50d47046c8fa65ffaba5737d569e0a094601b62a1086cd9c9cb71a7ebff9e718f3217fd6e837efe4246733c0a196f63a06a4b0dd0aefc37b3c77828c8f07d1b7a2455ceb5dbfd3c77d7d6aeeddc2f7e8ca0d6e8e23142cdd8ec219e1f5d8b56aa18e456702b195deeaa210327284d42ade4a08a313d4c87023005d1ab631bbfe3f5de1e405d0e66d0bef3e033f1e5711b5521a0bf09a5d9a48b10ade82b8d6a5362a15921c8b5228a3487479b467db97411d82fa0f95cccae2a7c572ef3c566503e30bac2b2feb2d2f26eebf6d870dcf7f8cf59cea0d21fc4f68ab05bc4dcb23c67008e92c4d466437cdd6ed7aad0c008944c1855108080808080808080").to_vec(), + hex!("f851a0b9890f91ca0d77aa2a4adfaf9b9e40c94cac9e638b6d9797923865872944b646a060a634b9280e3a23fb63375e7bbdd9ab07fd379ab6a67e2312bbc112195fa358808080808080808080808080808080").to_vec(), + hex!("f9030820b9030402f90300018301d6e2b9010000000000000800000000000020040008000000000000000000000000400000008000000000000000000000000000000000000000000000000000000000042010000000001000000000000000000000000000000000040000000000000000000000000000000000000000000000008000000000000000002000000000000000000000000200000000000000200000000000100000000040000001000200008000000000000200000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000f901f5f87a942ffa5ecdbe006d30397c7636d3e015eee251369ff842a0c965575a00553e094ca7c5d14f02e107c258dda06867cbf9e0e69f80e71bbcc1a000000000000000000000000000000000000000000000000000000000000003e8a000000000000000000000000000000000000000000000000000000000000003e8f9011c94ee9170abfbf9421ad6dd07f6bdec9d89f2b581e0f863a01b11dcf133cc240f682dab2d3a8e4cd35c5da8c9cf99adac4336f8512584c5ada000000000000000000000000000000000000000000000000000000000000003e8a00000000000000000000000000000000000000000000000000000000000000001b8a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004b000f000000000000000100d184c103f7acc340847eee82a0b909e3358bc28d440edffa1352b13227e8ee646f3ea37456dec701345772617070656420457468657210574554481235003511000000000000000000000000000000000000000000f858948cf6147918a5cbb672703f879f385036f8793a24e1a01449abf21e49fd025f33495e77f7b1461caefdd3d4bb646424a3f445c4576a5ba0000000000000000000000000440edffa1352b13227e8ee646f3ea37456dec701").to_vec(), + ]), + } + ) +} + +pub fn get_message_verification_header() -> CompactExecutionHeader { + CompactExecutionHeader { + parent_hash: hex!("04a7f6ab8282203562c62f38b0ab41d32aaebe2c7ea687702b463148a6429e04") + .into(), + block_number: 55, + state_root: hex!("894d968712976d613519f973a317cb0781c7b039c89f27ea2b7ca193f7befdb3").into(), + receipts_root: hex!("cf0d1c1ba57d1e0edfb59786c7e30c2b7e12bd54612b00cd21c4eaeecedf44fb") + .into(), + } +} + +#[cfg(feature = "beacon-spec-minimal")] pub mod minimal { use super::*; - use crate::config; - use hex_literal::hex; - use primitives::CompactExecutionHeader; - use snowbridge_core::inbound::{Log, Proof}; use sp_runtime::BuildStorage; - use std::{fs::File, path::PathBuf}; type Block = frame_system::mocking::MockBlock; @@ -103,86 +208,9 @@ pub mod minimal { let _ = ext.execute_with(|| Timestamp::set(RuntimeOrigin::signed(1), 30_000)); ext } - - fn load_fixture(basename: &str) -> Result - where - T: for<'de> serde::Deserialize<'de>, - { - let filepath: PathBuf = - [env!("CARGO_MANIFEST_DIR"), "tests", "fixtures", basename].iter().collect(); - serde_json::from_reader(File::open(filepath).unwrap()) - } - - pub fn load_execution_header_update_fixture() -> primitives::ExecutionHeaderUpdate { - load_fixture("execution-header-update.minimal.json").unwrap() - } - - pub fn load_checkpoint_update_fixture( - ) -> primitives::CheckpointUpdate<{ config::SYNC_COMMITTEE_SIZE }> { - load_fixture("initial-checkpoint.minimal.json").unwrap() - } - - pub fn load_sync_committee_update_fixture( - ) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { - load_fixture("sync-committee-update.minimal.json").unwrap() - } - - pub fn load_finalized_header_update_fixture( - ) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { - load_fixture("finalized-header-update.minimal.json").unwrap() - } - - pub fn load_next_sync_committee_update_fixture( - ) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { - load_fixture("next-sync-committee-update.minimal.json").unwrap() - } - - pub fn load_next_finalized_header_update_fixture( - ) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { - load_fixture("next-finalized-header-update.minimal.json").unwrap() - } - - pub fn get_message_verification_payload() -> (Log, Proof) { - ( - Log { - address: hex!("ee9170abfbf9421ad6dd07f6bdec9d89f2b581e0").into(), - topics: vec![ - hex!("1b11dcf133cc240f682dab2d3a8e4cd35c5da8c9cf99adac4336f8512584c5ad").into(), - hex!("00000000000000000000000000000000000000000000000000000000000003e8").into(), - hex!("0000000000000000000000000000000000000000000000000000000000000001").into(), - ], - data: hex!("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004b000f000000000000000100d184c103f7acc340847eee82a0b909e3358bc28d440edffa1352b13227e8ee646f3ea37456dec701345772617070656420457468657210574554481235003511000000000000000000000000000000000000000000").into(), - }, - Proof { - block_hash: hex!("05aaa60b0f27cce9e71909508527264b77ee14da7b5bf915fcc4e32715333213").into(), - tx_index: 0, - data: (vec![ - hex!("cf0d1c1ba57d1e0edfb59786c7e30c2b7e12bd54612b00cd21c4eaeecedf44fb").to_vec(), - hex!("d21fc4f68ab05bc4dcb23c67008e92c4d466437cdd6ed7aad0c008944c185510").to_vec(), - hex!("b9890f91ca0d77aa2a4adfaf9b9e40c94cac9e638b6d9797923865872944b646").to_vec(), - ], vec![ - hex!("f90131a0b601337b3aa10a671caa724eba641e759399979856141d3aea6b6b4ac59b889ba00c7d5dd48be9060221a02fb8fa213860b4c50d47046c8fa65ffaba5737d569e0a094601b62a1086cd9c9cb71a7ebff9e718f3217fd6e837efe4246733c0a196f63a06a4b0dd0aefc37b3c77828c8f07d1b7a2455ceb5dbfd3c77d7d6aeeddc2f7e8ca0d6e8e23142cdd8ec219e1f5d8b56aa18e456702b195deeaa210327284d42ade4a08a313d4c87023005d1ab631bbfe3f5de1e405d0e66d0bef3e033f1e5711b5521a0bf09a5d9a48b10ade82b8d6a5362a15921c8b5228a3487479b467db97411d82fa0f95cccae2a7c572ef3c566503e30bac2b2feb2d2f26eebf6d870dcf7f8cf59cea0d21fc4f68ab05bc4dcb23c67008e92c4d466437cdd6ed7aad0c008944c1855108080808080808080").to_vec(), - hex!("f851a0b9890f91ca0d77aa2a4adfaf9b9e40c94cac9e638b6d9797923865872944b646a060a634b9280e3a23fb63375e7bbdd9ab07fd379ab6a67e2312bbc112195fa358808080808080808080808080808080").to_vec(), - hex!("f9030820b9030402f90300018301d6e2b9010000000000000800000000000020040008000000000000000000000000400000008000000000000000000000000000000000000000000000000000000000042010000000001000000000000000000000000000000000040000000000000000000000000000000000000000000000008000000000000000002000000000000000000000000200000000000000200000000000100000000040000001000200008000000000000200000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000f901f5f87a942ffa5ecdbe006d30397c7636d3e015eee251369ff842a0c965575a00553e094ca7c5d14f02e107c258dda06867cbf9e0e69f80e71bbcc1a000000000000000000000000000000000000000000000000000000000000003e8a000000000000000000000000000000000000000000000000000000000000003e8f9011c94ee9170abfbf9421ad6dd07f6bdec9d89f2b581e0f863a01b11dcf133cc240f682dab2d3a8e4cd35c5da8c9cf99adac4336f8512584c5ada000000000000000000000000000000000000000000000000000000000000003e8a00000000000000000000000000000000000000000000000000000000000000001b8a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004b000f000000000000000100d184c103f7acc340847eee82a0b909e3358bc28d440edffa1352b13227e8ee646f3ea37456dec701345772617070656420457468657210574554481235003511000000000000000000000000000000000000000000f858948cf6147918a5cbb672703f879f385036f8793a24e1a01449abf21e49fd025f33495e77f7b1461caefdd3d4bb646424a3f445c4576a5ba0000000000000000000000000440edffa1352b13227e8ee646f3ea37456dec701").to_vec(), - ]), - } - ) - } - - pub fn get_message_verification_header() -> CompactExecutionHeader { - CompactExecutionHeader { - parent_hash: hex!("04a7f6ab8282203562c62f38b0ab41d32aaebe2c7ea687702b463148a6429e04") - .into(), - block_number: 55, - state_root: hex!("894d968712976d613519f973a317cb0781c7b039c89f27ea2b7ca193f7befdb3") - .into(), - receipts_root: hex!("cf0d1c1ba57d1e0edfb59786c7e30c2b7e12bd54612b00cd21c4eaeecedf44fb") - .into(), - } - } } -#[cfg(feature = "beacon-spec-mainnet")] +#[cfg(not(feature = "beacon-spec-minimal"))] pub mod mainnet { use super::*; @@ -237,25 +265,25 @@ pub mod mainnet { } parameter_types! { - pub const ChainForkVersions: ForkVersions = ForkVersions{ + pub const ChainForkVersions: ForkVersions = ForkVersions { genesis: Fork { - version: [0, 0, 16, 32], // 0x00001020 + version: [144, 0, 0, 111], // 0x90000069 epoch: 0, }, altair: Fork { - version: [1, 0, 16, 32], // 0x01001020 - epoch: 36660, + version: [144, 0, 0, 112], // 0x90000070 + epoch: 50, }, bellatrix: Fork { - version: [2, 0, 16, 32], // 0x02001020 - epoch: 112260, + version: [144, 0, 0, 113], // 0x90000071 + epoch: 100, }, capella: Fork { - version: [3, 0, 16, 32], // 0x03001020 - epoch: 162304, + version: [144, 0, 0, 114], // 0x90000072 + epoch: 56832, }, }; - pub const ExecutionHeadersPruneThreshold: u32 = 10; + pub const ExecutionHeadersPruneThreshold: u32 = 8192; } impl ethereum_beacon_client::Config for Test { diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/tests.rs b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/tests.rs index 92a93720ae9..d6346d3aafe 100644 --- a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/tests.rs +++ b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/tests.rs @@ -1,15 +1,28 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork use crate::{ - config::{EPOCHS_PER_SYNC_COMMITTEE_PERIOD, SLOTS_PER_EPOCH}, - functions::compute_period, - mock::minimal::*, - pallet::ExecutionHeaders, - sync_committee_sum, verify_merkle_branch, BeaconHeader, CompactBeaconState, Error, - ExecutionHeaderBuffer, FinalizedBeaconState, LatestExecutionState, LatestFinalizedBlockRoot, - NextSyncCommittee, SyncCommitteePrepared, + functions::compute_period, pallet::ExecutionHeaders, sync_committee_sum, verify_merkle_branch, + BeaconHeader, CompactBeaconState, Error, ExecutionHeaderBuffer, FinalizedBeaconState, + LatestExecutionState, LatestFinalizedBlockRoot, NextSyncCommittee, SyncCommitteePrepared, }; +use crate::mock::{ + get_message_verification_header, get_message_verification_payload, + load_checkpoint_update_fixture, load_execution_header_update_fixture, + load_finalized_header_update_fixture, load_next_finalized_header_update_fixture, + load_next_sync_committee_update_fixture, load_sync_committee_update_fixture, +}; + +#[cfg(feature = "beacon-spec-minimal")] +pub use crate::config::minimal::*; +#[cfg(feature = "beacon-spec-minimal")] +pub use crate::mock::minimal::*; + +#[cfg(not(feature = "beacon-spec-minimal"))] +pub use crate::config::mainnet::*; +#[cfg(not(feature = "beacon-spec-minimal"))] +pub use crate::mock::mainnet::*; + use frame_support::{assert_err, assert_noop, assert_ok}; use hex_literal::hex; use primitives::{ @@ -168,7 +181,7 @@ pub fn verify_merkle_branch_fails_if_depth_and_branch_dont_match() { #[test] pub fn sync_committee_participation_is_supermajority() { let bits = - hex!("bffffffff7f1ffdfcfeffeffbfdffffbfffffdffffefefffdffff7f7ffff77fffdf7bff77ffdf7fffafffffff77fefffeff7effffffff5f7fedfffdfb6ddff7b" + hex!("bffffffff7f1ffdfcfeffeffbfdffffbfffffdffffefefffdffff7f7ffff77fffdf7bff77ffdf7fffafffffff77fefffeff7effffffff5f7fedfffdfb6ddff7b" ); let participation = primitives::decompress_sync_committee_bits::<512, 64>(bits); assert_ok!(EthereumBeaconClient::sync_committee_participation_is_supermajority(&participation)); diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/execution-header-update.mainnet.json b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/execution-header-update.mainnet.json new file mode 100755 index 00000000000..97d498e2d9e --- /dev/null +++ b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/execution-header-update.mainnet.json @@ -0,0 +1,50 @@ +{ + "header": { + "slot": 4058654, + "proposer_index": 1039, + "parent_root": "0x758fa0a54047c0221b3107423e78b8910514ba7a0c4250401dac77108dce2ff8", + "state_root": "0x53c79320b4b7649e39a9f07903f4fc68a7cfe7a81cb2e30293dd7b00ee13f69a", + "body_root": "0xa76a7f037f12ee070dcb273d9787b13ff0cf17420a39564a101789318a157ec3" + }, + "ancestry_proof": { + "header_branch": [ + "0xbb6cfda1e02c3117d9fa41c1e1594ce0645352a073ad8b474f83c148e0d9954f", + "0xb44967bd8ff799126cad993ff7369f7a28d60281304d0c7c058e6721b6ce4c61", + "0x0009710ef2467f95542c2e8e7a7249282c08f62aedbe7d21ae4a7af04e1a890d", + "0x7bc5dc20638cfe1cfd5d2547c3efbed4cfb533c76c27d41f723ed876ab9edc3a", + "0x6dcd59a8a041cf2591921417cb8133f0ff5af9bfe1f1ab491e75a751adc9c9e1", + "0x3f25a2852042c7bf2c421bf16c0b9373c1d27ccb1eca4088f8191712481261be", + "0xd1f9cfe1f04031459e5c45f47b2a49c780cabb8ca5b8d76461db2b88c337ed76", + "0x8c37e3119bf7d3cb8208e832669261b0eda1b3c7b11d321760ba1c0649f61416", + "0x1783d3b7041ecb78d9e1f913b82bd335229ca1f2cc5d3cc8dd28c94152e887b4", + "0xe39fc366c951c7cb2100308b0a9417581c46812a7d7e89f516c19863f7686f96", + "0x3c29b6d9b8715dbe5d6831364229efc91ad56ae69e93cb119d5ef4bdc53fcb37", + "0x3cf6fe5e8d91dbaa77e6befa81e04fb25a3e089317d83ff35fc8adfbbf2aab5a", + "0xb41c97cf3b1b4b5bf2999dfb1b3eaeac5c1b12205e9ab0809988e3779d119047" + ], + "finalized_block_root": "0xb4802863fc1d32778211ce6aac8109c73c516a003213f4f5333c80472d08fe4e" + }, + "execution_header": { + "parent_hash": "0x9cffcba69c88a619483e13864704dde5db80e05f8d49018f615395ce09cd24ab", + "fee_recipient": "0xff58d746a67c2e42bcc07d6b3f58406e8837e883", + "state_root": "0x6a4aafc93626778475a416721104229035e91f0db788d0099b57e756cd272f0a", + "receipts_root": "0xe1ce670bdcf9acf4c62fee845cd7e81eabbb6db9ddbff56130020c6cf999a45d", + "logs_bloom": "0xa000980408008000328c1458805c005048b84812c134200090b40428568108a0648090105085100301844800090802484420800d020282019002040d083004031a20420240a4a8900a43296938c040802040220170860210910020036b8c482228c004440300021c82c0400110402a10800582424001c00000828310210020a18130504020790dca716194100880ea5501149104002bc05e189080901c4001010e0a040658a410072021230a5224265030082404000aa11f28162e216636000408842103d41010760972060060000500c20130b000000065401483200081a84934f020020120009618002269c884724616040000840e18080300024490000230", + "prev_randao": "0x5d9ac7ea788ecb534e98bc9079fa0bef199011dadadedaee5dc40e2cd702d664", + "block_number": 5025098, + "gas_limit": 30000000, + "gas_used": 13802943, + "timestamp": 1704437448, + "extra_data": "0x476f65726c69205365706f6c69612d4265706f6c696120513966", + "base_fee_per_gas": 19959019915, + "block_hash": "0x795021134c2b7f9c00b498ff7b0971dbbe061561868f702d8ca68a05e5eb5a99", + "transactions_root": "0x3cb7c92fde5d511cc90cd67e375c4388794f4c01e375e8e8a06d003b5593fd12", + "withdrawals_root": "0x5f5155fd8e5cd24b7ecb1e039792b0caff01dfda2990786d9ffc88325b5d1ea8" + }, + "execution_branch": [ + "0x85ff3d1c2bc3dcdd5543bcd29a1224c6a8c24875224fbb1e3b69f0515ffaacda", + "0x336488033fe5f3ef4ccc12af07b9370b92e553e35ecb4a337a1b1c0e4afe1e0e", + "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", + "0xfe1fa7acd413c54ebd394126ade19fc624ad9e4c60792d54ff3d60b07076b76d" + ] +} \ No newline at end of file diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/finalized-header-update.mainnet.json b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/finalized-header-update.mainnet.json new file mode 100755 index 00000000000..49434dee72d --- /dev/null +++ b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/finalized-header-update.mainnet.json @@ -0,0 +1,38 @@ +{ + "attested_header": { + "slot": 4058720, + "proposer_index": 1088, + "parent_root": "0x37c7398a391c71da07258b48f41d4caaaf891fdf558e110b9c25db716fa8ff55", + "state_root": "0x6cf68a66c993f1c27f499e054a5fbd7c0e625c34ea0057fda9691c561e990002", + "body_root": "0x109e4c0c647d42dba0c8c6569997c51b5bcfc1a33475b1433ded6353f48423ff" + }, + "sync_aggregate": { + "sync_committee_bits": "0xffffffffff7bfdfffff7fffff1effffef7f9ffbdfdffffffdffbfffbbf7ffffffffffefdf7ffbeffdffef7bfffffffffffbffffffffffbffffffffffffffdfda", + "sync_committee_signature": "0xb5727bad1db101b6f0fd7ec4cb79b43dae90366fe0cae31a62439388eb03ebd75732cee3bde51f814203a4c0f5b23898120cd0870f0e662bdf0f85a048b534d9a906e6d32a65df019059d34f724221075734ec2849c09679febecf6929934f09" + }, + "signature_slot": 4058721, + "next_sync_committee_update": null, + "finalized_header": { + "slot": 4058656, + "proposer_index": 810, + "parent_root": "0xbb6cfda1e02c3117d9fa41c1e1594ce0645352a073ad8b474f83c148e0d9954f", + "state_root": "0xf938f0f0cba85234afbaace20545134c70b35e6ff9f74d944b0fea309109f3cf", + "body_root": "0xcf6a7a6f653cb64b2b910278a478339b34eb08abf00e0766d10c7a8fe9bdb139" + }, + "finality_branch": [ + "0x71ef010000000000000000000000000000000000000000000000000000000000", + "0x3d4be5d019ba15ea3ef304a83b8a067f2e79f46a3fac8069306a6c814a0a35eb", + "0xa2e2a28c0bb0ad56c25f3c461a4bfe4f3b3b894bc0105a62e85f43a4ae1adc3f", + "0xaa2bad8cf9b0433d3d79bc5b95c067048b018d1d2ffd0c66db6e7cf86e0a314e", + "0x027f238235d07ac9757543c19deabe1d553d6fc110e8bea4b037b1fab263b4dc", + "0x7dfa1cc1907e8927295f78a770bf86b28f5c2bddcac38beb3b4beb265ff5608f" + ], + "block_roots_root": "0x4a5a57fb0769443f6472f59dbb78d7a9a69ff61d09aa89d5da645d634ec46a14", + "block_roots_branch": [ + "0xa09ad7f3afd681bb6fd54abba339549f3b601beedea79a5b7d448b1cf1e1613e", + "0xacdfd4d5eba154f118a84af7a2d17ba6100fcd9c24fc235e927f584a5b56e32f", + "0x36ca106eac009ed605e680415b105b3a6591830c38034511f300aae44802235f", + "0x171561a9e1afb413132d0f4d3cbbd810766c151be32ec9f2d609f40aef9e2588", + "0x7cd963eba3fb57ee5ce37ee4b621d24fc14d642e32f48dc48ade528e11458ab9" + ] +} \ No newline at end of file diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/initial-checkpoint.mainnet.json b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/initial-checkpoint.mainnet.json new file mode 100755 index 00000000000..1f0f837f596 --- /dev/null +++ b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/initial-checkpoint.mainnet.json @@ -0,0 +1,542 @@ +{ + "header": { + "slot": 4058624, + "proposer_index": 631, + "parent_root": "0x4abadda13b61df8d40fcb061d1ec15d0fb7bc5144252bb54c57b41893b642bf3", + "state_root": "0x6fe9fa01a04dcdeaa64eba04a72fa6dbadc8596dc5ec1fff2ef343520fe722e1", + "body_root": "0x6cd83df0ee7669e06e64496a1d2be083bc3bb9f2da17e9b1e62979d200328106" + }, + "current_sync_committee": { + "pubkeys": [ + "0xa13bf1fc1826b61cceefcc941c5a4865cefdfa6c91e5223308fa6a0aa6e7b13a0499a63edf5d9fff48fdeae83e38dcbf", + "0xb3285148b91dab139b053442bdd14d627ba1e1250fe469f0f2df854b6e6ff4a18671ae3879ec9f7d8091f99f092162e9", + "0xb00d95908e72c6051478a422eb2231b5f797c2fa5c696ed1e6b9c9996ba1d8236f512443f18c01ce63312c38fa383fd4", + "0xa866633b4293e726accf6e97ac90c1898cac83e8531a25b50ae99f0ecb477a692e6a5f2488447ccd83ed869ab5abc406", + "0xa308ed8737b3a9346ff20dc9f112efccc193472e6fde6aa218ceae11e288bbd2c35fa45c1d8bb238696a96767cd68b46", + "0x81534e2a182da0c6831479c7e722953d267ba9c63a204ac96a178b1dc90d0a6ba8737002688ba5f102eda5669249f114", + "0x87c5670e16a84e27529677881dbedc5c1d6ebb4e4ff58c13ece43d21d5b42dc89470f41059bfa6ebcf18167f97ddacaa", + "0xb37334c41a3456b73b61d0eb0777260af9c2e400bbec0e0c0fdb45c39ce0dd19f021d9760f35da801f20486c6be30e9e", + "0xab73a043ccdfe63437a339e6ee96ef1241264e04dd4d917f6d6bc99396006de54e1e156d38596ba3d15cb1aaa329f8f5", + "0x8983fdebbeba6e3cc3ee1c9feb24faaeee712356975e359b0ddca3f7c9c7448132d665f54a4629002252d3fcf375f7b0", + "0xa03c1e287ccc4d457f5e71e9dc769294835945561e6f236ac7de210d2e614eee8a85e21dfb46e2143c68de22ccee8660", + "0x8e6b888197010ebadd216da35b9716daa8675d93b3c33a96a19fd9ca42624f6b430b2ff115cd0f5b717341605dda24bf", + "0x8fb51e3ef3c1047ae7c527dc24dc8824b2655faff2c4c78da1fcedde48b531d19abaf517363bf30605a87336b8642073", + "0x893272a63650b08e5b8f9b3f17f8547b456192ad649c168bafd7166b4c08c5adf795c508b88fd2425f7be8334592afb2", + "0xa90c42266ca0a65976fb4dc18465b0a44a63ed3b2747cae74e46e3ccf158f98384e2e86c852e7c5556b083b3ded9d243", + "0xb67c621d9b6313a9f6744dfcdd77d4e9cb4bd413fb5e3199cdcd7f675fc39f1ba492860749bfddf98f4088756e844a98", + "0xa9760afaa51002be0948acf7aebd90ec4e60e0dba8456e445aea93408a0468b62bb6da4984b92f8f6061561c9d56f4c4", + "0x981b2d7c56ff38f1d02c5d7a7f8bfe71daaf94d48c3bc93e8083a0a23c1ae1ff05f90312deb09b35d4513c1ffa573d86", + "0x9515dedf061e654d58a43e4e525a63ad2a6274ea6f20b1d624a6ba7d3062ed68a0226eee6951ab8464906c52ba5556b0", + "0x901f724ee1891ca876e5551bd8f4ad4da422576c618465f63d65700c2dd7953496d83abe148c6a4875a46a5a36c218cf", + "0xa8d152e5d94b75cb9e249230db21af31de4d4f3d4ef60ccbf2212babf69aed2a38435a993ee2f13cca410ad55a4875ab", + "0x875ebfe737cea438e967d70ceaffb4360cce28ecc76c8c4ee612c47fb6b3e89af03c66981571066107323f49a6242772", + "0xa798a0371e8cc4dc42ccd79934b0db5a3a59f18a0ae09f2eb172596428fcb3f00312e783d6fd21cbc1610317f44e08cb", + "0x99c629c9cd603a9344b04d22d2bcc06cf45ebf62d97f968df19c73c7a50f4f6a2a2cc7fb633f509f961edfb94fbab94e", + "0x854410e6fb856da8b997ebf28ae2415ce6e1f9f6a4579fad15b5df61709c924a925397b33fe67c89ffad6143a39d756a", + "0xa3969926aa2e52f1a48ac53074b764648b4c71bd43430944679628463cd68398f700d874c14503b53756be451c8ba284", + "0x8ee8873de7cd28a54ba2c63a80b63399effed76b154e96ed26e7c0668b9f2476e298688b6a00c4b2ab9d020a897695d7", + "0xad54241ba3de6a4426c788690d3f78d2eb678814edc49d3fb988d7fc752e43512972567bb384bcc1b18d083d15e376da", + "0x942bee9ee880ac5e2f8ba35518b60890a211974d273b2ae415d34ce842803de7d29a4d26f6ee79c09e910559bdcac6d3", + "0x96b478b1e5e49d4ea3fd97c4846ae0f781dcc9f9ff61ee022ca92c3d8dfba89c513c46e8bb38b73e6b678a79b9b12177", + "0xaad9577501d7f3a5dbac329f2c1fe711710869cc825740f365488fc55a278d687bb72423560f7cb2cbd60546a82ea1e6", + "0x8aa3d9dad1c122b9aed75e3cc94b3a9dab160fa4cad92ebab68a58c0151a5d93f0f6b40b86fba00e63d45bd29a93b982", + "0xa12fc78b8d3334a3eb7b535cd5e648bb030df645cda4e90272a1fc3b368ee43975051bbecc3275d6b1e4600cc07239b0", + "0xab01a7b13c967620d98de736b8ff23d856daa26d5cd8576993ee02a5d694332c0464ed018ebffcd5c71bab5cada850ce", + "0x96cf5760c79cfc830d1d5bd6df6cfd67596bef24e22eed52cee04c290ad418add74e77965ea5748b7f0fb34ee4f43232", + "0x9443e6ba4400fb3370c573cd7e33f05e1475f9cf1d6adb905bee3aff8f1452d8d384c8a72c9110070f35c6aad940bba6", + "0x95c60b5561e53cfc26d620be90f84199ffd6dd9687c1be3a547048e7cba10a0be9bb6da000e7521cbd488d0901d48ee9", + "0xab69cf79750436d310dc3c5e96c2b97003f4394f31dfa8a9ac420595dc7b4d96dad5787d93347ba2bc6f196c241a3dbf", + "0x9145ee1fb6e84114c903819db94fa5a72bcbc15fcb8a7fd8eefba23b156cc46309281dcf78b48a2847b3754f7d7d7a79", + "0xb118f77f99ac947df97e7682f0fb446175185b842380af4ee7394531e4f93002c72b41a57a7c1b923a4f24b10924c84f", + "0xa4aabd1890ebf35423565dbff3477a09eea4e35f5a26ed449eab38e0a21fb89e9ddfe3a2003cddc457db648a1b5891a3", + "0x8ff5d2e6c98b1fea70cb36ea8ed497fd1233b9418948ac58c6c379ed35fb10f8253ef188c909d5e77e81b5b8e2a4ad17", + "0xa23f076306c120dccf69d7d2ac7f83a377a72d35bf448f88feff8b6dba9307fdabf34452e30b87407b2258b9edfd1174", + "0x87d2217eb05d657aba7b048cf3c661b463e78e51135a5b937e71975ff5102e596434720f02349c73415decb88418cb0d", + "0x8bb51b380a8a52d61a94e7b382ff6ce601260fa9b8c5d616764a3df719b382ec43aec9266444a16951e102d8b1fb2f38", + "0xb0053550040ab3a3996cba5caf9ad5718867b5f5df273ed8c6520761571f03a94e50b5f8a6a8c42d725383cce97d3cae", + "0xae50f93230983a82e732903d6ed50a506d678f35b6b4a4b3686a92b12aeb9d34cb095e8562b0900125bbced0359b37de", + "0x8bfa106ada4914419bf1d8900c5981dd5b90c3023196d7e918d62879fc3a575bd0a25f939366f7fd2240df6108b069ec", + "0xb3a5497365bd40a81202b8a94a5e28a8a039cc2e639d73de289294cbda2c0e987c1f9468daba09ea4390f8e4e806f3c8", + "0xb4f583e10aa9af79b4ebd647e0fffe1c720112727e5ffac4313f236737491fceeee194537786c561cd5777b453e5b03c", + "0x826be957cf66db958028fa95655b54b2337f78fb6ef26bd29e2e3a64b130b90521333f31d132c04779e4b23a6b6cd951", + "0xaace45334070c51cc8b3579598d4cd8cda2153bba51f56e3b1fe5e135c83ef70503c322756b9cad9d3cd28f1ecfc8227", + "0x94bb68c8180496472262455fd6ab338697810825fa4e82fc673f3ac2dacfd29ee539ac0bfe97eb39d4ef118db875bab6", + "0xb560c33950a355119845f63defb355807e56773f636fb836f7746155fad070e384fc1091b8e5c057e4cbc7da9275ecf7", + "0x820cc2ac3eed5bce7dc72df2aa3214e71690b91445d8bb1634c0488a671e3669028efbe1eae52f7132bde29b16a020b7", + "0x9244703338879e3ea00663dcde8f11095de3e38df9277d8c2acc26e72021c222ae40bcc91228789fdf0b69acc3144783", + "0x8d474636a638e7b398566a39b3f939a314f1cf88e64d81db0f556ca60951ec1dca1b93e3906a6654ed9ba06f2c31d4ea", + "0x889a5cf9315383bf64dfe88e562d772213c256b0eed15ce27c41c3767c048afe06410d7675e5d59a2302993e7dc45d83", + "0xb544c692b046aad8b6f5c2e3493bc8f638659795f06327fff1e9f4ffc8e9f7abdbf4b7f6fcdfb8fe19654d8fa7d68170", + "0xaefc682f8784b18d36202a069269be7dba8ab67ae3543838e6d473fbc5713d103abcc8da1729a288503b786baac182d3", + "0xa0f2092ac34d2363614fb2f57fc7b72db247eb1fa53f395881ce6b4aacd6fb920d6dc59507701d487288102e4c4fa389", + "0xb33de3de106be61481ccb7f07a7a63cf4d1674010e462388fb8ab5ea08f444ed7a277905207e0b3aa2f00bb9efca984f", + "0x84173aeaf3d96368dc7ca1ad5e5575da279113567e5815a364a0356a720c5e08cb58ca1fdd891924f4871d3eaae5de40", + "0xb6d6482ad7b9b412ffbefbbdcc28eb3d091b1291f54f77bdd53c4ac85f705c454940f466dc272dde7b03c26f0cd6ecb3", + "0xa2053719da2b7501dab42011ae144b3c8d72bd17493181bf3ae79a678068dc3ee2f19d29a60b5a323692c3f684f96392", + "0x8296f8caf58316af535def398a43357e48cb3b1e674b857eba1bd1b970da3dd045e22fe6d17dee4e9117f62ece3ec31c", + "0x84faf4d90edaa6cc837e5e04dc67761084ae24e410345f21923327c9cb5494ffa51b504c89bee168c11250edbdcbe194", + "0x879aea8f09dec92f354e31aa479d00cb77457d363de2d9a51ddf7d734061b6f83d6345cf33dbef22004cd23dd6c4b760", + "0xb8fca0f7bc276f03c526d42df9f88c19b8dc630ad1299689e2d52cd4717bbe5425479b13bdf6e6337c48832e4cd34bb5", + "0xb2a01dc47dd98f089f28eee67ba2f789153516b7d3b47127f430f542869ec42dd8fd4dc83cfbe625c5c40a2d2d0633ea", + "0xa19f2ce14e09ece5972fe5af1c1778b86d2ab6e825eccdb0ac368bb246cfe53433327abfe0c6fa00e0553863d0a8128e", + "0x95d1f944b0c53eb3e9fcd5632713602bbb9195b87a172a370ae2df98504612a55f3968615a39b569ce6a0fe9fb559be7", + "0xae36ab11be96f8c8fcfd75382bb7f4727511596bc08c25814d22f2b894952489d08396b458f7884d6b3c0adb69856a6d", + "0x824d0dc002e158adef06fc38d79b01553be5a3903566029cf0beddb2248b11da40e66feb168e8e3e2a63ea033a75f382", + "0x8f9f85ae6377414fcf8297ed45a736210cd3803f54f33116b0f290b853dc61e99ea08f3c422ed9bc6bdc2f42ab4f56ba", + "0x86c53fc078846c3d9bc47682506f8285ba4551475921fd388b96291741970c34b8de4210202e40d2de4acb6e2892072b", + "0x853184f246d098139230962e511585368b44d46a115c5f06ccaeef746773951bead595fb6246c69975496bac61b42a4f", + "0xb91b4260e2884bae9778fe29a2c1e4525e4663ec004159def5d47320de304c96d2a33ad7a670e05acf90cbba3efdd4d9", + "0x83492e27e07e35c0836aee6bee95d040b8d3e82db6f94a3917d07797800f7200f5dbc6c9596c6c3c70f8f470b65a9b6e", + "0xb1bb33607d10ea8c954064ecb00c1f02b446355ef73763a122f43b9ea42cd5650b54c5c9d1cfa81d4a421d17a0a451aa", + "0x99cb1728157a1b7cdd9607cf15911bbcb56b64d52fb0d0117b457853a81ec55913f977850f26e188fa2652579efe9ddf", + "0x8b7cb5b8de09a6dfceddcbaa498bc65f86297bcf95d107880c08854ed2289441a67721340285cfe1749c62e8ef0f3c58", + "0xb97447233c8b97a8654749a840f12dab6764209c3a033154e045c76e0c8ed93b89788aac5cd1e24ed4a18c36de3fbf60", + "0xb4790910e2cbef848448f24f63e9dd4a1b122cf65feecf152d5fde282ad6fcc6ea3f9cc23178baf85612020795e4b13a", + "0x81fc724846b5781f3736795c32b217458bb29972af36cc4483dd98ab91680d3d9bc18842db2661487d3a85430dc9e326", + "0xa154892ff23b284040e623bba940a6a1ef1207b8b089fc699cb152b00bcce220464502cfa1dfb5a2f62e6f3960cdf349", + "0xaf3f765fd293c253072b33a780ed68933f78d7e079d9a2079b6232755bedf6ebcbce9ba65c01f695602fa8ee17899867", + "0x97578474be98726192cb0eac3cb9195a54c7315e9c619d5c44c56b3f98671636c383416f73605d4ea7ca9fbeff8dd699", + "0x917c4fd52538d34c26ccdd816e54ebea09517712aa74cec68a2e3d759c6a69b5ccb4089ad1e0b988e916b2ce9f5c8918", + "0x8cf3c29531a17489a5f8232d56c5251ffddc95be3ff7ff61472e19fb38c5eaec841ef3b1ee36756b3dd8ff71ae199982", + "0x96d4b9b411319e531bab6af55c13f0adb1dd6b4286784ff807f283e7990dc368c16d536fc5db3d992deb4b0278914e6f", + "0x8903f7e0c9764ce844b15d84feea04406dc66b195a5f82ff4027f27361e11cf368538137d139368f5a6f42876b04f056", + "0xa4047173b5906c9b4292aaee1e91d9080ae74b1d3eb990449ed1f96bf22c3ee80f4915361e5bf7dccce24ae1618dae77", + "0xa4c4b96071e7bc92e41defba3507ddf423d93f3a94271b1f9812dfc4660e4c9fd24e0dd7aef324c46deb8d7a7c97eaa4", + "0x8289b65d6245fde8a768ce48d7c4cc7d861880ff5ff1b110db6b7e1ffbfdc5eadff0b172ba79fd426458811f2b7095eb", + "0xab4119eef94133198adb684b81f5e90070d3ca8f578c4c6c3d07de592a9af4e9fa18314db825f4c31cea1e2c7c62ed87", + "0xa3ffc3dad920d41ec3f4c39743ef571bcabb4430465d9aa811d0f0a7daa12bee4ed256527d16a6e937bf709ebb560ebd", + "0x8553748da4e0b695967e843277d0f6efeb8ba24b44aa9fa3230f4b731caec6ed5e87d3a2fcd31d8ee206e2e4414d6cf4", + "0xb15e1b4ac64bafbc4fdfead9aeff126bf102fdd125c1c914f7979680ec1715fbeccf3dc35c77d284421ec1371ed8bc32", + "0x9377aab082c8ae33b26519d6a8c3f586c7c7fccc96ec29a6f698b67d72d9266ad07378ba90d18e8c86a2ec77ecc7f137", + "0xb71c11828ecad7731136cb1f5b80392a4add8d62f8866a781fdde797a201ebf6d483b2348aacbea2061a5108933b757d", + "0x86793899ef71740ab2ec221d0085701f7909251b1cf59a276c8d629492f9ef15fc0b471beedc446a25b777391ab00718", + "0x8100b48ac2785477a123a7967bfcea8bacef59391680a411692880098a08771ff9786bd3b8dfb034cae00d5a7665621c", + "0x8b027c14affe47f83ee59b504d83b2fd2d9303de2c03ee59d169bb199d9f4bd6533d7f8c812dd7a6f1e8155e3e185689", + "0x9615800f8c95f95bf25055ae079b964e0a64fa0176cc98da272662014f57e7cd2745929daf838df0094b9f54be18b415", + "0x951aa38464912a29df2101c60771d6de7fadb63f2db3f13527f8bdacb66e9e8a97aaac7b81b19e3d1025b54e2c8facff", + "0xa0e68d24f784fcb2b71acc2d5871285623c829d0e939146b145e04908b904468a67c07a2f156e6b17bf531adc5777c4b", + "0x86a533b02ae929f67c301649a2d58651b98cdffe731b63fa32aa1013c271634bbb088c0d02865913c11bbb1bf57c0e12", + "0x81f145ebb9a5674a5b052d0e9059acc8f8ab612dd9f54d43ff620202606e19a86a9b284dc6480d555a030e5fefee8c50", + "0xa698b04227e8593a6fed6a1f6f6d1eafe186b9e73f87e42e7997f264d97225165c3f76e929a3c562ec93ee2babe953ed", + "0xb3180ded54610b1b3a2db7db539197ced6a75e9bb381d1f4b802ca7cd450f5418522ad2bee3df1956ed63ff1ffe95dc1", + "0x86fa3d4b60e8282827115c50b1b49b29a371b52aa9c9b8f83cd5268b535859f86e1a60aade6bf4f52e234777bea30bda", + "0x97d076617cf0a64ab3d1f030cfd72a303b6b252c0a7b96157ff7fc8af5970f00d14492c46e8f6f37caafe837d0dc95c7", + "0xac2c98a0ab3f9d041fc115d9be4a6c77bd2219bb4b851cbee0d9257a4de5791251735b5b8fad09c55d16eb0d97080eff", + "0xace7fda25c2fb7c18710603c16a0ff0f963352d1582a42a20c9f5603c66f485df8383465c35c31e8379b4cb2ec15b4c4", + "0xa07b35ec8d6849e95cbd89645283050882209617a3bb53eae0149d78a60dbf8c1626d7af498e363025896febdba86ee7", + "0xb2fc4478830f2ae4234569346d80b59899247c609b75bd2190a896498539e1f30dca5edbad69f0224918d09f0d7eb332", + "0x84926cf2265981e5531d90d8f2da1041cb73bdb1a7e11eb8ab21dbe94fefad5bbd674f6cafbcaa597480567edf0b2029", + "0xb5f32034d0f66bcbccefe2a177a60f31132d98c0899aa1ffff5ebf807546ff3104103077b1435fa6587bfe3e67ac0266", + "0x938206740a33d82ffda3e01598216324731335d367965aa0b740486d60ba2e86a4ecd546851046a61a4b0fc88295b5cb", + "0xad2b1ab32161e37ee553e3787f05f9281073d7ef7d0ae035daa353bc83da8ef8c76c99ad2928463c7c708f7404020476", + "0x94f4720c194e7ea4232048b0af18b8a920fde7b82869e2abcc7e14a9906530be1ef61132884bb159df019e66d83a0315", + "0xa26dd9b28564c3d95679aca03e3432ac26e287f80e870714c5946b05538b3cb43bba7b85c16bceb5430e81b7a04c1b1d", + "0x8ef0930db046c45ca5c69d565d54681d2b6d249e27092736aee582b29de3aac3fd96e1066a57cadd851b4e5334261594", + "0x92096ebf98ebac5c82345d3ef0db0f5a14af23ceea73279087426b281d6701997fe131fe65a7df7d624b4ff91d997ae8", + "0x81c850f419cf426223fc976032883d87daed6d8a505f652e363a10c7387c8946abee55cf9f71a9181b066f1cde353993", + "0x97070a33393a7c9ce99c51a7811b41d477d57086e7255f7647fd369de9d40baed63ce1ea23ad82b6412e79f364c2d9a3", + "0xa99cde5c7c85ae291c74c893e598cc0e6eb2dda2a81dbb504a638eb21dd2c41d6e5caf7baa29e3c1c32e94dca0d791f1", + "0x937ccbf8cd19b82af2755b4856cfcca3d791e33ae37e4881982ea89d3b21d205a9402d754fac63037243e699484d21f6", + "0xad7dca7640444f1268f03b67544815d4366c6a4a2f0d25ee78f3361c63095416216fd31aa0bcce7448cdd7ba73a6344e", + "0x84991ca8ef255610ebc6aff6d66ea413a768e4d3a7764750fd02b5cd4735d41df399b36e87647fc83cf73421a39d09e9", + "0x91215fc3f7243638733fe293dab7029e0c4275550102acf5f1638773cf8f8ef2c53ffa5bdfc1b602c269a2b5ab164b7a", + "0xaa6cfb3a25f4d06c3ce1e8fd87496a74a5b951ab72557472a181a2e278c5e982d290dd4facf40bd2f4f8be62263dadb0", + "0xac9f29ad08aaf27581fe1f12e210ad4ac6011507fe3100763a4120f9e439f3c6d191f3fb55aadf58bd865cfd4406c68e", + "0x87c6cb9ca628d4081000bc6c71425b95570291eb32ef2cf62416bd1ce3666eb2ce54accd69f79d506cefbfe6feb5a1da", + "0x93042dd42e56671155bb40d85d9d56f42caf27bd965c6a7a7948b39089dba8487d4d5fd30522dba6ba392964e3ffd590", + "0xa76adeddf2454d131c91d5e2e3a464ef5d3c40ee6a2ab95e70ef2e49e0920d24f9b09276250ed7b29851affbdbc7885a", + "0x92a488068e1b70bf01e6e417f81e1dc3bcec71d51e7eabbc53b6736e8afdb8b67d191940fe09c55783be9210e1cbd73c", + "0x8180ffffb5abe78c38f2a42a3b7f1a408a6d70d3f698d047d5f1eef3018068256110fcb9fb028c8bdccbc22c0a4c3a20", + "0xa50ab79cf3f6777a45f28d1b5cdad2c7ea718c60efeeb4c828d6307b29ef319445e6a9f98aa90f351c78b496575150c1", + "0xa4632399c1a813e41fb2055ef293466098ea7752a9d3722d019aa01620f8c5ecdc5954f176c6c0901a770cbe6990eb11", + "0x83bf5055d6332009c060fd50b8dc698d42b764b079c90a1fad8a83101f8dd1cc27acb27dc9d1c25ac8d3db4107471b4a", + "0x8c432e044af778fb5e5e5677dbd29cd52d6574a66b09b0cd6e2a5812e71c91559c3f257587bfc557b4b072a822973a60", + "0x8368a0f17c8427beb71dbf11a09a2fe8495a33f08c29c74a9a996a88aa01c0a09f9555abeb1ef1592cab99a9e05875cf", + "0xa8795e7f4c4c5d025ead0077c3aa374daaf9858f1025c0d3024d72f5d6c03355ae6ac7418bf0757fe49c220acff89f7f", + "0xa6d9f67ca319ea9de50c3fed513269b83fa067977adfd1e9d9ee07ad61b2ac1de64a39d7b6897ab55870cf982fe481dd", + "0x86b3a4ea9b1fde00cce79d5ae480353d60cb6ddce363c535bbbc3e41a4b8e39fcf2978eb430091ae1b10420d43193971", + "0x90fb5cac22a22fb8a6b619f1eacd95873be974d4d5d1f7080e523bb9b4b2644eda7340d780bd1ea8ce36407ca0410fea", + "0xb5036d4c241685bcd67156e4ab0eba42b97f639947d54b17af2c88fbcc5fc57359c7df4bc7f8df955a524fb1501a6fda", + "0xb1c56f028f31f0ff86bdf55788703b4d809becaf3e4d9d349f1b660a07d2f15e127eb72a0e2a5a2742313785a3de43a5", + "0xa3e909196f447e492200cc67000c5d7f0f585fb98e966cf9bf08257597fea8d92a90ceb054d4b5553d561330b5d0c89a", + "0x87cac423d0847ee3547f45ac5babf53bddb154814e291f368cbb62ddd4f2c6f18d77a1c39fddb482befe1a0e77d5b7fd", + "0x8605b88ce23190b1fa9d389b15e6907417239a72b97673d1479c4ccb8f4515c7921d14537775c74e738a9c3f122b1443", + "0x87587504e819bc7f0349705a05c15e8504fd6b2c25c3fd264096cdb7aaa22d8078da776215925d9d775a7f9355b6f0c0", + "0xafba279768f0f928b864645aa4e491e9c949bf3dab57efa24eeaa1a9a7d4d5a53c840019354068e64c65a2f5889b8f3c", + "0x86b1cdd26ea9a3ae04d31a0b34aa3edc9e8d038437152214d195381173e79e4ccf7f8f0ce9801086724a1c927c20e4c8", + "0x812d3ded3a3c9e58eecf13a29bb4cc13b01b2a0af322423a29bb0e4f6d9021d1d87ac4af7a2a6b88d34f44a8bc1b3c55", + "0xa988cfed9f481bc98beb5fc188ed3f6893a3ebba27c3ebace669792f6abf0997727023c3b6930a6421224f5b257b8b49", + "0xa38c974b57da968f0c4611f5d85d8014fd48594c8cd763ef2f721cfd2c738e828d41ff029e3591d7447e3125641db8ef", + "0x880b4ef2b278e1b2cccf36a3b5b7fbce94f106ed9fa2820cb9099a7a540a57e9fdeef5c0fb0a743049828fc2b8c46163", + "0x96e7d1bbd42195360267c2a324b4d9bccad3231ed8a7f070278472a90371867e2ef2c29c9979a1ec6e194893afd992df", + "0xa92beb343caf6a945990adcf84302c55d1fccdef96c34a21f2c00d3e206a9b2c6c6b412f66e5d4fafe26ef6446cde705", + "0xaa48afa77d5a81cd967b285c0035e941ca6d783493e1840d7cbc0f2829a114ace9146a8fbe31ecbd8e63e9b3c216a8c5", + "0x893a2d97ae067202c8401f626ab3938b135110105b719b94b8d54b56e9158665e96d8096effe9b15c5a40c6701b83c41", + "0xb614910b247c6ade31001b0435686c3026b425b9bff80b6c23df81c55968633349e1408a9a5a9398a7d5d6ed5d9d3835", + "0x991c660e4d476ad92aa32ef2c5b27669ab84026eeb5ca70af69bbbcd8ebc0a8fec17843423306edc78b4436629d55c25", + "0xb926a21f555c296603dc9e24e176243199a533914f48994b20abca16f19c30cfd0baf319268139fe3f83ce69afdc324d", + "0x8e70e4867d2731901d603928d72bbeb34b2e0339a4f5cf06e7a771640717421b4ea039c61dde951582a28c2ff152ff70", + "0x95aafa379cc6a2b4bdd0cad30b7f0a47839952af41f584219ec201c6c4d54610eb2c04b67b29080acb8cecc5e7543fbc", + "0x8465bd8be9bd9c2c6116d4ae44ec6618c109cb9aaee2d241e7a6ed906d398ef15a6fc18bc8b1d3398184241405954bba", + "0xb455f751232de0a48440d09983f4f4718b6169907979c9f282acf7177ab5b1f338fe1f2acd8d0bee4b4aad61d0340839", + "0x970df2314849c27daa16c6845f95b7be178c034d795b00a5b6757cc2f43c4c8d8c2e4d082bec28d58dd4de0cb5718d61", + "0x8d52413f981bc611427ad0534d25e914113d0ebcd6960aab6421608bec6648b89ae4b2ca2153c57d3cf4f1f37212aa5c", + "0xb7ac87da14b783914ab2e914fb7b536893b7a650cdc5baa1f3b4aca9da77b93a3336671335250e6467a8cd4aa8dc61e9", + "0xb37a2ec9dec3d7d9cbc911fa1e5310a47d23a841d02c8b99a923991c73fc0185d130a494748c64f2b5a4c07bcd06920e", + "0x86108b661fb2c363adcca84c114c83346413df748b959015c018452cfac14890bf585dc0a646d68727cc3cdfd2b61897", + "0x8421044f794a1bcb497de6d8705f57faaba7f70632f99982e1c66b7e7403a4fb10d9ef5fb2877b66da72fd556fd6ffb0", + "0x84d2eb008578aebd6f01254b7e46584c1524e6fd7a5a2ae5fa0ea560865ca50d52290cf2d12dd20b042f402e62181b4d", + "0x8d6bed5f6b3f47b1428f00c306df550784cd24212ebac7e6384a0b1226ab50129c0341d0a10d990bd59b229869e7665a", + "0x80e30cabe1b6b4c3454bc8632b9ba068a0bcfd20ce5b6d44c8b1e2e39cbe84792fd96c51cf45cf9855c847dc92ce9437", + "0xb7e74ab2b379ceb9e660087ee2160dafe1e36926dfab1d321a001a9c5adde6c60cd48c6da146d8adfa2bd33162eeaf1a", + "0xa2b1ea43f51460b3cb83657b4e296944658945d3ad6ae7b392e60f40829ba1da6a812d89f0380474578cbd0ab09801ac", + "0x91ead7dacf43905eb5d4b179af29f945479ed074126bad3b5a2bbc1663af5f664fe53a36684e9389ab5819e53f1344fc", + "0x927c030d5a69f0908c08f95715f7a8d1e33bed5e95fc4cfb17f7743cb0262755b1e6b56d409adcfb7351b2706c964d3b", + "0x883f38af3b2c1d50f6e7c515a5e02468d76890f6e669f7acd2df89365862fa65877095deb001b4e2868bc5b59439dbb1", + "0xa0ebae60a998907a19baa396ae5a82bfe6aa22cf71bfca4e1b4df7d297bd9367bbeb2463bda37aa852ad8fd51803e482", + "0x8ae80eeaed3fc456f8a25c2176bd09f52a2546d45d77a70f48a9e30aa29e35ff561c510ae1f64e476e4a0f330b9fdbdd", + "0xa7be457b8bc1bfde4865a35b7b1826118edba213b0f0d3cf5d877267cc1559cabe61cefb1e300142a978c29676036179", + "0xaf51da717d2a45ab96fad5d9317ea867ec4c6a411af6fabd72e568230099a04c036a0f114158815b1a75da6474dc892a", + "0xb549cef11bf7c8bcf4bb11e5cdf5a289fc4bf145826e96a446fb4c729a2c839a4d8d38629cc599eda7efa05f3cf3425b", + "0x8d264fbfeeebb6c4df37ff02224e75e245e508f53fb3446192cd786ecf10d0f704c4fc2e53e7f7318ae1407e46fc0fb8", + "0xac3195143035cdb4ddcd5f93c150035d327addee5503ea2087b1a10b2f73b02453ddd1a94d8e7d883e365f9f0e3c38c9", + "0xacbb398ea9d782388c834cf7b3d95b9ff80ee2a8d072acae8f9979595910849e657889b994531c949d2601b3ce7b235d", + "0x811e6a5478f708495addbb1445a2ef23e39ee90287f3a23ecd3d57d4b844e4f85b828bae8fa0f1893dfcc456f86f7889", + "0x8cde690247d4831dfe312145ae879f4e53cb26641b3a3bb9eb4d590c56c11ece3cfe77180bd809468df5cddaea4f5ab1", + "0xb42578df29a9eb23bed91db6a1698df49654d2bc1b0d7973b2a7e300e9cf32e0e6ac464d463d4d26e394e7598239c4bf", + "0x97ffcbf88b668cde86b2839c7f14d19cb7f634a4cf05d977e65f3cd0e8051b2670e521ae74edc572d88201cff225e38a", + "0xa322b5d2a6e3cb98b8aaa4c068e097188affef5dec2f08c3e9ce29e73687340d4e5a743a8be5f10e138f9cabbe0c7211", + "0xa076ea1084b7a1a33115ef62d6524f36e7820579868763a6ed1f8bce468f150cbfbf0ed04be2487aaa34100d828b0db6", + "0x944259a56e3b4f745996289912740281bde47e22705f142c2a483ffd701e780f51a01b177d2494dc8db9e69157f45d44", + "0x91cb79d52951d1b901e4a686bf4ad587e31db57ea5af6ffeb93eeafae3929879c386ddec860f803c2dc61055437e6bee", + "0x91efdbcaad9931312d7c41d24de977f94d7f3f7b88090a1f72d9a097a1e30cc805c5ea16180f463022d9b26b8863f958", + "0xb26f5ed09f7d5bb640ec94ddd1df0b76466f69a943b4699f53d45296d5d6b8010bb61477539bc377d1a673d89074d22f", + "0x80822499f96a1a8c0048f01f389dfcaaa5d8269c332dbb507fe46f270bcfd5f67c53f827fd867221592dbde77b6b37ab", + "0x8860ba25d5530cb8585975d8013a1c2d5b0f0f96066044fdc43ed13488ae44e379c624ff6993a18cb6e037809d7985e7", + "0x999d1c44e14184349064415ae28a149b3b11aba5baab6792744378d14df554a3625fac82038eaca920064822294dd513", + "0xa62c2e7c692403e874a16e08e46a067e19dd561993ca07ff79cecb53c753763b3e49d372638c96c0a8c921bfa0798a0c", + "0xa1c84730a5c41dcab9a5ef9e1508a48213dbc69b00c8f814baf3f5e676355fc0b432d58a23ad542b55b527a3909b3af6", + "0xa1c0c317e6e352e16e25c140820b927161ce5d2c4c2e10bca3057ba4d46b4f42ad7aba20de86dad9fc6368ea92695268", + "0x85c216e314eb7bd8ba02e092c90e132bc4bafb21c6a0fbe058b0dd4272cb76f183b83c6783fc321786065ff78c95f952", + "0x8e8f63ec8f4f1f7fcc61f893b671710c3c17f9d2d26c5c6ca40e671bd4b252bc0cc1655e6780d2ddcf2915d8f623b9a4", + "0xaaeb0005d77e120ef764f1764967833cba61f2b30b0e9fed1d3f0c90b5ad6588646b8153bdf1d66707ac2e59fd4a2671", + "0x92ff79402d5005d463006e0a6991eaacc3136c4823487d912cc7eec1fe9f61caf24cd10022afdab5f6b4f85bfb3eee4f", + "0xa32a5bd9b7bec31dd138c44d8365186b9323afbba359550414a01e1cdb529426bfa0b6f7daaf3536e9402821faa80003", + "0x845982c2672fdd44b33d2e56ad676e704c02f756b09e8765bea42b924c14724484567b55f0db42ac20cb70a7f5201c14", + "0x89cd9f6ae7d9a9ff2b4db916ba3af9fe700fcfbd16577bf73a965af938e8cf633020466b0298d3c31300360aa6851af2", + "0x8fa2d7b22af8e6b82679ebdfa13efdcb34289a554653ea6c1b16efb9f957f7fe64df787e7b03d8cdc8a732b91c916bd1", + "0x94f327bc57ed1ce88ce4504b4810cc8af5bd21a7e07b280a7866ce08e39b6cf7a6560bf73a5f10671271624cd7893970", + "0x90f4476224b64c2a5333198a4300ece8b3a59ae315469b23fd98dadcdceaaf38642d2076e9cd0bfacc515306f807819f", + "0xae0db78548261216ad7d6a7ed4e6089ee17b3fa311494b2f2c559e215cd3de7e5f3a781a49dcff428a8a61c2a4f49a19", + "0xa83371f44e007c708dc4bcafa7bd3581f9080a4583c9be88624265014fd92f060127e628de5af3c442a25f049c7e7766", + "0xb471c72bd2971353f4b44248b8e6cf5316812861a88ccfc20fd0d89a5e010428c387228b2f6f14c12f79e31afc9d0753", + "0x8962afddcb1a26cc8ccd3c993109e79a4dd747ca473b8b5ef93d9c2e71d29623b834ac945074acf118248e3ae7878a6c", + "0xaa0940e4e5586e79a3d97397c8aff3d112c6f759d2efac29366acc5b5c6a7cfef8d50516bf309da8b787de265dc8deda", + "0xa211120e1bb3b10138df1fa58efb009a298b8771f884b82bb3de15822b1252124a68f3980f96122a775fb96f05ddc3d5", + "0xa1047401598b1e6e2613d746bb4689e0406eccdbadf319a6609a3261cd09deec215d90eba6d0ddc50dd3787d60104e7f", + "0x96791b2b8066b155de0b57a2e4b814bc9b6b7c5a1db3d2475a2183b09f9dcd9c6f273e2b0c922a23d1cf049a6ce602a3", + "0x91013e0d537fb085a49bf1aa3b727239b3e2c1d74c0f52050ff066982d23d5ee6104e70b533047b685e8b1529a0f14dc", + "0xaa65c11071be23c9bddaa5203f3166e5cf043efe5fb8f4b26f8a9cabe71db701a450e79eb001c401da5752755d9cf1af", + "0x8645cc44d180c18a6d8f57ba57bae05879451997533cfe558cad4d3d586caec877e348915e32a09ee73483283c4df744", + "0x8eafbb7002f5bc4cea23e7b1ba1ec10558de447c7b3e209b77f4df7b042804a07bb27c85d76aea591fa5693542c070de", + "0x919c81bd1f3d9918e121e4793690f9ddd96c925ae928536322d4b98132f21979c1f34731d393f0ae6e0871af4355a8ad", + "0x98181e9291622f3f3f72937c3828cee9a1661ca522250dfbbe1c39cda23b23be5b6e970faf400c6c7f15c9ca1d563868", + "0x8f44c43b80a3c5f488118859fab054745cfe5b0824821944b82fcf870fda6d93489ea9ca4220c24db2f4ad09c6080cb7", + "0xa683d4865ddcc099f7b698153007b92f853b80f49b3be75163ea8cd1f8ff584b43a68e68de3ae61cda8ad4b41f355c87", + "0x942772b7c7c47d4e5957ccf1d6f1450070930af3e2b7eaab0dd7699372445df0cc910e6c0efcf501887dd1adabdaee23", + "0x805c06e565ee67cab0cbccb92b6656fdb240b430766eade3c6b0a0b1b93c840e2b4f028601451dca135c783239463880", + "0x84d3e2a06e16ced26094b356a16a4fb6aad50ad9ab23ef804a5852a33ef0bff76f3c5fbf7beb062376c2e669cb598679", + "0x803df08aa745cc3c0a799f3a91bb6ed423cd520c9d255d36c21bed1a0c3b12e8cad32f54da09dadca97683e9548fba91", + "0xaa2c3ef95b8d4265f01666129646004b6950d3e8ce74b4ca12aa3b90fbb445079a569178df772c272463a44d48922b8f", + "0xb0a4c136fb93594913ffcebba98ee1cdf7bc60ad175af0bc2fb1afe7314524bbb85f620dd101e9af765588b7b4bf51d0", + "0x93e4c18896f3ebbbf3cdb5ca6b346e1a76bee6897f927f081d477993eefbc54bbdfaddc871a90d5e96bc445e1cfce24e", + "0x89019e9550648962420984e9fd03597a854ae824567d9aa6cd5db01a4616b4e1477230f2d1362a2d307e2425a3eeb898", + "0x861b710d5ec8ce873e921655a2ca877429e34d432643f65d50e8b2669929be40a9ce11c6353b0ada1fe115e45396b2b7", + "0x88554c83648ea97dac83d806cd81d92531980346b208d281fba489da15a0084fd4d9a00591d1ca67aad3c5793685d55f", + "0x851fcadebee06930186f35293feefd40d7daedec9b94e6fe5967536c2c0e4cc68f58d3f5fbc76f1e77b90c9580074f98", + "0xb96a11048c7c327709d52e72e6f6ed0b7653329a374ea341ad909311b5b303e5629d6dcf11dcdb195e8c7592ceefac21", + "0x836075979eaf386ff6cb459cfd48fed171ae812b0ac3b38dc24dd8ca905cac1c600be717d4a0defa0a854f40cfaf8c33", + "0x90fc170529bcc0b80c46a53fffd8323fd2cc5cfa9b75ea4d36db21bd1f198335ad2bfa87f8990cf9cd9fd7989ecca718", + "0xb7eb6a49bf8f942dd8c37c41c1b35df43e4536e07ca9f4c1cfbbf8a8c03f84c54c1a0d8e901c49de526900aeac0f922f", + "0xaf6911edd6c7ad30f905a0a3f78634808832fdeb4206b006934822d673bcced8e378779261b3c4b772b34b8871987f57", + "0xa74d240d0d7ea0afe68813fab55388d77e75eca0519d21771dcb7170cedb11dc14b237b26c5ae1f7f728b52e5ec0f02d", + "0xa7b86e4f1366da44fd59a3ee68018a99c23ba3588789463bd88b0177a9b94030b58cb879a506e64421af966f261eaa86", + "0xad8d94e46cc02a1c0ad27105e8f672ec15b8296051801f1918d0bd470625686e8e8a0abde8f6852b846ee8d9132b26bc", + "0x980508c4d1e655cc6200f89a884b3a25c0c05708a3e4a101205c4fd901c3e20a943071a6300bb2614be41a139d4ef1df", + "0xb0173651b4ba0590b1d2f0265183f3729b5bb09893523ca12c4936120cbe5ef0d9b98733734407d99fdc766792ff10ac", + "0xabf72ec0280d56971e599b3be7915f5f224c0ccde2c440237e67b95489f0c9154ace04b7763db228473715f68053f071", + "0xb404beebf60026ca6843f2953cfcdee494d495c8e2d18865147102ef29a8f0ee470961d2246fe5a450c622d20ca51d53", + "0x89461cb2dadf51d6f1208b0965c8eabec895d7b19b7d90d3c6e49dbe75a75c30fd26db3dfb169dd46a4342280225032a", + "0xa61cb5b148cb7ff34775dead8efa7d54d7141182356bf614070dfaa710ebf07a4dfb684dad151db60c0f8261c30a4f40", + "0x83a798f47a4f62dcb8b531d463b0fd4a876d47a8ca990710290549255033c909de709471b4e823a60bf94d8baf8b5acf", + "0xa23431589f3a25070a188deead9adb0ed423d6b00af267f3f125cdd4391c1527909b5cfa88130dc4b67915f5002128fa", + "0x8d77e65ba6250fe18c54ce70d0ba4571a7d3e68a8b169055cd208e4434b35a4297e154775c73e7dfba511faadb2598c5", + "0x90e5db75f3787b819df471712f87b6f3281437090f5db7a2c21b07164446292a414c687e41de2d1ca00786b093239c64", + "0xb382fa28670a5e14dc954b2db8ace250c73df71ab095304bd8ee28f455ab26cc54f82775a831428e110d1a3a2af709bb", + "0xa58d2fb1c2612d28c54fafa7f2e1e6c336c24435abdb53e1be9dce9aebecbf7468a348b872549535ac18aa003f83ea87", + "0x9545f94c4e9056e360dd999985f8ad06210556fa6f07cff77136a2460605afb0ff1fb1d1a2abe4a4e319fd6c29fff80f", + "0x93121aa60f904a48e624e00f5410cf8c8925d2b0719f90c20e00cba584626f833de7c8a18dbfa6a07df24b916156bfc0", + "0xaa3446aac25f6c23ea16e8f7d19c58d187746ef3c2ac7d8fdf9bdc329409a07589ec8eebafbe2b156e7ba60addc15af8", + "0xb964f50011f03135e993739e2e63a71933ba4583040b3af96c7e2dce874226518f7b68f622c4a1d78b9c3ec671d33ad7", + "0x8cb5cb7cba886af58acadc5a4348524b1395a39dc51196316d759a9b72d9fc0fe45b706e264393a13ff911f0d15de45c", + "0xb50c306f78143b37986e68efa10dbe1fb047d58562e9b5c5439b341dd8f1896c7ae586afac0a3213759784a905c1caaa", + "0x97825edba8410e8bcb85c5943628c02ea95ee7595f559c030b94395c0d1d0d84c38eca199fce9c1992e572b5029b124c", + "0xb0922acd6da2a95b36de6d0755316594a7e2e32ea774792dc314e8c3cd76d9f1d69df38231e166e24bd42c664f4fbac7", + "0xae5ea228c1b91ef23c245928186fbafa1275ff1817535018d7d2d913abff0fd76bf41fd04a96d816f2f1891bd16e9264", + "0xb106c6d13ca17a4c8ea599306e84918127cf2de21027ac3fe5a57d35cf6f3b1d7671c70b866f6e02168ae4e7adb56860", + "0xa044cd5a3b727dc1cb59875e4025718375d12e706fffcdb48874e51a675dc2cabb209670192e408cdced5aeac65192e4", + "0xab1cc44983e46a6ea2430aa6616ab28614f43624665e3e6ae31a9357c0c5434f34e56c720906e184327693cc4ebe1fa2", + "0x890def696fc04bbb9e9ed87a2a4965b896a9ae127bc0e1cc515549b88ddbcbc02647e983561cab691f7d25cf7c7eb254", + "0xa86be58fef115445b909dffac6f51da3fe9214afd9c31fd564bb8f39b1dc3cb895b1222f2c63226b54b60b278ec45edb", + "0x8757e9a6a2dac742ab66011c53fa76edb5ebc3c2fbd9a7265529a3e5608b5c24b4482fed095725e9b8fed5a8319c17a4", + "0xa7e0ddbae16e4491822684c0da3affecbbd17ef96c5c491ac093c6eb4e162fc7854c367535e296fd3d6265c2ed1210bb", + "0x941fe0dabcdb3225a625af70a132bc1e24ccab1f8331dde87db3e26cbee710b12b85535e46b55de7f5d1c67a52ddd5c8", + "0xa24d05b51c7c128bb49979cbd9019e6618545d95275a44b5c3d1d03e71bf2ebffdf43fff50c30846ec27d279043cef4e", + "0xb526f40d519e7a8f2c81b69f71b3e2ef079028004c0448ba0608296c2787972491ec6d05ed6a8fbd5ef2da76325a93cb", + "0x87ca4fa85a257adf7e21af302437e0fa094e09efced2d7ebab6cf848e6a77ae7bfc7cf76079117f6ed6eded9d79ce9cb", + "0x9276e8051bed8f5dbfc6b35765aac577dd9351d9d6ac1bb14496bd98091005b9a4737b213e347336413743f681f5043b", + "0xa7741c52498e0a24db3ce7699882de8f462a2b3ed5e9f77dc7200cbdf46b6cdd923b1128759909d6dddd64700c4c20c5", + "0xab5b363ed9551e32042e43495a456e394cbc6d53b15d37a8859850162608bdf36d3d4564b88fdbaf36ff391bb4090b8c", + "0x838ff6630dc3908a04c51fb44a29eca5a0d88330f48c1d0dd68b8890411a394fd728f14215482b03477d33f39645dceb", + "0x997d3b82e4753f1fc3fc2595cfe25b22ac1956d89c0950767c6b9de20623d310b1d84aaa72ab967ef1ea6d397e13524b", + "0x85416cf3eef63d5530062d6f031aeddad101c7f1aea3bccb826c73f8a25d5d963caefd789a6b9832bd4ed459f268ae64", + "0x9194bc45e11d7276ed1c9ef3ad5a33d6a27372f5568563ca8ee213e2e7029dee404ab5acbaecaef698129798d35fd895", + "0xa4828a003513ab887082390262a932a7e8c5e25431824b7b4cc10fccba73265c0e5ee5b315ccef13906d971644913806", + "0xb907ec84b6ae5729d36e2acd585a350acacdeef148bcc5dc4a91edb57505526462bd4371574865541d8bb0d786a29b2f", + "0xaa5d1c1f0a7f6b9b3c3734f85864aa60bddad5121450218d76d82edefd2602685a820965c56d7eefe789d5115cb41e01", + "0xad28fe70a8606f87bcb5d6f44e1fca499c24bcee791971f599ffef1f403dc7aec2ab6ebed73c1f8750a9b0ff8f69a1e6", + "0xa641eaa149c366de228a2833907ad60eea423dd3edf47e76042fdf6f5dc47a5b5fc1f1b92c8b96c70e6d8a68d3b8896c", + "0xabac08f4df786b2d524f758bca43b403b724d12601dc0a8362b7a2779d55b060c6682a5618fffea2e4def169fcbd2bfb", + "0x8658a15df961c25648fd444bdf48a8f7bb382d9212c0c65d56bf9cdb61aab3bd86604c687fb682260dbc0ad2dc84bf01", + "0xac7983d50ec447b65e62ed38054d8e8242c31b40030f630098ce0a4e93536da9179c3f3ae0b34a0b02aad427a97ee60d", + "0xb8877a00a24b0ffcb2bd3fce8a8ba327d8ee2e98d85531cb61fec21fd49cd1696491cd51024a9c3820cf06a77cacf04b", + "0xae075b66e5f211c2149c45b211d1297bbc1d9e6497cb3315363c492a9a51ae5b9d0a28bfecd755d68553736901ac6606", + "0xafdc091a224486e7bfac169e6a7b4e008d2d04144508a337fd93b6f4d385ee3f0d927b1f5c1cd79a15e0fd6078e45dd4", + "0xb75c28941ee3f91b3535b4eaa0fb17b59ca65b5256601a1f6d0cf2bb4d66837fd16e51d6942856679012a5730a66e519", + "0x84a6edac5ac68a7ca837c46d5ada8fab136748b6c3a3b9165dbbc231ec386b15328e4ef7d69a15d4cf354135348a4ee4", + "0xb01ee30d120b97e7b60ea89b9b6c537cdf20b6e36337e70d289ed5949355dd32679dc0a747525d6f2076f5be051d3a89", + "0xa80deb10bba4bc7e729145e4caf009a39f5c69388a2a86eaba3de275b441d5217d615554a610466a33cfe0bbe09ef355", + "0x8d6e3df29419bd0da1deba52c1feebe37744108685b49ca703e1b76fb4d612e3959d3b60b822506e5c0aac50b2f5eee2", + "0xa373408beb5e4e0d3ebd5ca3843fe39bb56b77a5d3d2121d4a7a87f9add3ec7376388e9d4b8da0ba69164850cb4b077d", + "0xae0beb452af7479134a7fbc31a5f59d248e8a67d4c7f73a0e30a51db9cd33a1da3f0ae947fa7e5983aea1343e7daf06a", + "0xaa103a329b699d4102f948101ce5fae27226419f75d866d235da8956f11367e71db5c0a179dd63007ed53f7eec333aaa", + "0xa094cca9d120d92c0e92ce740bc774a89667c6f796b438b0d98df0b7aef0935d8c915d5b0dad4b53e383dc9f095c29fa", + "0xa4d88467136b99d6e55603b3665b6da0f7fb27c7759687f7e6977b6230272773d7b95049d999538c008f310c05ed948a", + "0xa23710308d8e25a0bb1db53c8598e526235c5e91e4605e402f6a25c126687d9de146b75c39a31c69ab76bab514320e05", + "0xa36d6952c2d7f88bf28032a76ed46c4dabbf1901a46efc50deb798d1b44adf7e0210fbdf2473a1ba408b5c98d76943e5", + "0xab45f5b756ec6e0b98d0d4301c87675a0a1f0b1178b8a9780c1ab23e482cd821834835afa1de890962212159e464b10a", + "0xb800be1788175a01a9228b0d3e7eb4302484a2654eb2a86c0f0900b593da0a436ef031ac230e2b05e968b33e90a342ce", + "0x8cc8d279ec08d0a5a2a09ad07fabb0122eb65f48da2571d83f86efa2c1c5bc51b04ae94b145f0a8ef19a3988638b9380", + "0xb4cd409256819e8e4627edbba90ec40b7da17a57f95749104d90db0364f5007b1accc816f4d51a0dbe5ffbcb737cb37e", + "0x99365fe5ab8ea8bd768ae7181a6ba49b79d240f512ce309b02f09d465fea276298ff55b5b9cb5b4162a901b390606024", + "0xad77fcac9753efba7a9d9ef8ff4ec9889aa4b9e43ba185e5df6bf6574a5cf9b9ad3f0f3ef2bcbea660c7eef869ce76c8", + "0xad2456725ac3aeb0e4ca5c0502a8abb4dbd8a8897d9d91e673fea6a0cffd64d907b714b662d73c0877b98d4ab3ce6a89", + "0xac8436e33619e2907659741d66082acbda32612d245fcc8ae31e55f99703fac1a15657342fa66751d3be44fc35d71c36", + "0xb0eecd04c8d09fd364f9ca724036995c16ba6830d6c13a480b30eb2118c66c019cfdc9dacce6bfd8215abe025733e43d", + "0x9439b663e4104d64433be7d49d0beaae263f20cfac0b5af402a59412056094bd71f0450bc52a294fc759ca8a3fddfee9", + "0xb72de0187809aaea904652d81dcabd38295e7988e3b98d5279c1b6d097b05e35ca381d4e32083d2cf24ca73cc8289d2b", + "0x93706f8d7daca7c3b339538fb7087ddbf09c733662b55c35f2a71073f4a17c91741955d4d549c2ee6c22eaa84193c1ad", + "0x926dc729e135f1f0bff4662ee3d6823a64597fe189b763ada34f246e77705fd4e062d85506a338e9fa98c4d225a3b27a", + "0x93f03495d53c781be8b76e37e68b64aa260523004eff6455ddc8a8552af39854e5181f8c5365812b1f65926534fba5dd", + "0x9834f66e5c946c3a8241ca2bbde046a7e88072124911d5d15c037a95b61e82b88b5c2058fa4a3721537dee39dee5da18", + "0x92ec1aeb2aa24c51cd5f724972c8b6095e77b237d83f93ed34ca0bc91a1dbf1ad95adccc59e0f0abbfef33f331f3298c", + "0x94402d05dbe02a7505da715c5b26438880d086e3130dce7d6c59a9cca1943fe88c44771619303ec71736774b3cc5b1f6", + "0x8368bb9b9bb2e17730c42ed1100eb870c88a8431601312aa8cb1e738cdb9ca2704dfd432cf1703c0db043259819631dc", + "0xa35189a105401f0cfba4b43be21723486c04659e5a01e67c43e8f9911030810b878beee696f04f63d314ccfe97ebb790", + "0x93ccd8c5f82374e0bef6562e16576f742d79b6f400e3485ef36e148088b61fbd882c3d2bb38ab0b43fa1dac77f31d543", + "0xb85d9a426a23ca9ee582bc16c203a9352dcc5f85440e46979de80eb572384479b697dc964cafd9457d9f34eeb77bb72a", + "0xaefb70e89dbf4456e077690509afcdcabf975416ff2fa16777fdf90b3abd3f5dcd865c43f1ebe6f8a669edc7f3bd6ad8", + "0x8eb03001ac9e22c6956a682ed458e650785c36d23ddbcd51ac4d9cc991325c02519ff1958987a08eb29ff56ff6e2c293", + "0xab4a1ffef7e001723c71f5d28f3dd030a06c42d91773733d117247bbf9c01cd66fca2cff8c6ce04c4bfb68dfcdd851f2", + "0xa9ef845ab489f61dbfdcd71abcc29fc38f3494a00243b9c20b9cd0dd9e8a0f23304df84939b9652cdf5542d9b3ee085e", + "0xb5726aee939d8aee0d50bf15565f99e6d0c4df7388073b4534f581f572ad55893c5566eab1a7e22db8feeb8a90175b7d", + "0x9953a7cbc152f101a60e3e381f2af17ebe7401e16ef6462d132b8f0f6c6a18837914a1299d1605f9f289b9561112f4bb", + "0xa0c9b944a338325f5efb675c9c12619fb43c8e25e80d38d6140e31d5070573b1a0ed9bb52576e4f22f37d0292d36a648", + "0x8bfd6a173a56b73480cc950ef266a18933ecafc86915a7453ded09efd8a0cf4466101f1373f05d48eae3e7fc5c0f7f54", + "0x983fc1ddf17f9756c9cecc00b39bb2ad432587a5c6d1c3296a383b9f539c9afe84c6c818447a709c0b686ba26ce5ea3e", + "0x94bbc6b2742d21eff4fae77c720313015dd4bbcc5add8146bf1c4b89e32f6f5df46ca770e1f385fdd29dc5c7b9653361", + "0xb26b4d483bca73d3f3a976bb595a0e40f9a42094e0febbad3a1874934be1939a1b362ee4ea14a4f5cbfa9b1392796a12", + "0x8dbe8fcbcc414eb352245c52549973f73d987012de9d5f2b2f55dfdc43cf8cc9ea6b147abf149817f80f9e15aea566c6", + "0x9604da21e23c994a0a875ad5e0d279c79210f7a7de5c9699fac4aebbd76d39b703eeec5dd5efc9ad6b9dc58936089ddc", + "0x8934e9a3feababa12ed142daa30e91bd6d28b432d182ac625501fe1dc82f973c67f0fe82d39c9b1da3613bb8bfe2f77b", + "0x85f2ed3ffb03e50c8f22553b8e6349be6244d893aa37a7c6dbd221e9e121579e5a04466e60d6b4d3567bc747b1fc1e9f", + "0xab0ad421f6fd056687b4fa5e99dff97bd08840b7c4e00435eb9da80e0d7d071a447a22f8e5c1c5e93a9c729e5b875a1e", + "0x841d77b358c4567396925040dffe17b3b82c6f199285ac621b2a95aa401ddb2bc6f07ebd5fa500af01f64d3bb44de2df", + "0x83f21dfe0272a5a8682c3c7814c5e0e4db6a9098f1fa80fda725f77ea81fdfd2fa36b0c8db013503a89bd035f86306fa", + "0x95c98e3b6b62f84edf7f297cae93ee5f82593478877f92fb5bf43fd4422c3c78e37d48c1ee7ca474f807ab3e848d4496", + "0x81c3a8c00cfe4e82f3d8cb48de7d4926d5ec2f7689f9cb85c1886a23758bc107a4bc6e978601c3519156a169d0bf6779", + "0x8e956ca6050684b113a6c09d575996a9c99cc0bf61c6fb5c9eaae57b453838821cc604cf8adb70111de2c5076ae9d456", + "0x83474776ef2341051b781a8feaf971915b4a1034fa30a9232c4bf4b1bd0b57bc069c72c79510acef92e75da6f6b8843d", + "0xb41780d9d67e9e8b81b1f62d25c0c72ecfda659d2bfe6825edb70ecd0e0724250ac364e7be521cdc112ba638f16360d4", + "0x842ba3c847c99532bf3a9339380e84839326d39d404f9c2994821eaf265185c1ac87d3dc04a7f851df4961e540330323", + "0xaf17532b35bcb373ce1deebce1c84abe34f88a412082b97795b0c73570cb6b88ea4ba52e7f5eb5ca181277cdba7a2d6d", + "0xb9574edb9567f07f85c7c2e6ca6c02d90ad7c7b87d49796f1e2fb7240ad071fb755cf13ca8678668a56217c62df168eb", + "0x82212706111fb1cf5def02b5b0eb7ae9e6ea42b4c7a2b9fcacb7aec928326edb9ac940850dd933f2822f6cf519de0d50", + "0x9579973ee2559da09b327c62b1cc0177f2859872885dca709e24dcfbb9bdf9224a6d26869aafce498f44c0e6bd8a996c", + "0xa102c2ade15ea2f2b0cbc7dbd8c1171de0c8092fc4ecef84b5fd2bae7424aea8be1629f851c75e4d1d0e96104e54bfbc", + "0xa5d7e847ce7793386e17fe525f82aabb790d5417c3c6e3f6312f8e5ff52efa8b345c1ff60c4c9bf7636f5ff17b7a0061", + "0xb4b80d7fbdb1dbf1567dfb30d8e814e63de670839a8f6ff434fe171416599fef831b8e978d6498851b8a81e0bc8dfb85", + "0xb6e6277b86cd5284299ced867d37ab98090ac44a94deef6898aeadd177e64605440c15b9609c07e71fe54c95b61873b0", + "0x8135a0633082e4465090d6930b770340e82366bc5c37be6ef6dd105f85acf63361e17de8b5fcab4c82e9f9b4029954b7", + "0x864d5d9858cd881eecb0dde5e3e0c6c5de623cd9ef619e87b82fd25c5edf45a1a025b1dc763c27c5f4d520fd564b464a", + "0x8784a8fa62e0ce23283386175007bb781a8ec91b06fd94f22a20cd869929de37259847a94a0f22078ab14bb74709fac6", + "0x8adb748d5fa5c22ce4c76a1debf394b00d58add9f4e08524cf9c503f95981b36b8d0cb2dfaef0d59d07768e555733ecc", + "0xb76cb8cb446eb3cb4f682a5cd884f6c93086a8bf626c5b5c557a06499de9c13315618d48a0c5693512a3dc143a799c07", + "0xb2af1f7ece1fd640c205a09614122d69d5d2e81a7618bedefd6dbb91c7f432679be4ced1e6dddd3de323bd44991931c5", + "0xb950b457c34bfdfdd9d6da9628d41749ccae03659518a04b56487bf1b4c0681b719ec5230c0b0fd5dd710894df6aa2f8", + "0xb21785008910a949804d1291e7533752641d31beae3cb518806488f81d58c38a5efe5ed9534ac692e68c3121e2f9d97d", + "0xa9b120a77d70c1cbc0178a12d97a78b2dd0b98d0584e8e780b937800ceb18c90eaa1f0a83c5b50e34cae1c20468f004f", + "0x998c9ee20d33f96a2388b1df642aa602bc8900ba335e8810baab17060c1eace4bc5203672c257b9ae750008b707b0aa1", + "0xa7d1676816e81a752267d309014de1772b571b109c2901dc7c9810f45417faa18c81965c114be489ed178e54ac3687a1", + "0xb409f87f0632aae9bc081345b17a50a767ba4198f9ac9d352246fb3bebd29ed53c9d6f148c2f318c2eb12846b0aac4cb", + "0xb40a3bae2b08c13db00f993db49e2042be99cde3d6f4f03d9991e42297933d6049394c659e31f316fcb081b60461dabf", + "0x8c1de4264e04ff7e8282faf81c0bfb5943656451be52170211cb7adf4ff21bccbb789400735579c622f69982fcb8e9c6", + "0x8085c60b6b12ac8a5be8a7e24977663125c34827842aa3b2730854ab199dd0d2eaa93084c9599f0939be8db6758b198b", + "0x972cfaefda96f5edfe0614c01533b76153118712c1c02c505008204a5be2aa438675d97f43384199517b1c08c7c9fdb2", + "0xa1e47798a782a024da340d6d6a1b1e5e15a0f2d8668adf349ca375086964414a563cc1eea3226ae637f87e78c0a630b3", + "0x8171f20c020faae112bb92ca213c1df5b1050151496c70db5c5319212bada83b120d515bd7d8b24736090c574e1b7203", + "0xafe779a9ca4edc032fed08ee0dd069be277d7663e898dceaba6001399b0b77bbce653c9dc90f27137b4278d754c1551a", + "0xa5a07bf219432e9c80c38596c93560b49c7de287f31e30b7a06fcb4d15982add4a24085adbc5b753c462be989c64c96d", + "0x9210be290176d7e8a5005d27e7ed825067b1c678b174bc8180f92b5c03b6c3d1822356edba84f460caf6bf5275cd7efb", + "0xa95bec86a7c8417a8df3a0158199327ba0924d3b7dd94cd7c1ef8489b10270ae64b8537ed39cd3699a48942bfc80c35d", + "0xad9725114b01152fff134c1a8ccb8d171b8cd11685ef6815b76f442d757d130bab9ef4c9845e66f4aa0237ee2b525c20", + "0x8018499ef720e28759133033833edfe17ed23e42f99058bb79fe844ddee823cfdc43916be2dc9724d18f9726e6f1b409", + "0x809c7a08fbef7caf4c137cd639f2e47a8ca60d13bca3990eac51ac2a9e4442cd1a1473bebb63c61d595b586525d7b027", + "0x9793a74fa578ace75b083578277a1ae8766d41a5c508b0f1135fb97dff1d0826002393a7276b18cbc4b3c5671360ce0b", + "0xa6d7e65bf9f889532090ae4f9067bb63f15b21f05f22c2540ff1bb5b0b5d98f205e150b1b1690e9aa13d0dee37222143", + "0x99c935fe18699bca9852200c292690a2b834bac508890c4ee9af1aa6999a8d590bf6a3a274bb55d5a73f1b7095d10f37", + "0x860f5649c5299211728a36722a142bf1aa7cbbfbd225b671d427c67546375de96832c06709c73b7a51439b091249d34f", + "0x9104ac7ad13b441c6b2234a319e1c54e7f172c9a3efcb8c5fab0ac1d388b01895a9a208f59910bc00fb998b0adab1bc3", + "0xa3b109249ac2900806f0f39338da72d4f2cc6d1ac403b59834b46da5705cf436af8499fa83717f954edb32312397c8d9", + "0xb9893f7a47af457a9efd90ddc0c0ef383ab34e9c1284e617c126965cd9f0de5c54ee8b7b5208ff190366fe445e9c1325", + "0xb77416ea9a6b819e63ae427057d5741788bd6301b02d180083c7aa662200f5ebed14a486efae63c3de81572fe0d92a9c", + "0x8b20a852fc8f0b7cdbbd808c04a0cfd2fbccbdc0cb2361434f0d96341c8bde6155695977768d563b95746dcb4339fe2c", + "0x96b15806d9009962fa07f8c32e92e3bc30be4ded0645ab9f486962a1b317e313830992179826d746ea26d4d906bdb7b6", + "0xb0d69b3861ca6791632ec8a87114b463e0da571bc076c22a8f0d9e88a1a5eaef24683f3efa8f34900d0112412e3dc4fa", + "0xb01a30d439def99e676c097e5f4b2aa249aa4d184eaace81819a698cb37d33f5a24089339916ee0acb539f0e62936d83", + "0xb19ca6e55f349bbb2dc3e429520ff5b2e817972470794f35c1aac8c118b37a694cfcc875b6d72225343799825d2f5c39", + "0xb7ea5e0d3cfcf0570204b0371d69df1ab8f1fdc4e58688ecd2b884399644f7d318d660c23bd4d6d60d44a43aa9cf656d", + "0xa778da56ddfe4a383816b43b027464d7a28689fc4a6b35b36883d3f36d9c41f0177bdbfc8f258afe8da90f02d3b64fea", + "0x910fd030feb5538f538e5ba74b9bd017d889ed6d2a797be9c26d2be8caeba7a473006102de27e87755742ba34e445bca", + "0xb49593ea6040ce82cfb5aa2881a4b0c42b78aa9fc8467d79c8e4a8ae4ee7355842841c8e1cc0558362047ed80de44fd3", + "0xb07447c7e87459315fcbda3fb86fef27f98373b1246e2ce367e26afd87f6d698a438501fdc13cc5de9eef8d545aab768", + "0x8a9f7e8d45f11c4bfb0921c6008f3c79ff923452bcfa7769beb3222f1f37dcb861be979e6eae187f06cf26af05e8ee5b", + "0x8ebfbcaccddd2489c4a29a374a2babc26987c3312607eadb2c4b0a53a17de97107c54eab34def09144b3098c082c286b", + "0x93be3d4363659fb6fbf3e4c91ac25524f486450a3937bc210c2043773131f81018dbc042f40be623192fbdd174369be2", + "0x8cf8412bd48b21b008f0207b1f430ed96bc6512c3712dffbbecb66e493e33698c051b27a2998c5bddd89d6c373d02d06", + "0xa5562fbaa952d4dcfe234023f969fa691307a8dfa46de1b2dcff73d3791d56b1c52d3b949365911fdff6dde44c08e855", + "0xa8c167b93023b60e2050e704fcaca8951df180b2ae17bfb6af464533395ece7ed9d9ec200fd08b27b6f04dafa3a7a0bd", + "0x93e4d7740847caeeaca68e0b8f9a81b9475435108861506e3d3ccd3d716e05ced294ac30743eb9f45496acd6438b255d", + "0x8016d3229030424cfeff6c5b813970ea193f8d012cfa767270ca9057d58eddc556e96c14544bf4c038dbed5f24aa8da0", + "0xab7eff4ef8696db334bce564bc273af0412bb4de547056326dff2037e1eca7abde039a51953948dd61d3d15925cd92f6", + "0xa3f9dcc48290883d233100b69404b0b05cf34df5f6e6f6833a17cc7b23a2612b85c39df03c1e6e3cd380f259402c6120", + "0x8b476b3b065a3b95a3d11ec60a749c2258ddcc5885bfb50b8a086d3fd1e49ff73e1dde733b8981c3d2d206aa0c87b09b", + "0xaf3e694ad71684f7214f86bed85149db039971e1c362119b979a135255aa226128802e58e2caaeaf8d89304371dd0440", + "0xaa19a75f21a14ad5f170e336a0bd07e0c98b9f5d71f91e784d1dc28a5f5eb6870a4eb35bb41edcf9e6efe982ae5c2c5b", + "0xb9528983419ab5766596683faebb3592982a76b68593f810186b4e5f94f6de60830739ad8dcc164c601d575b84bd2700", + "0x88e7a12a90428bb45bcf4b01442c11607433211fc2f9bee9545304eb66e0b4b5339360160bc782e185391385da7c5ad7", + "0xa4c4df0e29db19ab4c82dd6ca8570b337d15b59c7d84577a7a444a8f762ff16ff5ab3e4203a1d6b60a23ff949a93ea81", + "0x8f11ee58ef82b1bbd2240d3f548d8681e22bed5ce118d605bed4523b4bb39899ac78e15337daab92666750dfcaf32aff", + "0x8d3cba4d10f94bd3406a341c903ad144cfcfe6b61678d5c03084a56b4413bc30bd20d7a9fd5d839dbb565cc9b2aa99fe", + "0xab8a8769c754008a7976b6799e81d7bfe97413d0a79b90715703c1f8f567675463ec93aabee59277121fc4df88b5c7a9", + "0xb201b0546f19c5db88df9c684cf55ed623bdb43927d06051bd595497df741feb1485961f64e8d3d1811d9e2e9e1e54ad", + "0xa04016e9e13ad845763cfe44af4e29fecf920b4aa42f581715fc34fb9ca27776feee45c82093c7274839eef1838b10c4", + "0x8f84cba7ceb7652023fc8ebde4b00ecde1f550935bab12feb630d6f49517b4148f3cde184bf55d4f6ec99a849fc6f862", + "0xa2248409026f35c3da8bc4d5c02315066df8fca44ff5a358cc42b5c88bdf6866dc133617c697bff004b1ef20ec4b5748", + "0xa52c5a63b55a8001b6b67c5db4fd5e95923052f03618369312896ed9892d99354aebc0dee8c3b365bafa29e211a5c3f9", + "0x8c9fefe233d0d657349b7efcdc368f5aaead27071d224af780874751e7d241f6b88f7650fbb4133043b24bbebc12aa48", + "0x86ceb649a337a5a79c17b496993ca07fa93b38a582367ca04f3dfec5cef8f268d4e8080e5a76b150f5be1b177ef6984e", + "0x87dcb537e38cefa32e629ae669da42e809b5afcabdeeef244b72ce057fc18584a1e8c3f073d5d33775232707f0cc59ca", + "0xa020404547407be6d42856780a1b9cf46b5bc48122902880909bdcf45b204c083f3b03447c6e90d97fd241975566e9bf", + "0xa1beb9f673409ec678020ea4dcbe65177aa18e2932ceb9cfb33fccb94b9a8ccb664f71647d58b3c8b2bdbbffbc02d5f7", + "0xae47b31c5b62b38ee886ee04945649054369018dd6543c91f0138464af489a32c1fea339e0e0cbe82e3e8b9f2ef3918c", + "0xb18c41c0f827f6d8656d3fb93c90b663eb2eac034923972f8842cb30e96c32842b3fbc1127930e1ba4322d5b6641f04d", + "0xa6d6ef51a361df2e8f1d993980e4df93dbbb32248a8608e3e2b724093936f013edabb2e3374842b7cce9630e57c7e4dd", + "0xa49da42c27d019a21cc6489ada7b712b98c4ede28ba25dbcfa916acef48446a2baf73e03a48be763378a09774d4a03fc", + "0x8b62902fb2855300580e94830a4bc825d997ede33bf356fe3b7c08d6a8bd85a37879433fc6bee58f9b44ca280f4e8dfd", + "0xaf9d13103868c854821ba518907b067cfba025d739125f1e9cce0a04fffc3a2a1f25506c1209a0cfe1d6c1572c229ff0", + "0x8910f41db6952c25dfbf6b6b5ba252a2d999c51537d35a0d86b7688bb54dcb6f11eb755a5dce366113dfb2f6b56802b7", + "0xb551d1ce88cbf4ffbdcb0113a6e319513bd676d0078dd4e6a6f23ad336c1d0fb47a4e427bdedbe0fc8f152353971f81d", + "0xb8876bda1e709ab16e1347a1107852a7898a334a84af978de39920790b4d82eb0739cbfc34da1c7154dd6e9f7674759c", + "0xa7d9ae9621dd1f3da3cd2d435e891cc3579c4c0d60d6a4565cac86c315cea21a9ad883559fe7b897ae6e05f1aa989ad9", + "0xaac995a41c14d379853ef18ffc854ad62ad77061ca9bdf5029cab3d6c2630de114e777a7fc3322455939d5205ed59c55", + "0x999cec6a31d9b2f280017ddd59138014829fa34cab58e6c35a5014ec364b84712441e7a2f717cf2f0de8d5451e250924", + "0xb1f43b498cba1797f9793dc794a437500c3c44a8a4b59f9125a4d358afa304fc05b88ac31ed40b6eb68f0396b60cb7cd", + "0x93ba2e000bdb7269818d390bc4232992d280e69abebe2db2ecb6fcb1390d323238c9793574509bc1fa34051ac1928f07", + "0xa64808a2d15c30460651c200a09b50fc83e9d84d87abc156d06cee73b76fbd74e6d64424cb5bb83d3f16b21bdb7ae9d2", + "0xa75bcd04fcb44ce5cbab7eef6649155ec0bef46202e4eb86c88b4ced65e111f764ee7fb37e9f68e38067040fedf715ee", + "0xb95fc0ec39596deee2c4363f57bb4786f5bb8dfb345c1e5b14e2927be482615971d0d81f9a88b3389fac7079b3cb2f46", + "0xaef456af90354ff88039d2dde02b0f5a6790aa762b23e0a9da8c6ec92c3b8b3320687bb21666608b4a22615843afd1ef", + "0xb38be9ada17ced704a34a7498c4fd6ba2503f6bd886b693d4712267847efa887a26e7da5d60f8bc5014b92bca8b3a12d", + "0x991a7c93f06d50ec6a4340c6751b73eb5825bad02a954e44e1e2d424af928819ebbb590c6129ce35b3f1e908e2152f33", + "0x84888f2efd897a2aca04e34505774f6f4d62a02a5ae93f71405f2d3b326366b4038854458fd6553d12da6d4891788e59", + "0x941e2e3ba414a371a11c3fe92cabf688ff363da6230ec7c83ac7303f652a19ebc89cc494427c456d0c2ae84c72053f73", + "0x925f3bb79c89a759cbf1fabdaa4d332dfe1b2d146c9b782fe4a9f85fee522834e05c4c0df8915f8f7b5389604ba66c19", + "0x941c8962debd2756f92a6a0451a2bf7fbc01f32ed03d0823dffd4a61186628a4c3c7c482b18589ff65e4c449fa35c2a4", + "0x88ce41025aa153a94f91f22e7b96f9342b5e0e1d76274fc70c4df7d08f66d9f7ac86e55a1c6e77693b8b01b2b38bf900", + "0x8f142bde50abe4dac8e059003db41610436d5ca60d2dfe2660ecaa5f9628aeb8b5d443e1b57662076f77363c89a1479d", + "0xb2affe048c187d311a185503d8958cacbe03796edf79bc32e8533941004d9178bd2e376e627e1ba61ed43850c0c455cf", + "0x8f7bbaaac458bada6d852fe665c87c646133bab16c0d5136c3dc922095b9d647d93a9de7671cb7bfd4cbd138ae0709d1", + "0xb76f598fd5c28d742bc1a81af84f35f1284d62239989f1025e9eba9bece2d746a52f246f9bb6bcfde888b9f7b67fc4f6", + "0xa4c665a3e4e25a7af51e433c978573841bfa2c75c075e17dd1f43b2f0369249f3d3a46ff51051e8ce7da528b0fa98d16", + "0x81e0992e7c1c54c21cac32e36b90b25e1e5b72aac99c953c3c4d019eced64d7e316cbc0840204a4a51a4ad17d8b1d508", + "0x96d7a69eaf2761bf0e5ebcd607b134d5dedba8e262ca1d6d3e8fbf23e6419a8ce1bbe4cd23b9e4b5f80db54a802a9795", + "0xb2235bdf60dde5d0d78c72cb69e6e09153b0154efdbab97e1bc91f18d3cec4f660a80311fe6a1acd419a448ab65b18f1", + "0x838d5eee51f5d65c9ed1632d042bb7f88161f3789e6bb461318c5400eaf6728e7ba0f92c18e1a994aa4743145c96164b", + "0xacfbac397ae2ff23b31bb27b90788fd0fd51a50f8e8c9f4b31be8499194252014f0b1972b204aeb9c2836a20beb3c868", + "0xad85789bb62b60e9768bd330a31a16f711b6018445af6a47646f318f12df8d4d256ad00d1ed7c3afa4e98fef73c6c610", + "0xb2349265be33d90aaf51362d015ce47c5ffe33e9e6e018c8c6e39336d9327ccdd13d25e792eb33b43ed89a162f6ac2fd", + "0xaa458aaca6ecb43b6e45ea72d02682e5a7dc8dc22782669a0628e1638e73999319f011803f4ec8cf072467bf2c49c629", + "0xb9e6c9f2562e90bd3008669a42151538b70faf028cc5bbc09fd6ab3febc626df911fcc65744a2ad793ecaf3f91a1f701", + "0xa37185bd96faa526dfd3ddaff89b1eb29ceb4597bfc7e346bff9d6b3225b9ca87cbce0db94f05243c7232ead5f6607e8", + "0x824fde65f1ff4f1f83207d0045137070e0facc8e70070422369a3b72bbf486a9387375c5ef33f4cb6c658a04c3f2bd7e", + "0xb0ed68167a67490bd7d7d49e83341606d6e6fdd99b82e46747c2190d270719f81c5f5f8733646c246260f438a695aa3a", + "0xa87c2f13f2a824b7e2c39cfb63ca7b94ae6a11ade0c6b8e83f5092b933fa8b6157a5d2f09c23081f49d35cc85f5db36c", + "0x88f5e795cb36ab22bdcff01caca0e9d04db463c3d88cf656c3a0e0f5ac864b7092c738758b4c8f3b65e31995c6aaf267", + "0xac66f3a7041586ac1576e33598f01921e16d99afbf4249c3350f0ee1654de98bd37a61c243eb6a18a942db529e36af0d", + "0xaca69a4095567331a665e2841210655636a3273d7b7590e021925fe50757617898e1883532f9cfd46428c2e3d854f9f7", + "0x946d585d7aa452d37a8c89d404757c3cce2adf2410e18613483c19199abd88f7a12e206f87a43f6009e42f4e31ed20c0", + "0x9722c1079db7e2e1c49756288a02302b43b8fd92d5671585ac1ea7491123742a2744a526c12c9a0b4c4a80f26342a3a6", + "0xb80e8516598c59dddcf13fdb7a42d8f5a52c84e01bd6a39880f4acaefe8e4b8f09cc1b1a2423cd5121f4952201f20078", + "0x85bca2f86423a09014b562f7dc613246bedffdcb3aa41fee02270c13e6b00c8d6704dcbfbafc5997df6a90c7fc08c29f", + "0xa36dad4f7cba9f4cc843fe40f6240e1973a4c412cae29b4a68712598523cfaecb05272fc47d30772bf06906b5a26e282", + "0xa3d8610c2522d330df02511710e52b1d9bdc9f2b156deca12b1bf754266caeac4f449ed965d9863558df43ce9ae65a44", + "0xb3e313e79d905a3cc9cc8a86bd4dba7286fb641c2f93706adb3b932443e32eff2cbed695beeb26d93101c53d5f49d7db", + "0x88d8a32231ff2bfc39f1f9d39ccf638727b4ead866660b1b8bfbdf59c5ab4d76efddd76930eff49ea0af048b2e396b6c", + "0xa90d9502a9785e55c199630456fcb1e794bbeb0f5f8c022e66f238a0789998b126cf9911fd0b7d463b7706dc6f9ec128", + "0x8c627caf25eae6764501b9eff35aa90bd4f24952cad712aae20344579e83ecd104ad1f7915edc4f9023b17fddbdb4cd7", + "0x87d4b20bbe2dcd4f65f4e1087f58532d5140b39a5288e1a63fc0b7e97a6a56946eafdd90ba09300c3d1fef6356ac6b7c", + "0xa18f4464cf5cebade8ee280fa00e0917cbf1743aeb0dacc748ab68773b909e30dc60f40fdef3041b5f082e650985f7a6", + "0xa6ae4fd03fbb4e2150795f75a241ab3a95c622b4615f553bab342a1803b86b1c1a2fc93bd92ee12786bf2de22d455786", + "0xa89bc7548ea245ce9556eeee3fba98a3256f87499f54a7c5eec0c43b9fb4ef2fe8f6810867ed0df814a88ee100c245af", + "0x97f1a7370b4f5acf83b466f519da361c366915f560385dd7eff9d53700ad81b25c9862bc71d35428e82372a5ae555ea0", + "0x825359cfe68ad6a75578a94be6419179e0aa088170b6c20fc5c249dc3be7a260d687c93d8d8a343c7c72c2ed6a716de3", + "0xaa9b9cc039d147677aedd1e47ad9013fcc0da0164070ff7305b18e5786c7fac0471368637a3adbb78f3af174a5c1592a", + "0xa61687511b627bde7b3977e9a34cb7fddc2aaa509a7b99b6b6c7b97133845c721e1e69f99758698d82cca265d8703610", + "0x8853c582e86cf916750d670a621246a63c7fd78f68c556642053bcdfa7937de58885d728209736b7d5521b591387e9a7", + "0x82b8c013f24fe64b8e0337ae8b6a682cae336b8404eafc1404744f80f765efdb8b2873d1d3f31141e8dfe4d93346ac56", + "0x866ec39b9eda580d96bc2bff76af5cd4887b6788675149ab33bfefe38db82ad01b8d64c6b60704210918f3564cde1110", + "0x81337ebe90d6942d8b61922ea880c4d28ebc745ddc10a1acc85b745a15c6c8754af1a73b1b3483b6a5024b783510b35c", + "0x807c510df25c0ba10d4aa06a462e02f050c69a977c64c071401ab74f9ac1e60788aa504743b4cc1982da835ff9ac2541", + "0x96b1c82b85cdb8a7026fd3431bea9cd008f0261ee7f4179f4e69a399872837ab836a14e2dd45f5448d54800a4ae7c7f2", + "0xa48b1031ca2f5a5acb4dbdd0e9a2b4e9add5ccfc0b17d94818273c8df11e825193fade364e0aec10f1ff91d57d03a52f" + ], + "aggregate_pubkey": "0xa825959280c88c6716f6df807204feb84d745dfbee3cb3474ce81a1ef0c4cd142e5ca962a0335e68b7b4266769d631b8" + }, + "current_sync_committee_branch": [ + "0xbcfe80e1d24fbdad7bc058b011403a4c26cb56967654494cde51517f888023f4", + "0x4710ae46156553fee6231622052f7fb2f6945cdb59a5501cef824b1925c87445", + "0x6df62e05ef3e1ac92c659c3a519b8fa651d1b649c2b46fda58c48cdeffe8337c", + "0xd26ff22ef5958a707a8d98eb1ffaaf1f9f412e816c04b79f5434cb1792ccf608", + "0x90d5e61f0af673ab4d8b3ab0b978d05142a8295a163b198e6dea9d8c8f1c6d89" + ], + "validators_root": "0xd8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078", + "block_roots_root": "0x5078f286fa90b88a09dcccd4ac72f6c3615b77c0ab3132508cb8c0c07b20282d", + "block_roots_branch": [ + "0x558b658b1230e225ac3adce3daf0b066ed0484b4a768d55b74ba81579ca0e5d0", + "0x2cbb27d38065ff3f230247af918e67d1998b67bc7e2ce6c244bab7146e16b8ad", + "0xc63bfc96585f424385e3b4b39ce46e957017b716c54d105eb7e07c841d1d4309", + "0xe662b38f57427b58c46b09980db3856f17e56b60b36bd5471823b0f2cc1b6467", + "0x8b3bd99618b1e50cf284b4c3b03d0cc272312bce377d585eded77154aa5580a5" + ] +} \ No newline at end of file diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/next-finalized-header-update.mainnet.json b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/next-finalized-header-update.mainnet.json new file mode 100755 index 00000000000..3440749102a --- /dev/null +++ b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/next-finalized-header-update.mainnet.json @@ -0,0 +1,38 @@ +{ + "attested_header": { + "slot": 4066880, + "proposer_index": 1904, + "parent_root": "0xcab3b6fe3ca0c3ec6f9a8290d1cb3ade42b019f399dca754060518eda41fd429", + "state_root": "0xc47d2d0ec566de4bd41082ee14aa6294c05f264a4fb6a73766c75df917b57a55", + "body_root": "0x5dc66f1cdd8fe849e0aa63b096a8083c16b00814f37edd213819852cc43317d6" + }, + "sync_aggregate": { + "sync_committee_bits": "0x9fffefffffbfebfffffffeffffffbfffffdfffbffffff7ffffff7fddfffffaffcfeffff7ff3e6ffefffffbfffffdefbffdffffffbffffefffffff7ffffbfdffe", + "sync_committee_signature": "0x9146a1a3cc2520a69415103446e2c30676fcd164ef2beb42933bf4beb753f5e94f28fdcb6296e3ceda302b2a93c716d515a890894365a36ed535e099da76c7e585b8d6ed5fc2ec3c316049b14da844add39bc79cd3829a455f552438669ab70c" + }, + "signature_slot": 4066881, + "next_sync_committee_update": null, + "finalized_header": { + "slot": 4066816, + "proposer_index": 1396, + "parent_root": "0x17d77d07327f42b16d6d87a06c6ab5e56ce02e3ebc65ed2d28a64dd0c3a33d15", + "state_root": "0x9b498175419bce5a027c432fbb844f35138dc00083540a04ec0f54c77eaf061d", + "body_root": "0x6650167595152e94d0741c7a7b64d2c10ed01b0d11519f7d0c615c8a60dfae2e" + }, + "finality_branch": [ + "0x70f0010000000000000000000000000000000000000000000000000000000000", + "0x3d4be5d019ba15ea3ef304a83b8a067f2e79f46a3fac8069306a6c814a0a35eb", + "0x452c63d803b8bf301447a73b2f7a747e49f37f9c9a096d8ddb6c8302666b809e", + "0xdfebfd48ce69c56abd05de8266c76478936901404ac3869f0c068c5cfd33b301", + "0x6f1a65d993b2f461764934642be084a68bccee505bd3adc20cc69e151bc6330a", + "0xbd65074f41adb20717d733e64d219d832064b6417b90f22de6d065cbbd6b3d83" + ], + "block_roots_root": "0x4729dbb81e8ebbbae1acc10857551a3991fd5da08c27dbd304b62673edcd46a0", + "block_roots_branch": [ + "0xa3c286182434bdd4d55be8ef6e7212917dc272c204a4daff2d0244fa993d86cd", + "0x00d2df4cb3c0b06bb4f2722f975d6630a7f3c2a1ff12d635e2109f08379e3922", + "0x135a357782eb8f46d14db6e62bd3e9ad611d01f16a3e573cad9ea0c53010bdc7", + "0xdb944338cc4e7b11242b39bd83159afb122504a1934569bb500a4228b884b8c6", + "0xd381920000999813479b975b7cf0e5663b52c3ab06bb6ac66e723731e8f41e9b" + ] +} \ No newline at end of file diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/next-sync-committee-update.mainnet.json b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/next-sync-committee-update.mainnet.json new file mode 100755 index 00000000000..c445bfb48a2 --- /dev/null +++ b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/next-sync-committee-update.mainnet.json @@ -0,0 +1,563 @@ +{ + "attested_header": { + "slot": 4063296, + "proposer_index": 944, + "parent_root": "0x3e8712719bae71b519a25b7eeea9b412acb882ba6bbeeadc596b1682838cb6a6", + "state_root": "0x16add3b722d0b9075e7a3fe9cef6d237698053edeffe1b95f5b59a31f1bb4f1c", + "body_root": "0x724f1d72cbacde14baf82d273d3c4eafbbda3a56cb0f641cbfe76a426657327c" + }, + "sync_aggregate": { + "sync_committee_bits": "0x9fffefffffbfebfffffffeffffffbfffffdfffbffffff7ffffff7fddfffffaffcfeffff7ff3e6ffefffffbfffffdefbffdffffffbffffefffffff7ffffbfdffe", + "sync_committee_signature": "0xb2f86b054283455ef620757c13531ef64baaf8899527864aee1b86301c62c72b6c979865579e04880790c1ea418b53a717d7b8b85c70fda1760b2436ee04a25b13a8906d6aea8e94facef2444f33e4d5b4e91439adb981900c253186e742f1ec" + }, + "signature_slot": 4063297, + "next_sync_committee_update": { + "next_sync_committee": { + "pubkeys": [ + "0x936749ff47e5be307546564a5a4615bd8df52e2590034b2db19846939af3595a79ccabf0f6ff52ca46b9a1de3efd47a5", + "0x93fda62b785757b465e6f396f74674d5b95a08c938cf694e66beed7d2f317a4c9d736cb54d7c221d61e8cb3d64dca3ab", + "0xa39e96e33076fbb49c35a58b6e386d22fa7378337bb8b0d47699264f78e5ae8dc143f1f6d5f8b371deafc5c875adb60a", + "0xb5f69b7614fe07889b58142d7b438186d70214ff4cb209b6f271a3bf2bcdef5e6f1c7e95dbf5f2785aa471f0294cd029", + "0x987dd977d6b8d27c4065b61b3c078ec9ce3871fec02844ed00f5ad28c42f9cedecbe830ddd19e11a5c879b01eb0f8f80", + "0x9969ab62009b6aa81734579346766937d22ba73c008d24bebc183d1b3d3cfabc90b47f41b29bc6e23d70165594c2e774", + "0x840ac0e104b22eaebcaa1e49be43689f45434a6c5ddb71eec577323f38836ada5464b317fa3862773132166f2ac0a536", + "0xaf96a83f97ed0696fd29e59daa24e1857e16371f67089d08129f9c236753ea68c93590dce4d32c9e9818a21014da6f0d", + "0x8779a0376579008d0daa99895f548dd091b3abab37e91efc9cabf08835068c983ab0927e7c8eb0396eb83a5e0a713c56", + "0x99289672bfc48d2fbfd51a32d0d7f9d03fff37b8269ce45cbae1e9a091ee3983774d053efe8eae2f2d3f22a9eb532457", + "0xb60df25a7ac1ad14aef7e8809c4bfc190b715f94f14b0534cc2e4015ff6c322883cbdc5309e05d67dca4bc641c69725a", + "0x8c22f1f2a530879a93e744397fa6acca57b01fb62b62188ffa7487464815c605e1520ff4bb18e832753893649ab80d62", + "0xb3acfe8f25eb5153b880a03e07760f7fa30beca475843581b4878ac0412cd2038117f25a48c152e6d60ec16e4b1e9a45", + "0x8163eea18eacc062e71bb9f7406c58ebe1ce42a8b93656077dd781c2772e37775fe20e8d5b980dd52fdad98b72f10b71", + "0x8100b48ac2785477a123a7967bfcea8bacef59391680a411692880098a08771ff9786bd3b8dfb034cae00d5a7665621c", + "0x83bbd31e799ac14686085868e8ea7587c7c7969c7015bfe45fd8e3a3847ad5338005f9cdf58396b2ea833c4af98bd9ca", + "0xa59249e4dfb674dfdc648ae00b4226f85f8374076ecfccb43dfde2b9b299bb880943181e8b908ddeba2411843e288085", + "0x9793a74fa578ace75b083578277a1ae8766d41a5c508b0f1135fb97dff1d0826002393a7276b18cbc4b3c5671360ce0b", + "0xa734a3c947be4c7e6704639d4400aec2ccf5f1af0901b41a29e336afb37c53bf168774939ce51f32d4496bce1a32e612", + "0xb96a11048c7c327709d52e72e6f6ed0b7653329a374ea341ad909311b5b303e5629d6dcf11dcdb195e8c7592ceefac21", + "0xb3b7af9258af054362d461a74fcfeb6dcf3a37b6e33b6df32f8317d50d8be8e1970818a6e41c8232b89e1c8f964c6c1d", + "0x907c827a4fb5f698bf0e6f10ca07741c5b8e3ecb26aa53f938ba34ceb50c01be80c4afc5ac4358a5fda88eadea0cbe73", + "0x84173aeaf3d96368dc7ca1ad5e5575da279113567e5815a364a0356a720c5e08cb58ca1fdd891924f4871d3eaae5de40", + "0x92127d55535bf59f2b00511c82f74afe90529d4abfbaca6e53515d63303fe52b4b22383fb026a2a3f88e96d2bd235f6a", + "0xa9f261d19934fd26458421551e91f484d7a1522a7e7adbfb28f6371102a7650a5ae6efd49d9e33b03aefde647d134ce6", + "0x880b4ef2b278e1b2cccf36a3b5b7fbce94f106ed9fa2820cb9099a7a540a57e9fdeef5c0fb0a743049828fc2b8c46163", + "0xaace45334070c51cc8b3579598d4cd8cda2153bba51f56e3b1fe5e135c83ef70503c322756b9cad9d3cd28f1ecfc8227", + "0x97578474be98726192cb0eac3cb9195a54c7315e9c619d5c44c56b3f98671636c383416f73605d4ea7ca9fbeff8dd699", + "0xac5c01c51dac6ee1cb365c9b03f09906d9b7b9b4d1b73c44d9e8e06823025d7070f242898a975420bc87d6372382cab8", + "0xa9a591fdd18aec8746435eeead0a54bb88e055f55e91ffdd9bc663ce0bc2937fb296034ebb959d6adcf9af94bbd2f49b", + "0xb495404544c9335d5f184cd6873299a93174905fa34c14092f67d9b8545e71fab29545bc337e380dffcb533f7390e9cd", + "0xa3b7fabaabd4c2e555dce46add6c56851b68308c1bb7253576a9f32eda141522317b5c00a28b384ead3a880b8e7e40dc", + "0xae0beb452af7479134a7fbc31a5f59d248e8a67d4c7f73a0e30a51db9cd33a1da3f0ae947fa7e5983aea1343e7daf06a", + "0xa9d9a295590641b2b09d8473b50c0f6e036e1a009dcd1a0b16d84406763b4b078d5de6ca90898232e34f7f7bf147f61c", + "0xa5fe3dfb5031517bb8db0d5ade1e9f438e84bcf23221de003b03d2a2f4ea97629e81c79abc3769bdb8c69a512c189b91", + "0xb614910b247c6ade31001b0435686c3026b425b9bff80b6c23df81c55968633349e1408a9a5a9398a7d5d6ed5d9d3835", + "0xa19e7db50604f6b82cc28bc97135025459c8eac107a1c482919df10b8be2e4f24fceb93b963c0b8ac9f402e2f6ebf387", + "0xabf7da952c9d8f75fcc67fa7969fac0b26d4dc3e022961ed674ce85d734f11620a950fb1fb0ef830fba1d8b5bc3eced4", + "0xb382fa28670a5e14dc954b2db8ace250c73df71ab095304bd8ee28f455ab26cc54f82775a831428e110d1a3a2af709bb", + "0xb284286dd815e2897bb321e0b1f52f9c917b9ef36c9e85671f63b909c0b2c40a8132910325b20a543640b01dc63b48da", + "0xa2b1ea43f51460b3cb83657b4e296944658945d3ad6ae7b392e60f40829ba1da6a812d89f0380474578cbd0ab09801ac", + "0x8b886448cbbbeb40be3e71ccee251632186dccb51697f69eb5c746000b4327fd85be3a58fbd49f1df642a37f6388a8f2", + "0x9161ba220130eea190932ecdad9f114e385a31ec51c71cc8de451ffe5e75abcda37227c6a77f7090d4d8bbf134421bca", + "0xa24d05b51c7c128bb49979cbd9019e6618545d95275a44b5c3d1d03e71bf2ebffdf43fff50c30846ec27d279043cef4e", + "0x8cd1c73b7fe915e7169d351f88ade0f810d6a156fe20e4b52c7a697c3d93459e6d6c2f10dc1c6ec4114beae3e0a8c45a", + "0xb95e3032192bdc064306c683982d885f0ded8b907a532f15526a257ffeff2c8bdd7a2334c10d74b1484909b2e3ae0e47", + "0xac754a42f279472760bd36dd0cf36f5ec685e7fc2970c275811a70cd05843f94fe21745dddbd54135144edf1793aa0cc", + "0xb26b4d483bca73d3f3a976bb595a0e40f9a42094e0febbad3a1874934be1939a1b362ee4ea14a4f5cbfa9b1392796a12", + "0xa841594e74b66935efd295a6c06e2be03cc8c187b277cbf5cd2f590630d4812801ad55f3e502736d126441a2f22f1867", + "0xa845a8a3299f8e5fcf72358521a114c6077251e62ff6a885003f7281b0e1ee33715d9ca0b0082fbf7cb9d452d531c38c", + "0xa7b86e4f1366da44fd59a3ee68018a99c23ba3588789463bd88b0177a9b94030b58cb879a506e64421af966f261eaa86", + "0x85822227f6a96d3b6d6f5cf943e9fb819c8eaf42a9aa0bdd1527055442b1caf672522762831b2dac397af37a1c5ed702", + "0xb455f751232de0a48440d09983f4f4718b6169907979c9f282acf7177ab5b1f338fe1f2acd8d0bee4b4aad61d0340839", + "0xb97b2f1b2d6d744f2322812825ea1cf91453dfe1bbbb2678776e40e7d0fe682239d0dc8053f94d97e5a9678232b7a71f", + "0x815f53751f6d3e7d76c489f3c98d2b49214938cac8c2b417e2d17bb13446c285fa76fd32a97e9c4564a68f4faa069ad2", + "0x8ed7790f87f6975e0f3e501901b0bec1778c88bf39588989014c5dda76c2163732e7e5703c9cb2c1a6144ffdac5dcbab", + "0xb6cacc458ca5a0f04836c5640d34c70cab34cb5c87df28579a0d5e2c72edbc092814bdbe902747ebe3ce36808d8f4dac", + "0xab7c058199294c02e1edf9b790004f971cb8c41ae7efd25592705970141cdd5318e8eb187959f1ac8bf45c59f1ead0d9", + "0x99365fe5ab8ea8bd768ae7181a6ba49b79d240f512ce309b02f09d465fea276298ff55b5b9cb5b4162a901b390606024", + "0xb1afaefc9fb0e436c8fb93ba69feb5282e9f672c62cbb3a9fc56e5377985e9d8d1b8a068936a1007efa52ef8be55ce9c", + "0xb37334c41a3456b73b61d0eb0777260af9c2e400bbec0e0c0fdb45c39ce0dd19f021d9760f35da801f20486c6be30e9e", + "0x95757096c132e7f6c096d7b93a5a0d2594d5e609b9f13c4a9f878e95a389fa1a111b185dc1fd8f7d98b737dcf8d2af60", + "0x8f71f8edae59d6936846d8b50da29520f69b339f574ba9156d3d5f0cd4a279d36bad7ca7eb724dd48aefc4ca9ce26bdc", + "0xac2c98a0ab3f9d041fc115d9be4a6c77bd2219bb4b851cbee0d9257a4de5791251735b5b8fad09c55d16eb0d97080eff", + "0xa09f11d2bc6000d12a42b545ddc29c1973944a39787c5f27c96d4f6aa0d9c8fa9c479f2ed327fbd30376df3fa5b7d2a8", + "0xaa19a75f21a14ad5f170e336a0bd07e0c98b9f5d71f91e784d1dc28a5f5eb6870a4eb35bb41edcf9e6efe982ae5c2c5b", + "0x92a488068e1b70bf01e6e417f81e1dc3bcec71d51e7eabbc53b6736e8afdb8b67d191940fe09c55783be9210e1cbd73c", + "0x95cf2e038c790ce7a2960add7ab44804375f04ec6829f8cc63793dfe9fc48c7471079f81b932726509394fd3d46a52e9", + "0x87fdca39618051c4b3f03c816b13df2d4cd4c7c564e3d8693dcb58145b7b3b3db7884b0125b1e84d9bb82e91bed8bba3", + "0x815922ad356f490910e8cc3b0f7d3934b5e28c09711b5151ae8329876670f3de6d7a3a298fd97b580ac8f693305afb21", + "0x8bb4d08318386c91a0136d980a42da18c05743a5c52a861ce52a436e66a8ebe472dac7f7461db32ea5da59a23e9bd6c9", + "0xb0053550040ab3a3996cba5caf9ad5718867b5f5df273ed8c6520761571f03a94e50b5f8a6a8c42d725383cce97d3cae", + "0xa42c46a7e617d78b12053d7783f0d175fd9103db06d0c6982b38893a20b72fd8ad8501eacb3d47be06fd7c3ad89a8159", + "0x838ff6630dc3908a04c51fb44a29eca5a0d88330f48c1d0dd68b8890411a394fd728f14215482b03477d33f39645dceb", + "0x8ba45888012549a343983c43cea12a0c268d2f7884fcf563d98e8c0e08686064a9231ae83680f225e46d021a4e7959bb", + "0xa59a59db246f981e9c8e54aba52898c714d9787fef8969a6d8677fe6dec82950ff22a1364393b579f3e596cdf5bcd7b1", + "0x8722f3267a945f7123c1df8b6c2122456d81fed56e6369ba726b023c01c1f6738fc12e506e260d99e448fc920fd5e5af", + "0x89d356593ec09d838cd89306ce83c060ee797bf9eec8523f581cf263925699ef0f7161a790bd00bb09681534ed05ac82", + "0xb97fb8ebf2ee1bae5914cf96e5a07887ba41e712530eb2096ace318e989c0ad93060cfcf40507d927af6c7e945bcc289", + "0x88015bec478fd3ddff72efda0e8fc54b74faf804b0a3473cca38efbe5a7e6dc0be1cfe3dd62b8ac5a6a7a21971dcc58c", + "0x860c0eaee51b7de26e99033f352aa09c093943b59237f1313ecc35b0d711509bbe9f939c4bd646deb7de8103eea9ea13", + "0xaf9d13103868c854821ba518907b067cfba025d739125f1e9cce0a04fffc3a2a1f25506c1209a0cfe1d6c1572c229ff0", + "0xac7983d50ec447b65e62ed38054d8e8242c31b40030f630098ce0a4e93536da9179c3f3ae0b34a0b02aad427a97ee60d", + "0x8261f7e644b929d18197b3a5dcbba5897e03dea3f6270a7218119bd6ec3955591f369b693daff58133b62a07f4031394", + "0x8fa2d7b22af8e6b82679ebdfa13efdcb34289a554653ea6c1b16efb9f957f7fe64df787e7b03d8cdc8a732b91c916bd1", + "0x897eed8c65712e9b1ed8213abb85a6252ec30ab47eda4e36aeb8a72447ce7972861bc97957bc321714328c64af27544b", + "0x998c9ee20d33f96a2388b1df642aa602bc8900ba335e8810baab17060c1eace4bc5203672c257b9ae750008b707b0aa1", + "0x92378adc9d56996ce8ecdb9ed6510affccbcfd96712a23631edfd6ffdb1469847aa447db6b2bf61dad416ebcc5b7d1a7", + "0x83fc998e050cb1004fd016c7dc62885b07a95fc9b219fd6fde8ca2824c647f331f6b18ebdbd14569b906cd1ca1066189", + "0xa87c2f13f2a824b7e2c39cfb63ca7b94ae6a11ade0c6b8e83f5092b933fa8b6157a5d2f09c23081f49d35cc85f5db36c", + "0xa89bc7548ea245ce9556eeee3fba98a3256f87499f54a7c5eec0c43b9fb4ef2fe8f6810867ed0df814a88ee100c245af", + "0x8d52413f981bc611427ad0534d25e914113d0ebcd6960aab6421608bec6648b89ae4b2ca2153c57d3cf4f1f37212aa5c", + "0xb0a4c136fb93594913ffcebba98ee1cdf7bc60ad175af0bc2fb1afe7314524bbb85f620dd101e9af765588b7b4bf51d0", + "0xb7ac87da14b783914ab2e914fb7b536893b7a650cdc5baa1f3b4aca9da77b93a3336671335250e6467a8cd4aa8dc61e9", + "0xaaeb0005d77e120ef764f1764967833cba61f2b30b0e9fed1d3f0c90b5ad6588646b8153bdf1d66707ac2e59fd4a2671", + "0x8a60e066b13eabb372067a6b08704f3b6b98c0d468942738768127ebfcf122aef0ae2303f361c6338010fd371646769c", + "0xb7de6d7a4afb05984dce153e5570b104338265e45c8f0156f4d45c458f47add234a479e01c02d3c1817c170b5b65b100", + "0x983cb6bbfe83bce8326e699e83fca01ea2958c09808c703cac97a0ea777e5a5f3f5bba9169a47732de7459a3c7af47d2", + "0x8db19f6dd3789df179ab606508ca7e3da7967ad4340f630bda83df54c197d6bd3a14980c87fe10cbced7678c0c300ef1", + "0xb4e6bb207e08a1e096f6b27a5a60effc74fc8db0b6cdebc9ddbe88f434f4c8e0bd7fa77e015cc309db0f0922bd05b3f5", + "0x951d69f32685615df304c035151bd596d43bc3250f966e0c777544c506e3035d031afa4a3fcca1b85c41a4a041aefc01", + "0x942bee9ee880ac5e2f8ba35518b60890a211974d273b2ae415d34ce842803de7d29a4d26f6ee79c09e910559bdcac6d3", + "0xa0e68d24f784fcb2b71acc2d5871285623c829d0e939146b145e04908b904468a67c07a2f156e6b17bf531adc5777c4b", + "0x921da028f26a61a034f5425d6618eeb61adaa8ff10141bd65ac970adaefd3737a4bbd77d8a7a90cccfca35b0f4d585de", + "0xaf6911edd6c7ad30f905a0a3f78634808832fdeb4206b006934822d673bcced8e378779261b3c4b772b34b8871987f57", + "0xb044857d879d06e9be5dd70498b27a20aee758ef829d37d0ea12b92aa84b9d3c6194205368014d942ae0517cf6d0e201", + "0x8f90e72a54e6894d511061957162e753010812346afd4d90cfedb678b99ba1aacf2b6bd0e49b4b0e684da8082a048619", + "0x8317974fb1bdd174c7ef81a2a6478f887f44c1e8680c21730974e5c440846c4d43a76a3e90334b39508f507163e2ff8f", + "0x976eb5543e043b88d87fda18634470911dfe0e0cabab874ca38c1009e64d43026d9637d39dcd777bc7f809bbfc3e2110", + "0xb53fb1956a2a34a840de4ff0b5b1e0e2fb78a21ac8edbce6be6c26a4b4de6d37e9dce799110a802a344e8541912353d7", + "0x85bca2f86423a09014b562f7dc613246bedffdcb3aa41fee02270c13e6b00c8d6704dcbfbafc5997df6a90c7fc08c29f", + "0x8bca3560946189e4984126acb42153d8dad0b60e7f86518b55ea9ff7c899c9ec12821850943b6adeffbe9363bce4d217", + "0x952a95612aecce4321d2c17aabd2fb260b1cb41df5f76f5b82b46cf818d7a4f18e5e2944cddcd2280a993c0af4f834fe", + "0x9722c1079db7e2e1c49756288a02302b43b8fd92d5671585ac1ea7491123742a2744a526c12c9a0b4c4a80f26342a3a6", + "0x824c8a1399ab199498f84e4baa49ff2c905cf94d6ac176e27ec5e2c7985140dbaa9cc6303d906a07ab5d8e19adf25d8a", + "0x94bbc6b2742d21eff4fae77c720313015dd4bbcc5add8146bf1c4b89e32f6f5df46ca770e1f385fdd29dc5c7b9653361", + "0x90f7fa9a30d9f2812a20db97b3d03962a5b59719385c1881c61009e4c049809efe378b39cf74b64daa981358edd691de", + "0xa4632399c1a813e41fb2055ef293466098ea7752a9d3722d019aa01620f8c5ecdc5954f176c6c0901a770cbe6990eb11", + "0xac79f5491dbbd0eb47669225e781f94b98d04947cbc55baf287365831c100248bd0b39c911ac09b518715ba1ef0602f3", + "0xb9574edb9567f07f85c7c2e6ca6c02d90ad7c7b87d49796f1e2fb7240ad071fb755cf13ca8678668a56217c62df168eb", + "0x889a5cf9315383bf64dfe88e562d772213c256b0eed15ce27c41c3767c048afe06410d7675e5d59a2302993e7dc45d83", + "0xa0b3dff15982a38a2f56d8c6cfc5c5543c045bf2db24571d23387ccab42abe2756f34d5f0bf6a426bbad3c358b8bdb00", + "0x8009dff405aada0798a6cb7f418f73017d7a569a7576aff51348b15913a5e639dd232657cd775cfa0dd811ae5e301241", + "0xb31949c4a21181a54928f25f8598ea3dfcacab697a5653beb288d218d312133e5a93f434010ffdab3f3ebd0b43b207dd", + "0xb46f481155df4c4d576e5d76f1d4054e1129cc49398533ed32d0f681701276cecad4759e47b818f20d6a087989449529", + "0x88158d759eafd2205c770f166829fd61e8f17b2c13f440777eaf45f4d88a6e2028bc507680ff435882d5fb462f813735", + "0xa922d48a2a7da3540dd65bda3a8b5fb1f1741604e2335de285ac814c69c40b5373d92bc1babd3e4b2d32993f251c70b5", + "0xb7efcb232d3b639921ce21e80744c293ea77e25982b609e8cc82bd3999a734ca04ca43f41d9c7c15d162e0bbc3152495", + "0x96b1c82b85cdb8a7026fd3431bea9cd008f0261ee7f4179f4e69a399872837ab836a14e2dd45f5448d54800a4ae7c7f2", + "0x8295f613c162159f368340ca0fc2fd7776f7ad64eeafbd132bd3be1f1c30b5fbdc5f107f12fb0cff15b12c08621f457f", + "0x89e3ff351ce4f0d43cbb6385bac30b37431b31c7c073bacedbe0a60af3dd372aca672c6c4b4d05d2c4b7a040e80f3ef5", + "0xb075db32979df905cef986cfcd6db823ac21dd4013cecfe088885390ff8acd18d76dec793b80db5f7779426127daed7b", + "0xa18f4464cf5cebade8ee280fa00e0917cbf1743aeb0dacc748ab68773b909e30dc60f40fdef3041b5f082e650985f7a6", + "0x8fb51e3ef3c1047ae7c527dc24dc8824b2655faff2c4c78da1fcedde48b531d19abaf517363bf30605a87336b8642073", + "0x93e4d7740847caeeaca68e0b8f9a81b9475435108861506e3d3ccd3d716e05ced294ac30743eb9f45496acd6438b255d", + "0x946d585d7aa452d37a8c89d404757c3cce2adf2410e18613483c19199abd88f7a12e206f87a43f6009e42f4e31ed20c0", + "0xa4cfe97f6e61e45577ed6ce6eb7d1d9aca9e323b79b30736b407000555bf3e2ecbffd6314585b09000f09ee8381903af", + "0x87c5670e16a84e27529677881dbedc5c1d6ebb4e4ff58c13ece43d21d5b42dc89470f41059bfa6ebcf18167f97ddacaa", + "0xac7e49f2059e99ff65505742978f8d61a03f73f40141a2bd46fde5a2346f36ce5366e01ed7f0b7e807a5ce0730e9eaa9", + "0xb471c72bd2971353f4b44248b8e6cf5316812861a88ccfc20fd0d89a5e010428c387228b2f6f14c12f79e31afc9d0753", + "0x86b3a4ea9b1fde00cce79d5ae480353d60cb6ddce363c535bbbc3e41a4b8e39fcf2978eb430091ae1b10420d43193971", + "0x8167484b6a9bcbdef21464cee959a7a6aab5ac92ccc46214f4a2ed520cfb4d4de8917f9b9bd6fad71e66c17bd831eeeb", + "0x86ca8ed7c475d33455fae4242b05b1b3576e6ec05ac512ca7d3f9c8d44376e909c734c25cd0e33f0f6b4857d40452024", + "0xb49379bbb9f954d2ef5574199607bc6b3aa2cc3b48dcc3745cc77406bba2a394929844fec1b87c4ce65cd0ca0f83062d", + "0xab6366a7c6da8ca8ea43a3479e50ecf9a1f3b20ec01b8eae1d2a21ba2223a4ce62615836377c6395580a079c284947d3", + "0x9175ec473efbfaa029aadf1584f986371ecbeccd82ff6a52d1f6c66f51d7395e0ad67a5e8bef0600ffdb348978913e6e", + "0x8cfcdfa192b17321be4e447204e1a49ecaadca70a3b5dd96b0c70ab64d1a927d1f8c11a7e596367e5fa34e2307af86fc", + "0x905a97217fae8cfdc4a006b644e91b097df28e02da2f19f77e18f4b0c4aac2538ea83919a722eee5c0ff315a1daf3cc7", + "0x94b2d97448b452a986c039df1cfd651da59249b649182941556018af4ab61d2c6af82a29e69599153316f9b262efbcb5", + "0xb0eecd04c8d09fd364f9ca724036995c16ba6830d6c13a480b30eb2118c66c019cfdc9dacce6bfd8215abe025733e43d", + "0xb4d07d50fbc9634e5f4aeb884974068ea6b94e67e4527207f5f9c41a244943347d69d3c73af74d8de9ab3659d06c6d6a", + "0x8e54267871d8d3ce2a080e48786be3d97e5fc9404156436dc2a37bf05a588470b7656383bd79d58746d1667ceac54344", + "0x8277508c9aa4d1938c83b48d05fe3a440bfb50c5be79b30da1ac1853d19ee062797be19521f94b038cb991b1237abc59", + "0xb4aa92a60de61ad089cb027ef19a211c720ec0e51743b1166e3d71bac08a9ffff2f0687e250c6a7e1db866f7c4ae8f29", + "0xb9299f950db8cafd236a17f141cd2ea9ff441730749bab3571211d207ccafbf5a3990dc137400c405086c4d2879ab91f", + "0x8c38ab2a9558ac41c6ef736a5560e5960102e92f710efac3f631367a3f6d7227e0813579f349e661116bb29b2163b296", + "0xa5c11337eb91ce0e9b6d61bbdadea0a063beee1bc471cc02dc1d81c5dd2095315c400cbc6c33d23c77e98bba6bdf5439", + "0x8d3cba4d10f94bd3406a341c903ad144cfcfe6b61678d5c03084a56b4413bc30bd20d7a9fd5d839dbb565cc9b2aa99fe", + "0xac9f0b44105cf77ad721b97b0f04a37fddb2bb62c345b0d22a29e2870b8964d7484aad30e454c74608ce9901043501a5", + "0x8be4830a391aace561decdfea6aa610696d292a9e6b56448c6a590027df9f6762668671775272bac46ea335391ae157d", + "0x8e662149e22ce32383461ceb489b912f3c6320293d6edf61499164beaab7a265ffb9de3e0af6c95ca824d800718e1506", + "0x88b49b1130f9df26407ff3f6ac10539a6a67b6ddcc73eaf27fe2a18fb69aa2aff0581a5b0eef96b9ddd3cb761bdbbf51", + "0xa41cf5d678a007044005d62f5368b55958b733e3fdde302ba699842b1c4ecc000036eda22174a8e0c6d3e7ef93663659", + "0xa663c57b72e8acac40127fd3af579dcf9aba05910b26ed1155888543223d6558ee8e1c07f0a0e634e532ef6c5e9cf17c", + "0xaa103a329b699d4102f948101ce5fae27226419f75d866d235da8956f11367e71db5c0a179dd63007ed53f7eec333aaa", + "0x86c53fc078846c3d9bc47682506f8285ba4551475921fd388b96291741970c34b8de4210202e40d2de4acb6e2892072b", + "0xa7e0ddbae16e4491822684c0da3affecbbd17ef96c5c491ac093c6eb4e162fc7854c367535e296fd3d6265c2ed1210bb", + "0x88f0f11d0c2bf51453077cce0d3191931e73b104ee5c524da57e4eac0a88965f58b4abe423c1073f75fe3d3c666a209a", + "0xae8af784224b434b4dfa9ae94481da4c425602097936623e8abb875f25deb907aa7530bce357786a26ed64ef53d5e6b3", + "0x9408bfab1e7ac8b8b888c623bc0438b3a3460aff12436d13888315f496fdb808e9dc00894f272f348ed6aa475f848c49", + "0xabcf138d9363a73131f5bca56679d15606216bae1647c59c2857cb56818a0529c1b4b45e382273c993d62b7bcd552ded", + "0xab37a400dafa918d28ef43294b18dabcb4dd942261832f9839e59e53747c7b1bc44230967a9610b261f3abbd648e3dd8", + "0xa73b3c9d16f6c63659179b74b1aa5a0f4447c683ba38f9fc112efaccde4835e5b92c2f7041fa82cd90b2c4932704b9ac", + "0xa3fd9d8bbdc98394883022299fd9793e0c4f374d8e40d6ce89b2869d3173cb6a5476371d6095dad068ff217729f60af4", + "0xb4c5aa21659b3ae37fde62233b0bf41182fdd57c22fb5f47a236048e725a0e8636b9a595b13d9ecdf18c445f156ad7ee", + "0xb3a5497365bd40a81202b8a94a5e28a8a039cc2e639d73de289294cbda2c0e987c1f9468daba09ea4390f8e4e806f3c8", + "0x8cd49711b42af58a5aae75a38fea9ddc5e4183c467a3159b5b0629f01ba548513c577456d34c861911e85782e52c3b1b", + "0x868c13bb6bec7d56afd4e518f2f02b857a58d224fbe698be0e00bc178c1858e6bf5f0f7824fa013d5c8dd6f6e4147974", + "0x86f5a9bdeebd38fef93bf20a7451ef4c851d63f08e025a59109c68b46f4c61069a6c8c5fe90eb5af36943acc35e62f51", + "0x90c402a39cd1237c1c91ff04548d6af806663cbc57ff338ed309419c44121108d1fbe23f3166f61e4ab7502e728e31fd", + "0xa21477f0b51d73b0816b4b411c12db1e3a83698113ff9299ab2827e8da59baa85dbcc70afb831f5b0c038e0470562f00", + "0x82d09556978fa09b3d110e6066c20db31da2e18de90f973930f752970046f2df96b2a0248fdd833cbc50abad5c756026", + "0x92a346a321cfd73214be02f084ac2ff417900a1392d134b538099c92e7fdb7ba2174e9929c51b5e45bc3bcf718414dd2", + "0xac4b39bb8f0f62666a50574632764f8b6a1dc98afba5a5dad4409c920a0c0d5d2b5c2506c3a0d2f8727b7b7dce2ba1a8", + "0x8296f8caf58316af535def398a43357e48cb3b1e674b857eba1bd1b970da3dd045e22fe6d17dee4e9117f62ece3ec31c", + "0xa931bb29b6200899e8a8c257166400eff9888594daa1e37501390a1d219b019ed1b730d921a8f6d6fe62dff7b86ee387", + "0x8ae9585caa3c73e679fe9b00f2c691732f7b7ca096e22d88c475a89d4d55cb9fba3cd0fe0cedd64ce75c591211664955", + "0xb4a86fb5b0049718caead1bc036833a2caeb88e1afadbbbcb0cd021d95e1f33fcc916f0b97fc1b9226c37050e3463796", + "0xa15e0cb96a463ab81e661ca44c619b71a159680bbc04707ea5a5867ff38b15416e3abe55d2fabdab9aede1f157dd37e1", + "0x8b3f8fc8d2ec7a8db6ecadb8be90f55c1be4871bde10eb18c1773dc45dce042d93baa65b75c4688eb4125b6b7965c2d3", + "0xa4f964d672fa5579479e939d2d5dad6a5dac6fca4bcbf7d5ebbe7489f3809131667b41c3472addfe766d83202ea29c1a", + "0x86f0253db0918337e4e128e8056d2c793562c6b5cce8ba43695a02eae7df12605309722fd1e3b8c02ac513a4a49894a5", + "0x89cdbd610e7f57e86438e50874c3c7ba85afa63f5adcab9e454b5c203e4da65d74bb7cac5995a8652d10a6e438a1c2b8", + "0xaf2dc13a599c834b9af1b54a4fa675c0db92e807cab3bfc825f2c5571b3bc2e1c213cff941cc8b1080d894036f9f73f8", + "0xa0899189bba608887c6cb729580e570ecce9ca7107865ebd30def867afaaa250bac407c30dbee11b7ef6cd423269a8fd", + "0xa22542a4a2ebde18cc6aa29d5dace8b4f6720703f519610dcf01e671018392aff15728e3764730840272c9cfb074b612", + "0x88ce41025aa153a94f91f22e7b96f9342b5e0e1d76274fc70c4df7d08f66d9f7ac86e55a1c6e77693b8b01b2b38bf900", + "0xb76cb8cb446eb3cb4f682a5cd884f6c93086a8bf626c5b5c557a06499de9c13315618d48a0c5693512a3dc143a799c07", + "0xa7741c52498e0a24db3ce7699882de8f462a2b3ed5e9f77dc7200cbdf46b6cdd923b1128759909d6dddd64700c4c20c5", + "0xa211120e1bb3b10138df1fa58efb009a298b8771f884b82bb3de15822b1252124a68f3980f96122a775fb96f05ddc3d5", + "0x92ff79402d5005d463006e0a6991eaacc3136c4823487d912cc7eec1fe9f61caf24cd10022afdab5f6b4f85bfb3eee4f", + "0xa48b1031ca2f5a5acb4dbdd0e9a2b4e9add5ccfc0b17d94818273c8df11e825193fade364e0aec10f1ff91d57d03a52f", + "0xa0af9e02a7620e7ff119c3650d59d80169edd0ad452062b0e3e429c038cdaa4f55a18495e459367aaeb6a92c98003191", + "0xa61687511b627bde7b3977e9a34cb7fddc2aaa509a7b99b6b6c7b97133845c721e1e69f99758698d82cca265d8703610", + "0xb9691fb57be7aeb9d43995b8022051f199978d6ad635e1623a1bc1754b250fb8a94985cdc1e623e98767690a417e92a0", + "0xa6d6ef51a361df2e8f1d993980e4df93dbbb32248a8608e3e2b724093936f013edabb2e3374842b7cce9630e57c7e4dd", + "0x9820d98ef31bab813a0124ce48cacb9d99b2c1c625c41cb3d6e0b21f604ee215d5f37505c86766531dc302622d889766", + "0xa35ee5c2d7800489723c78008b495e1742f0542dbb487172ef438f60424c81aa41c2397095821248066140662133f6f4", + "0xae95ddcf3db88f6b107dcf5d8aa907b2035e0250f7d664027656146395a794349d08a6a306ce7317b728ca83f70f3eaf", + "0xa36dad4f7cba9f4cc843fe40f6240e1973a4c412cae29b4a68712598523cfaecb05272fc47d30772bf06906b5a26e282", + "0xaefc682f8784b18d36202a069269be7dba8ab67ae3543838e6d473fbc5713d103abcc8da1729a288503b786baac182d3", + "0xb551d1ce88cbf4ffbdcb0113a6e319513bd676d0078dd4e6a6f23ad336c1d0fb47a4e427bdedbe0fc8f152353971f81d", + "0xa11a7496c712734aec80738e30d2bf245758b34245076149854eb209fa6403be8bb0d4e515becc881b7f3610749260c0", + "0xb38e558a5e62ad196be361651264f5c28ced6ab7c2229d7e33fb04b7f4e441e9dcb82b463b118e73e05055dcc9ce64b6", + "0x9437ce85146202d3815df7f341a182678665dfb74b96006dc9d6acc16110d00b4a02717b702a765566457710ff5a7280", + "0x813bafdf6a64a9c40ef774e6c8cad52b19008f1207fc41bd10ad59c870fda8089299dd057fc6da34818e7a35b5a363e9", + "0xa5a1f7d42220d3740b3f353de74469fbd3a75ceccb3c84d0a87e43444855be0c51116a32a56cb1980294724d36bdda16", + "0xb4b80d7fbdb1dbf1567dfb30d8e814e63de670839a8f6ff434fe171416599fef831b8e978d6498851b8a81e0bc8dfb85", + "0x971882d02ad64729cc87251b49effc0b8db9880c25083bfa0ff34e7394e691288c7cefbb5cfdc76d6677ffb9da765dba", + "0x8144a5c583a61f809f6a9f5ba97dbed42f4086de71af955f5df5774f66a3581335926663502d7cc7b5129216da225f9c", + "0xb2eedff11e346518fa54e161be1d45db77136b724d497e337a55edfc896417de3a180bf90dd5f9d92c19db48e8574760", + "0xa6b434ac201b511dceeed63b731111d2b985934884f07d65c9d7642075b581604e8a66afc7164fbc0eb556282e8d83d2", + "0x85ab3c57517e3c348e7ec13a878b9303ff9aad78ec95b13242e087ec41f05f4a19366ae169fda8afec5300065db58f2f", + "0xa51f7858f1a7832b743a114127ebee1cffe176c988d4cb2348e45d4ebc52b43f80432c7276c6a5f8bfe39a432d4412ee", + "0x9332251b4b56579b201a2fd9e777e4be80aa213bc986ed5d1187cada9b225a7ed18f1f5bf68c2839bf330e00b2d63f22", + "0xb87e5f481b938ac8a481b775cc58be2a06604549e3c810fc4734bab76099e5c617f0243c4c140cb7dd6d36a6dc2286bf", + "0x83ca733849830cb8fc2ef469e7e464fd94def561ce49ff0aa352a6ecd0e52c7aefcd69ab59f3d1ed2d5b8536d0a7895d", + "0x8302ad0f2234535b55b975c5dd752c8a555d278b85b9e04e83b1db3bb2ae06f082f134d55216b5cacbf80444e1d0af84", + "0x8c627caf25eae6764501b9eff35aa90bd4f24952cad712aae20344579e83ecd104ad1f7915edc4f9023b17fddbdb4cd7", + "0x91066bac5341cead3d2cb168fde7da62b3dcf933ff5c1d379a4dd424b218c4e2ebcce038cc342e758795ecd4dbb8b790", + "0xa17e8874e2c59a2bdc31cc67095a271d31d5a4852ccf2a82eb7c457a3ba8c87ee5beb93a65a8f7bd04d10247e63d6b84", + "0xa15ebe9ab6de62a4d1ff30b7fc58acfb14ea54d7fa513cbcb045af3070db22bf9c1e987fa26c0c54356b9e38fa412626", + "0xa2ee6c29efa982e9b9abd3c5e4f14b99d5d0369d7bfc3c8edae1ab927398dc8a147a89e127b3324d7f4e3a7494c5d811", + "0x8cde690247d4831dfe312145ae879f4e53cb26641b3a3bb9eb4d590c56c11ece3cfe77180bd809468df5cddaea4f5ab1", + "0x8dc3c6478fe0150a2cc11b2bfb1b072620335516ad322dc5a644676a4a6aee71a8680eafb37db9065b5aa2f37696de07", + "0xa35fe9443b05f6632b080d0812e71142dba534b328f7d77e165aa89b370c158be708fed2ab8d8b3c60a3f83d6b1c4fd7", + "0x8266f9cc52944d85c50ba04d421c0ecb7ceac774f4485bca84115772ade238fdb5f5bf93f1f6c5288b3a44af177042e5", + "0x995194ca593943e772c58944789a30f8a91f20e58059967fa65364e4357b3483b0f94a3fe34e133bcf967859c5bd026d", + "0x83117ec2e506e292ff4759c270b3bca2ac221fc044ee7d3a4fcdd424ff0f4b961d6d268f7b9fce9ff07d29a4cb6ee3fd", + "0xb0a47515752c15e4dbeaf9ee27fab3b5c0db82f5c685e8f716fd7d8764164944340430fe3db1a5679e6ffea5a16dd919", + "0x91babaea18cf8f1e56feb0b89f0a3956c6469bb963d63312431057093b0ea0240a36abc3b7ac160e644e826cceb62530", + "0x9302bb41f741deaa5f2b6e3bca1427a6cf98b7ec2bf7967b7c0595efa258427323a022ef12f23426ff7a7c318462f07a", + "0x9022541f84e48b655e74bf3da484179e0e0040827fc71e777b68f19bcfd0e103d385ef957692e7091fe713561f38035c", + "0xa3b109249ac2900806f0f39338da72d4f2cc6d1ac403b59834b46da5705cf436af8499fa83717f954edb32312397c8d9", + "0xa94ccbf61b3a857744aa1540fc6d633afb8ab3c92d07fceef90a0dc54ecd2133490cbaac8832b26cf2f4b956471f36fe", + "0xaa744c552b5fc41e1ac6ca53184df87a1b7e54d73500751a6903674041f5f36af25711e7bc8a6fbba975dc247ddad52d", + "0xb544c692b046aad8b6f5c2e3493bc8f638659795f06327fff1e9f4ffc8e9f7abdbf4b7f6fcdfb8fe19654d8fa7d68170", + "0x94179fcc1fa644ff8a9776a4c03ac8bff759f1a810ca746a9be2b345546e01ddb58d871ddac4e6110b948173522eef06", + "0xa3a7196fecd25e9cc7cac79c35365676e48c7be1493df255676adff2209c0719f2190ceff3ce008d08efa07c244c11a6", + "0xb746447b0c0d7165f965672d71c318f2c1052a5ac6ebe320b14165c9276c839ed822a9183ea6e6dae63a4f826d421d65", + "0xa66d5b1cf24a38a598a45d16818d04e1c1331f8535591e7b9d3d13e390bfb466a0180098b4656131e087b72bf10be172", + "0xac1af27a7c67b1c6c082f0fe733046f8b155a7d66caa8ccc40a53ac5a55a4903d598b5f80543ea52c25205b02959f4f5", + "0xa485a082dee2987e528d1897dfc5ee99c8de9cdc0c955fc38c404c16c35b71bccd08770c93102110547381a2eb9d3782", + "0x900b9972180a2c8753f5ff49fdd2cfe18c700d9927b3c3e16deb6376ad6ee665c698be72d4837b94911a0b4c183cb140", + "0xb8454e8438641340b7fc8ac55b869abe54806f873ec0f2d8fc5425a1ba76ed8471425440621763b6e9d834b6e5451b98", + "0xb3ed0906d97f72f0fd5fe01cbd06b77d61c69f059f1e87a143a5630073ab69ef8876bc2a5e261d467a7f00f0050388d5", + "0x90a908b47d0c29a2d0e7e65a212d7e1788454062f46458c519c7f2ccd794ff21d4c24b91acf42a71a509aff6544f676a", + "0xb07d7c3f1d486f5657d5935e3d67403024ffdcf25da5c460fdadc980d8d6b931de623c4f8a3da5eb6af346193eb36573", + "0x87c2989f377be3751da3bc19172c5987d21c095cc3d851ee5120f67a5b3986d387b058688d54336d8510c49c6a66d754", + "0x8e70e4867d2731901d603928d72bbeb34b2e0339a4f5cf06e7a771640717421b4ea039c61dde951582a28c2ff152ff70", + "0x8336744d8ef3a3bb3e9ed3d6b83e08cafffc76b7438adedd3a7358b32acec0e73a4635aa3166362ab4e158e68576255d", + "0xa70132fe0c9580ecce2e3c0d4a531cabe48bbf6e7d1c1daf9ed2f315e81705bf1616b4cfda1c903b074e239ac6ab4c47", + "0xa978fb8ce8253f58e1a87da354f06af989b0bafaafec2fb3100bee272dd8664d2690f8ada7dd4817bc8b06ffb1fe23f9", + "0x94274299f0faca1152cca89282c10d00b5d3679cd4b7b02e018f653257b778262fb3c6c49d0eb83ce388869c283c3c05", + "0xb8233d647876eafe2746c10c1b41d99beea28b2627ea2ecb67a3eb0d166fadbceee34dfe942aa4ecf39e0d55f9d6d2a6", + "0x980a54f9e9d88a7ec08d04edbdd7c9222e99f270b1e978ce7140cc67e38a2e60cc1034dc5b0deb5b60e10697d3bc7295", + "0x8553bfd1a163df0d8bb1424383552b85a1c0d288dc1f46fdde90ce2d9be7e2688d7d06e1d6be06252c7099588d3488e5", + "0x8e8e48992d0394fcb9a0c56bbd3797400128e28fe395ad9acf582919d66d11a4811a7187897e60ee2ab4842800c8c36c", + "0x8853eff72fa4c7b4eda77e448e12bc8ee75f5cb0f35b721c7ee8184cf030a11e3e0278a4e76b326416fd645a9645d901", + "0x88e1e459ee5aeb8b36ed004f6d03da296101106fbe1b18f9bbf63e92321db51670c34050fd3b7dc56a4bad76403823ee", + "0x890def696fc04bbb9e9ed87a2a4965b896a9ae127bc0e1cc515549b88ddbcbc02647e983561cab691f7d25cf7c7eb254", + "0x95915d8ff2df795e7baac5433887c39ec6bbb9281c5d3406a4a1a2008f96c6f266adad4824c6c46429a158e36f5e1210", + "0xaf917d086e2e327d8d9e37ff85702536d7b15f444310d4aa832a61d850c7c3f09d31b3f5fd2a073e7fd64601275b6fca", + "0xa448516054e31866b54f1951b9a03f0a54fb13d938b105e3f67396ed3fbb015f290a37fa538baeb077fb4f9ac86c8305", + "0x8e58219fde5e9525e525b16b5332ef27fb6269e08e8c0bd3c20abb89397864b2c5bb55f5b6e03e8f0a0e0b04e5f72b14", + "0xa798a0371e8cc4dc42ccd79934b0db5a3a59f18a0ae09f2eb172596428fcb3f00312e783d6fd21cbc1610317f44e08cb", + "0xa8cbb85e8f38734d95b9d69346cbcb169c149b9801d9da46df5e27b5ff8d0ab7b870c83db3fac32a90d02efe5fb8fb49", + "0xa63868892ce200c7d82d7ae041db371c91ce03282adf796c8b1a1652732ec77add0945727b110339a80596c367c97deb", + "0xa0133deca5ae8f1100df8db69920b2d0c31aa21bd3849dbaf4c264eaeaec8937ab8f982770ce1ea17e0e258910a56d02", + "0xab88f81dc77f09a2b62078e7baf4b6c7503925a7a077bb30d72f4baeff8225039c5333242e325e824f7192d4d132b596", + "0xad83b3c5e9a08161950b1df9261d332dda2602cc68e0f5ee75bfa7e03bbef9edfb4945ca1f139df1bcb8affe8ae025da", + "0xa52c5a63b55a8001b6b67c5db4fd5e95923052f03618369312896ed9892d99354aebc0dee8c3b365bafa29e211a5c3f9", + "0x973dcf44ab60f55f5d10a8753ea16db9faedd839466a130729538f3a0724f00f74b3ca1de16987d7c6e24e9467f62bc7", + "0x991a7c93f06d50ec6a4340c6751b73eb5825bad02a954e44e1e2d424af928819ebbb590c6129ce35b3f1e908e2152f33", + "0xaa48afa77d5a81cd967b285c0035e941ca6d783493e1840d7cbc0f2829a114ace9146a8fbe31ecbd8e63e9b3c216a8c5", + "0x8c01b901e1067a89471927d911246a8b2f1284e93be9913406d7c88aba784694317e22a0a7635583dae7db45cafb73ed", + "0x942772b7c7c47d4e5957ccf1d6f1450070930af3e2b7eaab0dd7699372445df0cc910e6c0efcf501887dd1adabdaee23", + "0xafc555559b435c585b61096a34a15b8ad8722b2d3306ac8cbf158b46c135b293b08a5f37b109b138350dbcd1e0da9f8e", + "0xadc806dfa5fbf8ce659aab56fe6cfe0b9162ddd5874b6dcf6d658bd2a626379baeb7df80d765846fa16ad6aad0320540", + "0x80bdb82b7d583bf1e41653966b0ba3b4fec0e7df2ff08e3fa06fd9064bca0364263e075e1582741a5243bde786c9c32e", + "0x8d5776148c65e35d717da1902d74727b3bee21ceba8d337d77738932865f1b851e810b91346f705880da6cac63183717", + "0xb9d24940937b6e50a1797cad9ca58d4b2b2d8987bb8ec056ca2f397a2bdbb7af7939c0f4bcdf5a3b6fc80f65f9d535ce", + "0x81d6fc2f01633e8eab3ba4d72588e14f45b00e68ab887bdd4ec5e8558965db21189310df973837106216777b07fc0805", + "0xaf03bc1e94067741bca4978b9cf065cc6852090fde3aaf822bbe0744705ebda5baac6ed20b31144db0391309e474ba48", + "0x8cf8412bd48b21b008f0207b1f430ed96bc6512c3712dffbbecb66e493e33698c051b27a2998c5bddd89d6c373d02d06", + "0xb9c8a3894365780842a2096da49e48f7e77f05972e2acdeae8e8fed8ddc52a1e2fd754547087bc9292cf0c868155fbcd", + "0x85c8e7e1d7ee3ed366b530c5c9fe0a353f2907d8b80b16d00391780c04e3f7e060d433539780457732864e334039474f", + "0x8a3987de0131b7461bbbe54e59f6cefe8b3f5051ed3f35e4ad06e681c47beee6614b4e1fba2baa84dff8c94080dddda0", + "0x852ab89dc28bc26f6300800d9a3046bccfb3fe1491f29030f1389f40ca452f6b8a2f6d1541c1e523f1b59f8730823488", + "0xb5726aee939d8aee0d50bf15565f99e6d0c4df7388073b4534f581f572ad55893c5566eab1a7e22db8feeb8a90175b7d", + "0xa356e5b70bc478c625e32a38d29f0a619fdeb665503eedc304d1bf34562d4b6814dfc30aee5aee94ca4bc6394e412765", + "0x8b476b3b065a3b95a3d11ec60a749c2258ddcc5885bfb50b8a086d3fd1e49ff73e1dde733b8981c3d2d206aa0c87b09b", + "0x9171a7b23f3dbb32ab35712912ebf432bcc7d320c1e278d652200b5d49ad13a49ec8e56a0c85a90888be44de11fc11b5", + "0xaeddb53c6daac757916039e0992ec5305814e9deb113773f5ecf10355cc3723848fd9c55e0a6ffb6bcff4ad65ed5eb3c", + "0xb576c49c2a7b7c3445bbf9ba8eac10e685cc3760d6819de43b7d1e20769772bcab9f557df96f28fd24409ac8c84d05c4", + "0x8a277710379ba4fababb423026d9db3d8dcd484b2ee812439eb91b4b5177d03433b7a4486e43efbf2d2ce8ccfeabf323", + "0x80e30cabe1b6b4c3454bc8632b9ba068a0bcfd20ce5b6d44c8b1e2e39cbe84792fd96c51cf45cf9855c847dc92ce9437", + "0x804c021152c3304853941847e80480fdaceba3b9676fbe018268cf77d1a1856966c2f9686bb4d4aa0c4118a7e85f83cc", + "0x901f724ee1891ca876e5551bd8f4ad4da422576c618465f63d65700c2dd7953496d83abe148c6a4875a46a5a36c218cf", + "0x90fb5cac22a22fb8a6b619f1eacd95873be974d4d5d1f7080e523bb9b4b2644eda7340d780bd1ea8ce36407ca0410fea", + "0xa34eba9a41f2307891af1825ed501b74278f67eaef4bc57cae5c0c46202c19fa0d9a5dd8b91325f6c151a0644762ef29", + "0xa5c225b7bd946deb3e6df3197ce80d7448785a939e586413208227d5b8b4711dfd6518f091152d2da53bd4b905896f48", + "0x84888f2efd897a2aca04e34505774f6f4d62a02a5ae93f71405f2d3b326366b4038854458fd6553d12da6d4891788e59", + "0xb897fa90529458bdf3cede5ced3f3823dfb9b6d93b96b81429bf05e8f1a80f7c857d458045cfee58296b3ccbc4119abb", + "0x8117fbcf61d946bee1ce3dff9e568b83716907acfde9b352c3521cfed44158874af8dd5b3906b4a6b49da2fb212ef802", + "0xb6e9fe9fa3d4c833c3beae7f798f30f07e3cdf6f6c8eb8e2b70cad51b37af2549dc9f2e7f97f194e5897d4dedb904a45", + "0xa7555d66719916a2be7a7f0c8b7001aa2925bcb79723f78288f10831f9cec64923228b0e4b89dfd4342de8f70ce03cb4", + "0xa10788831a0cb2c3d14d8bc214d92bee6e2a9e92c423d2974760d84a6872a9465d12b628f9bd8a6e777a7db6f509b3a0", + "0x946948e31311703f64d34dc6faaae992e39b7ced92ecdc01df9761e3819a6db1266be718fdf434fbec912da37d1986f1", + "0x8675d210e67eddb3cefeed200b9e205679d36d8dcad70f09e678d8d1b3eb1059d12542f3aca300f384504458a881dd60", + "0xaaa18df4ad95f7443955accf8ec206f46d4d8ad9f1adb07b143b4225590917ed7ae050fc329d54310d3d0b198cedaf0b", + "0xad77fcac9753efba7a9d9ef8ff4ec9889aa4b9e43ba185e5df6bf6574a5cf9b9ad3f0f3ef2bcbea660c7eef869ce76c8", + "0xb201b0546f19c5db88df9c684cf55ed623bdb43927d06051bd595497df741feb1485961f64e8d3d1811d9e2e9e1e54ad", + "0x836075979eaf386ff6cb459cfd48fed171ae812b0ac3b38dc24dd8ca905cac1c600be717d4a0defa0a854f40cfaf8c33", + "0xa0617db822d559764a23c4361e849534d4b411e2cf9e1c4132c1104085175aa5f2ce475a6d1d5cb178056945ca782182", + "0x9831b8c836114f6d8213170dde1e7f48d5113974878ae831fc9b4da03f5ed3636342008228b380fd50d4affe909eb54a", + "0x97b43a6d1a47a1c415278344dba0cdfa952663a71fdcaf58d313c161e479ab5d1b980d8870055cc8f0d283bec8f97425", + "0x9340bfc34ffab8c28b1870a4125c559978ac2b278f76f462b5c859a00c3ba3426b176dc2c689096ad575b4cd4dbb76ae", + "0x88ad79a0320a896415e15b827a89969b4590d4dfa269b662bdc8f4633618f67b249f7e35a35884b131772d08025bfc32", + "0xa0230bdf83cd469c7248074bec535eba8280cfde587d7c63d307149e9626bc7642b4bacc9beff2d8e8f6ea398dc0ade7", + "0x8934e9a3feababa12ed142daa30e91bd6d28b432d182ac625501fe1dc82f973c67f0fe82d39c9b1da3613bb8bfe2f77b", + "0x87fd7e26a0749350ebdcd7c5d30e4b969a76bda530c831262fc98b36be932a4d025310f695d5b210ead89ee70eb7e53b", + "0x83a9cd621beecac8baebf7df4f7ee17bf4b70aac31df816ec3efb5cfef2dc5c0bf959c5227df3a7ef4c2b8d1e1b658a8", + "0x9529ea4a51324ed4ecd855faea43846a223da8cbb494e5854cef700ebbcf4d76119cef16192e6b7c51f82ab79371756e", + "0xb15e1b4ac64bafbc4fdfead9aeff126bf102fdd125c1c914f7979680ec1715fbeccf3dc35c77d284421ec1371ed8bc32", + "0x8f1d90034f998018c3f4b5947b40b139fcead2e40aa80fdec6a4337c60e9d5ff1923dda7f0b5b1731ff16f55027d41bf", + "0x86b706c5d3c5aca72cb23ddfb6452bc70dd3b1a98c8539a7c32f760778b401cbe90ef86c12d0468892dbcbd9a268a38b", + "0x9752561179783f336937757b619b2fdcb9dfce05aa3c4fce6d582dc966182eb85ab4ccb63e7e1736a7c5fad9d33cccd2", + "0x8bb51b380a8a52d61a94e7b382ff6ce601260fa9b8c5d616764a3df719b382ec43aec9266444a16951e102d8b1fb2f38", + "0x8097b13908662d245820f3b045d8c2c665fe9a054e9c661323924ec86dfa713b36b0c787ad4dfdeb979318810e687a48", + "0xa09b2a07d861e01645accfb088f7f9ad524186bd439712775459a60f8a1fbbd43ee084e4d6e23ffce06daa189cd1e654", + "0x941e2e3ba414a371a11c3fe92cabf688ff363da6230ec7c83ac7303f652a19ebc89cc494427c456d0c2ae84c72053f73", + "0x820cc2ac3eed5bce7dc72df2aa3214e71690b91445d8bb1634c0488a671e3669028efbe1eae52f7132bde29b16a020b7", + "0xb5222582ed6604b9856a48039bd643340f4bf1bf0fc805e8453a9eb7630d6cea1452d28536706d6fa3ec16617617991c", + "0x938bbaa0ba14597067ff4c0a7cfc1529c44160d6f61cfad12246526d84fb7a1ba964d3bbb065a348cf7a98356ee15234", + "0xa83371f44e007c708dc4bcafa7bd3581f9080a4583c9be88624265014fd92f060127e628de5af3c442a25f049c7e7766", + "0x8c17ccc763fcdf2ba7e27ea643654e52f62a6e3943ba25f66e1003fd52f728e38bfd1036c0d50eb3e3e878378bcc2e9d", + "0x9517cd84390fbbfb7862ca3e0171750b4c75a15ceb6030673e76b6fc1ce61ac264f6dd1758d817662abfc50095550bd3", + "0x936f7e20c96b97548fef667aa9fa9e6cfdc578f392774586abe124e7afc36be3a484735e88cc0d6de6d69cf4548b1227", + "0x908d762396519ce3c409551b3b5915033cdfe521a586d5c17f49c1d2faa6cb59fa51e1fb74f200487bea87a1d6f37477", + "0x8ec38c68afdfb6ba019204039c2fb49a35467058f561f626fa87314d705fd615a7b9966576052be1b3690028d3c5c7bc", + "0xb790669f1acb10911e520198795b259a18471cb3ac03f3885b4fa40626d414e26025790296fd078ef5c3681ebe4689cf", + "0xb659c05488f778fca3c918505d2d849c667471af03369ad9fa29e37bac4cc9caa18e749c62fcff22856945a74ef51356", + "0x97ffcbf88b668cde86b2839c7f14d19cb7f634a4cf05d977e65f3cd0e8051b2670e521ae74edc572d88201cff225e38a", + "0x9888c250b4b60306f4ecb1babbf95d0b6dbf6186503b2024b134478d721fb782d801bafd126cc3247bcdb1ee9d66de85", + "0x941f73b2138b4347ecafcc7b8c3d03f2a54dc49f580394ed08f22b0878ee7cb63d42978f1d320c09e7dbc67648c06f8c", + "0xac3195143035cdb4ddcd5f93c150035d327addee5503ea2087b1a10b2f73b02453ddd1a94d8e7d883e365f9f0e3c38c9", + "0xab6b47627cf76d9552c723818db5ebee7734542436b50ffe15b3a96e8e7a6b54f9a0965de78405e16e309193f147108d", + "0xb7c66da483b18f08344fc3c27bdf4914dabbcefd7ee7672fab651d05127d85d25ce363b0c338d6eed55c4e31f57bcb35", + "0xa641eaa149c366de228a2833907ad60eea423dd3edf47e76042fdf6f5dc47a5b5fc1f1b92c8b96c70e6d8a68d3b8896c", + "0x805c06e565ee67cab0cbccb92b6656fdb240b430766eade3c6b0a0b1b93c840e2b4f028601451dca135c783239463880", + "0x8528cf6ed82d9f729f9aee83c3ef763d85649d46019c4ca7dfb58d7824c2003f88ddb2bc5a40c4d78d86e68b675f4e56", + "0xac2955c1d48354e1f95f1b36e085b9ea9829e8de4f2a3e2418a403cb1286e2599ba00a6b82609dd489eda370218dcf4c", + "0xb043156fcd02b75dbe940c763fa8e8a7c7f6d74c1d5395db5ce544af3b6097eab61686950535a810aa95889ced12f74d", + "0x8e7d1dc7beb2de660b7da19ebf4cfef3ebb6a3d6f2f367e2dc91105653226e859137879171dccc586c10d9c4cccee7b6", + "0xa278bea51af1de8bbd2319f3a37ab14abc3bc0289ed31aae44f38897a7b24263a4dde1cb037e1441217bec0ddcf47266", + "0x8afa23226c47083bba80ab1be55b48c90c6629135533e3e4c14057d19febeba7f8e2cabe617b28ce1f0bd97a06972f66", + "0x9865218b0eb281e547e693055456d1d0c598bfcd0138dddb5edd5f5ff66cc2d52465f3e70c0f321246036d7ed8c606d1", + "0xa3a6d1ee35cc0ed9290a135086b32f136028b320650e1f3443434af7ff52dd74c546ffe2a1bebfc329f1b52cd72aca34", + "0x812d3ded3a3c9e58eecf13a29bb4cc13b01b2a0af322423a29bb0e4f6d9021d1d87ac4af7a2a6b88d34f44a8bc1b3c55", + "0x8d7dc174aa361d046cf183dd202cbc12fed780d7053f7047e11af9aded336318bf9928aab73ebfc81ca86f12007077b6", + "0xa9fdc2209bbf48970a404de3d803c65b11be96ab5a165183d05ed6477b3a0c633c3d6f0cb8eefb430fddb5b5be8cf887", + "0x83a798f47a4f62dcb8b531d463b0fd4a876d47a8ca990710290549255033c909de709471b4e823a60bf94d8baf8b5acf", + "0xa8b0bb9e1f8b0508c7d6e7382676663d27fb27e3f1c0e991a295e59498f4a5dbcc4cf89c73d3d587fb3b8f5838153885", + "0x80414adc7e0a9cb961b1f31682c33d8e01e3b8cf2aa2c2a911ab9b1f54d5c4bf92e18466cacf9b80333112ab015136d2", + "0x82d2b1053f6610064f838b3aeec585878f86323cac357c4aed054d87595c7734729a737b29b57940884ee839e984d612", + "0x91efdbcaad9931312d7c41d24de977f94d7f3f7b88090a1f72d9a097a1e30cc805c5ea16180f463022d9b26b8863f958", + "0x90ab68c372fd01bb210fb94094adb27296b7144d964bb1dd807ea8f718181747356b0f9db3feda78dd7a596209099ab8", + "0xb40a3bae2b08c13db00f993db49e2042be99cde3d6f4f03d9991e42297933d6049394c659e31f316fcb081b60461dabf", + "0x94402d05dbe02a7505da715c5b26438880d086e3130dce7d6c59a9cca1943fe88c44771619303ec71736774b3cc5b1f6", + "0x8adb748d5fa5c22ce4c76a1debf394b00d58add9f4e08524cf9c503f95981b36b8d0cb2dfaef0d59d07768e555733ecc", + "0xa129c9cf33df42b5a98ad98be9d940207ae154c715d3bde701b7160dfe45304679fb0481a4f9dde242c22a9849fc2d9c", + "0xb3180ded54610b1b3a2db7db539197ced6a75e9bb381d1f4b802ca7cd450f5418522ad2bee3df1956ed63ff1ffe95dc1", + "0x80e1dbf3296bdfa98aeec1a7560682165d13bc628061bd3257f345aa1ba13f8bd1bea14f117af562be22118f5a8265af", + "0x8d286e63f64a3e24c2e4c2b91bafb7c6a71d9438a2ffd7288c58ec6de9db6194eaf671b39c5a462c8658ad3cfce46f85", + "0xb4f4ed1bd274a852189719a8808a8f214c8386e844ca9ba13161b75d04c74633b1d8a758ce0b23ccbce8052494c81c3f", + "0xb1a3e6baed1cc37b9a67f38648f4fe365d23fb982027ab4202c3392d5459d7995264c2e9bb8e821a3e75e71390b6dc7c", + "0xabd7248ae069d3a3a45b0ef4dd5d7d54b62994e578ea20bdd3b7876596673953b94c5b109a6e4b953b517544b915368f", + "0x9377aab082c8ae33b26519d6a8c3f586c7c7fccc96ec29a6f698b67d72d9266ad07378ba90d18e8c86a2ec77ecc7f137", + "0x959675679fb41dd62595d8266e796834c1207dd70750e304b1ce45d3fc215ceb5214d6651fc97a061b6a570eba35b811", + "0xace7fda25c2fb7c18710603c16a0ff0f963352d1582a42a20c9f5603c66f485df8383465c35c31e8379b4cb2ec15b4c4", + "0xaaf15335f1fa2a187f24f3db7966fcda52c2859113ed8f460167538f5cde43429750349f9714edda0adb6705d401d27c", + "0xab99038a2a6f9228d5d7e67f47107abaf06af293586c3a6ab1adaf02aae373e3434ae3e26bb617302b8e3a7ce5107bd0", + "0xb3119de346a02c87743faa4a20fb90e7eac404a6f81ac681d593171cb29c5f79d4d5ab761b66ec71d4a86f43e0b4165c", + "0x89255902846cb35c706f6e8869a9122527afcf8a8b8f5f81497b5b71c6a96c601e7185acc78646e2a7884d148eeea815", + "0x8c26d4ec9fc8728b3f0340a457c5c05b14cc4345e6c0b9b9402f73e882812999e2b29b4bffdcb7fe645171071e2add88", + "0x903b9bf66c147ddfddacce63c8f12f62e45638383bf91b50e2fef29013ce54a3fd8c3eccc9b8961d91ca2920ba5b0c1e", + "0xb7a2c83971c4e4132f3fcaf3c4374872de67ea5d89814492309cf924520a23787401f9621681fcf526154e80849a7e72", + "0xb74f6e53b56856f88f8607b1c4e6c9e54aec15c5bb891e7bab00e2a13caab3b1d6529bf0d72d4ce99714b8cb8b973f1a", + "0xab8a8769c754008a7976b6799e81d7bfe97413d0a79b90715703c1f8f567675463ec93aabee59277121fc4df88b5c7a9", + "0xb34d4d2e15079e7e80fdba30cddf4fc0e6c9a61f7ab06a6ea0a4e55fd5bf632c6d72e021d6264d935439d321de883bb6", + "0x927c030d5a69f0908c08f95715f7a8d1e33bed5e95fc4cfb17f7743cb0262755b1e6b56d409adcfb7351b2706c964d3b", + "0x95718b06017ba9d45894867fd67148645d25d9db2229aa89971f444641ba9db4c5c6f0785f3b25cf2cd7fadaa6adc5eb", + "0xb30faf88fe203495aa268503bc82576f76a27f8bc8c4125b4c6f6e5e7b6880d495481cc9454713e0833317fa07da9b5f", + "0xa9ee291de5997232c68c9f6c3b568b05f46bfedfa18eb3776699d98cc7c6320003b7d862564d07fd28fc3691d1d28b21", + "0x8e54c7270d2c7041796f202e929ae921fd0fcdc8ef1e6eae7e67d461114fd45ecc7fb78247c072222e48d1292a12acf9", + "0xb7f146a357e02a63cd79ca47bf93998b193ce1174446953f12fa751f85dc2a54c9ed00c01a9308509152b3bad21d7230", + "0x8aadfcf3562f1c357068323352cb1745349a27a7362358d869e617c2410db747149b993ee9e881e252ecdd42fd75f351", + "0x8068da6d588f7633334da98340cb5316f61fcab31ddfca2ab0d085d02819b8e0131eb7cdef8507262ad891036280702c", + "0x89ab1e5c2565f154f92c9b3554160832d176613f1a2f872b6ed62ed925a33fb0b40b71b7443eaaa15099ab24693c8d13", + "0x8e9bccb749e66fbe47296f5dec33bd86e52987516263240f35ce9a212dbcf71348b60a016f830f2acd05482962403542", + "0x8fb74891a8642f25a55b5eda5818367aac2fdf9663ad1e3dbc0166b484c0cda581b243cc75131167f1afa9caaf6705a0", + "0x8027bc62b59f9f15613e38da74ccc71fc3eaee26f096d187c613068195ce6eb64176013f2d86b00c4b0b6a7c11b9a9e5", + "0x8658a15df961c25648fd444bdf48a8f7bb382d9212c0c65d56bf9cdb61aab3bd86604c687fb682260dbc0ad2dc84bf01", + "0xaf76d2de3664f45ed4024f1b944cd316cf758393232bb07bc695e5eaa7f04e7e09007f29e83f62ef6fa25d1000113ca9", + "0xa3c4269e6fdb75882f0bb83529388fb8e08d025d00d869a2ceefdbd38a060e59535bca43012815444cb84021787f6c7c", + "0x8784a8fa62e0ce23283386175007bb781a8ec91b06fd94f22a20cd869929de37259847a94a0f22078ab14bb74709fac6", + "0xa99cde5c7c85ae291c74c893e598cc0e6eb2dda2a81dbb504a638eb21dd2c41d6e5caf7baa29e3c1c32e94dca0d791f1", + "0x802f512bd4a97487491c0e07ab8a94d5580c72212032e34c42b7039b860a7cf8f1e2e24b7185b80d3ee00a9cd4c92903", + "0xb12fd5f747c5223c5150dca2728bb3a363c5bdade5a9d1415642b2201c51aa6bba20a988c51bb6452fee7e05a8586b42", + "0x99caf2cbdd4427666fcfb506bb6956772e058150b0638eacd5db2e8869c8565c1ff2c63f308bc3143874e0f31446292e", + "0xa9d47cb4c69fde551b2648a2444091502a56a778212ab544ac75cc1bd14d0f043f4e31de47fce9a890ef5428cc28dd41", + "0x94240350a53e7715c178382b174c4f918d35cde875faeda528c2f32073085c6032b47fcf00240dc264621041c105e0e8", + "0xa413befdecf9441fa6e6dd318af49173f19e8b95b8d928ebe1cc46cacc78b1377afa8867083be473457cd31dfff88221", + "0xb7c4e55e2b48ba55a71f72387475886e5b4715100e93cd2ae09582fd37e5646b54bd93fba311b65c842bd0aae1424bc7", + "0xb7ea5e0d3cfcf0570204b0371d69df1ab8f1fdc4e58688ecd2b884399644f7d318d660c23bd4d6d60d44a43aa9cf656d", + "0xa7c2174eea2b66b2a71cc8095fae39c423a353c7d5020ec2d0551317a66202fcf082c6119ba768755523fff49791bb4e", + "0x991e0fc7fddd0e316cf4bfe20478f10c15b8bbb618e6be52a5095e457ca52db8adc008f47d4624b6cf4f7d6c2b94a29e", + "0xa7d76c88daa3ba893d4bd023e039e1f587565d317609cc9ddce73f2d3c4d6d9facee20fca31c85322f10fdf15267fbec", + "0xb880555398668dc7d064a18ba82d574999a93a6843423703aa8e543fc196607239de7a4258710b85563f2889eacdd0fb", + "0x903f569a8de771406b9fd36384f1fea20d5d79374b8d9af24b4814f96c44739193662aa47be857543fa101aa70ab205d", + "0xb9ee3b7b95db0122edd90b641de3c07fbf63a4f70fee5f72051cbe25c92d88444314d0489a5ecdb1805f4f149f462ee6", + "0x8ee41011424da5e2ecea941cbf069ea32420749f2519434d3d8f9725ac789753404687a6745cffe4bd5dfc8fec71a719", + "0x8a978ee4be90254fd7003ee1e76e5257462cbb14a64dbca0b32cea078908d7da47588a40ffeb42af11a83a304608c0f7", + "0xab73a043ccdfe63437a339e6ee96ef1241264e04dd4d917f6d6bc99396006de54e1e156d38596ba3d15cb1aaa329f8f5", + "0x9439b663e4104d64433be7d49d0beaae263f20cfac0b5af402a59412056094bd71f0450bc52a294fc759ca8a3fddfee9", + "0xa53d2a4bef5f3d412fed35ac375f632eb72a6650efe811e2131a6ddcb530f88044f65b80b7d739998115b9f961bbe391", + "0x88e7a12a90428bb45bcf4b01442c11607433211fc2f9bee9545304eb66e0b4b5339360160bc782e185391385da7c5ad7", + "0xa163470735c16f800bed412bf0190d7c85cb2d3d588ffce245ec8e8d4872c756a109367e293caf4f5c0ca1ad31f8be5d", + "0x897d7a19b70dcef1af006df3365981d73068c81f18017f32fb9966599481496efd5f6caceef943b31c52750c46d9590d", + "0x90f4476224b64c2a5333198a4300ece8b3a59ae315469b23fd98dadcdceaaf38642d2076e9cd0bfacc515306f807819f", + "0xa8d152e5d94b75cb9e249230db21af31de4d4f3d4ef60ccbf2212babf69aed2a38435a993ee2f13cca410ad55a4875ab", + "0x95aafa379cc6a2b4bdd0cad30b7f0a47839952af41f584219ec201c6c4d54610eb2c04b67b29080acb8cecc5e7543fbc", + "0xa8795e7f4c4c5d025ead0077c3aa374daaf9858f1025c0d3024d72f5d6c03355ae6ac7418bf0757fe49c220acff89f7f", + "0x85e2013728a13c41601d4f984f0420a124db40154a98bbe8fddc99e87188b4a1272d20360406a9dbae9e49bfe3f1c11c", + "0xb380ee52038a0b622cd7eccf4bd52966573fadde4fe8f70f43fa9c43a5a99b3eaf58335a1948b561f5b368ab4e0710f6", + "0xb43fdb2ba9128fd24721209e958be7b9c84dca08387c982723f93ed4a272f933823ae084f1b1399ff6271e0da6f5aa3f", + "0xab2053c376c6bd113b89fdb2ae3b8401aa891135345885730c61cac7813f69ea7d906c531be752e28657f73af92d1f4e", + "0xb586e67ae1826a1cdd651ac785e4b38f8a0e042f103a9b7dbb0035626d5dec3ded04a4e2cc09e63b4b01aebe304e40d7", + "0xa86be58fef115445b909dffac6f51da3fe9214afd9c31fd564bb8f39b1dc3cb895b1222f2c63226b54b60b278ec45edb", + "0x8016d3229030424cfeff6c5b813970ea193f8d012cfa767270ca9057d58eddc556e96c14544bf4c038dbed5f24aa8da0", + "0xa8b593de2c6c90392325b2d7a6cb3f54ec441b33ed584076cc9da4ec6012e3aaf02cec64cc1fd222df32bf1c452cc024", + "0x860d581af35d522b5eb5fddd92a98a6b4cc483fda00820d1ce4530e07892890c096e99b33976ca3550bb900e830ad3b6", + "0x82212706111fb1cf5def02b5b0eb7ae9e6ea42b4c7a2b9fcacb7aec928326edb9ac940850dd933f2822f6cf519de0d50", + "0xa98f68569ced00cf2c9f85fe0b4bcaabed0652b9fbe438bb5a86612a0addb5975e3b98395f2a4788639c602cf21a8494", + "0x8600e2031c9113ad2a75c19872b5efef85765b524f74de98baf4efe4a75c6be563e9e19622388fbe9afe58aa6017b930", + "0x8e825c03c8409a3302266dc5f47fbfc381dfbafbadc37bd8d40f079ca8963d4c5ae6ef0d0ba6aef2d4688736f5f6bb45", + "0x8bff10f91b8c0abb6c9542588da17fa0118ffda4c82626a754887e333d7d69661b3ae4e400da15c49565f8d10a77d0d7", + "0x8421044f794a1bcb497de6d8705f57faaba7f70632f99982e1c66b7e7403a4fb10d9ef5fb2877b66da72fd556fd6ffb0", + "0xb504cb87a024fd71b7ee7bed2833115567461d1ae8902cccd26809005c4a56078617ec5d3fa5b29a1c5954adc3867a26", + "0xb5f32034d0f66bcbccefe2a177a60f31132d98c0899aa1ffff5ebf807546ff3104103077b1435fa6587bfe3e67ac0266", + "0x9604659740f6d473bd2c470c6751f2a129328e74e01b23368f692ad9b6cce0fe1509c3f82e9f01019b72f6bf3a8e4600", + "0xa6ae4fd03fbb4e2150795f75a241ab3a95c622b4615f553bab342a1803b86b1c1a2fc93bd92ee12786bf2de22d455786", + "0x8f142bde50abe4dac8e059003db41610436d5ca60d2dfe2660ecaa5f9628aeb8b5d443e1b57662076f77363c89a1479d", + "0x919b0dca4050f3304144debd653bce45768355d2faa698b99de06ca6ab8573a285764904cafc9262352c87d9287f0545", + "0xabf28b692bed19ee9152d5f8ade776f0a42a9762ea5f37d80f47ff219fc0a8ebe5e6eb920453e1ced3ea5bba19ae5be7", + "0xb67146b202afec0132ac0070c005cf664081e860339f8f4d45ac3e630dda05560936e646673e652d08cecd8d18fc64da", + "0xaa25208385573caee2a4830f09e1cc9bd041cdb78d3ee27a4b011815a62d0d2e0295c222480947ae427b1578fb5509f5", + "0xa35d9d6d5dd5428cce7616842203b5fa3721cb4b20f50c0113f138604954fe0cf214ca3d065b578f921054b9efe823df", + "0xa1c0c317e6e352e16e25c140820b927161ce5d2c4c2e10bca3057ba4d46b4f42ad7aba20de86dad9fc6368ea92695268", + "0xb9ed23f3f26fc9f31e1e30e8ae88482352fab6ef79a2eb8939dc78110580708f482ba3ab306ed6e09030653b9704a80e", + "0xb15978155af006d231888257c6e4beac0d3b0782bcbc99e61802a5c031252f05213c9ee9465e6816d9702e4a21cb9571", + "0x8c9fefe233d0d657349b7efcdc368f5aaead27071d224af780874751e7d241f6b88f7650fbb4133043b24bbebc12aa48", + "0x92f0bf3257e775c5c469cd9a43249421c9fd223996aeda09654045b885a512e86bd834b2947aef216b4d9dd5f8f2e9aa", + "0x81ad5baedeacae12f19cc6d268779c791ddbdbae859d218806cf887b91e83bee3472740b0736877c81c5c1969eeccfec", + "0xa54e104339286d3ce8271828fbac20f6cf7afd3b72d9b194b7cbaf65f6612416117be492bf4aa88faf6ada56cf4b6462", + "0xac2c341f0054876d28393d5125c84b913e754bafdadf769ded764b8dcd4b042b5dbc19b6f40ce8eb45edf7639b3d62d3", + "0x8eebee05702bf1574b12597b72a86d5badef064879fa9d1b9aff5ab75e5c71d81d8bc404f2614085855d6ed87f581238", + "0xa5a07bf219432e9c80c38596c93560b49c7de287f31e30b7a06fcb4d15982add4a24085adbc5b753c462be989c64c96d", + "0xa3d31b20198f326eac488e88fc5b9171276d4934b0bc573c8b55b2abd26380d5296d5bbea281de91c0945f34b37f42bb", + "0xb928a1a20f078a50f9c67da1d909e6656c3980f20b96bb8d06c0cc42557ccd290ed64cd78f9c9ca090cfdb9327eebd89", + "0x8a0a4b295761aa6d2d1b988fb0c65b4338cc3ea48410cc673671ca029ba6c51fd4e101b54472eae93611faee53d4eb2f", + "0x935f616bc620ddcde07f28b19a66c996798792b953264d1471f686e84f3c6f125e2a3d3a7a535c4175973c7ed2e4bece", + "0xa80deb10bba4bc7e729145e4caf009a39f5c69388a2a86eaba3de275b441d5217d615554a610466a33cfe0bbe09ef355", + "0x8dca376df4847cb8fc2e54a31894c820860c30b5e123b76670a37435e950f53312f089a8e9bd713f68f59fd1bf09202f", + "0xa04016e9e13ad845763cfe44af4e29fecf920b4aa42f581715fc34fb9ca27776feee45c82093c7274839eef1838b10c4", + "0xb8a0003e949cf994b1bb25e270cb61358200c93b1c6f611a041cf8536e2e0de59342453c5a8d13c6d4cc95ed8ce058f3", + "0xa50ab79cf3f6777a45f28d1b5cdad2c7ea718c60efeeb4c828d6307b29ef319445e6a9f98aa90f351c78b496575150c1", + "0x8253e3b0b85538d01b0ca90b0a1656ad80ee576d0c3fa6349df58df92683b510e56c524fa6144f79a5525f41e4a2ed34", + "0x917721639b1bd13c33ad5b332e4486c4202ed28ddd9fe97b4d2367a87829c742c9e4bfb508827f4b8cadd0bdab99708f", + "0xb0b8c15d67a443907315ba3e94a89491dfbfd04ff9238d856f46cd49a3324788ddff3be9d61b2987f6f5a3c7d852133c", + "0xb2a4000ce0ddd3f0543ebfe4906570853a85350d75418a1ff2608099c069f03510df576ea0cbb406b7ae8e4f21576811", + "0x801c126abff96fe9b042be8869d2907d0c6963a79901f9db46577a445418b7465a1f4b346933d433e539536a9a2df01c", + "0x9530f92929f61f9afeea5737bded7aaff3078367aaf65b2c75f0f4263b6e90990a2bf64927774c4f0289120d49558d6f", + "0xa065363b9c4b731b08fd361081f93d987ad336475487dd28bbda2dca92b0b5da4edf326995a4ae923a4b2add7aa1df4d", + "0x85c216e314eb7bd8ba02e092c90e132bc4bafb21c6a0fbe058b0dd4272cb76f183b83c6783fc321786065ff78c95f952", + "0xa53658aaddc51e20752454dcbc69dac133577a0163aaf8c7ff54018b39ba6c2e08259b0f31971eaff9cd463867f9fd2f", + "0xa013cc5e3fbb47951637426581c1d72764556798f93e413e1317849efd60f3ecb64c762f92544201eb5d6cfb68233050", + "0xb7e5497eda543c02a7b3245eece98d21dd4c587b5a05f21b5c785756a0b875715782f706fbbfeaa0edaa6faa6b03d8eb", + "0x8ded37d67b5368619a090266e9b5585fbff60319a90a4244a3c3342641f5bfa5130998dd97d7a42505cd896c29255530", + "0xa9b120a77d70c1cbc0178a12d97a78b2dd0b98d0584e8e780b937800ceb18c90eaa1f0a83c5b50e34cae1c20468f004f", + "0xa22b351f139096f9ed5baafe27affde1351685765805d458381e392e0bfc51cbd8af5909b3a1da05d0d176877028eb32", + "0xa16938f556b8c11d110d95b8584cecef8b95ef349ea64b59df806cc62c52ee48074d0b3f18d84533e41583aefd6a9d43", + "0xb95fc0ec39596deee2c4363f57bb4786f5bb8dfb345c1e5b14e2927be482615971d0d81f9a88b3389fac7079b3cb2f46", + "0x89ca7b7aecbb224d04839d36e4b323ae613c548a942830317aa0d51a111cb40d7e6d98600dc1a51e5a32f437951d6c7c", + "0xb28df3e04bde4ec373171401dbd0546f4cb6fa8e9a4a8019aadc653d4e05e0b5b9a64417715dd87f6df9e7b3145f6659", + "0x89df46082b8dc997c3e33fa94fb6ebfd19af29d619ed4d861f8ffcf83d02b9077b9754d0667c2fceb7aa31ab5f806f65", + "0xb0c707313762e66c681b0efe03ca11a49791173c1e5d42b235c3370e98c37ca4393e6babaabc3933e3d54e72843337d8", + "0xa4bf094dcd71e1a8dccca76dc7887476154e673551f25b0ca90d6dac8b3b3a2241bc601afeeb1564bde0432db1972999", + "0x8f88615a86867c4add4c6dbd2c717a7d5c9e6450e9540b56de14c31d9ff84e2495aca3f1d5be51940c183c6ced9da2d4", + "0x81351fd284d6d07092875f366bc5e53bfd7944b81eece85eab71a00443d1d2a9fc0337aaf34c980f6778dd211caa9f64", + "0xaf7616b8f2f56dc68e3e8ae5dc5dbb4b027e53ce652860687f1b15b2f820ea0349baea5af4e3ba4d865429330d3383d8" + ], + "aggregate_pubkey": "0x90ad8bc2718e8464a78d43480f280d3ae08068ad88c2686227ec6a25f4393099e7e21b6200e83ba1a8fc34a9c08f5069" + }, + "next_sync_committee_branch": [ + "0xbcfe80e1d24fbdad7bc058b011403a4c26cb56967654494cde51517f888023f4", + "0x621312d94927fb6e3633ca6b4a8f61e8fbc72799bd54639043f1abe818ba816f", + "0x16fc985fc30e89dee4524512296e2a5438c4c68d8f035d3377cdbc2c7f9e1804", + "0x88c597da85b7b1a0ca4f2e149ecaa3eb869e60e78e5127db801706005d3d0d3a", + "0x7b3e52c66c24e912c1c7aa3207753cd882ec3c691354ede99ec716da5fa0fe3e" + ] + }, + "finalized_header": { + "slot": 4063232, + "proposer_index": 1311, + "parent_root": "0x9f5209af620727873d563ec0386856f5100df2278ee157f8b058021e29a2d0a9", + "state_root": "0x9cfb7a4ceeb31d6be6dba26dace0a074066152dbe507e328886be16e8b38bd9c", + "body_root": "0x9b934ad271680073ffce322e54a0ba990caafa9a0ab95195e4553aa5936d3f41" + }, + "finality_branch": [ + "0x00f0010000000000000000000000000000000000000000000000000000000000", + "0x3d4be5d019ba15ea3ef304a83b8a067f2e79f46a3fac8069306a6c814a0a35eb", + "0x452c63d803b8bf301447a73b2f7a747e49f37f9c9a096d8ddb6c8302666b809e", + "0x16fc985fc30e89dee4524512296e2a5438c4c68d8f035d3377cdbc2c7f9e1804", + "0x88c597da85b7b1a0ca4f2e149ecaa3eb869e60e78e5127db801706005d3d0d3a", + "0x7b3e52c66c24e912c1c7aa3207753cd882ec3c691354ede99ec716da5fa0fe3e" + ], + "block_roots_root": "0x31ed28275cbaae8300426740b8f08d2d31b0bebac67939a5f6507adc361458d3", + "block_roots_branch": [ + "0x7fb8181acdb3d8c6c5e2db5dafd701f1439abfaf2da9435818dae5cc47683035", + "0xc439004cf29049836d890c28867350dc62197484a9c97ca0fcd7be38904e826b", + "0x433cf8bf2df73fd85edc9445bd609ffff88cdf3eaea77b593e3aa48e6648666e", + "0xf092d3324350b4889c0a16d9c2ed940798360d33e5d82b32e0049b6b25cad0a8", + "0x565c0d114cdf1e419edfdcda9941aabc3d9bb8ebf07a4afea082ba1ec2083331" + ] +} \ No newline at end of file diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/sync-committee-update.mainnet.json b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/sync-committee-update.mainnet.json new file mode 100755 index 00000000000..22a44e3cf79 --- /dev/null +++ b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/sync-committee-update.mainnet.json @@ -0,0 +1,563 @@ +{ + "attested_header": { + "slot": 4055104, + "proposer_index": 1862, + "parent_root": "0x5f44df1f70338aca4b3046f9e5b144bda8b27276320ca000077389d0aba35317", + "state_root": "0x9daecfedc819b45231bf93819a73efd4304ca79528032fae2e852ebbe514cfdf", + "body_root": "0xa33f5cdc6732684e6f248e5a7636c7e7bf705f0bf709098a46ba15c660b4fc65" + }, + "sync_aggregate": { + "sync_committee_bits": "0xffffffffff7bfdfffff7fffff1effffef7f9ffbdfdffffffdffbfffbbf7ffffffffffefdf7ffbeffdffef7bfffffffffffbffffffffffbffffffffffffffdfda", + "sync_committee_signature": "0x880f147850ac0a94130b81f94203e2f69d512c929df8b954b6adc20cb1e8598aafadf366c074b590c0905d584dd980af18e0c8a837bbcadf6b4438507aa46ef95879c0acd9c2d273ccb13d93e4938e9c601f0dd466f53369ae94e1287955cae6" + }, + "signature_slot": 4055105, + "next_sync_committee_update": { + "next_sync_committee": { + "pubkeys": [ + "0xaedc2d47fa2662be6ab58ddd3682bd5e53f508162968fce8326c75f92fb3c1a25c4d4d0e6904f9b6cb1ccbaaa9dc28d8", + "0x8097b13908662d245820f3b045d8c2c665fe9a054e9c661323924ec86dfa713b36b0c787ad4dfdeb979318810e687a48", + "0x98aebd4bf15916512508a5fe89d814d5d76423c562cd3f0a0af504c8cde53be30f4df00e3ba0229cbf8528e198a0df11", + "0x86bba46d0031989d0f1baccea4174fc3fa0d595e60d35a464e86c33c233e2d6def84fced7a00f59afe397cf4fb5b67c5", + "0x845982c2672fdd44b33d2e56ad676e704c02f756b09e8765bea42b924c14724484567b55f0db42ac20cb70a7f5201c14", + "0x926dc729e135f1f0bff4662ee3d6823a64597fe189b763ada34f246e77705fd4e062d85506a338e9fa98c4d225a3b27a", + "0xb930ecc2a26183240f8da107e80979b59da4e05f090316d982815ed6151d7750490b85273187ec4e07eb221813a4f279", + "0x81564bee5a3bd09476f658cf7719326c353485e2f4fea58d110071c5dddd3cabc349a8d1ecea45d589ed4479952a2ba2", + "0xa66d5b1cf24a38a598a45d16818d04e1c1331f8535591e7b9d3d13e390bfb466a0180098b4656131e087b72bf10be172", + "0xb9b9b6113301bd2b409b71afa1ab9e31d22f84f8cb03badaa408e1d37032350094124e533de766622d7975a047fade6c", + "0x8eb3b3e3135720036c1120c4e8b8d405b00d002f2bdbe601a06f2c2fffb940a9966d18636ee34fc003dfef547d8f3b76", + "0x898deb30ede570d391266c81132a78239083aa9e27a9068e26a3bc14ff6468c3f2423484efb2f808b4996c16bfee0932", + "0xa90d9502a9785e55c199630456fcb1e794bbeb0f5f8c022e66f238a0789998b126cf9911fd0b7d463b7706dc6f9ec128", + "0xae8af784224b434b4dfa9ae94481da4c425602097936623e8abb875f25deb907aa7530bce357786a26ed64ef53d5e6b3", + "0xb544c692b046aad8b6f5c2e3493bc8f638659795f06327fff1e9f4ffc8e9f7abdbf4b7f6fcdfb8fe19654d8fa7d68170", + "0xac5c01c51dac6ee1cb365c9b03f09906d9b7b9b4d1b73c44d9e8e06823025d7070f242898a975420bc87d6372382cab8", + "0xa4632399c1a813e41fb2055ef293466098ea7752a9d3722d019aa01620f8c5ecdc5954f176c6c0901a770cbe6990eb11", + "0x85f7ae1a7a7c793c408750ddec2d7f58b985fc3cdf9fcf6b2192bc57092b8a271b2fb6ced0639baaffe0bec3203e568b", + "0xaaeb466f4316874c2107a0de38dafafa65ce50039c20723e8797815238011426f4e77e29fc573e7c6d2df85c1bbfefdd", + "0xa8fd63da16dd6a4aa1532568058d7f12831698134049c156a2d20264df6539318f65ec1e1a733e0f03a9845076bb8df8", + "0x93600f65c090814cee5cbd5f22f98e79c69e63510501a0be6a74b111e4c52441133fc1c198c7bf235f9005aeacf1d441", + "0xa69f0a66173645ebda4f0be19235c620c1a1024c66f90e76715068804b0d86a23dc68b60bca5a3e685cce2501d76de97", + "0xac6e7e9960207138d5b4b6a7f061756c01cc4a830e5988423d344f23544ed0eaa790aed63a22df375768f670cc9b9bd4", + "0x93042dd42e56671155bb40d85d9d56f42caf27bd965c6a7a7948b39089dba8487d4d5fd30522dba6ba392964e3ffd590", + "0x85bca2f86423a09014b562f7dc613246bedffdcb3aa41fee02270c13e6b00c8d6704dcbfbafc5997df6a90c7fc08c29f", + "0x9550072f64a48cb86bfa224d492be9a91e5a6c9def04b6a290b7a19d96981937d5a2c35de6515d1881bcb167f6e3d661", + "0x8d797819318cdf7b26405d1a327d80d4c289e56f830b28d4e303bcb019aeb0b3d69bfed58adcde8a2445dd5281b86af1", + "0x90c04eb3f3679cd630434418cb3a225a73254887692429960bd45b1613f85b2c14723cd8c7f1e875588ed82b7f5576b7", + "0x9953a7cbc152f101a60e3e381f2af17ebe7401e16ef6462d132b8f0f6c6a18837914a1299d1605f9f289b9561112f4bb", + "0xa9300a33927335f482dd0e44d0d57704ebeb278f732ae8301073cb7d5e457f02a0cb03268de71d284b8c23fb96947469", + "0x88554c83648ea97dac83d806cd81d92531980346b208d281fba489da15a0084fd4d9a00591d1ca67aad3c5793685d55f", + "0x9131874b09aa95ba186bcaa9e040fabc811b9c7b905b7dc79e902cf2bb5816d7ee39b0b55be609f22bc8c538760b2037", + "0x8368bb9b9bb2e17730c42ed1100eb870c88a8431601312aa8cb1e738cdb9ca2704dfd432cf1703c0db043259819631dc", + "0xb49379bbb9f954d2ef5574199607bc6b3aa2cc3b48dcc3745cc77406bba2a394929844fec1b87c4ce65cd0ca0f83062d", + "0x876afcd045c8a18967923733a3a43757652289b0974cd348238a693f30bb57f38664ecb97877a5e5f7d0185039a2bf54", + "0x8db19f6dd3789df179ab606508ca7e3da7967ad4340f630bda83df54c197d6bd3a14980c87fe10cbced7678c0c300ef1", + "0x997a91da55801acb6134d067ad65a9a44ead0b53d3871bb97b46ec36149d25e712d7230d38605479796190abd3d134b7", + "0xab1abf9cf630d6cbcac0c503df44603142ac81acd647784ae0e8fc97800ef04378bc9d7f2087f959ad4bbbeec65b8dfe", + "0x95718b06017ba9d45894867fd67148645d25d9db2229aa89971f444641ba9db4c5c6f0785f3b25cf2cd7fadaa6adc5eb", + "0x8ec38c68afdfb6ba019204039c2fb49a35467058f561f626fa87314d705fd615a7b9966576052be1b3690028d3c5c7bc", + "0xa5d72ac4cdcd847d67cb5a68c6141cde99a91303ca84165bbdc6fd7f643422faec783de60739e1b2753088280c90a68b", + "0xa778da56ddfe4a383816b43b027464d7a28689fc4a6b35b36883d3f36d9c41f0177bdbfc8f258afe8da90f02d3b64fea", + "0xa2ab566033062b6481eb7e4bbc64ed022407f56aa8dddc1aade76aa54a30ce3256052ce99218b66e6265f70837137a10", + "0xb9c347c1c350fb7ef6ee9ca6780cf0604f30e3a74e9d0234bca6b3e7faed26148f2b736d9fbff6b04f5b947fda458e8c", + "0x815f53751f6d3e7d76c489f3c98d2b49214938cac8c2b417e2d17bb13446c285fa76fd32a97e9c4564a68f4faa069ad2", + "0xb3f1319ae34ad1d59207288f01d3d7b7e1bad7733fb4a819a09b011d72a4d736bd3c7afeb74cf56da0e00cf712042ad2", + "0xabbfb501071148e98b6aa56308197356fd993c93e27fd58987eca82036c1ae0ea89f9fb1a06c82851234643904c58453", + "0xa0899189bba608887c6cb729580e570ecce9ca7107865ebd30def867afaaa250bac407c30dbee11b7ef6cd423269a8fd", + "0x88e7a12a90428bb45bcf4b01442c11607433211fc2f9bee9545304eb66e0b4b5339360160bc782e185391385da7c5ad7", + "0x82714b00a822c30b317ffc1d4ba163990cc1ffe5769f91906a7f71ad1f62b39865a5314433a4ab2ba762b1d62b01003e", + "0xa3a930dd70aeeaff0f2e3790927d5425db40467ee106261615de5fcb937bb1621be213ccd8b3a14d96c5908bedc2e421", + "0xb2902161b565dd5b8e8c54187b26f01741a39ea8bc1120598661bd367cf8fc73e21eda2f0f6f9ba2270c80a59ff5985e", + "0xb77cdf45f39bf85ab3e8c8afa602f159de8352188aba5378957d468315a2d2326daef83d8ac6b227f1e7a514488afbc6", + "0xa9e573274f5a131d6c7641bc0576a2621b6466a5bf2cecb21058160a854b1b9e0be176da2b6b9b3ed562fc36c5f09119", + "0x876561bba29e656b7122f1cb51a02dff1ac7d470217d8a4799c01e61816c4660eea91843a5a42502ddf842d2daeb0586", + "0xa0ebae60a998907a19baa396ae5a82bfe6aa22cf71bfca4e1b4df7d297bd9367bbeb2463bda37aa852ad8fd51803e482", + "0x84a6edac5ac68a7ca837c46d5ada8fab136748b6c3a3b9165dbbc231ec386b15328e4ef7d69a15d4cf354135348a4ee4", + "0x8b476b3b065a3b95a3d11ec60a749c2258ddcc5885bfb50b8a086d3fd1e49ff73e1dde733b8981c3d2d206aa0c87b09b", + "0xb48490c5a3bc9e66cdc78994f7c73e0f2724fec8a304b4147799e5142396df155ef7c42065ed6d2c0393d138fb4d2a0b", + "0x849ddbdc3ac55ff22a3b2f4bc51892fed694490ab4dd342165ac38c725c8b38921eaefe3c443962925fc3726aa41e236", + "0xb49c45d9da4aaa64967c28f1fd77b7f709f5a331b58823eb1613856fd8f92635135981830a287e8dbda3a0e0fc481c5b", + "0x93ccd8c5f82374e0bef6562e16576f742d79b6f400e3485ef36e148088b61fbd882c3d2bb38ab0b43fa1dac77f31d543", + "0x81522576ae4ec9358f1a16934cd1c1116de609634e68f552924a972101eb7215f037ab8e0582d7b13541537d55554d31", + "0xaad60e58a19598c5013b37e2e4adc6721eaa7e6e184960d1dc4e6f012246abbb58a047c0679064d5eaaaaff02de881e5", + "0xb4f034f2b53ff9989e8a0f12c1484c58ed7942432a429af58a6659feaf23f7d2bf20ff7b9a7e0a28a2e09c9a730681d8", + "0x88b2c68b425269850c1a4f4608aca194da5c641adeb99e2f7fb92e34b8245dff066e73bde072be60f7f2c3d3d13de3b6", + "0xa749ab53fc2662a0796489be84fcfa59bb723ff748bd8980df0cb4b3d1e2943845b0d7c67576fa0a33c8b0ff8a86932d", + "0xabd7248ae069d3a3a45b0ef4dd5d7d54b62994e578ea20bdd3b7876596673953b94c5b109a6e4b953b517544b915368f", + "0xa49da42c27d019a21cc6489ada7b712b98c4ede28ba25dbcfa916acef48446a2baf73e03a48be763378a09774d4a03fc", + "0xb3c36fa39f668bbc3fec028875a820057dbf96f727bb423280da96d5d50e885d23bc23fb73457bf79089691ce7663a7b", + "0x8dca376df4847cb8fc2e54a31894c820860c30b5e123b76670a37435e950f53312f089a8e9bd713f68f59fd1bf09202f", + "0x95d1f944b0c53eb3e9fcd5632713602bbb9195b87a172a370ae2df98504612a55f3968615a39b569ce6a0fe9fb559be7", + "0x8c9fefe233d0d657349b7efcdc368f5aaead27071d224af780874751e7d241f6b88f7650fbb4133043b24bbebc12aa48", + "0xa2ee6c29efa982e9b9abd3c5e4f14b99d5d0369d7bfc3c8edae1ab927398dc8a147a89e127b3324d7f4e3a7494c5d811", + "0xb7ea5e0d3cfcf0570204b0371d69df1ab8f1fdc4e58688ecd2b884399644f7d318d660c23bd4d6d60d44a43aa9cf656d", + "0xa07826925f401a7b4222d869bb8794b5714ef2fc66fba2b1170fcac98bed4ba85d976cf9ee268be8a349ae99e17ac075", + "0xb0a47515752c15e4dbeaf9ee27fab3b5c0db82f5c685e8f716fd7d8764164944340430fe3db1a5679e6ffea5a16dd919", + "0xb7de6d7a4afb05984dce153e5570b104338265e45c8f0156f4d45c458f47add234a479e01c02d3c1817c170b5b65b100", + "0xacd4d1e11f81f4833353b09d4473ec8b15b8ff31dbf39e97654f5338a26c4020306d51018f1f4b9c4efdb92992408a6e", + "0x80e09f3bf3ea87d48e04b53d8f3b43b7e53d61f445f8c8a5a35472b84f6bb4f58f17d9832f5881bb44fc06156151e5c5", + "0x98d6d46f603afebcbc561c130e416d5a588a7e6c1f17f89ed6e30538b7f8dbf4b3c75b8a3331425c4ca21e03fe8b57f3", + "0xab671eb947490c43fd05e42a787344b21af89babb705393c82748eaa0cfcf80bee498d275a1eaf1d647ca3b2923d76ea", + "0x80e1dbf3296bdfa98aeec1a7560682165d13bc628061bd3257f345aa1ba13f8bd1bea14f117af562be22118f5a8265af", + "0xaef456af90354ff88039d2dde02b0f5a6790aa762b23e0a9da8c6ec92c3b8b3320687bb21666608b4a22615843afd1ef", + "0xa5a07bf219432e9c80c38596c93560b49c7de287f31e30b7a06fcb4d15982add4a24085adbc5b753c462be989c64c96d", + "0x84d2eb008578aebd6f01254b7e46584c1524e6fd7a5a2ae5fa0ea560865ca50d52290cf2d12dd20b042f402e62181b4d", + "0xb8e5226ad3515627ae6840235f5f7b7ecd54e8f01079c324d126ec852f6665ebb77168b3f2b3b51580e04a6ff602d5b3", + "0x8c1de4264e04ff7e8282faf81c0bfb5943656451be52170211cb7adf4ff21bccbb789400735579c622f69982fcb8e9c6", + "0x90bfbe37ac3992432e68c95c0d4342a9712126d1f50089239c9f4f6c0c202b54334e08604d245b97dc8e8f6706f6992c", + "0xb0a771b9a0dd7e352d46c8efcc1834e610dd097711bf7117678a99d386890c93b9b901872d4dcacb6dcbcf3aea0883ea", + "0xa4eb903990bee2374b14fa66fc262d6821669537e9ba241c87b4b5c9e2b89b32fff4bfc28ab8471ef52e8eebc3e743d1", + "0xa6b74c706b33d3cae9b7adc5c7502ac98f7bf94a14d579d2bf77b613ae555634ad6fe631ba36dc14bf44526436355e24", + "0x8296f8caf58316af535def398a43357e48cb3b1e674b857eba1bd1b970da3dd045e22fe6d17dee4e9117f62ece3ec31c", + "0xa129c9cf33df42b5a98ad98be9d940207ae154c715d3bde701b7160dfe45304679fb0481a4f9dde242c22a9849fc2d9c", + "0x858b6f1bd3e68fc536bdf1f4bd96db032994eb76e71571e2d85af73b898478b82f9ab432732b0beebc0864ad8025ae33", + "0x8658a15df961c25648fd444bdf48a8f7bb382d9212c0c65d56bf9cdb61aab3bd86604c687fb682260dbc0ad2dc84bf01", + "0xa8d152e5d94b75cb9e249230db21af31de4d4f3d4ef60ccbf2212babf69aed2a38435a993ee2f13cca410ad55a4875ab", + "0x95757096c132e7f6c096d7b93a5a0d2594d5e609b9f13c4a9f878e95a389fa1a111b185dc1fd8f7d98b737dcf8d2af60", + "0xa22542a4a2ebde18cc6aa29d5dace8b4f6720703f519610dcf01e671018392aff15728e3764730840272c9cfb074b612", + "0x8f90e72a54e6894d511061957162e753010812346afd4d90cfedb678b99ba1aacf2b6bd0e49b4b0e684da8082a048619", + "0xb2affe048c187d311a185503d8958cacbe03796edf79bc32e8533941004d9178bd2e376e627e1ba61ed43850c0c455cf", + "0xb549d272a7f3180826a978d747507e4dc80d82784abb655cfcd3a69cc72e7d58c70febea1ce002a89852a8f934ea70fb", + "0xa9ef845ab489f61dbfdcd71abcc29fc38f3494a00243b9c20b9cd0dd9e8a0f23304df84939b9652cdf5542d9b3ee085e", + "0xaa744c552b5fc41e1ac6ca53184df87a1b7e54d73500751a6903674041f5f36af25711e7bc8a6fbba975dc247ddad52d", + "0xa802b9ffbd4f01b877791aba27da972be4bacacc64a1f45687be4af01b84bd4b83fe2ba1ea78e29d7683f6c777ab2543", + "0xb44d2d9510516c0abb4fc101241cf0e0223b179fb70686519628c27f0ef56381232961bc79a30f592ef093ffecbc4486", + "0xa684a09add047c0fe648d9c5618500d1816047168e055e8ac8c952c3544a462cc095b32fab07d939947a58fcb4ec7ba7", + "0xb5eb31e5cba0193e74968099ace5808dfc457c6f404f270fdc4949b60daa7607ba1811abab1bb19fccdad61d489b6657", + "0xa10f19657a9bc5a5c16ebab9f9fddc3f1d812749cd5d80cb331f51de651873ff899e0670f1b079b29a194572de387a17", + "0xaf61f03e3ceef5bef36afa29ba2edc7a3b01ca26cec2589edbc9d124dd46e41410e0e3afbae959c83a6f839bbcf8049a", + "0x8e6bbfe492ecbbb8dc8889d3dcd7037a58db605bc6bb79131a72a9b9c1bad630e75f5e5e0c1bc407e73f3d13b116739f", + "0x983fc1ddf17f9756c9cecc00b39bb2ad432587a5c6d1c3296a383b9f539c9afe84c6c818447a709c0b686ba26ce5ea3e", + "0x8d52413f981bc611427ad0534d25e914113d0ebcd6960aab6421608bec6648b89ae4b2ca2153c57d3cf4f1f37212aa5c", + "0xae075b66e5f211c2149c45b211d1297bbc1d9e6497cb3315363c492a9a51ae5b9d0a28bfecd755d68553736901ac6606", + "0xa02f7fec0661394399a82b2e3151009160b3f5392017ba579b301ed42c85100c295acbfed46b6c58a9d71796ed0930e6", + "0xa3a7196fecd25e9cc7cac79c35365676e48c7be1493df255676adff2209c0719f2190ceff3ce008d08efa07c244c11a6", + "0xa5fe3dfb5031517bb8db0d5ade1e9f438e84bcf23221de003b03d2a2f4ea97629e81c79abc3769bdb8c69a512c189b91", + "0x8cd9d7e953c7ae07ee785d68a999e702565960d376692d9ea468556ad141229b1f3bc97926818c078901f73ecc578e93", + "0x81d6fc2f01633e8eab3ba4d72588e14f45b00e68ab887bdd4ec5e8558965db21189310df973837106216777b07fc0805", + "0xb75ac3d5b3dad1edf40a9f6b5d8923a81872832eb3a38e515539cec871a353b07cb477f6d55cf15ba2815a70458aac32", + "0x94d3c9406dc6dd7241a726355643d706e46b35f1ffe4509ac43e97c64c07592821156ba02ec9a78978e66709995a0ac8", + "0xa3b109249ac2900806f0f39338da72d4f2cc6d1ac403b59834b46da5705cf436af8499fa83717f954edb32312397c8d9", + "0x8336744d8ef3a3bb3e9ed3d6b83e08cafffc76b7438adedd3a7358b32acec0e73a4635aa3166362ab4e158e68576255d", + "0x99b74edbac662fff69ba412de466a427a928ce2363c9e59dddd664f6fa50f2e1dd3d464701b01784aa224b3d96dedea3", + "0xb397ed7134f447d9bf1c511bf92f2d27d7b6d425b8b411365fbef696cff95c2175461cf5dd83d93bb700e50ebb99b949", + "0xa3e1fe11f38d3954a7f48c8b68ff956ea0b6f8a3e603fd258c9406ec2b685ff48241db5257179ea020a83c31dc963854", + "0x949cf015ce50e27cf5c2ff1b8e2e066679905ac91164e3423d3fb7e05c64429e77e432db0f549acb99f91fb134b6edad", + "0xa1c0c317e6e352e16e25c140820b927161ce5d2c4c2e10bca3057ba4d46b4f42ad7aba20de86dad9fc6368ea92695268", + "0x8d6e3df29419bd0da1deba52c1feebe37744108685b49ca703e1b76fb4d612e3959d3b60b822506e5c0aac50b2f5eee2", + "0xa15e0cb96a463ab81e661ca44c619b71a159680bbc04707ea5a5867ff38b15416e3abe55d2fabdab9aede1f157dd37e1", + "0xb6d6482ad7b9b412ffbefbbdcc28eb3d091b1291f54f77bdd53c4ac85f705c454940f466dc272dde7b03c26f0cd6ecb3", + "0x8391e3ad6ec2686bdc686671d579edac2d5efa8cf0923577df28fe0735e4d5103173d44452816e3c2b2a7fcc1fcc20d9", + "0x818202d7cb60e4148c71633ccbe1ce311de7b7ff93a1988e86ba29cc58037189f0f275b3323a6719dc9bdcfbc49c35c3", + "0xa7c0fcc422c6da878926cc6763ae6ec685a5d8fd1afe61269957be6bfb3f1705a8e4c6e6d85bd15636521f5a2ceb3a00", + "0x8f7bbaaac458bada6d852fe665c87c646133bab16c0d5136c3dc922095b9d647d93a9de7671cb7bfd4cbd138ae0709d1", + "0xb6e9fe9fa3d4c833c3beae7f798f30f07e3cdf6f6c8eb8e2b70cad51b37af2549dc9f2e7f97f194e5897d4dedb904a45", + "0xb455f751232de0a48440d09983f4f4718b6169907979c9f282acf7177ab5b1f338fe1f2acd8d0bee4b4aad61d0340839", + "0x8aadfcf3562f1c357068323352cb1745349a27a7362358d869e617c2410db747149b993ee9e881e252ecdd42fd75f351", + "0x91bf4c32fa8888d3829d3c33e12550d2ecb70762d5eeecd044d4902e4a7f8b7a2592cf6cb7736eb6bd9d312f85c2777c", + "0x859426bf6211e68924eefdb26cdc168ac0deab291aaff7036163997bff34d45809932f91e12d113784c05553ca773b15", + "0x81730b4bc5f755e5b99c321a6996c65e57ea2ebe6c0e4e404ed30920194fd76db65304635ad054a8b25bfd982cead47a", + "0xb26f5ed09f7d5bb640ec94ddd1df0b76466f69a943b4699f53d45296d5d6b8010bb61477539bc377d1a673d89074d22f", + "0xaa65c11071be23c9bddaa5203f3166e5cf043efe5fb8f4b26f8a9cabe71db701a450e79eb001c401da5752755d9cf1af", + "0xa019370ca799c2c98a605850910cf43531bfb616393039fdfc370848feedd3339b2427b750ccc91952b03a09f690e9ed", + "0x8f84cba7ceb7652023fc8ebde4b00ecde1f550935bab12feb630d6f49517b4148f3cde184bf55d4f6ec99a849fc6f862", + "0x838733220d1559c800cf1714db8a43a67a0c0d1d3a9fc1e2cdcf615d20406501e5146fe8b59bf64f4c5daa1a6d74f15c", + "0x9708cfcc9ff95cf23f544119e17518a338575018f153b1ef50118da0681304919a226b2089a417c2ab7b4320dffafc2a", + "0xa988cfed9f481bc98beb5fc188ed3f6893a3ebba27c3ebace669792f6abf0997727023c3b6930a6421224f5b257b8b49", + "0x812d3ded3a3c9e58eecf13a29bb4cc13b01b2a0af322423a29bb0e4f6d9021d1d87ac4af7a2a6b88d34f44a8bc1b3c55", + "0xb2baa7eba496ac4ef60ad8ef27a9677f9507820d95a1c572d322621c4d0226b36146bfc3a9ca1645d123acbd945de3f4", + "0x89ab1e5c2565f154f92c9b3554160832d176613f1a2f872b6ed62ed925a33fb0b40b71b7443eaaa15099ab24693c8d13", + "0x8982534f2c343dda20cccf5a9c8bf98240bba5f4e8eb2206e63a1847097deadb6bf0d24b358014d564c5ef1d0448c43e", + "0xa1e47798a782a024da340d6d6a1b1e5e15a0f2d8668adf349ca375086964414a563cc1eea3226ae637f87e78c0a630b3", + "0x847b58626f306ef2d785e3fe1b6515f98d9f72037eea0604d92e891a0219142fec485323bec4e93a4ee132af61026b80", + "0x8368a0f17c8427beb71dbf11a09a2fe8495a33f08c29c74a9a996a88aa01c0a09f9555abeb1ef1592cab99a9e05875cf", + "0xb38e558a5e62ad196be361651264f5c28ced6ab7c2229d7e33fb04b7f4e441e9dcb82b463b118e73e05055dcc9ce64b6", + "0x8018499ef720e28759133033833edfe17ed23e42f99058bb79fe844ddee823cfdc43916be2dc9724d18f9726e6f1b409", + "0xaa9b9cc039d147677aedd1e47ad9013fcc0da0164070ff7305b18e5786c7fac0471368637a3adbb78f3af174a5c1592a", + "0xa5c0e42851b769d2d822e39222e708068455aae3bdf782975b59d3201e67a58fd66e16d380558bf2086bcab890a92dd5", + "0xaf3f765fd293c253072b33a780ed68933f78d7e079d9a2079b6232755bedf6ebcbce9ba65c01f695602fa8ee17899867", + "0x8a0192ef0903d7a5ed2e5614a715901f2554b324ee72390974dc90727ff08dafa580041a21a8e6c48a3e08e1b042afab", + "0x907c827a4fb5f698bf0e6f10ca07741c5b8e3ecb26aa53f938ba34ceb50c01be80c4afc5ac4358a5fda88eadea0cbe73", + "0xa35ee5c2d7800489723c78008b495e1742f0542dbb487172ef438f60424c81aa41c2397095821248066140662133f6f4", + "0xb1925ee53c9228cf80e2f5ac0117008a91e98d878f69bf03d00d873ef45f4351cb6988772d89d4ccddb40778d11e0dd6", + "0x95aafa379cc6a2b4bdd0cad30b7f0a47839952af41f584219ec201c6c4d54610eb2c04b67b29080acb8cecc5e7543fbc", + "0x8f44c43b80a3c5f488118859fab054745cfe5b0824821944b82fcf870fda6d93489ea9ca4220c24db2f4ad09c6080cb7", + "0xaf861bb21f84c3e7cab55370839d18ac24c475a9e833607fcd7e65c773ee9d64bea203ee9e8fd9d337f1cd28d5ca0d90", + "0x8f6fde2ebbd7682c69026069cfe93aa5410071f05de9ccd7070c8c3299a6539b39b3798f01a0b4e9b1330510bdb51de7", + "0xa35d9d6d5dd5428cce7616842203b5fa3721cb4b20f50c0113f138604954fe0cf214ca3d065b578f921054b9efe823df", + "0x8d562d6c0e0d8325032e1fbf836022c82a8f600a6fbb56c553ee5d1fac0f052c7ce2504c0fd48c9fa6494a6bff63c9fc", + "0xb02ce594310f1eb8acc92bb80de524a43e663e12fb64fc28291ff207f9d8ae761631416410c3c8f4d6890b8b7e6ed24d", + "0xa258f8c0eff666c2bb70e505544c3d10d6b258310e4fb2206fd0999f69bfb739a1e232d1e810e7206f490f6c44f6934a", + "0xa8a77936ca91df3b2ee7394ea821f2bfe91c6ad8193f44651466c170b6ecca97ab356fa7d947ebb4b767e8967092f143", + "0x88ad79a0320a896415e15b827a89969b4590d4dfa269b662bdc8f4633618f67b249f7e35a35884b131772d08025bfc32", + "0xa3c66439724d737d20a640bceed8671b20cf6795671b6d442ed1ea5eda6723ae559396c24f44e982ba7751dcc6adef5c", + "0x8d0e6475acfa2b904e7d53bc7acd070a2ee4894ff5720a20e560e9ecb7872ea442a51cf2f2eee4bef66604a5c08ad9eb", + "0x804c021152c3304853941847e80480fdaceba3b9676fbe018268cf77d1a1856966c2f9686bb4d4aa0c4118a7e85f83cc", + "0xa6565a060dc98e2bfab26b59aff2e494777654015c3292653ecdcefbeeebd2ce9091a4f3d1da10f0a4061f81d721f6ec", + "0x8d5de60e934ea0471d9e0a46489f21e03abb9722f5b3633631a9a099b9524beac5d67716969c83d824498796d9c106b7", + "0x8c5a9f6eb0a3ea95e75362b06e5cd23968447a212cf22e1419c984d74432c51d290b717f80e8ed3e76b1232216f99758", + "0x918ebb73eef984d0ce28083306626d04817038056aab4a82ff9ac8176ffdfbf3173c0b05e936daf553248b323fe54f56", + "0x8f9aededb605db4e499d3c383b0984b1322007c748dea18dc2f1c73da104a5c0bece6bb41d83abdfac594954801b6b62", + "0xadb198f70a7f1969ed0958be4a9a60dcc1806bced79c63692b9aad6c5648ffea1fed60b24bf4b1862e817cf229e93e83", + "0xb118f77f99ac947df97e7682f0fb446175185b842380af4ee7394531e4f93002c72b41a57a7c1b923a4f24b10924c84f", + "0x944f722d9a4879b5997dc3a3b06299182d8f68d767229220a2c9e369c00539a7a076c95f998bea86595e8ec9f1b957bb", + "0xb7270f33011db1bad18e076a162d6e53d9123808609773eb46e3a4ac69c84c257407907bd5d05b6eb5e926b8d8c6d884", + "0xb09c0a505457c6b473fc7b2d634222905b36a6ffcc015dbdffa3bd62218c94e891615e77f28e6e18dd8474be8c156695", + "0x97d076617cf0a64ab3d1f030cfd72a303b6b252c0a7b96157ff7fc8af5970f00d14492c46e8f6f37caafe837d0dc95c7", + "0xb405520ef829a2a3b8947f1687ab56a7af4026c1a6f99f59aa192bc4f3b12a2de407862ff74ba1b2c51889b8d6b090c7", + "0x8bb045e7482b7abe670d72eb2f7afe4207b5a3d488364ff7bb4266f8784ea41893553a4bf7d01e78c99ed9008e2c13bb", + "0xb2df29442b469c8e9e85a03cb8ea6544598efe3e35109b14c8101a0d2da5837a0427d5559f4e48ae302dec73464fec04", + "0x99daf03fa434a482d9aa4d090884c99b7208c1f5380b9acbf304e1bc33d3d6902afa5d248d20ccf03795e26901356ede", + "0xb60df25a7ac1ad14aef7e8809c4bfc190b715f94f14b0534cc2e4015ff6c322883cbdc5309e05d67dca4bc641c69725a", + "0xb46a818f3e492e231d8fa8de8848c16f0d648a2e0d1c816adf9306a8596fdf45922e59cbf745430570a19e54f45e28f7", + "0xb3ca2ab7d64b71e40693bd3e2288a1f78741a139403c783d259cb9dc9c29f16c00796b6302cdcea4a4314e132b4f9d1c", + "0xaf3d3dffbe55842dfb4417295a6ed1a82d26a579199494b305445215045785759be4cb57dc870c7ddaffbc101a854a92", + "0xb21785008910a949804d1291e7533752641d31beae3cb518806488f81d58c38a5efe5ed9534ac692e68c3121e2f9d97d", + "0xab7eff4ef8696db334bce564bc273af0412bb4de547056326dff2037e1eca7abde039a51953948dd61d3d15925cd92f6", + "0x8bb4d08318386c91a0136d980a42da18c05743a5c52a861ce52a436e66a8ebe472dac7f7461db32ea5da59a23e9bd6c9", + "0xa1c84730a5c41dcab9a5ef9e1508a48213dbc69b00c8f814baf3f5e676355fc0b432d58a23ad542b55b527a3909b3af6", + "0x948f808c6b8e3e109a999657ef966e1e02c96a7aae6eecaf912344e1c7bf7ea51c911cecd3cea2b41ff55acc31df9454", + "0x8d264fbfeeebb6c4df37ff02224e75e245e508f53fb3446192cd786ecf10d0f704c4fc2e53e7f7318ae1407e46fc0fb8", + "0x8d47a7c2c62b459b91e8f67e9841b34a282ceb11e2c4b0549883b627c8526d9e0ebd7333ba70630bc0ec2478114b6ae8", + "0xa4348ad30c12bb7dd03dd014cca599c3499ddf348e7795b0392a18f998289979478374e374a8297b5b6c427441e2b5af", + "0x92ec1aeb2aa24c51cd5f724972c8b6095e77b237d83f93ed34ca0bc91a1dbf1ad95adccc59e0f0abbfef33f331f3298c", + "0x941f73b2138b4347ecafcc7b8c3d03f2a54dc49f580394ed08f22b0878ee7cb63d42978f1d320c09e7dbc67648c06f8c", + "0xa308ed8737b3a9346ff20dc9f112efccc193472e6fde6aa218ceae11e288bbd2c35fa45c1d8bb238696a96767cd68b46", + "0x8eb03001ac9e22c6956a682ed458e650785c36d23ddbcd51ac4d9cc991325c02519ff1958987a08eb29ff56ff6e2c293", + "0x80637db55287f891baa0e865d2423191b9a575620bc4493ea76166d47b99fd89ad8625c21f446b01e3ae17292c78f7ef", + "0xa5b3da08aad945effdb645c797a0a8bfa828c9d658df2783a214597acebda3ffc07ee48d0ce1147d77540b557d9ada91", + "0x8d5e0b8cde1f62cc8f15d9f596e31de09c221da91b10335b92ef1155802e742442def161223333573158723f3408bbd3", + "0x931923f0c1f75a197e6244d67525b524ceb07510a6aae8cb3d56167cc1aacc76d26fadfa1bdfc55d8439c6ee4d4d8174", + "0x963a298fc8876b702424a697929c7a1938d298075e38b616c8711f1c7116f74868113a7617e0b4783fc00f88c614e72d", + "0x91ead7dacf43905eb5d4b179af29f945479ed074126bad3b5a2bbc1663af5f664fe53a36684e9389ab5819e53f1344fc", + "0xb8a6c999068c13fb71a99d75eabadf7edd2d32e28607baf001a0aeec412fdd3575602c68d3feb4d743b90396705e37f3", + "0x938bbaa0ba14597067ff4c0a7cfc1529c44160d6f61cfad12246526d84fb7a1ba964d3bbb065a348cf7a98356ee15234", + "0x80e44d3577f12cabaed7074feeb57162ff80b61f86cce8f41d1d1250bc455070b09f6ea9d0c263b7b4824701480f4c14", + "0x8d74f4c192561ce3acf87ffadc523294197831f2c9ff764734baa61cbad179f8c59ef81c437faaf0480f2b1f0ba1d4c8", + "0xa0133deca5ae8f1100df8db69920b2d0c31aa21bd3849dbaf4c264eaeaec8937ab8f982770ce1ea17e0e258910a56d02", + "0xb6a25d493d708b035b853f1f7a6628d8e0b205d2678293f763d7ea4da11d298539533b22b43ed2e5f708648556f3094e", + "0xa58c3a4ba86d0d6b81c8411bb73a528b4f3bc2debac0e0208f788c080a3a96541d57c927143c165f595070afe14b0517", + "0xa52c15840b89d92897d1e140b2b8468a88886c5e1092861e598b3a433b340ded5b35b3d632a9879820fd56f20ca3a68b", + "0x8c122bea78deee98f00a86184ded61c10c97335bd672dadddc8224a1da21a325e221f8a7cfd4e723608ebcd85a2f19fe", + "0x87a51e0011dd0488009baac9c611fbde01878f9cf1584ea407599742bb32ef10586d9040dae3e9800a125de54f80c047", + "0x98181e9291622f3f3f72937c3828cee9a1661ca522250dfbbe1c39cda23b23be5b6e970faf400c6c7f15c9ca1d563868", + "0xb01a30d439def99e676c097e5f4b2aa249aa4d184eaace81819a698cb37d33f5a24089339916ee0acb539f0e62936d83", + "0x830e70476c6093d8b9c621ddf0468a7890942589cae744300416639a8b3bc59a57a7e1150b8207b6ab83dafcc5b65d3c", + "0x83ca733849830cb8fc2ef469e7e464fd94def561ce49ff0aa352a6ecd0e52c7aefcd69ab59f3d1ed2d5b8536d0a7895d", + "0xb76cb8cb446eb3cb4f682a5cd884f6c93086a8bf626c5b5c557a06499de9c13315618d48a0c5693512a3dc143a799c07", + "0x8b027c14affe47f83ee59b504d83b2fd2d9303de2c03ee59d169bb199d9f4bd6533d7f8c812dd7a6f1e8155e3e185689", + "0x8e6b888197010ebadd216da35b9716daa8675d93b3c33a96a19fd9ca42624f6b430b2ff115cd0f5b717341605dda24bf", + "0xb6652440bd01316523feefceb460158cd9ba268dd8dbe860a0271f0176230f057767597e4197885ba907318ca202ba06", + "0xa0b3dff15982a38a2f56d8c6cfc5c5543c045bf2db24571d23387ccab42abe2756f34d5f0bf6a426bbad3c358b8bdb00", + "0xa8b593de2c6c90392325b2d7a6cb3f54ec441b33ed584076cc9da4ec6012e3aaf02cec64cc1fd222df32bf1c452cc024", + "0x96b478b1e5e49d4ea3fd97c4846ae0f781dcc9f9ff61ee022ca92c3d8dfba89c513c46e8bb38b73e6b678a79b9b12177", + "0x946d585d7aa452d37a8c89d404757c3cce2adf2410e18613483c19199abd88f7a12e206f87a43f6009e42f4e31ed20c0", + "0x8c432e044af778fb5e5e5677dbd29cd52d6574a66b09b0cd6e2a5812e71c91559c3f257587bfc557b4b072a822973a60", + "0xad2cdae4ce412c92c6d0e6d7401639eecb9e31de949b5e6c09941aeafb89753a00ea1eb79fa70b54699acbfa31eda6b7", + "0xb504cb87a024fd71b7ee7bed2833115567461d1ae8902cccd26809005c4a56078617ec5d3fa5b29a1c5954adc3867a26", + "0xb8876bda1e709ab16e1347a1107852a7898a334a84af978de39920790b4d82eb0739cbfc34da1c7154dd6e9f7674759c", + "0x973dcf44ab60f55f5d10a8753ea16db9faedd839466a130729538f3a0724f00f74b3ca1de16987d7c6e24e9467f62bc7", + "0x94df5fe87661101a89b49091a3d4de89331cdbd88531ebb08a95f2629886ee53b3dcbcc26bb6bc68b443303d8d397141", + "0xa92beb343caf6a945990adcf84302c55d1fccdef96c34a21f2c00d3e206a9b2c6c6b412f66e5d4fafe26ef6446cde705", + "0xb298aa927713c86adfe0de1a8d6f4083b718c8be27156da9fd11abd8edb3a54a926ad487801eb39cfc9363a0a3be0d44", + "0xb34d4d2e15079e7e80fdba30cddf4fc0e6c9a61f7ab06a6ea0a4e55fd5bf632c6d72e021d6264d935439d321de883bb6", + "0xb4a86fb5b0049718caead1bc036833a2caeb88e1afadbbbcb0cd021d95e1f33fcc916f0b97fc1b9226c37050e3463796", + "0xb6cec65e5268818c82c0a4a029b02f8d23de98b68730a445119fee670118eb34027c23c987fac950f9b0151631328a4e", + "0x880b4ef2b278e1b2cccf36a3b5b7fbce94f106ed9fa2820cb9099a7a540a57e9fdeef5c0fb0a743049828fc2b8c46163", + "0xab2053c376c6bd113b89fdb2ae3b8401aa891135345885730c61cac7813f69ea7d906c531be752e28657f73af92d1f4e", + "0x8fa2d7b22af8e6b82679ebdfa13efdcb34289a554653ea6c1b16efb9f957f7fe64df787e7b03d8cdc8a732b91c916bd1", + "0x8e825c03c8409a3302266dc5f47fbfc381dfbafbadc37bd8d40f079ca8963d4c5ae6ef0d0ba6aef2d4688736f5f6bb45", + "0xa40ef3d2291d8782540961ce285054678b3d322d3cf7fc154207228c290708b1abfc37a4d7762dab3dfea582a112444a", + "0x8dbe8fcbcc414eb352245c52549973f73d987012de9d5f2b2f55dfdc43cf8cc9ea6b147abf149817f80f9e15aea566c6", + "0xa7e8775e04214e3b9898ffb9625dc8bcd1b683e333acdceddb8ca6db241df08a7b80e9d476a711b8b7d66aefca81e9cd", + "0x8b6ed54668f78a4a7624683b9bf3abf2bb0b6dccffccd8c0967df6297dadaf51732800fb9832b069437a6bf82ed7e6ae", + "0x9437ce85146202d3815df7f341a182678665dfb74b96006dc9d6acc16110d00b4a02717b702a765566457710ff5a7280", + "0x86a790072efa2cafa97be4b6b31f8c533f3b20cf3922fc0285fd403da436e4c49c65c5f08d77bfe823526c67bb58fab6", + "0x8ee8873de7cd28a54ba2c63a80b63399effed76b154e96ed26e7c0668b9f2476e298688b6a00c4b2ab9d020a897695d7", + "0x975c3261f0f32d59473e588f89593be38f5694cfa09394a861e4330b7800fb2528ea832106a928c54c76a303d49140e2", + "0xb5222582ed6604b9856a48039bd643340f4bf1bf0fc805e8453a9eb7630d6cea1452d28536706d6fa3ec16617617991c", + "0xb75c28941ee3f91b3535b4eaa0fb17b59ca65b5256601a1f6d0cf2bb4d66837fd16e51d6942856679012a5730a66e519", + "0x97b510f9f46bdf77a002b2403d8e42b6d6ad5329ea080940844429763ad3efd592652789c8d3d4fac0903c705f533cf7", + "0xa3fd9d8bbdc98394883022299fd9793e0c4f374d8e40d6ce89b2869d3173cb6a5476371d6095dad068ff217729f60af4", + "0xa57d5de556853484b1d88808d2529450238bc467376ded84cfd7b4a1ba258f6d43b5958220f962c57b033abcef1d5158", + "0x8465bd8be9bd9c2c6116d4ae44ec6618c109cb9aaee2d241e7a6ed906d398ef15a6fc18bc8b1d3398184241405954bba", + "0xab1cc44983e46a6ea2430aa6616ab28614f43624665e3e6ae31a9357c0c5434f34e56c720906e184327693cc4ebe1fa2", + "0xaafe14dd3b680f096010788226d8413ca628feedad79a2bc78cb04d47c6ad910f7f46ca87b8f8281744625d8f42d5eea", + "0x86a533b02ae929f67c301649a2d58651b98cdffe731b63fa32aa1013c271634bbb088c0d02865913c11bbb1bf57c0e12", + "0xb28df3e04bde4ec373171401dbd0546f4cb6fa8e9a4a8019aadc653d4e05e0b5b9a64417715dd87f6df9e7b3145f6659", + "0xac63fc758c1a3bc5cbff0f5e0b5a07a5aa801363b129d4e0360165c7dc1057ec37b0d808e9fd6b179e2c1e66bbc6090e", + "0x93f941b4fe6c05621e7a651b87669eefd60b6e8a4a8e630a51fa3fee27417b9eebce39f80a5bade9ca779133ad8388f6", + "0x96d7a69eaf2761bf0e5ebcd607b134d5dedba8e262ca1d6d3e8fbf23e6419a8ce1bbe4cd23b9e4b5f80db54a802a9795", + "0x8b62902fb2855300580e94830a4bc825d997ede33bf356fe3b7c08d6a8bd85a37879433fc6bee58f9b44ca280f4e8dfd", + "0xb043156fcd02b75dbe940c763fa8e8a7c7f6d74c1d5395db5ce544af3b6097eab61686950535a810aa95889ced12f74d", + "0x8614a7599c8d97aa9ca63b876f677977cf0daa969ff2a9a153f297a4a46e08fa5d91492995de94dc32cf009ce6bb5b5f", + "0x81351fd284d6d07092875f366bc5e53bfd7944b81eece85eab71a00443d1d2a9fc0337aaf34c980f6778dd211caa9f64", + "0x8c722aaf5d5dad1845056bf5e56dbff0f8b501f4846610f99da01130a49c96db9962bfd9be20670658cf276cc308be08", + "0x8effe3fb27c9f76bbd78687b743b52e6f3330eddc81bc9006ca81fd640f149d73630af578694f4530833c2151522dcc1", + "0xa3d327f48eb34998a3b19a745bca3fade6a71360022c9180efb60d5a6f4126c3f4dfa498f45b9a626ca567fdd66ffbff", + "0xa59a59db246f981e9c8e54aba52898c714d9787fef8969a6d8677fe6dec82950ff22a1364393b579f3e596cdf5bcd7b1", + "0xa15ebe9ab6de62a4d1ff30b7fc58acfb14ea54d7fa513cbcb045af3070db22bf9c1e987fa26c0c54356b9e38fa412626", + "0xb58396bce7d32ba6c70adbd37156d859e153c1932d2b0c7c874a1182ba831439e80d6fc6d7d88a870e193f515aef2264", + "0xb666dae42ea858c9b7d903ea3ca5279f619c71ac6e3fda7469e2bbba08c7e8e12d6a3c35ff2c6383673b1b7c21db5e0e", + "0x8eaaa21c8955f15bbcfd5756421a045e7b4825576379cc6229fe9751f7a7738b90be19ba52261db01c1e13af955675b0", + "0x8027bc62b59f9f15613e38da74ccc71fc3eaee26f096d187c613068195ce6eb64176013f2d86b00c4b0b6a7c11b9a9e5", + "0x8275eb1a7356f403d4e67a5a70d49e0e1ad13f368ab12527f8a84e71944f71dd0d725352157dbf09732160ec99f7b3b0", + "0xb8c41c09c228da62a548e49cfa107630166ac5c1469abf6d8aab55938ed1d142d5ddbc4f1043eed9496e9002cac99945", + "0x912750d2f1b21756662a400236f797b8ba76c73e5af95941a8c6ef9427838c4826715c80942cf8cb7ed01566bc490754", + "0x862af7dbb38ad7293a4e598cb52a8ac84dacee3d9bf007b5cb6a18a1acead0aa33f6dba796ce630e632c97aeb7100d68", + "0x890def696fc04bbb9e9ed87a2a4965b896a9ae127bc0e1cc515549b88ddbcbc02647e983561cab691f7d25cf7c7eb254", + "0xb835ffaf54c8b878d3c4262ca2bf5e6be2c691adced622b35d998ed72e1467ba907f4fde8d64ce43b43a8196f48e55db", + "0xa6d7e65bf9f889532090ae4f9067bb63f15b21f05f22c2540ff1bb5b0b5d98f205e150b1b1690e9aa13d0dee37222143", + "0x8ebfbcaccddd2489c4a29a374a2babc26987c3312607eadb2c4b0a53a17de97107c54eab34def09144b3098c082c286b", + "0x900b9972180a2c8753f5ff49fdd2cfe18c700d9927b3c3e16deb6376ad6ee665c698be72d4837b94911a0b4c183cb140", + "0xaa9679c01ecf1f1452c54688e01cb25bf157bde6b09b1ed460b8c175d65eba439c7ad4b7c1d72415f5622f3fbc068dc8", + "0x887a4277ee8754733f3692a90416eeac1ebee52ff23173a827f0ba569bd84efd806eb9139049f66cc577e370d3f0962d", + "0x951b27456e2af80436608aadec54ebd03bda37fa58452631da63bc5ff3eecb5ffb73d356b19f6c9c4225fcb0da8fda20", + "0x9104b5af82dbca914370eadb5518b26bee7ed7edeca74b741585ba8b249204e2c998bd47a02cef4335e236f8efafef94", + "0x8757e9a6a2dac742ab66011c53fa76edb5ebc3c2fbd9a7265529a3e5608b5c24b4482fed095725e9b8fed5a8319c17a4", + "0xa7acf82999de75f231fd80770bcb0f4c720d6b1e4a2558fa1ce854382fda92beb89fea5b5d229dad85fafee7a9e98329", + "0x8fb74891a8642f25a55b5eda5818367aac2fdf9663ad1e3dbc0166b484c0cda581b243cc75131167f1afa9caaf6705a0", + "0x897d7a19b70dcef1af006df3365981d73068c81f18017f32fb9966599481496efd5f6caceef943b31c52750c46d9590d", + "0x87ac804ccfe7f1fa156b8666664a397236832569f8945e11d4688a9e43ada4d4104efb3fda750f48ef655a29357c5e7d", + "0xaf18cf1e3d094b4d8423da072f98b3023d296f6a1f2a35d500f02bde522bb81dc65e9741c5bc74f7d5613bd78ce6bc03", + "0x9752561179783f336937757b619b2fdcb9dfce05aa3c4fce6d582dc966182eb85ab4ccb63e7e1736a7c5fad9d33cccd2", + "0x89e19b665ce7f6617884afaf854e88bb7b501ecdd195a5662c79802d721f5340eca8c48341ad1d6c78f519f82e5a9836", + "0x94402d05dbe02a7505da715c5b26438880d086e3130dce7d6c59a9cca1943fe88c44771619303ec71736774b3cc5b1f6", + "0xa76adeddf2454d131c91d5e2e3a464ef5d3c40ee6a2ab95e70ef2e49e0920d24f9b09276250ed7b29851affbdbc7885a", + "0x8934e9a3feababa12ed142daa30e91bd6d28b432d182ac625501fe1dc82f973c67f0fe82d39c9b1da3613bb8bfe2f77b", + "0xa5c11337eb91ce0e9b6d61bbdadea0a063beee1bc471cc02dc1d81c5dd2095315c400cbc6c33d23c77e98bba6bdf5439", + "0x92d00e64ed711951aeb852908aeb6fd379ea516872dd512384b1e773ef078e52e6d618beb202d437d2a46bcb78087f7a", + "0x97f1a7370b4f5acf83b466f519da361c366915f560385dd7eff9d53700ad81b25c9862bc71d35428e82372a5ae555ea0", + "0x95614544f65808f096c8297d7cf45b274fc9b2b1bd63f8c3a95d84393f1d0784d18cacb59a7ddd2caf2764b675fba272", + "0x8d474636a638e7b398566a39b3f939a314f1cf88e64d81db0f556ca60951ec1dca1b93e3906a6654ed9ba06f2c31d4ea", + "0xb87e5f481b938ac8a481b775cc58be2a06604549e3c810fc4734bab76099e5c617f0243c4c140cb7dd6d36a6dc2286bf", + "0x806efb61d1c948efc10dbf9bef30197d1c269e5e7fcf20a84367b26223d33fade413a0bbf4e33f0d1f1a00967289015e", + "0x880b99e77a6efb26c0a69583abb8e1e09a5307ac037962ddf752407cacaf8f46b5a67faf9126bdbcb9b75abf854f1c89", + "0x82ffe4de0e474109c9d99ad861f90afd33c99eae86ea7930551be40f08f0a6b44cad094cdfc9ed7dd165065b390579d0", + "0x941cd102228aa81ef99506313a4492a17c506e7169808c6b14dd330164e9e8b71b757cbe6e1bb02184372a8c26f7ad1f", + "0xae96dc808c316a677977831bad1e529ef965dadb5d6aea25ab008fe7bb1543e596e33052cfbe4279fa060201199d2c34", + "0xa2053719da2b7501dab42011ae144b3c8d72bd17493181bf3ae79a678068dc3ee2f19d29a60b5a323692c3f684f96392", + "0xb17171939519d90e243d41839c3c5ce7ac7e6a978e4a7e56b2c8e6a2b1b587c7eacea47f2e31a55d88555d252c810ebd", + "0xa958987c2b3c84df8176b600f5b75a8badef9653c71eff967e76648937def38826eaab4027a639f4f300b20019166250", + "0x854aafa329e2b2563355641eba95f2aba5b33d443ab16f5e342048f97d97c4e2812ff27c6f4180b8110272f3151be690", + "0x94d4a1e3a3d28a948f14d1507372701ac6fc884a4905405a63663e170831578a2719714ef56f920baa0ca27954823e39", + "0x826be957cf66db958028fa95655b54b2337f78fb6ef26bd29e2e3a64b130b90521333f31d132c04779e4b23a6b6cd951", + "0x8261f7e644b929d18197b3a5dcbba5897e03dea3f6270a7218119bd6ec3955591f369b693daff58133b62a07f4031394", + "0x84926cf2265981e5531d90d8f2da1041cb73bdb1a7e11eb8ab21dbe94fefad5bbd674f6cafbcaa597480567edf0b2029", + "0x8fb51e3ef3c1047ae7c527dc24dc8824b2655faff2c4c78da1fcedde48b531d19abaf517363bf30605a87336b8642073", + "0x8ba45888012549a343983c43cea12a0c268d2f7884fcf563d98e8c0e08686064a9231ae83680f225e46d021a4e7959bb", + "0x973ab82026d360e2cf5676d883906186bc61b43f60767ca58f11d0995e40780b163961e6e096299ccf1c86175203abde", + "0xb77416ea9a6b819e63ae427057d5741788bd6301b02d180083c7aa662200f5ebed14a486efae63c3de81572fe0d92a9c", + "0x820cc2ac3eed5bce7dc72df2aa3214e71690b91445d8bb1634c0488a671e3669028efbe1eae52f7132bde29b16a020b7", + "0xa6b434ac201b511dceeed63b731111d2b985934884f07d65c9d7642075b581604e8a66afc7164fbc0eb556282e8d83d2", + "0xb81821a79c9148b41d24d85dc997336a1e1719da0e31e42af30812b97a5af31708ca3e7bc2e803c3751cff23af5c509d", + "0xa013cc5e3fbb47951637426581c1d72764556798f93e413e1317849efd60f3ecb64c762f92544201eb5d6cfb68233050", + "0xb5f32034d0f66bcbccefe2a177a60f31132d98c0899aa1ffff5ebf807546ff3104103077b1435fa6587bfe3e67ac0266", + "0x86ca8ed7c475d33455fae4242b05b1b3576e6ec05ac512ca7d3f9c8d44376e909c734c25cd0e33f0f6b4857d40452024", + "0xb781956110d24e4510a8b5500b71529f8635aa419a009d314898e8c572a4f923ba643ae94bdfdf9224509177aa8e6b73", + "0xa3f9dcc48290883d233100b69404b0b05cf34df5f6e6f6833a17cc7b23a2612b85c39df03c1e6e3cd380f259402c6120", + "0xa104d4bad69f1720307ed12363d1ec97952acfe09d9e3650034c33f3f20c763271ebe0d5b50b1d3bd15c469f4573b09d", + "0x94bbc6b2742d21eff4fae77c720313015dd4bbcc5add8146bf1c4b89e32f6f5df46ca770e1f385fdd29dc5c7b9653361", + "0x951aa38464912a29df2101c60771d6de7fadb63f2db3f13527f8bdacb66e9e8a97aaac7b81b19e3d1025b54e2c8facff", + "0x919b5187af7dae210f151dc64a9cbd396d1ae04acadebf542a7123004efc7ce00d6e14c170d876fbc64dc1b5d141a5f4", + "0x88e1e459ee5aeb8b36ed004f6d03da296101106fbe1b18f9bbf63e92321db51670c34050fd3b7dc56a4bad76403823ee", + "0x86b3ec14a8ffb811a0ecc3771f600d8b08c098537d100fba66def19e7ee4d1c397a311977bf37e6cd2d47a8a2ee8c223", + "0x898c4873bd356ba8015f6f686d57088fa8f79f38a187a0ef177a6a5f2bc470f263454ee63d0863b62fca37e5a0292987", + "0xb471c72bd2971353f4b44248b8e6cf5316812861a88ccfc20fd0d89a5e010428c387228b2f6f14c12f79e31afc9d0753", + "0x8b7cb5b8de09a6dfceddcbaa498bc65f86297bcf95d107880c08854ed2289441a67721340285cfe1749c62e8ef0f3c58", + "0x983cb6bbfe83bce8326e699e83fca01ea2958c09808c703cac97a0ea777e5a5f3f5bba9169a47732de7459a3c7af47d2", + "0x8235a3f09078dd34ce2fc17cc625e061298713b113dda12d354b3d2ba80e11c443b1dd59c9eb5a29513a909645ae97d4", + "0x8bb51b380a8a52d61a94e7b382ff6ce601260fa9b8c5d616764a3df719b382ec43aec9266444a16951e102d8b1fb2f38", + "0x9579973ee2559da09b327c62b1cc0177f2859872885dca709e24dcfbb9bdf9224a6d26869aafce498f44c0e6bd8a996c", + "0x842ba3c847c99532bf3a9339380e84839326d39d404f9c2994821eaf265185c1ac87d3dc04a7f851df4961e540330323", + "0x99dad12f78e1a554f2163afc50aa26ee2a3067fc30f9c2382975d7da40c738313eaae7adbc2521f34c1c708f3a7475b7", + "0xb96e3ff8bdae47aa13067c29318b1e96a7fe3941869c17ce6662183b7b064bf261e1cea03e2a4643c993728a2606b5b5", + "0x955bc897171aa65d0159aa6e5d51855833f83d8bd5e65f93ad26c27781171783f3988a12bf987472edb39994bd071ea5", + "0xa59249e4dfb674dfdc648ae00b4226f85f8374076ecfccb43dfde2b9b299bb880943181e8b908ddeba2411843e288085", + "0xac2955c1d48354e1f95f1b36e085b9ea9829e8de4f2a3e2418a403cb1286e2599ba00a6b82609dd489eda370218dcf4c", + "0xb2eedff11e346518fa54e161be1d45db77136b724d497e337a55edfc896417de3a180bf90dd5f9d92c19db48e8574760", + "0x976eb5543e043b88d87fda18634470911dfe0e0cabab874ca38c1009e64d43026d9637d39dcd777bc7f809bbfc3e2110", + "0x8ea5f88a79f4eb9e7c0b6b29f8ef2d1cc4c15ed0ed798ab11a13d28b17ab99278d16cd59c3fa8217776c6dfae3aedf88", + "0xb7f146a357e02a63cd79ca47bf93998b193ce1174446953f12fa751f85dc2a54c9ed00c01a9308509152b3bad21d7230", + "0x87fd7e26a0749350ebdcd7c5d30e4b969a76bda530c831262fc98b36be932a4d025310f695d5b210ead89ee70eb7e53b", + "0xb9445bafb56298082c43ccbdabac4b0bf5c2f0a60a3f9e65916af4108d773d62ffc898a35b0b8efb72ea846e214faa02", + "0xb106c6d13ca17a4c8ea599306e84918127cf2de21027ac3fe5a57d35cf6f3b1d7671c70b866f6e02168ae4e7adb56860", + "0x9276e8051bed8f5dbfc6b35765aac577dd9351d9d6ac1bb14496bd98091005b9a4737b213e347336413743f681f5043b", + "0xaefc682f8784b18d36202a069269be7dba8ab67ae3543838e6d473fbc5713d103abcc8da1729a288503b786baac182d3", + "0x97578474be98726192cb0eac3cb9195a54c7315e9c619d5c44c56b3f98671636c383416f73605d4ea7ca9fbeff8dd699", + "0x99c34f9bd0fcb18b3d931e562988cf91886a417f8678f22651bf3cf138df2bbec3f675de90f62dda769e0eda03d72b7e", + "0xa0047e03c89a95248543618e6b7ca2c7aad7acda3c9f85771ec5c93fa898c651e8b2ea3b6b799d8cd592290a986cdd7d", + "0x993726e0b1c2277b97b83c80192e14b67977bf21b6ebcde2bda30261aa1897251cd2e277cfcb6193517f1eb156d2fe86", + "0x974a5180e55eab23d4c973fbee6ad1010335161ecdb849fe6520b34c1f96530a4faff80bd738fe281019b79d968c472c", + "0x8f1d90034f998018c3f4b5947b40b139fcead2e40aa80fdec6a4337c60e9d5ff1923dda7f0b5b1731ff16f55027d41bf", + "0xa7d9ae9621dd1f3da3cd2d435e891cc3579c4c0d60d6a4565cac86c315cea21a9ad883559fe7b897ae6e05f1aa989ad9", + "0x800f6be579b31ea950a50be65f7de8f678b23b7466579c01ac26ebf9c19599fb2b446da40ad4fc92c6109fcd6793303f", + "0x86fa3d4b60e8282827115c50b1b49b29a371b52aa9c9b8f83cd5268b535859f86e1a60aade6bf4f52e234777bea30bda", + "0xa80ac2a197002879ef4db6e2b1e1b9c239e4f6c0f0abf1cc9b9b7bf3da7e078a21893c01eaaab236a7e8618ac146b4a6", + "0xb4bf70468eff528bf8815a8d07080a7e98d1b03da1b499573e0dbbd9846408654535657062e7a87a54773d5493fc5079", + "0xae0e15a09238508b769de83b30582cc224b31cd854d04fdb7b8008d5d8d936dbdd3f4a70fff560a8be634c141772561b", + "0x936f7e20c96b97548fef667aa9fa9e6cfdc578f392774586abe124e7afc36be3a484735e88cc0d6de6d69cf4548b1227", + "0x8163eea18eacc062e71bb9f7406c58ebe1ce42a8b93656077dd781c2772e37775fe20e8d5b980dd52fdad98b72f10b71", + "0x86a6560763e95ba0b4c3aa16efd240b1873813386871681d075266511063b2f5077779a4fe49ffc35e1f320b613b8c94", + "0xb156d9d22722bb6e3b75b3b885b64642fa510ba7e6057657cd61bac43fb9c284d05bb09e2d4b78a2a4ddada85da9c702", + "0x9779ca2759dbed8081f0cbbfffcb3b842ba335e3ae48a60c5e5c77c7a2a0623e4c415ec3a023cc4e216885fcbac3ce52", + "0xb8137fd57ce7d3cfaf8bdbaa28704734d567d0e7a2d87fb84716722c524bb93acb2c1284249027f3c87bccc264c01f4e", + "0x8cf06b34e7021e9401eb705dde411ecf7e7e7185f8c0b0aeed949097df31812a9fdd4db7d18f9383a8a5a8d2d58fa176", + "0x8c65aa29a9ee9066b81cf24cf9e0beca3e8e8926e3df22d5ff1236297e158cc8bc7970a2c7016009cc4efa8f14b14347", + "0xac7e49f2059e99ff65505742978f8d61a03f73f40141a2bd46fde5a2346f36ce5366e01ed7f0b7e807a5ce0730e9eaa9", + "0xa1c25eb9b73723982be78180770aa63c5f7b23c2e54a2ed7e75a860c4512d273008066f1124ac8a43c60fe1e2a8bf03c", + "0x9310722e360a5652737362f6b9cb6e9c3969a0c9bb79b488b3c7d19d9e8c42ebd841df346258ded2e393895c99b413cf", + "0x893272a63650b08e5b8f9b3f17f8547b456192ad649c168bafd7166b4c08c5adf795c508b88fd2425f7be8334592afb2", + "0xb576c49c2a7b7c3445bbf9ba8eac10e685cc3760d6819de43b7d1e20769772bcab9f557df96f28fd24409ac8c84d05c4", + "0xaf17532b35bcb373ce1deebce1c84abe34f88a412082b97795b0c73570cb6b88ea4ba52e7f5eb5ca181277cdba7a2d6d", + "0x8b8813bd2c07001a4d745cd6d9491bc2c4a9177512459a75dc2a0fa989680d173de638f76f887de3303a266b1ede9480", + "0xab73a043ccdfe63437a339e6ee96ef1241264e04dd4d917f6d6bc99396006de54e1e156d38596ba3d15cb1aaa329f8f5", + "0xb67146b202afec0132ac0070c005cf664081e860339f8f4d45ac3e630dda05560936e646673e652d08cecd8d18fc64da", + "0xa750404e9d4b1a48f767d2b6aa699200c92c3b8102597f8c5c1dbaaf08112a0587c05801dfebb3612fb6dfd76ddc9ccb", + "0xb0d4231814e40e53ab4eed8333d418a6e2e4bd3910148b610dec5f91961df1ad63f4661d533137a503d809ea1ad576fa", + "0x81fc724846b5781f3736795c32b217458bb29972af36cc4483dd98ab91680d3d9bc18842db2661487d3a85430dc9e326", + "0xa5cf6f4fd67aecb845eebc8d7304c98c69806d774d4c468350f7f82ff0f5baeecc56837705e39432a8d246aa2a7075ed", + "0xa71d2c8374776f773bad4de6edfc5f3ff1ea41f06eb807787d3fba5b1f0f741aae63503dbca533e7d4d7d46ab8e4988a", + "0x825359cfe68ad6a75578a94be6419179e0aa088170b6c20fc5c249dc3be7a260d687c93d8d8a343c7c72c2ed6a716de3", + "0xb6aeb7a9b934a54e811921494f271d5d717924c561cd7a23ab3ef3dd3e86184d211c53c418f0746cdb3a12a26a334fc8", + "0x8c6fc89428c74f0c025e980c5a1e576deadf8685f57136e50600175fa2d19389c853d532bb45a3e22b4a879fab1fcb0d", + "0xae95ddcf3db88f6b107dcf5d8aa907b2035e0250f7d664027656146395a794349d08a6a306ce7317b728ca83f70f3eaf", + "0x8c03fb67dd8c11034bd03c74a53a3d55a75a5752ea390bd2e7f74090bf30c271541b83c984d495871d32c98018088939", + "0xb8d68610fdee190ec5a1f4be4c4f750b00ad78d3e9c96b576c6913eab9e7a81e1d6d6a675ee3c6efac5d02ed4b3c093a", + "0x87d4b20bbe2dcd4f65f4e1087f58532d5140b39a5288e1a63fc0b7e97a6a56946eafdd90ba09300c3d1fef6356ac6b7c", + "0x83e264b1d3d4622826ab98d06f28bbbd03014cc55a41aaf3f2a30eec50430877d62b28c9d6d4be98cb83e1e20f3b13db", + "0x97ffcbf88b668cde86b2839c7f14d19cb7f634a4cf05d977e65f3cd0e8051b2670e521ae74edc572d88201cff225e38a", + "0x91efdbcaad9931312d7c41d24de977f94d7f3f7b88090a1f72d9a097a1e30cc805c5ea16180f463022d9b26b8863f958", + "0xa4b507a4bc2bc424297bf8968bf385fae3acc686cff4b7933b4f5b6ef3149995393d5331dbac4b629e8adce01a91a4cc", + "0xa76a26c30d8abbbd4bf982bb8bd2066a2ec823a5eb6fbe37c664e67efbe2f72d8ce2d00223b900699149f8441bff5ada", + "0xb3a5497365bd40a81202b8a94a5e28a8a039cc2e639d73de289294cbda2c0e987c1f9468daba09ea4390f8e4e806f3c8", + "0xa09b2a07d861e01645accfb088f7f9ad524186bd439712775459a60f8a1fbbd43ee084e4d6e23ffce06daa189cd1e654", + "0xa41cf5d678a007044005d62f5368b55958b733e3fdde302ba699842b1c4ecc000036eda22174a8e0c6d3e7ef93663659", + "0xa698b04227e8593a6fed6a1f6f6d1eafe186b9e73f87e42e7997f264d97225165c3f76e929a3c562ec93ee2babe953ed", + "0x8bc66e370296649989a27117c17fbc705d5ac2bda37c5dad0e4990d44fcc40d3e1872945f8b11195538af97961b5c496", + "0x8bff10f91b8c0abb6c9542588da17fa0118ffda4c82626a754887e333d7d69661b3ae4e400da15c49565f8d10a77d0d7", + "0xac715c7b3d794860a61d9c7bd224a2b14a6023f696afa30345aad2ce0a6ea6dbc142f34af1ffe7f783542851a28e8ece", + "0x91c5e0b9146fe5403fcc309b8c0eede5933b0ab1de71ab02fac6614753caac5d1097369bdeed3a101f62bbcae258e927", + "0x8553748da4e0b695967e843277d0f6efeb8ba24b44aa9fa3230f4b731caec6ed5e87d3a2fcd31d8ee206e2e4414d6cf4", + "0xac722bd742374f925185ea7d4d62d7510b2d8a6ebf5c750af6ce83e2d8a28c95a3e298870ec8254ab2d1d0aa2a063c60", + "0xb083c4cefb555576bb37b71f30532822cb4b1e1998e35cb00ffb80ca14e2853193c16a6756417853d4a74d625744dd76", + "0x85745bd84c92ddfc55df11fe134cf70e3c340aa1c7cdd6188a03308cf3a840f4f19629f9730b2e6426424989ff03000d", + "0x845b4531dee808b583645f56fa98cbdecce3ea100db60524b64f68e29866173791f01137714f4dc7fb8612f7f7943263", + "0x93f03495d53c781be8b76e37e68b64aa260523004eff6455ddc8a8552af39854e5181f8c5365812b1f65926534fba5dd", + "0x801c126abff96fe9b042be8869d2907d0c6963a79901f9db46577a445418b7465a1f4b346933d433e539536a9a2df01c", + "0x952cf6782b0ad3e85625391cc5f486a16bb5b1f8ea20defcb6857bd7d068dcd2701bc7ed5c3b773a869180d9042f772b", + "0xb3b6eccb2ec8509b4eea8392877887180841ab5794c512b2447be5df7165466d7e293696deaabf063173e5f2238ce763", + "0xb63fd45023f850985813a3f54eceaccb523d98d4c2ba77310a21f396e19a47c4f655f906783b4891de32b61a05dc7933", + "0xa113b889be5dcc859a7f50421614a51516b3aadc60489a8c52f668e035c59d61640da74ba1a608856db4ff1fa1fe2dfd", + "0x87fec026beda4217b0a2014a2e86f5920e6113b54ac79ab727da2666f57ff8a9bc3a21b327ad7e091a07720a30c507c9", + "0xa3ee8fd53158dad3b6d9757033abf2f3d1d78a4da4022643920c233711ff5378ac4a94eadcaf0416fdcca525391d0c64", + "0x8d6bed5f6b3f47b1428f00c306df550784cd24212ebac7e6384a0b1226ab50129c0341d0a10d990bd59b229869e7665a", + "0xb549cef11bf7c8bcf4bb11e5cdf5a289fc4bf145826e96a446fb4c729a2c839a4d8d38629cc599eda7efa05f3cf3425b", + "0x982691766a549df56436acd0fe76da78132e027515f27174c10d117bfcc20ed73fc31f5465bd7a22a101094fe913e221", + "0x985af1d441b93fa2a86c86b6d7b70b16973d3971e4e89e093b65f0ae626d702202336869af8e3af3923e287547d5384b", + "0x994b7baecc8bb68d270a3a88c58e4054afdbd713b4472f9522b27c1762c637ef8f013d745ce9d1dc8fc4d986d4c9338c", + "0x827dabda84c7f7b1adc0f5ca0fccf0729e9d7f78e1ffa7c5e9c4f66610ff0ab776c880b00c77137cf7abe14df977febc", + "0xacd17cba1203748b55bd9d7b940a16bb7c02988c93007a80b87e0bdb049b91f5ecce577e3e4ea68a0abe998a72cd300d", + "0x989fa046d04b41fc95a04dabb7ab8b64e84afaa85c0aa49e1c6878d7b2814094402d62ae42dfbf3ac72e6770ee0926a8", + "0x99dc48a054f448792523dcdeec819e1b928b1bd66f60f457261f0554f8532eedd7152792df70ae5316ab2f9c02a57cdc", + "0xab33c65587ecb3278325948c706aed26547e47ed2b4bc027e9119bb37bec67ddf5489fbc30304ef6c80699c10662d392", + "0xae89e41d8cfbf26057a4078f8a5146978e658801b08814190cbce017d79beaeb71558231a72bde726fa592fb0828c01c", + "0xa9901df92e2d3abbb25f3bf4b913692c4cd57da327b01c8ee2362c02fbefcf66cdb792c17a81dcbde3c9b9dba313e4a1", + "0x8ee41011424da5e2ecea941cbf069ea32420749f2519434d3d8f9725ac789753404687a6745cffe4bd5dfc8fec71a719", + "0x8cfcdfa192b17321be4e447204e1a49ecaadca70a3b5dd96b0c70ab64d1a927d1f8c11a7e596367e5fa34e2307af86fc", + "0xb8a0003e949cf994b1bb25e270cb61358200c93b1c6f611a041cf8536e2e0de59342453c5a8d13c6d4cc95ed8ce058f3", + "0xadc806dfa5fbf8ce659aab56fe6cfe0b9162ddd5874b6dcf6d658bd2a626379baeb7df80d765846fa16ad6aad0320540", + "0xa83b036b01e12cadd7260b00a750093388666aff6d9b639e2ce7dfc771504ef8b2090da28ec4613988f2ec553d1d749e", + "0x825aca3d3dfa1d0b914e59fc3eeab6afcc5dc7e30fccd4879c592da4ea9a4e8a7a1057fc5b3faab12086e587126aa443", + "0x845a4a09941f48677e6c03699770f9a56ba72695089e432a6f232294dd8da6d34e394116a9a87f3b0902c78332af9439", + "0xb2f168afc35ed9b308ab86c8c4aaf1dcd6833ce09153bb5e124dad198b006e86a941832d387b1bd34b63c261c6b88678", + "0xa094cca9d120d92c0e92ce740bc774a89667c6f796b438b0d98df0b7aef0935d8c915d5b0dad4b53e383dc9f095c29fa", + "0x956ecb233b3529b2d9cb80ae49e48667f2a3120e4a0d7131d1e9ec36db3a59dc2ef2a579cbb99d6f14880ca83f02b64c", + "0x906cde18b34f777027d0c64b16c94c9d8f94250449d353e94972d42c94dd4d915aa1b6c73a581da2986e09f336af9673", + "0x824c8a1399ab199498f84e4baa49ff2c905cf94d6ac176e27ec5e2c7985140dbaa9cc6303d906a07ab5d8e19adf25d8a", + "0x889a5cf9315383bf64dfe88e562d772213c256b0eed15ce27c41c3767c048afe06410d7675e5d59a2302993e7dc45d83", + "0x95791fb6b08443445b8757906f3a2b1a8414a9016b5f8059c577752b701d6dc1fe9b784bac1fa57a1446b7adfd11c868", + "0x99049e9a23c59bb5e8df27976b9e09067d66e4a248926d28171d6c3fdd1ab338944a8b428b2eaae5e491932c68711c7c", + "0x95c810431c8d4af4aa2b889f9ab3d87892c65a3df793f2bfd35df5cfdb604ca0129010fa9f8acae594700bece707d67f", + "0x841d77b358c4567396925040dffe17b3b82c6f199285ac621b2a95aa401ddb2bc6f07ebd5fa500af01f64d3bb44de2df", + "0x90c402a39cd1237c1c91ff04548d6af806663cbc57ff338ed309419c44121108d1fbe23f3166f61e4ab7502e728e31fd", + "0x968d44188e2d9d1508b0659e96d6dabd0b46aa22df8d182e977c7f59e13aa05d5da09f293f14f6f2ee1b996071cd2f25", + "0x8ae9585caa3c73e679fe9b00f2c691732f7b7ca096e22d88c475a89d4d55cb9fba3cd0fe0cedd64ce75c591211664955", + "0x94b81d5ad72efb4dd60867e71afcd8e87e1f24bf958d42fc07db66f6185a1e610987ab9ceef63109a36fe5544a0cf826", + "0x8499a8c3d67d1f6eccf1c69274393dc498cff862ea8e6c11ffb8107ae190d258ddc1d294f2a8f050488df0212063ece2", + "0x921109a390e4d7fbc94dff3228db755f71cb00df70a1d48f92d1a6352f5169025bb68bcd04d96ac72f40000cc140f863", + "0xb464d763e5ef724ab7ee13a60015df5c9a7809a79188ff6a7e0d5e5400febd42ad7330406a59704a44a08f2289d659c8", + "0x96f1a36134e0d4137a7fe8bbb354f50aaa67f28f194ae2fdbe8be3eb24596678d8c9287765ee90c1f2778d0d607931e0", + "0xb031d93b8f119211af76cfafee7c157d3759b2167ee1495d79ad5f83647d38248b4345917309ef1a10ecaa579af34760", + "0x88a7dc337d89324f025f686f37d21240c7da9a1cb802259ea8d8a83e246dcc2adceca7ca3534bc7bf8f3ae1cbeafb5c0", + "0xb30e022b8a563655074e08e123b5f96956bbf0fe221cc629c5fedd2764a66b475916ceb98867f935b4a47212e53ae9f3", + "0xab6e3180dae399d41243f23545e5e6d118844f9b8edba502a3503fd1162ed826f9fc610889a1d685d374b6c21e86067d", + "0x96cf5760c79cfc830d1d5bd6df6cfd67596bef24e22eed52cee04c290ad418add74e77965ea5748b7f0fb34ee4f43232", + "0xa5817c74a394b0359a4376ef7e9e8f7dfa6a7829602da225074fb392b715e1fd52c50cae0f128a7006f28b22f233fbf5", + "0xa50ab79cf3f6777a45f28d1b5cdad2c7ea718c60efeeb4c828d6307b29ef319445e6a9f98aa90f351c78b496575150c1", + "0x8b300dea07e73dd2f07b05d477e51f8424589f6b2fa6f461240e1322a3a7ab5bf227b74544bb5d66a297702cdbf6c6bf", + "0xb13b5cb86dc8b8fe87125f1a51fe98db36bdde4f600401408b75059a44e70b1bbfefd874e539691f3f1bf6f54db883c8", + "0x8d06205cd66703ce6776b38b98c32b27f45c7b3f65ea2d05e2b702c24d553f51c69bf0b17e8db7382475e3d370d2e8d6", + "0xa11a7496c712734aec80738e30d2bf245758b34245076149854eb209fa6403be8bb0d4e515becc881b7f3610749260c0", + "0x9615800f8c95f95bf25055ae079b964e0a64fa0176cc98da272662014f57e7cd2745929daf838df0094b9f54be18b415", + "0xb19ca6e55f349bbb2dc3e429520ff5b2e817972470794f35c1aac8c118b37a694cfcc875b6d72225343799825d2f5c39", + "0xa650864b7eb6769aaf0625c254891447351e702e40d2be34dfd25f3b5367370de354318d8935ba18db7929270455ae6a", + "0xa649208372f44f32eb1cd895de458ca1b8be782746356f08ac8ef629429d0780a0799fcff85736e19aead0b79bfff261", + "0x89461cb2dadf51d6f1208b0965c8eabec895d7b19b7d90d3c6e49dbe75a75c30fd26db3dfb169dd46a4342280225032a", + "0xb5d6f664ec92e5343792d5d6b629919c5fd8cfb874677df2264daf02bcd9d12facf9b859d5402839c9022396e20d260b", + "0xa7179d338fe5a0e4669364a364e17f8d00cb6c59a80a069afd5f4f14510df2eee90c07826553e4f7fe46d28f72b2903e", + "0x8ded37d67b5368619a090266e9b5585fbff60319a90a4244a3c3342641f5bfa5130998dd97d7a42505cd896c29255530", + "0xa3fd63e87a00b48ba46a646a26187ae6dcb16779721973ada13a545853e2e51b5e4df04630d670884ad4a2304cc60c67", + "0x92761b7e31f0c758b3b1f5b43a194b25aabec668101946eb6511132863d3afb9d18f833d43a8338d0e7bc78d8689e523", + "0xab8a8769c754008a7976b6799e81d7bfe97413d0a79b90715703c1f8f567675463ec93aabee59277121fc4df88b5c7a9", + "0xb354d0d1bd942f79002a2eaf37eb99dab650170e7040c13c824803ed7c1670dc910ccae13bbe58bde003829b140b45ea", + "0xb9eed89e003894ad2cc9d9b93a45247e1367ac69a00b0ed5e3280c1188b4cb90eb870d449b83a852a798bd02f9d0c813", + "0xb900a55013d0427e5da6b21611d6ae3e648f54f794cb099b2d2beebae0a957477a94dc415e8ec5e68e9029ce50d43843", + "0xafbf44071c2c905f7c8ef396eaed7f13deb7a91719cb5e8b9226aaceb876d81a10076383edc6216bc2f5c38a480b2957", + "0x80bdb82b7d583bf1e41653966b0ba3b4fec0e7df2ff08e3fa06fd9064bca0364263e075e1582741a5243bde786c9c32e", + "0xa841fe9ff26db21ade698f6dbfba025d90ae9f81f02af9e008fa0a429b993fb04d06acb93e40a9f81c78f73334555a17", + "0x8cd49711b42af58a5aae75a38fea9ddc5e4183c467a3159b5b0629f01ba548513c577456d34c861911e85782e52c3b1b", + "0xa322b5d2a6e3cb98b8aaa4c068e097188affef5dec2f08c3e9ce29e73687340d4e5a743a8be5f10e138f9cabbe0c7211", + "0x942772b7c7c47d4e5957ccf1d6f1450070930af3e2b7eaab0dd7699372445df0cc910e6c0efcf501887dd1adabdaee23", + "0x9834f66e5c946c3a8241ca2bbde046a7e88072124911d5d15c037a95b61e82b88b5c2058fa4a3721537dee39dee5da18", + "0xa90cc5b9c4d84f36962d0d55d5bc123dbe5ec5f4fe7b6bf0d009028b3cf14e36c11bc5365391cb4ae548d5eb04fe371b", + "0xa7c2174eea2b66b2a71cc8095fae39c423a353c7d5020ec2d0551317a66202fcf082c6119ba768755523fff49791bb4e", + "0xab92b2a177dfa55d202a653532f0e04d1339ca301aebe6a0e8419bf45be3e573b6b9ae4d3d822cc8279367a3d2c39b06", + "0x8a9ad977988eb8d98d9f549e4fd2305348a34e6874674bcd6e467c793bba6d7a2f3c20fa44aabbf7151ca53ecb1612f6", + "0xa7d1676816e81a752267d309014de1772b571b109c2901dc7c9810f45417faa18c81965c114be489ed178e54ac3687a1", + "0xa575be185551c40eb8edbdb21a0df381c801b6e99467fcf5882dd7cb34916960ce47ac732c1920ad3218f497b690cef4", + "0xb50c306f78143b37986e68efa10dbe1fb047d58562e9b5c5439b341dd8f1896c7ae586afac0a3213759784a905c1caaa", + "0xb31e89b4a034c1b73d43b3d63ea3bddea682a6a5327eff389c70b13e9e72185b0327682a0cb1ff3c4a4f8ba08b13d898" + ], + "aggregate_pubkey": "0x948a4b8d91bd29969cd4470b1bc24d34586d38e73d5be71c98a9894899471a5f708747563276b4b6d2716fdb72860267" + }, + "next_sync_committee_branch": [ + "0xcb3fea582872d90706ddc6d029bac0d791ea75d43c3ab04f056f62a11b89d27b", + "0xf26b4bb68eb7e6906c8ef4a9958398a48e4450bf9c8a462fafa4fde51cd5628f", + "0x690925f92c1d322d2ff2a5636539094825dfd2c9bf7538fe111b2358e03a71de", + "0x51d977e358166401c7cd3f6185468c1a8c69a4c3d8577535dd583bc427692e02", + "0x88d2089aaf2f6fd8f6e4ae499c6fe33cc34289eb9310780861e772204f07b670" + ] + }, + "finalized_header": { + "slot": 4055040, + "proposer_index": 854, + "parent_root": "0x8adf3b288deb17566a553fa7a06a2f63f4ac4cea4868af4d89ddca41f73ae9b9", + "state_root": "0x595e9ebaaa23f027672b4d2a33173a22b2839baac709c7f8e66d3219f492ee9f", + "body_root": "0xacf37b466d4f6b5d1db5b6ffe5d77c13972d116c2b0809de924427fd597d391a" + }, + "finality_branch": [ + "0x00ef010000000000000000000000000000000000000000000000000000000000", + "0x3d4be5d019ba15ea3ef304a83b8a067f2e79f46a3fac8069306a6c814a0a35eb", + "0xa2e2a28c0bb0ad56c25f3c461a4bfe4f3b3b894bc0105a62e85f43a4ae1adc3f", + "0x690925f92c1d322d2ff2a5636539094825dfd2c9bf7538fe111b2358e03a71de", + "0x51d977e358166401c7cd3f6185468c1a8c69a4c3d8577535dd583bc427692e02", + "0x88d2089aaf2f6fd8f6e4ae499c6fe33cc34289eb9310780861e772204f07b670" + ], + "block_roots_root": "0x7054ba439f83e9b2223911e25fad48eb28f5c362d94c0de2455a45436cc93897", + "block_roots_branch": [ + "0xc99a842c81d0b956eef988dbcd90499457d61f942375c6cbf67262909b708db5", + "0x5d32345aeb10aa3ede4be021d2231dac47cc2074f74b72466f0b042e69adf70f", + "0xb69608a2377956c1a39c3423d3399ccfb12307623c9df6358f5fcfca64a80102", + "0xcefd9b668e49ece82bd4b0ee2f1efc88ecaf0d9af464fb622735663aaf106c4c", + "0xc113ad1c971779b15c64772ab69cd775edfb926a60447974913bb6f58fbd12fb" + ] +} \ No newline at end of file diff --git a/bridges/snowbridge/parachain/pallets/outbound-queue/src/lib.rs b/bridges/snowbridge/parachain/pallets/outbound-queue/src/lib.rs index 201e524fb91..c3401c4dc94 100644 --- a/bridges/snowbridge/parachain/pallets/outbound-queue/src/lib.rs +++ b/bridges/snowbridge/parachain/pallets/outbound-queue/src/lib.rs @@ -109,7 +109,7 @@ use sp_runtime::{ DigestItem, }; use sp_std::prelude::*; -pub use types::{CommittedMessage, FeeConfigRecord, ProcessMessageOriginOf}; +pub use types::{CommittedMessage, ProcessMessageOriginOf}; pub use weights::WeightInfo; pub use pallet::*; @@ -186,12 +186,7 @@ pub mod pallet { count: u64, }, /// Set OperatingMode - OperatingModeChanged { - mode: BasicOperatingMode, - }, - FeeConfigChanged { - fee_config: FeeConfigRecord, - }, + OperatingModeChanged { mode: BasicOperatingMode }, } #[pallet::error] @@ -200,8 +195,6 @@ pub mod pallet { MessageTooLarge, /// The pallet is halted Halted, - // Invalid fee config - InvalidFeeConfig, /// Invalid Channel InvalidChannel, } diff --git a/bridges/snowbridge/parachain/pallets/outbound-queue/src/types.rs b/bridges/snowbridge/parachain/pallets/outbound-queue/src/types.rs index 07803ed9b73..28d400bb9d4 100644 --- a/bridges/snowbridge/parachain/pallets/outbound-queue/src/types.rs +++ b/bridges/snowbridge/parachain/pallets/outbound-queue/src/types.rs @@ -1,11 +1,9 @@ -use codec::{Decode, Encode, MaxEncodedLen}; +use codec::{Decode, Encode}; use ethabi::Token; use frame_support::traits::ProcessMessage; use scale_info::TypeInfo; -use serde::{Deserialize, Serialize}; -use sp_arithmetic::FixedU128; use sp_core::H256; -use sp_runtime::{traits::Zero, RuntimeDebug}; +use sp_runtime::RuntimeDebug; use sp_std::prelude::*; use super::Pallet; @@ -57,43 +55,3 @@ impl From for Token { ]) } } - -/// Configuration for fee calculations -#[derive( - Encode, - Decode, - Copy, - Clone, - PartialEq, - RuntimeDebug, - MaxEncodedLen, - TypeInfo, - Serialize, - Deserialize, -)] -pub struct FeeConfigRecord { - /// ETH/DOT exchange rate - pub exchange_rate: FixedU128, - /// Ether fee per unit of gas - pub fee_per_gas: u128, - /// Ether reward for delivering message - pub reward: u128, -} - -#[derive(RuntimeDebug)] -pub struct InvalidFeeConfig; - -impl FeeConfigRecord { - pub fn validate(&self) -> Result<(), InvalidFeeConfig> { - if self.exchange_rate == FixedU128::zero() { - return Err(InvalidFeeConfig) - } - if self.fee_per_gas == 0 { - return Err(InvalidFeeConfig) - } - if self.reward == 0 { - return Err(InvalidFeeConfig) - } - Ok(()) - } -} diff --git a/bridges/snowbridge/parachain/runtime/tests/Cargo.toml b/bridges/snowbridge/parachain/runtime/tests/Cargo.toml index 9b5000b56cd..0a09f89c6b9 100644 --- a/bridges/snowbridge/parachain/runtime/tests/Cargo.toml +++ b/bridges/snowbridge/parachain/runtime/tests/Cargo.toml @@ -233,8 +233,8 @@ try-runtime = [ "snowbridge-system/try-runtime", "sp-runtime/try-runtime", ] -beacon-spec-mainnet = [ - "snowbridge-ethereum-beacon-client/beacon-spec-mainnet", +fast-runtime = [ + "bridge-hub-rococo-runtime/fast-runtime", ] experimental = ["pallet-aura/experimental"] diff --git a/bridges/snowbridge/parachain/scripts/verify-pallets-build.sh b/bridges/snowbridge/parachain/scripts/verify-pallets-build.sh index f060cf958b7..74cec954832 100755 --- a/bridges/snowbridge/parachain/scripts/verify-pallets-build.sh +++ b/bridges/snowbridge/parachain/scripts/verify-pallets-build.sh @@ -57,6 +57,8 @@ rm -rf $SNOWBRIDGE_FOLDER/codecov.yml rm -rf $SNOWBRIDGE_FOLDER/docs rm -rf $SNOWBRIDGE_FOLDER/hooks rm -rf $SNOWBRIDGE_FOLDER/relayer +rm -rf $SNOWBRIDGE_FOLDER/scripts +rm -rf $SNOWBRIDGE_FOLDER/SECURITY.md rm -rf $SNOWBRIDGE_FOLDER/smoketest rm -rf $SNOWBRIDGE_FOLDER/web rm -rf $SNOWBRIDGE_FOLDER/.envrc-example @@ -74,6 +76,7 @@ rm -rf $SNOWBRIDGE_FOLDER/rust-toolchain.toml rm -rf $SNOWBRIDGE_FOLDER/parachain/rustfmt.toml rm -rf $SNOWBRIDGE_FOLDER/parachain/.gitignore rm -rf $SNOWBRIDGE_FOLDER/parachain/templates +rm -rf $SNOWBRIDGE_FOLDER/parachain/.cargo rm -rf $SNOWBRIDGE_FOLDER/parachain/.config rm -rf $SNOWBRIDGE_FOLDER/parachain/pallets/ethereum-beacon-client/fuzz diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 61939a2c80a..0423dd0ac86 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -917,6 +917,7 @@ construct_runtime!( // Bridge utilities. ToWestendXcmRouter: pallet_xcm_bridge_hub_router::::{Pallet, Storage, Call} = 45, + // The main stage. Assets: pallet_assets::::{Pallet, Call, Storage, Event} = 50, Uniques: pallet_uniques::{Pallet, Call, Storage, Event} = 51, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml index 6bb20b5ee35..bc8fa72bb0b 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml @@ -130,7 +130,7 @@ bridge-runtime-common = { path = "../../../../../bridges/bin/runtime-common", fe sp-keyring = { path = "../../../../../substrate/primitives/keyring" } [features] -default = ["beacon-spec-mainnet", "std"] +default = ["std"] std = [ "bp-asset-hub-rococo/std", "bp-asset-hub-westend/std", @@ -223,7 +223,6 @@ std = [ ] runtime-benchmarks = [ - "beacon-spec-mainnet", "bridge-hub-common/runtime-benchmarks", "bridge-runtime-common/runtime-benchmarks", "cumulus-pallet-parachain-system/runtime-benchmarks", @@ -299,8 +298,8 @@ try-runtime = [ ] experimental = ["pallet-aura/experimental"] -beacon-spec-mainnet = [ - "snowbridge-ethereum-beacon-client/beacon-spec-mainnet", +fast-runtime = [ + "snowbridge-ethereum-beacon-client/beacon-spec-minimal", ] # A feature that should be enabled when the runtime should be built for on-chain diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_ethereum_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_ethereum_config.rs index b0526148fa3..af2438efbcf 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_ethereum_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_ethereum_config.rs @@ -14,10 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Cumulus. If not, see . -use crate::{ - xcm_config::{AgentIdOf, UniversalLocation}, - Runtime, -}; +use crate::{xcm_config::UniversalLocation, Runtime}; use snowbridge_rococo_common::EthereumNetwork; use snowbridge_router_primitives::outbound::EthereumBlobExporter; @@ -26,5 +23,5 @@ pub type SnowbridgeExporter = EthereumBlobExporter< UniversalLocation, EthereumNetwork, snowbridge_outbound_queue::Pallet, - AgentIdOf, + snowbridge_core::AgentIdOf, >; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index b21cde248e1..b1ff98491da 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -99,6 +99,8 @@ use parachains_common::{ HOURS, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, }; +use polkadot_runtime_common::prod_or_fast; + #[cfg(feature = "runtime-benchmarks")] use crate::xcm_config::benchmark_helpers::DoNothingRouter; #[cfg(feature = "runtime-benchmarks")] @@ -209,7 +211,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("bridge-hub-rococo"), impl_name: create_runtime_str!("bridge-hub-rococo"), authoring_version: 1, - spec_version: 1_005_001, + spec_version: 1_005_002, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 4, @@ -566,7 +568,7 @@ impl snowbridge_outbound_queue::Config for Runtime { type Channels = EthereumSystem; } -#[cfg(not(feature = "beacon-spec-mainnet"))] +#[cfg(feature = "fast-runtime")] parameter_types! { pub const ChainForkVersions: ForkVersions = ForkVersions { genesis: Fork { @@ -586,30 +588,32 @@ parameter_types! { epoch: 0, }, }; - pub const MaxExecutionHeadersToKeep:u32 = 1000; } -#[cfg(feature = "beacon-spec-mainnet")] +#[cfg(not(feature = "fast-runtime"))] parameter_types! { pub const ChainForkVersions: ForkVersions = ForkVersions { genesis: Fork { - version: [0, 0, 16, 32], // 0x00001020 + version: [144, 0, 0, 111], // 0x90000069 epoch: 0, }, altair: Fork { - version: [1, 0, 16, 32], // 0x01001020 - epoch: 36660, + version: [144, 0, 0, 112], // 0x90000070 + epoch: 50, }, bellatrix: Fork { - version: [2, 0, 16, 32], // 0x02001020 - epoch: 112260, + version: [144, 0, 0, 113], // 0x90000071 + epoch: 100, }, capella: Fork { - version: [3, 0, 16, 32], // 0x03001020 - epoch: 162304, + version: [144, 0, 0, 114], // 0x90000072 + epoch: 56832, }, }; - pub const MaxExecutionHeadersToKeep:u32 = 8192 * 2; +} + +parameter_types! { + pub const MaxExecutionHeadersToKeep: u32 = prod_or_fast!(8192 * 2, 1000); } impl snowbridge_ethereum_beacon_client::Config for Runtime { @@ -630,7 +634,7 @@ impl snowbridge_system::Config for Runtime { type RuntimeEvent = RuntimeEvent; type OutboundQueue = EthereumOutboundQueue; type SiblingOrigin = EnsureXcm; - type AgentIdOf = xcm_config::AgentIdOf; + type AgentIdOf = snowbridge_core::AgentIdOf; type TreasuryAccount = TreasuryAccount; type Token = Balances; type WeightInfo = weights::snowbridge_system::WeightInfo; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs index ac5c4afd52d..fc97a3ed89a 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs @@ -47,10 +47,9 @@ use parachains_common::{ }; use polkadot_parachain_primitives::primitives::Sibling; use polkadot_runtime_common::xcm_sender::ExponentialPrice; -use snowbridge_core::DescribeHere; use snowbridge_rococo_common::EthereumNetwork; use snowbridge_runtime_common::XcmExportFeeToSibling; -use sp_core::{Get, H256}; +use sp_core::Get; use sp_runtime::traits::AccountIdConversion; use sp_std::marker::PhantomData; use xcm::latest::prelude::*; @@ -58,12 +57,11 @@ use xcm::latest::prelude::*; use xcm_builder::{ deposit_or_burn_fee, AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, - CurrencyAdapter, DenyReserveTransferToRelayChain, DenyThenTry, DescribeAllTerminal, - DescribeFamily, EnsureXcmOrigin, HandleFee, HashedDescription, IsConcrete, ParentAsSuperuser, - ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, - SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, - TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, - XcmFeeToAccount, + CurrencyAdapter, DenyReserveTransferToRelayChain, DenyThenTry, EnsureXcmOrigin, HandleFee, + IsConcrete, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, + SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, + SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, + WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, XcmFeeToAccount, }; use xcm_executor::{ traits::{FeeManager, FeeReason, FeeReason::Export, TransactAsset, WithOriginFilter}, @@ -383,10 +381,6 @@ impl cumulus_pallet_xcm::Config for Runtime { type XcmExecutor = XcmExecutor; } -/// Creates an AgentId from a MultiLocation. An AgentId is a unique mapping to a Agent contract on -/// Ethereum which acts as the sovereign account for the MultiLocation. -pub type AgentIdOf = HashedDescription)>; - /// A `HandleFee` implementation that simply deposits the fees for `ExportMessage` XCM instructions /// into the accounts that are used for paying the relayer rewards. /// Burns the fees in case of a failure. diff --git a/cumulus/polkadot-parachain/Cargo.toml b/cumulus/polkadot-parachain/Cargo.toml index a9b48a7984b..464c333afe2 100644 --- a/cumulus/polkadot-parachain/Cargo.toml +++ b/cumulus/polkadot-parachain/Cargo.toml @@ -167,3 +167,6 @@ try-runtime = [ "shell-runtime/try-runtime", "sp-runtime/try-runtime", ] +fast-runtime = [ + "bridge-hub-rococo-runtime/fast-runtime", +] -- GitLab From 14f49002c3420ccb30cf433c93f5f1ddcdfdecf8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 15:46:44 +0000 Subject: [PATCH 019/392] Bump the known_good_semver group with 1 update (#2881) Bumps the known_good_semver group with 1 update: [clap](https://github.com/clap-rs/clap). Updates `clap` from 4.4.13 to 4.4.14
Release notes

Sourced from clap's releases.

v4.4.14

[4.4.14] - 2024-01-08

Documentation

  • Fix find cookbook entry to allow repeats of flags/options

Features

  • Allow num_args(0) on options which allows making them emulate being a flag for position-tracking flags
Changelog

Sourced from clap's changelog.

[4.4.14] - 2024-01-08

Documentation

  • Fix find cookbook entry to allow repeats of flags/options

Features

  • Allow num_args(0) on options which allows making them emulate being a flag for position-tracking flags
Commits
  • 514f28b chore: Release
  • 1440456 docs: Update changelog
  • d6479ff Merge pull request #5290 from epage/or
  • 02f8214 docs(cookbook): Clarify intent of fake flags
  • c603f34 Merge pull request #5275 from epage/ci
  • 641b42b chore(ci): Speed up critical path of CI
  • 3eaf1af fix(help): Correctly show help for fake flags
  • d63106b docs(cookbook): Allow repeated operators
  • 148e102 fix(builder): Allow custom flag definitions
  • d53d881 docs(cookbook): Demonstrate bad 'find' behavior
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=clap&package-manager=cargo&previous-version=4.4.13&new-version=4.4.14)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 66 +++++++++---------- cumulus/client/cli/Cargo.toml | 2 +- cumulus/parachain-template/node/Cargo.toml | 2 +- cumulus/polkadot-parachain/Cargo.toml | 2 +- cumulus/test/service/Cargo.toml | 2 +- polkadot/cli/Cargo.toml | 2 +- polkadot/node/malus/Cargo.toml | 2 +- polkadot/node/subsystem-bench/Cargo.toml | 2 +- .../test-parachains/adder/collator/Cargo.toml | 2 +- .../undying/collator/Cargo.toml | 2 +- polkadot/utils/generate-bags/Cargo.toml | 2 +- .../remote-ext-tests/bags-list/Cargo.toml | 2 +- substrate/bin/minimal/node/Cargo.toml | 2 +- substrate/bin/node-template/node/Cargo.toml | 2 +- substrate/bin/node/bench/Cargo.toml | 2 +- substrate/bin/node/cli/Cargo.toml | 4 +- substrate/bin/node/inspect/Cargo.toml | 2 +- .../bin/utils/chain-spec-builder/Cargo.toml | 2 +- substrate/bin/utils/subkey/Cargo.toml | 2 +- substrate/client/cli/Cargo.toml | 2 +- substrate/client/storage-monitor/Cargo.toml | 2 +- .../solution-type/fuzzer/Cargo.toml | 2 +- .../npos-elections/fuzzer/Cargo.toml | 2 +- .../ci/node-template-release/Cargo.toml | 2 +- .../utils/frame/benchmarking-cli/Cargo.toml | 2 +- .../frame/frame-utilities-cli/Cargo.toml | 2 +- .../generate-bags/node-runtime/Cargo.toml | 2 +- .../utils/frame/try-runtime/cli/Cargo.toml | 2 +- 28 files changed, 61 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d4d3b2f6404..4a9f0c2d51f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2639,9 +2639,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.13" +version = "4.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52bdc885e4cacc7f7c9eedc1ef6da641603180c783c41a15c264944deeaab642" +checksum = "33e92c5c1a78c62968ec57dbc2440366a2d6e5a23faf829970ff1585dc6b18e2" dependencies = [ "clap_builder", "clap_derive 4.4.7", @@ -2658,9 +2658,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.12" +version = "4.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb7fb5e4e979aec3be7791562fcba452f94ad85e954da024396433e0e25a79e9" +checksum = "f4323769dc8a61e2c39ad7dc26f6f2800524691a44d74fe3d1071a5c24db6370" dependencies = [ "anstream", "anstyle", @@ -2675,7 +2675,7 @@ version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "586a385f7ef2f8b4d86bddaa0c094794e7ccbfe5ffef1f434fe928143fc783a5" dependencies = [ - "clap 4.4.13", + "clap 4.4.14", ] [[package]] @@ -3413,7 +3413,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.4.13", + "clap 4.4.14", "criterion-plot", "futures", "is-terminal", @@ -3576,7 +3576,7 @@ dependencies = [ name = "cumulus-client-cli" version = "0.1.0" dependencies = [ - "clap 4.4.13", + "clap 4.4.14", "parity-scale-codec", "sc-chain-spec", "sc-cli", @@ -4315,7 +4315,7 @@ name = "cumulus-test-service" version = "0.1.0" dependencies = [ "async-trait", - "clap 4.4.13", + "clap 4.4.14", "criterion 0.5.1", "cumulus-client-cli", "cumulus-client-consensus-common", @@ -5499,7 +5499,7 @@ dependencies = [ "Inflector", "array-bytes 6.1.0", "chrono", - "clap 4.4.13", + "clap 4.4.14", "comfy-table", "frame-benchmarking", "frame-support", @@ -5591,7 +5591,7 @@ dependencies = [ name = "frame-election-solution-type-fuzzer" version = "2.0.0-alpha.5" dependencies = [ - "clap 4.4.13", + "clap 4.4.14", "frame-election-provider-solution-type", "frame-election-provider-support", "frame-support", @@ -8107,7 +8107,7 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" name = "minimal-node" version = "4.0.0-dev" dependencies = [ - "clap 4.4.13", + "clap 4.4.14", "frame", "futures", "futures-timer", @@ -8571,7 +8571,7 @@ name = "node-bench" version = "0.9.0-dev" dependencies = [ "array-bytes 6.1.0", - "clap 4.4.13", + "clap 4.4.14", "derive_more", "fs_extra", "futures", @@ -8648,7 +8648,7 @@ dependencies = [ name = "node-runtime-generate-bags" version = "3.0.0" dependencies = [ - "clap 4.4.13", + "clap 4.4.14", "generate-bags", "kitchensink-runtime", ] @@ -8657,7 +8657,7 @@ dependencies = [ name = "node-template" version = "4.0.0-dev" dependencies = [ - "clap 4.4.13", + "clap 4.4.14", "frame-benchmarking", "frame-benchmarking-cli", "frame-system", @@ -8701,7 +8701,7 @@ dependencies = [ name = "node-template-release" version = "3.0.0" dependencies = [ - "clap 4.4.13", + "clap 4.4.14", "flate2", "fs_extra", "glob", @@ -11243,7 +11243,7 @@ dependencies = [ name = "parachain-template-node" version = "0.1.0" dependencies = [ - "clap 4.4.13", + "clap 4.4.14", "color-print", "cumulus-client-cli", "cumulus-client-collator", @@ -12202,7 +12202,7 @@ name = "polkadot-cli" version = "1.1.0" dependencies = [ "cfg-if", - "clap 4.4.13", + "clap 4.4.14", "frame-benchmarking-cli", "futures", "log", @@ -13043,7 +13043,7 @@ dependencies = [ "async-trait", "bridge-hub-rococo-runtime", "bridge-hub-westend-runtime", - "clap 4.4.13", + "clap 4.4.14", "collectives-westend-runtime", "color-print", "contracts-rococo-runtime", @@ -13554,7 +13554,7 @@ version = "1.0.0" dependencies = [ "assert_matches", "async-trait", - "clap 4.4.13", + "clap 4.4.14", "clap-num", "color-eyre", "colored", @@ -13631,7 +13631,7 @@ version = "1.0.0" dependencies = [ "assert_matches", "async-trait", - "clap 4.4.13", + "clap 4.4.14", "color-eyre", "futures", "futures-timer", @@ -13778,7 +13778,7 @@ dependencies = [ name = "polkadot-voter-bags" version = "1.0.0" dependencies = [ - "clap 4.4.13", + "clap 4.4.14", "generate-bags", "sp-io", "westend-runtime", @@ -14648,7 +14648,7 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" name = "remote-ext-tests-bags-list" version = "1.0.0" dependencies = [ - "clap 4.4.13", + "clap 4.4.14", "frame-system", "log", "pallet-bags-list-remote-tests", @@ -15438,7 +15438,7 @@ dependencies = [ "array-bytes 6.1.0", "bip39", "chrono", - "clap 4.4.13", + "clap 4.4.14", "fdlimit", "futures", "futures-timer", @@ -16582,7 +16582,7 @@ dependencies = [ name = "sc-storage-monitor" version = "0.1.0" dependencies = [ - "clap 4.4.13", + "clap 4.4.14", "fs4", "log", "sc-client-db", @@ -18544,7 +18544,7 @@ dependencies = [ name = "sp-npos-elections-fuzzer" version = "2.0.0-alpha.5" dependencies = [ - "clap 4.4.13", + "clap 4.4.14", "honggfuzz", "rand 0.8.5", "sp-npos-elections", @@ -19065,7 +19065,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" name = "staging-chain-spec-builder" version = "2.0.0" dependencies = [ - "clap 4.4.13", + "clap 4.4.14", "log", "sc-chain-spec", "serde_json", @@ -19078,7 +19078,7 @@ version = "3.0.0-dev" dependencies = [ "array-bytes 6.1.0", "assert_cmd", - "clap 4.4.13", + "clap 4.4.14", "clap_complete", "criterion 0.4.0", "frame-benchmarking", @@ -19187,7 +19187,7 @@ dependencies = [ name = "staging-node-inspect" version = "0.9.0-dev" dependencies = [ - "clap 4.4.13", + "clap 4.4.14", "parity-scale-codec", "sc-cli", "sc-client-api", @@ -19392,7 +19392,7 @@ dependencies = [ name = "subkey" version = "3.0.0" dependencies = [ - "clap 4.4.13", + "clap 4.4.14", "sc-cli", ] @@ -19434,7 +19434,7 @@ dependencies = [ name = "substrate-frame-cli" version = "4.0.0-dev" dependencies = [ - "clap 4.4.13", + "clap 4.4.14", "frame-support", "frame-system", "sc-cli", @@ -19912,7 +19912,7 @@ dependencies = [ name = "test-parachain-adder-collator" version = "1.0.0" dependencies = [ - "clap 4.4.13", + "clap 4.4.14", "futures", "futures-timer", "log", @@ -19960,7 +19960,7 @@ dependencies = [ name = "test-parachain-undying-collator" version = "1.0.0" dependencies = [ - "clap 4.4.13", + "clap 4.4.14", "futures", "futures-timer", "log", @@ -20622,7 +20622,7 @@ version = "0.10.0-dev" dependencies = [ "assert_cmd", "async-trait", - "clap 4.4.13", + "clap 4.4.14", "frame-remote-externalities", "frame-try-runtime", "hex", diff --git a/cumulus/client/cli/Cargo.toml b/cumulus/client/cli/Cargo.toml index 1bf25f3963a..736cb02b94b 100644 --- a/cumulus/client/cli/Cargo.toml +++ b/cumulus/client/cli/Cargo.toml @@ -10,7 +10,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0" workspace = true [dependencies] -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0" } url = "2.4.0" diff --git a/cumulus/parachain-template/node/Cargo.toml b/cumulus/parachain-template/node/Cargo.toml index 52c6ee7050d..7edb4b454c0 100644 --- a/cumulus/parachain-template/node/Cargo.toml +++ b/cumulus/parachain-template/node/Cargo.toml @@ -14,7 +14,7 @@ publish = false workspace = true [dependencies] -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } log = "0.4.20" codec = { package = "parity-scale-codec", version = "3.0.0" } serde = { version = "1.0.195", features = ["derive"] } diff --git a/cumulus/polkadot-parachain/Cargo.toml b/cumulus/polkadot-parachain/Cargo.toml index 464c333afe2..50fc48b3f2f 100644 --- a/cumulus/polkadot-parachain/Cargo.toml +++ b/cumulus/polkadot-parachain/Cargo.toml @@ -16,7 +16,7 @@ path = "src/main.rs" [dependencies] async-trait = "0.1.74" -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0" } futures = "0.3.28" hex-literal = "0.4.1" diff --git a/cumulus/test/service/Cargo.toml b/cumulus/test/service/Cargo.toml index b5294ec038a..f4dde7d2945 100644 --- a/cumulus/test/service/Cargo.toml +++ b/cumulus/test/service/Cargo.toml @@ -14,7 +14,7 @@ path = "src/main.rs" [dependencies] async-trait = "0.1.74" -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0" } criterion = { version = "0.5.1", features = ["async_tokio"] } jsonrpsee = { version = "0.16.2", features = ["server"] } diff --git a/polkadot/cli/Cargo.toml b/polkadot/cli/Cargo.toml index 0b47da4d45c..1b331c5ed42 100644 --- a/polkadot/cli/Cargo.toml +++ b/polkadot/cli/Cargo.toml @@ -19,7 +19,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] cfg-if = "1.0" -clap = { version = "4.4.13", features = ["derive"], optional = true } +clap = { version = "4.4.14", features = ["derive"], optional = true } log = "0.4.17" thiserror = "1.0.48" futures = "0.3.21" diff --git a/polkadot/node/malus/Cargo.toml b/polkadot/node/malus/Cargo.toml index f555cbd5dac..56d377648bb 100644 --- a/polkadot/node/malus/Cargo.toml +++ b/polkadot/node/malus/Cargo.toml @@ -43,7 +43,7 @@ assert_matches = "1.5" async-trait = "0.1.74" sp-keystore = { path = "../../../substrate/primitives/keystore" } sp-core = { path = "../../../substrate/primitives/core" } -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" gum = { package = "tracing-gum", path = "../gum" } diff --git a/polkadot/node/subsystem-bench/Cargo.toml b/polkadot/node/subsystem-bench/Cargo.toml index 73405a3bc3b..dc1179b7762 100644 --- a/polkadot/node/subsystem-bench/Cargo.toml +++ b/polkadot/node/subsystem-bench/Cargo.toml @@ -31,7 +31,7 @@ async-trait = "0.1.74" sp-keystore = { path = "../../../substrate/primitives/keystore" } sc-keystore = { path = "../../../substrate/client/keystore" } sp-core = { path = "../../../substrate/primitives/core" } -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" gum = { package = "tracing-gum", path = "../gum" } diff --git a/polkadot/parachain/test-parachains/adder/collator/Cargo.toml b/polkadot/parachain/test-parachains/adder/collator/Cargo.toml index a6517608b26..c2cea979b97 100644 --- a/polkadot/parachain/test-parachains/adder/collator/Cargo.toml +++ b/polkadot/parachain/test-parachains/adder/collator/Cargo.toml @@ -16,7 +16,7 @@ path = "src/main.rs" [dependencies] parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" log = "0.4.17" diff --git a/polkadot/parachain/test-parachains/undying/collator/Cargo.toml b/polkadot/parachain/test-parachains/undying/collator/Cargo.toml index d34a855ab9d..4d7c7391d82 100644 --- a/polkadot/parachain/test-parachains/undying/collator/Cargo.toml +++ b/polkadot/parachain/test-parachains/undying/collator/Cargo.toml @@ -16,7 +16,7 @@ path = "src/main.rs" [dependencies] parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" log = "0.4.17" diff --git a/polkadot/utils/generate-bags/Cargo.toml b/polkadot/utils/generate-bags/Cargo.toml index 8ec828ba072..5435baa6151 100644 --- a/polkadot/utils/generate-bags/Cargo.toml +++ b/polkadot/utils/generate-bags/Cargo.toml @@ -10,7 +10,7 @@ description = "CLI to generate voter bags for Polkadot runtimes" workspace = true [dependencies] -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } generate-bags = { path = "../../../substrate/utils/frame/generate-bags" } sp-io = { path = "../../../substrate/primitives/io" } diff --git a/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml b/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml index 8ee277e64b5..aeb62e87941 100644 --- a/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml +++ b/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml @@ -18,6 +18,6 @@ sp-tracing = { path = "../../../../substrate/primitives/tracing" } frame-system = { path = "../../../../substrate/frame/system" } sp-core = { path = "../../../../substrate/primitives/core" } -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } log = "0.4.17" tokio = { version = "1.24.2", features = ["macros"] } diff --git a/substrate/bin/minimal/node/Cargo.toml b/substrate/bin/minimal/node/Cargo.toml index 42eced506c4..07138eb0c55 100644 --- a/substrate/bin/minimal/node/Cargo.toml +++ b/substrate/bin/minimal/node/Cargo.toml @@ -20,7 +20,7 @@ targets = ["x86_64-unknown-linux-gnu"] name = "minimal-node" [dependencies] -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } futures = { version = "0.3.21", features = ["thread-pool"] } futures-timer = "3.0.1" jsonrpsee = { version = "0.16.2", features = ["server"] } diff --git a/substrate/bin/node-template/node/Cargo.toml b/substrate/bin/node-template/node/Cargo.toml index 6a600364c4d..aac24a83096 100644 --- a/substrate/bin/node-template/node/Cargo.toml +++ b/substrate/bin/node-template/node/Cargo.toml @@ -20,7 +20,7 @@ targets = ["x86_64-unknown-linux-gnu"] name = "node-template" [dependencies] -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } futures = { version = "0.3.21", features = ["thread-pool"] } serde_json = "1.0.111" diff --git a/substrate/bin/node/bench/Cargo.toml b/substrate/bin/node/bench/Cargo.toml index e90b7070396..e2b68b2a0e8 100644 --- a/substrate/bin/node/bench/Cargo.toml +++ b/substrate/bin/node/bench/Cargo.toml @@ -16,7 +16,7 @@ workspace = true [dependencies] array-bytes = "6.1" -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } log = "0.4.17" node-primitives = { path = "../primitives" } node-testing = { path = "../testing" } diff --git a/substrate/bin/node/cli/Cargo.toml b/substrate/bin/node/cli/Cargo.toml index 3a80dc4e0cc..4bf5efd7cd1 100644 --- a/substrate/bin/node/cli/Cargo.toml +++ b/substrate/bin/node/cli/Cargo.toml @@ -41,7 +41,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] # third-party dependencies array-bytes = "6.1" -clap = { version = "4.4.13", features = ["derive"], optional = true } +clap = { version = "4.4.14", features = ["derive"], optional = true } codec = { package = "parity-scale-codec", version = "3.6.1" } serde = { version = "1.0.195", features = ["derive"] } jsonrpsee = { version = "0.16.2", features = ["server"] } @@ -164,7 +164,7 @@ sp-trie = { path = "../../../primitives/trie" } sp-state-machine = { path = "../../../primitives/state-machine" } [build-dependencies] -clap = { version = "4.4.13", optional = true } +clap = { version = "4.4.14", optional = true } clap_complete = { version = "4.0.2", optional = true } node-inspect = { package = "staging-node-inspect", path = "../inspect", optional = true } frame-benchmarking-cli = { path = "../../../utils/frame/benchmarking-cli", optional = true } diff --git a/substrate/bin/node/inspect/Cargo.toml b/substrate/bin/node/inspect/Cargo.toml index d14cc8ff760..29c0917440e 100644 --- a/substrate/bin/node/inspect/Cargo.toml +++ b/substrate/bin/node/inspect/Cargo.toml @@ -15,7 +15,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.6.1" } thiserror = "1.0" sc-cli = { path = "../../../client/cli" } diff --git a/substrate/bin/utils/chain-spec-builder/Cargo.toml b/substrate/bin/utils/chain-spec-builder/Cargo.toml index 3848ef91588..e9dc4d83b6b 100644 --- a/substrate/bin/utils/chain-spec-builder/Cargo.toml +++ b/substrate/bin/utils/chain-spec-builder/Cargo.toml @@ -23,7 +23,7 @@ name = "chain-spec-builder" crate-type = ["rlib"] [dependencies] -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } log = "0.4.17" sc-chain-spec = { path = "../../../client/chain-spec" } serde_json = "1.0.111" diff --git a/substrate/bin/utils/subkey/Cargo.toml b/substrate/bin/utils/subkey/Cargo.toml index d4ecfda3735..822068f6614 100644 --- a/substrate/bin/utils/subkey/Cargo.toml +++ b/substrate/bin/utils/subkey/Cargo.toml @@ -20,5 +20,5 @@ path = "src/main.rs" name = "subkey" [dependencies] -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } sc-cli = { path = "../../../client/cli" } diff --git a/substrate/client/cli/Cargo.toml b/substrate/client/cli/Cargo.toml index 526db17fa32..caaa96b904c 100644 --- a/substrate/client/cli/Cargo.toml +++ b/substrate/client/cli/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] array-bytes = "6.1" chrono = "0.4.31" -clap = { version = "4.4.13", features = ["derive", "string", "wrap_help"] } +clap = { version = "4.4.14", features = ["derive", "string", "wrap_help"] } fdlimit = "0.3.0" futures = "0.3.21" itertools = "0.10.3" diff --git a/substrate/client/storage-monitor/Cargo.toml b/substrate/client/storage-monitor/Cargo.toml index 37259b9234a..2b46ccbcdc1 100644 --- a/substrate/client/storage-monitor/Cargo.toml +++ b/substrate/client/storage-monitor/Cargo.toml @@ -12,7 +12,7 @@ homepage = "https://substrate.io" workspace = true [dependencies] -clap = { version = "4.4.13", features = ["derive", "string"] } +clap = { version = "4.4.14", features = ["derive", "string"] } log = "0.4.17" fs4 = "0.7.0" sc-client-db = { path = "../db", default-features = false } diff --git a/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml b/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml index e21b9536727..d64498de087 100644 --- a/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml +++ b/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml @@ -16,7 +16,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } honggfuzz = "0.5" rand = { version = "0.8", features = ["small_rng", "std"] } diff --git a/substrate/primitives/npos-elections/fuzzer/Cargo.toml b/substrate/primitives/npos-elections/fuzzer/Cargo.toml index 29dfa809fbe..e7cfb75e54b 100644 --- a/substrate/primitives/npos-elections/fuzzer/Cargo.toml +++ b/substrate/primitives/npos-elections/fuzzer/Cargo.toml @@ -17,7 +17,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } honggfuzz = "0.5" rand = { version = "0.8", features = ["small_rng", "std"] } sp-npos-elections = { path = ".." } diff --git a/substrate/scripts/ci/node-template-release/Cargo.toml b/substrate/scripts/ci/node-template-release/Cargo.toml index 32210de73e6..b02f941811c 100644 --- a/substrate/scripts/ci/node-template-release/Cargo.toml +++ b/substrate/scripts/ci/node-template-release/Cargo.toml @@ -14,7 +14,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } flate2 = "1.0" fs_extra = "1.3" glob = "0.3" diff --git a/substrate/utils/frame/benchmarking-cli/Cargo.toml b/substrate/utils/frame/benchmarking-cli/Cargo.toml index 02cb6ebc303..21c5701b518 100644 --- a/substrate/utils/frame/benchmarking-cli/Cargo.toml +++ b/substrate/utils/frame/benchmarking-cli/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] array-bytes = "6.1" chrono = "0.4" -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.6.1" } comfy-table = { version = "7.0.1", default-features = false } handlebars = "4.2.2" diff --git a/substrate/utils/frame/frame-utilities-cli/Cargo.toml b/substrate/utils/frame/frame-utilities-cli/Cargo.toml index 96c43aee070..886e17280b1 100644 --- a/substrate/utils/frame/frame-utilities-cli/Cargo.toml +++ b/substrate/utils/frame/frame-utilities-cli/Cargo.toml @@ -14,7 +14,7 @@ readme = "README.md" workspace = true [dependencies] -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } frame-support = { path = "../../../frame/support" } frame-system = { path = "../../../frame/system" } sc-cli = { path = "../../../client/cli" } diff --git a/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml b/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml index 07e74a59a6b..d2aaaff9a69 100644 --- a/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml +++ b/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml @@ -17,4 +17,4 @@ kitchensink-runtime = { path = "../../../../bin/node/runtime" } generate-bags = { path = ".." } # third-party -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } diff --git a/substrate/utils/frame/try-runtime/cli/Cargo.toml b/substrate/utils/frame/try-runtime/cli/Cargo.toml index 4f09a34fae7..b5bce36e3b7 100644 --- a/substrate/utils/frame/try-runtime/cli/Cargo.toml +++ b/substrate/utils/frame/try-runtime/cli/Cargo.toml @@ -38,7 +38,7 @@ frame-try-runtime = { path = "../../../../frame/try-runtime", optional = true } substrate-rpc-client = { path = "../../rpc/client" } async-trait = "0.1.74" -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.14", features = ["derive"] } hex = { version = "0.4.3", default-features = false } log = "0.4.17" parity-scale-codec = "3.6.1" -- GitLab From 9d80735a7cccb7c52280ea057177d92e17203c51 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 15:47:01 +0000 Subject: [PATCH 020/392] Bump aquamarine from 0.3.2 to 0.4.0 (#2882) Bumps [aquamarine](https://github.com/mersinvald/aquamarine) from 0.3.2 to 0.4.0.
Release notes

Sourced from aquamarine's releases.

0.4.0

Breaking Changes

  • path attribute is no longer supported for importing diagrams from external files

Features

  • include_mmd! macro-like syntax for embedding diagrams from files
  • multiple diagrams can now be imported from filesystem per documented entity
  • imported diagrams can now be placed freely at any place inside the doc comment

Miscellaneous

Full Changelog: https://github.com/mersinvald/aquamarine/compare/v0.3.2...v0.4.0

Changelog

Sourced from aquamarine's changelog.

v0.4.0 (2023-12-13)

Breaking Changes

  • path attribute is no longer supported for importing diagrams from external files

Features

  • include_mmd! macro-like syntax for embedding diagrams from files
  • multiple diagrams can now be imported from filesystem per documented entity
  • imported diagrams can now be placed freely at any place inside the doc comment

Miscellaneous

v0.3.1 (2023-04-17)

Features

  • mermaid is updated to v10 (PR #46 by frehberg)
  • better handling of a failure to load mermaidjs (PR #46 by frehberg)

Miscellaneous

  • add Frehberg as a maintainer on GitHub, and package owner on Crates.io

v0.3.0 (2023-02-16)

Maintenance

  • update dependencies

v0.2.2 (2023-02-02)

Bug Fixes

v0.2.1 (2023-02-01)

Maintenance

  • MermaidJS updated to version 9.3.0

... (truncated)

Commits
  • 480897b chore: version 0.4.0
  • f78120d feat: multiple fs imports, free placement of imported diagrams
  • 4cd047c chore: less strict syn2 semver
  • 1a092e5 Merge pull request #42 from maurer/syn-2-update
  • 525a00a chore: fix demo crate dependencies
  • 50a0b23 chore: fix demo crate links
  • e3211bb hotfix: malformed string literals in mermaid.js diagrams of a demo crate
  • c135a84 Update to syn-2
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=aquamarine&package-manager=cargo&previous-version=0.3.2&new-version=0.4.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 6 +++--- substrate/frame/bags-list/Cargo.toml | 2 +- substrate/frame/support/Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4a9f0c2d51f..f5d57bb50be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -333,16 +333,16 @@ dependencies = [ [[package]] name = "aquamarine" -version = "0.3.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df752953c49ce90719c7bf1fc587bc8227aed04732ea0c0f85e5397d7fdbd1a1" +checksum = "074b80d14d0240b6ce94d68f059a2d26a5d77280ae142662365a21ef6e2594ef" dependencies = [ "include_dir", "itertools 0.10.5", "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] diff --git a/substrate/frame/bags-list/Cargo.toml b/substrate/frame/bags-list/Cargo.toml index 198af21be81..7fab47a20e1 100644 --- a/substrate/frame/bags-list/Cargo.toml +++ b/substrate/frame/bags-list/Cargo.toml @@ -35,7 +35,7 @@ frame-election-provider-support = { path = "../election-provider-support", defau # third party log = { version = "0.4.17", default-features = false } docify = "0.2.6" -aquamarine = { version = "0.3.2" } +aquamarine = { version = "0.4.0" } # Optional imports for benchmarking frame-benchmarking = { path = "../benchmarking", default-features = false, optional = true } diff --git a/substrate/frame/support/Cargo.toml b/substrate/frame/support/Cargo.toml index 5c0c4091468..32dcec727cc 100644 --- a/substrate/frame/support/Cargo.toml +++ b/substrate/frame/support/Cargo.toml @@ -50,7 +50,7 @@ serde_json = { version = "1.0.111", default-features = false, features = ["alloc docify = "0.2.6" static_assertions = "1.1.0" -aquamarine = { version = "0.3.2" } +aquamarine = { version = "0.4.0" } [dev-dependencies] assert_matches = "1.3.0" -- GitLab From 49cea35d0a13c145091e8b4df4efeb2f7b92f812 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Tue, 9 Jan 2024 18:44:50 +0100 Subject: [PATCH 021/392] Remove bounds from `PrevalidateAttests` struct definition (#2886) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removing some bounds as it came up in https://github.com/paritytech/polkadot-sdk/pull/2726 while still keeping `Send + Sync` capabilities. --------- Signed-off-by: Oliver Tale-Yazdi Co-authored-by: Bastian Köcher --- polkadot/runtime/common/src/claims.rs | 10 ++++------ prdoc/pr_2886.prdoc | 13 +++++++++++++ 2 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 prdoc/pr_2886.prdoc diff --git a/polkadot/runtime/common/src/claims.rs b/polkadot/runtime/common/src/claims.rs index d15e04a660f..4cddab969c0 100644 --- a/polkadot/runtime/common/src/claims.rs +++ b/polkadot/runtime/common/src/claims.rs @@ -591,11 +591,9 @@ impl Pallet { /// otherwise free to place on chain. #[derive(Encode, Decode, Clone, Eq, PartialEq, TypeInfo)] #[scale_info(skip_type_params(T))] -pub struct PrevalidateAttests(sp_std::marker::PhantomData) -where - ::RuntimeCall: IsSubType>; +pub struct PrevalidateAttests(core::marker::PhantomData); -impl Debug for PrevalidateAttests +impl Debug for PrevalidateAttests where ::RuntimeCall: IsSubType>, { @@ -610,7 +608,7 @@ where } } -impl PrevalidateAttests +impl PrevalidateAttests where ::RuntimeCall: IsSubType>, { @@ -620,7 +618,7 @@ where } } -impl SignedExtension for PrevalidateAttests +impl SignedExtension for PrevalidateAttests where ::RuntimeCall: IsSubType>, { diff --git a/prdoc/pr_2886.prdoc b/prdoc/pr_2886.prdoc new file mode 100644 index 00000000000..9fd97c11e11 --- /dev/null +++ b/prdoc/pr_2886.prdoc @@ -0,0 +1,13 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Remove bounds from `PrevalidateAttests` struct definition + +doc: + - audience: Runtime Dev + description: | + Minimal change to `PrevalidateAssets` to remove some trait bounds on the struct itself while + keeping all its capabilities. + +crates: + - name: polkadot-runtime-common -- GitLab From ce4e5496de35064c4cf4fb59c279d3834fc556cb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 00:12:35 +0000 Subject: [PATCH 022/392] Bump lycheeverse/lychee-action (#2875) Bumps [lycheeverse/lychee-action](https://github.com/lycheeverse/lychee-action) from 2ac9f030ccdea0033e2510a23a67da2a2da98492 to fdea7032675810093199f485fe075f057cc37b3e.
Commits

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--------- Signed-off-by: dependabot[bot] Signed-off-by: Oliver Tale-Yazdi Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Oliver Tale-Yazdi Co-authored-by: PG Herveou --- .config/lychee.toml | 4 ++-- .github/workflows/check-links.yml | 2 +- .../tests/people/people-rococo/src/tests/reap_identity.rs | 4 ++-- .../tests/people/people-westend/src/tests/reap_identity.rs | 4 ++-- docs/sdk/src/meta_contributing.rs | 2 +- docs/sdk/src/reference_docs/frame_benchmarking_weight.rs | 2 +- polkadot/node/core/pvf/common/src/worker/mod.rs | 2 +- substrate/client/rpc-api/src/state/mod.rs | 4 ++-- substrate/frame/staking/src/migrations.rs | 2 +- substrate/frame/state-trie-migration/src/lib.rs | 2 +- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.config/lychee.toml b/.config/lychee.toml index 72c1e66a4df..70869465d67 100644 --- a/.config/lychee.toml +++ b/.config/lychee.toml @@ -12,10 +12,10 @@ exclude_all_private = true # Treat these codes as success condition: accept = [ # Ok - 200, + "200", # Rate limited - GitHub likes to throw this. - 429, + "429", ] exclude_path = ["./target"] diff --git a/.github/workflows/check-links.yml b/.github/workflows/check-links.yml index 0932d38c9ad..14941efce24 100644 --- a/.github/workflows/check-links.yml +++ b/.github/workflows/check-links.yml @@ -28,7 +28,7 @@ jobs: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.0 (22. Sep 2023) - name: Lychee link checker - uses: lycheeverse/lychee-action@2ac9f030ccdea0033e2510a23a67da2a2da98492 # for v1.8.0 (15. May 2023) + uses: lycheeverse/lychee-action@fdea7032675810093199f485fe075f057cc37b3e # for v1.9.0 (5. Jan 2024) with: args: >- --config .config/lychee.toml diff --git a/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/reap_identity.rs b/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/reap_identity.rs index 81bd7620e46..2902f359dfb 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/reap_identity.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/reap_identity.rs @@ -95,7 +95,7 @@ impl Identity { relay: IdentityInfo { display: make_data(b"xcm-test", full), legal: make_data(b"The Xcm Test, Esq.", full), - web: make_data(b"https://xcm-test.io", full), + web: make_data(b"https://visitme/", full), riot: make_data(b"xcm-riot", full), email: make_data(b"xcm-test@gmail.com", full), pgp_fingerprint: Some(pgp_fingerprint), @@ -106,7 +106,7 @@ impl Identity { para: IdentityInfoParachain { display: make_data(b"xcm-test", full), legal: make_data(b"The Xcm Test, Esq.", full), - web: make_data(b"https://xcm-test.io", full), + web: make_data(b"https://visitme/", full), matrix: make_data(b"xcm-matrix@server", full), email: make_data(b"xcm-test@gmail.com", full), pgp_fingerprint: Some(pgp_fingerprint), diff --git a/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/reap_identity.rs b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/reap_identity.rs index 6de2562b278..31c3444f1a3 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/reap_identity.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/reap_identity.rs @@ -95,7 +95,7 @@ impl Identity { relay: IdentityInfo { display: make_data(b"xcm-test", full), legal: make_data(b"The Xcm Test, Esq.", full), - web: make_data(b"https://xcm-test.io", full), + web: make_data(b"https://visitme/", full), riot: make_data(b"xcm-riot", full), email: make_data(b"xcm-test@gmail.com", full), pgp_fingerprint: Some(pgp_fingerprint), @@ -106,7 +106,7 @@ impl Identity { para: IdentityInfoParachain { display: make_data(b"xcm-test", full), legal: make_data(b"The Xcm Test, Esq.", full), - web: make_data(b"https://xcm-test.io", full), + web: make_data(b"https://visitme/", full), matrix: make_data(b"xcm-matrix@server", full), email: make_data(b"xcm-test@gmail.com", full), pgp_fingerprint: Some(pgp_fingerprint), diff --git a/docs/sdk/src/meta_contributing.rs b/docs/sdk/src/meta_contributing.rs index 0d3ecea4655..b4f9d504c6c 100644 --- a/docs/sdk/src/meta_contributing.rs +++ b/docs/sdk/src/meta_contributing.rs @@ -70,7 +70,7 @@ //! > that they already pose, rather than repeating yourself**. //! //! For more details about documenting guidelines, see: -//! +//! //! //! #### Example: Explaining `#[pallet::call]` //! diff --git a/docs/sdk/src/reference_docs/frame_benchmarking_weight.rs b/docs/sdk/src/reference_docs/frame_benchmarking_weight.rs index 7ebad37ecad..db77547a4bf 100644 --- a/docs/sdk/src/reference_docs/frame_benchmarking_weight.rs +++ b/docs/sdk/src/reference_docs/frame_benchmarking_weight.rs @@ -20,4 +20,4 @@ //! - how to write benchmarks, how you must think of worst case. //! - how to run benchmarks. //! -//! - +//! - diff --git a/polkadot/node/core/pvf/common/src/worker/mod.rs b/polkadot/node/core/pvf/common/src/worker/mod.rs index 5e7deb5ca78..9dcd535d533 100644 --- a/polkadot/node/core/pvf/common/src/worker/mod.rs +++ b/polkadot/node/core/pvf/common/src/worker/mod.rs @@ -319,7 +319,7 @@ pub fn run_worker( } // TODO: We can enable the seccomp networking blacklist on aarch64 as well, but we need a CI - // job to catch regressions. See . + // job to catch regressions. See issue ci_cd/issues/609. #[cfg(all(target_os = "linux", target_arch = "x86_64"))] if security_status.can_enable_seccomp { if let Err(err) = security::seccomp::enable_for_worker(&worker_info) { diff --git a/substrate/client/rpc-api/src/state/mod.rs b/substrate/client/rpc-api/src/state/mod.rs index dbc2a505456..4acc64def2b 100644 --- a/substrate/client/rpc-api/src/state/mod.rs +++ b/substrate/client/rpc-api/src/state/mod.rs @@ -270,8 +270,8 @@ pub trait StateApi { /// [querying substrate storage via rpc][3]. /// /// [1]: https://docs.substrate.io/main-docs/fundamentals/state-transitions-and-storage/ - /// [2]: https://www.shawntabrizi.com/substrate/transparent-keys-in-substrate/ - /// [3]: https://www.shawntabrizi.com/substrate/querying-substrate-storage-via-rpc/ + /// [2]: https://www.shawntabrizi.com/blog/substrate/transparent-keys-in-substrate/ + /// [3]: https://www.shawntabrizi.com/blog/substrate/querying-substrate-storage-via-rpc/ /// /// ### Maximum payload size /// diff --git a/substrate/frame/staking/src/migrations.rs b/substrate/frame/staking/src/migrations.rs index 311e9667ceb..92af4fdba5f 100644 --- a/substrate/frame/staking/src/migrations.rs +++ b/substrate/frame/staking/src/migrations.rs @@ -15,7 +15,7 @@ // See the License for the specific language governing permissions and //! Storage migrations for the Staking pallet. The changelog for this is maintained at -//! [CHANGELOG.md](https://github.com/paritytech/substrate/blob/master/frame/staking/CHANGELOG.md). +//! [CHANGELOG.md](https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/staking/CHANGELOG.md). use super::*; use frame_election_provider_support::SortedListProvider; diff --git a/substrate/frame/state-trie-migration/src/lib.rs b/substrate/frame/state-trie-migration/src/lib.rs index 8652e8e9561..ea28d712605 100644 --- a/substrate/frame/state-trie-migration/src/lib.rs +++ b/substrate/frame/state-trie-migration/src/lib.rs @@ -476,7 +476,7 @@ pub mod pallet { /// - [`frame_support::storage::StorageDoubleMap`]: 96 byte /// /// For more info see - /// + /// #[pallet::constant] type MaxKeyLen: Get; -- GitLab From 01ea45c3a1abb4d696b77fbecc440f7905a8e9b1 Mon Sep 17 00:00:00 2001 From: Nuke Date: Tue, 9 Jan 2024 18:18:59 -0700 Subject: [PATCH 023/392] Fix deps for local docs build for Rust `1.75.0` (#2896) - Fix docs deps build issue (https://github.com/servo/rust-smallvec/issues/327) (Please forgive me and LMK if there are processes I need to follow for the bump a dep here I am not aware of). - Fix links for `meta_contributing` docs, internal and external. - `cargo +nightly fmt` for `/docs/...` files --- Cargo.lock | 4 ++-- docs/mermaid/polkadot_sdk_parachain.mmd | 2 +- docs/sdk/src/guides/your_first_pallet/mod.rs | 2 +- docs/sdk/src/meta_contributing.rs | 23 ++++++++++---------- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f5d57bb50be..c3e5e2ff41b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17418,9 +17418,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.0" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "smol" diff --git a/docs/mermaid/polkadot_sdk_parachain.mmd b/docs/mermaid/polkadot_sdk_parachain.mmd index 3f38fce046c..4cee54ba3f4 100644 --- a/docs/mermaid/polkadot_sdk_parachain.mmd +++ b/docs/mermaid/polkadot_sdk_parachain.mmd @@ -5,7 +5,7 @@ flowchart LR end FRAME -.-> ParachainRuntime - Substrate[Substrate Node Libraries] -.-> ParachainNoe + Substrate[Substrate Node Libraries] -.-> ParachainNode CumulusC[Cumulus Node Libraries] -.-> ParachainNode CumulusR[Cumulus Runtime Libraries] -.-> ParachainRuntime diff --git a/docs/sdk/src/guides/your_first_pallet/mod.rs b/docs/sdk/src/guides/your_first_pallet/mod.rs index c886bc9af84..24eada44a83 100644 --- a/docs/sdk/src/guides/your_first_pallet/mod.rs +++ b/docs/sdk/src/guides/your_first_pallet/mod.rs @@ -365,7 +365,7 @@ pub mod pallet { // ensure sender has enough balance, and if so, calculate what is left after `amount`. let sender_balance = Balances::::get(&sender).ok_or("NonExistentAccount")?; if sender_balance < amount { - return Err("InsufficientBalance".into()) + return Err("InsufficientBalance".into()); } let reminder = sender_balance - amount; diff --git a/docs/sdk/src/meta_contributing.rs b/docs/sdk/src/meta_contributing.rs index b4f9d504c6c..bff475f8e6b 100644 --- a/docs/sdk/src/meta_contributing.rs +++ b/docs/sdk/src/meta_contributing.rs @@ -54,8 +54,8 @@ //! > high level tutorial. They should be explained in the rust-doc of the corresponding type or //! > macro. //! -//! 2. 🧘 Less is More: For reasons mentioned [above](#crate::why-rust-docs), the more concise this -//! crate is, the better. +//! 2. 🧘 Less is More: For reasons mentioned [above](#why-rust-docs), the more concise this crate +//! is, the better. //! 3. √ Don’t Repeat Yourself – DRY: A summary of the above two points. Authors should always //! strive to avoid any duplicate information. Every concept should ideally be documented in //! *ONE* place and one place only. This makes the task of maintaining topics significantly @@ -69,8 +69,7 @@ //! > what topics are already covered in this crate, and how you can build on top of the information //! > that they already pose, rather than repeating yourself**. //! -//! For more details about documenting guidelines, see: -//! +//! For more details see the [latest documenting guidelines](https://github.com/paritytech/polkadot-sdk/blob/master/docs/contributor/DOCUMENTATION_GUIDELINES.md). //! //! #### Example: Explaining `#[pallet::call]` //! @@ -133,14 +132,16 @@ //! compromise, but in the long term, we should work towards finding a way to maintain different //! revisions of this crate. //! -//! ## How to Build +//! ## How to Develop Locally //! -//! To build this crate properly, with with right HTML headers injected, run: +//! To view the docs specific [`crate`] locally for development, including the correct HTML headers +//! injected, run: //! -//! ```no_compile -//! RUSTDOCFLAGS="--html-in-header $(pwd)/docs/sdk/headers/toc.html" cargo doc -p polkadot-sdk-docs +//! ```sh +//! SKIP_WASM_BUILD=1 RUSTDOCFLAGS="--html-in-header $(pwd)/docs/sdk/headers/toc.html" cargo doc -p polkadot-sdk-docs --no-deps --open //! ``` //! -//! adding `--no-deps` would speed up the process while development. If even faster build time for -//! docs is needed, you can temporarily remove most of the substrate/cumulus dependencies that are -//! only used for linking purposes. +//! If even faster build time for docs is needed, you can temporarily remove most of the +//! substrate/cumulus dependencies that are only used for linking purposes. +//! +//! For more on local development, see [`crate::reference_docs::development_environment_advice`]. -- GitLab From a4195326b93bf2c0f4dd8f562a218e0963983d68 Mon Sep 17 00:00:00 2001 From: ordian Date: Wed, 10 Jan 2024 10:32:52 +0100 Subject: [PATCH 024/392] statement-distribution: validator disabling (#1841) Closes #1591. The purpose of this PR is filter out backing statements from the network signed by disabled validators. This is just an optimization, since we will do filtering in the runtime in #1863 to avoid nodes to filter garbage out at block production time. - [x] Ensure it's ok to fiddle with the mask of manifests - [x] Write more unit tests - [x] Test locally - [x] simple zombienet test - [x] PRDoc --------- Co-authored-by: Tsvetomir Dimitrov --- .gitlab/pipeline/zombienet/polkadot.yml | 8 + .../statement-distribution/src/error.rs | 3 + .../statement-distribution/src/v2/grid.rs | 4 +- .../statement-distribution/src/v2/mod.rs | 242 +++- .../statement-distribution/src/v2/requests.rs | 25 +- .../src/v2/statement_store.rs | 13 +- .../src/v2/tests/cluster.rs | 145 +-- .../src/v2/tests/grid.rs | 198 +-- .../src/v2/tests/mod.rs | 180 ++- .../src/v2/tests/requests.rs | 1149 +++++++++++++---- .../node/backing/statement-distribution.md | 25 + .../functional/0010-validator-disabling.toml | 39 + .../functional/0010-validator-disabling.zndsl | 21 + prdoc/pr_1841.prdoc | 18 + 14 files changed, 1407 insertions(+), 663 deletions(-) create mode 100644 polkadot/zombienet_tests/functional/0010-validator-disabling.toml create mode 100644 polkadot/zombienet_tests/functional/0010-validator-disabling.zndsl create mode 100644 prdoc/pr_1841.prdoc diff --git a/.gitlab/pipeline/zombienet/polkadot.yml b/.gitlab/pipeline/zombienet/polkadot.yml index c246d98a048..4112096a2ed 100644 --- a/.gitlab/pipeline/zombienet/polkadot.yml +++ b/.gitlab/pipeline/zombienet/polkadot.yml @@ -139,6 +139,14 @@ zombienet-polkadot-functional-0009-approval-voting-coalescing: --local-dir="${LOCAL_DIR}/functional" --test="0009-approval-voting-coalescing.zndsl" +zombienet-polkadot-functional-0010-validator-disabling: + extends: + - .zombienet-polkadot-common + script: + - /home/nonroot/zombie-net/scripts/ci/run-test-local-env-manager.sh + --local-dir="${LOCAL_DIR}/functional" + --test="0010-validator-disabling.zndsl" + zombienet-polkadot-smoke-0001-parachains-smoke-test: extends: - .zombienet-polkadot-common diff --git a/polkadot/node/network/statement-distribution/src/error.rs b/polkadot/node/network/statement-distribution/src/error.rs index b676e5b6a22..a712ab6da43 100644 --- a/polkadot/node/network/statement-distribution/src/error.rs +++ b/polkadot/node/network/statement-distribution/src/error.rs @@ -75,6 +75,9 @@ pub enum Error { #[error("Fetching availability cores failed {0:?}")] FetchAvailabilityCores(RuntimeApiError), + #[error("Fetching disabled validators failed {0:?}")] + FetchDisabledValidators(runtime::Error), + #[error("Fetching validator groups failed {0:?}")] FetchValidatorGroups(RuntimeApiError), diff --git a/polkadot/node/network/statement-distribution/src/v2/grid.rs b/polkadot/node/network/statement-distribution/src/v2/grid.rs index 19bad34c44f..19f23053192 100644 --- a/polkadot/node/network/statement-distribution/src/v2/grid.rs +++ b/polkadot/node/network/statement-distribution/src/v2/grid.rs @@ -253,7 +253,9 @@ impl GridTracker { /// This checks whether the peer is allowed to send us manifests /// about this group at this relay-parent. This also does sanity /// checks on the format of the manifest and the amount of votes - /// it contains. It has effects on the stored state only when successful. + /// it contains. It assumes that the votes from disabled validators + /// are already filtered out. + /// It has effects on the stored state only when successful. /// /// This returns a `bool` on success, which if true indicates that an acknowledgement is /// to be sent in response to the received manifest. This only occurs when the diff --git a/polkadot/node/network/statement-distribution/src/v2/mod.rs b/polkadot/node/network/statement-distribution/src/v2/mod.rs index 2f06d3685b8..02fdecdd9bb 100644 --- a/polkadot/node/network/statement-distribution/src/v2/mod.rs +++ b/polkadot/node/network/statement-distribution/src/v2/mod.rs @@ -17,11 +17,11 @@ //! Implementation of the v2 statement distribution protocol, //! designed for asynchronous backing. -use net_protocol::{filter_by_peer_version, peer_set::ProtocolVersion}; +use bitvec::prelude::{BitVec, Lsb0}; use polkadot_node_network_protocol::{ - self as net_protocol, + self as net_protocol, filter_by_peer_version, grid_topology::SessionGridTopology, - peer_set::ValidationVersion, + peer_set::{ProtocolVersion, ValidationVersion}, request_response::{ incoming::OutgoingResponse, v2::{AttestedCandidateRequest, AttestedCandidateResponse}, @@ -64,7 +64,7 @@ use futures::{ use std::{ collections::{ hash_map::{Entry, HashMap}, - HashSet, + BTreeSet, HashSet, }, time::{Duration, Instant}, }; @@ -96,6 +96,7 @@ const COST_UNEXPECTED_STATEMENT: Rep = Rep::CostMinor("Unexpected Statement"); const COST_UNEXPECTED_STATEMENT_MISSING_KNOWLEDGE: Rep = Rep::CostMinor("Unexpected Statement, missing knowledge for relay parent"); const COST_EXCESSIVE_SECONDED: Rep = Rep::CostMinor("Sent Excessive `Seconded` Statements"); +const COST_DISABLED_VALIDATOR: Rep = Rep::CostMinor("Sent a statement from a disabled validator"); const COST_UNEXPECTED_MANIFEST_MISSING_KNOWLEDGE: Rep = Rep::CostMinor("Unexpected Manifest, missing knowlege for relay parent"); @@ -189,6 +190,8 @@ struct PerSessionState { // getting the topology from the gossip-support subsystem grid_view: Option, local_validator: Option, + // We store the latest state here based on union of leaves. + disabled_validators: BTreeSet, } impl PerSessionState { @@ -205,7 +208,16 @@ impl PerSessionState { ) .map(|(_, index)| LocalValidatorIndex::Active(index)); - PerSessionState { session_info, groups, authority_lookup, grid_view: None, local_validator } + let disabled_validators = BTreeSet::new(); + + PerSessionState { + session_info, + groups, + authority_lookup, + grid_view: None, + local_validator, + disabled_validators, + } } fn supply_topology( @@ -234,6 +246,33 @@ impl PerSessionState { fn is_not_validator(&self) -> bool { self.grid_view.is_some() && self.local_validator.is_none() } + + /// A convenience function to generate a disabled bitmask for the given backing group. + /// The output bits are set to `true` for validators that are disabled. + /// Returns `None` if the group index is out of bounds. + pub fn disabled_bitmask(&self, group: GroupIndex) -> Option> { + let group = self.groups.get(group)?; + let mask = BitVec::from_iter(group.iter().map(|v| self.is_disabled(v))); + Some(mask) + } + + /// Returns `true` if the given validator is disabled in the current session. + pub fn is_disabled(&self, validator_index: &ValidatorIndex) -> bool { + self.disabled_validators.contains(validator_index) + } + + /// Extend the list of disabled validators. + pub fn extend_disabled_validators( + &mut self, + disabled: impl IntoIterator, + ) { + self.disabled_validators.extend(disabled); + } + + /// Clear the list of disabled validators. + pub fn clear_disabled_validators(&mut self) { + self.disabled_validators.clear(); + } } pub(crate) struct State { @@ -510,13 +549,20 @@ pub(crate) async fn handle_active_leaves_update( let new_relay_parents = state.implicit_view.all_allowed_relay_parents().cloned().collect::>(); - for new_relay_parent in new_relay_parents.iter().cloned() { - if state.per_relay_parent.contains_key(&new_relay_parent) { - continue - } - // New leaf: fetch info from runtime API and initialize - // `per_relay_parent`. + // We clear the list of disabled validators to reset it properly based on union of leaves. + let mut cleared_disabled_validators: BTreeSet = BTreeSet::new(); + + for new_relay_parent in new_relay_parents.iter().cloned() { + // Even if we processed this relay parent before, we need to fetch the list of disabled + // validators based on union of active leaves. + let disabled_validators = + polkadot_node_subsystem_util::vstaging::get_disabled_validators_with_fallback( + ctx.sender(), + new_relay_parent, + ) + .await + .map_err(JfyiError::FetchDisabledValidators)?; let session_index = polkadot_node_subsystem_util::request_session_index_for_child( new_relay_parent, @@ -527,23 +573,6 @@ pub(crate) async fn handle_active_leaves_update( .map_err(JfyiError::RuntimeApiUnavailable)? .map_err(JfyiError::FetchSessionIndex)?; - let availability_cores = polkadot_node_subsystem_util::request_availability_cores( - new_relay_parent, - ctx.sender(), - ) - .await - .await - .map_err(JfyiError::RuntimeApiUnavailable)? - .map_err(JfyiError::FetchAvailabilityCores)?; - - let group_rotation_info = - polkadot_node_subsystem_util::request_validator_groups(new_relay_parent, ctx.sender()) - .await - .await - .map_err(JfyiError::RuntimeApiUnavailable)? - .map_err(JfyiError::FetchValidatorGroups)? - .1; - if !state.per_session.contains_key(&session_index) { let session_info = polkadot_node_subsystem_util::request_session_info( new_relay_parent, @@ -579,9 +608,49 @@ pub(crate) async fn handle_active_leaves_update( let per_session = state .per_session - .get(&session_index) + .get_mut(&session_index) .expect("either existed or just inserted; qed"); + if cleared_disabled_validators.insert(session_index) { + per_session.clear_disabled_validators(); + } + + if !disabled_validators.is_empty() { + gum::debug!( + target: LOG_TARGET, + relay_parent = ?new_relay_parent, + ?session_index, + ?disabled_validators, + "Disabled validators detected" + ); + + per_session.extend_disabled_validators(disabled_validators); + } + + if state.per_relay_parent.contains_key(&new_relay_parent) { + continue + } + + // New leaf: fetch info from runtime API and initialize + // `per_relay_parent`. + + let availability_cores = polkadot_node_subsystem_util::request_availability_cores( + new_relay_parent, + ctx.sender(), + ) + .await + .await + .map_err(JfyiError::RuntimeApiUnavailable)? + .map_err(JfyiError::FetchAvailabilityCores)?; + + let group_rotation_info = + polkadot_node_subsystem_util::request_validator_groups(new_relay_parent, ctx.sender()) + .await + .await + .map_err(JfyiError::RuntimeApiUnavailable)? + .map_err(JfyiError::FetchValidatorGroups)? + .1; + let local_validator = per_session.local_validator.and_then(|v| { if let LocalValidatorIndex::Active(idx) = v { find_active_validator_state( @@ -1452,6 +1521,17 @@ async fn handle_incoming_statement( }, }; + if per_session.is_disabled(&statement.unchecked_validator_index()) { + gum::debug!( + target: LOG_TARGET, + ?relay_parent, + validator_index = ?statement.unchecked_validator_index(), + "Ignoring a statement from disabled validator." + ); + modify_reputation(reputation, ctx.sender(), peer, COST_DISABLED_VALIDATOR).await; + return + } + let (active, cluster_sender_index) = { // This block of code only returns `Some` when both the originator and // the sending peer are in the cluster. @@ -1572,7 +1652,7 @@ async fn handle_incoming_statement( checked_statement.clone(), StatementOrigin::Remote, ) { - Err(statement_store::ValidatorUnknown) => { + Err(statement_store::Error::ValidatorUnknown) => { // sanity: should never happen. gum::warn!( target: LOG_TARGET, @@ -2110,7 +2190,7 @@ async fn handle_incoming_manifest_common<'a, Context>( candidate_hash: CandidateHash, relay_parent: Hash, para_id: ParaId, - manifest_summary: grid::ManifestSummary, + mut manifest_summary: grid::ManifestSummary, manifest_kind: grid::ManifestKind, reputation: &mut ReputationAggregator, ) -> Option> { @@ -2195,6 +2275,12 @@ async fn handle_incoming_manifest_common<'a, Context>( // 2. sanity checks: peer is validator, bitvec size, import into grid tracker let group_index = manifest_summary.claimed_group_index; let claimed_parent_hash = manifest_summary.claimed_parent_hash; + + // Ignore votes from disabled validators when counting towards the threshold. + let disabled_mask = per_session.disabled_bitmask(group_index).unwrap_or_default(); + manifest_summary.statement_knowledge.mask_seconded(&disabled_mask); + manifest_summary.statement_knowledge.mask_valid(&disabled_mask); + let acknowledge = match local_validator.grid_tracker.import_manifest( grid_topology, &per_session.groups, @@ -2770,6 +2856,13 @@ pub(crate) async fn dispatch_requests(ctx: &mut Context, state: &mut St } } + // Add disabled validators to the unwanted mask. + let disabled_mask = per_session + .disabled_bitmask(group_index) + .expect("group existence checked above; qed"); + unwanted_mask.seconded_in_group |= &disabled_mask; + unwanted_mask.validated_in_group |= &disabled_mask; + // don't require a backing threshold for cluster candidates. let local_validator = relay_parent_state.local_validator.as_ref()?; let require_backing = local_validator @@ -2777,14 +2870,14 @@ pub(crate) async fn dispatch_requests(ctx: &mut Context, state: &mut St .as_ref() .map_or(true, |active| active.group != group_index); - Some(RequestProperties { - unwanted_mask, - backing_threshold: if require_backing { - Some(per_session.groups.get_size_and_backing_threshold(group_index)?.1) - } else { - None - }, - }) + let backing_threshold = if require_backing { + let threshold = per_session.groups.get_size_and_backing_threshold(group_index)?.1; + Some(threshold) + } else { + None + }; + + Some(RequestProperties { unwanted_mask, backing_threshold }) }; while let Some(request) = state.request_manager.next_request( @@ -2857,6 +2950,10 @@ pub(crate) async fn handle_response( Some(g) => g, }; + let disabled_mask = per_session + .disabled_bitmask(group_index) + .expect("group_index checked above; qed"); + let res = response.validate_response( &mut state.request_manager, group, @@ -2871,6 +2968,7 @@ pub(crate) async fn handle_response( Some(g_index) == expected_group }, + disabled_mask, ); for (peer, rep) in res.reputation_changes { @@ -2968,6 +3066,14 @@ pub(crate) async fn handle_response( // includable. } +/// Returns true if the statement filter meets the backing threshold for grid requests. +pub(crate) fn seconded_and_sufficient( + filter: &StatementFilter, + backing_threshold: Option, +) -> bool { + backing_threshold.map_or(true, |t| filter.has_seconded() && filter.backing_validators() >= t) +} + /// Answer an incoming request for a candidate. pub(crate) fn answer_request(state: &mut State, message: ResponderMessage) { let ResponderMessage { request, sent_feedback } = message; @@ -3008,11 +3114,13 @@ pub(crate) fn answer_request(state: &mut State, message: ResponderMessage) { Some(d) => d, }; - let group_size = per_session + let group_index = confirmed.group_index(); + let group = per_session .groups - .get(confirmed.group_index()) - .expect("group from session's candidate always known; qed") - .len(); + .get(group_index) + .expect("group from session's candidate always known; qed"); + + let group_size = group.len(); // check request bitfields are right size. if mask.seconded_in_group.len() != group_size || mask.validated_in_group.len() != group_size { @@ -3065,17 +3173,59 @@ pub(crate) fn answer_request(state: &mut State, message: ResponderMessage) { // Transform mask with 'OR' semantics into one with 'AND' semantics for the API used // below. - let and_mask = StatementFilter { + let mut and_mask = StatementFilter { seconded_in_group: !mask.seconded_in_group.clone(), validated_in_group: !mask.validated_in_group.clone(), }; + // Ignore disabled validators from the latest state when sending the response. + let disabled_mask = + per_session.disabled_bitmask(group_index).expect("group existence checked; qed"); + and_mask.mask_seconded(&disabled_mask); + and_mask.mask_valid(&disabled_mask); + + let mut sent_filter = StatementFilter::blank(group_size); let statements: Vec<_> = relay_parent_state .statement_store - .group_statements(&per_session.groups, confirmed.group_index(), *candidate_hash, &and_mask) - .map(|s| s.as_unchecked().clone()) + .group_statements(&per_session.groups, group_index, *candidate_hash, &and_mask) + .map(|s| { + let s = s.as_unchecked().clone(); + let index_in_group = |v: ValidatorIndex| group.iter().position(|x| &v == x); + let Some(i) = index_in_group(s.unchecked_validator_index()) else { return s }; + + match s.unchecked_payload() { + CompactStatement::Seconded(_) => { + sent_filter.seconded_in_group.set(i, true); + }, + CompactStatement::Valid(_) => { + sent_filter.validated_in_group.set(i, true); + }, + } + s + }) .collect(); + // There should be no response at all for grid requests when the + // backing threshold is no longer met as a result of disabled validators. + if !is_cluster { + let threshold = per_session + .groups + .get_size_and_backing_threshold(group_index) + .expect("group existence checked above; qed") + .1; + + if !seconded_and_sufficient(&sent_filter, Some(threshold)) { + gum::info!( + target: LOG_TARGET, + ?candidate_hash, + relay_parent = ?confirmed.relay_parent(), + ?group_index, + "Dropping a request from a grid peer because the backing threshold is no longer met." + ); + return + } + } + // Update bookkeeping about which statements peers have received. for statement in &statements { if is_cluster { diff --git a/polkadot/node/network/statement-distribution/src/v2/requests.rs b/polkadot/node/network/statement-distribution/src/v2/requests.rs index 8507a4b8276..bed3d5c18ae 100644 --- a/polkadot/node/network/statement-distribution/src/v2/requests.rs +++ b/polkadot/node/network/statement-distribution/src/v2/requests.rs @@ -30,12 +30,13 @@ //! (which requires state not owned by the request manager). use super::{ - BENEFIT_VALID_RESPONSE, BENEFIT_VALID_STATEMENT, COST_IMPROPERLY_DECODED_RESPONSE, - COST_INVALID_RESPONSE, COST_INVALID_SIGNATURE, COST_UNREQUESTED_RESPONSE_STATEMENT, - REQUEST_RETRY_DELAY, + seconded_and_sufficient, BENEFIT_VALID_RESPONSE, BENEFIT_VALID_STATEMENT, + COST_IMPROPERLY_DECODED_RESPONSE, COST_INVALID_RESPONSE, COST_INVALID_SIGNATURE, + COST_UNREQUESTED_RESPONSE_STATEMENT, REQUEST_RETRY_DELAY, }; use crate::LOG_TARGET; +use bitvec::prelude::{BitVec, Lsb0}; use polkadot_node_network_protocol::{ request_response::{ outgoing::{Recipient as RequestRecipient, RequestError}, @@ -495,10 +496,6 @@ fn find_request_target_with_update( } } -fn seconded_and_sufficient(filter: &StatementFilter, backing_threshold: Option) -> bool { - backing_threshold.map_or(true, |t| filter.has_seconded() && filter.backing_validators() >= t) -} - /// A response to a request, which has not yet been handled. pub struct UnhandledResponse { response: TaggedResponse, @@ -542,6 +539,7 @@ impl UnhandledResponse { session: SessionIndex, validator_key_lookup: impl Fn(ValidatorIndex) -> Option, allowed_para_lookup: impl Fn(ParaId, GroupIndex) -> bool, + disabled_mask: BitVec, ) -> ResponseValidationOutput { let UnhandledResponse { response: TaggedResponse { identifier, requested_peer, props, response }, @@ -625,6 +623,7 @@ impl UnhandledResponse { session, validator_key_lookup, allowed_para_lookup, + disabled_mask, ); if let CandidateRequestStatus::Complete { .. } = output.request_status { @@ -644,6 +643,7 @@ fn validate_complete_response( session: SessionIndex, validator_key_lookup: impl Fn(ValidatorIndex) -> Option, allowed_para_lookup: impl Fn(ParaId, GroupIndex) -> bool, + disabled_mask: BitVec, ) -> ResponseValidationOutput { let RequestProperties { backing_threshold, mut unwanted_mask } = props; @@ -751,6 +751,10 @@ fn validate_complete_response( }, } + if disabled_mask.get(i).map_or(false, |x| *x) { + continue + } + let validator_public = match validator_key_lookup(unchecked_statement.unchecked_validator_index()) { None => { @@ -1013,6 +1017,7 @@ mod tests { let group = &[ValidatorIndex(0), ValidatorIndex(1), ValidatorIndex(2)]; let unwanted_mask = StatementFilter::blank(group_size); + let disabled_mask: BitVec = Default::default(); let request_properties = RequestProperties { unwanted_mask, backing_threshold: None }; // Get requests. @@ -1056,6 +1061,7 @@ mod tests { 0, validator_key_lookup, allowed_para_lookup, + disabled_mask.clone(), ); assert_eq!( output, @@ -1094,6 +1100,7 @@ mod tests { 0, validator_key_lookup, allowed_para_lookup, + disabled_mask, ); assert_eq!( output, @@ -1167,12 +1174,14 @@ mod tests { }; let validator_key_lookup = |_v| None; let allowed_para_lookup = |_para, _g_index| true; + let disabled_mask: BitVec = Default::default(); let output = response.validate_response( &mut request_manager, group, 0, validator_key_lookup, allowed_para_lookup, + disabled_mask, ); assert_eq!( output, @@ -1245,12 +1254,14 @@ mod tests { let validator_key_lookup = |_v| None; let allowed_para_lookup = |_para, _g_index| true; let statements = vec![]; + let disabled_mask: BitVec = Default::default(); let output = response.validate_response( &mut request_manager, group, 0, validator_key_lookup, allowed_para_lookup, + disabled_mask, ); assert_eq!( output, diff --git a/polkadot/node/network/statement-distribution/src/v2/statement_store.rs b/polkadot/node/network/statement-distribution/src/v2/statement_store.rs index 96d976e22cd..022461e5551 100644 --- a/polkadot/node/network/statement-distribution/src/v2/statement_store.rs +++ b/polkadot/node/network/statement-distribution/src/v2/statement_store.rs @@ -97,10 +97,10 @@ impl StatementStore { groups: &Groups, statement: SignedStatement, origin: StatementOrigin, - ) -> Result { + ) -> Result { let validator_index = statement.validator_index(); let validator_meta = match self.validator_meta.get_mut(&validator_index) { - None => return Err(ValidatorUnknown), + None => return Err(Error::ValidatorUnknown), Some(m) => m, }; @@ -134,7 +134,7 @@ impl StatementStore { "groups passed into `insert` differ from those used at store creation" ); - return Err(ValidatorUnknown) + return Err(Error::ValidatorUnknown) }, }; @@ -251,9 +251,12 @@ impl StatementStore { } } -/// Error indicating that the validator was unknown. +/// Error when inserting a statement into the statement store. #[derive(Debug)] -pub struct ValidatorUnknown; +pub enum Error { + /// The validator was unknown. + ValidatorUnknown, +} type Fingerprint = (ValidatorIndex, CompactStatement); diff --git a/polkadot/node/network/statement-distribution/src/v2/tests/cluster.rs b/polkadot/node/network/statement-distribution/src/v2/tests/cluster.rs index a9f5b537b32..7ffed9d47d4 100644 --- a/polkadot/node/network/statement-distribution/src/v2/tests/cluster.rs +++ b/polkadot/node/network/statement-distribution/src/v2/tests/cluster.rs @@ -75,15 +75,7 @@ fn share_seconded_circulated_to_cluster() { send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; let full_signed = state .sign_statement( @@ -120,7 +112,7 @@ fn share_seconded_circulated_to_cluster() { // sharing a `Seconded` message confirms a candidate, which leads to new // fragment tree updates. - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; overseer }); @@ -156,15 +148,7 @@ fn cluster_valid_statement_before_seconded_ignored() { .await; send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; let signed_valid = state.sign_statement( v_a, @@ -226,15 +210,7 @@ fn cluster_statement_bad_signature() { .await; send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; // sign statements with wrong signing context, leading to bad signature. let statements = vec![ @@ -308,15 +284,7 @@ fn useful_cluster_statement_from_non_cluster_peer_rejected() { .await; send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; let statement = state .sign_statement( @@ -370,15 +338,7 @@ fn statement_from_non_cluster_originator_unexpected() { connect_peer(&mut overseer, peer_a.clone(), None).await; send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; let statement = state .sign_statement( @@ -448,15 +408,7 @@ fn seconded_statement_leads_to_request() { .await; send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; let statement = state .sign_statement( @@ -497,7 +449,7 @@ fn seconded_statement_leads_to_request() { if p == peer_a && r == BENEFIT_VALID_RESPONSE.into() => { } ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; overseer }); @@ -544,15 +496,7 @@ fn cluster_statements_shared_seconded_first() { .await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; let full_signed = state .sign_statement( @@ -579,7 +523,7 @@ fn cluster_statements_shared_seconded_first() { .await; // result of new confirmed candidate. - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; overseer .send(FromOrchestra::Communication { @@ -677,15 +621,7 @@ fn cluster_accounts_for_implicit_view() { send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; let full_signed = state .sign_statement( @@ -722,7 +658,7 @@ fn cluster_accounts_for_implicit_view() { // sharing a `Seconded` message confirms a candidate, which leads to new // fragment tree updates. - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; // activate new leaf, which has relay-parent in implicit view. let next_relay_parent = Hash::repeat_byte(2); @@ -730,15 +666,7 @@ fn cluster_accounts_for_implicit_view() { next_test_leaf.parent_hash = relay_parent; next_test_leaf.number = 2; - activate_leaf(&mut overseer, &next_test_leaf, &state, false).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(next_relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &next_test_leaf, &state, false, vec![]).await; send_peer_view_change(&mut overseer, peer_a.clone(), view![next_relay_parent]).await; send_peer_view_change(&mut overseer, peer_b.clone(), view![next_relay_parent]).await; @@ -820,15 +748,7 @@ fn cluster_messages_imported_after_confirmed_candidate_importable_check() { send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; // Peer sends `Seconded` statement. { @@ -885,8 +805,6 @@ fn cluster_messages_imported_after_confirmed_candidate_importable_check() { }, vec![(relay_parent, vec![0])], )], - None, - false, ) .await; @@ -953,15 +871,7 @@ fn cluster_messages_imported_after_new_leaf_importable_check() { send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; // Peer sends `Seconded` statement. { @@ -1008,17 +918,18 @@ fn cluster_messages_imported_after_new_leaf_importable_check() { ); } - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; let next_relay_parent = Hash::repeat_byte(2); let mut next_test_leaf = state.make_dummy_leaf(next_relay_parent); next_test_leaf.parent_hash = relay_parent; next_test_leaf.number = 2; - activate_leaf(&mut overseer, &next_test_leaf, &state, false).await; - - answer_expected_hypothetical_depth_request( + activate_leaf( &mut overseer, + &next_test_leaf, + &state, + false, vec![( HypotheticalCandidate::Complete { candidate_hash, @@ -1027,8 +938,6 @@ fn cluster_messages_imported_after_new_leaf_importable_check() { }, vec![(relay_parent, vec![0])], )], - Some(next_relay_parent), - false, ) .await; @@ -1117,15 +1026,7 @@ fn ensure_seconding_limit_is_respected() { send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; // Confirm the candidates locally so that we don't send out requests. @@ -1152,7 +1053,7 @@ fn ensure_seconding_limit_is_respected() { AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a] ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } // Candidate 2. @@ -1178,7 +1079,7 @@ fn ensure_seconding_limit_is_respected() { AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a] ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } // Send first statement from peer A. diff --git a/polkadot/node/network/statement-distribution/src/v2/tests/grid.rs b/polkadot/node/network/statement-distribution/src/v2/tests/grid.rs index aa1a473b833..1ac9f4d45e7 100644 --- a/polkadot/node/network/statement-distribution/src/v2/tests/grid.rs +++ b/polkadot/node/network/statement-distribution/src/v2/tests/grid.rs @@ -102,15 +102,7 @@ fn backed_candidate_leads_to_advertisement() { send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; // Send gossip topology. send_new_topology(&mut overseer, state.make_dummy_topology()).await; @@ -137,7 +129,7 @@ fn backed_candidate_leads_to_advertisement() { AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a] ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } // Send enough statements to make candidate backable, make sure announcements are sent. @@ -232,7 +224,7 @@ fn backed_candidate_leads_to_advertisement() { } ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } overseer @@ -320,15 +312,7 @@ fn received_advertisement_before_confirmation_leads_to_request() { send_peer_view_change(&mut overseer, peer_d.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; // Send gossip topology. send_new_topology(&mut overseer, state.make_dummy_topology()).await; @@ -400,7 +384,7 @@ fn received_advertisement_before_confirmation_leads_to_request() { if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() => { } ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } overseer @@ -530,7 +514,7 @@ fn received_advertisement_after_backing_leads_to_acknowledgement() { assert_peer_reported!(&mut overseer, peer_c, BENEFIT_VALID_STATEMENT); assert_peer_reported!(&mut overseer, peer_c, BENEFIT_VALID_RESPONSE); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } // Receive Backed message. @@ -561,7 +545,7 @@ fn received_advertisement_after_backing_leads_to_acknowledgement() { } ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } // Receive a manifest about the same candidate from peer D. @@ -733,7 +717,7 @@ fn received_acknowledgements_for_locally_confirmed() { AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a] ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } // Receive an unexpected acknowledgement from peer D. @@ -798,7 +782,7 @@ fn received_acknowledgements_for_locally_confirmed() { } ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } // Receive an unexpected acknowledgement from peer D. @@ -930,7 +914,7 @@ fn received_acknowledgements_for_externally_confirmed() { assert_peer_reported!(&mut overseer, peer_c, BENEFIT_VALID_STATEMENT); assert_peer_reported!(&mut overseer, peer_c, BENEFIT_VALID_RESPONSE); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } let ack = BackedCandidateAcknowledgement { @@ -1022,15 +1006,7 @@ fn received_advertisement_after_confirmation_before_backing() { send_peer_view_change(&mut overseer, peer_e.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; // Send gossip topology. send_new_topology(&mut overseer, state.make_dummy_topology()).await; @@ -1121,7 +1097,7 @@ fn received_advertisement_after_confirmation_before_backing() { if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } // Receive advertisement from peer D (after confirmation but before backing). @@ -1208,15 +1184,7 @@ fn additional_statements_are_shared_after_manifest_exchange() { send_peer_view_change(&mut overseer, peer_e.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; // Send gossip topology. send_new_topology(&mut overseer, state.make_dummy_topology()).await; @@ -1301,13 +1269,8 @@ fn additional_statements_are_shared_after_manifest_exchange() { persisted_validation_data: pvd.clone(), }; let membership = vec![(relay_parent, vec![0])]; - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![(hypothetical, membership)], - None, - false, - ) - .await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![(hypothetical, membership)]) + .await; // Statements are sent to the Backing subsystem. { @@ -1371,7 +1334,7 @@ fn additional_statements_are_shared_after_manifest_exchange() { } ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } // Receive a manifest about the same candidate from peer D. Contains different statements. @@ -1514,17 +1477,8 @@ fn advertisement_sent_when_peer_enters_relay_parent_view() { send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; - - // Send gossip topology. send_new_topology(&mut overseer, state.make_dummy_topology()).await; // Confirm the candidate locally so that we don't send out requests. @@ -1549,7 +1503,7 @@ fn advertisement_sent_when_peer_enters_relay_parent_view() { AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a] ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } // Send enough statements to make candidate backable, make sure announcements are sent. @@ -1616,7 +1570,7 @@ fn advertisement_sent_when_peer_enters_relay_parent_view() { }) .await; - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; // Relay parent enters view of peer C. { @@ -1737,17 +1691,8 @@ fn advertisement_not_re_sent_when_peer_re_enters_view() { send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; - // Send gossip topology. send_new_topology(&mut overseer, state.make_dummy_topology()).await; // Confirm the candidate locally so that we don't send out requests. @@ -1772,7 +1717,7 @@ fn advertisement_not_re_sent_when_peer_re_enters_view() { AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a] ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } // Send enough statements to make candidate backable, make sure announcements are sent. @@ -1867,7 +1812,7 @@ fn advertisement_not_re_sent_when_peer_re_enters_view() { } ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } // Peer leaves view. @@ -1949,17 +1894,8 @@ fn grid_statements_imported_to_backing() { send_peer_view_change(&mut overseer, peer_e.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; - - // Send gossip topology. send_new_topology(&mut overseer, state.make_dummy_topology()).await; // Receive an advertisement from C. @@ -2042,13 +1978,8 @@ fn grid_statements_imported_to_backing() { persisted_validation_data: pvd.clone(), }; let membership = vec![(relay_parent, vec![0])]; - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![(hypothetical, membership)], - None, - false, - ) - .await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![(hypothetical, membership)]) + .await; // Receive messages from Backing subsystem. { @@ -2165,17 +2096,8 @@ fn advertisements_rejected_from_incorrect_peers() { send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; - - // Send gossip topology. send_new_topology(&mut overseer, state.make_dummy_topology()).await; let manifest = BackedCandidateManifest { @@ -2289,17 +2211,8 @@ fn manifest_rejected_with_unknown_relay_parent() { send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; - // Send gossip topology. send_new_topology(&mut overseer, state.make_dummy_topology()).await; let manifest = BackedCandidateManifest { @@ -2391,17 +2304,8 @@ fn manifest_rejected_when_not_a_validator() { send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; - - // Send gossip topology. send_new_topology(&mut overseer, state.make_dummy_topology()).await; let manifest = BackedCandidateManifest { @@ -2498,17 +2402,8 @@ fn manifest_rejected_when_group_does_not_match_para() { send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; - - // Send gossip topology. send_new_topology(&mut overseer, state.make_dummy_topology()).await; let manifest = BackedCandidateManifest { @@ -2613,17 +2508,8 @@ fn peer_reported_for_advertisement_conflicting_with_confirmed_candidate() { send_peer_view_change(&mut overseer, peer_e.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; - // Send gossip topology. send_new_topology(&mut overseer, state.make_dummy_topology()).await; let manifest = BackedCandidateManifest { @@ -2713,7 +2599,7 @@ fn peer_reported_for_advertisement_conflicting_with_confirmed_candidate() { if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } // Receive conflicting advertisement from peer C after confirmation. @@ -2755,7 +2641,6 @@ fn inactive_local_participates_in_grid() { async_backing_params: None, }; - let dummy_relay_parent = Hash::repeat_byte(2); let relay_parent = Hash::repeat_byte(1); let peer_a = PeerId::random(); @@ -2795,25 +2680,10 @@ fn inactive_local_participates_in_grid() { send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &dummy_leaf, &state, true).await; - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(dummy_relay_parent), - false, - ) - .await; - + activate_leaf(&mut overseer, &dummy_leaf, &state, true, vec![]).await; // Send gossip topology. send_new_topology(&mut overseer, state.make_dummy_topology()).await; - activate_leaf(&mut overseer, &test_leaf, &state, false).await; - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, false, vec![]).await; // Receive an advertisement from A. let manifest = BackedCandidateManifest { @@ -2876,7 +2746,7 @@ fn inactive_local_participates_in_grid() { AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) if p == peer_a && r == BENEFIT_VALID_RESPONSE.into() => { } ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; overseer }); diff --git a/polkadot/node/network/statement-distribution/src/v2/tests/mod.rs b/polkadot/node/network/statement-distribution/src/v2/tests/mod.rs index c34cf20d716..3ce43202b95 100644 --- a/polkadot/node/network/statement-distribution/src/v2/tests/mod.rs +++ b/polkadot/node/network/statement-distribution/src/v2/tests/mod.rs @@ -187,12 +187,30 @@ impl TestState { collator: None, }) }), + disabled_validators: Default::default(), para_data: (0..self.session_info.validator_groups.len()) .map(|i| (ParaId::from(i as u32), PerParaData::new(1, vec![1, 2, 3].into()))) .collect(), + minimum_backing_votes: 2, } } + fn make_dummy_leaf_with_disabled_validators( + &self, + relay_parent: Hash, + disabled_validators: Vec, + ) -> TestLeaf { + TestLeaf { disabled_validators, ..self.make_dummy_leaf(relay_parent) } + } + + fn make_dummy_leaf_with_min_backing_votes( + &self, + relay_parent: Hash, + minimum_backing_votes: u32, + ) -> TestLeaf { + TestLeaf { minimum_backing_votes, ..self.make_dummy_leaf(relay_parent) } + } + fn make_availability_cores(&self, f: impl Fn(usize) -> CoreState) -> Vec { (0..self.session_info.validator_groups.len()).map(f).collect() } @@ -240,6 +258,19 @@ impl TestState { .collect() } + fn index_within_group( + &self, + group_index: GroupIndex, + validator_index: ValidatorIndex, + ) -> Option { + self.session_info + .validator_groups + .get(group_index) + .unwrap() + .iter() + .position(|&i| i == validator_index) + } + fn discovery_id(&self, validator_index: ValidatorIndex) -> AuthorityDiscoveryId { self.session_info.discovery_keys[validator_index.0 as usize].clone() } @@ -284,7 +315,7 @@ impl TestState { &mut self, peer: PeerId, request: AttestedCandidateRequest, - ) -> impl Future { + ) -> impl Future> { let (tx, rx) = futures::channel::oneshot::channel(); let req = sc_network::config::IncomingRequest { peer, @@ -293,7 +324,7 @@ impl TestState { }; self.req_sender.send(req).await.unwrap(); - rx.map(|r| r.unwrap()) + rx.map(|r| r.ok()) } } @@ -366,7 +397,9 @@ struct TestLeaf { parent_hash: Hash, session: SessionIndex, availability_cores: Vec, + disabled_validators: Vec, para_data: Vec<(ParaId, PerParaData)>, + minimum_backing_votes: u32, } impl TestLeaf { @@ -447,9 +480,7 @@ async fn setup_test_and_connect_peers( } } - activate_leaf(overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request(overseer, vec![], Some(relay_parent), false).await; + activate_leaf(overseer, &test_leaf, &state, true, vec![]).await; // Send gossip topology. send_new_topology(overseer, state.make_dummy_topology()).await; @@ -472,6 +503,7 @@ async fn activate_leaf( leaf: &TestLeaf, test_state: &TestState, is_new_session: bool, + hypothetical_frontier: Vec<(HypotheticalCandidate, FragmentTreeMembership)>, ) { let activated = new_leaf(leaf.hash, leaf.number); @@ -481,7 +513,14 @@ async fn activate_leaf( )))) .await; - handle_leaf_activation(virtual_overseer, leaf, test_state, is_new_session).await; + handle_leaf_activation( + virtual_overseer, + leaf, + test_state, + is_new_session, + hypothetical_frontier, + ) + .await; } async fn handle_leaf_activation( @@ -489,8 +528,18 @@ async fn handle_leaf_activation( leaf: &TestLeaf, test_state: &TestState, is_new_session: bool, + hypothetical_frontier: Vec<(HypotheticalCandidate, FragmentTreeMembership)>, ) { - let TestLeaf { number, hash, parent_hash, para_data, session, availability_cores } = leaf; + let TestLeaf { + number, + hash, + parent_hash, + para_data, + session, + availability_cores, + disabled_validators, + minimum_backing_votes, + } = leaf; assert_matches!( virtual_overseer.recv().await, @@ -530,51 +579,82 @@ async fn handle_leaf_activation( } ); - assert_matches!( - virtual_overseer.recv().await, - AllMessages::RuntimeApi( - RuntimeApiMessage::Request(parent, RuntimeApiRequest::SessionIndexForChild(tx))) if parent == *hash => { - tx.send(Ok(*session)).unwrap(); - } - ); - - assert_matches!( - virtual_overseer.recv().await, - AllMessages::RuntimeApi( - RuntimeApiMessage::Request(parent, RuntimeApiRequest::AvailabilityCores(tx))) if parent == *hash => { - tx.send(Ok(availability_cores.clone())).unwrap(); - } - ); - - let validator_groups = test_state.session_info.validator_groups.to_vec(); - let group_rotation_info = - GroupRotationInfo { session_start_block: 1, group_rotation_frequency: 12, now: 1 }; - assert_matches!( - virtual_overseer.recv().await, - AllMessages::RuntimeApi( - RuntimeApiMessage::Request(parent, RuntimeApiRequest::ValidatorGroups(tx))) if parent == *hash => { - tx.send(Ok((validator_groups, group_rotation_info))).unwrap(); - } - ); - - if is_new_session { - assert_matches!( - virtual_overseer.recv().await, - AllMessages::RuntimeApi( - RuntimeApiMessage::Request(parent, RuntimeApiRequest::SessionInfo(s, tx))) if parent == *hash && s == *session => { + loop { + match virtual_overseer.recv().await { + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _parent, + RuntimeApiRequest::Version(tx), + )) => { + tx.send(Ok(RuntimeApiRequest::DISABLED_VALIDATORS_RUNTIME_REQUIREMENT)).unwrap(); + }, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + parent, + RuntimeApiRequest::DisabledValidators(tx), + )) if parent == *hash => { + tx.send(Ok(disabled_validators.clone())).unwrap(); + }, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _parent, + RuntimeApiRequest::DisabledValidators(tx), + )) => { + tx.send(Ok(Vec::new())).unwrap(); + }, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + _parent, // assume all active leaves are in the same session + RuntimeApiRequest::SessionIndexForChild(tx), + )) => { + tx.send(Ok(*session)).unwrap(); + }, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + parent, + RuntimeApiRequest::SessionInfo(s, tx), + )) if parent == *hash && s == *session => { + assert!(is_new_session, "only expecting this call in a new session"); tx.send(Ok(Some(test_state.session_info.clone()))).unwrap(); - } - ); - - assert_matches!( - virtual_overseer.recv().await, + }, AllMessages::RuntimeApi(RuntimeApiMessage::Request( parent, RuntimeApiRequest::MinimumBackingVotes(session_index, tx), )) if parent == *hash && session_index == *session => { - tx.send(Ok(2)).unwrap(); - } - ); + assert!(is_new_session, "only expecting this call in a new session"); + tx.send(Ok(*minimum_backing_votes)).unwrap(); + }, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + parent, + RuntimeApiRequest::AvailabilityCores(tx), + )) if parent == *hash => { + tx.send(Ok(availability_cores.clone())).unwrap(); + }, + AllMessages::RuntimeApi(RuntimeApiMessage::Request( + parent, + RuntimeApiRequest::ValidatorGroups(tx), + )) if parent == *hash => { + let validator_groups = test_state.session_info.validator_groups.to_vec(); + let group_rotation_info = GroupRotationInfo { + session_start_block: 1, + group_rotation_frequency: 12, + now: 1, + }; + tx.send(Ok((validator_groups, group_rotation_info))).unwrap(); + }, + AllMessages::ProspectiveParachains( + ProspectiveParachainsMessage::GetHypotheticalFrontier(req, tx), + ) => { + assert_eq!(req.fragment_tree_relay_parent, Some(*hash)); + assert!(!req.backed_in_path_only); + for (i, (candidate, _)) in hypothetical_frontier.iter().enumerate() { + assert!( + req.candidates.iter().any(|c| &c == &candidate), + "did not receive request for hypothetical candidate {}", + i, + ); + } + tx.send(hypothetical_frontier).unwrap(); + // this is the last expected runtime api call + break + }, + msg => panic!("unexpected runtime API call: {msg:?}"), + } } } @@ -614,16 +694,14 @@ async fn handle_sent_request( async fn answer_expected_hypothetical_depth_request( virtual_overseer: &mut VirtualOverseer, responses: Vec<(HypotheticalCandidate, FragmentTreeMembership)>, - expected_leaf_hash: Option, - expected_backed_in_path_only: bool, ) { assert_matches!( virtual_overseer.recv().await, AllMessages::ProspectiveParachains( ProspectiveParachainsMessage::GetHypotheticalFrontier(req, tx) ) => { - assert_eq!(req.fragment_tree_relay_parent, expected_leaf_hash); - assert_eq!(req.backed_in_path_only, expected_backed_in_path_only); + assert_eq!(req.fragment_tree_relay_parent, None); + assert!(!req.backed_in_path_only); for (i, (candidate, _)) in responses.iter().enumerate() { assert!( req.candidates.iter().any(|c| &c == &candidate), diff --git a/polkadot/node/network/statement-distribution/src/v2/tests/requests.rs b/polkadot/node/network/statement-distribution/src/v2/tests/requests.rs index 1eec8290fab..04934b31482 100644 --- a/polkadot/node/network/statement-distribution/src/v2/tests/requests.rs +++ b/polkadot/node/network/statement-distribution/src/v2/tests/requests.rs @@ -86,15 +86,7 @@ fn cluster_peer_allowed_to_send_incomplete_statements() { send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; // Peer in cluster sends a statement, triggering a request. { @@ -176,7 +168,7 @@ fn cluster_peer_allowed_to_send_incomplete_statements() { ); } - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; overseer }); @@ -272,15 +264,7 @@ fn peer_reported_for_providing_statements_meant_to_be_masked_out() { send_peer_view_change(&mut overseer, peer_e.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; // Send gossip topology. send_new_topology(&mut overseer, state.make_dummy_topology()).await; @@ -354,7 +338,7 @@ fn peer_reported_for_providing_statements_meant_to_be_masked_out() { if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } // Peer C advertises candidate 2. @@ -426,7 +410,7 @@ fn peer_reported_for_providing_statements_meant_to_be_masked_out() { if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } // Peer C sends an announcement for candidate 3. Should hit seconding limit for validator 1. @@ -537,15 +521,7 @@ fn peer_reported_for_not_enough_statements() { send_peer_view_change(&mut overseer, peer_e.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; // Send gossip topology. send_new_topology(&mut overseer, state.make_dummy_topology()).await; @@ -657,7 +633,7 @@ fn peer_reported_for_not_enough_statements() { if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } overseer @@ -725,15 +701,7 @@ fn peer_reported_for_duplicate_statements() { send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; // Peer in cluster sends a statement, triggering a request. { @@ -820,7 +788,7 @@ fn peer_reported_for_duplicate_statements() { ); } - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; overseer }); @@ -887,15 +855,7 @@ fn peer_reported_for_providing_statements_with_invalid_signatures() { send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; // Peer in cluster sends a statement, triggering a request. { @@ -958,7 +918,7 @@ fn peer_reported_for_providing_statements_with_invalid_signatures() { if p == peer_a && r == BENEFIT_VALID_RESPONSE.into() => { } ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } overseer @@ -1026,15 +986,7 @@ fn peer_reported_for_providing_statements_with_wrong_validator_id() { send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; // Peer in cluster sends a statement, triggering a request. { @@ -1096,7 +1048,7 @@ fn peer_reported_for_providing_statements_with_wrong_validator_id() { if p == peer_a && r == BENEFIT_VALID_RESPONSE.into() => { } ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } overseer @@ -1104,26 +1056,31 @@ fn peer_reported_for_providing_statements_with_wrong_validator_id() { } #[test] -fn local_node_sanity_checks_incoming_requests() { +fn disabled_validators_added_to_unwanted_mask() { + let group_size = 3; let config = TestConfig { validator_count: 20, - group_size: 3, + group_size, local_validator: LocalRole::Validator, async_backing_params: None, }; let relay_parent = Hash::repeat_byte(1); - let peer_a = PeerId::random(); + let peer_disabled = PeerId::random(); let peer_b = PeerId::random(); - let peer_c = PeerId::random(); - let peer_d = PeerId::random(); - test_harness(config, |mut state, mut overseer| async move { + test_harness(config, |state, mut overseer| async move { let local_validator = state.local.clone().unwrap(); let local_group_index = local_validator.group_index.unwrap(); let local_para = ParaId::from(local_group_index.0); + let other_group_validators = state.group_validators(local_group_index, true); + let index_disabled = other_group_validators[0]; + let index_within_group = state.index_within_group(local_group_index, index_disabled); + let index_b = other_group_validators[1]; - let test_leaf = state.make_dummy_leaf(relay_parent); + let disabled_validators = vec![index_disabled]; + let test_leaf = + state.make_dummy_leaf_with_disabled_validators(relay_parent, disabled_validators); let (candidate, pvd) = make_candidate( relay_parent, @@ -1135,200 +1092,164 @@ fn local_node_sanity_checks_incoming_requests() { ); let candidate_hash = candidate.hash(); - // peer A is in group, has relay parent in view. - // peer B is in group, has no relay parent in view. - // peer C is not in group, has relay parent in view. + // peer A is in group, has relay parent in view and disabled. + // peer B is in group, has relay parent in view. { - let other_group_validators = state.group_validators(local_group_index, true); - connect_peer( &mut overseer, - peer_a.clone(), - Some(vec![state.discovery_id(other_group_validators[0])].into_iter().collect()), + peer_disabled.clone(), + Some(vec![state.discovery_id(index_disabled)].into_iter().collect()), ) .await; - connect_peer( &mut overseer, peer_b.clone(), - Some(vec![state.discovery_id(other_group_validators[1])].into_iter().collect()), + Some(vec![state.discovery_id(index_b)].into_iter().collect()), ) .await; - - connect_peer(&mut overseer, peer_c.clone(), None).await; - - send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; - send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_disabled.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_b.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; - let mask = StatementFilter::blank(state.config.group_size); + let seconded_disabled = state + .sign_statement( + index_disabled, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); - // Should drop requests for unknown candidates. + let seconded_b = state + .sign_statement( + index_b, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); { - let (pending_response, rx) = oneshot::channel(); - state - .req_sender - .send(RawIncomingRequest { - // Request from peer that received manifest. - peer: peer_c, - payload: request_v2::AttestedCandidateRequest { - candidate_hash: candidate.hash(), - mask: mask.clone(), - } - .encode(), - pending_response, - }) - .await - .unwrap(); + send_peer_message( + &mut overseer, + peer_disabled.clone(), + protocol_v2::StatementDistributionMessage::Statement( + relay_parent, + seconded_disabled.clone(), + ), + ) + .await; - assert_matches!(rx.await, Err(oneshot::Canceled)); + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_disabled && r == COST_DISABLED_VALIDATOR.into() => { } + ); } - // Confirm candidate. { - let full_signed = state - .sign_statement( - local_validator.validator_index, - CompactStatement::Seconded(candidate_hash), - &SigningContext { session_index: 1, parent_hash: relay_parent }, - ) - .convert_to_superpayload(StatementWithPVD::Seconded(candidate.clone(), pvd.clone())) - .unwrap(); - - overseer - .send(FromOrchestra::Communication { - msg: StatementDistributionMessage::Share(relay_parent, full_signed), - }) - .await; + send_peer_message( + &mut overseer, + peer_b.clone(), + protocol_v2::StatementDistributionMessage::Statement( + relay_parent, + seconded_b.clone(), + ), + ) + .await; assert_matches!( overseer.recv().await, - AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( - peers, - Versioned::V2(protocol_v2::ValidationProtocol::StatementDistribution( - protocol_v2::StatementDistributionMessage::Statement( - r, - s, - ) - )) - )) => { - assert_eq!(peers, vec![peer_a.clone()]); - assert_eq!(r, relay_parent); - assert_eq!(s.unchecked_payload(), &CompactStatement::Seconded(candidate_hash)); - assert_eq!(s.unchecked_validator_index(), local_validator.validator_index); - } + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_b && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } ); - - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; } - // Should drop requests from unknown peers. + // Send a request to peer and mock its response with a statement from disabled validator. { - let (pending_response, rx) = oneshot::channel(); - state - .req_sender - .send(RawIncomingRequest { - // Request from peer that received manifest. - peer: peer_d, - payload: request_v2::AttestedCandidateRequest { - candidate_hash: candidate.hash(), - mask: mask.clone(), - } - .encode(), - pending_response, - }) - .await - .unwrap(); - - assert_matches!(rx.await, Err(oneshot::Canceled)); - } + let statements = vec![seconded_disabled]; + let mut mask = StatementFilter::blank(group_size); + let i = index_within_group.unwrap(); + mask.seconded_in_group.set(i, true); + mask.validated_in_group.set(i, true); - // Should drop requests with bitfields of the wrong size. - { - let mask = StatementFilter::blank(state.config.group_size + 1); - let response = state - .send_request( - peer_c, - request_v2::AttestedCandidateRequest { candidate_hash: candidate.hash(), mask }, - ) - .await - .await; + handle_sent_request( + &mut overseer, + peer_b, + candidate_hash, + mask, + candidate.clone(), + pvd.clone(), + statements, + ) + .await; assert_matches!( - response, - RawOutgoingResponse { - result, - reputation_changes, - sent_feedback - } => { - assert_matches!(result, Err(())); - assert_eq!(reputation_changes, vec![COST_INVALID_REQUEST_BITFIELD_SIZE.into()]); - assert_matches!(sent_feedback, None); - } + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_b && r == COST_UNREQUESTED_RESPONSE_STATEMENT.into() => { } ); - } - // Local node should reject requests if we did not send a manifest to that peer. - { - let response = state - .send_request( - peer_c, - request_v2::AttestedCandidateRequest { - candidate_hash: candidate.hash(), - mask: mask.clone(), - }, - ) - .await - .await; + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_b && r == BENEFIT_VALID_RESPONSE.into() => { } + ); - // Should get `COST_UNEXPECTED_REQUEST` response. assert_matches!( - response, - RawOutgoingResponse { - result, - reputation_changes, - sent_feedback - } => { - assert_matches!(result, Err(())); - assert_eq!(reputation_changes, vec![COST_UNEXPECTED_REQUEST.into()]); - assert_matches!(sent_feedback, None); + overseer.recv().await, + AllMessages:: NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::V2( + protocol_v2::ValidationProtocol::StatementDistribution( + protocol_v2::StatementDistributionMessage::Statement(hash, statement), + ), + ), + ) + ) => { + assert_eq!(peers, vec![peer_disabled]); + assert_eq!(hash, relay_parent); + assert_eq!(statement, seconded_b); } ); + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } overseer }); } +// We send a request to a peer and after receiving the response +// we learn about a validator being disabled. We should filter out +// the statement from the disabled validator when receiving it. #[test] -fn local_node_checks_that_peer_can_request_before_responding() { +fn when_validator_disabled_after_sending_the_request() { + let group_size = 3; let config = TestConfig { validator_count: 20, - group_size: 3, + group_size, local_validator: LocalRole::Validator, async_backing_params: None, }; let relay_parent = Hash::repeat_byte(1); - let peer_a = PeerId::random(); + let another_relay_parent = Hash::repeat_byte(2); + let peer_disabled_later = PeerId::random(); let peer_b = PeerId::random(); - test_harness(config, |mut state, mut overseer| async move { + test_harness(config, |state, mut overseer| async move { let local_validator = state.local.clone().unwrap(); let local_group_index = local_validator.group_index.unwrap(); let local_para = ParaId::from(local_group_index.0); + let other_group_validators = state.group_validators(local_group_index, true); + let index_disabled = other_group_validators[0]; + let index_b = other_group_validators[1]; - let test_leaf = state.make_dummy_leaf(relay_parent); + let test_leaf = state.make_dummy_leaf_with_disabled_validators(relay_parent, vec![]); + let test_leaf_disabled = state + .make_dummy_leaf_with_disabled_validators(another_relay_parent, vec![index_disabled]); let (candidate, pvd) = make_candidate( relay_parent, @@ -1340,20 +1261,733 @@ fn local_node_checks_that_peer_can_request_before_responding() { ); let candidate_hash = candidate.hash(); - // Peers A and B are in group and have relay parent in view. - let other_group_validators = state.group_validators(local_group_index, true); + // peer A is in group, has relay parent in view and disabled later. + // peer B is in group, has relay parent in view. + { + connect_peer( + &mut overseer, + peer_disabled_later.clone(), + Some(vec![state.discovery_id(index_disabled)].into_iter().collect()), + ) + .await; + connect_peer( + &mut overseer, + peer_b.clone(), + Some(vec![state.discovery_id(index_b)].into_iter().collect()), + ) + .await; + send_peer_view_change(&mut overseer, peer_disabled_later.clone(), view![relay_parent]) + .await; + send_peer_view_change(&mut overseer, peer_b.clone(), view![relay_parent]).await; + } - connect_peer( - &mut overseer, - peer_a.clone(), - Some(vec![state.discovery_id(other_group_validators[0])].into_iter().collect()), - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; - connect_peer( - &mut overseer, - peer_b.clone(), - Some(vec![state.discovery_id(other_group_validators[1])].into_iter().collect()), + let seconded_disabled = state + .sign_statement( + index_disabled, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + let seconded_b = state + .sign_statement( + index_b, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + { + send_peer_message( + &mut overseer, + peer_b.clone(), + protocol_v2::StatementDistributionMessage::Statement( + relay_parent, + seconded_b.clone(), + ), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_b && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + } + + // Send a request to peer and activate leaf when a validator is disabled; + // mock the response with a statement from disabled validator. + { + let statements = vec![seconded_disabled]; + let mask = StatementFilter::blank(group_size); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendRequests(mut requests, IfDisconnected::ImmediateError)) => { + assert_eq!(requests.len(), 1); + assert_matches!( + requests.pop().unwrap(), + Requests::AttestedCandidateV2(outgoing) => { + assert_eq!(outgoing.peer, Recipient::Peer(peer_b)); + assert_eq!(outgoing.payload.candidate_hash, candidate_hash); + assert_eq!(outgoing.payload.mask, mask); + + activate_leaf(&mut overseer, &test_leaf_disabled, &state, false, vec![]).await; + + let res = AttestedCandidateResponse { + candidate_receipt: candidate, + persisted_validation_data: pvd, + statements, + }; + outgoing.pending_response.send(Ok(res.encode())).unwrap(); + } + ); + } + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_b && r == BENEFIT_VALID_RESPONSE.into() => { } + ); + + assert_matches!( + overseer.recv().await, + AllMessages:: NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::V2( + protocol_v2::ValidationProtocol::StatementDistribution( + protocol_v2::StatementDistributionMessage::Statement(hash, statement), + ), + ), + ) + ) => { + assert_eq!(peers, vec![peer_disabled_later]); + assert_eq!(hash, relay_parent); + assert_eq!(statement, seconded_b); + } + ); + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; + } + + overseer + }); +} + +#[test] +fn no_response_for_grid_request_not_meeting_quorum() { + let validator_count = 6; + let group_size = 3; + let config = TestConfig { + validator_count, + group_size, + local_validator: LocalRole::Validator, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + + test_harness(config, |mut state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_group_index = local_validator.group_index.unwrap(); + let local_para = ParaId::from(local_group_index.0); + + let test_leaf = state.make_dummy_leaf_with_min_backing_votes(relay_parent, 2); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + let other_group_validators = state.group_validators(local_group_index, true); + let target_group_validators = + state.group_validators((local_group_index.0 + 1).into(), true); + let v_a = other_group_validators[0]; + let v_b = other_group_validators[1]; + let v_c = target_group_validators[0]; + + // peer A is in group, has relay parent in view. + // peer B is in group, has no relay parent in view. + // peer C is not in group, has relay parent in view. + { + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(v_a)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_b.clone(), + Some(vec![state.discovery_id(v_b)].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_c.clone(), + Some(vec![state.discovery_id(v_c)].into_iter().collect()), + ) + .await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; + + // Send gossip topology. + send_new_topology(&mut overseer, state.make_dummy_topology()).await; + + // Confirm the candidate locally so that we don't send out requests. + { + let statement = state + .sign_full_statement( + local_validator.validator_index, + Statement::Seconded(candidate.clone()), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + pvd.clone(), + ) + .clone(); + + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Share(relay_parent, statement), + }) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a] + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; + } + + // Send enough statements to make candidate backable, make sure announcements are sent. + + // Send statement from peer A. + { + let statement = state + .sign_statement( + v_a, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + send_peer_message( + &mut overseer, + peer_a.clone(), + protocol_v2::StatementDistributionMessage::Statement(relay_parent, statement), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_a && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + } + + // Send statement from peer B. + let statement_b = state + .sign_statement( + v_b, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); + { + send_peer_message( + &mut overseer, + peer_b.clone(), + protocol_v2::StatementDistributionMessage::Statement( + relay_parent, + statement_b.clone(), + ), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_b && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a] + ); + } + + // Send Backed notification. + { + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Backed(candidate_hash), + }) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages:: NetworkBridgeTx( + NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::V2( + protocol_v2::ValidationProtocol::StatementDistribution( + protocol_v2::StatementDistributionMessage::BackedCandidateManifest(manifest), + ), + ), + ) + ) => { + assert_eq!(peers, vec![peer_c]); + assert_eq!(manifest, BackedCandidateManifest { + relay_parent, + candidate_hash, + group_index: local_validator.group_index.unwrap(), + para_id: local_para, + parent_head_data_hash: pvd.parent_head.hash(), + statement_knowledge: StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 1, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }, + }); + } + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; + } + + let mask = StatementFilter { + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 1], + validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], + }; + + let relay_2 = Hash::repeat_byte(2); + let disabled_validators = vec![v_a]; + let leaf_2 = state.make_dummy_leaf_with_disabled_validators(relay_2, disabled_validators); + activate_leaf(&mut overseer, &leaf_2, &state, false, vec![]).await; + + // Incoming request to local node. Local node should not send the response as v_a is + // disabled and hence the quorum is not reached. + { + let response = state + .send_request( + peer_c, + request_v2::AttestedCandidateRequest { candidate_hash: candidate.hash(), mask }, + ) + .await + .await; + + assert!( + response.is_none(), + "We should not send a response as the quorum is not reached yet" + ); + } + + overseer + }); +} + +#[test] +fn disabling_works_from_the_latest_state_not_relay_parent() { + let group_size = 3; + let config = TestConfig { + validator_count: 20, + group_size, + local_validator: LocalRole::Validator, + async_backing_params: None, + }; + + let relay_1 = Hash::repeat_byte(1); + let relay_2 = Hash::repeat_byte(2); + let peer_disabled = PeerId::random(); + + test_harness(config, |state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_group_index = local_validator.group_index.unwrap(); + let local_para = ParaId::from(local_group_index.0); + + let other_group_validators = state.group_validators(local_group_index, true); + let index_disabled = other_group_validators[0]; + + let leaf_1 = state.make_dummy_leaf(relay_1); + let disabled_validators = vec![index_disabled]; + let leaf_2 = state.make_dummy_leaf_with_disabled_validators(relay_2, disabled_validators); + + let (candidate_1, pvd_1) = make_candidate( + relay_1, + 1, + local_para, + leaf_1.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_1_hash = candidate_1.hash(); + + let (candidate_2, _) = make_candidate( + relay_1, + 1, + local_para, + leaf_1.para_data(local_para).head_data.clone(), + vec![4, 5, 6, 7].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_2_hash = candidate_2.hash(); + + { + connect_peer( + &mut overseer, + peer_disabled.clone(), + Some(vec![state.discovery_id(index_disabled)].into_iter().collect()), + ) + .await; + send_peer_view_change(&mut overseer, peer_disabled.clone(), view![relay_1]).await; + } + + activate_leaf(&mut overseer, &leaf_1, &state, true, vec![]).await; + + let seconded_1 = state + .sign_statement( + index_disabled, + CompactStatement::Seconded(candidate_1_hash), + &SigningContext { parent_hash: relay_1, session_index: 1 }, + ) + .as_unchecked() + .clone(); + + let seconded_2 = state + .sign_statement( + index_disabled, + CompactStatement::Seconded(candidate_2_hash), + &SigningContext { parent_hash: relay_1, session_index: 1 }, + ) + .as_unchecked() + .clone(); + { + send_peer_message( + &mut overseer, + peer_disabled.clone(), + protocol_v2::StatementDistributionMessage::Statement(relay_1, seconded_1.clone()), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_disabled && r == BENEFIT_VALID_STATEMENT_FIRST.into() => { } + ); + } + + { + handle_sent_request( + &mut overseer, + peer_disabled, + candidate_1_hash, + StatementFilter::blank(group_size), + candidate_1.clone(), + pvd_1.clone(), + vec![seconded_1.clone()], + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_disabled && r == BENEFIT_VALID_STATEMENT.into() => { } + ); + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_disabled && r == BENEFIT_VALID_RESPONSE.into() => { } + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; + } + + activate_leaf(&mut overseer, &leaf_2, &state, false, vec![]).await; + + { + send_peer_message( + &mut overseer, + peer_disabled.clone(), + protocol_v2::StatementDistributionMessage::Statement(relay_1, seconded_2.clone()), + ) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::ReportPeer(ReportPeerMessage::Single(p, r))) + if p == peer_disabled && r == COST_DISABLED_VALIDATOR.into() => { } + ); + } + + overseer + }); +} + +#[test] +fn local_node_sanity_checks_incoming_requests() { + let config = TestConfig { + validator_count: 20, + group_size: 3, + local_validator: LocalRole::Validator, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + let peer_c = PeerId::random(); + let peer_d = PeerId::random(); + + test_harness(config, |mut state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_group_index = local_validator.group_index.unwrap(); + let local_para = ParaId::from(local_group_index.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + // peer A is in group, has relay parent in view. + // peer B is in group, has no relay parent in view. + // peer C is not in group, has relay parent in view. + { + let other_group_validators = state.group_validators(local_group_index, true); + + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(other_group_validators[0])].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_b.clone(), + Some(vec![state.discovery_id(other_group_validators[1])].into_iter().collect()), + ) + .await; + + connect_peer(&mut overseer, peer_c.clone(), None).await; + + send_peer_view_change(&mut overseer, peer_a.clone(), view![relay_parent]).await; + send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; + } + + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; + + let mask = StatementFilter::blank(state.config.group_size); + + // Should drop requests for unknown candidates. + { + let (pending_response, rx) = oneshot::channel(); + state + .req_sender + .send(RawIncomingRequest { + // Request from peer that received manifest. + peer: peer_c, + payload: request_v2::AttestedCandidateRequest { + candidate_hash: candidate.hash(), + mask: mask.clone(), + } + .encode(), + pending_response, + }) + .await + .unwrap(); + + assert_matches!(rx.await, Err(oneshot::Canceled)); + } + + // Confirm candidate. + { + let full_signed = state + .sign_statement( + local_validator.validator_index, + CompactStatement::Seconded(candidate_hash), + &SigningContext { session_index: 1, parent_hash: relay_parent }, + ) + .convert_to_superpayload(StatementWithPVD::Seconded(candidate.clone(), pvd.clone())) + .unwrap(); + + overseer + .send(FromOrchestra::Communication { + msg: StatementDistributionMessage::Share(relay_parent, full_signed), + }) + .await; + + assert_matches!( + overseer.recv().await, + AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage( + peers, + Versioned::V2(protocol_v2::ValidationProtocol::StatementDistribution( + protocol_v2::StatementDistributionMessage::Statement( + r, + s, + ) + )) + )) => { + assert_eq!(peers, vec![peer_a.clone()]); + assert_eq!(r, relay_parent); + assert_eq!(s.unchecked_payload(), &CompactStatement::Seconded(candidate_hash)); + assert_eq!(s.unchecked_validator_index(), local_validator.validator_index); + } + ); + + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; + } + + // Should drop requests from unknown peers. + { + let (pending_response, rx) = oneshot::channel(); + state + .req_sender + .send(RawIncomingRequest { + // Request from peer that received manifest. + peer: peer_d, + payload: request_v2::AttestedCandidateRequest { + candidate_hash: candidate.hash(), + mask: mask.clone(), + } + .encode(), + pending_response, + }) + .await + .unwrap(); + + assert_matches!(rx.await, Err(oneshot::Canceled)); + } + + // Should drop requests with bitfields of the wrong size. + { + let mask = StatementFilter::blank(state.config.group_size + 1); + let response = state + .send_request( + peer_c, + request_v2::AttestedCandidateRequest { candidate_hash: candidate.hash(), mask }, + ) + .await + .await + .unwrap(); + + assert_matches!( + response, + RawOutgoingResponse { + result, + reputation_changes, + sent_feedback + } => { + assert_matches!(result, Err(())); + assert_eq!(reputation_changes, vec![COST_INVALID_REQUEST_BITFIELD_SIZE.into()]); + assert_matches!(sent_feedback, None); + } + ); + } + + // Local node should reject requests if we did not send a manifest to that peer. + { + let response = state + .send_request( + peer_c, + request_v2::AttestedCandidateRequest { + candidate_hash: candidate.hash(), + mask: mask.clone(), + }, + ) + .await + .await + .unwrap(); + + // Should get `COST_UNEXPECTED_REQUEST` response. + assert_matches!( + response, + RawOutgoingResponse { + result, + reputation_changes, + sent_feedback + } => { + assert_matches!(result, Err(())); + assert_eq!(reputation_changes, vec![COST_UNEXPECTED_REQUEST.into()]); + assert_matches!(sent_feedback, None); + } + ); + } + + overseer + }); +} + +#[test] +fn local_node_checks_that_peer_can_request_before_responding() { + let config = TestConfig { + validator_count: 20, + group_size: 3, + local_validator: LocalRole::Validator, + async_backing_params: None, + }; + + let relay_parent = Hash::repeat_byte(1); + let peer_a = PeerId::random(); + let peer_b = PeerId::random(); + + test_harness(config, |mut state, mut overseer| async move { + let local_validator = state.local.clone().unwrap(); + let local_group_index = local_validator.group_index.unwrap(); + let local_para = ParaId::from(local_group_index.0); + + let test_leaf = state.make_dummy_leaf(relay_parent); + + let (candidate, pvd) = make_candidate( + relay_parent, + 1, + local_para, + test_leaf.para_data(local_para).head_data.clone(), + vec![4, 5, 6].into(), + Hash::repeat_byte(42).into(), + ); + let candidate_hash = candidate.hash(); + + // Peers A and B are in group and have relay parent in view. + let other_group_validators = state.group_validators(local_group_index, true); + + connect_peer( + &mut overseer, + peer_a.clone(), + Some(vec![state.discovery_id(other_group_validators[0])].into_iter().collect()), + ) + .await; + + connect_peer( + &mut overseer, + peer_b.clone(), + Some(vec![state.discovery_id(other_group_validators[1])].into_iter().collect()), ) .await; let peer_b_index = other_group_validators[1]; @@ -1362,15 +1996,7 @@ fn local_node_checks_that_peer_can_request_before_responding() { send_peer_view_change(&mut overseer, peer_b.clone(), view![relay_parent]).await; // Finish setup - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; let mask = StatementFilter::blank(state.config.group_size); @@ -1409,7 +2035,7 @@ fn local_node_checks_that_peer_can_request_before_responding() { } ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; // Local node should respond to requests from peers in the same group // which appear to not have already seen the candidate @@ -1424,7 +2050,8 @@ fn local_node_checks_that_peer_can_request_before_responding() { }, ) .await - .await; + .await + .unwrap(); let expected_statements = vec![signed.into_unchecked()]; assert_matches!(response, full_response => { @@ -1473,7 +2100,8 @@ fn local_node_checks_that_peer_can_request_before_responding() { }, ) .await - .await; + .await + .unwrap(); // Peer already knows about this candidate. Should reject. assert_matches!( @@ -1535,7 +2163,7 @@ fn local_node_respects_statement_mask() { let local_group_index = local_validator.group_index.unwrap(); let local_para = ParaId::from(local_group_index.0); - let test_leaf = state.make_dummy_leaf(relay_parent); + let test_leaf = state.make_dummy_leaf_with_min_backing_votes(relay_parent, 2); let (candidate, pvd) = make_candidate( relay_parent, @@ -1592,15 +2220,7 @@ fn local_node_respects_statement_mask() { send_peer_view_change(&mut overseer, peer_c.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; // Send gossip topology. send_new_topology(&mut overseer, state.make_dummy_topology()).await; @@ -1627,26 +2247,28 @@ fn local_node_respects_statement_mask() { AllMessages::NetworkBridgeTx(NetworkBridgeTxMessage::SendValidationMessage(peers, _)) if peers == vec![peer_a] ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } // Send enough statements to make candidate backable, make sure announcements are sent. // Send statement from peer A. + let statement_a = state + .sign_statement( + v_a, + CompactStatement::Seconded(candidate_hash), + &SigningContext { parent_hash: relay_parent, session_index: 1 }, + ) + .as_unchecked() + .clone(); { - let statement = state - .sign_statement( - v_a, - CompactStatement::Seconded(candidate_hash), - &SigningContext { parent_hash: relay_parent, session_index: 1 }, - ) - .as_unchecked() - .clone(); - send_peer_message( &mut overseer, peer_a.clone(), - protocol_v2::StatementDistributionMessage::Statement(relay_parent, statement), + protocol_v2::StatementDistributionMessage::Statement( + relay_parent, + statement_a.clone(), + ), ) .await; @@ -1724,12 +2346,12 @@ fn local_node_respects_statement_mask() { } ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } // `1` indicates statements NOT to request. let mask = StatementFilter { - seconded_in_group: bitvec::bitvec![u8, Lsb0; 1, 0, 1], + seconded_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 1], validated_in_group: bitvec::bitvec![u8, Lsb0; 0, 0, 0], }; @@ -1741,9 +2363,10 @@ fn local_node_respects_statement_mask() { request_v2::AttestedCandidateRequest { candidate_hash: candidate.hash(), mask }, ) .await - .await; + .await + .unwrap(); - let expected_statements = vec![statement_b]; + let expected_statements = vec![statement_a, statement_b]; assert_matches!(response, full_response => { // Response is the same for v2. let request_v2::AttestedCandidateResponse { candidate_receipt, persisted_validation_data, statements } = @@ -1837,15 +2460,7 @@ fn should_delay_before_retrying_dropped_requests() { send_peer_view_change(&mut overseer, peer_e.clone(), view![relay_parent]).await; } - activate_leaf(&mut overseer, &test_leaf, &state, true).await; - - answer_expected_hypothetical_depth_request( - &mut overseer, - vec![], - Some(relay_parent), - false, - ) - .await; + activate_leaf(&mut overseer, &test_leaf, &state, true, vec![]).await; // Send gossip topology. send_new_topology(&mut overseer, state.make_dummy_topology()).await; @@ -1984,7 +2599,7 @@ fn should_delay_before_retrying_dropped_requests() { if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } // Sleep for the given amount of time. This should reset the delay for the first candidate. @@ -2051,7 +2666,7 @@ fn should_delay_before_retrying_dropped_requests() { if p == peer_c && r == BENEFIT_VALID_RESPONSE.into() ); - answer_expected_hypothetical_depth_request(&mut overseer, vec![], None, false).await; + answer_expected_hypothetical_depth_request(&mut overseer, vec![]).await; } overseer diff --git a/polkadot/roadmap/implementers-guide/src/node/backing/statement-distribution.md b/polkadot/roadmap/implementers-guide/src/node/backing/statement-distribution.md index 86a1bf12141..e6e597c5317 100644 --- a/polkadot/roadmap/implementers-guide/src/node/backing/statement-distribution.md +++ b/polkadot/roadmap/implementers-guide/src/node/backing/statement-distribution.md @@ -123,6 +123,31 @@ only send "importable" statements to the backing subsystem itself. backable and part of the hypothetical frontier. - Note that requesting is not an implicit acknowledgement, and an explicit acknowledgement must be sent upon receipt. +### Disabled validators + +After a validator is disabled in the runtime, other validators should no longer +accept statements from it. Filtering out of statements from disabled validators +on the node side is purely an optimization, as it will be done in the runtime +as well. + +Because we use the state of the active leaves to +check whether a validator is disabled instead of the relay parent, the notion +of being disabled is inherently racy: +- the responder has learned about the disabled validator before the requester +- the receiver has witnessed the disabled validator after sending the request + +We could have sent a manifest to a peer, then received information about +disabling, and then receive a request. This can break an invariant of the grid +mode: +- the response is required to indicate quorum + +Due to the above, there should be no response at all for grid requests when +the backing threshold is no longer met as a result of disabled validators. +In addition to that, we add disabled validators to the request's unwanted +mask. This ensures that the sender will not send statements from disabled +validators (at least from the perspective of the receiver at the moment of the +request). This doesn't fully avoid race conditions, but tries to minimize them. + ## Messages ### Incoming diff --git a/polkadot/zombienet_tests/functional/0010-validator-disabling.toml b/polkadot/zombienet_tests/functional/0010-validator-disabling.toml new file mode 100644 index 00000000000..6701d60d74d --- /dev/null +++ b/polkadot/zombienet_tests/functional/0010-validator-disabling.toml @@ -0,0 +1,39 @@ +[settings] +timeout = 1000 +bootnode = true + +[relaychain.genesis.runtimeGenesis.patch.configuration.config] + max_validators_per_core = 1 + needed_approvals = 2 + group_rotation_frequency = 10 + +[relaychain] +default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" +chain = "westend-local" # for the disabling to take an effect +default_command = "polkadot" + +[relaychain.default_resources] +limits = { memory = "4G", cpu = "2" } +requests = { memory = "2G", cpu = "1" } + + [[relaychain.node_groups]] + name = "honest-validator" + count = 3 + args = ["-lparachain=debug"] + + [[relaychain.node_groups]] + image = "{{MALUS_IMAGE}}" + name = "malus-validator" + command = "malus suggest-garbage-candidate" + args = ["-lMALUS=trace"] + count = 1 + +[[parachains]] +id = 1000 +cumulus_based = true + + [parachains.collator] + name = "alice" + command = "polkadot-parachain" + image = "{{CUMULUS_IMAGE}}" + args = ["-lparachain=debug"] diff --git a/polkadot/zombienet_tests/functional/0010-validator-disabling.zndsl b/polkadot/zombienet_tests/functional/0010-validator-disabling.zndsl new file mode 100644 index 00000000000..c8102661020 --- /dev/null +++ b/polkadot/zombienet_tests/functional/0010-validator-disabling.zndsl @@ -0,0 +1,21 @@ +Description: Test validator disabling effects +Network: ./0010-validator-disabling.toml +Creds: config + +# Ensure nodes are up and running +honest-validator: reports node_roles is 4 + +# Ensure parachain is registered +honest-validator: parachain 1000 is registered within 100 seconds + +# Ensure parachain made progress +honest-validator: parachain 1000 block height is at least 1 within 300 seconds + +# Wait for the dispute +honest-validator-1: reports parachain_candidate_disputes_total is at least 1 within 600 seconds + +# Disputes should conclude +honest-validator: reports polkadot_parachain_candidate_dispute_concluded{validity="invalid"} is at least 1 within 200 seconds + +# Wait for a few blocks for the disabling to take place. +honest-validator: log line contains "Disabled validators detected" within 180 seconds diff --git a/prdoc/pr_1841.prdoc b/prdoc/pr_1841.prdoc new file mode 100644 index 00000000000..c99583e6dc3 --- /dev/null +++ b/prdoc/pr_1841.prdoc @@ -0,0 +1,18 @@ +title: Validator disabling in Statement Distribution. + +doc: + - audience: Node Operator + description: | + Once a validator has been disabled for misbehavior, other validators + should no longer gossip its backing statements in the current era. + If they do, it might result in disconnects from the network due to low + reputation. + +migrations: + db: [] + runtime: [] + +crates: + - name: polkadot-statement-distribution + +host_functions: [] -- GitLab From d1f678c0ec44e9734cf242247dab90c2678774a9 Mon Sep 17 00:00:00 2001 From: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Date: Wed, 10 Jan 2024 11:30:00 +0100 Subject: [PATCH 025/392] Unique Usernames in Identity Pallet (#2651) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR allows _username authorities_ to issue unique usernames that correspond with an account. It also provides two-way lookup, that is from `AccountId` to a single, "primary" `Username` (alongside `Registration`) and multiple unique `Username`s to an `AccountId`. Key features: - Username Authorities added (and removed) via privileged origin. - Authorities have a `suffix` and an `allocation`. They can grant up to `allocation` usernames. Their `suffix` will be appended to the usernames that they issue. A suffix may be up to 7 characters long. - Users can ask an authority to grant them a username. This will take the form `myusername.suffix`. The entire name (including suffix) must be less than or equal to 32 alphanumeric characters. - Users can approve a username for themselves in one of two ways (that is, authorities cannot grant them arbitrarily): - Pre-sign the entire username (including suffix) with a secret key that corresponds to their `AccountId` (for keyed accounts, obviously); or - Accept the username after it has been granted by an authority (it will be queued until accepted) (for non-keyed accounts like pure proxies or multisigs). - The system does not require any funds or deposits. Users without an identity will be given a default one (presumably all fields set to `None`). If they update this info, they will need to place the normal storage deposit. - If a user does not have any username, their first one will be set as `Primary`, and their `AccountId` will map to that one. If they get subsequent usernames, they can choose which one to be their primary via `set_primary_username`. - There are some state cleanup functions to remove expired usernames that have not been accepted and dangling usernames whose owners have called `clear_identity`. TODO: - [x] Add migration to runtimes - [x] Probably do off-chain migration into People Chain genesis - [x] Address a few TODO questions in code (please review) --------- Co-authored-by: Liam Aharon Co-authored-by: Gonçalo Pestana Co-authored-by: Oliver Tale-Yazdi Co-authored-by: Dónal Murray --- Cargo.lock | 2 + .../people/people-rococo/src/people.rs | 32 +- .../src/weights/pallet_identity.rs | 94 ++ .../people/people-westend/src/people.rs | 32 +- .../src/weights/pallet_identity.rs | 94 ++ .../runtime/common/src/integration_tests.rs | 10 +- polkadot/runtime/rococo/src/lib.rs | 12 + .../rococo/src/weights/pallet_identity.rs | 94 ++ polkadot/runtime/westend/src/lib.rs | 11 + .../westend/src/weights/pallet_identity.rs | 94 ++ prdoc/pr_2651.prdoc | 12 + substrate/bin/node/runtime/src/impls.rs | 2 +- substrate/bin/node/runtime/src/lib.rs | 10 + substrate/frame/alliance/src/mock.rs | 33 +- substrate/frame/identity/Cargo.toml | 4 + substrate/frame/identity/src/benchmarking.rs | 211 ++- substrate/frame/identity/src/legacy.rs | 17 +- substrate/frame/identity/src/lib.rs | 515 ++++++- substrate/frame/identity/src/migration.rs | 124 ++ substrate/frame/identity/src/tests.rs | 1359 +++++++++++++---- substrate/frame/identity/src/types.rs | 24 +- substrate/frame/identity/src/weights.rs | 195 +++ 22 files changed, 2653 insertions(+), 328 deletions(-) create mode 100644 prdoc/pr_2651.prdoc create mode 100644 substrate/frame/identity/src/migration.rs diff --git a/Cargo.lock b/Cargo.lock index c3e5e2ff41b..924aeb7848c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10047,11 +10047,13 @@ dependencies = [ "frame-benchmarking", "frame-support", "frame-system", + "log", "pallet-balances", "parity-scale-codec", "scale-info", "sp-core", "sp-io", + "sp-keystore", "sp-runtime", "sp-std 8.0.0", ] diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/people.rs b/cumulus/parachains/runtimes/people/people-rococo/src/people.rs index 9ff249318d9..88a89711019 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/people.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/people.rs @@ -22,9 +22,12 @@ use frame_support::{ RuntimeDebugNoBound, }; use pallet_identity::{Data, IdentityInformationProvider}; -use parachains_common::impls::ToParentTreasury; +use parachains_common::{impls::ToParentTreasury, DAYS}; use scale_info::TypeInfo; -use sp_runtime::{traits::AccountIdConversion, RuntimeDebug}; +use sp_runtime::{ + traits::{AccountIdConversion, Verify}, + RuntimeDebug, +}; use sp_std::prelude::*; parameter_types! { @@ -51,6 +54,12 @@ impl pallet_identity::Config for Runtime { type Slashed = ToParentTreasury; type ForceOrigin = EnsureRoot; type RegistrarOrigin = EnsureRoot; + type OffchainSignature = Signature; + type SigningPublicKey = ::Signer; + type UsernameAuthorityOrigin = EnsureRoot; + type PendingUsernameExpiration = ConstU32<{ 7 * DAYS }>; + type MaxSuffixLength = ConstU32<7>; + type MaxUsernameLength = ConstU32<32>; type WeightInfo = weights::pallet_identity::WeightInfo; } @@ -84,7 +93,6 @@ pub enum IdentityField { TypeInfo, )] #[codec(mel_bound())] -#[cfg_attr(test, derive(frame_support::DefaultNoBound))] pub struct IdentityInfo { /// A reasonable display name for the controller of the account. This should be whatever the /// account is typically known as and should not be confusable with other entities, given @@ -202,3 +210,21 @@ impl IdentityInfo { res } } + +/// A `Default` identity. This is given to users who get a username but have not set an identity. +impl Default for IdentityInfo { + fn default() -> Self { + IdentityInfo { + display: Data::None, + legal: Data::None, + web: Data::None, + matrix: Data::None, + email: Data::None, + pgp_fingerprint: None, + image: Data::None, + twitter: Data::None, + github: Data::None, + discord: Data::None, + } + } +} diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_identity.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_identity.rs index 65cac7875ba..1e8ba87e251 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_identity.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_identity.rs @@ -312,4 +312,98 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } + /// Storage: `Identity::UsernameAuthorities` (r:0 w:1) + /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + fn add_username_authority() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_873_000 picoseconds. + Weight::from_parts(13_873_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::UsernameAuthorities` (r:0 w:1) + /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + fn remove_username_authority() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 10_653_000 picoseconds. + Weight::from_parts(10_653_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::UsernameAuthorities` (r:1 w:1) + /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `Identity::AccountOfUsername` (r:1 w:1) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + fn set_username_for() -> Weight { + // Proof Size summary in bytes: + // Measured: `80` + // Estimated: `11037` + // Minimum execution time: 75_928_000 picoseconds. + Weight::from_parts(75_928_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Identity::PendingUsernames` (r:1 w:1) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::AccountOfUsername` (r:0 w:1) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + fn accept_username() -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `11037` + // Minimum execution time: 38_157_000 picoseconds. + Weight::from_parts(38_157_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Identity::PendingUsernames` (r:1 w:1) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) + fn remove_expired_approval() -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `3542` + // Minimum execution time: 46_821_000 picoseconds. + Weight::from_parts(46_821_000, 0) + .saturating_add(Weight::from_parts(0, 3542)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::AccountOfUsername` (r:1 w:0) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + fn set_primary_username() -> Weight { + // Proof Size summary in bytes: + // Measured: `247` + // Estimated: `11037` + // Minimum execution time: 22_515_000 picoseconds. + Weight::from_parts(22_515_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::AccountOfUsername` (r:1 w:1) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + fn remove_dangling_username() -> Weight { + // Proof Size summary in bytes: + // Measured: `126` + // Estimated: `11037` + // Minimum execution time: 15_997_000 picoseconds. + Weight::from_parts(15_997_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/cumulus/parachains/runtimes/people/people-westend/src/people.rs b/cumulus/parachains/runtimes/people/people-westend/src/people.rs index d279be65110..a5c0e66a3f8 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/people.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/people.rs @@ -22,9 +22,12 @@ use frame_support::{ RuntimeDebugNoBound, }; use pallet_identity::{Data, IdentityInformationProvider}; -use parachains_common::impls::ToParentTreasury; +use parachains_common::{impls::ToParentTreasury, DAYS}; use scale_info::TypeInfo; -use sp_runtime::{traits::AccountIdConversion, RuntimeDebug}; +use sp_runtime::{ + traits::{AccountIdConversion, Verify}, + RuntimeDebug, +}; use sp_std::prelude::*; parameter_types! { @@ -51,6 +54,12 @@ impl pallet_identity::Config for Runtime { type Slashed = ToParentTreasury; type ForceOrigin = EnsureRoot; type RegistrarOrigin = EnsureRoot; + type OffchainSignature = Signature; + type SigningPublicKey = ::Signer; + type UsernameAuthorityOrigin = EnsureRoot; + type PendingUsernameExpiration = ConstU32<{ 7 * DAYS }>; + type MaxSuffixLength = ConstU32<7>; + type MaxUsernameLength = ConstU32<32>; type WeightInfo = weights::pallet_identity::WeightInfo; } @@ -84,7 +93,6 @@ pub enum IdentityField { TypeInfo, )] #[codec(mel_bound())] -#[cfg_attr(test, derive(frame_support::DefaultNoBound))] pub struct IdentityInfo { /// A reasonable display name for the controller of the account. This should be whatever it is /// that it is typically known as and should not be confusable with other entities, given @@ -202,3 +210,21 @@ impl IdentityInfo { res } } + +/// A `Default` identity. This is given to users who get a username but have not set an identity. +impl Default for IdentityInfo { + fn default() -> Self { + IdentityInfo { + display: Data::None, + legal: Data::None, + web: Data::None, + matrix: Data::None, + email: Data::None, + pgp_fingerprint: None, + image: Data::None, + twitter: Data::None, + github: Data::None, + discord: Data::None, + } + } +} diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_identity.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_identity.rs index 65cac7875ba..1e8ba87e251 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_identity.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_identity.rs @@ -312,4 +312,98 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } + /// Storage: `Identity::UsernameAuthorities` (r:0 w:1) + /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + fn add_username_authority() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_873_000 picoseconds. + Weight::from_parts(13_873_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::UsernameAuthorities` (r:0 w:1) + /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + fn remove_username_authority() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 10_653_000 picoseconds. + Weight::from_parts(10_653_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::UsernameAuthorities` (r:1 w:1) + /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `Identity::AccountOfUsername` (r:1 w:1) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + fn set_username_for() -> Weight { + // Proof Size summary in bytes: + // Measured: `80` + // Estimated: `11037` + // Minimum execution time: 75_928_000 picoseconds. + Weight::from_parts(75_928_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Identity::PendingUsernames` (r:1 w:1) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::AccountOfUsername` (r:0 w:1) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + fn accept_username() -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `11037` + // Minimum execution time: 38_157_000 picoseconds. + Weight::from_parts(38_157_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Identity::PendingUsernames` (r:1 w:1) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) + fn remove_expired_approval() -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `3542` + // Minimum execution time: 46_821_000 picoseconds. + Weight::from_parts(46_821_000, 0) + .saturating_add(Weight::from_parts(0, 3542)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::AccountOfUsername` (r:1 w:0) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + fn set_primary_username() -> Weight { + // Proof Size summary in bytes: + // Measured: `247` + // Estimated: `11037` + // Minimum execution time: 22_515_000 picoseconds. + Weight::from_parts(22_515_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::AccountOfUsername` (r:1 w:1) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + fn remove_dangling_username() -> Weight { + // Proof Size summary in bytes: + // Measured: `126` + // Estimated: `11037` + // Minimum execution time: 15_997_000 picoseconds. + Weight::from_parts(15_997_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/polkadot/runtime/common/src/integration_tests.rs b/polkadot/runtime/common/src/integration_tests.rs index 4870432d22f..cfa8f4c3ad9 100644 --- a/polkadot/runtime/common/src/integration_tests.rs +++ b/polkadot/runtime/common/src/integration_tests.rs @@ -45,9 +45,9 @@ use sp_io::TestExternalities; use sp_keyring::Sr25519Keyring; use sp_keystore::{testing::MemoryKeystore, KeystoreExt}; use sp_runtime::{ - traits::{BlakeTwo256, IdentityLookup, One}, + traits::{BlakeTwo256, IdentityLookup, One, Verify}, transaction_validity::TransactionPriority, - AccountId32, BuildStorage, + AccountId32, BuildStorage, MultiSignature, }; use sp_std::sync::Arc; @@ -293,6 +293,12 @@ impl pallet_identity::Config for Test { type MaxRegistrars = ConstU32<20>; type RegistrarOrigin = EnsureRoot; type ForceOrigin = EnsureRoot; + type OffchainSignature = MultiSignature; + type SigningPublicKey = ::Signer; + type UsernameAuthorityOrigin = EnsureRoot; + type PendingUsernameExpiration = ConstU32<100>; + type MaxSuffixLength = ConstU32<7>; + type MaxUsernameLength = ConstU32<32>; type WeightInfo = (); } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 67caa347bc3..3fd3f2bc635 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -668,6 +668,12 @@ impl pallet_identity::Config for Runtime { type Slashed = Treasury; type ForceOrigin = EitherOf, GeneralAdmin>; type RegistrarOrigin = EitherOf, GeneralAdmin>; + type OffchainSignature = Signature; + type SigningPublicKey = ::Signer; + type UsernameAuthorityOrigin = EnsureRoot; + type PendingUsernameExpiration = ConstU32<{ 7 * DAYS }>; + type MaxSuffixLength = ConstU32<7>; + type MaxUsernameLength = ConstU32<32>; type WeightInfo = weights::pallet_identity::WeightInfo; } @@ -1620,6 +1626,9 @@ pub mod migrations { } } + // We don't have a limit in the Relay Chain. + const IDENTITY_MIGRATION_KEY_LIMIT: u64 = u64::MAX; + /// Unreleased migrations. Add new ones here: pub type Unreleased = ( pallet_society::migrations::MigrateToV2, @@ -1655,6 +1664,9 @@ pub mod migrations { // Remove `im-online` pallet on-chain storage frame_support::migrations::RemovePallet::DbWeight>, + + // Migrate Identity pallet for Usernames + pallet_identity::migration::versioned::V0ToV1, parachains_configuration::migration::v11::MigrateToV11, // This needs to come after the `parachains_configuration` above as we are reading the configuration. coretime::migration::MigrateToCoretime, diff --git a/polkadot/runtime/rococo/src/weights/pallet_identity.rs b/polkadot/runtime/rococo/src/weights/pallet_identity.rs index e8c25269ac3..b334e21ea03 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_identity.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_identity.rs @@ -334,4 +334,98 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } + /// Storage: `Identity::UsernameAuthorities` (r:0 w:1) + /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + fn add_username_authority() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_873_000 picoseconds. + Weight::from_parts(13_873_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::UsernameAuthorities` (r:0 w:1) + /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + fn remove_username_authority() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 10_653_000 picoseconds. + Weight::from_parts(10_653_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::UsernameAuthorities` (r:1 w:1) + /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `Identity::AccountOfUsername` (r:1 w:1) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + fn set_username_for() -> Weight { + // Proof Size summary in bytes: + // Measured: `80` + // Estimated: `11037` + // Minimum execution time: 75_928_000 picoseconds. + Weight::from_parts(75_928_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Identity::PendingUsernames` (r:1 w:1) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::AccountOfUsername` (r:0 w:1) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + fn accept_username() -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `11037` + // Minimum execution time: 38_157_000 picoseconds. + Weight::from_parts(38_157_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Identity::PendingUsernames` (r:1 w:1) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) + fn remove_expired_approval() -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `3542` + // Minimum execution time: 46_821_000 picoseconds. + Weight::from_parts(46_821_000, 0) + .saturating_add(Weight::from_parts(0, 3542)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::AccountOfUsername` (r:1 w:0) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + fn set_primary_username() -> Weight { + // Proof Size summary in bytes: + // Measured: `247` + // Estimated: `11037` + // Minimum execution time: 22_515_000 picoseconds. + Weight::from_parts(22_515_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::AccountOfUsername` (r:1 w:1) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + fn remove_dangling_username() -> Weight { + // Proof Size summary in bytes: + // Measured: `126` + // Estimated: `11037` + // Minimum execution time: 15_997_000 picoseconds. + Weight::from_parts(15_997_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index e0b9fd0fb53..e1416c4b754 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -878,6 +878,12 @@ impl pallet_identity::Config for Runtime { type MaxRegistrars = MaxRegistrars; type ForceOrigin = EitherOf, GeneralAdmin>; type RegistrarOrigin = EitherOf, GeneralAdmin>; + type OffchainSignature = Signature; + type SigningPublicKey = ::Signer; + type UsernameAuthorityOrigin = EnsureRoot; + type PendingUsernameExpiration = ConstU32<{ 7 * DAYS }>; + type MaxSuffixLength = ConstU32<7>; + type MaxUsernameLength = ConstU32<32>; type WeightInfo = weights::pallet_identity::WeightInfo; } @@ -1626,6 +1632,9 @@ pub mod migrations { } } + // We don't have a limit in the Relay Chain. + const IDENTITY_MIGRATION_KEY_LIMIT: u64 = u64::MAX; + /// Unreleased migrations. Add new ones here: pub type Unreleased = ( parachains_configuration::migration::v7::MigrateToV7, @@ -1644,6 +1653,8 @@ pub mod migrations { ImOnlinePalletName, ::DbWeight, >, + // Migrate Identity pallet for Usernames + pallet_identity::migration::versioned::V0ToV1, parachains_configuration::migration::v11::MigrateToV11, ); } diff --git a/polkadot/runtime/westend/src/weights/pallet_identity.rs b/polkadot/runtime/westend/src/weights/pallet_identity.rs index dea631b9316..dc7061615c9 100644 --- a/polkadot/runtime/westend/src/weights/pallet_identity.rs +++ b/polkadot/runtime/westend/src/weights/pallet_identity.rs @@ -338,4 +338,98 @@ impl pallet_identity::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } + /// Storage: `Identity::UsernameAuthorities` (r:0 w:1) + /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + fn add_username_authority() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_873_000 picoseconds. + Weight::from_parts(13_873_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::UsernameAuthorities` (r:0 w:1) + /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + fn remove_username_authority() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 10_653_000 picoseconds. + Weight::from_parts(10_653_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::UsernameAuthorities` (r:1 w:1) + /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `Identity::AccountOfUsername` (r:1 w:1) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + fn set_username_for() -> Weight { + // Proof Size summary in bytes: + // Measured: `80` + // Estimated: `11037` + // Minimum execution time: 75_928_000 picoseconds. + Weight::from_parts(75_928_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Identity::PendingUsernames` (r:1 w:1) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::AccountOfUsername` (r:0 w:1) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + fn accept_username() -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `11037` + // Minimum execution time: 38_157_000 picoseconds. + Weight::from_parts(38_157_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Identity::PendingUsernames` (r:1 w:1) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) + fn remove_expired_approval() -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `3542` + // Minimum execution time: 46_821_000 picoseconds. + Weight::from_parts(46_821_000, 0) + .saturating_add(Weight::from_parts(0, 3542)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::AccountOfUsername` (r:1 w:0) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + fn set_primary_username() -> Weight { + // Proof Size summary in bytes: + // Measured: `247` + // Estimated: `11037` + // Minimum execution time: 22_515_000 picoseconds. + Weight::from_parts(22_515_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::AccountOfUsername` (r:1 w:1) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + fn remove_dangling_username() -> Weight { + // Proof Size summary in bytes: + // Measured: `126` + // Estimated: `11037` + // Minimum execution time: 15_997_000 picoseconds. + Weight::from_parts(15_997_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/prdoc/pr_2651.prdoc b/prdoc/pr_2651.prdoc new file mode 100644 index 00000000000..e28013d4330 --- /dev/null +++ b/prdoc/pr_2651.prdoc @@ -0,0 +1,12 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Unique Usernames for Identity + +doc: + - audience: Runtime User + description: | + Adds the ability to add unique usernames for an account with reverse lookup (as in `AccountId` + to `Username` and `Username` to `AccountId`). + +crates: [ ] diff --git a/substrate/bin/node/runtime/src/impls.rs b/substrate/bin/node/runtime/src/impls.rs index 717fbeadada..7ff52a758b3 100644 --- a/substrate/bin/node/runtime/src/impls.rs +++ b/substrate/bin/node/runtime/src/impls.rs @@ -64,7 +64,7 @@ impl IdentityVerifier for AllianceIdentityVerifier { fn has_good_judgement(who: &AccountId) -> bool { use pallet_identity::Judgement; crate::Identity::identity(who) - .map(|registration| registration.judgements) + .map(|(registration, _)| registration.judgements) .map_or(false, |judgements| { judgements .iter() diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 6e7bfb4f4b4..ec1601929fc 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -1500,6 +1500,12 @@ impl pallet_identity::Config for Runtime { type Slashed = Treasury; type ForceOrigin = EnsureRootOrHalfCouncil; type RegistrarOrigin = EnsureRootOrHalfCouncil; + type OffchainSignature = Signature; + type SigningPublicKey = ::Signer; + type UsernameAuthorityOrigin = EnsureRoot; + type PendingUsernameExpiration = ConstU32<{ 7 * DAYS }>; + type MaxSuffixLength = ConstU32<7>; + type MaxUsernameLength = ConstU32<32>; type WeightInfo = pallet_identity::weights::SubstrateWeight; } @@ -2208,6 +2214,9 @@ pub type Executive = frame_executive::Executive< Migrations, >; +// We don't have a limit in the Relay Chain. +const IDENTITY_MIGRATION_KEY_LIMIT: u64 = u64::MAX; + // All migrations executed on runtime upgrade as a nested tuple of types implementing // `OnRuntimeUpgrade`. Note: These are examples and do not need to be run directly // after the genesis block. @@ -2215,6 +2224,7 @@ type Migrations = ( pallet_nomination_pools::migration::versioned::V6ToV7, pallet_alliance::migration::Migration, pallet_contracts::Migration, + pallet_identity::migration::versioned::V0ToV1, ); type EventRecord = frame_system::EventRecord< diff --git a/substrate/frame/alliance/src/mock.rs b/substrate/frame/alliance/src/mock.rs index 01e0e01fe7e..22aea9005ef 100644 --- a/substrate/frame/alliance/src/mock.rs +++ b/substrate/frame/alliance/src/mock.rs @@ -19,7 +19,10 @@ pub use sp_core::H256; use sp_runtime::traits::Hash; -pub use sp_runtime::{traits::BlakeTwo256, BuildStorage}; +pub use sp_runtime::{ + traits::{BlakeTwo256, IdentifyAccount, IdentityLookup, Lazy, Verify}, + BuildStorage, MultiSignature, +}; use sp_std::convert::{TryFrom, TryInto}; pub use frame_support::{ @@ -101,6 +104,7 @@ parameter_types! { pub const MaxSubAccounts: u32 = 2; pub const MaxAdditionalFields: u32 = 2; pub const MaxRegistrars: u32 = 20; + pub const PendingUsernameExpiration: u64 = 100; } ord_parameter_types! { pub const One: u64 = 1; @@ -124,9 +128,34 @@ impl pallet_identity::Config for Test { type Slashed = (); type RegistrarOrigin = EnsureOneOrRoot; type ForceOrigin = EnsureTwoOrRoot; + type OffchainSignature = AccountU64; + type SigningPublicKey = AccountU64; + type UsernameAuthorityOrigin = EnsureOneOrRoot; + type PendingUsernameExpiration = PendingUsernameExpiration; + type MaxSuffixLength = ConstU32<7>; + type MaxUsernameLength = ConstU32<32>; type WeightInfo = (); } +#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo)] +pub struct AccountU64(u64); +impl IdentifyAccount for AccountU64 { + type AccountId = u64; + fn into_account(self) -> u64 { + 0u64 + } +} +impl Verify for AccountU64 { + type Signer = AccountU64; + fn verify>( + &self, + _msg: L, + _signer: &::AccountId, + ) -> bool { + false + } +} + pub struct AllianceIdentityVerifier; impl IdentityVerifier for AllianceIdentityVerifier { fn has_required_identities(who: &AccountId) -> bool { @@ -135,7 +164,7 @@ impl IdentityVerifier for AllianceIdentityVerifier { fn has_good_judgement(who: &AccountId) -> bool { if let Some(judgements) = - Identity::identity(who).map(|registration| registration.judgements) + Identity::identity(who).map(|(registration, _)| registration.judgements) { judgements .iter() diff --git a/substrate/frame/identity/Cargo.toml b/substrate/frame/identity/Cargo.toml index 78f966c0535..1197a37ecae 100644 --- a/substrate/frame/identity/Cargo.toml +++ b/substrate/frame/identity/Cargo.toml @@ -18,6 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive", "max-encoded-len"] } enumflags2 = { version = "0.7.7" } +log = { version = "0.4.17", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } frame-benchmarking = { path = "../benchmarking", default-features = false, optional = true } frame-support = { path = "../support", default-features = false } @@ -29,6 +30,7 @@ sp-std = { path = "../../primitives/std", default-features = false } [dev-dependencies] pallet-balances = { path = "../balances" } sp-core = { path = "../../primitives/core" } +sp-keystore = { path = "../../primitives/keystore" } [features] default = ["std"] @@ -39,10 +41,12 @@ std = [ "frame-benchmarking?/std", "frame-support/std", "frame-system/std", + "log/std", "pallet-balances/std", "scale-info/std", "sp-core/std", "sp-io/std", + "sp-keystore/std", "sp-runtime/std", "sp-std/std", ] diff --git a/substrate/frame/identity/src/benchmarking.rs b/substrate/frame/identity/src/benchmarking.rs index 3d976bd6c88..fe2fb0b0489 100644 --- a/substrate/frame/identity/src/benchmarking.rs +++ b/substrate/frame/identity/src/benchmarking.rs @@ -22,22 +22,43 @@ use super::*; use crate::Pallet as Identity; +use codec::Encode; use frame_benchmarking::{ account, impl_benchmark_test_suite, v2::*, whitelisted_caller, BenchmarkError, }; use frame_support::{ - ensure, - traits::{EnsureOrigin, Get}, + assert_ok, ensure, + traits::{EnsureOrigin, Get, OnFinalize, OnInitialize}, }; use frame_system::RawOrigin; -use sp_runtime::traits::Bounded; +use sp_io::crypto::{sr25519_generate, sr25519_sign}; +use sp_runtime::{ + traits::{Bounded, IdentifyAccount, One}, + MultiSignature, MultiSigner, +}; const SEED: u32 = 0; +fn assert_has_event(generic_event: ::RuntimeEvent) { + frame_system::Pallet::::assert_has_event(generic_event.into()); +} + fn assert_last_event(generic_event: ::RuntimeEvent) { frame_system::Pallet::::assert_last_event(generic_event.into()); } +fn run_to_block(n: frame_system::pallet_prelude::BlockNumberFor) { + while frame_system::Pallet::::block_number() < n { + crate::Pallet::::on_finalize(frame_system::Pallet::::block_number()); + frame_system::Pallet::::on_finalize(frame_system::Pallet::::block_number()); + frame_system::Pallet::::set_block_number( + frame_system::Pallet::::block_number() + One::one(), + ); + frame_system::Pallet::::on_initialize(frame_system::Pallet::::block_number()); + crate::Pallet::::on_initialize(frame_system::Pallet::::block_number()); + } +} + // Adds `r` registrars to the Identity Pallet. These registrars will have set fees and fields. fn add_registrars(r: u32) -> Result<(), &'static str> { for i in 0..r { @@ -95,7 +116,28 @@ fn add_sub_accounts( Ok(subs) } -#[benchmarks] +fn bench_suffix() -> Vec { + b"bench".to_vec() +} + +fn bench_username() -> Vec { + // len = 24 + b"veryfastbenchmarkmachine".to_vec() +} + +fn bounded_username(username: Vec, suffix: Vec) -> Username { + let mut full_username = Vec::with_capacity(username.len() + suffix.len() + 1); + full_username.extend(username); + full_username.extend(b"."); + full_username.extend(suffix); + Username::::try_from(full_username).expect("test usernames should fit within bounds") +} + +#[benchmarks( + where + ::AccountId: From, + T::OffchainSignature: From, +)] mod benchmarks { use super::*; @@ -523,5 +565,166 @@ mod benchmarks { Ok(()) } + #[benchmark] + fn add_username_authority() -> Result<(), BenchmarkError> { + let origin = + T::UsernameAuthorityOrigin::try_successful_origin().expect("can generate origin"); + + let authority: T::AccountId = account("authority", 0, SEED); + let authority_lookup = T::Lookup::unlookup(authority.clone()); + let suffix = bench_suffix(); + let allocation = 10; + + #[extrinsic_call] + _(origin as T::RuntimeOrigin, authority_lookup, suffix, allocation); + + assert_last_event::(Event::::AuthorityAdded { authority }.into()); + Ok(()) + } + + #[benchmark] + fn remove_username_authority() -> Result<(), BenchmarkError> { + let origin = + T::UsernameAuthorityOrigin::try_successful_origin().expect("can generate origin"); + + let authority: T::AccountId = account("authority", 0, SEED); + let authority_lookup = T::Lookup::unlookup(authority.clone()); + let suffix = bench_suffix(); + let allocation = 10; + + assert_ok!(Identity::::add_username_authority( + origin.clone(), + authority_lookup.clone(), + suffix, + allocation + )); + + #[extrinsic_call] + _(origin as T::RuntimeOrigin, authority_lookup); + + assert_last_event::(Event::::AuthorityRemoved { authority }.into()); + Ok(()) + } + + #[benchmark] + fn set_username_for() -> Result<(), BenchmarkError> { + // Set up a username authority. + let auth_origin = + T::UsernameAuthorityOrigin::try_successful_origin().expect("can generate origin"); + let authority: T::AccountId = account("authority", 0, SEED); + let authority_lookup = T::Lookup::unlookup(authority.clone()); + let suffix = bench_suffix(); + let allocation = 10; + + Identity::::add_username_authority( + auth_origin, + authority_lookup, + suffix.clone(), + allocation, + )?; + + let username = bench_username(); + let bounded_username = bounded_username::(username.clone(), suffix.clone()); + let encoded_username = Encode::encode(&bounded_username.to_vec()); + + let public = sr25519_generate(0.into(), None); + let who_account: T::AccountId = MultiSigner::Sr25519(public).into_account().into(); + let who_lookup = T::Lookup::unlookup(who_account.clone()); + + let signature = + MultiSignature::Sr25519(sr25519_sign(0.into(), &public, &encoded_username).unwrap()); + + // Verify signature here to avoid surprise errors at runtime + assert!(signature.verify(&encoded_username[..], &public.into())); + + #[extrinsic_call] + _(RawOrigin::Signed(authority.clone()), who_lookup, username, Some(signature.into())); + + assert_has_event::( + Event::::UsernameSet { + who: who_account.clone(), + username: bounded_username.clone(), + } + .into(), + ); + assert_has_event::( + Event::::PrimaryUsernameSet { who: who_account, username: bounded_username }.into(), + ); + Ok(()) + } + + #[benchmark] + fn accept_username() -> Result<(), BenchmarkError> { + let caller: T::AccountId = whitelisted_caller(); + let username = bounded_username::(bench_username(), bench_suffix()); + + Identity::::queue_acceptance(&caller, username.clone()); + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), username.clone()); + + assert_last_event::(Event::::UsernameSet { who: caller, username }.into()); + Ok(()) + } + + #[benchmark] + fn remove_expired_approval() -> Result<(), BenchmarkError> { + let caller: T::AccountId = whitelisted_caller(); + let username = bounded_username::(bench_username(), bench_suffix()); + Identity::::queue_acceptance(&caller, username.clone()); + + let expected_exiration = + frame_system::Pallet::::block_number() + T::PendingUsernameExpiration::get(); + + run_to_block::(expected_exiration + One::one()); + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), username); + + assert_last_event::(Event::::PreapprovalExpired { whose: caller }.into()); + Ok(()) + } + + #[benchmark] + fn set_primary_username() -> Result<(), BenchmarkError> { + let caller: T::AccountId = whitelisted_caller(); + let first_username = bounded_username::(bench_username(), bench_suffix()); + let second_username = bounded_username::(b"slowbenchmark".to_vec(), bench_suffix()); + + // First one will be set as primary. Second will not be. + Identity::::insert_username(&caller, first_username); + Identity::::insert_username(&caller, second_username.clone()); + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), second_username.clone()); + + assert_last_event::( + Event::::PrimaryUsernameSet { who: caller, username: second_username }.into(), + ); + Ok(()) + } + + #[benchmark] + fn remove_dangling_username() -> Result<(), BenchmarkError> { + let caller: T::AccountId = whitelisted_caller(); + let first_username = bounded_username::(bench_username(), bench_suffix()); + let second_username = bounded_username::(b"slowbenchmark".to_vec(), bench_suffix()); + + // First one will be set as primary. Second will not be. + Identity::::insert_username(&caller, first_username); + Identity::::insert_username(&caller, second_username.clone()); + + // User calls `clear_identity`, leaving their second username as "dangling" + Identity::::clear_identity(RawOrigin::Signed(caller.clone()).into())?; + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), second_username.clone()); + + assert_last_event::( + Event::::DanglingUsernameRemoved { who: caller, username: second_username }.into(), + ); + Ok(()) + } + impl_benchmark_test_suite!(Identity, crate::tests::new_test_ext(), crate::tests::Test); } diff --git a/substrate/frame/identity/src/legacy.rs b/substrate/frame/identity/src/legacy.rs index a7953f7e178..60e812c2238 100644 --- a/substrate/frame/identity/src/legacy.rs +++ b/substrate/frame/identity/src/legacy.rs @@ -75,7 +75,6 @@ impl TypeInfo for IdentityField { TypeInfo, )] #[codec(mel_bound())] -#[cfg_attr(test, derive(frame_support::DefaultNoBound))] #[scale_info(skip_type_params(FieldLimit))] pub struct IdentityInfo> { /// Additional fields of the identity that are not catered for with the struct's explicit @@ -155,6 +154,22 @@ impl + 'static> IdentityInformationProvider for IdentityInf } } +impl> Default for IdentityInfo { + fn default() -> Self { + IdentityInfo { + additional: BoundedVec::default(), + display: Data::None, + legal: Data::None, + web: Data::None, + riot: Data::None, + email: Data::None, + pgp_fingerprint: None, + image: Data::None, + twitter: Data::None, + } + } +} + impl> IdentityInfo { pub(crate) fn fields(&self) -> BitFlags { let mut res = >::empty(); diff --git a/substrate/frame/identity/src/lib.rs b/substrate/frame/identity/src/lib.rs index 8588612cd5b..1df0a619ea4 100644 --- a/substrate/frame/identity/src/lib.rs +++ b/substrate/frame/identity/src/lib.rs @@ -40,32 +40,53 @@ //! The number of registrars should be limited, and the deposit made sufficiently large, to ensure //! no state-bloat attack is viable. //! +//! ### Usernames +//! +//! The pallet provides functionality for username authorities to issue usernames. When an account +//! receives a username, they get a default instance of `IdentityInfo`. Usernames also serve as a +//! reverse lookup from username to account. +//! +//! Username authorities are given an allocation by governance to prevent state bloat. Usernames +//! impose no cost or deposit on the user. +//! +//! Users can have multiple usernames that map to the same `AccountId`, however one `AccountId` can +//! only map to a single username, known as the _primary_. +//! //! ## Interface //! //! ### Dispatchable Functions //! -//! #### For general users +//! #### For General Users //! * `set_identity` - Set the associated identity of an account; a small deposit is reserved if not //! already taken. //! * `clear_identity` - Remove an account's associated identity; the deposit is returned. //! * `request_judgement` - Request a judgement from a registrar, paying a fee. //! * `cancel_request` - Cancel the previous request for a judgement. +//! * `accept_username` - Accept a username issued by a username authority. +//! * `remove_expired_approval` - Remove a username that was issued but never accepted. +//! * `set_primary_username` - Set a given username as an account's primary. +//! * `remove_dangling_username` - Remove a username that maps to an account without an identity. //! -//! #### For general users with sub-identities +//! #### For General Users with Sub-Identities //! * `set_subs` - Set the sub-accounts of an identity. //! * `add_sub` - Add a sub-identity to an identity. //! * `remove_sub` - Remove a sub-identity of an identity. //! * `rename_sub` - Rename a sub-identity of an identity. //! * `quit_sub` - Remove a sub-identity of an identity (called by the sub-identity). //! -//! #### For registrars +//! #### For Registrars //! * `set_fee` - Set the fee required to be paid for a judgement to be given by the registrar. //! * `set_fields` - Set the fields that a registrar cares about in their judgements. //! * `provide_judgement` - Provide a judgement to an identity. //! -//! #### For super-users +//! #### For Username Authorities +//! * `set_username_for` - Set a username for a given account. The account must approve it. +//! +//! #### For Superusers //! * `add_registrar` - Add a new registrar to the system. //! * `kill_identity` - Forcibly remove the associated identity; the deposit is lost. +//! * `add_username_authority` - Add an account with the ability to issue usernames. +//! * `remove_username_authority` - Remove an account with the ability to issue usernames. //! //! [`Call`]: ./enum.Call.html //! [`Config`]: ./trait.Config.html @@ -74,25 +95,29 @@ mod benchmarking; pub mod legacy; +pub mod migration; #[cfg(test)] mod tests; mod types; pub mod weights; +use crate::types::{AuthorityPropertiesOf, Suffix, Username}; use codec::Encode; use frame_support::{ ensure, pallet_prelude::{DispatchError, DispatchResult}, - traits::{BalanceStatus, Currency, Get, OnUnbalanced, ReservableCurrency}, + traits::{BalanceStatus, Currency, Get, OnUnbalanced, ReservableCurrency, StorageVersion}, + BoundedVec, }; -use sp_runtime::traits::{AppendZerosInput, Hash, Saturating, StaticLookup, Zero}; -use sp_std::prelude::*; -pub use weights::WeightInfo; - pub use pallet::*; +use sp_runtime::traits::{ + AppendZerosInput, Hash, IdentifyAccount, Saturating, StaticLookup, Verify, Zero, +}; +use sp_std::prelude::*; pub use types::{ Data, IdentityInformationProvider, Judgement, RegistrarIndex, RegistrarInfo, Registration, }; +pub use weights::WeightInfo; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; @@ -115,7 +140,7 @@ pub mod pallet { /// The currency trait. type Currency: ReservableCurrency; - /// The amount held on deposit for a registered identity + /// The amount held on deposit for a registered identity. #[pallet::constant] type BasicDeposit: Get>; @@ -150,14 +175,41 @@ pub mod pallet { /// The origin which may add or remove registrars. Root can always do this. type RegistrarOrigin: EnsureOrigin; + /// Signature type for pre-authorizing usernames off-chain. + /// + /// Can verify whether an `Self::SigningPublicKey` created a signature. + type OffchainSignature: Verify + Parameter; + + /// Public key that corresponds to an on-chain `Self::AccountId`. + type SigningPublicKey: IdentifyAccount; + + /// The origin which may add or remove username authorities. Root can always do this. + type UsernameAuthorityOrigin: EnsureOrigin; + + /// The number of blocks within which a username grant must be accepted. + #[pallet::constant] + type PendingUsernameExpiration: Get>; + + /// The maximum length of a suffix. + #[pallet::constant] + type MaxSuffixLength: Get; + + /// The maximum length of a username, including its suffix and any system-added delimiters. + #[pallet::constant] + type MaxUsernameLength: Get; + /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; } + const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); + #[pallet::pallet] + #[pallet::storage_version(STORAGE_VERSION)] pub struct Pallet(_); - /// Information that is pertinent to identify the entity behind an account. + /// Information that is pertinent to identify the entity behind an account. First item is the + /// registration, second is the account's primary username. /// /// TWOX-NOTE: OK ― `AccountId` is a secure hash. #[pallet::storage] @@ -166,7 +218,7 @@ pub mod pallet { _, Twox64Concat, T::AccountId, - Registration, T::MaxRegistrars, T::IdentityInformation>, + (Registration, T::MaxRegistrars, T::IdentityInformation>, Option>), OptionQuery, >; @@ -213,6 +265,38 @@ pub mod pallet { ValueQuery, >; + /// A map of the accounts who are authorized to grant usernames. + #[pallet::storage] + #[pallet::getter(fn authority)] + pub(super) type UsernameAuthorities = + StorageMap<_, Twox64Concat, T::AccountId, AuthorityPropertiesOf, OptionQuery>; + + /// Reverse lookup from `username` to the `AccountId` that has registered it. The value should + /// be a key in the `IdentityOf` map, but it may not if the user has cleared their identity. + /// + /// Multiple usernames may map to the same `AccountId`, but `IdentityOf` will only map to one + /// primary username. + #[pallet::storage] + #[pallet::getter(fn username)] + pub(super) type AccountOfUsername = + StorageMap<_, Blake2_128Concat, Username, T::AccountId, OptionQuery>; + + /// Usernames that an authority has granted, but that the account controller has not confirmed + /// that they want it. Used primarily in cases where the `AccountId` cannot provide a signature + /// because they are a pure proxy, multisig, etc. In order to confirm it, they should call + /// [`Call::accept_username`]. + /// + /// First tuple item is the account and second is the acceptance deadline. + #[pallet::storage] + #[pallet::getter(fn preapproved_usernames)] + pub type PendingUsernames = StorageMap< + _, + Blake2_128Concat, + Username, + (T::AccountId, BlockNumberFor), + OptionQuery, + >; + #[pallet::error] pub enum Error { /// Too many subs-accounts. @@ -249,6 +333,24 @@ pub mod pallet { JudgementForDifferentIdentity, /// Error that occurs when there is an issue paying for judgement. JudgementPaymentFailed, + /// The provided suffix is too long. + InvalidSuffix, + /// The sender does not have permission to issue a username. + NotUsernameAuthority, + /// The authority cannot allocate any more usernames. + NoAllocation, + /// The signature on a username was not valid. + InvalidSignature, + /// Setting this username requires a signature, but none was provided. + RequiresSignature, + /// The username does not meet the requirements. + InvalidUsername, + /// The username is already taken. + UsernameTaken, + /// The requested username does not exist. + NoUsername, + /// The username cannot be forcefully removed because it can still be accepted. + NotExpired, } #[pallet::event] @@ -275,6 +377,21 @@ pub mod pallet { /// A sub-identity was cleared, and the given deposit repatriated from the /// main identity account to the sub-identity account. SubIdentityRevoked { sub: T::AccountId, main: T::AccountId, deposit: BalanceOf }, + /// A username authority was added. + AuthorityAdded { authority: T::AccountId }, + /// A username authority was removed. + AuthorityRemoved { authority: T::AccountId }, + /// A username was set for `who`. + UsernameSet { who: T::AccountId, username: Username }, + /// A username was queued, but `who` must accept it prior to `expiration`. + UsernameQueued { who: T::AccountId, username: Username, expiration: BlockNumberFor }, + /// A queued username passed its expiration without being claimed and was removed. + PreapprovalExpired { whose: T::AccountId }, + /// A username was set as a primary and can be looked up from `who`. + PrimaryUsernameSet { who: T::AccountId, username: Username }, + /// A dangling username (as in, a username corresponding to an account that has removed its + /// identity) has been removed. + DanglingUsernameRemoved { who: T::AccountId, username: Username }, } #[pallet::call] @@ -331,36 +448,34 @@ pub mod pallet { info: Box, ) -> DispatchResultWithPostInfo { let sender = ensure_signed(origin)?; - let encoded_byte_size = info.encoded_size() as u32; - let byte_deposit = - T::ByteDeposit::get().saturating_mul(>::from(encoded_byte_size)); - - let mut id = match >::get(&sender) { - Some(mut id) => { - // Only keep non-positive judgements. - id.judgements.retain(|j| j.1.is_sticky()); - id.info = *info; - id - }, - None => Registration { - info: *info, - judgements: BoundedVec::default(), - deposit: Zero::zero(), - }, + + let (mut id, username) = match >::get(&sender) { + Some((mut id, maybe_username)) => ( + { + // Only keep non-positive judgements. + id.judgements.retain(|j| j.1.is_sticky()); + id.info = *info; + id + }, + maybe_username, + ), + None => ( + Registration { + info: *info, + judgements: BoundedVec::default(), + deposit: Zero::zero(), + }, + None, + ), }; + let new_deposit = Self::calculate_identity_deposit(&id.info); let old_deposit = id.deposit; - id.deposit = T::BasicDeposit::get().saturating_add(byte_deposit); - if id.deposit > old_deposit { - T::Currency::reserve(&sender, id.deposit - old_deposit)?; - } - if old_deposit > id.deposit { - let err_amount = T::Currency::unreserve(&sender, old_deposit - id.deposit); - debug_assert!(err_amount.is_zero()); - } + Self::rejig_deposit(&sender, old_deposit, new_deposit)?; + id.deposit = new_deposit; let judgements = id.judgements.len(); - >::insert(&sender, id); + >::insert(&sender, (id, username)); Self::deposit_event(Event::IdentitySet { who: sender }); Ok(Some(T::WeightInfo::set_identity(judgements as u32)).into()) @@ -452,11 +567,15 @@ pub mod pallet { let sender = ensure_signed(origin)?; let (subs_deposit, sub_ids) = >::take(&sender); - let id = >::take(&sender).ok_or(Error::::NotNamed)?; + let (id, maybe_username) = + >::take(&sender).ok_or(Error::::NoIdentity)?; let deposit = id.total_deposit().saturating_add(subs_deposit); for sub in sub_ids.iter() { >::remove(sub); } + if let Some(username) = maybe_username { + AccountOfUsername::::remove(username); + } let err_amount = T::Currency::unreserve(&sender, deposit); debug_assert!(err_amount.is_zero()); @@ -501,7 +620,7 @@ pub mod pallet { .and_then(Option::as_ref) .ok_or(Error::::EmptyIndex)?; ensure!(max_fee >= registrar.fee, Error::::FeeChanged); - let mut id = >::get(&sender).ok_or(Error::::NoIdentity)?; + let (mut id, username) = >::get(&sender).ok_or(Error::::NoIdentity)?; let item = (reg_index, Judgement::FeePaid(registrar.fee)); match id.judgements.binary_search_by_key(®_index, |x| x.0) { @@ -518,7 +637,7 @@ pub mod pallet { T::Currency::reserve(&sender, registrar.fee)?; let judgements = id.judgements.len(); - >::insert(&sender, id); + >::insert(&sender, (id, username)); Self::deposit_event(Event::JudgementRequested { who: sender, @@ -545,7 +664,7 @@ pub mod pallet { reg_index: RegistrarIndex, ) -> DispatchResultWithPostInfo { let sender = ensure_signed(origin)?; - let mut id = >::get(&sender).ok_or(Error::::NoIdentity)?; + let (mut id, username) = >::get(&sender).ok_or(Error::::NoIdentity)?; let pos = id .judgements @@ -560,7 +679,7 @@ pub mod pallet { let err_amount = T::Currency::unreserve(&sender, fee); debug_assert!(err_amount.is_zero()); let judgements = id.judgements.len(); - >::insert(&sender, id); + >::insert(&sender, (id, username)); Self::deposit_event(Event::JudgementUnrequested { who: sender, @@ -679,6 +798,8 @@ pub mod pallet { /// - `identity`: The hash of the [`IdentityInformationProvider`] for that the judgement is /// provided. /// + /// Note: Judgements do not apply to a username. + /// /// Emits `JudgementGiven` if successful. #[pallet::call_index(9)] #[pallet::weight(T::WeightInfo::provide_judgement(T::MaxRegistrars::get()))] @@ -697,7 +818,8 @@ pub mod pallet { .and_then(Option::as_ref) .filter(|r| r.account == sender) .ok_or(Error::::InvalidIndex)?; - let mut id = >::get(&target).ok_or(Error::::InvalidTarget)?; + let (mut id, username) = + >::get(&target).ok_or(Error::::InvalidTarget)?; if T::Hashing::hash_of(&id.info) != identity { return Err(Error::::JudgementForDifferentIdentity.into()) @@ -724,7 +846,7 @@ pub mod pallet { } let judgements = id.judgements.len(); - >::insert(&target, id); + >::insert(&target, (id, username)); Self::deposit_event(Event::JudgementGiven { target, registrar_index: reg_index }); Ok(Some(T::WeightInfo::provide_judgement(judgements as u32)).into()) @@ -757,11 +879,15 @@ pub mod pallet { let target = T::Lookup::lookup(target)?; // Grab their deposit (and check that they have one). let (subs_deposit, sub_ids) = >::take(&target); - let id = >::take(&target).ok_or(Error::::NotNamed)?; + let (id, maybe_username) = + >::take(&target).ok_or(Error::::NoIdentity)?; let deposit = id.total_deposit().saturating_add(subs_deposit); for sub in sub_ids.iter() { >::remove(sub); } + if let Some(username) = maybe_username { + AccountOfUsername::::remove(username); + } // Slash their deposit from them. T::Slashed::on_unbalanced(T::Currency::slash_reserved(&target, deposit).0); @@ -886,6 +1012,186 @@ pub mod pallet { }); Ok(()) } + + /// Add an `AccountId` with permission to grant usernames with a given `suffix` appended. + /// + /// The authority can grant up to `allocation` usernames. To top up their allocation, they + /// should just issue (or request via governance) a new `add_username_authority` call. + #[pallet::call_index(15)] + #[pallet::weight(T::WeightInfo::add_username_authority())] + pub fn add_username_authority( + origin: OriginFor, + authority: AccountIdLookupOf, + suffix: Vec, + allocation: u32, + ) -> DispatchResult { + T::UsernameAuthorityOrigin::ensure_origin(origin)?; + let authority = T::Lookup::lookup(authority)?; + // We don't need to check the length because it gets checked when casting into a + // `BoundedVec`. + Self::validate_username(&suffix, None).map_err(|_| Error::::InvalidSuffix)?; + let suffix = Suffix::::try_from(suffix).map_err(|_| Error::::InvalidSuffix)?; + // The authority may already exist, but we don't need to check. They might be changing + // their suffix or adding allocation, so we just want to overwrite whatever was there. + UsernameAuthorities::::insert( + &authority, + AuthorityPropertiesOf:: { suffix, allocation }, + ); + Self::deposit_event(Event::AuthorityAdded { authority }); + Ok(()) + } + + /// Remove `authority` from the username authorities. + #[pallet::call_index(16)] + #[pallet::weight(T::WeightInfo::remove_username_authority())] + pub fn remove_username_authority( + origin: OriginFor, + authority: AccountIdLookupOf, + ) -> DispatchResult { + T::UsernameAuthorityOrigin::ensure_origin(origin)?; + let authority = T::Lookup::lookup(authority)?; + UsernameAuthorities::::take(&authority).ok_or(Error::::NotUsernameAuthority)?; + Self::deposit_event(Event::AuthorityRemoved { authority }); + Ok(()) + } + + /// Set the username for `who`. Must be called by a username authority. + /// + /// The authority must have an `allocation`. Users can either pre-sign their usernames or + /// accept them later. + /// + /// Usernames must: + /// - Only contain lowercase ASCII characters or digits. + /// - When combined with the suffix of the issuing authority be _less than_ the + /// `MaxUsernameLength`. + #[pallet::call_index(17)] + #[pallet::weight(T::WeightInfo::set_username_for())] + pub fn set_username_for( + origin: OriginFor, + who: AccountIdLookupOf, + username: Vec, + signature: Option, + ) -> DispatchResult { + // Ensure origin is a Username Authority and has an allocation. Decrement their + // allocation by one. + let sender = ensure_signed(origin)?; + let suffix = UsernameAuthorities::::try_mutate( + &sender, + |maybe_authority| -> Result, DispatchError> { + let properties = + maybe_authority.as_mut().ok_or(Error::::NotUsernameAuthority)?; + ensure!(properties.allocation > 0, Error::::NoAllocation); + properties.allocation.saturating_dec(); + Ok(properties.suffix.clone()) + }, + )?; + + // Ensure that the username only contains allowed characters. We already know the suffix + // does. + let username_length = username.len().saturating_add(suffix.len()) as u32; + Self::validate_username(&username, Some(username_length))?; + + // Concatenate the username with suffix and cast into a BoundedVec. Should be infallible + // since we already ensured it is below the max length. + let mut full_username = + Vec::with_capacity(username.len().saturating_add(suffix.len()).saturating_add(1)); + full_username.extend(username); + full_username.extend(b"."); + full_username.extend(suffix); + let bounded_username = + Username::::try_from(full_username).map_err(|_| Error::::InvalidUsername)?; + + // Usernames must be unique. Ensure it's not taken. + ensure!( + !AccountOfUsername::::contains_key(&bounded_username), + Error::::UsernameTaken + ); + ensure!( + !PendingUsernames::::contains_key(&bounded_username), + Error::::UsernameTaken + ); + + // Insert or queue. + let who = T::Lookup::lookup(who)?; + if let Some(s) = signature { + // Account has pre-signed an authorization. Verify the signature provided and grant + // the username directly. + let encoded = Encode::encode(&bounded_username.to_vec()); + Self::validate_signature(&encoded, &s, &who)?; + Self::insert_username(&who, bounded_username); + } else { + // The user must accept the username, therefore, queue it. + Self::queue_acceptance(&who, bounded_username); + } + Ok(()) + } + + /// Accept a given username that an `authority` granted. The call must include the full + /// username, as in `username.suffix`. + #[pallet::call_index(18)] + #[pallet::weight(T::WeightInfo::accept_username())] + pub fn accept_username( + origin: OriginFor, + username: Username, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + let (approved_for, _) = + PendingUsernames::::take(&username).ok_or(Error::::NoUsername)?; + ensure!(approved_for == who.clone(), Error::::InvalidUsername); + Self::insert_username(&who, username.clone()); + Self::deposit_event(Event::UsernameSet { who: who.clone(), username }); + Ok(Pays::No.into()) + } + + /// Remove an expired username approval. The username was approved by an authority but never + /// accepted by the user and must now be beyond its expiration. The call must include the + /// full username, as in `username.suffix`. + #[pallet::call_index(19)] + #[pallet::weight(T::WeightInfo::remove_expired_approval())] + pub fn remove_expired_approval( + origin: OriginFor, + username: Username, + ) -> DispatchResultWithPostInfo { + let _ = ensure_signed(origin)?; + if let Some((who, expiration)) = PendingUsernames::::take(&username) { + let now = frame_system::Pallet::::block_number(); + ensure!(now > expiration, Error::::NotExpired); + Self::deposit_event(Event::PreapprovalExpired { whose: who.clone() }); + Ok(Pays::No.into()) + } else { + Err(Error::::NoUsername.into()) + } + } + + /// Set a given username as the primary. The username should include the suffix. + #[pallet::call_index(20)] + #[pallet::weight(T::WeightInfo::set_primary_username())] + pub fn set_primary_username(origin: OriginFor, username: Username) -> DispatchResult { + // ensure `username` maps to `origin` (i.e. has already been set by an authority). + let who = ensure_signed(origin)?; + ensure!(AccountOfUsername::::contains_key(&username), Error::::NoUsername); + let (registration, _maybe_username) = + IdentityOf::::get(&who).ok_or(Error::::NoIdentity)?; + IdentityOf::::insert(&who, (registration, Some(username.clone()))); + Self::deposit_event(Event::PrimaryUsernameSet { who: who.clone(), username }); + Ok(()) + } + + /// Remove a username that corresponds to an account with no identity. Exists when a user + /// gets a username but then calls `clear_identity`. + #[pallet::call_index(21)] + #[pallet::weight(T::WeightInfo::remove_dangling_username())] + pub fn remove_dangling_username( + origin: OriginFor, + username: Username, + ) -> DispatchResultWithPostInfo { + // ensure `username` maps to `origin` (i.e. has already been set by an authority). + let _ = ensure_signed(origin)?; + let who = AccountOfUsername::::take(&username).ok_or(Error::::NoUsername)?; + ensure!(!IdentityOf::::contains_key(&who), Error::::InvalidUsername); + Self::deposit_event(Event::DanglingUsernameRemoved { who: who.clone(), username }); + Ok(Pays::No.into()) + } } } @@ -925,7 +1231,104 @@ impl Pallet { fields: ::FieldsIdentifier, ) -> bool { IdentityOf::::get(who) - .map_or(false, |registration| (registration.info.has_identity(fields))) + .map_or(false, |(registration, _username)| (registration.info.has_identity(fields))) + } + + /// Calculate the deposit required for an identity. + fn calculate_identity_deposit(info: &T::IdentityInformation) -> BalanceOf { + let bytes = info.encoded_size() as u32; + let byte_deposit = T::ByteDeposit::get().saturating_mul(>::from(bytes)); + T::BasicDeposit::get().saturating_add(byte_deposit) + } + + /// Validate that a username conforms to allowed characters/format. + /// + /// The function will validate the characters in `username` and that `length` (if `Some`) + /// conforms to the limit. It is not expected to pass a fully formatted username here (i.e. one + /// with any protocol-added characters included, such as a `.`). The suffix is also separately + /// validated by this function to ensure the full username conforms. + fn validate_username(username: &Vec, length: Option) -> DispatchResult { + // Verify input length before allocating a Vec with the user's input. `<` instead of `<=` + // because it needs one element for the point (`username` + `.` + `suffix`). + if let Some(l) = length { + ensure!(l < T::MaxUsernameLength::get(), Error::::InvalidUsername); + } + // Usernames cannot be empty. + ensure!(!username.is_empty(), Error::::InvalidUsername); + // Username must be lowercase and alphanumeric. + ensure!( + username.iter().all(|byte| byte.is_ascii_digit() || byte.is_ascii_lowercase()), + Error::::InvalidUsername + ); + Ok(()) + } + + /// Validate a signature. Supports signatures on raw `data` or `data` wrapped in HTML ``. + pub fn validate_signature( + data: &Vec, + signature: &T::OffchainSignature, + signer: &T::AccountId, + ) -> DispatchResult { + // Happy path, user has signed the raw data. + if signature.verify(&data[..], &signer) { + return Ok(()) + } + // NOTE: for security reasons modern UIs implicitly wrap the data requested to sign into + // ` + data + `, so why we support both wrapped and raw versions. + let prefix = b""; + let suffix = b""; + let mut wrapped: Vec = Vec::with_capacity(data.len() + prefix.len() + suffix.len()); + wrapped.extend(prefix); + wrapped.extend(data); + wrapped.extend(suffix); + + ensure!(signature.verify(&wrapped[..], &signer), Error::::InvalidSignature); + + Ok(()) + } + + /// A username has met all conditions. Insert the relevant storage items. + pub fn insert_username(who: &T::AccountId, username: Username) { + // Check if they already have a primary. If so, leave it. If not, set it. + // Likewise, check if they have an identity. If not, give them a minimal one. + let (reg, primary_username, new_is_primary) = match >::get(&who) { + // User has an existing Identity and a primary username. Leave it. + Some((reg, Some(primary))) => (reg, primary, false), + // User has an Identity but no primary. Set the new one as primary. + Some((reg, None)) => (reg, username.clone(), true), + // User does not have an existing Identity. Give them a fresh default one and set + // their username as primary. + None => ( + Registration { + info: Default::default(), + judgements: Default::default(), + deposit: Zero::zero(), + }, + username.clone(), + true, + ), + }; + + // Enter in identity map. Note: In the case that the user did not have a pre-existing + // Identity, we have given them the storage item for free. If they ever call + // `set_identity` with identity info, then they will need to place the normal identity + // deposit. + IdentityOf::::insert(&who, (reg, Some(primary_username))); + // Enter in username map. + AccountOfUsername::::insert(username.clone(), &who); + Self::deposit_event(Event::UsernameSet { who: who.clone(), username: username.clone() }); + if new_is_primary { + Self::deposit_event(Event::PrimaryUsernameSet { who: who.clone(), username }); + } + } + + /// A username was granted by an authority, but must be accepted by `who`. Put the username + /// into a queue for acceptance. + pub fn queue_acceptance(who: &T::AccountId, username: Username) { + let now = frame_system::Pallet::::block_number(); + let expiration = now.saturating_add(T::PendingUsernameExpiration::get()); + PendingUsernames::::insert(&username, (who.clone(), expiration)); + Self::deposit_event(Event::UsernameQueued { who: who.clone(), username, expiration }); } /// Reap an identity, clearing associated storage items and refunding any deposits. This @@ -943,7 +1346,7 @@ impl Pallet { pub fn reap_identity(who: &T::AccountId) -> Result<(u32, u32, u32), DispatchError> { // `take` any storage items keyed by `target` // identity - let id = >::take(&who).ok_or(Error::::NotNamed)?; + let (id, _maybe_username) = >::take(&who).ok_or(Error::::NoIdentity)?; let registrars = id.judgements.len() as u32; let encoded_byte_size = id.info.encoded_size() as u32; @@ -976,8 +1379,8 @@ impl Pallet { // Identity Deposit let new_id_deposit = IdentityOf::::try_mutate( &target, - |registration| -> Result, DispatchError> { - let reg = registration.as_mut().ok_or(Error::::NoIdentity)?; + |identity_of| -> Result, DispatchError> { + let (reg, _) = identity_of.as_mut().ok_or(Error::::NoIdentity)?; // Calculate what deposit should be let encoded_byte_size = reg.info.encoded_size() as u32; let byte_deposit = @@ -1014,11 +1417,14 @@ impl Pallet { ) -> DispatchResult { IdentityOf::::insert( &who, - Registration { - judgements: Default::default(), - deposit: Zero::zero(), - info: info.clone(), - }, + ( + Registration { + judgements: Default::default(), + deposit: Zero::zero(), + info: info.clone(), + }, + None::>, + ), ); Ok(()) } @@ -1030,7 +1436,6 @@ impl Pallet { who: &T::AccountId, subs: Vec<(T::AccountId, Data)>, ) -> DispatchResult { - use frame_support::BoundedVec; let mut sub_accounts = BoundedVec::::default(); for (sub, name) in subs { >::insert(&sub, (who.clone(), name)); diff --git a/substrate/frame/identity/src/migration.rs b/substrate/frame/identity/src/migration.rs new file mode 100644 index 00000000000..88ac08d1bf5 --- /dev/null +++ b/substrate/frame/identity/src/migration.rs @@ -0,0 +1,124 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Storage migrations for the Identity pallet. + +use super::*; +use frame_support::{migrations::VersionedMigration, pallet_prelude::*, traits::OnRuntimeUpgrade}; + +#[cfg(feature = "try-runtime")] +use codec::{Decode, Encode}; +#[cfg(feature = "try-runtime")] +use sp_runtime::TryRuntimeError; + +pub mod versioned { + use super::*; + + pub type V0ToV1 = VersionedMigration< + 0, + 1, + v1::VersionUncheckedMigrateV0ToV1, + crate::pallet::Pallet, + ::DbWeight, + >; +} + +pub mod v1 { + use super::*; + + /// The log target. + const TARGET: &'static str = "runtime::identity::migration::v1"; + + /// The old identity type, useful in pre-upgrade. + mod v0 { + use super::*; + use frame_support::storage_alias; + + #[storage_alias] + pub type IdentityOf = StorageMap< + Pallet, + Twox64Concat, + ::AccountId, + Registration< + BalanceOf, + ::MaxRegistrars, + ::IdentityInformation, + >, + OptionQuery, + >; + } + + /// Migration to add usernames to Identity info. + /// + /// `T` is the runtime and `KL` is the key limit to migrate. This is just a safety guard to + /// prevent stalling a parachain by accumulating too much weight in the migration. To have an + /// unlimited migration (e.g. in a chain without PoV limits), set this to `u64::MAX`. + pub struct VersionUncheckedMigrateV0ToV1(PhantomData); + impl OnRuntimeUpgrade for VersionUncheckedMigrateV0ToV1 { + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, TryRuntimeError> { + let identities = v0::IdentityOf::::iter().count(); + log::info!( + target: TARGET, + "pre-upgrade state contains '{}' identities.", + identities + ); + ensure!((identities as u64) < KL, "too many identities to migrate"); + Ok((identities as u64).encode()) + } + + fn on_runtime_upgrade() -> Weight { + log::info!( + target: TARGET, + "running storage migration from version 0 to version 1." + ); + + let mut weight = T::DbWeight::get().reads(1); + let mut translated: u64 = 0; + let mut interrupted = false; + + for (account, registration) in v0::IdentityOf::::iter() { + IdentityOf::::insert(account, (registration, None::>)); + translated.saturating_inc(); + if translated >= KL { + log::warn!( + "Incomplete! Migration limit reached. Only {} identities migrated.", + translated + ); + interrupted = true; + break + } + } + if !interrupted { + log::info!("all {} identities migrated", translated); + } + + weight.saturating_accrue(T::DbWeight::get().reads_writes(translated, translated)); + weight.saturating_accrue(T::DbWeight::get().writes(1)); + weight + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(state: Vec) -> Result<(), TryRuntimeError> { + let identities_to_migrate: u64 = Decode::decode(&mut &state[..]) + .expect("failed to decode the state from pre-upgrade."); + let identities = IdentityOf::::iter().count() as u64; + log::info!("post-upgrade expects '{}' identities to have been migrated.", identities); + ensure!(identities_to_migrate == identities, "must migrate all identities."); + log::info!(target: TARGET, "migrated all identities."); + Ok(()) + } + } +} diff --git a/substrate/frame/identity/src/tests.rs b/substrate/frame/identity/src/tests.rs index 8ac7b4d66cb..4da31782261 100644 --- a/substrate/frame/identity/src/tests.rs +++ b/substrate/frame/identity/src/tests.rs @@ -25,17 +25,23 @@ use crate::{ use codec::{Decode, Encode}; use frame_support::{ - assert_noop, assert_ok, derive_impl, ord_parameter_types, parameter_types, - traits::{ConstU32, ConstU64, EitherOfDiverse, Get}, + assert_noop, assert_ok, derive_impl, parameter_types, + traits::{ConstU32, ConstU64, Get, OnFinalize, OnInitialize}, BoundedVec, }; -use frame_system::{EnsureRoot, EnsureSignedBy}; +use frame_system::EnsureRoot; use sp_core::H256; +use sp_io::crypto::{sr25519_generate, sr25519_sign}; +use sp_keystore::{testing::MemoryKeystore, KeystoreExt}; use sp_runtime::{ - traits::{BadOrigin, BlakeTwo256, IdentityLookup}, - BuildStorage, + traits::{BadOrigin, BlakeTwo256, IdentifyAccount, IdentityLookup, Verify}, + BuildStorage, MultiSignature, MultiSigner, }; +type AccountIdOf = ::AccountId; +pub type AccountPublic = ::Signer; +pub type AccountId = ::AccountId; + type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( @@ -57,7 +63,7 @@ impl frame_system::Config for Test { type Hash = H256; type RuntimeCall = RuntimeCall; type Hashing = BlakeTwo256; - type AccountId = u64; + type AccountId = AccountId; type Lookup = IdentityLookup; type Block = Block; type RuntimeEvent = RuntimeEvent; @@ -96,12 +102,6 @@ parameter_types! { pub const MaxRegistrars: u32 = 20; } -ord_parameter_types! { - pub const One: u64 = 1; - pub const Two: u64 = 2; -} -type EnsureOneOrRoot = EitherOfDiverse, EnsureSignedBy>; -type EnsureTwoOrRoot = EitherOfDiverse, EnsureSignedBy>; impl pallet_identity::Config for Test { type RuntimeEvent = RuntimeEvent; type Currency = Balances; @@ -112,22 +112,102 @@ impl pallet_identity::Config for Test { type MaxSubAccounts = ConstU32<2>; type IdentityInformation = IdentityInfo; type MaxRegistrars = MaxRegistrars; - type RegistrarOrigin = EnsureOneOrRoot; - type ForceOrigin = EnsureTwoOrRoot; + type RegistrarOrigin = EnsureRoot; + type ForceOrigin = EnsureRoot; + type OffchainSignature = MultiSignature; + type SigningPublicKey = AccountPublic; + type UsernameAuthorityOrigin = EnsureRoot; + type PendingUsernameExpiration = ConstU64<100>; + type MaxSuffixLength = ConstU32<7>; + type MaxUsernameLength = ConstU32<32>; type WeightInfo = (); } pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { - balances: vec![(1, 100), (2, 100), (3, 100), (10, 1000), (20, 1000), (30, 1000)], + balances: vec![ + (account(1), 100), + (account(2), 100), + (account(3), 100), + (account(10), 1000), + (account(20), 1000), + (account(30), 1000), + ], } .assimilate_storage(&mut t) .unwrap(); - t.into() + let mut ext = sp_io::TestExternalities::new(t); + ext.register_extension(KeystoreExt::new(MemoryKeystore::new())); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +fn run_to_block(n: u64) { + while System::block_number() < n { + Identity::on_finalize(System::block_number()); + Balances::on_finalize(System::block_number()); + System::on_finalize(System::block_number()); + System::set_block_number(System::block_number() + 1); + System::on_initialize(System::block_number()); + Balances::on_initialize(System::block_number()); + Identity::on_initialize(System::block_number()); + } +} + +fn account(id: u8) -> AccountIdOf { + [id; 32].into() +} + +fn account_from_u32(id: u32) -> AccountIdOf { + let mut buffer = [255u8; 32]; + let id_bytes = id.to_le_bytes(); + let id_size = id_bytes.len(); + for ii in 0..buffer.len() / id_size { + let s = ii * id_size; + let e = s + id_size; + buffer[s..e].clone_from_slice(&id_bytes[..]); + } + buffer.into() +} + +fn accounts() -> [AccountIdOf; 8] { + [ + account(1), + account(2), + account(3), + account(4), // unfunded + account(10), + account(20), + account(30), + account(40), // unfunded + ] +} + +fn unfunded_accounts() -> [AccountIdOf; 2] { + [account(100), account(101)] +} + +// First return value is a username that would be submitted as a parameter to the dispatchable. As +// in, it has no suffix attached. Second is a full BoundedVec username with suffix, which is what a +// user would need to sign. +fn test_username_of(int: Vec, suffix: Vec) -> (Vec, Username) { + let base = b"testusername"; + let mut username = Vec::with_capacity(base.len() + int.len()); + username.extend(base); + username.extend(int); + + let mut bounded_username = Vec::with_capacity(username.len() + suffix.len() + 1); + bounded_username.extend(username.clone()); + bounded_username.extend(b"."); + bounded_username.extend(suffix); + let bounded_username = Username::::try_from(bounded_username) + .expect("test usernames should fit within bounds"); + + (username, bounded_username) } -fn ten() -> IdentityInfo { +fn infoof_ten() -> IdentityInfo { IdentityInfo { display: Data::Raw(b"ten".to_vec().try_into().unwrap()), legal: Data::Raw(b"The Right Ordinal Ten, Esq.".to_vec().try_into().unwrap()), @@ -135,7 +215,7 @@ fn ten() -> IdentityInfo { } } -fn twenty() -> IdentityInfo { +fn infoof_twenty() -> IdentityInfo { IdentityInfo { display: Data::Raw(b"twenty".to_vec().try_into().unwrap()), legal: Data::Raw(b"The Right Ordinal Twenty, Esq.".to_vec().try_into().unwrap()), @@ -188,54 +268,58 @@ fn identity_fields_repr_works() { fn editing_subaccounts_should_work() { new_test_ext().execute_with(|| { let data = |x| Data::Raw(vec![x; 1].try_into().unwrap()); + let [one, two, three, _, ten, twenty, _, _] = accounts(); assert_noop!( - Identity::add_sub(RuntimeOrigin::signed(10), 20, data(1)), + Identity::add_sub(RuntimeOrigin::signed(ten.clone()), twenty.clone(), data(1)), Error::::NoIdentity ); - let ten = ten(); - assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten.clone()))); - let id_deposit = id_deposit(&ten); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit); + let ten_info = infoof_ten(); + assert_ok!(Identity::set_identity( + RuntimeOrigin::signed(ten.clone()), + Box::new(ten_info.clone()) + )); + let id_deposit = id_deposit(&ten_info); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit); let sub_deposit: u64 = <::SubAccountDeposit as Get>::get(); // first sub account - assert_ok!(Identity::add_sub(RuntimeOrigin::signed(10), 1, data(1))); - assert_eq!(SuperOf::::get(1), Some((10, data(1)))); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit - sub_deposit); + assert_ok!(Identity::add_sub(RuntimeOrigin::signed(ten.clone()), one.clone(), data(1))); + assert_eq!(SuperOf::::get(one.clone()), Some((ten.clone(), data(1)))); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit - sub_deposit); // second sub account - assert_ok!(Identity::add_sub(RuntimeOrigin::signed(10), 2, data(2))); - assert_eq!(SuperOf::::get(1), Some((10, data(1)))); - assert_eq!(SuperOf::::get(2), Some((10, data(2)))); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit - 2 * sub_deposit); + assert_ok!(Identity::add_sub(RuntimeOrigin::signed(ten.clone()), two.clone(), data(2))); + assert_eq!(SuperOf::::get(one.clone()), Some((ten.clone(), data(1)))); + assert_eq!(SuperOf::::get(two.clone()), Some((ten.clone(), data(2)))); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit - 2 * sub_deposit); // third sub account is too many assert_noop!( - Identity::add_sub(RuntimeOrigin::signed(10), 3, data(3)), + Identity::add_sub(RuntimeOrigin::signed(ten.clone()), three.clone(), data(3)), Error::::TooManySubAccounts ); // rename first sub account - assert_ok!(Identity::rename_sub(RuntimeOrigin::signed(10), 1, data(11))); - assert_eq!(SuperOf::::get(1), Some((10, data(11)))); - assert_eq!(SuperOf::::get(2), Some((10, data(2)))); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit - 2 * sub_deposit); + assert_ok!(Identity::rename_sub(RuntimeOrigin::signed(ten.clone()), one.clone(), data(11))); + assert_eq!(SuperOf::::get(one.clone()), Some((ten.clone(), data(11)))); + assert_eq!(SuperOf::::get(two.clone()), Some((ten.clone(), data(2)))); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit - 2 * sub_deposit); // remove first sub account - assert_ok!(Identity::remove_sub(RuntimeOrigin::signed(10), 1)); - assert_eq!(SuperOf::::get(1), None); - assert_eq!(SuperOf::::get(2), Some((10, data(2)))); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit - sub_deposit); + assert_ok!(Identity::remove_sub(RuntimeOrigin::signed(ten.clone()), one.clone())); + assert_eq!(SuperOf::::get(one.clone()), None); + assert_eq!(SuperOf::::get(two.clone()), Some((ten.clone(), data(2)))); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit - sub_deposit); // add third sub account - assert_ok!(Identity::add_sub(RuntimeOrigin::signed(10), 3, data(3))); - assert_eq!(SuperOf::::get(1), None); - assert_eq!(SuperOf::::get(2), Some((10, data(2)))); - assert_eq!(SuperOf::::get(3), Some((10, data(3)))); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit - 2 * sub_deposit); + assert_ok!(Identity::add_sub(RuntimeOrigin::signed(ten.clone()), three.clone(), data(3))); + assert_eq!(SuperOf::::get(one), None); + assert_eq!(SuperOf::::get(two), Some((ten.clone(), data(2)))); + assert_eq!(SuperOf::::get(three), Some((ten.clone(), data(3)))); + assert_eq!(Balances::free_balance(ten), 1000 - id_deposit - 2 * sub_deposit); }); } @@ -243,35 +327,39 @@ fn editing_subaccounts_should_work() { fn resolving_subaccount_ownership_works() { new_test_ext().execute_with(|| { let data = |x| Data::Raw(vec![x; 1].try_into().unwrap()); + let [one, _, _, _, ten, twenty, _, _] = accounts(); let sub_deposit: u64 = <::SubAccountDeposit as Get>::get(); - let ten = ten(); - let ten_deposit = id_deposit(&ten); - let twenty = twenty(); - let twenty_deposit = id_deposit(&twenty); - assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten))); - assert_eq!(Balances::free_balance(10), 1000 - ten_deposit); - assert_ok!(Identity::set_identity(RuntimeOrigin::signed(20), Box::new(twenty))); - assert_eq!(Balances::free_balance(20), 1000 - twenty_deposit); + let ten_info = infoof_ten(); + let ten_deposit = id_deposit(&ten_info); + let twenty_info = infoof_twenty(); + let twenty_deposit = id_deposit(&twenty_info); + assert_ok!(Identity::set_identity(RuntimeOrigin::signed(ten.clone()), Box::new(ten_info))); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - ten_deposit); + assert_ok!(Identity::set_identity( + RuntimeOrigin::signed(twenty.clone()), + Box::new(twenty_info) + )); + assert_eq!(Balances::free_balance(twenty.clone()), 1000 - twenty_deposit); // 10 claims 1 as a subaccount - assert_ok!(Identity::add_sub(RuntimeOrigin::signed(10), 1, data(1))); - assert_eq!(Balances::free_balance(1), 100); - assert_eq!(Balances::free_balance(10), 1000 - ten_deposit - sub_deposit); - assert_eq!(Balances::reserved_balance(10), ten_deposit + sub_deposit); + assert_ok!(Identity::add_sub(RuntimeOrigin::signed(ten.clone()), one.clone(), data(1))); + assert_eq!(Balances::free_balance(one.clone()), 100); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - ten_deposit - sub_deposit); + assert_eq!(Balances::reserved_balance(ten.clone()), ten_deposit + sub_deposit); // 20 cannot claim 1 now assert_noop!( - Identity::add_sub(RuntimeOrigin::signed(20), 1, data(1)), + Identity::add_sub(RuntimeOrigin::signed(twenty.clone()), one.clone(), data(1)), Error::::AlreadyClaimed ); // 1 wants to be with 20 so it quits from 10 - assert_ok!(Identity::quit_sub(RuntimeOrigin::signed(1))); + assert_ok!(Identity::quit_sub(RuntimeOrigin::signed(one.clone()))); // 1 gets the 10 that 10 paid. - assert_eq!(Balances::free_balance(1), 100 + sub_deposit); - assert_eq!(Balances::free_balance(10), 1000 - ten_deposit - sub_deposit); - assert_eq!(Balances::reserved_balance(10), ten_deposit); + assert_eq!(Balances::free_balance(one.clone()), 100 + sub_deposit); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - ten_deposit - sub_deposit); + assert_eq!(Balances::reserved_balance(ten), ten_deposit); // 20 can claim 1 now - assert_ok!(Identity::add_sub(RuntimeOrigin::signed(20), 1, data(1))); + assert_ok!(Identity::add_sub(RuntimeOrigin::signed(twenty), one, data(1))); }); } @@ -288,11 +376,12 @@ fn trailing_zeros_decodes_into_default_data() { #[test] fn adding_registrar_invalid_index() { new_test_ext().execute_with(|| { - assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3)); - assert_ok!(Identity::set_fee(RuntimeOrigin::signed(3), 0, 10)); + let [_, _, three, _, _, _, _, _] = accounts(); + assert_ok!(Identity::add_registrar(RuntimeOrigin::root(), three.clone())); + assert_ok!(Identity::set_fee(RuntimeOrigin::signed(three.clone()), 0, 10)); let fields = IdentityField::Display | IdentityField::Legal; assert_noop!( - Identity::set_fields(RuntimeOrigin::signed(3), 100, fields.bits()), + Identity::set_fields(RuntimeOrigin::signed(three), 100, fields.bits()), Error::::InvalidIndex ); }); @@ -301,13 +390,14 @@ fn adding_registrar_invalid_index() { #[test] fn adding_registrar_should_work() { new_test_ext().execute_with(|| { - assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3)); - assert_ok!(Identity::set_fee(RuntimeOrigin::signed(3), 0, 10)); + let [_, _, three, _, _, _, _, _] = accounts(); + assert_ok!(Identity::add_registrar(RuntimeOrigin::root(), three.clone())); + assert_ok!(Identity::set_fee(RuntimeOrigin::signed(three.clone()), 0, 10)); let fields = IdentityField::Display | IdentityField::Legal; - assert_ok!(Identity::set_fields(RuntimeOrigin::signed(3), 0, fields.bits())); + assert_ok!(Identity::set_fields(RuntimeOrigin::signed(three.clone()), 0, fields.bits())); assert_eq!( Identity::registrars(), - vec![Some(RegistrarInfo { account: 3, fee: 10, fields: fields.bits() })] + vec![Some(RegistrarInfo { account: three, fee: 10, fields: fields.bits() })] ); }); } @@ -315,12 +405,12 @@ fn adding_registrar_should_work() { #[test] fn amount_of_registrars_is_limited() { new_test_ext().execute_with(|| { - for i in 1..MaxRegistrars::get() + 1 { - assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), i as u64)); + for ii in 1..MaxRegistrars::get() + 1 { + assert_ok!(Identity::add_registrar(RuntimeOrigin::root(), account_from_u32(ii))); } - let last_registrar = MaxRegistrars::get() as u64 + 1; + let last_registrar = MaxRegistrars::get() + 1; assert_noop!( - Identity::add_registrar(RuntimeOrigin::signed(1), last_registrar), + Identity::add_registrar(RuntimeOrigin::root(), account_from_u32(last_registrar)), Error::::TooManyRegistrars ); }); @@ -329,68 +419,79 @@ fn amount_of_registrars_is_limited() { #[test] fn registration_should_work() { new_test_ext().execute_with(|| { - assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3)); - assert_ok!(Identity::set_fee(RuntimeOrigin::signed(3), 0, 10)); - let mut three_fields = ten(); + let [_, _, three, _, ten, _, _, _] = accounts(); + assert_ok!(Identity::add_registrar(RuntimeOrigin::root(), three.clone())); + assert_ok!(Identity::set_fee(RuntimeOrigin::signed(three.clone()), 0, 10)); + let mut three_fields = infoof_ten(); three_fields.additional.try_push(Default::default()).unwrap(); three_fields.additional.try_push(Default::default()).unwrap(); assert!(three_fields.additional.try_push(Default::default()).is_err()); - let ten = ten(); - let id_deposit = id_deposit(&ten); - assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten.clone()))); - assert_eq!(Identity::identity(10).unwrap().info, ten); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit); - assert_ok!(Identity::clear_identity(RuntimeOrigin::signed(10))); - assert_eq!(Balances::free_balance(10), 1000); - assert_noop!(Identity::clear_identity(RuntimeOrigin::signed(10)), Error::::NotNamed); + let ten_info = infoof_ten(); + let id_deposit = id_deposit(&ten_info); + assert_ok!(Identity::set_identity( + RuntimeOrigin::signed(ten.clone()), + Box::new(ten_info.clone()) + )); + assert_eq!(Identity::identity(ten.clone()).unwrap().0.info, ten_info); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit); + assert_ok!(Identity::clear_identity(RuntimeOrigin::signed(ten.clone()))); + assert_eq!(Balances::free_balance(ten.clone()), 1000); + assert_noop!( + Identity::clear_identity(RuntimeOrigin::signed(ten)), + Error::::NoIdentity + ); }); } #[test] fn uninvited_judgement_should_work() { new_test_ext().execute_with(|| { + let [_, _, three, _, ten, _, _, _] = accounts(); assert_noop!( Identity::provide_judgement( - RuntimeOrigin::signed(3), + RuntimeOrigin::signed(three.clone()), 0, - 10, + ten.clone(), Judgement::Reasonable, H256::random() ), Error::::InvalidIndex ); - assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3)); + assert_ok!(Identity::add_registrar(RuntimeOrigin::root(), three.clone())); assert_noop!( Identity::provide_judgement( - RuntimeOrigin::signed(3), + RuntimeOrigin::signed(three.clone()), 0, - 10, + ten.clone(), Judgement::Reasonable, H256::random() ), Error::::InvalidTarget ); - assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten()))); + assert_ok!(Identity::set_identity( + RuntimeOrigin::signed(ten.clone()), + Box::new(infoof_ten()) + )); assert_noop!( Identity::provide_judgement( - RuntimeOrigin::signed(3), + RuntimeOrigin::signed(three.clone()), 0, - 10, + ten.clone(), Judgement::Reasonable, H256::random() ), Error::::JudgementForDifferentIdentity ); - let identity_hash = BlakeTwo256::hash_of(&ten()); + let identity_hash = BlakeTwo256::hash_of(&infoof_ten()); assert_noop!( Identity::provide_judgement( - RuntimeOrigin::signed(10), + RuntimeOrigin::signed(ten.clone()), 0, - 10, + ten.clone(), Judgement::Reasonable, identity_hash ), @@ -398,9 +499,9 @@ fn uninvited_judgement_should_work() { ); assert_noop!( Identity::provide_judgement( - RuntimeOrigin::signed(3), + RuntimeOrigin::signed(three.clone()), 0, - 10, + ten.clone(), Judgement::FeePaid(1), identity_hash ), @@ -408,46 +509,51 @@ fn uninvited_judgement_should_work() { ); assert_ok!(Identity::provide_judgement( - RuntimeOrigin::signed(3), + RuntimeOrigin::signed(three.clone()), 0, - 10, + ten.clone(), Judgement::Reasonable, identity_hash )); - assert_eq!(Identity::identity(10).unwrap().judgements, vec![(0, Judgement::Reasonable)]); + assert_eq!(Identity::identity(ten).unwrap().0.judgements, vec![(0, Judgement::Reasonable)]); }); } #[test] fn clearing_judgement_should_work() { new_test_ext().execute_with(|| { - assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3)); - assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten()))); + let [_, _, three, _, ten, _, _, _] = accounts(); + assert_ok!(Identity::add_registrar(RuntimeOrigin::root(), three.clone())); + assert_ok!(Identity::set_identity( + RuntimeOrigin::signed(ten.clone()), + Box::new(infoof_ten()) + )); assert_ok!(Identity::provide_judgement( - RuntimeOrigin::signed(3), + RuntimeOrigin::signed(three.clone()), 0, - 10, + ten.clone(), Judgement::Reasonable, - BlakeTwo256::hash_of(&ten()) + BlakeTwo256::hash_of(&infoof_ten()) )); - assert_ok!(Identity::clear_identity(RuntimeOrigin::signed(10))); - assert_eq!(Identity::identity(10), None); + assert_ok!(Identity::clear_identity(RuntimeOrigin::signed(ten.clone()))); + assert_eq!(Identity::identity(ten), None); }); } #[test] fn killing_slashing_should_work() { new_test_ext().execute_with(|| { - let ten = ten(); - let id_deposit = id_deposit(&ten); - assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten))); - assert_noop!(Identity::kill_identity(RuntimeOrigin::signed(1), 10), BadOrigin); - assert_ok!(Identity::kill_identity(RuntimeOrigin::signed(2), 10)); - assert_eq!(Identity::identity(10), None); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit); + let [one, _, _, _, ten, _, _, _] = accounts(); + let ten_info = infoof_ten(); + let id_deposit = id_deposit(&ten_info); + assert_ok!(Identity::set_identity(RuntimeOrigin::signed(ten.clone()), Box::new(ten_info))); + assert_noop!(Identity::kill_identity(RuntimeOrigin::signed(one), ten.clone()), BadOrigin); + assert_ok!(Identity::kill_identity(RuntimeOrigin::root(), ten.clone())); + assert_eq!(Identity::identity(ten.clone()), None); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit); assert_noop!( - Identity::kill_identity(RuntimeOrigin::signed(2), 10), - Error::::NotNamed + Identity::kill_identity(RuntimeOrigin::root(), ten), + Error::::NoIdentity ); }); } @@ -455,50 +561,75 @@ fn killing_slashing_should_work() { #[test] fn setting_subaccounts_should_work() { new_test_ext().execute_with(|| { - let ten = ten(); - let id_deposit = id_deposit(&ten); + let [_, _, _, _, ten, twenty, thirty, forty] = accounts(); + let ten_info = infoof_ten(); + let id_deposit = id_deposit(&ten_info); let sub_deposit: u64 = <::SubAccountDeposit as Get>::get(); - let mut subs = vec![(20, Data::Raw(vec![40; 1].try_into().unwrap()))]; + let mut subs = vec![(twenty.clone(), Data::Raw(vec![40; 1].try_into().unwrap()))]; assert_noop!( - Identity::set_subs(RuntimeOrigin::signed(10), subs.clone()), + Identity::set_subs(RuntimeOrigin::signed(ten.clone()), subs.clone()), Error::::NotFound ); - assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten))); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit); - assert_ok!(Identity::set_subs(RuntimeOrigin::signed(10), subs.clone())); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit - sub_deposit); - assert_eq!(Identity::subs_of(10), (sub_deposit, vec![20].try_into().unwrap())); - assert_eq!(Identity::super_of(20), Some((10, Data::Raw(vec![40; 1].try_into().unwrap())))); + assert_ok!(Identity::set_identity(RuntimeOrigin::signed(ten.clone()), Box::new(ten_info))); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit); + assert_ok!(Identity::set_subs(RuntimeOrigin::signed(ten.clone()), subs.clone())); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit - sub_deposit); + assert_eq!( + Identity::subs_of(ten.clone()), + (sub_deposit, vec![twenty.clone()].try_into().unwrap()) + ); + assert_eq!( + Identity::super_of(twenty.clone()), + Some((ten.clone(), Data::Raw(vec![40; 1].try_into().unwrap()))) + ); // push another item and re-set it. - subs.push((30, Data::Raw(vec![50; 1].try_into().unwrap()))); - assert_ok!(Identity::set_subs(RuntimeOrigin::signed(10), subs.clone())); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit - 2 * sub_deposit); - assert_eq!(Identity::subs_of(10), (2 * sub_deposit, vec![20, 30].try_into().unwrap())); - assert_eq!(Identity::super_of(20), Some((10, Data::Raw(vec![40; 1].try_into().unwrap())))); - assert_eq!(Identity::super_of(30), Some((10, Data::Raw(vec![50; 1].try_into().unwrap())))); + subs.push((thirty.clone(), Data::Raw(vec![50; 1].try_into().unwrap()))); + assert_ok!(Identity::set_subs(RuntimeOrigin::signed(ten.clone()), subs.clone())); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit - 2 * sub_deposit); + assert_eq!( + Identity::subs_of(ten.clone()), + (2 * sub_deposit, vec![twenty.clone(), thirty.clone()].try_into().unwrap()) + ); + assert_eq!( + Identity::super_of(twenty.clone()), + Some((ten.clone(), Data::Raw(vec![40; 1].try_into().unwrap()))) + ); + assert_eq!( + Identity::super_of(thirty.clone()), + Some((ten.clone(), Data::Raw(vec![50; 1].try_into().unwrap()))) + ); // switch out one of the items and re-set. - subs[0] = (40, Data::Raw(vec![60; 1].try_into().unwrap())); - assert_ok!(Identity::set_subs(RuntimeOrigin::signed(10), subs.clone())); + subs[0] = (forty.clone(), Data::Raw(vec![60; 1].try_into().unwrap())); + assert_ok!(Identity::set_subs(RuntimeOrigin::signed(ten.clone()), subs.clone())); // no change in the balance - assert_eq!(Balances::free_balance(10), 1000 - id_deposit - 2 * sub_deposit); - assert_eq!(Identity::subs_of(10), (2 * sub_deposit, vec![40, 30].try_into().unwrap())); - assert_eq!(Identity::super_of(20), None); - assert_eq!(Identity::super_of(30), Some((10, Data::Raw(vec![50; 1].try_into().unwrap())))); - assert_eq!(Identity::super_of(40), Some((10, Data::Raw(vec![60; 1].try_into().unwrap())))); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit - 2 * sub_deposit); + assert_eq!( + Identity::subs_of(ten.clone()), + (2 * sub_deposit, vec![forty.clone(), thirty.clone()].try_into().unwrap()) + ); + assert_eq!(Identity::super_of(twenty.clone()), None); + assert_eq!( + Identity::super_of(thirty.clone()), + Some((ten.clone(), Data::Raw(vec![50; 1].try_into().unwrap()))) + ); + assert_eq!( + Identity::super_of(forty.clone()), + Some((ten.clone(), Data::Raw(vec![60; 1].try_into().unwrap()))) + ); // clear - assert_ok!(Identity::set_subs(RuntimeOrigin::signed(10), vec![])); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit); - assert_eq!(Identity::subs_of(10), (0, BoundedVec::default())); - assert_eq!(Identity::super_of(30), None); - assert_eq!(Identity::super_of(40), None); + assert_ok!(Identity::set_subs(RuntimeOrigin::signed(ten.clone()), vec![])); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit); + assert_eq!(Identity::subs_of(ten.clone()), (0, BoundedVec::default())); + assert_eq!(Identity::super_of(thirty.clone()), None); + assert_eq!(Identity::super_of(forty), None); - subs.push((20, Data::Raw(vec![40; 1].try_into().unwrap()))); + subs.push((twenty, Data::Raw(vec![40; 1].try_into().unwrap()))); assert_noop!( - Identity::set_subs(RuntimeOrigin::signed(10), subs.clone()), + Identity::set_subs(RuntimeOrigin::signed(ten), subs.clone()), Error::::TooManySubAccounts ); }); @@ -507,67 +638,76 @@ fn setting_subaccounts_should_work() { #[test] fn clearing_account_should_remove_subaccounts_and_refund() { new_test_ext().execute_with(|| { - let ten = ten(); - assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten.clone()))); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit(&ten)); + let [_, _, _, _, ten, twenty, _, _] = accounts(); + let ten_info = infoof_ten(); + assert_ok!(Identity::set_identity( + RuntimeOrigin::signed(ten.clone()), + Box::new(ten_info.clone()) + )); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit(&ten_info)); assert_ok!(Identity::set_subs( - RuntimeOrigin::signed(10), - vec![(20, Data::Raw(vec![40; 1].try_into().unwrap()))] + RuntimeOrigin::signed(ten.clone()), + vec![(twenty.clone(), Data::Raw(vec![40; 1].try_into().unwrap()))] )); - assert_ok!(Identity::clear_identity(RuntimeOrigin::signed(10))); - assert_eq!(Balances::free_balance(10), 1000); - assert!(Identity::super_of(20).is_none()); + assert_ok!(Identity::clear_identity(RuntimeOrigin::signed(ten.clone()))); + assert_eq!(Balances::free_balance(ten), 1000); + assert!(Identity::super_of(twenty).is_none()); }); } #[test] fn killing_account_should_remove_subaccounts_and_not_refund() { new_test_ext().execute_with(|| { - let ten = ten(); - let id_deposit = id_deposit(&ten); + let [_, _, _, _, ten, twenty, _, _] = accounts(); + let ten_info = infoof_ten(); + let id_deposit = id_deposit(&ten_info); let sub_deposit: u64 = <::SubAccountDeposit as Get>::get(); - assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten))); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit); + assert_ok!(Identity::set_identity(RuntimeOrigin::signed(ten.clone()), Box::new(ten_info))); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit); assert_ok!(Identity::set_subs( - RuntimeOrigin::signed(10), - vec![(20, Data::Raw(vec![40; 1].try_into().unwrap()))] + RuntimeOrigin::signed(ten.clone()), + vec![(twenty.clone(), Data::Raw(vec![40; 1].try_into().unwrap()))] )); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit - sub_deposit); - assert_ok!(Identity::kill_identity(RuntimeOrigin::signed(2), 10)); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit - sub_deposit); - assert!(Identity::super_of(20).is_none()); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit - sub_deposit); + assert_ok!(Identity::kill_identity(RuntimeOrigin::root(), ten.clone())); + assert_eq!(Balances::free_balance(ten), 1000 - id_deposit - sub_deposit); + assert!(Identity::super_of(twenty).is_none()); }); } #[test] fn cancelling_requested_judgement_should_work() { new_test_ext().execute_with(|| { - assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3)); - assert_ok!(Identity::set_fee(RuntimeOrigin::signed(3), 0, 10)); + let [_, _, three, _, ten, _, _, _] = accounts(); + assert_ok!(Identity::add_registrar(RuntimeOrigin::root(), three.clone())); + assert_ok!(Identity::set_fee(RuntimeOrigin::signed(three.clone()), 0, 10)); assert_noop!( - Identity::cancel_request(RuntimeOrigin::signed(10), 0), + Identity::cancel_request(RuntimeOrigin::signed(ten.clone()), 0), Error::::NoIdentity ); - let ten = ten(); - assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten.clone()))); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit(&ten)); - assert_ok!(Identity::request_judgement(RuntimeOrigin::signed(10), 0, 10)); - assert_ok!(Identity::cancel_request(RuntimeOrigin::signed(10), 0)); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit(&ten)); + let ten_info = infoof_ten(); + assert_ok!(Identity::set_identity( + RuntimeOrigin::signed(ten.clone()), + Box::new(ten_info.clone()) + )); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit(&ten_info)); + assert_ok!(Identity::request_judgement(RuntimeOrigin::signed(ten.clone()), 0, 10)); + assert_ok!(Identity::cancel_request(RuntimeOrigin::signed(ten.clone()), 0)); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit(&ten_info)); assert_noop!( - Identity::cancel_request(RuntimeOrigin::signed(10), 0), + Identity::cancel_request(RuntimeOrigin::signed(ten.clone()), 0), Error::::NotFound ); assert_ok!(Identity::provide_judgement( - RuntimeOrigin::signed(3), + RuntimeOrigin::signed(three), 0, - 10, + ten.clone(), Judgement::Reasonable, - BlakeTwo256::hash_of(&ten) + BlakeTwo256::hash_of(&ten_info) )); assert_noop!( - Identity::cancel_request(RuntimeOrigin::signed(10), 0), + Identity::cancel_request(RuntimeOrigin::signed(ten), 0), Error::::JudgementGiven ); }); @@ -576,79 +716,87 @@ fn cancelling_requested_judgement_should_work() { #[test] fn requesting_judgement_should_work() { new_test_ext().execute_with(|| { - assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3)); - assert_ok!(Identity::set_fee(RuntimeOrigin::signed(3), 0, 10)); - let ten = ten(); - let id_deposit = id_deposit(&ten); - assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten.clone()))); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit); + let [_, _, three, four, ten, _, _, _] = accounts(); + assert_ok!(Identity::add_registrar(RuntimeOrigin::root(), three.clone())); + assert_ok!(Identity::set_fee(RuntimeOrigin::signed(three.clone()), 0, 10)); + let ten_info = infoof_ten(); + let id_deposit = id_deposit(&ten_info); + assert_ok!(Identity::set_identity( + RuntimeOrigin::signed(ten.clone()), + Box::new(ten_info.clone()) + )); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit); assert_noop!( - Identity::request_judgement(RuntimeOrigin::signed(10), 0, 9), + Identity::request_judgement(RuntimeOrigin::signed(ten.clone()), 0, 9), Error::::FeeChanged ); - assert_ok!(Identity::request_judgement(RuntimeOrigin::signed(10), 0, 10)); + assert_ok!(Identity::request_judgement(RuntimeOrigin::signed(ten.clone()), 0, 10)); // 10 for the judgement request and the deposit for the identity. - assert_eq!(Balances::free_balance(10), 1000 - id_deposit - 10); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit - 10); // Re-requesting won't work as we already paid. assert_noop!( - Identity::request_judgement(RuntimeOrigin::signed(10), 0, 10), + Identity::request_judgement(RuntimeOrigin::signed(ten.clone()), 0, 10), Error::::StickyJudgement ); assert_ok!(Identity::provide_judgement( - RuntimeOrigin::signed(3), + RuntimeOrigin::signed(three.clone()), 0, - 10, + ten.clone(), Judgement::Erroneous, - BlakeTwo256::hash_of(&ten) + BlakeTwo256::hash_of(&ten_info) )); // Registrar got their payment now. // 100 initial balance and 10 for the judgement. - assert_eq!(Balances::free_balance(3), 100 + 10); + assert_eq!(Balances::free_balance(three.clone()), 100 + 10); // Re-requesting still won't work as it's erroneous. assert_noop!( - Identity::request_judgement(RuntimeOrigin::signed(10), 0, 10), + Identity::request_judgement(RuntimeOrigin::signed(ten.clone()), 0, 10), Error::::StickyJudgement ); // Requesting from a second registrar still works. - assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 4)); - assert_ok!(Identity::request_judgement(RuntimeOrigin::signed(10), 1, 10)); + assert_ok!(Identity::add_registrar(RuntimeOrigin::root(), four)); + assert_ok!(Identity::request_judgement(RuntimeOrigin::signed(ten.clone()), 1, 10)); // Re-requesting after the judgement has been reduced works. assert_ok!(Identity::provide_judgement( - RuntimeOrigin::signed(3), + RuntimeOrigin::signed(three), 0, - 10, + ten.clone(), Judgement::OutOfDate, - BlakeTwo256::hash_of(&ten) + BlakeTwo256::hash_of(&ten_info) )); - assert_ok!(Identity::request_judgement(RuntimeOrigin::signed(10), 0, 10)); + assert_ok!(Identity::request_judgement(RuntimeOrigin::signed(ten), 0, 10)); }); } #[test] fn provide_judgement_should_return_judgement_payment_failed_error() { new_test_ext().execute_with(|| { - let ten = ten(); - let id_deposit = id_deposit(&ten); - assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3)); - assert_ok!(Identity::set_fee(RuntimeOrigin::signed(3), 0, 10)); - assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten.clone()))); - assert_ok!(Identity::request_judgement(RuntimeOrigin::signed(10), 0, 10)); + let [_, _, three, _, ten, _, _, _] = accounts(); + let ten_info = infoof_ten(); + let id_deposit = id_deposit(&ten_info); + assert_ok!(Identity::add_registrar(RuntimeOrigin::root(), three.clone())); + assert_ok!(Identity::set_fee(RuntimeOrigin::signed(three.clone()), 0, 10)); + assert_ok!(Identity::set_identity( + RuntimeOrigin::signed(ten.clone()), + Box::new(ten_info.clone()) + )); + assert_ok!(Identity::request_judgement(RuntimeOrigin::signed(ten.clone()), 0, 10)); // 10 for the judgement request and the deposit for the identity. - assert_eq!(Balances::free_balance(10), 1000 - id_deposit - 10); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit - 10); // This forces judgement payment failed error - Balances::make_free_balance_be(&3, 0); + Balances::make_free_balance_be(&three, 0); assert_noop!( Identity::provide_judgement( - RuntimeOrigin::signed(3), + RuntimeOrigin::signed(three.clone()), 0, - 10, + ten.clone(), Judgement::Erroneous, - BlakeTwo256::hash_of(&ten) + BlakeTwo256::hash_of(&ten_info) ), Error::::JudgementPaymentFailed ); @@ -658,8 +806,9 @@ fn provide_judgement_should_return_judgement_payment_failed_error() { #[test] fn field_deposit_should_work() { new_test_ext().execute_with(|| { - assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3)); - assert_ok!(Identity::set_fee(RuntimeOrigin::signed(3), 0, 10)); + let [_, _, three, _, ten, _, _, _] = accounts(); + assert_ok!(Identity::add_registrar(RuntimeOrigin::root(), three.clone())); + assert_ok!(Identity::set_fee(RuntimeOrigin::signed(three), 0, 10)); let id = IdentityInfo { additional: vec![ ( @@ -676,39 +825,44 @@ fn field_deposit_should_work() { ..Default::default() }; let id_deposit = id_deposit(&id); - assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(id))); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit); + assert_ok!(Identity::set_identity(RuntimeOrigin::signed(ten.clone()), Box::new(id))); + assert_eq!(Balances::free_balance(ten), 1000 - id_deposit); }); } #[test] fn setting_account_id_should_work() { new_test_ext().execute_with(|| { - assert_ok!(Identity::add_registrar(RuntimeOrigin::signed(1), 3)); + let [_, _, three, four, _, _, _, _] = accounts(); + assert_ok!(Identity::add_registrar(RuntimeOrigin::root(), three.clone())); // account 4 cannot change the first registrar's identity since it's owned by 3. assert_noop!( - Identity::set_account_id(RuntimeOrigin::signed(4), 0, 3), + Identity::set_account_id(RuntimeOrigin::signed(four.clone()), 0, three.clone()), Error::::InvalidIndex ); // account 3 can, because that's the registrar's current account. - assert_ok!(Identity::set_account_id(RuntimeOrigin::signed(3), 0, 4)); + assert_ok!(Identity::set_account_id(RuntimeOrigin::signed(three.clone()), 0, four.clone())); // account 4 can now, because that's their new ID. - assert_ok!(Identity::set_account_id(RuntimeOrigin::signed(4), 0, 3)); + assert_ok!(Identity::set_account_id(RuntimeOrigin::signed(four), 0, three)); }); } #[test] fn test_has_identity() { new_test_ext().execute_with(|| { - assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten()))); - assert!(Identity::has_identity(&10, IdentityField::Display as u64)); - assert!(Identity::has_identity(&10, IdentityField::Legal as u64)); + let [_, _, _, _, ten, _, _, _] = accounts(); + assert_ok!(Identity::set_identity( + RuntimeOrigin::signed(ten.clone()), + Box::new(infoof_ten()) + )); + assert!(Identity::has_identity(&ten, IdentityField::Display as u64)); + assert!(Identity::has_identity(&ten, IdentityField::Legal as u64)); assert!(Identity::has_identity( - &10, + &ten, IdentityField::Display as u64 | IdentityField::Legal as u64 )); assert!(!Identity::has_identity( - &10, + &ten, IdentityField::Display as u64 | IdentityField::Legal as u64 | IdentityField::Web as u64 )); }); @@ -717,66 +871,759 @@ fn test_has_identity() { #[test] fn reap_identity_works() { new_test_ext().execute_with(|| { - let ten_info = ten(); - assert_ok!(Identity::set_identity(RuntimeOrigin::signed(10), Box::new(ten_info.clone()))); + let [_, _, _, _, ten, twenty, _, _] = accounts(); + let ten_info = infoof_ten(); + assert_ok!(Identity::set_identity( + RuntimeOrigin::signed(ten.clone()), + Box::new(ten_info.clone()) + )); assert_ok!(Identity::set_subs( - RuntimeOrigin::signed(10), - vec![(20, Data::Raw(vec![40; 1].try_into().unwrap()))] + RuntimeOrigin::signed(ten.clone()), + vec![(twenty.clone(), Data::Raw(vec![40; 1].try_into().unwrap()))] )); // deposit is correct let id_deposit = id_deposit(&ten_info); let subs_deposit: u64 = <::SubAccountDeposit as Get>::get(); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit - subs_deposit); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit - subs_deposit); // reap - assert_ok!(Identity::reap_identity(&10)); + assert_ok!(Identity::reap_identity(&ten)); // no identity or subs - assert!(Identity::identity(10).is_none()); - assert!(Identity::super_of(20).is_none()); + assert!(Identity::identity(ten.clone()).is_none()); + assert!(Identity::super_of(twenty).is_none()); // balance is unreserved - assert_eq!(Balances::free_balance(10), 1000); + assert_eq!(Balances::free_balance(ten), 1000); }); } #[test] fn poke_deposit_works() { new_test_ext().execute_with(|| { - let ten_info = ten(); + let [_, _, _, _, ten, twenty, _, _] = accounts(); + let ten_info = infoof_ten(); // Set a custom registration with 0 deposit - IdentityOf::::insert( - &10, - Registration { - judgements: BoundedVec::default(), - deposit: Zero::zero(), - info: ten_info.clone(), - }, - ); - assert!(Identity::identity(10).is_some()); + IdentityOf::::insert::< + _, + ( + Registration>, + Option>, + ), + >( + &ten, + ( + Registration { + judgements: Default::default(), + deposit: Zero::zero(), + info: ten_info.clone(), + }, + None::>, + ), + ); + assert!(Identity::identity(ten.clone()).is_some()); // Set a sub with zero deposit - SubsOf::::insert::<&u64, (u64, BoundedVec>)>( - &10, - (0, vec![20].try_into().unwrap()), + SubsOf::::insert::<_, (u64, BoundedVec, ConstU32<2>>)>( + &ten, + (0, vec![twenty.clone()].try_into().unwrap()), ); - SuperOf::::insert(&20, (&10, Data::Raw(vec![1; 1].try_into().unwrap()))); + SuperOf::::insert(&twenty, (&ten, Data::Raw(vec![1; 1].try_into().unwrap()))); // Balance is free - assert_eq!(Balances::free_balance(10), 1000); + assert_eq!(Balances::free_balance(ten.clone()), 1000); // poke - assert_ok!(Identity::poke_deposit(&10)); + assert_ok!(Identity::poke_deposit(&ten)); // free balance reduced correctly let id_deposit = id_deposit(&ten_info); let subs_deposit: u64 = <::SubAccountDeposit as Get>::get(); - assert_eq!(Balances::free_balance(10), 1000 - id_deposit - subs_deposit); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit - subs_deposit); // new registration deposit is 10 assert_eq!( - Identity::identity(&10), - Some(Registration { - judgements: BoundedVec::default(), - deposit: id_deposit, - info: ten() + Identity::identity(&ten), + Some(( + Registration { + judgements: Default::default(), + deposit: id_deposit, + info: infoof_ten() + }, + None + )) + ); + // new subs deposit is 10 vvvvvvvvvvvv + assert_eq!(Identity::subs_of(ten), (subs_deposit, vec![twenty].try_into().unwrap())); + }); +} + +#[test] +fn adding_and_removing_authorities_should_work() { + new_test_ext().execute_with(|| { + let [authority, _] = unfunded_accounts(); + let suffix: Vec = b"test".to_vec(); + let allocation: u32 = 10; + + // add + assert_ok!(Identity::add_username_authority( + RuntimeOrigin::root(), + authority.clone(), + suffix.clone(), + allocation + )); + assert_eq!( + UsernameAuthorities::::get(&authority), + Some(AuthorityPropertiesOf:: { + suffix: suffix.clone().try_into().unwrap(), + allocation + }) + ); + + // update allocation + assert_ok!(Identity::add_username_authority( + RuntimeOrigin::root(), + authority.clone(), + suffix.clone(), + 11u32 + )); + assert_eq!( + UsernameAuthorities::::get(&authority), + Some(AuthorityPropertiesOf:: { + suffix: suffix.try_into().unwrap(), + allocation: 11 }) ); - // new subs deposit is 10 vvvvvvvvvvvv - assert_eq!(Identity::subs_of(10), (subs_deposit, vec![20].try_into().unwrap())); + + // remove + assert_ok!(Identity::remove_username_authority(RuntimeOrigin::root(), authority.clone(),)); + assert!(UsernameAuthorities::::get(&authority).is_none()); + }); +} + +#[test] +fn set_username_with_signature_without_existing_identity_should_work() { + new_test_ext().execute_with(|| { + // set up authority + let [authority, _] = unfunded_accounts(); + let suffix: Vec = b"test".to_vec(); + let allocation: u32 = 10; + assert_ok!(Identity::add_username_authority( + RuntimeOrigin::root(), + authority.clone(), + suffix.clone(), + allocation + )); + + // set up username + let (username, username_to_sign) = test_username_of(b"42".to_vec(), suffix); + let encoded_username = Encode::encode(&username_to_sign.to_vec()); + + // set up user and sign message + let public = sr25519_generate(0.into(), None); + let who_account: AccountIdOf = MultiSigner::Sr25519(public).into_account().into(); + let signature = + MultiSignature::Sr25519(sr25519_sign(0.into(), &public, &encoded_username).unwrap()); + + assert_ok!(Identity::set_username_for( + RuntimeOrigin::signed(authority), + who_account.clone(), + username.clone(), + Some(signature) + )); + + // Even though user has no balance and no identity, they get a default one for free. + assert_eq!( + Identity::identity(&who_account), + Some(( + Registration { + judgements: Default::default(), + deposit: 0, + info: Default::default() + }, + Some(username_to_sign.clone()) + )) + ); + // Lookup from username to account works. + assert_eq!( + AccountOfUsername::::get::<&Username>(&username_to_sign), + Some(who_account) + ); + }); +} + +#[test] +fn set_username_with_signature_with_existing_identity_should_work() { + new_test_ext().execute_with(|| { + // set up authority + let [authority, _] = unfunded_accounts(); + let suffix: Vec = b"test".to_vec(); + let allocation: u32 = 10; + assert_ok!(Identity::add_username_authority( + RuntimeOrigin::root(), + authority.clone(), + suffix.clone(), + allocation + )); + + // set up username + let (username, username_to_sign) = test_username_of(b"42".to_vec(), suffix); + let encoded_username = Encode::encode(&username_to_sign.to_vec()); + + // set up user and sign message + let public = sr25519_generate(0.into(), None); + let who_account: AccountIdOf = MultiSigner::Sr25519(public).into_account().into(); + let signature = + MultiSignature::Sr25519(sr25519_sign(0.into(), &public, &encoded_username).unwrap()); + + // Set an identity for who. They need some balance though. + Balances::make_free_balance_be(&who_account, 1000); + let ten_info = infoof_ten(); + assert_ok!(Identity::set_identity( + RuntimeOrigin::signed(who_account.clone()), + Box::new(ten_info.clone()) + )); + assert_ok!(Identity::set_username_for( + RuntimeOrigin::signed(authority), + who_account.clone(), + username.clone(), + Some(signature) + )); + + assert_eq!( + Identity::identity(&who_account), + Some(( + Registration { + judgements: Default::default(), + deposit: id_deposit(&ten_info), + info: ten_info + }, + Some(username_to_sign.clone()) + )) + ); + assert_eq!( + AccountOfUsername::::get::<&Username>(&username_to_sign), + Some(who_account) + ); + }); +} + +#[test] +fn set_username_with_bytes_signature_should_work() { + new_test_ext().execute_with(|| { + // set up authority + let [authority, _] = unfunded_accounts(); + let suffix: Vec = b"test".to_vec(); + let allocation: u32 = 10; + assert_ok!(Identity::add_username_authority( + RuntimeOrigin::root(), + authority.clone(), + suffix.clone(), + allocation + )); + + // set up user + let public = sr25519_generate(0.into(), None); + let who_account: AccountIdOf = MultiSigner::Sr25519(public).into_account().into(); + + // set up username + let (username, username_to_sign) = test_username_of(b"42".to_vec(), suffix); + let unwrapped_username = username_to_sign.to_vec(); + + // Sign an unwrapped version, as in `username.suffix`. + let unwrapped_encoded = Encode::encode(&unwrapped_username); + let signature_on_unwrapped = + MultiSignature::Sr25519(sr25519_sign(0.into(), &public, &unwrapped_encoded).unwrap()); + + // Trivial + assert_ok!(Identity::validate_signature( + &unwrapped_encoded, + &signature_on_unwrapped, + &who_account + )); + + // Here we are going to wrap the username and suffix in "" and verify that the + // signature verification still works, but only the username gets set in storage. + let prehtml = b""; + let posthtml = b""; + let mut wrapped_username: Vec = + Vec::with_capacity(unwrapped_username.len() + prehtml.len() + posthtml.len()); + wrapped_username.extend(prehtml); + wrapped_username.extend(unwrapped_encoded.clone()); + wrapped_username.extend(posthtml); + let signature_on_wrapped = + MultiSignature::Sr25519(sr25519_sign(0.into(), &public, &wrapped_username).unwrap()); + + // We want to call `validate_signature` on the *unwrapped* username, but the signature on + // the *wrapped* data. + assert_ok!(Identity::validate_signature( + &unwrapped_encoded, + &signature_on_wrapped, + &who_account + )); + + // Make sure it really works in context. Call `set_username_for` with the signature on the + // wrapped data. + assert_ok!(Identity::set_username_for( + RuntimeOrigin::signed(authority), + who_account.clone(), + username, + Some(signature_on_wrapped) + )); + + // The username in storage should not include ``. As in, it's the original + // `username_to_sign`. + assert_eq!( + Identity::identity(&who_account), + Some(( + Registration { + judgements: Default::default(), + deposit: 0, + info: Default::default() + }, + Some(username_to_sign.clone()) + )) + ); + // Likewise for the lookup. + assert_eq!( + AccountOfUsername::::get::<&Username>(&username_to_sign), + Some(who_account) + ); + }); +} + +#[test] +fn set_username_with_acceptance_should_work() { + new_test_ext().execute_with(|| { + // set up authority + let [authority, who] = unfunded_accounts(); + let suffix: Vec = b"test".to_vec(); + let allocation: u32 = 10; + assert_ok!(Identity::add_username_authority( + RuntimeOrigin::root(), + authority.clone(), + suffix.clone(), + allocation + )); + + // set up username + let (username, full_username) = test_username_of(b"101".to_vec(), suffix); + let now = frame_system::Pallet::::block_number(); + let expiration = now + <::PendingUsernameExpiration as Get>::get(); + + assert_ok!(Identity::set_username_for( + RuntimeOrigin::signed(authority), + who.clone(), + username.clone(), + None + )); + + // Should be pending + assert_eq!( + PendingUsernames::::get::<&Username>(&full_username), + Some((who.clone(), expiration)) + ); + + // Now the user can accept + assert_ok!(Identity::accept_username( + RuntimeOrigin::signed(who.clone()), + full_username.clone() + )); + + // No more pending + assert!(PendingUsernames::::get::<&Username>(&full_username).is_none()); + // Check Identity storage + assert_eq!( + Identity::identity(&who), + Some(( + Registration { + judgements: Default::default(), + deposit: 0, + info: Default::default() + }, + Some(full_username.clone()) + )) + ); + // Check reverse lookup + assert_eq!(AccountOfUsername::::get::<&Username>(&full_username), Some(who)); + }); +} + +#[test] +fn invalid_usernames_should_be_rejected() { + new_test_ext().execute_with(|| { + let [authority, who] = unfunded_accounts(); + let allocation: u32 = 10; + let valid_suffix = b"test".to_vec(); + let invalid_suffixes = [ + b"te.st".to_vec(), // not alphanumeric + b"su:ffx".to_vec(), + b"su_ffx".to_vec(), + b"Suffix".to_vec(), // capital + b"suffixes".to_vec(), // too long + ]; + for suffix in invalid_suffixes { + assert_noop!( + Identity::add_username_authority( + RuntimeOrigin::root(), + authority.clone(), + suffix.clone(), + allocation + ), + Error::::InvalidSuffix + ); + } + + // set a valid one now + assert_ok!(Identity::add_username_authority( + RuntimeOrigin::root(), + authority.clone(), + valid_suffix, + allocation + )); + + // set up usernames + let invalid_usernames = [ + b"TestUsername".to_vec(), + b"test_username".to_vec(), + b"test-username".to_vec(), + b"test:username".to_vec(), + b"test.username".to_vec(), + b"test@username".to_vec(), + b"test$username".to_vec(), + //0 1 2 v With `.test` this makes it too long. + b"testusernametestusernametest".to_vec(), + ]; + for username in invalid_usernames { + assert_noop!( + Identity::set_username_for( + RuntimeOrigin::signed(authority.clone()), + who.clone(), + username.clone(), + None + ), + Error::::InvalidUsername + ); + } + + // valid one works + let valid_username = b"testusernametestusernametes".to_vec(); + assert_ok!(Identity::set_username_for( + RuntimeOrigin::signed(authority), + who, + valid_username, + None + )); + }); +} + +#[test] +fn authorities_should_run_out_of_allocation() { + new_test_ext().execute_with(|| { + // set up authority + let [authority, _] = unfunded_accounts(); + let [pi, e, c, _, _, _, _, _] = accounts(); + let suffix: Vec = b"test".to_vec(); + let allocation: u32 = 2; + assert_ok!(Identity::add_username_authority( + RuntimeOrigin::root(), + authority.clone(), + suffix.clone(), + allocation + )); + + assert_ok!(Identity::set_username_for( + RuntimeOrigin::signed(authority.clone()), + pi, + b"username314159".to_vec(), + None + )); + assert_ok!(Identity::set_username_for( + RuntimeOrigin::signed(authority.clone()), + e, + b"username271828".to_vec(), + None + )); + assert_noop!( + Identity::set_username_for( + RuntimeOrigin::signed(authority.clone()), + c, + b"username299792458".to_vec(), + None + ), + Error::::NoAllocation + ); + }); +} + +#[test] +fn setting_primary_should_work() { + new_test_ext().execute_with(|| { + // set up authority + let [authority, _] = unfunded_accounts(); + let suffix: Vec = b"test".to_vec(); + let allocation: u32 = 10; + assert_ok!(Identity::add_username_authority( + RuntimeOrigin::root(), + authority.clone(), + suffix.clone(), + allocation + )); + + // set up user + let public = sr25519_generate(0.into(), None); + let who_account: AccountIdOf = MultiSigner::Sr25519(public).into_account().into(); + + // set up username + let (first_username, first_to_sign) = test_username_of(b"42".to_vec(), suffix.clone()); + let encoded_username = Encode::encode(&first_to_sign.to_vec()); + let first_signature = + MultiSignature::Sr25519(sr25519_sign(0.into(), &public, &encoded_username).unwrap()); + + assert_ok!(Identity::set_username_for( + RuntimeOrigin::signed(authority.clone()), + who_account.clone(), + first_username.clone(), + Some(first_signature) + )); + + // First username set as primary. + assert_eq!( + Identity::identity(&who_account), + Some(( + Registration { + judgements: Default::default(), + deposit: 0, + info: Default::default() + }, + Some(first_to_sign.clone()) + )) + ); + + // set up username + let (second_username, second_to_sign) = test_username_of(b"101".to_vec(), suffix); + let encoded_username = Encode::encode(&second_to_sign.to_vec()); + let second_signature = + MultiSignature::Sr25519(sr25519_sign(0.into(), &public, &encoded_username).unwrap()); + + assert_ok!(Identity::set_username_for( + RuntimeOrigin::signed(authority), + who_account.clone(), + second_username.clone(), + Some(second_signature) + )); + + // The primary is still the first username. + assert_eq!( + Identity::identity(&who_account), + Some(( + Registration { + judgements: Default::default(), + deposit: 0, + info: Default::default() + }, + Some(first_to_sign.clone()) + )) + ); + + // Lookup from both works. + assert_eq!( + AccountOfUsername::::get::<&Username>(&first_to_sign), + Some(who_account.clone()) + ); + assert_eq!( + AccountOfUsername::::get::<&Username>(&second_to_sign), + Some(who_account.clone()) + ); + + assert_ok!(Identity::set_primary_username( + RuntimeOrigin::signed(who_account.clone()), + second_to_sign.clone() + )); + + // The primary is now the second username. + assert_eq!( + Identity::identity(&who_account), + Some(( + Registration { + judgements: Default::default(), + deposit: 0, + info: Default::default() + }, + Some(second_to_sign.clone()) + )) + ); + + // Lookup from both still works. + assert_eq!( + AccountOfUsername::::get::<&Username>(&first_to_sign), + Some(who_account.clone()) + ); + assert_eq!( + AccountOfUsername::::get::<&Username>(&second_to_sign), + Some(who_account) + ); + }); +} + +#[test] +fn unaccepted_usernames_should_expire() { + new_test_ext().execute_with(|| { + // set up authority + let [authority, who] = unfunded_accounts(); + let suffix: Vec = b"test".to_vec(); + let allocation: u32 = 10; + assert_ok!(Identity::add_username_authority( + RuntimeOrigin::root(), + authority.clone(), + suffix.clone(), + allocation + )); + + // set up username + let (username, full_username) = test_username_of(b"101".to_vec(), suffix); + let now = frame_system::Pallet::::block_number(); + let expiration = now + <::PendingUsernameExpiration as Get>::get(); + + assert_ok!(Identity::set_username_for( + RuntimeOrigin::signed(authority), + who.clone(), + username.clone(), + None + )); + + // Should be pending + assert_eq!( + PendingUsernames::::get::<&Username>(&full_username), + Some((who.clone(), expiration)) + ); + + run_to_block(now + expiration - 1); + + // Cannot be removed + assert_noop!( + Identity::remove_expired_approval( + RuntimeOrigin::signed(account(1)), + full_username.clone() + ), + Error::::NotExpired + ); + + run_to_block(now + expiration); + + // Anyone can remove + assert_ok!(Identity::remove_expired_approval( + RuntimeOrigin::signed(account(1)), + full_username.clone() + )); + + // No more pending + assert!(PendingUsernames::::get::<&Username>(&full_username).is_none()); + }); +} + +#[test] +fn removing_dangling_usernames_should_work() { + new_test_ext().execute_with(|| { + // set up authority + let [authority, caller] = unfunded_accounts(); + let suffix: Vec = b"test".to_vec(); + let allocation: u32 = 10; + assert_ok!(Identity::add_username_authority( + RuntimeOrigin::root(), + authority.clone(), + suffix.clone(), + allocation + )); + + // set up username + let (username, username_to_sign) = test_username_of(b"42".to_vec(), suffix.clone()); + let encoded_username = Encode::encode(&username_to_sign.to_vec()); + + // set up user and sign message + let public = sr25519_generate(0.into(), None); + let who_account: AccountIdOf = MultiSigner::Sr25519(public).into_account().into(); + let signature = + MultiSignature::Sr25519(sr25519_sign(0.into(), &public, &encoded_username).unwrap()); + + // Set an identity for who. They need some balance though. + Balances::make_free_balance_be(&who_account, 1000); + let ten_info = infoof_ten(); + assert_ok!(Identity::set_identity( + RuntimeOrigin::signed(who_account.clone()), + Box::new(ten_info.clone()) + )); + assert_ok!(Identity::set_username_for( + RuntimeOrigin::signed(authority.clone()), + who_account.clone(), + username.clone(), + Some(signature) + )); + + // Now they set up a second username. + let (username_two, username_two_to_sign) = test_username_of(b"43".to_vec(), suffix); + let encoded_username_two = Encode::encode(&username_two_to_sign.to_vec()); + + // set up user and sign message + let signature_two = MultiSignature::Sr25519( + sr25519_sign(0.into(), &public, &encoded_username_two).unwrap(), + ); + + assert_ok!(Identity::set_username_for( + RuntimeOrigin::signed(authority), + who_account.clone(), + username_two.clone(), + Some(signature_two) + )); + + // The primary should still be the first one. + assert_eq!( + Identity::identity(&who_account), + Some(( + Registration { + judgements: Default::default(), + deposit: id_deposit(&ten_info), + info: ten_info + }, + Some(username_to_sign.clone()) + )) + ); + + // But both usernames should look up the account. + assert_eq!( + AccountOfUsername::::get::<&Username>(&username_to_sign), + Some(who_account.clone()) + ); + assert_eq!( + AccountOfUsername::::get::<&Username>(&username_two_to_sign), + Some(who_account.clone()) + ); + + // Someone tries to remove it, but they can't + assert_noop!( + Identity::remove_dangling_username( + RuntimeOrigin::signed(caller.clone()), + username_to_sign.clone() + ), + Error::::InvalidUsername + ); + + // Now the user calls `clear_identity` + assert_ok!(Identity::clear_identity(RuntimeOrigin::signed(who_account.clone()),)); + + // Identity is gone + assert!(Identity::identity(who_account.clone()).is_none()); + + // The reverse lookup of the primary is gone. + assert!(AccountOfUsername::::get::<&Username>(&username_to_sign).is_none()); + + // But the reverse lookup of the non-primary is still there + assert_eq!( + AccountOfUsername::::get::<&Username>(&username_two_to_sign), + Some(who_account) + ); + + // Now it can be removed + assert_ok!(Identity::remove_dangling_username( + RuntimeOrigin::signed(caller), + username_two_to_sign.clone() + )); + + // And the reverse lookup is gone + assert!(AccountOfUsername::::get::<&Username>(&username_two_to_sign).is_none()); }); } diff --git a/substrate/frame/identity/src/types.rs b/substrate/frame/identity/src/types.rs index d3e6bf3973f..10f0db8c25d 100644 --- a/substrate/frame/identity/src/types.rs +++ b/substrate/frame/identity/src/types.rs @@ -232,7 +232,7 @@ impl = AuthorityProperties>; + +/// The number of usernames that an authority may allocate. +type Allocation = u32; +/// A byte vec used to represent a username. +pub(crate) type Suffix = BoundedVec::MaxSuffixLength>; + +/// Properties of a username authority. +#[derive(Clone, Encode, Decode, MaxEncodedLen, TypeInfo, PartialEq, Debug)] +pub struct AuthorityProperties { + /// The suffix added to usernames granted by this authority. Will be appended to usernames; for + /// example, a suffix of `wallet` will result in `.wallet` being appended to a user's selected + /// name. + pub suffix: Suffix, + /// The number of usernames remaining that this authority can grant. + pub allocation: Allocation, +} + +/// A byte vec used to represent a username. +pub(crate) type Username = BoundedVec::MaxUsernameLength>; + #[cfg(test)] mod tests { use super::*; diff --git a/substrate/frame/identity/src/weights.rs b/substrate/frame/identity/src/weights.rs index 95898e6c6cd..1feb8252c84 100644 --- a/substrate/frame/identity/src/weights.rs +++ b/substrate/frame/identity/src/weights.rs @@ -68,6 +68,13 @@ pub trait WeightInfo { fn rename_sub(s: u32, ) -> Weight; fn remove_sub(s: u32, ) -> Weight; fn quit_sub(s: u32, ) -> Weight; + fn add_username_authority() -> Weight; + fn remove_username_authority() -> Weight; + fn set_username_for() -> Weight; + fn accept_username() -> Weight; + fn remove_expired_approval() -> Weight; + fn set_primary_username() -> Weight; + fn remove_dangling_username() -> Weight; } /// Weights for pallet_identity using the Substrate node and recommended hardware. @@ -345,6 +352,100 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } + /// Storage: `Identity::UsernameAuthorities` (r:0 w:1) + /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + fn add_username_authority() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_873_000 picoseconds. + Weight::from_parts(13_873_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::UsernameAuthorities` (r:0 w:1) + /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + fn remove_username_authority() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 10_653_000 picoseconds. + Weight::from_parts(10_653_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::UsernameAuthorities` (r:1 w:1) + /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `Identity::AccountOfUsername` (r:1 w:1) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + fn set_username_for() -> Weight { + // Proof Size summary in bytes: + // Measured: `80` + // Estimated: `11037` + // Minimum execution time: 75_928_000 picoseconds. + Weight::from_parts(75_928_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Identity::PendingUsernames` (r:1 w:1) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::AccountOfUsername` (r:0 w:1) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + fn accept_username() -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `11037` + // Minimum execution time: 38_157_000 picoseconds. + Weight::from_parts(38_157_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Identity::PendingUsernames` (r:1 w:1) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) + fn remove_expired_approval() -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `3542` + // Minimum execution time: 46_821_000 picoseconds. + Weight::from_parts(46_821_000, 0) + .saturating_add(Weight::from_parts(0, 3542)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::AccountOfUsername` (r:1 w:0) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + fn set_primary_username() -> Weight { + // Proof Size summary in bytes: + // Measured: `247` + // Estimated: `11037` + // Minimum execution time: 22_515_000 picoseconds. + Weight::from_parts(22_515_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Identity::AccountOfUsername` (r:1 w:1) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + fn remove_dangling_username() -> Weight { + // Proof Size summary in bytes: + // Measured: `126` + // Estimated: `11037` + // Minimum execution time: 15_997_000 picoseconds. + Weight::from_parts(15_997_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } } // For backwards compatibility and tests @@ -621,4 +722,98 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } + /// Storage: `Identity::UsernameAuthorities` (r:0 w:1) + /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + fn add_username_authority() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_873_000 picoseconds. + Weight::from_parts(13_873_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + /// Storage: `Identity::UsernameAuthorities` (r:0 w:1) + /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + fn remove_username_authority() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 10_653_000 picoseconds. + Weight::from_parts(10_653_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + /// Storage: `Identity::UsernameAuthorities` (r:1 w:1) + /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `Identity::AccountOfUsername` (r:1 w:1) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + fn set_username_for() -> Weight { + // Proof Size summary in bytes: + // Measured: `80` + // Estimated: `11037` + // Minimum execution time: 75_928_000 picoseconds. + Weight::from_parts(75_928_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(3)) + } + /// Storage: `Identity::PendingUsernames` (r:1 w:1) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::AccountOfUsername` (r:0 w:1) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + fn accept_username() -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `11037` + // Minimum execution time: 38_157_000 picoseconds. + Weight::from_parts(38_157_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(3)) + } + /// Storage: `Identity::PendingUsernames` (r:1 w:1) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) + fn remove_expired_approval() -> Weight { + // Proof Size summary in bytes: + // Measured: `106` + // Estimated: `3542` + // Minimum execution time: 46_821_000 picoseconds. + Weight::from_parts(46_821_000, 0) + .saturating_add(Weight::from_parts(0, 3542)) + .saturating_add(RocksDbWeight::get().reads(1)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + /// Storage: `Identity::AccountOfUsername` (r:1 w:0) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + fn set_primary_username() -> Weight { + // Proof Size summary in bytes: + // Measured: `247` + // Estimated: `11037` + // Minimum execution time: 22_515_000 picoseconds. + Weight::from_parts(22_515_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + /// Storage: `Identity::AccountOfUsername` (r:1 w:1) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + fn remove_dangling_username() -> Weight { + // Proof Size summary in bytes: + // Measured: `126` + // Estimated: `11037` + // Minimum execution time: 15_997_000 picoseconds. + Weight::from_parts(15_997_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(1)) + } } -- GitLab From ccd55552a85ae45227abf7e0a4aee803b707229c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 11:07:29 +0000 Subject: [PATCH 026/392] Bump parking_lot from 0.11.2 to 0.12.1 (#2901) Bumps [parking_lot](https://github.com/Amanieu/parking_lot) from 0.11.2 to 0.12.1.
Changelog

Sourced from parking_lot's changelog.

parking_lot 0.12.1 (2022-05-31)

  • Fixed incorrect memory ordering in RwLock. (#344)
  • Added Condvar::wait_while convenience methods (#343)

parking_lot_core 0.9.3 (2022-04-30)

  • Bump windows-sys dependency to 0.36. (#339)

parking_lot_core 0.9.2, lock_api 0.4.7 (2022-03-25)

  • Enable const new() on lock types on stable. (#325)
  • Added MutexGuard::leak function. (#333)
  • Bump windows-sys dependency to 0.34. (#331)
  • Bump petgraph dependency to 0.6. (#326)
  • Don't use pthread attributes on the espidf platform. (#319)

parking_lot_core 0.9.1 (2022-02-06)

  • Bump windows-sys dependency to 0.32. (#316)

parking_lot 0.12.0, parking_lot_core 0.9.0, lock_api 0.4.6 (2022-01-28)

  • The MSRV is bumped to 1.49.0.
  • Disabled eventual fairness on wasm32-unknown-unknown. (#302)
  • Added a rwlock method to report if lock is held exclusively. (#303)
  • Use new asm! macro. (#304)
  • Use windows-rs instead of winapi for faster builds. (#311)
  • Moved hardware lock elision support to a separate Cargo feature. (#313)
  • Removed used of deprecated spin_loop_hint. (#314)
Commits
  • 336a9b3 Release parking_lot 0.12.1
  • b69a054 Merge pull request #343 from bryanhitc/master
  • 3fe7233 Merge pull request #344 from Amanieu/fix_rwlock_ordering
  • ef12b00 small test update
  • fdb063c wait_while can't timeout fix
  • 26e19dc Remove WaitWhileResult
  • d26c284 Fix incorrect memory ordering in RwLock
  • 0458283 Use saturating_add for WaitWhileResult
  • 686db47 Add Condvar::wait_while convenience methods
  • 6f6e021 Merge pull request #342 from MarijnS95/patch-1
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=parking_lot&package-manager=cargo&previous-version=0.11.2&new-version=0.12.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 2 +- polkadot/node/core/approval-voting/Cargo.toml | 2 +- polkadot/node/core/av-store/Cargo.toml | 2 +- polkadot/node/core/chain-selection/Cargo.toml | 2 +- polkadot/node/jaeger/Cargo.toml | 2 +- polkadot/node/network/bridge/Cargo.toml | 2 +- polkadot/node/overseer/Cargo.toml | 2 +- polkadot/node/subsystem-test-helpers/Cargo.toml | 2 +- polkadot/node/subsystem-util/Cargo.toml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 924aeb7848c..59734f77c34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12985,7 +12985,7 @@ dependencies = [ "log", "parity-db", "parity-scale-codec", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "pin-project", "polkadot-node-jaeger", "polkadot-node-metrics", diff --git a/polkadot/node/core/approval-voting/Cargo.toml b/polkadot/node/core/approval-voting/Cargo.toml index 5fbcec50cd3..0be0cfdea25 100644 --- a/polkadot/node/core/approval-voting/Cargo.toml +++ b/polkadot/node/core/approval-voting/Cargo.toml @@ -42,7 +42,7 @@ rand = "0.8.5" [dev-dependencies] async-trait = "0.1.74" -parking_lot = "0.12.0" +parking_lot = "0.12.1" sp-keyring = { path = "../../../../substrate/primitives/keyring" } sp-keystore = { path = "../../../../substrate/primitives/keystore" } sp-core = { path = "../../../../substrate/primitives/core" } diff --git a/polkadot/node/core/av-store/Cargo.toml b/polkadot/node/core/av-store/Cargo.toml index 4b2baf3fc55..e56fb4f1cdf 100644 --- a/polkadot/node/core/av-store/Cargo.toml +++ b/polkadot/node/core/av-store/Cargo.toml @@ -37,5 +37,5 @@ sp-core = { path = "../../../../substrate/primitives/core" } polkadot-node-subsystem-util = { path = "../../subsystem-util" } polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } sp-keyring = { path = "../../../../substrate/primitives/keyring" } -parking_lot = "0.12.0" +parking_lot = "0.12.1" test-helpers = { package = "polkadot-primitives-test-helpers", path = "../../../primitives/test-helpers" } diff --git a/polkadot/node/core/chain-selection/Cargo.toml b/polkadot/node/core/chain-selection/Cargo.toml index 6056ddd41cd..8e7029876cf 100644 --- a/polkadot/node/core/chain-selection/Cargo.toml +++ b/polkadot/node/core/chain-selection/Cargo.toml @@ -24,6 +24,6 @@ parity-scale-codec = "3.6.1" [dev-dependencies] polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } sp-core = { path = "../../../../substrate/primitives/core" } -parking_lot = "0.12.0" +parking_lot = "0.12.1" assert_matches = "1" kvdb-memorydb = "0.13.0" diff --git a/polkadot/node/jaeger/Cargo.toml b/polkadot/node/jaeger/Cargo.toml index 81947f4f6a4..58fb983c84a 100644 --- a/polkadot/node/jaeger/Cargo.toml +++ b/polkadot/node/jaeger/Cargo.toml @@ -12,7 +12,7 @@ workspace = true [dependencies] mick-jaeger = "0.1.8" lazy_static = "1.4" -parking_lot = "0.12.0" +parking_lot = "0.12.1" polkadot-primitives = { path = "../../primitives" } polkadot-node-primitives = { path = "../primitives" } sc-network = { path = "../../../substrate/client/network" } diff --git a/polkadot/node/network/bridge/Cargo.toml b/polkadot/node/network/bridge/Cargo.toml index a2a4735d7a1..ee4033b0099 100644 --- a/polkadot/node/network/bridge/Cargo.toml +++ b/polkadot/node/network/bridge/Cargo.toml @@ -22,7 +22,7 @@ polkadot-node-metrics = { path = "../../metrics" } polkadot-node-network-protocol = { path = "../protocol" } polkadot-node-subsystem = { path = "../../subsystem" } polkadot-overseer = { path = "../../overseer" } -parking_lot = "0.12.0" +parking_lot = "0.12.1" bytes = "1" fatality = "0.0.6" thiserror = "1" diff --git a/polkadot/node/overseer/Cargo.toml b/polkadot/node/overseer/Cargo.toml index 132a2ed4832..f168bdd0807 100644 --- a/polkadot/node/overseer/Cargo.toml +++ b/polkadot/node/overseer/Cargo.toml @@ -14,7 +14,7 @@ client = { package = "sc-client-api", path = "../../../substrate/client/api" } sp-api = { path = "../../../substrate/primitives/api" } futures = "0.3.21" futures-timer = "3.0.2" -parking_lot = "0.12.0" +parking_lot = "0.12.1" polkadot-node-network-protocol = { path = "../network/protocol" } polkadot-node-primitives = { path = "../primitives" } polkadot-node-subsystem-types = { path = "../subsystem-types" } diff --git a/polkadot/node/subsystem-test-helpers/Cargo.toml b/polkadot/node/subsystem-test-helpers/Cargo.toml index d0be9af4ed6..c71f030568d 100644 --- a/polkadot/node/subsystem-test-helpers/Cargo.toml +++ b/polkadot/node/subsystem-test-helpers/Cargo.toml @@ -13,7 +13,7 @@ workspace = true [dependencies] async-trait = "0.1.74" futures = "0.3.21" -parking_lot = "0.12.0" +parking_lot = "0.12.1" polkadot-node-subsystem = { path = "../subsystem" } polkadot-erasure-coding = { path = "../../erasure-coding" } polkadot-node-subsystem-util = { path = "../subsystem-util" } diff --git a/polkadot/node/subsystem-util/Cargo.toml b/polkadot/node/subsystem-util/Cargo.toml index 6668430d3b7..3147a4f64f4 100644 --- a/polkadot/node/subsystem-util/Cargo.toml +++ b/polkadot/node/subsystem-util/Cargo.toml @@ -15,7 +15,7 @@ futures = "0.3.21" futures-channel = "0.3.23" itertools = "0.10" parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } -parking_lot = "0.11.2" +parking_lot = "0.12.1" pin-project = "1.0.9" rand = "0.8.5" thiserror = "1.0.48" -- GitLab From a56ad80a38cd44f030e04fd0d8883093980f41e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 11:16:49 +0000 Subject: [PATCH 027/392] Bump trybuild from 1.0.83 to 1.0.88 (#2902) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.83 to 1.0.88.
Release notes

Sourced from trybuild's releases.

1.0.88

  • Work around dead_code warning false positive (#253)

1.0.87

  • Update proc-macro2 to fix caching issue when using a rustc-wrapper such as sccache

1.0.86

1.0.85

  • Set thread name to produce better message on panic (#243, #244)

1.0.84

  • Stabilize usage of Cargo's --keep-going build mode, which parallelizes test compilation for a significant speedup (rust-lang/cargo#12568, #240)
Commits
  • 52caff6 Release 1.0.88
  • 0321a01 Merge pull request #253 from dtolnay/deadflock
  • b720ee6 Work around dead_code warning in flock implementation
  • 0081291 Release 1.0.87
  • e0c4c0d Pull in proc-macro2 sccache fix
  • a6cbfe8 Release 1.0.86
  • 7c5a8fe Merge pull request #252 from dtolnay/cargofeatures
  • d3cd15b Propagate cargo features from source manifest
  • c28428d Merge pull request #251 from dtolnay/skipcargofeatures
  • 3e4029e Omit cargo-features from generated Cargo.toml if empty
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=trybuild&package-manager=cargo&previous-version=1.0.83&new-version=1.0.88)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- polkadot/xcm/procedural/Cargo.toml | 2 +- .../election-provider-support/solution-type/Cargo.toml | 2 +- substrate/frame/support/test/Cargo.toml | 2 +- substrate/primitives/api/test/Cargo.toml | 2 +- substrate/primitives/runtime-interface/Cargo.toml | 2 +- substrate/test-utils/Cargo.toml | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 59734f77c34..3ad73feb5d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1371,9 +1371,9 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "basic-toml" -version = "0.1.4" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bfc506e7a2370ec239e1d072507b2a80c833083699d3c6fa176fbb4de8448c6" +checksum = "2db21524cad41c5591204d22d75e1970a2d1f71060214ca931dc7d5afe2c14e5" dependencies = [ "serde", ] @@ -20661,9 +20661,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.83" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6df60d81823ed9c520ee897489573da4b1d79ffbe006b8134f46de1a1aa03555" +checksum = "76de4f783e610194f6c98bfd53f9fc52bb2e0d02c947621e8a0f4ecc799b2880" dependencies = [ "basic-toml", "dissimilar", diff --git a/polkadot/xcm/procedural/Cargo.toml b/polkadot/xcm/procedural/Cargo.toml index 74990f873ab..e88f4b0c846 100644 --- a/polkadot/xcm/procedural/Cargo.toml +++ b/polkadot/xcm/procedural/Cargo.toml @@ -20,5 +20,5 @@ syn = "2.0.48" Inflector = "0.11.4" [dev-dependencies] -trybuild = { version = "1.0.74", features = ["diff"] } +trybuild = { version = "1.0.88", features = ["diff"] } xcm = { package = "staging-xcm", path = ".." } diff --git a/substrate/frame/election-provider-support/solution-type/Cargo.toml b/substrate/frame/election-provider-support/solution-type/Cargo.toml index 04400147790..508c049e490 100644 --- a/substrate/frame/election-provider-support/solution-type/Cargo.toml +++ b/substrate/frame/election-provider-support/solution-type/Cargo.toml @@ -30,4 +30,4 @@ sp-arithmetic = { path = "../../../primitives/arithmetic" } # used by generate_solution_type: frame-election-provider-support = { path = ".." } frame-support = { path = "../../support" } -trybuild = "1.0.74" +trybuild = "1.0.88" diff --git a/substrate/frame/support/test/Cargo.toml b/substrate/frame/support/test/Cargo.toml index eac2dafbf00..8b61f25f569 100644 --- a/substrate/frame/support/test/Cargo.toml +++ b/substrate/frame/support/test/Cargo.toml @@ -31,7 +31,7 @@ sp-core = { path = "../../../primitives/core", default-features = false } sp-std = { path = "../../../primitives/std", default-features = false } sp-version = { path = "../../../primitives/version", default-features = false } sp-metadata-ir = { path = "../../../primitives/metadata-ir", default-features = false } -trybuild = { version = "1.0.74", features = ["diff"] } +trybuild = { version = "1.0.88", features = ["diff"] } pretty_assertions = "1.3.0" rustversion = "1.0.6" frame-system = { path = "../../system", default-features = false } diff --git a/substrate/primitives/api/test/Cargo.toml b/substrate/primitives/api/test/Cargo.toml index 0346ad270ab..b0975082c44 100644 --- a/substrate/primitives/api/test/Cargo.toml +++ b/substrate/primitives/api/test/Cargo.toml @@ -24,7 +24,7 @@ sp-consensus = { path = "../../consensus/common" } sc-block-builder = { path = "../../../client/block-builder" } codec = { package = "parity-scale-codec", version = "3.6.1" } sp-state-machine = { path = "../../state-machine" } -trybuild = "1.0.74" +trybuild = "1.0.88" rustversion = "1.0.6" scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } diff --git a/substrate/primitives/runtime-interface/Cargo.toml b/substrate/primitives/runtime-interface/Cargo.toml index a4c8457b598..0fa2d1f3276 100644 --- a/substrate/primitives/runtime-interface/Cargo.toml +++ b/substrate/primitives/runtime-interface/Cargo.toml @@ -35,7 +35,7 @@ sp-state-machine = { path = "../state-machine" } sp-core = { path = "../core" } sp-io = { path = "../io" } rustversion = "1.0.6" -trybuild = "1.0.74" +trybuild = "1.0.88" [features] default = ["std"] diff --git a/substrate/test-utils/Cargo.toml b/substrate/test-utils/Cargo.toml index 526ed7c049c..af8b01cdef0 100644 --- a/substrate/test-utils/Cargo.toml +++ b/substrate/test-utils/Cargo.toml @@ -20,5 +20,5 @@ futures = "0.3.16" tokio = { version = "1.22.0", features = ["macros", "time"] } [dev-dependencies] -trybuild = { version = "1.0.74", features = ["diff"] } +trybuild = { version = "1.0.88", features = ["diff"] } sc-service = { path = "../client/service" } -- GitLab From af2e30e383b48302441f063929d4e69959db9830 Mon Sep 17 00:00:00 2001 From: Nazar Mokrynskyi Date: Wed, 10 Jan 2024 13:56:44 +0200 Subject: [PATCH 028/392] Improve storage monitor API (#2899) This removes the need to unnecessarily provide a very specific data structure `DatabaseSource` and removes huge `sc-client-db` dependency from storage monitor. It is now possible to use storage monitor with any path. P.S. I still strongly dislike that it pulls `clap` dependency for such a small feature, but many other crates do as well, so nothing special here. --- Cargo.lock | 1 - polkadot/cli/src/command.rs | 12 ++-- prdoc/pr_2899.prdoc | 10 ++++ substrate/bin/node/cli/src/service.rs | 18 +++--- substrate/client/storage-monitor/Cargo.toml | 3 +- substrate/client/storage-monitor/src/lib.rs | 61 +++++++++------------ 6 files changed, 55 insertions(+), 50 deletions(-) create mode 100644 prdoc/pr_2899.prdoc diff --git a/Cargo.lock b/Cargo.lock index 3ad73feb5d5..e00c173228f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16587,7 +16587,6 @@ dependencies = [ "clap 4.4.14", "fs4", "log", - "sc-client-db", "sp-core", "thiserror", "tokio", diff --git a/polkadot/cli/src/command.rs b/polkadot/cli/src/command.rs index 9290ec584e4..1e25f6533f0 100644 --- a/polkadot/cli/src/command.rs +++ b/polkadot/cli/src/command.rs @@ -256,11 +256,13 @@ where ) .map(|full| full.task_manager)?; - sc_storage_monitor::StorageMonitorService::try_spawn( - cli.storage_monitor, - database_source, - &task_manager.spawn_essential_handle(), - )?; + if let Some(path) = database_source.path() { + sc_storage_monitor::StorageMonitorService::try_spawn( + cli.storage_monitor, + path.to_path_buf(), + &task_manager.spawn_essential_handle(), + )?; + } Ok(task_manager) }) diff --git a/prdoc/pr_2899.prdoc b/prdoc/pr_2899.prdoc new file mode 100644 index 00000000000..0c7afc0ad08 --- /dev/null +++ b/prdoc/pr_2899.prdoc @@ -0,0 +1,10 @@ +title: Improve storage monitor API + +doc: + - audience: Node Dev + description: | + This removes the need to unnecessarily provide a very specific data structure DatabaseSource and removes huge + sc-client-db dependency from storage monitor. It is now possible to use storage monitor with any path. + +crates: + - name: sc-storage-monitor diff --git a/substrate/bin/node/cli/src/service.rs b/substrate/bin/node/cli/src/service.rs index 5e6e794f732..67d21ee69ed 100644 --- a/substrate/bin/node/cli/src/service.rs +++ b/substrate/bin/node/cli/src/service.rs @@ -38,7 +38,7 @@ use sc_transaction_pool_api::OffchainTransactionPoolFactory; use sp_api::ProvideRuntimeApi; use sp_core::crypto::Pair; use sp_runtime::{generic, traits::Block as BlockT, SaturatedConversion}; -use std::sync::Arc; +use std::{path::Path, sync::Arc}; /// Host functions required for kitchensink runtime and Substrate node. #[cfg(not(feature = "runtime-benchmarks"))] @@ -769,16 +769,18 @@ pub fn new_full_base( /// Builds a new service for a full client. pub fn new_full(config: Configuration, cli: Cli) -> Result { let mixnet_config = cli.mixnet_params.config(config.role.is_authority()); - let database_source = config.database.clone(); + let database_path = config.database.path().map(Path::to_path_buf); let task_manager = new_full_base(config, mixnet_config, cli.no_hardware_benchmarks, |_, _| ()) .map(|NewFullBase { task_manager, .. }| task_manager)?; - sc_storage_monitor::StorageMonitorService::try_spawn( - cli.storage_monitor, - database_source, - &task_manager.spawn_essential_handle(), - ) - .map_err(|e| ServiceError::Application(e.into()))?; + if let Some(database_path) = database_path { + sc_storage_monitor::StorageMonitorService::try_spawn( + cli.storage_monitor, + database_path, + &task_manager.spawn_essential_handle(), + ) + .map_err(|e| ServiceError::Application(e.into()))?; + } Ok(task_manager) } diff --git a/substrate/client/storage-monitor/Cargo.toml b/substrate/client/storage-monitor/Cargo.toml index 2b46ccbcdc1..7185c62e276 100644 --- a/substrate/client/storage-monitor/Cargo.toml +++ b/substrate/client/storage-monitor/Cargo.toml @@ -15,7 +15,6 @@ workspace = true clap = { version = "4.4.14", features = ["derive", "string"] } log = "0.4.17" fs4 = "0.7.0" -sc-client-db = { path = "../db", default-features = false } sp-core = { path = "../../primitives/core" } -tokio = "1.22.0" +tokio = { version = "1.22.0", features = ["time"] } thiserror = "1.0.48" diff --git a/substrate/client/storage-monitor/src/lib.rs b/substrate/client/storage-monitor/src/lib.rs index b88b66d2d60..28d9063e5e4 100644 --- a/substrate/client/storage-monitor/src/lib.rs +++ b/substrate/client/storage-monitor/src/lib.rs @@ -17,7 +17,6 @@ // along with this program. If not, see . use clap::Args; -use sc_client_db::DatabaseSource; use sp_core::traits::SpawnEssentialNamed; use std::{ io, @@ -70,43 +69,37 @@ impl StorageMonitorService { /// Creates new StorageMonitorService for given client config pub fn try_spawn( parameters: StorageMonitorParams, - database: DatabaseSource, + path: PathBuf, spawner: &impl SpawnEssentialNamed, ) -> Result<()> { - Ok(match (parameters.threshold, database.path()) { - (0, _) => { - log::info!( - target: LOG_TARGET, - "StorageMonitorService: threshold `0` given, storage monitoring disabled", - ); - }, - (_, None) => { - log::warn!( - target: LOG_TARGET, - "StorageMonitorService: no database path to observe", - ); - }, - (threshold, Some(path)) => { - log::debug!( - target: LOG_TARGET, - "Initializing StorageMonitorService for db path: {path:?}", - ); - - Self::check_free_space(&path, threshold)?; + if parameters.threshold == 0 { + log::info!( + target: LOG_TARGET, + "StorageMonitorService: threshold `0` given, storage monitoring disabled", + ); + } else { + log::debug!( + target: LOG_TARGET, + "Initializing StorageMonitorService for db path: {}", + path.display() + ); + + Self::check_free_space(&path, parameters.threshold)?; + + let storage_monitor_service = StorageMonitorService { + path, + threshold: parameters.threshold, + polling_period: Duration::from_secs(parameters.polling_period.into()), + }; - let storage_monitor_service = StorageMonitorService { - path: path.to_path_buf(), - threshold, - polling_period: Duration::from_secs(parameters.polling_period.into()), - }; + spawner.spawn_essential( + "storage-monitor", + None, + Box::pin(storage_monitor_service.run()), + ); + } - spawner.spawn_essential( - "storage-monitor", - None, - Box::pin(storage_monitor_service.run()), - ); - }, - }) + Ok(()) } /// Main monitoring loop, intended to be spawned as essential task. Quits if free space drop -- GitLab From f2a750ee86e72c9ab677aaf588d0a33ee8446bef Mon Sep 17 00:00:00 2001 From: Alin Dima Date: Wed, 10 Jan 2024 15:19:50 +0200 Subject: [PATCH 029/392] add fallback request for req-response protocols (#2771) Previously, it was only possible to retry the same request on a different protocol name that had the exact same binary payloads. Introduce a way of trying a different request on a different protocol if the first one fails with Unsupported protocol. This helps with adding new req-response versions in polkadot while preserving compatibility with unupgraded nodes. The way req-response protocols were bumped previously was that they were bundled with some other notifications protocol upgrade, like for async backing (but that is more complicated, especially if the feature does not require any changes to a notifications protocol). Will be needed for implementing https://github.com/polkadot-fellows/RFCs/pull/47 TODO: - [x] add tests - [x] add guidance docs in polkadot about req-response protocol versioning --- .../src/pov_requester/mod.rs | 6 +- .../src/requester/fetch_task/tests.rs | 4 +- .../src/tests/state.rs | 7 +- .../availability-recovery/src/tests.rs | 311 +++++++------ polkadot/node/network/bridge/src/network.rs | 5 +- .../src/validator_side/tests/mod.rs | 51 +-- .../tests/prospective_parachains.rs | 33 +- .../dispute-distribution/src/tests/mod.rs | 4 +- .../protocol/src/request_response/mod.rs | 43 +- .../protocol/src/request_response/outgoing.rs | 67 ++- .../src/legacy_v1/tests.rs | 9 +- .../src/v2/tests/mod.rs | 3 +- .../src/v2/tests/requests.rs | 7 +- .../subsystem-bench/src/availability/mod.rs | 10 +- .../src/core/mock/network_bridge.rs | 18 +- .../node/subsystem-bench/src/core/network.rs | 16 +- prdoc/pr_2771.prdoc | 9 + .../outgoing_requests_engine.rs | 5 +- substrate/client/network/src/behaviour.rs | 15 +- .../client/network/src/request_responses.rs | 414 ++++++++++++++++-- substrate/client/network/src/service.rs | 16 +- .../client/network/src/service/traits.rs | 22 +- .../network/sync/src/block_relay_protocol.rs | 7 +- .../network/sync/src/block_request_handler.rs | 2 +- substrate/client/network/sync/src/engine.rs | 2 +- substrate/client/network/sync/src/mock.rs | 4 +- .../network/sync/src/pending_responses.rs | 4 +- .../client/network/sync/src/service/mock.rs | 6 +- .../network/sync/src/service/network.rs | 6 +- 29 files changed, 802 insertions(+), 304 deletions(-) create mode 100644 prdoc/pr_2771.prdoc diff --git a/polkadot/node/network/availability-distribution/src/pov_requester/mod.rs b/polkadot/node/network/availability-distribution/src/pov_requester/mod.rs index 6f9ef9f6a9f..4e23030aa49 100644 --- a/polkadot/node/network/availability-distribution/src/pov_requester/mod.rs +++ b/polkadot/node/network/availability-distribution/src/pov_requester/mod.rs @@ -139,6 +139,7 @@ mod tests { use futures::{executor, future}; use parity_scale_codec::Encode; + use sc_network::ProtocolName; use sp_core::testing::TaskExecutor; use polkadot_node_primitives::BlockData; @@ -231,7 +232,10 @@ mod tests { Some(Requests::PoVFetchingV1(outgoing)) => {outgoing} ); req.pending_response - .send(Ok(PoVFetchingResponse::PoV(pov.clone()).encode())) + .send(Ok(( + PoVFetchingResponse::PoV(pov.clone()).encode(), + ProtocolName::from(""), + ))) .unwrap(); break }, diff --git a/polkadot/node/network/availability-distribution/src/requester/fetch_task/tests.rs b/polkadot/node/network/availability-distribution/src/requester/fetch_task/tests.rs index 460f20499ed..a5a81082e39 100644 --- a/polkadot/node/network/availability-distribution/src/requester/fetch_task/tests.rs +++ b/polkadot/node/network/availability-distribution/src/requester/fetch_task/tests.rs @@ -25,7 +25,7 @@ use futures::{ Future, FutureExt, StreamExt, }; -use sc_network as network; +use sc_network::{self as network, ProtocolName}; use sp_keyring::Sr25519Keyring; use polkadot_node_network_protocol::request_response::{v1, Recipient}; @@ -252,7 +252,7 @@ impl TestRun { } } req.pending_response - .send(response.map(Encode::encode)) + .send(response.map(|r| (r.encode(), ProtocolName::from("")))) .expect("Sending response should succeed"); } return (valid_responses == 0) && self.valid_chunks.is_empty() diff --git a/polkadot/node/network/availability-distribution/src/tests/state.rs b/polkadot/node/network/availability-distribution/src/tests/state.rs index e95c1c3a27c..66a8d8fcdcf 100644 --- a/polkadot/node/network/availability-distribution/src/tests/state.rs +++ b/polkadot/node/network/availability-distribution/src/tests/state.rs @@ -19,6 +19,7 @@ use std::{ time::Duration, }; +use network::ProtocolName; use polkadot_node_subsystem_test_helpers::TestSubsystemContextHandle; use polkadot_node_subsystem_util::TimeoutExt; @@ -324,7 +325,11 @@ fn to_incoming_req( let response = rx.await; let payload = response.expect("Unexpected canceled request").result; pending_response - .send(payload.map_err(|_| network::RequestFailure::Refused)) + .send( + payload + .map_err(|_| network::RequestFailure::Refused) + .map(|r| (r, ProtocolName::from(""))), + ) .expect("Sending response is expected to work"); } .boxed(), diff --git a/polkadot/node/network/availability-recovery/src/tests.rs b/polkadot/node/network/availability-recovery/src/tests.rs index 1cb52757bac..f1dc5b98c09 100644 --- a/polkadot/node/network/availability-recovery/src/tests.rs +++ b/polkadot/node/network/availability-recovery/src/tests.rs @@ -22,13 +22,14 @@ use futures_timer::Delay; use parity_scale_codec::Encode; use polkadot_node_network_protocol::request_response::{ - self as req_res, IncomingRequest, Recipient, ReqProtocolNames, Requests, + self as req_res, v1::AvailableDataFetchingRequest, IncomingRequest, Protocol, Recipient, + ReqProtocolNames, Requests, }; use polkadot_node_subsystem_test_helpers::derive_erasure_chunks_with_proofs_and_root; use super::*; -use sc_network::{config::RequestResponseConfig, IfDisconnected, OutboundFailure, RequestFailure}; +use sc_network::{IfDisconnected, OutboundFailure, ProtocolName, RequestFailure}; use polkadot_node_primitives::{BlockData, PoV, Proof}; use polkadot_node_subsystem::messages::{ @@ -48,8 +49,18 @@ type VirtualOverseer = TestSubsystemContextHandle; // Deterministic genesis hash for protocol names const GENESIS_HASH: Hash = Hash::repeat_byte(0xff); -fn test_harness_fast_path>( - test: impl FnOnce(VirtualOverseer, RequestResponseConfig) -> T, +fn request_receiver( + req_protocol_names: &ReqProtocolNames, +) -> IncomingRequestReceiver { + let receiver = IncomingRequest::get_config_receiver(req_protocol_names); + // Don't close the sending end of the request protocol. Otherwise, the subsystem will terminate. + std::mem::forget(receiver.1.inbound_queue); + receiver.0 +} + +fn test_harness>( + subsystem: AvailabilityRecoverySubsystem, + test: impl FnOnce(VirtualOverseer) -> T, ) { let _ = env_logger::builder() .is_test(true) @@ -60,101 +71,23 @@ fn test_harness_fast_path>( - test: impl FnOnce(VirtualOverseer, RequestResponseConfig) -> T, -) { - let _ = env_logger::builder() - .is_test(true) - .filter(Some("polkadot_availability_recovery"), log::LevelFilter::Trace) - .try_init(); - - let pool = sp_core::testing::TaskExecutor::new(); - - let (context, virtual_overseer) = make_subsystem_context(pool.clone()); - - let (collation_req_receiver, req_cfg) = - IncomingRequest::get_config_receiver(&ReqProtocolNames::new(&GENESIS_HASH, None)); - let subsystem = AvailabilityRecoverySubsystem::with_chunks_only( - collation_req_receiver, - Metrics::new_dummy(), - ); - let subsystem = subsystem.run(context); - - let test_fut = test(virtual_overseer, req_cfg); + let test_fut = test(virtual_overseer); futures::pin_mut!(test_fut); futures::pin_mut!(subsystem); executor::block_on(future::join( async move { - let (mut overseer, _req_cfg) = test_fut.await; + let mut overseer = test_fut.await; overseer_signal(&mut overseer, OverseerSignal::Conclude).await; }, subsystem, )) .1 - .unwrap(); -} - -fn test_harness_chunks_if_pov_large< - T: Future, ->( - test: impl FnOnce(VirtualOverseer, RequestResponseConfig) -> T, -) { - let _ = env_logger::builder() - .is_test(true) - .filter(Some("polkadot_availability_recovery"), log::LevelFilter::Trace) - .try_init(); - - let pool = sp_core::testing::TaskExecutor::new(); - - let (context, virtual_overseer) = make_subsystem_context(pool.clone()); - - let (collation_req_receiver, req_cfg) = - IncomingRequest::get_config_receiver(&ReqProtocolNames::new(&GENESIS_HASH, None)); - let subsystem = AvailabilityRecoverySubsystem::with_chunks_if_pov_large( - collation_req_receiver, - Metrics::new_dummy(), - ); - let subsystem = subsystem.run(context); - - let test_fut = test(virtual_overseer, req_cfg); - - futures::pin_mut!(test_fut); - futures::pin_mut!(subsystem); - - executor::block_on(future::join( - async move { - let (mut overseer, _req_cfg) = test_fut.await; - overseer_signal(&mut overseer, OverseerSignal::Conclude).await; - }, - subsystem, - )) - .1 - .unwrap(); } const TIMEOUT: Duration = Duration::from_millis(300); @@ -342,11 +275,12 @@ impl TestState { async fn test_chunk_requests( &self, + req_protocol_names: &ReqProtocolNames, candidate_hash: CandidateHash, virtual_overseer: &mut VirtualOverseer, n: usize, who_has: impl Fn(usize) -> Has, - ) -> Vec, RequestFailure>>> { + ) -> Vec, ProtocolName), RequestFailure>>> { // arbitrary order. let mut i = 0; let mut senders = Vec::new(); @@ -380,7 +314,7 @@ impl TestState { let _ = req.pending_response.send( available_data.map(|r| - req_res::v1::ChunkFetchingResponse::from(r).encode() + (req_res::v1::ChunkFetchingResponse::from(r).encode(), req_protocol_names.get_name(Protocol::ChunkFetchingV1)) ) ); } @@ -394,10 +328,11 @@ impl TestState { async fn test_full_data_requests( &self, + req_protocol_names: &ReqProtocolNames, candidate_hash: CandidateHash, virtual_overseer: &mut VirtualOverseer, who_has: impl Fn(usize) -> Has, - ) -> Vec, RequestFailure>>> { + ) -> Vec, ProtocolName), RequestFailure>>> { let mut senders = Vec::new(); for _ in 0..self.validators.len() { // Receive a request for a chunk. @@ -433,9 +368,10 @@ impl TestState { let done = available_data.as_ref().ok().map_or(false, |x| x.is_some()); let _ = req.pending_response.send( - available_data.map(|r| - req_res::v1::AvailableDataFetchingResponse::from(r).encode() - ) + available_data.map(|r|( + req_res::v1::AvailableDataFetchingResponse::from(r).encode(), + req_protocol_names.get_name(Protocol::AvailableDataFetchingV1) + )) ); if done { break } @@ -532,8 +468,13 @@ impl Default for TestState { #[test] fn availability_is_recovered_from_chunks_if_no_group_provided() { let test_state = TestState::default(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let subsystem = AvailabilityRecoverySubsystem::with_fast_path( + request_receiver(&req_protocol_names), + Metrics::new_dummy(), + ); - test_harness_fast_path(|mut virtual_overseer, req_cfg| async move { + test_harness(subsystem, |mut virtual_overseer| async move { overseer_signal( &mut virtual_overseer, OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(new_leaf( @@ -565,6 +506,7 @@ fn availability_is_recovered_from_chunks_if_no_group_provided() { test_state .test_chunk_requests( + &req_protocol_names, candidate_hash, &mut virtual_overseer, test_state.threshold(), @@ -600,6 +542,7 @@ fn availability_is_recovered_from_chunks_if_no_group_provided() { test_state .test_chunk_requests( + &req_protocol_names, new_candidate.hash(), &mut virtual_overseer, test_state.impossibility_threshold(), @@ -609,15 +552,20 @@ fn availability_is_recovered_from_chunks_if_no_group_provided() { // A request times out with `Unavailable` error. assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Unavailable); - (virtual_overseer, req_cfg) + virtual_overseer }); } #[test] fn availability_is_recovered_from_chunks_even_if_backing_group_supplied_if_chunks_only() { let test_state = TestState::default(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let subsystem = AvailabilityRecoverySubsystem::with_chunks_only( + request_receiver(&req_protocol_names), + Metrics::new_dummy(), + ); - test_harness_chunks_only(|mut virtual_overseer, req_cfg| async move { + test_harness(subsystem, |mut virtual_overseer| async move { overseer_signal( &mut virtual_overseer, OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(new_leaf( @@ -649,6 +597,7 @@ fn availability_is_recovered_from_chunks_even_if_backing_group_supplied_if_chunk test_state .test_chunk_requests( + &req_protocol_names, candidate_hash, &mut virtual_overseer, test_state.threshold(), @@ -684,6 +633,7 @@ fn availability_is_recovered_from_chunks_even_if_backing_group_supplied_if_chunk test_state .test_chunk_requests( + &req_protocol_names, new_candidate.hash(), &mut virtual_overseer, test_state.impossibility_threshold(), @@ -693,15 +643,20 @@ fn availability_is_recovered_from_chunks_even_if_backing_group_supplied_if_chunk // A request times out with `Unavailable` error. assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Unavailable); - (virtual_overseer, req_cfg) + virtual_overseer }); } #[test] fn bad_merkle_path_leads_to_recovery_error() { let mut test_state = TestState::default(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let subsystem = AvailabilityRecoverySubsystem::with_fast_path( + request_receiver(&req_protocol_names), + Metrics::new_dummy(), + ); - test_harness_fast_path(|mut virtual_overseer, req_cfg| async move { + test_harness(subsystem, |mut virtual_overseer| async move { overseer_signal( &mut virtual_overseer, OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(new_leaf( @@ -740,6 +695,7 @@ fn bad_merkle_path_leads_to_recovery_error() { test_state .test_chunk_requests( + &req_protocol_names, candidate_hash, &mut virtual_overseer, test_state.impossibility_threshold(), @@ -749,15 +705,20 @@ fn bad_merkle_path_leads_to_recovery_error() { // A request times out with `Unavailable` error. assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Unavailable); - (virtual_overseer, req_cfg) + virtual_overseer }); } #[test] fn wrong_chunk_index_leads_to_recovery_error() { let mut test_state = TestState::default(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let subsystem = AvailabilityRecoverySubsystem::with_fast_path( + request_receiver(&req_protocol_names), + Metrics::new_dummy(), + ); - test_harness_fast_path(|mut virtual_overseer, req_cfg| async move { + test_harness(subsystem, |mut virtual_overseer| async move { overseer_signal( &mut virtual_overseer, OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(new_leaf( @@ -796,6 +757,7 @@ fn wrong_chunk_index_leads_to_recovery_error() { test_state .test_chunk_requests( + &req_protocol_names, candidate_hash, &mut virtual_overseer, test_state.impossibility_threshold(), @@ -805,15 +767,20 @@ fn wrong_chunk_index_leads_to_recovery_error() { // A request times out with `Unavailable` error as there are no good peers. assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Unavailable); - (virtual_overseer, req_cfg) + virtual_overseer }); } #[test] fn invalid_erasure_coding_leads_to_invalid_error() { let mut test_state = TestState::default(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let subsystem = AvailabilityRecoverySubsystem::with_fast_path( + request_receiver(&req_protocol_names), + Metrics::new_dummy(), + ); - test_harness_fast_path(|mut virtual_overseer, req_cfg| async move { + test_harness(subsystem, |mut virtual_overseer| async move { let pov = PoV { block_data: BlockData(vec![69; 64]) }; let (bad_chunks, bad_erasure_root) = derive_erasure_chunks_with_proofs_and_root( @@ -859,6 +826,7 @@ fn invalid_erasure_coding_leads_to_invalid_error() { test_state .test_chunk_requests( + &req_protocol_names, candidate_hash, &mut virtual_overseer, test_state.threshold(), @@ -868,15 +836,20 @@ fn invalid_erasure_coding_leads_to_invalid_error() { // f+1 'valid' chunks can't produce correct data. assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Invalid); - (virtual_overseer, req_cfg) + virtual_overseer }); } #[test] fn fast_path_backing_group_recovers() { let test_state = TestState::default(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let subsystem = AvailabilityRecoverySubsystem::with_fast_path( + request_receiver(&req_protocol_names), + Metrics::new_dummy(), + ); - test_harness_fast_path(|mut virtual_overseer, req_cfg| async move { + test_harness(subsystem, |mut virtual_overseer| async move { overseer_signal( &mut virtual_overseer, OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(new_leaf( @@ -911,20 +884,30 @@ fn fast_path_backing_group_recovers() { test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; test_state - .test_full_data_requests(candidate_hash, &mut virtual_overseer, who_has) + .test_full_data_requests( + &req_protocol_names, + candidate_hash, + &mut virtual_overseer, + who_has, + ) .await; // Recovered data should match the original one. assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); - (virtual_overseer, req_cfg) + virtual_overseer }); } #[test] fn recovers_from_only_chunks_if_pov_large() { let test_state = TestState::default(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let subsystem = AvailabilityRecoverySubsystem::with_chunks_if_pov_large( + request_receiver(&req_protocol_names), + Metrics::new_dummy(), + ); - test_harness_chunks_if_pov_large(|mut virtual_overseer, req_cfg| async move { + test_harness(subsystem, |mut virtual_overseer| async move { overseer_signal( &mut virtual_overseer, OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(new_leaf( @@ -965,6 +948,7 @@ fn recovers_from_only_chunks_if_pov_large() { test_state .test_chunk_requests( + &req_protocol_names, candidate_hash, &mut virtual_overseer, test_state.threshold(), @@ -1009,6 +993,7 @@ fn recovers_from_only_chunks_if_pov_large() { test_state .test_chunk_requests( + &req_protocol_names, new_candidate.hash(), &mut virtual_overseer, test_state.impossibility_threshold(), @@ -1018,15 +1003,20 @@ fn recovers_from_only_chunks_if_pov_large() { // A request times out with `Unavailable` error. assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Unavailable); - (virtual_overseer, req_cfg) + virtual_overseer }); } #[test] fn fast_path_backing_group_recovers_if_pov_small() { let test_state = TestState::default(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let subsystem = AvailabilityRecoverySubsystem::with_chunks_if_pov_large( + request_receiver(&req_protocol_names), + Metrics::new_dummy(), + ); - test_harness_chunks_if_pov_large(|mut virtual_overseer, req_cfg| async move { + test_harness(subsystem, |mut virtual_overseer| async move { overseer_signal( &mut virtual_overseer, OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(new_leaf( @@ -1070,20 +1060,30 @@ fn fast_path_backing_group_recovers_if_pov_small() { test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; test_state - .test_full_data_requests(candidate_hash, &mut virtual_overseer, who_has) + .test_full_data_requests( + &req_protocol_names, + candidate_hash, + &mut virtual_overseer, + who_has, + ) .await; // Recovered data should match the original one. assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); - (virtual_overseer, req_cfg) + virtual_overseer }); } #[test] fn no_answers_in_fast_path_causes_chunk_requests() { let test_state = TestState::default(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let subsystem = AvailabilityRecoverySubsystem::with_fast_path( + request_receiver(&req_protocol_names), + Metrics::new_dummy(), + ); - test_harness_fast_path(|mut virtual_overseer, req_cfg| async move { + test_harness(subsystem, |mut virtual_overseer| async move { overseer_signal( &mut virtual_overseer, OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(new_leaf( @@ -1119,13 +1119,19 @@ fn no_answers_in_fast_path_causes_chunk_requests() { test_state.respond_to_available_data_query(&mut virtual_overseer, false).await; test_state - .test_full_data_requests(candidate_hash, &mut virtual_overseer, who_has) + .test_full_data_requests( + &req_protocol_names, + candidate_hash, + &mut virtual_overseer, + who_has, + ) .await; test_state.respond_to_query_all_request(&mut virtual_overseer, |_| false).await; test_state .test_chunk_requests( + &req_protocol_names, candidate_hash, &mut virtual_overseer, test_state.threshold(), @@ -1135,15 +1141,20 @@ fn no_answers_in_fast_path_causes_chunk_requests() { // Recovered data should match the original one. assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); - (virtual_overseer, req_cfg) + virtual_overseer }); } #[test] fn task_canceled_when_receivers_dropped() { let test_state = TestState::default(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let subsystem = AvailabilityRecoverySubsystem::with_chunks_only( + request_receiver(&req_protocol_names), + Metrics::new_dummy(), + ); - test_harness_chunks_only(|mut virtual_overseer, req_cfg| async move { + test_harness(subsystem, |mut virtual_overseer| async move { overseer_signal( &mut virtual_overseer, OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(new_leaf( @@ -1170,7 +1181,7 @@ fn task_canceled_when_receivers_dropped() { for _ in 0..test_state.validators.len() { match virtual_overseer.recv().timeout(TIMEOUT).await { - None => return (virtual_overseer, req_cfg), + None => return virtual_overseer, Some(_) => continue, } } @@ -1182,8 +1193,13 @@ fn task_canceled_when_receivers_dropped() { #[test] fn chunks_retry_until_all_nodes_respond() { let test_state = TestState::default(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let subsystem = AvailabilityRecoverySubsystem::with_chunks_only( + request_receiver(&req_protocol_names), + Metrics::new_dummy(), + ); - test_harness_chunks_only(|mut virtual_overseer, req_cfg| async move { + test_harness(subsystem, |mut virtual_overseer| async move { overseer_signal( &mut virtual_overseer, OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(new_leaf( @@ -1215,6 +1231,7 @@ fn chunks_retry_until_all_nodes_respond() { test_state .test_chunk_requests( + &req_protocol_names, candidate_hash, &mut virtual_overseer, test_state.validators.len() - test_state.threshold(), @@ -1225,6 +1242,7 @@ fn chunks_retry_until_all_nodes_respond() { // we get to go another round! test_state .test_chunk_requests( + &req_protocol_names, candidate_hash, &mut virtual_overseer, test_state.impossibility_threshold(), @@ -1234,15 +1252,20 @@ fn chunks_retry_until_all_nodes_respond() { // Recovered data should match the original one. assert_eq!(rx.await.unwrap().unwrap_err(), RecoveryError::Unavailable); - (virtual_overseer, req_cfg) + virtual_overseer }); } #[test] fn not_returning_requests_wont_stall_retrieval() { let test_state = TestState::default(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let subsystem = AvailabilityRecoverySubsystem::with_chunks_only( + request_receiver(&req_protocol_names), + Metrics::new_dummy(), + ); - test_harness_chunks_only(|mut virtual_overseer, req_cfg| async move { + test_harness(subsystem, |mut virtual_overseer| async move { overseer_signal( &mut virtual_overseer, OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(new_leaf( @@ -1277,13 +1300,18 @@ fn not_returning_requests_wont_stall_retrieval() { // Not returning senders won't cause the retrieval to stall: let _senders = test_state - .test_chunk_requests(candidate_hash, &mut virtual_overseer, not_returning_count, |_| { - Has::DoesNotReturn - }) + .test_chunk_requests( + &req_protocol_names, + candidate_hash, + &mut virtual_overseer, + not_returning_count, + |_| Has::DoesNotReturn, + ) .await; test_state .test_chunk_requests( + &req_protocol_names, candidate_hash, &mut virtual_overseer, // Should start over: @@ -1295,6 +1323,7 @@ fn not_returning_requests_wont_stall_retrieval() { // we get to go another round! test_state .test_chunk_requests( + &req_protocol_names, candidate_hash, &mut virtual_overseer, test_state.threshold(), @@ -1304,15 +1333,20 @@ fn not_returning_requests_wont_stall_retrieval() { // Recovered data should match the original one: assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); - (virtual_overseer, req_cfg) + virtual_overseer }); } #[test] fn all_not_returning_requests_still_recovers_on_return() { let test_state = TestState::default(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let subsystem = AvailabilityRecoverySubsystem::with_chunks_only( + request_receiver(&req_protocol_names), + Metrics::new_dummy(), + ); - test_harness_chunks_only(|mut virtual_overseer, req_cfg| async move { + test_harness(subsystem, |mut virtual_overseer| async move { overseer_signal( &mut virtual_overseer, OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(new_leaf( @@ -1344,6 +1378,7 @@ fn all_not_returning_requests_still_recovers_on_return() { let senders = test_state .test_chunk_requests( + &req_protocol_names, candidate_hash, &mut virtual_overseer, test_state.validators.len(), @@ -1358,6 +1393,7 @@ fn all_not_returning_requests_still_recovers_on_return() { std::mem::drop(senders); }, test_state.test_chunk_requests( + &req_protocol_names, candidate_hash, &mut virtual_overseer, // Should start over: @@ -1370,6 +1406,7 @@ fn all_not_returning_requests_still_recovers_on_return() { // we get to go another round! test_state .test_chunk_requests( + &req_protocol_names, candidate_hash, &mut virtual_overseer, test_state.threshold(), @@ -1379,15 +1416,20 @@ fn all_not_returning_requests_still_recovers_on_return() { // Recovered data should match the original one: assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); - (virtual_overseer, req_cfg) + virtual_overseer }); } #[test] fn returns_early_if_we_have_the_data() { let test_state = TestState::default(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let subsystem = AvailabilityRecoverySubsystem::with_chunks_only( + request_receiver(&req_protocol_names), + Metrics::new_dummy(), + ); - test_harness_chunks_only(|mut virtual_overseer, req_cfg| async move { + test_harness(subsystem, |mut virtual_overseer| async move { overseer_signal( &mut virtual_overseer, OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(new_leaf( @@ -1414,15 +1456,20 @@ fn returns_early_if_we_have_the_data() { test_state.respond_to_available_data_query(&mut virtual_overseer, true).await; assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); - (virtual_overseer, req_cfg) + virtual_overseer }); } #[test] fn does_not_query_local_validator() { let test_state = TestState::default(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let subsystem = AvailabilityRecoverySubsystem::with_chunks_only( + request_receiver(&req_protocol_names), + Metrics::new_dummy(), + ); - test_harness_chunks_only(|mut virtual_overseer, req_cfg| async move { + test_harness(subsystem, |mut virtual_overseer| async move { overseer_signal( &mut virtual_overseer, OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(new_leaf( @@ -1453,6 +1500,7 @@ fn does_not_query_local_validator() { test_state .test_chunk_requests( + &req_protocol_names, candidate_hash, &mut virtual_overseer, test_state.validators.len(), @@ -1463,6 +1511,7 @@ fn does_not_query_local_validator() { // second round, make sure it uses the local chunk. test_state .test_chunk_requests( + &req_protocol_names, candidate_hash, &mut virtual_overseer, test_state.threshold() - 1, @@ -1471,15 +1520,20 @@ fn does_not_query_local_validator() { .await; assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); - (virtual_overseer, req_cfg) + virtual_overseer }); } #[test] fn invalid_local_chunk_is_ignored() { let test_state = TestState::default(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let subsystem = AvailabilityRecoverySubsystem::with_chunks_only( + request_receiver(&req_protocol_names), + Metrics::new_dummy(), + ); - test_harness_chunks_only(|mut virtual_overseer, req_cfg| async move { + test_harness(subsystem, |mut virtual_overseer| async move { overseer_signal( &mut virtual_overseer, OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::start_work(new_leaf( @@ -1512,6 +1566,7 @@ fn invalid_local_chunk_is_ignored() { test_state .test_chunk_requests( + &req_protocol_names, candidate_hash, &mut virtual_overseer, test_state.threshold() - 1, @@ -1520,6 +1575,6 @@ fn invalid_local_chunk_is_ignored() { .await; assert_eq!(rx.await.unwrap().unwrap(), test_state.available_data); - (virtual_overseer, req_cfg) + virtual_overseer }); } diff --git a/polkadot/node/network/bridge/src/network.rs b/polkadot/node/network/bridge/src/network.rs index 2fcf5cec489..21bed019256 100644 --- a/polkadot/node/network/bridge/src/network.rs +++ b/polkadot/node/network/bridge/src/network.rs @@ -264,7 +264,8 @@ impl Network for Arc> { req_protocol_names: &ReqProtocolNames, if_disconnected: IfDisconnected, ) { - let (protocol, OutgoingRequest { peer, payload, pending_response }) = req.encode_request(); + let (protocol, OutgoingRequest { peer, payload, pending_response, fallback_request }) = + req.encode_request(); let peer_id = match peer { Recipient::Peer(peer_id) => Some(peer_id), @@ -315,6 +316,7 @@ impl Network for Arc> { target: LOG_TARGET, %peer_id, protocol = %req_protocol_names.get_name(protocol), + fallback_protocol = ?fallback_request.as_ref().map(|(_, p)| req_protocol_names.get_name(*p)), ?if_disconnected, "Starting request", ); @@ -324,6 +326,7 @@ impl Network for Arc> { peer_id, req_protocol_names.get_name(protocol), payload, + fallback_request.map(|(r, p)| (r, req_protocol_names.get_name(p))), pending_response, if_disconnected, ); diff --git a/polkadot/node/network/collator-protocol/src/validator_side/tests/mod.rs b/polkadot/node/network/collator-protocol/src/validator_side/tests/mod.rs index 3a974014994..1ba6389212c 100644 --- a/polkadot/node/network/collator-protocol/src/validator_side/tests/mod.rs +++ b/polkadot/node/network/collator-protocol/src/validator_side/tests/mod.rs @@ -17,6 +17,7 @@ use super::*; use assert_matches::assert_matches; use futures::{executor, future, Future}; +use sc_network::ProtocolName; use sp_core::{crypto::Pair, Encode}; use sp_keyring::Sr25519Keyring; use sp_keystore::Keystore; @@ -559,11 +560,11 @@ fn act_on_advertisement_v2() { .await; response_channel - .send(Ok(request_v1::CollationFetchingResponse::Collation( - candidate_a.clone(), - pov.clone(), - ) - .encode())) + .send(Ok(( + request_v1::CollationFetchingResponse::Collation(candidate_a.clone(), pov.clone()) + .encode(), + ProtocolName::from(""), + ))) .expect("Sending response should succeed"); assert_candidate_backing_second( @@ -761,11 +762,11 @@ fn fetch_one_collation_at_a_time() { candidate_a.descriptor.relay_parent = test_state.relay_parent; candidate_a.descriptor.persisted_validation_data_hash = dummy_pvd().hash(); response_channel - .send(Ok(request_v1::CollationFetchingResponse::Collation( - candidate_a.clone(), - pov.clone(), - ) - .encode())) + .send(Ok(( + request_v1::CollationFetchingResponse::Collation(candidate_a.clone(), pov.clone()) + .encode(), + ProtocolName::from(""), + ))) .expect("Sending response should succeed"); assert_candidate_backing_second( @@ -885,19 +886,19 @@ fn fetches_next_collation() { // First request finishes now: response_channel_non_exclusive - .send(Ok(request_v1::CollationFetchingResponse::Collation( - candidate_a.clone(), - pov.clone(), - ) - .encode())) + .send(Ok(( + request_v1::CollationFetchingResponse::Collation(candidate_a.clone(), pov.clone()) + .encode(), + ProtocolName::from(""), + ))) .expect("Sending response should succeed"); response_channel - .send(Ok(request_v1::CollationFetchingResponse::Collation( - candidate_a.clone(), - pov.clone(), - ) - .encode())) + .send(Ok(( + request_v1::CollationFetchingResponse::Collation(candidate_a.clone(), pov.clone()) + .encode(), + ProtocolName::from(""), + ))) .expect("Sending response should succeed"); assert_candidate_backing_second( @@ -1023,11 +1024,11 @@ fn fetch_next_collation_on_invalid_collation() { candidate_a.descriptor.relay_parent = test_state.relay_parent; candidate_a.descriptor.persisted_validation_data_hash = dummy_pvd().hash(); response_channel - .send(Ok(request_v1::CollationFetchingResponse::Collation( - candidate_a.clone(), - pov.clone(), - ) - .encode())) + .send(Ok(( + request_v1::CollationFetchingResponse::Collation(candidate_a.clone(), pov.clone()) + .encode(), + ProtocolName::from(""), + ))) .expect("Sending response should succeed"); let receipt = assert_candidate_backing_second( diff --git a/polkadot/node/network/collator-protocol/src/validator_side/tests/prospective_parachains.rs b/polkadot/node/network/collator-protocol/src/validator_side/tests/prospective_parachains.rs index c5236ef3eb2..23963e65554 100644 --- a/polkadot/node/network/collator-protocol/src/validator_side/tests/prospective_parachains.rs +++ b/polkadot/node/network/collator-protocol/src/validator_side/tests/prospective_parachains.rs @@ -314,11 +314,11 @@ fn v1_advertisement_accepted_and_seconded() { let pov = PoV { block_data: BlockData(vec![1]) }; response_channel - .send(Ok(request_v2::CollationFetchingResponse::Collation( - candidate.clone(), - pov.clone(), - ) - .encode())) + .send(Ok(( + request_v2::CollationFetchingResponse::Collation(candidate.clone(), pov.clone()) + .encode(), + ProtocolName::from(""), + ))) .expect("Sending response should succeed"); assert_candidate_backing_second( @@ -565,11 +565,14 @@ fn second_multiple_candidates_per_relay_parent() { let pov = PoV { block_data: BlockData(vec![1]) }; response_channel - .send(Ok(request_v2::CollationFetchingResponse::Collation( - candidate.clone(), - pov.clone(), - ) - .encode())) + .send(Ok(( + request_v2::CollationFetchingResponse::Collation( + candidate.clone(), + pov.clone(), + ) + .encode(), + ProtocolName::from(""), + ))) .expect("Sending response should succeed"); assert_candidate_backing_second( @@ -717,11 +720,11 @@ fn fetched_collation_sanity_check() { let pov = PoV { block_data: BlockData(vec![1]) }; response_channel - .send(Ok(request_v2::CollationFetchingResponse::Collation( - candidate.clone(), - pov.clone(), - ) - .encode())) + .send(Ok(( + request_v2::CollationFetchingResponse::Collation(candidate.clone(), pov.clone()) + .encode(), + ProtocolName::from(""), + ))) .expect("Sending response should succeed"); // PVD request. diff --git a/polkadot/node/network/dispute-distribution/src/tests/mod.rs b/polkadot/node/network/dispute-distribution/src/tests/mod.rs index a3520bf35f8..880d1b18032 100644 --- a/polkadot/node/network/dispute-distribution/src/tests/mod.rs +++ b/polkadot/node/network/dispute-distribution/src/tests/mod.rs @@ -32,7 +32,7 @@ use futures::{ use futures_timer::Delay; use parity_scale_codec::{Decode, Encode}; -use sc_network::config::RequestResponseConfig; +use sc_network::{config::RequestResponseConfig, ProtocolName}; use polkadot_node_network_protocol::{ request_response::{v1::DisputeRequest, IncomingRequest, ReqProtocolNames}, @@ -832,7 +832,7 @@ async fn check_sent_requests( if confirm_receive { for req in reqs { req.pending_response.send( - Ok(DisputeResponse::Confirmed.encode()) + Ok((DisputeResponse::Confirmed.encode(), ProtocolName::from(""))) ) .expect("Subsystem should be listening for a response."); } diff --git a/polkadot/node/network/protocol/src/request_response/mod.rs b/polkadot/node/network/protocol/src/request_response/mod.rs index 2df3021343d..a67d83aff0c 100644 --- a/polkadot/node/network/protocol/src/request_response/mod.rs +++ b/polkadot/node/network/protocol/src/request_response/mod.rs @@ -30,7 +30,24 @@ //! `trait IsRequest` .... A trait describing a particular request. It is used for gathering meta //! data, like what is the corresponding response type. //! -//! Versioned (v1 module): The actual requests and responses as sent over the network. +//! ## Versioning +//! +//! Versioning for request-response protocols can be done in multiple ways. +//! +//! If you're just changing the protocol name but the binary payloads are the same, just add a new +//! `fallback_name` to the protocol config. +//! +//! One way in which versioning has historically been achieved for req-response protocols is to +//! bundle the new req-resp version with an upgrade of a notifications protocol. The subsystem would +//! then know which request version to use based on stored data about the peer's notifications +//! protocol version. +//! +//! When bumping a notifications protocol version is not needed/desirable, you may add a new +//! req-resp protocol and set the old request as a fallback (see +//! `OutgoingRequest::new_with_fallback`). A request with the new version will be attempted and if +//! the protocol is refused by the peer, the fallback protocol request will be used. +//! Information about the actually used protocol will be returned alongside the raw response, so +//! that you know how to decode it. use std::{collections::HashMap, time::Duration, u64}; @@ -188,11 +205,11 @@ impl Protocol { tx: Option>, ) -> RequestResponseConfig { let name = req_protocol_names.get_name(self); - let fallback_names = self.get_fallback_names(); + let legacy_names = self.get_legacy_name().into_iter().map(Into::into).collect(); match self { Protocol::ChunkFetchingV1 => RequestResponseConfig { name, - fallback_names, + fallback_names: legacy_names, max_request_size: 1_000, max_response_size: POV_RESPONSE_SIZE as u64 * 3, // We are connected to all validators: @@ -202,7 +219,7 @@ impl Protocol { Protocol::CollationFetchingV1 | Protocol::CollationFetchingV2 => RequestResponseConfig { name, - fallback_names, + fallback_names: legacy_names, max_request_size: 1_000, max_response_size: POV_RESPONSE_SIZE, // Taken from initial implementation in collator protocol: @@ -211,7 +228,7 @@ impl Protocol { }, Protocol::PoVFetchingV1 => RequestResponseConfig { name, - fallback_names, + fallback_names: legacy_names, max_request_size: 1_000, max_response_size: POV_RESPONSE_SIZE, request_timeout: POV_REQUEST_TIMEOUT_CONNECTED, @@ -219,7 +236,7 @@ impl Protocol { }, Protocol::AvailableDataFetchingV1 => RequestResponseConfig { name, - fallback_names, + fallback_names: legacy_names, max_request_size: 1_000, // Available data size is dominated by the PoV size. max_response_size: POV_RESPONSE_SIZE, @@ -228,7 +245,7 @@ impl Protocol { }, Protocol::StatementFetchingV1 => RequestResponseConfig { name, - fallback_names, + fallback_names: legacy_names, max_request_size: 1_000, // Available data size is dominated code size. max_response_size: STATEMENT_RESPONSE_SIZE, @@ -246,7 +263,7 @@ impl Protocol { }, Protocol::DisputeSendingV1 => RequestResponseConfig { name, - fallback_names, + fallback_names: legacy_names, max_request_size: 1_000, // Responses are just confirmation, in essence not even a bit. So 100 seems // plenty. @@ -256,7 +273,7 @@ impl Protocol { }, Protocol::AttestedCandidateV2 => RequestResponseConfig { name, - fallback_names, + fallback_names: legacy_names, max_request_size: 1_000, max_response_size: ATTESTED_CANDIDATE_RESPONSE_SIZE, request_timeout: ATTESTED_CANDIDATE_TIMEOUT, @@ -328,12 +345,9 @@ impl Protocol { } } - /// Fallback protocol names of this protocol, as understood by substrate networking. - fn get_fallback_names(self) -> Vec { - self.get_legacy_name().into_iter().map(Into::into).collect() - } - /// Legacy protocol name associated with each peer set, if any. + /// The request will be tried on this legacy protocol name if the remote refuses to speak the + /// protocol. const fn get_legacy_name(self) -> Option<&'static str> { match self { Protocol::ChunkFetchingV1 => Some("/polkadot/req_chunk/1"), @@ -360,6 +374,7 @@ pub trait IsRequest { } /// Type for getting on the wire [`Protocol`] names using genesis hash & fork id. +#[derive(Clone)] pub struct ReqProtocolNames { names: HashMap, } diff --git a/polkadot/node/network/protocol/src/request_response/outgoing.rs b/polkadot/node/network/protocol/src/request_response/outgoing.rs index c613d5778f5..88439ad4036 100644 --- a/polkadot/node/network/protocol/src/request_response/outgoing.rs +++ b/polkadot/node/network/protocol/src/request_response/outgoing.rs @@ -14,8 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use futures::{channel::oneshot, prelude::Future}; +use futures::{channel::oneshot, prelude::Future, FutureExt}; +use network::ProtocolName; use parity_scale_codec::{Decode, Encode, Error as DecodingError}; use sc_network as network; @@ -49,20 +50,6 @@ pub enum Requests { } impl Requests { - /// Get the protocol this request conforms to. - pub fn get_protocol(&self) -> Protocol { - match self { - Self::ChunkFetchingV1(_) => Protocol::ChunkFetchingV1, - Self::CollationFetchingV1(_) => Protocol::CollationFetchingV1, - Self::CollationFetchingV2(_) => Protocol::CollationFetchingV2, - Self::PoVFetchingV1(_) => Protocol::PoVFetchingV1, - Self::AvailableDataFetchingV1(_) => Protocol::AvailableDataFetchingV1, - Self::StatementFetchingV1(_) => Protocol::StatementFetchingV1, - Self::DisputeSendingV1(_) => Protocol::DisputeSendingV1, - Self::AttestedCandidateV2(_) => Protocol::AttestedCandidateV2, - } - } - /// Encode the request. /// /// The corresponding protocol is returned as well, as we are now leaving typed territory. @@ -85,7 +72,7 @@ impl Requests { } /// Used by the network to send us a response to a request. -pub type ResponseSender = oneshot::Sender, network::RequestFailure>>; +pub type ResponseSender = oneshot::Sender, ProtocolName), network::RequestFailure>>; /// Any error that can occur when sending a request. #[derive(Debug, thiserror::Error)] @@ -128,11 +115,13 @@ impl RequestError { /// When using `Recipient::Authority`, the addresses can be found thanks to the authority /// discovery system. #[derive(Debug)] -pub struct OutgoingRequest { +pub struct OutgoingRequest { /// Intended recipient of this request. pub peer: Recipient, /// The actual request to send over the wire. pub payload: Req, + /// Optional fallback request and protocol. + pub fallback_request: Option<(FallbackReq, Protocol)>, /// Sender which is used by networking to get us back a response. pub pending_response: ResponseSender, } @@ -149,10 +138,12 @@ pub enum Recipient { /// Responses received for an `OutgoingRequest`. pub type OutgoingResult = Result; -impl OutgoingRequest +impl OutgoingRequest where Req: IsRequest + Encode, Req::Response: Decode, + FallbackReq: IsRequest + Encode, + FallbackReq::Response: Decode, { /// Create a new `OutgoingRequest`. /// @@ -163,24 +154,54 @@ where payload: Req, ) -> (Self, impl Future>) { let (tx, rx) = oneshot::channel(); - let r = Self { peer, payload, pending_response: tx }; - (r, receive_response::(rx)) + let r = Self { peer, payload, pending_response: tx, fallback_request: None }; + (r, receive_response::(rx.map(|r| r.map(|r| r.map(|(resp, _)| resp))))) } + /// Create a new `OutgoingRequest` with a fallback in case the remote does not support this + /// protocol. Useful when adding a new version of a req-response protocol, to achieve + /// compatibility with the older version. + /// + /// Returns a raw `Vec` response over the channel. Use the associated `ProtocolName` to know + /// which request was the successful one and appropriately decode the response. + // WARNING: This is commented for now because it's not used yet. + // If you need it, make sure to test it. You may need to enable the V1 substream upgrade + // protocol, unless libp2p was in the meantime updated to a version that fixes the problem + // described in https://github.com/libp2p/rust-libp2p/issues/5074 + // pub fn new_with_fallback( + // peer: Recipient, + // payload: Req, + // fallback_request: FallbackReq, + // ) -> (Self, impl Future, ProtocolName)>>) { + // let (tx, rx) = oneshot::channel(); + // let r = Self { + // peer, + // payload, + // pending_response: tx, + // fallback_request: Some((fallback_request, FallbackReq::PROTOCOL)), + // }; + // (r, async { Ok(rx.await??) }) + // } + /// Encode a request into a `Vec`. /// /// As this throws away type information, we also return the `Protocol` this encoded request /// adheres to. pub fn encode_request(self) -> (Protocol, OutgoingRequest>) { - let OutgoingRequest { peer, payload, pending_response } = self; - let encoded = OutgoingRequest { peer, payload: payload.encode(), pending_response }; + let OutgoingRequest { peer, payload, pending_response, fallback_request } = self; + let encoded = OutgoingRequest { + peer, + payload: payload.encode(), + fallback_request: fallback_request.map(|(r, p)| (r.encode(), p)), + pending_response, + }; (Req::PROTOCOL, encoded) } } /// Future for actually receiving a typed response for an `OutgoingRequest`. async fn receive_response( - rec: oneshot::Receiver, network::RequestFailure>>, + rec: impl Future, network::RequestFailure>, oneshot::Canceled>>, ) -> OutgoingResult where Req: IsRequest, diff --git a/polkadot/node/network/statement-distribution/src/legacy_v1/tests.rs b/polkadot/node/network/statement-distribution/src/legacy_v1/tests.rs index 8ac9895ec5a..2766ec9815a 100644 --- a/polkadot/node/network/statement-distribution/src/legacy_v1/tests.rs +++ b/polkadot/node/network/statement-distribution/src/legacy_v1/tests.rs @@ -50,6 +50,7 @@ use polkadot_primitives_test_helpers::{ dummy_committed_candidate_receipt, dummy_hash, AlwaysZeroRng, }; use sc_keystore::LocalKeystore; +use sc_network::ProtocolName; use sp_application_crypto::{sr25519::Pair, AppCrypto, Pair as TraitPair}; use sp_authority_discovery::AuthorityPair; use sp_keyring::Sr25519Keyring; @@ -1330,7 +1331,7 @@ fn receiving_large_statement_from_one_sends_to_another_and_to_candidate_backing( bad }; let response = StatementFetchingResponse::Statement(bad_candidate); - outgoing.pending_response.send(Ok(response.encode())).unwrap(); + outgoing.pending_response.send(Ok((response.encode(), ProtocolName::from("")))).unwrap(); } ); @@ -1382,7 +1383,7 @@ fn receiving_large_statement_from_one_sends_to_another_and_to_candidate_backing( // On retry, we should have reverse order: assert_eq!(outgoing.peer, Recipient::Peer(peer_c)); let response = StatementFetchingResponse::Statement(candidate.clone()); - outgoing.pending_response.send(Ok(response.encode())).unwrap(); + outgoing.pending_response.send(Ok((response.encode(), ProtocolName::from("")))).unwrap(); } ); @@ -1869,7 +1870,7 @@ fn delay_reputation_changes() { bad }; let response = StatementFetchingResponse::Statement(bad_candidate); - outgoing.pending_response.send(Ok(response.encode())).unwrap(); + outgoing.pending_response.send(Ok((response.encode(), ProtocolName::from("")))).unwrap(); } ); @@ -1913,7 +1914,7 @@ fn delay_reputation_changes() { // On retry, we should have reverse order: assert_eq!(outgoing.peer, Recipient::Peer(peer_c)); let response = StatementFetchingResponse::Statement(candidate.clone()); - outgoing.pending_response.send(Ok(response.encode())).unwrap(); + outgoing.pending_response.send(Ok((response.encode(), ProtocolName::from("")))).unwrap(); } ); diff --git a/polkadot/node/network/statement-distribution/src/v2/tests/mod.rs b/polkadot/node/network/statement-distribution/src/v2/tests/mod.rs index 3ce43202b95..bb780584feb 100644 --- a/polkadot/node/network/statement-distribution/src/v2/tests/mod.rs +++ b/polkadot/node/network/statement-distribution/src/v2/tests/mod.rs @@ -38,6 +38,7 @@ use polkadot_primitives::{ SessionIndex, SessionInfo, ValidatorPair, }; use sc_keystore::LocalKeystore; +use sc_network::ProtocolName; use sp_application_crypto::Pair as PairT; use sp_authority_discovery::AuthorityPair as AuthorityDiscoveryPair; use sp_keyring::Sr25519Keyring; @@ -684,7 +685,7 @@ async fn handle_sent_request( persisted_validation_data, statements, }; - outgoing.pending_response.send(Ok(res.encode())).unwrap(); + outgoing.pending_response.send(Ok((res.encode(), ProtocolName::from("")))).unwrap(); } ); } diff --git a/polkadot/node/network/statement-distribution/src/v2/tests/requests.rs b/polkadot/node/network/statement-distribution/src/v2/tests/requests.rs index 04934b31482..dc2c8f55290 100644 --- a/polkadot/node/network/statement-distribution/src/v2/tests/requests.rs +++ b/polkadot/node/network/statement-distribution/src/v2/tests/requests.rs @@ -22,8 +22,9 @@ use polkadot_node_network_protocol::{ request_response::v2 as request_v2, v2::BackedCandidateManifest, }; use polkadot_primitives_test_helpers::make_candidate; -use sc_network::config::{ - IncomingRequest as RawIncomingRequest, OutgoingResponse as RawOutgoingResponse, +use sc_network::{ + config::{IncomingRequest as RawIncomingRequest, OutgoingResponse as RawOutgoingResponse}, + ProtocolName, }; #[test] @@ -1342,7 +1343,7 @@ fn when_validator_disabled_after_sending_the_request() { persisted_validation_data: pvd, statements, }; - outgoing.pending_response.send(Ok(res.encode())).unwrap(); + outgoing.pending_response.send(Ok((res.encode(), ProtocolName::from("")))).unwrap(); } ); } diff --git a/polkadot/node/subsystem-bench/src/availability/mod.rs b/polkadot/node/subsystem-bench/src/availability/mod.rs index 7c81b931365..faedccdf3e4 100644 --- a/polkadot/node/subsystem-bench/src/availability/mod.rs +++ b/polkadot/node/subsystem-bench/src/availability/mod.rs @@ -109,7 +109,12 @@ fn prepare_test_inner( chunks: state.chunks.clone(), }; - let network = NetworkEmulator::new(&config, &dependencies, &test_authorities); + let req_protocol_names = ReqProtocolNames::new(GENESIS_HASH, None); + let (collation_req_receiver, req_cfg) = + IncomingRequest::get_config_receiver(&req_protocol_names); + + let network = + NetworkEmulator::new(&config, &dependencies, &test_authorities, req_protocol_names); let network_bridge_tx = network_bridge::MockNetworkBridgeTx::new( config.clone(), @@ -122,9 +127,6 @@ fn prepare_test_inner( _ => panic!("Unexpected objective"), }; - let (collation_req_receiver, req_cfg) = - IncomingRequest::get_config_receiver(&ReqProtocolNames::new(GENESIS_HASH, None)); - let subsystem = if use_fast_path { AvailabilityRecoverySubsystem::with_fast_path( collation_req_receiver, diff --git a/polkadot/node/subsystem-bench/src/core/mock/network_bridge.rs b/polkadot/node/subsystem-bench/src/core/mock/network_bridge.rs index b106b832011..5d534e37c99 100644 --- a/polkadot/node/subsystem-bench/src/core/mock/network_bridge.rs +++ b/polkadot/node/subsystem-bench/src/core/mock/network_bridge.rs @@ -33,7 +33,9 @@ use polkadot_node_subsystem::{ }; use polkadot_node_network_protocol::request_response::{ - self as req_res, v1::ChunkResponse, Requests, + self as req_res, + v1::{AvailableDataFetchingRequest, ChunkFetchingRequest, ChunkResponse}, + IsRequest, Requests, }; use polkadot_primitives::AuthorityDiscoveryId; @@ -144,7 +146,10 @@ impl MockNetworkBridgeTx { size = 0; Err(RequestFailure::Network(OutboundFailure::ConnectionClosed)) } else { - Ok(req_res::v1::ChunkFetchingResponse::from(Some(chunk)).encode()) + Ok(( + req_res::v1::ChunkFetchingResponse::from(Some(chunk)).encode(), + self.network.req_protocol_names().get_name(ChunkFetchingRequest::PROTOCOL), + )) }; let authority_discovery_id_clone = authority_discovery_id.clone(); @@ -212,8 +217,13 @@ impl MockNetworkBridgeTx { let response = if random_error(self.config.error) { Err(RequestFailure::Network(OutboundFailure::ConnectionClosed)) } else { - Ok(req_res::v1::AvailableDataFetchingResponse::from(Some(available_data)) - .encode()) + Ok(( + req_res::v1::AvailableDataFetchingResponse::from(Some(available_data)) + .encode(), + self.network + .req_protocol_names() + .get_name(AvailableDataFetchingRequest::PROTOCOL), + )) }; let future = async move { diff --git a/polkadot/node/subsystem-bench/src/core/network.rs b/polkadot/node/subsystem-bench/src/core/network.rs index c4e20b421d3..bbf61425f73 100644 --- a/polkadot/node/subsystem-bench/src/core/network.rs +++ b/polkadot/node/subsystem-bench/src/core/network.rs @@ -19,6 +19,7 @@ use super::{ *, }; use colored::Colorize; +use polkadot_node_network_protocol::request_response::ReqProtocolNames; use polkadot_primitives::AuthorityDiscoveryId; use prometheus_endpoint::U64; use rand::{seq::SliceRandom, thread_rng}; @@ -311,6 +312,8 @@ pub struct NetworkEmulator { stats: Vec>, /// Each emulated peer is a validator. validator_authority_ids: HashMap, + /// Request protocol names + req_protocol_names: ReqProtocolNames, } impl NetworkEmulator { @@ -318,6 +321,7 @@ impl NetworkEmulator { config: &TestConfiguration, dependencies: &TestEnvironmentDependencies, authorities: &TestAuthorities, + req_protocol_names: ReqProtocolNames, ) -> Self { let n_peers = config.n_validators; gum::info!(target: LOG_TARGET, "{}",format!("Initializing emulation for a {} peer network.", n_peers).bright_blue()); @@ -355,7 +359,12 @@ impl NetworkEmulator { gum::info!(target: LOG_TARGET, "{}",format!("Network created, connected validator count {}", connected_count).bright_black()); - Self { peers, stats, validator_authority_ids: validator_authority_id_mapping } + Self { + peers, + stats, + validator_authority_ids: validator_authority_id_mapping, + req_protocol_names, + } } pub fn is_peer_connected(&self, peer: &AuthorityDiscoveryId) -> bool { @@ -428,6 +437,11 @@ impl NetworkEmulator { // Our node always is peer 0. self.peer_stats(0).inc_received(bytes); } + + // Get the request protocol names + pub fn req_protocol_names(&self) -> &ReqProtocolNames { + &self.req_protocol_names + } } use polkadot_node_subsystem_util::metrics::prometheus::{ diff --git a/prdoc/pr_2771.prdoc b/prdoc/pr_2771.prdoc new file mode 100644 index 00000000000..1b49162e439 --- /dev/null +++ b/prdoc/pr_2771.prdoc @@ -0,0 +1,9 @@ +title: Add fallback request for req-response protocols + +doc: + - audience: Node Dev + description: | + Enable better req-response protocol versioning, by allowing for fallback requests on different protocols. + +crates: + - name: sc_network diff --git a/substrate/client/consensus/beefy/src/communication/request_response/outgoing_requests_engine.rs b/substrate/client/consensus/beefy/src/communication/request_response/outgoing_requests_engine.rs index ef462a54fca..7121410ea10 100644 --- a/substrate/client/consensus/beefy/src/communication/request_response/outgoing_requests_engine.rs +++ b/substrate/client/consensus/beefy/src/communication/request_response/outgoing_requests_engine.rs @@ -43,7 +43,7 @@ use crate::{ }; /// Response type received from network. -type Response = Result, RequestFailure>; +type Response = Result<(Vec, ProtocolName), RequestFailure>; /// Used to receive a response from the network. type ResponseReceiver = oneshot::Receiver; @@ -125,6 +125,7 @@ impl OnDemandJustificationsEngine { peer, self.protocol_name.clone(), payload, + None, tx, IfDisconnected::ImmediateError, ); @@ -204,7 +205,7 @@ impl OnDemandJustificationsEngine { }, } }) - .and_then(|encoded| { + .and_then(|(encoded, _)| { decode_and_verify_finality_proof::( &encoded[..], req_info.block, diff --git a/substrate/client/network/src/behaviour.rs b/substrate/client/network/src/behaviour.rs index 745550412fc..1f234683392 100644 --- a/substrate/client/network/src/behaviour.rs +++ b/substrate/client/network/src/behaviour.rs @@ -231,13 +231,20 @@ impl Behaviour { pub fn send_request( &mut self, target: &PeerId, - protocol: &str, + protocol: ProtocolName, request: Vec, - pending_response: oneshot::Sender, RequestFailure>>, + fallback_request: Option<(Vec, ProtocolName)>, + pending_response: oneshot::Sender, ProtocolName), RequestFailure>>, connect: IfDisconnected, ) { - self.request_responses - .send_request(target, protocol, request, pending_response, connect) + self.request_responses.send_request( + target, + protocol, + request, + fallback_request, + pending_response, + connect, + ) } /// Returns a shared reference to the user protocol. diff --git a/substrate/client/network/src/request_responses.rs b/substrate/client/network/src/request_responses.rs index 5af072aaddc..0cd1cf06bb3 100644 --- a/substrate/client/network/src/request_responses.rs +++ b/substrate/client/network/src/request_responses.rs @@ -56,6 +56,7 @@ use libp2p::{ use std::{ collections::{hash_map::Entry, HashMap}, io, iter, + ops::Deref, pin::Pin, task::{Context, Poll}, time::{Duration, Instant}, @@ -172,6 +173,13 @@ pub struct OutgoingResponse { pub sent_feedback: Option>, } +/// Information stored about a pending request. +struct PendingRequest { + started_at: Instant, + response_tx: oneshot::Sender, ProtocolName), RequestFailure>>, + fallback_request: Option<(Vec, ProtocolName)>, +} + /// When sending a request, what to do on a disconnected recipient. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum IfDisconnected { @@ -264,8 +272,7 @@ pub struct RequestResponsesBehaviour { >, /// Pending requests, passed down to a request-response [`Behaviour`], awaiting a reply. - pending_requests: - HashMap, RequestFailure>>)>, + pending_requests: HashMap, /// Whenever an incoming request arrives, a `Future` is added to this list and will yield the /// start time and the response to send back to the remote. @@ -348,29 +355,25 @@ impl RequestResponsesBehaviour { pub fn send_request( &mut self, target: &PeerId, - protocol_name: &str, + protocol_name: ProtocolName, request: Vec, - pending_response: oneshot::Sender, RequestFailure>>, + fallback_request: Option<(Vec, ProtocolName)>, + pending_response: oneshot::Sender, ProtocolName), RequestFailure>>, connect: IfDisconnected, ) { log::trace!(target: "sub-libp2p", "send request to {target} ({protocol_name:?}), {} bytes", request.len()); - if let Some((protocol, _)) = self.protocols.get_mut(protocol_name) { - if protocol.is_connected(target) || connect.should_connect() { - let request_id = protocol.send_request(target, request); - let prev_req_id = self.pending_requests.insert( - (protocol_name.to_string().into(), request_id).into(), - (Instant::now(), pending_response), - ); - debug_assert!(prev_req_id.is_none(), "Expect request id to be unique."); - } else if pending_response.send(Err(RequestFailure::NotConnected)).is_err() { - log::debug!( - target: "sub-libp2p", - "Not connected to peer {:?}. At the same time local \ - node is no longer interested in the result.", - target, - ); - } + if let Some((protocol, _)) = self.protocols.get_mut(protocol_name.deref()) { + Self::send_request_inner( + protocol, + &mut self.pending_requests, + target, + protocol_name, + request, + fallback_request, + pending_response, + connect, + ) } else if pending_response.send(Err(RequestFailure::UnknownProtocol)).is_err() { log::debug!( target: "sub-libp2p", @@ -380,6 +383,37 @@ impl RequestResponsesBehaviour { ); } } + + fn send_request_inner( + behaviour: &mut Behaviour, + pending_requests: &mut HashMap, + target: &PeerId, + protocol_name: ProtocolName, + request: Vec, + fallback_request: Option<(Vec, ProtocolName)>, + pending_response: oneshot::Sender, ProtocolName), RequestFailure>>, + connect: IfDisconnected, + ) { + if behaviour.is_connected(target) || connect.should_connect() { + let request_id = behaviour.send_request(target, request); + let prev_req_id = pending_requests.insert( + (protocol_name.to_string().into(), request_id).into(), + PendingRequest { + started_at: Instant::now(), + response_tx: pending_response, + fallback_request, + }, + ); + debug_assert!(prev_req_id.is_none(), "Expect request id to be unique."); + } else if pending_response.send(Err(RequestFailure::NotConnected)).is_err() { + log::debug!( + target: "sub-libp2p", + "Not connected to peer {:?}. At the same time local \ + node is no longer interested in the result.", + target, + ); + } + } } impl NetworkBehaviour for RequestResponsesBehaviour { @@ -596,8 +630,10 @@ impl NetworkBehaviour for RequestResponsesBehaviour { } } + let mut fallback_requests = vec![]; + // Poll request-responses protocols. - for (protocol, (behaviour, resp_builder)) in &mut self.protocols { + for (protocol, (ref mut behaviour, ref mut resp_builder)) in &mut self.protocols { 'poll_protocol: while let Poll::Ready(ev) = behaviour.poll(cx, params) { let ev = match ev { // Main events we are interested in. @@ -698,17 +734,21 @@ impl NetworkBehaviour for RequestResponsesBehaviour { .pending_requests .remove(&(protocol.clone(), request_id).into()) { - Some((started, pending_response)) => { + Some(PendingRequest { started_at, response_tx, .. }) => { log::trace!( target: "sub-libp2p", "received response from {peer} ({protocol:?}), {} bytes", response.as_ref().map_or(0usize, |response| response.len()), ); - let delivered = pending_response - .send(response.map_err(|()| RequestFailure::Refused)) + let delivered = response_tx + .send( + response + .map_err(|()| RequestFailure::Refused) + .map(|resp| (resp, protocol.clone())), + ) .map_err(|_| RequestFailure::Obsolete); - (started, delivered) + (started_at, delivered) }, None => { log::warn!( @@ -742,8 +782,34 @@ impl NetworkBehaviour for RequestResponsesBehaviour { .pending_requests .remove(&(protocol.clone(), request_id).into()) { - Some((started, pending_response)) => { - if pending_response + Some(PendingRequest { + started_at, + response_tx, + fallback_request, + }) => { + // Try using the fallback request if the protocol was not + // supported. + if let OutboundFailure::UnsupportedProtocols = error { + if let Some((fallback_request, fallback_protocol)) = + fallback_request + { + log::trace!( + target: "sub-libp2p", + "Request with id {:?} failed. Trying the fallback protocol. {}", + request_id, + fallback_protocol.deref() + ); + fallback_requests.push(( + peer, + fallback_protocol, + fallback_request, + response_tx, + )); + continue + } + } + + if response_tx .send(Err(RequestFailure::Network(error.clone()))) .is_err() { @@ -754,7 +820,7 @@ impl NetworkBehaviour for RequestResponsesBehaviour { request_id, ); } - started + started_at }, None => { log::warn!( @@ -825,6 +891,25 @@ impl NetworkBehaviour for RequestResponsesBehaviour { } } + // Send out fallback requests. + for (peer, protocol, request, pending_response) in fallback_requests.drain(..) { + if let Some((behaviour, _)) = self.protocols.get_mut(&protocol) { + Self::send_request_inner( + behaviour, + &mut self.pending_requests, + &peer, + protocol, + request, + None, + pending_response, + // We can error if not connected because the + // previous attempt would have tried to establish a + // connection already or errored and we wouldn't have gotten here. + IfDisconnected::ImmediateError, + ); + } + } + break Poll::Pending } } @@ -976,6 +1061,7 @@ mod tests { use super::*; use crate::mock::MockPeerStore; + use assert_matches::assert_matches; use futures::{channel::oneshot, executor::LocalPool, task::Spawn}; use libp2p::{ core::{ @@ -1025,7 +1111,7 @@ mod tests { #[test] fn basic_request_response_works() { - let protocol_name = "/test/req-resp/1"; + let protocol_name = ProtocolName::from("/test/req-resp/1"); let mut pool = LocalPool::new(); // Build swarms whose behaviour is [`RequestResponsesBehaviour`]. @@ -1053,7 +1139,7 @@ mod tests { .unwrap(); let protocol_config = ProtocolConfig { - name: From::from(protocol_name), + name: protocol_name.clone(), fallback_names: Vec::new(), max_request_size: 1024, max_response_size: 1024 * 1024, @@ -1102,8 +1188,9 @@ mod tests { let (sender, receiver) = oneshot::channel(); swarm.behaviour_mut().send_request( &peer_id, - protocol_name, + protocol_name.clone(), b"this is a request".to_vec(), + None, sender, IfDisconnected::ImmediateError, ); @@ -1118,13 +1205,16 @@ mod tests { } } - assert_eq!(response_receiver.unwrap().await.unwrap().unwrap(), b"this is a response"); + assert_eq!( + response_receiver.unwrap().await.unwrap().unwrap(), + (b"this is a response".to_vec(), protocol_name) + ); }); } #[test] fn max_response_size_exceeded() { - let protocol_name = "/test/req-resp/1"; + let protocol_name = ProtocolName::from("/test/req-resp/1"); let mut pool = LocalPool::new(); // Build swarms whose behaviour is [`RequestResponsesBehaviour`]. @@ -1150,7 +1240,7 @@ mod tests { .unwrap(); let protocol_config = ProtocolConfig { - name: From::from(protocol_name), + name: protocol_name.clone(), fallback_names: Vec::new(), max_request_size: 1024, max_response_size: 8, // <-- important for the test @@ -1201,8 +1291,9 @@ mod tests { let (sender, receiver) = oneshot::channel(); swarm.behaviour_mut().send_request( &peer_id, - protocol_name, + protocol_name.clone(), b"this is a request".to_vec(), + None, sender, IfDisconnected::ImmediateError, ); @@ -1236,14 +1327,14 @@ mod tests { /// See [`ProtocolRequestId`] for additional information. #[test] fn request_id_collision() { - let protocol_name_1 = "/test/req-resp-1/1"; - let protocol_name_2 = "/test/req-resp-2/1"; + let protocol_name_1 = ProtocolName::from("/test/req-resp-1/1"); + let protocol_name_2 = ProtocolName::from("/test/req-resp-2/1"); let mut pool = LocalPool::new(); let mut swarm_1 = { let protocol_configs = vec![ ProtocolConfig { - name: From::from(protocol_name_1), + name: protocol_name_1.clone(), fallback_names: Vec::new(), max_request_size: 1024, max_response_size: 1024 * 1024, @@ -1251,7 +1342,7 @@ mod tests { inbound_queue: None, }, ProtocolConfig { - name: From::from(protocol_name_2), + name: protocol_name_2.clone(), fallback_names: Vec::new(), max_request_size: 1024, max_response_size: 1024 * 1024, @@ -1269,7 +1360,7 @@ mod tests { let protocol_configs = vec![ ProtocolConfig { - name: From::from(protocol_name_1), + name: protocol_name_1.clone(), fallback_names: Vec::new(), max_request_size: 1024, max_response_size: 1024 * 1024, @@ -1277,7 +1368,7 @@ mod tests { inbound_queue: Some(tx_1), }, ProtocolConfig { - name: From::from(protocol_name_2), + name: protocol_name_2.clone(), fallback_names: Vec::new(), max_request_size: 1024, max_response_size: 1024 * 1024, @@ -1359,15 +1450,17 @@ mod tests { let (sender_2, receiver_2) = oneshot::channel(); swarm_1.behaviour_mut().send_request( &peer_id, - protocol_name_1, + protocol_name_1.clone(), b"this is a request".to_vec(), + None, sender_1, IfDisconnected::ImmediateError, ); swarm_1.behaviour_mut().send_request( &peer_id, - protocol_name_2, + protocol_name_2.clone(), b"this is a request".to_vec(), + None, sender_2, IfDisconnected::ImmediateError, ); @@ -1385,8 +1478,239 @@ mod tests { } } let (response_receiver_1, response_receiver_2) = response_receivers.unwrap(); - assert_eq!(response_receiver_1.await.unwrap().unwrap(), b"this is a response"); - assert_eq!(response_receiver_2.await.unwrap().unwrap(), b"this is a response"); + assert_eq!( + response_receiver_1.await.unwrap().unwrap(), + (b"this is a response".to_vec(), protocol_name_1) + ); + assert_eq!( + response_receiver_2.await.unwrap().unwrap(), + (b"this is a response".to_vec(), protocol_name_2) + ); + }); + } + + #[test] + fn request_fallback() { + let protocol_name_1 = ProtocolName::from("/test/req-resp/2"); + let protocol_name_1_fallback = ProtocolName::from("/test/req-resp/1"); + let protocol_name_2 = ProtocolName::from("/test/another"); + let mut pool = LocalPool::new(); + + let protocol_config_1 = ProtocolConfig { + name: protocol_name_1.clone(), + fallback_names: Vec::new(), + max_request_size: 1024, + max_response_size: 1024 * 1024, + request_timeout: Duration::from_secs(30), + inbound_queue: None, + }; + let protocol_config_1_fallback = ProtocolConfig { + name: protocol_name_1_fallback.clone(), + fallback_names: Vec::new(), + max_request_size: 1024, + max_response_size: 1024 * 1024, + request_timeout: Duration::from_secs(30), + inbound_queue: None, + }; + let protocol_config_2 = ProtocolConfig { + name: protocol_name_2.clone(), + fallback_names: Vec::new(), + max_request_size: 1024, + max_response_size: 1024 * 1024, + request_timeout: Duration::from_secs(30), + inbound_queue: None, + }; + + // This swarm only speaks protocol_name_1_fallback and protocol_name_2. + // It only responds to requests. + let mut older_swarm = { + let (tx_1, mut rx_1) = async_channel::bounded::(64); + let (tx_2, mut rx_2) = async_channel::bounded::(64); + let mut protocol_config_1_fallback = protocol_config_1_fallback.clone(); + protocol_config_1_fallback.inbound_queue = Some(tx_1); + + let mut protocol_config_2 = protocol_config_2.clone(); + protocol_config_2.inbound_queue = Some(tx_2); + + pool.spawner() + .spawn_obj( + async move { + for _ in 0..2 { + if let Some(rq) = rx_1.next().await { + let (fb_tx, fb_rx) = oneshot::channel(); + assert_eq!(rq.payload, b"request on protocol /test/req-resp/1"); + let _ = rq.pending_response.send(super::OutgoingResponse { + result: Ok( + b"this is a response on protocol /test/req-resp/1".to_vec() + ), + reputation_changes: Vec::new(), + sent_feedback: Some(fb_tx), + }); + fb_rx.await.unwrap(); + } + } + + if let Some(rq) = rx_2.next().await { + let (fb_tx, fb_rx) = oneshot::channel(); + assert_eq!(rq.payload, b"request on protocol /test/other"); + let _ = rq.pending_response.send(super::OutgoingResponse { + result: Ok(b"this is a response on protocol /test/other".to_vec()), + reputation_changes: Vec::new(), + sent_feedback: Some(fb_tx), + }); + fb_rx.await.unwrap(); + } + } + .boxed() + .into(), + ) + .unwrap(); + + build_swarm(vec![protocol_config_1_fallback, protocol_config_2].into_iter()) + }; + + // This swarm speaks all protocols. + let mut new_swarm = build_swarm( + vec![ + protocol_config_1.clone(), + protocol_config_1_fallback.clone(), + protocol_config_2.clone(), + ] + .into_iter(), + ); + + { + let dial_addr = older_swarm.1.clone(); + Swarm::dial(&mut new_swarm.0, dial_addr).unwrap(); + } + + // Running `older_swarm`` in the background. + pool.spawner() + .spawn_obj({ + async move { + loop { + _ = older_swarm.0.select_next_some().await; + } + } + .boxed() + .into() + }) + .unwrap(); + + // Run the newer swarm. Attempt to make requests on all protocols. + let (mut swarm, _) = new_swarm; + let mut older_peer_id = None; + + pool.run_until(async move { + let mut response_receiver = None; + // Try the new protocol with a fallback. + loop { + match swarm.select_next_some().await { + SwarmEvent::ConnectionEstablished { peer_id, .. } => { + older_peer_id = Some(peer_id); + let (sender, receiver) = oneshot::channel(); + swarm.behaviour_mut().send_request( + &peer_id, + protocol_name_1.clone(), + b"request on protocol /test/req-resp/2".to_vec(), + Some(( + b"request on protocol /test/req-resp/1".to_vec(), + protocol_config_1_fallback.name.clone(), + )), + sender, + IfDisconnected::ImmediateError, + ); + response_receiver = Some(receiver); + }, + SwarmEvent::Behaviour(Event::RequestFinished { result, .. }) => { + result.unwrap(); + break + }, + _ => {}, + } + } + assert_eq!( + response_receiver.unwrap().await.unwrap().unwrap(), + ( + b"this is a response on protocol /test/req-resp/1".to_vec(), + protocol_name_1_fallback.clone() + ) + ); + // Try the old protocol with a useless fallback. + let (sender, response_receiver) = oneshot::channel(); + swarm.behaviour_mut().send_request( + older_peer_id.as_ref().unwrap(), + protocol_name_1_fallback.clone(), + b"request on protocol /test/req-resp/1".to_vec(), + Some(( + b"dummy request, will fail if processed".to_vec(), + protocol_config_1_fallback.name.clone(), + )), + sender, + IfDisconnected::ImmediateError, + ); + loop { + match swarm.select_next_some().await { + SwarmEvent::Behaviour(Event::RequestFinished { result, .. }) => { + result.unwrap(); + break + }, + _ => {}, + } + } + assert_eq!( + response_receiver.await.unwrap().unwrap(), + ( + b"this is a response on protocol /test/req-resp/1".to_vec(), + protocol_name_1_fallback.clone() + ) + ); + // Try the new protocol with no fallback. Should fail. + let (sender, response_receiver) = oneshot::channel(); + swarm.behaviour_mut().send_request( + older_peer_id.as_ref().unwrap(), + protocol_name_1.clone(), + b"request on protocol /test/req-resp-2".to_vec(), + None, + sender, + IfDisconnected::ImmediateError, + ); + loop { + match swarm.select_next_some().await { + SwarmEvent::Behaviour(Event::RequestFinished { result, .. }) => { + assert_matches!( + result.unwrap_err(), + RequestFailure::Network(OutboundFailure::UnsupportedProtocols) + ); + break + }, + _ => {}, + } + } + assert!(response_receiver.await.unwrap().is_err()); + // Try the other protocol with no fallback. + let (sender, response_receiver) = oneshot::channel(); + swarm.behaviour_mut().send_request( + older_peer_id.as_ref().unwrap(), + protocol_name_2.clone(), + b"request on protocol /test/other".to_vec(), + None, + sender, + IfDisconnected::ImmediateError, + ); + loop { + match swarm.select_next_some().await { + SwarmEvent::Behaviour(Event::RequestFinished { result, .. }) => { + result.unwrap(); + break + }, + _ => {}, + } + } + assert_eq!( + response_receiver.await.unwrap().unwrap(), + (b"this is a response on protocol /test/other".to_vec(), protocol_name_2.clone()) + ); }); } } diff --git a/substrate/client/network/src/service.rs b/substrate/client/network/src/service.rs index 06db23844d0..47e23337633 100644 --- a/substrate/client/network/src/service.rs +++ b/substrate/client/network/src/service.rs @@ -1048,11 +1048,12 @@ where target: PeerId, protocol: ProtocolName, request: Vec, + fallback_request: Option<(Vec, ProtocolName)>, connect: IfDisconnected, - ) -> Result, RequestFailure> { + ) -> Result<(Vec, ProtocolName), RequestFailure> { let (tx, rx) = oneshot::channel(); - self.start_request(target, protocol, request, tx, connect); + self.start_request(target, protocol, request, fallback_request, tx, connect); match rx.await { Ok(v) => v, @@ -1068,13 +1069,15 @@ where target: PeerId, protocol: ProtocolName, request: Vec, - tx: oneshot::Sender, RequestFailure>>, + fallback_request: Option<(Vec, ProtocolName)>, + tx: oneshot::Sender, ProtocolName), RequestFailure>>, connect: IfDisconnected, ) { let _ = self.to_worker.unbounded_send(ServiceToWorkerMsg::Request { target, protocol: protocol.into(), request, + fallback_request, pending_response: tx, connect, }); @@ -1160,7 +1163,8 @@ enum ServiceToWorkerMsg { target: PeerId, protocol: ProtocolName, request: Vec, - pending_response: oneshot::Sender, RequestFailure>>, + fallback_request: Option<(Vec, ProtocolName)>, + pending_response: oneshot::Sender, ProtocolName), RequestFailure>>, connect: IfDisconnected, }, NetworkStatus { @@ -1287,13 +1291,15 @@ where target, protocol, request, + fallback_request, pending_response, connect, } => { self.network_service.behaviour_mut().send_request( &target, - &protocol, + protocol, request, + fallback_request, pending_response, connect, ); diff --git a/substrate/client/network/src/service/traits.rs b/substrate/client/network/src/service/traits.rs index d4d4a05a86f..74ddb986c24 100644 --- a/substrate/client/network/src/service/traits.rs +++ b/substrate/client/network/src/service/traits.rs @@ -551,8 +551,9 @@ pub trait NetworkRequest { target: PeerId, protocol: ProtocolName, request: Vec, + fallback_request: Option<(Vec, ProtocolName)>, connect: IfDisconnected, - ) -> Result, RequestFailure>; + ) -> Result<(Vec, ProtocolName), RequestFailure>; /// Variation of `request` which starts a request whose response is delivered on a provided /// channel. @@ -569,7 +570,8 @@ pub trait NetworkRequest { target: PeerId, protocol: ProtocolName, request: Vec, - tx: oneshot::Sender, RequestFailure>>, + fallback_request: Option<(Vec, ProtocolName)>, + tx: oneshot::Sender, ProtocolName), RequestFailure>>, connect: IfDisconnected, ); } @@ -585,13 +587,20 @@ where target: PeerId, protocol: ProtocolName, request: Vec, + fallback_request: Option<(Vec, ProtocolName)>, connect: IfDisconnected, - ) -> Pin, RequestFailure>> + Send + 'async_trait>> + ) -> Pin< + Box< + dyn Future, ProtocolName), RequestFailure>> + + Send + + 'async_trait, + >, + > where 'life0: 'async_trait, Self: 'async_trait, { - T::request(self, target, protocol, request, connect) + T::request(self, target, protocol, request, fallback_request, connect) } fn start_request( @@ -599,10 +608,11 @@ where target: PeerId, protocol: ProtocolName, request: Vec, - tx: oneshot::Sender, RequestFailure>>, + fallback_request: Option<(Vec, ProtocolName)>, + tx: oneshot::Sender, ProtocolName), RequestFailure>>, connect: IfDisconnected, ) { - T::start_request(self, target, protocol, request, tx, connect) + T::start_request(self, target, protocol, request, fallback_request, tx, connect) } } diff --git a/substrate/client/network/sync/src/block_relay_protocol.rs b/substrate/client/network/sync/src/block_relay_protocol.rs index 7a313458bf0..b4ef72a10c6 100644 --- a/substrate/client/network/sync/src/block_relay_protocol.rs +++ b/substrate/client/network/sync/src/block_relay_protocol.rs @@ -18,7 +18,10 @@ use futures::channel::oneshot; use libp2p::PeerId; -use sc_network::request_responses::{ProtocolConfig, RequestFailure}; +use sc_network::{ + request_responses::{ProtocolConfig, RequestFailure}, + ProtocolName, +}; use sc_network_common::sync::message::{BlockData, BlockRequest}; use sp_runtime::traits::Block as BlockT; use std::sync::Arc; @@ -43,7 +46,7 @@ pub trait BlockDownloader: Send + Sync { &self, who: PeerId, request: BlockRequest, - ) -> Result, RequestFailure>, oneshot::Canceled>; + ) -> Result, ProtocolName), RequestFailure>, oneshot::Canceled>; /// Parses the protocol specific response to retrieve the block data. fn block_response_into_blocks( diff --git a/substrate/client/network/sync/src/block_request_handler.rs b/substrate/client/network/sync/src/block_request_handler.rs index f363dda3a2d..f669a22cd2e 100644 --- a/substrate/client/network/sync/src/block_request_handler.rs +++ b/substrate/client/network/sync/src/block_request_handler.rs @@ -570,7 +570,7 @@ impl BlockDownloader for FullBlockDownloader { &self, who: PeerId, request: BlockRequest, - ) -> Result, RequestFailure>, oneshot::Canceled> { + ) -> Result, ProtocolName), RequestFailure>, oneshot::Canceled> { // Build the request protobuf. let bytes = BlockRequestSchema { fields: request.fields.to_be_u32(), diff --git a/substrate/client/network/sync/src/engine.rs b/substrate/client/network/sync/src/engine.rs index d7b024cd801..952300a14d8 100644 --- a/substrate/client/network/sync/src/engine.rs +++ b/substrate/client/network/sync/src/engine.rs @@ -1263,7 +1263,7 @@ where let ResponseEvent { peer_id, request, response } = response_event; match response { - Ok(Ok(resp)) => match request { + Ok(Ok((resp, _))) => match request { PeerRequest::Block(req) => { match self.block_downloader.block_response_into_blocks(&req, resp) { Ok(blocks) => { diff --git a/substrate/client/network/sync/src/mock.rs b/substrate/client/network/sync/src/mock.rs index 42220096e06..a4f5eb564c2 100644 --- a/substrate/client/network/sync/src/mock.rs +++ b/substrate/client/network/sync/src/mock.rs @@ -22,7 +22,7 @@ use crate::block_relay_protocol::{BlockDownloader as BlockDownloaderT, BlockResp use futures::channel::oneshot; use libp2p::PeerId; -use sc_network::RequestFailure; +use sc_network::{ProtocolName, RequestFailure}; use sc_network_common::sync::message::{BlockData, BlockRequest}; use sp_runtime::traits::Block as BlockT; @@ -35,7 +35,7 @@ mockall::mock! { &self, who: PeerId, request: BlockRequest, - ) -> Result, RequestFailure>, oneshot::Canceled>; + ) -> Result, ProtocolName), RequestFailure>, oneshot::Canceled>; fn block_response_into_blocks( &self, request: &BlockRequest, diff --git a/substrate/client/network/sync/src/pending_responses.rs b/substrate/client/network/sync/src/pending_responses.rs index 55308dfc1ea..e21a5763225 100644 --- a/substrate/client/network/sync/src/pending_responses.rs +++ b/substrate/client/network/sync/src/pending_responses.rs @@ -28,7 +28,7 @@ use futures::{ }; use libp2p::PeerId; use log::error; -use sc_network::request_responses::RequestFailure; +use sc_network::{request_responses::RequestFailure, types::ProtocolName}; use sp_runtime::traits::Block as BlockT; use std::task::{Context, Poll, Waker}; use tokio_stream::StreamMap; @@ -37,7 +37,7 @@ use tokio_stream::StreamMap; const LOG_TARGET: &'static str = "sync"; /// Response result. -type ResponseResult = Result, RequestFailure>, oneshot::Canceled>; +type ResponseResult = Result, ProtocolName), RequestFailure>, oneshot::Canceled>; /// A future yielding [`ResponseResult`]. type ResponseFuture = BoxFuture<'static, ResponseResult>; diff --git a/substrate/client/network/sync/src/service/mock.rs b/substrate/client/network/sync/src/service/mock.rs index 6e307d86984..420de8cd5fd 100644 --- a/substrate/client/network/sync/src/service/mock.rs +++ b/substrate/client/network/sync/src/service/mock.rs @@ -117,14 +117,16 @@ mockall::mock! { target: PeerId, protocol: ProtocolName, request: Vec, + fallback_request: Option<(Vec, ProtocolName)>, connect: IfDisconnected, - ) -> Result, RequestFailure>; + ) -> Result<(Vec, ProtocolName), RequestFailure>; fn start_request( &self, target: PeerId, protocol: ProtocolName, request: Vec, - tx: oneshot::Sender, RequestFailure>>, + fallback_request: Option<(Vec, ProtocolName)>, + tx: oneshot::Sender, ProtocolName), RequestFailure>>, connect: IfDisconnected, ); } diff --git a/substrate/client/network/sync/src/service/network.rs b/substrate/client/network/sync/src/service/network.rs index 12a47d6a9b5..07f28519afb 100644 --- a/substrate/client/network/sync/src/service/network.rs +++ b/substrate/client/network/sync/src/service/network.rs @@ -54,7 +54,7 @@ pub enum ToServiceCommand { PeerId, ProtocolName, Vec, - oneshot::Sender, RequestFailure>>, + oneshot::Sender, ProtocolName), RequestFailure>>, IfDisconnected, ), @@ -94,7 +94,7 @@ impl NetworkServiceHandle { who: PeerId, protocol: ProtocolName, request: Vec, - tx: oneshot::Sender, RequestFailure>>, + tx: oneshot::Sender, ProtocolName), RequestFailure>>, connect: IfDisconnected, ) { let _ = self @@ -134,7 +134,7 @@ impl NetworkServiceProvider { ToServiceCommand::ReportPeer(peer, reputation_change) => service.report_peer(peer, reputation_change), ToServiceCommand::StartRequest(peer, protocol, request, tx, connect) => - service.start_request(peer, protocol, request, tx, connect), + service.start_request(peer, protocol, request, None, tx, connect), ToServiceCommand::WriteNotification(peer, protocol, message) => service.write_notification(peer, protocol, message), ToServiceCommand::SetNotificationHandshake(protocol, handshake) => -- GitLab From 6a80c10a6fc345f96a504f11e99dfbd0ec1ed139 Mon Sep 17 00:00:00 2001 From: Marcin S Date: Wed, 10 Jan 2024 16:50:55 +0100 Subject: [PATCH 030/392] PVF: Remove artifact persistence across restarts (#2895) Considering the complexity of https://github.com/paritytech/polkadot-sdk/pull/2871 and the discussion therein, as well as the further complexity introduced by the hardening in https://github.com/paritytech/polkadot-sdk/pull/2742, as well as the eventual replacement of wasmtime by PolkaVM, it seems best to remove this persistence as it is creating more problems than it solves. ## Related Closes https://github.com/paritytech/polkadot-sdk/issues/2863 --- Cargo.lock | 2 +- polkadot/node/core/pvf/Cargo.toml | 1 + polkadot/node/core/pvf/common/Cargo.toml | 3 - polkadot/node/core/pvf/common/build.rs | 19 - polkadot/node/core/pvf/common/src/lib.rs | 2 - polkadot/node/core/pvf/src/artifacts.rs | 359 ++++-------------- polkadot/node/core/pvf/src/host.rs | 23 +- .../core/pvf/src/prepare/worker_interface.rs | 33 +- .../node/core/pvf/src/worker_interface.rs | 4 +- polkadot/node/core/pvf/tests/it/main.rs | 19 + .../utils/build-script-utils/src/version.rs | 31 -- 11 files changed, 117 insertions(+), 379 deletions(-) delete mode 100644 polkadot/node/core/pvf/common/build.rs diff --git a/Cargo.lock b/Cargo.lock index e00c173228f..6ac2fe567f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12671,6 +12671,7 @@ name = "polkadot-node-core-pvf" version = "1.0.0" dependencies = [ "always-assert", + "array-bytes 6.1.0", "assert_matches", "blake3", "cfg-if", @@ -12753,7 +12754,6 @@ dependencies = [ "sp-externalities 0.19.0", "sp-io", "sp-tracing 10.0.0", - "substrate-build-script-utils", "tempfile", "thiserror", "tracing-gum", diff --git a/polkadot/node/core/pvf/Cargo.toml b/polkadot/node/core/pvf/Cargo.toml index 2642377b6e6..be35dc47b8a 100644 --- a/polkadot/node/core/pvf/Cargo.toml +++ b/polkadot/node/core/pvf/Cargo.toml @@ -11,6 +11,7 @@ workspace = true [dependencies] always-assert = "0.1" +array-bytes = "6.1" blake3 = "1.5" cfg-if = "1.0" futures = "0.3.21" diff --git a/polkadot/node/core/pvf/common/Cargo.toml b/polkadot/node/core/pvf/common/Cargo.toml index c5c09300e8a..974965be593 100644 --- a/polkadot/node/core/pvf/common/Cargo.toml +++ b/polkadot/node/core/pvf/common/Cargo.toml @@ -39,9 +39,6 @@ seccompiler = "0.4.0" assert_matches = "1.4.0" tempfile = "3.3.0" -[build-dependencies] -substrate-build-script-utils = { path = "../../../../../substrate/utils/build-script-utils" } - [features] # This feature is used to export test code to other crates without putting it in the production build. test-utils = [] diff --git a/polkadot/node/core/pvf/common/build.rs b/polkadot/node/core/pvf/common/build.rs deleted file mode 100644 index 5531ad411da..00000000000 --- a/polkadot/node/core/pvf/common/build.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Polkadot. - -// Polkadot is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Polkadot is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Polkadot. If not, see . - -fn main() { - substrate_build_script_utils::generate_wasmtime_version(); -} diff --git a/polkadot/node/core/pvf/common/src/lib.rs b/polkadot/node/core/pvf/common/src/lib.rs index abebd06f71a..af4a7526e55 100644 --- a/polkadot/node/core/pvf/common/src/lib.rs +++ b/polkadot/node/core/pvf/common/src/lib.rs @@ -31,8 +31,6 @@ pub use sp_tracing; const LOG_TARGET: &str = "parachain::pvf-common"; -pub const RUNTIME_VERSION: &str = env!("SUBSTRATE_WASMTIME_VERSION"); - use parity_scale_codec::{Decode, Encode}; use std::{ io::{self, Read, Write}, diff --git a/polkadot/node/core/pvf/src/artifacts.rs b/polkadot/node/core/pvf/src/artifacts.rs index 17ce5b443e3..78dfe71adad 100644 --- a/polkadot/node/core/pvf/src/artifacts.rs +++ b/polkadot/node/core/pvf/src/artifacts.rs @@ -18,8 +18,7 @@ //! //! # Lifecycle of an artifact //! -//! 1. During node start-up, we will check the cached artifacts, if any. The stale and corrupted -//! ones are pruned. The valid ones are registered in the [`Artifacts`] table. +//! 1. During node start-up, we prune all the cached artifacts, if any. //! //! 2. In order to be executed, a PVF should be prepared first. This means that artifacts should //! have an [`ArtifactState::Prepared`] entry for that artifact in the table. If not, the @@ -55,28 +54,35 @@ //! older by a predefined parameter. This process is run very rarely (say, once a day). Once the //! artifact is expired it is removed from disk eagerly atomically. -use crate::{host::PrecheckResultSender, LOG_TARGET}; +use crate::{host::PrecheckResultSender, worker_interface::WORKER_DIR_PREFIX}; use always_assert::always; -use polkadot_core_primitives::Hash; -use polkadot_node_core_pvf_common::{ - error::PrepareError, prepare::PrepareStats, pvf::PvfPrepData, RUNTIME_VERSION, -}; -use polkadot_node_primitives::NODE_VERSION; +use polkadot_node_core_pvf_common::{error::PrepareError, prepare::PrepareStats, pvf::PvfPrepData}; use polkadot_parachain_primitives::primitives::ValidationCodeHash; use polkadot_primitives::ExecutorParamsHash; use std::{ collections::HashMap, - io, + fs, path::{Path, PathBuf}, - str::FromStr as _, time::{Duration, SystemTime}, }; -const RUNTIME_PREFIX: &str = "wasmtime_v"; -const NODE_PREFIX: &str = "polkadot_v"; +/// The extension to use for cached artifacts. +const ARTIFACT_EXTENSION: &str = "pvf"; + +/// The prefix that artifacts used to start with under the old naming scheme. +const ARTIFACT_OLD_PREFIX: &str = "wasmtime_"; -fn artifact_prefix() -> String { - format!("{}{}_{}{}", RUNTIME_PREFIX, RUNTIME_VERSION, NODE_PREFIX, NODE_VERSION) +pub fn generate_artifact_path(cache_path: &Path) -> PathBuf { + let file_name = { + use array_bytes::Hex; + use rand::RngCore; + let mut bytes = [0u8; 64]; + rand::thread_rng().fill_bytes(&mut bytes); + bytes.hex("0x") + }; + let mut artifact_path = cache_path.join(file_name); + artifact_path.set_extension(ARTIFACT_EXTENSION); + artifact_path } /// Identifier of an artifact. Encodes a code hash of the PVF and a hash of executor parameter set. @@ -96,35 +102,6 @@ impl ArtifactId { pub fn from_pvf_prep_data(pvf: &PvfPrepData) -> Self { Self::new(pvf.code_hash(), pvf.executor_params().hash()) } - - /// Returns the canonical path to the concluded artifact. - pub(crate) fn path(&self, cache_path: &Path, checksum: &str) -> PathBuf { - let file_name = format!( - "{}_{:#x}_{:#x}_0x{}", - artifact_prefix(), - self.code_hash, - self.executor_params_hash, - checksum - ); - cache_path.join(file_name) - } - - /// Tries to recover the artifact id from the given file name. - /// Return `None` if the given file name is invalid. - /// VALID_NAME := _ _ _ - fn from_file_name(file_name: &str) -> Option { - let file_name = file_name.strip_prefix(&artifact_prefix())?.strip_prefix('_')?; - let parts: Vec<&str> = file_name.split('_').collect(); - - if let [code_hash, param_hash, _checksum] = parts[..] { - let code_hash = Hash::from_str(code_hash).ok()?.into(); - let executor_params_hash = - ExecutorParamsHash::from_hash(Hash::from_str(param_hash).ok()?); - return Some(Self { code_hash, executor_params_hash }) - } - - None - } } /// A bundle of the artifact ID and the path. @@ -194,120 +171,31 @@ impl Artifacts { } #[cfg(test)] - pub(crate) fn len(&self) -> usize { + fn len(&self) -> usize { self.inner.len() } - /// Create an empty table and populate it with valid artifacts as [`ArtifactState::Prepared`], - /// if any. The existing caches will be checked by their file name to determine whether they are - /// valid, e.g., matching the current node version. The ones deemed invalid will be pruned. - /// - /// Create the cache directory on-disk if it doesn't exist. - pub async fn new_and_prune(cache_path: &Path) -> Self { - let mut artifacts = Self { inner: HashMap::new() }; - let _ = artifacts.insert_and_prune(cache_path).await.map_err(|err| { - gum::error!( - target: LOG_TARGET, - "could not initialize artifacts cache: {err}", - ) - }); - artifacts - } - - async fn insert_and_prune(&mut self, cache_path: &Path) -> Result<(), String> { - async fn is_corrupted(path: &Path) -> bool { - let checksum = match tokio::fs::read(path).await { - Ok(bytes) => blake3::hash(&bytes), - Err(err) => { - // just remove the file if we cannot read it - gum::warn!( - target: LOG_TARGET, - ?err, - "unable to read artifact {:?} when checking integrity, removing...", - path, - ); - return true - }, - }; - - if let Some(file_name) = path.file_name() { - if let Some(file_name) = file_name.to_str() { - return !file_name.ends_with(checksum.to_hex().as_str()) - } - } - true - } - - // Insert the entry into the artifacts table if it is valid. - // Otherwise, prune it. - async fn insert_or_prune( - artifacts: &mut Artifacts, - entry: &tokio::fs::DirEntry, - cache_path: &Path, - ) -> Result<(), String> { - let file_type = entry.file_type().await; - let file_name = entry.file_name(); - - match file_type { - Ok(file_type) => - if !file_type.is_file() { - return Ok(()) - }, - Err(err) => return Err(format!("unable to get file type for {file_name:?}: {err}")), - } - - if let Some(file_name) = file_name.to_str() { - let id = ArtifactId::from_file_name(file_name); - let path = cache_path.join(file_name); - - if id.is_none() || is_corrupted(&path).await { - let _ = tokio::fs::remove_file(&path).await; - return Err(format!("invalid artifact {path:?}, file deleted")) - } - - let id = id.expect("checked is_none() above; qed"); - gum::debug!( - target: LOG_TARGET, - "reusing existing {:?} for node version v{}", - &path, - NODE_VERSION, - ); - artifacts.insert_prepared(id, path, SystemTime::now(), Default::default()); - - Ok(()) - } else { - Err(format!("non-Unicode file name {file_name:?} found in {cache_path:?}")) - } - } - + /// Create an empty table and the cache directory on-disk if it doesn't exist. + pub async fn new(cache_path: &Path) -> Self { // Make sure that the cache path directory and all its parents are created. - if let Err(err) = tokio::fs::create_dir_all(cache_path).await { - if err.kind() != io::ErrorKind::AlreadyExists { - return Err(format!("failed to create dir {cache_path:?}: {err}")) + let _ = tokio::fs::create_dir_all(cache_path).await; + + // Delete any leftover artifacts and worker dirs from previous runs. We don't delete the + // entire cache directory in case the user made a mistake and set it to e.g. their home + // directory. This is a best-effort to do clean-up, so ignore any errors. + for entry in fs::read_dir(cache_path).into_iter().flatten().flatten() { + let path = entry.path(); + let Some(file_name) = path.file_name().and_then(|f| f.to_str()) else { continue }; + if path.is_dir() && file_name.starts_with(WORKER_DIR_PREFIX) { + let _ = fs::remove_dir_all(path); + } else if path.extension().map_or(false, |ext| ext == ARTIFACT_EXTENSION) || + file_name.starts_with(ARTIFACT_OLD_PREFIX) + { + let _ = fs::remove_file(path); } } - let mut dir = tokio::fs::read_dir(cache_path) - .await - .map_err(|err| format!("failed to read dir {cache_path:?}: {err}"))?; - - loop { - match dir.next_entry().await { - Ok(Some(entry)) => - if let Err(err) = insert_or_prune(self, &entry, cache_path).await { - gum::warn!( - target: LOG_TARGET, - ?cache_path, - "could not insert entry {:?} into the artifact cache: {}", - entry, - err, - ) - }, - Ok(None) => return Ok(()), - Err(err) => - return Err(format!("error processing artifacts in {cache_path:?}: {err}")), - } - } + Self { inner: HashMap::new() } } /// Returns the state of the given artifact by its ID. @@ -335,6 +223,7 @@ impl Artifacts { /// /// This function should only be used to build the artifact table at startup with valid /// artifact caches. + #[cfg(test)] pub(crate) fn insert_prepared( &mut self, artifact_id: ArtifactId, @@ -376,151 +265,33 @@ impl Artifacts { #[cfg(test)] mod tests { - use super::{artifact_prefix as prefix, ArtifactId, Artifacts, NODE_VERSION, RUNTIME_VERSION}; - use polkadot_primitives::ExecutorParamsHash; - use rand::Rng; - use sp_core::H256; - use std::{ - fs, - io::Write, - path::{Path, PathBuf}, - str::FromStr, - }; - - fn rand_hash(len: usize) -> String { - let mut rng = rand::thread_rng(); - let hex: Vec<_> = "0123456789abcdef".chars().collect(); - (0..len).map(|_| hex[rng.gen_range(0..hex.len())]).collect() - } - - fn file_name(code_hash: &str, param_hash: &str, checksum: &str) -> String { - format!("{}_0x{}_0x{}_0x{}", prefix(), code_hash, param_hash, checksum) - } - - fn create_artifact( - dir: impl AsRef, - prefix: &str, - code_hash: impl AsRef, - params_hash: impl AsRef, - ) -> (PathBuf, String) { - fn artifact_path_without_checksum( - dir: impl AsRef, - prefix: &str, - code_hash: impl AsRef, - params_hash: impl AsRef, - ) -> PathBuf { - let mut path = dir.as_ref().to_path_buf(); - let file_name = - format!("{}_0x{}_0x{}", prefix, code_hash.as_ref(), params_hash.as_ref(),); - path.push(file_name); - path - } - - let (code_hash, params_hash) = (code_hash.as_ref(), params_hash.as_ref()); - let path = artifact_path_without_checksum(dir, prefix, code_hash, params_hash); - let mut file = fs::File::create(&path).unwrap(); - - let content = format!("{}{}", code_hash, params_hash).into_bytes(); - file.write_all(&content).unwrap(); - let checksum = blake3::hash(&content).to_hex().to_string(); - - (path, checksum) - } - - fn create_rand_artifact(dir: impl AsRef, prefix: &str) -> (PathBuf, String) { - create_artifact(dir, prefix, rand_hash(64), rand_hash(64)) - } - - fn concluded_path(path: impl AsRef, checksum: &str) -> PathBuf { - let path = path.as_ref(); - let mut file_name = path.file_name().unwrap().to_os_string(); - file_name.push("_0x"); - file_name.push(checksum); - path.with_file_name(file_name) - } - - #[test] - fn artifact_prefix() { - assert_eq!(prefix(), format!("wasmtime_v{}_polkadot_v{}", RUNTIME_VERSION, NODE_VERSION)); - } - - #[test] - fn from_file_name() { - assert!(ArtifactId::from_file_name("").is_none()); - assert!(ArtifactId::from_file_name("junk").is_none()); - - let file_name = file_name( - "0022800000000000000000000000000000000000000000000000000000000000", - "0033900000000000000000000000000000000000000000000000000000000000", - "00000000000000000000000000000000", - ); - - assert_eq!( - ArtifactId::from_file_name(&file_name), - Some(ArtifactId::new( - hex_literal::hex![ - "0022800000000000000000000000000000000000000000000000000000000000" - ] - .into(), - ExecutorParamsHash::from_hash(sp_core::H256(hex_literal::hex![ - "0033900000000000000000000000000000000000000000000000000000000000" - ])), - )), - ); - } - - #[test] - fn path() { - let dir = Path::new("/test"); - let code_hash = "1234567890123456789012345678901234567890123456789012345678901234"; - let params_hash = "4321098765432109876543210987654321098765432109876543210987654321"; - let checksum = "34567890123456789012345678901234"; - let file_name = file_name(code_hash, params_hash, checksum); - - let code_hash = H256::from_str(code_hash).unwrap(); - let params_hash = H256::from_str(params_hash).unwrap(); - let path = ArtifactId::new(code_hash.into(), ExecutorParamsHash::from_hash(params_hash)) - .path(dir, checksum); - - assert_eq!(path.to_str().unwrap(), format!("/test/{}", file_name)); - } + use super::*; #[tokio::test] - async fn remove_stale_cache_on_startup() { - let cache_dir = tempfile::Builder::new().prefix("test-cache-").tempdir().unwrap(); - - // invalid prefix - create_rand_artifact(&cache_dir, ""); - create_rand_artifact(&cache_dir, "wasmtime_polkadot_v"); - create_rand_artifact(&cache_dir, "wasmtime_v8.0.0_polkadot_v1.0.0"); - - let prefix = prefix(); - - // no checksum - create_rand_artifact(&cache_dir, &prefix); - - // invalid hashes - let (path, checksum) = create_artifact(&cache_dir, &prefix, "000", "000001"); - let new_path = concluded_path(&path, &checksum); - fs::rename(&path, &new_path).unwrap(); - - // checksum tampered - let (path, checksum) = create_rand_artifact(&cache_dir, &prefix); - let new_path = concluded_path(&path, checksum.chars().rev().collect::().as_str()); - fs::rename(&path, &new_path).unwrap(); - - // valid - let (path, checksum) = create_rand_artifact(&cache_dir, &prefix); - let new_path = concluded_path(&path, &checksum); - fs::rename(&path, &new_path).unwrap(); - - assert_eq!(fs::read_dir(&cache_dir).unwrap().count(), 7); - - let artifacts = Artifacts::new_and_prune(cache_dir.path()).await; - - assert_eq!(fs::read_dir(&cache_dir).unwrap().count(), 1); - assert_eq!(artifacts.len(), 1); - - fs::remove_dir_all(cache_dir).unwrap(); + async fn cache_cleared_on_startup() { + let tempdir = tempfile::tempdir().unwrap(); + let cache_path = tempdir.path(); + + // These should be cleared. + fs::write(cache_path.join("abcd.pvf"), "test").unwrap(); + fs::write(cache_path.join("wasmtime_..."), "test").unwrap(); + fs::create_dir(cache_path.join("worker-dir-prepare-test")).unwrap(); + + // These should not be touched. + fs::write(cache_path.join("abcd.pvfartifact"), "test").unwrap(); + fs::write(cache_path.join("polkadot_..."), "test").unwrap(); + fs::create_dir(cache_path.join("worker-prepare-test")).unwrap(); + + let artifacts = Artifacts::new(cache_path).await; + + let entries: Vec = fs::read_dir(&cache_path) + .unwrap() + .map(|entry| entry.unwrap().file_name().into_string().unwrap()) + .collect(); + assert_eq!(entries.len(), 3); + assert!(entries.contains(&String::from("abcd.pvfartifact"))); + assert!(entries.contains(&String::from("polkadot_..."))); + assert!(entries.contains(&String::from("worker-prepare-test"))); + assert_eq!(artifacts.len(), 0); } } diff --git a/polkadot/node/core/pvf/src/host.rs b/polkadot/node/core/pvf/src/host.rs index d17a4d918e0..21e13453edf 100644 --- a/polkadot/node/core/pvf/src/host.rs +++ b/polkadot/node/core/pvf/src/host.rs @@ -218,7 +218,7 @@ pub async fn start( gum::debug!(target: LOG_TARGET, ?config, "starting PVF validation host"); // Make sure the cache is initialized before doing anything else. - let artifacts = Artifacts::new_and_prune(&config.cache_path).await; + let artifacts = Artifacts::new(&config.cache_path).await; // Run checks for supported security features once per host startup. If some checks fail, warn // if Secure Validator Mode is disabled and return an error otherwise. @@ -884,14 +884,13 @@ fn pulse_every(interval: std::time::Duration) -> impl futures::Stream #[cfg(test)] pub(crate) mod tests { use super::*; - use crate::PossiblyInvalidError; + use crate::{artifacts::generate_artifact_path, PossiblyInvalidError}; use assert_matches::assert_matches; use futures::future::BoxFuture; use polkadot_node_core_pvf_common::{ error::PrepareError, prepare::{PrepareStats, PrepareSuccess}, }; - use sp_core::hexdisplay::AsBytesRef; const TEST_EXECUTION_TIMEOUT: Duration = Duration::from_secs(3); pub(crate) const TEST_PREPARATION_TIMEOUT: Duration = Duration::from_secs(30); @@ -915,14 +914,6 @@ pub(crate) mod tests { ArtifactId::from_pvf_prep_data(&PvfPrepData::from_discriminator(discriminator)) } - fn artifact_path(discriminator: u32) -> PathBuf { - let pvf = PvfPrepData::from_discriminator(discriminator); - let checksum = blake3::hash(pvf.code().as_bytes_ref()); - artifact_id(discriminator) - .path(&PathBuf::from(std::env::temp_dir()), checksum.to_hex().as_str()) - .to_owned() - } - struct Builder { cleanup_pulse_interval: Duration, artifact_ttl: Duration, @@ -1110,19 +1101,23 @@ pub(crate) mod tests { #[tokio::test] async fn pruning() { let mock_now = SystemTime::now() - Duration::from_millis(1000); + let tempdir = tempfile::tempdir().unwrap(); + let cache_path = tempdir.path(); let mut builder = Builder::default(); builder.cleanup_pulse_interval = Duration::from_millis(100); builder.artifact_ttl = Duration::from_millis(500); + let path1 = generate_artifact_path(cache_path); + let path2 = generate_artifact_path(cache_path); builder.artifacts.insert_prepared( artifact_id(1), - artifact_path(1), + path1.clone(), mock_now, PrepareStats::default(), ); builder.artifacts.insert_prepared( artifact_id(2), - artifact_path(2), + path2.clone(), mock_now, PrepareStats::default(), ); @@ -1135,7 +1130,7 @@ pub(crate) mod tests { run_until( &mut test.run, async { - assert_eq!(to_sweeper_rx.next().await.unwrap(), artifact_path(2)); + assert_eq!(to_sweeper_rx.next().await.unwrap(), path2); } .boxed(), ) diff --git a/polkadot/node/core/pvf/src/prepare/worker_interface.rs b/polkadot/node/core/pvf/src/prepare/worker_interface.rs index 984a87ce5c9..45e31a5f453 100644 --- a/polkadot/node/core/pvf/src/prepare/worker_interface.rs +++ b/polkadot/node/core/pvf/src/prepare/worker_interface.rs @@ -17,7 +17,7 @@ //! Host interface to the prepare worker. use crate::{ - artifacts::ArtifactId, + artifacts::generate_artifact_path, metrics::Metrics, worker_interface::{ clear_worker_dir_path, framed_recv, framed_send, spawn_with_program_path, IdleWorker, @@ -165,7 +165,6 @@ pub async fn start_work( prepare_worker_result, pid, tmp_artifact_file, - &pvf, &cache_path, preparation_timeout, ) @@ -205,19 +204,22 @@ async fn handle_response( result: PrepareWorkerResult, worker_pid: u32, tmp_file: PathBuf, - pvf: &PvfPrepData, cache_path: &Path, preparation_timeout: Duration, ) -> Outcome { - let PrepareWorkerSuccess { checksum, stats: PrepareStats { cpu_time_elapsed, memory_stats } } = - match result.clone() { - Ok(result) => result, - // Timed out on the child. This should already be logged by the child. - Err(PrepareError::TimedOut) => return Outcome::TimedOut, - Err(PrepareError::JobDied { err, job_pid }) => return Outcome::JobDied { err, job_pid }, - Err(PrepareError::OutOfMemory) => return Outcome::OutOfMemory, - Err(err) => return Outcome::Concluded { worker, result: Err(err) }, - }; + // TODO: Add `checksum` to `ArtifactPathId`. See: + // https://github.com/paritytech/polkadot-sdk/issues/2399 + let PrepareWorkerSuccess { + checksum: _, + stats: PrepareStats { cpu_time_elapsed, memory_stats }, + } = match result.clone() { + Ok(result) => result, + // Timed out on the child. This should already be logged by the child. + Err(PrepareError::TimedOut) => return Outcome::TimedOut, + Err(PrepareError::JobDied { err, job_pid }) => return Outcome::JobDied { err, job_pid }, + Err(PrepareError::OutOfMemory) => return Outcome::OutOfMemory, + Err(err) => return Outcome::Concluded { worker, result: Err(err) }, + }; if cpu_time_elapsed > preparation_timeout { // The job didn't complete within the timeout. @@ -232,8 +234,11 @@ async fn handle_response( return Outcome::TimedOut } - let artifact_id = ArtifactId::from_pvf_prep_data(pvf); - let artifact_path = artifact_id.path(cache_path, &checksum); + // The file name should uniquely identify the artifact even across restarts. In case the cache + // for some reason is not cleared correctly, we cannot + // accidentally execute an artifact compiled under a different wasmtime version, host + // environment, etc. + let artifact_path = generate_artifact_path(cache_path); gum::debug!( target: LOG_TARGET, diff --git a/polkadot/node/core/pvf/src/worker_interface.rs b/polkadot/node/core/pvf/src/worker_interface.rs index 456c20bd27b..ad9f0294c09 100644 --- a/polkadot/node/core/pvf/src/worker_interface.rs +++ b/polkadot/node/core/pvf/src/worker_interface.rs @@ -384,10 +384,12 @@ pub struct WorkerDir { tempdir: tempfile::TempDir, } +pub const WORKER_DIR_PREFIX: &str = "worker-dir"; + impl WorkerDir { /// Creates a new, empty worker dir with a random name in the given cache dir. pub async fn new(debug_id: &'static str, cache_dir: &Path) -> Result { - let prefix = format!("worker-dir-{}-", debug_id); + let prefix = format!("{WORKER_DIR_PREFIX}-{debug_id}-"); let tempdir = tempfile::Builder::new() .prefix(&prefix) .tempdir_in(cache_dir) diff --git a/polkadot/node/core/pvf/tests/it/main.rs b/polkadot/node/core/pvf/tests/it/main.rs index 09f975b706d..15b341dc094 100644 --- a/polkadot/node/core/pvf/tests/it/main.rs +++ b/polkadot/node/core/pvf/tests/it/main.rs @@ -358,6 +358,25 @@ async fn deleting_prepared_artifact_does_not_dispute() { } } +#[tokio::test] +async fn cache_cleared_on_startup() { + // Don't drop this host, it owns the `TempDir` which gets cleared on drop. + let host = TestHost::new().await; + + let _stats = host.precheck_pvf(halt::wasm_binary_unwrap(), Default::default()).await.unwrap(); + + // The cache dir should contain one artifact and one worker dir. + let cache_dir = host.cache_dir.path().to_owned(); + assert_eq!(std::fs::read_dir(&cache_dir).unwrap().count(), 2); + + // Start a new host, previous artifact should be cleared. + let _host = TestHost::new_with_config(|cfg| { + cfg.cache_path = cache_dir.clone(); + }) + .await; + assert_eq!(std::fs::read_dir(&cache_dir).unwrap().count(), 0); +} + // This test checks if the adder parachain runtime can be prepared with 10Mb preparation memory // limit enforced. At the moment of writing, the limit if far enough to prepare the PVF. If it // starts failing, either Wasmtime version has changed, or the PVF code itself has changed, and diff --git a/substrate/utils/build-script-utils/src/version.rs b/substrate/utils/build-script-utils/src/version.rs index d85c78d2c99..cc6b4319eca 100644 --- a/substrate/utils/build-script-utils/src/version.rs +++ b/substrate/utils/build-script-utils/src/version.rs @@ -59,34 +59,3 @@ fn get_version(impl_commit: &str) -> String { impl_commit ) } - -/// Generate `SUBSTRATE_WASMTIME_VERSION` -pub fn generate_wasmtime_version() { - generate_dependency_version("wasmtime", "SUBSTRATE_WASMTIME_VERSION"); -} - -fn generate_dependency_version(dep: &str, env_var: &str) { - // we only care about the root - match std::process::Command::new("cargo") - .args(["tree", "--depth=0", "--locked", "--package", dep]) - .output() - { - Ok(output) if output.status.success() => { - let version = String::from_utf8_lossy(&output.stdout); - - // vX.X.X - if let Some(ver) = version.strip_prefix(&format!("{} v", dep)) { - println!("cargo:rustc-env={}={}", env_var, ver); - } else { - println!("cargo:warning=Unexpected result {}", version); - } - }, - - // command errors out when it could not find the given dependency - // or when having multiple versions of it - Ok(output) => - println!("cargo:warning=`cargo tree` {}", String::from_utf8_lossy(&output.stderr)), - - Err(err) => println!("cargo:warning=Could not run `cargo tree`: {}", err), - } -} -- GitLab From bab0348372b58d5106333faa597423242e831a31 Mon Sep 17 00:00:00 2001 From: Clara van Staden Date: Wed, 10 Jan 2024 18:51:27 +0200 Subject: [PATCH 031/392] Update Snowbridge versions and prep for publishing (#2894) - updates snowbridge crates to `0.9.0` - updates Cargo.toml files in preparation for publishing to crates.io - adds Kusama and Polkadot Snowbridge runtime config crates - moves runtime tests from the Snowbridge subtree into the bridge hub tests dir --------- Co-authored-by: claravanstaden Co-authored-by: Ron --- Cargo.lock | 164 ++++++++---------- Cargo.toml | 5 +- .../Cargo.toml | 14 +- .../pallets/ethereum-client/README.md | 3 + .../benchmark.md | 16 +- .../src/benchmarking/fixtures_mainnet.rs | 0 .../src/benchmarking/fixtures_minimal.rs | 0 .../src/benchmarking/mod.rs | 0 .../src/benchmarking/util.rs | 0 .../src/config/mainnet.rs | 0 .../src/config/minimal.rs | 0 .../src/config/mod.rs | 0 .../src/functions.rs | 0 .../src/impls.rs | 12 +- .../src/lib.rs | 4 +- .../src/mock.rs | 29 +--- .../src/tests.rs | 0 .../src/types.rs | 0 .../src/weights.rs | 2 +- .../execution-header-update.mainnet.json | 0 .../execution-header-update.minimal.json | 0 .../finalized-header-update.mainnet.json | 0 .../finalized-header-update.minimal.json | 0 .../fixtures/initial-checkpoint.mainnet.json | 0 .../fixtures/initial-checkpoint.minimal.json | 0 .../next-finalized-header-update.mainnet.json | 0 .../next-finalized-header-update.minimal.json | 0 .../next-sync-committee-update.mainnet.json | 0 .../next-sync-committee-update.minimal.json | 0 .../sync-committee-update.mainnet.json | 0 .../sync-committee-update.minimal.json | 0 .../pallets/inbound-queue/Cargo.toml | 23 ++- .../parachain/pallets/inbound-queue/README.md | 3 + .../pallets/inbound-queue/src/lib.rs | 52 ++++-- .../pallets/inbound-queue/src/mock.rs | 52 +++++- .../pallets/inbound-queue/src/test.rs | 1 + .../pallets/outbound-queue/Cargo.toml | 14 +- .../pallets/outbound-queue/README.md | 3 + .../outbound-queue/merkle-tree/Cargo.toml | 10 +- .../outbound-queue/merkle-tree/README.md | 4 + .../outbound-queue/runtime-api/Cargo.toml | 10 +- .../outbound-queue/runtime-api/README.md | 6 + .../pallets/outbound-queue/src/lib.rs | 4 +- .../pallets/outbound-queue/src/test.rs | 4 +- .../pallets/outbound-queue/src/weights.rs | 6 +- .../parachain/pallets/system/Cargo.toml | 20 ++- .../parachain/pallets/system/README.md | 4 +- .../pallets/system/runtime-api/Cargo.toml | 10 +- .../pallets/system/runtime-api/README.md | 3 + .../parachain/pallets/system/src/lib.rs | 2 + .../parachain/pallets/system/src/mock.rs | 4 +- .../parachain/primitives/beacon/Cargo.toml | 9 +- .../parachain/primitives/beacon/README.md | 10 ++ .../parachain/primitives/core/Cargo.toml | 9 +- .../parachain/primitives/core/README.md | 4 + .../parachain/primitives/ethereum/Cargo.toml | 9 +- .../parachain/primitives/ethereum/README.md | 4 + .../parachain/primitives/router/Cargo.toml | 9 +- .../parachain/primitives/router/README.md | 4 + .../runtime/rococo-common/Cargo.toml | 26 --- .../runtime/rococo-common/src/lib.rs | 16 -- .../runtime/runtime-common/Cargo.toml | 9 +- .../runtime/runtime-common/README.md | 3 + .../runtime/{tests => test-common}/Cargo.toml | 81 ++------- .../parachain/runtime/test-common/README.md | 3 + .../test_cases.rs => test-common/src/lib.rs} | 49 +++--- .../snowbridge/parachain/scripts/benchmark.sh | 4 +- .../parachain/scripts/verify-pallets-build.sh | 26 +-- cumulus/parachains/common/src/rococo.rs | 16 ++ .../bridges/bridge-hub-rococo/Cargo.toml | 6 +- .../bridges/bridge-hub-rococo/Cargo.toml | 7 +- .../bridge-hub-rococo/src/tests/snowbridge.rs | 15 +- .../assets/asset-hub-rococo/Cargo.toml | 3 - .../assets/asset-hub-rococo/src/lib.rs | 2 +- .../assets/asset-hub-rococo/src/xcm_config.rs | 4 +- .../bridge-hubs/bridge-hub-rococo/Cargo.toml | 39 ++--- .../src/bridge_to_ethereum_config.rs | 4 +- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 107 +++++++----- .../bridge-hub-rococo/src/weights/mod.rs | 8 +- ...s => snowbridge_pallet_ethereum_client.rs} | 6 +- ....rs => snowbridge_pallet_inbound_queue.rs} | 6 +- ...rs => snowbridge_pallet_outbound_queue.rs} | 2 +- ..._system.rs => snowbridge_pallet_system.rs} | 6 +- .../bridge-hub-rococo/src/xcm_config.rs | 29 +--- .../bridge-hub-rococo/tests/snowbridge.rs | 43 +++-- .../bridge-hubs/common/src/message_queue.rs | 2 +- .../runtimes/testing/penpal/Cargo.toml | 3 - .../runtimes/testing/penpal/src/xcm_config.rs | 2 +- 88 files changed, 579 insertions(+), 490 deletions(-) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/Cargo.toml (93%) create mode 100644 bridges/snowbridge/parachain/pallets/ethereum-client/README.md rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/benchmark.md (88%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/src/benchmarking/fixtures_mainnet.rs (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/src/benchmarking/fixtures_minimal.rs (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/src/benchmarking/mod.rs (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/src/benchmarking/util.rs (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/src/config/mainnet.rs (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/src/config/minimal.rs (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/src/config/mod.rs (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/src/functions.rs (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/src/impls.rs (91%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/src/lib.rs (99%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/src/mock.rs (92%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/src/tests.rs (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/src/types.rs (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/src/weights.rs (97%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/tests/fixtures/execution-header-update.mainnet.json (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/tests/fixtures/execution-header-update.minimal.json (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/tests/fixtures/finalized-header-update.mainnet.json (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/tests/fixtures/finalized-header-update.minimal.json (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/tests/fixtures/initial-checkpoint.mainnet.json (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/tests/fixtures/initial-checkpoint.minimal.json (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/tests/fixtures/next-finalized-header-update.mainnet.json (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/tests/fixtures/next-finalized-header-update.minimal.json (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/tests/fixtures/next-sync-committee-update.mainnet.json (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/tests/fixtures/next-sync-committee-update.minimal.json (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/tests/fixtures/sync-committee-update.mainnet.json (100%) rename bridges/snowbridge/parachain/pallets/{ethereum-beacon-client => ethereum-client}/tests/fixtures/sync-committee-update.minimal.json (100%) create mode 100644 bridges/snowbridge/parachain/pallets/inbound-queue/README.md create mode 100644 bridges/snowbridge/parachain/pallets/outbound-queue/README.md create mode 100644 bridges/snowbridge/parachain/pallets/outbound-queue/merkle-tree/README.md create mode 100644 bridges/snowbridge/parachain/pallets/outbound-queue/runtime-api/README.md create mode 100644 bridges/snowbridge/parachain/pallets/system/runtime-api/README.md create mode 100644 bridges/snowbridge/parachain/primitives/beacon/README.md create mode 100644 bridges/snowbridge/parachain/primitives/core/README.md create mode 100644 bridges/snowbridge/parachain/primitives/ethereum/README.md create mode 100644 bridges/snowbridge/parachain/primitives/router/README.md delete mode 100644 bridges/snowbridge/parachain/runtime/rococo-common/Cargo.toml delete mode 100644 bridges/snowbridge/parachain/runtime/rococo-common/src/lib.rs create mode 100644 bridges/snowbridge/parachain/runtime/runtime-common/README.md rename bridges/snowbridge/parachain/runtime/{tests => test-common}/Cargo.toml (78%) create mode 100644 bridges/snowbridge/parachain/runtime/test-common/README.md rename bridges/snowbridge/parachain/runtime/{tests/src/test_cases.rs => test-common/src/lib.rs} (88%) rename cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/{snowbridge_ethereum_beacon_client.rs => snowbridge_pallet_ethereum_client.rs} (97%) rename cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/{snowbridge_inbound_queue.rs => snowbridge_pallet_inbound_queue.rs} (92%) rename cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/{snowbridge_outbound_queue.rs => snowbridge_pallet_outbound_queue.rs} (97%) rename cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/{snowbridge_system.rs => snowbridge_pallet_system.rs} (98%) rename bridges/snowbridge/parachain/runtime/tests/src/lib.rs => cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs (55%) diff --git a/Cargo.lock b/Cargo.lock index 6ac2fe567f9..13b90eafa75 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -907,7 +907,6 @@ dependencies = [ "rococo-runtime-constants", "scale-info", "smallvec", - "snowbridge-rococo-common", "snowbridge-router-primitives", "sp-api", "sp-block-builder", @@ -1952,10 +1951,10 @@ dependencies = [ "parachains-common", "serde_json", "snowbridge-core", - "snowbridge-inbound-queue", - "snowbridge-outbound-queue", + "snowbridge-pallet-inbound-queue", + "snowbridge-pallet-outbound-queue", + "snowbridge-pallet-system", "snowbridge-router-primitives", - "snowbridge-system", "sp-core", "sp-runtime", ] @@ -1986,11 +1985,10 @@ dependencies = [ "rococo-westend-system-emulated-network", "scale-info", "snowbridge-core", - "snowbridge-inbound-queue", - "snowbridge-outbound-queue", - "snowbridge-rococo-common", + "snowbridge-pallet-inbound-queue", + "snowbridge-pallet-outbound-queue", + "snowbridge-pallet-system", "snowbridge-router-primitives", - "snowbridge-system", "sp-core", "sp-runtime", "staging-xcm", @@ -2063,14 +2061,14 @@ dependencies = [ "smallvec", "snowbridge-beacon-primitives", "snowbridge-core", - "snowbridge-ethereum-beacon-client", - "snowbridge-inbound-queue", - "snowbridge-outbound-queue", "snowbridge-outbound-queue-runtime-api", - "snowbridge-rococo-common", + "snowbridge-pallet-ethereum-client", + "snowbridge-pallet-inbound-queue", + "snowbridge-pallet-outbound-queue", + "snowbridge-pallet-system", "snowbridge-router-primitives", "snowbridge-runtime-common", - "snowbridge-system", + "snowbridge-runtime-test-common", "snowbridge-system-runtime-api", "sp-api", "sp-block-builder", @@ -11677,7 +11675,6 @@ dependencies = [ "polkadot-runtime-common", "scale-info", "smallvec", - "snowbridge-rococo-common", "sp-api", "sp-block-builder", "sp-consensus-aura", @@ -17564,7 +17561,7 @@ dependencies = [ [[package]] name = "snowbridge-beacon-primitives" -version = "0.0.1" +version = "0.9.0" dependencies = [ "byte-slice-cast", "frame-support", @@ -17588,7 +17585,7 @@ dependencies = [ [[package]] name = "snowbridge-core" -version = "0.1.1" +version = "0.9.0" dependencies = [ "ethabi-decode", "frame-support", @@ -17611,7 +17608,7 @@ dependencies = [ [[package]] name = "snowbridge-ethereum" -version = "0.1.0" +version = "0.9.0" dependencies = [ "ethabi-decode", "ethbloom", @@ -17634,8 +17631,36 @@ dependencies = [ ] [[package]] -name = "snowbridge-ethereum-beacon-client" -version = "0.0.1" +name = "snowbridge-outbound-queue-merkle-tree" +version = "0.9.0" +dependencies = [ + "array-bytes 4.2.0", + "env_logger 0.9.3", + "hex", + "hex-literal", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-runtime", +] + +[[package]] +name = "snowbridge-outbound-queue-runtime-api" +version = "0.9.0" +dependencies = [ + "frame-support", + "parity-scale-codec", + "snowbridge-core", + "snowbridge-outbound-queue-merkle-tree", + "sp-api", + "sp-core", + "sp-std 8.0.0", + "staging-xcm", +] + +[[package]] +name = "snowbridge-pallet-ethereum-client" +version = "0.9.0" dependencies = [ "bp-runtime", "byte-slice-cast", @@ -17665,8 +17690,8 @@ dependencies = [ ] [[package]] -name = "snowbridge-inbound-queue" -version = "0.1.1" +name = "snowbridge-pallet-inbound-queue" +version = "0.9.0" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -17684,7 +17709,7 @@ dependencies = [ "snowbridge-beacon-primitives", "snowbridge-core", "snowbridge-ethereum", - "snowbridge-ethereum-beacon-client", + "snowbridge-pallet-ethereum-client", "snowbridge-router-primitives", "sp-core", "sp-io", @@ -17693,11 +17718,12 @@ dependencies = [ "sp-std 8.0.0", "staging-xcm", "staging-xcm-builder", + "staging-xcm-executor", ] [[package]] -name = "snowbridge-outbound-queue" -version = "0.1.1" +name = "snowbridge-pallet-outbound-queue" +version = "0.9.0" dependencies = [ "bridge-hub-common", "ethabi-decode", @@ -17721,45 +17747,36 @@ dependencies = [ ] [[package]] -name = "snowbridge-outbound-queue-merkle-tree" -version = "0.1.1" +name = "snowbridge-pallet-system" +version = "0.9.0" dependencies = [ - "array-bytes 4.2.0", - "env_logger 0.9.3", + "ethabi-decode", + "frame-benchmarking", + "frame-support", + "frame-system", "hex", "hex-literal", + "log", + "pallet-balances", + "pallet-message-queue", "parity-scale-codec", + "polkadot-primitives", "scale-info", - "sp-core", - "sp-runtime", -] - -[[package]] -name = "snowbridge-outbound-queue-runtime-api" -version = "0.1.0" -dependencies = [ - "frame-support", - "parity-scale-codec", "snowbridge-core", - "snowbridge-outbound-queue-merkle-tree", - "sp-api", + "snowbridge-pallet-outbound-queue", "sp-core", + "sp-io", + "sp-keyring", + "sp-runtime", "sp-std 8.0.0", "staging-xcm", -] - -[[package]] -name = "snowbridge-rococo-common" -version = "0.0.1" -dependencies = [ - "frame-support", - "log", - "staging-xcm", + "staging-xcm-builder", + "staging-xcm-executor", ] [[package]] name = "snowbridge-router-primitives" -version = "0.1.1" +version = "0.9.0" dependencies = [ "ethabi-decode", "frame-support", @@ -17782,7 +17799,7 @@ dependencies = [ [[package]] name = "snowbridge-runtime-common" -version = "0.1.1" +version = "0.9.0" dependencies = [ "frame-support", "frame-system", @@ -17795,12 +17812,10 @@ dependencies = [ ] [[package]] -name = "snowbridge-runtime-tests" -version = "0.1.0" +name = "snowbridge-runtime-test-common" +version = "0.9.0" dependencies = [ - "asset-hub-rococo-runtime", "assets-common", - "bridge-hub-rococo-runtime", "bridge-hub-test-utils", "bridge-runtime-common", "cumulus-pallet-aura-ext", @@ -17839,18 +17854,17 @@ dependencies = [ "polkadot-core-primitives", "polkadot-parachain-primitives", "polkadot-runtime-common", - "rococo-runtime-constants", "scale-info", "serde", "smallvec", "snowbridge-beacon-primitives", "snowbridge-core", - "snowbridge-ethereum-beacon-client", - "snowbridge-inbound-queue", - "snowbridge-outbound-queue", "snowbridge-outbound-queue-runtime-api", + "snowbridge-pallet-ethereum-client", + "snowbridge-pallet-inbound-queue", + "snowbridge-pallet-outbound-queue", + "snowbridge-pallet-system", "snowbridge-router-primitives", - "snowbridge-system", "snowbridge-system-runtime-api", "sp-api", "sp-block-builder", @@ -17874,37 +17888,9 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "snowbridge-system" -version = "0.1.1" -dependencies = [ - "ethabi-decode", - "frame-benchmarking", - "frame-support", - "frame-system", - "hex", - "hex-literal", - "log", - "pallet-balances", - "pallet-message-queue", - "parity-scale-codec", - "polkadot-primitives", - "scale-info", - "snowbridge-core", - "snowbridge-outbound-queue", - "sp-core", - "sp-io", - "sp-keyring", - "sp-runtime", - "sp-std 8.0.0", - "staging-xcm", - "staging-xcm-builder", - "staging-xcm-executor", -] - [[package]] name = "snowbridge-system-runtime-api" -version = "0.1.0" +version = "0.9.0" dependencies = [ "parity-scale-codec", "snowbridge-core", diff --git a/Cargo.toml b/Cargo.toml index 231aab8dee9..38cae6f640c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,7 @@ members = [ "bridges/primitives/test-utils", "bridges/primitives/xcm-bridge-hub", "bridges/primitives/xcm-bridge-hub-router", - "bridges/snowbridge/parachain/pallets/ethereum-beacon-client", + "bridges/snowbridge/parachain/pallets/ethereum-client", "bridges/snowbridge/parachain/pallets/inbound-queue", "bridges/snowbridge/parachain/pallets/outbound-queue", "bridges/snowbridge/parachain/pallets/outbound-queue/merkle-tree", @@ -47,9 +47,8 @@ members = [ "bridges/snowbridge/parachain/primitives/core", "bridges/snowbridge/parachain/primitives/ethereum", "bridges/snowbridge/parachain/primitives/router", - "bridges/snowbridge/parachain/runtime/rococo-common", "bridges/snowbridge/parachain/runtime/runtime-common", - "bridges/snowbridge/parachain/runtime/tests", + "bridges/snowbridge/parachain/runtime/test-common", "cumulus/client/cli", "cumulus/client/collator", "cumulus/client/consensus/aura", diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/Cargo.toml b/bridges/snowbridge/parachain/pallets/ethereum-client/Cargo.toml similarity index 93% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/Cargo.toml rename to bridges/snowbridge/parachain/pallets/ethereum-client/Cargo.toml index 9f8749c89da..59efcf91fd0 100644 --- a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/Cargo.toml +++ b/bridges/snowbridge/parachain/pallets/ethereum-client/Cargo.toml @@ -1,11 +1,15 @@ [package] -name = "snowbridge-ethereum-beacon-client" -description = "Snowbridge Beacon Client Pallet" -version = "0.0.1" -edition = "2021" +name = "snowbridge-pallet-ethereum-client" +description = "Snowbridge Ethereum Client Pallet" +version = "0.9.0" authors = ["Snowfork "] -repository = "https://github.com/Snowfork/snowbridge" +edition.workspace = true +repository.workspace = true license = "Apache-2.0" +categories = ["cryptography::cryptocurrencies"] + +[lints] +workspace = true [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/bridges/snowbridge/parachain/pallets/ethereum-client/README.md b/bridges/snowbridge/parachain/pallets/ethereum-client/README.md new file mode 100644 index 00000000000..0cd3b9f8558 --- /dev/null +++ b/bridges/snowbridge/parachain/pallets/ethereum-client/README.md @@ -0,0 +1,3 @@ +# Ethereum Beacon Client + +The Ethereum Beacon Client is an on-chain light client that tracks Ethereum consensus using the beacon chain. diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/benchmark.md b/bridges/snowbridge/parachain/pallets/ethereum-client/benchmark.md similarity index 88% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/benchmark.md rename to bridges/snowbridge/parachain/pallets/ethereum-client/benchmark.md index de976e12149..2e19fece7cb 100644 --- a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/benchmark.md +++ b/bridges/snowbridge/parachain/pallets/ethereum-client/benchmark.md @@ -7,15 +7,15 @@ for it is super helpful. # Benchmark We add several benchmarks -[here](https://github.com/Snowfork/snowbridge/blob/8891ca3cdcf2e04d8118c206588c956541ae4710/parachain/pallets/ethereum-beacon-client/src/benchmarking/mod.rs#L98-L124) +[here](https://github.com/Snowfork/snowbridge/blob/8891ca3cdcf2e04d8118c206588c956541ae4710/parachain/pallets/ethereum-client/src/benchmarking/mod.rs#L98-L124) as following to demonstrate -[bls_fast_aggregate_verify](https://github.com/Snowfork/snowbridge/blob/8891ca3cdcf2e04d8118c206588c956541ae4710/parachain/pallets/ethereum-beacon-client/src/lib.rs#L764) +[bls_fast_aggregate_verify](https://github.com/Snowfork/snowbridge/blob/8891ca3cdcf2e04d8118c206588c956541ae4710/parachain/pallets/ethereum-client/src/lib.rs#L764) is the main bottleneck. Test data -[here](https://github.com/Snowfork/snowbridge/blob/8891ca3cdcf2e04d8118c206588c956541ae4710/parachain/pallets/ethereum-beacon-client/src/benchmarking/data_mainnet.rs#L553-L1120) +[here](https://github.com/Snowfork/snowbridge/blob/8891ca3cdcf2e04d8118c206588c956541ae4710/parachain/pallets/ethereum-client/src/benchmarking/data_mainnet.rs#L553-L1120) is real from goerli network which contains 512 public keys from sync committee. ## sync_committee_period_update -Base line benchmark for extrinsic [sync_committee_period_update](https://github.com/Snowfork/snowbridge/blob/8891ca3cdcf2e04d8118c206588c956541ae4710/parachain/pallets/ethereum-beacon-client/src/lib.rs#L233) +Base line benchmark for extrinsic [sync_committee_period_update](https://github.com/Snowfork/snowbridge/blob/8891ca3cdcf2e04d8118c206588c956541ae4710/parachain/pallets/ethereum-client/src/lib.rs#L233) ## bls_fast_aggregate_verify Subfunction of extrinsic `sync_committee_period_update` which does what @@ -59,14 +59,14 @@ cargo run --release --bin polkadot-parachain \ benchmark pallet \ --base-path /mnt/scratch/benchmark \ --chain=bridge-hub-rococo-dev \ ---pallet=snowbridge_ethereum_beacon_client \ +--pallet=snowbridge_pallet_ethereum_client \ --extrinsic="*" \ --execution=wasm --wasm-execution=compiled \ --steps 50 --repeat 20 \ ---output ./parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_ethereum_beacon_client.rs +--output ./parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_ethereum_client.rs ``` -### [Weights](https://github.com/Snowfork/cumulus/blob/ron/benchmark-beacon-bridge/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_ethereum_beacon_client.rs) +### [Weights](https://github.com/Snowfork/cumulus/blob/ron/benchmark-beacon-bridge/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_ethereum_client.rs) |extrinsic | minimum execution time benchmarked(us) | | --------------------------------------- |----------------------------------------| @@ -84,5 +84,5 @@ benchmark pallet \ # Conclusion A high level host function specific for -[bls_fast_aggregate_verify](https://github.com/Snowfork/snowbridge/blob/8891ca3cdcf2e04d8118c206588c956541ae4710/parachain/pallets/ethereum-beacon-client/src/lib.rs#L764) +[bls_fast_aggregate_verify](https://github.com/Snowfork/snowbridge/blob/8891ca3cdcf2e04d8118c206588c956541ae4710/parachain/pallets/ethereum-client/src/lib.rs#L764) is super helpful. diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/fixtures_mainnet.rs b/bridges/snowbridge/parachain/pallets/ethereum-client/src/benchmarking/fixtures_mainnet.rs similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/fixtures_mainnet.rs rename to bridges/snowbridge/parachain/pallets/ethereum-client/src/benchmarking/fixtures_mainnet.rs diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/fixtures_minimal.rs b/bridges/snowbridge/parachain/pallets/ethereum-client/src/benchmarking/fixtures_minimal.rs similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/fixtures_minimal.rs rename to bridges/snowbridge/parachain/pallets/ethereum-client/src/benchmarking/fixtures_minimal.rs diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/mod.rs b/bridges/snowbridge/parachain/pallets/ethereum-client/src/benchmarking/mod.rs similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/mod.rs rename to bridges/snowbridge/parachain/pallets/ethereum-client/src/benchmarking/mod.rs diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/util.rs b/bridges/snowbridge/parachain/pallets/ethereum-client/src/benchmarking/util.rs similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/benchmarking/util.rs rename to bridges/snowbridge/parachain/pallets/ethereum-client/src/benchmarking/util.rs diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/config/mainnet.rs b/bridges/snowbridge/parachain/pallets/ethereum-client/src/config/mainnet.rs similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/config/mainnet.rs rename to bridges/snowbridge/parachain/pallets/ethereum-client/src/config/mainnet.rs diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/config/minimal.rs b/bridges/snowbridge/parachain/pallets/ethereum-client/src/config/minimal.rs similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/config/minimal.rs rename to bridges/snowbridge/parachain/pallets/ethereum-client/src/config/minimal.rs diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/config/mod.rs b/bridges/snowbridge/parachain/pallets/ethereum-client/src/config/mod.rs similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/config/mod.rs rename to bridges/snowbridge/parachain/pallets/ethereum-client/src/config/mod.rs diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/functions.rs b/bridges/snowbridge/parachain/pallets/ethereum-client/src/functions.rs similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/functions.rs rename to bridges/snowbridge/parachain/pallets/ethereum-client/src/functions.rs diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/impls.rs b/bridges/snowbridge/parachain/pallets/ethereum-client/src/impls.rs similarity index 91% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/impls.rs rename to bridges/snowbridge/parachain/pallets/ethereum-client/src/impls.rs index 7e72b12631c..300431d8770 100644 --- a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/impls.rs +++ b/bridges/snowbridge/parachain/pallets/ethereum-client/src/impls.rs @@ -15,7 +15,7 @@ impl Verifier for Pallet { /// ancestor of a finalized beacon block. fn verify(event_log: &Log, proof: &Proof) -> Result<(), VerificationError> { log::info!( - target: "ethereum-beacon-client", + target: "ethereum-client", "💫 Verifying message with block hash {}", proof.block_hash, ); @@ -26,7 +26,7 @@ impl Verifier for Pallet { Ok(receipt) => receipt, Err(err) => { log::error!( - target: "ethereum-beacon-client", + target: "ethereum-client", "💫 Verification of receipt inclusion failed for block {}: {:?}", proof.block_hash, err @@ -36,7 +36,7 @@ impl Verifier for Pallet { }; log::trace!( - target: "ethereum-beacon-client", + target: "ethereum-client", "💫 Verified receipt inclusion for transaction at index {} in block {}", proof.tx_index, proof.block_hash, ); @@ -52,7 +52,7 @@ impl Verifier for Pallet { if !receipt.contains_log(&event_log) { log::error!( - target: "ethereum-beacon-client", + target: "ethereum-client", "💫 Event log not found in receipt for transaction at index {} in block {}", proof.tx_index, proof.block_hash, ); @@ -60,7 +60,7 @@ impl Verifier for Pallet { } log::info!( - target: "ethereum-beacon-client", + target: "ethereum-client", "💫 Receipt verification successful for {}", proof.block_hash, ); @@ -82,7 +82,7 @@ impl Pallet { Ok(receipt) => Ok(receipt), Err(err) => { log::trace!( - target: "ethereum-beacon-client", + target: "ethereum-client", "💫 Failed to decode transaction receipt: {}", err ); diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/lib.rs b/bridges/snowbridge/parachain/pallets/ethereum-client/src/lib.rs similarity index 99% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/lib.rs rename to bridges/snowbridge/parachain/pallets/ethereum-client/src/lib.rs index 53877ea58fe..c99458441a5 100644 --- a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/lib.rs +++ b/bridges/snowbridge/parachain/pallets/ethereum-client/src/lib.rs @@ -61,7 +61,7 @@ pub use pallet::*; pub use config::SLOTS_PER_HISTORICAL_ROOT; -pub const LOG_TARGET: &str = "ethereum-beacon-client"; +pub const LOG_TARGET: &str = "ethereum-client"; #[frame_support::pallet] pub mod pallet { @@ -692,7 +692,7 @@ pub mod pallet { /// Stores the provided execution header in pallet storage. The header is stored /// in a ring buffer map, with the block hash as map key. The last imported execution /// header is also kept in storage, for the relayer to check import progress. - pub(crate) fn store_execution_header( + pub fn store_execution_header( block_hash: H256, header: CompactExecutionHeader, beacon_slot: u64, diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/mock.rs b/bridges/snowbridge/parachain/pallets/ethereum-client/src/mock.rs similarity index 92% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/mock.rs rename to bridges/snowbridge/parachain/pallets/ethereum-client/src/mock.rs index b25e8b0e813..217d37db8df 100644 --- a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/mock.rs +++ b/bridges/snowbridge/parachain/pallets/ethereum-client/src/mock.rs @@ -11,6 +11,11 @@ use sp_core::H256; use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; use std::{fs::File, path::PathBuf}; +#[cfg(feature = "beacon-spec-minimal")] +const SPEC: &str = "minimal"; +#[cfg(not(feature = "beacon-spec-minimal"))] +const SPEC: &str = "mainnet"; + fn load_fixture(basename: String) -> Result where T: for<'de> serde::Deserialize<'de>, @@ -21,60 +26,36 @@ where } pub fn load_execution_header_update_fixture() -> primitives::ExecutionHeaderUpdate { - #[cfg(feature = "beacon-spec-minimal")] - const SPEC: &str = "minimal"; - #[cfg(not(feature = "beacon-spec-minimal"))] - const SPEC: &str = "mainnet"; let basename = format!("execution-header-update.{}.json", SPEC); load_fixture(basename).unwrap() } pub fn load_checkpoint_update_fixture( ) -> primitives::CheckpointUpdate<{ config::SYNC_COMMITTEE_SIZE }> { - #[cfg(feature = "beacon-spec-minimal")] - const SPEC: &str = "minimal"; - #[cfg(not(feature = "beacon-spec-minimal"))] - const SPEC: &str = "mainnet"; let basename = format!("initial-checkpoint.{}.json", SPEC); load_fixture(basename).unwrap() } pub fn load_sync_committee_update_fixture( ) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { - #[cfg(feature = "beacon-spec-minimal")] - const SPEC: &str = "minimal"; - #[cfg(not(feature = "beacon-spec-minimal"))] - const SPEC: &str = "mainnet"; let basename = format!("sync-committee-update.{}.json", SPEC); load_fixture(basename).unwrap() } pub fn load_finalized_header_update_fixture( ) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { - #[cfg(feature = "beacon-spec-minimal")] - const SPEC: &str = "minimal"; - #[cfg(not(feature = "beacon-spec-minimal"))] - const SPEC: &str = "mainnet"; let basename = format!("finalized-header-update.{}.json", SPEC); load_fixture(basename).unwrap() } pub fn load_next_sync_committee_update_fixture( ) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { - #[cfg(feature = "beacon-spec-minimal")] - const SPEC: &str = "minimal"; - #[cfg(not(feature = "beacon-spec-minimal"))] - const SPEC: &str = "mainnet"; let basename = format!("next-sync-committee-update.{}.json", SPEC); load_fixture(basename).unwrap() } pub fn load_next_finalized_header_update_fixture( ) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { - #[cfg(feature = "beacon-spec-minimal")] - const SPEC: &str = "minimal"; - #[cfg(not(feature = "beacon-spec-minimal"))] - const SPEC: &str = "mainnet"; let basename = format!("next-finalized-header-update.{}.json", SPEC); load_fixture(basename).unwrap() } diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/tests.rs b/bridges/snowbridge/parachain/pallets/ethereum-client/src/tests.rs similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/tests.rs rename to bridges/snowbridge/parachain/pallets/ethereum-client/src/tests.rs diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/types.rs b/bridges/snowbridge/parachain/pallets/ethereum-client/src/types.rs similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/types.rs rename to bridges/snowbridge/parachain/pallets/ethereum-client/src/types.rs diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/weights.rs b/bridges/snowbridge/parachain/pallets/ethereum-client/src/weights.rs similarity index 97% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/weights.rs rename to bridges/snowbridge/parachain/pallets/ethereum-client/src/weights.rs index 69d3e809986..e1a5578f466 100644 --- a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/weights.rs +++ b/bridges/snowbridge/parachain/pallets/ethereum-client/src/weights.rs @@ -20,7 +20,7 @@ // --repeat // 10 // --output -// pallets/ethereum-beacon-client/src/weights.rs +// pallets/ethereum-client/src/weights.rs // --template // templates/module-weight-template.hbs diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/execution-header-update.mainnet.json b/bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/execution-header-update.mainnet.json similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/execution-header-update.mainnet.json rename to bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/execution-header-update.mainnet.json diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/execution-header-update.minimal.json b/bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/execution-header-update.minimal.json similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/execution-header-update.minimal.json rename to bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/execution-header-update.minimal.json diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/finalized-header-update.mainnet.json b/bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/finalized-header-update.mainnet.json similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/finalized-header-update.mainnet.json rename to bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/finalized-header-update.mainnet.json diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/finalized-header-update.minimal.json b/bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/finalized-header-update.minimal.json similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/finalized-header-update.minimal.json rename to bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/finalized-header-update.minimal.json diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/initial-checkpoint.mainnet.json b/bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/initial-checkpoint.mainnet.json similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/initial-checkpoint.mainnet.json rename to bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/initial-checkpoint.mainnet.json diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/initial-checkpoint.minimal.json b/bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/initial-checkpoint.minimal.json similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/initial-checkpoint.minimal.json rename to bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/initial-checkpoint.minimal.json diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/next-finalized-header-update.mainnet.json b/bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/next-finalized-header-update.mainnet.json similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/next-finalized-header-update.mainnet.json rename to bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/next-finalized-header-update.mainnet.json diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/next-finalized-header-update.minimal.json b/bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/next-finalized-header-update.minimal.json similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/next-finalized-header-update.minimal.json rename to bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/next-finalized-header-update.minimal.json diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/next-sync-committee-update.mainnet.json b/bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/next-sync-committee-update.mainnet.json similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/next-sync-committee-update.mainnet.json rename to bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/next-sync-committee-update.mainnet.json diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/next-sync-committee-update.minimal.json b/bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/next-sync-committee-update.minimal.json similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/next-sync-committee-update.minimal.json rename to bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/next-sync-committee-update.minimal.json diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/sync-committee-update.mainnet.json b/bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/sync-committee-update.mainnet.json similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/sync-committee-update.mainnet.json rename to bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/sync-committee-update.mainnet.json diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/sync-committee-update.minimal.json b/bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/sync-committee-update.minimal.json similarity index 100% rename from bridges/snowbridge/parachain/pallets/ethereum-beacon-client/tests/fixtures/sync-committee-update.minimal.json rename to bridges/snowbridge/parachain/pallets/ethereum-client/tests/fixtures/sync-committee-update.minimal.json diff --git a/bridges/snowbridge/parachain/pallets/inbound-queue/Cargo.toml b/bridges/snowbridge/parachain/pallets/inbound-queue/Cargo.toml index 6a5ea6f8222..f645b4224d1 100644 --- a/bridges/snowbridge/parachain/pallets/inbound-queue/Cargo.toml +++ b/bridges/snowbridge/parachain/pallets/inbound-queue/Cargo.toml @@ -1,11 +1,15 @@ [package] -name = "snowbridge-inbound-queue" -description = "Snowbridge Inbound Queue" -version = "0.1.1" -edition = "2021" +name = "snowbridge-pallet-inbound-queue" +description = "Snowbridge Inbound Queue Pallet" +version = "0.9.0" authors = ["Snowfork "] -repository = "https://github.com/Snowfork/snowbridge" +edition.workspace = true +repository.workspace = true license = "Apache-2.0" +categories = ["cryptography::cryptocurrencies"] + +[lints] +workspace = true [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] @@ -32,6 +36,7 @@ sp-runtime = { path = "../../../../../substrate/primitives/runtime", default-fea xcm = { package = "staging-xcm", path = "../../../../../polkadot/xcm", default-features = false } xcm-builder = { package = "staging-xcm-builder", path = "../../../../../polkadot/xcm/xcm-builder", default-features = false } +xcm-executor = { package = "staging-xcm-executor", path = "../../../../../polkadot/xcm/xcm-executor", default-features = false } snowbridge-core = { path = "../../primitives/core", default-features = false } snowbridge-ethereum = { path = "../../primitives/ethereum", default-features = false } @@ -42,7 +47,7 @@ snowbridge-beacon-primitives = { path = "../../primitives/beacon", default-featu frame-benchmarking = { path = "../../../../../substrate/frame/benchmarking" } sp-keyring = { path = "../../../../../substrate/primitives/keyring" } snowbridge-beacon-primitives = { path = "../../primitives/beacon" } -snowbridge-ethereum-beacon-client = { path = "../../pallets/ethereum-beacon-client" } +snowbridge-pallet-ethereum-client = { path = "../../pallets/ethereum-client" } hex-literal = { version = "0.4.1" } [features] @@ -68,6 +73,7 @@ std = [ "sp-runtime/std", "sp-std/std", "xcm-builder/std", + "xcm-executor/std", "xcm/std", ] runtime-benchmarks = [ @@ -79,15 +85,16 @@ runtime-benchmarks = [ "pallet-balances/runtime-benchmarks", "snowbridge-beacon-primitives", "snowbridge-core/runtime-benchmarks", - "snowbridge-ethereum-beacon-client/runtime-benchmarks", + "snowbridge-pallet-ethereum-client/runtime-benchmarks", "snowbridge-router-primitives/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", + "xcm-executor/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", "pallet-balances/try-runtime", - "snowbridge-ethereum-beacon-client/try-runtime", + "snowbridge-pallet-ethereum-client/try-runtime", "sp-runtime/try-runtime", ] diff --git a/bridges/snowbridge/parachain/pallets/inbound-queue/README.md b/bridges/snowbridge/parachain/pallets/inbound-queue/README.md new file mode 100644 index 00000000000..cc2f7c636e6 --- /dev/null +++ b/bridges/snowbridge/parachain/pallets/inbound-queue/README.md @@ -0,0 +1,3 @@ +# Ethereum Inbound Queue + +Reads messages from Ethereum and sends it to intended destination on Polkadot, using XCM. diff --git a/bridges/snowbridge/parachain/pallets/inbound-queue/src/lib.rs b/bridges/snowbridge/parachain/pallets/inbound-queue/src/lib.rs index 834e805fbef..f7eea0aadfa 100644 --- a/bridges/snowbridge/parachain/pallets/inbound-queue/src/lib.rs +++ b/bridges/snowbridge/parachain/pallets/inbound-queue/src/lib.rs @@ -44,7 +44,7 @@ use envelope::Envelope; use frame_support::{ traits::{ fungible::{Inspect, Mutate}, - tokens::{Fortitude, Precision, Preservation}, + tokens::Preservation, }, weights::WeightToFee, PalletError, @@ -55,18 +55,20 @@ use sp_core::{H160, H256}; use sp_std::{convert::TryFrom, vec}; use xcm::prelude::{ send_xcm, Instruction::SetTopic, Junction::*, Junctions::*, MultiLocation, - SendError as XcmpSendError, SendXcm, Xcm, XcmHash, + SendError as XcmpSendError, SendXcm, Xcm, XcmContext, XcmHash, }; +use xcm_executor::traits::TransactAsset; use snowbridge_core::{ inbound::{Message, VerificationError, Verifier}, - sibling_sovereign_account, BasicOperatingMode, Channel, ChannelId, ParaId, StaticLookup, + sibling_sovereign_account, BasicOperatingMode, Channel, ChannelId, ParaId, PricingParameters, + StaticLookup, }; use snowbridge_router_primitives::{ inbound, inbound::{ConvertMessage, ConvertMessageError}, }; -use sp_runtime::traits::Saturating; +use sp_runtime::{traits::Saturating, SaturatedConversion, TokenError}; pub use weights::WeightInfo; @@ -83,7 +85,6 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - use snowbridge_core::PricingParameters; #[pallet::pallet] pub struct Pallet(_); @@ -135,6 +136,9 @@ pub mod pallet { /// The upper limit here only used to estimate delivery cost type MaxMessageSize: Get; + + /// To withdraw and deposit an asset. + type AssetTransactor: TransactAsset; } #[pallet::hooks] @@ -142,7 +146,7 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] - pub enum Event { + pub enum Event { /// A message was received from Ethereum MessageReceived { /// The message channel @@ -151,6 +155,8 @@ pub mod pallet { nonce: u64, /// ID of the XCM message which was forwarded to the final destination parachain message_id: [u8; 32], + /// Fee burned for the teleport + fee_burned: BalanceOf, }, /// Set OperatingMode OperatingModeChanged { mode: BasicOperatingMode }, @@ -268,17 +274,16 @@ pub mod pallet { Err(_) => return Err(Error::::InvalidPayload.into()), }; - // We embed fees for xcm execution inside the xcm program using teleports - // so we must burn the amount of the fee embedded into the XCM script. - T::Token::burn_from(&sovereign_account, fee, Precision::Exact, Fortitude::Polite)?; - log::info!( target: LOG_TARGET, - "💫 xcm {:?} sent with fee {:?}", + "💫 xcm decoded as {:?} with fee {:?}", xcm, fee ); + // Burning fees for teleport + Self::burn_fees(channel.para_id, fee)?; + // Attempt to send XCM to a dest parachain let message_id = Self::send_xcm(xcm, channel.para_id)?; @@ -286,6 +291,7 @@ pub mod pallet { channel_id: envelope.channel_id, nonce: envelope.nonce, message_id, + fee_burned: fee, }); Ok(()) @@ -330,6 +336,30 @@ pub mod pallet { .saturating_add(len_fee) .saturating_add(T::PricingParameters::get().rewards.local) } + + /// Burn the amount of the fee embedded into the XCM for teleports + pub fn burn_fees(para_id: ParaId, fee: BalanceOf) -> DispatchResult { + let dummy_context = + XcmContext { origin: None, message_id: Default::default(), topic: None }; + let dest = MultiLocation { parents: 1, interior: X1(Parachain(para_id.into())) }; + let fees = (MultiLocation::parent(), fee.saturated_into::()).into(); + T::AssetTransactor::can_check_out(&dest, &fees, &dummy_context).map_err(|error| { + log::error!( + target: LOG_TARGET, + "XCM asset check out failed with error {:?}", error + ); + TokenError::FundsUnavailable + })?; + T::AssetTransactor::check_out(&dest, &fees, &dummy_context); + T::AssetTransactor::withdraw_asset(&fees, &dest, None).map_err(|error| { + log::error!( + target: LOG_TARGET, + "XCM asset withdraw failed with error {:?}", error + ); + TokenError::FundsUnavailable + })?; + Ok(()) + } } /// API for accessing the delivery cost of a message diff --git a/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs b/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs index 6b79a55e3c9..b031a46e219 100644 --- a/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs +++ b/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs @@ -22,6 +22,7 @@ use sp_runtime::{ }; use sp_std::convert::From; use xcm::v3::{prelude::*, MultiAssets, SendXcm}; +use xcm_executor::Assets; use crate::{self as inbound_queue}; @@ -32,7 +33,7 @@ frame_support::construct_runtime!( { System: frame_system::{Pallet, Call, Storage, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - EthereumBeaconClient: snowbridge_ethereum_beacon_client::{Pallet, Call, Storage, Event}, + EthereumBeaconClient: snowbridge_pallet_ethereum_client::{Pallet, Call, Storage, Event}, InboundQueue: inbound_queue::{Pallet, Call, Storage, Event}, } ); @@ -112,7 +113,7 @@ parameter_types! { }; } -impl snowbridge_ethereum_beacon_client::Config for Test { +impl snowbridge_pallet_ethereum_client::Config for Test { type RuntimeEvent = RuntimeEvent; type ForkVersions = ChainForkVersions; type MaxExecutionHeadersToKeep = ExecutionHeadersPruneThreshold; @@ -142,7 +143,7 @@ parameter_types! { } #[cfg(feature = "runtime-benchmarks")] -impl BenchmarkHelper for Test { +impl BenchmarkHelper for Test { // not implemented since the MockVerifier is used for tests fn initialize_storage(_: H256, _: CompactExecutionHeader) {} } @@ -200,6 +201,50 @@ impl StaticLookup for MockChannelLookup { } } +pub struct SuccessfulTransactor; +impl TransactAsset for SuccessfulTransactor { + fn can_check_in( + _origin: &MultiLocation, + _what: &MultiAsset, + _context: &XcmContext, + ) -> XcmResult { + Ok(()) + } + + fn can_check_out( + _dest: &MultiLocation, + _what: &MultiAsset, + _context: &XcmContext, + ) -> XcmResult { + Ok(()) + } + + fn deposit_asset( + _what: &MultiAsset, + _who: &MultiLocation, + _context: Option<&XcmContext>, + ) -> XcmResult { + Ok(()) + } + + fn withdraw_asset( + _what: &MultiAsset, + _who: &MultiLocation, + _context: Option<&XcmContext>, + ) -> Result { + Ok(Assets::default()) + } + + fn internal_transfer_asset( + _what: &MultiAsset, + _from: &MultiLocation, + _to: &MultiLocation, + _context: &XcmContext, + ) -> Result { + Ok(Assets::default()) + } +} + impl inbound_queue::Config for Test { type RuntimeEvent = RuntimeEvent; type Verifier = MockVerifier; @@ -221,6 +266,7 @@ impl inbound_queue::Config for Test { type WeightToFee = IdentityFee; type LengthToFee = IdentityFee; type MaxMessageSize = ConstU32<1024>; + type AssetTransactor = SuccessfulTransactor; } pub fn last_events(n: usize) -> Vec { diff --git a/bridges/snowbridge/parachain/pallets/inbound-queue/src/test.rs b/bridges/snowbridge/parachain/pallets/inbound-queue/src/test.rs index 6dc3ac45374..17ebeb39446 100644 --- a/bridges/snowbridge/parachain/pallets/inbound-queue/src/test.rs +++ b/bridges/snowbridge/parachain/pallets/inbound-queue/src/test.rs @@ -44,6 +44,7 @@ fn test_submit_happy_path() { 27, 217, 88, 127, 46, 143, 199, 70, 236, 66, 212, 244, 85, 221, 153, 104, 175, 37, 224, 20, 140, 95, 140, 7, 27, 74, 182, 199, 77, 12, 194, 236, ], + fee_burned: 110000000000, } .into()]); diff --git a/bridges/snowbridge/parachain/pallets/outbound-queue/Cargo.toml b/bridges/snowbridge/parachain/pallets/outbound-queue/Cargo.toml index f99fcc72e19..de4487553cb 100644 --- a/bridges/snowbridge/parachain/pallets/outbound-queue/Cargo.toml +++ b/bridges/snowbridge/parachain/pallets/outbound-queue/Cargo.toml @@ -1,11 +1,15 @@ [package] -name = "snowbridge-outbound-queue" -description = "Snowbridge Outbound Queue" -version = "0.1.1" -edition = "2021" +name = "snowbridge-pallet-outbound-queue" +description = "Snowbridge Outbound Queue Pallet" +version = "0.9.0" authors = ["Snowfork "] -repository = "https://github.com/Snowfork/snowbridge" +edition.workspace = true +repository.workspace = true license = "Apache-2.0" +categories = ["cryptography::cryptocurrencies"] + +[lints] +workspace = true [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/bridges/snowbridge/parachain/pallets/outbound-queue/README.md b/bridges/snowbridge/parachain/pallets/outbound-queue/README.md new file mode 100644 index 00000000000..19638f90e6a --- /dev/null +++ b/bridges/snowbridge/parachain/pallets/outbound-queue/README.md @@ -0,0 +1,3 @@ +# Ethereum Outbound Queue + +Sends messages from an origin in the Polkadot ecosystem to Ethereum. diff --git a/bridges/snowbridge/parachain/pallets/outbound-queue/merkle-tree/Cargo.toml b/bridges/snowbridge/parachain/pallets/outbound-queue/merkle-tree/Cargo.toml index a3432163622..27c4ae02e52 100644 --- a/bridges/snowbridge/parachain/pallets/outbound-queue/merkle-tree/Cargo.toml +++ b/bridges/snowbridge/parachain/pallets/outbound-queue/merkle-tree/Cargo.toml @@ -1,11 +1,15 @@ [package] name = "snowbridge-outbound-queue-merkle-tree" description = "Snowbridge Outbound Queue Merkle Tree" -version = "0.1.1" -edition = "2021" +version = "0.9.0" authors = ["Snowfork "] -repository = "https://github.com/Snowfork/snowbridge" +edition.workspace = true +repository.workspace = true license = "Apache-2.0" +categories = ["cryptography::cryptocurrencies"] + +[lints] +workspace = true [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/bridges/snowbridge/parachain/pallets/outbound-queue/merkle-tree/README.md b/bridges/snowbridge/parachain/pallets/outbound-queue/merkle-tree/README.md new file mode 100644 index 00000000000..a3afef1d671 --- /dev/null +++ b/bridges/snowbridge/parachain/pallets/outbound-queue/merkle-tree/README.md @@ -0,0 +1,4 @@ +# Snowbridge Outbound Queue Merkle Tree + +This crate implements a simple binary Merkle Tree utilities required for inter-op with Ethereum +bridge & Solidity contract. diff --git a/bridges/snowbridge/parachain/pallets/outbound-queue/runtime-api/Cargo.toml b/bridges/snowbridge/parachain/pallets/outbound-queue/runtime-api/Cargo.toml index c92e725c60d..1f2b51a6752 100644 --- a/bridges/snowbridge/parachain/pallets/outbound-queue/runtime-api/Cargo.toml +++ b/bridges/snowbridge/parachain/pallets/outbound-queue/runtime-api/Cargo.toml @@ -1,11 +1,15 @@ [package] name = "snowbridge-outbound-queue-runtime-api" description = "Snowbridge Outbound Queue Runtime API" -version = "0.1.0" -edition = "2021" +version = "0.9.0" authors = ["Snowfork "] -repository = "https://github.com/Snowfork/snowbridge" +edition.workspace = true +repository.workspace = true license = "Apache-2.0" +categories = ["cryptography::cryptocurrencies"] + +[lints] +workspace = true [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/bridges/snowbridge/parachain/pallets/outbound-queue/runtime-api/README.md b/bridges/snowbridge/parachain/pallets/outbound-queue/runtime-api/README.md new file mode 100644 index 00000000000..98ae01fb33d --- /dev/null +++ b/bridges/snowbridge/parachain/pallets/outbound-queue/runtime-api/README.md @@ -0,0 +1,6 @@ +# Ethereum Outbound Queue Runtime API + +Provides an API: + +- to generate merkle proofs for outbound messages +- calculate delivery fee for delivering messages to Ethereum diff --git a/bridges/snowbridge/parachain/pallets/outbound-queue/src/lib.rs b/bridges/snowbridge/parachain/pallets/outbound-queue/src/lib.rs index c3401c4dc94..9e949a4791a 100644 --- a/bridges/snowbridge/parachain/pallets/outbound-queue/src/lib.rs +++ b/bridges/snowbridge/parachain/pallets/outbound-queue/src/lib.rs @@ -5,10 +5,10 @@ //! # Overview //! //! Messages come either from sibling parachains via XCM, or BridgeHub itself -//! via the `snowbridge-system` pallet: +//! via the `snowbridge-pallet-system`: //! //! 1. `snowbridge_router_primitives::outbound::EthereumBlobExporter::deliver` -//! 2. `snowbridge_system::Pallet::send` +//! 2. `snowbridge_pallet_system::Pallet::send` //! //! The message submission pipeline works like this: //! 1. The message is first validated via the implementation for diff --git a/bridges/snowbridge/parachain/pallets/outbound-queue/src/test.rs b/bridges/snowbridge/parachain/pallets/outbound-queue/src/test.rs index 454a91d5df5..0028d75e7b7 100644 --- a/bridges/snowbridge/parachain/pallets/outbound-queue/src/test.rs +++ b/bridges/snowbridge/parachain/pallets/outbound-queue/src/test.rs @@ -110,7 +110,7 @@ fn process_message_fails_on_max_nonce_reached() { channel_id, command: mock_message(sibling_id).command, }; - let versioned_queued_message: VersionedQueuedMessage = message.into(); + let versioned_queued_message: VersionedQueuedMessage = message.try_into().unwrap(); let encoded = versioned_queued_message.encode(); let mut meter = WeightMeter::with_limit(Weight::MAX); @@ -134,7 +134,7 @@ fn process_message_fails_on_overweight_message() { channel_id, command: mock_message(sibling_id).command, }; - let versioned_queued_message: VersionedQueuedMessage = message.into(); + let versioned_queued_message: VersionedQueuedMessage = message.try_into().unwrap(); let encoded = versioned_queued_message.encode(); let mut meter = WeightMeter::with_limit(Weight::from_parts(1, 1)); assert_noop!( diff --git a/bridges/snowbridge/parachain/pallets/outbound-queue/src/weights.rs b/bridges/snowbridge/parachain/pallets/outbound-queue/src/weights.rs index e4b6f8439b0..87eee1a31e8 100644 --- a/bridges/snowbridge/parachain/pallets/outbound-queue/src/weights.rs +++ b/bridges/snowbridge/parachain/pallets/outbound-queue/src/weights.rs @@ -1,5 +1,5 @@ -//! Autogenerated weights for `snowbridge_outbound_queue` +//! Autogenerated weights for `snowbridge-pallet-outbound-queue` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev //! DATE: 2023-10-19, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` @@ -12,7 +12,7 @@ // benchmark // pallet // --chain=bridge-hub-rococo-dev -// --pallet=snowbridge_outbound_queue +// --pallet=snowbridge-pallet-outbound-queue // --extrinsic=* // --execution=wasm // --wasm-execution=compiled @@ -29,7 +29,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `snowbridge_outbound_queue`. +/// Weight functions needed for `snowbridge-pallet-outbound-queue`. pub trait WeightInfo { fn do_process_message() -> Weight; fn commit() -> Weight; diff --git a/bridges/snowbridge/parachain/pallets/system/Cargo.toml b/bridges/snowbridge/parachain/pallets/system/Cargo.toml index 4356bf57220..70155370d19 100644 --- a/bridges/snowbridge/parachain/pallets/system/Cargo.toml +++ b/bridges/snowbridge/parachain/pallets/system/Cargo.toml @@ -1,11 +1,15 @@ [package] -name = "snowbridge-system" -description = "Snowbridge System" -version = "0.1.1" +name = "snowbridge-pallet-system" +description = "Snowbridge System Pallet" +version = "0.9.0" authors = ["Snowfork "] -edition = "2021" -repository = "https://github.com/Snowfork/snowbridge" +edition.workspace = true +repository.workspace = true license = "Apache-2.0" +categories = ["cryptography::cryptocurrencies"] + +[lints] +workspace = true [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] @@ -39,7 +43,7 @@ pallet-balances = { path = "../../../../../substrate/frame/balances" } sp-keyring = { path = "../../../../../substrate/primitives/keyring" } polkadot-primitives = { path = "../../../../../polkadot/primitives" } pallet-message-queue = { path = "../../../../../substrate/frame/message-queue" } -snowbridge-outbound-queue = { path = "../outbound-queue" } +snowbridge-pallet-outbound-queue = { path = "../outbound-queue" } [features] default = ["std"] @@ -68,7 +72,7 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "polkadot-primitives/runtime-benchmarks", "snowbridge-core/runtime-benchmarks", - "snowbridge-outbound-queue/runtime-benchmarks", + "snowbridge-pallet-outbound-queue/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", @@ -78,6 +82,6 @@ try-runtime = [ "frame-system/try-runtime", "pallet-balances/try-runtime", "pallet-message-queue/try-runtime", - "snowbridge-outbound-queue/try-runtime", + "snowbridge-pallet-outbound-queue/try-runtime", "sp-runtime/try-runtime", ] diff --git a/bridges/snowbridge/parachain/pallets/system/README.md b/bridges/snowbridge/parachain/pallets/system/README.md index 9e4dc55267d..5ab11d45eae 100644 --- a/bridges/snowbridge/parachain/pallets/system/README.md +++ b/bridges/snowbridge/parachain/pallets/system/README.md @@ -1 +1,3 @@ -License: MIT-0 +# Ethereum System + +Contains management functions to manage functions on Ethereum. For example, creating agents and channels. diff --git a/bridges/snowbridge/parachain/pallets/system/runtime-api/Cargo.toml b/bridges/snowbridge/parachain/pallets/system/runtime-api/Cargo.toml index 97d0735bf63..96d5aa522c0 100644 --- a/bridges/snowbridge/parachain/pallets/system/runtime-api/Cargo.toml +++ b/bridges/snowbridge/parachain/pallets/system/runtime-api/Cargo.toml @@ -1,11 +1,15 @@ [package] name = "snowbridge-system-runtime-api" description = "Snowbridge System Runtime API" -version = "0.1.0" -edition = "2021" +version = "0.9.0" authors = ["Snowfork "] -repository = "https://github.com/Snowfork/snowbridge" +edition.workspace = true +repository.workspace = true license = "Apache-2.0" +categories = ["cryptography::cryptocurrencies"] + +[lints] +workspace = true [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/bridges/snowbridge/parachain/pallets/system/runtime-api/README.md b/bridges/snowbridge/parachain/pallets/system/runtime-api/README.md new file mode 100644 index 00000000000..99827c9c2fc --- /dev/null +++ b/bridges/snowbridge/parachain/pallets/system/runtime-api/README.md @@ -0,0 +1,3 @@ +# Ethereum System Runtime API + +Provides an API for looking up an agent ID on Ethereum. diff --git a/bridges/snowbridge/parachain/pallets/system/src/lib.rs b/bridges/snowbridge/parachain/pallets/system/src/lib.rs index e5077abd921..0042093ee66 100644 --- a/bridges/snowbridge/parachain/pallets/system/src/lib.rs +++ b/bridges/snowbridge/parachain/pallets/system/src/lib.rs @@ -79,6 +79,8 @@ use xcm_executor::traits::ConvertLocation; #[cfg(feature = "runtime-benchmarks")] use frame_support::traits::OriginTrait; +pub use pallet::*; + pub type BalanceOf = <::Token as Inspect<::AccountId>>::Balance; pub type AccountIdOf = ::AccountId; diff --git a/bridges/snowbridge/parachain/pallets/system/src/mock.rs b/bridges/snowbridge/parachain/pallets/system/src/mock.rs index 7a4f6118930..bb9bae6b56d 100644 --- a/bridges/snowbridge/parachain/pallets/system/src/mock.rs +++ b/bridges/snowbridge/parachain/pallets/system/src/mock.rs @@ -89,7 +89,7 @@ frame_support::construct_runtime!( System: frame_system, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, XcmOrigin: pallet_xcm_origin::{Pallet, Origin}, - OutboundQueue: snowbridge_outbound_queue::{Pallet, Call, Storage, Event}, + OutboundQueue: snowbridge_pallet_outbound_queue::{Pallet, Call, Storage, Event}, EthereumSystem: snowbridge_system, MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} } @@ -167,7 +167,7 @@ parameter_types! { pub const OwnParaId: ParaId = ParaId::new(1013); } -impl snowbridge_outbound_queue::Config for Test { +impl snowbridge_pallet_outbound_queue::Config for Test { type RuntimeEvent = RuntimeEvent; type Hashing = Keccak256; type MessageQueue = MessageQueue; diff --git a/bridges/snowbridge/parachain/primitives/beacon/Cargo.toml b/bridges/snowbridge/parachain/primitives/beacon/Cargo.toml index eb717325e8a..8294e903dfb 100644 --- a/bridges/snowbridge/parachain/primitives/beacon/Cargo.toml +++ b/bridges/snowbridge/parachain/primitives/beacon/Cargo.toml @@ -1,10 +1,15 @@ [package] name = "snowbridge-beacon-primitives" description = "Snowbridge Beacon Primitives" -version = "0.0.1" +version = "0.9.0" authors = ["Snowfork "] -edition = "2021" +edition.workspace = true +repository.workspace = true license = "Apache-2.0" +categories = ["cryptography::cryptocurrencies"] + +[lints] +workspace = true [dependencies] serde = { version = "1.0.195", optional = true, features = ["derive"] } diff --git a/bridges/snowbridge/parachain/primitives/beacon/README.md b/bridges/snowbridge/parachain/primitives/beacon/README.md new file mode 100644 index 00000000000..658d7c5be7d --- /dev/null +++ b/bridges/snowbridge/parachain/primitives/beacon/README.md @@ -0,0 +1,10 @@ +# Beacon Primitives + +Crate with low-level supporting functions for the beacon client, including: + +- bls12-381 signature handling to verify signatures on the beacon chain +- merkle proofs +- receipt verification +- ssz types + +The code in this crate relates to the Ethereum consensus chain, commonly referred to as the beacon chain. diff --git a/bridges/snowbridge/parachain/primitives/core/Cargo.toml b/bridges/snowbridge/parachain/primitives/core/Cargo.toml index 706c508363d..1cb28eb3e50 100644 --- a/bridges/snowbridge/parachain/primitives/core/Cargo.toml +++ b/bridges/snowbridge/parachain/primitives/core/Cargo.toml @@ -1,10 +1,15 @@ [package] name = "snowbridge-core" description = "Snowbridge Core" -version = "0.1.1" +version = "0.9.0" authors = ["Snowfork "] -edition = "2021" +edition.workspace = true +repository.workspace = true license = "Apache-2.0" +categories = ["cryptography::cryptocurrencies"] + +[lints] +workspace = true [dependencies] serde = { version = "1.0.195", optional = true, features = ["alloc", "derive"], default-features = false } diff --git a/bridges/snowbridge/parachain/primitives/core/README.md b/bridges/snowbridge/parachain/primitives/core/README.md new file mode 100644 index 00000000000..0126be63aeb --- /dev/null +++ b/bridges/snowbridge/parachain/primitives/core/README.md @@ -0,0 +1,4 @@ +# Core Primitives + +Contains common code core to Snowbridge, such as inbound and outbound queue types, pricing structs, ringbuffer data +types (used in the beacon client). diff --git a/bridges/snowbridge/parachain/primitives/ethereum/Cargo.toml b/bridges/snowbridge/parachain/primitives/ethereum/Cargo.toml index 3624044f86a..016f16ce0e6 100644 --- a/bridges/snowbridge/parachain/primitives/ethereum/Cargo.toml +++ b/bridges/snowbridge/parachain/primitives/ethereum/Cargo.toml @@ -1,10 +1,15 @@ [package] name = "snowbridge-ethereum" description = "Snowbridge Ethereum" -version = "0.1.0" +version = "0.9.0" authors = ["Snowfork "] -edition = "2021" +edition.workspace = true +repository.workspace = true license = "Apache-2.0" +categories = ["cryptography::cryptocurrencies"] + +[lints] +workspace = true [dependencies] serde = { version = "1.0.195", optional = true, features = ["derive"] } diff --git a/bridges/snowbridge/parachain/primitives/ethereum/README.md b/bridges/snowbridge/parachain/primitives/ethereum/README.md new file mode 100644 index 00000000000..c295aad9040 --- /dev/null +++ b/bridges/snowbridge/parachain/primitives/ethereum/README.md @@ -0,0 +1,4 @@ +# Ethereum Primitives + +Contains code necessary to decode RLP encoded data (like the Ethereum log), structs for Ethereum execution headers. The +code in this crate relates to the Ethereum execution chain. diff --git a/bridges/snowbridge/parachain/primitives/router/Cargo.toml b/bridges/snowbridge/parachain/primitives/router/Cargo.toml index 40ae12920e7..65133128ef4 100644 --- a/bridges/snowbridge/parachain/primitives/router/Cargo.toml +++ b/bridges/snowbridge/parachain/primitives/router/Cargo.toml @@ -1,10 +1,15 @@ [package] name = "snowbridge-router-primitives" description = "Snowbridge Router Primitives" -version = "0.1.1" +version = "0.9.0" authors = ["Snowfork "] -edition = "2021" +edition.workspace = true +repository.workspace = true license = "Apache-2.0" +categories = ["cryptography::cryptocurrencies"] + +[lints] +workspace = true [dependencies] serde = { version = "1.0.195", optional = true, features = ["derive"] } diff --git a/bridges/snowbridge/parachain/primitives/router/README.md b/bridges/snowbridge/parachain/primitives/router/README.md new file mode 100644 index 00000000000..45967cbf76c --- /dev/null +++ b/bridges/snowbridge/parachain/primitives/router/README.md @@ -0,0 +1,4 @@ +# Router Primitives + +Inbound and outbound router logic. Does XCM conversion to a lowered, simpler format the Ethereum contracts can +understand. diff --git a/bridges/snowbridge/parachain/runtime/rococo-common/Cargo.toml b/bridges/snowbridge/parachain/runtime/rococo-common/Cargo.toml deleted file mode 100644 index 656ed6de26e..00000000000 --- a/bridges/snowbridge/parachain/runtime/rococo-common/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "snowbridge-rococo-common" -description = "Snowbridge Rococo Common" -version = "0.0.1" -authors = ["Snowfork "] -edition = "2021" -license = "Apache-2.0" - -[dependencies] -log = { version = "0.4.20", default-features = false } - -frame-support = { path = "../../../../../substrate/frame/support", default-features = false } -xcm = { package = "staging-xcm", path = "../../../../../polkadot/xcm", default-features = false } - -[dev-dependencies] - -[features] -default = ["std"] -std = [ - "frame-support/std", - "log/std", - "xcm/std", -] -runtime-benchmarks = [ - "frame-support/runtime-benchmarks", -] diff --git a/bridges/snowbridge/parachain/runtime/rococo-common/src/lib.rs b/bridges/snowbridge/parachain/runtime/rococo-common/src/lib.rs deleted file mode 100644 index 97f0332fe66..00000000000 --- a/bridges/snowbridge/parachain/runtime/rococo-common/src/lib.rs +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2023 Snowfork -//! # Rococo Common -//! -//! Config used for the Rococo asset hub and bridge hub runtimes. -#![cfg_attr(not(feature = "std"), no_std)] - -use frame_support::parameter_types; -use xcm::opaque::lts::NetworkId; - -pub const INBOUND_QUEUE_MESSAGES_PALLET_INDEX: u8 = 80; - -parameter_types! { - // Network and location for the Ethereum chain. - pub EthereumNetwork: NetworkId = NetworkId::Ethereum { chain_id: 11155111 }; -} diff --git a/bridges/snowbridge/parachain/runtime/runtime-common/Cargo.toml b/bridges/snowbridge/parachain/runtime/runtime-common/Cargo.toml index b835152cac0..b81c5d496e8 100644 --- a/bridges/snowbridge/parachain/runtime/runtime-common/Cargo.toml +++ b/bridges/snowbridge/parachain/runtime/runtime-common/Cargo.toml @@ -1,10 +1,15 @@ [package] name = "snowbridge-runtime-common" description = "Snowbridge Runtime Common" -version = "0.1.1" +version = "0.9.0" authors = ["Snowfork "] -edition = "2021" +edition.workspace = true +repository.workspace = true license = "Apache-2.0" +categories = ["cryptography::cryptocurrencies"] + +[lints] +workspace = true [dependencies] log = { version = "0.4.20", default-features = false } diff --git a/bridges/snowbridge/parachain/runtime/runtime-common/README.md b/bridges/snowbridge/parachain/runtime/runtime-common/README.md new file mode 100644 index 00000000000..57d178ea2d2 --- /dev/null +++ b/bridges/snowbridge/parachain/runtime/runtime-common/README.md @@ -0,0 +1,3 @@ +# Snowbridge Runtime Common + +Common crate to contain runtime related structs and implementations for Snowbridge. diff --git a/bridges/snowbridge/parachain/runtime/tests/Cargo.toml b/bridges/snowbridge/parachain/runtime/test-common/Cargo.toml similarity index 78% rename from bridges/snowbridge/parachain/runtime/tests/Cargo.toml rename to bridges/snowbridge/parachain/runtime/test-common/Cargo.toml index 0a09f89c6b9..ae72de406fc 100644 --- a/bridges/snowbridge/parachain/runtime/tests/Cargo.toml +++ b/bridges/snowbridge/parachain/runtime/test-common/Cargo.toml @@ -1,10 +1,14 @@ [package] -name = "snowbridge-runtime-tests" +name = "snowbridge-runtime-test-common" description = "Snowbridge Runtime Tests" -version = "0.1.0" +version = "0.9.0" authors = ["Snowfork "] edition = "2021" license = "Apache-2.0" +categories = ["cryptography::cryptocurrencies"] + +[lints] +workspace = true [dependencies] codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } @@ -48,7 +52,6 @@ sp-transaction-pool = { path = "../../../../../substrate/primitives/transaction- sp-version = { path = "../../../../../substrate/primitives/version", default-features = false } # Polkadot -rococo-runtime-constants = { path = "../../../../../polkadot/runtime/rococo/constants", default-features = false } pallet-xcm = { path = "../../../../../polkadot/xcm/pallet-xcm", default-features = false } pallet-xcm-benchmarks = { path = "../../../../../polkadot/xcm/pallet-xcm-benchmarks", default-features = false, optional = true } polkadot-core-primitives = { path = "../../../../../polkadot/core-primitives", default-features = false } @@ -71,19 +74,17 @@ pallet-collator-selection = { path = "../../../../../cumulus/pallets/collator-se parachain-info = { package = "staging-parachain-info", path = "../../../../../cumulus/parachains/pallets/parachain-info", default-features = false } parachains-common = { path = "../../../../../cumulus/parachains/common", default-features = false } parachains-runtimes-test-utils = { path = "../../../../../cumulus/parachains/runtimes/test-utils", default-features = false } -bridge-hub-rococo-runtime = { path = "../../../../../cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo", default-features = false } -asset-hub-rococo-runtime = { path = "../../../../../cumulus/parachains/runtimes/assets/asset-hub-rococo", default-features = false } assets-common = { path = "../../../../../cumulus/parachains/runtimes/assets/common", default-features = false } # Ethereum Bridge (Snowbridge) snowbridge-core = { path = "../../primitives/core", default-features = false } snowbridge-beacon-primitives = { path = "../../primitives/beacon", default-features = false } snowbridge-router-primitives = { path = "../../primitives/router", default-features = false } -snowbridge-ethereum-beacon-client = { path = "../../pallets/ethereum-beacon-client", default-features = false } -snowbridge-inbound-queue = { path = "../../pallets/inbound-queue", default-features = false } -snowbridge-outbound-queue = { path = "../../pallets/outbound-queue", default-features = false } +snowbridge-pallet-ethereum-client = { path = "../../pallets/ethereum-client", default-features = false } +snowbridge-pallet-inbound-queue = { path = "../../pallets/inbound-queue", default-features = false } +snowbridge-pallet-outbound-queue = { path = "../../pallets/outbound-queue", default-features = false } snowbridge-outbound-queue-runtime-api = { path = "../../pallets/outbound-queue/runtime-api", default-features = false } -snowbridge-system = { path = "../../pallets/system", default-features = false } +snowbridge-pallet-system = { path = "../../pallets/system", default-features = false } snowbridge-system-runtime-api = { path = "../../pallets/system/runtime-api", default-features = false } [dev-dependencies] @@ -95,9 +96,7 @@ sp-keyring = { path = "../../../../../substrate/primitives/keyring" } [features] default = ["std"] std = [ - "asset-hub-rococo-runtime/std", "assets-common/std", - "bridge-hub-rococo-runtime/std", "codec/std", "cumulus-pallet-aura-ext/std", "cumulus-pallet-dmp-queue/std", @@ -134,18 +133,17 @@ std = [ "polkadot-core-primitives/std", "polkadot-parachain-primitives/std", "polkadot-runtime-common/std", - "rococo-runtime-constants/std", "scale-info/std", "serde", "snowbridge-beacon-primitives/std", "snowbridge-core/std", - "snowbridge-ethereum-beacon-client/std", - "snowbridge-inbound-queue/std", "snowbridge-outbound-queue-runtime-api/std", - "snowbridge-outbound-queue/std", + "snowbridge-pallet-ethereum-client/std", + "snowbridge-pallet-inbound-queue/std", + "snowbridge-pallet-outbound-queue/std", + "snowbridge-pallet-system/std", "snowbridge-router-primitives/std", "snowbridge-system-runtime-api/std", - "snowbridge-system/std", "sp-api/std", "sp-block-builder/std", "sp-consensus-aura/std", @@ -166,9 +164,7 @@ std = [ ] runtime-benchmarks = [ - "asset-hub-rococo-runtime/runtime-benchmarks", "assets-common/runtime-benchmarks", - "bridge-hub-rococo-runtime/runtime-benchmarks", "bridge-runtime-common/runtime-benchmarks", "cumulus-pallet-dmp-queue/runtime-benchmarks", "cumulus-pallet-parachain-system/runtime-benchmarks", @@ -192,53 +188,12 @@ runtime-benchmarks = [ "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", "snowbridge-core/runtime-benchmarks", - "snowbridge-ethereum-beacon-client/runtime-benchmarks", - "snowbridge-inbound-queue/runtime-benchmarks", - "snowbridge-outbound-queue/runtime-benchmarks", + "snowbridge-pallet-ethereum-client/runtime-benchmarks", + "snowbridge-pallet-inbound-queue/runtime-benchmarks", + "snowbridge-pallet-outbound-queue/runtime-benchmarks", + "snowbridge-pallet-system/runtime-benchmarks", "snowbridge-router-primitives/runtime-benchmarks", - "snowbridge-system/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", ] - -try-runtime = [ - "asset-hub-rococo-runtime/try-runtime", - "bridge-hub-rococo-runtime/try-runtime", - "cumulus-pallet-aura-ext/try-runtime", - "cumulus-pallet-dmp-queue/try-runtime", - "cumulus-pallet-parachain-system/try-runtime", - "cumulus-pallet-xcm/try-runtime", - "cumulus-pallet-xcmp-queue/try-runtime", - "frame-executive/try-runtime", - "frame-support/try-runtime", - "frame-system/try-runtime", - "frame-try-runtime/try-runtime", - "pallet-aura/try-runtime", - "pallet-authorship/try-runtime", - "pallet-balances/try-runtime", - "pallet-collator-selection/try-runtime", - "pallet-message-queue/try-runtime", - "pallet-multisig/try-runtime", - "pallet-session/try-runtime", - "pallet-timestamp/try-runtime", - "pallet-transaction-payment/try-runtime", - "pallet-utility/try-runtime", - "pallet-xcm/try-runtime", - "parachain-info/try-runtime", - "polkadot-runtime-common/try-runtime", - "snowbridge-ethereum-beacon-client/try-runtime", - "snowbridge-inbound-queue/try-runtime", - "snowbridge-outbound-queue/try-runtime", - "snowbridge-system/try-runtime", - "sp-runtime/try-runtime", -] -fast-runtime = [ - "bridge-hub-rococo-runtime/fast-runtime", -] -experimental = ["pallet-aura/experimental"] - -# A feature that should be enabled when the runtime should be built for on-chain -# deployment. This will disable stuff that shouldn't be part of the on-chain wasm -# to make it smaller like logging for example. -on-chain-release-build = ["sp-api/disable-logging"] diff --git a/bridges/snowbridge/parachain/runtime/test-common/README.md b/bridges/snowbridge/parachain/runtime/test-common/README.md new file mode 100644 index 00000000000..d582f87142b --- /dev/null +++ b/bridges/snowbridge/parachain/runtime/test-common/README.md @@ -0,0 +1,3 @@ +# Runtime Tests + +Tests runtime config and bridge functionality in the boundaries of a runtime. diff --git a/bridges/snowbridge/parachain/runtime/tests/src/test_cases.rs b/bridges/snowbridge/parachain/runtime/test-common/src/lib.rs similarity index 88% rename from bridges/snowbridge/parachain/runtime/tests/src/test_cases.rs rename to bridges/snowbridge/parachain/runtime/test-common/src/lib.rs index e5a45cdc92b..8a6834db2e4 100644 --- a/bridges/snowbridge/parachain/runtime/tests/src/test_cases.rs +++ b/bridges/snowbridge/parachain/runtime/test-common/src/lib.rs @@ -1,12 +1,9 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -//! Module contains predefined test-case scenarios for `Runtime` with bridging capabilities. - -use asset_hub_rococo_runtime::xcm_config::bridging::to_ethereum::DefaultBridgeHubEthereumBaseFee; -use bridge_hub_rococo_runtime::EthereumSystem; use codec::Encode; use frame_support::{assert_err, assert_ok, traits::fungible::Mutate}; +pub use parachains_runtimes_test_utils::test_cases::change_storage_constant_by_governance_works; use parachains_runtimes_test_utils::{ AccountIdOf, BalanceOf, CollatorSessionKeys, ExtBuilder, ValidatorIdOf, XcmReceivedFrom, }; @@ -49,7 +46,7 @@ where + parachain_info::Config + pallet_collator_selection::Config + cumulus_pallet_parachain_system::Config - + snowbridge_outbound_queue::Config, + + snowbridge_pallet_outbound_queue::Config, XcmConfig: xcm_executor::Config, { let assethub_parachain_location = MultiLocation::new(1, Parachain(assethub_parachain_id)); @@ -109,8 +106,8 @@ pub fn send_transfer_token_message_success( weth_contract_address: H160, destination_address: H160, fee_amount: u128, - snowbridge_outbound_queue: Box< - dyn Fn(Vec) -> Option>, + snowbridge_pallet_outbound_queue: Box< + dyn Fn(Vec) -> Option>, >, ) where Runtime: frame_system::Config @@ -120,8 +117,8 @@ pub fn send_transfer_token_message_success( + parachain_info::Config + pallet_collator_selection::Config + cumulus_pallet_parachain_system::Config - + snowbridge_outbound_queue::Config - + snowbridge_system::Config, + + snowbridge_pallet_outbound_queue::Config + + snowbridge_pallet_system::Config, XcmConfig: xcm_executor::Config, ValidatorIdOf: From>, { @@ -132,14 +129,14 @@ pub fn send_transfer_token_message_success( .with_tracing() .build() .execute_with(|| { - EthereumSystem::initialize(runtime_para_id.into(), assethub_parachain_id.into()) - .unwrap(); + >::initialize( + runtime_para_id.into(), + assethub_parachain_id.into(), + ) + .unwrap(); // fund asset hub sovereign account enough so it can pay fees - initial_fund::( - assethub_parachain_id, - DefaultBridgeHubEthereumBaseFee::get() + 1_000_000_000, - ); + initial_fund::(assethub_parachain_id, 5_000_000_000_000); let outcome = send_transfer_token_message::( assethub_parachain_id, @@ -153,10 +150,11 @@ pub fn send_transfer_token_message_success( // check events let mut events = >::events() .into_iter() - .filter_map(|e| snowbridge_outbound_queue(e.event.encode())); - assert!( - events.any(|e| matches!(e, snowbridge_outbound_queue::Event::MessageQueued { .. })) - ); + .filter_map(|e| snowbridge_pallet_outbound_queue(e.event.encode())); + assert!(events.any(|e| matches!( + e, + snowbridge_pallet_outbound_queue::Event::MessageQueued { .. } + ))); }); } @@ -174,7 +172,7 @@ pub fn send_unpaid_transfer_token_message( + parachain_info::Config + pallet_collator_selection::Config + cumulus_pallet_parachain_system::Config - + snowbridge_outbound_queue::Config, + + snowbridge_pallet_outbound_queue::Config, XcmConfig: xcm_executor::Config, ValidatorIdOf: From>, { @@ -263,8 +261,8 @@ pub fn send_transfer_token_message_failure( + parachain_info::Config + pallet_collator_selection::Config + cumulus_pallet_parachain_system::Config - + snowbridge_outbound_queue::Config - + snowbridge_system::Config, + + snowbridge_pallet_outbound_queue::Config + + snowbridge_pallet_system::Config, XcmConfig: xcm_executor::Config, ValidatorIdOf: From>, { @@ -275,8 +273,11 @@ pub fn send_transfer_token_message_failure( .with_tracing() .build() .execute_with(|| { - EthereumSystem::initialize(runtime_para_id.into(), assethub_parachain_id.into()) - .unwrap(); + >::initialize( + runtime_para_id.into(), + assethub_parachain_id.into(), + ) + .unwrap(); // fund asset hub sovereign account enough so it can pay fees initial_fund::(assethub_parachain_id, initial_amount); diff --git a/bridges/snowbridge/parachain/scripts/benchmark.sh b/bridges/snowbridge/parachain/scripts/benchmark.sh index c47649b2eeb..c9a561b33c4 100755 --- a/bridges/snowbridge/parachain/scripts/benchmark.sh +++ b/bridges/snowbridge/parachain/scripts/benchmark.sh @@ -7,9 +7,9 @@ cargo run --release --bin polkadot-parachain \ -- \ benchmark pallet \ --chain=bridge-hub-rococo-dev \ ---pallet=snowbridge_ethereum_beacon_client \ +--pallet=snowbridge_pallet_ethereum_client \ --extrinsic="*" \ --execution=wasm --wasm-execution=compiled \ --steps 50 --repeat 20 \ ---output ./parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_ethereum_beacon_client.rs +--output ./parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_ethereum_client.rs popd diff --git a/bridges/snowbridge/parachain/scripts/verify-pallets-build.sh b/bridges/snowbridge/parachain/scripts/verify-pallets-build.sh index 74cec954832..a62f48c84d4 100755 --- a/bridges/snowbridge/parachain/scripts/verify-pallets-build.sh +++ b/bridges/snowbridge/parachain/scripts/verify-pallets-build.sh @@ -78,7 +78,7 @@ rm -rf $SNOWBRIDGE_FOLDER/parachain/.gitignore rm -rf $SNOWBRIDGE_FOLDER/parachain/templates rm -rf $SNOWBRIDGE_FOLDER/parachain/.cargo rm -rf $SNOWBRIDGE_FOLDER/parachain/.config -rm -rf $SNOWBRIDGE_FOLDER/parachain/pallets/ethereum-beacon-client/fuzz +rm -rf $SNOWBRIDGE_FOLDER/parachain/pallets/ethereum-client/fuzz cd bridges/snowbridge/parachain @@ -93,18 +93,18 @@ find "." -name 'Cargo.toml' | while read -r file; do done # let's test if everything we need compiles -cargo check -p snowbridge-ethereum-beacon-client -cargo check -p snowbridge-ethereum-beacon-client --features runtime-benchmarks -cargo check -p snowbridge-ethereum-beacon-client --features try-runtime -cargo check -p snowbridge-inbound-queue -cargo check -p snowbridge-inbound-queue --features runtime-benchmarks -cargo check -p snowbridge-inbound-queue --features try-runtime -cargo check -p snowbridge-outbound-queue -cargo check -p snowbridge-outbound-queue --features runtime-benchmarks -cargo check -p snowbridge-outbound-queue --features try-runtime -cargo check -p snowbridge-system -cargo check -p snowbridge-system --features runtime-benchmarks -cargo check -p snowbridge-system --features try-runtime +cargo check -p snowbridge-pallet-ethereum-client +cargo check -p snowbridge-pallet-ethereum-client --features runtime-benchmarks +cargo check -p snowbridge-pallet-ethereum-client --features try-runtime +cargo check -p snowbridge-pallet-inbound-queue +cargo check -p snowbridge-pallet-inbound-queue --features runtime-benchmarks +cargo check -p snowbridge-pallet-inbound-queue --features try-runtime +cargo check -p snowbridge-pallet-outbound-queue +cargo check -p snowbridge-pallet-outbound-queue --features runtime-benchmarks +cargo check -p snowbridge-pallet-outbound-queue --features try-runtime +cargo check -p snowbridge-pallet-system +cargo check -p snowbridge-pallet-system --features runtime-benchmarks +cargo check -p snowbridge-pallet-system --features try-runtime cd - diff --git a/cumulus/parachains/common/src/rococo.rs b/cumulus/parachains/common/src/rococo.rs index 6e31def4b55..9ab57f0a6c8 100644 --- a/cumulus/parachains/common/src/rococo.rs +++ b/cumulus/parachains/common/src/rococo.rs @@ -117,3 +117,19 @@ pub mod consensus { /// Relay chain slot duration, in milliseconds. pub const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6000; } + +pub mod snowbridge { + use frame_support::parameter_types; + use xcm::opaque::lts::NetworkId; + + /// The pallet index of the Ethereum inbound queue pallet in the bridge hub runtime. + pub const INBOUND_QUEUE_PALLET_INDEX: u8 = 80; + + parameter_types! { + /// Network and location for the Ethereum chain. On Rococo, the Ethereum chain bridged + /// to is the Sepolia Ethereum testnet, with chain ID 11155111. + /// + /// + pub EthereumNetwork: NetworkId = NetworkId::Ethereum { chain_id: 11155111 }; + } +} diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/Cargo.toml index d923f7388a2..2bc57bf2548 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/Cargo.toml @@ -30,6 +30,6 @@ bridge-hub-common = { path = "../../../../../../runtimes/bridge-hubs/common", de # Snowbridge snowbridge-core = { path = "../../../../../../../../bridges/snowbridge/parachain/primitives/core", default-features = false } snowbridge-router-primitives = { path = "../../../../../../../../bridges/snowbridge/parachain/primitives/router", default-features = false } -snowbridge-system = { path = "../../../../../../../../bridges/snowbridge/parachain/pallets/system", default-features = false } -snowbridge-inbound-queue = { path = "../../../../../../../../bridges/snowbridge/parachain/pallets/inbound-queue", default-features = false } -snowbridge-outbound-queue = { path = "../../../../../../../../bridges/snowbridge/parachain/pallets/outbound-queue", default-features = false } +snowbridge-pallet-system = { path = "../../../../../../../../bridges/snowbridge/parachain/pallets/system", default-features = false } +snowbridge-pallet-inbound-queue = { path = "../../../../../../../../bridges/snowbridge/parachain/pallets/inbound-queue", default-features = false } +snowbridge-pallet-outbound-queue = { path = "../../../../../../../../bridges/snowbridge/parachain/pallets/outbound-queue", default-features = false } diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml index e75187bea95..0904578b156 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml @@ -48,7 +48,6 @@ asset-hub-rococo-runtime = { path = "../../../../../runtimes/assets/asset-hub-ro # Snowbridge snowbridge-core = { path = "../../../../../../../bridges/snowbridge/parachain/primitives/core", default-features = false } snowbridge-router-primitives = { path = "../../../../../../../bridges/snowbridge/parachain/primitives/router", default-features = false } -snowbridge-system = { path = "../../../../../../../bridges/snowbridge/parachain/pallets/system", default-features = false } -snowbridge-inbound-queue = { path = "../../../../../../../bridges/snowbridge/parachain/pallets/inbound-queue", default-features = false } -snowbridge-outbound-queue = { path = "../../../../../../../bridges/snowbridge/parachain/pallets/outbound-queue", default-features = false } -snowbridge-rococo-common = { path = "../../../../../../../bridges/snowbridge/parachain/runtime/rococo-common", default-features = false } +snowbridge-pallet-system = { path = "../../../../../../../bridges/snowbridge/parachain/pallets/system", default-features = false } +snowbridge-pallet-inbound-queue = { path = "../../../../../../../bridges/snowbridge/parachain/pallets/inbound-queue", default-features = false } +snowbridge-pallet-outbound-queue = { path = "../../../../../../../bridges/snowbridge/parachain/pallets/outbound-queue", default-features = false } diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs index e62a73caff5..85547f210a7 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs @@ -17,12 +17,12 @@ use codec::{Decode, Encode}; use emulated_integration_tests_common::xcm_emulator::ConvertLocation; use frame_support::pallet_prelude::TypeInfo; use hex_literal::hex; +use parachains_common::rococo::snowbridge::EthereumNetwork; use snowbridge_core::outbound::OperatingMode; -use snowbridge_rococo_common::EthereumNetwork; +use snowbridge_pallet_system; use snowbridge_router_primitives::inbound::{ Command, Destination, GlobalConsensusEthereumConvertsFor, MessageV1, VersionedMessage, }; -use snowbridge_system; use sp_core::H256; const INITIAL_FUND: u128 = 5_000_000_000 * ROCOCO_ED; @@ -94,7 +94,7 @@ fn create_agent() { assert_expected_events!( BridgeHubRococo, vec![ - RuntimeEvent::EthereumSystem(snowbridge_system::Event::CreateAgent { + RuntimeEvent::EthereumSystem(snowbridge_pallet_system::Event::CreateAgent { .. }) => {}, ] @@ -168,7 +168,7 @@ fn create_channel() { assert_expected_events!( BridgeHubRococo, vec![ - RuntimeEvent::EthereumSystem(snowbridge_system::Event::CreateChannel { + RuntimeEvent::EthereumSystem(snowbridge_pallet_system::Event::CreateChannel { .. }) => {}, ] @@ -190,7 +190,10 @@ fn register_weth_token_from_ethereum_to_asset_hub() { chain_id: CHAIN_ID, command: Command::RegisterToken { token: WETH.into(), fee: XCM_FEE }, }); - let (xcm, _) = EthereumInboundQueue::do_convert(message_id_, message).unwrap(); + let (xcm, fee) = EthereumInboundQueue::do_convert(message_id_, message).unwrap(); + + assert_ok!(EthereumInboundQueue::burn_fees(AssetHubRococo::para_id().into(), fee)); + let _ = EthereumInboundQueue::send_xcm(xcm, AssetHubRococo::para_id().into()).unwrap(); assert_expected_events!( @@ -481,7 +484,7 @@ fn send_weth_asset_from_asset_hub_to_ethereum() { assert_expected_events!( BridgeHubRococo, vec![ - RuntimeEvent::EthereumOutboundQueue(snowbridge_outbound_queue::Event::MessageQueued {..}) => {}, + RuntimeEvent::EthereumOutboundQueue(snowbridge_pallet_outbound_queue::Event::MessageQueued {..}) => {}, ] ); let events = BridgeHubRococo::events(); diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml index 43579cfe5bb..5d0cb41395f 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml @@ -91,7 +91,6 @@ bp-asset-hub-westend = { path = "../../../../../bridges/primitives/chain-asset-h bp-bridge-hub-rococo = { path = "../../../../../bridges/primitives/chain-bridge-hub-rococo", default-features = false } bp-bridge-hub-westend = { path = "../../../../../bridges/primitives/chain-bridge-hub-westend", default-features = false } snowbridge-router-primitives = { path = "../../../../../bridges/snowbridge/parachain/primitives/router", default-features = false } -snowbridge-rococo-common = { path = "../../../../../bridges/snowbridge/parachain/runtime/rococo-common", default-features = false } [dev-dependencies] asset-test-utils = { path = "../test-utils" } @@ -139,7 +138,6 @@ runtime-benchmarks = [ "parachains-common/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", - "snowbridge-rococo-common/runtime-benchmarks", "snowbridge-router-primitives/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", @@ -231,7 +229,6 @@ std = [ "primitive-types/std", "rococo-runtime-constants/std", "scale-info/std", - "snowbridge-rococo-common/std", "snowbridge-router-primitives/std", "sp-api/std", "sp-block-builder/std", diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 0423dd0ac86..3010cbc69fa 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -35,7 +35,7 @@ use assets_common::{ }; use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; use cumulus_primitives_core::AggregateMessageOrigin; -use snowbridge_rococo_common::EthereumNetwork; +use parachains_common::rococo::snowbridge::EthereumNetwork; use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; use sp_runtime::{ diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs index 2826c18f3f7..121e213b57f 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs @@ -31,6 +31,7 @@ use frame_system::EnsureRoot; use pallet_xcm::XcmPassthrough; use parachains_common::{ impls::ToStakingPot, + rococo::snowbridge::EthereumNetwork, xcm_config::{ AllSiblingSystemParachains, AssetFeeAsExistentialDepositMultiplier, ConcreteAssetFromSystem, ParentRelayOrSiblingParachains, RelayOrOtherSystemParachains, @@ -39,7 +40,6 @@ use parachains_common::{ }; use polkadot_parachain_primitives::primitives::Sibling; use polkadot_runtime_common::xcm_sender::ExponentialPrice; -use snowbridge_rococo_common::EthereumNetwork; use snowbridge_router_primitives::inbound::GlobalConsensusEthereumConvertsFor; use sp_runtime::traits::{AccountIdConversion, ConvertInto}; use xcm::latest::prelude::*; @@ -817,7 +817,7 @@ pub mod bridging { 1, X2( Parachain(SiblingBridgeHubParaId::get()), - PalletInstance(snowbridge_rococo_common::INBOUND_QUEUE_MESSAGES_PALLET_INDEX) + PalletInstance(parachains_common::rococo::snowbridge::INBOUND_QUEUE_PALLET_INDEX) ) ); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml index bc8fa72bb0b..849a4cf8cd6 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml @@ -108,16 +108,15 @@ bridge-runtime-common = { path = "../../../../../bridges/bin/runtime-common", de # Ethereum Bridge (Snowbridge) snowbridge-beacon-primitives = { path = "../../../../../bridges/snowbridge/parachain/primitives/beacon", default-features = false } -snowbridge-system = { path = "../../../../../bridges/snowbridge/parachain/pallets/system", default-features = false } +snowbridge-pallet-system = { path = "../../../../../bridges/snowbridge/parachain/pallets/system", default-features = false } snowbridge-system-runtime-api = { path = "../../../../../bridges/snowbridge/parachain/pallets/system/runtime-api", default-features = false } snowbridge-core = { path = "../../../../../bridges/snowbridge/parachain/primitives/core", default-features = false } -snowbridge-ethereum-beacon-client = { path = "../../../../../bridges/snowbridge/parachain/pallets/ethereum-beacon-client", default-features = false } -snowbridge-inbound-queue = { path = "../../../../../bridges/snowbridge/parachain/pallets/inbound-queue", default-features = false } -snowbridge-outbound-queue = { path = "../../../../../bridges/snowbridge/parachain/pallets/outbound-queue", default-features = false } +snowbridge-pallet-ethereum-client = { path = "../../../../../bridges/snowbridge/parachain/pallets/ethereum-client", default-features = false } +snowbridge-pallet-inbound-queue = { path = "../../../../../bridges/snowbridge/parachain/pallets/inbound-queue", default-features = false } +snowbridge-pallet-outbound-queue = { path = "../../../../../bridges/snowbridge/parachain/pallets/outbound-queue", default-features = false } snowbridge-outbound-queue-runtime-api = { path = "../../../../../bridges/snowbridge/parachain/pallets/outbound-queue/runtime-api", default-features = false } snowbridge-router-primitives = { path = "../../../../../bridges/snowbridge/parachain/primitives/router", default-features = false } snowbridge-runtime-common = { path = "../../../../../bridges/snowbridge/parachain/runtime/runtime-common", default-features = false } -snowbridge-rococo-common = { path = "../../../../../bridges/snowbridge/parachain/runtime/rococo-common", default-features = false } bridge-hub-common = { path = "../common", default-features = false } @@ -128,6 +127,7 @@ bridge-runtime-common = { path = "../../../../../bridges/bin/runtime-common", fe "integrity-test", ] } sp-keyring = { path = "../../../../../substrate/primitives/keyring" } +snowbridge-runtime-test-common = { path = "../../../../../bridges/snowbridge/parachain/runtime/test-common" } [features] default = ["std"] @@ -192,15 +192,14 @@ std = [ "serde", "snowbridge-beacon-primitives/std", "snowbridge-core/std", - "snowbridge-ethereum-beacon-client/std", - "snowbridge-inbound-queue/std", "snowbridge-outbound-queue-runtime-api/std", - "snowbridge-outbound-queue/std", - "snowbridge-rococo-common/std", + "snowbridge-pallet-ethereum-client/std", + "snowbridge-pallet-inbound-queue/std", + "snowbridge-pallet-outbound-queue/std", + "snowbridge-pallet-system/std", "snowbridge-router-primitives/std", "snowbridge-runtime-common/std", "snowbridge-system-runtime-api/std", - "snowbridge-system/std", "sp-api/std", "sp-block-builder/std", "sp-consensus-aura/std", @@ -251,13 +250,13 @@ runtime-benchmarks = [ "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", "snowbridge-core/runtime-benchmarks", - "snowbridge-ethereum-beacon-client/runtime-benchmarks", - "snowbridge-inbound-queue/runtime-benchmarks", - "snowbridge-outbound-queue/runtime-benchmarks", - "snowbridge-rococo-common/runtime-benchmarks", + "snowbridge-pallet-ethereum-client/runtime-benchmarks", + "snowbridge-pallet-inbound-queue/runtime-benchmarks", + "snowbridge-pallet-outbound-queue/runtime-benchmarks", + "snowbridge-pallet-system/runtime-benchmarks", "snowbridge-router-primitives/runtime-benchmarks", "snowbridge-runtime-common/runtime-benchmarks", - "snowbridge-system/runtime-benchmarks", + "snowbridge-runtime-test-common/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", @@ -290,16 +289,16 @@ try-runtime = [ "pallet-xcm/try-runtime", "parachain-info/try-runtime", "polkadot-runtime-common/try-runtime", - "snowbridge-ethereum-beacon-client/try-runtime", - "snowbridge-inbound-queue/try-runtime", - "snowbridge-outbound-queue/try-runtime", - "snowbridge-system/try-runtime", + "snowbridge-pallet-ethereum-client/try-runtime", + "snowbridge-pallet-inbound-queue/try-runtime", + "snowbridge-pallet-outbound-queue/try-runtime", + "snowbridge-pallet-system/try-runtime", "sp-runtime/try-runtime", ] experimental = ["pallet-aura/experimental"] fast-runtime = [ - "snowbridge-ethereum-beacon-client/beacon-spec-minimal", + "snowbridge-pallet-ethereum-client/beacon-spec-minimal", ] # A feature that should be enabled when the runtime should be built for on-chain diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_ethereum_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_ethereum_config.rs index af2438efbcf..d633da2a8e7 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_ethereum_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_ethereum_config.rs @@ -15,13 +15,13 @@ // along with Cumulus. If not, see . use crate::{xcm_config::UniversalLocation, Runtime}; -use snowbridge_rococo_common::EthereumNetwork; +use parachains_common::rococo::snowbridge::EthereumNetwork; use snowbridge_router_primitives::outbound::EthereumBlobExporter; /// Exports message to the Ethereum Gateway contract. pub type SnowbridgeExporter = EthereumBlobExporter< UniversalLocation, EthereumNetwork, - snowbridge_outbound_queue::Pallet, + snowbridge_pallet_outbound_queue::Pallet, snowbridge_core::AgentIdOf, >; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index b1ff98491da..0052e9dcb38 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -71,8 +71,6 @@ use frame_system::{ }; use bp_runtime::HeaderId; -#[cfg(not(feature = "runtime-benchmarks"))] -use bridge_hub_common::BridgeHubMessageRouter; use bridge_hub_common::{ message_queue::{NarrowOriginToSibling, ParaIdToSibling}, AggregateMessageOrigin, @@ -102,17 +100,9 @@ use parachains_common::{ use polkadot_runtime_common::prod_or_fast; #[cfg(feature = "runtime-benchmarks")] -use crate::xcm_config::benchmark_helpers::DoNothingRouter; -#[cfg(feature = "runtime-benchmarks")] -use snowbridge_beacon_primitives::CompactExecutionHeader; -#[cfg(feature = "runtime-benchmarks")] -use snowbridge_core::RingBufferMap; -#[cfg(feature = "runtime-benchmarks")] -pub use snowbridge_ethereum_beacon_client::ExecutionHeaderBuffer; -#[cfg(feature = "runtime-benchmarks")] -use snowbridge_inbound_queue::BenchmarkHelper; -#[cfg(feature = "runtime-benchmarks")] -use sp_core::H256; +use benchmark_helpers::DoNothingRouter; +#[cfg(not(feature = "runtime-benchmarks"))] +use bridge_hub_common::BridgeHubMessageRouter; /// The address format for describing accounts. pub type Address = MultiAddress; @@ -154,7 +144,7 @@ pub type Migrations = ( InitStorageVersions, cumulus_pallet_xcmp_queue::migration::v4::MigrationToV4, // unreleased - snowbridge_system::migration::v0::InitializeOnUpgrade< + snowbridge_pallet_system::migration::v0::InitializeOnUpgrade< Runtime, ConstU32, ConstU32, @@ -512,7 +502,7 @@ parameter_types! { parameter_types! { pub const CreateAssetCall: [u8;2] = [53, 0]; pub const CreateAssetDeposit: u128 = (UNITS / 10) + EXISTENTIAL_DEPOSIT; - pub const InboundQueuePalletInstance: u8 = snowbridge_rococo_common::INBOUND_QUEUE_MESSAGES_PALLET_INDEX; + pub const InboundQueuePalletInstance: u8 = parachains_common::rococo::snowbridge::INBOUND_QUEUE_PALLET_INDEX; pub Parameters: PricingParameters = PricingParameters { exchange_rate: FixedU128::from_rational(1, 400), fee_per_gas: gwei(20), @@ -521,15 +511,46 @@ parameter_types! { } #[cfg(feature = "runtime-benchmarks")] -impl BenchmarkHelper for Runtime { - fn initialize_storage(block_hash: H256, header: CompactExecutionHeader) { - >::insert(block_hash, header); +pub mod benchmark_helpers { + use crate::{EthereumBeaconClient, Runtime, RuntimeOrigin}; + use codec::Encode; + use snowbridge_beacon_primitives::CompactExecutionHeader; + use snowbridge_pallet_inbound_queue::BenchmarkHelper; + use sp_core::H256; + use xcm::latest::{MultiAssets, MultiLocation, SendError, SendResult, SendXcm, Xcm, XcmHash}; + + impl BenchmarkHelper for Runtime { + fn initialize_storage(block_hash: H256, header: CompactExecutionHeader) { + EthereumBeaconClient::store_execution_header(block_hash, header, 0, H256::default()) + } + } + + pub struct DoNothingRouter; + impl SendXcm for DoNothingRouter { + type Ticket = Xcm<()>; + + fn validate( + _dest: &mut Option, + xcm: &mut Option>, + ) -> SendResult { + Ok((xcm.clone().unwrap(), MultiAssets::new())) + } + fn deliver(xcm: Xcm<()>) -> Result { + let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + Ok(hash) + } + } + + impl snowbridge_pallet_system::BenchmarkHelper for () { + fn make_xcm_origin(location: MultiLocation) -> RuntimeOrigin { + RuntimeOrigin::from(pallet_xcm::Origin::Xcm(location)) + } } } -impl snowbridge_inbound_queue::Config for Runtime { +impl snowbridge_pallet_inbound_queue::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type Verifier = snowbridge_ethereum_beacon_client::Pallet; + type Verifier = snowbridge_pallet_ethereum_client::Pallet; type Token = Balances; #[cfg(not(feature = "runtime-benchmarks"))] type XcmSender = XcmRouter; @@ -549,11 +570,12 @@ impl snowbridge_inbound_queue::Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = ConstantMultiplier; type MaxMessageSize = ConstU32<2048>; - type WeightInfo = weights::snowbridge_inbound_queue::WeightInfo; + type WeightInfo = weights::snowbridge_pallet_inbound_queue::WeightInfo; type PricingParameters = EthereumSystem; + type AssetTransactor = ::AssetTransactor; } -impl snowbridge_outbound_queue::Config for Runtime { +impl snowbridge_pallet_outbound_queue::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Hashing = Keccak256; type MessageQueue = MessageQueue; @@ -563,7 +585,7 @@ impl snowbridge_outbound_queue::Config for Runtime { type GasMeter = snowbridge_core::outbound::ConstantGasMeter; type Balance = Balance; type WeightToFee = WeightToFee; - type WeightInfo = weights::snowbridge_outbound_queue::WeightInfo; + type WeightInfo = weights::snowbridge_pallet_outbound_queue::WeightInfo; type PricingParameters = EthereumSystem; type Channels = EthereumSystem; } @@ -616,28 +638,21 @@ parameter_types! { pub const MaxExecutionHeadersToKeep: u32 = prod_or_fast!(8192 * 2, 1000); } -impl snowbridge_ethereum_beacon_client::Config for Runtime { +impl snowbridge_pallet_ethereum_client::Config for Runtime { type RuntimeEvent = RuntimeEvent; type ForkVersions = ChainForkVersions; type MaxExecutionHeadersToKeep = MaxExecutionHeadersToKeep; - type WeightInfo = weights::snowbridge_ethereum_beacon_client::WeightInfo; -} - -#[cfg(feature = "runtime-benchmarks")] -impl snowbridge_system::BenchmarkHelper for () { - fn make_xcm_origin(location: xcm::latest::MultiLocation) -> RuntimeOrigin { - RuntimeOrigin::from(pallet_xcm::Origin::Xcm(location)) - } + type WeightInfo = weights::snowbridge_pallet_ethereum_client::WeightInfo; } -impl snowbridge_system::Config for Runtime { +impl snowbridge_pallet_system::Config for Runtime { type RuntimeEvent = RuntimeEvent; type OutboundQueue = EthereumOutboundQueue; type SiblingOrigin = EnsureXcm; type AgentIdOf = snowbridge_core::AgentIdOf; type TreasuryAccount = TreasuryAccount; type Token = Balances; - type WeightInfo = weights::snowbridge_system::WeightInfo; + type WeightInfo = weights::snowbridge_pallet_system::WeightInfo; #[cfg(feature = "runtime-benchmarks")] type Helper = (); type DefaultPricingParameters = Parameters; @@ -703,10 +718,10 @@ construct_runtime!( // With-Rococo Bulletin bridge hub pallet. XcmOverPolkadotBulletin: pallet_xcm_bridge_hub::::{Pallet} = 62, - EthereumInboundQueue: snowbridge_inbound_queue::{Pallet, Call, Storage, Event} = 80, - EthereumOutboundQueue: snowbridge_outbound_queue::{Pallet, Call, Storage, Event} = 81, - EthereumBeaconClient: snowbridge_ethereum_beacon_client::{Pallet, Call, Storage, Event} = 82, - EthereumSystem: snowbridge_system::{Pallet, Call, Storage, Config, Event} = 83, + EthereumInboundQueue: snowbridge_pallet_inbound_queue::{Pallet, Call, Storage, Event} = 80, + EthereumOutboundQueue: snowbridge_pallet_outbound_queue::{Pallet, Call, Storage, Event} = 81, + EthereumBeaconClient: snowbridge_pallet_ethereum_client::{Pallet, Call, Storage, Event} = 82, + EthereumSystem: snowbridge_pallet_system::{Pallet, Call, Storage, Config, Event} = 83, // Message Queue. Importantly, is registered last so that messages are processed after // the `on_initialize` hooks of bridging pallets. @@ -758,10 +773,10 @@ mod benches { [pallet_bridge_messages, RococoToRococoBulletin] [pallet_bridge_relayers, BridgeRelayersBench::] // Ethereum Bridge - [snowbridge_inbound_queue, EthereumInboundQueue] - [snowbridge_outbound_queue, EthereumOutboundQueue] - [snowbridge_system, EthereumSystem] - [snowbridge_ethereum_beacon_client, EthereumBeaconClient] + [snowbridge_pallet_inbound_queue, EthereumInboundQueue] + [snowbridge_pallet_outbound_queue, EthereumOutboundQueue] + [snowbridge_pallet_system, EthereumSystem] + [snowbridge_pallet_ethereum_client, EthereumBeaconClient] ); } @@ -991,18 +1006,18 @@ impl_runtime_apis! { } impl snowbridge_outbound_queue_runtime_api::OutboundQueueApi for Runtime { - fn prove_message(leaf_index: u64) -> Option { - snowbridge_outbound_queue::api::prove_message::(leaf_index) + fn prove_message(leaf_index: u64) -> Option { + snowbridge_pallet_outbound_queue::api::prove_message::(leaf_index) } fn calculate_fee(message: Message) -> Option { - snowbridge_outbound_queue::api::calculate_fee::(message) + snowbridge_pallet_outbound_queue::api::calculate_fee::(message) } } impl snowbridge_system_runtime_api::ControlApi for Runtime { fn agent_id(location: VersionedMultiLocation) -> Option { - snowbridge_system::api::agent_id::(location) + snowbridge_pallet_system::api::agent_id::(location) } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs index b134bb41ed1..aac39a4564f 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs @@ -40,10 +40,10 @@ pub mod pallet_utility; pub mod pallet_xcm; pub mod paritydb_weights; pub mod rocksdb_weights; -pub mod snowbridge_ethereum_beacon_client; -pub mod snowbridge_inbound_queue; -pub mod snowbridge_outbound_queue; -pub mod snowbridge_system; +pub mod snowbridge_pallet_ethereum_client; +pub mod snowbridge_pallet_inbound_queue; +pub mod snowbridge_pallet_outbound_queue; +pub mod snowbridge_pallet_system; pub mod xcm; pub use block_weights::constants::BlockExecutionWeight; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_ethereum_beacon_client.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_ethereum_client.rs similarity index 97% rename from cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_ethereum_beacon_client.rs rename to cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_ethereum_client.rs index cd960597b44..0d5f29c6ff2 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_ethereum_beacon_client.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_ethereum_client.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `snowbridge_ethereum_beacon_client` +//! Autogenerated weights for `snowbridge_pallet_ethereum_client` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev //! DATE: 2023-06-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` @@ -47,9 +47,9 @@ use frame_support::{traits::Get, weights::Weight}; use core::marker::PhantomData; -/// Weight functions for `snowbridge_ethereum_beacon_client`. +/// Weight functions for `snowbridge_pallet_ethereum_client`. pub struct WeightInfo(PhantomData); -impl snowbridge_ethereum_beacon_client::WeightInfo for WeightInfo { +impl snowbridge_pallet_ethereum_client::WeightInfo for WeightInfo { /// Storage: EthereumBeaconClient FinalizedBeaconStateIndex (r:1 w:1) /// Proof: EthereumBeaconClient FinalizedBeaconStateIndex (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) /// Storage: EthereumBeaconClient FinalizedBeaconStateMapping (r:1 w:1) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_inbound_queue.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_inbound_queue.rs similarity index 92% rename from cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_inbound_queue.rs rename to cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_inbound_queue.rs index f734227a411..faf404f90cb 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_inbound_queue.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_inbound_queue.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `snowbridge_inbound_queue` +//! Autogenerated weights for `snowbridge_pallet_inbound_queue` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev //! DATE: 2023-09-06, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` @@ -45,9 +45,9 @@ use frame_support::{traits::Get, weights::Weight}; use core::marker::PhantomData; -/// Weight functions for `snowbridge_inbound_queue`. +/// Weight functions for `snowbridge_pallet_inbound_queue`. pub struct WeightInfo(PhantomData); -impl snowbridge_inbound_queue::WeightInfo for WeightInfo { +impl snowbridge_pallet_inbound_queue::WeightInfo for WeightInfo { /// Storage: EthereumInboundQueue PalletOperatingMode (r:1 w:0) /// Proof: EthereumInboundQueue PalletOperatingMode (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) /// Storage: EthereumBeaconClient ExecutionHeaders (r:1 w:0) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_outbound_queue.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_outbound_queue.rs similarity index 97% rename from cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_outbound_queue.rs rename to cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_outbound_queue.rs index 6cffbc5344a..8adcef076e0 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_outbound_queue.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_outbound_queue.rs @@ -43,7 +43,7 @@ use core::marker::PhantomData; /// Weight functions for `snowbridge_outbound_queue`. pub struct WeightInfo(PhantomData); -impl snowbridge_outbound_queue::WeightInfo for WeightInfo { +impl snowbridge_pallet_outbound_queue::WeightInfo for WeightInfo { /// Storage: EthereumOutboundQueue MessageLeaves (r:1 w:1) /// Proof Skipped: EthereumOutboundQueue MessageLeaves (max_values: Some(1), max_size: None, mode: Measured) /// Storage: EthereumOutboundQueue PendingHighPriorityMessageCount (r:1 w:1) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_system.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_system.rs similarity index 98% rename from cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_system.rs rename to cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_system.rs index 88c6c669c88..c6c188e323a 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_system.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_system.rs @@ -27,12 +27,12 @@ // pallet // --chain // bridge-hub-rococo-dev -// --pallet=snowbridge_system +// --pallet=snowbridge_pallet_system // --extrinsic=* // --execution=wasm // --wasm-execution=compiled // --output -// parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_system.rs +// parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_system.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -44,7 +44,7 @@ use core::marker::PhantomData; /// Weight functions for `snowbridge_system`. pub struct WeightInfo(PhantomData); -impl snowbridge_system::WeightInfo for WeightInfo { +impl snowbridge_pallet_system::WeightInfo for WeightInfo { /// Storage: ParachainInfo ParachainId (r:1 w:0) /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) /// Storage: EthereumOutboundQueue PalletOperatingMode (r:1 w:0) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs index fc97a3ed89a..dc98622cafc 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs @@ -39,6 +39,7 @@ use frame_system::EnsureRoot; use pallet_xcm::XcmPassthrough; use parachains_common::{ impls::ToStakingPot, + rococo::snowbridge::EthereumNetwork, xcm_config::{ AllSiblingSystemParachains, ConcreteAssetFromSystem, ParentRelayOrSiblingParachains, RelayOrOtherSystemParachains, @@ -47,7 +48,6 @@ use parachains_common::{ }; use polkadot_parachain_primitives::primitives::Sibling; use polkadot_runtime_common::xcm_sender::ExponentialPrice; -use snowbridge_rococo_common::EthereumNetwork; use snowbridge_runtime_common::XcmExportFeeToSibling; use sp_core::Get; use sp_runtime::traits::AccountIdConversion; @@ -216,12 +216,12 @@ impl Contains for SafeCallFilter { WithRococoBulletinMessagesInstance, >::set_operating_mode { .. }) | RuntimeCall::EthereumBeaconClient( - snowbridge_ethereum_beacon_client::Call::force_checkpoint { .. } | - snowbridge_ethereum_beacon_client::Call::set_operating_mode { .. }, + snowbridge_pallet_ethereum_client::Call::force_checkpoint { .. } | + snowbridge_pallet_ethereum_client::Call::set_operating_mode { .. }, ) | RuntimeCall::EthereumInboundQueue( - snowbridge_inbound_queue::Call::set_operating_mode { .. }, + snowbridge_pallet_inbound_queue::Call::set_operating_mode { .. }, ) | RuntimeCall::EthereumOutboundQueue( - snowbridge_outbound_queue::Call::set_operating_mode { .. }, + snowbridge_pallet_outbound_queue::Call::set_operating_mode { .. }, ) | RuntimeCall::EthereumSystem(..) ) } @@ -492,22 +492,3 @@ impl, FeeHandler: HandleFee> FeeManager FeeHandler::handle_fee(fee, context, reason); } } - -#[cfg(feature = "runtime-benchmarks")] -pub mod benchmark_helpers { - use crate::{MultiAssets, MultiLocation, SendError, SendResult, SendXcm, Xcm, XcmHash}; - - pub struct DoNothingRouter; - impl SendXcm for DoNothingRouter { - type Ticket = (); - fn validate( - _dest: &mut Option, - _msg: &mut Option>, - ) -> SendResult<()> { - Ok(((), MultiAssets::new())) - } - fn deliver(_: ()) -> Result { - Ok([0; 32]) - } - } -} diff --git a/bridges/snowbridge/parachain/runtime/tests/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs similarity index 55% rename from bridges/snowbridge/parachain/runtime/tests/src/lib.rs rename to cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs index 9a5d12e2892..f32c6cae69c 100644 --- a/bridges/snowbridge/parachain/runtime/tests/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs @@ -1,22 +1,37 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2023 Snowfork +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. -#![cfg(test)] +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . -mod test_cases; +#![cfg(test)] -use asset_hub_rococo_runtime::xcm_config::bridging::to_ethereum::DefaultBridgeHubEthereumBaseFee; use bridge_hub_rococo_runtime::{ xcm_config::XcmConfig, MessageQueueServiceWeight, Runtime, RuntimeEvent, SessionKeys, }; use codec::Decode; use cumulus_primitives_core::XcmError::{FailedToTransactAsset, NotHoldingFees}; -use parachains_common::{AccountId, AuraId}; -use snowbridge_ethereum_beacon_client::WeightInfo; +use frame_support::parameter_types; +use parachains_common::{AccountId, AuraId, Balance}; +use snowbridge_pallet_ethereum_client::WeightInfo; use sp_core::H160; use sp_keyring::AccountKeyring::Alice; -pub fn collator_session_keys() -> bridge_hub_test_utils::CollatorSessionKeys { +parameter_types! { + pub const DefaultBridgeHubEthereumBaseFee: Balance = 2_750_872_500_000; +} + +fn collator_session_keys() -> bridge_hub_test_utils::CollatorSessionKeys { bridge_hub_test_utils::CollatorSessionKeys::new( AccountId::from(Alice), AccountId::from(Alice), @@ -26,7 +41,7 @@ pub fn collator_session_keys() -> bridge_hub_test_utils::CollatorSessionKeys( + snowbridge_runtime_test_common::send_transfer_token_message_success::( collator_session_keys(), 1013, 1000, @@ -44,7 +59,7 @@ pub fn transfer_token_to_ethereum_works() { #[test] pub fn unpaid_transfer_token_to_ethereum_fails_with_barrier() { - test_cases::send_unpaid_transfer_token_message::( + snowbridge_runtime_test_common::send_unpaid_transfer_token_message::( collator_session_keys(), 1013, 1000, @@ -55,7 +70,7 @@ pub fn unpaid_transfer_token_to_ethereum_fails_with_barrier() { #[test] pub fn transfer_token_to_ethereum_fee_not_enough() { - test_cases::send_transfer_token_message_failure::( + snowbridge_runtime_test_common::send_transfer_token_message_failure::( collator_session_keys(), 1013, 1000, @@ -70,7 +85,7 @@ pub fn transfer_token_to_ethereum_fee_not_enough() { #[test] pub fn transfer_token_to_ethereum_insufficient_fund() { - test_cases::send_transfer_token_message_failure::( + snowbridge_runtime_test_common::send_transfer_token_message_failure::( collator_session_keys(), 1013, 1000, @@ -86,9 +101,9 @@ pub fn transfer_token_to_ethereum_insufficient_fund() { fn max_message_queue_service_weight_is_more_than_beacon_extrinsic_weights() { let max_message_queue_weight = MessageQueueServiceWeight::get(); let force_checkpoint = - ::WeightInfo::force_checkpoint(); + ::WeightInfo::force_checkpoint(); let submit_checkpoint = - ::WeightInfo::submit(); + ::WeightInfo::submit(); max_message_queue_weight.all_gt(force_checkpoint); max_message_queue_weight.all_gt(submit_checkpoint); } diff --git a/cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs b/cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs index 651537ff8b7..3e821d45569 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs @@ -26,7 +26,7 @@ use sp_std::{marker::PhantomData, prelude::*}; use xcm::v3::{Junction, MultiLocation}; /// The aggregate origin of an inbound message. -/// This is specialized for BridgeHub, as the snowbridge-outbound-queue pallet is also using +/// This is specialized for BridgeHub, as the snowbridge-outbound-queue-pallet is also using /// the shared MessageQueue pallet. #[derive(Encode, Decode, Copy, MaxEncodedLen, Clone, Eq, PartialEq, TypeInfo, Debug)] pub enum AggregateMessageOrigin { diff --git a/cumulus/parachains/runtimes/testing/penpal/Cargo.toml b/cumulus/parachains/runtimes/testing/penpal/Cargo.toml index a21023a9331..cc965c154c6 100644 --- a/cumulus/parachains/runtimes/testing/penpal/Cargo.toml +++ b/cumulus/parachains/runtimes/testing/penpal/Cargo.toml @@ -79,7 +79,6 @@ pallet-collator-selection = { path = "../../../../pallets/collator-selection", d parachain-info = { package = "staging-parachain-info", path = "../../../pallets/parachain-info", default-features = false } parachains-common = { path = "../../../common", default-features = false } assets-common = { path = "../../assets/common", default-features = false } -snowbridge-rococo-common = { path = "../../../../../bridges/snowbridge/parachain/runtime/rococo-common", default-features = false } [features] default = ["std"] @@ -121,7 +120,6 @@ std = [ "polkadot-primitives/std", "polkadot-runtime-common/std", "scale-info/std", - "snowbridge-rococo-common/std", "sp-api/std", "sp-block-builder/std", "sp-consensus-aura/std", @@ -166,7 +164,6 @@ runtime-benchmarks = [ "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", - "snowbridge-rococo-common/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs index ed405aeddb3..9287ac30514 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs @@ -40,9 +40,9 @@ use frame_system::EnsureRoot; use pallet_asset_tx_payment::HandleCredit; use pallet_assets::Instance1; use pallet_xcm::XcmPassthrough; +use parachains_common::rococo::snowbridge::EthereumNetwork; use polkadot_parachain_primitives::primitives::Sibling; use polkadot_runtime_common::impls::ToAuthor; -use snowbridge_rococo_common::EthereumNetwork; use sp_runtime::traits::Zero; use xcm::latest::prelude::*; #[allow(deprecated)] -- GitLab From c8112e2c6fd9f1f5e7cb767b682fda746fc00520 Mon Sep 17 00:00:00 2001 From: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Date: Thu, 11 Jan 2024 01:30:32 +0100 Subject: [PATCH 032/392] frame-support: sp-runtime dependency updated (serde) (#2907) `frame-support` crate compilation fails (reported by @koute): ``` $ cargo check --no-default-features --target=wasm32-unknown-unknown error[E0277]: the trait bound `GC: Serialize` is not satisfied --> substrate/frame/support/src/genesis_builder_helper.rs:32:24 | 32 | serde_json::to_string(&GC::default()) | --------------------- ^^^^^^^^^^^^^^ the trait `Serialize` is not implemented for `GC` | | | required by a bound introduced by this call | note: required by a bound in `serde_json::to_string` --> /home/kou/.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde_json-1.0.111/src/ser.rs:2209:17 | 2207 | pub fn to_string(value: &T) -> Result | --------- required by a bound in this function 2208 | where 2209 | T: ?Sized + Serialize, | ^^^^^^^^^ required by this bound in `to_string` help: consider further restricting this bound | 30 | GC: BuildGenesisConfig + Default + serde::Serialize, | ++++++++++++++++++ ``` This PR should fix this. For all runtimes `sp-runtime/serde` feature was likely enabled by this (and few other pallets): https://github.com/paritytech/polkadot-sdk/blob/f2a750ee86e72c9ab677aaf588d0a33ee8446bef/substrate/frame/system/Cargo.toml#L27 --- substrate/frame/support/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/frame/support/Cargo.toml b/substrate/frame/support/Cargo.toml index 32dcec727cc..04717c012f4 100644 --- a/substrate/frame/support/Cargo.toml +++ b/substrate/frame/support/Cargo.toml @@ -24,7 +24,7 @@ frame-metadata = { version = "16.0.0", default-features = false, features = ["cu sp-api = { path = "../../primitives/api", default-features = false, features = ["frame-metadata"] } sp-std = { path = "../../primitives/std", default-features = false } sp-io = { path = "../../primitives/io", default-features = false } -sp-runtime = { path = "../../primitives/runtime", default-features = false } +sp-runtime = { path = "../../primitives/runtime", default-features = false, features = ["serde"] } sp-tracing = { path = "../../primitives/tracing", default-features = false } sp-core = { path = "../../primitives/core", default-features = false } sp-arithmetic = { path = "../../primitives/arithmetic", default-features = false } -- GitLab From 578960f3ea4f1336167861df0b6eb6dc99b9eec6 Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Thu, 11 Jan 2024 11:39:33 +0100 Subject: [PATCH 033/392] Warp sync zombienet tests: add basic BEEFY checks (#2854) Part of https://github.com/paritytech/polkadot-sdk/issues/2787 This is an initial PR that adds some basic BEEFY checks to the warp sync zombienet tests. To be more specific, it does the following: - Changes the snapshot used by the warp sync zombienet tests to one built from an updated version of the kitchensink runtime, that supports BEEFY - Adds some basic BEEFY checks to the warp sync zombienet tests - Deduplicates some params of the warp sync zombienet tests, making them easier to extend --- .gitlab/pipeline/zombienet/substrate.yml | 22 +- .../zombienet/0001-basic-warp-sync/README.md | 31 ++- .../0001-basic-warp-sync/chain-spec.json | 150 ++++++++------ .../generate-warp-sync-database.toml | 7 +- .../0001-basic-warp-sync/test-warp-sync.toml | 8 +- .../0001-basic-warp-sync/test-warp-sync.zndsl | 16 +- .../0002-validators-warp-sync/chain-spec.json | 193 +----------------- .../test-validators-warp-sync.toml | 10 +- .../test-validators-warp-sync.zndsl | 23 +-- .../chain-spec.json | 193 +----------------- .../test-block-building-warp-sync.toml | 8 +- .../test-block-building-warp-sync.zndsl | 24 ++- 12 files changed, 176 insertions(+), 509 deletions(-) mode change 100644 => 120000 substrate/zombienet/0002-validators-warp-sync/chain-spec.json mode change 100644 => 120000 substrate/zombienet/0003-block-building-warp-sync/chain-spec.json diff --git a/.gitlab/pipeline/zombienet/substrate.yml b/.gitlab/pipeline/zombienet/substrate.yml index b687576267d..ca4daa01871 100644 --- a/.gitlab/pipeline/zombienet/substrate.yml +++ b/.gitlab/pipeline/zombienet/substrate.yml @@ -40,6 +40,16 @@ tags: - zombienet-polkadot-integration-test +.zombienet-substrate-warp-sync-common: + extends: + - .zombienet-substrate-common + variables: + # DB generated from commit: https://github.com/paritytech/polkadot-sdk/commit/2e4b8996c4924fc39f85198019039cf0987f89ec + # TODO: As a workaround for https://github.com/paritytech/polkadot-sdk/issues/2568 the DB was generated in archive mode. + # After the issue is fixed, we should replace it with a pruned version of the DB. + DB_SNAPSHOT: "https://storage.googleapis.com/zombienet-db-snaps/substrate/0001-basic-warp-sync/chains-510ac1c891afe26bad6fcd6d74185917b3fb1b4f.tgz" + DB_BLOCK_HEIGHT: 47222 + zombienet-substrate-0000-block-building: extends: - .zombienet-substrate-common @@ -50,7 +60,7 @@ zombienet-substrate-0000-block-building: zombienet-substrate-0001-basic-warp-sync: extends: - - .zombienet-substrate-common + - .zombienet-substrate-warp-sync-common script: - /home/nonroot/zombie-net/scripts/ci/run-test-local-env-manager.sh --local-dir="${LOCAL_DIR}/0001-basic-warp-sync" @@ -58,7 +68,10 @@ zombienet-substrate-0001-basic-warp-sync: zombienet-substrate-0002-validators-warp-sync: extends: - - .zombienet-substrate-common + - .zombienet-substrate-warp-sync-common + before_script: + - !reference [.zombienet-substrate-warp-sync-common, before_script] + - cp --remove-destination ${LOCAL_DIR}/0001-basic-warp-sync/chain-spec.json ${LOCAL_DIR}/0002-validators-warp-sync script: - /home/nonroot/zombie-net/scripts/ci/run-test-local-env-manager.sh --local-dir="${LOCAL_DIR}/0002-validators-warp-sync" @@ -66,7 +79,10 @@ zombienet-substrate-0002-validators-warp-sync: zombienet-substrate-0003-block-building-warp-sync: extends: - - .zombienet-substrate-common + - .zombienet-substrate-warp-sync-common + before_script: + - !reference [.zombienet-substrate-warp-sync-common, before_script] + - cp --remove-destination ${LOCAL_DIR}/0001-basic-warp-sync/chain-spec.json ${LOCAL_DIR}/0003-block-building-warp-sync script: - /home/nonroot/zombie-net/scripts/ci/run-test-local-env-manager.sh --local-dir="${LOCAL_DIR}/0003-block-building-warp-sync" diff --git a/substrate/zombienet/0001-basic-warp-sync/README.md b/substrate/zombienet/0001-basic-warp-sync/README.md index 1f8bddee640..62717a8582b 100644 --- a/substrate/zombienet/0001-basic-warp-sync/README.md +++ b/substrate/zombienet/0001-basic-warp-sync/README.md @@ -10,10 +10,10 @@ The `dave` node executed with `--sync warp` syncs database with the rest of the Database was prepared using the following zombienet file (`generate-warp-sync-database.toml`): ``` [relaychain] -default_image = "docker.io/parity/substrate:master" +default_image = "docker.io/paritypr/substrate:master" default_command = "substrate" -chain = "gen-db" +chain = "local" chain_spec_path = "chain-spec.json" @@ -32,32 +32,31 @@ The zombienet shall be executed with the following command, and run for some per ``` Once the zombienet is stopped, the database snapshot -(`{alice,bob}/data/chains/local_testnet/db/` dirs) was created using the following +(`alice/data/chains/local_testnet/db/` dir) was created using the following commands: ```bash -mkdir -p db-snapshot/{alice,bob}/data/chains/local_testnet/db/ +mkdir -p db-snapshot/alice/data/chains/local_testnet/db/ cp -r db-test-gen/alice/data/chains/local_testnet/db/full db-snapshot/alice/data/chains/local_testnet/db/ -cp -r db-test-gen/bob/data/chains/local_testnet/db/full db-snapshot/bob/data/chains/local_testnet/db/ ``` -The file format should be `tar.gz`. File shall contain `local_testnet` folder and its subfolders, e.g.: +Sample command to prepare archive: ``` -$ tar tzf chains.tgz | head -local_testnet/ -local_testnet/db/ -local_testnet/db/full/ -... -local_testnet/db/full/000469.log +tar -C db-snapshot/alice/ -czf chains.tgz ./ ``` -Sample command to prepare archive: +The file format should be `tar.gz`. File shall contain `local_testnet` folder and its subfolders, e.g.: ``` -tar -C db-snapshot/alice/data/chains/ -czf chains.tgz local_testnet +$ tar tzf chains.tgz | head +data/chains/local_testnet/ +data/chains/local_testnet/db/ +data/chains/local_testnet/db/full/ +... +data/chains/local_testnet/db/full/000469.log ``` Also refer to: [zombienet#578](https://github.com/paritytech/zombienet/issues/578) -The `raw` chain-spec shall also be saved: `db-test-gen/gen-db-raw.json`. +The `raw` chain-spec shall also be saved: `db-test-gen/local.json`. # Where to upload database The access to this [bucket](https://console.cloud.google.com/storage/browser/zombienet-db-snaps/) is required. @@ -81,8 +80,6 @@ Test can be run with the following command: zombienet-linux test --dir db-snapshot --provider native test-warp-sync.zndsl ``` -*NOTE*: currently blocked by: [zombienet#578](https://github.com/paritytech/zombienet/issues/578) - # Save some time hack Substrate can be patched to reduce the grandpa session period. diff --git a/substrate/zombienet/0001-basic-warp-sync/chain-spec.json b/substrate/zombienet/0001-basic-warp-sync/chain-spec.json index 8c09e7c7b03..ab0c5bd0898 100644 --- a/substrate/zombienet/0001-basic-warp-sync/chain-spec.json +++ b/substrate/zombienet/0001-basic-warp-sync/chain-spec.json @@ -3,7 +3,7 @@ "id": "local_testnet", "chainType": "Local", "bootNodes": [ - "/ip4/127.0.0.1/tcp/30333/p2p/12D3KooWFvMbTsNZ8peGS8dbnRvNDBspstupzwYC9NVwbzGCLtDt" + "/ip4/127.0.0.1/tcp/36639/ws/p2p/12D3KooWQCkBm1BYtkHpocxCwMgR8yjitEeHGx8spzcDLGt2gkBm" ], "telemetryEndpoints": null, "protocolId": null, @@ -16,11 +16,17 @@ "raw": { "top": { "0x074b65e262fcd5bd9c785caf7f42e00a4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x08c41974a97dbf15cfbec28365bea2da4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x08c41974a97dbf15cfbec28365bea2da5e0621c4869aa60c02be9adcc98a0d1d": "0x08020a1091341fe5664bfa1782d5e04779689068c916b04cb365ec3153755684d9a10390084fdbf27d2b79d26a4f13f0ccd982cb755a661969143c37cbc49ef5b91f27", + "0x08c41974a97dbf15cfbec28365bea2da8f05bccc2f70ec66a32999c5761156be": "0x0000000000000000", + "0x08c41974a97dbf15cfbec28365bea2daaacf00b9b41fda7a9268821c2a2b3e4c": "0x08020a1091341fe5664bfa1782d5e04779689068c916b04cb365ec3153755684d9a10390084fdbf27d2b79d26a4f13f0ccd982cb755a661969143c37cbc49ef5b91f27", + "0x08c41974a97dbf15cfbec28365bea2dac713b7f8b14e2815d297585d3581e774": "0x0101000000", + "0x08c41974a97dbf15cfbec28365bea2dad47cb8f5328af743ddfb361e7180e7fcbb1bdbcacd6ac9340000000000000000": "0x00000000", "0x0e7b504e5df47062be129a8958a7a1271689c014e0a5b9a8ca8aafdff753c41c": "0xe8030000000000000000000000000000", "0x0e7b504e5df47062be129a8958a7a1274e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0x0e7b504e5df47062be129a8958a7a127ecf0c2087a354172a7b5a9a7735fe2ff": "0xc0890100", "0x0e7b504e5df47062be129a8958a7a127fb88d072992a4a52ce055d9181748f1f": "0x0a000000000000000000000000000000", - "0x0f6738a0ee80c8e74cd2c7417c1e25564e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x0f6738a0ee80c8e74cd2c7417c1e25564e7b9012096b41c4eb3aaf947f6ea429": "0x0100", "0x1809d78346727a0ef58c0fa03bafa3234e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0x1a736d37504c2e3fb73dad160c55b2914e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0x1cb6f36e027abb2091cfb5110ab5087f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", @@ -32,81 +38,80 @@ "0x2099d7f109d6e535fb000bba623fd4404e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0x2099d7f109d6e535fb000bba623fd4409f99a2ce711f3a31b2fc05604c93f179": "0x08d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", "0x267ada16405529c2f7ef2727d71edbde4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x26aa394eea5630e07c48ae0c9558cef734abf5cb34d6244378cddbf18e849d96": "0x00000000071c0d84db3a00", + "0x26aa394eea5630e07c48ae0c9558cef734abf5cb34d6244378cddbf18e849d96": "0x0000000007662b322013223b2000", "0x26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0x26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710": "0x01", "0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545", "0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746b4def25cfda6ef3a00000000": "0x4545454545454545454545454545454545454545454545454545454545454545", "0x26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439": "0x01", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9007cbc1270b5b091758f9c42f5915b3e8ac59e11963af19174d0b94d5d78041c233f55d2e19324665bafdfb62925af2d": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da923a05cabf6d3bde7ca3ef0d11596b5611cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da932a5935f6edc617ae178fef9eb1e211fbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x000000000300000001000000000000000000a0dec5adc935360000000000000000000000000000000000000000000000000064a7b3b6e00d0000000000000000000064a7b3b6e00d0000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da94f9aea1afa791265fae359272badc1cf8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95ecffd7b6c0f78751baa9d281e0bfa3a6d6f646c70792f74727372790000000000000000000000000000000000000000": "0x0000000000000000010000000000000000407a10f35a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da96f2e33376834a63c86a195bcf685aebbfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x000000000300000001000000000000000000a0dec5adc935360000000000000000000000000000000000000000000000000064a7b3b6e00d0000000000000000000064a7b3b6e00d0000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da98578796c363c105114787203e4d93ca6101191192fc877c24d725b337120fa3edc63d227bbc92705db1e2cb65f56981a": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b0edae20838083f2cde1c4080db8cf8090b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b321d16960ce1d9190b61e2421cc60131e07379407fecc4b89eb7dbd287c2c781cfb1907a96947a3eb18e4f8e7198625": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9de1e86a9a8c739864cf3cc5ec2bea59fd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9e5e802737cce3a54b0bc9e3d3e6be26e306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9edeaa42c2163f68084a988529a0e2ec5e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9f3f619a1c2956443880db9cc9a13d058e860f1b1c7227f7c22602f53f15af80747814dffd839719731ee3bba6edc126c": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9007cbc1270b5b091758f9c42f5915b3e8ac59e11963af19174d0b94d5d78041c233f55d2e19324665bafdfb62925af2d": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da923a05cabf6d3bde7ca3ef0d11596b5611cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da932a5935f6edc617ae178fef9eb1e211fbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x00000000030000000100000000000000010064a7b3b6e00d000000000000000000000000000000000000000000000000000064a7b3b6e00d000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da94f9aea1afa791265fae359272badc1cf8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95ecffd7b6c0f78751baa9d281e0bfa3a6d6f646c70792f74727372790000000000000000000000000000000000000000": "0x0000000000000000010000000000000000407a10f35a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da96f2e33376834a63c86a195bcf685aebbfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x00000000030000000100000000000000010064a7b3b6e00d000000000000000000000000000000000000000000000000000064a7b3b6e00d000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da98578796c363c105114787203e4d93ca6101191192fc877c24d725b337120fa3edc63d227bbc92705db1e2cb65f56981a": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b0edae20838083f2cde1c4080db8cf8090b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b321d16960ce1d9190b61e2421cc60131e07379407fecc4b89eb7dbd287c2c781cfb1907a96947a3eb18e4f8e7198625": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9de1e86a9a8c739864cf3cc5ec2bea59fd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9e5e802737cce3a54b0bc9e3d3e6be26e306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9edeaa42c2163f68084a988529a0e2ec5e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9f3f619a1c2956443880db9cc9a13d058e860f1b1c7227f7c22602f53f15af80747814dffd839719731ee3bba6edc126c": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080", "0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0x3104106e6f6465", + "0x275bb9277673f20fc2801bcda9e63d2e4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0x2aeddc77fe58c98d50bd37f1b90840f94e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x2b06af9719ac64d755623cda8ddd9b944e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x2b06af9719ac64d755623cda8ddd9b944e7b9012096b41c4eb3aaf947f6ea429": "0x0100", "0x2b06af9719ac64d755623cda8ddd9b949f99a2ce711f3a31b2fc05604c93f179": "0x08d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", "0x2c5de123c468aef7f3ac2ab3a76f87ce4e7b9012096b41c4eb3aaf947f6ea429": "0x0400", "0x2f85f1e1378cb2d7b83adbaf0b5869c24e7b9012096b41c4eb3aaf947f6ea429": "0x0100", - "0x2f85f1e1378cb2d7b83adbaf0b5869c298ef7dc060436e4ed803af07632b89b65153cb1f00942ff401000000": "0x601de9615313b00e8cea3ef84e79e50b2fb70e2c8a47cff478b9fe8b3fa8f2db02000000", - "0x2f85f1e1378cb2d7b83adbaf0b5869c298ef7dc060436e4ed803af07632b89b6b4def25cfda6ef3a00000000": "0x601de9615313b00e8cea3ef84e79e50b2fb70e2c8a47cff478b9fe8b3fa8f2db02000000", + "0x2f85f1e1378cb2d7b83adbaf0b5869c298ef7dc060436e4ed803af07632b89b65153cb1f00942ff401000000": "0xf6abb8e2242d0084dad2c0afef26d70268e93e7e6072ae40949c58fc53713ec402000000", + "0x2f85f1e1378cb2d7b83adbaf0b5869c298ef7dc060436e4ed803af07632b89b6b4def25cfda6ef3a00000000": "0xf6abb8e2242d0084dad2c0afef26d70268e93e7e6072ae40949c58fc53713ec402000000", "0x2f85f1e1378cb2d7b83adbaf0b5869c2ff3ae12770bea2e48d9bde7385e7a25f": "0x0000000002000000", + "0x362ae49268098c4c7de8029927a1df2f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x39deaa720535a0afa236c5679f4b23934e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x3a0e22bc6b9ec8129f8b37b4779576b24e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0x3a2d6c9353500637d8f8e3e0fa0bb1c54e7b9012096b41c4eb3aaf947f6ea429": "0x0400", "0x3a2d6c9353500637d8f8e3e0fa0bb1c5ba7fb8745735dc3be2a2c61a72c39e78": "0x00", - "0x3a636f6465": "0x52bc537646db8e0528b52ffd0058dc2705bea5c66d15541040ac6c3ae971bcf5f1040221a8d1f8b7c17e61bf21cce87411480b10bd8daa5e3c2b65f8c4aa364e5a8ddf27c0313827d06a2d6334e074db9ca7d876ac8d052862b9984530f4d340bda4edddd6e4de5ba624536717e1139e14df2d875c7f7086dc3fa3d398b64f50fffc58fbf4fb73ffb0d39cc2b86761cfe6d3073b9c1fcee7fe611b7f4875f9a7d8cfe208fdf493f4d3b07d9a73ad05c8cf39e5c4dde679c3c8391b9ceec4fd78c824d218e4cfb79cb8be9cb301eace3b7f8a274c182edb72e2e83349855e7e4a2a795d7e27998b94f46d92b42eb543afcbcf5f5c9e5bf2d52dfd9b2f93dc33262710e3fc79b943e09fe2d00f8dd7edc4350b92a692a2facb7adddffddd3d89e9babb7b8e0b9d61050b2b4ddf3efdfdb3f629e9edfe9c18c4f8715bebf42d6f6e3ff74be1b9c0c8b9187cb89c83618e5bce6ebf90cb3918729745244063391ee9710cdb87bfbbbffc6047f275725e904518e7f53cec48efa788c4bd67d104a4eb81534cd2bd67cbeebb075b4c32deee59a43da30fd2d0c979410f3db2fb2972cfcad89d0f822c7ab644bade3b59d6eeddc9925eef8f34e8645980eb0fb2f8d9b2cafddec99273d7bf234bee5995292c3051e1fa97dcb31285eb5f76255cff23de917c3f72c8afaeaeac6ef74e96462e7d70864ed2ef48be2c9ef05d8f1cfa6e67cb79dd0ecdabababab5b225d7f4a72cfa6a53d9bcf739903246f521840fe916b813c65e41c0c50b7b60fe76078bafc61ff4c1bbfac7d3887b3bafc37979f73580490ef389f9f5920c8edc3f3cee7075fdc3e4cdba79f1f9c200db97df896f532c31e008355cff83a7dff7e1791b4e5097b400cb89ef19def24533b4524b567fe2c96c02292fe233d5900f2edfed96d8f34d29c2680f3270934e67054b7a4b7bfceaf95fd879b568e777e395e3aa7139fded3ff484f77779fef3ebbbfdeb6364afae9f74c32bf6dd9ef3de714c839e5df7e908f8c208b30f2fbb388847f8a2354c1e170305cb6dcb3b2de7eb0436e9ff9edc33deb3fd24ed29ef50f602cc7dbfda0ac7df8f683331cdba73fd63efefdb2f699b79f45244e492a38b708a9def9f54e6ba3643efdf9d41acdeb964524d396f3ce3fd247fa2f7380e4736a01f2e59c72bcfd606d9fb266c81ce3fc32bc0d3a198071be3f3f8b27cc0f725b7bc6cf3d2be99da45f916a7e3f38c349d21b7211a2597587be4b05e6ceef17b908d1c4dd21112e95f0ceef777111a289bb43225c2ade9ddfffe2224413778744b8f3fb594c4271b83bff48831d3217995ffa73cff86bfb94f3faf3834ed69ef11719fdf9592481f68cdf6ded19ff91063b9c64df908b10cddca5e2ddf9fd2217219ab83b24c29ddf3fc51346dc9d1fb60fdf7e16934cdc9d7fa48ff4913ed24c72cff839a76dd0789903a49e5d06c80dcee7f629f9a7e59ef1f323cd2903720ee774f91b22454f610414ad21610c79c190160c991a32c6102286c0604808865831440c2057860431c469881042da10f28221370c9961881742e6186245881c426630248b1035848421248e214d42de18b224644a081b42bc08a11212032164081943081842d6102203212e102286902e84782184cb902d845821a44ac8154248304520a449080d3d36e8a9ea99a3478e9e387ad4e8f1d233464f0c7a723d5b7aace849414f153d24e839a247aa678b1e287a9ee889ea71a207891e237a44d053821ea89e247a94e81941cf0a7a5ad0c3821d11f448d1d3448f163c3af070a046c68e1a3b69eca0b173c68e193b65ecc060478c9d17ec84b103c64e979d2f76bcd8e982878947069e251e259e241e2b3c31f0c0c083dbb9dab963c78e9d3776e0d891c1ce971d2e3b2ed8e162678b9da99d1becd86087063b74ecccb133831d3976e2d8a963c76aa7063c1be0b9b293c50e163b2cd859c18e0a76a476aed8b162a78a9da89d12ec3cb143821d26768cd82962c769e7879d1b767cd80162c7033b42ec7460070440ec0072c70e13901b00b9da69dab101481640ba00f102880b807001b20490278094000813407e000204902cb51acc20a61390a51a0d80c850fb52bba376558ba3660710a5da1c409280e06a5635388058a9cda026478d8e9a1bb5aada1b35366a30a86d51aba236454d899a096a4c0059a386a546430d57b3528361e76987089d2f74dcd0a9d25943270d1d2a1d18e88ca123860e1b3a73e880a123874e0c74e0d02943270c9d3674ccd0214387063a32d0a9814e171d2b9d3774d0d0a143470d9d17e8cc40270e1d2f3a67e808a143848e077478d0c9a263834e0d3a34e8e0a0d3019da61f6afc80e3c71a3fc2f8d1821f5dfcd8e207173fbc981ef8f1c40f277e90e047133f98f8b1c4ab04f34b8f0c604288573fbebca26a54d0c8f083aa2af9f0c2c71735197e88a1d3c33787ec8e9009f6434d1b36573a869a0bbc2f3a778473d49e422ec2168453e11630203c1bfce0522347784527869a17542d68984219603d7442c086a8f902e34167294cea425023469df26e50e3a5878c70a926d5259b1d6267c8bebc5eb0d303cc03a1d2384307467490a583a70e74a851eaa0033d8e10bfc070a8568c3db8be78687c74f408e2c545b481cb4a8f14e06c51657851856d8c3bc8bc78c5c047d40f2d6476c83421bb416581cb062f2f2f34646ed42d7c24e164f1ec78a9e15223e6c54b63d4e2c38a48c78c1d95a9068d5a11f54aad04b51d5c68b86010adc61a6ad4a0597aa541a39463031033726aa08901c9445e21ade05841c6602307a9f423f827300d1b19f4d4f1657000825718382da827e8b0886ef4808123021c23708ae809030704384ce02c81c3054709215d709cf8f1c1f900ce062a10383e8852b468d0b2c26962c686991a7048b09303ce08704a504bc306861a326ad8b0d9400d0c6ac0c8990187861a3a74385063464fe12ce1c4e003063ec6f831831e40f4f0c04b8c1f67782ce8d104a8460fa79d257afcd003043fcc905981103764a2e8a1030803d005433e007ab179b201818d10f406a01dd48ece868e0956431743dd42bff4e8402743074387ebac74576a0a2a15758aae06b1aadbc07f60c68c971daf2f558a1e5a3aa577aae9a24bea66a077b8946a9868c8a0a1010d1d3435a061636606345e66e2a091c18c1c346bd0a83143c7cc1c3469ec0411ce40860b4d0b605a68585093aa69a131a25ba2c982e605b52d343e8c1bb0c901f6011808604f3c88784551b9c8ae646dc072f820fe88991bbcc0e88ae888e88c70c9d03dc18aa8319851a3f683c8c60c1a325f646e206303992b19ab191a66b0c850f1a282460c9c20707ac00142e60a192b6049302b3255c8a4e03df03f00d181831d4419d4c6b0517a55895334493b30b41534565c4b2e1ccca99682300d980e5e0d6057604cf306e31a3655231b3e62f08241f5e245c66b0c0eb48c408c3f8c1eb08943868b07e2d5454d1aaf2b5e5b6cdc78a9604c0387089c271928402e5e55d86001af6aba8871d4d0a0070f3634d4d8d1c3071b2b21ce268b8d0d3367d4bc01bba1c68d1f2ea859e387979a18c09a6c7880d95073364b3565d0ab9a19d4b2b091e175831a2b180d3859d4d421b6f17ae2d5c4cb891f37a89101784718c3cb0697198e858f261717ae12b846e02ac2b585eb042e295c53b8927081c015e59a72b5c07584ab0617169716ae14b8b270f5e0f2800b0bd710ae255c4eb884706d7129e17ac2b5838b07d70f2e1b5c50b8a270657171c065848b05ae15b8987055e1bac275832b07d7932b042e205c1f7005e15241cf54cd183364b862a8b99a2943ac439cc3e606110e9106e21be21d40bec0711273220a8068b169c3956433c3aca3c6c4b303073cbccee891c30e0e385c841b7899a1e30510aa1a143555b5276a4e4c2d707ee080033b576021d88961a7069c295810af357464086100bfe0203141600387cc13322600bbc0f100e8458f25c02dc030769a00c1787d51b1709d51b3807140acc1cb8b9a06ce11343000c204a40c58075e65d868a9b1012ba9fe00dba1034137448ba047053369bc6cf0838d1e3df464515bd0566ab8ecf0a0d34563f1d9507bc0116205162a544da22e5195a81e783272a2462a9e8b189731052e3b64553eb8689911bee18901048d57171d2d3836e0d48033838e0e325f006143c68b8f06b5a57a458c8b2ae5aa636c72a5d1e303a21db58a1a11b5281f31e058a92800a2850f18ea0a5e50d4cc21dea0a606231a43b8801101f321b4e25b8833a82a10e5a849c2d10296c533e3470c6a5c5073064e08bc1fbc19bc2b5e0c3d33e8b1a367e81a7a072057b4161b1d76b4b8c2a01903e452bb41cf17206a0021a3cb0244059d53a743d7d4d1d075a0d3d2fdd005d1c305080f3d5d741ce87ce87ae878e880e0d1d2edd079a0cba1fb40874377031016e00c61f3464d0daf0d9d1c7ab010b700d7d0b9a1870d73861b367676e0e14167079e2606e060c101838621e3820ea39de8259a896ea29fe82e1dd55f34091a0a97aa5cfc106fc423417304cd123448e41891e38408845884e834163192603402e4400d23c6464c8e980c649e64909029a207971e60f4e822a7889c12e488409c41e4808885468a460b1a15c4ba88c120e60558450503b442d64566860c8c19ab993b66eae8b1460f1af460237644ac043124782cf168e22143ab8adaa56545cb8bda45eb8b2fe245f042f838818f2d3e50f02178103c11b12b625bc4a44627c629c6a81814b12d3113f810c207123e86a8d9e0b9e1d1e1bd018301ac0cd8182316a31763163eacf0d1021f57c8acd00981ec8a0f86efca1783a884480271095087ea0270872a06a8e585e5b5c38b86d612b5205a4c842c08c908b1a835d42cd586fa058d153eb4f808c2070fad21ea0b5a21086f107e69bd117620ecc1d3a2268697453746774617032058d870c026861aaa9a1bd8d450e3854d520d1c364d3638d4dc5113860dae260e1ba69a2f80cca16307101bec28d145f42cd136340d4056d0589aa973681e3acb9ca3710d03902ee6d5acc1b4c184a3c76a5acdaa49032052736ab66066b164a260b2604e31a5983f4ca989c584629e60e6a609261573cbfcc05cc1b46246318998219843cca46965c6309f260c1357c50215983e3c994d4ea8b820a505a1261098400424f08006a49000144e40c001941820090953082300100091282c38c07979c648c16a072a6a528125539a00b1b0640938fd4914a0254b5abf8127529c003dc1f92b5c548401202551a440292a025a00f94c1cbc0c34bf24d4c40914222946455058f0e0956c3e89895a68e1f556b8a80848a8c7c7c0310f03b7700099c7f1e05c090935712224d48400349c3bb848084a1323a0274b80802cf0018e1d2cc50251a02cc10011900b434ba04cb94651805ac04013141ee70b03ad7003067a22c5c992274da4084d71c1060c64d4048a519426464551a0c870ea6021a1264e8c9c3421328a228500301c2b067212454a94254d9c44918200a3282e4871e2e4f6c0a9019429170345500a80814be2d020041c3a7270e660189c19b01ccc82132953806c70e26022175680628128529c2c8132e50255a0894d06a78a8b9e1035b90010d19215a24079120568ca1228536e91901429284481d2821404581c38780a14168a8880a25c40ca120c00057d80f3063f018ab20294a2282e18357122850a14178680961811499902444404c70d7e026589115011910b4e6870dae0222028465088a4b060e44293252b2c8132e53699f2244a1322127ce0c8802f0065ca25020a2292e28013481c361808c80520171290c213a015566892c20f9c35b828c809100b4ebc7091511420222016a240791c35a240b1800d4e1aec044a5114284446558096604068ca94264b88809e084171c116e4448a90ed06070d6e614913a3264f9a18011d0086734606a00835816204250a14191c3338c88914a10a2c013272c109501520189c3298480a01429e404215686214c5050b2c3172024404e54914284b96d0e880367c2083918403c3ca97cb4820e770b83b919cc66355b1aae694f951efc6c6fb273d1bcff3bc27c99b1b8ffc1beadfc75f7f5d6b77adb39bf963effa7d5d2be576e68ffb03e9f4fad1a6def7791fd013fe987a7b5f777fb4995b74ff9add99b2338b226566ffd8fbbe9deea87760f7d755efcfbbfb1b476ef70aced44a99ba7762f56e96d8ac3a99bac74ce64a65cd72cf9d3f0fdbe9d7ec2f661bfe987ecceca4dde9e73895dbbb72f5cf690794fac7edb4d93f76fa71d3ef73f7bc8fb6536766ca9429534ad9fb28f5f6ef83317b53a64c993fca4e653e66a7cced9476bb575ae5cafef19021428430c8eed4e5a20e7a575abbdd0586cc937a5ead1f738fcc9f3b6598bb5377efd1dd2be0eeb0eab5d6dae3d8b4dbdde79c3e67d3f6f6a6d4bbbf6edaecd46beaf5fc2af5c09d3af5599dddbf70c645db43f7daa42ba5ee2ff6f656bb7fee1574265d57ef4a7b093b8d31b37fd3dd41b052a069482b0dc31aef1a760fc309788712a8719ed3bf5ab97b727fdc13e4eb09e21e0176770a1386ddd3b9bb99fba3f9421aeace94db2140a97baeaf7eeef4f3a8473d66af52eade5fb7fb473fef8ffbc6fb3effe6fc981bf600dab4ddbb2937b37fdd1f7bceee7d2008a34054a820303bbfda1dc0cc3e3bef98b9fb989bb9eb66c7ac6eba772c67ee58ecccdd64ef581d77ce9a5dd771d7755d73d779c71db3983b666618666f6731c73033b35831cc95997aadeedd9f7b8e7b7737a51ed0ee80f6cbddbfe6699e6e8fba7703ba76f7a49501ed7937ad1fe5e9cddd1f7f5fc7d49dba376d4f61d20528c0030e9d7f780218051ad6f41ac7a969202774cb7cddb06eeafd79b57e8e0098ce016a351d6f1a86ec734e9eacf6febeef874c7ba594c62adb7ccc95a73bedd0dd457710e6e476b06d427666a6dd4ca33edd41f77228655a29ad94b6f70ca5b45217a5d4044a5db429f5da5e2b58bfaf6777fb6cfe3e9c0efae3e993d99550e7ea6cc3ce6266af71f7cf6b6776f630c63e67c8ede2768ecd364077e8edce727767d51866f7ca732661febc69f3474343536b7dbd5e73ce5adbbd84f6f6aa57efd09d046feaeefe7277eef9f5d7947e1f87cedeee4dab778314ac2085e9eee6ea9f37280382ec3ed929ad15a4947e1ff7d7d49d7d4e0ec3574e873e42483d44e2341e76bb7bddcdeeeeecfc7ddc55669e9f659cf979e8ec79dd4eabd7dab47af5efebaed56937add4a35e53da3da7cf39270c4c7be73c3bca6af72e403b28d33dfba360d7fc79d8dd9336a594b67f4e00dbc7edec3d99bbdd3fff3e76e6767667766f6766a6a0e73ebdbda977f7f4cf999d5266fed89ddb9d32333365fe98bfef6b76ff989d7a5f6f7766767777fed8bddbbbbf23dff7cd6aedafcee97d3319113c99effbbcef930d4000edc950af7e9fabbdfdfbbeefebfebe98f77dfc7d9ff3f77decf4fb78ec9a366d9036edcfdbddbd73ea7ded1fcf39448a2153380f6e0c10496901a805cf8805a448219a0242009e0011013d2192b2c427841e20284446207c0043d323a5a60b72d2a402424252402852d3c3470f1a1e464550aa00dd742d48e981620120a22996031b98284053a634b9f10b00450122ea0e5a806214c50522cb81058c5ce8c14115201696184581423465899322282ddc0cf1e95145ca058c7c3461a1c8475013274e80827c42e8e1c14188f40459d20314d444a8024b5688028585a2262cbc102128413c00f8800807690244e4032868895115a0283a3e3e807922048505274b8c845c686201a027b4ce88a88951d1073d1cfcac00a5888c7190220c00052d710245a8022e4c99111575d0e29ea22220a2292d4871b28408888a142740444b9a143d7102b42448904f083d539c0015fdb0587062d4a4024b58288212058a05661f60c002508880a870608980a200adb00400414208a1e709d0122946533040e4a4039610101520a125559ab480035b418ad09215a240596105294234b3051f0c446401275284849adcc054017a12054acc94169a181501b500c5e87b449102c5c84993a2284d888c96184169a1022e14d1584f80808a96b420e5499426443606c8a88951d1922022291730028a92032bf2596116821150d19227519a2c01226a32a5052943c62640424e9600add084488a51d112a1264ea4088140250a90b338c8922852a014110151594224c5a8c91328424da82c2982b2240a94262c38b18005a42c31aa02c401952840fe03aba3f986d44cf805a466c28dc462c247472c9009b7c20e09e9e8e8ab48ee47484820528b09231d1dbd8e8e68bb33399a4847474794c9d13cbacddb64f2c27c611e1d1d1d1d3192787474243261a48f8f908e909c9190e6d1d16482348f909ac96dde6ecde485f9c20bcd848f90909cc9d13c3a6a2647f36832e1a3a3a323a48e1e1d21cda3598f26d264723499091f1d39133e426a267c74c448481f13a47974e4313942ea98204d24a46682349991281346426a268c8484e44c9026d264c248938905bc342633cf168a9a70ff6aba2dbecb9bc2179ba6703ceccdfb193b61ec6d8ad3fa61f6369d5af6e654377762d95b3bc9d8a6622aae72ea625e8cbd219102ec61fec6fa1bd3105beb6f48a4d0bd3775fb6f48a450bfeb5c0ec6de580fb373b4b709e5b4fe97bd4d97bd7993686fdd14da9ec24d2876c109ea68a220cbde9296425bcbde904881f5f46f93eaf6330db1517b63d949e5b47efa9ebdcd29a7f577f6d6d5766e7a36a8a2065a90800530cca9a9c58c21d4f882082b9f3dea2b9a5002872dbef460a37656517915a572a2534d533447713977a250de975e0555e5509eedb450755fba13d5955367bb266fa25ff6d477757507185faca087266a3ba6cecd37bc08c30c20a4c2b0b1cdbf6cdced8f8b1dbc7842862cdcb0b1cd6d87735a7f39ab6eff1cc138bfec70b7bba9cb1c1c59a4d933361c31c711671c31c611611cc165882e59dc0c8c9c1b4288db0f5ece0d41c5104fcc1a30bbb3b395796543826b58f0c86e3ffffc59fbcc3075fb6f74daa76fffecd86d16fe36cee5c961ce39d9c66a98c3873984d395f5cc2d371260cf8668c26947f0b30d091c10081bb60640bafc2fc840c4b644c4d6cf362bf3cad61609b64773ea809492486310fd0f6e89d41d5dfa25eb006cc6ed2c11b57b26eb7724253b57a2ca562d8eb568a25fb228f9c105278b10f8e01e4da4ae9b0b281f40e625e61c9ad77fde00f293f00738346f3f0f5e6ef8dd3759346f7f8b25f065d9a0f9ac269a5cebdea8de21bebae0b73842f8ad16d87db348ce817ed8e586cf7a10ecc26e3dab45253409ebc33fd2247c0ffe24c16791e1bba8a4fe9c96b936cbb6936bf3590f9265b3a8d43be477e08c269237db8dc9f47f5c3a9f7970bade7f28a8b003166eabf159fbd878dde7cc98b0204667f3d1a38ddbe9b44fe9fd8c3baeef25842a30699f8ea54c689f79bbe7d1c274bb1fd2519edb3117299f9a5bf219b7ab3fe57edffc46deed07694efb74443d45254beef7f5fbe6cf32ebb00559a2094852782dcffb727edf64b51fe99125d2f5823c31c967bfff6cf98267cb79bb497f70762bf16f25d3b34ae677f737e00e425c8fec260cb7accfb9197c18c158fb78df3d1549a85fbe709564c270eb83dcb8fbbd47d68f2cbde73fe21e0c777e7b55f502d6fe793dffd83ee2f3c7daa7f5cc7ff339ed539f7fd63ede23dd16297e25914010fc231d9236f559396cb9f4451dbc07b95cfa1e07ceb8f441fa208834c367b1c00727f8437ec1076b908d92ef3bfab93e259feb03bf3ec86a3d5f56cb8e509ff5ac1db25cfaaddf21e9d2a0eebf0fbf92f3b25c1ca1d56ab56c50f725fd22a4138a906ef841de9f40ffb3a5f7a165f165d52e6431b4e5ed86ef912fd27b89394839935ebfc41cc4fb693be2210976a147fabf48b6555209cb06894f5f7c16910c896314df3df03d5b8a0f5a1bf0bfef94d017ad0d6895d4f7be821ed9fa2fa8d64f49fd6a12fa2c5b7a0f3e089265f836ace70bbe47dab0ec08dd830f5abe1c98e3d2071fecd06b3d68cb794befc3073d6c91e197f386df8d002601c1f767d9a179c57a7ffaa02d5b1f92e0bc1e396f8be43b2ff3ed8618b9fcec359c0168182ebf8b87c8d1446a7568039884410f5924c16d39a75802fbcf13fafd595f562e52bf6479e86439aff760fbe5760ffb32c8a1279e40df6d59af7bef950e7e210d3bd10095eccb22e7edbc9fff89273458c5138edcd6b3c8790d8024c56d3dd80a5926208d10e50e1dd52421cefdaa880024a7db7ab04396480292d31d62725b0fd6b0251a00c986db7a100c5962121eae1259a20948b7f5a02b641da0cbd7fdb8997976aef2a8e97a0f86218b65cbda2e5779e474bd6f91cc3a65ebe787e209fd2d5b4e164356927ecfbacaa39b4588ebfdbc959c17ac618b49e8fb4f71c86f903802d2ed3eebd9f91e34df46498981dbcf17a94e2f892c583c0a0ee4c09405072f138710ecefb7e99e67f7ec9136ddcffbfd07a3ffc1f5ffbec9ee677bedb5c7df5ee59eecfd11f7c8ee821dd90fce59c3d83f3b0f3b1a765dbff7839d38028be17d3357f3dcc976ecd907d791bee95b803c3b3082b387b193b89cf3418ddb405cce7540eace2ee778b04a6264a5ea96485178b774e1062b2eff6bf6303a1597731f58e2ce2d977340bc71752ee780e0c01449686541758798dcaa1feed091eb9646658c2103e296464f408065dcd2688632ba5b168141821f504cddb2286aea561c8eaf2effe56f1dc0a179e98394ecbeebbeb8f300fe6dcb5c08dab8f4e9cfef49da28e9beb8f4bb2f6e598474e977cf7788afaeae1ae9f6776ddc79c4964b5ef2821d3689733bb2fbe24e9184a72233ad512b7927c1eeea5a9b24f3fd4998efd608e4dc105eae51dfce96fd54e6f547bae47592bc6d045e7ea46ef69739ee7cd9eb3ffbf9fd5d3401490adae4fca60d23e76e38e3d6ffde6b7d25cbd607b1be7ef7dffb834d860fba481bd7f32d91aeeb3fb2ecb643af4bc5a8afebc31769e3fa79c70769d80f36699384e270177c7afd82df645f16934c5c8b24b8fe458eff91ae6fd2c317492f48c38f643aee8bf40b76e147f20dee8bec0bd29edc7dd41b3ffc8f643bee8bbbd9d425be5f317c316e48f68fe4eb8ff88bec38e8fbfa6e029214f5b9d63fd260f308f3bf2926f9beda24f11bbedfd0964851e070b749f0c129ce1a46f05d24f8305cb04317093ee86f5c90cac1735cb00b5d64d177a9f45d81685ef0a98864d230820f52710416e3820f7247bb72e0027f0b2e86eb22792ed8627d83e233d75aa0f8618b2cfdb23e64852dd6832451288afd21eb5b248b26b00e8b9fe707ebecd8336aed752beb996b7e5ec029c3482fe76e78c19461ec2ee76e880173ad83eff3bceffb496ae0fbbe2f0d9049708add5cebbabbab5ceb7e921ae8ba67711124fddd73e5225420097c5f0f32333373cf6772dec9af906baf6f3203a3ebc50f1ffc0c8cad677dfdef33307afe7af5bf5edfaf31c05792efbf1659de777d677d7dcfbd7a2cf0abef2495796bfd6f72bbcbfdddfead36a8fef72c1ea0b26c8974599375abee5eff880fdd6ed76675edda3ff9491bfff9fe4ddaf83b59c291cbac537effbd937cbfff2a9151788744b873caadcf621226b77eb5cc3a247c64593fc8ff7bb092966888ab70b86b04735bef6e14ded6d767f1842997f547ba92444322dce69abf91776b5f7f164954dfc8bbad6751c992cb7a9c2111eee41aeb2bcb32ebb83842f7b592f3bf725efe8e2cfbe733b5b5674e8e757e5880ecc1bc7bb0f307a7c86d03bfb625d2ed79fb9899ffe33bc9a1dbfd6693437e5fd33259d25a2793ee43dfd5d5d5975b9b1cf25bed9077cfde7f64f93d95f10a511c0cb7ec1ffabec07075a9d4921544bf3edb72bcfc4d86fd54beb27f8888ca778b90eeb42c2261efdba86febbd6fd9a1f9e5521669d497beb5493273d7bf4524fe1ec9e57cef9da4d29ef7b61cba5dfa5d8974bff9555bde6efd26677777fd598434e423f0f77b437e29b5414aa892f96e83f89b59b3e2d03327768055c6166f787a2663152e32bf6fee52f1441f1f7cf1a5ede37df8fccc7359dc7a2e3243f2b9c673f9bd24f5c93abf4e92ef145b606b04d66b5e904524fcc1c69eb59ef5e04f11c9b425d29d2cb2458295a4326f392feb2749655e16eb2bc99782ae6987fcda8ce077feb4cf35fe792bc9b241f5c1a7e250bdde8321f862fd14e7d2e86f59967f82952cebb35ab644baad89a405daf276c19f248bf49eac33bf340092149759673eeb8ff8d0ed7a3fcb5be490b3fc59e4541afdc726f97e64ed7a6425c119ceff489b6987e6f52c6fc1e1ee8feb8900f426a431a8fb0f6ed9d989a5677c3937830fe0c4d23e7ce9037111229e4b043f12a7f1f399ad6793966a36ef99626c58da2776e9d70c29632c85eec4d233fa3c68a090e4fdfc23fdc2584e2c977ec9685cfa37fed16974f8e004104e4051e17036efa96d92382a821a4010431027b0252dd56cf399626cfc494b6dfb9e6900b6f91ec93400db0d8914e6df50701afd3975e97b7f432285ef3d7b3be234fa9fbd219182f7d3dede69f43dcbc3b9dcfc92a7980632a8800837c230820c2efed21f1283916d483a6071821f7e98a2cb1233b0b18dbfe4b9f4594ce17138dbc4d23e1f5cfa9c436dd06ceaa63f80cc454a1ea457d93e2dfa1da547d73b332eb55de97df43f1bc5b3a5f742ae44d5edacf7a5dbf276a92b612d6cb89e25a2765f1e5d21241fae17450049b9db7d496d59e57a14d6a2e9765f66e052cf46e1336e67a79e50b0f30515f4062df7e672aee9cb053bec48226efc47afabab2b1f6c2c227033632861650d1cfd39e4575797085c0f1a86c8e244d48153125238a3297cc62502b7f30515382a0248ca55c1b1164d36fe3203b77be60030ef949cb3a1896b342f1131f0193696c5f11936b637fea3283f7c000c18bee070b66a7149389c8dbfbcbddb720a48c34af253d2bfc506ec7c31c5958d9fc506c0c81823047758b9bab2f1c7aeb77702d02925bba7f3ab5df7fe951cbbce6b345cece2b8b29e754fc979410fe97b1d9d9776c3c0bf72112f65d77f7a7d67bd7befdefbb3bcaf9ebf7befdfbbfb77e4bca047f2ed90b41bf48f74bff7d37b1bfaf3f6b5a17078df7d5e47ce4b495ab9c6ed06c8dd532ee23d7fe791437ad6bd1997a767ddb3e865ad52df7f5adffdcc7fc0effea67d68cfea774f848b3cd7ea770f9263d3eab7c8dab4caa3fa8fac69f5bb97b50febbbe72db71c72bbe7c145ea3b55e891fcc1eafb43dd9b9ed5ef9f3fc5fa36dffbed6bf37dcfb91ad4b89cab018d2beb597d6f885e96e59ed58e6bfc2c528f9cf7a891ba7625406e9fcf9ffe47cedb91f45924a17be6da08fef4711082c503f8d3af4f6d592ffd7e8a4355926280017787ca0bdcc08eabeb7d11d2f56cd1674bfadd91423529061868951695545b56015924a1a34fc511bc67ae95dd47ceeb911d126a6d92f8d3f7a736a89fdaa1db2dfdf677b353007e0f4e1109f8e1775f49f1998bb8de7bd0458e8074cbf0c1677184ea0aaacf1f9265fdf9e014d9835dced520c6edb8e6b53842f78b64fd16392f08b278807e16eb4592f52d92e7b3888465cb79d996ac6716d90ffe9106990c1f24f9822c92c0367cb043909c9745125a97b956f283e00cc1f08f34872059490c8ce183dfba654d526f688358df2059b27e2ae967cd568be4cb22f956be5e475292f68cc3e95a409e32d22f65b77b9eaee3b9dd773fa47b5913b7fb9bfe695b67e4763ab7fbb17dfabbaeeb9e733a1bc4b923907932cf27207fb0b0673114daa77c1adab8b92573b9f4bbff6af7f7f3bee42ef77b229f4f594b689f7264a17dbe37d23e35f77b15da87733534ddef25d03fd4e6dc85b7dcefb97d6c6e19bb2591fb757fa46fc0263f21a608eef760874df6952171bf07b927bb6b685e5dfe3ed63ef4bfefbfe79ccf0671953fcdda074baee797b21bf6e176ec3e092ebba1fea37fec9200f20e19230d586eff386120bbc029c3487b369f67fc29e92414d0b9b87bcdedfff096e3cd097b46a3009e230826bad0800439dc20031bc760d4b288643e1db17ce9b17d64b73fac3c6d783987a58d4badac67937336009968ec1ab6cf1c3b00b91c1b745dcd30c70d888445871b9e7000a34b1177d85804e7734ec943ce7bc1497b36699f4049f06cf9d7fbca1f8cf6cc96467e5b2f6b1ff0fd6fdae7033f16cb96ac6f3deb0b7b36b6cfc77a7ff023e7055924873f451278dcd096e1b7fe23f986a4915fd683b379baeb23f98224df168be49e95b23bbffacf95b771d3986be5cd9db6f4409fd323f98a30bf9246dd9d21d86195eb3d93652d2b7fb0c9624ecffcbfff9e7d4c52b29cd7238dfcf24f72ec19dbced69ef578bffa0fc5e170389ccd7fc645fc7acee569cdce03eee493b1d6366e7f289bc187db7ff3649ccff34ee110c96bc42b6d5cce5d11e3967ffb0a16f7fd47a769fd8d047c79df5988b40fe7ae7cb9fd46a67882ff7c1681c672d63d11cecdc074fb75fa67dafa8ddcdcb44f3f933c3d6b9d9ef57b47922cce581c615e9d9e4d71d6b37e0a8c47b7b60fe774371d0790c9381ff48e9832e2703818669f30bb7da4670e23e736c0e57e709d72112e1a3977258acb972fd885948bf4e5d2bffbf9a00bb26b24bbfd4e96936888af6ebfd177e9839ea8e4d52473adf4af9cc4fbee5924c1ff3bd24ef2ad64d97d39afff47da28f1bebf6d50f7def3a5245f4f54f2c1f52c73cd9f8a48ba196576fb67dae6d31695700da2cc6e5b3bb9d6efe209b3eb96b9d6967b3691be498d00b9dd7f2673bb2d274e54f2baf49da4422fb5cccecc5ce3205dbc7a7693bd05387f82977332bc60a6d132ccc0bbcb3919eaa0fea0fbd0bc9acf62166f06f1724e863ba693f37e97734c42b02ee7984470653d6363d620037617b9d621d7fa99ccc0c839a62dd72fe7985070cbcadf2f32c9d4c495f1e775d535763b80dc0ee89e1af9ad1d69e437c9c4e170b83b9f92464eef7c4ae7146386ee0f3a39599c7fa4bbeefd5d44e23d73f2eb9fe2fc16bde7a40138b18cf3d9320d387f9224f0052739831657d6b2cbb9a52fae2c1eb688645eced55075653d6b71885ee61a7f8b4886e6d5a5e15a7f8b24cc4b9f4916f927392f9343f3eace771109b5b19ef54f52c6b57e273530724e862362345c846fff28e322ad20fac10e1685174e923d58d833ee597973e7bb2ee764c8e2ca7a361f64ea3db973790e20370876cf3dab5df7471a04596c40bf2d912efd239b3b8b2af8b7bd21d96ef4dbe64ede906cf48f746d9fcafed35f1af95561e4cb29cc777b3bb22d213124c2f57eda3a92da72deee3db2f4db7d93fe47bc6d2ca6e0b6f9479a927c9b641bf74fb521f9517733813c34726ea98ddb5dce2d65b90c63918479fd8fb423cda9c4a70246160d807429b521d29c0570b204e49e913091f8a74842503fdf20b64347977fb200b202e81d2ff8a29d9b8074fbdb863df3f7a79d4742bfff91e6f6b119a1dfdfbd9f4f6bfbb82dbb0ff2a7ef791fb64f5f6fbc2a00590123f8a2bf84e5f2fc72de69c39ed1a70fbe4c18fdfb878e2e1d9a97da0a80dc20b74f7bc824c8394a6d8497a77d4a23df3ee5cc48fbd0f7d7699feffa8fedc3392531ae7fac7fdae639d79fdb27259834ff120097ec88e099bf976002e096d4a1fca71301d3fc69ade328fbffe0961fb478025371fb6b869431f214976f49adae9b20e91af5a5cff405705954d25d6abb6e7e51204319f90b14e42eecf21727e052afecd2f940a0187279faf7a5ce65066282f173da87763f85726eb524bd030a19dcf9a3fffcf4ec87acc6ed9e26d9badbd95228e73e1b23dbe6b482883b3830f586153a9c61732ba048e3baec7e4ed3e603891abdcb3928a86ef9777aed5e80dc3eedd94a96f5d6ffb8c8e77111afe3229d73116f2ed2938b4cae79cfdeb441defb7b5e93b567f57bef67b565add7fbeff3bcaea3d4bdb9487def6792ef76d523eb7b5d3f3bf4dda07e4a96fe4548b7bf497b98028bcbb929a2e829a06e0bd13ede50fcd3494cebff61a6958d85e5c33c2b3bcbed2f6197610f8021978342ea1af5f5279a4d65be006e8b27787742b14e7f0f31f2852a29974b446fc95d54e8d9a463246f433581ce3c9b30da339d9e75397358ac6736582e7d1bcf8ed0d77bf642055f6ef7448c4471fb5930ea1fcff517a07d38f74413b779b84c223ee3ed248ac3a27f9240272438f7441bfd1ef9002b73900fc045910fc045d133be3ced53d621edc329788015b639447c76ec9b9e35ec0131e47ac677bcdec30fce56f25c2682f4c412414081613583191c61632a2ef3cf8ef40fb5f1330466940f4fe0da89266eb71351dc6e9e198ce53febfb6e0ab2489e32185bcfb7f5f3bfd6f741f4e9839d888465025292efa72d83be9f22fd8f0cf23e4a270f6bfa1b15ac19e286d3283c37c83fec197ffdf69e7e29c473ebb31eac64ed591be3f77c9b45d6cbfe536dfdb59e4065de69a98dc2733d1b44bfb32358aeb3677077f7f9eeb3c7985eb610caa17d93dc44c5718650cef422c4236344172210e2f9beeffbbeeffb84be28dce5234beec25d7478867011f0f96ffa67e6f530cf1f8e3d00a6b7c9c4629e5b16461221f331b171e61b1623ebd9477bf67d0c19ebd9f733e437edfb1639eb190cc917f6ef3f32b0960c599bf63d8c1c7bf6fd48f2f4ecfb1739a467dfbbc802f4ec7b912ca167df87a4093dfb1e2451e0daf7ec3f449af67d3f7f8a23f46d59eed95763ba0b0128da92874b17c6e2b22dc51785786e149e1b147eabe4b9b30c6dc973c3cf893dffb70fecf9cbd88d79181869a467fd317248d3622cf8230cf94e9bffca9189e28ffe03f3e3f7c3902c22196d19fe57fe15df4596e3156d19de72e48bc20dfabe1e39d2d8b487cf96b3fb31598e2e11c808c67f1739739aebbb63f7fbf0b97fc2a67dff3d7873bf77912212d1d69e7d7fc443922c6577da3246b2ec67bb882ee3f89e9d43e61879cb9d638cf5997462ccb83c1632def295467e8634adfbafd67194c9fe673c3debc68f2c6796ebd9982582c575e6be7624c039bbdd29ed989cff8948645f8c6cbd18d97a3306237fe7e22a76e8206d752c2fac3d63ffce3fa8b3b567ccb3d6cbcc9fabac72e9e5cbb34507a50e7ed37b1aae75f4e69486d487be77e1e4e2fb96eeee20839f0472b808e55cfade046bc8e4bbe82efd4f4442ffa667fc32aef14f19c930a21d2dbfeffba8571a399805e46286dc1b605b9670895cfa538c71be1091cbcc52e8bc80bad3d9656a4ba4282e7df79f618cf35d88b75c3acb18e74f2e287da702049fa76e39a48cf5112ea202d7c42fdff5e5ec87884effcc9ce6e1f74cbb7eb5338db11c5b3cac073b474906ba30a28ba62bc4c3c5849eb946a74d7186e4bc2209640463498488ffbcdeffc88b046718b2fc27d6347fff58f86a8c446e8b88ff2421517fe96daff72f40fb94d5a7be7f09edd3ad677d68cb1b6f81ef42442eeb5d547253010e42405d21ee7259f4b2c8b23d7b7d2491c953617b4ed417e7943377bbef723b59ff94e0b4ee8938ad7b7e06b2c548ffd6b30ec8d408648ab19c5aa696f6e96f6b342f121fdae7733aa27d3e4b0454fb44b58f4d4f2cb77bbedfe8b4eebbf17295a55c05640463f725a8c045d0184ba6badd3379d23ef5bb670137a56fed530acdeefcfeeeab98506dc95c5c44e259233a9be05af71d4219fb482023602d3dcf184baeba5df7538c4a2255e6531212f497de2644fb94d3a97de8779f0f8b48be5aad106f51a28121b8f042758598ea4e7a3d925e4a7208f363fdc3b66aebcaf176b652e7fa7733f7d9c0df97eeeeddc75dd7f1cc72bcefefc85276f9fbb2eb3aaed1779f1e59c62e7764195eae43b8c66347070d27173d3db2b6c6e8d9dab376a6773ecffe32bc73ea08d7d8081109e480219433847f96c3c577f937936a72573bebc541bbae637ecafcb2aeeb28384da0725ba270fd2759f2dc39e79ce5ec9ad0b37e27857898cbed233deb9fbc85889139bb5c29223d6b4a96425198ea064d8b44a73fa1d333de22813b9fff36c5a8bcb94239977bec596cda92c89ddffd4ce7bdf7294444c65bbce9348020c8df24ebdce6b94de476f9df7739b7ab48c25a8fb450cee5a79c33e43291cbb2d28bf5cc93fdf5a6673b7276bbfca6946b311691944244eefcb6b3fbc299bffbd2f3f83dfe208fe716fc938b7e3ab718e7cf1890e075dd7bd77d10a5f426d67d4929ed485b32b9dd53727631cea746dded3a4b72d9755de74f20b70fbd6077777b7bcb00f697eeee3d6bbfccf432fbf897dd3788a8af5f5d3107807ee9de414e49a2795b095f5d5d6effb2bb8d5a890817c9a76701e98325330d625ba70b2a7391c945f896f4b9b6c6382f7dfa5e7b367ffec806f885970dd0e6394b505582d9ed449313b8ef8201726fc0eaf60c07708740ee12702901167480f38f984c7c694288af7d027039c744976be4d7bfc8fdb84873cd595150b18aeec585f791f1b1bcd4d7e55c1371b0445ccb69006b53a8456c05e1a247bc6050239d02165601d3da2226468232623130323cf50a3855408239aedf2e0196db3fc4c80765c84528002e915bde9044fe4454c6cb3ff4978a5fce5d4af6b8200d295943ca2ee88594e471c12fa4e4cc056b48c9980bb2424ac25cb0155232c805c190923c170c434a861714434ab62ee80a29c9bae02ba4a477c131a46477415848497a419890927ec19890927dc1180c2c2626e3b24446e3ddc9ddd0b580f30aa8286e49a19a8082f280169d86c262ced9ed05ea0caa840f4a24415929d1841249283184a7441b6228a1c496fa8d97734ac8515d31b0bca6568b0360750ac1277189dc12276831e10ae7d42b146364282e505bc46496f012c25c2616de662249092c4b58dd3126b3c41bb5c28493891a6238c74416d8f8728921d8625518170c16e04cc1571954d3edc94dc059c41836146e323373126d24e18593f8726524c87c11d39fad4a9ebaced39673887333b72a798ada72e6b69c35151628d87f3f8e0ffbbcf88f0c4dd9552fc8946d35f323e3f15134b6b574ee3fd9287694d31aca69dd4f4e6ba75c12b95bce2a9eba652f4199ec74923dccccc7bccccfe75156198c2dff636c29b3e5e8d45aaa6664ac66aa50cdcce0bccc30cd3055cd34cd3459c954dd923249d9d1025bcdccd4cc8cac8b4cf6fd4de53f3c686c6c2ccf6a6a2c0d0d0d0f4b79f008656f4566ca66acf7f3a7d37492eae9659c54cf1ff3b3cbf3ebd9a614fb39f52fb2e78e71dad74f29191a1e5353aacb949215999fb132a599b7223369ec0b323b3363a79722a4db39ae75c76c59636c39c2d85206b3e56cb4e5f7bfc8ceb195950b9ef84007d0880304b6594b2db551830db87165fb5c8ba8343c80abc3043656d73147087032e08ab0816c2859e9d2050c4e6063a7b95e7ca79af1c2644714554d6ea585e25ea04e2fd0a714c0616b24a66e4999a46ee75cb3d9d8b2a54c566df9f7b3b9dced9fe5b4388d9d3c5bd6a7ce962394d3f8525bca8e2411e534be6ecbbf50311dd303c83925cddd999f89e241130545c38366522d4eebe741e79cb28ac9c46233333433333c66666a64646256c94aec9564373ff333df3236375f4dcddbd467ffe161797c0d8bc682cf36997d61c6be20f3ad076913283e65125f4f712fd8bbd5b7555b5575eef3a8ea50ac677fe2a9b5bdb853d15792b1de45e6adc4629e6d4a32d6a73e86a45ae69496a9db1ff3e59c1a81d32d1b57c563d556fed34f4eebafa3ac9f6e3f68ad1ad731b69f26ae9fc62a1be7d47c9a5652d3d64f9d1a14fff55552b7ab6e4ff194ffc8c4bac81e05a74d2a1e305e669e9d36be8cccb3d35c6fc563cf4e0bbf63969d063e28533ff6e28c65a7b15ee65f3c2c3badf5330fbbc92ccff7532dfec3c3a2e0b4f93330b6e42e773ecc965566b42553ddf92f5b8e31cb4e73d992bddcf9a22d65a12db9eace07a996dbcfe33f2d5b56962dc7caf3f178b6ac9dadf3eb6521c1348c1c20e780ec3face707adaaa68d454e1b4fd127a7e12ad3d8c44f71fee3ef24d3323631ddae2375f72e5053fec3b62e54d40b7d826a2aae7226ff513a8ab1d5af4fadf0c9296c396979a55ba8a5c97f94beb7e255eb4c4eebffac37b93375d465bafddec5f2fbf7f4bd9fdfb2b63fdb9e65a7cda6a6f2a2e5f6971d75fbbbc97fc62a1bddbbc828eef697dfdf915063e950936d2fa34fd73673d38b97cfab9a39a8692515859bca35531729a7b537a99a3edda64ffed3475831061a1da86105b67e0ae53fae830dbe1061441054d8fa6994ffcca519c0b8b2baf2c2d64f73fe13e40a1ecab85ada62eba752fe339da82307263a70c0d95a4bffd4e23fb76903bf5bdfacff89f21feffba784fd55fc07b42538adb79838ff695914fa2793ffb0ac0afdb3a95a262f789605a7f537f52e5cebf72eb7dfddbd9f8971d2aa0f89f6584515ff61b0b2be9c5a2e2f4d1beb5fb077f173abf52087e2873ffeebcbc974f92b09b333cacb6827d4d2b4bd443b9f467e1496a60df6adfa254b7dc939f04b2297c32f792effcc7f6e283c3f8c9c52e48b9c5d5ce4a422a717d6f3d72a4ef347c169e2f38f22682753cbcea6b6a5cc4e2d4e9bb6fc3bbf9c52f367b30abe3f4f0debfb13a995b258ef5f82ff80e0cf9c361fb4ffd992a5eefcf23d5b724ec6b263674b22d569d4963c7776cd8a01e49cb273255b3dfd92a7a82dd996b3cbb664abeb930463399d9e6ec9565655fed3a50b1595172fe594f29fdb1fc5d8fca793ffdcc4f7befbc207bf64a9af6b3deb4bce755ffdef4b22b79c4e2e7b7b41f4eccc697d7bc1fb723a85f641a95ccbca589c8baa76fc884079b6b2d34a9e6e2175d31480a327fb76da7ddebb9effc3faac16188ab19779feeaaed7088b81791ba6698bc9ccf0a8f9a4a56aa37999272df1d86c6c0d0d199391313c666448598ca4e120f363c8fab15a1c040c6b6c6e38480f1f381cc425be46184ccd746fba8db445df738deb9e7ef8370773b85ce35e56bcfef737f7a77f0bedadab9ce650537846960b1c5b7ff3b1a79ce6b73975e3d9e404c29acaebec6d56fd847a7d2e741c2bd7385c2ee46155415541b1fe6b2a707cb6815fb693d89a4ea3eb4b1e5ff65db64e89a1958176ec26961dab954d1dc5d83e5b9dd6cf36cfb28dfa0b69762b0b9073ca59553faf7bfef71ffafc1ed991569c9256fc236f325fc91b8f3f8ab1252d8936eafdd2b4794d947e47ff567f69daeadfba168bbb5f9ab6ce5b323154ad5f9ab6968cbd252d89b62426116c32bf346d37245288bdccdf78d8db8c5d9a3619ff987f8cbd4d2aa7f9c3d8a5696bf9c3ec14a7f9b3ec8d89d3fc47bb346d9dffcbfecd6597a6addadbe8347fd14ea71b3bcd3fb44bd3e6f9837636396daa7aef8d9dd3ccd129ef998ae7e3aad69793aa658f626cddb3ec518c8d3edbbeafcfb6fae584aae4477a6447ca9c369f92efb4396348b3bfafea8ef44b59f9b79cf5dc31127dcbf5ce62bd7d4104bf5b2dd0bec00a9f3efb4f685f68bd7e3efb8f52d873c73834ef2765530affc624c4f6b22f802efb42f879569e95ff88564914ad67e534ffd02a85e1f753eab3e583560904676eda52d6b24aadb7525fa96539ca69fed47a562cabc47a2bd5be409f6d4a2ccb4eeb9f504efb703d778c44def7cf2546ce2181eb27a927ce2181bb9e37359f9efce766c58f626cb5f5dfaa3259fdd638de723edd9884d858764cd9acf80bec3411aa6c4f3d778c7fdb9673887ecf1de308ccb5b256f6979fd44c629c498ce5e7e459959f5397f9d4b7fca43e29ff994f4ef3af751c65b25b7e52d79ffdffe23ea74fea73e2336ee94d7956de54cf2d3d9cf7e4e13aa82e1d54ec9694aa63a26add9236d128dad4ddd2735e5c8be7bacab5485955b513aea59eaed55339ad7826ee4beec253d6eb7389712a31cedb5fcea7afea32074715a9eb97179066c766c5a9288e15ff52d361ec26e78be9b159695cffd2fc6cfeb2390f9be3d8fc039bdb9bf74c426c9dc454b359712bdc92676ba6b675cbd630b6aeb1b5b53508b6b6b7ee9984786c24c9ca6763e2b1f52fb9cd3b9b8b3697b1790f9b7760737bf36712d24ebbb637fa4731b6ef6bcf7b2b2eeb3acf8e6e6f4c426cfe4c426cb718b7ecb4f94731362621366fd21cf8fec334b6d34f5a7a99edfba4a5d1e63df8fcd57f929886d89262bf44c4d6faa5d096b4f436d6d7e797f94f12d34d28be5c3ffe528e0d7cfe318969664b5a2262837dd2128f2de6976636985f92d9c64f5ae2b179335bc741e6272dbd8d7290f9cc21cce78f215d1c643e0c297290f930f2c541e68fe4c821cc7f91321c64be8b8c7190f92239c341e687240f0e321f24652c647e8bfc38c87c16197290f995ac1c020799ef91351c647e47de7090f994ecc141e63be98383cc6f128783cc3f8a99ad05e8d15f8a6123494c3c36ff256a6ba71d7dfeafb25addf3879dadaed70883f1e78fb111262ac34698c21936c214e3c146986e646c842987868d30e9d8daca9c6684a9deb011a6b1071b6192f960234c6febe7c761234c331b1ba1964536e276ac61236ddf69f3f98fe86c2a9073ca6e0a89b1ec9e3a29f1add05c14ebadb00b4e500714d3101bfd9b9527ffb137b732886013eded86f3eccd7b1944b0b1ec0de9082a64e8ec0d034a503029b18226ae6c371944b0517b3b52c38730b43c75c9c1e6f4bb4f5a0a6d5e8faf55b79f296663799de7e35bd489aae3f134f63c62ddcb4ce13ccc146da2f65dfc1b1229906fff063ef9379b07e9e76ecbbe86e2fe657fc3ddfe9c8b1c7ccecccddf904821e667fed6317ffbfec614b3f98714eab6573914cdbbfe0675fbab6ee7d89bf81cd8b7f63692f6760404dfc6de68aec6dea8ccdefcade778d81bc7622f636f74caa7702c6d82c9be656fd487a5b4875dd2b1d5677d39e658f5a6e66d605ee4f1dd7a98538beaf657279967395131958dbd895f639938ad7fc6de50705a7f8cbdf138adffb3b7251ddbf7a1bd5128af72a886a2b15df53cc5e3c9441e33cf637c2fe6f523d46d575d280e21c40b47257abe100422480d636ff0b0421925c6f9bee3f44b77770edddddd8180618e12351a86620e3a345dfc10c3d02592e0e038b95d25d205e1be42100b1a1d43590c66b090470c1fc0843de0f020268c3131cee79c58c8030b0732618b0576266cbd80e411be154f65a10f2a7068c287818f9a3096450f9b7044c10dbd0963399b1ea10f236a7c846710118387cb0c8be72d3223e390a9537322dca0508e713e75777797c1096169c4ea87231731950c7d60016343191630ca41f82d8d342714a35e1d842010aeea410802217e10be72086761cb0990d2c2708c560521fcae60fd087d00e1e9842d233a2021521312e37ce7aacb5f1391f07750e37c7777770a24a470305bba13864174e5093d2e6690b053639ceffccc3b406a3a3f40a0cd3ef0a0831c0e2cf9383e7adcd8d4d0c878ccc8c46260785c43f3eada24e1b93eaedbd202b608af5e3dfc3aea125fcf2292f18f34c82212d81f6998ef594412c3748c7d0ecf902305402105264fa618e1926653cf3a4bab95e32d5a9ae6985a9a6696f6d1021391cc2ae66c82b7cc288edc1614de64ea59e3dc0027132ea97d7c1ce793771daa00469c3052654a1b56538caabceaf0c1881025108922c2021339bc3079c2822b8e26225a4c1832c5101550f0d20585145410d7984943b0a0c043029e128ed0c152470a5042488615cfc4a5a053021d223c7610e11942045ca30d9d39549849319bbd0c669f336bd54135f322811c26847264630d1e7cb0caea773f4b4452ddb84e2f483a2994735b767eeb33c1c82dd2a8bbad56cbd69b198ce574fad6b784e8a72212f08477f0c90d15df4d8cf5e54d7973c1564bd602bf7ecb96e07f7fc46364949b5b3ef944245f3512c7752b747363be18cb822c0aef5ba4904c268bc53e161945764b16ae7ffdde1391781f8fecc278304484622808bf450ac5ca5819bb2d4a416e9fd67b6194d82d85aeff4796fede772292d0bd1cb742b10b0b613a53c613bce8077e39dedc502af47e0fb6c872bce00bfcd7d3fea14d03fff5e10c403877c07f3d8fafffc872ca108f4f45242f6b44ef28bbe3f82f925ea3f009d7b748a1f00365b2da7a6f916578c177b20caf0b7cd7d719803a77c0773d8b43e1f56c697443f09d74bd8b485ce183e477757555c70dad5078c50767e822e975d156f97018f9bdfb1669e4d73ba8919d9c2c67cb967f5bb29b1bd9188b8de16d7d19b640f0f35bff48b3482a2db2acb7f54e96357c7f3a03c073a7a4b7f5fe21c93d6bfd1107ed90b7ba67916595a1d92292eeb31e299e403b6a67cce4a00890bf2231f2cf0180ff334aa9fd2029891f1b500308aa314b07738cafcb393594408063ac76ccde185d7074808291950608368ca3173433466f8a668391750508698c2214514fb33ad200c20318a4418307b934965890460c52e377830fc8183d393ec861a46f7840c358d360638c0ed0183b30406862ac5b7800c4c892ea800553d0e2780206682cd102348ca08931d6343ad862a4657460c6c802c3832c63ddc28df15b0108478c314e80f0c4c81ac1075d8c303efcf8800e5acec0b2c6194a5db8d8f2410f638d0c3c9861ac29f062fca2e8e089b1b5841523ab08da0c660c7141b0327e977366fc70671c3043cb9d9fc3050f6a9871cbe761dd3c7f09fe439f7f8afff8b3cdf3cf9cffccd6f31f61c17f68cf38cff6f5fc44fcc7d5e3397cfe09e53f391ffb98e757c17f609e3d781e9f5ff6fc28f88f8fe7afe23f33cfa408822deb05e19bb499fd07dfc177e48d55aaf99bf748cbc1dbffff481cabe475f0b3af24cd2a75f7b407c91cab94f3cfc18b648ffeeeebc3480fac07effd072f439256c9929ff33c481f568926f3f56948259b57f2f15978b9207c4cc7d6c3c7dffc8b54f261affcb02989efe36bbe5563afb86c386f639568fef537f68a8c4de9fb9a97d97cec5b1f432ad9c4fee65d37effa98bde236251eff7a16a97463afd46c4ab0bf717deb29a9e4b25704605302df47cb5eb9b129b5bee66dec95984dc9e6e9c3904a32d55ea1b129d5aff9b657aa4dc9e6fb9d66af4c9b52ec6f5ec65ef16c4aaef7f19dbd02635392f9d7cf904a337bc5c6a6d4bdcd07f64a8e4d49f6aff7e04352c9037ba5655382f1ec95974d297c1fdf81bd42c4a6e47dcd8fa4921525245b8ebdf2814dc9e6fddf5ea1d99466fec5fa7ff227a9c481bdd236a5f16fde8a1292cdda2b03b029bdde87556259a5f19560af04f34ab18ff92bd3e6e3497be5c7a6c4fa1aab54f357a6edadd27ca57e257fa5eee9e3904a3656e9cab4d9bc0fabe4bdd2f74aac9fdf83548af91bab646395645e69e69578bc12cdcbfecab4d55825f095c257125fe9f5ae3fe2209047b94b43b2d3f865e4cc69fc3c48149cc63f4356711abf0c399d9cc61f23abd3f863481ea7f1c3902a380de734fe919c4f4e637e1749c469fc22c9c469fc2139999cc60f9213ca69fc2d52e6347e1679c469fc9564c1694d4ee3f7c819e534fe8e7ca7f153b204a7f13b39c569fc4d4e2d4ecb398d1f691ed1ba12017283fcdc73c738c284e25abf0a5cebf6c058765303317ee397b381184ba6fa619cb7ac138a8b14f10f054dfe8f6a4e8f6a2fcfa45d62087e3b8d51dd62d5afbbbb9b54e02245303f14f47abe4530b6a9b856ebe787d97236bebe9c512b98ba8d858bbcec7f2d8e9a358ddf6539b4207b5354546b4671b5519f8dba1dc5b5fe26b6d591868061b3aa4175db73652dc752e6e4d04bfc21309cf3f54114ea5f41f4881b97f841f44926065121626010751abd20ea43cffa893a5b06512d3deb328836f5accb8f36d1b3fe209aa567fded14fbf7be7bfafe9ef39f98a5514eeb87b1ecb40e46479bcbe572b95cee874659772fb7dd8b7b712d5ab468712d2d56fdaa5aacfa55454949494949b5935454545454543b39393939d1262ba7282b2b2b2bab693535353535f534f5f4f4f4f4549f260e377113377113a70277e12edc85bbf0f0f0f0f0f0f0781dad4d342a2a2a2aaafb69136da24d54ae2ef234e322e00fb59c862068cbefd97ca2962d6f7a36653d9bb19ecdb167734eff30ca25866054944b0cc1a828aa16ab7e54542d56fda8a85aacfa514545b9c4108c8a72d9b28ab61cc3a81b2515e54d2d56edffbca9d56255fb7969b1aa179d5c2e97cbb596afcb75aa5a4719ada202499d5b555555552555252525252535a5a6d3749a4efdd3a98a95959595150a3cc5533c35f33a3a6bafe7d3ea55fa51a6fe80538db2060093d314b79c5d3ab2ec926b531c8173458a3c5abba9fba0f97c51e0daa4f1cf6c62f1cfecd234c50880203272a4b9eeb41276fdc18ea47736f98f6cfc88fa0ecddb3f9b6617ff91c9c6b1cbfdbc26a70d5cf3aad9e7d1ef1ec67276995daeff6c721f6532dad44e1e0c40ce017bee1887986b1f0a5c842f5bb23d307a141929b841e1d77cbf47d13e6590f83639d7df6c797d0fa9f17d60017b9c29987f2e314f7ebf77699f92af626fbfdfc5689f3248e639285dcbd7e780742c3debb7a433f5ac9f243da967fd4f3aae67fd3864fb20dbaa67fd3dc8be21bbaa67fd3664d790eda56773d24cd9e43167a60ce9627817e7e2538e854bf916cf79141ee53476b716b0c5aadddddd44aa8f54d6a19792bdcc5cb3e03fb58ea34ce6e57e2587442691d9fd50277573924d5cebff6c39f3d23ebdb47be9597727f5ace7979ef59ca367fd234c25d336960e8ce5f40282b1e78e916f0a5c643ecf8b4596cb392c926ed95e5860753d4bfbf8f45cd3ed7ce1fc5318e2f926b2a9b8083b55d3d7677debc1ef20c6a27ef7a74ced1334ad479111059628ec68ca65d9a245ca072c9ca684e0f2d43e41dee58a1ed13e412ec6d5d597ebdf3e8c657b89baccb5efcb49e54d5eaebf37799337f984729affa4f3b3448ce564bafe93a9a96758faa7b364e99ff6c187fe692184e89f3ea29be8997f3b8d2591eb445eb6ace0d8126d2963fdadb63af27091cf76d4f765375151f97ca69d37a93a8a8b7cefad6e7a96fd6acbff9494df1677529df15f4ad99ca367d496e3d06ca367fe2328999dd481712289930505a5df7bffd510fcd68b1fbee892c17ebc8979988f199a5f24f3b197b132b11818d8f8728921d862d5cfeb6833d163bbab5dec76a7dd77d8c25f6a3d75dbf676e4bdf72fffa6dd1fdd34adfe47acef64fd47ded3efabff512b46bfffa8be077ef7fd51ebfd975a369817addf7fd4bd0763fdf74720cc78043ee85a6ad9446b0567fcdb52cbe6b256705a7fc40261fe1efda3eefb996a6cafbf3deb8fc0ff7ea9651bad151c97bdb1beeffa47fef4996a6c626841cb2dd6d3ee8fbeaf7f3beabe6b59fab72396ad7f3bf2af7ff43dad479f773beae891b7fd0e01363f2840ea03b8d93c538dcded8dfe6dc9b3f90fe11c7d5bd8dcde965c367fa6191b1d9ab4b3f2ba62aab1f9dface02cb53a6aade0dc8ec49f792baf1a5b4d0c667481b0f075139b81195d60cc0b269b81898d2e500616139b898d30957a3132638f99188ceb8fc21f6f40d6d7fd91f74e440f1b9a97752f93592b38b7a3dab2a1b156706e472d5ad9064db69b9a9918cc08fe51f8aebf2db56c36d60a0e8dccde986a6c3ceceda8f5333198d105b2beee8fc2f7bf1dd59f89c18c2e90e57f14fef7b723fa33b1bf1dc93cccdf8e627efcdb11ec5d7f3b7a3df8b723f1bf3f0a9f35637364ec18b31f636330f6066665a395bdec8dcbc6449bf347a17dd08e2dcb2c1b56fbd9da21f4df8e3c1b760821f41f515b3b84f96e6987d0cf7f6433595220fb73fdaf7cb074bdf83cfeeb19e661cfb18f29737a46c690dfb37e1812468ea4cc458a64488e2d16890433671b20b74f10578d4145b8bae38eeb4135280c1a836241b2a09ba0b7422204e5f8d5d51dd7e71060cf1d2351918f21fe21d60fd51ffa7ec8fba1ee87e80f157d53b7bf0809d16422b6e5b39e8865cb9bfa44d596b2ef893e5bc6bc27f26c39764fd4d932ec1913515b52a9b9fe44fddedc6da9ccdc69735873c600e4f629f2bca2aefba12216ab55148645afd758040313f345ee324533333c8a643f34bf48f643343688686868841186e60fc57ec87f08f643ae1fa20fbe92fa4afa8766dbf2f6a4b1a56cdaf279d872e62626634b8fd952068bb1250ccc9631d768cb97cb9623f8546a405b862d5bb2a8d45cfa546a6e2da9d4dccf96df16d7f3efec10ced5d5d5a5b6a45273dd96df16d7bf34f2ae5b2a33b7ad6cd227c09b1eb3c8b44c33f3f26a6c280f598d89c9843d9b45da8e21172132a2b7fba1d7a532c3e2224446dea53f24c2a512bb5d1122a3befe437ea9c844eff95d9e8db5b80895f07645a8d0db15a102738b506951e94bed4dcf66112ae3eda7e2ba5e848a77dde6f46c1669eb47804c9fc8e87b7eda7d5eebf96b6db15ccf1f82a14b7cfe1136fe2bf6fc31d78589bd917763de68e60ebd2e8fe7978557e689a8d0cbe38de89d79a3d81d12e1da1019c15cd91319b52ecd1351f1aecd1bf5ad792222a3f1fa7822a37a7bfccd1bc9ee905f1c2223d725a2d217c736d7e61b7977be0fd2b936bf0749b936ff86ecb836df8664716d7e0d59b9369f86fcb8365f467a5c9bcf830cb9367f8604b9365f866c716d7e8c7c716dd66a23d7605c83e1da0cd764b816e35a0cd768b826e31a0faedd70cd866b355cabd56af3917c4cb7ea26a9154859b1245585941452725f4460031ee478aafae28a10b0ae48828731368e35a717d4000c28a83881162fae08afc8218771e6724eaa885b8eef6b744edd690f358c327777291bae63b1b9ffbbbbf70da3eb724e0a861b5ece5d41c7ed2ee7aea8aa01581241dd1e21c18f449090107fdb2877fe5123cd1e01acedd34dd6f993e79c64cfb9022e5cb8542e5c64df5812b9a38f7fe3e0e978f6bb9c9e7161755688e77a9ee7d93f03acb4769de75531c6f5aa80010c150b1876f0210926a82742d0c515705cd1e50a29afbb2e2d83c7e58aa4eb793ef4522b1db9e08d29b810e38c2fbcb03117ae250fe74ca29e2d5e688163ea06343eb0851561b0ac30e3035dd7759d155bb07458baa2b5250b261e991552d430bb12b028a55356f4205af154831532b8acd0e1735070cbe7f18cc86d69aa62cb16301a872e72d862820f6879838c2b1b6dc1a53fc271691572e8d04ab1cbb92d465cf0726e0b102ab83296fd749bca7f3c2fb3ca9b534ef3ec0b1eae8b6745c5349ba6962a4f4c3cfef37d7f49a47b1b25df69de5447da34807ef79d7da13eb5b10d9ce1870485044c9bf77d47ffb347ded3ee864403e61b245801ce569ffeedc8fbefab3df2fe85a3cfe25c0c1964c1d9e8d3eefb65fe4343701cd94f651f71e73fd934a07befbb299b06d0f79ebe376d1d3992b643eafe3cc0e33f6de3075f4f77faeb5d4fa442eb59df302caa70ab475a01e20b302f3a6883bd5b2414a6c2bcdcf994eaceffaa5ce6e9cc53d807f3627d507c5004ad4d3fab71534e9b0fd3c5a6adee7c5733b55337b5963bbf2389ba17c1fa300f635f807d7db689301ff331f685ef619e6de0b745d2b18f817dec5954e1fb986f62baf3452d777e8cb4f11ec9167bb02389fa55783debfd895468bdebfd871a70033ffcd737e026fef8ad07a7a802eceb4f5185ef611e85a4fa30e1d787b136f4679eaa386d3e8cc4d9d0e974e7cb58a8182975e7c790365e54eeceef4652e634a2a27987868814a0801f2252c1a601ad7f7dab9f48059b06bc5e10fff56c83f9b648baa70ffbef41d8b3a882f81f0c09236dfa916cf5412a2a806d49ad7f3500fcd6b7a882f8af175508bff52caa30da97b5f1774d89644856929dd6226ddca2c01d42974ada34928d9d763422755d5d0072775227c5643763cc47d9181bc7366698819513d440b5851646884ed45063e3e51c1549b0018eded9efd97432a767b418dc510618531da0428a2c7ea82148a25688e7765dd7f97377871b556429430d2f6164810596ee061afe676b7ccefbcfe83f9ffdb276dd8fb8ebdd6ee9765d47ed1af53f27bc9ca30204b77c9e6e066f94c5a8e8c0951e65e5786354d8304367a9b8b2e44d41b798428c18a618c30a8fcbb929d0b8f4726e0a32b8413abf2fc3eb799e57dff33ccff3bc8fa43da39ef7a3ccfb59fb08f15c5a1b07907368bf0da57d3bb8f38914a07f2ad5cc9dc0eacea992e7ce1c0a7077feecce2a140c714b2377caeeb4bad4fb3ec08ad50c99c21e1083975bdbc7610f88c1a9677cc1c9ddaeb6338e31e672ee04572e4f39317af7a5ce0562022f2935c11b9732d9e8c7fa87da28a5b3ac945213b07129a5fea3db8e83cb39135c71c5cb39134071cbf1697b1726f0c10447c891e3e58cf096cb43faa7daf87352545dd8e59c144997c5fe233ddd18633fffa69c1d19eb99900c9c88c1972b1a8050818d5e71e98fb92a2efd9bfee11c0e8793c1463fa77fd8466de95688675c63e45b8eb7dae6fc26c79813a3783907051cb77eb9e5f828005fcc3e77a6902f403a521b92aee58ea45c73bf8d9c7ba2897291eefb3b2e22c7954d27e9144e97a7e8aaae3f38d4fd34724e055d9e6ec9530eb502dca5560ed573c7d8cf391574f1efa4fce7880aa09ac65153b92e5254d75530d534be65e7e5fa774efe43a7a895ffb49414e788102969f5c68e366e8a8bb42dfa7ea8e8b3fec435ff69c535fff9d4a58318dbce2f5c73ce498971cbee72fd5b88b1ac01e01f87fa1ff6e11f0fa54da8c4a9150cb4899a041d536a06680441400353156030482c168e08048a26d7f80114801098b2545a9fcaf42888814a19430821841802000020002030334c0002449b3da1f71f290cec0d6a2eda91cd9c18032ff0dca5a25b87109f947ed71b47ba08981d9bf2eb8274611b9bb453e3e7ac8da1b052cda092de2ca54eb20d304da0082804cda4a1f3c20b1db431f06a0187aaa837b4efb965f92729070114f4bcea59b995635e6ab964472cf4a36ab4b19709c2ca9de559662a421ffc529d1a7b238b3f2aedbd15738daf14666fd4f24795bdb76256f795d26a6f84fde51b60d7db9446a2d08e90226a9d8d122b1a6cb88ea4185e8ab8e828c0b547bbd13679d2e8eb62008f3df7c003341b2a56a1313c5bee8c133f55ef2b6be3a8f64de1d95bb8527d6f859fb221f71f6bcd8b6c8a9d7e5ae19cbd1d83b6ef5dca812c912fb71f29ccf63e3881fc2ddb5d2cbf8e2013a84318cfc5ea0ddb63bb22e7865cad61f213d625e0059b3965d0d0ba019f1b9c8f463543f237858748ee5ea3cc8ce2e9169db250f69c42c4957ef25f05bf927d337805e7a9c127a68ab304437b4fdf1cec75c4976720c5cf675cbc7c9600104ec31deab1daa6da90ea2e68b2d3fb183b47fada1739a348859ad424dfcd9b5a51a636050bdaa24005bb3e09d32a06af898c3ed46bd7ac2df71250bb69135da4b3230e9a600952a3cc8dcc1ef833daf8af458999fb360a2a0b55ccab6b747098d712665194cb54527b1c476b4e091333379dbd6d06867ef58142c14f115b2b940d25b4d25e5dc424683aff6af940c398b7e6d19b796ea7247d57f6f1b29f5a3042643962d66c46aea38ee900a581e4719715dac6a44d115c8616ed20a5c64ae32713d2162995829cb618dba14a67e654b9a7aa0ad972cd3565b969a3ac543a5ca6a717047923c352c8baaad3acab74ac18f070c0da4cd214b5d89b3bab2805208b9e7870c36ad252ece6816850c9a571009a29569705ebaac0e73f4d13750b574673759a8e009465223fd72f4de9a84d861936f12ed4982c4395d1424c35e51c48136a3bb71e1d79b70b521edddfdd699a24380f1faa9b9e956b7b3d41859a768f66a9d89e720e4ef1c4423e57ef896749b13efdcf6ce9e1356c06ce10e06fa93e1305e565f67da0669b831e088c05fa2f19bc2ebf67657f7d691c9ce87d1f5761c8bbe256fe5cb3f027af104fab7322ded5187c0c5e42ee42ce8a270b5b252e3f050235054a7b7bf28ab5bea6c6b4f4964b56e2cb65ff8d2cea2a8a4b3f71ed05c0442127b2aa9aa3d5949d533991365698308826d8568c9a443f916060611e49de48596136deddaaca8651c4e1c762906a01a1b40da9f7888ada2ba960e322b592daa3de0455ba1582813a54d77f8d896cf131506088a9bba9f2e218a5a46f5ec66a4faf1697b1753c30fa2d759189369d38b8d6059246990ab474780e435d3f1772b935304f056102dd56386b9372ef6b781125778254d44995bab3eda025a1b15072bad43cc1afd5682b16ce25195ebae8309c013ed5bbfaa9c7820349259df8681249971dfd2c01ddc3db884b424f3a0126be38a999dec88aa3d05b904b4bd83d2ee6043c1d394cfae52f77a340521e074963371f336152fe576a72774a16cc67fe0188393e5257b75f154c9409184dc7882e8e76c44c617f8bbe191a9eafe4d9243cae15e21df29d5863ca452ef3245a288ba66b90922243c5425aba5c8c845af81354dfb276445e7638df27521ac547dbc3cba9a395ba982649ee347c062f49167dbeb91b7d93f4daeadffcdf3b893749e28ea96747a2251dd12dcddf32d81258ac5e1626fd71cad511914d5d789326ef8c6c39e122d373d120c1974946253fc4bfb63eed5e467fba65f46440959dd836ea6d27bc4a21e599bf34788ad8bd92bc90f8902deffc3049c8b70c9de0629f23c561da895c73531c7471978f3e349ec1402aaeb5a6420bfec49334613ba38eb3267466eb8ce8d59adf4b3e7fa89e2274c0b2c1d5e34047f6fa091d695fe9d1064ba530cecb62fcef245c4b8f43d09f1cfb284d2456bb7aacc819ca1888b7dbe2ca0ff83c8994bef1da1806f9c27a7ebb01f4066e489df2076af97793f05fc779fded8cc8857e1fa2017d627eeefda020eaf90d931dea0bf2ef799e2b75c10b0f8c339059b86124a8db6a81dc435fb43b9890082202d636438c8a86aba073f75df8e3cb00f25ec6f0720a6cd342f71ee185cf3ecc02d4534e7487cf64be6feb6ec18d340400426452f811407ee619e2f0a440bf0d20f1252a42c6506345663530c1585405f964c212073a6ff8b86b0d61a2ae9c0511f5e57ec7bb433e6514688a56697d15b4c70ba4dff9ab8ba44f7a83dc758e4cf30c54e781d89513d83d6c9915014b882ac53f346c1c4b54bdb424b3db0688c95498cb9cd1f3912197cad54afadd7992b8f40e38baf374eb32a5e899740e46de3a43a8f39bfe7c9f77fb734e886a2212d4c175032075d54e4f44663a096901c81b5d71042a0f83841fc18dcfbda063064b2b09936097c6d75db9116b120847d2f7e01baca50e9ee5276548f69e0b460954143ed52ace21ac28e0c83f9e3d68202df581b25a558ab3dea6f7903571f32706ea6f46e7d1e53f6d15283d8ec329093f492b9eb51e5911020f4c6275593de84cc4fa54886d513dfec010bf4ac8111316299d70238b13cb64835f4849c7656d2e0a85cbaf474a1b9ef97cc84dbcad93e7bdf19c407ddfbbdfcb660f84cb303a705bea1c8ca65fb7955df5a2799b464b5499d4ffb010399475a9bf24a1a5aa03ef2c7dd2742b2336842a1b2c0ad87730a7c4ca3f80e15e3855f446d650449477629f313c4f6fb4a4217a4a3923e2f24408ec1d306fe55d3ce2f2f74536516422b51e0064cdd56b59be5baedd1e0d3f181055d0133f7cc1fe93eaa5410f74a11b148f70902a9f4e2676a6b4ac09fe8adc5f2a4f92aa5b8eda56735b937214772fda15e585d2c2a28777e3e755039e14322c5e88726dd471b446e35431e4a16d93141a72c3cc5fc1e0ce7731033d8ed114ad8b28fb8134a6a282c1fc20b6c5bd8caf1dc90d42bb6a4b01633d71b7b117faef2ff0a21c6a04c3e80736d1bbe6e843733cfd43091f91d2457f54f5355960682c21079aa9029fd89d215e307f6a4302057a57c42e62e034e52adf29c32f54f2d3d99d80053b9635ef497c564f733fd658c2b2819f189c57e9ab1ca23f1f2edf474eabbaa0371d966c29c6a30ec7cf09e866b7f88dddf0491ded82d9750976336d482c070633bb3b74b3fb1bd64564faff999dc059947cee8bc9d7815955e5e7a395c65a9988e184cfa2aba11d7a67263257d80c86466de8f6608bbe5ce27fe78cec69c143a2f2fa3064b76765d5c5d29e4f467b4d60793bfa8711d61bcd37bd612e548d115f7e3601fb39192e1fc068ec54b4eb8c9bfbc03f0d32c346d587193b8ea03f89d7c3b0388800ce66685019b0302d438b54cda15e038f79fc73f15bba5e4eefa3854b37d6ed5b9871a4c68d574525fd6e5007eac2a7ab425f0f09b43d6b8bb407bdd007d57dfec15cc52977cc66dbd6aad4cf6ebb25c7c66c7477729dbd1e4102b4911dfc436e9c29b3aad343aa41ef334246749f382e62d8d479cac350015db653088a4e93b24be39fa1beb8e1add7776c9826d28c4e8a96d554e4e62560277dd21e413f73e700c1b10e90a442a210b5c402d206d083c21b9b9a166ce94ac1f82a51040b1f3125afd009698a7b3faa49f4758298e68b352fbaf599bcece122f88bb819e604cc23088b88bd725c06333d184a2fe4285c4adb755ee942c78e0dffe0ca705cd465f6cf41406053e51ba9f5d14894bc014deaee964462db16cd2b60296041e8c4028d9db38eb6acb9a1451d6f72e963f8a96bb4ca7913b7e16a174162118e1d94dcb0593f660ee859b9736261b26643ce67ff9f7cb76152f0f222db9042a421a9d4b642938423414faca9aafca9ac52a4e42fefe1fcb3a9769c4daabe989c05ddc21873df5c3296475701c66f8e8e05e3e4626b0bb90c5c81913b61afcfa5bed9f78b5d667473e9752ece61a6b78bbdc0c0f572d765d9e2566c5112dffe7a7967743bb8568337ee2c091e2cd153c350a1ef642ca8e59a70b18be35a73b227334de8796aa5a5f908ce82566553f0758566843c57684a09a19e832946a089080e73ec42c0e15dffa5d3fc3a22ed6eee702894ef04c694441d3882bab5e3b19b77bb39b9134f94c88af0dacdf39e785c32ce9e98219758ee795b329c4a3283c89609c765679600e120e0da74e43590531452a8370f7acdc890af227ef833ed3f89dd90c8c4212c55c15753ebe2d2d9f8d70034966d14f77a869443d5e7dd4f25387ce285d9fe78cffb02122ba74e6ec3d7316672bde6f746497f635c08deb205c8fba9babffdf05937e10c0ce4b7c43971ab6ccd20005665d40581912a831504cc53d99e2078a2609b21aa271506b5435301ef04c6d6457862dfae833c81651b0f1ba9dcc52a791f2aff85393f5d68a7855ab398698775e08463158fb97bbf52eb4ee24fac01c1a5354f3d257ff4745dd952081fbdd08ea83dcd92f6ae1863a07dd78ba04d4290fed64b1c6014814cd81c90ec593fd8fc8c9e66b6c4284518ca65711cdf049454e5a59a16f34e93c1fd23c2445da0b891957c66f9b7466cbc1fc32b0a382351bc5b631b89834eddb2a8d35d2c4f2261733aaadb940cfacc87c0403e7d8ba238d3f1314c24f4941115f54a5041b2fc58816ae3864ec399039a91f8502577fc5e9918a5c0e752ab49da983b4b752de08a80bf1d76cba9f556393aa8ee96a2d9d76f3a8fec390782b9205334370d4f25d0f29510e2f471c6684044fa496ac299c91e9cf4dad132aba8437a109d4b188b6381dccd4af3d725174dbbca4ba552a85440ef9cd9a2a2ce1b0658827443de4eb17e69e3ebd75c3eacec4710b3ee4c188d391abb468db4fce44553bfd415f77672ba125a64755f54e99547dc8ca391131c80eb8b647d9f2b18d07b17d015be5927b2a40a66bbdc312e16731e49afc6efadd90b887593c8f0b8ab7c48a8837d2918e7b9b2ce4b12cc5211481b78b474713c641762d99a8aa0aa5fb258a62a393fb6320e78f168251db5e5b57aeb0d02ea9adcc80d00245fc80b9b1000f99ebffebcd30bdfd3fe403aa53a590a57f94ebb7d4511a1e9e0442465b695f028e6eba26cab08cce4bd653d01a2494db4487a3dcdc294f84dc59c341ce6f57c976863b57e1c376cd23fea5c09ae5ede3444c64404597f3f3700f12dc40fdbfcc89cb974adddc12545701f469326f207c133d0e620693202b01a031c8f102835953a465db484773104294f553ce22e39a560466b228950fe8594d689cadaff46a6b27f4e6e6b26313ac6365b1a27268a86e41bdb58d392abd83920819849a02631c279e96adda9889d39e3be786535a4ead7082aa2641d98820623ef3a77bcccebe6adc609d7d2eafda7efdb410b95844a8542b575d27ccda880f4c430f8c40f9ca179b09fff92163c85214f868e9a91fe9dcea6fdc336d507b73aaedbf3275509a8ddea008f3a04e5847b6ae6b006c7b4655231cc72021e81cb57cae946139c848cf14f3eac4f842b16b066d8e2354def71ae1498e3b6dac3375d7f1653a41de6187acfef508754220543135350ca52ba889eabb99aed267c66d7a7627acbe02a279711a81bbebaf5eae1c9133973f49e66f9c6835bea8ee90033c0dcb5a3dea5ba9d7c3a65c454448d6eda84c84ecd37120b0d8e18f3bf1491ae04dc9fb8a980d92486aaa7ff1795f166f6ce68079ac865491a2b63250b5eb7728acfc0968cf9f753ed242c871a6a4d98c43393c93d281ecf57fe38bfbe7df0bbf3f5cdd764dc7cffb471273a2c76a9810446a1c374f97bc526978649b85703a35e6a6e02429332ac0d99f08a41bbea26920312ce7a72d4ad4bcfb2682e1d1de0174d36aa0d34abd484d402463d7916b493b31c135971183a4214ae08f2ef4c8d5b16e2ff523225e1d5e2c263d71fa0b1e0e2b9739fbc53e46261cd3e6f7430c2baceab7dacfa6e80f3c78406efc56e47a642c4de674c8b5d7cd35161e98669cd281daea8be38ce44a3a790012e4e78f2da5c1c0ac58c0340db48d6e7a1e13255ead70dd2e4a27c4d3af4bb7a517290d679628884204515a079c8ae88ecb4681903a942059fb88880ddcb8d47415132e20251249bd05aa612adaabd5cc0832e680c9faef141a7ee4abcf6c5613159737bc49cd19fe629a5f1be80b35cf8c79d78d591a96cb121569ae5c61df116e892e4090bded4b1b15628c1f85e2831f5414c8d0aadd23e8950c7d3694885a57ace181a0bd4b93dd6742033b4b982c5cce4c66586c3f3b1f682a9ef939a64b197e260b6c5edfc670847719916f30c7127d7b410344119fa2c0af3f72066cae9a77af860fb5ebbce040579efc9174301ef5ced5da526b5f20689a7905da5c733fcb7f638ffe874cc977a9d16eabcfd6f82734be5bac2249c28ebcc59e54a2bad5c69e546c0080ed310755e92eaa5a74d9537f8921efbc44ac80fa2a7775c46ac323495bf245eec0a02e64b99e2e6f0acc6f7a2625bb6d81124e2f7c857d09d08c9f065f0d70d78e3aabf2c8fe93268e87915e7121768a0c5dae4a80b502002d86d462394dfb084145326330cf6ed07196d69bd5ce3dfbbfbc629e78ff792c4071317a6dd87cd79fab4f436a6ec909a98233ddb29e058b802a16b4c66d537bac5c8aad17412ae3d0c3f3a4f663dabb21d51b393a96c23e41cf7acb5d10044a7e8146bd97e9f43dba6bfb67fefc076d7826dbf2fc01672e0762c4708c5cb2088307d946e52d7cb124cf662a0cb003702adaf04c0345175b811ec78bcd83989788f4e1b4389789fe4dda5ee4d74da8d54fbde74852312ea0c790ec4ce2a98a419d4b735def0dc3f20e6c0177c1f676532c82487b1d5648541255404d0cab3c6bbb9483628e098e6e823a18406276b89152fddabe3ab79a3fb063e06277a710a31197a50d815da9ba850d8633da651e85bf2945d10f58d559a9eb2790fdfb65c841e04bd5afc866cfe55bce1dd1738d1d2526e04e7fd7e59e1a35302c3511cf560c8fbfd080e1da8b05137ebb0e1ee3afc97bf49fc18031abc78bb60536b59514be897565860f2b22db46d52daedf17e0476a962ca623042a2a79ef79b8f2815258014be8610c01b17c89c7a5111ec4bbde5e67255f7ff18b4ef6a23a5e2be22186c1256b5b985809773e3ed2de021e8354add2140e28e298e31c7b19feb0c3fe768aa8c33f9ff2c6895f2fc12c01713c7147e1ed5238b6f429e70f6dd475e5f2f26645005e23ca1bc15f2872c9f985331550a198863031a98da57103656a596bbec59350157ea33a60d0428a78d711bd6a807d49371cc728c1abfb8a6aae18c34d0b2b36fc0533f4c929d6d01572763904996ed490ff3f41c37a44fa6eb8993050330e71b5463223bd8b53788cf6f648d7d2db560290c1051e6450723fb978a0c213f0bd1af931561c271da4881e8397c02f79b1a75b67db28d6f6f20051bdda420fd7c4612b20a3cbf9778f96301c4a70981940a072d2f16feae28627b44a64981e84bd589c105d1406eacd04b583fc2d78b2162e5c2b6b32026ca2794d38464d52211b47f2101ec587dc58e470e0b8bcedc70e31f5e02e2ae12d31f99fbe766657e943ccabf125d627343edde9df62e9de6a5b5838121e3f9fcb21d66a893986b295dbb78e95dca72a153110bcbd2efca9f860203b717b06e1b2a2640dbd133a3c80d3b7f474f176898ceb2b2772e0dab1f460367f61d11795fa715b91d3f17e507b47031d7a432bc7861d1f45db58651491bd0fd197a30a51ffff9fa2ccf40e934aeb4dcfbef2fb76d4e74c7233840be7bb858202832b39cc70328959c10045cbb234e06a2c1281acac44e7a2f84c7f7fa30f4308bbd045612a72f1377d55dae2ba29ef36bc95c195437c1a2cc4313c5528f6790c9120f38157128e41cbf10406a72b85e0507b7e1228a3f2a80e6b85d29554fb1872046ed90deb2d0e170023928856dc52f3671e60d928cf63edf42886fd2d4bcb17359f59a07ce5048edf58f6fd55965d770220ce1fafa445a0c11ddc30c271540d3f8135d170bdba4ded555d8ad4b3534296f2b0a762da4bea83d60d89373d5c742bb07c4cfb76c0b823edb23ecf1871ed27300461a3d38e360ee80d2e338fca6ad682b06481e8e83888d758f9c4f37764f83d8ac023944ead7e0a5664559e8bab6451b120d42088dce7ada71cf4a1c3bed6fcb48193d39482b288abba24643bcec7442d5759e9b3094c52dd1a1390a166713d6a0a37b3c7350481b187e25d71cbfc1feafcda1eb22b5d8730dedcf9be91adb6ecb16144a25631a496c5c66ebcee41d00b4640003eb9b1d394f5f8ee79736e2929ce3791b1cc3df155e6dd80b2bc7f91ad13c1997874e15ac12488acc3f4b56d50582f0423087562b03c5e14cab16d17910cd795ed4c93e496aec1c8e42b259af81988b6fa1b51a5e488049e14d63290d30463343ae3cf120486af08f1c0f37fdceaa01ae14858b4a7b33a1b33c1a12588bd226edc4b4b9e1950f63c6c1b91ed74cdcf08498cac054231dfda990740021df3369b6b917e083f70bd4650c5f4debbf50c304c2c02920f1ff289abb20c24c23f22a7fd0d09b3913960cfa389173cb50b1f33181fd6abcfb34618c82a073353a14dae776fe127aa44a747296904b4dc0cbb7d2462e042552d0f9a7770e103a780df978a841f8cd6e4d18a91eba4e27d15e4e2bbb5fd1ce94b332fc4737a572399f759f2d2de70d92bbdbf391252b54d4f9d2a85d6aa832c5ac0f259bb6e013ba2f6d387fdefbe287834c341e91eaa162ea5470ea969e6aeacab5edc457b0bfcf526f0be7d998d3acb54876ee31fe93b885ca08e03fd1101a9f6283b664cd8b66f7ae81af8c330f168269a3a00a2c0835be103c2365db06607e1b80df50733be2f24002d1af85080efdf2891ce24b98475708d11c44a9ada84e8ec23e5b6540f76a277df5beb0078ff182e145082c0b48e70b745ad2651bbb70bc8e4a44da8bfd261341f8b1b9f0eff3f5bf8f4cecb0fe8637b6414d0fe7dede56801b0c153b3bc732fe6905419785c47e72f5c74dca782f222d82c987d84d46c3f83849577f2f1312d9f7c43231455d231806b26dfb51d8ba02fa1be8a6899e3eccb2f5296a1ce3657f20cd4173ab6d5c6642f29621cbff6f5f3ffef84151fb5da5bee1f5de807e861ef139f4b5d0c8eb07ada9136931878d4dbab9de4a8a783a8672f17e87d089e3d744b63154270cfa78a78fe1cfa704129f5fa478885f56fe8e6cd20e377c600fdf148f36798aa837e0bc17ac305960771d14666f739edab5822869e9f5131173b050a24d269c7bc12eef2af6cfe83165b10677ec60f740aa0e14e8edfa28e6412999eac68e15de1d1fff9b82492156030b289ba7836893213fde4d4ca4d6489c2133a8332edc8f8e483452c05ab127846b65fc5930b858c4f6fd0adc85e18fc675aeafc65d9b9ced088ef36a8602b422833128d4263be2cf94612d8b6809da3fc68f4611417b55ea332ec007171df88497c2d16f589402e30bb79ed859d31d9d83f6904bff7f2431e7120b7517bd94dc57fe1ccc3965094d4c8e8be8a2e5481b575cc5ec4f76122c0318b34f5ea50322def9c366a9a9956b9089d7326c330655b82edbad92b26b29f2fd87ab40b833cdcc711dfc62f9cd7bf9eb0738d4cbeeeec7ddd4b6015639ebc1f7d1c01f716642d54edbb40c3a5c5aa960a7dbe6a063966885fa62d49b28ea00681281ccdce548ebfcbf26e751f1b299a8dc3c21023195d54d3347bd3ce61a69da8605f89c6d161737efe6b5e527544cdf3827f3e62ebf33a7d7520031b79f3b8967ff40822c9467bda6d2bf3c06b0e5b42791c3b04db66ba7aa48f10424ed7cb763ab0cffab6af5e679af3183869c74b4e2f63d2ee48f26712972c2d4e1e4849dc4c75f7a3100f5a165f5e15697dc70a5a3ce1f9d3998e8ee3e110c87ef83a5fbc2a20f64abcebe87293ac719fe5b20ac2afcfa7dd558e9be395d0d972a074512b12391d7a856e1eab046b1542cf803f928923f0350a1d76efe4800c91d65eb9659b051104f7163bedae3d2157fade540eccb48e49522780ed91c88b4882f1e6d5a9e4e956859ef320223ea68a57c7bb565981bb56086007e70335f42c08ff6d1ce6a24850a91251ccf43e9b9617100fee0f149ba9b3bbc944eb403286996ff9774228e77b6f9fcec469e0a3704fee9f7077cbef9c3e93117f8cbd5d915b3c53ad34a76cc7decdc8fce33cb69fd1a3db3d11f9963ec58c302e7288290b5a3614a0be453e048ac50974dcbcf9dbae46a11a2d01ba9d9493d386007defb4108f7504d77601c4925a6daad1c5363942e014ef97b2e7dc4a6bde641f4abcd86c5c178ccae69e39aed0f09980653a7d598a67d87587c06110e005a754854af55ef79fdf2034e5efba7bcfff842e16cb8ad4f524331a30ed6ca4b7d121bc637b804f90307a5c9175644db5e0917add4308549dbd5e51a4b45a208df16be7b50dd54e58545da5ec79bb82174614fea40bba4e5433357ff87c143611e007b7ed55347838820b5364dfd7de952e6fd5bfb344420f8ecf3370f611f1b8ca86c9f1dfc5151f5c3b3de30d55ec60359d2292e926c6a7595f5dbc7300730539f47274c2ffe43306cf8ee6bb2b18693b1dc4095bda26f3360a7d247ec03d03693849c8e3f91a802bad6cc4a9a4620f93c0d3e1a4c744c6cccc1d7a9e955431c43649497d61f3d162d53379f79cee4cbe6bcdc2d61751f09612519cae44ba28c9d9c481806c777a2070465aa43dc7b50ad106e6dadf39cd189d95d647b22a8ca6d931d7cd4da0bf9fe28cc59e705ee3a7e3368e5df8e746a0540ea25c8e769f6dbe1d9b5ece225b7c796066500bf6ebc057520700e429d65a4bf05bd72cead9948242ae7131f21941a627a08c6ee5635749207777ec455eefce4c13a8e956b4509c4a88bb6d7190c73399899730719b5c97974cb960cb578e885a1e3d1e1099dd25a1565d2e3cbce28987d10a8a7d9125c41f0163c50d7bb3bc7eb4a9bec9cc4facbcc08e202dd50f820bd081f446fe007d35b7c60d01b1fa136a46e92cf79aefff226dc939b539589da8912f1a6b4481dfdccad4b23ee88ac7312ca70d9b3f2073aa1a579d8fe7573bc7fa2bef54c696c6fdf7e78d4519e4c70c0c24eb83497faf40dad191c6e70faa3e93ef1d4c0b9eb43ec8716fdaa9ffe9f2dd04c99625a72e36f9ac234b0b681f406702964653482d682f1f31fef22bf1fbfcc0abb32da30bc7887cd6e1080f2d610fdc3c070a05da2ff98797c02832842b37a31486af908247de748b1b685700e2429d718f46ca2b34d19be94d8182562464ef17dbbf66dc9a516a2ef0715879561d631f86bad67db5a330f5d3143db4864349b4e5e439e6a145353bfca7928f2feace6eb5e4f935d923728bcfb8b800028ef0487a83fbe1b680b9a91fbc49d1847f4b0bc6d1d810bd1501affba3eb024258d5b681c5257f7bcf598307101af3bb497916507da43ced9205c51360fdcfa0ec6f9c3d6907a49c3944942ed6b1403321c3f47189122d85e842c1bfea28ac0f786ea654cfca4badd50bc7521af9093e0bb0ce3af8d27af12451912a7e03f9ba0884a04a6f63c436d3e690703b53f8016f8b6c884824a342b9d4bd811eaa40f474e30e1c54b7ce52f91e860f07616aac89882820a69da2f20aa2f5a7e48b6ae869c82ad837cac55af7c9e5a685474730c7618be629379d8a54b4bf5d6354c2dde2d975fc749a699de5bcf32dfe13e06054df534d6608db699e91390cb95e39778d8f185a045c9a6ded78cbb8bebb23c9a1657a9b4865c78a40a224b6ca1b7e087d0ad7113b3ea9dcbf4e5c377949d01abf2c32bba86950ca4d43aa3e271cbfa86608830fed8589fd5f57021ecbd1e54da6438a2454ef04a642a9fd42f4fab6590527517b7dd68956e86bbe299359914199efaf4397ae386da63f6c14e4a36c81f054218576a384b5108b23cbe4cac271234053799dacbd91adcd74df345dce2345c3a9707059cba4dca3537d37ee0ea4cec7a8fe6a79446e06814c687a9c68818f439d39aaeaebcd3e2cfe75774397f32430b66bd3877911495c0b90ec1f01cb2451211e8fac316c1084aca550cac2d1cf43f788f935a21c0a17b13f88290c543e6931996c1e25e5f1cfd818d68f1d718a14012873a7568e4a9c3ace3871dc91a530c3f8b3c08a115bbc421eedf719a144536195e12bdd800777f408e6e9aaf1d3b1b0bb87ffc3c94e084a0819bd9d3abf590030552b44ce0fafb924615dfb78247e8c7fee88ab90e7e2fb0f2f3d0369979b5e7fa727d6eb82cbceccbe6c2cfd363a489149a724e02405120bf626e544ca0fc97abcdba3054a11e20cee642794a24f5032853cbea21072372b64424a011e0df224280a169000737dc72ca147dfb1449e13e8e677e24480e70a695a9813dcdc5b1e3b94335331815de9e233d6bb925f0d7d308a3643d99d31fb370823cab57677ea5ad136b1b45c389b3894ae5f5d2f3b31d2ebb1e1d08906819b867c13fbe7975824bee474b0ed6c4081ae26e36685abb04e98ba00838ccb34b2f802a02014695e898ded7a225c4104411f9f92120a301c48795bcf49412e8bdce70dbf5198df4dc5113a9d52dc7ba1289e4b06191ae36940f6b13dfc92f6f18f669e92e0c3d5136c18859daa4a2557298b148187e29d8705f06809d260a3e5f676e2316ab31df76b55d641610ff61c97b823ed61e45fb25b89ad18d96d9168c1be55674a901cd7174e0498f1a1959721c12bf32c59a6d1b0b7acc96e006f714aaf451669379fb9637e82057cb1e8ba710c43ed117efddc17d4b67ecbec195561f8d195d0b51a654142b29848324853cc777a8fc1a561382e3e232004670bb3cd56762ae8341344618d4d47208f9ae5cc52718b08f889da9a97e06a80f700af8dcf73618428cb7379e7c5b5052b59918b751a4f32224c61a66047a9d609ef5cf7252744b2127b7b0dcd7f4d8d13419201b06df235b024967dc87a922b4aac44fd1ef94ca98805203aced89ba43710323d67c2ffd03dc483c224fe43dbadfcce5aea24ad2bcede482b31e9ab7a13b324162d56635f5aebac9329954e1d1636841199d58b8b0842b667111739611d939f35196b8329c0015252758e78be56e19c3f1d6e7b73d4973a07edee1c8f31d9f1d20c23403b2a69d1afbc501a68c5d04a537f5b6f7f7d8170edf8dfa4ea72f16891514b5d8cbb41345bf16564761d5c89ee29274db5a9a08350f6a2952bd1a9f8631b85a59ce5d056e32625c6c658d19dbc973c83bf165489269f42f7c502bd3c52ebad09cd44b8ab5e1762a868c442724e615c2e6aabeaa3e46c1ab7e6104a9f8312b55e914184f51eface583add07f9da6228d3b514c31ddbaaca1e2c5399ea3000df3342ae2ce01dfebf17217421e038494c4b3f8a52cb91b36c77299fa336043a349a2a5f5d4896a244afe4726e94f2f1cd02e89a8cc400eca22979c08e8fbee7aa0ead455ad470eec33fc85211e56fca0e18f50dbb16823a543c0268c73bdc87d7a13ad4465e7599845368875b45e64e77f9ac29910108941c4df04224bee7e0af26808da05b6f30a0d558ff366302d5b9441918617386790e390d43dd8972b5025c6c003aea8906482493b7eb6987e1c89e66b4cf8d66a6432f225636563d47896aa06320b538703bd7233d2d1529cbe7c7ee2dd4423412b1455299adba9e05be87f440f5e14012d7e44c0a70f243ea516758995fb4641dad229c4b2df55f4ed2569830fb84e55ddc040e7687690240734c5bc05981b9d3ac122aa490e35b08dcf2cb5ca0f9c3affeeca04cbdbedc41302e1f76e456709531f609d1747f497efa36735819d20bb73efffac7e9eff52b0b59e4d3378f92827dfd5044f3097f927bcc27172a13e535873bc7ee971f36e2991b3e5285ca6d09c9b166b6b2383a7107018ab6b541699593207c7925a0c5050de446612391dac6b634082cad3711cadd66844153421af90ca6ec7a352020316d835c08861f77717622817ab926a6137490c2df60c003e46831b23ed3539f988fd966b029475e30ccfdedaa30e92e76fdaf4b1ae25e58bc6623d7b0929aaeac3d7481d9575a46aeda762796905a64186caeb0bd257d996e9fe03c602b168926d04f5b3968ef45f001c25311619ac1114e23fd8b1f382abdc0b49754ab15076aff23f4159bd0fe8d8546f24b812f542c1fab63a0b775563536c8fab6282a5450a59ba64521d033718dbbd107e388c2a55fd0e4711900eb7ffb18f10f7f17ec0bc10d484c1f998edbfa3218494f575857949868393238dd66bb50341c84409381a5c5858a3090a9a5e3b58533aaaedaec495607d3fc465dbb027d826ee187dc2d706a0e058902d099e6bc132daee3c5c5e197d20835cc6942e849f9fd7a20cb3c51f707a9caf9af5c11c19bb3a83385cc47d78e1191d231f8ab3d1d9e783c7a17147e14f2e8cafd98a4cf8f1f9ffe7b1de3e8fd2385fe6e16743bd53565ba155d8b4f40320b9581ece0b38edf24bdebc6ba75c1fcf395c07a846cdd367357e89fe81b277ba6c89bf63ea5ca94e4784b72e43615990f0c0d770aad51c735ee622927c9ac3672eb2a61cb3aceea79f601296b9ee528c6354265d92cf2e03311e97acfc850799408287c1e6ea83720320c2a0e42edff504fcd6828da11b30e5fcaa543794f068cbf16518f78073053f5056c69896d91d70b7f471f180938f2178d0d091153276065fb61fe168fec0a4768f2e52ec14dc5c6281026d6bca4897d4a04f074a38b2710160171b4d2dd41e0245ef7da941f11e1c2d79d6ca006d018b395bfc52b92cb4473910a29ce103749da71e5f1feb322497717a0000ecda2e68e412d0ee340f70aab402bc7fabf24c05ecfed15496fd39a6b658b6f098bce75a34662085a725f364e6fc72b38368ca87693e2ee25a06cab2f13c10633ad73b4610a0edb78bab3efc06f38b29d3540aa3f72bc90efa1e3bf52e0bcd928af40844e9cc78b7df1e7d01f822e608089c4007f1578090ec3b3c1e9b25b89c2b07d48d6c7c7fdb0dc4b3899a32c7456fd13a8082b44dd67413911bf6bc98e8502520b8b90edadeca68de6641375b4cb4535fa9283490fc18de9d4df6e03e9b66b13103cc9ba7d5f3536e4e8814b5d70c2f01c7fb69161128cd4aff928ec7a4ab49e6bab1c7fe7927dc7adda2a08f0d1c37391d73346781c2aefa346499ea2e5d2ede2108fc44a03a8c38166dd0c4a95162db39cd9b834c7d804c4d3ab9eb3635502deab599d5bfb95d72b59c90614a5b0d74eaf9cdfd00982b5aeaeba9ccee837140dac541f5d0f80381e1a6a9730c4f8f7e8b592c539f96e73b7516b998db9b6940b65d5a0f0221eda939af58f93e7d77a24b06c49ff53589f8342ac16f6fc94ff29dfb4a585afee9ea933122e8981223bf3efd4af410088ffca42ee334992d706f527a8d8f9989af067e5a9a2cb1dcf0bea18232260654431dd51726d2483c29add94c217d05bb8f8df072f3290689d49212f3cea2fbc337c2c0a9812ee72cfb1d7acb55f9c35d61e5443e6aff8c447252f4aa7a1c1a61c06ecdca76b8edf64881827726e0601e59b5fb844b99f7ada63a13627730e93ec90310a41ee5c744b0c1870a1844a91155f0f08c4e160f9e8ba0a0decef6d6ced168987d707bfbb50e03073924d44e4238f11b1b9002bcf11b746dce92af119f877e66bce32ede73a19bab999413994040d76bc561c893cec7801149659b8ef301d6256931b573ebcb4b5ce0df690b72f8c242a9586967dfecfd553b34ac214c3dae889f4ff465a916d8849cb108a4dc1bb46d2e4753dc85642762e9d4283287ba83db9657a2e62004f4b0d620a89cb1a8784b54e34aad099ebc1ad7da627aba9597158639a5bfc526e68674a278d7b0587598890192478083dc5015f28582c8c423d6b7df57e2c03e92f99a19231ca14db9243bf11a8bab0a0e52b3bd1d4669e67461f34c00dfd0c48617bd01416c725384c3ab741c7f9c3b6da7fd521d4298563ef8353d0496a901838de4541b4559cbd589b083a13a5fb626ea4c8c042f89535ce839ab143ec88a50e3db04b581c7278f551a8a0c88f2dcc588482abcca00ab84d498b8fe29b401bbbbfa42a4cc226c1723dd88090ae5b22ba8917b5a060f2238fb5182ee2d41fd51783b1ce5e08f16626f5150a104e8d63eb005c41916c3b78ff58b8c4eba0dbf7ccec9aa6d2ccc3187a3a3c3e57243b0440e80824362fcfce297ae40bf0dffc84b19e9a44a14ae41cb024b9744ab18ede9e9e2cac6836fdb89bfc895a99275fac83c1baa87f0efc48166f755a68405144199f467d9e57b559937a996ae5a5f18f8295ee7db7a98a459850aeed35e90a245a0c6575de32d8eb0a2a7de98741e77e219d80119beefd82086712390ec8a2a37e78aa88704aa86a250c2f91d85cfafa9debbb80f82eb54509b6bbbe00e6225374e4a47fb5554c833ca88ba7eec656e9a5a403f7c0843687d500d2e66659f5ac6e26a922e047d0d0c9e25d47b4e48879a0caef173b279536eeea391eaacc1c095d2bce4f5e1a700839dd29cff2c1a158d13d28883594972f14f4bc943dbf18c1486a472445615dbf93f665fd7422e5b5382f6b9d148d0608df5f9209313c53139c979a50c6ad89841cf08101b2c6a84b18fab12f08fbfc2ca794c2c51817d67f36a01b56cb36ad8911d2fe033cc1359926ab888be8b04e6456ecd63805422364c752783210f6ea0dbfbf1607c35e9d40945be8d54d4d7fc90e7571e20cc7f8bda3b6547dd170a3e917606cea48db513251ec0129194d1342637a7ba2387ed867bfe195e002436a2f8f93fd2e79ed9eec513d79d2a185daa39101982a301e09c7c1c225ac2a62d9a3fb42db993f9a3f774e321c6843008dd08f367d3ee56f0543be85e04438800b0a64513803b6ab4a312663f544386e738e6f443e3fc04d0a4f81269f1ce79121e9f9466cad5c5eb475f26834f72cf718638528c3e086107f32ae58b8e29b3c9b8583796e9c240c0faf9435b770d89b007d2397b2746a1d9851f1b9c9b59efeb06afb1620d64dd67687b5745721b673c94adad2a4404c602bddbb2d23658d969318f449527b0f128cac9931845bfc300420011f792e93535fd3ea2126caf2c6b864cbb6bab4d30214e246464078127706dea43bd1db23d6563ced164200c029ecdd9e3330ef7d76092a4c2806c348170dcfdc08625bcb20cdcc4ad32ad2d289bf6af7d119037f605b5afbf130a6092e072dce1beb864023a9f79c5a3a5f98dab3a65515609b404d5ced7bc1375aa94ca605f68846ac4ac88bb194d6f6da7aef92c63733af3c43c30810409578e3d8e22d31d0b06283d6924c9bb4901042a939610c44bd3feb72862b816866ad20a54de52c01758813ca8b6ac36be0c97708225c799a837cb3cccc967080bfaed5163cf3d8382d0a7c5f482bfbcdf0a4ea2513670bc39a5e00fdf19370dc6542f5c3226d04b4d2c0c8a65bae7c481bc49ac926aed78aac0af2cb110aece11b8f2b6fb6cad716f50441029f1ffddefdce253c4708d22604a82b2f5016a63271cd02e506c7ee1c80cb4ced4e47f6383fa6eee82aa0472af9552e176672d5592362440923fda58a8509a950cad878e023c075f585dc3552eaa4af92367ec4659bf5cfd8e6afd04c17df69629aaf19d1855479b5f1d7c722602babecbaa9186e8895c4115b8238bfab23413046e63be7970c971d902fb5ca2ff4dec4a236343bea3abf1845c1b469d73a1582d164635cfcf2a04ec1e215e89b940fca1cbafddc50fca43805600a8e086e85195800ed609459d79690f4a0514c53c0f32c1c1b08222a1950c04972abeed430e0f17eeff06544212756bf8d66c5dac489283fc60846329da5412f28a0a83d30ce860d16f201887c0af84de974d009e0018964aff08d4a9fb14785d023bc804899568df516bfa449263b931b92fb3cd3a4f2708fdd851783d1362ca45ff38a0cded50a959292da82accb2164b0ba6e0d6ae606d2109b53f666359995afa62923bb4c3254b0bef114505603218e9a56528fef28461b3483249d1e9be49f2445b7a3b878eb4cfb1036ffc01f57ad9908c34da333896b780d4f748046462c192b269501842175b0e67d9d29481ba563f82c6b56f3421c637bce9bb65f7017c4cbba2ee7d9616657655095c1319e295d1e00c640eb26f2f431e1ae4587a4343a79b870d4528c8e0f69595a624599e938458ba643a20681980ab6970b017ac0d7efb1b5e83f1b1d1b063926abd58deca36d3565288acc2d4088b8e13896da1e46350c39c5e761abfc4703271e668c1059894bdff08f0614aa4772d9f72e40ca6e04fc34193503ef1c082e75c79095e9839c18185ff4a1551f946cd70456766db1d0a4f39e59c52f62cdbce32ed8a8d3dcc41fbdf155471ab636e474c6eed245703acd50824f44e0d6295915c1412371d0dd2536287265c93a71b58b937d47b6a8671bc106c95d7aab570c244ccba305e40c4d55127dbd9c5a9ba9447fb46c313266191a701c076b04f76ec98206554d22c4669aa6c85c0c762d20bbe3f6a9f1ca611594438f7895240610c58f75aad70cd75470f9a007a30d8b5a66b6cd5bcf836809b187d1ae86248f569bc749900106cc2baf43949fc306c496b9a6a34ec5baddea773dcb7be6e2f04e0e8839f302abd884c807aa696edf973eeaf905e67d6d1ec80e4026696ed140ae4713a22c64b59ea37cbbfe1b35c3ca0e35f07a2990236b360f30ad7e84b23b55ba60505cfdf008b59d44305570b0a6c4b61ed2fb085c6be5482d0a77ff94280fec16f228d04adeeffec810cebc7be2a3943f40c67fd14b0b35c4a3764e1b639249720dd7827cdb22a04e235c9299802b7cfea5b7e9b07a554046400639ac884ba9f7ca5c0315daeae4ad29a4a780f5bd9929780f771215b229624002975ab68241f120a3611a03619244c0cf5d911a6e70449cb23930c93c99c03bb04c229418c1d2547720e3b3f5f11a0e84f0f51fba5af4768708271f0d432dcd8c1f808bb517fca85b7eb18b4ed187e5fe7dfb29277cdf1e9b9278c766e79590745e3c9648a4a94b9f5111b59ff4aad2266bd4dcbb7515195fab0ba485c4b62bd46873652e4fe998bc4fe4ac1a50d4b0eed44010b2540927b78d2ef5310655f3234c947811482fd9c0c6cf8d57d82494189b66697dc8798404ea234f787ffd54f04af4e555e138802ff0328b4c181612b4d80208dbfe6fd60659c42b0cf8af21dfba0e02b4ae205ceb8d55ba19c43d801e50abce08d4456940b0b515ad01552167dd7149183d6d7fcc918d5c22d5a993660a5d87f30da0149d4d0b147d6e525d843a242acd3368170c7568ac5c4dc2c83b5623bc4197daa2e0a13c07552705d4dc3717ea70adad8004b6c51d8766d22d61599fb693ace46d0d7edaf0a79f426834864b8fc06c7faf4e63cff3dfc316a740bde3001f18212b212881d40245ce78e0ec4fbc0ff945338c6d62800ae1449d7404da370037535090fb2dc3507c93e817a9f9b5dc5ba646915052059b0130c385531acd4a53d6ef234cad7165e4983c14920a6b1dd439844c3e49a52035ee80c3f81caf89952fc057db6bc1bff7c84b99672ba5292ae0930bb2ffacb8c8c6eaacceb0de43af7b79575dc5e36931cf83f68165942fb9de822b40f64fb78069f6d9c4665b39d6c5a356dea6c7f23c5f638119327621b2f5921f5a38475344a68af2ac4c0f4c06f1dac3127766da05c31da5ccbcf18b6cf3ecd417178c808cce370407c25219795f8fd540c9cc89977073c9fc4d8638d7f1b18a056b42ba00da1a4ec79674148924d98e4d9dfd73e5260f663507af88dbd72c9b713ed17a919c655c4fca9b71693899e4d54dd0d7fda5dee217f563d1dcec94593801d3a5284a4968d5cda17684dd1ef507c10caf1ca437aceb7d0af69e89afc4bab4a19d5a3cb79d2061cea20e49495ff6ff4f5b6da38298de4dbcf9188b581a927935ae7da7395a63d717c8ac5eb18f1f5915e6dcfb781c4092d23fa99817d889bedeb5190597d71c448f9b70346d64334d17cae44d9fd1cd6abd6a1d1d331ac63e837550d40ae851ee34b314dca48f9de4d3d458cd0c7b422494006ca41798f11c6fefca4879067a76c39bcf38af2791c92ea1e810d041f517ea35690b4c32cccfa2ab67cad629c718014d15d0e79764f1e06fbbee7388d92db5c918955692f2e4e6ce4802bbc02cbc6016b35dabd0b3d7c5e6c50973edb775a83f9f51cc05e6674d572f0bdab7dc19438ace4fcda2c8787ed7cc0094b21c5127c6ed177f6364cdd5e92076b7d9b7f9a4859ac965fd2e454bdb77ab009e205a2b8cf0ec12c3cc6800e2745c3cd5d021e34bfb6cced466231f4446b3b0843de787a01c1c04d7b7380246d95a9d82bd2cae6d967b9edd23a9f8e6a2a61f96d5e277650b2057ad66aa25138cc5e91266e3be80733d781805527e225d91b044f2b3a1cecfabb3ae8e095f8b1eafb2ad148b8c6d410701f6c4dffecb8f431a49e70f337d1dd584b9a6095069ea7d87e14402c5483ccb79c815860349a6fc9eeb639cfd52fe2fcd5808d066a66c6300322d74e199fa8c014c78b5424abc5949dcb81c7e5cae3d6dd813a45c4582bd5bfb8450b03ae76ee5ea2ff5a1a3db944a2d5c638414ed72eec1656b46e2167f77dc9761e4243021bc45f7990b953ad35eda2538395ed7870f350cef1ba503aba18f172dde2d46de2343e22de42d3ea1c2ce175a73bd67f36c108ad619e7fb06bd27262e320e95d21774dc1b8cb65355f3db34c36bbd2f596b1e4334be8265e6d27e6667a8e163336ffaacfec3473d3bbedfd5b8b964210594fd36304cd97cb09daf43e20eaeebe79f08829e0700e685a3f98078c98e302a0f5fdb7d8d3a1ab30521ad8f42dfd27c7f9974f55f2978efe8f1124b194eda34f5fc79a825b8868e3796bf411bfbea58b0afdb042941457f3f321dc53128a36b89dbb2dd85bb9f96faa21961a3448033f29b2ee181443999cc30fea01d5e24ccfd0c5463eb8f51e9a1a8983a30093ba61393e1e8aa5287c92009f1a7058b09acdddee731e7a6c4861afc55c7091f2aa5c8ef698fa39eb79e0af6ba2eabbc5df753a0b36cbdfe42d955a3143cd93271cb8f012652c43e54775a31cc3e3c9b60fe8e495c395937bdfb8422a340a3071b8245a12c4f2480edc87ea8fc93101fed600f825a4314fa0482adf0eacdb07a029c1f2f07de4c4fd3a5c0107a6631078867a3a812c272cd2b97addd7c3b4c0c7c19e13396721783c4f9272ea714669dee5c51d246dee723fecfff678deb7c37756c4538a2b1945250e67c6c117e75d0a619163be94891e7f13ea29b7fad1edb8988bb19ca2af144ac13acdabff82d07dd1a6d72f527d0c1c988f3ed1bf0fa1cdde0bdec42b838035e659a8b2c53e1231ceb843235bfb1d7eb52dac6a6af0dd4feda255bdfbe90a80d5b24ab259f358e4f1fdd42ce99778784529ce1088e9ddb178ac67345e4c80bcce2120715a1ab4e17c0790abaa4b395439b5153ec5ad3fa4018bca598f242c5200df5c3d4ca72f72f4236e70b797355843533b291a40c63ad423ed5c16838c586142cefeaf2f4073fd06fd1198db10d4e327a9454a04fdb0afbd25dbde2d15179920e06664e6986a9551e6d0e750231c91f81065aa5cc56f313373c110c7f022e05a39b2b021b6f59d28733088dc715c31a410483dc68f022e9286016b05ca4a306182b829f5fa3140aaadf5160359b14eae2daaf5d9e0e55d52a97313d46c0ab641de352f092cbacdd880d85e0ee3be096076fa84c23cf3280fe1d4406da0bf9f233e1ea908944b8bd1964c5f8f0f765ac4c0fe9a9e0dbbbe42a6f8fb8b4b9e423fbf56393256669012a4dc005c89325a5ee52f14f98402e22b5bb2ff04692007853f3f3a376c7cf9c23c987b5e443c2d488a05c8295d0f0f84c6ca7360d3f22f3632f0c30377167e8d75b10c515fc21ad07824e0ef2b53971f73edaf1653c5ccca861cc44cae8354b3e92b4d99bbf7e590ab7a982dbfe883b872b2bf4c72841209f0ca3895360cdc5e7e484738d7e4b6886e227c1e2e2f1526d583117d7c654a75688b0c0f1310b6cf6f2c7dd49dc3a84d0010f2b83839852265f1fff3c307404f18b5926493b6de12288b1e703cc5f7f5ea06ef1dd2011202c80ffcea302c6758de23336d03c5d25f3df577790a4de49efd09472ba626a60573fd3320afc9893dbb35cbeb08014003cc61bdff6bb1d5c46590164c2c7a0b82f1707b8f42789a6e9b96640fff53f71c62840ddc5eb34aa4d3f3ffd8b9cc782a993dc2fff8b636b75ee60087bfec016c72cba50c76d30f9da80d8638f029d4db221e00d40a908fb7ca99f32c671387cd3448972d84a69459dd1a17f1b40e5512b04e46cc28b5c8156ad54c13720b0faeb614a97e08bb4a78039ea027bfccff6db0637cdd6e0ec832423ca170ad3deb57ffe3343c34f069a5349fd8eb8de975a56587044472f49b370550fff00b16e9fe39ce7e0afb4b8c0e43e234a4db043c88d04284e5228cca274ff92236ffe0f68ee67be398a65dc407da34fd518f807840732e79b881a06fda39874e17964b0f4742c2714e3e70d92055827725bbc7942d9dc4828d3227c7735267230ed24fbad8e9883907a1e336963125a2366390709741dc89e9448fdd2145be4e6d34a4d1d91470dac20b4eb76b970ca456f8572fc4633fc2598247b792687b1c7b331a3b4461f0012e4e9c9ee9b04dc587dc8371141a655998648ff89e91ea9264bba62c8e825489d9c7b6913443b8b2141bea76f451f489d05cd8241023b948b112a703a173fd65c849ff96ad41837bd93a18a59dd35fee4e6f87a9e5aaf775041f5da2d8112a138c0cb8594454a45ca083886b4e310d0137d663668d80b30a9ecaadb345d561049d459bddf0ae98bcd165f3d1ec3fda3e856e095d7d0800feb329b39f95c9fe291876825792a3203f4cdc3addca09a724f687018a24e104c3dce0bf414d27c0bb2d14bfc1f5860f3bb1d1b84869e0c8949b867e390207d96b9506fdbd486deefac20a0b1fc459983bc0e0b98aee13da113a36ad2fdc654a2f9fd8128409c00ca213bd405f60f97c85f4332738288791db25ca328b4e7b3adb7c0fef638f5cb4b1b31e94e47b9ab1e2e9a13753e1ac41f849edc5777d3e79e911225d79a952d93ac11bc52b67451cd6b87cd75c58e5ec3d2c1790d1637276914bda8b547057b6f09f9056cff04dfd118043bae7b50b13af90a8cf86475d6391ca5b22b0a23d769a35ade080c36174db8df670d0b7555619623dba5f03abe959f440ef0fe46f5c3b243c71d9f7e8a50aea522d08a3a89548150983254d893e3c26c8258f62008eac8e3187c0db5942ae141e62412aec3771cd63e1fa224b42a59847c6e7484ed31b26a1fd8381cc0ac1b86e6873ad8ddff7a50b08836baee156592c2e418a7c6b3294d246683b645f046163430e170d4d989fae7861782e9e85a4a8d677f8bbe23ffc486cbe8efe00a4832bda64d452a3000311df6aaa591268dd750376ae9ae734810613de6931414f2c3d202c82bec35f761dbf0588b62177647db07a0e9f9643862cc51e6403f02914657a27f457d717f19afa00bf6084b6b34731f5b9964ea7cea07d5fc5a85c12a00210272f19b38803a94e9a412f7de54621888be887f213fc7d9c336a07c5cb0bdc4dd73508109047147332fdf6ac19d17d0afb263dea52bf6a651a5a55ca912ffb69c71e36c05dc2484dc2aac4d0f848e18ee5718edeb123600c02b8df0614883dd215e67070e83b980571522882f83a1e9ce8e828ab2bfe34f42558e6a9817745974927ae5333d244821f67d9df9c95495ea16745e861e5f70b72027b74e25f0d125871b44f3463eb9a068bcef7cc2e5516bb9f3328e897121b563e302d606248b579f57b2deaa605316584c1ee99e24c5a257a590124cbde59c00253c501317b40c2afce813c59075b831ad1e47fd01ce1b9ea012264450f8d083cb43541c6b772bb254f0ea63ece3168b9a27ae823339c97bf53bcc40755ef1ad035c9046fc2f43d0730498fc4f82c511b831d1f6f671ffbd0f60aed8d1eda8b0a6c318dd5006684b14fe4a9b0d4289fb208146c66bcfa93837cbdc17268465e11b3bc4ec000eba5b06edffda7bb5b530b8f076b6de88621c368be445efc6934f7da18263e4945fff49415072fdc2432368dc42cd6fde6a9dbc6999eb59bea5f2bc2c1a311322b57dbbc7d66815760a6245b0a8801501fc46d4c86204072ea71310dc2170ece85a1a4e93fdb5f3279ba9ef0d8b214e89733782b3073cd170ba670e47d832f8d44d8cc452cbaaeda04e4bc0c8a5243f98713b02cac0047c88d02d7be6a9e661c47367b2d984668ed2631e89d848a37ff8f8b7466fca64fc614be9c9da3cbc16fce7138d531ba6d1cbc5f82cc7fb4988c4693f6fad48d115a621fa5a1386c3a158c28c25a8ef9dc7afe78faa7a3563650455c591a0d943da8b1854a3284fb24f48f8520da6e6ce0a50ee7b2deced0701ec88adfcbced1801c4f10b605819f80522e20b15084141fbfca155e9687368b7bac253f77f83bbea5c3a0a03ac22aca32e7dfaa5bc33b3ddd928ab92af639675012a1f14c7ac8e4370cde2f184e1ede5465f7e7e567f3ba9313ea13e3b371c0ab55900b58463fa2b623f2c2080b8bd6f0f040552f2a3177953cf405d8d64f1cd6f260cd10bbb1601cf91239eef86da322d064eaba184c4ff115858062197f40b1b91bddc8db374aadd3248036e6107e12d416d5b45e4e0a87f5e7366446c84d16451d93f985e9dc5dbc64394b513bf93b560abd74eb79bac566cdfd7fb0fefe8da81f9fcb266991ede82bcc349e8bf7302175f6abc5a2416043252e160e04c232deba30f24f5b9cec79f61801c199db899468416c198e9adcb709034392d70076c5eaf585cfc1f102ca014081a18ae0a5e32bc6acca708a6c160c57acc3aa20169e2bf91ea91c10aa8a2a58b2d498c69fb5ee647cba92832fa4473bdb495e17f6bf2cdc42a82b2e2bc0f7aa8884b16f147021f23b06554a56a21f9b0d9f235bffb1a1a9edb2e3b012cc3777409541acf5b275561741ece824ac7d026f0c39ff21e284ecaadafa04c34bc72ec88c8082cc287295d9c217ef957de0e1bd90401db8dc3b7361777cd144deb06d680236367a2b055381d645d6330af6005ce078240fe72b7ca0c303286c50f68ac2a419106b6d863a9b97f5cd88fc70aad3b8cb8cad39af5f736e88bd98415ebd8574e562f1c614eacf50215e1c82a930f3e2e82df5a21da4bd7120bd320b8f2eb6cc6d542e995e34d900988f5a94954c33bbca43fb6ade09cc973c836d9230ee66a2c0b4831ad630f49691ee0a1cb1465ec1ae046407f225fa016553e46bfdc4ccf459105440ee49e7da5db84014e2ca337069a8998de3b3cc25aba6db94dac1530fd577f6846e09e4e1f5c9914d6b0c78bf7ff28e9881437cc0e00ac98277405a7e8066963a29156f6a41d2d6a9630c903da922c9d720ff8fba2adf52e117f595cc200ae9ef0e7b51966af7e78c5ca656c549b6d617b8ed4aa9127f7ae7d80630f5536ac75ad2b56300dc9e1bf14a71d6b7850c312c702bfae60d0a6d50f76e07a9e3f6347506f636b13d271468b01ac1605de2217f5f0beb2f2e85c26ab56e6a91a108275b0bf844c958b0af0222ae7ecac2b96ea4f56f9ae0aee3b7845a7dd181ee81575fc1f440eebe579d10078131b2379103566478b904b5f28680a5fc9f3684f84bd7eb99967a9f2278595f330bbc41d10f7088c540d0d19a93b65aabbee34b26f2d6002aa1dd673837adbca65866675b2a125a352fb68384298c38e825f986f052db5bfbd1216aa11855509527d20411442b376f6424aa518d081a9371b6cd032718b22a6f0cc6e9667db39525e5a671575a706e6e5e644bf8b3b158ce06bdd9593f11a0f1d641109c25c9c0ab03b9349633aa57318914c4702a53223eef1923db68cb1c5020d905c01d0dcd38433006ad5255116a3dc5aa7e084d8ab10d1f270d1c786724d6c8760784d109314249181fdeef836d59c79ae748aeb2fadf41ae298d92d0ddba53f1f1f1ff30ea125361a23578ad4b937caa11a384fafa1c4978c19b71ff2f3b609810971bc6be60c0fb31acc3ef21cde2b85fd21aff4958e738b981883b7f30dc7ce85aff73e4ba80d4759108954456b8601d3c93c4010b24ece63159ea22bb69f02b60db70af792a2fa220b1035cc745c6018a5e967edc1bcf2e9a2ead4ce3077810b6f5c2847b43b85511e3ef8dc4dcd31a6158fa8ab3ec035d8bd4f134eeab0bbe1fd52c5c141e06577af66599783ab038af045885f2aa6da28f48408f667f8ea5b59587b5c475a1b1e55262b217157993e50549d4927766119e674a733cbe8caba446bda7cef55a0364a41e1aaa69f965c139b829dc7427e62d36873d7e19081ee1ca699422c92bdf8288e340b8ca33a9a35c58a92263d3b5070c62ba0b6313ba837040f4639a22d34982149ed38fa1204117cc7af4c959e0650dbb161f97ec704463b16a1589a08c096da40464431affdb0d6c0ab84e554db7aea6cbc316ac951f79a8c9459daadaff17f543c9c4859d36334b7518c52e9e06dee6723a41f96840d2386d329eeb316709c1d95caddf882b8cfebf27ee199854b124e1adfcd81b3c1e5f4ccbfe23430cbf72b49bb05c7879ed1aeb2acb1bc7325b900938318c7104d8dd2057eb604426907a637ed7e19c6d7336d83d112b83f3aa5fc6ff0984ad06cc6b576f6ec62c38f37f7b5080ece2c62d3025205eec7ef77c2f5c618669f1e5bf20d792365e6c44d3983f83128179a89c7cce1f7f9add93c736c36eefabbd2f501d1d423199663227edc8b90efa5256ad8c8206dae862489644544aae2b5342f9a2f4b325477667b2fef471db6c1144b15fb04e1f41a87a43f14ba69515b4cab35d5ba326fe8ee6917f867b9bd4e50a8f2230b06c8bba75dfac5785815c846c533e0983e997aac1dc83ff73577f4740df9ca1fcc3bed13b611da3ed055b25b12780f32cbe708a56a79952bc6e3d23c99312246b90d38d3e3c6c2e3c55ff2f04ea1303ae45b3617988af9ecfa86c6808f1b6bdba20c4cfda71e6430c58fb6c0e9c82cc0d0a9a2e63bf8e93eece12a943eb702e748081e9b4d2e37fb920ccbfa6dde536d9f6dee7f7abf2c6c13b0effcd1dd4990a52cc3cc6687ca703675dd1cc074b308e7fa60d57076e56383d5e5f02e1bfe29592fa6ae0e8c90ffbd94e8757f89cbdb196d1502cc598368cba4989beb574a8ac3022354c30a9fcd6a560c9e53c4975fd7757d74334459df724a84d6706975a56094de3e9d39090389951b903fc16fe19e6f8c80716f7b9137f6911e40b5540f57c27a47c68f40475000231e8c613fbde599d0a08d9276c2f58fcb1df2f111428af03f2e9d7d1c942c4fa58c67eae69bd5e51400b097d544b6be51e8c28c66048315e3d5cdf79aebebdca54118d5f32f5e024144027a63c6f162cf51527d130c5a068c8a213318b7f40776de479df22dba62d764b5b57b88c7b864a62d088466307de16f7e2d36751ebc1e2c4d046d2d1b6fb46f14c592589eb6fc5ed105b73692674121b979988efaa673f93b32dfb4641ad085da16e1e3a2cd9a9abf9678d3c6db4ac74c51132a0bb1d858bd9f247c016bf870a2dcb824231408875fda4ef8fa2c52114c7ee586e213834540e622014d6acb682ffcc2cccbfd13571f1266051578669dbd9622319359d66d27f14042feec254952d3549d8b027bad35780315b0657360aa18ef18c10917a0a9937d276cee2e8a4495b1c2d7c6c3ac8a06a69f31324b026b0295fdb3474d5b3c1b606eb62d851a1e2d84fc3576f99a300016aa356b11baba1e0dfec87eb544743ba15c92ed5c3565706ca8b521e5ba8631070dc1d1d63b5307fd2e871acc1268f0da20719202ff0f99f7f0f53aff74b773676415e9b1455e749d291e126bd032798675fd4725a2cb877d0e83d9840c74cc6e93d4c0011ca01a4100e396ad83ad8ba3bf80d3e3a93b4048edd829678d3bf9060af91c49c06c5c92d5d4827b310cc21d75817f02cd8bf4515155f90812d30ee24f69743314677574515b5c0463fd3a49aadec3d61be3067e41755a76cfa96e44d4dce5990ec80cb998ace89e5c8c728af14cbbcad72ef6559e0d65100e879db9934b71c4856f53a49b490509c2984f8612793afe9f285d17338e80a47ce8392239a1c451025f70ff2390538b89a5c1fade36f54e28cb17391294919f780f945fd047b639787c588ff4e9913e77348fd09e8ffcdad96fc16f52f72967b50d2de81ef3037455bec94e6e6f36809804b7306776c639daea9a85fe120c60eb6019526d3493490f65d5c9f4d7260b6dff838b311e1240f849c44e40a8a082a86843461a033df32f2c5f10c13c642b22563f15e83696f71c875294cf5706c5fb10fc7feb9ac57a4bb033ae537d35b204c4a9b0e6569c85a1e4ddc8d48371519ad438a7623eaa621a57934518f2d867b65d6b2582daee8f78be9db3a1076d945cef90d7edc816074cd461f4a71171da3536e38517aa1a7c1bd18433e0d86f82da4eddd6defbdb79452ca5d0c400d950d3e6f5e740975cdbaf8fce0bafc74d1527e6a3d2009cdaad4805cec0431010a42e2484bebc5dc1bc82648c8c802f16f563d929511f2372dbabab4173f59e082b69c28d2dfb188b60555c1e566f563f5fb665d50fe7513f250516bee2322fa4d73376bb0ad185a31b482546188288bad5f42d1b7055b39ad9e18824b4b1f134254c2ef9ba5e2eb0df3d7c777909f766f3368eb9b762b2202cdca2ab38ab0ef25dc8bbffda6159d3d7c0ef45db384be2dc821118538dc02c2f466e122310516687ed3bcb7857a1f74a48505373f852a0e4cb418af5bb8f3ead14bcae8a814abffdc9b8a37472e4a513497545cc446bb40eaa97d282da791bedc219544bafa8f0a8b045ee1ca9aab9b46b33547ab2e54735724faebb5e63edf483aebdece68ebfb66fd75f24559ab8cfa0287c3e170385c08e6d09c035f0c94ecdae541b7d977c6212d0c43f4b34f038be70ebd04bdfcfc9d57443b507e46f78d0f511bdfb9bffd4380fb7dcf0cf913c1d26c212cf594481e99ad79953a532289efe7932c711903e641871ec2768ef7e03fb7ffa15faf52889a427a82c8311ebd3faf8e1f077f9fefc68f553cce589724974cebe1943c3ac4d9cf67b73b1e64d92b566a679633b618b63dc0284f3993415ba7953c3f7aca5717d1a77c89117f4acf522b83ac64a0d287082a673c08959a4a9e59115f10bd3ccd267b96a083e7be9f7d67ff9cc4e78be0f7dfb9af8a526646b495fa871565d00e43258d4b262ac310f2ad34a31495e411162579a445191b221a95f52af9ae9edd82f0b687ceeef80fbed6a3b21c23ba28431c2c5219b4c3952f26309e9030cca68a3fbbfd218005ff7bfc96f715c328b3123746592211934ad04ba6a0fcb47485f1028743ab63c4dde6aa458b8040de6bc3e826eef4bda86851c8b68635ac210882a07f3db0f2c4ad5fdcb4174317efed3b73e842cf81d0bfed1fa29846d31aac9ed1a334dabf3ec6f904b77b6f89b1115a6febad22997b6f0c245555adb5d65a6badb5561c36e24ad1d55e115b9ceb91bd169b35f2077ee1a7f1ecda9b74034caa3c2d74a9e88dfbefdaafe62f15fd7a908ab808a3903f10346b842888e2f88de398c7118fe3388e771ced388e63ddb99eb3d974d10f346b5cf3828bf3675e604bb3863541f333cd6c9a26bed634cdaac5518faf6bab6e6a7ad9d7eb553fd8ce318eaf175996668d7bab47d54d1396c1f0af63fd9a69dacb34807db234611606abb9b437566dbaea982607f60d017009dea233186d26c6625acbec27e1e0dc9a8c6adcb7d5235a53adc6fd593daaae5303415f746b2d3565b058f176496c9408ae180d92967034eecd4ffaa29a878746c3341a8d766d85c1768effd120968afefa6d7f8988e218414ae36a194e998473c63b7767c7eed411b64d2093e1e0e4e4cc664d3bb527043f112747cfececeaecd096684b3c97c77eb3593dd2d1d9d9e1e1b9d1683d3d311f1f5c9251ad4040f8da71c7a67b2abe9687a67b74896bad866bb55bb322cd6c227bcc1a3eb4ffb13f15f7f8d89f5bc340b9abc6fd1bf5a866f0d57b86e53d77c5caa01e55c7251989e8a8e26523cb7bae3022cb219308768b156916b2f29ebbac718d8c4a23f2351a1989a191ad3cb0d247cf4a5befcf4f2da82654ddab9baf4ef6ce1345672a542ccd48aad5665b3134444434a335dd6645452c74ac458b16b0162d5ab468f1657c5bd8da53339b6640b4594dac41b66c02f2201bbed1846c4dee33dab56fab3f43f1b5280ac27e0800fefdedc15f5488f4d3ac71ffdcfaaa5061eb07733f4fb309b5e605e58a3a7487ecd0a7c2244036c25d5bb1b862e887be2811d1ed5654c4a285db6824d228864848e08794f145b24848485506db3986cc26a2dbad286909572b8b92058b580bb3a9fc8c32bed6a88ab08de38988cc1a96bc990618c1772002dcad88450b23b3c6fd5a8f8ef0b5b51e552f329bc4ebf8a2b5bf7bf6778bb6d66a3d8b9f495cadb579cfc0d246ddba3316b4598dd455377f6b43f445599806b06f74a76817481e64fd30d1d769607bdab03a5ba4ea464797cce72e3fdf33a3d8baa88da02fba4b24dc8b180cb3a9c6b03144d8cef147f90343717c91a5098b69d9114ece4c678787d6e3f353030a12f21355615b3144742b62d1c2081f5d5b9182fea21b036f510838216bade5d72a02b25eb2d65a6beda006fe6c91acd7f879eb625d72496bd6c05fe33e07f64350ddf2e8d23d3615b0f315bd17a05ffebefce12f5f20d82ec1570ffa8a6e0c7c05edad6086596b6f40777e8ccb2aabf7265a74e7382f0dda7a07f9b768e27b4b6c7a366bd8372ff89c03fbe641149b4d1fca817d83f3f6e0e782dff96d8da4afb37b13af12ce68ae471fd8af393bd5bd4935b951301e3111b8d136b6641b94c1d1204bc4e0deec6bc6bd595ec525e5d86eb3269d7bab269947c7e78869dc11631c866088437c86a82649fbb9ce5967b9c4d556b0fcc8b004cdcf926399bd963d332c3d2f1d7fc57268268c06334d8f5d530d6e8b5b6f9af6edbe6f1bb797682ce1a01b67f418c750186aa2dfb967dc974ece399b5245659ef50a559e505010134035dfb8194035b4de22dd0d70aa8914ecace68c2ddc52122ee9b7d5cd48b28b8a9d1516b4d45bc344cd05f57a3d23c8a0a939a0ded501add15253a6f6e3fb9644d67ed07a8b2aaff2ec54af17c512d490277dd658121b9cd1cde877e525f9b03caa06c201d56a49fc18fdd45ba4857323029cb3ca8cb8fc86baed77e51971d9d8711a971c4bd1dc719db3feecac9ff3af276b8db465362f7839462f4fdb12aa9209355743894aa1d26bcd95636c24fdf3986fd14400e9a2d3b8d78afd604755c2f51642cdfda061b53acb542bd2ce327d20c7c37842af3527f3d07f646809f5196791b26b748bff64c2d09e2570389e1de7c3e39b66b348d849ecc383d65b647b18e7dcb5d7413e77199e3bf6dbeaac91cffe9df5a6b55366038c6edbe3711cc7711cc7711cc7711cc7711cc7711cc7711cc7711cc7711cc7711cb168e3e91609635ca3618c6bbfadce26264b831f1feffdfcf47a3e3ebd5e8f8bdeb6b7ad4e4bcd56199e1a0d9ce3a9b7c842ddf8aeba6050b3d2b470f4ad67b519361f1eda8f4ea3b550f125e70a638c4b1f2743d78e4d04947ebb91a10ce63c8ebd5a267be537b7dd7078ceb07e20c7c3ec558865e8be619045caf64ac7501ae65ddd5bc6bab7fbc4bb4f50ecd57dba4f3d3eeba9b7483c79f6ca066d2909c7d333e3e1e9e909122228485ba49186e65b346ef1a9b43133bad974199ccbb7a8ac5d6e64afd1b0d49beba191e4575a74973f3aad6ca1a2462dcabec31f259863cfa9b91ec75e2f2ecbb284f59c5697b33c5c9443d27765122b52e915e631c7a6024ab7569bc7ea62386e9964ae694c342c920df4deb255118d2d967bcb8e516ba54f5c6fd86967588bb065aaf8cace0fe44000d66e9178384723866627419a571a6aafb2e72b9cb33d5c943d6334db5e6d076d755769e39cf22e9fae5216af52f8f5b3e346cf5e9ef8142dd2e83430e8e1299e1de4dfb8f2756e1be563073fd06cfa5ce7b43f3bede79cf6abc539edcb4efbfab41fb36fda27edfb540bf47df4733c2e3a46cff1ac16892c1d9f1bc7934e0b63be5b6c15347e94b4efd88f5e6b8ec777ce8fa66fd88f5e5626dbb348d9471f3d8fe8b661f4a1eb30bbcf4e8719a5dd9b0ee7689edd2d137ef3e685bec763354773acb3e3aa84e3d8c39af3713c3a769f33ac45a3e39cb8de46979db51ef59ca387423f3a6d44f78def47c72602467474b4bcb78cbe3e6bbd6df2b1f39cb516edd863a791ddf62c935891b067a2c71e137aecb0d76374db3035ec34cf7db397e716c1dfc01f3a79ee325b2411c561fe7c7739d7fa3882acb67d9f1ef41ad9e2ac35fad14551747b6ea3174791c6c5dd72a45be748ab93d7e2961e74129be6a9c12d02fd737b7ebef556f7d662b3e9739cf4721ad79ed8bf93036c36c57cebaf9bf675fbd77dfb5ac5ebb1f3e7f398cf5c9f3f5976fe64f4670132375d03999b9edd4471c090510db4eba0384cd78e63e632cf91c2ce9f05c47ce63f1faa41cc673f1ac0dc74989b8e73fe7caee339d29cf3e7437f1690e338ae418ee3f8e738280e183e54031cd74171fc7cae7111e839521cc7f1f3a11d68a0e33bce809af2107111e833df4171e0d8f11d5407cd91e6788ed4ace9ec9673d614e7aca9ecaca93e6b1a3b73a4b033475a9e9bf6a0db8bde001d708623e8514435b8b70c666d34f69b331de499e8006e1148e3de40bf4ff4e719e4815e6d20ca81fb145ef108f1c918a9b3f7fa6ffd585b5d35650fd83155af32b82e8a9ad694b484f6f377edda2da0166107a32bc229cdf9bb5e6133837a84773cdd5bfd8dabbab75aedc5b0ab9b45a1abf7aca0abdf1834f62aa6f8695c5e0884d669eb4d28f5d04081ed495276eaa744516b1acd337abbb70e7a3d124dd7dfc09fef0d076c8dd52ef500e7a3862a1e47a8c0c3619db0814956ea81a52188375569b53136f8d6ad1367c04ca5624ef0822e253f304c9a22bc948c9d3ab4d15b8cb5d16f64527052d8eaa51e845ae59945ef4c3eb1a384def982fb6280fce0a578aac8d653ad328e2c09612bbde77dd29638ea1345cce8520f88f45b5bc29523572919dbc9b23fa4802295064037e429256f894f2bc5c30b4e2989afad382b398344554ac684c6e82dead03e2488524826ce2abdb310114ec24e113d85de59d64368081cb687901ca4521c1ec89670aaf1a4d27a29d8b7b7be6342ac4b6f114848ad0b171d78b5fc02480fbc948c65367a67120a718a29466ff127434d255195de1d9c46d8a564d797035010bd45924de53255a54befe39cb64c38ee94142698e8520f5e5fa052187e0c50cbbcf55ae62dd2972bba948c8950f4ce2fc6a0ed25a9ce48e19091e155e68c68268af04c96b18c11b90b9b714144e3842ce36334234378e6074e991e6740087110c93019cb44e19cf9209b717a911973660d4c099c32278468869067ce9489612433251cc28c4e2c53430e9a15341925f98c0d26192e386782d065b68466bc8848f81c09c9408166ce8867ae40abd10c980f4d8f98192be11929ca7811cd2891cfac5006cc2884c606bc4a395bf9e94ed5dedd81533d98dd39ded226c8d381bd114fe55de5e5a97a759fb62c2feb70efbbcabc7b05ea763c7c957b1f0fdcd9a99e6eeadb029f2ecf5e7d4fe0957dc2b96f07c3d75a6b73c618631fc771b4d6da529cfdadfd35fab3c7da9f81bc00202f0dfa96f8626c36651367f382ecd96cca68fdf087718da4c7582b3f59afb5166374976fad78f517e77bd1259eac38e75c7ece18573dce5586f59cdda2376c6dd7f51cd7f9b9680633c7f12eebf312b7c02f5f9f9d77ea52603de7bc5597878bacec94f9f8723287312dd3315849be463104a770ce56657dbc9d9f6497b481ac7b09976b0f43de7a046e4e5bc0ba8d9bab3ceb343078eb349d75c739a61d64e0e95062862dbad4faed955aaf5d5f4d5bbb1e0ce993c4a555a0db03afc2ed49a25eaf52be81ff7a154dd0d77116579cf5ac16c9bd5ea50c8a3324fafaa967444367bdb9c8af67507c95344f415f17aa79d1adde2c0279bd4a2dfc7a06c55709d3b3bf6e33a2d2d7836e462d5814d59bc572f47a958efc7a06c55709d33833da5fc72dbda0afd792968e8c5ab0a8378ba5f6f17a9590fc7a06c55709d338b31d9a8dda5f9f310021fafa0f8d0120b938326a516f164b3d7be1d73328be4a98c699edd07c6a37bebf8e410647f4f59e0364f00287e4e2c8a8de2c967a46e3f17a9562f8f50c8aaf12a671663b349f5a905fd7200241f4759a03221003c60b1c928ba37ab358ea19ad76865eaf12057e3d83e2ab84699cd90ecda716e4a8edf6d737d080127d7dc7021aa02029068c17382417f566b1d4335acdef39cbb93832526a41018ba4a2183718442f86702b906c36ee0ddfb837ace3811b39250a9262c0788143aa378ba59ed16a6ebb275801928ba325a35c0b2516141425dd6210c1187ab10267f37b5d04ba26fa7a8e57b3060e5d054b39250a9262c07881ab378ba59ed16a6ebbc9bc5e2526bf9e41f155c234ce6c87e6530b72d436746361e40297c4c3470cfa3a8e930f2619152ce59428488a01e345bd592cf58c5673dbcde89e00f0eb19145f254ce3cc76683eb520476d433716462e703092969ea060d0d7f5102800cc609251c1524e8982a41830eacd62a967b49adb6e4638b3bc27cceb55b2c0af67507c95308d33dba1f9d4821cb50ddd5818b9c0c148525a9a119544067d3db64b6241000030834946054b39250a9262d49bc552cf6835b7dd8c7049f77cbf9e41f155c234ce6c87e6530b72d436746361e4020723496949c68c1ba0d4d40afabad964ea6958100000cc609251c1524e8982a418305ee0905c1c19b5605174231a5a6143cb7b0ac0af67cb94e4d741cb14c3af8b9609865f7f59a6d4af9796e9855f8759a6f7ebda32e1fc3a8e65a2e1d7679609c9afef58260bfc3acd32b9f0eb3e9629007ebd66998efc7a906502805f77cb64e4d751cb34c3afdb2c530bbf3e649998fcfacd32b1f0eb2c2c930cbf6e64998afcba0bcb54815fc759a69b5f87619996fc7a926522f2eb4a9629e7d7972cd3905f97619994fcfa0ccbb4c2af07c03251e0d76958269ba5baa74f94be356c156aa708e04cc1bffeafbf4e03f6d72dc0f9eb01d8f9eb00f0f9eb3382fe3a13fad7650cfdf50a58fcf525177f3d07e3af2b29fd750ace6a91b68cbf9e74568b743dc6792dd2751867b648d75f9ca245ba8e3b4b8b741de9d416e9ba8b736691ae1f9d348b74dde8ac59a4eb2d4eb748d7599c368b74bde8bc59a4ebb7d3c8225d273a7116e9fad0996491aeaf38972cd275db39c3225d2a1aebecc53832988af346feebe8e9a7d01974029db5f3e7dc3376c5b2abd563a761e7397715f3d8774e9d7357358f7d76eecaf5d873308fc72e3bb7f5f1d8f5193bb78d7aecb073db248fdd3ccb735baab753bef268380c361001cee5d44ae15c4ef56b44f752e589e8ae57352bc420baadcee943b785da6574db295bf5d8df1a599135337ad3bee646b8ab847f30fa559ea59a5279336e8052533396664425594a5a7a824ac2253df62f3b68847bec9fd1cd480dd7cd76eb69d9dc860d4b0c58fb40daacbc38dba83df64f033411dcf0c00c475bb23113c10d6db33133f280164149bb91fd46b9717cf938679ff349578b847d8be5cdd5d42784708a2d25903085ae8717352510117eb50732388ce912c4051282209115e69081d72386ac333a22241ce1252c011128d4c0c584294af092664bf8840b574ee083102e1f2768e120d38da03ba1491256824033259c80133444818035c58820cecc109aa0cd1340bcf940c90d55cc3819ba0a13840a6d94d47082324c3c18a306092134b4095302191680382289102098b9210d162354e0208a287e2051831211ae1491c2f77ddff77df58a13595db6a420458931bd20e80b1282d8f0f402991344208284f033cd0891a5a3049e8e26d23cc4e7127a7cceeeb7abf47ddf057a14896255e487ad11c6bcc981e9f7c1bef2802893132409149128165a5882462b3bd1c2536865245a4bb4866811d1ca45b4f0105a369c3f3014c717599a3272776f37c9bd5d276153f776a9eeedfacd57e92a5da57a95ae52bd4a96eae62c8f3745eae6ecd454b5bb5d92a79bb34f4f96c7cd599dcefaf8ea22b8390fd8b8b90d947a5c5f7d833bf35a97d06abe337af59b118f57c7252dd1bcfa8cab642ac1bcfa007abc3a0607c8c0c7ab6be080085ca5254e9efe78f59f2278158bb556349b6c93aca91b60b8cbb29b013211f3b4f419b9929461c0dac2e117ae7a46d76cca41ed550afa478bdef6ca8a59e2e469cd73fcbac5ba01a85da59cab94e3d76b39388d2ec5253f3f3229f4ec5ce2e3398d0f49c6a2746d498fe7343d262642dbfcdeee121acd34c99c451b2de1e11983e824dcbddd253bbe63863df48ca57bbb4b7496febace87b7f400ee9299e734da62dd227b756fd7730b1a837bbb9e465b191220b09e82af3c20a29e8cfd344086c3c608596276a9cc6b7aa5eece5c404d655ecd05dc5486ea0ba2a065cc4e8b18aa1f231ef49002892198f86063450c1018728200c2abf22901f1c2e585228c40e31466cdd83543ce194957948f1a6648a28627217ed8906f789203c8981c80a0d2040f3acc0026081f6fc2207e8040e583820f614029524723a465e9ab5dad6e8f5bda00575a57ddaa3b874e14d19d6347e3310284fe43b13f4675d809692bc63bfb5773ae18638c6eec1f8a2d768b51119bf12763d65a6badd5daeada005b895759342ec637dc92dbbb4bb1975729fba4a0eb571a37973f2760ce19dd9f874e7edf9773fef2f77d9f8bf9dc95778a637df988e67bab34b1ee172abae39cddd1b2aa156d49e3ae886efdb2ec2097204714f1206a7bb6cc55027368367d4c501122cd6fcbcb4df9bfd3fe0b225c31e2b7dde51d50570682d9e7339b3218fa7590891e65d0fcb6f7011f9cd83f27b3d9f4e126bbf572aa392ecb91c95ce6158699e7380e1c9fe5a01e5c29a63ce1a03a1cc741af0e17d92e5c64f5059900b184807db061041f9cf8d064874f903c7ee5f9f0f47921ab6d83bcb7d5b1e8bef2aef06aef2b0f87153e3f551956ab1e5906dcf442e1a211f4ce4f6015ce7d5074ed74dabfa92a9c9351648b148f87733952eb9fd5778573301d7cd8f2a44bad7f5938b7012ecaca3d9c6bf1c313434ce952eb590be7725479f3e6cd1b2bbef207e22cabd1fdf5defa063897b770917574572dd4b4254aa2dfeeedd3db4f2a4fe5aa9ef54feb09e7729a58c2422fb59ea1b670ce3a815579f76d655e9109469e9cde7e4f34fb41bdfd2eba7317a8ed2786ac968903fb1d84808310fc1af56b3db24cf5abd71564b56dbc55ad16abef8d096d7d6b7bf1ed8729460b153d543867c99f0e4e4e6f26f9c01cb41330ac584211872c16e49088664988e37805a7e3647c895680bebcc8320baef270608ad14205f8611ef766734296592cd83433486966090096f16f997bebf162c24e007cf51ff79910b0d80c724b4c972bfca631415928da105a2643eb9d37329c0a8094c0c9917a5a3d9a4de5cc723c23cc7494b6e8ec7ca1e025c40ecf0f49578e858796f318ee413c5aed19abff70095584e0e7617a024f5a7fdd678773396a7803b5440a13da30712487df3e5c9ae8fd20c148942474e9f6c1f2dba792397383086f8cd031e44dba7d70f8ed63a5c46f9f2b1f2c2d3e44b444fddd3eaf2b9fd795cfabd7f3eaf9bc7a3e3d3c9cb33991850c0f4c7c6872c495df3d25b061099b10ac38a10211e9eeb1f2bba7891d9a10f245ca153247d2ddc3fbdda375e677cf16d70b494f941792297f774fd54baaa7c94baa87ea55d5b3fbdb23f5d7693d9cab5746b6ac382199e2cd90b4ca6f9ad65f29765052f5419a3457e9a6ddf09be6e2062468b2a42cb1cb92ee1e2abf7b9c9e86fcf5dd03d513b5040dcc123431fe9b96d545ebd245c37a39d1aa5e4e34decbc9eaafd3743857a580e255094105104a3062ca6f9a5391d490ac1c74d0ea6242ba694f527ed3a0aad090c58b0b6894880122dd341b7ed3a4fefaa64dfdfd4d1bc1f08c607878d4f070fddd3c5dbdde5f1eadbfceb3c3b96a35441026a0f8e0893354d228bf79a4feeea4b2d2a4f0c31133e9e699aafacd531535044b08266868d811916e9e1a7ef3585d61fdf5cd93c5236664c243e49944fddd3c50533c3ea67886f0ba783c3a1ea7bfbec3c3b9edc48ea9a822524cb540c3ef9d094031460910281cdc2c49f7ce0cbf77ca1c4105c994a91a76a090ee1daadf3b5a7f7def6ced70b5d989d266cadfbd5335ea769a8cba1daaf169076a7cdad98d3b527f5da787732ba24822a48d14179b23a0fcd691009728322d0041c20e27a45b4786df3a5d1948212545083abce1724af7ce93df3b4e7f7def3ced0cd1a203468b98bf5b27eb4aa7cb950e564fa7aaa7c3d3b1faeb3a3a9c2362d3c49724d448c98a4aa77eeb0899a201092c4f5c31a12add3a4e7eeb4021400d1537663e6063048574ebc4f05b47eaaf6f9d291d2a91481b91889bbf7bd625eed4883baea959d6546f4aebafcf76385787f0f1440813c61899c22385e1f74c2acbc9c9852d4e4ca124ddb326bf670228a2862a40a208614c0ee99ebdf07b66f5d7f7ec6a86956646244dd4df3d0bb766e1d64cd4e588ba99a89be5d0c0820845ac10a5072e5f5cf89df332b264ca1a2e19485022dd394c7ee7f040a50405ae3146207993ee1ca9df395a7f7de76ce57069c989a225674a4e931caa9edf39555739505739bb1c29adae9c9d43fb9d133ec1099fe0e0e0d07ee3845538210e1627281ca9bfbe71a672af74e3508541da8441dca8e1e2f92deb0aa1645921542f84d29221ca191f3e64d8c1ab926ed992dfb22aabbfbe6557322c7009191170095994cc876cc8ce6f19545757974cd7e56495a5b7d65c5674142b53feea2ad04a37b1a2cad250597a9725f5d7633d9cab65821882ca961dba9a3ca5b685df312d28944cd165b1c1865dba634a7ec77688b082113b62d0b9a9926e9de4b776faeb5b3f6910490c44128bc5b0fec6b2c0581518e38131abbf1ed3e1dc986508104ce0a16b8824290bbf634e3574545cbe484121871ee98e9de077ac2e2143171790eca6d44049770cc9ef98d45fdfb1a918d5126d9670f317d6f575c1d47c5d5ca0130c7482814e30d80ee7162085cb0f2976f84164f71b56c14441452607246d8c18936ed80abf613ca826ac4ee044854c0ee9861df90ddb3018961518112b517f619f15ecb3827d59e69705fbb260260fe7727c70240c12416cd9c1c41babc26f33688a561b116490a2254cba4d1bf5dbbcfab1e48413aeb658e121dda635f2dbdca6c985c48c8264ca5fb3c95f73eaaf592565424999bb6d4afdf5b287739509146890f232246a2b4d5ae477a95501178e58f9a1042740504977b9f596c8efb28b053655a474ecca2c916e13eab7e9f4d7b7f9640ef97494603e1da598b24b89f5b7ccfa9ccaaacfa9e4edd2eaaf973a9c3b40126b9ca0e1618db92185dfa5539625b4788152c24b0c26a4bb44e17749d543af0c9621b8146193eef284dfa5d45fdfe554ceef92ca0bd9c68b9bbf6457ce22d5e42c2e2d324baba7a5f5d7c91dcee500f2e508167638e10986ad21bfc91ac4944eca0a503790c025dda409bfc9aa024001b36608992b4c82a49b14f29bb4faeb9bbc22b19e90449e9051a40f72c85f12aaaaab8ad46d9287733c49daa059e2e4c7961382fc7e591d200c1145b4803ca52993eed7d5d3ef57d60d26f8b801ca171d2944a5fbd5d3faebfbb5f5e2ca415e517290d794579317d5df57557e41e5d72ebf7a38577b505d4a1429e28d115da92de1f7a895801d2660713a8344d491748f5b16c8ef71851b98b4b015458519a8a4fbf5e3f7cbe9afefd7d36b081ec1e0514cf97bccc263173c62e1b10a8f3c3c5afdf551877320b841480c63c490b01322f5f17b749a8185146a006303971ee91e9f9e84df23d411dd0c312c41262b041de91e7723fc1ea5fefa1ea7462a6c456c83ad886e443522d75fb1cb4accb2ea59ed706e5cd2c4901e42662823432ac26f512a07942f49a69440e5871ebea45b9c72fa2d3ae143161eae7a38d1a149ba45de87f05bb4faeb5bbc12b1701091080e2246bd7e8b50184af4210ec1525d584ad461291ece6de089335474d0d1c2134a52107e873b4c6d21c14b218a3031a43bbcfa1ebfc3ac0d58e04161450b0f880ee90e7b3c7e875a7f7d875b215711619422c229e3efb04a2b6ca215527585505de12e94faeb600fe7ea159e0e2d4360d5d0c312e98edfa09690962c3fd610c9024256bac1ad0f7e835d7fa5da8809a31b42058974873a1dbf43a7bfbec3a7bfe1102d20182d62c474835db0fe825957e0942b100be85402160d52449460f2258874834f7f75bf412850eaaf6f702a074b37487589b4b944dcfcfdbaee4ecddd714d7d5953bd292da9bf417a28618286aa89287a48f737f56f7e7f559fd55fdfdf15ceef0f2bcd47244dd4df0f6aebf3f1776bc85fcf5d9fee86a9526303902e42ac4e904ef13b5bfded42a5851f94b8e92125ddf94a8adf994b0a2c418ad4b0860990746737bfb3d65fdf794bfc9db9bce4285ea6fcddb949aecacabb9da57232fc7802ca8e24ba256914bfb156d5902436403142e40459e9c650fcc65d5d57968082c85615978f74e736bfb3d3d390bfbe3354f83b473dc1609e88d9b88badc245559867b10ee7aa559b34407a3abef850a4eb3776c25039e81842ca933527004937de3df11b4bfdf5df98eaaf8e3656879bbf4eb8488d13d743e1a2acbbc3b95a86479612c82c59410a98d489df57aaea5a31b9bf2fd6022e91ea25eaefbe500ef0f1376bc83bfdf59c0670975205f5667ddb285fc194bf396618a2ebc70a3c64f8b2246de2b7b55a00102427f43802831b2ce9b63daeff6db9feda24346e91f56da3fefa03aad2586fd62ffe3d8af96b9b84e9b643ec1313bfad53056c8c10420424b844e892b27927217e408982cc942d4b6cd9f284e50b1a273a1de9016e4e57b4c7922f639e44118509e9c5b9ba0686105ad0a1c908315c49ef9aaf00981e11212c99024c557a95f8eb38f0affb127acb9ce82dd3e9abb76e6ba2b7eebd75f3047aebdd5b3791e8ada7deba6ea2776cebadeb17f4d6bab74e1ad13b76f5d663af58158faaf382de31a7b7aee382de315b0c7ac3786fdd0683deb0abb76e96a037ece9ad9b3ff48675d1dbecbdf59e2d7a9b5b597a9b5ff436796f9dcca2b7f9f4d66961f42e7b6f9d2684dee5d65bdf71a37739f5d677a0d0bbe4bd7520357a97bab70e8484dee5d35bcf50e84d3ad19b9c7aebb318f426796f9d4704bd49dd5be771d29b7c7aeb2f2bbd5f576ffd9545ef57efadbfb2f47e49bdf557958be8abeaad874588553fbcb8e2458f994da2f3f41ebbdeba57d1fbe5f4d6c75e888ebdb7be0208cee5d4ba4cea2ad5add00a0a940f6d1f3acc6c0a5d08bdc7a9b7ee60f41e796f7db645ef51f7d6675af41e9fdebab6416ff1eaadeb287a8bbdb73ea3a2b7389ba2b7b844efb005bd45dd5b171241eff0eaad8342e81d5ab10e6ee90d5abd75708dde60d65b9711a13728f5d6750f7a7f5d6f5df3a037e8f4d683b4e8fd59bdf5202bbdbfac87f2200882a283601623511ff27ce8a6d9149679d14bb34924cd269066a57768934aef9cf5d64d287a67adb74e12d13b57bd75b288de19eaadc79eacc780e88dbbdefa8bca7ac983de7807bd7110ebe293deb7ebadf7e460bd078bde77eaad0745e96db7de7a5011bdafee15c03583171d4800697325cd497cbe62e4c7679f65bfe1ec349d4ea77b4ab3111fb6f8d05f665398035daca3d9048a6653b6593827d3c9743624f496e9defa96eddeba6c274b72a5080f9539c9745f14fd5f0ef779fd7e979f7fcf3e7b95faecf92ac5f88c6585309fb1ec867c76d06ccab52a7d0f66b3e92ba5d0af2dfd5aa34b157419a5ad1859e13176db8d56b352a489ff3c5f2516ff55a50a840b9fadd98471ff15a1bf5ed1ee65bc1144e9a4e82d9e59e449e1b42a9538691e4b5f29320196b2b09489e505c58ac345d8afc61883a8888b70d5bde1f034deb6eab1ae1be7a2a979accbdcaab13cb5bcca9205b2e441014b59cac298a5e804acdc71428c953b49e81268069aac9465d1db5e5d5d5d5d5d5de1943b5b39a598c4ac14d55ce9944e75b553024599c18856caa674f5945a47f629655bc49f12a8aa572b3f1ab4804a5993a0527fd02554025df172674ded2c3f1d325a962da8284536b652e45a51c246182a452432515926b9955f1ad16e5c510964456f7b7525b228c5234a71a66b34bfb528714cd6f78b5c6599ac0d6f947345dc339e342a7b6a4eac4538173a765c95f1557f5199b2579ede9465caa82da22255e15c88da2b32323c268fca9b9a6faf663a92aed2b6568f1dbb6851ab12682eca0f8af592442a3f5114af704e0cfa7c75f86660448ab637e79c69554697067ffb571df40e1f7c38572cd2ea598de09716c1ec9f69dc100cbf0fbdf13d08826808becf68c6e126a4675c7e58c962d046ed267e9e453dea10c5a9a0ad6f1c4ec4b966d3222449ad5e95212b0d0dbaeb99d6355ba6cf33ba6fe01b2d63dabde1330404b83a5b8fb2676c367dd93400f9e6cd6f1c3add67b483d16f885f91b2571c21b83f82f8419403fc23fadf35b5b4f52dea19cdde1bf8b3df376f42803d3f652c6af03fd75ba4812e82a7067d8b354a54d3b2e72ca2f8f6998681116d7d572b119b4d1f885ad3003a2e00e1c20f016e463b80d3ad21abb5b5625a5355aa32aad7db757d6f5729a7deae5f1ae700ead1f59c8c36d5db1dc0bdbdbea216fca0d19bf6167ccd6d94d72da8325e7fbd8a4f1863a85b84c590062ec24966b5f681f6dcb6123bbe50160a63df007f7e4f31f41c8ae199dfa2153c71a8d634dadeb8c7f5fac65d259427de0f8d756b64abaa76aa4a5dd036a1592a5e2d4700639d2a5230377d8ba55b290fe01c0c45f57d6dcf8ecfd0471bb6a610b551e69fe5b4786934f75bb652958751297b355e9007d1f6642cbbce4fe801dc9cbeb8a58d2b1f04cffab9ad36fb8c73b6fd2dd7a2ecb5cf5b97b6c74ed06c7dfd1aab36cf15004e9ec67cebbc132e8df9e629ddab87d64df00b40ccab93d6afd9047a788a2f7a782e8179ec7412d3d1699c03b8b7ebaf13832ae6e9e7cde8c49d49df396346ebd23fe2579ef884f6df3acb0d51e0d31880d72bf2662ad2b595b69fff88fee342fe23a2190079cd831cfb2549bb23f393e8a4488aa4e8a26f27495288f42092249d244992244992244992c4c9f199a9cb4c9224e943923d64a9494d239dd42167a4e79038a4cb48922449922449922449922435192361a4499664261de8ac9782ecb553c445d97f4e1b2996f072cd45d77f81fe73ddc783fce7a219d4fcc7813c3bf6d1c5fcf432dd6a6151d4bae2a0f3ea70d1cb814edb858b5eaf97bf5e4ee3be5e2ff7e979bd5eafd7ebf57ac972665eea382cc6f3bd5eaf57cfeb4543b7c8836ebdf3d241b7d5fd6bf6ca7939ce4bf6728d6e0bf5afd7ebf57abd5eafd7ebf57abd5e31747f4e30747f4f26fa2a5f24ba3fddbf72d7bfbc76d64bc1e73fa7888b3ef739352efabcda5e2807409ebe2110a4f56ab356c7c32d6ab1b5d8626bb17f19049d043ff0033ff0fbec67cfcff3c901fe2e309f568faef730a9ba53ae9276faeaf9c4dddb122eba8e4bbab71b8446df2a7cabee5548020f540f3ae8a15fbbc4741a97667b9eaaf4005586ace71c6b9175515753ac47d663e7cf75d26d0a3b7fae979ed30bf07360dffc580527bebe66b1a184c7eddb8f6118e210dda367979db11376bedc9a178c2e827ecfcfc76b36ddd0ab79033f017aba9ca17af0a2366e0fba350dd0d3e50c9407d1254e9e9a68d22db2e29b674dabf9a138f14737554afe2ee14e1af5c8fad882f6df22f9354b95247fd1adafeeadbe58af5e170c81b426a8faec3f4cf4b6bb7dadfe7abd17ad36eee9817babb5d6ef73d2def2dbb9da8b737514f475a1223014185bae9ca1d8fc7dd94eb1903f300cc12fc3903f300ca33e10fcb21afb81e0976308c2e6efcb762a7f6018825f7efa2167305ac6e49c79743927f18484fc8161087e590b981cacad923f10fcb2182e536e905a22e74ce6ea03c12f73d1d223e74c43fec03004bf1c953f300cc12f47e50f0c43f0cb4168f8c1bafd40f0cb27a86073b64ba6c879899c57e821e76c06e37b31d8f5808688b77e1b418a2b34a001b3c3e38a4081bcf8e6308761ce91befda56bae1cbdba5895aa522ed14aa215fbdf1d7ef5af32cdb048d7ab93e1f9d5b1de3e7386e863eafce775dfdf33c07afb5e21787cebedcbe07f2478ec7914abcfc6797df55bb357276b48d3222a81c704705b2d8665d4deffdc667cc1effb2c0c58ad479fe31ce22d8390a4bd49f2ae3c2da8bf713f06f2050c9cc2ccfa47adf94a5951b5028be8cb9010222e2229a2158874ecb819290a43a464851344552c3e2822f2e4c663280a16405a90c04209d18e1622ecc06237a445f401113a2f5c3d845022081e0c584154f0a10513ed8344914ec3c614d9a071b89c408b3810e1a0c32945635644515a714249eca981826c9321493497c49001c68b3cdbc2e9c8806481b25c581b9423738891d8f3a5c52c0c0b7287a24c2be2b68308686b684665137980a8105f3ba0e26bcce9563c07e1201494673d00e92a353bbbf2d3c4070cc393412674b20ccd2c6bac9c1cc4038e48e341766b7c195f70ef05f7332fb8f55e6dda10dbc132b93373ec84b22a7dd96dce8ef3bd5d8b5ed4de7b2f112f116a24a9883d59c22024a0f87ae10381b0f98dd0d6efcd366808f26b42c3a277feac944ffa5665dc6a9dc80e38b06ffefa0df1b3571bf9bda0770622a37307e1df10ffe702ac538fac59c3fc8a8af588a719503fbf0ec8e987e2f020e7f0cd14babfe8ce135a3c33ce395f8b03db1efc7dbf5d5cc415875f79686cb8d7f2b2a665dc17ed5ec67b7b86042f5b9248abdb31da46f13194e0a1c3951f8e20a24c5a2b88820b550e3bd82401c142f1d66553aa8cfc96039f4f5da56fcf40073cf67beedb5f7c4fd4c6edb17f32a90f95ed6449eecd7acf11bd653b190f99d355cabd951129222223521455e4a368c8df5d0425dbdd64bb22d9aee8c6c3b91a4c52d0b1c044162042dafcbe59d00684221f38a10b018874dfba7edf96d270e95a808147096fd27d7be2f74debafefdbd64db7b9e936b7db8deaef6ddfa0feeefeea9bd45f27eae15c8e11ca08e11df18147922652277e1369fddd41260a0626929cc9926ea2267e137101e20305365c88981242ba6f5cbf6f4e7f7ddf9e6e43b41081d122e6ef26cad257445df4151196ee1155e91e114ff788acfe3a910ee7aa9a214852c0c1c81a18aa30f19bc8490a0612945c45e124dd444fcfe6371114971f393061e20b5710e926da1149fdf54d3445fe26a2d244da68226efeee21bd1bd2bb213d35a4a786f4d4d0d00ee7f609bcbc312187373a6459e2f7d00b3a2755218871626647ba87b67e0f518006303a6489a2030d27a47b68cdef21abbfbe87ae62bf87b0d20c1149331405e3f710d4d6908fd8d690bfbea24beb86747ac8e9afafe0e15c03c20061c6092423bc014289df2bac9ae84a82ca981c88689921dd2bae92f8bd220b4b6bab0d4f47e449ba57a8f9bd62af58c1a56545142d2ba6ac68b282eaef5e51155b115b115b21f5d76d3d9cc340cc112c167ab0c10d9a1489df362d105c684184351fc80025ddb6237edb7a1f6831028a1e5a745049f70add0aa7bfbe573cc17eaf18127b6203137b621363eb62c3fabb6d595536dedf6db3faeb361dcee588caa18525588c14699225cd6f1b9a188ee872e689d319a874dbb47edbb0b4c023ca09549e5449b70dcd6f9bd414d55fdfb62adb94980e156d623adcfcdd2aba624e2ad43871fd85c2453128adbfae628773357448783494800505efcc6f1552434dfc80626a0a4c1050d2ad62cacc6f1555171082e68a8b10639a48926e15bc32bf555805f15bc595fead020b96460511581a15512a7ca818f277ab80826da16e605b2a78fc75948773475a469280b0638a2921647ea35a47a889828d151d2a40916ef4ca88df6856932294e8a1890f51a8a41bed15f11bd5bafa8d6ea51be5824541a3c0a2a0538e7ea355301eda8447054361280c95faeb670fe76a9b1d08563d429042e607dbfb7d563160a80851040952b89192eed312f1fbb422021b2082d8d1852724dde810bf51a7bfbed12774084c84130c4c04317ff7097b3a614f276c77c276276c779e3b40f1c16e2a4a93273ec6fc3e3da0c5083233f08010c142ba4f31bfcf18d63cb952c1071a76a090ee73f7617e9f527f7d9f53e6ef930a4c1b306efe6eefeaa9e9716d79d6566f4bebaffb0ee754b8e131f1810213bb35a910bf7d04a7204ea08a820c9523e97630bfbd4a032b5ba8a0b0830c4d9049b767fd76abbfbefdcab198381126517fdda1cc29f7313584d7c5731dcfe9af0bf1702ec71122d0a4e08305166ab0f2e5b7908c1dce7039c1c525cc07e9160ae2b75056069c78a932844d1125b449b71010bf85b690902982902982909010d5df2d54650a4199423b5348eaaf07f5700e035d636e6842c9921f74c0fa1d54a138320213676ec04ac2857407fdf03b288745489a10aa70c16221dd423efc1672faeb5be849680898203060c4fcdd4159bda02ebd20acada0aaad20de0eb2faeb413a9c8bc0162740b0a10ae10b0ea997df414e2190828411509cb070440de90ebafa1d046505c5ca4aea863160d21dd4c3ef20a9bfbe83a682a84a266d4a266efe6ea0ae2935535c3ca02c5e8fa7f5d781763817aa41c24409251f9c8025e5e13790140792f0c035029b2e1ba64837d00ebf81a480a1ca13504988d8ca4a375097df401b0808ab0d109136517f37105409e4a3041a52d6ba4a205d09e4f4d76b3c9c7b00970f7690f24215ac255c7ed774a60c3145550a2a84a14a776dcbef5a16053c1c4cb08107066b8a74d7b4fcae69fdf55ddbaa7191b528646d4aad09d5df5dabead5a07ab55d4f4aeba7abe6f4d777ede96f6d08c9e4070cc944ccdf1f72ea879cfa21793f24ef87e4fdfce8702ec79414ab16744873830b4c58fdfe410ae2861b868042450712e9fec9f2fba7eaf0640bcb0a63acae9449f78f0ebf7fa4fefafe99027fff50b569d3c6cddfedd345ea7cd4903a1f2ef2c9278b7cf2e99101a022a814091a0f7349a714325323c00040002317003028180c8a06a328c9b144f90114000e63b65260521e0824f220857110648c210a004000008000008001a588ca00984ddc1a451fbaf9cfb961c8ff7b3289e65cadbdd42222f66c6dd6ab7c1bdf1cf354aef12ef285df769b694d6dc1a333d0b5a3f8c7961c74a0d18c4e3dd24813a7e9f27ff25e9a1dd91c9326343a600a343ef5146b088a2bb11db8e2bd1fc26e9e0acd637d1d476173dfddbcad8b587b7267872f7993e8e7dacf52614b1bdeaafcd3e9be3aa9665dfd2e71d8f38ead7514b0b51baa7d7eab015f23ca901cc98c0413bace4278363584745700bc2f7ca205439e90da644d1af0b2c967765d8da3d3df290edd2f9cf2f48b3bdca118d5d6219b6ae8b4c33159f190f0ad12d23661796dbf0d3d46d64c6096ca0565c41bc82e53925b09e0195e730346a1c0642ac0762c782667a657bd58983e3a8369db82fc14df4c805591c5fbe8a63c420b9f468bce76a6f6e011d37547d5725005fadc4e0fd345637e8e0cb18c4ae6dd1061371328c52b1243f80e949c444a63ba5761a8afe2977ec36594747496e8fef731c433c3eeb1d0d4fcc9fdf6b11859b24e1a25930c61d914d4faba54e98d5ed4fa360a3d63e77d8aa7829e273a89c921b8aed9487bb9631e24bb547289d42e9521f2525d787d157d6f87f49345f26d501e97472c6e0d1eab884ca5d0a58fd4dbf8f3918233d097deff66b59aafda223d13c89e77d3a2ef63da73678d9de076508298328aa1c0f6c8bbaeae0dcca05c424cec1a375b4140a5c3e1a600280a39219be2449bdc19889004b31d38a7abb8d11953520f59b045ae700a7da6a498aed89686f7e93aead269de6e7c31b9abd054b762f40cb42cda90661a5b4a99290828a69def47260d649b6b29dd69b987a21275aada3f4c3616e554ad56832442805a962a68854d48274f4a9379ea14136e4c3e8b34d6377e003f991b3b73e4954f2920b0a5cbaf78b2852ccc7d6f7bc11981e052475c585592380b8d49ed07aad0b6b4f3aee88367545be5f15a2636cf5a225089fc7fc859ff7d41bfda5379385a2293bc6a1e9bc464b9b2a059484323829b897417ddd929969b47ad0a1ddf0339df0f15388d7c1e88a801cce4e69b09988e7b99428bbb2bc51bb64ddf4f022d57f4feb932ef720745e33c403818245b4f786ec3445ff9b020a71299336c04ddadb0b968f1081b6981a7b05a70276f8a3e2475ec520972156ecb28d02b08c266e1ea436434c9b06eb243fd122bf46219028429b3c013b9b6746ab970370f957df6fd2f64f4edc25d7a53f220339b5337a1c145c448f46f9d2f638b9a1288abfe40a3ca171740f87c1da80fc6349a5cb97f64094a383086c0dcae24701e8b0e17ccc5c07accae4233dad06aa3f31c706e046b7e50e7e9012e270c941886884026fa8dd0cb94b8dfd96a9bb854b39853bb78b30b30d209e810e5f256e703a6a041dee10f28cc625cc31ed8dc3520c2f8593c4632196fd7a2a8d9a0739414c4692c11b771f94e059c92aab39bd05bd24ec8189dccbd68b43e246ae26b2169b03bf141a60d200e280b6e6826703a008e9eddaebb7c5c3e5aa63cd390c8884e9e5f203755dec2f9bcaf695e54d5990806af7b6795acc3450fbb5534e322068ed64018e2f83ed9ef25705b193f2eb28fc91190b3c4685e17053dbe12eaaad9e4b683e9e35b32dfa544f1e87e301a1c4a6a5519be059303174506af9813a142da9596c9f9be4025a77ffb80d9de20e5db07286065345dd331684fa9dc4c352704695315322e616356d685f5aa05b043aefcd8882a949190870984a2a0ac1711d1f32bbe380a5169c09fdb553805cb7839203d0e961b5c3b6712d736b0178dc0c8fdc3604458418ef59a1495ec17edbdb0fd93e482a505b98e645884c80cfccaa2ebcc151a4a59593d76476620572e0288eda5954c755846875d40ac7c68114296488107a4231b80358a59fa70b383f0d36f684a5119885bea4c36415da8f7e8e4b551d995b449472234e3e14f58c2e75bbb060e558b7014abdce08fc5bc86dd8d83d18df260375ab882fcb42866eaec9ad651cf204ef9790048beef049781281b24a0b6aa0af03f183259e16a4ae993d60d471ad0220cf65220df03161ea5d63150ac17e5828c4130603d662d2b7bca17cfeb7cb85913df739cc507e3edafa0525d79d0c432ee0611f908d7bbc0a4774701c159ccad6177486e090f8e1c26c2432b74dd77c9109bf448dc2b1a4d2594d3f90b5260b1f31bda13e67ff72b008d1c7b5813333008eabc0ab8e65b7943d79827b130f38fa6b3560131e08352224285d60ad88cf75986348845da5b733b53b4f6b2a722259df684eb8a197029e92f568a2328bff318b4f6bac434abf55c42b357f0955d4e879607e48cb80849dc3cee84f722fe6daedbfd4cc20cbaa08904212285acc9f76b2f9955511db465e06dd0a82d9052fdd53da7c962ca46052153222a0d7e8f7a82fd0cba40458bd8105b97c4fd3bd2728d0b0797559fcbe18279dab5b9a541ae2423f23e971d0fe1d60ef654a3b512932aa0ea8e369d8240358f3d177e410c37ec8b918b4a7e97a243b382ba64e96924e571117f7458b358242b6795f0afb0fa388445fe239e16cf02d1be3e6df042448478e1bc457769af7e9705c560038c239c0132892f0e270e30408e3f8ff30388a864794d9f1d8511e9940a802a88ad15716c87d127116145711ef66089106924c820dc365d58b73e8832248a65ade3ea71a224bf922885053a7b8371eee4c3988b55d516e545bc6e16468f800f27808423fd5291b48db1ea191a76afe23448a6af1277c06994c93b41354182680169c2843ab568f9ce0718fe09d05f3aa1f9b51aeb41cfa0c61be9935ed6841a1da7d44b15439934f91c5c412857b17b4fa0c89dd026c15ae385ea91c9a906505e3acc355dda2e9ea456de8a793d5f3299d80a9230f0ce2c4874d849c8041603445b9e26aed63592e7b51d4bdd4c88c9c39a7cdf40ac46fd4b48daba5523e440b8a4a44147ebe6666fb573dbf1b2359bcc94fbb656bdd1871efcf0d343a5a1cb3f4c545905919fb0e9da13a75a97a7cbe996b30fe5562190c095150871da3088bdfb3b235daf2378c3f1a6df731d7fc8875257a1b79fda8859abab929b323932b3e8059187c810170466ec1a012018f5c16fff5837e1e203cb1a110f85a23d09b23acc203f0818b7cb9b082fa1bd61446f68b5e03d58a54e2bd96a32437b3e817b459c661966891ada83fc2aac6da067c268ad1b58a88c1fa290553f059d3c30638956901de9d54485f5269b10befd432eec6d1a1ab0cc8a15b2453f2562c781526acde7801927b34893f06373533b7d45e6b48c4ba67d09900efee3e23162e238ac260bae8ef40a22b255264c0c3f21ede8b771d884692692e93f0ef41656946de9c9c48df1125a902fedfe302622fdfd23eed8633a1ab3c00a2b65b20fc67d2b913327b3a62b8912564d3781ccfc83713331dd27e782955322330f1ffb9859f8806e76ddde7021ad993051d9d6bd4eec18a7b4644e566a86d4d83864c2c426920dcd9c8895879b326902b2a14d5362e25053a64c2083ffb9b8d56f80b492721ce0ca09e3b13a3efedb415726ac3181ccff810dd5bb28d7e79890af32c6245a2eb3e2976034bd4e6f084d2f5aa0fd257493ff6cedd36c84b4087cd42bdbc44ba029a51dca82990a4767203b454a90ebefba85dbba68e356900edff736e47094354ea2855b898c9edc0ecc225bbb48fd7ee7896122cca36eb0bf3d850d82dae5665cfa9314c8b435b858f38556080139d75cf5da329d6345f4f12ae567c09dfa7213c130a08a4e90d4aa3b149384fed197e3e9477129567cc28f4a3847701d85cefb443f7718209ef39de54064c203cc2e07a9e31d01a934a57080af926fee6e5d37fe1ea521f6c674e5c8b44ed060246968eec115a0bb88e0098dd38be8e0d2a7832ba10eae4b325cf893e13232ffb06dae919aa1bae8d0d1f0b221c40a6ee862a2cb5e4d0714bcfb4a90fa3f3be27e64e92fdd64562c1caf3a87e0e96db1888000949f57014c69543bc7f05861d99cfe52db502d7b1af734c23b289c6182b2422d007b8195c932001c6c3fef3b1b3864f2067bf37cf8579a0c28466851c129e684437b6a7ef03cf06843c5d3cd0fe73ce5b215f54e373ffcb424e03654e12654f6e8fc1f49d92fa264323626bcfaae27342a64a33d4f09e32ed5a62cc85f0aa4c846381b297093222f4d1220fb4f64465e0ca7dcac093f3eaed7c36a7d09d4cc832dc5c15084cae1b96644ed951f18fb6d95930056e34cf3a2ca5b6ed0f6809c9da8b29517da5f008e020bb6ccd9799773b5999cd49eb715def6ec2eac642b4adc5eb185e9adf196977edbbd1331e867a8ce6dcc46cbd39d08edf85e80a3a967fb6a701457642b3b6f5be1855987f1396e9991d913a99868f6a55c23cb36fa9191101754a98a8e72a9f9e4a4cab429fd3a2771ec26d668590e339a39c94d7c687f245174db142e813901572587117075de0f83632315b37d0bf7dd455e649e9be53cf49c7cbecd459dc72821124a79601cc008aab5fec97a88375dfb7681a5aa4fb89d8bc40096e803c76a7ed9b7662c06a3f1327fd75d9dbf0a4f79729b0362ceca7466814a4fe0a9484d16b1b6acfa8cb5ace96f5aaa7f7cca31322ead83cfec42ce1205249bb845c14f9e1b7208f9c389a323aa820a8fe11c95a6a7d5bb5d4e35a7b190a4893578512ea3bed8484ba220a610d20c59aa5dd4c2b01dc5933a08e4bd6993e19922d8c509293b355736992042b58528d3280039fc0c3069eca6881234248338b9553a350df75c7f3956501c5cc0dca0c3f662ca6d9e0cce59f58b491c1aa71572702580c50698b7895da5a3e135e2d7a423024aaf7ca9fa1490b24cddc0e507b86167f263e5cf811e1b086eee70a1da8813507b5a0842b5e38a8fce326bd784108ed6a15f8eb5454850ee1d5a255d5cefb00b5e7a72234919859216dcbf7764b37cf55a32db7f6a6231a9b4c02b7d9478d263aa4ddbec17be80ae16f8bebf5f897e9658d4d7debff96542c658de7725754c5823eb134829f9c0da5cbb9d2c2f7d5f80e06ea244ccb5a3bb789963589fa5bc947dea01e293b509473be1dfe3cd60277f28ed50a59ba77c0c297a28d9e84629d64c80e9b7cd8dac03b02ac31f44477532884c09b00be7de1b71ac0d2c33c2461bcfa848d4983c833663d383393c590b80e9c8d9a95853ab5783c55c9c8c4afafba0347a7d192498e7b38829ddf3b8af967fee0023afbed51f7a5c73008cb8185dd3351a53b62bbd62fc74b02948005829938a905225c98302e795aefd0c2160bd7d113181824a3b8bb4ca79a17108c11faf4be4bcc4963b6b280f107787126fe5ce523a487019daceda0ac19d0a6a982247e0668f07955033fd80f668381a07443e6d854dc63156722aa9d71c9a90824dad985af379e78812b7e0451f161351403e74ad4bf00067c7cb433478e438e06779f3d7a1e4a8d69c1c63c0590bf4ca3e18b9841e8ae086ba00822f9478139895d6ed92e9e2a905b7d2daad989f46def36eeb5a37e2eec5899755eed980d75a2fbf5a1ec6e20b64fffe8681d999cda81e790dd0650bbaebe074bb9e78dd9ed1d4f7ed8e078e4ea2cf3f5cb501ee9b49cce98601063ceab24b4883d670fd72f301ba80ed73332f0edfd2390ff702226192f95a702cd767276ff17a11b87a79bfc81bfca5d02bfbb893eac560d4150bd82989659a32737d06256323d8e61020adc76a3a741101b506a1d501416d1a4abc7b9108bafc12b004f93da056573d9993f7a2822cefcd1034608d60f3be8d22a0a6311121eea938d6e8eda267294070b23e8f64994aafb95edd4708936005ebf2ba4282e2060176d1be11558a6664ac90e4eb923ebd25aee87d0cc9f3a83ff73d935c7e72bb8e794e6025fd5bb33fbcb32b8934164120c8fcb28307face6c2afbdf80ac6a06f640a816ca84a31380a3b138f96debb920689701f19327ae48be359c9b27963eb0f45687fa95f7d888beb4836607bf022c9a71b9d649079a271dd7226be9762643c9730b0cbd1b6d041baa65a447f231f84432ae121000326a32e488a01ce3d051f2d4e8b23e53eb0b4d5cb81712760de61828c35058b8c9ae89eaa85f8293eed0b70104e3e9f0997e4e879232bd392902816b792bf96264f442cf5825da4a24d6cce9a453c8e5188fbf0d508c5d468874c374f7050d8e58726810c81f1ed0062d303d0bc289b5ae7986409d6c586e9331021e874e0afb0e915ab0c8403b0c9e022dd6e974b7b61a60933e2b0c859df4bd48e0839288408cd1e1276550810871c30bd053b50153ff758d83967fd7c1779b9bf0b829c30c98d5c71df838891845b1f4256bc45c2268a33e40408df62df428d7800e4dd0bb0ebe1bdb84c7471986c0549cc2c0e7580fa422decd6a2ff549fb350766b16e063da049a96209dec7134ac46add0c501a430358fbcc7ba82496ad61553a5c3639bc3560d734fb13f0eba8a6f1159dad44f5ecbc6e0501422e8c18c223d80514bdf5e29b1734313cbff05a0820bf9bd124602d479094885b834e18772341028abb2d6616a820739c1305d59fc53323b73b7b3887b2da9def9060bde6570e7f40564ff7e598516f3cd75557c0736d25924e958430a0519a643a183d598fa7c50ae46fa34989ea6fc4fd0b0e5e022ea0b7a585b93f871fe91f0181aa7b8dfdf48a7e78dad35508581b5f75b7bf79898aef7b8724b53680afdbcfa692b72daeb800667fdf778c3232151a33c7dceba9e904e33642b15026e027593b26de1663fd3134c53efd07a705a2a277b6d65845bc8df1b1b0c754631ecc3dc1f622c1f19608e17727da8ed45c7ad38259694776dd713bef6ae7fb8296455859cbd49fe76b64e62ecb46dc35b2015882b80bf432c04c5e97ec9183d0e94053ec7ec53a24c887bbf63b4a30f3ac740cca4f0c4edccf83663764d3dde5118177fdccb8fa922b500b99e0dde9e98efb900cf727b1b715094475dd1506f070f3ccbd5330c7839d0bc2b1355c6351ed1a4b80b8b4fd662f1abe4677a0d39a82504afd79087554074b98613db55a5161c4825d19e5a173b9486a4fe9722201f8ac91b2deb558a83d1560740d10cb71fe45cbb125f1536f657daab26c995ac93ecd5623d0c49c6c29417475c8b7d7da8a49de1ef82e5c50aa85e92e9fa25bd3b59490ec1f182f90220e6c9d3dda03e676f26ef384c027078964f11b3acb9edf188734ab8cdc889bf71abc4041a7fc64e733951f06b49b551777b7f481df974784aced2540054d8bc14ddd38b8a593657a1390701e14b6178848346e0d2431e3b9f0b83b51e02d49bb82aa8d0907e71362838655a8d1c0b798a4fd0858ed8623f4cc7847f758be0bd1a894b489a54176f34af19786657be77fde0a0f66e970f0ab6c323ed33b9a2bd58d8768f535aa686c97b5bd12db1acc955066e47cdbb8b0ee0ffc4b78cf4e1104824ce3ededa5e168f6f0275c41120fe2aa41c4d56795225e82e18437c9f2464bafda3a7acf8825ee5eaf8346b494ff932c0dbfa1873afcaaf0be3f2d304ae5ac84ac7fda4baf5d3cdd94c9fcec4ea83d1ad99600b89ba928719117223081699196c1f058f0e2f458a9bdc172edcc8d6d833ebc5cf929a0ed3937dab80888a2e19ad5d2c6dfac4d842a8fb5515d4e7e278ea572729b1d75d2b8cbe65bd5d20ca72c5e70116d4a919b0c42458a8d1c5c0db95c7147343cd1ce75ae1cf0ddda17484995281ef575a06558fcbcd8f8955b78cedf8f3ad053482da3ca8a8c4268c6388b257d160cad4bb8634a3be743f3403e6b797014b9327ccc02d405f9a2472dc05830a1471a264ea008c968296e2da4bc80fc303462614614dcfcbcd71ac0a1af1cfc79bc233a4ae3c15691501abdc18440c409000d811e89caaf57c4734b1cda101535ae6a08390cc2aa778a44403e75b276fba8b20949531fa481ff8a7176f0e4a8b527acebd2ebc2af8a935aeab85e3b27cbb2643d4aa8d5cf052add460e5d0d50248abd0a309f0bdf883f843ef7e7219a968e64f9d6f7b8cf3334acd044c63a5316e1d0ea89e1ea13c6c0faaefe7c03c4853750c8bf591e6448a6a3dd0734e7ea2652b0b321d516cc98fe5a042bf754a5d6ed54e28ef1de1e6588cc280b1760dfa4b92d322d025f4c6c0f7a1800b8c9a31a8dbf9dc732d59a5caedf273963ca7f5b83ed9bbc38fff45702159e04ad5a41d9980b3d6cfa40f4e6e73096b17843d47887dfdfa867cc0899b16f57b5dc173d407072095ba490be9601d19560e025affd6c3fd7c72b888ae28a0ec089ea787cf622e4038bfc30c9e3b14430b77d3f9e2e9955c9fc53bec34e6b2a7fd9b6ec69a7437cbd112e3a8c52e5115aa5dfe206b53b0407521bc8c62b86fca04e4960f144d7f2f24972c019d6a001e8f5f0884b4f3ea124aab54cbdc12d6d0e7fbe953293a6c1359f3d2593f794c3a2898ed250cacea02ec41ecf08312b999794fafba93070a0883a7b1524cc59fba3bb85a02942bd2e0d4160f1686b98815f8b96ffccd2b406f581661b70e921a0a2ac80c15ff39c9f133aa0204cec49142024cb765397103bf1f92989af2d67116e133ea8a8e86bd323b5c256584661fe1f366d40e3aa20be536254ce39ae4e65f812459779a91ea84a1dc9f0d58533d205820462ad75f484d43151de8b765bb8fb060fd183739f834c8aa4387e483075a3c89f4d8fce0e7a163d0f7bcc9b276611b57122ade7f5a03916a861be49a04068093a094e11deeb2fa00b21795218eb897cf0e59b555f738c92299d7146995ea78b274a69353f632d5c31c39e4cdbdf79a91761bdf08305938617d5efc49f755aa0e6b5c6bf3223c9f9058b33fdf2a88479e96428419e484bfd46a8a741f31cfc7d4d521c11a9a1c680b1bff22b306173095c6d3224274dd22db0e4fd467f9990fff220b758e21b4f406f9acb6eac1c993250de2d35cda3156d71ebb25ef04476e3e0cbea9882590744c3be8cca0ba5146fbe7f3dcef9d7a74ecb14884158704ed2aeff71871939e9874a5c6606af1f80cf558c1857dc4855de7460d4511126c922215c3e742340b31d1b5c3b75c848a71d71e6f411274e3b1e0bbc306801ccafa0c24e30aeeff05bbf99de67a47cb6f9dd2a471819902dbbe4e13f2b700ec818e7d5cfdfb759c0909b0ffb1105e3475cc00d382ed67a2a9321e5eda935e9960ccbc2da161f65fcc009e8efd76dda3fb759ce9ca624b9a51bc1d25470eaec57cd68bdc9e40406221871d87eefc7e074c5b064de1f97a7f874603671b74156e2e9e2b8416234bfabb8b9b1498df26dda1995549ecaa2d6b47e406daf69f5c8824bd11d2bb6581f3f7012b74ee68ea0624c3ef044597e1bbc7bfd047c087376b1bb49a575e6b4ed52531f1ef9d8671e77c8c6f500a0365ddf2ec8f8e58d0177d8d8a52832298678e6f27781d35a3c4fd4c87eb124863e8f644a01a630ffcd5c45a137d57a14fe3a1e2f87d2f10cec055a5753c351b3355520821ae8e90144e65b3d4410b5046da3d54800aed416770de131bea0df5d0e6fa1abac86944d5bcef9a9061f5dc82757e998fdefb399ec5584834dfc4ba4f47db06991bd1c7ea8452443fbd12c9c65979f66093a5ccbe708e1a5498a1722619a93cca0004c355b70edb15d1f5b3a601aa6b8d647cdb147a034da108e24448ff708a5d34b979327258edeeadead7b2edc619199863ed14db7b5b4a7a54adb74f45a1988762a2e1098d81277134d7bae71e526b5473ed7a8729ddb5d0ea3d3a20a57b13c4825aa64ca96e0909c2384d7b0f30fb3de700afb1887675accb6e401711fba90632520fb680e5f28c518b2784dda01017dc01475a245e3560d324047758ea20dadcbe1fa590b641d3051697069985b00ac1cf8a5c1ff7ac920093ab8606e52264cbf63d7e8c034e32699455cf8d1a2ba5a7f80f77c3795940d8de31759c66af7c333103b7fce6182eabd3fe7f051c0a515c513bc87a5ab8b292a6d7b350eabaae8b4584e6d1dc67d85f9bc0c6e912f69209ecf93291272b659e2069d0354c36d4b744bf9d744e05aa98d94d40ef903cf4a33e4751b66cc238a9fba76e1bf2b136819a3be28e6fc16d8293d73b75ddc691a393f7793154d550d2ef70c8c99cf9de43c1fb58b1770835e819d8c590f9c34995e818d4734319dee4a18cbc9a4372002663e275d4283733c6ad80f69361f768fbd9cd1805e454074d487ebd9e398116f14f22810f94f826c01b903e9b463ae9d050e2a6cc801c4ef9e3d7afa8d174f172e44914d8208699d85f0fd77efdf3d7b849e922f52f24d5238bfa59e9be8e411b3cd0ed770f34fa8ee9d7e318632d1761fc03287710e6f86415989ed8e6857b82f81597b2917434d1a72f0423ce20afd758085b152d02e07aba0998e7c9a75993e3701319e70ba52ee49d07e65bb3491c9eb96cd1247779441ad1284a30be8b7a162188d97628898a318ad09485f419f44a2119d7aa6bb5c63b4885cfc65dc284474847c8954964f07f8db960545d6ed93fe8aa96dec8cdbb208c8963dce210dffa58f45a63923feef227c4f48659b27a2452ca04573f369efc7cfaa39e90f7bbc926617be5839d9aec0b85b0765f527ffa39deb652860e5a4a53ab64d6cee1dfd345a0cf0f7f7a54a120d6e3278d78ee1145c456ec76d58f454525baea32bcf14952008939d338160179510ef2ed0324525a2470f499733857cbb5132c3bede02842e5b5347186e8f5b13c3aee74af83818643eb4c23e7f10ee10696b90a07df12444af27d75765c52dfe9211869af2c1dbf0ad9bd768a31c9c3fcdbcc3c39d54a0b24408969c8ba15bc31398af27180bfdd0e47009e8a1a553623bf67d2f281a428e1ee9a70fbb98cbf234b4a0814be188d57bdf432380d3a6a6b1a800cda084184ef999d3843bd8fe96f4ccd7042670597696c382cdffff90137bd36d7bf6cef744ac335c5dd75ccc5250a954a1b600200a758f655bcfca7ca6a2448c340b242dddfbcc5b02ac6c7b62280067d49712319607c255c78b4466610e790eea16ebaf9765fa21c5a198e64260112c05ba9382fcb9573bf730504a0b59cc16f914fb8c640d9009bc94dd1128b260184970ad6d20af4476c883a557250abef836ea1a5820ff10456a84b29c24ca66aecb31dabc89b2d98c4dd50cc571101795fbe9677c2eadbe349b1fd22ad5ba6e6490e96934886376c79567291ccc13c10020c25811ea15691655a0417566a5c163dc6c60336e6cb08ca53e903ee50bf82edd7d5508169b2cc2fb2d9e9e79504455bce4ffa821b3bfa8c1f31faba1f9dfc81875f7b2f2f97fee01ef3f56f6e85c3cb428310494dea4454f03a1f182da2387a597878ae59f070b0b640f124be61e2d7b6459dac9288f438ab90b7f22cd750f74209e10d773bc2495909d36a13d4d4b6a3d5f96f83d9096a87b722d757b542efdf670a1aacfbc40b7f724b207ed9b0edaece34e7d1c4d651552af72881d9803e3f30b266654b461d6259f36125db2a50da697d4b561f8259f3652a5b6db06d3efbd6d24452f97b4ff27e13243ef683da48c43c1cc9b64b5a176d97da9fb86f02816b329924411489c501812d3a8ad606d0146113ecb42bc8b919cbaddae0c66948909a629a246d0683b65dda31d4605f79413619c505c757c809ac4c98c7780d25b9b032f0e313789efa0a4d4e017b329524018d15b9be4dedc4edbd35e8e6568bd34cb99bd4dcbcabd3f9699bd302e137b732c37f56a2c7ff6722c43eea558ceecede84e60ef233ae2c732a8f6c9f92658b9894c8f9099a9b60eeeb0c336dc80f19d7d5f01ff46d5f07393d53373b7ab2b717fa933e5865227e6ce566fcaad56ffc4cdaa0e999ba49e39775b5d99fb4b9d393794c7666ece708a19db4b663659197d7765ccb0571031c520420edda58622d7dec7e859ee4324e8dd874dd0741f3a41cb3edc04cdfb3009baefc32668dd8749d07a1f2641eb3ecc04adfb30095aedc32468dd8771da6509320ea2b50a79f4e6ce337e5499f81713949d4e2aa5969b2ed1e457350cb309e37bf76a8b26acd7e08d4250436914111a5a5020d44082e252c352148e1a84a2286888124553031214c41aaea258d4e08242b0861214911a5aa240d440f2e4510d5ae2ee01b89ff6b6d23e1967470a5b710389bd8a5da7bd22d105c84b6852c3703faab5d09075c08e60a65707108e6cf751226990044e47cae72df795af1f7e3ea1c14bb32978fb2d28a18b0c6a47d24407e86db92a3f3655e1bd88594e436c355481d09f19fba94f2da6039ececa6a2ba1db369304359350a72516ec7cecded51b1f4064ba791aa75bffc0da11fee13708c8b8fe9057483cee7b22cba86e228915ebb46bd2143a590672c82bf340cb89463f793628d9af50fcb3ccf3a6f0b8bada356f807fbe0afeba3c173428774d5b014a5a52d0ba091adaf7b38b308133229f6ab544fb40af14949c3dba11da660d92e10782c84df32ecab758743b1629114645abbf4998a1d0126ffcc3a1d0a04dc094fc10e31d7d7de0fc53c855d810ac644a513cfedad39bb61fa8218009f4549a1f1920122cb3b891ded681030a6e5060c54291c8a20af0068ff9f402097710e4155177efdb30b243496212cd5878d58650fef871238488f6cbdd69070db7f4f8a6dfe1baeea6ecd48060088d15101c0f9d5c2b175389f6f2d540243d884f0d4c47e0373273a72034ec36ae693fb5837a6a3bc959b85c6f026966187a10da300f610d99c0c3e17fb340959320be4a683ed3b530f8496ba55a0a18c527dbd8f347bb0e23647156a450f3431d6b8d4bde9ad9c55d0004012cc62418eb10e39509e6f77f6afa0c86d96fa2c3c27523d82fc5c040b2cf6a34bc06d9c26513a23dd1771a42dacab4a0c038d99f61c00b575eaa0ec8dbe42a773942d82a923816423a58af41b65d0d9528b05dd75c7540561e1611825c33ea0179594483e07d108218e109a7d31460277728bfb887a89155ea5ab6e5ba8f8a83c5a70a6d376ef4bb60dbe55bd971c4df31b61d48189dfdcb5870631e3257e67b5248517ace70b1e4b42253518224f0a8558b7719c4c91b9f837b10637c4cae21c6f8807fee5fb803fa7bfffed9aff4fb7dfddd5fe8f75efcbfdff41f066e8a505cb01b44e6242e3fd2aa67ce67fb8262fc0fd4ca1be1a153cc366ad50a9a5bf58296ab5ed0ecaaf7bfbdeaf5632ad5c303e73572c07558b9880016a73859ad0daa24dc943d1d3b0730078a86e85d311e69d769b1a321ed96873ac9775ba1240f040c27744670d94e8209d3049053f4c9a2850a4137916854b56a84aca506bca0d115e44185048d4dfb3b3d445ff8ba469a36cdbea834cb51a259105e39b72c1132aa7dcc519557243af3b5427e3df49070421cc0fb86d0a65a0059a4a4bfb360f8f49aea084dd5ca39254d8d255aa69a030bf3321dc609fb0966247802d67e10b5461567ff8980bfc97c831d6aad5181183f71c0ed3381b7e2d0b461b383b07dba7e8d2bc92670f843ef8d20f3bd74163e3aebd215d8c890036988238459bfc3263b6c3b889aac2a461f0b643f3cdbb402773be3f5a879120d2393a1c06c8b5a8ff8884d14206f8bb414c7f7bb5b3cf29f8472ec94409bb3e3083f64efc0f9e6d220114a6a02770391b31b86f320afa6d3d819bc6660a35281fc9d170d061a10796ad6000a8c8963684011c2a4395464856a656eef0193c3b662709eeed769bd3e60741b0ec67a837b4feb9f8017f097510e63f42b76fb0a96e306affe1b5299b0e38f9683ff51bd6f4144f551c2889b1838dc22db9a3b1a742e75ee1500231fd565b5adb1efc7afc6600cabdf84713377be876af28f2ccdf3cc6ef971b3ad034709c6ff8b30f1ff76bfc6b81541088d6f53d1f24d25a98f339704038d51be8c4e0ec2745057192a9c444530b38ba8d57ce150d15774a8c0654cf19debe0aaa829a6a8427bbea12b4f1a25b2c63a94b5fe5c9429ec51a617e22b3c2305c05f5104ad034746582c42dccdd1ac5d6ce523a2b383d4e98a83ec19aecd590f1c6097064cf7f0a8bf08d1f78e55b0fa5250c99ea43407d706431cb42248e4122686fc1f674860fd0765139f1526f451b415653c9dc1d2cd5f9fabb4bf2a0d44aea6bf4efd13f89726d653f60e3bfde2c92a1b871196f7f997e85a93fe8ec948d494be0597f2c6a873f780c8ef3c8238380acb747b462003e6463410a1fca9ca27503af986504a7365ea451c3588a5f7fa23c4199a0b1e6661587d821320eb323998176026156a3a0dd04495acf90425724b9c67f441b9413a1b02d145921929d5054711fe604cca4fa26084ead2912aecc4c16a261fabad8747859d19451036ae8d8be5fa1f479d40051d1144f6be80826c7846648a34df0af6f61674cb0d56adce67d8eff71f9ffa18e951bbdf9dfe66d671a0aec902c08e8fe2297c8edf6b823ef1010f7f71a44f2318612539b58ac033df658c0fc3b2747cac106a417305a37baff069cafe733c1a19067707713a6d543abadbed259b5f74247702e053801dca07add35e77ed4f4491c5624ad0abdc05c4d8641e84ef293327c875ab65653d8c81443a571f8e5f74e5a2f240996c441eb6567d64349392e7bfd5e513453d76eee12ea57dda92c2bb35c99f8f44a18ffe04e5aa8be4fa10d8558738bfb1ad28bc5c357cedb7e067861f186dbbb3a245960965927901f5c23f9004a2e27005ecb7c3b9352d4cb0c0b4d2d630d8e32371a64377dbd2af7900d45ecc30950e2643c76ccdb546daec8e6223e2bc9bf8b5425b0a2d24ad75e055472234cb101a81e7180dead1278b1e09abf3c7355aa4d5c0d16e97e81a711646c6975c6c3efbe6e8687a5a20304037f3e9cebda2d2978bd3028f7bcaa1d09e3889a49472e7655bd50428c67731fd43fc2443e0fe4063a48b880b9b75015dc58455fbeb2f81ba2923730cea811425dbd4dff6cb20e76c33e8e4f528506721fffde6ba9dad16a32d3949b4ef1930f8bedc94df49b7c002e4285cc5c8124656ef9021ebe6b9018aa1a7481daef874c19e7d710e52d1640a4809b3490562c75feba6ead42d17c6d2e1fef5aaff8b7d012ca1aa424838d4280e5052d2ff93cc1a20b2394cc889305e324ce2b5c643a06051cc679cbfd0811e503197350f38ded07eadd56cbcc0f9d222a21f14be5741b8ec479bd388ccc517c4d42908d3c398cf37b2ac243a6c78ade57ea7730c51b30273e2e5e637363ec74567635c6056609a3c6b59eecbede479deecd0b2a7a4655f73e3569f2ed324eba9e1ff1520a2b4905af6c0af514daab6ac69232e5637be5091385079cdc2248c063ca1b985149239f1433b06081381f11b81b3a968d90775d6f3e55442a4b8f3f3184fd181e4e6762f0afde111dd22080814703b1e8886fffda8de78dbd5eeba706bb1ed45803c233e05121f04a613dcac7ba7ee2b34ac59a2ca9f439ff06f7fd158f84f8d508a3d4aaca7505c7bd07b54ecaee5bc708619bfaa0ed09709df31c6c4f21310f11bdb3f2bb89df2ba91ee7f7d425116290b19ef5cc3cdf56404b46951c0c8874c678b38986c88b2fb6b2973c13a57269323f5ec79f876612d4b58fb91c44586ac06cedbf7ae14b67fb009cdb3c5318fb90adfbd6c6c48765b0b774cb05656b1ec65762fb6d728b2aad69ad00bc8a0f692348357eb87530467343bffeb1284262a3fb3dff9a8b075fada0b76e05065b0307f14a765f79af62ea7ddb916e23d76c7dee007dca04eb8d8187516c2ffe7f505d3f5abefb8b68c124288937dadb9930f77d395be797c2a4a7e60ab9aced9cc3d4976c77f1682e847b27571f284d8f3a514482b3f37b000b07950c45955f900f31d95c937b99bab8ca47d1e7c83b0bc459f11a19f74fe2c695e72bc8ea395cedac4b38abd2ff977eaf906c0c43eeae22a93032a7870d01e19bfafae85ffa9a0f3e069bc0374bbbe968176173b38e4c5383a35d80e4e863500e21905f53875dd4d78a0a5167e30fe1b87d34b058bcc55e4e22c83fe4f84cac685c81efa79ecae4a310b5946793fd85ad07c983daf78b0522b20105b88e251a85dc8a7348328f4ee44775e3e901eba5928c2e4a900c02be691f12fc17f014a3020f68370e63c242f120f822210281406693e1e897e47446785755bc4c3899b5f5220fb96a21742b45ff1c207c99369b21494b365a757307b070a11cbf3123ecb1bbb242996e907319e05e397b96caa6efbb7658ba41e4135c5f9962f7e0422be3ebe65e6d6cf69234bc15fa008f0780137fab22d3b01f08091f96e154e218c8c7c25fecf1851bcaa7a87a93572ee23fd5c07eb0bee3eb4243ec8d5d3fcfa0ac38931664682b7506be24d5f7927abb13d5220ada0198536889fa4369e97f1b60dea267dc127b17238b89b29de63cf74d19bdeab661fc9728796dd58b981f0f37a98124019be0afeea881ce2a58da5780f662531b30dd0e44035eff384e77c3c53d7204712b82224b5cd96cd69c6e05b61f8a8421f006741af436c36b573e0c32d62067db26a0edbd89616698bd4a2d7a8626f15dc670aaf110701e6f24d03d90aac01b7ee0ce42f957f7fc73b9c40d290d5dc885a1e1b911b9211398e8be81a3454f1994a26a89ea276f884bba7e8290b0bdf5ceff1eb39e70b749210340053aed762ececa2763938c8e3e1624aa79e9a388a5078631b4bf7b1d71b7ff492b03879d24f7d4efe48aced9423421656f270c5dc9b4587fce4a1197487ab5b92b7eb079cdbde043c6b60ce5c3480b4168ea0b335c2e32aebd5c4adfa95ccdb8796f854e097f0abeb4cd2a85d0be6ce5463bb14de77c2eb2d30cc17ea507d6a066e8727d2133c62a286376bbfeb5be8f6d4fe8adc44371685ebf9d843edde3cadb992ad9eae20272ec18fff90f44a602c13a64218756e0affc3ec8919d70f11b86eecadd3e481b5334de453a4ed9ba318a7df66a3366e18e16ffc6386452e0f1cfbe6f61e41b5b6423fb1cd40ae5a884dd68c2e396fc5041cc957f4827e8b796268b7c97c25f80ba7c6f8eb8906c240a52162402c6669a62f6953c77525d241e13a0cfc42e8e9107cddd492b08a452e9845a16eaaa942df3428150915e8e62a0dca2a6af6b7cb3cf2fee2a267cb831de31f1357f1ca9263a3cd0c05c87264e20f192dd59412abdff08bd5bfe8dad4ab0674a81cb631a1a202309ffcee12bd58ed3ab9c01585c3b20eb9aed7ebebae70c6326ed8eb19c1b05d48de221504784f30282bfb3a52e7d0c0ca25601abf79eabe090855f26880bc8b7f1d77c6514ac1f09ab2d29321de96c570d726f6467cde180f895ec3c2fbeae36680c66c08d053d7816d484578de03d64c22457b53b8cfbfa40fab9ad1cfd93a8343d7db99529b5cece2e0853bc7f0c20f348797e8f3bb208f2949e64bd788c9626880e8de2e21d092e906cf31e2bf756d33f27d8cbbf2a0a06916ccac5118b3cf9a15dc265f61f874637a17b3f026abb91651d02e2f74be731cc86d4d32e174bf2bbd84c31a6ae5d3f7e9a129d24422e2b61611f852a505706abe7f21893fd5bfb0c0f606260a06871796246bff54b9b1fb4bf57cfc8cd6d72ff3bf9b31471c84c1a51be4774e5c0a17911e8c35a3f4d281a061e94bb5a75df2b9e1f0f21b6bcb0b38a37a3ef32e549b74181e32230c950bb842061fcd8f6ece4b4178ff27b8b8c17da1eb987ac6c1ac84bb41afa445190652c6d8e21457b8677813399d59d40c9d5e4038edd0eb97992cfd3607ec75d1b5b2ff97ae76d93a041a598b9b42ae5e2a840a72058ab80e854af4e2ecdda6387520473db9c345ba22eaa93d33d6991ffbfc996ee939d17cde47d2d4b73b4d10ad6dc0762b0b626a8a411358f362e89a942c7a8b466cc21770b5061bcf26faa3811df30592b8194850377900d4da4dba5196c6eccab2cb091bf4551eca27df5afccb0a955b5f43ae71df731ec3b02c93ab27a000c7304cb3011bdf2db43bf375f1910d58b6c44e270423b5e480160b8301e05b28c0e2404d403636e0114aef7181ca5dbf17a0e274f34609e59fb6b023a50b969862209d4a0e0d1021305ecb60a13fbb58ce2f81306dd7ab2181409975458129d875694ae7a13c1a35495fc76647f80b310acbb78c4ede3c2812947472f011606919b6ba04dec376b3e734a07b506804377c7ea4f6120c7d851690fbd561c01ae76b8b79e1935c122910b263ec61be06c75bc2c7f611ec1508971615c22641ef0e0e3ae003ddd25a4ccfed87b82815fae19da3573c813479c6997212fe2b215be94be2921a73dec66bb97f25b92510bffa04c25a85bae883704c91cbc82ab3fccda12732d94a36b29823ca4746affa834bc7be26afc809abeb9269b5493fa9e9fd27794d1711a85adc3a93871591dac2ce4cc39a8332dab7290bd7423cbb63678dcf2dd2ecc72f243ec9489834080d2c2ee06f4ea5c20d69b9afee922fe2ef3e4c99e80fa54785d4d32990bee9051f460fe02dda20af7b70bfca7a1e3c1b5c42d2e509961a102745eacb08e8b3019e79dcc019444bd2042d4cef10f1bbc665ee2164051a4adf0d4a278b97dc50d69d387b4fe0a015a2d8d3b95492bbf54b10400af950c9cc5b7910ebaad51e09a0129f5183660db0f579242e6ab4d0e70e98d0590b427ba1969f05e949c2d28061351bf832e63c134bd2945dadf3e36823faa5f19bcce6b8ddb8af81b643b892594f0a4c35ed9b77383083ee8e06ad155ff61359a939f6dc39ad6af842b56b4304c562089a1e5f2b32d21a8a6cbe96cab661da67ce0baed4719fec895af4179814f0741b893bfdc21d275a4ed8a4d0af98d641ff746396e0d669c92fa6ec5094db8a3b10ac697fe3ab8aac1d4318cfa36a0f56e91f6de0579aee033f77e9a757d7284368ce5e8b374a08540c8bfa08d55ca6fa036d8c30ff3d6d8dda98c2b4e9742c68f1ef89c5935b0b930791aa39bc756cb2139b6114d856d9ac9cfa940abbd0abf6d959b56c169cd211c2b1cc72a89f43fb52b0e728ccb64d4b6b4f42e9d600dc0f8542ec300258f2275afd6c32860ea73f82f1d77504183906a9801372d70f56fc6700295b99a83e4cbfa524045a33896df7015237377d9748a0341e5a5faecbdd0d9f902f429913836eddcbeb276ebebbb1d2223beba63e69fe30298f387d87e1f04755200ac8cbc93529bef2bd80962a25ae865e4bafa033bf29b0924957812c228984c2738812d203f65af8ce20c281e940e9c9f0c6b99c4906ff397173ea1f815790e3a55088e78d3fd82f3f7638e30cde40384373c1e02477d9579bd6de1993560dae29e0b12e0624d3639217ed873c6926b3460688d428fad0aeb687db9fcc3b36af336f75806f920060b7c3c01ed9e76b43a67d31330f578187e684b9a7cb0773178070528f9e1be1f3c36a96f3812050cf491a1e414efda1f46dd1c4da13b7dc1614a627d27366d30dfc5e01a52f3212eb208398396a4818d774364bb814be91fd7e27f36f2ed61cbb6f81bae58dfe61a7b19a29978c79f9f1fa23c3da26a9124c81bd8a6e7ee09a5e1f4e6056c1ff6bb2a9131d0e2e5edf6034a59d4dc23beb14d673b55ce77618ad1e91b88a8ce0955291f773ee8be47fca68f44c64612a62db627296d50f74445b47222151142e0235701d166872d863298bad5d9a9bba068a030bedc470fb834cedff4dcca543f36e84515722dd1cdaec754a591e2b2ffe70c334d0c4e12e10f0fe9fbae674b9e743ed0f59d674a45b17c44de1149d4a0078062924580ef266394d70d4f5d436248bd5c5c9156342b9fdf0496988349aea451d356ecc639f8f2322aa0c354933e1aace38c4602b6419d424e27e873cd401f4d74bce890a33e6b831260c899a1be34f709f43f68d58796b80e3fc8d3970d8a29ea3d70353f550561faa2a76315adf09ee7f9414669e1ac9f87261dfdaa4b5ceaef76f9d34f9264711033aaec27ac1e5998e95ba38da9be1f83736f0b9057d0f6477ffff38ab0b9daee2b907688bf35681ab33372cd4431464f335ffd6039d1582957816b91348c0a66623b9422795d797eb7a087edce1b35e0debaa8ab2d53665c8e43880bf0fdeb1a0b38273e5bdfb6c16d52ebcf28db601d146b4bbee54857bec63d10fc2bcb486e7694eeacca8d91307cfbec3935d2d762316c5616d02c1f91553520266aa56949ce2487dd2617ac020d83e9b47f5d677cd0a455a24caaa1244126eee3d6c6ab6d94608dc5d0675658c3861348aac0f46deed4d0e19d1981ecea73f28e2854c62f5f7f5078869f3e18f7e77b2be0843935d50be495e9b5635978c77aade571ee4aac066895332300435e00e79418362cd2cb03f4164a8c1a348b80deec28c1553435e97aeea1a4cd3c0662108b32aeeec32ff109f58914e20c1b742c715e1b50b8b47aee944b64b11a691454887dd9a2316e7f7cdf38d195a2e91aaf97a46fbc29efb5dcbc63c89ffb5143ab8d4b243470a158b07850bf1084295148b422e024817830aa615c8874c208a8537a24385054725d462bfddedb83ccb227cf4b34287970257f545f3d34148e8e6c26fff538458b91ecbfd59229f178a2b395d68da5cf4a30ce4452698f0135306e7d7fcc0348ccaad10b25df686bdc8d131c46309012e115894744663756279538b17891640d460680f95cb89a5ad0434e13905bcf9da7a6fafe672301afef0c3b72d67aedb8ed8f147e68a164c60c4b65906765e564714f0b0d534ee1f1f91da6dfbe05f3109670b76be344f044cc2690898f25de1183e8340e5bd5c2a27a4b585e32b428d90a675a67cf610fe5761228b8e6c029961b36b64a840960ea1c3e9529cb1d6ade5cae23f6bbd671546d28304979c51f7aaac25528ddac359a11f8cd632758f401bfc44fcc19e76ba8832bb11ac80458cd8a6433b88821cbc80374b057dbcf4607d0072504c14434cf61de7feb2515dd597999f9270227dd9d7c9c242e9d5d8436a46d2195accd86d90c28ec236f44864c1363b734f6570ad865fd5edf34f4ffd3e6493b50b84509bff453382097ccf9ada958380befe2966463f86ce83dec5886e8fed484b62352fe2754bb457f411da78891766bcd7832f9eaeac14e4dd693b8c92b34ad0d821e81573b7bbff2205901092429cb9e2d8c841b730abe05b9d32a3f4081928fdab4395960d8a26e70b81d73030ef2a1399f708cc4663780716cc78ab8e56414b0f1139611735caaf157a9f7829f4595c4bcf35fcc61d67507d08f0aca0028e4f508b4b052737bdbf46a0f70a2d9e43d2b24b07dcc6f3052a2470da80d2c50d72204dca81f9246d4034838aeaa262608096de97dfdf00d491f0e8be274f02ca624a3fa3f5fb46af1ea3aa57e5f70ac1d478a4ab7e0f84460013ea1ba3d42517f185f1c7c854681c4218ca810ce011c30d5d205054c58812d1ac946d38671a00b3ff3ed8ad2be3f4f981f8c59712f14b8dcdef20d26d8082b7f139935e9cde131c350ef97b1f3c29f459ac456f6b543bb94b1407cb50d0ae19f0ee428f79935c73999730e15164627a23e8b7fbbc123ecc78bd505090e9a20c2f485f0cb8e074e16edebb753b9c41b74366539b9617f1a0753581eeb44402e93c5cb01ee8215da3f4eabcafc2c639ba18e55f192b29a24f8011a54716beb885ab10a79caa3bb75a690bedad7b9f832fdd5f112d579296fef347fb487e506d2d835fe05988130b3c7ab8058f735360287bee1775848e5400b473d8dee5e5e49e088065727d72673f788ad2d63905209c9c90d5d7970b96494a2733abe136454a48722ed19f392a6caefbe082c109a568ec110cf146020410e6ae3584444cb4d59754ae8b4d22d52c3bf7f2ec907dcda65e4ada081231df4562a7032f2c4d964d10b8a3287c615e89151649e08b97008e464a0867e15286277cb9492b71abf136ff0497ce8808a8c8cbf1e52f8a856dab61e56c1755937951ec7c70dea12eeb5ae848384457212c317d46c942f377f0463b30043b41f0a0f67bb12f4c0807f0c304ea2005dffad0057602fa7c633656d18bf681bda8ae2f7ae73b336c2d034719f0692398353aff7d16ca0671c61d7f5adbc448a1cca51f4de6d571c4751706094f1be1602be5664f6eaa6372071c8ccea8de6a2f06ab83c2273be27727082661878944d76228ea601c1531a01807d7c2f9298f0fa4eb8a4a2f0fa78b91ca7e0a9210dcce16249532a4630746383c072e303df59aa34a019e25af6f2dac4809a77d6f90a29ccfb9f94ca4e3d39473035e61594a49bc296d3ae5b1a804a7323a972a1552b56aa68f12684519f02be794d06c5e9849dd3f5150beac987d80d2572ba1103230c1030ce349618d8519ca772d9921d12a89f2c83103af0fc8b5d189dd90841df9c911ab72d28319cad9b544edabe35886309e107ccc09e96e3284e0c87948b598caa90b022fef9b03726c59b7f23e02bd34ebcc9a185d623f599527957a4846003dda1bbdaba360687323df9d5e9f0a10c911d45c4fb8bdf0e8557fdfb45323174f49bb33036a7046e8deb57e602cf8b890657da8ae5c1cf97c763bfcebb5e62307de5ec47f0a7c307c61702dff064907854ca69a55493da7273bb08222b17eaaee7fda7c0a18644d84505de606da2be649464765d77d111159e96a8c44d66b4d59bf162a1aaecaa8c464fea76cbb117b55a71c378cbdb38edd1e8ca58e00d3c8c97bdd8f12dbf147c13c01a4c9000e26788631d62d3b736036882f57a397a5ee2ebb0a9946b6aaaed0f56182d795941216a947afe632b3848765c00cb0cab8aa3f7797978d3bb54b088a4058bbfbb660377da40625952210c0e8083d1623402060ebdf8dc697ef93118f15190f36c911d9088a78ddb18ef7b6a353d16bfb28952f3df6a520abaf632a00a5115ac909586741495e172c1862cb9af65bd2472be1ad2c5a96093ad05be1d113c4ee6ab50e50d766d3a1021a790b9d20a1b40210d2c9875b8ba95b5b8e1ec3e2bc85d7c5e11ed456d4303b49408a6ed7d5844ddfc2185ed7bba8a265c63e47992ca6fb0e597721f44e1eecc1100b11e6f0b96ea0e4d7a8c35d79e865a32de001606555fe5c25aab513fe434779afb16190168038c20cc496e114c7987343d8adc9976bfb2e689e1e3da4af10f6b6c7f726a9b9abc9339e988169831dbdb1a52af73cf6cc7a83b2f18f6306bcafacb21fa1934c92eeb94f26e9b06b128ceee241f294056a7160f6273c071ad600cf1ad829f164590cd507011264bb0741676e4008d28fece5e0a8f59448e4b35a8b735c1ea2880333f07033d8815bf022e2285b0ca525ce3acac512b4dd1353e1cd97140886b1d48d03a6ca31c2d0b83bf98008c8ddbbd66a6bb192ec0689ed92c93b35f246f69e8e946e6af5e81ce52af6a9c2590a2790e46f6ccf38456a017aca453e93560f09b9981c2e422e2c834864f3545b026987fa5a01d729ba98fe84c0316946fcc4371653dd99f2e560ae0b4bc60162412b0bf3975987ba294b59e2877ece0b71b6c448dc2d99e1f856e1cb4b84699ec1311cea4d29a2e3824bb703480da5c08efee30408bfd6b9272481a39caed7c82402eb3988a6893a3f5f8576a84946a8e2f3600f31f7f2c9fc27aa4a70b6bba8f6609764bb2ae05e43411b34f4ae1e665084258e4c0904698c2d6b9da455f2b3a68c876c6ac722e7cfb22d658f26fe74a9b438d48f51f4529e02b8178f6457c832f4e8ecd3a7c762037552a5ee8b7fca1dee72be675431a99a289668201f6dcd4b37bbce033a3c59e5e115ca00f7702a86df9b5b27915122a7357b4a16bae0ccc855103271dc4dcce6112965d42de6ada72f51909a08351900146c317ee13b27d8bcadc42a860b1b0472ddb272afcdb71e89485044019a3ec47b3ca960463d651eac263959f01380f8f919e2437872c0759b8e5c09264e0dac8e027e662c2abf75c1b1940c21e84e87a754d703713872cf1699547109aec7dcfc3238ff05873f96c1554eaefd0bbe377a29e80de5b85d83700e540b3b9d3ce0b024e41104ba6537aa5820da19a703cdaa62056cecf1c67c309c701df078e6b31026ed56e5e75da84c77bcc89632450232d54fd155fb03b19508b05002a310906a7321517d409d21fef5df3695bbdf86bd0ea43c5562c30411d9ddb6dc52a694640a3f0a930a7a0a49baab77559830c7a7c6777777ff23dbc3af9478632d47f7ec6c867d0c2141fd7d521f305e89359e34a89f2251047586342258a1c41caa2e939821478d31ce58718253da345236ad60819af6464ec125205c6567da9a6823679ae60f3346ee1760de63188691e6d2442a1f46397f985e029991b46dc70b368d944dea038aa0a0f5b943c690109eb08365825dc7d102a232658b9cf1de8a5c2959ca28658c314a12c827121dc3c14475d62d7fb617836c624448d8633f4c4c462c462931a90452d65fdab4171489667452d77b3e856ac618e35c4f6e552aa191f387b9bdb0756d240ff5fbcee380f5e2a3e20ba5336872386b2576d1054432c618a39452f20aba075ac728a594524a19638c2d85849146d05926d823c5467bea07817888c5253e020285fd3c94f1100f4d3efab9d19e192c7105f6386b0510c208218430ce28230ce6466512ccd2a13a91214bb22c215a32549d159fb92f0956fd21843470f5603761a8773295793217c166009b4c5af4d87fb0496d9e73a7a8a87987818ea8e4ba39bc3337ea10c3a28c58ef6059e0cb5f722ea58cceeeebec316e841c9296d25f3e74a34590c51e93f882b9517e652a7882c5abbe22131cfabb7b978461779e654a39290a4b02859a1b151a827232544a29e5bb9498942e4991247f3d967a786c1913844390ec52c2b9514a29254c179bf5c984978c31c618a5941247062ed7faccd15bc818638c314a29a5143782a1b880a3ec22482388e2db8821cd1831677c4c76362f6463e3332c903354df81a33acee6f3bff9f25ff3d001eae8201e1c1d280cf62f5926dd3413a9bd1c1bd4cdac0659616b6bfa4b2468ed30b922b2ca8e48890414230a7a7102f44550955c34fc7e6805917b9c3366934d36516cdc666e34c610b988d18f986a8c928a18e3a909378521a5134fc5fffa6408598b17f8dc286b21e4594c76648c31c618a39452da3cf119a44c22e7d87d85aacb44af46e832665294bde8eeee32b6df444d34708da62db0eedb24accf199dd0969312ca871042093b1a21a53db06c73229b2fe3cbc766b7af611b0efed14b3db0c6a45319d316a94829638cac448c3e027667c87d53e3016a1c4069b7fdba1a3f2e25bfe66103d4d11f9da06c803ca00ed4d16f32c1bc984c5b47eae6954a7ac9f97af17968d55c9ad86f823a7352ba03777a073939f84a7ad13a6e6be277a4eebb40f587ebc507c2258645efe0cf0b9c4570f9a432533024647a073b14935366922435b94919a3141a236f949a4cff9e874205712224b4519b1d2fc28c9874f7f7624449ac0b82094921a1fe190fe551b0852b7f4eefedbf444a229f40a1a6a99238b842f59c2b01d86555ea0cb03451013568d30038f842264d28312c4a8ce314f772b06a7bf79f476c9acc49229988b4eccbcb71c4c663cf0676d99e4b3f622a94d6afb66e07a6e92b70bf34de90e9930336afc9d2073dd18b5adc622946295b40a564e7cd64faf73c14cac66688cfd090f7cc209baf7dc47ebd38434926ca038d5ee4a6324bffa2c52998905e5ed3344eaee2ca575a6f1ad72bcd378de39526378d83ab12b7c90702137fbec3ffe88e27d013101823f1e917bb13adf33f4a2af590118b353edd9afead293881788d2fe9de2ce504b411f85eb77e303e0ebb11f8f1bd3bfdf01adf6b746e7f7dcec738b6dca394524a19638ccd33371aa57494ff6cdfba787ea64419aa47f6cabc828357ef41e95af966d81dd5d97bd97254a7a4ffb68a55ffb83c8440df1bec4a75a70175f7652132a6fb4c4b4d2fa58deb53f6481829e388b0d715eb866c4d7f944d723dc0b9d12b252a425d5ca930702ab141d5dfcbf1cdb81f99a90c650fd8f57a977ac8ff7e6d548fc9b41923b2281bb03303180fadda3ac84af5286dc1da6ca4b4b1e12a090358e9c7d7ecb509975fb46eb78644ca7ac46e8b564bedef8c3126b8628c53ba122637794e789e6f3fa1ad9452c640e73b16b7927c79c1482e47e05b943039355226a794513a9531658c5101793029860e5ec293d2cedddd1fb58355a5f7df4e229fd88169fabf4d9decda1f720e2184117b77c5103b222cbab92f0ec9b51e3b4f2261ba74e9327d90b24a9cb3e3dc4a1fa594b2b4a132cc83d08a3d4a4391509913892e6397b14fe10546fb48caa67ccd378d944d140ff451933b0c7e8f1d9d7f2b976cc881b521e421a2d8cc629c9352938905514a8f95480aa29991668c2065267f9b1f9bf5e933444248299f638c12462965472b40992d605d8c31ff79f43f948cff6c62fcb7ae17d306a580ac173f3edc940ff67a8b2af693ba806e32b8189cc906c8a634b05e1361afb499b48e2483b4aa08114efda0814d01b15e0c5797263e0ce771585420fa8bb4cae6074eed7ad35597083930a8feb04a8e0e1a86e3686afc35000ed51f66dd733562a0fac327f273a35b946d8112030e688cfdc055a4ca773f62aaf29deb266c131554ca29698fd89d9c78ebd35d069a0d8aa46da5196440d9d94da67fcf43a16c6c823c212434434ccbca1333ec68d0abf092242d470fa594d216accf1c359e307a410e9fc2f424e39c93e161d773251e3960a2417c3860abfa0f3940395472a654ef207cc97d471cd6df1a7fe89877cba457c067009aeaa68f729bad1527439aa6df145fba52f7cd2d8618ea4765cdba1f4a23a0f0872cad7187dc7b805576356e7016e1ff91e3d7bec6183fcacb3c59857decbe24ae0435354dbf0c0c5ad008bd015dba74f1ea7567fa68638c1c638cec0426d9a3a0497fe8b0d46362f2bd63a23552168954f9f1715a8b5becbcd483df25d63986b1173b9451c739bfb93941e5c7ee9b1f8397eff0096d71288c8a1f464e760b7fc71328c40176499a9b35967c6c855d2c01d92e409274a90628857579e7d1dda33bc767c618638cf993891bb1ece1aaa8fb84a911a67e94865865e76d4d3f8ce7ad4f19042c71450a32ae1d48265a3254d9c71fa7997bae431f18507f9f506afc2fa6ca0e026d4d3ff30028723dc0fa41a0f5097da40ecf0ff461a21fccd803a13fbbbb7bc78fc31c343b0a9b7e26ff221d7c715075af82ba0fc117047a85754dca01dd57fd7888833a0542106272508fcf60ae63a5ffe8f69f09e6bf5fd5cb7fa41ae767a82428c744fb207860b158ac157d0d869bf1f2428d01a840898ba51a6718a9fe839638b934f1b7971a3fe37cc02a89c657fd7f60553ef683d6ecbd044456d921d92e95d4c5ad8932ebbe10d408975f66e75b13bf582310d57f13105d8947d4e48882d7dce28c524a29638c11670a97bbe646d751805109ab9450a894914b3da27b1258e543f9fcb2f301d6d83918fbc26646f2a098935293e91f6709972b4ae95e7d0521a270c8f88c1118b61ee61553e2476670007d0105e7c0cc10ca8b012966537a703e918f5ef56e08f67ceef28744312487d60acc103cd0c2d74a4f5d00e4386c22e4cffcfb1153f57fef09f5ee6f6f9aa691cf2528930aa69ff14c0330c2144698a65a8475cc3e3e6dd5f6f2f1513b30ac09c576ac176d24875a6f879217ee4b9ea3368e6a26129771cb039511930f8fd8d4f8b00424c6132c5430eb9622076cea129923d9a3f8c8aa7964734286bd76f7ef086f9539ce87a51f70044ba4f8630f5f3efcc861ddbe7663c713a8ffd6f8b3d423da90533d7ae7f3c86684298c30c556034e38c5ad1ddae75da2d8d08bbdf9e582cdcb00d42a197e6d3a195ec0829efa6d3e6775eaee44011e2fc30b51c0db744aa4f42be0bb13c2e36578193a253c3e679504b5f99bf72c45bdcf407b23f7a6eb3e5759157c35cdfec48212e1e324d4fdadb1053627a526d3bfe7a1b00d9680406c8bc79d84c8f0de7b9d12254bf68a26785652fe952ce11f7811b492c2bd005e86cf59cd1550f8de2f8edf6f56b73875fafdd661d5007ebf9b70eac6ef374fab08f0fbddc3291bbfdf4f5895e3f73b0aa74cbfdf3fadaaf9fd06e2548ddf6f2aac2ac0efb7154ed1f8fd0e6a958edf6f214ecdf8fdc6c22ad4afccaf017ebf8b3825e3f77b0bab0ef0fb6dd447ad42c0ef3bcb99b06ac7efbb4e02dc09ab52bfef4fdca755aadf6c67347d402406ea986e0600ddcc4c07b560b07f7a00852e48423dd0228469c70748e899010097030b88cb8145657b80edd4fde778e213f6f69fe366466362c8909941a386c9c60deebbefbaeff41cf75cf7e178fe9cbaa51edfc11e1edc76c3650ae06c38f8ea8fa1fb260cdd0bdd67dac7c191ae905ceced9f38d21047d2c2debe0d8ef4626fdfc491b8705a8bbd7d1a9cd684bdfd199cd623c36932380d88d3acb0b71fc36942eced534ecba215692a4e3b6a9afd14a76d619afd04701a51d3ecefe0342c4cb38f004e0b3a00a751619a7d03701a8ad39e30cdbe0e4ee3699afd02709a0ed3ecd7701aab69f673702423a6d92700472a6a9afd0170a42c4cb34fc391849a66dfe3485698663ff35998ee9b1fddbaefb5eef32aaaf29fb2f98c85531ff6535786bd53d6d1c035a3b2cf2e4edd1862222818d57d2ee22dac62b21169e9a98b62b1154e6d152864a9fb1cd4aa5eed6793b11f4e7d994fdddfcf7c3875823e300a36855318104685539c82ba8fb9302b9c6214d49db20f547f92a01f746547381d006e5718f7f1ab6eadba1f3920ae52f705c02951b2243be2b59272f25f82802a442b2927effc55dd88bde5a95f7624031700ee60506644bf7e99bfeac2eea34b85bdec0802b1b70fbdd89badfb31f0d00fbab69fba0058522327009ce3096d673e7ed57e1e9df992874b5402e52752e12f078027d49344f835c2a036bca5f6f3164ec9f77e6d967a402b4a38cdbac9200832cc1da5a139c51fa462a5967acc1fefce9c29d3027d1b7461a67bf6fa73b0e7ede09784c22a29f377df35274171dbbd79a1eeef600fc21d2c58425e0ef6a012edb727318944ca489dc7218128f6e092c642b4da5ee3966c53ecacb4b721087bf07db0870327f8c649e9d73829d873a9c7ecb6090a3f86236c0802b3391db0454ff5ca838f205bece860c362b9a1ab0366acf37bb6f468d85ee7b373fbb0a9a424519bdc5753e7673fb98fa6cecebe01d4993177c4a662d84f200da8185714a7b01d2cc51ffe7c2deab7afec6b08d1ec49af91b89f29ba52dbf38250448aa854f83bb08ab3879f638d2a3c41fd76d41802d51a0889c33ee3fa39853d01aad82a5330aa6c434424a808a7becdc203a7aa4c014b859f837dec00dbab70cb10e8967ef0e4fab774034fee6bc66d1529bc2a97cd39272966393e9b1a2712d8e5c70ac108203a706a76275a6588a644a938326e071e046da907a8cb8328b450616976a61a50d30ae8e755f8455ab52b081fe38a703bc0af82ae1076762842048876972e15b2480c5305160c62270a3b2b25374c3464b418982f75da155eaed546822e2082cf8af44b78044106aed5e97356383e6705c3e7acfe7356dde7ac6cd4982123062d2979f9527712927de94b9d92d2679fb37ae17356317cce8afb9c55ce6abfe376098e33695028fc18388ffb2f5ee07070a82ef4e3d7eb05d71084ad96d1d18b3d7eb1e746157b21817e04b437b0f2bb0df6463e7f16a2ca4fd8e3fe99e63ed4dc7a6ea6769f2938849c88b23daed791f6f34511f5eb27cd8a3db429ec71048a3fcf13a56391cb81e2eb753464145f928b5e6c0dbf47f7865cb61dac2b5c5b7e98f04e8b75459525ead74fbae30fa7bee8457dd5299c621d13d425aef038d9b6137792008e3f3d8e0e081c7ffa3867fc79acd4235e9103290e903838de86e823e827c6ae0738030714d61ebc7eb185838b91cbbc686f606cb57e34aefc71a855710a512ce510c491177bd35de3ab5571e85539c630047d810138e24fabbce8856e9b669be6f923117b1363b0354540559401a4e1ffbf71e3e78badeee2cfd630571b54e8e745ce434d4ae06abbcf5463cb8615f4e3d76b6f56d59449bffad5a4b2084e1d10a71702ae4ea7ee147f57a7e7f71e5a63c842e3891b628397ba5700fdd41d88e080dee06c70afa5062763050adff4847ef107a855fcc5d2f03387e1aa3c82ca1f9b88ca40ec12e257a603fa404c7810d47120f843839bc1411e2450f832fc32f8618802ece1600c0e965894870d0aabc2180eba60100f7de1e050d3f0938ce0a645e8064e7ca2f84cf9f9b9a1c42d6cd2a567e54da0f09d09744b3574750224799df0b2220bc756dc012ae271c25ed429a27eb149e579e23d3d0ed4aaf8b38329b6ecac3c0bede2a7f26b6fe4de7021d2c21e3fd1162f2aa2c21ebbab7320f6f86100837eb1058de20bbef6a62bbfd6d21b4211da424bebb057a942d4abf8d2db8be051855cd8732bb1ee1536d0c2a499e5452d9d56b39af0ce4ee52dd5f0428d3f4ba05ffca9b0f4a3eb27822abfc4ed4aeb0d08fc5ec8ced5bb6fc9ae366ea32085240cad346e57923302dfdf091d25a854e9c9520f50d7950517d47e6d0d7f3cc5893dbf38152b3f1b716a5d5c742a3f1f754f4761d5328188b9706aab58b1c3af2fbaa2d87eb814a17e3d31e9409cfa62cbc5a9af5f419cfa9c4788535ffca95438c52d22eae7565af5f32b7588fae1a89951fca92cb457e800063552910cd4048d2d4e9dd8c55666165cb17b5d81414cd08f836ef07eed4dec4e34c81a3f762cb435fc469c622c5916faf5e3d756f78a185851bf6671166e827e3cc429ef4e4060779b0d481c13715116e8a6020ae58d1c8c5346da6e24712721a49c95c69d84684a66d3f86b9fb3da2d66d98bdd89867571a1739240af4e12e0df7eeb44407afe5dc1f7d7be243c597e7c589add0f9b1a5535beaac6c7691cc66123d9c7245cb3eef4237ee7035723f2d7c5854e95aa2ab97515fd548ddb1589db55e4785055f83be39299075a16148abf8683e3005665f2d7abf3f73f9b39290d92714998a6794801dd69c2284545285e90b781df6462ef701887530b21dc66d80961af83b0d75c15d42bbf0338f590fd0b66be2144bd3237f110324326eaee76ef6e6feff676ffa1113a8311c3d6ece7d4ad5b82e1051ca71b364c3568cc9091112386c2bc94368d944d4c466f2ef5e330dd6e7709cc61662d1af42c28bfc6dceefe12bb6ef729e95e62a0eda6f87d57d5fcb0dbdd87bb8421057cd7fbb77b994de0b367edc7aa91e6947feeee1b77abdd95800855a0dfd736cd78393835e4dffe93bdc781df886fecf57774c83db3ee7cf8717a924ed215be0b216ef799e0cf55650f29cc370db71d5f76303eec9c3d538c5d0f5e8f982a7c29c828a57c9798c4a4d7d825e10adfa9e0eef0c6468feefe53da9003ab57ffe07fcc70c297330ba1186394d284ea41a1e6464d419a97c327cfdea29412c3b028636904d24b3df8796e14a3a2273e0c2207b1d6374a29a59432c618db05ebf38aefdec88f9a8a42a171dc7a4bda6c6757d9fdd6c4e84fe4dd87d8b418639c73d2dea22d6fee5bd45bd1dca84de5b701428c5146982e3c89b076be3531e70a4e93f4113e3d57e201f17be80453ba54434ef59fd8b70f5cb1d7e6d6a51fde0cfb65ce0e4957ac93bda51b62e745c02eda421e0da1e47c602863e46f1fb8eb41c687ab23fe46eeea48baca6e3958614bc84c76aa9c1897b1883c077bf23df6e4a3d893b5853a28e3fa0af659d7575a8853d8cbff30ef6d4e5658eaf14215146ba12afda769a4730b63b0873fadea16c6e5c022b928afe47bd1ded474517d8b2a3f3641950febe90822dfb4e662d5b00de36690251ab0da8f7158d5b00dfbaef2fb8a8c51e5f79133d991df58a4785265073db3a4b0523fcf1b6b71ea93d9e1d487c3d4c33a9ce256932ad949953cf5c381956ee00f6c6a7bf91ed814cccb1712c406f940ac0afe348d7cf9436a7c3c173c13a623a809aafc60104172bda85236e99d22ec658dfa75508d26823c7a0ad4217f4aee2754f9f0a755dc6a9ad27f35de53f9301bc72d2c3d05f2682c56877ce923a8e93ecfa8fe162d1f05c2d6c82aaaecda4efab1871c0631d8b0bbe6614f76cb3aecc91df65ea874d0d6cc981c82f069177bf25fba06624f9686a0f2fb49fbc497dfadeca589ca2b4c2325ed1a4ba95bf6b6eeeb2c59117bab7133b0275fcb36c8e1d0c05867f30215f49ba9f2bf47710a56f95e0e4ec927717d853d99752dc49efcd975107bf284f51556f50f8bc5626225bf8338b5a9ead3c57a5bbf1a5a6896a5d95a7db02ccdf6c04ed54bd9631c576d7138e36417f49bdf030a7d28ad5fd1ee84fdae5887694ed8c38a75dc624f7e2605fd2ab520bf0eaaf26515f49b55be7c29492cc384b633d88a9df268ad2eedbaf3273d73c23d8a5b76ca9a7f383585819808bef0c354b054c873a542d65261f6ed9287531fb37a38f5b98ff4e1d4d747d2c9d17ef2898c52e1cf1406ba822ea74eeb59b765ddc47100a74a0fd9461e65599665fd5fd72c6866d9c3ecb3eca83a15fea1428ae591b1a00e9f2fc78c8f8d3ce29e8c057970142d9bd977f771fdf88759d079380ae4e14fa08eae87ab951fcc873d1e7e88e91cc9a3c95d0f70739e5651da499ea6c93a2ddb6612f4c37c6a14f6a0ff34cd13c8c3a5581df0a14f2ab606fec7f5f327153e73e73eb16e95574ffde4d12ce2d409e661253dfc8cfbdc0763b52a16613e58cf9be6cb2dc097612c0fd904eae0c2a923188eca14b54af2b46c0279482b5007fc37519e58d4a4d2d9c9a31eb3339966117b5b785a25839a069aa8d4acfbb028f06510d67d33ebac3319f452e567cfcccc2c5bf667533b6bc9035f5a813ca411d4c163a5c2ee301ff68eb6868b34823c6418ab630b5b035f4aa30a7f4615d4ffcb58af0a3356c6246bcd17a78c38d5c3fc24b36a0f7f1e712afb197984b57290fe93473d24a195df3bcf9342f2cad6609143328b0cc2ea80cf9c1cc2d640199471415f062d2adb81611b58689a0679eb66e6c85c12f443d5c9d0e173fd6085023b254b564b20f30d7c23d710429844728c2ee690c400a94020f67aa83affb7aa16ba8999b3ebc8f5bc5a2d14b95b684b0f35d1164e9dd61b4b6751a27ead056ed0d52ad872d5102bb4b235fe730594e10b06cd49a9c9e4cd23e88732d5ee866c8d7f0bb52a87a5f1f77642757f8d3179c56f5467c2aa77412c9cda2a5e04d50f6af988a840e425561550503fc8059311eef070cabf5d9c3aed7812f5834eaa0f55c7e16f62820e6995d734fede3494aae7a2f07fa65f9b09b49dd1b64077c3381a8333f22396ce561172e2a8a8bd198891a8f061aaf93b46977ac4d0b46d7ef940302b2c6931629adbd8830e85edb319323eb26464c9c822bda67dd6efdda576271f5bfd6bd8eadd8e2ffce7e7541c7e79e75e301b0f6774321d5c1a9c263dd6652f349094d841939d1da8e0ca125cb0cdd9bd5b317607444f44396a96cb0a52b297eb78f38f886d1a473f868342e349dd897f57349e76277e58e56fede7a0a02f5d13753dd459d8831f040dae7598a69535a15b321b77f2df1a3f5691385ec8c274c594202afbe7f0bc2a8a2a77a82aa8869580f0b0002654bad30f9727e8a9fe393db43139b05eec6dd53458f267ce077892c00b2780a2490f6b45e3a1d4f8053071558e46b784c6d378cd937005b20026aedabf0026aeda1d9425343a29fd52fc736870529a8b559bdb0cecd9b007677085aaf5e00ea70afd96b469dc565802224fd082dacf251c505cb06a7748d0fdaf5b9bc5e4c072c11765cfa120027af9b0a1499090201042f86a5513f58b6a41e1179b65b0772835a1f8053db65a2d085403048240104b8b080241a01a5d340d7914424643746832b443dfd0465be58ba37ac4a953bf026a8cc161f8f810b9b6e8d76b6f4e2ff4809a2a4c85df437bc3117161556fb12a08e44d2a7426b5bfa85f85232a08b151e6ddea8ceec0f8f30e4c0627c43a974fec7cfae19bbe7e5261d7722d68276169e067f5eb2157510f6d0d7c1c9e4103fa75ab5bada2f1f0db8855d5781853bf6ef5f7cede34511b310d7c58a36b2d760c7ddd1afaba15d3aeee83810f879e40bf6e56d011a8c0840aeb0c20aac1284ee2c62eb81971a9d1680b976ef08d4b409c61bf7c4aaad635769f076af3cbd51f0cfc276cc43615a029157e4701721e226a17bfac20d42e3ea27edde48b55f1503fec9d21232afc9e25885c0bfaf5d0107c085953a0c154bbe3d7d6c077223aeb56b9024f6d22f6e07f5ce3b724015fd590a93dd4aa1a73526a32fd7b5eb76874ddea1935a05a7f01f4858f0637025441ab58a155bd76516bab8071d45b6a0c81c2d20ddc8d6d5d02d23380e82cf558538cbf476e87726009a5f6b3528fd6e1428d5c8c0a4b3ff6bfb81bf483a31ab95861e986fdd8ed7a5e7b873dd82df6206b68ab7c81a5c25ac261bf3b243570edffe1b597d4f68d39fa16fd50d1e18fde2ff8e2d409b6a08e0a9af00e4c41d8f3b335f0fbd43dc4a958e1779626f2963761157ce26a2d9cda2a5db02afc36fa9ce53a15cae8dddae1d4077f2a7c58e448ebc06e52e1cf2c40e8f0676fbabfbb1fb6063e57f8700aa79430810f59ec4116e4610ffe0b3ef48bac0a3fb25a059df4ace0c756dc8952a114ab2f36893d3398013f803e82ec8dac39a0cd5718c0a0ce0c83f6861f3ebcc2a97df804d81af87c621f9cea0adf06f8413875a3c2ff01326115f41112c2a9adc245940ab554b85c2ae48fde28f8397038f511000671ea94e2d60c15ae950ab9637803e7e0d4c9042b8ebd81b50a196d3f75dfb4022a43ab0200b323e8fcd951c685c422f990a6b0caa687c464a82ea949dd8fd4438a5217be738a531ff422b238f57193d3dcdcc888fa3997ba91c984dd476ad5a5375841492d4ef1d4ec8853cc5c482c66c9bc8cd88347ecedcbb05d3c3172ad92a0ff302441bdb731711fac375ef317cddffcab5537bf34de0de7b9ab69b8de781cb6e118688f6cd8f8ccc6bb8d8fcf47a7c7f1f088536e63834279debfc9c4dd112cd530bfbbcf6117b926f4c3a2d47dd3e9e38fbfbef9d1cff4fde7d9645bd85ba34affc37e6a76d4d5a031a3fb4c2fd37defc9e83e0f15a3cb7c62bacf86494033a0de65af0c003a14fe9715d57d2c0aa7e00d6e2b89fb3ca8eed313f7ad95e73e3efad68a0d1a6607b940f11e87e1ab55cc3c5e0c4ad02f3b621ee8a2d014bbece8e326fbabf116006e573e30c110786ab4a005364db30f03125ef72686ffe6c2f01fdd176c1efbf5d77a93813b09f1f6a80a32385a799fb3dad21d11b023051d1e2c75ffe38fb7442f728483ea26e9ee7878310fc31d51b8c2cc5354c4a9d3101d38d126caf8691f3633146193cdc6c0c23b2f226e93a90f6fcae8db05fd3628898fe5d2926a320618b36930193d749bbbbb79316e3eca6b150f41a8cfce07c6f14a060a283f377bd9cb975363f8e285080aff232a0ac2362818803ad355e66e69fc913932fb47766f006b414a2e5b08b9bb7f6fe1eededdc61d68ee1ee72faf296851281b5e158a72499886872a502f6d51108c319cc561140ac53242deeef80298232d998f6188a828089c1886cd396d5c41a8aeeca93999c79cdd3d7fd99bf3677f4fd39c1deca67ceadd67a23d9f605be4a62ab05ed32c033090753f96a6bf3faebe593706d45ffeb7434578f801b2b6ca16a6d4fe21adca59f5ac3a4ca8d72fc9f3421e2fac4a92ac853c26abee7329763fe277334da8425b06d21a5fcec7e128a1b47e356798a6df25778a0feb16e1d82113185a0f4966c57ee1ea805ca3f7472cc6f81873d862bb3bb1b918ff7cf66214babfdf8500eababa7083ba6dc951d7d545a7d22c51c618e30fa2b020fe0c630140a2928ac05cdc0750d7d58527d497baae30ac34c32e30c182164840794161042618c8034b851e72aad0b245123b34d882cb166ae081ed2183c15a931ee7cb462aedd30d81173e3a7861d1d30323aaf0000d586083214461052bf0a4000c29fead28d2c41456149e8085a585a7987eae94d27fd0050c301da7262a432915b02c91456271052be850da052ba84c951c0c5552dd2a2e29ea47a1cc00084940c2105d24618515fcacf81f85c222830758698214a0d0a0084f5c8941fd4c0c797a6044142bb4c0e4f50fc42a28383822092944a1042ef8c7f46f031858e0678b1457086309415491c50b725084235eb005125842f8008b140844c10509b478a9c0083ac8224a9421a8c064052c7801152014094e4c38a009275842093818421255a860c21646208494524a29603efe1447909ad0993e9b18429e40081a26a8e28a294498011458780a200d8b2634a1e352d4efb5d0821cb55d5a5842d69a257091832368e1043d2862d5388c9deabac2e84295755d611ccd1bf8a854b0042030907022075380d2802d88a2f841124f68190285ca228a1ca86c3982082bb610644416cf62b148f099989ffedb000a24559ad0320250115c6042164f88f84901128ae0420411522c9607fc60092ac842062e2eac7041e5a75f8427b60a472062a2488a249a5471e2e708294d3401b40510b0f4e4e04089297494782541c78a19c4ced4b680051e37f104284d749c3cf1411195d5ee20082c28a83882111257acf8b7c4a88ae5ab2b8c292ada335b80bb40a89f8c8e23258e6a503d0c1254f8cd50fd7795850549e86942ca162656fe9453eca4faa338e5bf83532fd5dfc60141f6065688048450b52be99cca51631735da38827ef4a12b0b46a834aa3f34716ab759c56f9dad12418c1bc4bf83b14e8a11f8fdb25392b392bfa520b23bed6a36cd0ef933d511e4c386203f4026426c56cb16ed6bb978a71835838d0e14ff0eeeee6462e61d6c89ddc19c3333c78da61a5136ecb54692dc45d86bced1348d0477b0581a89599cfab6cb163169e7540ff293cc9ab5e64ac6afb79261b392f15f8d19646c1a89967e3f07ccc7bc36a4fecec29d1dffbc36fd98d2cb520fda49622d7d978080a04b972e433576473ccac1ca9da53217a4f4d2750f51c372f6c6bd1669950d4cd3df3ed8b381038fc4b3714170d89afe1b56c79459263bc8ca02876a7f7f6bdf0f593e3f7b8d29cbc77ce85a9adfac5a0972562188f19a73d833a77d89db3824b08b977a68a46f9246fa56890008192f045cc950c9e84e41627c8c4e095c8940c6c7f89c553faa39c80daba37f72386c8db63725ac8b9c0d5bd36d037b1d3b0f870e6850ef7c49b8fa3369776ee0514046272546b7a52031bad3aefabbd44352c8da9ae6536cd2ae2bfdd0497774f611c48686acbdd9da5880426d1c4c38d8eb2cec7cb0c7ff896098860b34fa3bb393a47d64f833c31e435485306633750c8704da4882d6a8ebc2821335d62d4152851c3fbc02856010e5e01574296dda7b85091a407168b66da651ce14d331313486b6c9b4850d7605dcc10a0ae2d407afa87c8581f415f0676e948353ba586db8a810540254c9ec4d12f686fefef73764fc500c380489d81a7e22b008085ba43eaaddb75da01c0cda1a6ef8a7de2c5b8b534df8a196161f5566ee85bc44508761e987d7207ecac54a847f074e1580e115508769b8053b4839ae366e403f1311e80787b4186159960cfbd47cc6985583f636ad8af1a55f2bf205e6b71352408506a87088a6428f63e8da80705543fbfcdbb4fba829497ce1bef764fc6743e6bf18d58cffb25a7ab82a1a5f2a3d8d199c0c27835b4e3ee44affc221698097b8e592b07fc376137bd0bd189d088088f142c0558c183f572d444a975363e4ac62fc6c1ab601fdca8d031aa3c7c6178ed5102b7bf7ecb9e7413813c01ac3e210167b081288e8e0f13b76dddd9d65bf599665998c09676bfcb353961539e2cf03a7369e04fc246152dd1d8baec7c14cd46fdb1b2ed62bdca0faebc0a902547fcd27b0375185f21d5be35e6de480fa0f69d59c1b58ff22fb45f50dc3d4aa97edfd5d1301102faf9562d7dc02125053240075863f1b185c5591a629e2382de793beaf3375b351b798ba65757bb8aa18bf6d1f83dba5217d0c4782e14893f4cd6d5fe2e6f7c675fc2dcde79ecf73766d92b942bfc8114fd235fea08453f3b90577f885dba669f662077f484c89b4dfd83372423a65339048ef836866a872a551f9718208e941e5d78155db05178bc51ac1ba8c822a3f2acb814525f56d91f30a2a2f1121b74d235292341287636b60eb57da2fabb49fbf714a3edc39c334d98e2f28c923751e7b9c7133f3833a7eb9124e4132d2d3b9fbd8cc3aec5b7345923135daccd5fc96cd2afba1f6cb55863d4e3787c4541b07ac7a00a63a56bb33e2b4e58300f34e02dda50bf74bec1b5bb9ecdc5aa0824c38bc1c54a0eb7a15d5cff41aaadf34e1f0729c82ccdf2a84592bed69abb2e79f1a6ccdd57c12c744089bd5fcd65c69118ad691709a94713cd4f8b9bbbb8c08a85b02b253a8db4139f92b59d70a04f34190a5dc9bfffdbb20d97b17815d651d4b8e34d0b65535bad082b5da1b1ac4a11f6a6dd29a33e2b4d4cfdce9477c7eee3ed819e13f75e7fd3935a7f6e9c7e7d4e6706023fdd388bf372cf1b78c43ee02ef6abbcb3c789779975b08389f5f6bcd5586ed66dd94dcf743ed561a49c2d565d4947b330fde8575ee4299b3dba6e95d02ed82aecb8ba2fa4d2f788884306b158d78d1f28275f28f8fbde44eded1b08a5dcb8651edf9afe263bf2dd32a621f39b92dba8a0f4b3460753b1ffacbea72adb98abf252002a8db4101417c1cf6eed285b74b975594400356b1dba659f6b6b9abdc605b9bbc49595e02b72ea6c60ed4fe41a31663cf6de376353921ae7570131081f0ea2708947efb21a56efb21fb3bb650247b94fd16d59c55ce8a3d761fd43826da538ec9f6dc0e3028923daa497ad70092869cdabb8ace958020a062afc94deb6f58fda7c64969d9dddd5e7ac93a1fb8627362327af747d78eb6ad9282fd6e15e209705f2190c562b1e0d27856fd03952727c5dddd7d484b0a129b6a2449d7f95ecd59fde84702bb544e7ec631c95e0829486c6a9236407ce64a35e464dcaebc6309888c2a716858fbb18c93e20363dd3de3cbec7c607f8c1d092bda72ca35081debe07a1108efef770e562d629c0f2cb1f7d681d6bdb1c7ee8ddda8f2b1caed33f6e9c7c23af906d8a57a27a10efeb81a81ff4988c9ae86af2cf706f26824904beddaa51fdeddd6f0c76f23b1ab61ab07b1da7a80eed009ac5446d25db854f88ca4bb7479e903c3ae078c75c0eef3973fbccf5f7e977050e2f18708620948a56fa8442c98ca9a5432442410000000026315000020140a068482f1804cd223dd0714000c7eac486a4a170985610e04318a216388210400001000011019a26d003f377ab5bb613e6773c7b7ad172515035068d34b4714ff6b36f4da4ef25b18a866ebec8c5ed5ae3710351334a1fa1a35d8d8b174c1cb07a3cddcf370caa0a4f18ca71e5e99be454e27a5bbd3b4d9de8b10fe01d9231f0e709c8260969bde5826edd42652b55b6554c5c67c4d7150b093502931c43656081818b8e4e561203835855b6ba3580ab49429c045171e75af299afe39e2b17855625631fe2efcfd492ec320efbd472ac454ac0d48a413ca6d17ac683863bc003292ece4136a8965134b23c12d9811a31c2595432145f489df68ed5a99f95d0190fd1c40642dfdc45792c4d0df4a89242691056950718080448f40d6cd63c0ea76833a10ac5466b185d102a1a4e7355839cb5ebea1d23bd392a94185e4cefe1e6720f9f29400cd831ec228dea517aaa5eaa7fd2751af49dde8252993126f0f9581b70a8d136fe121d0b971d95314e17ec59010fac9bb7099e2554d4da0ea396844a78753a088b156a13c35b0eccd07f5e52c5748f32479dc65943ed57b9e024b7540fa8ab3b360f07ad38f0b4be0d40889f2839aa56db96b347e05a1a45117722763bb0b7ee74d12c4ae40f590b045b8f6bde26caaf3b7f07379cd3891ed63cd382985e53184e3302c1af07ae6302ccb3d0162060a79104d50032e374709d3b2352aa940126a124d79d880190b85fad77cbe4de686e74b00e1da5deb53274074d1fa9f4eff58fe56dfe05ed1b5a4a9dc50998fa3b8bc46dca3da9ac6d4d5e4878a5ce0b424aedccf5ed6175071495bab00615c6cdcc45b2bc936a77e46aec17f6a6741608de59c18565aaddf8f9a98592c3e6b9420226b4510ed8b4a4a44a2c55822d87c10f7293f21a2a941620984b42b51d2a423d1325f18d98a3fb7ecfd3cf49b48e4b259d678e7efbc6f2b21d87ba3151f0b7b8d3b16a8fb5bd8a3de6f575b6f462d367ddb2d0d6d04dfa37731b791b020fce10a45e8bb872140ff05f1fe61eda5fdf7a7cab18fe24cfcadb5fd4971c8d79274cd9c019e3c3c79af8af682a2ea5bc6855f9267ffff6699908005ebd5250ce40f72aa81d73cf979c417a32fa676b7e582309174706aa7ba44be174219de7c7521a5fa8e07609ddd62350b69e245fcb8f7506f9c9f803b330f2be207b12576284b970715b935c7925b216a1fc0e73f6124472a400b158805e52178a5c404a1d65c916f563415684f90bf0fa7309fe49d7c9eba8e64cb5b9784778059d16543dd218e5fd94730d675b81bfe103fef107f1bf9ae58375e39248ecf4625eca9d31ecbc31dff20b894cbdf73e49911aebcb04e34fa05dd270cf385476397d9e7c91acb81c6fc04bfac104d93f05f0f053c667b47348c0523852215fd47c6913073ddc5efb8378a65e143b861c687e438d9cccb30a89f7072af4b2aa5199301ff23dba48c45f6ba662b9a912fbd49533e14de2da404e36389f052a431bf84983ee5c586e2c73345554642e1ca39a4d0220162bd7e23a0b0e6cf0b1f051b8b9c8c9c11da9a91742d3b660994fc5a78fc09fdf2354dc9570ca1f3a798d40b861bc03d4916845d32063d460b76ec4e5674535bb53b1631522eb46873e13419d20412c24cd02ea3b0be9780bb0dd7ad4a4146a9cf9bea45012b4c3d643de2613dab88ed250903698938a8acc6c28cd685da380aef9d36c0f5a0c1815936a268d3e41957e15804be307f9ab066f5d8ef7701c57a22b946c337bfc63cabd55d7e2f1fab31951d9d8aefaa2cc918f74e3519dfba80947184987f5f22e05321df6a8ba96ba6edbaed4521888cb65a410f893c97482b2ed783d89a103583856d1e6108849072e3036ef39f6e76fe4d3a4b6111fa7badec21f45caf9efc9fb8331219df48783a862be17c2466eba2d3679f8e1fa728e84812dcdeb1c4e0d023e7f32e1f0768fbabe1fc896184363d9f314006a945ff67042a23813cc6b53ffaaafeb0f26480e5458c774b0a493fc8f8ead0774708975ca0d9a4069fb21354fc8037cb3c8849c2fa42c7157b89286b2da1f412556e66475199af4e450d6169a8cd68e07a65ffdd4c2857be10f02df592be35e5275857609e02980a7cf32b77ef9dfee5e6ebc6e5c675d3edc675d3f5e6f5e675c3fdc6cd6eb8ff19b99fbff927c4c5f109072ff7473bdd16df1df5eb8de6a5ac0df4edb08ca5579d79dda5ffe12a1d1018cf8bbe172168e0a7bbed5e2abc6d54fe26a8529266ba3c2477e67a6045d4e2ab5ef98173209562a4e71023df1a619548448218499e589ed90975f1c6d5aa394337c2e32f214e547d71aeeef764a028aae6798cce850b3f839ccee4ec37a4be16eb11e22033e67587b863675e130318f1d1602a414f824075f8357b151b85f110723038cb02bd8b462c65d0621e7993f4635267c8ebc5068d3df1cbb41e9b848967f232ed17db6dec092ff3151bc2658e3dfad7841f8a1e56c5e60c4d19dc88b4054a00ece8b87ac0793ebc1000eec281cf8b27615aa01f25e3afd0b8f7ce03c7ef8dd00898ad28e62dcdb11b408e27de71f3321341d9a8deb9f2f2db0471ca006148ec19054ee8302e35d9378e072dfcfd44e840dc61fa2550b52af66a96937c8a8cc5fe737f43c1a2f6591404c2729e645b9487e70efa7ebd05be6287de044badf7666c4ed4feb51193f42bb9613f79e293a96b204aa383eb9f941bed3347eef13eb25af4434358111b3096092ed31eeb06334504a4edf4dbe4ba59e782fc56495355beb7c5d6d9440b7a6e9489855ecce444c882fbbde221ce00c275921c6f93d8ef43ae1d47815c49201edf2aa880b29edd166c1748b11354ac7b365c6a14749454893af162fa8b78e3ab25bbca0ad69dcf3c3ab34d3a48ae6b4bf76e97a6a982c4b8449ac10c405c6cf077dd54940365253560b7ee4c4b4475403c65d28c2c759c53d7097235521fe5f5a8e9429965a43a6f548f83ca70427f05c3a35bed4bf1b4a95da7265b2513beee10942f2ca95c8daa5c073e6030fcbb60f5cff4cb003d2df06405e2d2655def0b0a1a7243423c409eeeb5d22a0f4cd2714d87459b6095b510db21feb7b7b4715c9b615d43bfa65f89bf941b27c80b1f41b48611daa2b11bda36c5bf3224ed2a4ceb1a377d3129b3af4a492815c298e734fd96cd5c056a1ccdb93527c65e4d47f11ac058d550140ca90eb39517638fddaace56822f30768faae5237e1f55c3d08f3a6321bcb90f8a599caf72c97404484e985f8f28e3c813507c10d42ba427ab83cdb76e86856260ed86b23e5a13cfe74041450f6013d516cb0aea6afa82aae6d1ecd1cfaad36d8a85acf24419c50e63da3ec8ee934cc4dd000e177a4df31d369901ab7670dfbd494b27a16dc6c8e8d77f585cfbf0c45bc9c8dc86a4584bbc24c1385289310d0e0cad3efd8a1a862d8b06074838b6a9b52dab0827a2cb60646f16cb4323da13615342c9cbfc866646e513f53a5b4101d92eb63cc811e198a2b76b99d21454e32f02d8a06c56446e4f90783f0d72ad3ca1f7eeb8e6ccfc8361495f79a53e1077d316e7dd8758c5d582199002e666a8a5e5c64aec2e37384615abe9c52a8eb4e915455144c7949fa9b7a7e69d81b275aef28d32a69e4cd4bc11e196cbeec649eb0838cad87536708627419d5799538c0924276af4e10eb867dd6448fcece16ec464d78856b2b40a8b2cb5745685d2544bad13666b4230d19cb5ab9ce9bfabd2a3e7f6df82b02e744bd312434e1c26c68a79f5a8d9c56eeac28360985291f9b020d4a4f30fe1c1da0668eee333f91d4208996271b57e39e7ac239b24d92f61561ee335007e08b3ffb5be396983ea0ed3dfc4f24cf8d3cf8a8f4a662870e057ce0924d031c1ba98bdbbca5dbdb0478352e6478089d96adfb243cd5adb2af412ffa8e85a7cc60d3bf0ed0fed6ebb638efa405bb183551b35f27da1abf6d5864845270eb8c284e1510f8cd8a8212aa13780eca6db6a02a406ccb9c8b7322c2779828efa72238792930b88594e3f7b14bde0bb007708869dc115327065423b7671e35380a8476a70b0c4ac28dc9ae62469a98a29aa88658c1f1fb472ea88de83eee85c72b295165d8922a560e249541274f441cea02cb6b885664052e1022fe209759114609260e06bbe326c2e73e725dc281136b5cf0417abfb3451ae9d83dd52657041ad6e7f70efc4b97ca602623581181f991d06e3e3fa25803a78d12acef6caaf1607127900b7225dc81e81cbf566ab1d005735278e026e041f3d10613981aef008fc75bc277bf243cb94f7af030530431d817a0bf7132e252fb3b6c64c6b5ad53b29290a38096823f22a23961fa0289add9851277f335edb08e90ce950575c2178dff053d927456ddb8c2ef58e68148685b7c4a07a1e429f28a71df96ab8b68d294411dd33ff1137600ab2399b1a2b9a9901fbccaa97fe886263dd8b4ddc7115220416d52dae0c3c04f9388ecca5e76ad5c84d09f60cade4ef45443733f0bcc55e1cf9609b4ac71636e7afcd59e03c36a9e2fe72e2de3108d2f1b75e8556ccf2218a9739721968add49eade57e3ebc15328cd1332c0f0c0e3de997b853c3a6b134da6865fdc8867a7186017dd812a1cb9026f321e49c27f409b26906afb980c5d95ad2042394bb1db3a7a094b4ff2eab417998f6eb7ebbe7bae9369b7521b6c87cd9a666c302ba0e4deea8a6904a0fb8a9b8f920420871230a3a4eb5e4a9282855b3b15f7543117832439fc1e7aaa3166c2bc45db3877a3b80569c606268bf6327093146a0e035134298f03c8edd736412c2ddfea52cb484618163e0b47848662586d1f4e19a6d17da0a561a68af1cf04c62c8760cce06f41f09ea0496fc186c4512cb54d265344864f81c47d58c043438485835d31b1526da80b46a3bda075df8616580db1c5eb11d701de4f37e86a8f11eb472ce4ccedb8884f038e617ccc486b6b4b34d7f39670a0ec2a013ec0b99aee1c2d473e2b1922d5b8deeb2cb9b359ab4ffd1293e64702c53a927288d6ccf579387a48622df94ad0e4540b3c0a4b5007de1ddb3d64caa4bc2bd52c75c9f901a973a0a41850961e52616f6aa27e4cf08c205b20704fa84588c891be84226479e1ac6411715d6dac3c00855e37e8633963f0fc291608a95132c856caa8b9b5a6ec7d62a15ac6fb4fea54299475597523ae48917c093ca6ed24d70138c4e89a67e8df9bcc7b7998fcf8f6c32a4f1d5baeeb2ac984c382b70d3d1c0a154c5dc28d60c2adbc70a01881e7d67c980f2e336c783399058070b2209bd4afd09e929226780fd5baa2ef7ff464031b05824a8ac42e889e85d9e6212732f4c3f30d3d8701ab37ad231a655a1ae023728a303557d5e6e98b68bd7da95b7b15e9ffb6b4de2daade39c9abcbc619885ece1414cb595c3bb9132b41e142c87403adfa706f0daef98af834507c9c0628962ab657a01d6e07e5aa1365d2e248eb7cf47b0a5cb42cc2b3c32f91000102ed721b51bf1602e7cd3d5a4f6606c96b6f3aa1745aa0b1a8ec0285e46f0a01d91c846d82b83100475fa9ed12250e13641b51128e5a69e7e123fea07aeeadb0d1627483797071053b81628c8bb42d0f5bc20cba0c0df9e844854704a116c3714381c7478f64e1daf2838d8fe7fcbb629cbeb2c21c3e060d1d39baf60068327c9284575ec96a8401c4791cc48ca3df2c1a1b421645ace5c1f66139222dce0adad47cea0174ecc3a374aa3d1f2b5e3e8b48748d85e3a940d7352a805bd7c9591e549b6a6330f31d851531a3f2780ea1729b0bb145e920610369e00446da2a428912e1b8509118fb39029bde68cf02093b047533bdf8d114c2ccb956ea7a1b90b6d63684be84d37273b9f06e65553e8ef6db3d2bcdb4e2bfc126edbb54aba3015dbc3e4227b96648af98671ed6d286f375d6dce40cccd60d6b2c34f910ba84dd22aae682a23a4676b7e34f3f9e0f347301ff35be4b1808765246aee8d0193030570510c2d16471e8620985b52f82282c0422a2d603a3d387599e1c247324cd74b6ddc7ca1b1ecb890a1c857454728a2b0474d72a7bb5163fa5bce701076dda943d32e8bea413af0e13253de6aa3fe9ec13016f30b828bf3be7fbcffdf3b36ef11b2a2bf4c8f95fa36aec40f96d5ee2085578b8008530dc2dfe6fa573f21702dcb2686a64fef40160e8738c1810b2ad7c298d37eb0a3953985f0af10e08d9ae67041d50d800c38028a0e38c7b9aad57b24752a67db9f771b5a959570e2efc39c8f900a6290d66f26cab4d3bb540d069ddb31bbb7e96d10cadf7dfd9337b95f65e006f0dbc8f732293c510cb8530fcd93e15e81564ea390a80ac2876b75f24e3ffbc217dd7d05d35bdaa11bc619e7734082034c7c485d2d4041b9610eb221aed05182242cde059461c3c0b818d4a0c03c83bbf864ddfd745f9a937ed2936394287350b4ccac57c6601b65ecfdf0a81c70e6e285dbfa38b2c47654621f002f12c1b33a5d4e23b45da467eeb6578f86f6840cda781b221c3f18b97ee9a2dcfef2a9c7fe16ede06004d067436990090c2585ececc6ee86964e02dec5de68eb3c64cbd016e25746bc18c491188c1d2c7fa4115bb05d1c8285ca51bf7090fe68ac50090f3a140ae70d88afd2d085b8649d146923f1facaa537badbed807b80d662ba08b0b728dd9f2e1193419b1a45bc6bcbd2418c07ae1b037c0b225487c7db855d19d05c4dcbd3537765cba5410df7b2fd08e030a4ac17b207bbd4cb9dfd6baf0e3d31db8918784055bbc3bf077316ea1dbabf74c831e5f7518556550d3e372ac08b28d3082ac26f5b145face5a8253143239e8c214cee939005d1eaf77063aa72b7e1bb6f656eefa5ab54d451f953ed61f788461d8cd50279074d341d1691668feb7ca4858e9d6c907e4e2401c4dc29077416014ac9f1345935b8b59beea17ea7d924471b9efd8c03971ae0d9bd40c663029954e9068f3974208b688caac6b1e90db97312e01d8d8cb97073cce05fcf85ac5fcbe831613a58299f07d9869d42bb3c84f0f448a1d9ea9850a457d590353d8244d423ea95e07fb494530d5ffd538fa03b85484d939dc0d59238cbc4726f7139d3ab699bd6a0aa99ba728aa1226a4235e6c09f038e7d3d3d28ca16ce021a2fbfd85c90e66281bcd2124808e92d5f1f9d46baa3577d93e58ebda38671baa9a212651f8bfc72b61bfc85b80da9f4d6aed850fbe6512c3b1740236bac56463a497df357cace294ae31493ccf5915e9d6313048da035c809e8285a23b711052196a82eca830585de3fc564e83cc0a965dc1b25cc0432e1db47f6d89c0969505151d5bfdfaf4cf02382dec9ea91e409b6411a26b5940a1bafc3da0c14b974a5ae1ba534a5afd108e6341f8f4f86bbabd07300007223fefeef8543fbc207342018e957b88802d6ea17b398ac4cb5a05133f6eab839537f6b0c89133f3a114aecab88bb776e409612419f09dea656c16b5f4125a3cca32a2c0938707e3663d6b8b2c0a982598d9b4c8b30ac2fcf5a71f858c0f121e871a09f8b2b259ddb6219cee464432e93b2143d405bbb5f30dabfb20260b2bad0be4cd45edd8979dc1905b57f50652ccb16ebf50ce68ccacd66f35816138e06406d5a45cfd67d1ff2251c29fb378f11410dcfa5d39886f3d6d2e13838bbbec5936ad912c562945812d4a02926e50fe89ccc29001572fdd5a0bc87c1213e829ac54a8bd5e39294e71e696941c1678698f5c9eb4bbd0c5b3dd834b54bd629eba7d45808c983b1f6556570f3d2ddde0860306105f3ef18b52632fce3f7d8511cd4d129180758890113d29c1f46e3910a1b7fffc8478a7e15a0c8a86510861614af5a86c66240533f6e2f5e79a997bbc05bb70fe5c69bc5c0dbb1242b2018f684a596e6928496b605db8962f91ad2748132247db5855f27989e869b4781c37df347cef335cd61ce99393e9c78dbde19e55099cd48251574931e615d6af68fb1830e742b6141c7347d0fe89f03866d4665cec8e188333df6a8168510f52a929de4180b4dbe97d2302d4dc733d3d057a0d44200eaa8562a464d429005cb804e00d4154df4a7e7572cd8c56c6f35b860416d80f4b164945f3551ee171b0e922ee3dd3746e77432c27457e49c9baf2c463c4eaa5fc1b2e55e84142773acf6cceb70becd25377050d1901fe5dc4f82777651ca2671a0994457372a88617f47e896365fb7d0d2630ef70d250fd8ad269a1d1b8d615d45b0e7947953867fbb8f82093ecc07501ae06f0699fd383e57d23427fda748868d46831683a375a0f2d522b6bb988dd8e5693d693882cad11b7fe74397496c79b7cfacce01232020fa2b13ff0b4017aebb24b37d2cae2ba2c8680ad70684ccc01923369eb6c08b2ccf3050a85baee3b5c7657c13bcbe4df0720766037f093ea6f3a745f7031b3367d24ac6f694e34c533c47838623335f49ad5a5f7b85e1980283841adb9be0a4b930354214391e796c051b3523d11987dbf4ddcc3aab83bc818191c76278c5e9468d01a3e9c3e3d08526d9c53b39e550b80abe04bc2193989f124ca73b3e4d373c7672e2df8d45a78c85608d61c02f81bfde5afab9fb845ddfb173d0e7c7719f65b89e3864524ed14e54887da35e192aa967a49e8712947449ccd465497a1e3f8e5aa4a56122385703260e781dc0e123be0688fcd2b4f655523941ab242aad40c461dc386c160a8ccf39ecc017c52d19ed38d1772b5c70d74e2a53232b020d75c6a0bdcec0d2a7e97114ff66f49aa358b8ab63a4eb451d5230351e20ebcfe4c6470b9825caff1e82b2d7fed3771902c1fbeb6dc2840f31e93b7bb44c18ad3244d152521210510b6e3d507eabfcc8f1169b1c503631c8d29d95fcff95221dc492a06a5d8f55decefef653e219e8d2d9c655507fe0de978befb3b694ecd660db1927c5460fcfea93eab27cbcbee0521ccf339dacac74f9323b149e9e50eba2bbd4e6d6f21c54e2fb489236e3266a0b0db1f27171b70148cf8404324384b17013f43c45f32690e92d3f36d24a32aadf180d936ce5e22a2f52ee46923b44be6ef6fa2e25bc257dc63d0b5ea5d6b7f54ca1e233f12d5a6c3dfac15e865f0aaa33e5d4b3cd44b62b3621c592e312da4c3884468c861b7e9ef5cf32d613a888320b8d506ebd336f404b7532da2bf93ecef13402278d1ab0c3cc38e2faf85a00508c675fc1dda1d407af9c9c9f0cbd45db155167fddc2a4fc702f7dc45e1205759e50691d2bb31c9c6ee900b63ae15f43c32c99c3d7843606f724374933b22405aa81700fabec8d034a6453f305f68eecb3883a579d90febc625194b9a84034fb72a95386aaa662e6b2b1e6353d5e3416ce3ca67e7463845179c43f633199ac4404ccef2ad050cfc2b1c575b368e14d928a0759f34664f3d078e56b17a027f3a62e19cfca5bdc81e5eb0cd7f73aca6a40adc8c45fd6d3ccbdf78362ca2f9e8e2f07e39b571dadfe9b08a959def576d7d7036b8421d45ddf888e6a0cc384bc57126488d1ec6779d9469f4494e60d4467c2e12223a7108ec564e2925b9e8f5c91119c4715a42035b4291474eed855cb294d69f232029db6b03b1a1751d34b038dbf934eb81d46c078fcb474516e9e04e72c4979478a2fb8697715fb18114e0e0320c3bc5e79835ebee5fb3468706b1d93d96fa2a3373ac7e5e28182740483bf5918405222e13641475310e63ac60295206a11fa141d1014101a4fbd0565e8845760fe424294b458a66670dc144aceae853a3009b12770926346606fa01cfd1422cd536bd7a34849d6d331d7370dd0adc365ad720063013bbf393dbc3abab4986280821944fd81837a65850e83eeae9c9e52c5fe403eafebc83775203a14a3d0d351cd0f0b40f6a9bc8340168dec8e6aa8b588885f687a1758a2a894ee7f7e5125d522cbb5f0389764815f3da7467e0e88f3c03ec8d2e15bb01ff53e5fbc22fb4211fc0dbc0472aaa8cee97bafc190b33b3cd1ed1bb281cf6c19c94617c5f496752448656e1abf3e37c3946a25845c2efdc8efe6df563c24334103132586c1aa7627fd95707308f33a693e7849698804bc99b6b0874b5e8ef94414c3320406021455faed68f05376b6290dd288fd50227966070afad681cfbe241ac50155ba00279adfe2a6d842f14c6fe54115efdcd503a264cccfc7dc9095ae909fdbbff6bfb881679b9e3080c4aecffbfcc043d7c2d731a652f60737a209361500c02e0099f2e9befd39d5eabba98626baa854beca1d51cdde819368b67195d12a0c3e7f0bb7df218d6ec85ef0757e764b87d00674148dda870d6e5cbc4d1476b30890f74687b7f64378da481c37183347c4143b0daa1aa4c6cbe35a98d9d61175204c73603e6814dc6cd00953b0f10ce6a5b3cbbba2e703c9fa0879297458793d95ca1575e03ff265f9a9b569383dc5e94df14ba7204f34aa86e51c00df341bc3a8eb57df6b135f16b01bac7da6ca265af0e8ef8e53d2f69dd9cc1b84d0a1337a8cf0901768be4d5a23a82deff1a7f68866d9280d7df16417bfca2f30ce5b117c81c7a2b2cf789ef2372465e31a9524fa965c0b0a2da0c325d0f69720d25bd49038ab1cee418a6e2d4b8a129f9dae8d07e64adaf9cea2485f477f03d72609bb99b0ec600af2a1e0a11946d18910f495872d1fbe0e3090271c03a9e74095da90234ba249616044c3d1038eaa3183a8aa9a8c84d3b673c7d840476830e244d1b19e6fdbd6c05bcf336eafa2128072b3d97dd345061b144c4bbcdafb0b16db59a2bfab1b847ea40d183c1bd7730787bc1f91db15e7b758a966992baa6837608eed4519ba45a1b611564788fce29e0f88d5c11a26746c6ee0a3e3327efd8a31774adafed080d4a49f3b0164903009f97ab9e532770ad0cef7beffcb607216eea8026fb497d6a48e4c0d8706282abeacd1a58bd876d39e5ad8b54e78a5f28881af27653c3539fd06f6d0d66463bd557441440469332b0272793e782eff237c73575fab3a030bfa284526d95d89c1b9c041ff0b68113ba713e191e2a40aaed97bfe44420a1b0954480d8fd5db81aa31e003afc0c292984250ed599b2df105124eb7afef43045f617c544424b07f241d151509992b6f19c09479a5c92185165bc595bc5a2e02b72bdec2eaa386667911b5a54d2c1f9e75886ecda5cc1a5af1ff3203c863f98a20f342da55da62b01ebdc48c93d3cc5b72171df8fcb62b4bcdd533d90d493b07ad2428261984a075387f702adea3ff1446183ca1bd706d870f82d6fdb22c8ef905a7cf0d34ff57570eb262cfa2e6255c331b4028c215f1eef3de545e069eca52d5a3725b57091296aae4b1ffc87987b28b2e591d4717015e6319c4182193e4269ec515993a83aba7c21b935190e56dcbe33aec6d6b501384c590fd7524464c370043c2becd636f574dc18d26ae1c27909b428be71190859d94ba77d6d64151825280178286b0fefe7f6a5cd8af505d0ba29c05bea2556acb0fde62878136fbd99d26e290816ca8afa03477d6be4b0eb4112c5bb7dfdcf962828bee15ebce9ad9bd001771241604289db16074947eaa6201a308eeacb2bbb75360e4ce80c32a2d0de4028c00d3a9ac8af175a42bf564b87579c1cb37f065751b9e53e067a70683c34e02bb34b95736acf6b31605654b86810ee64512a751d395159f52bf1905d156b3ab709f68b94b976cdc737eb6d96d47b816e91230cc51ac78f7de223c70364cc2214a043d4fb9349d26e94309540078b1f1472bbae0e84893f523c31440cda29c352a067983868b1cc4935c0981a7674a89c48fd3daf4524b300b9956e54e9359ca7016a9f6c29b1fedbc99ede995b41617240a0c9ab53a72b7996533f3584d3e2c6a0011346173ec65ec01b23578c0c358c0fc7af9173b081689c5930ee4b510967c602eaa2fbc28f56e66a41854363cad7b2ae0984cfec4fbeb4e96e5d559956ffa7fb02cc8991dc870b08bb8606ad9455950e9406c6b592f9d210950fe58fdb8ac101cff9f60f0b60fdcdebbb473122ef8730552e1479f462dad68a993a7dd1981b21634bbcbe9294d41493c87ffe26c1344572f38ff84900666250402bbe0fc1e86ef30d48521463e973a42085da45dd18ed0c3d59a56446cfe06fb8d63941d79a62f20715800baacf3fb40c769d0a7f0c290dff1764538a7e37f65a996939fba1d841ba9b90abfcc65e757b9488d38f884421da665881021f1c4365f1291e56ef5ec76eeab0d204c54835f82642a13fde36fbb80ebecfe4c8eebb56b13906ed4dd22829b48a0f530b6824a262be77b9171bd08d8c7154f5c0e90fa4691d8fa696a7835020c1841c5d549679d3473b4f07d3774390e8fca31f8c8f30c524a5eff708ec4e0f53b3ac9da378119046f14693918ff3499cbea0e0ffa0d6dcc21857c905c558d5039e1d0505fc174d2faeed90a3d1a24a80c6b50919e7f5af72841c03bd895ea3ec4c84fe85075c307e239f915c38262b98d49612ac3aa4ed0f464480ad3789251b2131012e1bea8efce99b60d8bae984ecd3f6696a61a0541d275d643390998aca62a9789c04de27e5644fe52182ca337614e3961df5ede92c65cbf8a5c6c0cf4045c229310dbfe9ef8a3a42fa34abc7a606e7e69466f8486615ef139d4e257caf13eaf634f6188bd04c037736ea6a7bf783463a23f40802f43bde08c80528aa6422f4b869541100a3ad677c41d28185c86cc4c3b509dc01dd1581a1f09635c547ff7b3bf792cefe3d3104040fea7302438492345dde3ec9cb916a01891323a9c34f5b38ceabe47c1919752dc444711de5670f702142570227e161541c4d1a900e32fc6b09b4e1cf4082e676647ecf0404c70c575bb90384078b340a4f4ae76c5c1ba1088bd518c4fc14d8c32e0cbc65c0a2cee3fc6edd5ccf2228f93a93cd622082c2cd4ee614776d45c67021e28ee6ec77e8c437f85d923ec6375a8d3d1500eaa5d465d08b9eee0ce59b9191dee77e77c37695a57a546d13b9ccf42bc8fc5bbcd2f70952921c20694411858e0225ea94d7d86d48e046833cd401b72ce94a4415233dba5b983e06a662b69f21624abc613d80398ac2177667f56489b48fb45e93c95636dc8c465aab680f040ab0c773e10e05cb129703c1000b5fc0dfc4f32ba4be3d9c738a9d6a4086c0706ffc4d1ec08bb5f9fa7df24a84a3924857410f2cd3e9186b42a0010fc0545b644de56e9ba2f209d9b6f95b8eacddebc8e2dafc10acec466e455d186e27443134b6e27f591f096de8bf365756a7eb12743c33ef03531a8e950b450dbd170524385d6d2ac9469357be0fce6a3401f647c3dbe8e8343f13000f3b624ed16f704855cf53804dc2af0fe7210abd5319f1f6558d5ff40a4323601c95ad2661046d2ec327f660e6b69aedff825b90b6ab01f5354e03d653ebea6270688e20095c6492fb5ebb6268851e95f27e167b77b19797ddaca6518d7283ad3e5eaab8ca880cedc37f667688085d4a29c1d791e002d983b3c31a87ef5229d3083ded95ead402b78f716989e315619b641f11203eb49b1a451b00701383e382e080c84d2c675be7eaf48452879f88d7516ca04baf1d5fa54d610f9798cc7928de56bfaf705389d6ce4438a16b7848ebb9f6ab418369c51f72f5bc16e926628666dc63148df66686deaa9d45aa2f36e54f14538ce105ab35ac04c44567be15387643ff0fdb6cae0ce9c3a85ec15cbe485e0b4e96cb12de946be7319c3527b8cecc58fc1a92e687ca66005e87e91fa5622e978abf8f508316a6ca220445901048167d8e7bedf98347600101d1c120506002028eb1750ab4c2be3473d6e4d0aae7c2cef6f8577a200bb1e6554b26de6e965c2594d76ed3167b341c0c49b48946902a4d808b82e1a36af0594909891cec57a4486581e37c04c89daa2181de7104f1c8308604ddd1e029b747f9b7af0f228b8690cfc0c9b68c5a34fa7c4d078dd5577bdd7bf443d9cca7823fc1635b5c0fae65b621276768c030c35d9d073613591d5a7916ecf5af7cdc0897fb68432d9e93f25ed5318b86a6a0da8e4126a42a011be885f0bf5df2071412bfecef2b8cbdfa90bb7e2ae8702e85bfff1e732bf541dd2cde0f5e39f498b65be3b83933cd624465b722a4e52e3038d4efe310be15d4735ed0570be421de546880fff9d502ea49ddb98dec4eafee9c93fb1bfc77461fdc35fb034092401cf74a125015b6f09e52eed0138c4ecd49ee64380515da49957512dad8ee044eef060b7b1debc48358e596e49f3f82fb38179e4d3fb25cd99af884caab2f6764613ef18030df31784ceab1bb40e9382f4aa696f334f908a370ddc14b70d316e9ae93f82b81b2e66a5742bca027acc94c7f1290aaea9130b9ee841123dcfcf6abbe94fc70621c8af7e09ad8b3cd3258f3621e1622fbd99c661a8431754dd49f7dd1bcc8a40c81628f2c0df6e23fb897841dbc7b82c2ab877739ad4e43f7466a987c20c4a4bf0e286fd1a34c02194c46280ef30eace9cbc62dbb1c21be78599d20979a5d8a4ecb31b5e8125031da50d8b3e645fa062639bd1ba340b2e22fcf06ba4bb2c58424ded7fd7c35068966bc859fe48fbf1c2e770cb89de049fc393e913a487a0c228c6c66f564f60d4c248247a51912a1b023ee9e92d43b3900ace1e1ae30201bdc4f59a8bbe512220a65cab16b6e952e0f98c7750bec33a11b96bb3eab5b03b4e03f338748eb3482e665a6648a6349291d068c522be61da3689a75749551c5c9e82aca10e62b8f05bc3e2882d4a30edb55d8f1b3ffa6f2d10d26f52b9a38e590aaa0115e0992e3406e09270f03a3093b26d5a9feada1e7aabeeccf8fb128be603fd7313c5e9754fd074a6e533d6033b62625ab2cbe7f47642cc719654b3b96f7aef73402b1241399e6f87b63dd6fdad57aa28caa1fc35dc11d0f6abf552a2a6a12b9739d226eb8029cf4a6b57114104a492ad170fa75e807f24c175ecd20a31a3205e51248fbbf7907e1887f013634fc21fb051d6036cf8f6dc220ed39e8d3056beed5f593fa00357b9c17327d14c480683390b57888e0aef319fa56805642d9c58965676340629f1729becedb473059650264b1bf2d6e595e7eda059f595a7edef8792c9e5210ab5322f509ecc5037e759e8242496f119a56d6d7a6b28985d7c10e23dbbbf127227460fc439cd8e9c30874c80c2a1951c1a15259f12644173088300c6b80d8b840cf6bee1f2e0f98414674ee7f323538b29a5f10736aa39743978479579f40c5ef5832fa211e315415578162ec1cfcfc0ae524fbe754e3c15c56adcd7e1d1dcd0cef8b9b7f1278f56762068242138372c5edd1f883f9ec903a12333966a5c71f6293623f7a63648e5e3d7924569765104b58374ad2c2654158b1e94c3ee075fe40b20c52c3da7450fa7a3bbd2830652121f56299af10a5739b87328886e26d810334f30481695bdfdd04650eb668628b8a487a6f045d423a90ad6fbd112059bc812c9791f9c4cdc9d68cbb791b19af03cdb7756b30e9a0d7041b58e091507df2eb039052d947011eab0a72046e9c55bc1a45f708633ce5b5cac508e2018c9a512fd48891f21888094e6ad3ab2bc8cb4ae8c804e0ce9ffcd5004872d3045cce3680e2f676912562a57f6260778ff8100ed544454f6b672e27f5aa0505ba5a648c61c13eb16579c76fa986fd82e6cd63cdfa1606b17d2004f643ae1b0fe0b13f3eac65dfe906376bb02b7e11c17438ca458b01733af6915ee5b8690fcaff7c0af759dd167b599dfc6cf9aabbca6cdcace2a94deebbdfca5c11e917e64cf961cc8c29168c410eca9f3f24fe23cacf51cf6c8317f69c2601b90ca761b92f3e2c063f5df41f9390af587acb014f8a19714c8de40dc0b234c71b2c5a5b8382c0cd9cdd1fc6e1690d48cfbbd17d60e0f325ae3feab4f9b7ac016bad58e96687a308263be84c924c03d663617ef8b2f88ce62381935dbf9a5b275a3ccebc298080083cff471d819e23713fe105c30c203e9ff99ae052fdac47aa6ec924e5a53831a5fdce3251ee85824284e0b1f45676e5cca603a45405eb98fc64f4bf8003d736e869ccd99c66fb4f4b4ef1387e0a145d81eeb6acd91d7ef274b60470a04a32d43fe53f98c2475149ebb0a425a3e87d8a16d664e5073abd6ba43d7748f54757d592b8c4f857b51f9d692a5a1b4620da0d95a48ee1b2626b75cacdb17a34264f91aecdaf6ea5e1a2a381a92af3546c204fac86a40a2f01f606264f4067a902c4261e1af98007c2c46e3148784b0bcd7ec6176197d64b76e104d7236eb577cb88ff4a3f6530b4bd8583a5d100cd02db88c64b6f5a2a456284cd022cfcd2981e8c889eb54464ef1650c1b0ea803974e05d727bc01723ec65d5dbd2c64195bc2f02acfb62165ef97ebcca9295ff6a31bfb96ed8b9c43e70b0e29d3925d43d6d07c1d058398c570da909dd23be25bb2c02c1b9a7f1885a5d0f7bb13317c76a772e698369948411a38a4a8161d0dd8be8eefdb6314702ff4ca8ef02da3500cf1b399dd291d086f008708614a1a5dde41ed364206e13f15fb00e54e5e4fdd7580e5bb09b507c542b09e2f46a82d558e6c640df3164e51d9aac1864cc9b982d6c8057ae2d6fcc31ff22533ccbb95a2df33566e071a306158dc01efd77ca1ff1a7b661af5d15330f2ed55efb73d8008efe6dbea3c03743cf21e8f5a6b0828900370badcd8df6e51610c725378646c5fc300e886b22104343ea1de191b41a05796c850e3b59c32983dd6feabbff874253292c6e464e00442ee1586b0b9452002650b7e147c55ea8aa6ca6129ef227f7b6d7c13442e7b01f48d98c47870328d9f961d9bf49911861d935cb18ce5246b04e0f3058d33e46a9f28d6e156dd62b5c633440c8221d71a5c12bf5b6104acea94e69955e2119ddf65b9fc2ad3d5a0524ec4fd765ec97cb9003135ce31d674d239b0a16a59b8021dd91aa215589618ed0b2e3fe62c57f42d1ed600707b5b764abf009daf8ed9d54d458a4b7d91f51a8961229a4ac01d6cecc9d9c1e0125eec0f2ccd9bc400e3a6640a1683e8596760ae73bcd9469bcef912c2109f0675eca2438a8313e7d4c06e087d1f8a07d8f50fdb963142c75e43d59801921701004f08b3ebee574a90c92066232a037b9fdd097e325f300b6f1d6793961180ca73dc58d9d5654cee84d62027f215736c2462d8e8694ac8039633419c563e7e0eddff8c591c5bec7f5e34d809d010301a55c65272a1d50418c7ed0edd1886e49b62e8e0363bbc8fecbc987fd5bbe31d1805251d88514cdfbf7d1a113504bf64133bbd776d5af1fc3e7785ba58d4334fa0033e20b4ac56974ea8b35bb11b8de12a3f2af067742f0774b2cc99645e6e3ff048887514dae88af3aac78f2257a5c627134c40a14aa10f42c8183d01075a6e60ab94012e58a7164ef0d714ad96b27d0395a7d9df22af6c02461e475fb1c03aca0e515831ce2164b70877ea4f359036289e1c257963aa827eeafd8f1a184f3dbec109f7728a9f03fba01846a9d7121c5bf6957a00a3c95e2e3effc5cc96c214450a383cc00eebde608a37f6e52c53802b6820b1208622bb870204332df8cb425c0230bd3faa6792f514462c0554c96b39301f7bc884c07d0b2b0ded407a6dc6829202e89904385e4a6c2d0bf3550ddf5007e5d4a18311882362ac5792cbf12b0ebc6aa7a358f5b18a72cf9821d7f804ca206bc804a0ae734bc86573c67e1df8b8e5f119274766ce6e6ef295af6706876065bf6b7535256444c58445f70e80901587d9b333a6f9dbf1440173af9e1632565ad9bea741eff3896e64f17d73427b24bcdecc50b80fe31ba345c84fbc7b3d82722a46070faec51879c1e5fd0b854eea3e09e2c0bdb009a06b7d5188c9aa1f904185bb3bf1fe192b7eef5ef7791c7c081d986b0304e3f9d3fd173af2d3bc06736aa03f50ba787f0d497509a0cd7a16629853dc84a8c852cb0c9b1cd72112120e5ac57f339af7448fdfd003dd04ecbefb19fddf55778b869d191581182c84da051f55169196193cd91a6dfa028b2e6411c7309141222c2d61947e5c5230cd69df1391f3312bac67045c1adfa0caa9022f5cab051d5302e36541083110d2abd78e7e1abb6222e1d488dd89a20e75a1112c001c4fc9f8747afa88516463aa48bfbe606a219dc30cef0af2f8d90fbed0344806558cba64997210f779e9e45f2b080c3499416fbb3eac1a978318ed9f4fd34c6fc764a689177105047697acf52d93e8472a3190c6798901b36dadae0864eed48165ce57765d61272031a229d6605be903e38b3ab044730ca7f0bf28c182cb4d892ecfeba20ee72dd13d7bcefcf92a053ca91ffaf301a486ad92fb396cbdebfb3920864116a41a1d9dd27f5ebb53e4dc6a6fb4d656a6f4678b7197132046141040add4b2a135c027da490c22ce2ef5fef5d569ab94275f00b9be8a1055fd0055a19870788f1f37e61e9bc24c8b4f1852ec1a2c3e622a73ac3aa7fe57c0d2ae1bf372047d1dde0b6e46069d71113e34824b9bfd6d7206d706b0df6b389a17441954b45665bad78ec6e24a5d222daa406158ee49db4f3d964f8d7d908a132a805b65b5439f62f2a679c764b7260c2eaecec3a35019a0ad9fa4b35be9dd113fbd9e3858ea8f243c038bf283856a14642f6cba12abd3b9c7df3843e148522d2a5906b93e035ffadf996bdf6c648c45c84aafbada85302d3053b4c9ad653a57490ae578358f6bbea9901146417586e9a11e57cf050a4d574fe8087db4b98035aa6e4c84c416f19832c0737f5578829dfc64c38ce32768adb9c81cc655ac1d12e19d0d696da098f8cc2d10c66a7fb8b7004e71f91376f2f35230988784b8e911eba83ee469078ba79d1cd8097e472ecc0d5f233bb558e6dcb17509010f71c225cab060d5991004bad2014e0ff4eacae4337dc325acb80e63e9c5963b7ad6e52012ef07748b21b7b5be9eb79dc97fd8820c848c8ded194317ba556b9b58e364ef82b6986629f56d4ff65aae25e90e94271f0825996302c5cf2833cb825895c97431e5f417a483b8e7f3a61c3fabec64f8b0688be30a1588d2a337a16eca94e4228e6c5e608586cf6dd13345b408b2650a62073ea6e3038a6e0aece2bf6800513041f4073de9d53888969ae66142d5dfb7e2f0ad8a99607f2deb46db4a1dce01b311608e7562587d1adb9a1e9fcb326025410c629e0aa2148a5863d6a9c76b353c67c43ecb158ff0efaf596570614edba03f98e9f55c31daf8a7f4d8200defa06055e14337a8db6af16049fdd257aba5f76c54556489ad91466f800751c79af635c37aefd3e665d57c830805428f0ecf2fdb2caaaf55e2d8ccb7f96219c2fd5306d931771d8e206a761300e50a937782372767f7edff86c5adea81bb92b8128cd17c23313bca0dc00db8bae083496e215a0de67582f6f20ceb75dac2bb4afd98f2a6cf9dd780eebcd6fcb66203bacfc293944cf93aa72441c23df722f07c07161bebe940464f8a8fbe6f9e3cea2cc834b7c30236d3bd6db17479b14bf63b8442aba68ac1e2573b79536e6155aedfb17b82417273558261b97f9bbaa2a80ea96273f1e8df597d91df824ace3452377c5b96a48bc8b434e838d2d95ec218a35799e81833c067de69ac2836a0f57cb37dc07396ae0bebd0abbb1072bd0fb0a2c30b2d9155b304754b175cd6d94cb4b44758ebaa38dc8aaa5957a9dd012aabf7620fc425d05a30979ef357253b1227b89569b685eac691d45aea740f30701b341b51869572430f1a1c70df06150df65eacc14a1df08d446bd51ba730056b143b086031a500a2a0129211b4f45fc11b311d37b0d9e273fb6b3dbd0f0cea5d13b3a67e5856a51af7835de2fa32904366fad847229dd4af2a72d3ec12cef9e301d8ea34b18c6531867e4127fcacfe419240b427c662b6fbbf0a7b969abd2fe6484fd6da591b8e03cbe21dfae0809d6de5b0418966ea510503b8f3f3599050b6dd7e11924f429dc69b2d1f82d9305a7401e716fbfd53f8d51b0b7fd5f3ec53eb0fe8b76062ed9260a740626f8ccd3cbeb38d646dee589075d039ef7208f83e3373bcec38b05820c05fff0b681ef98a384bfb1b933198f2df981e8445729247cfe186dfc7c756683914e5df31296b162623309c2f86db977e1acb8904f8ef9e3f3665826c1c2ddb5c3411f8424d040afc982042b8845f734d2a7c0bebf0f0da25684e54bcaf4062271a080c3a9b81f601378c9ab74a3a22d8b902256efa8c48c3ad3dfdb295c5fbecf286eab755cb8be7f5205ec61f17bebf8464f817713224da978b44f8dcb9a7cf720626b2a47aa3360b91d712477ed3c61220e6029802a904ef16cba696206f455781a71bb73f0127bbd002670c9ccf1f132ce0a32be28fec58d7418c1f3c5b4b0681c3b73fca26077a88939f4960ee07721f1859e33f9b8b2191022883e724494588741e2fb858c1c823b34c20c2b1b96c609cb396d4ef7891870ac572c5d5c60e60f6709bd613e3809764109305f01adae46105e533602452572f8690f09e8ae449ceaa82386c90d62c22c5236a31aa3589c6ac38f864238ab0bee3a86dfd674db6281557a9e034975d3da35976d6a3a42cd87494821d9dd5ca0cec2753d1a45f6f2dbae438fd077500bd3268389c57793af96d834854b5f02124dca720def1c66d285c63d316ac4bd482bc492147c60720ca0de0c1f5bc4608679e1226a1150a717a45c66468b04714ef17f88ad968169a43c80d6c7cfb8f50dde222eb957e7ddfe5ab517e8d17bc5aa3426097ab67ad2b6cb2d5a56e70494673a465868277ba7d2d3f5654d180fbb6cf727fdadb85260e3383e183ab0db365dd8b661a2189df0a9f93c0fba98640f5699859212933ede180d2056bf8fde789aa1317020d220b5236fb351112c838d25f3bbc054a197e76e4addd2b0edaaa3ba1eae32a39aab52c1a40d04f85e281a69e5f24502deabc3862b004d6ef22c6ef0e97bc0b7d3abccec9f40517bcc06cce9e5e83ca14229120ba21b1e4672f6a60b53543adb6013fd60c89de7bf59622350b5e054260ba5eaf461269d222dbcdbb3b3b1ed46269929396bae63a0ed98db64a35791f5a307c308b242182d1f881335e7470f24145446a9d71065a02759047d439e714783dba45693f8f9de0e490b834bf861c68d9fea284f4cb9c523efe3f9393591e25ec9cfec12f8f37bc8e42dc3664678941ad2768c73927711dea2f42af9256617bd527f339c68c3f95bef715b442c3eef239e07525cc8e68d2590e6d4386b111b42ac60507b9c4048633a390c89ddd42feb4995b8bcc71d27acd4d4452d071d5f1a7327f51b86b8b0a747f1b46faf80789b81f4c323f67256603040095a34d6477f47a17098d4661829be1be804e3d69e95fd3a0a3fdc4457c76de7908b73dfcbd24cb5cf69041be019449a573b5d6a972b1dfaf351e4c20224e70323cde8986d509413cec84b017c7f3de1349a6b78da62b5389060f37d5aa4165bd11c7f6238de1c0c08deb6c760e108897a9e5a53f281e8863d1c4758dc0a15f3e3e927cafb6f5bdcafa920bb86924c119c44e1a482208278e222140bac402068280953cef01e60838b1da8898112ff941a4969c496309ccb300fcdc7ed72457a131f67886587344b15e2c0b8753faf395b432ac1bc82af3a2e0967c250532f0858fb4f6bba4479952b1795a2164a78fa9e3aec4203aa5131281faec613b4489109bfb9d1a6ae516af4f11953d65f3b1bc15f2d66a46ed473caa07e321e697b06483957a0f1aad5dee791b005fc57580cb4b4c0872f597d7d7b5ebe53b9c34983eacd97a18f83cfc5697f8f9d01fc280f2af023efbb1a795135a1fac6d66ae10285bfe7efa17d4911fa650b088dc6e393340ec6cbf9879649c27f59733638e4c1d260fdf808ec9762254e6cb8b66e2694933db23a8052f11526c75083f212ce0b63831f5ffd93acb91f9716d042706c4d6ce06350b72b341cfe54fb30721a97e5a2e203edbeaddc482a634efade976873fe04b93679877fa4e17e1ea812930c4a755365466517cd649e53f9c7dc99406f9687c1620636971419c85cc37539c80823c9c4472e50a7c5e95ec1bd725c02bc768d31154bd70da3b2e7447ae8b438c6387d772904551fb9ec94b8b4ff52c3d9403a6421f946e10197a016be6e401c531497ad9ac3317465d6dc5f676bdecf28a67b05380d5205f05dfcf1ea6bd031f704d3819bb332e8a57cf1d74d66c82470db235f66f96483ee3b6f80b4e6ec1709f26c59aebb28d54b757a3b5e7d4b4ac6f53f596c6d9f0deb1f2ef343311bbeaed4320f22837114d58880d05b250203abbda419731584f001d30e633aa6f8395c04e1597162a0c3ea572e58c5b423eac970b180fa25b770b9380c120bb37e7968ad5da8fb6a58bbe1ec88f368a628a8cee426274f5a20134d933d785697cb3b58859573addaaf3e0adbfe6d182c2aa56d8e52d0270c2b44813560bf3739ee468ebe74e1e8d910885dcc48504a661506fd7744fc0091f8f26d08893dc85b0fc8917e273f129350bc268ac897f1792c2752112c64d3f2c18b4e3fb38782c3354aa0b81689dd087d742895d23c98aa26727e61125f764f4b78d78a6a82c543ed5423d88e395c2ae7e279794d67a6159c0faa5017b0c4bc03d231d53cdfc3abe089dee5c4209fdcb93acd3c802bcda62170d47156adce77cdaec5b6801e07adfe56153b80325d3a37df6fef3bc623423daa63640d08dd15a8b7a2a4f4650951702fcb5307980ef1fa87d53d874931b0d4e7198907b9c0cd1fdf87a79111376184e88554b08143c091235197971cdce96407d2749fc271d286c752fa1981c2871cc049990f6eec5c51a657fcf4ee7862f578562df757d674f80edfa86a826d080405b1ee0246e60e978241a6db45ed6f59a90b82843820294e269e2ea0e6066345992c4a607641c1fb48eabf528b2cd2ed3897fe3be18992734cdf1a1b6a0497443bb6a7688f70e0b3220c5d0c73569e889976c70e0cfdd9111ab1829919d9b8a840e6435dcd7274238cb8689abdba6a0b6abde895655020f6f4d28f7edded0ceedb8d77c64b098026a210ab6a5261ee66b6d73a4369f8001ffcc67b25c6760fbd5a8bb3c4ad8f3f50b00a85ff61a8ec6e96ed2ca5aa537f9b115af98f82f46c15780f44a57409c69884bf8ddc48625c4376874eecaf928426e751d125a4db14af2737e227c98ba713f69909b2b46ff00cdd9c58e647d9b9e1762da520607e8b39baf9b707584ee277c55e51b8ea0e9cb039f2badc3b1acb230d6da22f8525f3054418711c66c69fcae312bc3808f098c17ed489c9861702ecbc2f9b9f4e48bea2914c8c158d1804b30df29af34522307832faf004ec720a0abcb5199a18ecb816e6fc5a14f5090a541d264cf9dfa83c31ead138ca5615b8b72d94b321feedefa56e8c9b4baa64c358a974f9af29134fd304b798243ceb3477b032f2c638f73260c9685623c57ac0b33c450821c78b6be2f9917ef5779b137c3a4e06c28f287d7645cce97c8891825c1d442cfc38af9b9b6e452c90a71f27b55388ff34a4f56b5c5c1cd69fbf19e7947e1aace7b60378e375ee65ddd702f986d9c24c19d1ad712026fe021b3e98b7254c64634364626b2ec625082138c9517441677e0568326eba12b939c04e473641e49c49eb2ecd72bc0cbfbe8aa3a11d91e2c32db1ab2d90dd16b001f8b4d9711d3f684124c6d9bc2a9dd885536613d295d11bc51ac7b2005a4d299a6952a903c06235b2f97dd6c4cb364d41e43bc3b445b4a2afd81b86b222729418a62806ee42af7b877b67f9a1b17ce61f9bc907f2be311b7d74f70f300b4ad76f08480d3b6aca0b48ca68a57a3930f54f438fd046ea82fbda6c6cc76a87ae52a03f006b2b75b0b6f4a832e53d496455c3a42dfa667a8d380a72e8a451812f4964b21b1a67afc228554a8488757a01523d59048a5e4a8b1ee4ef13a45aa4c98dc39ed77642bf094d45c41e83919ef5b28eb06e99e8cf76066173d4b6cf7fe5662d18a8afe4c1c26dea11e79857135d25878abc0a02ec408a62eda2d7a6f861226c9a99b3daaefb4fa3cd07b9199609fb27c0d1af0810bb335c28dda91425542db993dffb7e127725c5002cd793f33197fb82800a076178913b54359a44cf5328e149cde8c1576b83544eaabf341deb45f394da6230e0862a1c7c6c10bdc66358771b5a144dd2db223b595f8cc32bc79225034fc05dbaec1302904c7291091ea791793e7adb41ee4b22564198445745750b274751cfa052e18f550c0b4a60645c6cc6eb748a4836e3e75153787496ff230f6b5fc9abcca6a19ca4288c1185fd1f27988a21f8d1784b0766304d2da89be3781df4b8807fd735387a4299674a0c2e6e005fb953b5ff8b1f6715fe9c71404a246f1cb0f06e96c8897f271a17556c7ba0896568590e2aa41638317bedd969febc50112bfdff8744e43475d6974bdc6118a322f69fdd07493254c9fcb47dc2cf87d89a7cbb65e2d2399dab7667174d7fb21e427b39614e2963155f18b22ebd8ae875c2dcbd8e864b903c13a8d7d9e1fbe7b46df27820759b844fd5bf47cc3a5fe53d3d48a2cb344217916ece7e6c00cb847ed9918a887c5373da3ca224341025ebc9437b903de8bd84d977493f3125774bb0fc9f6fc94e7a4af7397f97d60356babb2939032bef769694d79c291356d658ce5441a67ea118ccafba69a4c8e100d730389aacf46a6a49023bcdd9aef4aecf81a3a0b9144cbe9cf3cedf8d8b4040c3f6dae8e44a38c7acf6e0582b709f90fe38186b3d82ff56b800867b1fc4102bce2ad5ffb856725b82f08a7974f2ac14e52f75422834f1c589c6177166ac552fea5623afd8587d512973a993551454aee3e0ca01b7d9a2ddf44b0a6b563ae335946e1c485a2f149787a4c6e410586f57b1952f53c75be5d87123a0a733d3ae465651a508f172ed5a1768c1cdf1470cd7f1b61fc76c67daff94c3dd33a5de821f08b6d128fc6e72ce24821ea945366e05f0cef469c064ae33bf48912f1b03ff9ea20a5e7d0f2adfdd48d5de69812a8a921ac48f7ff90b832819e2c472c82aa584360633c32185fe92257eed0161b2f8ac8d836c7153f6a51957760b35a1d6d665b58e35a1006dcb37450e0a6bc425ddd4cdb281d5254f991c0a193ae1c1824191b8fc29133cf0f180cc62b2bfee3718f875f909792f7c51c2a228945b5413e15d5515e721576889f942c97657382c29e6bf201584929f4fbd60cb1dedebdc87952e8b516c069a701a15e0bbfed1af9517de5e85ddce3281d07dc20f2a0a65411ca6d54412d5763e3f8443e889a7aa49a831bbfc9c0e84fb1f04feec07c50031c2fe91e2fb02ce28261508e48fcd42027aa03d27da747b3de5f95f95ec1439262726c9fb27a676d70e0ecdb2472570b1e70a40f853569be95cc57bab0d7e57d7a6904c749dd7955cb55d35113aa481be3b98effc3d662f7a595dcbe57cc00cd7abb613a31829756462e2a971b99e8283556ad0469a981590da86f1e14e0c7fef61ea00ddaad8441bcd631e9f68c3ad1e420d59d24d184a3c5e0d1bc3f230a4d24fd4430a2907aebcf28322a0cd9cb368e53a3420f121362dfc4843b190fa026f56f9f006978e6913fe3afa1ee2641ecfd52cb0f1f5f1fa68517d9a4567e0958255c28787f6eb294cc01dde4a82c7c3ddd2934ebde822a2cb0c1d0343a7e4cdbc638a9345a78f9380a96af9ac1131c6d3544e4e734cd33d4e08fe77fbc32638b88b7a61359c79462b131b4a53dc3be738de25aef21dce548b2b462125d6e6e167c409bcfadb1dd3e8fd937017be40b0e2bd58312b13438d9aa92e10148bb1b496aa41d818446d48a688b4fb65947977f6fcb0d6a113a053bbb363a85da5dc6f5f91d54db2892d977f8c2c2e404ed0d403c8d607a6035e915164a5b5ef8bd462a04f24073f528649bab27510f61af5669bd98ac7a15b3d706e751f217e4f4582f9cac9e42a310c3688226076f761f5fbf102f2c9dbe30b573340401dc9edcdd2b3a9459a00021959d441cd1f59b53b2ee7bd62e8382351bbe8b5e3f95e9e282bebe9c48f34a24fe377ca46f559c754e46746ae5a2ec32367eaacf56ea9360b92b31a647542b99da86c3c8a6065c24e5f9d1cac23d41b8810bd2a2ec55f4a52ac3cbe8de1d94916d392497c31c0767828883f938c090f18db508274a4e80d206f0aba97f07f6aaa59b062bfb7c7f5f0f9d381ceb4b9e54103be29ffb4efcd43d6a076e91e7ae3bb79e2b1bc512ae0e54648327e0e3f47d347f5113aec681dfc71800d151773c3aed31c03e45d7f9a7917f144531fb726acec0fa583849fa8d7c36a39a7deb0c8c150884985f402e50b7b384555610150b7afbdda9d5a46c19e6e79ec9e14c835e9685bca997141c73f701cce9d94f4bccd5cfa7e1f25a0411ac7311b08a6e10ab633782e8fc2799debb0454b5adc5dd77ad97aabd3eff8cb373ccf8032ba461549508d74f7062aad45ac7e2012a07bc91ce41a253bfe2463de0e5ea2ef32186121aa3c65fea6c667c55304f776c621c0d99189ab5bd761deaaa021c011a6681084af1e61ffa6420b2a3ba73675505e7428138d47706aaa4b630e1fcde009daea0a84895a12bc1123826f9d69d0f3670778a0320039bc1ba93a43658d41139fd7f296b863e6a6ddf6f5ab75bfe707f1d97eea9fae733268e17e8f703400169994590c6f2da7d55b7a446c4a59e50c62dfac0670f261a87374b894b405cb3623370e0530aaae36982f31f57abf2c2f5de9f0fe8c5d2a226aba51ff0d13108b4f8c9d421ba9030d66aec6d88b0226974e219ccdf3617568483af6fb37485170b6e3977841048aa70bf493fd4a17eab2a20c7d41f4960e91a5af8d09ca7da9a34b62bf95fccb07353915d15cdbb238f53d6dc1b61b6c0ac853ce216c172183d971ebd9e90f19c7ed23efd3e642e95f8488bb55c8d4ec472bff9a8fa8accb8cc5a586990efb70f0b3445113479dd6fd517aa15e36de2204ff7c181ac898bd7129c17017d91cd8f8c57d01cb4ae8995f7043474a9e4fc1062d7f4e8d0d95cadc1a2f4f44999c02d962e8357981ced71fe64968fe72486563b6e1d070aa5f523abca9f9f99ac43fcafaa452c72684492e40ba4e8a2cb3abc21013b23508c34565318e4aada1cf6a645ae0906edf030b6b4936460942c603f5da29ca358473e7d08d0d53c1b5f059559cfae579bc3ada96ccf0fd56cb7a0b921e408d3afdecdd7cf36ea83ab805ede9c4cb1bd30ada118e2828899050829e0fa9afd306d53f0b6b42edb20014e80183d73f9f7d06c69950d436f8cb1be43a12a95a7b1abb94090d790875e92232cb213b516b36f3d9d4a7cbe67d55568fd095c70db0a52b2e0e18dff623b24735d002dad91ad0368e0f6f1b3d4fa3b2384056301a34e6406359f9d408e308c5b70a75db5f395b479ca2b001a2a5104a5f89c922cd4d4482539ddf20d589023bb0f07c70bd3405521b4a86b12036283a768defc7ec32b08a7e63c09cf4316cb6c9e242c56a207c422f4c97cbe0edbc2d3be4c7d3951567afad7bce6a7b8b1f85468f97d63e6fa833944dd5d8d31fd0c5ffe6af822ac9245432b75deeb6296058345f3a8ee36fe42aaef01edd48c541099e3182e76d1f19df1003f14eb997708dc25a42f46fa300ae10edbf73b45f748f002400f93de9fef9fe92c03b48e9e8bb41e92c868328c78eeb53e92908dd85596f04da1383a7b3e6194763d55187e3220780a7a20fd501b31e5cd32052925640135cde8219955aff51ea08c5973acba08816c681569be9120c785e0ed54b9659a071a036ea6b21ef874512193d0141863673402613c2b0ea3c6161312f0007c08161607bd97bc404ddc522b42abdc1a8af10abce2eaa93465d1ca1adaeaeb3535e269beec6977ae59c76d0dd5d5668c92444c02b1f48dc356ae6ac0c9891f597710e8940217ddda28f1d8c815af094c48194d96dec3f397a460e1358919defcbe6b6011f7e04670e96e5928a9e08d2aa04a8852c9ee8faf5dfa748b9b063d7013ed7c8c911b3d8f8da1f3a62a87b4dcb4da545ef17931d8beea0bfc86dcc99160aa56ecd047b54248b2f00ad85d38d7f693afee7fbfa2128d018f99937dce7094db93f6bf0eaafb4d736bb8cbf5b7fb84efb93150127f16a30b353a6a9c3d9273ed790d90ca5cbbea36d80555c025cfa488e25eba5ae7d5c566d8540dcad41c80be280a3def80daccb8be3958f4e144d8a52290017864e4d2fbbeadb30200f88fda044e0c7438d8fde36cc56dab54264ce91140c7cb7ca2835e28748aebdabff0f0c4ff606b69fec88aa00b5dfdc10be5c37db87e3ffe8c858207429d37d1650772c9e7acb15bdc46af3353219b0919c792334a74a3ad9fbfa646340a8961037ab4f5ad1879aedf735e6d092c6b778021529a342acf125a44047eb094a8066fc2803844994b947123c1d4548a7804a9a642a1b99636574b67531884f4068d3f3e84d795368fb21399462c01f79ed4c89f24c58755c8423fd8b821a96257874ce559d8bf92e8f00309587029872e9a0ab108f846a386c245dcd1892b5c3dfd9a86ff085478f350d12b4f9f11b0bcca23d26af3c53ffafc6120f653cc441d675ca61e6384a09a7b75b347b24409633e3bce09011330ca3e3e0a04728a926910a36e0ea91c9b7340c50e2347270ddc2a8da6b816507f0657d532678004a8fc4b13abb08d28a85596f293346d9d8a42a5a70f662fc9cb07a6703bdb242fa139c2d861a9575a8f6207a10f8eee1d6a0d832fcb39f65461e7e734be83f1795bad95d21646a99a9fc5f0bb32d672780c27fdd0bcdd9404d343a7526291ce4238dd835790efd1429da4bf874964572044e403430fa9161dba21f70f703e2f635fe0c77c846b517fd2203039cdcbbf8ad13c6f3af43af3a8c92fc144ad1b4f8bf6a71c1ce9a238d256277e93aac5a4c0521a150bbb01a873c8907479f28d820a51639650d9c6cec2d0885d7724955b670a346725a04e2fb3b33082e55c3191ed6f823abfe671ee28921d919c6a1eb5b11aa0ce8346d739ff81fdf452ae2d74dedecc6bd93c5d0b45f94d5cd1eb40b15ea3a2524197f3ebd198520ab466c97b0231fe8629a8c273399e17e7a23a7bf9b76c281555653a07f986c72bfde7636d4616592a953a79afd01f01286a30f83049e489b395903b0fec128f9f3a074d986f9a4764350f0bcd0e54c6a3cf8b29778b775fa95b50f0af0034e1ca4ed93c4d3206e7541a01c134c62291125625a940b12a8e308e2fab3962764a80735cfc823d0d08aab4728565565d1fc6a205fcdd42228492f1c3a6f17cb0f6b5f9ca0674a8c592f11fc6a98a249a52c1e8f548cc28fbb73bb6324c895f862b2565a60b31ca61cd461f52b523193e27c598477e46d043e87012314e7234649958b8d3ea9fae87ec089af840f1304e061b65736c7d8809075585dad0d3699a7904aa1a3a8cc510ef7d5331ab1aba16bbd2d94d080887f8ce7d5d42f4816d70ed637486f5d00e654ffe14d52c3081021a8cfedc416ba75d7d6b2bc7111729e2409f4a03602f510ad65b33ebea2e98a54988e063a851ae3f3c0ff43b8136206132793b4a3ae32ad5b60358ea4fd3fe03e4746a945183085c6127e3c0b7ae06fc6c0b4bda553f12c9538a0f9f0fb86925a00000393c60b2c3b410cd4532ec09b069c89a819f95ae60af26ec66cb619c502b69188ff2c7ac883445008b909a77b81f97c20e5027487020e1100223817a1ffc7ce380412c0151956c1884e72bf1dba0202a6b25e2f2ee1c876f2f0296bf6a8f790fda128c9ce581e5401caecb39b0605606d6680cb2c05b33e8069569f9150d0ec2f9defae1fd30af0dd01e4ca75f829c81d6a29080cc9667985b76bfbc799a2fb65ce1a43382a9a512bc0c4185d562977ded362468a8be1e9a3fcefaa1f6f33374fecf3ea3e4150b0dc108e5335ad6e317f426e4055dee4b0414ba9e6df0f73f270e3701fbe2031cdf2927723840115c8a08aa8f7072f303bd4bc6554edbb2cedbc12036ce2866200434117ae83a45e59526342d1ead13981147d1b91dea622ef50c8d1f378b005fc06d5ee210b61f92c6267e9cf46efc41b55d37b800f2a619c2c2bc255052399650e2a5a8b1f2818fef77d1ade04b052d45295a6b561d92455efc1981e3260cc568f25a496a164013bf83ab9ba1b17df021668be876f9b61a194cdb92a731269fff309ee834e8563d5ebcde36b8f801bc300c2c1140cbdc12fc28e978889f12dc25299acbd37b8fca11effa843e0b72cf0b0cd474e678844ac4a41aa39b4d6a0d4f43a0bc05c4034134e14ac7444bbd301677a2b10837d4e24cd467058d47aa21cfec762bdb72794a0a2bc0143b90596fb4a0ef9e67afccb35bec6c54f25aaf8d4edf6d2d1e73f3cc18eddc61cfc89ba29bcd1f5aaaaae0952e79f042a58ad68628d515d2a6ed0e9b10e5a42736b3172dad43e4659fcdffe275750c9be96506a066e6d1d839c255446991457248e3597dda864b4f00176959fc0f3a7c6f1bcc672f2b0ccd4a5ccd46ecdb3b9a63a05a85beff49e8f88e98d3890349f92207d338e1337b34472e09a0b098cb43c9c9a034882dd34d893a364f65131a07a2f5da74f592834db75a9b3066030ec30f5f28ce8bf08af571ff4c47e8af12c6196c85b0975f88a3f089143e835b7a1879ec3443460d62b2b60915b88ba0791c6475388f47c398d026d3ab1ee8dce226203e9fb13820fec0fcb9b34f82e16e60a8efc192e0c381a1417306bce978eb8d05e958931c9aa533e8d0116f32e0cbe982b0e6fff77e19ed904fd2ecede624924e8bff0545de88763d4decadb6b07dd6115e9d402b999da3ce19a66317c02215914d15bd016d5cc13e674c27a7d0e2221cbbbccb0092031b42d52749212c297ecf6c4ee983f48ec0756a318aa168b934838d3c3324a0d2498ba3206a7cf8fe2dd13a9a5c29cff5c905caa9469760c80739a75f67f28cd02299e57f46b8623484cb00cbf6859a4298e5117f1cc41a61d1943199dbdeeeef45040870d5d3aa48763433f2370b0cd2a52c4bcf9440c55f3492e2e65f3914b0b380a655cdcd48d49608c64d981a47de3933385535bff5952d9376b4287d3ead35b307663c79d71bb4c007e68fa298c080ae047064b2f636c189278a4bb97784de29675ad1d8042baa85a23f810b601dab69161cf493108bcf7f6a1f67c397db571cdd169caec777dcdda34abfabf6ea70beacb82593c7f680a58f8a09e988f845616d2a7ea2a15bb166d04c1d32ded1ddc3be2562f6c252a7e49de157a2482a4ae92715ea1461a3a0159a990fcb344c37ff81bb0998100252ed801d8b98b067d53d11801145e7a6300e104ebe01405445f37ffe7856b66ce4ca3ef3838e0d6439df1a4e86fe767fd16fdceaa0d20c74fe91f3bcbfe7078fb3cbc7a67e61b6ebc8044cbe1a72fe2f7015aa71bc464cc078b630038a555d985dd73c2ad80e4ca6bd372829564690c857f14f3671d7f4737d7ff5367ec68198a1569f563859f5c60b7443980cc1eca7e4a0419a6ac875bfc598fb890cedf31f430ceb416d344b7eb007ce3eb9c8483faa824c7313b84269850ce88471b05838889064ca57c31ac480678f38f3d94c14718995aed836bbb72986dad40dfe4a65a24f2da03fc25042a6157a95a30d815271df1a9248c74b1cddde5f6e2a8e6ba65edffe82edb4892c5790a2d1d4de854167a7c90fa12714c2f6e57e904a07904ec884081213bc56c66429fcb8f0660d4baf7a451d822a6ced5476bdbdbb61142c82664ef2df70e5c0acb0a680aa44ffa19defe76eeb3fb7cd3cc96d0e74806897e589f475bd55a0e5b49cdfda846f490ca54327d6693e964f2ccd8fc99407307fcdc79d6a51e587b2f0af583e092252c968c138aa9a43de5db8ef2713f7db7441a556b62cd1699b3c3c3e289f9c9c0cf8f063210f343b2dcb5d7dc6f246b4ddb4d1876bf1dc65dfb4c4bebbad6b49efd997ebfd2533ab47387d96e4f43ae3b636283b4414afaf6c990be5dfbec35d35fdc4d18a6530fb3e75ef1ebbe8461a4dfbfb4f697d52c69c3dcc8eb42a6c8403991647cf6299ff6d3c71de5db6efabc97beeea34f74d2177a0cc5560aa9a5b4565219625c99819f1f0dc4fc34bd01249555faa6efe354865da67b718a9e647fffb2bfa7bfda4918b65d3b8cbbb5daed8772ed3bddf4dd8f3e12d54894462f5c6bb3c3eeed33fcd27ec23052ab6297e95dabb3528652ae7b9209d7d488ec4b58dbba90e53c91e88b2dda212d405ba347b38436cbd60c3404a1826290cc913b4a3eee337cde515fe8299fe9324a285f8a9e4895862fb65264a0f0f8087991a0eb22080a1a81b5f7a2503f088a404890b5f7a2503f08364a173af71a138a0a78b225148e3bd1c87daca9924028b3e2ca7cc7a23964b1240e6d3343160d59b8b39ee4b8d039cf74ef332d1b02b283cc7d1b727517322513e9d3208c865d349443287353dcce618ca57470efbec3fbe931e442691f289b18f787931a55ca956a94777fa1bc8b13e58d5f29efde694ff94ccbce16946b32a77be7beee9c0e1947f94bc651304cc71ed65d068ed3e217ca5330eca461da9dfbabe3ba9317fa4ab8a686f49ad125cd0dce4e689433495f6c09098a693d1283a7eba2eb64b4b16449cc85424ae1b6a3bed3657cde51bed2492926ce76295f6c914cae26ae26381abfcc0cfcfc6820b6b5f7a2502c6bea80f47bbbf79a93c52e53d7e1549f8ba6eddd5fdbbbf73b0cd3e14aef7e3acc2bbdf3be9d708aceacab190f8943dba474a4fcf457ca4f18a6d387999ef23a1d05c34a3fe118327dde4b5fca9aeea55ea5772fa5ec7778377d47f7d2a7c384e3f44a385aef761f8de109f974fd1095b1d8be96acb985bc6ca150e157dc0cdfe9a8cfbb8c0fe5a42fe5a510377a7767f8620bf5c5968c2fb648251cb345e6ecc470cc98a99a583af9f991959be2ce4cc167e0e74703ac19ca40cccf9c2d76ce392de5b6a3fcf49a947bdc86537d199f69e9b8489f993bbdfbebd47da615aeae1637660ec498e832f37c8fe862f366a79d38b4f1a7a35e8ee8d29fa7400c65202dba0615dcd3bd7337dd3ee52a1db61da58461a5a7749d0cda60eb64f8e55d0686a5600fc350f009cbe86497b1291ddcb7bf381c67865fa6973009d7d4dcd7885ee39d7bcde8db4bd36efbbad0c813dd98fb0394f568c86b8484db970fa515794e94cf3fe5d38ef2653f7ddb475fe9a42f65ea2ef26228555b285f6c9dbed81a7db165127db1d5c5cc16a984c7496318895df49d8c19dcf0ae061257240e3102c547d9f203b78a2bb3f10f6cc59597178016ae7c877e48d5f3105ba45b207ddaa7407888ad9a1aeddb6bb297de3855b18bf498ede767ccb46444bf9f8f3ab4dbbf2c86e9347e6537615809cb88601b96d191317dbbf6995608e6a923633ae9abd922c2291da56f4ff545b7f6a2dbcf6f2f7dbbd9e7bbd297ea974ebae84be9289df454e35709c716e9a2df7b114e354eed4891020f4ee06447e9262ca3f312bd84613a2f7bd161dab7ef109d034a20e1890b68685a220ccb6e2c7d243cfa745ca2675f4ad3b62f25c23535a1d774afd9aebdc67b0df71afbecb1b5512153356f3fee9345640ecd4d6cd9d8ca7e4cd5fca4204933b33922ba947cb8a23126ad953597559248b0649784e879a29914095aafb821cbdec8228d43959c9a9996906575958078c3ccf017a03daedce0862c1edd129b7559837af2451799c562b1589946a94a5c913ff97451e5345d4e1f0e47e8014fab93dee9935538a20a39ad6e7a13264f70c3049ed6e91fac04318b214a5a76dac027a8a5332f714a0753e9a6cf64d267f2fd4c1e7d268b3e93439fc9de6772f799cc7d266f9fc9f63359fb4cce3e93eb676025c88410d43abd0434c2a0a48582f279b1c13b1285bc8edbec923caf61f19dbea6b1a2a06058095a51a54b5d81e8ec0c51d5f79ec3b3c4a851176eec398305573ec7c7160c4fcc22c9933c9fa387667122cf4320bac4aca5663847573c4fb36f2f8e9117aeec9f79d3459530fee40cdbd0d4e8a4224a33d1a45f77c9bd7bd7494f7bd7c54945b4a3d402cf3ad194807dbdf172afe86691cda2edf6bbdb760f257a2612fde2f08a3ec2212a775ff82cbf98c3d71cb877b7a11ba125fab65f9fbd5a955dc3ae2de85a8c03bf3498612737ac91b3d7a89fcc3294837db5e1fd667827d477950f9c1bee8752da2c6fb3c84c4a8baff59e33cfc69ca2077308e62035d71f2f097349ccfdb03f06c495c9720016b0c1d9ad7883767b613030080c0b813568823c4f6337bc12e8e6d44bbbbdc5b058869686532e6d66a69544fbe254e510cab2932909d3030d59b68087c7933c234b18b178354b2a521b53ce796f63db51074dc3b012b4aad0c5709e74b13b635629cd689665d9a946c4cd88c0a17999aa3ee5d9999167a785fc08d260cd3020ec3c519329f6a6c5d120fd15375ce5db60f78c46c5aee675b16b25907a5601c306701557faddb11a675927c4aca43102945393b29364c9901b213e3f82c0accacab31764d5b07142d59a932787489aec5dcfc62c91d56ca12d1db4b59a2a6a69dcd16c6896987b88c151e4c5460e14ea07c1d5aa8bce15f3c1751dd73dc41479b19143ce6957d765a74a4619623e9a25b4425e2e986649913435437a88e9e1e57ac1bc62ae18ce1671b55a1d86c68ae58ae1e1a3c60b1874151b66a3507395a3596068ac58ae181e3e6abc445a83c62a7a34583456ab154d0b2abda71936d21ce3ca6b344b7871a81c7c71bd7ab061754f36a8fcde19570554a974028971a3125dfaa5db565cd7719dc3c5b259d1a811dba28cb83d344b687bd878c111f323082c87cb7a396c34d8e2613b4fd6060e1b2f3796090f2bba34901cf25324c80f2137384790c07a2889e1e1831557807e04f9010403e2e142175552dd16635d276d78c4f49034f2864804830fa0dcffd16d9ccc71bd9aa55fc0d249906149eece85b4d08dfad260a31a943e70ef1e72f7ded13a49f5fdd436a359c2f853eb411aed57346a744bf40250184836aec6f0a033e28a6cd06bf0d9edd7e125bc73ef66e806d71cf57c34d87fbd77ed5ea4d5d60d5f1be98ec6c566511207896788376cd886384f6933959ecbf203bd3c4d9d81d7f2b8c71c230bf7d07eebece779d693527ad6fbe6799e77ee0b676c0dddf02c8b7cb8bdf33e9abbedd3b66bdb69839a77db2cdbfb1e0e376c716c508b59d34e3ba44376972be64d8cdb03c73498fd93c2ed87f127025523ba1fe2533bc46bef3c731ce5c4167ba459ea61eaadbd17853aaa491399a4c12a711aacb7b3451e69547d9548ecb5a87b14f81588caac1ca27245e57aed8b1905ae583c3eb9c678882d98a9aa625ca9a4c1fa0ccb9d06eb27852ba7ac4d38ddc88356e220f105e20df3d3621c110a793ee4f2f4a1691c71a50c37bcf9d6e89621ded2eebdf7765d4a323379a770c3e8130407bda49138b4bc41d2c8badddd6dfae28692c607874facf206f99b53cd4906f2071d0653b001142d450a72761a5996652846e415dc20d3537a148b434343938216b5414f2fcd810e4c34410c5d48c10bc400a345a3c8947699524a293d856e509397b36cc615395469400e6da091c525648f61b42267437c51051429a8428f0a8030040539fb8a358427677f3122673d446021672f856e64b11e1c81232160082264fa1bba416f2290f4a8c8e189460e67e44c256736e42c873472868224c09cdda2a0276747d9e4ec6f96cca6670814e4ec2356a6032a9a082253c0135114ba9145a146a60f152144cf8c9cdd339249968e4e11c418999e531142103b310959258a205240809cdd460186abc5584d105a90f5d414c139ab91b32ccbb2b39aa53ebac45c4f2917997edacc467616bdb3e50718b2e8c1177e983831452b83226755d080660753f8020c9d24b4b22539ab020956e4ec349a45cb599665d96807379663de71b133bc78b4f79e5033ac56356dc990aa0448f361013da19e68925920b23062064dd505828b18f445391114041a9bae77b64414bc40664dd3b4d3207c11842733d35059eb398112596341ab5efba34bcc5a56c49156c53c8125485a1573682f0a8922f754837278df1141bd44aa3dab59560f20834bca91878b2105f0220603d0c2f572e4e12227c9ed72e4e12249017eae8c1c79b8904245836b73e4e1a209aa2cae28471e2ea4001ee16639f270d185ca095c7ca1251f01345531d397f6420a99e6d873040ec5e962086eec0102498e3d401891b721c71e1300753c59a2c0f86329cd33356dfd992ad9627dfac90a77d0a499a40b00f1939f34283f693a30834c1f76900ea52a903a48faf8045dc004364b08a50f95ed65593f6995fcfc3a2805d75adad59fd962ab882af92b9c3801284b2a04fdcc96d8720214647de28a9ca1226d00c1556356835658a10609e5809a856679ee8ba0661965f90ea743d22df2c80f67827086d70a2f69b4a60f92d84e93243f4e0421cb276450b384bd24cb870d463d92e5659d42969776489697960a4b45db6021b5f0e9427ee15333443eb1ca611fe138eb0364e346e39721cd626f6c911b7b636fec8dbdb145ec8dcdb13b56490ee993e5b9d08dc638ea14341acda6fefc6ca11b5d8f344bcda93b35a7e6d49c9cd9125b3b4a787c6aac8769433726860123ba00e0e7a626cf7469b2836c6caa1a871588c70d9ed9626353257fdb07757d5041d9e736e1b13e1ccd7dae3f3eb21e4e9ef8110426a483105d3c10ad903d309338c2c429ba45a6817e92a6c11a9a2136f2ed4474f1403d9039c693ec236e91a9cf159ee4e863852d72687d7cb6f8c9d6a759a2cf15ac681612901b7d8c009467c8910a3168b20c51a04f9329f6000dede08189533be489c31c62f6c147dc22630fc42d1a89db3c3434b9af10db014dde22d74f1291370dde1829522409ce9128c0901b89f5c9c9d9d949d248942cf16162254f83f230e878bea027490c1189e14e2a633c2af5f80331e4e9cdeed460ac8127db49170d368bc4a913d56205c6624e6c036e0f4d1557b493a8ea8709c832f718bd85c9823c51d060c8bd0a23f7971869b01f672a82368c1134ca7d181905d0184e40d9438382ecc51772a53396819a259c4672374b7711841c71c88a0fc137d8a780912e3418b97b8cdcd12587987f40c5157a525c918fb345c3332da94d19144a1c197b8a6e1cc24dbdb6db6f384efba55ef6da2dd6709099e7e35313ebe85686230eedad8844c99e55d65a7b061157625a637615bb553a5bc64e947a79adec342f917934935996c52aaa2a204a7e5bc7d1d99ce4a2260a81c82f9c91e3b3500e5e68c38d2cdbb8f285b44a9c5c6bf5116333c680c46b73688e0be53033e56e846883f15d77e3dab822bfd0bb9103cd368a3a11271289449b4824125991481365a24a4553d42229baa1b6654207e4071d6e9e77d103c921e6781e628b5ef2f85e1f8c18b7c7c3f80324440b1720413daae2251039595681849decb595fdf0ad842c71b89a715483a89924c6a03b73fc0cdda89a0dba33b4430fc9d95f6237118c394630d59d7b97b7cf005914c5851bc626303dccb709721afc4f13458a18094216326d5ae9875570c3991cbb71634ce9aa473a6822884c7118794ec793a2c65092572231dce77005529ce77972b4aa51524ca49208273b59d2c7fd7a5493dddaa4cf5e633f7ae314c52e92f6793fd39ad9b5bf320dc3742e86d98f0edb9e5d510e8943db68cfaea3bde257f6118689bceedc76ab3d7b66394fdbba5006d469419f3c49e10923908c138acd913ba3fbd347bafd52dda62fd5da97ea6c33b99ab89ac8202020a01e69f1ea2d5a8cdb0f59150810d00fb3abcdbad61ad2b9571d2ac35dfb0764ee7b9cd231bafd0eeeda65745edab9cbd88f2ea3f3e2aee154cb8c6e71aa239008e20f21d16566ae08398434811c01a55ca6d2f6d7e8dbeb372ed53cc4d6a8d5de0f201a6e0cd6de8b42fd2048234392439b5d9f382f456688916232625e4cdadc948e3a9df4a13ce513ddfb42efbe7bee1b75cacb6c9145705c1966ad563a622cc678d0e18a2b73ce3963766b310f40329c6aaef4d36b4c4739c5a9c62e6edbba14ae54ea300ce5a6c34e2f95bafba5fa5d37a58d597d712a7b37c2a90c7bdfb68bbe947d77d1435f4a4777d15316efe82e4aedf01ebaf7d04cce707fb40c10a098a67c3af528dd63cb7b6c99be542d7da98a5d35f735a353981e427e4423576c47644457935db6b86e12ebdee91bef26f49d6cdf7491c6e99c50ece726d6a46f6c6868fa2674d15fba6f668ba88814e130fe28d13e9acf4b17d1377dd32de822fa265e30ff00a4def8a1e254db7881f911a45b9a8633591c25695347afe17eba992dd2364e1ee10d631a2c5bd97723d8ef5354f58c1b0dbbb6bee924ba88d73c681cb412d987fb4b7bf387c3b099968c4d9574d2431a049aaf466822cd32b3226da459ea90fbc596bc29822377244f8e92fbc956119c9c1d253cd927fbaa0d5da4735a49fb344eef74ac6fa66aaebc99ac4b4328994699151de5d34a1fe9a65166b78cc7498c931f4052020102fac1b4b5e8f735da4975db4aa34fd1b7bf441bd660573412e1687d709234362938397207f5d99f3eed29a3934a753b95eeddecb9d7681fdd6ddb4efabc3d75ff6a3761d8e81a9631c9a4bc64b5cba0dc3ebc2b199d17eaf73232ce7df4c9a07e9ff2c1745e28144ee9189d7baabffdde6ff81e86721998fb08cbe8bc4cdf2e83f2d139946f9fe9a3efd6c3d88f0ea37dbbbd8ed1ada69d3e9dfa6ef4d2b7d2a8f4eda4a75edb49df768c4678c7f6d14730edf7b1451a7da5ed2361ea1a5121d2a6484e698676e7822eaa507ab984d2f7982d324e23bd07572cd4c75dc6d73de543f9fd4cb75faa6ea72f551f4a652f7d4b94528a83524a51534529a594d24829a5946625d26b45a174ef122551fa55a9547abfd47587a19ca3b4eb3eee4b357e7ffb4c4bd3629a45667a1e37d248b7a4f8a08f4fa296b58bde94cefd553a87613a5dc2a97afcb2ef308c746b755cf7289f8c8ecc09a7babbe99321754f55d2b9a75ea47327e1780ea72ae621b62eaee941efd18be8b72e34a254f260a193fd05bd7c119a3c67509e4ea69db13c451867f4893e7724d752c293a74f9e9e2c325b66d054cdd9c4499e4524cedca1b8831a6806379c3bdbbc22a88a08d4134e27363c441e160fe6cedc993d789e3ca078eecc9daec1bd84b7c84ee835dc453b9ab5386c9a5463978753edfdb5ddc31b27c21268aa66ccf327679b2d5e1325b365eecc6edaed93adb933adbd77a7795a49fb28992df701dbc3f6699eed8bad0edd706defe6ce74622a993ff38a3c67153dd349c7162d21ea20a01db225c2b09956037dd3e666e27411ee9c4c9a25ec2e0228dfe91b9df4d7e824f0de843f55364e95bc992d323af332a48f2e53fabd7d0da574903efa8bf4d1c4afd22fbe53652f7bfec754d1897f78915e3a0fb1d50316838148b8f4b9a68a9ef48d7e1fc6d8c453c695b8321fa76af4f5177a5c0e1b4702149863e4d0b756a29d3ec66791a9768d6aef6f9f0f2dea6f13e1d40ea2cbe720c2b1c14dbe747fa16f5fe8338481b293af8b741291652ad14a9c14913c3eb14ce9c4892bf41d96390dd27358e2b492cdbbb36b1a4c20bbbbbbbbbbbbbbbbbb5b7677db8bea6f49109bab17128936d971b6a6e6f6a5e67cd7ddc3b0d0bbc33ce9356d7920b0d57bf7852ee2ecf62d13e14f76dc66cb4099306bad5ad4773f0d6e91ab3671e85e8e07d4a9cce0662fd246fa488ce6c5f5b1cae10766c255eede5de6ccda7de2d05ed4bb87e04d7409e52ac5edbcc3f4a13bfbf61cb2778dc3794e6a9f30dfbcac974344962e2282f5b58b7c98d9625bf5ffc47d1357ea43f76e441209e170fbdcae3d9cf7f09d1f6afbdceec3fca9c13aab7d2825f76aad943951552f71c87da806ebbb5a67d7dd13964570779106ebb57ac366a23613b9be999038f4ebb970c32ec2a2d22c757ece39a7176b6863c53ef44e280a1ac11f4184fc90427e48ef2fed7a892ef337c796ee947b188f9029f707704b8cce7d36b6157af7d508c16a856e635ba38732485ba0f7d116987d555f57347c61dc9adac18633d9e2983f32dcdac9195b52d1129ee8a1bf44384e5508a7ec438fadd7a74afb08a76ce83b460f61191d9911aeb161b5ba0b615bdc778444b8665e08dbea1e5b1e76bd7c39aae85b3542dc568c090863121610862203c25845a6bfb305e647e2e6a1b75fa4d69334190aee0bee15fd35bae8f222d14f18069b91f2a5d24f1806bb33a4df4b895ff7270c83cdd819aead10dd4dd3f8c1c34402cd1a1bdc340dd2110eae8ca3340b77da9d5e2a992d293ccdc2a45942a740d1a5e485c8f2d2a01514658a61d1448b08441095f2c596e94727c5ad398c403274e3be93e2663f82d450c4ed3cc369787dd83499c62f9a88c211b01006115f006ad1d3f0499b4f0060dc27cd92d96878862f5632dc50dad8d4e98cd3194e25ce8c2fa5fda92fa5e11f5ea9cf380fb13503c32e4e3db66678f8149ef1451a3ec3e50c34c8af741a3e199fe1433d86487fe9b8a21df5c9f8a44dabe869fb1c9146a8cffd2493d0279334d8207d0acae8933c9fb459c2f45367c212d0b27c04a81722486f634ec99ccc268925d08659ab06c15879f566d4dd4d273fa7cc892bf311cb9d06230f8e1fd927cbf679992371f0e28a892d8748225922f9b6772a49dcbef797e80244e6eef3f9cbd9261a8d46229168f4eddaa7e592c9f4fb1da5d26fe932285f4afef4d8227d2989533a4847f98efb139639fd1e05cbe8bc4ef85e86f4d8eab24fcbda2512890359d3aaf921448ca08efcf8ec072b7d2fae982fb644210dcb1c9b371ddc0a06d7b605940830b8f9b1a146534a299594de076aada596524a297e5981ac06a72b8c44c861244296407f3ed62c210ba6074ae99663cf12262cb511e7ce6740e858a64db46850cb6d93a495f4cee5473b3f3932269bcc16dba26f9be8a265fa1e22b2c03448b7e89698a9a27247f2cc16ee07faa2696a32c5400fc9b49443885e8a6bf397d2d1ede84ec23542bca5935d473bf7fbd40eeef7dc2fae21fdbef4e9a476e8db374ee9307bc2589283344e499be812caf47208a594def9d5a01bf64e2b992da553d3e99ba777327d67fa52db675aa52fb5e11f5ea59bce436c99300cc433ad9055c23a1d82a6aff4d100c38d2daed59deb1b7a243649a64b32bdc1992dd6de4b7f3fd27782d11830cdd243440cf490fb23b5904d1aa4177d92678786505bb48a9e760dcd939f2f32a5b28b4cfbd3b2b599f4c556e672b0b971dbc4151ddc8a5d158cdb8f65ddc5baa8427ff821c8cdf24066196872109bb3937e1fca941ea477c1348823bad8d3eb105950f4acc8928a200522c7a0adfb81c082e0e689551ae4bed1bd4f14fa40d64f4d5cee5c7d78999abfd3fb8bbbf7790fc374267e79bf1816a7273bcf4fcb327423a523f4d15f211ca76a845f9faaec33845753458f23aed07bdfa78abefb5834a54304b79eabe1a6f1a776bdc110c4f0931590e310ba004556a7bc46e965f6507ec391f6a53c8739eece7338dc3ecbc50064798e468a71acb8707978f4f07129b970c3f81379785cba1379e4b51c7ba0c8228777053702653f6861cd29d2826cf1405bf52f1d2324bac8cf8b20f6704d5304371408892b93155d4279561c2382084ed7d67329ae5fccb985161db1d08105686a9db3d67a591bcc76b3a19da15b35cb74e9af441c62bc2114b78883a4efc6e100b27c78036a0000c061cdf2214aeeb8d26f2d6e189b8820e24043ded0ef5f20b6b060a20b6509c30b510b395221776c61916608bfdc8f724e29e7074a1c06106f90af3400904359664ef89899899cac3bf372f6f8653bcc07913ae8e2bbb3ac3d309bc956cd128a38ac5bc5f2f7e44597ea925db6962d146e189b6020ba3421cbb3a6aa87980b441c5e30d1a5de47f2842c1044e6791f335319ca81c6184331c31ffdece7810dc6b366cbed97c4a1c61be2258f96e3c3d8042666d0c5568d7c8c57e9d67b6096090b2cbfb3de5213216ffb96e60909db431ac9939ab860e931a3138a438778c3fcc42c23b05e592fb86174d2835a7befa39356d95a71443de8bad8639ece5833ed2079c64fd3deefb2ac434a2badd92773d5c1cbd9bbfe428d6adaa95671d75f988591ce9a793674233e76ee7e16c3997bebf8b067e7b066cba4b392529a6913d3ec21a594ee44eb7516636a06a81c1f67a593d619638b26a594dad43cdb2c61bc8c93ce39e7ec8e0b5aa0546a418a49062d68215a21597e5a1a032dcc89238ef25352e9a493bdd560c5799b25c6497134d88f361a6c1afd15adda0fae0d2058b38cc2e0aa3cd3ea0ceaa4d32c3dddebd9d922a3aa3e461a7d5e5ec6b85e965846907a1bb789626b53cc0210714111d900446e28c71e17d428e17239f6204186fc9ba172d68344177296654560308a9ba98aa018ee28c71e247e4023dc9b630f1231247cae82044e0ebfaa2790544a2ae795d3e6d974d22a86541837a4d9569b9d5a39a2b2fa7431c618230ebf1c278d94ce397bce49bb637777ce6194360a3244dd21ae7cc7d67ec0dcb4717ee243b905503f8632a8e7082472d8345dd3437213c91da3a1a109a29b8432890872b408430c2ab0410f6243c8a1f4d9410e654c62d1319913ebe8a40540c8a28e4f72d7cc9c808830960862084bc08101931cca224608914389238fe48eabd9e24310648083253b4fb65085560b213721db196b42104f8c410b1e317e5a3d45ee5f9cece54682152a4600c1003f99126122532264c8f43674838239461c0c90b96ba11b5c4619b182fce5ed59e8c6c6534365468352e786a8972b9ab42afeb42a66ea04045a5d11c4a26955cc4ab069d56c41a1622d6092eded9b25a4ff28fd8cdb90e2db9843546e154185ac69a7a59f9c653c4520e9236ed8b19f1690868606081e1a1a3b5bfae7e7a68b4c234f27a42e58790576e1ca10e544e264c9495114f6ca1863dd682127e0450d4ce0042a827002103d4e94411453f8a6894c4f8375a2072567286591e98d0d5880844c8f0adda07726891b90a10c487821451450340f144540913296b08230327d4a8480154f38a2022504f2618cc1586b2d8ceb158b7fb960228d1a8df1f33dc4263e31c618e3a682ac09b3091fa8481423dcb630ae9cc748f923251631461a638cf81469157725c4adb13d7b26d1c959653fac92892b1fb1684a29a594524a69a59452dab19e2554fc4049cc162bd151634716d4fd4e344b89c32c561da02eaaa88c9260439e3f9805716b27133058b58cb3e7258e9f0ae8c5157a0a647f5149bce8327f85ae4f01f0b933f245e9e0cab7066ed7168951d4663c7d7170e5e365164839f6576badb931ea92727833496679f9cc8594e76d6c91a48c73e5a3ca6c25745165e200274f7ff28bbbcad6de3b43301603820f9cb83b477cea1463c874708489c9cf33450bace8eea69466b5577727c623d6c3478cbe6009cd6685c4b559ce9d314615f4102aa707c6cda1bd3f3589631aeca15dbb0f7d1e0dcec693ca39e59453ce4b1cf6889973db68f3e83135ec9a314d9afcc4f468c2c34793263051a820df0cd44595f06e3d37dec881916e8903144f1cb9993f11078e1c4bf29c3c730a2249b6b879d6501a2bf21444bac8da125411f2c431ada5d1e012f6abd962f1276d7b848a1f1b6a4829aba4524ada5236c1d3b35b543ac618e3a3c4df887059f3190d54661744e4f4e2662339311be4a9a494524a29b5d6524b29a594ca15488f70795e6ce0c841a9b53725c79e2558b841ac0875b670349e4e94c3a756d5c7305cfad076f40341672b23cfa3c41b503d327dd5e8274a5c49a963a044707e86700399be5a8066fb6dc3a7b8321fa2783ee4792e8227587e11661553d639e794724e29a7aca11b92ce1ccdd2b3e79c731291854b26aba856c898f4913e32267d60af4019963e71a51e003cb8dbedb577f64bedc09c2af53a890a52b841196a603ae11236b265bfa38629705a4038a086a755821aa6c069592c839aaa6aa7aad630058e9d42078253e5801a9e96c51f0d2f50997d5631a2a422d8cf6c1ad44595b0d264da302b1aa48ff93448e792e812338d5d6be9ec209a0eea201a1e164b071949b89904b61dce9b36d3264ecec4f521d833dbac26b38c7e4183324c812850a6ef9d69edbdf3872aa1c8d4c79b3eddf4e927dd12c21d9b35dd90da759ef499dc073355f4351c71a1d8bcf8dae17ed238b62a9c357348a6dd1de4136b42df1d343b1ac213e7389c4428928963278e3671b28933a5c8f491dad4bad32db932ff40e9251d22aae88bc834894b95c8f41587a84c73ba90e589a94d5ca19f5c1177d263267786120a9c4c3f71664b131155f447e4c4c0064ada2674a3876472c68c8a26964bdac6da7b51a89634422a8de905b4b9276eaf4212e85ca3cf3d71b5980b26ba94327d0f99e6ba7c0d5fdc17fbe1c81eb7e87dc3dd8e6e7b5703127706ad794c00bd10b6c686d5daf01755f442d8d60d2b35e4edadc4a79095b8c6d6c5c5f71e0d43bd6733e4a641b06d6e6ca88fe842730fd17ac81c92da214b452a71673645245132809be8c283835c95c835895cdb87c329b9e18dc3323aafd0b9cb78dfbe830b9df3bc875216bf369cb2dfb8879e7a710f9debcec9fa1a90b832f4e1a896082f727df7b54d6f32c8620964a3c4460229b119722381b61c1b4cd5b7cd270c44a14cf631f10a64693736077da4bb69cfee96565861450e591a62d20994859f5a4317eeaa4392c644972fd3f7882e2497d9b6e3fadb2605e9690d5f5c170ee2dae7a05fb1bacf292ffa4ccb1b8930ec7e34d36a199dd7fde832a48b2e733fa29d6374993f19882afa3801c0832b3ae9323342291da48bbee37ea44374d277884ec2309d1dd20a3be0e2062fa0a16991f09daa968e9c4662cb0be11da593b08c8e8ce8252c33ba5f6c75a21cd1a553de67b28747df2a4774e94c65e69eb85a5c999d3d9c23aed05beef3eea98b9b61f0ab22973ff50b72460e929d9c06737696d41c6a9454a0c9a1a4024dd67a882e33d3675996512a8f9044642a83c840f33386259206692c94e1304621d37758823c710f394d7bd29eb427fd86855bf151e04fd735721a046bf491adfa4e466a73844597104e7419407499b9be91ecc0a20bcd0258c2cd00b073654ed114c52eeedeeb87705fe37c9d33557513e3f60d8e146e289db48d932adae64b7243e9244ea18323b9737de7c4313861840b4b2801c517805a7d443a914e52605c0d770e1ec2adb48b066be3cc961cefa1eff01ec232ddb94e86bb875316df06e736c5d5b004c2d24983f5b80877c2d480c455d5fa6ef694dd54442986c595fa9211892ab5b6760521503124f4840655e8a20a08be0630dc50f2f0742f3ca28b448991690c43a6d18b4c1faf90e9398d4a9ed992b2b4ebcedd5afce2be61d8760ea7ec630bc6bdc3298b6d8b6e53dc8aa5120de322dc50eeb4f66672b51c2fb9d76aaa68c6e4d21c99dc28a5ec2ad2308fb8428f852b314824d2189dc2912194083231b129c1e0081f538e3d4b96a084114422a571efbdac958bd2d31a4b9ac8deb54a744055634224887e712bada75bf670db28addfb66b1bddb62daae86128add46a543bd55e1aa477f9c034cb8b521bcd224fa190020d6f96415759d1a55b624b8cac0b4417fa18558dbae25611df80d8e29aaa992cfbae596bad36f6d859638d353eca1669f871657ef20702ab42f0f9810abaa88223bacc56b7b8af1475b839f440a6b2d5511129ae4452a68d6f5cb93adc4c7f587b5936bae5029dbcaa32ca31267b8e115d648e4d5c54c84c0306c61583b9f75e18d72be67ac1b85e30ac55ccd535ba67ffd8c8227ee479d8c82e71ccd7a3c196f23c7ac4f9f81ecd127177ecd851bb7da77d3d627834d83c9a45daf77b584dc6f0e8d119c681590df6bf9706adb0c28a1cdd3de2974c91c3db3fb8a1cd194d271f35d20580501271ac001d820c60a045567d2ceadd034518446826788191eeeeeeeea63dbb9b3261c2c4a7079f263e384a39f62c319243544f7592592a8c484204303ca9f72ddd979d861abac171b53ed380c9cebd725cf6ec3e7030cdc2d5d75aeb39bc7d309febd560cd7e3badeb05f39cadb8706bbc6aed898248ceea911bdaf823457df7f282ef6db63be77d355a555970fbe14aae7498fdfe61766d2c2348bfaa24c8fd4af30441e719a748fb4bd355c7d16870fb3e55f516b5c44b532f6eb8ca3514325373ca6ccaf53d82748ba8de064eaebd53a35922cf929c5cebcf92277218bb90118b5c3fe9aa59263dcdec8c08223c8944c8f133a24bccf2973474a3b69438e8434dd3341ccda2e16e1c0dea109365966326571b3824061b6c9ea661a359ba098d1e2880624ddc7e54e95ad34515ce4991b8420fd420ed2f32d56692a964ee34487170399ce812caa3df67f473e77ead440060dc89a495a4e44b13091039464ae2cb934a1876b19d2aedb0119e69350e9be7c6fb911d7d8461a393704ccd9e58f2ccb42c0ebdfd3b676862dbc9eef9d9fbd15ff7a36b3a0a86dd9b1ae5a37b6bdff7afd1efe8250c5b8d7034dda27c2f5dfa8bf41289849a2aad278cf4128e5355fae88dbae0fb46dbb8e38a761957343b5517a859681660ec9b21779374644b2b99aaedfd2e64e38624301f7ae82fed63d5d1c073650ed10fc19138589c9e1e239de6cd39499ff6d117e7d612ef207d8465644aa35f1c5bb195ea1da4df7b1930dbefb8279d84654cf8e2b7ec6db9433bb774424316985802354849a49209e5f6d36442e9e429e5744af9c5d7963eba45f9bd2d7df457e9238cf28b47275de6a67c32a593a8a4ac1775414c95a2190120002000c314002020100c870362f18040226b931f14000d83aa4e6e4c1ac9d32888614e216308318400000001181111d2b40920ba942a8cbde81c14c3fdea0a82824b6abf724bd5fff5abba7e36cd081f42841a3e8d589954911c46deff43d4a417d352a5d0bf67278edc51fbabef31ae69679b2f1dd7c53718eb4ee3afb8976666a8e4a974971f14e7bfdf38fbde0ca8c6dc55ec5d42fa48ad8d2ecca73c5f6996e2f723d936103f66e275c9145969712f4612c0b4531b223d07758f54d2fe9d5b254d19c99c68c975561f8a97eb15c2e93bec2a5bbd2d9fac9874f4cbf027ae16f95b9dc32c4f565a0d2dde3ea347a88ea53a6e693af227ab8074de3b2db55046dc750c71d88229e79b6ba4ccb7bf918896d0459cd1e659e21344a9c2c948c1f580b88168fd34359736516b624f824f43d4cbceaa5157c429c9d4203232548654acd9f60cf4d5077d4f4e1249fd985da0b1dca5d7b1915f5fb94fc274ae5616a5b25e6d5170303271e1b05d68bf326a82f8d260bbf471cbaf7a35e9025707ca0043f5fb7ab67a840b8b3263ecc7a7ddcd4ca2c30387d8b46b73f237b8df39c7a7e7683cff2cbcbb2193eee4b46756a84d1c2b465119c01182ea14d3cd3412a64fa67c286e7f82c3ef05221cea799a616fb80a57c5270400df974dea340696b8046bfadbb678cce68e7c8d00faa8552057e02b5fb713560ae861610cf83d2e4e6bf81943810214c7fd0402c44a772326ea421f35d8bb1800341d473566097ecf7143f5b041522aba2f3f8bca1d41f35ad19a653f799877d78ea3a01b13047cb28f6a8a34ecaed45ef33d6bf160c45298e1c6ce52a533d086fe5afa71844882ac39f71a41367c99d302a77f10f59b4bd36df93aa7b2d1552dbc1232add751559116803536225b4b0a121dba218946e5136d0e835a344bf0ba5a7ce6e16d03068bdb3a852a69785b99a7949d32f24b00937601115dbf53e1e5f7a7287eae0f4532a0d76323d926d91bfc7010afc08de1a571209d26f999481337e3352418b104402042636689f359abcf1d93235f48d5872853dc3f7f3ad2bd331c7cdc15c9d26996c706b6d20785c8e81f1f91cf58df09529a6e46d78a0955eed735b51fd8ddbb65e6aae25de354b86647473697135a38ab943b7235353d654ecb64608e63cb11a83e88a9c62b920735e21b7831b5c2f39f289cfded3b3d641d8e781679335c8a9079e768c77461e814e3e0021cc9f25738c7225091cf68dcb2006da4adb010fc4f8c0546d0e76c93b1b3224ecc30c4ff942c4781139cc82ff2293312b3bf47f2aefc7eae52618ec3c09fc1d3df7203bc0c850d1039b68cbddcea7fb8c622d6b9d9c07aab8a1e94e21dbda163626c5317278f0f06ca4ba80220e22ca74839e36d422158da641399e40921df24305e7e82ed435c376bb999e24e1260d285b6a889a0d7228a209187a20001d53b9d38256b37eb7b20a24fc8d251f69ccb4dcf071ea9432bf5f31467bf588e446c442d0a3fcac9456c150de2f062ac465c443a4b26f569e763cc131502652ff50963634a3b7297ed7edca438a27f163d318a37d428c664bf4e2f501236ec7c18c1d4c97aae59be2c689146c1d4d0d90e5552f8216bc9e2b6de2c813ad9c1b7fc487a7c1bc86c4d279e2870207f616f06022e5fd97eca0a0f0c05f5271b51f3d21e15cfb147bb692a72ed7acd5988deeda8b571b821aa63329dc7676b69b753e1e288a4263bd9221bbd1271b345f8a62c23ca5c946d31b0ac65ee7c057af86d8e3ae749202f030baa6ca2cb060cebcdb88593f0733d995bed518ad7b36225a57ae709c23847026329eceed3d0a0b680e29db470a3ac7ce5b80c0d368bc1a3993d949e9a83e1a4319b740b02e58ad6a0820ab7a017adb3d06d00c8ba74dc4ea33e52ebd244af9152de63303c1e2b38e0b66d317bf611b9fb039518c189f8db5f6a5502e2c9210746fba55065f4631a725041fed2511b0da29ec8373c15a5efa4bb7eba86802f5d5a1dc854bae79daf08254c837fc2b36db3ebe78d09d7950dfbe9a5405010ea4de4aa0807a1340e88284e10cb8d90a2f13935479c3f43df595b3440f2889b7f35d87b3356e3b162afe6b4927ec0ebe42392ec9fb999b4fcc2588912d430e4558d174f54bb361c4ff8ef4b163ec0e790f9dff1ed7c29cf8bc9e64f572ff7dd22eca03f609bab34fe18a4762c25593cd178674ea7b502874384956254f085b83fb3e2d7f7e318f08a01cf8b8c49f495ee913b6101418c659b00c640104ede37e2a3a4024733529d721d4003b5e5b786c29a7388450b3a641ac258ad9091b9bb5cff234c89b72c886b043c21cbddb5c6102d24264426ba7fbe73faf96e1dd2e69c50fcb430792c64a0e3ff061b0439e4c8a88794aaf6d299ee70f8fb3a79c779936d6fafa153a11be724991b0069a8fa52ecf46709a6c4435665917ec884383125606c7775c21a035430de4293ac57cbbda062ccfc23f546c2be6049383bd3f83964a411475d24fbd8c9e43a6712183b120f5009fb080eba7d0b0aa3ac2149a8229f3091a94a820c14219ed5f5914b32bf934fb7ac5f128218b94c128b2b691350239d536e907b74ac039f3f2e69dc721927668118607c1b68fc0ab47f85e79026b2ce30f14c29834ec3f14ce5fbe05d0f1e4e60c1d9a1ee42a79c41d659f2f24b0e1f82edfd56bbe680cacf94694a1760c3144333d55bc7f4d9529d5f8489e2350ef480b787f865293c5152fd9ef71c432a358a0829676949b0fbacc62b9b36f623f03ddffb1e3e91531ec8c128d54407a1e2b82880c465afa49d2fbf0fdf099a8b6807bb2f881ee22caa658f6ac1f1616f133d5ca35d2193abb8d4baac97bd1c4cfc3128866f8eafb35ca1ee82f2b005b8575bea9f27ec427885d50214f1fe6277d71b09b07130556a2cabf00ed30c9c20d0dd9fac0dd6696baf139e6c07ca531e1c8c6e1a3084b0e6e0d50ae7275a2e14140c8696734ef8fc243ed3bb27ec253e2366b99804ce1f90b094e00a5826500b1ec278068d9c5bc017c71c307331f2b332ecbea224bdaa14fa6357ab8b300d2dc81d97144029a9c1f87efd592fe367c51b3836c8ebc51fe6b8b85c123e6f92a9fd7f0dd62bcefe2b0f00a51c75250851df3e74ba4e678e5c49d88dacea588556380fce909cff8039b82d811e0585eeffc727834bd8b8dc6601573e8fbbfba51489b97f8a12d8fe4849761f6578df5ffb8cc4a5ec3a3cde9060385227f28411e8b282fb124558a600deed95789138c922928e4de8c03a82eff7fd4d05dc0501e400388efbd2b91920156622d7f214b60721ff5e1fd3f75e121ad75f76fef59fe249d860b505865d44e486c6114580aa86ab911ce832c155ddd186b5ba2279c00a40c89261e14c926b4490364d17d1559fdb6f79d73482d6b400d73fb05aa973a3fa096317964ade506c46db2aa910f91ae70267c83d62a701817aac49d2d8db3bab47cc7b6198bc75a327cfff3695f557dabd673448d45115a151138d2d23dc5a31788916aaf88f3ca1bfcfb1240e0c32ad0eb13dc1f5b6342a3090695c1a87c735bab6f26a0af94b57b5480d4c9b4e91935899a82c662457cf91a7616ff42d541ba3ea0d46724a4729dbe6f5a063af1fcd6708ca048152fdab2efc64e85f9c2f93054524e7a21a743ea9824712d23921a4a1302109b4783609a22ef39407ad727ce30a02ef619ce69d4886502ea8703104510f52d1d961f642d0212b0bc87d6833b8e34fb6f4cdd55aae01a63fa305fe141d7a6b20541e3054642392c0dea3984fb6f7b3a8deb36c1111eba7dfcddbee491bf7dcf1fb590aeab2716cd9993af260eabdf21e3323295a34bf5f9583f6ad63030ccc6e32a2025c429ae047640390374f01822fa23c72ce5a9dfbe386498e706069f4895cc518b49f9069d39b2587875200bdbc830372e4003d57ac6448bab4402224bce39b1d2268de6cfa0e1bef3232dcc66810fa447280227ba8c81694e1b55a060295b66735bec3b69929d90e8d51db54bfaf4008ea06e5f7eec487dcadd53cb657495bff8dbe03d74bad404af68385497799faba6eb2207b6a943a63b3f03c68c80f3275bc1a0bd332ad79416df200bbce6ec7c8551de0ba6939d0f932a171ce482f1de0fb926b94ef5685febe1610cc3edb4aff83805153de8ea2e9f9e5e332a9967feddbc29c5a00e17b75b7d59b2a6d53c249730a749b6540c870f18388f102b085e44bdb44889c2d956a70360395465bd0e34b40ab5c009f2896278258f705fd28c2f2596a79c10de9d6657336b44f658b390e4e4149bb3682dddd2b2fb48dab1750726bbe1a059bc60c0831589ac33f750ad1beca08f5cfcf0a407dd8c09b28fdd3d9ec31fbd5ab1fc54978bcf9e6a857bd794c7bdbb3a4e9298d07ec1c855ad8030b0520d42df0ab770317a3235f78d1281622604401195becbee5143bada08130deea7f2301e3b6172d7a8715e223bcf31645b27e0e558e5e5ebe610ec4a8b73ee667fba15728dd0e2234009a7ff9e6b96579a3d04fc84dbb5a277181fb379315dd0dd7d820afeb4cc69668a8690d493f3a54604f06fcb73e0dafa07befe56198d76bc7e67d47da62698b0f3b1047386e110e2b5d84da07ce4930f25bcd6ec27fb98c2c7e52f5a4e3922fcd05587c3fcf4649449b8fea7cd947df28f9da4f6506fafd229008bdcb101ff1ad4e0493eff08cf720dceb6852e5d40827881130e003c2ad9e54f15794eabae60b5a7d29075d40c7e9c264d7c5c426b00719a1ac3369c1fa29f1c89d192e1304542709ebfd8a15e724912936aa3cbb48ade181c70ae8b4635c3d604a9686e8432bfe909f6365c1ba7ca85fd3c424f9ccd91556dac0a137022b57cbd5615a189f8c4ac403204bbd61ddc4fe568aa1b24eee6676d8e1a50c4e4d3aed42f21d0b0aa73a806cfd3561657979d4c335be15f0579ef847107b0562dc126b454e39443267a441722ac106583e7e06dfbf9704290b659e9e11ec901f31b00dfaf26e5edec1341ee2bb3260a1872ae7b471307bb97c112be0bafc848de2b7e7860d62e517b6f7516b2c5f26493d6f7cc9f2de67c93e44214cb72c04d46277184c4fa5a31bce681153484768618cd68e147553953517ba55c0ea5867a4088e2d480d31ae67c9b6a3c6d6bc9e21a32c85d89a9d4733ec97e5390942daec9e6d357b2609a6c58f20a76b7e0040ca48d0bc2fcea5132e9ece05fbe4669e275c5cdc02de7398513c79190f3ea0d16410e7bec85e7b055beeec354deb090617b64c72f4075e5ce16e590b599ad61cd043b603f9085be0d6af7d586e7359016dfcf26e5e18abfc99b32e4915346d9b76309d25ee98f7da743adce963b25b7eabf7f976cbd9d1af9f2f46a287c8cb79ec0ea37861a60838c00d2ec566bccd4e812f0842d4db134ed77359df06959eceac428239e854052fdd86d14941c71bb9adc208551f39e3329769104e0c8eb24742735b828c2e2247d8d6453ebb881ae45ca8887521833b545886039302b9ac39ebae366307a4d9d9d3f4f40276d073282e3c51e5f510da1cfdeb6ceb0f45bdb38a64320810a8efd61e0527d6290adceecbd775d47ea2b8f51cf6d06b68516b2dc305f11b656f6c3b6d8da64d4c7741a2a6c056cb64713abf8bdccb655be03cf8292f271ec0e8a468391b4dbf66d975a8005c418b8a56bca370a448b59aa1b37294616ca10c59fc130d7187520dc90a6b6864d2b7432d4ac0e3a7c87853c8dacb90c9630d7c2272fa499214ba803da96f7aba412410cca108698f74e0b2513748833427eca73a3e79ca3c54c6451611367efabcdd872406d8d3b28abbd91ab70c0ce1542f4464e957a59993dbeb2518961ee07201170b1049a010c407c01d9643bc42948e676f14b6271a416e05cb140832cd7601a2906a16876605ddbf5228a00b78efaab6662889966d902bfa16467ca55db9c9dcbbf43fcf4ed74d7bad523288f494f1c3dab4e2422c0ac4fbfc7e7d8cfaed6f97981546c5171023e460c447414c1bb1fe1807374da41f78d4240c54885655ce55fd4429484da394f1f7949b0239512fd02c2ba92398bc4d7eefdd94fdcd14532eec727be4e5c7bad11381c7c2544a7d9b67a5826f11b1e4776aae6eb636c2d0bf32ea995bdfb803ffd8a7a565e23587cd66c3986ae179f6b129399f286aad7e4ce26efce8532c01e85850ad58f609eb6370a7dce18b8018c85824f37e545b95df1b7e04638c11546c006ba5c904212833b48c0caac3a21e367370cc100df488d20e221d1c071e06c16c28682b7a877475b6e123dba7c4420809d3747b653928c2fbb55a8614be89a5aec4e20b36b0430939971975ba923d92c54a8fe760f14b5d9e78f6141234b6507fa84b06c87f47c7939de2dfcbe6f910c3d056fa4977b51eee5781c4c536ab4af17fd623b417e3be4c567f18c29353d42534ab4a460b55be0bb5eb85295b16697499d165de1d5f3e402d51563c83a3e25503ecc45343253ef75d71f358bdae4fc65dbd7397c8937530371b34c803d3ce74b464840b595b84ca08671a610281fe8c1b3db9ff89387926d21acaea6967ca3174cadae1dd6585dfb606ab396b2827e0a57195524ff9a1326d427964a27fa8d3dbfbff44e550fac481ee644e1d89552af309c9efe2cf841d2126fee500d5802f22b60411c899e14b0ff836ccb85429ca8a2050d4d623e691184941ee4afa9e29ef8b865110d6861c4e2f305d9a8351979f4ebbbe759ee0cc9bb1637a78285897fd321ecb937ef08cac77666e5caaab72e2355b11416ae100b304799f5d416e59066edc0b833c01a3410c1b9f04959a1b62e320316a9268d7f1774a215ff21b62ef2896b8353335a32903abd275760197aaba2c6d8918d24424eb0f492315abf235c01b1a29a8b713d121f9f32e0d48a952c2882191fd836e085cceac673cad2f847ff40292e3c12f2764d29c4b2931f2c2b489abacd2b32aff72b1b0c58d242fff95c88cc99bd122d147f6d6a270403c0d8569dfe492478fb051fdfd5564286104b78c1c9155c048000d26276925961efdd6b8feae919f1a5de380f474007b4f9149ebe8bb5e229e4fea7ca54e11efda06d5ae5b930406e0d8a94c16bed42ce73e6d217c6bb5fda479247be06b8fabec7b99954952feab89ca34eccc4a3039c527955fd78f12c85f3069a7758287c57c27a9651e4304e07e4acafc3f6b56152fb7f5d0484656d3c378f5ab38346e70735de0461db6ed4d491f9af1699a0cf3dcf6aafbc3b7a77a053433abc351a6af39d59fcba3aea431b19d7571ea22dfb11c71321ace3b8c37fe23c874766ff44a4320a75d54130d80ec7621df0219b8a8d3e116f5e1d0e85a38f0a84c15dd40af3ed4796a5291dcdf7b012b89c528a348a06b5f9db31b4e18d345f36ded3be82a879744cce0847b0e13fba15c013ae892f0ee8c7c6840c1a5ac7318de809d9c2ea43f2e3a5136e8858f82bafc7b14ad066120226191be7ea480658ed5103c85d3224b110359236e647d5163f2e2f9603a6851bd367e395c84b4898196faabf63eebf1e4314493bd14f09eee37c4f42b4b86de4afae186f5b5d75fa5941dcb0ed5afd66c7f4070ab0b4585632d3c0e8de767d1865ea03bf397cd50e4fe0d7e0203a00b656f2003d3f6f591ec2ea1c6ac7542a567e39c366ef52ae892915081e360014adf7a594227c8f4bb03c4371343f4e24ec34bc23ec80cf1e7db1534186dbada216d7b9cce945e87614222eca43e0e33304c05939e44f5754e7ede6ad2f6268fc142619351163e7b34778a5c7807ead0695d07113e7a11c176a94021c3ed9d0cef3e4b274ae293aed5d9d3e9cfc45e35f5dd2d4b4ae761229b05f8c81db99330c207131b319a13d527980cbc82cb0704fc465ea75f02c4cf9bcb9c320a9721e27a4e9c333133737412cf8af2b3692334d3c4a0fa6b0d6eec86f69c1f88582c6d7645c9cbec53a8a47658ec3e1de06c9cf5fa67e4031e6db6895b6ae9315f67339fa290511850ffdf64f1dd5ed66c08cfd53fecfda9b66c7b49d9fa242a835a9da124ac62891871c1fa5be35e0ad9eb2b27ce3cd42e767ed91e4486bba2ce72df8c112bdd0b79b3562ee5f531d0f01a97f64238ea8b28f054fe4f37b6ae859f56d17acea721d3b7eac6f3d7a85f2e8930bf1856b8ac75cde72eadbed59d53f717cb8cb54c56589f60c995801e94391fc4724e35f0551e3b301f17e40584ee415819b3b7fc12d92f3429c3b54079acc852647a023279c2d036a6e29d480618a9df651e150166a137efcc2e309c3f72b8bb590cad436477909f0b8b0d94b9e6c7e1d682d248d67403c55ce1ca82ce8207b626e4ba6d737a16c7612a61e93984dd6c28a46f281fb34122bcb7c248ae39207674ae287a1f79387df61395cb6679443e482493926bf10290ff5666ae014d6b82b6bf139ddd89a9e34460640b3caf0b70485f4d37ab6ab6362429ad0c8658b76b900602ae8ccad4bfa3582bc323ae946d1b75e44d88ca86d0e5f637a6150882ae0f6aae405ea12d6df77ac663e28ab6e63ac9d3b8082c951d2f83df4550f2e645d4892498c52a3dc023f4bbc5500a3dd810a382966ea97d0697cb4fbb338a4f0b078f367ba4938059f5ed83a54f39788bb8404c35309bb49943d730237444bcd1467f268d8c83c6356bd751820ee3c9c576d3e538d5a87d63e0fa4d35ec0ecc6c08976f9c768e593d7229d4f3e4670f7063698fd873ed5712c0bbc2fcb87a08c432d3523798cf0119d51270496dd5e2fe3e56132962dee12d2c2f3c8f41f8fb29fc13975fe24ac35d696fc52bde035f4134584a005936c80a4102fb56d517fbca6b689da0b0cbe0652848599c0737597fbae03741fb0bd756fd40ae849d8c15ebbdb1adcfce40091323cd7f0a2d06f0fcba69a35c0db345b3170d6d03b7cccaec060b39402f8ee244c649b2523db53c25b6b4ce6512e08d2dec88ec22b203a2901ce5f433f6748b6aff81085733a1174ec4a3c55219f0962c00d8dca47fb4953f768e0a7b45f2147cbb8fd0871a2f180d82af43d00b3cb0b88fd63ec21e89e1e2221d69c7bf8a01cac477750127a4d4e99ad4c9bb999ef51e493b8c8e39c305fa0b86284dcf6c1e714c40330316d555eddba7674a83d2bbc8762a22f69d4ae2ff64381a2fe68a6a2e07871d4f27a9df04aff1ee0ba714262ccd301c7c3e4f18ec3e05a0f9d49c0bf6bb287fc7611aaacda61533305e7b488d4e03701f8d26632847e523797198d2ee4c8c8865cf1876e9b2bcfc1cdfbe6271a231922616a2aaf372894f6f30d28b065e3274f89faf3e02a24b0a541f3d5995d509511d0eba57da48e857f40882b2a65683b1a48d59bcd823f34094b754365c2db67dee8857b277a206a21f42de6ed2c55fd11ffd8d665114c780d8b7de7e685dc7f6fb36b05db99afb5fb745d74984524677c6babd41bc08b1228a2288dbc19af134abd271d76de955e0c5f4aee350a12487ed1013310a72ae9bc44af61a650d1a8b3f006044ae90930423b0b45a9d669502b90bdb098f9b4ecc5c8622e7429a0dbcef72b0cf84c865a8e938138af67523985787f0ab9b97da16f9cc888beafe8823e0a02b8b200756d81ee15adeabfc0eab9e6a3180a6f7c7bb1dacc65de75bd082d13b1b5fd055c487c6f1bc423ece879ee7f87348cecb87b6a8513032635bd29017deb751c9e08582117b880f6c355db47ad76de14a141da2bb894063cadd5c70520ba0015b286f61eabed0d88ded949251b40a1a23b151a1877329e86cdbdb1310936f05cb4550e069192a93af62573c4b708ab221d94210b874e5825bd6b2c52e78e8644773420f3759c654ba1e5d258ade0963191b5a1dd2a1ddaca4669666deb77496021ed3a14f0ac93b0c7babdc59789ae8a7280149a8d38d1ff581fa38b94c16ee8654ca1b6507a9a2b8b0bbb06b58d49e109e2d9019766926667e3fb0c2c2a41e783f7e9eff953e86750555e0d24aec890e9951583924fe18987eb161cdb84b13161c8d41caadf7e0bd6f64ee815053ccc00bc967c84584fcdbe49890a747cb647d014d48deeaa024afde198581960957923c48d94b32e93af7f9eecf7c635c68c2742cec1c880f20207dde5f8ad586e55d6f0987ee5b2519fe8cef1379f8dce8b39a42e38889f7e1e4c6aa3066b780d7ef584c3fba1b54cb268ac10ea5db8aaf13f1ee2136dd87325541233fbee10f25b3d1515bfbf8ce2e3c66bb0867ff1ae219f8805caad54b0a3191ed46f7e61d18020c3c9d8f475d077e188218459fd796c46b7598899898b03a0464140a2154bb93cea55f60d6d6742781cb0494b0954483360abf280d7460b52d3fe84d95b60ac9ed9b977cd6b65cc9cfbe7b08dbfe3af58c2e8d8b847271e0bc4542c1989982a0a22f5453e0852eb76d6eb362ffe82e709133431e846acb9184fb4f44918fe97389528384c01f81eefc1a1fb7157b3b864a2007111d5fb554a6d0ff87097af4ccca2db136b7e23f79d6aaad245ff998800442ab84a424ba24ff38599655418db7c07da9376e5a474a9c7d81668f8acdbe6e17c3f49035e01954d57538a98ad3667d2b332916cedefb47e5202d76441e6acdef3c748ad0fcc267698327f32b8331bf3234590be98077ff14537119c4f2dcc7f64c25f2f76bb187dbcba8e5a227b4f41d43a56b6449279adeca752e449362c7d0818fd99a4baa620e7e057426b15b43daf1832c4219959dbc6534b6667d13312c8ab12d38f7f5ea7f8b69498eb8abaf8a716db958eb8706451414f956e505758890ccc4bcdb44e3ae04d1d2a21603c53367a9e6eb009d4171bba4779cba21816fe0ce2c371dbb09f018c59ca15813e0a04119475bab3c1f0d3ca79884a1ba3d8f264367db973ca699a26bba920aeffb8c98d4acd309a8eafc04f52a4f5d4ce1adda7e0dc7d89e759e2ff479463e34a5676f56f796f6ad4e5ee454660dd642cfb5a874d4886a402ce029744bcefe5f81bedb06b1dd5b1f63d6da35bf22636efe884ae42582bf46baf6e0592385a31c853d564e89ab538bc12ed56fceb7dfb3e037b93d70ae7c315edab48a9c561ccd9dc91955660d371eef1548c88cdb8acb9fbe5ddc4cf7e4f461c335e0f8a3e8f2bfa8e3ce1227b17cbb943fec9e811eb3be16b4bb442d3cacf352dc9feb05c0ee0b3f044dca5477f3994cd25088209bf36fdd82424d8d695d0c5a722aee9ecf28c352958b2882a901e93c4c10ca49e7973e17f96fd56b99efa37dc15a2f45ced1cd63b972b18c1f1d7a7fb6dbe4e483b91a6d842d8e141f3bba1277310b41acee62472f184d24aa2e6423a3943c05e408a20231099174373c763e690950b0ea6e31075d414818c4536aca58f98f5ebebe3488b4a1ffd1e023ea9df786666643d2a4b729f0060eb53886182a9f03435cd75f318c2549a79366761dddd71ddc21d5ff01aec0c9a33d4fb649f99759a393764df9c3db4119e8d73b53dac303a8ffa3f92936ca1f4abf8d0629837090a863d85775d3d4e26e99dcf03cca4c9cf32c9d98154e391b6c5ce72f28e912181ee7fda8046181f69caa360506644df207ee55e8a17223bcdb3719518dcbee8796a0a5ca43003a757a841e88563cd4b72eec2c62f2b081a60213e25b810ea0fcea7dad26861dd7ed56c98767fb7b5a5a6aee612b843a9930bfe15bbf25b6c2aecb170361c67faf22a5066ac01b1c4c9f416b13f4a1081604bd2054f9e46363b67866577d0c621046f7188ce6397ac60844e8d8a818ef1fa09e851958bb252381b84afc7f382fbfb9d7c857fcd79fc8acfaa2f78f88ce3899e0cf7146b5011880d1a1946103572b4eb3092ecc77c4d744d03229a4be0599007439da4ef36fc69c5f59b229a46e13c616064829997155caf03bb0fc07dcefba8477adce1d668edabd14a708fa5a496950148901429609dbafafe7d6ee9432376415a9d4ccdeb11446da6a17bfc3015c6c449a0c9a371fbcb7b24c9d75757ffdfca3f0c043d91124c776ec3b5083ff0cf93448ac917acd9ebb2bf44aa4f5d78b138c50cea407ea53887ba4c162dee9ad00aa1e7ae861a8219aedcade0f05b14374f8d12cc7562a4058c2620308902948dfe6099b0d6ab962ca116d6d97668413fe562fd1a6308ac0f25e8034d8366781757775c88417709273b14e5775f4aaae8d7592b848a2eea62cfbfba52884742dff83cb50b1ce52b31c2896077430c9b3e633e9784b6876e32d065276df0451a1d32c0cc6fbd87e75b93049d37e6caa0fc6ca82250742229863dc0c0dd58ea17249bd06bf7856b3e28d0f5959e9dfd0de7552a892821c1e9cebd1b54aae2bd5adcc79d6937997a086f2ac7e8d1491a27ecfa0e6bddf443b797689d04d576469934cd21fc9f80e65b1c8100fbf423a0a1ddf908dd24ff14bf8f05b9fc8506e4b8a90be677da9560c2afc83de491cc4b97f94403abac0f0a194fe64be626019bf8426dca240383b6b8b7f8ee2d330d5efad6939ccd898bd0d0d8e0142389737439d98512164a7c1a6882194e72292abb10cb6590c0ca258fc4eb274ea4e3c342bf379927aa4477b962f150394ea6832831c8fccf69a5d8a0b32128e18a4344f1551cb06d2950222ba23b1c8c89655dddab670f4846308349cb9c0232deec73a8f44e26fe46f03eb45e5818b704bc967528a9e3620ab508089ca2b9588d23a9b664742892c6927e758dc1223fd388b65fae4fb55b416935de3d050b654918b8e9f78d91b49b994a69c179e1a2d80789b4e1a70843111a8d3bb7350fcba57d154838bbc1dea4f9159001b5bdc71f35a629f69448d2650fa0032919423aa1ca27b606a6fb4256346dbd0a60e3384f5bc9e1f177a4205e8be892ca8f6919246029471131f4efa04f69f26a3d23a3ca07a57a993acda25b63457e1254400a61d9e4e5cdfc13199bc835bd22a848d6fe05801ae7b8fa8a10b30bb7d9c8e4cb583e8aa5ae4830c9f14b933354dee709f909c1df1c744e6124d06a7708e5b1dee475f0a2c06719bdddbc88e4e43b50733fb956e4033bddba17c3c2b66047f32f304e54f56db386d4a0d10e52f93b8440a164719928625ef4a683e9666a56b0320717c0f9f14fb5edf9fce986b23cff84a2aee5271ce5f9798bafa4fe6f6c7e7812711692e83363c017b946c0f91d6f8be40eacf2fb827bae3d54d6d4f9387b8e92f3f82a1392b25f22f64174a19e14149a533725048908b6292200567ed9fe2010c1a7ea3347727ee569d472d03e260065991e26af101c251ba23a7d7480643295fb203d5b7a3b3e6e25af36a9c47ad7b9c38498e771dcfcf31574b8390c9191075abab3f89d01bd559effae6fd0c75e488cfc6379b8bb0dd3be1f5374c87758c011ab5b0313a0b34a32375b190eaea9760f336c664952e07beabfc838b9b8a81a5c420bc1d2856a83b67e6ec93c1b6258aaeca26b04145cf218cefd7b613aa83e3b9cdeee9fb3f1f228bbd6ae65f874212705c407752a0b1d740caae552627de4ea66e87360a180e31827b7c9fb0835d9c7ab168706ff865dfc7e1deb6e85d1a544baf53944d11fa0f6cf35c6355e202dbcecc76c52f3d188a43db6cc9dd73a4f8469a824b196f62124d32370f5a85ea45c14abfd037b752383cb7c5ce4725f42251b4ddcef8b6ad07e5449de1e58cb0fe500f6251ca865ad36c08340110ece19144bab4cece6964cfe2cc3bd1d29d1f193260ce92e734034630f2a35dc34103de3a7dd0e8b8c03d6edd8dd277ab4a7785710528ba32afe6a9225ae4c188bc5ebd50634fba8cc59ea7aaf3c7d0d052325daa473d2871e2f3161fccc44876a1c79595f6a46366296ed1b0c1cc49bd5cab8e05f59855139b602dbb0e1825889b2315de3594e6883d720db5558ab61b58efb142ae4c35b26a14972fd034ce7a9c831207f2a17aafe4de3d0bd1dce621babaed2fc8e1f561660b9626a7902a80d0ea0867508c9c0236c2900dd38d595b3d1c5e5d787b3dd92a23edec5716aa1e56d28f1987b215ce02664fa6b212ac3c842ebb7c579b3881c61ebebced8a06acdacb30ccdaaeda6ea8dcf57cbeff0eaa54252f18709be6c46358d9656054aebb848c7cd1b53223f36e94a5262215b004176f6963f05102b736dde71a69ffc688758c0961515525228552c4f630ec468399d151891721bb00a3a1ab5a92fd29ba2f3f465784c904adae0b00190ca8b0ff5cf003e63c258a2dde978f139c25b7f591c064e854521d02336fa3ed5953f9e6b66795c1a3c58affa386f8e752d4d57b8b57a88a4bbd31a297bc82da93217c67f803278cc3b8c6618154445edadf6e512e79dddfd81383ccebeadbe3ecf42e7ad28a18880963254c9e661bff80a7c84f7d7c53aa7fe71afb3c5004ce2e37ce595e88c642599718affcbf64c904780f035931b5c98985693ff9c6403a2b10be6750e6eebc11867ea182f0134ab5bb5c79a5fb7f527750958cb0e08229b4377591d30f91d1a534ff23e87f5c2054c11a57ba12fa3c2b976c00c1346185f5ce14de8ae218266e45ddddf98344364f4f214178f6954bcee6855bd3296b610e0fb69c8bd219aad27987fa31879e4743006e5e0f92d6bd15cf2f4b95fa0d8b7218ab21647b0bb1c0b83fd16ef26d9148d389bb09c5963cf9c9d4f6f539d827fa269cbe81c815c4f0752eb32d86352ba3e3e0427b78244d1e360c5504f830394b40948ccc8686a6578759b6991a4df92984876467262e6636642cd55877420344bc6569715e12071e692a7cb22711d90feb500f83d3df3f1c32f2183ef4fae32de6e8afdcef1facf6bbd531703d0a2a8838a503aabeb506bbf9fb87e2836082e1c9c55b0e5c082c0005b62a7778580858ac9d4d82171888b2c605d24b137281cc4556faf70d786dcbd9ecb11836b15e5fd7ea078399ddbeea4c4394fce1c704fde18a3588ba080cec67ea2bc3312cacb2a500d60b8e54ef07e95b3ef689ededb284e8c9c30b587443c77a1628cb3340ca7796768fafdd32442bc2b182d8c30fa54967c312894179aeb37e6002bf92f76af8adf5c12a0a43a7b419a178ca582d4e7190fa735411f01b8246ddc10d866916bee3dc55b59e58facc2713350bdeec614c937012efd402a99c5ca83b1c801d879c456ec4ae621d58c01d65680e52329ad87700789000a5c802ec7734bd7048b6b03fa009bc98e4a7eb2c34d3bd5b811042424680f5bc6c257cc32726f24995f53cd1ff4c746631f090e60892fa7b9e7d1f0d683121e2fa89b09d8594974064b33d11a9ea517200b2d570355eeb9a39f8cae722f970053879cba5ffb90c551e72adaebbdd15fefdfa0f3cf4e04ef9b67f9fab96bfb5d72d6cbf196fa98f1ee1e878ffa145c9bc4aa3e411954494aff8b80bdd7049fb3c814ec70dbdb414c34db693d6f5787592a0f1ebf7c1b89bfcb3fff936d7d7cc07326a52a57206c33ab8571101a11ce9245a6196e1e5f922edd50a3ad03b8e36fcc21667453c4399b0f4ee39f15550985c911cce8d26cf7ab1b815e7216a8e96b8a812462207f8a51e9a54923138a0ac220bd00bb11ef91e1e79f53ac8a70783e7a6998680e36000d002d53ba97fd51a09774f18d9a4220ce50c39fe527ae1024f2f285848ae29af638a1f5eb056305609f5e15cabd7b90f15442765684a010cfe570db9ba66de5ada9bdcc9456a3957bfb48d7f8051ab2234dcce2b8b01ae557c182a8e9500d4867951925f01016cd52046d8325f45add9128200fcd952cbc13230d6ef0563b0bdaafc71ae3c4f3f6e68d5b873f164fa1b479ae98428bb1e3cc034dc658b8ea4980e0fdf7adf91d61992d50a36597734fece06d591028ac47ccc25d7d988101e6b5cb656c34e362af5094e92c20e0d1f3c36dbe2f8cfa0a84372210ba20357e76f18e47e3e4006f1cfa400d087a61fcd2f101b11befeaafdb2994576a78f75839b6a69174175af485abc0e0a6dd81e12377ef180101d3f6d21c36eb58ba64c26f12a1d97c086ca5846a36eb3462bf35697fffc9bc1b97d0266f85c8118dc6594cf4ca82fb8405433583610c50642728ab66df25b1bb94c5efba828b7df6eeaec9530cc9ea33106e18a71790e0e4e531247379efde8299d39980e50a9176e18ce6aa82ff11b5c7f1694ea16294f737bcff2a0d9b4b26bd39db9d4961a32210e5321c667a95be90acac699a906accaf29ef36762e878789970f13fe6160db446ad1d868fc6857e68ee66d6d085b863ed18846e55e501a8aed72dcf5f08bb7ff70b48e50a144e7a037d214043015c69b0f18f16fdb7f9166dfb55a68480567cadb4fb21fe84559bf57e35285b43e3aeb1e5ac4feee183e701a834a55b0cd4b2f61eb9f37ca8a9e1efdc97921304be01b18e1d8a2d50f2c7978d090590f5c8ad4ace6b78b551e65cea365c8e352c5b4d6ae57c5a32e6eb632426b6e6cfb290198222b29705b4219c632e95124ea3d35f2925e45358733ba4ad75a7490ee8e77f8c623bdd3ba5a7c054e922fb8269e684ae154ecc668738bafe1a0188dd3beda462d254bccbb8187a9cc0af38f7b86ba2750b4a83b7a69da5a8316aec1db8a4f1fae550f37deea4ae9d47ece3f63fcb8abd655a94e4a13c3dcea1c662ff564e18662602ee74df9841be146c1c537454c28c53f4ccdac8c632c4991e8eacc8671782fec92f9b7d2495692f01880d715eeb4be0389c94533b93703818e330155076f9aa9be168007635b1f526d1ae5c92df354b5595c8f6bed3cde41ad916a3ee440ba1b65a93bae9994c4f8e601e079493963ee67061874ed5da40cdc0dad7247f68596979ab7105188584309ab480e699430b5a433b3c3013fbd4a1103ee8b570ddae0e9bc2f4567a94da0d98b2f182c944f3b919caf8c009fb15b91057713ee370272adcd8199de644ded7c908803c28b47eea19f486e21cf39d0576605ad7018612958263f1e672d044026f20eb1998ce3a4eb5704353e56b9b34b852dc948dc9bdbf1e8ea0a92a11c0e69c1ddfe16f39449f730681897cab56c9ac9b7d010005b1a93201adcdeb8a75390c6ff54b5bde37028332de40ec70694ce8fecd780f66c031cbfd4aa7c7d4383e5db1d2451baec921a76bbfceeaaee1530d7bec19525713c63f37a1b18df145dcbed6e981d600a6e1ec26b540e92601e841eb7114379313738f413fbade80b2f501f9bea60d12a43a045780cb4b373aa6d610e206ca386b99ec7fa1ab6681a9320bb86402d6456a8866ef352efd816affa080c327aeb164b11c3a51c467a5c78ee303787b0ac4ff528feec12ca3914f778d57b31d8a7eb2b8763d95fc40662d230d0b38b0e5054c775ff232cca8182b3896e6c8d1a2deb67ef93701b60768ab267073c7c89a070257ab1c771f9859c63414cb4f7b00371efde5d423028016cd0110c06e83069ccc4b26762deb14628080bf62b3700526069166038d95e9b1b1124775efc20bab823a52505ba008f3be66d99009d7730983766a9101f6ec5da1c69405036fe5de161db26d6ea785083ac9114148221fb14858b5f911a561296961b2fb232b0adc013b6802a2df0a766aa0524007f932a585782a54be574ef37a4db1095cce6be681302874a9fb8b1f992e2e0fe8ddbb4e84898cc168153e21d70f2bb2c8b9492782e169a753d9cb525e8d49a2500d34eb0a2e938ed7307563d48b321749501595da7af439ccf5861677e3b90632669029110ba5d59e2bb4b6f832425830e954a04d994421dc8a739c9878282fcdc5a928e20cfb8498b4687f921469938265809e04fd7ad21a0773a96e034b02f066edc0fd0afbd445f88487a72973d333ca5037a2d9f90c5eb0619616dc4c575d80569d9827e26a277d841586f9eef6394a325b5a9da5816b0690c558aa29a1331c55c38ec713216efbfb9322ff24cdc82e4d4034b3d65ea8c84efefbd3e5b116471a9920b77088a9d898fcb49cf8c4db764fbebb39b39d7b7b25b121d7ef7958930de12ab652153b0e893673c23b12b60c96f8a7c28d0ba6b5fccfa50594cfa6890e32988cf4ac0cd60480a57a84e4e25f21ac2eed7c9ed841fad933e2777f7f09a13bcf80988dae86dbe877d4e2e6d57c49d22625db425d9c44611310c5f46514c1a2c0f6b61ff1620410c05dcba6e427b9650d3baa8ab87e031f5a8cab39c1fde0be43302f8404f5571e5af37901145875c1d3fce05d7f777e1ef2f012850594b004888133fac7d0e4dff2b04711364bc49509c2f7e629b3a4f991497d542efa31b4eab2e0625f9d3272247e1c4030f9a19416fb5935622bcace9f200fbd6b7704e655e223135a99f78ff664764b0174a824c4ee3b0192c2768094d7c30fc2ed5f70cc6ab68fa1b493902d21cad675f0934c31e77b79fd45011bd0e6c6fa386f39f942d62ba5adfe773eb958318a52ba4c81e075e1411f7538ae17ad9d89d7f6875940226f6d00f823a9c58ef23480e25949414a5f090ccea2542db643f22c2560e906ce76684a618e231164ebace175f8b31e3bfed98153775b3a2004dc9314832d5ae47daf51ee6a813b073832949408cf1ad7cfcfc7f51cd2bd4bdd969751863183fe118995b7a268f35ce53443b6e12cfa4bc34c084e6d3e9215b6b51e477cf5248998da802478bb3192781efc22bfd2b2f85fb536a2e55e0295c094f92ae205a15bbf77e709b5a6b8157832c2d3e67669fb054c1f37c535fccfa7e409f4cd81fe8fabcf52ea3991ccc37016b661ff5bdd1d362ecb0d547a4351d567e1a839ca9e3c5bf27a9769528d86762e0358b7cb1b5a51115ea31c2afa086c93865c2410096e29f320b21f1c0887f25bcc50b320934fc9daf1d6589cfd66bc267f77d1128003c18b5c9ac345e883ac5ee11c5c41f543df29718dcda23807b1736fcaf2613003844b709a76c35d89173668af77459416981f036830aeef0eaeb1ca09d711bea22350f2a49db81dfe1b5a97886d6a15cb98190dbcbb877a3fdf629c30f16a6dbc2d674285f746fb1c2e4dc81f42b52f064ffb8a32da578d4ce9b76abef5a91947760496d1281804ab6f5bc079e19f02fc1ac63f76402f7a01beda48a08230a9dee6de6b8c8998cece6a4b3d3a37e880dedabe170153c9abc9541140cd00b9be5a0678cfbb72f268f145f265eaa781c34e8572b96327a64fe48d57827d492fa52f48907c0726062fd737640661d835221668cbcfd44c18b8debdf7c4efc016d4def3660e89921e037c27c7cb8c350741ccf2ac9b16c7ec14acc7e4b10d25ebd205d7728224187ea93867da359a8a6ad25d56a6e55c9b56c7b5ee3abe763d6b672725238c8c6037e8435fbcad8120f61617690bb2c454aed5e3c3a96f7d9c09342a3170040ba6e8d29021c70326cb3b8187e14c9aa1465b010a933724962ee485d4a46e1aa9d2d34d485827f3cfe37039050029d6d9625888806cdd36c0e1735c0ef6da4e709518ac074949a3c299b54168abce3198140d1de4d1bd92e48d59daa82abf6efe19c71cbc62f58b4efe1290d3e53381f0fe6915aa39492fad9e830408fabd9f25f0aceff1d41e9f51670e3cde28d1f89dcca8c1205df05b2e6c49ce41a81a9bd1907fb8fd2827f41952e5cb779f1401f3893b6a09bd0aebaab5b136590235e02f74f98fd49390757d8e55df118b7accaebeff5e707b4c2dc06e0cdf03d6444b63ddf3f2b7642e585774130b8433a322f989b485f6947a1e9f961a9dfe9fc3ef02228fa1586503d389ccf054d5c5c75c3bd96e065180487783ece3d78f79fd925ddda2c371ffa5fcce34c1e1462d54090d56ad53fc0090617983fc9778893d016ffdd7d809d440149b3447c6567ab62e4b43a90c784f4d42c777dff2554775e325d1c3100bfaa1bb997aaeae09f5c8ec8418345aed6d18de9855388c3fc992e3dc70ddebbf76cceb7fe39883301da39e36de59900d16d9db725f864746823bb16eb2820f1f6e4f39a3026e90d14a0f773fe6ff0ee3cfc8ba0884e0fed0e24c5a4f97c6d0e5ed7e07606e06aa4d5171cb43105dde426b9f227e69800a77f0797874bc401cf356cbfc83f8ff46cf1a38163d58199403ff40ab0177d994b63771332b0a7adf6674aa05b720dfe350fe87907ce62cfbe711c34b75a3e6eef46582058425ceb36c6e28e091e262054059cac5b54050ce32e8c3174db761ab30fc66972d95cd0d64961633405807e0d007556f5102dc2a49007832771b84cc8253c71bd62b07fea9e4772a7ec7aab58b23316faa9baac9a6f32395c986bd4398077f13cf5d2c0ddf0e6ebc469f46eeaf22f1e21714ecb417406a1b90192da3f1d4495c24cf6ffd5d101283b4649796ce7d5a802891d59ece54cebee724ea25adbb4f35512ba0d03570b1990b77c0578cd3364b7e51def8863d4268d1d6f3ec90d2bab2f557233d0d94e1a364474485c72e07cc9f90dd393aa587200c7680cb7e0011238712be6eddae7d5658a5f87a60432fcf767210978716a2283cb0220e5f9724a85107dbe64019e2763722dc8c6319909ccd96161512e216b137d044536ff5eca2434182c31c0662e620cc56752162d5b3fc894812f3b6eb862b4d7b8da5921f73e5d03dc8599526509cdbda1d6e8d80198018a5a91665a9d9fa7b3e841b769834d97d49932971db5659070201c4116ff76a0ee14eac2ca39ebd5baf84eebbf3cf8c2e3af8bad70d973f1067d12744c4b652ce27c2c1b80112115cdca62fff9e27de482a5ea08c6a63b633c514c73b3b52aaa47b1d79a65ede2f58f5b8cf5caea9070050d4159c71c0b9a4d6b552531ecedfec19e61b69ce0591ff82c6197f73478eb6b8fa7e62743169c92b5dbddd52c185029dfe5b558c7af6c7a919dd947c7492798112fd9772a62303014c62702ef28846a4279d129118662791a8ad1c157b9095dc022165cae6f190824e5841cab8c67a9ccbb432a5f18b8d2d3c89c57251bd22d4b62e4865c1d230c32b4b81b825fb074665699c8507af4c97bf4582ee10a1829b3994710b27e19cc96a1d4a8b8385e9b3b95b13694750eea4820d7917b322e6817dd048ef06d7bb21069cb5e5faae526cc71d9823d58635d49cc3221eb57db3aa779b5d38d94c87261048282fabe0afb000f5c53a3ffdd98b3eee06d37c8536e50fbb6b54f197a94bf8ea7ee7036feb187fbe2dfe1cd57637a54acb74ba3bf009e1bbe308a2041c61584b1644fa562000ee0320f33f50d34ed1900cecb47f91eb82a2ccfce0c8707651e422e913aea2ccee913e8ec318dd4aadfd9f687c8d27e61d30695ca6599c07f7b0a8c03d2f0f4859cb69d082462aac6634c59928942cbed1a5a18e439f5e9a3e8dda433d092d38f4a1e2dac01f36cb7cf9e0ef41b21cd4e9898557d15c1318a884a3090364245b86af30149a19866506f0d5e80d8f946142bd4930761b994c6fee386a891704809442f8b43fa770185123c9dddb3918e6c9ebfae5adfe866f66c0627553982f7cff6112636462ab2aba37c4f6ce5cc77e3570354785c2436e49d1d774ca2b9b8299805896a4a88390ad8d821e0c96f8efe651e4f7da2bab403a1c7fb3c74529390ad51ada3c59fa0b02bd22198a3ea84e291957a0554f22948ae7262f74fc312b1dbfe4363a32c04f7d126561e88d0806e2658c38e83d88ce9ce88bffefba70cad88c090f9ad9c9f5c7f933e80b69862dbf43bfc3f0c726eac154eb71e6a8db358a60670b5a310b6541c22c2d81dd250fea72f899a641570219215d52145c703d39008b6e5d31775ca33c57db4818a6909f69ec5ab55a5a6c680775d281c593cb21efc3dffd4a1b78519a893d259d525ee0a9c8e980c9d339c348dd0315746f14b1d2276e5b34c83c60be9ee5bc173c5a7ef69a5fc66a93482a6cbb45690d0ee970e577ca1998c614abb5f35711e00bcb9f90fc50e84b8e47cabad62526873921bf58b5f8bce088c99cc48a377114c0699796897242ffb2d7e2ff4e334cbc1330d3ae17b92e004a56c937c58a6a44b386bda191846ba8d140d2a09bf46f374987d330d8789607a353f5b84bf979db1fcf591174074e6fa06141bc046725d481b39c60ecd7d1a5cd9246f3485719911c2e8a8cc71ee9b7897ab385dc5836d28aa8de7da5b44a6b16545267a718db680765bde65630bb513be1fd796097da98d13ff347daf38a8e535035682b3c530fca9438f7596c07b04ca338132899c851a09b0f0b9cd22807fd9ad4188c16b68bf28ef36a1b1942d474886d7d87518e2bb7b8fa8cabf6ff95038f39e724b979a600f73526f0bcbc59155c609ab86f5e13a009ef1c201616d9f3dfd08816988631464ea60baa276b8f114a8b25d11aa70871de5928f7c6924e22bfd23f8a9330e5144f429573b65d72c21697a070924a2ba0c96fb84b83bc369809b41dea790ec0ce2205e695cdf5e74f53a268ca6d222b21b134638ff7bc1752482f8c47c3bc972d15be545b56601eaf81b55f0d0d3c1eb7aa26dcaf3831ed471bf02cd247df61dd4a6919688ff15bf80b1f16f4d017a30d7121fccbd875372f28d585797202fbbd9cf499ab0082c1dc4cb12303689fbfa89f73765943e4e9c8615c9ecfbcdcc0554a06fb192ae3bd403e834b1adfb0fbf1e06e4f8e921afe7fe707fd0ec9aa0150249c80dbeadd8c3b00e409f83501c10450830edcb9c578e443ed9a81130731c15e41cc04bb00d0c19e06d28f873915cee7b67fd4bf4f1e56fa0f53a127d00337bef1b0daad2867259ead6dc3926d096c053bbec653f99cfd89e433ef5332b0eab9cf96ec78f7e4b9284330729fc23464064200f9e6a9d1da6b487db3c210763d0b6d3bb3070ea95b5d2604946214aecab35051e2f8bf9262be2bb49125ba70a599fbc0377f029a79f32460dfb0df9ee305211a2b4d190a82130b26a0fdad7270e88a5b455d73dc8bce88e1c9f4f6e02a2d9a558a1631406d2db441b32c513dd7b2c3739be0d2d5ea4b5b4a460d3d90af5f9ec20337c7c2c784cb9fd796b1b4e2ad9615a258bd11ac8e92652188896e7799e57f7f249ec23233294b88c8151b5995739219ef0fa17eea76493ee56ddd7c5cd47ff779c361a83f2d1407c584a4c9b64193f61d14bae8bfdd45d151484fcbd61566cae7b8f1eb51e8c958e398fab2bfa08c2c8f8611bdc7466b23230bc2469be14d2c9aa20de768e4368a6ed3848867296d88a165b009de62a00a4f512c93ff57a70dde11ab1078a74b5115be11e43c39517a5ca141346654353c9094d0d4bf35ceb90f383776c47d57420a0721040966b6c1d62e0e997f7c2d3bab51e0be7549c17982bf84e6950901acbb71a44458ef48191c6a7bc6965f61624b48fcfe41ea4c1d54327cb34f7ac221d063b2e0b25520fb4db3523d39be5f20c85ee5a5d88c7da538110dd9fda0d0a62e2391945220732a02885e7b98d0a58009d00a3a723ffb9e5470aaf7e0ef1eb2012ad42522930da389e2b7b8bf6dd8dd44687c5a40585df8dced13e219fc298c74662d9714039092aa6c3e1642880c6f8d4d5243dd87be90fdcf3fbdd9bf5813124fcd7bf3dbcab63201e88d252c876ac5194b4f6d086296d5935ffcfc5cb99cb54b966906a39cc28695a1851906484b392c27b7d195917dabc9f5b3958969dc0cecb925d8f55639722da479ff0d2c232c87d3981ef17a9ab12cc8a61b04ae12edca7f2a48f363c9d18d6d5819b19ee19003bd2e87455418272156ad11ebe17492f9dfb1d3e128689c15a16844f473e628f61fabd0b88fadbdf124eea6dad220042b32e11d87c6a1d5787dc6761127566bdab8357ed1b4768f90d6611483161d22b4a8389186d6996f643496734388306ce548ec410c36c00198ff25ac2f229b9ed53a29581cc744e2e7d8d92490dd28360c14c93598baac073f86fa123f80c531a66e8affc021df8e749432c82839a3bd28122108a8442bebac3434c8a16512ab55955018555f867b7642b9db597894a75ab0000c81f2d1ba821a1a87a1b3ec952e4d2cb8286934537700c6a8603d545bd127f6cfd3e51b35422d0b2e2f007e9a55c284005ddc70d85b2f8df037d3c75406614e0e6a1c077ed9d8d5632779eb870c6ffea54f21ce636b58c94e3a5c437c7d6976d98b3cfa85bde04e2de1553ab7a214abf4ef299652a954418e423bb0da3b49a2d341cbd563cf535779fd9630e88c4de16c02a17d7c36ffe88c10f29c1558e764ba7925ef6c544493b7cdaa8c64c604378ba3a02986fd92a4acdd341a8c0c7bb3f1f7d9d9b7ee58154979b526944e9f7751faa3274230904d4011379cf228be33625d4cec99b9baef68f972fa9f3211a9576535938589bed476b56a5729cb1d9707d4cf43fd6ed0b4905db78439c4318620aec3353342d9203c745d171e85652ada68c2171b556c98ef3f8b0b54a9d2cc0e83c6e5c83ff7c4a6ff5ba22e18d42cddedce718e217d9a21d08d61bebd244b612990112b9fe9cdec3872d4be6d386a73ebb4db0ba5d9f7e21476f6e9ff929a608f52fc711a40d68bb7fae3b06a76718dc9836f5b2cf5a0eb86b529d33183692b028de22db2127c7201a1522de8f22716d09b6cbf1c49b72fb7bd212cc57280db71fc19b9d210a6aa08410440ef76b5f40f73fdf1b7abb41b532e84a03d65dc1c8fe63badb0f5227ab847eb58772ce7dc80bac4287e1e1f5677e908d91a035e5808e9c907eef7876ccde5de7987da71a8f81ae3402dbce411f4515d24fd23bf26d7005d4794ccb965ba56dd83c7cbdfee0cbda9ff7005a1c6ad912a44754dae1a1da6ac49bf288bb8f89c8e7df2d49d98e0c92a304bed8974b46f3b0846296b6dcdc1910f82adfe392decbeb5711772e9f89cd384dcb39c44a1ee077eac184bcb95133c273b7654fbc32ca2a19d783555687aa08388391ab83687ba635e7c8117a620d2658e203fdd06f835623bdc0a9d1f67ea1899e5ec8ffe6224d1db6b3fab67e1252a5ec256ce229ffd39d41259bad1d69a46ce425a005628427d395c0971d0711cc7443e23f3e34b53066a47ce124d8a70c7fd9bf5d61716309d63bfd3aff346054cd1ea73bf0eefa90a1b8cc407069946ddc5b35f7affb6a2bdaddd9792c056c9aba563027e1dccb3119e25f723815bc87de3cbcc770ccbc8ace611f10e47dbe7bad85a2a77b17249c3cafcdd1ddac81f09bb8f70aaf17cb8ca28a5c3a4ea836ed7153f86773a160bf24457ba03809a6469a292ae03a58981a8b1fd87c42431a23ca944501a3c8be85c339c32aae8344a51882a537362f392112efd0a0f62e1b89ce5abe7b08e50a1a3788f8f5dc9e27d7acefde45394b27f77cd22ffbcb26002665e29161b6a908a2801615842cff2491dc1c32a4319dcf622f9a438eee9a029eb80f8bf9e3507a5b7ea938d7cd82169964b6e7d08118982b1328c5316951d699ce2b967607a94df334ec8db489cde8f03f85c1953dae353bc7580d248af29958f941655da334a4135a24539e0e9b88bd898e944d0005640dfd4fe42691ac8b002d08bb1f63c602bf4fed452c190a7b00d93e16cbbe4d24eef721a64d3c84063a32a86539dde55e826264557fce17c04e130918369ab05f5efa631156d2c60f7469b5ccd7ac47dad4714a4524af2a9586f3908d7b2b8a6803f3d6fb58d5a25a412963ac1417ae9edbe25ae17a05e2debc7b470bbaa96e75c3a5966d9daecef89f8b201277a91b8f1467691344bb74a9292822fb6a2fb56be348509e9fc25c1cdd7a0397fd918aa89d6cdc1d51ce9ea0f12ea90cf71682ee34c3362e86d4438df91269162ec7afe9c55b9446a957c4c54a3ff475145d9a6b6888117db4e5eaef1386c221a36cef00c16a2f045b9975e15386033a40ef364c3a1e6c33b74e531ed4592de4a34a84388d2c3aa5a23ded91e4095e5c759960fcfd6f92aaa77372c47715a99b2c48d256de89b11c09c7b5fe2fa78ff22af4e45b99d2c964e4b11c5a37764aed5b30d611ca8c24441e99f960107b4dd07932c5a866d51a0e0cc1ea511541673c44bb94063254860f2679491490640f8c9fb0eb357dbc7ff6c4c2c0778f245018f4da9eb1ebd01ded5c649568e9c6711d811727595ccd4fe4aa0d30647f6796dca042f24746ee7bbe4b5d8d97893cf04944666375771f159ece94482db13f4715a4cf55369689a23c53e170e0bb06bdfd2ee15f9a89d5fc132ade3713db680b7fc368d4bc6b39f6e1f68e7aabd8882deea7461df0211c5426e8cf441e863fdb02e051f5f2f3a15ba7555ebe67b8fea237905bff2e1c2722a412b7c860c3317b6b882db62da647dcaf31a8838088e0c3c0bf4dc411d807e81401e72bf114dea5c1c6436a1a298f332be146f2fec813f1bb54c5707f06be8707c016c9c5a31013e10581bba3c5858750e91514464413e7e88f71a89c92b29b5ad9859b920d7921c85643e18b4f28a75b7060a7218eca89946b62daab95ec39468e071c3861bd773c5cc8b3b639fea3fa278d65a75b9693f2dc0aae433aa4758816d5be7c52e8f64facaa5e78a359e4e39da8ba28991ecf200a3eef2564310bd5b2cd0bea1978c5a89b1a8f5898c637afb718dded1d2f173809134cf29ee3875e5bfae417608fc2bd3dff223a854b9702f9aedc06302d0681c199142edf24eddd33505133192ea41115d8d5242f14791067755ccd10ec98b1b8c4090d4dc5d1ed2bf804ae8eccba4a2d6b4a1b017080e105656f642bf99a80f71d98b7612a1c337048da3d10769c12373ab3c3866560abe4dddd8a01ebc0f00bf670b36e232e160ed07f6a4794d1f717cc2e2daec2e579baf1eaab862be879a8c33f7b9aeced65941ebf2bfa66d2662585caa87724d639dc1a87662439131371e71259f6307ba194d70fab5f59190a0f057b301220076dcbd02320d558602f7698781f5a609ffc291d339618cdd6f1a69e4fb7eccfae65c7507d1b361d880b2982075b676f64d5f3cc909cf50f833a2ce390eadfaa0d41d7996848ebcfff4333d9cd080eb120ecb0df74f92347bbdddcfae579dc14eb05ec23fe354b5d0f09fe94beb6d672706319ef985e5693703c818356242601effec71d2f204746608c53a1ae490d4a2dcfde8ee032c99d7057d6f635b260e811fd882eb490cbc510f7e6ace0c08a1f8e38406963829bd55db708381155a81a52c2b2b4f67796144d965b2c8d38908aa8f0372c3d91e0559aa37365a669c661380d49c107eb60a4c81440c33ab19a71234d167f8a89dfbed148ec217ed97447ace156b4537e0d460728b5c280385c65d313be39baa27ce3f44a532fcd56577947b2edb9bb24c95b5932778e2a6647b2e9bb4df2267eb0ae8329ef9ff284191aef781769b9575becff7d51c5d028974b4c3981c4f4c7b0fc47614d2a99791868f6331046603f3a2588194fdbbfdd998f8049a565bedaf51df07d6892174d19b4876a3f5b1c4f7c5e414373a2ad9874351fdd092dbf8f6fca5c3c645942809a341e7c16c2ad354c759dd39a81faafd4cefa27aa40a914d3c4a5c0419d12e10e039e1166564e1dfd0d1c11991b2f7075c212b69e1b2b1287a387a133a7945213e6d503ce976a5aaa58ea3cc4b0445b24a2c145bfea82778d1ccd086baae94c9518df7e185e404fdeda70e3b0f2dc53b1928b977cd4d9dfb526cf374b9e4b34e740e4bc975f1ead44b2632e1875773861a996388d9566c8037d19943067691b9d7a429418d5387314e69454c91ae403f99d717c92eb0f78fba6228e61ae2e7d01caed2c9fe645013b56b9926db39f0c4fd6d067c8b3b9c9d0bf72e040195ff6b7d6b8bcb5b78b302017869b8690e2ca1a728c1e17d9d154ae12031f01129fd4e955090f31098d3a1655ba9b87b307a9c2c78af427e7196470eb453410ff9870e70669b60651a221166ba6299bb95571825247aaf92e028c1bb5ebd9915c5215c462c8f4b1dab28a95dde7cf2bd1f5f76a7447dc3fb6521dddb6e7b1bedfd76c53d2eb43eab18b23a4bf06d4503e84054e87e666ae0339f87d1fca555bcfe01459818e053bc99aaafef4d5df2810e8db206e31068459c31538142c9311042036c65e98090f331ed60b0bd4b77f30000ed4636610e83a2a664f2e3592c7144fa89ef3e78fecf4fd4072168168a2c5620a5c60119e48cd8393fded6962b22d5f9091f83626ab1a0d1e47aaf37cc3c647590ca6450844d460c4bd8bcad09294af2f527bf63d9c9457826755ffe4d1494839a39b7aadf80198fd179f99d2260bd213770a450a58b7f4ffabeecb6c0cdf066210570ea29d05b2905aa47413d512980a404195bc1ebcdcb6620b62b120142ba720cdd4c36ebb705bf42098a0afa6b4287782b38f514d22b5829ef4ecd30240311c795e886988048f34acc6009a2dd95a82aafed03326905af4abbd258a09f834a312e5366b35b7eeb502ae405a21b5f8b2e68c3a9e71a28e7c2699908de08a9385ed73ef65351af80faf37f78d8a2473742f6df73d2f508cc790c8c0d23539d37f74bfa2a0254fda72ffa2b3acfe4d2fb99ae727738066ddd0b6eeab8907d00fe444a38ac1e8bf63c67f93a9de4944a54deebc49952878bcccab035b0e4871cbc220a5d7dbdd2aff185a6bd5a118a345a29c6c9111bfd96833283b6839664153dc43646c2deca06755095c82098e30213c985dbc15dd1bb967370078c65577a50302ddea93917f2060be444967424c96f6bf3b2dfcd1002138439e400fe3d66dd0d38969df0f61cfea2fa041ac8aa7cf89b02bb63053c040cd416af653ba2e8b7b9271f0f56f0438a491614917de7208e63e4c926cf514fc97a7884602c348dc20d02d14cd5aac8ec0ce7fba996e2ac4a2dca2a347876f88a3706f6274e21a91ff43596fb4f088360d314b7054c25c127840c00a7338f00ea50f952ca8b5cc6c3619aff0278317a7700498a3053c764c0c85331585d36466ac76e78b7dfa88e42ba633ddd3f1491f84a0c2cc1a6d56f78dbf4bcd48c53b9e6234e32d29acce12f06f793634c236afe1f360c294c78feb8d548dacd6cb5f861ff590b7d8041037cf918c25c5687e0c2b69f30bfeebabd6b76024f11fd04855e36b2f5666de151b8b681cdf2d97088a20388f0aba54c08123bf6982b2ee4a300ffc1bf292f25a5007df8b73a5dc5dea2a3226fb400f91deee720601ab4c63df6dc4ecc54661b9a18c93fcdb0199bc410ee40192b9608f1000b3a986ace01e7823ba0027cc1544ab4a003650d12af1227d66db74c78934d7216f378a3d20711f15723fa7b4bee9a880a1fe5060282738b75afb5661f95cb7cb635f42386dd299b28b9706f6c08b0a10cacf71fe250bd90b246b430972b6cfd8a5727b62119ca3afa9918aa36424121fa1ea0638cd4e4c0200585c1023d5127e93cf585a05dc7d485fbbdef7b68d6911d0ed0f4ab6be285a842ddd051c4958d8d9d89d403560b3e78a2d7cc37d08aac26783f31e607dd375f4c552ac477809712073838d30f4e57b24e729d580b781294d763b25c7d3f55e34fb5ec46922d948d2d364951129ba75bbcdc8592a67fe1355a5a4b42707d14b938467a9d43c5fea7a2ae564c0467281a6e3ce255ab60f0b7eff7f7f24dc7b057f2f02fb5479dd954f90f15063d1b4db248429d627e8f234dc2df15d639592e550b3915c7d8ad4e9e7fdcd4d43480930c450dc942630f3238c2e7b176e912e10d7ba2c590be9da0367e4ce7ca02c63a23dc3e2aec3f6e437fcb0753447260a556f8409e24486b2fa72ded0c624b14b0c53313c40244942de5f76e89cc44f1cd62124f48d18c1a0da12d775e9c40beafc8a36770863c9a58952e03ed141240ba04e0dd4cf88b11507b9bf58bf4746bee50cf3792d1af80db365290f25837da91f429a3d064a195876158a32c6ede883a0e245951777c163106de1822c82f093abda3ce1b5fcf61a77972af3de3f7e2892ef55dd25d25f6ae7df6b01927187925ec17feeca6a64f00c64f1646e4d3b52cf75706bda87454d01115b5f67202741c19b5ea04a3c9ae94a999346ad0e90c74d519c4aa4acc6a4a58affa368c5b66afbde5a6b0f7c4fd1bfb24dbce0df84693c0260f22366cb1b2d2aa24036ac494717f296bd1f4b6ce8e75a0451910c3c3fa2a5e48ebf0e25cebfe2738a50b44f313e9486e6ae1e50cac3f20229fe1934a7005665dabffbc725140d13788984a5c12b0c8095a648699946bc37ad362d2ab79a84cf8d4bc0346227a52b40b2ef6e7f1047bd98022b88e71767e8eb8f61f70c81436bbe0a17abad222d0010c26f5b0f26d4b28a3feb1eb2a34af3ec491d63ff6a7da0aae0fd8ead6977fc02b61961cdecf001a6984e41fe7bc0b9a8ad24dc6f3789b8d3eeddd443de6bd3a12abf34ebc2ee7152cc298369f2720e10371929b3b5c38e9a6d7ea91aa4e14c00115beb87b0aa0464eee762d5eb474e77a11bc9a8fe1462cd018dc18060dc3bc8f0703178b3177ea984321610afab35cdba70e7539a8120460383d11889645987b070c481a35e713a2db71acca2e9d06046a41dc2fff6d4d9c916443b5b83b7d99fda4a3b0998c292787b65e8219da5edc0a63488a1c04c37e1ad4469a2821bb38dc9467f05b70ca3f26e640c9b14675042f5125c54b060c70b3f1264c61d0fd0479034796340290a7230060b9be7969c07dd2fd7c01dd33f8542c67665266e51f59946be712209e1e8bed1847982c4788a20839aeab4cf35ffea55e9eeeae1eed2fe8566c81063f3fc8179dfd25004a41e41e347012c2dfe66809d1d659bc6ed1e4a0977a229ad8ecf356105dc845c1211758837d55fbd9ccbf6f7de4cf0fa6e9423e2ee376b303dd4dca73b490eec3ec7fc1253f4fc898802d593edf976c9b38c5d1f9d37d0f7e6d5cdbac952664913596750ef5805413101401176be1fffa292bce4dfaa2261300a0041254eb1ff38a75645bd4c1ffd0446a281ff6f5b1bfe820ed69d32dd47f8cb6f81843801e0f2ff3b52c103dd60abbff87388133e294c9411fb777bbc9818e26e5b80eedc054c40282b280fca915e313c911aa5a0d8f0348ed7072d0147c898f2317b2490e16c0cdf0f3065c035724a19245de8926f3647db59850f32e8e29fed16aa27df418ae91f5c93911aa0205a29e9c70aea54db6c261a569a8864f1002e89db5bd07ddf76ab8c00c767d1218f40f3db05d211f027cdf7debaa0e731a95df72381ef094df45cb9ca0ad7a81ae600c2df4977fb722de929c7f0922f41298f1cf79d0ae17a3e46a6e16cedff9490356a5d211cf8dde32f949b649f493065afa31f1f34c325c425132d0b9baaa196b8302354527579ef2b759eade6745eacbbc11dc4219cd6f1a01b9f05f82952f8233485c9f57079107a80aeb11def45b06c5b0c46a3c7040677bc09de93c9c3b21be4877e02f90f01e77492f25260e3ee9764df120b830c48376c86d206b5c0b2a4b4311b845fe757b7522f500e92aa636b539c14c01fc2c20fc956ceff9b74fd087c3314dcf81ff8e24c06adf0ffc669634bac29c1cbc0d142588bc3f52de2881b6290ea00750ecb9b2a9e204d45102405fa58af25c02166482632df5cc525c751ac1873aeaf9cbe6893f494c999b4bc2c68837bafa865949bbdc3c445290f6ddfce018de6d9bc19ec01931b1c1bb918f34755fbbd61f4bbb089c60cf9b14b169ff0a077754b47a9c4945a12ba50830f3fae3d6fa0e199f5a77211a942351979eb19cd1b9d97ad5bd340873fc5c19e7a83028fefc6f571883490dfbf1bcc41e89c0b7a404ae77b6b2318c17813d9f0ff29b1b147d49cc7553646feac11a47bd2a20c59eaab4b730085f06c0e6d19fb26922f1ee1f05328d76c7e11f0aa90aad0f7aff603d92d3d5eb7b99ba39ccfad6ee3abc1f400c2d770b0af645bc652dc6666bb4f24b8c93400179e52862beb6a1254c97ce6e9de196adab02b623ddde97d3cc766173290cded705e1a8e81519cc19836b77bda6478edb5ea9fa41ef2ed53561d6a4bef3e62ef84f0ed339b1eb4c9a5677644b12824557b609541f6690976ec64d7456dc1d712ec6fe573990a63537742e586d07b7a6d5d6b7a4f2ce3db2328905014762c809bf622ccbe50ccda3742ad30c9c4c19895b5681e6f338b92895fdc217f2bc408dd02502f9027723ca9b8640abd22b39a4332240a7634d9048838e0c3f5c18acbd36f6f87e8cb9ecc7abbb8089366a7d5eb6c3d01a7842c4af95fd11fb3c48a793e2956b3042e8fe14bba5aebd16b71cce0d5d892645ab16ab19da271bf8b755d4938cdacac96e64da98c20e29cc4acfdf1b4f56851e2d80e1dd277e1fd57c86d05340b602fd52c8059e3e3d7e90b6ca7bb78087c0d1fefd90b1a17a4db4cf817b33eb1d507a83929f9099c169f67c27eb6d83b85f48da368c4ab28db4a76de41bd9967f55e0fba0a4c55aca8222a3b79b53a7cd58a462f6234c2d210c60a7adb9d69370a20993a7fd0e60f22c9a0c84f3c4b8404f8c09a47f412e9456f8babe3c636f2500f28d49dbd3abe8678d4dc2535af179d4d2dce797e0f26881cf05b0ed804922dcabef989484114dad59acd856edb10b41400c10dd2dae21503072d95f2615451580a6f8e3222dfb890d5dbe27e41b46ae2720546ce8947d2e6c8866e7467366def50ac1f37fad5169d263cff7773dbb35f8b563290a2229df50a8df80b2841ed830a81e21ffa07f2435b0652bb8c51a279e60816aed7bbfe5ea35ccc2450eb2b3fb5728bcfdd1e5357ceb26b597bf2b71872231a136e67c36845990d8a959035456032a63d67a5a30145ea503994e4191ec1e2aaa874b6a029bdd3c29cfe5f63c1694a45895bb0f30e2c0a823ea2fd6918ebd058120d24bf33f000cbd49fc7ab310afae7e6b5ab39dd9481695cc0a48eca57e98a0f6edf52dd99b6cb9a59429a51475077307a907d099497bfe9e821dec58885b34dc62a1199ec80765f70df91ece8dd6a03c839ce9b1ecb949cd63268ee59e7a64b0d670344ff31a0d3fe4c73e9e6080cffc5c19cb9e460334199c3a78bc1b2e2e48ba5946506f7a9e8b870e560de892cbb5e41a8ad262c245c9e55a720d452162b96a66686a6866a6ccb2168b8b926bc9e5e2e2ea2f5a0708a00ac46a535b6538fee632c3bda79cbb56eadad59ecfb44be9071757abd56ab55aadafbdfc9801c9e572b95c2e170de887f250ae191a578d2b860ba929caf52ecfb514d3329454f8ec0411bcd4f9f3b3e7e745aa5a8cf7776d32f33edd62209583542c757bc80191595c4e539d5b696e37a05c6568af3f08e7466b50f24d1c0886542ce34080d948e0b404850a25966035a1f90915d0da63da63271858d37e25d39540e6655e93e156503c009fbf04503c003f7b7982811f76363054e881cf3a205eb5af407bdc8f36f39b0e9ff619ae37ae57edf9db88423346d51b29f413126fc00ea73d98b781049d9376a8da62d29e3b92f6dc6d7ca19ee448edf9c6c4855a67be7f659329eb3efe2dcbba8f5ffbd3fbb8c6cd6721b1cec73205fc6ab5f2b195bb130cdb84e924242714a93dc76213047579c1d23bbcf26f2425cf5c9eda9a755f67a9ce318ca53a9defa9786ae79380fe01d37d3ca7ee536d1d4472ee6c0cd18f4e28b95df21d99b70983c6aea886a391e11ac991609ac6096d6ad9fe9d5aa0f72eef4e2dddddbddd0db7683c4c544a9807de2e2a3f90de591f13892641c15ee63faf2148a1f2cecc333fceea6cafbd6927c6f3f3f44ecd0e7d7ede1dcc621cdcee803755724de8d3224f758aa974915cd3a6c970fbe3dc3e5127e7dc1ed128e2e48473ab0326f3098d829af227a1981cd023e8e6dc52716e7150316ebec62fb3859e34de3c2d736e6ad9e6cc6cce6d13319e38b746158339f598266c621b746e8b284e14fac1189b7308f0817e53c6e6dc01686824cdd89c3300adc9e21c8faaf1807ed0b91d4ce6131a0545c5b3a27ad60a9585733d558bfbf313655e724d64ba7ec935a1dd760bdf66b3395700cac5cdc6a43b0b0f1695158fca4f41457902c40a6a1555b138bef8520c2eae2d6973903c65e5886873aee01d9cc4e2e8ef25f848edaf41829eb039b7332305cee9987840bf89c2e65c0b262c9cd3f14d709b7304a89333bd0c87c3ff40f1d7b83dc7b429e0f838c939f61a0aa71ed88d630ebbcdb91cb4051ff4e05df483ceb1508344bf89b339a7faa2699173386a70a0c2e6dc00ba702ea79ab81b4d687c6cbed0af860ad114ed6d4ce8dc0d19977302d887ada453fdcde449eda7e198885b2e88f66085cdb9154e3882b7611ce4362fb5f151eb508ca3f105dd0eded89cf3b024657171692fdd45fb80e68bc780e8077336e70240e96989016ccea98063730e00345a10aacd391c9a1816b0b03997c26f3feb51284a592cae88cce3f03f321d94cdd2a9fe66a22f9a2af58959fbfef321fc98d75638f598a9ceb5f445b562226e716cce97428dc7ada76ab8754a04b3be3d3ba8e5d89ceb564504d89ce3e83c42bfa96373ee6990b02465e1d8c5b192a7963cc553d47e966271d07cf1543f0be80423d06fb6b0615c13da563ad59f718c85e324cec22e14b8078ba3df3914aae909fda04d127636e74e989ee27678886c90406980f563a2130f28d6cdf6b4026cced9548c6b32f3936322a6d21e4fe954bf9c827eb06773ae46c5b826f425c7454c45a66322203467a3ba609a01415a0cef88d5c60bfa4158dd7fba37f48636e0d3de81f06f1847671f7be4c36fde617af89a16398f5c57ad6bafff97d307a8fd156e8e7f370f7ac375e56aeab9f188df577fe7c19bb3a71ed039ef2ab150e89c066dbc58c85b64b2621dbaf70ea0f70e189b9b717c9a9c01e5f7b8bed19b3bc640d3ba09cabfeecec528bb5bba43e85cba4008210c1146e8485d60eb7c44e0af167d1b07be38ba75f7d2254e8de30df30e3861cba97295ef70159beaeee391e1a43d825150e835bdc39b5466a1ca2716aa3470fd3889fd0ae5c5e124e88fb168dee1244ef5735d15eb6c7b9c456d156c75f38e95d1575e4c4a6b5037988c527a49baf0d07d0df04244514a5a355a609dc510c2a8292cbc1861e2c50701e4404f758bbcbc4005197891818cba455cbc1c89777777bd07e70fb5226887eae88bde689df87d80d8d92cff77361d4df1674ee8abb808b63f5175d152151c8a8a54b9010de20e2fb943fc886508b14b0e3b4001862b2a7191c312e10ae6840653d7284912499e4cd102830371050cf08570922cf0935c1159052076eece76842f00156adf50a576078ed73c6ac307e23562988cd371f8bf19a7c296b638951fd6f0135446a11d028f69b9bbbb3b33bbbb4b8feece746803407c77976e7436c18068d105b010e5e66616742bd5b12240bdf26cdbb62c7b53f7e33de53f99fb28636f7a1bf9304fe427eb6cf8f4dadb48e0f4da9f3a1b6c03b5fff43612e663303d8ca9c3ba184e359cba205ac79265475459fea8fd9a8f8f7f5201aa9a71369889b3c13a096c6f83fde989fc642f01eddf068b61c3be86adc3ba186a78223fa66f55e5eefb51650744556568cf67f061ee6ce4f3dbc8ce05acce24b074581d56c27afefdeeee1856dff9cbe6388ab23226d67fb9fbb19c0cfb31b4e72bc38f0fceda407bfbab045b315a051fcc48a23c3e1ac6cfc3a30b4cc6d051162e35c6960ef55bd7567494850918b78a8b1a8150e3df88b2fb9b257e7eac5facd84709b335a2f163e499b2e3a992072e9892648b4d0c7376447ef6b7bb522ca6ae51932c6a7758f74dfac3a2dff415c4000911484a29a5921d322600e580a48909905026a07062d54f7c71021efebf091640a8b6402285d0a2c3115478d1610b0d3a0a2962600458e504592069a2a5dea8a1355ed7a889154e68cbcdcf809d9dfd3d39806de03e22bdf1a9477cc901cd1ff9918ba1573ff297fb4a50bf10c0daaab1f3ee2b410cf4477ef16d1460aab103414c855d13f9eb83aa7a9fe655c542f3d7c10d5f885054b78aba39f0c2a546098f66bc25a32641ac24f9e32f6164057dcc43edb701fa98090f7a4a6d278cb8a27af7b1d26c2c5c8dab803210cebbbbb8b104b19cc548ed25b5d7df37f04e06b86dd89e2dbb535d3c3d3d3972701c8dd861a0f3d99ce6d14259e9a7b99d6ccf3a8abfb8cff6b030b03dbbcdaecd699f9882148a39c675c03b1bf9fe1fdbc82e067ee8e37c54bd93b67648506f43825f4b010a9d2aa03f54a420b60895795136ecaad50a0a0a0ae2968cb0b165a32756b539cb4b9be29f29a8fcdf168157d4abdc3577a94c4434b9b5571ea0a500853a11acb3ed467887e7119aa4f22f2fa9fcaec3f6cce7ef2ebb3337c56f43e5c9df4a73528a4211050505316fcfd3c43fb66e3db55aadf679797fff019bb31f143429ea9b835ac789608f9f6750f959e096f3cfc9cc44ad266a2566a1ee100d910f4d6da373569f1dd42dedbf0ee22a9c72c94e36e5bf4d6c133d3d3972701c0d1adc921dec5848e3b8a5853ad1f6c0f7f7d76a402613b210b77a4a7bfe454de479d0c32dd53f460ff467d51e507b9d05ef2cb7d1f696a2edc1de86af504ba046d002550595c269c81e7b4d4a295fc3ae547e2bb2d002938f715c8922514f691da5a5a6e2de49d5db4b94b0e5cf4cdc280653aaf313db93bdbf133551018a7c9f4062b985663df889ad90fbb88adc42f9e57452a3d5b18daa176d4e134a5390424d2b45e58f2888c8777835dd79c5add841c0f49ac641272a47e4478b5c07606783d9605d0cfd3df810f0518d1c1f55c86dedf721ac6794a0f5c3ca5159541657d2c6e88162bb9caf529042b3ba3d337b7eb66103857228fb5dd230bb4e82e529e69ae81f5a89a0cd518259add36a9d1d6a1d9bfd45d23a41adc384db7699d59e867a42f7d4a36356ebb8bb43d6a232e44056b7d005f2d4f2f2b28fcde1ef1e720be5b81fe887aaad04a891b4cebac01cd81cf6b13dfbb13027a528d47a1116ead7409cc43f27a528d4ffe7f1764db439fc0ee4abf6d8573bfbc395c50de4acd9a720e452ed3a84973a80ba46432c51b5de94e6dc02d63e3a3a6a94114d62a72c22e65ba8a7a8f9654e2527aa44bd71059402142772c5852e872e560a4850fa7209efc415f32fb3b4616510db637afafd72b53dbcf207a982da520719c4e62ce15467dd278be20bb0ee934ac0ee93466cf749225ce82a579bd38f6384d20eb573ebd591efb0ab8196bfa0bec609fde2172d58c787faf4302fabf00ebd82b282816416b55f3e219dec4e5c49a3f8257e9142dbe39b66caa0cb7768bea78ccb559d88a6531a6a1da905c3749fdcc2c8897c2752147b353a510d117465d8546f922bf90e7520fa8fa2be4936d4fe5e6d8f33d2f6ecf397dacc456dee52794b6daea2f6c7952bb9922b05c09536a73fc6b81e520eb2c0d2f289dc1c00218b2bf90b2d9dd48e4ad854b752f003900ae04a87da3648a12446628e5fe2176050a9fd722585a2f40ec792455a678dbe78523b4a24416040513fd94232022308f5934f3e0954fb393252af1118536a7f2cb283fa451e221224107018aed43a6b34840a6abf7b699d156abf73f207949f4f326c4ad0fd4d09caef10908fc3fc99f99898a72fa3c37a0d7b882814a548744e4a55aaae407b5df3343f239fd854bf14b5bf0aa5ba45c21c6a7f0dcd8c944ea4112a0959446dd9fa47a1565f6aff4a0acd2003735e6391f65a0ac52f9bd32fc345256c0bfd948b602c01fa63b818c6b2d06f02a211287e59b9746a2e8af6d2aa58eb6ceda56269b55ad9f0b3c44a11205793fa39abb6890913f57325fda5f6c36521b0d47e9c661254fb864c5d1a59e5d40a75bb1c75bb9e8a6aa2ee6b6e05eb70506bef4af0ce6ca24af52bb5df93f01f76875b9bea4715f1b55210b5df83b647e968624747be33f30dd37d936edd87cae487a25dccd73e6aafffeba30fd68f839edf63a5d78e5ac7ad60cfb1b052db7fe8209f93d25652f220131065a1ae4382a600857eada4a4a198a07bea74a05f077590efa8828e1ec0eea9566d0f7caeada4a41463ec3eba425dba297e5e4e6dce7e9f3a4606da5229a59473e54af98e75b283b07b50d5d6d322c671c58afa8227155279c1120c6050210cb8a85015a5385185922258441942f203ad547845cb912184b8c1d5c5163f108a20c85042b7f20ed3096416355601000b02c1aaf04a0ca290e669fc385ef7d57736528ffec5213254fb97e3f83c1e0742fee6f7719fbee1a9452aea1cf8e112c40227f343082184703e67a6ccb565779ab529ffd9858bea4d5c2bd81d6eb50baad3d4af5932a8fefca4394a7d9e2cd45e2b5b84d94eebce6404ad47726c38438d147600be90b84e57cd1f0ed315e55ff72c4d68821236b129236cc2c464844d684213fc1d09249cedd1da4d0e3388b33dd3835128f4364e1cc6f1f90d1e38aca3539df26a04b039fdb1f3ce9398c4a2d79ee76d4e1838dbb34daca71235e8c8448db1c6e78931c6185315fed60005157ecf18638cd1852a460405810809546cf9899da5c62d6ac46a8c31c61b75594a961c434028e68c188649214241d7a0803c157d67a5e840870844d19212450f11e081d2cb2e2855ab8abad862071981a32f9dda5547e009a04e6d8da927ba50c20a5350d30d01d0820715b878f1c30bbc60b202165e144151188dba454b10a2c2d6124dca0ff55bf85ceccac085123ec16e0e413b104695dcd9f8d8caffc256eeba0f7e0888549f765a5b6653fd348ab8d40c28e8477d053ce79b9ea1474c4e547b0a80d5d4c1d9bc5009e324f562bd39243ec7249ac6eb0ce34f7f08b963b7504b11df414a29e50f5030821720615151855505952baee400042b60384141144140c8a658416b872794ae8851b4608a1e5e43614bc056498e3046080097141900200846528600c011c5ea1a4979c1f4a72ea5f420a548fdbef20c623a5ef50e54edeea851942f5555d7e88820542d46b9c3585aca855a90ca1f3dc98e91e00ffdd86584c414779ec244acb6a2c2671eaaa8f07dc0e7221d42d4f4df9cd23aa687dd42609d3f613f44a9eaee6024f6e13bbcfa767807d3c9ae7321d67e46e21dfdc3e2800f77d48f5d7cc5d57d2aef3b0c728783f763020ee3070af69f10af3aa0a08b650f5f83f1e32e60ba0ff57468534b5424431847da9e609cfba60386f43875db1eb7752bc4abf6262e6e409b5ad60cdad4d68a446b53bbfbbd9bb3b51765377f92be2852fb073e77c1406e6a3f3f7f6b7d6ac23dde0d55054880f3dd78ab03df91000bec7cedfaf2582bf575f8e985e8b54ebf00ab8f28b4b89ec9b471bc9e694d23a830fbc180f6fa3ddf89a153bc43015e60e8f6cec7e6f43fa13efc7df80560e22f41f14585eac1962da4173d4829a554819722546104282e20c2059d2404138694219a8a2a264802bc92859222f1e33671c5bc1206108e6843b8c088c88a14459cc00737cc2956469a8afabd0f2d1e27bc07f55b24a4badf2a1da1a56e171f688110aa68b9c1122d48e2c7b11c61a5ba472104510a8660a2080b58f0e3af4ae1080d848c8c8c5870c38fff0cfe85d6353a62ca1147645a767b365effad3d7f17bcef5437e7f48257f7d30b587517e00bd9e905b9dc524a97129a60fc7d7a6e4e3fbf8908b46b3f991e802350adaed11142d81b1d11449552055a943c95f24265ea1a1dc13a0248059de8eda671bcdef13ac5af52f114151d1d2121c9d87da1df561f7513655c0f821d4542f977773b082184104208216466ee7677a1bb37ef36ec61629cefee32fce973be4318338fd9c4a07c87d9c4645c8a02e5668f2d73df56b185fb37dac389c9fec9e35aa4221ecf3d1dde411f150f8ff612f0791b17949188d062988d8cc0a1327ba89bcd41fd6eaaff5052752f0249f522aaa83b447ebab97768da3069a8e7ac1046201f9610621d01a38a255354f80fb1183101054208e1a90796a37e5b0e8690d0208a2a290a5bd48c410aa0b8e0cb1660e030742503362842020a1f562084112994cc304b99c54e477bce037a315a70a37e5bc56680a562180d84a818851edc2a5b2c11e40589269696fc402427a298004e3a37fac333685529df291d5aad563b1ce105cca473a3d93eb1031dac503f1d15f2582a589c7051e14348045185464418c9c0880c7cf004880a9fc7e7891315be0f1fd6088aab2655da3a271acc099d60590192a7763a1182110864594ae221b1850d50758b8e0045b5d28c8c60c1beb0d59f856ce4b141961bb22fa43d66e6863437ff727333fbe021419613b2b44186c8204286ac8fca0b32a48656dadd20429a0767dbc9757f743e8a509cda36b406d55e3f1fd12bc4c7d6bf0fb70b226408f6dfee90d6599e9352f6b129fe211c7bc41844c8108fa73d5e0a524377b7c733a4756a689d8f37d03142d426e1ec7791cfb055d7263ed728e37d5a4b323284ba2e33011b5a49467e508178980c34b763f4fc966f0f4de5e5d5af9432cbb239b1971c08b03a1f62523a0c1c06ac7c9a0f8ba8d4dddd2625e0869658fd9c60e0971d10afdf7cc871434bac6a9f1c306374b2f380a972c7455a45d0cf592c2424f41d47696f635ed39eb34d487bcb4166e64c2205e140b043b86e0b5c5ea406b3ede90598ff1689b7188eab0d29d4a789ee2e96f6564224ed2d0cea20ab3d56dd77972bb5a40775bdbbefac2f4b4c7e7ddaa769e6b7ab756a7ebf5bbec3937ea8cfe3a11b43083f20f3634e3d32245de602e78145aa1d8043754f351d92b38b9fa6fbe6ce74dfa4b4fb509eb3f6b2fb78ea56f82d1598d36bbf9d7a9c3ade3856c241ededdb9801fd980933691d5eb5b73f817c27884dffd6227d80dd656dcf4cdd7724eec3ee746b53fbbb9f759f2ba9fb2dc4ee386bdfa609f473d6909f1833289d018d988052f92643710f399cbfe1792b6954fb655996bd7c9f6ea19d936ec6dad4b6507b926b26ed2dfca73931804895add6e12a65c74aecda82ee774ba875be5e62d24f5a67c906beb7eaf2903c3ecc25a04832c00717ea4a5ae7e101647436fcfb23e3f77765644e640c3fdadb476a269dda8f5cb7322c5a75f96568cf480333b4b7fbdc7dde02121894df1ec6098912c3a694d23d761edda5ecba854bdaff407dc6d8b967d3e1cbce3d7670c2d8cdb781e653e343b8df8120aafafd00a26a61b98f85baec39eac28f4788ac0e39fad9cc1a5ba8df6e0fef3e8f70dbcb511bbee6de428d1f2b6cd96d1c39288c4125a0220c5457f8f0a8fbd204384cd01d361b6a7cb871c2232a61c224e878f1e85015c173e2068e14aba3bd8552aada833096a0db9768eb1be37f83aaa11bb682083b1d081dee8e7686ee0edd89488e476032bb2123460dcd8c0c8d81396d5a669a37ac563c28254d89c51831d61833bd4f9b30e639e7d6850959c4706664680ccc69d33008fc40a2800c491998c105a4cb15083119a974dca360e3841b9b1a34503364c4a8a139c26225090a5ad26a11212464c4d0901244444d141555393aba828464455252162e97164a4a4e3049e70ca537287884224c663c37363568a066c888514333234363606e58ad8c00011d61b19204052d69b5881012326268688a92942c624f63604e9b86fdf8142dc0c711047e20558007ea42289b586366d6186a52ca8e060d4229a536a1d4349865d9369526f59245ccaba19991a13130a74dc34c33d6d025284609b1a247c1c60937363568a066c888514373c36a650408e8088b9524286849ab458490901143434a101135515454e5e8e80a12921549494a2e083119f9f52f145e365e27bc6e5e36af1a2f1a2fd46bc64bc62bc6abe645f39a79c9bce82be605f33abdb697f632bde62bbea494d2a7943e6334b9c7d8d160828ec5d88ef1438fb086eacf32c687f26394cf9551e093164c663730a74dcb4c533260ca528cd221364d28fcc7e3ff3b00f7df1675ff6d134b2576dca360e3841b9b1a34503364c4a8a19991a13130a7adcad1d11524242b9292b27069a1a464d2dca4b9c91402697a8dddf421e82ae794262d738f99d330db7bcbe0e61daf87612eb3cfa64f475fe218260a26b3f87abd5eafd7ebf57abd5eaf215f6e58ad8c00011d61b19204052d69b59e2879c164c623be6cbc4e78ddbc6c5e355e345ea8d78c978c578c57cd8be635f39279d157cc0be6757a6d2fed458490901143434a101135515464456935a4a3060dd40c19316a686664680ccc69bb61b53202047484c54a1214b4a4d57a22243444833324209df01f8f8dff7a78d838e1c6a6060dd40c19316a686664680ccc11162b4950d092568b0821212386869420226aa2a8c8cad1d109ac19f9de29927d111ca8093c8c307ea0c4c741f50365fe37e99ae69ca1f406857a08461631c905f3bc1c2a158f2e72c5ba2123460dcd8c0c8d81396d1a669a37ac563c0001c5e0998586c9ec690ccc69d332d3941590c115c3d80d3730a74dc34c3332c0c789a50e8a68fca7aaf15f0e9bff74dcfca7c373635383066a868c18353433323406e6b4699c24286849ab458490901143435388888a6cd85484c92cbe5eafd7ebf57abd5eafd7ebf5ca5eaf9764254a4b344c66386b9a7386d21a2854f7bf82e7e550a97a78787e7c8a16e0e308023f902820435206667001d90076b4c264e6c557cd8be635f39279d157cc0be6757a6d2fed95bd4caff992af1a86ac260ab89545ecf41f0ae6bf1a31ffddd0ff6cc8fcf733ff7534ffe1d4fca7428cff3c19ffad30e3bf1ba8ff06a0925c503364c4a8a199e17a78787e7c8a16e0e308023f90282043520666d8b86f034a34045912c1901b562b360204c44798c54a386806674f3099c535cd3943690d14aafbbfa11487344cce68ffd56cffc940c5d7f6d25e3550a8ee7f054f7239542f13cbe70c9a583e67d004a18931c69e1707d65d319618f6d8f27c3c11091aefc8fe9bf03f53fc6f9bffc198fea3d80e5ed39c3394d640a13ac6c138fa2197c734886910c3b48c7971ccdff9b0e7cc76fe3a176fc02e4a68b3757625774787f0e50eddddddddddddddddb0218410368410c2861042c6b1ce45dbd581d07b4743b82b3dba943a107a775dbbbbfb61175386685d232f5a35092b758dbc4842d535f2a2c8b99bf93eeddc56ee36fe1a6817f3dcd1ae06a89d1e06a6b379000dcdcccb3c09683a09c8689d4cb73f9048e537c51334c524787200063f21b0deb4d7031802a5375a68ec4e0dab68b375761f528f54833176b32b4177b300f573a5947008ab1c080dad8290c3135aae349150828014456b28b5f2c5529ce24a500a6a50b4260917248104126134667d2eb62fe1c77d47653bf3bda34e3d078d7f5de030ea6eceeee6f4360cd31b1cd00f35e1eac7dd77329e1f3304414914b7ae11e1f620b07824f49b3b284f39ca860a14109e6ef6807e1e8fd6b9d13ab1759689708344bb0685e3a9183e0a158361ae61355840b1179a4e87e93e140c46f331cc3c8d4cf779357b98ee9b35bca7b29fe9b8209a51ad63de61defdb5a3fa09e98a3dccc7701f911af37dea11f31a9f5c680e7b98a732446a0b8995761d04c6015333339853f7cdb9751fd53a1397753b6fd4ee38f6625454b2551886614934d635222af2bf0423300a2459832d7870a4a3f84f5d28e8f71ec70382b40653f4c0d81596cb1a1cedf02fc591cad403742e3249f7a6e7993ac36e4c4079e3c137aaea0bc0fe7e00c87e46f9180facced5d3a90767ee9ccd1b5e53e1110015e47cacc33887cec59845397fce2e4ad3ab4c3894670df40ab7530fd6d89db9adcced796d08bdb339a2692b6b6b304a6c9adaa3c466a6c9530fafcd4159db9db92f46754ed5ad71a76e9d4f067f3042df1cc6d8157e9dc39999b48dfb6454e7beaefa6b9a6fdb729f7fc3f63e186fdea142a8c44cda688296d10c0000044100f3150000300c0a870342a1509646cab03e14800b739e42745a329ac6b21c4761180419ea8001c010430040000666a4d100d0df795064311ead65739644e40f58d6d7d089910dde5a6450c003bd139a4667ee089c9e430be73a8ea1522c421564652a7fe88484262d4c7de3442e4ef095221ccd1477b1c01742d59e3aa3c6e52e799b1cff4561f37e28ac7fa8340ae0d1068d3c4e120163cf1eea548dfe0bf4beb6593d54af47777ca04379f0fec2dd2023f1904834a15428953881b2ac036fbb044643a4427c471ec9e520e7ad5707e81ea4bb5ba0c62270eea9deb49f2f50599a0e9c6d610d24017d80d3a1af5301defb70de48e57814baa059841ad02f0f1d09b6542fb7009c8d5a04bc01bc8bd6674c5c8a265273a75554ffbfb4fd99a50221497fb1c0cf988a351ed7adecce5f0d696c3c5a6d394f4f1b5f0caab64af889fab749fd56ad7bd06a8b72d83b1130f942ea13c1a34ecbf1812577ca9ce88a0df98353b6bf924231a30d45ba4a4154174554da53a0e06540ddd5bbd80bda6c712eacb2d393e50256644ca044672ac681d5721d57a3d2b36f5405d131f362d02d360f7086530543bdd056e6eddf7109841946237ad1030cc04927252ec439263842eedde300f25ce859e460148ee615029f20850064bd01235ede6813610c8e1b4cabc0b2d70d78539d0182fa1f40e5e7ef2d82ae070ca3b048407507d8f2e7f7f9068c31a46d093d8b956fc0840cd5ae720f788626094a750bd69c9ab65e7b8035c270dd85ce8e1f1576e0f025819324b9ac586f30663ee34bd12d18f376b7cdf40cb4ed162c0d75acb7411c4bb89fd10db699bd050b32b46edfb6b6070ce27a5c241fb61d386cf492097ccc059af8a3d4e4151d119235a768d469e6e1d565b567de6a635441691c91e989be5333902c92ec5e6cd308b17a601a8b6fbcec7c83d96cbb208671c05380771a8d0b0c3fb01ce3f1dc746f70d426ba00501d3f5dec5202669d090c68718fd50413988a3736373ec778e79210a88896951cd1e514514a581fab28c82f151e4da366e94782f3f1cc0644c571be3c65830a381fa0364adf7ce615553fbc65f8f26a72f4d6fb6c8802e65f61435ca39db3f85d08bb1f76ba6c8c3e0712a57d29c52e27e3dfb34edbc418de55a8696282919a75d60a099e5817c4d81b227c19f827ac932a455832c5bf4be1bba015ab1742b8b3290a2e9b9c2a7537624ee69173af4e34ab5c49b99b3acdf78586521b7d628addddc1a36859b8f79b8217b781c8f9a4b6b5827b9a1411aa811218fdc68b5c1c0678ca25b5081c0e3152db45eadd4e8cbd613bbdc991b758dd7a5e765a9b0cd76ba891f5c209e04be9196809ff53ff3f22632d9b47cabef33078b50740ed0f2a020bc8e1eeafe34422364d82264cc67994897afd3465dfe7944a7bc6e2a997e58ef464802fcdee263af90836a2f6456aba9cc6bfcb329d99f17daf7ff2a909b494ce5df9bf31ce92bbc7ccb9e732906ad4ee29a87541ee6d76349eccf5c9d7c0814262d4badc4123a4c6456da52462decc5c576d7df7858901dc2d0dc4e88c8712637cea1d1c82ade48f21dfc7ebb2e7e574b54cc80eba0634f80db44d8dbad324502308500c92e8eef143c24328020d45474dc3a0cc2bd01ea2880f1be68222e47278a9c6fc9382b08621dc09b4729b04c0f0e63d240dad460d77ff87d4595350c42eb728852205a312d2d76990c9f1c8589fe4f5b130e2194834cdcb54bb388c7f977d7a138e3d9ff8d5caeeb69268aa4b9fc0d43bef0c71c3dbcd5f1624ca8388d0b2805287b3f16fd9a66136baef238a7c3280add275d7ef67c499c4f69a30e7bc7f668c2bed1f33779ddbd78c0dc26615d33e7df328ae240e8c8fcf4ce12012810aef8ff1cde2e74124317de6ca06c6e5bbb7a182ad3c47c65067bf7135b1ce697ff70979407b833d413c20ef708f8007b0371c9e8db0f939ecfe9e184a5acd59e91c9d118338d091aa496bc48dd9d280ae2e67272dac33c635f0a1ba7dbaec6ca50c351344113856a3a59b731fa4667cc076c0158307c29479f835bb30b24c4523cb12808b0eedc8e31e260a18082814243048c902d9502516e584269c4fc8e50a923dec5ff2998a842f9ebc68a435962aad1b0ea76b7e793a917275110c2741018cb14be13ce6526387427d424f1e13ba53b4add431c9349f50b3c61f3d8145d6be94aa1b38a8e89213b584e434a1d253546f1617772f5e838c071b9127e40ace55ff197b06f35d83245b85ea3de48088a4bd2c4597f3b16fb3a7c36cec6d56d7b1ae3ad5bdee3ad791f54533837cf5a69a32628daf4f4729ef062f0a7dba733b7c8eb1d214936c081c953662ef163e7f0ef3ac14ee73bd0ef6c2049e1b0bacc8f69514a06b623842675d886316682a7fec877e8fdb7e0ed0eac30edfc049b69a97f05533d1fc3b387705fc2492301889e45595ae072f3c8c7eb33e420846a20a5c82b23668940c50cb45c23d467fb1ea415cba14f47f037a70ee9f8735bc0da0003facb729d6a0d0c8ec68413ee73e37905d0bc6de20c572880da62e3251ffb982d41c8f2e90906532fbc2d2a7d25c6747b0511a9653a66f7ac49be061bed33989e6f61b6c90dc4be5bdc3be29e1aeb4c1a9ef16a63e094e6390511fc83e453f3ea7c9c69d8e1b4b8eb7185e9db238b3ebe78810e2eeb7ad202bcff13112d149f469f42474bea1ab1b469fb67a6fa51577e5b8ba236d484af528b1c59fab24742877332ee36c2b08022aba9cc045685f7e274b3ab3c7df070bf839f6f3aa7f978549c77b6daa1de3baf7c5921f4386ef2ff34066265667e2c45376700089aebde43b96749b8e7fcb4a5ac0119fc22ad2d841b284f0f63f353c88fd675a0f69aedfa8c5f655b6caa866868907981936b27d7f19619686d503d90c97178534ae06ac93a59520ba355be79ccd1cedd67e15497a3c997c443ec9658b23f1b5f79164d52132b29a612c6723d1eb5ac9b8fa9f21e760f1d2c142b937cf45b41e068fac75015587e3e36fb249677e54df3fe83c318075450f819cf4f4b843a55914ca0da4ea296f3f1ff1a510220a5d8ec022b45f7c97acc9a07e477da97c98ae1abe554431dd3ce5725b9888549e545ba8ab119cc04468b444d5f11ddfca9cad6e7c4eb6f3b9105d5d57e996b4191d0e3407e46d068b36518a1d6ea0a3b52f7d87251df3a36fb24a03f7c5db8c5c6302b94aa5206179293f052dc9b3eb7aabc04b4cbb80848953ed738a210d7ccda514ba9cc1476f3ee61d96f4ddad8ad5514f76c840e205457dee2ed0a9479217e90e66bcd8c31079dfd0bd32111d8208e3091f20bf4f6f4332f128b596086ad7af5e09de29efb4e7c07e657f098fbcd34112aabe7b9fe07accc09279f643e3b8541f16f5ba4f32019bcd54c1eb531607796c2d789e33ec72c23216461ffa8ceaf9fa3d866307c0a8f6e8ad6c5a0b1de239f2ed0d923623fbbcb1dd3dc3ab19e1a610974a85f73b73ea315834fa5a42b2f7f88eaca71d4ba180ad2ad6c5c77d213cfc5d4a8cb2c3e633c4f38b0f9052ec8ec2fa0ec23087d612a77d41a8ae25706f71d8146c30a9276ff05138c6b008cc40ba9bf70f9cd2bc6ec67090291a34232045387e6d696d03b96703894d074ec635d0c15fc9cb736850c7ff4f6b98685ccc06e4eff2dd1026323aeaebfaae06e2b6633b998790b4bbadca9fd68700d9338de539cc53839f6a9a8b721d880bd8d9fa196dde968eef8e37297c57dbda24f3c4def97686c7350027db4760ee218dbad664b4c05b1735c77cbc73b876000e0dab04e5c7a3b34a60dddbb1a60214d874e29bba9155e5cd1475faec963ad9889d4abcac18a2bda43ad971332e3cd0f961263b155b63b19f6689acc082ec27d2b72a38bb609078dc85bd576045873172549ad4c600bc0e1706b5bf3426dc6ca74812025330451d81d8dc643a16817af9e13385942e3c6c0de4302501a43bb027fe3d18b6e156e19aebfe6b0bf6e3bcfd181cda0ed654b92a432ba0ffee05f613fc4bea680446ad040f6d0a2ca458b65c050769f94b1fd0ff492b6a0b6fb50ef3bd9063238646f96ae75a893ae15709aad73aacc2b8a7b8fe44d356fdf879ec319ef9985ad49e17cec4538b4e00bfb2c3d8495d1480fd1f1752767a18ee8459454fce06c8b02450d6dcf50dac32e951453b0c98e1fe7e2e3de61566cd3079f4bac8fe404acf07237d0406210e2f7f800dc2534ee689f48eab0fe0af6fc8e60a821759fa76383dad01a00b11f260b7cbad6079e05eabd455f88e608c3615ae191cd60727e7de3b08ee483d60689edf9bb43f765e7e0c47ffd1047d13dac247f1268d2c8e17a765d6ff48fc1fed4b3bb443605a5ee55b42d54464497785436a0f74fa4669dea8b3921012c73af3327dc75f82126a68fa36b0e8b059e0de4009fd6a20d715fda45227b9c1d82e37007702c52cf5cd929535a777269869596a7766301d9a734b98e9a8c8701e3e1711199a014feba06b91cba96b9234a97e3fca33b91d122db83a8d142202854ab2a3232761483f03f31df63de5cc63b58cd8b61252b9507ef8bddb540dc9d8b776b8b3174dfb65a9d626ab4219b01b1018d9146f59ce21a0e7e386986366c79d2552b165518b868187328943d20724055a8b1cded27b78c287b9494110f2e8abfc61794176ce0f999953ec14992ccd6cf66c85b5ffd798751f23458e4c177ae9fb3c30bad18d0ec743b40924b4a1f2b6e89250695e6d01935e3c0dc9ce3f2c61b062e739390cf475be0eccdab1655502b070949a5f499d59b9ac08c19cdf28c1850e5d2d072bd0eb64c442f1810fea0762972bdc05e69f2dca7de0a19b63f62c1f8bad0b49ea1be7c963d85f51195ce9f1bd0aa38a80b89c22216d3e88e7012934b65db8af45671f79eff83301efe623453172d0ba0cd103319619761f18fc4e34707d1358c32015e5b58d2e1774988b84db402d051572d3f9497e57ba965e3e3cad30a43a1f25ca25b43901580108d3e6170ce01806ae1a09ebd08a04b3e1169dbab9c1aff4cc3f15fc8e5e0eb16fc9ca8d0cf9fe54a5da107fa6daa580e007636c7146ebfdc2ae45a23059b58d90f203b48680743b458c6fa916e3a368d1720cdf07855e13bd1f53e9b0853754827d16f96e2d2809ab3cf1bef14fc37c0d36679f5a0ffbeae887b99a3959b64faeddd853285608e2fa0c9bd35febed6fec065e0d983cbd8c187924757664a8a1a52b2b8239682a5f8d825fc5d821967a86390d3f67f8587cc2a46a274bc406449f1052635c7680e4e9e36f918cf459759ebe40f5cdb278094c7a3fa635c163f922471f31902eed7d9e3cde038abad625f7da1ff2405cfb3bfe5813747a1607bc223ff872c27663e9c8113ac4b81c569b8adb78072b471bf497600deaece3631666a400f9d1d4993bd3ba4a98d7598443f529d7b2949584e26a8740af14e66aeb2974dfb2908a269e07a87a3b6d1910f956deffaada1417e463f4834feb0eba9bc4e7a58344bafa5de615bab8fbebd6c604a6c28f82923c423f7b18ddbb6c0d221a0839a40a9884d694588150112893a8a72f7c1b4984fcc1f0b666d4868b0b6f46490710d47defe952a20bbe4d46929a59086fd39989c6ff4e01f33775112dd31f0a1c6b9dcdd8b1e40c4aa7e3578ba4d29742bc796cc7fff3dbea996345ff02b705e253a16c7400479fa29d257c9024a38eeff5a36f386354167a59e86e7d04bd74238bc3fc1c020d8ef2eed09bf0c5ab03ebc5dac26c2670a53b3545997577faa1e952be4843c1d474001a87bb15bb92d4b919809bdcaaf77a2427b0113d4248e67253782de84f09487167295a3aa038e9091ea44ebc09b7b2e963b73bfb07312b55255e0777fb601fbf2ad561399947d7b55b36cadfe8c39eb7f07a606a4c348d4dfb7a7fa07c989f72739c42e096be1e0d3c35525f4799d89fd26273a32b7e1f2a7e01a83b7e4029e125218276b6e5568d97e7d5f78c449bfad2b66c991452890e2ec07bd555f5c99dd50e59212de51211af6cb6827cc6f9b17381056e433a18e4f3c132a4c6fa4708fcf3078143f80a1559a6d8b9d10a0689f4fc61425db27380b00e6cca6a2b6047de0ad42af6b6b7dd3adff083c0360a6214cd9e984c8f0a48f8bab19ea50a2b93d04bd972a3a04c05abcaa20e346732c91b58a5944c1505ca36ebcfae15ad9c5c0ec3f3cb6acc271be14d2927f4afa1282d5fc7673887d6c08a279152ec4292fa2a7e6a99bf32885ef541c4fb45c9d15b181c8511ed5c9d4e44d8b656374146cad1bd6c602b892a816efe15f4234266ea2f44d45a8abd90b06e54939d05055bec508c5b76017b815c893115f164dc0b9432d6417efbd137f214c8b4370813d997f26f2f0e8c44ab8ea402d6defb8d32c1879aad03afdc204fa3b03a8ad00baa06f5196b4e0cf582ba8e2c110856ff46edd4e524583796744266489d9423e3782aa9b25c515402456613775356028df4b348b77d9fab9612c22285022b40352346627a1388015821ea8a747d8ded86809e215402a9017250fd61b106f216d465a4c6e822f930ae7f723dd1c57a98dd91bd0bc3a94b7d01560477c0846323eba415220177449bde08ed83a2c3504e52958936ca2639b5d8e6a71ca5669686015f1c645e520dafad39addb64f3cdbc510127c4e495b55201d0afc324cdd87093bd90b6f83d0e0404a25d82dc0ec66a1bf7b601f80f65bb70edbd5edfeba657cb077f4969d7c5e323f5719a7bfb8662ac24996a8f4ff1a8762f057fc9211fd0cae983efc840ec734e605f5e6509629b18e64620206d58253bb22bb03f480e42ab31a796e0f5c1ef57625322cfd184843e6bcc2a34c1f58df7222a7c3790433b7b6cbfd47646155e420cdf42dfc1a27c366d1293ad92df4a7d01a81cfbfbcc98a3de66d935c8afe64335bf1480a8af8d443af41b0bfe830b940a718fa880fc74a83a85b7952e907385eef739858601124a21e0f9a4c898b21e04eeaab7c59315e9f40da080a04b94bd2403714ee0caf44d35319f9ca87e1a6bbb5f7810a100f957f95485e85713654d9fed3233fca2ae425c10475ce586bfbd55db18562ce13e57a293b11411363781cb950e8e70e38012d6c02e4f06251476c14a2a30e21f8d950860e20028f8bab834f1efae6c6e81c0ec8f4c834273398f06eac1a065717b58410a03c109633270851a1f7636684415fa4cc530efff811b7e2571760fb11ce09e797d0e599012013e376f2e04c6c68d47cf077ad701153f3ea2fa478348e50fcb2e05a1218e862bdf9616d603a8fdfd2adff361b9fef6f8b19edfcf2c1dfee1fc8e86ee47573d83ac16d7c871877bce5751bf1fb09948bf858d43d70f96347b052bf2054008810e84037daf658b41a34c7fc8678abb1b11eb37b2de8f8389e05bcf1fdc816cc736219bae92a531fdcd671b2ea485b6e56463d81ffceeaf34ba5062eb537249b136b9564b2a83373bc8e934bfed3d8c66ad83f0e5d851d6cb23c18832a22f4ef93e2641ddf13c8791f06cb2eb2017ae72138f89fe1c85f2e57f2438348e6999c0ddd0cdf5438622640b6ee30796a4b4d4fb517e425b1aa9de428eb56285414240aa00a418661b5724124e29d1f08af8f6dbc8e834f574e6c085950342ca7209794a794e14fd583f4c807860e87029112a7c58db8915d116499f0af0a1cde3867eba69ca6fec51a16c8bdc9e750c35181d4f7b54624dc6692a9e083ad55f69109ba79b2e5a7c8706b0eef5df4ed13f955833c4d9949e2e0d44894694540fff8cf50e253a26f4c094f4a176a162a8ba2be16d894b1c4dcc572d01e04e8d3fa6c19e007a0886600ed5e5228041dea74138ce05528cba891a70b935ba81b208001a75e29d2736b124a85a6ab50e440b147dcaec352575167876bb07fba9e06f3390bf2e46039aea0188f8653456b810805cd2dfea5fb7bc626194c123e97da879e63bb3be3b830c86661dbc29d29651e32fd9ef156c95128652ab3a47c6b5fad20fe61d18d1220bdbf6ee0dedbcfb5f549e765ee92eaa151908ef72b29baed959920547f96ecf38fded3dcb668c9c703d66f37efaabc092fdb4594b46b673589c67e4df6a2dde5c9525290f9272ccc963edc4cc47133888733c4bcfae643754f248e984f476e63653a7623808c32001a191fc4ede45b04afa77da9e2524d9b7e62f44bdcf8820c421022116874f40f2338146e3137be335016a8271ba53dcbae0485fa7a147dc45253e19c2995fb68b0385cfa8ee0e7b51b0075bd75d651fe7d3ddcd948edd303d9dd149c607b32d0a90174e7fc22f4828b0403040a1d602dc520ec239a1f6ddf523322c9fcbc2ea02585f92dab2683442d7fc519df92e6f0b0a4925c5224814128538ab53962f56acfb068e00628c54edf44a2c23014629036ac7211e07919f61ca1ec7bdd6d8cdc431e8a17b15f65268d5c5b46b84bc09706b708f62613b480bef02adc1b69a6d5bf041afedfb1015a439e3fd36516eae779024b7e607e1162b1ff69c5cfbcc25210fbe20257827019ebd97ca25b9d8c639c913c715a18636bffd41acac736f050da63012a53f6c1bc918b21b064008b7c952b505e20fdf3e6ee9b3487d92442d100326ea15da1162c12039e7aeb3698754ee526c182ac4b327596514a2dd126671513eb609fe787f0c98e03b048881f613a66cb636ef4b84e0d4066f1608439be18e23e60e42ddc1d423ef57f7094587c682ef243319eb1523482389fcaf2eda2e0e9a635ab67b0b161d8c4612ae2a8f7a465881762b3bdb04203e209d4c3a5a1d307d42af73016e1c4a47140d305e5d3d32df9b6780e7f32a5b7b7532ed50614b8316ca9187ff652744db4e18faf3658f9dac1000d88cf283a3fd0e5d6ca229599e6aaf4f8ead73048d5c0803e47a5516e8e80defba2929ced244a30f268398d2e6aca80367861d605b2b6f7881fbc4bb86d0b6c03bb4704782251d3935d398863df66aaf9531ab00649afa44bc478bde633e739abc7aaecee9387af290898538521e1e1160f9429f50769daf79506e85f3d8187c20d89555cbb5c398c502e376a80b5a5d8f853ae59648e99eeba0672e121da01c3f72783de68543eb9f24feb5d9dced675119f758ef2efe309099d5c33536eea5fa0c5960b9ac90694b498f4eea9ce02ea426d14a9b1bcb9bcfe8f743c69175a6d5f83aefd3b8a60d932c24bd6bb1945dc905949138db8b41f2da228efe3e7ddc80a689e77d80398d4b50f1a414ab513a3f9abc133a91623d6d20b8ebfd2d65d872291099a3fb4c807b087aa0c1902bee1e3501cf16b2ca68898a045e3c70974da81b4a0771e81bd8e54cba3ab409e92923b0a21a569701e95f800d2f061c752c3abb3d8debf906bcad8b952344817d84a486d4828201d84bacde7a8aa2948dd5488446ed65d34c3747b3631ad3e9f16735ffc227092f697a856f366b8014bc69557d6a7062139dfcbafc5c7b1c36662ce66ff97d3778d183693ecab98cfbe941602d6e3c60bf6a9388147a45896e29d4925fc7e12c72d32a25b5b256206640e8fbd7224202e584188f52ac593e13fdc7d4a5e81337af345796bbd65894e0b5e86c19d9c8bba0663dc6bf4a4663b167bc14592577c803916b0d4e2467c1a2d12ac1463744b18af81d28cbe8f822dd51c1201c4275d6b79e3acd08b00f475003057088abf5fdaa30571ff0e62e419c8d086994cb5163abb796e86943142a8e622a6efa5ecfab5041db15e26d1ffa69136f7ae3bb9eed26407385b72a02e81f3a2daaa6e094e5208c38a84624c64f80fc81d7d9caad4b0aca4953b0eee10529b4a4272f97ef05b49630273dde627f6121e39afce8e575917826fcc131cf113fbeba77f2a265f3eb38611c8a5418bfdbd916cfaa06f4b95fcc0ca5d1c6e5bc48cc1e5d221e3664f098c008ab98cbc929299bc6dfb89ad30580cb2d69830d9a885934218be71570c08f8aac52d4e32de961368063aa7f72a913d98ffa0e09c9d377ac42652ecfd29241ee6369a7b3f4b167f4d7799ac227378aac77aa1c431796c6cc27a422919556157f6f7e7aa17aef1d26239afbaa735b7f0d4941546e6e0bc27bbd4b848c2b55e3f7b7bd639fbc31ffce601225043bc09205b307f020fbf96e734a7f9fb4919dc3c30f82b8b63a35c88b6e007f6f82ba89c30d72238288599711e000fdfd84d8d05ccce8b02f63a5ef4af63764936f48a9b443fc621cb15e439b6043e98eb58d7d2ba85d0ca354025c35524c05393588c75d4ca621ed4f66197e893b5c4e5b04b9496ea94334d32c446d995da7c8d59335a42c5a0d4ae1cda57b3c3b5b6d2c68cc873e056726b059a22e7435eac8a5889bdd2d456c6bedfe386bf519ac9dcac4740f7724eadde37cf22de3a243b3ed97a4fb834107019bc8b97092036d60095ef0eea350d29cf0be4f1e6dde1691453de32a5469d2e675f91846284cd5ea828a85746cd7346f2f8426a1c19df7cb0815d9e9d35290772034f21c756f88d5006de821cae6851125a5da3dbb48b8725fd3a31a25c3195c2e8ba295521c62e856e66d7b68c3d232e2dfd4170939f514605c2a22f3766d52b5005b92c11cc0bf8acce29789eb33ac008f303651b3ff7c645650391f46d4cb1a87a743c524c5842490101eca0a0b56eb74421541bd9f0ac39683603c50c99efc3704c9bea057ecc451baa944b0822355e3f59108a67da51103337deff97dca62378c1d07f17393775e3800100e73e5ff1c24bfcada77d9fe10226546939a9d4b58d995fe679981f0533832bb11a9dd3eb602c7f65e3d35cb15bed3a6e1d8b11e1aa40177b45ed3199edd77e0a2efd584996c46a8913c6fc8589617fdef789253f9279e76c161cbe4d3a8f439c28cd963cb8163fab40b9a0cd8de13abf7c826040a5241fa1a8fd1324eb40906f1f40f9188944362e983d39ab89b87d622df8b32b19c1dbc4d97c4fb9b4cc287ff50de6ec9487bfc6767b2f1b781c853c9f139e1dcebe1c1d7927514b68eaf2b0abeae8c442c775a20598b91456910c819132d19b30fdce330aae2ef32a90db888ef5e09fd5d747c5e54dbf130af6c29677c120ea94e61812530b76b1e60c6dfa31a3a4230c36a90fbfc8846bf932620e3e28c4e863b7992012014668cca1e7346d593a8ac436de93830077cf915f948917d0c21ec2511d831b32ecb99c77fa3c8bbf8542b01ca252d179aed4c24109a2bba3fce9bce75b80f13a3ddf96af9094e3157edf29411e677afe1127188f442ae59a6a5d2ed26c9cd0ba8d9ae3560790e40cbc829b4950585e97bdad5b3908e9a4e108f6a3274fc7915677b74a16091904c21b546bb01beb7c3fee40c8b41ffd07bca9a1187d1eb35cd2cce60b1cef23d58618b255a12ac6a5f0badb9af5abf40bf5d0f201b91b4b9cafe4b0d66c60f7146a6ee25ef7f750a81d6f935027d00ef70e9f48b75d800b0d305db87b8d9e39a1d152fbd1abe6e6dfe0340c70fd2887af99a04a36f173d5ee7210aaca7db26727a5e5e261dceacd56ffcf3fc2038d07ef4a93c12699dae49de9079616e9b38dadbe6bd1c3bedc967f150ef4f02783de16eb8b74121287049024fef877ebd8de1682faacb7962a8fecacd5370bacee8c2302191b0fdef9a79d4a18cbe5ca5ef3bad66fe55fefd8d9dc35e08e8bb11ddbcb9bfbe9b122a6b76b8dc66d99a064f26faf3096a4de5465ae8dacfdbb4840f9334475b8357d42140802c104bbbfa2fffe827859ed650ccbcf5c7dee37b288b34158a355889067261faf5af94d6d2e2cec9caca7edc1662e68a74fb41d9d5ce39fc9fb38539b89e1ad71a7fe2d658385463eff43d63f106f2171c92c559885af31c0ab7ae85a8e031208e899844278eea1d3da9aa5e4a94e8d9b73549ead2085088f13bdd567e1e2e23923072ab76220881d015e3fb390687449bc8ad829ab6286823d18bb8440dbec107c72d15f281e316e4c0548aad0fd8e9d7e7706a427ae31db9c2732d4cfdd671cb99d5c7ad6555f9f583a60930ec2da44dc5423637f9a3b655c284b8269e9a0fd9e446096468056e7a6d598190398341421726f366ee0261c6d0ad1203198378f1881d9ffe0061319105af7f2f9fe91357cb5033999c0c0f32496a4cf22878368556c146eb1ba76433e3921bfb36dc09e1fa738ef170a634a64ad9c2c93d485a7dd7d38a0895d936e29284af993f425c224c3c22c4916790c311bd120eb970b43307cb9273c98501ead19ca024ddca20ed8a78b797d4b164b3223f8a33790f94f1daaedfcdf523808207e8383cdfc5fa2913507d176d1630a08b2f8a090081c41ad355ea28606ca789cc2aacbe421e13bfffc564ea6e245acb8f7514f6f94da50b60fa95a3d256697aec17c633e1ab278fb4c4ba3acda78ffdd628cc1277f9432d2c681419a8973500ab4ded261d4b42b3edb16f4198e89302822bf11727fe79a5143b43d40dfcb1ef38a6ad491a788c4bda413bde92ef99e44604db7fde66a0ef8a3c4c3a30498e5ec09b2a65abbd1c10e906853cf88a05119aa502b8f8fd03e9647c81e1887ef754ae16fbaf6e387db28643b8b66a4e9e7faf31d087f5e1350257bc5c802a07998bf666a33fc3f60b28d9835dcebf8c5809e622378670814c30b9dd457159fb26b53e1c95e168660809b882ddc1c3d4549288db429866d34c76220154ddd4ab9e5596c13f60e13cf96bf5f831737c841c40aafa8e905cd01d7ab146bfd12aad52c7a685d8515377ebc87b2a9b1c3e6a93e0ac6a54d68a86260ddf635adaf7b09598a7d21c060a04e0c9273540f449264330a1d8d3f2a33cd214b7d4b76489a8eb05246f31457281204fd66872eb4057ed6284e4ad0f8095c26b3f54a17ebbbc427c68b12586e5104ff44053f4ac1f17aa6a8a59a4567d7e30b5394b69ac5dda4b22ba27d1c0251d2e60f627cf05e2c984cf15f84e0a9842896dc232d1347dd9a1fb0cbf58c2c039258059c52731179d1fcb8913b1c1a158858a408172d333c2f894e7877824f0b1507daa2733aaba1cfcbeaf786dfac0cf36624f6146a8173df41f0daaceb7d50e5dc2472c079d5adc8361313e20d8f575c031ede05dddbb7865d982f272dce26837d7fb61c6990e77379061ae6ce5b9fc9f3355bd4ff9a7db73f940fdfe0eb48a1152e89c4928723e9edc14bce90b22779c1b72f36bf24856720cb33f6a809bc9d2ad421fed5227bce558898c88f3f23114a453e7af0b0a760f9483396b571a37a4f255037ea0b2986f9a1f398bc80869d5d7d1de832cc72a10645984cd021c490e97306ef075a842a3791b2ca4816f3d23733ca16e917342c1203d8c846b1ab1be32eafe49924c8e1b81489d892215e90c59026138d530d1577b2f8010057e218bf92446dd05de7d6b9678420e0ffe060cb9412de06edc13e639d5a655b08ac6e3523aadd118ee1b108b5902e9f0cd94f59f9b21b25abadd84112b91a60ef254c0f394da418e64431e6eded88c865a976ae8b6332b92e02c324ce0238aeeeb94f1776b98401f04da5fb7e167fe892753678f7bffbfc1829c2ad70529723034e1bd36b9ca33716114aa3b90bd8c13b4fcdb9fc8a0235715a1463a91d7ef8814842283b1258808f4ad671c0e7611d7ff28f98300b79b63e266b7d0443ff9c99f7ca59936cfb22543b319f4ae0f8612416d7ee803b04c63c275d721f6fad0b60dc7a053fb11c72e33a78424addca64160ec17c71c5f0094cd63d2df90d565873ce629ff1f0bec2412a5253932cb1f931b36f566f757061fee36a8b4c4548793ff9e71cf318743f4a1c9488be3994f7b7e86c6e1281db3e77804bf2c7622474d9d9c4ca648988fed0e6d84bca4aac8479dcd701568470bd61f0c0b2888a1f23a35b559c0b816acfd6c1e53b892f17b9ecdb8650498a2eb11c812c800ff12a02b563beb2ef9efdcaaab337fa9572e92eba5aea0bad4877fce4843427637b7fd88535a30829795afff493e9998b5aaae17cbb6cb83b561a84061beb8619da0ca7a2e5142f10096d9890c65502ac423a1b164c23afa34de779d0ff0ef6d883f44c9628dab15b6d5dd7ce05118633e841f563d65ebd0b2614094a2e1b0de1f9c3f230f167c8dd67e2a20fe7f90ddff7b06f55b7462db05987eac44bfe9432bff0133585b7494c9a4c93b76edaff2e6d22a0e93e1e9e1985c9f8dda50822ae7747a8ab46ba238f438985335129a133fba59fcb64e969414be2ed36efd293956e3c89c5ebf846283b6a2d78cd2a5e3858e18c51cfa4255a0121b4af12ec4a3295fe949668d6907f7b5f0b9f9640b239d6d6367073680ab93f2cb1851ed0aacb307fe3145bdf49df5fbd414e3c225d645aa86c26f5896f1d7aaf13cc0a00cc2dedd5d3453bbba6830d804ad401b8fab7f6510dba3a21d65d5468e1107a7ddd63c06645ce6c7f89e82fb95439384811ad02a1ef00f16bca32421490c87f6d3d140d1ba6234ff9a3b74e66e774aec2807fe18700587a5090a6aa5f0f00e868f459d93831af24186695eb3c33d68cf6df43d2d3d1bd6f6420f1d7ef572d8e5d1d60d9f5071ffaab15d02417b4d6c94ace7a8246fb6bb4c2d45f04ec2f44400dac6fdc84798834340191dc18b137a836fd394798eed4ebfc39be3850e33893de7f928deb834d8cfa9342e2eb1250506f0d555007098d0a21cc8e4e3a636eff171ce4160a842f925ff50c3b1d257d699723b3b0d47225b092139d06c9043b87c0bd370d17064c7fa9b35ecfa6c0acd3aa3ad8170850d3c9a5d2bcf14221d77378e28dce1070af311c3c5a72247d9a43eeae38c0fbede23f500cb8a372df5b2c6a1437725dbb82f94dacfe713b8854c1607ef473d8b437bcc5866cb10a8bf9f7d056e6501d2e89ee8b52546ac2c1153f00b7a765eb435eba65bac805fe592142aeafeb5019d6d0f15a6730ce85837e2a08478c2dbef608b0c7912667f3576817d187ac4a22836bca24addffac70c15cce5604b0d7749d856cf75f7875c50b747ede9a43d3878708283283bf908efb14d4544ac28e96a7ef042a54ed91599496c40bf9fbfeea1a49c7760449c5d4f7008d7224d4b3829aac6b55a3f2295966d31821e20de126a7bc34a17d65f1db753ad4868a847c95a79b6d1b037ca9403f12639c5d94eac2e8087b0d302f914fb068290f77be34a0ead151b5e673273b54c0a986c85101d3616387644d3d535905e9baa83618092c54841479a06043804e081821364af4a5bd7151e77606ae4756e415a6debc80fc31e0f40665cb4521ad0eb25f09c307687630652570d83defe779d94d8bda202dd68b64b7f64c39edea7b911f58b975bfbc2de1c1ccd55bbd5c5d98b3e3a6a44899d4733dd5e73f5091ae98d83cce87a252d710a63b68b6b4d738e78b24b4413463850def2ac43fa0a87b9fae3d84a53df24655d86dd6a367f92eec4f52a2dfe029bf0d39fdf1562f38419a95fa3f1a9cb44d35b944c02b499304de70db1430a535522898b77eb812a54d0a8bdc3eb5c07f12e5c215def461a268a01fc77e2f3d43ae5daaf1092ad043548adba9db475f903985cf2075e1dfe217d44105466f6f107349c0290aa4f7e2f5d3a1dc1c8fde1ca8c79332014b6cc839bc05faa9e5405948cb91955c07e00dadeda8f0dea0a8e6cc6a6d93d20b769821f5aa4db2c0998f274583e6e5a648eee828a996341e1497c63118aab06c06c7195b80aacb62d6be6e8a10fc50ca56b9b94ab03a3c338e3a16be7aaa6b3d385bbea89c81b5b907a0c8c2fed07770ad3b1c8390f4c1215313e6981235160fda3bf0f46421b834856c83c6c42a575cbcd255cf4e9419f56565647bc1406f4aeceaa601732585496c4d0fa05b221b55179c211b90934b756c7c00afe15894635538d2267924c6c244a01bb536e08dcd1b35887db3d746dd7bc14923b54a3497da8637dda356beccdc18696cf58e69ab762792d874aa1e44c5a8dd577974d1c667f1e8a0aa72814bca3f937786b74a13198b9355606f8b11fb174a8b8b2d9c81bbafe90bebec204a3a93050328eaa3285f2f056199597bcc353e14b308bb5c3e22d91edd401124e03727bad236899b8fc26d0b51dcacc2b0da9414aa7683c3af2393cb106ca6223d4bcb37b77706a31bff303252e2c015dd0cd91a28fe85a9c28391e988ce70827c1db78ced988d71963e3e6de4b0588101375f33b79cb8d57c09a1c3637663da52523aab19532c031b883922e4ef836f34b515b3dee861f7907fa04c0cd4e083d68225d86851cb9f671c81672804714a9020acd0ca0be4f9c33eafd9286b844fab9c2a8580b5f79c7ed7992bb34c19eb5ee1aa38ebd620c999b91ffec0902d5fa933c47667c0628272ff3e9d58e623049ae0c3caa0f7223a48bd647a58ce1e95a62ba21b7505121cbd13411982ddf338793177c821ef7e2454dd2180c7e968f24cf53efbf7e962f769ded72c00c7312ea2dbd47ca95ca1eff0aeec8a8f331bd7405b44840cb0ba3b0cfded40a208730fe62e537c99561714de7d4f3c81e0824d7a045db8da8f9c88e1114a9a0c97e1fccb7f0126a95d942350ac132157eed442117c22cd69487a004c08d03eff97569e18adf23d2b54dbc924433b6efe4e20f42311ccdd66943bd5e31db7d4b1052446626486800a178347c5475274751719c7ff66073d2120652cdc9f1affc2a350583ede431cc85ec00dc441a6b529592a8aeea99047d257a05744f281982f8178c9a1364e21c9dd63fdae573e2b47f87b138a4b3597377a507e898492dfa61bb255c40fafc8bd9349896abe0a08b191cf1adb21432660a663656c53bae3b8f7db657878b2bb2d93e62ea399aeb6f5757e775b8e7fb3696da882d24d6f9465f1566edc0d2d6c08d2cd1a5dc56f30f9c47f78fedbd58d09ddac40b279026d513b7f9c1ab721dd1f8a6835218b0c62d8e03c6af48d530d6ba7c74ed3f11b51ac0b9a8f319ced2cd2846b6ed308a1551551dd598fd2f406e8731af3a8da3dc6fbbed744e4b22b3d73d5331bbb7245082ac9df6d72fd59db877d9b8bd442d0f671ef0eb2b872439c1eeb6b92368c52b662536b1e85645705511119f00949d5f2890652d1a71d5457674eb761b9d02657498f9b9f7bd8a2cf1cd6b1d5b45d64c00c7f2be2e546ab6e74d491898addc3e762c4476cddd4e5711f5a4ab6153e333204faa185c56c2a81628ddbf4004ccf4ce649c120d20fa33219d0196dcc0c7bafe2e34eaf327171a72a52c93528559ccc5961e1d502b158a7a701114c47f35cfedff455c23a67f5de66887b46bcda187dcb46f00c16e2225e88fc9fcbe5667a0676bbd527d371bd08eb4abec65801c226e021da0e0526dd1882755901482e8070572a43366ac23da5a14bc96330afb604b5367f64ac9fea96321efb0ddad7c329b3feee015b6a668e4473aa520c94ec95d4e367b50fbcdfcfd81e173052526cb65a34aa748476112c0c25dd60eb7a532d90f541bb948dc26018f4443bc714c6e67c0a18dacd5c6141b2ba8cca6bc820658d6de9523a8a42066fb0b3b56eed8f9ddf2d3735f87fc49ed82542fc2f8c4b1b71b1ae93c62ea07f1cc052c9dfbfa52f2f180943ca05feb7d5dfb04f57d4de9136542f9facb60af908e6c4a047496bf382a1658ec47d3a27be7027ec8555222f9f16dff7029983ba3bf0e99a913ee6f98ae03bf295f86469f935e0c0e89658d116a697009a0ab5a99a7434d55c25a770d4b57a741a55dcd7ae33ee33e819bad15413789fa3f1a6f116bd45c9cfcd8f0de0fe6c71814939633b8cc3bbab36ba416e0fc45a5ede806620506a6e5e222f0eae213c7e3a3a359fa4354a6d9e04dab5ced04bd140a0ed447f9ca458a9899933495f0337ae057093e52ad9aab05c6e4e161a540cc70e4f24bc7140ba401b836897e8651eccabf4fc3a1c0c829668dbbfc3448dd5cb20575753e7b1fb97a098386a10c9fc551021eb23eb681dca3c440b98b9bdc80723afdf5f22bbe5989755e2129648133ac04c1975118af613dfe9883d2982cfae922a19b44a875ca75ed3f5b92f704a2a0c8ac787e9f090f1b0c6f66223985544b68a5696f2afffd15601443e29d2afc6d9ffdb4f32b67e4e8720fb29102cdf4383e58ccbbafb106264e5a2fe47ff0f0e573c2e98b849a9f1b3129686a071e9b57540cbad68dd72e553dca204ee40ed99e0367ca45e42ca058f9c14da69349c183d8fc49d8236a0e81c9daed7082366627e9c95f72f67acacb320ed35c915d1abb8e49340e41bd3c04cc591a115e1664a9b6d8397097d9a6622a7c60e7869194589be5c0c7d6f0854dcb9f535625af328875c6266c3c0ff3df818ade7283bc1aaedee4b29e90666ccfe4e2b0d451f0972105ad695abde4cb846bd99573060701d477496c20f5c8a611cda86e46e6194b8b2974cad6b5fed3af15df6447fedb1922d54f71e325e7f27a8303fa42f60c14c6caab36ec22053599b1091540235472e37e774eaf461a4a64c54b9a482629495326b53b08c825e0d19a725f14d12fa7e2efac47bb2cbdc598af68f24e7f338c5d55950b2d47e09b6037e30247083a29038785da56134b57863725531cd427c13af0298dce83e68f17d13a85c2e28fe7d34a05250583b1a4732ca0090be652819091c161205f7edba145eb9f65351a85ebbce227e9aced84dc34de4cab1af36f52a01f287f1b8d58f35a17306270a19c057809e24ff4b78082df40a77de032f987d7827299f616be6249f4e5a3e190cc6aeb85ef605e27b80001a4ec66357ef621ad06649953c201770cdf8ab794ba2d74500a65aad04b9c8d793237185e79aca34c5b8d3399be558c70e4e907e9e70d798d62cb1888b1b0d6aeea4ab6c90c9a2b045221ec0a1df232b6bec70ebd5accf45927311c96e3a463d03039a27c137caff88b36ad06388da213ec1fc0c75c6c646faa14da7fc748dc01be9e6b62236053d79a50181fffe0700fd7d78815c3b99445ae88140febede19210e7dbb3db72b4c55b63cfd78aaefd598595faa58f9e72d00bd9b102bedc15fd31f33fd3a840c19987a91b1142b1f26df9635230eacc243f27b4fce3b1ef62cbcee2b30f3ac216218376d40db08bc35ad5f4a6f5ac0008a9032ed17e78798de71ba21709c63fddc113f14f320799c29e7ba89871e9225ac953bc3457e45470ede7b9fcd70714abc8dc19a4802bd06ab1acd59d69816778d55e7c9f10ed257d28e9c6e9ae0e3d53485a20ef6c2a46d6355a64ccadb040450dfa5f12c3f535c296e08e1183a685b57ada0ff8960a6a0d895e09c511fc79aacbcd03026b47eeb3ab4eb57beac82492303e129c3e168028c112518bb7ebb9fa4269617cb2ab61484914993a79a3f117434dc928047f2f549bc7fd0a3c4e593c7a554d046a94e549cf505fadc3537301f3be458add522bdcf5fdbc9942dcb34c158cb713e2df0ef0db5c7ef5500bff6bb2822c71a88b2c094d1ffc7e130a53552b4b3fab54e8372be661614df20cb7396a788eb565e30979e3c2b318a51257323b0f99ae03d179247f888ab731227111791f95134c2efd1dd44ab7857440fab93bbe07e6ca3e9b0d5468aa1c478ebc60606f5716b6a1bb53c366fe23fcdd205369178acd5dd230abbb0734270ed92436b5e73d0bfab9e956be48f2c31ad986acd2dbc06dea2763ce85e55ca73fb13e3d12fb5e8267cb7450057e4f4a0d1a7e3436ab139ec637c0cfd8d5bf14cc6e43cc61665973524a86121c07ae6611e43a5adbebe35549b42a4488fa0914243d47d13368da811e38483b67ebe5a4ea2f09a23b70dad0dd3693ba771899dce8da192f9b9536b801d3e0391968da8416b762aac180e30add2c730c85e400c27b419a2af339e481522297e3283566d296aa7691c15a87bd8c3a831ef477e13e9ac3d44e62731757b1838ae3b88ea3a5db9eb9c7b38bf16aa75cbe2ae9faede2366a17f9a208b3da4af81b2af3a7ca7b6a8c874d5f0d59e20a26143e911d4ba99925a47c5cf23c72d788bcb756a75653bd55cb0c13cb93e930b2e4ab236318e85d441b52af6793996abeac4e692961f7d335baf155068a2e99625def90b8434b80357e484381a791ed7ebf981d7dd5c202a15bd2536845660dff3a9a1ca6e9b7a2f904d1920cd7954918812ba863411a026440fbae3dcb3459d8a2c44695d23eb3abb56e2dc1935632787b33989b9876c6c3b03e50021740d3ba464d536e85a486004812ad1544ed10c4751ae13344102c44e50695a569ffe6d4083d5b26c2f46d7c5840c27856f45938bb13bd91e193c4f61c1f5ec2ce8e3a322a3b535a992633c3c82b62e5a3b81eee21d620fab80af635b1f85da35d204b07e5b6455d3db7e352f9f2968edce3a0c34fb0ac425da027b98d509d0862ad351763d7c4c9a4432b2cf741e2385bb26e7acb333b093aed231bc695330b188f140dcb89d752b9f9cf11716a076bf19690e8196f0ac4483e775625500edbb88e78a3befb70cbac0634ae3b998aa0b34db39f0c088f2196550552015a405c20cb171bccd981445b21176c24ebbbc32b2931c15a0f84fdeb8a9650f6af563f60b374da42601a6f7c9e1ac6ecb854712ccd5a9e811cdbe2229d8d517ff7e809e758bf7c03a88884bd33f7f1cff3c4e317d612e57c42af0da0deca619ec7a16f49131aaa68d42c4119565da3af3aab8804cf3e81b9c4cd389bf1c95c229a049b696d2f20b348b68d1c41441158a1a866446164e9fb4367dd861f287bd543eb164f57b1e80985bfbb0a75be18ada1ab4079301502bc7fbc086d2691082f4fd94c90c9429c99a703d724ea4287b70d58759a75ea71106b0e9745fbac0ac1d4b8d6b6c06b885413e3165f0fbea378507ff3c470a9acf63d241777f486386cbc66755d170e8a5a80fdc88d26b018aa35739993e7e8992ccb2ccd4edcba28e6cfb6241efe1689dd2f1aae17a4c1f765e5136a2288db67da39672195e702596a0b70b47299741f4e83390e3f342c046f2545766807f7b5d7ec0d867ba5e086ca36067a3e9c48ae593e101c9b517df65a4d2aaa16d3c996a1fcbe7fceb97a1f5bba29715407900f03f4e072335c34be830a347f75b74431496e01bea0f6767c3e7094be5669b514526fe0e55e808ed29f649542d2b641308cbd9b5f899d3fa8557891cc925bce017ebb6ad0c2fea702cc88dbcee394038c6f0b340db763e5fe15587df7d396da30abb4e3261a3fd41a36b17646fedc3ab94e585e989dab3ab2ccf4601e272bd1340e99ea9ed62eeedc719733b3077aecc88a1a77635003e81c1192d817f52afe089fd96df5f61f2c0f4bcd6490acbb9ee362247b8553860b5192d32b9592343c52f51897b45e3184c2986c2281572bc18a50463a2047c234fe0e7182c4f80600dd2c282209d207027be10db7e706e71f17e9c2ea51fec610fe718a5bca17387fed873dd0ecd822921d280487ffce790df1cf8e538c3d2864ca7532db8208f4bddd4a0fa9fd8b38b87c921d762cbb10b490af8262ecc0eb162b9d4218721a71c19618ec7e0392b9cc9ee104ed99474ae02a21b9af976b7b126696d075bc0c253106ad98fb7112844a6f5c91d2dc74cbb81d0225b2ca6baccdb8a21d08b3c500449aff7cf3bc704827acf1ed25ab076a0756d4f435b96c7b3f78793c311739242dff63a0ea974782d6135d49222f2d66f3a801a9f87eddbbef3d4f8bb9d14697587ef19a190562f768ee29b79563f4a7c3b9f906cf54cd1badba02d2ed7fbd5748988759103732fb186d2d1f2107ee1e8a706dc5e82149d7ed370d425a67c3f61686c652616e5eb6d782798ffff47b0a697a02a767655534c1bc1ecb71534b1798dda5c59adcf3a606a08c470d630c48c04ac34f6fca0baee01628d8b52d35257db44e995f3902ed32a84115168399107f2e4ce29733e5e9885f890cf53bab977906c42053d92b91831f42ac0f9562495c29dabe1162d57b2afc61d53cc893522818ac13cb266406b6659c2b8256401656e6cf45e43faa3b08a05dfd0307e6abd2365db2c7b13cce1b62c296d1b839899fcb4ddd31d17929822870756b93efd48f65ce56c0456ed0d376d7ac275282beacdba789253affafc7c162cb205178b92814a447c0a58563eb212e2c57693c25a42d820dbd5bd9df82c38e2e0cfb37823dbb5eb9924a848c83f5e87d53b324855499615300e8bdfc06beeb90bb2357e729f1f5c9c1ed405708ef046d602192ed4c3314b2e882ca19a175bf3a2cf2fb579ca16a4a008147684d7d10cc978abc1a15df0999d00950b92c34fec9340a25bf95e3b82f74b046c20be1ee9cea051055961e997e5c2e314141177a745c328aba7fafd05149b4430135836eca3cf076cbed9c34c3f7a93b6a8e8231266b24368a8b85c694bf7a30a046b74e25955f3615d404585759d215c38ced97abc0eec14251fd0f3541a6124ebe4b0309aad20459f750910cf1fbaaa49b7ab023a7244815e1ae4f5a299123548226d512bf52995aaf7112bc5470142587bad7258cad0ffbd9e5cd720dddfb467a61cac7cdbf0ba8be4be4d5690cc6bf9c2cc7ba65e8ba0ac2bda65aeb969502aa4a1c78e079b1cab3dcac5fad3618953660b40eb0d3487153decebee55dd0fe8f3da986268e7f980ef85395d02b277eae1a079b0ffe9df8b7a3dc7fa208125193c597c5cffb5f6337d58374fc5fe08c0c11bc6d7d114acff3898afe8a8eb47c8855983dbf2c57e0742f3e909cca9221ca770001bea85283cae48429e1466ca9669a4823e5b2842c89a462f6bad5c9b257e8ba1d1adb45382c5ac695d92683f06fe1838ee8da71a35741d3e208e664abccac8f311e8eaae2702f75199eb32efa0ba3d986638fa160096ff52c6aa2eccb10994de7ca31d1b41e75e765d546f0d29ca1596c66e0a59117b2fffa8965517c79dcc1dca80245f37960f606b468de54d8c53a481070ec5a136a228e38daae7fade7a9901044410a0622afd92bd0f75e4186316e3848d975077b9cd2f9445cdd53f8b12d9e9b84a1253f28e335bb5e6b7ca142fc70ebfb9d1a0160d6b740c7f920cb6156ace9a7ddb1eda66d2526151335eb012482b2559b3dca10980349a6a79919a7f0a27b29ac634589715ec9960c9368a5d1e5ad6a54b502b99f81a72483e6db177ab9e6a388a6350b3c9d4dc1a9568f6ab37f0ca9fdff3cebcd75ed1a9d65ac211bb086247334fbbe72d1f2a1ec892446ff72e425f1bf535a9e352d6237dba279d24f2c4cfcc15f18a38073955ad568e208d5c2fbf44f6991d6bebc2314ef3114de5d33c5825c412fe9b8e1ecfdf5e6895522a11fd82c8520579b6699f756cacb3ad361d18f726f57607606f009de77c45a37eac0a5ef501ad875632f44b65696370613cee04283529bc539ff8ab8dc71609c730c682f997548c6b0f878fa5c3a915d4a414fa995b038582c18ac14cbc38eab69a0cd06cc3829fd1955736bea523608fa040ca5f25a1c3b078bd821a093775a22e45f03aa4e3f578d18e9653a78ee96968390f999a04d4d8dfa929f14585c3c59118acbac5731584424fb8b054105c18503ba616bd91acd517c11902cca023e9b339c2745b1441bf5902189d035786038ef7468d2102e1803ee2d0823380214cdb80aefe2d9542231a63182d1a4d1e8cb9aa95c7dfbec0e45fd99e01260ccc7f6a8797f842dc1b1c4fd00adf9c01213731d793ed1ef15cead98ef8ad8600a4b6c22c0b4a6ed630fc3fa6edab6ff1cdb93da7fdb01482529b0927e00dfd849da00a5f0a3af79ca756dc81bf38b55dd992a5c4b195fbad7879170eb6583ed6e6da9567f48b6c29165e094ac78c9314885ca81dce5e83d20ad5abe1748a85a8d77797f425d0c212ecb2d9c4340080c304ee4ec611bc1b4c746c2028b213cfda833a8ab031bbdc86f1573794918cdba8b9b12446de3ab41f432c06b0473964832934b056df907d4d0886174e93207012ba0510a2a720fbc123df3d7973994a2d37d17bbde65a9052c32ea4a9eeca6376f6892efaccb15f2d2f3147e6323012227e06df99c3290224fffdbefddfc0419b35c43f3ff605622c3f1f637d705c6f85735332539ddf944f08899e9f10db362360f1fd81887d9ff1b19883e160d33e8c43303543637dc2ef471838e675033d6422e75718011fad2d2aa95b88ede49e63515e01b4a67dfdfc10a7bdea9fc44c367b32b5bf1373c93f7408590214f8917fafdac853e0ac06caf29c02ddf46e3e9fe6dd42cbdba99f3443b32c03844d7317c46b3736ff1790c121d27f58d02e031464a79d14cb8fa87a0f36cac25e161ae0c86a579ba9dddc25c9f22a894988eb3f082a4db6364d4124b163c427433707bd65f8749a2fe9e48dbb95ec522ee1532647ef4c3d3914245934d1956b65e62c480e138ea381c008cc36ebe541931164619c0423ad3f1b006b7180a670f8ec42a1c5d23adb34f94e8923b6cbdab6e9bc461c1d4e760aa02c9a58ee57060bdd61e69e418db70caaf5d627c8c28b279b0616573d1156edd31aa896783d6b9d8476c399596f6212b2118d9c4252fe9582c1d7eabfa64b63eda4f02831d2c26877654ba5bff1f7221ac21e1978691d5f0ad133cbae796a41c4cfcee54742b8c32b3b3ebf665920ff9c5064256242f9b3123960dfcd6b8b565b05e6fa4c242869cd191ecea62ea130c4022cc75d73722e90214529268a1116da3c388f7a8444f2e38fdf232d6d937a6f927ff639e46822a590bc08334165ed541fe4df286b04e692b3dab68fccca13f343cf2b7194d964600e40c7e01bd482923517bb537f3dca989c551a8677e92a8dffe401a379e020e8cfc5a50f208cb28d2277a3f0b757346c8c5949910935816cff07c5907aa121737b5ec576ba6eb598ca38df1bf9f9ce58e7bba9a326f1f79c371601885cbf5f869ef7ab61de86aab68cb84ac34d8b00719f0b9d79202e34709ccd22c865f825a4592229932b87c68c24e499a99b9be071737a506e80644bda5c286e0eb35d7619a4a482c4f07da3b2775941a499b0b3f5fbd3a203fa0d071d210b358c4f40f33f26ab5ab24db6090e90ce194403aeaecd0c710dd65795a035a4ffd32be81f52b095c2eab2cc1c50ace483e6767ff07df49f26d32563d8694edff2c0dbe650cc0e0d8a78f71854d8b0dc1758155cfdce898d62e813727465086f016468572999e70c8f7599d3a1354c71f3e8daf43b02ade7568ebf03cb076ca99107f81f04cd8748062fa4fe710ad3539493982f23e810a3cd7cb9e0fafb22b939132219f65f8402a77a4dcdf086e2f299026bd5731088b97434779c3a91f063cc9067807b9929ba5c956722dc00482329780a6bc4934025743e02e0ac2b844c3acf44352203a5947804369db5ca4da286d75d68d6f2422be879c3877257725ca3a84f81a73e5a81878164c130a1b53ab3e07a3aa990fa30144de232cb800f910443088a9cf5087ec0425b0832b30765179ff971f412c48acc27764aa2970c71ea67c2ac841c0264e80213a495c07cd7b548cff5f87453f314772d0b64523a4ac346e9a7638a9778531cbd0ecb60ebf7c801ca4a42628954b6bbfb9fe749bf421efef45f71b970627fd0832f00159414c0fa210346f2d3845a5bc917325360827db8e375bae6c56f410c79ab3a7fd70f1a0fba61c1a621bd058c16c7118420a037f5ba8d7260f0c897b19b656565d633d350859f5648c8160c63f2ff1b56819d5bc90febcf4eda5c0e7a2ef10149d7a5baa45afa7f7d423f54220f4342625a48a5878718f04888ba5c4826dbdcd4555e8075537bc473dff94aefec723d89d81838f646611219e01df5ea5515f5530b358e16783424811bcca5e5316dfb61a8f67d84106c745b0b170bbb7d42d0197e39d1a6d12114ef37488a0715d063e84e98fad7e342e2d5b3b0843cc1f456b10a9a2644297791076801cad64081674c08925bb49b324eabfe08f75c12f46308e710d3219f6941204b87322f0d3164ed50d01c8238460597a83a713ddfa14a8bb5daa0e983775317d21c24c17cc8da373c96620ff27c31f57978213bc7edaf03112cfb1fb3997129eb31d5708c2a6b605a7d4b109540c96803eb938dba7cea21c5edb5ca7255aa480ff3ae4d1d188366b91b984cde973022509fd9d301368dadd383439e5dc7eea2bb0e9cbb660c7bfc0224403fff18a8daaba7fed38c06919eea938ed5adc281643325d1de87365f00aff9d50c68036a020b8313f0a67a971cbb6350e14f0a8c06aef9954c8efb6b4be2fb4a13d688109098852e02fc55bbcc01baf052648cae44a93cca4fca29168dfea1d06b9c9344b8a374f7c1058344a47001c9ffc08ed3d0156652d9f2882615ae76d8d1377224a84dfb298c83f2cfb6c3cef1f849519c9ecf5e7e52e62ce9c66f85a9400c63fbd02b3d37e13f2c89809e12741be003afc88f995ba60b5477650f63df60bd30ad03921bb65b4c84582d912426a153b537c7d824cec8e1dfbb33b2cf30ccb31ffd013232d3d53c691cc262cc171a3ae9da97cf5fe677433728acdc3294ea79dd250cea4d9aaf2bd51a0010b586dce393017e292cc0459a835fc652d7cd66abb0500d95e3f04eb309f3ca90dfec8c1119c691fff1a04a384ddcfceb74e3162940920b76e64c80cf4ce4a5b3cd449c839b19c2e0068dd8c46fc506e9a905a4a16c3d21665a0916014aca5468390f8ebcbb375601afe0544b194eb97283aaa499733fed3944241086a1d82001691b75fc051a011e1c98651318b48b8d109d821cef3663627986bc49ddb55b93d60fd720a8759f315ef947b541981c32c403ad430e5b9cc87be358fe514d4d9b6ed211c77e72c71c136412728fb037faddf07e84a03a91bb28feb3c44a96604d781e3b8d100b51b651e029d19fb6b5261307ebcf27bdadeeee7c8fc6658785cc1323aa2a7f5d12d639ad71e91332f80ceb3111d8e701a815ef294ce7e2d247052c99e9b64413e61c87e1b7e96198f8a6244b94b124e7b2228ef653dc35b48e15a148664a360d21278907392cec5b37ab60d703ccc71f2016f33eaab3fac531ff92d840230d2a038b5e15c3e482c42b2465ee1e0542fa0dda7d5f5241cf8536fe98c4de80910eaa0bffae1397a1967e7b00f2afcddcea6023357028ec884ed5e5dc38da4d704f6259f3058d4bc2614739cc6230c9f1467c35c8bb4b6421680020c365f619a407f45cc5bc0197069e6991aac28e3f1589bb59fc99ca1b5aca2284b08e441eb576f2b708b64d414b2223e46f6fb55225005395bb1c8ef94079a7df2d26437051e149f6544bd10a66585604ef294c9bf9a783b17117ffc3a05ddd7073b629bda6a582270f3ed12e3ca40a9a83cd1d8148aef840e8fde04a4f2942b5900b7c79dd941f72be5dddea884c8421293cf08e6527400099672e1288e1ab957df1ba3090fe9aebeda5b48ef6bac2a39fbca30b5baa3691d4ec7661bcd2bdf5ec4f2d7cc3018e9e7da8f9571aa2501f9d3d5678091ae413e81bc9368f1193fa95ee437cd27447d944094cbd034a04639f5a304cca9a0e7589ed157bf66477b1ff7608fca9fdfbff9b9b3b641b094267b4eaa879bbbe76e5fe3b015a3336b8f3383f78bf2ab4a968fc14f467b68e18009de8475ceb0a13775033867d5ac9e00a1c4d5a6f5ad2f69652ca9452b009ff09ad095eb8a6db7857f58d46d363fa463fc134fa3b11e9f6771a6f2818488a1dd0eba24361a01fecb7e7fa36c95879d371110431afe5b190ebf9bf96d76a7d656fd916b7ba6a3df72a22e7f8661fc8cb2f2f8bcc402dca7903099ea45a6bad319c9925d11b7ab228d140b9602559a94af294a5861dda3ca1823d7102aa82c902ca87294fbaf8e1066773434f1625fa54cd98ca2689c6d0a40b13830c459e89145190512203021688f0c2e48a270f6aa9dadac31319ea931b5ab0b8169a685f3248d3b2da7452da462ebdd1dff1a79452002061e5652d38a4db6f474f0bee86647a59b8e61d679836600c2ef3f08e993bd2f87570154d0a799e770156f23cb6e23a6b711d851f5b85978b599ed8595428782a5c7724fe3c65b26432b71b8070250ed368f7cc73698f10e4ada265209c0cc442f66c09f6e59d1439ce10eded5aed97ec58a3e1c4d2c8c1810e1a3b3d3e1198d4c795cf0a885151974f5e3c88b9590766f6251ffbb0eddd521c6ebf7d7d1222190c84c4ca6019d3ca72c752daa42802f57dfdaa61336d4e2a72370b4f3e661bdddf5a2b8714b8f2fb8bb96c96534a798f6af795efa4cd6d9fbf688773fab794d2369b062510490c2d24619e2419a1460b12aa27ac16992254f8d61a37355902b01801451528a84070c50a2c2c9cd43047c0b086504a29e5374f6e562062840e55508e65864ea1c2e3bc10224bee8e5fab51fc54a5544b96268cf820c92029cb113b6a94c8c2e58ef6a7c097f7dff368fdabf55feb83c8f79ee9eb61cfe3fb9818c4f5dfc3c4204e41c07f3ddb2ae879dffa59f74734f9336bb63694a306866c035fa2c758d36511efc8fb22f0bda7542c7a7deb0556af138b5a2f4523ffd61bc9f73e5777420326282dedc1d7acfb23db8e5927ee402261040d9ad896e779b226c2082f9cec2281af50be8b6afa2443fbce18305f7ed17c5934df138d48903ff4a7c8f2a74a833276bef4dc9334917a35d83673cfeb231b0f31484bb4df75eb7974deb7bee547363adf45084708e97be883e52a11e80a5fff0f03cd9e6be5fb17c97759c522f99e68f47246e5f3f0ef5c9cd978487146c51dadf73a845d96423590d65961e54f4a933ff3bdb09b73d22ecda17817ec8c490342ad9cc639a409dd751fb61ec4c2c73ef20776598706652cdb8c9c8a5c2edfe57bdf2c72bd271a59978b46523462514eeb123d7fb67963ed4efaae679b0ce57bcfc3df25067105b1cd04ccdf0104a9087786ad188bdf54d11c1c047105f9bec500efe543c0e554e412adfce9209ea844993eaf7eeb8beab7bebfd5bd271a79dfbd518bbd8732eb56e87d51cbf3de251abd510ed9f6a1d8514693b2497fd2bcccd77dcff53e88fff7dcef7a1ec2513fc793f0c3856c5071509f6bad5855378765cd1df9ea7aaba3b48a85ead67fa13bb251f9f38be4cff9522c7a19c97f8947362a8e3fe6a5dffd9ce6b4a6893e4eab5fff93e0d0044ad8d1e7d66ffde873d9fffb22ff4ff4c4a27e17787dfa369da2e0512ace18505f3e8fee5d0ce2dfbd14833815f9771f447efdbc56fdee6794b65cf5bb96ab25a97cb16e6fc640954f9fc7fc2a0611833815d59fe2cc16a47b29ce5adcf179dd34f9131e712ff4c1f6f31d6934ff0efdc9c73e9efc99fd4736125adc815482064e6cce69b2d6dc8124dfd6ddb5c4bec964322677cf75e00456260c8ac359ece6f67f356883fb61b1e0e5af6003d806eb6b89c81f0f2ad8facfbb76d878745be0c7be88be053bf96c03c3991465b656947d2c55ee68afec6ab70377c04422f5c1270212fd9275fd170bd9666d38d47d0d3656e7777e26ffa8fb991477207993fce9de99e48fd2d0ed5e03275609e7bb9cefbe8ff8d304dfb1ad7b9a31a03ef822d087e9fc4e0c49e902490a7db0f2f90279cd5eafef81746fd47ddf3ca8bbdd779307517121184fdd3752f7d475dd94dbf591dbfdeb7beadea978902b7dafee9d18a8fb9d1088fce95ea7fb5619eb504eebfe25fa93d3baeec5275676bf430ae588b3ef63247890fcee7548211c71f6893c40fab00f521f7c1eb08f7d4c0c421ff66ceb5e042964bfebbc8060c915c0652f3454dd0e08fbbdcf3748f4896f47be828560d81a796ebf7c2f949d2bcd1725564daa246c7e58ec8e9c5f65ea459b78cdc91d193765b2891d6560083e4ef31acfe52e3f20dd1935d9c48e3469e5abff4db6e1dd4343b50e5e5696071848135684115a6ca39fc19dfb00fea93fd20ec0dba2080c543f47093b7653d61bb621654c6c0b5944807471eb7718b6c1ced46a6e8de25632b70e89b9d5b3b2da4d4b4c52a889d6818586ba69484b3714c4d8ba4ddf3def251ab9bef546df473ba1c8f5df090d609b953ff54d6800dbbc6f00dbe67fa291914cfed43fb2c91f69b24619cbb6d6b36dfee8cdfc8f6cdd14ce5cdc81d438f953bfa15a8326d6f5f903a9ef79d666ddfa1a38b1557efd7e924250d599a450ebeb7b9314aa9f58df25d67770075238df15ca5752656a75538c27ab81be5e3ff4c176cf77eca66eaadfb5833b54af56ef755d68821df7a1b973d87ec3c73edf87c5c23e2c96079c31e08b604871662b3afa22850f30d8ba975fd4bd148bea7bfd23db2d72d96ab0b1ddd7df81d489550d0e25d95116fa60e9f31d87d8fc00a5852cacb842c35ebab9964fbe9295d16e4bffef0322979ce6f5482e8d4777be6d59f3ac1c7b35b28698a24b1a234b7a58c346bc61b2a68d99124c29520596272d1e2693c89552ca1987bbc1063254a4c8a0851a2c2c34998207a90c0e862c5ba496f0ab2b5c58f71cde04eba362ce39e79c73ce2b5cb430320409a41470b0cd3477ce39e79c5fceda862e1560acc8a003939929407089818a2b4c7460340095a58817485071e5031a299d264652b850a384eba1c817567ee5ca085a4c388922aa34fd80431a2f8e988200586438024a0b16397421c50f3e504a29a594524aa1585862045a72534c0461a3515c4a29a594524a7718c87fecb9fe3d6c835d72210127a2f0d084e588ac2dce5c5121a74991264fcc60254a114c707028de804e1c0cab01a3d3c4b160198105154cbcc062c604ac2d9e3c59a214849b27babc98f8110f63de2031c40b356099f29c95282a5ff28d99c27577e22c2bd084952d597c81c4cb5499194baec0f04407295c38391182167bd381e86047cb36baeb36b7c99e76dda54c227b5a7727ca3a83da878f4c27c1cc2cce21b3bae7dfb1879ed37cd049a778c2bc3e68d72d95c99852ea31f3147fd0eb2fbd88adcf5eadf2877af2a7abacb2ca8e79dacbf3798a9465e8e38e3b578eb992622945963ffd1e333f03b5ccaeb1fce3ebdaf80a37bc44ffb8c1652019069779f8877f8a2f83feb43b0ce442dc7d0acbfc1ecdc65a5ecbcbf2644e29a7b5ded7f758a8eb2c9e353c6be49c9d0b3feae59fdf2985dd009e73ce89355a2cdb3fca50b2fd9ed378ced7654aeb0b92a964fa94a7052b2995799776b13801dff33bdf231a39ed8845e1fb88463d1fbe518c17ffc866413863c0051fe3828f312bb2e07bde82ef7919e18cbecf1fd93efc97f145ff329ebe0c19ef231acde81fd964bcd18c8a2714f93c06df00b621c5780c4423230c1e03d1473cb27dcfb3ade747598fc8b618e205e1d10c7370feebd705e1914d0cd916866cfb906d3242b659101ed9186cbd53fda8b7257ad50a9647f430a33f4979d0d4070b9de67f3aaf0e5d5716b2edeb20e779fe6370e771be43fb3ce128de1d91e773489c30271c7d884e8b85f07d7ff0bd8f219e7fe1c8253b8ff339e17874731e0724caa1f43de0707c9e709c97e777c2b1efced3b0861536d49138bf131e5d1d71004d03e76738d6b8389f43e684e0e384ae8785e38c1b7b1b8eaf1b13619f43c2c2fa603895427f721a94d3e4c34022973897785fbdf9e5ca3975a5c089ebc18e8ee39c8e30899daf249bf9a79b6f87732e71c7c578f92ee5423df4e53b94074d318718e29c923f522a9c54f207e7342a6a74772d58bee3c44d9c377138a93495a6d2954e257f80b03f451c8e891b1af2260a12e5e0c08d4dc0e4dcac6f119594586105218c501652104e80bb630dcb1ee9788c283cb4765ecbf5bd4058cce2f4effc8e38e67c8bb30f76bebfc551e777de493af9f3849e6f30e7efe88438a1b58285af304aabdfebafcd3e13c76791efabeeeeeef4ba4f2969f2a7264a29a54bd9b49aacd297a27bd3d04567f70ef61da197ced9ad3a67ab9bd22a25129a90e70c0116e28030420abcbe0cdc7e497fb69c68269a2128173e5f57cb342af2ec98465ff67c815becff4cc1f6bc4c26853eb0e67ac19e6d36146301b874000bb832a7c509dcaf7330609b81a890d9c47b4911dc623f5a69cdf39a44cb3a5969ad34031fecce652d50b840ebc1e6bc01c01bdb61411bc27a6aac99322e18f9e23f1c8687913101a83273c41d2d2dcb0cee8e5ffbe1e3037c9cc3ce7f2a9b0a4ead31235bccdcb6dd563a2a4f539a62f676bbfda84f4d5198a0c0708e48dd8003e788940d51a02cb5129813c58b121f43bdd44a9dd4482f9daa23a0a8d1498dd437201f8f14313bd478a48891d2b7ac36fc3e5c14d8d086871914d8d026046daeac466859e5c614793e63a8f8757850ed3c2a291cd5c74b121c6ef776766f3b291c5dcd832a0d8018294bf89005408c143143b5193e9300307c9962070402c0f0458a199271b47bdbc94f4eca62a488d9e1766f67f7b6eb6a53ef19a45e776f6d37e7f5f0a86b9da68f7db22e8da56d9b27853c2b73a197e7341b7f87b2bbbbbbbb650f0ab6866c9320d10efa9ff77ab9d0ab461bdb59f7b9b13c293d2576ac5df953865eada291101b156fd5c9f45c36bda1e9796fbd9a1372a6dbed96c456eb53857aa2893b565c95fa1feb541d13e5e54d1e99e18e526949ce8f7249e74719e5098a0cd51d254e4aedfc28a7787e9461aebfcc492ba43b4a2cd966821f6516053f4e24a52527aedc7132cd28b21f67138c1f2795eb3f71e39c7222eb8e936a86a9e0c75935fb719eb9fe136b66e59ac0b92345ba1ee329136d9272474aa95cff9142dd1fa9d4f5a754b4eaca1d698e9eb9fea61e79a2883b56a5bae4ba6749284d5f64957c73640a8f73ccb4a24bd40aa557d76d236d731dcc94ebd31d0c133ef5a58601c3d379bcc40d2b9705d21554a67021e608054d535c3db504973b36d51d3bccf5aeea31d7cf4061024a0c848dbe347a13099cd8b9a353b9ee6ee5ba4b5d7f1e9dcaddcb1d3de767ae3f7390bdff3240a2ef8f80673968e4d1555421c2e72ff831079f0b442136a71e3ec4fff7219d942871bbe27ff8168044e1874cc59521e3638044322cf81e90c882d78db17363fc8cf19e991be36d0eeac628c3c28df133902886ec08a5dbf31580443db323eeec618044b30a5e06125500c3092617c6530012c190c97e029048e67329c85d0a9e0724a26082097e07249ac0f29009c1e5791d908867c7b6f33920d18ecef398aaabf33820918e276fce5b9028872685867098c04102078704575c1c0c2e0ece5b2717a704555c9c31572ecec740229c21da0fe530c25a31d61ac0e2b8638d6b9f77b8b600d7dab74c9cb9f66555415cfb9fe4daa73581c4b55f23810dd73e0c24b243ae1b7b10248ac196007361ff02896042e07f2011f8aabae3ce7d8577ecb92fa0fb7abdfd725f4b44b92f3134dcd7bb40a2d77fef72595d97eb3d90c8555b60baadef40a2d6f5c254b99e19cf76168009e256f96092eebcb9dba25b90c30fd5a65ad65e4d8937b6bead696ee5b9b5d65a2bce6b47833bf630a18416258a48820a1f3276f4e6eb460d246a88a105092c544b77fed3a8c0dcf9b5249ceefc184834876aad3a2e14e941892a374954f02d7aa0c0823164a6ee38e34b0e253022052398b418f1e68826ee7c1848346bad74bbdd54a0c2050c324dbc6a2c819bcabaf3655ec4dcf94f4408ee7c5a8d0821eefca122a898829a536d9ca25089c2218b93275c8b2c3cd82f83a924b7be8bca13b0560008d0c5aa4b955bdf135d40a2c9480d527ed022eb4a198f893beef4383144d4ad5f65530529983441040b524800e5a6cb08902845820b9b5b7f7a7fc4a44d15140d48a84052c536b3e8d283102f0baeb0a34cc6369ccb9958106768b398d99c71a700ee9c5235dc2995c59d5c906cc982021d3c18920b5f0a3930890bae214a2fa6262da4a7ef07275e0a2e235ee850a86a458d515289e0bca8354be810ac6ecb902693470a750b0c2f48f6a6c7a30813e52d4d30f01882dba225061e448e6c19f38407529519a8cfc1a2659dd75a31e8d245959f2bb82ea6a46c8ccbb82e8ec840073bbb8ceb220d00907851e40d086a489aea1839cfb16f31096e7b9e4be9628fcbbcad3c07d5583efd503220acec89359a459250e188cd68e785b89b9bcd29f66ddb098500e0c8cde624e5b374cfe8c8858923900b7b0fc7791ba55190204284e0ae7f8e7b61a10907f8e28bac5166dd9ccff910bc98788209fdc585b12d278cbd5b715ae3a0947a1022013cc536e86d98d75f6e5aa8609edc51d4223814b19c7f82ddd35cd88fbe060ad49b9cd0b1c00e625c173dc74057566718c8a75873fb5d7a3206732c35b718cc83c2cd46b080d3ac744bddfe5c4bf9f270d655fe04d368878281fa5b0ffb58ce83d03f9c56c28f9d43a32302c9f27ba38f348d2bb6e1a9e11bb06ffeeee839b631bbfd7e866dc8b7dfef51f08dd8f7fb146c23e763b19b63a517f6d591b173476e57e574ce2879100bf510b7bebaa2e2b97ed3d2c9f11c15da9de1343f83c51dfdeaf663d52072793be8cb9de3a07339e618dbb9b66a346c038b6db4d886ebfb3b8b6d7cdfdf6fd8c6ebfbfde6485af08d9ed234fa463f358dcef9b1dddcfec6826fe4bcce8fdd05dfd0f96ef2254953b8b86cd886f7bf5ad7437965d867ae988172574daca3601a7cf93be92a754e071ba3ba7df908a5db37a96f3495297da3ab9a46f78d1ed3b2a6536e3ff912032931902f5172fb1d89c770fb1d06a6d1af139e00fb1c49a56f3813a6d1ef4e6e3f0e95db6fc39ea2a3601afdb0b0d5308d7e306c2ca75d856dc540cd40fdadb0730cd41f463dd891b360583916a8aec8dd907076ec1bece948d2153bf6111eaa27dc0eadd44b5cb0632bc16e4f550cc19406ca12942476ec250a8ce45098d24c1de5891d9bc93e15914295a62939d8b19b5e4c8ec3228527a6272a4eecd84fb72e5c18e9e2e607282b33d8b1a126c09acaa2089b348d6ba99c1c1555509921d253fd85891d7baa02aa21724cc034558769c18e4da581522e4d19aa9c9baa3141d8b1ab5e4f5db6c0ea92c552e7fa8c153b76ce454595a686a099424a6275f5821ddbeaaabb4db539c3e436e50688a936423456b779b26363d1dc1553b92bca7456bf01811d3b6b3e2d2d21c40dc9c98e7ecb80ea48921f89620a8c4b1451a2b8442186cb992ca52558ece84a4f309eb8c0d0c40506325c9450e1b2e4c51214253bfa12ceed892c24a6284aece84c2da521d24861d5e44e831d5d09b7c50d6bb29ea8f8d304538986a7efc6a40a282b382911d8d1713bb928235f0c29e253fe658a1d7d6a4c054a5262c24889b9024b4a892b29313938958711c28e4e0584a3f2059557f918afaa54b919d8e0925879cecf006147cf71172afa06046ee5576e055261ad5003c814b502ceb1bc0d0f7674ac3617e4864073c5d4c2a73484153c0c8126cab3fc4d0d76f4ac2532aa2e5a246175e982885c973650ba643d7143a2624779a34f4833507961c591a4263bca233838a9b42489ebb66407a5255176944a4762514837798b2262064b0b17555143965882e2831de5d21230b70549d29314a62d48ae6c51ca3145b9c18e92a975cb59110595155c344d81623f6ff965eaf64b2a0f9ae0f6cb2c59180f629c1a9c3c63e5a3c4926fa6740975fb5b090aa766c9f5ef97563c68e6a27c725a3fcf95f2692a197971b5aa8c81fc9bb3f5c29b5b94239ae4a465a85879b57a6d6a509222a5345de1aca865802f4a3cd95ae2914d4a59ef63205bc50ebe1448d0643372bd908ea266cae624ffc8f6b54257c82091d7d55951eb67452d57382b3ab2e590267487d41582ecb68701d9ed6f2155b7fb1a8edd74ab27a56ced2ef4414122da6275797786de6dc9cec12e1fb3003e9642d236a5b777f05506f244727a908b3d7ec82bc48fdc35f0f5f821af8b33297ee0cf01797bf077df78a2f365f28786423a2b21b52648a86c4eb3fea3dbe2cc028d1442e34d53968d7d838f4e1ab29a2b2c4b36dad5f7c49b90fad5c8a9fbfa4642e8cfefaa2864be73d9a0ff6397019070b619b2ed897ddedddd3d0f62a64dc76eda83d28e763de83b9deeeed5ddeb8feeeeb5dbdddd6b37adb46b57698fdad5aed2b047f557ed78ba5e7ab35dca1e3de99c41d26ff4ed1eece8dde9cd3b6ba55cc1c06030180c06832989599c9c17ceeb735e39e0386f4c84812f58ef4cd17df7bb9444b97f9dda703d832074627f77fb9c507ff495df0ce57fde4f7faff6140c21f43c1cf57eca64d68e5eec5d9c9e373de8aff733304862bbefd75b80840bb08dee2995219359ae79907d9ca73fe441f43f1bbe9c063e4e689d063e831f607071c4e934f073b8f5faee2c4fe81b0b4fe80b0bc7d605c597d3acd36efdc4f979a2e7c9efeebb47cb1934a5777b3f767777777beeb3d66e6f47a1e594b8fbf1abc3d677e151ec82633803c17bdcd6bbf75edf0aa86cdf762f1cbd1edefb4f30047f31508ebed19752cfeb72f878c4583b4b782fb95852e537db70792f5d9fc33de48077fd7d4e087ff4edff5e14a42cf4f2a752faccccf45be2d8ba14e7524f1c615cda458a2fb782cb5da4e0e17eee7d47df7bf672ec6875debf14caf90a03ff25be2803ebf7f55ba0582ba0a28e1d2dd11347d98591b3d369948ab30edcbfe6bece6377fed49f320dc77eefe70c9a72fa8d13fab2e7795ef764af2b90c1f673b7cbe512e56d47a1a707fb150463f9c71d7da36f6dbd8be3bc1ce8eb89b30fe4175fb03b56cb6d12174873ce39e79c5ab6d8c2ca953f63c8c7837a9aaefcd7e8197dec3352a52b9fbfbf7850470025b6fb640d17727d5f1084f92ed1fb1ed6a0025ce2d823a3ff8130c348f90a7388bd2bf6333441c8ed76f6d2fa1efc75fd9c52a34b9cb99e8a2f97e89910bbde832fa9c658c936b7a4a5284f56a6c2e4ae661645f22047727ac9a90a8220deefbdbe1fb712ff97962ddadcd77f200852ca693ba29c0af9b6402b85fdc04ff080afeb3d68bf2d90081499698cdffbbf9e411082dcefa7260882df4f94524ee340dfeebdb0ef1667ae7f072a20769981bc10e4944c8281644b34a1e594d32437a5b0f9359461c620774e5152814ad851e2a86efb3355f29c2633b3bff4319fd2e94d3e376faeebe75f5da0cb5adc58b99fbf725caed073c8913c612e51feb844ef1369e174212427ef918abceb8bd06c4eafa7dff77db1b0ef9c733a61c71ebedf2be4eb66ca35c0652d592c5ddc652f97b56425dd9d1e0f8dedfe73c2ca6f70becbe572b93e27ece77a97cbe5daf120970873c55c2e97cbe582c580b03d4ef3d6cb157af7f57a851cf0ae0b043f19c85fac000c247362b1e9e5844e385370fea3af1fb621f6e070c99eb0d8b740d87f1ee8c1843d831dc4fe85a3033bf060de97f862a059072fa7bdc41eb18379633171c86931256ceb7b7a767660b158ec5fb1900023b0b1afd669fd31716708471c3d02046169072fd08a218c7d77c2eef6dc0edc715ae3709a1c62200240d94f1c77ae164f974b70594b9698fbb95e5ec89f1376945d097ecb55410d33f687bc2e79bf594c3c0184f9c1f7531c5dff89de77f70b47ef8b8923901b73b99e9dc6379675edc73e87bb4ce8ae15c7be31317489a06520091359bccc409d43ce5bb6f1bd74fd50d390eff964ff999f681968fe50dfc0611af3a5ce7d39cd479f11e7ce2b5f3db7e70fdba8f7831f06ea8fb90e13669ecccccc93999927f374f38db5878164723e9db3328737586571e48e3b35c6da8ed3e7015f134c9897190887813c7e859681b2eed853c1072c6bc1c2ea71d846d8d7f320b681e463af49e1103dae1d43b519bad25fe08338682fb3d5602199ac7910ecfbb99b89ed86751048170693fd912de719023c3fc11751f032d1c8a973c471e882df6211cf4f70646b71ac5d1004c57e863a73c10745761a4ccce1b19c3f22b23018ec3de070fc11c679753e271cfbe63c2c0473421c9d30f63938e2009a46ecc170ac71639f43dae9b41a56d8873d188e5c55e3824d60e875e883abaeace5b1abbe17569f41b33b12c7bd2b7dc4e290695d66c22acc6526aca42e1017bccc84150cb73bf0b1cf38b9fb56add5937df7934da92696bdebce0f5609c3ef41f6c5b2d0c3f88ffc0e3f9c170e48543f4cad46cee34c1c1c1c9c9fa109325e5447fe13159ec1a23f99d00e25f54bec3895c239c36e9eb7d3dab73c9fc33bb43f799e41229ecfe155f729c0c1365cc8a9e48f95424426f87f22305e06052f3e910a3e94fd054f64f616e4b8209cd1bfe0637c18ce76c470b623ce18207ecf1789013a5970d04982c5883539580069795d03a1b33618207ce5e5ba216e799db367bd4e66ab4e0224104d53c63ccd97d5837c24b7bc4ec7649a2c6786b1afee641b55555521034d1a65ecdc9de241f25fb46f592daf6ba6dab7acac2c20f2a78d1dffceffff7faf8a40fbaffaaaafd2d18940fbaaaffaaa87c23e791015176a1f206118ef2f9e959595e5b4fe2e060f1f5fe0052b6ca6d8e4961cf12d2ee042ae25edeb738d08a49c4fbb70a4728a3d66276957b1c7a44dbb6743f1e4e30bb880c4e6089b26595417545703de352176fb93bc7c7c811a97a358f8d242d3e5a8a42fb788cb5149b7fb3eb42f36ad6efda82bb26e157ff8dd80ec8e406eb7dbfd21bbfd6065a6cdaf5efd49c51ed7ebc6fa7356b1077d797bd4dfd9a9228e2345a46d486773d2c0bcfd7ec3dd6eee21d9d1ab4924a8e4ecd9fde524e9a0ed124bf0dff153af43fee8e4ecd84c5f241353333593753925ede7fcdc71e24d5a86d61c34b5eb81a5843cffe9762967cff939efe998f9d19ef7d211823733f1d43d5826f7a1c5c4403558a6afa1953f4dd5a3c4ec266e1eda9f81b837171b05a621bf134b903fb2c5212530501776ec269ab73463a96fcc97efd1a858fbda6b799d7b1e9691b1ba894f5337e91b93a984eeaef94f0fe508c5a6d15f4397459cb9ea2a69951ba16fd06a7fb214ea3c76b968dcf2baae25d6e48f7ccf7a9d4ca4c91f1d9c1dbba99b9a264e0998cee96a9da41c1e4c24aefc190e154046bb4193d17288d8916941e3ebe6c0b96c2c175a2707cf6b87d2491e340a09b18d66a0a6c91c363de5ec9e3b4ca64fcf0e5fdd4973da1c3a0077a131d0147f6402b8d2935db1e3506d2866c3c7e3bcfde1153bf298dbcccece8cc3c809cb357a54b02c8e3db7ad1447a32b9f8f26f3d16c1ad51ca5c29b2815982e6d1ba54c9f7ed75adbf5dc6ac960f00f7d119cd632cc62e97fb114ecd838cfb356267b991403d13fe3340f8d8dd1c48eb599fc7ae79dc9e725a2d8e2f212516471c7ce758e568a8bb1a455633e076c2376e988c325ca1888fe055d58cf72e541b866c25fd84cf887829d856d34e8f4c2e152974b1c5b864b41d90a3d90a8d5b53a113665297d0ba0b0f5ebe5a823315c7939eac8d2a5f5e7bf6a388d3e1dc01256c7e5c0698dd5420363ce29ddddc5277777779fb25f3bd7ffebe934af041edb609e724e1c9df8441bca5db5acd166481bee58c39d597ef9d8a756ab31820f1c595f86a8aafacd15bed16a9886cc72c75a96cb625fc1a8902de6d0c6835cf4b1e2683ef619fdd603a8358dda320b856dbd477f874cfe8823b05feb86be7f3d0fd7776290ee5dff1283381575ef1267fe3571e6570c54bffa19db594eab5f3f0463a5486b2c97c8a28cdb1d964315bd5a9349211db52a73d4fc26abbecadf1c634ba0973e093e74882085be2394f21f61f9c187bdeb3f4f6cbd80c81fea33f931ab99c46ab562e24bd4d1a2af1cf2879e2063a06efdeb257d5848935d38434ffecc8ac07f3d28b2fc697f7deb5f624b647feec0ed102b4b9039a4d0f7f475009142afa7fc632dacc91ffa3487d653f6a4508d7f78aa255af9c37e3b246ef669320b8ad8d90e24efbbc7b97d5da3cc2fff8de5cbcabef043990cf6fbd7fbcf9d1d2cdfef5fe26cc7f7b306b0ed13dbf6fa198fb6bdbe6d2ff1e58f8c81eac7b6589907dfb7dee8b50309c9f52fa4d67fe26cfec7b8d93462f9e3fad6cf6fb5fe138d5aa251ad32185aacf572d487affe67a590b4d51ffd368d2a59c643cfb2ca0069eb442b9fb0f4bfdb1bcd910d699e68b24203153a8c913514b1446e49c9932f5524c9a4a8335777e7725411365a2e3ffd915d0be36e0ffee9ce74ce661c53dc01986760fe5cccdc62af19a873af9479824c93eedea07706c6175632b851410635b43332e490666882f1c577b2d25aa3ae9248b232bb237380124c0188ba228204575277b4566677c4cb512c48b16f03922dc858d855065b2c5826032d1654a2089b7339aa0a2e071184a91285829cac65b437510c9171396a851ab620411249282811c3840b2637de9021b5d65a398082439aabdb11596b240d4542c026290d45e342eb7294162c53522debbcd25a690650589ccb5157b8d09454f941b2f672d4151c9eb8f2441645a4086965aa0c915a6bad33cc550d449e5a628604c1c290145ddc91712c1525451452e48cd4bce63f4e4fac60c4c2de6470439b0c6ef6438341d513187861e9e5a8dc981f2ad6bb1c950bf3349b0c5551556e789f28235f5c7a390a8ad51dbfd62447dfa33e6ad77a33dcf16b90e18e4338b424943b32d55208eec863ae3c73c44b142fa4a2aa9031442d3de9d45c5145d2940a498419e248ca1b23382c490551440b36f93aa4900796a678818d1a1e8c28d964eeda1ddae5282757dc9ccb514e7277b44f83068c90220d0f52acf04413f904eadbc242adb5562b48da90a0852e7e6823612002ea85c90313921e28a53074435c86247838628635e4b9bc4f9496a66b2f476959bae3d73a2f7ecc60f065c99f389a21c907334850b88105304b6868152d545beb981699289076d6b82e471589e2c2b81c55e48b10b59ad76ad349e9a44961e5e5a8225eee68a558bf1c55a4cb944e8660353de09c308249912f2cc8265145b87407966680c10b93149535b65a8d2a92e58e5fab8146abd59418695fab81a10245052a0c946432c40a0a2570814c0a6b9a904b34704314370481c20878b805e15794c8d8e18b2263b07893c3937f2899e48eb21741d21434ec60868724ff503cd29ccd1a2b68b24082839632b51a184fa3064a22e112e4b0830b6c567022428bff20388cfb5b28773327542a31c0a188353621ae289bd3f48cdc0808bcb06213a2010b36a749a9bf6ad83c30b9a264933571c6a37e97664c931b6c426057b6fa9d68d44e048182954d488e0bb62ad27c83fe23db375f7456548d3c230aacac10c2260414c25637e8d0680055aa18926513e2512bc860abf906fd95f61824b26461a37da553d4154bf787bc19cc78d059d39f4f43ebdede3e1b0528eedeee2e9f711fdb867090f083032a574a29a594b286d736f76e8b3ed3e50d1ffbcc781835154fb6fa4e10e89ebe37c666f48db159f913847d79b98b104977ac5d2995dc18f4c18eb22b7f2e40bb1c756b73a36e672e47ddc2005d8ebae1703f64a11ad45208bac45045893636f90d82d04d10c672d44d863bdfdd8bf8e4532674b87df2d541635df1847e138e6ef747dfe64aafb790759b1d69b1eb1f631b5dc17510013c639c2fbf7f8ade112ebfdab5d2ee64d470afd49bb8e8b47d8bcfbf63a07ec97dfb7b6ebf8e22179281a5c50b2b35866ef317e93c76fdafdee9d806ffcdc969934f5934b998b2d8c273045600545d5c58b20605ef65e50e76b4ddc213160d48724aacc87a7ab09e10b164c8fb2cb1e3d36684c08eb44ea6596a951953ab21c58eb5dbbca209d7550b433898ec3834a9a8b49082d3224b0e0e60b023e3a67094bc48c17991e28497262b2f529ae84840163bf2540c8b6a4892253b8a6cb0235329cd2b8e7c57ec204204b6d891ab3e2c2cb0a4a061040b70ce958b62418a112324f880b2235b794ab92ad250596151c28f2a7664ac1615152b50210390a114a884ccf695412c95b2810000001000a315002020100a87842291480ee4d1b87c14800b759852785295caa34912e428884106194000218400008c31c42034662400841b56c86f71fa51417e37e4a71efd4006fa43a135d3dd9925766406335d98e1f3e42b414e52679ac03f9b8fadb2dee55c91f30e1778182846c5412f0ffa798402a4f097292e3f54c25f9bf50c5a21bfbc262d9f838ccf13512bf4298100996c1df0280bc341994c870ab3476634a005339c3ac35044545f0142aaafcb7d202390cf0e4619ad6342aee4896ff35f326500502460c97e021613232e30b7204cbe25e8d5798ee4187c6478ed99443a591507d17ee3f4044db28af9c22619afd3a4239f17ec93c277f28adcd5b12617c01685ea8c298b4fa3d65432d88bc90533c25157b51de23d6e2949123f0c450d880224a9cbfed72488d92710e8b226ed4321e6827097a4e04bc62e2e0a1d64c3da301fbb474a3afd9bc9cdbfe5fe9b20f199d9f0a907e4e9c9b7781d3914c58569fa7036dea1014008d1ca956e1b0e3c39d5e9635d5bedb8c92cc67d04a3ffd72f4696a91e01014c7d70bb6622a11365cd44828e603513073a02a899d4b7a23e85e5a2bda008ca259ce31112c100d47009363ef61b191bc7c2f60784631d254fd276a92219cdcb8de3125580c78bf433350ff14ba7523a0f1c12370fb631cd1d121e115a9be519f7dd5c922f02fa60dc1de55cb7e4790180facc5afa2332de183dce8bee354b21b45c62d69236ef2117f24b4405fee26f65e12f22c25bca9ece60c8e7d7dee37f2c11ec111aec2cd05792923b459d8e705ea15603cdf780e8559bc0a233c572a11c44f6df3d4f933733e9aca49e091339e428d9152f693fdc3274887c1ed38afac03b8162d70c32bcd8c4cd123276b829764c4c55610929aa9823c6b90c8ce21238edeb5e85faea737c4667331cfe8021ce1b669c6a789678861770b2a3962896746e7d7c7e501f18f50377e6323d27fadba284e56d9c46440ddd99b80e0fb7f5790c79193e6991c8db54f059fb01842936962dba14f3a73b0b4f62b1ec615d9d9c4d6d16f8b58f5f86305e517f4a1e0f6f61257baaffdd9b5ce6c01a6f85ea0dc58fa0ea13706ffa74c43727a1352e52f47229761169b983a3e23a562d7721af8002cbb03f866f0426f1e1801f62f99bb2933ba87670e11faf1e3b5903e40da79c3c87b1f4f819f9e01842de0b853f88576255d8a9ed0af895fd66348f2a07b3a5088497b9551c71de3680ae0322c1aa22931084f63b6492df2705fa031976583f01e568ece8af6c4d79ce5f5c59859e18135340d925f33139bc3a3731fb57177ebc4469508db24e289f37635f6008889323ab619f542c1f4b14be1d67b08fba2b576748c32e764558742cc1c40d583fd07b256ce20f28c3484c020155d8c8e2adb1110e8c9e3a4df7c2b33e58a9a7e91b64ea71afa9de5c7a1477e44288d3969f0dc465e5303d132924e1a10225790e101df415554b9efb7343201ce30b3b7ce9b45930a0b5ea74e296274da48b24628f4c94f004e06a5c089d88ff510c7d32d020ce5749f9dd54b6144708df323539aca15de33859670536ada3ee520a7b26f779c21fd5ae9b08c9298dc99eaebf440c4ff7e789ae30a8d221a2818c72bc07627527953e2e6e5037b9e2df569de38a95a5297d9c4db126b4c17b7054d2185549476bc3a402612353abe2e2d53945376a5cbd34cea40eb305f028f655648a4db4fefda2b4b67bf9d85739d13963ec899175688d8a2d0c33cc15831e10040f02fd3d316878e79a528b78a0c6435da6c25ce340d11c9fbc71456e2794791c94c214d9052118ed20add31cade11088cf3a407de4bbe8102d7d28132a9bec53c4881bd99f47398332c0cd517ecf456fcc1179316f452c7e6c3249c4a0165eba2ba422eae611a5465b3e8a3faf6b35cc5c1a216b649e4bdb8afd3077940ac2635f7eb166dc10edb075d5e1735021fdffd40b51fd28ac28cd742b756b4db53133ec632cb56f5942347191cd7e6302f14fcaa6645482478598055d683c69c1a592c3f6ca1666aeba3d043e40afd031d11c79084d629c932679ad7f8e465826f199954919508baa410c204cca2a60446307875713040b242b6a223352e6452fc5b9374f90ddc0684fc98add717c36c9fa0111575e43c2514e535fab39d6392017714691276deab6621e547308212a62ac848a8d78dae616383eeb0f4326fc1ef4b460d6060eea79b96318c8ea79513259e56c95160e62cec5ac56e93331a81a1639eb4b8a6a687f4c1db40cd5850b11a45db9b946fbfd284085c10500c37e26354723ce43e00d335e227acacae44a6b3539f363cd35fcc772d8726ba3f44ba304f0c2f9722b894eecc9c2da2496672c8770a2ca56c63764ca5738923b8b37d5c42a0251e6b66d6c7d9abe487c1e7231dabedab3215adff85e1fc7f6513aed6eb14bcb70c19aaf24ad82d413e364b531ea42f54cc7858d969f07116be9bb2e0300c32915da84f61a6b1298c5472abd8e95228a1c660a62563268545b54ecd57ae16fc10aeb2c9eb4855e941ec079276aeb134b1c76d03d8f5245b8379f22e82b500939b4bc17639f547948145660c96af5ce8a391dc34fcd46d3fa2b3ea23c6745f799f3c4d42e8952de67a925d8f1189692d24d0f8049f239026bda8b68ce7d62a5c0ccf09ca400f349a7631529ee4e26e7332fc4ca9f623c486b32b20edd172fccb7354c6d032b3b9ecf5a5cb960c5cfc7c12ec65bbbed92983280356d989cbb4ebecd6569020aea7e20352b3bb2fb69aee8a6a51df0d067ce3790361571e73820820437ea77f28791374a8904907a70ad84b30595491009b21887301019d8cde5688095ca3b56317d39894ddf196e1128c5629707ee3949ccd528ef7c4e7a0754c231dbac62e0577390cbd9311f60ec3cb8e96c3d4f60a1b4019771bdde4bd4a7e4b780071829878b16304288c69aebc0d34444f6ad1a07dc9f2a3083f214f54b53511246c4134be6b180219d9fda0be16a1c4d1ca6671df8f1d72fc22fa607704f52c9c810cbce163c7e8bc8843a770b96c958ae5387cb6df7f36b210fbb3459225f06b83e6c7bc8756f9403ba56ccc47c59043d04d3b750a516e60f56928e3860504956004554f6b7a0affb84a0b536980414e880133edd9fbea08010fd5c0918a1ead00e6810c51030e0d6e17c14d3ef862857e0dd2c503b7db37c234497773a5483ec6d7d9fb7beb43b7cf25b7ac86ef370a2c42ce03b60848e6f18930b6f9fe19961a6450ac39d9a55de5cb6943fe226ca981a68d77a989aa17ab483c4dd957bd2ca80f6e5f9f61c0f5a5f5967b02d7f6161d0e58a7a2176bc64f8bbb0ff17797b7a1796d40b092b78d907b9970055e4537e2a6e3713772e07a58a7a326cd600c2add81aba8dc9f1466474ee7e126fe0e021300c97162ca537083d4c88bae6313e61c46bd7ea07e456504707cd1165880b636213703c068645cf205d855307ced1c81043a691c2351e6e571d93375ecebf127be3a3cb2c2094cb8a66d47dfdf26071603385f8661f65d099ddd7c22648f6c5e861de69184ae19ca63ee7a1d68607f56aceb9e369b12e7b1ed37261d9dc1361910e633806d77a8ea7a067d6cc101f39a2503ef46247f505726e242c3d2103140f401986032a030bfdb7ce5a6b1591dbf6381ea31e88dc47b03634fb1be460c0d9d7d91d7965e67c9e70a5c833de5d52cf12f64e94ce265efcac479f97809ff9ba13cdb4d7094635a1a63fa04eba1b1b1d3b71b3f2c2b2716cb92b0aa7922872de90d4be1bcf06ea21cda6653e7f2df5f3aa0b33ebead26ab7618e26cea3040d8b83406460f79390839cf83dcb63d26280333194036c26b5716aa10542667907dbfe5d3f1197b4aa0c4e85596d297f8527defa46280de22946203a49a2b48b363850ff260061072a49e42a7aec7b10d5b4e672716cfee4ad125bfc9741eaeffb3380c34cf02faf2be702901256a5ed80e4f684b87ffd87d962c46bcf7bc11b667d728da01e4f5f17adafc0e7e61baf43e3636b695266a2433559bcf5d7698fc913c59b518aeb4b6c66e8e8c37d30ef931212733329cdbfea178dd2804411f2b6591fffd5144a787f4b3cdb8cfd083257d81bdc4edac8fe5c2844f8228b6cc45da57d72b8fb0f62f30e42bda5dd50fa2e834090f509caf7e35bc5a4d43ba829916776256218d8d43d1094fc580796356c45ef880bdd476bbe9e933150892ef8a81b897fa46de126617d52c23c9d9d0aad823cee0e4f2bbbc0758b2ab0ce0d4d343a89d4779083544521a3b80480319c6f7d9587e08064381416a74e492478bcb0830a90598b90a2e3c115ded0db6fb04a438da79ca254c54bd77558ce2612800a7db2cfe7917076b8df4cfa1cf1faf20a668dde5d128fdca12374ec36fcbb1f77f7f1c9ee2bf12a744b6b53137edcaa9b776ea94f34c1e4cbcdf2bf02092e0a691e2883f16c852b119eb012640e7cb697426b133703df66e6615fc8753cecf57e28ac8ae88a6bf800b5da25343b89b6f868393bf0c79ce2719fb825b9568569be30bc3d5806aaab6a19f2d056857d275d563211d0c11d40d06f65d7a260cfcbafea4a6bcfd422c60ec284abb50a98465537bb4a7c83322aa591b6429b3a6698913153b799a0bf09cbefc7714b60b7ac6d3e20f984bec3620f53ae44153540daa67034fc85b09aff1f29cc015478da5559651122ba8501a67ea0ec02db71dd865bb49b381374fb84a23e44644badb7f17a6c4f606f6befe6b6f89a0510a10677bbb4d7e9e165010e3646b67beb85eb102a628ba121075705e536eaa2d6fe55bf0fbcc4250cf007ea711cfe59e5b6720850484d2890d591e5d12de986e75afceb10620b96f6ac0e27c8ca34fe4ca17b1a0852b392455912f45817f39cf02a968331031c823ed8e022c0d06789c61eda6832e9c192ce590b5ddc885d74fb570828880086f5ba29124dc73c9e1f18f8cb83a1eecc8d51ffbb0bbfbf4e671ea104004c4a97b1aaa346a87e02fe9373371ee006d5a4d4012c166c0e3f40a72c77a96bdde65caa49d3f084aed6f65c532abf408ae08cf3b513491a7e09140d7355c89410f16444cd855626314a3bdd0af929772252f17672207cc8239ddc75418d3aeb0e598d4263cd3eb0c4122b866b042d4fdd6cd32b200b0ab1e8fe08f5ca4dbc302807c2cdd494b91dea769564b1aa9d4d83529d1d786f471db47f9dbf812c3843e433611dcd4b07391db4d6e4db7ecff3cfc0c1ade2f451be34cf7d00d86a482614d1b015dc99437ab043756346f361466ffe977d8c6a4bedf4a37414cf7f8814a98a06a4d11ef139081432eb85e856f033ec62addfa2f91c683f52f6bc17108662b6cf4a899fcbc4e840b858fe3127d9912e4ba84352f88c8d34b4338473dc94c206deef759957c90157d712a0e534a485a8ea755d2acd8ff22b5ec754c21487e5d96551e275b10e20338bb0fc243cdf6511a04d66dbcd9a0c59b1657c9a924c78be832b1242a65c02f041293079ab2c598aeb600211b909fbe694ceb1a91faac3f8037dc370d8af630e4637d8644b517309f9074aba1c8edbbfb857cc617e972f10c672ecac8da1ccbc7c680d4d8e38dc6f83865446736e90b4b6540e1145a7e7d4f201833df2c22317721320a43f922a629b197460b21bac26470e3012cdbc5d384c5bef5209805648a41a4c5126e3c7129dbd1d48718bb316f71012f504fe1687cbffa8358f0667e528e578a0463ab8839ba62bfd36e8216d8d9fdf301723527c20f87cfa612652e6f657fc92d57f98359e733d481e8f1cb9ad14cdf7f725920572c678782d9271c8733aa1629a9c9dea4012e5b0e8117f1bfd81c74324a28d92661c9376196bb0ee04e3883889fd99a18a4131d189d9a0ca03e73d0d6c167d53c7f58db13aca35a323c572473bd03de31c1d69aa4337b8a794cf5ea962fd49c035137dc600bdeb23f5fbb080f30e7bdb3c5de8a24954aa534d0ea27fc20270eede74fc4d270781c39119a859af32ccd19c9ef0875032448bc93808db1c4304694485f53b4dc507b52879a027adf3476269a8434272bd12220505682fbe978702073925255462b3a5cb14d90742cc29592266dcbbf28dd6c3571358bc6428fa28993e333189c60b9821cc89f813ca58b0c6a3da74fcf0387f888f1943a1e3306ee4854577b25500dd28a84ac5fd1026f76933435ece7f38bccb0ef16c744284abf84f3a24b9f03d81a3c09449f6e2e7f684ae73749e08bf4992cfc9d7e4e95f3045ee15746c3aae5ff62b10cd9fb705b9eabaad56ebf5e1d2a4f975dc27965097c833016d59eda716530ad9e29e58e2f2ba171399cc3303e5ae3907584bf5346e6b119f0b0a9fb2f5a617bdefade95f4a36e2861a4ccc047b3a3f655b4ff9f65ed139f7c1308f32a22c6f5b56c0d38054d024fb26ad4b7c6220ffd7912ccfab37b59590f1a3490c53afa5870b8463d7e6251a9448d575e4327039a2416bb65d25cfd6ee136d595e6bf28e96b60a58590a805f166d4d0c8ea09eb431a81be04dcb6a5475dea07f0593afbc7dd138a9ff99aac9778bf440d3e8473fe34a663d0c018faeb09bdd5c1d283ac464cefbebc942b49ee6f4bccf3c2e59248cd7bd3c5c0d93c9b68e34c70403a73e2d839b36ad4b424adcd7eca3a4b34b2e4aa294c847bf977559c58eee92299ace0fabd21d7439c6659d7c74ddc78e9d0710354e45f45f6fe396a247be17fb7067eeb344b000787dca4e003d133fd045d75c97e176320d3264fa91324411d3d6080cb99eb2332a26f204cee4d7ce2d8d399618481dca8d8bb577a183f1ecf971c9b94ee228dce1384ee7c76a9715861055cb09a933ab602b2920d41091eb5c14ff15809430c901aaffcd70ecc051e87fa6d62f9a97e48e4a60347f96d0bce2e8dec8ec3ecafd291b9a2dfdcb1219650d1bcd0b4685a4b6302c3351a5f030a799172a6464d3032889fbe1777d41f42a5959442551cff5242c8247a03750457c416f0662b6041352d1435855348f81566769593b1c8eca46e86ae44ffa4eb90a2af3789d3ab3c893b54778742271342e390c1c686d59a22586fb3ac42439011697dfa5127a83f1412d36e3dcc7697087d07b6fa472b9abfa79535fde6adc820c5f0e65d1cdaec158fcb0fceee5641ba6ea5623b95410ae1367bd55a265c78805db58af2fc062916dff637a9ccd0afce96c349867ae41c7a1686d68f056219aacc81a8c291930f9f4602a9e861aa0af51710e05c594434d56445f23cdee64b8c5d43eafe2e6904e97a8fe59b36c8ad1e7e8574ba29ee1478a180d0bbffe8e5db0eac4b47f9f78d91285fa3414aa7293409848037188c0750cd2a349948b7c32795d0e48b4566f7255249f48d56fb2d1785ec3e4934a3365cb35af90b02ec768685ba199072041c4b3d6fc7f099495ae99da95255adabc5fc6b3ea26ee056a445950003afdc03891bd0964ae84e6f6361b98999515378da4037c2b2dba5d5f91da039afa378fc7a382be0079792ae9fcbb5e2920e4514c155eb025bd08bd142b5bc67fc3772fa6feb355d02c50f969b281e43804804b5b01703c9fc386888d4f3bc808c61412de13a3b70e66518e56ec8de304b2901d789effa31cdc8d12331663a1a9c61f62c0584c99f5ddd782158e3df32f5509d191e06bf97defdf704688d80fb48b68b42b0e009005d8361b758ad1fbcbf655c4b2a965449a359738c91ea7f13a528a83880022c893f51020941815c8f6996c36fdf537c9ae3e11272e9334a57a911f8a563c47089a4f33c6b05bc95c002db0e040089ba31503222b6b54525837bdc6966df58548e790a38941b7b28df87bc6c7c9c66860a15913999769cc125ef58f83203833625062ec5675aafb700b489366786c14d621ca9edb5297f590ca43f71a2c93211cd7e7338dc1dd8ebb1015c5d12424470c46a0dd7a8f2862171319cb482092da1a9866e56b5f20afc1cdfa0247d783368164409d05f95807e1f7fdc143ead9269e916c125dac91d2cc0b267fcb641e4c08a28067b4508b77d106fd4849642696f820982df7344ed9910a2004ccd8704c2cbf10917ad74c242e5808f9e39122299a3ff4dc66f3ef957666564a3225cbec265086bd05351c3ecbff9c41219ab8cf3ef1ac58501442b083c09a8d43b26b8d1aa886ccb046d04e152f471b77432816139a18ff6f20edbde91351ce7c4f4be25a6109812ca62dd66eb558ad28fd6decc03263fc7ce143f60af7575d2048213b5011b78ca3e2c78c64dd6e38291b46b34ae6abc1f188057d17296bbbecd5b08c0395120211f3e9e2d588d34975f8c6cdaa3929ef58fd1f393b085bfb0deb11b433c449961c48195ff4011a493492fba7d4e54e94a3c38d1521280116ba5ff19b627d858898c403b4dcb0d1c80e39fb9acdb1b836d6a7605e93281cb1f64746e6913a8910e27abc301b4ddf69a77038cacf1f36a4ca51706aadebe9e0313585adf901482c0de6b14154724ff40308a4076d024ade8b088441d7fe1d17b15bc8bed23921b6101b05f9436b382ebea409e6be863b340cfb103608a87da97775e8cd056c688353112942790ed56ab9da46322977ba0c426af2046bf4025cfa04ad8809dd04d9321f7087b135cadbaf5126dc5c1182421496f8b50d230f5d9a103f0fa1a2d42b4407f876a92b416be125ac60f0c9c10ead93145134cd1cd8b968768bd42af51da46073c0a19dbb405cc30976c1f3874324bbd425e846303b8c8c01542d6863233a122c1144910a8b2396ad987306a4a2dc8273a40d741b60625150922d0167738bac7e4f6b6ca52ab1cd0ada5e55d5d5752d9019f707206290d49b31c3018af200419258098cd159141c34d1fd803ad74a382a4fd32c57d11a932a0c6d9561fe176513e0cdbb61cee338fb54769c20084255b3ded5093fe0783796b18b85d5d93e650f5e39c53e317bc0e881a75c542a36653e517bc0525f5370c68487183b6e3c4f7e9e9ef258a0d67e09474c70c475e761cbd19bc62cb9714c79e9cc13e1d884e4c226f133e181068456373ae0cdae6b2d141dc72b477b0d864a57f5b5d3f32b6bec7e8d262d8a694a030ea07071418da035f40d4bed45df3c18aaefb09817a51e667e81e97d077849033beb4ecf4be80b504de9baba66bca16141bc89bdeab8bd66af424b266e6fb79d09ce85775615d43a99ddef8ad2f6813a7b0f8603ab8f6e6ff9b3064fef8b1843c8915d4616921e58c93593760469b8dad6017e6b289acf31b8b2ca59570ae8bbb622a1538cf7bcd7e41bf59101d56634d39064217d21d63ec8cce3a1b746ef54fcd124607fb34893792122e5cde06d875e2a7330c20383d2af3b07dc37a3389d1ec6197ad2e0586a46d700cd656a339bdc00792a796e3a07131a01a9f47d872938a326074abd889f81f8fad0f2634c1b8c6eac8af67ff9fc9ad0c1a862748e04fad1c8454e6cee6fe83804a0f16f68a6b4737aed674b5caf706e8ac8ef421e6e7f434e799bdfe8426c359764492900d6a7f1742e3a32a0277731c82430cb7bf2c4fde836c50632ee7cffdec82c03e336a1042d3307239ced5b886bc13a23e0a7bfef22c1721d97214e8c50fceb2b4189a583610eda9ad21a0a60866a165a799184b520baace846a7e79a6ac1dc74cbc53c67f30ebfb622a9586a3714e9592da159a5debe8ef376708fd5dec1b17e83d5ebbdb41814935a69ac4c5194d13927bf7fc501a5f5fbd929251f9ec33800c5632a1236f844a75b49106adad7254e06e48a1b13ae4cc0f09463d6ff283e68cd7a01c52720e0c22c9140447295798afb48c93c242df820ff06d70928fc6959be3a16cac9854b572de7f7006af27ec864b576f3b4222d91ed2aab11e66ae912c1040e0a1cf1cdefec6eaa263bbb85ae81c724145f093520014597200a9710d9127f0b3e6601928453910e17a85f1700038486bd8c132556b894455130a96cab26441c0bc9510a2977e87ff002991331f5aa8d4700632fb2f11ddaef0203ad8c14e2cc2cd7dc0163e03582a78a78074d103cc4790f0325056dc2f044b37a80ea8397ebb9581c5d22123415506f9a081e9424dd3413000460cb144a8f093f619971faf6d98a3bded5c8150e7413166232ed59b2a4f099696c62f47a84c39930d26ba981b41aa55d0469519d6a4acb8269aa5471e45c94652ef611a88460bb31c7bb2596fcf65929e2ca36297de3ff4e6027e4d503135649d8fdd91669d324ed39a1061a3439a53a5a60a326dfeb45eec36f832018b5b444f0bf1524b45cdbcf6133bd96a4dafa1c9efca189f8e1260cb2246d8f02c4842406161ad13ed4a55a87b294eb4789fd175437eed5b028727ffe7439b1c3b4962407c30ae26991404edc855c4a01c5b54010584e81680ce4808f1ba314b00ccfba5f19c02ca4a4e14357bfc41f98a3377238f98de8844d1c3ca022591707774f4352b2a1c5d3e856ac9f5660bcb587e8c3580d6c76fe9c396e06ac5e8040ccaa46037549f8d900d9c29c40f96a1863c86aeb7c375f5d3c484fb534902702304fef264025ab229fe65e509871800b224b20ccea288fe7a38787a3b7442f300101b79ce690583384cadcb2546d468d34318fb3280a853cb6d60bd4f33d2143dfd03c062772ca6c9ba4317a3b61dc658da3e35c91a2fc6e2b1552579c52359a109e27667e7294cffddd04a0937808253b7f84dd977f9a1e00b88a219ea7dc50d329fdf0d9d0ca0c23882d1aad09353bb1ff4a53f3250949c67d1da8d420556b4d399de51a0c1dc77b64dfd5c669e6d84efc158fec2313fe629cacd1733c4a5f8c71a77218f2a56950376c64d7302c4b56c31fd3d44959d6afad7bdd39dbdb4d514855c480f23d106dd50844209b0a546723a4c4c82b2f1d71dc3460338f8d59c139c842d5b22de4709c1317182084200a338990fd59f7ce54cd90991d2128454a0823be45aa93e14446f90d808f06ce74c76f3ed2ed03b0dbf5cb80fce8936eee86dd636dba53a6c66c51b567c1262da575c4e3f6bae55ed01830892898fa9578f4596ef081fc05ad20c6c58fdd0dcf9f316b42eff73de75ae1737f10f5f9aa6898b7c8838197a4cffce9ddb44465c92bb6e77a1f79a172ded3a893f17beec8431da52cf0ecc0f78ae3d6ecd3da29eedf8769669d3e9bc7e6e0e59a160110e4e82af2894800721638c65f60fbe3e80b6d89fc99b52cbfb50292f3c7f513bb221f42234d64197a56260bad1f06df318236cea18bb5700149cb01473e335d7cd6ec47d4ae8c902077106287d67db85809837bb821064c9ae0ff9552405a68929e054cb5af4d845b6d342184b55aa25e7efd55e379ceaa9f8672817762842a1958162306ff629d0bd6d6c7e991d61c00343e2b400244c5f483a163a9a76ef38b8e8750e0b07d4be5716ec971e0eb409db861747134338c8989bd4325f3d7b5c999cf7ff595f841959225f04d5d170522941e4242a972e12f5abc280ccb6738669007b59871ce7597f9596b003b41c233b50f35c950793c3a625898fdada168fd0d18c81db19f51313161545845d8db20b339eb7acc5cfe4119b746d671b1e80c3fcb29a0c86b22088fa77ac035a07eec5bbbd364c0d7c4258c3591cc102844fa863353590206604838b78558ecb075a4cb6738bd2e4c203ef9a6990b8077c627f472d0bee8c2140ef111468d8afa022d9d76117ca87b7f562bd0892f16b574a924ddbee141166977844943c09b3e65004a5bf0c34ccc6c60b70d774f6758b860de80cd08d5dae3d0951c5bda3eb9f3ead78e19b26e2b16cd280641c4a320c051ce540433997b337f5f2110be182a954eee183ef8a93ac4d9f250531e5a921c79e78bbde82d4995da489170a73f9e4db0df0c203655f0e52f41305e35365908131867fabcbe1a54d0198c1d001d11af417a6e0a7e75a7fceb8645563e33fe0ea2aaa4c4d84c7b03c7f05ec37e2bb1e011bca3f17df3076dc4ad2d2d242c42ca857cdaed821a0a95438cb5018b43e305a8d188b890adb3504180c7536a90daa81ec34130865db10c82f9501b67a8f50a0c02fa63b8a8ada4967fcd9d7096f7dce32d854e0e25339b217382d835c555f6d0d840f72d0b1a8f8078f55d7afa537ebccdc6a75981a74f60f7f11b600408a7e417ed66b889f940fdd779c7bd194af212853687378f56a0b70fc89b47aebc32dfaff70e392f74382fd14a06f4e43a74479bd371bbf86a09ecbb77bd6acd63e2673d392f61330dedc85c4531316016c08a1c3ebe72060b7a0df1615da352da4b849123a5f0390e3536b2b020899d99ad0c2ef0d9f963e0d203764cdd806f92e8485ad4537bac7756ed400946897d756a569b00687daf7f519e73b75161f0cddcf79cd4ab672e45a6d8e97637a3b2ed1e520a983782752ec266d22ab3b75479ef5a9ef74f5c2ffefa4523dea50a3ff507dadbdf1bcede271233116c70a9493fb8943b903b84b2b340b63109b327c12914cf9f200eb131b0e0df5f7982482c37bf784881c7d8c294221c8b989cf0dfbd0367f07202207ce08d0590e9507db901a2def4478df167fc7801bebeb7633ccbbe3aea84377b533d6d00c90cf9ffa7e20d8809bcdad167cf47ad4ea2790177825eeea966c020f83dccf087dcc27cd05c1bfe448419ca557c94d7513dd0228139b7ea58561c1ba303064f3b5b90580feab4ac661677cb373f9d52d8044c40e120b5b4459c9f795aac1ed50be1c1d18a72703a42ab317bf108bd2c701a955618b240e2fc14c22221085061c28cbcc83c491780115367c83057491b516cb15c1fefb132bdf617eb942fea8cc97526fc2ba21cd3266d82412876b9a0f83578e7faa3e631c16f8749329eaa03d7cd9718b44d2c8429539cfa8eed9ef2d634692c048645e5f2c641539c83563e8514f758bfd2850d7bfe15024421875917ae698cdc1108304ecd83539766e0b22e820edd45121b336072e67acebcb2e1a9beadb84f06248e4f72b0a00288ba59f67ccca91cd94b56cc6c1e8ea77b385bf2c7ce0aaf026c12fd2d7428a5e482a0fdb2362ec17be85fe971759ffd054919a45cdffa348ab0e5e812030159cc03b19d78b2d57be5c076a2d09f54a91f91a49ba38deefc794483c836ea63ed4252b1312f2617c9948a867d6d7c9f95ab61fd6af15f95d66c265bf9a98fbd75c3e73aa30e0af0f8b1e035b13a9d0bb613e8de0556ae00be92606bc95a90ab20462a7cd6b5b9b5fb252926704257f87f4e3887eccb60620efbe4d17cb84c9424c342f989162ecf423588cf36aad32cc19b0b0eb1b1ace3a87092bd070b0464216d203aab6ddef2b2758374d2f10094b4152c7ba5da4995e89bd4765a7adbaa87d5762846d79d52e6621c10e203ba175e7edf5ede13e761c2cfaa5cc17e5cb64618f69853c091ef9fbbabd8b57c9e2d72a14e23d3ebbb67010d8f472c9805423df1e68dcd526e21891d5b0f235e7a59aab86e75f882fcfd28fe8e2aebdd6d2b19d8b9b19a2807349686eb1606dea25cf97b2e587d203232137924fca1db45dd2be7de55b6a760dbb01e5b2661b3381994eb61a24ccbda60bd322646a7ac4114ab145a1c3473ea36a6628a5fed87a616fc3ea760ca41579e138b62731e66143167f791c88a67820b56292353c9f9f318db9a142be455127972a298055e93315f9e548c6518e1cae6fa1406b6ac8f136f4b0a217d2de576672ea170824b1dcea9dd37431707a0bf6a12d411f163bb30d90b5d972394d7b6c32e87b7b5b7b88f6c88e265c2324565f92fcb17008f6c5f9e99323271165a0aa6a81494490d7b935981dc43c5296da0ad648d16551654ee2b7a98bbe0f8d0a5841d2aaad430aa8cda85a2ddab1be7d2049f241c3e5baf1ec8d341b36f8eb49c1ee56083c6d28f71cd6f4653cbd98507081e795a066e226c0fb4d2c6e1fd7fb7e177bb0d390319b4e0948c720ba8b1ae58c6280247b777a7324eb1d57c9fe7330ae227f9e4a49350e44726936775937367fb46b624b6f69ce3a06bf0e7f9480d29061d72c495e0d7b4c9d66289d944857fc37925368e3c34d03429e1e5273bc27918535a15e7336c140ac8124e9c2e9b561880179812cd08e33ce09ea7ac52197b34c9da3aad9435be0d6aa53357fa1303870de46ddb4358694ca249e4632b25d56f4b458f9b0dcf5c91764bf8a94524c589c3756bc0b0af4f2badd46e6ee0ac4e6156723f6f6746312a50495dfe4d5a1f1fc85412b61363b5b1bf5f6d29e1e2c6946868852701d5bb057df911b71f550481dc191d8901a445c12b698ade5583ae67a0f226d1247d3fa6dce4a78a0cfe98d9b4b0581b47b88f36c34abb8e7737964df85e012e77640ca78265a13f4d3428329c1e53f6e152cf4715f8b129145142156d8dfff644233ff2d175d79f87bd37e1948fae2f574b1d274b0ec13bde05ef8db54f1982cc795a40119ee01099662614e7201635d490e7243caae301d912c0b703d8dbba7a78d299d1fa70293202bf7cd10a7f8bbb3bd231bc8a97b0b0060817e13e747687db9876febade1be570d631772395cb676fab1fce95322ec350d9672423da22ea02b930f3bfa90bda31dfd614047feed67c1e4cf11c4ca91fc2f6b74f5383521e5c1cec9e3d81a8e5d948b5400c87f9a0fac49508eff3e1f95911d5dd13f3f1df388466a3af4b1c397446e11f2630b55b061d9b76f2ff7b71885a8ad424ad8f4da9f5b901f5707b438c2246983018866826cf7eade1b921ec3251f5a6283d37699964998d56472bd1a08fe463da4a91ed118af90bf3a7ff0d49fc554f5aa79e38836f6b19ba777cf37f8241aa725dee6d7fc0f1dbd3e059c6b69b75dc280217426f1f3a251dda3fe726e24a0bd10bda449bd55df63cb9bc0ce77f0a32aef85c78d69978e9de58392a631dd21c0dea658065d1a5c2597763c846ac512e0cd160e9448d1d7cda8a5198cd8a825434d4a0170cc266aaef5a78c7d030ae80f136dc41692473b059d04b1e972943d86086ea019511d615e21272599c051e54e458b5873eb3450437a251dd7fcaa5f6b549f1cd2dd1c82dcb680be32a1af7f38f20067e7a249edaf75ff4699cf5d25b52ccf8c35945cedb620f0b9236b267e804141012da3b543abe6bcde1f1e363621ae94da82f61cda86eeb1b2c0e4523035499201ed5ec1933f73104ebaf827eb8bd1fbaa09f829a7206e8369619a47be9ef37f6563e31271c9cb44bd580747ec37cb50f32629a6233c07239cd8ca0b091cb24cce0bebaba8362701d7570b8d13a960d6ba7316ccb9d12737436617e8cac9921a7e15604cb692da81213980b4742882c2cf0d38cfe221b8deae1d01bb26e4ec56486e02cda2b172a7944cc79857a8744533ecb0e5d8d59a67be46712c48ba5d2fa34fac8fc8b3b12f3bcf5a06844ae2c44462761d752a8de2cb38b0018e868581ebacd22690392810704661b5b3536c8281fcb7e1ca7f216892a1b09abe4260a96cff14138920f514a3e86139bcd09875be55d9b45e8a674980170c2731f53f221f7937c9474a400d35900bc75a41ff4d50beef98cd403e4e7b30a89041d6a107bb376dccbb081368e5d5e64828a2e302ba0b5123c048249c60751ae5c747716ec4bbaecfc1c687ee3c34bae01e5ca8c22e1d791f12a72be28d16c4e6efb85c162741b27f2c9d5c7cf704734892da45aa0cf00062c390c5275fb52c7a2f900c1029afdcedd88cdde606925011a85c42d6f3c70af95c399ca9a7322b5cc23e58543fec4ee52a87532d33106f8a4d0167e9b7db2f16e016a0c86ba70fe6c03a712897083ead0d3b31175c331db5963c30408370c08b11e7f457ea44954a54a6f1c15ed771eb2a0fb1335a42967fd05809a1f6c3c3376a6fc80657a9842eda066c91f9fd9043b889f822f83c11fb28e83fcaf2864e5785d0ddbbf60da73b86539feaada1b551eccde7df9deb238a963666179416234587ffa89eb4e19b2a992ae6d68a07e18a672a958df1c69c1f872a9e2c9b2cea80b223aa626b3b23d81ce4a598d2d7c374cc978fff163eac42c84a6c0cf88ca6c279579ded7d6f621ab72e180f5b0279c7b72dbadf5e04ac30d0764834e83d5f15b1e50a9046a94c6fb653af7ef215a08428809b8a58032e78dad5ab058cafe3124c000144920d85333c62dac934dd83c7060d7dacd811dc81ad13275a020e202f8f9b8632577249dc1a8a2dc25ffb727fdcfdb7f9af9ac6ec8a6f096260f7af709b689a22dd2f187ebb73df5e439d2f9361a14b98c48f9eca0c5259abd3722dbb3bbf98b83ca4f440b6552b1837d7aef7c607aee0a78e18a0ff430591b78f62cd99fa314bf7396733b2e7d946b5ebc34d0d86158bc6175d5cdc99560970f34e1aeff5650cf47e4237cca0b53a981862d0e8931b0ef3d8500496e04dbebbbf15ccae0da299dc0fddc597027e4eaafef71bee2d6d74829fe1dbf3d2d7836115a80cc5aace84838ab19e5714dfb010b8c79b0008c6f8d350d3c8687dcb2e48ec269d8ccfaa9d773e7207e1dd28a3857144a4d52057cfaac8bfd41a34321509e9b52c16358b068917d5832c6654647c4e2d305072df04c35b2178bd08b8c29e91a417128ae5ebb95df1a24a06d1f1b1eab3b5b1ddf1818d613909ce3234242c2aa8cc5e163009bd4403e03732846ceadcc36fa935d62209bad635a69c4e13a71f4bed4f81a9d514aecc664cbfc638763add6f8b99ec84a280cf5e9683e07b20b11f1cb0fede3eb5ea69af42e40ec973ab65fe40f5bf283aeb72556df84c4808cb28231132532d2dca7f78a99c857e7c67ef2b1357b28b994988d90a8640d8ed9083d315e71d5162c7ce8d08d4660ba990109ab991ac399b951ce4c46b3fe7873a39021e7e12b04e653a305ba793a54003c46769dee3197f2ad465a298cbc42f3d7a1f480efe98d0253cd95342c4cd22049cbf0b0c267a104c8b33f961e2af95026fbda6d204736b18b49700f8e87a21d096acb73dc1a7ff29f49032c5c2e7a45594740fd4800a368f7e08758f2450a803a717f5ec012549c04bac9163b8a99ab94cd5941671781c0f8fcfafde5279e14be8e5360e18d26e85740bd89085e1df9bc3189fdd34c6e9538f47d061a2c1fdf2529f4b2494a5f0f6de1e40b3156dff9b59f4299844a507cbb36f7bfda9c35454f47b3690986958f46c80710edd2d116c5e0e4faf7c5a68682439bb925a164969048d9e86f2474aba183af13f6dbee1e839e9c36e0a6aa342c86722b6e171280e1ed4e58531ac8129cc0beaa041af085c63c777a5a66e21c2b58b18379948c3f5e5fb3051517b889348deadb315425536fe5dde70fecbfe37a5e3660efe3c87e8ece9576674bb93db3d0b47f3a771cbd8e7fff13887b7bac15735d7c6d9c6ac15dd22a400f3deccc24949ae9219c9ca1e8fc88fd798cfe5ecc8d259a84fd442be39514c7d0b7fd08ef112fb70df9f231362776ed9a766409b8b809b043c681159bcfb72331de75cdd6bebd4c453fd704bf7dd295499067191511415a4536897bb943a6f5f5397ed9a8ab85ed1cff8782a3e889769e5306737b81249517ee2a105479b54f45be9d580f83d85c8039d9b34ad6312d86c6bc48c30a3dc1c3297d855d49ced13e2f353f9e41f252b6a83e72b6afd2a5e7cf54068ee99f2191935166c7d7135db821b3fb4b5b598bb0413b1a30d8bb731e19f57b969083ee6bf340b5547dc0fc121de1d079ac11336e0cc865d22986d3b95826fa6de54a45e9d09f63f2154a6da26dc785d33b36e6004414424fd95dca6682601fc1d61417713aa6a2e0ad11c03e6cdebe24ef83ac1191f5c77f43135db0e3f7fe515b185873d6f6ceebaf125fef4500e4754569303240d40e6d5c7308cb1d27efe375c5a6d613abbd2b196cb04becd63fd8e1612bdb291848e6089a5258991254c0f4c6f4737f27c3e6fe218f59b7e3fdb5423066cd2eed6fa539b4d0018ae4ad65ef9034d7b1592556e7d5aa8051bbfb112236bc6869385e19ced1e2fc2c4db4625d439cca0a309146071687ec3f7cfc94e3aa282c84f080aaab2e4462f841537eaa96378bb74e2c2c7e24f38a3f720aa5f37b4b34bc5d1b2e38ae1fc869fc8b558a35cb6e509670a24a4fd9d024ff6b2d2ce730e0f0359495fcd98a2199ca42b35613db27865dafbcc75c719767c48708733e65b53d052ea0922b1546b33d76cd9b1b0b11bb1b79aed07a20e8c4a99f0a37132c6b86903f556db9130b354698e3303e50c73aabeaa670a6aa297c1ac7e9c66f708fc5bdbf397474a34274f448d7935d8b040285192b6600cd66042fd41400815fa9e2f838c315c1a02fb820c1dfb36d5fcbedca77aad73ce9420e7e52a757edef19e21909bcbac302c7b1075db767ff16e8c933ab79b7ba4b8938f1ee2e759cbd383aeb18bdc883d21b8d03d0a312cb2c307d754889022acca3169054122d191dec1546eeb6b12b8bc940307c36fdb9105d512b5d631ac344dafd65096e51dab35d1c33fb1c1bdc6f535f8467dc5b54b888c6e58e2894fea19fc684dcc35e22e1126a7520d75d736a8ce3e91655dc1e8f46a99cd05c5411d72b6e1ad6b34e5bcedb860ed62310e96a431fbfcebfa14a444bb134a73251c3c1a33f75c11f66d97c813fadfcf0af55f00efd498ab1bb1ca18dda349098c881046e7989b162888d63841172a5bcf65b42af81887b60e9aee9f27b6eb1a1957e6b1fcc8f807642e568621dbbabae3abaa7d03ec80b915f155d01e6aa08f2f6d3e24bbb4c881a49dbce2de1d45f7f999c8336304838de2d3a57db7f23d8fb29026021268cd3200bd7d8937fdd2052eddeb68d8510bf3562438ea0eb21f5eb5611f4f8e6e0871716e786e552e4b480c5026bcc85b7103d65c7059dd30239ea05a4cc337b658020b061174d5c00e5a19ac7c3bc42c2b9310dc491fd37d50451a67aad59a6f12ea4b65a5077e7ea387589955108d7d838457d82c90bbdf0d2ff79627ff9b604de9d2cb55e10329daae942a4c5eec8c53525c53367b1f3e971b63f4a05e36faa7065ac35eb21ae0dd8dac51b045d4fa68babfece59979cb36c54cef4e4363d86377d0d667bf30263d4d70c9f95d620d1a9b1c584bc3f08a940dbd6db17528dcd1ffe1e68d28b54be1347ce0c91e3abb56dda5ba9b32ed448cfde6368f41910160b19b908f3b5609cd833827c990579298fdbc527868f01aa563851f094847dca8644eeb300d19dd419da702f8bd79b2b77a2d210d5f849bf6f771533a9e9a5593baeae695252629a61fb341478dd8151571873031793548503f53791692d5318d39d93abd6cc5e77f5683bea336673382b647829101cc83b2c49405d10a8a50a5b4ac733cdfd8f55d4a2cc36d2144ac51c95a6878a041fe2c79302e7d69b11112d4214a3cc2d6d54ad40b9b08953842f1ae0352bd98938bb615ce3b9197a8b39e25fc62dfc7ef784695315aceb4724bcf8d3c7a4c0105fdcbd8d8508adeec78aca5d536d34840f2d0d4d33019e7fcb75df9becc703243141d5cf935f9d42f6b36e3f67655845ab79add0f050c0ce40e7e28179673bf54c52950469aafb65303d0e27bae68c18b741ba8f7c1fe8f9633066d49c47b523c6f09d7e441895fe50a71dcfac15e0fcb13f5082d2fc94a5df8965b5e11ddc4d11d36f69cae7e93694e214a0996a0705ea35139b3f6b9177343ab967c6d848a43367be183948083883f4765312b5094103b66e8c8d35cadfe3c776154649a9385a8442c86a391b23bba19ebbbf1d0201471337522399b781b5376b9c3ded4db9a00f271904655ac4ae42474a2cc0b1d0f3528f72c57e5e62f800a2c6c8d19413e51c42f6081bcca51ef3d87f16e16db9597beff6801a76c3adf2793a939d296f302a351902a3a9dffbd185ddc24f9eba8d57dc001be14c69b5749c6f6c6a7eb6163b1e1571c6f107abb3b9a1be3f3fc0f888e69d07bf07c24be2e01913f7df895511c74ed0197681ae1f86559ecb64a09f869c50412a9d8ea3759f356aad509da3617f739cb1b95da1e19b5140e8c0ceca139274d2ad7d41247b275ead5039d27667547520f7755f9e2c5c2c6836e5f4027b0160801bfd3240e73a65d1a97f3bb48e431c241028e49eb846939baec30c42c717f4cae9f89a62d2fc51ad6dae1cccd268f606eca0c96dcdaae574fd31152524bc787c244c69b31543bd1c488b29f7101f8e425eef3c6abd2bc0c55b308b305b30d1e7387462087522117596cf1dfd14a079430e312f137220959a27864c8f7b4a2a1fdecfdf7bce75508ee81679731f32d1f7f3198e3f535bfdfa09170ff6cc0a95719916083a0e8ad9d3e47120c9e98ffc7e9398dff0d74fcb3361b51b4f24d293c722cb7a5ad8954b114192833d3b1953ebc1e8d12fbab74116e56d0e07519ad354ab86056234cef3704aa91c1262b4d3db4fcc12c7a554a10051f52800a0dc718c519effe3fd329057226eee2121d848fe075fc439955a509a5c1ff8506c68d54e6bf338995b6750f9433dbebc89bbc3be0b8c650f2352925dd5b22dfb43834f15aed82f3f70c32a948cfb11b4867088fe0569c2f5ba14c012f23df7076eba3b55e2cc70527d42ab4e57191f8a25ceb41b9d4d01dc64a8efc67fada379ff5d48c33a0e1c3521387fb0952918d8427b695e8862f40c222f20d30a13c7c6cc8a679fc2cb8e469018c977c31168ad502dd28428530d1b630e95ca75d90543b64da9470b0a08ba9b1d45b956360cd7a61e4d9fd5f339de6c508b4831b55a222159f573d55de262c44e3efea22dccd0063826ae5882ffa001f78930142330c4d652c067431fb9a574fd40fc436b4b04d3e9cce778c02569f12dc180e092e8629fc7c38a70867360dc6da0d5e37c9c14733816595ec3e418887e9b9119fe8100374c6823bf5d06d5d1d1469354971be8640850805827dfa6f0475dc530737d8e552701cb47a35498dc2e01285f910aa51583e810d622bd16b450a78089c1dd5731e1cc5bb4fbfb2911b3c8aea094426c16985f27b085e89ed84baf28f85eb3cec2d31c65116978a44a575087b72150ddc6460babe6a332962faeb90c4002887d174dd01bd4194e04488afcfe402d54b05fd70f9d19daddfa35e9427eac7f4ea0c4cd24bbb1fa04e7543df268f32cf221b57b1fe9156c034c4aab5576d7e91820be44060874136b4bcbcc6b4f27681575d3ac2c0f396b3fc9e8913c225bf35b8cbbd3e4825412f53c6b4ce56305961ae0abf8ee5412eae33462bc489b6c28a3821e2f89afcdbc34fac7fd573699e46f2b381daedc84b34f91718ecb7de5268734f547f15d21089c88b5bb1bb1b5df6ff1ba655212acacb9a1d7afc9927abd09fb7493fe49bd010d73e0c6f5597c7babcc094c915c4a1414583e6239f0b75537d975540e73f3e8bc0d1b28c073072a1b0596bb36a69696c514dbe9bed38ca8b624962632461e4a784c64dc0f258d2c383d0fdbca7a08c39224e0dfa6e13d99d70cb5290cec2d725181c86ac2e4dc3fcb2a5e630ac60ac4085d76b162abf6c90a3969274ed348ff8c2493ab00b7251da422eacf82247cb2f0b0f4f31bcd82ce43c6a8160ceab52db4d5aaede3f71f878cd109e6795a01b7ecb23365511cf890ce9a45609fe555ee41680d902141d3cb45b46400cb08e53b688df527b14ec84264d0ca6ed9b3615f55e4f4384d0c6d4489cd75ead20a2db945632752c965d06a402f9ce0b0adae1caf70a77ca665e2b3642cbf93557356ba98b4a46dbea590f6fbcdfe359717f1c465a2b7aefa88894f329c22f04e1e3199189a71955e727edb4638f849d133ea0e747b1f3043400d4a2b8d881794cd24cd299bce6cce65ee63603c56d076a4a427b7b86fc48be1f436ac3cb21d969014c803f0ab5dcf72a72e8293db0c4f0d8b4751349e144df9aaaefdfd875a98cbbf9858aab07326e3e44d91c51813cdb84861117bde4e5dc7a84f9bca8e960801c35d29e3b592543f5bf197982646e510b6d53c697bd3518e462d7788b04d66626952dfc99e652064cf68eb6993eea16ea02c30361a1e69c413590f44cae96e8d6a9e1931a45379a742c246bdb78a11497d6622eb2e0aceb201781a1a22b6c1425319aaaa10a9dad236d99eb1019b884ff186d6759e18948b8fdd46d6cf83f5efbc390a14e97f8781fffb40811dfd57bc684fece0db13aa6a1c214493f19cb0707d9cf72d9602293ca31bbe5b8d3834094a8d0e92feb4aeafad66853ae8c3b6dd410abc5c1a5e94137b325200fcb0545d6121a790afc49a8c8cec757f68f5991b0c00fa1086d54040d1452a819a5c1aef4f3738a6db25505a7b703b11659fd0897b62c36f951a4e0abcf1aa3e10e0c9e0e44fea6c1a95cb7c5a36d9933f9445fd45752fe1f1f680af3e92172c55fc159d0f911f9ed2116a323ffdd64faa074e649017f7cedf28515ce3d46cc6d01611617fae87d82df6df30546c589e9817b9694e4db98c63b0b9ec204eed41186b62e4dc60e69dd9fb5e3db4264293b1111aa1be2bf9bd982f2635445f53c1688e52143233a10d374e01895d072ab317b6e878de15a65f991f93d367e634a8019b4166927c9a24b98ac0725278a7dc9afc616e381782d503be9e49422b45377d34ac9bfc0089b037bdfbb0fc7eddc00dcfcaa597d181e39b7ad17586fa8cdea62d8dd906f56333cc6a831b9d03cc5b90c37339b6227489ea9900dd5e1d5908c28020694d9a3cf024cbee07ac85add847c1aaf2b0b62b303e2d512b7c08fe72e17c603a9b7c581a7b3fda3c522c3e30f080921431e3a4596ffcc941612685df714c506e0b216eac8cc7d9691ade7cde74edc2fe418da8b3fde3224eb882444a4392807d44d161e5d6c51dd3b771dd6a4bb30b91a20eb64766b8540336473dd097dfc3490e8de885f345995c8142fcfc62747bea4983f02bb69e1d567a7c0784e456d326a41e697ca8a8f342c28203df70ea7534e6df76201d93acc2f9951ea250261215ac58348ef6f32e1e7fb5e7e69d9dc8107d9a253b4ce4efbd5c6a8075b23434b293fab8042e9ab62161373a9679132b775394c8c6013489ad462c86a24431ed68abbda932058ddd126a4b088e3b4575752404072d48cef7d4a83e6ba7034ef779bd527ff4906b6a62e15d4869f51bd30047a7b60c9e29522d6b02cbe992283552200559a76552a5cf4d684686376d2b69572d58ef12c2bb560c54a9e17295c8727e5ed5b601eebb2ed7bc9d4f52001b12d5ab85123dd70db77b346b12eba8aa653bdcc49ed987dcd9b6fa9e8073c71a311a06c31442e39f7d6954f05400284403af0c880a71f3a096289f9c97f8756a485baca2066f230e0abc16cc07ca8119caf43d44ed5ccdea9af525b3fa5e9c363121d15e6e898215d6a9dae0764599d66bc88bc037f291c879f31b05e9be4467522ee6d36fb1ce9603202d0f6cbb30532a962f3881e604af270b9d639d622457985216e1657d25bcdcc0df17bd023a5729c4f151162514e1874e3d970be14dd08704172488098370c27a90f74e15b0a5a1612d29feeef192c412454da4040ddcd0722963c254b874dfb158253845fbf7b6015b0833ca2cd024c9200096cc9df8a4a41ca0881011b1392401da68cec795093af2e2e7f83916089733fd4ec303dd9457e17a2e44eca9615f62ccfa3870ce672f2f34a0e92bf60072799442adf708c17c163c0d97b483fce83f12893abad2b3c66c1b1ed0e2484170799a561b5a6c9d6c3fcced52b61e14cab90698d4dc9093b6e09aeb491e278eee4c6f257fe4fbdf77f79a672cd5515c78e49e9dc3e81b0d51db9f4d970bceaa75e531383c16420759d972e8f7a7362410f0a2aeb0014fa0fa76b4546b42c8e15cd4f7c0b5228240e4f0c6ef6007debb09c1b4c8e63e21798d5554c21044bcc2a6e7a2136a6757bd456ea7217bd0e88aa3226d65611c205431747d132602d7f7409cd74c167471f8a7041f60b4d41ee292d551377078a5fb9361961513278cacef52356f1064a44ae356380b8bcb6739254beb5a3a6cc5feae7c4f99dbe81073fa38fd3905bc159d13b4e896bd023bba3f076e276444d87360b3811eeede71b96cee3682a27d35282fd6f44989e73f4138c4a29eaacb47cc28f2c5f2f2933218476c497737ed4501ce3e624598b6ef0efe7de6a37d25a051264094fb366622ad6f1be5ad5c3dd49655f0977c802a55e6e570622135047dd0ac1984ad7c6b0ef865ab2e64d15ba658edf0a89595c2a96470eb134283976accf90a919931e1247f39f15296f667b09700e990ca37ce8a85b9fa32cbecb6238a493a416201f6b24beb3e45371c973744430ae02d85237d510c2a5ba7106eb4106cabf774d04ad3a08c66e84675739dad7b11268a21bf2f7e51baf213f4dbfde2ce71fed0c043d37ab246a288d96ef4131124c9f6aa4eafba1d2355ed51a15711e2b827329ab1415cf7c61cc6d2ff614a2c9d05500b310efc37d8bc05f853d6da21d0eac7e9a91ca31841402d249db15a370a44f75ed3991ca3c7a51a9b84e5d765d316402c11ddb9df587908e08054961f9052c1aa5327002f1e2f8bbc3bb594fff81d8236558cf5548a40c4b1b03721e3275c561aa58b28f1fec346091afc844435828685e71cf35814d50886a0012f3fd0857e3303d15f11b2a0a2b6df2d71a9fac43b0084e11063cb411400f4fb08cf6e9021a498f018f66bab530b20e58f0fcea73f64c6d71906adf320cff8f1556eb4c9bd4570d362d1b7db57e8115a8bfde565a4a2430ff5bee598cd0e01ffea8b3fbeba0db07286a4fa5d61aea62608f6ca5376ca18bca8f3a60585fd47d8cb7ae18b2969adea0748bed7ec7442d0f88f5cae067d899c0b9023a76c6388e22cc050eb0b55801c1634a971b4ddbc2d3ad671a57928a13f321d9e335e56ad02fa724fcae024189cca7587d498df9fb9c978a2eeee7ce73c892459f0452ac026b20f1f08dd4d3daa48b8a508a5ca9aeaa8f67bda8fd57c837877d5924a4caff0f185688c4336beeb1034b700f52ea05eca02e38a3fe60e813522e082ef724cab829511e0fbaca9a8eade836e33d3356e41bf2e1f156984b189f56a464fd8cea525b448225407c1a41c845ff5e3fc49c0fe37ee766f0c0caa2efdeae03bba2c0d1a28b28a1d14abef0274162e109a54fd0279f86e9650d038bd6e5648611f1dbc141d110eea7ae35468598dff70a8a31da0516c45f40b5dd835c419fb1844fc593d343d78a2a68d05794fa08d5630fae41036431b8bb5393e139eba0eba01ea0876ed7f6a93ded9cc30733f55d9e67cedc7e741a20f5ebac0ad89fa43b8cc78aa42c886032cef1c11293cf21d23ea0873c0ef7e5be5179918b97d783cce1c1bb965c4dc30b6244e16bbc3d56deac22f5cd50625a95d3f6e4272609e3c0d85dcf23d66bbc3197e73a096ea919a88b1f0c62eb4eafc28162623cb1e96e523f6f08a1fee78a64f6949d1b4cde3361ea87455776582f7df350a30768c5550bd648d6f4234a66cfcf3696cd337357153e2a1fa3f57a6fad70b369b6766b46d9326ab4ddc3183f9e603c9ac3409017acb59636ad0b1e7a9c65743aceed41ddc86b0f08caf5e4e980dd5f326eabc28e1ce681f62307a2f4b7e2c031765f8931c449e8178688fccfbddebf6456f475de2791e12f8e62c434cdafb0a84cf00b5490a36b4548e59bd7a9a40c4417cad2567e8ab2725dd0bb6e1f31072dbe354b78e4695ab14c41824da053256cf8a8c08e118f0d335bef1d324ab554dc01e4b00962f272e9c092fe1134f4153f7f41f4362306088e5e936642260e35bb9a8a7de6f7833a0ccc26ee9ee69d5c5c48909f1bc01028fe64a0fa55bafe8b02302f0f8c2182c254a9fd584ced26ae066c3c56fa68281489fe8cf0dfcf08cf6a93fa9a83d7186145fb5034485b99724f8a3603b54fca0ba520d87a2151b20f75931dffb2dd128b8d79fa20a8da46ea6b97e8d4c4f2ec12bb07b6ba8d781d3712af3ca4d0b1a9f37c57ccb2bbc4c53fc3324feba1c7745f59ea2c010932994243bd40268841bc44eec3e40bbf5ab275a02b1abe007bd399e0b8ce14b12a28ba0c77864c89e05cb5a78ac626ba25e9bb487c5956c8eb16f42b8423536878352dac51a1c92b25b5f583f3bbd52c50a235958cf45b0497cada21a28ca88424c69bf6a8f5e270e27599802c69fdbc0af25e8f70b6e5d66360f95499904e5516c39e7e3b1486bd57a55ba24e002028c164d3614aecb67d141a5bca59172acfa2819f860aded79af98e2107d4da7fea951f16803630644afff40b27e8911a23916f958d579f7780775556001a64a80c10b3547119c29823c8e6f6221ea62f2cb7e7a16bae65baf063169db7b4451bb545da46b5f77f1ac5df1ff72ef38898164d53b23bebcdcdb71d7d45e3fa3266cca0027f87c8e8eb6bfcd5213c01407ee2810ca8a1ac73a63fc5e345be45174753380949448e786161e1de2863e4c76f32fecbf5443b07c1e31c7c579d4fc94632797586f8f363baa792849914a98484f91255aec102e65ff4a92d5602ffef95c437179a5d2c483b724c403d0a1b84ca08f7fd3ec0a78abdbb7b05e1bf110308fdff06e141927fcbc11f340c27e9bc82fb043e1db113239202307473cf339cb291014307da46022786cfbe62bce9f8877ebfb67134312a92345d24a88082d63e0cdd4b7870203e874255b458fe5f3804f3ed0ec25670af750b50f60fb8acff97d707741ccf770928634dbf63d6dfc3925ff9efe8f32ed70ff71f2dc5907aba4cf35a661875ae222693057ddeb481c668c00656b714d9e0391bc1c8c9983f2c308b2f4e69c1620a6dc6c3cae2e3e1873ea13e31d1fa29cc15806580e534e1a48c319f6f28f00e3c817ccd451c82cc28bb95623f4d8adacb54eb9ad0fe7e0b52385281a4930c28c2a33d1b2b2a141aa219dd6adee1c59b172159e466d0071b092368d658315f9e65c6f6ae63c376adf3309f05ca3411848e14af0347c2e446915951dcb91f2ce9918e09d1cc1201cd1da2e7ebf6c3bca0fd8c40985e2519c892915de2ffee9b50d76e54051d7d21353230092ff24e0dbfbadaacf9f85d56c9873974b4382f424ce4007b93d01a37490155e716103de87055724886d57c68468f440c5ab75317b0c101260d3d3f70b790b4e8a10a3fdd846b40ad1731a868d48bd5dc0ffcaa7c3fd6c0a4ce9e085386670175d056a53161b7b35caf514e93f4e51cd54e6906356c390b8c93dffb07c7b0ca69ffdd83bb7e0d309ed6c788bcd3e3d42584af4e49e103614dba2b78cc23b35b2e8228d81d849c7ff133bab5c8adf8264479f86126e1090b897df48f9b3778171049ff92b44010f1cf03f02e32e196a14fa09717cbc829c7cd619bf03ef832d995f2848d0a265abce8bbc8fa2a2d0e430071e8feb302bccc320a05d15aa8a99e88e414f2212bb81466179e51194d1c5a01d9e274d85782d49cddbc46cacf3a14ca1072be7e9bd1799621c41e050e4f423078e025acca7e2d6603f63ef4d61a3e79518036f0e1b0c4521b6dfb4fedc938308baaa7f8833282e24cc0037ce1b27ccb0a411c3bc735a0907045a6665f80e92ad1a844fd47eb4004ee922f5c7a586c46524242603aec740fe292eaf876d47699158faec3c784d0267142d2b9a4dab63acd4ae53ff7caf051615eaaa09d4293b0233e3498667e97a475e6472d8e9cf44fdb26729a570994d223d1e3a424ed686accf7f895d9459b1d5a95d79fbebf67057248922c6751163a1dcf8471b41c49470c29f1f922a2f4d77eb6d00da4135cb688e9960eb28eac5ac380a376e04b86b623b7b4a2cb1a051f5851ef0489afce94bb94b7a8c3682c00b4882051e8b9aa6aa6bd60eb0fc43410255b19749c08d4091fb20dd8e11bcf3f810ab03e7ccc98341747201268c649bee58110048d3d2aeadf623ef2a1fd0c77c30bd7224a93562dbf6377fad34b0dcc60445373e1ec6b2c591b0a450ea32f78623bba2cdf0ae3b1fb4661d4e68a865e6e4869d9727b371a78e87d7439b3bcf7125c169d47ec8d13da26820b215ca0cafac680bde1e66288d7cd7b5585dcd062272350ef5ab500a3644d368e5aac7379843a174ddfdf46150f926dc60d0fd5eb3b3bd399012c1ba36ad0d9d5d77e88c601cf410e56f83cb43896929e6745a0f8e4a43a30e5501205119577328783ffba93e6ece4b52cdaebea94e26dc7c228703ad2cbcfdedd949bb20ca040b786c441791a45a7c986ca4bca556d2b9a42c273008aa13bcd3309db652f608582348187809e4adfeb4a24d5abd7aa26da0791be3b799c1f3c83586ece4d63a83149309296f959fba783ac627cc009ad18f050c88a30be908eac13d503fbed0f6d981f16de606ff194cd97ee6c43407c894bb5c2ba7ff3102533fe649df333b924c2d5d28bc0149723578881229239fd802a8fdf6a56f1bb53c09a91a913c499649601248acda2845d015c14af42f0c9971346139de39630c20c5a60f651f02f6926b29632b641790516582f9f0a3e42e626228feb4ed6abcdad4a614e3cd57da7fddea64ce6303e4e2e6f26bbe629549943f6d6081ddd6997b9008f0dd4e78b761249f84f5632e4800c4fb05921191a6ca173fd1f17c4af8f2171c00509a48c4f8d960906cb86e3aab7b0e79fef798ef5938c8d822dfec981f2dd3bc31375fdd17635204acfac307a3487d0451171c12ee1a209f103cb2b7c45fe2d358e9c5d2b2dd9d300271d3735bb2514ad3adf67699c2b3ef3f802d0d1a08aebd49361c0f9c5b134d1f214768bc6e1cc588fb0fa3aec1221bbc1bb3757378d82807861fef9c634f13d9e9b9c3891039de80cfae1fb7c30d78212860da6046beb7317bc7e760c7777eaaa046cc4f02ba68314657309c19a50367919a9f3e8ff1b54898cbec5cee96c4aea4aa90266193660efbae272cac2e61f18c5c3202f108aba1620d8c2f020182801ec0f2100a6d1b363a90ae07c5bead6fe25784bcefacfb1bd97b4b29654a32a5145804040483043fc46088142a539e9052c462600b059835f57a71bd18d1a8dee2eba3d6d0f057b6592fdfb24adb238558bf2d8ff555b64232f7d547ad61f92adbac6c7b96678568f9172c991048ac96ab86c52ae960cdd130002a180e31f0dfe20d228a6079ec8b68f9173a2d4ac074b27ccbf7fbf2a88d96502c58e6434bf622d34637e410d866399b65fd0a673839d69095ddc8b1feff2dab94838363e87a1c1c39164ece6549232d9fe2d135faedfa95ccc655ba715d2ba3d168a5aa5aaa2a23addc609a6be5b7ea476f55a51b3682aaef01c7cacacaca252556246f304d2565766394d9b8c134bb7384a3aaaa1cd670dc108bc5fa4d8b2c8bf4625996949794524a79c9eaa5bca4252d69b9110dabaaa48d1ba7972775295ed8cfc52e33d8a5c205529230062e84fc4197f7eeb7efef377f98b53710deedededf0fd2d58227537d6edb0fb750bf166e2ab4143448c023aa19c1f73a113899452d3fea6d550a0c92367f93479ec98fc6e79dcf26c0f931d22c49789155a86425608733770ce71b303c2fda658cb9895df65cbec76cae9fb47d59178c75c6cab8028cbbddb238898a6a94a7a86e43712c800349a517ed49ad1cb6ce3afdee22ac6cc850443c68f5a0343662fe58bc7fe07cbb73c101931dbb8c25eb0582b2596910e2396571942acbcb3947e20a9c0e8c6e829a03256328de44cbfa24026eb480e816de68335ecdaf877db87d90e1cd678d7adfb2ded60cdc9dfc132a2b1d241964fb125df6df22f292fab64bd351ad1b0ac2b46964cd9147fd3118db8325ebfc5b7de8aa5527c7959d688c675c9aa5ac96854d9c51ae3304dccb6fd6aab321c9d384cb32f7fa755551fe3ea5428d4cd0cf86e9b19925e2084f0dab0c931cad2cf4a961a4208e146194ab028f22aa6e10c3de841163d903b4d3451d44415192eb420d4d811420861b8ac86f35ad6b2afe557cb57825143fe84ee1d3e7efb30779e915873dfcc211cbdaedc5d811e1743767e6420a4040c51e2c3f70f5e315648603fa900c217865c1a7b982afe00bc80d980ff227c09af8fa51e3ee1e8537c1919653060f6acbdf752098c0a28ba98efdd0fb01212cc7df5a92bdb80cceb65bc7e4735e05bee610f9faefaf70c2be8a073f3491852c6a7c409cf7c34ccf782fc5021ca3f29ea7192c4542ee693113e148a69f4c97c0f3303017dd2139db0d4d2eb033be3abacebbdeff8de7b3038ab015fbe7ced17b9c03097caba2eab8a80cef71edfc1a8117fbed23eaed8e224307f17d2c77e349c0e3a6174432402b044f38a111d57b3190c2430fc7d78cf26b0ffde87150249673ee8c31762ffbd10485ce603ccd409f1b21b9480adab29a989df14f9f92f2ad8f614d08782a53fb820899423528278ca114454a4f474a11342f8e0eb52ab6624c69d2396c2583e225c1fbb034405888a8bf921fe7a1b403afc36808080522faa1c71717952a031dc3b1f2b78e74365dc0b1f6c53206c8642d127eae40a05fa1915d113344b539518d1641a819f627fcf7746c7369719e1791930eb5ea559c2850648b8ac80861c4c71f1a1a10916eff251a2e779bc873023b06d77b41d229e69b4c741c13a6a138f1c6942e707a55924148a1645222c45c0b6f5f16142476de24f1678f972478029400108a00cb880c6708f4365acc0b41808d335f879453a3a7a042d113bb6e7b5f7105589cd8c065093d4d882699d796665db02d17126f73196743e46f72265541bee1f6804531b87a94d4735997879f898bc58131857035b31777ffee4cb2934c4e0d758c75cd7b80373bd45357e8d8198ebef618ac5ecbbe7c5fa1151889aba00379ddd9d1dc2989b1467bd8d85f7ebf7e083dd3b58b18bb0eeeef6e8839dbf113c9722780dbf9d045a8c7d02191a3b48c2ee4b62b06661caebf7fc79630f0667c5139a05afdff3e73d22c21a28ee04a902617b15c8e0a4bdfbf573944382f9bbfb7bbe648808ca69c60b9b9e417b601a7ffd1b3ee0e4d880d6a80c853c652663587337acdd50044c8b790ce1ab1e84aff2e7f253ec19ac640c6b314eb6d40a42c055c95635974073c7f7b2205e670fbe4cb3de7d8cd556104d8bc1c931a34c4e4142cffb47cac50a6cd3283b7ac44822318dba3410ac7de6c90aa32fafc4101114b70c3720bcea7ae5724f340b53dc498c6bf1c518939c463b38275d181244db97f272a2a3b3fbf3c7cccccc9c392f6d3de0e4871042f8aff478b004999cc1e601c6ccccddbd8ebbd7b97b9db9db77e3c608a360294c3fd74419afdf830f767cbe6193f302d6dd1a83bf479cac32fb1abf63d5de0826bfebeece56659663ec67448c4d42475595a5094c1fbedd1ed696486683b525d2dddd4b647b4a3b647bf4692cec59225de5e4d8d7d26e8411427f858e3fc5d2aa5e96aa4a36aaea5996f5a41cc9fe37aae17fbd0d55eb2d592ac9973f83b5eef15e4544395e5766433f6e31b391a584307d9dfafd02a834aaaa663e58eb1dac45e9d922f05b1deccc331d2d59609b0add70291bdabdddfcbd0203e75cf78e94eeee0f2ecb88c693b0d71f6cd75d42b573ce41e8205ce71e3a084fb09d73fd9e7b19cafd7b7ed1f1ce38e33d84ce41f7dcbdbb25bd406cbe2ef55477f7dff6e7de95600183b96285a5ab990ac1367ac04197c33937849c910ec59a0ed3c4f8d6c1cf6199a3c3555b7e4508e1cbec848270468c314a1d7e8d68b8846e79749f21a584988eb6fab78ebe33f60c2847343cba8dd6d1513df7482fefbd6ee8ba1b967e3ad70dddebe79c73eea4c8589285c9b41ad8defd1cce98d5d10e1c64deb0c97d8a515530ff4d0b01434063b46bf7209c4b30d9f735d7fe5e5dd3b217d6629c2efd8aec4c54877aef596f35c26a4403be3895b9e4dceebe760f3b704d20fad7c8f5298e9594efd9893594945e954634aaca23af389837aad16f392a7ef5562c954e712687bb4bc8f022f5a8068a6922cc50a7c928ae20c3767087df33379bdcbf0c87693ce30c4786d305ecc47f61158f9460694c40ddb8682edac60005d85545bf7e0f3ed81da7a0a0dd06bafbf337c39d80e955554546de17b5e13190610996830b62da0a4642069827fd6bdae904a439130e4370bd03054cf5af61ac397f2a92cc28606e27059c4ea7d3e974caa1323910718299519bbe809a0a1db41196bc7ecf9f7764d40d4980de7bfe9ca4fa5aa3833953ec42843a383848a4229c85333f6e899d9d203b5660c1ee6ed3d06c9a768108c484859a8914371c61db62f8b6f4a66abd9560baccb25bf55e611a46627cf32746830ee183cfc130835876e102b6ad0fff4cf113a39d4e33393a6e8e080d3d39d24414a7d3e9743a9d7252806dec73f26102867f9e3869a593ca9c26f39ed486e7d545c0bc446facbdfbf5731ef1c032e1c764b28ac482e8803b53d5f8da69820f112245889060dbf69c7a86c0a498462f1f2208050535219a1b6a6e1a4ad3b4d7b409401930c371261b54806d0c04c4049e5c0d94d12ce4031b4a2d2d9d6117c768afdff32122283c7e18e9e1f9fa3d7fdefe8a520522fd5cc96cb896ab840035f15725abf480d6d4c4eeb4794096d80373bd6532c63dd107c5348e089122fde4891327575cd1a40993b9699aa6695a0e36b9cfc1010b28a6713e37f8c1ebf79c6558ae3bc4aef184212228afda2f16403cf5b5289e7714495acadc5c5cf80626d8b63f3fcc404344507c5a7b01c9a016211b50bbeb2bcbf16a27227cae3b7b374cf32858ea520936cb5db0b43909a67ff3e0e6e387250622e59584c89c7a55e2ccca162e3b65f08135a1671a850de123826f3be57818ae19bd62a3920e9d3662a808c771fc3d0e0ee78793e1e028451cac392f6055c90de1c877590faca11c6ac6cce30724574604d30a2d85bff7f62d33ef430821fcb74bc4ddfbb9f773efb7ebfebabd776494214bb1845dae08330df7ab7dc7be355a262f06afee41f74f4387f00d114159c93670c7e8842a314b3848151ee22176e278dc107ea2b1141e622a6ec70999ee9f778cc638d818c9a4e289a955d66750356d8c646e3ce42cf0214e986e7bd1b8a8b95002dbbc4811a6790232136ac33e38e889d188f0a1280a17334cd35595654130c5a9d48c869026bed48c979af152d97b103e1acf66a466c05497092ea6d1d601cbdc1f690c6c87e395b9414c8e23d5f6d703936377cb6bf481c9afdad563f2bbaede7d4c75314d1341f99906a51a8cd6905093c78fb9af3a73df470560a647f6c8ea3e715a263f1bb442eba465587b9d2c1729988cf5611f159c6620e9b5d3ebeab6ac6c3b36838197ebe2466dfcc6010e40296a4335401900821e2a93c3110c6fd4c67b0a3e2722448a14e190cc806ddbd333e4f4989999b50984da04055058292ee22286c251e8e400036c632226e22729286e681540b8430522e810bea1202127344e34cd3d01db5648a8899290a48bbb7b555553f66b20e9d40080ad061b38e0520310bbab23c6a7043a84ef46131a7aa2314dccced41dfc41414242397c3a9d4e454551a250494d1e3973377b895d0574081f7c7e5d2e2e2f2f303537dc198a351bae88d1b58fcfe3e0189203a55272a8ecce0a41ddbc6abc82890bd3fd86000dc374bf2da0a43516180d816d27d4699f3323703398579baaa66da3a0408a2387ce0e95713cd4e478a2b041a6734d9ac09c50674e601bbb2017238675cf885b8e20c2c47d69bd04846387b183bebf0efaee3e04feaea43073615363320bd853e1832bccedc47cc4d21f9410d242480b283f509cdbe0101fbb0b86e3cb8be68af5dc624fe7fe456fe791ff65f3b930f02b1f5896aab2bad730ccddbcce9fdd7719863575cead7bfbbc9d332bb373ccbcda0e33332bb36bc15a67d700d8c63666deb25619552765dde3f3d8afbb338deedac58e0d9f7784cfabe817d67bafa5e9570783edebcd5a6520f4ded8cfb5eb6fa7704af9fb98cbac9bb461af99661f3412218470480adae7d160058e073310f99122b60842c2c303173f4158010f5b502942944491dcc1922e9a54d1c5130c3006aca74ed10591c9075d3cd186740125092225446a300322b438a245920dc8dce732401865f7b231b8549300d574360603d4c4598c262f99cca2433cd28177e7f2af940256aa02ebe74b4d2f231c56a24861e90f48489912450b213f54621005c67b0d3a8194a94127e862eacb6a6c357ddae8500485a5038c11f74cddfe0fcb296408172ec32a4c09218410c22020844f4addc27237fb9dafbbba2eb391f79c70c2df69d7775f73777f1d3358da74bc533f3fa90cbfe7ce637c8d84b5c8708d85e53a87cab876ce0531e9288e080b735e776b672eb2d6ceb96f6e02e327aa6ae0fbdf85fff103e27929e60a6cfbf8de1be2ac192f01ebdfddcdfcbb5b477392d7ef515fa639b42efc8659103d3d6329b8a7d52c805c6825444586869c14a181326099b0c412459ae05004b6ad90d0154588526af386869ca4b630379da2331dd217b06d8584ae48a9cd9b4452284263ad3252c2779aec1f137a0b163688bbc2ce921aba055878a719f705f7f71c421dc23f7952852a40010a4c60021290d080b9690dd0344dd3340568cd05d4a4b50d3b9a8f108478788444c1644811137b647f36898e0ecd622a16a652406b58244ba653844da11bd514217c9d18e1f2c408e52e0f0fcff22c4f559d2047336c11e5d3622c2dc6d262acaad262dc568eab7e107655599f62ab6a29a5bcaeb6b690a51baf2606520ca5d186aaaad0ec1b737fc75f2e8b18049ea1a5a8c1080a8542a152286772989017f02e84259e6ced0e0d64fab315a55ef2922069a84b357eec355447d5b875db31f78a7db590114c6af3def3e7fd1bea0028140a8532c0d2686035f7a80ca8cc4a91496db897f939e66d752b9b951cd0c95b6b8f394d406de09394308592b4484280d668cee4da5d8c1849d329801c61f2db080a0a7a95d912065e7a6ce0c6f0a236ec2f4a524db57d8ff1e5a53be3f1638bb83406662f31103f5615b73f8f511b864668fbb2022f6ada1ca4c9e3c7644c4dcbeb8ef0d81d82110f0d63bf0dc86c87fb63eef36a0c765e6776eb56de4329af070584fe5a922c55cdfa8dd1923700f568c4157b0a96b8e0744ab91a949af8af203e3ee48e838367480e873dc43804db3468eaa032ff026cd321140e1dd446a5081eeae66d2378dda81bd40deac6279883a8b48d9b0731ab118004100053160000180c060483e180703c502451f914800f638a3e745234140844418e03298ae228c618420030041963084146a1a14107e32dc3d1252b309dd7fa2bc0260079069572cfdd25f0912778bff438acfd9fc4976d00892659e065144eb16a5cc5703f884abc36ec39236ac9c68d22f6e8dfa9c3a2e0689183a8b9b2e418026f1413a23a74a79d2f4fc72542a96905712f3deb2e4531df19e7c0e10e287f6d526f88756e52b727ec51c9fede104e2c3f650d0d090a14c493773849f2a8d8e49a7722596df977ff473ddd6bf929325352d82d02c772d2f10a1ba7c21bc6f6669c807882078fcaa7754a09af00aca0de2b5c291d08c12261090a0f716772ee185e9a3f5fd7820abd449c3d71a03acfbabca4a9aa8ead156be86d6c98de91fbfda227167382dec6ba64cac7a1273009f2c48c16793ba387921bf88293cc582e19e2e058fbd918441e4d030758968975a6bc2a24ca886e9161b84f4f619fe4cba73e775f2985728c8d7cb80f84baef87cc221d1fdffdc0e8b36261c39ef596fb889522843127c9f02c5bf723e22d9c77103d53a8b3b467cbcd70d441bd9043c416a5b9894e80a28c580a7aad37a643bc85460e67af37ace7611ce4517666e2d1737b287fefbf53b37ddab7920e087a6ada1b2dc7a9222179c8fb465cd2c27124757e6476fb7317b7b070896f2b2a5725683da7ebd52634c1d0d732d25de98b488423cb0a07be5e440b8c3f7173c48ab255a8d4f08920620a0b0262ae3858d66f92bfc215a462f4ab9ec066a74c32c4411c77cbf2f2af5bd97ca2a0b8a4f34ace709d8862ad4f5c15a5f074acb7bc720397ea0e50f9b45f845b7fca5925fe750af5e3c4e039c9be96becf7affca4afd7315cb64d276a998bf5f7aefb6d64f70c4e0497604780aefba6bb9580ed4470635a02ce349bf79a2c87fbf87fb17def7793ec92667a06c322b5a46ccf986e89e52c221293b95c33d2dcf5cc8f9fea810e38a4c257d615f359989c57ed79212a9e20f04fd1e045dcb9619677c2353b809c48787f9c1f4c119a01b0aad3a8006a23623b173de268a308dd1f286643599a366c277fafcc6b304e80fd667c9474b61fd6c82a1d998cf082bb8c6dcf29da4957f3286bcb93f6e6d497669a4a4084e54222410d0d1c543030fd0e326c4c6903bbe3d7731db407a623a41a3d7f5b6943a2bb6fe63d2621e6eafc9cbd408e214fada0c4f7c6b7003b9e22c9ac29d851bda1be502af396da6567eef582742cbf80bdc1756e1974d332d2a90507934be2ddb9916c97c88fae15befd0b1acaa06cf0ae97b65ec5104b13e2b729a5e9c117c6503c78c55cdf8e2fb3bc1ae62becfed8a0aa76989c8e6e84e9bd4a66d308826a604d0a170d1dc5d37e88f9a1937630bed3ffd4ca3899990f005511c1d3999bf833e5ad7136548c3977e96c1f9fa6a22fb7f72e12fbbf9534f8bf7960de7e0b86081a2dc883200ef0046000d7b5424c4bdc443b374118dda2a3008007b99b625e52eda4b3d2180355a9591ca6dae395db38bd5e66ee8ed179ce12c97a46bbb4aff9a361f481487b12943c8e7bb34c577a180145288b34353dc659e999fe6142f6002ea0437a472dcc4d053ade531d56f2303a59c22a6ac0f213e5cc2bdfe40bda80bb0f41c4d73525fb8451d0c2506db1cc6a1c0948b986c243423d52ad65169166cafb029e770de7a25c6100aa75cbd122a5a29d5d2b23f92104ab1bc0d8569282a7dcbffeb66251c490c005c6f1c40ffcf6771f2230b80abf8468a92bcd8da023a0fc26269c3d574e66c9943d7c28614119e4e0a7b71b54a4a2b486bbfa9b8e6c996fb8cec6248db170f020a560765ae9df90214c5b1623cb33588f87c01effd151e26bf3b45650d0e2b18b0b1cd23b04842df3e687fa28de7aaca8436702c7a6e166569adf90da6e9aa1c0fd0c65f0b64812a2d1dc6a63924f3d3e2d13d648d97380ea56509c53526b002511e933543b46cb09463ad4bc5c3e4b121bf622f015742bf76835417224e5ebfc63bceb42200f80579eec1fe471a30905bdcad33ec7e36a33b3436a2617246af64f9543a422f53369a5a6e75eacf6b57307d8410b81e239cb9c130d45d143500ece27e0253baaf3f1095eb97acda7891c5755725c9452e5eaaec3e5fc740e707854b62185f74d26b756a599c8d82bb8126b28f0f4943d59a1c5d415d5597bc2cc0f643055500b84a455a768da16ee34a57696cfed198c89b6c509e0e2635c585229404e76f7147c5b6cc73d03a083a78e2c7ee96fff9aba14e925e458618540e171d3c929a094f3c396483ff9632e1c5ad8bfbb611097a85ea23fdfc13214ef0ee3dd06b67d805306a588029dd59873a9a84882ad100b799bbff483b44a54cf4af18961fe9422b20d9a2bfb20955115995842279365c97d77b145dc2d39b4431b753ab06bd573bad8a76b55d65a779238ae2c748150473a9bf3ce516a3283b03092d42f17d0af4109d54cbb324fe109a8998e40bc4341bb7fb2724ed875bfc04aa78cdf12fad6e0d73bb8370f3cd5dea055906a1472cf2df66e9f801ca39d174db1de9da875f416b7b1951d55a7d0a4681efbd7843f769ca8a55a7535f6dcb1df52df8ad8e82773acf407d7228d28b92851c60e2df939a7e5143b1a3eb0e8048ae7cc8a415bc276c6996d73f790f9f08ff254c4b7403481d0902e40acb349ec5f48407b05d5768d9fbfa0e5cbb88be68dbdc59740bf05ceb10d6785981635a8a871956b99dd85d25bbd2e8f5e5b3c44a83e1edc5b9efbfcb9cf902dac53f413e8a43b0942f521e2d6ab2ba237705f6bbd5d8d797e3f788b6d03d87360c5abaa967e74ab22d93fd226f5ca5b9a19875511abc0d883fdb7f060e520ede22391ba4e86ee181bcc5a1347a63ba29968ffcd16cd8c972382dcec61cc72083962a8ce45efad0611d940195a9b97e0b8a162d6e601507107a40efd12b09f455ff7953a34a57137a9cb7e7d95b8dac2068197c3786d8a8a11ba05213fe306bc99c070670be8a0926ef2a4dcebe3d09ac76ac206317c7c4acf6547dd51313e7f979092027c7951daaf7b24298a116736cfc1a2bcf90a91682571c325595548ae8fda47a62d8eea2670e7dd1a5d91c7abb4b299436ef807641cf19572ecc6fa4662979e1bd145efec0c26e39678c4d6984f45e143130c0071ae448a36758acbcf521560913c2600012135c879bb8dfd75afe6f568c571899c22744fdff38d2fcf8d72b90a691be4dcd0dc71d32953a37d0ae133ec1607304c42cc103e2092858d5301cdc7bdcc2c3d4090109071fa09e20142cd062af13d09f1da11e77a0711b97d0df886c21df7d4f0f23f5faf5021eeaf942bbb853d487048766646b481242ebc5e74d5ed648985208dc9c6a61943e7962a625c2d705fabbf840893302d6346f729c087c7f9d34ff97cb9ae3db3b49a215be9951a728558fcc2564dba3cece45a34799c181b5e2c6f7b03f98984262853fcc2269c93857a68ddd8a01c8a065737585202aa172cbaedd78228cd8f54d2fbcd24774d906e64fd8530170dbff84127f5ffec779c7e2a6a57dac009c357b00c9d63a8cc0c30ea20b6dd2b8916eae0f07db64199a8eecf0cdaa0113a8412866cb1336877f0c3d8a8800487888e03e0b0190ab936dae58cbbf610e0ab9e835963fc570b902d867781327c76d5d876268ff6642042c59415be738c04c48f1d46aeafcb171b9a898ea95bb7d2a142e4816ecfb96e5e67eae12f7965312111560fecd486b761bcb42054664986ac5a6781ce7f85070a611eea49fcda12684238fc73f90dc2d9c46ab11fddd48fd7e86d3d8f119ac2936bf1ceeb6b1424bbba8f0ebb8d1dcd02442fb92aaafd9eb9c028526a29d5fd1d34b5ed9c150cf915b81de6034343ff5e5ec45f1cb8cb82e2a0085772a728112c88b88f98caca38228e0479d8d2c4431a44dd7a4b43f513b037ed8a1167124230bb62434bf47786cad4b5ca2809ffd7af6a6c700b042d3c1d74e0590193f4197f65fb37885d86ff8a710cbc451f3cefb04bb7e13a538db8cf9cea37423d8ac44e016d8cf84c44b9f63f01b170b0a8abd869d824a399c46240043293b24c567b36b5a1df40a3119d4d17b5b2f21c70fbae7aa256159a113e1813f0cd272c8fa1edc833da0ab3910523c2577b1dfaff6cc93c5ac8f5ac33ef680c14786c6fd600f2dc180b9e96f63c896e35e43e13a60b05224f8cf11fed8d85b859e75d0341235f73e60b8d385efe0db1ca614babf3fdd073b7ac3eb03e5e8cf34db305188031b1899e9f30148f444074691256d7fdfcde7e7251e08697175d25b1a2cfc6a69e63eaa08a3bd3e925513b10c766c502eb616e5e2a34545682e7f4b12caf7d6a41c81197553d3185bf0fdaf187ca54fe7cc1af5c6463a41ca786c4d60e76a2cf71294fb0ecdb9da3e2765f679e3157bc48c7b684116d5e76a13a0474db2bae834e93e1408944a3377a0ee3e48e066e1a4b6d164a1f0dad493a8bcda73c8832d256375f7c8bbc3beecc3523ab3ff53c4b59bd5d7aa76a2d617df64d87743d5601cf306f1edcf67a742b2462e652fdecd1fadd5ff5a188847c090cedbe91b07f11be7a0c5ead55724fde695667b2748da1dd4b4ccc16f3ac9d1d12e238451e02a6e568299bbc482a695d7907131f1ff76e69876570e9fbc590547d0a578af61018046788c64f6a36c1c683f55c665e5c597f3f3c04149894547d691cd93a6fd3ead19c602d385a55ae653847f812c071ca623b58cb4aeef98861a58432e499e991c33d61004b102443283018bb8ff7420a1e0a0bfd955e79fdaf57c438b6687a7c382a93a16f78147fb2087a20066d0cc3645e4a6c0a7b6fc3428af50826441e7bccbb84c92567935caca940479dbd78b569d9dae0d693d0c83ae597223bfe23024292c36d1e3bd9d755fb4d7d59db78e75d9ab5c06af0de5582791b223606790bbaa6169cf38fa2caa82a1e46d549938987a9ec3de7df22b693c620f3b885c37d2a604e78dc26796016ef5b81a3274cddff09cdf898d84f9e1e990026ffce732c37cb35fcbf8f8272c3613b9a2b7312caa9b7556e16bd7e8ca811c85d8d59d3e358c1b6f44fa9449687a01a8da8878ccd2b73697f225667ecbbfcd166958d2185041ce9b03b0908070f44e9827440c7aa87653f354fbdd4589ff4ddcb27cffe4a0755aa4b1fd51602dfb3c842dc1c0ab78b748c7afd08d1d5418d874921bd0da8b447839aee22371fa4c2ca4a182ad249704d86db449ed91422fda4311018c7da08645f46d7ed8eb207349a1cedf2e4bed7449c5cf5615c16b887f186aa44e69e0b52cace5e8948b190b19ddab7a7fa22a7778589d3e7e1964ad2fbc142063e0adde6750c238a40d39bd93e3c8087822c869c4cd8e12c6d075ed958fc7e06a0172d99bc4328fcc952c60069e14c70427a91c43d8bd5c650cc874836224f6157563aa8af9ab1e1536d1e6967a2d8409959ff1e03b6ec44f46ae70b6d48d1ce93c1b3d38e1466300a3ec8980e9551ecfc90299124b957dd5062cdf648786c70d8c6596e8b57d287eaa87aaa1116e406df1708a2a03396be27ef79338e1498a8e82c747b099b2a791827cf97bb4b70ee24d612db8f6862a8bdc9553d831114be17ba9a1223d6f919e952174802a755753337a7a7ad63e7a2d9e3a5d723a2d530bb703838b20567f34101fd1c40ba07e60ed212f1bb6b0c89f963bb1133d59dfac88f2eab5c7fc146f51d321f830de09760ed9d8afa6c4e50bc02bc560f6d2f026065cc14107471d3b40b4ca80b76a9697266e6a58b239236ee06ecc25cb4bc5e353bee892da74527310810cc6eb7ac3f1f40c3ed7cba8ddf8e270ed0c53966b98797d06c6e75d7b55014c315617ae4560af12e639aebf60232b7f852ec9d479010b3f328affea318075f5731d1f68f4066060977428b1cc935a8a9681b4b144c394f8719e80db9d01f23a18952387d513181ad082e87264ed2f6ed18a4dc1533d0a35997712718bedb972b873eee40a2a2df8de6739aa9e322bdbc4fb71601e03a5a5c05da08f179dd5c2a1eb3076383d052ba2790b19d992f1001eaa70f61f17adf456b6bccdf0aae90dabb80cb0bf303e5fc1ee1fd129f74198490dd877e7eebf9a2df0e6032432bd0699f0229803debc0da4e58ada9f4979551a51f5a9cac181db016d4dcf17090910000abfb5d7c89f35f803f2af27259ea6f8c3e8c2849e2332697a89d5020f46ef07cd770bf1540fea48ab0fd336905e9c347d3379fe41f248a388bc004a050d072f381513f64f7843802f865ff3fd9805a10e93685d59403122f68d2bd8871d5157867e9b7635842690f6532d70b4cbb22b930548640b9cdccbd0ff1e6928f70d2305472d6a13cd4513f6b46745ff86f54318eef2eb8a023ae06211e0f6923df53f7c36574664c1987ed1df5c5adc085e3e110ce91cb791d1fcfd9903b38d3d6615d3e90e75ef81b27de481e9b454dbc9b4994da8b4ce704616499645e019c21d90d0a3daa60760832019816978fda118ba67f67ea0f930fda00e275eef1c1b17d7973726cecd9b75308f9631508f0ec34f606cb92a5d1ec3dc747e44b22fa88827059ae67f32d7beb422ed85948e4bcfa0b9ae1b7ed355a3792101e67619c9f2cba9c440d7f1c51adf1c21acbd7c46982c09467c4463fad0175f16ad4b1130b9ab20671d412274338313d0cba4caf1202674d2144a9501991d4585c8ac48d00cbc0828bfb15149c7311e1210949f74beb65e81a49403401d6a669621b52ce362a8911f04a60ec415980b78fcfebff641e093465091403aa4206bdfc7767b97cc0c8e6da82e97226ffd6fd40644aefec499a666268996d2ee7f27f50c066d97d2118d118b5f754c83632a791765e500002121ba23234c49e17310ad04be4592f31221ea5faf4ccb80af8c14befea77e4d3e1f1e056111a19ba29bbf688736fcfd4a1f04cecbb170dcf51c542ff6a3df4610e173c2d79d0708f976a75f7e1e6d8476294a62af717c92afe490d6221f5d1cdff520681516f47161480fe89c043257c60ac8635a3c57db15fba1d3cd8d71b5af4b121fa3c30e27fd2562d953e22343c816317e90fcb18784bebf259a8a3705fb249c4a74f0e178190bbe24cd352775911b53f09467fbdb3de80c9424a1f73b15e82895886920ee8147b3d1498a4a123d3191e680cc0aaf7a3295bbc64eda3f32fc3aa08764c2492ec5d59ebf4a002b2f2f1d42a6308a00fda7fef23b5c892317b24b00abd135a58ce5701c5d868642238cf32969f264e28803ac71f5483212c94b66bb0b58a719a181025d17f1cc381b9cd7c3c877d236ab68be2e5ca94cb8a3847b7da3a55af18b0dd460742730c790bc19130f33f6ea11019865b1ec1937ebb98378a26a4085c04b00b21d1a62b6b8e116242c5c303bd0e5971eece4e54230ba9ca99cee962b2e89319da81566eaf50dde148327073f93e9a275a665e938342bfa3843675048d0ef8183ab4bc015775e11722490a02c399a29ba427133a25b618f164b496807784f5d8a5f6ac49349d467320e740c9eb6ea08604874f07b906293e8a71a855298917b7060a845e40401ab40ed74082a31a97080605ae7626e256d4e8ea3bf68987c2f0a7b5c653e6431261a0b3266307673cc330c8fc84441abca6d1a95707d621a2aaaee762b0e01cfc89bbad795fc71b5bfef138ed619cffef71b9d05e2c8d394954c5c21a07be021318035bd3f2dd890eedcdff3d024740c9441a4c228651ee48144a1610886d52f07d52f80046620d17dbf58830fa30d1e086cbdde0e8798379629693a9b107643fd51430f5c20e85f5f16084b0a5f5971dcdabe0696c0fe41e1de64eab245d2a2ccb4811b2b2a5de54b57357a9a80a6bca9a79e1193dd1a9a6098ecf8162ea7b2c26a21484f08d32daa41b3b1a1d9826e575bafb7eb5d74b28dd46ab98f57d2d3712fb55a5bd55b955b518b0fc68ac7b9878e61a3c69c629916a6e6aa084e4fc17d47f48e3f843c7e8010eb6c8a88d184400f1bc4198322c1aaf55863fddb0021d3b3c0cf4fee7b2c685617f49e64884b3014e836c0e02a6c59516affa8446bb119c87ffff6b2aaa2fe3cde9a54204eacc1e38d49f3dfd656dda91b5cafe586f5655de7e4658625b600c1dac54176c7b10e81a2dd75f2a25c9743ec394c8347e10a225c2e0e5c0c26a6015e6aef8bb078fa888329d40b450766d639c041d3fddc1048f99e847b0031f09ff9acd3d97455760c55cee5709ad1a40339f879af2509cd68290c6809d3d0182c4cbbd8f611a40eb62ec1c72557edefdcecdda00e3134b5b8e41fec0a003dd2c3506b4bb2dbcf588398ee49040bab7460f1bf2af4cd0d061dc7126e54988505e64f596be25fc828a0c9f1b62cb4f1c5973f0cf9ed439a4dbe68414db052caeefe64008b2ea722b080ff3d0fad241241999f9468ac3bacc28c2776644250268b7c3a4b3906b4b3350a8d141023797459f6c02ede1b74b98db06bf44e30822aca84daebd80d82c32291cce91ac304a80b4869dfebb7151493169da0c419e2d0edab5813aa2febddd1dcdde643e97ebc2ae881074762fceb1dd4ccf9a57a03ac831397509fb913f02663d6ed03c2e03a41aa387fbbc62ef16d214744bf9d96df55f78392a4d25ccc34c0aaa7ca7c4cf3dd47f508391df3e839db57f7b93838c3dddeb73e8e75cdb8898178c868e325028a86eeb271394e8ca2e9b12fb2f172405d6322ab678a404b091aa52cd18978cd32230fa2e4e6f04ebc34faf5bab8f35e4d11d6ebb2640094da629fae19de32868d75ed825f8864108873194c39ebdf25417c4020d0f721ecc4ef525f3d36e4dd63d62a0b878a91a1662315b440f3b1c0d04140012744991c2f3585dd68bf73bfdc804e394ce17c9801074e8b270c616d0160dfb2e0e6435d3020f45de64f1fd55e1b93dd17ba2e6e4a2592351b44598d732114a764c45c895546af728cc919bc4013ec5dc48094aebc1b477d396c4356aa4cd233dc3dcd322e69295e6e246af8bdbf50b410d86136e0e38c5d2ca1b887f07a99d610e5f6b8c4ce27793c1358ab34ddcf63f2b64b65c6ed06207810576fb591543600107e80e49ca619c14936c4c029fa50a4cc2034bc398da83ab6968452f451c833f45b3558207004dc060e77e437e06a17f2c93d4405316ec26c3066b6c828abeeb80ca85c52c88b8ceeb1012513dd2e298c5625a4edabbd1e8b2b495337085df65eb7f05d12e1d03e1234721541f85546141d233326dafdb85a93ab615864e96c46042f700e6b4e43bc65d454b7798df39359e2681b8b6fcdb223d2723449626f106fb9187e043e9aaea82be91247708ef1111f31a46db2788234ffe29800553e2d3a7e73ec9fdf41e6e95ed35c97a4e28513baadb0ddd952cddfa0b91002c46a7a82d802dc73f66522ad3639f886d7aa52f32bac2f1564b819049fd87d7960cba44dcbaa5453c9144df9d684a708056a596309922cae60b8c123b88fd951b0859816791cc1f7232d01ae4fd5d3ab3bc7e15dab9224dc799c934e89e06d231f5bc475a685d4053a9f3991434416fc83b103490cf4e1d882e64fccb6d4aa3d4d19cee4f91a11002ef25288c2c0085cf053b4e7a81fbd1df14ae177f66382c271f78c0f605635d6b53569ffe09b339fa90e3ba63c08a25eafa97f5c554f65373ad254c359e79ae98404b5570793d20f9a92a323aed1aab908769de5c0dfeb13a808b4a58b832f4c6e2e9d0c890e8aad48e063c1b82e04c83e67e34f67bbe963404148bdd8cf6cc0797ae998c84068f3bb3dfbc592af6268bb39cda9b9bc55513933ef62ea18d2b69b4bb5f9ae515f718a77fed7363393fa1097a126847bbc556df26932a3797968dfd63bc928f7c73575c72fcfcf38e70a93e80f9823096bf7b920c2e2cf69be33486e7c90f78c01a75a0770ff0ea613452340755cd0c83696f19beefa7988f5a0772eca56b3db6b450d829854867462465d88a5b278bdc5b75a2dab07cf2a47b4bfff10bce98576ba64bc72cdc12fbd7cf0e675ff41d002582fdcc5ff80d4bc476130ac8fab9729e746a2c9a23782bb57ee515d01f4036042df31593935ede2305d54eb2bfa4cb64aa752a952f60aca5fc8d4fac98175cd697206c7e0961674fcb1031c28b2c9ae9b2ba8a8e861a009cac598eca6a72c26541f219f2a074cc6b88040008d5234f704bb44fa1a28f8b1a4e0aba961da23eb93ec452e8b1ce6d450c01de456eacbedf8845c0ef1ec507aa684d572a6c6d510fa3569066482f40cbccb6d0046227e45264a74139d3a31106d13764b6562f82fe0673351facb4ffffbdfcfc85a30b99b3f2ceb38a6858a7d5006283ce8d2f9526f7eb942a8c886736df899e7c8c6388c0600b4479ff9751013380d0c640ef9445c2e8a9c8d86e75f4ab0a045b12cdaf1fd0d81171dc4396f2b88149f1d6a714e58857f04b954be2d48cd198cf244150c8431abfa02a551d16db246199ac36327142dfb42e57dd990aead33bf41764b8161274801148d3fd506baed5aa18a3c39ca078d08f8b1823c1e0ebf83af0c5a5697407857d580e32573f717dc8a0325c46a8782e7f10af319c230c422a5c6d4f23bcc18e016b09fe90e1a0ee05072fa07e799abc40b7ee9ebc2ce6d5d835b05c7e17db5c1c813d05ef2d3b9aca1d3388293edc512f0624b95a8ca8a15012abf54b67348462b4efa5ddfb56491804236ead4d9d2ec0c1dfbe85ba3a47ed59b12c675e19308b515132b2601bd62b2a10fdba37550f9451e2bf5c01bcf6e45fb66439bd2239f2773c38739eb5c119d26c9a38d6c7475726dc8f6db7acb1bb48d5cd055a7bbf87b22d3bbaab0937d306a408b289155f748d63683d464341118270e86b631c2cc6448e34abf3904d6b27104f80e8762c398e39db084559ae88c3309a52a999bc40be1c09b8ed0c9bc027fd753935ed3cfe4875ec0a2354aee2fab065e1dc10b9f428621cec5c23e4b9058701c4efcb1d81fa68f5a6cf5b87415cd1fea63d5e8b74bcbbc94593373e9aa8552754554da69cce451d28770459d622b7eaa0e057f5a5b2174ce039c40fde8eedee81339981f5116e4b27de56d4d42d1235897cce28375aa95508b14cccaad574859e1084d0b9d581a637c14aa8b132a66c03d1eadac01a2fae834b083c7f606d911c5fd496059bcab9ff82c12da259eaa2d115f395c2a91f91ed154e22e4aa1a8e05e4527c4a19943cfd1c42accd41525586a01fff8e66fa06c876b2e80be2c22f1aa9c2a57860e18f78704999a83257e5686b197feb97f9ebe47494586c34ff91b587b68ce05700b9b72b94f28f1522f0f08cd2a1be22a83fc826daaa20552baf3c9a9abfa88d7313d5c99767482814d9146cc431edaf7849c12ac1a6f7828737acded992383d8622847980e30d116b00e70eec3043c839259601e7378fab8cd9ccda075ba245fb6a1f0b62cbfa3a69b8c1ae753c677f517c8e52aa5e8f861e54264a2c43e524a8e36d2fbbb8b949adcc2ced9dcfd09e3d82f3fd703acc4077cb8292f5ab61cd830c6d43be9855461ab7e2da48f233d53df31c37a058045c76ea4c7a2046f572f54873bcd2db17e78bd488e4af2002949bd5f3969f7de5f7053dc844a28702de30b8b104411c2f8d6bd527ab3321efe83947ef3318732bcfcc6a74e43800240fb0f028e53de04540b80b7ec1bf15605707140b0c57eafc8efaff8182bffefa5627551462394cd8ff91c3f3e1e87fcedd3cb504cc49a93cded15f9e2eb0f0c27732a2cf846c6cc77da5b3383d3c2a50d9d87b4ed94472ea7b55ba2f2ec0fac5b98fba936aab4bea63e791b40bb270775d8497c078d046d3069d28dbda02aa3e6ae0663e83bd102dceb4464e80d0b8d4bd19f33568075f3d508c1bf060ef9bb8a4caa0d15aa6ea98a120a1b6a6ebf599ab1b74d526edf7c9e00851465f26843bac5df8a0a3f604aa6cca8b088ff5859141a66dc6c506be24347086309fb9f161cc2b035475a3424c0ef3eb0f70bce43c280698aeb960f58fc608e662f4cc046af85219b88f460786c5b78f97aa0fc8f3e34537ebf86a2c0b4f5618d042b5c99c428068c3e79a9c7997d35fbd35c0f93439e48f022875a432755d5cec569a6904097a1a99fc1348413bba428fd672553a40c595da1e721838e0a547b6ab1a1f1a08e8d4265f2f9273258f60379ac15bd15077b8656239310758b422ac3667d1b14f4c91c88f6075e742a98b5ce08d1ce57e2643333ce97e42a76083f8f2cbdc484a152ddf43f9b26368cea0cc58987dbc690527a80ea8cce61cd8db7774a6563a3cc92983ad3564bb0e83be9b52bdbd32aef41193da50cf1e1a4d755997a5ede7288e4d48f43876080bedd047309cf83d2f651054a42719f599343978dd444bc6d0f3ec99f30ea4c0cd2de5e2f642784efe7aa4d595e3d6e3c528d2c3cb1f184132500605e51c9e2642a5db48e116f650905e49ed81373d1e2ed86726604938149e5f33a7293a013e9bd0d43d29f594ca0536166e33987dc61db4e0917329cc93c2833391f398e6a4c0383fe4a1fa1f709d9176bdb92536ab646d751e59dd02db2d7a9e0108409e7170277d5f858dac385bd40bce6e0886a7b4b33bf4924bc1f2423e3cc5698ef272edaa02bca8cb9000e4120fe35b43e7e9c801c0cc5da4a93013dcfb665d05f5a954266e20a9705b8799582f8f8cbf0291e681740caadb6cbcdae5eddd814e49c080bce664cab1d8ba040713f0d3849e898d7e36ac411919fb56018b80d403dfe62d603ad6745769b60d0b6046e9d1b4a9c896ece6ce644c2f6b922273abf60e825b639a8034238450f93f822f4d96630af25b68db1b8be58a8316f2313c5f09c6ac8ececbfff4081a9a938da4e1efe57ab3cfe69115911afa49897f0eff48f450c962168644b1ce7796058c260570ba229b8df9f7e85286cf1d38d5ce78b4a9f82d4b448a0124b1dec0f47e0473a5d8d07d9c13f42734ffcd29c450538c8f6c640d56919fc7f230fdbc387130c9fc8eaf02ed16cb74cf7a4eb3816371ab3192f6d82ce8472e42653d22a5fae0ab296d935e647c5a1c5d9909ec6528cf83cf7a4d00b0f74b0e4355900ed127e64baf6836cb8c18985a0bb48b28e2cddd0c83c05ecf088f45fdc814fd915e9207075dd8303281660411f70733f50a661d57d2dfd5a2a296313ba43c7571ee5c46e464826ccbe1a6d8726b67d0a4e56fc2ee76bf0b85c36dff559c1ecf33d4a32b97f81ac0fb3a1ef5fc8db98723f4cc5d2aff315ce2e0a4010112fb97e9b527f41bd67b2a66d43dd3586207f1d654948151cd44ca321e756c5cba9d44b9e8f724344c4e94814d82314394c28733b4877013d1e6cc237e4d74101c84f49ba9a7d00dcdb668b3c3b507e900887d9115aa991fc797609217b6a3de8f7bcb078659a668ec21166c538fe894eb143b3df42cafec0b8a583182ba2c8ae314afcdff3b215ccc60a21dc18b730d59d0d47ec0245c60a65e5440acc76c0dafc93ae373f8b6f56274e079d995ea79ab561fb4c15a5c307b19a617510b3c20c215e3da04ae61b9036685c3b105026d02ab1278da66627f11990970f347d22e47170894f02c2769f5aa0d5f6db46cf3ee996c68ede1dea816bf49158eb9a3a68ea6f613d4c4edd46a9b295637a4c6b2c8c3fe690d61090ad3aa6ea10321e6b559d6a453f716bf19860ca76fe01e8d8e794643beaf0bf322a0771494a2645a95016531daaf5c7a21b4db01c558749e3e159d952b02652d5f81a59fccaf8ae3f280e727c965e1d3fe67ee427e1fe64f1aab09032d7a09f5aaee06c2d4a34a897c1134d9a220e8e0c9b7fb935ca4401aeb6942732c99b8401ff2aca2398249c590f0cfa0d5639e22ecf1aacee33491a5a4e2d78882659dc06d3f0186b09ff8f4bbec1b6e161d164c9a8e3cafa1ed2278a2c8b283a85988884acd6484b618395181c9ba38abe4f7c57aef001fff311fb36504a8b11e9ae46272f810111dcbb5a62478691b84eb9ecdbb514a69646b4ed801f3e8b78e913b89de9cd902244d9cddf12244db728227795977a1814d065e8752d885edf1b4d65d427ac0550bba5417281eb56c05753720dc997c56a08c44a1332f4b46569e13c0568187d8cd7ac97a158c5720167da760119e015bdf1db7d893e0e4a5e40bf0254db2ec91155413d9cfd912a0242e6d27bb974a01444d99436296944c4dee492cbc1a086f250db52ccd47cf478b501332138f086fd367ba991573affd6bc0382975ff0bd10eeba529c6d9dfc12d987ebc49b7954053fecd8d1725f77d75704fcb258c836faf56b7d1a04702903b5a0a7c4c217feaa9b2dcdda821d7eada0da9766cb4996ebeff3fcb283897ae568417b4bda3e3c4dc729a39ec3e4274184316e842adf06e6a528231d82d3c2ddbf9fefbd06f749602089161601e4093f67c4cfd1e8aca4167104346836752cce382ba0868226f0d9428dfce013ed1da11469c158678cd9c8fbed77cde8287702e8bcb3a5f0b12caeb141701747caf5a6d9e694dbb6c24295241a1aed81a7d7e49e22fc0e4a22756e4548e1a222f3da9d318a387db1ab0d8e54a62bc9d2d48a50e98d7db21c18322e3032dfa2d5df302015bcb687910ac3a23708fb32b3128b03f653dae55d9b7370de05305bf6d5e54ee9488f2e426ce857a5fa9b33c3863b5810a1dd8664aac0b703439ca0d038c18b2c63fa24ce3575b5c4f42430088b140e7fbbf1420712f8bf92043c01bc522774d50a33da91a2f22e476bc05dc5d8a308a9829357e1b15477e171c960dec328cd521dcc3c8330ccdf52910b11223069e672ef024fe761a618befd11814951b2015da51ed54193c22d1d6836a6d706f4a42af4ab275ddb9f6ded2339722c9f3fd029b5304c30b07b0fbc0dd092a386b502f802aafd202f554242caa1059f85c7e41fc1d1b866b4349facaba4255b0f849b225b10a513d496c6ce70ba6cbdf166992fb329cf1f5ceed998770d56174de6f724881cdac946eb34d1c506f8ba86cc69b97d90c8b2a0e4400b54debe16e69c6654d2b9f1d36b34f80272169cbcfeed61c5a22f146da42a9b3b9411cd790b2a8b569c7554557e55e555d10b0d0474d75ce281cd59fa3701545170407dc76070bc03e81f6367175d54da3f9dc3d10534fd8869fea87afb0c7f4c527066fb025c2ebed3f5d8bbae1082a2cb5acb1b7bc659ec2ce0f95ff10d8ba2cb1a3ffe56fcd2e4eac18b5216cad870c9b81f4c29acdf211990dff82d7ad422d52e7f8d8b097358a596dd3f19dad9315fb5c51f1f9ed9a0095a396d7ee36c07d1320aaaa3df05d120362dd8490ce469a55b89b0b1bed5fe317edfa1c0e19106046396ab0934af72be7be909835f651a153c2bf208269ee4270067ee0c6dc0e66a52c7340c6d86da2e5dda9dd30d8f7a34e931b7625a30efb196ea2b8b1a1fac2d3250791c79f3ac92a92684107218119ef83d5374e4d78538b497f7ccc8425ea5cd1b7512f0ee1ba2bd1c5981b9f7741164743808341b91cafa456038417a15c049f2169a44e87cc50fb549a62cdaf0cbe85a4bba4af70adb5d479dca07fc654ad1105120b877c4d66f979e6149a7ceb655888f4b51d4d4f5e6b3a82e00bd423b23d334856ed1997562cca85921dfcc512cd01bffa23b5b88053c7d279720057a0933029fdbc049f8ceef897411a919a624198bea23c89b3211c6c84fd77712c9de5b38cf2cd73423ed15de063ead87a817cb85bbbd8e58ac46a202ce112babb60f648eab22a3e9a71e702d8a5e01192136bc1ef4a619d4d0310ac9c14e8d0e80ff9dcaf887dce2795a48416f4e64ae0188a67cb9d1abc3f1e85157bf3aeb6dbd3f6ae40257f95ec3005d530def59031e6360f6468c30a4cd34514240e08a8cc08961bdbaab75590a5692043c17b8cc3d6780d955c4f1792b781a93f45612b932e221210f17429b00b4b35008145482f218abab9870c30e191d0871727ae944c6ed1571978477328fd986509f1276fa6adad31fc978fc5e96db5b7404db0e7086d5b373be097a1390c8a92e617be7848e0856f5a5e53d4376f12c3967fddfe04ff868cd428131ef2444b573d0e7e7899b2a5a869a2ed19da1b2b70453b883e74394feb55f53ccb510e5e0965e2828492022a8a7f88c6f31c5bc6d72f41dca8744a54c562b22401a5dc368d5ae15980f0da0554a0ec133d8bcc023abb40646344e6d17f486dde77ebb0fe3e49ce0acb6afb6e11cf70d874de6c7c2b484e57efde757ac154c4d53ac149bc8b77f414808b2a8b71a3091a81c3710e2a9d36de5747066a9b54cca337b10ea947944079de1791066e959b3192d15ea7959bc1bb39663dd9cef5dbd1f36f20d6fe7b0949c37b7ae135ef57e70de21042b54266ebe7a743089a783920aa537d88f09208d8b392a4fe77d24793fd3484bf6de780b65b2b3fcdcecaffc48000d252076a2d44fde6c283ac595e0f99f8f389780271ec6852f3f63608b47183942aa757f07421b718522199772b50f07580b7e4e98b848e6d5f6d1d784e7b8b8994d0f2b66bd1ea465724f6ab50fc4157215ed830be3e792b0c908a61ae01875698cef994dcf63b8447532893ef274cc25b7a8230840d1d442bc30f3eccce9485472ab1b3ae7a20a7d40089e7d7287048de485c6ade633549feb12cfec21f13e9b93877f32302dc77ebf0bd6f20325c6590236c9c0eaf156777b282724361d3099eb116948601a6f41f5abf30834ed32338f169e4002b3d026231a48a70bef6d6b72cf3df05dfba0b03e4a357ca678b885f3f542c8fc195b52b4ae1e34df456fc42d28021c8ee01c3cc9ec2b6612d17044c5ad99431c9dd7c65155c85b8e0e8760b300f60e4e41e141743820c73b011acbfeb514662c53121e0e8d5e752eb1e8c639dae88638e4ef0334e50374d508e8b31a74acd35801724e8be6f70cd5f0b3c67854283912626aa3d8f2d861a2813752bb55059354e09025da3184235f983808bc11dd8371668c39d49360a4e81ce740d03cf7a4926726b908468029eb280c08f6ab1f32fde9b9beab2ad2fd2217c8c0946e928e49d8e6f901478ab904994568bd4bcca65a92ea0ac847efaf359dcce8517cca9e42c62506ccd0e8732256e1b0250603d41223da7346b75962b6129b46665962307d9563b9813049b0c4d099ee2b31e19544cd33a34392f9a1db0ccd83c7c7ed9598f484247a2d591f0851bd728d13607891ad099345082e1592e7de18e938315063c05cb5cfda080aa52b2ef8e12134c8015dd4287f456aec4b3a842b858e4e7fe6ac348cb0c17360cc32910022ce688921394672bfa1017c757c0cbb871bd85206f64d3c4530c1c6eee1435f61b0356813951920a5626a4a1ba512eb232940c80ba154db09a4782075e87c5cd399bdf80f8a09358b22c0dc5a65f3af50db313913b5bfc6b70d93104f4ea4707ec5c6413e96a849bb9ce589060b725689d5b4ebba4b5306c0d795eb505495ff90675b2dbbf023381e3271c5631ce9be67ef2d838684d3178625ed2d5be716e72fc965c690602f36295f64baaa5507984d45e3250971d9c0f97211b6e67e44a431bf3e7c09566de3f59fd7289ca0dbe7dcaccc49b6e68d8ea5fe81d2b9f793848c2b35196ee684d15d026e802013ca54a2798ada5b29e4d5fba9398ebcd5ab3db9baad6ac6b702375e8d3dffbf6ed5ec7794ec8b28b88b5a5edf578858ec65deb1b6c4c2ee4bde05c8325f9d3ff17a72db12083265590da06ab3f875b0735971ebe7a0048d4767e330647796454572423045047011cfc903a82dde9bbd4338319785fd38c34e19014a2bd6a920f6480c39aa17de8790334c562cfb61494a90dc14a50a95f01a2a82185e63d9190f0caa75a3daeb79f8025848e472da38c13036ce84eb48a79d0b0d1267a7c5ad0733d0bb050603142edeb4a06044d17427b781b27039abe21b17024b3f273903c4a7401957c90709df19a4451e404221ab48f05ac0914e0556086e15447f7e90309edd83a96a7f9ec3bdd37c87e8970f10043441363f3f769bdc48e299662b229b781c53f7d00a7d39bd8eb771662932fddc90d40a2becfec6c0206fff2a6a8ba62f933111591fefb4367cbab6bcc840d8bdd7e052925a878bc1d1369f88629f75c4729e2c7036f652dea484396fd48124f4187d144429aa57e9106d214e7dc212db4365ac8f4e0b3d24134113d1250b3afd606ad1bf7a141affefcd99530f6640e9dde85108b04474ebd1ab8bd673b51ce328dd4e3cdb314f0c8f962e3106b68589df552e11e7903f87527778c3fef9f4fcef42f7822c7ba86ec3e69ab27316a8f96ee6b9ccca6ac3ab346815144563d07b9be14af51fc21cce51dca2aec0910a5d29a8703331df63198139f9004459a0d90638ef7534c9028ed620e2faca92fcecd3aa57cbaadecbc7a0a9159fefd2ee89f793007820d3418991d907e61baa1fc668ee4f8ddff5c77cf488059b9a9b0f5a277b28842588e75270c1e77fe0d9263e940809a7bf95224078a6804448f2c4ea20521cc7b2171de2603585228bbc91a398df4dd927f690972a8ad928167649d34b116bdb020574c04370ed6da5e7f928bfdf263cf1591a4fb63ec147d880d0555e40c022092959e0e7e9f86014334f7afc874940e1f9d15d61db7c8d45ad7698db4b495d238494df84f7074352761afc8f4dc48da95174cd84f9fc02c0f3da4d53e685159ebab0c2a6e2a7af29fb8cd5b555f091e9d20ac014d8e7a32e34b3a030ff6937ca54596ffa865199e49c4e5257b6a5a843ae49bb2c8a58789c4639fd6e769b086f174d0b1f96a187a41b0f5656b8b80237aa8066169d12eb690944835ef2f9160212ec62378a09d43153c9ef9fef570953dabec02a51439575079e680d23b5a8bfe370020ff32a5909aa828f3b5bdb6fcc8af6d75b9f8ae112eefe561f51602a97225b3580264d105ec6fba8dc052d6f9e2000be6ee3c077f6020aee3d52ab39069c4015d8d9355386e7566dbf237d00b0f9326de98cae0fe1c44c4bcf047ccde6a4baf9a7f8b8d533bab5f2dcbea68193da8289a5d068c162002e93047de2d35e4f07cc52b6a65cbf66f8b536b1aba664e41fa7f67e7823b70894dd5937649a7c0a199526f9928bdf722e8aa444c01c8e31e8882a80d5d7ecedffde4637795161d06d9be4960d40ee103a3ca9aba9ae5e4d9beaa8c18b415d7e790c966213f8dd29d4b54ee55cd580d06b99427ead75fed4d1b1ce42a4ba29a9f41039f542d130eb2a331c41ca853941393e9bd1f7596d963e66506c4e06371334b65b79cfb677d61b6bfce635894c06f9ae1d6b5e9144d0c10622a57a934cbca5f6df39240ddba8073ce6fdc8454b74e43fb229e9f7b5450aa98ba4b85c0b14415cdd4433a0ac0ce309c52d7ad733d845952cc7246bdb406ac822d95096e90d814baa71821cb4e39ec432163f6f305c4fb76c6561cb2923dde27c17e5339145b47fb9bfe450c052d893b99e4f7302364433932e4a5e26b0184387bdb403c6e26e646dcf3ea58269f083ee1911b759e9af8d141c0a6cd24a1473194c228bf562426ae37667ea055cd4fd8b7f6c91b77040e239189a79607acbfa7f1038e3187ac3f9f4eec9bf1ce4f04b67a4aeafff2ed629e6ee031d7679774afa270bbb784175cb0a7644fffacbf40438177bb03ee10ee53346403c1a284430bfdd0de66af05430fe8413a26d6bd791c7bf4ebd1acf637098711efa7eae8a6e73aff547a421587cbf508c9b5271e8a5057d136dff739a1fc05f45ef44d553e2b95ff1eccce39b7c5a8447ae1b78a4a6bdb4a09505a7d8f25280ce2a7cde2f6268062a07c8c3985a0136001bbdb602d5713543e8389debcac84df0f156f61dcf2c3e3e462e49b39d3f16c009f8cecfeab0ee65b2a5ef168a9f21ae25e4061a1c2df63a409ab85a4506a2eee736139612ff79044f62bab0a4750e56dde97248eaf9d745346f5a4d6173849ccc8d5f02c2bd55886162c8a795332c2673c7c857f5d689fd37cba093c0ee588926a1f7f5a071ea3452340d41597682663f39de020bcc3b60b0f2c2a3890a4c893d41f26c7097e679a1bc798c3d4bae849079048866861b2305b8f7e9a4a111607c9ba33fa594b7922cbb620de516aa172e6b0d41c033f890110644963578e61e6eaca32cd2e57caf1825fb93bc6f09705f06dbb88160168ac5fa76296042e17b5cccd9c3720032882ff476ff7000ed4dad02d3186dc25bf0b41b02fc53f5a292fe25a4fac97afe7965a377a9fd09779d3e5eed756bc10b6b61bcdd2d354b43ae5cbdc75a2bdeb3a18b6736ffb671d5d1ba2fd8ed4430fca2edd450aad22c253f88805e2bfb44dc8d4a617f37f49bfeadc8b8a97b69f40ed43003ca5166785b30ce424a07026d0563d3624b9e585045b675d6f88af2f2650b0a863ac375b916ef185a765479f0392e82b1fc2c59c513b167383d6704629dbda1392dda331023d02c5379d0573c7b3edcb730b3f3cff125217befbde59652ca246584074d07580746320713d115f6efcb79c4d8398c0a696811fb8f161b4ac638dc9672bb94c7de85d409ebb17320a5443207fb66451e29d163b74618e76c8d1efb8ff65890635e038243192e13aa3d09276358e289e88a8b89ea10c456bfd76b074de4f9b5d62ded9980c3d13770f4e72e98bdf41c30fbbef454a8e1a763b7d66f10cb8473497966a6492e0b6369e462ff0eea3dadad991765cfdf2457f233f7d6124e32dbe06da5c2c9189688a5114ac3d4c5ac13cf3a33c59dd1692fbdd3da7c9a8a9b96b3fd1de89cc9134f3ba7a5d576fe80ca2b355666f369aa8ca394a336b7a320bdd5e6ebc9c9e916576e9bb3d3c0dc3d719cbc76823033a5a1c8aa524ad90e020eed6e5b314867edeead0739daa7e368bd4a5a6d7733ac6d574a99d17a86a33da59436b576d4a7b596a3b46a1d05b1ecada3603d2339ed4caeb5d64a67d6d7959d2caed5522f5c4a29a574aa524a596badb5562ff294b56a980911194ac9504a260d194ac9504aa64c1a329492212aa30d7112c76a3808f57e64d8478fa60c671680016b43397f3e85644efb0b9e0b2db6c7b4cdb6e0b3b47155051438ceebd19cf34e68c9c26915f734d055630d6431a95c6834b4032171b43f7d0b21731ac914125a80c7a389ebaac469d13d9f4353680aa986c8546b8d6a427c35e31acf4f8b9e4bc920e9124fcf52fca4ac1c4824f1a33c82f59c488c9933e69c530236c4d0303ddd508689d6a444492899dfc4738e538ad1112c871fe7d2e4b2f9386363a6ecf264c9044a82708202d49a94499432b36676b3835c2e170fd31b520288899a49b09fde4b930b2945e68cd9657ece897482a04963ce3969d83c0d973f3c0da741430a134fc367783d34da490d92124dbec6b3d75393b3a7bc9e9c8a42c6a71ce5f5a45028f7bc1e54f6a204f15ee79cd7d3d56c79ce2513cff9e6f5709b4fc9b3d56836afa95ef3aa6945535e4b0204afcde035c75e8ff601d2d0e31b24b47cf655e1ba520550bebcc5625c3aa0043de5e95cf434262a86a1dc7b7dd8c205cd099cd0e204d6bad488bf4d90f99bfa7befbd4fb0ecf82d96780bf298fd090e7ffde27ba99080bbf7de7b594eae08c20cab595e13a323db164e5d132c48b426ae89971c300b6584b6262c38920135925ec91f71ee02043008426a1206d0cbc94f08582043e4c48720169a849c9400a8014c8c9c2001c4c216474e9e48c2020c8c6aceb09ab55a926d5e221991428430b088b20598dcbd443232832422224cf9090a80999c7a89f433f4c50f124ffc40e12c2a9c8ca1095119436528a1b12e7d0447d4aade9609218b3c4e8b2717dbc4e4d3bf2ef26c59b98133d6a2f530296b3e8ba40b94c773eb228bf254b756ecaaff2856cefa9defbdd8859e0be93e50d5a2f5e0c81224436d2d097eccf116477ceb2d5abff19166aef8c287232e578b3a8fc67d5db65b89a399ba09123298ca70e5600229685c689ac660da62362c571966dba25a9dcee974ceef7a67860d25b78f5c0d25198bdc9e5d467ad0d57458ab614f81984d6dbd6066a90e101062b94b5d91658b1d7e39fefbc27de1beb8900497f558fa419f66901018114c245dcff51ed02dcd39bb55c9e35ca22658bf49a1ca505b94d8dbfba99f30cef99b42736922993ba6d2c4d14adf48be5b1cee7a08390dd1272257d1cb08cc8fd4c83775b5d84a734787d163cc2a6aa3986c435a5a4899e8ca4b6e400daf81ef837c4f81c8344fe5ac431910276338c2c818466328b9b8202aa2a34498248941248653bf60cc9827a630929e8ee88f112e308ac0782ae3e933901f080864a466a5d3cf34c9a7e9edb125a963a3c2f17a86a8b5d62aa7d3d945e8104dd3d4dedf5376eaa686758cba6a0f5121fab2e16d1acda514a3445a795b25a34396070934d44343f410ee21cad44df488aeda312c2f1db986a8100da2afef1b1a1a72ad00c263a74cfd31313149a61a86b0d323fa7d97c7d3a1efa3b6bab223629eb9d6229e007044ca5b8b268f19a988230178eb9bd763712de18857099400838594297489985a6bbd7992479694357ec479eb7289b75e7126810adefab7e4ad7bef48a4129c1173344009a4a126ae2d4b6468112788626b0e2290c04494f1d5b3a326967873f563f7b58aaf4844dc60f4d56db64ddd0f752888afd8fab0be1889b1394ba7c77810be7eb92ba3648a122c3708c5944c716448496c042a00b1a4a40b20158496104999ae8c5e896d1a2a6fede4412a8900f6d6dbf5226491062644b691921d0905c5c893525a6b6d254a7d299ca199acd43b0d6b476186f9f5254df333f46b91390d93396d43961842501ef1df681c74fb0cfde3acf9d622736a97e9332db616c9a342af7a8c18305eacf826244c4628500dbb89f369516cba847de0640c4a9c80f102230999ba1565fbd2b7a2dc33295545b65e613926501f75524f1b4ed89c3c351967f2d48425f41c75b6a24c7f86da0364be01648e0d9fa3ab38796daba595565aab05a9137db24ecf3c51273379a430aa449774cc64eb29bf6ec1ceb90c95023d3f9239d4fdb90b6af2a88aa437a1fa388fde8b9f312fd87c7a2798900a1b70bdf819e382f1c7a3fa68a4443cf50e1ca90d638b9982872dc4f450bb9ae480c482a7def1a74e943a5198cca14e614e79a44ed4a99337757aea488410947b86dbde0d7db2734939e8ca488b64e486f5518bd4c71c96671ed1d65affb99ea7516647cd534debd6b954388b64ce9469349350c2f3ba0c0c4d7120ab03459c1651a107bfb528c5a8c529472ddaec5b53ae97bb20933cc11b2d5acf204eaf2c0b9438accf10640e94b7d979b48e0cb717e4c92473cd79e1640c565e62573aa350f2f376ceafe79cf34eebd65a2c28161c754ed6306b9a38a4903a66986d51253b76c5624bb228e72862619c33a543928aa2fbf7e55cf47d2e242a8cf260b7b021dade03ba859faed3d3cde92967b41919519eed888a1f679435c13823a7ad4ace9ae60eae0989630ba9837b42e650a7463267883c72464f7d33a23c0d83e5cf45f1c7cd6886238bba165444e22029112bc5eb2079b420ba72cd1d163671507769413e04c128b5520cd156bdce84a44a4891ba85cd1dd9d3c4419dba164479e813623cb530091be229bd22f494a67ecc96640ef5322dd2cc296b6a91d2316b921486f3e74d14e98970ab2bf2a6183386081afaaa62a4e90a11a22b36c03a06548a10ba62435191e6f055ede029f68b4e9eda524b8d24f258b52c5b142f8f88cb4a749f9883be0d67f3957105ebbf3aaf87528ea31dfe6810875112e9a56be0248f386585ebb42ee348c963ad49c04bf77e988180a41ab13c561a366080687fb8bbbf5fbd33b106ddc7820d3a8c73630fcce4117fddcbe604b9060f073b747043c2d286854a67c991f2583de8a42aab168ff0d966e70be797f5e086d27ce5072c9d7f0902019e6c96f2511e2b88036673251cc019d939620949494a4a5c66d69522a961ad1f783dd5034a716a98002080a7dc45041b2fdd032f64e3d54baf60371ba857edaa7cbb1a68b028c256de13364410800e00bc748e881bf39512411e7108f57573268fb547cf11bf9e50109b624c4fe711ab7d7a3ddc00c258c794478c03e7fc7deea2c89a2fdc83bff4400679c40408ea845445373627050802238fd58397ce8dd065d747c0f325c4f79da1fea42474b5836e5eeee0965db493457d960e0fba9a35a6aa481e717e52a73c6ea3ca54990dcdbd837fcb22675511271c47bbc3584addde7b25186bedbcf25e6b6dadaa5aa59492524a697777eb349d61ed30febeee9e362fa90447a9e5e5ea65d5ba9f86e30cdf614d15f93e8d410c2c92dfe418c460bc6169cf51fc35fb5a29a55d6fd42c7bea17dbea9cd7d3dd466bf52c08e69c93ca7b9db22e9d5d6bad1a94c9e0386fe0b0c2a6b47691a758bbc8bc5dd5a2740dcae4e9b8c5fc72529ab95a25adf5de7b6ba594d6ec95b9f6da5a6bd55cdab95d8b6515d265aaefd3b67a2de6bc32da56b39a6badf55acc755e190f4b9e35f33a6bd5b86dd3327bc95cbfb6d6cc6b9d30d8b56450489cc471ae69ad813797a20b558a9a735a87bb70a4e135d5f7691d963ac2b983a250e36bea8e976da28f4f18176a21e6b84d7bade332ceb3365ece53e2a01fe86eab92af732994ddb814d8e3b3010cb28794a7739b95a2a65d97a207e6a62d4d58a5ce759dd763dd9b3b54ee58e917d549a9a3276c09d6e459dab33a795af0c70a7a2ef584101c1753923c28805053acf84c8eb179db658c278ce0a919a454f514c7a9e32a9e7aa6fe35d1c55377249e22393186d1d3536f297982de6e915f473c15a47ed8a1b3e20955840f1c97208f092642b07561eab0e8a0f9a880897be12d4bdbd22babb8cb8bae2413311f7c52006302063f3419b97af0b1c2c8a8071e7cae10322a010f3e312123293bf87081195d09f2d9f2649368c0c5899c7a896483183a10c94174caf825121120a62042048e75f9d571c660a8a4d7e1f74d27b80a562f05196cd76e3f417e8741ec6fa0abcfcbf4585a2f05d902cf1b94cf49aeadd7c33927bf10c1010636e09f1d7e248fcf3df2f8fe2087782d244a86915d24151f19327f21b9a03c124c2ff50e75ecf61ed12e7287b467465be6b1cb1ef398cb637bc563dfbae49a9caab42937e7061b80372d7c426e1ed0adeb1cf806fe8542a60e2598e2490e5a1414b49e68524b94d74f4bc890ee86d613940fc95460a5f544f331075d217b89969c280f8bae700aa6d43b35eea36db2461f1ead11c67e9fc84c3d63dbaae48cebaa64ef477f295bd5ebf1b9a17e9d83b0c6e80a7b06de50df20ac4c4d7485bd82c92f649fe82d7a7c891edfa1c7d7f5f8be1edfa0c76e63168be4c9fce6b1db29bd73d43b358edd26491ded1f76492d938d8faa1fad91063e5a2a1ebb7d519e2cb446f87fb42fb03ac99c6a46aeb06357961ac6e3ba4457d89f62c9a37db5973cd6a5c7d8ab1592875597a48e49231c3f3259cc58bd7c3351235532b74774855d7a12b86e8de80a3b8fa64979a444449cd68d9eda22d3f0b19f28914d980ac74c54c3f1c35b953c5aa3948fd5db3b98e11b0df0468bd81bbc115bc42e9f01a9b0fac6254fecfd243eb5881bcd63dfb6e4544d78420eab13c83d57ad95c730db84d43c1af2680f92c85928e4490b995f0f85c8319e285af282c9d5ca42ecae9634616e3fbd94134d049916b5883d1552a21631f64b947d70f619e00cf37f481d9b63f7a13ccd4457d8714e61e750a0fc0d94df4cd825b6fdf4f98de6b9d449af3095d22bdc44e66007e50e7a84c48167cf6d4bb6b676addfdced582cd11a69e196ecdf1b68034d9489e9e808069bb1212712a71165fa8d62fc7dce8302a13fcee7b6701cc2f43ee61005b14f30887dab5129bd6ac72115cafe45dbd712722c91bb27f2f4ab9467488d90c917d47ec8d2c49205f038ba99d685deb1dffe02d0b7cf97440193058c7c177d3b0cbd93999424795b6951ef8cd40895d23bd4c9b77737bd14ea1b6997af42fef68e873c9d47d3a3ad67fcc0c918b87079bd5e499cecbd768bead5722057f0c909f2250cf2acc19bad1952f08547af107f5459a194822d4a90b6cc0029055470607008b01553fcde9b44149a8e3a73ac00fa5a3b89134014e32c35e1a46f7e578a7c2c588a319d398382f602054f38bc709072c3d367003f9014b5010542568ee0f2d2ca112fa0f19b19194315463f473724f919ea19d8ae497ec65b6fa30204215d41f2d665116f2d75ba02e5c72e7aebba42c58f3de5ad9d6d9bacf0f58ebdd6553b640fca4f90c67333e90529c8a0797b7611dedfc673d36341f3ee6aafbcdced5a0be19194a6e0f670d8e099107c830078db610f9b947d04e9951dc149cebc1b49061a7d967111d2a29d209216a36fb083f71d72032579eb1f2c6951e2c7b9f401985cbd4738416925e8a5b74292d46225cb4b6f85ab85b20048567cca793427bd9e9437889de835b0bb3661fc04717ce6e998c9de09f4a3b802835f7e823bcf496e6eb2ceaa859f731bd24f5083e7384e7a0270411e7da83e9b1883a3086b7ae9e998495af2d33914cc043f4104fcf474ccc078a8f1bd42167a6d3d2d4b969fa0cd679e0928ef10b7e63ce8cd747933e705718338bc3d7f6bae037163253f41033cc7693ec1d9d1e95d97cf35d6b4c7a1750c66ae81a38f769486a588c14f90009f8155e6d010843eaa03471f5fd8655d9662ca4fb0009f819dccf911a47e56c1f80902e039e9ad90b578a73441f319de4cef97f3a078f47143eb13ec6e28b5b002cac151a565cb4f90f519a881a30534d087eafb06eaa8052f85ccfd2f289194927c8633e585207e82e14b6f85cc259682c84ff07b892d853d75bfa0449a22f617df5c9748515cffe0550f84f31b02998f0a479b4779d722762e93b351362080f01287a30fd5639fe1383c77935ef0d24b013b0daf711e3dbb098af017f452b8a10ccea3db6380e633ac1ecab9eb61efc0f92660e7c0f91c9e586250b68892dfddb44ba4242b2f91b018f113bce990019acb1645781b3fbdae459473d43be1b62009a416bc94621291b493a246218f8465e92798e3bb934851bc7e821fbcf452981b9a414db24703a2b1209ffed2d7c4f7216617cc300df0a6ebba5c3b1478a36929f046736d626d0678c339e79b731c5803e2c61c28df03b78e4e303ec1b994042848f593531e9b60687cf1aa1db2e73304c14249e6f56991bc0d225a1332c7e1a87aec5cf7dc8979b4e4d1b863b11853ac29e6147bdad1f2e29238a80d1b8f026de85c81478c375c446346b1a3182cb684029d9317dc41e6e040cd97ab45eb63b55e8af0e2c48b142f53bc24e96879519239f2b9bbfae9ad1e05ae1ed7a6a6a332f248e56533fcd16203c55c73fe0cd1bc0ba2a7855c665353513657d03c3b613e9a3e4a41f389a4458d869f6e83fc741cf167467dd84c14d8403a5e720fd11f5d6c8ca39e29682ea4458dca167dd864e7d10d94f35cd609c9951cc244b9e833922bed0a2800f05acef3681498f318942a787a097b89d465cb5ff1fa0f5e227591f29cd669e06c0a9bba145104d1b4ce659d06cea7a32b623bb449d64dd488af8e99acb92c0a421fb502ca37405f86d94def84ce35ce51e31606a13f9d73ebf54c07e14a96e102d3fd65389d66538b5665258f3e6cc2116716678fa45fb12c5bd4326e03c7efb7e975285be6e8e94cf753bb94d0b491dea12678eb5369168591517e7d7a5a389f269a89e425c99c4eca8c9b4b8f85e94e7a678e38484b5497d50ba2c29135def0e969e1db67e6bd834275a89a02c709e4538836f1b4931b37a68b3635925e59b7363d28cff7a1c2cc7edf2f160a3d2a6c003fca2d131bb7804af5d35b6cd15a950d68a4c84cd37a32db87b72ee50863f3f0d6fb8824c13a0ec71f8fa7d69a57c3006a3a923a2e3d821e71c32ecd91d4a185fdd2e9925d0852c1ce688777ce39a7ca6f03e970c9b8f2a0181cc37b7de2b468e7b401279a5e596fcda7b7de320686d2f374cb7a27e91eb3e9ad6b7367be756d86b66d87dd3d7dc020dd42d5622e7030c08035d1c2d0a2b52fc0d0a2d5c01c39509895434bbece594785e3073e47f3cf557ee3c60be78652bede8937faa5853e3e8e428b3a54e47b820a3e2dda51e543fccce96d816a5909bda3eda0dcde70b4c05f9f5c4d2da0455b82064e47813e7eb468bd877c9518294f01f58e9d28b7fea3772447bd9e6906956ac187ea512ffc0cc7394e478152f3f1f3c17a1cba4079a63c62593bc1348f8d4fb7311bf035f6ab815ab41bfc04259252166f2d90ccb17e25bf28400515578a145d314274a548100541ca6597edb89c2ca1c6a57fde0898e1d2bb1a0464976e933397dfdc9185aaf98df91167ee58491c7646e8a1386d0d88e92a4bbab2b2f581972cadcfa2deb961c01c737c367f1cef4b691e969559e6371bb54ddbfcef78b9ab6930f40ee79b11a9a3bab5ae0f2ffcca34c47963b264075b953c30d0150c94a731ced7fbfbfa0556c03b08a88786fdea320fe319b628c5021c8a88690103072db67001c5481364c8c08829a264b1c1c9ac4c492c0bc5124058e9258ba6af8edd71b22c82b8588a135e9d91c5ebeb972f6fad95ec3858108de0d3996441c4054b5d50b9610cfa848932342c8ce044d1b26035ab0373c60757181c7c180a134410511813bcc244e941284cd21108588185b102041038620af365070854390ab3050f548ec28c910304a8307d354b61352bca8f1850641a2f917ed26071430f4d727d897403098c18d1e58627696e90f2c31d01ca4285e3acfc7047b63280b250e1b828595c2e233680968881c2868d0fc9880d20d7123150d8b00145cc754ea65259a5d539314c9a74680919c215910255a69794e9ced6789d3dafabf1e6161d949ca0256488a6248a2459e4eebcc65acf7377eebc1a8bf20e47cf6f4620ed27b40ca3e75c8327c8cf35ed1c38c2f039e49c07f57cc2c42c91f97bcdfcbdb79f832a79ec180338bf01e3faf5eb9cedbae92fd3df8ec9ce42f2d0eb5507c943c306d3abebb5c7f8f0372cf3d7c72ac46da1d650c8e4c23485a92564c846054a4b0317326446085ad587cc2f925a4f524ebd86d6061b803588aeae6b0056a126e13a05ebab48f63ce5637dd5787b69bf28cf34fcfb824638662eb0163f4ed88b0bc7d48c70acae26e1067dcd8bf2b417b9ba391c5bcc5fe75ef5f51de34290abd39ee1f811c9f56738ba9099b40488574bc8900d8a0fad27d387cc145cd17a9272ffa8e4b1632160c1b9b763134657d72f1ef353afc92e6174c6955e082687b94e5dbde3f9756aa4773abfde31a963fbeb0d46eab87fc3f1eb2ffee6e6e2efd85ab080f29b145232749e72947b9ed2209c4abdea6eead407369816af7b6037b578bd03fbcced588bb7c77419b09d5abcd733a516efd2bd1e02963aa4c2827389b1c1b9c46c6564e1b632b2282063b744327669e7c4d22b9808902035408310960e175abcb5928ab7d60f80c3ddd039af013318c4aa5a5ce13a0e715ab4dfa7815fd6b44e2a2053df52b9e67a0d28e50afc361c9c3983d8e7401c15c7398fc6a07dae3b2e03f33b9f5e0fc63d1e8a0b551d289f66dbd488641a9e401dd72fa13bb9a32345b9430089a50e96ccb1ae52b1b20b6bae098ec894295b1954a8e08cd475b5495bd21fab4d8b99579f4b9e04a84fd8e80e4a1ded46fc0cfd33f45b2d896cadcd42ae660244965afc2f43418380b250e1a86099b2f9b724872046bea68750648ae937edf480861afc1cbda0a14dca921d9c704438224b2ce162441811652b632b830922b62a990a9d9146738a06e40fa9c3c65b0f2275c8ef495e328738e21979b528640119968c028f164340ca4b4b34bcd1ac07c92fa985eb47ac85ebabedb14e85c821189169add685fe9ac81ab6529cf81a560a2583415ab4aedc2f5d79cb001089c37a0d7fc81ceb1c9c208ffe35ab2e843e43e41fd631ce4ed65a4b438bd67f380d3fc21fd4696302280b150e0cb7440c1436c2d8b8a19ebd06fbdc504f79f69b94d7f80cf73e2a2160e11a8950074dc941720688025d59af01adb5b65abfd5390faad6bab5d67a2a64512c99456dcedfe7f54bf6f10305f6a02b6b9d26e5ead662c0ba0fa9a3bf71fe7c9664787f41ef258ebd55b060fbe284c8921e63230c14ce35440c60c6bc9a7208ba612c81a523de709c4f6593f9d8f5681fcdc3d2116f388e6c1a6dbae9e9e441f274109d403c6da78e01c993e94aeae09eba0fa9a37ef3279341bd83b2b0837c64ce03e48a3a8bae288bf53d2da8d32b8aa3e4116f3fe69f8eb73272ff985fdab6211199f66811ca8f1e48799447d80c182eef4aac0d883c666fcf9e045269d2a449d3aa2d64978b490d6d5a3b22fbc8829247dcdd587032862f498a94c6a83f5e8620f535ef3a07727da401871ba8f116a494524a432099b7822c3d0c643e760e879e0aa31602b93ee2e93ed7418c7f8621902c6442bf7012a79b2a2ddc5c7aee398f6ea9bc0b8b741de6b6ceafd7aef39f1a5a5df893726f0b81648e352628cfc0142acca173da85120cdbb9e7cdeadd9c5e89d0ac67f7a4938657c88bb195d01b88b73072b0bc9e59adb5f3a66a5eb34c63d54bfdc3517553de58a73818cf6ffab8f1d3592de668517a074359ceb00653a6dead754dd7a0647052aee44803f5ea3fd64720c058c38fd22509928451c88fb2a6907f86e38f9febd47f6ca5610e5feb877aed1bfe50ff09c71f6f4306d4fc0ca524806cd51426fee9429e4caf610ea96d812438e2f086d9e29c7399b3b9901a5a5bbb0c41ea03c97cd47c03f4997460f3bb85456a70b58a081992a64a165d80310619695a9bffd4d0dac29fceb9300492b9740b32d9864cd7d150d0cb08111b5a45649ad6ab466b0b73d8fc670b2f38fe781b6e60e4f0b57e36e79c8639e0d60fa62be943648c888c1f2e63ba94f1a4f5f3a47d0ba9cb1b1287d21e8e887ecc4743eea4fd907d74169625260fec4157ed1d8893701044a6432d8a7d5d903af0b7bf30a50ecebb8af1dc4490a7cdb6853917b528851aa1c92315a2453b45429489cc69bf61ca54c85f680474deee0215ea9d9132f9f6a644dfde4e2813a9c33bf0463b42f57dde8114a8574d5f1f6c91c7a654322dea1d3a4a399dfab0348221db4969b13da66971a38ad3b7d6a12cd6b7731ca5aea72727a7a69cf4a8348d1656410b99220800000100c314000028100c08c5429148200fe464df0314000b85903a72549bcb836910a3200a32c0184208008000000800801087aaa60800c804c07847778a62af42045c3eefb1395633e29e034b5cdf2546325fbc9c514f576782761573019d19b546730653acc2cc978365d94273680b7ab0d6ba402a841a45626b2a7826cc0148433ad8c14b87bdb74671d85c2fc8e1cd5df4eff07fc2f3af20fe69ede617637829b6f1ac2acea81d7b731e23d615868225d8d30e4a2fd73a9ee00fdb3bb0379f2c623787d6ff0e60bde4e2429651c41054f1b8e5eb177d93487f1a85c27fffeb02c5ee47001de08d4d4e3da1a43b78d0cd36823dfcfd63ab1559e12971e51e16ad1d9aac40d1b8a1d5c36535fd152cdc1dd743a6d1e713dd022c657f81aa1b1ddbb6ffcae518ad2be036bceaf2921aa2705002f800c7774a43b0ce527d08b6496bed3e58b2761805597beb0c54416617d55f1b56af38d66223fbd0a748bfc1abad4d37eb1cb6c53d2572046012dbc8ad1bb71d254c3a3cb7c2e3dafb5f5a980f5c0bcf895fafada1b01c51473e5f878fa12557bf4d03819c452e6f12e2930139c8d49e428e443fa2428e924dc486bc24fa881878a5eb7e4cac4db4c33e138c559a01664d15c9de976c24c17b5706157cccb889fe8b74a68fdc3dc5d1e105186a265886585229a734336ddc1636a4af7ccaaca6ddc215b168432cb21f5cc0beff97ed10668377117741ea4e0f3bd6094655b7986652629084ecb289add5684280d798e06fe7c76f2dd87b0b80c6d881dede7223cf0df9aabd8beb883623568337f4eabd45978e1e8874268ec27d758f2532d17ba33b412f940e2c3aa0f4ddacc85d4d89299fdb772c99897e86f4d6737bd32d3df748eec647ee3edc273419315e634e5a6c633eb08a285b4d240cd05aab26cd03c1faa733e8e2ddf046250cc643a48e2f4b14500262a0095c55191d8b7e95851ca50daefed250b591c12e1f27cea70f3844a68eaa475d344ce97aef58357f5a422136c8d1fe0da71686bef4fecd995dd063a9faef2bda19214a5b53976c43765fec464fd51921955d1cb6be50b676617246b8478ca199345ed4fe1a90006ac71abdd7e67b3b1780ddfa7087d73d18fc125f72379742ea53aa3087501ed05505f77d03e141d17fdca58a194ae6d0c3040397839e50c2346a68db07d05c2dfa9d7f84c1cf3973f67a0f7a382238e01e438756988ad898382dec85da89415f9d93bad46179f09ec8ef6e037a8ac7145f753d6528ebfe58bb482feed01572e5f6413e4f7eb147d9e7570bc205523acbbe61a3cb0387a5b206768dc06055259084c297f7d579bb1dc111afb5defbbf1d15ee906a5e81033acca506cb4a6e9468ed0563273e2d88d221c33e56bdb1c7160e48a876ce33926373eaf2aa82588be50b23e6366c5704446ae843ca862cdfec095680aab539b47e3f445bdf47b92032a3487f5b76d1e2202c3282bc794d2f216d7b16bf4593d654868899018f277eae3f8faba52e7c31aeaae28fdd02f09d4032d3c3b7b30e9411460b3cab5d78d182d63484b6cb23b69315305a9d9a496b9899c4defdcca32ab49c06efa833c6e110e30e0e8acc1ba2ea4561595cef8a4bb8bc6a5520ef01a4ff440c6bfd79a6d175045316452ce210924922315e8d66b83a70966a8f2962788b7730a48439c0c57b50a3163d96adcaf00e8c58928bf5e783eee9f7b9533683224120d8c6fbce093b5cf4e17bd49cd8ec0dc92480420e5ea6fa84c455798b19cccaf848dce911cba782654134648acd0024ba76416ea60957934c9b2586926a42e08bcc6a3915093a968ed2eaf9561160d5b5a798c41377d03a62ebd9ea92c56e65eaa1e918bb67ad93c4d8c0b7e91209736a37da56e81c540a097037024cb036586efa74a4262ca2d657bba891bea062f9026b07ffcb72aaee241b57c1d563027cdfcda26064625d9adcb55825ca7cd8ab0de4595c62f72e236d5595f588094b439dd8b73177fafc8b8518787ffe52df8a56d030a1819e651fcdea99b504db92a225d1202c6c09f9a13c11231a443ff9b99efa069efd92979f4f702dc291b11f316fdc25965832d7605c31193a2947ff72dc8dd500b70802f66daea38bda1eb816f1d2eb0a28fc2411f77a7d5445cd181120e65663e9ec3d12b9b088f9a365f215c0ced12e609c478f0f8bd0fa58d2f5dfecff35d7e121921b90809b93198aa87ba951c80be1f90036629d5b15c67cebf3d496f120e9df73c60bb3b831906e7825194d91319d9ba2b65720eec3e7e3292168157621f2796903e8cb0cd5ad2b5f85f5a1fdcaa42772ee681b7c3a0209ed17218475fa3928b0401e2bad58841677bc944569126e3f1d148abec182d675042ec67a6f1be04dc4716bf184b398c903621717c280132166226e5f549901c16d963e80b4d295543bcb52fbd3e57f548ddfa59c460ddc5a1efce7908f3af2647087f57258507ea2661a66c937bb28509516795888da0695c34e116d433e305ec12cf9d6912e881c2f8a76b1e2e4ecf4742f3118656312552ce3da13a8f37b4e846503f51520ce9d76b10f2419ee8d88b5e4715bad2ddaf1ad1ae58436353cf49b1a719577186b4bd0c48403564039398b9bd6054b8bf13732349794951afcc2adc2265cc215a8e7c17a2516c9a325940469611fc5ea0aed01c03d8d035ddf7fde924dd6b32b8866256f35fca8886f5a4153c445366f61c0bb452a2ff470b0c4f1ed6dd9bd229998be2910743241261156fbb9feda06160c6201a02782ca826232e4f799922bec0f2794a16588fa930952dc4b3cde1ac6a174df06ff9eaf4e46c7caa56040a429ce1a79f15828970cf01a5c806fd636ead0e9df1953890bde4c8fa4639c05db3e0fc9bc0078c67e52683aba9d5528ec84864fbf4e42879d1ac22c28f0977d2c5cc565455db7c7a7fb5160ce50a67a58ad1e6ef4eae88de23df15a9043b9b5297179c238abd060b40798bca8731db0557b35b51c8304a9d7fb63017622a05e2b0ef967f29d1dda46d5b740d2b9f72b4b4f3ec7829eef860d9217b54045dce60b23d4bc8921e5f33caf44bbbe4c05b55fd24d3c00a7f2fff1bfc02e6c2ccd077a2cd8fffbdf1d54245da179e3a1269fee5b49c77123fea85bba483f55a507b8d50f512c4566c2787a59514b02af6c508fcb0082fed5dd2a26b356ba7ef692c9dd18b6e59500b7524c2cb0722b25d082593da662e301b0d6c39769bfaea7f3ab1244e95c9fce51f95c75b11e383cc210e55194832dc2c4b5bc9a977ff0e205beccea0a7bb4ebd82d1bc3a9fd819da5cd48f959ce2c7298ca44bfa02023e4de912c2ba61389de414c837c8ce7bd587017ae64da958b875084bb77c306b8a0c8520dfddce7e072cc0eed5e62364336c02a841efe26f0bfbc79ca321c8eb8ac8935678c599cc85c898673ca03fa93d052917a94364561bd32d3cefd43de8c5656b538d2e151e9bf018f170ebf7f2a8b5a31a79bf049a3fbc9b00e45dce6d81b8d9b4f45e4053b6c741a8a3e1bb364ec15b7718d488fc3c59449992aaf97a1e24d108166cc200a653607ba74325e1b8f0ec9cb25a87c15b4188aa8fd4673e0d68c56067ed2ea874065176af3ed165484b2fc8b0d2f78c80d7aba42ef9d66e3619d3da9d10bb6562604d5adc509b5dad6be2c0205cc915c8f099118c4d0b0bdec8dfda7d266da81ae89f8a6eb30c3e515b8bd846d985c463fad024185eef147a81aaa23b4b761955b027711d49655df8854ec2ccb62206a45f8763634ff0374b5e02737791f02bb47edfb037296d897de719e91d50b92b27ec7d44debbb2776cef3d762408c1466ccdd991d906cb0586f0947fab9987aba1ed5b7beb899f20401f53a79c084d4abeacd3777a60c137220248aeec16e8db96666627e3c4f1b8a5edaaac1535925a8b17ab9595336c800c368f078dd7c497526858b2f330c953a18d1f199550d5b13b709f66255c42c90748c4d884dd8934a82d7c832674990e2c530523a1d9b70f7dad0da3190be9e8486735baab7af0c6a39cbf1f98f67fecfd9fcd81dc4d9d396b7d5862fb0effae3052bb49f27c3c06e46b2bb92977d4be43a32d513c89ef0644447d1697a3ead73d57eaba307b29d884289744de4937cb65864650997a207f7ac5d11c3553e3ca3005e683cb74e79be7b787c31d6bc2bc6fe1025d57cb72623819ae8eca69232971d645c381841b72de279ee4e7bb7f543841c264b85501bc492424bf1ab2184b7d2f4fe1d48450bac1e91512e1e6e117069f66298d3debb42b8999a261bc135446fa74d27219a5fbe8f45696577c87f6f7096c059546712b1fe7156b03d4428cb242d2b56290caccd8927aa18ab3f7db81bd0a6efc765266b76b4090cb6420f68aab7c5db9a54d8c326602dc6a0c27aa7689e159a148f494829b82bd2ae450757536e95c89b6b4da68e897fa20d4e737aa559493b19ad5675a451d27c785f034d5f3151cba0305840c72ea9cf0c6c3369a9abc998f035696f40605549c942c8c26df2591d8eeaf429fffe619f4f9afb78a10e57cf8e12b4298b459565b6f2ab3f7d5c13cb07ca53ebecf431881471fd49b0a6e0371c7266f4bd1529b546855c5406713d2373ae3a294c82ec1034012c956c95889f36afe71b77ff65bb7c0b05071e5f398d55c13537015f0b2f2f4d3c72bdb337addd708a41eaed5b626d09b49ce479e5be7676bd72ecbaf154a11d448ce1571091657c91cf73dd66c58160b61510851c17d90a9ccd9ffc435888c1f364dba51b11f65404ec8bbcdc945cf7b3d3ca1e758a130681879002bd0332d1149fd31bc9d1f2611754cc59d788b2b4bb40215abd0ca033e579292ea907f6b0f30dcc8540fd0ac55475698fe9fc28286208ab0d0fa1bbf09493889ee0ab19d4f7902815334182359be35cce0ba28918a8dba75202a470349f3cf4a8d00b9b765ec78bbca9679179bc57008ad28b77119b8ae8f0889d582318fa6ac6df0924af10399ca8f6c8047a88b651e3892d22d76e0166603796fd69522a3cb88c59ce36312830d16a88e35a43aae866d58d4c78b4c6f116de4fde286a8d9f2d8eef7d70cf9b28633e3760f046d331d15cb4aaaa766d4ee566fd6e0b1c15b29a870f6c335b3de247e267cd5020fb3c365dab1309af01107d8d4d69ef6824ef12d4b3bc5aac83bef9c636a27113e5bd09531089f5e514c09cbe9d80f8544dcf7bb2fa0f4f65548c2a827812dd36c1f49f2a85ba0337b1e278c26358b274335a3f9e632a2f75accb2bff78f45d8f3c142d34746abde7fb592668e568db0224aa35522c4fe6291670f0e0c7ec1b4e829bda17edc6cca97df589ff45b0aea3e9a6f70bd088d6c0959741423f87f3ec210c7fb93f79e393337d8e59f68ac40b652ef684322aeaea11affcc733676310be2860d8aa0183562eb00b198ec628ecca18edc841e533fa1a31b7a98dae68d094a3396b319997e289ef389d09c251f23296332eb3750fbe3c0bc9ca3b30c10aac1af8a89140feb4560004e758844d71fc26693e5020a5d35da4648213283be0862223c3bacca945e27a0dbb90939ce7d91d5e2ce1e6d2097a28c9a3237d32580e3183187961661ff6771d74aecd538be3c0891d26f0bbd9693dabdb1ce18135f2d7db42833d7a390166c48968397abf9c058ce251b279ee9ffc4c7709ccb077c0d21d4c915ad87c9143300c3c36b277eac6c2929d903beb9d1ca6251aeee830fed76d63844d7b73805b8846ddc7be2d377dd8883064528f0d05219905a70b370113a01227cc8fd4463360be2c62f5093bd1f7881d51fa7b71c69fb1bb1f6ebf00504dd41594d168ee702d81b9c6441d31f97d587ed7abc3b70c382eda4e9d3f64e86010196b8613090d3ea64e7036fb9ab876d5390daada4c74c0dc4fe89e2ec0735d3cedc3754d7b922a6d40410e51a47022c6477f036564555ba430978216ea1681fcc3ea06efa7d32ce98ab73f4823771e2c9f022cc84143aa1bc3913f9b1867c4fd3a27c6eb1d9290cfd457907655d44addcd3ad2726dd351e98a0c2bc831745e3ddff79b9d228ad638ce92273290bdaf47eb54b2d457c6df2226981c5b41cddb291e14d48058de736720fa7151ea79a6bbdb90f3779159bbd577b011680c7a1fe3db4fb5bbcb2ca2b7008ea0d1c22970fd6bae591564070006488eb5cd0bdd12f3a477125293a1fc7515329b1c1be54f53999e874f522b4633c6276e5d27e02bcad0b75c2f4bca4529a44b8ad2231b608b280bb7d9d1771d1baffedc9dcd906edaa43dbf43bac2652cc1c78586e520da1574b3161e043e755680380a511748d8d6c7078d2cc0bb699d6b2ed7e2e4d6a2508536462894188f06f570c60f182a92882b643350c22b85eae96ec9cf1300cf7acb00e1aa2e29a3872975be0ad3f104a126e5d37e640e53bfe7aaae15e74393cbd9984c99b293e9ea4636423e811dcbc585e6a6be97db4f9e187887568ebe04ba8e47375044fe5fac39b7446dbb1b0b196530896fc00c0b012fdbe40d13e5f2172b2dc3af6cfbdd62acd0b13174e13cc126ca5b44c341cc43d9ffda0d0cafd4b8a54ca125724f653e4864d51a797b63037f48c261745311bf8d27c410b60228c13afb6c184965469f25ce033550bbb03ce70d5cf28a2f219f7a30ad2cd72ac3ee52dc9b56a0fb3e5d2bcd8120c1260649621968891b1f1de6a626e14d7bb2f8389faa8a9e97838cc2a67c23bdeb028f6862f1fde349915ac1e69d419e5740f5971f559a4be3a2da91338831fa8dda71568e160f06021dd75dcc772b6802c70aaa5588087ff01d5795baedace066395bf32e13dc7477559200d799c4c717f28a21b82945a1a4c4a077e89a149b94d891d2a377a66d6eeb3aa92dc1ecb576ed1241a96814a46da8ccafbcb081b5736d4e90a666c3368ba6792bef17b6e02e5840dafbbaef7df9df9d84fd950d4f0ab930e0d735d93dbc923f4f19341e447b2ce22fb27ceaeccc67dd6faba4550c78b61925cd7d2fd789e7e41fe6bdc7e451032a442f547a4e64ff4dcea090dfbe5eb2ed04f5427df0d8808ae5bb2e9fa79626f4e2c2a6ec2485e54f251424747308560e11a24343e02eff07ec4961221f799614b8713908596d8a400bf91e5d741db91bf1890c3856a7bba7876e1f6d3501850eaf899c0eb76b50fa51b65876989b8634215a663cc54439d5d27a4999d4fe8270a00a2b30046aec809dddd8368885324c129f3a3ecb8cec18db0f046de988643a34a533b52b5dd140b9df3897c8c0aea401f30ff0892df608b26c5e7eb3b17913026dbfe757a3e7fd88bef645700ce3947c6868e369e8e60eeaf4e746c6e3f409cd6fbb0beb404188aaa6f4c5eae5e8ff89312f6a7d8063c3e008fc34cd74f97e52431d42857dc5f7bf86e214f78389e2464658786b5889d33c91ab278d2add0122ec450ce51ec529e307fb46aa7f96e98f925119ef3bc7d836346338d18bf4859e9d67f907748675be65321a46f3312877a34ffeb3ae7500429de8bc423ea758a55279402155d106a446566f0d684d50b77cc97b4034ecfd11a059e4e91e5cd40a7a78276330ead47a3a32c7886b4e3ab94d2978ca64adde5453ebd46df2f766582a6ae39377da521439479d4e70f03bb70b101a21f8eaa988843762525236d4212d1d31785f3b7f16911f897a0b0d6c4acb63fe03feffdfbe821c0d908bdb83813558b9db6253abec82205adcfe71e401e0897f30f3fd192e534f26736359ab24a959baaee44c446eca96a1729e4b900624533c710c1a95314fb106f15729dd62b74b7345dc242ac46ad0114bff663fc011cc2c16dd093413758ad1246c435c796d434123d5798baff894a6c60626b60750c505840776e32000f44d18748ec3b38dc2a4ef87e1ee4f130e2768b38d45eee75eee9d7faa68889bf22295914c9b43eb80ca335ef4a09e841cb00b2ac34573b342d4722eaf837091d6b4220e1263290f006c2500534ca478a29504aecda8bc7e1090fd63d81a9815af311f338f49bffae5f206385e2bd2ab9d6ccea77fb1b1263ecb428dda194dd756b5fb13ce1ae19532d41669cca28711eb44c86718bfae91a382a1e8ca4e1e502e8686533c04aa4734cc189df5c12594c96eee18d21706858c350a3129a873f7c936755e8ab373a35d90b2ef271673359fba688050318a9644a66737e2b66603097e4005e783656d71eab1b5c79c7dd21453cecaf9e417534333e3c4953dec02c44da472495a0086e29a017e0c5fbdfaee1948d5e4ead29c78c52eaf14fafdf09ec09c7a53a6a8773cae0be90d2b75c3be34dc3c36b6df59dc148c0163f3480746fa027a32c953d04996d1c8beaa2fed6c835c9a56675d1f2a24e731d8cdfc809f20744cc0c56fb7e0139769bd057ae106d0487954bbe51579cc42b303df1f07e42ca58a41714cac5d669e43457c7c387d3fc83975088198b395fd3b4965c42c7b0d20e2d5b231d03ac30961d6b9fa1d12e73b7078799f8412ca3021b4045e3a6b34c976b281e327155f67e5d76489d4243eba0150d3fc9af300926debb7d394b6b121adcbc2a2351465ad06b497059430d46f970d0475cf3c8d605c16094316cdb2c6f7f6a6141f4d5ae01ea3f476502bb9fa2bc04fef37625d89614c480a3732cb6643b984549bf623d33b5ba9fd50a77e8f86edbbc83316810b0ce86f4cd2170aeb9d611ec3d8c718a83c7a20b79dde15dadb7530ded64d4b5dcf38fce242582329f9d6b2d70e7f78add99abfe700b3c0741d6ccd0cb5a8a5e913724fc3a89ba16547d2b3ee0c48e36c1a5dda14e740b8955e03debb344bfccb25c1888524de63c6804b546c419fecb95ea41ae7324275ace92a99695afd356abf5c32d432ae104654a61ceae1cb409c5ec0c6e13a513ea6e67de8101046365b749c25d29e4fb1e193c224dc03ec48d9aad7d9687478395062766f1964e7f75243c98db05269174f145149f816113382d8bf337d028b2ed03b98449e48f1c28f3dd3669d9c17a8a27fcd18d28abdbd3a5057f054a8746ee9fa172a9467a1e7941aefa9f38790b2878f2b85c4ac240b06d9019761ce37d8782db30fc6a6ed3094223a3b96efd290ccd85702a4ecb8dfe069aeee384281f705c1a1710fe9060439b05df3c3f7673f38b24fbb9cccb87ad2e5dc84a75dc77f2bb03a4bb700ffa82a017d09b48e6e1373015469c09357e0894aa22d3a0eb5ecfb078acb222d004e8e1b3f46652b419bedf149815b8cd143402f70220a76046c1c3cdfc8b28ed911a6ce754c718c20fed989007d07389648f2e4f85aad282f0ec26cfd5afdd8478320cdea21884a44e618d514eded2d18e5f51b7c7cbbbeac558751ea844d937d7f1c7664dd10408aa2b23bf87dc57f8f4cb64f04bb2108e6899ef2f7b2e449f3e429669dbd69c5ff705ec8d616781a512a602469f1880c6ac596237d602ce35fdc4d9021269a97fb8074c890fd117dbc587d5ac360906cc07f799d3f17abdd6496cc8a9ebaf5b8c2231097ceef6409e63f2a25cbe306f79b00ea9bab38bfaa9bae97b2a14f6a50fb2156c9331c6dfd2950524d1c0108dcf44aba1002ea6a1ea530eab216c731131b482f52ea75415fe8eabf4f11ada7036dd8081523a17b6010b5ea8ef0795bddeac1e7f42d710371f00d881eecc0d7e8e0900f02927764ca33070ebd12a841d6d3495b380a2fbc346423cc4b11a2fa1021bf567c3a8e3e9ac87f02cc16098bea6ede1074c527dadc29a80ed57ce3eb684659039462ceef603a9ec1dfcbc26832f5e3a27c3b7b8e02b297e8881d9a528a02d01fed9b3c1f8792a5f0570c8e261a5a29713bda9bc0fa4c9b5af332d0bc0988a883f9f1dd4b1e0238b7aa34aaee15f23a90849e7be6af8919888128abd00afa80e839852b88bfa0298f878e0a62a39af6140ea1cda4d37c8baabaf07498239a04deeeb59b8b7f8e43fac96c7e3e11ac7d6fb613d26643189e8c068cba9ac075ffbfd3ffefa4c8f26eb34bc914384b07aba06eb957a21a02402ec0b4ca122d3d00de6c16bd64b04d98ada1ca2c71bf3fda34c0cb603558337619a531f4e786224777da08fe0e54e083ea0f6a48c019fcce2edc4732b16aa203c2dc77eb7ff6b7047b524dd9bdb88b01fab841b4c3cad0ce22e7c8870d31bce93967f09583e635de14fbb8a10fe95aa6101dbc5c4c3b1a7a2722cee3b0e94bdf39ee8dd9608e6e22e92c6e2262907f72f0a5a2b7af8908ea9aa924e41d13cbba7cf1ed1841aec16051a2faed66cf96713f9b05e502dcc5722485ac11dbc3889a08112c5f6b8e72dd57905ecf8891d98ff4fa615b4fca0fe93f56a21e7831d0a3eb363d5ea20b2120942b434bf4c3586b3924d375442c59411d8f91790a16ba8f2bf8322b8631628b3cb201b08dc02eb2f54fc6721cb2beb47ff5f62d01ad019177dcf94bde373d58991cad74b0b37db45e97f03765eb7f06e8641305519801e46dd422aff8c65dd78ce8dc2ae80552e658876613ae24e1e082943fc6ec1f53ebf60bf8acde3e5f9ccba39f2e443c190286bb4b526e5fc38c69be2abd470f15e3505e9f9446dab80712ef019abbfdc16a3d5b818225313471c0b45314fd9706126bc85c3bae0b9f7aecfc80c7ab898fb4456797e9a748e94dd08ceff58f18441e8bd41df47a7022239ffacad6a79325f9421d08f4c81c621fdee3bd9185c78f1768aae42f9d6e74c5d4b33fe454a754ccbd5feae7efb687004e569d79af6cc538eda04341dcdc4c140e22ac17b5270cd37b712b6195f3c0c6c299984e78aaf3be5d8dbd785e18b0b58de4ec46038d545227615983a5ba217ab7a0d400b1624d9fa254b7d8e092f06646c9ea557de72b8dcecda8267603759dc58a7ee097566048cfa4580f790b0e9c2a8de1fc05b48ffaa20600a10388a77d44b4829569202fbe10e6e54dc0d4c39642b6b0f3253ef7dc764c896d897a0ac5ce077d7f2aecb22416ec44e3fcae0cf99f77ecf9e3aa85eb7a50a1bc5a279c40a45cd0732a99fa967fc870cde5cd9865a89362bd5af786349e737b70fe5c54f52bfdf90f829a78072007880b2df682906e611ddbab939104299c0bb78c182642f8909a93e58d3d56002a9242259e0a06a674af7854203f2ff8c55b8f3c911a140630ba6832e7ced3799fa6e2e4f7cb6b2efc26327e028aeb52865b8328bf2745145bd868b7b5fe7bb1c03bda037be8b13faaa9c9da5db6fcf055e7f0fd59ddf66006a1e2b33a815bfc0d1ee7df62545f359ae0a07e001ac56b59a019674b2e0edaf2567a35abb0b40c612f65c21af620c1a8783a09cda88c01c908f688c893cc0e90f70bafdb3a80c7dbfcc574e0a0eefa05637be9d9cfc8856527a829b0207d17ad486c881e0c8074e8e807734523d403e0c4e7dc0a0bb3eb84aaf01df34d2c00069a8d3646224a7f4bce96804ca74d02069812c538bc4772b01b63d1895fb7e7a0771ca22e6efa73d2516251da333310f095608b9b9c9a0f8d8b808268e3d710218289a1293df318ba543521561fb57ccd98eef73e7565c362319d07b57a5c67df699719a4ab70e51235c18d59dcc014df08b1d75653369dc16b7102f4cb534fa828efaef19eec0df9f10389cbb233c06631ff5eb4e25547b21bc5d25e09aefc978e98a5af91dd5a748431d774b0a1d38423d271da3a9e1731f858cfbb6286c152241a667b723024f135d2a9436a035c5633b420f38175f6ecffe8ad869a56c14c78f89712fd35c5357f71bfbdac3104642b5a62f134e7fc8e9f047dd925b4d0e9a709172ca6cd3c344dccf0b5d17f7f882e2b5c81c570bf855cda92d1d97bfe2f103ee264332660fa57807a58f9ab6530c7b6b984bbc3a7daacce621642513e85f37dbcd421e6adf5ae764b9b64c2fdc47187192c68f16f615ca7edf987d117739dc7920de9d2b7f917034b37444f488161133bcb609a6b586cb32d41817cb502f42c96ef625ef6ba7045cb4c8d1c10f8cee86805e63056848534e04b01889d5e7614c1c1d87f9194044906db2bbbcc96d88cbcac930bb02a56de121a107b51eb67c86d66db7b59879ed79faf887449a34573f4bd38525acd4a355852e0e6328aeff41343a7bd285a9515cccf7d27636e3a0f0e755eee1bf5d4c8a716e9212a7d36bd7250d6255d7868f75ceb2510d8a36a14d2abf7abc0bcf2e33585cc2bff3784b890f78fea584dbd84d886ceb93d8a1cf6829147f22daa19d85d5a006e01753f484a99461619a567f1729f286b51e8d3d4205be768d22ca07375905853e5cb8c5a4b3532625f0bb4a1563df02ad233fe0f1e3e88a791ec4e0c07e1d621a9f052c963aa6dde02df6722649340088c26c83ebeb53c49473d0822443767526aa422afce8852fac6080dd90ed81b0290d3f1d8b8e141ac258c26dc469736855636f63e0f251fa4184678bb039ce0aaf5247a5aec47d93d17344b0d701a1168df0926e7551c847111ea00f37ec79d0ab674b5c01a2762198df803b0998561ff956a8114ddeac273b53c808c5774c632e26a1344608e71cd720d901db9334eb6e36e4c27773d9cd0a40de072cf3bd71afef9b1bff0d01737a8dab3ef9dc8cfc89956dd50e5eea663b7e266ff042b22ce2add235ea5628469ad7b50eb988cf020d80fddf977df93f1031f74994cdb4d88c3310197406d0fc1379e3b91421596465040bd500e275b5ef1f77b4bb105afc2c4684e0c6d6abf6227f48e8057c184bf7313933141581e95489902f6f0ea86c643d9ba018febc98694093300f851d8ff52817f69c805c1fe3535bd9ddbbfc400e3c217543950a5c3bc99838e114fd55ea9200b228bac4e9d20d87c15564f00d143d1e00a45954053da15242bfdef7ca2cd69ff60fea8896ff9a4616d6ae84d9408ab8733a87a5e3d642e6bc92e16ef57243a359e83c51d5adf6cf5f51636c9fa8ecac699b2ce78669db8ebe04f43f38bb53adfece5ef666251bd4795bd689716086815ef76c0d8d228343c097efdd4632555de08c69e98e2f91738776ef88d203adf3552b503fd4381385f9f7e7340bc8381da712fb952709199bf570b45069903c77dcb608526e8882724dd1a459affae4d999a1267be00a1f2042ddd899a028be5331860f9b39d001ff509e243d9e636346ad4189c4fd9351d06d4ba128c1c4e91df7f96fd71859cd07c8d378927d0d1040a31184a141722cf8e96d72cadbec660c178944a7106cc3a1b97c824c741f33d137503c1e55575d538db5032717969c7fdcf89d5faa692fe9016f1c7b7477185a06ec6ed03a660b36ec115825628b22f8621fe895c04e36d6f97fb523295d70a2eb1ec2a1c5f8ec2fe9dcad70094b63b890b05bcd173407f092dc8373f25c1420ccde3bc5084c70d5eaf2b2b1995745e4cfec75fa6b882fd09c31e5d36e2a57056efa4d475bc18f007891f83337fd5a9cf262daefb57e56d830562622265b29067fcc42e64867fc71501cfad996841e60f10244b41ee01622fbdbc5615050b9be2b08b4fd7e4f6c06227f720a8d02c410595ffe8cc4aed707f022ecf917284a8d3e871c50cef30328f69c5c526138b14298070215994634fef1cc2213713e90bcda24767b84172513f066652b9074f34a0499a6cd0365769c1a3ff5fa10b3380c970adead64306c51cbfc2d4c44c8c6f2776028b49f11718466c3861e40cfc49a1860067629f36d52fcf1cb222958c8c65269a947067662bf24082adf5d0f3fd9d34938be4e22e1ecb8453df2dfdd0f81c3c52ef28270c1b08feada6f9ec6ddc177b2f24b515021dd74df595bcc35a7aa154bf6e770161d2969a54bee6c3dca42d7cc444372da1542581e840c4c729259e51fb6e753fea441b6c4197cc6d4d57d3b491d68e8e4ad2a8f4d10f99b930a28695aa80c109982d1540289cca45f7267699ac0ccdf594598d370b185a117ac3afa9764d9525b550d12dc6f2143d41137b21f1ed0b31fc430d934ea2a938fdd60ee85c742645f24c6770e3448b59e7344b6a561afc7a76fc1a2efa8da16fd3601b9a6843fc83990156f6746e81836fda5fadef4c52eb54da10792a8e6048592d0b5f7cabe31963ef48b4f0c68b0c4b6a729de7030fc0596904f1b0e25419a225f407768e8253a989fd4306fd71001408f80beb6d3e7bc30755cf9ed10f0a515cb8dac5d4a0939ae50fd5e7fbf71e0fff878bc88e040a46f7c47439f9dc6e9e8430572da2d4efebdbcb59a7df4473e9c6015a84b742c519a8b5b9933a58135dab4d0feea5f0efa413d57737b3dba0de981dfdf23aa51e08db8aa24a7d68ad2caa1283134045f444ce97473271c76572c90aff2b4f10d006149818047cf2a900ef0ef34a6406e1bb9f5e438040a6c27e2ec197c2357c8cec32e231abb48b20407994403688940c4b8d6a0f8470ad695d24aa00c083992857a00d5889d73265894a0307bbc546ba01bf17feb60e2dcf4123a721da5d59f5a47e0d08d949d19d20c5ac7d694b6417916501c89fb0518b0c5ab0be8b3d8f60f15eaadb2a65511273255853cce06e7616db6dc48e79c06e63492d5243690d52ec79a66a0f1ac65d5ea2737b324c0a8a1c72a12768e406d54f8fb5419387a270c6627bab9f3f1cb00774e639333d696ebf6666699a574a283270d17d05d68c8e2eca900eb5e72a7d0e6dbb5a7b23d4c2e99ed7808131b5b04cfa281fc0d38cc5677e55fa3eac13ba2b325f887698d59029138dd3afcec9f950c6578e573973e04e6302a33c7a0a0d10544ea43d5f7eb5b5badbeaf63d4fc2d636e19aecc54ec6a12048226a878b66ff7e35c114c438c0423982df94ada9f80506e3aafa4f90eee5220030d15b746d0ab45b37ed63bda7c0e7241a84a46d79a6c5bbffac788e9119845b83364aabd5e2c1fbb8909f23ffa56001db509ffa3ca57da35c7ccb14d1ad21f89c1735a016407d60518c5b6bbce4e79dadd126ae0f883d80723f9e2e8ccd75990b80529c04ff568059b527b5c82cbb2c14851e7b252464cde9531eddd886ba096c8a904b516ea01f06f80e682234a1071722cffcff7dfafefaa73b2431b31e88271bb7cb93a596e48470ef32d4bfa7486d904fdd7babd89e1756b850ba6318c68f05ef45c6b92ceb47833f2f81950a19ff39c0f1042be5a442ba6fdb738580713b0058618b4685e081a32c8208eed57d50fd0bf271d721eb5a0bec1e753066be82714a0b93aecbb729d0df8ea368741ebec11781c067a6d48821822b370186b2e1e6c20e7b2c4b0e55e7d6e1211a3fd6fa81adfd3a7fd114cee79fd75c7aea2dd2e2aa87632840b2c75d13a4631a87d73c7fed14ebc9f4f604d22c1408ff7d27504fe68e4d0e8860daff1b9cfcecb29a425a63e004b454deceaf5f6e94b49fc775400f1ae021c6b582774c18d280c7cf6732e455798c1f719a3c42e6adf011716a38deb6ca293a57a1d4a51f9412851db92d054f22edb91dfd62e6b52be3a64f92521238d6393565a46cf0fac72f38a3cdc2b60a6ebb3eff89b1b5db544941b46cf64d68ff555c8653cb86ba6753b3e3e87bfcf62aa140be722bc452cec56fc8647d8b01edc7071ba5a04aeb598a2eb5067dc4c375cc81f553a11d586f9bed470db9916d6431708ef4f3f162549b0d8192f36159f20235cad552e822d6f27fb9ca14b1bab94dee7cf81be67aaf913eff0e512b7904afe179466adf109bd74bc0c105251b91557f050b13ed4185b69292a9131b03298da5dfeffdd8be5dda7f65f838d0b6fec298c8c445dfe6421afffc3ab88207974af4deac3c9805243cbe41a85cecba93f8ab6d2ee0a7cf30b091fc739fb7850d190a7289a0c297207f87b159a0561d55400fc6de42bc18db19b0673d45d1fde93d6ad557011883186c0c99f01439e51a213fea6958e784b5d7a89b74a64910c758a38425b9b9e6891c32665313b825909ce7c5cc3498b061edb562b8da00b0d94e3112051023c63848087e41cb9e9d5ef30e6dc1c772c730e92c36a00fb5a76f3184113b3aa680459b4e4ecb6575644e27144f46c93e9c2bb359428dd05fac819963db353defac9ba605f6506ebdadf953895a60f23cf55c2ada02c20c16f4887385383602b23aa16a6b75940d19b404bbd5a2058905cc34b70dadc14519a119bbcabd533f47de6f4756944966a96aac379460aa55231692cbbbba35606d037561a4769f19962d01dd2de5ff4b17dfbc4a04cb20ec7e3ebcb0d8326e0d77e9bfb3ec0b17dec52dc2de60b47c1ec360e0162ddfc82018b50962a7a7efb97cc038347646b2ef453c6af4a9d3b7c9e0df8a5d9018dafeafae65d8b6022d0400ea512bb80f3a3dff9dbddd909c792d289fffd196ffcc3fdc3ed4597e182b1cacc9eeb6de434545066cbdb5fcfdf0b28205170da8032a104199b5451e6a65ea15c6898e681531dd096741dc3546f6fcac4cce11c429574065544d085c2bbc02807993f386b6060ee0b56caafba312fed026f524ceadfc55490d8f41160fb4ed3d702359b320c0ca62944a833e344a8d24079ade725b853b3ac979023504cda981810cfcd6b230540da59783ee0cd4cdd773c16b1aa68f52bccf825fc6bf701c73b73522efe067ae4762dfbaf4b6823c6cd7d522a9b84b597283cfe5ba748c42c1cf9227d8a28d37be1843c54e91e2a7fc5cbce2f689a1b79a4d88898f8afd619ee6883752eee43233b12570db76eb9fb8791bee3ff20c7b5e77fde9c64bd8e8c3146850cf0bb81d74f72ac26303a866811da35388113158a891cc2ed6746a5581aa163ba9c736031e37b54bfb6ff00b424e50102554109567aa16b814cb4ee905800c820287c1512bb241da79cb4f5eb276579a83746181a071f6215b3bcdc90cd057e17fb06e43e19d92ed01df4101d43306b60b4aabaf073e4d10a7844c0d47ccaa06b30fd437488921521de8d354da6d2af9ff5873e4ab190cdc9445e4d629b5bd56d866a7d292256d51804be07f35c336a2a53910aeb12ee3ca68221e00d3909a87a0cf76a55d4140d9c5701eaeb7d05c2475610268207ad0d674f56db3eb62d8e89d800655150174b8a4cf6c747124dc15c9798e5ba0dd62a04e8e67b82f7c950dbf8af6aa9197382704a911aff2e458ab934fd7fda4a5620dc02185e972c93cb2b8a8a8317fdef0a9e7ee03f1babaca7760a941114f43c96ea71bc00f532a6dd63fb497aa8a4421c63eac8ca722f636a27cbbf94ac3a81f000ceb3b97864acd43c2f07fcd2b55c30507b2ef1481f6387c33b5902175de5b8baca2be6f900af631c26ae1c93ad9404691d337188555b4aaf9a70820e53ee9caf1b2f284f62908287bc1abdb7d55357006326a6177890a79642b0a270e94cd629d65e0a1eed0e8d340e901c3d720bdc3a28f01a1876e26db30e0d0323111c7f8b0bfdda65e88a6da16b9af2938582a1a16e9f8eb054a01a50ecf05b2dc5a7619aa6249d865974dfa1f2c69c5524029eb3a05ff382b2573c30077485397975a9e6bfa649a4a8072b7ec42349991b30328d330c6e111aac471c664210ca01ca57db6ceb3b01d9c3196140459b42f70df7bd24d1bac7a753c014e3a407df854e157e11b833c19e613ab7e7da017e16c1ac9bb1df67236ab56c013f48504c3b2dd19931384cc055fddbe83351d074af7da1119538b4332be2ba8406ac94c7cbb2c7e98cb68f08265d17f94244c0dd88c957bc58cecd1313bc1e0f1e3b2361381f1b58920d6618890860db7a321c8724c41d826facc5c56f9705b41d3efda5fbe0f7ca3bdb93099250e495136d2f8211b88202684749f86f3d26820c6c7b0c367a1ca3dbfb31f80986b1c3389b4872593d31a84e6a25b131091974764e01452fb5270637e41bfcc5aaba6632e164e68a2811ec5d17f6b94cd79128a9512b3f2f7dff1f18132dc540b36f1f2ce798daff58ef873e1209e6e2ff9821f26101241e8f47ba58c52875d6ca85dcbd1b72238b540bc0a9c4c41ff33868aa0822c70a8870b08cb5d80914ef160a3378da4c388d1a7335363806bbaf1b0e9cd689327dddfdb327b894b091457748d3dc30e605d63abb2ab27606473b94801791e3d9d0692782546ec582337c490fe09943d3e99e46371c1f788810f32b94acdda5936304a585b3d8ebe64092d1b8f6249989785cf13c6ea70bbd94eba8f281e38bd796c424dbda62fd2f9801690e16b6ccd9b3ff9ae9897b245294ccb71f25effbe4f0256d3f514e532794e792e0fcd5b017a4a02e68b86b0d22a169a1d42b7e20da054ba4f8c4d65fb330f729231de9a258a44895c2f926e4b9b4d16befbb2ff1ae9147cafebbe32523788f504bdc1f95b9f0a5e87423867d9e2e3ee6a44211021d46db7cececa656ddf6338ea0c77719217f192881d7cec3f3a26eef04cf2b1937900bb38f79f45bc95777bbc11636232d8e198a9330be3ec4b4677afd2342b98a22d6285279b49b2f6372f259f84fc38536f3900a4d63351744894b4ae9825da6ef650e1dbde149230482f64abc1250aa1c51c4c304db7323de36c3e6a78de0a5fa496246ecefb657edd048221be03d15baec12e72e34a1727947a66acd961c35368361717ecf9177ea0f15bf4eeb7c60aa1a5baf6e1b4a2445842cc3f8b2078b62df2424e59ac2773075a749661cf085119f8a0d997c8ba1efd3b84aa090b4aeddc42c730500d295c1462e993c7c63b338402843a307e16b2409a6b4bab98505dcd4e53ce1b339ae071f938aacf44853dd9b66c17d5a85e81baead308543ee1e8a1b64badc316b1a0b250d36b5a8c992c45379fda70f3dac5382b687f470b91640b2aebc55cd681f9f24df4b9da3303a61fdb1fbfb1efb93f38193c6d08b48d0946a2a7190202d08b7f65eb7fdd1567da5541540bec7314a250e10a1b2d4b476cccb05764acd82858c857392f532b8eb1de95a82c9df013709342ece1a1371c210791ac5b45b70e0c3f0cd0ba6048e413dc458b593450e32c63edce10ac9ef21ad1b4dc825c1510c4aa3278bea3e8bf7b9893dc9fcdeb4a510b65679f608db85940bad7071b7f83bfcb61d08b211e05b255e8b022ee90812189a69873934cf8e94f469cfc7a7488d51132ab8ae55d90bff0d5f9370ea6dd847c4f2d4d54c8fb6825004dbc32d869a056e9cf3cf3d1e0967579520e3eac734eb2621576dd5ab1ceb9fbaedcb225468fd3df2b473abc7578dcc33786773c1da1ebfe2d2108018ae2f93d957f72016bd2fa30eb64c9b3b9df3046edb284a9e86523040beca619afbfa1fe873c786c0f4d1afbc71928f58fbd1bd3ee2f1ee929a5181c64fc24a351d58b5567b4cfbf0228ec373f0a15834f66191bb7ec622ba406f58ae6ce5637e79d7bc83c632350845dcb8fa14241ea1988f0c41ac20ed17d3ab20e5b721737417532e98891c164717f0ffa66b1f8473f8bb8a6d5d2933cf26b46420f794acdd8e904e22fa4cdb530d8c43be850c85ec143b21c3a6faa21bd41078a8e509e9fa09fc48d5747f37652790bc6f29b60adc9f0faebe7ccc21a69670c58023355c4da98852a2f9ed027db7ca2012bc6021ca6b6fea003423405a3c3330803e7f0debfdd0e7a568ea4e9ae51e930dda296f42ff213df04fd1a5420e567125d4f27dbe5adfc67f4e8544f78a1fc3c78507e5292bb970d1be158484d394607000656bcb5f27a830ff7cc4fdce386ab7ad67147cbc66fd57d56a909c3e850a4adbe8192bd1567310673579364780f5d7da7a17dd2ad247b35580961ee44d288d14f72c84167204f455490aa47a39f955b56be55068365f87bf1307b3fab238801fb59ca41283ad2c16f85ced17dec48590f925ee84396ce2ad70ac400381ca959ff1f4129840a932daab92112788bff75cbcf97abe50844bc4166fbe97b7922617b5dd81a91b9c0a8f46823cb168a75b5eb9aaac37e6260fc40fa3afaefaa5bce19e43d1575e4a0f9d332a29f123aab1a590182d7dc1c5624de05d4508acee1bf9ee36d6a33f3385f347f4a885be7b31e0d4a6bc8249a1641eb43f1c1e6994a2ea3b16eebdec04acde26a27d6aa9d7d0339968e7c8721729d85537e38118519fae8a41c965b23c0b7f5c65a38ef79dbef49cd8f975dc7f87759560ecbcc4026540d90a142e953e571f25927fffde1891b22e3c07c1861cf1f37759230586b499a8f4fe2fa31f5645eedf1841ba6527a492c42d6484b25b7e0c2dc4bea2a70e13459c34274e33def0535ff417a851539ee782ac5db3621073d814cb7acaadf1834c73bb36801f802b4b96acbfa4c5004fe59d2bd32a24576cda0f33b41fdce3ab5eeac4c47c8419b501e22c94532c1899f50743a4adb682ceced311479af705b43f718e08946112c486232f6de6ec16569d1da3ed57174bf973035b52fd4d780b3262a732c1001c35faedf21a1d691354bc3662ee43d9453e5d393070d32b7c62b9f14e0ffb845a6d0e1eb2618d2e1b91d20c36d601620d4c64fff067b9c54891e30824e5f77c1944e8eee66d624d69e5465d667c326a9a8ba9a2a3919ca3bcf9afa0d70300337a9a109c3b77e52e07420b161cb735f8a55dc7c695ac5cb8a2bcea0365560c74f8160b10e879693db13a131f9cb6094a16b4076ba397c4bdcbc011189a6dd73dc7e9483a42ddea5ac11a7b3c0aa9655150eba55a3ba56aba086b51585b9037283c6b65955417cc8a6b514fbce1da452ed2aa0a83fc019c85ce05de6900191589ed772623ad73283a92fbb9b07299c89dca21d452b6537a695a55b286fdfa2e37eb4dda913c7cdc96d8042659533c9707a72ddf0bdd652722739402817887bb96cd8ea77fedf9da12e51aeb58e837b41002d4b7f563ae1f07f355dca70179e36cc41e55f0fde64a823708ae088a69694d4cb5db5f756a26f21b99cd56fa04ed050dde746f06162869244a8605d766074d590e3b5d350f06b68d731be29532bd24979080d78aac31c207fe53614a9e74cb36e5f8b2e5a41bbfbe0783004c77a0a649e1ccdab450f1544688da6ddb016d10a819c2793158997924ecef636c34c36427c29f0648423a59aa0ba9860594c1629f69a5039731c898fda902e17f5ce62e541b56a84c6917cacf72cc67a137ff34927c58ff84b6c8584c68141b6d3fd3a7ab403ecbdd08dc1ca63d9ddb8c2de8e7a9fb6f625140dd123707110a326227ccbc7842bfd5aa9ed027fc155a2ef8da030a6386b3312270f548eefc6c88eb20f5c46663795dd9631dbfe45575d5fa9035af6546b47d679b02036cc01881feaaf032c5b23241b675b41801d8b37be5a8961849b9f56c79e0bda89d700f529926fa3eab15f7351ab8d67a5fae2f6a71630667ced0ad0f9d5a754ef5ec8045c8dc438aefe8c0795557b2db4a93ae0b410281acd793a37b0d66697e15c1ad2f244d537a554bf36d53e160aa8ee9a77eb2053a3ea6ef5d435bcaa77ea8c29e9a373862d17038b3f41b7e342cee7b9e180ce21ee0dbd5838e7e989153353138d77d4903631410ffb91777db7f5b9bebd5d66aec6594aae2ef16fbadf63cd0ed9af01dc57b02ed7f489ab03d5e2eba8caf5d04d511840dce48355be0da1c8c5f65caeb8149a6acb1b59b50a4d8903868729d148e8d4274d7e91cb16b59e82ab10c8c3d714f4f54926c3ac55eb97b72d4ba78b72815187fcebef017dbeeed57b062df85b7df8f28348760806fea24f8c1600b6e5c9ad7e17e32cff29d42cfcaec2457f856ab7f30cd1ae01d321914ab0733a8921566407954b9fba629c0448a6ccf3187fa62750b70c07d89db7702be336f1001b33360acc7a05f2cc374a4f70ad15ff34c52ded921bb5599e5b86ebbb1e41b3117c465946caabcd25666fd1d7edf75c0706e2ab513775f8c8a238c49eb3b0e9c6ae3aba42f60094b7c7cc8ec07834d272dd997f7f44183bab7f6f5178e20479b7216729750a18ebf5677e9a1319e0b0a1c22d9fe55adc259ffaaba8f34f3b131e006b8ffbf47e82d244a6804293a9139147953c8171e7b0be689c35ff633e54ac95e6719ea7ea5cfeaad03f31c63a8dfbe06578c1abc8569ce1f9a00d1ef61d165e0d3e3b347a0ce03d44f4335074d86ad6e6a40f692d9415a01dc76a88ebc9030d41118f33be2ac3146de9345858c0d06ae288f2a7b7ac75eef79d35c84d1a3fd42b5cb7faf16a2a9eab9dcb33059ab867ac513bca348e091af38ee6ed54de90dcac28c86168038b5f599e713240bda2c40402984ace1410fd9c8d4e8fc31570865c574290a98f5768761ed68258807aae184709bfa986db86fa690129e9305a74e884df6c5cd5b45bfdbcca3aa3dea13b9b8e982e1805d21044a969a370889cced618bb32ca38ee18efeab32246355104e21a51ade50290b3206c8cb419c844ea497bff09863dc0adb8f5c3a025dec5e51ea3eec5f3ab824a5955cf590db9a875f9dbb52e735b634d8cfe5f28615474c354f346a0bbc22ab5dae87da94742ea3e7bd28a3aa8f7b0cb9cba91401092aa77b608d3518b2b04a7f1e93e065be6ae931a0e7a6eceb93ea78e57788bfb59d3b2b45ddb286a513fd0a48103ce416d08dd331f771526473435079441ca0a060e40f393b4b3fe77e16b8d6bc1c94b0800756e852bc0ddffa73e8c897dfd3c332ba21c507aed811da3d0be39ff6597a0fe50135a74eddcb7c4f68c863cb1837e4a208af34d561e0d84a7a45fe854b961d0fb1492db9862ac80f5ee5eccac19583283524049dc578b0b8284daec6181e1d4b308b1500584e5ec0504563a1de8fc00ef25a685101547a2aff6ab62886ab5811f4fb00e2005dffd74a21dfbb8debd16188c701514c472d12ca0a93d5e1f575d02cbb6520077f997465f797a2527d4c6dd28f1d1e98419c45d76b78f2af5df5ed4ba5de31127e4f1056f075a72f716d77e2a8d3201b1dacb59d22a61ece1ffd3e3d8e1b87e08fc7890b850fadf1334853acd03b1feb2f824fbc771c050494fee381c7542730b597b5eca41af19d4f9b43c22cee22cb27ed6ae5e0606f772ff849918b7de30b08a57bf21a1b89dcaf66c999507d032610e45d5094d913e842a98144744ccfaca195bcf61b96f9a5b751ca651d0a4af77e835c3e09e0efaf6665efda482573842bfe235b0ea00437d914d93277f0d76c0c97a5fed00b014560b27cbaf94e8e2b343d8869d771c9baaa7963a4f769ec11ae617228b5fedf936d75b7fb9cfda1fd0228a066cddcfde670fef4749f7f3b5ca0133893db5839bb2f69c9cc42d0d9854259c05e179f466ca8f15d9ac52a0401c5d4dbfd1606268457b7af377bdef8524079ed339e267ae1a65478999821828a6fa57108ca3a780a382a55b0558c3136e3bd3fe451731eed7e855d713aab78e9ebec43e6310ea79c7a10ccd187c86d35e9deb96c5adb4826783d21840e3c36048b3f2f96ccef819d125ab0ea24d9807d0535f1c855753cfa7def4a2863a8be3d3d40cac6055abf27b738bdfdba734f729ddb8f894429c05ee3efe25bd1d030a8d5a8e78e0edabb5d667b9d2c5331727cf167c6d5058747388a59844f0157ca85c4730251dfe464324010691bf767e287b21337a01133f1230cfbbac12d43bb40967f3775306b13e6e4fd7097b8694287d46f1a8671fa20cf33d51665f89de15cd6b8d4362574c690ba57187839447c95f69f5120e51e4d95efb0760bfd2c4c8991e1a4a8c0b79d1d614ca444c928a56675ecdaa31aa90931451a4ea464984691d322041bd05ebc8635900f4447809e503a112068034374f2dd364e16a95b85ce610786446efa473d9a0e350be60208cce974a09bb991a6406227c92711c01c1106ceec16c7ef1b218d0285bfb34af34d7b8253083eecc5360a820daa4237e441f071fc464fefd4b27edb0f480ef192ae587fa99a805045574ad5a0dc5149808549b6bb7d73852040dce7cbf0ed5f0721bbdc5824f56bf3875bd756c258d104e1f36f94b1364aa26a2e49ce0a11c1fb9d5e8dcb886abe4f0f9d1f27c0716ed71b1342b3348a599e422f56858ed5a87093683a82fe03022a95e4aad209fcd48eb1059091fa0744853cd044e69ba6c29f460e9f4d8af0a10b7fafb4f5c9c70aaae6f688925618bbc27d09cad29bbd93c37dcf6a3c9ceb309efdd0dd21e25a83645fbbfb2b87a7e93407e31264f89f6af4ed3e4022f4640961cf9d098b56fcb129cf4971dc3b9b8fc70eccca2ef332252979afac760e20af6cf26c6d09b54b42290f17ff4a9eec01dab5aa5d463b5c55573b9c7290ee33b953cc781fe99c81154fbe121e5e66f1750d326827c263ea3a9681e5dc0256d2a52975d400fece0314c8335a32e59980537ba80cf416b433dd6b9df0314bebb17446d0646c629235c5c6393d1b0d157094a1cee84bb1aa393074dbe4f16852fbae8a09db910af7a3bd2adccfeaf013d98587c51c78e96653539b62d4c636398491758c1746ff273716d7e0d78e63aea748bf9a48237a589d9baffe2fb64244480a4014e341c969d8fe6077cff35c998149cea5bd1706c6cfc2de6531ad1aa84ecddc68ae1c37360b95ce355293b8295b9c804f72c761f3b57ef2471fc2e183e90d14afdc70c9ef4e98e0b46643596e995263606c3867f45daee83114e74e50c3149d69fc933c0ed990789aa0b71f54b1c5a01a8afca063e29f4152054595a21e101d395a491ee8c6d9bf1d91eae4913a09d90910ac0513b10b0fc6513e17f96584c7d9cfa6bc86ab1ed366df18e1b4abc30d0efe08f1d3680096bf9b376ff81c43d04dd4cc802601329b3b26b435d2ec04c12fe278c66d20979941b91ab1ac55ace047b55014c0ede4ee29d0d99086c2821556f4a91179d56cd5ec1feaf0054a9fc0ce0af4ec6c917f156a639d91629985b13542d569483751a3cc134e22d614e84dd2049aab3ec31297a79acfdd5b2e77fc3b287baccee5157fcdaa1a2cdd6614f9db583b6abd06e90d50885a23489e7a9857472fefc7a5c475352a3aa08ad5d2d18845d8f0cb2f8859f2d758f0f67af6116888b3c5ade1e2ee78ced3e5f0bfe25940940b99e7bf1e45fb87f843462f3fbb7dfd8eda26c8af81b4b4ac7160a2e7f887edaef3a81912b5cd859c81e11946c72f6ffd0168437131f03a5340e714066e67f66b2ab2f55ed676e84fb27ba9428905ced0a5f7a119ace3a840a9c9af0d903e399ca912505c12cc4f3e6cdaba7e11bbb3135b4b7e36677fd6859830084d8c4b0e74ccd02d03157c021dfd255ff3537e405e3f1d0fe836c2f1cb4deebb392cc02e6d4c05c2dd910d0ffd18e42f674647bf1440f5166266f5d52be6fd9539fc52d487b82459e73b5e0ca251216d76c69e0fb4c4019e9b4a501ccb53158a967955c81eeece059a5b0207fc28eda87de2470627f8af7185a818b9893a24c81f3920a25e196d668589492cc434bde85ba8926c5fcb23c57f3d301937d59731a0a3d2008c28a5324098b2bbd263c0f9a1074fdabe4a85121b72a74d0b1314385c757be1a86b50537998f3efb14999ab9c69afd4fad3badc61eed9499025a69283ac0bb55bdea481d09ad2569bde73c6f6927e76035ee3a7f80c49cde86b0cff1bdd4cd575391b271755e2eb54e6191c58bfec1961029f178aa74497bfdb42aa6e59bc16d58c95073ac95842b62b46fdcbc309d9ee4b424dcaa48bb17c5dc6240e5b6a2ef2c3dba724a79f4ef1490a8797fad94073897f428eb08cc76b86a6bfd465a694e3d7c33fd9efd540e9c72d2ca80743774e246d1c8d47e55be6853f5ae0029283a522f46f93fdac991513ff38b7471c802023738a479ebd9d38e638da04d557dfa8cd4573f8a3b2a13c19e6baf482e8d9bd0885a58cfbe4dc53c107ac456ecd7a087b3bea4276d52a1479441a00505c66377d6fe693682738494b3af989a84b6252287b2d78fccb585b410c90d849cfe568103712239c1704148bbda4b342fe07a46d7b0cec8046a04fa23ff468c009ca41c4565a93b432fe50b46ac56cfc0f4e1840c4894bd3357726ca7c36ac2625d48104b707e126dbac7bd7b49f8958d6af26797c3037fa6c6cc0346872f0c4ee63a8c76faf67cc06f3dc6800e99bd53c3bd80ab522e700c78b0b1e052220427042ab99e8d5920d0ba4a0789afab4ff41b19c0d004ede52fd750e36730b063c54713c06f4eefc3c7a3c396b6910303b55651867664b102a26208e9c012ec964a317dce1fb2c3685af643016533fbd608ac93ef43cd92bd09917b4b99524a018508f708df0842b10b283f09d80a7026ca1f6dd7c69db8c65251523dd29d47d943e3f628b548130a0df5cead0d2e413be2a33efa78247feaf4d5d928234d182baf073e507e2ab859430d7270a60d30747f770d48adeed3292b7b2c958783e3717b685c822653efb304b304b46ecfc9ee45001ea15f7a3cf855de4a51a5b75bca745945c0e3f13649f070910081b74942ebdcd3517785c242d5b059ceb033d592b5e373a64d15b43f643dff7cff1d9fa3faf8fd9ccaebaaeac358551feb78a3c171c1eb5ab8c9056b7596719c4179d75f1d44acf1679051bebfa68b4625dbcfa06d9a8cf125ef96338ceabe6bc7866dba76f917bb5ddd7c0119be7f9bbe84a9fd1d83c12a5f408698c43bcaca2085294354c608856d9763d1b58ed569669943c1e3510f87358ba2acedb185862e1e8623619eb03d98ba6a079d9373b04b3d974a3df34c116997b7b0b33b3fb118f34ef348275baf7cd8fc77cd196936b2f97d2e6a215ca8aed9a51b165073dd125ae01170707890e3f77fb6c7bcf1011097c054780447e22fdf3175d571aa70659bc756783539292635cfd6b8eb8a2fbd6e5df1d928321fc95a167fd398411d2ca9e5c0f11894443c90e190ede01c600237bcdf17ff8d07848448112335ad5a0384f11013edece710a09d1b1e37b5028e54dfd1ce06a3da72ac05b46b57b833f0c6e37df1db78abfdca95c7a0f6d5782ceacfab292f060d77e640abd6f6c531891e69da9176a41db5f66d47234790340fcfded2d89c9ae5ff3411ef91cfdf4d3be397489123acfa987635d4eab837f9cb27106b37d55022c94f2bf2973b41c39648d59be7a979f871b035a1fdcdbd65993bc0cbeadf1851485299b9b977c025008c9ab8b32c97eff29392bf5ddccccc1f9ddbdca4ca42757021703b46f624c68b538cc98a12121528474c1475868c19d4986804b7bbbbbbbbbbbb628290e0b3b31d37f1c8e9b0c8fa1387002f16e06aea6e29a39400309c6c3163e8b5acf164c46dddc8ed07caa072c3531151173750bac1e886a4309cfaece8b19391b9eba279970b2e0422caef33b2affb141b63d4589aa67dfbde55dfe2b66d31fa5744f66ee8d2dd37c61853bdec3451882863163251926127d34f9ca5b9dcd98948501c1276b056aecb65f4d9f136668ccdae038e893613edba4f868cc2704c945f3291f74800d8907af94154bf3d173fa005536c50f9db0f69514aed555f90f6b5e2fbf8cb83e4d78adf0882c8d7be2097bf3c09b87d12d027f555e9d00534e587bf9ab08419d22e873242640bf59fc925987224c3ca4e8c3136e9581500329a54f9a908c61893d0004510485f286d6962058c47c42f0c1369ac18c71655fe54c30555fe46b184991a0863c450e5cbb83748428818638cd10331c610c3a5c6d805e7504950e26a982c66d5c8a096a48005944c8c998c0d1d8ec814dd1023f38215349119a2c80260c82cc124ca0c2616706a22c3e5862f51646650a444068c1b88c898b1c102543c8911030e16f87284130401c058c2e40585872c4ba0b858da07644e4d929a8c692f64311b906c20c306a2346cf0c42436864912d4f2482d6a1e5f933146c9bc05b7756577a4fa737b715d712291cc51b8fd40184e2b706202bba1090c3064326a46d54c8ddf0bdb997aa46b0b488e7aa3c62f4c81f6c9ad9bf632ba103f5617e2e344fab1564434aca9fd610df46de07098a1494abb3f5a23bd758de1f60363c42c812d61d2637ca006514a9c94c8606d300e1cd0fd30d6b8ad4292daea1a6afc3589732fa979ae72724137c62825ff7e2dff50a0a9fd6d6533a4fc5ce88f31da3e8a7493730e628c51070be87ed27d77e516a594a1ac45bad8b030ae0eebf8816effec662835d3b959fb26d77df9752791dc5a382b92b342a3b78203da68a38d36826ccce58713638c5e39d2a7f281c7f766f6707804fed87275687751ca9e1da3267bf8a0b6ab1177706298b56be3152e80baa9fe3c9a67f7a34ea8bbbb7bb84cd9ddd7290046d058c3ae76cbfc3a64386e1fb79f31ca9f3f5b93114afafaf3c7285beef4246ec2f776c13f8747e09f3bf6c5dfa4b5bb7ffb87ee66f160f6ff68bbda8b3c61a41b54ddbbe3ae9432eeee8e4be3393f8489839cda6fcf693cc250ff9652fe87c03b48000c60445c84616262064668a0c90e34389343163b98e2454049f913ef24452bd0e287a41df84003154f8a4fc2d6eeee6167ecd27425873262ae8851014622ea01c64c51c516269808a20897c1961a30c1c1f184aaa0faf7f6e8da3121ae80820c8c95b07240f96ba5c0fe49aa2bb50bb4c0a28595ca7f02901061988490c2534480a2fddaf342c5ff218292b0bf886b5f0b3d2415db2e4998a95df73739b93a21fef869178ba084b6526817be166bc7c7441ab573e4b7eb5d3cdac5eb84a5490dd74989863e4d34b9be38e38aeedeb5cb9d992977c739a7cfe9cfc349a1daefcae572bc82c0bfc06da852deceeaf84f6efa967aeee9b19e3f8efbfdb39eb5e38fb48b3ea1fee1ec7cf8330bdc49c5384e0a0dbbba404fb3a62fbcd4dd528699caaabba50c3195ab91ff020afcdafb884976482843631bd53bc6ed07bc80925153a25423538dae3dafa426b58f5a8c5fa87d2e685c94518b316ada27bf7dc12b7f8575b1e3eaede12cd5df54fe4d6a1abf4ca5bcd5e9dac57146d6b6692b5e1dde38068573c518638c316ad23deeaed4b64ddb18ddbdbbbbb5f8b1bbffa8abd32cd69ccc3fdab5b4bb37d6c6d327b46b3f046ef7a04b4d4ac571aa94a66d8cabc9d9dc944a95da1c57f456673fceb66d4bb172ea4a7777df388c7126d95dc6a86952326fdba64929b79a252dae5edd7ca6acb15dedda326874cf9152935195d32eafc6e75d1fdecdae9bbda5e3563c68341937d50a38c6892915192783855e09796215d7b9bb0fe936329b18db2aa678a4562c16a5fe43687cb058354dc494a879bc86de44d58daaae8a53a53457a9542ae7544e44cf709b23e78ef628b56d5b75504043625c6e95d3a57efce5e3a3c2ea476a05e4bda254bb9a48232202f235eeab7e56af38a75d3f9b8771dac5dbca472af08fa69641798fea5543ed045381add68243bed6146e41d94588004155debc6264a4d2a2a6b9e611082866fdf191ca63236e83c2b33585e91e0f92a4b49556ea587be94d6b2828a82abfc734cf92a9f2f90c17b54bee88d1fed83ba8e03687cb21a3b3ca3258122c06c5240595bafdf6feb1d991aa9b31b5f1a91bd05aa183a13585e6190c62908bf852bb9b53e551cee11f23cb1145c366637b18ccbe787ba8b13c1d667b3aca5f1c420c34aace9fac0fbb29ab27ef612ff6c54fa64ce577352aff93f70ccabfb065bebd87937aefaf7e1a4ff5b1886b7afe2e5bf273dcf5d3190ab5b35379d67ef29eee992b6366820fd00f7ff1bc12e3591028a076f17fd0792cf3177f121495839bbb6b9aa6757c0f716aaf2ae020c7fd148750a2822d757e3fb51857c845705445fac5ef1fab7f44188a05f70a4490534a54881a6e540b322068b850a9c631228b585d1dd4c5e26949cb512c06ab61d80a29507e2d5f30ae82b4a6b0c0f717abc0055b53b45f9065441935dc99bb76a4e7e3af2b43b5178885ba92c52e3b10b4cb818a29a104ae288b448a18d515eb68294a110c3c298a13356428bb9483931a466e77a10122f01ef91de0bf998081e1ac6bc4909e86b1a268f547c2b0a2a51f70a8fe4466ad2f701b2ea31449f9236fc87e78cff4214d3274c5d03fb8e9a57e67474b7d3796d0709b90782472d73aaa8ad66906a2eee9fad5bfaa256e8041c3598dcc663bdb59ca7be6f7e41eeeb7c7c63daad4eaf403790ff7a9f8d5dffcd2bef0c6497ee107b53fb6b7363882c4c89c4dadbdccd45c3a6132543ba85ffd48bc8784f66242ec9e552d41bbf697e3c47b4eb0affe18a692271c90ac0e0fe12f88a328d155f79777797957d3de59ba74e9d2fd71982e6cc27c0cd61ad6aee62149049dc5269a18d2344dd38e905490180263831a59a4903dc1a4c687a218c8a198e44a524a29a5c6b47d318368484a29935c79028b35a6502286882e9c698a303da8be94012545b524a7abcbb483ac0cd72df93442b04147101d0307b34359ff392e1e06604206008b1504c8328500aaa05add25a62e71dd054b4ef0a07ddd25a62975abbbc474e44d96fa0a099ce1e405982b76f8618cff2b5b0f9a51d1126954839438bb03254ee567668900a4d0ad2e130f3708a3868d8728d5290ed30e666aaa2e130f5cd490fe5cc2b7d490f500335fa0aefcb0035292ebf0af7445ffd36c41f77763661cd89318f3182d95dd573e689e7bd54b6edd66bdd77d230e272326ef3d52aa714a793bb1976d979d9aa7bf9bff7d766a9efd7ed058a27fd050da11f6b9a95decd42eae5c436eaa1c26a9dbd51ecafbd347351f3d1b7e72eeb86df536de115f7d8d27a45d71e58366cacdf7cac7ea93acec0d47357925e811627737efcb18a5bbdc26f6d23c2958d38b81daba1f3fb1d2c7499c5457c5ad8c454e9abcb84daae3525d978ace3aeac14ac7a58a624d4c36f1db091bf911151db02751b5417e2e95e4b1cacf58f8dba9297e69721813466a29ed62362ac2b1030d39eae663682855ee1b8fc911af4ffc73fbc2f9313f0d214284610cf5ad80aabe85e6514d6905b9f1fbb552d829ad203537bf5f6b63128eea9e7801f2976cc98ebbc48393ea41e51e1ba39913a3213889872d356c2a957bd7c9b35476a2863c2602aea3024ab43d36080530dcfc0d0d409ce7e728efc1f982664802a200e7614801ced3c020ce1704821fc09b1b5f1008a2802b213734006f40d615fafc9579da5c000605fb2a0e28d4c5507352eecf63a80f7ca0fba9d4f37a5b395ef5735c149ff11a66039d1f721217e73782197dcad971a620c314685a6afbfdf678ac34cf7e0c2526da5c00f6648408d582862b2352a47b3e0097a3b8547e3ed3b05dda010a6e871f87057787a356879f9f78f093cbd5319bce4983f382168c17322881422c45d1f442b4040a0c1a018b2d305088c13c394206c65640abb7d0c0cc0cecd14314483118c845efe834b16558230b224e76ee05ad0da03043060a390d4ead15be209e728319a240a1550d33d03f4619b460e6040aad5e8004fac72f8865e0a48918284473c611e8df6eabb112276494c0f616148adc38f4182bc0785a2e509834711919506902395f42c31846a0d026a31b460a18249093ee04ca4a1328d49d39e268dab08596797483153230888198c129060af90e47a076460a1033b06938228a285003a306982890eb68342d6b1c29f10ed6698b2632e712f58453ff10454313c8f96ed114451228d400323d84891a0c6a98411328b4d383981844275c684004725ad79e27110326723003b9ad6b2f686540d4c00914ea34aa84818019c0cc402e654506284ea0d00e94334dc09c56407b4108c0818c245068aba0828015283102b9ae6b0f0135d8900472abaebd03b4414311c8d174ed711618cc10052e93922e512047bbf6dc8719c8000672365d7b41ae0519658a40a1950e4f14dd74ed79d10f349881dc8daebd20f985071a66a0d03a1501469caebd78650b2d92400e47d79e63a146124720373dd0d13550e982040a31bb1358cc38710472dcb5d76a982992815b85194dc840cebbf63887299e20818cc31145c8c0a03ea3062398b604092b92402166bec107eb7bfa98dc75cf751dcd8faf7e3e7b21d8597561f5f397b43871dead9ea5303333f3b6d1d4d43c57b3d56c5b951f4b69573f8dec35e856b93528576e0d2a2b173bd51a5a975aa1a0aadbef340f8b45a993eb3ff0e19b67fbfa1989f2cf9cb88455ad41b515ffae363ea2195237b903a49582fc14f091ea4377e276f2399dbc67c1e94a1ee522384143f752bbdfbdc8afb5fd5657bf54f28e6d338d9e3ef8f0114be1595dfdacabd5b3e72b2f7e77146bd84523e0da0a838645e2d6004abfbf95be161fb5cb632967d0bf12553525ba8572636957c76a33c5ca1ed7560ae189324ddf708184adc7713268e0fa4bbed7efde1159b1a0618b69a7586d294c5868377d1dfbacd0fdb063304683e3a464667ed9d139c4bfb065a21605f8b55f41fe7e30eccbd73e18aa04d967180cf2f96b2cabe3bffef2e7dcb3820ec94f0890cd0d686a5ffeae239c5e66476a0e7ad05251430e780085b62cd0007fb4a630ac700128b45d010350bef605ad164d4e4a80429b1210a0fcb61510f2a8fc49407f7fad207f7ba92465c497d60a9f267ffbb4179a33dc40e70e166d0591d383f6092e567801063cec2fe5e73c1454fbd9cd5782d5c310ef7922eeda1e5e0b44b6ede5a1fd7aa14fd55ee09e9db5d0fc0d51a29188d742bbfaa714dba30544fbf8da47262a667599a880aa05a8cb4485953a9b87a97e5da62f522a173b5f49b949606b94c0566d86b2b216b5fed82cab06a46b7f093c1026a9fd496a7f3f0da4df05ed350f4800aafcb65d75733c32e198be38a9367599bec0bedd1853af799b53a5b7af79aa8f5e00ea265dc6df3eae50e89f807cd9d5cda95acec6af43a22e4c76256e66228d33c47df3040d5766831ab342458a07b6c7cff668ee9f2d1e83a7d82f8f45fc34ff682e445aca5ad6b226d24da4894c2dd409112832994cf603886a319b1cbac848e7b0cd3245462277195f70cf0356cbf67cfbe2af41ab600b1d587186146210000a0454f61e95dd0b5e4f29a985763191fe3eb023f87f42768c2d4d2e040d295454932225d174515c03494a9467686790ea0f6dc30119cda4ddcc8e934f4c16ee0c8b152ad508926d9a91718f4b4c14ef88f11943c61828471e738fcd8cf88b998d301bd16464239a9c363a90329ba5543355145c1a45508c60b1b2b9fcc53db7d6a28be23aee3eea280dc4aa8b7240c39d4d1ab9e7169ba3a0b151236ca53a9bcd664a9369622370699f1e4858b8a3847009fc710c438cb00c5a40b9913468d8b00ebba836a9bc89bc67f51edf699a703cde11ba8eedf3dee6711e9fe20d2e768cf8f8f8e4482aa28b895ec0eb4eaed1ced9a60eb149678a494a95834f556a23cee1a870dd8d0edd0a071a32d18a0627079a9a9b266ae80d26166a08b5c942e30e269b9b3528efcd0d336ee044a191c331e273860f0e19d0f8fc383aefe5222226f282fafbac8f07396e80918395c5647573a3abe33f844be0cf6647b8f1c54cc756417dce9821c30a13319940820924101111f9fcf08f65e5d0f16388dbe112f8a70008b0d9016b87fba6053d77543bce83c71b5de2dc51ed481c208af8949a130d37c6f270a763b2e3a345dec0a0e12209194af59f1d1f7f2d2e0e1d380e070dcabbbbdddd3631a0fc5a7c5985f24edffdb40f8165357edddd0d44eceeeed8dd317677f4c254f566efd8da1641f9e3abee8dbadb366b65709b13c68e9ddca6cdeac4df1882d4be6c44b0994046d9695b472937d9cd8a6f33048d326a51eedd44d149bbfa7520456ece2dceda1efc5df9bb591d790304d555fbea7d495509ba3d761dcbdf5d6af365949299e76b9d9c40ac470da58ddae51f1849d13185c6a32e4654b99aee612727560b8d1144598c9115437efae019c939c9830f5929c7c7c8454382e2508d2f24d620699ed6c718a353c4e98f1f7fb6d8a02def9b7e1869887ff0852c1d5f485939be90e5c117521c319c2f9c4621f59b161b34ec66ee365f386521ad29f21dde3a79cb521f51f50ffac610aec99afb2c5839ff0eff863e55b00d4766662766e06ea2061f93962dae2899a8419558a65489455665134330f183ecc9a104462e4dfeb38625a6b8e2a5ba6a36c1344e57643a7fce7905cb15236a76708ff8f30aac4625246afcd6ca47a4341011e58b0e9e58d0448728b248d1344dfb20f5a44445893035be8e958f488bf83259719f60cae149e205498c5102a96a4890a9dae758f9d05c55601113638cd183950f197657e454eda3f6338caa3d3d628caa3dcb4a1355fb474287236ea8dae358f9d05c581c01e6468c31e270d951441a463451841155fb1b2b1f1aa54bc49002eae8090dba28e150182104b793ce8ede6c971a76496324c5a0c6b759f9883963681874e5438b677471b50668da965043126a6842d59629842a59aab021832664f005112d20a28baafd5639aadad3346591a166a90a518df157ed84937c4dd3344d8bb17972545966aea6254a142f4a4a645c3465c9c2c251e4da1e4ee5892acc1237a8a416638c93a67eb99c06d490c7135a96ac3040d57ed218aaf62ced9f49d5de25c41455fb9d1554ed7d8670aadaffb0a06a4b31b8220b6e4372a2c6d7b4170c41668d1fd6b8f2e505dec5883238b9f221674e036a5c42ea414c8d1fe94e943151d4700415596600e35c9460c0006003d452e3c777aa695786543896a65099223c99da26b7edc809903094acec6003a8288c80c8949682f8c208880d8a5831a4a52c456c6abc92e84ddda52c2f4882eea8bb9445869913b3073821bb517709872527742883f67b6fef2e37af7cf65ee8caa05dc39f6550aee1772d5710e83a3dafda1534741de99e4e721e924907d89ebef9f83bdbc3e6e9872b5b2f56b387f86b6adae86071f7ae0ebf8dd749de53a45ff1e36b5ff1a39918d3a871e38259286a7cd5174bc5b88076aa317e38239176bd14347424588def48716e7c1f6a16941a9dd438654c20f0c154606b05185ab45d314aeaaa3102404643972b27d2744a8b18a4356541d6ae363eefbbfcb5fc85eb64820f945251513c8a694d4949fc1c0d1b51c16691e324ef6125fca4f247a548c44944f10b3916e78cb18bab18e5aa536ddf7393316a1a5be917d7481cda3d8d6ba7fb58feab5fb0fb9045e4323281e8a7f37ef82b16c41be22f21575443463256412d05015b828192f61a0c90ea9a517749ca957f0a43bd1899c0af02f7778c8cdcc87dce55d1eaf0774882f00f274569cc7bf84914218ae0278e19ad0e3bed60b1b4546a4e6e7ee4542b1fa9e7150af3b7d7e616a3f69af69aa63113738e07e1bef3f9e13e97efa83e745556815540a010fe9091d888a1b831565081db17d16c38aa53b62f88c1d60adbcf9f1f0cf3b7af06d97efe377bfe825b7703e12f2e0b9847c130e03d2278012606b6806cbb0aa27dad0952d54fef705610ede517d49ab2e3affe7eed7b97bf3af60fa02b50fef953d4a10b19454c45f3e733c1b468991d390c894a0f35eca893665d44651cac0b0065a2f88b37f2392a95f21ae6af281c2ccfaefc56b24df4042b4b37015086527e9ab2d509829fae18b183862573445136b6879f6417557ed8f116dbc3515c832adb68abf69325a1629d7cf7f7afe352352b1fbefdc79523f1fc6ececa3554cb5a42495977547f61cf729e15030d218a2e5964e02165e84aaee44a4a3e49d876bee7a4dd51fb926f6482f4915be891595bfd496a557dd8505256fe9c50ac1c28c74aded34ff6253f4a1155be92944e6db43a12ca09a71ad20a15c4a0ea7f3809003464074d367e8c9fe302628107e530ed35951f877754aef1fd9f66a73efc9bac3e2028eddf811ea9d1a4055328b78ceeee21cc7c0758aabbbbcbb8d345530c607bf47b7f5d506e57bb583a50ce3bd512b4e917a309f1f311e10a6522a8b7093f3eed62614157c77b806145b1c58747102933dcb66a620201fafddc0e2fa85d60031318b8c30b0a126223643cc4c02af377bc083aa040b8974254ee93d4766a9e30cda3e359bff9c66a0f7ad6b0380fa85d1bf7add607df4c1e4ebb5aad0f85ae2dae6edf5468533bb598ed7b4cf77094eddb8a53dd24b87deb03ee08168668336a9eb0a554212a109ff1c2c40994ad35bb99460d0ef7d1766d34eaf01a69fbe875d20e19286c7b96c74349dbb3d3f639be90a56a1c8ff385cfbaf185ac8d05866e543620a5e6a1f9ed1b4bf3a8d0db37d3f6d07e93cf79e1576ec8eaa777f3d10b8b2c540739d2757e3fde4fa14fbd01e16d3cd5afbcd67caef341f05a292198d8526b1a69076b7b6e87b75d10310403819a67fe4685053210a680f03b3ca0e6f9eeb7e7be1049e57e7a21923a9fdd0be777c441f85af31764a15fdb775f6b7eacf313c2c445cd99f3fb8f80fcd5d378ad14668802a85d714f65e5f168d79684d4aeed456883ce57a179e647a45ddbeff0b81ccc62e0ae2ab06df377dab5bd099e4fbbb64fe5405fc906757e612bd52d6ca4bafdb46b73b6cf0587511568dd1fb076a054287f1bbfbd233ea5fb58e8178f61a24e89d95e917d4261bfdfbd10ec537561bf91585f682b050f859eb457a576f77bce20ede2ef3d3e94ca3ba5fbcd2bb24fb55d8b71a7985591e45af4199130fd19699e0d970cba83052fa85ffcdb218942fb1b22a45d5f147de2518195449178096a62183f50f3c8a3caaf42f3b0a050fe1fdc2d7911537b3581fd0e6218128e88902726e2e13a21baacccccac04c6520c5566662ade4cad1d12b444f146f9f8ec33d7354a7032071774ab5c41802b03d16a2b85cf058d9bdb24abbf0a5400474b5ebc8ce1a63db369cbd462ed3021a6ba6e897a73fc58bb1878ea2e49115565f4a8e6e100fd10a10dca83846ddad9d99e6caf71e1769ca191080b438eb4a66d5d1847f45059fb8aac530a5d18473cf199554e56c2bf9d26e8d6d8cf0e25bc20edeaa75cc352146264f4d6d7d6b25e987d90419a877f9be1e989334a0051c39e2d085150ee57cfadbc86f217b39ed0d404bb75da50298772198c363bcc7bbaafe53df39eedb74a46cbbff9dd07c30743151852afe27ece397ffe0043270aaa1224154ed91eb67d42f361f8d4b79cea22f53d09c181ea43156c1f02559db27d3020f1d747c45faa2e54dffa2bf53191bf70c044f3abe2dfbdea4356179d8fbf1884293445f35bcdb7622b7e53bad80c8a6ac84620704137075dc6a00106c230bf05443ff54940fa0555f1dfbe06a95d9cdac2cbb1652876aa4d5e08183014ab468a30602856a7c020b4c9c0d46f9fda425b260216da5fd84f7593810ba63ed82603b7afc5338ef217d450c38e70f217ffa6c9dfbe4e1ad3444c5a16726da6767592bfa648bad2a4863d6b275dc4db5a9750ba87953419542a379da91cbdc3e6d6b61766a6957ffb884af3eccf28109cbf12b4d5bfe0a6b630abfab0f40416232c2d20db02c2ad9fa2fa84546095fe24759ff793d424b50544abfdb552bfadedabac1b695af27342bf260155e3ee744ee8cece67478436e886446d6666d5582bc149521db3fc6c36cf458c9663a9e90cb7d8ab7f10edd931455f869cd849141f691d817e0489c2e15504ba87edd1411b336307513c81421cc59725c02afda0062435811f4ea369fd3fedfdf0819ef00389f70075511cd43024ebf403c9eab88deae7871bd5b56b7bdea889a30534649db0f2a1fdaea226a36c7d0ed777252809ed72c7a9db05091e6ac84426f8d4241dabbae05a40fd49407e76fe1610f3b7fe62b0fb19ec8fbef6fe24e0802e9fa04203b58be3d57e394ee809f6e5ef2f85913e3e8a3a8a95c1450551fb439b96c02a02ea360d9d51696da212e539417168a1336e67bc8b1815e18ef0c38ebf711ff990d632b1d2f7d43d4def8186ac1424a9306385cb11182454c3c3141780f4855a32a411036b825a01fe351e9256803390d404e47327c5867f0b5989abef121458aa4735cc4bf56f22265090a9feeda47b968b24180c16c32e4d61a63ae8cf6d6c85612dd7e2af6a8e1d1224341c551aa2ddb3d2d675bef2d1d1acc47450fcb44350f304bdabc29dca4afcd3dda7f23ba11060a15382ae334cb56a354143b6c25492c4a86ea00cc54fedf2ff9ad0a54fabe36fa3023a47c0f5e90857b9339f676ca679564b104c75fe74549a4154fde9a0e6d96fa2213fc57797a2fab399edb1b5bb9f6284220a29b5bf9c6f9783536cb49fb6f16a94bcd4137eac50212cc4232ebfbbe3f7d7fa515598693c01390e5de718e2a3d0709f7866c84c5c8e01161242991583630c50804eeddf1edb7136b553b59fb74788105f7d47646aeaa8f36dea4cd5f9d3c6f358db0b0ee0df55737bf7053c046739fd82a05c4f5804833e3319e23d3f29eb818474169403dcc37dfc211bd81ea98ff353de065627fe72805ff1e38c7b465c356a8c435627c6c8c31237cca0e14ecafa77ad53051888029302abd31598abc57eb1646a8e9ae372fa6643b5046d9edd1e110c6003fbf20f67eaeb6f00db83045c9989b9690af1971764684531c6d2594c7fe9981ce3588f0bac0e06f8e5afa37e21463885e4b0802ec736a6e5c0a996a04cc6b22064a1a87c44d096dde430146e98392965b11c025b7dceee2c88b4d0aed412f42b83f277165886b828d13c6100b8abe9ed129959939b9c526eb29b638c31ae4777d75ec02a6f5d3235b70c547fee8eac52b1b721d3344d8bd107ae6776a8a3ae4df476775f01e1182a4ebf2825c3a293d9bb70817243ebcfb5e3f3365f3379720ddbf0cd17b2ea46433a3f74edf8a4bc3db9bddbb67c21847803a75ffbad1415f46342d070ce36a2e669178f76c9ee62f7a87e555e0bed496de7495bfe9fde96507e2d885b80431950606090d08241620656892f5423464b1358a5bf0532644370a2a88b47f7a89e559a27ff0b1d0214a479b69701a6a8a8a42ef64435756646000000008314000020100a860462b1482c1a1236691e14000c7b9a427c56990a84519203310a21630c01000000000008608066c4120025949beb342a08da99c14bd40aed6e5ae059c18bece3e31c32031202481e301737c55a5b07996a4ef450ab8c2c9344c846b0b4ed9c39f2e3e8455d22c6257bcaade8167c40387c9bf12f38617fdf5e8a2ea2c7bab614bd54564dd3a17670f89de9fe9a112a22d00169d178fb531749f72dd5877d220f48ff91ab95c5b8268c8f25c178a7404d68694635be7478476851009fafed2039e96ab767e9e83ac46814d3d4ca2b497301e6338da96dea5e2729b3d48a6dc9a6d87dbc21cfb8d6f41ed4a8735b32a40039082e76c6040c40bc1a446ba2c5f59ca560a3c5451c72bd6bfb325a370f2c9d559ff0d6f893ab4fd1f12021e520069a0b14516b6e0305a22945032da57ff829965ede15325b2ab9320edd598e99f7b3e45d98eb05bf6f44c1bec7a7860ed09932b335007cc3d6f09de42cb657c656d9edf2369de1cd2eb564b865d9fe0321ce12d8312c8509375c4f2a62f0cdeeadbcbcc761d82f2f5b80e6ca90018b2a9e704d2c94fcd6a170ad44d4ffa4faf775322fa1579b46436aa18636555991c2c3a06467aa2d27554715e24a3d38b2aa1d61f45d7398236e5d57b35a4d3011bd71c6ca5d175f0d215d1be0ea7eb60eabdea5ebdff72ed14081ac7342bb16eb2a84f3643b2707906d419451504e2ab2460bd8267ba6abe7e26782a7d0550e3d1b826450ce28e53d3d325785889bb5f17648aaa8e011338940c4c03c2be6fa9427e5ada20d6ada7118b4f507f07d0990ce6c835a1d9ae8d8ad303a4cc1a7975b6ce2a9b378a1cab18bef6e11bd7db76dbecc43830b5d3737dee3e5f06013567dcda06c34d1438de4423fe6f985ea5ba9bcea516c58a060cd26846d2b9abe4bc1c98b08d69255f68221b9a75c9018be647c0e5de9f24a5ba6844ed731fba7e47ac6fdb12cd543dedbe1c3b10ff92d4219b935d7485d0b8bfc446c94d299a4f87b9af0a838b0978f3481cab9933c6cc36f4cb86d52f3c61d63d307c9b28680d1f364b9b1c8dab150383a7222ac62492a5c686a9835a0d513a08dda2463c144a490ed1dcd06dc77f16e3c9d0b94dcde994b0f13d5069433403a4834ae2c03f76ac35318415d3f208e3748e1ee9ff10a859fab119769aa2a63ba9a7823d9c72f4b1ef903730a7a46d9d2cdbd77ff8367e2e871594a6e75dd028f7b9086bad736b6247c859011fa399f401c43b8a742cd9ae6cdcac91ac54a1c9e7cd241bea75782ae3bc9e53f9b7ca7c8f0ad8edc40a297681b2d32f574b0ddd1eae80e0eedbdd61d69e3390e359ea48a393985c96d8397d570f74d7e6e9ed7872bdd8f299815a6d5721d05c17845597d8bf9e64c8ebc5d33126c9c35b5d7011ee389bb5e19b8808cfe9055e606eed1795297ca82966dc8ba3532dba779e7f91f14c0f25e8460c9a4ee4f238247a07f5d624d25548d8f0d15d6dfaa3bf4afced947f0ddad0d1d9ac8b9254dc21f769e44db7bba0f96354d7b45a7e0d89523a666da797c33b17572127faf0ff3ac99d0088b7e966765ee61590731521e813f07311b2251a5959c858f9601aa44d11f53fa49a8e62fa06a5efff21a07a2647b5bd85e31a465ec3b2be336f94ed4db158173fe8719450e01f99cdb3486540eb93edb6036baa5853fc5f8d312491a6cad9896d0271892f12dfa7b8f0388017beb01c3faaadfd32a4b189b72ab2daed67499490dd426de2a40d1f7ec5d56271ae571b680d48d341c3269ee8a96442280579123815fd02e97bddeabd35bb7257ea4ec1af879df3f74ae0c01c6f56c7076fe3ef7e05bf0d552ccd2c733c7a0cbe9546053c312a870ee00db5f3ee538a969fca0ce58e672824025a679ce5216e6eeacf3f505820175ed3be7a5bcba5460dbf1ebd60ef02d610f3c3f90cba9e7648b4187455f724c5f9c9f7aec75da96555116ecf3f3fdc218649260d406174def4f2e2fd267e81cfc8d7881d1c92dbf9ea3f5f154e81832cc46cf1cb0344b7962e31fbd5471f728928e93e69d692670a3c84259f220c66045f1cf5b75baaa7cb0e7ecd804c5afcdb5bfc7c4f8c8ed88d8eed88eda0a6629be786b8048da6d3a2a29f2aa7d965a1550cac60aa52bbbd72c665f54ca6a5d5b2a96f02790f000dea89a31fdf32a9091c6cff0c4eb1f6fc6781d349876f8e1ac2b23bdd70d43348a09c35e3b22bba9ac6486b4de48388afd0203ed374b0346ef63650a0c0dc33fbcd6e3d1f550526c252c313beee7f8815c809c0a0aa431bf552228eabf8864a558b2c1139bec6d35a49e2b7d9d3289cb40cb3832960e6ae2a903bbface4bb5a99fd5b1a8bb24e897e62cdaa3518a0424df95d2146611e29742899449e0927ee966cd051005f36cf42e0bbaf5ffab32b0e7b5e892a665351b2023232ae6f5e8a59da1ce9b54d67b4c6ff3b1810cae5b9a154514266a98cf040645efb3dfb63aa5270217648623142fec434f1bc7e85c4dff0c03f4375fc9cec82941e533bd73a889b932f829ce7b343e6be751fa1fc5b7e5f5bb99af0842199218465909134e78404490113e247b12328fd15b10e40b4a9e70ba961ca33ab1a8098923d29288f1ad6ae190497d2538c52748d3ca7c63276961871ed89e44d2d781b8272a8b89eb47f24007038b2fdac94fb49cd859854ac757cd192a8c4346a01c6f3f0e55f0bfaa33cc79463166a2e2d1fe7b623b52ef03e2560e813f1ee2f13c9f125a1f49f259abf95b4add92ed9b2ad2ec303c41789bb1cfb3c9cff949653f6f967f462b7175d4919e65f021189b2c40db4cb6012c6db9462b70690208ef7dd6070191f7d000dbb022c630093cd3257f81b2d2c2e9d2bac7194ea88f4228766636ca966cd997ec13b20c7fa672291090e7a370e3b5dbe826dbb9f546e4fbca1d20597c57c7ba254d4a3b5c6f625ec79561012156c77d581878412c89f76401ecf2e684804aaab91525138b7d42255a4069cdb5d2c4e54234282ea76b05d96b6772ce236068cef19c5b0438ac8c37895c8352cc0fda0bc3add46852950dc1164546f8b853f1099b9fa9ddd38cd922481aa35c12ea5e1bdca18b577f1567d391fc64b7d5d04361bfdaa5c6536772f6e5db87efc213fdca1b38f20bf81d2a7918c74a5e0c6d3fdd4dee3c6db28791d667823316ac4e01b4e407aaac34edc907d790cc1353c67accaa7380c9a937fb58ef3630662d90e7b39b38c0101b606183eb5d5da9267fcd6801bc20d79528a571e3cce59b3b2e8da18fdf55806a3cb16fea53e3728b07eebc2979e108f8d2d9b532423d231e506c0546b2a7793284d9a07aaea5d03ecd9446d6a27f8b551dc233b1d869e85f654fe929477169c237d13542ad3810ef416c39e0e4dec26d093682873d6d909dd8cee81c07f72add41da08950eb414712285b63d1fa6a0a99b1d2a80bcf4dcbd8f407f3492cb86b4901141ade321c9b7147c20ec43306cf6d8d72b2fb3c962a2e1b547d18e239f4b9c43d65fb58a181e09a0e43ecef88bf95cc7858a6ddc8c0e8c8a8d3b3fb407e37d2a17cc05832d064a4779f1d3f346b74ff69f0a5e88cc5b7a56d6113aa55ac246f96bae29a6cbd62131b56973b7bae3bf81fa0ccafbde42e1996212a081d6d47b6807ed3a5d9186d4afe6d31535b3a71dd6fc41cb83f1906ef84eb21afbc487d95f16dcbf9301f03dc10cd19ab81ad9be7bd9a68b4a4e5d70d8d7d77789302ac51db2bf43f53ca3647b4bf3064c51ec0f5f5dcd40dfdd28bc2d94d132cc829d13349c9e6a0571e3848b2b0228222491c2ac0d7b31e56c942f5ed68bea2724deac0271b0c2dd8677f707d4b0636408e0eb619c5e89def5ccec3304378e622ca32ea91fbbdeb97849da203b157a8951e1ea4bda398ff50195f042fa29a464c76126be7191fe2365e7bef6f5adc696f30c5ab448edc05019b47533efd2d1a8e9a98fe2d2f4f71da215cb33d6b5527132174d202ce7f46eed2682782c472200bc296330a43d6164f4a4c0e8841e907f3bae7b61a9f00deeda2385a7ee777a3bf1f67c65f55c81ccbec3e582f22f2897432d2dbd6e071d5bd68678bb4562d645c79950edd76dc7ce9a26712c3b788875f6b7daf8dee73f79737f314c2623a24acbdbb193958ffe8c3f834c659dad64901b437b736e823824d066221f9f296c4b07c961e8431238518c86e4a20ad19a8e14bd1b772234e0568b6c690bd31935380b6cc9f50b5ef9eed3af09fb477359a3f226e6087793d5e49ba0343cc5e6b8e41534c1a6015eeda31e3871306aa5075471542bd9b324417e10f09789e663bae8f6464847544fb56fde9f8810ece2aa1af6df348888352d3d2dcfc0c19efe4445b65721baa97730f665fe1e3dfdd9cae5c7281e553868b48c43cc863540a8eec6422cb36620147aa6a07e8df4865b62bf0336f71d99058aa51aa302fb2e3f26aa795233cce1adc34ea64029ba611fb03070bf8f5c3a619cf28f282efe9deed6ef22142bd61d9e15c360e4df2b90b3e25e590b9ba564e2944a4966e7e334c64c71ec10163ed9c9e45ebe08a3940066b96bb75cab2c3020cade315faa88964168ae278fe6ffece6898f92a4e4820a84fc04da65026092b58d522dda43c703d746f61f198300635f47dd5640f3d07c15de9c05c05bf87e463e11867141e6949cc905cd84de3175e64b8918fb9a60297b654e8828a4e5dc978c3208b52a14f34a234086da23ae5427fb012be53d3d5a260e45755659458c9624ad84813ef999b24c3c05a4f1ac88e0580b437f4f001f7df7c344cc226f07dd43cb0e8832b6a330c0d5b89160d968c8795b246065516f958c9faad7f64532ef0c20c72d393ca7a0a63afd936835c53836e3c4949708cca9bd452f24d2df384ad2fba0636872482b2c72ca73a8272d5dca3081bb49022b312925c717be76cd4b20ba54d6fde0ba3a34ec9f520e42634a59f83ece07341c16e490bd7cb0ee488705fce61b00ba28282f14fe49dada049e96d3ea7c5ee08bb984c8896d16a83aee3aeb7255296f21b01bc43a2dd4eb06ba5e208fc5c2b343b691b96aba210c06ce91439f09ad60ecdbb596d885999b6758b9ecdbf8f96e966fc3af177a1efd6fd9197f55050c0a93ae7f5a4a1c38e855b462930a7282f7008aeb9d694f6e4134dc359085fda9ca36c205db9fd3aebe8bbbd5bec90cdb3b005c809d8af3aa4c1024a2afaf5bddab8f94a50ae23b4b5bd00fb9edb99bcf1fb0f3deeb6cf16ee2cb310f4b679d9470be66b7b4fa11a845eb2acde4687d1e0b19128fdc2d8815c222041cf6282cc4f7e2dfeb3a3aa13890fe4c19e223788914aa52082578214a027dcd12ac9558d59bce8bb718ba3592a6df05eabe9e83256bcfe2a00c114f513ffa81d1064684b0c9f8d488f913d518c08a9634f09e6a0c8776bd68e7868808832a1300ed1db4ab2719cdc4c6e4f8e2bc55702d411c351c29d2643738ee67ed12ce5da1d099d57590eabf96ecea7ed375516973bc9234af21d3c0c197d0b45a662133912d18caafcb44a09a5a3cfff99748e07dd590c5fce43d50631be3ab47936ee1c4e43f171f2b865fab372a60d956cc4025d6c93bb8afc259439ed9cf38f7a7c95fa2d7f7e3afb63e43b904d6f2cd12090ba11dd3ab90d08eee8d49b8fee235238d8d3275a8ff44962c4d00eb1cd41d2dc54ab0a41d7d86d60c93152cfbef5c0ca3f803831d0f1c14100c64a9a260ed6fe43e2dd41788795cab5e373e1ade5f354f858ec509d2b6e59736cb4d25f37749703ce7f6664f47ba82c21f2386b55aa9b427218d1195ca79f8072e7f0dee8d09f0cf7b868d14061a2cfaeea8d67791bb916f7e8d2a87b05c112730a4b0a9c064ab8134c6cafebabf20156ca9840a38e7e53975f061c76e8335c021ef521f7554e8eadb7bc726ff20a4c4297221642e3a7c4923b854f6888a9985fe6e3f1ca48296385683c5b9372c609068569459c9d9ece3d452826ef245008c09814804fc097aa40a7e0db1dca621041bd08207ca708c3c03537af66d52f4608fbf49c0a56e5d87c734e39a451c7c975a07d5a65aaf63005548b6b82b9645db2d6e4133b46cec7067eb8bac33f2dcee9e22479ed878b866b68fc75e51439457c42aec219b0401884a6f8db72bcd0a662f4e275c520f663565a10610135f5f4924e9d54a0a03d2ffde49039c684b95741e0f7b35c173c8f915aff228137912fba39a768cd4575b788bff724102b929155b91d74001393cbe84af7d46552fb7a9c52b92d86500fd41e4d4cf7465372c8bad7d15db2043fc9b7ca2df98cbaa90d1df75b504a7b82a3705423a17d22acc5c8de3444edef7c41e47995091bbf47fa343924752e6e3b51e210f1248a5960a79c3590933410efcd04a52001a73ea87c9a461d9fb476859a4d64a28c651056b2c93ce99e7f422751d21738ad857212e2baea08158efd8f47ce8b74460d6c928136aba46bc3674d853601026ad5fdfb2d485780be8da5b0d82c98714b6cde9d72a2a747fe6eb29389c40fa75c127812ad3afd5a15622fb55022f8dd0bf5fdfb79adbf08ae2de79131d476b7216818d133fecb35f3bb4c5eab12efed4e125daf8f0ac0a48e6cec99c4225ae4d913c5730186a081236616611d094d3b7fea045756a779eeade5c2c38cf99e5555de212e3506614343492f7f178072b698d77c124eb990fa12f80143ea745a46ed73e8b667d6a9e072e3d5c99a821918b3615c7932c85874236e8590a7814a3b9d8f6fb2c018c5ed045f9c37885b5beab2e5b8cbb05c4af5965bbd6e21ffd0ee71dde62559804070273904a0699d07634d6f373743836c68a5c0d27fb5c9e87ee55f6408aac5ea7aecf5dd543218acee9ca3183041a7993b42da88179c1a657f3a43bb3ff16241b519e8aeee937e80d4b00f892ea09bdeb76f908cb0d81e3984e42e8dcc0df59bde0448e5e5bba48437c1cca8aa4cd69bfc138a9ae8ff0b3c352ed1a489dd720555deb55f05ad0bc8a62a5cde8a82746aca9da02342d18aafaa63fde1c98e7ac68a3f832adaa9ebc594f70aeafaac5157d6d9584ce11b5b130cc2dd872dbfff93d0977f91bebfab4ed7f92c13c8ea7b2bb6425a6e7a501c819b76864eb305b27e004786d71a2e9b0b85a64b2a2326c55e60a586adefaeb15aa6d9357b542755b45cb27431f53206ce52c11f46ee6f22641001d83e28b801e4bad813e7e83c6bbe1a6ab456384f19723c140319846d7353b6e4ca01ffb7e5aa88ce57bfb4af38781b2d388b03864df8bef400bff1517482428067bd2f285bf43ac8593f54788b404370c757647705a15ba1e5d940cdae74c7623905d6b5d3cb356ac38badeff3e899a34deb7dce17f9cfc173613dcc9b62b1cdb0672d64a954dd90370d22c6d65e89c77c72b462014370f9bd57b49938dd17e6c4464aea2d0e63124ab89c6ffe10468ce7b23c828bc51a3ba7cc28d1457fd50bddec21b738340b0b5e6b9c8ab8416d01f89e36b76a667160d9a0039dfd885d35ad84264c9525aa531ae66dcef1822f703e3e909141e29f26325a0830c7b4972be562788ac5e50af9dfb99749cb544e0b21c3ae1cb1cfb44254cb8b162973bc17279c94215d5f4479d86f94f8910b633d6797d8a16adeeff1b126d6707c99d073ce089ddf3c475fc2a328917169d7c614d649c541a659155f523e44858fac6a804a31bd1252950804e844a430f64e0a203890bab444fd84425209496c5fa43d5f5452064482029c6c6c018f069d30577d018ba006fb44e4a0635422efbca3586892c0e01d0b35bed3abf1d02d9e32d02c907e9e4f9dbed8e5bf60a28c955dbd51dafad029bbfb829da53a655c8c3673ded35b7901c98c56a904b8bc557acbc264f38771909f90b2a20f79d8f24e37e41fa898068686235cae85ba9fc32e243e234fc3995bfa3d27ff8520bb491c0f356193557716b353a0f65e5b46acbf4e4a14b7f341b9dcd6122f9aba0e6aea55d3db4def82787882021ed08665181b35084f519f86b4e720e159d04c9c9915281e135c3f2ac4a1a790a67f591b01779214bf9b7e6f9f2c0b6ed88c1c907eda0e9cf552c6448692ed9829c2dafa593b32e2f7f20f94c41ca6c8098ab43537adcb9637d4d2e3afbd12931e875882aabe67a1c034211b575c5725fbbe98e4ae1aaec5aa44f1a9bcdbae868366c43968525459198fe89d368482d8d6154c0314849580abc34bfed219f171d08173991342b2b9dd3ce1e298e3dd5c87f634ea72ac6ac5253062cc4418b5c03af73adf7319068415775135d19ca4dfaafcc4a1c5c81382f689458b144d2d5c857a4fe9a012ce69b6398cbb8979b4c177f6f4478bb92e09f033f032c1b817d99e0968ef9f95b8a3b600ff4850c4830c8f226cdb4ac9b8192a138a12d32453786e4be7eb4abe343063e6a6a64454aea7632ec613dc872b3858fa4b2d29b1de3b111d8c1f1121540970999c73821623ba927afb9abd090c65daf437e1760de8977cda703e043f7016a128c2b17c2fb5ae246408ab280827dbf5525565507bc02ca56089384d007cb9dc4e649c9a4f4870137dea2611fe7dc54f09e2d0e2e83b67ec873c64dfd44f7bd25bceb52d08662389cedba8f174db93c24b7a6721170eb804d6953da084a6454c61780a8c4cc9a0ec816d26c19f0cfd5edf20086e037fb3905d490114c107aa59a08a3e09642f8f8197b7a5f121a6c61a3f3d1a3aa7e1fb7dc2974485f021eb0064da66515b41b77e0b4503d6c6351629f55f7be94859f4620c6aef4d34e2730255574883f33b4de348e09fd3089be315e1e775506b75455c5acd7517256aceb4a9650d1a6990f713b44512526d3cfdb064df0b0ce8788ddb2a433a265c67a6bf5a5fac5a5ee633008cc4271d044ca40e994420cb1412dff0b2c65b479dd20679a6ea5268e8a0d33b48530ad1b822111b4f312a4322ae2e4b7b00c2b8c4f1094fa7dc55798f01141d6eed89f88089cdb288315db50f1477f64b48c6fa1819c38e03e52e5eb563ad94a729dcdb8916a4794fb78dfa9c28d182a0ea12e5a560bfd34be1c3c413f13c52106e604b814f23f18ad3826a0109fb14c1adce0345831d39700d6f4f9ef22e8ceb46855c3609b0cc5c34a5fc546a97b74c5f3bd84ebede1e798de74ad54d963625cc00fb45e7652481dceacbd7280c30786067bd7b7228a0cd0c3427087aad96ab11684e8b59865373102a628605471a476023c9e79ca1096d1ef01f9fbc1519c55e19286e4909ec13dc20318f434c047a6ed0887a1a973835ff0ac7b757ccadbf24febc63a53cf5add643da960a5ad78b12623637959940ca7185a5b314e5ca1a9e7d777cd5002f682e05d3fc21e1624774086d5451b9420ad8b3d042e38b90079d78565be5185a68c4b113da0abdf7a758c35cc636ee7dddd53e078d77b8cc54701536b979491600bab02832332def1bcd73b34a441b525ae77aae318aa2786532684dc5ee13f7fc52a0cade15b086cb861edbf21f0907b2e73f50fdd3509799bb117522d3a5cc643cff9d5b07ae50f188441bee420d8a2efc3bb013f582b22439a5d0464919944fd8816edd694d827541a5c8eaa3aa7bbadc27391b82d8f442b5487f7100a186818d67031ea3103db375899b1eba23b3c0f6d41fee2eb18cc795a8c2723a26145beb918792112cdc5f5dcb93e11f748f18cc525a3459f474c7744bd5ea5b1a251ca33f199bbc87ccef9c0a3a43e2b82dedd3102ab17f0dec9d281fe0969c5f175eb90dbeaf92e061b667cf5c3819e1e3d5a91eef7b6a4d5466fdf2091eed321ceb78bea8e395573066d8df8b650215771b9d3f2e4fcc354a4fda1bf4d7fe5901903be8bc7696fe436a72e2e8cdc1205e754af016edf187a8f2cd2a2da3b335ddb47bd83949000d9743dc04ad0621d42471455f2322331e744ce7246dcca279a5f9f30bfc72d4e7de8a02d24930240280457b0cf212f465b7ae951c7d7ba1a54bbd28aa579375d3f3161a89c3df9f1740356e578b1b364aba992121962e36f2b96d4178dc1142d1d4cc5174e9b11030f6fef82541da218bdc49b6b115f967ed929fb019f2df5f51ea9c0a59fc6beb7ea99c30d08093d31f49ea9856bdb17eb1a73fb953ce362203eb7d3cde1b8d1a55f81233dff4a54ca3f60bb856793a855571004363099abf71a092bf3ea3fbf7f5b7241379a3b1347c603b0489995f60fd279c973f6b9f9d8cace18f2b7991591bef90fdf5283c21e65ad024fabac0de9a61af0fb69f268e8d69b5b5e0ae4001907a8715eb5c7f5c2d8d95830bc02ac5bbf059791c0fd28d1d2e2f6ceae94de1767058dc86d82e7bad218af6ba59fb1dd951974c274a43de9236d7f5c60a4394104c85b024e99140ec6a5baaede28bfaa256336b4274ab905c6e8bee5e92c55e8dc917c966015c6315f07c1d8c822d5dd036180a5dd2db3f6508ed8ee32a6a0efb0a4d1b8c59f26981f70b811ed26818c7004fe0ccf44e758c8c28ef019448be469422514de3fe4603f0cbb8dcd405029c7a63ae74a886e4ed392f374f742d4cdaab4d326160d47d559b8ec21f725d1cb9827bbec15599ab7191ffd09b514b246b7b50404b68ae576ccf2fb6198ff0ea591a7f15355e43a11af4c61625ea302a805b39d7fd8fcd97ca915b53c989655b2ca666bce5d2fc384096bc3a55d4e0d9d79607e829a708e888f7960bd6ee06c2e4e11948c2d35afc04b88cd50ce4c06ebbd07bf54999018bf9b2fa092d1e9436b4c1f0947123b27e5137858ab55b1a9f8913f3667d1c588d362065cdeb656cb0dfc1b1fea4b7e2eefa2e38ef09126c9a39926a40db466bedf2df53dd0201e00c914bb4cefe797353039141de0269ab7719d9d477b184ff63bb7634274af6fc5169f78fc65d1aba9b8216107bbb67bdaa3bcda654722add7f2b32582e798f8d074c838ae7b8c34017e30c87f5764d82bd020bd72d544a4fb2170061c19ce40d10fe8d11d5892a4db3331f055a757e6b3a42ea973efdf1e1ea6436755027ee967a0499b762cba390a1923da2978706703f28e3fb01456f3d5352c18644f16ec55e38a3907a13f2f63ca41b75383a855119e5d22fd60bdf1809d7e30f4b62beb9cad5d2717d97d700fa14480cbb8d6053ed86b2b618c5b3f680a00518dfc4ad6236c9a4128c8187c71bfab5c0c7568b51b2aac54d62b9fd604dba152c7c2b27606c3f8091367de8d04b703d3c3a2800cbb8b3b1b0cc50561fe09059ab97233a827577a435192fe00e8f1917008723551ac688068fe5c75081e33c62a23786cfed5a5c10b1e9b763cf4b7f384e8a9f382882aaef4263e8d4ca32106eddab2f7c87f7f15ef114577e0f1e0e3d5aea118158415f930e6b0f3135a77016c65f3dc810d64d161a9bef1611b7308fa516d96747743f8bf9a60decb6dd4e9f7ad9df420c25084dad62257f963e49288ee0dd309c854f73cc34d4a53edf54d654c49047b23a59c6f13f65cedb3902a226b61bff68b3b6e64a6f8c5330da8e636e0b819c0e76fd426132dbb12436a4cd280afedaed90e772f3c5c46c76cdb6fe6e7b770a521270dd6eb1510e59713fedbaf874434bd78f297bdcc42cb4c2f4da9fa018003cbcdddfab79b432e77cb8972a130a8b4c689d23017dd1753f7dad7c48de8d85e3933f5c9d718897119891c38d4a3a93e7454abb7808c8e4fc4fa230ef4925d0339e92d1ada7b5cc5a482df4a054fd1603548234a7443bc9a2d7b664967c3b5b84b6d9825e27f0fe8f3626ac41985f54807237a95cb2a9af87b01a7462cf43556b902a33b335cd17153b08780528d56871402c5a3107b1f40f1d62548b38b53346b7434ac301d5218b2a5b1a02078a1dfd4d75a27499398d1584dae3a7627d2e53de5c3b6bbb8222ad23a904863d68982a4646b027e21f6a8d5574398bd6f30a6c913027faee3b880a4f5c038a0eb7d3af133f96273c64c408a4001870a93384474678001a88789795ef91a3f214823ddfe8b833f64f61344e9ef3c8923fa1d2ea35927e1030b0a70921842374fe8cfbe1379c0d23c06024954fd4b4b77c98c8ef93beb96c6b165aa1669d32a0897eb705a9031f9636fc9ed8e98610a24ea878b8349198945285005435485833e707b3a91bf6907506f119aa4da0503c5dc7baee6e855ba98c7cc33abae0e23dae57cb8654e1e90fcbaa1ca35697a25061d225ba2b626699b4802515fdf271f324a3af9dac3fceeab0339bfbbf00934912ab1c05f80cfbfae102cd39c978437c61b17d391788a0b0613b86b51d8f5079a32f8498224025e835077f57ff1f055af2846245427d4cb4fd97e6c526a9d7c417c0f6e051b2e1d3520a45b6865bf53b05dfacaddc4a39ab1ac06657ae2fa80ffd19003e2448de43cef866a44d59b0e211264338bca0bc480308fee2ff9950660a2813029a85836ebc758abecd548fc96c020eefd2ae1ef93435cd692b26b72e3ec803eefaa7b8a908bcfa74e939ba82f50a49a1c4e45ef0b6b610f37911f8d28d01f455cf17588d9db97c47780cefd4d32be7c9a4309d31fa2710d4d0bb3c847e8b43cbae682a2974c01ad8fc5563954ec75094bf3f4e55e28728bc425160f4e9621a3a41486dc4c641c08ba3bf170b715d486e355d5059277007297c7a8dda904aab666a411a92a8a88e7314819cda8089653c38ac789fa7e1dfa0bcae9a9aa3eacf03368ca0f59a47e94af0b09a564602734b3e768e48e6b05eaf7be03586a5fa03c73121085295397903994b3c0238fad942ffa17bca3a774abdddc278de187079b60e00a4c775409e3b61dbf5a59b02df8b77ed1fb2ed8041dbf88f9028e36c78b20037a5d2bf60b1d8f58638e3c743289260a5bfcae7946951cd640be6cb80612796f746cdd76977522c4126101d3f0bb0b1f94bcbc9728cab904397719205ed21ee1ac9409052ed54e3e46cf391009956f1884a89c7f0c2b4dce98a5419cb78067dd7a1822b46777dd07945d68d4d7d34698a1a3f7ca2c4998835212e4ad403fdae85a02c45e226b8318abcff5b791182b64c1c90b118d9c29d91dc147d5818b3681154d32d3b33ff8e56ac2192d4052527cf7e8566b489135c78286ae6ac87a295df5d6561a9eeb3038836b58f8a563643afa1680440925d5398883f10508741be320ac6c58d230f8eeaf63140d6c60ac900d24f5c6b5b60f6d813edb94c991f5676157320f3db6fd33e2a8ab87e92f7f7c7718fb507399a85adafe3942f8267216486910f6787ad1b455993c05fb075a0fb6f048d01a502d8b9da96b3752356a944339ceded31007ea022e0d4796471fe2661040587232758e46d6714f81fa53883bcf0ea5590a9ec9e7c4b94a6ec399aad3b81f60e8a2a07f924efc52701ac53eb8e25718c301e16a373b10cd997f7a2ecce6f270ec04dd4c27a2c5636b6b20889e4e6911108764a8e48c2739d83a4e8e66f95a9121899625efaba6cd348aba1fe5b60ec1d6bd2803cb5eac75efab6472a9bddfb6453bc98dadc6c246a1152484c31352cd7785baa371a8785cf59f64fb0e840acc2dd9de1a64d17903e5cc707fc986271dbdba632caf479829eeaa6708945d4003ced1017b4769ff7038f83f32d21b67a3ee778fa1a5d2ebd33776dd796da8466ee68d07f35ee4107b61f00bed982f94d8069451b9b042e78e5ac365fc4816c2c9923ed63c483c7d639aa16e7ad4fbcb8354f748bc3bb67a5bafe70cb48ac175ddd9f9c6d86d58e0911e9bb5f7e9d598012f3135733a0c8a9106358d429ad64603bbf6c57c5d0a3a391c591dda9168bd1feae8de23640a41f1d7d9cee48798e21d0fb4a8d7cd8d7652d991a246b6d57d338d7f965d7e4683f0ae48eccecf0a475245f9f33bad5ec4c688943553a0f94b496de195b5eea86adad1adc0afc65dda9f70e43d853a184df9eed774a322a97d8d1b82304263067b17a5d50928baa384fae2bc007929c22c05bb74e3c7435330aec68df4a40e9622462881a9fa160a6e9493aaf00fc665c2baf1eca494086ee05b59cc74e4cfd91dd0818fcea0f53dbb50b75965b402dbd1e82664a592af2089980799ac343ec0b70c36754b9f7c82d237008b46994e8be4c6a00b545bd1186e370dad3e398e61abf20f980dd4eedf53003f9d3307b30ea7105590a29d2fe55e02388339be7d0cb8a243fd572bb4197e5fc5f5b912a69f09b6a5294848bdd19a652da4fd5c638d9d7879c04bdd441cca7a25a80da135373b5febeaec2f36b2fa4a33d143679e4eac89f15e2cf2ef34550c590c40426a854a627bd9c5ffa2c85cd2e43423ae40c1764a6b07acfe6be5040cc3477250b9fa725f4382e57e0ee2babe440e36434ab19b0ec2f001cbcf821788c2a02e8b2a23b525a7a7f01cfced901640d87c3a48bac72169d92d2c178fbc4881c1d8e2a9f1f411bbb578950b6c5b34af6013cc16af496938044b983981a97ef8031371ae8f028eef7d649f4a0560e70153ff6ccbb72c807b1f39e473de24b6d27d7b6808376b7553223fdc63ed22eaaa595c26e9f3ecb30fc6c9e1586a14773bdeaf2da5c6003e783ec65dfc25bcf354afb64368e9c538d3708e5dc635e2b62ba7a9f62344331510b7652f60e04fa399fe5723935d44d6cb78be7ebe96b57e7dd384d61e2b3cbfcd739dd13ee46959a537091d60b373acef04a3889286789287b060ed76d189fee6708c5f8f1af9119ca241f6b934f0b9a78d487f72912d943ee74fdf7267f2670e6ecc8bee4c2ace3dc3d6f61e3de2e92d993450d10cd5e29ac7e91c0f47c4e6b142258e075356271a64b122348e072762ada3f11899d5b71c8c0680a6b61aa142de67025b57640e35c577d937953d1791e1d34ec1529e7ec01535b875f87417cf4194e36843f664d5c7f72aa31765900be30d760fdad5245d4696d35a6cc05ea853173e50fac202a4e2d903b3d876b34f6ba09ce6eda810b6e5e0d47a664072d09967c18f71f37917aeb9e47cd1c5d02f5da2c0618aeba171719a03ceac7f94aeac2f10363f09a5cb8a3240703d1b6afe0d3ea0d00a72bee9acff19cbac28be12012a37d55b79fba3705763b75d16aac8209bd164771411b3ec96c0e7bfaaf604074e71336e1b60d8bb53801ae258c2d9659d9780514b9319fb8eef09bae972ceed2bfe91f7ce41c861b3c186be4119306f94d9b0a183ab0e0a0c20dd5e217cdecac65113f8a7c320e177544e6eee8b3ff4eb76ca1196eec3b722bd0a16ebefe705ef777ff4e86ed751c6a7f80562f1419b9e7dd01f7f9c0f7b919407316d824964ee2c14663b3c3b0602565dae13059336dd9afcfd9042c4af74abf25b5ad9e4bd49795ef3e01371a5e84084494823b8f93191d14a1c2b9d059be8169866222ab532b233f7a0aaf1613517cada50f71057d6880e118bdca0d8f6265ba1f8582faf97b1d04d8d85e26b1b22f3a501ab930aca7129a05aa7e8f4ab2d68110d0f9684cdac3af5332c753213deaa98a7f079eefce267cb69f7c67634c74eada140b30b3ed83a0d2f8ccf65e73d3259942d1c3dd5de409608612869a198e21c51598cb5b07d674daceb0df4a58640716e2e139fcfedf43da2de3a64a4ce6e7a8f672f3590a1a2cda3c2c4edcb1a885b09343439a15c62b11b26b44f4ad05935722fb4c98cdae873c9be541c207437ffbe2b7a80227b064572552f878e39f838734fde73ba21d8466f8d62c83321d354a10c3a6dbc81ae53c57bf03dee816b7de38c4144b98983e71d9d05fec4c08c53622a70f80c9b268928b659aa6cfd95fe6fa451d021789a9630a71f7c2b1d20e73624d3e7892591d9cae0654052e5caa40aa689c66b111f6e70ef4d98382a0e3123192eedaeb23de64a2f22e68081e533cb840c42db55de4a3e5646c9e0d7b3fb842f7a640dca6fee3abcbedb40f6ab311494961ee2e823189bf6d8aa91f46c333d9f384d3cd43ffbabfadefdf7a7e9a6f7baebf73a483ce68c775af34e846ae009318e83646edb920a31ecd4ff3bb0eaa9badfe6a1d26c66b86ee69e23c67abe4eef8638a6abac625605dda1229853cfc2c31fcc562179a6078db6a82a38e22c3cab143ecf1866d9fc41d5ce8cfbf1cef0eb67d989dc40836246e5e88331b479959983f4ec91d24061c0c88cb7f03c78a1b76e4f9303a2690f0308542bef979959e06f78a4152eca5f9899424b086320ad320025b893310c4c36aa0be34532d9f025a88b5e11e2b4b986b90c4e0511aa0e2c65d06de49d85bd1d7823cc819504f80b6327913e2b8b5aaa491829ec66d9b75ba5ddf5a6bb6ababc950d1046004fb04ffca53a79d8673d695468bb6cee9eed83d101e0cabce36add74ba5730ed7f04876e862fd07a2998c14a0bfe2c9d6d25bc8bb8873707e97197eaf78390a080744790bd61d5dece8360f156da94a3a61d225f68c92e2b0da4a59817bf7f81ddcd16f3a20d649f82cbd38e18637da7306f8968aca7de2c16072626fed7cfff047607001a7bdafcdb52cda29897aea74c59402564d11e9ea0edae44872ee60a8011867cc53fa38401594a3d38a32e060d84c0329b53e1d9a8190a9358f4863544efc945a1d737cd77f5c6e598605956b7c9211e4d8f880b2d8053511601d6289cef348e1f9727598a21a57f99e830d030a2db74ca7e0d1cfc621fc81a05087dedc0b7a3f4a302b63e5799e50d3d9de36534afd1d5e209d6756923916010f94fa44f079fd8f6e6f27645bb0abecf1eec911e1204f529db990528d435293524904cc5362a533d278ca267085ddd44ffcc2a0a023425dd41764b719cbe5b5c8989b40def1417caf775738ae660db10b4982064272a70aadeb92dc7720ca6dddf8625ab312058ced1922592bacd722d17566d4d8ef5212210a86c8c5910aaa06b43de1ea53aa011450c12e84bc58a1acf17b2a014a92eee2b8505288b880fcf8ddbfe7da413467a0a29635d3a6e4a9141bffafa63cdfb21d124df06b2aa82585ee1f178722d4de0931e88aeb9b0823ef4a4ad0bc04c97d02358404c8075ccb9bb71364352ac4a9223a55e009f548037d98f8c6f0d53715938b3fc607983a7990531605ff47322a511a7b7507eecf4889acbe8f2957dd5a2a53137b4ef3e920a2769834e23931f45f70321dc7a425b6b131a229a8c4d7c1087699c1814d751c7c806eb22fa120e07a3f7a59fdbf51c00494d1d9cc947b14ef3103aacfd51a0268469c76a628182e6b170dd8ce36f52b329f89543d85cf0d0c5b87ea24384f2242bcc35317d53e0a91c15d1c921657c05e1098611d2fda349760ac815b7c61d2da030e67aacd20358f54c255add543f22e5afee28bbeb969a661934590ecc1c3d8cd66633ed6207c7d8605a2c9d72bbf8fd6cb6652f37b51120e634c0a438938dfd68ddc941519e8545fea41fbcb2e65e77158f7bbce6c561a951b4ee6bbab3cdbb36ff2ff8e1048422aad5099f9617438ede1979361032887ff2ce2c2f28aa01f692116994dc05450f572ab435778731277000f48ae60288cb01609ca1ca60dbb48e35c1a85824934c9a7b8eede5408e3714b88fead02c511c162502bc4d0c8f33da4166c16acc1884336e123675460d171c33f20955c894bf05737a68e3081b5882f7441a2625daeef79ec96b244423a4f992628be30db48815a9dae2eecdab262f1f9c54df3603a419ed5fd8dd7e0353181c3035dfda84a06270e3db5c4e2a3ee695b2bf5391bb2008094dc4bf417547e0785c17ea56c1e7abbf5cafb40f9c428f8cb35370ab5092b38bd2b33cc88dbe85f7cfaff06771e4fe664cd89bda8f8a9e4695f4fbaa5b0bf148c6373dc77cebc0d8009c05031722303e7ff6e4f49660202ec20d6d6924d8b716364cc8ff60c837ad1086f484fcf64cf71f747bd0a72ab48b7c8ff61fc403adde3253fe6b6f8a726b20c9ab2b8efe03e6a22dcfe30f004b2cf5219f79fb881931be2dd5a5236b3bb3413e02548b28ad729b6e263c444c41d42d4162cf4e3c83e1c6985e84939a8c4c9f5995613fb353ea5f49acb808fb872f2f5d2382f451541b6b0eaa46057fae52c9d7ad15b2d2034ca8f82444098cd644d68c4d5003622b41cff80eaba989a54f1d9ee1be8515cd41caa27c85bd30875ef752e2e27d934f9f74d2d4eb94637968ef5a420a63676c83c942fe03f1dbd1b2aa608faa1a1093d9fde94e3e835ae1c40e29251a85e4ed40c2f5b7a2fcf62768650af7634c8153203024dd6d63c3d085c0a8ab720b66f022d1b9674dfc98e0ea5fdd854d48270b796c935102cc32ed0a389e79cb3fe3261537e741cfcb5209c5d4725161d2f4cb199737debea6b7497d5883567c00c967fa432b1fd511822a907ab5019e2d0289ce79d25561c95064a3e73bd54470bae829825cf1278dee01931314fb3ab93e573807ed7df3f655050ad51597e4d494aa55c08775be61c6c62ac7336454bad1bc8b9dcef3f6b8a88107f8c87dd0ac3c0d5372513f5887335905743d39cd66f20abde60bc0b96623dfec7c1d6c1962fa06495d9723946b1318609cbb7c87c1e952fe8f61beb352ab1f0b4b6cb14e970f48a730b69ff7be4afd9000572c6a83bf45168cb9948bebece7098e2b02e89b0e00141ca8e9e7517c3804c3f1d2233509100b5fb01138f8e50cde1414cb5d33fdaff786acd6f64854ff0d635bacff49aee8a62db2afdd05736e4ccd26ead9b99086bb046250c0de2a53b12a29e81b8f8241c33f737b506823c7259e9eb37ce7c50783ec24d858cf5503b8b044c962af1be529c79f2e1de78d64a728d02ec4e9360d7d69d5bbdd9a13e2a865e9cb6f9bf2c09a5bf98e7345747df37c335dea394143d2fec9091d3d3d237fdabbb4d21429ac60a0b83fa9db382dda7f0d444ecd5ac1009aec380b5a7b6264b9c4ad50b67575dac4a28e96686004f2371267be1cac849ac5b900cc51370d5d6aa11aab3d73dc102d91f329a5e94a60cca5740a9e02531d35e7231558b28fc6455d11b6b3e88dd9b8a59160dd646746125cdae8f19ccb41a47d33083e93073e67ab23d4a04f5c2f76d4b02340183720f52439083195a2964f8b661b7fd05146c1c6f783896e3b5cbf64a24aca407f3791dcf76103bf47343720029dbe239d897bb2d66d766a8ab1710ce4a1ca111d11e17ab3f29168f315d41338845bbe3ed30f5c75a0406c1d3755155a9860511bb05e8b5410dbd6836f0429687d10ae29b2171d0c2b8be71c06322ddee6cad1b6b6b3593a77a724184499a59a00198b83e1ea944ae574f00753d64191bb00d69db13db487946f03d97a9aee4b3ec6e105a0c771062349ee4d32acb30cadac76d5c68b00b26e956528f2d474a188a03489aa88744fd630f0c889b512bc993046919a97480e96ba2dd6525bfd567f95c5588e14d5c2c540393d7e11c9438e07e00141700610229138e94f92980321ba75df15de13b17d10e4d5947122e217d488590ba802142d1069ba847f060bfd6de1bcf10cce23a22515b86c6ca7f037aae88cecb0e252c5d76c113b07eb5a463ca95028861a0890bc3bd228cb77efd30b68fc8b134492b42b5a16b0b292a3ba2247d457844ba775fcefb05bdd7771fb79f40bb60f48de308a953c093a5b3986c06e0f0ca3785e0060295a59529e69007c7a688d815deb50230adfc90c3ed1df4a9f65e27c05a7272ba58f5a9165cfdf07119fcc228e0f5a32eda758fc690ef6a65b7b887b584bfbf54e7fb559202c7a6fc628c82cba006ea866cf288c7d4990c4ad44b8242bbf80f3d13658f4f1f8397349b61ae4dd616dc24d0fb3fd0df0e267c2409806439d14807a0ac4ebfb84803c3cd0d92b0ba2495fa4f8489ce8057625be66fd40cc99539c98f7849193aab82767fd2b4badcdf70d57dd86b0f670d89c24a97da7eaf510b6a73a95592b287824eb7cf21563f0f8630f767e80c3b04c202ee36580fee19fa80abc78dd28017a134093722db8b5aa122173ed4d1eb0765605bda2e82347487c78e065a20c52862cab7d059dff69c5f01ee140330163df3fbc36f989f9dfb39868fa608cd0dcf17b9e3bbe44b4bb31b790bfdee40d8f62d1c6a9e8674ab6d0bf11c151d4dc4808ced08fc03094f0edf5f73123f877967921b0529148db8f49180049836fed2ff509ab28b58de46010ecd1603680f0a687626ff97a5ffc01f63081d6063f69385b5c8b40c0c68c1efd500410a4292106afc743ae5b054936ccab21c7946f899678d57c8ea324d84228c2ca0b24b7fbf3354bc8d5697571ce0c47744492a2e906aaefa9bd2ac2084e205dd58e25d5427ae63f65c905c2b7c3c6abe82e8380334204dbdb66c32722f645b8d0e054d27abcd5773280234feeb8c7fd907c568dedd247c2bed67d547dd6fc58faa6486f50f4da612bbd9cd68c4d0b24ce2df10a2eecd4183753131eb191859768ecef0c32a5f9e26c8e85b068c9a922bfa9e216304d37c2c49984d16450e0d2584440f91edaa6ae7e6e7abb661f436758f067a9f0f43ca9b82c4edb5583aef9da02a6d0f520c3655db6916cfd8a3d8de73cb6618ae56ffdc2e16de5e4b3c86881d48934b73db6b47f144e2d42659034479b1b398fa2ad90ecf6bdf22c923de9e304070793b4d32ba7f4f05535aeb3a0af4fe3c90442323b331a5416dcbea2edc590ea359fbaa8982e73e28485e86401edc51b72560afee7c4d79f87d7e6e1703d360707fc01f17f8a23bc24e98d19d9f37fe1d19ddc2754123e878ba26547402e9367359d40ef916bc289f36a5b63bdf336a63f4e23f211a3cd0afa6763ce09237066874ccc77ddcdde214e406275aec9eecc7c85ecd666d54ff08a508af33c958cb1086f0b63ad85815eab4617d34a71f486d835602504ab82ba172b559755e6a200fe09e25d55b12d49ab4db4f4f5d134688b22e755a7f75d6316f4edcd88f87dcb8a6bcc9eaddd31d9508289271d64c956743aff3f6666f80b7774d44f5d6b35f10c31f47f6a420450c0ba0f235c80f6b5078dc5ea1abce0cb0144cf60f5634e6c24cdea5f4140b581448b6c70950995fbb5d96499dec3c12dd1260f26c81e98ce7a6dcc40398b9d1efc62c46908768c6ce60b04be82c2510f5411ac9898bcc04f469e842ab79b2abfc0aa369e9d993f37457a2adaedfcd84f52a127b854b038b174e6fabd668ec33cd8540aff6c73381732d54b5bcb6ceb2ef10336390e0747247032da9db6b275f196bf65f80d0d1eb6d06713bbab48bcef4cf78011abaca99c0df1f237ddf34a5e09a75fe1563e09425e2e4291d50bfcf6b85dd25fdd9d0174f9e654440e991296c8c395ac6bdf03d54827a437cdf8e61b7995adb6f1d5cacfe2faeaa368be7d37036b4d40fd91900ad7ea668fc0e614417bb16e62111cf5be8ccfd95a17d877a6c900fae797fa3b6162824adedf38dd59cfa949e797cf8b8bc5369bd3ab017d2cbb95fd6637117c08582a0cbc17ffefb5307a512ac322d9888ba36bf4d8928241cf69e0f866146accac95aa59a7e06115f5db1c732e7198d5ee86186709000915a5c78030966bd95c6e53e079ebff20f65f7bdadae2348880900c1229433ec0c5ce1f22c7302a32cbe860549dbb89890f917ac4141fdcb2900eb0f840f1bc1d8e083e5d9dbd3b38a12338345581e53068a07be6a1bc605617b87986124952ced9c7d199b4eaccb366dd4338b70248db90936bada8a417ae357cf54bd41e70fdce12f05eb40b47bb8bb066a3e7b3bafe7aa82e1c32f14ec3876d9f5e0b54e66fc603929bafeaa0799547265e800859f28a0671ab0c8588b015dfc2a4149d09dc8ed197e74a58fbd597ce28b43d56d8a126e508db508dc28b8da17a6880368dd884c0d1276cb9fdfaa549ba4096d30b58c41ad1338387b3479b791627ffcd9c542a65ba49232d7f94ef54d18c3fc60c29d0187e228387598f15337b64bef3f3133e8bc367a01df3e65efd14c8373c245195380ac2cb2b8760b8278470c4b1bfb75fcd9e523f5a69d9d962b4695b5f659afe6d24dbb26a0b67b857083f7f0f718a0110eb879fff0c79a80e5f72c13b64e8e206a4b36259d14fa31cf01a80617e5deb4ef092503ee1a01ad90e7115ef89ba7a92c55196d0509b6c6c15918d738fc1326da169974f6b0da7b77da8ca462181b27d75157b757490457220a7c7e93d31862e1230c578f8f11538a54148ac72338db3c11c6e494345f7bbd3ba0a486f151bb72402f641e321251c08b82a2bccfbd4d8d93204752583dddc8fb36dea1a80fda6693d38b3489ac43440f55b8337d5b3d8412ea35480cab494dd2cc3a8bfd913492750a35ea78a25bae3221590a8d5a8e054e53c9e926120c63daed779ca354b86dbdd5d09ed5fcabdfce30c9a53329e8517715ffb89d3a89a331d37ce70673158cc04e5b75f43be68d78ddf9e63b8b35435bc3812844648c36b4a836601cbad9bd754cc0f875158a627e48f6f316538fb309532b7fbc1a3051b2bc7c9bad1889397415ebdf556be1c587513ad8b04aa66e5dccfb36bc57e03853f52e73bf1b4aeedafadf7756fe07ce66fcc8a14cd8af03069a0e5e6135045f0f8830b3cd3e2e5f23b91378af1b2a22c5b4340fac8db4456a1b165d76975caf3d4c263abeff92b6ee9dd9cc379e8321258ce4322bee5b7bee0ec05357568db17dbf4df684a239ad0b678c40147e73faf5ddf2440e92142682ba82b54297ff48f1a8839dc62cd524a62e932e39d0eb2cc7db4254f210a70f80640df0aabcea7beedc496baa5f87d2a3be20124f456a1262990e93d1e850e0568ed0354f4128424504d600334278146ffc052846424e6ebb233bdb1c561709b182ec7a67e371eaefc4a09c650d7785c588455d3e5c6f2f0cf70799278a685419eda16fa0adc03883ecb9d71f53d3a353038b29fb48fd6c4c804b09e8be4de9f0749e18fc80065694ec1662cf44de97f2fe4fa9fd0cc32b04279c3b1a3bbb18924c98b524a55a7c5f4053bb65713d07dbcf74182e8fa8a7cb1291209a58deb47997b5fb5f281f6028515af21904215cab456e90c004aceac3e2a1757b8a8963d9a271a80e1856533c3844253679cc8f495dda6addbc98d8d8f0b1903b797e6f8d6736902e535e5d7084de8b98a98a265d60f091a0ff8f0415c654877ded29c9eeb95b9aa26abb6c7a21076ac8db903f358e94ce38b0adbe7f61714fa8c028340bcf92b80126181f30a082d88ac0a07c42fa4435ee0dee6fc6917dc0a0ad0db573c024d1ab868d72e876b0e428624964c952ef79fef55f85355821db4fe1e1136dacd26825abeef7971ec42509da3370ea5ff31971d5590e03de35096ccad299602a55047c8ab3485d41563196c5b4d3880ab605c73eb5eb8165ff5ee5473820e93e46d42cc71f700982a32ecf64ff1a565e58ae1a4649dfab17096718e6ff5df6dc059e9c65c4538072336a6ee1ab29d9138d017da1971335e8a71a433f6d13781bea4c80279d2656c0fae2b011198cfa13b0989e228fe2a8c29061d85155d69b51814235b03427276ee228c79a9ff8a3005e3260a942392a9b62ac89181456c40e9665a906e6ea42ea99d4a632c67f6c7958b10662b01541fa53b2e865f3641515d2a685d408db977496d8a610f8977abfbdd27d941c2add24edb67d0d86a7304cdb9637b75f1a054d228c600ff5466a4df03cf5a2b53c367050e8e7179be9e76e8946b9c3917d146c43a78af0756011af07245aa3d74c84752f9b0d08024c532b077221ee8e695d66e572a66042e65d47a505dca98578c8adb02f7d1c2a94c83f459d58f5ed936a9274805dc4ec5d29788edb8b6818d3108f0b73f733a623b08c15e176e8a40cc179e8371f04a55418fc081e5a9e9d2dec90b69cfb0ede5be668284e337c7a6cbc3209698fa366c5c413e3bc0b199c31409c729abef337ee7073b9b1e529d3ae0418054371e9da6979973be3c56b36e12c85374fe238865cfcb55e5f30ba80ef00d2bfc2c79022c8fcc31cb137c6a878f9969921d604ae98899e9d519c75d95171073f12adf00a2ae17d0940407ba4cc0cee2bc82ef564a87d5b0701df35e417cb9a113ced67f0af049aa5953c3aaa3bd40a5a8d56c8280c0b12d4f0a3ffaafae3503637c889eda78e7faebe83bb2b7c353ac04ad8f36c3d4e587c5ec1e0d63c2484b0aab8b297ccddaa1987d96be1209facf100166d11a7d17203d6950cf1cb3bef2ef2d4039120464f7f828f3f7bb99bf82d170ffc320f5f5bda400fc6a7f300e446033bc5f7ebbd4217d853f379fe1b197a3e1b3e02166f4d54394fd3a014b1ef6f3eeaed1cf8a538051b192df38f161a1afda14768b792c609e0b612c2826995414413f65cd5c6f827e922e8b8d5cdf5016dc62db320a212aac3d02a4c3cbd86b6a4381d27be74b4b718502e89886aa485784f20d6eb07a878886e2ced02a9f34d42016b8114d55eb0ce2efe413d6f0336ad4294fa6683acfcdb79520688fd7a2db9fcb9f3e430a24b3ef359467b858b3ac4aae79ec836c62184c2d666d2b1dc3ccc21db6dfcf566689f87e5872e7938524312c563545c8c7c187124f3dd1d4bbcccb0cb654d32efe785d4afa96f5a6ff9879ad1f93bea579049e46edab020ab9e30a9e8e9be68f76e2bc02c51b24328eb2a6d0a3bcce9e4625b0a9bab52b203b50fceeb063d898cf3184f400447443eda016f1874631edd5311134d726608a4523e091b7b8b7eedb22d9826274cf4700aef3f177196bfc1f92e1042be2439c77b4bbc1dee8e5ca28a69448a9014a1a9fd2d5d14b3103bd7cee397fa9d4e34f097f3491a49d50a5fe66e00e92942740839994ff9a88db1c00b8e28102f61d2e0a37e228424a33e8cb64024d34a8de220cfd2c51ba0091c2a227dc84714a60f0f9e4a0fc04cc852542216c5a756e33c914e18e3a297556ac19ad2d796e633de97daa53ed0d66ebb8153f8cd2fd01b197f9c8f3bf89805c694edf192fd134eb942f37820971df1bf096eddbe609563e7637891ef1ffd8c1f557afbaadc7de1cf4545647ce41e51444591b072431c4ec6cf094c2716c365ed2498a81a44f4f10314b15927dfea8c012dc089549f11800b76680a4dd946003ade35ac309a4c420a7517cb1399d5f8cfd91ce8e8d92dcd680b66e6dde5902a4f86df016007d489413689c72c2d4088f5535aadd953295be45b2edf2282593b14f9e77cdd4af04c2d7473b1d3b02ddf76169695ba6320271a1e0d33a00f50c024622c7f6010ece88e03e0e238af667af9d72582dd973e84bc5477593c5611cde8d79285b41c7096313bdb1431520acdae2c1368a2fa5fc7e2012f1d23d355c2bbd319471b77a22844af1566f668bd54b52b4500bd8887a037a843b747bd46dc97689bb32b00fdc518add482328b30461954db7edd1b158a3a2d97caa11059a1bf397ff81b971bd24e8ad96067edffbfa3093d7e9f34639eb5551f3d6e9bc1743d8d6f98a66c9311a14a86f761171f931200ce45d62c34341ff4f677a24b563309b3441b799c2d66b755ed84c571ac1a1747a8e2d460ae239814c142b6ef7d0f1328e11b620b956b5c5996372b9305d001ff4bbf6197fbe40f62d19396234191ad09cd27dcfa0a1410ece3a7355b4e59a6ec71da467360f0a80b9a47fb212dda2a3b2823822511289a69f3a48f6b913207d55a2735a07333f283287b4177c55d1a309be5287b23b94b4f30597ae7a843797dfc04d9d32f3826138f772116631bcdc1f0f252214c0be07a269d9f92e09071221d12e2f4df8e846d6265f78dcf95a07a6a66b2e054cb1f401ad7abdf81bc410532741465850b06d00a282c81561daac2a7945894d2e9ddb80ec7e84dab9c9444ec9a48aeb0bee07eecfb87b305762aefe45e613a62b2e1b5cd2125b945bf346aedb4f1dcb01ff20a70b9d55d445464330a0365ca78ef64c280c25e0f2dfd1f90e9b3dfb8255db412b2793cf91a914d66ee574d8c5481275f2ffc0bd20907ed232e40cf572f650f3b9b20df3c1da05cc511eb1cafc01f3460520d59540608d83bee506c9d49c5dae91f91cd4bf6af4e7ba7ca1913e0e3d22f3fed6f9fba77096a4bfcd09b47f26f1ff64785634666c682e0a2113af42955a70d68095e9567d8d65a7af37ef9d705ad91428222b88276c01a82e425c044cceb2e4d950d3109d1d1f0497bfa5308782de55e93648329c06aa7c4d0216142a4371d0ca5e10e08afc4eda47d343c37b63dd056e5202e3d397c0d212e66a5f1d50406d8c0eb047a8727d7aa0a6f5c24f27e3be894a262862960318f1e3b8ba8a44433f13932945e0108d3ff43439f5743501b415c76d031acc351ca63299f8987ed37e74d7b5365d9057d7fc72a5f8baaaf0b107b854887b09cf2a1c25a684211017a66506fdcacdf4067505129a0c93cdf33143f0cc6615644217bf6c9e21138174877b948dfba3fbef1ab9e99d5a1fdd4493b98040f186aedfef02e1be02e6ee091b958ce8cb0165eaf629331622a5c9705475faced7e17483e220dfa71cf2ae6b04bcf9ba76ad7f2fd8a07d23a8dac6a99ba8bfc929b403f86c64991af57d8c68d8c820645189038691069634454286100704555d647db9828d0007fe4409c9c35e1cb0fa283519dbd3bed45025b60a8e83c487025fca91d8e3e3d828d9a182ff331ebf1bf5a7244fe1edbbe172ea0af4ffa4445a91d168896e42b9f108de91866970c31b6d4d496e00d6f321c933781981aab303bddd364c6ee14978f6dfb448cb4882843516417bbcb6abb0d800d812d2bbdea9d3863af8d9e6af982d0f4e95a1d53ea25534bf23080f6077ca0a2579a5a810dd8615d6ed065d0981a13d10e0215410049c4f949dfc343736edaad8a42d443d0b0ef5b0a342564da2959dcae5d02014c8de1b16f15c0c4db6129e6bc1c1ae74efc756d3d74aa2eadf1236ba95ac256450dcbd78111bc9e38c0aa0c989f6c0d11169ce76ad9f1603eda75de1a7994705748b07e2fe33f707576c80983a3ab82d9235e63dcee29eace753bd8d2e766cb8966be84d9350bc082cb4f71db2e50c1912acf8766193de087a5cb51ae7897a423429b350e314fb57d0fdf3b7419d72c257df3587c919b6dec98ef14278a6c0eecdaebf830875e591f4aa98d9b15c99aff07071b1a98938496a230159b9bcb091b064d44276ac168268246ec19bd67d56453181b12e453ce92666d5ec0b18008d0f925f8188354108fa508834cfec3f84fb836fd40b3b6ca1d7915beb26c88ea44fc9c7de840d8d65cb149ac6bc1655923cb48c449a36e94c256ab6baad13070991588e4e61aba968630df9cf5783a7a0991a8593f0fc7f9fa01769feebb28e8dcdcc77b10a795b0650b956a94597120825018daaab3023cf6091bf7a9cb98ac96078f008731512a3caacf61e5f764d8a57acf0ee61661527361ead048be13be85ad95733129ab05e4d521a1da81f08107e2bfe8bd92533c9d8a756ecdf5b6b9619430b0fb5e4684d0260048bba35ef5daf623938731956b3eacf37ddcd8e268e3bc5351aa6b85367d7da0c0cf37fef0cac309182b6571fdb08775d887e75489865b6380c599551204a0a21e51e7cec8299a31180f4158b573c5cb6d3a8a3bd61f668c36f7337443d231cc60778b249ed011f3c5ac38142cb3e46fc604d40d33084180a7e4b128d0b5c89e25c439179318c088359b3777d2c4443159057c6c5043471bdde99710b04c10999538670a290935cbabc7a2129441b426c046d33421a35e9168b8d4b1b1c6ced3adaecf038539611e5a92bb4657cb937e775325d2e0b5953b448e7b9cbe586af04d7c1aa4442e8813ee399c5fa3a9f58ba7fdc6865bd27df63692294d041a158343aa41f4686de6c3e92630fd906b4c3b16cceb174e2ea7e58ebd7447d3a3d11dc5cff66820d6a0c7364092aa0be5bf0f8d6923bab94fe830956799e47c1c430c9bb6b6dfc9a649ec90baa78b2b359b288af9334259a3bd8c3437ed7c884fb94a0e5eb7ac86471d57f865326cb15618681198e001ac8822833ea83b2095fea41c8af99be51ad2c97308e88facd973845286a98a592e86f5b93f2a6bbcb72ccbe03c7c21009ed392c86cb1f97b056bad56aede49fe6489ad9dff61d489f59571c88fb64a6d7c2019ae3e980265cb43a44e8da2111a8258140c31e93c5d14503913a705a1c1e81edfa348e06d9c28b4dda02d98185868145cc43d72187082c388ace7e19ee9e2b30f4f18f25c9545830235b46ed5838ed0b2b8193b8058cc0bf5abe9b3733a735e2e61ad6a11e435ea32f77530455aa65c06be6d1c74b9e9d385d4be1e41856f62df0cff507ef5f99717c8c98ee151f72a828472a17e73b66c303054cab0965aca620beb0a43996cd91427081d585376c4f04f58e5f74387aca95daaeb2130dbc08acb4d9b81a4f98eeeed61c050bbc0e59d0a18f9927bc5170e403da59663b295e98a1797e5434df7d8cc39f785b7492fb31a65b4ef8b791f26acc252111837b448fef81b9bf0e6d24b9fd718abc11dc1bbb103a5643d45d504b467364907c7186df40c585352abf72519e8c73abc055a8e44e4d0681cd89dcad907254e84ce83b718a1b643a6b564004b9eb36b7340e834a08ad0caecb1f2576c400be6034647b248d2bd3f8a7c6b037034edf8fbeff6c3bd04f3e952fa3d0bd93673bc332b1abaa31b2ac2792fb742fbfc6d477c02204423ea1dd55eb3a0e9acedbed6f182dc80747f488a4d9cccd280f6355226e6e0473f3805489e77c3ac8b832401011f97b6283996d347e97f98d8d639e1142626365a3f186eca5da5a39712ac1ff366e63f74e8f5c4e13f40915f3e1fee2add369bb880ea668564c2d1748035a13c14f42f65c88732a26859a8fcae53f0d84c593fc8d9754df6639d539cb612b90e9ebcb9b0909caf258aa70fccddcefdfb7e12bbe4d9662936922e31bb927817be35362efaafff252f493f97580725810213b3af048ed0b1089729f1705dc2c1572a9060e1314454b57bad6f3505cbbea99fd98490fb88dbaa56ff2221f6faee10835f6e4584e8152668d1715677ec9c70bac658c2dbae6a9a8f01e6ba59b85df1cc63c0c893e04faf53af156a76bf77c707478cc177b71e5f90f9cb422f1428467b6a7c812ac44e81a38c9cdf192c85cb74c727bb016f9e40385c5114e99bc48d5cc0fa09cd763a9d80b5647ba643b0d85d1e288954c35328f1647bae4a7915db438f2f8e3f6d2aa88718ffcaa62af6cad51d435dff35f2d98c61ed1ee68399e8afdbb60aec14c7baa63ef8c38b03110d8fb44b1c5e9b293cd10f5bb0c7c3973f7ca907fdbd72ff83ff35011d0d1029a63110d1702f9d7e61827adddc5b1068d4a3879c252e494d88c7c0e1a77a7df12934e405e00f4e2145990404c44e284bed917c65a083982e55463d73ee058051ed2b5260c501812236ed8137268cfddf25e5ec40b74cacb8c2684c0df7a19fdd7df1346813994b61fb52800d5cdc878571b448da9320894a8269813e96b19fd3ae5a76a4990fa817caff7b9521724243f889eaac25cc377d6df64c9e501d8d44b30f71aba685f85b1ae9857a23d133cb47196b807d4ebb8766936c28bd58d5acad1ceb31cdb59a6826f25cf866d430c3b34af96d174df7a6dfc252cbb0dcf5fc15946a3b3253380be242e3e40079cd26d11c9e730ed48043047f81bca6523027f88a364ecd66b2c083a3dc3139907225dc66263da3513e49bef5ae844c9e4ba4abd3a2ef82f0c31bbbdff516f9d879bba8a8ce59133464d5043e1b1101a552c9f29661e6cc3031b478bd4e1bf7fac6b79e6c09125ce59988a7d1c1b7c278ac13b79f275fe53c8675a7509e6bd4ab87674206cedde3e9af682da4c76bc8b33292013c4ec41e5cf0e71b5becfb528190b58832fdcdee718987cb6ab679bff3d31809e48628a7269abf99e4ec376cdba18aadb642c990f12d3a017e0d26c617db836d2d0296a36cd4fc189050713c7bd7963750bf1059b73b1614aafae80bd0c6e2552abbfb352a34f2639499d226177b22adfa30429c14dd992354800c4b451a374f55490bd6d02d03663f3f0da91fb52c671634ceafb7b7f3e7499c3699c130f75afedc1ddee42e5940f73ce5463f96b857f0073f31476dcc42929adeeacf672f9325ba53c189fe2ebc162efc1a8478fdcd805796455cedf8ed31e87b932b751b006a33246cb2beb94ebe44a9257a5983fd1a9d9f317d3dd10bda11438323283335bc746ed4bb74f4e3bb98d559d000d490ec843cfbdd7587557d462f09ed0620f52c5c6fff7c54e4d593c3341f68405791c1e9b01ca233f029263ce65ea386b180f1e7a9cc5eee69154479bd017484f03269e4cd7f60226e2801227012f713d6abea192cfa6089383c856b4ccbc3c3e3845a507a5051dd9be7c885138d7a1dee1dd6afda4d84aec3b7fbc31c6232af11234b3a0c95c4e4a4e5cad9b56b8b325d69c257a037f38d293feb77a59c1102504f5040612f6a96cd6bc5ea000a626249aa85d0b0fd854c68217e9db8b6e0b1fe833d13f5fbbd6b0788e64961dca7c6a9a362aaa58d508313cc5fb368dbb57f48d9921633a92256bf49a13e4c00369f7dc4566a66f46732945a49baa75198abc50e170373ce3a381cb3bad4b040285654572e6c8213e2d2b8b4407160d4c17695a5d5d9d653b16a12e39ba490ef49ca9c075f2e01c701f725a5198095803ef4601ec5432026c8ed9d33dc38ba021458c24323bfc2345e006b5b029b0434f28e04280ed1443058f53228aaa314cfd1918c2abe80c4aae3f5582bef8576e4ca7a78912fdf9be2ac9d690852cd504e07e59c8faf35bca2a785417339674292cb5a19659a8a98ce9641c48c35dc831bf61d24b09c78c2b67abfade50ef405c288b036d6e4cac9c1271411af959235f602dc3e4e7e882406110f4e47555b44d04e788956e33439d81f33e5c318e1c156e148c10e003d6008641c26d0593cee1282e5acf7dcc4eccee4ed4b36b48ab3ed1b274046a83a5f102f808aa17062dec3324a1e1e6d415ee1e2257f3f93400cb5a6efc1bcfc517024fef04e0a95b3da94d40aab810f24943854a10dfb89b9cf9d0d10fb68a61085800ba14581100af53c3c326fb103c3c9ff012d91db2d44c31579f29f522175a470c89e8adc62bc1a57113839711395c94188003edf748e477550387d636b3f04debf1d65c1974b39c75202235b2ce9e5c5743148224632df292b88bae45c77ccde542c9ca16864ebfae169e04da5a365b1714c72460d4d4203e9385ac86be04c99b090bd2a071e28570b2f71a360324c0357adbd7fcebc8d65c1693c74956ea85bf6e7d823c0268c84ce6a57c7b48e23205e15bd2a68f43606ef4e8d3fc2a1fce594df950c95717af73c00c845b10e3e2fd1d168bedd362759654d113902de61c25859292b152529cfa200dfdaf6161dd96585be5a6dd9ec6e5decfcbbc5f78b99b18b9481fc8db9327b1a384991109d01a804f38756aba10baa0324c6487e339fe2b0db6acdc1096c1051cb303af0c8278869ad1439702bca63293634ddac1856f0147b082fe6332ecad08829f34a72cbcf969c5a24cb1dca073bde74e0cfd183631dbdb1870c0ffaa61d82f80de0c6c4d616a3117574a82809c06a4883ca63e0314342550efc395355540dd8bb8e49c844818784274bfd86465350a8987586625e41bcff984f6edbb440f1ceb42edf8c759aa184f3ee9fd0f06fa6769f98062978f7438d36e72e55d9ab190ef09b27037e477193157ae7b8cf9e808c3bfab668ec1acaf224cf21a41ae7068a34c2bc22a518129f7794f966369dbaf0984c3b4f88d070ca32d4b988c3a18d7bef087233d6ec03cf20d768d41c5e1eca012e434aa1412d08026a5de46c24cc370f8d387030657ef46d4e6744f342070c77771be046210bda3e075d27a4626f16e6a87afb45c95c524aa536f00ae2782aa0915cf5e3bb038159038a58ba5d1824cb04a237d7a94a842d3bd075a37770c7edf0dd11b20a17fb12c05a8223278d57788109a721b8052b0d3cbed9eac8c48e4ffc83e97bff6a9b184118e2c09169e79e16881127df462fbb4f581099a6031e7d8380b9f5499640dbb1f1a445d02d3e9450f96f9c8a5b43eb4e3205527da9fbc799eb5597bd8c761808add79c2e59d0a2161e02f60bcb96d2013f78d97a519f5be94a7827ddae8f6af915671ae50716b64098a2d9b0e309d7158b269248dafcf3666c47cb08d52854803e6e20ad4173e1d7a683d63b9b487204bce22a2f18a2ab87f0a44fc846a3e4c728c2691caa226263b1fcd6a821e279269d0e38ffd30d852947008a180bd1ab7e431a8fc83585c8d8968ee6fb2d6daa3f695837eb558064ce81d3e4f23362c7a30b8def0e1cad6b527ada0df038ed347461d956e7fcd60a7c98bd36b3021513a403c8148f181c03d8fc3f04cdd2b8f8e4124121c408f9f8cc945ef9169c0c8bf072c6826823242e077f2325d6dd0f5de852dd2af1fcfe123cefd014de7237839ef4ae393752bfc43bc6ef06a2339046561c81a5026660293186a703631fe24a76b13323b1509dcd7be0ae1cf6c6922f8013756e8d71108f02ac42473f21f80d70e710e3953f5f1690e22bbb3b8594837409e3eb7519699ede13d5ca6b0aa33765c198d4c0180b2cfbd743afc36777a346276e9fd27c0fc58e10dbdadf3cd45540204d718cd52f8d87313d44fe9b6e9993e519127981878a32203437695f21a5d421d01a8a5c68de7c23042494758ef5d344ca8c3d063d4cb9a570e736ec3e824f575e5d59093de70b271359c5491b5997d2825a5af0112b89a96897d93dccb15ecfeb0488b83d0f731cda2e920e388728daea48b29a32b1adf517079f3345fb296e47365df70aa9598a735e317e060f8a9eeb5c2bdaa2372c3bf5bb2fec4059703a62a0185f0cfa94cf734cd26ed49c06f7a2149d0e7eaa628f588e5d5afc74815b24c04d3e0d306e0ee0a4954f2290d94e7163d5722252b18561f1f5c1476d6b1d75d000c0cf8de0aef25ba24d976d7a7d128d4e2f9b1b41e6d54d5d5bf9397ceef6c311ae8b3a08fad0dcb013a1424a22a65bf7de311aa487bbdd42e7d12797fb46016fd41de6effc87ea790049b86cd186e31c56c448b8554c416482c96d423bf7e449250ff8f1f35d52e07b3188ea7379df6ec42bf30129fdbe06e08eee3481d8888e43ee481bca4363aa6800f53f4877e2ead080625b3e0bd0c71f16640996830d79e5340e91ca80a94e565d94bf4c8134504c581b878cf64f3e87f979ebf9c6a8858786e028568580422ba525584c8b24ea4711b217034fbbe97b3aa73824ddb74df7baaea1fb54b7cc6659acd7c2df81ee5b88c1e7e6b93c82fb04af84b5d583e3e4cb2ebb9a32191397f13b648140cb165fd0803256269bfe1d4020e0c01cdab84f30c5d2b11d43a57c7c3ef5747814508607ec20ca4645a1a0a3e2445d96ef6dc5f7ec5c7c73a9caf42252370b34617b92974017f9924b66764b4e4ecd2fb5814afb2dd413a8a9b12183ec19fed07b5d3839a2643229051139805de8821b962e301161321b1823398e7c3ad40cf155bbbe254af605d610aa6b9f2635b5c065c443d515fd49594053ac6d54ef8875631679637d65f12cbd9542812b57722090da030df62683e30095887a65d7f4e28219f3ed27bfefdab21a31b1665fe59101154698ba9327ee232453eabc5cf943d7e14e33ef703e4b00f891b0e62579567ea8df6063588001fc8edadb34c76cc8f49fbbdaf152e5f60e11285d13358869156283211fb0dd002962200707290494e6a6d07fd22cf3888e40b44d7f8222df9eef51ad11a94117a706c241cbf573f44f6fd502fc345b68cd12ed202b8b89d1072dcd76855a410c889923400d1f68ab640c0ce55e27d8f1e5dee76480523b45abf216863e158ace23579ac4fdbf069fab8476a3afc580859d170050d2d39086df7be33bda9d9881e7a788de0dcf7bea40905a6bca36bc2d04dc81d692a5e11a7cc3a6a7777731c40651a2b5da7acbcd00680c5d476a74321c9fff4ff3085b7eb36103cb0bff1e9b38d0e398e1f9d67c22288c1257ceb910d0f5942b26aa0e31b08bff4c1aad1cf151a952ad91ac6889b2a79e076ac00df04183578208305475e7453d6abf66c03ede7bd3a9bcbe386ec8b3e56e5b3643d97164a06a4e1e04ea7c6b945071fd73c4e12275384f4fbee39271612add7343edcd19048e3dbc72cf78b90bb2927d989274122064d39691326317055439506bf101c5c763070f87fc5cd8233b1c229fdd02a64bbf2792b86d864eccddd7c21a133846ad737deacbba40342702d3ffc1e8b83dd2c273e0cd7bd2cc7691dd290118a64c3965e1615df8bda12fb1218f3b5a0c9f0f79153f4e4590436f6311a08ee66044bd8b8a534c674385771d0d513fcef14b43098489126497774c0ff59ddd5de28df632ccb1a353b40ffa1709a40a073b303ddb557532422aa850e31949a768b4e7603cde96d075c87e492d291418bed49b96cf69e3c651f33247a5e9400c698bfb665b3d5a4addecee71c0057c84847a65a4b0af2f42660d02ce4a8a8c907484038ac40e43092aa4d050bddcb00afbbd70b253bac8233b753990da2223c17f2f03354f4778c8fd6d8d8b1f43c2b7c02e809c0ad65822e5b1688c1f70f0685d0c31742c2886793bb122ab3cc047594d387930b10adfb88ce10d84703ddb75f393dfaa24bc903643b889611c7b03d9b88faf7060b5c43ff8464a42514c8237f1d8fb11bc6c44ddc952f56954350945a02a4fd537c9caad27f120bc8e3278f91bf2b68b998991b1955f374dfadf87a978aacf0fa253743b735678f36bf52b1ff1783f92589e1394568e5c7ea924048eb632facbb07aff3456fa96ce301c4904173ec82c728007a2e7b9402e3ae81b1fe51e980cd41b5b83e079181389507cff283a610c1d4b0aa06641344933bcadf5f6248acdba454bb054066aa3aac8f40a4701a20ad8594a6fdd14a6db03b961347f407058cce7c18cdb50661b842a081ccd7fdc0de7a0f4428b37fb09ff1da08e912d083ab20f3e53fbaad162aed0f8bbff263bcfd34978d2a78e08efca093ac15d8011337bd7617c001d4b5c45253fd83edf9151f59b9b280dd531b3a560b21d2aa37c77c9d25b83a343b993740bc5e568e49f22546a8599d622874e276aae802166b2583a5b5503cef5ae8f1af4c6e5e1314be8ffdaa512705cf7008f849a45cb4c473585e6f892c06f620954f76a077b3c92cc62ca368f2de1847a8b96d7eee47ec584bd8514a43f8ffab21bc07b41104daeb82995c30ccba9a0e251d2a102168e36481dce2c0d163f09bf18284e080c6488505424ba5c256ad2ca04381c9334548b60574387598b96fd7f1d76954156f4dfc445d8b88ed585ffc2104c7858e5cabde0b8da691496b7bb735b9a594322519d9095c094609453b64fad3484b9e93274b261268594af776caad6e49f5bc77ded7bfec7c4dcb4442510f0da81f5e8061ca0b9313198511605831005330a165cc172699116392e4f900f0e1872ac44801922d26808225082856386fd4336008c0194c9c0126d7c7e027063450810214966e505a413a0d71c39c73ce1e6f68ae7274ace8c24486972a5670c40a9acab0a18c33c4389921e50c1472fd1ede50ad2408a28647ec124446d1d413793e8f8e183c5480058a29a35c7f07930a78c091eb5f20450aa6b0c01baa1b971c1480494111b97eec36f9114956cc39e704bda109801e39cc914222d725505084822272fd1d6fa8ea3821b50206b9be0e6fa85a219ca0c97133986fc7c832c60a79be8e37346f5217343806500031a41003863c1fbf5e4c4a00c316585280c20a098510355b2b7e07bb5b8c10d4e4f99f373473c894084396411846e4fa9f4385eea28ee45adf460d91ebdff0866a17f50421b07202a65cdf863754b7271d308ec895e96b784375b3628a1f2576f80835608a57a2162f9074783145982861b6f862875cbf07e88b2e72fd1f4082e4784375bb225a10ee00a36403cc152610c204b55c1fe60d551d1474395dd472858a92ebbfc010e5fa34b0121266b821072eb40c219f20620515ce1417f8708145174170a143aeffa242b48af7755dafa09ba6e2eb17242e50f8c224d7b7f186aa1135d4787122cf7719d9e450e143835ca3960aab61b8d428c68a14acb0a28b5cffbeac3023d7ff2b9ac8f5412c72c8f57bb01893eb03d5b8e4fa3fb21022d707b294450a725dd2e2895c1f842d74c8f52d90812d98727d225e6878bd6aad482899894133edcaf34a9729baa45053830e1722b0105197b8c872ad5aaae821572c5e86115dbcfbbaae976b56c18214797ef73a620bee36518124cf5f7d3184956b9b9e92c8138bce9309b9d65a6badb5d65a6badb566b92087ae297c9862cb0979fedd52459e4f5f3f905133a3531679ce295158b5d65aeb4e9e45042db1f7058ba2498597164734a2c832bbe1128563b7486293b76d73bdb098820595d78d422a494d97292b6437d784992b8b231b1750a0a9c2a866861566b67072452992a935d14c79e1621135c3840b2d2e453258acc0d262ea66f922ca66191343b785118b89122e8b266f04ab2b689d9621544f9c653a62b718ad66d32ef1586cf2c4633187f7554bb2802a9cc25861015a142d69197364015434a9b0002b8ea4a02149920287a2055cf1248514240be082f4399a4c6dfdb295564aab8e272e8d1c9762b872e472392ec5c0c50a3184912403d113198a7ab85549d365d174b020430e3218b1e446278ea0e59d2519a05892a1cb7dffc273bd9c80b224d39f5132998c05195680a48b4ed470845ad0c2ad39c18223eeab091597660af874594a607155392e359122ff52932b4ca83a4930189d48622ad31c645cbb45cce8da1c979a7851c495c971a9c91832382162e2ae725c7292828e14eecc71c9c9121b392ecd30460fa782eef60ebcd0c20d2fc8eeeeeeee186eb6736d312846cfb12f6b73fe25c494835105827e3ac3c9184252b6a726b8ddb382843d665cebb13e2342dd07ab5f2b16c27a0e17693deb8b70dfbd11211ae74cfeb45e7ebc2dfce2aecc7bcf61ef693ecad8ccdf6dd24209667e437ab2bf63a97463c60d6d035ac8fb8ef5716db749eb240eb7928c612bb7f3be48eb65dec345baafc1600d4c9c47642d066daf3c49c8128757929125966164f9f3732207392ca5c615d785a5918cc999bf1f8258cc602040637ce0032d5c448a90d6771f65ec65f007baaeebbec320f88005eeb7f0c5edf4dd87f1098b16b64464cc7bcff3dec320f80057996e7fe8442d2ca50616f7bd0fbb080bcfc718dc772c25077fc95509799f0ad75f853530a5d3978bc3885b6bb88e8d3c87e0affaf9e1dce0aade5ff5dc6c99a3acfdc8300ee563c70e9dad8ba1edec6b2a064510f42efa916c21f9124a3a5296b827cfa2e8d2684a1c76b307190b5142f16f0ba7466beed3126ace6613ffc148618ca498299b4573891f492319258732cad1e752554297e240f553314b563df7f50bc17f72d063f2064b407dfa1c547f0e749e2a2712e33e2a1c420d679e218ce0b92ec0e248bf10fc371a427d7ffbd14b802a048b00bc7909880e4aa9fac54c9b62507de95f8b3c3f93c8634bc41f9985962b57644d8350d67cec78bd646454d39f1479d8978831f95934451ee9a59f6a2a2b8e43764327f269244a9e1ff3c4b52831b2d6535ee38c58ff1870f800e4a5c28d1ebee1fe7020b2d25aa794524a29a594725229250754f5616cfaad1be2c2ac94db263729e595745220b449bc575c07e2df06af136ef430941b46a60dbaa393d2de6c383d95f3757c839e5a5cfb405cdaeda3106c73f78a9baacb7be50c0264851b9970dd95ef6d822c4109b61792bace1b6a2d0e7abb3bf548bd9dce0c8c9cb41c4d1a35256530dbb918db5dab238f1affc3c01e5f7212931d6a7af48064d2069bff74cddbe994d14a14145d249ddd1435e53eb2a1c254713159bef5861c07894eb20271b3d70f241079e4ab96b81209cba317686e28f9e3a2f93c8aca55ad7c48f58ae72742a41f1a41c24074caa111a41cc2fce6def5c1fc6dde8810cd07f3a22330999f79966c72c1904fb27cf9c47d4287923469e4a054d17db9c47dbc972f84e65d2ff33580e65db2fcf120dfb12bf9fd9c8a741a6e3515717dcdfb27858585b8de0617b179d7d77c456a9ee6af1897bebf74288fa202459372b0dae028635d83a3941bcd93311eb974d93d329c51a8bfd0a964f93964dc501ee121aa57492877a92807a5fb181c675cff469247625c9d12ae7f9d5df9b11eb9f263457271686404528aecb8a37040b961877941b9f2b54c18910c4b40e71fc8c854ca96c1acb8321ca1e6f72f00cdcb775acf644c65853e31e2b8012021414145351d4509239dc8a14b1d4d41426a922f9f38b9d374b8f2639634ea94ce9671b21286caac84f2c88a54b7d42487b28b4c924c5dee510cdab23c8a729fbcf84f902c2e618162924eb24ba52d619dd454a46b4992f2a89564902ea16a209157dca71fe93aa883918ecff151e76b212ec77795acbd5729c7176b2c71e5bbcf741a89ce21c7e74daee40298b4d3f94c68a1300ecea8e9f704b7a1ba269b24b9928d25f746de799d0f811e082e4ebcc0c504a83184e6cbaf6b2e80f939e6ebf86291ceefe0225284e4f81cb888fc4d8a101daff345e4e7f8fb51fee8e022fe3a709431d6b33ec71765ecfe90b1f96ef3fae834609f63ff7e278536bce12b13c1f11dfed5f7aaff1b4f3f4aafc6b79e88fc71190e1cda0f87afc7e1dfc021986de01a3804ca3fe48f7b7197cdcfc1a187c9f36138b434f00b872e26cfbfc1e1cb06879228cfafc1e1bb300d0ec1192c83c39efc6ae110c89540599d5f2beee1121163f3ab402d912796dc4991677e9ddee4e0fc39abf48e945575be28e4440e4eaf1263f39700b1e449c5865d8989eb8e83882b8dde5949465d6ef8b1ff2a03c04028f7a7179e73832f8932461bc1eebb1122d87d47c4ebb82279f52dc580b2524e282eea6c51c6de5e4e1d392bddbe5b750772b95b712b1528bd0d883ba3cbfd2d3d9244942a35262644a13f29729f965522134d2abb90ea48460a555fc6c9eede906398fc2f7706024b0e5545d51bf24ee6606fde90e3d8e28676ca4e5931d6be5ecf7943931e1539d81d11d20d3b5957f41a81aabeaf2bea64f4ad980fcaf673fb8ec83b99fb548fe2b1d9b9937545ee13ab4a36e52086bae12dba45ee538418395415d12197dbff70ba750d1c2e4d8e5bb68c206ba0fd48ca7268a537646be470433f72cae176d4e3847b73e5aafeb574433b7593c4a54734949472d8c972ffd1a447b9df33923f5b918cf51fe5de68b93ff490727b49b99f4611eb4b0e3d2bb228748b84b8e1565494fbb7221bb7a2dc5fa162cc63ac50381c52a1324c7e14f2280e937f24e6fe94e4e1bae34e8a314a96c450b6ed3b6a2a777f03a6d086ed94dc8eecd496d4b84706e972016b2f2d6ba5a824d418e6452fd418d64d2e112b640a3586f513b95063291c44107463c08893a21cc470e1c315412c49117534a3a2d4b049c0095210484b556c01430b162b284e0006892701133932753ed0b8187f36b757c6a8c521fd4ae9eb65ed638b438c514afa93cef8515c8cd14b8eef4a3551b76337998a5a26b65de692f27cf9752698fd5eb38836ec47fa21e0d0beea6df521752d8675509f6e1d1ac9f439efbc0ebed0089df282b813417ff9e188608f18f3ffc99e43c38716f24608f3733831ac83cff53fd74975b044e83179e27f9593ab56d56e5ceb762c4f86c635f3381fbd211a35df3eab5d754e62065ef4688841d5d5e3a36bdd97f9f845dc87f5f17be623cdc7ef27add44c34c2d6f28adf556206eda57bd87cd84b3ff149e0c2cf0cc949f48f42d481e8df474070086c890ae81efea01733d8d13dfc77d830176af310503b281a384d5e5e37b89b6c70e85e831baa9110e0b9c6042e9a9e4599cd198f95813e12f552e6b6820c6179386c31de6db647013d3dcd75d4d7611c7429f7b73874a2ecbfe1b0c5647f2f76646fa8c8e30ffb0eaa280639ecbbbb63b7fc09c31d06aa4a4375e1331c9791eaf999423019ea8e0f2304514970a92d2185822c4d542c2b54289c4890274427011347d4b6265078188e7208eee8f172648261492da1d229636cc5e860fc5983129b5015a24253889b1dad1bcb0acc4686f5aacd93a492c478fc8ebaf225c7ee22c76f2f3108a78d9cdae829c6be32a5ca94a51cbf9562108d8f4528e49824472639badebf9fc87cd84744eda489688841351f9f7af6145bd64443c808139f480ceafe87178f31c6da1621518aece4b129c420c7171283bcf701a44190dc9175a2df9cebcaaf0ee7a3dfece2099c4fe626314a5d3c71c3062c49eaca97dcef44b98bdc8f63e3833dec6dfc8d1b30182ceac6d719e7eb6c03ca0b8d8f7ef3937949889c1a9fd3942a35a4a7a51a9f8dcdc33ee7b9ce1bcab1b1b1b992f375a6f175863129d1f862c6e9dc45ce247751e4a9f968cd376b3e995b0437af2f03dd4e723f95dc35af4fe665dee66f6e6464648e6ebece355f679b36ea2691a7ff8bd945a7ccb532c098a1f9641f74d110329a06d5b35a19341f8bc5adbca119160bcfc88821e27d747a9fcc718ad6931721518adc2fd55bb2773f554b019dbd272191a7df931ff50264a7ded413000d72a62a4f0146b2ca474f4b47d6513f2ff7fb8edcefad93376fa8d6ce5de4e98f3987e8f63bd9e818153b2bad95ee94e0cae4c8d40253d1f572646a61881c2a6801e97e0b32b8a0baafeb7a41c9335a700188abca91a98523605a20daa1dd9a239392339894444d2f48321633a53b3f5c1a53e8d002450e9fcab53932295122ef38a14409dc40491253922472f83d3d4877f98fcb63fd4aaab9b13c57c751a970707ab23eefeb56d64655b3727134b6bb92eb64951b9098251ec113d063c68c19d31eebb65a57a6a37165a51c9d3ca95743bd9a1ad652afa6c6b40102410bf6006d30326e38694c98bcd1572f8f4e2b99ed7dfda42c20dc6c09c620dfe13e1debc8838100727f3880ec1d1b87e6ffc69cb37538295dca28a594aa18a5a4966e73d6bad139638c314629e5cab9961de99cb3fb557fce3a65f458364c5c8cf12565534a698cf1467635b8bc26add1c53bf2dc2e8a09e46084d9703d3796db6fc3ed0cb3e1469b29433a5d730c4ae30ced628c118740e594b1975295ce6c49c97594524aa99452ca158beb28a59452cab1ba19b59aad6e46a9ec94895bcf50cab9bae8451c4ae0ca6ec76f88ce53eaea62e49194524a29a594524a6d7c8cbe2ddc7ef9b4bb439d1c256aa5b5ba1cc442d4248fe058667904efa93c82e777106f5b0e558ed5089ee387f5e72aabb6ca7539e2d75a6bac35c6aeb6fa7632b5d63a536ba5b17155cea69b33da5a9fbb795557df7412a0945219a3d71fa2e30dcdc773ce9b5965f64c719a4637a51ae6e4258fe0596a86f4e5770f05e7e33c75725e37382e53029d9bc5e95577f7a455ca2e5772b9b252dc45b3abb8928a2b7174b0b3a1a1abf1c2d0b470984564ae6cda9a6290dd2d251829c1483926090d5232f13061e84c1266d231b015b88a3b779e71b13dc33a885fe414814ead9bc579e5f8bde2b8ef5b71ddcb7d54acf8ed31c8fecafb4ef515c144ba2d534d42e4f1b7dd4d718f74d11204c82c71cfa43062510f37ad9b5e03a4d00a379216aeb3e96a3c8fe5b2400d04164d6bc6a99b76901ef03a9879cadc1cbf08526e26d6cacdd0b4726a60d5d874d14b6edc9187bacd0d2701073f887315243ae174919b9a9a542a2f9c4b94d3ac553d7d57c96d82e5745064efa6d844ec2cd97d065a4e8dce02c10a883c37861a366cdc90403d3d3df267c571dfcabfb8f118470caa407afac7693247cca0a3ba87bf183b56756b50345f254d164af4a7adc53baa33e825620f7f2f5d8c7237214613f7e1d078dde0ccc701135bc1cba8f20512313098925049929464ca28989220fd1b4d773a414b122c2fe2a27325994cb66405160a52b49294548832836486d73243c76ab574726b47abd5f25a1f8fc8ad9f2d26246372eb6f95dc6afdaf00456e3d8824b7be87052772eb8156c8ad99536e254912a3cf67cff33c4f0531d93be2c4a4c2112ecb9373652e27733f392e8527994ba18bcc7939ca036042a10935b273fb28c656837664ea23533a001aaf6090c3a8a50bcd804ad126f2c9611fc9b49768403f66c994bebd24a420d37f2165fa1f0231327db0042032fd9e12aec8f481984a1893e903214acaf48310a520d3ff000428993299e045a69f01fa44729089c08ba21e32653ae14ba64c011f975799f33af9a9b2cd5cab93df96b9dbc9af669ab9998e867375359d8d8b66a6e686151ac9b00e6e3a37f68091d92ea6a38e7bccb9e1c69f2a748c1d63eceed8dd91c6ee27dca42f99f8f4affc22209bd33d467713b8f84831469d3927954e1d989c2955b6fb72e5538a6d94f5ba125b1d816a256537b74fd2f9d58f66d5eab33182f4adfcb939f5bd5a6abf036bdf1b52596c75b0364c4509d9c4001de3733b5f1402bf22345000e3884c68e7b92e020267e14b91d0055f040400e0e2284a28f616c8b80fd991675ec6bf70479699f91fee9fcccc476f68c6a6c647cf068d4fc7fff0170a3766fcd6b5dd0be686b2c88fcc8e5a375afff26f73ffa68efc6cae09c1fdf79ca9c30d5f5eebe2e0d3d40d250ddf7cbbbe717c7b43aee75c2e3a66cc182c3947a5aea5399af33b1ff70dfe0e88fb776cb8709f06ced30f07e77f382725c5e108343ffd6cd89367ce174aa770484f479de04a263188fecb071d72c5a1acc1667b4614f9c4084bda279b3868cdb8345ff3f6551f4a1a77b3a972a85e7a43aa8ae36b8e987138def960f279fccecf0f0653bdfc0dfc602adc001ebff330893de081779ee7c1876dd8039e079f0783df12fcac8c71bf5357cfad6256e178ca89f023cf77bdcb254254ca12873ff2c421b85ec7ff70ff5cafc3e70f77bc4d11b6ed13c100746772b223e24ad294f6297d42975c7243b90ffdde41c096a964b1581deb6547955a0afcb61b9c100115b42652fe944e93d2734fda6c311996fb6553948a8a4c4952b925131130e4502a5dc9dd3fa52b2146892b5f02259a6c9c4d173d0e74bcebfd73fd8effe1396f9f03df88d0dc79f085ec3c08f3e78932362516b20373ac0121e0f3e0223fb003a2101019eb0fb283ed86a5c03e0af1f0ce87bcf20f5fcd6ff5f60b3fabb0857d21d4bff987b45f97f375dfe3e3b103fbf09837d46117eb69bca1d5bbbca1ee5d1feb7574cf7a6ef5dd2865afcd9a94a2ae92d39383c0fe90f31ba1f3dc70e0f78f7b9a83c3435e19c7db1c3d1cffc3c31c78484fc6f1f83f2917e7693c87f3859db717a5b1610cf4641d1adfde100dd8f7309d8fded01724e7619653b9761e076f3938b4301cde1756816190fcfaf971a0f3f7fd0f7f7da10e6e3d8daff307e5869396fb713c1ed293bf9f1dfe6cfe3e188eef93dfde3f27bbefc3f1850d73dc0135caf4bf8f59ca9c9e6a505153535150b5272737f223a424a5a626a524243f8a9a729917f98ce6349f4d452935393dd5a0a06a4f4e4d4a3d6b5a1bf511525212521fb551d37a166b112a2a6c595117b56c2aaa07282af5e0f1f100b953e6fe87b7de88833c3c7a7c3c3e1e108bb0e5b033067a3287c320f987e3577d18d85e7a43f8fffb42780cebc0cbfe5ef6778c819e4c7108ad973df95b2663fd4684769e87061c108544e0de0151087c1eb8481110708fdf791e1fde1e9fe411b66ce7a3d08e0f63144f186b418840bc835fd25a7eadf7aff53c1f2cc88e8771d8015168078e3226b4f3300f5a68e75b6807f74cc65a166b29b5fec6e79f94eb5fc36dd4a851a3468d1a356a7c9d6dd8f8ba461b19b9769ea3f9c2ceafb7f9866e705e62b007e855bf3dad6559a353df5ce539387cc1f04603d315b698c3385f3842cd37ef72798d95351f63cd4b0cf6b83e04ba71bd7f353fbff0e6dd1baab979aebb1b8c3d8cc76a5c51f2d1915f71b05fe67ede34d4c29ee47ddde746df852b4b9afc89427d5434739fb02ff87c890ba0df82afa75c00fdb12fba00e4e7448d50f392dcdfb289b4b966881b4db511c881bff33e80b2a4d5ecef3407dbc886eb4d6a9fdcf9bc04c42758c88edd6886f2481a6530cb270787b8b20a491483a2fc96e1953e2e254dd27c892bb32ca72021d9194c49c6fa618e3bc98ac4342d4edd4a2d3b9a328a6a1a54cf6a71aae73df6c41028dc3ae8595681d093e50f395718033d5985c320d27654023c3066cc18a7bce1213de0ce178566974b8b415dee974631a8c34cf9f7909e3ca427cfef28077b4ae9facff61026ee2929cfe17243497bb2f3f40bb0b3f30dfefc064123f7a118e66fb37fcfef89a11c543d216950547ac8b2cbeca79def0989bdd41cd4a1a5fcc7c378acbfa71c3bd40ac9fd9e42eb3092d6500ef63794910e9f8018545219e5766f6dec6926e647fc3b3c947712dd34504a95a69cd035ed0195e74feb2428e28c07a294522a71f28422cf773a060633c6488113279c7084a48288a93a43539e566a92ea4b511493932f96cc4878400b3424478c9824c961f60025494c3308a1e40149a03a147a3607bfdc558e4b4a4e782d2d51a2134ea5ec7ee3c5f599776f68e667e48cfc5519575a4e46e6391919ee7ee190b7ffc3657dcb71975e7ae9a5dc8febe387b688f8e3c231c65898091a6c25bbccf159cfd18ef51ce775ed7160bf22c929e57c6eca29e5949999796e662674654a714711417a1c788e52463e6c2e711f9783bd4d23ff79e43e51fce72c923f52d692fcc9bbc830eee332647feb0d61e9bc8aab57e6b8c8bd27399555197766d673fe0aba00c8d2822c71228e3f4e8b5f0c8ab97b80a4bfc45362a6a46c6aca5a6855c6ad1a90b28fa48f309e6864f23a80cd23da7d2865f3894c5a7bedfde849a4c8e3f208c71137743146fe75e6412ae54a2499342391ac375d262af5d1d7aa54ef17be72eb0b6d9e42ba1269db5e25b1f538f0fc23f2f8d323f789b2b5979e3295dda5cb29739f302acd22f70925929c9262e4530e27d13c92fdeb064c4d9eb237921e20b047de97b419fcc0b2a7c9ad1543a14940ac9227f6e13d34df061e73202986a43aef9da424e33a50dc6071c3e8247ffec445a450db42f2e9c4b097833b40f901f184b8501123424032d61d6b4e515f28c150c5dd9d521a630c928daf74f9caf366712b0e87b8f0063fb3e31fab14eee7f0a504be72f74b8544189d6adb10d50417471814700722bb39a7063a87ffeee3ca9f41087bfe3669ca91a949d2528e4c3248e56792c14bae3f9da4bcf1722703e2529ef89b4febcfa7923b32790cd8de4a0fa828e01404073fd672e22b7b7f54124d94a69c90bd8833b2632b59e847dbf445fbff8cecafe39fe3378cdb0f5edfc8c8b4bf2ed78d6e5b75291b241f5e3c76d92af5188a5290fd75bc658c42e215c52aa1d65aeb96335a485070220c192238b2811ba0c6a0a054c2962db63cbde045f17483122c6242d081394185e7cc781d95540ebfc722795b69ad7495040d546011a3c313a229b6b43013c5161c9a98f7755df7c6315a48b1f0c2d30c4e2c4df1658b628a3050ee65e264c3840b2624a0b92e262652324e8e4c4c96e43075d2ba59d58aeb58565e4111003916c522abba325f6c2266895c7e8b1cff00d18bfebb86a5e3a4322a6b9b71cd0a04fe903f351f7ffb2800426dc8c416a0ab4d8c4c36400ad16022644c7d2ec47577bfeebc8e2e57adcb39e9e0ae643890b96d0ab7a7cc8c4a2929a986a456cb1b627dcbe3c0b3ea672c919679e71ff88f17452872fc05b8064282282006a9b647723b9b4569b55adf2d3cbd157655dd6a48b547b2b328dbaccea2047902c2cd7433ded0f6331e079eebd7d86c1988535ea441d105397eacd66a5ddbac962405f84f276d76f65ed4b575c6acb596da95da14990fa88773b95c3536b55be5b420cad9500f4c1b1b9b9bd7ecc95ed4b5eee17f5f2f3abda8e633236a2de946fecc7cf8caf672f78b4232ab4c693fab85284ebfcc95f9eca521f18412391a2d9623b1fc6bb1d6760a0009285cbe2c51b3a20769c50f38d81e2b434c996925994c76245ec9f406a554504a63971fa464fa3f4801b104105053aabc10c409327d20415ec8f43f10022aceef07223b65afed0be48354cd0d510aa4207e90c2f85025d79ff186aa0f5b7c209190e75f6f68ced083095a35381080872ab2f42025d767d9d04981c20309b9bee70dd59a274c5290d0a8c9218a19b9d6e7bca16a8520aa5959e014254b14151130b02c8f284620c5084ac8f3b74b850b5b6badb56576108369075a9e4fef9c53096fce39e7bcb88acfa18f5cc15cebd10db91e89c9f51f9c814987292865e40a14047777a0687941060c0bbe9ed490d84cc9987df2850a355a9c6c9e4c417125d560c181862317682470410897a32892ccb658418896a3308a8e987020e30425990bd6056e8b5703926ddbb62a68b40aa3cbc311551551dc2b872232a5db539ae569cb52dbb2406d59a2b62c531edbc026b668a7bd82a6ea525d2f2b64326673f86205da258a902e53b61cca6032a5a02205d385b26426048b1294274a8438d5a008a144c8144d509a8e087932fa9e90b4525a2d78e1d21c979a5ce1056dc9c9931811b7cb71c9490f3b29383102cc618b135c1a26a42d3a90f0e1dae4b8e4c48a0b922c39215a7232c61126883c168fd825b7c9eb89c72213513c167308c68e80628cb991e3120d496a947d4efeb42f3fa39634c924c6ecab24cdeca2ea644e30fb8b946c5f1eb98c1283aa945f3b7ded25f2d8a75fd71cac12833afbdbb73548a61dd94a22b2f5215b1db27d570e97ba8e6e2869921655ef82726592fb6c336f5f1a49c9e1502a65fb5151dcaa5379181e1585fa03e2ceef1cca999cd99ff6673e6924690edadfbedc9837498b3cf6372eaea3107d5648a28f6a87f6993cb40fd744f4a150449feeedbb0939b81231a8b3fd767ab7eff5972cf1a7919a3a83bed26664db28c8b6bfc816894bb6d6beffd05092c49f0cb808da3e12d97eec22b2d521cfc0c47ef55c4f6e3f573d06d477e170ade522875deba4b559becc7be00f0b222303f3e02dcd5f07ed47a1d7a5c130efa310cd47a10bf360e6657e06c33c0ca5e6a390eb6530ac6228331f856476d4a18a4130dbaff97a64ccbeeb039231fb349f53b5efbd878138686393ccf7818cd9bfd5daaf6f0107ed4365fb8d74a53390b3ee61df43ba32abb556ce3bdac9aea37226674d29fdd6b4b3283db3cf51caf2b2773e27d79a3d25f79cf4eaacd6fca6b56fbf8f74068dd43da2676d876d1711b4bffa7a8b085a29eb1ef66d7b1163f64390eddb318c5a397497451e6b27b6ff61b92b4b439a6f71c8765af943b61c9e13e987a7dd502737533fe9eeee4e8105df9698d88beb3fbb890d377a584a13f7799913dc59420e6bf2fceb8a41dbcfe96097a6fe58002e72ecc902a4e2b1bc96c8516210e33fd83f7d45c7fc6b5051397ed857f48f3ba970c8c3e250878d1cf65383919d8bee6de4d067339f55e069979b504ca7f9e43ee184623a4d2db3cb84c2a7c824242f90b4f09991cf7cd61598451e7f3148536492ac85f19f98524c420b2d4d579cb2cba7ecd24b76da4e336fba22bbf8ac27a7450e25174dd28718f39759f4500162f9255e55b23b11f24be4e95a3fe1d87a67350e7f83fe69619914f2c861010ac0fa2ede4b4b77e3150ed491436fca8e7978412412f672c3396b2d1e94a0d2c4b484d64158ac8779e081f71b863540f5dcdb8779c0c1a4c530676158c51e744f571836b1072a98c450ba0dc31c43517d14da3ebef7592b1de3eb25f8515122bb0612c8c106fa2181787ceaea73082eea7034a600f7f11d3948ac9229b5d4e577c45de51824a3d71e02bc2c710da4d537fd0f885bbf33dd24f716e3d55bfc41883807e3aa704ffe0fe346196b9a8392ca98162eead4af8fe867420bb551c4c07f03e346198b42dcd32e6da3c8e3bf857139b74fffe949e23e52616b44b123893cfed1480a8beb53fe3886dbd88bdb180a7dbd7c4274dd1f470b37eca7a7277f9232e9754a8c31c87c70c782e848efc84d73374d36b1ed3845e48686eb665cffb069e0911b85a2500824611207110a6b8ac8589b715be68ec3042476c05e2491d2332497888346dce80de1143a02f57b9c6d447051e795dc28e3d634e36f3fed4f4e2623e2e07cee05c38d1edee186718a88aa7fc619e777b9b218b42306adf2acfba99247befba28cad6cb2dcf856c61f1b0011f20108ee038bf88bdb0f10199b1f8292a88b7e7090fac89c54c62ed9670e88423f646cc65509d1845b69fd721c9c8d03c98d320b064ce2da1c999e3ce5f056c182e40913201597e6c8f424891a25d01daed3ea3ae5d65deb477fabdfbd75779d34470259b9d19c6a5f39decf6ce395e3edd0696d9ea55c51fadaaebd76a3af1c6f874e6b524bbb4b819b52caa77f03f7e8f89c73ce493ff6f4a89aa136ede89cb3937246c5182395b56ba594527a2da5946e1b1254c61869ddac8a524a6b8c91d6788c2f393b2be5fcea54553a372e0a183060c0cc31130c183060c08099748699632818304761cee0a24ed8b5235b172d99cd365b8ba88848a9e46aca71f2f1a4211670d07f840c38e81fb59a12e03e90dd1054d77943abef9e257b8040ff97f781fe4a5468f2a7993ce6b6afb41114775292060e42791deba35252126773582a57917163ed86317078c891c9e315a6274732b54adc1085c6ebd4c2930d275ca61b54d0a5eaac40083a850d4972e4fa53e74a0d5276e4fa968a5ceb2da2883bbf062436d01ca851134b84bcd06484059329a3291784b880549bd87ccc923282b833487408716768b8e0890f31302e54d9e1b6725c72018a1d2ff7e6b8e4c21535725c9aa184292a318733c69c79811873ea2f7d6e34b640e44972fb093339790f3d8b41396250cc114714b3f944b325f46d8c71c39ecd9ad6b2af8b965c99d0d3f7f1f229a5b321b87e1a36b636b926bb66b24cbe99db3af9b532cbcb5de6b84e06a5d8a8248df745392ad19400000001004315000028100c088402814828cd835db10f14800c7292427c5c369708b324c661144286180288018400038801305354e3007682e79eee7040c7e23542471cab3e8a5010746afc592d0001442be9be613fda755f3bff06fc67ae8bc9ca997de96f1d991bfee11f78851670b5b4b95668efef23aa28d84cff32f9e73389ff847f590a00db04c296af65c491abe3239626006d70d79e1b50b2a8e531e915c542949b08c52a423b61c2fda524c05831051a9755895e1a838004331485d7366eea40ea1053646b76a6b3398ffa7bdf548259fbb75d0a2641fe4b53720ccb00a8e2a12e7265874ac9fe1c9598a0014341e72b10ad74c411e5592742c7d0d6560d6e2bbf532d6e3b93e5cf47dc076b5e091e66f6ebc986754743fd6af4aef6ee3a306529b3e65cb17656e46bdba337a7172f212c7dc14a71782b98036879eeceedf35b87e932858369f19ae72d42f10e70a33e4b73084ebd9d2541774ed8808b5d2434c37bda30b660efdfadf39df20e4b9134759d5195464f7fb9e90642fa50bcfeadd576406b94d4941d98490e3b8a18b89e601e2ed493990b7f6bffedf0b768360bc28de26d84ef4c2c1b9172118272f62bf53f842898cdd30bf1538cacebbc17da9c752b2af19a22e18b48ae093c0f38d82df097090c7ee2c06ebb421126d1c4266c9b584e3c7f902d10fe7e96eaa9665ede7e0556184ef9038e40695d5a9bee647059f5c304ffb41a0a73d6cc0dab4cf8e8360a629cfb0b172ee198e0fd13b5ec739f7986cba0f06980554f3cc2a3e4ce8d29a624ccef6d7e09c0c5ebbbe055339800b6ce564edabd1fe63ccffb6a773d2d6812470681e7aa4a32e34cbc41a0e63582ace32718f8bf1771e47685e7db024b98c5a8beaf54ac4ac370b5782cf42ce8c0c190ae653f34ad15f5188a6168b383498461a09652f82a8a1aa1f530afbd18776ff8850cc83b11315bd5bb196e62e3475875ea6f3047d5822bc946de632dd8cd6fca0e287071e47bd136ad41b10b8496a6ae3876c5d8e381bd6dbb1a94ced56d323cf21353bf045b32e525b0e326964b11344d8aeaf6cd8ef23836171e31b7f7181a9ba0ec6525215513c42d561f3f0827d887c190d0652c7d110d751f2ed6c67f011590d1e39c94531a937ed345eba0b992ce21a48d4ebb9d0de364478d859e0dbda75473f819729f61af4905bd86cabb1f27206f3be97e06d9d1a73187a168b7bd811eadd8953b27b00c5eaee05d885db156a8ef6c4a801525026cbac229c472aef2aaafce5ff7a8e79abd1b6ac827e7e458f481e0b791cdb5c7f5f950f5398db7a4ac5ee6ecd3bf9a2e4992188fc8ba142ef93b5a0a7c7e357dea81219fc92fad06e6605d5d4d80d86ad2b506e218a887b4fa9197525f82253494a9a1008b27403dd97f83a2a960c9c57308bcec5825f0250c6b865ee6cc2648aa84018432a72efcd72da302166301ea4f56e9f2fc80f0006b6507f724242c13f630a8cb1277843665c572e9161bda2a4a65e24c5e3a7ad532b5a171a3e3d87cbe23531d81d99a4173d6b28ff6c42bf6eac3fb72bb9e3f0af4d2a42c1e84a9a0d1d271a7a0a2820c7211ea675bb18b356681e60a28be3fcb0dd198b81c2c7e2e1a9237deb891f2eedf971cade6de3593c824b140b528b206f9efcba4738f2be492128ee5401d147f2401103782899c198323182f9deffd9181ebed7962c5bd5e3f9f34fbf6646fcde6b006d3cb342c8618f122078e02c77d27119ff066b4918c31fd57e2130e7400fee29e9010d144ddb296c9d0665c9e3de67ccd0f513362b26ab5abbdcfc31ce12a2a91e98b3314671fc95f9df63b3690ea1759b18b9beb2b84fac899206d6a80ff66d73863c79ea7f39021fc9c8496fc360d121079a2fedbe07955b2751aa6e1516b55bd982b283d37eb7f959c43c9ce3d7b94f494eec30ab16d60d0efbc2cffa157921afe127cfe10a146fa8484968cfa0eefe665107151aad7b6bff957f9f0ec3779c898698d4fca929b73074ea4faf5c8a6a7171bd3263cf97a169e1908adeac7b3d95cfe1802fa74270a3034694de89423dc548ff858e8f22388b915badc1b04d8457c32b64b9051960a5d4ad684b31c2d8543afa5672e85b633537b399a97485d4468f74985ad28b5b624dbe2c011bc1599cb1b98061bd21eec7b63b66924c3254f187d00232fafeee16f3ca502a79ae6c4fbb6e25592463f7ee7eb145dbaa4d7d32ebe4b4548db2520e3682c79a7ee34470ecbdfb4b6755443935f664bb4907bf10c5275e485cd70559b01953e147c477f91bd24db739898e47a03d6e9afa1cd9355437f3a3d2b083c3a44addb3f8613544a052804c2e75674fdbcf836c4d3755fcedc7f2488e7a9e99fe1cc82de48ad6ac17a0a9a2ad38b03d2c57bceb38484b1678aa278d574415bd3e6d355d12f02dca12677f77775506d0f844e3b3a0f4c3cce3ad081b09c3e394db22955bbe392310cc33bc5e76903c2c46541748969f6655e1986febd04cf474b1ea758dec9030fcecc1dc1a3e4d967545d7a00ef220e1a127b326d585dba2f30da5da00b4181abc7c1e3f67a9a30b085434fcca8d848267ba21a7b1a5b7634663975ce777d0892c1cd96672a6b1a646c7ab01d863c832c9b47fc7478a0b3f07bd39e11d8da08cbb2787c4e2e6f903d2721e5ef59a2811fa7065e19d64e69e1f9a1440147a8ee0650083dc729a4b0d3609e47f7f829fa1a9b59b9b06fb672f996d43780981c3e3e300d247841f76494956d40f9529c791dfac074537bf78efd8e017a8e05b986019ea70b521a24024e68b525b16986d6d2f8379c909608178633e390fea3617618e8ce5b833088c111f6d03156e9f1f4d3059f58598669a8eb0aa278eb07425e9348a17472bbe5c27f5a8051a853dc0ccfd5c3f685f13ccd4c7efd7c0d1bd3f30cfcd2c234fc5f4a29d24b5f0de189f6d67d5a7f0a77c48e1b9ca785d1c02c3ac557cd2538f11ac84f54fdc5c9644c2dd0dcec2dd598292c602d2549c45282c581096f4b4a00d08cdf503b70b33e37b54fbdaf4b987b72da3501da27b5656979f7f0420c11b354d47d34f86cb3aebf5aa992819b0fae6e8298e599d5534b776bb1fb69b56639ddd2f2aefee859ef4c5b631a772e7e416d168dd080816f4fd409a194df7faed7765a51b58218501608f5029f9714501e090a281889343c139186a783736bc48c699aa58307a278acbb86e5b1f66a05c6510922d111a0f480a0693a2251a2d0b98b75edf55113c98962c939d21cd9dd11df61ad460643519705930224aa3114acfee91f2d9232e9c8889f12ac2aee97fe262a7299b7c18236e7650740e0ae8889418646be6239c3650c8de14c6d503763dfffb5a45c0222af22c67151eb9627e2686df42edb06e6ed1ccd30c81ab17f10b428b7dc6eb066b5548744dbc33f10c037b9857b166eee6ed0cd9098c744cbb8398241b38253d37584776b7a5f479db366551e4b586f720b7d00ead598bb921c4548f49d9368273500ad01c914a8456dd005a4346cdb2057ce80cec123fbe5bb3d48520c69b367b8e6d864ab81193fa1555ccc08780686a0370be40cf22acc428360e24f018b180e2a27e9598631272b0bff68a6b02531fb6da3a61530c5aa804575c7573c8709557022f7456c2b33629a26c076c98a98a8452242558c13416ad78b4adb2bd2b972a4d3358abf44f088dbf9111c7ec6fc9212c729bc88767724d99ccae0891bde99eae80c2589ee2b3a033d301d63b22c5e209172ea6b02edfd11af599309227ee974f38d9b77ce70a4bd642ef160ffd76e853d9c1fc7a27858ccacb653af36aa478d9a6f9cbf904d437de6771b70b761da17701c138f5f1a1d2dd0930c9e5c7a4e0356f1bd0e429b2144dcc345511955bb471514771f22a53bb5ca1a178b9229cec2760c5cfe549c60fc54b0ddb8f484553cf035eafe0c508b0837671ee314c11f1dbef267fe402024b97b32b40b954080a3e7323f2eb8e58cb71652bab0c1b246bb912190ee56422e3831b6f3a6698d4051b311192485e565aa53f2eb292848669909823d1852be4142869a19752359346daf96e7e49f85f2e152cadd4259339af1658d6e457bf0fd7cced16c8e686434a2fc5c0f89c62d589da28a96b452660a78d87aa8711faae79d2732592b2bd0b3a560cad54c9a9b086b9046972729f17d53d04f9d32a9fbe5d9d0d908c1782bba71f3f0f9749abda0edb1edce33b191de79aeeeb9ab4f6b7c7dbbf1932d9ccca879c11ede04d96dfcc4994ac73d4d8f5e5701ed1038133feef02f4c01a2c8d3d5b4e767a9b512c33c16dd7dd359f04802fa2e9903f2486ce933a53a9b84348997508e10fa63c50dc57d0accadc6004dd37791cffe308d2ec05ce42c60dc60b4484ece62c7a24c495346cc8ddd71984877f02bf4c338d4ef0a2d4ce2746bfc5a212aea38545c1937008cd03e20b4e81887a20b2d0a6a8a96870bdef54f5e943587d33c9eeca1511962ec300aabdd9167a2c59048797045a4b002a626c624e4da50a2635de6b619b2af32e3e0351635b254d4870607f183290cecd3271a8835433d7d10d129b194928d6a5c06bd2e94e589e4ca8ae13c03d9183a63394e3cb220787b8289aad9c6236d35b496023a27e85ed60a14c75328b3ddb69c7cd0ee4c4def6f1b7289089795a029bafe62f7ce585bd3cd1814cfd090cb0c560f7d370d91184594cd06fbea69afccbf1f1c20c31e15c1783c4b3c144da257695487eb793d0041d88b8f60186bfc9b607f2a2446999673216bd2cc7060ac49b079ca05bbe83f83a41dce6fce9afc7b24af4d55481f59de189fff0535159aad329a44a05626ebdbf1d94d18b2657037dec74412c9c000fa5ade20e3e01f49376b6fda09b8b5de67fdf22bc3e040e1efca4a25ebf80f3d8e03da89ea107709c74a49082e39f7944784c2a29479a83c742be426d4c95779174ed814c5b3a66b151ae1a52ddb3355aa2a22cdbff22ae7695c30090c2ffb9b46e33a0b1bd500d69169831b46cb5b9673d57c01c481fef575d16dd22ff5b558de252620cd732e68421f18fbd2c2e9a3624a981e56fb684f0e296392b0ef94ef77a13cc5b4a2eac92d805d51f3011019024b492496b40ea0a2a8b318473fb9a6221970200b4311c39cdffe6832770f85569c58da0be34673e2388156f074aa42edd75f3e468273306993682db5767d3711a0d14ba75655a4c64b9061bb831b6e5c2d0c58872fdab87baed90ef512c184250ebafeae305c60f020fb802c6a169db66651ab9d677a2c971c9b71531809c1c1d0bb6b59a74c33f30e2b32200b2328513dba98e30a73f4d20c3c18193dc02cb46e52684d3f209ae0d801de4b70167bc98f5ddf0885aa2e28ab142cfbc01c99be142caf3b3bd8e8b5c202df8b1ed4fe24aeaefd6b0420ce74816c33135f48233dc4a011ab8dc4cc13fdf762bbedf24257875e2e2d15818a38cb6617283417a8aa6c6a6c36642298cc7f1a17b65ce4902eb64bf247cf84abe02942ec4cbeed68e0b9cdecb995a32ec72683c4029fe4b2d82e946d458721ffa229c887196ddddcce7e20f42f24fb7f012c40c24526581348d93aa66c09d96d1e908df8643270af9e9fd8fd613e256b8b7ff340eef5bdc6597eeaf034621d3137ce4684aeb817bc76a051dcebf2691a296732082ccb6120336e69948ee703f4c50062ec8392a5adb464c004ec477fb56f457a5ae661068608d04ecbb556b577da687a7e67c73627c4c47aae74210fea689cbca5da2f031b5e06d625c1430ac87df6533504dc9f0c5370b383172d82d93511b9d759c7bf935d5230c213962a52a49bcf748044e59be91433e2ee556ff6685ab8fe3b938be2d57db7285684e1e0eae17fb4a2d6ad272da5b729a7c2517ab1e0f550c977ae955c16cb20bbbbbc5a26a2798f5e302ead4183265370dfbeb229a4ecf2398fcdac89e9634f4c60978681e5712a064bb8e2b07a43ccacf7ee08b4af294d8f986bcb304ff82a3204a0a487b72a8f45bd8aba3f8a2333137420ecc71c2d1692e24dee4c63ffef09b67e1dfbcb222422bebb4e1009cb8e2d1463a353529bcdd97bcebd6da2f11c86089e3f20c4a63341ce245ce4ab3de841b081865ded615e8354b45a77bbd8704905a06d50c1c17bf0bb072fa79fa07617bdb52f5d68ae777e033d8ae8be6829de3a20183ee72485f73b921cd56b5a6a3ba036a1e1c4c89355856c4d4b69133ada1997ee7915b0e6e73677a1b48bbefb015595566054de1ea727e2d6513f74c7d52107fd901691a4019422bf1809938bfcf6ec19ab951431acb030ab3dc52a071498643d027a1d41adfdb31dec49acefd200401d66f30435fd0a757f15e7340f89aeee55f573e065bbffc9b3d275ee4ed7862f610d47edc0997caa88ef533a590fc52f082a472957c27cdc09651811966a5ae676a1250a11f912080ede317449c7c84ddfe6659d5d5933c22814764fce43e42cae02fdf3340f4d0a601843d8cae7219a9acf4314d4a5cb93c2eddba4f9bbc9bbcc7effb373a88f34a5bf444435f11eb76f3934a4f404add9282378e3dc15b06c008f766fed68d1e15bcb27a976bd9fa54ea0201d986bb5317f40c31cade6f4b4c203aa967d2871214ee5765e88c8b4b6401faba2b4b2302c0e529385d90b4430c657b15531b57f4c8e3373b01c225065c016998af985014e5c5e8fe99893b300b96ed219b6b5468e4ef9a1f0b960456e299e138695be55514f1e6ae3bc8ef5f525b9884aed0674da427341e50163e1da6e72a2a2674d8678cd01634473defc80520b38ba14dca438d0617ae9642afba9ad3834305f7fd74cacc9ebafac2f4c74d3bd68ee6e827179f52d9725e6599d2f0d79b5668c53cc76a502e1223c729f20893b2cbc85ed5c02ace565c9c6e2d7161e9c96a6eb1ecdb01c9f549f260cd4884599906444059193ea5b27495be531a64c60a375d1caf782b9c6e87deee7a2be5754434dfe11dd10ad41374608285e23ed834a44e2442f4e804e885b556e7a41a3684600e6bd80bc9a21aba2f51024dd1f6491dde1fa6f198ccd8f5ce8fc56d8af9c6fc798adcb52e96572e90a051e1bf94dd36e4bf40d851920eb87be3ed26ac19d32effd0d51947f1956cbfeb13b0fea0e74630915d1f79bb786363b3637f9f3709f894cc5513391db01cce56e827f34738c26fbb06043b3cfc08152ba04e20bc4bafcb94bcc791e7560f054820f3226c58715957015472b5aeaa6bd0fe0a0be6b328e14e95a1ec28928d1d3dea3d85b07d9f2a685333acfd0f4e4f9800a911d2b83accca03ee80bade8909cafa71bc4a738b05d56839f7681b365070707c19a06900a71851ab10e5454f3ca17c793b41cb38e1a70bd96a2c38d9d84c3172032436bf3e81030d26d35c2b1de54350d7f18f24fc4c70898a8ffebb14d378a256defdfec1fbfba3e5bc54472d344fc1ef7b392fda337fb208aa4acba81da0b9e03f9d71871cc1142e40f09f57a2afe442b077d05dd98921afa5289630a4f699afb81ac776a99dcdbb919728241c8b28701b5eddb2aef8e245b88407bea83b0ea893442c61370021a03e5048ea818f2e90f81ed46c7cd0e25827071b00f4a01223fa40171e1642ac94c184e212486ce299b2988515b187ca3ad1c9f45d85bea3fd4705443952de219720fac7e540a77ca02d466980e21dd140d2927d38979029180f10de1c8fed5d368ccc6f401978475de5e12091c62d0149f64c615150fd58f30407cc2bb3923d8da06da6a8b5f52d1529eb9929b32843ea11c5c8baeec819c8afc5848763657f84f6dfa63fbf050b3fd82485e49c30e29d917c29f5946fff9e6b80897fce88e0688ca7e2b878ca1e44fb4b4905502d0458041ce4cd42f948099266302ece1ed26d686d49881806021ce9e148021c6b21d0293424136d047df2ab35930927f1f41c73f42e9bea61765b54af114dde4b3e26234ebf42bd1108696765729a8927443bb53311537c043102fa466c854a4a4955ae5800c7d479abab134b365e59e9c72e83c8c8ab35a728248464794c4858ad14339ce8d4cc57b142dda3497775dca2c1ba3412840d623bf28f6448b4c2ea5d1f283948cb54924b2d423df8761c4f5782c3b12487582925c3a10153ea7bd91708e9196f57115ee4bb4f19708bd23d391a472b981285e486766209210e2c518ca341884bc22cc84267e004cdfe15cac0d7a1062ced52d1d44e1117ca4230a6fb57bc33300f36e9906b476c724b6c13c72ffaa5528c0b5b45764c747b46715688ca847a7153213de367f2b0c7eba016e299455b69d31e82bade1a677fbc3b702fae29a5689e2c90351cd1ce808b12257a0a81e02d7aa7e65f88953bf44ab5bdb6dff66251830ca3f25bf540dbac8dc7b78cdd7e29378071b040de96448ca954ebfe545842dc40a712887f35eb0cd32fdb6489e6cfe715c0e903e8b212b7ef048abd9d66053fe02d60f5ae16d1233a2cd5519050a92992ce98aefb72c163e35ba664a259f6c17ff66fe19891cfcf0254ce9853a8f6884c068031b553d9eb990ec723dc06ceb9419689a14aef187d74ef71675614fb9d753af8feec9d97c89abab3ef8f450f55e13ac0e480edd2f0fc0e53e256809d011cf6b854a84eed9c432a33f348725593419df15eb381a2e730121a881abf7b29e600d6419a008340565bd7c866e6e10a1ccb6a9049ee9a94d1fa35c5c19720b6e25f54c61821879078a03ceeaedc6362bcd0898557b693f587a70971581fd0518dd6a83d2bf9cf1f05f2b30a5f0ba290f83849587a3b795c2d1e350b25e273b5953d8ae5c8858743b5a09d0a2e9d5f772ec8f1226703dd47ef160622d3fd2b5787f17963393184a243ee6fe0861e8d48cd1f97505d6701512ef41da07bb277bf79bb973027fefc9c8a34ce27aa50a99e207e54bb40970cf63c88c8104068a675d515910d24b777619dac0b09b022b7f8e6caf8ef2c2d7c91f476f89de58c90d4c611143a7f772ca2955eb543ff0d7ef5bec1d40cd2b6d4ef97926ae1b98d709ae9a819389e26445727323fc7664bdb1c8f5bad2ef90f1dc82ce6a4682b7a9effaf169adbcc3db015b357fbfa8f9e773061c9d42eb22cd795192f4da985833de501e775f14cd58af70cd2a2c1e71849602cf265dc8a5c654411f73d1dce6997c1c6a02633edfb26da42c6a7006728ab1068f80141fa8d5f9630084026b2524186b34ccf9e3fea705dde4606a797e1c3435a1fbfe8764e4e5ee211e55cd368926eca0437fe0040fe3bf12861dc21bc736891b23112631099456512cba94706e56f50e175c1153d36ed93c85ce8ba194161efb5f9269bdf86ffa35e626f65655e0e1bbd9becbf1853d6bed5685f3fe1b2a08c3be820f2853b5c9e83c66f28530d135641343e3b06498fde7e68de70837ca49b801d8a91e9c8164e23f964979e99766431b86ab2fb4785dac439876afc34491ae029c7548401ee818d7bdda9e00a795c303b679c9ff49ea7d00f5587c8faa59e6744926d643ad35d84e2f8a67ade9c476dcc8c19d56ad6ed1456ae4f0284815427c49f2277f59fb1faa29c6500f1baeefe9cd0df345e1a66bacd6adfec55cf2a2d2383816b48b6efa53ba673f121e915511ebf3ce246deea71578581a904a5ebe1692a8b71ea8fd9635ac82084625148c9fe6698191dd9556b745f8214b257c41a3962df35058ee57b6dac70ad887e76b6dbb35515cdb62c320d3b8f284cf94ba2e53c8f8a6cb4ce4a49b607125112ae54105d918f8b80670e8ac050a41562c3c73436c8a928bba6694c99dd5d1bad666879203eaadd31cb33292999a40d16d26befc6fdb6bc931622ea8fa0333843a397118a10892309441a83b82f84ae0fca6987d56972dd553229fe2ae1e48a80b6370d030bb131fbdfdc1f63437bca62fd35c4790ed5ddf0f1b3079231a9926c135072c58740cefedf2ad536922e3012d7482fc2ed5ae6a401c11aebcb0dd28a0149095ca1f27a8c13722c782698351ae6f7819686799733555a5b22029891d732a365be636474ae59cd31dad8c2972e42c6ab1a04b0a43a9bdcf1e6f1edc8420f10b7c2b189e148c60f05ca77d8ab184e0ae977fc8ebca2c4ccd8d7d03e8f46a4f7797ade07877c1459732a0898f62f1dc0476fbbe4421c6e7dafd02c2b577a4753979b583072ac9739b79ee952aaa965e31bc34a7ce2441f7605457739c0ecf54e8cb11c9604679b01faa0191869a98bd942d11ab993285655dbe54e2e920ed5038c202d18cb7a9baba3dbe66e2dd025ec5685e2738e3c10001ee0f0f548a71e4b47890280b675a028de6f66a8082cdf4a539cbdcf2959c1a2dc148efd55218fce24d410d401b64e5a43a2bb4bb8876c75828931a1b86da756dc2ecae9c4c4d22396129a76274c92f0df2e88753bef5b4ab8fa9a8ced53e2352c16b9b005ee3b5dc14855520f2f59fe210e0b82351c0517c1d8d16927c681b2c7bd1d42a6962093373ae9294fb7cf176cc3eefca7eb2ada239f4609bbae5bbab837ef2156d40c830203efcd2f0e289aab0a138ff68540dc0712551149b4586f631ba07d6f85004ea84b28c1cda635af7c3b231733798faee680fb909cf1c6f9322da48d17072fe433b64c60b256950312dd51b932087bea40ff0ae20ea468cad25d79fc0ed37b3b9305f7864b111ba58cc4ff7d23fbab72170baa458590fde830231d98caf2be60abacfa9150243bb86c0db1504281c9fb9679f33eb505ed5204a9fb7e5c8b56b3dd3788d328e2a9d15b445f9ff60a133f4c6c319fc1dbf886d6c98a2097041870447cdd7738b7c81424106fa275153a68206ee7f21d92da4153cd83c944f827cb786538db0334224640a096050075a01044200eb135ea712472cf3fbf96a67d9180f6ef247f0f89939e90b159fe1f3786adfdd6aeca0e092c224b8006b17751584ee068b5f5695e2966b684aef5b11aeb8a8fd2044275161210d9acfc8998ee926e7ca16cf38eee05303f39a2bca2f8e081954032bb78bcc3ab956a5b2060648fff8b5177eabbb704f1b5555b5de8b80ab10947cf52c1909c7784b8239e60d25455f35de3fd4ad6f6614d6fad5e596c59cf48c98787491785c7725a7fae719da7e6bcf43499db4b14a3120bb794bd99f31404a139f93b8e9ffe6e401b7e200b3e4c9f6d32310473021aeb814e8916c3ada7a5e82ce39246b052eb9219e1ff4d5a00e37140b96dd9d18fde32874334ae6ce2a22db0e31318acf98f351ab5b0e4637282483576f3906ac7c90a40d2a7fac82d52e208be812eb4e05fbc939496122560a7be667e82763b7d60d6150c7f09e10c14ac9c62cf551c45ce322e62fade950371aef2f37cebcb8e1ff09d302d90e9b85ea974e892d929f383ade43a8d7738129fb5388e388ce8a429783d6602f1c1c6cdb7128cb14afaac30283d87f5745aae4a74e5a72feb93da962033d6f4f49400fbe0ecd5bb40adce3f8fe41abec029d5eedae924d0da2df33912e07e09f40d9f998872bb06deca410f84f025f99f02af712e86d3e5e800f7a80da30889e99d62f5887d0410931c807f70ae12790ff941721df1fc85f92a6917c4653c41dc00c7af993400209ecc4d0e8e3c3d743aa198220e45935903411f05e4a033024f88724ea8178fba0eda71999c2c00f2bf73c888875bf17f96c824604cc1688c602e13361145d9ddf11cd5f1edb9e71f5ee2def31510c1578593b75c86c6585b6ae3f2e89d822507a1f7af736133c8d1ff6c9f89d3a09cd2e1ad8dd53a91b9970430699a8da912a6efc3c19d82fa8091e28d703c37d8d2293a3d6baea2445212e8cb1dde0ca857e13257ea888071729b78a170b6b6a805335edc1fe09946f59fd029ef046003dcdf9b02b2272d82721cbecd40d0a8ac8ae0b4e9f4c71c63076a3faa191aafbf096b33ea760bc74d5d78f0826b7b03657aab5b67d9f2636ccfcfcea5d9fe9b312e155a8d0971a78288f78b6a0bbd1384f40366383733f59657cd3151592a4d7a6132cd704c3f025224170cb3172fd66f49efce417cac2ea4f2882d651d3824f9a0320b493df7b410a38ad2722032a9921d06c655cc0c2b5bc8a6476b27e132c237d22d5880275f6a48444be5584281c0d76afacbd2820a766209cdadbb523838535cc5f7f69be0f34e59ebc9bb6ef9327a24e79b60b0105382b5b7ba673ffe1251c2995cbef1ee3d6efe8251ca5e5deafb2c9df5904a401033dbd0f3fb4d09a24b9d5f28b29ae396b4fd7100b6eb4d50e62d1af29f018930e0f5809082b0abd17f1eb8baaa0211f2bbf6cf1e2a51528b71bcac670d6df28e3618c8419dc63d4d5bda899e4bd4c004f13e7bc6f6b88e287de654a32417a8e273a90c588404653687716d675302d3f58513fb6b293e9a9d0c6c868a99a129e3627bcf25cb531d7a79d5aab4413871c8a9ea543d5bd16dd3b811b6886772a65c3bebc39d4e59378f1d63a2f67d48c6dea1f6cfa455dd8fbc38e939e2406d4e7130095f732b307d98aa190a4a32a92510592198e817211b43bf640b8b795b262a9a6274227d840f7605b33181316faf3b49fab71ea06b846f07f4a95baa2ea6e24a28c514dfa730b88da2c698641005672ee338672213a88f17441710a9858c9c64d6c7755689596291866eaf2d7c09c76433cadc46400fc522429928a004ad3f748042adfd9513c207c0208048295808ce7992216693e00b57b8c4bd24614389fb2c86feeb60dff532bfdedb74da93f268e4dbffbe3c0db41aa8ac39399b7d3b0b60d8879bebff4edf4cbc52e84ff592521a3dfc3b01e98d42e1cb57d1fd6de43e9f77534d6b2922a8ca937a0a6bcfa4c70be0000da13c8dabd6777bcdc073e0e08b95f3a3efec6cef025145dd1fa7493930c8561e121457a653ff46c225f1a56edc767b0e61e236c3529f19beba65e2362ccd2715117aab698829e1af7ca222bc91bc101aa9b0a5012ad6c9d4a35dbb130eeadaab51978c5cd5b04f0a4494fc432b1e485fe3c4b8c0d42060d5018f79b3642e4bb017fa604a00a25016e62f72ad335a8ca08516f516201b7d116571092a6413bfd03e3b1714d83eb6f2aceff06eea44745634c4d44826fbef2f7f372da0ee6bbc34cea1033ff82d7fa2a831f0067ed02f0f1a0d79cb26b4d0521da7259f234b25b8b5532c12659de38f719861703dc9b4cd3083324e0478259e42483a61d6a44e84fc3285bfbeb65c2c8e4960dd0feb02655f7418d81ccc99288abf0486318c8fa04c0d82cdb46adc20600e841e4168baa44f5bdfe615c66395e141f76d45e31599ccd9189afb234564a1a787c5e1395ec8cdf4a3a863cd134f55e49409e6f4446d3c18058fafd1295b2e19d0666b4fa2a7268932d307ef6a9cc86e1ad21da32942b1593c2c3462f9d1ffb36b2d88683ba6d7bc918b34cd5f1d412cddcc2f8228b34e1d96933c6c39bea970472655c53f977348e1412f7d0e124b478cecbd58f4a5063ce2059e9536ea47b0e43172c2a7c76a8e7bfb3d84327cd7ca671c957cb5c8b8d14530791061faa95277e8410eb3bcbc6f38daf0d97399e6467bddaa5c55dbd309a32e6fce3ad2e8940f2360dfc8f77b194d2381e55a9a4823a2ea3238041a4238e8bba966123f548a933c8501b10bc6d8639be1053a756c20e46310cbd5bb056ac50edf1ec389f8ec1c041074590c964a2122ade63a3c7857efae06971a23a26a0b18a4cd9c2e94cb146434a928b73a7aa6f71001ae4f61d0884ab43299117bb1626ba9b503f81a302380eb1c9275de3002749e05f112d29f5d476e25b9f97b905787cb7c70ea14f39909099a739c17f7b532216e5dda5a7156e2d907722b66c54ab23a69e0506039a33a18a3abaf859e19e1609d7b3115a4a4bcb6e690e459150b416a587202d30bb5395677059bfda741626babedf072474110c7b8a843a17a216ac57a9925142b179f89e537d0cd57f3739f9ffd50a6f4c02ac5d8443fddc2aaf53bd9f0fdb018c53db11a97405ea87b44b59c85014fdf0a398caf91c670cdb0805bcdf1e741ec4d36ab77e48531bd6afffbb96e6218f79d358a84e313c7bf4805660c38f76e0aeb106fee5197976f2f9cb0e6dc90e1c35fd09f9c68e5f8e3f45d8115ec6f8fff05f772c8dbb5c0d44f4d90ce03336d579bd68d22101ef72a9805e9c7b152bfaac0ea15c8f3ac21b1420c820d9dd580163fdd743b0ebe9a26bd0d6d2197296225e7b18f3e55d8d26538c5728edc98dd85567797aef9298e00f13c8e9bb80a2d956c944b42de90731553906f8f41be77af8ad36e7cc4a58f165b262e9b30466e1f817175d3a1d9dfc36ff68a0da3121ebb820ef72888c0331d0f06b1326d76979d477ad0438ee97710cc1c86a03a21ec778c4bb7b18fa9e7c854df32ed9658c0734da9507b8e628f4f3aed61101d928b65bdcc84cd9c70ed896190f58bfb1be0d489a4b52dc003987a0b4689642758041032aa394fa7b8e04b3011a01c11d020944b2cdab16776f0de19e3fe91e0df5af3b067f760e97245383f4d217e44a815cac4131dc5fedd83e89302d9d38c2997ed03f868d997f3a0083ba568c8ec8cd91082f34175f74c9c9b37df2627262079eed831048b345613f15c2ba1b20bbe40549874805d1635716205574248f2001195a9bd87dde611de01cccf96932a3f51475930903145ed5a5c481416fce8ae0eeda25e966034254c8624db7a5376772e735476cbb0ae36264e044f4ff53f3870f21a7199cd1764918a0c628b054e915e41fdf34d9aec399197827917b2bba39c0471ee85ad4c56d1aad9f2aabf35eecf0240817f197d0ca5844acee815619c6afc4df5c393e8c306f5f26aad7528f80321577e391950e62d8679be6e43120e186df31a8091719dd077c32d82a2f7a90a2ee14eeacd131aa6dec47637b1ea59f52ec76e63a9cc1200f666325d107dcb41239f72f0ced12982d2b6cea4f16bb6f4fbd6aed01f661c877a80610ee1007f5e1cbc83c9507725a9068bd3f8136bfaef15da0f27966aa17cf9afe610771f678c5f70f79d0bb5bfb4b693b9ffd0928c0297ed92f60f06563a4fe924757622554f32d673493135cf3a9ca668e7ec46e23ab4b01735857d18a6bf06981958d7ce7829fe0c12c34c646732fa1ce96141a65e5b99ec6ac4b8c131eb053b459b91ab9b09cd1a223bd789ae6ed3e1cf17e0b2c76b90d34f1cbcd5a002d8354ef18c01cc9dec8dce67e989119841dc514f427ec2d505453fe1d4a932f46bb1f8e7d9a65cb9fecc307362a5d7eafc3e4605e7b2364673ba95043a78cce173ac38c710b2620e06c5370120c15869299bc88b48eefe98278a83d35c46168fbdea497c34c613b31d4e9cdedd4628c4639bf2526fe1121a1277b03dff90605746b735eaeaef73fe08ef8e7e333bdc8e9c00c245840db48aa3beadf5538b3ae43f098870d05125cea03bd43f6cd4c055eb8547bc74ca32d6378bd0af58a846ac0965870a49fc74a7ca9f4369cfad9c21870220d76c42fd4eab9ac029dd336c0b6afec4f3a48c58551d04c6d15b9bf18fb9c2c2890ada1f046b88fec1391e17c60ff0bb9bedc271d6fac69610f17e8ea37fe74a176c82702f4cbb1c1ed44071421a6e296a1945363ceff1ebdb3943e72452c35ccf7765f378c4103cca698204c23884cb6048f4576c7cfd9de75667441d29740018de41d9e68004915b9a715dcb142480469f44b298bcad5d7f50a110472c98efa412de53ca818e04066d57415b8ca81013cdb59a006c157ea511efbdfcdc58d86cd3b2d4b96b209a53591cc17e3cb00762d5f62255618be056110092945a09310fe890d789b2c106b8b6c8abd6b54066246732f7e5575628795bf7d4e503358f93505bf1c30f136a43740e99322ce49bf9fd6ab4181a0f1fbb2755d8d993d3827107d6d6f8cdfd7691de9d8ee7f96212cc5df2af3bf437a2663719d788c39bb36a1d9a59a7b5d7ed4428581c248863bc71c33f3f8a9064a504f41af47904373c583e04b971b4996907e236289a21265b375a329fd217223815c2182639a4c54c03f038f01f2cf302b8c1df57710c4e41e58a8dbc444ee2cdc05aa4c168ff056099f7d1a9626c762e9992b459eb28c3f7db9ef9d4b63160422801b711f0413e0bb555a08336aaccb2aeedd111bb913ca118319b0061ca2bde5d6bb509adcceeaf11d2ed69fc6874cf7fd4021d8d7c8d7da0c3db868499997379cb22c41b8a7a408e7e5c1c5450835fa9e10d3cfd2fc9740245f260d4a0d2bd85cf0292cc27e7fe4858cddebd82137957308175dc04811a349e7f85f2c1ca58dfb9e04cc843b66042e0b40443f01f505360e79d0c0d0d7493ce4b4e7c2e00192cfd717b0b39e5ac2e940012072d8772106cfa90d9bc180a1c6dbb3ee876a19952000e51dc6450c02caa5ca0a11a12014e4239947749683af4f55352056abb144395d9df4d8bf67d4526925451039bdda0d1c744da5e4575145989108407320efdfe34a1165aa3c4608c0bd1a333bc68ea071363b64f8e228a9734727b43eb87df8410c0c1b05ea3eaddbcd7f53bd179817454c7ad158667143be6f7c025410386475aa646816fe4d30e6510abe49c585a5e9fc61e6262a17ce2b153c192ed05ac637a34db89f52a7180f9e0022be561ff29bd901111b5f22a98fd0ffb698270bdc19718833fa847c615f253be815c2570c5c9f87fb061cc63cc50741a52160eb2f6154dd41a74658a480420a1ddcd214acfa5f54f2dc0f108c4753a11d7a9b8641e7c9fe3744ed3d183a6b888fda6417d1f27c53cac96ec2cbf62c6268b240234e4283f07323b1a7617f726151f2e16c668a78cfc22507b1a164f81e2b0746cdce2d0db3c63f04f82456189b9469d6768dd409c370526c6d3fbcaf1af7d8dc7675b6bd63e05444eea6d5e41628db2035349dc171e3af02be77f81a6822d85c29bd5dea00b6d9e45f2afcd18f0622fd179c0f05209da3435174bb789ccebe4a627f11a95692eda3d858310b7a036d4a0eef435c74a5c9fa344a9cb37983b97343b4d2f50a5a42bb88854055d14828fd99e672694f309aa168d63b7a1e5b8441d5f799ae4fafb4c7945d8cca24d40999fd8981889073c7dc3bbca9b060a0ca2ed5c130920b3b0c03893bb8fbd3b5b9a79d92bd31cff9a8fe53deca91d0f3f5c3f7deb1221d58a894e0ff93eeabe670a146b2f18ac119a02b2c74edce75900eb87b2573e091034eb1c8daf9c7a131de8429320e6d3e9116e789e4a53fc619cea1e670b48305bcfb27d8dc05452e1f851c3978d076bcee70dfb8620318b1fe7c9fe3ac3305d737f7f51a738a500a392e7c8e0f2fd2dd7930e5392daaae1ff131cdc3800f1bbd40978907523751d460f1df51c0e8c8b51d9a0dab61b7f580489eeeac852ff6e8ffc6f468e8f9d780a6a650e9ebc3abe5d797e021a0f7597f2c6346252b7e8861070c1159adf9955993bd1eeb7d0ac155864f4094f9ac658dc85f2f32cd9eea110fb58512ceb393c8ae90aa9e31012d08ece5927312938ad0669c0a1230408bf6bafc395ff6d965c0aa9b0687a66639093cba3c5e8251e5f1fce2502da951447c43d5d1acf9985260f7a092b7a5b3e929375e635bd6a8829a1a1ceb4768a912f6249f6ec062a0ba9c0334b4b0017de97017fd2a7c2de60ae95f3be46460010ee4bce35e1f7ef15fbc0ba6970f8dc202fc1c3937fa6771c8185e65fa062b7e1b7f9a2ba3e7cb829abe5f5c3a527f60fecd62d271dddf1b7ea1c4ff19dc0dce809f26476b9f37b55b8f74012f2352683abb408053415a89e912a48b399f0b7df5a15cfb7436c94ccbe6d7ea3c94e2464e51a7e438a5ddba6f93ad9369884be0034d000a401ecd5b43a68ae644e7761f535b081cc420ec76b50165d94ae85a8e6da6892538117e41ed23cd75272cd98b6ac35925b03a17492c23875231abfc0f16f7b90c3b58f4f92d8b361d31696d704bf459abd1cbbc3aea66baab105f7b49b8bc79e7193aa07e696442f3a327c5d097f0bfb2f6cec225cd137807a8f87cba1b9fedcc816e1a0bdd6e2948f07e2b6fb0b71e3cb8886f37e0bea940119a8208ebb4d06106338d04081291cdd753b1eecdaa2270c16b2093c71d53aeff1494867d0c4bd4606785e24b7ac400301901f4209c54a911466b494b4fb183f347178c0747ff1dc6432d6b1093dbb36e292cae9e35fdae32ca9486c3c0b15441ccc27a90c062c03766fd07d77ae2ba283ea85f829e46c0231099d836da229458d5c700d3aa092d510b2b4ceba1ec11650b985ba1709604ca8804c3d3c18a4811fc433980e7d99df65515c5790f10410b8052080ef208b145ab7ea40214168461ea56d93d45a8426c30cc2699e812ec620d71cddbf31eb3974c35025e7acde5dc0ef5ac054a6e30841c805986cc1a42d1a501c0abb8e6934e1b56a40d70d0499de386a66287de65e84962c86645ecad5379ea2882449035d512649a6f6c88a91085de595f4c3b2ebab803d7323aa00c0a7358a47d83f2bb9094955494fe6853495c4e52133840988ab8a72b948578afcb2b209c126a344d56cfe56b2ae33b5b89f96c7d6aa35b788bd06ef573fb71a06075868e4744af71a4aa0b665a4fe79576219e41f2ddb8c77c498ad2167f11aca8c9376a0a199cffa877ba059bf4f461a1373a93c450293c3300103d08642af2b8c1c1ccfbe3fe4442194786d3ce3ca22015bc59259a5ff83908dcbaf623efd2c0a908191fff58aa355d48b44b1a82dce31b36a3abf6837882daf5047d4f5d546677f894b956242799e3a525b7ec3e825f4e003055567cbcee91b265e040d82581a7c19f7952547b41f157e5752f88bf60c5fe62ba56d0de6f45d130007c4de68ffc66af75ea5e89235a5f4b90a00647e79a3acbc9a0e33691e4cb1f18d0a7810442b49bfba1eb77450bc27fca89d6c3f2e631e3c2d040cca1f5579891fe1752f493555ccfb29e675fb7d5ada7e02c6d026d049a3534b342196b075e135ddc6078dcfdf4422e62400d5830233ab6b24105ab164512913578343620f3713d31a6f014b4850811dbeaf506122feb2041250a77720f52e746a6002ff074c9ee00829ad2ddcfcb8abe4b1d6d9832f9427673e9b8bc63de25ceab83be3aae9778918a1b82d6549683187c900bbe43571c4dc3673c480a3de7c9a8fff20bb320c84f2d20ae2bd98dc9cbd220330e27a78bcb1ba279b35e39ee18806cdfe7d7f6e3af5bb03401362a78d994227fd90ae65a5d63996280d857a8999b02e215da8d623fa12f3444ac98a94831d38b07e90f2cef0ec21ef7edb0e575a855ebb0a5aa777093bcf435601b82bca2b22949166a751e5ff79b046b76d730b000dcc8d75f56e7380e810bee5775d244a05f5b8c9568504f39dedff95b53ce24e68fa1e98af8cb77e5631e6dbff8f3deb62620b04ae1561aec71c8df9ce27bb7b7d64bc0b8de3c2d8525778fcfa4252e51ee6f1f366889365494a0853aac874dcde127c9941911b8606f46a9cd6a85dc027b7bc9cda337d5bfb04fa7bc193d2da402cb1e9c3f3d053b6301360a3806692be13812076fb9bb56f519ce815cca7aad43300992772fbabc34a7c2a30dcb375080de4403dc5a109d0ecc2f8de6f19c8b263398b839708952cd354ce68dcf2c6561110235908d65ef5eb404f77f97fb948b8c82108e41d4337ca53dfbe15f31db3ad487386435507d773e59f90a5e5a1a3651cd45b02773d8f71e4f8064efa3a902e815e1a0fd98446a1491f84d8df6c8e384115fa6d1ffa3265a184d3b98ccb21e885831ecddd4ec90663367c0620ab7810a0dcb19f101baeec58e171e4713603e69ef69c946a041c7cc1ecf088ea2956b55c8a9ff8b619d52cd08da70aed2f47a20fdafcb5d4f8912fdb914b328670ad64da9b0d335190d3399de7d611b9c6256b3bb128914c3ce18b34abefb09db252f2107fcd82efc9bc30190853c512156166a03f52a45922e9892f7c017e58bb3e8a7f1f538840317ab8bd931dd20cf69c64b4ab6af0cc35c56e786ead61cc8ccc8bb3c3c6bca3a0808ac03b8822f4747141704e0a783b94aaf7b16327a9787226d4f90786a832c5f2ef2e6b64111d9015073f4c8d67687a45db95651307ee1df2974ca5ace5481e1f1ea2bd6e4e41cd4036b4097fc8ca3467e030e785833f87654bb53570c28f61d52ec5aa93e37dc9f72ad8a2a30058319f8abeee5846d454267c231c982bd9a760a09dfb7824dd7ffec872384b01efb78653f9d84baa3e492c22a741d1b90fce50e79a877a28b80eb23061ef2c3b623cfcc0cb8a13c819cfe049b0b0d376bd0ddc1b8d2df6f249735a5754b6d16b42607981549d74e0538d751a716192777bd23357bf88fc3141d404bae76ddf7fbea845d6c0ab2472301c1a6d12274f3d662d91f3cb94222f8cc10e161063d204f11cc2152ae5a6116fc294cf47811e202a8296874577f8aa65c7d838c4cd9169052fe26a6382fa9f4ce52e92a659d41b6312bd1b50d2860b1c7dee8375c43ec40900223d9e35bdae127c9b459ed75dbe4f9caba443d2926514b6440a11362a04ee0cf73e407280e6d607f3e5c0646148228296f92815124cfd761bf584c90ee09ba17ae0d0cb94f414a65808a15360559c408fd0cc8bbfce46765eaaed9a4e726de66914211222d901d6fe45ce9b8162f1f60d9a90b31dd0d49972673afb202fed1ef043630776898c49ef67adab577e509a0a1a6f28f7e3d12288332ed022898c6716206176d8c9a61024a9e442adc7adb34ec8046447b1d0af89e0853c9491e871012940af7d30558190e150fba91bafea662a298bc726de678e109046cdf7ca2beaa64534234650af2c3b3f5e39580f8c8288adc95090e0a7bcfb26a7f1d3cc0c815e96e2a1c24bb699ab000e8a08753cbb53d45367116130238a4daea5d766deab0cf1b75376b3e3790f21a524a274bd517334da91689bf73e3cdda52854175b0e0d9058bc99101266105f0a24f29c8ac91420af246a264fb2ba2e0ca20e361414424f9a4529d1b34ddb9ce7af76f6c977df90edf25fe1517815c1e021de8c90025f64a97a0722d9afad4ab8766758d2f4461bfd50c9a91f8ceb27952a466a7f01bf4aebb3ee739ec2fd7e2d0f1eab3336d22b5a8dbdbe802362b14496f6a6c747ac0ae1dd13c1d084eb33d7fc1acfb77623477a5acb3db14f36572abe60141fbd4b56ac608bd45462f44d28fbf432647e2bb105443529eeacc5fec45b665f5009d400c76dd6d24a99a7a4ff2fff533bf9e931085aa92fc5c9ed7875032bb3d523bf8851b154cd57fcedfe464e908c1e984fafeff246af3f8082094a92b8d10302f001af04abaea3892e90d9085a04ce7c686dc64c9bae933ebadf1c556abf84f6d6b9fbeed692fa12c6e906264ffce27a9be730150c76ac24735756313f79fd5693f399bf50c823d5fdd8d7230d389afa31f829183f079f5e68822f1d0e891fc03b0bc384550475718205b5f5b1ca2d4b5c15acb571dd3d99de1e346147958693b1945054ede4800f78c357974c4168ce71a78703d63ec9996fdd4e911cc6cf43a941c14e66f2fbd3c0433497b45546e9e244fe17ba133022791eac05f9ae3d27fbbac14e401ef94321f6e0129fd0b936f4f125978873d5d6931e6fb576a4cba0c7834c7a451d8baaa5eb7149cf7d86c43fd55e3a9d311ea3b297f54193d741dfa7b5d024499735d23e4ed0a810018b7437735935ab0d0162850f01b1be88f6f6124892448377a29ce8e4149cace7186409e9cf99d90090b3d007d3a83ff4b652280772fb9f3f4eb0ac5888c06fe1d7745769d312fdb9ed0186a13b03b13d2e241a1e91ff2371de143e982ca0b4d99b74296e47b9671e3b7d90bf9858be611a5f1d433e0fbb5be5000c03405ca82d8034ad2afe97b6ab6421cb6877e2a8000308f393007a7bf13403087068176e16a16ad61a4b5cd0546a601961a263f922adfda6950131b301632e0ea696c1921c32e654b658285a2c267501907930620641a2a028dac050e0d103627a2a6a154304de401721c3443c231988cecf63b6b853ab5ad4c32b4a1086b4c8b1e013ba52f26c96c8254ac201f85eb73d53a56eda2e4b2caf05ca4c90a9ba417e111b6d17c84082370b7e0a0951594cdc1e211d33c11eefd09653f4028ce32b8697b8837bd56e216e73d71669328718c2499b453ee458745c462c386b8f3f129382e3a4c54217bb2156cdc131286d9b68bcc7af32731a8f03d4bf602a4fbf9e14869f0aac5dbd281de986bcd23c2e00a91599f302ff39f6947aab6a329011f584191a58637c7a44f105d6b39b41947686418dd33a36df60e621c91e2ea9e0558073f7a20385eb359ee016a9c697a17ecb78ca760da0b1330a7de30694c6518311058a8502e3862e507779d14149c4409ae8b10be32d70ba038201102ba80e295da21db101ad32a508796f5e0597a49c03c04f33f9c108268c861275bbb0e12a9d57425832dc42b682d64e3c9af3e157aa4408cc48d4f16a59a7f4860950172077d2b4693275be446499064f113846ef55aa755b06cac23d2179e3a951b528866f2872a4b5b599367e0c9625babf1919b3891836321e74c30a7701b2cc68608ba2ffbd986139883a47e937ab0972719d0813605bde34bd62e2106baafa345c03d6a07b8c8181ec883bdea7d6e5aac78414ae6402e608477a9f3d5d2f190f817d8be1a80f78d2a304e01ec631400b92f577d585967ac41f03511ffc78bb54a33cfc21317011a46c1b076f84cc4f06b42fae1fcfaa409ad5b93e5f6be0f0a60b02ea5024162856e3c263758b91287a95b1ff7d6ef443b6df104560a3fcd454f76fa30a5bbf6aec7afed8950e5e899ceb586b5f7e4f112f5abb49705059d4f2339a709d226c4e8ecf57e300d060b4e753e7571a0a71d7262c974dbd14d16f4995241fa9b9f8abc9305b81022f8747fd0ebfd7d49c6700535909afa36bcdee8cf1f8f5e757f4fe51c4d37b2d23a58abe1027bf70c445d4fe540143f0dac1bdd65477e96679efb045119353e2d8bbb87ebef4ccba05460030dec2f105e4ec8cbdb6237badf6c66c009d4d9c048aad6cf8274b5789c809dc8bf4c5b48141010977d55ed8a5c1c6b1cef254fe8837b1d0617638e48474d70cf38724d6d5e7442e4cb0185415aa02b463002d052bd4ee3f92b7641c1a33e609262611486e3caa3a7671e275e84e803b408c408f922470b1129c58a563941e8d4eb1784a614805c5a56e547b2637062a1cda4e737ccc41f1487874e0309c8c081dabffb52347eef0de26a73abb341f976f82ea82297612051a4f8240150ea5fa0b07c6521572b4cb827e4657c57e9e8e08362e68612514b75efc86b805af9cff34cf78d74f7f808d471506be09d0488297c168917044de93c68c2776e578ca6b1108d79429a8ff8c721a520192bfd560ceca52390b16d06c8b649aca0bd9e9f3cce24d2bf1fc6353aca13f95b1a555740685bf7fd9400615e76b6f64221419a31d5f762466068051630aa8fb144f2f15024c36d239a2efba2522a7d8ab84d563805cb19ddcd91c716b476c0f1538cbd034ad0fa73f29ea898652f712d060cbc2717a50dee8a4f2fbb86a350796e8676ae1da0737a83736090944627c91775baffeeed78a33f8478fa68e3cb496e129e41da07bd6fb2c41f17c7c24f803372c542a0ad7e46a7e0d0c753d95e60e8913ce694113eec95d280ad4b55488db6b71350fc6de4d477aee70885b8a22964602ac0351fd7aaae7c3a0f414239d150aecb50c07754bdb8c7e566470a58f38ae4f6b4eab52ea4ee2b6cdf970e2ee609179338d5ff506d46a52621fd44f5cb1550d507443dd1044e7f22bfade45b97690906d19f6788ce2a4383b64a791dbf395d0b1cf9076b1cda679908ee4a7ddc45a14b725101b386b17e493b0ccfdf647a01f5f115273c2eb9eb9aff8e20c7c2708091262211eddc41434516ff09dbc28c36fc11b19c6e44181070af03b30f8bf4fe41e69b27bc186871d360d27b5775f93b7fe8721b28ac5d814875eade81f8b656c69e00ed7eb1819534d1248ab61d52f84f1e004a72caf5c8df0846beaa4e8e599823d78eb383bdaf47f70ff92ba6b4fe16b352a57b370777ddc87ae43f2b9f7b3a8f5c39a96f3ef7bc82ba51620f89561aeeb936e806e0f3b426a4ef0626813dcc52aaafa76fc47a5c2b943ae8594d04366b1672b3486073d7e298e802078e9464a56fe77548afa6d78f996245e623568888b98e57b1a016f3f15d1cb17a2bef10cc2089fbe5a2203f6c505886104be9b8c6c5e7b3c3b18404d5ee37d254851d495a77ab348f0ff4755e0a38081f1fb738cb5864735903ab0523cfe065236f1e6a206dd86effeb3c58565744e24d26f813aad283c6dca20283303724143ef81dbd25b625c47fb7cb478cbdbf53d6391e4a6d6df4cea26900b91062025a850b70b0feb918ff7d43dcd06e9ac72b0e7bcb43f5db7e8be0200c2df9156ef91f7aae0f97fb8463080cadce9d4507be5cad2ab54adc68bc22e64fb3e3ae2ba58f99e8639fad36371b889e7f899d214da0418dbc3c4470b87552d8508a14b7f7201090f522b13a64b765e2c42ba472b5e0395681c8fa2b272207738c4439377e2832a87bb14b6fbe7d90342e9dc69a3d8051c6fdd602dd5d1f197f862a4023426643e8f0b3361c5ec2fb76cf0e47838fed41ff25114f917fe9d96bcbee1dcb3ec976a9e2e55e8ab01abb7afb39eba50a9506845e5ae168b13b2f55f0d9347482ed87540484d3856f17b81f7bf0f1edbc3eef5b7723b06311d84617dd769000aff6c2305767740a4a44260d4408d5ee0fe6d867ac9080b378cf41c80f1cd3aaf18fe8fcd5b15f203da2df112c103d3c4083f9f184b6ad1f22425b1f188cdccc215f8e0311a8fa202ecef048fa9f97471db630271fa81ced5d8f4788d350c0f1d85832c9e7611a63ba30e31db103e2140cc352ee720e4d6201c01a96173a37e3478a59d6a046d5afa24b3473f368af8bf0dac0ed40cc1f7ce3c1647ae998804bb353ac7f65881feb846f681650c856ae1a2c6cbe71190bbe14c0a948ae24765407b168ed6f25d85c22b7f10051d8aead42d4d915b70599c57662a8d5fba727034a91af6d705d432a5c688a0389ff69164787251c00f9217ef9fa4cf00c2536ceb1c039db86ca2ba39f1b63921b941e1d42c7e98f0e290db381b42d7ada32fb6f4b07127ddcc992e2f178a610d5acc487934e0578d07d1b0a5d9bffb75972851df09b982e8340f18705f0af40143c3db451d0821600952638b05900c965a2ad665938d625123f9ac3673cdedc791d7704c3f318a08aed37e99f7eb27bafc2bc49f93446b28ebf749c27dd644f8fe245a0d21ad06b16b3f185ccabd017d1bfee04c4ca16d92a3c2f8fefe16819161cbdbbbde145c0dfd72491f31d25c6b9fc661a5904589eb84a1c48aff52a360ddb3ce0dcc9cf64740d1ea822a08b2145aae2a0119063906e4ecc3706571d595ebb63ea13034012f21fddadc68769823642b863f9d33bc241523b221ad37dd29893b8c5161422e46ffdbf0e78800eadb9da845c5d5321bf1534213fd2430dee2aaa31910b88427e2c9a42eba7ebc52dab082a09142ae109f9f5bc392a22e4574a880323c0132228988b0dcd98faf8eb8698bb6160aaf3c5322c010bf6e1688bca65d5f791f5236bc930cf7abe3dd00096f3efbcbf8ffab1f34b365ec1dabd2b1f859c7c9f062b49ed5ec2009bf90f50ea4db1f983d5fec538dc358a2ce630a96d0040a8af12bbc73b971fafe33d98a6985f5def9b6c8c9cff80b847f6e144d0ccc5f0073f57bec3432e0bc4d7de3c05290edbdec0777bd31e7a83466405a3dec93b3ca3f9a7ced23c5961574568d370293ffe64c7bf559302ea6bd0fc16c7f59d372fca6ef20e24d26a65efbf96721e4889cb4e610520543158643f43b18598499627fa4acc8632bf9e5317994a99918f8c654d4bec62411b76f68680ade5500215d49acb8331cf63018d51fee0f665d01bc3cec895d05bb6cf8f0603014c2a1eca7afa0a2e282b7fdc63b094f293a1b6ca80026526290d98197b521e2b5175ad6723ec71cece2e6f650dbeac74610154c7c1fce1f0dcc713a6a426afe73692097042f0c1b9b7bc4c4e61bbefe2818a979ceb0404fe60a730e8b8df770815465b5d7ec234ef8aeec66d14ad2f25102170c8efacccff3a93946f7350143368afa0bc65de027db0db117978c073317d4838c9a5b140abfd68d9f1b136937a1edd86604f095f1cb094709e6b6ff66212ff29c0ac106d161bccb4aa66f383263bc66c924793909b3ec7e6fca29f9fcbbb7ebedd1cd0d5102f4146359f1cc362905d0faf32a863bcfc016927c1f6486b31193dd5ca7f3de37561ed4e18f14f39343c148c978b5be431c4349b511fd220e726eee022de4cdddff171d956914f188382e5c83b2317ca21266bc761aae7648b2d7a3243c29d96e3df7bcfcee559dea2f52f31654561fbfccab1390e4c2c6a436a66f9a453f8c2af2e647b577788ee386ae6984d68ebb3227edc559781751ea0320e1626b75aff587289ce04a6a1fe04acd230ac85f9ab58b9994a8732bc22c2e25434e69f88b34f68cd3e09a383c228647930c903f88fa2ca6b8fc7f5ae2cf46b99da9e6efd7c3855406ecd3ab83abdf8edcfda9283ccd95d17b4e500ede81967fcd7798c2dc9759894ed46ae3ac9c1dbf228ad8f15742c2b2efbfdb287e574822c51140eae7983d9958e40ca8f689de5361685c20eff44f0cf0923d8f5b6de6d28c2e0239e15dc55ecd392dc68f1063679df00b8178502d7943780674dcf5dcfcabbcbb2853615c4130b5706aec20b074d2a6058565c0b7a12cd0e6880fcc221f9d6c184ad336ae21d71f187bb0014d600f2f7ae93a764722d60ed8c96e12105a8acc09ca0daa53269ab0da10827c5d8ba322b2943953bad198cbd714bd93c06f0e017104a2c08a56cf5121755040e68aafc11ca5d2e8308d62a4d761ff257a5119a63a485624ca89162a01abf7f0227d8ca07dac6e54fc06b236e672345f07a03828daf27705a77964ba15db181912376b9765ddf9a2a0f62ec03df15083d9931fed94972de4bbaf6ca45018aaeb49502ae6ab41461c6b50e512be7bb36d590068a55045c1753e0c41d92d11e096329a5642b273ea91f7042794928ba2d92398d9365aca43b40c99ce0b2868983fdbb5e3e4091bc516848fb6fa85f6f2700a287d93874069b8600d101529681fa52890e537f331a79ac32b1930a41f18503666875a87be7b3ffb93266f78c182cebde965b2b114b67b21ee8bfdc3486d1cf380d17c52788ddb06dce4c298834dd14a032f791edf2b096f83022fc0d5420b69ebb9d739239f424090556cc8139082419ac90fc030f91dcfef2df8cefae62c01c9631f1a7706681e1139c7d25a2e6541cad2507ceb3c088487e8de6a0d60124f07f32d518c14e9f35c322793b89c74d60b6ac7988061044eff19ab982d0070f5134d2e1d5176be0e189470c26bb94e465eaa37f5564fdd6f2b75fa8449b964adbf95efda31a0786ddbb54e6337fe6a6a0a8cd8b5ad81cdc83b9e42899eda552da5c0fbe43b7bd40430ca4db196904acd59fc9dd6d2d9a1fcd896416c28677ba6b741f49e36cce89abb946c8b658402d3e71673f0deda41bc7fb6b6487bf446e944f04d7cdd1fe35d8c11f1136e2238274e338fdb982477072d596b83f0a4c56bc1a294ab6c403d4e2c93beb83bb2afa51d50f603704486579fca1a56c6823972cf7886c78bd09b99251d1dfe0684bbc1415c309ff09a348ea73477cd24f1fd2a87a78f2cb1003fde4e3b9786600eb4976e066c3f6418e25dc6ee42f9e587de0d233524e872570d07162edfa3770a0049c1c792098b8807e3f23b04569b2e5383648e10fb93b0c8d790e1a0b5bd85a7ac29d15fc5d77ed867f1310cc37fe6e37ca687a518c88dd5535345fb8b4719f20719615a0db182cb74f9576b3b8f1f8a439c04172a293f0c4eb34759cf7cb302e6ad0ad0527e05891b90c3b5122cf06957b37846e12038225f01bf6dfbe94e31b675c36c9b0c65c9db294c0154cad324a36b72413ee68af50c5e8f7076af3628b2230fd72bf44a721bf4cf9cddf65c027d642a18db7dddc0dbf1212ee4327657149c8b0189933b3a83a5da495d9fd6cb0a1c2f4520419ba8a26d79528d715f10335a0d4101d4f6da509a3c2e3cd32c0efef852114644575a7ed150c66813c0b7511e9463182517aa608fbdcab48d152bb9ddcb0494171f5253c86f8ff85cb1c905e4780910708422172cacc0962edd2f9d7b08e56756ef9d0965228d5d7c128c278b456c403c5756467cf3764a5987e0fd0693cf5cc8e75bca9ad130782410cab4d51691bf04f3b4130cb514f4de8b4e1acfb85ef18c3e689b2bbc07cbdd64ccb88fab44ba4cb9d7d7312ae0d4ebf8015fa4f9842c83268f2444bac6cb057717048eda2907d68174555cfc1c5bdd6069ec460da69962490f44e20041f43c23ac04964388e08d1c2db030734c10e6e84b17ad86bda100f678967dc6a9c8523469f1f362c7c1def807f5914d1397b254a21ca9d98dab989fadad6fb853412dfc3f63168e9e253ba61b39b2e3ce0165c5fe2de1730d6028030b144c3b3db810f773ce4f98dcb3ee5084a62ad2d076a12515d790197eee0cb0dadcd55cad4614d7d13468234b78b4d29625faab6768dc806c139011752dd36d096c57a4d9e4086915bb9d019673286ae37b02506283f13f2e272a31dad8dfb9eec4e2b48541ab683441fd5854d498757c5e0b0d2b3e31dd9b58a129671243444a72bb75e92fe7f32779320b042e8e1a908fea768a3c292e09320b415865054d17da8168015f0721de685faae1564ee66900744c59ed23d2a839c6cbf582341f8eb41120661b5363188a5ee9431a8bc29caac697344b6abe260a5d304be621a9a00cf171446d6d1de576bbb97864c7792b05161c7c34f455397eba9c509cac949bf71399bdb9ea97fb38277204bd22964ed90a0c0612060c56f7106af32da9f387ffe107d9d099771e509554c1fde9c36a4b4ecd4358bcebae2e29ed99f953e910b5891b7269cc9067f2c06a842afd18d157f86eac1be24a29c9c436ded017fa41a3a4adf75d5bb1cd61b35b2545070086dfb96b246bee7424b3323f379e3e398a527611ea627fa2423ee559034f58e01c67c1573971e42675fb637bbd0f9490d8d8b0a05275651c73d0f6ef35656b58fcfc8a09ba244e2a820769e1316ef82788093076d1e342e595f2b663217e4d2f3260cc6b1c74d844440bba0e4feb2798c03a0a0d045af4a16f65038739c54ee840df2fb9561d32cc8ff709213191d6631e313b95fff0de876c058e23f9d1eba5ffc141640f445c520680c96e8bf7431062921c5a5eb5f402efa7db7efb7998497e7c0caabbc6bfa51e7311ef277185fec4d8e91e0c8d8438e9c651be58019da1fdcbe97d1a046b9c0114488dd928618f71202672c33234fce51cb15f4a6b2733eedc8590044a72aa83fe8a3f79eb1e1bbbdbeb00bab7b2282e801957a693a4f4f0e5954cf88326ca59fb19c002656c12b5dd22e710cc14e72a947050735a09f168582d782d459c5424944948151263cf65b3ae5271bf377e11f235e82966524b1e9aeed22dc3ae3544ae660aae370792182f07d7767b4cc861193b79adf7c8716ae767b1760f958be5290b6fd1b48b0a12bc79be3a6e2330038bf7268d478f83cfefa3baef16f279a6717e616d586e693846fc49462ee5936632e0aa65b05834ea6fa78e6d4a9384bb905a1fe1b5d4fb6788a109113d9be875cdb7e33350e15d038d44b485c55f637f4cf50b8b6ac9769e400d78ff8f8a3ae6c7eba2a4be0763fc70e6350c6a1a2a64a18fb9c64cdfbd52428255502e0858de1a04ee3297136e9c5e588b50cda1cdac118452315f3282082e86b0c4be17073913718bb8346dd8756a47e59845d9901718d53a7b58ded58f442d2a6f1fb1d35b07fdb0cc2cddc5f0e64eebfa18b0b5e6ce5fe687cf1f030bf7c5146dd74c83b1ab7e104cf47ec0bf01947660ca532a778c02772a1cf4d23827d2b9dd3c79e0b9409d0d91cadfaca5056eca7204ef42ed44eb1b1e9443d81d17aee5f0fcc95723961d6d5f6389e86a1ca0b1ee7a30f463e39954207a5049280d2beffa264e30192325a59caeb9573eae34741cc635bdd2322b11cf113ad00461732dfa3458d5bf81200a66f9f79779c844e20845b8a8b7b67a0e64edafa20858c3567d3fe433a7954287fee03240d983a7cb93b46c5fc80ea253a622866a994c01d4bdfc3e235e551392b064b4a434e40d45950006c38b448ab40ae852f9b52c45604235dec6145f6a66bcd709c71396c903a196258591d6cd9bcb7b7bf70b0240106b47b5949f02490c1450002bbf9e312d0fcda6ce5b27e8a6a82192700054155ccf1a118a0d84c91603ba9075492bc4d380275e43651228582481a1a7ea22c35f20be435a52b664b1bbfaa8bbc86861e077f48c84fc8df7b8eee2f522c5b0e756df61474d3e13a95c6fc96e92aaf5da158307abecace3ca29e5b7066b2db049290491380a641f3bf5a87f12ac448a27990676571ffc4a4d4d1446a7bc8f25f5c5bd609ddd79ac0120dfd0520f4f3382e28dfeab834166f4bb27af544399c117df06450565394917c364a517a7a10c310d18f3bf7ebec3605b704ca42242be2532b00166d6a3534d74dbf16085d493c6852eff9a4b002f6098923ea8707857e1f08087b0e69cab39090569ab59df8e5f1035e4e4d21673831592b446a05eba947988535ba06b3ba45bccd54845d26d36a4a8acf5b6782e12a55d90e55fede0fe5f443b57e811114263c668e91806da972a6f6d3b8e2c66237699a1c5a1ca4396a91b1531d458adee2592247d21fa938709647b1b428d7ec9e783b807ae1f835a8327aefc9f4b359364f9d6fcbcb1c4870c0034c53b7dbd09452e449bd224f1854843f7d54000a7d288613225a6c66381050261fa72a2f9d7912240201ac735ebf77e5210e5befb703ca4a6300d7c0424639ed8d09e06c41ea3a21a87b3950392a2f783faac210726220b492b38f90b45b46e671223379a6e606cbe98bf66488c5223c665151290838b8850524ef971ab8d918c70948a62be09aadea955b105ae642224c6762c520cfc44a86db2908536e7ac4782fd7d2f4c4a151aee54982a1b4485cf6b84f88ccc5ad420dba073aa574da294dcc89232b951f5cbcd89abb9eee2a80c5a3ed2114c21e24537f47c7e52b0555d7db24b300e5acb4375ed269673149d42a5e1e64bd778792ebe96445ed33c946f00b0b1182dfe1aa888605d893c398d48892d0fe6016fa3de9665a7422503d10995676f1b4991112141d832422f23ce245c08198b451c7bf9d64b9989e4b5575dc3f70d5b95746a1b8fb26c7ca9490670908d724c3708996af3b9d664b044f7e4950210a2896d13e54a8c1f7d0e6e72c37b53195b11f30d1a620462c02c65470738455bddff7ffb1cd289338ee9cf3bffd169a7650f9ee481544605c7ce19063a87777f180eb77f908f230738a822bfc675d2a4ec8efe0d24fe7fb14a0ea168af7e41bdc822cd1cb72f73e212f3f3d8cffa62197a2795d2857d0aad8af5771079c68935f2727d1930466652cce0dd947aac90e430b2a3bfcce0326298cd480b9a03f2f721eeb4506f5df67403669ae6c7688576cb9dc4aaa0f7f05a11db6c48af522f74a69b506f740c4ff115f2cea0c5d2a93d8d591175445daab3c24e17e0da5b6dda585683494afb3c7423874a235a89de6ea4dacc0a3c48d6e06d83687faff2fcea016a2822cc25d578c75ac9f9b68ebb531307f8ba97f3645361c921369f25656f9b38e547bae0685105b34d0d0e8cd3879973c2ee6f1d99e63a669534d9fa7baadbc97ff89fa9f161ae23dab1cf8e388d355433c816fd73404dcc6901c10c6cef13b9b5bd7fbd03dfab0c3100e6e3dd88187d78b3922eaa803e0ecbe3e6c374cb85dac51f0233f075337912e82e1f884e4018ae22005352d4d3d159d81bd40a5ae914f07f26926a2af720f373be19c36239f2e9b50cbda9dfc7533208a04eae2cc68431bfa0418a0b976d3a204f71c2820c4ce2db4dfa5f66d2e966114c59d143841bc7e82ce9a2347ba002a6d5777fa5f8588185503bd70362e15a845d103230c240cddcb4d0edada2be960d095aff43f20d68f34271cc69cb4d40260c368066823d03b837e0f44c57a602ca1b70703dfdc05bf56f0ef9acd46bad10b58aaae821f91b114da682e1ad3556f4c28875c2e5a3bee0378c12624825c4cc305d20b162ccf76502e3450747f0795210099606813a90863cea75133814bae7767698a76c016faa3ab21b61c5498633d55466f2d990760c00fe48e7d64417e3a431358598fc88f0b78fa200165b40e5ebd40e35decaee6fc696ba546c929c72813384f43923a4138742a443c24c5dbaaf6184b6badb6dd32450eb05ae99032bc5b1fd2204ee4f1d149f836b084573b97cfbba9bdf45b42f81f25223bd427fa528e3718e6baca056bc083b6f89994c838f910eb9b2ef60e2c3f59f9f05b1c6442df0844cb906aa7aff0291659954c1dd510d9dc99bcb9576e21e297124d771adeab31478adee2e34f27e5352d8a43e8499e2f3b07c51babeb5ae7491b4183a66bd84a1b6b4d124e87456ea612a4da147ad49b5fde21ac34ce49c8ac1e364fccf0bb099a75af914e1f60166008fdef134e3999488461f9bb227825df4ad75ca08ec27ed200cd0419131ba6335bbeb9bd623b4d9ee96dcb4126f427e8a458567b7d36f13487dc140bb2587fca48162adc67cd0769bcc09d309aa6d09b23650adcfe97652e00d1e24f1d8d2105e0523ce3deba68e3eab113c5aa633637cf7b1ee413dc288de57f0588ed27cf8ba0732e5a90bcfef8419f1acf73f6318f7610ab07902dddbd5bf84a4068f5249e6d5f6fb9fce44c661759ea3ccc76c031e814453d05cb71461b84aeb028b6143ea3e0dd4231e614650d452a423b5a601db29685d05370e369f4939aaef07c8c1f73f17a51b5e82296cd0299904a098a7c97025eee55d14b29519e75f12f5dc09f4baf55bb8e58c4e061c80dcee40b8cbdcb662a596e9daea7bb60c8ac2a08053ea37f2584c6a1ef5e2e02133d8abe25848e94e61af5381192c627f54a121934a703ca941684582056b24a07f26597e77e2fbd1946fd6760593e9d316307dd13c1cc5cd5030680fd9fbbe537813459e0f28c39d16d1f823a43ee45b6a9ce15d5c0480fb04a5f9178aeb1adec2563e0008b56d2882464efbdb7945bca94640a5b08c60743081ce4f6734b7e06e248c2862e84f373dbd21591dbec59f971fca3e6421e61422e452bdd18390e23bba217535a0907ee2d6e8112ba4e646253fc3b3ed9a64c791225174c1d9138454e59698ea223ae742e713764a6302ea9b9f1a8874b32b211cb9187e32db9f52475d1e32ff6f1e12e1ab1cb3f1d2c6b05298505a41591c202ca5e7e2133b9118c9175771e7e88a6cb11e7684493021bc62746401af40634583445baccf58f5a6a8818298b28ee91cb754cce90c4cbb821af31847361c368148d5ac8cb183e2c09643e3afed286a28ff69b0d3c1ae25127c05ffb0858edab6133faed63a282cff63dfda33de649d93e123009f2d15e7a524640030e358c407b157c827cb4eff12d763ea48c407b29db47821afa4be0c3dd8ff6d1107dbc411c7f09619deab2b1cdd67991b91c5efbacd142b14bc7a13a2939be3d1c1e7bebf4598eff7bc45f375eba14563e51617fc3a38149f439c206907fe3dba321faf41f21295d59fdfca8e58b928ba568f4c5a42f1e6151f2d45ccd7c03b13457ab29af944fa43c41698d2bbfe5af66e6929116a52ba59371e5473594ba7858572f041bc6a335a6b02c1fc6a75fcaaf76257db61928bffa9939e77cb2f20060836d8761793a9ebb16747c7b355ef4d1e1235e2935afc36379dad778ec53738477a6cc873a2e657b2b106ff968ec816032cf1e83fdcc175aec6bea65bc50478c97144384f1629037642615f6a9172f05ca97f259be7c50e25c2925273f8787c36b216fa1bc76d2445de3f5136fc9674d91bf153971e5ef68b234f453895d20d05f03096e3c0ed1e7c627a58c5db279e5c735983a87bbf27b4a3bd12f0008f5122d574a19a5a419364390cef1252197622e3197984bac8bcc6426a5c8921ca9df94321da386e79814cbe15c5bf7896126a0946294821527d6ba5a514a674b4ab9c8cc94524add23bf5ff756c3a5cce73c654f2ffce60c1bf39f93e38db367bd724e2b95e0eeee320773777777c7648c4ba639991963c6d8c3306c323327ed650c0929e7a44fe56cda22e5e7be45d62cab5ce4dc82512e1bc7338b8f25e900c93927bb2acd2a9d53c75f2f74ab29c0376d01be2264bac7cde71727e63b1a0431df3cbbaa7508114782b5f94a31ba84ad52003fd8d465242cb818c3dacb485850017e81050d70c02209ab821dfac1b7018b28f216635800d104c3304c054b2ea840cb009ec06207af08e78a0757b2ca6abff21855bca06b34acd8c1698d1b97a051458aada2835395266b650bee06537448582cc9ace4dcb0e6aa9e7170552a555293ab4ada82b7204aa56a6eea6d6eea53a92b7eb8a92bb0dcd40d82e801a8e57e0123515f918070516fad407151cf483c705284aa904191aae474485600a1564a6b2e0dc0a5b40a1f5c6a45511534e01e84418333785812f2c1aa38d21281d0c419480c61791c39515153ac649538f2e5eae80834260c1555ee2cc09d54a471670db09ce69c734e71842b6bffc089271ac663871459dcf9727e8d72e7dbd51457eefc0771a494524a1b3421a59472dae008cf0656a42062fe9cd3872f9cd8d003305a70848b31e79c938389020c1c512461f5824d8b5a6b553d11860f9688a2972788d0030a0a96d4134d442726cb830f9d1051504634e1a29c9218628342d4219d407b22c479e1244b41940d0a317aa84318695014e107fa6429b341070c668582a21ac50e3c4c178448a25140c941c2ac86bcc5350a24807061082d5140e1c4851428457185095c2062298a1cb8f0c4c82ba2310304cfb03097ab141145006a14e1c40e4554013a29420758952280e0a40726b4748b992a135dacd0ca8526869e0041145104af6856b1b10d10b12b82cd0013e19db8a2497d31c41bc6a42c66d56312bb20c03e31bfc5206ef99be0faf340c4bf566bc31587ffba212f6d552c0c6dc41bbb1e3f319f51c1b9acdb4b09e2e8a834f6d3b3bfb8b69f2aa5a1bef03b893e33fd98e4d2db3310fcae54e6d3a25beeed1ef81e84f8e27acc47c45b3ee3840d75e8e09d7ea2973e19b1c5dfee1a18c6d3088ecb1db8ae354ad17ee35a6b0ff6b1ead724d8ad0df382284563217e7dea15c9324ae9ccbe30d2c7aa473f529b6ed9e37b5c62536c395060b19f397eb0fcac060cc0a0728512582831f9c497b10138f2ebc962fd5b7d5f911217507ef09dd8b7d773a77f8fdb2db8ee188350843aa5ff832ffdb02f94f383b0aaed60bfb9234e82d54b3df6d9e2a89b882f1a88a3f3d957d4a9e3e637bfe370b4f9126befda59c72cd6e834de19b99b2f1fabe37f968b3407da4d2ccc6524a3265a2db0db6524a3237880646485910e6a58ae09891a24a108260840440d8a3080218bb5d16a52032d60036ab0342f23f5604526c5d32a0c16e2ad9dc9c308e01300b0e38fc9bef10a41ba57b4303100f35e6830e29c80009efbb12b7edff82c9b8bbf79949977ce9106e30bcd205906c18285b1f4910e8e4dc3505046df12843484b0d20eb604218d20323a16383b7078ecc03140eb1aa051a8020b50d244af95ab594dd178de110eb361aad1b204be846c327a1a42b00ca94228c01d19315b380de756ab93d0a3b16d31cae8b1b52933efda36d4dddd1b7377d7399239b20747c75fd8ecee7677f7d8e5deb1bbb7d34c0d5863c0c72efe2ea6408169107b49b1ae07f65e986d15fb9ec6b288bd0cd2458be130c7d2c9132a08bbf87980dc18262d8679956a84cc74b78de3ce89329f64661bba7f5766cccc9699ebe4103ca1583ff5a6645469c1a114aa4255e8052e7e55a494b40dda066dc3c6c7e8d3261b9f37ea853acc1fdfa56b524a29a594d99c2fa59452babb3b7f3dd2203fe52ed863d8d4a2820df2cca47429a5942ea59492c1adde60e3b39452b2942e8fe0a72da69c5272ec32659729bbc8c984c904c90425cc39e53bc628bb4da13ad8f82e6990a997ecc8c86808a329514d4d72367199b2a949ce262e534e2967939499724a2e7236bd787c9fcc2e19e717b99c3c2544e614fb28eb9cdfe3d393b3004e6cbc731ac166e34dfbacca4c6699967dd56483dbf7f4f6d17e9edf13fc8d7a717e766adadcb6d7e6c7e9fde0bb3df5f8c6d82c03468d0d573d9be296ffc74e0c7bbb1f7fe727d303ebcf752bf2965d8fbdf97d27869d9f7db6413965fd2f321fa6d3b25ff96fb3004e3c09bddac70273d3cdb0d9036773c28a0f4337895fcb567e58c18dac0323a594527ea1119c989898ee7e791a2ffcf9617eb5aa55af52a9bed008cecf4f4c4c0ceb5931ac2fe6865dad98c8bc3c8dca0b8de0e0dca059794c66647e62626038bbe2602a0eb7aa41b5adf2d26112192691292dd5b5bf2249e4f5b76ebdf0486b1d0a853a9d78e774ea3adee93a7669cff18ee4b4df78476e9ba6f18ea66519bbb4fad2abecd29ef2cee9b59fbcc33ba9d75ef24ecef61ec63c18df68df9ff23076f59f3cca3c926ffab5774fb24b7be94d76699f3ac9937fca637679cbe7387bfacedf7e117f2939a97a4ec5a99ef30fc9e993d244f5aa6fe6552a99998ff9f92b7fc1fcacdf9e6b2108baf6b9af5e9124f2da47755f68bf7e6ec69389f12c8cb73a72398ee338958ae35e5eec498a8d6deab680edd95b42a53e0eef43c5e3e4ec943f9fb9c8a30c9b7d6cba217d4d03927d614552e443fa49d9a40cbdcff695808a7c2acdaa57de8af960ed7d8006dd47639b5f04491874432925a0529fcab645ee7ab40ffaee7fd2b447c27d32d05cfb1aa7d99e6e6603c8741880dbf27b1c8dc3636e75fbf3553d9fbea755a7af764e11ecb3eeadfdf6c278bbdf5e3e36ddd46f1b6fcdc9ab39e7f9957d65fd4217279f7947fbd3b7abbf507b1b54a47941454d57e39a93af79bd3d12fae10cb79381e6729f7aee1e502f12fa2128a27df745b4efad3f24f44329f39bfc90d0f65cd62bf3fdf621e13e294d645ee6e96f350e78ee7e707c4fcb78d55b13c717840da07a99afab42ca7ccdcfaffeaac121f3f337d5b7b7a341557fdfa00ae6653c1c3532ab97f998d43ccd3391f91baa9f7926aabff1d65f333fbfc6b3dc52fdca5f377ebe8ca7fa1e87f1c2005cd557a47bbea87ff14223ac74431074bbdf842eb32bf585ddd7bf3d5feb6dcfbae1d1784c561f0dda0a8c98811041508183283e3cf3d9adfe0d1e68d8fadb56fd45c3126ea3c947e66f883e43d48749908fcca67dbff4b46f85fafd80faf2bd5b81ded63efec9930dbe62bee3623cebad292718563e8b85af97952ee60019e2cd3ed60af5d23742af0c7eabd2152e98ecfcdeb6ea890436f617951824109b7cba3de6965797df0af5fac73e415d82d82d3ce5d842561ffbfa19e6dc7caed7bbc9427dac3275006d6a6aea72b125d46fc1a873642b5df9d987f5a994a1f7d1be12b4920f957eacf3d15fdb9b9f451d77730ef3fafb01fd45b0fa2d18e9b863a0e2df6c1d4485c7d073e707f57cf71c9fe3f6e750419eece9f69f7430337318743d36ddeed9f568f693b3fcf9b2b080db31b05658c0ed5f0037dd3032bbead1c468cda6c635d87111d6294fb27315e8b8f543a2e3d69f3eec4512996e8d4b1c79e29491a79550ac6ea1fc0ef2e137ec5898efdc39a0629f8fed6bc7c2fc2abd96e26e5e91ecf96a5e91ec63617ddd0b5d855b3f242adc1a65bb3c85a0af0cd87d8a7d2cd82eb6f86c5314b1b4165d6a72f02407368842ce03d2164b785ec7288f36c6529c174497df89cbafbafc85245801d9380496b1ec807451dc391e6ebf6d918b6ddcf95d3ba7b2e06d08ddb0044aee6cbadb77b92f8caf6ddf378c9fbd772c047953d3edf19edee16a1e17a1cfb77a45e8a3629016fb045b3fdbcc96ed2dd333bd6a55c3744cdb4ef54bc746f5a9bba6f9d67a6bae6bd3c63a76bcf1fd95c586a561fec81ff957917f26c67ce10ae60b2dbfea88e872eab35fb862b141842516a13e2e62ed86c74ad1ebc7589c915fc6d58ddc754f0bd51f6859776466e62fbef65d2337333773a41f63a4941e493243e7546c6a571ac4d260fc8c1081e185af71aea051609b99397baf34f8168b62ccb237d2491dbb3b7667f1e5b6fdb66ddb16330f89c77844e784418f02db4410613771fd91ba09de6116e294ed88066583ee99d751fa8829ae431147252d0baef30be79c7372546c3f7fa1ac517af4b420ba31f7eb12b26460e33b958d19bb825d91f259baf7732fb179bb7bccbbbbe3f01a77f71befac777799777787797777777777777777f71fe2eeeeee38eeeed57d453383a326d3b04a3794e54e5d4a05f3728325a3847583663523a324060c18d58b92ee74ea524a2cead4714a68ad7453a26595e6f84e89ccd1a111d939e4155b70f4cc112d34976a15ba3e31724c3774a62e10601fd7c23e397450d9857dcbef3a439d4bdd85bbfb7b8f9618f6ad79365b11b91ec52676e4e3dec2cf7077af2291d8f86347b99b73dd845fb6871bb95c356a3e8c6b5cd6cfcbc894f8f2acfad4c7eae476dc5ba6d6128bbe88568b78426dcfcf21022e53c746452ef126bef64cde8a356b27f1e6f9c75f9e14562391c7cd8845456e9dc8976826262277125b49a9a8b97051f21797c8d35ac49bf85a70616a2791a7978837d1ad75a2d84eb468a9f9c215eb0bbfc64931ed84da3acebea852b3fb81dd1b344966acbea4994fe67333623a1b7c4b1a75094530315b542fee728975a225525cc7c4c4e44e2ceaa4c4a553e294b86c182dd2a2a8480bed732dcec4a5c1a8466f914b6e8cbec68d436057fcb05d0bbba2141cdfd960f943d7d2ccccccfdee9fbb96226c8cfc6125aae9192628fe4a713aa7c38814bbfe1b31c8db3caefcdd3d41b1f4b18fcffda6715bf65aad5ddb3bebd495479388669986f5b66958779fcd8dfbc2eefbe91cbed147c3beb0d2d45b54ca9e1e75d2ba8ab179f577e93289bd4831c62aabd58a777a48b768582b76d9558d0d965ab1974fc32f03649ad6f508b2e21dd495cf383f1f9006654c0f36642c38b458f98eb1a0c4963ddbb24cc5230a214123a5947ed635f6fe713e730dd2efe94a64bdf31174315a44f7a675cbe03124b1ec924f3d1aafa65bf235cfa65bf2376fff56ec929b7b2cff90afd86028aba1c807fdc21a8a2ef5519ffea84f7fe3066b8cb49212b726c1aefab1eafb576badf463cb4ddb5b6bc79ae6f0dad12d6eb5f8c64fa0975ff4f945bf1dddf2c7be70bb61bdf38b4166a928bd1d382028b9e8fdfd2bedea9d8d4de6784dc5309a2465e87d28f6a5d0a04c815d724a4c0576c95700dfc8df648f14748c6cc8615c39a473c2958e01704de45100dfe4e01d156e5060f0a5c32ef9f3637c92d1afaf7d3603a25f310cab7269cae0d421a961c69578d4f9e062d1d6f9d8ae4f28ba3f82f5892311b5eb9e4f1fa134189f28b1db0c341c894e78a76ff7f18412b2dda35efb6c72bc63bbbc46c0adce7e339c86387d7dfab1566befe9749ac15f40521f0ca8cf4883324a2cf758f730af7ad99dbeb3dffd0cfe02bdd57d4d755b87717d7aa95e4e24e097eaebbe1b724e9f0eb77b1450b7bae77ff18274ab63c1ef0a7cd371dc6f282f88f5f8caedfef49da058ec27e8af15b8d53d19b7ebba0f756ef7ec5de7eabea79fd8fef89143eef6e985ffe40569b0fb976e736ee66562663e2b1353ebdfeebbfb5902d3bdeafbf156f7b103d260f72727acfcd87d4c2452fda97b98d3cbab4e1f0bc54259d4dbd3a34ef6843afdca5bdd9f76b0a7eec3d5ed7e86ced1713becbbeed9a6fb8ac4a2d9a726b82d08cb0daa61c615ad8b51b4eb9f7591c84776fd6b17857cd4eb12099273b7813962a3bf69596c162bef64cca33d6fd66b40b7e847af278506290fbb280a7c43a906d84561f016cd00dfd06ae90b7449763d2aa5f4638c315a22fea2f1894486b0f6535f14fa58402fac98b7cf3e2f1fe423559f7ad5c7024ad1c09280ea6154413ed9cbcbfc4b4d7d2f1f7b2b4e919bac1cc795b7e8c378ff42e7d00869907e7b400d6adf4f8354c6041de01d19ec0698c79f3e911778277bfa30748ea66d377adacb08d9909788f00eeae96780794e4f5f039cd33dfd0e700ef7f48b70cef6f441c02f1d6fd19fd1e1ccaefa272ff24dfdce7306eb731e65b0fee66d0cd6d7f1178a932e7df6fada47fbeb117dbff42fdfd0fae9b08bfe098adddc7ba1418abaf523c22e4a9ffd6fb59f7ad587e32dfa2f40f653f56365f5b38f95696fa495b4ac6a35ab0f7a8bfe69079b42e760b9d90734a5c1faf1eb740e4d143af97067add507ea9e7cb0b171b0f10ec7925f5cb71ca65b1e39de9827e31b7faec1d6b2d8adb9ca2ed724d75ff4954817684a833cc5c636dd200873a3f6608b5f37cb7ad8254176a11a1004e3c0cee96f4757ae87777a08107f116100ef58805d3c14e01bf9d2524ecb62b51b72d6f9f00360b1f236734efdf60360b1f5fde7e9bbed39a0d367bb49e9c7a2d91bd9329a51a6239dd3577e922c56de21424e4416fb285bf7eb9efbd67efbee7b0e48fbad3f963b7d23ade44ddb9b8f72ecc43a23421ab1c929de6ae951640fb51091d785c9859c49cb1253176ff563515af2566b51aa4a995151d2512735166ff5917614c588e3a4d745de92d2eb28a827442dd44344714888a94b149ae1486bf196901f18881c252d49e9e9e000e9a95bcc13194e7a9168860501f601bde5ffdef228e4adf68e784b7a44bc253d21de92de4f0d273d203838e9f5e4e0a4a7a383931e8eb72427bdff38e9adbc253d6bc349af7a4b7a2c80959dc14a8f0501f6a9de72d90918f216c8498f05243f18bcd51fe4b371ebb4590103e946302e237df1837cc55c19666e7c18dee98f30ec8a32d4db57cb627d75e58d4fead7803d7d09843dfd3e1616560d45379c6fa495e6d785d2f53fed6081a68438389d1373c4079106fd67f7d3e0ec6910c7877f83cd4bb6f0c6652d872318bff0bbf1f9dbbfb0ef3718afea200aa101668c31c6c8aef81e5bf16f7c8c4a4a428ef4e0064764ecd84c8012853ef56cda61981c815235246717135309619c77c5894f66b0f20810b656cac4c474e4c81115143664a623a4e61df9354b42a6c1e460436682b2bd98c15c8cf47041709d92ee74c56e27948a092818daaa6cb02133f15175e94920423a8bd44b1362528aeb1893224f04d231e945b506962337f222214474705216757a51ca89b261d5ae62d738fdc2f9be756c5ec13d874d32738c07f0c2c2740eb78a1dc6b0c63f295629b4610392152cb0e189248c80c40dabd665a4329eb8a7cb483cc8610d185bd1e83064b208c21658ace08c2cbef0342a30450926306083871900c194c4134af8b0050d2c43284388223ce1c5510f16a5140013765eb69203130428b2f5b2951c90a04866108159c961e86e97ad3461a3d7702d6104932266a0841437306a1fb41449741835a805549a8cb6a8428910d478c2a70a2a866842858c13302142900c94a0820aa32fcc6062061a407409c3084e4c21c4141d7079820344d0c0062e6010c590920fc188043734f1448726286109679cc14df082cb900cb890b16404dfe25a18074c8c8104222ba46c9101ced72c965042b542c4e4486594016385480757bb6c85080b256af31bb513467d74e5092b188a201714c1a8054760b1c610429e250442f0392aa3890a9a60804614a38612436432a4022f24242424b4c589932daf4587036891afc396e82de4d19b9c6c1c5fd873830d13bfc8c3374c126f94427fbb51250ebd0f76e304966f84e996cb1b3e08aff2eb7e649c445edf912de994dd4a3d61e3cf2fda25fcf894131b8db055ece5639827035d210addfeab55e6d56fbb014e56b5c7b4ac22f19034d03863256cf62b599379d4c3784828babbbdddbbbbe79c18f6cec4564694324eb0c619647421c50bc808828c1b968ca0ba8cb434c6cc65a4a5a4251a2c4959ea610c36c640c21867c85c461ae34ad218518cf182315430c6500e4968a265088b09c4c8811855c49881182e10e30731726023e632d20fb460f9c11596062eb8302c38228816fc608805b76b821117264b142c2bc0a2888b824205b7a302e5724610714f3f5c19228b10f7e53252184a9edc4e8d2b29c88282ab9d11c44d8101c44565f1c3f51b5cf1214b0f17ab82e8a68a78b8f40527b8d5881d6e0784934b2f23f960071dae652387db3135b95996a1bb8561828bf10087bbe180c99d575c5992e5869b4971c5862c4aee160329743b175c69cad2c69546b071ab1057d6c8d2846b2f23f5a0c915266459c2dddab8d2258b126e97c695247041421635ee16c6e730c3fa11ae5f4602030c30ae706a051ea51777f2004540480bbe04549f521a238db45aa01f20ef6d9a4cc005e6f1e71d5a7fae1a9c5f6570b0212bfdb4108109580003fcd2a94a3ab5cef97702fdb06b2ae18029ac341f5c71346b28c5408ad534987d2c1ae96fb4522c64d51f33d6844666c4e6a45fa433624f2316e7b4737e2c6c3ef6b1300c9b139bd954025cd5ac583435362be660cc38b2e2332a3a02408d0d8b66b5a259ad6c914dcdaf56384c4c61f31d0489c5528079f855bf21f4931f0e24f586b4101d6cb8ba14c0b1d915c22effd313db92597eac39b1297f4a39a5bf5c213e46619198babbab7588191860977c29dc775ab86f488331604f7f089117302f89bd1660579d31e98b47f128c3c17182e3afa885192bf94f6ad147b153e2508348d90c6c4c3aba72a59d81893c1790e11d0cb08b89020cde0879626bad4cb1c8a4e9c0daa0209ffea98951b3ac9ed0f276340fb0f22bc3aa579dc60acb3ef533d495f5ce2484628c1c86b591235e926e1561977c0ff08d740ebc61977c29db73de06ee68d088c300faeb87d6c73a1fddfd61970c13ab02bf56de927f02efcc977fc32f06230ff6f209b023f2642fbf00bc739379ae1df6d26f1579b0afc53749270800c3b00108615c6a0a51877fe8b44efc8142ff40c17da0905d9f73fa9c523be9d0d9d9c8ee0737d8fdf8f958f7c39b92310c8b18d6da09094a763f5cca1fddfdf0ee47164baf96c56675326d6cc3c1649bc7d91b564d567bad734194514a83505c4249c02ef923881995523fab948619581d1d22f3669d8feee228b294526efab1d7e3587772c262f3d3316fd8d42b6a566b96d55a9bb677cd6ad0715cd771b33d1edbaf6aa66d9f0e8ef6e9e0b827b3a4db9e28875d591b1362dbb8b94d8fe0abc5add9fecdbf524952cfa32e62b14b3e0ddf14619eac12bb5babf5c3191b1c21754bbe94ec352fab300d629c7bf18838c58b4b744b7e0b8cc06a8c825df2e3137ce351a278378c464652fb19fcc57df1894fbe51f7b410e9c355dcd0fa0d1e6558aee2b27bad350bc08d4bd5ca0b53f10bfb6cb8cda673e263fcc2dea625a57c7e9e99e117b317bf5bf2d3b055e9a773429d2b5f2fa49342e7c897cf2e798212df0ba5d58a5d2ef4db2b1f8877fcca1701bf70b8255fca9608e057c8d3b15f401d060dbf70bcc53b4da441f92f6ec97fe1c89ffad4bb55e7006159527ab9e1eaa66eb7425fec5babdd0a7db5f7a858edb3a206811a940f34a48508b04bbe8f1f2a4a1e15cb376a58b20d468679b19734d2ce86108d146157e5f100dfd49ae5f0e82e07a7c1fa59e61969100625360ee1a0842c8f06eb6799bcfd5e03d8557f93c9c1cae01749bdfda83fbd4f57bff690c2699dd6f568b2213788a37b97a74e2bc2afd3179d74ab7efd803882f635e1d6df28277383fd10e7662feeebc7a1531c7a20feb2df0a25843d7ddfea22a95d8f9f25a8afbb38d460fd9313566bc2adfa462c0961939e685eb5ded250d93357351dd8556313bea99cb7e4861208f970acec51570af771675f1c8252638dde12ee71781feea3a269bf753d32da0509ba5aac7555ad91f9b1b28f393ef9e2a2938e43cd796c0486ce89482292be8dfad3671f89bacf501fe8adfaa78cfb2efb581a4bd37ed3b22dd3b2f756cdbefa30b06ecdadb1e885093892b20f549f94b08dc958794cff64171bdb586b51d7b24beee8168f6ea598a7a5e29d137ce686f64acb3b280cfb0dbba134bf08f65549c106a5ddd1a0b49db303a6b31b3b20a306ab538e51c29678c7256c138505ddd3a3b03f7d2c20fb27d59f9e7dec07f954d4a7b0477d2c20d4a73ef5d150c30bea837ca27d98b7dfc37c8ca1de3eca4e89ac18a3576f4d4c27059dce99f1e8d3c6e8a96e276f47b7e6470f64d7041d4ba1c1d9e3adf9123b256193db61d32d8f6fe6a901dd9acf7f9a73887d0cf08e0cf602cce33f5fc810dea13fbb1e18a555767d213abcd3fd7c149887fbf93cac02338073b297101d1b73dee63983d86b1e6510fbccdb18c45e88bf5013fbfeaa576de67c9fdf29609f0ebba6ce9d18b6f2d6c4308c6215a3d869074b3f7c1bfa014d9961a60e8abc314ab13232d94894813b40558a6f60bac6dadbcf2cff7eb4f6406fe1780b356def4aaded1c2d126141bc96659a963d517dd243dc72a795ba67350832ab35cbaa740fc889069f68f5b34dab9fd1da5d295b966173238e1b639aa6a27ca06e7fab2817a7ad88b26939750bbaa7362ccca79efd25e3431f27a394f60edaa53c3ab90da6e63198ba55ced2e7b1e3045a6586629847867a67784786d5b5abae5d8f0dcbbebb8a79dbad35dda230dd52a5f8867efd2cbbe8cbd86035201de407e41dfbf45bcc7302e7dc20e0456774548b3a751c10c60246ad2bede8f73418843a901d0e82dd0ad86b0ff3aa1798afaa52ffb2bd9156da364e92b9f483d0d73c5ee2a688b2aac926d53e97a27dd65e0c49e4bffc9e35bc722fa2b6a8546d58743de910d100000020004315000020100c884302a1503420c8b2de1b14000e7398486654170aa491280762140541c6186000200018628c31c814155501adb64ad121e68267de05dc66414b0192b2c99904d78b62811c63441cefdd086fa45d23c4ea2dfddcce1af0e3e2b9ddea3d2e65bba93f07f1c59389cdc74e88304acf3892d9bd7ed743c5fea13601808dedfdb5ee3a724f371604e9c3c41cdd767795a0debb90827bb90a030e1cc1dfd6227666abe0f2476168b85d92c8105e546b2f625141bc561002aaaf419ad79bce52906ea36db067f465719d7696e225044a49a1944f2cdfe99b65d335ff143e31df13fd157505f6c8d55161dfe7a963941dcf6f1784367056b8ac3af7f5e79d56a67d2f31b99adab1b456bcbb4c903d55af6a1b08d975cc1839f970c4cb19b8540775c70c497c8614df17d3c1c6d92d3c4d6a393e768969844f72dd9378672fe1767d6bacf8ad3187b109d62936792a4714f90f447c46d1e2d714ab200cd582025ecea6c41c44b72991bca4827d5eec13d91c86d14333279be7f2495e5cfe611bd1395a911d89829d4138382b157cd759061644b49a4e62f79a67d563ed009d4439372611ab04b89027da8ae8fc1ff9e26894452a0dbbe52e816fa154a9015b680808e3231f1967445fa0b6cade0e21f5af7a2a63c6f04da34723774ec0661b00eae40fa42b09e00adc0c738033ff5aa9da41b66d1628c3473c368cb861967c284e6ed6536b5c83e56f0afa8ef4f7cddc1a78472bb7cafdc0cd1ea4be39889d426dfec678ad6e36fe4714fb0764e72713109a3682a42799ba8702b186ad25858f05f5a92721cae4265b49c34890713baeea52c19ed0afc09751e5e6ef9a776299d9a453d27c28b6d2355b92920b120a556c08a7573e95b04b50e1768a299818d10d1b0c6c9094a98d6413960a1f7d66434bbaebd38f3365d2a4e280a540453a1f4223920964ead75e64f80f9c31489363b51bec9705cc492215a5821e42ff28aa40794a95ec20868a655ee4de7e1ef6aa196f3308396955d43125fe9c24ee23ccea8dc5fb48a9b02aa67ae73fc284c2609569dd126f259e793a6f130c229054df76fe23a5da284618ad2a2dff2317080f55553d41afaeaa8f31e88530de31d809fa84afaa4060733b7d1bbf0812ed7d9a4f721a0b43615996bf1a0bcc6c2c9be85ea43187100ad1db7a5cd23cf6d3b7237ea15d8920f8b6e0e4e44545daeab9aaa6a6ed7c4376879ae63d2a103dd7c5635ee02e00a1ba53d33c3261721a8cbb66166c7dabed3e7250b2a2a6ef6d24b56610f6ce4092ec34e08ea0665aa101b9c74981c65fd001986baac1f9dbe5571fee8f6c82a53d14e384038a60c7307d62d8b99de4e9fd119b6f92533eb4f10b70844a04b294dccdb7e86271bc4248c5c9bdc46104c2ad0a53bc49089f8ed65274b951adbe23bca97a17d3c55b2a3bfe96cea8ff886e2bdee6f48d59ac02cb337148f8447e94a314117c400081ef43b57446fd8ef046e1073101741cf7fbaa0f1a426cf4d4f6d3ce32478e9123d9a85d65b97488fb2b10ff4fb208463a19fef524dc6d95a7f517e1247a350b3c63ca17cc9225685af1777215bb009538521557088e156155fde15749a2fb1fda51ca913828e380c705dd90b1e1dfc973a3131b1fb72a9273e09dd2385222a2e495d4d3a53572a27eaa1238cd2ff51cac5ffcc2c02dee07d88becb4ad30ba7c4c04939deefa2503d75407a767ec217e38393a0d2ecf49581f5c84d31163c62fd866c581093f60b2fae4815d615ccc74ee1cab7492e25400f5556ac244f267636c9c4c5a21172f42a8d6d8eec256c4133059d5c53e682798c6086212a1c7d55774db521a0de1cbf3f0492386efe7d1829b3be6d50b1989f68af2264c77d78fb6a38d6a9c27006900141c17f7879b60a74e64ee56fdce02cd8d5c25722d2792c9aa1029170c2cc372bced2357f48696905c5b53955c7a659029067ae3531fc7d7743cfc82d23c48c4f99892ea7d184ebd733a70c2ddc33752b2931059f67e41a0075b4a3d17bd2ff0d11279a121c0060dfc30b1a449f612e33d5811f7c63a03f81b633dad03f9c8c43144ba623cf0f60698c9ffc860781e4b6f04f7cdb33ef6831aa06f4f6824798609e339957358a4ed42f6d777928c205fa88959fe9dec7f8532db336203713f4f21d6f6122f9eb016717b46bb9d8860ae03f2d212f52006a300f31944876959f48a5ee16d91baab620d705407c31ceb3a6b42f00c255d2f3e828625d3895b49675f695e8b66fb98b5d05afd4ad7ffb9888231160f42447bf7eff30819e938f6a52fb9c04363bf97f4c5414a13b208bacdc17ead0456093b7fb2369a244f849654e9cfc340c471993d1e3ab3f4915eb311a22d0cece2fa919be8a2597a4427954bb9076a0ae69b0469c6f4ba1c2e318db7fe076d243429592c90a360e2dc889d999d7816b9a63b122e48508aa84dddbc4d8426aeeca2bee81e187d8e2ec0b9b82e9a2c9180968426a6bfdc06cee6d17abac1dde03a9d6af0e0874d72e753e993263b2599500d08d944ab5564051a10a0e536a7a935297c985d2d09317920b5ea574b1c6c8bec7e6d7fdb98a68581de0e38630036c1409bae8df108a9707885b5cf0841d69cd09abf9996b5e475633d494e1796c700dcbd74d64ce9220c66c32b3318a4b1d38094d572a390f65320c24d4888c4645a8f34dc7b6a50fee352779e8d90e9d5cdac20e0515835cb03a819cd61724debd0383ec328abe6512ca6ca1d684b5b019cce4d17ce46e18a5a67051498bf3c42745579427c8cbd19fca8535393bf3c0c30d98f04bb8a1c99dc07da1bd04d135b11285200767ed4373f87768a660c91e51fdb1a3351b43537b613c1fb9897b4daf87bf6fa10f414709dd2eb20176c1b52428f071c987b563edd726f7db9bee413acee6ab92da64de4e204dcc74dee9719701c95c6e4a7dcfd5af771184a209a9e80673226882b136a71e609ded70c7293ad46c8ff9c02da7c12cb3a4bc537060ac28867731a823c30cb62de804a186026e937c80e8d8880ba0be97ba24805564deccf2c3189b4708e543a4c873322aff11800904e9f33992cb4e7d1ab04dd12cd9fdbedcad5d25ba2a1880fd567ea77c9c6fb1f2bd2f8e183f6e3661f61095d5e898811624806b71b7404e5dc74b1721e353576697b85e24374b78019f0682b25c779f32b527ad3ab93c88f129b3e91629438eb288db08a33af8d489679378eec838c52b407733003a8d84b998d7aefb39b1c8ff18a370f083f6387460aa09c7450bc0f9ccffad59784491efb640622727de772c5c53b83bfeee59482dfd0fe0fbd8df278a45fe95bbd3494825c2edcab25571d2ff195b756811c65ebd0ee80dd600de274489d0478a5be74fd39a8710e7f8883209e926300270effe1fec05672780d41612633cb6420debb15c6145af01e1cf8c6086f233dff5925dc97cd2a89d2737e74b0da8c0486db67243089c587de1bee42ec1977d1d457f9b75e6d988f6918108c7903495e191c21938a52ca0c9a9206bc47c4eba798be72f9126bea561470f21dcf76cae091812455de57f9ae30636ed4780e78c80b3a0b51ac20e4ff375b4ccc4461e33a8f9757b5442becc0ae8e6b5b44f0baa99036063b7a01449fc12f37561d1b4abffaf89c7c334fdb47ec4c8583da031303907e0c0ebf2822dd5a76606d278a1290fb30e62c38198f6223336d8d446d4a84f0bbd96ea93fc0d692e291744ef4a5abe72ecf1c701ae35ea15f7ce98282df4617edc6792a00342b698b3cdc68cc68811bb8c9834dbe9e0e80d0cd163845b9deb2f766c63b035027ca22d3f1f1dcfadadb8f41baf53035988f851911e8388cdf2e14ecd1836bc77cb2d42ec19e2fb8b618f8c753a78ba803d726d770eaed0d2abec200ae69c04841c15acf60477b213035f72181ab0df77b1950886d7508753c4fdb715f84de16f81a75e871e4c8eef68aa3afcbca306f854f66fea2058670914c556f22e4a605436e3c7711a6f46d5689f0857025c46f40d7dcb1690d86eb0ed6ef3fbe5e0f2e675455277bfe33b09faea9cdbd144a8ecc79184ae29cf48108699f0b4546079e4ae536a8ba24518ebd7590fff3d5acab0ee3fd99e4785c854bbc5fe7da3f5e51385d2e4cc359dc6c2b5c6007cfbf530e4f6badedda96bac0a8dc5e65acc9060fcd1e884af99d102840b2889fc592780161a9fc48c9ec92d1135bebaeab1e128bb0e2f5a2754031f01f99813b925df2c51916e2e5916f54534ad849b34878346003e9e8ccf0862e789ad4622e0f787d25ddaa0d32b567dccc81cebf28d4d01ceb64e80ff753e06a17c926f695e315c8eeb067b0aac0b1c17e279a274126463c1405028fd83ae65490e83d07acb41b2bba5c77791d0e30cac1fce9593115b6c3ab017f630febcbdeb4ab1c8f6d07a11303b00a2588377ca35d5e3249d05b7df5b3a7f4e9480bca93a37c5f3fedb1c13033cc30977e65451a3fe467460782ea48f33c064d1c205bea5ffa8c8062a29a2e099410c688dfa9a8bc4f5a2351bf3bef231a131067799eb8701bc28dc269b4d1ed39974520347759ec502f5f64da015297d3d44a061e3980b1382529b252f07a8a5250cea15aa665fb39567afdb3d572caf7f4dcaf12c9544ae24cfd6e58c1665ac9e7e1c2ad8d443dbc5bb11c29cccaeee8ac42ead27cad770c705b238b0194f77d1224f4ff98a3f5be76679f43e25fa36fac564ba76f7031e90c2e784569c8108926ff075cb8cf2724ae60015922a80725d5ca5e1643a09baad146efb7067e9775a7280d3018a3669f97a2df154d33d91e2ff7915a4a843e9101efc20aaa1a6aea475f8218eb02e890ad1c1cb35d3128ec83d9fc7bd90fe5a986c6357f2f5c8ca05a42dbfa326ab7abd56140040ee4b61880aeb680b262f26d892d77bb8201cb17fd3ea5f8856001f3fbc730d37871d2ce69bb586c81023668967136e0855989f92d9fe7e00fc4115af2a153ff6fc50dda5ef69cb5ca4449242229cdd65bea42e6b98b1fe19b5fd97e2cca219806b17e256a29dd21abf2c5a85aceca816ff5a0c047b9a61ac37eafb0745fed28bddf11e121364a1cb3bbbc25dbde661380e0e1b560fe8ac69bab1dfe152fd34065008520c9b786783b260a71f5cc0c2e2ea9181258ac2ed1a304f87482e43e6bbe10be1f62f503d9bbd6555b413880ac444e5950c55824043303e24b9a14e88e01f039367aa38829dc22721d41e9087c55132be348e63d79760ed90aea7594db9092374ff8bdffc17dfe3f900f918b50be49a3baeca61c67aa5ee82a44e4a4b03eaa10d417c9352f79377dc556e52fdab60fb7b7f6633243665d9cbc2a5241b08105b2cb54003d221bae9b613dc03494c0766d500442ded0e59de875a6c587ee0a74f2aa900d62133981d7054a017527e1f0f2a06c24b0d09d98d9974d8d5509d26f0d3c5afae09ac6de5252536db18b420ccc31649a76401ba124e338af97d71bed34ac4c443d3a945ce163c4a5626061cdccea9b9bc5257d612abdf0c8eee23157458c013cb859286cad6913651d62ac3d81248287f84b32b7467f315b964d1334658a30c4f14179e5026ec2c30e555529436899953c9042b8a196a30443e8928434c31bb0efa6f29c2f8be7108532c9c2b2b46c512afe309045c5c359a7787ef4fdc5a47e10f4a8b7cb995cef769a4287ea4bcc0cbf885d16451964d9a120287346f660b332662cc7b009228c2e8ea9f60038f4fe8609930924b6b08bd84ec56ef9cfc564d605c0cc00e265e7cfe14cae009cb6834f16d93eccdeacdac6e7badadff84e6c80581f20f8e006e0920d64bed46d7fae47a365d89ad71888580282957c19cc55afc347edefecd2522ea26e9562f84e8a0efec7f898c7f05b82743f8330556be75c0a83a32f0a3606e18b3ff9f21b94ee15ae92f9909564b4a664fa72d8ae413223ee34f5d5b3235e659f265839a27af614ffa38a62d4b7908e526cd4e302122709f68f32f74c44a55ba2c2801b66cb199a2515823dcc7436d4ffd033d5e1fa0cf433b2288df9a147dc9467920a29652fcdb29c7d717dc576943ea90ae9b5a393d6b8586d1fc1477b670ff67fd09b5be4022b7abac859474bd8f8f3d572cabb9051ca547247b43489d339d63655bc6d135e4da61ebabc149f9e78da150e02c0babf5038f0984c13ac07120f20ee09c6ddd03f0793a6e622558c994e7350bb00e8c2b5289e6e87320ffcfb3a3651291984486dca9ec8c2026bfbcb4d17507c28e255828ff01373c36d96c97cedecc0f218558981e52cc73e11745d12c98d7911f1c725cce10339321080c68a01c3e2e169e025ac61e52c0dd4e40ed7c9ebe735ef9c229d8ea7602e75bb6746c2147b735a8f6dab5a5cce634f36a737250853531be9023fd4d6412b2ea58c16d055735928677d97ef181c51d170a405c87bdbd0303e102542a9d9cc2bcf71b7ad1510d99a6e46652c3b8814a911bd16ed4a7d54e68bf20e3139ada9727a4e9a9c38266f73f25e37616b53baa7d3700fa4b8be61852ea87ac2866267e524a5f6ee3bb7850cf10c827bafc0e323f1eb2172333df3fac7db189cf11534610db4d6878f9488975c1f807ca7f89490b55688ee625de50dd8f723baa37d137d2cb7308955aef02a312aab1c241566c843bf93971b4a0c204b0368881ca0f66b5b9315e03b1c21b1b9099cc267dbae4c880810c1b6b327dcf250596c7ee5b245b8f5413cc7ec90a515690fb5ed3d481a4ae6f921227349940c5eab5055d3ee976c2df0f28f139d11f79e009ac4356c279cf2cea91f97cb5259350bf1d01e415490060ea217f56038b5eb9720beac1f0a1580333275cc8321a48f3f56cf51a4cde698c6ee246ea9720e33741ce4896eea7e1064be8e5f1af395463b9f5f6c897e46a50beffc65d9de65f9a2089e92ab7563fe32447a76dfdc327447f73c7768904d29ea15a8fb875b887ea37cd48faedccec84b239330201baba091952963db90c6b647284ff145022c78827f368bcfa805afcbd21dad9bb5038dd18a525d890d66dadc241f6f5f9db575cb72d7aadf9226ab13f21ebb5db2531b4ecd5c5128f533a23b6a0f316bcb43b1c1c9cc7f9942b4ca940591cb9e30593dba7c433808c4f8be55c8ae40d9d65665e5e62aad402a16067347e61199a6ea79cc66469f814d222d5ff2bb7c9b8c57abe74cfc6b28ec2ff16e5f25f651950b8030be98a3471a2526937a7861824678cf2ce12598826f90418662e0bc08f16b98634d494152d84ac034164541dbe4fb9cadbe4fee6b7cc78068379dc47ea9c254c405103b6043ec3fead90926710f3308ff84f1136f67c325046fb54929860fef5f78814810def2b736ecf4905408dfa1edd3b5de549bf3f1a4386ed588914572373e39f97624c928c7d70ce2163b877e832e42e37d95662462f1a151f92456c6b1376575d94a073e27e88926e56164c9e080932201e22870aec4f0c82d17db623ebae21e5737c31a6b9d2e8f7100f88439071749e7fe15ae9019e9ae42a0f1fde6566a86c70c401fa9ff88bc6c56ce0d1291dd59ca6af157694989109ab1135f55a0bf4a48848a84f530fd807566601257b5c69e65a6a604c1629fd592047719a9ad3a62a03329ed2cc44008eded2255f5788fe8b5aaee082198d2b9a1adeabb68c2653b8f97e223ff0504209cfcc68b282f391956f3119447462097f8f0ba3f829baa8a2e753b3998e04b19eb69768d834492eb6ab304eebc55f81fbbcb106dc30f6c73a519118cc5c727402f623799cddace960f82405c571733987fd652151a3e2dc672a6c82c8cf00fb5b90d120ea5bc07bf90052ded24bc664dc2ab48b011b8342029f269b27c25ad618cacd1bedbb6b08d15389380628fcca383855077c9f05240b84a5fe97bb1953970691b0e8d2390119a1fb73ea4e2a7ee2fc69a47de3be80ed10cd7bfdbdb14595a4812c1b73cb5d5a5ba1c22541ff01ddcc21637b4c16039b5ded8fc5898f0fb2a61f8d2f8d4e7997da2c1a87d294411c4841c895063d1b18d2bc9b0dc7622c8eb38e4b6eaf2ef320c2212517cb0355b225730078d29efd51fa19501929e8404d46243906e2e2130820ee00bd1d849608dbca4c3a9e8af6c44e94aa48cf5654545e9ad7dec1694481feb72680fdbdbf95c7b5ada979c17bafb3627669d6b9fd619aabf60454228a10a99049276403b5ef266d8eb8c6d72d4ec508fa46480706267d42db00390a997cb11ce81dbfc0f933c6269fce244e40d07b56c8f0044ec12f8a0b04f841f5bd44e0d78ca9ee0f15fbfe1f46c4afc03960b83c37d2f39cb0d72e32b1f8f4bf484e0860a68f0d8b3c41ddf909ac4d5b3d7c4efc8b43203dcf66091b18d51d5571c1cc96ad2d143b0af68bfab3e5d4ee37684807983a730fc53308f6defe48bb53c323e088b6577647305e24fef966301e90a8069f6baaa0b8f8dfc62ca6e549205fa498f73f5a072a63fb44b9a65c2c9671d4e2449d69e6152e8a55413f93f1d45fbe3807240fa2aeb6f1dd3b012952a8cdea136be7f017723423763dd2e089475f1cc07836e2257cfe8d6d87ecb14bd347803ad37dc04bd4b2373e530869e3987d28e0b90da2b6e8d11e6cd13e2624a0435dc5918eed3963801269036d9865a6fcf642e7879d00c41e3acd8c1eb2aec691f6f09175953d90e4ea56c95e12cf98f2223f98da000b884322cb57388bde3d7d37f2fbdb1546cc2a629a8fb19cba1c6e8096f901986ef2c866c542a7d55a36a6bc989714cebf4e431d9d4e22ff30446d7fbc0309b5031b1c02f9d325d223f547373c4ca349e14e85d4a1b3088d1c495b2f512eb8cd15c2b4ea598736625782d600b2ae7656bd9342e3daa030e11f6b920538960f0433605e6d4c429c58e5b5ed7bfb49d1eeeb626c5adb2a3bd190add64b6f9dc3ae55e2967fb870b36e23b7c15a9ef35868843a7040a0d0fe2c8c274b532400074cd3e7589ca6efe4e1090bb5e41edef21799337a627531afbcdf552abeac42877bbb8dc9d4676f5168d0bfaad782f8cfd708ac2ead7ad138cb686279f1fdf58c2adee4230e4922ff48ab7bc062f5c6918f6a5c6de614613e9845d2f0077fa24f9d1216161a06adcaff4a07ec9fe0bf3a2c5fedf35b591b95d4d828f73c0e7f59cb747b99dd3433e5e7ae32e0ade2052abe4e2f48e1b05c76d2499cfcef01427b00d67698b8c733dc2d75cd9d3409a95111c306b748692c9fc74350d6799be551adaa09f1ad6dcda31f5e460f67e06d768e40982e7c212b64c78ce98542022fd9d591bd1baf2af3a3509b3535fe31ec1534b6aed8d163f98515298ab2701dc47f1f8e09304514bca92271f6bc8602f2344424b6b410bb69a5d25195bb6d069b038e72e7dffe79f1a0291759d5af51869fbba2e0cb6557f1cfae22d5c38aed8f33da45e3d6bcd4fcd23789dd5f9f932c35b64723ef8a8190638c965735fcb400bbad5954a73a8c234c889bb84260ab13d138fc0263bedbbc479fc2d424ead3a735ec5b0801198ddb80f317dfbe84185ef5f797d5d72b4f71128e641cab789ee105cfb0926a4e1a3f9baaf81ef7204ac1ab00b46fbc9842e6bdd997b8a37df849ed4f629028c36dab6c4a0e27780273135f619abf468d8ea3a25814a8018c095d7dfc0a0172efb7c644cbbb14db5f8333d0a7bbd70a52ad448f0384cd77a3f94c31ec258a0ce37115eeaa6b62fed5c8123453809a1c9fc806db38a1541d04aecbd593c6b1e741868764c5a2be5aa9cced303dc9beeb68e7fc96a24806f4d2f280266d6441fc0224b8013194bd13672fc08ace2cb7e9d8980e600b48298cd5a82536396eeb9763cedf26a5ed9196bd43d8256c3b3137ce8115dc16aac3b3da26bc2ab9bda444d3e8dca5723d26fe0cfff259dfce3ed4e52f89d622c00da53bec616d0ebab2a57679a4a8b308dbaa51107220787df9fc594871e687d0bb91b84a09f0f852e130c5298ceeab1d2296b741008acc500d2860ce0915269fd47af8f2426765090f88f0aa002935b708a26a24d69c34cd679875cf46442ae65fb0b6b7e0c85f7784c7bb4f5a60ab94e4a36b8ec67b913e3d663357bc76370accd64011443fa9075a9ca02e057292f0212b3ca46c4623f62b16dae1310cca836227de1f3f0ba40ebb4eb0a4ab6602343222920b151e9c4011810a15a07891df8552bf72e6f46af2dfd45d79c959d1c436dc6b9462fb146636125915027582c380ebf73ff2b8b15c4b21f5b99c20f88ddb81a26f132129d80aa81fc55bf1f29a6f0e4e5c65bf4a1d4a0fa451f7ef43b950a357809a10c1ed1501fb92e447ab44f63d4280ad6a45825d233d36c5c670900d0800ae3e0a84454517d6bc1f0b675e01689ffc156ec75ddfda8eb165d41ec411210803abe492e5762f10b9a44d2105d304dbab22281535e5ff570c6d6c398506803328abbc52fbf5767e510813d60c0bd1d8880f6a88b0fe38c8435d6314374378d2ea937b345e32dec1a0cfb0c64638ff8ec2e832bc99eadfc949ec1a97b43bb51da987e301e73ffda8b2ecfb60ff0470255263069a9afefd7c75e269c8d53f0dd46d6ccbb46069ba65888e6badaac8978a31f6724276962195df087fc6bc8469a4ae1790419e2309b486b830f7fe6c287e366db1c398976a79c60c23b7c94ed66e92f54bb61a1a0ebf6a041d011c6cab0994fd80df84d6118e080f072715ee03402bdc9398f078c494144629728edfbc61e26d6c7beea2568c0fccba7712839197799683e359db3710b91ed5f2cbc9e562fc4e1a2d9bf82e69c065b3b29ac139f03ad191fabdb544755e606c59807b6ce4ad4051decf223d840e4f63b7d0a1a32a79de8f01280c02a9217855d88b7bfdcb0f8416432b3539da890547adf85fc5cd367d9db1189e6c79a1bddb73b701b47c89d971c8749d7ddfc708959b6991af53cf421c9d88a5ff1a8c041cc7e94b926f561a859dd417c8d7ce169ccd495447322793499b97668088d899696344ad964cd94c471f80f97ea5642249afbae784d8003a07ee8f588253271f1eed3bd520722eb4fa2eea55059ea65e34572c60fa52489a4e31c029a0f034a1d449eb87d3284abd77858bf7910ea8d0cc0b7827a976b3908cda0a84d632c7ee4a5397c9856ee019f8f93fc0dbf3f374b2434789796b181d99859d3e78045f0898bbabeac292c9a545a931df70e40d3cc108ae2ea732bde581ec67f91cd860cf94218ed63941b1bbbdc4fd443a5b62dee7ebbf1f00a35d1737488a096ca649d118a1b4d3b9498adf1a3d0a72afaa62821639eb7643eccb5934e8354cde6328608204703abd6c8d5c2d26e460381bfacfdea6ca2abd188b4f1a98a5e8431f228e4e82658cb6f2909c49ae72832e8ebd09c1c2a0a588bf490349614ba270fdb94388ce49c8ccca1e2b500804140f54409267342c105bea3c6c787eead27322e8ca09703b7413cdcf6296ffb438c6ae1a6c4620cefe2dd0b16dd6d017ddce8457134e2f89d58c06608bbe299be9dd91f77c028813b6cd53f6debf885c5d45685a42d035744bf77cb128c4b0fb85749000dd0ca4671b26a9648fd3c8fbfafc1bfab8be9ebaee200227bc4810dd6aacd9fb6609ca331e54b5303b58838f39784477c80e04aeb1a1fd63e7fa6568a434d675854cfc190e922ff5583d0e4cf56d8a50700a5b1f67300b8f8fef2acf72005a950f12153f194cbaaea80d5385e9236b0fc53260aa582e69b4c3f9f5b0e6a47e28e780b556eb6774b1f75697f0c45228a60bd608a3285395b9f5c9770e8a5c11c8afbf79196a854a92a0f3e007ca8bf14964495ec65eebdfe97c592c509f57fab9624a345ee8168e76a430992fc7925a4275aac61493bf12f7ced7cd3a14aa7c8dc29266086ad7aa7ab69713dd9fa418fd0e5a43525fb1f68ee103df4f52a6d29277d51feeeea86fa830366bf0b8c6fa5571d881a7e82d4b7f487a654152f6d6029d504dcd60514232d84fc790a245899364d944207c8cfad8b9481c41508e11432bbb4052abc4912e8c4fa20d487d1964bec0be49224d60508e5afc2ac903e6389431276c6cf4656be7cd5b53049747e5bfa2b47d50cf5b4756c87dc9af30459dab09fa931fc9c6362339ad3c729ae13189ad538c8097f53267fa52eea1cd7e6b8dc4427c36849da699955b4abd18d3b10ec3623922d495487fd38e540871a69719a77935618f66795442194fede38075d3600e6df797f38ff491e753bd31af6c0f3cacea884c0b62d2e308534f9baa53cf4f3e5230a1dc6ab00acf66bdc6a44760ee75fee62a1767184c852534d5f02e11faca1429800d2da226c42b82e5fac89218067bee9365942ca8f9693285aaa98290a7ccd55451b4b16d0fc17a9f6376cacda42282939115732d20dfdb177005c20e7852a4b161d6e606ae2f88288556c41dd19c2656b546a0e1af15f5368f63290e3f7530684c80f0a0d5cca8c20d0c64a6723f8375283355aecd0230444f6f2a3a5b156c0707b2635d948ffe2859410fcb05738007aa0e41cd060ff20c26e70688999e52c7b1dba716ccce36dea3d70b3e32e43a5cf047de3b057cdc1870e24f15294408c659de16cbd937e9fd7e20de08df9f7b9efa7f44dd9472a8b6a1fb9a3ad6e63eb28fa6d7a82af61245a5d9cc21d594eb670bc70a733c7edf70a37de7d861b0943417285ad6b0f7c87899235a892bcf25a37fbc12012fe0d24d2c019271832ab12589d0d0de81914ef9d89d32619862bd7cbc405bd0881e34267976cb18c62d7f6fe6a72609ee8c08d197f801e1b472b1b870ca0515125e4bc0247be43bb959925b41055db1eaa204d6529dcb4368c5d004ccf7a58a350d93a81a91b4f866489865e0e490cef54ffbecafd5e6ed8d3bcacc32a2c7d08c9bc9f98ce0ebc6b93518c87e66046b0290723c5047bc773cd7751259e35ece5c880b04f85d4ce873736e648efe11bc1b823a07a0ff8c6cbf15387b4dfa0fd0cd4568450cf468d17d01dd01b417d705b3ceb5d86f4809e7e944382e532d99288ebe023480bdc17ba8673146075ff3031ec93ee9516c2a5800de32ec7604bd311ff959320b7dd88de83bc20d850d3425eda31286533a02cd628228c8e90348bf749ec40b5d1716c7e6d63e3a0be77621d86bc3b3a3d3ac1620065ef4e25130215a49ea8312c4681a2c548d8d9bd093366d3c923ceb86320b56ef84d29fb1691ea673a311a883e16bab6cbc5d5005e5311fff76d61b68bb4a32bddd3f9fba7c509e04fba8aee29d02ba40ffbd2c4266443877cba9dc18c1a6324baca6a6b54cc41b42d11647d8917a260fdb911d5872dab819f72ae6f3576c00e3169ba0b7a2dd06765bb67df0ada8a1eb412527444d27d3f13f384249ed547b85a70d8e6f00196d3e19b44dce1f5b152463de577952cb1238023a973ea392ed895683a8ff364ca5ac37c06fe436ec91c7e91363dc4b0fa194012ccf166557804f9c12774e1dcb6907d2f262a4b0dbacb21e3d984bb725b3e48298103c97ead4dc958e5925bef578d69df4cc37b97869977947d3f49ba071cacc65159dc11837e50daf12e5969b9a52ea613769a65137ab11bc0d15eccc7d7eb98c71173f5cd548f06eb0e8507ae04d7993b34407d389b0a046f24e192c012306b9ab5b4c9497985185430ba511aada683db869352a37e93948b2a7d75a2bc72588d54f13ec7b886a558258208e4005e7a0317a721a57fd6d2c4ac6bae4f1ecb93fd1dfd72debb8f7da4b986d26aa055d2d9e9a1b15c89c62097166f2cca5b3a133abcdd152d69d1f13ca0b4708c264c5d7a298aa5cce299e281ec9c95755b33a1c3d7a046d78c7eaa14df33458b642a6636cdfc0f925561f68c1cc7e868d2d31b1e5d318e419e28d73ec1a206cd694ce0cd4637956caeb778630bee52691252958def97a88f4c3aad9b29133b3502c73de0622b8cfd9e6539decdb3f356040796bd8c9de8ce0360969877b531636694a48b063b8f350a503e60104c598f2d42d2b6ffefed4f83e4086a7fa7690b095f867784e99130efc98a39f8cd322714603e072f41cc2b49570722375e631a8691cb32fac31c84d7a81b490326246e5f6ee53ff2cd0cc62ccee594191a781e3d5336d7e62414c70fdce8119c04507bc741436c56eed8131be3bf04142815e29f05287bf5d88dd0c1ff041428adf0500f7145225d5811a6a8be261118c32af7549e53f4b10727da65702dc41aef0918cbc8d75e20ce7e46c2fd7e7145e2efba17a3fd5e865964119a2785102c1a4fba30e0cb8ba128ef9c7a3c105fac94e51d1a8c47c90c093a298eec3b4afea3144832ea58b6392476b2121a8ffa50ca8d8bb0670db8b8bf39f59d71c67b6c1908f997201f05d1dd5320ef3fa889c07809a87005eacd497a6beb9e40754d45411cece865cba7ce6cab1d0f5c2bcc6dd14e7cc8d0fbcda8f446893948924e8e4ada01d87f81fe586edeab3fc61c06a3fe889ed179c01d18d5d18d2ca2ebf4de4266f1487235dcbec04c382e67b7b96ef263cbcd0f5b8f5eee165a5e307294f35ca0b6a470ecb238880379efcd3e57479b64b06c7436450b6dd38353709ed7addc9e61dca4a69349350ec90158c7056d52fdcf2165e2cd8ea06c8159dc20fb1aab5358f186f8496864aa2fb7f005b0e68e5ea7d58ad596be96ddb6ffa8d03e968b2c599ff49bff40ffe4a100dab2e0a9af88c8853470c0b0be4eb3e44d03decaf0c2b3e77f3586658099743074546596ddaa0f76fda9c4576f061cfcaba691d20d34551d89838c9f287169bdf7a4bf6bab4d845f295b1759ddf06cb72e0349af25df4e61f83407bf273295f84e712fdcfad67d4700ee6cfba8da7c724e0280c0e8b0bd5e9d94ea5ebe3e17a537ba9c0e50d67bb3fb4e4c16f50ea8b649a343cbe72b77dbd59ec588bf915790250202dd10f3b3f5a50972bfce46145a844fce93e7fc3a39bb8f5f264b404e0ce551ca7db9000ac3d471939e1d78d29affeb6fccac41e45d7d96559b1735cae8cf7c7e32787ac64f1ee0e073c0db24b015ab3b2a040c13fb4192420401a03bd87f85ab8ccbf80c0f825328c1db39c105b8d2c7ddbefa6b69cd34d5e75f828f543c76043dab30ea62387e6e257fb20e6dcc2e0c8590fd3bc6422653a582abae4dd1377c1cd6bf4a2fbf9833b99e91e1780bda61e32a47450ddf17b06d347aff92d1002e27f177b97751520827491b639036dbb483a0260741e109786e48b8c1938126b895de91ee94f073103aac2a3a58a092880cb739c1c63990bbb160442a3ea3c62822c92e1bbcf5ca26b114a958abc8eb6545beb3e93e13811d69f52c6a3098a336a024881eda852369d6f069c73edb6142c63e1d67607007b6d37ba494603064488c2daea01d2b542de8252cc39514caad8a98241538c42d959de569c1d2043992ca71ed59de90b91da4276a68a9517336254b041d202d4f04a74d3667d95d91e101d0cacdd3355fe86abbe8f112a05b31216225b114f63ebc9204d051d2d54657c80e661124a008d546542d2876804db8da86114099b19ad230811972a196bbc76e1bff4075832ac084ce91367c1114663bdd207c10dcd7173d7a546cb41df09517639272d6252f3816b5df0fca75b5c4f20c91f11d27b70b9d6685b97b46dea073b67f373cef11aee84a07dfcfa75c162efce3b33b576f50e490717440fc336493572651ed9e11b947e382ba64f94f246d31b51f82b02feaa8bc90c19b6e19edf9263c972dca1a4cce2958cc9eb47ac4e5b1d3955b8509952b50c7206e1c58b711a3b1b681f110d3e6d5afe66c8b57ec6d4bdb581cb1e2d6a07081b6d004bc7562e5ae4ebd8b034407c6818a6f6dccf49d99c77e7b2e19908c76bcf3ec12b3376af1385165842115ca7d4162644fc0db3354e80124b5c291206763fa8c50a3a19a0ff051e0d46afdc5e8ce608ab25032d760a1582320769b439a3f958fa294c79177a4f57c85992e6f3436e23cb9017e935732528fa7661829afa83372d51a7c63e1e946cf4c9e62260743436ea102941ae82cba04a9ea739b550998cc385506db268a9455c911e0a1099f755b167af95ca0b468a8913e7f6bd90809aa429c7d68c7104577883f1c22743ef09ec7395f5b533a8095be91b7c9ab6884769131081dfbf48ef8bbc4076e824f3ec51b460b1911a8cf3eb1dbf14b696738203d5ce2bba17f45fe1b4f14d02061486500a292c46becc7a688168df040c9ab1ee8fc6d4030c3e6f06e851cc54c881c14a82fea782b1315b22c7e3f0a1da2e5db0942dd642a7c7c9940b4f47485651d9a6fbc6cb86ed4f5f1d8d99ff922828c2ea50270ee3ea4c864cecdda00a894bdebdcce2c3901ed0dc601830aa276ea90198204146accfa749a74ac40d5b82a7b648d8c36d9abfa31146cdb284a60288bfcaababadf938f67b1bb223a1bfa81f0fbcbebd24daf4ba41751fdb6e4265c5a50b07ce69c4f2f3d96c35863d4445e188acf83e5cf76bc841596f86ae16f47e8f8cb1f57579c38b976e7a7386e8e6850cf778585e553a3945e61e54050923ad7eea7639ef52f26ce0d6766887c1f62202a1b850ca3c3b44a77cb04563b30ba57dbaf2e29ff450ebf5d60f83379c5af0e7e4ac01de828db26c4c2f5c11d7591706c756f2b6d1098b852de236e555494090d706fc11a3f4f9a2d115702c72bf211b3cbd8f052044e28f4f2f71c27711916715ad96cf035d1ed588efd2d17b20b02ced01a87272c05cfc99b9fdae190b3b92357cd5e4051d5b2bec459428e4cb0ede41e848a0a31aa809208bb531e032aa797e4824596da07f99972ff6d6c1b72c911655b01530221bb10c2b953e7a1c9bc808e751fafb34db23cb349ca12bb9f2833ab1ab5b1a51c2da99cf600917e6264060e10d2db35099904f932622ed48360ac334c7788c3528e668b152e9262d802cacf413df119443727ec3effea4468662fa6c6994d02159159f0220b73496906732ec3c4ca4c9bac873dc90c479ace8f52b71ccb7e549494666658251ccf8556c7adfcfdb9655ee704514a262c1076cd70929dce25c836573b069cc26986c3c855824339d761e4357d482f5640c956a733fe214b6c0357bc247fd8e9246eb9a256a20d5a10bf7b0deab4b241a92618c793f688a1f36b0c2160ea2b2d41f66678881af4dd91058ef52f662ad0a49d75da4073814c7c601c230ea59d524fb8f911e0a6546af7d6c7288c3da58aeac4e1abfb894811e212a2f9f541864d249c4332429e0c0667e463279474f277789105b5ba03273f0f319c7185205b18b4f073144a1ed081c9162ef18d71c652f74befe7313d130941952cf4312338f095163075c91785af6c8229f2c609c6909e6bbf117892f9794b67514f2c8254fdfa5786d5bf042b9922ce2ede45dfb6bcc6e440e2aeed12788c349eaadbd22cefc184c663b1b99ede3681cc52ae0d81cb51eaa92636f966ccca8c7177fb0a21faf331ec03e29eb4c3edcdd5bc2e7db0f29f2972668872cddeb0ddc7983c7f851cb6636bc52acf62d283689e1e66284e079ee6d3604f18f8125ff92b0dad007677a43ae102dc6c21b4cc31599e26d03c5b9ca1f1596a631cc2d92c13d014259da4ad2e027bdd2cf25b72dd0dab9e41995cef1085c2e8e1846f3154a4943ce33f92ba6d1a07ce238606c1c4d415fa78a046d7e0df504df6fd099d112f6c0c1f19b231d8c628f450668f1e31a7f2c61646b6c63c3fdc39cd49cd21853a22d40c66a6e5378e82de2ab0b477d1bf8d50f0081e4bf415caf82e04b895aa342b9e4c0cdec3ebefca5da545faa162628888333b7e32c0bdde0c1343f62ec2f9a2fc23a456eea48de8cb3a9a2a4085821f2c7f749c27d2144afc426878d64829245fc75edaefaa2dd0ffb94809272fcb776b2568c433069df6a5c64d440f06516539e2630cd50282cfbd9151695da13950349541d22b29fbf936778ca390a27727165319701ea0b8b8418f0b4184b4725cd3eedafeaea12984cca61a44b77dde4195dfc8a2b3a9ab1133bc251204e8e5a24da39f82f2c64ec3ba41a7e5ec7bf828440be64073bfd17448438419f0b6399282f2a2d4f335f9ed7d9f748b379c2faf344abcbd42e3a08c648a4205fdb037ea9dc48708675685c539e9c2b48b9dbd38ddb1d9033fc41311c35b9ade22a86dfb93415cada5646b6c67c3aa017ab5942c744be4a33edc089d7bc163c224b0452f3b7dd495a10eb1d480b7428d6dbdca88a504d368f6125ac15350d6440b60f3a0a10450858ca80f93b44da4c27a10973cd323ef86199932585250a6a3e3ab408c035814190e76cf93da062b5f087c8bfc22fb91edddf66ead5450e2ef9130068d78f485c86be9802553e8e34a70ad2545eca03885633881b85507c65bca2ab747b2992bd03624b6a5933bde7fab0482b16282171c76f6fd013b2c3daa3e7d5174bf8726d2c3f402cae5f240f5be729d8b024a95fb49ae6245f6f02dd49fa511b5de45ea6b4f0d8ff5d402193912b3f96999b4a7fcbed572147e0b02f1d3a78f1cfdd6300f93b9c4b18a64efc1b649cdc0cf873692ab249306c87e27d39c136c828b94163fbed501f392989ddd99c817503616ba9c453b3b8e4326516407572dece4e4c04dbcfe9bd76face522671f1318415ad5cd38fc7c1b1972199ab7e90fdd6bab8d63d3613af408f6acc76b054415c06050726e684ada91064409aa081d145761ec27d891df81e195b0e08e8640b68e126acc23247508b79e7e9cadc730a3f451abd483f01cb6e938758216c0f6b1d6e7b67d8a99acd8c1ef1dab92d2d14c977ecec03b872a74f7632a5e1e318749d923b9f8ddf0c0ecee5b9f0b1774b7b81e91b5fb1d59fcc13c0f16993cdb78a2457e657edd9541476670d447538be79fefe945f0fedfaf24b79b030ebb1a16536bd66b87b23a3f4d763b8291db1cdbe4ba366ccaeeb324d91b78a2f533bed512a63ce35b5b9320b643214a6f2c69c45535c7fd1a3bd0b3495a59e1ae8b2f85bf3a39f3efac8e3503fe01ace8c5fd565ff5cf207620c2a1899148d9ed0816bcdbb2ab8574fd54c84d97cd4442c0ee14e3dffa83e65df4b17607ef01dddcbcac52c88363913dcc2efa57b03a6637ec44a8c1e252214e728d915c0a7184b632a3e4f1a92b520c34488a45b57a27c2e98c991743e0fd8f916ca874364abaee5744c61f4024966ccc69482af7d817c4cdd00369285a7debf869fe646fd0903753b1440995a3bab952f91393f1401d6392fc643e213146ba6cc79940cdbdb35310d4d85382a2c1205e528bb24263e850170540fc1d071c4223b441f1eb8d783220681329d1c25b35480311bfad007d8e9b85425956c67b19e2bb4e62b0f6ec495595b37a96aa053d0b7dc54a2ae2223e1227e8fc3a16229e4f9a904103e2376898c56a6f7a032fb17cce48c298faaf103b433e7edb7f4222a671a47800d25d0fe2f39f7db4aa0119b7166a9cbcf1abe35869c52f801b803a759266018ae3c349ca05756310a64203f48905146a81f8a3d9cd0091a8fa7cf378525e350aef1ee3876289b166c10187b9126d8af1ce95b482fc95d47b29b11bf70efaebc56ae3378d2f9b3160907c76f80ed08d5ae32628efbe6f216cab582a0f693e8bbed4236c06aea5d886c3d4f7195033546dfc22d731aa95b038fdcedc79f827b4567e0de2d7f86c79e4fd0d491165bef6b031f83e2078847b52d21fa6fa6975f37cd0e50f3e25e893f704b6f06cba4e4846580f8e70590cc30660c596bd291935361fa23f00803277514e5f585709a71b88be0d5a2b051cc41a5135402416e307d5081959e85af76050b453227611f6d9ddd028dad8805a3c286405eb92f010a8654a7c03183c1bee9173a43bafc2b0cd34f7018360fbec1d0bd46f215fff365159de3047f461830b66b6527eea31baa317a4b27b24ab6013d434467cef156bd3416aea227b5386c11a18768f51f45ef9fb511cfb92dc127a24336c6045d3788951c6fb2c2ea14a73206b7c69d03a2991f563a9eec1fae7d42f793b61295862a7028bafee1b9d5546ff60d8350e56ba071b7bec964b30f4e0008ec1849bd088e1cb28b17366a110a6b39796408140386ffb8d4603830dd32cb4117f70da94ddce89ff8cc0fe4ae0b3355fb90b1c620fa6d85c3b8416e8cad051825ba064cf27979bed061b0132ada91b9f19259f83e5f419918b2f05695e690b64343c382988ebc69bffae31fa57d1b713111465030aacea73174d4f0873094cbc96817ef66cd4eb81c1eae442ebe8792b388a68062c039d16071cf244c4f191a07aeb5a30019c2c8d6d40facb5538438d0c749e5dbfe78487138767b40b47f499790075b8a5dff57c70bd67f03dc5f73a18871de36aecfd292bcb0a89b6c0e33ddbe35e6a541904c0b8eea67145f9cdb4fa0a79d7a0ce50d812bf579259679360cff1398fce1dc06c4599a00332959a472a319a46141cd07805c010c58555e054c56ea14b6087e11af74c0f6b99c82e26cf88199b95e03e0cfb2cbb193dd27233fff25e5bbfe64f9863c1118beb13239fdbe3500f77e4e02606e9c7d3191b6cfef270462df39dedf9430cd093d0f85ed3d0f22b457186870c036cdf239b5d177d05d79dd4a761af2ea46b3a50409e56da306422f4b0162347a7e79e9468c192c3ef773fe6412629dd9b6b0ebb48335deeaccf31a17bbc45df14f123bbb6deb3dbf854a3fb0037f6c88f7c3482bf8b4da1b802ff1b8322f64cf455f2d0b10f9ed120f1c93dac20d0838de107eb9bd1318a61f2dfd8936104efbac5f6ffb673562329227240b2ad50f65441ee15ec930dc74b087552f254753f9ecebe2d63bd77ce6ba9a6cababa926796bdfd5652976455dc1da7ad0ff873349ef3dd10a1a5e0b92b3a6014df06d80dfa692cc8407d163b5c0c9a8ace50d1bcf164636ba49b92b7d49931405be577114347cf1c4d85c2609126025ce2080783f01737879249de7aeaad6f33e091d54feb4c45d2830f88efa01fb32f0fcf67dc66ba98b2060acf504d0ea5df09eecc5a501ca7ec9901871d044145cceec8277a8728ea34483fc480f6cca223019c9c7261427a4b418e1d0ac40dfa170603193598cea1359b3291ce8085318a7cb67548aa1f1243db75719da8f17135064b984b9e5fa96ff056f638837e169bc103dc360a284c06d3e68e79a91ee5dc14ca97ba4242d3b7e09ce531fef4582ef2383131ff5803a36ba05e260984eab61be17d5607d49ce5f6db11c50e90df29def9b44e9e48227c5a6c8a1dd37b5cd59da7f40644fbfe795e5712064042e259063b3b834aa169f3cecdbc2c2fe16ed9d588942a664f6d17a9869f6532680f3b09fb420a875c225fff1fa2e26754b84fb4cc1ae54e4101457dce3d4b2c9177c78f5caba7b5498756bd6345b18f2d3b9a9a7e56289a368f4893b362ea98799b4a76a89cf3261cc1909ba5470d3e078872f1b7287a36c986d2113a29a50964d5c80bf87f3ca481cd6748a91c31e94e8ee8cfda615ab9249eff787bc615e014a11e75cae53f9f9573e8604bff5b880ef8499703463db5a71b093adf60981bfbfd00fbaa8c6690d0fc27b2aa75d58570bf3c1fd77912aba09dbff32274e73c575865d5bc73f9f1cdce8066f925ccd31049c777be01dad7452349408566f4c2810c13b95805792513d0236b4ba7e142e5c8c7dc26e0a628396c45861b614c5f8d627587adb6574d276e68b0f25bf0e7f10e439e80db2c8370813b4d2b4a03c6a5817767d5b328d1092ce45033748f570d0ca32b19d25fb6ac12c6f8b484a8e2ea509f4a11b7996c9e6d3abfe2f1d89ce3a2705f2a1adfeef2ec141f1f894bd5d5fb9b605bec011c4753b25c4f2d4c5d35cecd409ca6d290eaa52e416cb0d601918098a9a9dfea46cbe6e4ef61e67094b313f04448a5e0706d49ecccaf23d083dc8f4c8eaaffb8451746ce85851894960e7df687bd24babc959bb71084e93a0b575db7897628675b9139ab6a9c31bddd58c014a860a64103053ed333214a4e8f928459e521ba4bc1f1936e7e2c0ad3a4f35f5545288345ed1072a302aaa4bb422d041ae5518deaf10d869d939ae43d6bde03b25085483e13311288a27ab6e211079d9141ef89664ce6289cb2dc18097b444a5268fc230a81bbf4e01aedd925ce2d1e73a809f5c1bc6a33e91b28059632d1c7feac77df453a38b5357cdffa0d234d2a86ed0fc34d019e7ded9d87cd6dbd537b474d448af3cb74aa45ec1c6bd7c59a7078820f11e8bd9e8e8edeacb24372e4dde9451ae6649bf4abd605cd6730703437a2f36916deb13b8e8d183bb4d7c32da9720e9f1c23850663bda3d8c268471de84d892fbc28e8ee22e3369c196fbda6124cfab2c54e15440c4e27e4429bce9c4297287f8ebe939dea95324eeb981a14897bece61e35701393eb3ab659a3159ecb19e6d09dc0d2a630a58bdbbac1e0c536f2b6e604eea740054e425bf34f8895719a7be3a4117580571087f49088652af6450ec20fd209020693e31fe58b18eacda49b3b245dfb0ae0aeb0d1c0f036de53c8096582b813db096f3df7aa38da5803fe591c14166bee99118e227b2c81149322489a56a696ae3e550e23f88224c8db8ca0f048d246c9507ce33f901b859235a225e26bd0f35a74a6a7d85d95745ff6d45ea5aae51ba42f5fafea5d64f7201f905155e743d561cab3f0dc8d03398852b8e24a1e27558266a7a868de044c72d3d1d064775bc9de806a8eb7d2d735d70e37f34c33e4c1a08828f333130106f69c60f5648d4f4419bd6cccd57188417521dbd1ea4f0ae2257032749fe196667ffecbb3497ed10ad35873c44db037ff18123195fe916afebf28a5fb90d91c91c702b4c4f23e4e9fc6badbf1b678fe76ebc11333a6db4340e9da126dc84c2ca815ebeda2f7ecb7654df3d1958a7778ee2678bf64578ccb93cca228d770494f0d59ec89f1b2800756690429060430e77c0b88fd7c2214c559d44474b39fe269ae6fee2ef6a35d70b219cea7f04bcd11706e2cd1f56fa8ba8d399c0cce55b18a3e995882733ff0c63c5cf184f3a38a91a902b433dd3c2d3a0dc4c50e30d5f3f9bfd7f60519ffeea0ac96d4ab84c8b8f329161f4622656f01f7252006f24ca1f23d8ce243c4d070a30183f5e4f1779703a65a48da90553b6e410738c84db270eb129c82a62c26f812d9628a15f45a8427f6f0c14100e398c488633d2ac86151388697db61992fc4948da136040ecbc0eb76aa7aa07908b72cb2bcb719a54414c3755229bed338306bd4b5491fa29ee3a16525db5c1007033db451d5cf0da302052fbb766de86f3569af6e46ff0945858f9dd52f2a72b2966d7c54ca7131aeab8b67266b94d3871c513d52e3b532b00feac4bc93fc6399237d0ee6d69665b3af154bfa646a3a578b9f98f7d858893507adf1221b073f2e4c50b274ab280e1b26a169886e2bcd4893c15548f11c7cd830505306779061add04b1e5734bc67df84980acd74574cc205543f991f118d7284ccb4c4d9f54d1871a00c6268a48f9b59dd4ddd4bf8f861a3cbbcb5748660a8182c6cb3e1d6bdecb54f56c6933817ba12afd74b8e8ff631203fa294aa2091f40e4914355da6c1f0bac085388d17345766808ae5abfa59218950dd369c6e256870bfb5789f5e1d4a97340f9a962e4937aeeb0defd980e20598bdd68425518b018d37067d1c365bbc247730db31695240b2e2883c58a8edf1d9e37108b7c5f576fa2ac269b26883f541a7dffb25146bbae4fe3900301fcadcb8bc0a00b0fa316ff8a04a6c55209fb127da406f9674009c2e20db614114fc5743383c2122c52f27daa70ead2d5e00ed2a50de4b67d8542b08675fb39539adaee2338e8fe19846d9a18e6d9682122c8a0a622a5b835db000d3d8318a87a76d769d872a8ccf01072f5f71058770d1b1dd5cfc5a5af457e62cd01da88297319668c5a8645c102158c5e7dfad2932711789a44979ad7e7337a69b7dcc29c8b1279b4704172adcadf81ae682647fc684351ae5da0ecf6ee9d900cf8d7d29e7ceda7385b98b2c05f069991061bfb00b1c7dc668886954bffb0ec5a198982e4ec77869fc79da7d95b92cd901d8c36f6771a64ed81afc8fd0c0d8d5f79d4f919ecb4506badedaf8fda5e3a9de7f8dea577def88c1e0f1b0e14e08a47ff85c2a928f95663d6e2f5d1e9dcff9f001c1306db2243ab0c34ceb26432c877597602bb2e8bf463d1f9afa8e39de67b3b43f54e80bae59896dfc7569b043319cb53e379215b0c8c8b8a7c67f2e6698d72a343f303e715db24d77ad2acfe83d3fa1a65d1f94d719c8d4516b021ae0a488cbc52b862b54cc3b2a858be86a9437856a978eeecc851c8b0c0845cb597ce6b093dcebe0c05b375a5c823aa03e0449c9772e35bcc145c1bd7e095afdec8396017017895285b31782509314209e3c79ad3a9d80b0f7f54390d54ba0699d23e53fc0eb266fa7d777fa244a7dd9dfd7d9313f8cd3980076e5ab1e62c6aefd049aecb887ddf2323fe90df38b2bf76a36f305ee2b430ceb0b2879c63800ca9dca94a5b0dd6ff768d516224ee7d9fbe04d42ae16f8967182d55155f0125526c8cbb1f651ff2867c8f301621f65dc3334fe96b5ef49f9d913c71420533ac86d769173c2e9401ab74c243696de8db47068b7e0de56b63be10cab5a6f09f7740021fb9be99a60307a90676a65c5578f9963a4cc256829811fb2b45cd13085e33c2390f21f9cce78ace23cf2788527024e1041bdc1a430f6cdc57f36b617c1a45267990addfc14380ddb3fff321b0eb61bae24af2ad33de982b0901cf760ec0bdc59cf2a1859e9f0e4269c3e82c06c354ac7552230d26f955da5df27b1957e9570eb687b724da2ea8a377bd068ab26ca9cad6d50abd1d87be51c5d15186b4e0c898c7db513b0bdaf74df89b18fc88770e32e0263df00adfa8afab90f160e7f96c33e89d3533fbe0dfbf6e1d1e0799638472e75e01a2dadec7ff6d3dabd5fa79f3d5d3d74f1ae2ed72793031290757dbbc7136a782db59ff8c85370b2c08025dfb768a8d487797c1fb3b0568af71ac2cf2ce91822fcbebae6b7b154747d6cc2855262fc201294547a187f5db21858930fc157c57f9721204018aeef0bd79ec5d93271325891eb61f06fb70e6d4618abc0efceae62c20310a9063371e5cac44185c78c67254f531638d9c61ee5fa2a4f02dd8b8327c40b271ecc475f411375ed945f2bce50803d41f84bba76bb3e48fa814d610b83136a0589682a57d852f601a757fc627000fbc4d2e2e9035492d7aef38f07aa0b2ab0e8d444d6ca9f2c5b1f92253de07ffb0a17c7990a05665d1cd97f57c089001d3e627598132e8b9e963589234398950076b0876b316eec96c8148b8a2ff3fabccc76c488cdd72a928f6a53ed3a95296833ab8fec8b77be7f10bb1c14ee36c17ebf3108468039b7fdb468bf2f0c6982bfa45e09d88356659a47e95f2fb4952ad29dbc046ad40ea9aed96027fd6243fa4b0d4e2927b06ef2cb77bbf1ca0d66055146aadf8c967858499ee6c85ec3cddf1155c4970cdad5eaedf0afd1c9e7425871e5a1f0d03aed0f042a96b81bb19772dff69f012dbe5d5ef90d2c5052b493fd9c2d0f032d9ebfbc648d5c887cf90b1fd5c93647b4628a8da8d0bfabfc0cb568faf2926d741670a2bb384b7884da13df42a20b91ba8da822951014bda239c58d4e16a4e7d046c7082e741a1510b98c376c596d71227b03550f4cc767bf3c414bc2219c7e2a1cf049bd21cab406de78576d9be0c7aa08b2c24dbc34c752a6466671dd05bb9d0ee2a35b3d5b5828f3e0ce7b48de3f4021657c997e98db2004a823b5e7f98e5fa7d010d6422a023d7850f982512a0248837c6eff2322fb7b77b6862b712b3d094eb835559d72a14689b014ad943bcd3d978942bd1c5059ead3f763339184e10a9303b6b117e2de1eb3003d7064ebabfe52136cb6c999065ecee0380588c7743c848580967695f6c8e67a51a1286565e2a01fb69b104d74be196c30e4270505ef4491e8c8d0103116093c84414cd8697484bb6357465350c180a4eefc6a8399ef384bb39ab2e52f8ac410f13741d8c52f0d467a5462e4852c208ec49f65635abc2251f3a9d7975774e076aaf7971790b78aa394f1587b377075ef14d6ef3acd7c03a7b805f3151bb09847b4045c0a2921ce4e448fc1e0dc2c7833bc5cd4b76de9187654f65e78de35e0c3db36a464fff70f295b04c0fa2c4b03f660a5e875f1acafe4333cc07706290abc7fbae88ae1fa8cd454ee1150b6833e437fc7cf59c28dcf99d07123860aebf1e36f1d25f5c7f4dc3fc578f615dc25340ec59fc27b0c0a5d2b229a3bc7446e313534d9156ccf28a2dd7366ce439da125c124aa8cce12f62f49b57b190c0efedee7d9f49ec8f91013f863474e2df0cd8782d978db791f84b9027bc804916bea310002f7ec933a7f00d10af21d1176aef1a78249ff41ca4603b67ded5bb46ecb6c3e084b465e733cba989d90a92c839bedf72b51108d7bba586494b95c5d41906474ca12e87a9f88e102f0ec7d9ccb23027534bd71218b224a5fa1f21b21679bbaae9094339aa79ca68e9ce5e4cfe626d7cc98484f35db7ba5bc1409044b5e3f6888dce2e8709efd2283327ea95f037c4cfb2082e526e713fb8ebda8417eeab48e9d8c78fbfe74e0bc08129ddc3895533a2926798009eb2f19c884e2256983882467d876d1f6ac0bbf5027e24ef0dacc9967895c09a803e858799a4ad6e5a458b7cc3f73d68527f36ef3f2659d96c945ab4137241ae4280559092d502d739c30917b3263e7321b53bc2e15fe5fa9065ddc2b81d2bc11822fff8ff012c384fdbef667b7a3e8aa276126810f2237fa9a7b1c96c32b20937963729eb527ea326982b5017234ce330a12ebd1c93d05fc06decd5abc694d046e0a517950fe005ef86dc66238610be6716b67e54d9f427c845c9965a3146553794fc236b2b050d7aecc440a00c3d46c8a5149dbd902256a1b4b8073bf68521e6bc186c392b6864311d21bbbd72684415e21f0428891655e96eeae276a1958c8fa7ee031e2bba2d75ab525ae2d3100a20741823747d892c46835803c1dd38ef419474d9d0573d303239b10fd6c104891cb98554459d2ba41382241d86db4049638b1e9eef17edc3332e9038f51b15123f95134c575d2ac7e8921a48d38f7e5a9ad6d25c0793498c25347c80cc92f6de08be9c5092506dbc9a1c9a1e1646cbf7d21f9bba110741ecf26d9ede1aba247b7fb02fb8e80f773c6af5dd4807de848e57fa0fef3595cdf71010152e67c0b4988a28d431faf8a0ba01dd423e3e3d1030f29643fe17bb72f29a1dd80324a5f92ae414d907655e1d97f688b0140738afa5d1ea610b5a8d7348a508cfaeaf2bb8924e462b6516cf15a5f882b1df813803c4cbc0f1b821ff974364e3e312ee21c2a6d3fd0854d8e2e086979292a2dbf43d3ae08a016cfc384680f66cb64c97e8fef67917d2d3e34228ee539f47ce0595825361a264187504b2920c1182013784d06d418b89dafc1469d6f4fab5d8386e940ef11e46fe685cce87337929155f15006687de0d1b1bfd9f9487c4e77d623bbcb9c96da745ffe477dd362e7f6bbb7f37690c388529cab9ccbc577ef96cd0d32ec9981730cf47b2753fcc26407e27aa5b32a229ca3613c02806859097b75cc96c46655fbfa208aa902232821c2402e780cf933608b98f0f3c52f79b15ec196283f481d006bd43fce075e5618be101a717c810b2e073914c711549fe22c39bcf25f1d0b4c636ef92c2fc97651011b59f99c6a05157c7f7aab0fa1645cba9e7395dff61e13e6552bfbb2ef415f46d5ae71f0f7cfe65f3c5b39b5d34db04c5f166702b2fdce5f04c487ed3028accbf3da510c05cf104bcf5633ab4a44ea32df7814acbd72fefaa3f1da9fff62974d833c0b732ba563634168a75cbabd4b4785c762393ca75efeff7bf5150478509df5f8709fd330df110ca2198b5e4ce92fc5c613e4d41c21e79029de18c01ba130972557153d76b21c04b50d6e1a013158f5c47e8a1c77b0aa5ed18ecedc4a523a5d6b0aee7ea0a75572a0b54ad2cf96489577c86edf4e906b1913dea529cd7e9dda1310019c6dc51b4641a038ffd7924b80b9af6a12dc7f8ab09770612152004efca8a65395dd248c96aa4845452b884ae48ac74d7eca51b40e9bbca282e14a265938706d6b101dd7f5337d4b725c61e1a79e46a29303b78d512adfefeb0b1e7540df32f7e513b51def3dc7ce29176722ebd991ab5acf9d7617403c6985cef3601ee5496c7582ae4ec98593a5b746586fde02aac4a2065be599adbe20edb135e9d8ab13ac00add4fa50eb592d5630bfc4c2d325598bb97ee38956233d1eda5602601bdeeaaa8d2904764322021c3a64a144cdc2e8b76ca3b9825144e9ef8a5b9cb2ad281db08caad09dc51d19670b975128d5832d4a44ecab2dd4e392396eadfd322f9479c637e4fc10b55b2afc66e6de7ea30ddfb56bfed8d3e05e0a4d2751f49310c4419262269bc9a2ebf4f8bba0bb94d452fc60a2ed6bb0e578e4916ebbe0ff95ce265a115d4be44b6bf650b5a4eb94fa77341969b3c0ebcb07bb0c7821bc0709a93b4f2478454b741087a35cd07a13a685675ccc2eabc25d8ad3c7f5af234e7241f623b133afa9489f8453227b0a7a259d43721100714d2857f9615cb846ba363ef789bdee76bd438c40c7fea960a8bd55513033348699b7961cad63f6f42d66cc431e660e48bfc1adf43aa0dccd01e4b1ef20decfb4d5cd47021fdceea9e16328a0de9e33187ba04011bf12683b2ff85e8602730da0eeb96e5e1f2ce64112bcf9258ca1ec60093077f690daf1f0b4e95233a4d87c092d8bb758a856be895afdedce82e5148085f7e1aa71e279b8609cc1f89c8f2dfe7201868e754b57eca92a074b05ec878cd5db88ef975ce4906255b3199ffd16caf0fdd4c9cab70ae3872cd807b8bf4a364babb7acd6a989c89eeec35172fc47e398a85490a272b8feb983e69ba725f66a4d10556db21599d82805f6b186bec99ae06d8c068dcca64cd4d34b339b5e9076ab1a4fbd8d93d0a378cece535fb0b6fa581f66561d14b99b374f18c63063e1e7b7d1bb02ce395772621fda74625592a1509bfb7476f1089809039b7c2a26c2d64c320a5252f91e4414ba9061109f2860c2df52966398af4e4c210b6b269869702a909a19ba3482e066d50f8860673122de6304c1e9f974482078faffbbd3a24d040a2498cde2b5b943e20e430a95b7f307517543042edd7efaf93c99abbf5337fa85bcb7c53361c8bcf45bd1df499767c06e6b73ca5a7d4e06d6ccd0628eb48813e87d6a4cf519c1022b4dc4c5bb33bd6f5ca7d45509dffd2e6e76fcc88325810881ff9d11147fbc6a2a1b97fcfb9b5426003eae371b2992d95c0190ebc3bd6ef09e792f93e061a6ea994b32d401febadd90de2a5a6af4658c78c6298fb31bdcce8148b972d98b7cf0d3731e6d91f840062b4afac78bfb64b56e65b2de22231bbb313dfa49704fbf7cb077598514e25e43409fbc3b4e65db3b0c0ce5b835402e66bb09dd55a86ea57be1e582366d67ea58d365943c4cca29101ce70af911d6cc3cc204eb2fbcd07079a098c6fb99d632db6ed099b602002ae7000c4231c70832c87bf8b916facb0016104069e0297a228e4f24b1ffc9e37e8e604403ce491e4469cd0592bce9a5fcd2c1a960d2a96176952e6e6c7c53c950e2cc3efe17f4f8c0215f7f4c9d81c615e7c112cf37234325a9c6a041abee4f2e1483525ed7ec6f864c25985ac92e2b098f6ae42ee429a451305383627096bcf95018cb22cd9a1140ec78319de29c8b5211874042a1a2b6b2005f714d3c5688ad364ebf96c59216c32d325bd66b4149e8acf9817483c9f7264dee0ee6c17252fab5f1afb4e41f5d513ba4cd18c818c557174f6142668932111ae8886235d28355e8ffca886470becade505fa99472c03cdb64e9c76d20e2fcf77d002c69b653060cc13920b703afa67b36190193abfae2edea2b75ba65a8a94f147cb10c388915d2e620c813591476b40526bb0487d18e28d882d588be8c1b6c01b8c92b4423a80279b31e14408086d27f1795adaaee62273c4a2c09674948107482445230d40c2d51200613e4a7801e2d09158503d1c63e1913580a22056a8523239fd8b5eb7ad4d6688b65dd946c63c5e0343e9e207b744fe28390bebe69ab19bce1671db644f5c4d706294bfcf23b1045c0dae24a1b548f832d704c1171d668e046a29055765f64cd122c83349280207f713ec6d7e3362320df75136a5305a49103ba72b27f5820cc524a0783fcc92540a636b56512542300ffde127ca48755ca33eaeb4a3fcad21b18b0a6c2379d0b877c96e7020070fc623abe006cc2c593f76252b6698f12d8255385b3bfd9974e5664117d49c8de9b6cb9a59429c914a5072608a0075147ff084d17cc60fd434a95744317dfa1ba4da541305656914d0db60632d8fed8b42a74adb921786955adb4caab6ed3afb7386cf5c686d996964d76f5943d656b3626b253d844a20f1a8cb25bf64b6db5fa6d255772255752ca8f88a505d7552ec431eea87bee91b6ef65b41db17e7ba46e7941a26cc8532ecf3661d3d8909f7eeb51b2e1dfe84d0d4697c2cac299764c0505b9504389c5a729a62b2f08cce0cb7f8a89415f6a3042b9fd852745cd08fb5d7563172737642a9f6bacff1642080db28ff94db5213e710038c4184fa85f0485a4bb7aeaf54fda0c6020d611c6ebd3f3b95556bd12b3f14fe85437723e47b1bbbbbbbbd65a8f1c8b952ae254413535e54d0daa9973e7fa57ab34cd397343ae9a33e6c63f8a4b110a0b8ff598d8138cd8eb62c0b08e68e958869283e5862e0575e39c7136cd836f9443e7862e0525e78d508cc5f735cdc3d930778cd1ca78dd3b07c1e7cf8f0760c6cacfe353f3a8f5b6b1215715b1d61381244b57d8ec271b3b35c8c15b8a032d754d70f76fd67529068acfba633da64de9857c879f7a46664f0492d0a9725d2a2e71749a6efca3168a11ca56e5912d2dc50bf0e0cebe6106ee3c2a21def9448e14462b979fbb1d57b08f69d085441063fc1a638c532ed56044622b2c53c9e8a166fcb1f62012740130c813b99c6c1524a61b72951179b9cf6c56242bc29572d42ff71e0d36acd9d31d2bb0f46764ee699023a458f71d21c5584158314887f41212e359ffa21f9f6ebf75de11ffa3d677cff25e42fc488c7b7aa4f5befa55fcd949a0e76dacdcd3a220dd778414eb7ea394fb20acef28c6aac32207e97edba851358af1acefa8f531e867b46d528f04fc59efe560c31a3bef48f7f6e30a859e6fcdcf0bdfc5747ef835fb59c429cdb49f45fcd2af48ac5f18b38c9f64025a5e52cf97a5df7e475adfbd7722b4be9751f7bd84b0de9f553b8ff5ac2772cab1e91971cecac609e89eebd35823042e223e25d80b7024d4d0831bbff5b343aa1cbd19bdd67b566c5867b6630536fbf8f463adcd7dfb4e57146375a4cbfacc7b01b14fff957df721d2cd4ca81fae3e3ef55e402a53ddd667b1fbb1fafac9ee595ef79af44224ae5ab95c3dd0faa61835b0c165282aae5031755b9f3da07b1a56f6da15458f487f186fd6fd583deb930dfa0784fb2cf3340ef403fceb7b25b02dd66bdd1722c9d80de95fc9d0e76637a3f4b3c9f28a6419fd2c760ff0cb755e9178b9af886f5fe85e96d198d4d967c46fbf5c791ce8d73e1328fd5e3fb2ef05a4be7f28bb1fdc60483fd2be6d3912f4110cc443ce1e0dcaafe39c2cb93010f7fb833d5b4ae9359b93cae539e753c96c3ca8536c910a7318b558f0d6a128050a150af9cd11055888d983f8c523ba5ce9e5f613c1e011285879310822bedcfe1f18944188b90d24defa452706923f2c61bd58a575c569ea7664ea9aaa24314c5a2614eedc6e40ebfa73d26d8fdedefe8d0245d29a52b1796cee98bd6d904e4a4106ca420a6d308f301eea98655946a3dc3e6e7960b0ee7e10e0fa34ccdd12b1be8492a684ceb9a3259973ceb92599f354c164712749994e09d5a6821455ca93357162369973cec9056dd2e4882964d07ab0a658a1e7888642082396cc07ffe75da87ea54049ec3084154ed04045455e6102059dc354032b3141f650dcb007d4144e6ec84f5041526fc258a3a429a19452eaa50a2a6a157652a8e20e8d32e79c93ce4922abd0228a0a3ee78a2e0d0b090834349440872aaeb0e2c9ffbc79f39455b14605695dd6c75a3071bca0f64d1a1c59bd0cf5a6cc0dedcb293e9b72ce3748ace077ce39c12ede68916f787012f98d0d4b2cc8374a5254ddd0be1072e4c869aefad81aaed8a4e887941bebf0c840459fc6a0c76e16f16def039d75d7009f1d9dd545fc4a59f4fa31affc79e52743eeba0fa25e451ded2c078a28a5947215853806350f8dbff0bbfc610ed7c7618ccb40714d0458a8c793c043f139c64e36f3478e1cb24ce33ea7fb941d7cffaa6a610ed787c1ed8ed1234ecd28986fb33a76374f9613d162aea05b30a160cc2c2920e924e0d0691ea2d0c18e17477899410c1776a40e52bc10a5704297b0cc610799e509a5945236db9299a539e79c5bb42496ce6001536689cc218a3c38bab80e021531a490c50b7660708a414561270a298c608edededebc00792363e08a715737ba96ed0410f884c8df3c98b71a3dc6e81ee8910ad12a1f4941fbd51fadbe97907aa4fdeab35d100d29cb8b525b836050a305954be3b21a2d92ee2ae9fa1663e762a0d690b02110b96e8df8ae27567e3abc8ce66fd33b92c27cfa47d9d3ef25847efdfa1dc93efb65e1587741e6571d5614841dd6e06dfe6929a557ab11af3134e2d78b8df1ce90b261e50924ebd95aedd71e840e8df8cdbe703aa5596c31db7caef40b91aee6bd7bfdd4cbe873d461f4fba83639cce46fad785d57fb8d3fb0d9d3cf3edba4c746b0f68528d4a75e18847ff5fcbd7ec4d79efbedbbedbd82dbb7f7fc85aeeab18725dc50fe10d7d5e86fabee39efc8eb47f6abd5e7dacb8c662f1becbc7e5f7df4b28f9da669da735e1d12224529dfdcec7fd0cf68a5af7df54ca0affd466b5d7daf9708fedd1bf5733f02c7942cf15fd2cf7decf50be97f202265b4289b6a98628c5c966dcd5572488332f3a10648a2c776231e1b729c127c931cc75b59997dd7de40a615bc3be7ee3e65dcb05e4966862eab276a758f05451837c6b8c48a4be365f3e07169bcab2ba2e1fa0bba22d7054b66b817bc055dd10516fc8caec88219cf65ee8cf7e98a66f8bc8caec8a70032a264e0b83264bc1d7365442941726524a9f2fc262a05237ccca9f3863560d77d6d73bb28244144252d0d453279b258cde76a3f57d3c0b8e26a618401834c0e28305c30c01765044085c31ad7816ef8737de8ba7781e7ba175dae7fd142175baeef7822e9e9d28832521084d405cf972f7440a2a44649621142c4192584b83367694af6f0f1adab8b2b61b8cda52fe9db00ac10b9aa252e7d59b9b8e1d26f592323ae9ca9a109942e26903c68b182e32ba59492c55dea83c10d6ba4d962882a2855415cfaac05144f292d028719435c5ca5d1428d16488ae48f1a353c74c31a2b9872a91aa815dc61228b2f97feaa2ba23f7628163c0061a1e6d2d7ba22ea0202aa8b3ca410183c58e0e1e14a2d5f5ab42b9a63ae78e2ca9f49288f2b942e6582cea5575cb9d44529a55d0d3b6899e109a8289cc81d82684329a551892b5fca6a0410ad035cd9a4c7d2a89366050bc2dc71d59942698618a70bead059c167aaca823a5eac20038cd30c3b4e96629471f2b1d342cf1a19766e7062a798a69a62d82c515a524f3d45b0c022f364c57462a85a76d840e1ca24b1ecc459dac254e9ecdc5995e1ec78a18599daa044a960a856539c645254da0d4fe8d454f58185d9942121472853459960c14798da32a558a14700c324a1acc013471853e577902cb198a5762d599f79394a69e986f63fa62a9d3063c4065466c2c0943063260c336f02800233564099c90206eec1ff018518d3303ec3e6cd0842d0f17721fb50679e38d9accbfab8a82e33c1b441155b5f0077b03d337050c6763ec048605746dc60b2aea81e2c8dcb5067daa839a3050726b0f632141a261c0461e56528343074b0049a18b8a0a90216292555283478aebc1cc504889a467ec040524af9335e4687c085667cd149c6e7b4f919b9c5c9bfa393537b216850dadb5e062cd8beaf7e19fff28ff148b157ff8c7ff97794c5fd339a71e413a570623346082f8208f326d6de14368c4edcd5b2854bf3882f1166bc8c1732e37bcd8f21e435bf2016bccf736c8637c5f09a5ef367fc8bbecf7c19ffa2f463cc789fef288606868d5ba2d30caf4e4f460c3b592d5bc442710aa7f0001cc56418cd16da5aadebbb19a760a16efa81857aca9d78a8e7ed6f5fc86fb80d0b0d198e3ac00da35310cc73f226060aa3d395641836e5423e45471b100d19eb4d55ea80815efdc2a7e14dd2c730907ce9f235505ae2d132a9f565c78ac54ce632475d3e40fd3008e65da6c15a7da21030900bc52c0c237ac3fa421d6d40344f66fb42171f400b0a75c0408f7e215755d9f8452c0cd4ffa6898d71a83450a2ba336b20e221edca0fe10703a434c240f2a50c6a50d24062c3a0fb2fc45588104519a5121a141465f5a15f0d5783f25d4f49e23031c5263c24b770b95a8c04312221c85410128884800d150fc9205808749893161ee2d897332e3251472465494957f8d2cf3e99cd7eea713569529b94b4c4431dbf081ceefcfe0a033592fe72fb6392152b6e686fff2775a1a2a27092ee002e434901c3dd5afc2359eeeeeeee524af9bc926337aebb197d38fd6ea8a8a44b68b0692029212669a064e9ef7822e9f6c73b3db8ef8f639a47f7fd318a7d90109f044025e9c647bafd118a87b4efef383da85a055f6e57cf9eabb56ea1e5cbf52f32d1225abb4da5795471a1d677670083657deb8dcc4b89da87442974f3c85483a51f910f095bff82276c1899989a877c252c12b21ecd636e3884c7c8cee306394f3210fdc85402fd76b99828c779803ffd6a784149f0af3f6bade4b1f2c75c60bb3c86f5bdfc39e641c3fae5d743d362ff06d1e686b1ca8e226c18745b4f36fed956726cebb21cdf1144801e02906c226080201ed22efd1e3c945d4a298d94ee6890067957580b368fb075e9d3a78fa379bc44982fdf68befc5e6e24ffe534c8ebe16058f0fb06a9f7848dcf2d1ef2a74fdfe5424eb15d8bd78fecf267998f23ff1b82af20b1cb135c945f12ebb098041737ecf1ce64c3ef6e23b6b8758d06df07b38e0b6e5cc1b11cfbf0501d29b788237f4c6a9fd78fbeb7430f5caf21bb600561c35aabec8af43512af4767f9137511bffef93050af56b4bfc6cbe95397b3bbb3ec9d66efd9f7aaaf5a332dabd98a66b4468334fb5c0c445d48946905875da8d6af66f139ca961d65ec2867d3bebe84c423d947a4d8ecd7be5f46dad14b483752cc575fbfc8c45ffdfce339992753c97d822596b0239528a5948af912a6c91c33658b3995d426d9145a9d25b78261c527fa7cf4c1ee75d655cd42326c3ef5a6cf902bbbd3b4164d8a1224a14a73ce3971e0acc89aa024c86850a299d214154c4f64c8d8d089939da1d366632e5aa89374450c5f5889f23fadcb5074cad0792242894f09cbb97a5c574baa25852403fbf23753f431bf768add020ff9d7276020f95576fe0555ac43d9f935d34ba766f26abd9db8a71c2669d59572cb93ed0fa55383528bbbbbbb3bcd6a56b39a65533a15f13c72cb4c63a58cc997f225a5d3952fe593749a5912175bcfc8ec2ebf38c34b66f6cf04feea00bcd8500ea08b0debe54827ba942edb3f966ea4bb7b411a74b11c638f066316fbf10586e5675d6139cbc62a39dde8aa11b5029b1b81e460f969ac60f9392e2c3f8d26cbcf6961f95759587ece0acbbfb962b0fff1fb698d952fbf23f225443b32ebcbef6524e94bffa691cf77ed031d16654357c631d72ae9e9c95aaa6ecf9e3cd2aae8c3bf6ea25df050fc3a06a9c36dd9e4591303655318d6df2c75f0ac04d3091bcaa62a4a45a9eacd92a20fff4ec2427d03c3fc5b0505ddb8a18106afd70d69950c1937a455d90978c83f1b32a7e8237e5d259eccb2afc618a43583e5a0fb65d7bf12c2c84005eb3f4370ffa0c12f96a5571692672453ca9c65f2e7c7ccccccb17f91735e13e6471dfe8573ce497d4e77671f43bf3f32f3836c57aeeceb17cea79ff48d29fff44c4aeab37e6c3e98b579d0d9834ab13dc3fa4dfef931d07c39db063bb3e7ccb3f7ccdd9d4ee7a4b75fa553122e9862fde51070052a3fd9a046e99c93524a69651b73596599ad2bfbfa8594d2f7d64aa394e9277f8d95ae7243db1c1c1b3fb4769b2fa5d632217b7bf9f20db3eff5c35efa56725b99e1b2496da756b3596687317fdfd1b9fb0423d90581afc6401c65fdd8ddac3e0b8a3f4ebf6d153ffa8842d661433e30069b7d17f13c79eefc000085ed9e7b18a5dfd4697baf9e3b23f1fec8600525a8103e2019aca084822bb39a7943828e6ef6e4759ed39698c47dafd5b31e2976f45a716fd4fd5196d567c4fd113bac23f24ceb07540e04095a7536a66672c505b9da576ff34222770baa755bfde6199137669ccc3167556b500fb0d6ef2a653a72b7a05b3b22dfbc217eb72d7ba2ae73ca5b2f145d8146e1c6f899c07a9e3c4c3d3f645580e3b2428aa156d13452cb45a105153e3b1df87abe0adc215fec351b27a06a14a87d6b833de4a7860fb6bdea853528e0dae28324c5dee1c6d42b77a2a0246c2a777efce2d2276a10dc3afdab3744bbd37f2efd420adc213f57360f198ba2b4dca960cbe001f0fc2e1a6c28a5dc7e0078ff1978367078ee0ee53ad3f5a5eb9ffca8e5d29f1edc3bd32bc2527e7d27a7ef1efd1e4abf5b2cfa1db73dffdd322e7695b6d25418a8df29d392cfa5c914e91a4ad5604f6c2a3ce4b7eb58b9dc2da0bbf30e03f5bf1abae6f627e08654eaf6bf7ec40fe79ddb318e8cef5a2d8871e89ae843aa79b00b517bc5e9125df2f61933aef4e61b0094b131261719a582944be372940a4e57724f13cac6383ca4cddbf3126183e7e085800febe46f4a80beefe037f080707836dec3f130cffb0e827cde14d1ffcf87fce4c6c67fff46dfff3ced5efe7d363ea39feffb8838ac8170bcc77770bcf737bc0e1ec8037a22df9aa311c777248b3f8ef77e03ef7bd0bbf1409e8defc0fbe7c0037a98d7c17bde919f07df3da39fcf3e0eef083b6c83204a6c7c47b218d978d81fa9ff1db1f1c19ea877b8c1f13fdfbfc38d8dff0fedcbdfc8c6e378a3ff9fcfba977f22e0781b6f64e38d7ebeff1d58d8ef6f3c070ffbf083e6f7e1f81b9ff73bb0b040dfc16ff0e0051f4409d077f03fde911bfff33872bc87c3fb1c38be1b379e633f39fe7ba31bfff3396e7c471e8eef891c47920601781168e0e1d0e003f044fd9a36bca58ed9f8f794304140ccc62f75ec7f7a416cbcf446e0988d774f88c7fe6f784772fc8d07f28eb218e9f80ebe23254c121003faa518ebe0757c2fff7f8e1d2dc518d0bfdc3b92c528c7f7f2cff11cbbf1475efebd44d0f138de28c7df781ddf5116a3ff1cdf5107ff7f04f4369e63389ec8813c8ebd67c36387edc0638b7018d703485787d7081cc3f147fc1413c18d17018ee7588c85910948098eefc637af743061de5cf22607de065e00bc977c8efd7cf18af7925facf27dec30cfe398e6c5022eaf25468cbf315c3786651692317e2e7dffe4c243f6dbc7e743ebf3af2f74f97cf8e0f599532e7480eaae9fe2823a6e28a76e5be0c509b91bd2a513a40c2fdc71c3b914ce23b8c1cc7e1e3050f6d26b58f63b82b2677d2178b3ef6453b67d2bd9247d4269b02753f6cd2522ac9cefcde33d8e6d36bc23b6a28a229262287448a05012cb223f86b2c98697c1bf07802506eaa5a8a464632ff150d75ab2f1ff05a87e8a4f36bc230e63878ba6180a1d12306462598808804ad27d01f1f94929cdc3bf5794ba52f70ca5734d1c7fd31fa9629517e3c8407a75065a9c4e4ae716d65e8e6a52e786d6095ba700f3d849b54113343770b074095818bb41c1e21811c3096ec860b5cb514d7668e2060ea6d8ec7254132a514d5450a1d1ac71185882a8264b3026b65e8e6a920456452d2dddb0c5883d3fa0952c00781d830e9391d3b48ca39ccb67b2b495c7ae39f8f3355c96ebef18db0220ba6ece07ce4fad2e17e8deeede2e996bdb6e29a59452cae972d5eadeeedeedeeee1e4677daddddddddddddddddddddcc1e6b5633dbdd168c891cbf7ee2cb96d3a7f469a5f4e8eeee3eddbdcacccd63dbb81827c7e1abde9e3be7b43d5c10e7838dcfb1e9996105671f9d9eb4eecc2d2959b29bdc26b4d2404f4ae9eeeeb23a33334797524aca75c58172cb28375db2b816e703c7c6f7766666890597c5c697cccc2c8362581968dce5486d4a275a9b34b35c6b955a46679eace59e676a92524a3549bfd612cb0d4a2d8fbb9c4efb0b7c95ae71ee56f6d0430f31e41472dce568529335a3938ed46a46670f313030e2c96378d0608f1e2c7b7a68cca0b2517a936696de217aa259cbcdb362b78a110c8a42b109cf2acb326e3e07a475b32b5b4a6c7ca2bea2803b1bb7e23a6d55a90780411804ae7b0ccee7ba1ff2d20910b9b856d6b2140ef89e8bc613cfa6553775537f37b5f74c4bd497c8870ab7327cba46833e3e5dd17c9f0e8478b7ef91351109e103063491e8e3b2eb2a8081180f118765868c18b56948d597b2baaafd2a41f974b716c72f906881a10446125c1e2a3d75f2741191b461a590c38c242e2851a25e71dac2c275289f0f5d6acc8d5467dec42dc6a51b5f32c9a6282638dc5056915602bf3557b533ae1aff036a727eae5ae7ac9e03f31712b9fcee69316ace9e11d97dabf5acdf9cc7cf5baf46c36495a42b5c4cda925445ca690b978e49639a4774aae1b6969854030f456b5f0cd419e5be90b3cd43d3be6d83fe5af36885ace7063b20ddb79e763f58dffac2ee877faf1fff99c07d7d13581ff7b1731edfcd0bebbdb776f6e372fd5416c45663cb6f296b6b5ab665f57385f2fac88fb7b0fd527619374565839d7d3472552e06a795317e1f2748ea10db25730d1777f4b136f2701e91fb6958fbc795a53733478dc50c245faae988d4d1842de4fa823556b0ab973cf4bacc1139ac351937cdbb526a14b8f5d3a17b2217b2600e192f49b1fe10788abb27c81bdaebc3403e633608d1076d14f2164720982fe70bf22708f65a2f7b0c9ad81882526280c5ceefad2b821297ec09f2b6d2f471811c59f6072d4eb23069c70d665d7da275355ab027c8195d51f3990f78a559502de058210a777b9f79675cfeee4090cf711fe76d2bad66744abf1bc771ab8de32c6bd3a17ba1eeb3b55ad75f30eb16602f064d408860ac50b9fe12c808ee7c39878c97a41b9f8ee04a2963dd04bf61816a4900b458d762fde517065961c0c4fafbac33ae3ee7e0baea75f66f48d06dd939a0748d6ec6bba29ef7aec8468dfb0171ece8211bbcdb13750cbff5930de82be3eb0848323821c1020625b2a071136386ad7ef3647c2b2f94778be1c5cd0b8feecb7ecfc70ddacf6708775b9f0d3595c16deb3ce95b08384f3e6fab2f3cbad525b38e63441a6563fa723e9dd3887b992165432458fce49c1f90ee8847bb62e3e253c5f6f21b48bf34322f064454adc72552c788878a14173684b1248822b0a041bac10b2a52f0c49aa617a03883a51ef1a5890b4b5bd4489971e20e9427636a70a18a34f38212197c50228a175e52e044132c984c0933450a253985a5bb301126490e5cac5461d102945c420e1a178620c10ada784953c606364ddacc3047094c1d32588a50f183152956cc14d1650c92152469b2f06108252b5188711c783042c30209dc2041c39a3261d88b28787e386229890c45c43c0a9326f06899414e5211601070c50a2a2559e84c8142aa480f767218020571b248e14b12121f78c0f24445c78d12333411461b20f0a8417243145216195878d374c4164c501af00186285190c0f3660a05484c48be809344c40b4c5978d12189282827a0a0c9d243122e28beb800c60b4b9078e1e9d5449326a29ea2c890844422ce1b26a0f2cc80e4c9982e3d749b33499871a24c0a787e807204961f5334c8f004551518d0482e0ee7688a9492921b92ec70c5882fb248c1c1ce114f9c48228bb02c3081a50c1e20bcd040440d5257527053039425e4c82db379b0001c12acd0c59c1380791a824a082849ba8c31c2890c42fccc2084933a2e8019834706b1c110456c21e70b0c4b3c915a6201e29c3b1828488cfd183dba7497d2047fcbf9b894f2db06e0c532736c61e39fed7fdbd1e08423e55a96a282caf5e8cd0a8faef605c99ecfb4af861b1b1a91d7ff33af2bb259966599b31cab7d4fd8ec897ca57d6683953fe78330f61101d6317b0cdd98414d82c3e6134008cb178479ab77b780ecb320acfab357f6b5c197f6f433ff97f63103655fa5fac2cc5282534018b22ccb3249b92b9f5969a35936e79c349392f9d9a564965688bc0cfb6ab55a497777e9e2ea5dc732b3e5724193f53959f21429a59430068a43eee04f8d70ce39259d35f32624b394cccc524a29a5945232b313ac2ab6c15d00fed81579db62a27f5a16fb63fdceb2efe88f8ef891621c97fa6d2cfb5ef30ba284484c7298fc1c6e2cc7b4cf92e52542f6ab37ca7e95511965af7d47447e81a7ec439ee25864a21aeadb58babeb1bde56ba706e57b66ac7f3f295929656520fe4660398a853b37690496a35a48ba1a0f55285151b4cc1fb0a85158f82259e79c73ce6f86a72c2988422a4e9dd804e2ce29ef9c73ce282876aeac320aedb3d5afe25ca0bbbb2b9a9991797d6a9a94ac56967d8b2f708d4c6f0f071b5dabff5c1f1176f55eb4aa736a9aa6d1baad3c49572bc642c677df3801514c4e709e3ace5add7cf7b1ddd9fc699817ff6a6dfe8b962459b65e45f5301c193b4607a37750501838e4f72ef97e411359d34829074d3a77528e41ae17eefc1a3be6fc1a656c92940bc5e8c7675895b65d9f552297d218437214644727e8e4b084ba5952479ea15382254f986e08e2887af2e4facf1326782403eaeac78316cab6678ea8041ea25f2debf983feae42ba27ee7cae85826a341577c670fd2368d3f0100b2399f0e1fa00b4a13b9fd9cb9d5db24b3f01309003a8940278c0f5e79e3ba9f3263b20ad1f0a6c2baa553a23730deb276aae824be0a1eab12bd2ec4ac4bc91835d71e1c1f6e02786e2a9356ce2dc59410855f47294933437fca02dcc45d5103e709102869730f2045b7871030c29b0810c1236fc8025c825c50a2edc2c718309a27832473acd3373a20cf15b94133237e427285e739dd9506597a39c28f1840b0c6a2995a9e4b201e76e6c86c0c00e65bab860064e17282658f26632b1444e0d486aa05343d2172820020b1f9e9023656e804a933356a058b303179985c9d28a09262d38993f9f6813a529b436dbea7294132e576cccee85ae382465fff42bd2baac8fb54feca65d8e7202844cc1c7449b945ad5b41ab34863f4e862ea8dee4aaec7a406659426868ac2f247270957be7b174cb1fc52724bf68e6eb60c54b0fc910121307f80d4b1973cc39841068a3f35a4e5cf66d44bb03def60201b622cf3d768707a4b2943ee5a8e6777fc9658304ba794ba9c9e0e4456b2c75ab2f27988cf8df23959e98c69985d0ce4534379e7bd7bd8f8e7b3cc595096654fc199516a5d73d6ca94259d328b9369fc9a3d675ea0eda8044e974435e9d0d4000000404000e314000020100a07042281301c1ed2e55dee14000d7992466e5c9ccc635190c32808216388210410000801060898a9a1210e00686d76025bc4ea29c66fddb6a2625ef32650a17d51929d62e56f757534b5b9e7b69a46ae0504606dd7041902b0ed88c9166c7edae2f917205454e88abc5ac38df461653ceac3153de72f6d48708df4bdc8f5494b6e6f0e589b8d05e1a32f599c0eb4703af805f5e7ba19063c3213553b890b1e3413f8104878e29d927f86f3302866c12b308e9971a5f0e562c1f5372fe18aaf8e2e40d0dbf772add0bb868d736f6fa555237dfae0d3b0d09a62de1bf91eb8496d23c5ea087cc370f1123ee8c4dd3f680660bf4b8ff0ee53012625341a6c7d3a262ef00e23d8b42b83ae8125ec0359d869361d26e8998536ce15c471e4ef808d8917825f6f8af2787bd0dea78a4cc528c7fa1ccb668f297dba1a2587c1d45e900e0e1a3020ba5062eee10cb5761b9ebed3d6a6d0672b8cf10a10ad077cb63340cf968c0f51a2c04565806f62d25b8e8db508a6099e4a810b9d053c74d86a66cec8875fddde71ff2ec76a5123d2803790b430886eec3d83b57e1dd3db0386ad98029a74eef4ad1fd92abbf0e77a4fb6aa8ac22bc1126c21b4315717640458ab3492e4d0679644ed8d371a52efccc24715b1d5a908ab0ba4bd7c94ae6032833ea11ccf7efa2c004ba4fe30ee2a1138e6c6868bb86721ae3d088a38a0e8c49e63b24a275a614fa83877dba3a46d7bc2abe565ac528244b10bee5e192a90248b978777b897ca8af3bc37313b80edf8696418bf91832ddad7aa5055822c6eacdf814f3f9f9f701fc49ee5b94b70642832cb9b883f994f2a0050fd767cb1d6a7618dd35b7f49a74726bc5303fdda29631a435b091c33f32810c0cdf439f1d1c71e520e206f798ef2713ae4502fd133463345999c6d44b54c9753a4b943d2c1c56e8cd6e248e01d70bb887a2bb224da2517a133f668b32dddd59f4438ffe030bc036072a3eba9ab97fe5a621d31ff371be3ff8f3cda7b6446c797ae9ff1a3c0dd77c0202b91eb36f6048e8b42033d1e9ec14d211a7d430a44e1c9956731f50156ea6d7b70d1140bd850de7c9e4e5409e4519fcfad5aa90cf606e1bd68e2c8f49a2db2e94a3cd7ed0a1e52790bca95181efaab69a04bc593b91ce64548bd3343ebb108e882c57cf4be98d06fcdce6aba45422417e8d4c8a8cd9fd09dc95ac0e273bbf35c6a92830b3daf1e96bd7448a6a9691c5377bf6d35ab30331450c9926b19468c9792ef4b554f52349020eb109f6ea8c8540457cf80334706f511ab5419a891c01b27f28bac0e8878f851d49142885f64ffbe325bffc7080865f3c8d1ae5391de18526bce8b43d3422a994182d73656537c21ed39cf4a578c435568bd8dcd4d1d0d4b8aa0c8cab19efc2c352b5157125c28f771c5eb7b36f7ac89eb8ae6fd25f3b9b8feb4ce8c9861a7ca6a4a6121de7eb91ffc4aceb45df6e58e185c55316ff4898059a018caed30ba1dff6e5e5d2bc7489a09d323a2cee41a363990e621e5ae9236bf1e9d04c747c1cf713ba3a6c59d23ccee2e929b1fcefdb7445e8f12382c344a3bc2bb8fd904dc6bf3d66c6924d4c746884e0300298393c069081b51d59ed0efa673ae13ac788742757d91846fffe312d22b0b064a9269be70c4f592c0c6c0de52d8ced45ef73c43a5beb5b2ea119b026b36a1effb37f5a12692677ca2c5541421b230b03791102770890cdc7c70a662f1e82aaadd35591c2b36d7013a371e49e4de7d03423f2dae50a3b90e9179cef4ccac2c355af7b1e8bda115ff7f73a32137f52a4f59eb8c6910e1a1193ef2084d82c9d356319c934e1fdc96888d0be44f164cb03cc48e12cf2cb060b0a25a9e54b91e06353967ab779355891c3dc4d5630fd838d8540f72d9e2e0a637784e68821893b91e26c441476473e3c5608e067d75ecc04043e73b800a7dec75044d97c73f0e933ce1b83430b4a851104e11e1a6b2069e4a1c1a262103ca332bca7b0e252e9c66c4dfdf2ae04954229363bea1f88c183b70ecc34a2b2302d3ba0bb9a111c06ec5a2dca278802217fb0855a3ec8070b1176240771efdec29d0b4880d4371392a170cdf200faa9804599f96c90c7dc90260072255633517ff0fb5095a771c7c1dc51dc867956f830a24485d39f37050231e5fcb01e0449c1a2c49b1e4c41481a94a700c177649de02bde910e27fa12161399dfc84bcac462f9142f5b20ac5b29a50cfa442a04ba756843f75e50becbe095baebe4b075a1e2dedb473f07352a268f32e322013f4ac1caec9e9796843fbf014747798d3180c661dd459b583abc0c72ffa2403f583034288187c83ee4262581cfb45a1e6eff1c18333dc76a1b123518cfc9219879c90dc6413baf3b142cd965ecc06d11508dbb941cdb956c18dc67141a85ae572d5e9e7e78289497fb28733aa74b38115f72453178729f537c645adc677481290f448b568a5e7734bc7e30ed2fdb19473908e08ef89f0e4f7324e7f1c9dbb86166edac1bf0225e2ce3801a1ff61ed21c025793a38f267ec88b38328e908ff60cdcb51542c8d424ef440efdbd7eab13d3dd9c8ee930882250051dc5fdeeb70b2ac9eb2ef950bd21cbd697f544aa562c5bdc5e1dba3a89c20da006ab3577c6090257b5ab837564a2eb0faf6063c6d3c8dc238054fabd9e346ee26029deb5232d786cbcb997eb9f237288aab003a534f990912bad043603937329654630adb6c17aa52727e42b9e776e716128f077f3333990953b6d51d344adff581943dceb93a3455d0b577294bc41bec01d431489a681f505c165eef26738811023a4f2a564dd7112fdff8d491e168d15e8f3501af80b5d1e19542ba325cbacb755d2b8af9717eca17680e11b6e5bbbc04bd11a8ab82dda34442adbcf5f4268d1d0adccebda03c2d016e87eb329efce80ba8b5c80addcc018a646550acf33944ce4a8c0a3a99038ccccaa050f73980bb598976e5920d47792da8ba2a7cd5e94a0c0a583de184e8f67ebe25b5d8c4c9c1daa61cc4dd4a2529296f5dcf99226e21b98ab904fe9253dc4fe610150284f374145d57f6d9334f104b7a92c2783915f6d230b1f5a9a1bed31536ed668cea09d414b6979e37ad5864ea0e712b725889622f2d616fe61611e03ea358e44e46af0981ccf3b25a462220d52f354dedcecd5d3f03a2169f892820944e343bb2c9455ae24665a05401e39b6f7867f7a178a544c27a1c51888c447f7710021309b1bfd87fcac3a9ce0babc7d84fde08063f1a8fec58de1666fe375287476adf88e8d03a83309f524de2674618c0ed83842607ac8ddd1bdc5326ee942db97e00be6c4d95042884d9363ab6d3128274de8e879d587779b72e62bb96127844eaa1f1eabfd65292cdf32cd2ab58d76b040ed1b39d738a4f154fdd0ff34a2dc6a1cc05a078814b075386993addf53cb2284628838aead645c15605ada73443d9b002004d930980570187ca6d7f22dcdac215541e626cb6888e985c4e0487d8e2286a221a3dba8987177bbb57b52163203ce118a1ba0a546844fa000b36aace6391cc654bbc9427b45ab9a484d59b48a9a16ceb9f3a1f81479393486371a2e6703064575dce91a832a90fdd323954a60820eca2fa9b24497b94651915cdc36438809cec30630136b7514f7169a381f181c4f93c2dd854806273e69b96b74da636c1af04d7539f3d9206487aba6d63eb9d8ae9f70d8499cba1750f5d4e032e3b8593eb412a36e382715c64f066c874f6970150148bf9182abd3ad5ae846b1ed687ccda5cd9b96800ab09087052ed6927c1c444a5fbf287ace9521cf27cd561892629188c58425f26258a2ef57351e5cb1955a56500e640e0e2c6df48a5dcd24d071482bef17d1899fd9f5630b3c036568aec8d0f6169bab3b695ee320130083f9f82d6ef2201de83da92fff4a66424813cdb2031f3da18ae33a7dae28d83102a9a3f3ee06c46f1d44f83b7824e2201297183c742391ef22a5b2de7472c4a7d4c6f47b809f68723112eea94036ea46fa763d8dcde494fc82f2e0606f80e583749591a2012c1d5a04f4b26d545a89ef91098c5cc8c3ca2dc80be25d28405725a46c9d1aca405028b1073ef6d2f94ce8a7368451c9490afecad731e617e682989c002f0d1d848f63340ee072ceb5767fb370596f4c182cf6a836d63757370a8320ee74cddd8ad0cc46927e8f9e64fa6c1c4587df416f96d9798aae74089c3ec5f0d5075c18c3763dd516627cfbc9b2e8df870996cc7a99d3e5631b9c90b64589ed12f1cae303f8d52ca09da7c26865a5a6f66fff17bd45245a315f5df46e7aea209535e5e30643bbf9388dd477456aa2a00ad4951520f4d115801f0be5e62670a9ae6fbece34b9f6cf672ee60ee0ead44152a26a3fae43e9f4588daa9010d97c7e7b0bf3c0551b55029443d6c9c00135f0d7830a266522780fa1cb1b79ae7ea0e8b14f0b3592de045824b857558e5cff771bfc9ed31ffa6b159fdee0964a6b7a534b6b0b159793b1d0c9a9c9c24bce3e66eb8cfc4bce036ecec3fa88b40706299a6698f4bcda375b51ad53854a0fa537ef266b37e9f2a718818cb075aa6d7703b5cbd5458bb027c58d54ef05f187c1799177ba2f7ad38c5de65bb4ab96a161f6e46dba55fa8d2908fdecb5a622ec76821400a23fd771735cee9dbae0df327f24846f426b84857d027f7b4ce3b6d9994f29466127cf1f4eb852f1509791d416975cc5576f68b2eb0813cc6cf025f77fca11b365f6688aee19c7e856055fa5202cd01dd05447bd22088f42d0d06e808588bd35394526e023e74e1eaea32b282610c7bf4fa4fde324a374b4cde461b7709ce3560abd8592aee09afd0d3fb4efb25bd9ed5a9e2a1fbf9fdba4bef0af6d5f74db0c0dad119684f9471bb57e5bc0df284472af5bffdb98623d08c45fb29d7b905ec28e353409cd8fbfc3c5e4fede3a8f2af098c073ffe6156539dd7c65fcf1e12c3410a7b69a5a24bb20af60b6c707b49b1d4bbb89c50eaa91c077ebf3c5b5db1ddfeb78d4e993807f1a34f62e6d9a8f2e9a5307703304f2787700504a8f61b467cafe2e9c80e10e9e351242c40da681931aa1736100cb7196ee7802ed58efcdb7dd41c76a54f01c2d94b38880324dd9686a0e087aa8efc647adfb53b21cbe24ea0a625ee140d4762277ba9f4affdadb938622f6a288f3206ed7b1c76ca34e9a1bd000a2dd53a424b96558974dd1eb75991e051dcccbfa83e81a22bc40a3bbd472c7f623d0d60b2bac20c48e9aa52720def41c406505c0cd064784d4ad74339ecb926ae4736ac33d5bb5c0b0bf833f0eb4feed4409b5793b879ac4f9da3938101215fc84739c4a78e81adb26dcd612959e08f19fa68928b55d36a715156f08e084733ce8c686fef5281e8d9f97fd146aa81a5a45aee9a72c426c479f4820db4dfb9a3122447dd75a4c7f69679991247902e80793237fb42853bad956f94c7ae5f2edb4638fd7b510c6b962026e3567eb26543b35f9789aaa5002ae5f311cb1a5798d42ce1f1e9d7a4d77da7705bcced0fb37af384891a470d2a63b2886cafd7d0930148e77e1200c207264232e931cc4935afe50e61bc5f8d38c09d1d85ef1994803de4517fd0601e40dfbf91030bc49e8fb818036d03ea29bd0135d20b90ca8d39077286dc7f90851a79b598cd5d5dc711f95496864ba1418173c3f0eb74a8cc7e130896e7b99b03f705f4ff8b4fdeb26c31f59806cdcc4f09d3084044554d1b052c0691e9ba0c6c1b4bfef820ce8d3f4e81411cf9d89e47575a8247302fde9bd864c628585df5918f07b270d202a938c58d1c4f70591d6887ed0c4b07916c66c71019e86dfd08831d08593892a41db5499d17345dde2f39aacf439213882ae02dbef297dc7fbb94ccda52a80ad4d5ddccf2dc73997545b6c39b1f29a105e5e10cccc06d5ff79954632ac034cc395db74b5271e0f1184209474cb4155c88a8d409082df84124cb5ce45af10656ef70b8cd49a67c5ce923ad14983ac3ab530a710638c66434738e03299f25be424011d4e2dfa94a71b63270f9bc0db460325e402953f1517ab84eb0ab628451eb0a474d4bd8d755298d670e14699611b4ae1454a0485728536c6ee46aae4bdc678e7c2f59e23fed3a6c86f87874045d571135e438fc35bbe4a12504ac96ed4309d64ddc2d021b80eca9b2c676bf9de37164d61ed2ff9ba205fb23d285d59ad5d0632b8e0c45942c17430e20559ffa7d8d69a9a5a46ab4506d0ac0147fb1e53431788e8dbbb44e9df60394c6e47c624a28ed0c1da21f97549357b16d4c998457170f0e82628b4f1733696143322f196f7d3f978825f3a0b14478e1c94de9cd0d961e82478223a705421a3a5d47ed49a0e8a57025e6c765bbd8d2cb193acd09492e6042cde10aaa1b6024e226123908891b69ac0f24205934c1bcac72d011103744640462dac81c4ab7404de9170d629d1edd2a95801a962c4d7934f10c127abcd8c21c91217ecf666a99f4f8b9bc421d4a8832618a7a1b503557f67add8e4edb6f8155d174ae0848c8800d4e411d847ab6b084f4b49daffeb5f9c7af769a887245ea40b55bb2e3be2c643771686fc5f6ca27f4a5af6b7a091f7890d36c0ac8761e8bc047864dd09cc59abf21c638f29ee78088d75de7979b759d3800363d57fd7a01a939974a912d71d2834f8c9ca82b942d0fca5d849fa3e9cf23c12611a355fa22ff3397a44a9e86b1ca6d5281d6a67f4a7bd706a7939c17cfa753910e99b730ea713ae976c5701ecabcf3323d01c0a6fc1e85e60fc82fcd4d9b4779eb4464e9f33914289d3dc5521d1f331025d7f3d1ab5f88c2ee2ec72b274583d01fa3dadbf73d4fcbd3beb3e38fa7b962748761c07d104a4a62ac9fb2442fb691d83ada38153f65164de908146378ac870ed904ab8aa0f6f6608293dea14f68a10288766f70accaaa3d66ad4ec19ff266b4427a240bca7d17b27e74f9bbd272930f9ac40aa9ddf0ad088fe16fc3f41196c10d4563c53991a27453b4aea9d1eeb37d52fe06ac2328e6382daf5c60610638b0032159d5caec79adf47e861cb439d60c8231cf0ea05edc48382dc62a836c49c24b34a285cc5783613501101f630d5b545d679918955cec7aa40cafccf208044306029cbf03bbeb2c9b7dfe2aa3102a9dde11859c45a5daea4f2c6cfc506b9e63319cb90c4c90c58de303071196b7d363f9bc82e6c4c5882bc661b472fce6c836c3cb6952192a3fe74aa3f0e516aa24655c579e052b9b45dc74da903df117e411ce32b2c94cfcfb11249990ba9e4312fd84f8e114ba6c184ac91ea88b692d09c01401802ced0c6b2718d83c95ca4f38fd4f00c08f8b8e30f019c2799df2b953995fd32a314d6ae03395ddbc732c60c7d66f428297e5d802dec21a26d4e9881016d34ab9b28ed0012e3302c10a9902f2d70d0e6b4ff4ff8beaace306931d093f5cad0cd0a1657a5331484e71fda0bf5d5287b0424f25187a7b0514ecdf6699ec5f85147475e4993eadf79ffb8016c9e1ef16362041c063dd373590d14caf8fb191410e62c23bc4b6cb04f3105d4c70858b2a41cfa0128b3c5899822cb79d047b1687834dd053a242d1687d2854f8e9273f8ced39e82d10d9c0d10399ff4d7aaa75d8f08a38c108a80731d31b792108ac21e09396d5dcf1f9606bff035113687fcbc695ba3d19110d3e9fe9307600126e0e0000e166ce053633df90058e0337d882c84ce184cfc8b9b1c6385556258e1de4031c653609f20949136ec5d639b1da4d100bb5c48d4f42b17be11bd3559aa1146c16cd2e160d42354eb84c150c1839708c646b064e06e04d085e3261e23c9fd105ac363000bc60441416a299970701609e3b541b6e5045b107b3619c4f496a725b6112e0cd5c4d6ea1fd55f9585981df823acf7939d974c98097d9608abefff5d29fe1c88519b20c652780b632683313624f1f36ef5575cdf6dab54cf6afa1b1301d5c0f8c0bc2196142b04c115748494c20d2c702d84c80d51c4560d0aa5f7b1bb10deba8833a06540f547582209eb3643c356a914661d811667cf2aef048b29ddb45a09a8eb2e6e12968b9bcf40d8bae67d89df437d41a0d063d912dafd639fb7c393fbb0bbcaf1720c09821c9316f36a36d0f0a663bb546dd98e51dd4ed65cbf240064737662d252742b994fcef1bac11060e9b1c290b8570915c623ffd5506cbf02b1e8671323ee0d7b0764d906442a240c7e6bbc147dde0c391e2147dc9cc9a916006d545daa04109458fd3e39803a85ef6ecb8b98982f7d3cd52cb34b0aafea94c562ce26e04b53006a7ad2f0c1937eb7d065eef0fcad34ff6ae80dce7c0e72cf471d69565fe5eebe158a1e95d8d6160abc4782328e5e9ca8438aaf43843dd70690b44f02e5bc894cecdcf8c4dcaffd72dc6287285aba75e03adccd9ccfea2782c302f64be619a09af731410f72614b85407f9bc9f1ac5728f8a38c8fa30bc1f33bc05476c1d4355e235f9b198760f0174120c32e400ea5a9bae1044194e79f42bc9dc6282d2e8e503f4afff1d222d027d2e80386c9521a4737d9f19d5857926cd8f45f99b84e3d5ac10883664f674bfd5d3bed864f302e2e503f3b038ae0974c2707c42fef15a8ac56aaef21b2cbcfa5658b2aef3ba27c27df53e9742cefbc741f42f3c644318201bae7540184792af7e95e87f6b27a94631543330ffb8cc2a062a366a7ade77c166490ae2e0206073933d7ec2a9dbf4e15be9e5a5a9ccab5d2c6cccfdc984f89970ed49577a9669247fde50920b31aaea972d25a7849b893cf16a0ef41b7c8977a2aa18e7588bb5242327db9008d12f5a2a593e14616c0a634fe6731741c04ace10c3754acdc06faa11d3a61381fcfdca365e41eaa37f516550589e91fb1fa34a7f591fc42270d1f85d3e69f297d5a76795436ecf6e9a8968ec686b575e703e3ea8fe10164f7bf587dc96c6f50a4a71efc3c9e070b0e98ef6a8c512edc3071ebe8d16fd89781ae45e010cf24eee2958dc61fa5c30699af775235f552f849676978bfbee5c752242596185527380f1cd40e18c5bef5e599aa335ee04d6c77ddaec1fdc1217c5c127374b3b69c139fa19b83c7998edb182dda062e757e5be1a2b6cb6d36b44968cf1dca232a3658fd299216342724067762365cff57e14bc4d6470e5cc75ec7a09fbaa49be4dd76f3f9626dd92b3755a2d11eae9089a8733630ab481a9e3d461943bbf1bcb5dc750292c1b5ec0f6113bfc9baa8d258a6c03bd29536f62691fa4a200ca6e24767e9dd9b1ad5aca15a251c57f7d615d0ebc2a8943d256095a28835d16ad3d6e60f26411beadd4ce208558abdd529f4c7ef29ac36f8e0726e5050ab329d6b041ee84db56cd83b9b95191aeaeb2a3592edf681721d5c45f001295e8a89e9446e78ddbe23f5f15bfbfdf1df1bf63dbeeb431c906279563457126b2a7481c6b7ba0fb4f8d8e30ebeb88e82f2b350d47f1bd243cb4bbe416b786ef6d193922cd16c5548f5b3b2d5acb3245019201f383d3047974cbc8f3160fa7e107f0cd0177ea67a79ffffd0e25e42138a03e0924702976104cca260c79f78c17a53800b2ca0c6603f2841649a411ceb6adabd228ea97622a2c3ad195cf9e8c029d218e3f3731bd741c018807db42b59a44885b40772b0488cfb0f3712803bec5f1afee58f6237aa9904c4abfdd09d24c22889d924754512b6e435b4ec22753ac1fbcbc8692001bbf386268436ba12afc57710584f4420e4dbc04a2716c5adf49a14a1dbe201107b737c88a07b91b0ceabdcdd53676d5104c3203a71eb93ba402e26a8764bb4bf069d957c795c62751614a91dd2003fc8f5b0af86174049e2867867c0ac114f1e40ade705abcdfc8e4e1458719d1e199c2f184527313cb0da23ec01afa53a2006f37ccaa3d50acfd8e8416aa705d49e058b2b82da0d7bcb3e0420c824d8136306e6b0301e501f00987c21c1b9173ab946e931638c9d56a794cc0b3351da7a604ef8d4b9bc3e8c2a1b004cbd60f58f72b0163e43b16a9b00e6eef7b3c3fd2b886ace554ee41ed11e31fb3816d1ab1a07165855057baaf5aa13f38d629f88b5d0901eca002e4d80357814a437357e0468924dae70ac5293bc734790a18c7910041f99a8efd39f673198574bed10744bfbc0ea5471f8c1efffb4556db3fb618d91d041eeb057f1d436456205315eb75469365dcfe1fdc22009c15d8515306c4fa61db008c9ffd70aebe56504c6c38c8414f00ff9a0084ae8f928824609b259beda0bad48d33b408adc1a10a51175919fbcbbe057ce4041c7be2c0bcaf9d772ae05b48523a962cb06070210d94a0b2822f3fb030e21a08226702a2870a9cc637f8c2b26660cb699dec04f55ae4b8814a27825f01dd3e8134d082f07371799664842184afea0442f00927eb038ad4018e760c4f0b746e19d21ef70a8400d8fc89230e151207de4e0c7d5b32fee2f775c3063238dc205b52c208a860d296bbcc2d67d03eab7e588b25f271c87e37a6bea86e05026acee08d694655c62f6c043209a868c632602271383ea3e6952b08c0ce28ec010f2d62ea4de050004451e460cd4c4121cc09caf28ecffb41d74ff0bd3ee48ea25d71748504112df0bc35a1d6e9d9382c069e63c60d88289e837638596f57fa22da3e7ce906fb85202efef24356e0ad964f6b0be5b2452678af4e6fea45d28b4f8e138c77d1f4321ede96b3bd0f21223a1520d7b74b1ac60c4d1cdde05d054e47f8e01d2e44d0e8ce86ae1bcc030af4d554eafca9cb325fb2af676aa3d125db7b4c5571daf742bc7f80be3b8ca1474324332a4db35cbf6ccc7bfef3a1a7c51a38bd02f494230ff4baf7a6693f9aedb5bd1ea6f80d9ce8a17b35f51b079bff1e76291297ac81bd95aa39a708940fd4ec86f2afbb97b4dcb4baecb008dfeabf9ca52f1b4dda758fe388ac68f6589f2b6dad34554db2b74860ec5526bed67b95dbdf3e8ff87a953c324a24efa7870cf3d73025020270207bf7c4be9bc8a09e3130473def0563ea4353304c5d4c3383458a0100fddca114f74e378fa06145f5faec7c772e9fb9c1e78cef7cfff22e844b02ae7457b07691fa49cd106e03b1b42956ffb91929e3d0f00f2e2dd6ed5db63974e18ae3cd459d9268d4e20bc9edfa95124920783bb1d06c5d35c8191e6d455ff0a3a90d309c7c25c9af449d5ba745fa10609621a9817393973bf4b4ea75958faa39eb0715c35a2a3de6d6976a82a841ef45afdc1f24b06a6003e0b3a7da9e5c1b87f054aa09efbad578037dbdfdd7d2133abe925be59f9e7fd683be7362ca46e37923f00bc8768110ad85c387c76ecebd8875e97ec47421e6093631d09ba734fecceb8af3614fe20eb778d06cf6bf4ec1bc1f02dd391ce80fa96cd7877c0f501bdccfe8487ebc87788acc1445bd3204323f871f3fe0a28f130fdce254200b3f1a36d71a1b6147143f4a430517688f82f7f4e40fbe7bd29f864964b3017ffed1bf2f69766afc7aa372dea1c021aacb624dc06b12227e0cf1600802573ffa4e113e27fc16569bce7616da9da64681e4acf896d45eab051c55cb3de88c2cb8e9d6282e5dee3fd25c88caf75eaaed1ffe75a7682d4b3558aad1a1520d7dea7ec1c1b879e099c0e5a185628abdc28035ff34867a855011efba09fe7ec1e080aa2ffd5d9f194a16552e7c57a9605076d50b79975130283755b4f25df301368536e93dd48669b2aa2e80a990952cf42a7ac1366c946a5bdd02671a495eda21a8dd1bd54c67042028a4ffdd5ec2e3a2d943d0cc8cf2cda0d608090898c939a828457a5ca01774cb12a1963c265f8777caa62b39042c8176de6d63ca2903c0b6982f45375a44f85fd942077aaa7564584259b29ace640b53609d67e0306e757699d01b30ddc2cbb6323427db79cd07c9dd2fa0ec56820e00d1012a2953ebaa1e751ddd44e378c2ce97cc6281162e64a8be58d6c59ff8bb73e862a6be3165103c5c1a845825b93f1921ab432ab021d3e095307f8b836ae77ad62e8d090134a48f2b3edb08f891c2c8ac3ce18492006d6e84cb725f1164b5827fd6caace9b0150f1462d25939f0e075439df17b71f53bb5036e0ff77547a3ac59f3da65ebfb673b8662e88a2722511fbcca8e191896f5804562b1b7e383952858b71ade6407b42ff952f9d7cc09411e84b1f2ab9a3c634cfd258366146ef8a883208307b6091aa6de65c7f5607b780093bb429429694e34ee6fb8bf64b1ab45274a1bd1b5a11615b20a4b3c175cdec3a376f4c04bdd7213b9ebfd14192fa8cdcbd7a3ea0d67c706d650558684fbc0284ad0d5566a75b2b315ade236f36c82709b561e59ffa63f6808137d157fa0ae4754ad479947fd47510a4972bbc5523b73c47b8f505d24eb84e77856cade1702aef08b9d115b99f1246d271f1a2abcfc6c0af38b51a7779c500d74353352c98e825e3c710b8c5ec26940e8ed90de734da7abe28fd5b132874c107198c9decee9626a57083a30d822218f9b781c3395761b903be931b19132748c4372b1ccdc487d56629fd775baa481a7aed10005d5b1f63a023854295e80dbeee46a99df02216fb6a22142622d363292953843f5c5eaca138205bd5a4654c37bac8865ba2584b4b79ecbcf456b6132120425d71650c2324532b982a988e5361c95e114dbf0a8897a312296fbdbd10762e466e0c8f45623356ee903c45420ba12d390ab8780f76c14b08c64839bdf1f9caea41756170bc82022834ffff51cb1fda1e00942a8dce1ecabfb7bfb4785795e5c05f4f1d1a9a144e404683d85653b758200b984a151aa9339324d48b5c3dd1588bab30e335e9cc0bddc6f27f226ec17aa8e9b92cf9ce5999b46ed016f40124f8ae8aef2b85f93ba8cccefb7b1e7742967abc134e5774fff2477b997b570d74571037b490ccdd4d1110ff28401731b2ffb680d28f80a0606ad8aee68c7d3c60ae79a015d5a1aae5df92c74f45211a1fc8070411e78df07ed0e9c27f4e98f9833df9d906d7f2f150391639cef8a3994f0e968096395d9f00e1a2f4f358bbe7ed22d657ea8fd9da9c5edf21440480b606840ded9be0b0d5a4db98dd9d650381c2f1147fffda3d51e13c124e4dae72d5b59c9f4456148e026157f4516f95dc1261488878fabfe755a65c644f11b78018bbbc429fe1a79d861051fe5aa38fd7fec7e653e1728cf6ce847b8643c770853f19741fca90de277315a9a23ea1843d6c44aba2b46d67de4fa5ec1b037fe37d59586305b1835ec0414f4f1c867778154831f8311806b2b0d29923e96a77d19284fbf5518976084b19f54ffde40508fc8a4ea41f27d6817defe93125e9d3035ad687f8f460b5b9dd0616885a4eb540f02792f93b2cf547646315633c8427b9b80401b807da220a671fe0aa22da59bac88d90a7e8a513c9f809e80c84338faeb66b52ea111be9daea01168c49af7fd67691055f1ab15c384d0104715430f32ba7ce080f5bfa05509a95d0328738b1dfd9dc6771515c19a3f4db04f9a24911081e722198753a510133a3c05ce5e30ba983ea7585905940c8202938bc0c6835127306b394f6fcf1e5836b1d9d6eba112badd6f08db63c7a706932098e312f4f200695bad3751011e8b5dfe0053fae8ff2d5c354f62ddae0bfe2158813dfbd4029c2f5fceb959824e2c7ab18f513e7f293a023c162119761e2cc1520075b2f7be552faaa70c1bd6318f3bd6cb6fa64224671ed6acdcb2e996661373b44f065350d0a2e56fea12bc6cfe326ccc1b64513f117fa47e0ca8c583eb25bac76dd47801cafa753f195dd99408ea4dc582564b228fc505ad6cadb22bd22fb5ad412163039aaafebbf07b00c8798034aa81159635892c737653b082b9d2a723dcd4b5260f0d43c41df65bef89c507b2fc3764eaae98e0bf6000cb36f503c8a584d84b7d8c42eff3d05d8331a3126846b390f198d249139448f86f07e50dba15ca7ea3a86622f4408d191cf0dc4f854fd1b52c50c5128c41ee071e37f714eddd1450a64ff8fc6988dbc3b848c4a8684d02b12d87e0d0d3185344e053c89f974a4694c47d54d76cc352d74f86502ff871974f3bbfc27cfc3aa303161ee9a84880953b275a7a759cb7ec9155ede82be28c3f182dd9cdbdf315969d52b6eeefa3a27336c255951e4ebf8556a04b4322eb431a3afc0ccd49508551c24d43a7e1f3895aa0d8e9d72c15da0f8103dfa1f9fb1bedf88d1bc1d7d3f34bcda9f41e26d44b864cc0c2895525f362cd7257d11aae8680d33f56cc98adc548b47bba82430f7d01bd0a50ad9bc9d586eee2ef3620f95f3f37d7e8cac4ccdc17f7e91486dd5018ad3f2257dc475594eb5e8dce5c5408195d052b4d92fae966fafd851e458143ba19bc4e5d9cd3ccd3fc89894b62d96e0de96b8000b760de82d7733c8bfa25f4f5ae0373cf9f8eb2fea7903be204931727066744d0f933e2b24a5e48c262367379d49000b65c968560233a851a4208bf2f89a2d7e11a37478f588c26a1072a446c2d7f46e6700aed9cb9a358505b60d88963dced832ef99dd989eb43cb4a5a69b00b49e02e00a618c63349140041a62acdea08c18c214f9dce10243d69850e5eacefeeca4e4f87396b6aac652b748d72064faa23c275d668c018a685b44e12637cc7f90c2ad8f3236c70ade26fc4310d4435d7514bc708e1e54757325d7d8aca953c0b6a7b2eac1e91152480bd3d3943dd95f636483302483fa22c4e691279907af25fcc833e1688731da7a85a8bcf2c7090a236b755cbb7085f446214e6b36c02d1b9a228769ec69b85f69f8a525e90a7f9b94aeb73d7834b2cf0f84fcc801078361d228138ac043d59e54c240c269d16584950f60a08ff46ccbb1b128cce20305d8a334d2a4a65b3e6d6e646a90c0d4c4abd7f5516f0c0f5fbd7caf1435063799d972904554fff0f5c7aa9ea8127fae8be4b3c112bd8a34ffb2547310d00466f706e10f1cc4b050260d320d1bda3f8124149a0a96243261a6cf78196aab0f7b08b536c16eb65ae7c7f97ada7c938aedd41a0d52b06224b348f505606e53179a1dd9bc540fecff4032f7d7102ec0fe345bcd7229611654587ed28f09bbb5dc032aa1526347af6eae3d9aeac9835213132ea3e3e71b86100aab66b817c7cf7b921560b354514aab3ebed138d8180fc004557a97be9015ac00ed49c3437f9019daef2e95cdc99133519b845ddaec5a02cc0d6e994ad5b33d50d393f0fe505808140852e8a6af9ebfd1db2d8f074ad29180305f87083f9e3fb77ededa663ae9531ce44074bea3e3bdf23d635a0102a5df6415caf4e1d780e3f2f2c0c1ff3494a1102458aa9c58979b554c3a71471f4d0d80c408468633d02c7f645716aa5d1959f1aaa51fbd377584f0daa34f2c6415bae4c2ed42a748b78f5ebc08a905a8a6ea5d1d7d791f236dd456cf52c8d30bd136435afa94df4689094ba1663622d6f737c1ac5202b315143175a7b26ba1dcdbb276246d10659255848206d10a3d87664fb557821a1515b368efe5b2263500d8895464677d7864e4d51b0d3a26821d214f94fb027aad69b1b35159600de727f7846f7a2ff3993d9386b56fa38a8cda76d909d45686216d8535e544bb8d3e6e9597d12ea42db5481b8b925e322359f1717dd83a2d6cebe47a94ad52e3ad9d322c69487e8b444020eb8f3a96e1daddef17b5ae478711141b3120c994371518ac72f9dd302e1395c5ee75b641eb05ec81b84e74d0829c202616050fe320d6f31d53b0fc9969912cc9c205a17fbb0c502e1245f91bfa91d0b0a1b0b042a2049240c6f0356f88fdf56efd83f4b32155d66943f92a8f5d1383a159f3ee1482232f1da96e83c77deec7e7947fa771f9596029c118dde3f9f76b3fe12ff52c5adca917cd59a9b95577e3e132750644803baa609ed0cc25122a20c14531d5cae26ff8c9c0b2a0772401563d5218725924e8b27a081814dc80bbc88a414d2546cd768fc937e857224e3b7d00fb22d82c788bd8998b8f79877c225ee130bcd6fd231fe95bdb48c883332a4284ae83483b2f83299de1780da1abcf41c8884d21667371b046eb4e98109b23eaf2715fbc2d206ff444fa664609340c28131627d622484d4f2824d9eb0534f63706043f1f03f66969121c524c269ee5c3f1970a86f61cec1e69d561c6add3182a252d333924c06ed692e22988e9adc9253e19f8ccc2ac2416c1f0fc947435083d20bb44f3572388405a1335403245a03249bf73b5419100278f563b92674a81462ee0251e942f60671bcf733733064733606070cd9b69ce6f35b785c480c341841251c33e2379a75c6e4fda1d91964c53fb1a1b68bddccee1f266e2c5394385d9c4baf082a281d304863410c3ef16cdcd45f20a6479df3f1bac6024e42a10316e1e58f14fdf56c274fb99fc20f0c1129d9a8670534cb271cadfc0fef4a7ee4eb1fe46e50ff4730050d689249336a46572156d09922a23b5fc30d2f1469d9dd9d33080455665b330d9a9f71bc7a7eb21bb191aa3f3eefd0537754dcde2d0ec4a33fdc75cbefedac2190d502db251bdcdc9b73dcbf9e76a54fe4cbfb707691c92bb2681fd5ef0c22899335eff3d41b0c0463f25dbd0faadfc31258de222b7d70570bc73bf828aee036cb2ac783ad29076daeabfe694ae8812aaa522db506ce3da6debb5b78ddcf357cb72ac488b47b517edb7acc80f8cce616d4c4c25b125e6a21ee741d2ade25fe7837e475a32669b30400c560c3f0cc412a78052f5f82d1d1eb1bdf5eda234ab55f26c7ec586f93c95154039e4eb248f0d8e3b72e1cf5ba208d01a4305c929d8b6b420a9a64542a39442cbb2990856e9e8b61669bf196eb528f9cb8ceb1a7d17021dd34eb15b9541e290609c44e436b99faa512b6cf606f6225e6ffab94db941818f03106f200d426ded1512a1d6b8d814337e8c636ed341e813e5507de6fb8e7508c9e2f8290de405734b3af784298853d9b07cbf098f32f153c70db2a14464c4854aadc45641c744f322d0a4d02bf608d7469fc88e0585acd1b3691f2887cc02840f8217016e9cc87bc205c113a689cbc641b8ce797c32153de0ec7ad75a0e89f251fbd415fcebf7e88a39166ed834e141c34dc861e06c3447484f8f51fbe67cf46a80a6e73a4301504aa7872ab32139d9536a9c1f8e0c584121b2e200f30ea6739813f008904035976f26bbad8af4e090258cdc7aefdf712b207ad71de30c07d127bdc8dd9cf713ef009834628a1c57d510209122f0e2f41199e01a6543e58d6416e8c49f768ffe8223ec834de81bfab71db97c01922025bcb7e1cd3fea60e752d25b4879cbbbe5a6dfa00e32adbc043da5c62a6c1e810f7072d7b42877a81e354b6b4bf13e65ecc804e507b41eacfce632feab55774216b9bdd40445eaf151c457a924e5449daa02640dcff2699c13bf9a96901c0c84c82e1224976475619999179a253f823a06ca6b8fe11f9445d4c995a7e82bede49db3422cbe2bf9c7e81154f07767b193a41908f079432d409f8ccfc964a49d9fda188de07244aa9627807332a6b99bce9e95f700553fbabb053a09f11ab3c1d073c6ae4f4b2da197e6a1754d0381bd9a5d4d4fe45b3d555d4012089aeb442fcf05b978c65f8aeddc6d82a879cc2cd24a7d5aa45742f635be976874fcfb62aa4ede08b7a27b75a3b1768bca69e8fcb1683fb083e069a48e369840199025b737408d365c45645e40f6bf8a3f39d09c758743ba5dc4916431758d7b468d451686402d9a81a6a602c18911732069ab8b2f22d0988bf0ba9a33f728cf3112abff76aea06e2ec4b744bed12d1e50b099583c89aa5941c38c4203a54ff10903cec4f18aa84884402f82cdb473283f91bc5e60f7bd319db11ffc74c4bd3e31b6149be4d12309420e967814f4fb3f5daab019a58ecf89244bbdc20b131c2468e7dfa2a33f7436eff65a8ca751bd3dad736ff04ad0e9fd8ca6dcce3d46c9ac185d7cf8cfb397c4888f043f2cc48260a190bf1e5a6d75ecf5b3f5a31e5b67a34fde1297a8ea7a3a9644d79b98ba856e2d9a9f3e9f62a1f144b022f995242a243cea676e0c1e20553c7af32bc847d0a4376811d688a8effd19f15deef6473dad972884460fab3a1454f4bc82305e80261fb92752baf4971dd19b49de6082e32602183902ad2975d63885a2a40010114a8c999fcc934724e7ec68117872c18c60e60d9e3a15911537a47b5520ea6a1915d0f2b73583ec805bbff55a38422c85d2c1f70951cb793b76412a8390f1478c98e24ee1861bbe9a48907143972a0a85f48e6ce0bb729f4647429869ff33003f649638e700988613419a95e5f48f4e553e8b811e79001c0bbc73c2d291beef22c48a3ba271c604d55a5874fc1b98ebc42f029c04f3d6b6a7223bd2a50bcbb470c6c7541f50c69de850413ba77a7fcd6cf539371277d38b4ef6374aac44e46658e3aca566394ff7e2733e6b6656cb025b71bd694d236a0516e7b3dc12dcde00696df3eca092fbbe3123b9747c93eb179d925bf536ae37c009f6e021281fb2303a168d2115686ee366004201ed70e2405af6d00ee2b0c1065118684297e24119130ae6df79671a71e5e101264114c407e157f3a7e30bfe2a89b4ae619ca3e10de20c843316111df289d508400d1d550fcaf2501da33bb43adce25c7154c4a843c582c29b0dbb9a863c35a94651acb822edd59b1f8bd09ed5778880374cf56999150e204ad46f7f4ee903d6f548dbe00177afbaacb8255664bfcf4c9d12148bbe14fd65070bfde24b1f1434facc9fae1593faccf316e5d3f75693fe51620a249db1f6e191ef0eef924980e94fecbc6a32f9f66f3cf510d66d8b0e531876799eda5d40eca97e9858e2637d258805de1e43b69f0ada8d46a29eccf0da07e517624705d085cc35da3a92d6d489d04af97e2d748793a19fead36dc40124763b8469520b36e9c6d8fd9186d24e6acc52bb791c25e8be971989ba84408437b0a2f0577fd27ecfdb38af4e67f9144e27e6f9aff7f9e282f0b5188014976934a655a1e2307b2edc3d81e74a8fcfe617279e6bb0a3e8526856270efbf2a781b0dd96e3a1d471bc4519c60109e5d216250dbf9905e7537eaf9acf8f71afa86535e08e511179f3ba0024e2305921d855d9295dd3df55ea384f678a55da3779a00d31d262434f2f4b682a33d0c319472dbf56e9abebfedcffb06233e689f9d0f014f0e885bb767a2b8536fb5d85a92b924e01c2cfca852212bd0bddb1ae3528b3c4175a02c590e484bbc8467e500cf6051a0bcbb315f0902cca3f4942a33e2a026a522234fbe3ca064d539d617da5ff1f1a59f15ea18a386159ea1d4668c93d58f45a4185b57ac191adea4ccd4f4378516276c84ecc59395461e0b740e6fb4325384a04a50f48fcd15dd1f69e0244851dba66db4120e14a3b3089281b13433f57abe60137e0c9fc6c52043f9bd76b90086aeb4dbe7b850b750b6bb53ba8e1e71a052b7f08da5b816b91d9122a9abbf2da561d5f3e6209f26915f60c1190af367478b2fe33735775bace397878f302c3742ace2dcee927901cb09d1123cb7372f419ba7970809ea25c6979607d37d402e64485843c47cbf5c952185f33be943d0701a9d7a0a1b3a665bf9570d3d4c7d372f5bc9443714dec33ecc847a1da94dd54bfb9ca4be2c1f195122d0cc042de68739e9fcfe2d045770800829006da2e1041b09f8fb11f577f10297a6bf55584f48dc777ce34a415d1d01f0e264499a0880634f5b1aee639208017038c4765b6a0da523c217d4a6b3bc59fb99818dc5d73f576583fe6fd6300af76371115c07fe007808732198eab5e66190cfcebb22340e64d1bcb555bb2ad0305a2e6f97535d1b7bc2149895044d2332714a09289a698849876ef651b181bd3a42b7b20c7a4c72fb65a8b933458822c85b141234d1f591489a4a7ab9e3c0b4312257ac29eec498ced58894ed8b4e11fabfd5339dfd9e952de5e7de42234654438f3a2830ae8a3029db266f50420b654a228e1c4bbf38fe863bc6d98402760eda3f949441387086947b15b05aecd7a24c33bf2d24e57e5db58bf89c1820ba54cd73919c28fa28246ce977178f818903f31c585e8490f09c483fcb962dd9c4c7203472f7664b1e6892e3b12b7ee06cc9bb18e0b53ad2ece96bbb9eab356cb3dfcf8ac35aed3b0dad5ade14a34c80c53218ccffb769bae236dd8d1199c7ec7511a493615f3e6b4d68f9aea112b5f97e437714dc555f03b084070c744a9b8316e3f2c1d5615de61a7f219559cc7fe17d58206ed80ea9b57340be35960c2c50b25d6ac1c35f579fb2b506c91a8acf130b7db23626b4c2a3ef959e7d691d5c9eba7de5ba65bf4f0cac19165365ea57e921e6ac30fb1fa381667f2d526a38667cdc94155b1f994fdc6662b2a4f3e11b1a4a4e256e819e3afa069824df70a003e161ea426e868b7f49fff155ef02531b13d39907bc000dbc72806374a8ee4e6838baeb39f4aeab34645e838cbef0189c5f97c6f68305b59f2dc7f4e126141ee36b9eee6da581df7a7f840b92b9c171c6e11747f8f2ec31799debd884c75856865c5ef7f75cfd9eb31ec7af0df66a1857eaea47f80973c025c4e456a0845bb004e87370bd76dc530b8de7dd85c862bccd7e730aa94ee87f5c825e93faf2b1d9a4e1dda35079a6b6a763748735cfa19057d94b664c46438d3c5899520d9c6d3e17734840724376ec7809e4270fe686803ea53b143789f9f21fe6aada26aaa3e136c23167a7027a04a9daafc6e7b62a1b07d2bc08d12781e5f83f6cda491f5aa31c23dba13f6273a97b6f780955dcc43d8dc6d23279c337d3562bd250d61b168969b1ecd1f2f90add949a96345c541bcdf1ed967a3b381dcbdfbc336d8dd35f14aed206300f5eb50e65be2a77c1c38b791e6e0839452ba0805231b5df19166df0b99e2e5f8ed5857429e433864ddb549f1725e9110ab1e0737a62ab476d153bf3174d3d2505f1567d2b5b0ea20dfa332893dec5881655ebe236b199de5ab4f412f92d192b0e352a4c211b0f23c2a17a8300c947fb2404fd65db5fd68173b43c99077bfe45bed7c7736b3943017a314369fe560322ec9210c1ee710fb3f8bc597b6819a64858b49f503174eb37065ee96a684ab58dcb7ce4562c80d2c20c78ec256431fa245c30981911ffeb78d659312172e73d17f4397c0a83167f1ee526cd5d12d2d48ffde9d94803956597a386eac8d66c4389797f7f93c53f5d9f4c7c71dc2693aba15d5b95d0ad4816e4304f1c6439b59cadca720fa365ca897bd73a4e133653d93332a110ca1d68b58dc98d26561b362c11dbcec605de270e6889f95b4efa159b8b1edf8982c2661eb11c77a2d1a0380a85fe761d053c8a894028374fe60094cd18a869d87f9903b81824596ef0f920871bb9e1a60c7ee860beb741a1d36b189dadc644bd0a0f95cde7c45e51023580f81e4245cbfc28b23968da0937696ba007e8cf7e404173e6882d027af461ce72092301dc90e71123dc5c70d24299de0cf7b26d3b38a36c6adf0a165f0653bea90f8ceb27e02a43cd541ca43371cf6308bc1b9d8bcc0b2f7889aabeaf138a610a6833a8245fdffdd656418d0327f5c322a3425b6a5c2e1fe1a8189e90e3f02ebf9a77f348b03a6235eef5443e8942df8d3f63ea33afc37d2784167613abea4fb1465e8aaab51f71c51d35cd726a5d5117784c314695aebccf967bd185747154ce9557b457969f490deca1a805117365c47f75a3e4cab87bd1b00064ce7c2d975f9768a545bf77691152c4aa4bb6bfee0eddd98e790d7ba913738e99726cf2f09b8495e3531cded6d96d5119f5da971579f4dda5102c27e563d174d0f12a098139f7c469a135f4b790f350c4036fb67e6224cdcccfb2e9ff1a41f939cc68dc4c0b24070c92a7b8c42a2ab216107c94e621a2c74d3059e3409403ca2c737acbb0d29fefc69c9ff99e06a12ad9888928e4a2a353855d4e171f0b3816973812edbc6f7cceb6ec2a63628dcb2409d5fc385c40e9e01dd1ba6b10935222e416665957baa754260ded401f2c0e11b69cd174799a2c5090358413fdc14ddc0bac60219001fa97322f5b1bbad5a7e1caa8220fec2b222bcf1aefd143e52ed8b353152322891fd153c8d8b6bc8d7e45e49dc89f0df7de23110fcd8b99b28f4edd1497b5d679c769f0fa8bd3b8cb92a035d6788d1dc8ff7f72454812fa6219192a4818b7420e2361e0caf4493aa2bc1b751847d818a08e3f59b29940cbba99a4e6fce60252c70bed88724dee30da6ebd9c4795076d17fc94e8f61a62d300867ef4a76cfe433c1087e66a4a1bbb81d1ad209b579c442db285c11a1e89c66604012f0f6e7e142b5942a5b40909b38805d1b3c762327012a89444cfd78000201753625c86f108f5d180218827ccc1e6bdd402fa96e80a32bfb2b720b85ddb168384d38b36bdb31044fc9119dda0482bf2a575878d8989e3f4a1dc93b693c754cc5b27e065bdca5deb7c254f83b21fcbe680f0e817bd9a800c7c150603f59acbf7aa5c76a3c7f0053cc7889868dc4aa5d54fa216067671fefc11fa04511ab513d65f2db00605248b974250806022f163d1e3bf385a80ed5d2c60a8f2814662a1300adf85ca39dfbba1771ab2b3e534fee7e51129b90cf92fce697219cb7e20a06371a09d1f64e21f54c2537a3c5a0f3ed5398429db3d1591f8c7a66a4a2502bf4d0702a24db41e9df2deeda38fc0101d5eb3654f75c474afab54e8296b60087598967c1bb8a0db4056163b4403ce6dfb68e721f6db933e606d9effba251e7d056513117031906aa79307857c029ccd87c719b32a80afe7c8e2ecf5e2f60a729f28e230cd75a377a641bacbc2221f397c9fb62b9632806e7e33db7a5e5e3ef7d96ba2b3980dca335ff4a50cf36b51c8c90ab8208ae8359d18a71e7bb190ea7fb40594252ffc1c2b1d6b86840725eeaef5da16ec0cc337888ec628e9bf8f1f5c5b381bf2a267c11bf6c634f1be8115b8d6be52ca1618e5906942fbb6a682e4171d849af3c973d414a26ea3d87c23999bb80619bed6c4d5a2906b80fbe8a41af1127b2034ca403e109b7453c73ab467fc7e472f2f6aed293c96f3f1b32fd713b298e060781d8b564541be9c5c79d1475835006174b448490bd65fd0fb1ae60d0ae4633d5cd17a4d0d44d5492394478b9bc9c9650cf4698cf795f64fd40f035d1b72d30762f245c1c8be85f76981758001a1b160a56a812d5df257a297b7e12d084440a8f111bdfbd081a1e320a2e3f0a9f099d032304f77f58d13991b8c6b8ff822977b20c66910606412b7c5d5e8978b2d5b75f7295524db7679b4331c5827f0f81692cb710e20c7f3e20e754b34118defe53fbea9c3a0a65134387bf3cc9810a6ac7b3b3b15f1c8e88e1d068cbcba076324d732c9f6ecfdedf19214f41f85a78039f63da2447e1a9e35a0d8cbd2819cb6ac6b46ad11fe87aeb2641e9814386dde74ee5667180c26371843b569c1103c13b119397a269318f1502761a5ae0c3fc89299a914d3faae9fc95c38e1a5b7ce9083a4fa5bffb963b2770b900e90d587096a9d33981b179291c9af15036b1f9d385c6c85980cf9580c7b898534d88c16ecf5ea245ca0587959c2fc791376a38abb575a8b9b05cc155ce4572d474d35e323942ed289403210f45396309878a57b54065877f3aaa59758924373b47ee929b0830ab75c6fd1fd855e3a4321afbce4b84d15e2f71f01ec0c1610b53b7b3460988a6d9534da8c385188d57c88973db4d5eb8e2007b00f53ca35ecf0ad19cf7bdad3b2aa68cd03fe58737a6cfd2c8b370a70e9d4b433953ad1040def61a9caf1367f02698c694b840df28e078a0a4f581886121f860fbef28995036edc9e4b9cb8ea3f83811f9c8ec5a28252cb80d7e3cced9c82389e410c36002ecf25842cc523a58f7d046c2092c63006d8205537e3aeda22ecf2f4c479226cadd47aadd4985ebcc11e1129845d53fa3023800b358ce38257275ab3c8095ad61f6aefd20ce441560804247c8a7d73591cb1412b22952a29bd18485a0058b9742f6feccfb86de074f1d19f498a16b65ed6cba8210787ca0b3a9201cf8de5541bd599a62d519a33c32c0f7fbf329578322c6ecbde3b92d1be8241e2146d691d29e970832189746f968ac3bd79ce43a5c5558b3a42a743f3127a329c90389fcfc22d60777210f3ab6be73ef8cdfc5ee4b8a90f026b4d2b462446ab5dcf9aa05e37f1e24b47aecb77b63541228f78115283a615d40c8ac4a9d51dcfb567945cb12bd9ce47d1a0e05781d9d351ce863065d12f7096ba11d5133a0f119f930d5f15ed14fbc152a24f5e9b10ec10a1165e3b747c7ff5de5c21603d24676c3f9ffed4048ebd002e5f5427f5e40912f5799587348ca28512a2e4ab012dc66d7ab9221a55a8aa12c977ede77e96f7c0a01aa21c0c9c937e13d8e4466adccc35b4525ff01ac17669a98e31cecf9df6bc825b68b86a27c922104f28c0cbf1a6fd312577ba7f27aa1e1ed80621cfae46ec385706a295bde402cdcb8c0c6247b6f81b1d4cf222908218cf8fa275b4ce29dce03e956052bd1b3a4ae1061095015079d2fbb5c8cbc3be96041e4b60a5a019c8d71a2402301e86d0f5c67190bbd013ea90d94dc4e297211be06015864ba75001be8cfbe78bdc2f73a12279798fd56f9ee918e2f3e65b8cf84208160cd3c113446f2a6894c5136dc033353e9a87b38fd160392cf724a5b591ce8818824415d6bc50b40643d2f61541ecdff9e62e46085683614d9849c3aa6b02ead05f8b7c001b409d1da3ca7954f1acb8281bf3f53f62e7e2ea324247941a97063a2588578ede81f46ce3f59e7e44ce42ee6dad846c8216d000ba5c0a711828bad9fd60ed399fd703c8e9f2f1cf7380807fa462187080b71658cd17c653b152c22cc1bda870e98d68996194894d0867fc7f57a9abcd496cd36b19fe0dd1c54300a55d5451d5b67ea969735de4fd6fc3f06ad07a307ece0074b0d80bcbfafb30a8656a9965ab4c2d8f911430b11472ee5ef1b3a2c053e48db3e82f1d4139aff10d56d5a8d46de6f3e960a806d7202375a272ee99114935c15bbf286a875a28eff62b3f3bec83b765d03e5c8d01eaf1853a380226b842dd18c453ee0720c9a70b1b53a681200b232bea0d2d4db5a1ffe3c65ab15200c8d6bd963422bca72f4541397575b8d61c291b2e4ea95c3784e75c663ecbc073720efd1e8556112c3a9ab2871c408d1df32ed653cd58411034800b897666ab7dc16846defaa9026eae1811785025a33f9d3b33b6b0181335194a82b99a6bc4dfbe0fa3bc6788df9cf8e9c7d1f8098d14c5f365ce355561bb4e0820aa3cd2d786cc44688d226a715456ddbf4e483a555b1683af231b32662d7a1061ad6ef1bd4a8e9024522d9534eb88ae5863afc33461eb6f0696a74762e4b8fb742536ea0a1e01d1ebdf94165c2547d8342d67bd8ca87191f7f071ea412153557fbf0580a723b420121e101b24cedfe97b6d897b9be8de8779c482538a8f4cb047b5fcca13aff715880e1211e7119d2457d3484440eaf0830b6f845363f5e63fe4abd50b301bd0bf746eec90ea03a36ae540b6cc5c125732c9b7daa7878a72ffb84113aa157cae408c9e9928600db33d91108e465e146488c95636715048b86a9155a5dc4328a990c6cadd4d01bd30427de3b4deaf3ae5f659689b5240209b61523210d0576b4362804a554ba98c9f31b39bdc19e56e8cf1611006df99f7edc9ca8e94c54c40e235710a42bc200249d377c3b183f596c60fc03ddbdae6bb4af1480eae36c59c0d11b3d6e5a8e5ae7506ccbb7f884eb6b1e72d84f9695e96d5b481a5d9a4991ea5976db9a926527121e96ad9afd23210350286a5b32cecb68870ff1b9d56a2acf6d8a71c610234ffae297d84125b182a4809f7c6ca9b00821d46ec0a2d6a59a1a805b9aaf57b72544f40d54cfaf36ab7d55d295bef11044015d675abcb831a4046d00d29e109405c01527528f0f5bc821b0722875e8664976d7deaee2ba2b58d6b70f8320895593a5673944e3fbd7e4040b5811df184e069928ff23e309d149381e5b25440902429a8ce5ea394eec643549fc0512a8477ba48df6d564af9ada1fea8155507ce1e45d30be966853cc2b0806c5a76ec92d7e710ba1c0b9f855a59cc094699788e2a747a0971d2ed9a321fc63a22ff5dd6c29bbe21901344665628c55001f998806dab99d9efa692bdd340de9e19c814f4577ae7745bf441344d92320a4dcf8494061470d25e1e26612336677018e4e439c870022214ab11d9e71a9b1491ac1d0b376f0e30218c7e48d497af6c62cf4e7722e56030c11d26b1ca51434e4fe8003cba95407ce1c6438a6b2c99cd33bfde34b2682b3d4c2f8e60dd11e6881b8414182ec2bc9bbd06e579158f0ffcafef3610ecf0d59d4ada78161b2d5fc99548d3a236436b2e38d47f21fe34dd9d240ac85a9ec54d1c4890ced77124d27ae3555cf47cd5dfb1f0a4b83984cfe51d53a56f2a6210620ac6f9c9923950f70bc4c5738d2e4e9767a37a91714d969ad66b7bcf52c9012f15dc602ca95798c59159cba69cd29b6a4232cabeafc8c87be24dd1f02842204cc1332b8afa3f9e09e6cd160704e1ca7d1332b890a2151a94387b675564c52bf662bd6119952be8150c8c4a245ccb22e6db18a05fa121b2b577a94c71b08d7d021a5e64d54438cefc5d2ac4867c10868d68d6d0a4cb48a43084a06f19fdcde7472a84d23abe8bcdd37980eeba6b9ec6a356949159187d4b2b9d8a874312b3b9983514787b102add531e6a640e8b8fd240484b80f3d1ccc95b649b6c2750f4a6397d33c59367685e5cd2530310aa9bbec18ecab748f7545c5ed8c746b34b0102780954347e5650c6c1bfc23e66d7d9f438c32d4903e8326b927d26088b1317c2e3c1aa6db9f1673bab5fd7fbc9d45425b9e413f24b886105edbd1d23ae511b45384614a5ee7710e7b784205456d861425a6382390a0f73fe10770c4f3cf23f8206b410e9639784e632d79fe439db98e46193784ff8ba338d434ced3382bbd790a85ea122dbb1dfc9d474a566b455f2be3fd6d2f9bc6d3d6432eb437accbb4db6dd83271f07828e0857b9fdc64eb88cdf2faccb7dc00be0a17353eb1b0bb6c0d7695e6037abdfca41b88004fd3ad06f7f07ee9c8a1b602c7d306d4e9cb8f75fbbc24c9da340f406ef9b1647524a88c356a14e78072535bcabca2006086b852c903032639bc6a285982625f0b36d3440798101c8d4c531be35db8e9311c43509c378999a52c6415d666c69ca58f6ad912ccf5d91a80a9dbd3c92988222965ae047f8982a412fa9f5aab07407419dd5d0d4fe961da0b013b9fd9f08eea991e4fca2edcca85d4f43bbdf6c3fdbd478cdc2e7f9f9f177569d536f94b7f36dcae2b9a7e59164259bb533f59cc22f97604e83cc41da5c4ec16e15cc6940177352f08fb5345e4da6ac2e2f695bbe694587aed814e117d3737154e07f59bbae3080afc2ff6beac6988862d3700b57b5bce295d8d46816cda8808c4855c1da25c99a205d0a9cc344b69165b1fa50c2d32803cffb399f0b0e94806dedc32864bf1b10178c014815f553a6be84a2953e57de36fbdd9989fec704ec9c0895c4472f90b501d35e95092af866019481205e60e4cddfb82880e5448b9afe51e9d2dd4099be398fb7fda61ddae8610542c683fb0d3750e97e37c055e629b47e4d4e1f268a5700f133d81aec8acd014280bada48a6371d198b3a5920a1b5b2b88ebdb9d4e0f1b972045c21d34e1b542a1923c0a2102d3321ecafee4494e0960c4d798602ae3af5ed1c681fb8e85d4a26fb8119acf774214e61517eabc537fbec3ddf5613264e5ea3f8413ba8d24f8482b94c0109c662e50f42da86da41a2ac34e38bb7991bd6b0038180802e4f9b709feab5b9c444d09473d458e5ac30a6f9bb0cc4b00c24d32f79910ab8e9b36826b73102aa83a331f7d1c0ca8433602ebf935c217dfd29aca8f8e9ef1e3e9f5acf9bc7fa003cb1fe4548b54ace0a4b619b2c3f207c7428ab1803ca56613098d859c885a93dbb01d7a222607e27e71a15a34a7d1d1efe0655b818f044ddd4ec4c91ab49ab18d58a7970021f0c92e99c3a95705a797a99a8b536baa6f6d31d2a74c4c3db08217a00bf8026555a6f869285d79d8a7f8db9a67db608dc994a3d21e07bb7b333c2f423a5b31471a39506bc823b6310441d9f6448c9c7c8aae1bc391fff94419da3e5a6b4c5edd87df9c3fa25b8d4a7da86c44c2406099bbe6e80789c942450d325a5c147f1961ca74b7e688be7ff322616cf4706a9149c9fa114dc80d704df620c8a9b4ce483085fdf63d3154c533b645729c3783c6f4a95537a230c492068e61091298b3cc70e90431e26b516ac8ae634910e1c17f9ee734165f88f366a0552890a246f7abefbbe6438d93b8896be71db18e964ae0f49e9adfbc1e1b987f212148ee5e2ea746909d8f857a17580237b41957ddb2c0036b0db4741cebe30e42b5983f4ffb452ffa9797b00d55fd33f52b3100a274c909c30c60c0907a2ae864b145ca41031eed91fe779141baf7d871b6bf351d82c415f00c7c848f937b98eef20768782670cc962bc4f51bea2c23e3539c6377464acd12eeb6ebbc623713a3b4a22cdaf4c312dc9b3c90d4c1603d54f738e6f889b445d8001709ab1db64c24f057a4350e9de7772d559638ce3456a3852f8bd5f94d6cef422c1f2c40c6892cddff12edbd983d4475fa59bae4dc9b9b1ab9d6b6c3fed4046559700c194b81bd7ddfbb16e7ca2b620a2541c1a7e946a6b6c86036862804e4596db4e4fa6619def02764163512278680fbf40bd6f44485f771cac100d379773d58d2a4d2f21f2eafbd306f26ad52ef2a8abc0ba39fbb9b985f4d9415ce937181466a0a24070956e562bb9d00549fff52aeaa4f4c6cab434d017588775cd0737b551d7b7979ee32c12361a7512a60083907a5e6b97f061a2920a210a89b35750fcbe355fd58d7211e986633101849b9ebf53912cab3d50a61069fd3f58aa08d9f9c5ed69e3ba31563316d25d7ee6c62b7b629cd0fcac976e9bb0dcef4f69eda5992f81ecc1d90af0b5189bb99072377c2239560b8a9df3ac9f9b36f86fd2dc9e7c7b2f2ba82b671d29f11f15777b30544fadb41b1620f2787975a02f0e64d208d2bd3f9e54a00dcff19ba6fd77963227c654c7e358042a7ab72c24c1db6842ab300091f3cd7b37611b94d732b2bca6703fa096d23540b5b1a80f80cf3a2af3b8530e85e388093464a98c3e30fccd48a5fec468d683dea74504f645446f0ce029575e879d855acc68cba782af074fd4ea41169c71cc488d861d31ff20918374900346222eb083da3251ba1ae7cac6d26ca1fdb3d0ad3595f4acb0679855f6535f8d0d954e898eaed73f65b62367857daa729c5d315f223cc7502bc90fd1ef70f73df55cdc04875b5f8e387f2c1efa73f090e4320f31d8fb62833c5a052b2405ae5886314b98d6330309c621862634a6879816a73d67302b6a1a57f10c2f3e627b5f1790dc3f8b9f4025aeb03fdc30744dfdc8c979985b3a6096abd32cde191087125e03b9878f431e0be8e353a1804bbeebaa6723c9832fd53ae5ae10cecf0356a1c8d0ab70e720a280e69bbdfae01b3c7cea347ae04cafbac9e9b3cd707c8c099db3526c06803063b427eb46e4116df13d33c5e5b7df524dd1cc5bba20036f02bae5968a1d00223444030a4c06795c308c4a4e07ebde33e77b6cb6e745b30d681b967e9329debee0e531201ed67bba102646712e7e606ab87e4441a758046cea5487196e5741601cfe3abe995ee48e7f0323a400aabed1d0da27f5fa5fe013c84b437bef2de5de524a99648107790758079c16a78b2a85b0f3c8e5cf38ca2f7f06da5b083b77dbb87da305b88dcbc8a8ac0a5917f7e5df3e201db41657dbebffbe22a128d15db509dd44af71dfe2083df76a5b6de30664e7f56bedb5cd3dfe4dd4e2aa4389a8d7dfbdd6bf3312d14f645656b9fdff1117f7ab1cb0a4b24e54517295d359c1c5aa11f7b54bfdc27dad155685dcc57d0ed8c9ca70dffda4a437e6ef5125395ddf5330ff97c7215403221ceead444037f7f641b8f17762a9f735da9bce155815a2cfbd0c532028a80c51c392132f5078808b65220e15158cac0eb54aeb1b870c93710a0e51462459776b3dccca00be6bb50fde71eeaa268a289568ca2043e9044c7630aa72c3ab7a400a6a0b0bb3872311966a40410a3166ec127084c8709ac4c0e9616b72ffde264b708a6e1370cf599631683a24db15b20fa626094e042e2099b1d6daad5a6badb5731583765d7d5a6badfbd0a696035f83b6f427cec974f1fbad368b4319e816ad2fede27764cb0798810e43ab83e723c4ee2da7d4bed16f92506a69a594d25aeba6744b736da873debb8f6cee63d4086142d209a6086302154bdb96ac80e3c25695d4eee33d6729a4a0046f06b950a7547fc8fa4cb3b9c0dee5d68bb6e2eec6070469427f34a7fc6e361d757e90afd91e382be34a0a5338144ba8084848418924610ab25d6a319ef7939294d2df58bb8f783badd537a5d4d234de0c0ab95615f10cb5487e145a47657150b9f8a8ac2898fc69d3a10a0524f404184e609182e504242758151698105984329e0866a0c061db4184378345c90e3fc867cfd995dad67bceaed076f9addbe4cd2077771daba78d49c5785f46e57cb9daa8ffc97914ea518f42bda638b647a13e9c17d8478d2c3aa0bbf2c7fb9cf113cb0af6b8f77239f851a811bf833be8bfcec9f970dac8c911eb8362f7d543594a5a1232c7b536c77dfe8d02ad9cb9f74422211cc0078feda3e7a1bca172d2bcd74151169871460fbcf780fbcd1bcb567671bb973a3cfe39cf23aa763e14e83df765ab14c29c88f23c07776c5fb6bccf62d9da1985aae1799e8ee7fdac42a9f7428a73c0ef537af4b1cccfe5926c096d9abbce3fbbe7ef44cf9efd3f686d6fed2ebb73b873efbed6aecb9ca69e145df7572cf5f61e7ff77df5ca233beba0ddb443ecee9ede21768805a1fe160b945f1ed9de885fecaed3e9c65201a58f7d7f47cc93e59f12bd8ca78dd6f6cfdb7bd4c7b2b5bbf7442c96be87f6edf0f85d52dcf7eaec1bdebf5fe78bed63a980dd3d1ecb17bb0c3bdf41b737e269c3bfe5e9d04a74d93a7bceb064b1f9f1db2be2cf6287e9d74477ffc1d0eebec478d30f81288e0f8676ee511ed95dfe8ea81b4bdf2b6f042102dc1fd9734f8ae37ee7fd043b2f7fedf2571022b0d2c037f7aded818fdfc6dbe650acc59b41d7ea11989a78282929d19413b4ee50a95695c4de9d1aee96f2b2713470b809e71d1472973aa1f376da789f0a4a8de15ad55dea91ecd35a6bad8558d1a5cea1b5d69a47cd51a291e8d1aed11aad512154d786425dd34f18292d618b794c25944e3da1b98d1b794c24362567d2e1b123839214159817dcafafb5d6dcf64c2237ea0a88d8b4b6422f09b1bf94a209d5e05dc0021e67d3771e4f56a1eef36fba89498f2e94e8efc1e71e7feec6559d5f470ede1357f37356b31b577304d2fd4804cc1c8178d77bfcf9c16f9c235e79231ea70e71c5adca32a2f46ef14e4812d3d528436b0d7df1f07ff93fd1878e203527a774070999a6e1121065f99626d910c9a3d5c444294d559175a94ee5a42555268fd28406793c86643e688e011d7f4c0bea73a38e334c581d4ce872d264474d827ca1d168349a75ef8046a3d160f8da2062f48deb94db6a8e011d7fbc0478db797344db82bfd0b8cd5ad5082dcaf2a12f5e130a4aa275afa3e6ea893e74705059ee44e3acdd39a20c1502a29ee45bba7c411ae2369ad39ce65b10ee3dc80c528530a69c2b15d3e5c442640d12547a6cca7854a19a0f893e5e95cea882873a1fb0d3940db496506daacb4d95b99baacac6a9d1e5d090fa55001d0cd19a001c03cbd1cd2fde412229cbbfa85abaf9cd2938960e0d6dcc6d37af5cf0b056edd85a6bb5b539ebcf596da57a1363551fa86a65532b1b7777fbc6f278a0aa950ab55aadbb6d7776956c7a7baaa93d675962b14dc986440f499cc95e9c6c4f9b52957befbd4b565051955c41432ec10d97b3e72ccb122c66294e94ba74c512ccea50abb4ae5966594698a5304496a5166dbd211363062b495274dd73666506194cac1c69d174cf99953056b47c332b55665644d8df9eb32a5434616940228592cb4847820c461449153ac45c46e69922a6334ad018d1118aaa78b9280e3218417379db5745fa324a62e48a4384acc8e5e1af8a5e53f2a6e69a66a0bc70e49aa1612a7279de57c5a12e5d602eeffb2a1123b336c399970bcc2a83fbfef78f6c22463e22a4bc5c608c7c415489b9c05491087d45b1c2e4226284f322cb4d60ae490990f355b1e55290400a25971114938ba404407d55f41f8c2863e49a52e0f08393cbd349d1265f684c2e3752692da2d29f9545691554da747111f13756b481e332429b2081ebfaa82ce79264cb152e231e1043dbd048e4c2c0260531b88818018f704d4a00235b9926ae23faf572557105a4522a684f4cae3af2c0d92908168ea8d72cad793ffc0961387fb8ede2546a47ab5cf5f1f418d90955433c61cf900ff5f1ab52a97878787a7a7a7c7cc8300c7f7e7e58b0f0e6d461dcddddbda7c72728fcf9f1f171afeed5abbb7f2b5fcdfaf3e3eeeed5ddddab7b75afeeeeeeeeee5eddbdba7b75777777afeed5bdba577777afeed5bdba57f7ea5edd3f16fad361dc5bad5640aa162e5c00bd78f17a6f8aa238864463059ffbd00d5518a4220ad23060c4881123045285402a55a8dd9d060d1a34aead9486cf1f202090a885aa45a802c2d385d3161f510b17ef22c8d2f0c58b202272877beeeeeea5915dc7175f75afeed5ff5f14c571ac00dce1a001e80763c6a0313cc6ada0023003bb71108c1ad467850123460c13741d65c890419224eb63b166cca001127d90bf0d90c823d23a8cc78821838824594d44feac1b435313a9767cee2e43860c70877b24a88106f60542f0489205ee98f139050dc07aaf5e4a396c67ad7a33543342151d67801af82e8f78343e1d46d7a861e3d361b407000058f059e0b5565b1ed1416b7c356cd898b5d6fadd7bef68810ab444d7b1fc2cb0a0d50a400004f0b93b6500166f660e7fafa7503771b890677f8229b29543984f341fde5459f47ba2f0d74b6cc0e7a0748608c1ba298bfe8092f43bf0b40e4a27b5a3fa3014150f17180c96278b3a9329e44dee4293afd0e42838acc98f9a7a1e1084e6c3000e9aa8177ede6b308339f3260e03e283a99bacdc8180f766479f362e3562594c1e3e9f0f48843f04ba3836ae088802a9a031ac49112c870687866cfe0949f029d96afd7879ebfce416b4d431720702721890e7e2d36174e9b04d5f7c1fc5e10e03896aeac54e8a851a6db1c65edb1eea032a17a4d8710383f765091e304ca0dc69fbb73d136cefadf758079dc55830fbc2011833177c8863a685daaeb5ed3997466b6f81661b102bc10f3398d1326506850d67542d8011807d6dad6a5b6badfdbcf4b0b7b75b0b5af63685fdba98f12245972b33b60d2a427f1097372c8badb5d642e00a9b1fc8a0a04413319765b32d0d4cb605b7b5d65a1e2ab6657078c2d21d2c1026b3ade58264db143e0a13ac5b4f5b1888bb1ca7a5cc931f2d4c2b2d67aa84492cb4b489f93cfdac80e449cf9657b80294253c1a2835f9ac80258a2a4bad6705189cec24f18c8192d2f2a4224267470450b42a5401565973b6c2d3955814a31e578e909e662724151183cdb68c800ac7719c15d9374978928d9a8c683a0a941e28247179d223cbd1079cf4b0525466498f2ab42094f44821294d093db6182561420f2cb4190b5158e9b102d3cc032454e9a1a5287c41abc228ed527f8c1b748bb6ae93302a5d62c0f4cf9e332a60643ce99e3d6754ccb06054d4e87f2209a8c3708a538f2935fbafa9b899f23df941a414a51e5298286b4609fa1b018906f79cc59eecf2ff63574cc83ad4aab047512c07bde365c60934169344e33232aed0dc120d11f477264691d64acc2881b652b068d076cf59ec0d0d2ab11390446164333054d4b0e2031812642976d0b7948ef5edb5e38a7a083cfa57a4b4eead1ce9d7bab2550b92962d974b7ed15a90c8bea5f6eface307dfdefeaa7c071bceecb2b563fe1ded9ca356fd4e52b2cb9615cb1a45cf2abc2c6b183da8bf71c97fb9e0af2217d8afa8fbaa66289a7ab922dbbe46cbf1533ceaa840dba8af0dda69fb07e5f83a6b503a526ecf1e7c28da75fc1e47d125de5bbc567d774cb75b3b3e25e78341344d8ee20ff4898b34321ab52719ada98b15b4bb01dccb297b3bd60d1b59a35aa62a55d9b441ff0160740794a4a2149a8cae5f6270532af49e6002aecb7e1551dbc50aba3ed2a6235cd7e746d7b1ac62362d67354252b3983a2255a34b0be26a9a5fface1914a4edbbd47b622d82d1f769e6fe0eb97b08e5fe7e1db978701f73f17e13571b16b9747fc5cde954d11757746cdda0acfa198abea3f883067b80e01e95687f6a995021216be7914db4da7e22816117fefc9c08c32e0e7f16930cb9b8bbda461fdccf0d44bb70b9fd2a836e6fa305501b8b738a46b4bf6f969d214b0b33a8acb2cd3daed3fb184a5c6d5a4727f53535a6bec8ac20155d525965794f521cde7bdeac792c3fe86077bf4d173dd8368f8ea56ff781c49f925ee78d1d45a1b4fe3a16015344f54f3425b7c75f71fd0d2afd6a77c6983e904a47226030ad78abb58ea8ed270af5aa71857fe7552b20faf10864e755757b4fa5bf52fa459efa984c4ab45e478b7efd22740c2264d2666d7374e5fddc65def26800bab3d7a2c4609bfbec5b6d0aea8d1ae0711b29121f4850afc1efc421746fafc5557efdd3851257795cfda88ffa0df4d3478df48ba86812c87d8e48912829345ddcf66da8df60e77f679c95f58d1ba08ae8df54e26ad33c4f44f528a1e9caafebeac77dd42fc03ecfeba0358f3c63113dae7ed457fd4a35aeb6a7f4f5d3d7aa5f6d23eaf5afc447893b44c00051bd1e8910019380e94252040c109ed73e5f84877bfde1ab463faa2cee9fe7555ffa9112e1e845af373ea31efd6f8c3b5f448f2efbd28d94e019551c87f281a24828c93d4adc3eab258a46a2421388990a6b36f7f3a94c61082ecf8ccaecb27ed9dc6fff65af29c198ae3421e18c36f72ba751927beead134fec922e39b14b8a4604b235bba46b36d7c42e699bcd716d7e3a5192e3e85115a2322aa301ac292481356ad4a041b3b4942307498ae2cf8f8e4ecebb3651b2be57b10826b7a8b188116ac4930bcc7d9e31b210f5f55fe7f5a833fea847b2b2eadb2094bcf2c54214bc2ad3022bd22b94b4f6099daf104ab5a314d54a631b17c58a2e6952514c6f493c288eaac63e07f382fcf6194071786f3ffb0a98187c6fed27828077fe3eca1431d91215eab9625fe9cbb67eb4ad97d93607fc666390b66d6d4b8bbc310a25adee9cf407d3c6486563280ed302fb58a462a60dfb3489929ead688f8d3ea6d1db584e37442440c59a2362bf0405169c5ca8c713d079fb7a5ec0bd5d0179d44864b5414fd24b8f458cd027925ea8df19573bf8f572a5c6490980f5d7d4eb4f8d9f7ad4a7c62761db79c5b6938a6d8b448f4d1bd60a5dd2188d6d238dd531a6472221bc5e2e8d1a894840e9ebebe5d2634fd2ebf5727914ec803783c017a818b9ea1f71856f74fd20eb33463086852663a490418c511263f6449ec9e10972891c9a72600aeb9a5aaf67d4bd2426c98e729abb2426c9ae6e1a773767eec720d22fbe24263bbf2426c9eeba777edd2f8949aeb31f750ca85be0bac6fdf246d0b3f6c67dfe1af7c6102b070d1af7ea7b6fd4a8d1ba31c4dafe9406ae5af537b4bb6edbb75ddfdbdc1bf723508c8d7b8da449920b8a111463cb01b7a018338ef03c4a291d29c514079d94529fb5d66ae9acb5d64a29a553b4d6d25a6bad94529aad78d85acedacd5a6b6dadd6564c71688a81b51587b556bfd65a7b496b2dbec1db2e75ce568a73cf58abae14d56590a8d2c7b456d4fb9cf306aa06fd26a5d6526b29ad1445524aa9a6d4da9be7eb18dce1b8c3718763afbd1b9c6b3738ee70e824b79fdbfb06b67de72ab7d56b647b1b277beddde05cbbc1b1d7ed7577270be78b3783ca5a349d668a2f77b76ddb360e5f8e26f99005ee84dcc959f4e79eef50388efa255d12b2d0a95dbad3c59f76af7b3e750caee52cb89f1d03ee7a1b77fa28491fc438dbcf74733a42a716751aa24eee64371da12c74faeea7efbb7dcffc29fbbee918383939dd29a84a958b76d80ce99625f56b991b1a74dcd480044de726072414103ee47ce3061876fe9c6f78da59cc6c671c9eec8c030876fe560e5e86f4dc81e382366739ae862336670396cdd9a0c4e666376ca9810a8ebc51f30cf7c3be4928ec7b3f6c61df59d2153430792fc4c84c21d3b219b57e20cdae3448997de0f5b29d3d53c133d46070c0aa66681234c311a784b540481c60010509e90ad212dbb2b132c8b6d5019b5073c0a187292430d44ba749939cbfaf634cc0129a5031acf03169ca89e18b134f098cc106269d2a6452f4cd4ac830981743104b7009455d0c4d4eb825b21c83131dd8f2f8c304d92c8627273f9c182529e18712a6274b7e3429aa5204f362c20f136a33193eb0e4078c89862f84474d1586155186d8fa67519678c2e950ab42a638af598d8928706a90d2c40629566238d1a83d67525c8891468a0d240b5278505531d3ba33cfb7879a73ce7b875c107cd3af7f64eba074ee0952588ba3dbddb62be309adb3e70c863755681f353386d03c3ccc4881fe6ea061a4c13036c070820a309040bed1e0130d3ae584084767bc1cf900e648461e25bda0b4cb6f591454c7b9f33e300744695027b5a38259dae313feb05801b570e1e2c58b6305412f60c49041b266d0a86103002ffcf9eb59a4d37c727ad51cf6e44a5e3accab05ad00086000376edc20000ea19616d779a13e2f7f1d06bd5287404f7a2890e8e6b80e41206d732caaea8fe2708da4718a32a13f4a5677b7d65a6badb5d65a6bb3b515d7ca430577ef56ebc5b5561e2ab4bfb5d6da5ab3b5d65a8bc9b7d65e5aa9b5d65a7b456badb5d65a6b3d6bedb7b364684fafcb5e9775a8ebfa4368fffb41d0aef5a2eabdf782f7de7befe675f7d68c3bee5e226cadde7be79c2048543f08c869bdb7de5a6bad76c35d9e5d9e9823efbd97db26b74d8a290e71daa8b372b7dedfeebd3af587ca9c73cea04aaf7fd0aedb7b76ab7bb31f04590fdf6badddbe8fdb3008125dfbd9fba6cd41699dd40eea9b14476a47c5d393da51599e7b6f8f4f55f1f4f46c9e9d3d3fb5afcfadd5faf60189eefb7cb527fc6ab5f75a8b83c577efd517e8de163e55bc66399cbb0704614363f2e14ad5d6cefb7418c0c109b0b64934101f600eaa2a1929c551ca41699d8fc90829d0493d06a6902b391425264a2328cd5a5532528aa394da5165150f16cab55aad2664b2e867803a95f089762578c6d9743472a7692384c27b7cd8b051a9787eec1552850c096148085a488e1a9bb0874d0f143d60abd5f3c3a27ab9f3bacc429c17bc601ab88ac87fd808a9d56a405688650394f2daaa039ebbbb7b0577d8bb836ece49575d5544f6c694bd70baaefcd448b5f6de6de3a6e83ababbb5eeeeeeeebe7118679c73477d568cf3e79e73eebacef3be1a443be89c9808ccc9b19bee54965277cff33ecfc999f6fb9ca26a543b83b46a72dbe501411d46a374ddf56da523ce41a1505a6b9d21a21c3b7cdf0853a9d40e49546307dd2110dd2a1e90082889ae63a9bdd65a6badb5d65a6badb5d65a6bad7574f7fc5d1e8968c085abd6eed5bdbabb57f7eaaea3a3934aa5767676542a1511518f4f1895554e1e4a1d746010310407b90811471fde7f4e854dfa449f6a94299bc640a21ac3a2c1112f81c928c42177538de85315aa5b6a14c7a0569916d047a2f5cba68fc2941acb5386e90b3124697dfea49422a184e6508ae4068922d66ceab02f94525a4413344529a54eec1d4a2b0e4478e0043e74608511580e6cfaaaaeebba9f212165776fbbaeeb2a120f605ea0bd5cf9f1e440a2bce9edc3ed081cf6f6b38aed618448a20ad9cb8531fe376208a618bbac6184525396a61a0864455071c66e7f99d43cc984465f950f46cc0050c43d7387b8730aa625fbbebd976969df2150d8778811ec4b44d2bedf3af364df1fd27106cdbecf030d07f645d3b46f1a12f64dd3b46f115e5eba0a5da6cb2484d3ae2f5ebabc340dc6defd68632c44d3bb80440a2e4079c900b36d70e802b6865440a4400041800922ceb68fdbdcb80104961940f0b06d8e7d69afd76bcacd21892b650389364bc6daa06d6bb0586d34e55463ade5b66ff9d93f6ccb83990e98e101cbb64ff200c5b6df1a62b2edeb506261dbe721dbf67d70a01467db0fd203d3b6df8107b69df960c5b61fc20f4c2f2db0a23073b634c3b63320901cddb9b570a40993315a509064042c2cd828a4783c4ba66bdb33d8be3b3051e605ca832e75ebc60e4580a006aa103ec6586bad7fcc9a272d2c86e2e9c598374d80546113b226949a6072118e8953b452d3444d143557d46c69f1b22725b050856e62405816bbf23302a3950ce94aa8e689858ca9c86789a61f198d4acf12b05076022a3c163bb1e4041a27d4f8844e4e5025e1d44326cbbdf75e36489435c59459fac1060d0f48c491648e8a52aa906644eb423ba2acb9552119d9131dda0e19214cd03fa0e89222a326ca1346984ccd494e125d34193831d06210348180a6759862429b241d567852c44b87189ca461d241c624044cf88726b8a933a20967c491114959ebd044d1e606ebf006ca9dd8e2354a3fd630717a87244eac2a8c628a1f51584159739758ef1025ca089c76e80213c10e47454d453bc8a614a114bef036806025a9e0c3942f58b4dd7336850c8c351aef399b3233010833539a76a99f86294db08af4ef399b52c5192a55c2300446e0cffc16e4a19c4b3ff3d72f73e89f96b2c0df11756c624bac6298432bea5c50ce337bea7c39d3f89773884e447d8ef8bd8b3954ec6ce888e564431ff42270a744d47ba2fe1cd17b1d31e7679b0d72306d80ef2dd9d068a858ce1e76a9cb09c410bbd47ba6d99a875c3b3aa2426a9ee7c9947833a8cc479b7b8ffb12dc9c36f7a56a03c1dd9a6cee37cf0a4a72db6b73af83b2d8a5dd774baa4275ac5b52cd3f9f6e4dd306f7155ca14b2e4efe42716cb5fbdc7369e615b93493c5855c9c79c1b46eaa0836c7856073f768ab2579e8ddc7cf81fd5c57f46f5265713f5dd8c73d72e12d147719b11125b91f63dac77293825ff7a80ae1e7c27ba4b967818db82ed8c7d78fce09bd7db9955b93d1e67eab71b5cd4dee5dd034978f9ce2ce6883ef91b5770a4121d0f2a042add6745971ba3c178f0e9a73ce39e755b5bf01f9f4ed58040c10f2e9577b7f0392fc4b7e9109ae7ed8afbf01f9f48afef68fb8aab8ca9ff30884becd39e7d7599c5b67189651127c2ae2a2ca0261c4788d9594d0df971c6c73471c8c039f2ba238ba073f3f75af0d76b00d96dd1a8a83e7c1cf4e1487eac1cf6d288e9d073fd7288ed4839fc1cf4854686baa2c30a8829e9f3497d96036aa4239ccb1581592f1e0734719e87111e61e7c0c23638ce573628ee12d542897a12cf08fd0a08131967329682c679959a682b1cc91e3c68d5d724fe44ff0c7aae7ef1f71ad7a80d4bf2311303d4f64044289904fff882bc7385865818fc7b1c45a1c4b1dfe58862fc6f2398e5659e0932ec6926c31963fae46163fe1586a9fb1958f36f89e7f3c222e8395f01266c26828093ef9d365c5551e2fe043c6a7385815c2f8e9712dc44e1ad3b00c912345fcaa2cf0afc81d7134b0e48eb8a3a31cd59554361a734c2cf118d3250e017e55a1eda8b2c0bf9ffa9e3127bf6e4ca1679b0cb41da58e8e36f8d3458ad3c523e63594045f2566274a82bf23e636b94649f075c43c0525c1e76855686be26038d35e18a68b3608eb621b7cd8069f3baa421989b2c0cf6a9ad0fc52584667311b3cda60ce98c71fd4254397d1dc13f75431e69e9e36f89efd5a059817cc0d3e90fcd2d9bfecdeeb44164c3ae7c11e3963d206df836ec494fcde52f27b1dd43352ceb10450d71d73acb2c0ef9cd0b3ccb1a6a6a6a60d7eab0a3960b2c007a3d8e0e7b8a0e94ec494ec5e8b9692dda3c41c31487e308319043b2316748506fc493e08165901195b3f8b606e95df77fe551ea7cbe6d873a2714adbe8a82c1087f7f33d2cd6dfc0f74c4524603cbfe713ecc6361c5416f818fc2c967a83ba07fd3d8ce679b40dbe3375e07b97fc20cd20cd20cd60fef2c17798831a0cc1f73e1104c1ff3eaf29e1cda0922bbaad2ae4faf7a2269f2d5ed0dd779e534ed90f77d1a78f7a1df451e07ba223117d54163864dbdfe8304a823f4170aa9ad0df7bcfbd40eeb5c1df68756eb40dfe26ab186fb20dbe0b9a2e72a3ca025d1ca1ed57071feb2ab43df8215985eea3c632c49b2be262568d7eeb256cfa7acd765a43700cfc0625c329f404260620e00d42d8c107f3821bf49dd20c5c844d472edbdb0ea60dbf42039feca8c48c9a6962e9d08c00004010002316002020100a87c442911c87f24c14dd0314800d65823e665c401f88435192c34008628c21c4004280310418620c62caaa0ce82a27d81a1ac6c4d01061b5d9edcef91f453135597b57896b298b5c3fed1607cb8201197f8f5f0b436057a8d99f0bf9df4b0982c9d8a91fb0b66e869a4f43fa1ddd75ec69db3caf7c264881990dc6a65fcde8b6eb2fd58728b77d373a70d78b6ab8db30c1258e45eaa8e9bf1378e20dd0f39bce6dc57d9ee720f1fd0bf4ec72b18683abeb89f8ecbbde6857bfd033626cd43430c9911a89c73558d1ade1cc59ecade19f68984a28de704b00c86e1033c924462667a000997ad9e6656fff6e3aa9e4c3221c21951df47598f989bfb3a747f91fdfadc6fb8a6910d74f90fdc7cb2040a317413834047e19b9d105e45e54c75b7a7c8de76a4a3cb8b2b970206acbcca66c79930d6e481c8615bfce2dec4810865abf6c19f6a0c1c2a98c2f23c3bacbca2dcf7f44cf630c6ec94b5026011c8f8f599dfcac8e5c73b2d5dd7c505ab97fb19c9ee6409494fa22491750fde0fd9467f535c948f53a394e0a3fb5a51439a474a43ffe0da2f0fb6225beeae4d2bf425289b3d7d24d1411cd89049d38e1905cb5c1f58c5a7282a2aebb4b01a7f3cfcf1e91334257e1c78ba5ef2af4f6591ce6e3da3c315dd24bef1d6226f74ba6169fd7c5f7107c2e78bd0bcdf326af270dc269fa5692034440a399b139884ea4386b2e6f1818c921af102f9a4d4776d6e1dacb78121feb114e2da06156ece0b1294d364a6f9a945644790f06d10b189394897602912627164d109876a7d104b94a02d963b04c98adfe403829338635d40289c7bf7ec49b1885578e65310819420c4340b0223899f025f244a068b79d492266c9fcff60100068c9cf3b66322c9a0e59f6c641e7810e1f95b821c769ddc56ee1acf5984945cb94453feeafde9aceda418d5068c6ddd8431a9b2431330886538fb0b5f29e2cfb904739c92981f50ba5a8a09900e1cbf7ce45b53a3412d2199c79f3d73279ce7bf8c76555c28536b3115e28e1cf42d426884fdfa5657aa83f4506f8f2c20a335085c96c98e8c841e481cdc5f8e789bce4f5fed95e47bb40a8f0d98c2bb2805ee504f04ea7f02d6119965c5fda975c2f4f89a25a6b61b4201ea3aaa0a9a9f0ebb8dcf3e12b9c10b0b18ed82b3cbd7e99bd98d85ffcc22551f2a8ddb51e579d1c2839cee2b99994c7ff68af798c5550d55ebe53f2fd9c7cd7fafe95ef8b372883c2fd75f738a45ae9d2835979ec2e8472f86e2e9dc91b3027eb487aaf74b275c9bb45fd7fb93b914fc20c0163e2556e6820d3e87f737c6b4167f9950cd460687eaeefb159345275223f0d26ebc0348d4feccdb3c955e74251d4956a1198835f2549e842e1725db120c2984255cb18ae10a0ab8cacc0ecdedfc96e82e6954497942952d6861f9b4d9927fbbd06b62bae756af2d71b39b2891f5676abde8076e883d075b9e6df8bcb3856d6e558bfae510b77bbe76aba13ebbe1c8ea3c63af59f36c84d316917d238164dedec159226a108c8ba947c9c62a0c03014eb9c8d509ffa5bc05e41607c6c1dd535b1a1aefd55f6db9f96d7a3b4266d2eb39f69bc491c6705170635417c76f54703283816e6819c50faf07ce909da0355d728e3cee04d1a8a8918516c52d4e508ab22291c139e499378066fa2098da96ecea3b20d632bee696da3f856c7114bc00c7c795d6c50aea4a5f77c8e8668e51dd5269c2ef02b1c48dd6419f6cbbce964b8875173e27282c87f2e351353154d91a39bf7f803d6d3d51d912d98309669d2010b52e5839308a2069b02be7d3627223b48889c6cb50d6cfe56f7bba647e6faeee75aa747dae0c3b80d82a1b20897a22569a1aee7de6dec850fe285470d4650fd7ed5bff265cf56e3e0b7aa584af25fbca77bc576d8f8e320a50a595325a07b4a7cc9fe66bbf2e1dfc3683c6a8f769f2645cf49f1961276f04f5a9bc0cb9380747d1075107a28e7a5b6d071242cab1cb1e0ea9e3f70a6e4bbeba8fce40b75d97b52356f987ab24fa187d438aa92fc23803271ffe4d658dd7f9d4b4fdc4ccb8e39ef21b13ac9f116ea22bf08059a1029821fbea8ce91694f634fe3e20670d28b1805ac5bad5c52de942e18e92dd1950384b594cf9ee9db5fda8399a017dc3204bd8ca37c8f9393edebcd9fd887d35a00d06b25c7481116d85c65c45232f6495ad569fb53fd2efa112bea7534b0cb2d399b4caee03b8d601c6618d213f97632f991829a2d23a0e988a01184ada7b7d6a20ab748f24b75b7acc32c90d74eae950073858dab1ae2a47d95f83d02dd2e42ba19c89c073e8394857ff25a567ae5be5d255ebee0367125100a3d1895a5c4794c0679555eaf33c0f7fc85480836be9d8a913631f4c1fcd008e5d0d9df2ebc2d77959d0417b9eb31165b5bea1430194084028e88c6f2955dc9b9bf641c3a6a718d1c0ae442a5378d747440564a055d57a5e6b40dbd02471728212291f7bcaf2a6ccce8b9c4c47b03330427cdf29f9263bdc8cf8021c8cce00b28bdbf0af40bd2d25e6b0476e5eb662ee0ef846570cfd469589934a62d5cb8eb8ead95dd475c37147410608873b81452f58247c2bf07c80f241789faf967072df51961e9fc4b31927fa71ce272e5c8be516e761f8754f05d74b9bc8074ff31ac4eaf56e8985bdbd9640b994fef6feba9e81defd161185527321d3ea19f3cf19275ea7135a42da5955200b2a990c4d2e6625f8cb513ba220f1d67fd3fe90b28eda00bdba9fa161133374b3d69d9663794b9d60e423bb4f92222e3c011f1367d71055c4f9e49f007cd48ef0c6b59517c8d34f9cc2895bae29adca51953b4d75035c7e7b437a5619d2e369b310823f197b2411afae924ac4111d40eeab670594b05482e41417a181c89128e3595a6d09c0db69a6f9d5693a3fa789ae4c1265e64768fb4ba30d5f41b7e896c5857a57722bb24c2dc61bd42f36f78b5d972703c07644f72c2b0486cdbf9042177938bd4194fc2564851ce6342ad4d864df71fcc4d3c6755480c9a1ae1eff08b461d3404ab9a28d109975dd48eb47b23a73dc73228d20e0d6981777c23b0be501a1084d4f5cca8b54773e8c85fd612003940f499e88862c0e7e0b4bcf235a960fc5e925701b59e568474ba462a9ba301524dfe5bfea76bf83959878a77611885cb2265578cefea64cc9a2456ff9436bb136ffc38633df479f5325a5bd0587342436c0a3ac35da5f019d2f536810e36076dc04219cfb3ba8fd1fb3987d7c4782e7440bdb1b8eff106a67e52948bba04147c8cf4191cee1aec8d2df88cefc3ff8cbf5b353e4566453b35be6d199fbe7d073f90b35a7833bebb682133595a7c04631904f560f184f8b8240c30dd5a0e449e2db9cb5127c5a7ac0f1a70f57da79237af81cd81088e977d097e61138949481a1137b4de92edf28df8bb787c9102ce7befce19e382e5b761ad2d03d3b71b0887c05029fc4f7497ee6aef1cfb1ec7172feb4fa09eff82041ef92c32ec5de519defc68c2736e9c3edeee16bd2f794eebb42bf65dea99b110037f29017aafdcd7d91d036569bf32e00d8b7da8925ad6fe4eb49316fed23372c42983cae806b82a4f7cc58597a8f01fa84db9aefd1e48f975b892764ad8b1c3a7a9fcc9a27aece21e5883c40bbe52821d8c02b40981d6b65fefd7922ab78966632ebbfa852d3d724b27093a6b47824b0a6b0d88d2fadff1f5901abc0959139faf3fe39d1873be45e5fcb7ed134990172dedcad8e998158b2bbb5327e5a404d95953e1f51ecac2561767e18e45e2d0aae56a8c471d7aa7140f8086112591d9cce551e38f0ebd2fcee6ca0cf604986e4d1e98527302a132d103a27077a31d525c88986c67cf4a82ebf0bec430cc8f1ffe8f92a88c69672cc364ea2b5ae017ba9d74188f0c75acf22dea894fc5a1cdbcfd916491f296fa19c755201e98a3a190cc5ea987afaf44006da82152eac9ca23e503729f814944a78a604891d0a8d0729dcfafb6d58e98603c8bc8eed584fe24c37ad1b7c09658f982fb7cc585f4f8e7e637b3be7c20dc89702920252588efbbbb8bc3537f892a44958ce2719a15f1a5ee67e5b42068d8efbc16bebe6dc98000aeeb5cc297310fb464df60bbd49aa5265cc59c4134a009487c1c97aa94f53c318170df2f91110acbc96d6a289bf75376ea0ec600c3e52c5cab8c0743e878335034ec53ea79c790e617ed5ca5c6066885f1ec090f3255dee96b256f02e8f7d36fb9c1a476cdbfc23e3d68d2a31ab99fd207e6c60e5a74b6cadfcee3072e9a551c4118f3e28faf0be5bdebae8015ca5a829732ad95e599a9348ed881a992c356381a5b5f0df5aab843e029e0f24ef7e5b5861a0291b8d5a124feabd0d0c8591c19ccf10578d813cd4809e55b18f625f879221052f514ea5629ae02e7e80ff21f9e0f680cfd0aff1d1b821be69b73d9a34fc08cf43260813c0ff7a646541136e4394c5c584ee40feb07ec8f1def6592c9b624f73e47dd7542ead4b43b22b47c40ec1b8243ce508114229a823c2d9a8c8679a0c7133a05be73b83765153decb64c12d25895ede4ff315904d593edac9a0bfe41d5d958ca9c999c775e619e2af9d6acb34d2c7f521e11ebef4dcae296c28e304d14410664e6cc9ae8edd0bc5eb6d2c68114745428a0c29a69a5f0546b2d3d2caff559c304e074f7e5c6727ec59edd35216adbd139e32bb199d5837ed303550a2b5cb739ba2f977aeb92a304c20481c9b834e5a2bfc25bb7d9e547f640821ba1a82c5526abb8014898b0b5d051d9cb5f28a445e19b3a2dd950c01204f1c7669ae2131694420c44ed42cbfae04978fa5c57548acc773861715ab9c7f047d72420fa8adde633d1156d5497a5329dd6da7c2b340897cc030917c67c974e145fe28b04d0fa082f6270fcd7443a1dc948c9c297f66b40da218fa736c8e30d469189d5fc6675bfc5f9b5aeb027c3dfbe5df94c11f74226ba670c628ede39fc2e76321503e2a61a02915b098f6ed2584d053360e58a7a6a9c24cf8b7704ed642d943cbc97d07a992a1f5ecaebc20401e7a0203729716ba6b31ce7ebe75c618f998644fd9a890b581586d596240c7626a19eaf11c116e401875c37f5c7d880b10f92237f941e269710c77c07a5acc91de1e4728c5c4d89f07a235634e62f219f18efb3616102006a12c9f03cfadba5514d5a52ee8ef3e3bbde7c2c413a2146ce87e934659d4504f71b763f423ae176e6af2a606a6170f834f82346d632448cda60f28f874541cce70ef4136548a07498c113394e64a250902b398edb23d3a2aa588830149328f483ac398405be16f72fa02b0c214c2d2564c4f7338899174d7277ab2e2e81cb2aabb7624ba23bcdccb7adf73836718044eb753229d835c634dd9e04f1ed9c1623006d9359f2159fcffe3e4f5acbfe2e0f4a815a080ad0735a752a6b2d7b378c6ebbb439450d7d475eaba29ee3a90314475edc8248f814f88aa0701cfda12108a323942e5ffc5446ab97457776a384d1e7073b85d9e8717a91b9ddc1298f4221817d378a7f2f0ab05d3dfafdcacf15462448839c82a2020495d44204bc49a8fbff7f19000d8393c670b92f5e28f051a6fd336f00651d094e25b23325c330a803c32d013db104b79129954d725bc94b807d5cac913c61b84696ce5574615d9d5f6b5ee87ef037c3ae921a7477cfffb77e9e76986055f79479bf16e1c572bc58ae94842233149a8845a279ba6c67a8e6fd357c1cc47baa6257fbf55bea7c025873bdc1ab3374a3ec4df449837d3e841ce9a90055f78f5c05e9f5217e1437c09c05135d35e3da575ea1c2ff3f90c11cd0816a01ef9790c159b19dad415457589181ae8b42bc4c9235981e0d61ef29e3ddd9747826c5f97aecb0063e132857176e11030b302c1d3ffde49776f3082c3d30f3ebb62ffa322861e5a88b238c78d965621ce69d1dbfb1a5462893067f99452f2cebb646401be4550fca1e268fac4efdc31b1f9876d55bb6f6dbfdeefa8428cd0bf3a71e3ec12ca2d341395aff4e314650fe31dae67184ed130bf2417a7a1cd577cd71b3c796e75a0fd6ce479565d2f24cc1ce97aa276b2b9381644c5bbba4168c7f81147e60d5f0874ad8409424d7db856373147d036c6b2eba5c3a042d146cfacb30ec4663701fd2a437f2f8d155f3b8cac7947f0b226d3e25891cc7a5f2f7815e9ee68245c23ab9ad76683f27532dfef21efeb63b4288e29d8365011a4335e2385aebb80d558e598400ab5be7e43cd49d1be351aff492523477b50c6fcfedc8092456d50e2aa89245a932feef1c48415f849ec4259165bcb2e7e2b3ad2782b9998ad1a8f4eb0e1f2a959a2634d643e5ab4b0bf48136b810d205173c7799a3ce7b4319821926feb0c756d78f8486ffc99c46ee5756e4fdbbf15c894814c98a1d5346e95875166b22bfc010c74936f74dee4a177b3fe1402f60540d13c36700a8b44f7fab7e4106601b1f9e70a03c7b262ad83a9f9516a01e7c7f9b4ea9b7871970f8c35e35f08387770dc88e32bd6ec2ba924b91af8830fd36a33d0837be85db1113766167f79bbe241969656f848299f88218757d2509141648a25db98bab04bfe79e5543ffaa492f823fdf4adff6369b37bb93f6a607d73e534dea327536dbd957edbf298da5d7d9afedd156f54f96fe52eea7e407536053cf7129c1e982b8eab2538206b3e0ee40f81582cd970efd5644fad9cf72a46be60c6f537f10a6f688ff4a152227c333d81bda8244522ed828692b3362e1e1489da72b95e14c402478922307856c981ce5cca51772a8712f661d441d5126f9d7cc9b5d821395c7cccc1774633c06a7874c1227bbe284b8a0695582c685817749f7219364335e07068e9264512fb0ea7156be482e076aab1ff85b059a16a99732343d0c3f01b56b381724dbde96093f716025f098329b9dd7449f02d00a1cbaf7582f49e89a2c6347477834cc210947bc3bf93adf364c0e52b95a1c2fad7d8d46345a87b2d83e0b0c2ac7e6817bf6befb6f4552c4356f3ce9bab94e91c835c372da1abdb896fd86e1587567f86506b25ff1cc8137402724630d1a6e6795f0b0b5fd4c94b9a31a81a40913a5d5251b0a82f77c0dbf6f4375eed7e34d7499c9d65fc75fcdd5f839678c6918b015882cb57c4c74d030fd5e06c60661c23b3cb3e30aaee8bb3c66948f776a705da9db7dc6c89728a0716a7058c7ae127dee1c63d95b75324ab28f68ade867531222cbfbbbc7426fa6b245e29c0ce08c05cac466e8d6067f216604e72bc4d0319c93c69282a8325ee3973d5a56ff521dc0a62e33379ed36108e069c38247f2b42b3a1edae6fc9bb45f2648a3557e4280ff6b9209ab9c60821233e81312b5f372fe9de589d205a773c8043d33c16f8ef38462ed9c434624c213aacda13eaf674c20d75d712b4e992fbb2b3188ec9776a319147de8dae1b8140c1f7dad7d16869105dad409a0dd0ca53244bcccb90a397302fd208d6fc4decf8a9c147a7fa33800f5de467238164ea008916557b9a8f8a19c00bddf4aea3cb139f5f0743a83641b764917b8fa07d047d83609ebcbcc9ccdd4f3a4677b7e7acc37467afab81def59a09b8960694d199d0b62debb85613acab89ee5859b41e6f6eb891fce67b290289c0b33419841a70978da9e711a023a9da6941d5122660c84844ebb2b087c8eef95eb0e0ce5a8a1b9494f16e57d05c1e3a0fe13730f9c9fd6e026d1e4e5b68870ad0f832f5b8d42a691bc36db8f459f36c84bcbade7d19d89fecda504c6e64ca2ab9c710456130918899ea439ffdfd4728e2593fc80354cac56a517c6d0010ac764dd6818380ced161d6a89fee0ed9afe545dd749b6006ca89220c69f8f39daf7bde019eac750a129e1612de1c5b8b6da9e438898d667645789e12cfffb0dc5a1759c98fc5b02b387f833aa559310f062db5adc550a04de4ad05e7ebe46c7544d822dafdfb8782273c8a95c0a707babe9438f76fe5ab46335979328f0bf3cae9b4757b7f3ae364efcfd06a83122f0e81bd71a0cc22ed62e9614124125af12cefaef02cd343550b8860c38fb8ad0cd2d5f7029c1180c00007cec855a43d54abddb4ca207660846fcbf12cc9834c97b2318e2706fbb8e75c9efd4a124f2608bce7b5172e7dee2b8dd24d9cf1717a505051eb659b7ac3b0ec6990e77e3411ec89a86d7c106b21373d4f5ec6aa034e24f29f9b40a1575932636256fe1c2007a5a95db515d54f2351db807713e3ab3e81f29a723348b6e0a1cbd158d36a676f3c5da9f85ba3094f7bd70dbc2f824f4640bf6f4b210923f64c061ff99447daa9fab2d10cc8eac73d8cb2a398670bda1eee8234f747aa1650d2657da29ff8ddbb3ab44ca2bf9097bcfa1138391a68482f49b86cf19f345f81916a819ca3b504ecf853840ae4d56599edd4cfe61095c9bd03b69c75921c6f4009d04da38357c226212467928af5885c8aae60b3ee956e7f96046165fcc7196b2667d276980c4f8c51c143685fac6243829f00e7c90e63a59fd993261a1ded0b202e58c4c076be600272a364d229c1c9139b3426271fa5d889eb6522142d589a0420323c1e53559b27e161d9fe67d28ca80855b3debc04c6c906072584ff6c051f6c4e997c74838fb9d157e725d55ef61ab258aac8a18d1042a5cce74833b4e1151d3ecb39d9aa6db8a0dea13bda5854d8196b41c2b61cb0ab2c1d673d280615e84e2311557d97e542a09b359beabbfc494d45b810e82761c3c049487cfc648b7a9bc27c42e68fe89f2e23f3e28e4958e3083356b54fc04d1e5d70fbf034e0db313192aa688bf60defaa81a0889793e68daad33179b924af7ede6fb6f97d6a51b018e3af64dd9aff4879816b728e800f3acd2f2ef99feb4fa6f9860be97b95e9b9efed7ca5d0d3594ff73ae50f64bff6036a92be0c1097e08c24d1525bb1f1047e60946366840bc0c559c0c47716a2c79dfd095fbb35f54a57d0f2822777bc5a6e6783981ce89a55999814a31b83a05ef1f54f99910a78fdb2202088a369fecf5209531f46acb16648c03232b24b9e0245266e3d9d08268a59c394f58acc75b5a47fb5088b5f8b3d5a9602b4d6040a999a29864a860a4cdf84b6c3d26499c6ed6e2f71a74d1a7370a1057a65d25fa7bd34120cce69e954d4f7ed3b510d6c3f6e99fd4d24509bc9ab57929b742609acf035507574b0f619a431dba47ab9b9a61cb8b09f79c694c392ea1bc3271042e2c835aaf211dc2798c58ebbe15fc4b66be58859b631949c78cb0c22b42aba140d28a50dc5c55a8fa56705028dc1c044576a9546c45ecae16666dd4a4c8d28937d66d89d54a5fe386d07c18e924ddf712dd59f4563434b14bc406def999c7e9358ffdba647b9420f4e3191ca553327665ee7f68b0f6525774899f1fc840a49f5de96a5775990a1f9c7caca4e6c55e4af053c36b95a597f5c6a262c44ba364a551f21dc6d275ec05cf7a7b95d24ee44a02627283ed6e3e28202bb5c70d86bc83a7d8f32e2d15be65d53926eb1ac2031b0ff2c860f0ed23dce8ef2dbdcc3d588fade57de8514b067c257800fd300fd1e51f3ad58691b4d0bcbb549600970cdddda5acbbecdcc277e8f01bdf693869a4234b9a6cd216812172d705c8b69a73dc97c31ba0635f8d0811ba7b118b9aa855dc0584a02d2e5941ec1b749750255b3a9bd418ac5117c0c2f4e3b52f4092dc915ecf99af53d2aaddb94ba2d41b3bacf405d47bf7886fd3b5b0c5cc0582700453fb0a906e214cd35247840a12f344939f78e7ca5adc366d90088c01223f66be5110460cbe00f1e84a9128436c299f045500ecfee680d69fe14b27cd3418b273001b43cb65b4daac709bd4b4aea000e3ca8aaf95e8f60fae327734d716aa8d80930aec558bcc424bd2030cbfbd3707de433ba43c6122c014d63e052c08d0118f14980b576591afbc204ba19b80dc5d047fa7f7a3ff92e8df5da75460d85d2282bc0840f9b9f78f043fffcd317206558920c8f5295d520d88779f75436c0171eab692af86fa0ddc7744fe435522cca42fbfd081fea78fd7f6b984222219da97851bcec481d7845ce2f55f1c33bf6ed7517d949e698221c74a21d3728b3748a1f7ef0a3bb1cc917e656b37b2f55bf3061983a21d25889e4ec34a8784f6af12ae3d909eec0d58f730c2ce008d5d5f72eb9427eebd4423c0c8b61a725bc0f9a121b5b3a73c551f71bc72fa0cc90d2a21713052277e2eba3b5c253a8eda809aa671964a7426afdcad8e76005b37d918ab051f27dd13faf625cc0686923c385d7fc1408aec4fb0edd4a9db18c3d1b1023c818597fe145a0be2fc2d1e77be16de7bdd51e1ec88d2b0d859f3a9a1b85d51cbeb90c3961dfdba70952ba444ffaec9c233604976c382678fdadae4a0bae5b971fd85f5c6c6f38a1d56db282ebe3ef698c7e44b47212b48159a00c102e4165aca1e4ba0f781068753f56835cf8eeb97c578a92d0c020c2df5d9d29c532814b7e66c02d5d5ed9201c07843c4d8df519ccebcf0fa05b091b7b60a1884bebc103bae7a71251632517c153f982862cd855b904f70108efc6951b7cac2855c2bdf3a0658552a3f4336f473ca5bd12088fa3becbc8f05c1189d01012faafe0471c262f1af7382ed398134c41ea6a16958a786677efeddc8b77240862b30d07af6ade53dad1adb8d01fac102ae29db97e1d6357926311ee8a712f5b7f23d4353790a988357e13dcc119c5d9eae3d6696cf81ae24748401fa270dc3d6c5280c4403eec3d35125e8a8d3154f84a04d6751e00788a62af714ce12244a61ae16e8779fb231a014c71005fb58df9fb37cd0a916f49fae00ba77641461967b2b493babbf9a9d544d66dea97c3015f2cf04cc93c8dc239557d8503a3824878c788da8f7196781894b402fd8e2d89d30dee8a13eea62bc8bc843193e519dd70627b56a10a09372ca7a609d589c31e755900b0e11033a624200deacd23d58d5a261dcd289b5fec7714cc15907b986fffc9f48ffdc041b6707fe507a3b91d9cd15d74176e6963e2caaf777e0555c0f22c0747b275eadcc03560548278bb0d6ffdf9ed91624299f8f070246267dfc85eb161c05f6cbd9445c2fe0e17e2bf3425050ef35ba3cc0d74a55fe8d73b52feac3fe2106c18b0a8bbf02b207170cc541b61b829e8b958897ec7caab7dc79a17a886b5c2d0b27f69c29f458c6c64e24fc87ed1eeddee1b0ad699ae2fb6f79c664fbd7fa7bc9fe62077c1b5a20289650fb9fb9427790cb786720234980d00a435a097d1b7709e40f0e33b6180f2c56fd3eee3c7ab131772f57afc39e9d735edef9b9ee0d1ab9519fff1e7f6b24f685f8ed0ac01f199585590588babfcf077a6dd39c7b37ed85da08c9a4d42ec6112877cd25e793a398b763075bd44cd6aeb8a6d040612a5c7197da9221a1fad69d837c84b8d08fffecd18799f13383375fad267803dccdc461f53c2f255b9bfa28227f182224abdb06c128548006d3ccb0442d88ee898f13fa88fff7edbced3f26c8ccd568afdb6e481c9af5b21e4e11f79abe4da39c4ccb8961891f5492e5fbf0fb81f8df23f9fb3709714e4fe55b218cd035e6cd0371a5344e4ceba07f3404e20f6a0dfcfd232202345a7bc185cda2331b4e6f38f18db2b1ee94514234d9a4a412911a383a3149400793b7d64e4d511ceec5899d5b7d483185f47ffab1f1ccc61f70165c0f68e842e60eef4014fcb0bcaf6870bb9258804b4a2179b8f372818e90ea2cc5dd208031583ae89fe3e012c818ccc361b26e7a6a67643d47d7a06788f04383c665a7d71e424d22f206a7ddbe0e06169dd0e9c900ac2edb6fd67da36ace681ad3dedaa02b6f7306816e22891715ef946ca29b12a6a2f6a43b1684697740a0ca56261073dc15941cf8cefcd7760ed44d676eb9f6590d52a7a6ee80814fc43593a492d39cc9e6e80e9f85fba34751ab426703d33dc85ec262c751ca69326e6d4104192fd9280a1982f32af1bc0f43201a773374788be3f39d12ec031e11b7008733521a20f15f38e87b0be1ce2394f568bac2b3aef576a8b641267ac81f41506af7bdadb5a75ff18dd1c801b84128f733284e4ab2b7db5601eeb191b98ce5a23107cd0c7a01500f194df7c2627fc52a2b73fc2d955d66e14e6560e88447587054b8ba6dcea50fd3ecfd184388f7c6a960569cd2a4da0be53568e41a72a6e7645e1e6c435ff92804e925857e9f06622170510743db2afde1a329dd0953f27f5344afcde33181b6f010adc49c8710961b92dfa7cd2f55f2b0781808638e209c4c5cf5aaf94166fb1824bdb3c956444aa32379b79743b438972941aa811a527378863190c31bad24304fa9e4059e8afc284b980587683a8f14628b0711709aba9cc5af570870e22e45d3e84beddbcfc382d864324d9eb0409558bd437ca2219ade60228ba6b4b4ad13bc4de71568e492f8ee78f4b8ed1e2228bfb20e17920d8924446efa5e1a4f5c343ea31e9c0db8870fad37e4a1dc86f1618aac9a91a103d4f17bf8baf70a1ee61672b3faca04535b49093a155e38361cf78521dac54b70575ea75915667da5acf9e7ed2a453b015125aad9a8679137e696c4c947beaef0e6e84fab616ef04d8b0549e835aac8ebd9c76dd01dcf1024f2fe320a171f318be32efbda1c7582048bff3ec7196799b5b76d8f97df001e7cf9ab8bd33bd45bcfb73e6ec840bff3abb3979e4d2012ee291e3bca107030f2ad2043f0601ab1ff1be9c7654bca225b14730f6792d315542c73aead0c78bbe4433758363a00dbb3418007195bc1707b0bbb00861909a70cf1d5f3e51ae57bd428e793b071c1bb1240a7e3999ca9e9f57eec805de1c6d99dccf0a345e8c1e26780f32be0f849a3390619a89222be8219617044219a5e20f6c99c2024ace24db1f5b1c10a597fe6583de0d2657ad9024e0c14a2757f0ccda2329a077313a60aa4707da658e6abaed10fe94b078c625cac3c0e75b1be553179c424866f6e8a86e924f6c365abb22f4bd80d0b52d774ad757c231fe5e461f46312f310a37534873ba75162f6febf89aeb0ee1304bcd2f63284d9ed04417df1f9b5785b39b317c565096a7318abb0da0e264e77f2a28b41093569cea1a7b6001e557a9f540a3f26b094a110d0b94687924fd1dda3ab59a3c0138beb014a2ce2a39e3a88d69d98ac567cf394e31205bbfd3a7b406a928adcc6a604f19a30c1b06dc464d514f68029c2c7296a10ad178e9caa7e3202f2b58e3488a643e67b505017df4d11b81647b126653963c701e645cc112bf9015789b4ad71e6eb450e30a957ca0bc1cc935682503a6d51c79a933fc8c11ba37a1ee0941236093081394ad414e3bac384846cb7a72cf9b92e4e102b6fcaa288de03ca052c1aba40282f219f41b43b95d643d2cf0c2c5cfdb704b3208408f3fa3b50332e06d16ef4444bda02edb258ccf0cb8577824c6537389b8c4d0db14aec3299b84ba2165ff4bc4a6b98efe2ea6a38bc84b31f6b3194816b6bf93fa543a2711504cfc41b1c165641e77a718f310967289107bc231444d3c921540aee9b7ac8e3e9aca9b72ec18c266812a69834141bb9c70b4c99d911961e7ad05e7f28085839026f4f780f808fa168b9e236638584209aaecdb0eda555debbf4253825fb0bc3cc63502dc854cbf4341b9fcde7f2faf67070ea4b4b017ff10a8f45052e50d416b58a5303fc6c74556936682952093f31f119ae24bc07e7ddf3a6c2d591a85d96a0fee331cf5ab0ee6e9a30abbd45814d9790cca5fda88f586fa09568205a7ce078d04c46356dc96865a1a15c3cc279794593521988d615582e0c3940a9dc9f37927f0fcdd1aaae0960d36df722dfcfb02ee7ae0485231ae9af86801ce4a7e35f3d3c6b668218668eea9419d2581f1e52a3bab9aa42680e4b8ce2f06a98d7cd92b42ab46410e58d2443064c60e81200b38016aac53148acfc9ba6a9272c8fec5d3e852d0af0eacd018582a007be737edf271901d1ae642f903e319af0ac8eaab754e55de24a56b338ef2fea6a20af7e808ada3c78eff9ab3193f11a4a138078c66531b0053b691b7c939357bf3bd7373e9bb316934e6f00d13a0e488ff57a4a3f68da70e302ac956ab45028908d716a3b98bde9e9444f4a13241afdc42a457cfaf7e4f00be92e45b5864d6785102881d525fcef67c7d7348eb8a0da8e415f6f22cfa9e398cff8780d12af751a08ea5ffb8dfe8e747f2d6b883347f8fc3c7a29b2d9b66a59f3d3a8cb3649456bc206d5e301c822b7be430de4ae6a7ff214d937cef4718477e252fe6bab45aac5d1872ba20a0aa53f171158852e3e1959f2ad3bc7ba5b63cb3622a8f996dc66b5b71cac32dff3c363e1c8ec309d586e5e6e8144894325ea63836d56882ba1553a1c13e153ada13b49d0adc49accecaa10370d5bb43357c8bfb8045d6c4d105b339f76746d297d07ad8f177dad9f23596a6ec75b74f6fd692bc95a29fb3139bb200c550b553a8e371f7cd1b06b33f5e308729eee3f417dd08d3129c9bfab52d32af84e57d117aac2d839422a813d7f68471cd87d322d69c729aeab06aa3f56512d8e11d093bb84ac765670b94740e85e656168a3a6717d3aa9d2d818bcab86abc2f3869f0c563b12b048054d8369f16a08ead9d75ca920c769cc6a7315bbb4094ec817622497ff1865c86224f04f6646f899a13e8da9717133ee6c6bf830c3ab4fa90f328f55d8faf5f445620a9ec07261c74b05d34e11b4ba631f5cc14d5b1d5def056d978ac35a7500be44962c22d25fb878d333f6c13c3c9c5c811c220b83fe976fb2deaa8d980535cbdb565aadcc907ace4f6121fd6075cacbe7ced5bcac5c7cdf1b6f1230ad67771ff749bb994dd91c1f19eec37d33355ecf6ca51b49ca0baa9906de2c4f2dab6704f74d9e1965f9aac5ac4659a5792b1cf6ca60e818e8d23de1a43e95e88c41a995c90ecc0ec22a676548ca6ee6230a153217bda9dabc71c1ccdf6aa967b62d7a8753cb0dc78c835b3df663ce7d700be6d90b55f4037eee03ea2a1a910f2e511c1da3342727af92d5fd7ad83b86fb6d5119d2eb6c9358ac765528273b18d831c370f8c3e626966a13679469b41d4ae427b930049649565a17186a368ea679e37c0fd74c5f55eac3641ca1f2a0c125c37cdd22f12dd3639b7674cca3d0edcef440ee648690a69e96c9018d3c41f19ee6e6ef68dd1fa71c7fa7fd6a99cd04e8e66172e282bcf9245f4a6a8c0d5840b26c57bb6e243b95e9395c79be7bbb75c47571bb83f8fec0de3e0b37c33db2188838ab67a4d388893d58b061aba9f0721ec167f248cb02873e77d59752682733eb3436343aff1a76ae51487accb15b2c6220a157b3538bf8048c8b1834e9ed50a6415ef771dfeca20241815efb838331e59f63fbd2efc3dcf618755b0e8b6d4d0d6441c5dbfd969bc3adf3e1b8bfbf5fd4e212fefb093474ae278e7e9e46eee3231394815e0e962ddc696417a9503d8399310c459f1b1eda2485717544a50418b3174954d5b3c0c30284bd8ec86055be15949821fa22fdf7bf1db0f24ab324ff74b4c9e92b623f8f7ccf1759a534ed63a88a8595530909456e571d3bd3d7c6505b28203ed41b341a5ac67fc4fd82c184ad88bf903cc33adc8d0339008c1f2b8121d908195d2569e4a81f601a0d123f1b215905a717c9d23cb568716b0b7761acb2603fc95d4eb45543e14b4c295836cb48ec97b15f2411d5e1e285dd057e3636def3bc225ad757c23362aeceae3f7e819172297f8073457bf8c4996e52790c0ae5e361b6d563b74efb22c153de1cf75cc075856c86c40ce71bdc9a3211d19654fb457f06c64bd34d5e0cf30ce0b224a22328d74505ef2590199fa8e894d3b285f81384428932b30a644411ee61626db9ca111369c172c6fb3cfd09372b6c884a8e8cdf6c3c8b6c80800a9c42cfd4600bc0817079b61f72312d5cb32ab465a5dd8df1e6f13e8455eea31992ea86041188507e92cc6e7ac90383a25c88741d19fee86760804340439e724b4736e90879cc26e3117b1b96bc78a91e9ee562a0c48012c6f38f0950f8f2797ae61acd7cadbfbda4dd651b4fcf2ba87fab9b751353ad772027847e67d033c4aaaccc05daf4f8a736776bd890c8e123ef3905d055d072426127a717829ea04fd0b62204f25e12d48c57b13a8e7463309c83cc3c6d620413e95dae059ce24692a98291891b102fe314f1352e0fd91499aa48f2e8b444edcdaf736277db2d09f80c98adae794d534de325101097ba05d739bd7cd2899583b67977487a7a6f3e0f13e25682760dfba50295dd0fc82ad3095a76292056a66a8c6cfc802019a73819e0407164aa60b27603e3653a45c93407c691a982c9da0d40902a3d0f683523fa6cffe235e56b3f2f92d4c7f77860437d64e30a09f490a5d7c70f39db4b23c8c5a7f37ad5935b9913e2e755e8dc18477a03ffdb931bea03535e136922b1e514bb0bc97bcc948a79c063e274a61cdd7cf4dc9bc1431de207f08d7cf75c938148886c47e9e988c100232ada72d6928c3530ffd85eb6eb0aeadf4a9d7be23039a88d5eb8aa6707c88b0f5a9067ce15cc62905875cf42859b1ba74c2ddb36dad5c8622c229ddd1e4174f239031037e9a7a4e0a3947d359292c092387804039cad6321936c9a8cdc17d993634817d95c1a5e4bea3bb728e60da7da5ad46f1f1f5986542c84eb55328971250cbd649408bfe9896314693c84d021bc7da0666b257ca0b1cfa811478e5948dfd1703746c30cf117f848b40f01682bbf7f3fc7b5c5c16919a57aeea9e124a45418e148ed721ba7c582ca6d14d560a9c7c71ef32f8e4f9c9b7bc9fb99d9174c45bb238a879c75bbc79fc76704ceba7258af664177211ebfd66e11c8dfd2953b87e01181a17658ed3576d572ae5b42b7df366755637108d4b431dafba62aacddb46efa2bf82d4c48559c9347305823cd5b8324c56c923b13bca18b6e1ba1ad6347ae221035b9a83a5f27b9bc1ba2c65b8aca4d36d644d22381c4baaa8d0c462439652df63e96449b96923e70c15e43254aa89baa549e784beaab4e9061671b648d24efe7b3b5ea49d21ef40eb5e5059612b820e0b89730db20ac5825057eefb25b86cd2792eb3275ccce960f8b10b0bec0020dcc93610bcba5a0acb5e135c67f3978570fdd739a0fa6343b5a43a14d26e4ebbae0ad93553dc7a6695cade9f034fa3b15ebc838b587f78217897327d8124da372bad0143fc0f063d3a02f4548343df13c5240ad4f0e0a6ccf2875f2b7a18a4c90c333aade36b3596af339b287e90f6ec749941718019b0b6dc4ae7ac0b968741d6783ecafec30b8a87e042a6ea9f53630606a1a3c4d6a9bee5aaf1d4a979f41f68c40efb236b0fcb172ba10fde5289ddff7ed50b763c35e5075ecf6449414a15bd606d616024ddbab3454f940a64b958acd85684b40cda3b6c5245b38422d7a3a54a08083271120e65fcacf4b782415c2d21ff034011a120db5783589acc177dc67694864bed5713e4516db58264657a600d2bea9fecce391912439e7b2fc3c3161094e8639b46214edfac6aa178b49550007611456b0a17bee73c1b55cdb1ef155fb7b5d9ed605964c543d286719ca4438f2071480450bc0c1cd44bad920313ecd3f70f6f8d78f2a1c5b7bf2c4b23bffcc05828a5489ea0a4b66e8190eec9120e7381d824cefdf9792495bf7fe1a6ebeef23c6af070b56b5e54cde44b7e507115a8e4f8d1d4197fd2ab7b8795bf701831f1bf0df21b3beddd2f470765a529a23aa8c4a755cb3d898d39031065f6e2bdc9c60894f12d1b79e4f13d23e79502775abfd15d54a42c59c48306ef79fec4ba76b191f4f43733fca00514d6267367a057c42e5578bffff741ffcd0c79201cbc0ce3045baa9f4241fd14809d5f32bc178bc709b6c7949394efce4b93448408059bd4204ed5cd48608d7287e692e5e8488765302fa504ccd65269f541c01086142f4a715b6a1f2fb1bbac3366d91a6900b3750e681f015256201e1173a2e6dce48bb83c114cef2bfff8c564b3836dbb0b59148274c24a041edbbfc4ce336e9eb51391ab30afa1e62d47dc11db58aca8e872fa126d13eba3729681e5cbc4b10e5faf32a7e84b8362d155a7a16f27af5750e5d223e4a004870409f02d4255973875c533f4a78b0795e813334319a7a3a4f36880a86d46f99b76b1814803f3279343814d8f980e5513038ea0f0461d9ad718afa5dfe8554e34711a00621ea67414797fc1898a3979297a8bf04e502e119fcc73353deacb4c6e910ef8ae2826767fdac30b9f4fb26fe93cc1512a0c1c0f055335f1d1026ab425e80edbe137c42759755ccde3a703fa7f8fcffe0eb0f9219bb9d2d571f9219b23711231eb48d6421e3e6cd57e0b1fb99473c415df767618026d58a73cf1f90054c681c31988ba9d4a013e1a1cf8eb9015a32c62d117db16f3e3c7424b52d8f75bd54b99d9ffe024772c10125658e814bd67e8db2075b7f663cbeca7b8b96573eec67ecc241c2c5c7f3c1e837c2685b5e733cb21201712ed0d9be67702c5f56371444fb792f10d8df6cf3b28b55b950f98123055f97c039883102a48760b25efe6c70c94ec7a020b252fe3ef5e5ceed9877973f1d7d17ae1e301dcd44822c72128ebcf149f57163901081c0e5a47a23556d88ebf51fec757f38b87fe6f68cc34bd29bb36fdc77c19e01feb061c8437bba8ff1c1c9cb8fe77d6b0bf9dd933064f2804c4635e6c7f36afa1aad138523e0e8c15d5bdeabcd68ece9fe4c06a4c98df6918dfd657e030838eca2e080443832b0703d44e454e09d0acf0d0df27e43e3f9df0a003f05d7b49102d63849de00803d2527b285d1f4f9f87d2000647663846af838b513824ab2576ec9d8e7100f1745eb3ed4fb4796142245105818d008429ce040c2376fada931a490f225c7297c58f0076a00f88a2f8c422eab67fa75cbfc4ca40be363d91df1f92d49b7bef20114aab86d3fb4c91852e833d73e64c489e44fd2bbe810f1d534e20bd7cf9fb276d0a896f5f3ae506a84d5f2831ed0c9de277079d310440f9cc564430e97a541df9188fe49b9abd8a203561e77022b6dd1ff96ed6aa883aee6f3ee00e132fdbc8c4c4ed23b5e7a1f052a803b2f052106d87bcd8940e7e687cbef6e19a72005b30762d84e37c17fe121a8846dd9325ee8df5e60bd5f30c0d3225306ff6227f06d84218debe3ee16fee70f24a9d0097a4913ac309f619832ded87858522f90ae60a84e01f592455ca38ae13ffcedcf3f14b3868fed29e7c405264d143e6704477c6824aeb2cee72d7cb8a22f56c9922b4552777833fe331cd917635534929f51768dd055ba8ab053eaff83c8265dcae994cf52b99478b471e97ebafad6f13ee52f677925e28c1742cd36baf0e61d85658e080cf5c26b86363a5002a4d535da0407a29ac5b5f8b4d730632f76e0c8bdaaa4873602bf275606813f53a82552aa44eac4bfd1a17d4639dfd3b8189643f464803781640a224b54bb3f0cecc8acca6c7196be52cd47bba012201af5a42e40d19e6f014617aa3f6306d8673ffcf12ecfc3146676103c33d41775b420e199f9a5ccd9e69f56532ad56d2f09da9dea36f59206d65e1277618b9f978836342374875ff278439766893276c298271612655093bf8df19fa8f5bea42e94337b39792813be84f84f6d91a7c22f52a86eb9605871f3d1a975ea41f42895826568bc51c4233e059792c3e9daabd2439c0e343543bef3afec0dada24458e63e369c6e42d14784b4d3d0f1a801d9c1f4d8d9d0f1ef112d1e96f5a188f9be74c55f00b8cc31466bbc07405d72e5f0907bf6f05a29c7c60e0f497f7ab2342f9d14dd82bfd0a7ac63767b27d7cada2f29aa7c7afd3e4a0745bc14863c4e973e39679bb1d016d8fabe7fcc47665810663c078ba646cd126b2824b5f2448f194d765f22bf6116073980a984ee51966eca29ddebdeb045b9d09198af0f4b427180960e4429870cbff7054e9ac0118d663e7d352393243698f55b613d8e00965438fafb4e9f2756e80caf90243a48d2b064ad4d9c443c77e05024cf84a68bbbf69ef0241d7f04fa566cb719ec6c99005a9ee89032eaa23d93f105b0c1f4ef96d83d85998efe6918bec970e158f387015843fcbe7d9fea1e748ed5ca08c06868f6649363d86100074b6865f508af811c94247fd87462fca1b5c35763e21410c705c4b1e07cb081d632943e7c1e3d4f2edc22d698e85ac112592740e03c469a7fa8875be4d92dfdd008549ff60408f9866ec4c6e9128ba031c18285686c5ef6fe31f3ae5dba8b746b7d0ad7b2f7c629fa0312155759620ef37f4bc6c349c6b46087f91fa31a4fe51583f1138c7908a344b937d0c900f058aac9b2dcc12c4e90c093b5630f462fd1a8ba4cd5251a9d91f5982a24bb3f9e8b42a6f1d01401625535d7afd9938fd84ad2701a86c81ad463c49b869012f2c9655a7a22d8a786a2c1748dd295fc289ca0ab2fc0f80e16956048c51de8d5e1720a6b4c2ed0a824b55c7f1bdae0cf278d490f0abdb350c848b88992a9e456793c853bec5d0b3623d693f65e9d12d0af4fc2519e90b5e978d3c9ef0a28649c16f6609169ddcc044bc877e50e9102a04c0570080bc99533890e0c2fee72fc7bd9f1d2ab90d079dec7fb12b43a4a0579c7cd26be8cc968659dec653c3132d026391bd139d9f9efb71baeda2200c77539cacafd6dbc9d3ff142a6940b87212ed03900e936498010f77580b62b52e6e22a2b74dbdf09535fc7e1b2c33d454b61f7fbbe9254b46b58924427e0e36464f0985de1b153adb9ecaf06b007a8dc6c5ab86e7d76c266a428b10ca65faaa1127bfbbb8566f29a697fc3178a3a9938d202ae7480f78dc79fd8eea2d261a56c17d609baf4fd5195443db72a9902abd4f488354b660eb722ceee9cd58ad881485ede5314cf48955a82d44392d8b511dcd5d7a6726b4bcae7825808c704e8a880c892f607543711c43a360c747b486899a22a731940e582c34c6746e476873e5d6ff2463a1ad7a4d266b7bc4a63843701e25d4ba789ec91073fc655f2e08ecbb91f32aeb746a37e1eefa5347ec160912223fcedeee3175728a220d08b2c314cf54569da8cf3f39032f5eb6b275c849b066f0e0ca120c41da2907fdaef2ef627e0d12834cd2756422aff55bd4bb116f5f0dca276489db87550b1e38ed98bdafecd72869bfab0eaf7d114eef5e337bd7c10b9f2c69d6d764bc7906e421edb6ed9c9ff06f58e34bc004901784489a71e00ec1d90b72819d3b55f47922a8ccd7d4c9d4f7f36fa2a196cae1998c99a9d123743b57110d0e3fb0c744bf894287a627230b00a5cce0c0db8add0b690d1862101b07e219f1e4ea5eaf4ce0cc89f65f88f078c974926819cd36804291b8cf62b69056c365ddf717f0864b46f3c7ed7e614af9f295c9fc7fe0eb3e2101412cd38fd9ebf95a7750c7ad60683a26f876e69e33a03ee7887e4e2e6e54dd5d048244aba73607e410c7ec899cd2b7b50d51f75672e90c143c63f575e644b1d6913df6930e21529778b35ec01743d95c099c76f14ed0ee6ba80b127a25697f5fc885cf6f260d299884730fdbe5e7f4b51c270b9699b5dc5f4f8eedbc5fc85d33cd343d455c3daf0300a6dced162ca522b157b3d90c82354a9778ba9445d89ded62704278e52beef9f95e7ddd25aba3afc7e47f3ee878de91ee837acab605771f4f5b72c1afa40b76bb8635310d56a2bb07a99820bf686a34e5c8ccc230c8b4a9b91e46a096dd85e16ecc40e97e19f0959846e621a4b72e5dd38104012da037c10d8c2993a94960c2d60b3bc8d8a09de0ea1e7d2b40b26c2f1446e7bfe41aaaa1878e1da14fee86d9fe51b35c719e1de5215d78868229575f5fa3b849c6fea86a2a04f9acfe106ef670e0459d044fb510424b82d3fa3ed586a052cba5356949103e945cb4da21c0ccb16b6542c2c382ef5a2935a1e9fda1451ad5907f10486f4060afca2aa4aa0aff201a49b403454d7cb4d29802884986baa3ab96280878763b51e197ca4c659d704327dd8a966c10e969ce02af81411f5968e58490de59e730ef83dab89a3a123fec9cfc8af360e27a961345dbcba8f78e322cee41079ea15628b1c382e9f765e17aade169694353d0956d87b0387bf9494f6c3881d58ca9b9558f0bbb18082d4539b747675368823213d496807fcce060c3efaa8b5b5f6abd204ff9edff6c6a1c0584908cf483165a98865e785fd0a96556c27d708bda67b057929d6d4d6913e9d64e90838b92a86addd526a9fc0135d4c162f216c22c0779bf7b0e0086e014258185b8c2ca2ddbc29af6c7bb2f3f39fc5e77680c6e0604467256477245307b8367ea480bec0c23b86a35c937717f30d3dee87a46283e75f5f3f78c74071ea2764f53f66b893f123412be41b12f8efcbfab0f48dbbbdfbba5f899d0a27ba656ab3d4f16532372806f5197b9ee60dc89b69711f88997c8c745e08fc4d9eccef93a7cc31576ea9cd0670e2e017ac84a8b2aff23b3b240e54e27046cd469a25cd2128838e8bb54a218ab7a09e0aa409576d8de1d68c30228151b86ae33a215674cd059defcde2abd498c71fb1a9a2a1319776391cbe97163fa15232e47d7c6508756b25eb81563c12b17a3477eed186bba073571c1e766e54bc79ec58a23b7a7f8d611ff75b081659b59a4486ff4518f571a8123c6545d17b200b75618a7948a703b46f375837b33f3c810b53758ccb5a76b2859709bc23da25cac032c4153fe1f3e1643018b41e733f285adfd6c392ae62d444f98100b6d22b8c3240d21ace2d1f71870eaad62cc139208548d7739920055a703de7bb49818faac984b8874c9dad3e61bd2414f95ea476e43a4f2236a65511b430345e4eefca155816af2bc16229f41cef905677a5e786d64a790bd1b2ed61698b4f92a040fcd5a896a2de9349739d5b6ad2595e028ab0ea570b21ca1c754ce95a6dab084b4a70bf18f2c1953d698770708b1c42def9becdcca4c06f3357205460bfcd901a1a0979c4dab3bebed5bdf4bfb2b7dbc968adfa08879f3cbfc96a285521c4d8fc553eb31dd84afdf382b4f5a86dcb40db0adf644affa4387b996601d657647be5d384801ef5d841da65c3fc065cec94b333d5ad8a03b89db3ec1c4c21232bfa899cc079ff59df4fd78d7216386b88e462fa40c8ba7b4a30e61f0f0fc8cc4b73cca3fa4eda9a84de6444ec58e6e338ec1747fb15ec40afe8643d325e3fd6073017f0855ab0d994ff728fe242112aff087133da467a437f29c96d0f5a9c7d5f3e158a7c9384d10f4900f015dfb1096500586da61f10183b49188971c27e24aa620a564c2128c828653981fc5e9f034e52d9cfe6c6e222d50c0cde28d2206d19f723a42f88524e7b98b9832c45bc4194ee070df3d9081639f5b91a6811e9cd52025d2d259720de8c4529f311111d911e2c0a6bf4d5294e2841b819e5d11b043d4b0844f5d6d4708901197b5804f4756917588b02d97a18616f43e1f88658cfd8a863a01ec49bc3c8c833290876039da4b4f7d48d68bfa6140a6e4c22f6503d5b15a03bde980d07cf2cf6a4c6cff391abbd24d494e7201feac8c3c4668fcf9565a18622682be0884ad162589b06f95c288ed290569cc527e5425e31d2a5bec58b53cd7ef507840a4162e3be4184a3f496f75049f55a3491cf8b1a1ca017699fa910125cf93eeba2bddde17604152f9d368bd8cc334130f94bbc70f88b8ef9178332b48f8a4c38f60c21778c08efaafc4850e0b819e68b84106e6b1fb2c99cecf181dad6aadc3db7ee7a84efe5d0c9d42dfcd1696a2b7d0eab3ebb258768ed961395576d5e84c958ca2112623875b7d998185b5844901b6a1609297410753f91e9a94361cb1617ed19b9f8e272710a1ed0981102a04540872ce7765c9db290be76af87d0efb2b0aa928e85a54be50626b6181b9ba7526a7d45e4ae8aa828d91dd917ad32c319e5a0850abff1c4c8f2d690a0fa46d98c299e91131279ad55fefd96a6031b728589c8df4c3e097568eddf76c40a6cad256d3447942e4b0218958d2363b3c38ce5b6020df4ccfa1ce2fae3892b343aa84251d1ac480f4d218dc481b3d23c49036408269c428eb5c399b8696bc079662b0c143bc562840b41829860738d3ecaa3092aa46b772cbebcf497101da277be91c042174423a6a7538368083044c27453a7469c5b2ca7c35001de8b6ad60d2abc0b3015a1a2aea46b71af2f0509e61201830f9aad4919e75c0e9aebefbf58ebb7605e942c6b210cf9129b434b999f4074a66249975cab3c23e9dfb30db820d7e629bd8d14adfb0c32bb144d2d2fa066ba613c699c469b90ace8e6d38040815ea69e575b1bc4de766023fe3b2b842a1a7f77532539d992f880725cf03767168c21ce1f4698e0cf5888c255a297731c9756795c5cdea96f97e6f28a741e310dd0e841eeef5debeabc71081ae5cc119b4484b5ac841bf61cb3da27b553f1db4968ef64379c46149ae56159243910f9c30b14c9cd1e7196a4d5bf18950333e8c7622a82d9293bb4e615aed431b40d7cb30132fcc8b4fbc68b361599fdadd228fd701ca3f44a8538487150b9a543190867d0c3b91bceedfb0156f4b020500a02125aa8a7766662a41a32fcdd3bb21a58d94fb69470f37f7e43585b0bb5450c0c9da0b88e40df21e3a12e1b11f17e223ef98829854290c5eb9fe265f860c3ec79ebf78a6921dd743daebbaf151922babb4d43fb80164937be03651dad2692c996fb81bd8ef6cc7b697d9dc47b3282a07dccc95014ebd3749bc4fbdeef468de8a5e9653a27464b4fdade2cf8daa1acf0df840266549205902376a65f295018b5aab2637a5362076aff10cedfd0d788b503bd09413b83b476e06510b422d825c62c3870dfa33aa514e4e791f3b64e293f3451900e98c5807c9f844cd57607d89eebbe71a70b85197b206ee6c68f243809488281bd00ee03758334d8d1736c74e7de7c46c1227f22c4273ab16a1f4423211550f8e96b7265af7359478ac550937c86cd2ef4f3cc2cd6618451f9c5e8c01a879223118ff7e499711cdd1f0731b70fdd7b5739cd9897498f716738b038863a50b25f5c6150c27c5536615ebf828578a29d23adcf516f836e14772f93ee6bc694f69a845f91b3bd81333c97c907c8c885822518e06fd035ac09e05a7a3706d62aad3466c923578a5746c79041029f45f99f04d4fbd003bb6805de9a8576002867b3d4d4a6af0197734baadd2ea3e903aa492167acc9259f227f84116e45d529279031316f794cd529db374cb3e59917da750ead0f3b8e9b68de0436595ec1a214ff3d37dafcf1789c65998c049722c5a4d95db7065f97b69a7e5dd57ad1e6ab7f8af21d4d5f5dc042aee323187c7e4f1d82ce11472fbdb1e2f978027dbd16940dbdff59a1eca22147fc79cf57a163a8e877d8723423e27e6c6eb13fd7f68a5ecd9902e38d0b9e6866cb01c3bf9ab89bf3160ad2dff4e9bace58f929a8676e509a2bdaf6ff9fc27a8b78971447af602f70e669ac636e62d715b541017ae194964ae5c2dd7157a8572f2417c9b89af50bb9370e87986bdf96b52e2ad0469dd3db86bea32df576404da3f3c1f5a085f7be512b24e0045e11393be74f98d2660cd5c94589360f152af1cd8a46e4320d1e885204200994515879d601eaaac3fe8c518bbad5b893b481fa43261a3cf89e14b9e3b8a928055b8b53ceb6b5e86bbb20c76ae3d9cdd002078952ecd4b89acfc3465320d6c75a7cf815dde49c3cab279fe8624f8253f98cee7519998059f6d514bac27adba9fa7b99ea998a6ee41b3631b906c532d7be0fac9f2ed29c31c99e9f30edd132f8df2650e7aaa162d21e2c1e4e2e9ea81c6c085394f7b9d706adbf5d3f99a0147e9ac7e4070624bc6add5b9f21eea422ecc48ae550b27ff94322d174b4e4ece165ba3c02b75775a746ebd046b870be555d1b636acf23b9ba4a5d7fcc7c297fb6c17356de085ba43c28208d1aef0af1488cbf65337715646a7f23381f54024f8bb9bfe387c422362ce92af0e2e2de5ac1a84f75137cd7c66ea4052981ce51a173afa843b8e7dae610622f50c51756e567645d189fdf3a5fe0fafe1d2c56b11d531d62679f10c61df024814dfd95524789ccb24469ce1280760a9bd26fc0754a477b498fee0a81c53ff1cb26ecb5f33ddc867d0fd12a41c787a5c5919e0f25cbf221d67be6a12a4b05adf4dd869befa1ea453723a4dde1e3796f2aeb3418d33208b9e8923bbd6a925ae94504a98c48b7d6127a84cc4141a5161136bc54d0dc5069af5416d383a8d12783016990d706720707f85e8b4aa178a726328e9d5b003468caf3b8cce020dae4c7196cea937cd1170f3a4049db8906257e6808ea8e0cf16051474aa6d5db0df643121c991cbfa7c0291f5591b572f3e8fe36df0a72cb4b6d9e69db7f32a1b5fa21f30a99e7742c2ccb4a1c850e19cea7e11c394c178d5055d15c0b490cd15980b97082a1026438dfdf962f14b49edc5654f3ab2a972dbbd0125e324691b711cc37b9de1445ae644f02e4a618a70248b3232afbb332b58508b7068734f523b6cf7a49211e2be59f1cf3bb2ca8b77f891d76fd3fdd820ff9193a7a5bf067e39d55814119920b19a3a8fdf5434fcd901b8565257e60e404ee02617f3d3565bfcd90f0f16a3538d20c002a7ca78580f645b75514ea4bb5076de34a1a8e05657a89830f40db422bf921d38aa287489a3250d922ec8e620ab0414d48cafa09e28f54a24ba82ba30d37174ef53ab0249f3759cf608797cc14c1ff88be8ab0580b8639eb8fccbe8d4eb298cdd5c6bb4d6473024af389685110280d6b3a39d3395132b120482b223f1040bef91ba9a51f9fa287a49ba5a13fd591f6bd88d3743d68a7b9300a984e0790aba471a66ffec552c23ca2fa118d6a5b987910706cbdd69a486b7bef9da44c291e06fc063b06313186d8f7c3c418d42cc5c499c730f39eb731a9598a7df8b11e91490d8d09bc813071e63dec391613675ecff33c94f0610fbbd94c883d6ce6f5d82eb4338fc77e3e3fdf6d5e4e9d836a937312a15ce0d7796b42a75befe89cec797cd338f43c7e3d3c1ff2bc4b64eaacef1199d42cf57c90c8d43dbdc5d455624f55cf5550f3fc27edecdbce46a82f7fe622942acefc9bc6d7ff0c0afd7e2ace5c54caf23df84da38b09161969e8c811f5f36a967c9e3ea55f7f897ecd51a7599b4f4599a37f934e3427f4d3c9c70728eba7be8f8f9028b77ca65396a8a5c71f91871db25ece66f5f4fc4d6e053d8f413e7f9b4eb29757b336e98ea74e198c424bf5652293ecd52c057d159964a20cba62da216ae95148ac0a9fc7f06fb24d28cebc6f1a6515cff3c823ce3c51290b4379393983d223fd1ee9f37cd0579149cd6c845a79ceaf6d96ea07894c136ad6dae480ac07e5e5666dbe8fe5599b50558c21776380bd3883127bd8c744263533a5fa24f0584528de5698383ef85085c33139c9317c2cf561e26c89be12cfc77efe9134421ee7135c94d8628b34c418b05411479f8a33a5faf4617f9b57777a5ea278ac17b35ed4accdf7aceefc9b0775a78735e57856334bd2e64472f3363c6b722a7cc970b3a6356b73fe043cdea69607d4e452480bca44dff305439995eefa7759647fdf161b0c7b4e203ae1ad714ddabf67ffd30fdcb3b945ee98bbb9bbe7c82f94f6b21074a3adf0e94d2ef2e9799ed771e9ba07ddbdfb29eeaed5f99c1eceb1621bd778e6bc5c18267415f8caddf89c2012286bfce0d75b1d7716ecba06251465a2972ebf2392329162cfe3b96e0c24047ad51b912bff25b6d0f7babeeff55d650c14bfd7ab07cc049e87895866507a847d8f30d1a98e3cefe46316d86b01c76623dfc76c8f12b6e4238fa885069e11f672f45eeffa91d9c8f779ef1788e27e1df0142d6575326d3623231aedffc5535cd77b52dcaf0396a222287a9ec8ffe01b0aca2370ceb682f2211441d99c70b6d4bd7f27fe84e2d177bd7bcfe36ce9fbee3fb1136750bed777e26ca96302bffb9ec7506acddad6ace1a6d3cc9a35cb238fa0e5f1850b5fce3557de239226614888898a614191b34979141027e02c9146e825411b13fe98f902ce0e428408792e4fc1c9f2469d2ac8d00a3206196974e9fe66f7c7f31596a5e5237b240a595a0d4ac1acae7a66387966e5b1362734ab2bf975df045dcaf3bcc5988d62939a6058c3d8e7dff74d30ac611873a344886be8c8a51131024274a402b18542624262f2f2e87a8c6c7f934878a40271a344488c687e3c5fa50dbdfcbe3b12abc2fa0eecb67d31900868439a529425b3d6555859ddf7816f5b625465456330269ecb23ea9ec2604cbaeffbe6ac9d6d09cdf57d0814ab955e61dda615c6e4fbe073a254ad8dbec21ac6c21a86b1ef0b6b18c65c9fb4739c9ddd765fbbbb7bceecce53745dd775b3737767263289a6cfe95ee7eeecd2dd6b6766767707634176a89c6efb6e1d13cda75fdfc9cc36afbbdfbbe77ddff7cd2c14fa73b9ac9cd057adeefef96466ee84be3dcf33a27d9e47f43d337722d3917ddeed664fe8e3c3fc7d9e6ce3fbf9ece705d5cfab554be8d03c2be4791e1da5363e77f7aeebdc3bae1a92a9999e85c215d84c347b78320fbdea6ee544ea935851bcd9f9fc1f9d4fcff33c22666666cff33c8fdff3c0392de3d073cff33c9b91e7defff03acf3dac28d2ea63a2d9c373cf9bdecf6fafba572d71b7799eb7867d8ee7795ef53c4fc9ddf0bcce465d22129d7be7eedea921474ee75e97eb72eee5d49023a7f39c1a72e47877c7ebbcceddddbdf3ee4cfa72a7b6ad7aec2a3933cac509b5867b97f32ea7061b723af7ba5c97732fa7061b723acfa9c1861cefeef8634de66e29bdf33ed0f5a2151663201893ee8576b88e3aa52831295a563c55575655c5b2b4d0482c8915e4f323036b4ce94a46c124546df3925268e41ab906284868c7acc7078ba1c059ce63636267cd28a50965a5d34be2244e268331f15e36c4c34b7229f06f422e3f90ee8582e72098211e5d7dd14a5f3c916a1f4d79db73b7aa575de5790ece32b14e43d2e4c7608d85c5a4f301c164566214b22614d4cccd35726b4b6e493bb8de9a503cb69f62ed641b06eba86e2385a6d7f41a1e3c66104827336a424da85966464da8324ab3165454b7fcc5a5eda6bae53797f65475cb5e5cda54d52d63e0d2aea2bae52e2eedaaea96ad2e6d2baa5be6e2d2bea2bae52d2e6d2caa5bd6e2d2cea2bae52c2e6d2daa5bc6e2d2dea2bae52b2e6d2eacb8b4adaa5baebab4bba86eb98a4b1b03d52d535dda5e54b73c7569bfa96ed9cda5fd4575cb545cda6054b77c814b3b8cea96a7b8b4afaa5b96bab4c5a86e33b8b4c7a86e31b8b4c9a86e2fb8b4e154b74a2eed32aadb2497b619d56dd2a57d46756bc1a58d55ddda2eed0c54b74897361ad5edd1a5ad81ea16c9a59d46757be4d2de40755bc1a5cd81ea96824b5b8dead6c8a59d55ddc62eed35aa5bd8a5cd46c7e90ed4366ad835f937effa34d28fa113dbd857fe38f2a3714d5862608241022f5c89800b10b0f28016aa5071000b2ba830e5968294063060010a4800020e8082010a70020106608200a204000a00964a20610425114200e183271e74e08483264c36d060bc4b32c0e0022549922cb0211d2139520105468cbabbbbf316a28798b28d36ba8d968ab9bfd79d06f6647ef77d84950662281379defcbee979a02cc2b48e91684bb848ca2ff2dde9b74adfb93fb826ff06263523c9bc2542cf13c3252c9b4598d6305b9df0f6dd298e725ab594cdb2a54b9fddec9cbae1b9d7759f473f57d7d53bdfc117ece592b4a63d5c84f2e7cd8a48dd6354bee47c5a292c84d5a758aca7613c62b33b9f863c3ddf13fa589f9e1ff1c7072802a09f20a2202021219a50d08e1db51d42329904b21d43434386643c7810e131349b15cd78f4e831418f990f1f457cf480000223087cfcf861e40704ff14fc0f6b2bb02f8a47441b410448221089888e88220002040908519020b620408408b14048101a2d8926a4564b52a349208112096a43865c304402cfc31e17ea2194ef44ba6ebe5b90c890a20c8a883c4d2075e70445628a4c51640228a30b1815f912ca77235d47c59d6f04340a75a0c0df29303255010554472aa802c991aa232456201d5d6143c2c2025b164916689124690b2549b8b8408915061774910106185892811777c99bf17ea1c108c6061a84c16483ab264cc4e0a0c9184e3820a30327703ce8a08c271e98f1c1933340f8002b041032204208682889a0811194d22061840d94400207964a5003004b595000b04600a0b0112500710410458e0902e8c0004c6883000370e304026815e084370c5000385030c09c03a0400701078823010890430109f0c00214b0c58005ccd10006d491d2003a529062e796c207a6dcea50610adf5941051c0b2bc8e0001666a0e2001aaa50c9d242951a1ed082162b0fd802012b4e2e40c08608b870c395087079e14a1709bce0050609e0c004430e31306189e1cb9d4f9bb0e8806bda41061c981964e0818619c264a1414c0d59a0b4d4d0c3162d639cb690b1c1a9cc0d36f8c0e506335db8fce0a54b140e5e80c80187209e7210e2cbd3103a7c39b3830e4480d9010d0f6072617828424c1823a0c41cd103549a313da82133660265c820e1439935667c48e207331488faa1024044b1090208258408c2024308b1c49921da107186093444349143e34411b9278c28028a238c88224de50976e823604de6953db8b0af144770cb59344111232314547004c91192cd82a4244a2ec020832577d46003264d3870d281074f3e00210411944620a18425004009401401983000029c500003a07000042440010b604003a4a4709ba2c20a2c38804a95161e6005022e44e0ca0b12808129062c4d8d6b197a86a6a1b3740dada5b7b453dbd0373497eed25e1a87cea19ffa4bebd03b3498e6a1c3b49886ea1e7a4c93e932ed439be91f3aaa81e8205a881ea2cf34118da6735d441bd147749a58db400748e5f3db7e5df03ba5ff7bf01381aed755a8dc29ddbbc0fefe16865ba1fc39e9eb6fe1ed34d7fbee4b6cc1656f54ae07de1c67b3d96c369b4d4a29a59457fe7dd3a960a482d17c158c5430f2e20ca83be4f294196c5ccae35364bfdedfacb838658a3f089dc856faca96b31bec9fe24dca7ee3ae053333b333b3333333773a5871d74d766766eebae7ae73f7ced9d9b99b13092396396d8eff9c57d8b123478e159e2a030e381f04255127250fa919d58f35c5c645b174834428aba494a449299e73cea9a933da14c599a2443690352997b8a8c2284a92f644d82f9334d9a0d1cb967064514654196ba8c018e2f6b84cf585d4a53c332597f7f425fffb66dfd366cd639a3f452699d734be8d041ea9c87493f9df6cddc86307fe1229edecfb28b3e67dd3e8b2b34f6c81041e95442627de38e37f5d89b3251c55c3429b20fff54bf3ebf357f92f91a9aac55907dff77f4fc599d2eb674bae7fbdabc78631f95cbf444a291ceed266ee1903c5f073d92bb3e671d67cba220c2eb25c0f4a1e71185b9491483d4e0e430b2fcd9def69bdfc4a61dfd4afc6c5a57e98c8c4d474a52a8a94ad2b27597c05fb259e87f53ccf7be21253d087df34de786be61f7b1ea59db9381b413eeca1f407f7d6746e3fe801d9858aa83454fcd0c595623b95e924ae1cc2ef6f2bb6e02e1839a693cc4ef2b054124d029f3c37d9fd6e61d79bb027733a7d2394ba231df71ae7b3ace5f4cefbc029394059baba653d20112e92df31618532d1cda9cbf61dea896aa8eb346957234e727d4f100c4399ec1f8b6fe7248df62f9365792e97cb45eb64e2ca2a9db0b0b0b01a8b7e7d02c13094b9aa8bbe948934f4f2a97c1e6b2f264549ffc65b208c8a4d66ee36f5584fd3794a79c8befc59a59bef6f9c45c5f924aba4d4d02f99435686269c35d9535de22cf62c4536e2a409e34002512130e8a78707f6469c247b17dd41bbbf4929100c4399ec9f8a4de49589b3cdcb29ec2c4993bf43149508c127e992469c249b8986aae20a893723d7f5af9732834420d187b3c450bcc9c498787b176751795d4fad1117b9c4998b612eb1c9bc3723f7c65946f6d64d5cf9df7472dd1b67dd8c48ad6bc4d7ec90426d384141444e6611071c4f23953858a08ed448679d39b8913a9809e046da51255181a7917a5a4f1880a30b2a46262c3ed6185922c122d4441d4ae046ea22838e0dcc31d217951719a81a29f522aa0aa79156aa3590801a29ac8a306f9c461a0be3ccd59b3284c88d3484b2c269a43d555a5983971bda8cd4a74a2b6f0033d566a43f55daf6a2c50a6aa440555a2639068e54165b231316a6630c183a46352278995822c1c27696787a625433457653278bab910a0505350b0d6141868badb1a9b1b49c5274de2a7ffe94190265a2e99dc8d414b03343d588e5cb1a418944ca0b8437f082b3366b73fe1499769041c3184ea38bb44e62ea08ac91ce9601ea8ca7715a1e5b76179f349ff2146fde688db4e1ecf0343a9189026a6434b49863cdc85ea8c1658db4ab9de53034f084d548bdda5926b6620b17592396971458d3ca664b1dcf160b6c8d1dd8d9231ba6781afdfb0ec8a00b041f9c48af07c16f4e127611f9a078035d6e6f4d13c6840a757710743d88f4025dfcb2409dc4254e9d51c575f166b3048d3450c1e1264c8479b1dcef13dfd288e6cb3a21e850d0f1191599e01675443ca1cb433e095c354a8309e1711ba4c72d901fb7444111ec1087ecec7dfcf80181f511410f2033213c6a6e8786b89515b9dd51c4ad9091ea3688e5d1e74a96cc9a5ba0fb592512897c7aa4bafd71eb73ddf6b80def74cb93d434a9b36c01172555b754092f91ed16bc605a2592e6d6ddce25d52de0a20d24136fe2512d0e40f75707b5031813ff396b375b22bcd96c4be4b741a844d6a407b127e107defd810f08402108892053e2e1a30704ffc3462012050122a4469380c890a22213185160a40224478e6c481624495282c10519dc25e3061a30e1a089130f3a7802c207212889304209242c410140000410c504020ce0040314a08b1214aaad8b94038049c182ae262500cc6d0164a634a08c0af24b8187156a2b619ab48069720aacc9df166d6156a86efb884b59a86edb884b1d50dd76119752a96e3b776995eab6d15cda4275db445cfa80eab6cf5c6aa5baed212e854075db425cea4275db415c1a81eab681b8f44a75db5197be50ddf60f974aa0ba6d3397c250ddb60f973255b75de6d218aadb26732996eab6c75cda54dd760f9736aeba6da84b5b86eab6c55cda3354b71de6d2a6a1ba6d1e2eed2cd56d83b9b46ba86e7b874b5b4b75db3a5cda5baadbfe72693b55b7fd7469db50dd760e97f60dd56de3706973a96edbcba5dda5baed2e97b697eab6b95cda3854b77dc3a59d4375db365cda4fd56d3b5dda5faadbde7269eb50ddb6964b7b87eab66bb8b4c154b79de5d2e6a1ba6d1a2eed30d56dcf70698ba96e5b864b1baaba6ddca5dd4375cb772eed31d52dd7716993a96ef903977699ea96ed5cda3e54b74cc7a56da6bae53a97f60fd52dcf71694755b7bc75690351ddb2072eed20aa5b96e3d216a2bae5382eed21aa5ba673699fa96e79cea54d4475cb705cda68aa5b7ee3d2ce55b7ac75691751ddb21b97b611d52db771691f51dd72072eed34d52dcbb9b4d554b71ce7d29e4075cb6c5cda4854b7bcc6a5bda6bae5ac4b3b89ea96d5b8b42950dd32072eed0a54b7bc814b9b4d75cb695cda4a54b7ac814bdb02d52da371692f51dd72062eed36d52d635dda4c54b77cc6a5dd4475cb665cda4e54b75cc6a5fd4475cb702e6d28aa5b26e3d28ea2bae5312e6d29aa5b16e3d296aa6ef9ead29ea2bae5302eed0b54b70cc6a51d51964a18810a19618a4c0385301207ccc1085c94c025acac586a49c90acb8c0fe8a787ddfaf77137fbfddc7d7252c7493ccfef7152ecf93f4e82d5245a39097c7e588c87cebff99ddd9dde9ddf9dae3befbcd13b937c7ebe9c9c14fefc0ae3a4eee7f78909bfefc702f9d820a11db2211eb31e3e20f8c145f6878be48716c8060971917c98ddc145f2ab95d9211e5c24df6567b6870f2e82808b7e70513847e8a325046f70ef7c6e3e746df5d33365403f3d56640f40a1191158055cffd9e38621c82008be3b7844d63e6ce3e9b072b281067707ef6024215c936f346b42180909c968225da6f20682408420d8b91e04c5255cc27ea3b9c112ab1c6067c8807e7abeef6fb0ef6f3c975fc9f79c844e9077f0e922f2db0235e9a16fc810280c7f5ad18822b04cb907082491be9f3d74a875228f1c4ff4ef867bcfa7dff7cdceeb3a6f4eb71fd0f7c942300462d9114a248df6830c30743a5dd7d3764f2783a083a1ac7560083e4f36e19ca1ec3c91e6855606e8b5e7303dd91e967a267c61044366c92c999925b364e6efe9f1f1f9f9010262212166e6f7616666c92c9965b62b0b7213e4e60aefce095f96b649abc08856011f3d61da74226936224fe4d195bec2e16433f7a4311294ae4d6f9c6d2d1c15a564b9137410fcc0cfddfd7ae715d40ae378c3f7e5ba9e573d8f525707e5d2939dfce4d7e5acec48a4be0265cf798393389136f4ec2b27b0cec2ae14abb4b4aa566b85a083134b6ba2f181adf9665e4d2bf06fd3ca65acca772b086a69b95c1de875567ee12227a943c3d045dac0a38cc2418eb9f3a5d60eac500d23358e6bf3d34469219bbaa184e2ee88229c5ef0d1f7f367183c31506792c1488d9bb54e72a58b4c99a881099b6df9ba6ed7755d57ab7ce224d95ab62f5b29054b279836ff4a27e9ac2e327f5291c4c69dbce5e562d157f24a369cc6126d17e1f7b7bee24ec6401cce09c411e1fe65681cae03c12f8cf5f490c964412ebfd86f8f6060da1ce2a32b9236e9874a12063e4ac2b4f936499b4fc5bebaca5aea22f33bf1939fccc9237927903b5f5ec934241288c5664a4581bbb2ea4e09e7ce29dddcf99fd7754f9ba58c755d8fd2446aad247cd44eb491b469158b6959595ddd97e5d13949def93fd2ba6e8f9ab07b29a5c4698562ccb0e6b66d20b8288876828fca740f4c9bdf4e5dc79d6dc4937438a14c82651a4e5ac349f226739cd473e7576935919eb8487e895ae2f670e7d49a35d87d59394eaab0b55aab2b623271678e8be6b3010317c544ea37e600e74f2d31c29bcce5e60cf3ebb84eebce032ef4c8c3febeaf6777cb29a79c5e85334ff7e979288fe6f7ed5726692e0508ca99c691c031c8e5a90e7820ce9bb0839801e68d335371d87ce1431d5f48b065482e6808301b000347ca0d38fe812b26cd89ef14bc9812238e1c3b5e9cb1f3459d26a82b78b89ac30cac2b92703a6850307903079c115b561c78c2ebd47e38a18a34e83c3103163f40f91cb20f813a1abaaeebba2ba400e38501e99b31a8cc5c5dd7652a33767290800b194d703953070b0d0c31856f8121c7240386902cd8042142881c5f1c088c1a0f12c82185a03d5138b2b429734689ab37ee8120564c2068524b1a566feea06163ab8c91d11b2a36535084e0652a3650c83ca1cb546cd0b02923ed0ce94172d18137f241f9619b3754312e6f5c5bc891f2b6bc19837e3d2e538959e2d2cb5462d208d1c1853b45a46933831923d6c861f485c75185c5962f6e8ce12285865167bbec4ebb42cb04be2d5f842133a9c4784165460dd7130d5da6d222cc7d5da6d202897b7ba32e0ca3967d6c847e792a8e5518278b2f0edbcae16a035dd6b0628d71d28983c5957d5371a6be08c3e9727dd3f5bee9d20f7ceec1e3846f078931263227c021ecdb5dec56e13bb7fb5825e2c19e4c97074d2d806fe5bb9ee73df1264d37d9c47bffe941d3ad12abdd7f6114c19dc738893b30dbdd93bedb2332a4e63fad4c3e99dfc4e7ac83babcce05ba3b0cfcacf5afeb5ca0f884ef5cff2a3ca5bb4feb60cba9efbf8f69a44d63bf27ce963cef9bc6177fb5209bf0065e998f2542975113e1105c1c2da5a858d162bab245e3d0927ac24a85b3a54fc9c927ce48e0d1d634468d4c3d766ed6feb6992e428544514d59dd7e6e28cf93603a2bd75abdb50667e6de9a4e63cdb937994576612c293d89bcac89227a0a2594952c2325a3726fa454d59a36b989c4e3d8df663a89ac52a68bf4f3982ed233694796813374fb659544aa61f5d41c3797cdcdb1e6c471a9141d32edb3c7749996c2658143ceed3702967ca8040c1d28a95388460000002011400083160000200c0a070422911c04e248177d0714000f65783a64523215082391381848510c84530c432110c22086102619320ca2191b5000fe119b2f79ec20e98583a718e11691fa39be5f84663d1e7d5568c5c2e90c46c61fc91f537bfc407132d6e8571cb37ea078d81a85a8fe08d532b182b5998d69013d9c71789771c5122b9c17527f21b526f5b4e6b465ac4ddf395a537c3198b9296b86b57126b6c05b3df56f9fd74c84817f9900714e928259802658f5a4ff6f9541ad2b84f154e13037523a695e9f2754a5deec90a13f335a901a3be75bd0f54a724f810c69536d4d04212658b9171312f131e35024d4432e96ee8ad01704a843c4b94703ab55e0588fa1e8a38756627c2b9605bb7c5a310961b7cc6c6e78494891b7c06226f1df093469c07ccec0b16e634ce30f42f44c659e1ddcde70e4e3946f8b495d6ca37752f85236b222e838da1db0239b2390acde82ba8f431446d84acb558c7d2889d50fa64209075818a604537fd45d2ebd4fb748845fe54049309847ada679d79a6003ddfe933419ef93dae1aa41667381343252e3fb92ce76e1491e6b7bacc8b7393f999f6259c70412ffe03d4f3515225a586a51d6feedcf6c36189bee722c5839181998b5a1102b6e411e603f7f0e7af2cdada2827c62e90268448bf44887012665473272323d353ad65e207044bff3b76984da6a5584a625ec990dad613f477212189e01be8c37d06c80662b6d2ae4e82c990bd296c850da2f6ebd3ee6b3229660410843389ce78222091d201fcbce0ae0a4e77d2e330c15cbf9babef1e4c62485c2818e097c08ae0b90b40c5a02d552c262f557b55b37ad1f6289b77dcc81ec3d8c4dabfe0870de6b9757b0a7cf1ad492d8001ea9ce71494afe960758a8ec0a4d180334b21db9e049b1be4dac63e01bac7ad1c96e2154ca89d4d63d0775dad7ea88266ddd9921ff03235860c870cf35dc2553f666e9f5a1a359c544021f178fb55e4fb2af9a357fb5049bfd32d771df33cf334f0fed50f2e765404037058271620e6312754c01d375a736cb9e2d193ea3fb8e1776a82a5f2f9bc248828593022cb73661060810d2b1ed123fe001af3340a59303ba729ce3c9ca6ae97c74964e9d87fbcdeedaf805999ba5a38d6a3507d9a0d81f747e7a67b1cb4309e6bd7709f4b39176940d24ef7bb9c43cc8c240fcab1be31190c652caecbd84b3ef5f8c071c7f4338422e878481383f05dc987019d0232ac0856628df9a39c756dfa50b696367b4da19a9c14636c2d64af06ef86828383b3810c10601af19e6e9e9a52e632edd6502a897339fe73e4ff7f794598e517d9a8980d3bbf67959b26054563f2c0a90fd2e6caba6eeac97811db36c4df002c306c30c50868753b90adf445a62d87c71b5df90056e6506f3fa22b9642237c7920c04f2ad66a1dd70e87efc0e440b2b37748938e61686ebcf81f62ec716c6a449420785d09109fcab8211d1932523a47fb19207ff60e606f1f0ab329a71b13a23da45c5472f9a860dc1320e71daa154cae3e1ed0c26f0cb99c080e91e746fa3f99c4781d35c713a4b8270a16b712e3424e1e4ac969caf2951c96bac26d3189f5db3db9b95d41d4b0d9c465954e5a5a369035256e239b3153a57238a030dd19885b3501f60d45fa02b4cf21e2c4079808dbb9515fd47f4894987c633d1ad70c06862f42decc13071533f2c63a1c685854cfd38493f6bc9e5349b871eedb7e815f5e1520a3f31f6edce2280bc18f5922a8a170b152a5624664c55f1bd2a8c718590d154b03d03371f2f34837e1a926e954fb68cdeddc55ad52aea3d67062c13655f44d7978a1483347967030a30163b86a010ec9a4da939b3b4cf66d5ccd293de65caf3be3f1e2343a37fe7fdf05125815cac8b55ce2a431633010d481c5df059d2be3de0718ec276d215b6321612428f87c7c4617cf6b56222519974dfbee97734e52b1a3890401833e45f2f9fe06046cf8b81ddf2be892545fb65119d7887e95a257dc4ea2640d781c59ffa767c1e10be6fe4da8f33798c84612ffcfe3548d501d4bf576bbdefdbf43fe1f77dd4c718c8f755b895c6365ed1dbad8381a20db3ce8325f4787dae2bd8298b08eeeb50c4b25ad4e44e2d97f771f81680b6ff3c468f26eb627d0fba81bf34dff129a0facfccf1b71d8bf35acc5a75775c4a98692999208fb8f27e6ac4337016a171b90f9466e4f8e9ff72e6f9e3907eb2f29c5b817f8c01a5e11bfd238ffda9aaf282e86f70e87f6e79fb036d285b5403785e019e3e9f019ece2a6c0e59f8bb2016025be3ee1e29940560bead25b3b381d3919cdd91103a32f03a6a3546e8bcd9115f960cbfe89ac14a099df3f3e7f5f3a005f4808a3d26d2c1cdb5f0fe3a6122687a55a1293b2d72b80ba563dd0b9bbd481d32572cff070b09c5adb6e4aa242db23c49688e19cf0c895b090a37c160276410ed5723ad5afa835b9f3d1eb8a3df8691871fe4795b9968dbbb4decd698d8726e398ddb84634e415354c3b88d2d3459d23bf03de538685e1807535aaf341b2fb70919a90adfd36d82e1a88a089da0996d824e814511a080054bb6b2d4ac78215e90654433bbb1b1fe4ee9c2064ade943968e0d4cb630296560a2c4fca83eab3560828230277eac1d61224ac55eee676f298149e6772b53266bf0d6b47359bd004df6a2c534fccafec66bb18a65988d6ac84f566e2a40121162c11310c0cdfdd645f69d3c7701947a82116e12a8a94ffb363bf0e9b30fef63c3acdd4615e567fc8c6939fd8e3950f0fcb341080306317c8d97d6a716da352a5de4ff3794eaac4a0343a42fd5db26c349bcd80bd0124260d57952ddad545980fea828cc28f0265267960d8f89ae3bcde8151e1812e8c5510a2c4fd21aecd6e6dd6234482f83a5c1c0cd7ba0f6d7a506b8a4ce3a609b4628c9e8a2383943995df99fef146ce42a104db1061e4677dcda006328ee7bc2771d29ece5f8971c56300fdf1d3242868c845974b551ff2151a8cb280f0cc2075b8dc2d8a5806c370d115a20a9c546f3e9d998b7c90fe3306f558c6454d207ae51b0a514e579f05553c259a83217f068c3997434c6a307195a4ec17f5dcf04f137ce10297df7114f4bfbea3baf0b8f25042b84670a94d90bce6dafec1318c481d7d25e4b155181af2aab2b8ffb1f4551544d5fa5e16c8141d30cb5fb5a9dd00fab5f9bb37bc658009b62bdc7b0bfaf34b4a4e8fe239ead0968fab92a73050ab64d521b0e0a4656ec944bb35138a1a3e33f369f70980feb26c69a124c407824ebc035965d114ef6258d81175d3ba17756db5d69e5a0b427f039c7640f8541b8e12123d012837a8ad7e6955bc2bc56bc5826a4538bdbeb66114e104cdb134b3e0e15d7f58978b85f5c5d556515b54b7f52c67b338e3ae502e93c3257c0babe0b1ddd8e2bf86fe995403c4d8de3a876b92a8821afe47f812138cf3252ec9be34b3e0a6e07f48f6d1b881316c97b81dab215dacac75b80e40552c586dd1f2ef997adccf62932415d645de4ae27ee25beddad8a34e707de5948c2d559fd4b974a0644da4b64b54da45f6288aac52d9704c38cd364e5a46a25252cba012a1c8c4fae605165e241df31d11be60f7f0d71e3c981f2298dde1ae60495fb5b2165a7580d8f3b32f35a587e4034709081a38ce88be45f34b31dd85232b2b3059b10b22f9c2c50468882d0ae025615cc473d4a14a61076380000701b35e8285fa602dea80850502bef6ae6535645d258bae7d3e269941d8126a813bd24bac76d018d041a6b7258413a49f6b8a6c3611da3c7547a575a2825942539373cf188d96a5e0852e9db4acf01b52c2c29ced8f9f71bd360416c4fdfa9d4b3c152d0fb220e2b12f1bc376a197a4093fd558d2adc3e839fd6050f637276a83d7758df9a3b784cf2492ed6b2eea56d769ecf287db1c2e9a0f453c65c746985501fd6ce3498275c2bd57d2aa3ed12517af954593c6169b794c812c29515866aa7465b4569bdf04a80da439d6e9f6ba7a21edaf63a7130b0474ad4a822d850f8d1553549038f049aec7ad9245b456e8abf8c9eed2c716794a016348594e0fd48f3bbfcfe84bf82f65e1503cecb947d8cc1654278ffa7237b67d4aa97853d04bc9a736629e693d794f6e43711d02220c05c2dcd5fafa8640181540f2f49453ce9419b8dee6cfa512466834ee9e7bb937d3102a504ea62803561aa2084f4ce4ce52010c1a6ccca3b54f5015773f530ea1537f5060370584242c1d845e41a20c709e905e87bde3b6935e3b32c46a951ae533ec7a01a1e2873ab8550d5801471ed35795dced4aaa8c1c312a83251d4a84f276d6a94b9aae182e0b7ea72b184eddd286488663154d12e1697b806e8b8a90ea150c392164183e32afc05733ed8292420c87173ce394774ecd0b032405bdb7abe30529106f868e3a146836661cf7615241912fd2b9f5bfa5c1852cb3aaee8b87023f1555d2832d6db526a460982282923be9d598603f25cf6acb03a71b0d9387f1d655a223b3c47261a677d1808fff37cfb8ff39e7734d73ac7a073a90060cf4447920822c10f4e11f196de8277df9d4e20e761508747cf8d63e62461a431135d9fc4f2770f54674b64a7b003c8bab13812d367173c5d96d8395aab241f10efa96109f9d3cf674dc3474556c461dac57f00cdce6678bc99d842ceea7fb5dc89a35e9a0570ff5d9c91d7b64213f6dc672c1656100a7b3223516add60839287c3e6946b40535ae799aaf0df1a5d88dd611a8e4f5684458be52b6e15917d98e8cd1eccc47ba0cba9f1972d348dfb07c5fe0646e88685b68868bfbf3dc36b261c560ff497e5ddc71ba757a1d060dd0d3e9d8b3c9bbfbf354c460cb8c33d1571b47f97c1de8a959e53f3410a8836d7de7b6d3ddc6aee4d57c1df53fac4ba00de3bbd88ebdd9909f36636db9ec74b7f90abb9935e7296dc51834185b663a0cedf69ad03d0540a951c639bff9f224b25f876a4cb6a7964acab129a6853a2b54eb72897925b5844f589a897fafa40238d3708ab591f467fa2b952bc0e56f31b07efa71851e80e2b47ba2ad49a63265faf344b014756878b8f5fc3c91c0a09954687a2d7896c4eef4bd18951a43253d6cd1dc3ddc8a0c764afa8b65a00087fe415b70926a3a995b113ade89b8a59aaa42fbab28302538926a648caaafff58e306434092d04c233c7ebe0e789a0f1d6d9eae46dd8a6325f383d36e48ef4a6131a4fa204ccefaab8b87d7bb1c91ea08ae86229f364a39b68a58729e0ff2d352393412a547b192f4a14cb6668ae8f380e12d19325182a15add83bab2099e09f3e2dd5275f26c8bda0baa5a28b81721463728ef7cf2c90101d540b12c276948413f0474905d5e7206a8215c8d8e559865a082bbadf0d2bb8500fcba31f8d5139548bff03045de92c42236892de493e813caccb82980b031dfde3ae48ef6bc49c5c6332468f4b2105689c55132e645c9c88ea186d809a54b5742d11c32ae7fc6a0d3038ed887ab7be650817ca585c100af89aa50e25fdd3b7765e7cdde70ff32ed3c32330504e7cf6f983f369018d24fe3f7013cef17c845e5d8dacfa9ba812a72b5d9a0fbe3d9a5d47bcbf67b43d2065587e33508108bd4c53a00046b63ba709e6ecaa32afe5b6c87e03aec259f716a45406bfe56adc8f5e329f1a4b80701c4e9f6ac2a881d6dc126891634a0b77ddc18f214b347d6c692916b5dfbc8414e7c64399628e65162618b1e88169e013c8815d6ba21f9790854513cbe568f00ae14ec9bfa2442ceca8c6ad5c8824ace7f569bdcf5f2abe63745ab65149bc3fbe6c0b5785c116ef208ef017d02f5aff1636cecaa05e09e5bb522e0dbe0d1ed924dcbd121262bc9ad2a6a8748165ba15c542cbea0d5fe81d826c4d536879d1f5fe8584108012736c235bdf7927a704d5bb62d9d947a81058701ae58433890a51cf8e217fc312e5b169ded94efe6b6481aae83cd820cba68c406d27f90f8891cf5c13594748a56c67e26d5fde3d11f37910e98890daa9d4306f84d6c0e983429a0a2f5819c677b2e65b0c472a7778341b25f7f42443d38e0736f00be78c809c5e7c8ef3de915ad25268be88e178ae67bb5da915005260b9c24daaa28b84b517ca3a55d0cba7e0b3c546451c25141474f0aecfc3d10c0b37087c20f050ef77ea44268241aefcbbed82ed3d95871d01df3ac4ac58122415b720ca3115305c31c708ee8df707fa8422a20e721eb102814b232586ed9b606b307e9beb259e7f1aee62038e737fe2b99697c188aa42a7620bbe2fb6c04501a51b233698b5e5f515f191774ec0e9c028ccf5562ee5c4a4fa0f64fa85c186e9867beadd179e8124f63f7b85212459b236622de6454180ac475b59109057721a0826b8d51adaf8866fc028aff5616480418e4ed45694462b7eb5e963666ca921b3e5418354a3bd6ea488282b83b5826c9bdd8e2848176d789afd4f7e62b9fd17e2375203e3fd26366b70fca43bacac9b7d0560c57d5fb5fa7314162be7fb4ec70386974d8e037d22f7fa70e2a7df0b885d1e9a9233508e3012c0d230dae0d2baceaa3be857f4576969d40e57daf6240f54d9f37bdbab66bed2300e6574b711c8b703c6856961c039da44a855cddd5c8e8a7bffc5deddf1c7523400ecca6bfb749aa214f524530011cc91e4422f1e8584c75967d9ef5b8f416ef16af03942ada14299c3d4d70a59bcb40b460a92ad0b239513e7d48f4ebd974a4e5479d1eeb4178d41ee417c1d011242c4e17eacd8249955a4aa9f7540bc5b8e430fa8d8974bd850cd48171e1f5024996bebff4f338f0a024d13262ab3fe56807bfa9d4d5979a5f0b42ab3b04d4f19c474e80cf1fb2e8d9e612723babb57e66d6a326a0db6a6e18b48351d6fa394a71ca174aab190c94ae5d589f04c8f2d9a12b18f53150f2899e89ccb27ff91ddce3345afded292707144e392b581e4849ed43bfc051babf6463d175bc994434edaf9c6789fb9850028b8d74f431a033c8e6763268b4027f1c9108f6f218414ae1e1b1b762841fb748891b8adb421803f11c2bdb12c6a0d42e5d5de84396f6cf6d407092c3bf5c406b1bc1cecd31dd990da0f075eca171d3f0ada99d16145efc1e7da565301de1ed10a915d77e2ac5efe45430a240046b0145f58b75ccb4d98960109ad9263cfbdb598f08694c1011ac47e0fe1290b203faef9bab3fe1f9f82f6461ae1304f4bdaf6e6f949130f250fa0123b910dee0e62d0d3e0dc91a2cbae33d0efcf4c053d16d1233bc2091764ca7b85f29e8e14d2747d8564829f99310d28009c8836e39e3af0ce757ce1bf85c7238f822f29137dbcc37d3f0342207516ba79c607eb919e97a013257772e171eb84da9212a364dd1bf54d7d4e106c0c0be94eed395d5aa682a1f8b8b3421c6b59bfbf11b8bc8536d05bd80da44fd002548db3d605608e0bd664241cf19744d676dc5125effb00810ef332c47d0cb9484fd46715e40f9eb6817686a3084a3a40070ef204b109a11b326294815931e4c86c9ffaf6d0a314788d92c93b3bfca1a1e1733270a194cd274a336678e8833e0bc51b77e792cf4c0e9dc5cf643f2f5d03a93b9dc4025ef80f9443763b77f8ca09c5c5d2380f3f05d29c8c0df2d5a6e49ca33613865edc8527eaed125f0af8cd92d5c0556385ee6ee189796afb64d8190dc57d4f4b8b5f93dfe4d7c07231967daf15e21827c85cac6a977058356ecce0d1cd92f60b0700bac30df9b560702215826dd6d86f07270bdccfd475a912f6e0ec02a5935dfefb1138efd8a745008b223b1886fc8015d5718d48b860db05955b1074d92bafe5823d51344650853d86f4ff773c46aab645fae90714743de5361d050e21d11f9c4a5509ef60eabb162a204d1fb1243bfabd86b7ea3a1da566e56ae370b83acbed768aed29b3b18a45d1a87e23fcf0c550dbd663f581f34b0fd8c8c6e296c0ead83186c62840143cfb76bf7d3f2a70b7cf35b61311760ca9bd6311befacd0281ea17d8a0a6aedccf4d9255c4f529685987d37918fb2e5504d174c4ab5ed72a75d7e4a2d60677214b58f653f960525addcd7a4eb9603793e4305f5cbf7bf91e8b57e498a70834cfde331112142f6e9e51101fae817b11ae2584a8f8aa06213fb39b55027257e7c801c87fee64ba66701d1cef47e7840ece7d085265252be04958ecefe3dce6e3c29c0147d778536f985b43f85f163575d5e2b783386b5e0aea373ad7d5e83c5202e9562ef0a4de9107aa50f164eacba26e784292ea16198d270a14ed60506af0566f77b3cbb48a4f75689ec8861823376d0f7873af70016988a536dec84c6533fa55ef49e277c01b5982332113856c41fb8cba8b2817ea879a3d2f34aafcf73255dcac858771cd324fe60458d3e60f29dccdac5c9a0753a2f7a60238f6bd422853cb438690c929191a91a85529bf1992bf750c630517988ef7400ab85d6d35119be8259496369008aaa0a8af84db509b1c38abdc6d813bfba97c3f62237dc27d85030c719cce17a9fe97eea3e0a3824c159450c19dab45b7a648ebafc68328c6ac55149e703da4d0bad530f4ba28ce731296b5182553000642a9bac31709a7e39f3580e94fecafee734d05d04e2982173771a08f99ddd85506839e176ab380135759333bd4fdbb9ecccfcb4a15d5aca3ded4ee24cc6d3362e39ff3a6d688796644ebb9238a3e0b48dcbceb04d1bda2d2366d3964d99b4f4e4ed42e0554a73bb584008c9ec0a8610080903287e10718edbe0c30e7e045be3af47a372784dfba8f18ac8f5ab2491b254386530108451d5902513953d47bdc9bbed179cc8e0f0b93fef2a6ff01183a8691e15096efba1fd99295c12ef159145b4420cad3f90943d4b5aa76a425496a63f05041667c8d9a59e89d50b24ccd53d85d4c6fbc03fe4575584f00aef5b9ca2362312ef0a3858e5a32d9d23bc5971596cdf3864e1c5fcd43d2fdff24eb2b3b63fe861cc75f2240de001c5ca56e1321ca4e467f3c2197100ab2592dcdb213e71cb2a0d177842ff98c70ad309d398573abf47994866c8007b79d2fbc1dd24da88b7d24ce411dc6a516bf169c8103d6429ebe638fd4cd24905bae87a8c3d743dc87d753ec43e5d1e635f1d1f739faec7b04ff783b85fc763eca1e321f7aafb31f6e9f210fb75fb98fb743d847dba1fe2de3a1e631f1d8fb9a7ae8fb14797c7d8afeb63eea1e321ecd1f918f7eab21f232b13018c0ff4d0eb1bd5488fd614f64951d4babec83d3f222295dd63765f9518d14ec01105716d40ace3659687e27f6b6aea84a772aac0727bec47100faecf492ea65d926ed5d5d34ed6a6db3c7d1035a16591f08f09cedf0abad4fcaf5086b546781f4dbd3278d4fcde8f531596b3b992efc5a7113a7369a14bdb26a8f1080b1e13a7e803776389eb96edb7a8d40177bc3be0f28bf2a64bb690ae190fba85b10021f482bfbb1c7d1e955c6cd6ee17caeb2e8b397c6e45c76cf8528db8f74cbde4d551cb164c9c1eba3d480f7058fc597998bdcc36f5b5f1f04a179d2a70f1edae5dcf3dd3bea8c0868f66d3e7be57de0ac46f77715ef7cd07d4c5a3c988b398862534689d06408389a270b6369a66a5378745b9f2aa86fcb9c6db3b3eed580dc6552f875da3ed11740af332fffbe3fe7098a4f219cb45c93561d1fea806100b8dcc67ba65413e3b905b9899ffa7e3eb495d46ce782831787da586aa8c3b5cc5bf58b77ddff7d039818060df2198e9858cd961199b31124b978dcf4f11589bf4a3888301a14e342ca4bbd5e6b89611b5c353753fc7ae0c413d416477c31805bc64138fb9247c8502644c0224b99c80fdea37828e1253b892658b9591fe010fed1f42e8a28b7ac14301b45b7d7e246cf046cd92c6084827360b411402a22547a78ea63a80962b2fc60c69c3391d7c0b2429b534e48206b9f2581d805544da231ba2a4d9f702a23627c70210f08e0af8dc9214ae9063c5afa96249cd14f94fcbe6325049f256da42e24c9220fb7be600219ee5c06c7ee57f59463b657e9bd50cb1cfdab457ce9eb3cc12995a887d5980bc65c1ac51f99810909ce80ae88e04da59d6476b8a644bab221aa502734575203b12c05e791f6d33322dac0ac1140b981b5581ec8800fbe5f5e00dc869655544575a682e7405304702ed2deb83352045ab7513ad7201b9d04ba01d0b69b7bc8ed600292dd795e80a85e48056817e50a8bdf23a9a2624b6b86a82291422075a07da4321f6cacac19a23b3e5ba88a6a490dc2835d0e3802d6459650171444955fa3a7d1615d18eac89c0f4447185740ade65d4e17a8c4c2ff015ca101846e8a6819660be959e65af6038f59e7f1b01ac2ce956fdd8ea06471127a6a88b80edcdda7bbef0027f71ebb0925024c4dbaad36cba3b58df4f1dcb06cb06c2b15063d00a0e8403cb450380767aebe024c6ab4735241ed1e28059b191ef07077961cc4c64c9f79389b8103023b0e6fbcb212b08981735f3fd71909503990bac5c7e58c49623662246fe7f7964a50033b131f71f0e9942cca8a895eb0f87bc34664860c8f5cb455c123122b273fde5212b88988bdaf97e701095838c05a67cfe78648b11732256fe9f3cb2420823b135f71f839452c8acd8caf78781b830642432e4f5cf445e0a1811b373fde79095440c8b9af97e18888aa3cc45562ebf49b42937212762e4ff9747560a30131b73ffe19029c48c8a5ab9fe70c84b638604865cbf5cc4251123223bd75f1eb28288f9132767dd46b245882d72780e6efd77aad265eedb4b84e8dda55723b69d2280c62ef2fab0e90942f5fa2557039b7e24a8c62d71f158ec2d0274dcd2ab8f854e2040eb2ebc7258e83501b5de920b876d6f13a2e12cb89e58761221747ec9cbc34e4f11aae9975c2c58f42b813ab384abc566bf08d131165e5c2c7a81107a73e9d560a1af09a8774bae1c167b35b1349fe414cff74d81cc5ed8c9b94cd2f00a3a4efecc826e73f4b7dcd74007c30dc37521bb78fc429fa85e2f633221b82062d220578d080a74e9963b505627145cd330a94ac03ae50f81a5bb055c3cc7f0b5c399ad7d31c3518ea81363acd0ed1e6b43403afc3caae17c382a1f4ea7127f8c7c2a6de48e7f54e9e96341feebf8a60ea3573054867aa4f0838be382b17bbaa49258a856e19b386677426b161529f0c858dd04997d417a6d471caf11dc094e0e72d8f18dc4f5e67a3449ecfbf89cc04939b7397ae1565534992f018fa675bacaa3d3d2102954e6eeee8a6f6b21f9a4738aee0c796ce9bf98727e73ffc772758621db8d34bc8db42bbda0567ace869a44dc142b048c7ee9a8bb6834880fc80796165d6822176e2acc124224701275b491160458d4917ba6ff1137ef0cab2a2bc6d013b84e7e1e29c3163c961da8921edd5784d84a0f9efa0432db155379f1266fbadb50cb7e0e083f878aed2f9b14cc17c782585087ad4d33457711e1729f6084f1887d42fd4644d6a7ec756a363654d63c8ecd94676ce0e4bd1067169fa6fab643d27d224cdef44a908f2715c3ebbe35adc470a532f021433382ccf21f2968b384f46825ef81aaa80c2d3339b5efbf6b44ccb07a596eb14670e09adfe230569e9b5a8d16b1b8357d966c8ca6dfdf7baaab977e4397553c99d4c5650c0c6f1ba113e1723ec0853073d33113d9e97cae7e9b6e11d093bf854f3f6391702bb13ed261bd4bb968eb0a9b736cfc69b186dd11f2d60d349226e25112ec0d278f5bdcebfedc39492420eb69c221d67ae5c5bc2ec8de209df94549534b745f9531d56441e1926e3709cf2e87dd61356f6a6027539e119df563d19f63a28ba7af9e9ec79e3ecda97d00bb694adaa66a9f55ec31705632f84ca7c7d07dc6075e7754df867dafb4e8b095372e3c6db295cab859bda9df10201f79f6120107b8adc98be26969ffeb21611dfd7e7794a884ba5c9fc7fa3c75734a6104cfb910fe75c748e1fb1e59569a5267d9e96f054bb3cbab20b38882825bde1df1f4f62d6f61710444c18716487014c517a058f70fefe79e0be48034f5524de6989b7d50b7b65457bde92ff58026f60c18a9cd8c3a11390f64eaca5db8f721d5e137403cd7adb664bf5833941d4e73023ec694802400d29c5603c065d92ba5176ec2eceeca28c5c4265f84007eac27c14eb80a1d4acf4bca5e6cb240b16510cec5a468e64b4f7b7cbca46b7656195eb83658d7b25f7f179e6122c3fcf88ded36270086c9e67c47caf7c66c96e84799d51f25747716da79bb600eef7539d6c8fc9bcf4ea7c8d40c7a06b40d20390144f8f8f54b65f1306b07341e2b935b88592092318267b14509eebb573b5bb439a0cff63a25feae606a0096c4761b67a0cc28dc5d77043b944e5aa279045c217a39c17f93e0b6eb2481ca89c2e5c2b9794690fe9a8e821ed412200eb7684de10e8fc44de51706fdfd8a75b326ba1b32c53e083709700719baf45b5f30a653bfb002002cf8b21310db1773bc429442bee053a8a2dcf438768002021315fe01d43c7b50f26d4ada50a2e5d066ba12e27712f076df2f15685955586f194189b8c005c5a22e0eaf5a114677c1052c12b9c9d752666d3b99418d5ed2972214a32eb4991308974b6e11085db7873389a8598a6bb5d72bd447fee13dceeaa09a8a96a51326abb4d9e9c608217e9e9b8e2c6915c2445f4df18f6b43452faa6b3d77596e34caa3cf92ae04fbfc0227c91e9c087611612e5541b93943b1d3cac13819d66aa9b0130b8a7c55b2bced8f63134cb6076c2443a918f5dbd52f16b1958410250f56b4a0639b2e7ff484ebbf8f41d76058c20f76d70a1469d3165c51da10067bcf77c485ced737cb06d4f94d8eac408d2235c2ad2cdd3f4526fb7cf44d6a0090ed7bfca0319af4b2144ba13806a764a4e1fe907bb8193a4b4e1cfb13e0c5b85013683ddc08bac6748345c19d04a1d515e11d55e39d4b6f0b79e6077f73823bd2a506e076b73a60728409d622d6b775db016fbfb6fbe56ea58e550a825323d8b552dce3e70657add147d15b1fd00159a2967242fefa37d8022d17a0112e373a3201fc1dd32cca4edd3dd9dd8eb20037d12545596dc1818bbf09b676abcc273ca9b8a08d7761a8515add6582f9c7249f8a3145a461ec83d8ea4aec5adbb7035d8e66e8e619e20b379d7ae071d4838234b7362f981f389dc18afb8299f4ccd6b4c5f308149f2fcd89e888f64d6bd44adad62f3c7a5eac3ace4a7521248976edcb06a44083741105aff0f7c2a6fa71f3dea9287372a81f17e29991e3bfde777668a19ec16648c4fb21c21853aca3c045f3ede91acf102aaabcfff8c6a8ad62c1e612f9e741c102f8ebf1c02ad66fc5af60902877f279094e312954adc70c1ef7d12b855c2333d14c68732ab73a8c93e00c94565b1e755ccf4113c88e8d47c432f6006c326d8359a3093b6ebeb9512414233e72f400a1934174c2d82b1cbb4df7cc3315e84a12b50de71b60605ba6ff780859cd2fe063eb05afcb6e383537566752976787a58db6be0eb88d1884912e51950740c1bdc948cdc01bc7da5a585398132b9dbccc96ecad097c85656481f4042b28b8cbb2013d07064bc1199c3f74968034c15a14781f8086f0df43389122ab3ece51ae1b83874d59c99802d05b34d4fd06e9ad58cbf487a4e78d23d6ed0b4427e1ff0f47c2247cb90eca4688ccc5629b10dc830dc255a72dd65c0f40a508b24deb0e5008183dc1061ca6d06408b30208cc00e0bb5978aa5ef7adb862434e8f2d5fe71aa0a57063f4333408ec128244d7c05d253c78de38249c12bec676f1ed2aa71e350178565646338fbe1e155fe52679d282a68e05be44483e463701174012fcce3af8e56e49b4697ffa7df43feb06ee718a7d6e1615169634f3b109599fd70fe49dc9d55215585d637297b086ca92faebf359e77dea47703bbecb70a607f44332795f64e5c267f33db1e44420ec4703d661692d9b6e88d0e4f4ab55d9c0631885b1f44f36a2be002ffc01c89524ce544486aa82e15ac9884a7ef6ce2e5640d3bd334eac12905426b2b771418a99d924c55859504643e828a40d69de91d013a2d62c61fd5a958ee518aba792ffe79813305fab11fe67f9cd2250efaeddd98264b3064ab3db1873b13a0d124fb6a171b504f9b624cac3c6082ade878d6632a4f07950cd4ba95366c1bd42bf96ffd2d1b56b5483c140c0187a37edb84df314d538f61d0b4433a04b174b8390f5b641b25aa159e81835f8832ab19d3e679fc4914938ab897158bc2e2b309112ce6f69a542c36bf861df3c06ebdc296a5189fc2dc2eb5748110a7e749a4622e8018020d22aeac517a42912d56471d784d669a7c4386cf52d072fe5113700806d77b59cb2089786d9439212740acc868e6f7a02fe30c8f6ebe06bf52fa5328503819945d970a0f970e4355dbd9464a31f90a689e7cb3c7c3435ab31656d667077cc1060f53a6aae3a6d2a767cd050bd367b101b0041ad2fe2bb23f76944051e6df5a0c49a329167b4728f7ac7ab2f0386e825b3381c4ac68048d0410f03c65b004cd2b8395cc66472fd3513a05913f8e3ad944c8d45fc5ab1d12fc6b94c6ee8234cb56ea083fd6e7142793418a253a032874bc0a2efbd0753e6345a4b53d95403c4d40a9ac3c034d539e661ed2ff06688789e6ac1b8e76a4a3af3b940cde3c5fcc5f41526002e6975a8123c3647b0e1475a5390bbfa7c6899056bccb9ea0695e38366003dc56a62c658b1b4d990cd95554f7b33c472aed4437dc505eda3487b4e57dc61f3d7e9dfac66715275fbb41a68f965a002f3c221442f3864d53cf10a1bf5318344b1decb3999b39e1c06a8738a439429f5d83f966573582f050754ca212366ddb19e5784ab41ce278c187a92bb2a24b2bef50dfd582f2624fa81ec1206bc7fa2cebe5f5b1b66b1a3c424dc7228d77ed211341f90d6a7932a5c5f0b1330eec3d2f1ebdc1d78e9f3f69c31f0b268bc545794a4a76b19df37ef42d987c74a19752915a78aa64fc5c016a683ae0ca14d1a4e6582ba079f862e9df0d5635283e04e7c839350b4c1c60978050ae78f13b08fdf37e155b36fc2cf5c7e5d72eaecf2c7573e56ada22f4fa491fcf05ec4f820ceb571cb817193dbc07ca75871439caf688fc846a10be9cc03620a1525b233e2282f2598dc616370626d4b537b7e9d43de831acecff895768e953f037fe2432ac3b1bfdfd55d2d476ee491ec11d6b6c7b8e9e5276b0cc7df4758636ec743d2abeeb797a8b46682a7a4c9a1d8e9393c1185e84ed1686f9e385ce4c0ed0ff7cb518917906229432f61dd48563cf3e3b94cad4487eb08b1758e3660e914b6f351479e57199c33b1bfe4b56248e89240455c245eaae2554a54de941bb958890d4af51c8986951950fcd12254d4ba78b5ee41c400327ec2eb37701c591987d91333942a980f327a70055954f220f4b826cc79c099550309816de8e3c814557d16a1a73f0f8e8139a2135f69f187f25cd5bdc971a912ed28d0af229bd207792310f7bc3a9732f70c187d0cc55ce5545ca726d53fc00a9f3aec619bfba0ec4b4852776d589cd315b43e07c13311258379308c11b975a438e38cc50a814edb18ecec3f8f33119ec7c0bcce20074ea60cc3750b05683cea2f486ee98eb26d17515525c3ed37cbb10a12411dd1566cf6eb8f3681a0e351b388dd8303ac60f8931fb3ca71f561e695113b976156e7e9dc11311c9c118734e5b92341199d10957bf496ad371c10fa947cb48fe2d6436828a5581dca2c7668a4afe42c3c1bb23fcb258ae3ec47ebb44ef07a73a6f4f24cb9289648162ea6b51bd85329006461e921428c310cde6125d914906222753416601d453c686078cc6a5237b78736811659927c43a2b245e5374f0a0788eb5d63541644471a390e4e62b27812b3e2b84f2f05b049b358b0546aa1c30d68854227a2343ee3293d8deaa9019047d9f5d50b172545d6e8000cbc29a6d1cde162c1f4b91429e394314a4a3f54fd87744ee82304bcdd1d55e0310c830602c74fc92e094a8b27fdea2b286b8b09ddd78a89012d66c01c6a84545727629ebd5cd96c950c8548ed4fa73981c7039064185e4f28f72fb60e115b93835df6938d8040194dc447dd971a76f5d1a85ccbfb05b2d60a38a8fb47f22d95821d1b53d82c79402b872db5984a55352a181ab3a5e38e45e8091fb015db034184637304b5eac0b1e9c0386be3cad265ca6c67d25209915c6bb0dddc0893cdddad9027c4178527ba705b8abe9a95a4138a84a7487e95651db272e7b8dc344966e58530362580f8061088174a6ebafb67646227f9a89ad0f82ab479fd8afcf063536e726451460561b635465adc3835a05cf612ea1e97e9f91fbf8be34d6b264de119ea7d1dafa4b3a76062c1643e22ec7ea17bb374a24a893d0018b73c1a0d42aa9721b42912532ec8fca885b59014935543f0149716dc72f86014e2bb74badceaa228d5537bf72b538a27e52bed4351a8a06ea638797869c25b065924344010b811eec5cd9f60455e81943189e473542b34d9cb2ffb05c5097dc2cca887be639ed42a2f8634f496d784d2020eca218bf249298b9a82f3e69355ca54a44b0ad3f4cae5eab74e4900ff7c8261c38be5d2d3e7a44b79512daf3acd599e7779522c0087711be71959aaa4ef741648cf059c60800bdb9b96001bca50c8d385a9b02cd46485c3958f5bc850d3491d61927b524424114be8660ee055559ee32c4a6e488c37272409b062c52059cfec17f6356ecdc22eed08112cd85772c0e469c1683b673d84eff8c8a82db8c3faec2e5c6b62726044c6a8deb90dae917dde4d0b93311a13ee12bd904f179c601b49e826b0070dde35039fbfce2d4976b4018a876641e1f348c50ced53db4216c4895dbc05ffbbb54cc74222b11514a533676ed04b2b50315eb5fb75c139c84e5301a0aa9f21666ced5b425a0008fbfe21a3b60957fb1779e379e8d00ee2a85a8dbc45422ab71def9b92a992bc638932ee17a85f0f425f3ffdebeb9fd607501f3d35233f9e40f1c6fea8c56491babf5a2a0f8c08d2f54a98eaeff37dd8fc574a9a60212bb74ee8c4650a9e8b7e14d2040becdddf171b23c5ba7189aebb14ea0d7bdc5496e316b2c74a9dbc235d0706bd92a2e0ea0bdf48c5e33ea053a9e283e4c67f94722cc757b392ae2123124f03c88a52a8dab26b38cbac4347e1f70a5ff08e892f397159e57cbdd15d86cdb918dae75630d32c6724bf9c2af8563dae3b8325dd138534984194867173e7d9e8b906ac9e97667cefea387ae4a997dda43f1afb857c220128fdd3f12bbaaeb7fe0d1bad7ceb4b532f1456ccd5d7af3b8d66a74706cfebe986c183f3ee77fc7e3730f487a51cd8770d4ce115ef8ab2156baa07912d3ea1822d6ba0c5be7777bbff161ec792de29f2940e10ca0ca162708978450a12f97c1c5f5a631841d3e05991e4dedb4eec91a8aa641ced9f0d01ca8c4f991b117541c19fb4e8c141d9c30f37c0378f03f10a26adb849eeb21a16e2c6576954490c41ab7a6363461e7396a5439d208e1b099c1f9850383a402f010eb8a8fa566df863af97f8301e8359466eafb6df57c36a0e3ff90f9b214b6d4ff2879eda8058e7b6b3ed7c88c636c7e588b0a72948fe10a84f23923d37f1c172e21f138f3d23e34391fe85bf90bd22742bcb86a7d20767d161acc8db632593d707745b7e38be07e745ddcd3ebcc1563b587f208930f5bfa0e641ca8939052eb71e6fd74be343818e68a311b680a058c6bc4af003fe3a21d5082b94a5b6bf4edcd6eef6de7ca35cdbc4bd7f88da7bd1efcac9c223e6ebaf08d17d883cff270c85c95b6060c6e66cc99f99e2f92ae58f5a9e798a8e6f3eeafb0c6a06f9f86c7c009d53c6585e1e8e9de8edcd4efd4128a7f046077e353afe90489ff612808368f4e0200f6334b8f38309d2a4df7541515a9d65e727e8acbfb85b02942e15c2578bfbccf676820298cb6901b4b7e03b8322fc15ab49a73f19d7361d84ae9a9947637aea0dd511ad61c1040d2297b8b0a9ea71c7803adecd828267e2ea43451b878d47578444b3faf416521de3205af9788d1bf64bc580e0b9c16c165608bc544e9b16e6a13225b4d8ea58f2425772497ccb8f8a8871de6d405fd746fc0b15af0dd4bf8042b8b07bc8c5e1a656456bd1646676fe0c560a6e067c5413a9459a88919765fd2dd0f58b50a48e958381130d881243bb127fceabea4fa5a112aa0fc5ed6bbfd638da931efb6a48e439191f010489cd32b0b31e6b4553b5a41471a85a90ed1355afa5b41c2dbd525bf1ff945dbfc3b205467a2b602fb65ebf4c09d254b2eb2ea694e2f3b5b239550db193ea969d62659e1a015f258e648189217544a0af6422b02f0e5db2a1af4aaef5c0287f9cca3ae03ddb46d3f402c52f36a4ad3675affcfa6bfff69b7689f181aca4acbb683e19facc9fee7ceb50e32536e9db29495a41c93e668ad33101dbf7cca098506f49db7c2e4f928212cef2ac534c7bf489166ba002ba738997489e770c76dc963667b8e5524e33039abb17a6bb6980a6948faa82fd97bf5cb25cd1004f3525ccefd5cb046f2396e3557c24e83e7e1c664042d3762bbfc3fb39778568fc67363696be9c8a01b580b35cb6be6b46ab4ac055f09de5ceaad881403b310c8d3d7104356d3cb109e1e141c1f75de703225d15801fa85784251b785996ca76f9884c5d5602ecb3568499fa1ce9b54dc7ec49f8482d41755fc20d89175a1b06d362265af4b2c3d07ea82c5657c6da0b660b37a66ebe6536dcd66297cc53f8d3fa6bff62fdadcbb21be3c3e63654eaa9a0e2b8977b80bdbcfe23cdf57ab952d2cb61635e5e445ebe31c9efbd1b6ae534ce7ed0e5043b13d9b6d1a09e8e81080624ba036aa12e8657205816a703f9819b4295991c26757055b82fe96e34a8125773129a97aae8feecfc88f8292ae25cdefbe214013b2845fc8cebfcfdeea32ed63c334d3907afbb01306e789d8d7d99b24cbe15ff2bbfeddd6d6fb9a54c29c922086e0865082017ca6ae58c133178d272c44b5dedfbda311848f6b6b9e8125d97df43cf35227288f41bf8da1645475da04ffddbd8e28c81c7d54298955b468e2e548531dcee55c49121da6ac86cf9a967385538ddf13744fac97bfe86742f3f9def71ba0325b889def3a61722f15e14f6d7bd28947e9aad71b26eab3e1d3827f4f20bc2395f28fa49863cd024647660284412ea54daea36385220eaba3d65a06f9bb5a512eb8e0c2473d49caee99205c9648e92393eb329cf992e3f7533500ef3d93fc99d2e3a1dd4665ab7ac0134c61d1b48ca88707bf410c5ff52a97dac3505e99c6dcbc2ca58266d247f75570d1b48025d1cdf8080569427e59658e0b4180d9b3c67cf6666e7d9546b588b81c3375ad82fa6f1d7f193180c44a5c59101004c654db7f5b7b8591c1e1ef73baa9b099259fd97959033a328ac0fec77646f2628b9dc023e71109c059e71e743105272cf6d5828ec868db01899359b713f577ef2d04f959f9c59fc04abafc819ff8ebb7f60c7ee59875325671c0b3b36ecfaab9fbfe3286baab46f335a0c3ef9cb8eb25a8d9e4dae61ad86ac51000e173e15a6f1279bb66d75ab9ad69a0264cd08a4e8353e388a59de023ef97b9be13280f5ccdc09ee197425e48cff085c49cfef1cff10d8391d14f65ce7409390d073cf21098544fce47f822acb09f17777fbc08259cc624d5517c0bf87a0ea1a1ffd4f9a7d66c82c1f66b399aac539552db6142ca9e73d3df349a93837666656a3a767f5faeb703269d1574eae4f958e97f5c6d2413d9be9c857b779dce3038f0f9d5729c4853aaf65daa9e3083c422b5ba7aaaa565df3829c4e2693d99a52266b56e17d1e15b57893999987300a08d6b13f1208f6c9019fbc99d5203fe1f2fdf82e87cc52c352a7325953256d4ed77fae1ce5393e5bf7f975706135cdfd4315d871aaa6ca513d5389c4b0e3545def3b551368aaa66aaaa6aa67ce6da31bb349811030856f0b4b58774ee6fa6fe0f51bd747d77face17a3f7b8ab9953842278f23ece839d5bac123f449b0e9d0e8f4ecc63147b58f4f0c34f5079a5af4dda110d193422426ed4dfd2ea24762d24c1d9a82c43ce987c0c03c2914220a212ea19531df27c91975ab5b2d92625e5efbef9afadaf3e81aefb570f469d15bda57d1ad1730941ee2f8c94d3a2f6fd2417b17d29b86700ee9d954811717d2cbfc8d1f42fad18f42215ec2286a68caa17ef8fda4d01444e66fc8fc0dd390d29bbef4a6973931a149fb984f920313923ee685903e26441285f7484cdb9be8c39042d37c93f6a497425e3ee6634224a62d3c22c4e5edeb2073621ee687c43c4c28441442460ff342d810498fd7109851a803f3129a667844079963d2483fc4e54921920f63432c29dc2149ce2881483ff6c851bf7f7c1c2f735ec2284c397491ae2b187a1238fa17b0e56340978701edf367d291791d648ecc0fd1f1a5979f497b2dd4b9f144748451f49b1e3469323a748451d452e961625e8852e803cccbbc8ea7610c1da9949f489fe36352314ffa0ac07c8ed0a443223de7bcbc3ce7bc3c4ecb8032c7049ab4cff149726e80262d34e9c8bce97384486ebc298c22f4329f244706bc11de78ebf242dc08b9c7becc9b9e86314ca1f493cce871b8fce82b601f47f89cd3d2f29cd3f2387d03e49c12c8399a4f8b3e5068ab35764a04b64fa7564f7c7c644099d34f80a200d150ca74b956ab2d86543d9897ce051c81cfa305b4626f5d3d11d82993cbf694b15351ba46037275cd4be698f875790a50bf1cc6b039e9cb6f6e73e3d015767e3868e12849a861b87f90a7d9da7713460b6b9bfbed473b3f7485cd71a917b344429d16a77dd5f4cf470d400a3712a5e327be3182056d237cc32d1d1fdc299bc0ac27ecc3eaf7a4117e59f97cc8a7d35ba485f245ca481716d3cc9f22c847c822a4b803d37012f2347f9271e78f3d1ee0ce25eeec959c9993888ef7ccea03e4e0ceaa317d7af9f3a1b3d385d2756ee897433f9d6c61097bea17bdefee169658ed76ef3d0c98384211d6c8d9e9de7b9c762f7485e52b67a3be97ec83c7117647e97f5c61fb8e7f04071df7fb0d748267cbf9befff3c01e72fee6be7121ffe6fcdb3770bbf2f3b0449234fd149469112cc2f38aebea4427794c665b62666ecf9ba51668a9856935d6261565a0a1659a69bb49e9943c7b761bc8540bafe4824ffe2bbed144e7825132f0c99fae98891517ec6ae6e94dea69301918f5834f387ef2e7e71f16c73217923022d2a6df9f0212c55b704e7cbfc3944bc4515f58e78f8460bf173dbb80ac0bc552fae431d72808b67e5faddf8878bbd435dbc4a1022bafbf1372060792c69f03d9899c59b1941d587eb1ab45b0087694414138ea4706f19c6c92a1243a57ddfec0b130af3b719557349860a7044836ed47190433b9baf910c1ecc82eaf0bbb4edc6a8f90a6813a57ce0401ca1901c10601393b87a378b99968326bd7684f1f8a7f09641037461c91156ce415ec46a97ad4b585dd4b0bb6c4795de53927c79e0ca2f785447d4690489035da1741daf0bfdc201cf585bcf213dfd090a3ac3e1b561ca579c5e148a3c8c031af021c05ff6eca633013a4e8cf51f846879de0c5758e12057649200e9233fe0b0082c32e094479355d937aa6eb32744d498afe23e82251a23cf977d334a78b5f1cb4c353a4b08cb3308ccbb8feb39999081fcfeb28a5f46f13e19b10c81f8c92fce272fd475748189d1f84a36cc84d644b18fa7f3fd7bfaf8bdfe56217bbd8c5ae3943eda3075a3061c5cc54f479feb651f6fd4bd226f4fe37a4cdf6fe38a44d871a8938d8e1f99c96fa2210880d087be97b20101d18430f3f75600c9a46e4b26844e48d9bdaf61cd76d60e8a927fe10c029009e486f0b08d3b6c5dace748a42e16f5b0edb739b6df916b0879f5a207ecd012116fc8af9916bc2d5d1adbe725fad56950833f4959cf1245656fae48f659b59ec0e55729d2e99939d15faaa45f00b3b83e6939e554c2833ca9472a9346ba5ea993b9fa584e5ba159d1d3b76ece0e131c82f06bfcbb5a5a48445c2bebcab40def0c034cea335e5206f8b47e70bd8c20bec894b811debeb4ea9b0ae196b8a47977074165c7f1b8ead44e32ee4c95f148ec2d191f08523b331ba8baf3c9fc1556a25c562b158ab98d02530c0207a278fc11a8bd5181bb24530df43dc2b4080c2ef7243d85a46d78c9a6ac7f5ea4a0339e33f5facd335db0e5d511fcaa230a02ea067d02b940daaa24be40c738b4271d8dce9e9a427939e4b945cd8b65381da448df18d16ce17d3f8aa36c1286f62f60c8b15292f17eb89931d9e949c093a03c69b985de79bc9869c50b88217d765333bd2d89c6958b4202d0b4c8bf1c8ae6b53d0903447980212aebf26a5fb32b42854a05c9fd2555c2368506c21699e7869ab96e6735de3b9ae29b9fed40945ec481b2b8d6a257d2a83ca681579d343481a9736fc4e1c713d4b2fc1727dd450705f9e3f1fa2679791fd3c1a8b89c0c6f202f6cc0ae87ac26a273c2939e33d5de32a12f4895f66c1b2934509ffe84abc65ee0d83bdfa497743e928a95e754ff3901e86926667812618e562f009039589baf2267cc531ee420c867115f6829df00a8fa031a9318e8ba9982891418679475f854db0a34f1e7fcf022ba36bb66f959f8266cfa56ec50b7b498b211556b6d84b666490e1f341bf82a14bc123950b6d95ebc2b179683e1f737acc614e65fa18de041a8e9cc5570e7398c31cf672a2b19ea8a2ac9c256de83777c48b515e78043bb24f87a3c68489b4610e7d481cb7558d4ea64e288b52262d1ee0009f8fc91d61433ffa6ade2e015e48861df9d53b3cf3b7679f57cd91fa24e02c65748ac935808d4dad5cb7558e7d6e6cb0e1f3d1cf60e83678849f04dba55ac8307eb53845cef85356829ca1f1974a47da009133fea1efbbafe1aef13e0583c1d8a04f5a6451271e48574c542d32fbb89c30100d704f550d527ca3853a4c235f2e2951666c763161976f6695e9c574c2f5b7a3d077b2fbae3f1fdef77cbde62be8e52beaba14e8d21e47558daa6e89f278c979781a7e871c666147a157ddc27aa5c4dd2d5fc7fda4c6449e0ffbb0cf086c292dbaa2c819568b4e562219aba6344aa74ffc332c32cd8a56c67509a3726da0311a1b698c871dd887ad982f15d3b0158caa66f049759965be1f5f35c363aa9894ec302fac1599a73ca3adaf1665420f43c684529ea6640f71abb9ea15afa68cb957afd7063a00368103e0ed517d98c6a7aebc89ce039eccf181d1993741653e7c43af5032a81a3b88d1181176ac31719e214ffe57aecbe810b329a3311aa3311ae338cef27a7158633e6ef8814303aa1a5418d000a64ce88aaae6773978dc11b6bf7b80c7da75bec2af51aa0deb5fd018743fa9938f862b592e8d491b1ac81b5781f32b083fe0178d4925211b96569127ff3358577c281badeb7fe3a331baa24ca84aced02554e52df77196af441d27ac5ee97c10f87c841e02524640488e1ca51b5336653077984781bbc9f5ff42dcf6a4d23a6b5795c7311a9bb18eb1b792334e5a6445e91a1f2c77a4b11834a0eb515cca48633cd2980d3406d3112224021190c01026d2a9dee12cda0426c051e056c023810e9b389ccae7c3615b583956f61013581ad53c74e77a96399b5168e3fa0d6341d2f8944dd99465e954ef4cd994f5aa9d28d19e684e3426da121aa3313a2de09140a7d2a73e8d5ec6f5d74020b64b4326c8197f0f43d290402718748247cc810981d880b0b75f03df8f8fa76400039f8fee31f0ddb0018ffd4a8df5180e8b8df575bdc586e52b55aa8c5f2e98273dcfd7ab6b48307436d3d9dc5635caa0e4b6aad10d6c60871d38e03d619a1a30aa82c1277fd235382f83f5761ff018e4eb32391306182f47f912a220850f460002860e63c18e1bcff5a70cf3ce2fef48205865ac52ae7fcdb8ed5c4f8244d529d2865bd5e77edafbe58f866167bd4348328fd33e4c41609ef442609e04c3313f6d57c381a53b20cf40e9a798977921312f43fa98f015f348603e26e4d776dd95c819ff900d4b5fe6c0901e66474ad79048a153d0838298af098b79524cccf277463ce92812cc8f3a607e748143be9937240260ba2ff423bfbecfebfb422b612a1cc4b3dee1d8e78542a1d00dc58032679e2167a0c034565a9cf5c412d4a27720df18b0731a7422e649608967cb89d1d1d35f82b5e854a695299b58ee94855d8c5336d615533932cb9036f35b546034467ec2f577987b8cbbce578b77d553e627ff6db3b6549a29e01ac92214182599f674cd9436678c1a112b285122ac15661ad7a76cca2efdd219b6ca3629d3989cf1a755349e23ddad29e9896d9bb53446631cce57d7cc0f78fd810f7c3ebaff0008b63bd61583b5ae384bd7b077936a4cfab6d2a8988ff99898d077b2602983ca94981f3b8acc8f0de5c7aea2144a5f72653cc6619ef4386dfa422a2c87ac228135e6ef1cbf58d5ea9ab1c6ba46dac4aa8c8eded47aae2fb9ae299133313b8a77a43123357684e51fc7cf47f70cf62df2dd50c4ab31695345a2b88b578d711581c7af66d2356c480e43b6206da412d71b09cdab73951d6458fa9d5281b45102f341ec63054b96eb3b17e554a6a07ca5a451358a85c25ec51226d743273cb4f892332e73c6ba3a5dfe422a2c83da75f7771813541aa5b1ac8cdaeafa87bae60b8d05b70b79a3a940d2bca4cdca511e863cf97b95cdcfb0ee57aeaf1c267ac1fac52f7ef14b5ba2f5809a1239c32f7eb1e6d335a394dd2a5efe74898c56719d3eb94e9d30b91e8edb168ed6964ae1f8e27c98077bf849bcb1f58cbaaf28a3933ca476e58b573edf78299924470ea1bf0d39f1c8b2a7743e4ee3a07dd3d9abee884d5dfed20a6c897e0ed96db914a56346b340234643166854817aa92ca44003caf4b59ef4e7d26f4f874f87d0735fa2ff8e12620b815be8eb735ad564619c115bc28b007a72cf7a8d6ec198c67f0d46f50b5a72bb7e5ec0285e83595bc88d615a14e1ba37aed4a28858aa0a3da0d73369d3fd836eadd1335e836f7a0bd93ef056b7357dfe7068118ce7dc601c8644f54f0bd6b29dc8db31c5f2fd5ad2a1fcc896b562abd5f37d3bb2f48c3e9d1d20477d2f7afe0ffcbee58788de8abee5452fc4e8bf9739dd8e2c9665bfc586a6feef47a3377528e4fb914988e85d5ef42eef1f1250f67d53421381f502dbf2f6e76b2d282dba11972ca4729065f4489b225ad883f66ec4ebb612d2a6732cb7815aa444b032685821a2d05e88ef5de67743cb14e47b9717f2bd4b28fa51c8834c14dbe2359d2eda5e04f6cc82b3949cf1300d5b05599386b4b902ab5544af5a37c802a87bbaa7c56ab15a2c16abd25ab5aa51510bfd91f7e295a4b063b77ab688b69e9033cc05df74e7a0597d65d69f8f1fb88dbba3063c76ec96dc9e55351cdefc6ef88122081895180cc6400ea4c308931968c643b8fe332698cf476b74bb188fc1d1ed969cf1d98807505c219bceeb7ab7ba55c33d55cd62188bc1e2a1e26ddbea562577b3b85b0d04ee1e69b3d5c7e91fee14ec15109ab48089eb9d7cb990009231c38e3d6b713ff6ec093264d81b6652ecd82d192b36f41df5b6ba79ceef1f04fa869e65ac60719ac17ab7cab354dd52a92d354b5134ecd8d3f3b41edbefd0c28e3debe16184e597a965a5164b5857de915d2ef04fcb823bb0520b1400ddb17be413aa80a15185185c91c62c0cfd58ed8edde380f9a67e4a04cb2e25ac2bfc1ce0e0c777013812a8d25ab5aad11d3cbc17c460144bc127e7b055cd7a0106183e1f4e7c36f5fdbd9bda0146f5ef868f8bf09c3de72401bd4070923b9fc386d2270ffdd8be5ad8add08f1d9f79ce2a8a9e288aa11fcbac198fc18f492ff9e9663e853fa1fd58d3ed5b9aa2ea9e16bbc759b552cd6d9b556301847e66251dd81e703c27ed66f0669861003bccf218740bc851a29fc29ff0264e5d57a4fdd0431f6286c4aa67c794596805c85d9a6f6bd1bb87fc6c8b53c219084083c720b37eece4ae8659dda2fe85507ce11276ec1fc80e82acf1810c2e1612d53d7e6af10dab68705d1ae1fa11d28b9022b73c099574150d96b8feceac59f7a8ba877e17a56f6e5bd54416acc106cf0862b00bd6b317fc4967712cdee34e3c359b990bc04a7413492345b7a07b4a4cd8b17b1a4b8fae449485f60fcf6aba35a78d0d37ddd35724d713fab17ec7eeb99f0fde69d19f49cfd89028265d17bd121689eb3e32024b9b204775cb51cd6275688a95e1c28eacba11b116728a79b6b023a7e61dbbe7867eec773f1aae4c19836312d5e5b05946a4ecb64f11be100a1b2eb1b31f79f2174217b36ecdba35eb59cf7a26fa3c26020b3ac943898f3bc2f695339bc82bde829f90db4adab470b7d9b6711777fb99e26e1c645bdc9e4118d16b71631e39b33dc8861d79b56d630d77abd94a77fbcd13a174cdc8473090a3a436f211d2a6eff63ad28657726607470591286e224fdb6fa328fe7669a8847b98270b368a104a88f9de6f510899efbd10f4bfefb1bdd8b1778fd4d46db0de6e52272d6e4fc1f9dd90e476340c7b2ba8a5aefcb8c7e96a5ff44346159ca9db51cf3f5310d1b7bc10d1b788420f85881ec9e845db57b053d7c74fdb083485defbd07f4f2916ebdf813ca5c50dc84f9beb075310fadf5760bef740d8a62267b66ddbde51dfaac4f2d3c6ab16472e0bc4767ff8812ffdf938ed59c9630b8b74ac4ba2abf527581fecbb759ad77d921c1387eefe48bad1e6749bc71d6119a4b7d3bc0ddcee9cb7e3a8e6b579e336916cb1d6e77a61a0b0f46768da3c3485deb4bdbff726eefd33857ed382ccef7e0385ccef42d3f6dd8f9e0385f87ba12948f7a3376da1902eecbcff5ef4a370fb91fd9d963762cbe9de9a3621ecbf84435c46ef12f6f0537d99d37d3ff0252267ea87be203307c74ff5394e081cc562fb6b0f03dcfadf016e7d2f01b77e07ce204ff5bb8fd19033f537905e6945ced4dfea16f2acc7ad0f7e613bc525994db36cb381b828a52efaaa556693728a5344e80c01c2375ae801a619c2a81e7a60141bc127244b64194b649650a74d168d603c70fe188e3c2ecc8f31301004b8b29329996acd41b59eb5ced704a3ebac569133dd61bd22692a19ddcdfa457d7d95bd9a70f7578b3ea5c50a83e88458adfca38913153ed58c1a0b408d5533d86755cd60546da2731f39d344cef8aa09f729a4374ffdd1573d66a852a4c8eaac56a932bea957244d25430d2e083003d50463be6898af09868a7d26188c622b9a99d90ae62a92b9260a3ca078e01b2ddc767adbe19bfe5965dbb92f03f0d03656f8f020a170fdbb1b7e3118b4c6180c465533eacb06ea041a03e3c5d5a736a9aceb7c53a7a837a0c20b16cdae691e3ab52f477ea1c346702af472f118a42f35764375428dd526eaca058f5f3870119caa818a01f38bf9622bd8278619fa01105080d73140cbc1ab2b087835562adda82bd3fc15f00df73b3ca61ce8f37328ef568382aecc342cece8ab1b8fe3475f1d69aab3b3c353430e0ce9635ee6774a6fc4d672e5e72af015308defdcb1797aa7ee58122467585602f92567f097e12401466e8294338c3c46e9d3a173605ee60b327360428ee1c0696cbea84aa632d5ef4c5e0eda646575683ab0cf310e9236f20acb292642cef8f3b4c3fce46d04c16032495f3eda89e89dee22a88d2b4197675c85c388d9b1c48ef5a519616b65b1c871b26d8992a674a76738b1a88650ad27a7d888909f18c128ae019f425a830a86a4f1e7d3c8fb42cc4f5aa34104fde08cb0e394c9ac2cc112648481b094167de4d55abf90370a7d558a0bdef49955cc2753c9ec993c2e782eb80045cef877313b5b09247a882a9a54859a8a6735a4c08ebe72e2acda64861cca7c144a94ebaf49b9fe74caf59f54ae3f3fe153fc78f3256dba90289ec267be7cec8ab26c8b673eee4dc63aab41be92994f9f41981f6f9002cd8af9005680966fced9f2cd1781324703e54d329bdc80697ef46a0d3b726c7a9f17e220bb90354d24123128354dd3b417cfda29f31fc9b1561704cbdd915bab21f00d18d5293fadf8462c2dc17a5184920fec0e3855468b31366c6ae58a327250e81322fa165260b9cf851f3b3207f14de8fd17206d385104248ab330031802b286539eead405e2a798eb0bb30089b95cb1de36b07b408514bd7bb87fd08276c92460b1ead70e4f6a95e2d20784526d631ad157fac28c574cd3346db52af57da1a93c69979306ea29edd350ba74c36b1c8dc3d3869033fefefd4835c159f886959044a4ba2e08b6cec08e9d1a6bf87e882834f177434c1ceae488582b53bfe84dfcdef726ee5ec8f748a2e0f09174ff0185dcead5f51a1a8003878ef21c85833cf9ab80ac56da6ab5ea55af7ab581dceda4b6da9ac80a3aefade94f10887ae5bb12dfaa26411a825b928d598cae6bee2b5be48ceceeb691524ae914083ca4db946529a73085124be1eeeed259d0f168517a73523a5dca3927d542295896c297668b7336a1352de81514d4461b1bc7416183823627f51707390703776f7ab3062efca6014cf3af1467111dd53b6c481aef56725bbc020705695b6d1804050505f115244a6706a5256c12b7bb881a9d3a8ac2fae63d68b70abe9fa2605f73e3e88b9d080a92335e586e5f6d35c00112ae48238b531a965e99451a4069b45cceec20290976f4eef5cbec2c6ab123971718528c4ce9060e530e1d4e9d3a75da820b0f863b78bc000018c453000410c38c0c343d661800010840001a0a50538029e058a0aee1ff12cbd2a88ae5a17d3eaae631ee75faf4a6f7c3b4ed98eba5522db164395e776e9bd329f55992a5f652e9fea88a9d2df29c1e02b960f657540186cb3ba70004ab8424765cb67405c8c25cb1c11ded43a1c42500645141b1f5ca2cae2821801558d29559ccb2fcc006f998cd9e30843bafcc62b6e2e1413453b18d84f4765c39df0339e5a720fc14b33cc5101205c44fd2467bd92c2e1cbb899c2133909f805c40409bc370470682e18ed2757b8a3b843c39c75c3e72c683662d863c48693ea8da7cbe99a10d4c23830d4b48a147e6d3cd559b3229ccf09946c65260d40fed7b34ad292067e6ff8fc7a1b3bfc5b0a39c89dc125b2fdc125b2d51e41b8e314d174186c859bca6c05e8e6225e4c9bfc9f5af1a9dda8e97956bedda2c999bf358c6329ea99c30162bcdd34c38884e4da353abb5d6aac1180ce697f6fe42b6d0c21f39e392335d7bda5639308084f00d6f2199e594e6275866999fa858af07d6c42f734cdc3304ebfe1c964a1206b20556dc1948eee11bae82892ae48c5bd2466b438a5790a2f3c05d84ecc1c24d8265adbac00e445af487f5c81997c9aa4c26639946a7cffb5081b35ccc1823fdedfa04d1f0c0eda79e3592e3f617a1e198e3f673620c321cfb678edb438e5b84fb51738c392e573b346cff37c71c957eec815b84fe46bb508f8ee98eb6695be5667353db26a5734ef6baca6bfc748e5230bff3b6e91d0d694d84bc9fa0474790e4b24ff6c071bb73765c881d8aba6d200e9cba53dbd8351f5b05c769396e2b21ca7130fd83eb01e616e1e877dd2247e9e4be4e2e1c616e11e66ab8bd12db3f964a258fe3429a86c4a6bd168e20c96d0e9caef1164a19c3fc19a2da6fcf6d1bf5aa51285da8fbdf363727d7bdfde0c3f5bed2ed470edf9b55b0fdf6e78fde9bda08641bb7e547ee47a1f6ddc0859e0da9e8bb341cf9ebe7c3d6c295e511f9beef3322de5ac11ec4aebdee46b1866a35f1f620de16517d7912fdf72ddf712e2010f5ba70b3d62de4e2f238ce85b4d9e32a47f2c7df1ada14d87e17d3a86954f3b4f9385dc11be4cb4b696302222fcc0f09b8f56b38822417e6c7fa9b3743a12d7c6f9cb743a18f646248a4972191b649c281e36ffca8fd86e36571bcf613c717d1b690391ce1d6a27ded06285bb45f02678bf66540af45fb31a06dd13e098469d13e0c7843c660ff05c42167ecbb8039a468df04be3cd93b0a4b72c6fe078ee2b5e13712b945be1789be2e044405e5d4b45a1fc7ab374bfd31999365287466cdb7ca3c9d8990962307ad959b93a3b4bb2bad5b87638e4b7bc871399ee198e3ceafcf6d2d8eea9e8e39c2ea8190b675b4f98bd4ef2ced7e4ab939394a9fd66deba17427b7fde55c58027d4f9b97f26079b845ea87359cda15d80bb9c06e4f9dfbfe0a8a5db3859b87251c7fed37edfdb5d7e86b4184ec7f2ccb6d93deee4e6bad557bd7b4f75a04a2c2890bc356e3d1a8d0f7e9c51e4fe4008a99b1c68a7ed7021a36d40ae3fa8f1d3709a280ca7db9520b1410e176ecd51848d44b1bd2a54eff8926977ee743c8438bf4c31e5827240ac74fb46b76685e42d67440320c24cad61f590797527f7b433c7440d6701252a4cf3cb4fbcd93903552d2e71ea72cc5fab47eedf1a894751e929b03aaecd60f8542a15028140a8542a1901129bb45ea6f1f0ad5e7ed4bb11a7a9ee7799ef71d0e1ad0b045425fc48894dd51f4f53d6feb72e87efb31f4a328d4ea9cd5d6fa3538aabf3e10593726ecb6ddf0fd180a4729bba1914d41ec8f7e88fd91e887b4bc281c43ef3d8e87a311ed3d2058bedbcb9003badf3c50fb7e6cf543a1ef2ae87de759db6243ef51d0dfe285a31129bb5d38562e046ecff9d85aae7492c7e851b8270301511a82bdeaaeba542cb93917171c857211046b11fa11f56496140c73314dbfc0056b6182143016b77beaca0b1825d987909d0617c172cf546a5404172957a5b56a55a3dcd4298bc1cac10c542e18524f868911330315b74bd9e1e8c92ad30c54936a52a47a443c29508af5973255b03258ac8c1a56260d2bb386959fcb75f1662335048f8c10ecd8ad1d50b07c7e72c0aa3c907881b504005708828b284be041446bc62d2fe9a0c2cadbf24f856d9d524604c1375aad35a238a8540dd65639eb140d0800000008a3140000200c088703e2e18040a20782a83b14800b7c8c407462381608932887619451c6186310218400010118819991ea00be231d829503017ee523f858000fe934e6bd14408e7c2f48bddc293628b7668cfbd82a34b80ff58d0de48ee977fe6222a58955f1a59754c38eebc5b7c60c4662a7a14ad62fdf93d6308ca6c658645293f2e1525337a4beddceaa9adb35a60284b6dc3cd149aea25d23877de2a0634845399c9e97f975dc4b0745e765e4350209449ec12970fff12ca61edf472a8dec65c563683a5663114f67f615ea3374324360f9b59f8b8f8e925bc3c78bb47c48c70514cb1321624a297052b30ab69e8bf9920771daf3e3d61741ddc2d6721ec3530dd113343ddcdc17c4418420bbc44d145f2d1019cdca430c21da2ec409670f01d9bc8f5e1862ff62a1efcde85604ccf36a60e41eefb1c51bd54c743670b1d093a14bab127131ae1be6bfe2fbe49c2faeb40d62dc18686b29292347407b046573618310d36dbf6379cc9a889a3e08101d814272c68e62035168fbea7086647677a35f461cc0120f0aaa2516b38a08a94216a1af50e83a53f990341392ac1eeb63824c8f11cb85e3a110dd3b03e72638ff878994f9a18c49c83dbd9980321eb172f4b02603f81b42c38679fd8607d6870fe780c11b9d4f18fc5b767d9abc51d2150cb39f0e3c8242a02517254c14a400a37b0614c03a2fb04499aff770a17c9e0235fc2a6df0f0525d6e2803c56774c8da1946e0a8bfe47899b04b441d37e92841480725543b64421e69531b6530a15ff2762652e0cb33294d41af9495978a48187c25bdc248fb47135de44f3435d4c227b7496bfb3b49f8b91b530f7f94fa60080fa9f42be88c1634fda7345939f0c5e0d08937a205b297654355e34881e49438c8c72b0fed9ab6c76bbb98742a8f925367419bd2a3db73d43cf59b8e80988191b498d19aa73082fbe54b07f2f9e0e32917a77b9631facc2bb9a24b39108ec8df7f477e994587acb973b682fa487aecc635b9b891811f41140f41867221a81c41df8aa24bb1c86e2ba8055bfdcc9293845829ffba1d3fecc63b2256d91b01e1abb6f6483807e418ec476c25f1b2571906044e2e19d8f54dba583a52724682627cb320d59133c676da2aa6b3a56eb81983768bdcb47e34a4f07f9fc972a2cf1906dd924583587851246d84704f0e746604fb1ad19ea2f9db8a4bf2dd6689d9b0ad1320be5b037fe0e4bbc09d7a659b83cdf2c05c770c60ffe2f8509e77cdef3e6564aad574f657199f75f8f4d06bb80f0f7d322f778591aff05e6fa7cae2503f6b22a3a0e979cd644c86443a9e245a7946d7f13731c82a53c04771922436f8a7fb7e591329f7d456afe2dc3d73b92412e8c614fbde13a0a3ad0a82a6b2733b21132876a7effe14027633bb54b183c822787f1eff91a9628b3c1faf5ab44a14c909145a0ed886ea90d8e2d7e89577a32bd6c2b3dcd543749d839a898fc15cd9b29f1c933a0a48f5b354977e01ff0d5d021e76991e152b354721490af95754fba1039494ce715b34f82e2bf47ca3fafbf11f202f481d7dd457547616e1d373975cdc5a018ba09234bc86dc91d1da138f0752cdc0e5bf83d1397266496b774657556d41b2362e86ead366b7783911866bb7c7f441133891c063be15ca86d977bf421fdb963426a2d7bc8179ce6a77eaa924c3ccef1ca2dce60a6d93915a0ed72ef1efddd737d6e1ff3527a644940c341db1af6fa9ab93676ec97a9f2038332ab555336888815155d9dba9a1b8e03f3dc4e68fa81003aea8afb2fdb9608e48f8454736078d0debbc0be16a9e7101c7e6559e1e2f6b9793794426c564a0ac2612d2842ab453974678475b2391e0b8d9aaa26e1cd46f96de73e3a94bc92ae5d0f17d7e18528db4d444f2837f33d93a3f75e2e7796ed4b8031ee25d3c8f84bdc11a8298c821630fec94e76e46821cb1f975c3351414a4f9c48379ae87d2088ebe8b9116f9bc358cf770e9d8b61a4248a16d2909acad65c2b08a6c0dc60d53d09c59e838c4f0f1c716aab44e1dfd114f2294f033cb843edc6006664473d262991c1be3f261817066fab854d64570e23cdb817da47be1f9dac4394f8aa231d200dfacfd960e0f5cdcf96ae9efb0b07f703ca50b2d3b8b3d3cc0cdf194e84c676f3eca501150378d63684fcf4613bb32837a106310c9ef63e227e5c33872ca6ac421cb9e7c7d864352192a90a146e0314e5bd9f84ef527678a609848592d523c7d2c612ed23509920303599cd4a0ed794b0a5064d734c39e33bcebf80baa1be98636d1787e1b678d532253523036f182587722876f240745b41c385634f575ba32efc70fc162a1ef248ae23f403f5aa0a443145a76b9bdeaea3f92279f9c57af7c0d39d169f7a40b7159b1f0fb7108cee3fde500e851f6e57f394bcf7520c3da842c7755b8fa9b7d9b31eb787d7a2f5867d0b87433608c164c8ae5edf1c00de6db67c984ee2c6ff6c1a894f2230f96bc71ff709924c2d2ad0fd001e2c9ccdc735697168cb56063b188b193380ff0411ec4b4d77385895e7253b2371e3e4bb17667bdc9f226647bf9d0a59b1ea296860d9fe57fd70f696998460a8220749f2b08d28599825099efc44266468207b8df5eb5591dd4a00ec167e27ae536ae8e337931542554fac246b6f5120e0fc359051c998840edc109fdd81e56ce4ebbf9eacdfab1947f453bc034b3d2c27dc0928bd417a07cf5c79e225639a2f792a028de6885f75fccf8f71f70cc0b46c5f1d539a30d5e812f34afd09510aaff8fa4dddc0822549cab8e74126dea9a89aaeefb4f0307a083617586a0e2c508ddcd706162e22daf2ab62b13ce3d99d1fcd678e058821f5ac770d208c5078fefed67aabb894323331d3fbeb9b07ecba64aeea4e47918f6afd2256903897277bb1dc319c9cbc8e2ff6b700a2f99a7a9e10e4664525d6a821b690f3b41afca6d4b504aef3129a3e020a499760829b0086651e0fc8262e80ad8d7e8bd501481a2599666bc9a91f7e84f5184216793e54f10c1ac7e7214092632e603a6fa6c75c77fca21451731fcea82a5eacf26a0e2a06731e8f74cbdb7a77ba73a716ccdbd220cee1d266657f9aa96d9d1b9ab6b9a63ca7e56faacd8a19900d2edaec3fd32bab0fdc2280a4613f46d66ee7fe8523be24189fc9a1569d4d3db08e9d673e4eec35e862586773f2126ed00cfa240926df00a4e6471533fce91396e116474c3c0106f85291e72f4dc2f28163a115bac0c8f82dac4d72b96ef6141bc6c84a0271cc8ff009c38bb6affb12ae4df714c8d16bd880ff41bdb235e4f4f3679ed375198ca3c417d03bca9d68a9dcc8721a004479092519428c9942a80cf2d1fea4bf1359a0abcce9bc687105667e614333327cdc79f46d82a75f2b106c65700bc7c2fe13e1b3db829f677692fe3bb93ec59d188c96b38ab8cb27be0098ae03ba17e35966e73ff587cb7872717d8423254ed537054f98497aec21238c0916e15568d0a4bb2d348f4bebff37cd0254a121ba9dc099f059d1e26e829567f7ba94892b2e6bec56ed354a7c435f4dda696e12322fe789508ff8d59abae962ddfdc1f6d07a0a792b6c2498e492f0fc2a9c0e071981da593743964466e5aa8519997f355ff202c5b53f53c0df38af0b94cbf1f5f1c0a490c4e1e82d56c69188a612045c218c8ffbaa50dec70d26672b44ffe742e19a7f6fdd2663c58256965e953d367e1b1feec4362c335c1f6f5be3f2e2678df5accab67144e5f1d8c7316aa5637ef939915997b923018a2dafbf67e4c00f1ee5b0052d57454b90c204eea5b349de4f8658b1529760d362f51cbbac81f275aa24258a1f6119395a41b059d16923bb865a86be5d9b31bab77e9b0319eed1e88ee80cad6f9eccec4e0450aab8881e3b932d2cec9bab0c695fb0ddba3a238df61978543e1bd7e8555dbc85163f63d42f58e2762dcf7d05fc1e48984130eb09c6df7aa6f8547901942b079802dd79efc0763aa40d4a1290a9061effaa39b6b0db3d38ba62b4ed2e24677e4b5995d588bdaa417a52dba137a069e954c0bf9d893e5887a87478da10a3e5b2d238343c8975932ef3149c139ce0e52d704ed288279dd4108868e0c5fd4d408541643466f25bc4307535ed3bd21224e36b2f0a9c44563e81765c487668acf99733ca5eeafbd6ec2f03f4a4ab0da67e70c0404928832843367f7dd8dfa3e798cc300f067e646e4cb039be3f0b9ee84e2253a2689b4b233434dc537e5285d1385b58062363ae6ec809231eff1f258cf4839f6488b753c6b796ba50da9ee60ea084c936764dca09493d382871997036073667513e39f7cf84daa19e440b18cec99959a85441435bfd08fdf62e51b895b0c17d91247681ca79ede288f1590a41a93f991ad39882360c5ae27cdba6aaf167260429c5793cd5ccd9b1adef5016e64d981bbc6e58f84290e594de303dd5c45f7fe94c4ec6308e1ebc34decc3c5bc0fb7047d05e465b311ead1066bef6f532394d299dbb8d7171522e1b5cb450bfc9b4f0b8cf4afe402cf115c2c3d56f9f7dcb4428341ef1760e68a058af0e807bf42a18adef36a6c8dd3f63957416e08f4fba4f40351eaf5a009c1f3d50d7f9ed3e95fbae627b30ee21495855a4e512850cd9360bdd803bdf8449ddb9ec73db4f2c283f2ca602cb662438f6a1e227c3c135bcda7d698db6360d4bce879e81e189dcbdbd124c04d95ca03d5dc274f0f5011c68a5791f7a6c817d95d2bef506274f3b788c44a69464f2cb0000f3d7139b9ade9ef87659cf299f977d66c2ff1009b7178054ca3fa7db27ab62178c73cb38639ad5ac4b4f9c90c09897a5626750823fa3cc05a2537fd78f294db47a1f3a4a3f0df45231440ddcda4061a57807b421ec3c018ed87cd8fe48770cffb8825350f0ad8861e7a64cfcad27a32ea9370d26e0182db8f2db2c6582717a315adb60f48c00d2a966becb3e52383ca89c8012698d30286eae20cc8eea74f4011bb78e021da309366e49d047d1418eb580ae9b41bf260f1017d2f3f22b04061a0890d9da9683f7cf16a23336ad5010d61563857c890b1e267f11647ab93899b5f62151757564adcbc5202809efb6230cd1d19947b9fe6c38af442929805a357f3c9a3603cfbb996721101a13c5b2617512b416e7dec41999db32e8088502681933ed74ca29c75fe1f1352b4b94ff99731e1e4e79938ecda428228f29f160430a8aafdd90692c71b0bb976d944d1653f3c5dc8e567154bd8b756253e0e7580c0e6fed26b12003a7a8a13ac5ad76f45f67413fa26671ed93c0385c6df61b39bd6faaa109a0829e07143604f4801e5720458188e52959a5d7d6baca94f853d4c7065bb0bc0a789b60892ef01a8d6a6651be0a5803cbb28b5f3c3891b107ee99424b8d6069313d2ebbbc35e62c5805f0c60992c5e090ba1c32fd17e4d684ba47b851809d60113180c84adafaa24b7ec3bf08299051f3980117945db3ce2fd775d91574b1e4b3cb607a488eadcb387fc028e347cedd67e5163b6a34ab912383e3726ee01b85dd017e3ff17a06040f0357e474958ff9aa76a7c45c289b5ff245589b4f06287be8aaec2ca4b1c9c8f18a68c1954cb195a915f8b4cd8edde3fec5a9ec30fbb5496450144f8e2479b68e1e1ddc156405f45e28d0581eb1779d25c272096a1e856c190bc399c0e0c0d4d1bab1388b8fcc69e1997b1397ee0080afac909e7c045b2b181e6c6591e4ad92ca8fb6ca2e1602ba3d5881090048e7cf52791a5acf6ef22e49d18cca55ed2041ce1844555aeedc6334ab92b724d2f8962b5c264750a3c11f111af0fa4befeca44aa2c441726bdd51de875962ee9d673d212577e0494b893dc9f1f2076ea2b3af4555c2499f13d27d358884d030984c59edb302313af9b802246fc50a9664702315ed2c0bed99864461bae88b3e40d254a131a20a7e6ec4cb8081b6282a7be3a6e64c3ad1a0134be3d5dbed2c6932403b629b448fb656fc6562b68bd51bb069e162e09cd03dab434501b48d40481cdfcb9daabd62da73ce2a8a3bf20fc615f166713a7fc8be1ff082195134ae95c96247a4ba918f19fac2c26c4d5523ac3691aa5a5c132a133ad894579c03b3da7628cb296ffbc0f1c02b26d2fc7944e67915601c2d5184b79ab07f6119d595eea475d0968bb2046fa9fd0275a0c9cea1a1ca459abd0e309f723f2d4fcda9fcbf35c0287cd846c27b58bfb2df41090a7cdda70a508c473e33e733ede6fe8faaf627228bffe8085ed2f40a6936244ab85aef85c5bca5d02e0240350d4b564f65d6f27d3b9097fdd8260179d0eb1fbf33905a9dd9b693abe278436450cd299399907fe14032b97261eeffdbb20785798ad16774c7499abc7565588beeab1d9b62c6090d89c31a437633e82b1c861d126619c0d2537069f7f30edc2a2b3f89c9c0ef202035d7fda3d44ed9e65cb9b50b349766205ea63e24fc764c26ee49702dc836b427413b6eab33a95f77e0eba02375da3544ec7ec50997d46808267f42baa67ab44ed7d28aed67c781f8849c86f18abe4ef4c52612525d225ad2aa9335e7a7b6da33585bf1d6f4b592e853ea40d67ac1eb14af71ddc3b482026049b7146318c5b95051158bdcbe53a46329280273f235588625a9e726ff33c793ee859d082bd3151694f0f89028945fed400869570905306138e668650bff26a7f1b02a89654f0db86780258bce146720f3a14a80fc0cc503cfd3265ed272291cba4651cbdc0e4c3d54233b67a994ec94071e17b10fc9ad959c6863de13a3509103ece71197154f810b28aac71b810b982c5f69555cb0561bb3ea3b50ab5ddde324b7c4c19d2fb1972fa2a3b74e4a10354df1de5d49e35a79a8291ebf9b2fee7f6c67fa79058ee19ce729c060131d2af4fd861b510db865088016e153b3050a407f3d8754ac56616cd460a130f98c50babc8e9d575658cbed9d1d221d8b00651cc208058afa0b8310e85cc80a7ddb6eefaffc2e24f7a9bb7d886f1ab89ea8cd108b770f5b4ae139cacdff4a5753a2cb2a986ecd8d1a5672ae03184621fe4e08e210fdd2d3253ed57408c8d9f8a1727bf22ff4810deba87d44c8ebb40a3d7b1bb00640567909b401aeef254306c34412933e4a83fa0f614c494617c85cbd19061f9e8f1cc778453a8f749ef7c45c2ed2a362a8a9333c781fde05dcffc47a7280b957c8e75dec96b78878f9f2eafd40486538f0dc8a9e39944c785d1369c52172e5804b865177c45ed0e44dccb5bf2f1a5a6ab004e73e5fea79926bd0cea3a79e3a93618e933c9c954fa3a37395753930b1fafda91895b12c721f475c1efdab64105c874c130a5755b2daa8d82f4e39a095d9fa488902783718ef9ad1bb24e65ad1c63d9567cce61e87f6b5065a3e2929eb8d70e20aafa251934ecdde984a68e2f1955c91ea19b4e72a7d97c4eb0f85d5cf6bedbd8b12760395cc5b1f55fd90b9dc34f130ea2afad88ab917a9e66a61aaeffbb2946c79c6b23b161440637c1e1b19d7a79d489f52d347dad34711c3dcbc2a220054907b8b7999ef97cd1fc1b298a2a2864974c11208252cfa11882f9bb40d678d9d05956cf293512ee9c19b81fd6469576f48e8d1ef735fa2adda5059227711937d7cd7fd1b4f82fbc2b83b198759043ed751758359cd6da4fe4951974b66fa6156f5200164607de9b8bfb0fcbb561625f65e683200c49793afb5cd2f7ae0a9d5b3e1aea03873e66b1d68336534a935e6574c593d589b44017bd5c1442d51c1377a1cf7a020e84c220038eb037822945d2066bf8bf94383348cafd4ec43f15f965eba005dfa38c5f94d79dd0173418361c2652c4ca4014c6d0cda75a790a6c3b6c77e75d0c172c28e944d97def7b9bf023278373652ac0cd40851f94470874ec892d80e4205840504dd402b76863e2303983f840333d48bfc470146927868b43caa0f9fbe56af036f96627567684cf90fb8bc94437a27313e898aaf71de55d93720a664894be15e04e6b0692eaf21fa7ed279f8ecee91c9fd8f467f3010c54e58b8c3ee3cf83588622120379851b4cd506724796c55f7c137466dd480ac5c23d954a913415362dc572455ae454a2fa6092439b9c6a5632d84ad71aa96dc8574cd10d4143870757fda0eaa43bb958222f8d4f7e664e680ee7214a31420da84cb1fb486fae544dce469705c01619d9c14777395b892979c8276f4e656f3ff1923bf5f7da8e5dc75a76dd63ed1027b3b2512661992528744afbcb8384dc81d9c1addc6d13ca3b4ac70f33e04fb5c09c61d7fd5514c3109453fba7f7376747d22356e95a6c70e4c2d30e43d4f8e52825e83f163451592793fb1c708164ec42cd069b40ef372faab79aeb5d08e02aba14c8f89772c5c113ad6d4c635d718db58157d815a4a540b357f6686b29886a4aea35b1704d1423e1ea514af9eff46b03f7e40c146befa2e4a082743a62e493c56a59388c72c3b78637e7bbff6969afd01bf16b2fd8b8e0759dd5281b2d690b5445a2600ba3bb5515997af3c8d70a40faa3c1b6087b63274a8b953c88c22225637f931d6317e1d340abfe51dce3c8dd119ce2ef6c68a957288fa3e424ecdeaf16857b9189727cf047ea352b7e922e6735381b1a3e739024cfd994f4354e97e3df4227f08e61f1badbf04485f10658a42871c8f3df3f360f35c3990876a23d97f40af8fcad37b82ed38419ad85d44b05b3792b69bbf0a538118210d56c9d4333fa67820e086f4e56ad466e606c84f4cc9462702153efcefb9738e769f499ead904a0a266ec8e39eae699386d3d1a7e69c01345e61371e855938d850fdc6fedb294ae41bac012c82413f3f2f3488bda9195b8929b8c64d9e603e042d3824816f551d775c02bd3e042014622d81ea1455d3d8680b9020ef09b143345d436b4465d050acaa6bdd20dce09b342c0965c976d7e9c25811478f4935897280789c09e052abb292513246b7292ef97b1517837dbf7584d7826355e0c4c82ef4bd88cbedad2485170a98539c7c72774d0b2540bc64188c89bd4c05e44be5e66bfae8ca6d1844ac0aa6cfafcdb2c7ea527bb247fb12b663922516994b220407241a8c15df45c6b444b39f42ed0caa334e947ecea01e0e01b4999fc8495211cd2f03f5342e3dfdb1f314381cdca1b12f74ff7cb04bc79ed7b1a33347745c388eb07c760114d84ca408d1c2c6eeeb920ddd7f4b89be9c9c319e6a46769846ad9ba88646391849671d1224732c42b43c5fb2675a15156caf76d5d332685408b87f92245e70db3c999e57f8ee08e4cb6b836568e291631cb5a634c018363113cd8b3cfb6bdb6e542bc74b74e574cbcda6fea681b1b81da88f32a6412873c804b49388c3e136da31179c529214288ebf626180cbb29ada0c0e92697a3809ee35d5750a928a5a01ea0ac8e4f3cb615b002bca4909acedda0f333409b6a8ed4e3245f99bef2a4fc43a73bef2fb7e0e3d0e7347db10beec567b7f6d1a0d95bd9ca1bec8a6c67c091fb30685e80d6f9df290de3f41b8bbb3a4fec9566cea4745b2db16939930ce3bd515f85d5b054d88475c0bda4162217b89aeb02acd805495fae0b5827ca969cdcf76bd89480d51970bf68df2eea4a53d0febb1f76761c0d640586cc66e62c8f85144b571096a6c834dd44bbf2ecbc343ceee97e0570b77cbd8194313241a8d6f814684919f26ca4f9db682b84a6d591f1627ef86871d79e8a3d83d84f62c0c77325bb241a1b45e6580df458b80d45efcf3ea95b322aa279a250de6927100e51c66d354e259170e4afd76033d9977cdc7e34b2846d1e69aa3ba28c12c3b476e67b7b868fa73353a5cb2b228ed5ef9e33f85869e1186e487e5fe96b16a9b5a272eeee82fbc525cd913baa6052c51345e9e75a87570bb2189594c749b3f56d395d3c95392e2f4efd9452f95615b5ba1cb1786d18f655fb0ce96ea9525d003f817b37329f8c345bf4eddef37d1cf1bd719028622cfc2b325821db19f7ba70ca00ae07fb9e6ff0df889c884134f86796a680473bc76ad9a9b8b79ee7ce6b782d652615554de6fed04bc06d4c5f3bce8afa8171c83943ccd4938b296410aa9cd437b9fe052d0d9d2c078716da054ad7b430e9c20ed62cc48f3b0b12857949afb94e68e2d7779447ce82038a4fa8b21276704162160b5ae71a9a9836070e28496a2df502a8c404f5a13b6880185794ac46de8f1e1450c069cef43213e6d7d067b47545ed0a2bfaff20f11d798c13cb7c0ea1a29814602aca5d6a7d1116f97fb6bb8928afe32fc443b7e03448dcf4874939d2fb9dc54ec2be43f11509cc9bfc49e80cf4552cee392d321a1e4529a54b904ac7a88097663d64d949d90f9df9482f866cd027d9394816b029639427f392b781a70971c310ae20e3591e59c76dec0c768c1d3184d78891321861333118b865d15b14f08487316573211b30fe70bd8cf11715acd5278cf10a3bea32221d5269fefbda5878ebf5e45ddf2f580b1e0a1f19e3bceae34a3ca7159d3fbb125fee3b28405df5d8e0ae8d9c9cb25ea15711ee33faed09b2d18771b047053ee9db5f54c8451d475a20e5a17b14d88d1c8301264099a13358d0639bf96f600c542a812424348cb027f0497f9fe7b13e5732f99a389429bc1f11394787aa361f293dab8b93b52a80a819256b34183c7a99e35c1017c6de0eeb1da011d07809e703394b3ec37148ca8fea80e8692c19ee376cb7c6ed665c16753b526e43c32ef1f1bd40ace941cb2aaa1e66452427fea2ba8a75fab091612876a1e38d134474b6dc3ad6b9fd9b3f94809387112a9dd0ef897e794285fb66e4ac3eb393087579e873d8b645ca62407f0ab9d8095e7d9cbf75008d63c3906ddd2f69b194ad87279b308c445cc5a508f8a2c0227180d483053a945664be07935c3d10bb00bf16f8b34444fb3566a0bf04d0df57bae4bdaedb39497190f3556c51d19fd7353f41971cd0b7ecf145af628b364c841c6d99ded3d8eeaf3d12bedc1288585c112809dad72c3a1141ef622ca7cdcec4ad074305f961212c497d5e3da196ea4fa4b87e00ba79012d0914e225461a172ebf1c89cb49baccb27c31383893d463c2ebecbc5d4e4a2c3b54d0e38ac21b90c5e8a7dfd820d074d70f2dbc5bb1c3cf01c3d8153fcfe8e7768d801dc8904f5f2a77d0b8c91dea52209aec560413126372ae7adc81f0b6ae0d884be4298a59524ff80cadf0ed8b13804f9ee9a5376cc241d093b5d04bb43d01633c1c95082b975a7bd22f27878793d7bb7ab12a665cfc727bb4b30bceff3740683a3d17ab1a07db3e5aafece1ade5cbd1c6506e4cadcbf36a82c44c8714899b699bf1a88637b66f2c9a529b2c3875bf03b4d20e451bb4411dabaca8a03dc5cf031028da62da85bc971de37975f9f4d787cf24de9f236f7fa543f59c33b8da97a6c43227be219de69717263d78605fd8a262ef3bd56c1264c03834d1dff8cfd00fa49b9a18e46bb76633bb89227e609978cd67678572dcfab9405093fc8f92fa9fe8ea643ea110080bd1bb65c107c6d1516b5d8ec820abfb7948d8a91bccedd2219c6f6cb123ae369adf1cdaf44512d425acb64e3229acd232da5259af0681efec2a944ffefeb1cf80774e41f96e488f2f4e3d9e5252364cbefc358e8a3603e4eab29bb9362d37c3a0d0da615934e2d83c51fcd725a16454ca4389ea59efefb34277ab9ec678acd1c8bb2bd39db618a5816098fa94d3fd1207fd74b547ba1db55ae113048074599f588083968a4b4b85c0c84248c2454c3560c5910b455b2a3c58afd21f71767247e475082ab953b7e45f5524e9582465da05eebfbd6997e4f992b2f4f5a4db881c06c0a4d7d67bc1f89ea57781af84669ae280a0b005cb07592305274b13c07cd274cf89909791e90d7ba5677cbc703b3ac5b6a2bbc0458d9430b0f4e52040706b70b28e0a3d51edd8c334f4659e53ce3ea64c5818b52cf7a23b852634ae66282fed75974027c7a2fde03d72f33a0405017752da647fcc6586db16759d20ccd138705eb10887dc2b1bb9f8dde688f2e05b4cb06bf1f171dbcbd80c00711a3b064f5078878e0587d35072b00350cc416c71bffc577ba38cfe9e967af0126ee13f70d83e033a285c5d09334bca6c27ba71d4e8e328cd8a3824c3210daa9f7d9a57878468ee0bca12ef01190798b1a3ffc4228f214d449333111590d5e9085957caec71d2b76522de183abce98e283929bb0c3c32741a628e284cf4c42337dd292702d28e9a063b65193aa756b9b1eda37e107a249721fa66e0f566e236b042477cc24498bb8e115ecfca982a118f28991640a8502217a6d9af9a44964c5451f78eacb86ed401f0986db768170609ef253a239de19d036e78063c364888868eb4f10c2f1111fc102250502d7c51fe605aa6002b85e909bc48b02bcf7759d2e4d8c4208ae03b9c850bfd5234c496ca985aaeb6efd7a03c2916e8861f80379887ace64a8e5f198dbcc28c6d44d9c4ce7e529bc0ca89ee8dd376702f2b4a8b5c505884c3894d7888b7a620bd351be945398c0a85df348a5c5e1e617938bd8799b804ffcfcfb56b9466af445b4c140b745c255f69a6c79349a4c32a1cfd44aca486ff290fa160413f9fd7e16088e5304ff2428d209c36ddd3b0f651d636f423e24e3320371b8b03a12f390054ccade002aae2422e84fda2f007b3e7f929ceb911de67daabeded28e3995939401ab1ccfed6cb211e1fb8e9c187518c63524fef89127360f20a76c851bd7c98df9980922f9671015a120dd825ce4a4e670314d0d5923d733f64cbb2ae0954e47e2e5c9cdcb05f3f7a0d2b91111e5c1d641c654b3f12f543fbef36f58b32b80270d27e48eeb3d44c9987368972cd5938890eee583a4528daa243cb9d2ade01318176a1ec83400551d746c05257377d79dafe0e0d5e1dd9e0445983c947223a40ab65dcef9f373b469a651da47e74725e73d077ec8e6965439cee220736b156d504384abb47256734552ea69b7e3c8c6aefdfd39f684beedfd5addfe6a32c8563234d1c9b611a3e59682de7efc3f9cc9523a56e9d1beae5aacf5140103989c2fc295ad7a234caef29f09fb5e6c8108683702b27debefec2078b7bd8f30d63b3dbbe5a09ecc83aeafad2f8a7bca3eb97811049ac0b7062fe9bcfa42ee160a889461a9d8480ec0e816c7beda7fd032f960be7adeab3b9c8caec1322938b0c99fb87ac18e95726d3589a2bd914ee15614c8e2878ced75a91ccc2b267971f6206033d6c40842659c1870f6f464d0c4966ca4eafb8389cc5c979f83f208c3a8d5ea6a5ecf2902a3fdbdbe7d55b5e16bcd1e2d120c58a4eed2ff44c5a23af32a21eafe5274ae675bd202b1781b7b977bc458f31341cfd3a5fcdcfe4d16fcb1bbc71d36bb536bc0b41860ddba15cd57ac95a4ee5a80c2ac4628206b616561048263bf22c5ff297ba0589ea6596df46e90b8098d1606bbc0d8cb5c1374f38568380e479d9d93ec01835b218b3ed3b6017d4f146672bb16272407914d98677cbb03d85075738d915435a98ee133ada2bb344c77f03229762d1a06247fe9559683c493fbb80a63901fd4f30c9ced26ef9665f39a0cb7827a2303ac124d2cab1ad8efc8815588641a00990e4063113cc3ce6e48e056335808fff5bb61c61091b26e2409cc591941127f89df7548fd6e0a8fdbe87e72265b03bff47b848ce41d279cb386505bcb86e1512a82682e08f039accaaa3f1d821f8b8ea833e666c2bedb0bb1f41ce8b1f41b25704321c5dc7982e73cbee39979d9c8b07a7c1ad72f2455de5e6079621ff4397c95624d4c4e44f563a56fb85ce99d6693187bfcdbc7ef206e312f597f6ff9b4fd2ff8f234c3c873d66afc7ed2093f3fa336ca02f5d93830634cf50cec09e5dd3433f6de986aeab6a67dc425b6d72fd445846b305e31347b76ec7c9e7d26b0228e50bc1cadbb018cc32c211f40973cdf5a195e6c31f891c26d75cca0749b4b01b4d02309819702979098e58cca06f06ab16a7ed5b09ad5a57cb942e6bcc010428c38bce727881b00cfeeee52de91335e62b9b31c3c7e1ecf528d05502ba54c4e92d902da8bf41db79a83351565998c25dbedd2dd05c068fb2d08325c480095ba9da00320370fe0cdbbd9672169adeb1c5c013deb0c6f7824e796a75f927ba961c7da8c82de7a2a60552eb63cc2e7273ae33caa3e8c15def0aa967dab2c1235d47204ef60e8ac14ec39c36dc66272a09d368693d64e1a7d8548b501b9d64436f578cc0a91d7fa1ebcc0711a8a396a00f098dfc105b8fc4450ffc77fc1bcbfba6881b0130f04f78fa6199ca3e2ade1e464b2d54c3d9d36f3eb5f6c814e08db0ccc8a76b8fe0aeb85e22cc28c6b76c48ebc9e4c936c8cbfde80d50067932a70488eda1cc5418fdf0c1161aaa3389b47e3568e02efc6a8476a7a1c95edaf4cebc1693e46c57d739fe01def2e988f36c9a2d86089a8205a8f66a017ecd373c5fcf5c9a7677e5bb2564ef4187fd61ef230d5bedb92d1f3376296d6a1f738f8037c5425e256e2d54a054a277593a3698de56f2b439364c9a8ff736e74e993a741df893fd7fe589cb2097de9d4892cd0fcc27df14b77d7d6e2a4e32781d442a1e5c3ff5a487038e8bfe5c3aa06a8b44c53c4e3fea58e58c9d6d59e43f9c455e633b397bf3547d611b6e0fe3263b90fd73e503155d8135139d6ea9bceb09dfcbee6b68d518ef4833102308f05bdd9bf5e872d11da13a5cea7090c6215cac0eab1a07306d73731c952939fe242c1b2898b4ddc289d37ffe24a95ae4157389dc9d49c8b8f6244b2b55150a2b45e149a04005988b148c8820015d5117284e9fb3b9a927bfdbf90611f5345564eac866f1a22c833b2af3582bdbd6aaab9d683f4e45240ff7aa142329b53ecbe889501b987441c07c799f30585fe236fa0e10660b4c4bb9bc5daef4d047f0d4b9e69de3d5198d97343f303090520fd3832df14cf52cb583e3a6ae78a3e313981ecd011150c5f52546ab710b1d5064abd2d6e1a250b1e325e8dfd948e9b4635af7f821fb0f95e8ae8cdfdedee00b85f71430b41905ce800b2fd544a4f19afa98c9ba5019845343640308146e5ba8ddbe8db12775e516ccfaeef95d2ca8eb6b4b7c1fac90cb34a6f0fe87649fc06acc9d45139c4b2d0f4447a9589fca8468efd3465d36e01ae6c6a556df1417ce4da61366f3b4359e082c43f7832b46c64f52da8cd249d3c30163eb948199532daba5c35013f8ff5c0f246adba9cf79a03f0ef80038feb71211ee59bab93d725d11efff58b77a708bca225c6b40eb87bd468051d9028d183025c67c6b9b8e7c1907b8ed204326cc6ec953a385a8b13b532a145d74d78808b17360117c68bef7be55f3d8f9f1910d46be16b86c3f8d810235cee45e0945e111541407b8f3898c8ba21d73806765582bb4928b726323381f05acceeb205f0f65fe50fc70b016cdee488d459c4f6215b24f8e0f5e5dd2c0bab0a1b2adadddafbf6e10a9ff2ecb0478da5d73ee4691874bbf53af8dad139cfb2a97cc9f3b5be8edaf5602ae0f6b76fb911353420ad352d76693d5b827e4604f7d6ccc57556f35a9dd8a62b4676f062a3f9e7f764ca50b4bf98e15c5fed57208ec61e6aa52410365a32a65e31a3e93dede1b81ac0b921612618fcaf5137f0316924cb2ba91afbc3f088b3412f0ee0ea5c0f05c771a6c00f637c2ff4dae3abb303c073a4860960403e720c204e7f1fad39709caa27d337b3d8f572b435cdfee518661a1fab8e64c7aac1586b56135d92d04ee9f4d63bd516c0b8373841cfbc5d25c7e808eab1e4561e0a7a93ef7c731dabbdf6405a5f8b1bdd92a736942ca38c1eb349ee051910a27e10fa7b91ca5c36b8823aabef1560e81e719523f575bd954e8e7339e6bf5a9e8898e34a5044c255519bda83282a5114250c62d9ee4ddffa2f527888c3ac010c8901da01f4464842662a07192298eb8ceac5f06aacd9ec8c095d83b6fc4750ef763061710191f7f4c928bf0213922e17cfd6536e7b33fff955b81169749f1a24fb6bf3cfdf9b97156092585e526e78c3784ac03e78a6972122ec1f555c61ad2cff36ba604390421589e045a8d8b84c40507adf6880059aa38f437afa672929e0c3aab215180009ec6aac1beee8a69193f681eba3c8191780fbf1e20b8c2f1f62a7a115b98eb1e41499b8844d362555183c6e3eb8d203c692595ddf8712006d00f7be4fdc6b42c90b9d761a1a391f2804a517fbd31befa9c2c66238b965d8aaa705457bf331492926aa7fa412072f2a55d43b667c3572a716943480992cfbab67cba785ec4599643d24691e11e90ef8a5fe71226254ed1578e01342370d100a0b908d55a319bd39f03b5e4f8ef37e08f08132b861af9d7cfa2472173224eb4b1c38bccc3248538457c8053a530a8ae51adb598f00526cbfccc4c04a98af0306c82a11749d0aabbd1b6b792271985770eca1f4997a4ab0c6d8d5338515f50a40d8c8459d845a8b275a4ef9042e753d4f5db404563f4b071639572520742d9187634997d189dbfa0de42ef91b8763fbbb5b317d6ae28543b9d112125506f9e16be829ca297f0c1b3df5090a63763051609219350dfcf5fa94678abcd5be8ca8339671a17cd1c03ff374ae99f51bd1603a2fd9322b3e8e4cec10fa41f4cc756bc46f3a1ec5d0f301ed8ec67339f317579e66fb081581c28588ae07f415013c91c18fba3b17708d838dd92f789e061d1356d24ac02c0dd0d8d3ba44f89d5c8068e967ceb94889e3e9e87064450dbffd478324cf4270e13f38285755964f537853fc403042b298e68b8368f58259cd3b0ce9bb468b55bbcde7aa59f90b3b4629364c128dd11106a82541c474d47441defa9a7f9938c439b8a2997211d64c9642a607c27432e8c6ad1ddf089a30ec1f4509bc0c26b922cb9fd16c68cfa4cb6db18fe540352eaead0413a5469fbe9a65cda02c7ee85ee788a1fce28727b3a4e2eb0d320e1b568b040b8c4bb85aec536a096d12d0c2ad7adb391190e3a986aad53d1cc8640f6f42e1375e6a17673b6af547e90ec9d18f0c7e447f8109d111f3446b3c72ffbd4e54d4e95daf9d7b1e57a0a8dd50c5395789b2d50e58a0598d51e682997d6239a6235c1e3c1d0415cd0226df024a5d5a4c27010ab4488784b62d83eb2d66ff073183d34b028a101ff8c223eac5731199bdbb907c02cb845d3abd65008a26b44b5ac8195b12931140e5271483179949ecdbc3599abef333c0305bd4f7005d9bf6366428191c05f3399ce9027f82b5f5812e71a14ed8a77c4d0cd7a8b9084e4b95c997e3b4041a64a454ff9410ceba45f069ec5ac8f434dc2172e147c05c3c255a094cd68609be864c7187b95aa7c5ea772e295581975fdc8624c10bbb847b41986a1a18f6385930a229bda2ed9acf82e043662dbfb357c6bdc288f4f2f1dd9f77ca03ff6f0466b223fdd86e13ab702b56faa9a1d2124363f76b2e59dd73d62910cf27ca79b55bcd0c179e0a1eaaee09b3109ccfa525ba8aeb28c5c329b5aa16eb2b00aed95bf1f3d53ea74f7af1c0e152137d7690c7e59a8a7442e6505a20e556a8c6d0361215711ab69d2ecf02ca479a40cf4479b4d47c8e082d13e4a78a1fb250f3a00e2a7b03470a6e790f266847048d73c388ebbe0576a69a21867b50a56d3240b84eeb1050ce30f51df03facf240fc2737b75f20f8c1f0bfc00d985ab818a44c9c3b43c214af8684d774b88823520d9986bdc0030b48be3261e90744ad06447b62123fca6aea5c073ab635d7de7d15104668d5471c72af988a05676de3d14e2ff8b2dc947626ce4987912034bb469ec6d324f24d2e0ee99d784db08fe7cecf5b1a85aa0558531a752b115c0f2902828ced5ae075662a5715beb97eccaeccc5e2204c011cfcd0ff0a73b3f79512a78d65da5f2c448e41ef030c2b793a33b53233d8ca4caaed376b14f1439904c84c6a534eae9459c69948654fbe1094bcd09848c0bacbcc65289c9ad8b5acb7253c9e63d59047c13374ef98a28495f3dda9c917b0174726125df9f9242e258eb46ea183b467b38bd29773a06ae66edc46e5d3ebb7c30b5c5ba2d6980648505cb5769e37af64ecffc9c9fba4c3e1236ca722b7740ceb09f8f65017f45029694eb6ee9366a50715d36e507b1462eee151948956beb9ab25824611e58059e24bb288efb57bc0ae052fc7184c732962b75c3f599088e0b2145dee4b46cd260e50296eb3c4334b7da4757d30da6ee8a3dc04250ca2ec6158c4b39c02e002a30545b021a93569152362e60a4fce5e2b0adc835fb1fbc91e79c5d32e3bc4491944abefef218349fefe0615bb64ec6086ed398ab56074b98787878650a5d84ad8688c1a4815f5be54c546513d381a6e744de59086391621abc8062f4523f4a3ffe4e9355cbc8ba6455ca6044d64691c215b44bef2ef281d8a2074969fc411ce749b3f8de30346694764432f467d152053262610252f89f67f47204e3152dffa2b00d39b122377c1906cc63ad40f38e4bc1dc49a3606060517cb5453d0434545ea8e02870b859d2797991933fa02d40022fb9f4ec487b812a6b2c551656b6162d6ab1759e212cf2d42872a43e0e3ec372d24f37d0f7a0e6daf41a95c80bbff0e0bebe6488af7971bdee534414e3251f37d3ac799860e7f5fd4b5a093b152940a8b4bfd6a2994eeefb0eba935904531738fa657f40969208c7f7f2994a5ea02f7a8ec9d0dbc9c4cc21d7bdef28a753fb66440fd19f869495b0254b3fb5a76310280719d06aa424d6c656db36ca44013692b63648166333396415c843628f94abe19067717ddea9b9b8f4ec0f5173844da8ddb29f5b633229295c741d50b64d846a6919f798061e383158e3dcb2dc83e171a1a0db89c16000c92fb1e903789fbd75ee15ffdf1e465c35fff4364afbfaf0d82d4a5c1b64c31369c2a72b2f484b7b5c773234f066760f09a3b486519ec1804b14f5ff005528f40c6c140be2b27d7a87ad1cefee41d59701c540c5fe38cb3f408a28ae60fb1f489c352821e5f3eec3b983c7e84f070902cf36a5f0329dea20ce823e7d52cdd341faf293e4d3fca3b6b4f59a01d18d4fb3f0c8ecfbf3645782d48937c02f98d68dc1790220554f573186f890bc1748a4597574a351d09bbe7cbbb13eea38a36032b7520b900d31dfa05b628ef1c880c30eede5673e8ef87be4c7e1eb3e55b866e0a79dadd40aabd51e921593fb3eabad598bcd788bf04b2c9ab31c7e75d4e10c224a11e9cd4ba65f08e3cc21b01dc220f0f6f5ed04294f40b74bd946c45b5dcd841042204f87a0c9717aed7ab3d2a7e0cebbb3119690915dc9aca0012a7ef3130b7536e2e6ee58f192d5b0ac29fc0b596748b9540714395b971c789a720136ea2fa8be33155595b6d6d6772a90b580180f8ce6841253249b30222e85683a470d91e0ab8f4b70bc75d09e98134fd31aea8ec283a8f09de0a7ee68f366764003e7f76ae6ad0b9d7cd06599c9ef408b1dc97c52c82833c5317b09a78b3d65a375e56e4778f4b56e9b52f5b88efcba089e1a16d9a76bde1d1a2b4cbd5482a26a1aad7a7c7943776cf268f8881cfb7c09d80e120685fea9d962354b9b78278d0108992b8e7119a2e11882358e84b6a0ca60e7f372ea5a4288b6d51fb7484338e9e5e9c055cb4eb64f71eb6fa4a97ac46df0ef065bfd2fbc7191135d0314496d5d6f6d0d4ea9d15c51499160462b4659f6f67cb5066df22d47c1472e245c4bd146381a3aa6a735dc80d6eb96ee6631cd488ef3e049664085221c92cc74329a41edc4081a040d95204220ac4b61e7d42aa30e2a0e28860eaada6da05f6e0679e86e822c548782637334fabbe432b30e7dc3e7d8b0a66d3f8fb007fb6a188bf7533a02dd17b61429582066fa45ea122d13a8f2f60397ee7b184d750926b9fc28f8c4a6d27e452aa3b6a52f239f446ba9eb5507c1f3ab679afd9efd684f1845eed7a9da8cfdbba0bb96f3a2cac22efcad9e5dbf43cd628cc9c14b5ca529d572770bdd9507b3de01fc7ce78bd3b4d4fb9ca8ef177eb6d58ddd0812329467668e28bf966fb571cf5643c7faea3059afbc912ced37bbf97b964c2784b009f2928709a1825dcaf8ec062162887248ccd996342aec5b84102d5a6808ab3063cc6f35572a62e1d60575b5670401b140f2f797353a151969c240abcb8a20228c53ecca4065eb49f49c471e4955b3b000f70e0a4be99a45fd90938b70e66deacf1b407386deaf54dc40afcda5a6fc1ef220c125caa2b68bf22ebd66b1a2b164d048e9b91f043cd90b1eed4d2ef84b7a24dd553fc67acccf4008e53f6b294901957b12f5931b6ac2b113317a808dd0198c10ac51bce247a1bc793b8d6e96222823580bcf9d5e2f028cf6116b88784fa1477a281d1478ca9f35bcc636c3f7c5a281d85d147496f99f93eb35db15e8cc61b4d7efc7d2b79128fb569443dc1a64dc61fff640d6f6c766e0d12215657bfc6f62c4750b4505f78ac4e10a64a32fe686b7615b69c5c0ae92c0a22700f846c218276444d40cbb17ee03299ae07c477e25768117b896aad7714be3377a34a3d45c14dcb5d9f716d6a977369d902cbfce970841ffc4f5af51501f3884f3e731b1a35867322e79ccf47e886d3b51a4a280833144b7a5474a04d89b0964cd6901b48ca40eb973c2bf394752dc574425f982846bd873182f02d91024493f710e6c14c9b46c4a1c08594c76df400da0f2e01a8857bfb5a898582d00ae02214b6e6ef2c3454378e5c21489225b05db4ca9352e449d2f2eee4e5bdda8cc85296e8ac50286eae97a543630f61db0d222c49d757cc95473c494f063da26680a3b9513ee5830a644aad338cc6feaa84f8582bed672ae3304b0598e44f3afd3aeafce0814fcebc18e38b4355e87072329138114b99cbc3556467c8619dc2c96843a39cf5423fe3c5f823b705ca74b8e12b46a32ad5bb82ab18456b044bd7f221badef67c1bfa5b8b8486a96f32ee7604e8136b2d3b1463569c224fd5081938db3842338759a1e62d8975b51cb035efb896ecd57b988c9f98db4b8094598883b5774d6e1dee0ee66a529f4138a8b523d5f4f2ba775c60f15d6eae4df50db6d3903c251f32f6e456bfd982dc5d33e1a89a497b79b9dd5ab2b5bd0f546a63e5fd02c775124834fc825ca88a773ed052fb968884c1f2d86d71db0831c29fb86fc8f1f562babc4a55819fdc726bb5025497ff15f070fa2081c07cc1041d733fc712687c483b40499f62515e8b23b4cd6136430e1f8114dcf68937942d3cd88069bf34d093fd49edb71ae438b505b0db13f7fa85fc3c3f90a70a73c1eca04b893d396d5ce548a608b56aac3f461f3e1883c6b6145afade6c7d47486aff547ffa1e309464cd51cc8abe60b32dee670bf29f10c5d6c2f7b35403ccd563006149c698f491129f04805ab7acbd67fab2c9f2bbfe74ad21faa31db21bd92974f4ce58600d52c957c734a6dcfc42d1043c1063cac03d47808d022b21bcae03ecc905fab4299a5ea87db60ca89c75f3d0d2d6df536c884a9d4de24943b1010180183ff4cdecfdd7ff9241fd9a3f61ec02c3eec0649c7ef1927276019a35cc76d40bbae92d2ad134498f5c8291206df0f47f7da3b3add1c53e52f71b8b45a48358c0baf7b80207945d21a5a14b029f29c6c70cd2d0a7bdd7701ae00ec42ed4f9ca8876dbd0f5a4a714e3329225f7429d8bef3b3c99d5804b695a2a18d2241c265321802d0ca5994d49fd05fbc192997f3035d7f355d2f03040518916a39b8fff20832233f1f635301b10479b9428b107196bd671ad3c79b062bfbda63a66242763aea0c90d8f195331cf40e55788661425ecec129d767ab7dc62db50a9c6a84f3822163ddd55f8aaa6f9070b4fe71b9257f7fe4279840e06a57414ff1fd6f14506cb6ae73d3e82b04d2cf3a883b16f3c95d1a56046b6b242048c0990072ed398f2284a98ede53d156c3e4e8476ff4f68ec85cde5dca377c65af6f9b4c88d5821179841d8db743c4295d300d020c28541c4b5389179e5c20b3989843763fcc75f9d857f5e82e163c75dfe661eb532b4e5578532764f12ea9714994ca643d5d1029edc9baaf7000df0d511dac74852796846c1140f720ba2c0b81615470467bc1fbf81af2b421fa74f0a7b3097fa2f612a1c85999e5e965986774b936cebb08a1615d8f89af748212b572a633b99807a0de10d7eed93b476685f9203cf8e17dee0cb5b3badecc917645e8fe4fa6bfb31a59689760ed39378155441df9f182902d7939b78b6dc8a6cd193829dd2599a328ae56e931a69485f2420d909b73d9da4d84d927462421efa566b53b5228a0107d2fced97c73bee3e59fa9b712dd61f4a8197531e9224f95e5559bad5b270a3965b34fdf71ee4cb7b007dddc6e84e02a8610ddba6924b7a9ea6912e07d494c8523827b1894ba6bdb50e17f14c40cf92aa43dbd6a21fd9b01eb48157b87166b72d1c59ca7d6eb591d4bdb5a9bf96433a7e90c7bd05156dbb39fe5f73f3cea106fa4e084904765faae98450b1e28076b2fe166cc501fc13e348389cc00953170fb69d8d17ba463bd930a6b2fac7a720f214b0c0800f6303326f030a2d08d7d76b8d8702a916a057510362d2b2dd0484e9762b938f4b76836b77c4f7883706d9d1414ecff5c94e9cb8cf875985b3e26fa47e7ca633fcd83da2d6d97df527ce3ebc575aa9aef2890aa645f1ee506b4524da4930761a56a4536f3090473a97474df0f1ad17b5b879d385ba251ac5f9a5c64b7d929518719896832d579e0052db554ab831fff57550b9c2cbb03ab063933e05b1c0293f43044f9dbb623825ac23e12b1fc4e674f0098f1acfab472b1594b522515a416917106e990b8ce03c3c34091291c4e8a813ae3685f0ef1a98500f94308a1d756dae7cb2a5f6e658950c04e4c85a4be542a479914dc310bf9975cf4f322f5b52379eb11037ed306ebfa3655f630ce5fcc01e9f9c98166db4f5fe5e623db08419def7fa089d080841320d70aefef0bf2a4509736d4381f81925b79554291f956d85ec7962c30373e2240361958d5fedfd12f05eff5a5d06742e4678de72102b8c0549b00b2d21fe392bad65083ecc6012a327240bbb1ea6a11677274c30acb7e1e5af74a3b836b195388c735e1b1f97a0a6962a55d1d9f5c813896a7c0b1d1625af4bad9f9cd41c8c43d778dd373bf0f9e755d83c2a86a444a63c997ad0447c40f54632fd0670905deb60dba56a574d4649c51f7a314de94b19759f6c873753408ae49f71aa7b714329dc36bc202a6e976d140ff3529492b5c87246bd7fdf145c56e8408bde28f1f9d5e9feda39d0c5b952a073dff8627b7ea805f9d57b96121966ae616751879a27bc0cd9e7671d894aeb0148c3f6c6b94d53e09bc35b44753a9e4d775fb5eec89dd14b66cce6f65938355d55c0c5a3ed5d2d6ba02bf1defc8d29f330871c5200e9ff49c4ab5f0ff17159cc96ecfbca8520672cf8c917a4b5f3c632e862609f695b774ef219ff7bda407a08f15b0f75b81247dba1dc1dec5cb247d8dfebc17f17520556ada65aa06d490ad59fb8e6c49a7d9f7736fa4af0afe222686b141fa0158aea41ad1e8706f3fc1692bc32e2157c2a4e200350c06651d176e9f0fa304d0cc72a4931a550b6587f31c7c54ed61ce0e010efa047a58c50b2a57fe8b70e481b387e37da9976ac9850bf24c901ffce85072cf5865dac2a908f8b882047795b8bb78919c2607f8dc3c5a718887f70d08520dec343fb623efcb9f448c1550f07c1ba075b910c8f916b65450faaec150dc6c2d3cfa2b56776082c831e885cdcb5b69235d4497e65fab67bf4ff8839ed58004fdae901f09aa887e147bdfbf5d65c65b1999084ba0f27058139ea1e60c0d37cd68948194b7c0e8be9f585c64bc6c5100ce9b7a840c1b06714eb6f7f4e2cacf54326a33a49d6480b3742d5e3554f47ff171e187c51eb6aa0976ed496cdd87ed71aa3598c8c8691360e181bb2247e3dc863f5cad877b7a5eb97135b53dd7176d7dd3006d41744b58b861f889eb4468750ee73278ef2b21ca1d5950073c1e926da58250b7aa7d6478c4c784f0bed51d158f0ebe6fe26330b56c7d07eb6809de72265587175e8cb17e3ce22a05ba4500e543f3fce8e5685017928857d4793454fc5166c922f2cc327b8faa5825437b6d4addab460aee7116537f3cc418d47155f41b21132578edc403ea7f62d4e58567f007ff4c61ab1cb90d0cfaa09a8277a97e45a8b6e78b162a717221af6fb13d515431aaa4a5f1ae85296165a6ac3363d61740b3ab36e1edc34e8e73a022d724bdcd3a980ffab6e1de5e3e8e1ffa931f263d5af061e1e56a83d503791bfaf1c2711d1ee8280d94c371afa5baff85b174653d6c875dc2a9e609f4484b3cb16bf99bf630eea650ee31b31e9bac271579a3eca32efc7bf5eb044ea4589c080ec20ee8aadb75cb7bceb7cc6890a3647ab4a28236f08a7d7fd1d82f40b82a5c231143f6261e17307c6095423d57bbca23bcbc7c95d3a72d2c35b76f67af91ebff4e8dba568c277e13978078944ba48ed8b8e1758a17236f7c5dc809936a37e564f8c8d9d732019dc49802a5ac3cc039dc8c795acf1523141dce6eb6e9aa19fb4f72852806595ad795a88ecb557e5e7d3ec0b85d692981b1d577d4c1668b822efd5c3fadd2f4e82fa47e701e65100a11d776c292f27656edecd981e89245be302bfa8e5e81f18bdd1cba40a5ec19656b02e502fc18be709cc1699f1afc16ca9353829eadd98066242e4f88382bb879148e9da0dbe338fb7d083b6fbe66f3c816a3b20ff266889bec9a43932dc638867f85e655f1384c923de503f4c1af2afc68a0a1fbc2297da0d7ea3587929a9d2838c8e09a535aa4b76d6a054e267e3d9132bbcc60447606306dd0ced5c386721e0403edb3d8dc2b64d09f9a239d512b04e0d6b3814196502292a118021364eced07821573f4cf3da7d6ba94ac75a1087c6e7a78dcfe2f8b87741cf156de9d449a58e552df95b6cef5716428b37354f98f62023887376ab4824a55d27b8852181028d24bb517f0fcf60695aa465575b7d16adc11954f650496f52d24cdc67593ac11ca4291676f48fd23a342dd4b685da3332ab5f4991be8a6c6e89c9df6ca31467d49139b90cce8c4d4c06ea3b35ce854f143f1c03bb7596f7462b25f9c8262d49ad7dec663ab49a4ae0fb0991d0a35b6dccb1f2e7dd5be6ab4a33f302331fc2b2798cdde9b71596d2319478362bf842471b7ff025bed5e28ee6c509cf363e15bc4a846241b62a212c39e895aa38478592d1516ee7b5b95c1be73ec1f5a1285a9a09879cfb76eada1f960f23f59eafc89555a69a21babf1e5978eec61b5c6a626d0c22865e14d30c6b72ccfb049de909c0e5893bad84ba0b090495ebb2e3f0ab28a5ca4d2ca62b40030a16c9dffa9136916adea9c9d1ceae7038e2ad8d831a2734b87f0d7b2f6f4358785e9723027b308fb39385b8e4763e6e67fc9b5c8ab22928039684407cc98a5e7d37803e6f4c1acfed4bb1c37e5cc1963d3bf4c743c06633c68fc7dec89c9e05e61073b5a5d4e9398ddc8c7e0bddd5f35923c931b3d44372de55da5b9506a1ce657a24645f93b58010077e1688aa9cd85404b7c4c61971ca5ed1277364535c2de422f01e082a74240677c8e6289f66e51350561b86de8f2aa2441913567d00c7aefb18b124e53ebf057edda8d7f188b653e06ca313c8ad9d723b8fb32f1a27bedf5cbfb6e1186c367a54d0fd303d7bf0f4898164f49652ac71e0b38f0052b202d93218592a76a96372ce426b1b60e2959267c59fb08dacb26e24d24627e63b7bcf632f6d3d75a08efa32707fb9a2bced37b22e81c2d9d97434ce3a6a7b0ba434fcfd6017949e25e117db16365681a49d5cc4fd7363f520380e6a37518eed6759fa062b811c833dda6528674c0ab7c2be5159a62e8c2abede6270149c965c03a01456f581803ae4773547491a52c8b295504bf3492ffe5bb220a43e1cb6001fbc75948f49ce875b3e055c1fa2d496914d7f49e98e7a1678b2351aba528ff14a2252a6c753bffb0a044f76e813b84b0538fa1060144887e98976c9eebc5f89bd03a3b4e04b68088230889623d728f9096b1b29f97066974153456f15f5fe6aa040ad4df7ea73fe6d737acb29cd20e0b87b158d053836670a23b31c6fb27fc13df39f906dc7a7289fba17c1e3b5d0de847b97058c6799d409d78a93f441be76eb8d0719639cbe3bedabba07ed830c55704aa1054e6c08b7b26be44bf6345fd8bac2094d383bb1863e625c538050df18cdc375352f06e6665313d6789299d5692393fd1d468ffa8889a866fe5a6f9aab8288b89f68889896e146a7427c5037697a0eda944a3f4cdd0d98c308fa41d397ca52fbc7d653a02f5b2ea7f08e00831546719dd025a379c9fb87fa5f1eada8d64c1c3c8e43ff861a331588160a9cbf19027d095e9d4d98f8aa358f23ddd8b598aa89ae982d8431b853aaeb7ef0d859cc9d62c7e864e4f771efb18144d34e1df75abc740e2f84820a387f1042f21e3985d25cf354388f0b6632d949cb9caac901631b9318d1e92e7f5caa3842bb485ad398d724f584b910b4b985c743128953147c49ed9329acf4cecbc7ce2673590d9263be40a25f640c19d3df2d27d04cf07aa2b37eeb8a6cc08ca470b6385b85ba5be7a19702608ea502acddcd01486ffbfdfcd5de33045c3656954c9ba1be85f4f2060fc9faf57042bebbb7633e167f2eb34e47e293714a51a3341ad46252a6f6cd9ef476d3de991030cee72ddffcbc953b68367e287373fcdd7cbf2ac1b5a22d8847abe6ff29a7577d09f8bb8c0becb6fbb2220726fdf21c3deafb67ff65fe7ce1f4e3867c8a6a818eadc00965592df155e94bac654d4c3acc5cc779abc3dfac21c553dab8f72515a061bfde0dc546817b04189831efcb38affc2f17725eb6c234247ef9672a1e89c83791321e0852e196ae8094afa8fa1f5152949fa0f8bf1f9f465ca3a994d33f7b8c825872c8dd086d3b38f8d1f7874ed0166668a903049ff5ae76fd66343d5d093fbeea8e8036d7688ea6cac5bef200826943caed7f0811df30412c11fbca212782af7d19c8e913e45b6b7b46888e1997ba42e8592dc03d6e03f03078b42aedffd213bfcb1f592e4dc31725c33e68b7bf48057fea93548e7bc4f65debc9936efbbdd883e40e025bf7441c6e357b4669b008202f61ded44344c7d0c8b5e9c9068beb6537a4c2b2c3a7b49ecaed3414fc8d9a9609b38f623b0d14f1533e27264ffacff7aeea69e0339abde8a9b82e4564bcb9d90a9251a35217dce79afea1f3f4a311340915afa33a7d4a5bcf6d2feb0c2437cfe7d4a5f0d938dc078240d38a3d9b7fed5124ccac30d29f4b09ee7c0ce7ca317a3e1cc91623755f112d9fb510669083a3f20341fa0ea2ba4857485f7ebc7069755aa734ca69c14360906d9164d84c5fa62029db6416cf029f0e7862ad9d025cfb6d1f3f11bdda828310ce5ac863dadcb615b3b931a364b0d34d101d9134bababbbb8273b3e7f2b9d411f2702aa5b6208df89b9317e2d9541c42e2ee339f4988a49fd10310c3b3562775608f19145b66cb5c34046054878edecde7831cf2d8ba59f37467a525620f6c728434484dbbb32cca6cca8fafcda45078c2d3f2b3f27bba120fecf4dc575610d4229a0acc7f9498cca52a28105ceb7817f358f7db4582d9aaccddd98f5638ec5b1e45cbc7a86ba177178e9ac0d22d536df35e5d983e29fd24e654a1e196ccb60ea7c46efc720b94b39d0f86a0fe526a68b8cfb085d8c81f5f8dca0aa9efadc06858e3460e8e18cfd92f6dd29037017899a9b7cbe2a88f623383910d92d5c36579180ebdc884f95ca153a81e0e27eebfdb6315bf4bd2e9fe78202ef21cd02d1de1283fa8b8f07b76dd4012f09cf85d141978e4c8b0ca5c1ed57f5097f1e580b71a9ebd63bc907d847a4f233f60ec5aebfb7d059840d6d6ce2ecda2975ae2459ad4765098b69d0040c23db036a54ec11ff7cd04a06d50dfa6fe90dba93b3a37e47d1dc3feaa34047122dc329d769ecd06878ae8c1e912f0b9773e1fd2138ae19c70d3dcae23265eb67005e042d415aac143326cdb63c3e510632e5ad72a23fc46b8806810b02c1ae90c6054cd09b4521e61b7a606ce456d8ecea77d1064835b88ae6eeba25c81c943a21b365d98dcf830b070d590f74d5c20098ad43b984220bba0196bdfb4bc9beeaa1088ba4d307ce6675b8f1f3b96d9b940b82cab9f7f592673bcd4b6b4291ad1269c710d9b8b0abc45ec7ac7a85a2560a8f3494432a8bcec00a73fd92046ec9f35b22df7c065b2843bd1a0c3284c47b7c1d47437a70136e0f2040bfcb761f6f148eca114cc925b37fac8ec002a44d804f0c470fa8498ade2733158ab1b913c037c87cfb4b92292f790281b4609bdadee8b8c8fc23ebc390870bc157e6cf8e17303148b2a60591679d76f096378cba85a15f07bf357a085b825fae9737804adf64e537426242861c1eafc08e3eac8380ea3898d9d0a553f53374270a4be45a7fdc088d3f8923ff4f1779cdd4c2ee98926b855985b13d1fbcbfa42eacbfefcbdefcc464e88f56aefafd74314526e408b3b23a434c741706dbd60926e0db4f99b7d8b4b8b5e2e2e2757c9bef8567be60500096dd4ddd53b0be674f347f5d224f569a8cfeccaf9e80dc5125931b737873682cfc43a62704b91964ed8096c527255283c3fd0a6b8f6bcb963380a91e2b085e8dacb81e6577e54288f8be899b6b1f0c2a21672ff176dd1574d6bdc98ecc1848b122994e7a6edfc8d29d62d160c796fd3e5fe91772476be0d676724f5a27007862e0764ef792c8e8598a79ff4157d57e80756e57e29a5cd64ddc68ebd43255e6f8c3cdf60f548f9f98c719bd7d8cace6fb37df13903322e538eb19a8ce3e30a37e7341e7e8c511a27ef302814aff8ff40aa7f1e8d96f10cb4991815fa9ab3bcf7cfda0c03adb5e878ecd99f3f40d31812b34e8034a5bdb6dddee350734a9f6ca88648f63aea30722ba410a8cac1f7a58ba319b1c3b04887e23a85c2ac01397ccab62f1102c705ee10bb878d86b66198d5550233ff8f2ed7f3e22d48bd800cbb600a97fd1bc4adc162050330f7b1942b6f0b499d8e423d03e8faba442407dd8ee0872cdcbfc15e2733dbdbcfcf033160c6c9f6384915ddbc2284d5aa34f025ec1658b221e9efb94240b3ab170e633ad0eae39ee9ea6cc1898fc0ddc662319c322ef2d0cd714b8131420ea6c8cbb1c94a49cc877d88913a9a084567aec4fdc0138b601a8a7db0d8190964b867da451ad845da51ff99fa41493aa927000cd5132b0ab93bad88a3e68cb42430c0e3d5ec93bd91f43b260f983936f65cd1a9b4fb1a87ec8ba3b1ca85166cb9e1a4ed2a5d15690d94e798e1ed24f433dcae76d72e5537f6563046e38ce709ee8b2f600e89583feb492df6f42aa17bc3cebb99cf97832c72602813a5067296e434506ae063fd5fb0b731de2e367a8d130615c9ae86f884fc60e89ec8c8191740f861cbe56dcdf5c21256106951f651ecf6f1f34b57ff1171b763c1ad4ce936068752926c5a4845f048c35a9ed64adce76fb7a34ecb35d5a12c05987cb24718576a6f9b78268f6090c4e1a85c954b504bef34f75227f67b8b06801201887692945936b93851fae203fd54d1e11f7c24334c5c50e5f79cbc3d0dfe7a8be447031e4d00526ee6903409191faaf0e4cabe006547bb64060fb846a21a120d926fe4744941e8034d318e46087b91129173cd765d36917878797c0d15837fbda0fe2206d8ec71b265ddbe4bce9bbbe9387475ec2f2ef1302f060c48db264394fa80ef270c2c09da2d995d8a00a4a500051ecfd06d6ee59f16cf4c4308562021ba1091b63506e4d2496cb0f8274e49b96b4d120e815bd508efe975fc988638e3717a514a238e8b95ec5d6ccf0abeaaac310015763c49e49f7b1886b81f46e1534fbc28ca796b233e820b4fc0e6724bd8614055de6ec312dcd1760164ba2690ff3b61785755c603f7e8b15ccc2d7a5585124895786f69755437f6aa29c3eac0666c1699376c0b467a1e1ebf175c07b3ba2a2cd3f78910b9bb6a564d84c1e2782c73a5422c980b68d1e6dc016f0ef1156bcb41782453e4ca77b2ad3bc2bcc1596fd3ed4b0d6f16243c14186b4ca764df572edf2c3115afb12f730666ca0071549d07a2ca3ad2c20a1fbcccfdd1a6641edb2d294d819b292a5e40404a11af20b65ef638eefe150b9bf5bcc73317a6d60e410417724113a629a94f231d15aff1caf940f023b08456a3b4e3f780d08d93bdc58144dd3a3afc3df3f96adaa68d6a4a0005c1ccdf1163fceed06346eb3e622bf2d62388561442d825d597af6ae31726c156a8121ac9dd171d390e74603481852042909bf596f7187b76cf6666da36c899ba466965e802722751f6997754bc2f372a032a09985ad2428bbaaf6d81ee99c9bef3019c6582974926721629d4321dd289fa89383fca693a5d4bdc60555225f11566392ee259c6546bef9ac1e26b8241ad9846efcda391e160b99160b5157407f2e396e97bd163c9baf30a45c887cd6a4e1735a675374dcfd364c1ad5eb078d511a9bf493f7d54089d36915d74a6bbeda99c742e9f034b5e5340b4f5e791b6c987368b5ca6c019733258df6f9f3159d2a298a5c1f76e51f152558c1e5da90deaa4de403f20ee8f1ca479ad61394fc810817d97f9cf52eff06c2e037e3cf147f783ca5a20399350d48e50ed349958706f4bebe6b9db4175efa1016997b88b4b7f7628c6a42c62377d4ebe88c84f9401474afd9b490b760096ecd5d7fe9038a3eaebe08913395cad829669cfe05120df11339d3ffa978aed2e7ef211f05e2d26e420b6ca07f01322c7052a441b5aa24f1223c9a8def535b541e61b3f160ad3494afcd2f092de90a929eb9bab47a078009c9a53da0a2bd6527e73d000cc5431020f15bdd85ad5f5d2129ced3eb02d40804faa7fe885720d8dda80369d5edb5b5d45d553aaab4b34857914e13829bf64654c9261966fd63dbb691494363e6017c3f98d1b15e5edeece10d8040b4c6778c09a43c6e7e1fa7aaf3628aceed347072e5ff219fbbdb6eb9a59432a514520879087c087eea9ce0a6a445c1f6adb646981096deed8f665b8584a6f16f42d5c27611b2c216bab86d04f903a6f17fa24a61a908314125b1e812854419e1524b1eeca0422f5819fe42dc702e41d29420694f6cc892c6b54ad2685325699226699246a9a449daf4991e52b22e30d8d662adb6baaaab6d1549b5aeeacae3f16c9e0d06f33cdf30b7f1ab43678b1677f7f73c1b0cb66d2fe29a2f01a102583a37ae7a3e9dd753708dff9848645c86f4b819bddcb8eaf974de83de4396fd96224c11c66d2d13c6a50dd63a302947f877115edf3dabd94aa705defbafc0fb929c9070c9f361618844d28dccdec85a4bc39ab061c3fca3542ad7612b58d36030180834ea713344448406079124e9d30e188c460d56b163e4c8dd1d6bbfdad5adae358abcdbad180a75b1eb6a5723778cddeeeddddeddd55ae337e21a04704d02c09273e7849db9e1c80bda3a49b86646847b708c3f68731eaef3628c317a3778191ff24e172758c162dc7edfaaac51322b4c74efdf5418879947f7856cc5ed77cf732d2e75ad2e4d66e0df4bbe3086cbc46d3c149740385c86351249b09d4885091eb3f6cecfc8097b03267e2d73900ad3f803a15e71e71a7f990c060624ea71e3a00f0789d0502409d79c741c1cc956359e2063c7c8919bdb4837ec155dd1155d5b6f5bdc6273fb8e91232a2837d880ea27351d39778cd0aeebbaaeebba91c7e3f178b66ddb647c61258dab854bdbfb47572475ef1f5f481cece872c51797e8f58f57b024e152bf0cf3d35cb3b9a060d9c4262cae7b32f8ddbe245ce31f4534ae112e11e13ddce0bad7180cd40ea9ee1fe216a554a107a771b1ca42e5613c798d0ab1f5459683f20b232b028169fca7a822ba8ca476767676768cec189131992756d7bf8b1c63c766ee1be6888a27af79cd6bb4298d3436b7cf9b799363e40608f8602f1836e98d83a20c6d05d7f8b37f77715d8beb322e39b3d74d298d1ea5f1f361c2865e9bdfb2ce433d2c8049fe8ab02b768aeb2fb6c277380be622ca261e06cc654e664544b93e856bfc5532559b1ec60e5f1897d81f423737b55a4be9cd4d942b1959a462c7c8919b6541aaa591d28d6e3146598c41e246dbb62348dc464712f7bfa1530da54f5bfd12e0b569c252080a2023043861fb23c035fe096892049ac63f2626f46cdbb66dfd59c28a98b01bd3606ef464700ae4806b74b0b0bdd1205ce347e2916d6b7074c453b64ac739d8bde5e06f44b02d16f58a25c44a2592a12896bd8f8a0de5f57fc5183932f39c71048140111465deea6696f10517da8936ce628db19014f6891a0fae472aaec71d5c7fa70293dce5059760de7594f418a62937de755037a61b0f836ab2f12124ec0daedb8087507c018b715d72b1509c146b4770c913ad78ace2510947177089bebf6bd13b3c0b2ecd8f43c47c1881b81e6770ddb770ddade05db8ac068daf26f385f5da982fb432be6abfb0ba565416492d93c9643299cc23eaaed55c2a95ab93459290982c268bc9e88b40a2be5d8ba423227655aaa642f5e3944512334f8f3fd0c1ee641de8eab8fe11159b38a97a17772e1e995cef40d1e7274e0ff42010687aa0771b50bc71e32b358dff87f6c37ae383e223c2f5f7a468015ce3ae831376def0e6d33961411fde88e6ed3e9f8e54804471072deb9aace6aa2e14eabaeafdb82e8b3c445a27eae1b2b26871e102e3bafb8c2d01d11ea66c4597c4e80ed7fdc3d053d09c5630cdcca24e2eba2f9c604c19d7b84c76c5f0316ebb7a4b1458b82d8bb55a3b57aa4872ad56b550c85a97aa5659fc0212c51d8822155ce36f43f4825445528c4552e401d3f8fbcb5452ace213abf88395cb7cc7bd10f90b2e85eb1f12312b20f4285c7f1b9ec5f597ae488a3d341598c61f89d00d6c105f1012030b4078e0b0b0f2146b2e03c92c16f1e43b91343defef5dfc0ac699a0f7772bb8e4bdbf37a171b870a973a7fde876f7bc9bb255e34857f3983299ecce952c9298a5cb5ee9f23dd0099826922ec034fdcc85aac4f60c9a50b5e84700d3e8d802f37e25ca0f3d97305f38616044de4724eb47048e6630c10e07db656e13c618ae749ec700f7f1c3217ec4c1f3ce3870384cc1c1f3f1dbc46e33677ab673eff992f873df4cbf2989e7e337d3df8d0ea6d932a1feacc5c19f7b8f28b6e787c4f73cfdbcfe84e8bc203ee7118db866bec80b2b67cd01ba27830eb74e2bec0cf1bbc7803ff73fba796edbf462bf0621edcdccd03df743bae7be2453b64f12bffbb66f48f749fcbbfeda0bae9913fc4449b0f2c38f1f2b9d5e417e118b11c6cccc393723b0935fd8f62f5ac618ed17b20893524ae78c94ce58a3284e4ae383925239279d944e49279d91718a413f4797e3e278afdeff289fd2b05e19075d7a3f64cbfa23ca3869d41fffe3231cf4c3f81f3f5aa07f04618eebf30bdf47a5df0d78e76de639a2dfccfce49df7521d599df6ec4bb7377d79530e02731888d1859629877e620b2b35d394fe20b46ea279bcac38d8d14fc77d3892405ef711b5c79670a471fc8340f3f8b07c68cbba4262e66a24a46be63595758544fdbad63ce23b124dea4d6e5bddaa9452d64e344d94f2bb691e1df7e99eb0db13f673fd76338a10c491f02f1d9d73e33e54e4ad22b8a6ce561e0e085f5a1f99f191c6e9562f41eb86c25a1de9a6c56677773a2708052466abd5aa6e72dbea5665e5a4a7fb745252295b5cd33070358e5361239ae8ee09dbdd2f36ec58fdd04f9d0bf11c36b0f2b7207caba856d8a6545ee148ec0bf300c24a2965f7f1401f2ae26e75a249bd45d3cc20d038fd650b246efcb8ea2f34004dac5fd07b272f3fb8c2085b708107ea09d1017da148131f86289c564ed8b0b31076166ef4d30d0f3c73c2e9e674bae9d837ce830eeab43ac9205c43e794f5930506b0894dde924dfc1fef47e5368e9bdcdc56ab6debb62ae20b12b1e9745af9670389dce48992f4922378809972682780f083cbe4bd114d0a1203a05bb17d4d206f2b92dc89477151e1aaa8135127073f2cb6d5dddd5d02a6f130da861162300e8ee6e18fa3c7781fdedf112c4edb5fc138f1f4a526340ec7a5fa56d5ee9faead8a8d53a479f8cf4e32ff22dea73fedf1ccd37d8ee3681c1dccc37b1cf7f3f7e339734d7b4baea91f19e3c74353b85d889c71ce3a6b8c31566baddbb6515a2bf56a6dea0109bdc0355d802fd4c5ce90f7fe5c158d22c9fb66601a7fcf62b409a92159d56ab55a0d0912d0ac999bc66ddbe846bbd25ab7ba511a29cb91ec1163947d7a60437f5db7c1e23630b7992f63acb53d5c953b2cf921e435aeb919f5b8d9116385abc562514ae98e118ee3385624b1228d1cc755aed46bdc7024bf27d890778cd8e047dc66bee7312e51fdb07212259627386d8a5415ab2b602f07a5d36f918dcb5e047c87209114a35061d5eae08dcc11b13833839b629e394cc0e502b00da54c30e81fe2b83ce399bf654cb04d2bc1b4e536cd9af14516ad3355eb9c73ce39e79cb3d2a9044bb94b348dcf280cfafb84c2ce26521e45b3454534b138a8258c1dfdd01a2362138d11b949cbf5a781f58471e6a6985f718ca84d51c4b7e3e68d11b1a9ebbacf526b4c5f4f65c399e2b2d5ba6d33156933254f0e42e192d499a82e369c29192a6eb7613bd89952c2b2f763a6666a862849dc828242cd9443ecc1cb04c31022e86d94810fa8dbac3a6d0dd1ad6198a908fa60449115599755ad0dd56835b06e54b061b35256dcc609931a9592af48aaf1345054505166111316036b2ad11525b27c60c39992f9195fe39b9941e667fc4c7f43647ec6cc901a1ffa1a1f7adaece74b13c988362eac77e04c7f8dee97097d8d2f898d0f7d1200fc8cd7c144433403fa175e07538c6806d4d9108db62b581a2ff322206c979a9981c6c73c0664bec6338e1a49313ff318a8f1386afcccd7781c684c1c1f80c7c0cc0be0c3c1c6cf7c003e1ca60cb1f1338f03001e47674394d3e30a36e66bfcccf63a98a82bd208d1a1b0176d459a0304615de69dc6e733f38ee3dd0380884d315f030038be991a2aba7d3313a8bfbd0e37462aa22219dfa21bfccaf8220d9a074c970bf3531416b9309f13ad28aa60bef8648698bff14362fe068d2fe6852f89ccc739d113cd10b1292462538c884d34ba4fc83fb1a794dbd0bcc45a9c39e82e51110cae710114d7b7309b8856e825b8cf0d67ab8b619022184cd3c91b9b0a60cc142db2680e7adcf9c2ced4e748e31aff2e78c76bf1e435afc51d445664c52cd189e8839899a2551c74eaa22d185e60e387d479e0128dc6cac2c1808511f31d644b58a99adb8491b5a2d1bca4669309e54b644d9f59668a6be60ff38a0c08312ab028b10897933ba33839588b446898a9ae61a68a843cf3d08ce7be980f41b7f14d554ccb66b4ac4616685441e6eb2d66cc142d66be68b3fbccd46471892fbde16c4d29b11559363eb40c7470816052a4451a6f9cc8126388248e60d03fb23c92a612ce510c26aebfcf17d7b87baa65911669916524922218318c9d1d76967891365373ced93595a231900ed663f0325fccddd2255b9265ebd6db16b7d8deea768264b15eac178b158233078d98e233b789dff216d7fa28e30b1bca4e4996cb6da4152e6ddf754ad45056556ca122595226a7b82eafc89914b11536942c09939fef1e1472ff96b0de9a7ddff711c99688e5921549202859208b6e3af849bb9ab41acb8a8291d4bd7f1a003bb0d3e2d545f4642092011aa41467c9c0dac2b66ab74593ec275b9dcf7c06f35d0085b2e059afc2071cc00de34b1ee086f1d53188e8729b3006115bad2a31462b3706c125d6d7856507a713969382d6ba6ddbb67d88648049f1ca4bf67ac5dc30be5876854932ca8bf5928105856be2a64567b9fe339e39a145b9e2379e20595c23a3482b5255a0a638edc82bb8c6d5b1497f506cc8b4193edf3d0628066ca481c27e8e965198c65f52b92e81705d5eb9ee4956a758ed4a75aa53f3c5f9278339e7fc7c3e1f4ae9a4f3f3f97c4694d239e7ece1a4fe7c54bbd13c1ff77d2fc4396984b1c562b0d7bffe35e7dce6165f91f4953a6ccb84f29a5aaecf2ad79fce6df3bef9482a116167fdaad5da5048b6c00b03171b53602b08cbde6784f55fd5d5b6dabef0b7554c4d1516b799b05904977670295eff199bb348ea3e04044ba5ce28dcdc895ed8ed89839b152cf7d2003eb0fe7c398a2e5c6edb4c96db843175533eb5d84272d30da7943bc60d638b4b7de327aa41c77d463f380f88df6d9b1f3d2022bf51e55dc04d311505dbf160d914bf7faedc26fecbd5625d8f22d912c9c086b235a16cb096dbc46f7be2a02792810db727dbebfa6f5ad8fe30a656a9a852a55253958ae08d2c95c72a5315695cc776cb411f4f1c74c6e2e9e964aa3a6f015c5322029ddee7864bf1e30f31753363aa4a3855b2255b32bb4d617bf27d7860a76a968a3207a74a0a9646beb6205d30933298491acca4103369c42c0bd7bfb1c0a54d62c134fe52b8fef10bab85eb63cc18bcfcfb0726c9163321f55442515a45b43ad58598daa61853750256019b80d4af2879c0530906e36a3261c4759eaf364210aea726cc55515485a52fd9ba79d5dc6e5dffbe3245ac8a9815b1d754bda66aaaa6aad61d23071dec566db1cd0710a5b3810c0b103b302b56acc41839b2a7eb4fcf6284c42e0a892410308dff16d73fecb8e6b8c8c58e8989d93eb5562bf7484ecdea2aad9344d55250fe95db6a48786b8ee3aac771713aa83f346a95c2073a34a4c43123140242103233ac9db36eb14306084a2b5be48832bc1ff17bda281f3737a36ddb1a4581202f24923acfbbbf17b93d90cc2259d56a35e7768c7adcf8e01a121b4ab89b993bb2562a5b69531a69ec6ddbb656b54a35a9bb8d0eb791e2a43afb32bdcc39e7a451b66d71dba20cafb25d6bed6d1b218049120c491bdd91478475976b676727ba7622084a54241941a15ed2a6132e3d719b3058d2e4f6a11f782e993b4c9611ff18bf21dc9784fbeee3fe685c03055b7feb264dd6228df770e9c541ff3837340f5f010b1a87abbf936af73e2f22918424d2344e4ef390bdbc20c9f97c5efdf9ee4f0dc9e713424237d16914922f36d08a741922631ef5c8018670442dbad3f5e8d445b1d026940965512b5445a15c7f19455068c1429fd0551435a1729b761b896a169394db44978c0f36152342511445538d436920002736a42852acd5da900f360036a0a9bafa01846f7f32e5a05314d7f8e7bdbfd1c38b75d74db90dcb1bb24c004278661e4fcd43f3ec7864d7ff46b760352600950d23ab968a39d8b558cc16c164c5c513a594527631bbdd2dd7bbbb259df3935d8ff1c186a35b639ea73dd03be84b9283a9c240a02f097d2501fde73b8f6846f4cdf4c3b4e787783c0ff32561df9e7b1d4c3a7414f5c2151b6759708d47591436ac308a1a82dbc022699afc6bcc6d7a78b15dbb2145f96f35b7691a4579fd627ab0ed9a32a47bef4bd2d5ee874d53c21ed7e455589483ce84a6fa0b47280d8091c635f091c68d60c31fc51b273676fdab169817fb1702312708174ba5891bd22154081136e458ade2fa6701a3281445511445515477b2f1454a29fd7a924b112ee1b8fe466c9032923a402bc235fe9f13a4eccd49acc52d77cdbc702b553ce65dfcc51b07c1d2206ce855dc4626817a13ccfc2458c42e65e35227650ae34423e020ecd410d7047d4dd0b7e33c34f85e60e9875e60528ed320e0728ebf935a44a790d0a42291c697e8aecfbd39952291e44b348d37e1f3854e8450fd4287c29bb88d045fa2b71697a870a9fa1242446887a2bd096fb9b7ea87a2703b91edf5b75a9ed06f7b68ba66eb7113631e16e8c8c7a787a5dc9467e592dba8597fbe7ce504c4650f24b3fe39ce0c84d58a15e3220506e5b5a56585ae56d5bd7635eec9c27237fcee6bad5f3f97bc15144d226244af1a87da20d48496218108a126ec12fe7586374d7bd5ae48530433c7107694ebcf79b7f2e0fa3f5769d9f951fa021bb26c031cd000976ef00126f5e949f3f0f76853f801130c869a4707e1c67558f33084ebb18fad0ed6533fa127da4f6606b80083880cb65aad56abd5a8c7ca52e166a64c9bfb65737222a94a493b0f1555aef9175a96d69430c963c34858d029cf97e3a371b88f86e6e1fffcf2726898afd7e49253abf461060cfad3d0384780602b705919610818d7662c2b66f3dde3e68185a5b55a6ddbba3098f993827262f22122ab44b8f35c91b922658e48294084694d7a1b69dc00d37dc05988d0b972743dcb105ea24966334f3794b957ec8d1bb24cd6cfe7f3f9eae0e73381e8f92244081b322dbc61de22fd34f847e446caf20d43a0474185d828fecc32c4ebe9d787610a1b72145f50b9a22996fbeebbb9f9978076846bfc6d11d6238a5ef480f483b040c041e7bbcd7c60e10d13029e28fc206ed3d94c520cb20797e4fb1549001def36954b5bc771de8fcd0697526069304e7f29a856864b9e77cf15eb5d7bdd779fcfc7fbe1f916c944e172f6084bbb1f1a8d46a31df1bc1d0e8e1cece1e08d833e722010c4c16e193e88a1dc85a5091396955635143a1a7532274f9cf8cb10979c8e4236c0208dfafb236bbdf4a768042d9271ce398af3e5acdf10a7e98cb07ec31010d6e6c086f6ba7c8fef38fe7cc51084d840dfbdb0262463e380c1216c689c3e1de1022f5a57282143316d368aa25028140ab56d3b463d3a06338399ebe82736d4d0a76ec234fe12a3f333ccbbfba5773d3cb0a31b3f9e15e1d9ac8894348cb98a2d66d7218bb1d825bea2966d4606ef3ed7f87ff7c726f3b76ddbb61a5aafadc6c5a5261ac7f3fd963eccc370c586b1359f348ee7065c62e2243fbd22c953339aacc99d4892f1fe13758a246fd249999c359ba44bb6e42aca28cc87f2142a854aa15cb3fae578626722107ffe8caf03150eb5d08a40709a4e49711b260e63058b5a82e212f3c7631173f6d5da50282e81b9f10718d10cb771116f5785f58f556e186bddb6214245d87645527479a660ebfdcfe1a4c8c4458c1397300c5c8a33f8dcf0bdcb7db515bae185b0d8b88469fc7fa84e228a6bfc0a1bc6566c6d1f7a1f4ed38f058b6bf12d22601c04308f7e5983112e4d0528a0fbc25a3d5f6cc556addba8c7cd5cd950d2ac6256ad184abf9eb4165655a9ba9b9b1bbad55a6b7d52f7616dff4251b061e84a5291a8c4f5ef2118076c33df85e052ff4da4691ccf97a479f88d77439e7d5f6e92d4f79bfa85355f6e68641e709266c25f51dc2074872269014ce37fa35255954aa552a938ae0a19e260ff27369bcd763ce54fbc7054173f7913dae46a4339399184a4f6e068462c51a06c9f56713991e43f1a816008d6b39e71e9b3a104dbb7ebba6e3ebd61ab26f390e17ddfcfcb077d731e902888839e811d52a20474615b3509543525e9314cec31f48f4056a6e9ff421b2af7db047a04bd6d40e87b6c60d8ddb8efeeba0f924e61b1b5630efabb604abf0ecc2b895d389950e0f6e57432a14226985702533b9d4e261d1d2502a05513cc2b71c02c6482791d253cc6eb64820168827918dc98604c30cfbd6c900f0b9d05d3cc9eb0ef1a62d6a63b3d836189ddbe9909f408e6f7ac023341d0c2ed1cffe00e6f5a8f59382a41dfee5974d9f006c4041bf6cc51b3d96c369b51ea33cf65b67065d65167a08f500eeaddb6b1043b9271123b5713e7873bc21cd7a9cff67ecc2f6caddb3665a432da3ccd79d2d15698344b67d55552934fa78e0c82b147a3ffda5f47c4dddddd3d09e80bd8ca94c388c90f5ca629fd21c36230fcc0facf990830974b9fb95cea3a7dca9175ea0607a9128be408f5e00006232ceda0b0f23671d053ad1c2acb7c3a9d4ea73ef58952a7755268ec34b7711dfec5dfbdb8bbec642097fc9238ee03eb573b8f16d6efec9e5e3708d391449fa6c37d7d5a2455ee0b400dac90d98d1e5e2ccfaea36ed846c0208495c16934da9c3b68758c8e99274f99acc7b03559173f317a778a42987843d75b75606a24b5153bd7df690d6cd8ad4869b2586beb38a9487f09781e611fa0f72f82821b9c04fa680d0025712793ebfcc53b2b1e366458ea156b1efe138b834da4b0adfa9ed8119020ec1d9c808df81371555c9062080c3ad83c8a500029322292a06a8566383ed40aa5a4a452527630d26ad156abd5ad6e756bdb463d5a33a4b85caf1d2f586656645ec0b65497ab7dfb500f48e7e1b863c3762921c68a3cd142609c2456669f54deccfbf629926efa497ca2a2a208dd4a4214ed84b80385b5723da9f2ba5cd5e572b95c9c886fbb869cbc2e4e2754cb0a1396ceaa4aeac9e90482b20623c95a2e798de35dfffac562c1e5367d1b50b047e889f66f4fe9f6fdfddbf71ba91ff24e7df0648db06d65db28a5b6e3a55e05180a77fb3ed5ea606f2fbd1f5b1525c1bd0d6ea4af9123f2044b7d4ed70dc0a300bc8502c0c6a9410938416aa05d6c100c02c1a07f0d8d83a479f8105d584a382276da69d970c4c869e774629d4ea7d3e964b1405f1cc7c5da49b264151df9454a296badb5e6c076dfc1a049978508dafdcc5924e6863cabaf5a3b092781b5849429490e323b28d3e773e8b8b032791f6b50dc660726758d4b325c9a21272c7f58721d06256c18dbd5318fc13f0dfaa6312fd61cac5dc023c39b6133d948e30f33051b46d749a2b8a71c05b2dd30db33dff3f15c1679a28f8863acd185edbeb0b7442ef10a26512298c67fca941ef4e086edb272c376f911b1567bc2054ec80df4d6e73e569cc6fbebedaf5d4caccb89d30d252ad6ac58ff6e2bc27d72885061b91bf2dca813d7db65a579b812d207066740ad4820e42a0a39c42bd624ab5dd48adfd4502b4822a96b55d45c35b9721bae166bb1166b1e0fc735421c1c4284be6c00c1ccb4b1d056df4412dfb0870a0b739d524aa9bb870a6b61c842686665b15a739cac5c00b3b826a6c541eeebd4ed20ae7f6c988f9c9b90671fe010b007901841e33414be02140ac54385a5fc04834180328486122b024bc6daa4d06655615d094d11aa227473c38ab1582cd6b6c154890921726242c310a6e9f08cbd906ebd05724c08970470fd89c0000a283d19a6582a73847dfba9967e433ad50d79f6b2b6880d2152b013f0dcfe402e794c888cc562b198903977787c60e6a992826a321b89b551eff40cc1728c49705f9f37fa7f798aafe2adc899354a7b38cde69b1662778cb17687c57a37ac4dba35c6186387c5c65e71e9bbee8574b0729b9614a61ff6eae670e5d50e3329a3bf6f6d6795811d503db0d36bf0067430dbbd6ff5e7ffe5571539ab55575fb93c7592a97f90684929e58e9119dcc43dc3803e1eee330203f27ca4b0ec604ebfbe70f46166f678a011e89b3ba31d5be5975365fde837bf1d233b3827288b52564bd6a54aac61cda55d946bb53614fad128ca6ab5f61f0447a366f58b4b7c7d764faf1fc6a5fe1fa6b84634a10b76b3a351a86d121c3721063d58c294433c220c93e7bf54ca32d7d8c993274f8ff60cfdbef4abe7a39f1107dddfeebcad4bd8203b18b1b65a6b592c101073ceba4dea24c65837fff13f291d758a76c157b0204290e80ca100eff0175917589066120d1a39187683cfc042b854e3bae806e192288bdb42827cda415110075d6efd520bcc11fc4990ab7ad2c38b95715e95759356791031ec7c820dc1eba22dd81094f2fb85041171b121087acb240c0683c182ccb9c3888e8fd8100e7f99c383cc9e93ba8e3adbe9597be9d8a45cf274308d3febe8f1ea973c5dff26820d2e729a5ffdc9d51722ac97cb59a8e8b2e58637314358ce4205961bde64a982c9cd424595cb598ef0e2e2f6eb543f1e1ffad55bc4729dbda4384bac4a9f9acb7c65893de186bdf369653942ec86ed456e348c56a415aef7f0aa3199ae80df5aad0d85fe417074634508eb1e1020ec20783ae108c5d3cb4ece628425d8bc765eafd7ebf5dab6978582e338e68e7c24e9288119638c2e9c4c32af2383fb9890679f1f8c2304300ed83cdc13b14946c4261939ce711cc7fd370e17f27e8608f41f519bac884d9c2889cfc788941c9111c910292972fa3cd853dc225cffb000d73f2236f5dd3e326e9a216a1367454a723899bcef603ec7258ce805bb9e08072433433eefbdf7f97038d271a2d6e260f7f2e19182c5e16a975feed362a5b07cbd9f7201192118a3c56f00e8fd6788580121cef5070bc0a53700f3601b4a039530e8df34d063b8eeee340ee42ddce71f49344ce38f802b15641a0eee73d41d5686877624e420d708f1b8c5c2e3f1b0876745aac7e3f1783ea311087ebe1a699cd890675abc97306157b9eede00506fb9a410278512383f9847949b273a52ba05e5ca78fb31f67432b90c5ba4eb72201084020e1ab1e1c80d48224d7f441ee794d45ab972ed20b88542455253a9b5d6eac9c0846b9c874a7bd23a6e93059372228d8eeb6134185c0069d9c0862db3f12f12699630e908e7c3c3033bcaf3f5ab50a47893277de7dcaa7c00036193152690538324f4175360d05fcdc3fb0a4c03c5f5530db8d0b296a3aab85a2d6ba18e5454ff509d340a2593c96432d9a8879021a998d5687453c4061f3db8cb4b0b6d853a236c7f884bdea871280fd73fe4031b8eee0cb9949147233a1a8d46a3d1b66db5be55881c63c766668e0fc3e50771649a077fbfa00a1760a61c1820c41096609acf1f120117f1174435780cccd26336123bc03cfcdd3fac2132820d6faed74abf9b1b29c1ea25c618afb07d638c3146902cd65a6bad52f610620e7d90213970dcf80c001036e4fd33925e003f2f2b43d7fd8642a15088527a84945246dbfaadeb6eb08a31c65879d63ff817e19201a4c93ecc69f3d8a8a24b72e474bad1830ad606f0869f3f810e97fb7e90c83ad8fd9d534f06f91fbbddf2f35d07deeed37d1495a0c7f8bce78a9d119f8b9df48000e10bfaf682f0057d33de8f803ee8bdaf0718a0a75f1f06e663be1a693ceed99bc17ecc10fb319ff7cd44a0043dc609e483bee71aef0b6d002fa7c3fd70a28f8c7ad9ebb82f6c6c62fd7360439ef12039e06bf57ca1e8f6733f2bc27156c435d25899108ee71a219e837630a71466446415a6d66a63ce39a70e9348245598da9da304db452f3a78716fcf8b2ad61491b8754422e97dbc17aee99085ebefa8482272d2c18103a777a8748db805356534020000000033150000200c0a860322e17848260a728d0f14800c70884082583e1a48b32088611ca4903106210300060404400433ac14053a62ebe1d49c3cda53fe7eae98e3e643a94226bf60417b85a91e3e638bffe5089ea7e763537b32c3cd1b038c3ed906023efb9e63f336e064a8a5567cffe1dbc0c094a9331d30f3b69c1fa8766c68dcdec5dbf79c271ee0c74b7ffa91677432bea0e7760a7cc1827b9935fc8bf91b5072e98c86924426c89c405bcd9ec76dbe2abf8b798d697cbdc896c50bd10f35b60d3eeee2e3a9e6833d8c3fdc9099ab586de87e245e3dd53f5a77d96d350a46ee4a20ec638faca8d75b58722f4c9d5bf121a79728d4dbff51812d25abf793941e0c2a3e16ace0527081eb1399986398e835311a9d843c292e10d193638c719ef7cfd7f6db872fb15176b6af55a7c41259774b743e7789008dcd33fdb5aeee4c0821d8133f78bf84d086cce763fd2975d25249e98900256f18c87ec3ec65ba3796c66396f3d40cb3e4c9235fbd9c386e20e511a6494adf8484fec0ac303cc9fd5ce9de955f3b8c3d890d84fc9f49851918390692050b930aa0579e9ad95d4f67abac99a2156e8e93dccbeff8726d19dbe1f738d5e6ed7c81f89e00e560d99582d3511fd4eae2c29a878ccd80c50717ab9af4827868365075a7a67f4f981646cae036e7d550443e5b091d11a8dbb68935740a15ed5daab9b4b9c564bedf47b8c41e2b26eb9f4fab1ebcac8d42f858421a2789cb6abeafa8603cd6dc3ae1df90ee6c4ac2ee834dd2688f12d65da7c2fb57c0b5720d571f17e5b89b64333557a8403c519ee0153a81296d23cb115ec9cc8faeced45f44fabdbb023c37503c1bda0f244dd058a0871e98bbd4e82b4b63b49ad2739856ea36ca901473eb0b125b68361cadce9e8fb4c36654b25830f9d53498c9060d377291e29da82124d2f2f2b081a8f4863e004b0616448ec2caf20752c8ec48e23aab98bd5aa73d6e853ece07c8aa7c44562ff00118bb279768075bf267ac182846526963eace6824eb4f159bc13b95b78e24f09182615f1f6c8da9cedecf86c906d856644d1778143198c830b1d57beb955188d86a275864d4f5fa80a4c72e30164540087cc42ff9727c32262ea5fc500adfbdc04c1a29e92a9f226a78adad762c357c9c06f4635c001d00ce22e486d8041ce8b8063ddf6937531de8bfaac2e6631107123727a9dd72003ae25618b18b7d7895e442553a98a6bd0b626aaf43ebaf5713efdde821caccb1fc37d15039cdd5081133f990cdbd4572ba8199fae0fd85cb60836e247223e06cd98b1a2fa39f743322774f5ba60978abce004c9f467bb2bcd1b1d1f16bc0c0b1bfe4380594a60e8c292610bca3f87e4b333474b25b02f8c15541743895ff0d42318117dd915595f6cdc4236582b62383e04de142221d853474510a33e68c682aba033e40b58ebc76bbc6290c30773b02cf76fcd1178b3a2ee7f8e8f0fc7390ab6e209eaf8cda14e00a8d0df50fb9901c367b8d55d2671cb402de4f72c2e7e2287ffdb07044884a22902a1b17269804e76d75db1de3187ae9943411682352fa2fa673fb0b818702808f2048681c5785b1afda62f312e6b7b34085bd8e3327cd5a3516ea969af67a2efb5fa660a86b841d56073fecdc848b0ab4820cf1ba6a0518546fddc3aa69f5022edec05965ae0c3dc47e8a6e85fc73ac1b4e09da48ed3d53a56bc3688a032d9ee5c8a52c55e44998a3c187ff1d5957efcbe0dd644cfb9adfe76930432b7015d19ac16f64b416e9a0b4d35431c27fa157c4d6546b94469717208a9ef5e444089ea933e9cc3c016aa0d2d87cbb90bd340d5d291e694d283f019bfc4f428959d736f5b64ec3e26bd24ca3c5f47394d134b17a824e181534f7c4c7016c5975e862d77f7c17203f98155dc4bc3dde2706189ca8a0f30cdb6ff0b7ac52c187aacf776aca195613a013c29d387817a57895e7df921f24384c56e9bc980f61534848c2bf683912224128644ca8599eb24a5afe099b80a72846470d30e9667628615161a4e182ca3ecc012a5f463a792f424412cb371d5289c610963613d2c89bf147ab590b596ad168d09f959ef77dcd554a927e8557c038723f857f9a6fdf08cc80a557b738a86981da9b15998db868ef528d12ae19edf7e79192f43b0030a00dd35ae6422ac970c657fc6f05d16c62d285b56ae153ba5ebf61882126f6416070e6d6caafc044f1410cafcbec35560083280eb41ae14101b312a1f906d0803adeca8d56e3b55c8b7d59082f6f0967ca9c3013ee94d68236909f3592ba01c801f3066d9e8f53db3ee9917d641c7afabdcef143a35918ff1e0b3ee042966632845372cb10a3d3d7165f0781b38fc300e1a6855ff14a54d9e0b85da30c8e917554f58acb08ce62b3b4d0f0cc431fe514351b0dcfa6ee4a38048fa8e95ccc4ac6a6bf7187a708329cbbfb45a20400f766dc5fbe3f8bd6c01c11363d1d5403eb63a2e564ca500c7c5ab9e57b63b842a4ca541f88c27623994bd1223e82a53e4ffd467bf353255ec48c98d1304d65a0bc0bdafa55e8ddf9fa060cf497c2745543ad5855612761105814e8c8dfe28965282f1121502ac17f9e23fd242b5509870abb0cfc3cea02d28700aae84c53c47ee4bf9f48611b8c30af99f36881d16a91b2626e9fa5b2fe34126128a51b518ff14868931744b9cefdf7d89295be661474a494f2305e25a17568dc11611278160b9ea49ac7aa0c4f9d1ae59aebd032ee838a6fe11299727b97cb6f0f3891bbd69cb48535d2f68b8e28d7a7e27b8cf0b8d8e20ffa142478c06d8a0bc22ac0d7ba8b3afc491980c809b0eceec3fd899fc402108979470025ebe8a8a222f98194fb3e9316e16ef9effd147df3da0eba96289ae5ca9e362b9fedc74695958a965df4dad6b72fff8d05d4a4be04e5dcb923077c745526bae38d9d6774e4e7e63afd4922fb947b0572807c84f889a32f90fb771a682a9bdf5155a31e0986d469b0e69181d19624d0ae384985681c49ffcb2e141ea8440f30b0d206d9815d7ce97d04067f1001a7f9aa4cea198e2bc91f6310bbd35cb4658d06a1e560182dce36c20e3ce539d4aae733fbc4a2edb6a1cbf13e18d3c52332047fd2f87bb177025aaecd21a3d78b3f859ad953338f7d710c9944a348921805137c51cee1ebf3b7abd2bd2eff48bc6c2f9f3bdd0b32de2ab613313936e325cbe3749ffa7a6377a01532bf8303a282701f102eb21647f7cd7fe6703cf7f5a0f1fbb0a0ecce432b02d948eb1bb99f850eca8db8a04a2a42df4ae6d8640c26f51a6926fbbd67a5c6f408c0d2229665949e909f22b189f71e1b69207e6e162b7c085dc9b1f84c419878845a611d6c7e1500a61d132064056bb5329615241cd71aa62ee67df9700cf1ef5725fad2508f59f41c94cb7ab6362247b7d9b9914c94602e602c81e1e69b2746dfbcfa05eecd43af1277f83745bf2a2bcc8105fbea6e82656bc44a25427fafd91311c34049fbd38599b17536390b654c662572d6180f070a5e1a5eefbaee7b186f2a51d0f94eb86423f7049c09867a6ba0e8e831c963a0895b087d0a72382505fd857e22f100695c6b2db6d500b563e0d93810de15bc602be8ef3e3e953f6f5071a3cca42145469abf001a1d644e6470733ab6f9153268eb85fcedc950150ede8e01fb480db574c85a9a2f49e5df326c5bedc8ad6e28ef29d8fcf5f0188892809f680888a9dc93c51f3f66d98713b45e19ce33b05c4f11d7bb1fb015bdaf0629ffc8633b1a0fa3aa3800fa003a7f72e4a60588ec8743207b6f21cf9f96b0fe20cb33d3e5361989f0cfa05ee8ac497760cb21e4e253876ea6c690fc812946908b79e8a354dd2665f3415cfa23420fee8b62d1743447aab966c99df93050992cda4ba6125f713a111191a8220b177f575b71426f3c25aea18ea52b6e24be13f90de47ccec53fc53d328697ffa8601d6f804022c3cb68e97f047cc83abf819d3218d36ec4d9951ade708a04561c7eba07edc995ed404c7c1b7f174246a2509c5aaf325d3ab9e467377de354d7d1802a79804da159f2fbe2af88adc376df0046f15a7c6bd109475608da1dabd3043aaa2d9fd190f62e131fabe00eb1487c39431aff841da124546423ce668fe09ee5500fd5abaacf527d06e5dcc128e77c0f530ccaed2e9c9d4b0461c8cf5af3bbefff458dc6aa2eefefc4f69e522bff8463d0343815021966c9f5aee60e025d943f37baeca3e0421500081742a80c14d9ee95d07f88d88e62e88640803219da46a860f1d8aa905b12356aa842f2d8e4bd536e625d3488720018d8663186c8cad165e9f3e44f6b6ca5da5329850b9332056d0ecc5c1cc7eb691c14d2aa9344cae648988be775ed2a5a3767493f9ceebfb7e54268d5c133addbd8c83e93504f758d452df4d7387168061150bf8d1c2e562078c4ceb31eb453672d4e18c45a5c7d50b3d76f27351715f300aa0507b2293d88489abbce4edea2a30b1295927f983f4e9fce7b547a49b1f2dfa38a0bb207e1a3a12d89eac800d15deb523fcc44cedc16afbc04e160e26662b2da8f05d238d6b81fb8abbc5c40e5c7ab175242d54e20fa0f839d54b32ec3ba87ef63e407746998e6536fa169dfd074af8a30a42996c6bc6f155698dfcc3ae14b76c556f0c2e790ac3ed65101d3f746a62e45d12556afc0841c038a7f9226ac88bff4c9e13eaa2ced3719a7a6cdf72771d3d1420cf79af1945e6299988d9630305f06c1643bc4a42d090e97a460602988dd09d55a0f3338ddb4f6898290dc1bb69701dd35b1457e1a0170b56380b06e82a7e86aa2ad2dae523308089e49c7b499da12a5826b44556984b4ce04b44412848a638881b2275c58d00ccce7200eeb5771b9895f0ed4d841fda00b28ca8cfc8f9a3249ecdfc74398fcabc720b8d458b3557ed9fc641f213abf5a7856f49394d2cb8b1a3196f55fba01a9691fe8d5c96701cb0d89f20245c76fc4ca49b6467f2a233142aad5ea75b0b4599ee4a86bf48f546db9f59396f73a836c176ea6544b4a640d6c5cb5135c29dc7ca942ef01f1e9c93e1520c961a1333f1625e04057ffdd71386530417f1a5d7a7b6c91ca2c870f23eb8cce3d44f66492c44a8f353f836afba51fc3d64c372c2e8b473a721254bcf0bfceff3867966954f999a814c4a5d0b0b154b6a3aa5f83770e14de14c8e9c390d8410ff361d5f0838dfe306959254f62e48adc6112ae26527bb0062c12ba5efc99a6fa8fd341bca9730ca51a730e8086ddc4bfda344f91bda9685e9867f16964af46d2da38c4fa40aa814aa99d13749bf4ee6d155d113be71763d80333ccbe9ad85090b228552db7b5bc3851cca82e80705b740df45251a2b3321d7c5ddb0fc8e064c802ad6907067bfb6d3ea8bef3726c87bdbef9f5cca7f30d644a1f5919df5ca9f58d02dc53007b2c001b05008efd46bff4948e11197283f84526e333ea5949f592a79c9a487ee2deaf5aa02d976a25db0710717faf8b196f6df9939ea8f409defac02ec7e97fad3500286567a1fb4178d785b85619f23ef685ce551434af46516459e00fb1c5a1b88c1ed57300fec042a57f70f91aed1093ecc1f4af0d1e34f494adc503a0a40739769cc95808f2f1e88520ae5b3f5940995ba243a12576a917d1beee263657207e7ad94cd2b06b3068c011c60fb1ff9dfd2c07386d0aa3c7f461d382f9ebb705aa3db04f03b651ff004c518e63f7c65baeb517b0845d83523f57feb52cd31a0dc803ebcc521b34e3c58081033b77650efa62e9187d2291b314604b21df488e64f4990c8990a6f36a9367bc838d6719d2ac2d1a2d7d667b56511b37271a94e6ca3caac8e3a1d013a16037807ebcdfe18bfb9e0f6521cb87e4fe087283a3875e9e60b550a0ddaf9eb2b672bc3d3a708b915eb573e4eb36cd2b7774b21f8a3504794586673342f0e8b13d13e46855f2aae9493fb020bdb826bdef0cb42a5aba683fbe60c48146a1a77da9187a73b833550c8bb91060d970ac3d2ec5757b6353eac66c81f4a8e488fe6eb69e88086ca3633b5b3655a07c8dd2ce7cbbb26589b4b8f21d43d723f80f0c7cd8535217eae639934e30caa982bfab4a6c3b38fdf4e163110414168ae9a527a6605160885dc7199f8cc3d9afdf7a369f26742ea7df8486badc6bd765a2fccd717800d46c36962271b06b00dbcfe576984c58b5e7deebc5b0d24608a87799298632ef373118d225bed47cd647e298643587c0a430b01ca837c52e0788df4030c6b52b278bf8b5847f8498a9496aac1b54815cfb50c33e5f0581ddda77c7d95c38ef4d9ff0268aecdd02d7b164bdd7267b66e91f0cb5533ba3cd65840ae0303838d390668185f0f8b6235ce490134eaa7e76ee062c82999e666f30ad251cde26fa4aa5746ea2acbbc55ea1dd785d357099c6b0ee1686d9d4942aa96081d29bab3545acbbd2430500971ed86b1f0b2482530ed2ebf14f7bd4ad3ff94eca7831fb70062ce6731ed80454ba3bdf7475c4b919f13c491ccdf5669416d170e0c5793df76518e18c3772e91b5ef1c6095fd9d4bfe0d973b3666042df85b6e02f1973eceead3aa3502498508f7c082d764a1926122900a2c20f4366592563d1b55f972488987214d63853a6036339fc387248f9da2ef7214e7991c23a16b04431468d795e3c7b2da99257f678d231d8b89cc96a26a68c4b8d82a451fd8ad2c79546402bfa365c58f8bc31137fafdd03be7cef9c594a4b7f1ab17fbe233a665c1f071e5a3073c1cfea76b9b1252409bfb16ace86d006880d08f0a035f26e689f27a77e7430d41b77785b56d31c307d2c0b4b1a33d8ad0dcb042a2330947513140aae52d98ca629b717ece28ebc04fcd85c549ec66f63ed8dd952f1aeffc971f5469330250336e774f057afb15b224c07716bc2b2b33d1c490a67ac82f84147c54181cccd0fa76f5d3cac128c8dd781158ffb581ad87c8e0abda6771283d6995cc2e27a78bc28f9dcb6ab478a95f01047a55321a3ba8b0eda1db2d9e8eeef611a0e0501a83cd3b17567dd1888a1f0aa7b72c48fcdde05c13e5c909eed65b6fdaf0ffe305445d988476f4d518566aa03dde53ea7c45cd1d63cc700457b20e7999b1b04eec640c4e03c0250477b4c24b34513fbd7a58eae9ca9daa3edc905d52069886e01351a9d344404b52337532253dc27b3685bd71cc26f8626e9b1b1f8f0d51fcc83cabc8592099d3241cb7af063e03d71f688938becf2efc9160494a2ac78d5074e928382d6412719339a6e7b07234699d5147c1b8a985495bed6f49926844b2300a0c9f7aab8445de6796253f54205e446f2cd0113a8c3ebb7d3e57361f03cd71a21c2319efa7da6c0f3c417ae916fbacef331ca8196f8d104e594b55be7f9a9a11cea92feb65579f2faeb5d2d2895044ca2979969e3b65d790a0d0765aeeaf254e1370465677b6a2366602d1328664f23693de008ff39441030f1150733fadfeb6c38cff28519b02a145a4c6364d05a756b1e78670fbddedc947e13b6ae175fefd15a10564252275495f6b34c996bcfbb743644cbf89a69b252966f9f4047f5f21011a90f85bab824dd2974a5125f8bc6ad6b4a80090105e6f8342649fcd4da0d86ecd4984e72783f6d1e657e3da8b9cb43194c59fc429709e4e5023e8bb5c50e864d27a11a6d3742b5acadc4f23ae21456b9020ee694b7de5663a7a86670f34d5217f72564eae30bc40f510c2c60b081230adc5c2aacafd1e66f9568b5703f6446c504756ee69733fad92e9aa689823d0a23b97d46b99612182c95bafc9819ff1067cb41922db2dbd3ad5bfe33b48767a688aa33f393abf4933263989a7a564345d7c83d0548487b0e09649f112201c3ed470109dec0296820e1505b76575d44d4befff5dfd01c1fc49b010593470761108bde3a441c7c4fdaafb190b564170de9ab9df051e7bb0adcd9908e391dbad9f0ebf0477675ecdf311799e69b02ee8318bbd2a025c3c0edaac4a3592b79f62a4837314c11201a84f31e9e6d958e57866040a5f2bb06982cce859b06162e7a040a5b33f2be5623200756880a328c9a19ae924fb7c896f5496a60340abc3125eec47590fb92dd03ca44299e8716bea1d047d06acc421483b6e41fc46a4a745e158aca19797068758b833d51a5179d53d42138f6381735cbbb0c2b54426754a62afaa6fa98d0cb4625e0b03ca0a3d371cd2e6dd1ad6da6d2bdb297f5f13f597d5b7077ad97108d0e98ef8ad3321cb4370e8bf374dc67e3e00030171ee1601d2f95086414f8c70209dc1716a50219e35992df51d221d1fdc9a18a45e8b29ac81e5ca93d30d428216c45440b8cd926add5519b0054bb86a61b307c22323015401c2eb728da840ef047d4c2abf2996a60944aae607e0e052139c6d12df55f4e28505a16c0e7ac134af49afc298e4f7493270bfa502282bf2bd621c1aa9383e0a92d5858523b198cc46a14067c1e00d8de0b32ed1c531761786b9e130d373eb9fccc6eeb2eda5d8f75785b906bc1c05906e0097234487c6f9c1bce308eafa1615256edc6b6b87a2e70d81c86576634bba14ef1b2daf37a283a5f4cb18ae78e59b20362d53afe4710bcf560be1b0bd378dc7d95accdcd00d0c880634eeca564b4796895b914c7c506238ae3c395a68137a2195e000451995588909204a746379ac80f54b7755f9c430f7dac534b39ad28c28b99e8015638307e72450b8cb6d56c68b791582e86757a7cb90d014c783178b14b8bfe53fb1abf2a9111591961bd0131261c82275d1628a06024cd36e44e0e4fd5204894b6e17086a8c8ba36d0aeab3737556bc35642082d351adfa2270bc1faf0ba09d661ab6cf443caca1997093d787a97413cae68482221254ca6ad099580274db1646fc195b4b105cfed9fba2d3ccabff992b2e05a6aebb5d6ebc7ae40ddde56c86763007485ae72adbc1375be6925b889e3e02259bf24b1aa12b76f9ad65306490fd405938953c69b71f50d702e82e4c451a537200e3cc349f342daf3a4c3c7ccb0f15e616383124ba5de8ac5d60764c040ff56c415220aea6222300c018f7ca2ea3dc57d508c677b779fdfb326d77d64b7cc573d08f2d8d48e79cecd62f080f04b96580534a807432fe4e4f0433472e7030652a9a146b463f83bc36b46c41ffb48b1325c11a3538a845639d98c970e1445658a013a8d9a72ba36aedb034b621b89d757e460e32d771eb95782d6fc4a726c9accb93774b04d23430bc9e39b9c2181878fe1ceb632adbbf2df4fb39fc55a73fe78cf0a50a40791b2f94d84e756b7c29e6f7f8f0f4c44a87775423b21980066231bd3cb306d03a86ebfc70a38aeecec325b7f9e8c4ac1494ee261f2a283ad8a2970450d2cd5254dbefa371d98ba1b27bfa0284bfb1e4d069735b724225ad6d93912466c1a74f07cd9843d4c411fc05540c4777283635a8ba7322b10910fba436c84809e0c1cb773f53860351cace24da7f26f1aa05ae4c0a1a1cfca141c8d28c05a16ac2cb83404860d2702cccb54f37aa462a600e70546cd3e426f7ced4f257c8a47f406b1a0696ba3af516dd6e02e3d55df110ee1ad2539d3d21f7fdda85ead65d32d69791e0ab6b3be2b2a3f158a38b2d8a25ca8ceae350e29a573a3e1c28310a92bfd4cccaa5ca4602788c2936196e7b694c31001029e7e9131abc4e57be60c8d60d90dcb73f084ff7735d9b6b40e357f528f934cc700c8d873c4018b91b15293e280528bc1abbc95f361e5aa23a6df9f4c3ff3a5c6be857892e384b0889b5c844f5f0c63a698c04bff8571655ba39c0d6d98bb355d39b4eb75e43715665d93f7d840aac0539d367298834087915c53105f9282082bf20629b93072355d70ab1772d0069349560a1901db72e359a81848280cbeaaa41a6255212fc3c9d2c035f185fb6c3f0a95daac8bbc6b7baeb449199ca6e671f1116ff046fc4d2fe77d654cba12b157f2f217f4c9d24de8e021b95fc4bfea89bda26b27e2dff3956947cd72fe88c34e647c24f80a64f157eb3537a44f4560089e81ce39f4814c7c921a1fa0c5e85666555bdb78b272bde309a023bb70ec66ca3005144d6de55edea7ec7394d1b2eed9087eff331eb5bc5f92efde73c5b1449dfb5f8d822094a12624a6de71d2efba4699d16baf0571eeab785a885669f7a64c1b5cd34d43a2e27d12e5a726b993525c633796837224003c7b3602469c8e509304f21905f743b88340ed228bb1ec4ad54bbeb07e8216d08e31b295c69dc52ef205e8ebf038bed90be5f70c60bcda7782207f3db2650d2154d7d774ee622bc31ae36232a1563d1067b4eb0e46aac2fb174a39c0b066de4ad7ff88b6625f7d7db6823b3c919769223f5971942dd7d3c9ccfa912f38f6096ada99838387799883324dbd265f55e9f8b5d34c3cdc699464517ac47a02a9939a82aa997f3a37696f4fbd9555e4189f787f9f71d3d290864aac4a1cb046a33875f5b32e9096f6969c4948b49ef670d0c8add2dd394568bd98985bc772598d18c3eed9327befa440387134671d89c27a04348f8210988b37304870ae817268ea4b03bdab17d757423f12a239eab66631fbc9b8ab917fb0d2dc0b89ea17114f80e01006014f1608233a4fb1f11c9d1b76e4ec072518d98848fb2373b034060fe6b635dd7af23d1188d3873b11a5eefbc847ab0c8308b41eee2d3bcc5fb3cfffef4a800eeb7a48b65d6991fb630aa53788d49e3abe8faa94d78b2c4f9bbb2769d9501e8c5303be66cb20046b5d82acbe1496501670b2e05439b70e57ac25fb3f018d4d37cb45bf7c42f62aa5e1e221c6b9b28407e6e79f9cf6d1b358d8461b9ffa992b0d40fbb18c5de6aab2aa76e3808fac00e780342c661ad75270afe59adf06d299d15461ef5e081cd4e32aff98ba8f7e200124bb361f1b0116e66e6595819e6eafba9af907db765da91d61dda9a00156948626da81e037589f371aab04fdbe959b4f1fe0d267b311dc59689b8ced5e175a1906f194b21712770f3b31c4ef87a826ae9515df000e88dac119c99004266fc18303621595fb33b04b0b8f6306103924ff5d26540b087aa20df6d04adbb9c265cfb6d23e1de3c43204f48533b6d6a5e7df1827e8f8152c75f7bad60c0c4d3deb6b3de5392798ba377cf6824017190849b04e2e14d774ad42480797d80817db91e36a5f26841809fc418d6695c867d0464db2d4390f4260b4f1bbdde97802cae777bb192f8b093b3ebba2a865458d262b1a1ee4d826bed829bfb52369e4a13307990bffc22269b41963c938b646935bf28b90ab1cb32fb8f5ea03229c8ec4610733b4b09eb5997aecad42b68e119bff37536d9c6fc0e240892d488c8f4e26757f640d94d07fd7a4b49c7042f7aef009a8495af1b9aabaa32b69bfb611c4bb6f53958ee3812cf95c091b0f55220cd3c6d8539e3682de051b36c348243bb6f5636ccb51d3bb4ffdf525e36ca342d7c45c5e112ac40b02af57da520e2ff87c06fd575aa8bd9a2128b9902fe131d9c39a9c7fbf496b50aed58cea85b516ecd60996ff961d073b42bb01ea4b14b6b8608ed3901a7f29302bd825fb74f5054bd1660ecc654e76eaffa4cd88fa28caf6256ec32ceb2c60bc50c1544c0fad34d0a51effc2ed614630e777d126164013d729701fffa0cebd3f6ae55644dc6a0798e2a068fae33840a03f6468b5b22b60db75c6faf8c97e0f069fcbf8fdb60c9cc5879357f0188b68376da4d6a0cdeca36e729a63e0ce5f59de37e3017deb575791c57e9620fb2de96a7d8f21be0a7301939ec61819b8ae52abc17fac40ad022fb06304f71a40d20d7784408a4cfb10636de17817ff6fd862d7ac0bb7c2b640b5751078c4885f4fc28b803ce31b20267443e1251f6f248e0607299a9d912e73a18dda523911c36f840c7fd7064a245478505d30994d090c2291627f44552ce0bbc8a37008de2a018a38a4c55ec085301b5dd89d51ef0981523d72f9697d8158d3d030a48ca9aae08ac397545e443675925f75cf51cda139d3cf07e73397fb8dc520884214c292b43d343258314c471f4068682a463877f12c8581681ae56116198752e6735176004d5934c99e2f84f9072ee8d9d153a340fe80906c95d55a8c9cecc6d502255823e95d971ded6d2d6a1cea2f0496c37e609195b0d0e500bc15228be89f59c4d5599a4c5bc19e816d4f6067aff643c5edafa203832bb50cb18980704e560ad70f57546496b34f2d535c779a2a51596e8c7855c05c0e7cd9a8b916782abc2430131ffc773837f1e26bb650ebb846377daa39324f298956c08ff5cf0fbdf2a3307ce0213b375696e2be34ded5835a6a2d73825f79c92e74add5ab94393066d3821526a7c720e83f80a44abf231a3222f0dc7a4538d2f9141f7d5ca2be517827943108279dbb22385046c5ee71ddf7ea41e16b077016028f0a18f000f821cd83ed20afb1638be0296efb9865c816e6292d4416e165d8f4974c87aa9a1f9a49620494694ffb742a5ebe486c5777243355ccc4d942ee5aa512d80452427b384eb5f8dbfb2a53814d19ac1bb310b8e47e243e615d68d9bb18f33b6c59e6ea4cc0bc61a2a24672f23d9b1430d8953f7be0dba7805714cd2984c13f8a7f55932ecfb1ba008738515170f305854a408f2f25b2780a915575309959024221d8d7d3501a3538b604d2472a73282228eb7ab5f1f23ace15cd85aa28581173b847650731cad92b488f04a9cf1bddb329051e1c411aaca34467f5d1c6105c5cfc059d78f33ea865c8f3787b531c0603bb1c6374ef72adc8106690f86de4806481b7a199ffff55106eadf8e6a2349d3025e9c4d6bacad5b6c569f519f2e85771d601c0014c28c570c17659b9ea605010700789703e086fa669d91ca726bab52998ec221c9bc9bdb144304adff22d3738dd7328b4c19f76c16be3f76833fab29afaa5b0c0b15135d7c3a80421a150c48fa4f65792d9ecd9e14e7cbf07530f0122f58a1159e1bebabdc375861850d77449bbeb5ecdcad20f2b6b6619bb9e57520d187f8eee371a0f01c784d1491746686ce3415520922ff10b49cc4aeabb185a9f41c449129b99c51658acd5ee7418027c7feb40ba420ebbfa2e759895257576d9adae4119ca5949d7ca113a18a1e7aaa4a0f5574b0128fda51ac7f91453424e4550ec0b7f3643fc4f7ac1900803085384deb4e016f21bccc1007cebd66d52ecd217adfcc785d857f162877d41016f197b4e2f916689bc7d4b205625c4d348165d917dbb981816180bc59afeca4184c842973693b6568f36e477a801a8b4e6d6c81710167cffd5929afb761c2101acbf754f7a08583f33dde4978af1af3510046f0db6756684ebe3e1401d81c00e20f3185a863e216efba675453b202d28c62e3491d6eb63c7d37aa10035c85a7517795a330b154c7cb2f6083c136e9fbb25c36e6fb192d8fd5d55c7d99f40dcc6518a419cbe4e4bc143aa301705733a263402ace984fb039ceae69907c022f7219788edf9c91d30281ea6026149c39e2c208d6337e76289c62d7febb1dd5101338d03c489b6adc2a94708a556c6b3558e49ac548eb29cb428c0b584cdbb554f3473f478d86a071e67cb2857ac6331c1a99c89537623d4ade22a5b8bb3f58c066cdd5a78245b54d1b46c5508e9aa5ca480d6c0197c30ef4ec078d86c7c72b9b43f53201f6bcd62b5ab8d7b67b01078e005fb58ddf52c091c11fc63a04db4d4f5ba97598ba81cf668ca917e6bf1b021779ac9acc81b2ff42fb06b2cefd491adb7d616bac7d314212a8966e5c79f95bedf02304968fbb040c76d423533b96402fe7407535ae831ae5cc893342eaa58a7052658c43ccdf677c5b9a0a729ce66716d1e0e7138fd5713c02d3d3aaeaaf2430543c12610caceb5e667c3eefb43e9c4dde55220ecaf3df2d3e55fc660fdfd6d8f4a399394c1fad386e3a30945c406ddb95cce3faa541aa011b4fceddf4f4fa5eb8491ad0598cb7f35dab27f8f5d0179ee5c3ff96d970c92dbd67826be8b92a1012207fd80ccf0df4f7663abe11e21717fb20a130a4b7cc3f2a4ad0909836f3255c844d43e9eec2e91a5683962f89c0b8c5c7818e376b0dad205bdcce83f18f207c2e7fc4ea3f106ce02ae803ceefd8611c8b708b335f8c2fd637200cb678123037135e0f237e6f9f18b04e30947bc0f0ca60895407b3e65dbb7720ab08f8fa46332dfd0e26a4dece89b67229f4a44ce1228e404b179442133e9a6cf90af982dc87c8495ed2f55e69c3641533bb5c644f8dcb161f8373a87f8d90984853151252daf616c94e0576a0df0d7d8c8ac2c6df90eb70af87ba0ce497d35a1b0b9941beaa5f6f17d3866a3bf3eba92347c56e7195483a6b66dc4d504da7b010674f4197340b44bb4cdd871c20502fd1caea9b820fcd47c828afa01021027e538b49239b9a990ef86730c82a4a9372e956c04a92b2ad355c1b423d487c3cbc112a990e72f755b721057880a4690a8d1f92099757ba174d7d887f1d9db36756d051ededd04c9b5b5020f15eeda6e02d5bea38696fc277177cca7dafadfb0184ed207ad0f840e0d27bfa626e48ade790a78f6f0cd5a127e283a93ada77af832706bc1a66d87f73f7f70b26859093f05ca7baa3432cafd5a42981ace66c4bcec1404856bef94b15c0af397bada8e30fed61f41681050cf98c9bafc5f6b94d8e9adc8551a31608eb43ff9754dc6d389eb6c7eec194c6234735aaeb5ed3740c5712e0a2c4d550bbbd3820d8353c12a80089856d01d1f559bb8c3d85d141e571c7351aa84001f802004f06e06e0ee4f9418253194a80cae1f68f3ea80186a35893eac6c32be4dfe0731b4322014d8b666a58081ba67c209afea223cf0750746672e268094cb4b1464c4b47a6b3c00476b645250105717a8ed7b42809e35ba86b264e7fac5d704493bde4bcbea7f7852649929b2eb3f1633f1f9fbf8d7a208dbc9b3ab3dfb9b2449c00afcd03ba03660811f9b6bda0d92003dcef87b32e1856e5d1cabe9568beb8ca647d0d32f9e2b040f0c30ae8ba71c02914658d6b47e31d620e7e85d4c6e32acaa125dce72acaf3c3af1770bf1ec9a2c88cf20ab6be60c9a44b0a092432f54e4d31abd701d5515cad6f30f9a62f20a5b983f39fbc3aa7997b9e60fae514f7ca3a18312f396ea699b7362b25e2132c34c1657adbeed960afbb0aac991742f204aaccd7f80432ad058ac4062b68d5d16e8ff8953dc32adc059dc572baa1b7495a0cab58ea3eb14e0103ad282a56b91ed5d43d6e0f18f175c98e02eda980b864ce32368c60381a9912a4494a376d874de059734e878e1fe264c61451161c4d303c98339c530d2a5329245ee2f081964883cfe76601fecbd0e9cb22033e74cadb3dc5857a37c64b5e01c1d6f809f810563b38d000c7557613475297eafb8e2587192fb9cb048869ac64a48737d4971363c80a054806df784cc5ef30e083e9ac6eb8c1701b08495a832340270a4b604a9f2deedeadbf50a16f12aa03dfb2d8009028f3e9baf68732fc24a95b65feb3fd0c25e7b52b021a50c85c02830f7dd0729bfcb440fa7a471cd5ed864487bd068a0a766b5e15305934d2ab6caa449ebee6c51869a064dcdd418306763257289ca32e0a7be9a93e866f388cbd85fadb7d68f55e346b6f7fd5837b3a71ac6e245b39c1f1bf48b0937dcc0045d32a2c8f9ce0f4a29deccffb65d35af6994a24b743137efda26c028afc0482ca9034ef0005a8ba5ec7c450f486b84c65deab89d00acbcaffd3191026b01017b56bad2969c35f79fab7d7e6e555015ea9872557a551cf7636fa579cbaa67e1867991c93db45ec52ed559819a3701d6daf9c104dff2647451dcbdd51ce1f837a86dce8a7e6708abce62b85fd8d8130c8834c7446c571139b3df6a375b97a55556f7199c74787303703de9ceafc1880179a61a075f80761836b98ae5502c1dc9d860a244328d1a33229c3fd7b61fea92b8bac334cd36b971071f38aa87670dd178417e4ef29bab34e4a22685f57e1cb12c899605bef84494cb058b1458fd683b86517dfc6e142c603e48c6cdfe3813a65b8c8fec9fe86a0a80a20deeca116178e5ae71cbf4226aadb7098aa9a87265437d62583528de7ffb1d26c887e855de6befacfa6ad6ba55b26dd1dd27c238589144a2080d8a1dfb3979aa1c8e0e1691ad3911ba66b1ff705856e0d451f8720d2b05964fc6a11509ca76b3060107cadcb45fa3785c418348321caf7470dd5e52f756d89ef4642e241e06cc8626af2d0db5da0d76ba074c59a0f8496f45a1d55b61dc9abe52e250a34f6ec79cf353998e712c62e9e7782c24b68676813113269263bd5a36801f88c39dde6f7dfef6ea4c3972c4958fb0fe63b268dff39f7b3df2481ea4acf1bb5db76fba5c4981b7eab77db2c23de2b11e2ead7db601cd1b6f5e86b5e6c37418763555bc8458eff7e802b18335c72ce12fff68ee581e3e230af6a56bc0c9dc99921ebcbd1674bee1b902237f9ab70edb6b655e82cd7cba88b8e2849e2f15dd206721ad142984f65ef13f3f143e5d95c25e37c4672f3efd4393c0f26b5280dc330e74a704fd6421505f65a923a4b21c40668102f7b15dcd0f82938fad13c4747c591a3ee84725634186877219dbdebbbcb83b98118a4640fe93305b571e7e912112e63e1aab96867e438c612ff5b32b828b09dddc147db76cffe1dc8b6542d388948222c1956118a203456e37ba6178300fbf711de38c758531b004a227f1fdab53a826adf3e6329dbc6cc72f3ae57e566c502fce9aaaf7d8bd42dcbbcded253e6478429bf846db7c0185e590d391a1da5eadfcadfec21aabbbe9c8e97706c6eced6f8b1960f41e6086baa9c2f4385195b124df5825dab2e57afce2ce59628ef6df2f5c644de08071db5a1ffb3d061c3ba083c4c874bd9d040c87dce6d7039550afd7ba98da24f7fd96a07f44040639452d1e8407272a137c28233a650706cd554d37c5f44466dde0777c801ca7af1b3e29d38e2b32321cdf8f26d269a8c1dac3f5e95f0393d2fd0c1911bfcce84da0112d556df7b06748c14c66b1b2910840991a75184b669b0a83bbd65a4267d8cd65400e4adc7ec4c706a478ed4d5a7923e8bf68941a6f397b914aa2137daaf543c73f8415329a5277aa90f6a632d1bb41ba4a9da1bf741b9e640dea902c906f510af80843fb59f17dc8dee8f27c4b255c0338ae75918311eab7100518f536fc3f1927bb56e3b186a9526748c61f7cd768fa1ad1e4376c6dd8ae91391a8a7671ec8b446b47d8d92a27ae5aca8d20368870a731aa411a2ae493fd133ddfb2a2ddcee5a8b6ac3665a6fee0c64124f07339b24d4ae9ddcf0f46ec28c636ac7fa209fa4c8cfac5c4c0171df05e4d8c69b8516816b0df2b05862471f65a7612da344c479270a78cbbb54d6f496a2333024b818b0d21910658e6aad69ab2c816a8d9af76b2576b1447f613039a5757d131b2bfc37351642e3ae6a2b8b262d4160225f937190bc7bd8b774edd8eb2d12108597a1e5cb05213fdb0cf0e1458f16c74c71105ad80a14ed1680dad776e6213c2f7a65cfdca20cb7517802c7d30d25ced7df83a0dbce5212f427989db4edad7622bd731d9d74b62a318858e0586547395d772f5f7d0ab376bd6839b9c15be9c111181d0d5c3cd460a0d1273bbb818d07bb0ed2a9dba9cb59b0e839bc040bed2809aca1b069a83dfe6da1b1b800bce62747dd66a3d270991335d0a80f1fc555a6c52b458369db029071183296ed98990f888ae7240bf8ba8609111b01f64dd4c7f9df805b81a58abb8ef49be421820093b54efa715f42dafa6e71a205c7252caf80b72d2ae51c0c017d40218932150304b2bd548e4bb009aa5a968d182f9d4702f4141208695d230ae6f4c8f7cc28698d3b0672acf0df2c36e57500429b460cc89eec2846e14ccbb2c2d569121dbd8fac0f8f291c02e152e0f51889b02e88b8469ef16e37354f3f63fd038696aeb8ae5574334845ee23ab2ec48cd066aabfee7ba85ce307242abf794d2128608510bc60a4774da2c9074ca44623460ed6da1c958aa10a88deba50b1df4d783618d2a30186845edb4d44a24cf3aee719f0db34cba41ad30430db935c2f30d276f11e35b47b6315e82534d07f8b1696cfba72581e5fa3cba2e7befa8c8350d68315c7f758d87da0ca0bae484b910babc2f0153255da145dee6546d8431fe487998facc1e8a18b4b2017c0f8a993b08a4f853d645cfdd7f12294f6e65057717656971d2bdaf8846350e6a7b4db5565bb91a6f13eb8421f1bcdaba61f5da99fef77b9b8b6ab5dfdb0a1fcbd2624146e6c54efe99002a7d1ccef3a6a049aa79b3ac7a082c9a9f6702df0e8f1fd1c3e0907d13ca2d5c9943be4b5465b0a5922f69f1514bea4cee8368afdb09264d20a92b4b0d54a917b8554efaf87062f2e7c1441b8a6a44eea9fb61fa5d28b2dd1fd20e88281f1ff52d248786693efa499ebd7464b3738aced1f499222af7caebdc4e21c5893461621afffc7edb52f2f928747875a10593dc114836349b219122553d8acb0eccbb105349265538ff196a8cfe7293dfa81ba58ca7b7979ee3300d90c5393ac4a82c6276c57f930346deb7721b993b1bae09e47cd6272867e5b236920ac3efb9b9d6b41e29ec033a586071e5e53cb11e1a8293e1b49673624225597c49a63755c2f53f95e7c5d0857afb31ad163362c4f8535e2b2df837d64c0b6adaf017851baa167877f63733b6715993e3105d6b1a8f6202388fd5d6ce021ed6bd30f7c2145977e786dbbe968e032ee5929e65bb5f1f17ecbba8a587c29d69fe430780d30434db3f205e13022675a75dbb582c0ec8bbf00b37e157934cd16864af98080ce4789b24c40dde2d45692e51726f42e5f5c406deaf27b33c2e268dc7ae03f8d466f5a6043b814fe0a23cc85b7f6e69b6750e3b9352b34e78471f628ddee680be61a2cb8b371d324451181e54b00468eb1edd149feb6bd8b65621b6908b9d90dd1d76da5d212bb6afd6094a2398b2c54f41650082aa65511cbc89f8dd6b8ba81a187e288d75f120fc6581583d6502bb0b22bfa99cd1ee45bf31a3b9039587081cf28a91496152901d9fc965c954cc71dba5c4dafee67f7c0b2b62a1d7616999b27bcea58bcbbd55d7956ba41793854e4d2c59b51d6a9114142edcbe9a6e95cd0a1733b4c2ef80dfbe56c5e92d516edc68646f89ef271cd3667e0c3278c8f968e8020bbe7f51b65fe82cba0ba3104c48716d03d3975ff1046e6644b528c89f10624c1f99b4cc2936f268cb7defa05d49f15d5a82946c98a634d9004a315d50364ad980915a758b35ce3e91962e96199ede91d2cddd212f2f3b1efa465e0ed0626a5fea7652b4fd2aaec1183db649ee9504d5cc415a0f92aeac9a4afc1288341d8cf74a711984beb31a82fb605cbe77599fac0c08ab17929c6367ac54c9c547385518ce3a20ac03f700d97b38167f15e8011d92526a9d6391a57e297222d6a00a9be584d59ee91449bea91c52a80087942c66ef1ac5bbe7f38a3060b444552cc58a6b92fe4dc679542f84061ab27264ede6aafbfcbfc1d506da2b43970db032dafc7056419c003e7614b154482077ca1ddc54a0a446a8116a70f0c6c241ce2b43567bd8416fd29471544ae581740ce95a52983ec0963aa073755b73f0e5c12d796b05c6a7542d9e4e4d092fb8ee0dc89a8f5465a43e0a92c927bb32d16bd6055d2e2abe860eb4bbd652ef090dfbc52ec9fb3e86a069ea63fe3390ffba165177cb3768e7bc5e45d0b86b0aac27d6660426af993da77b80794d1532c1e20d8c52e89fdc370f8f1b087ab689df216285ad668f1a39985fdb8dae8e226e54ad723ac96f8fc4a731e0c4116c93fb97c2857ee985a8f60bfadbd82bf2b1d97387c0cfaba64beac91e72d525beff87935115581ab9afd1812f1e61b46d99ab2e9016caa2b6b11a6959d1212e80aadc5c1210bfca8c00d8ed767012d4cf8101a2b4654e10cac7342fee7fd869e8fc83ab7ae0caf55189511f266375b4aa66227e9f3b1f0fd37cf9ec2cd64d27e4c4eab78490d0cbd03ff96237872959b6b64e2893c80512470794b1855e63b1077d40bf835c93b11675d24ad6396a5327321c19543d11bec71cbb802aabfc55b9d09c7d83fca03ee3af414fda88a4eeaccbb3f4717e9aa7d07a0d19f38bfb3ef445c3f6a5d0c1d9d89a2caf7812fc36d1b1e10bc5a3a5435af6e2087c34e770c1d73fabc8f0fa908aa4e487a8d2f11887952008622ab8b8d9db8d981829c54e1a5de3eb3766d0f5955ab74aa2486067cc75f11b74d400329c23c07210bb1bbc39204f83c445de9875f9dcf94e0415271b5925eb32813035122555500f78f0c4a108d7e0a1b119c278920e1f3ba344c1fe250e56a577710377b4d08dbd7dc3491f4c3414bb9fc995fcbd34d7b408f36f3b10d8af513d3a85a62428f949586babd70c15b0630afe1db956d05ec8fd7ee4d4250df08ddf254e1c27ca192accafad9bf4c9301b62b7fab614d0667351334c92a6bf8d2db855b9d2031d371059e1569b4e3df408b4e5613642a6ed26e65c7aec3c2a86cb2533e29e80c08a3d03d0e653c927032393602a02797119d62c678870a7a13b6420bda1889804c73e930f65179fe8023f3fb1661e64d9e5479e247f7c123e9666c19e89b634c322d4d1b3fcc45c61c4b4574822967601096a83d870ac9ef98e82cec79c008de2e0b9c7afc95e86b226dfa81932ba175268f0d7e390951e40af0b057beeeb756f7983496ddf18228bef4b3a8549f943e88946ba49381da02aa1bd67d0d737194cf1dfbb93e36b5ed54887dbf908a353b65092afdda2d4021b575f5ea1d4f9cdd6e968a96ac3dd6a442343d90b1a28ba19d955bcfe338f40f59e53812f5be502e2a082e501c3a356200b47e7f0575bea4bdae77a9e385ea9c2b71817fb942971cd659b2c3b0f80b0342c7c3bba06adc8d75caa5d44209a8bfc55000053d43868041d71065ca61939017c00d16f9398704c052eba7e4869d72369334f29fc432587c5608ddb47bf5e6c08c3ce58bb1257b12973a89b3640110accf4f26a7fd0ae57ac5db02b7709a27f811117bb33669f1139e2043ac9d1286f288cae9696a75522e8f4177ff0b7456f6170892c7865a92ad49af6a85d11ad4bf6cee3d3e80c7388eb3666ebf4997812fe14e795f7515979f5f1ba3de1592c79288408862985bfe5c33a360dc963397a809ebdb21c20d9b681dec0590f8d98ed8d959ef9fc95de6adf19ba01d9049128f3f9f0e087f4c68d201c36b8aea07a3c7577aab068f79f64cd709551beb2165a277d2a2dbf89e653e512f0f4d905c6a5ec25242e220cf838f5382262481b6b298e32438221effd31cf0a49688e574e65e8c081fbf6a680fef754cd9135a16a4f932d23b9524dcb4831b9fc01e52c454a451759a82e776faea3a6f81cfb8373859bef442ed3dea358bafea3501b6b72a0b2886ab83a210b5378bd9563a7908d4d33622dc3e026d79e58f16a22bb7d46adc2a982cede2fcf5ce5ce7c5ab567c4b60d646a762345473296141bf0833e797eefe35713af32669b1cf9617f75c785300e2a092645bb62f23887c13089796a40954bae6426e1898b3c683bf623cc6ccc138445c5c52d1166cec802b0b6b51d52163e6d0c55989cda9f8d68270f9924a52e197cd38c0bba515d2a69a2002162dafbb5258a61581e9cda65163040cf55f7aff0117d6c2587ff5b3fa9660d53cd50b8880ee0ed3153ae91c591e6cc5d16243c1e06d45e827b377e988ad5d617af7f3f2686acf249ec0e5790615d0079dec7f9339106d3fc44463cac394108fc86c83fba3b85fa4c78aadf5b4d9ac8eb78d0c7291239e65a784091e77eaae8ba450a0a17daebee902daf1d1e460c992f8e5624583c8c651a130c14c188c585cdde36c00442dc29f50e5d3e0e88f6729336366920956986592ffc25e42d4fdd76fa9ef2b8475ec56471226869ee8be0e6bb0624db6c7808647cc9bd88740bfa19d9cd43c061ba4139afb3e22d814d546f9e82d338119bb9875a19294c034e881ab51a072e2888fe8f7a911a0f5dcd830bf4d6edec76b0ae66524519092b7ebda85eb38b432247f3874bfc0023f6c0876dd1476d29ea17c71804a813e80544fd0a3755dc2e37e8d951c8cf95d65192fc80bd21441814bfc249bc4d8802e361d36b86184da2697f3856c3dc4f0b86f1fcb8a33ba285d0a3acef6a23b7074aed1ed15a967d94339086ecdf896a7318f7fb32b864631b18d5761e2fdb6c79a1fb5c043d70de28d5f0e69dd533afac3b3d2d9cfbcdebb309b46388d649d0ed32d30d3dfc918eda088fa39f84c5694b88b6655ece8980b654ec3d47c0a0ec7b7797c0614011f7cf57f9c46cd8d2e90d9125404f92b9dbb36bd3d9f6a3abe9edd2a62e0e595a2fee7a2f67a344090120056b3023ae6a6991d7d20ffb0f38d673498f4cc5cf022c7565a716845f054fbf1573a6a733f54c324376112fc507c329feb837c31f671bd5ef970c28519b66b9fe09e83a5110bc14c031cdfbd4e39ff38a552342f369220e9cdd623f4143b3a4caa2b2a87c499f3fee9744d5d2cc85171825d988dc5bac0b26d8e7f43c25378d8827053bd88b5f06efa3854b530963439d108d92d87088a853e0a63b9743b495fa2d4ef797dd9f2cc3e6c1641d40f112b2d020c13da59676a122afbf6b6d50355ba901ed3384d743202178c557deca94dd20aa16223155b93e7a59eaa0416b6dc4ac8cacb3d39d1c28bb6b73638628266a42753149e3c30ab7f33b01daecd2bbf566f8aaf5a35892c3c9de83f20b90284115ad4f46b9913d9985f1e76757abd9e9c288cf1e45364a6d2623c0a04d031ed2017393f9f34923d5e79a5714ad7cb7404e3fa0a90ac881ee08f39967e6a5da7866d6b2075c293eebe7f4fcfc80c22599d12bc15f574955d7f49e75234d2dfc0536849a19d6f419eafd336789679cb96fb57ac9a6698539694b197593403daae72c162baad2a1988df8343b146402ae6e2a5f30e544cf5511fcf075ae834741acf68cd298ab3a07e7d8b53f040c677542af1221e261de84cd62d6c0956db0d92ef7830ccdc7928124ed20488644300a99f7f0cbf41513a84178b710afd5b47102ca794a3b267a01623308ae01d60f124d88c8af3695bbe8637250fe46f53ebf359ab6e501aaea643d3d597babc437b243ad1bed7c096d2b6e2f0308708c0dead206f7d6092974f0c23d10966b4dc501a03dfe0e842dd0d2418d35dfa0b7237ec43698110e8329a6b2777711535eb53dc2677383c901724df564a01939bdd9456b93aca7c0eb6117341533a9335a10e2d587c11d9916d7c4890c1537a439fbee851b0824b1f523bbff93b580126677f6ce02a9a5034fc9341b8fdc790f9ca2a24820ecffdd7f6036e4cb06bc0301a0f264d46e84621649ad65c7f24917f6dfead5d9385362a829d54c14829e16d559547f288d5a59081f4c9c6f511af5e94804f10d1fa4690ace573b82f10726297953db7c7d38523658c9d4546548acea36cc8d11238a88d8501462131b9d0010cbe488048b0f83d203107bad3d777c587608b6173c8c1d58dc88dcd2069ecd981f87cd9498196c40940ddb85601c467ddda3cd0ff014c7f779cdea0f039f28d37821ce4db6669195cf5f28741341cfdd84718b4d573dc633c42030ff1e7b8d11837ef70b52fa62d2b3c6a8df64e0cbddd91e5ca87173c32a531eb6a6215f9ac61d48bfda398750ff039ce903561f62ee75e1410b8c884f889bfd4ead3621b1dca902637cf3b4d54800eb58155c8869b7a5e1ac823c3ac40a191c894253979d0a7140ecde4f6c412ae707fdf858ca6c6de95db80205d1946460242d8887b9219c6eb1d67d94589dae015e2cf4f4709b5c0317b9513044a389110d22f70840aca7c8c6fbc81846e2a486b27304e1504033e9805bc41194f1b04a56cddaac691f9d612a6c95ab3d2b7dc4f25df31f5aa9349fae70ce2226f121556872a1c1c6333ce81a47de02dc5adf68e2973399991810d14dbdc2fbc6c022921383df5c03ad371fbd00b9bbb7e1ca6c63bb9205aef492813f654c2fe128c1e98c3c2843400218efcd34adce90f64614e752556d77eca1c9232ed2d7cadb928e330c1ed0f88ed9834ad62de3bd00eadc32e5b79aae44e1331b15ac08356eedf0e8e6132e820b28990b837246cb03f54e073feeda6a8ec4f9ecdbdae07921c6f0b06edb399f77895b33c843d434a86d538e0e8e37700c88110fd54dc2fc82c686866cd1c29ed427050751b2966acb056818da3e79b84c4e37b1779da3a101f812af231f792285c789f087941431225bfaa2512af3f4121791b987a83c5c46d2cea321ae16813056e4ffb6c9c6c346d79f5e9b9a7fa70368af5a7ce4f6b3feafa57d1e61684634e07221012e4a03787c7f8f3da6d3107bcf03eeaa47fa8d6b09b2e7549644bad5974b374dcc1da11221f81c22f9343cd58e43f229a3b188163606d4a0fe1826f6eb66d1b6d8a3ecb8e3c434d419af53681c842521ef7f29a3660489543b66d80a1370600e2ad5316f7d3278d376ed39d377a076e01b9e95d65da55c2cadd3a2b6a3ff7d40a3cb14545d08550b967e48da7a903fa632b90b5667ce5048ecf42957ab53b8b712f0dd68004351e2c5d89bbfc2261bbf76795d1388b034514ad4a335a4dfbc17b9f736232a470d5d6b9957d9f7abafc020523c74bdafa9b82f2d48554d56db16a04d0b26938d2d3d13e34cc3a1dcd9a0f138f7471973e050bbe26f6813ae1fed03ef91daea1cab3490a37d432f1af4dfa4304d1131ff4f30cacf53153142f348f7b51a2fc83e58279f0e8603393321d86b97ffa7cf21c8a1d198bb9a8ee3b51c65e4a4e0ab69b62f084410f38d9039920556751fe3391bf6560e2acb3151700311331b02fa54e44bfd4ba103afe621cf8fd1fa83d8c30184a15f6ad48fa9c29059867fbd5caf143a40282e1d819bf3c371bf31f62df1d80d9fbbc5cfb4a18db255c51b6d55a912bb0465a175c291ab13f838789ba549214caca259192ea38bffe43c84a87e4cd5d6498ae94ee3a0f99656d3a825b7172e9bb28150ccedecb77aca715c441b45772fe2ce4e7635ee4c8258274f3eaa94c482d097232a66b7611c8efbd80e5fa315218ab857ff5ae03ff33976c4ff92f1c4cebe43e993f7a5a9b8b2a132e1fda7dec957b3b9e98d36911829909a284ed6ef1240e02171b323e922212c78cf84ccd2453b092e928c9a04c22f7825300f5345c3dce8e5967856b084b851921a6257a68d933b101b9cd135fb12a159c190dd0a212960e72c8a0fe64bbe958025dd845d296a509a760702692575aad8f0bcdcd9eeb7c83c5557b134d999cf01ad47c7c1cd1ac7406af0a44d5fbdb9eda198aef9c41e77061506445e4813239e41dee6cadccaa221fc66f6ad87cb421821fbc9172d04793c0c2e044ec1be5d81e006e2016ce7339022b7d52b37b36e1e648a02f4400902e9d8ca229565d9d3ac04c1dd6a8d4368f302b789915aef24b76d1859947b9a551be34ef9b4386ecd5cba2712d3f4a9afb50bd2f2575a8d98e75b065c8e29328d89a1fc74f2aa6174ddb527eeed80e5fe83475d9a78fa525901e582a05e88f8ffb558438e32d68a341de6e95e6944d10ff97abf89cc5c4d4abb6a55898b09a9c46810b54548556ba7296aa31a80e5c4e2cec5dc58b0c8edfef3e41541b79bb844ca925901533c7c0ab303f9ca371879cb68ed6fb9b900476dfc175be1803f14848ebd88d6af69bfe28be8d0da3896e07d8b8d89f40f348b5ebf010698e92d44d4c2976962d9b576fe6f9bff1ba382a4a3da6a85c7f087df812800e3939c26b4c44de3a2bb4d0d5e5e6c5c09d76524318c2116037afd338985499b26049e7eab7853d6a773c3ebea01f73d010159351c9a303e11c1d5bb9970f18c4ff54d4b690a7107664d73770cf628b8606d13ebd6e4fe80549fd336e5c6808033a8e60d693f5dd3a339fb38a39654188a539d984cbee76662ed9d5d28a5f1a9a28120487f888d825f7c3541851a6220a2eb06c7380cb6733978ea5e41f0ce2abed93029a376c66fa7eeefa056d6f2fa00f025be678e5b4a25ecbbbef826495f01101205991592a7fb231f5e0726c00a4b618206d9a14843f4c30473b4e091d92f41f05ecc1269559fe17fa2bd7b881791513551312b058be92b229f7454c153776162f92579b10ca2b35ef37dc95e504b6d92a235462325f312a95953174a3c4bf8a9599ed4f44f49dafb0fbc49a3b2330b5db7588a792ec00d68677addcebf77680831cc74302c40f2b0268144b5f1970ab4839cf8d466ab3ab00547a45e1eb272519ce0a613866863b69f3e5d9f7b79eb9313dc04a09462c354c2845fad52e5406cc412b77a32c071caac2c8032840a4dac3fd01a6b4133c16e438ecf28812432b51ba02a939892bc84c087b54be99705e77a344021f2b70964c2dd445120323c85b4a2a16334c682fcb0869ac0503cced5b51fbc5abba6b528ab0bf139685f9b09f313c0e9db38cb3955d49eb5d72885d694d8ddd9e42531c6f11297e1f15ee92be370a967092a09eac04759681d0eae33e5043cdf7d2d4129f9c9fbb227270c4ad69db3b3e119002a3726783f273bc1abbcd469278ada4c7ff8acbc5a839aa52a33a8223b3a03bc80eda648a6584a220e504d435a9c014f2ec135faf78cbc7f488b532a868baa0f4536bd4323e7e27c1951e72c65d2b8563c311b676f7c2f7c6eeefa176085a6f08b62e03a23c131739e87bb9dac05c0448093a22dcb491b8389fe4c6c962ff8843ad0e76baa23a6ad6aaf29048e3174d3f71b5e1109852cce9b92a8c0b34a065d5b761f9baa13b335e95e8927483c95c7ae2baf97f59dd50d397c6714e0a5f1e3cfe4544057ede6ee94bd4e21b483ea50917d1aee469701008d0baade1b55e707eab23e929cce9f730ec14831c9be24dc7e071839714ea095568881caa5dadd42a370032a289fc0094731ba4946d479788ecfaaee55b4cd3466a5b4b2446b04a30d5a5503e8523d958afbd1ed1fc70f487a579d11d0816073daeaeddcf85cdb54b54f177e1bf3ddec7075ca8ef32f9735cf82658a145586bcda4a06ae26d61b84a59a0baec5ac897dc5663c81b3b54976e73c92d07f26fc98c78c733eabafb9559e843598ad76cbea68336c70786cdd7e7e0d680e7d9e73caaabc8b4f8d35dc60a19dff7373017d59b4106c569a2839c7b7b274308711c58e658dfc9ca9756cdff2c1716010df4eca49e2d1c2c7fa17ea110a979d7d046788ff86f57ee164fa2491787dd64a5e13a745eb60638c20017e013e04f3572fcd247b0d71abbea295dc36134b4c238b963a08b00e1a690a8374bb12be81ab11026a27aaeb533d117223a35d4ae0467a7dbbd0d5830d6917290a5870e6dc46f9d9398b5173b4dfecaef3bf7ec096ac4253961925d592ed75d9579b574a129bd1025492c08aa835ae96cbb461271215ad48cf5b208816e7cd0c847473feecf1d419cb6bba5d77fa4225a20288f5274846ae94f5987bdced38d756bd8c396fb245a9e2b4c1326cce16a120d8c30d3b086a2e8e6245a358ffdee715c32baff63fa01a32659414a0e24f2db0e2afaec89365f7c45e22b662f31240e7969723e008876479cada45ae650743cb4411d80eb74ade9202275304e624eb0fb12fa93f1586f671633907e4b713d4c05b5f2b1e70454916e45d71ac2cd380764527240489901ee3a00cea6088faa2c5c9a799ba93adc666e41ca3ab4839a53321a33195854748128a1596b4982f223b41f48d514b6a484eb9bfa92d5af769bed16671f625442b5b0f289d39e8449cbd8bf01226429c5f4407af4a07e75618135067374d6e9a2b37e064ed786e6c7dc20cd45bb73b95b794250689e8a557168277439e4bba35c842c1ede78a1f7944d74f4ff9ae151b6051612891b53a3d9f224672f8744d6d09f81d5308fb7ff59654588084f44158214eca054eedab94d6930b15f1452c727c5868f14e02c9d9945ac048439c393af89ab61a422ba67e4d8c07326c463a2c5712ed5caf34420296a3749ebc694fbff47f69753195e2489d98261da76dab7831f5e660aa1e21961104954140165593b5b0b6ec9525a337ac3d0722d0252cb0b1c9b958a0edff3471ef0d509ecb6ad68d5e602a17b00ea99fc3057236d18676cbb8bc5b6988a8d213d1d31634f94a952510fb1ee1b66ea3117cf65463fa42b44b96d303829acfb26b791b30780b87c1c7cbca3afcb97f18adf3176b79f003933d671d5cd48d57f049d8759b5475a5805373d53b003bd004790bb1a6403ac35a6fde7e9aa250ac2dcbb0f9872181ca2f6f1c11070a53a37cb88e2c4ceef08b0dcead10ed26f90dc3594b7d2b1089c4caad77fb6c505c9a141dabac72e3ca17234e5567c08f86138fd871a104dcc34b0bbae329470851487f16acba4b6da1f4f19e239a6d68dd7c7819706a2aa67e77a778db72d911a77801c443b404e6e7a1e91664bbfce3ea8562cc8ffce7700244308983df19e007043dd66d86cebf257cba8227f0993ae355c4c6a1e0dbd5552350495524e5bf594fa653073ca5a38b4ad6e20d5e1f4a4b44d54b95582d74da101c06625259ffc2020662b1738dde95a6c67301f8d887c32793101f74408a92a83c199492de55223dfca478067406586faf309c2ac2a15c450fb60265b27fb83df96ced792663d61f8eebfbf827e939bd0031499083c8e5274b13e6ace4991cf85dbd35621fe46219477bc996b6dd7163c85cd84c8f05ae9c7604e19a8b2cda641afe1a20db79a5b2d2c937c9f31686694670805cbd7f4251f99568fc1b9afbc6ca0fa401221a5e3bab4365240d75b84f64be0195a44da6d2e0ffb1cfa8416ddd994e15307f86225c777d8257ae54bde5e6c5ff8b89ef5e225f4b6c7f4c3bb50851cda62154d0081d34b91344ac33d72b0faeb2605e8bcb69a9135cafade1a1c540ac9e10193e95de6d58591a202918c7044bbf0bc59186736553289cb3397189df8a1b09dcab9378de24dd0434d46b2261e76f2173112026dde1483186ef7268294e8b91e649b36e83f3c92570b334e662233c272b9284a6c9a0da34bb670ab02f519863a3b50f874eb95648b740397870bcdce75b0d66e7d9ab763b04ef06cf5434c1b02c54c51e83a41d7cb7a9d1d3c516cff1fd371737211128e46a2a865fe1ed3aac76d689d9cf22711e879b8d76f1b889f61aa1df3b03dae0c35d49ce3027182ed32ff993444c8f63e4f4a8065c91ab8b0944e24e74cd1f1a244a05068b5a43b1497df6ebcc3a59956cd10b903fa5620b949dae2a184dd589154ac609f1aa9ef3fd0c3e687556e6c943a1975df244d8786240c59a2e490d50aa785bb0eb33545ad00aef11fc1db7b1a674874b5f89dda6e307a6eaac1cbe471c6dc279745dba6e8a982ad94f5e26ee00542ac96cded164bbc9b3539e4343606f84d19a41f76a3ad681a343eb32f7a67978a496b15f4914625ae662a173d536ee6f8a7ba9347d1131d7b96a3caa44533f5038ea67e9993a874bae31966bfbc794a1f35b9efc249a6076e639bee04c1ae6234f66cc53342b9c5983ec68e165797054adb636ae71c6ab6973b63997012747b504ee426a46230710528245f271b0b4b120e46e731cb9f978abf4be721391d0915c46a302ddf7b61c23fe34e0b7988840c8b06b22ae586443a2623be6a79cc08940bf004ef733a5b7a559fc8128986c71170c5e461334b812d87dc9ef3c46bc0bd667a144bc0dd7c26522db94ff204d942a10408f3107b8d3478f51018d0d7afad1116121361260f785beb5185b3a4a91fccd66e982ca89b438865f0d60913eeeb9df77b36e3e79738ea1517c888b6dd26d8fdecd1153dc527187c9a98d984552102752e695bc2c5ae18fe5ce73dc0f050e0d2db7c69fcc8c30b878821a3d9df2a4214869075ad75c1f6e5e0ba980e07f91e53ce10a5e8c18fba754a722f28a369765561456974c0dca108bb1f420f833acf526301b018564d33e1aede0335b000757192324e7df4f80e4c11e5b8d806e2040425b926c26f9be6b1e0ef5dfc70bd993339bd39033abca0237dbe6b2073d7327f314883b052f3831052c2626ed92561d50b1be74c5c423ea7df697540c6ed4e6f2737870ad91d6c80554a17ad37ab9727dbdb821662bfd23a2f8c3e8687e299c8a7125a75db559d9b4518a2b1003186fcd9838303260186ab2b0e44b35de5c8354a68ea69d174b7c33c10f3879709c5fee8c1dc22f6b0c07527011b0cbf6c4352b391f162e8c7424be55e855b27d3ff613db56e85525af830dd0233d1312a63e52be6f8946afc365f9e6903b23bee323535c3321f4124a404496318f6a1f94230d8452456d53ed43f322d04928d02ac565e5d5481699de8b7efa0ff5d9718a89e64d14f05716e3819b67ff4bc5548cd8d8ea9a94c313cd733c803f15c1bd8ae962af3a4d5c491f590f2b3b0ba26c925e48b1b9bcf8e7ca281091b0f5d9ad2f45b655a2e5ae9739edb51658c7a7cc788fda2c833646811f9fcb2792b89de42156a3c34c07a808879bf0abbd9b08343b8e08adee2a3795d5f24196e719dee7b220dca49eac557a741b2bf9512b46e665ae7061f0c9f4421f8ef5d9ffd215ccbd837fa15ac05195b6ee4699740a5d835912aa1d8ca58246b465e9462ba9de0f9fd555288f8e61863697560a366fb0d694f1a03c78ec79130a2bed12f4deb851f40d4eb27fd5c69b885484e8243138a5279c4547084ca1d9f1c6b56ca0d4e4e3c0b616485bd8fe6e5b8c237f8676ece24102ae885238456e04d8cf72437ec20acc47b707dd0d1c8338ddccce6a67f1e135eacb57e4515deac7cb2705b1352a16bbc9de10c2a059f1ac7a2156ae841cb41f6f0ed1af73cd166daba0c5d5fa8382a8fc877b746478b2564aae4ce2a998b097bc527b44b00ee4bbfa0a14c7b807adb4d31f070594c494fe1404537c644290abf3174fae852800e6502c6c04a0d00cdecb84e291c225fa40ddffd53f28bbf2bde3015acc0a03b4e6636ade4f4ed88909ec9f51b2c1028dc74fe40664a989f69b774ed56388b6cf2d7a3f5b657dc816b08766bc3c21724284400931a7a1d8fce0fb947cb0935985338ae90ba30e407b2bd5f5e85751f6be259a01b3fe64bfac0f2f96e92898496c51af5580638e45890a8b17957278a474adaf90835c9bbca65c39d6a5677425eebcbbf7d32c5eecc1c495440f1abaf550ab0347431c9b24ddf0f50ce24a2af3d964039cf782a7bb6ab822b85d6587576596251728953d92f6843d14c207528386942df47109f9d0a405a392e427f1f34b93d83490048db38bb81766e35cdccf2fb903cef71e4c9228559dd1aac0de7fd7658409169c468d382eeb512f87d7bd8e50015f74f207b1044e89644b87db3e0097a7ce2436cf90de5f043157bc942683d0f66c535623ff162b3ce598af3943f27d1114f9e67a466c5a08bea0d97c2cda582aee94e3f8a7f7c4802b7df4fa798b0da5b8378b03cb1927acd376467d1e78b860096683a713e7d3cd8416fda734ece30b6dd376644f1ce3f4dc0f77eba11b913ffcd52335d61891c368ce76e63454937007b63a96ac57e330687ddd2ae8a9fcaa6014849e70e9c0f981447e28d08eebac4c3b5838af4a321a535911f6c539b109705c06b051edcf5c4203a3c628891e741ec7285163099f07f471b47588adf898aba0b7189b80f525841d9f3e1093824b4372fbe738316a43342829b7b1e7374978610bba6d961b3ba4a74d5a504284693bc9d1ebb69854370d0b3a8771bc71dc02077982b8bb03338f600a3d2ebd98a57bf3d46ee7225c618f7ca9071c6a958740202610ea0282252df5d2c62a6651640c83fa8e37691165b359a786ec6858480678b62b8ab6f3431fe743cb023d9b1b8223acd86b169a164e2a62e3626b780cefe4a4088432df4a244be431ae422f1d586faa7bd221433e88866ce7aa7b42a71cb263301a120691d4b5ffcdfb6b8e3209762b3edff6286823aebc5451670792aaff5247b313378042c427aa37816efa2a06a0424f27254ac85ce13a04cc641403b8da44ae5ffabd82e7dcc195fc8ca23cb085482957119db777e14c787d28f82d83b243518e0dbe28ffa5eef745405e37b4973bb43c563124854b494ef58af000c2c182fd76f58a8743bd360478432d4b0ee97ce1c581aa660ff111e65f390cdee20420d8fa4d8d692076167e6b2ef772695fde4c3fd420b94ec04761bb129598ee707397da0518c054ce178a646ce0e9db289fc301f2b432acf1e1cc9ef5eb56448f598c72586fbf008c08e07fb047bb70de34e85f5dfa9706bdace478a0be5a82420becef94a4f1d94263de507bd21dac40648c4a681dbf628f8707d2d2c6dd401904ee01680ebe823304928cb0239193076fcb5efca1cdeb12fb1e109e8491e5207322adf4a044037f4a02818fe52abd813bb931c2509640afb1aa2cbbf218b08f98472092cf7fe0842444e10df19061e34523bfb51038ef29cf29ed18fac3f290d2f211e228a219e0ac384d3ee01cb628b6e210a684ec13b15ee16ff5c9e7c51e1d83657f30d74951381a2cf0f8e4bc458290ba4b340d7e659294937c05ab75c5ae3aa4a38f4a4a0fe0dd2497877a83702c83724a24de7152d459239ef472afe5ea9ef091b66012237412cca772d7b391d89aa8512c21ae54d3dd91f2bcb46691dd9d955ab171df60d861860137a5a5dfdd6fb4780b2ded6017d0b663bd29a4010cab8fd38eec114a37d01aff11406605486fb8ebd155f275015e2e3d893ad5220178f97addcfe06dad81826225888604530d0a16571cceb45635fb0c69f60ede6ff091074722a3d749cc99eaf08c522433b2a75c12532437de9053666968d66dbbfa4d54683e1635404e12b975997243d9012bf523ae51be174232da9065ed45c4886165434e87a136943bd4ccfb9c5e62aa2bb41ec270296fb4a2eb76f1091f79a2af8729b675caea7774babeef5a5b1dcbd7b88c31d83847edadc280a4e02942a1419c4f8511fff75e4ea13d3d40737ed88ba62cde622fab19725a98e018b5d51281eae636a7b547ea4941c26a8b7b5916fb648e274040c6ae13c35fdddd2f49874ddacda922a0ea56eaccaf1a2170c18847246c8feece050b4a1511da13d151f30e331880db300d0d58cef821c90d02df1e817e68b9bad148242f4e016169eedcf00ed03054e24275de95f013ff591ceafbc27a9beadda8c0f1adc4106a00e37b9f8c1d2334f097b9ef6602cfcb10f8c1347717a563c92f2ccc44654df86a0a25d84d364da7ec0d2008f677fdce7e454211244da0baedf597cd5a641a82bab1e959d71eee131a0b05682917d427db195b42fe63b504cd1fa98b8011218f17891852788d1763abc05c7980a2d88f1102a42db1d38804c9d72d7bf4f909c1ff1dd4cb3d2aa543927385e0c89624aaa6c6399ac10f597c568b01612dcc3a981d10989c4042141611b5fa3c7fa67b70b2e8e8016c41abe720ab3eef1ce57c2723de3a48133ab87f047f894f2cec8b5e4c5ad1d0dca54a8315f4e82f1f2d0d7c0c5f60f5c51ebd70bc013ff448b596848de3c2bbe96a42941b86466d643978dfc82667b19df25b491ac04907d66cb73498242f88c54871da6d1c592eb8b9d6d7b3f83276cc4df65ea541ce82d7b84cf2bd3e6a62a8631e3c9c48488183639399ff3e7a980ca4a0fa9f41b6ab69923725f33603a0d8bde144a4a5cd10b8ac21344be6d7045e58b680fa5fe684f3199361f5dec7ac2a331327f4fca6615ec591818d8a8af43a8c92436c72d8a884f11b9e414298e191192cfb6641ba2cf6f1a5f494e5207e14137e16e6d1f78a2c38e6d1cb44e36a214e0587323816448068b04e22538c1f68e712c42311904426712dc5c50e89908ca93707a60126b6e79cc09ece4992cab2288e226656ee3c83530971ea6196aab06bf41e4ba08ab1423559e22b009c4238335a44f64e6f68281d98762c296c8f5c0813904243140db2a3db11d191432cefd034dfd335ece71dde2303a9446d9339ac36e59e4a31af53722e19a8ea36dc0c34dee2912a276f1658ad823e42aab286e1273a11d804aaaa3c4be2dc36e8e5fc2378c64d1edd9f26d245bb1c0f7d9e3413eabdd20e0b171275eb208c94307a5320a9604b32af250a38ed1c1c7d103ab0051d1c0e781888440b77d1af5d99c32ae8ff3418677b3dc7ce24327f9a934f8c02843181090123229bf2c463f75bfba55dbad63689cba2df98a203017c8a03da1e8a6e5920da15a903d9abd27f458ea7769d7c31cc9d5666cf13012eb38c2e4c5d4817d6c9680af1660be02e4427ed4b600ce01cd600702076e890f040c95d081e7d3bf0c3b271a7f28ca15b4b4222a8027941dc6def2df79652a69402d206c606e40623d80c9ff1a2a4c1f519df2f6962824dedc334da87b3ff89c940c791b8153e3e05916bc120a89953cbb7a09e6680a26779fb32c0202da8a7960641508752097452ac766fa01f10380871b9efa47077e53d6fcd65480a19af7d3cf849c67becf96466762dd44df0c5869e665c0e5c79ef3ab9a28cf244ca64109d4376219bc005394a981692149200512e71fd59240d98013d246cf4b22ed64a47739f59f8f33ea3588b5d064856404f829dadc9f290460c262b7c6245d7d171978e8e8e8eebb8cee7222a78d286bbf58a80cd521bb2da9881804bfb47a24e6e57e089629ea8999aadc93387cc23e66a2a993ab3c8f567c9cc2559ab944f230a2b6a2f47d0abdbf990f1392f36a26f7911588410a719dff2334432b04922e1924abed8885a5ef4a3a9e049c97ae6e34d230adbaf434a6004bdba3db4a6bd4c617d786eeb5e0629e78712b0f839c958dd9ea823660be965c6b7bc10a7fa5dc04f31bc88f46223fad18fc09cd18b5e889337832451a4171b979ff12ea0444998ef67bccb8f482f3632fce8650047e0cbf72ee0cb07eee0a7183e0650aa402dbeaf3526634cac48592c2f56fba25d79d65c8245a14260ec86fe7850b7012d131b70bf1f31d109a0d440766a29419354e28f188f9458f16f0bed6f037de8d5953ab012a808c5668809569ca86e990c2543c9503294f6a22b64133551ddd665c4609c73b240f30769fae91af3266886283373ce39c70bf8a987840192127203c60f128689cd2143eee0c8144c4345e7a84cb3bd8c0178200b143b234d4088f18425cc9546bba7e3eaf63d5bf50dc8f340b16dd53d9de366b58a75cf0dc8f34031ae9331f2c701f246de0887e7755cdd34dab205700956b67a70fdb9d3a4681c5ce7182acc47f86ebbb7043e5066451ec23210827f304d739288fbd2f4da4cb60a010f9c59955158bf75369bcd4a386a6c6a7b3ee0669e3c7bc6672882952fbeb681de337366d4629dacaaaaca65bcc2ea936aa44875d59eca9acdcc524ad7bb58ba4206b7608204ec94f36385253b7dffa3a508d7a90ba7e0aa629a15d3f068095724565c7f1a46ac58955c7f8fe723c2ca97cbc31e3f1a94b0defb007def49972b7485ae303564479d02099575fd4d9508c35415c7f8fb083d28641a661a174161e57bccdc1dc182eefc5e76083de879f0fefbd16b94a88d22286c836255d2a2bf4d3925d80357afd65ac11e82a017879b99b99b6a929341d0db83f6cdddddac854421c0fecaea09b2bb3b6ba129d65b591eb6a42bc4a7461df1fe03736a4769d2885362eb0adc99a982179a68e11a4f7ceac0235e71a4492e61187f9974a9aaaabe5c66565555555555555555516aa393cd5062eceeeeeeeed6f89b58e107a8536c14628930c1211858d0dbcf612134b9623ce5fc5881bdd7e81c7c7f4e3188abf56f93f492c3143bf6583640840cecce2311f1ea71fa00baa28b2802907f38a658973bc198115eb8fee5e072ebd7e47ae86dec5b30476af1841e273be37802fdcafb57635f23d9db24d6a20848ee46e26b493d4a18d44702033b03c2bb01283361cc4c99b97182157bdcb6d0460947e720293839729c1c512c2547ac82a8e48e4c713299176b99ccca703c742c2cd3f8f4004e8f3aa43be372de6b37a42947ee69a0426a82650f6d3cacf2c2c94cb0672f9cf721ef43a00fd07f209f38506c1f4e0621c994370ab115e4389415e528479709e226ef1df40a446f973f0938b39d1ed6670f3be5212705ecc2b287b54acb98a60ad370d30939cae44892a3cf26784029bc4e89b1e29b92a6940c076d6a9694dfbd1ca24dede27ed324101c348c1ca261bc03454985acc17599c4f5e7da88ebae2a71a049204cb3bd8c42d6402661c428a1f0d6624c09639b9aa6699a8d871330409bb86bdc03304cb3b111b817390b1a5101e3c8710d23a76a46cf8a56b5f95a47032b8eae7f7f5add3628e69cf5980e12616549ca4d1bd5c0e66c369b513aa56bdba9b5568ed5e7176ddc7e1a2014d45bc11078c8347c2587ce128707d3c80bfad58e0ef49fa67d0fea3ad07fdd7b3c80fe034b2e60f0f1bdb7f2a1d7b4eaf2848f2336a15f791f1ece4bf7f7d2200f3cac84409046c312b603bd9f76d48034baf1e7750ffa1c30c7035d442f6cdb01345260020e6ffa060bbc600710217ba53886022c2b712dc9706432994c86c3712b51586245a68a8c47c8d76b072baca7dfe1322f9d16e395e08b7cbef385f8a10b560c7b8734596b297592cbf526055d602d8bc5816dd1c76d5bc48ae10da5290786f187b2e347cef9e3bd58dddddddddd1a7b5d8963dc9320b650ec77c55207c57a572c953a87a39690da154ba551693492a65269541a953a28d6eb4ab26989c545370fdac443c2748eaac48b0a2f287891058d2456641f70fc72a84f3f1de697c3b6b5ab3492168a5de176668b039bf5846b48eba458012feb3ad0c7f7476c3e90c197e9e3653e9f3a1a9858ffce8ea4cdc20633f3a862c16ed788d1bf09863bd6a5f88ffb78e83eac924fc9673e33b39dfea261fcfb5be7755ee7e7013257ecd8f6bd063e17ae30852f2440ab44f791b9a2ab1e7045dfe19058d9627948c308cb2c27e22a1f1f1f1f1f1ff7711f4a6d4891125aef689675234ddc7332c90bdd3a311cfaded8a0092638874ddff0da840a7ce246e65070a64acfbc9182cc27e8262716ab321addc4b46dfb949873f2e439e79c737a366a74873d86f4a9128bb2a3720c6c62e53fc7bc5eafd78e275c2e53b581654c8561fc64fa77b519b6b05f415ec781c03ae76c1b7c474cc704c3f7d0e50b567ee7c0ea70b95c2e970e4aeb1394520aaba1d2b44d6a018ef1f7c14d1501579ab6efda4198ca6d928d4d0678e81bfe1b49233961abc84710d989059886effb0e1ce3308e03d65ca06fd8d0bef1b0524d2bdda0d6ca951bd6b18e553b44126fc4f51ddf683d0449221c7e2ccb1c33478d7eece29a63099f1d2178bda28462b59b03e9a43ca5e372d2446b088b476584fbf9f9690ee4714c41946a744a3baf683d10685d292edab4c30b870215ae37ca9398be8567e1499c0aeb38a85e83ebaf5d61454fc16029580af6ad48b1e00fc8c30e8aedeed63fb27fec0f140bbaa2ad3d52a0fee43df7d607568914de37cc0391c026e714c7b1384f718caf9048adb8221e4ed95cf4aa6157a86c20e7ac54ba87e826ae607d0304a5e01c70e863150ce33f04ac75450f58a9fe7151e9d98fa760ab15acbbbb57a9558a4ba552a91df8467f123ce5291c351c637323831593b55ab162517660465e4f5a3c158562d91512984a07ba4e225defe2fa92eb9d27a58c59e9ee4ce34b347163b8ac8512ad4b3f20fa5623ddd717a7914bf295af6444f9bada532b5c7f2986bb46a3781595693a762cbc07bee21831d8e453ace46bc54dae285f2bf95ac9d7eab5922ff95ac917378bccd554ada68a065484693628388764b24295a039c6ef064a9ed56baa54413c0832e64260182f5e1edb9cc0e4ab5153c5327649596513922402c748270ee3bc85273df5b56af1fe0b710faa3e05c738e854348c7fa0e85c5c7f0f149b0572c370a0e85b340c2849c334283a0fdab7a002e63275c534dd73a01b218b24207f5fc95713962fa6e1a0742191c079b5d65a3f0f9c71988ee11bfd376a709027c31352c662b5645294c47660515cee84a65229562ae52c16d3905a002f4bbf45f9e4fab33c6c79d87ec475e2933e85c19a34119dd5800684218924830c2c2e1343abc2ca9f48b0288be52c96a649901315a534caf86476840f95580c0683c118c635d2d4fd5fea1fd9339773f68c695cab2995c23006a3c104eb75a100ae07be50d0f75ee841341861c546813c1fdc7befa37bd088abb31aefb9f701faee6342b0f48680e831ee4b9022bce7be08d0772fc4f51c071cc3c2728e7020112f35dd5f804f1df8e5d0af69df0d25d0c097991a5e72a0e2cbe6328515676ca0c252c043972aacc8aff9e9606f835270df2869b2a222b1a8158c4a4d0b6d947c73fb82f6b17b44b1941cb10aa2da49496696b254b2121c8114c0915c9f0234763e722b608f122c7dad6218e92cf447a91ab97188d82ad625aed1d5ae518ee338fae823a5212d1c368e23eb937294b526b19386173616a341c48aeca2410496b5d6da0edc073dfa4ec3a0513b49ac5fb1562c7058859dcee1afd1b7f01d18a094b8cb437f6f314d7771794a8c0a1c240a2bfe0522040926c6518bc562b1586cdb3e2ade88840ee69c7394b2f267a9d65a6b85511a6cdbc61bd76aed68c4b6246bb576349261e871746adbb66ddbf64d60bd84c3a07e7ad997b5f6e572d2398cd008b8b3c72f9670fd6b04b1628ffd55607b50cc61db8090638cb1c9a003db9f433f10728c31a64b5932bd2c2c10d26bb05d1c9345dff0b79e85f5cb333995ed970b4c59970b4c76066b2da53c76e0ece0d14ce03009ad262499210a2bfdc331eebed2beab2e97cbe572b96a0d39c6c56264345d78508494ac9e73cab64cf30dd1a6b053a206334918c169bf7de55eba7b0725a4d324edfad73f728cff04c230cc800d06d75f93c1047bfc306261457e694e58314442b550c21da3fc5ae7f49e98218e391acdf9df7279083db0e28ae17c71e4ee4d50a9ab80cbaf99948a85bd21f4c51c51ea9a0b344dd364386de29ee7f34fa93d3f0b81c9cbe7f423e485cf890bfb86bf0c0654775a9a0d8648c2ad9f6ea00d35e4b421e461406986366861e89a0c67db4036d05ad358638fc5ae7c2c76f43e3e432c7b48a5f4402bf60b5970a5863e10e775dad4b8bad53ac339f7858e8eead553c4e52d77e22bdf9931f7c9e33293089b5a8700d7df554ce357c63b274df64587d1a0c28aae13facb2eaacb50a699b22575244a0a6153cb078d04c380c050b6c9681e92249d837bef76fffcb5a3d572994f6b47abf59ab5c637411554bf1aad1608342b28b45102b9cb16bc6913d464f496d3371c023e30d23afdf07666a7ae93d137ea26b51a7434806fbce66888c6d1c98139559b54677c05418d3a3339335f135e33a3191d978e8e8e8e8e4e8dcc93f2ffebd7afd555841498b0a95500609af6de821558e50425d07859b15dcde3aa6258da4bbade76e530720414a0508da7feee9fbd916c38a6c64350b4a06c5718566cd503c18aed5251c0c3510f8ef177cd5c3eee72b98b028d637bed29f8737e3e33357da8cc586c4ad122d31fa4053327d1a3eaa9e5f9991f80aa27d18bdc1589fa7b5e791d4e830afb329faf769a3e3486478931c72933442d2d2f12b55811c9cef8185e943f35325e87c7a0b049fec8dbf2f2478c1faf63a377f99834b98c4a2ea492e85b5e9425ede98f07913f31d0ad21c00d3d2af46a446143ef695cb062c76231f9c3f2f67fa68c22653226757cfa0649362161a18fa7482c6154521cc6bf3562ad5432406fa9b10473c728188bc5c299b2ce82c5c62ed7eba78a131f1e1915d893e972b19cbd8df64cd65a0150afb02f3bf8a9e7edd7130b4a62e9e778ffe4e9974b1cf5cbc562695f353027477bef2b98537fe33ee783e11f0eccd940ff32419b8fbe8fe7fec5c67b1f9587dcbe971db4dfde4603e76bcf270ada54f0067c9960cd69eeb4abd52c579425ede258bb38d62e8eb58b631c6b17c75c1c3332d359348c7f17302e9a6ce18a6d00ca288cd194d18d6bb2d060cea94d6dd643f6e8a17953aea1693dfc9b2013baa78734795f396f7605fb89c350c07b7c13ecd8f53138c6ff658c9bf3a20f35c6e8e798264c2ae8f9cb53430d38703ccf66cfdc0d4f9a617e369bcdb6ad34da18a8b657cfd66a6d206f03792330ece5d3886f9de252ba09d7bf91f413b197741324987a4818d8900b6040032c532a75c9927a48538d8419d239980e81d5004b804bd3488ee6aa860a27c45aadd3adadd699d010b899678ca5bcb8675afbb57e53fa4cf3b9e8c0b287b7bf1b660d13895aad9da174d5755dd76a750e6460f7ce816a6534912c79691ed8ad195d8189bb89d40b266559135a2a9f222b554b65237beac669df01fe0007543d5a35fba902a98fc044e0d0f6105d9715d184b1a5ea3a15f75dabd59ab1999921f96db53c2fb451c251637313c4689b9b3948376b5ead6fc009c3d22bfe126c0f4bb84c831081dc9e2bcfea8bec73e3a107403058917d4413338f1e48600296916f5d70fdf3e1d90d0d7a3ac56efe36ee15146be07a6afd826cdbb681402216bb12fa40228fa5b3dc4a0d7d54d3346ddbb66d037d9625b4c20256cbad84be0ee46d9bd771356439c161ccb0d878c4939e9f202d6b2923d1ed92d87abb24768eba2476e4a387fe4305c463c58685ba4ad7c934130e5552878763b8ea412a18561c09c089ed7fd1a18ddcee1b49c10a366c94a6aebed8bc67bab9f4a582363f9a1246aca3c1081721d896151b562a51d8f852c31246f6c460ad82e5400a969955b0a947bb8ab83d706db3cd25af381a81110557e708a5a9abe09a15a18511d63ec2465bedd980c49088f580cd601b0c06b37198a60283e1a8117501d3509a864ab57886b08e5829d1d15028ed09b11a56a56106564a6dc60cd804d130c47ad81c48c52e20d4a4848dda3698f7844c715c5754adda0c2ce781225c6f2de8a80247e17ec181a4d62899ca63e9152b2af460b3fe8b1ce143e4ec2ae75447b35c34daf6038b6528160ac51282041344505c2c168bc5623729ce2d9526a289182580c39134351305d0a1936f7eaac05f7d05418d3a23e76c1a680bd8cb07f0e33e5ec563b399599624ab540a435913aad4101c1e33b8420aa8d38f298428a7232f3a740fae33abd5dad1c86b50bba669db65e7256150723d8c22bae8557cbabb3f3d42830e9bf564fb555f355eff9476b7bf49e7eb8ad7742758b00e7b85a26f996911bd7cc5341bd3d02b7a57182d87c2f22e5e1c9fba24f67b1dee45bcfe1436318df73c3b5e8d5c77306c42dff22ca496b724d13749868ccf01fd8c0fbd88b4f220d207e67c2ffa1cd0b71cb111bd8cf7d102ce781f22d0876d7087d0b7fc4de85bc09c2336325ef4392c3f03bc59791198635f460b89e54524fb73b290f83449dd8b3caea8bd0fa3db4998d10d1de83f1c159702865771186fc2add611fd0ae23e6da45ff7670ac3f8bbcecfebe7355ffef297bf5e2f4a619dbb38d15ad358e3e6315f5b2101d1b70438b4461a898063fc7de0186718ff2a5be0c1857dd19e6f09da6df01d2e235fbb3c62d7885d231d34287169db569dd8b68d37d6d1d9b0e083c372c79126eebad23182c5e101019a3044804d38339d23878930298e157c28ce26936dda56ab27f3dcc7758a389594942e9b996bb52ad5ab54b2566bb5eb54ba4a9afce42ad548baaa8e8690a1320abfbeccff022e13c40557ecd4a80512d515bb894de4281ca5e7f3930d1031ab0047b9f3c9ede7516b10ef4917061e848007490bd5e3aeb7bbcc640b516eb77f9352cd063318e18b91e3d8fac6711cc78dd2b46975d3ea07e27134053b63c269391648b6eeebcc04b94edb368eab756686eb487cbbd5753536375cf0388ee338862c47ecfc9186a156ad473dd28bd78139317401060f4e393fbe24a723f47ff40f923875dfbdf47b1ffa482ffd20b05bd50097ca94202b021359ebf3beeb041d232684cc9692d075d09282f3465b5f0c2bc060b7baeb5958b1a90ed977a3608f1d845220429060626cb55aad568be588bd92e79c94523ac1be9225537a75b80f0971ccd1684ed115ec775166bb5361a43f2158ff2aa511b3d9b8da09a2d2318262aac39fd020866d596c8918aa7e384cb1f28a55d37a36c36d7626ae5b212e45d899f67db9569487de1c116c8361d858adf2ab42c7cc35a3b3d96c369b699a3785d6fec31a0fd8a8e1ea2971bfe64282b1251afe5326d8fffbb55afbbf6d4e34959479aa092925ca9c5276777f1886f839e5fc98a1c4ec14fa1f9c173af6a52c0c36f528933e4c334720a314639453aeff94b210cf9c734e1114566c253bdf0e7d0abd46aa170c825ed10442dceebdf73ee47954649f293b1db8a78f4347677f3754903ddc260f13366945c85432954c25234919c704e118bf230f1ddcb1752453c9502e336532994ccaa48c521baa101566e6f97acd58c591a639271039ba48008462a76d28dc0588331ab94cd7754d0242ad10002c7c0d52781d417bdaae57932d3a47659acd077c75bb374fdfa82feff55ce7813ccff32a28b4d1d203d555c0652db450e57a2b9452daff9765e877f7d73c48e2ce27acbf46a2b4524d2b694a24a574d229c7719423cb15e5a85d51b21cb1e28f9e102bf68b254b96a2ab821b720c33b934338a5b02bfe24b77d0093b8ee3467f0325d0af51272f0d3e3703db301211ecf793d2eec8d6db4637ca1a1de0824eeeb4bb9bfea6c3f348d20abbc35d94d00ed4d11be86803450f78a0f73c1f40d77b1d1e690711ebbdc82e1bc01d38a858fade83409482a8b7c47a339ebd1e0741c3191b58fa6209071c331dd75f6d14b62389f5fa50e36a4fa5699e4a330c050c0683c16a361b25263caec1cd5c7b7e9cf8548945a9d5ebea0652a954dae488a86cf7ebadf5946cd2d4e329b1f28acf63b52bfef5ba4f88edeaa655971efbc2bd1097a3a105db2abe53f5e2513529b26a7d31b0948617581f47fa7d74efbd8f9707da8040ae46ecd82caa28d2b19b580f7f504f471949f97e19f1d281deca75001af66262d943ee786c93b4ef6feb1cfcc8a5dfa3722c2d4a6538ac97794a29a5da87615d00b022c452f0653e0b71bbd520cf65b48edb36baa2a0495ff30f87bebda2a4ed7a3f60130e2887f7aec97432dcff0c21081d8676fbab8f53a7a0a26f386b27d55af56a4541d106e0a35960c20bb60409cfc85a511e826046ca04a081384cacd8abd65e003f92c1b2700e467abb4e8ef19c458939e7a4829d1e7ee1c4b6cdd9715b2761484ab05c00f017b06d9536cbb65adb9b42a552ad60fec4c8ab88ab87a544a51a8d46230e65a92459a552188e46fc725273c3329834f95879d0b6f9b0ef3912b7c2bef73cac3c2805969910197299896aa70897993c3185eb29573292a61a2961ae699ad63f05abc4271a66e02a8e718d44a43ead907a95d349f002aa75fa315b4a749195ab52aaed4557a9422f690a7244abbff2dbb63dfd2ca001b9f31bec41fbf99ed7a058128d443fdfba4cd7812f3bd8173d0f2bcf028a56de87e86d079244dc8f6ef7deacd665e66b2ba4976949deaf3c0fa067017dd807fd0ae8c3c7ca7bcf27fe74a0afad9034ed7b04a3db81228fcb813e8c6ec3be9df4388ccb4d6e727b52c3c3fb95d0adedf3335bad34a67195f3381157f5ca55bd72550d35e0c06163a55ab9cb086aa55aa95e2a954ae594da50712e0315b8d979641e7329fef21ead824fac8fcbd09722f4a28c22633b5ab7c33457700ea984964e4bc75b5d41d933f668d1df0183892540d6006d8709f4df7b9236f5f03a4792040ad71fe481a27331db62e65968ee45928a846936ff828b2d3c0b6fe9788b894ec78a2988709cb7bcd571a18d128e9f6f8ac7de0aa594524a295da976f480d087422f0ac0d42d8771d7102e9f28a5945a92e85948f657487d0a919eb8fe4e5c06f837164d84437f569f4224543d8942274bb2608e039c70c13aadbc10276f85c4e30709b342e2615f447a11813f802ffd166c70073f853e04f62861502e43b94c119c63fa4801430ade5728740ea6f95e7419cf2079ac7c917d388ee338707379a8846392f40d241cd3e2987602dff07f3510f8868bdd9a7139c61b089b7634bfa783d7921a74d139ba7796b72f826edf986003692101a2eba8648eb87456b2110100000001131500001808060583e190583c2e9c27d51e14000c61804084643c1a09a4410cc350c820638c610600620000000c0c91a8005bc4b75540a5a7c72b1deac50145f8dc4928dd364c074088a269ee6dfe486a1253dfae4a91eb83683c7be2abe30ad51f973c7c268c732e8ff712c14d2b6159b51439e66fbb7210af987b982a00826bcbf7e28eb27efa429df022e047c4271939921063dd42feddf0f2719645a76fc4a962a073a7af70baa8efb54d55a27d93719c641f8c33029f90d5e58d35719c62d7755351f582d2e269d3d628a6a751ed31a34f8240329c070e9648c5802a045db863d9cf40445b0c278df7d0fdf26edd62eb90caf0a8a0a1d69d84882dfb62ffad8faa54d3307de15dd3a4cade71fc11a4c9fe03c21e02fac399b2997cc8a7581f30db8a441934184df0eba87bfd4c734b0a3500e2cabe6d7e2587073cea4c712c021a900e439abe8a36df876321bd5e1dd189f53fdb99d07b13dd5be66c12e3107a6e1fb13d2e9aaaa80a707b64848797408927c17d4278565c732853861a9b5652083c50acb269abb8d77f5325231858e3bc3604e0cc020993c41205628091b626e07eb718fa43c37cb4e2d484f935d82269a29d0c2698a6213032ec325c24380ceeee5160a8f8307a02a297966fc2f63df573a80452eec54da143bfcdeeaee51ec6f06c1c04c9b27c675ce3ce96b1300961209fab8aae6c6968d96a2ef24ed067633fb5349caf52c366b82f5361003c7d5dc4f209b46aec54ceae2bc361ea71d77f6779559c9b30548c205520b84d0c6c00b953d273ccface5a88ff49f5320dc4cf82f7e966b2d97d82ea59e90de3eb2284f69e12fd4aa8b8f3b63a290a242f139a2bb71e7fdaa2dde223820750fbce770f88ce7ffa4963bbdccd1923811cb1a3310872841489428b57cd37e8bca7095840ec583dc08bcfe2a9259390a06bf59c1972f6db1ef75c123888d24db519f82c9223ec9311750ca9039825b68a01cd4888bd54a844d70eb0c32e7366dc4dc32fa794fe4ffcb78259a2e16d2c1397a38ba90c9bf56a2f4060c24048bfb2304d1612f8b233594f77fc494f62a29c14623721828a1e4b5264090272e3efb2145450631bba11192cc5da390cab66c8041590d50a9bb19390378271977000321aa13ec11b9c6b5ef849f56990610c2891094cc57ed207da0b58ff2630cd3030a2343b72fbaf7863d5c02ef0fcce269c574fb398d5f37922212a71037e680942eaeabafaca5f8d22e00672ccf690b3efb177ede1c8e0241ea5f6cce84181921802f9e88ac7db43133771e6ffe87c5078b9880fab08ef7f586d6c305f763c9753bdc537bc200d22a1b3552a06463d1c1ecbc7b1418fef7470020eca9b44e47dd34f56179f4d3979cfc99ae87c3d50a586b4e45b9f38162737f84268c7f031aeef6deac37571ab87ffec269b6622c4b8ebe1bd9bcca9ecfc587f01d74ae4205fa715b832ff7a18ccd52caa79ffe0bf8ba31fa94da79c386099d32273c4b492d095d0dfad08c5dda8ec265996925e12f3dc56165fde30179e24c75ebb34ad4d869ea5e7d04d122e6278686dd34d01192f098e5f11178f25da24ebc534943b0c54da911116a0225c41a7bc2b1ddc80969369c512d042a0983f92fc084a8ba29eeb386d4fb08afa396330a5009b14ab80775aea993744276dcfe0824b6c90a3c105ed2385304f95525c3c7316f5e508b3e4d48265a737cc2b2427e2d809572cf6190871215ddb9b526e68599f27ca8c7e9acf43f30f9180aee798c64a33295cd17b24a643b62ea6ae59d78f71369b67de7a77c0fe88eeba008439a19e32ef7b88b2095c2187ed8a5bba01de81222a89bf6167a78184d1e358988615b41bf88485c56ab78871c2f25a76443eb9efef0bcbaf66041011f07b8b71797d5d82c0d326c4edb90a633f4dae21cfe522bce3b749ae2a19ea31fe08ea8cce9ca9d4c17157ee00b22931e61f68d277b4ef9a623f4cd7ec43c2958fa53a43b50fd4a3fc47bfe7a05a39e5be281b6f58110248ac2606f7c1e7848cb2b5a0e3ed9875d048c9e8e69af173ea71ff6910b7d4dcf9fadbf1661c5db3115cb9cb1aed85079706255abdc40c69d0d2810a2a1ab821f4dc5d2a141f3c4a74ffb7dc1fa3337a8e53db2777235f1bd902d7165f482f30ef08313bc4d8e827f8abf1df92fb57482ad4f85ccb67ff6254990853988f8e34c1ff7c7c2cc1a8553ceb6f714dced694df8c12b789fc51c671a3d56e358cc4ed05c3c08be80b4322d7fbb964c450acd41f24390420649b61876ca9e84b4dae0b44ec88662bcbd6627f1f9cb43fb4406e7a4231e6686635002426c5c5cbdc10157e2e0d03896c2b2a85d91c7ea3a2388270c6de417c82f0296b6ee7ad0a33c5175fe4bcf5c0488d85c42924c9f66caaa4b7cb5c3c486ce6c1e4f736f27c42c10810ea7e52b86ca09826317c1f4e791ffa7f970d753bde5b1d8890e2110aae3e960ae47bb62b05c7dce68304d4478e444d0b0021a16dc5c09e560d108b55f9a83fe4ca4263c25bfd1ba7a8cac88314099149e8b8a3302525ad21e6e171c4857023c0d22425e956613687fb84caf0e1085f04a5dcebd05aa14149bc9000f40ae7d0a979eac196b3ea77cc1e900472d196d9dc10322a43a4b63824b1a73cfcef9544ad41a9f541500cdd601ccdcb55239616fe2cf20805af10064c9a2c103eab785fb5afcaa0288287402fb8881a11ce68d4acd689fc170f0dd4df4605deb214bf82b78db0c5dab8a95077a0c43e074b61820de2d5b9a3d319331124705fb27d4dcb192e0403cc241667f512595d84bd36f1fffa60f0455f9ac022e3402552c38da214794ab8f1f925952569403a2769c7dcc4290de6d76a71702b2d5b8c26662793abadf79337f21efd7293cb1d57f27c43e1643278f7014493a6eadebec9eadca9c8c8337e69fa88b81601253b10fad222b24f717d93155181b51cca11ba3a945fb686b5e81fd95feb5aae1d18036c9d58c781f997df3afd81d4c32b8fd02498cbaaf172d0ee81b76bd4d4e8d6f2edfdabf747de81b5f0a0ee42841b7f50dd2e6ca5f682e69211372f3bd5ed3101ad0c3415cf89f4fa0b43f7049528721df18c30e6bee31e41b7dbd12ab574ed3128f7bf85a1e0603cc1611690fa946e93cd34c0464626e8f1875a506b2264317cb3a1d54fbadbd5b0b2117bb166dacf872c6f910da40765a58474ec680cd3a095990db68c06cce2be4490b31c7c2e5c63a1a61a95f9a026ffed3669fd2ff1cd5b14cd2c97b97c05d12208576bbb3aaab596342dd5653ba3892f73943305d99ed76676ab49765defd56c6444a20d36059d73a3467917a7462baaf8c7f5864bcc84a436553d58061691eb013920b0ff338f4af469f67cd8fc77dc77b15a3cc7abf038185113104ba82059b8b47076ee02b7c3a8a02af80e0917107c765d0a9a602cb280d28b8a1f1e37e678b1d6d1dffd1347b2433322eb500ac5c669a3f595cefd6e21c7fb2cec274ae8e60854636543912d940011857b03cb3c9e40071656d41a7ffa2b2c27ba5e45e73e406acb1722fd0611a45d56117ab5793c0b41d7b8e0cf58a768ba160db3ae9670ad342aac065a4e48b12a8648c3b2b0c52498e3aeff2091cb30f630f9f360f533113f92ddc8d77f4c7184a3950b9960661865dc046af7fd502e451a2c1ef5d02ee69f95a2810789004dd525e386936d41afd48aefc038aad78adb8fd03b3b28580a296c543deb10f79af3a1cb06670df1cd083434d9e1baaa7105aa1b1d3c737064b21ba962fbdea89fbb4af8d4d1ca8045700b6411cda7b616d1b7a5269eea20001de27a1d306c87eeef553e34df3cd071d078ea81ef12f9b34ada1905a9bef9e589e60554abb265bb1315d20c238760207929536f6e2ba2769cba4c786d75f9f3475e1b14ea60bb0ff131d7599c205b8dbfd92acb7325ccc4b069d0563f30ab50c54812c66f0a7b0eb7555c3105677d10c2d6fa795b06c9a2b6e73c23be86dbb3ba01fa702162eaeb905cba71a18041a138899b7efff68b82245aa071c00a3f2af2cf5a4f01fafb2a3b6ae0202394cf177e37d1c739a6998d2d3ec9e60706782ff3ff22d4de1f2133e0b22c6c04eb6085217a07002426f234f7207ca3bb5afcb0cfd66c61c8770aa7ccc0608c53c43e753cb300cbe0d3a1c2319b96fb9c510afea4040e9285c320bab877d9d0af1580c3498e6a16fb58566dbe542cd0fa7d945d8194518520194d2f26278ba18b76b31a4a74088c9c3c35060c85d9007a4707b6ee0bed053c580d2efcf5911213e2300b0b510058f2d040c9ddc2ce13f8e26063b40f862245ad3920a320fa5012ae625435b878fe65e367265e5e35bee89b3f612ba3fa1465a463c141c99e6da0250c96a9c2ff6ea8871bcdb4ae49448a0f033d9ed696bf24981cf9efe568edfda34912c0e3ffa3df8fffda3b699910c4d5c183d98d05bd8129e1f3d1e0fe7fc0d5c813375dcd1b51e0f4f8ef2ce5234a35051cc4c0c93ee922e7645c121ac28e2c7728129633860f383211aeb1c8311f3b9633dc0e506ec87ab243dc6acc4f05ed9f2da9423f54791deb92ee12e698f3857b4b0f7afb5e33307655cee87cf1c5757db9c25cce8c40aa0a45331790844606dc4d40a696465c4bf79c7d10dcab3f7b8425cf62826480cf5e108686b6f85d1f626e12a8107026d1d48d56b2407b22b34d4807efe83e83782bc1468dd24ca44f1aaa2856140929b19a24885d06161de4802df2f01c2f932fe726068cbf3dad0baf78b193bd59c0923acc2590b53ae4f915fc0a22d3657d085139dd3d52c45feb687c9a03392cf530bf92095889bc942763396398baf7a754b0e2539a16db4cc63adcf983900d2f5cf077192ea85ce7c3f94b202f32648055b102a69b500501ba4cf025ba411714cfe7fda756d812543b31f7920efd20968bc0911faa7c23a24ad8ee628eeee220337093e246d31362a87d746bdadba15ea2625f769d93753775056fa3cbdd5bc36b1d4198e8984b67a31d8727720d3f1351916ec303c58efe0a0e0bf235296b3c8fda15d69f8270263d26de3ce55556cb61a3c2829c4241695c6874c0e6700334c567df1a25fd379579364e3d563ce9375ea227f13f027e6332152580f80a6dcdce6bc34e17331ad311e9d76f43a1dd64e1bf8402b6066e5f9bc2ff61cc4e27e1469e01f9c3cba70112ee9a4fbaf73a47445e9913963d3c6846c16d3307af07dfb56d9d416324d3e933bc4644b67a61d4a1e4e9dc3d66a002207672bc3b66b8cdcb0e09af3d3b97ca754019f934b61541cbe73d7c109f3f9535cb97a5f75d5c086fc2b4ea0cbcea4bd2284b609d4a5718201e069000ddcec080ca97f8f7fee1dbd005cc8527250d8a4bc1179ac1d74aac425093c162aff0f22605059b7994783f3232f4dd96c5bb1fb3fd522d2da87bc2a28d94e5ae2ddb2a6c6004f2a51dd7c0c3e79640de48147ef7a0f70c3272916d86e3939c8d83e88328bd11127d56b487089a977093b4e2b676cad27f44dc3f4d28139a4d6d81f5a91342974a1ae1b8634396d64c634708e28e48d39df050ec23d228cdb2d45ba753eae3f81b3282838d9c1ebea26a5d07deaf56f2fdef6d014b4d7621d7c2797c1532378df8d1815ef922536e52b1305979a9a64bd3544a486f45c39afe07a8d4201407dc16d2407cc31b247babe960952c56986ee75c5c1ba142facd46615372e9e88a360f0165fbe01e8ea572300c86cbf3e8fd1499d999163cd8f620e21433a520b80fd80e1557214b7a644f09f897091a362adaba63c5071896bebd27e1c9268f425239540699e6807a2c23136c082aafc4c29502628f4bfdf396e852a62522538c0780d812d3fcff8991528c5ecc10800607df981879205463d8e9e2bcd776c3db3ea0bbfae2b431f324fa3d1636b51e554f219273ece699f8f8088bd9757390e4dcf481fd97414486aecc9ced42c6db6c2d68303366e8d51194e7c443f5a8d62783c4b7b21db259b9b52b777db591cca8e2bab424ef7abea063244517d78ac424b1466e8cabacdae2d665388a6f811e69abd342e1e9c55516ffb7cc5924670db1c26c9932a7316a88a4b515fd8e2ffbc378d2465811f892c80d743e5c6206b1c0c5b6cc23f0bc020d695d64582781fec69c308f352e89d3fc132cf19f0951766d7875d656172dfded480a15532c3c5c741836c39f99ab258fc55774a35042a3dc04b5c1d89fda1f0da289f1296ed453795248dd9542bb27281048bcd6aa8f192f41bb39c9ed3fcfcb65a3c28b4f09ea79940efb07de19203573248c986c7746c95a1574a9eec60078c0f6dbe5a4b7611390671d38d5f3181facbe02a09e7a3f2bf1c276aa60be6d1fba3124c272ca8c67701db7168dfe3f3f5f7faca407b43cfdca7d442b390eb595404e51726c8733da3fe70154f7a671bfa23d03c286b8aba37efb31977c4d3a4d6405463e2b504a896cfd76ba0f754f3e801bfe5a18633422fd50ba93c24302eda7f820584210c54ee037d37db88b24cc733511d1711e5530b02101f3fe70cc297d1f2977103e3cc33f7f50c7b830bfd2e485d5645ef17fa1e98d5dd430a7c3fcab0f546238c6c6003c2c48af161ceab17973e96f58e256782d8deee55172021c039455d71af78f6f4a9b93e73d8e665b94e993710bb710854c20aebdd021e6964d1909a875df30fc3755fa9b61e29443157998c09c1fa8546cf1202d8c01520d3e9a63a1c538de76203d87ad2f673fe4d0ad34d90d04fe7d4ccb14759e339d1e886cbe9c59c05f73c478dc5d6d05d822fd26e9b137b42a97756507811d77b89daebf9b18e7c6bcf0e0f08e1c4152bbe7860af7515db364fc86436f315ec87215318ad64aa9751d0ed9286bb5a9f1ba25b42cfdc8d62a58655d82f200e27269f6a43c8eed9a7483e24ab1c62b45ca509e9cb0b0f84819cd8c7556ed2b8ec83faaac3949d56c3a2a197c9f53970f2c6c37af0272c8839b2017316b4d38ace2151e9f3f47893dee1c6d61c31d24449c1bbe9a5d667f0f70ac9159b9171bf2e221524b470c24ea40bc16341e0fc172b6d3172488ff911e9b5875a0b2626029b8419d76aca1031f60e323054b5eb0e0c350642731f88030ad1faf64a6a4076f1f40e9ced772881da70437f16168fa5c3fe4c36cb3245a04e56b0d195c6b8760308052cf8931f62fe34ff28210bb876abad9210731bcb1e40f6e126a82ef504461f14788de7870662695b53b2b0f75b58e7c20f6ffdc1fe66e78fcbf6390f5c76d10b89b7fff00d43cc1e0ca9167c82522cb7a5e1c3b0b052235d5e96fc6c87f58310fd0873bd2e551b8a5e198cb2a27600f5057b94a474fda69a6dd8f10837b6ba578f561e94f135aa25d0b508a58bf7afd30cfdbdfa5544192f6c7adc0055db1bbc95499e227fd40b1ce63c443fa438ea2b72d7ba454c6f6120de5f48a79049f4a4426c5253981a4e0d382a4a965d3d0fb769ef5a5d6d3d6bdd28577a3499ae518c3f3dcfafb4ae3b2011dfda41d042bdc10b643f1b231d11659e6d8cc8ac395bcd948932e81da32772c416ad932f0db8c4ee1aec87cb988c880a31167c56777e7851648a451d7690089a01ae253995c2511792f4adf9ed67b40e60bc179c7b8f2bd51afc0c80f7631628cd6a126fa6c5d1c66d568db8d32f7f6e39da066f5c62b9c49389d1c9ce6a70c6a41293dafeb7d726cf24bf0d9240b0231d628690802d50238fb5d01a1958150c601a9821fcce1c9aa2593fc3f5ec53ec007c1cf1c7bf2fee13bf71a34e04a4ded34dee000cdcc9f7b51166e4a9a640c97ebd2d4b287525fc226a5e1959851825639227f7948b6e1cf3cdbea9398373f86c8cae16429426c462331cbbef3a338a57375479af28b6078e1aea62909b4dc30fc2bbc50843dec6f7f28942283bce03c0ea1e7992ee34982e713d0c6b11ffd5e5ca23296f27e97ad7714c8fa414dd3bae9c205fab2d077e6349da1e40f620ac725f145565b231df862fc9405c58b2d507a2b699935287b860ec7da0150b3bb93092925c232729ccc1251a0737b6a272b82a21a65cdee1f15974490e8eb826a6a9b57f0940895824659a0fd44fe73be6101b7ca86aa235dd3984a65b72cdb6d801499f1f4e14fbeb22827f4eaaa5327e2af6d472faf5ebd9c9d672d221c251d89fe619951cded6cec9788680e5ea9b617f5e667670adc80ebc230f4bb9b1aa1e26a73fa787c3699b244dffc88053cae09c51622d0954d96ca725a7f1f196d7e7c5af4da93afb134c6336dc4d471fe287701d580986d5e2f9e7ab6413380dba9aaa6b469e4f86bc82affec94353ef1344244873851ef8ff96aa537a6cda05c3f9dc0faadd387c0dfe1c07fc775a0f32dde5c4bdbec0c6e454a172de29f596ca138aa27f77549b24a193707289be392fb54524394f158abfccbf0920ae379963689ef1a3819932ece9c585de74d697bf0b5757cce238c27f5aa7c015500fc27b751339eac4655158f8029a87ee2dd524fb7cf48371d437d7507a664e835ea064c0183bf90ed0d504f11952aeb149d4405f6bb08594b491c4b891adc52251c800a6631b2f458bd3e2fffb06ad5b7ab5739deeaf65f9ca59d8fe8a1d5ce5c62a378036d148ccea23351231951cbb37e52f153997274782f33a1bff0120698706e508348484cd6ade31e378ee644040cf4b1e94a062cd992696a782938ac494395e597356e521cdee2aefe7b2915e2168411d38dd3ac38c72f4aec8651b5faa50c5d0ea5417b75fc5a042a38c5b3306c7ca817f50fadf12602d0cc1b904e747fe73ee15ca4f31d0ab20911ee0fbd66c972844050aadb1ed586fb23b6beeaeb80353f31dbe00c9f654189568ab15beb542b692d4c60d17a8c01b1a4df9440e41abcd118d3c27b627b78192eb976effc09f3f911fd4d55c4e0296fdd250d4dde80ded3991d61704414efc5de9a403852b6c4c42c6f015c8e75a6fdf09bc45070e70d189d42eda5b20aa431a3dd036e894e60523c20091c0696aa367fde0fe6e8011381c49b84a0a050c3c200f997b00248f1ee8dbb7c26d7c0a0928128f3aa103d40d548bb5bddd4b873a1a799e942d4e4d4fe9080804574149f75ec757915984aa798b75522da221fff0e37269123ced35d12b78ca6782db74e630458df7f4942fa7b910ebacb38ab4f45b572cb43322d9305d409c737b6929d0cd6fc84469134c3f432dc1f420e092a2b1e613a948f502a5165f781d7cb447d97c82a9ef0a94e57d827e051ead65655265a167b8eb4ba198fa2372913af11f12b88db454dee48893c4be33b40347ad01a57e2b2345dd483e1871a34e6c57d36af4b4dd15651891bfb71450902334c1fcf33e97c749e07cde87cd8adfe233f02b5ca7cf9746660fce1b5c0f09653979fec34b3bdbb86e56df7663cceb82c65b75bc31233df99d32ab520f4ac9154a587ea42f7fadc824479061fc095476e384c73722962c88c394968af26b1189abf3724bc4bfa296f4245741f68ecb71ec5325171fcaf44cb1fff56ba063234ad465741a2a11e6e5ea1818898bdb7d37517f6f16da61623641a4e26bd1d5588ab6a9c6129d5ca3a4259b943d295427dfa0b9baf551f6a42618c906118511675b49378daedf12abd77de1975a091e6a8ce98a170a3205b749710175d879859b457ec988bd89f2100eed0a9c02e95a0ce7bea68d5a18dc223b08d0fcbdc4eea3438e9cb310f72464992be3f5fd45ec6b3cbcc3a282cb0455f91d6e350169ea9045aae6e0b8c5dc190511845507f105caecd0092e6430c512dcdad69d622a6af8373511dc027a65af7e8f3d3f52f6ed97416f8717938837aad82dc000b797f739bdbfefc1e0c740a49b2e53df5339af86aba1bf116d34094ee24db37a0cb16eb06f6edbd451c7a5122d1688702a56c18352d5ea017838d9e8df9f33d8e51e9c80e7cd84253991de7f31b5990e44c210199b5066ec89b61d12af912333a253f76615b7eb899b29c8df7b591740f7c9162b20038a6342796fe99a66ec397519e602f352dad809548bb3a70403101c069c3cce76b40a202af446ef9145de16e0d33c646e9e36258f9a4ffdde85c3155603e59c6a07296a3b93e0003e552f96a6734f6e42742cf55cc1d425ca2de539ec2c4c9c7e123a77e40791534e0697e3d4482716dbb5963a051ee7e6e381d443ef62e132092387350e3cff79c22e028cd4dbd70b150cceaa2cf7449caa20c679576d15135eb22bed8a36f893c6c1848d96b89fada8850c29640b639fe6368975bfcf863c5d27b59422b181ab0ac18e04c57a1bdb2a98a9653d16f6e651853137c7a1b546088cf06530e1f0e17c0fa75bcb8f2f4ab6c29fc3dd81e5dea0a4492573e6c0a29f8c090ee7cb10eee41c28c7f79dfac954d95b8e7ba9302d7fa57f2698b0a6c496c77b483767e423778200c2fbb5615ea53b751e20daaf9964bd37bc787f61374cc20dd36482840401de24097d9610e2cebc2273eb99c866134a25ad804b24152d751a8596914c2c01c5dd76bd388121d2171205614445f8166625ff79ed11b425bb4f50de399f3fbc3011c78da96439c0a85db5ead0dbc568fad5763c127c3be6b2a8c2f0ca463acb8969fe8480f289acac064b8ce5c024abe6abe476391f258a051486d35ca14ed4988a94ad0285dfb60772d62a2611a811fd30002cc86a296752d1dbb7bb4c6a88cdd9a5c90e99d02d6cbfc97c64dbcba749028e38fa7fc33030f7f6e21ae7e680600cf4b2a765fcc4b740ab6229776e1561eaf196adb281bedc3f8d10efd1df336468af4f04438d94987b88993cbdf7f143143dc6636a7efdcc838e65213a1dd11adaaa4fe2810ea161a1d2cc154c3c5c28d8898a7b8b70344edcb82ba762bc9c8b35cde31d785c59a2122860b117b3078339018d3c176b6f07c8a5b2b41fbda86c63a48f74cafc3d0d99819debd46a724e17656abfb21d20355cd0572a5f85612ec6f2b58486c5ba80811a90b9c69ccc90cd754844a53e49a3f507ccd51bd2d8952de78ca474df3543913422312024012c670e880450cb97a18033a464d5356d57d2f51f2bfcda01e5368d8db7c89916c773d4341f75c51a447d420089b5e6d23bd5eff3f439e7471418c0d8b68deedaded2d4ba2dda0d0c995856196d7766ac0a1473f5cfd9ef411ae7ddffe3fb2e76633c5d17d9eef36a420a236e6ab7159dc573b5156b91d4ac6687978703fe02861ab9b808f7aac5c5bbdb137e334e4a046f370c4ff51088ace0bac5c232a250bdd29ac26e8d7db9fa65f93a12203996726986cd1c0a1458aa42b16e43ac1321a4a31a3964e5e0486aace2bdf936f2bda43402b080b083eb1200b0894a64820c37b312138815e59abd319d121456276f22973290f406c61c489fa920d75dc084cfd5c1aaf7660f238f0329f8132369431b5e48eb67c612a3e336cec069afd52994048045ac69c7065c410d6278171e99e096a04e2bd23213532b970656c5a06b75906b73b52f51c277d5d63e70c7a2e8ecaf58c89ddaeaad68e40855ddf76e04d3f1edbc88e4093d84b3cd0fe67e88b983fe444bbcd88ccef64c2930e1b7aaa5be2cc90122816d0cbf48f0fae630ff71d621fda69d62042e006ad96a3bbd0588a19e65d1c8712ac8b587909209bbf5f009fbcd2e0935628a4e999635aa1deac96b4abf7272905cca58102d8aa9a8f80943d735ac52faf6b816aa35e868306b9d1fa2b56249fd644a23f49c73f10cd6f089bffaa859ebd3a1694b8b21cb5b0ae9f9adc17c23db222d00e04afeb2b980db309fa90700bea810a590d23f809b03eff7d30962bda5fc942057595f79e2879df7eba0df55ca77453e84a7115b1dc9427e9c6dcf20c99dec66e6cc34962dfb81a60498a40b84aa7b3cc04b973cd63b323ed1a16121d826c572db5bf4e7cd8a8dc5748741eda69685280d8c3c416cc87a983181a29a292b201e32f40ac3aa6d035c82543e2955ba01d0f1cd355b3035a18b72bcaa9a3ef6544de4a3729542ab11aa9590ff1d2f1895159cd3d46c008c608b0c940abc6f6492ae342c7e8c19072e896e93516d749b646de09cc355385753472a71310e4e5627d4bcd9455855c3ce353cc0efeefc5f318af3f731d0d26f7dfa9f308f0fa942c003c2fa7217dde59b746926d44e33031d1ecff9574d0b9e7f2e13537b0d167e903fd5dbe050e1da40618e7382a709666bff057b39b5373a96c1d6aff5a10546234cf6eb08289cbe8606cf75eb41eeca09184bbbbe27c334ee08f0401505812346546cb03b08fb6affb5378624228be5211f1904987d4c6376b8191e58634fe8294ae97ac9091dbc67018bbe695492668c02dfc01819d98a25e3b26be8c11891250211e19d80764f69c64d241c49a7f5b5700efb0e0218dbeae2ab0d41c6959ec1f7eddafb5c19221e0e57944a892b6580b8de6eda32c49fae0e944e8d7adf8bd841afa058aa9c69b1a44988ca0aa1f2e2a4804334c581c96274917e99f3098ec0cc8ec29ab4709aac9ea68a7e9a5cace3f1725010ff310979cb3cbfd06e3de92119c9f3831fae082e3879909c50c02c71dfb2e83233e1b6f43c0cadb38f62cee202963846ceaf67fb202cb1e9674b19abb2ee12a57e757bd8707f150350b4a52988de0ff06ecbd83561cac68454511ee69cad9b752aaa851cd63787db35e6ea54122436a4c3564c2058640dafdb67a0202c522dc68d26233e1f0702e8150cf955c7fc1557cc1e90fe3bc52a5750d85ca24f9f83a0576994a75a300aec370eb29877b107c8e656df2e7b990534b0c1292b3c4f5037f08d9a7e265fabb8c0296534b59b1b364f8e6203173d67ac9805d1011661750192f3907cd633db59a5673125d4f7c323590187c9b0e0f043a307e83fb9b22722334912263c16177a9bb3dcdedfed2bcdf53c5d4c32c8522d75f76d74208fac5f80259d1300bb2730c86b93a029db926ea0f0ce83f45347923ba25ff2727ae66971c9c2941ad5dc4025428db6afc1e7b72d7befcc6db16976584a2c66ae1ad676f6245334bf4712074155800dc048cd340c0dfdce0585128d1d53e0fae1d68229c6d70542413b1f4e5a4b9815be942c537ebf901d98158dc970a00ef63e77de541172f7da53678bda02c0aecf2c121a40bb9a91bde2e84442177e397264971689c0240adbdeb4e83aa18eb0b9cf6b3986c8a39865e6949231710c6e720cd05a5d7dcba28e2ed5f934069ee0b70bbdde8c7fce7d2ea26825bd40b5b3a04d3b62c8708898637e613a22e4e351377c95e0851ea25d85b9276850852e80b2c69ace512cd2463493a0eb80b91f2532cbfd3f910c1b2357a468dba2e7dac6414ce295f36b5bce993ea757d450f78950c1040ae921e1838a881fa99ddb27b8de1647364cb323cc77febac0c4d9d400313027c21d205b02820e85a0942e9e4047d65b9597dc26e14b95e3ea1586740e113e218772e28c21cb8042bb68fad17caa1536f8c7f54d816a02ece6e7b0bd09d1c487f32e55d7c200e0d036b473f45ace576a1de4007b639f3fe2d7e8d09e63e6c04a0bb682cb80ca0918b71ff16ae4e94bd4b2aa600975ba444477c55798d321a177506d5861c9617458a73d153b67857c541f84aafe698cced7e09c6600205f03ee14646461c63527d70843c690844eb7178b591122f849cf1a5fec5bc0f07275d5d102a440e5912f2f75b8ac5c11e65328970e9fd410e55cbf4ee0850daa696581b943869be35e431a472951d7c145b5d6df832c61e5f1fb95428764f2f1f1b13582570f19f7f16b1c275a33a04b370ff5e202e7755483fa0db6bc41b142a431a7ce87cd09d41154022c7e36581e3cdcfb81cc9c20aa2f6a6e362c766f4aead5719f2c3fa95ef972bd1fe7a500acce6c360455cc1535692a8d34f030aabd67b52ce855d67e3457b2089e8d12f3468c05403f414f580b41a0e302c1b8894a695b939564858c5c7b7b7425e1f8eab981acd58be6d2094cc98668ceba21168e6b6bc94ff870de594f041490ac3cc09e5fc80c818c95563361e5fc42656ec689cf182e15e4ce3fd8dee70c89afde7c072f5dce544652145e04c2c9f1e31c02299390224b68c4b44c3a1bb5342cb491900d0983b70594c132176b9dcaa69271799715a01ccfd72b9e058d9c991578fa81aa50f541a55db386a327fa6af400548ce9c2fbf495b9ba520b5df6b4fcb5369862a0d4f43464379c3fad7a6802f75782c5bcc9863c5354536f0a4c090951511415cb22d7d20e8152576efd513260582c2a1d8754d61515fd25b0d4e9ed72380b9e2683e62a3a92c5efe570b8995fcc9d620c46f2c1578f3c7bb5ca4805b3fb7984e87ebd06062b5b5a68fa3ab60a0dae27c1b5851e337d0f9e01a1f2d2eee0d74e092ab282bd7ebfe2bdbf0d419a8e61c615fb8a819ec759d4c0d114f17306584c9ef46b16f7761a1f0ad8973714897e3ff8632595af32aa4839d6d7901e103a5f1ea6a5153602d2d416128e927fd978eec93a40d438e5bf6bfd535dd8a13673f5b880a9f5ca5734526a4118b2b53fe96f8779ee452b36d3b98b08cddc18e2ff0fa1366003ea20ad894b4bfc2d6d3c73f7d4ecf32850085c4b6a0d97e17ec7e2fbe12269bb3de3d8c8d0d135de8e9f97a5ba007f91399e1b30457beb9e1ed01d2c9dd9903ca645f022d28b1c29c4c80bf65b404c16531f3ef30cf5297c8cc81e1907bbf29c463fbd4b997fce4a5c21aea9c78e732ec67c3f551734bcd1388ddf7a5a7bb1c10878359805e605fb4fa3bb28aac12ebf267927fa7e776656d325f74ba29da5c2bf3e97413234efabcdb51d309c362bae4cb685612ba04ee50e7e9fac94df9445490117765325d9d9cc2536f9576f79e0b607495e3e5a75285a0adee504b1a78e65edca0862f2852d1fafa4888d098df513802120c26800c93d2d729a0722ac8b1d43bbdc9c61b8b0d61551c6b3ba6d9c76844f1da1399d459cad53f660a5b08f37bd7b5c60f60a85597d7f9bca4a7928ffe83e1faed5b40776eb974403f42477c91c664ab12a5b8625cd0605719f1cc82b9d18a2f100b279901ab9f66eca211f23d9c51155bb0d67bf434fb9a5e52bdb13c148a4b4f5068124bbb1fe18d3efb69612cc1b021d7e7859da69f8af25084406f289bee11e19bce8fcda2beaa94e02b552dc890cbd8068f04d6d759d916c1048bdef77a5fc3f3c1df687a8592b0246f0b476c820d7a01546fe5a2f0fe1d450eb551a492b65eba8840174351856bc4b4b1af8062263f8685cb81ecfcf3adc661ca2f34dc6089d3d173092c634266b9df1a8650e8912545984129363f4db3caebdc130a758209dc38777ad5e759d4039ac2e68a3149b1fedf082deb1b436284a6c557a6ea1b0a3ac7a10206e4d477efeccbfc3004ae888dc3eaff9ee62b8248c68e66b66701c0da40151b2c41fb02b3a19dd0c40b30199bb13db63e566fd6af3e3812f469ed23341e3c0972cc6e1ac0868ce0043cee79f89922b14d4b9d40a7b4c5ce184f5850d4a91de0e6b0497598062604245d60b27a37a27eb37faf6e801a04e89b12b080f74925705cc9107f29085bae3a8c5d368ac4e1a76bffd6169eb1f314100acfc4923303f72a1425e9643ffba82c3da63b90ed822eb405711f21ae1915f8816051ea837bd335bc10c6a3aee24e0fa4c1323cbfee3062e1b00516f60e50ea2758f725fef3a27ad16fbf95d7958cdc20b5e81a44aec8935f4d17116ab8f59a24c74a55746075848b991017651d3d1a6b9e6185e591c0bc206856988f2f522d132cf7428c2b45b678aaa38ca5d2e99a80303b95381b8d51450ee7d40c4f18cf6428a07aebaf22533ff86f8c43c192df3e659320c71826e4060e945c449d008113db777a856e9c89050adc8a96765a74fb13ff8853936d1d60d98d764d2d07c0dab6f795719c8283d048424295effe0711e12214489a970351b55644541beffaefc7da8c1a86fdde7deb735ca5fe3123ee03034be9bccd4ff3df460a9e8f31be0dfb49116a5c3dde10d9c955479994d3fbbdf7051aa94da6ab5c7391dcfd2903cdb350e40a2bde5710bf582eeef32128e3dbedd2b20204bccfdf0b57754169b31d72825dcfe0493f17206e6b06103c3091bcf693e0868183eb34f80f00763e06f04e2e60abf92f5f8103e288ab431266ec594e0d80c68dba450c6ecbdf7a0a84d4dcbb9bc5b21866364e0cbb6426993cfe5dc03a5e61a6d62805d8c2d8cc44f04b4e07fe2b97f0f608bf43d47b1678e0ba9f5095e5340d492a795a0d9de9c398a79a9caf105763ad6f0c56d492989fa088729fc1d62b2a31070f3a3e7c7926761884194ef95076370ec4ed8bb2abe0fffd4d1e8fdc7bbff8a912e552d42e44e91bc82fdf8878098f5eaf1bdd0d8e3f4684e13a778d0c5fc33ed7f048ca2f9a82e9460767949f6c0ee7fef146590ecc664b28e28c21e309a0b004974d44447fd1ff477ed9403e08f27864e4d354aafe3bd8152a89610276fb71342a507220493e94da9266d2e0ee186e0a492695111dd17793594b90709daecf592826fa480300293785fab87ad630c430163dd2871eeb1ca218d6d84d52d58e8ddd4a6d510444b90db32b562d4a5e76a84c281630cd80a3c41468757100ddde4d28bbcf1282038984171203c268c697741218ba0bcabdcd5f82fd377a1eac1e09f9524ff0d72a8d43e5265767cb79ee7b25946abde2ce090bd38f907ab823cbb3ae3255e9c1bd27c8f4173cfcd6ce1136e908828d1199cd6553dcbaa45cdbbddfae2ae13270a5e15b11dcfd28c9f040b76e1d189879138b807a116b00abbd1850f56db94a9b5cdfa1c294ac24811992e510c463a31d8dba010494d8b77700b186677e94fae402bb9f69ce396320c1412f65641314b73280580872468d9671b0c546ddb8b585ff76210e0e028a98132a098d1127b4bfd7b3488a129bf3111144fe1ad63e085f9e63c6b6022b35a557a34cbe8f8d82c58d6f015ad29d46d4eb607fcb4bc102e3cc726d153d3c0657d4171dfc39f3ad31962629769fb432aa010e43a5c30b4e71c0d8ba124355c5b2a111280037569a63eac424322c432758f7a007f0962720ecf5915ccfe1c01eaeaa75969ec2fe588e808da49ce8135f7d4c51d58ccf37a9b8538576afe6218bc020731ffbbbfd76160d546f570d58bb2a9131090dd2c31967d66a471c1ff64f939e38dc7b4df8150bf4be18b58721ad96a177f577c3b5eae7a398e30dc8297b476aca74ca8234b076a5afdf339381200b8279e92e98bdb4cf4c0aa48af634ed738210497e6d000eb99cbf1ae704071a6c431c9abc8997c23749070d53fe4fd53838acb06aaaa79aa46af9c564305718235a758add978bc65d315bc0d01e5a2511b4bb03c3715973a4666b9cea3cd9b783e86ac224443eb948c2baec8c99d18300410cc1713b92202ca86f88a2f877128a81abd3b08057c7c25ea57f2a1f8d9bb974ac05c7ab0aa100df66600ffbd3330ce099be1dcc11f846ba69ec08b0c96b6649ad5fd96e11634260ddfccbffc49665abc458943444d0b339c4c445e16e114a3b6ac5c498107ffca4cf541b30c684729c16adaa0dc2460b8aea248bf7e19843503b9fec3bf7f1c6284944f6fc63016e6890f07fe630427eb0cb471f191e238a43f194941738a0d19930e8da9a553d3c681673a832e013911cf85407f0c8dea55c91b47c01179f94cafa55f19480ca240c7b5b1f372b6e405bae9495d32e36b698dc2ecc60353d114f89ccf724414c2d28fe8cc36308a5e6d4116da7f59aed50d38ba103fad4bbdd6f183ebef044732439fe0963305ea5485022c199eb4241ebc6f89dfce44bcae8f927d67ee80467dd20e4ce5955bd51f62dddcb617d399c43ce46621f6e5dd0a94c8c1ad655b532a43bd8cfbfb783eeba32618e662ab00c0b80952688a45423558401a1bf07c8f67ccba199db609c3c1d31db6879fb919e477ed6e940020665062a84ccada77f96af76587e404ef4bf562ffeafc45a14dc8b18a4129dbdde07655c940c27cdbfac313d04e80b032574a434c66bf19f9017e715220ee28f478f748c72190e61638fd5e763b5fef74318115a0d85c9264f6708e002a50fb158144a4cfc23658848771d8fcebc522942405345dfe00f9b6e8c19f387b13470d6ee6907606300300008382d4686ef3de62517c93837f2f60fa9347d211f5b166fe4d7e531c05c57210b88b29e56c1405cd6c9b153e3f1bb5c5703329037b2b254be23223e68746dab50bc1f25ea87020f2d95c818f21b63f386f41c0fb0dd8254155b81dee18cad39426ca90e4a535cb9e76a27a089b2c3ae6cf104e69ab3a99e937f4ae18940efae603b8817676e4d600c46d4e427dccbfc714dd5589f65b645eb9ff71c70f9c0374304ab21d76e386d628081d98f0b3ba608ede102340af0e9b9ef8226a8a72730635b0921a25b3a0578a813cd9db37dfae130e929edbd48b44d6453c29f2bea4c53dc358e8ec9a1fab04808ac103f8cb8fd59aa9992f8c241449b5efd1852f7bf1c9eaa003074815f9bba43fbef249973c30fcd29e5d0de69a4f6b6ec6cc12950ebc85d7ace1d0ce29d7095a3ca01db64cf02123814f82fc5bcd5dec1eb06582886a34249bfca144872ce269aaf50ea4b7e71ece906d7ebafa2a2bf81646f4b66a203e1c8b44f7dc48f2b90f5e7f728b3ae5fb89b6b4bfe90c0d3fac21ce81545abfc3f0d7bbe37e209b71310c9f53bbf4236ca4acc586a8a70341397f12344cc97bcd25f6c3ceee685eb9a35c0fad93837ca52af8ea92d03221df9eed6ef563b23941f87a4fcdca2dbba87a8c2b9cbd05a106cbbca20e16f93d3c26415e84d970bc54ffe830c866ab4549a12c23ff84645817219f91fdc101048256ece05958c0ef86eb38eca2b55a28e397904a0f8e0b9f94d39d49c689367610fed215e50d17a051fc26f14b07743aba98a218a1434f2ef82cbc168d72bd658550cb8c2acd8f3fb02ef70a9367ab085d91a51e8e5c4f2424ab56f0f25382d4c11903956da35da763f89e4da7bf91a9cdfc7a54ba3cda529b7c04ad2bd23410288075ef88b13a9cc07e5c8ff4cdd79d476666c049753515aea4c54fbd2bbf28020b6935e6b3b93a106d310cf407818ef8aa6b31df4d6d190dc20094924513cf488e1610899310ae60cf9946737833a074822250cde9288cbacaba54b3e124c00da42ec163955197ddb58e9375c0907220c93d4113ee729e8d98f6a34ef8c6713609972666b4f84e10c7f575742e1f6f8d641d99524446eba86e9b3e9ccc180ff0ec3cb40c8f2d8ef8e520e180c289d3c4ef298d6f86e257cfecadd1e4638fd72f611339af20bcc7b98b2d71b55a6c2c468412487946907f476278c10500512a6bd8386e0ef261d9b9d3f4010487bc45823b1f36ea63f71a06bb1a772f14a09d9b8c40d250b6b8ebe87d0c7292b8890da226011b96addfd8a75a04621a851d368a0a1879e22436408d11e66e984338db2662e48130ed18ab9670d824c80b189bbb74fe25b90258a03ac816cd00a59566ed2e7149ddd341bed866deb076fa4d0ddc32c0952815a633eada34deda23925d3949eefd2c296d2b2b801d502933445214d79399fc2df95b7d6a311add180500d0eb98a965cdad919edcfb2b456c832560370607c0ea605330a6a25c63a700760279cc1f650df6bc8b7f85776dc6ecdce55b4bc62eeca940663ec638412300d0fea94ca33064cb8f4e022a5fc8ff9b1a71f15227ebfd770a511be21f2aed815b9d27814f88f35cd51a197ee29273714c2ac5ad8f75a898bb44cd8571aab8f69cb2af4db6676db7b2f530e362b1c3bd0fb67caa48cf5df5607e56f78083e7137aa97bd7da13e3824bd3c5e292c81d26f7d1078a29935e05f7503659aa56271c5262391d6c8e2a08fff86c22f6bab3f3c1efebbfe42cebd00433f555e517ed822fdbd34de4240b79b5c2dff9aac290c3857463180f21591ac197e218244125fde54dfe404420bae25f8d781e28c9ea74a8c2f746d428ceb70243577eb03f8321ff9abd41e8e6e7a8ba6b4a3bdee9168d2ccfa499303d53df271a15245f58e0ba28b94377ad046138e287479d9ff58721587043af7c89b03210cc1e8249f3dc5f45cec07861b08d7f8ae5bc094b0a52c2dff86cb1bcce9644477114ee9b257e4446ec63de1b488b155a8bd9955425f6be3699c5d2be7ee10a4ad426d2a693d7e0ffc0e38d2623cab55f28f05c5557c1da59896b38c07f89f141a4336c304cee5c289e9a05581b0ef813fa1cab7026978b74413d261b75f6114aa1d5124e8cea8cc4dacf091128675bad07d6f2b6b55ba182d57cb5eaecec5a39c6479873e0e37587fccb6d07bb0544437e2aa8f2e89a548e87d3329626438df0f8f8becba8e0c41f45a1e4fb5a5444eadab86d8156b6319654cd1feebb1289a09664828afeb4adf9a5839d01c85a238ee5be9a24569d7146f5c5a9678908c3c4941c72b6666e42a3e6f4db434198645b9686ecafe52a100316169ef4fed55e036ccdc099afcf298d73bea505df608abc60225504566aae2b83d2a221de7657579748efccb0a7c70ba4a6d0837cab4d58e46f9a48a07756b53a1a5ea0f7635516b907bb64881c5731e8fff60097fe4335b275e56df9d80d97a7739606a23efe4fa7fb2dcde63ea992acb3491851c1f94bcb67a42ef5f7844d293388b315223cf205409cb9680103af2b223dcded5b2fadbd0d339c75bf63b19042aa77869f1ce4d54932f4e9b7a864a1ad8fe889077cc0c885ab105d6b4ea87eadc70793f21aea5e5418915951d3e7f59783e9a48007b1dd3ef033c6140a6b41ec4c64f715c6343507d05b88110e024350867ce3f6ed080e90e6d7f9a480556a5a70c5d17ae4ffef9011f769c763cb0941087965d3ce4b4cecfa81dc37f6359e4dd370bbebdb1cc895dd53a3b36fec10320f4b16bb39f2204210ab0ed1d5fc01cd489023914de7aca27c8891dd700cf07bd28c9278511f3fc2b9da833aef11cfc46f4b3cfa147b2977b99930c98f359eab14c71b750b8efeef8265c868c0d15d5175e1f77dd22ec47efb08c44930ce860d12497ea7b9ee5b6354be91e6d0cd85ac4110cf0d84e60855c5cf5c3a60bf42c1034209c8508d516a49e360014f62be407adb5165fe7e6d215f9a21ca0f1957a92d3bf40bc6687b37e8b90347d3e854fc3d06146acc42bc6e512bbcc7b90fa3fb627d5e5a70a3048dad8ac721f5f3e11112cbdcee5c1afd6d1a31d0a81c91ac1d6a50eeefb966737e3ba4728275dd0a300573c37a22470f859ff5db3a31ba6fdf2e5522b143ed2283e5e8d29ae429c6b6b81b843118e67509bdb87739b1527c63491df3cd2916c69c5f7e09c7a7e6cca493eea08c77144706ab7e5f3e1aa8525d3cbcf2ee1111ceef895f16818b06901c588cb4f71680c411c0a6e7a811ee6e71b0f5096304e6b2469cb131c4ab174fbfdb82d0d9755612428bdb0f78f85fb7dc4565580a61ab107fd4cc0b9ac381a859a8dac21d182c00efc11d842834289f2c3f487b761447d55fc6732427612a66dcfc6af7321812de5277a3c681f7200016c0574a107f1c133dd68d1ce966ca0a5d99fe1ea1a77e61b0aecccfa1273a46036a1563639926abd89d323eac27de61ce714c9b840849937535767dbc79925dece58c574bf4244707e91aa2fb9f26c01bad21602bdc064682a30e3f5e5a48c978d2c0faccef90cb904fd1e7ff7b13b67adcd221e6fa6ba7aa63d05190598dcc8e0a1b60cf58ba335aeda1d983b6ebedf045d4e77d11c2270ebb158c2655ef7fce3cc45f39c0a83f3d0e4104d0c88b71cc45dc235aabfcc9cfa71c115a9161fa08a8f946c2d205c023740cf063e0041d98a91684f080c5fdb00cf4defd83cf92a813f93ea01e1e91e33d8fc60769c8274b254dca39fbc8c2f2aaea89d0225eecad34d1886bde1d9066959e853474a71ac6fbb44714026c3b5af802c9b977aeb83338d5479c9d7ec01c86bd357d04c80e4eeed0564ede4b2444a99d9121b8a823934c270906b48ba2d1b35e0057ec2608338c70db90b3c77e5548a002d88fca8b68d07136a647de9d2b94a0dd8f2323c60ff2185237ba07efd8d49b4bd809bcd0b22a864ab8a279cef7cbdb22e0ecacd8cddeb6fc8fe24d94f2788d91eae144874a53abca9e1c019351654663f5ecf40e1b256d13a3012fff19af4c119a5d0a3d256c87e05dff323f3d89af38b8b6975abc69d3a5cfd70a78bda5488d353a97bb20805262c3884eec00c098c9472a9c17661c273e05d409c1d7dd569a25d0f8e85859751609e6805a8079169517dbb8cf82671034c8ccdaf73f8107d191a524d23bf0853acc1ebc400305425371bddbc230e35675770b0c5c27e0d59e294db4032b0fac21c83bb971c4a57242b40c14d088f9b0b3f6fd422a951da18b66a38752273df0419a74579e1d18a82bb8d21628ae1dfc1744deef83163062281099fba4840177acb4f68e4bc97c249f4a98c1e778eb63309528785e6ab1bbf9f48f1f155b0fa44a76e764e2b678c4e3282e9d386ee6d5e844981fc0d068ce827e092c66d7016f28260cae6966b6f343a2721489a3113fc9cb5a7b18044a2b3c883c4a076c01cdc6853036d4eec04ad9737bd327a350df1fbda99a86da8c321057903c15f54c82eb040daf29d310666013fc8c473b3242f8643d1fea179e1a3539d4bbbeec7579da5f2d0b4a0057639d682b1cfb7fca089c02b9ff52a68242802b71292926a7c2206572a1903acb4f705704de9f6be532ceac4a4b30014691d0a94c12096d7d4659a86061fb91228c073ea4b0ac2364351573000dd3ae49964dbbd915341d3c548430916af268b05883b15a0cc851bb7e755a0325a0b12fbe7b2c725484e50ee3087ff80c2ab5730b91b5e5e2bea2d2823a40a68745e75d0810cc1a5e9bb5b35c1c13af83ed9a1dd43984659e4acb80bac93f55b2efd6721635a0b3713048288f2a61c5082af585a61c621046c37133df6877d84e79f9d1fac2490de14c798440701c6d41a00ea2996e1288467cf08a7825e88ae82358fe05293ae71f91ab4ec498c3a157c01910a31cc017e27af57f926f1b4a11273342924f7a0d08a48b707560adb1ce9ae81fe0cbca97900b771bb5619a88b133157fb585ebcf264f26e0246a29126c18cb7692456abdfb48c1a102aa54ebfd5ba3ad107faac1bbe07c8ac8c4fd217e29bf142ae7d386cb0ab4e560a9db9bbc25effbcbfb8f35df51ab5e76fb81790176a6b84331800015895b09e8d8caaf5a2fcdfc518a2bf8a31ab50ca30fd6a28ab11f96ffd8a1be471c34613e29ec673cbe802e17373373d5b069f4d8a8531066ce2687f0c32e0056c1c5fdebdf3d163b32da327c74d45f97d1cb31e73596d0f18a3a0622914df5d2716788b3831cdc3bc4459bb9943150ef090bfdd1742ac89b472388cf746ce7c6e6115e31964d4d22849c1e50edc4c42fe91cc4d7f2ef3f0f66898183514e2b07b72b73ef9a63313466878209f0b51901ed12442924d60512bd10562b500965b18e8487c73564df6a393e1ee64099c13b880d3004e31cd1d3bf0043a9d2bc52f6875d7bb22efb00e01bd10256817ee8c7d02935cdfb4925868c2e556ff0a0252c6f80b41e3ae221a845b2e0d07188a6b1f22f533a02f2f13bf2fb06b317577764c40f057808b3138e21f7b430cb79f800f16f899372296268643d6c8aa884beef196ac118b2355181c687341856628a9fbda1222b327c99420912bf62b838599195d1763c1f7be40aec21581be1a12b2d7e267811a8dc4e0cc3242973a15308c24732306a05da8320926255fec276050ae29782f8eb2aa510f1d55d30682edef929e6ccb5d0342f4411187407021b5b11b61a4922ef93e94ad1abda2fe548c4a81b79c3ff4dca1db0984345ee5a064d070d09c51b7a89a423e97e198c75d99d0363112df24cc35c051bd577e3e6f1c4dd0b8d66a5ced9ab0648c8dc6ee700d445c3c3e5f0368168ffcb0a13e21202bfd678a94891c7be25fbc7f8b9645fe645c8e2de4060a0e496f2e1627673064fcef19ce19e313c1fb3384740fe77dd6155804e46fac78b905d906ea28b7771ddfe2cfaba204eb48d65c1c33e2c93830940ae44e5abf50e0c50e67c7b6500dc981f7831cc7d421a9cad4119787c1bee501df5b3e419006a21ab5cfaec44c6b28bf082ac31865784d732ad407974a6b9cb3fc788702400bb233c8250dd636e4cfa559e73dfdff531f7d151aba75b13c93d007702759d4a0d5c7053d3c1f84a46dfeab5f1782e766fcf738eaeb2bce8edee1a08431aa0a2c5743ed412a0d68208398d503d0104080c86bc3cb4901448a1224f9d4a57e49cc5b06a2357ca97f13fc3067a72dbb559af7f347983854a28597e0640619c0faefe4e306aca40c6c836b92aa3935154a7d2387994c9eb371374eaa0f64c651ca76eed4d2683286ec2a6c648e9e4b1f69aa91fac2c083824a1381c583f369b8069c1df44e799f0ea0af8fafadcc2c0804db33a7fcb5e324d55f4271a63d70ba7ad9ddbc59e440316f1ea85ec74e62d1d5a9200d965145f1480d93791ab88bdc71cffb508d587e6636dbd7c447f5416f087196abf41e65823eb988cb9341a9c84549ce4856d4d35545fb1936c8003f2a637751f408daef9dca9bc63121197e57c1133520e770a5c19795d9019c9668a1546f7a318b4ce74a0c49e0f6363ea597e60c77db1c54e20c758c58ca1e30c27a22e4304be0207c5d18d246253521d122c008222248bdae69217f5bed647a6b6df7b43ed3740c8f2cb7d8239e0b0f2fd82253956b92ef29f123b034040c8c841b013f1cd23f3bb0b2e595d5862b560d52fc24342b656393e7fd5ec1220d0b97ace46011d61c31b2cbdc87626858552362dead4bb43feef46d346d8133c72f9f09786356bef5354ae1d1720be9e0e382cccb9215f514d52783d63749d5bcaf56d9287cd287230339627380ea20a0850b5cdc3c4cb413dbfb493f34c827670404e281f5d34b80e1cc129f2e0c99c6f3bcd475a38c10e261d22460f6c68e59c50c328ebc3e069d1bc1860c69d3bc3f7682eae08874ce7f8a7022e130158eb8488c5af85590e35a53dd5fdf54d716e3e7713a331151b25386de025b0eba5362f4b8297d66ad5e6f152e9808c7e921145ec445cc0712379bc324936161c6f5cc4cd0c353c12683aa6a424a502f3d78c42cad6a5f4b7db57d0c364e32b3e8d8cad4d01c6472a33f002257cfd7585af45a41084f932c2dfe8acb5b8822b79861729ee055ba89b96fb025d7a6de8bd9e6297dd89fd206e4fcc209c29ea187d8e496333d2789a8a6dc5e20ad045363805188fd2d43aaaf9aa99d066429916e81e1227977e065a6ae7f3b85ca5069a59dba92d96ab00fd17203a110f5b9892251fa731b8a8494c2818734315e364e8366f66f69170672ed93283a445207fc617244e11ce338ebd22d5d7bbc5b4138e2b9075055f91b5a28741a71c22d857e07865504197f63c5c58d9b4556aa6b742fd0109fef09250c4c4cbd037a2cf9a96dd8f731ac821c863a5130bf5e0f86f498f5d22554bf1552200f753ec72111150b412f80e2f55aacb764a9234525c2410545c445efff46ce2f2fba6d58c3fec874e694563b8350820d4af9fbbe6ba6d14c983b3b6716b8f26cf73457fc576ed54206e8eba3ba6b25b9cecf347d9a06edd2a3dae8ce97035fc246050206568ec815dede61d503cff6e9b7753604cc70bcf80404082eaed037f629d3fbbec371e7a5a077ca0d9b50c9d38ba11bb4ae6f28032af931d3e183e4421c39c91acf01a99d6236755b914b8655d29fb86c0e543569ffa995eefe52d2342bd951147cb1a4bcb4cd4d69d9d080aa7bd07b57e15a0e0ffd8f96dddb49381bd0ed88defc964af041207569e67777a449d6934dbbd359bbc45a4b8d218a8e9e6729fcb26169f74204145ab9e2e67f9ac7569aa9e70471d0c367925e9932c564828a2ea5c91f7aab2415285edd2d224671d34e54961a5b1200a25754824a3fb596b699cf108b538040bf2f00d43e8e158f36ce6a77079cf78978d94735332300a5c663e441ca07c7415f7582d52cc565fe08186c0939a0a53e596b62a424cc454683919280a218f8e21d8fca2e0a0b609bb035413167006be16a1cb9eae2f76893444efe8fa26e0bde54e54cf682a6f91a0d2faf7c4f31d9567972467452d2524982c6706b242d35989285902e7503c14fabe5aa442fef51a200eb495490e6a397dbfc4d594ab7fae388774a3a775a3da383e650521fb5936b40b0beb12c1b87bc088328785b80981f3510da3114697643df3d280fb6608b84ef69a7a5904d489334ef150a74ceae6ee6d704ee2e9baa7f4281fcb16f4bf315774f49ebca369678186912d871e9cd21f8dcf28eed11284eec6be42140e551dd3ec59e9344758468dde9e9ad00caef1f03e4827aec27e46586a51de2d26fc2e17c470ea67463130669f0c6d34224acc32458e2747edb44ed167f33fc2984ae8d0e75019673cce3130e6d4f549055ae941a0c6c464519221f73c728bf376bf0ee4e680da75e910f0f618b0a3c599f425f67acf2c31f6fdb95b38206ff8eab309ef755f3c2c31965131f290fa771851352125e7a795c08159c6dce4894d046aa1b6a2af7c19d8e8431c5ebf29997fcc22b7841d2039e5ea8c01195103574b2800ea16fd15388780eb1bfb2bb052062be6adf61884f043f871f9179681b40f2edfb9ae04d4f09fc1df56daf2a5c651f6c1655666822177b1f6c27b3a2bc5d5bb46476eac65e2be24e6095e162c138b6d46112c54c97c18cddd5069b836aadd18c1112eafc6ba8a044e07fec0b57f67cdcdd9cfa478890ddf61ac7b04c5abb47bb8525cdac4776185a100e74d6e95b92c1e8872adb07a329c9a7442f5ce4895dd1cfede15d6898a54b063d8d87274fe88b3149274b56f75f5f6bf5a6ca9999611bfb2e114742f96c52600b11a4a4491b09f046f5dd3a3e546f39d177f561aa35d884e49af9c0e2edf900849213edba22e252d5767ce0404f8bcc4f6c8d974214efd982463a94e769bc95ca00bdc88a5f62f5257e62f2f5f9f5d2faf8af85073b11a176cadae0c413e57cfdd23803405502679c8ce929c3fa88cdc3e0db896d470480b1cb1b4b47be284049fb79e04ed2d7396e927fd383716a55d6a9a1443fad25ae320a87ae51c06ff44a683636ef354d841ce451b79e8b5e896684c22ac6e54bbe6f73a01c8613cc80d52437bace8c0ff8b7576550ad2043223bf59fa7a000983d56c3a9eaa428b73e498832606a1cb8f3f7fc3825548527004fa224cd934c06a8d82ab3809418f8adaa2892395419acd0338386b6d1f99754625ce03630924dc74575cb37ea3b4151951fa9b6c1d3ae4bf689489fed48e86078b3827d37421ae1d146c4e9569bb0274419b72661c39b43376b9814ca79f2fa7b28ed9e04a3d498529413af3b51373c16d0ce9450d6b74137e12043045b530713d5106fabc45b8767b30c11ec4c51aa224aa6baaebd9950afe32c82ea597765fc020b567f681c7247275e748ef440dcc1c3463105d35b2ff94c83e1a73d2ce7d1fa0246bd20bbe58a97835d2830278bb9406767c80d8db5d849a0fa73d95e06636009b583e7a712e7627a64cfe5866efe2176890413af4637fa870f6340b501b0393a8c5e4a71c4e71f22a594f6eff9c74f26393e865cde5313fcb432bc99f000f1c1bc69b32aaa99c3fe0f1113f83ecd5a65915bc41db9799eb6b1b03d0fad3c6be77919ab232e9b6947d02ca6e3350f57b46f4d0068c0e319de44b7823b5cafc24385408f55a95057109fe411d2d77421af97c490198168677da6e59d8c469ec699bf93040b851a50d8f57923a2b36b25c5024b84f7225fd6a9c4c76f389dca07c64fc1987d8ced0694e106d58ebe39a001e471f1552b831b5f050da9dc19fb44171265e8f0e1696166579104b09bbd4ae41efde8ce8cf49f4f0a987f9120962c6123d25008387c6383b252b2d89435dc002017675f5efc51b486213c6608dc104da9ba66fb31cc044229fe9ac5b3db9efd0de219e511893b408d3798bb57215137641565d5ffd5095841b7a3ba6c4502fcea53910159284c2ff910612f2fdd2802d1441b242a0fab9d74a3fce6137ba649677933de48ab67d9ac2ccd62a31844db8db2016fe6753f2708e37237d8a9beb85c71e2d981327c33823a8d4207df0b0121a4c38badcc72f8f650ad8a3f1c964d61410a553c7fd5350e43063a438adfff5fc929b5e6e1d0215fb11cda94fd962a69645bfb0397f2dfd9c1a2267a56cf6c14234184b7365e5b880c9ee6fbd5f5e300502344afef7ff8add0203ca4c7e021f0901f5b79f2c99745496a16dffaf962d4bfe02aa3b4fbde7af311ada018384652168fea2579738ba3daec9a2a614fc1bc6bf633c5e4b5e9c4c29437885f927690cc55887aff87bfb58dfbe18f087a0d0789d4a454be9c37e733f6a39b1a14ddf0acc8c2d4c1db96b3a42511a01b3ab80dc2c50265493cbeab9534c8fd878902b7846b72cfb4434a63b67bc3ceba0ff42bb8c552572a560c04e9c8b76cbda952e23031faa0c39db5b158833d958451a9a6e320729f0b40c69dac259afac3ecfc852d05dc22c71425d543951a6f592337fa9c4d51b0306ecda6d23c7a6086fb5d96564dc0f717cac82b7679fda27bedb4d79c118f66cf64873e374023a55e29389186a0e1b8f64e5baa7f0894646129fe468ea9e0b39ca15be2343988e5a85344edd1fab58be7d8add79eb726a5d0544c836029d6374dbc85f93636cdd0fe783485e42d708c13344d208a9eb57a0a2bf368f9f1978efb3fd57501e5818debc2d3281d176a029379b0ef90b29adeeda8249654530ab16f489d43a6f8b04fca74d48d42d44752e2206c64e5185b3f8ef31667ab347b0f4908c8e963fe49d5cb246904ec6bdd574d016e0034701acc1c75c86c1c0435b9306473cf8a413794fb46840fa559adf12dcd7c3e09f86b7b17c912afeb705c395eddf457d125bc23d745674d3b7be5ba4ce3b9464b93095ca11bdc6a65e3e3470f2c834caf76ebb588c3fc654af43cfde26a0e0ff79626de3cd93f5f8f3ba5fc462c6a9928914ab0f2ba7ccd50d14d4e567e2e9b4e1e50f60c8151d11f962ec175609bab069b70f93b158618d416064138b4eae630bade7ca82bbbff0f54180b654ccde3528a950eb43bcd0cd30d5bc488fd5123ddb8b5dec0f395d73e67ea618a501f0a3d9a31d04332b92e9af355373c1913dd5a98013cf8f2637beff06462c9c5ccbec42e3237bdd7347374d9b3b16940be20ff8ca6119368087edb207bdcd6b00cd245d9447f9e92e19548e9fcf72ea2a8a6e1ecfce44af6864a9758b5eccae389e33e742f235ca10007ac79942f4cfd1e200320af1c6c6938516268d3823bb20f53b8a0282c6ef2d9a5dc3f0c9926685c3ec93d6a488a6de61b2b57271f7b05a997c20a87b080fdd8c8980c4e600c37845a4db55de43b023e646074816fb68e431660bdb72db70c661cee0888a9db65fe98b8a1d574b7950b5e9e51b24146007a2afb9a1a7c8352a10edd1fed170c93753848c0f70e708c21b552fbd9255ce646b2ea69e1fed9110a015633d987ca8fb6b99fec50402a5dc40d8a349a4800272867b9ae501fe9a94fcec2e7e86a209210d9bc2aab338720f9e28612ba1ecddd5cefb91c7dd5902f24937365028a879e11c17a227b2b38cbc6d2f79794ad52eab5d1a98ef13aaa3e22eab5db0c753e1ed856349e3a07ce6389722be9fb40077ecae38bc3b619617e61450d276646e5879c70c1d9ee90206960e470fe5da9fe925e8adb5672f3a7526665807f031d960c749d6cbc73a0ee040252e87ffaf36703e1bd29e1d540a824631f2418e7ffc8f7dd35c9327d0fe1373d08755ba1f290771fb65ea28bfa1d1ce24551743ea2f5f9e4f2aae934d870afae0dd1273bef0c2d6e85de10d9b59b601d7e3d0b1933de33ae204da73b335c366dc9b5188eeb059f7a5c6eb2228d41903c0859b0ead3d901868274fa4068e3c813d00033741ea73c915dc548822d584e368c0afb9c8fff7d4650ae2c2051dc60ee3eacb4e37afa2d870529cadb159d725835f05dcd2e56e16c2a14855a8ab285d8cc94af527e35605952cb29ed045ce53ce96d3012d2b87cb5dc9c5940688b2ca999417e43f13d350ccf33f13a8c24599a177032b13fb0a9828bef842959b645bb4be9843ce7bacfd24360f686807e329afd84902dcc15c93da620e0216276e80ad7e32891c526510d878fb53da51ef66f25e457e971c56158744e306d30ded17ba8cc9703f94bc2c663ca5456c99988df30cba8a9cee778d8051fa62589b34b0a5bfed80a7ac5e9f8b8067c0676581436a7046a87e95aa70532b8a9e64899a4a1d79d4598b914dad5df0276cbf5a0c0e6bf643dd2fb9ef53ea8e356417cbe71d05b1b81a51ae3ddb78995c1490f492ead7046b19c5fa0ce2c89175d9010c59bf2695a926bcf96ae79d347fbbb8319e9c2adb28752a6b9c1fcadad91d8d95b286b34326808aa6903dbd806fe6e7f1c1e899571b0bb4e22296cfd7412783b127b1c84d762e11ce0ff1d7a75752e198641454cba8d94192cda93586a6988c8ef74d97f6d083ff746376eaeb14ec5a1d6dda6ef4f261a08acc46032a2bf9b970e7aa8f6a6c4d7857d1fd2290477ee669400ed6f746a3e5572b849367d029632653ab6106db9fd2e639531b9e1098218a4f53473e2bb3d165b365b04f09cfcff0ca8b42ad7dbc66e93900b90020d984e76b5260a7658d0826120c8087850a135f7fe5fd8a30b2ae7b8c3d9fbcff4558b267097dc8eba576a2270ce990030638b75b7d462729830b5b57fa46638c6c00d6dcab8381c768a80131ec9b059b39beb66a77973a406c9339b06c4f376df92b49ef6904e741bbd04417a93b388909ab029f1c5db8a19525995b328138b99748ea71456e7a413241b33241d030ac8dd5d5c4014163707b1cd0e9bc5f1b25d7fbb7c3b7ccc80b57226f47da9cd3aa090ce9aed9b97c99f4b96b177130434f5f044b6c3c5a68bca0835bcf0b8df831fbb12c7e6b41f4dc96f61b6636cd2d67b4a5f804ff482464b9b244922654a29bf05cb05c2056384cf83cb4f3f94103246cb4b5d903f84b0582e44878a344992244992d5e52095e2a2bc4ea7d3898ad39f2845013eddcb896047740d85c169fcd3f79c565229a8405788ce7890f1adf0991b0aa3846bf6fa243ae6f35be130df666a2714bf82f37a2b5e892b89a6b1bfe4a7782856f0a753105bc4901fac7be61d03d608a5ba1d90130cc33014eade7befbda11008a6bcde542873280cc3300cebb1d1aaa27d62fed80fe5f90976a821b06359bcf7db7e58adddba17bb376443947da7c5d5c2d9b4f628ccab04d134bbd429ddb44dbb30f6bc1cba3f346ddab4bb5bebeead9b366ddaddadddebcffa4157b0caa7e3b615acf2e938ae082c8a6cbeb24c4921c6b53056f988e83be8de2c5f9cdb40a390f320366299ea609867bfee7eddb59b356a35ab59cd6a5ab679b125d42efd9ae6477d352d13d9bc5cd1ddb4e9fdffd13b2a84ebbaaed369752ff5bc9c413014baaeebba7c34cdd7ce78c576180dc57ea2e9780ff1835df5a0c0758566d14f7ea233a09675cd3753500582601af4e4613860f04070030e5f5ae6b305b5744c0aafe0eb743a9dacfd0f183a6763a6f9add6b71690795afe7c26d3667295b7bee5262c302569134d9224fdd60a0fa6be050c3de33770d3fb81ca0b5306372440cbf400402652355e04920973349fb80933796e3299a6699ae6bd366e4c9527582854ea89142567cf2a8a8a8b8a429521efba2e123c9dd05ff6b9f8d59b0f9a977edbe72821b0d85c847f9120830d5b506e830a19a03df4aa4fa1de7c93d237e99b660875a25028140a55832bad8ef58c45e061be011df33561cbd0ee017bae39d3ec206ce489f59145318e23a9ec1142ea9c929488d47154a94a6e855dacb550f073b57a900b374de747b221af72d2b1dddc60bfe1bad15123d040086b0e1e3a22d034ae23819e711e1ae673d7f9a85a6185518676e27ed241142fc2ebb9ab1fe4018badd27185d7573f198ce3388ee3385e570d1528a59229c584086aa754723a7215e148bc896badf59215c287b8f9f1136ec4061a7a16fb8b8ed263033e680002dbaf827e72afdb0e158197c475a7c6832ac0a107ff93826b16c130003d2a5da552a9542a595b23f4b182529369753b462514ef755d2c2ca15333b78897e4f2b067b25c696a0b1fa92762a75eb2104ff53cb8036aea181e5c3f2f91c254c634454d2693a99e40d44a92e5ebb85bb783cb5ade9ecea853601d554ca1d28131de386d0a3c23145b955facc0627ec9c2c6831d8e500a8ba1971a60f1caf0b2048b311c80d6af069a3d50433b096faeb986fb7da09d84f55bc15361d1eb3e22f067838733c24c099c4307f4491e29a295003f797af0d64b02f2b390b72b14c81b9ddc2852a6e83c89e61ee7799224499224795d35700f1126241126b2bbb3ceb22ccbb24c0a07ba6bc2e17b9b841d8e8cd20f94153e9ee79ea184a29b5ab2acd600411908d10297f375bde0fe8944958a2442d14d36b250c846e0ea50c500080eb836290cdb68e0b1ca5bfe1da41b6e735296d910bd6063ae80715374a4d48ea4b247888e3dd924b66489849fa91d59cdda56f762ec7939836028f494d2cb0bd15014fdf0421e0b13d833cbcb711f98a8cc510e904d896ad4ef420e908da734e2c9329090115594463c58f644e3687f9891bd241adb22ec108b72c933f2f7a8568764c707ed4841375c21e602cae1d9b1b292735cf2ca97b3925b720e4b9651bd3acda1147ace096b761790e6dcf6e9724e0ecf0e973ce3cb99915d3e1a38f728c725d3c026954fcce1f4c901d57da20dc78386f64da0472ea01ecd9872b30cd4061ad6cf0606b8645f0be8078519594dd33444f40c2dcb233a0b7a648950a435605d526849672e130df3f9f244d1636b60c78eb9453aa67e57eb6299acd0eebc35d99114beafd81213987e383f6c18586cf3e6871d473a8ee368473b86f5a654bec5c465cce639cebe8481c57e02e4ad00e28811977dd019f046017bc6403cb8669b5da39a96fd014a53f46819759a8d701f298fb68f86e71e61370f9af77bd22cc0f75e1f3548911162f5125493f07307de65027f7ed087b756268c18b65ae5ce977b2f4bafe15c86e3388ee39274ccbb736e39950e24e2bcc6008d002e947580451f3fa1180a49ce43d770dce751b4cce71b8ea4c1ef3e97a26368a87d5e96b4c440f9ef5d89810b748d972e43c3e5cf16f09a2d7fa6a169b416ab9de01a2e53eab8da0758995d1e1db76929cfeeffae95e3f8abf1d3e273d9e6bb5ce3931d3bfed4f87c3a6ed340b563ee83dc83e30a40d45a315b310b002af08cfdec9b409b66c8b699e301d05371aeab063686b5f6b2172e71e05e620232c4b2e7a74df3ee8e5d1d0e232b39fe23f41bc21a7a156ab889562d485ce9f02af40097452c671983720b9feeea64c0fc13b90e33500ee1e59f58f3f6ddf061be40349c7b98cf5912d8e66be19b45d1a783a11fccb24face177307c7819592982455178896c3c0c58233472411882e3382ee7cf4745c64ade01c8387ac99d5d724bd6998157be729917508f3619a097fc0179cba7e3e35df8cc92678058be1ef28887cbbef21a11b4cc679719f9472f2b36bfad805eb20c900a885f5436caadf4c8c572d957befa924701957000298c4acee7c301c85683114f96731875c7ccf8d1c67d7806b843140f057a84734b969157f2966f68596d2e777b6e9101bab7e5e215efa2c16081d24858ad3c2e832151ce9d8d037444e066078fea590574298c73ff29dd2772b350bc95c9dff01f7a8696a4a6e9c65155852af543dc756ef62cd2abddb19a200ca267e8fbd03768e5618817f40dc2a6f1ec45150d856ed131d46c9a6adaf19a9ac4445b49764c74a6a292784d6de2325d9324e19fa087a84dde888ac52f51533fd22fefada82615559b5cd7a97bc61d46afd174681ace344410f4d4343f6ed1338fe4838ca7919ec60424000441a01452f8f154d69e9aaaa8d1666c4ad3383d62ecf3c7d17fc450972601a24b744c915a83f0082a3c8d271dc6204174580149891105a110405c25741883a800054200319ec6244e2f40d2848d0ba66a661cb78e11bd70aaa083b516afb0788deb0842a967169ec01f09bc0061d82a40c2046038c2e03ab88ceb8c54e772d2785d1876eb652d86a9986853ead4bbbbbb3f4702ee8cfbc3cf0a8f7cd499d6ca82ec89946cb56a619c1287cef4c595d65aff71b390c2a2af2ed18d274ca9b121464bd42d9e26e76a85d918f4f0d0d3c3c3e8299c9e6ef5e0ac56ab9567c3f3562b4ddbc14385094f7cd05a6b075e7c20c1627e5a6b39841449962b2749cc23aa26282524e9799ee7d119aab3e309c93478244a0025144956b4472b27d414249df1d6553eab758d17293c57d4ac2a3ad3de2354499e4ca5195a928eab91349246d2485a95ab7255ae4ad34fd2248f409e48484574828c438a189d8c41c62145ac56abd5494de7399a3facc6d509c6d8349d3a72498ebc7704d8cb28f8ca66a8cea7d0353448cbd0d01d466ff452892c91259205631ae487d2905211a5911c499324c91a42a10c8436e083070d3d42a150284492a927caeb254ae45484f49ef968d7f38f86f9ac7d62163e97826635ab594dd334da1d734ba552e95dc1cab2fbddeef77341462095600123e89a175c4648d35c3d3c55ae3b991052a74898f530cc285f28c153e04678145fc251a46b4631cd9b8186f92c468f934422e517722691346d070f179c4a77777777f7aede1ca5949abc887690144c24f426ed0799fbf943b52ccbb22caf4b8b5ad6b2a2ce28b5274935ab939aaa4c52a9542a954aa572ee546aa351c4094a52a32fe2c4893412c1100b5f60b1969563a10a7cb5b004ae496a595b50026399c6f5ff6421dcd6a2ad90b5907a98cf57fb52a48ff42454288a42b196f553dfe2add042287eaafc944d7d2af5292f371312944ca3ebab9ed37c7d34bad68f8528b85d86e690f3c341f4aba74e0b267c7d622d3b500e38a168f30d34cc58ca06a7b0c32e7767013c8ee3986b78d5fa7d8afb5ec9c37cd674c01555cb0759080277e832b496652dcbb2ac652d65144192e5ca4912f388aa094a094692368796e18ed13e5c75d0198c1f80379017587452c454872ac791cb95640c2d43438004e1cffca030ef425ce603ed76bb9f9bf513310c046088816878ae76c7e7a6af78d4ef668a1b5409b502149193c934dda04c138599a6699aa679af8d1b53860e7ad5cda3c70668e8a6d775b917b829752170a61fcd1887563ce86ab55aad78d47aba529038d01ff61867173dd0a104477eb0d65a104c65daf54e5afeb30603b30985301b1d5c8a7a201f6d1c8805284001c228078866c5c84d9e032a48ce491afe7d3e2f290c0cf7f9690c8c41e1ccf12948be388d72806c4c588dfa5d28401023ee5df80ce47918c268bb3ee0365d7cb5b68f9447da47c39a2c86ad5adb9349a8ce94a73bdb7d9bdfb66ddbb6bcdda6792c14efed981c83f79d7b3d3f315a5a71ba7165813fbb3cc1a2ef34cd969f07fc7da287bfe5a7b67d94480fa639e557f48d2cfa86155e6891c2c165ada67d626bd9d5b0ec6adfaf5ce673876a012d4183bfa24318117eeba4a413cfb2e8e797bfdabe5c6ddfafb45c7e6bcbb9d5e556abdad0228b89f9b39853df2a0974bed9b42ca3f289f77e3e11e3eee33e31b75a1c07d6e898908d9b8ed9c1e3069cfaf9171f4c96144b88c565064b904abd7492f4141c71c4e98b68bef32e84e5092c9fd862884159348bfd84e513fb0cc72c7379cb2fb0e4cf083080ca27e3dcd2322d9fd8397896ccf26d94a394858585858525b3b8cc7099f1c98d9f252443c60aa8c683a18eb121dac183860771721e7427722ae2a907959832be33a2d66aabbd31cd9badffa7c09e6f9ae69fc98366c7d4d4fc0c5a86e6b57833090ad5738305169dc6cdd987606b6cd3b80adc0c30962fe87234b016b4125e1f17e13379f0632c0ec2cfbf45cba85208038b7ebeea513553b106d488f5390163d96607c9086db6f92b963021e2a6693eabd7da0e862bd3c00f7e06b984b7090f839d5074d62545665d4e9e60dfd9d1988096b33c03368388c27c773842e7953dcfbccec3bc83713ae974d2e9a4d349a7934e279d7daef499fdc8e4fb890f8f74b9bb63185823e482c4464130c46303363616134ada41d0dddd6ff0d07bf0114f8e0ffdeb4f131004c15a59250a957a2245c9d9b38aa2e2426b8cbff4b07bf66299a6699af61d0e2c7f56bbcc65b15bee99cacd8cf33a508f34500db31e7da77d8ecaa080b32f14ca26ca35bfd84d09bb37a29f348d4816ba41a15028146adb68183b1b60ac29d87996251d3a9aa63b555452809df4b913bf441be91bb507e572a6046dd206ba59f4f30ec1dd24539c43601d55879f5ace3e1a375aa641811e693466c83ce20c00b0e234d241013aa91110da8339caf2075a4223d9870348619ef6608eb6ac65d1f3c126fac66e6c422ba1c15f3dc10b25241fc10ea7ea4b4c4cd5a952a2a4c7799ed8799ee779de7b73aed06064b15aa723534c52be54e4c717c2627dba4fd77517cbaac0a2b35827d64a7edc7d3eb9eb3e9f87f38ae7173d29fd0cf9e17c92c56ab1582d91889e8e3a4f2ae564b59a8613f2319a46628d45cf9375b2ce2d735974161774c5e4c1a74d5c8687929e22ab7f1485d1314d2a53ca4404f53bf74fceea4c2c16cbc462b1582cd655a38edbaf149165fe2b58e5d371db0a56f9749c870516a909cb70b295560aadeeee6b93650765d9b5f9db319fafc96432994c9a76a2678f55e7b8accd19e833c34d7df4394ef843d163a1891e9f50f44e9c448e1a7ae17b87492c7a5ae81e9d494015de0cbc2d3cd149abf644777787e82a1402c19cdbfd5d6afb1158f4540a0473f6ae86e323cd5d9645279908d08d1e0b23984b8c48b14003dc581c0109967b7a1eb4f91b7d39b67d46ba8fcb9a566d1c908d38fbbcc44ce025f0767531d40bac7181dfc5d00fd21c4225a1b761437ed5cf895d951281205523b50245adb56bfb05fab073dc0812518c2320da1045463c9e37202ea8afcb36713a91669323aa22292eca9e7b3a7912272fc36ac7dd8ed3a8f0b8ae0b39bf3714047a825fd0a61c271dfcf9860ff866b7375eb361b96e9f13d1beee98eb52b400bb0ccb1758ee220446084ae8c6bca75396ed18adb5d65a8b596b2db6c1808a2a701676a1e88516eb70703178775805d8731294babf2021438c9aa6691a160aa5f22766cffb7080bb58a5a0ca543e1df7659fdb5d16168c3d2f6710bcda6adb6a846c885eb0710087459bedde2d9ceeacd2dddd38c0526ec011515102a8e85bd7759f8822c5eade7bfb2f765d1fe63baff3c511a81110059cb45062b4b9d0e2240fd2329f7750e94174538ecbbc7773c4eedbb13bf7ee6022d1cd329ed389349b1c5115497151f69c4e2b1b9b3055390cc36c9aa63ba92801b2d1d3eb7ef423d2ab4c0394427802cbf7c222a27f813c9d5ab4568e0a6b4dd3344dd334e94c2804821e78c19013312851a31c200ad0190269c4e3194808053838473c5a1645d67e8f553162cff1bd9c7212e6eeee5cb6a00fb492d0039eb9bc7508702f412215f61224ca5026ec25488ce193e4c665ff9c84611223b9ce45b6c8d8ba2772022c3ee9650042dba3cb2d1fa8613cbb69e24fc5cd2fecbedc315e2a7925f16710be8b5baed7855d6e5a1b1bebeeeeee9fb5d7755dd7957178c92e19072fcfc88fe401a4977170c92f198719d9cba4fd8e86e7195eb24b9ec1cb335e5cf2f5edf0f20cda61cfe4cd57758c0a26f6e5931be80554432b096dcf0f7cb8c16867809e04b9cc7814280c7bc44bf2c12dba00038a49924f3ec992f1019062b3eeee16ffaabb6d60791865fd70d68f1387fe1d8e6a2ba537887af402ce0f51005a851911dd116a02d0ea23882602167fa2a1070fd66a87b53f4c2c168bc5fa11b2f1e1a1564abfd5067cd46bafa555cb5b7655bb691976dd5aedadf6baf7da22863ce6ee8e5dcc8235b831fcffde7b5d49ca2ccbb2b274f7a157d7d5ba4a4f728328fa0676c3d6ec701922f80f2e0dbab0fb6291893c51c64cc6fa86a57d03cb9e9b66a84a7778749e0daf2357b0539e1efef59fcb4d5c64714583249779d702085307a1cfb235e2943c4cd96a95996e19966559869ab68347c912c4da16ceea455d6932f03ea30116166d1b823ddb8cd3575f7d5191c5b0ac0a1004310631884bd6087a4813d137b24c81f01f7c6479211c08acc9215d7f307a66253fdda125238b0f454616df0832726733686615460d819587fc900a9272313e2b327056c99fccb29245af594dcea8edf0b18a505dcb5a11f075752c2cdb2643fb8cc8f872808cbabc8525217564393b060c7c84f0b38a11c2cf1f28210dd2cfa23b40216475cc93a592e82caf94eabe3f39f102d327e7833db0582c168b755d66ad6fadbd027fbc2458ec966a478808870b85df753c5b48bbce092c86b4f0e66f5c81b3f01ec1622806ec490cfebd3871d3c239b55aad560b27f582eeae5d5b2ab5f4a2f4ba905094124a92a5cd46391b6b6da8c03603010720ec254a9284b69b408f74ae6cb3d8ad1728e0ed72047001fe2e5aa1a396ece0e43d95dba8a0ff1f23def702fc9f93f02181c56ed510a769bc898ea9a23405141d128ca309383bea055224a2244992f43728176bca759ef8576e93fa5c8434112962e3505e08bd2e6e09ced12a702a7c65d246d3b4ce33d6c960f34b16d8412fa105d56e0277dd6bad09ca186a6e7930ec0e077e50088c57f0bc9bb13cc3fdb04c02338e89c88ba05bad6e75abd53af2048f154eeb3ccfd3da8eb91e93acadd553700267d75ed9fd687099bf9db59496e06cb55aad160e86854129a553f0f6ff5448ad6507b81a241403096fadfd2ec77605c6e1f770db82f3dcaec09e4bdcc39bf252447e9ee779f6b8ae2c0aa6b5d65a6badb5ed3838f7629c7316e1d0999c5bb9955bb9955bb975b3ad954195123aa71c209c12e48887cb40424490608d78b454a9d4342dd664537466465e59242bdb4412d65e3bd6644ba59bada6597b5df6ba2856b14aaf6bdbecc57da41691eb889ea12814132a1e1b2459b52c8acedc286090c242c5c406255bea9824d7674976b4452c59b2da05f9fdecc97e3ee29456ddaa944e415114652d2a8bac9106515e439f582788405116c5836dc1684b2b9bea9826e7ca96e8ca96ac2dd9922dd9922dd91286995e13ce28986952cfaf188f42dd7b31db11d1fd4cf4f32c014785f0ff47f03c8ce1192108660e1411423734b4dc619685e84cf9284eb4ccbce9cb0b9ffda8042e3b5ce9900000000001c31500001808088442a17048342295b7b23b14000d537442825e3e1b4a849124c9d114a30c328621028801408000c150892c2ddcd8ab999bd4543d9452a28be475855e6441efdf869a9c7eed04c8b24feead4d784bb5e98b0eb34645472f2c0aa6a5cb1e45c9525fbb94b0cb7f78143c9c394150da8d0fb07dd83214b014cbdbc732b77ac29132d9d931009fcd1a086ecfd58179be1a213dc83a3c45775a5bed482df17138484987626691f016730dcdd1047c6aaf9a6b54421a328c5e79562cbae5dd98150d7d18fea05a2d2282bd9da99e3b53515262afbb684310daadc2e33b5bc08160d9c1027a6e280a71d70e120f70c43c48f97d58de2761878cdd226f85980c9a9e93cd6f7ac287d8fa75c023f002e713c5b76ffd48b5ffd85062a200daaaf1e0711042b3a8126bc2c5640cf13778af074eaa29f81fd4e241a49165a50e9f539d751e5c906d684d935cf592db0d35020ed627c712ad834431c04ac64a13f7a72aebb6809974d250527c7c41f7f427597b5cab489f7c2631f34e88cf3ae4f42baf87af76ece5576c5bf0b49233e4484a6fcbc4d814942b2a9c99f313cd00d97a5482901a68aba5dcd569425b9da6c8512bda8a04f531448d64143806f621a0b7ea653ebb21fd1296bf63551cb58412662de6bc64232558eab703222b9166339d28217a538498d8c55f451fd8d1af76ed151e5d86b2ff932ffe56c4c59b4e0610aa12840804debdf5af4577aec948eb8fa239b7f47fc6f92f4f9f5753b41d7a0a1d653f6c4625c01e609eb15af69727ed58b9a14b2cf2b0ef42e4cfc1312b79cc6a86359867f18b96bee4cca441a7ba31888c4c3ca6784cd22a999a54e6700f6238f43715d7c03c7c9345e2eda3e80047325f9ecb2c8e083dc48427a206966e39142e75cc1cc5a3263331e9ca51639ae5996b82cc04e58f19ea44f3245cccf0ed4bf25b31ba3103ad980316cb264fe8bcc08934ceac860f64eefba4d5969aa5c18c1d7948e8424d9199def6ab0d9a1152cc7d11fc038e70364293e7f79e80d20d7d2f823710d1549f325459250e8157debd11b931e82c9662e4fd850176a1b6be3b6c7d3bdd29ac108fd47ef07dbf639aa9fb076792061d28b6dd82aa88d417f2c7bfd63498e3a1a9818731ccbb2b967def42f8bdac8fdd6c19703c113ab6ce9e2e2236205166a3a77f4f01d4239b635650920adc89154b0d635a23c631fe10436de96ce08af2ca3065bfa1789a704e79d6c8cde9cd1a1923d65fa01e373bf629356c1448bb36329877ad885d023c5b4dcac57a10659764699d3e2f7c2c3b128553b6913ac4f039d903de3a342227c0212916db8893c904313ff3b5a92336f6b21242afb37af5c72bfe908db124646186a3fb597694b6930f12dff4a139fbeebd09a57638f42aa3d5c33258f8565a29fa0915866561aa8e2da28c3761ad2884407cef8e13bbf490ecd17d5fb1be6bb9366b8fcf79418540bb930dae190e431c90dc9d81a97ff9f5328331a95eef4b243f6efc1e13c8af4d453ac47c1cad32f35a98afbdb4f5303d54434b73a45991f9ea0be154d7fe48a9634fc5f5104fba3e8209aa723ade8f9ca96ca9c2bb4515f1128312160e910cb9249ee7b93b105d91834d27c25afd9ec80ca7d056b381a4309e6d30d258f92cf6059eefefa98d76324424840a08b839113193246ca59d296b6819e6765a3480dd053fa0bfa54a876a85bb1bbe512c7c105c9499d51b7c7bffb46680060d06dfc18a9dd4b735a6366b41a07c84124ea9415ba8dbfc6fd31553f857b0423e67d215f3b52a113bf8348f4c407199978f5ceb1a625dfbbd65e570d5485b6eaf5a58597b2103a2b9092ac094289327835c09a18acdb282964aad6e6e65be42ab39e767c9349b9fc89f96a4599b857c6ccb6f70d3b8f260017f8b9bc50ffaaaf705bec76082e2d52cf42ce46832193772ed946c0d51f87d935ec9517a2a1dd450760926bd0cf24167426b79cab2e456a44583a3a89de85bada3cb5f48f567504b26db24e66c26e00e01529e90cb19c29375688e776d1f7397e4739dbe1ca563ad4db46de9be29db682dc5068e5d8b1f1c944094d5fbfc52d08e9886a38b2983efb848a4ba6dd9e4ab1a3c6b5bbb713cc4bb07a21f13f378c9546447b40b9d5c3764295d85368a96637e3cab8bdab6fbe0f8bec7eda54bc205bc2d75953d535cf8a21d3b812a47eb8c76f51bfea362c45f6c87640d79d2bdbe392530fd0d22233d802a058b8040a129f1b7f229457e0ed2aee6a385afdf7cb0fe457e1d320bb0a90068c6b9f39cddd8cb0c7740ce68d61e094cd3358ed99fd5293a661d13250147381caf90ac58f5bb87ef6cbb67aab2e7156537593eab8f1db81a2d33f5d87d3d1046075ac7858f336c9e4f54b03065585d57298ea3d6a206b5db8de10eaf2ea6159684182c1bd447c407aa4024149f67dc69612c511fe0413d63cafbe347419a88e88922a901567780a0174a07ed577dd760886414ad95eab06d2f1b01adc55728ba22793c45c155e69bd6a40fdec8068107cb9e9e97518ffaec2545a5c3074c384f3bf7e14c80a691c69f272ff146ad861432a21a8cda43a420e1f26bd1357e29e1bd50630cda39d6c6d58ae035c4ad6120430a39c3d2d08b882463e094073fab43fb2905a94cf4a50e6eca31c4b0493857b59174a84afff3f07af2e9371857c2c53c523a93d180eb59cfc3e1b56f35a5ae0e377840be332dcf11f26041cd29ca979a20e84c27b2ed612a9d4bc3f00f5c4fdd6e8fd801bfa3c0ebf2f7e28c4f406a5f472558a880c2568dc266fe86f51c9b9e22e62df55e1b0ed003f5ab3533641e6f0d7842bd1b0776a6cdd7d63b21185e4f96ef84ccff8611ee89aca01daff09e941101c89de345514507acf9635494e88e928b08ee93bd14951b00416b84d0eb61b10c1d2f73087724c45d8cdb374b85bb35c2dc3fecd85a230860b1093419bfd64dbf293284571adfb27bf951c70ac945e9a5f6b54e7917e025f16b1204595ea3fedae44f196ee001af608028511be53e9f613e9c844dda4741ef94333cdbef91f0f16ba810baa132ae82c70597166c28dcfe3f0d9f3bc01f78f62ea20a0d6358d00e15e32783a88277903fd06f672cfbd3acecf5d7f29bab88ea85b3498e12827d984e489f360583fbdaaecfa6a6714aa7d21c8f23334f281ba678af6733400fe9d11e5e25d0d1ad1497716a3587a749076624f81178015bf47cf0106e6818b828ba65a2a287ab12398b605e17f4e97576db31c709d88e8a5585b6a1bb512e628e73731fa8d754677cf6ccd9e9950874337f880ad364826df075a46ee444ec74cea06b678132e273041644d8966a8f6368390a121b8528966239f2ec58e798a9fa2b0a8b5e04d9488fce37bce285e27b803237a5c45d382ffafbb3a0be967a2b126917e219cb090a06de48a5adfd84f623b681742e860197dabc1f004109972f51651c495bb32c0c4a9b93eb99a331cfe8cfdcd4df2eb753ba9c34715886ea2f07814b2a7e633e0bf1fd49e6585e0e07e68dfd1051ac0d928acc8a21dfc91331f8472792227d6d9102c800f8f1fa35dacf9cf3a57122b5ccfb86489c049f2c6d27908adbdc1d3aaa36f1d4157d311ff0003f7c2baa78e4f4864161eef5ca101c97eee9caebae37532cbc6b034f320ee1780e3c626cab2df674bc978ddeb801cf5232133ff18bd52044ccd9ff0912177a1cb610924c1ba15a2d31a35b428223c89d55a2227e2dbcc2afe5c4f835d8e658dd92403a8730d87b9f851d70f8a6668efb1aa091b3ae5b9cb75b99173432730ce5e2e6ed66c972bd3085200b8bcfc257aa77cc964f483df88c311b89b2d19606fa6dc3b7953ecfdca90afcb81924870dfba42edeabda6b7898530583e060c6f27164cb67b094a2e3f60838c84afd8e95a5af628822719b919b1f0eca7a68046ae16bc17940aba218da2401ef4ae03d0ccd018e2808d15a6b5a0718b24e6d4014e303f3826ced880eff2f206ebfbaabfaf8588c3c2e623f2f51bf1cea41e7e4c7a13974921a5f42b346b01759346773c6e704e313999fc3e198dabd2bfc8935e5307991f1253156dc2a2c9c516f3b0d8e8871bac88740b3f477356c2160cdfa29863121b5d6dcb917415dd70bf50691224a16809f09b104b0ffaa0e0652c28484274c198be2d0e36a948f873f36c03133caf074bab48916619934d17319b20367ace9ced6e2505ceee5aacaba9241ac2fa4d5a228ce9a7192fa2b7b2de3581f858b11ee84746dc640b9d31403ccbc34194c1d59d2360cd937da21bf0e4267503cdb2e8872c9554f209116b6c60c7d0b15f0e2c2f854088734cf646a874709f241d82ca9c0e6c1ec9d90be5d7cfba4761d64520719a94ead7fed8f17e085c0dd17115862d334067be0b9b8e4242daf953f16b8c9cf1108a940b2788d7138ce0e281b20a4353b231744df56a1cb8c97af32eece387a3340096528af1d160b6bc4d2a1354adc74e520ccf3cac1841c0662c122b12ae26ace04351ca9657dffd66dbc59bc0434e5e4ea63b1a0a49fc7bc3034b8c780fe46a50c7f8c90dd1794df8c3233b61750f470c31005a899268ac887146ad8c11e16df532592c70cab5459eb768ac26a80808ad4d0e3711c2acfdb21a80982b5ee83354b2846450aa51cf16c798327094c5ffa98a28266571992ee3929c06432fe51fa14ef291452e77c8c32e18de83a195d1cedcb151281454849890fb730ab7642ea139bcd3c9a329a11fc002aef36f923ecb0c664112d8a557dfda6eb513d98fb5b6e2254d1364a788197055c422ca8fc1fc917d038c170dd88d7a7bd2d9a1909e1dff0695f854635fc37cf9f03a066a6f8674b48ec80253b1b33eee4cdbc32e8cf5c7663b06942f0103495ef4181f79c00b83240b5d7fb635d31a19db5ad1533d78ad5eb7f5031e779ffbfd13b46aa49088b8004b6d7ae3a15b8644931ba55e535998fc83cc252b1d1ae62eb713e6f94c492a2d9fd6103a2b9d77e78fa7588ca6c6b4c91b26a3ec974954fcdbd4d362ec644b2bd68a7bd4ac95343f73d898f26ee3c1c358fa5bc574b24ba47094304be79cb4da72e345b8f33678a04129f6652e3971ff22047e77706ed21b38e44113a1f8a347582dbc64bc4dcdab25067118a38c438ed952a323a9f83a3c375d5c5d75544f0432c7d416fa6d0919403ca69756272566d0fe9052e013dbc2b5287add033ac768518eeeadcb7faf3ec4b9abeb7538e2b836f5530a2fe436a1314ba486c41bbebebc2fe6ac95e0f6d7e9ad1065c1793100f255eafbc923186230c96ba9f2afe0f8555935a54a542bc54c457755002bd6c969ae0006003a0f2b73782b98681d45941b3c5d1f512126f253e1a1a03f249e0a9b59d8c169ba8ce5caf66cb16c74fec5e74c46097c3baf86302acaf298b6434926e9d337b30e5247364e981e2250fc4d6f2a4e5af3a59ebc51bd6382e86f35831ad7ca7ba4b6a95c1cfe746325ab5569f2561fe53156622ebf91d08a3c377fb6425bd6b710613937c0436c4ec796cc1c23c032cb9fd4d8ceaf6122abc18169e34e098331872e81a7caddb273a6af965b56efa1bed756313a8f8ee8647f24909599c4a2196542a0f96685b840e6daf1848b4b1fd9393409d76229d402340a325f6b1ce00297cc4680b79fbdad7c8bbd341cae7c95b92c1024ec2eb6f4976f669099f0a4177828589554a1e6dc8d9f47b9164aff79661a1e11fdd1e310d2933b224bb08ff5a86250b04c7f6653a0ab6ac9b1e93b9fea3ed7b3ac9c76112fc240ca3b78319fc140efdf24770d3f4306d6a33b1a49bba76db61c478be52fa4cf948fc51a6a587b9a27288a5ce44d857c3f047db005c13235bb79019d1fc894db43914083c9c90a2cbe950491fc22a5fee2805ca40da169e83fc1e6b82f5e459abb1dd35e1d6600c3b4d00f973c77325b9405b270ff2f55ebf047aacd26df7c2139698ec5bebb31c9037c183f299d70e35e8340072f4256dfa56d93a14b9c851f40e9b94b89790533a4a808beae3c3b83d08d105656073183c34f863b8f48768bebe057e55cb5be67a04f0e2d7ea5a99725de18ccb1477a74fc87ccba2915a16a593d49cc52687254b5ada3b15f61f9cb721bf1cf4bad678c2cc2b343893f9f0cdfb6566b0a14623f601185b809f957855b7a6f7a6a6544aa9456d3e85da043b47521f0b60e7505b0c335a73b5fe20d9301c668a083dcc442d65dedcd77386ef481be2c844d4ae8cda706627c9598a6854c3c77a6e04647e320dd7e887a1b8466f188c363fc31f9fc94170fe55b210d6b80741c1fc746c954dd99d836399066470e0fd938428a7e1780e1f4be40426d1f529d7626584d6934be930bb74393fe6801716ea34919cd327c5849e2da71ee143b1b134cfbf12ba1cb60ad5a49a9d80e72c4de474537bb21d27e0612532e872e90de18a426b08ead20b64bb0086325754a02e74b95cb9a45dba963f10b630d5a15a6e4c09581100aa30b33093c4098fa8214362fb676e06ea4cff1310b4d694b05b760519e5570fb1e522ff088cd2aa1cb3731797f6df1503a4bc0a7857f9086747f6de797278dc203b5f463c6b8133217dde9d1fa50e6cb98ae2b6902e727512fa332c0735b6dcefb3e6144c3756e2c69835c79b29fc05a15140271d86d973cbbd5005eaee72d9724048ca0b05bf6839488fa1e5002d715a943d2820a65f1a58e2352b55fb99f9b5f4e492a12e4c3b0ba06648350b0f240e0ac455abecb750644ec9064f7ce55073192d2ece691d217c3507705d6c7c61524719e9ca3222f1b8475912e4ee159ceb3b798abe032330945a539458135c6ab713e67c7184f0260702683d2a8e4c0b13ec223d61b9bd01823603a25724e2d174eb60681b8bde11de521de241c8dff470f782bf55abf5128ee0d3902cb002c74c5cae10e76271d6d81fd0475ecf48e551628ac9485143393589e85878c1374c6f24e2247285330b599a56670381222b54e57d3c1f38eb00e8dbe5e7046f808477978bf0ada4a7bb7be62b1c9aae02bb7934731c3be8c964805f3287b46a2ee216e66d914b916b130d063616a6eb1fa44d004bdabbe70860859c9675f89fd5978a6a7d601a8a0c6c1fae93419903aa3839e24ed43ecd44a80df420364e7ebe333a295f95328ae6f9a3fcd908345ad595069bd72be9058b281f33e45bf519c5f1714fd39b82e473a66ae4098982c6b7cbbfb7b30d949e94624affc426e449b924d16cb8827a640bc76e18b170fa8cb6548eba488d5fcd4de90ebf8437427ecb2906e65b061d303a29e66dc3fb44902e69ab1836a86207e35841309926d3dcf3a3e6b5908c1f1521f4fb9c34bcdc203d796a8b0be8a385b92addd0a36b247beeb210c0eb8ebc2f48770fd299055864fcc5fed0f37d0b0c8992b6c29d2c3af021779503ed1aa89ed2c3095c43e2860e50491439c463b290a7138035f51df94be4576dfed226544362c6aba12f8b37837952208bb260300e83525abbcba683344af6f7c164c19a472ebe85f68c54264fa30114a9f12395e88ef9966dd6f0ab5d1d3bfea1e8f8e36196769a885f841a27980dd7f47c0ccadf58434f82ca748728cb91a525f466290c34993462d9a71e7a47f0e5bc3b2303be19588d96e1b89b8ce24a114da4334ece8466647034c093855ac8539f141cfd72e89a0de523cd72f2cc65bc1ce9997dcb7291c4424ac7c4e6c2e1a5982d36c6279fc3cf437dd149b5971db863aa414fcd673c84b159828a1e9fc66412c90a70036c181425d6697b84515b11df40700f9d857f1026f711c71ee06e94e86c476ce1cc6cd1b81cb8c69ff05a416933e06d6d3cd18761cee8060dac5cbdde9d9f067b4d622f39e8d3f4c221f343f8c1ecaf2c6d5b9287ce4dd85e43a99148aadbcba7ad20fcbca2908c27a0742b821aa2fa84ba5df63795b17ab7a7598b87fb9b728bac19576f6d9a940b44b964924d82e765fa33ad33924e0db10393f5c19985a36f3c0faa42717072f9e2d9a34e048004167c9dd0ed4f679cc12158d91466e08be8b694994c934acd82e7d452a9cc2b4408b084341a74443863cb6713d2d378627414eeac776fbb3cd793d76ab71abfefdfca86eda324276ce779afd6bb02eb8a6a8f232c0452273f73bad5729877460ebdf9a663ccc4f27e7f559375d252d37a0519b1fff036b77863480d83f0a2b529506d045422c94951b18b221a269be1d92846dc607d0da70589fcbe88f9785c6e60c62f37a940f889d7875266054b07a596cab30915957ea5f201e44ac5595279d2cc7e1565572481f395b24b2bb880e722e3d738a166a4f213a06ba7dd128e1580a5893eab2614b3fbf6d6db963071358cd20bb2547aadf04537d228fc6d1a72baaf4ec38c905c04a770f0b236433df01584455731321862ca75d60ee4b5fd7f5ac9ed4380ac7d113bfda8f65de0d5918109bcf810a3b401340879b4f4e9571b2f5c1c9fb1a71fec99ee75747f6b6efe9a9460c001ecdd2a5ea819ac85a6e5dd8886937de53d55d81ee982bb5d682b3c0e921d8ddc94d7122499950407d112d03d8c9310e6cb3f58e7d31a90e47a6d7a729fbc425871ab26da749446f36b70c8838088a34c3dbf02748996daf5b45adcf85e57a88049c85b9e71f2147ca5dc3a8d2e6a1f84b68bea956fa149ecbd97b822d50913f41f6902d4c58823d9e3ffd03a911d04ea493690bd0d4065028fddd9c3088edd487b5887f8588cbf8b70d88a160cb90aa62536b6334c5dc5001b3e4485dfd4b8de407b1537299bcf6c36492d7b03762e3122d59d2fa0a610e8d4067a0bcb816417b52b34ef41807b65fbe7545ad51f11a82b4a395f498bd87b90915b19d7e1ecba217de937d3f68f85b0e23ca03438a623811b25505499286c3d6bce49b3bb4fc701d5f45d9cbe229b17ec6b901214eea6c5bc2b28e8695a111e9c8e25360b9dd536b29193ee9683ec8101c3d02276b85d7bedc25022a0ee8a5feebe209e568e868b66ab75febe44352b82e8b6155517c89c4442f265a25c38466a0fcba093ca29c4779b4a8886083a39ce39c6d6c836476ca3d497a43c7fc9621e5eee377f5b295b9aa40c0592f460388ba129eb18683a861b447f8085f42df80a4e58f068ed7df32af9078671d953e839581a456cca4d034aa923db9bd42b0723c46198a237c0d18cd6a6481e08edab6fa438b4743cb2474486e4b8035ad6fcc4530c03068da1c04d62c472b823f2f11d7a5e6007c84b2a93c9699e6696c29ae5d0a4937b17d0f4344053f481183087c2bab8fdc5b87fa62873cd53811d911e598ef194408376707b8946030aaf60689f790ee014b8de67dee1ddccfd149e469a9644a4a996b2f8a7a8d8ac4437209bc8df37ecf054c9fdcf2eb5c7cf87d2e477a9a540286e6d821e898f2ff22d5bf63bdf879db340f9dab9ddcf984a0d53f1bdae520ce76cbd19d5efcdf1ed36dfc1259aa6c202494bc4e02f60db1e8cac542162ad04efc1b77b4db45a73604514e3519e65224ac4ca4fcc4156680bc0a7804ba455c8f673070a4c3fe00b02d5ebf47598a635a18099c18da48e3c5fea6421b6711e9d211b437ac2ad60ada11d3968a7e729f6850e60a06c13cf2db1d17cbb4ffe5905a41f877bf454a24909238447cb2ff6f60497aec953c884b35fa82c4496896c765fecfce8a2e94f8d4fa7160d356a1538a0d87e80538f9f0185c38342c8e0b5a7553432ef4185b06dbde434887f6b2f9dee6d0e8bc59a458d226ed979d86a342b2b331133b72d4e89dcc152da2a6952ca3f67ca0b678d34b77dfca91654d5b45e3177b9f2888c8760ad99e99bf2a21a05dec8a82e574b1cb8aec136f8d9c58e1d921cbed385fd5ca04cd98b20440415916e30f2d38c211a2d4bb96e82191f7085c495f65fc599f30628ed0426078bb8fc2a81eb485213d6b9b8e3ef5ebe8d3dd2d2575a11597e50e26f7d32a4c50a9fc762a95f55d07b189f4039af12e4f3afb5d1bf642568007b70d96e9e93433b306dbf826f8340fe257444366729197fca98c1422e64943d46fa4f36db1e819c3096b59e9b24ac4e0e4940943f6599fabeefebdc6d14eb9165edb05f330ac5b6c0e27d17fa953c96a2fe53908b8d88c4cf76a18a8fac1641b9172768f611a7d3c904c7d0dd0a0f7f732dcf78983d1f7debefca4b0695f1c3955a3ea6bd61561a01286eaa89249ce4329ddcdb6bc11835d5b09b4072d14d2b1f75addb4a908b39fc3ba179c6c23d89688d4a374e8fc4a44bd846400cd0e57fe0ac52c3da024e82b94c3cdb084685e028256418cd8d57430617c9c14884bf877dd871c74ae9498bcbfb9173d38722f84602a18575e2f4185f5bdf44c44ae305019471ea44061d52c08564f9259d3d73d328a636ebe6132ccb7e8d6b6841c1aa00c93f177c4a270b52e3579bacb8c37d4badaaabfaa7758afdc594a2d09cdc02f66d89f03c780e3a001b8847aaa2831d97c6cffdefaff8eecde42659dce336870af544a12a0b1d58af12e5886ea048a275e4a25cc01c98d8b66f2fa2b5c774aa18528259788466897d323c54ad109d97f05763c8e2e1c2ccb7bf7fc0ce200cf596c6b8e28ba55666e0eab2e3fdfb6d5ad00dbd1ea6773fc56cea76d806a02ee0d8cdb632039137e56347d69e18b46715a5f4809f6200ebeeb8dff6f6838acfeb260657f58ecc0e0c5e6a6884bba4126c68485ba31f37343ac04e89e863c893f129f3e92a14acb844976f6175c01472b24c56d270116c7a72306c070b99b18822656006d40253b1a7428fc5b990b717c568bd05cc7b11f1c13b9c2907ce224bd32ec89aa9c891999dd2526d9addf0734c78465186b42accea6778b5f06dbc507b27886c515172a13e991a915e7c7f95d181b30d20a864f7b7c3d8614c6dda8e1475be097025355c8a49d671d9b46723200eb0a9658b803676ffd2d575841afd2336ebfc1f53ef211d4043bcb34fe88c06aa0c446706b8b3b2283671eb71f9568e39e1215ff4372088d534564fd3322fd25554710dc387b47f44bc4fab8e1b6c707e9980d9ff268ea72f0e2afb2f0bb70090cd1b0c94b3d61031d64e7d23110b6a846b26cec0b5560eba1d02c03e54320f19aecf6aac4aac952585b8601800acb40271a67fe84c7c317b3214d8ab36dc2728a8135a780278e48de7475467bb39e9b7343ec8f8d08ae9532e8800400c6089778d57e0a12a7cacd0a7dc5b5f880e7854073ff2109118c9dc04445ac2f0e7ff78b4a559008c6ee1b841a88c8d906b00ee5acf97466ec723495241af1ecaa9fe5b87a7427bb9356bf05137f80345092d3fc339b623a826e6d2f28213c83dd1b95032fe22bc7f2687b2c88380ac3ec67ef491b7dc6013b1ed877371b72028ab0a506ee4d36250438335c1f7f3cef52435f7f7ec7495431a1644f5863e4d1a4250d60aa2b5536cfaf7de04c51abd4de05ab98d7869d64df4242174ccda7d22ac7322379e4d19305697244e5124495030241406573cd425cc4ee9bd4d57c033f277ffaae35fa1096f3d96e4eaf36dd302bbcb80f64ea5c4a7978dcb8de06b1824c9cef5a7c72d741f6609c0c572b2a65953f24f71cd42bfc7d29a019767b7b5885e1485bc31a8ae30148020032cf944c79cfd3b100d76ff7c99ad6641b161f3432ca1d70c5db91064f52f86f977e71b5b5f489167e5ec635081fe9584180a5dd21855e35b95e53ad4f8d6b372ab4a9a39a6abfa482a2d19256d5f63b837c4f3188bad3785f4514d00a699850f37fcf53708d2a0c06915286d87adf1f5bf8d355063c7d605860e73e537f15f4806dc6bc08d1093b77a6025beb459624ed64e539ed31e95e8ca5ca440c5c5193455a43012b7885cad713249cb47ce2846c0283a0c490e6880c57beaeecdd5103e99851790f4011afa5f325e235877a5a0bfa96d38f535810f688019782d41a36f358e4265466a0468721eecd40f8193352c4f6aa20432475984255634430b6663022534997844970e1ef01bc69f4f63f2814369d2f745cd6dbb6089657f6eec3d081850cd36827b73b8fc911951ad2b761d81dad57462aedb1102365ad864f5b7559b924e0c086b05d425cf2bf8d36d99cb56add289899f8a7153e27c6a266128fbb88abbb8ee24c4f8f455645177cb1c9fafb5a549f95cfe69970c3f9771e732adce75ec10b16acb8b716e0f22481889b92b846525942a72ba408a11c751b59aa81c7504123e09a4162c554dfc0911ba01c62e4434b542c78fbc35f576520ec9d2115e4e4d5a7369eb72326276a29a5856c96ce2a86635025b70f0ae0d84f92d5a8442bd4d8c797b71d9f2df80ec33f2f8f36823d38a39bf37b77ad434e09704aab409291dfda2a8c01775820ab32aa38020b453c68d7bf2b9dca0401d51182d56bae2b78bfb411ec771ef526ed0323de1777690c47c9a20566f74d9e86f03b33a4613e80c45f1e0c341fa127e0e68d36d3a2846c5b4e944a2da195f784658acea1e9134be42dbea2206f4555bf142020aa876930b272764283095da7fe21ff07c27489516d9dd280c12ab7184c3c55df743977c669580e6703b0f98bf269730b4036ffd27bb32df59e6c8f996f539c046f880a99f85b2602917da7059fe718875de643ffce75a9400f7363574b9cbd3223d7d718cb7d2ec3f3e9fd3582dc4180ea186ede1831c07fe295a4c5288239fbae18ed1d11deab78d40c1217e6bb663fb742dbfd620eb36950a025045a1296f1c8cc58d69f6e99aa882101be12048017edc87860a4a9e53dfab05ab783ae6ea58b237d364f0e1e9c5871484c94ec394d6cbf4da1d54ddf72c08ddfb9f4f0ff393c5ad830534777bb1d4f4cde55f3659a8837f459e5d729ae3184105352b3e69d8fe44131ce64e0cec3808685f7ac4fcd40684646025b97caefd5464f295e8f4e682a74202773e3b15dc9c2cd7eee918a94fc7c454ec9b789291769d0d32ead9070df8284ecf81f0cf91b56f2e79871bb100839c550e1cae97a346dd6c62afdf4edd7e810bd910e48f717c159f6765a5bd2f3d601cf63427009544f0fa6abed4c316d45f10e50afdd501d33afa9e105a6e4a01e5d6c9dcdf274e015b7f9f008a259974f18b9e4d54aab50c16ad33831590e00c96f9d6af6e3c016f14a652b44a327787dbe7d3ac986e84da957cb4aff994b940a922e81ba2eac0b8f4be962e3ba8d554dff58e8b897ec40d0c8f4a680cb11a228bf3105e32617b096bf67b319b64cac1d4c2f74445371329a21c6d403f65529de61419a800c9b0247fcd3cd8f96dbbdcafd730657e651519359cc2bb5b08d98f819158ca983629e2239cc82d13e46631162cfbe46262b1c7dada16f2c36d9b0c520ba9059e92a496226f9736c94c39d266c98530f51b2ae9cc0f3a633011e2d730a6a22563b272306dc398d5e52ac580310883bb690595d3957542b4ed3a711dd780585f5982df60fa42d3aece90db5fadd375f12e988d65ee80b90083614da7298a8bc39ff1d9d918a65f16ddfe890ee74db420f8964ac240c120e59d942b0eff6f9271b56b23cba943efd4d439fc41da041294b8f263f3ecfc14298cce3b6b22fc6365067143721287443c2b33ecc42ac551b30a3f5f00a75410a94698a6f9a87829e8de2d9c6b2564e118ada4c223d8f44b0cbf3f934942d02a4d4d0511a99c530618cf69b5c9359f826644addd9270d0675e06fc5d1ec8bc2e480762caf181a47ab0dc13a95462d5cfb93c3150bce59c9231b7ed5034e647ef9d4b21b960d0d6a898bc528551ce0fc3a027ffbc48bb6de3167f2a0a4e9b34498774b8f03c032f46591f1e5b8e8900d1bc41b404b1b756afce3c3136dfda82d4cc1a5cd7b319a2b314c33790d4b9ac47c22083743da1428b803910891909bc200536fc5ce2b45df325e0facb0864356634716975bbaa784408a06219900948d87d54e7208ae128e29792e4ea8fd560097330308a7e8ef08225629fd84ca6f0a92e96c2178e5184aba21dcf7669ea49a2722e93145ea34e90816ca4306fbc759641a882854e50d0a4173a06cb1d40bbb4af82e278933a5030d220bbb944100b3824a05507ad6dae71861c8d38cd42d68c62c7ec37be50611861950bf32661865fba32df5c787b951a86f8d775ca81cf594534503a4d36b76e495251a8855801b0d734579b0f8bf4725a16508503bd16f46afbbfd8a31fad25ee017ce43b32651569f5b26d3bd9e4db1354910b8cf51e40040709681115b9a05d8c582ada63aa48b8ad53f186f716852eddd94ca08a40aaceefb10a4515d9930277a5f10a19cadad1eb3e9f5930cbcb2879ce29c67a6e08fffc77968e454646ceac21dfa2704590027552259af8edfbf5c4bba74853c5abea7f7b512872d2c338a0bed9bd85de5a6b982f51d10903e204afdd090ac23e4391db273bfa630750ce748308c5428873b92858a481e771b90ace55c5de1c6ecd36def60e73e43491c9f4c787889a619d90a82298e3b0969a88a03ac0cedc5344acbfae1d3d1b2313084a2da8f87ba1d6f82dc2de50c66cb43c0291c5c8cc0e7ec135534e3e26ed040915622d22c39f7dcc0a26f137b6daf65acb96aa95ff2b50a6c7ffe7f2ab0954ed6e923f1809f872857f44e54c264ed7732d28376d9d4a1a055007fa10fb923b28d259eafc47a89e9756ed4357708067e0f6de7c969dd6200818def3bf5c421dab786992512a3939f467494737d48d0c0d9c79a78b7af3c2252418475ee41573d6fc47c9a1801ec50ca36862b1fe984b313fc083b0d0f9be92476e760416115bbd4bd87da197e1cd83874cda87c0797136c5e0a578e55d7e71d8aab97ffaf2286a834db791270e217c0d9fd5f706db36e8f24d481e821f17ef33dd99797e3674fa560b28a1f38af89d1312020f17f146a36c1d23dad75c23992c613a9124d3e5545cfbd3051b91e55db54b1b40bd43a3f8fd9493dd1e3d5f6e48ed5a29bf429a614671f9bdf410479363bf5e4a7ffeb86d3e013628fcf8baba271c94e1bf6e1f16da3d772b39d75304b746201a950052c08f9e7d04828e86847d186aa1335601ad0204e836bd51adb0345e22508484b6cd3cdc9c0950916e318c33b0e74e7f0de57678c8e712b1c49ba01e7238a15686ecc70963a38636c5631ec7df0b59b85d593f2817ecd8a432bf6cc6caf9a9729d7ec93af35ea781b68ae94b550133c35b7da0c8e0f8f4b0b2ea4eea7dba7d39568f2acbf999916ef77f3d9de4ed73c38969bd3675a10c04c9c8902210671f88711973785f216f81b6be9043ca3144faa6767232edb5f6bfa7963ca3d1c9f3d5d81b28ae4d5cef5e22275433f5b4ad917a7f211bd0cb08b0ca7663a2153329423139edd4443597871300b00019ab45225fcc210cff1104660cf48339124969758af975e8a5e7cda4d37e4603270c6985d5facb53334a215b520a61802926db529552da0df2c0a1d2463628b36857e1e1d94813e212d98c984013b66246fff8bb094a59fe4bab6ae159bdc900ad4268d2cc7465d74fa49cbe73cf8261180d1c5b71f0ed938ae74eeba71cdc19a4a5dc0028ec16553fba0bedba34897f73a25aac2a8b7c79fe2a7e287395812d434c3bdbab6b0a81441d6495ff76dfbb55319af7c93cb4b6e9257b095d2c008844dacb0825f6022fde172b29b9cafb5e2b7e622c789d22eb73eb78461043a173e2b933e28fa50ab224578da1dbd6fba8d219dcb0fc7d15a2c1acefdc32a07dae30f0177b15265ec84bf153da268cc814640642cf9224341849e9cdae095a95328ca43743242924f9c1c61e924c9b38e117ad34c2d78e90c5fef223119947ffae2460a98ffda68add68482ef2a462689a320894dc1ca21505b993ede407aa849cda1d073298c966dcbfd935170382c4d38eb7a72f533645919c6a71a48628a91a831da57ec9c9b76225a00a47dd99ff7b93046e2f6240cddbba497e997091b103c0e144aa447641422b238adde70758c94311ed098c55ea92b407569cb365a8563e40474d7fa959dab10cf06a34392bab28821b43e00614fed85356c3a1aaa55bcf61260f3bb43e93d97394845a885e55a0be27988c2c48ae0737fd175fb38598c3463c62018ea43c5272098b73249ef7c4befe1448e86384c893accd48514f76da6e391d2a91e7cf669eeed8971b22cf808d0e20213299cff0f6f5860071ef14a431ca3c91dcbd96acf168933efaceee2b411c3a05215e3f23725e70a63ca02945f908726579ca97a85d468d75945e883d9106a53dd93265564431b5747abe0e48d0cf96782189dd99e06ae73e4fd26982f595c6ecb4dbf3507304c1a5511a345be9049f10fe5390c22dd52d2aacef0235a87d1c5cd7a8da2825b12d2e9bc54b91b6dd1857f9c7963d8b58f6c18e05c073a3224ca1d117885691f9458d3f292e54dc6fbe542aa982b9746f1788e8e0a318e7b0e24c458a7d2389646df1fa468e8a4f0c275e5949e5535237c57a8ba7699316ceb1d407f199ac0893679398916ef827ee280f3b6e8c027bc8029ae130d35de8f4ea640802cbb44baf51c8c9ad262720902dd02424ff5abf0ae738b83fc0df9eb46d4e17ea60b3b887a273aab899a30a0827ca0f79e0b8bc65829edfe9119cc504a7c2a691d102e74efc41000a039c7ffd13d6267262f82b4c85cd8986f274dee642e56e0009e97e887ca37137e0213be7c5c6d16f771ecd40f15f69e95ecfa5234cfee5a426aae4cacba826f1fd7bff17633cd826251768fb6b06f0dd44f50c599497a60015dee1f1ba9c3c16d5e3b7cdbed23ad6d7bac65004cf4f9613977563f6aca206135003781de7617aa53590432a14a841c10fa17d3b7009dd31b0150058d569b0d735430ca428c4a00e98d7fcda98d9afad85c07966b9d0374b0c38453bbc5c36c331a3337a0bbf23730783a31f860fd166eeec27db2eb80834f5b84625e345207427fc3d84633141c661b4489054fe0969d61408c6162f6f513c8160516b1aea89ed26516407d5605e6ecf9d77044c1da1e63ba72d49aa19b49f1e4844c70e0e212ff9467ea48b4a5d0760521d03af1081b83fb61ff05c664034c70e4a230ef8236b00ae89c80e62a7051c911d088c2abd88ec8033522a68fb87db47dbb1d03ea16cf1c1c9273d99ee14c80ed27da91d1d341b0c78d00e1e36723b956a09d4ee7f2eaf586707aa9b7e44ba615d7763ddc85fb3dea804fda11ffe45b0703aae2efd40b27e5fd01f7096f3dd9575d2325397c3e0e09bfc5308ac41b21ed448b10a32823f2614ec147dd003f97857224a761bfd7c87fc01271dbefd6b8b63831746132883b6c432b878881d462f8c64b907fe23e234ae8611747aac8dbed0dad83849d648f99cd6b6ea21ce5483bfa8c6a4504021b72de308264694001579647cb42e6a66a07277a56b8ee3a4c50e6cd4a65961d14a67a7b84fe0c7313e5fa2c4c43d738380d8ae5e23938b361a3eeb4d770fe657e9a198e0c4a623c17e337d63e9961024365682ca5634ae910e8e0d2d495300ef162c670b78368f3027a87398e2d36f36948c8313008f4e062b85f7bdc560c9a66e1c91ca9de004f7b1cb38ac571f9a81c587204b47bda16e60b7d644c7fee79f66f2eab53edcd93b3bcfeae6db6dbbb63c21704fb048c8723129d2c40539d862e6f37db337df49d1412695eaf3ed515111b2a4aa0fec3dd429d127b449eb60a25a9100f1466ddf30d9c76611a89e3672b56fffc605839890635541cfa5362da2ea532a34eba9b10c9629fa14ef1bc0be4dada92d00906f811ae3028297e1fd156f84fe4f0303bc77217be53897629b1142cd96c9601f57e6725472c0b3716c2110e1b20824cdce5ec02640fe2bedafaad274dad4bf6aa8d662b45ac47cacd2d74ba53d8bfcf92957966010e825a1826df349107d95feec3cff04a335d96639134e7dba1606dde82c2ae0dd9b81d1651c37ff369601587a6c53fd5cc8c38adadfa2ba43c934c129e653658372f6ddb0df3e33544caf26268642839cec97119ea1bf82efad609ffc42b8dd46d474136a7986eae95973f7acc1acb8195a70d0b3596d931c24857839abe40c452e390bcf33e975a4e4255d487f5f173e56bc05db85fb98a7c8069d4bae97a950ad51fa6cdd788a20e4d2afa788191c2303977955ba1939e5c8594670690a369f956d10cd266b1409f0ef1b30592a01fa2a6b777e25149d24de86446102c11584e61e26f9d37b09f735eeaf68607831bbb16075211d896c5d27cdba5f99482edd822f44042ae570fa249e19f50563e056e41cb4f019935c04ce1f478ad260569b721afe497856c61af92923c2edf16028cf65477fce56724b13ffc3d30991e89b29f101831d715e00ef4a304bcfa1a5277a94de16cddf5eae3c5fd9ff562312777e04f4ed4ea5243179fe5f44fa3e64f26df2d1df59d4f73bf14b82f2cde5bb9c5109faf9eef0893137224a2066a6f9aea3358f664f383d1b8b8cf3856f80334d3958283f2d7bd74902b28f1c888b74948448ca1be95efef9a2ad0a18c57fc9759c6fb907c41c89d2672f12fc26b90b376562288e5549e95aa1ca447a245d842f19fcd5197fc771bef00cdb6c4a56854b006f6448cddc84be01382325e85930ceb74c852ffe206421747bc45ec856dee7e67c952a78c255b9e6a0f2bf3248e97935a65cabbeda869884bc533a94c7dfad72406aa24c37c80c23419fee28364b0837c7d2156c3a50b051e2d1d49cef66b9d7152509b126bbc7d7801b27c515311175deaa8384a0ec2e3e715aaaac39ed95d7de7ad128ff1273bee0d7cb3fcee70f3819dbdaa1339b41e995efaeeb5a6a65e7015e6ba1becf7bdff67973b606b5c936b6245d26d0af47fc746b53a9b4fb3b30ee36fe48970febe382db3d734ece3f7d43d0c59299686871cec6cf7e09401317d21087284f384c9d9ce30092db0c5fff2bed078e0343c35b3011fd138de43dd35567822f7a422476a558a381c231bed794f72028b43eafe664ae5394d4db411e5203c5da6a32658a444b4fc0ef4f3c6f661e73f1cb09048b1557c8fe6fd5885c8b7122b8ab494329495597b1e504df7e399e50ab21de2ff8e0f6b6c60d792816273432c029b431e8b17a111a7a3c1e759903671cb8e1ab0d924d294be502495e23b5efc941ca720e1e0bbf2f56352ef8262f0a62f6ed87d4629e4fe09893b676221de295afca56bc3247eef64e262c9377cceafec2ca688dd873c4be3db2abdc246a28c7cba2de78675d7361d76c840a651eecc0a2db9ab4e2244c53ed942c3e2a3ac6910a710b39cddca4ea2e5c52b2bc660c2568a3c7583060b5a38bf4c7f3ea190ba8dbfd33db917b13c1bb45217b54019f53085be7e1de821d500a90c64173c43782a49adf5f5181c80dbb7f41c1f9c9e13468140635d8cad9f0486bd0a10b1ff21bbdae377caa8d3e764b8b2439b38708578e672382de17b17a20b7a7fbae90e62080a143073a48098fe0e26727a84741ecfc5bb473b59c71fdb84f3caf7b6d1ccd13c68f599f8fe40efe26871f641fd3c2ebda29736131809387d833420d65c2360541096242876668f6344351d469ddd307640f6d2f58d48586c90cfc69340d7758d3ce9a0d9f2775e0835a6781b6806871a5ab7151f2190168919d21b95ef3ae8bdfb28251d50d6650cb079bc6e248c427e34a7366e71cf048584a90a9f7d185180076d3325f4f2c30c1be23a48385e12c2b3af8196e47a183e085eb1f02237317a52f875576d062d2f0e9b0603350312819bb6bf690ceb789319728b7c045ceac783437796f38b75bda27b9a3d581a34c3c5d6f41b982b017a991b3147c019656e02af822f1b05843ba721b4ab531ac04c383c3385c0a76160c84901a579db7bf4604a20da31ba8ef88886a123fdcf95048fc3a184234c59a17da25ede799bfaf9fa3b7e6687dcd87048d5e92ff39a229655c0d55aac3bcc07fa3684e2a357854d0e4bb529d7af08128fab5def92e858b01e2dfe27552b3cfd03c25cff80c77490782cb0d657141537ce0da170c5315a42671bad21b472d2c6ecebf0deca0596b2af5111695b398143c4c717b1bebb7ecdffdb65c62a81d5af918cf6f0d58cbd655da5c82effdb54960ff63364658aace409f922f2671e66358953347a58481570d3c0edd9a9e0a52174873424555dc29ddf8b9a5594e1751004d016ca8570be745feb7ec6b0a47cb2cc79e63af02d06865af1ffe14576f562e536f7437cb70010b23ffe718649584d0507b4f63714be9047529e808aafb75de0441980c5035a980530c3e38886fe823c110e0b10f54a8cccbae674f1126abe51666a91d97814a6970a32d39ad5f76d83a3319d1865bd14fa2fae908edff19564b2f6d5632d9de0e7c0cd10471a0196629a5d61e99b09c4664f07a8320faba24164460e1fb4e263a4d2c8cc356f51a08189f95e2589db59ce086e884e30f5dd3e3902ef04d632fc530cc4479f8f166a3b8d6634c17c6684b2b1ee3a6c5b7eea07082fa4c2199d5279de8567161f48145f7de3af54e94f47ebf4c066ad4a57abcac1730896e23cad79aa8b5f8b57e4aca258fe438d6495649024f0e308b376744b5c662a6d1ee95c2bfdfff2197d486988608a2aba9efd1733342e704ec0c42c80ca78f4b6a4572106ead8947bcc8c01735d465d4c4b77ed1974cff9f3e28a04137b0144b52a7efbcd81192855b8c5f3b9ad29f195de871c4926d4a1aea5c176ebb4abc54bcbaf0563bdcc26bba15a58f9adf699d4e5d53c500d6f55aaff687dc70b78e0e3f762e240385cdd1521f13bf5c2d2ebcce37baf8b5118e905d15180be43f3d831c7c91ba7674ead6eaef5a18be999e09bd51f94156683f40afe48e87b1d1a77b02247268374ceef84bd1cbb8313c75d3819655e66fc6f8d522b94a518cf068e4c9f76d72ecd5910c8354f7d71bb194007723d16be13bf81c37961c4f67cfe9b853ca7d350806a6f1c758c47573fac9da52d46d6675e361f698d66588260358a4d918f59edc01488f30e8ac6ed7b5af8951aaa062771fd4dea41deca000c2eade0a404df79f19a2427905b1cde9fc72b0ada361dd9147a168e2fa1aa46304affa74a4e6cb3a68d3b9db3d248189a350a6735677869ca4783bd1ac7663545ce792b1dca963bca87db8578b52405837412154a84929027719f8f84c62a2933f452f0ea85131a970369b24df26211f74cbcf37f263ac32a22e128d80981151c435e4a24bda86b105873e3d8e660a8cc23e1698e8a146a5005f2054e9db911faa763fcbbc0205c86ddd23e47e91a76895bdf3f63192ce712ecf12c6d714cba02ad6b7c3810066ceac7da83c1ca30b34386e61e18797161fc774163e909b6252152b557bf6bc036f319dd7537f88b4358a241754aade0d866bf689c6749151dd9ebef34216107da9ae61a0ddeca5d3eba7ae18e4c9653d14865a645973e5546bb530b430039486bf4b420373355953677a5f0500acc856c816a874d831f3ed858e9c1e7d3e2a00f06b475f363a053e6b846945b6b53e8f0de71eb37a10d49252acf174a529d4298db602619e057e041044331ad64caadc7b737898a93849bcd1ddd96e9f81bc6d207dca8e6f1f187a0437101c8d9175d6ad37057a3fe6a7346500126370d06b8c1ec92aa651ea3b7cd17ec37912f542132d448c3024f53e8d6d47ea321e98914b0a7c394be700125276e155e7256f3c532c0fd5d1a10ac14401137a776be45ab08127d4b805f9c83506636f4bd64732f9875ff0bf5a69e0fd42935c062cbbb816107e9ec3ec6bd5688e4a9b414ce28fb04b31f0be7b5fc48b80d194ed333673a6b9a938a8260dbda2567726e1664fdf581fa5c24a0ac561909f5f2f03d204133b2a38548f56e1d750368dbd4dc1cf3dbe246384de6122e22e2e022202fc7b060ab5494bdd6a67f48383b21941f18d376fb4099998f7139dd6aa271573919b47466c16d0cad8580d00cbfbe55fcbe13a0efef82ecf1bec2592070cd366d9f721db3d9b48315ec9205aa262e35f2868c4e33b21a0f1dd016ca436160d6690116086294f17ac4c9e3f402dc04c940d509be40d54e10893d8e96a77eccd6ffe7a6b268d4a1a22a34d1d939fd67f525cb21b8d4c60a09a22470112fedfcaf8deed7e963597e885c8b099843db0a8bcb386dda43c9f9961da5e68b1582d985830e6bb5fc285a07c92c27c4a4c537983cf5d6e10c1dec23d657b5d612ef17650efa05711ef6c6f124bf152e856edd78b2a0f1f0a43c88f71e1f15f40102d9bde3a49a798fc85eb214e8a0f72cbd3b256d3b5180a832cd500359f97edc354cdb90466611ac6418ecc6e40c4f40df5eb56f5052e000346f7505e3fce4d5d18ee27e30114a96b17d02b1dac569fb06f4cb33b85f8352438b93d9d4116ac376a3d92d93ea66c69c5440945f74a43ee38cbc3a5c2dc35f2632d6ec78ef6479916d47f768b0fdf3715e402be01bb07b85e62bb1d8b466868a89e6a83a8f1bfaa8a2775453530e4122c9f16df2ef24f77b7a986ec2975ddda3678406e06d0ba7c525d6610e773c83d623979fe9cd23b00d67f9ce87f1cf2dabe327792bd225d9b3ee225fe9de7427f6c3651910958ffd13cde55eb05d90af8af11211745872a595e0ad787b6837055ff53b5881ffba8833a332ae57b13721815a47540549e03a9d38b6b89aa6a0071439a390c3414399cc49d0a27e33259696df06ad09fecf329718eae36f58219823d8f816a0764efde7542999aed9ece46319b876ec8219c4bc8a79750b6e87d02623e293a63b038c50656abf90098de7d1667f0569a36a5cb19f7f2baa481ea8f53570bb0d744bf5ec6716f07c0a00ee32d835a428ef30e3071c9b278fc19c4089c1fd1abda374c939dab7ef38083315b8ad9676fc40765a22c727640fb24635b86da0e5b9ee8faeaa1811c5152154195d1808354ad9da2a5ef80348786b0c482c7aa44d81f39781ac2e9e87616504ab229033de9bbd63ae5ae105b9f282ac1e82a3251e03b2955191efed4060db9455710c618f92f4f57f512e5eb8aed02d74d71bcb11c0ec2e9c4e299a8ca72c600954829c32ea7f67f7bd1e1e1f9a9844d9614cd8f5b78da4bc455638707a299050ccdab95ad4d2a91bd9f81288f09225871a358af4ae09ddee54edb7801bd51ee01350924555abd312590b106755314e86b4c6e4daf14fef4d4cc60e7f21827bb45d5612456206a2bc5059010ab52ba3ab568fe9a8e1ff303c4ad6a6ab38de4887af7107b9cd2408d83e154295cf57da5500f0beea88d89854d180389837902504e11ecb1f53270de9d5811ac4224c074463702917194b2c822b8149a4293c1f02c82a688b49a1eb55594927b0d051c06893720d4749e07a417403918c18c2becad3010a9badc01605b18c1e5e37b22c4f508af01ab719701eabc0a7489c5bdd0ad4e9e55a01bdfd295ad85128f288092325df61963020247e7816491842902553f9e4b05668a367639fc7cef98cc6afd0164891bdea9c9c25d386c084dfd13651c7ea16022db893f873e5072e599b55d627f513aa95bd8b1bea372c32893199219199753993a484ef18e8af7930c893b91c5206f254dbd28514a14ff14064365eb1449bfd23165e47cc87593a6a84134292963c87a0bbc8f3e0c12a3ea649bf499b87ec60845c44adea44009bdb273fc21d236ab7e01e0ddc267def96c6474096a8afe1a49f55a2da00a0f30a3fee65047db0d4da64ab1153a01b7c9f7943c0b8e30df564b149b7685a617388d5e2fe1564ab3733c899ab642e91da185d424122d84bf410f2e9e79064e70497869ef50fb9b9d8f463114c403296c93cdcef97415ce4c0a0c5a635d388547f47043c623f3abff46f9c14ab9b5f1c3357198c456d2019a69f448e52f532d8ed2dc474a96522ca1656f0a770f6626abb5384c437ee3857b212b3b88aad59e6b565d8d47b6b79543ad7e0716d3cab2907f512b9069d5c7de3785e068ce7b312d1cdab4765348d658fa6f539a5d8a7306517c8d37113868461bdad4b1f32a7919ad25eec686b1f8f84cea836856a94a07456a51ab56fc96a91be026c15dc5d9c07521a50582f99244e8750f9b6d575e83373dfc4e2605ab5812c920b9a643133ebb282cea0334f71e5437d98da1eddc0f50f36ee7cc78966c6aed662be312c8b1ea311f8ecbd349051c66e0229b54b499a77402f6a3a3f4149e629eb977c58ef0c0ff87f14c8a904ba219f297141efddad5617102021c61a5053ebae4d9c9e40123ca730744ca68a357114b0661da17092f2491aae12c8b9c8aa72d3327723554fa5f75c7a5be608e7a5674ff534e9e82607355abfed7b234eda1a6d6ab9ad3c35814553acb070dc85d0ceb806dcb0f69f71ceb8ce3878d708cc6b848e8319275b90b83a1a72790c117f7ccca65503c5ca178121a89eb47cbf575a7b7388b6143e8d551cf57c085590ad40f9ef56f84945457140875b882166d4a9d22e92a5779fc880595cdb47265f5ed1241bed76eeda69e00eb5d61b272bf792ca393bf73cf5b3a51646851fd5af9f3937981de9abfc75a7aee959e9e2eaebabb5dcd0316e0a7b13ec0a24e67e94cac4375acfccc01cc7496e80738c5d8f5fdc40381d05b8bda1e770541f9630ba1907cce783756c9803efd43f977c8903f59cddec74cd972bea9de860aa5c18db6e4b47e591b265d91ec7d476950bb3fdfd64c8022746c7366a060b451c0b502c9a9e3df5d74035bccfc9d16058f2ef1ec2f5c15c3f966850826cd7aef05814aa51a7918285702938a996dd0c643647b384d4f9bbfb85f70209d4bc1cb9a7b4100c31d220203b88d597acc1d6060e7b986c1b111f9d22a211640b5b8c0e4bb40482e09242ad3c80d6435d2445decffc44d03d8053028147f33ceab88dcab9b78592cf697893df46af231629a8c8b6436090e95ef88b66167b75c7b6fe7ee52edfe56fe2c97e78aaf11c57d9dde7d9c52627399313d27427df2885488164dbbd231b56761df171e81648c14f158de379333e83f9b7e1501e67ae5bdc9330f4d46fe320cb49d2b055d2a18ebbc4dcb008b9e41f1a72d54027cba7687e4419b658e4049b5726eb240e060cf599b58bc06966d5941c8ba904ff337ae8fbfe85fa838065b99e0a049a0b38d3bc5086095ee0d5a298d364eeddb1cd93fc380ae6764d2e8503201393b6284ad90ab557367dae61bd08b604d2bcf81979fd4a643b68764d4c387022799fc7be21083eedc7134f643312578f9fb2d2e6fb1598eca608ff3cf9a49ffd41ed1e525077a9b4f889692d4310515a4cf2c3b2379fd533fb12cd74ed248703ebd74bd544da6b8bfb83f97f39236b916760f5df44423479df36bc6c53c5d4f03c054ac0a85d9076444e85026ef7c4888c483b2c46c010350563f5381bc58b5af76f2698b0f52702a805f1a3cb9a7c5e423186f93532c686d54d9f39c0122c357dc5b01cf2b88b2eb8bc7e18576a30d46308c46075267bf043ad3aa4606f8ecdb15f860c69d4133c03e42c1775ee5ce4c748640e859a20502e97df08009733f5f1e93a8a8a959bacf20cd4b46ce47768cfb268248e00873d8e7e0ec1380948c087419910717c2a385fbe93b5e206d8106729c2b7e6e74896a472c953f9a2f80c82f2f285d1725c272ea735aa949244fc9f7005d2a43d23faac8e788dbe840436f21df1a5c0e11e16159ffeeeb6ecd8850d21ea0187c41cf27aec5783b2c379a04cb65a6c209337ecfcc5433d6df6ee600156b2043b2536eaf00aceb28ccd3a6b86ac0f73e8c9f407950221f1f77768339590766c967c617fc651e0ba92e2dd006d0818e1cd3df05a29d5cb5a5e5da07c69a3617f4bd035874718f4e7b437e20ed2904258405d2d3b1addd8f0c3e92507970281cff5b1618db7ad3a6405a868fa739c2969ea9864d8f1081d203b6628d50f6ceb2c26422fd5920974cb92dc8153227eb4e482bf12802fc626fba616b9cb30cf3f087ebec37f8033ab4bce2cd1e0c5e5886cbdf6fbff038784f9179ac2800608f0175a8ff5745361ba60d3835273e0d1eee2d1437e2f7f8fff57be2baf823d78bf19be36b1a485b84031c8075097e19a71e8ae80882dd92b507b67152011f2d3c737bda76db5d1d316f01efaf9e0ed0fa11738f5e8808e08adeca6ef235aad17838e0bd7cbf4b15c53ec793286025f6fff9fe46ec95637e1e095e5dbb8f8a115ca14baa15e373c5816d386c00acc88dd1a3e472e4692b1960d082ad5e8a062a953ae6d220529e4ca67f17df9bc69cc2903db8e41ee9d7ae41d63d56bc0dfe076790456f18bb160b7fce44df852d73d6067791eae69d6e9b06c0d8739433d988f0fc769f31e2c298b9ad0db0dfc0aff0a22f6b3c008d09c906b081c7131a886c5941c2d9e79c7db5303ec6e504c7b7e3cf24d28bfec4aa12247af47f3d5171d5d9dac0fec0387de709201f235138832da48a3432ed961ea72a140420a48a820c8676a9449b62e2cad85f63f64e779ae341898cb722d6b5242a1cbc49b43c43022c895d864a772881ac87423db7a94fff7df2d763957156e1b0dc2431f6545b9603ae4ab2838e0a5d7e42780ed6121e4548ff02959e8ac6581eb102060fc1bf5738c7321d4e5477cc73ca51388e1603e00fd6580b4064561c004a4796ce7c0f0d561e416a1a48ba26a5542456b4f46a38490c4cc5dc4f826fef82c8eeab2aee892b78dc7de1363c86b019d5d4817f067eb7a8722575ded07e5397b727081a1c00e90388dc9ba09c21fd16b23ff72a1fdaddb012e174579ea4290d4709511fe0572de5df6f1beba6054d3e8dddd03342e817ca82384b9c487db5ca88a4e1b73fdf500dcde5d47a419419212a025ed51b6e64cb18310994d6c36a95b7b8e1cdcfa4a27d917ac8f10247e40a03f56497894bc86cb3345863c7ff0dacc3f602c0275e46e4c58d126a59e171544622cdf587776645ce89df8007a086d9f1b786b7c50040e4bceab847c2d9fac05bea40a6848f6ffebee3fd053e30aa6803d0e9136b22639d1bca08785ae8fda927a81959ea3b13c84b7081afe73e1215c97bfee0458580d59453c853ccdab3447149d260a9f93f960aca9e5949f7a2ca6f7aeec4c8769a2f4738d79c632bcc2ea737ef4482cffd457f0658d4ca8874a7140ff6e76d9dc05616ca4ce82bd05b7402c3e18103f7e21b1db179a121a823043777d7ac698a8fda28be778df475629d4e64572b4ca5061656040ba3ba79cc3299c14aabe35baa2b457232c12d150a4e9e0d3b7a4fefea3e3815fe300a090e6c6be04e8fa511f7d9a65112d3a48e35fb97a03077500ca39f10dc249dfaa7ce67edd05501135aaf30cd2935eb06de6f204149e60d41099dc619a236b7d20634209c318138f3216a69a1c9770e4c3bc0999b33f23c2be1ac6cc98e1f48b4da194ca9106f257c8449dcbbdc525b7023261ba145fc4e616b1f0094559b7942176c7824f3969be8c09eba3fe4310ff76dd5ef39b018990db75217b3ed7577815e1b96ec5c271f1bb8d6ff53d859ea0c980335217e24324d4ac1fd5581b6483f199990c6dff014f0a6c7b46ffd0fdc1d035ab33d595930dad53607e5c8dc585e72aa45b8863fd60f0e78af06e43efed81b58131b6b27d4b4fbc55899a3031d56ec65d89c91a1060a27c1604690d718705a8e83f9457e7f9e6c1d0803e0fe7bf2e049fe9f8fd2464b9b249152ca94646205860574053e45755a29469c4cbd47d662f9567a29a59ebd3806eb9ab8f7d251278aab64431b924e4c8200b14aac6889946559966559965f7ef9e5975f3ecd975f7ef9e5975fbe17923165d08636b440acf811c9164869436bc3907c7d98ef67aa4aaee4743a9d4e65792a4fe5a93c95211b96655896362c4b1af35f9665f9e597effd7f59e2adafa0c39e96b021b640ca29eee28fe1644bb2a17b5d156c68c37074981a86a10d6d68c397ab34030c2349154e766fce7064dba8497cfed7a84d4eca904206bb94fdc514a394d20bf3b277af4ab9d9a3fb18dbae05c7fcf0eb303fdcd590922dfe8b81b2cf2ac8bf0b5444d3ba4e52fb730139ae6c67cf9bab0a5384385d40eb77398b4c8395bc3ce62ddc2bf71572104eee63c67ac4324692363732aca6871e3ae9c4c483003129119d084729c7711cb771383f080cfcd1673961ba143e7fd6e74a702cda86ff681adc4731c5077a0ffc89b6d1393c98a61a8073f5351318cd976841b37eb40d9f4247ac29dfe3f09e3db9f3e03931beb66aa7b40d1ad2144c01838ebc851df3cefd4ee5b40d6fa552ad9c0b7b8bd56a1b1ca6651bf66d4a350d7fae33a59c06d399985eb7ba065ef87c4c42071eb23c4aa93dd8ac1437e23ab57d380ab930f470348249c3075238bda0280f3dec74b84dcbb0e63167f4f0416524b9234a29a594524a299d18e7fcf9fc87a80ae35528346766df20d8a30898a04b8f7895af4d05640a2a910f2158562511f742784c2d51e76f673b140d8ad22d681628ea0485eae137fcf862b22ccb2e1a97c025a2a64b494b391d3a0c8d6a5d0b0fdadfd741cb287d8c7eefc0ec077af8eb073ebdd8fe3862c6d829a0e60a35572857425128cce650da36f8b9cea6c53eadb97ef02b07ca3f1c4551144551144551144551d4bda19110c2d0462770220bd4a3380c3a800043eebf66cb081530c678bb19085317f1da22d9f5393add17395618c3b21a343964e4755dd73499ae1d95da1db9acd4e693bfbd817df695ce15ad533401840483115a26922a884832917600294b20330048e43967dc073d938934994c26934966fb81c1efee340a72fab6ab967620d6e1f9f953dad54c8d408de3691545892a0999836a728de3d829cf7d918c580a96923d675b1ea198353899550c804963219988ef68d2c4a2f965d883e1513c67005a64fa9d8f233e4670a6625471f538f2e0466c15c2e73bda862b691ade4614610a57620425aa2528811c57230e57e24a708cd738625ca372857d52366181a1cab1a9944629f574321319ec548c4aff1472a5c9b142ad344dd33c1d4f87b1bdae9661d85e375585154d581bb76d1cdeb86de3f0c66d1b87b7546adb36ef25b4790c1bd0cb5ace89dc14881e33f84fc76b0ba2584a3d218212726a624a8245b1568cf1171983583948a886babc94fcda637d755d0dc5ba0ed234b80e420a1264073a08d28320a828c49448ae3872ce5967d5461a83c5b410af61ced42fb848824344c6a1f8ca552a8ce17f956a6555f831ecf157ac93a12efecd64013e84593d0a93cf875059b6e322759d7380ab542a95b52fab8d8806843585aa6e0200838cdd8729ba6e7713864c43eee59c73d79b5a2f16dcebe14904217e3deddbddb79b826677d3a7d76317c83eb6f4de7befe6850c7eea67738cfd3f14b04891bd2f640a81ac83c5f5ae8b8b32e79cd66698bd40c8321b17727d50a60273e5f3b7995d4c61b6ecf0813cec1235c3de5a6b6d6685ec9915727337441081ee8af495d1227fdb9b9a1f993e58e307ac0f9c2b1afcf3214992bcf7254496aebeae797154a4722453cdf615b95ab739b8901ebc5f6b9cf93db6eceb532f5d7fbb52069adb83738b1c201ea20e39508b38ec8b21438e5c6ee370d4dc9426ea9b3d67164eaaf03172a2078d691199fbcbe15199938cfa9426fea02e8c658a1013dc6863e17ae374fc9024cbb4d30fee614964ee734b877bfe3fb8e7bf83a344d091e70fc2f3f9c10683e32ce0f9dcd22a2a313a1ff957de07d7e5ce07d739c863f437b017f58ac6ac742ddac7985ad72201ee57de022a1fa30bc2a3d279ae9ba20e688a3ca029ea96c3b4683fc4a7817f611886611a913a52977aea247d726fac25ed63b8df3aedb5ecbb3522d5544b602d655ced50cb6853ac9a6a69eb8a700fd6d2a804aa715243b4711c4712d7d295611a892d79d552b6d512564b9ab6615ab66d9bb665dbb665188661d80f2e9381190c06ff055367b2a9c5bc625ad1812ec568b46dde8bbbd490c18126071ca81986d4596bd79e329ece26e3b99bcdba2b32fdb985429a0efed3fbb7d66b1c845a6bad1d155e593aacdd42097b10dc6a6152eb6412932426afebbaae2773c64a53355902164d7247c3224f56aba80da60daec89ce93cd7f512260d876927d3f3f7c6a2499324258720ddbb45b65ae410414c1b4d360de736ad5bd98f16d96a915ce7d2c1c241692b8c1285c17a7466bcd036b6566bed5cabd4225b64a9d52a795a2d4f89eb783cad96c78343c7699082b5d68a22c639ff6b1fcd8de7a8a190e7e5bef7da720b916ba9c1307cc21fc6e00cb75dc015007cce8217e459679d2dfdf88710cdcf067bfc36d8e3164c9ba29aadc51275c1c0206a218af7be84481d23cc39efbc5bb4966d91e99555f22c45d0319e0c2928c20b9fff006cd04ff17ded9b86c5b6cec7111f5b37b51d884ba6a0b4b71c8ef97518688b4ceb4f6e87ecc33bf4e31bb82ba239e77d5eeeb82ead7c42a7d3e9e42cc34a0c337c5e064b0c510534452b20950c6a510cdd8f23d8b3fc87a5e333c8685106b98805f42023842812e3697c72376a10f9597e05d4b2a2f247f011ed8710cd009aa24f86719b8e180ed01a484706c845193445db16e33d5088ca5017acab9d9597e163f818cf926198eb1ccc029a2dd218191eb33c986374169dc7d1438dcd8d0f397ed001844aee782787ec743a9dd99d4ea7d3c99f19c3097905bf4a1325a81edab74c974c6d24c98925460c31805838cee3a1c901877b3dd4d8b877d33fe800c2bdc65ea094524a29a594d29e349c93e5edd7183f6bf8a60058e0a35a648a669195b7b1a295ce8710a2958f010ab1688a3416509f20758396c89770210c51a4f9114c9c208a348a8223986089b47a04a9092d91664f80d30529d2ee14486a8012691793205c4125d230145054220d2b021454a148cb84ec201469dac602ea2751842b91b66d2ca036c2881ba4441ab7b180ba0826544889b44eee84c0f3d5074d26478c1889b4012cc94f54bee24c1bfea4690871184c9c3397e7b36a25cb790b3b4f2912d3e355b5c49c73deaeb6e68c2fe68c279f4a075622a52ac4fd49dba8389346eec0ca8433e173fb2bee7d6c2892413b6ab9401a4259d1987ca3380c062fcb8e62bc2562ce99edc5061a3a7634b16ca29e8ec807da519de29eab3a1d8b4bf2d90e94d9280d69d8aa3046476d10af87e1741ad2b08661188634b4f6e596d955be18eff5ec23ce0ec018a6d9bdb53692318f5266cccffe721ce013350b8f34d4c54e549da84a1b06398274a152428ebb5add253587aa0b25b0c6d5683bc085942f56f77a09d5f03c29c158ad30cef93fc7531ca190e7652e2efe8f13f185141c0018e48f98c15ead1ca673accd716f6e3169f48a0aab1386e9c8844194e3c175e05f57dd884bbe21efb460ce894321defa8155b9bac77814dfb0cd5952664c06006cafac7316f690738693e9e2bff2e273af24968f72fe7c7c544953e54bc8988b9e9488d9b91467b9776d6dc14d0dc3bf303d475123a68bbf14244aa22a70161593b88f95847125a9703e82290916c5b6d65a6e7bae7beae2e07f18ee66c2b611ad1e6dc3a604d75eab65afaa3db40e773219c6183f6e1b3a7a4c7c84c76ed6a6a6ea7a11258aa2288aa11a353659d45ae76ceca2fa824c5f730fab9cd18b0cce32026ee4ebef20d41b5399c1df8ee3388ee3bda1910bafebbae6e4ba0f253f9e4fae992e2e8009865c43155ef3e347f6d8ffd87ad42175116f6ac81a92478fa68bff689251c85f230ab98507017cfdb4fb40ff7f5dcb0eff5d8fb300041924d1852d82a08552047687795c2928a145175f37a7838c530627596373e303d7d1e2aa21a37531e7acb356ecf3c7d35a7b85464411a191a99a53b5aa610d925347505a1508ebaa54dddd1da2636fdb5328582ba20926910f219a481729d191d9796780e763541ea4513e5a2ad1122d8d4a9a66b79e344e04db69d756b56dabda76752ad59c69fab967ebfcf643883815ee8710691d100da94b8b4dfecee78e862d990a25659fb3ced3d11235512a326847d9db133dd9d169644fa3d3a87b85655bd6cd3963b37fb9fb58afb88d82f4823aaaac7553d5c861ee4a4557aa95ea5af14156a9ee6d194f5cd7cde5836a03d7755d97733756e4f999f63df86fa0ff5cef85643006d1e4e01e8e1e40a522c66661f39bd5d92ecf59af8b5bde139ff4095bdec4a1987ecac950fc496a625fd2232715e0d3beb62dd01b8dba4755f491f8d51a02716f840251263455494dc345da8d843811235ae7237519cd1944883ef2d168f4987a4569d6a2c874a6711e001dd3316811fc64568b22bb1645ee0ffc7c9f6cfbcc19ef743a38e2e7b3849a2a52f173823cb96e063d3a4b02eb01d7389c0e2bc8af850cce164e0cdac59190728044132d22c960e8a3223645418aa2288a62ad9d1f4c1ba0c8f33b5a9669dfb1d66e3ee6143e602214f9b85e080f293a72fb7998f6825a76b83f5da5bad7407ee0c7ba2258868b4075f48218d4757e1d9b0ef795abe97c77b8ac6e71f30495fdd168341addfb121a6952e8a9892909a694528a67eba3df4adc05479c2871a2c497cf3452d20ca5826b65328daa9c24a4911494131393c9f484c94d3e254ac95af156cbd432511c984c485a2d8bb24b9a4c319551587346e5e20a5df8dc3e685354455d4ca696a9656ab54c36c8df72fdfcaed4d5c42f158d59b99e78a916148fe9b28a19e3a4542a954a792e219fd4674fd4c55b4e52d99469cea04adc85e2c0549a4a53d932b5544b98584c399b4ca4c96432994cd70a0c20b40199265babaad86d0cc3b02539866f080df15f7f6d13a9a1e44dc6f2f939038446413748327d709236ee79dfc74fe96dadc66168cc0f3537b4cb51ae7a24ee28cbb2eceeeed6b29a39a736b5d63410f7f5c7075bde344dd3b4a7716d730fc7d542d74a69571965c6d7b5d61e31abfdda3d8d5f208caf8b3a6a9cac3975ec1089f0002214d262e9506121d77b6f8dc145fe0ffcd0f4efc075bf7ecdbd5173df723740e045188d829e73ceee401503584b336248dc7b2fbeeebdf7d2eb567bafb5b8de8de534978c4c4a46ec88030799d2c8ac7d77c39165a426c284c9e19ef5c04c5d92df3bfa7e942cfe74b807f381e9f9f370ef0324989e5b92ed20006814a0a8708232423a31b15fe9052253831ee10371f83a1a2c0f6f71407f1ef26bd9c1437efd1ef2ebaebf1607f4d7b2c34f2490beeeecf7a41225914824128944ba3744ea187177afdd3d8634a626c9c964c4f675f12b810411a2dd6ab28cb465abbf6f4eeedf98e47104e2030022b93ef83a34c78300be3a031872f6f87176cf823a3e903e109faf3e8d8fa036b9974b2cd94734943503b5d4faf9d86cdf22feb40de4b5d85246c6fbe914db2abb2bc5ad467bb04b353fb00efbabcbba161bfc6204feebd1bd5a06711797d265d865d865d865d865f8a2a2827d9354f6aac3322ccbb22c4b6b5fca184ca04e27146b0a9395125594d493d309632ce5ca329f33442efc099281c4b4f8449c928373c8669c7d76b91b7d5a32636a6af83e594c27a793a8042b419d5a6082214af04dd2de93b34e18630cabb141dd40ca1778d049e183dab60ddbb0ee31fe1504e6fe911a615b66b047d5da17952f68d6da69a7c51d1b5bd3384204492484d664145d3f2f900f7e4377b70f5b6be0e694c1900acc21b7f75e5c20bd7365ec7018eb27db699526398d27c8f56ac2ca8a528a1208655fc103d58884095648018491342a41c2c1109c71f45e42b4c385765d2fb9862d642b10d7556bbd735a4f167d5517c624d684d32a8a1255123207d5e48ea3aa474a2bbd51a96846158db9c944594959b8062bf2a42e2fc83a8fba786800a50cf6489be8aa010e64e0a655f6e80a3d5aad3b8ee3385e17e785cbc0b6dee762528fc6e76f593e9a61b08690b135c3bec4f45cc084a906a37164afeb3611482881d3a3ab464db9412142134f89d290bbd3a0b134e744067b341aed20f7e0e19edf7882f60ba533d4d3c57638c820a6251d6cdbb6b57a6cdbb66d1dcffbcf4a6470b63e70b2b2fd56aba58282eadce4a03a76c86053065b01711c4d0e387aa8b1b9f121c70f9ece6a73ec8566ad9d765ed8cf8bf1cda670041654221f42d0a0c24a1465ef43081a56c84288487b2166167250240aa2ad6fb801c4e1f3cfe14f83835540a72b420efd10419d3316490f69daadea97698c942fb81ba150180a3b0c851348c04d08019309d38a9950088970088e1234eebd84b073a75a6f46a50b46f7de1fe4fc00ca144d9053349102711f3781918c93e8fa16283214597c6837eeeea57a363e3428a24b850fc0f8c0a9f201111d50aedbc950971c2e0d122a3e70b27a3055d5da9266e4de712ccb1d9f4ff9293f234ea271eebdf7ca9052d3552c91b14506272902df8164361473890c2394423bc4aa6d35ddddf1a9187bf083e149624badb5f45a0ce49f18a3753cdcc5ffab3b505fcdb99da3c0052600030d683b546050426b5c8d754790107c11da71af2b546305061a8b00df9c12c5dd2f56b7680c0de70c28c6d7a45a0330258bd9635bafebba2e989c6f5c1de8e3bb78f8879f86ee91420a84843b0a7d5c3a4ce91e48451cdbcf4e87fbad0b627b6e7bae1b421404f79d0c743e3f7d95ce67117e5af2803a201ca2f6da6f8f3d2b88edb5b7400bee2ca0fdd65151744ca7d0162d411a8496301948e4e11fedeffa9a6538e6873b1ede3474984ab32830bfe811cd4a352bc5eae80f2125d13d275e16de161e0ed6c562b1582c16c65e8e62db5a6a69cb58eb323273a63ffc7692572783657e166152978f0a191742768cfd6554f6de1a342a5582d184c5643585848275a94bd376bd2297ba346738b144c74fcba7a2fd8794431f7dca074d29b207f1cdaec8a539d3ff83bbb80fee6203039386ff8c06e60c77ee060ff7ae07bb74030cec9b9c0e334aa67d373bae86325513bb8175ad2a92c12ea14aa55229c707f740aa9b39c33327d5cea6811f43a1b2ac860c0e3452604c92d9c74c4336b96d5c6419b68d66ce601f27e348c6e29250f03fee36f206c69d4291ddc6fd9cdd3daebfd129cd094992645ed180a13a94a8c5c0d62776d0597d630c04cfd71d0e3232d78533a4858316929648e2e93c264a85802924896173860c0ea4e6311821b5bb975d204e51d92d2832385b94bed8da897da23f421f6d3320cd39ebac5a5649b4da11574b29a55893b06fd29ce990c6ef0fac94c126913e0f88b130580eb30a50c06c8a0893c6942839547cce240559cbb08d524924128944b2f6a563857befbc531445ea7934a48d628be258924183eca1b73c9bf8b1ff74596eac2124113853b7033ff5ebae676022b78c26641f0d046708a70cb7484b5ad2520cdd7075a077832dcb39430cb2add124947a61e2a16c5032039939ef17e2de776df45b88d77879b1c1061a3eb16c510740684d42b69f13294d454585eb171d667ef4c39cc8ff953cc0f96cb0fff8b3b7d1402dfdddca402dddd574495dfc4b20ccdba1bbea5e0b71af4527f93ff1092a7ca08fa6286f5996652903671cc7d32a8a1255123207d5641ce99c18ff77163295a9e99691e971cefcf56559d6cf910cf6785d374a669fcaa8840e7a64c968040008405000831500001800068442a16040302094cdc37a14000d577a3e805e401c48644916c46008a2903186190288018000019299425500c62fcfd202af25a3cede476926b63f2a54c0fc9206d818fc040159cf0a4f6aefc8f07baa91e60ed749d43d2b2075d1742bcd3bb80fa7945c6b03d62f00a582e2d7e383ff660afdfb19659cc6015385c8a50af437bcd7837524f7e494b6b04eac50e64b6d2bfa44c81c8133c6b6b6e73ced05c1a6c24ed55d67c4e793a6a61b9a093193f59769678b8a9688a82c81b1de893b294755e589a146de29e630e9526c64172833fec060d2124d7fa25cf39990a45895a744f0967917d7c338afacc4d92b9f99e2f1427963fb6d07bbcace34e5bdacc0d7fa2d28aa0865e6ecdeb93f5f49cd395c52ea42f19c6a8e88b23f8427b54f294d5953230599815eff254d31dc54b89aec8180f0f077c75465fd946cec4cf1462a94c23935156412b78c13bc3b0c5dceab9ada90ac8ab60db5aefa194ea07c7797fe8537843952fd2c2fcfa626275d37e31da9e4ccf61327d44dabe18340429de298001def786b431a7ce3484191777928e9314ced8158c3ea8e836b83a3ac51886c4e8d470523b04b12c0e8dc2eeecde12a9cc60f7b6ebff74d1b80f0527e7c2677df060728f3455f7a41ec225d68c8fd8579603fa9d283b0b1c37a7e5568a19c1b3586e2830b848d02e99c4dddaca53fc844f1a25075c611859fc4e19206d7511e6e3c024201e88d02ca61076ff5210056b04017c2c22a71ee401e494bd4f7f985fefd0eaa0e459f1b64a5c723c562ea632c58793adabfded5ef5542a57da5716045e64bec5801589356b54dd105eae52abd44ac0d454f65a70cfcdc7553f8844295d833232334965459bcb2bb59dc359b221cc1e6541b33ba8bdd2994ec0e1b34f1aef368c5baf83d472599f6467bc44adc24ae290a6d0b8a8ac76bf3d42a0fc9f668b18bc958f481124b044e07f00618073b1925e58c15c162a9b830bd28f0e61c41b2629abac63472c652f087b0676e3b2d85f830ffd62ac5e22d87846f368b9a357c2249ce95e10fb9080af3a98176a217ff4d3d00a6e4bbc6cb81877c78e0356ccfb560260c3eac23fa2d9664fd88a11e08fdedd7cb6ec92ccd8b522a1d41008cc3c232bb64545679de519890597285d53b2671ffdbcb0dea41897c74d49caf1341b38640217cdb816821984cd168191389176c94cfeb9e17e068949687149e541f57a3f69ca67466f159c142a3af050b1549b8978345f8029501125fd07cc395a18741557f54496a191439f69def98e4ebd420bd64219404b58f3c91af362336cffa5c9eb0e42640bec22829b772c9eede40fd4903d2869df7778f7ecedd5774f4b100e746776a2fdde95ca10a3feb74a75ed01bccbd4516c332926999679fa8951155178a92b9c692a0ff1e3bb012689f538ffd11e70539114f90a13b0da116f6e3c87c8860ea453c91c4518a98921d5c6162d4972b74900ae45fcd8753cc61c5370c9d9e11ded5ad755fe3d0732817759f78221afb637ec7c57e3993e30fd67becbf4ae2db726811d0ddede8ec02734a435f2b192e4c8217c0ec681c956644890b25453d4b6bb720b1302676c43213334d24ad2b627409b327d1bec1ee3f06fcf0cf2811089ca9eb4326473277dc27d2523161c5617e954bca0df6c2a9654d1c3c4ac6719087917a382dc680231256c87b822c5a9e22c8c20d0035e542af3649632d6a533983ce8842a5e13b6482689a6641792c004890c1f19842737664dcdc43b4dc79fe6452dad542b3c48a7ddbf4fd26ec1b3b4be258c89f982de888620b28d7aefb09c469da0dda58e9282b58092d48f7e06fb59753701b436c87777b513159b43ce6aa785751a5b7a13fda5703f485c159a418ef0c1cb98b569e23eb32ad5bd151c5a4f75409c3e966de62d24c66c405825a5caf780d4868827bbb2efe6ef83e3543fada09ee8acd91b92a9b0a426799ed9a2b40bab7a9abc3c5db38cf3fe312c2424237a6ed5cd106d07b71e64f297a4626c30f4afbe78e2325258c0087b639dc9683ef76edc4dde00a1a83b73fcea0e18651830b82d60940785535eb302f5506faa736f3df332b86579a9a462e8880934aefc18270b8aa317628cbd245e60eadf848b366b064eceb7d199d023bf3f16100a7b4247af47512ca48b29a84359047501d7014628363ab2d0c0942d7f851b8cfc5375d3a63dad817a3b8aea4733952284530a9b16fab7827aa40cb3a437d74f5925b64dc5c9ea6ebba9a5c47bc79474b1cbaac42e3d8e96c8eac84225f706d16e113eed66a1b265f84ee753c6521a063f4b09ca749bb03cf7caa3a76c7f69e8b1f1fcfb99dcedbb67f5d3ad68d2390b39759ea25be59ba325308a46b3023a49c08630957c34f3ae33cb446b0b5c9b5e9526978bf55862dcc9afef56b072f2ead393efa23f8971793aca9c6213419acf51fad0cb2b6c17993ac0a27d94827d9e38e3a8725b527595ca7014cc4496c734fe964eddba4eec1b5bc25595712997d68405793ecb08b2cbaaf88c396dc02201d1baad3daa4ceaf59775714fa3cbd06802c95878d0f3431633bf964fe213e9cf56e1cbea79aff2313b56781c3b8dbf7e13aaa0849bfba71b82643208a9f129918a03d868e86987b589aa90fcfec0b7c3c4e4bb58691cb1b64593e2d5d923d4ad3175c5cc0f5173beb928e59f8bb6840abb9f8eafc30ed483b8fdd9d245afff0c2ae7cefa90b6d35de87e1e1ee29d862cd3885499143fb27d970e85722c5c52cbb3ebf78ad6d0e58a9cc5f238cb86d06ddc69ee718b9286c15cb7108c70aba2b3e70a0a23568e62a0943c745060c106e314443933b9a5e18adcfb1ad909891b11eb136071dc8c5507267982866d613a0ad7388ab6c2bc329d5ed826cfc012a76f19c9a3988218e8294067e7c5dbed236ceeb30619a490a95906d44546fb7fd59222729df91a7a510eebbdd71ac0972b124012f970c39b4159582f8f0850e028d6fb234f1244a00d7d4bc171e21ce81ca925d2e2afbd23d4a56eb6a5023d7193fb1546da43da033abc5fb0f2f2bc3f54290fa6d20c8bf6047381407fad8c58c7a92af6d5b0514ae1e97e74670e750a1d0d976830681fcc6e292f87305515ba69d0a87b0f01dd8436d5a65b0d7dddd1c1a4353ac00f33e38446398d9f5744f1deaeeb4e2e164462740eb0d351137a8b3e5d63c9362a538e21928fed3076071d05c96d070ceac4705076eed0a1f266c64a22826c8cd4769cee50b3a53303fc4a5bbd4e210c0d2645487d0fcbd224d63d8a5eb6be5ea590c1893c18a1f5a3c2c68d287343f743bd6d904ea00c0804893ecf34395237e5372b59889ba0c9d1fa2e302d13c2e94a021aa63df3faa3e80bf1eba8f27120e25845ae8358c62998a84a232c5b43d11a4f275bf5aea2ec8c1bab9842ea2614ec2ee030530a52ba9101eab409698f939c7e1206d1aa3199288e860906bf12451fb6a486c9a6c6bbf9bd75fc25246bb6136bbcf4719ebd4212226e7b97ec531c84c31f66904e631171ed4d55c2d0380c682eb5f7b8a837f3b0ccc8dca8ee36381b7f5cc9267ddc4051203afcde2315f9d4f4612538025cee70a924a19ca6620035decde70fbf2ccede068b1ddb27b9edb09e66d03ed5aece4938ac49a8edee848260b224bfd6e7962d97ee60f805d230c8d1dd279911c49c01ba0f7a87b04075784ed76de05730e121c45a9043a483b9a235152f0964b3a2878527cb45ebce69eac7dbb2ad2021d8d3e9178189e9f73a0b671b28a2384421a7aaad69ed778b30e8e077e63a7173e756f25240fbe40ad1e69156ef56843d75efa0742a11efea63ae4d076295fbe6fa481a0417f63b7b1e5eed1b5628f40e3c78686b2a31587c1be4a591bfa28626150f583d0bde714e8ab8c753552a4f6ab55f77010a542cba9d000980deb78a603befa003f74ba29b677d53a72da7eff92310c0428693d5ee7fbe99b32f5d4b6fe01c78a5563afef4336d82e1e2214e2db9389226a958270abe5b7264cf60315f5925058e87bef5637502b2313265f7a7d268c1bb5ada9008fd6c01da67c69980ee4761022d52020a4e2eea3a905fc41783f12068291f85803b834847ab62adc49313ed6f52c87ae37eb8f5204fdb9699cbcd6887dba04511866690ac16199ab8cc8c7b0827dd10608367e664cd177b3758d2d1d3a2bb8e7ae8e62175da57d71b007a244438b459b49ebd2aa139882d373b52acb6852b1bf4fe480a6e351d3a6847ecc255e889ab30701322702ac1f31cbfaa16fdf60526665a88cd1ba9414600720906d97969b2ec9cc8dbea16bb005cdd17ffaa4b2eca181e279fabd82e3734013b7c862760ce382162675d95269bc90612924f1fab6e883ac02697a89a58d4e89f567a4373ebd3bd0bbd279d5d20bde63ff24dc10cb2fe235f7a5c3735f09c3529571ca80b6c9dd9b078fa726bf31555992765c38c5c6480a32da180196656575e9bc1044b9758bce811411fcf7d2f79b2632ba4bb46e4f9c1a949e19f07684770459bc3546a743fc4daed6874e254238b7ec78120514ad4e40858343c960ac18ba84ba168b793da5daa2748615689ed5e1f8d6b3a669b61bb2c0755e472892b60e97f16e0e08557544c43e12ebeff854cdf4a867343e8c32c570b8549879b5f3e323d5efce881b44d5298a23f8d1ad7e026c2df0c58fdbad2a1d1f57286163fd8faf0414fbd9f38be581b686316684b50c2a5fa6a54e2b41462f21a7d503f3aac04aac67c142060662c32aa1273d0dc0f8fb4499947ea15c2d629b125694007e3aabaaad95c1c475def01edc2243c1529e16f86c6bee1cbbcb233b38414f8f800c2ed772f81ea9a89a67405e8db86dce67ac1e266818a31a1dae67ae4f0053697d01f3190302d1de03d40a878cd722ffaaa693647f36581f2b4427c7070a17948e194be98e3eee1b62663f5c03944cd88462c01711e99d943610a93f2351147d0e02f2633a9074efd3295c7f0fb9b3c6c1994c911950e2c2e8170e98f0c85656dcbf80bcda19af36be7951e1d634b7c154a5861e3df779586ad4ac54c34c42e00323b66e1c3f6ce7ae6688a4b7aea13d433bbc017a036ec43ceb13e264e04141a93ddb719f9b3c41cce03eccdadfb9e8ba4ab95dfbd3712054ee8c846cab5f936aab94c202c0a2949f90c9bbb9937ddca230fbdfb10a35fd5b6082487f18eadaa173926a8324017ccf81574eaad92f8ddc70d4585b75e34e82c643d70dae5a300e26ab120bebb5a83c12917324849b9b8f1c5bdf154af4ac99435cb445eb02128417149b91c116081bda59aaf18140ef2bc55207ae028835fa038ca06210bbfb11ac43c50a7657c687a24508b74ed3a693f1a174261006d245692616a5fa3618ef21138a308bc0b946efdd1d8fda64d15e9256b637ad0ef58f0bd7e7a0982f7ef138555a04b57c695924fbc242f4c9acb15afa8416d5284f21424517312199d119dde35c73bd8625e7a54d7d266eeedbadf38b837c9fee88fda35690429069b43fea9282e84d47117a465160878ac87ac67df5bbfa8345a3f86fee172bfff0c0a2184e9914a09b02dc3d5e5f9aca70c70c4db170e68cfa030975008de8a28e2e9b124792d0606fcce338d5e11dc1121afcb516011f4167a9f56430654665c78ce470fa902e53ae49807a477eb9e6fb4e03beea5c03eaa5423744e0ac17d1abc548ce8989854726e764ac4b1c109c490064d77c6ab5d3f9302370a9143a13824f53e13288f9d5b1da91cef3031d3074afd2dbb3cf4a6d7e9c13bae16a0e108297d07e69e248354e6d527f76d9a617475cb14085ac564085c80276dc57d4b6a41031a3feab429dc45e61b3d19abc7582622174e7f81d6337aa97ca672a64d5562679c80d9dccfcb8abb6397cd7f8527c7fbeb5af40ae8e64b4a278b23dfcd0bbb6030ae95940ed9d30f21281fb21abed9ee79ef14c78dceda006d7b6100514d9da46ca952809d4d42f8ae722c9dcbec8f9365eaf22820ac3b907dd7ccff00b164bb74fc3fb8e26ce70e49d8fbd5289cbc4e3198515d2e80ec75eb1f728a6cee7a557ac117f0cd8f189c55134ffe12cd95da9976b9dc750c1b48cbb805f6e6a0e8e928d4cb407eb2da462aa9deb1c0ea86a0a5fbdf9528b5af05241d8519c745ebf80d00271df256a2969e7c6a0be9c8ee8b8bba52ae4f9b12b2c1f7e1f6c6cce1241beec981d945d15d3557a61078c11cf3f229e81f670ab09f7aad3bbc055fb5d2d3d16912d8ab7013d1db96cfcea00e5d10f5c5201aea9dd38d4823f563839eb0e60c862e46d7f228f75acde2270c01685e8994854fe83ee3fbfe42350f4bec63245bdddc83de2640a841670c1e67965d181850347ce1118bc8e69f630e7036f374b6f382e7a6f5d065098bc505d3bf725c4128a4ef7e2a06facb1878d8d2db970ba5d807040a4a4e7d5ebfaf993092dc170719ebfe63cea2f025a64dba471b110192343732696ddef6f38e5fa7e8eac7115758fb971745998cf4e0736073a719a537b3e16d89e999ee0f0f244052adff6fdf2cb6a84b37b71ced93c9915bcaa99f23b01f674cea1600da4f57ed62664d4f120e8da4a1843612b108688b5938086ef15b7e460a15bbc0978e60c7a087725c212cdbb0a062b5d93e5d12792641c4f3bbcc128c8e6ed5ccc0851778ba5861aa36a35bc8fbc4caf891a2fbba244a7d76994c7e7fd1f2cf449613c71b72f16ba0029fb0191e93b45261e64a74832ae3c1ffd1982e5ecb7157024bafd75c1e5812ddc30591b09fd2e72e95fcf45b060c5a2ce914234cb65d1acf974629f98f274ed0903602a73a6391f4f6bf702b8cbd9a18a4ac92b075260403941e4fd136500848f702375294b3b47ef6e78e0499b33e4deb9cb658714d2219cbb93f422d78fa87f17553eba3224871548bf275b646056b6514009fb8a6032fc0e9409750f177df7f303987bdd75cccbab3789b56c794ec7f85e6fb232c4de00a4cd6e03d8ea308b25dc3dee58fa5762708185c82bf88278b96d8e305c9453c5b830103dcee14fd87d1f76da413cb7a8cd30f2e878fa02eae90bac34967f7120a7379d0e0f528db0382a694bfeec64f772e546346ff0170137718ec7d2a33bb4acf155a03f18eac426612784d1ef466f4a258081482589ad54204e5997f3e92c2c1b08190ac78fd80aff472a37ba9731cf50f6c9f56afe1109ad1af84d10bf5ce63ff9c609860912d3b6c06ee193d855de9ef3b41049b757f5ab942cdc0df858e16139267780795e100e04503cf320a1fe06e3a451719a441e40cb9d0e78dad4095f62094a27b7b437232895bc338f5ba0b4938f4cdc406942722940c851e5cfdfc4b93691bd718fd4eaddb71d050fb1c37cce18dc3617782509c7175bd3625fd4b0d9e89606eb7fb2b00a0ed54839804260142eb72a4477fa1c331734e13798affb63729d209edbf4a50c4ca900a98bb4a0f358291ab785632966ba14b57b92ad73e04fcb49e963d07fa266dd8a050cb1d6a95eaa7c18a8c225502e5cf8d4bcccf453f5998aa177e5a5a53130ebfce7c7d7e76ee4c6668412a52a044d6fc987dcc133df96880185254081c738184688e7dfa69fade9376b03d5929143d3e480eb9d3d79c42865384e3f24eca2294d5a8dd6947442cd3ee8c2400cf18127261846273c3362956c65b11a2ad147e658006d611c68fd564d557e73e988ed819ad84c9b5454455adb63458d31bb7d121ecbde3e5e98476d89485bf05aea48ac27112c4c6e1dc68435c69467617ef027f76b7f65ea0cbb34b5c44ca0d8096aeae18832b541f515cb59bb64f6a08f7d8b69314824368fd2f081db48c7ef890c3b7799afa9d2c18201ab1b2202f2e42dc8f672e13f0c9a2be755776c3772181490b98ebe09baaca3d6f4b3a64e93c74803dd2084e34369709fb7f5949c739727af81c1707ff4cdb8dadfc8c00814ae121090c48a9af2bc882e73eb046c1e26b042c46dc3143ad20a78110a0704374546e3884b8640a5b06b57ae60e9600b574d4838281571522703b89a54526930c68a26c3c23f53946535c1d93cb7dc2e21bc772fdb4ab067aa14da4b2719be6416b92c707a27622c55e204b34085a743f77148d6a88972d6c7c3d7b4ba2600a1f59f2b959927ced9917331e3b8e5cf5fb76bf1b2cb3108bee4ff0d0a7d01a882d87e30140c61af2d3212c971f7ce678084e8eef547e0bc65ca54431a0534cff6a4826982847f2b6a8662669b9e48064c6a7e7ae0cc52ae6655518ba5765a7d2c57f4a7c3850dbdb2e5b8f657820f72dc215e34dd75d49c42454afa42b118ba87e195d562e56c346d57d4c2da3f5b094fd492da6b96b41737a2e632500f8d0f67f53414132b3bbf1f17b861de0dbad2b0f1299f402e538ac08b200b901d054222e08f4828b6e9062094cb11f3578de02b4a15db227bd9a111416762043725c2d7a533a518608a0a00ed3608a1cef5b5b0cada9dd7f4474236a6561362710bf3350565a1d7dcef49c17775e161c3a720fdadeb4f45696ab530aad3fd4e190227d0cab95f0ef8553b98f6875b514696f119c0a18c7083336aa63912d980b351313ecc3f66c27a4e61462ee23a0a7303be455d81a6b5140fafcc1a71acb192b30a80b3dbb29d737b67a2238e9c7d8fe553028ebc9726f6391c81a88f33a83dc9e372dae6cfd756ac34336d1cec50485f887843086f90d11b187d6fe9e68062a59a86e14f646e01156911e652cf54cce7ec15d98bcb68b0402c29ef3f8b2ae24669698192896d29aea2beaed1fff9c63aab186ebd93b4557db92ba813bdc8edddcbec07112583da2333f62e6bb075bc12c88f7c87366230b7ee84a3351ffe7952f8c03a0affd90a56745a28dd8f3cabd53a33b7d0e5029fc6af0a8f8168b1fd4364b1c5e2ab7fc0a94a2b4bcc7904e3bb3f58d139c2dc8c5e92a334222ec27a10a1cee06c18a2bdefbde33645c916d10ecef3e38994ec8a8494c2aabe934a70cda2b8f31e1649082252aebc457394d42cbfd0983ff21625ae9a7004aea66aa6c3b6b70817d1bffa9e810ea5599461276c1afc51694fb9357da37fd556fd96de313731a7e92ae2446715380694f9f8f3a652b8f5cda16db33442f575c54c7f42ef0da60bbc456c8a5323a8c410d10b8a134a49954a0c1a6d7cbebe91463756f0a526aa7b369438a8a6f9c8110a68433f6c35097176ffa01fb59786f85ef4b2694518afa5813668c5222faffad826b97ec92c8b0739989096e970b366a2b2fefde632f3e199cf492833be9a54411d9d78c536022ce502ac1deeabbd86a49682275b51ba0e797c18fe92708457230ce35cac66d4701dd7ffcdeb316fe4522f27a3e099653808749ad7d87c7518fa02fee83c10e1067057961f5a4725127e11a210ff99d0f9065629632f4fc0e82ca94107886a2f40a37731c45cf22c160962f3d59129142d642263f280a9571fd1127679786cfc51b9ff4b9f25f0d3da7b2294c84f3024376cc0932069de82f3141823447403e555fa6e04d6511272cf0d2228c98a2749be9ccd2c0292d060e4f2012278271f012e2c32b652360bf6e4701fe2b84adce4a3078dcafc8cb8474215346293afe42439bf02cc3d0da7d92979283d6c8f1370c68f286441858c61fb266776eac6f8dcf2c36755a16f7801bdbc9bac2d4492e6ebf76efe88df38f0d3b87e8c4a3999236902fe525b2db33e36e666635380697508fb3aea391b8978c6aa6585a3b3201beed8a582167e97a90ac9dbc75a6513902f9cc9c80216ab400eaf1e7433c306129641faec246b2826fb711a2b0f5a0d7da4bf0a249e5c8ebdec98ba026563e0b81ee30ba846e42d01be1374026089fa1e58a7f3900c1d04e11d15307900b4c784a3fda73cc3bd8ea1eb81bb8b232613c6fe6344627336b5431e11041e9b5dcfca3955c858101333642a04fb71b99172035d8070b5315a918c639043305f214c083388abd9900203e62c52c9c8c3382c276492b971746b4427865414beca5f1e2610ed5a27e9aa4b453083c5652ef161cc04f1d49c3b6ff5f40444af49ebc71e15de033589e68c5b982e1beab107b85793864a084eb38182c94d0ca268cb4d59c54d93be162f6fa4025baf51eca72dade4d00684ccb84fdee4d5d6ee3e7c85cdf13bc1ec699dfa0018a6e3bced9868757a34e860bb38475586ccb3177fda5b6fdc859b5600580b531706db503f2bf55a7416289fed1c5e877baa0f37871be7c09c0d0ef7b7ceb1301920bd49902f834f0ffabaa2611f08230fb4d2e7fe6e075c0a1765e753b899b6bb6a5c5a779754369f7e4ed93ba8bb5bd4cf7194b9580d8ddb60ce85da4e0bfb63faccb5d4778750f2eedb84bf80c3616f1f8542bea8fdbc22eb978e4a030819d8d705c0c4aaf12ba3f1abe4ea7316bb8a3f94d0e694fce11cf6c935530474e099db288d3fe924b72e99f64aefc04314e637a57454e930b43060d314e992b58148d3fea48cf94663b07f71ab7f1255924d261158c472bf0dcc1630a642afbd931ab7d19d340c9344aa8f4daa86be9bb031a1ba52f730573028c50dd95fe8e7447d39832e3cc2d5aa740196573a802b4b9b70313b173f0d503bad24f0fbd689e06a401fb7771ef79d80d88dc4bd36bd243a4dc198646261176094746ad89fa779a74dbfd518c23d95335cc6b5299e0d6467788452cd09106a3bf62e537faca88892f228851266b1c6343248853388634e9a733005a145c6d46ce45f1921a120864c79a9e5c4ff0a26603e681341c3bb25bbc16fcce7fd242a904b81271a8b07c4c75da1fc39925d9baaaa8575286035fe5d24571ae28c0af6abb6c96171e6bfd9c4ab18527bb2d018c6efac2764855d70044cc800b9ede4b6b7ec38ef28738a21933bcaa25d105dedc687e8b8189650eec4f5d1db1dd32ff0ecaaabcd16caf445bf47d88261c2f869394c525e10a758e30999ea6eae752dc4917c6d1deec71265482f4626aff6845f47be3527caceb76c1153b235776be5e6d2a4a4ae63c21000d750c548477260fe0891eb1b9e9f1bff3bd9de9ad952f1b4fc3cb47d12d2dd4da2e585fa095755e56e2c9b6aa40573bfbbc6f1a0a34871e358454c5c9faa2908d4b50bb10f403f1e381b35c9ebb39d00aaf58374b4917498563dd488e341b7c0aea43de8f160de4cb5c2a2883998f6668a48e9e21d96d04f8f07311f34efa84c37040e92591d9feb84c23f32a7d7ec04f35872b51a8438a9753ce82171e73e0000f2d7beb6f236f2ccac0f548b1b06b4a254df3508dbf3e37aad35604118eb601c0f4a2296ed132268a9b805be5a5851cb76970ee3385bcffde98f07bd7a968552abe772ed5dcbd45946dcc5f6cd302ed6b8570a31f7d356e323f12f77e24141f7fe9c76d60dbaac3683013e17af1318282172ea45f93eda84fb338432f4cc5d488ccfaac24c6eb676c8be18f9a2ddad0c7c02bd7f118d7d49c669fad6fae566fca49f9d9adb279d4b1e6333ff0610e1e253d632e83437d359ecec21d3de502f2fe217923327761663d93a7c80ca6c2ce5993b71088ad7652650605e8d982beb012c9159c317839d61d64a9be669f10e85d98d582c2c36af66b5bdcadf66ea4de334682d559be1555348dfe01e8ca584793797476d32eba446061bc900a050bbd3676c3974934f974a10d3dafe8630fec658cb812e00bf7b81586474b0e25f3309bb501781506e676da8086f2924888cbb7ffbbbb9df2333ae069acbc92f069e56e916ba901b6e9d82067a262d6700f085dc5a802dbe0e99697723cccc2e77526c26f15b34efd455aa20374acc9b6114c6a64e36809af56de7f30e72e3c1b27f92f1ffa46ab97bd003f0ea39ee3e75263c072aa9b567572814d68a0671fe698c82ec6003f6dee5943232214b76d49e39151f3069e13c8a378baf3b4d1d08e0fcd63e09b8c333703669bb65250270f60642dcc63b0eb78bec38955cac4db336834fdda5a419e9352c371372cec4f59928b60ee5fa87080c7458df60f82162acd52c531970f0e3a8394d1fd6ad860397afc96c67c400ca3f73f869f892af4b1a046ee5ab321e1f65b650a76e2ab4ef6ad459b23600150b76b800d6d88d3b36ef11dbb710024165580b33fbc125f073b4e6462a4d2b1a58f4ac0315a3b5709f7624e63a3dd1ba468739dc167c3887b3a9ddbc456e12853aaf91cfc9e2a2259cacf0c5794b6ed9f3962840f5418c6b772cf0724b6d6e3c3da2ac764d404d5e308313cd56ee1f455c5f79738b885cd5da77ad4a3e8e2b33995aef7c456d0a7f5792f19c840e0fd9b67810e2f52d7f503870003c3cf4d7508d50e2b6c55e5b93849ec62b24bc929aa822e139c9b57a6df12b4818a15622cf075f32e9eb4952e6bb9510c109e4608ff6931025cd02bd96d534175587fc4d3e281ec845f68dc2aa060e94465c30bac79c2f8bab7cd2b096e3b2ba66c8f9b18ea34813e2e172bd55d47ef937194cef571262da86eb9ab5b32d1a317e196499a093181a8ffea317296b928df806c3f6b39d64ad6fb8fc8a78b16b1da3275f280f95b13021ea4740c91bc8dad97ad2fbb7b6b2787745aa5a46106c7edae4f062cf1254e8435b535f477dc9f150e5488c20d88f0473199146c83405bc8b5507814d8811dd049c4430bdffba1dc7727fd5a25d5cc547b4b36d52a4b4cb2354dce4100ccad5b59eeb53617671a9c6bedb62c6ebd901743dd9061a73286ca38b830deffa0166562a5b61fccbba29db1056722ee328bc16b77912e85b3d807c41b0d4956d295c6698e070645823240216abce102d212b3ce13a24ba87c5ddd6ccbcf6238743943edcecfd462828d7c2ebd3be4af91e738c60686a334beae5266079160d4aaea3cf278132342a6909cec0090eac12b2eb41bace7b602b7f4e23a7eef8ced7ce0996b3b9891bb51ad6f799985d6850c0225452228c159eec8056261ef2ad00d85bd12ae2b9c5e2642bb2606f092c714ee3c9cf04ae1e4af59d0e0213975ff9c2de2281884701a08c2806e3e876851db50256794bbe278afce23a36d95b7474a3dc80a0f7b6f64ba8d3e82f15fe2ed04432f147e9180561ee837ffec21a1a13bf5e304d39bfbcc6b0c4aaa71b315a4a0f7cd437b090cc280ec7d860fc7e6ee35315ebb906138ec05457f98b36530933e1d391c424943dec3701995ac57221b8a2fcc90063d8a8d12402561abfe833083b300c6bef70d9d53d1b79eef8ad7a91b95e7f1d810071fc6dc24d44f18e345bd4882f30d4d186a09aa3cc945293c33cdd60448b93432aaf85651dade7d436ba4f0e77a8bd038eddbabe862f7818be49d9816b3316eb08e47aaa6ad756fcda54138663c37475ef6184ac38125863b4066babe67e3759b7523fd551df3073cdaa10e6aac83c075303947d746e0bbe7c0d73ff5844b7d15a45e834601395651ff71c1fc2da244af3131809795685e3d11297b38f7b5ccb9b5663cc2aeea5664959d8d65bf9daddb1b2ddcdd87b2895b241a80e22b326d3563c80e56a769087346bbb94a9fd96c989f158fbe28377ea9f6b55684b4fbabbd525399ee01a086e08ff5483f33ecd062dc32b54220315d99098901ca28b3403e0f89a07a893d67278a02bd865366f915f1dda5a7b2c71227c5314a1bc59e8dfb2aafcf87e07433d25c54e9b95a526067e95fc40b6a6fe4bdfeb78f4606c5ac4ce2d1becc716dc2c987fb919d7cdc25d395f2b73d54c4cb6fae1351b928086be2694bbb87e244bfbfe15362386db0016d7ab02864a3ca2aacce0e98015cbefeb3a773e7ffeacc296df5c579b3d0f07052a1b9f48aee5f12ebda73f79b95031bd48f223c4b638f8d4eee87fb1ff9cfb295f2977cf8f269f9f93109573ff27ce7e99b8bb31d79d9ed602181829515d135df8744601e8179f043a86fd6cc057b06fef9af34ba30168e46e553c5b3e0fcdf9921db8a1a419f6c7babd0edad46408b9b270e863a32cf896b3a1ac7f25992fdde4579bf7e95ee1cb161aeaff8af849c32ef86009005829537f0a521ca54ca16886c3fba55476b23068d7a24bff95c6660dacea458e1006fcc4197d6b8bbd20b77f6b14bdfa37c5c495a6c5b0374f8bab7622b56039fdab072030eda1ce03d6a1330e0d33e0046d4a70667c273a5c61af4f0b193b896c5fb99a68b26f0a7b442001ab48c9e5fc04464eeb386d3947db3e14a2c38c7a25186e75330c5a816c210b3c65b43a6001f358bc0c6d8406832c32ad5a3002fc53b65f49ba405240e31b314f5aa1fa4dc9ee366fa7e0c4b4c5680672a4b709da37d2c9448ac1b8a317428590dc47429ae841e25d718682497dadc2044cdc57540a0c67e6c0f96033ad7ed71b48bc524a129c0a4e0735a397cf0e51e5765f56279c2a72d0dd1d59247f8abc64ca5d0519a691b710c8d5516f27b1cc6930e99243c1971c65d27414a9c34579269eb13b7ebc4e999ee7cdc39dcd3ba037af9eda42ddbcd9d882d2e816f85b6e7bea388e452b75b7841dd859f25219d08f479dde74cec802e86c81624cc7229137d0979b3ee3342fb7f949b9ae9fe467489b7b756bed08764e7221da1abec729c513bd42693470f36f84c8205b9e793515d70b8618bd0398b6ec7599ecd8c4995e481770d848d81b6a1d1384646521155f28833fba10cef0e603ab91a2ee3e0e0116b3a7685f474d41122cc947b33199d6262ad28b06047715a68ef2c94b329b38ce8d9e428e894c0197cc66e05ef783eaece0221a2437bf60084749f82e3fccf9e779e129c49f8ec1624134fae6852f8bebb967691ab790385e6c3aa4a35b88b9fb1c6d167b26a43e6d10c3ead4a79a5eaf8fb68903bfc5165311637b894a16a9c34eb438170f69ca781d6885d6a09bbf8bf0dab88a38a34f75d0f427d33b3d2a796156bc3929b30efbc1c1e06e226cebf61795a52104f5f95d470534bd0bc28bd19457a79a6649c7625820554d2ab695f80ca0c708f0cfd0e7d59515b81bfd9b0758fbd2b9d7bc1b59e764466416c7ac1cfa87320eafb891d73ac579d984a3a6d41d82e671ffff9221b7c57edcf2187bb0b2db16e0e445722a1dca40c78154dbcf7536cb2527d87f4d3b56604b63640b6b3978bd10af4ce70d0608c4c66c8d6260c8c802e26c4df85291528d6a0c5097424aa31a680df5ec9a41070144f342d30c5d8a4148283cfe5fd74a4a5be354baba5e725078d7d563fb4939b36681cba48a2ff5ba201ae93347547f696b5820b66e436c0c2731d895458878eda0d6d6e440d60ae1dd3a5d34e824b9cfa96dcd69e8329237df73cc6d8be2becee34b5d7edc53c9503a44138031a9be24f935b8e3defe95a8abb6540499a91385d55545dee69321fc1272d08e8ff0b8fe0a17e653f0254aa1f7fa368c6d4d5de4f29dfa8ff4eb976df7b8f554a571b34aa371be258ac0bd21078f044ab5154c9aa10ed56668627ce492905a42feedbcf234443820730740fb1ca9993869643364dbf4b4c6ff4d92bee72e44fcbeccb7f731f85d23195fe8015f0b5816b8290fb37505751b8868c5365152005b97705289c65e7315b5b69f76193c4f6dbb69fec77be5f305bf426917c0249982589d14a620c0685b22191c4a6365d17b8f92b7d3ca72c35f42ce9af50f627b0029ade625b103523a367a696014f20ded1862fe0e33ccb19092868b48ebb4ad43969951db46390c6940d8c8e80d74367915a7780044ac04df259b3db4c7dbeba6e6f56dc61edc215b69b283639aa5981de21d14b8a62599a0e59538442442b2235b090a1c5989d4687fcc93b9eb0c22ce8207fb6a0389ba0870738319a125d6326332756fe54bfd33f9973c0c35e91490469c317536ad3d848c878711dc1e52952ee89b32f939596fadcbd27145407313520dbb32e13c5229e35f9b857cd3d4604a8bbe63cd4cfe9838774a5d3a72063812d1b66e9fbf1591ea449964d4fd451e92f5daa1a5fd6e6e48a21a4814247ee3ed4e763511169e06f9c197fe00ab271b234f27f993c0c8011d1401b3c3db4754ce7a3ec6be141f91efc5a2de8ddbba7804f99987ac9cc8da33607dc479de58405843f2ae6ebc8533efd97282c32de3de3e835afa38d634d1aa87d76a9ebb0801e421959959cc34efa54b3cca73927fcf653b56de764a20564f4feea9a7a7c2603fb351a5934b33c0a278a49cf94a7822a52b35c4d70899e6d1a0e7b384553f4416387808b62bf3766ce0eedf077fa364347b031024044b52034989abc811bf4126830bd443ef833e5d92f47b1ba082a6232e46cd3ed6dde994c71ab76827e18550cee24921d0f157683a711cd58ef8afd3b27bca1f97afdec1eeb2ee009d895ea9dcbbc99c3657c7328ddb9258c1a347edf58200739425ab30d9c1ae1ff84bf291e616f5b16198da5f74ef9c1aaf881ab447b549e7ab1486cbefe1ca097e79ef0b868d7a501c64c178a7756f7547286aa0dedad17b2bf1c4d8608588dea2b765f6074d57e54dc95030e1a8601650ac749c9395b254de1a79833ee153339322bf006b01e7a43a4b15441857e808593d775c7a85587b56937194434a089469f741a236258cb04a3d5dfea4079e9fcb2711a1dfe68c3bc22d150fb499aaf431056d65079029454728b086999864e2e7fd1f968f72d37ce77601a727dd182715de56e0b79fbc661e66c289b0ad74037a5e536958fc95eaf2c36ea6504917550966164b5ebe2e668ce265135ac4b5c949f9fccaddee62f3d9e5905a91abf536bcc029b51dbd38f8e01cdd3c414975086a2124e23ccbb19818680b2d896a750999a9b34b826e45b95977c74981cd0fa9a64bda3fcd5ca96042f914493b8c8172f4e6558594275025dbc90509b84c5580809d22cbc017b9f923bd1c71b845a928bd91ebe31a50af6e3a9f38d24086e0f3d00688c88cf8b4ad315b6202ee7cb25674e5823ee5f269c7c281bcb207ac90438a56ec79a5cdbce21861819b798c98d326da3c06644a4870ed890150fa72fc24067cc40d02d856ce689b315b63d1c92a1619fbd9022bee6a94e88c25209fe68446a40b229005f70a4e45b509bc78fcabf4b0995ccd9e46d9058ee6e0acf26349a9dc36324903bfc6001880736541f402c5d40350d0e331b822d84ecf43295e28bc7ccebd75d1542a6b137bee79bf053816251ce6ce89883b1918e6f879f1a51324801c53b3edfeb759a41730f928ce53d70eb3a01608931723075b9030503eb38297d38f3b20a444952e7c4054a0971ba4cf911ccc8f3abfa0dff23fd170e0cf0ddab25f5ce308178be9678a6f7aaee4b1ff45bbffd4e1fd85d9fe92cbebb576bf28851cff3924e5ebff27c1fd184c37d64fe767f71f492abaaf7fc96ac23cb479ad16c5bdb4019f4c84fdf17fd2ef546278f4c27f937a7c1bf053772a53be0e7886572a930ba9a9cc55be9190a61a23b51486c4e6c901dc17a6eb4e7626fa93a7051e22163f8d34ff8cb2f151fe5879fc8ec3f09fffd50510b52cdad8cad8f5d317614a36048f3391ce800c49bd09bb91e90f47091f96fd59c1a5a7dbf47ef884e14bcc756f59815555016fa8cc0dc3fdf9de32af5f64ee14ff57aee0a26cefd51abfea360c8984add837d82b450da5cb2cea355f7fe47b63fb196b8bfec78be2756ce9eec2cae5802662eca7f98303388efdb864fd1640f6273d59cf1f32e1d81fcdfeb30e66b9cd800f5a33eb1f75849a41fe574d2c5f0d4e0cfbbbd35186c238f2a7f064367c10594038be2e51cc942037a7c5f2b1a6866239920277ba1a65e7a60c4a23912883c430c41a09d8e62aa53795cea2cfb61624c836fb879a9574ac9ef68bb7fd00b5f3ca7f94766e9c9a7e225502fab91b99e0b8ed631c1ceb84ddb012b8e93836fbf77fbd56001b1f8b18b61a43872df64e6a94bb90c13e32541878b96ffcad4a8ea41924ef319c0a65e6e068b7317be246a2d1744682bed142da46dfcf04fc1656829a733f092bec40124f0027eea838a5409fb4e1fc1b8e1fc245973fa6c53fb9a9661b0c0f9e1ff7536a92488d09ffa3c1b5a1f0a4cc7fe88ab0960d04b17b4d8f79bde38f0b2b24f1ddf30a3fd75b853651b4e73da1c840a1f0fee536fbabb213292ae7b1ed40dad312024338167b60528609f15457ae7b6941e8ab01302c72f6db288ce77f7161eb35dcf89bc84d70d36ee6cdd0ebf1c6ed077bf5caba58ea497aff1d9b3bc4cc9802a7b4ccf2f125482d6e0d1c6c4cd9b43fcae01f82c0562a8fc3be3fc2e534e939fcf2aeaf4aff5b0cb7aaea70a5c1480de76e00c2b35b3a205851ff1265490d126f0df0614250de7dd3bee49b0b39e673f2e4a62cbd0dea0e1f0421cc345f63afc80dbc51d1901135342f71aa1d2d5862118c869d050726d2ee09fef3e1384078a916accdbdc7fac1bc9e4042fa26fb9fd80551a75c67bc8b28c6db6072d070f54dbbfcf7bc826fd172fb42ca356cb4c4a9761107e0214e95cc482d756a342d66b4b6618d976349b25b263d2ec79b53c7d439cb1bbf8a68d0bb0ad484246f111a908c2be6adf43360fc50e093c311deeaec42e0c5818aafccc6c815d3244d88999daa4257510c34b43eeebb2a608b674e2b3bc4c38ccf2659fd923c0ebda89cb2d767b7eb9dc727a4899a605b7f5722bb8882b280ae252dfe0a925dd002ea5db098bdc349b2d9a57d21210eb44c4f9961c7f89d136fb095f9e0cf685788fed0e2202cf27780eeac7aedecbd2568d63627683ace9f5b6c69d8391a6a2b61d18c967a9c050ebc93950dbff161e59cd6f843de895d14f302161659c0018c49e36cb7bd39bb81a8eeabbc06540c5933db06a557a904a3f9c56d9d0786e4118e1b4b53eca846ae0212f930d863b8738af580067a3ee5b6c6ef1a64c1c27215324817ae8ae9edd62d0af33f031de707c06431e6e2de6f00edd47958444e5e7e7de3da0349f4670a6aa1f38ed2300ac7aa606d111080b2695042cc0f434870bd3bf710cb5255fb557f71ac6957f04684ad49ac63ae19987e04fd0981f4930dfafa236c39610edfc18040e8fbd7afe72dfe70a04597c197fb41d998c8449dfef34e650562586b6d09a1cf9610559311b157de674834e0b051f0faa74b196d14074e5d78b5ac6fb2286efa45a9a1d1189ed4573fec3323dd514af5d0f5de4e4affc147d2af527a69fce7b5376a90a4d86678ca62e56f5cb250fe3796fe02ae90c4865677b9874c40ace6bc288daf987dea8c841964cc37dabac6b5885e52234433dd6b00525f3dfea2beebc068bff9f6fba915231bc603b87d7a227dece951b89e2c2057babef5c57559efa59b2f7677e183d53e718e978ca1df9137daf4359a884937b40596392364a48fa217255d2180817fea2d3eee3352533e66b8c561aac40a0fb33c0044280c7059dc11cd783222a481a0cc3cd85d985b13ac204b790a357a845fd1502e9ff07ad4c1b51885e1a2a374748c00af687576219f57b49e8521f7e46055b6d1ca53111570d217560686c50c58615b78c04c1e217d69cf5d5966d6a6fc20a0b5ad2d5c541750704a9a072628af962b36de467b563026438d740341e4d359759609402c1935ad60eaf6f99d06b02f8781af16b0cd381e06f58745309c882490170d5f546aa9221348173440a0a8f755f335ddfb2680a1b6975d95fee57ae0990c4714abcf53f2bf79bd03e8a8e8b09489dc474a958b10e62c9992caa0a5e96853d7f2c490eff718273224720119c453ae3cf13bb8b151dae622a1406ec6d2b00913c26423f6d3ad5f16ea1f1940363aaae7c989742b8530d7ebfc07c6cbee8dfb1d7911c91f1b18e570dec5182dde7846af6ffd200231b46629dc0b791cc674c0568c9e4ea6b8f86fe1ec81ef7ce5dfd505b78d36764fbd5d17cc2e357f95e38e885c71d3c954f17dd6209ca7d83975b9fbeed37dfc13966708922ff9e13ceed8baf7881c543790cb87f5d2f80643703c35c84351cec52905dffe9d645f08bede8eac7b3377119700dcbecfe8850b0d07b1a710a90190b66965916bace8ed1d34855886ae2e0b0ec88e0f50f61730a87d8a062fcd810156c26a3611373454756110286255659fe2515023ac282c454b70f80fe0629c2a5353b1802d35e33e619e4e4c06ff81420ba10bb08d31ba1ba20e252ee90ae239cbeed027d4af5f06cb7482ccf30bc254b19ebcacad8b580c44206ed0ececa6682e8f7ad65e77a43c663103b3dc23cfdcda54e48de000473fe9d6cecec9bf20dcd05e7b32b3ac8b71d522029809e537f61b796e185dc8d63e700f03c07e997dda89672a6e4f6eaf9058f0fb884ad6a6d3b8bef13f6fb76da64c2c90233b4455769bb06b6f3b7a91dfd753c986ff6157f6a7e653d96fd135e32b39aadab067499268eb8650fec8dc0261412928500763aaab80224dd009827262106a2c900a6273845a42bd3d07c5cf9f21138a82eb3b7b2be3b7c264ce752edaa35d423eb374da021dc2b617f189aaec1a368202bf297fbb6011ff5c0157e65cda8750b7e3adf2536720b8cb94419bca4a4ac02de87fc9cc95c1f64df8f02ea3a05e8fc19f85d63cfda3c9257231064f9979553bf202ed6582d1dcf75d8ab168ecaa3860cbc08f1f188a72fc24754cbd51fb5fac4f5bda78107b25d034480fa370074ce14c2f98e31a6340372b6a85b2dd7d1c10b65872871a8c89bb5b6d6291f1ee8c83118fcf4c6876d2cf246139e3c829f00c64132065c272dd26f5ac72cece4568586c93564d70375fc7d510ddb0e60f86a1f0adf11ff636dc17f622a87faa8226278d1085022421aaee77122a234588227dc00dbbe8c6066c38cee9bda5a9e93c8593b917ca05a114fc24e03e5775ec6095f9036aadd1e386bb00e4272617657d12658342e3426bed1b2278c556ded8d22ac052084371a8558bc01933caa1188ad95843ae00892f1479aca1f8e0c1f94654fe6a8e966fb04ad38c19ae7398c83f0b65d8d28d656215ab5ec576a3b6082e9125ca956472edcd6a12502db97b0bba51b225cbfc2e490961f3f3fed7880fa08b59aa3175cb616083a360c89279efbf5166a5c151d8d7993aa16adc259eaaef8c919bb1881ac1a2c0896bcaa74d5b72bb06706a6ecabaf198a65b58b72209d2378b9bea7a78b779289c2ec7254d75c3544a945e6d79cb32f42bb8a4f0b00434151163a3a4d593cbbc6426d369380a067151dc55c3c44113fe7b1e8da9612806087161ec3c75d206ea41feefa987d925e7de71b401fa6bbade669e311a6bbcef828393d468030486ad9d006611fa4aabdbb8abe9ba4aaeb9847216303cda8076fbd851cb33055574b202204a0c3c2c487b8dcd06b37c294674a88fc99b45c6469ab17d8585d2d106407b08eda019babdd79f360aab765d93f407d2f46c367854779e40c571bb6e430fe9930201960b2bfc186d20616637db5bc8be8be444fb7c952140884398ca66b1e00319a88c4f6b36451b2c899e79d3f4a8c5d5eafd4156c28b2ea970200342957ad083f86c10fb690b3b74464bbdfee0b301fbe685ddd420971c29401349a7a5e61a7472f3e2e6d676ef9ebbe86ee1cb50fde19a33ea892cc59b4222cad73022a4a917b128a7bd6b60622979bb85b2556ad77a382574afbcf15e4265c35577811ee9148a5989c3870370ef610b364f21914145a5122ddeb6f87950dd87e3c3ab69dc869e68481ae43b4fd0b36868e06a391770e823e6ba442b8b8453d80d2c7088bd6aa039971a91da348582c4e51fa7eaaa558a09d72d0cb232b291826038f626a44e4d0463751c787c021f6f0ad2dae04ca9cd1aa4d2466026c8622499ef7346d7fccbe7490f2d9df3442051dac959c7d784330b081fd3736317d2cb69ccfaa5f43e554e348a07c7a095eb4101278aae78b6991289f71e3a2357e21c2fc2e0e793a206011848c528fb79c64f53f219d9a6c5b81a1650908ffaa9dc7e9d7ac07c647aa10b15a8fd9c31be18ce4aca22f00499341521cf195c24a79cd18a2afb1a332650ab7802d8d1fe5baf5f42471019d50091b5ff0592954c789db462c19ac469a16ee40393b308b58e6f35104913ac56f5bf340e7a4d0dbae945c56cb7e0e1d9566febe127029447e204513d76f5fdc4a470be7917d9e972f0e2afd2430052b0a9f4a2dd4669f739f8edf1917bcea9c4ed0079fc420fc25f83879e54cfe90781411004cc33676ef018a598ccd600acbe051a3e1093ea39ee4d1fef0718bf9540164a5be16a1d48fb887b09f902676f91636cc4d9ee83a4ce38032c88dfa74628a7b1251732d4ccee2cd4ccb1ccdd36111bcee342406ea787c79ce397508e5fb2503af2b040a824356724e30a502179bb8c6a336c3371d4fc658935d4181f5c1a793c8f89eb10cf53ba5385894efc739781f1cc15a12f910dd0cb5fe0430a9ad4ad9e4569ac71aef71079484e34082b2df19e760f2a821145f0f7048d6f4146aa939984803a547d77255fac21e1c2ac6665f153400335f81a60630f396225f3e2c7465cfd14e6760b20e9d6edaf1bc6705f4cc8cf575e2c511dcfb48c8297d7e946c67bdbdffa73a0207c97c0ab0e262cb5a7c0b733a4bd8f326439cd44a81de72989a25a3d10853f3fbfdd1650b725039e2c57eac1650f9b10cc4473dc3a04ae8f4c4dfbb087ea1c1308b2e0fd02625aa1b514395d709b3aecae19c0c31c5d4c0283126e959efa474bac198aec8a1a6c53052b04857520e8bdbce80c7f34beab607e660bca8bb97ff423e8d1dc7537b1ffb2fe2a115d15c5bdd556cb94fe4475856c94c9e296ec990a240a0d331fd0536d0722cebe172aac5afaf47f25e366b9718e26bf79987f9202a9c829c20745c35d6c2e852c984ab202a6d556dcbc04de62c74ea6ab2212241bafdce3345136362a721c1c5c2019b6718b0a7e736e5acc00333d014d7ad6a56d040afde47d361f19c93947b37c97e24d47655da3327a9f594e46c9f43c58991718232130a546c03cc0c81ac3b12e2361222ec87ae6b40b951a126ee409e849cf57c5d66555399ebe38e0b95e8b2020b79363c5fbdf73e0ddf2d0f86165ed56acad1c83ffb6a1192ce5941e28d3270113c5100fa50a1ce683430c4301531c6e7b1de339a102f4b0e6b6db4f23b16b3fae68f4426b151783312d294e22f330dcedba593582e6af622e1fa298f97de5d2f9be1593b7786e33ecdc2a6ea96b036d7e882fd37e39681fef2b7c0ca90f464bff5e2a1933be6d8547859e972b94957afd0d0695ed206fe0b75fab9f04cc21ec242fb26c8c09024949feba9f5daf4012e25b6deeb4f25ef105f223b0c7d71fbfca6d43f5663f25c5ccf86c15670b0434c33bd77cf31563bbc19106981a6557d2e29088d67c468b07edd397aa99b1a6424687092c6ae79045722b4215280d7ac5f07cb1180fa0c91404b1ffd0c0dfcf0b41d1dfbdb1dc6e2575ad61f401f1f71827f541f9cac859a20b6e699450c1813eea20903b01bb8c29c003e2a4fee05091ca637f9e1fad0ed0227512a2a36bd7e63aa3f66b388bb52611d2e246c9cb591142f0373b06edf2c9fd78b7978f6783a1a7f090bf18bc5fad13bccfdc237bbf7cf2512431cc7c5430f313f0fd7d4884598b9cb2f8632099dfa4836a4a99296f0b8a347754e78c3e08ca9216a0423366b4e3067e76da5298f5aca1827f1d4bad6f03fa2db26c1c2349f32c0ba210bbcf835823c8c420880a0c8ab1b4824158d21b1cccb65b6167bd85c21dda6e3e50bdbccd0888b10144041e8674e3036d6a178b31d18ec327ee9a943954383479c93fc21a8fb543065b21654a118c13cc0f2c34c7889a633f4904931d5ae0d2405b973605be9cd9fadd91536d990f5974d7970239065addd0db7ac20f966b58c0cdc9f814d94e6ad31580f27424b7189e1d3b7976e03d52238ff767396e1c4f92966747657b04611fd9d63fe2e0811485ce948c095fa66ae95417786cb8a647c6074dde996e4f96d5200fa995f495de60bbd321bfd2ae379cda28fc82506666f15e7672fcf57298bd7c4b90f62d4ff8c2c8ba5ff6d285714264c6a6821324f29d794f9c40a74abb0bad2045c327a35cac25c12a6f60f64e035be2b0b92fa2ba60f9e53e183229f99d0b399168174bee85f673526349e43440e568724b72eb475515c35feecc644627f181723da4c27aea1a9d9eac2474b71bd45675dc744506bfab468cf8a0dca0b2b01c517c37ccef474b744b3baf5cc8658444a1c87c849f550b08a2612abaacbfee646a1bfb6a41759b1a0b44c0de52b38311ac897d613c277d5efcd100404515274294d4e93d9c1da388c9def1ba4b5fb66c18451f11eff5a5e4b25f62257a84f12aca9a08de493aadde18408532f7646c6bc75071a17773b2963e8863a8ad04f10f1cbb87670858c9773ef6195aadc4062e7f996f310e0f8a4d4aec1a157e4fba89a2646b5ecd292a75c1106a549dd58f3835089d5b00e074a822f49b00a10753b5bfff2b12d574d4e31daa9faf8a9c348e65b610a61d3f22769962ab6d4a853f17c532a59a29e36f93ad5c9db2ecae4ecb64e59a838b57e599d04719246a41ccf12cd3995bc7766229488946189c972b15ce6cc5924798dd989f05db20731dd2d2cd1f20a94c1063bb75b9e4832d7e84d6a1a4de7573e5673f217bab3320e470ad88db461ef4a5d85e6f00d782b8db003be0c420cccb532a782b8608a898f451c96fb7b92f3129d7a458547f8a928e373db2134f70a36f491a42164b162ccf162496645d1d8d9c4158ff59da588825aede81c172a59ac534ddf4a873793b168c1aecc059d8b5dabe17a2b865b1d32d0dd6ff646195ce9e5f07f684ff2394ce5f6e7f449b19574bf66df92abb02ace7520c1a4444789ee12abb63d8116024c62c7abb87e640e79ef8f18d96462fb8dd631a940e300c2ca9ade500ba0aae6152183d96bb6403537878613454272ed7867e19cf02678358373aecf4b66571b0f83f850b5a7c652e674ec8269e56348e02be54ccb12db18cd69b23767e7269993eeb8d8c5279645ca11ccccd3d2fd1da18d5afcb718d96750f6bc590184d1854c8ed27ae2798207ab7c2a3ae29907e1eff4235f7ebe8040cb990a7051891757bbc9593d08699c76d50ea016a7aaad68870448f34eefd45660204fa03d463e1c6409860edebcc3a27cb4b508ae45cf2d2acfec0d91f51c4fbee0c1bfa261c1c47d152ea3a7aff3a8f065a3e6b192892faf85a03efc5b5d6336941fdf590607ef8acec096c22f39fba11a00f6672fb08ddd888788025d740039f11758817a72c055ec1889daaadd3e73baf9df1625a0891e750604b302069619fc0036ed6c53ee25bacf4ca31e1fadd68c77ae542f70dab8826b00ed10106a541f99b5f54a5fbabebd0d991ffaa927fa78d560add28fe08fbd66145349c2e2591ee4aeb1dc256fd4ab7352f44310240b89fd3bfdb9d289fc9d437379c36058bf256ac3a63483b4e20bef9252c8484766c03d68ae5acc436ba65662a80b8ccb08de04fdb449cae5ce49c4319e60f5ce8fb4972ab858ad2e602af963f92054348b38249379e1ffabb2df5b9c220cb702f92a7062177efe5bcab725c5e53943dfba69f310f71d429d497d96ce300ff1bb5f551f305fb3492fca17de04273f2bac0194baeb838bb000d2556aebe7d40c31255ac6536af19b34a8a3a040718dc58f167d3d16551c87a017f87647a27562ef4830a5c0430b673508dd90c55260248731939ebc4bdd7abbfe6e5e081fe0009e79371a580ddf7e0717cb251225f42b267a87b675ddad92aaa3753463bfd230b8ca0421a22e61f57bc33b0d0fa1a2524643ea262cf51251f016a331f29ddb3d8749606f57fb6584b77cf6b90f742b7c7b4bd0c0161db3b173bc0ba93a8f554e5f09caef6ac7e5139112a92528ea04e0be8099047c3e640f55db57bd8969c0b7b5a99feefff4d60fb8fad07eb142c21c519129a669825994fcd0acec5602c9d0bd3b59470f8b43d8c0b730eb4b5dfdef619b2c01729bf2d596bc9125db0774e08a742d1a6cbc53f436bc485b1ba429198ba7cb428f9bb216e6efd17b20676218157afef3f81ed0734e471f72d90250c17a8dd75614ed910756f64d01f59be57060ab23c484d8f196327c48346d1929ad0cea5c8ef4e918a2584c625ad33ceff46f8952f4d7607562ffeeeee633de6d7a2fa421ef27a980da427cff4d45f5962c1a70d6b89b8ad58852aab47af230092d01cd60c98321b4aeddf0027da7273549306515d914fbc4ce5cd25c43ccb5ed24379381801557f19e1d7d2e14ee0e256d89ab0a422915727d16cde6dd128d9d03d11b51d5c69d7135534ca6aeed8e5b05881fadbeadafa458af811c91757f29e1cff2a0c5e12ee76c5f5ad9e80c4d7798fea8bee7b8a3dca2e66e4ae3980c203378dcd52172416d9855a0d0038099755298a1ae0f0b86acc3392c5eaf17c71bde76a3e32f3963e470ae263c00438661afe371977a22442d9b837b99251b354b08784bfbc3e21cfc5134a2c68a94bfc1b8027819581db89aa3763b775864d27c978fdc8746b1ea82581d063026a2ca293561a8b1c0decf1076a18aa4fcbe73837f959b7ca8216874b03103fe1a43ec22340878ea697d5d770bb87ecabf7d56bace48c11aff6a9b08309cb341b7539e3c707fde42f72c2166a044824360e24638c31065ad1b82692c0521a8871ed51ac032dcce313f6510e0a4160ce97a3deaa8e68eb900d87b7c2726ef86962376a7e36186fb9175607a6aacd97b7c406c367e85bf8f9a6355da3e167b538bec7bd541f191b1d2a0176dc2c4832138bd293b54c93dededf8410af2f72e0e37c4e033f3f8980617a9e2f4341798a5ab15a798d1660d4028dee75adee4d0af74649470a228571e9d94b594981a70a84916add37da6026c110e9bfda93072314f35a18f956a49698bb5fd8d12cb481e51ae5dbef7b5e53222c570be1f9955b4fc03d825b4061e195b5ffb07b9eeb3a750f40e848b817fdf24694282d0e17fd0fb860811cbc7565c19fb4592545b8fd971aaaa25aa548479b6a5babdaab57ac836201179f129a1333f085388eb3986fefd370dc56b88265e303ed6c0c0c53fdf443d9502d28835768ec33cb110f7d9dd9ad3f01c39d6585f8cf0b5d2aafd279c421edad415dc82ca599c8ac29caf5d6435e8cc7f9a52ed4cf5ec25372c543812469789f28fd8d8d96072da1262fc9b892ca149acd93dc58f18fdcfdf45728238554a64821c356a1ec56461efa9926f4a5e509b7715c341f4eb15237c60eb4c7e2b41340a0450b4d1c0173e7dec2bf4c0a7248206192cc37916e860be965b151587766cdd785fa005d0b20b2357bf7717ef8e240c619e8aa01c627b16de979b3d56cb8191983cdddac1893911d6b4dddee1591f6a01126d65a492b11b074415e2c07590dc3f015c1182b92323d2ef456a1abe24fdcbc12cc4f17b7734be358be389844cb19537b0527a42cc7a685c4bef8e4fa2991f0bebb45d38ba4f3f44cb51b3cead60c764fb02760c51dee1e32a3bb671f67585322e23e86173630c0413383e7335d77df0a96d0ad6a6161aa14a4d4815a3d7f6cb74c4337da781761fa92a77e06934966e735eee1f9340410151d5de5f0247908ac95e60d67ecd78b9e0794afda2c47ccf319ba1389eddd974eb73c23cc763b884de374cefb9060dfa5ffd031ecee0b1119600ce1d2d069986bb1f099c0b036b1962c54a5ab693fe44675bd83850079da9fab5f3a073af9cbc2154779793ab22e7225a272f7dc599386f61ea1a2c148142d37150ace6786b2ce67caf2fb90ff46b99a616fe544088d99d43549b818211980f5e374d0aadc7b38ba7162aea7e785548cbda4ae85fffdbf7afbbba4384c634bdf9f97d2f1f5bd540689501364980a0e47b9e9985154f91ff9407dc2437901b9ae648fa30021fc638ec2af60846bf3123027f2bd07e508da449c3a90701a4536e0781313defe21cb11482933251afbc50b9164c01b75f9327e7ba850d458f7c5c27632f825c9c4585885ba9f735b8ba78c2b56740d6abd9460069c5d02aa71814c5e4010424e079c48509fbd9d87254ec77dc26891177202d14e2a3955c91b46bf28b6354fcc4f99f5ea70983f81cd73b51d11e662407fa4dede007b5248697cfc3e000c01690dfe98597fe37b1b3714289b67ac7dc86f7b77db724b99929429b704f104a80477766dec707148a66463078f7b677776efbd3317a14c9d973017b219ac07180960383c2d2ae2869033e9d3592ae188e082f2c4154c18d8d431ddba278a3c9564aa2ae6d9e83bf2672af98ee9c7dab1c88b8a6e2fbae8e26c36b3b163cb8cc717fa640bed2189fab0042d82c160303aa444049986408623f758866c48b52dd2e7ad20b1e5615e248aa2488b6614082ba5052a5a24d222f145175d74d1451769a92864a2289b55516294a468ca501351f48fc5542a95ab602caed2297acc251689f090cc61be63c23277e46c478e335a98f9656eb1b9154571c8771e3063642fcb2de2d0c762624c8c4df1b38781cdd0bfc83136c4846886bea585c5863445c533994c9c899fcca0cc4cac391363be3391c4c498288aa29128c3c58484a702134a2975efee9eb5d65a6b952d1a5488ff7f57ffcc1f49a3aa2bc4fa081b0c8e87367c17a539b42d2f586bdbb61582a769e34c6c7928d03b27744ff70a3f9a2a5dc75f69cbdaa75572b6eb68784ab8ee5adf29ae11030c8c90439c40ee20ab136c249bcc1df9d32f2cb37665eb8f9b95c8de9de04116a315118ac9623c82c631a8729c4c867f51fc9ab5be93a5a4f87f7f1434e0ac22ee50074ef0f6f696e0cd04df91220a5246ad76fb82c2ad0341e4d7a13e35a48c897bba19a48f7529a791283d294ad143a186784513bc6bed6b04293d51fcc21c9b0a10701cc7b54c06050f1ebe834307997ee5e13bd68e76a45f47aa82ab64085f69c4b2d609a5b4d24a7311f1f0f0601ef9f1d42aab9492561a004a29a53cdd0326b96bd624ed56332cb72ddf0e494e8e0b735a9f0b3826332546b20ad1134e26eb3b6b36c8646fefd4913b3566f774cd09b87ae2ca2cfdaae47e7e5923fa407804d594a83c0de2314390134ab2224231598c870cea710cca525a60c4590b8ad6de60b797b5d676b693373b4d34786a08811ea0943efd1e57e62a3105d2fd218b92d2ffff27219aa064d908c857a8f29ee5d7e56971dc45e9b04baa586d569bcd66b3d96c369a1a96bc49cfa3fc87abc96469562b666a561af8f1bcf6214d9d37ddf6530d431d3434185ce9a8c1290f955aa1c306a3b00dcb632b3e8cc23658e8c3365f0aa750df89357540d64b524cc3bd3c13cde42c57ebdb8fde99424cb57dffcb9891dbade5184b7932cb32c7fc566b6db5542adab79a41a81431f43385101942fce1808f98ec47ce600508db8f47a94f4a653fa5f724b11050f020f4336f3a1f23ab905c1784c8f94ad22709e9c3e15aa4c6aa8ff69161a45cda409eb8d29ab5dd51a5846f79625aa4a2294dd38fb5f7ce94e40d759bb7a1a10a0299705da247f754fc61be4bcb98d84bc798a69fd7bcbd8cb1623725a48c892b8845ca903f73e63b3f676f4428d631a69096f144f20ce336d80de6dc57a5acfa7f251ffa2e3ea890ffdbed769bb79c6ab3b1c1c3906e45c62f5fab1175cd03305d92268d0680182e872b8f2d1fc4b1a4945f721314aad631a495ae8d58c669abd97258695d6925b55cb45aad56abd57a28c116a19f0c988e1065fe020c068b113d293214246b2294e46130a2144e5c180e3da59340c81e2409ba2f1216ac1949605316a1425c6bffe9ffd75abf4787bd300c433725d9bbeab24dee2a56fd731c676bc51c0854bbd51213ee31752c36b1660fdf913f9d65e1e8b85c978d2f9c0dcae1ce22011934f0be1328e528e59842a5505c9696c6a5a571694ca152282e4b634d0a75023f8f86e6d6d0d0ccb05e1ac8174b9c425dd673014f2770e9f34ee0d2d2d228e5f875266b39eec32fb3349868e84629471a6818979696c6a551ca51ca71695c1a53a8148acbd2d29842a5505c96c6142a85e2b234a650291497a531854aa1b82c8d5746fb2914ed5228da9530b3657574e9c7142a855a1a1dd3cc9f203dddfde481cd719eed4cde079e64ee0c4d0dea53a9e04085940d7e1256b9111752a9542a582c52ccdb54e23a2bab54e645dc572b10a8c32b160b9b3b02949cb9f3e2967164b1484d2c361b0b162c6e5aa06646d3e8c511a9765373a52865b1c614681fc78202064ee81e19cc005be31cede346264c1daf7b4c4832d913a427376496127b0002cdac58b0bebf333317df197c71cd6a0e8140175c32651f8805fc64bc930dfc6c349b5846486ee44648b22732d993f9a4a8a8850b9a24e24c9e96a32f5e80408fa977b893f867d8b13a09674448e845786791196bd10204aad8c50743465e94aa03b9924996ed6028896c68064dd88b172fc2ee9e53b646463264b676db368b5c33cc0dc607e01750e9839c6fcb38e6c4f87c25b1cc70da6208c08454abc9c4298aa128abd0aa003819df0c10acab6b309e369231dec4681f37cae91e0efb282b5a2289aa11677d947d93f1998cb229b359abd59a0102673b292e91424c868666cc980142081505a51e4ab2888c8100020821d0a0b63361894b450821844063004ff3311c36680cc05fc9279938138b339c414e3880afbb71efeaecec804016ef002db15baea44fdfd626423718ebe880401dd6010f309be7abe1c9dd417e98e3cc3b753adcb58f8fb64da69b4df6954c9c297d1ec98bff0f7b0ef8f89db4f371a0e2effc8162ffda7bed94d96030189030317c12872d2e32cc185923e50e294676982c5b0ac9a59a8d1c6292a584c1602afc4813c84c79132365bf66912ca51c132583f8a70e8f0e08b3ece15e62c29a3a17e46e8988dc81e92a625ef85a9029b661bc84f1c0b54982041b488211207b2d7bdb9eb20ccaae8a8d62d692373f4431029bfcf8bd10f48061c10d6eb8410c90c01811213f9e3539263ffea993b22c14a16acdd60c144262160a304240226c322aacf049999d5a8879451481320c31898e636d20d2d13c2676ca6ce2346de2f494dac4e9fcba2a13b0400465488d881f375800a302e48614252b416644b622455b84dc18628c727362c80d22642a03c06e298068cd56b843162a4a64b1f242873b933b4a96248cc8d2c48b24ae4cd08b1bdc0bc307395c9a1b865c9413183029306e23123e8c4938398c4e44318a995d530b3831dc0fc90c1fb8dd8a830b19ee69042c48fac105946b734749a221d55e80b99f3b4a12521049361843dc2f7794a42c2ec4242fb0580e6aeac8562a779425885a4bb557acc8d1e10f733f2b28ae3ff247822b747c0a8e2dfe562958560a8f6b4dc04b695ae155c5dc63ffa16354faf3f3d8621d8f2d4b87e31af3a79f748c8a6b4caeca99d18aca95b439dd87f45e36b7784c3127574aa10a787dc34287fb0aadb53fdc0659426e63990f4ecab55163864bdc76f7fb7d79369e9826a960f1be6e60b8af36aae1ee3e6407dbf4e1f50d0b22aec4ed3f6e83aca1dbb8c674406a8c104c62c07de34d164bc96d2ca7c441e99dd6ce1e8e54a526b9a2f55818cf6a59ed58c2ccb087013e4bdca3d216441b524a2965ad392d5aa7848b2eca66559424299a32d464766777766777164700c8159f26122560820387d8d0223ffeec0e47bcd793c58911a70991217f8b204fe495ad159f6007140c65b9c188177e2af5916badb5d65aeb10b533042830a29fbfa3180c29c84e72e068f2eb60554858d48f2d41669828aaf9e1e57a31a2f92166888c6d26489153134a170621b00922991b867cb4930e413c116c126412bf22221d0e2f364f052d58946ac871da8816645758883511c3d145e9080814457028156d40c85864051c369821c1d104ed28880788e0606244e11544a31caad150b8d9b25feb2c094c98e4aa88b1706d6cb872051e82d89e1283a231bb700205930683c18e44d1a202203da50363a6307eb860ee285aa49440cb0b5c50b95cee285a6090e40a102d4ad0aee78ea265091b19b4b828cd224c6389e90ac79de30548dcb152e852d0414787254ee1c76311e6be46c8d415e4ad706cf10a67e998d8aed0f1987ad8b9cab231438a9d5563b278b82f55b70a5f61a68e5f2d17a5dcd13da92c318feee964171e93b58345140fa878078bc96dec49a1e93d4154eb110cf4e8b0ffb77c3c010d645abf8ae90a02f36b4fffc71d6b8489232d0f0eadf4516b25eaf6705f570292a7016d93ba8bdce188dc12db2c16af6fa4cf8ce57eefb4923f3468cc90051357e220b7cbafcf7d5af54f25e276585610d79faf62ae9a2a06575cfd5692c94a12cdb062d34a369961ed1d8e533b9b7cb2c4e7cf4be6563672a1262e4dee23159a6489714c706b721fa9600308ee4cee2315845ad0eecd7da4028c862bd325044209181db81f0c421e6e97fbc8470b4224d73b7231c68710889323372a37dc0f071832a8618ae8c3f5721ff958c104b7e63ef211a44596cbe53ef201a3b9a37499511bb8a74295c245a3e570d16834174d872b878b46a3f9d72e1a2d878b46a3b9683abe3f4551dfd5c7db88aa48d009aeb9e3a2d1683453cb90728a0aca08e1c4613b2146feb8bd132de68477174d872b872b29c9f522486fe58438e10c1180c879e9fd2d9ba391ed235bc68cc9d45d8a31ae5f07a8073febb2b56b1b756e34da08a12bfc2b8e42152b57925cef2e9a0e570e575be92b9df4d2c33027c4e9300c3f10fc4cb7939886735c2fbdd58a31001f12bfa40b395c345a0e178d4673d174b872b868341a0d575351f46decc499aa2f9c2a3c2fec7a2fbd7be68781a9232fd05d5e49ac42a680219f913c94deddfdffff9d524a29a50fb8930419ffd34b7777772ce54bf9ff4effab1e67b2de75d6c479edeeeff56b777fa7a07cc09ffeffc6656c58ab52d15a2b5d514a4998f7b3dc8dbbbb4b4ce9af7000e4631266f84e030306954c316d3c95f3a8fceaee6e4b6baabf97af1cbeb057ba12bfbefca29452fa2ffbcaa189dc8ca59452eaf8e5b793c194524b29a59452ea81df077a4aaf97e9a8dbeeb7335fb9ee6a739a46536b28eabdc8eefbfa724f2f956259777ac78425ab9b6567284daba69452fa1ed8e0e1779f3add3dfd294f6d7116f5594ae9d3cad98e524aebed0429d64c1d8952eae269e5a03ecbd9f99da9ffd27f7de03bd269becc75758cc63cad0f3cc9dc194a29d8dd327786a60675bf199aff477dcdff7f8f4acd7c3b5d4decdda2391da331a594524a2b4d0d8a529a9ad286e2d777b516d72a3357ffdf4bf1fd972b255dbd5ab955df2b85faff5e2bebaee28a1072ba7b6581edb66ece4963ce3973e6f4e9d3e7df64efeeeeeec972ef6a55f2bc39a7e339fd954657ed7dce9f52cee67467bde69c73ce39a75fd895787e375783faffff9cf596ad7f73fa4c25c5e0e7513c29ab398eda315f393a865677ec4febe931f8d9dbe3563a660cc5e17dead0ee6581ec983eeddaf5ed9873bc9646e7bd3e98d8c3691f1242fbf4c6f3f0347926fbada6d723db9b2debbb9084d0860b870e04341696bda9b9412c83db08374f4b75c3803bab9532bae72439cb8194b21e012d63e21bd646a57d35dbf8367aeac84a95bca3bf338060a6cad10c3c7490bf07c9165b9e34501d2141fa37412808216a803283211b55e194ffffc3c712875454ca01c8145b8aa4859b2e2f9e40e7883f715552c5c95083235fc28f5a95e106a2039951f10521b38420e28b1c3822dbbe8d1995109bdd2391680890a932c00c63d783aa735a29ad1fc470054a7e61a32b5492ae8c30aa5c8162063e821a1331519d1626ae787de3b5c91b00305c4e04dcea9e1499c33cddd399c31cc7610018b935b738dc608bbb2cf0e3e66648cb6a750cae95396bf220777409c575b524667f28e7ab1a8ec3e15fcd9793c3129ce1309e3a26dce18a2f873d0f3768b2d85911086fa898a24409b2ad768616638badef38b6f8face636bb15d7140826bb1c53756646c599cfde1b0b5788696e369cd90c3ab2188ec0e5ead153f9ee1062270936db7188fb0a0851147a0c0d8e182b98f8ef03074bfdc4747720899dccf7d7464098e0bae29f7d1111a5ccce0080b2e5e7069c2e080e0aab0d4702dd20b1a2ee782704603c2881035301244d1f5dc47465210c28c14d9c8600829bd69fa899a4f2557396a6f3a4085bee3d66788ec58eeffff2d27f32f4ff3ffffffffddddbfcf1de3ffffffdf29a51eedee6e53edb8eeb6ffffefee9cbbc9762050e37777f76aa25e77ffd7dd0efa9ffeffdf72efee52e6ffbfbbbbfddd5be604de53072e78b2bbbbbbbbbbbbdb57afeeb2ad34cf39a7bbcf5ebd26276d87e7ffeac5a2cf9a33ecd56b26b7cb4e8b27bbddddfd3bb7dddddd4d83a3ddeeee4ebbdf7ac773ff5957a652777759a9bbbbf707fa40ebfca4ac5fdf7274e94afcd57274cc3fada6af6368fda1e72a1dc3d9aecafaf5e95793f7b4f6f7e0385a9fe3f073958e01673f06fe7e4f9ececffda9d71e88b912d3ff80f5ffb49a68db5775d8a1b5d60567bbdad3e451295d5c29c1126696ac3779ef792b5f1779deac6eb735752bef0329066fc870ac578ffc2c1a13ca4df8815352d938373ff89dba6350fa2c21acb5f7fe0dc2ca580b42ae500d342ee46082792f147102222345e6c8080c34b2966bf04f1d1f138d23188e589c2c13832c834f2090cc494b11f80211ca046c054e6ae311413c61e445952317828e8488744cf95b1c872d132d20c95c01321d8283231686402ff2a53c62416c2d31edac90447eccc18d122b1ce5aaca15ab00816a132b5635638523f9710a10e8392b5768e48a6d40a07a332b12829d5c71aad66a73ad15dffa43ae18d72752a6a88043814095e21a2247e4a7921fd38040bf82232235cc1459f98b45e6a60643029938a8d4ec5de88e1136400013170000180c0886c3218118071339cebb0f14000f4c783e5c5c2ea48bc3a1481003290a63200662180620c410630c610632a8ea08003bb571b1b5d28e6ab92538f456f188d0a93bc2db4e411b91dfb7b4856b84d6e480282c8c87b213b860ecba34d473f9b735bbfbba91cb070e27583551eb3da938d2af070a9dea78e31d45ae15bdbc4b472bb0e231cad3c4b1669cb35b5de25156c939cf179ee56638e10ccfecb6a85f71ca3d35163060397332c2b945e7be8b899d412132c255c1f44537de41fec2f8aa318cf66b4d8990abdc9bc6ec35b76dde7ac80fdc36a53e9d587abf2f40e01e3970815631636c60ab0a1156e1d4f90f3bb46b4f06b1e5cd616eefa50cb268764122a6fa3d35d117befc737f84ea8b99db2c2b047e2f1df8604004e03229edcb7c70a7f661750314339dbff564fcc0e9c9a593a0df6f6882278635bc7ad7f242e6bc7fc8b650b4fe4b03d8bbb5a6a20cca8cfb705ff2d320d58f8250d4e15356a630b331527f21d78f0b09784f078618b31f88b506c5d3532bf9d045cc023420f54490e05374bdc7cf38d30032a38b8a40b693497c3e92b0198836f00edbe47f10128bc16a040f0755a466aa3360164d6d76a313e9451b5ccb67e7a33897cb09c30f710a3d73ad16548444cb207e87903444ee736dbef78077cd2f9adc6e9d6d3ed530e1a06a5634c4d4df1e24d7ea482951f4d033d2e2eddd15e64dead564dc9fccfab1fb39bc2e9c18b095510f64e817100070a66a3277ae0f11241a121fcb9dae7e9388d17891a97f1a180b4c38bd1126224e5b5f1888cf60c1c7c3f6c8dc5c77bfd82b912b1b53194cbb4a049af1ed9f20d4ed3bb4663028c538739f5839151ced87d66d92105c67058f6ac9c9f2c29ff0bdaeac1800e4455c7948ca6556a6abf7ff36e1a195a095bbf4daa9614e0733785d569c6900a7456c9b1520e50b3485d0470d4c4ffc09715281b1227c1a850f98634100e43b1cb279f1ef91e2a0a7458833734d31443a01cf2af6409bd49ccda11d47271ae8d5ea0e2b1df7e0d5b9e358ec19838921dcbd474a9b967b9494b4fd6918deead420956a79bbc567fa0f0f1736d0a0c00ab61bdd61fb4dae7c1c1dd7fc32c05bbc67e5e4884425336fc30b1fd3be75c93ed4f1222ea65960f253ca2846d2c0f4646142dee13f2dd0a4587877bb31b64186d40d1983b70503c40c61f9fc363133d3bacfb6e5a6d6eb386ba0c6d09ed88f1daf1222abdd5a1fc352bcd6c50ff4dc9dd38c2c09b5f1fe02413f3673684382a1dd44ecf827e7fcc956669913b75a0ae217bc764f8efb0a243667170f49b01417109bedef089cab7c89c627a9f7a7cd11493dd61ad6b4764e46300cc5ac8eb08f3b448148dd44a212f5437073bf71efff21b519d91fcd1729f4fc7684d2824d965102782691e37a21667a4a99c44e0950d4c7229be3e1faf9d1031a03029070b454a7e32543bef3069c915bac9b164dfd320658d64a7573dd8875b1376feb28e972e1266fee6bc5c75bfb808279c340a64e7c16e01d88954b8a5e38e6411fe04adcb71e5b9b20d20001d2c3b3489378b067930d9d171d2166ce7b6059692dbc6b14fdcd90ab2ada6cbdb63c0177a94aa6ddeb62a3139d49bfbca036d955ca5d145d29616274e6074620e8250891af575cbf83f6842ecb19b97a1e8c4e684d010dde9685cccdc21916e103fb0570e37e309a892693f9af27a698227b21cf152c854629ca0b34cc9a11a5b82278cab805ef2a2fb4aef2a3de8f203ab31848683d4360d87393e574bdef9e349ee0a42f7c1e13f0e620d005ee4364af3269467a237b46bda1e525da1d3df2495a4cea457a4b00acf0597da411502a56c7e9d3cc79a3f1d3096b2ee52a95aee1640880977a17450e8546d5ea6f0808b0c8f95c8815b50ab034236e2203c299503373d5acb9164df38d7cf932b14842ef4986b174a9b2e4b87f125d2a8ffd96d5517aecdc05c5158177925257489e9d90bc2cd2d0a534717bd0b2e8f6d4444f5464642f883294c9468ce820cab0c1d66012be6bdc7e47b871e7ee9bd53748e9f69a75a1895a1ead7aaf550686e75ceb529576945f464141c587a4cb3204891a18e16122232c485208b71c93edd5ec52daa140c96dd4f0b30dc7845f615e34a5a515e7cdbca068b8b1767bd0a3711205ba86ee9d3466d51622022cf2c34f7df617bf6e2ff800f9fe85e708b8417cc4e8943b75ab91e2f0117867ceb8c38142b34a2ceb90167101b8de441a66b77fd6e96f6f826d3006654bd33989cc79ed8582d574a764fff390e2e84a2aaecc89409f8dd638dbc1c3b482b9ef0f0c0505acaa620c53473345c9b22df075a3130245c7c962263f3b1911645aacfab545a1874317034359eccc515a07d2021d340647c1d7cb00555ec111cf988773c93042087c75c7cc67b354c5d2b3325c5cc260cf05280f81744499cb1bbf2556b89e3866e94f2fdcd9a112cffc07d51feccca81b3640ba1224109303432c4625229f5e8d87c620118894ce78261509d979c5a7b1285229d5c3cef4e688978c40558fd2b6350d0c15359c7e58d328a8326c6eca1802fce969b51ac6fea73488359b3c192ff8a0ad9862a79f2cc9463e5957bc0008058878fb6f122f4dbf4b649f0e61cfa6520f9df547ed9cece0d4cdfc2ca233347ec2337e9d0bb503c31b3c221c7080c828dd2b5439409105a0ebf1bfce1bc31032d85921c6443319c7b75c39cbd2729c9d510ddd074fcf1c422cd6adf9c80a7c3f4b091a699d1e5bec8e3bfab5201c630048b68043c31f3b66df91beae21889687aed006a7d745e82c50943cdbdeac4f3ebbb56b81c14922723d8f1e163ab24604b350a78632168fc3e30a1ff41d0073f52684cb9f089405181267286c475c016b33f306eda46ac0481d4fb529ed3c348860a38e373818b30e32f97b8bb124a366264276c5c5dd345b9b1fbede1ee200dcac8e02e2fee8dc9537f0c9e715fd6f6554e15ff007cbcee52bc1cc1e088283179a5adc121dc5e240b593518c8defdc1a41a12ab8ca33f19833ad77a39d0d80c2326f993ad123838a40757650782cd4660d175a2ec5195c84a008d94d24a6c4280f6eaee278807d2de44401291366e1ffb067dce109852b637b10695bd1226258241652a93be4959341cb5131f29e57c7ff4410f8551044860963b1130428e467c38a12858bd45a9504565d01f6ba0c901a2b90acd357d4e0094e1bc5e08ee580141088ea9d41bfd321ee81d8b055e759ea417e1ef71aa9f3eaa2a9d730b028a003cb997062e0cce01c6842ca64c94693d1a10ef3d0ced97afc87991acf5cff9fc785f2a13632caa1976a054221de0d73272465f2ca3eaf7f2be160f23a6a61b8a24b5b6b2283ea1ea3bf40f20c75d8de09753543dc80730bb09e6df2515280c52e3a4d0861da1ccf871f04f18a15cd8b00ed03fa5da1a527bf617a5d1e071bcb33e5f66559a8dd31801770a34e0acd35cc1882befbfb885f41bac8ce8e1bb42b18c16b5d28ac308b12d90a1c20f01c405c8e8f5c38a8e3b09bb614d92bfa3cd07b5f55ee47073e6601423ae0d1cf349a2eb1a6c3bd4043e8b156d764571a3b1eba08519a686bc0ba4ec4af54ade220078b463b1cfa3f5051854869fce246e841b834ec0683c589fb5bec071f3642bb2188dae89042bb2cae7c6f76cd42d1054316ae824c36750f883dd77d3341c56f9837ffa0c86500de8a297ab5621bc4162ac042093f2349de0dbabe6e93cc8a00978113b173012111db42b857dd4c08cadcf8a9f89443f87e9a8e5f46a5a5ea26e805729e8b8fd2053a2b84de1f9794b99dbc9c076c166d61b321b68ac2ebae1343e839d7436e9b27873c26988b3b56eed102b978223ede406d382c081d5458164edaab6c6da1407a417eb380dee5721459c8e641d68a30319bd2ab71c5487b42b07d183e763c98001f6d913e2f1a2aa269bbf0a462c8c10ac7825ded2b39c74d3e2f344cb2922bc3f61506bff128bbbab4e6a70257b0a5b5cfe7ca82c838bcdd291a078233da2638400e2b1a1a1e592ca09c584dcda74a0fd30ed18dc5121838921208750de5ebb6442a13e42127b3881d997329bc0223bcdfa30a29430c59b430f5731578275dc7a8b4e50e2e77d0838cf293122a9a680197c2e03cb49b35d70cccfc043cb5876e4176adb22f4905d8bdc2cef495263851d456c36deeb236c50b70cf770b28380ec20c2f6b9f9e4108759127261bf535613e42e2a3767e140bbbfc703f919427277591623c6141a4f50583eefd812f158edd7841af0d01316d1bc3e8631a501883b7328caf40244e9f005bf83c6a7512a4f51ee94de344602d96f05140fd769a3c351ed80d9bd7030dce6b9c0e913988a4f0b2db1dcc8feed0dd28253b91e57d19330738ee82f9cc5890617a47ad0bd3d229c701749d200d2eb8063867707fb3466ae9a72e7bec7df4e2baf69bf5f6ea0de4072a8c3280e008afe7617cf388fded2bc9411892cf9532963c4d4f0a888f743a98f44ecb7fffba61941e9989f0002fc604a06a4c00562c8462ae47d433040f0d1c90891ce0491294c4c5c985bca61919ba3127adfa366db86b6ef2433397c862ede49572217db7d3b21596af8996ab62446dd79eee7239097707ae3610d7deb6435c9bff8e6d565eb652904d46badbc1f11e393ad78ecd64033bb1594921301dc629dc529fa815df6601c1eb1fcd4439dd9a409a59c8bfba4990940a014137357311a94a5e73ee3ff18abe813048a9e0d483926f9bd68e3d9e5490b35140b0bb5e31ceba77ff8396bca321f38b385b902f493c3a5b5bf7e9afcbce86fa1e7cc3e297270f6a68952e9fabd6377b0e946901ad59895ef6c34dc4aa56a899aedf3fdc0d14d616fb08a5ecc89d2b333764c38a07faa87460d064f557512717902b37029eba00d92a44844a117b8374d5153c65346b3e22ebdfd1c20bcdf030ae244c1770ddeea3a86995bebcc219107f897339b5269ec8e7cd46c53fc1b0521b36f3d7c94db3e2675aa9ff644b4d8ec76b75d84f9f4ac72cde4a7c4e034b2107a7081866484a7da76656423629593a7ca81c1e9481d0d41967e3cfe00b44451936e111ce5ac1c2c64bffe56c05688cbd1a1be7a025db666b0d717ceac7e7f6dd15347ba1ea26f8d3221e68764904a5d1ac3792eec48b8d652a0e3fa21a4eb727717638d83d3043b3e7f4f32560439dd21b809d36ec81af37ed0b55d1b89a757f790d1a397846d84d5b46696a3bd6a6d12bd68ff7851486b0db7e628759e7e297239afcd881d99ed3234e4a13de9a74441b28c7691985d35ef3d06ea8b388adcfb0ceec20831ada9eb4e3f7e7e6dd1af5c29b9897ae57dba4e4714a3a5d391bb49c7672602934d403e6b483f49099910ee98983ab6eb252ba4267ebe742cd6cbde53de7b04cce4cfbb227c4dfe72f2d82c7d65eae4a7e3ec8cbe9afd0f97d1a2f56a1130635012ae1222b38d216204882ca83aa80131625dff0abc2feef24b82846646a9ea9ab2af577da7a720dec7a8afc11a70798c9fcd702503e217f133a1557a6aeaad46f3f2ddab59050e300515f8e4c9bb06a4644579f066dff9407293003862807bcb2caa5d618349f7bd81299fdfde77c1043f7777e7fd5a0ced70cadf7cbce5588020a266fc1fd8f6c8ecd0f50d3d056eced0e95c5e6c00d8b4dd0448adacaf0e69b5c067607177c61748bb37c4ad6f02eb6560146352417555edb29d5d1616a799ee5c9fd5c092ef97f9bc92646a9ccae6bd7324de5812d5d5ab96a29b07aaf86a66ff0b7e4dee6fc8d26a1e92e2e317991507a1bd22201fd552177d1e7addfcac2d686330095d4be520e15e94cd0903b5b9b1bbfa03edd82dc1871c9d12e8ca1d6a4e6fd337b3a64db7fe896f2bd2a525899bbd62b6770816c21cf0389502280194cd9f91c39083da68306f8567e6f70adfe37e4097225d8a57b8edafce75be8cc88dfb0c4118ddc5df05c32d406edc8777dd0e459e4995d5d1a5020e38fcc2c3047f134023aed8328e7293dd1658bee72a3771b40f9036cf06c8c644b5e5334dea15f3e991bcf92ed441ed4081e5a1c1fb9396dc9da999c6caa5bf237ad0468633090dadcd9b6eb53a635d3d92e8f572c9cedf4076e34601040c3797fd1b619c115b48003698612dd274322a0ba5e6385c499cdcd04d7d96aa41bcc5d958f03677d18e9e0c858c7925b4147a189c9909f24b62f1855db48278587d726238e474971208fd2f23102564415f1621c31b5ae7020799b151f659769a7e71f01baaed61567404a65dd1c2ea7adc9550aeffff50292fc1161f0b104cb161ea6a704aad0f460b244c109e476304daa3c2b3898c466e574bb6b08a5308e64c2e194f3d050d85b81ab4219fb074758b2bfb847047d8dd29fa7ae882752bc52570e8990732144fc371222dc249cc9acbcd1613cdba85355700d5243166ae8c798de09341d44041bfc8e87e8087af7ba75aa7d51eafb78e09bd1740d58138b81f0242c2cb2db38fa7da17951fa94523bdada8a641129395ab908721a50721ef5482c106fae070630c3e84126f2e7026e2cac916608e2c9cde19bd584076d4e58ebaf2fa0e416a30058348322c48336798a719bb8ef477d4d5a8106d437baca5adcfb22ef9486b7ed95a21fd11f5de0d52d56ef777b0f86faff9bd024772878758fe0ecd4b4906ba855af06d2cf03f74d715a82999b355edca070660d5f4ffc81d5cab272f1f3f803edb52dc222d207bef40e0751e28314f23996faf2f444c7ae53d6193bb016f9082fe5f724f903710fef65f740aebd792c13a7a45a1fa03e6da6f334c5258f63d4cc66950ff56003518be09529c1f3f94197486ea0ff39e67c4cac99904fc4d0baab43c29e2546c9c013d50cae6f2c49f67a528cf309083eb0c44671c5fe34541f08090dfbbc6544a650d1c8db8d30eca03e0eae5f27e2cacd570311733551af20eb8701fb885d50e9838f154f1daae4482deaa00119cfd741fa0953135681e38c633b0c35c4b419830863958d5e895f8f14616d5c7565d4fb6404727bc2606092825728b4865a8bbc548f55954552e1aa0a4f03930a48f64f8bbf242355c8c5f7a288b81d4ca01020f1799afa9cbd4f76d8d52651e10956d0aa1720528924bcad9e97446a1dcc2ecccd12493477e6994fcd031647126bcba93b6d09f80ef115d1b8f5652778a10ac4639454dfabc77057ac09f3d69b3e2998a63d0b5baa4fd16cb1d8cfb8f9f8fc496ed431aa7a5748605d6f74eb7c71aa5eac94662cd0a61da51a3eb3240a173821c467965f81154a185713cc1d94427a9284467750a918345fd158c7e1b30910b84dc5b65d2f8053252b006cc75785abd70b4263d62a80233ab8922ae393216a9d8a5674c12ba44111b3ccddf2a7b02e22f6ca7e5ac943ad686f0a4cd76c5a826fe61fc45a676c129b8383021bc4396917a802602b4271f407ab4978046c92c1ff39692fc6bee0e29c46987074c60de4820260195e75091838e8dec05f427593b0dac948a1d76c265f0489d4f68ceea602d18ce71506212d51f864e60c1ce9f77eda39433b7bbf1a0b2f280cd9d524392b4ff0222fe8a62acdd6b36c2c2a64c07b946ad2567cc2ced2d0d9e1e3d6a56184c10712988631762b92f137d3fced2037807fe6d21ec72827813d073f828a6c3b5bc573dd7a60d265e64dfb7476ccc961827600a891e58027bb7b8f044dc299d4bb0435902ef03b31fe65845581c192be887c17cbaf7e9ca897c250127141ba4c5f76c0a3c422999b39b7b52a923d0870078d55058891277ca6b3504582dafc146418a77c22c0dd1cf99741164506a70169f1855135760b3494832766a53947b33bb40d7f656b8caa6138c4e628ed40169c036c4e3e2386ee31e0ae55852b5a769c78a6e2a9f7dbb6141765b01f0502955608a78a7098ae16e75b19590c20a47359c6a144545628fc390d1c8596b8eef54ebf11ec2ed84b0fcf34e784a65d72f7a592c16cc4b693e6e14f0868417130192a5cf2323aae6c51d7cfe710678f8c87cd61d4e2be5c98af5311809b45be29f67eb5e30d6c9c6a02c5b5b6f09395b5510454600f6b673a21b2a9c50f177cafc02a20c63e23d06e898f8fab8fe0a693c8d3eeb800d390efedeed045a871110b5cdd158c8f0a0b82adc973fbf98096d0ac01dd8183ac7572251fbdf2f2c71a8306ecccba9b430027e74ad1f5eb755152d5bfbfd4ca1aed3e11d7b10e117f51da6662015f828b08a8c16f1168356d79a7a3d2611fe5bc0f0876129fa873f06c5dd54c6776ce2060883d41e41ca63c08141eae13a884e2059ff6a73ad63e01c127a0da3a4587e5b54ba8ba97465b216b997b6dc1bba316196c69d9352b10bdd0f94684bb6e95670ccaf6d5002d915ec185c8a6def1dd1194dbb7cf828ab5f0ac445b23a6a9e87e407069a6a5a8b06eb13084c5ba02448556f6680497be2e7fcac45743a4c492b69bf053a5aea7e28ca77b1cbb7a63c40ff29d5230f1470f22c315df38e99a6556ae4e8b6e8c39c366a8a96fb8bb7a8a264ba12d7e3d0bd689b4d5c3e2267adf52fed6ac145b50640ea6ce06b3e63245a4fe4cdba64454b0e182a5e640d50f39cfbe1e064a5e0d24fb759b7741350c8eedf6a4f64bfa7007bcec918f2b203c8dd2c7f4285f9a37b3e49a604ae703eaff2c1c59de380583e815a07585faa489448890bca0092ca8ac6fd9f9b93a9ce647b864f8213447ae2d045cef5568e5fe7c0229e33a56bff2d42bb75d1fd3acd9cf60ea464fa8aeacbcac788d094219caa9bdaa04904b148401fe2f010c0b5698a438ce50c7861b0096fca4aa3f871702dfae180c8249f25abacb8655612d1449efb10dc98bc1665c2fe33ee7f92500c2ddc59418083a4343a996525c044ee8edc0be298bd13f28be8561fa401dd0ad150530afd1108238889e9f5fa64f25a71bdb08e8d108e82888683d8ff8baf82b4f1709109e927612d95719e402c2ba0b1b9fcd1fc5bd9fd9cdb18600a626bbce6dcd9653a84b08eec2191420524f6678dcba412d422656b898eeedea9d2f2748d57c88b655cc3c31ed054a4dace0a71d7b4fd51bae7752b81311d65d42b7ede5e3c477845f7a06bffbca4b41e4305ae1e4c428ab7341e03af9a0b6ce8ee438b39ce09edf48025528c338b8c807b737080003a0884764b972dbac5fd8a1d196b480f6d5f1d9356a206a25ef7dd5504b46973418090c0265c30072b3ee3344a6f18d3d19cab8df175db8b3890d88d12cf097ea8e2f1543c1a0c06946f556b3c23781df1af9ac3fe2dbf781e09c614a10697c1096444f7e0da43015471de4d2bad04eae4493ca8a56f6cb8a4cb78c10fa4b138451702ef10394d19d2319a05412bb045efbe89a76e72b7dd9a4c0de56367ed8b2fd1605c9e5a4b7b5291a8cc992d2e2810246c8f747b0de7f7992395cf66dc180ea9e23cc14f5a55945c28e822cf1b58e4c7240b78b22e4e0973cd5726ce60fe5d20eba9fb791a036c29aeb8dfb13e22ea42418b06fbd28566c9746891fa8b388e8791c48c000b868181b06d06376ab1824ab776fc08c60a26c537d49d1f65d2d4f6830af29ef5b1672d0ef57c33f3fe19588efa84b41b71ebcdc6c474af7db3907f989235fe93297d39a50c528769dca711ea614a4f773951a3d3f6e1040ee7df39d6e922ccde0e0a8ca9aa25e29e03e8601a4956f4eb518588b727f21bae53405946812e8c89a32e8abbf7452a6697e78132994a47d69f6901f05dca76e278121f5dc4ab2f9228fa2865b47e93564094e39546ba2dcfa9920b84e2c40ce523f8f5dcfd91b25729b4fdae63ea89c7b241e1c596999fcfc03575cbd39fb0695d55d8e5152a58a1597eb72981311e4b9dfa368b8ca33c78977b54d9d3fb7525162866409962bd7ea34e201131f8f6c21e9a518e98fa4668f1dbe156cca4771886439bb43d4567ddfb34cb9dc318f3731c24f82df80305d1be941461806a6670859c3fbd984d197d53f253b32045021f40091dda44c0175408d80b235f82b40d708bf5420b6e1612c43bbc614c394a8056e818b82a0fb0645e94fc71411c6067aba2cb208c3b420e1cad140f112112a978947b8202353855158fca35bb8a2c201fa1ad233f64e8891cf0cdcf6a73b12da81546f188eab38bc602850d241a538514f839d01ca624d5a7b05496136a5a4a80fbf105a3303ded484e83f2e380605eb4162826e800fba03e24ee8082a33e003748787b10d426d980a89f21af41144c7d85cdb6af8d15a60a5819d31658226128875c0aed86a401109c64a37565b310a4306ba89614ad0d895cc682a52dbc0663ee9845e66e46c5ee09542140406e70a9c80b40bc92905961153b742fd27cc0358f9d22044411da85bc8dc264052b8d13e3be0bb9fff5be8dac7006c4165f30f349692ce70d6723161e0a716c2bdd6c29cfeac2468d3c8e81bec420dbc1f82849155b98a6500cb1db90c2a13fb8237578424368653da4bcde9f95bbae556858a874b739ae2ad6631a0955ca9247614b59e083784a6d777e5f555f9b1a0490f623a95dc651ff8f81ad093c29d208a832dd5def508bc040bb41d2775fc1bb80365efcc7c14911094c1865c6b9ebb71b58c02552149d21db10dc93f09043d9186996c0af98f3ad3a06713c45bc3abab2590e318aee9e0db39a807566fab1a0e17d8a0062d935d08d59882462120599e6eb945e714a131af453fa70f40584ae71d703197676c62b09afc5bec59786a72db2657265298f89d7f3d5d029461480913ed70caf81d9f31cae1495513ba0b39451a8591dfa0ceadb989d6036971f24c2f75d36ace8b8f298413dc459b9a7c74ec1f372833b21cf0f88500d4d61d930d0de98472abf6859082f9beab109e7b9aa24f80f67e2d273ff3660ac2ac265a037409cf83bb723840be1dd83a47b5946a12a07a3128448876cd0d456554e4a2c6d211009aceb63e86c0137ce21cbccc84c23d59131265004aade2336d2fedc26a1c2a9cc5aa272fe0cf5f33d27a067eba590e0b719e646292547faab164bd0c24d5a85bbeeae1d4ad72155f40cd2c72248bb0a10bcc284379c751a96a5acb54b027bdadb032b2ca0a54aca352b6b0921913fa0e7a0618c5602ebd6ccae333feb8fdc343f2d42f3aba3f411d69d26c3c5004bf99b3bf535877cb58f101d43d93daa296a94bbc8820a61569671d65e61979eac9f2a86a2ddaeb501fab41dd543c742da0e4527f04000a1c48feb4d10bccc079c4b36344416ea0948dd4bd7f0fdbd682094910ff468616913c01b2b07850e81eb873128683e889d785589c3c0dafbe61b2661f1415db244c18cfac9e30e86774b2b19e0508f3d687b4ca86613442315c42f1244817a7eb07aebadb654b3433e886534dd3839a6da9a58dda0e68b37dce520c9ee66b8fcb8ce6361c8bdf81d950821ff46cc7b40f97ea5d537e578859378357420f722a3420676ad204a8d619948677d93085936cf314a8f5bf93fe690c4740af777268f6ec35f0427b45f3cfa6da2374ca57a03ccf6df6b1103388cddb623884acdc4de051515d958878757e1125044ef03c9ae121ed95b353b00efcad93c6dde70bf12a077e7e227f01e2b5ebc00d0e0bb59617434cd40503490e9ac80f32265cfd297efbe64712357d5027a021f05a6c62081a890012bdad8a8b123b1a38ff706c0caaa50290c5bab95294c4c5c1731831ce932ee11a59f9ef712a080343d08c527263286cbc0975a4965e23d37c4b519cc4a05873e0376443fbfdb0e5d645fab842e6dfd6950389cd7cafb99818b709ba10eab352f3946bdfbf381cfa0e644df698a535ebbb98124d42d12d2b86dc702eb21902186cc0ff88688cbe46f1be0263ca1762029b85414ded2ff7010dfad105920f77cab0d7f4cda2c2630fda6d469ec3b904dd1ac5de0e623cf6a8cb46c709016d0dac2e5bebf3c0e458bd6203578dd9ee112a57b4915149866d828525105ba01ceb9f21da4d9c828f28eb8e0f5f877eb362c0bda0c6d117727344c2367b10ee3951aac6dd98d2759328f0ca6a99e7ac7d20f361fca569d8982d4044a028dce1d28bcf18d548cbccd50900298914726dd6b47200331cb7cc8b519061206db8b39a0ff8b8e6a261f9134f23cdd44adfa5e30b2c7fff9da6e6c6bcf86996a6535df054f3b58029f557e624d0d08bb1a8ddc1f195a23f4ec51c69cd7ff81d4257ee3d52abd59dbf4e6233611d14d001dd26cd1b077ee3c5f24f278b34e8fe201b830da21be340fcfa2d17f39924e569830e31f6d2239f7a09e3b9ee2990148656787baab78b42418742346653ee38dae9da3e2d363052ff6d704c7f667852f25862069e583fadbb1690df6e4be619764b1ae7202e9b583683ddec99b2fa1395e3271676b68df627c67d35d2774a0cbd91f65a021fa06aa6aa0059e3d9407e79ec8fa2941acaa6cf0ff4af99226a0dec8ebf9f3cdd36b099eebc434b9b235a519367d2d220fc2b96e065d4a348fea9e6cd2523c3a56c2721aaf8f51bc270345bae13c2da86b3838b8e2c7d708473d1f2729958c95aa65143a597c9d2e4b74eb82a6ed184147de7dc465c2e2a8a84ff5a0003d1e1fdf17d1458932a442ad009a2719a2bb145b3baf82c39858b5ec5ce8674599fff3828a48a3ceab0df7e9d86ff04d6fa7cb6e6bc031c2aca0b7310d090d812372faad95c09b55f28162f13835933c3b46a998600e87588ede951b513b77a1f43af5ffb1eef6801f4b93aa00e362310a02ba26d2dced2754a19156d7d7c246cbc939a6aca78ace58983c035390836758af77463f8f9fc349cfcc27964549dac7778a658361d84137ffa7d46c4518caa2dfbe738f7629abf505936121feb49babd1ac44ce3275a63fcba3c4c6b0d3fa99a5baa69dea226ee5b6d4fc5a92af6a5e52e97b135e54dc89b7cbb690a93b5dfe92df775bcceec12e88bd322e63e7200d213a0a9f3c4e92d950d63051b65ed3f42132fba7ccb62d39d5800f28158c2eed121b3a17fa7d1326584537390aeaae48f5d97cf95d3f584fa274acfbbae2a5ecfaf0ba6748afcfbedefc419b62b55e2efb49dbaa3770d25ff99d2aa31c67ddc7d5ecd8f38f42369502c3874e2d7beddc255163b98374571302598979ad8b2ff1524934dcd8f226717a37680e0765d434671d730f546be0b3f91a17a78e6f5c7c707297950a768ab7014d39b0986a31bb9feb2d403567f2fe252cfb926c1d6a20eb6f6e74ff8c11c7a06dc871c0fbae4c48bf59aab81557ea515661f236a4e8dbb07b38f824ffd068b786666002b7fb9b477d457a063a059f9a0e0110363897dac74d98adc34b3fd1d8621b28f992117bf00979eb09749c50e2774db1efe390935726f1a32da030e7f717da7b12b3c375490a6741e9edb81045d994a0a677bb87afaa66c4446bf55d68a1a11fa55249e671dcf97cd664ae851cef4552332eb1c76c1af25d796f495ea10cd49ca740a95dcc4e6e3b49e899053d542bc8ffb8441d335228fa17ed3b5251a8fc3590ce1fbdbe02135e831b30becb6438614d5fda70e74e730777331f43efc9a63348eb8fd7662b0d97386d002d8e06cac2354ce136bb82b5619ccc9f85df17f630c783912085bd1e259c69657249d72835db4005ce694427d4f0d5be59491c8ec4cf0112acdbb5b8b60da1ebafdb377af7097684703747f45f63db5f62e0c5403b497349d457a7dfc1f1d72dca54b40d38fc69f86c24f35f13891fee5b466f6821b4a0472dee3333a8c5d5ca5d1f0c18ade7cdb6932d9c75eb56ba342911760349dbcaf84a98dff196a9ddafc2b8ad6d784da52b1461198fcb2e318f71580bd217b628e8a119fba34b2219504d3b0ae0d39a41da448a85f2474f35462498f85321aee754e204d2e05bbc1e0d4fb167c85dd27583ac18f7ef81268bd220bf2b682b4e41fab524c55a78048aafc06934f9c83d641afa8c4e42ce80445762e5b3db843cc681229fe5b7330b50797105598237cac3a4235c397d81e0b6d22f4cb7c9c9cb341c1e7b494b9cd48a263b27f1cf1945ef0b44f4fc8c95ebe4fa0e6dbcf663b1693d8cb636dc7d2c4ad5ebef3c35b861db3d257c945e2ae536ac32de15ecd5369b8f1a254ebc5f18df7026cd7913706734a377ccf79617bf81b85f0e36776db11cb956dba76101a033d42e33945ad70fb7f1c6be0b9af58444c7f1943c54b3d485ea095feec24b208885e10dc260a5050c889fb21b68280aa67910063523b8ef200ffb1397296039e22b5c9b46cf1f48a88ee9c9200de0e1b98b8733922c72f7dc615f62d6456927a7517836f64c98143990bba0905980acd21df42b0658eef1e6b7c8602fb0ae65f72397c0b0b47f8474aa43fb564808c64df422d25e81d93bea0e04b646d644ff8161af25227172ae54ae674649a25f30a5ff42a92536c7c678a1df5e1ecc35700fda37599f7ac4afe7c2b81062b6a375f4e224d3764e1cb93812caf44508c5b4a2eb3eff02245f3803acc018e2ea94da9d17afe89b067f96b5195943c3392b8816f3b08e9e1c0b7ae7669409062000491bd344303f805133b314417c91969a181a339cda45a721404d16ded7dec0ae7e9bd9cd9ea9810c70a2ca6267fd602c27e4119779102d1e3cf98c9188111f8f60b4a85c14be980a14f31873567713f6821f3c5d52c5c9779472fbc0cf6374a3a5bc44d91f8ca6c85e8d6d7afb5f9bf7d65302460a01790d50f644db96bb809cac62b42952e0d7917983166df5396d739d6e871045e369403c518413586d8b27c3d7f350b24a83100c70dc3859455671e3679a5c9c092e15cba6012882170131a7022fcc1b739cd1051c018e1975274a46664e82583d57798dcd4183ee2fa6080dcc7de6f987979db612c6ff4cf1d89b76100b7abafa91a42d19151886ce07ffc557a49f9dc49229a889725da0bd10d60dd5246977b581e74772a33774b06ab9dc8e941efe114ed7581c616b66f0ba3a4dc05ddf48aa372d0cbb53c1c44596bcb14637f5e1121a48b14b569e6b86bca70bd01fb4a3a7277eeec368450d309fbe98ca9ff87b2c237d25d5a4149de38a5be1bb17e7fe666a068ff156d7b5b0cad2fef355fc14fce04e2496317f82db4727209120c0f3a2fd8be93e0775cc3c6a6761b8b75e37f99d4be23496e5708b92267735723443da89f0f96ce450360b9d31d1dfddf48055efd76941f07f9413e86d71c5d1df2e1324cd89dfe84028ff0c4be4a36d4b16eeb364f7efc2af51be8d1d7eb080bbe41c20a01be827d098f00f0bd1c52add0b82dee12b137753a71baaf8c30fd14ab81f33402690723e747e894b0f4a3c1d3b3050ef9f669c3d1da11215de238dcdc12381d8c65b2eddca014bea6d73dedbf0c232ec5e8ef5e4e786cb44a6d4631a99322d9ffe0c3495c196a35df44d56506448f1f1739d5dca53b8fccb3819e7f17f7673368c8b8048ecd4e3a6daa1072d75ed32d8bebc5c49199163c3394d926e24feb7106fdcfcea91599fefdef18d524e90337a92d9ad1586545c1dae1c3df6e040dce7f55a9f488e0011a36fe9460f8528fbb3e177127de898afd0beb6927c13fbb4dfaa78617b8ea234574b7b905bdb0f974feacf00be10cc7e0cc0f803c0e1e94031d30b37793cf72027675505ce053c3d537ce5b74c9b55aa9a2fade9faefd027c2c60d293d13ef0d7728680a70fc8f419041c9470b558396ecd2ceb572221bb3a7598339d2abcf1001bb59edba032a8446954d5f42db8fb5485f68c626c60feeb555da8df251182fd708ea05b834582f7de84012ceb40dd15bddf0ad3f86fe4de17585fdc5d952832b995316fc396fbaea639da06c606029311fd9251797a4ae870d137d329d2ee8f33bc59fa6c755f87be7e3382409c479c7889bbbb6760040889297f1a065469ebd96313e988aea3372293bd89b626fdd375a25b1fceecae324cdcd6a708b53ec4574252eda425044b255c78d5e21a3a1c29daeb68605c8be2fa4dee0a026d1f80ee24e01bda2eded0d8e1c07c0a3ee8e80784dc22b846d7be67f81b618a4ce7e186beb9f5fa6c8daefe87c2fdf58691319f0850ba2df97e62411f732b3e714a85c46dda776c869ac65caf1a74d493f55c7b1d8ee15f0be33e784fe7174b34ed3beeafd92026445b84eb7979050c0b2d16733cab7a2e6202459d61f9053746283a111294e593fa454c66749a7254c150bf507565f0ebea91417d6d20187ec42f5fb7ccd77290f46294acbfc67564d0242569c3090c90deb09200ec87d86ae83b83830960f96b5248e930bf753a9d5c19f59a135b686b42df5bcbe7ee9a9ef299b086c72ac82829e8ebbf5620d777324a5f94cb1cd57afcdb4fa9e3c3c4a1432aa1a3d826d92a3671cec4262104b8d070bb7e7a515061383133f906604a072141fc965bf98de1ff341069658013977dff786461b3b13621f27d4b181adde0072d163b1572d8ea08d1529612230a3b9d39a8c5d83ffafc6e30576b7796377da74a31a985dae10b0c7b4dc9954b3f7ec3313325c60ac4920dc5d19d93e5798189f7575938d7a4f2635e635e7220fbedf9f0356e053f4bb4866636ddab29d13b2eb767d71fa6115cc85b492ef5d7452ec4399c670f00f9b453dfac690d1ec00080b69305949de57acc2a1326e66a0078191fa68ea255b76a1357456f5a125187b6831afda8209ca31716a06d782e4ad4f3988e0dd2202ac6e31c3916edb999be0a17fd97a38e4e61c7348bdae9dc7102de2b788bbcaa36ba7221d3bf5a2d1afef867a39a1f64d59218628dcf9f8048c942aea766a318d86c902d31226baf33cfeef09248a0a4998054edb0e98c3a98b87d8f3abeac04db5751e6d1cb6ec93d4d36d65553700c782fbe25bf44f9dbfea94ac227ce586521aba6ade6c4a9c9be4b4f467ecd151f997c7c6255b09abb95098f0fc4f56233168f9a833ecfe0c7faa7aabfbd7573ca46f6c23d2d11dc0c51c61b56557cfbc10501d05e19c860f34f810ed214e774dc3c2be45e1a44f2c7e9538a622f821861c4c92fdf5281a7d0377a7e139d3cb9584b921176745999a5aa9a9e465fddec800fbc3e54c417d6402f525e9e157cfcdb6e864f83c8e0e96dbe54efb2ee0434485c96aa3d5fa1420cf0ad78ecd2943af11bf5f72269e5a64c879bd9c4f005dd5465c47dc4d13c66428042f9dfcfff61865a926a5032501cc4853f90b9a23ac75a23a943e7d85c51330a2585b43077489602a60a3fa82bd0edf6f46811adb5ae829102279f4b526ea99bf0796b48bc5902521da50b95aa89dd91b9288d9e00dfd2b804f6cdc9b08394273464b033bb8b2013b6cb7e47f8807f129bde855d2b7242c147e66dba936f735c1123a79efc6c44c03a0470310fc0497e2e17f857cc340802095bb10fb857ff1057868c6239c054f1d058889b50cee6fdcca11aae53a6f454c2d15ab7a16039702a2e43539b60ca68e562c13d4ecb565d95fae5c29e3e669565dfaea37b7c5b4b84de44580c17af18278e7a6d9b564c406857746e4d42560c0a1102d2eb069cdc01d2ef5330a2bed9bff252b9e887d284d57c89b52b6633969511723e48d627ecdf26279c93d6cf263bbe7370aad25d10db31d38beecc824152bfe11d6a713da9df7eab0f1b4c452e8d0e8a320efaa6d49947fd82dc34b389601d0f8aca9db686f6c8ac376f4445b705330038ab7efe3b3a9714812b6b242b2d6a22eb23bfe6e3a613f33d4ce3f3be2ee00e02662aad313031e3f790969fa4276d7329de32355f77a9ca9b50061391b232cf0782c946aa684b99c7170e367e1a72a3284ac33751d8c95f28a4081fee4c86a0d97a094c73947a6e435ccc81e3ec3d0e3498ea5ae586069f8193e63aeed1282f523b0bd5f0c93c7fe16aeb05f70100d4789a3fb2b036ed7f7f602abb478e5d63bd3381b612b61ef7fc1bfb3589f88bdf40dcbcc6bc95aafba8ed05296e40080ba6b79d4664630a21b62934cebac5fc73a197b0eab7b3976cc8d5674d457b5109bd70c71089cdbed50f0490628bd5c47bb45effb36341cb17bb19b7ba3986e3966b0207411479311b02189672e33c4148e5bb06593f37659d196eaf9b2142ca8dd5bba539dc77131e50dc29426f873db21e1f0e15c8e35fa2eefea8f6dc979c0e09cd9d7272c8ae678b90411c97e9d6b004e12a37adf668e349f52189c83554c356ba386542ab7ab81651ca45e6afb8c3453819b252625e595c5e317f2aeca3133081de114e370c3322baa1fed60877745f37d21382fa7a0f95641d60570eaf0f9930cd14ae03840c1caa08d3a07b4cf0a9a0d34770daa393c75bd769a76580d35d2e68fddc7404d4b65c3dda54a7b7e3854c1fa3fb9aa0b7eb14f9979e8aa4d0f7c1a16b1d6cff434f2c52382ba795289d40f41c3c2f31b977e86fae8310e71fb58672871e92bad782850aa25dbed375eebc901dd0bd9e9273c087d2de24a51434bdcc92629f2ae19aa69d0bce0fbdae98c03ee5e261950b4afd1c7215b119783a68bad0fd1dee23391f8dcb35394899a352832d2754275e99746677801ee5c2cf3329fe89f3123193ce52efd31056cb003d2743615bf3e7515b3013cef3f388569f47bbd5a0b6862bd3530ec34707f4fa14360337feae21899e100355deb735777fad88089ba3b921627a53d82ab89795e033ed0ef0e879598a3163d4229eb86145e8dba7db6b9e4e05069928cebc7cc49d2b02f4b2793d0a6da10c5945366e2aede6a1639678e3ed7f2a4ec1da5b8c26a78124960b70b461f82419ab75ec0703ac0286f14549c844e937920c94347d20e4582e45057d2b3e5baa3a51c9a8fc05407ebc2c5d420ff8823ee160f294323bd0005052d25ac938e05f4ec0eed7d3b4c9e087c834c02433fbb084f2531c414bac8920b45ea75f52a61698ce6e747bd2e018a7d3c1cd1b42f96f3dece717295958d84b46d8d75a4952ea4a176ee9a87696e369ecc53d7465e4d3c759aed2957f5303b0db25675c0d4b889ccfc4f9150b5d96eb16b49f61794aa2a97dfb397fd3b6662766a209ac593ed08b00d88eb0131bc97179612d911ef00fa49e646b6152a13ef69f3fdb0d424df27496b44cbc3dedc3ccc7e25c96d8aa710bdf2bc45e85182e202c5b0d23dd65820dd6a65506376152d389a5e282c8b898527b317256bdaa3be98da98527c510afd369920d9b616058b2377b9e361af7dd85bca3d35331dc9d373fce60bff7e704678fa1e3737c79383e8c19f8760554dbf43148110a6068817e9c8ac81272e3fd2acf50bc1e0320018bdecf258d48852e9ecad58cc3faee4befc393bbfa76b18d66c07621dadcc78002ef3a9180594bc2267664547444fbbceaf8a019d7c22080086c4748b5a020d90209b3acc2686b1fe14c1b02518bf891fec37823f95658a15cd83ccc8a023c71c5e8fb9021d9a3cce4aa48622bf9793f56e2b3f7f9a6dd006e803ff2d534bddefcc3b24b60f90a508330be8390941d8cac27a1ff39bdddb2dca07253eb8ff74d3db78837cc02e3d3faa41e01012153f2b15df2423cb48332bd4c7625ed2436a61d91f1a0389906dd6a74a40193f4d051fa7a61472c5e709eef74f16f307e42fae827197d22412ad6fb9c9a40d09a9c7d49495b5ce2836ae9f82ff8dd452bd35b004e658a2818f1c32e2bbc345f80ebc54afd32aeb33708444fd8fc6c9b43f312991b83a8c4c7d1189bbc83fa131559bbcb69c8415099c3b2a14737596183e465433ee60189fc42c772a1175990792aaf00c7cad7ce604002ecadc5f73c650910570eaa49a7d602c6ab799a87a256888310fa8ae2ece0fbe026a68c2ac6fb40bdeec8a921ed3dcd3d9af03528a866778a11da18b06f8f85a2596f2170f572a6f939559cadd9e7ed33c225c55e4ba9aef80072a550f0d85931ac021f68703657f73e8925f81cd779fdf4184bb4cccdf667bf03cf4eeea24c54f08f4d158faa2574ddbb9edee98cea195ab7460685eec506f6df97d14d5e5989c054ef428c2b462661433cc2c7be41a546b09c3636792310c300da66e4776a4848b3a3ea6ffa0ac9896aa4d0f77bcfc15eff57bbe5ea37a0981d1d07131ef6c333740e199a41d0e12ff0c49f0f7117b31c49ac91ee9d33b161bba92904026b665d63083c07905ee95d9ffb49b1df8e4f7ee3b92280ed13a3084bd324e3dc161787a73ad8b36eea42d90f332cd30c8d10c34e65790d59095946f013a3f630b81ada24c075bc00b0837c9c54bb275ccf57a2ec947789d0b1c6595bb7f79399f1e9dc68d804a486c19be164a450b431381d82331abccbcd0cafa1934206e502f76478904c492be848b6559c3e8b2fe65f947c2edd8f245bd6115afd0974873134f6730b0cc74f359f06047671ffc500f65432ead4bea9f1fa6ebd86604267d1e5b5766e3d77d3c526e3cc2ec9c21425b53390a0398d49fb9a3775f4b65039932a8a6d3673ac46ebe94706b4c004eadf4bc158309a55493ab94997836fa9ad91e698ae1372c7228d282db805765cd2d761d81debd680de4b9ec23d23381fc5fe2f6017c49a453a361590a574c1ef05349642d9d65a687eb19753a73634726d6c6b9f10b21bd984ecbdb70c2d0cfd0bff0b3f6032f4832df2bc5c22ca9f792d6543552d8bb86a6d1131a33c3f7f1dc5196c49f4381bac5505fb655f2f419221d6ca13758d257b20ab394964a711b8081c64bf7894e7446113c6a978ec29d3b19ba2299ae26d748d797a244489f2a42d5a94679c731e80c7bd899e2623571368557cd441d7a0af8936284ed163294cbb32201e8e38a45cafdd20e92c8955927b49ee222d6f56eafdcc7643b416d073f373d3c40dd0cd913893dafe9ba01b2b1a47e92d858f5047a12877ad75b38158c2c0b65c2b55f5a9db49557d2604fb5a0f6bf58c72dfe3c9df25942b568fd1a071c05c8fd5a0716cafd86b3d35d2ab520684a650d028aa0b88c419fb7ada13674eafa74bc41994d7d37aca449c49793dfd8933a8d7d3261a87ca1571a519712d1b34f683c69ee819eef518111a23922b17afc75a72f5f22c0b8c091de2d124b25167d80e723da6b31d4da07924ceacbcebb118cf27933ca317752d4b94eba7075a264d9dc6c1f2fa0b49ae3256fd9514672ea1ebe7899fd3a07b814dc1374790eb6554d4ca95e8df0594ebb54efdef01f38b85dcc3fcf73017f2a7606eaafb7d0e2b75531d4e0d913acc6f52877977188c63a4c33730bf18e71ee6387fcac2dcd4bdb7e56f4bd5a5c373f9c815cceb67d2ced52357a9771db6a96ba54a3eae5aee928a4172d5826512963128855baaea4d295526a91c72404a8734e381e9ba2c48aaea3defaf35283b3aca3cefef3a6b934a317e7e7e689665493229294b4a4a2a259592ea4fa9a816957e4a3fa59f52515151517dc62357f54866414212a6eb8e783cefef2c4f2614399b954f9d23d95913922bad2555f55b140d9d904d91ab1572ddae1081c6a3b53423882bd792ab3aa426916bab12b1db85b91615e5fa7ad4bd5e13925bc0745dd7e10f3a212857a05c3b5bbf6942b9a6d8934c922b6d8bc6d1597ac1d28de56a465da36e3d5255b52cb4aa5ec80b3a50f793ebe6936b85c2e681a7a1d322570d0bcec684371e93a954043724106f411b904c6a1cdbd1651a7a26d1383a5756b5495a4faeda0c727df58255c97832dbc18c27d7dbbb3511bdfad3dd80a2578f72b723770b8a5e7dcadd9044af1e7537a1e8d5abdc2d49d7a8cf82e44a631255f543b2242c916e893311942b52bd8bab194955fdcbd58e90e4aafe48557d96594b91727de947ae341ea9aaef4ea59f5c9f25c915e72355f54036a8133a51fdcae596e091ab0d8b56d5d77a14fc65f5167fd603b98e20d713fe626496bb1d758daa823fee27d7734cc499ce75abe79a88ab529254d5734b74492c92a423b9bee3366ec95614bd7a0d73ade8d59f56ae2f25d52ecbb623d376546f326d474f6c59fc9492eaa611895ed57aa257bf618d277af52f4ab09fc693ebb72ce20ca713673eee4ce2ccc9ebb7a3380373fd8614678eb6d8a2d892e2ccb77121d7d7ed9f6694eb2bd251d5c9b51ee57a4d6e2cb7ef8d24b9aaaf3ff0465ed15b1d912d25e55aa170dfd29d6ccb1fd3552e54d235e051f0291726814217228141f0db91cc326bbbeef73c996d3bcaf5a5a25a2acaf5a62b03af1387dcb8c18a7d7048a6b883121fe80452de8e51146c7300948323792b8294b7225b446f834582608ebe59165b5f6c31814724c9f0ddf83b62a7a79094b767f77bfe6011a0e86dd656275a52b5bdef44125d230bf6834ef01849e2d99ce0c9db9dd0525a0e84f2f6147cdcc95f4e90a64dc1246f5f53a19337888b00e56d4950be4e04925c4123494418c915f6ed441cc915fd56d2a610ca17fe9a8a9dbc61970823a9da0e8d24c915114852b57d7b864eece40d7f3d4552de9cd0c91bc5441c49d57623db59833b20cadbbf9ec2c8897fd9edbf0e3601245792b51d36112457a9d3210b07b250be1d1a218a33a56f4694e4ed42793bcab552b5fd74b72b5bfcd9bc39d1ca1beea2b71d1a6999f0971519e5ed2da191a3bcbd6336ec033a81a49de8641a59a963293c91a604c237c2f0235ee396586e0a0bf3b557ed55833c1fe409ca54889ef6348e93d3d31750251a473d7d71faac7519c995fca4cf6ed02b2d336233204091b32430394b22ce9c4e9ff1c41994d36744e24ccae9b39e6c8938833a55397dc644e358393db5226657d82cba2df2b6c3247a43323d6dc995d6d276d094073d633a3dfd41af5a4e4f85e4cac5e929915cbd9c9ec2a0bba90d323d9624579c516986e5dd3791ec0ed5f18aded1cf34f4449a498da33b3d768421c5192c08f3912bec545382cf5fd0a5c08ea0b3cb039916b58830a1be0ef31ed8535848ead853c72e04e6d79b958a4f3d8775dd54bcb98e3d1ec39ec238a963c781f9f51cd6062455dbafa0bc3d75b7c36cd7eabace0ec643afa41b34be974c5199a6be09c10ef3ed02362c8f5a7336da6ba2f6c286e5baf066458457645b1692730086533cb06387390cbeb9708ac7f5eba9a7369b882fb072202758019295fa0f9d5b7295d5d20e4cd7791e1090d692ab52c9f3feaeab317c7c7c7cb22c3b3a7a719b554292484825a4125245aa48b59515c995d6aa3ed5a7b68a327d6947ae342359020a92463b3b3b9ef7779db519cb679291dc82e46a23922aca41d12afa188513b82932e5ac68b2ed6c44db5644e4026f45529564bbe58ce4aa32d18670465a129c1167945ddcd45fae4b0b22b532bd6674fa2d081555f4305d672dfea0138c720065fa43a3db82327da32e391bed84324464a5b62c1a47e76c2bda582ed7ddada86b703c5245b72a5a451fe401fda7f3c994ebc95453421aae458745a65b1632e5764a2520d8526dcd23997240dc4fa6af8913a971d04f2d7a55ea6b080624579155da7822fe361764faea851717b24a3b59666d0793e33f98fc957632fde9724c448f1ee5723fd1a34fb95c1397038a1e3dea7247a247af72b9a0e8d1af5c0e49d7a02f01c9d5b64554d16f4cb22136898ec8b9254a4672b51d19657a17772b922afa97bb191dc9959665d61e65faea2357db4ed6551f94ea93e94b48f42d5bd419dd5b2921657a969b237af4db8e5c955a454fe92dfe32fad3b6f375cf317277b3ae4157e80b10673ad31f20ae2a9254d1d3d3e4e8aea0d47b6735ee8aca1d61ce287af4970afb71464831227596957a95654f6c3ed4e5f45b12d1a33cd1a3af78db891efd8b12ecb693e9b738637a8933dc29bd8d33df29fe3828ba38f37156c8f4b4fedb8a32bd762457f49a915cb55c6a49996a4699debe3790e48a266a3e72055b156fe415bdd511d98a94a912ee5bba93f5c974e542251712a1842012940b83e0912cb3b6eba4cc3e9a5c5b729565d6766d65fad295b9f9891e7c0a17e1728d883a436edc913756a44adfb8ff88adaf93bec8f3f2bd04630b26f9a0501e42b22e5c845461f9cb4af7061f58a49964753a9e7afaab8958ffeef3ae234a72fd1556d46f22d57fad848672d77e51aa1d20a7eeb4aa9ea7a7d24a3fe34fd7a89f9c022a4ed56f18d65bba76bfeb80c9254e074cae18967047a1954f7450628e1f151376cb3d04b404871f9be51e025242f412af99bd64d90b98652fb21798bd642fb2972c7b41b199bd64d98b245a96d1f6608430d2a04993096343d4b3ac258c11c6a15894936453f41941932200810a2ec880154190239011723c2ace7017908e8ece0e58f15d5c75cb1700e42f86c68daf93c896596cd14cb27c7f7088849192892920921bf9834994c025566401990c49a20a199790b1892311494cf2452553c85f5ce26345969734e0c97288065ac8f2afc110b2bc375483a3dc4336384296af714196078207135ac8f20c18628249962f020a59de88a11b504107073ad8c10119788a14a1c7a788157e868a8021cba11f21211ea2560e9214191d21dd20cbc3241da441e7063b3b60034f1347e85122cb1e3282f4e30411509010114f963dc483a32c1f731667be4d28cbc34d28b7d014497913da8c907dc82dce40a20cb7242cb825c9cdd9c4d2155d37e4a36404435f68f101419e9fddec253ea8424a9e73ce39b119f97a2791628a198c60ce20075d0a2613544d6610021990010c43621c010c2be8cce0838ef95aa8eb1c1d637a65a52ac295f686456e4455bc8c19ac4cd7d10091e55b75bd74bb7c1591e5bdabaf0d64e95d38124b298cb6157d4cb4020c482527d80069044d8fb410c1bdc71ccfa41fcc16d0132da0f1424b0648f9eba22cdf56c877f2323159ee2119b4e8921944accd3da4441bb2b027b987944022a2b50f52061209d1d09841a38b4ee491349a9877727970b62f8aca646ed0d050e5c8724ead7236d8c466092bcd8e863703001e958d9a7925bb2eecba2edaa815b9494faa68eebc24362f99f3a4f39a5794534e39a5fc94726612ce89ea1848e3ec0bc503adbbe17c9c53e2ec0abfb0e7f40ff62cf19ac8c3cd715baa240f7c81b9b806b9d3ed9cd23f8c2c78c9d95ca39b86e250a877af22ea5a09439e9724f6933c197ef630e529a89f6e6f0afe687c3437b9beca7a6f78cbfd6ec03f68e496dfdbfbdde4fb12f7433ce18f473edddecf3ee5f56a29d7e68616f615e67a697fc8a0ee77bacb4b9c8dc51d3d18bcfde28e5e0bee6ba50d5fd421d75d43dd0f66ad391d50e59eeef77cd2ecfda1b37dca9b4b4067abf2cbdaffd0d9e21b5a5815fcd5bb1c723aea5b6eba2aaf9129d74f56b939b906c1320a63d086cb6b644dcca2075d60df6398eb05e622c22c05c71f8b4ff01dccaced3aea792cff6458fed1d44896bbf2973b391b95a7ee4bf4506f7977bf9cdcb1e49614fce5e494dbfb5d057f30ab1cd67acf9391913c9247aae0abca57aea9ace0c0aafcebb2ca6ba2e491f0baaed35df0e9d8e926fc7557777b597e6a39ca9b1302f5165c6fe7eea2ce72bf6794157bb8726d4565e5d637a75281e8ac828360d93e7241c03469d26447ccf51980b9e21fa8af5c9827b74326a75ce5167f5008eafc24f920f51c411e2323a12322a496fdd745349efd2793abfd47a3723fd34f6f6e07e4c9292af88b4056b9bd9f4cb6aff77b9675d7fa1aa972835c59e5cdd9a86020327f30a3700564720afe78d87b7abd28879c0dca4fb723109d2d0e7205d181264d9ab4b209ff90c9278f3b72b5b5aa1ec6e4faac56fc6df8078ddec997e7933c196f71d5aca933800891e8d1ba71487b6534cb7ace47c80361e7c060c4e090d135e2bf1b06e0411bf1dff38c4cf4228acbcd43015d63e60d442f7f32594787862a80479228a3a5101262e180d8409c8155682f62a199340a3212ba060c401b2cbc7681c007a00d5647d7f824ccf276864d58e8c3920f9093e1a14fcb962c0c90abb74adecba48c5d7d5d04d334e4e7f5a169c09ad2101861bc380c6491bbade8259d64cbba3b2667de0b68b210ca0c4050a28b88a8c602b2bc5ac5e50b0359decba65c49d69793eb9039148221b9331c02c18ea9e5fdc6e98ed3f22a6a8e38c8954ddaf12100ca2fb987424064fefa25244bce46bab80c41cadf3cda8288792ec10940c81f3542434b6e2e2e93682a89392ac87e14c800f2a674c43cbf247a51069616d1d60c269e3f716662d1aaf8a905518e474747aaa0e17137d6c5c54546a665c4564427c3eeeaa0582d5707c5822b6fce86e535918888517ec94d44e40845355607ca53de33af93cde97dc234283b02731345afe584cab18b7abd29775ead6be5a812cab5e6b0cb9b8118c4f591a2c750ee970198a27807cae5738d440902e445c6404ea6c03cccb31586951c3434f9c80704a6264d9a346175d7b0ad7427d09d4dcc9fe8c5cec7757aac00353f727af2751ff39d2f98fb28a78460e5698b0201d1a0d40e7a79fa2eebb2dc51a0959be5a02a0e3081d8586ee7959b659cda51b37ccd12a78290f312a778dcb4a8d103666b12b576928841d18b4838ed2d1807e3f0d8812c97df3c858720e103cb05a7e40e64a5a4cb7ba4eee272212d4fe11e2e7ff90b16d2dd05a724e6f17297964b2002f448f42e6db95c5a44e5b4fd2146b9a7907b68c808326d512671c6f4f82c1b621f4fab50c9f1b4886a91291639d22ce47829ff6c892691bce48f59447d81fd2890c4418c381267604bc21389bff664689e9d1e3b6dc9a352504e6f59a76d207996154c5530968251f00957fc7979074dde2890c9740a34b31c2dae004dc6f00784e9a6933b91442f4a1ce40a424893264d88323689b6162acbbfe4eddf34ca4e232f4faa745c789e6e9f1fc53f68b2f60dcfa049247a1113faf901029a447312116597372bf566c9899d3ebbe6d2b9d6d27579777a7bb43c75ec0ed1f2141662e4c6e5dd85a4de22790c4961173c892065f9d91afa409119904a1b9d5402b59800922bdaa29802490a84bd33a53ea4c4a91d9ffd494c7fa80f6542ca679c8da42d7903135b391e43527739057249e13b7bee1c123df9895dacc17e3979ee64996d55bce46c36708420fc60c8a5933ab21f6d115d7174b493450f529cf926912de2cc377f72fce6901c5b4b620f2ed48a38f3fdf801eaf191ab26b2f3f95da7adc6e1e3c215b82e9168651a85c6d157e44f6e91618b1a5d17863c9047082ef77161d85272e991a872b9cd921253a02a02daa2401f355a82f6f4c096cb5b6e4abe59ddb1a3388321c955cbe3b124aa4377e4cac5e3290fedd1828d3ab9b38b7be94855fccb9d4952159fba13e9ce23a98a7771646dee2110a4217ff3c8e5c2ee9690000422f3088910bacbeea624a62dba641ec5792404ce884b0c3a310afbc122b8127df041073b20db927be80936e427bcf044d14f4b99a3dcba054e2a3430d04498c92e92ba89acf8c88a184708aba50a3b02464c0a24403188e1f3a29c72ce396717a44ca459a994d1186126e79c534a1b39e9906c49447461d817ae2fcc78c10848ac0470de0c6d2e51d367ad22a3226dbbce5a795df68ca7dcd825239c48d7135910b66801d0132420b2001e9f2764d08382a427828082999d4048aa3a7b228a152c00053a3a80b0a311bb30ec8261041b2377145d10438c28788105387cc1b2e48ec20b4e14c10b51743d48b62e22cecc13cef4dba355d76d77215f4ac0130e6e1a84105a6b6d2dc1ec1f4d861d764cabb2cfd4d8ededd10768b3961ac34abf6e91d28fcd2eb863348d3078cdeb9a9e91adb9878e78e10a360bf9fbbc47433b524516062928967be8881443ae9f9c88a717b439693721bd539e2c90a3ac79e2c800cdd81ba50239c6d32cdf37058165898174938c6118e711391ecec72c6e51d7755d5729f7d01126e4cf7ee640eb188de330d5fe936b13b91ee59a45f42a508c9f628b5c638c3046182352aeef187f72358254df874690ea8d8f317e12212455f1f144141101e39d58bb76ec12512455da8910922b228e2e2b9e42286b4652a5d5973eb803a1acfdeb298ab276680429b3b68d2065edb0891fb98a2c4d3bdc01529ce922ed2db5778cc61323cd82968a5a9cf893ff41e24b9992513e428886ec59ae509f90c77e599e2f8a6ce7963458e9237bb06338a2feb514ada20ca5100a6aa01f9f9d3c44d1bd018a1ef4bab33cbe6b39cae52b7749a9682a97e5a8fb37be69c2450a1d54d20a5286c75f4be1c828432914ada0e46c22c65e2335ecf60d2df02704e8f04280ae8bb3b988446fb6cb8d30d83eca31c60bd2a3e84d9a459eb185099bfde0cc277a970a3b1f77ae9e222bdfff681010504f0aeb89de757474a4f21ea9428332dd30d91367a60cf2bcf4996ad0e9c1ce90680434d48321ac83f29c8941974b0cf58027cf5324712615e7e74ff23cecb1fd8ede8ec9d9348ef826287a2a1772f488521a74a9fc3aba7cf2853f382b6f79c461b9cba3cbcf4fea86e5a9b33ce5027de42a75d31df5eea86bdd6de95a30cf9d4279c68e3a73fe221267523e3f8be40a7578048d60512b7fb2a7855a9ff168ca783f0a75a1905431498a1e44f28e1e3475324fe2ef47ec9c1cdf728593c3ea4caa7eba46aa8fbd71aa69d668d30873f744c513eea993933ae79c73ce39e7fc49e5b84f8e3b0fb99a5a51a61742a4492f26d19bd717a06a7e9221cfa9863c4faedd0c64393e1edd0b8bae31df42996af205b2a767c87eb2470ae105b5679d73ca25c823a0b460e1b116b6445bc1c2a2b460338de62963906da52c3be1cf5a3c4dcfb2ad44b169858db95e42d1ab6e1983691b0796a79c22cfd951fc93373092a704c2fcaccf354543d14e9ae998e9167f59663793e9d7e46caa50d64a375561adb5e22f55aa37dd1f4c2653ad37d592092b99ea4b2b7d714a3b764dbb66d26ebda95ec3b2c725639e0c8f7a8f05746f298058de52106917666ddb36ce86fe6272ed3a6a1c58f40a8b42abe667e93acaf39ad46e56deb9a0def21edd5db09095776fc1428cd40b5139eacdeade2a1d16d2bdfbca85a0aef2d4102a47fd46e5a8577cb3f2ee3571720a6816cb4d5514eadd6f50ef5edf756fc1382bef8ea302391b1e2c3db98347b10465f815a10caf72a5206299577951854df140bdf3d7513092e208a7490194e18b6047c1285f4771267efecae2428a3312338a1e93c696604558ab8fe2104552055f449cf95a8a534ebba6dd5a51b8130c046257748d79b1d6c5965cac08b3e2c87e368af81167e8e7a4415235b9cfedf3725e6e1167b417f5b4788876bea983b5bac6445dc594325d339d6ebad8d7a9d33b0b01caa6db37a7c3def49a78ba3f98ac35996e4d266b712a6551ac111a8a351d25eaa06b74b6a65b5392d5546852ca8961589bd2de9673ce0bc34e4bd74412e38c104278b718e3c4d98cd7fdb2aef15d2288914a794929e3c4536230cee092f18a18931ec4b0c65f863b5ed7bc660e8573083b646a88fb983300ff86cf9be1af8d72f6989b828f390ebfe1a68688390e4f41dc23e638a47adc7018bfe1301e00690a6cf6d835b128893d429484a0241c654882dc43486802094b202189dc4354d8dc43541cc9dcfd66e64e4caf91abd4498c13ec611cef2a5c93c9958753a51838558a8153252144259309008f817164ee6537ca30e336fe9d9c7236275807b762e3a6e065bc5933ae77d57bc4b80c2c44c663c8c0292e47c815d0ac4b55ec72581e4ec19b19f70eefd5780c8ce3bdc671627c460a4b46885291540ade06be078dabaec238399a164fbc9be262dc1477ee9e7715c6b171ef3800788cd410337ad4788af3aeba9018329ec3eaa1bacc65b0100f5fe0467519188706d748553c1052156be29b65037f4d44031b816f1600b0e44ede31b2779b756760bf4e7a76f29314134e0d112386eade853c06eee10951e14b95097bb8a5ea6ba19cce1a0e17c6ad81fb74b38cba7d1d9e0809477213292122520224747294fbc18c029fe12c86848a868ec024cbe41e12fac94976b60d951ae21e873be01e079c72003e8c18f77e13e31ec63172729c141703a7e05537321ee331304e8ac3a92166dc7b8f19f7b0102337315ee342bccfc03d6a7cc6676021315e03374b069671151662e466c655172203f7505dc6656021dc55b8a5ea44939c0da732e3a64c4fa5a49868524c29de4a0af7d44a8a938153284f7137329e4aa1c898b1825354b65b141977064ea53cb57273192bf886c655dc4da5527a7087d67ec6950144e66a514ad69eb0acfc2b87f98ba7522e9ef297a79e4ab9dc9452397794afd0a4c0bcc09f8c8b14cff47217930aa7b8d368c12915942fc8cc283fa9bc26e664538a3bb9a9d4cab9a71cfee4326e6a050f41e3aaa738dc8306567dc6653c95827bccb88ccfc0324e375d2032a79c64dc96aad355b7a5ca05d2dda4499336649413cae995b34139eafe885ebc4518c1c28cf21f7e1cc2c37b82bf994d87af917106e5b18838739a97717892c15dd51c96891ec763c82f55dc077540c8e16f66eed7e1551d3e3b39bceac2132c13bdb73d577ac3ebba258883cc2026c7711cc75d1cfe70327778af77b7ccf418387572d5735826ece1d4094e0de13dc66fbcc7f8c963601c2327f826c65518e75275f21827b89fc3aa91f0367781d0264d9a30d921b3c680dbac184064def007b38681c8128e000eb759306eb35ea260bf1f5d84b3ec628fb9cdbae136ab46cedb196313b78ecd81892fa630e79cf2f04a29a5d426ca35ed1aca0f9a0c3921b0b6fde446cee6243e27cbfb3d4720c39fee372f67da6e6f4e8637c8b55ddeef46deb8fb6d599b3ae8350c51d77e733e85c59cf3f31e0d19334fe25544eb984d1e420861a4810d3112610bc96b0def4723c39b60609b551f5f83c87c437e850afb6d25d4077f75ce68640cbf9382fd3cf983468e9797c9e2cc87cab285a609e0ef11ec0735001c28cfc3b8d6dc8e79183fb9dfc9eb8366a4e4ec7508c04bb502086c9251ac853fd6da1b376e683a04e03afc6ace2687d7c4d5ccea5773363ba04ea893a6556b6db53f9c6c3c8a1eacb54a1e0cbb2857351b7c92c706361ee5ebd5daa4dcde949b6e54123d28f385630bc79947f8d3456022ef50842345189277f80e45207245cee11fcca72da0489273780e876289c66dd8c9c9c93cb9e289cc41871c0e374e07cc395cb3a75faf185669d0e9302c2c29296f8e8525e584c36e6861535236cbd9d4aae3f4eeb5c26a391da7eff0eb62ab9f6ee7541030ef70987738ccfd72f20edf2108017c00ef68accc8e9765f6b7efe674c01ff071bc26621be5ea75b8343434a75c3dca8534a7f9e9d809e6155fd7f59caf9ee535b2068919f52d25057f39574acad53511b25cabbf2e7b5d36d6b68c8a5a45464618923b77468216b2c88d043128b1b9912006241ba783dec5bbeb020a26906c81040a22499664fa08c5904c1fa13852842d327d11aec8f4ddcda27797d45de28c193366cc10d23366cc98819343e35c0aa72cea299f05a203e6ec33628d15eb5cb81cc31f8d8cc538eb23516b0591282a6971f6cab37036b57e72db9bd38e72533a520ee328efcc72181e5eca711e5e13b59ae73c95c2373cbc06e3f4701e8ee3c3733c87d5dc3d0f37957a7eb372dc54aaa62663213d9c87d7f4e003e4ee9b7b711eee759d2e9657cc741a4f0162937d06d681e3dd4df7b3f93fdd171708ccdd258763ec4edffd59fddf1d1e77f45e70b76121e8bbcb7b81c03c00fc65c771940b738c9d0a6773e10f275f3511757a146743af410e08cc28f745cab19b8284c728d357242208657a8c08addc435464d1e51ea2624946a293e9afe48911830346a9e6c3cdf11e2e0f7f716146b930972ecc382ef67b61fc8147cf72dc87332007f6e10c38bd876bcd5d3cecadf7874cb6f774c19a68aff77ae5250f0e31317e612ef0310c8ea84b4e08fa8a534160c791a88b44b65a8b5142501f6e0e0bbb9d5fdcce289defeddcc3cd61e1fbe5644a2477eeac71a86b184cb9306f712665666b32bd394a4da68bcba2579f72ba66ef1724460e01f51988d9877dc7fdd0ddbe539e723acca89bb2efe13039ce728be4c029fb1ce7e1ddfd307cc2457ac0298b83d8e1399c073cc4880e01780e3cc4c8ea489c656426b56387e7f01d9ec335952d09b98790f864c8518cba30290b36559f9383d8e102b800b00fd4777867980a2287d757ec03f51cde7905f3950e872ff8fb75b82e8e934f98b529b76731d9145b537016bddabde2d3399b0be6a77b17f7833987a37678773f9cbc3abd1f4ed621871b24e61c0e7383c4bc03e4ecb31baf34cfe24c3dcd2f997ce3f6ded0c2d2fcb3f906cd339a67375ee284a04d9a3469922bcea277e3cde9a0c137be9ad921e8c6953a5c49240057e670e51237b01ffcc99a83c9723dfd84bf99ed3526ecb79ddeb9721c67632d863f1ccc9b433dce543c3b16da75428d03e61bb096aea32c375a8efd861baedf7043938b93afb7d88b0178fa0933a5e4a4d4c81b302cbbc7c0313860f853adc51fcc57095bfffff3bedb5e3140aa2aabd61b99a80651db80af7129b4c4ca4f39fe753cfcb331efb8f2e1313e6058d403e601b754c9e0962ad5ed8cba9d61b4beae0ffbd34fa7afac5cc3b69595affe74235ff57e1727db5f29c71abb3f6e4ec10180364eaf91315f077361c6a48fcab1a75c4d6e30299ccd75dd0f02d95ee56ad7c500cc11c8f55f677a733627db25194bb92b1a2a25db265945454545e55f17d9fb5d08e4facb9aae1f379b7000a00decf67e3a646c0543a213ee681a07ecf0977df52cf8eb360065fc05fe3299bbc0aadfc62127848d9fbc466600dc0f66188745366ee3326c5c067fd606fe7ed0c83030004ee3aad74800dcce32ee97a9eed7e51af79347c8f0312ef793f8078d3c4fe3defd6e320da824d2b81dbdfe2582fd32ad844f5698c8f525ab72ad7f78390bcb3597bb84fde2d191f77cdd775c1d2673c1b227c76500c49e823fef84bfabe0afc38a60dc895e123d70080b49f9e61ec2c292ecb3454fa6711817dac9306e3fb3761921a9878c4044fa40266c66b6ec277af51867637116bd8a82ae016fed0a13ec2751903f591467ba43974395c34b14340ed36947bc9049103077f466ae4fb95ffde99033611df51626058939eaa864e070cfb396d6fbf066e5780fefc1c37dc0427c380fef010b3172e3c379b8901e9ee3cd8ab906b7a813756024459d24265107e64f0dd1c373bc470f38a6870f98077c1ef9e3917fc8641818dcd13b86f119340e23c62d0ccfbbaad398110307d59bb39171a1920b7188f1c3e06f66986b37f9f47a0de35a6eba761e9ec3aa16a786c8711e7e93e33c601c23f638f526c779380ff039700ecbe2efd69eee07f329e5d5d6cd743f1ab962d36ba4e9dea7dccf7b7342c0b88df9e9de70c983533b6246ddc56b24ccc5e1302e048231f7cbf2fd2f0e312e447299d4e8a35e666badf5516f2d13ad96256a1129c100ccf65048e8542f54ffc12024156340668b81402660abc2d60b201344ad97291c11b95ca2be1e5efa1ce5b0208c98b75cc1bce52ae532390ebb28d79f52ea4d3030f04793eb636230c69e973fc92393e30e19e1486e79e9da4ffe82c48cba8b766df3af18ee9cae35077d603e1df6f02ff3e19fcdf65f97ed3f2fdb5fae78b87dcd6da972711f6e0fb7e50f997cfaaf9d2ef409900bf330fd29817a0c63c8266c0893b040c35aa3721ffa68783519da099aca18ae0bbbae09afa0417a45a88529b33c23af2967f462cf75daae9479e9631e3bdc6e68c1a68248f1318fca9d3b7f13a776a0327654c660cf77ce1d67e4f624547ca09480b00d4dc02e7a51ecca4209dc381ad6de9c19c811a3f89a1cc8f130cec8432886ace5a5564d9c6530c3160d34b863769baeac35ccdd3967420dccc8b25d2a6345d60c4347168c11b200e7ea406bb96261d89583102c56ce3c0246b80520682c0d6e57abe6c90296456fb3b0db2c0d76bc6eb396d0b03967841ed0e68457072694110e41c37266a075a9bd920660074e3ae7829009373c10d4829d12a020091f104187e107f69a584e11248c0cdda00966e831ba90a022092d4ef043a63bc3fe6e83fc793468aa60227f2dd44986aaa8414f14296862086a1882c492b28972cf1b720f1535c9a6dc434548f688d6cf826d2e421e493e45d306441b0eb48ef920cfbcaeebca2ad69bede6dcf29cef0b4462b7c8764d6e14723371a66aa5f78138409c89327af2317a387048f476a8dd400b11fbc9e46db2c06e7126420ce9135ac764119569e24a9b8176552a22ee207f4d09c87798d422077104b4b09f0c16f693c9376b15bde806f2754920aa906692269d60e155b4b0f0f29b110b85748dbe0a182c3c8c314231681d53935b080c36fe9a71c618048b54d0b41c67e39c0c71ebe8d93d67f7ecd9b3bbc140318c6254ca8961584b2963f2bca83c867b46b694f328e8c7a6402b652f3dbbc41fbc32eca39f5d83bd59edf89af304cbf097fda2b77ebb27d72ef7c9c38c524c7f7439fba4d8857f1421ef8f2ec74b25d06fdae18d2da4e672230c9b768880f8fe341c44faa83888ec472d621ffdc1893fd87de1ce4060ee5f37b5e37afdf5fad227f6d19fcfae5d3aebb33b2b9e1b86951e5f7a8d2c5d98afc38abfaa5dfaed66af77be5ed330bd2d61fc75af8f2032777fe384886fec235ed334fc553c4bf7a15dc336cf4db5cd73977ec22032633e801c41af8f2012bb3ee23b5f1708fce4769c726ae21df1fdb8a3cb5fd32a4a7d9230768650681d330fa1fc25040b1f2f2bb0e53819e9a8699a8f2247c8b08cfcba20b88edd4706642ec281eb9d254e0eeb7ae471e1ebf04e213a595e0f8194980611ade116b90f9108a069dd0ddf57b0dd4162ec9eda15ec372584337a57b0d9a78410c2ac218470369411e9ef8285ffbaecf22f71e66edddd36ebeedeb2190498bd0f2184597e9ba8f932e7dc8106000fc06bb0514353386ae5aeb1d316bd993b0a3028c95df41aff784772fccb148260458e570840a0d1488185ef4d87488370caee6e8bd45300e5eeee9e32c6c4c4995496b7eeee9630b08d7d3492fc804681902a78db51d84290b2a09021514da7e4869c0228ab846b5860371067e2e171e20c4df4e05519e64f468706f302da8364d9342746310cf380c019bdc982655858f089d82b04bb5261ad15ab87174837418a335be0479ef9b94d21996cc43c4bf70d7f7f07b18d9d8795e422205b44f4e6514e60e790a833758032c59148e4c178628c31c6083725b496f029f2018fbd11208d0862fb4e6cc27e91076a10a7b2c76738882d0e49d1cad8e3cc1cce66346275a2146c7cfd23ce00cc1f95d8b586339e60df6e77967f453a1669640552d0c91057405a0106223a39620dbb189cf9ab3ee283cc8c1dc38c88de3c8d94c2d94a944c1d29298c3a3b3c30893c672a08cc47846fae07cb3b8c8343852776585d77712012419041100bc7e5382fc7717178533b4acfb961b99188bb474e47841c8f96d36b5a844f5d23f4dbdd3175c4eb031ede5410a5c797bea3744af107e3212704c70096a7ae414e01cd6a79730e60790ae31c216f4094c44abd7b0660ce5e23e32d3dbba597ba8b0341c03385100bc7053ea2a7904410cb883cce0b3ee286198258296ca474177c04968424969193b7b038c1ce97ae4c5db973c89d3bd12b510cd57d6641e6cc6cef446f422b8c66963ac212267e8aec767b7a9a379623715647ab112caba8e8cd883f1a18362961bf78abc3be747abf0c578046f6615fbabd56baf1f4f06218a5cfb0434b33faef26c30ad0c8df4df69e9f3a53c7b4448c31e66843b1c89361fbed1661f9d54165b97de441a1c1da4f163c87b07c0e89de1cd29de52831c218233c1dde53778dc0b35c24ce32f2d2b19c8bdc351695b7ca63562a7dbb5f4ede340cfb0f9db1e76478bfe7084c085f57de5c94a5d39b93e30d72e5151c0068e3462ebd466eb7a3b7650ee51c8eaf9147dd6fe6146c44f47ed0c8273c77a6ce144a7189fad947457cde99608b4e9e7df6dcc4990b70df80c8d8558185cfb2d935127e592ec272ecfea0c93106b119fb01224d9cc93e9fa3c6932b16dcd1cb6663a16b58a16dcc6b175ad135e6e98557942e3cca227a33ab6d141fe329463f9a4c6113585932eca92c8bf391888b900e3e4b92f2bc4f134079c6a03ce77c4667a6ac429e3a7205ad88aaf979052c8ade8482fda68ecffc9ccd3242cb9167b24e0dd041823e72c5806cde8839fff2010bff02027b09a5441b628071f61704cb7d7923ebb79d114e4a31ce112cfa2b23555146aa6472c7c3932a1739b0f0510a1ce4f8971cb0e2e5fce7498f860b27d44352d0c9b1832c2329f0e4af5b9c8e148a90bfb6425eb38b332f71669281c6cb08905808641e73ef319fa20530b862152e256cc8c109ae147477cbeeee8edd0db1abb1eb6aec9a92045a1c4084534a29a794524a6d421bb023b431e5001ada90d25a137607703d8bd08694529a8080958680ad602963ec18e337f3978ad0463fe6993b69638ccc119ff2d76519638e97dd0def17f3c92c718cf29ab223c45840712e8c5ed725e31111bb9a482831d8a4dbc69cb31fe1bcb00bfb81c5ae26f3921884524278c2a08497d863298310c3221614e3a6e85637567adfa3efcee240b32ba6db867ca984bf23f2d5860cc32efafe840328c5b671c1d8309e408c4e194f5e34db221c006cfa2a4b598c56c26a29533cc4c2d7c489d9b8a49098e7b5d2f6755b561bc7d4b87b6a95fc76a53c59205fb133407326af439a4ba73b2c964b1848d79047e44b7275bb22044e402206186c29f7901236d0ec25bbae086722f4e0fb82d73c84104208af39bd6c622f110ee03ac5b2972c6799e72c4d6cd2db7962d9cb8bab94c15206e11bb3557cce2cc9946491bf4e52a4a40a29e418e42b265f57138e902f254ae4ebc615745032f97bc9c1841e26846109567ceacc107476094755c8df96278aa80479526188880b4b90420c2588c00a4ab8c2da2fcbb009f644470be2764a5089f800cfb682522b49ab415675404b4f604e10ca86884c70cdcc4e91822ea080080f04996147676768880d44e814a5d44026cac490813de58e420c6c802164b5dc518ce104558ce1055f18c30c66f4d82c771463c88137033ba99079ee28c850c5fcc001e2cc67a3a60040a0ae6ba27e20c08413af28818040a402851f9ca025a60d489aa8ec0401c8058c249028a11205105c40052888a09288a0029311b2eeeef6011172f7690ac0a33f1b675266314fb0f0fd3883e7212b7a727fbe5c97854b50824496f88978868e872965747663d735a38c538832c2d2a905c20b4613b412b029ffcd39273c651f6d62fd9a98d1eb98bcaed933a31836e7ecee19e48ad3057d2161e1e375cd6be294c472c4a2db66d9b265777777675052011e368700982057a4b4616268c30b754ddc3171e144cd84104a3803f003fb6519a8a58456286163bc1a9b33b330c88e3dc3b28cca2ca318c33d6397638c1d73288c4dc4d87dec7336f6c67e659916331a23ce6a60d1314a6cbbc61170ce6641291cc9f663c71c081f20e535e735fb03ddfd5386724af99a78c1fce564f9a923c2a3c81d68b2bb5bcaeeeeee8e51cad9b108730c5d843093ff72329c17964062d89c58b7a9d492177627463367dfae715d18c5e6293ebc2e2f6bd8d735fb7a4d2c7537be2044b141264f39a544a26577c309610732ece779fd82311a6918bb21ceb07c733912c227c42cce5ca62ccec0381ba722ee5cca16e83296d1f79db3c212cce095e1a71c81d4eaadf5b262b54a292fe7155a8c51da07d5a880200806913065f6f929bb67e4bff92cc64b39e79c73ceb89aac289b905168cef63c19191a1aa12c7dc83e64d3eeabbb9f050dbeb24bce970cd3c83db3d2bf790c675225e72f0c772b20a96ca8a46d15753d8d3a4533224000008314002030140c8804a3d1682ccc13416e3e14000e839a4878569cc9b32c88614a19630c30400400404000406466da00c0c436764055e2e393cb7f7b1169696b44dc3d53a14306f060f1015863a2d2a8e5843b9ffb1ffa8beda4fb023d1822bb81e7dbad20d60725548b59eca7d708e201e3b7810fef2df099633a29698dbd2f1ced3defba012367169b549e4d97c89dfa747367248fa832b38c5672abb70631dd62fb7c83312f247bb3001a6313212385d857242d53ca162676cccbb2253d5c5e75268c23f738cc0ed896aff9c3a49f7b4211fea5dd17ebcc4092a25af46e284d62ad80824a16614b6585ce602bf3971b0c8d51f74d0ae44034f3aea9ecf41d62ad7d8108397e3277bb31d0a1a1c8771c6c2e2776520bd4328b64ca5ef0d7aa8ffc40782d4e095f26371739baa153e4cfb722c8e14744f4cdca76cbb26eb4068f060f03935dc6e692010fe6aeb8bd090278383d7c603c47eaefa506271e63afa1838ed54ae28f32a6b9064e12c10b0b4488bc7adead5c92720472bc2420b75c37d19f2ffee648bed2445cf523c8b70c463f768135a76089b243a87348f645980f14e377a9cea930fc076a81638f0d0d90086e1d54713a8721f80ec81b7ef4c39bda043b160e3243110d5424069a3480936c7a4d954cd512e0642e15543b42337a6cbdbd8b8d281116e2510fd134f9c9f57848ecf632a45b81b40d5be89fc85854397205ee5d25fad1ae49424ceda8258c431a9d380e047c84615b261da9fd3d61af153243bf0aaeacf3c6b18225e8c690dcbe4416ffce18c230257e1d8cb20e0c3e1fe18fcd421986c2399fa401b3eca1ef13d0293c667ddf4869e7858bd67ef8bded878b01c03731c2ff9be456fff7694ddff5f69e73e8a185cc91e73b8fe6a044ca8a7ca55efd7ea8f8961e72e36431c4611d3fada9655befdc3426b1c299cb0487195a16511d77fe3b83ac56a9502e95d8a00ccdb971c23c1dd65823ac470d3418a6fba0523b28c099062a9e98893b143d5a8e1e9b0f2478495e81b84ac1722cf92302aa9269b36de546705a4bd228249def296ff7fad39edfa4317049cde183030ff9e1a30389330ed683ca5bf18a1f1c5d1c51b32529375d164e4ff80208ecc4ac8f2b3bb7c4420fe3904d931f937293c371d5466e0aa0e34b00d6acfb4e0c58f7f476a28e13f9884e0cdee4b5eb55c5564bcfcb3edad5367a6a5797caf0956978b41005a2bba3275d275c5d210e7f919a800383ae15989db5bb8c2f32433a440bc8ecf88a61e53b75b7ed8a01c2e4df9c4062b1c2b6fc48f701d70a8a87e34aa2014adbc13e7245a93bb0c2a6f41108779272ec56c733252b48e88ecfc0c57e7b989db3a5ccef273b165d5394961537143bd85c1bef0447647df647a9ddb3eccdf51f021bd69a5c4814db14a2df1b3986e44abc4dd8c2e9efc10bad6e0edc875bbff776c47ef0070354dec4310362cd23194b7037e939e3c6dcfda97aec58aeadeccc3afdc97f380e9a284383367c04da44e6f14a2f6f6046bf80c9598f35331f1a0e5113ba8603c2f863028743239e6fb643fff67e8948545b549626777658a5a50cc544b4e1639e4888859c598a9279f210a81dcaa528ceb010399ad36a9dcb4dbe86e2dfb9b1ba3c9169a3ca4ff1c4d288165573338e200b8e6140be97975c0a4a01d11b881ba1b0688513c657481b947a58c256a855e657015c8437fe54329753b0f14ca5dc2466031d3003d348ac380c969c5bb6fb579cc23582874b87202068b76b906831396ed9352a33632cb81dccef939a2960823a5a8714fcf13ef3f4521445ad7fa4d496d3dc4efb1c7837a2f9ce1089147a7b683113975e80d235164f2c02992f69340182eee9aea434f4c5b3f53f804bc98b2c1e60c6d0c98471c064e711a9cfcb5111fe990de1f10265f67d28cd21a74a4a6384d49e53e43b191a7e781f1d301129f523d964b37957d8e146ac0e673fcd126e69718fd540016b8314dee79fbe432bc35daa3f3078388aad066ec691bd0709840ed1d930e67738a2b355b4cfda2a494a9cfd26c6463e17aafcb5815b5b48ac8445e24d5f1cfda0b9ef3777c0f24a2f58cab0e4e63fade0cb9d2cb593caa285d84c4125bd80a1c6aa230d2c06e34a2c78fd74dac4733a1287122223f3ce7351cdb88d925b0edf02711ad3fa38f264d2f039299df95d04dcc0b17dcd11f1149f079538689e70eee6257ba8ba85532a9afb879e765bf9c64522a7f5aec4cbd9d8bfb1689f41dea405ad318c868aa5391754a78f8d35b47db53e8ecf87fec02ea293550fef24dc6e0cfc11e93b502d626c3afb2e1600409277155fd28a69bfbf18f2a09f67cdf609f61f8a3c890673951edb4f23d78920cdb9e08b157b1c168f45ad2f8cd73931a232c2b62d5c4cc108516dce83a4bb3260006e8848136064b63b69c5e8fcb9e3afbd61d9fc4623bd2487b5ab41c337246d643af851320faeae845109fdc4600f216fe429290eddaf6aeb6a8648754188c8b3ecd379e96ded7132c80288aec874cd785721725ca353b4903ba297d656f76292b5fa5f4f9be561c4de639a6aa0054f89af41cb7b338048ac33e7d8ba371515f93c4badaaa7d9222ab3d6dd2906da792a2769d17164a3ee090c88c545a3694bceecf4ab1e484acc4d232c63fcee98c29cb492f40352662cc0147d07b2580a19392e91a0dbe45ca52a0252f0d1fe4c976749a875e91a9824a4ad32df1acb490a2958b2b571c5061bb57b32665108f383c4a7d463fe69469322de535b6436ec0d31348b52283e2ac868bebdecc72e517c662ea1420e2ea0be47f8df233a9dac41e771df965e986cd3557f8ccfc73defadacb0c835c53fdd2f0fd4b802e585a67f29d292d08f49912853080132ccac600496561df98a1fdb943f1a53bbf403c907e392a3125bcba002b1581853775d46ad8a84d89b9d0c527f885ff7a1bed4a09bbae225512e8eaf4bac07d6eaf3db807dfa8edbe84036738d189bbb8e0b83da99150ec914475556ce094223ddfa764366ea61d81ccf668c9a81564ad7c843654ef76b2ed5bd8407d61621d86023f2d32b1d5b38784d4179f1db676e9f6f96f97882a70cd33e84d51da044ce43897a29e8010191dd76e3020d94cd3bd912696a4b2cbf873a099050f5050e1ed2443331784cd4da9d0dd116b5681b20de4ce509416829d191ad8f178d8b6a168a1a68f7a0a9d509b59d6cd9d732b57451ba7d59caa22d1c723552f4246b63fd06a5267695481dfad90f4a1646f68917cb45692155f4558c59cb9e6f1612902f88593d046c10915ce832aa5a74a0cf22c141fd5a75c91e608260d02db438b5ae0c2d453b39ad74716da369e58239773c59fabd7cd27ba89d90a52ffa0c3b4624ae55a9d99aa145307dc6f5675e79e3558f1f8cb09086e9e61f976c3f7f9de8331061585d02b49e0961dc181c4d8e048c0529375f4f8395255be020b88ef7e248a757fbddd76ee806ed79c8533fb2f1f8b00f0b42b8e62e22726a128239fbe2fe73ffad1d0478714e044a519fdaf4e4706b801dc16332d2184bc824e9041b6a6734ce7585cf52fdeaaa9498aa3fa449102819f0005b45b9f6667f4fdc400bdeb3c8d4f96a8144484ac9b8192bc7c2446cc3f370c42559c58fd2304f901cbc2cccd89bd5c4db98ccf407e05db64ab4c2176dc67ff2738b667f9706aaf55578e3980512f3c94e1c83fdfc096ca7b00ada08c4b9a7f2981dd8c3f3f323baa278672bc14f3d8d8db265e2b4c21815a78f7d19a500fc55762e262930f4b3128e2a7327b23dfb944c190fd25da2a7a6c2f28809f1e7390bb4a77614e8d9dd4d11a9c4412a6b06f6829beb8d73898743c877264b60ec764d5fda11561eb330f0fa6fc9e29f3c61444838a18f3b7b598987bf87f83cf8a0c707d900fdb815b7b5302e2e0a0eeb5c011cfe26a6475f8608b5ece79af3ea01222d31b9b3853f20b4569878eb9b01778bb180136b8917c6130551a2ff655fc189b32c56875b63e8277465b8259b2dc8a724bfdcb9645eecdb04da3c7ff11aabfe6a5f52026c4cf1978ef96c9f31a56c230882b9a2feeca8b39a187e28e1294e2f79aae36e05dd3865255b32214d4ec03e3f435724c100194febe1452bdf276310313add860c512a98e9de30fcd174571a482cbf73c78e5c08b4f9c49db2bd84bae61967dc7b7e7e807d9ebcf9af37e5c1af22459ebc14c8b2108d54b7fc92f0e415b25d293d9c98c921088d0726366e4762d5c16b62a72d3e058764ec60809aa67c49937576038955367aac259476368557b563c9b418ccb7055523bb40ce828e8ce4ae77d8b8e9acaf4cca4f081361b3b084f4f935099791bfd4b1751eec0aa0d1a604816ccb54923ba5798186c0690090ad100ccab762315eb4d0ee2fa776a9d09933c891169770441c83ec869ed7745f9ddb91d665069cce12176d12dbcca8b1048224a5119d499cd0082e0b24f74a6d6cc4640ef820b6ab6836cd6d374099f74421d39336dd554ac6c59a6328d5c4ebfddf7e5a1aa4db59b44912b25d2b1637e8a185ac0fbbb455a2cc51c3d06059d4d3bc9b72b419c3527e85cfd0ea43c1963f023d279efb094fa4a962a75a8812a24bf50fd36234b848566b364e135b53b81e8ac88f11e3898cccc3ce692e2bad8a36dde9b7d61a6aee17a0ad9ee49284a283424f4d9130023ed4858813e0347fb41d54f96f7986dfbf09875b67ab3ed2a2c0b4e485391f37334b7280ca971cc8638e572d60e46b5fe4ba501c40d5b777741f316c6fd5c56704405ea6bc294616ff95d3ebfbed3fdcb256d56946b6c04e058d732bdcbbf14c4b2b5465581d70a26202dc5d50b49f321dbb18bdfa69a0c0de8227873ee9b67647f8a3a7bf381295f219414cf7021d7b633b7f95b04f43857ce6998beab7ed66e02ce435f378ca9afc2d9c97267c9289dc9ab53f92b4fe7b2b506ce9f49b073d8bde4c82496ea32c16c043674bd820f5acb061b56b0edb407cfc93423bd161eebcc7be83b4127e1fd4609651aef10343abe834f1f164a3c949275cbd854ab9e294e231946bf9d5bf170a3ee72466d9a6562d7656d0525d3209ec8d839fa8834a3af685010b97a062ff3ae0c1a80a111424f8828620829497fef4953551fe52ee21f884a3fd53dee6fa17644471f1c59f7f7e01f228baeba95416b67d24cc975394a85685ec21e576c7446fbe1a4a701dea87f7381a10a929fe6a751e80f5d7a679b56dcd61db6553bd133de15a585c1cfc32babc38e429df36b9cb1b3e93c10911a0ac7665edbb2de33cfa3b101312a0c8b11e14b129197ff0eb9f121a617c44a805c17b44943f5cbcf4c288a5aa32ee2a5080ff8b943be8d6e0a68ab835a78f68c279e43712e350c34c502ccadbb24419da5c3bf22bad29696e0f3854772d50f7968b9ca069a2728d3905fa00329552a684e4e9e5f82d55121c1604db0ee006f1e0de516ab1d70bc0ea68472480b58334b11f2ad7a5ccb5a4032ba260cb212eaef0be6ddf4c95e11c346772740989e9faadc8f8c11876f861e512b894d47a39921ab4c6460c6e8bebc09354fc804cf9b59bdad3cb94ce9085005eac5cf49533945096844f8a1113b7b4af69ee9e75f7d0099d6e75bbdd39c240ebbd0213f73a4df4cbee7052df8dc2cc845f49324955886d000e51c89c8bd9a78c043fd1e48941fa253a1d8fdf06e00d28860ba268e24d049d96a813972283575024338d4c151e95c2a4510653434596a7d1d305581dfb7be6c5115b9a93152c70f647244f735a9298faddff763b70bbfa4d5901bea34bef9f4219f634fa35a93533000336dd0d99116e4d3a23880084464052a2ec469d321ece80db6bab330ab185b32a876637306004978b49bb01081d3a58ec5c3b2f9b3b5db17a1a4d2e9c9236631b8624cd2862fa1c324217ef737e0e46cd79c08f67b5f39db24580b8716bfb096bc790fe1b02ac658c8a3c33cf064d2ccb50905963826c6850e3a4117db24ee9b2bcd77171dab1bb4aaf63ca9847a0e70cdfdf3baeebb801c617eb6e7dee919eeebb194b238fc8fb64705eaf05ca0e8fc4f56510939759682aa7d5277b968c89e172ec3aeb851a16f05bc67c4a6715cd10a8db04dc5deb3457c757a65c8a3c667c5e3ba3c81ceb5036cc17bae2a9324c055af9e7234664c3a306f5450f3162a074bc5048b6fd7663501951c48015fc300a7a97dd7ceb05a8045ad549414d086536d6ba4fb877585d07e99f7106a36e009c422fb77d27df07a1e93137268b1bc8a23be72272f76ffb3a32bac5248c7ff8fc7ad3d146e27950700e3c2c59aa1f5c4a0d083d68187521a83e36b473cd5005f19b35e6edc23ccf897a4c3fb93f859dfcd1f0f26cc45a40859488c8c4a11ed9aad3d6cac4c0c156f8332cd24c01b1bde76017e945da6bd1e13db405e8aa020319a69b4826017a36a4afa4a00d51b3705cd4f3022e88353c8a5d0dd1fff6dfe234ac3abf1e9156411e34def8a982a74b9911909931e5338cedc5342f31e5e251b9739911c2954798b5140edcdbc72c2db3d9802807395a921921326292c6bbef0c4572a97bb5d7cdd5049a2294788648820a1fc9bf143429fb3379fd88c2ca5be114100b2711ae057f598cf75df8ef1c38865325177b55648a1d15b7a5252d04c2edfb49079b9a3b4046b1e1f87ce526545a018a071aeee55747c87919e11237180b5ec6e02e41a2e5f77de1d43155514b9942ebbbcb2ed59a8105e89fafcd38858f8ae336a7afce90c14e8eaa874e40b64c03afca87c1cdedb4261c9ee486e88f09527e4c24feb0924caaa40831326cb457a85856eb55d282780f5b939baf9264cedbcc435326cbbc3b661ee33848592d6acd4d983c34e06a7b5bbdb4af61f1caf746cca12648d9da68786846bbd6e645615496d98242df15a44904dbc2e4721600338967605d57fa23233cd0d4af629f0ec9e6ab90fd4a7412817a33467402b8be0161a62288bb95c135cd23402a11918fd250f3d6d0904f1569af6a54cbe389600542e2fe0b3707eba68556a9c522e8fdfbb31b6c46212d765977a0286045fafb3918d38c38267b0e3a972d811264401cdf3586844982dd59af7e0058031992c77450b0250bd7e5764320797d48a0f3f36030e45c1a21e8be1cf44814d080a7b15e267236f4740a927d028e4ed0c97bfecee88272bd827341c703b1d4c857cca9fbd3d10a96b3e6f9fb1421e1eeec91d1cb30cca8506c120dc7a6c616e370138a02f2ded6940db5c1e92941c416c2f2af7d50ae5381fa970c8a0a44edc0fabaafba29f38c902a34f9f523050d944688ac0dc001df3ae96a435fa621cd81a601965f2985b798ad3243c70765eb68f7f67e1584400b5d9e2729315e714ac75b0a0b32c194a75a3e9c0f0ee1acbdaedd40214324409db721cbff86ca6887b90b800e7860b9ada5e3cc499096a954134f4e765f6a58b33abc4dfa1e0221b46fdcd08adfe3953393f16a8a2a117cc52bf1d0f428209ba78b10481c55803e95cd3ec79099771ed3507e7b5f6551fad4b49f0f7a32c71a052187ee35c347df512ebc40bb7ae94a2389137dc510b694233b731af2a00bd1507e07c441d9c2f219b02e923ed5e5b7a1bd0b544e226474274ec8f35a85130468320076bc9ce0c26dd033b154356d9bb33d46c556988a5ec27b97de18f4915751cd18aba8dee4a73eb172742819871c40f9495d1121f4becdffbdb6617d1abc3152254489d6236309efce375519506ab2fb31c2448b9b32d91efeaf93b80251915292cfbd573dd5ad75726989e843cf9e3934eab3bbd7adc7087be75d787647cd70a5b69ca3337b327dfc7ad5569e23663ca5ee844b7480054b31fe72b96387aca843c0b59334d599441dd664685b56bb9f4db46997cd731d2da3b0089ff13c11b09f98e135666da5306a248611337788444c59ac0aa5c614035ff50f8272cf339acba389309006f8c477867590bf080bddf6bfa523027ab143c68498b11728afac88f684ccd8e04806c91d9312fe8411b6a4937d8102715a0bc838a49f1d0e0b9e27c047a1cbda06fefe380392fa1fbfedc21a0651d93b20c81a1111a7ed0c44cbcb8247cb703e575646a5241a663350e5ee0191bb9167a60cb71321cd7211ea634b735db159bb5b420b343d4073a333091046c703e45a5e43fb48b98fbfba7761d74205c68f733cc25bd16db1a4d633a9cc89d0cbcf3058f4b58e231da5fe8de53672689e03de0ea79afc6538a62d36d729c33c58ae66712493a44c9799d4016ca6e249e2dded55ee119f8d43ad1be5920f725668c8f96465db3a1c9ae67468b8fa006363d6d2fee85ed9eef9a113896a08d35bcf3783d121589757eee278b94e71e4e94e41bac9c0e7bb844740e3abcb211ad2060947948086da401d702af6dbdbbb18bee1375ac4b2f088909309677193aa468fc3125f3d6170a1afd7fb1e551afbbfde8f61d0b71d00ac1fe932c08d62382c1f97af39417f7cea6981b125f2f3b5f7369060f67adf4dfabd5ef3da7d1eaffc64e3178c0df4958c132b673b7e24dcff797937f72567034de94f3318ba0f66c241df9003c2f09f9f71b71f7974fcfb6e2459dafe8f2135090fc1cc1468b449dfc2e5b67d926c0af2be9a478da0005d53f3fe8fa8356d2470d01185b0e45067293aa82fae2ce8445117af79631f84375d7b4f9f4e7855a9457d3181c3d0a6c13dab0a1a41c8aac32bf5c41864cb436c97e7c739d749b124941dd404c9af42f60f4da322fa05dc5aac283f9fa612567b80a664763787b9f1761fa06ba811147deac1207d0c6ef943c33d29e9a031bc144b10b32e30cef6b7d5c7ee4a1762825590e05f6b3afd1212f95458bbc1a545cd66ba2adc3b9a55a2aa3557770c610c6d051239da83d277001dbbf035b77c7ce6da840f04d43030a3f065eb5f74a0f70b78f2bdc7bc9785c5b1369c9115d790cbbd8cad3d8a23d1efc6db23b8faeeec31c15489bee096ec7381f8729e6886be1837658b80a135c4ee7ffa6d06c6fa304994bf8ba9c4e7edc8f50836ce1e1c3d386a1c6edfb9ee95e5b1bb52dafa58f7be9ce5b0e882195125a53c4e33e795eefb3352da1c20872bec804997f96659f111ad109435b95773eb88bea1c124c4516ee559e7c581d9b1143ec5ee10f32c519e3227882d82c4e74250d429c23b044616e0a70cdfb63b616562f6231c37bb53a4e4206c21ff4d9d1c431a65963fdd765f068daaa97d009778b37dbe92fb13bb0e3ebab4821769b56b7347a32d1f0631672ecdadb753719d6a17949fade60ec0f1d942bf35eb5fdef580bbda9218bdde66519d8fadae2c4f36ff389b5e8bc79e67846aa4faaad24854e95a55e654cc4c4da3720feec8dca98950ba6598e9ccacaa09a404d52945f55248e082d366abd210594afaf5101cbda6b4ea4abf6e3efbece722946f79c2de62772118514a3e5dbff9af6a22b5ddd7b152eec6709d74341278a99637a94e297d4cfb40c8e954064fc3810ab0ea6e5a2b8d77f6fafbadcbf05385f82396fd07a0441b857f752c696a469414dc1f63fc4589df6a018d5cb6a54bdb3c59219ffb3570172b02fdd65bddba677814fb1dd29ae243a7f060bcb25b7725286bb3745eb7dd95be95bd7c47c1aac839153f2e480b0b1ff021e8f4a4cf3b34e5978093a48691fc83150f2e875c0cecbb37f6381de797e0ef00dc8b883d25f9dc24a2a034e05e45682bdd7fb3c865a501f63e52af077a3ba2501270af23b49502945e25c95c44e2a72753a338155f4aa2825b35ff71efd112e499212e3b7a81d00693c768c07a13e736bff9b4e35dc5accc57a344bdbb776326d4fc8e870aba582bb7f1ce91ec7993d40247a9e4491a9ef95a5853dd4551a860f1c5b5611e2d6adbc2aa5c6d152e5a546a87f6a3e5a5e0221b658e30cfdcd11b9d873690b833c345182c771b0a14f357ec53a0d611649b93af066f6ee3a460943cdb21f3724219771f1977b5f3846750f6424112a885cb10b10f48ae93756d470ee3ed54ed81ce8cae6c3877db6641b0643689973367125ef406f696eb58c67dac6f1c1767d4eaa82d0f4d35236c998b3c0bbec8301ef4871eac90dd66739b2c73936dd6eec169479eff6d8632302955ef3e01e20193c49115aa31773c625a1eab0d69c01fdbddcf56b6f6a5a799d34d86438af30624bee30d6aa1498514d436a73927182302d2d4fa426634492cdff758548690817c85aedda916b44073f881d0e1ce6aab2e7aeda4cbf24cc324c61569186dad962ec6de7bd095ff7b0c8d52f1b64c9686f70c73a2e3c6e0e29c283811b93e76f4579878bf19a1a65cac5cbf1dfbd53ce1621dcac6b4bf1b5143a90661d14ea2287de3c97d1066a4d405e76c20e8d9ce6a622ac9ee42d232c60d2ea1f672a24414458366e6e12abcdd3918c01d7e70aaf05ae487994a5b84fb97becabc2e6a564d1c0638516c384cb27f148d497f208142b358366adeaaaf229e360b28779999395849d5fafcd6d89d96b05267ada1ed91f9bfac8985d396d38f464407d46017dcb4867d7c5d1ec491d235a0d1c65233840b9f8bdbd237097aae9ada2618c883db74dffb7b2f6d0adb19c76492332b6e8c80d8f3aa6c582595464cc0ec84dbab790bfb1de86cb54bbe24e0ad25b19ea57cac39504a65daa8791c17b2d3479dd373ea8e9f0b7ae0388da35b29953c9d46cf08c263d24e66a91195dc748a67ab3ddc1d1b565acd2a55109b199c553d040501ec9c3c101470bcf49e45f9b40088dd22a0a40c2895f8e28d58871779e145562689e9ba8893931faad1ef3b13fbe728d11f0dbdab3d898ca387ad000b817166914a4dc89800c81c1b526ffc2901db2bfc615a645ea6d5d49ef7728900978c9ea1a02ff31545255ee28100e4ec7053a2631e946ea050df4559fdda37ba1b8ede8ceb446ee7e24ef41a7d0c7caf81b65b67262f7842ac705fe36f803b11032c3f4eabd191de8bbddecc64624c49bb0c098b73095799d5c69b0394f3f884c4be4bad81d892de9e56b8562be2ef4d20ef440d028a9b13a11cd8fa6fb9661524895dd322739c762bc7c13ab66d7912566709ab1f522c406dc6e3b54549b86a7b29fea9bc4604bde5d1b4330817d0d7647be40bfd5030cc6601df002854190fd186ec7ceb90976503dc76238653577055a4ad1034198b32d30302fc9bb6560af0705596ca06b4b6107c5003c225bccd708edb6cfb9e84defdef90357990be679485cb9f112cbbad0c9513d166aa8184818749807b2665e0a08234a81b8d6ae0558c251e684d3c0897d532f09a40b1eedf699639a1558f6c75e3761350465114369edecdb9e04f2304527a68183230327280e61d2ca7b0619efa07e98b133fa0b860a735a04619e2002e9e9a71732bc51bde299beb151d4d5b692711a827bbddd1e43592bfe844ef243065056e7f40ab7760504c6adb9d899c2a601eb2e44dbd635c1b051a8ffbfb1dd8e9029c9d15a4fea5b74c905cd615ad9f8643a9af046d59dd90121092022c0aabacf2a7dbcc82250f451e008646d51f0c655a6c86796016fd266ff7b2ce86f13fe6154a4665c7333fb049d6f7f9198ebfc7936e74340d74c3e745e6149eb31988b046f38e522b2422a6bd154ae0fe6e8beb7aa4c816bd11436a59956eb134426ec501ea9e631aca105dc86c151c0aefac881e0009149a496091be97713360f935337768040b217d9c407828882dd48091779884a834ca2999c031ff13681a1884d3a90819ede08e4b07c8fc5747144c598106e02d7064fe5207613864ab49276eb27a370b197348bd556d9881174626102866a2f862d6d6c10004f2ca0887d7f17f17343074c401d78ac8fd3f47ab55cb19f757a18b1e33b324dc8894f0307fae4575108d37cd7a08aa9c157df624a116a225a1aebb0fa04b38009a9cecdb28d20df2629a4346f2b48fca22bb65573bd28652d02e4709b663d7923586ff586f131a1c22f29f5303db8e5828011dab99bfeab744e816123123b66bc96e9e64e758f805bb202dfda12395c902566c5f506626f0e2cb038a9c7676817dc72e1bf196942893112c3468e306cfe1c0ed432497c921c6b7db911b823b7ccf7becaf0d1dfa618accec50ac6fcbf48b2e01bd3d781a7a8d21bdbe54c612ed8c8e433ca4b7f8a5328d1dd9098ccc63801d171a0f131db61dc46878a0923693c19f599dbb418fc85c7c73b7e04e3ccf5786dce0e06e084541d9e1db27adddf10bade7a791511e0481bcbf048da90aa09bc7bd019eeb51748644e9e6a923a363e1bf5c6b537775d5e722058fe6402a725e61fcc89a6ff6e379864cafcac0c03a844438d9aab5a97792ef193d7d5023d706b9a5b96c865dd4873b350e3322886d3a512bab9f27c9fa91b3b870e26647d52626ba26b332c17a22be9d4add760e3375d028fd10e7a6df2c416119c56830b8e0fc91c6235d39a162a047cb692e56eddf63d7138b0e26aa3fc693d7562be780c432dd54fdd8e18a57146bda6c30623b846f82737d685b2f42141c03edea0f4924e55a45bbbb07031c9778047e62463849dc3a2d25f5666a2b502a1d3593ff07f04bed875ce1105562492876d59193e79ca4135c387d005cc5e758faf234c8128f740c35ddb4903e5cbd69150b9e5e145019b7448c24b12aa0b60c1c0461fd0db1ba51eb4a1b81aced55864b569fe754dc6418de827663bffe0b38aab8cb0b75ffba296d84bb6ee7a90d16ff3ec936fe547877db655672288790f5b9290ed4f9285947453ee85522da2e033a6f5ccd52c828803d458c84647e09ca9e66c564d46b10c85666900bc5149bc5c6468341b3f737987aa0b7dddd2804e9f5d1f0318d910a14dfc9202141cfd79a95aed2fbe82631584c8a44af2584d8ffb2a56c90fc9f1d97abd66fb02bbe384d339fb7baa271dd04cd23f7ffb3faaa7bc34843f0f4353f21d3748eb401ce0e795831e0db60024f47884def0f5cc6054fd99906ef4c46fb872ddf55d3043f4e6c23b3ad847f8232f7555efc0fe5232d7dc7c5b3dac37be54f9781e030b2d2cc1f41ca1674b116127a7ddc50febe8eb00f1d14298791c65381eba2fb49474523e2ec5307a31bc65171ce3f098087a030a79a70cb844e88d1213cfa58e54904d86d2e0222075148152a7d1a2efa27041789aa4f8eabfcb5a43f2f905a6b01200967a61d15f0ab11cc558d388fd40ed4206662ee52f41930ecf87a0680223f8ee0b1f197e21e1666d19f6f4d5b871c07a92ffb8b8e90e30c16213d6a8d2a4367b5d207fbcebec1842e5dd7ce59a9a3f330ace7e29428cb660a06b3436b169ec66b92bff32f7368608a25a3ed7f16ec4ae410111a226c0194e7aa3a98e7fcd3ac238f6f34f5fa5711c37b6081281de0ab688ee667448fdad44ee54da9cf6a0f6f94cd0ed114f019b5bf2f9e6ed21622f3699a4437136159275c437736875adc7654931be3bb41d2e753407be0984e923fca1b4b086a5912c24b104e922c7ab58fbc374a12d75be1bd2a48285b00365bc3692314369eb1d71b85c42f09d747ee0054c0d9eece12f11596e86443013058c81843033b96f2031e8c2c39611d1f6fb4d384109fed2869b4f5313da0b9800b41ec60907fc9894170486fcdeb5835960ee31fe63a0d21e3f8b1539e938f775b1fed43ca09b0d6f9056384ce40d992008ab0bc44696cdcb99d24ab7bc031b40ef7ad59c7bc93c47bbdfcee8f5643c0504dfa659d794fe8f8643a0bc2f3ac9bb99091af3b0ae2784e23489f71d22f42a09e46b4de865befa2a346de0bc882642231c1f76cbf6094c23002be31429d12222de7450de501cd8b2af9202750593bd38b6c35e2cd25fe67819bd523ca87e5c24b7e517b746a23016f645ec988393a89f1122b62fe4862bceb1dea888c825bd5960d4029831af2b9aa1075c647291690fba5f82dfaf332ed2540c9bf3471b8744ff79882d22b5ae7d318d70192b5a12c4460d46cf1af641a69975b7ff07d41ef2a65ff1e51f36512af357c16c414055e5b3eef7b5268ad64650e4fd8c19f4f2fa3a842d1f2cdf0a49005f5d0350141f9490a5e2061dd03eda013346af81468b1855f1b9718020d0d158973a41b38b270e3ced6b50c4ff42bb78b4a3361b121ccfef2472d4c32592a2a3f4155dc202a8e784b661a1a28d224714853636900f10c37a31deb824732a3d56aa2daf861ed337d7cc89e54b648a78666279d903d475f7d0520561a4a2e1c25ca1a11ee59543d90ee4b80aefbd9d776187edf7bc35b3df1efd2f0c8410d5bca2536c75bbf08f976efdbebdef84cbcdc40916b9d38f1a13f32ce1f679fddd7c24f5f926c1a2c0a5ff8f7a657eb0bd21f1a10a0adf82e62abd75d057b0960a08773cdd04168a40ea6b9c8cb1bce3f101b1fd1fffa4dfcb610905f8279b9d2ab87f2db75757ec60c93937bba28a78d31753e536f04f9e84d6c7411adf693c26ded1a4451d08afb978bbbb2bc12591f520a5d2bbf1aefba606285c479ebe5acecba1f008bc9b4afb3503739bf1e6bec461d55dfda827fb3195dab61702d48c505b88925e2cea0fd0bc86eb7bafd2f480562bfed37fbc92b2e2e3904b07100f8da40494087a968425c85bc743e011b137129fedd7752a66f1dcbbd975e6fb14a047ebad528168f98d9491fa140717bc20dbeeda0c0aa4ee2d0498b2e017e21fcc06c5a8dd63dd56c7d93ac939832189bb20e7816c0e0b3d93e7dd3cd51c79cc27397565fc31cdb4ee34ef9365c2812c341c70e4d312e0076d0154dcee2682a1ae2aa9db1881acd181954a2e1743661cb7a3f524a855c6f05e4629578c357612aad2b23bf8b8e9151b14a008d4cdf7d5574d330706ef158b04f941249c139d7b2aea6e5bfa16d649055a7706e8b883c0d64a3331d08a65e56dac6fd367ea257f84ae464b3fcef0555aacfddd6f6fe9dc5a2c28f2b0382069deaf7cae4c14dde2a4af2540967ab8fed78d2d377d70084c2266d135b61410e1463f212360c290d1c7c4792f721b046033d6ed7acf193405b973818af0ec7e026c80d0a28b9fdc09ea73bfb0d0fecdc347d193d107513115d520c0739fd34ae7525dd795d0a4d6a8bd189042303c3944dc2c3bb913d40a918722ad5f08777bfa45e90125afe3160a9cbc067918fff1847147324879610249f643f88086295a6d7ef1b1ba0c6999f4fe41f2ff9b88d54445b94f58b066d56d405b452b3b38c8f51fea981f4a21da56426c1cbd71cba4dcf362e432481e4bcd317b5bd0a67db67b0a559dcc252b459ea1847dced7c8c8b153e3abe034f70e2b29f708783ac9c8dc073240f49a7609662801c9f89c48d55772ba037be420b47a473329e21e033021ae4da13729695a7bb563f6c277ced9bc63e305ea3bc2b1f9c0e7227099230376bbad2091e51edec9e4dbf0d2854f8e75aaadf13a5adb51a95bc19cf53f1d13716084390d1e765f3d4b296079700bfd7647086e9e01d4e35223a303b9a10fc061962bb29667f31261e7d6d00ab8b044ca292b91ddedfbe6877d260096660e23c6b8c41e883763b636c71d787c019b3eee8665c401178af18a6403dcba1c8b6fdbeec3a0fee6b2878bc03f30a82ea62d2cd60c46524e445205c68cce4a49f145e2aea07be1e7e38e41ccf7e091cddc2ab0f708b9d210c8bfc2af7b4d9b7ab67205b53667c8e7f9274e2eaa3c5e4cff1b6d637b802f189ab81b1528f912e0f398a6e9b6dcfbf2cf968822d95a69b1bb98f6bec02f8b2d4dd4e5ea78dd4648d4e9835c2c5d6ea6e57a633033fef44eb478a056a485c7523348583bfc549673c39768c9e0c51649f6792be29a213655f54ee2df44610776c42223ebf6eccc4fa6eb7f122fab17d82b85941859e556ec947e5af5ed293382485a5dd2e8fe0e34edb3e6a0804e92f23a4bf9892102abd65310a2d65b1fb7147d5a29155deae468fb8e470296c6a9c55f04b2dc6d42ebf8d65e6ceafbb42cdb526f7b1af844b7185234b687b6fdb64a530c5d63b60b062db1a9b2445b6d424f563f784e0ec58c70ccfc6c6ce04c70d2d7e48767ce7ac6989679918446171e50791dcaa69a6125c580e5dcc4ca1bce6eda84dc3539c95f658c37075b16f6843b3f5d306cbeacd5ee5c14906f58afd327cde5c43d5cbf7530ac0d510b206ff85da670d5ccd1b4c40365287bd48fd8ea07d33241f7da4b68fb0b4a4c55f481f24118143c7a52c5ffb219cfdab489303321cd0dda1232eea3ad777538a4a7ceefe8b01e7e10681d51bbb283ced841ed0d0df633d40fb174de1397c9b193c0e638828e82e2c9a20f59329ca4287d61feddd39fc3e476e4d5800cf9fe1f2ec61ee4313409af24d344c38c57c74b3ca3c0d0dab0ae4e8b91c5266605797626ebad7ab3238d4a7411d554c2c233d6c96f0cd15fff9c548cb6d38a7633359294a4c2d203297e0fe8dbb2392385632e915ae5d230d9eaa57ae5ab014b4519fa4aaa953795f9385ff9459b05b7f88f98cce6821e3532f27edf388d9d98fceb5b92c3276c4cd6567375a29dabb52a75da242b7a314809d267959b263df1e6f373b9c77d8861c95569c9e9797aa02b7883e0027637e1051995b20aa1e33db0bfa6a0c679088da269cde95258d64874164f02fe2a716bc6805bb2b5ae2e85f77508f28d09e5a493fc7c4b4ff811d0b205399221532c678a4fa0b95df74ac3c736a31654306a9dcb4e9465a15adc26c57442449a8c83319efdecf6d74592421c0860b68aaf60728912ece1ab8daa507e32caa501484fed83c9a5689c2de2ec0af973caf23d907b403a64b6b1f3c21c2e12fb07afb69b89aa6b81718dd20eb03e086e3cd27a9b64ae9b033b693fc4e1592387b1aaf070269e2f716cc694246582a7a7056c2ff46985a397770620a0b33c81ca8c908f889cefde81ab7830d7162800443649c13961076ba66bf3ceb306c45cd5848f8b6bcb6495f7013fd3e84baad8350d369f53c105739851238a9f0c3bf7e03cde451595445093100e63c376aff60a216a5d51c43ec80bf1fce647237a7f22bf19c83199388be072c3982af0259066fe01afaff41a285f6d990bf365f5546d455ef7ee8aa0c71fc95033068d0fb35e36278a00701525151b92729f20716ebca2a2a91aa73b8b3d7cf1095874df4b74ecbbc19523818c603877fec492228aaabcb49cb0c5f8256267b76647002d288a0d23591f620067e987c241bcd08ce276a073e21b3acf61331edbec6bd129c2e7ea3df45be5808109dde59d1baa6456912390779193ef5177f0ff4e977552ad603758a1373dd6b5094a626b55de0f336a058e390abd183a49cca8a965afc770cd8279be614b1ab9d1e3cf458490030411c2e1f2f04edaf1ff1a33d3e08961988b2ce49c2b0636a076cec93e6b2c90520cdedac14c4a87443ac5cdb189a42223ee196d21483486df2a64820c35ebd7b680b1b7f6a3d5dbb5756a7ae7d79a82ff82ff440b4ca9afcc1ed44dab63bffc93a3ec0d87697d2290374b472749fc19a42ea1db1dabfc41cd085fe6d52a1a557e8ba08e9d01c7db50515c2a32e3c5891a7ddae9223edb98edaedaa01915330d2b84e2e27a2b90ab1098c149a81b60b522e094923e158d9fee0f9b099a281d6ab3e9445ef4f4fd062624736cc9e620d256743c62c0d387c348c2fb60453d74f1a8a6164cc68b81077cb0d29d4d2846ae974afff20a6eb3df9e464f66c47b4bea18301c2eac14adcd9bc56eb6a12c7b6bf45c0acffab7a7b1fe70d69f6ae5093143d7dd900ca021ae1c97700ffd1b16617b151e8fcb7ed40af480580c9cb4a4c92c69b383cb88edf652feebd84bcf52b30df8dc58f485d0e74a8b2fc908bb69f2271a9412c9077331f537765b857be7d6ff48e0601b03755eaf7e5d2434077215131d55aa3a361ced31dd9f7d055e6cd589a5a48a2d43b0121f94b6a8bcb8353526b8c16ad83f7501a2df9bb237f25fd05bd8449b295775fbb8b6abe34f0ea66038f385c2451ea912db50134c77dd904a41ab0c54c1173434742c690ed384ad073ddc05144870c08ce31fdfb5b86ac5fee2f9e49a276613da33d682a862fa272236ec96c36015446e356d7adf5fdc197d757b7d7258eac95d90481973785b6471ac802f726e17dc824a5860dfd60f98f253aa6bc8376c71bbf88e14fcff5f1b0f473a03229308410fec36fd004946a8b6808219e95c75fc36e9dea6cc242d4d2f076e3c17bb0e7602a8012afe9450778acec6ecbe39d865b8e73ae85f9f3c448e0d7d5ca2bba4fadaed67cba29b985e22a2442daad690380f751dadc931ac9285a6054fd05e01a8ed801b0db90749644673383fb808a8adbdda51000bb08c522fc5768e8566b4280b0408c36d9a6d12ef4bc0a31095babf53c64793a3b794eac375708c3769ca46786bcc2d90d8b9e2f8dfe18453cd24f1a495fab30be5130fa2e4a5b1d22256f43176c4a58028ff12eaeec070eb35abc8cbb5beea7a0d3e390864b13ccf18d74debecb0f12e4db6b1b2608da8bcf3c4a6c85eef8db244b691d5732cf20f0d8aab1f5b8aedbf4777b4f4801a491f40ac7f5735ad60c42689138cb2d648ca60fd67548933c869d5f640aa29fc533c928911e99d375fd8a7ebe28309376500c48970cd28c020c7f3a338fe889e1766b276c6d175e090263edb794ac371a1a22b9adda656a7d3e3712cf20dd1413999b0ac37f0ffd3227c40d136a78c74592ad3d91e89becd842ab08a3d0b16d0ea230c5994ac0bc829477fc6e8891778006c50533b83a68542d30c36aa914408f9190ee72b73379b1ee6cdb9d8db26cb50233137ab3cbaacd0736f5ac3995804fe4949bc0dad0e1108f96f39c07e1b63081908ebbf9576235bfddb489460bfb94217d09d176947e8d50dbf4dca0fff975254a3b275b297b6930b2d04d9115e6865208cf1097a0cd1c41df0f8ab22434398a976fe8872c37d4171202fdd969cd66959ff487001c41dc62dbabef24b40a14e733f824bd4bc401cf0961aee662ce2c08e7e71dde9da5e7fcb0464ecd7c7b652403d712bb9200dc6c4b9dc80308b91101febeeb9d0ee049af0670d0205307a09d386e1016ff3e0247e563addfe562bf8f1b589a605cc713459c887111c1a6bded18b0a33eb3db58dec051796312261028fd66af69e9dfb822439c9a0274162d61a1a4c72cf0b2208404114838055e53ff0fdb86856d3c6e4a28365056c9d28b19ae8fcdbad74e631bfe053aad406170f9692583f09452b3f298dc7cf2158b4429cedcf38619e620dd60723a056213103904f39505fe4b956ac0e7e4b4ce3735d2db55e2400d27d5201fd2bc24cf45d2bd8878a0838383450e6d2826565c180a2cfc76cce131ca61a05bbb11fbdcb8bbd67e40d668ad90fd0a11ac827a5d07cfa0555d2b59b8f2f2b4f90e833ff119da56c87108581c2d9b5a7a03c70c39e1005f18f72845be647e7cb63c6bdd8d58bced3ed7df99f355492a32ebe824ffe90b33e8bf8eea189c64038f7870ef9bd1aa9fee79a43dfb806d11e55e24610dd3e0a635a2d039fc55e449d1b62f22c1662f619891f0ab0ea2ff76653c17985fd1b25881be516a66449f1832ee84562b63bf104f8d327b1e56bab6d6e14ee347a64b5bdcb23cf1695d7c85ea181e875c570ab971cdf2c80a15fb49758caf03da703063f19abdb6ce6e4356fd1c131efc9b2cf1d3dedf968608391ced7b96ee6d071c6a8e38ae76cafc922c3dd99b7eb5c25da32c8892435d119e8533fc3bf65ebd02015b7013b82996ec98d18793a6c43625f0ff004762ab4df9c04e83b4768ba6df27a8b407f5149907819b5344f0e4a76c433ef88880293866ff353ff4f4b5f35789694ea52008808e815026fa225f0cd3636f65846fed129935f410b495045dedc4e2a706cdc292203e0e4188a27690bea5f86f22b7b5a857cee935cafb9dd50ab51b32c6ab96a104271a12afacbd795976718602098b257abaed5d77d1eef63650f2db3e2f815b83a359f31a74486571335467c4640d5257d731515bb0ded783e589fb8559e3d7f17f455115860d679930fd5984411c39c2df51e320acfb8c2b8249f0f80501558bc9d97e4edc268de6f98b60905f169ead6517061521999f68d1e38c251ebca319e222f8e48f084eacc6ce695f847925a83d2db6b75ac221d6e092e7338a703e66f5ec3a3a4930e1ec40a7805b167b1256af10622fcf44b11dd191f4f145ec0ac5fec7c99845beed924138ae664b56fe112ca3ff0a2212a043651ad8b579f32710de1f11856dfc12c6be0f817fc81a0e9e22ebc75806103faf3bc26ab1854291ba3ac0649a8aadb04452e18456af98617a3fd3538f315e060fd875bef2fd0f58f8c2bc0d134e14f71637cf880c955edad8e8b611258b9d0895cf2304e46380b28b1c598043e82dd57e44ad06bc617f78ad02b205c9a0d292e0ccb903a834989365267713e54690647ea678a0e30f8545f43420a700b965204ef96330855644eee547351a9153ddae1175c5c3a49615261002a89a3c7d28061d6870254bbfcf8c4d3f232c3b458bbdf452b4ee34f22b3848515cbb8621ae96977019660a2a566dd107b2e69d8f88b8b63a3a3db4c384833cb5dec81772ed77ad64ba5d2f574c2cd0f344976ed58deba32a0351fd15b151547da3ee939f239e01c7243e77da80e84b77ec27a9ade9e837aece030d51662288da86781348da2cf9e4d91fb1cf94d77fa9d82927fd506624718b8cb4168d64f1be9d785abca0fae1fe967e8bece4a59e416fe8fcb06e2a6bf560d9025878d4ec80b8a1a000f3460ca67d4d0f389276b674c70b4222c1c22c5bfbde3e51faf73e1d4e1457d17d911bd02e2e9d96571a739353a1a39d22247711eb86f688155a2726035b1db07adfebdec94af9755e8a48273d18c61d81e6f03afe27cf96adcada8b8e2422475af05eacefd52e17a3dda8c655a41d9b8300f1e6f94d59a743ec7ba5245af0517981f8d9e6f8baf8b86a0c82fbff35b84fc993861b390bdae49f3c4c73768f4106be0437f20d00e5b95a3cf611821aafbafa8c73e48c18a7012c4d20f6cbe87e71f5c6fab6e44556e79f75b643915068073f7a1d94604f7226ad60633ed37bd4ab16e4415a7b80d7903b448f9031760807a180d55a7f1854579b5272b11957aaf1612d02750c1b0ed4a59f6a0260da01bdc294e39416814845ccda753801cba9e02968325471d550cc2b2ef8c1fa0fc8700126355ab49b98e12c2b160ad383e59a00692599dc3a35e8b9b4467ad4f78591a0b8fae470077f55f1cc14fa24a682c61762b12d9f60de3c89110c2408f3a83c4a2a9c87d0f3f111a71d5a3c35fcd49da62b08414d6d34a28878cb2b1a625dae9d88dbb12b6385b1ce48e25584b561963cc230d98d1c2b6e31505279a1f0bf4dd9f44a5b50108abce5b4903110cb5afcd61c89c91f2ac4be423f7de443819a9b38cef2b501ad2a42123a943856ca3e66f327b4030242bd9639c4901443a99f54c2c08d768bd4bf755ebeca478b2aeae56c936ac081d81c97b3081a4a48d49978870f31f7f774a63f0102348cd06621a8465bc756d11f7edafaee277d33e7f2c35ac543f025e1db35138430a298f796cb30bf208294ef18e18ed8286233e477bd1e21438a8088e5b88fc664bdfefad96158f5f8db305babc207f361aa787711edcd0040de5d2b60d38652981e2f1346fcb1af0412113ce3b1340489010c7f373f1b4218e146858c017ebd9305f3524de2fcaeccdaa814c7dc88b7202fcdf6aa417745bc1ed88fe3e2bbbffdfeae08fc3196641dbc86d76238e96d608cc0444359d7de34765505d899cc0d538bf10ebcdeb8d945abe5a1ce710b676394190b80a76b7f6aa56ba74f2a7c86a6157ce8890a5dfbe0a62ae28ae7347f0bd44d3b67461b7d85a6739215ee65c9f304f1d64d34baed53a40b135f1080c599e30fd504f462631e69f743e766f7a8514ded78feabb6ca781789b2eb83ebe056286d212175c9e08c0a5f1991b14825c501f3e7b8b59e242a11768ce43902711722b383c7e61e150d4eb1dc3d7b99dd14b1565b2f98f16e59e3f6d3506d1ae3c1e4f6b310da49462744bf307a6b1d361ab45835316aa96ba83fe8e2e5d5e2d0b836b396ea62de9b5f83e1f76cc1fb7adc9c30983ee0fed148a50489cbd1435bb0d69d2d8ee98754690fdec4ad02506ebc30f255bb96c281e1dad74ed2a0ac3a477f597d961b2c7bd0627a42fc11d00d04e5b59c950ca94d00b64bc0945fb3dc5e58241b4c3c13b846b61424c6c86c751c55749fbc48a2545b6375a0b09f5ad8927359de381f0c4b1294a50d8cc73ba487915775640afe2c3cc45a7f060cb1ae44b2931ac78a2e5539b3ba79184d775a5fae5df3d433e32c312df49171bb3c7ff1206a515562446b7a5a0b399d22247ef327a5487927fccb78aee4d40fa26f7c0757bccb233d8e2af61d588da5a51f5a00f32ca59af193844e11787f86d1fc968412c1af469bc8cccbfd775580dd646523d2fb63ba43e608908e372216bac21f61bf3a359da80ccc9fb3689d5fb058f793d2bbde05e6f1339677b48a606868818db2ed04fea2c00fc730f03586e116eba4642c404df12f6a09879ecd5d620c7af27ddd8e5b72a3790c48239ab4155e147d0c26085b1068686cf17b89e8f62156670e25f1d1b0234a2c8c2dd532606c3f2b8940066deadf66f56a922b8c9cf60da212194af4316cd4536a0de98198bfc9388cc1b7c5cbdeda337e1ba003451175a7b390a11d9e4040894ad34eadf3117b6b3861d7ce0de1be0a2404a40f7de0cad44410e0f892868a392ec0090cfa482ffe87de1dba5402550fa24fb045ed2efbc9461e05b52ae48b35f65185464cf6b462e063f4f2c6063dffeb4848b50b52a0a14105f89f0aad3dac2c35466ca7af93e8723ffdf0271dfc73506cdfdd8320a28137221b7fcd608d32ac486c2909c1ac125b05ae3f11281019adde1c1329cb3df59849f502c88f1bf3b9dbe218cad2299ee2b5cdb14715068dd52809b001e98740673798fcbb4569e6b557a9f6daf4cd90b4b55f6e151cc2fd4b9646e97136b108fde318263696076ee49074466211ef7c49c13ae075e9d83845ead3cc005304d81fb57cdfe489f2594235f94478622c8bf8383ff6074a8daa64024811500fc192f8c1a925a5db63022e2821d52dc8c53e41c5134433693b7f67e0429f6d0a93422a684846bfe3e797c3dab31cbd0e6dbe76f6788711d335c3bdc070c8ad0cb4ab20c22102d82989e9baed187e4e21df4b23ad043d91383869311668ebba68721586a097fa504823f94abf8bee2c60787b4e58ed29486b2290f005ea5b32ab0df41b648a4b8a214457f8d006b68db587d26a474d55acfe7bc8bb9a795e2c101aa468001dccf1271148b7818fd7728108d3e94ab8d42ce7ea4e38e1e8429e985c08a5b5e2112f514f35ba2f6efcbc52b672a1a6a1d8bb31a3353bbd89267469059d30207dde74a498105c20be18992bc0304053b1c45aecb1e82d652fd88a57e6d875f16ef84f3e627ec84d1179fa9cf46e212ecb9728c4938b398fa82b1517b33f1940bb31e13ee69adc6d9b1ac1c4de8c40caeb788364dc5bdef3805cb6e2ceef695627b21b443c45613a8bb2f2ed5a0f2efbfc2aa0d428179a308318c8c7e5daabbcc30e7849bfcc11c8db56ea1583f0de3d322cba806c9249c5542b2c9877ede25c23475ab5727d3543e7cb7a2037b9356ac95ce4e7ba518385a5bb1a752e9abc41d73b3f36286c2f0599d3e9f23895ad4c5c4b442811bb430c470e634d0751a5c5eb0b4eba30f482f35b67acb748c7a7df179c043f661a2a1531e30fa6a7ce50f9c2162097b0b3d168abbec56b36d2889ab4a8af033097c9aa15182f3f3baf6508bb669e14dc0fc26055f4699522b318cb6fed27025105446dd3c9e62d3d796934d0fca083ef3e54123992cd5be88cb6aa4acb41ef6c20e394e220d368258ebcac7cde12b2a3231441db814d82110e9a078cd9c3afa8e7cb06bbecff84ddaba5e21d0a20f66938dbe31edf9d6f0b28b8bb04167eca3b2ffe703a230e8ddbd4bcbe576903cb061a907e2d01feb3220be336bf9640965e64a2d71ab29ed35b0bbd0db739a0c3a686f44b2d3c4538836f9bd32c4921b8867036bf9e0df731b46458c0b24100ab9daba55026c39d8ea78eab8951f7248d77b119191f91efa5d7b698de7e209089d1b452f538762a8b6936a7da646460e43d49d78424a3848790bb9c2b9bf641b1dfcdd9ab695301333bec634e610165af8860cff21e80f301cc0053cb26351fb4160aca6e99fc9c1717d635396a8052fa97029219c6570642c519ca55d40883f1a49b1b94e42d44da967bd7983474dae43a0d9c106ab6957f7bd7e98f919cd87e29f46b4394ae40724246f783dde38bf5b286fdaeca31981fc047567e7f6e353833e548ba1ee51ecb2cc6f575737568f203bbd412c8642d36a14c10347b3843afe9079b67adf8bfbd888633c531ce524aa8c423e4c106a287a733c2dc49892493e29a394ca38c289136c34fc730d6400d66e56f5befb615a3cf83910b1a35f704e7aa114a843f0bcd23fad81276504b8f31298046e11e91332dca33890239c82d924439f258e00e3f4e621b6ea4a645fa1c451a0383913cf7b9f070861a92b4b935b6a513803dd7e65ccb44ae88611f7af66ec68ce1afc575f9241afb39943550afd4e8cb67ca4e6c5cecb86de427b290579a207cc7d8252b27062dffab384ba338d4cd6fc2573f02d4a0421a51ed218b19f2f0fe3d81eb819f81b4c6b735a31edbc59ebe5eba4b081cd151ea943052f72e036b76b07a70455ea383f291b6904f1f9eab6c793b645c73635108abf378a9571fa6a505de763ec58f9195c4264ba895c09c3be0bee4644b65b029d48f3c48c16859f04251fd2bc24d5d83fede56fb05d8ea311abfb620e56b13fba59fef5f22c98189d3a94cbed22b0bf73396d9ed71a986d07bb75e56f6eb4955ac218b1243c205ddc5b6085da66fec5fbc41953b27b7b151e7317c3e6f9fa9006f0f2f89cb53092486577244abfa99065e705a39e4ae5e2f9182626c9c67fb0c3c17870e6a3a9514a789e90dfdf977865d22ce65218a910214de41a7894766e9d41b80aed92573c0c12e1da0fd1592a78bcf60f9f4fb0c5fa1cdfbc792f78f9714ce6cdd692c76e05684158b827c2fa26f03a9dcace322b61a76180d8e91063a8807731bf46b5a4f05db19373b88d85e5ca06893277c57bf2c1d781aadafe2256b599f2103d19a9ebc7c75c42aba47e25e31883f138f7e5b214a3bd32ac84c41ea1c60dd43cf2aa7402729e7f6cd68bbd47e26426a839c8aac6faef6552267d0d7894bf5e95618a6d7bdffe5c5ede31515e1b4ed325f5f1550f8886138ca405ef357bdc79bc0115462404d615762d78913c8f9292bc007c9f9abde4ff78a6cb6f0d2640ad4407602afd3825f50af05fa65db34e8c8ebe1460f776ec01e512e4b64f62b81b3367c1572b7489416368859071baafbce97d325940304d6f58029294e354f9e03f4d03a42e4cd0e30b88c61d9399fa25f076f9bf896f4733a986d1d9a63d17e26705f1a681a36bf5b9452383fa018bc48d01a3f9d8344204c989ad191c1b6ab65993d57ffca0e9e931f34883821825e8378a74e824e48ac94607602f5f2659d35d41682c275c861afa189b898101bec6e1470a82a16ace3c95a03e878d8b76c6dad9578668fea2d0952778403f082a683c5df519c0a2580eb9dde228e0284cf84c2936d3777395d49a13dc50d38bacacdf6cf2003d309196c92c17983a179777451abc874331d342e02c115ea9147a565968cd52749918105793517e9ca35af49a18626843b6f1a63fb087e3b4133f55cf2ff79ad6b113f40e04420aa1cdc447c6b3700b6041acbc2a17fa81712445a07f070db66f4edb4408a8e499fa7cd821908bab367cdbe5f235e3023c588d872f3f415ffe0c461d2faec735a339303c63e74f57088cb89775dee600eaf9a53e6c9608dc9a8467d8bb5b4eebd69c2ed440927c45337184dbc906963f627a13f13185898faf4443dd558ba30fdcdc4a6144333206c945d7db4d5d1460596c31b2c00e435d6326e95e239394fd8e9bf411cdadcf6f9899195b0898ae37cc25720ad74042788885fd66da309c6b13a0d73bc0678f0afc6b0a71fd7414e880da125f5158d23fb53567db4a42141a121e7b2326c50d3ab3ba34bcd2032ebd41237c056575d26c85c426a8ffb575054ea3173f1c6833fe8582a10a269bbaca3d082ca1a52e5553c871f0f82522deb356c416e88538dad8e1b4b912c176413573507db238d1a725533db557c2285d9304e2b7d19ff4c4d24fdb48cbd9b6f19d9194ce5c3424431c0fdd583ab25305ae6cf6b25811edf0f01f7224df67873b293930dade3e3672055224dd0f9ed455cfdaf041268c8f49a7beb51de0aff27365b215a241d71f41174257eeaafa0a68beab5a9ddab171a9db0721ac17aaa90242b6943c394feda96730f8f85312d12c27a7a88e8049486f162b3ce5b02111db0fe360ca416d27796f25d9d2e78ed1e5ebbc0a20b4083120865fe96daf9125256bcc530a291541fe87c72eab57e15c9643d2a61e4db5cebaca8f52f9a85a0c78a40ecafd1526a927f18039af82075cf1bc0bba98f7a00402c1b803f4c574f6d40db76cee91506d0da21402298b2bef6187aee3b85f7e153386580b82914a4b3c69cecdbf1a108c70174d933c9db0f54bdf8f546b514fafbf0512de6d20d780a002bda80a5726055bf8a28603219d862fd92910297e4ed0227a3437e42ae3f78e8e6e22345dcd87ea404d0e29f6818bc82dd1da4109e030465210fca758bf462a474af16fab51128c5cdd66808b9e038eed7cc7ef9956a00bb082b1c4685bd314aa0ba2492cbd7d10bea7099d18d1d6a377bbf1ea4db13656f600611c12a84cbbed41d571aeb9934036ed40536fcf813125b2ebd953e25bbd2a45cb7a24ee5f6622e8ab37465619bd178175df9b7c95ac64367378c3cd0140069f1a771f53c1aee04e1f055038c566b91b95c7ca22655c860f06904f68b7e18261c129e2dc1066f3675361e66e7d2ab46b72a4c2a377378da04199aff21e80ab70b35db6770582ba46656d2137222a01a683821b72e589c8aa7f49217a74c628dd2017a48bdf83b2f3462487b2606f2f47b1eadd7abaa23616f5adebf77a39d3d323d14938ee88ceaeae23e1b4c9b3e3ce1f472632f5b5f39d76c946a67980a135458b3ccb1c9509dad37b522981d514b41b4c131642b50067fcc118d524317d9e9bb442ce396a86e5b428b6a40b0e6e9e857065be7c103a77ddd2532889c1354383e1f9c160afe5590bf756109964587b7c9f3d92666eb9783551511848096b8d8fd30f17c9642c58cee5c0d6de55c522906e7c45d0939454bb44fbb47348db92fb76d51b2e1d7b32abbbea0d179d49ee3913f8165dd8456d2ba61a5000ca6596b3b9f3723523e0a7d82bfd26912cdcd8870dafa7bdf5b480290a8a735d157012a965415686d529745418d21602241402b778291d72f7fc183896d77ee248d3fb8b61648c9c9a8e19492e106ae93b0cfc4306970a53bdf9059f151b3001eea9ef41e1eb894adaaf54a13bc734fa0e6f6112685be9f080717db0122d99faa1fe97e05fc1c57e6cc110280d9ab0dbd8ca86243f9fbcd6dc56ad9e77625902dcbfd7b5a172cda669cae253cbb95c3c97c18ec3584f70c4491f6d34a2c55bca6d25d7c99801f94e7661c0a03320031466d9e9adba4e1981b7261dd844d109016712db57388c1d35d1b999928634f84d5ca611cac5e53d2e2039b2d2c38a0d3ca438a9502964a21ed1ea5ed8c044b3e022a4aa02858f29d365559f77471675ef0755b25c5bf04c2f9f3b1f39d920e1b498a3f92020833c2755565baf15e96b2b266a118d40b39653c63033d31ba1db30d33b5f2e9237b2156a46bbb2c74619f06619a53ea93bd56ff1fe58669fe7511c7a990ecc1a5ed2bc9e6d45f87e5196d40abc44772e37ff7f101988e8a9ebb9ad25949d694f124c02153cc6970290d864c9fc72aeff8e522298c4cd489ce25e2789c1921c1422806bb805c617c8981f9af5fe0e4e9b95e6e60fa69beb19c5fca08a0bea187eed957d3893e77b59a91fc97d7290f6c23b4e17520f9430e3a898c7259cf76caa23d06ccf16d36e0c7900dcf3f1c0c6916d425e20f7bba9b45a1d09dd87e58bb85a621ba8d74406a767ab59f97334fb7bcfe113e966f57ea87b90f6ee7bf4ab3660f2436c764f87e32bd6a4a5f978fc6e9ca350260a4c1d4d1dcbcc7c059ff8de670c2a5faf08f5cea1d9ad4f931ad45fceaab8ca38719bf8ae152e302a7e03c453bb3338d02c226c1776fbe8e696def33cc9a8c9000c6b680a5d20055aeb5f01948480f2206be62f668247ddf0c7424ca4916f324aeea057e551b0629edc70cbb75059d714fa3f5d707c4602e27bae0361062da7c6e503e62ff3c30b0d6ea39534d6c23d2f89dc49d6488392305f499865b2e861f20775641888c38bac092a1338f422c4e159c1e1473ff24bd214cd639a5fbf5823bbf3537745755101814a4cde63c0db6511d4390fce353cfa12700aeef529f39da47d3d78b77d7ffc08871e5061d166580596586a33022568e0a95cf7736f611b39b315357615d4a3f6f86211409cb0cc64ffb35760123cffa28be2fd724596afd020fd0606d159ef9d5720fefe5273afe00cc8b7ed5865a5d488980d67ef2092d5bf331f2fe24071b68d51254e57c1881dbef8b4bcddfb4553081196965fffc1b05b39562a191b41e6ad1551f9afb575c21efbe8616e516d9092005a6084a09459996d80416e9ceed1877dec58fb910045aa73407dda5e58104366d3712aa903d766c352b84e78676f30cbfd99547d47ca08c2c8728e5f2ae3df8a8312186375af03aa99dba2af73c21f87ad675dd8798a7c997a65a3ae958d01b217cc4b98bb08a3abbcb77237092036d9bc43092367d4d0aaa905cc39e28e11a72a5045123d211ca54d98e669240dff4883fa2de45daf38c752977fa811c1b55609c8309b3550a367079c1f6fc8ed12bbe2dc4c9553470a59d54d323420762f84022764669e2bc16e67d0bfbf723c270ade8cbae829256ae252aae31387d096eeb18989067ff40ecf6d9be0342960df95780ef81a84951b907fcdbd61bb4d88492c590411462e5e1639a5fa251c03212ab94e4778ebcd48ad5df206b2fb4fc4033833b9034bd6ead0673578d551691020256fac43fb95aa6ae497134ca08e7d3518057f3261387cbddbc1bbffe402c25564a7f2af46154124ac783318364a6f22f293e3a82528bf3c284babc3d064f142758ea9d291de32f62ce0008ade2de0a150a61c86b011430a144588b7ddee8ac29f9fc767a89615593c7cef9a3e02db71efb96210ffc816057bdfab5fd9edfed807ffb3cd84a99ed564ecd5acbf159a7662b9e83f401c9489b65f88d28c97b3be308c3119a80eb23877cf281eb11a6be5e765cefa15ac4bcc8dacf47d8e483877609393d19f95c9a51932adea06a1ae4cb3c0ca4867dcd8dc487acf0cc0296852ec641da9d7c90adc81ef02981c82e33da89718949f34877cbe0787bd80b8a88a08b0d6c8e100a911a79aabc524e257890db7cb927f4305ab2683ec9d378019880afa570ae15f6a52e8e170567c9a91092fbc294a7bf71f5278c5f99b46b78713fcf3b9810f421acdb2b014059e9cc5627e96660bb8ceb2dd172f412e4f6c614bbded915c71ce29d7d6eea3da7cd166caf4ce413a5f66002edf6b1d496bde3823c26117940b9bf5f4949d6ec4df19310a57bc43a6ca03b020a28f1bebdeb251d164edd02169a57247af1122ca37431883469aa901e50aee0b69745fa977c45a9477c1f45acba96be8bf42a68e4a48ac6ea275dc87d5647e2e4bb616ba6f4586aa3a8fb3deaa7b8f082cc90e104a1611654166541f14826d253082135ead870a659606b596b8adf85934b0b079d1e7a348209359f8d168b15d0ef918bb3dafe822f91a9131008bf9bc199f3a422af1388d5291f23219001a3f3d5c5e109fc8d4ad62a06c63db3ec3d1f1c59bd61ca52b8e4f8c4840570a2e9e26665b3d8541ce32b34a5b12d9c425857fa1bec75d78721537a4ef452ddc253b79c087a28c5bf338978dc89be8f76cd64a252ef0e7d46944b1d89efa1889ca5c81d67d660f50610fbe71ad304d29f313fdfd898071a4e0562cc3b3a65c72a4341a59bfd92fe192d481032e53482eff4d94565562c8f75638a1ba60594a8156699ae300377c18afbfb4f302ea6b3963704a0410b565f7c971d249255883432743e5001523f663eed6660591eaf966200fc61e1b87911d4c7522d50ec5ec51c15578cf50f497b113e1da18444d50dc7e723f0363c352ed6ca3406f959e0f064827e72f9c80f923804a3555826927e11609a0eb522669404843073b098ae0603a2041c38a2f4214289217cef2c63ae05beaa00c4b77f7620750c01f1003331775706336f448ad32d03974ea0ed155c22e2c0b50284ac48930d58be043c9628b8faf8661d782ea9437cf7dc50820019faa5d8c33e845ac65b064d007cdf0aef93ccf25126d3827b7c60497cbfaccd4530e981976044008879c184324b2281f396bea0b15df5aef0a80ab4a74398e3110515c98a8de0caba4a43eb33607c9a1bd0776134292c039741b8e986de6cb8a66aac1ae7bb9472fd97d61c6d8b84070b1ff7096d4fdc52e66d17ea857ec064a1b77821eaba5c7cf25dfe8dd9188c7a70f327a4386953898c50515c5e07b0c8d6e20e0c40e749b414ca0dc4d78f302122a0d60d41c0d7fca4c5f851b06e55b183f78e629b3fd93c1677a707fec77251ee896bc52d6e13432c95e54ac7eedab5a6d4f4bf009343e6a283a80128dc03b60d32c47e69ffbe15c3cf1539a46079ebd954b9b07ca34564f3051b25957b3fd9c146a43835ec85a59bdbece417978db00e2d86ecd767eb9db491a3f74740fa159f871790ca84094bfe32f747885cd831b693d2e63e75e963254a313fd01e86d5d29436397bf7d69a7825a8084a5d17d7fa6f130b642e0e61f86b346e15fcbdc868f4409d046959b16662eb78ad806784ba3bd0f467acc909bef00a7acd467eadebe651ced6543c8d98538731381fd0a23cf0ee97170830e471309294933439d001954d21c72ce443210703b0805e073ab3bba107a02a78b87e77fc3c2384222163c35a4c46582b2448b3c808c48c862f1a2b4ccec42968704a2a951d320da2c846537b0fa1b5d854da779109d7dff4dc555ae775322a750112438bc976a3628945153369e17c1264478f227c0020a773c6437c7999e6764911aa5d8527567ff4cbdf0143e23842f5ad3c06050cd6c4de29450a9f2e0c9d248992872fcc9ed18dff47fc32527d0b6fe889e000d54e71ce5cee2188dbf37fc98f2e3d34873d09982e4011564bac12adb29f0e5790b47d2812800808aeb89821365525dcbf8bab4ff7737a89f634a93bc80acda41e358e611a024f02399520cdcd11d4486c0908e134c2f3c7c18f93a5bda9d6c5e54118598f93131d9bf4631b0cc424b11f043741ed6204a8c51808115b9e4b4dee2d50a31608f1414c3fc4de83a5c7f1687cea2eba3b92782603bfa73a54bc78fdcc752537c60b0f5f1fbfb4e05140588636e9918dad3f48d75ce931a02f39d4fe0b39a7d0eaa3e224ef825cb7d94d25380e1fb87fc36c760f3f6e6b62e2d52d4d1682f8e6684f49df629902262fd646ba2a011e70d14f3ac26fd3767c10709ee101153500b44e422a69cf21b5381c6f4b15f724317092d9fd7af23e6e97258ee7220020fde3f01c465d26bd888663966848540372608437fcb966a8d309a7d75858d131e72f173b6b85f1a27c80a88328a1577b68d201f1a77bd0dc113b061d544978f06dfb4fe840c2d8981148d625c85dd069744b55b65908bc32a4211568bbb20af3525d106d0ac97a0ec3f7f27349087e89dc5ed7d33f3bbfb5711904b085b6cb3e3346e0c901a641874a6de568564285939a19e317c7b4aef66b744d7ab0163911b1e911d7bd2f5ccefd9fb12a298240ef6a837f32714e3709c6e08ca9216c981c9b1a582984dcf0059310c09c55cda92ef77a329a8e86fcf0f744767a6c4616726bab748c5a6fc32f1a05e45a1d84bcd20c2f0275849aa97ad4d3f0451d0ce73a04a45016f760d36643afb9eba6d021ecb6e53b912cbef11d1f590bac099b3e98e8fecf332bc009c7ce15185796d3d2f8acdcbff84a3b11cc89eec9296df8fed6a231a8f41651a673f14540c1190baf6382354de66ea56ab686d7361281573ff327442f7a085429844b800364a662ebf996a6a3b21769b9cfcbaf41806d7cadc138b57b44a2abdc60a731d9c54a6c8323fcf279c2fa13c5c8e8b97896cf3c54be90ed130ec753757511ae6917b772dafe94f521461d63cedba8242e1105f28a261632a30db863d7e29e7835f3b71168cc8405ae199b538d9e3a5d89d16fcb1a87dada4f29fbb52b717efa0930a636924b530aa4958d20941a66ef0564d55ac8f667807bee96e083e2d6bdeff0d73807fb2e08a6df6154fdc05ebf09dd2603a9a387f5d6f0d146676f5274409f10e064f8d88f54a6cfffe2e69b994d5d69757d57c921983d16a7d0806cbef21ebad0b1f139466ad8b0c0cb8a54e53c3080c616b026149cf39c3acc29e759d0fd6b54dd428ccd182614944a9b71adcdfbd3e8a95944f79b1337050feed6ce72dcd4fc6b36bac51a05083d62406d0d4e83041632a9e84d3d0ac4ff393059f7224bf0ad5a4cfcffba0ae9660ae3f350354522aa3394da4ce1383faa6723b8063c93262a593a590d76d00f38c149e69925b9ce9ab15c3b5e88f94a3980050ba82eea1d90ff8530787e72564125ad5d6c9a2347d4d1b1bf6fb712fb96bcf2c20116c762b69449118546829be48b8d980e1e04712d4c90136832f2fc03bb9ace910446bde292d37e0ba2e228b80ab527406c460004db2e108a23374d737147b1cbc22532b8cac84b1bfa9a55ad8cf29fb11e04b18f9834763279aacc000b88650c893678a5d1f4ffd844f7ae79e04a33a1db7b89e7a4cded60883703d4c430ba44c7990f59b5e0e1537afb6caadc2d649b18b19c4b236314192e3ab8c5c62f007341ce35a86d809756859fa14afa6184296f65a4c262b14b9bfef9795860986eee85d52d25ce6ad99cd48be425b91d3b6a18236b5a6b327532a26d2c2d8387a338169fb882cf145b7e8434bcb7d829f22f5e954caa9e86a1d7bf1240feced94f80e00eef078feb402f008ff05ccb20eb1a74bd61089d92b519064ff5c2176cf5be544a2bfa705ba62bafda1c7b1551cb4460bf0cc233e2570b2068cad2dbcf92b112521ee8eec2d9703da3b49fc33fab217ffbe97573271b867b7e6649fcfeab4d359ac0e8b3d37b2eb1bdf4fc38e5a8e7734bc6e282b34fd6d292528a9d92740468988f9a2be8e47a838d538a0cb08b914e8dacb50c9e996e91cd9e63aa1a8df0533a60289ac23c577340e6bb490676a1f1c23fc8ca6f918049f05425f7d0d240f1562f8e05ab891bff85ce6fe67b7f265e1903d2e44d3c9a030cf1b61d62ac6cb6ea29283319b65cd3d1ed99ee9b00fa0bcef7f83076494857a1aabb73d8c8dab2bc97452e2a10a1d158fec1bd1babf8a836dbc0924759b67a1168ddea7ad06b73e05390e8c92b79703e6def143f28365b62e3c1e0416281da2b8f3c9b3adcc2398b0a7a4a75d9617a8fa5a27a5e9123056b1adf2fee36342c98329970c01b0e9271b4012653d4355ee0552f0809c288fc352b8b71bb2b2adfb224fe3c3fee3f6c9c236781fa8f452c1a3da1aa50fd8072aec2af1fc479ead2505224c0e7cdb00cf9712e282d964a6202fb6732c77bc425620b1a36a5f60bdcab24b99a5a453c5882783a1fd8aeaab85865842dd03ee87b3b4b7713b105ea4618ac3563234e2c2d2a249f7bc63e75ab93663b324ebca3775ce4bd3c11e40754d45fa24be8fecf73240d0208a446324c7f5e86c2a00a735a9c8e21dacfa4acc9673f33bdab6cd97cae66492989a4cd1f0a2431e58098515a1068a1bb703539672337e9b7b25ec0747737630c6e2b259967efd4b77d44d2a92621a25865b3900657cab83bd399557bbe6711c0fb0acadeb930f7a42feefb9e21efded7a2329fb1a00fb0288e463824882efc21cbcf93f671aa687e990f23191ce25f9a4d0d5f7eee8292bcd4fc031a1b9cbb0774cd2b8a792bb8d81fb55485873b875183e5f91ebfe9f1de1d8da605fa615e3b372b6d5dda3e70451c252c39d4605fed1b0f3bcd993005a2c398c6d0efb2ffb421cc4424563dfb530c7aef1292627ee24226c6bdfd1ace879a94f379bce15e2bc50071bda35c0beed005b269478aa892aa8f605c5556668fa685f7212ba0523881d261005b245b6301cbb132a45b636bc5c8d50876738073908aef2e92dbe881853e0b9785630679571d900bce84b8fb6459efe8c6d6227a2f5be9b8a0e274e6a57b143f3e52a8a3a1b36916575a00c0a35e238e3ff4bedd51fc1a80c7fb01e11d04d4898ca07fa9d641695cbfc0b7bb94595b05fe9fec182ab259ed771f4027a3a892bef38142c92eff302e5b4a3ac9c1a95d339ccc253766ebb29b6595d32d1190e23cebc5338cf91b4f4dd9c92bcc677d392690519712713cac72f3df2161f4e22e4c153ec8dee26b4918bf30b507460a93cc3d6cad0c40eadf6808ba37e80d93e31904f568edde2130984a123d19d58b59f02915942a54364e8540560fa6d9aa95025d3adcad447d05a09b665f02d8c2e319ed1f66f8b2e2b11392574e8d83405cff9a54b74fd2da9ed6e0497a530078d8d7832c59e37c813f6f4da8da2cabe89ed55647de9f912af9cad9100f4f1321cb856191e57051196aa9b54c0061c834be101a4d700ec16528155c16388913860ded7c62500b6098be0589ae1ceae8de53123dae708cbd9c8a88e96472e009737a1ec6464fcc28fe1983d8abc58f5fdd9353065bdc79ff750beee71b2cd45fdd3251b223a95403726ce4635c5fd20764ebee9e2b7e725afa457513bddae2d8468a907ebe1cddf204c831422bcb07c36d046cc0512e1861adfe67af02477513763bc8bb4de4f2ae3e04a201c9af37c4b8bed3e8200297795510a0f166b4bf301b8020615120a8ea242ee1da6ab60bc6373cb32da51fb3ce051013a7e20c519cf821b7d1c36ca1a0f9854d52f799b0454b5da006bf3b83c0853995887f6443a7e545b4c29495ee0ba8bb50f403ca75b35f61bfc0948c9e033afba4edbeb576322d49035e4cb60d113b40370cc87a35328e1f26f8dc18cd70cfbbe0abf6a81f1b0ec1760e683c2bdfcfa11bd40c2eca814f4b4195819a985203b41fbc98377f1a11fe498e21485ef200af052d2d8b7c40c87c8784e0799bbbdeab5de79328f8803f8d942a24e83e190ea1a0912fc950220ec17daf0d5928d2e8e2de07f2e076f778b1ff6a955f2d1602aa5cc1dfd30c3b70d0a7f74d2826c6792a6e211535bf946a4f50c684ffa188600acf10f00886014d881610f3c6b3df2c8a5a265dd2c45a7ff7482790ad62542af58fb8b339b82fdc171b28269acb4108e886842f7121ae47cc9fc472f4536506478e182201dc3e246496513c05920a3cdf6a8c3b47d794420671e592b93cc258b73e9a5d6901607523af77118d2b7e2294e2d6ab989cc80754359177bff28ea4341483e3b57779c4b80f5a041ff07ce5fcd9bb9a2ae1b624f6aa544e11c5c55f7dd8aaf1321fd9aa92e7640038545b24f0240d7257de4f2f4b45a08cb26eac54fbe52e2a0267256c1be98f6e7a6eaa3eaa5794d21e19b3c6341bab8871dcbaa5ad1b32916f152f7d5baea0c0a9feb50745a268ddd70a3c1f73e4bd7ff1362d55147c2a3926f92a4815db9c9eb1610fd357702d3e74cfa28889a6f3f38caa7962f5670a3fecaf725d0048036cc1b83b6f84aaaf44d5e9cf6ca300d393b03c517c4c08aef9924e26e7d02e9386fcef14c4ae018c91982f1944a7e5127acb6681bf4401d975fc666314642efbb7793b047d45b3dace5cbae92cf46b1e97428653ec23c06f208f1a4ef13cf8aab69e3bbd257e4e27dba671f5e128a4b47c1e876d192209c353f721ce48a55374b98a697036105457ce1e8ff732d5d74b10d1e68235647a86ad785262ecbeac5342b20025229dc4e2735552f37da064f36a573e0913993afbb98938dd4c7473cf71b0384a630c3d4ec85d486b69525095815f4797375f97a045fdefb535c683e5ad08cfe3c47a0b75792b35b6ad427f71e0106e2229a3d83aa9f22ae155bd75f84151f5e24a0c2352dab48a3d577cf0bdeda6d7cb8712e48a1d3e25b677ea3742f15953e39ab5621f869ea1896f6536c472d79b2369e70f98ceff2065cec129d1b389417b2deb536bfb04dcd088d04189d9765182e11e4354930af9a80361d397c6cf92f6d7427f2bff27f8ba94accfaa5e84384e45954d02ddec3a6504ef07a1c45f4268660d2645b258d2734d885acde6e204a8412f7d7fe25a0c3ae57bcaa747e6c8aa9225a71fecde5da8cb98ae17192df28ae7a6db30ba2bb1fa92bc051a1995e8d1c3d98c474af51a6ef010fc9ec1956400d1b6908a5c5dcd5c408d9b3e20807497ca37247f17e1cfdcb7d8e44556b32a898eb0d2782bfbb90d68e41147ba2170536329f531930daaecd543012cc48752177aaec84110dad6809c969a0ab6968e323e658b64538ff43c5af121e4f66399092acf200a25d932ff59a43dcd2da420c5ee72d4f52ec56e1904afdd7a87efe2431635a7ebd7d81ec5cb836eff8d4b22634ebf11d1438f91bee07fb1c30031d8da24c10b1f6b66d48c638d48e67af9887f7e59985698c2c1bfe48ef0281115a153d84c6e21bcff24231662374f7202c00ac6bff57307432222bcde5d86c73597deb83cdfd73bf2f3961308d2f4eb625b46d16b88ab83264a2861f3291a4929636885286d79bf9f45395462169ff6bd53e898f54509b38cf24570c6dd89601a5028cbe528a85639bf8ff0a53995cdbf18bb8fb9d9c9abf96699cdb4e7b067f82b8e34fbb7f095c98ffca8afd10c29b1b217a6d91e8417c1f5fba6725bbe3895db33948763429a69526454262779520cf05ffd78a07fa8a8997174a8d7b2fc34d6b39c6cafed1a6032546b2f1de727b0385932851a133acbf694ec0fc4ec9565958f480b698c81431924924c8075e56a52d00327c80ec2e2193cabcc2810b7bbf0b46e5bf39b1ddf653195a5aefa3ee4081a218e582349bec13c5b46ad910a7d036f0d2c608d9ac8feab9b1ce781818404bfba61f81394d4367bc8bc61157d70ec7d878e63982905418ab0692e4c5f7b3ab76fd588231ed030e1003665fce7c9c2440c421d28381098730341048d10df3dabf079eaa304eace1e3fe012408a8f29a844371f2546350d8787b435ccd2d014aca1c78bc6cbad243829972abe2acdcea7b9a88b50a90f0c9204ca3a3f9b54305e15251d2f4e10ee00105140cae798342b731c20e6cc34bb3318e4204cdc37d1219c52bc53e32e6bf45c1d6ef7bbe8e72ef9c5aedf5f175380a7e0a7b76ee2daf2633ffb1fb5d61a2184904df6de7b932de50e8b09f50879093a76447829c34abad4df71a1b6bdfbee7c3ce553cb49a485c4d6ac23a5dd58e7d27295dfa695d2c26b52db287b55a0c24b4ba11dd5d3c70a1cc147820fcf43e0a5edcdf3f8a95d5611f2d05a92c2c753e9b1d4e381b492f4159e02b9b582f156cddd0ade4a83cd3945c05f9af5a7813e699f4b2d3ed3a8c33c092df3e47aa6b33aad33061fe11a186637994da6042b5ad57ec587a7dae4c7f311ae41a789aad475d94d66b2b48d89dcf86815c12f55871612d5e5f391119c3a0fe91647e95ca93918ef7602eebeb614c00ba73b8fa8575a3ec233e28e9eb1dae384946766867c0821bcbbce92df380d65b80bb84e8b340839c2853cf2e31ae03a2dd2904492a4ddaa77fd94ff68521ef41ed2a4bc89963d1569b187b4ec65d8652d8d8692acb29b0cfcd46828c9aa8ddb0c15a9cd4458c729d650e41ee03a2dd600c59d9556dae2df774cd354a7572c4a7e529cbeea58ad187dadf49556a230abd66318f68a5ea66f6573bc5bbfe396aa53f7fcd6b7ec2c036f33e8cc269c52b1d38b321057a71bcbb4c7caf4ad761bc1cccdac4cdfead22c3be9938267503b49bb89b2963ca8b53a6b8297e9da5bdb6dd2b6acab8defecc79cc8f7d24a3974dc7877658e77a5fc7437b66f46c7d5c48dd79f0faeb1a9e05171b7fee38a7dd837c5ddfa327d9fcdf16e05dee1906dd3759795e9cb402e7cce909c1ed7c791325c2347a8b8f559d7d5707349d769a1869a4bc475b6aa26b95f5a084228d3577e93e9cb3a7c63bfbec9f46415518a76abe227c8ca742389ff1c141fd2b2a712edc4ac4cdfea17fc68eea97832bb595606deca6e3355738d845a276d899f145c637ad73bd98dff7ae2a0be67a18c7d302f2d3ce941b6bdbcbc88ee494d569a0e8fa8eec6777b52f00c2992e12c2cc2dde9687821bd6071fb431851069a961868a8b91de35e2e5b4f0a9e01df96b48e67c4ce69125b13908267f061ded4076ea82dc136431863a4674ae5bb80e82b5031c59cbe7022909997dff42d93d12a2290c9ee00dc0cd856c6ab38d3fa2e0878ed0f190c048ce816f8800b8580b77e93b9eb2e743193e670e640518afde1e6707f78404c11ea6762a445448e4a55ee0cf9012f2f0a50c0010e308001c48861125304f8aa995c3145a0947efa1543692da0ee021953044ae9d4640ca515614a51b9d6cfdc3a2b40a51501b7e4e670b2a29fa1b9d2222287b3b9d4258199cbf67240f44dec6572e9756bfdd3b6573f5dde1a44ad94b224105d19d17d175e5a674d60fa344331c4c1b932af00557eb25d4d32c249dba619c82a98a6699ace9adc80fbc31f62f8128a6086c69a8991f605326603ee0f31fc1c55f0f1509d132287fb0333f363d4f813ac9ad42298a1b9cc7f98b9932581bc3cf19df5f6304d30e7348114dce95369c9b315cfa14e878756470d2d24c12666fa4c8c8c26b1bb5bd6701241f79ecbf4cce384702217c4cb229b9ac47d4575ce654ed932f574df6ff52ad05da7e6e9f5e445b7b0186eaebb035527a33a2250b00ffec13554d00f3815fa1938157a47b121bb56e85486acef3c2fa106d9a5e71f4e08be94b570e9c656b8945a0c844b7dcc39abae4d75cb38c508e1d48c641068157a4a9b5ec80f1f4da2d7c09079c005419dceb52e4ccfd1b44960bfee62fa7152f641698f26d14fed0c593cd38be890517aec331f41cb8e20fc657514015a0d5cc7ac8ecbea704f65ce79aa59f3d59a16a5d6034d7a344ec79a34dd12a71dd1cb534a27ba750ffa48e50fe7b4b07bdcd114fb08d5c9d8200edf11f56a1e47e34c6a524da2f4f5d9da55280d1910da40b67fcb6cd3d849e99be6d1679405f254e8619a690cfd43424fb18bf89029b9747b492e3d1cf2bc30d22dd4693dbd4e4d4e29f54c5804de5c3ae9bbb9f4959a4f85fe69d953a1879ae8a9d09b6893ce3a7f69f31f8fe65e367f63de8b59866c13510ca3306ad679012fe478417331152cb954dd668a1c7ba5300c135d27041704355f313bb56da6c8a5aa3bab88eb54a5aeb345c465ad4d245ae9167a4ba3a7d194de3d7af7281de2d2b7109c10f323ea1555a94af5e9b3e7f24e2f7a2ef0f47f2ef1f44e06b5258863d5dc210f4a2ec24316830484281a31b5a007d388424c13f2a185ea64e4dc290bb91eefd655ef66f77d7242c0fb4ec47bef04702e0e36e03e06dc17c47dcfe43e00dc67d94d64a4b216c6bdf36f9959f408e77c56e0684632f89c17979f2bc3e5e7905cbf1e5f9048111ed2e35ed60ed1c2903dcb86121d7041bc1787bcf7624e6deb89ba392e989979729fd84ddccccc3c396747fdda3dd78e63cd9d5cbb5caf2ebbb3a364a2995a109a967d4b4269c85ae7e160d527cc364e9c7a629ce959b4dbeca94367c85c8c8b111dc62b08974018df45f4e36b8c81a3edb586302699a6254d4c44da857d94c18b57d32d930a215674a4792e289f40d773c13e659f4ea6e863127dbe9160684ca0d893394db2ccc2e920ede3d1324ccbd8c7ebee49e9e3b6acb6a69ad8497ac7b6ce4e770f19dff10238d954dd69c954d9b7d397b6a72aa38c30d65c33b3331dc08b9664d32184104238279c304208219c7114a58c324231c421977a9d46a0915330890b823adc91a7e4cea55eaca9e91ecf051a792ad4df42ec64390423b46f48b432a091e7f26c0bb13513031d136d87ce90bd9f5f0cf509c873a999a7ac8881c5a50e874cf7e1034845f5782a14f55aeb057074700c768e611733a9ed15b9d4331f59e50ae31ecf856b322ac9dd5e1697fa16e3526f0875f7843c15eaa3e995ad4ebde7ac5665555cc08943aa1d911db2fe4549447ee4f832ed443b32329ae071340e9c5ef7112adfc9d82e0136c943f63ee7cbdee31ed5c99833cb442492dd92b8eeeebe1cf05b13d79500c68ddf5c892fa59452da1cf1d0be491619b2bbdd5996adb339e0379e9fe0f9f33a37d9e688b68a79685d57ce4d2a6a0c1940844e15709de8ba3bcb9672d46f73babb140bde75ccc4bc4f1a0ade567dfe5944c8cbbff7ce6326e6591ef1d2da1cf5f3b4d2dcad135a27de794c3c9dc77be76179ccc41db0a110133f644c34f15c98a0a1a1a18979114e27b92625e14cfa906dcee630ce750faa33f143b6b91dd73aba855d66bfbfc88405f8466bd287ccc5af34c93d3a19d3734316930bd1104e854f9dc91eb2cdd9189102c3f770ced7a811b1125ff39f4d7d1238566eb4a51c2578b78a79772716c8eb9889919f1a0a24b449b0c0051c439d92f23c6662a4e5414f599bc31d6aeeba24aa90a7d23a213fe57c2a6e9e873c0fcbc3b91dd30cec6906dcb35b9a5b022679c8a66f434c5f70823a0f4a5178eaee53c678ea4eccf39053ca3f1727ea79cc57ea939eb24e886278501e4578a74e9d1664a8b9eea4151ad75d67053920e16e435cf739499fece49e6bd2fbbddbb19c991a3a4146172f8b5b6badd5a2281af593e607e3ffcb06e09515c02d0c158089dd4401b01f0b00eb9e8ac766189db46bd7ae15acb0768b6aadd5568b1ebe52971b393639363936d5fa5551d70d9753b1b0bc1f2c34301ae5480d75cb54bd4a2dbb5375486aad20842548d1ee18a7b690d8fa130d2bfebaec46e34ea7d1f2cacaca8a5cc12c16cac2ac4c7737cbb402a5bc68c83f4b5978c67c979597646141b2524f69b362e9ee66e996eea9592696ee696261a1c162b195841f4e55732be6ee943912102b9f78c6f4e97d0a22247ab5a294ba8bd2aa02d1ead4c5c235e8998256f56a2e33d50d1942082194333a569e15a5ab57b8465f3e2a5e0d0bd790f45bf56a6efc3b535b5919aa31335fd75ba33159d0b2406dc3a151978f26a14f771faef07b7cb565e1191264a93de1834ea8ddd8e2d6361ad5b23c9c5b2baaaa2aeab22c2bcfd2eaa726312d7b1af5e0a4b3e724bd748ba7b2ac58c896524ae9a5692c5ca3521c1a0e8d998f43a301594633099128cb58b06fd395daadbee1d0ee75eb553b66a75544f5d2559d890987c6c2352a16295fcda558409c5285ac8644f594361dd36af66aa5babb4bcf61dd1485d123161234ce4718db96a8bfc768ab943951e6449913658d3ddd58cf3955c6c6be31927a49cd292fd337cef909e7fc46cd39678cf36c23f5b6a32cc6c738e3678c51d6cc2a227bb4a5f83e96d58f8da00fe89ad70a8e6a8abf2a05e37d9abb549c2ea5c5f864acaf4eb5eb53939f346a8a320b75cbe4b9982d8651ec5b758f700de9b196aae766ca96e267e5395f238561169bf198465f2fe1bcccaaf5ebba6c7579dd3a52bd562ad218638c54468871c80f92758a846e57d2d2ba3e4a2995e9a795b049e97ba04b3ab1293d10fb7cda0f175981507ea319258910c9a244dd234261212917a136acc88d9752f2b425b8527d2845dbce0a60f26c41d28eb0538f171149e9067aa4de4da9ea7c85c9b7950bb2156832993604a2eac330cdddf71e469908fc68d63d1a251bc61378720506af8c5eb172e14bb5ad5c4a29ccf215977abc62e5621486612b37567cc5153ca3c8159f06d9fc6024cea2cfce9a7557df9cf3692549cdf9de8cefdd94e731921bef1a47d5f3ea9ed11161dc79cc3d5807c6c94868b41b23b91047157b8a71be15aaa3cc8bc798df8fe71e71ce0dd25b9667de5aa93a1ef4899e950944d98f87d2fe71eb93ef69dddcc33ad43ad3e8439ac9611e47abedf989ca62769b17cbdb52dffae4272c8eeace3ead4c7b3a97d0273ff1e8e1ff04d79887559502c5a58fd6ca86a3baf3950a14179e9fe02778063cbd9b2c222823b9b1bbbb9b9f704ea5415ed47e40b8755ce6f279153f6ba55af5eaacc167d7ab95ce39674b47cd4967654a62d562947e7b8fdf7bd396e8e51f333b66c7dc4a4ab33bc64e7237c8dd3af190b6e74d6f9a3d379eb302d2f617fde8a7cdae6e9e33b38aa87f9885446631bb351fe33a59cc6e1311f101b9954af9de7befc9091ff7ab43ed7d4e69f110be5bfabaaff4ade273d17359992bcf4e2cbb2d5755256de97d1e5a7093794d6de93d9ecf5c8138cdd9afaab375c49c56e6e153aa533844d36d954de66d0dc5859fd4a51193dda69b792a1211752e8557c62be77465b453934ec2c046ea145267855aa5966559f3b22c4ad9baae43eb0cfa654153c8e51a78e3704056dddabebbbbbb9b7ebea76a62a25b9e8c333afa6eeaf3247237cf77dc86efd04dd38ae6e79942e014d28e7294f51ebfc7eff17bfc1ebfc7efb1c5a798628a233333b3075a5df3de0512cd996522d14f72d3c6d6ac7704d7e8b365091172e555ea7ba07cd7bc3f51762be75c1ecdf6b242bac86e22510d8c5ff6358f40d5428206008f26867d34a314bb89ee0d18769ba2074fec76131bb2b05f1ef72fcac8ad1446dadd3d3d0cfb2c0ff3207f7336cfe5a4b81c0bb3a869514a29a59452b6045fa78d4c4c9c764d9b9999395e1a2b3373f3cacacb8b356796894494d23b1a798675782db9754d4ecd9b2e5a727be7e565658544fa45229b1a7ac578ad57913a7422086fe6cc3291e82791acc9a2afec4be419f1f24eca29e4f24b615b040f4f1a89f3c96c2871a35b26750fd5e6a9d4e2c3acf79e2c83f51e175c43deb2ae495e58cfca64175ce3559627f3489c0b99f93db6cf96ac1765195e5bf2467221bd90d68bf4d1923837de4d69a5945276216f2417f23d89433fa7e71df3c82e7806851e2a2f4b4a0fac26cdad966559f559d985e42274bdd2ea5bfbc81b97853b6597142e0b7c4ce329a595d6bb801b0e87830387c3d970f0bb56b4acec42be3e8ae14ed3651738ac57d5d25092c9bccbd6e329ae5bdc8d8a419b2e08cb6e382afb8feca25ad985bca1288973a9eca24172e8864b2abcb9151b028563a577ef9d53cf7f5a7d6b111412bd6b464723e9c3bc2e59eec15ffd0b5eb7b80696754f697d5ef0e6c250bbb08ff7deb39856dfeb7e481a7a51c2bee3c2aef53d245ce39d21172d6d0936f6076fe235e1cd8defeeee8df6d5dfe8db625c7e2a2d9e73378cf3b9b1270fbf7ddc9cd9f4ae5b7fdf3e13b0e0af3f6d93168376649d1fbf02f35c9800d96d9e844cde7b87dc5262c72c24aafbdefc09d9130bb26d652008e5256937b62c24aa176f621f5bd0c776651141e1925b2fcbd2dcbdaecbc2de2bccf368d4533494c3d044cf34ebafdee83757bac5b554a77ee34dd2c248278293c4aacbebba2e6c9bbfbe4d7b7d5155d7b7fa78c77cbd32b3a8522b032fd49933cbaeeb882a0f7f695beb5c6923136f92dbf578fa94cbcac06bbdfad63a5993ae8b50b46915515fb2ecc6d242a2bab555ae4fd1c774fd621f978cef2fb846a56c7fc133e2a9bb14de5c9652cafe62023500d45063bdfb55dd4d0821105d920de19ca0fcfc24c3b76d094aadebb3db34a3e3c94f0f08a6df711ff5b7756f93a16ca94f29d8ef51946b50b24fa98d3c039ee7a7f7fedee127aef13e515611d79fa557e419f3c15fd78476bb7cafb1e3a59abbad3ded96364f69f5308fe12b16ea96e90ece73ad9555bdb37cbc0c12d2469e5155761423d7909ff8f23719bed4e9ab0c4f94ddf84579fa39e37defef4d37421b79c6342bb676706e75e51b0890cb80ebb4c8c9b93936b7eadc8a91ba05bbdb2a4dc675cfe5130f92daa354422a0ff3a44cb756aadf21733c87b4b2a5ea155ea67abdce5bdf7a2bd6b9f0cc966fe5d2062d8d3301a4096ed7a195ff3c5db9efce3585bdedb6322d66335b6a8b9d5af6b273a26c891e7bc4a2b3327dafd3697339aeaad44ed465c1486f455885444d621d76d25c0ecc8370e6e2ea08960d25982eb163b343a90d256c2c6103f3a866d95882f9d948b6a1848d259ecddbb96c6309e78212ddce8d9bcb8930220d455bc2c689c634547d137a31e13c2efa862fb4f1369488dbb38194cd8d87d82314dd0b8675228b6233fb44300eba732e29f7c08f34f75234e754606822cd3914cd0a7dece6965c07e5e3355919081d7fbad1561978a91c78e797e01ad596a8c74b59c953b6c46c97e01953daedd95cf825780684f444e3188e71391386a6a16827f555279a8b715611f2c6a47ab495c4c99cf37f11908f274368517b79efbd373fedb3598287801ab486eaaa63c69899e185e4b2484c2df2138ca45b26f64bc3ecf604126624d331f313dd62c53be62835772d4dfebd62f05570c9a4e4ed7412bed142cb489a04374612cf4822c0976f51f17d6e59b6da9c4b76cbdae2c7ca2c1a4a32ca6e38aa63f4932ca2343f59eaeebab3d8af63f05ab6749d9a0065f9090b09689f885cd578a8c51810c2d09d8f318220744bf1f4f58134cfabb35be8734b93af22c300e89e3f90e6aa568920ed5611743275a94d6d0bddea52543c11dc7f8c849f58b13abbc29c3a538b43f8c89c9375260fe123131fe1217c44c431d6737933097c8475f888cc3c5acde465f62eb3bfc73a7c8412429f01c9fd755a980188b49b8e2b0fb5f8c8333339de9544c8770e6691982c22a2140fe63d8b88eb9876317f72374277e11f64cd4d47d4fbaa3c41111101e1291bd23806f4f164d6eb890fb2d23cbcef482e8cebb458c3cdad5db17504bc59b74c0babd0ab96c6a734ca5611f49174a389365b251e4513b54afc8926d2d88a003d4c8bb4ec28dae7279ae7261ae8ceb2d131a1c3f46348737385c6cb1059bf5d43cdc23c07e3676e9cecadae2d783ee29bc23361159655c73ec7b0eb309d61d9371010184d4e5044175f8472628279387461d7f99e0c7b523c299e1493a7e5116c460708f41110100602496c4405c8032b9383b42dbb333a3010f611100c34b2c204948140d64d4037b138039d848e594f9126d831cc9a3c115e9e5899be26761bc10cc86eecf9c763b70cb33e0a320a320a320a22bb90145a369bd1615d24fa645d348964f33bae1545a2ec5366d15b728a2815616589b42dbb333a325196890ef344d63d5ae9ba1361229147748fe5c13cbf2eca3c22eb338540d84766a27fa6d004fa605384817272d2cacb8591797e896c36a14c2793c9149a40d3679a98dd5ea8cb5f5ae419565529bbc5d339e374c2940b90f0e1f20caed3420d3ad4e62a7b7daa7f3e9f4ff5cfa7faa7b4e3560e7e3e55755dd54c223f339b62ad5ebdcfe792f968db435ac9fa609f4ff5d0e7a1ea0a1da631cbfac7e43af60df4ab7a8acc747d3e17945f36f4ead7517e7255199cbe5d329a5899be21bb8d6086b37b32bb615745f908cfa86c35817aa9dde0a71df5e564a54d77b7a7adf3118fa7c23cd83dec394c57fca9be65af144eef1a7af560a7af0f81348b89d48f87eb2dcb6e15d3f3113ec247f888a7631fde7bef82d2c4e4105af09649e419cfc48462138a4d2836a1d8e430cf84faa595aa4965627299fca2aeea323953186326c7ce33a35ec913c72106f1873d9c31c6159f5cafb71bf35d87401fbe2c1b6334615a85b6b9fdde7befa395765cceb24358c157d91c0539f53ecfaa2aabaaec302fa3fec9ac2ca3fec9fea1b8faf0abe715f594f8f9565596c2aa8fdd463093d9cdb215351f84675074daedd94cc2a036ec6eabab99032dcbb2ce3956b52cceb12ccbb2a6c9aaa6eb569d769379599c1b13c9344cb3a65b293ae3115166b504c37b5d4d3a51e9289da6191dce4d229452eaa615ce393ae77fcad2fe7f68c54e3c16c824bb2cfaf19c602093cca2a28732d18927f33cfbc75e009fd089282546004e3240010820630056d3ec05100000c418a5c010a19c9884401f4f865d96a2368ab2b72506ebbdf8de93efddb27bce49ca7e9772644589f608c89b2494721bbda845f958db6e4cad572debfddad7dbc29e61575b95a5941565184b25d5c9d8e4902b1fe37c71aa26a7e88c804c37cd382335aa99736e9bb555dddab4d3dd2625575e29491a4717e9faf74edb6e2949a6c72f489051107931c403849275a0942d25948f75ec1631ebd5f58fe6c91c13b12a2b33ddf8884c131fe1237c848fbc19aca118aa93e15c7c6e92da96f5ad264739237411c6cb4ff67db20bba6137ecd449e6a4ddac539b8fed198a1180ca6e2f77fb6d945025cf360fe65c7913bbb1911bb21b34c23817e7cad0419f76e301dcde39171937b9732e0438ca9d7329c061dc3917037c74e75c4807c09d7351b900b4ab68cea99034e7540ca039a752008d009a0c6d009a732a34d66af6767b11800d80dd56006063d88d34b229763b8c13bb65d26e32f186401fdbf3a2a124c36ca52c2b13af7ca5a56a29ea4dd196f897d9271b79c6cbd1baea4839c2a9463574e74eafee46b4cd0df5a699eaa9d4e254e465afaa5274aa8f8054232b4a9647a6e88c80700d792aee163aac3c9e438b3d20bb356466666666b615f4bc5b551c5951bd149d1190917cd53b8f82c05797e90ac05752db463537ba2ce6cc3291e834f2a50504692a7a0fad5292409af7f2b2b24222fd2251c35190471fa722293a232055b5c518d55c8ad1ed2585741439650c1b2ab194524a91ddfef8c44a28e508e7d6f7deabec28c808c8950c318ddea35d5bd36c538a4e671195d018d12d0e833459641195641acf4b69a594a320ef103eca51104ea9ee24f940e33215792ad3776e74725e8cace0dce91b691a05c1d145ba089592e4522c95f0744c8329f25c5e5e565648a4ffbd225de4cac72925c98d1f05e11ad528488a0e458d6a2e9552ca51109e11290c16c01ce86f301a2826d7096b17a5924a2aa9a4dba36207a554bee9bb3e293e94e2c6243f7b554aacda9275aa4abb4d333ae4e994a7534e17a573cae953b7eb74bea24c594a299595a5205ba51d51af9f522291234fa594a1cffaeba297b624dfb4d69005514aa90455b55237b75a1425a594525217a6657f9ae89386726872aacd7fb4ea308fe935a5e0cb96e4add75f405c29b8c6f478b2e702efb1f3b624e9abb4e4ab86843feb67c5d54528da89963d15eb269a7b139b8f508a7aebd53ba7fa641151d15bab9452fe52534e33577f70d059d41fb7625d31106fad9ab5a664a1d40a83a2a09cd45b2214eba2fa030546b5aab3a5faaea1ae3e205cfbe4dbfbf17edc780ba556ebd937bde94daf288e5267c16a5d1e26fbfcb81b8c1f0c639232ba07868d012346c5f5c634b2392976cb60882c4bd3b585ee81a45d920042870ff7e528e124348ce4e86c6ec7ed0c41e3c25c8065a016641e22783e63f880a8f02613a010e80f211316989c7caa38f9c4a3bc8080bc6051018145cb20d231ace8101513a572cf855ff88557483b4c8456906d2f1df8cb4530be906d6e679b2d5b63314563d144da8aa6e2c19051c6944f18b2cded4c266c5e919d9d9d1d6793813354d72d20e09a5b724dca0c10226d0c847b308d119c1b9b259d835f6c08c1a02c6c707ffa30a9f74932a4c87381e767c43c827a99b21092f38a02dc8c68ffe04351649b33f2e8f38820c988b647b819efcfbe7c608d2fa09b1797ac5578850ad214fce31a3152396803ca03a47f16869bf1a89d3da2c27d771f9d6c7337324dd818c1373733f4630a79136fe0cd0d0d7838a10d372419cc822ce00c8921babce3bdd7ec5ebcb6995b430b49b08999e11ddcac04fe64c1c60b1b0e831736d188112336e69c73259b73ce25d9e68c349c18e6b9c8bf1bf15ce2d4a47849e106373827cab83b50b58103b5d908597643348d72908958d0e366a11930b89febb4888318ee969dfd40732bd6f39660222db9a19384910a2fe0bcd8438f1d3b9c010b254062e00fee0a10ee26a2e26ea41fdcedc5077773373db89b335273210fe690e40863f0811a7e78010c7007406c01270a353c74e2202466c60a19c4600d72c8c210a2c08798feca737140164cb8828a9c1a306108317d98e7e2b2480213867421061af0200e31fd249e4b0370e690072c6001061e57c4f46f3c9713242982199450410728d82066016668c10ac0608517841c89699a1ab0a1f298020b7d40430de620071b0401ea8006150f78140951c105e6023f5c4970411772a0c8208410562c8021b0e10311f480033a08d98153bc81055317d04007287ee7c590374494ebb61892852147ac232c794ec417fc0b23a0ebb470c313575eb7c50ad0206326c0096e3e8639b8a49e89a20f3588c3139840042531dd5ce4478c3ba02e60430b824c3d842e4c95138e0061f0890f52204245c1092c48a18ae9c4c4872d64b006eaf270dfdb62055fd09b2d64a0c5c5aedb420660b8db23139c1093c7f3aafb1e1a7e6be59efddea3a6a99d13629a64047ed93a17c47b6bbf273778af708a3312018f609a3bc5799eb2ceca591096005238e9a4df22c7c8fc4967e4182b8cd2cd2b34855ae184fc4acfb175ee21a122a5749a788a16ceaef4add14fd3ca95f255ad1ee35df50d58d6bd95a90bd051d43c45e79dfb085ce8357c6fea8f60e6be379d9a93faa43ea94f869714457d4ed4e690f023988980a31cab505db760539fa51342462744844e08f89c10af9d101d3fd996e2dfe361bad497af5193324608a7e93d7e87dd7756e92398b96da72907b67b4208fbd49b7a85da564d337bf6ebdbbbccfede2fbd57e122c699e57869638c18dba955e62d6db38aa8eeb42e68bdad0850b768ada89de27c73be4f32c6279af46467154c4f359e29cd2eb5f2360601949055eeef2eda8f217bef34de9ce83451ca73b6caf44b736fabcf2c3b3569a23e69f212c6e8966a3759750b94d24ef2512b8114627ea377b3275875eca2ce3cb4e009363195b7d0831076626a7b010b3cecc4d477e30220f888a953d59a13030e919c980a6f728cc4d4a8e343484c95556bfc041688a013536790214284c4545ab5c641a6f0e326a65278d0c3196a626abd830c68626af5052700e126a65a794092b3862038e811533124b44127a6665a0cb1424e4cf564810b3631f553b5e6bcb8998226a6829c165f6c01276687b3f9820b45980d40d440c36f48034d4d4c3da95ae32d7440849d988a52b5e69a015b75793603f85554b5e6eca0879d9a980a0346ca1e84a0849a981dcc6f8b2f906c2949dc9ce634cda9e15ffca4c1c7865372dbd81c86c1e54c935d420c48e6bc1b433127cb4f0069244f0a32f01132b4ce9c93aad7ab463dad3e0b4cd32f7b91ea75bd08774bd7e3294b630ed9e888ebf157a5286de6520d87e8f69f83da4ce5ce030d29e504a6cf1731cddca76def0ddfe3cc7d7de13403998d70b4e69c73e64a6d939fe4ccb52c3ca30ff366203318a4e4ee9b514d93e4a8a649324e31c2a74c2949ea08488ace2808cf98a0803e608f2689609a373759f328c84dd60f2699baba4b5578aa82b7e0f3d139345e562aad52578081c015229c627c36a1132f25949406a9c944f808e49c0b2f2584d7263dd122eb4ffc28a1d40236dc82d4c403d224f98034493eca4ea2fae9956c244f8aa86dccfda2ad502756b0818140b7307c40ac90f5b739ab2cc2806ff0049b98429a24af9c429ac472c736032b1c3bdd542ada6d42f17c5e2bebceb998fcc2ee5c16f26837dee46c5e5e565648a45f14e5e434e6076f6c9a34591a4a3297a3c3c2c833a669c7754d3ad922eb6f2ee746073c70f5c443ce0322815427c34db74e2554f284099d9311c94af5b07aa5dea2d349ba05b6924afe5d1a914664196495a253ed280864db5e344e1b699cf6c2088744312e83d4469450a7510d16190e918c6f1612c5b80cd228c8888a0b3b67cb7a07270bdd8b6e89d148b2ce190599e01458c029eefb2848fdd64fe1ad73ee1b05494972273bc99caa868a846d86847aca66b148b68944a225504de8609ac82df154f6f7eecea8e9188b2615b1e1226cd32d946d4e90c09f70daf8848cde15814bc838068cd38a1bb94811510c1263d1840e915bc233a285d0081769e281de3645951136f2399f8b3cebe122f7c5ccf29b78d9465a42e592385d5a6861861e1701b7623b3144acd396641bcab22454d5215b4a9b4dc88cb879cf72f78aac240fef46ba150908ea43740b5579c0e9e0a828bee421314417c5385320090dd850e2c69350272718418124346043891b57647c8da040121ab0a1c40dd2151941011b3148403c7743e2233ce4c8345d73e2234ca4d6a16e40dc6a52cc7242f0090f323e5b19275d46b790ba25f2890fea542dc39f40218b775d9dd4647cdf7b7ffc77f73ec4fbdf65bc9055ada4ec66f654445374d2da39391bda11093f587eb0fc60f9c192fd6081d60f4a29b590702b8ee507d532c7f2c3ad38961f593896898bba0d7199c66516c9c233e02bbe86442864a2e2d5f4147ca75d99f6fdb83c979fd8677dcfe9a39068cec3d0685c886252cd53ebf3232d0586283bc9e2c287404d1dfc74ab2dd17a59c712cf52ab65b12cb52508a939f9d637ba0846ca484bd1606432226522f8dca3bb65dcd8dda218f7bdf7bae70f961f2c3f587eb0fc6031695018429f8f941f2ba5b41b12d30eac91b2a1e828a69dd0a5168a62da9976604d4781c1f816822de4ce77145d73e79d9bd36e32b0c77bc6ce06c87e3c8f6e240cb66082348f0fbd6452d2504c3b4d82dbb46355d5b403806f5900be4d013cda8dfa27c6e33633d03d02b0ae55b2bf56e918768e2c8c771a31bb85328c3ee512dd3997d14f465a8ae61c0ccd39156a1d907b75cdbd6e62b7ac85dc4b64e35d6d431fd1bdac876828c940f29ecb5eff7c3cf71105d7b82edb51cc40bb73a3e019f1991619098470aebcf08c2078b9a568b32a605437a25ba205e214689715d22f12c5ea155622238ad0b8c7c76e248f15b1c52eadded2a8b3cdebaaaad8f5155fe306c4b672e38b6dd3366dd336f3d166a20e35e93d74abb6b91baa19b96feedc28764e1a060ce0a4653370c22e5dce74cc22e1727c480d2ae16e748b3ccc8e69999439ef6e9a7ea35ba08f2b35c7d3b4d24b4cb6d25f58ad3393929d243ad38d0eae11a8a42d98643dc9d4880000800001011315000030100c07c482e18838d2242da40f1480108ca24c6e5219e86192e49032c6184200c00000008000a0499800d2c3730312345a41b15206bdacb84e2b1f029f9d8e502d16e8f9e56813233a05d7e6f9c8d82ba6c3e017cb304a39141e336b391e3ddd9753d16ac99b135d53d35460e5c9d4d87b49be59f3cf10ed73be8c02e28ca0009158e6ca59f306c35e552500df3a93e1c977f46aa097b1a5348ae8a5e15e4a59949d7195efba0dd2cb502fe35239603ae269b8975ed2594ab2ef2d008884cd6708c21b7349537e83bd1c95ea4ef8508c587121c40d06bda614777b35ece57c29eb573b2c5e39897c65f0be5698e40cf11f4ba729757a4f707b57fe60cc5f42ac8155b70a1bcd4f752e784364612e9dbd2ee8d85b85346723e0c502221ecd1a6545dcc4740916040c75e432cc1fa2a228b470daca363049e2b5eda6fe879a78d3d6a3fbc1f772b2e3fb96440008a3a1e05798919dfc836ec0dbf9099c5f7304ccd142332e09710fbe421ee299b6b2a787e60fe0b62745cd66ded1553cf41f83ead56b0085dc86fccbe95a63f976d03e45f5507290051ea7a0d17d6f510b7137c179850bcf9744392e16f609f4f113e7141b2825be0f6e829c0e67d2815a1fb71f4c3ee57ef1363fec21af9ee9d7a7b6d93a30e144dd6a10435c921a13e479a70816f50b96d948fbfdd0cad29629c63fbb808a064ddbdf5f285252857c0103cf4bee02e3e05b67950c87a2b964cfebb9679fe16ae67807ac185d35eb265023b73ee520530cd95a3631b4bd85714d8561ca9b12607418649635443037306056badf3fc80a1d5e3c3c0078ba0e3d15fd830d039a2fcbbf9e7d065dc1c5f025fbb4045110b3b2e64faf077a995daa30a2f52860410493caf1dcf1a4b24c0f2fd148402567e9d823f9f392cb5db961b7ba388d1db9ca20289d2acb5e88b4ca0a881d2991ae4af7049156f359edf613591c5a28c7bec4d3b288a4d61a952cf63fda3c8104abe4893c2ceb4fc686df7cb84eca5422aee0c8fa1c05d50f2fceab26e40f8b6377951a2cb9e685760ffde5b4acf2fe30e3b506f89273b1dfdb8b2cfc03ce8bca3411943aba21d2045e22d41b7e5aa0722241431ca49a19f0a838fe78f4e4f0bf36fcacb4c416a46d7dfde6f65da9eeda75dceb65207ac21f8f8bfa61fe3b77e0a7493eb84190b88db1c52d340a04e0e25ac283a97f2c1b7da38d628323c35b96800c3baebe1380615ee94a0fc25f33e4b11332a53a01cb821c571da192c18775f599c7ac55dc161352378efe0869e2e10cffa43352cd755a583d4dd4188519a1f0495b647eed4bc186d94c371dfa188a1eb1a270d48c9c74efb4d43c21abfd81c3e981af146730ad2f8cb3bed16782e0f6608bc291bf6e8a58f35953fff4a149032b1aabd3688b405e0e5c3fa4bf3eb96b82f11fdef11189bc4e1331c4feef2b1ef1f467307b6fe095ae9b2755e5699579148032accc1eace3054df08fb56ec6b645ca7969382e45667f8d4372954896f0597ea72e32fe50145e8e18510798543664576976520555ccf44354df9154622a337427fa80c5e87a45350a18341ab2c459d9ddc171639e7d8f68c5d270a4a383210ea2eba3920708022f04a45507e3ce61341110aa9f30bb3707b0574b77bd27ac4c45ebd2c8b61a3a38b619e9b341faf3aaf399c3a9f212d899f9b7e2f534d9add4469b2d4397f9fcc2df99f8d799f5fac7bf69492a66143b80fb9616bd314cba11f48afed0edba3232e68e8d2654e0df4516a7563708b9ebbd10d82c95c8c6fb9498461f3d2788b6c8ad74f0991dece840e90c8ca46a2b7ff8d68d1d677ba7b2a66d72254b86cb1a32085e0569978c770c00683ea85c39c16c55ee0a3515d9205d1235f2e3ba75020a4da072d90618259b4d7a1e890e422efb3347f49c5e8e8239361b2477cd28fdb5f587d166b5266edd8212a32799f223b098268f14b9b7200cb1a85daa48ac8a3a71b9a75bcdd01f440feb3e3782f5ce66033418ff16bac6d312e97451f4747c996334c916b367156090431c4b8c2b2fb195f87f1e6cdc62e9c61122cecea36d525a24918ca0b7343756ba003ed99fafb9fe3cbefef7e92577c8e7a8c85d4733942deaee85588154a31fab1ab585f3c21115af0370eccc6c6fc6e146ebfb2b1f9a5e4737741cf39488af3744a43f4195bd5f81751919f4f66e505253d3e04db13c7ff0d63c163f94ba0517bbb3e38763a508fb4cadb14016e28a617072b3ae29b6a9bccb0f60f24370d93b3a0b6ee37ccbc89e3cafe9d451b4c7e7605930f74fbadc11f612e7d37f5a0db49dce6412738859d31f05f8209661263e7e54025df2030ecee406a058066334f82125c5802d9205d7354af750c9c109bfa4dc64e19751268b37bf527bc1906bfe9bc3d06bf3d8b14bf785554b3e46d68062de684c403f4adb71fe0bd69a27507af91a600a1ec38dccfae80295a8f3bfe4f707e300e7885c37ece307b775ce7f38d6a42e998411f4422ab2b2bd8c39ea86368432b41ef1e6c3b0aa2a6442b76a8afea7ff39ec1c3cb3f81e24c3ee05b46c55850828a1a8e269139d5fcf2d0ee87eadb8cbcaa3e9c67218c33bd048a66c2a3cb318ad97befab4cc05f10ee07f709c54c9f8782aafe31c65ebc5e590c4437cedec9a31d59afcec40f02ccd9f9e29125d747ed2cb669d3d5ba2414e19583b4854aaed797e51e6a543ab7fc63cb80897c30c4961ff42ca5df99d769fb69106937cf32018654bb3d24a3a8e2671fa130fa8d3ea44ee706f2f85d1319f93a5f075510c5d11793b9c88596802c48532cccc51abc5db62f942d97a18f20428fb7dd7fc9b44f85f3e026beae560246c11571579f0cb7da5dece975c8bd20fba98bd6cea45ab3e31a6abf5fd59a4f3fbae4108c0720d99b3e6b399e42d3ac95e2e52eff661b8905a17c150ba6e1f359edc0b2b2ef6e98ce0b7808329e33797f4562ba2cb85f3424afa7a1be43903d96a54700df5880870ccd76b970c9b06ae137ad74e4156fd40b53aae42cf87e9b7b1365d510b5a0b735d151e08ec28ab9c30378235f119eb2437b09e932d4e016ab76908d933da0aec442c204e436a8d48ff3521fa9a2bf3021ca717e0b019ec7fad46b3207bffa64cee6d83064633ebd431ab94adf8b14717dc2086faaf831bb0e6f25c05c811e53d1087f85c97bf250422572a9efe9fae2a2af9b709db20eec9f498f344422a77bb7f2fd0595e966f64609892e1880d675f0a0ba59006d55eb64600bdae4e503ae2a45ca9a196806256def0213130050c4d15e5a8823b9b5bc4509cef0f39c2e74cdfb5a953038f3bff437e456f8119ac619d45af52abfd48fbfc27497c1c2d73feb9c7edba0173ab8e2b47cd9665cda557b0dfacebbc4ea7032f2bf57f69694c91d64d787dfd0991956ee2be1a645e5f0b4b30148b3b01bc406b8551784a18c2efb3dc86af943fa3b40f78e046a6cecf5e0355a4ebfb90fa7b14244316d28f43c3b3ba143123281a61f822a484f79769dcbd1bd6c76e1ac8f4b5d8e2d439528d707f395c1ecc1a7715a6b431a0f6fd89b8aa0285801ac875a99989f3e2e7630c6914e8b082b4233a3636039949dc5c6cb574d3c5847f4590c821897d207a116f7e4f5c14846aa8ff8f186e47bd9a49c3d44c43515eb3f34ddbfa99bf462ed95f17a3496673bd525367fa8b70bf479ebe4b8847c4af3c799001a4304c0eb826607120e46d61bc52f1275161e2cc84fe91f48bb50ee3dee807373d20fa3a6c5a5a4b755fcf8f031d34c5af19905c962426b0f99072ac3fcaffd9b390335e242adac4fe9f60981daa5f3921fb0c8761169d05782e3343b4ab290f4289ea918a6f512f9b020e804f3a64b13b4c64db384924f591d52b773d28ac046a4b81df9d24d3ca3a23cb7499db77b4e339174cbfc628b6b46ece7eda2b026adaae926031f03d30dd64b475fa820c29cebf8f4c75bb0d94a73b0c96f8c40d15247f7491a7be9162c0aade681b0f2675951e43f1e496cca6e8ce236e1eeb535a58fc1075a399e692e36eea60eed8880765871c2b78697a233f7aa17a975df36dcb7c5bab1e905893c32a41dad72b8f09152d65e20bab56584448164c2478015161904c0191d7cced300c98b438b6f5c857c2207e066a3f5fc04fa07aff49c18e77e59248211845faaccea9263f58edfefaa4b511f98d2ac3e502315d39d0d6d67f72ccbca371c88e5f429ca63ec39548e20325d98951df6eae992fa9adc8037347c20c2aecf5dfd0f06a1f653a3fa82e318e7760eef521a67816050212cc15852623b4964d531e1318c4d4411d2468aedea76da63ed7f4a1f7dcd03028917654f9edc46e39a778ebae52991488043cfff9b716e5ae7b0a0218a41fc1d4329bc5f32af06dd2ce15ec3f1c3e6f541139986693891042874d6ad25bf9525e41d2273b1006e84514238141b1074775a74b98abdc71490c0c96f0ce7e8a938a355502dc7c29f206ee7461b7c847a87e4b5b77d77d88d1e0828f312522104725f0f311b662f0c176668966fd7c82d3ac63cb53f82902e16d3a3195e8fe41337e651e58b285ba66ad358dc4ed77a68e2ce34a06b09875abb4be97c3ef01b0e5536b8648f90d6d0081614c4328a988772313eb8ff5612170f15480b0fd826f0723aa141902173dde1128721aa7cf33453a5cfbc6ed941cd8f0b5c5d7410d76ee17a8d5112bd03bef2bb716f59bf27374d171192df29fdc65ae70874c5df4adeb7fa87f625f569c996b84e04faee6c017b8e0d927b7bf127c728aa2a6060755cb5d0e930e4350dc0fc21408da19b7130075f2a5419b86dcebdd1b1382d89b4a943bd46f0640e8d17ab7d0168b277a3d3aaa453fc3aa47c7e31a92de240718a50670e3fb01824386c019a4a04684f448b01de0901da054a557027f3851d17924a53b73edc52ad55493505e017320f83e6e57eb514b2a72cdf470d0e8ee173875194acd0ed91d65770e2172c6312a4cd7d15b20a3eab600bd928077d55aaf086caca49a0dd68a6d5b2d564aa0c38dbdb28815c3402e313f96ac8f40316b28e9d428aad7c7e44807800269b2435f3da5ec446610ae5eb39051838018fb9a7e8ec0a74bb6381171fd99de482c8e8bb5e3edb65d8f157c01e2f2965cd70c164611664a6d01d43afd9b4a1b5469c90645ea739e132281ceb3308508b039ed6e2db4f9e7e97bbd36599010c313f36c18a1bd3518489fe8ae1e28b16e980a8f786260ea37dc95c889fb59f58230482a16d738cd50b009efe79ab0b5fc2212502000e8bad67b3fcdd3926a04ada27444ae69dbc4debeff9758405f25504dc685f2a69b28b6e0050b62e6667c0c114a18acd5e0d830f3493f35ea05fccb27b7cd8332be79d87868df6fe6d6ac5f255f3a69107ccb28143ec2f2213025fb087a74412df4024e4c2fe0901f01148d6d84d96a9d4b03fd8654db33bdb15d77236ebd135b254aa86f529fc3372977d447afaf24377da1134b8a58d8a6a52c69b20f7c2c2182fba4414587e05a7cd21cd26518a018a9f7ea2a78d789abdad06c7b9bcb2a845863b23bf39b82d4ffaf616022fc3ed961f46d62ff0a575f32a915ed9f7705c22b5227ced444d5d1758c7c52f870cb6e65dee78d959aa5aa40d87bb33abf9cbdf601aad9a8336b7e922e0c3dfad325ce257842ccba8f26dab31312ea462abb91594b73595ca7bca129d9958710a7ac3f3fd121a9cb53f69c913c4876fb3f2fe92f17addbe494252198f2fdf09767feb85353ebccb79f67ad39910fc6fbe93e0c7cb73ee5500a3c81db5f208430f95512820f053ac814f2cab2cf7aae262a89db970da58d807d0d5cf5a287cabc1d4b7f3769383c4cddb6a314b69ecc2be9f35d7d305a4bd94b887dfdd121abaa897616f7e5a537461ef11b979c2823349b10db0361c86c0d0ac92ea4489b2ccc7c1522dd42463179151fbeb184ad8263283acebecc87c8f58833c1ede47913be93583a57755fd16edc611a4075f16d029b7af9e4af2550022b33236145d0ecd5aaddd409a5097626aad88a2133bf1f3ef6272979fda28c3ceb9a14919e78d9028b79e444bf07b3f615309a7d4cac2406ca7daacb996461a54f06f959d153cc60c25e46d3d09170276baf4b39d37d9a18f092b8c1ab2f99cfe9dae28c4534d36eb1b953354bc992ef2c4b501ad0512c372a0b89d3382340043118f43e502913c247a3cf02982b2ad82d1876d31edcd3fa09f9905b283119a088f0ac4ba4a5b5fe53bfefc108693d132be8234385feebff6ed6bda88ef6d1a4a4710fb9a6798240d3e33f1b385c20a221ecd9edae3e407547d2181987e22587dc4e1f6a8a4d7cef68dcaf04b0b697fd8a1068bbe667c56d10e9141ee5974215e6a08c1083546377ba5f7228f6b5121e54b7862f9af677897cd92ba8de74677a39f26b6cc83a8479e39f644258a1f808fb8ba7aad54dc90eeaaf9cc9213cd13a6c09f443e83c19bc43e82c197443e83c191c331d30524d2bf03efb7937f4afea8216701096a422c5f4cd105e286bf982bfaf0a454f1755f80653392c82371c7ba7c163418f4616ca4fd7c8d2b5e0b8d5cfab4e83d27389b3651acb6766d21b20530166f91033bf316e71779152568b555c6c4a4d0a6aa75c9cd7dcc8bde3a8c09949d0b95c2849b6c13ed9a560c7f62e04456389952d5576bd5e11ed6609a8bd8f3ebf647e19f1fce29182be444f0dec69fcfa249a98338194d9f2d5f14aa70d6df21b9d74d01a3b1e11c71368282949ac53352cd82d2a43dd679e8694edd19b5b1b77940b9c9d0bb321b8ecc01a3768b365d814848465def84783350d6ec3a1073279a687e3a01a63e6933206489a3bfb9ec7326d28dbe684ada197e82d452a984ae58ca7eae62510f0508735743adafe18d4077144cfd6957f9176ff49d8023fcdfc2b28b14cede2c456cb06787f55ec16d74c3876cac91c13bab853545e13781d1fa4130e689905739b0becc649365f083e5cbe9bd255bc3ed4b005b17ff569d6ba7dada8bd8cc6ba005737e80f5df14c4a282d7757648a3b07e40af85c732cf4b3ab5b4a2ee2d5c46c74e06bddb50dfcf5be7de0133dc7e565b21d68e8e23560f59ceed05acec5735a5950adc4ecdfabb0b2b1d1f468aed0427ce672d3e0a5c6ae31c1329ca09e4e4e6b0c50ca2135a1f30e2d5083b96c20d74d77755e20cdb04b62fdc48ae20cd2bf7307ed21f7bdf0e9602ded2cc6899dcf376b526c40e159f60ad2109f435256876f564766bb38ac6dc0446e6fc5cf83e2ff6918286461c95aa67e7dabf5ba979ddfd96338af4e739c29a2be051a7b05991e25049c9c7d155318e9c421fcec1fac42d5f971767e8f6cc39fcbe5b00620136ef80f94511af7751eb228d2e00202856f4d2913df71c2abf2b02cbabaebbe4108a4da91f1ac506d9728768ff47c0a59a735c1afab2b85b4d6ffeb4d96eb6de8349c4848a83ee7a0eeda83c12f9a0e51a6d5955295552e0688c3e5655502162c54bcb685f156777a7f095f5b0ed9a5aba2e4966ec49b6ed9329c7dd1bd33adefc20ebb6d174d9ed86126aca5162e8861ea7f21b43a53cd64c12935286c1a6d3a0edf584b278e91165c2af27c4d5cfe13247cef088fa19ebb9b50ed04c225fddc2bafa4012e7a1e30530cd95ca51d52f6513d54ee1838a5069839b2625d84043f5649f3a6af7d8def5442e3f22a6f41c1d776ce8f259e206ae69d5327c537abd30eb971eb7479f3e754f42b0b31c2710e382856b6af1c9987e3caa24a75a08d8af8799ad2882e0931abde72cd90bf8f0d4eddb138e6ca4c0de55121e1da4eae8bb616ae1ad94dc3a00de1989e995d837d5d67b839b6a0bc13384460bd7c06b0a3eaa00030fa81d8d27b4d2b617068aa1291a557f7750b6e626459caec50c25ba8b9c96f5beecc4a30bd570029621e0bb26f52245b513efc320b1ede1ac634f2ae668b9a175cde54ebbe1209ddffe70ff52d1f9cb14290b645f21799ade1c7a018eebf2e330562a6726949a215d2a532bbf5b918b52ab648cce52337f403998e82438cd2040e92dc85f363d977e8dcf2c958b263bee7dd0fe6b3cd9728c423e79388aa498be4665a7256f2bb8323143ff55532a6e9073900daea1255a6ec75a12a3a072d8bb05b311dfccb10859eda8be5868e18340c3c3846dc6cce73215a131b95602d3c3a1a7fcdd0d9129a8a396657908bff311b4d940e36e603b18eae4733e61430aff35ce431e5000456d0da32073dbd3a5c5b9a402b9a515d99291b1843edc6cc49c9e8e6cd232b8242361dd65002f0941254297863bd19a8cf32e2035559444a3dd0838f8c6585f31eb0f67fd5cc9c0f7bdc0f264bda06ffa52e00c5345309fbc5065e26b3fe190a74f106886807dca3963c0d84da793e31d630c16cdbf49b53495f996dd68e5e5d11f2027b73ae3dc8cdd33b191786b9dd4b84e4471eb4fcae60b347a0ad9ff1ba45e3e02ba8301a445724e772d51e7d5459d2538650ae414561f0a6d1f8e5eaf03ef2bad5ab0d8566e45287f81fcd9fc78c065a27a8a05000224e2dea7515e42cd053402c2fa2ed74762cc48e02b2568f24ac15ab297f4a0f5fbb2580507678b903f571e2315b450626fe4f28795c2143739e7c61a54cdc714a9a82d5f4187ff3154612a522ca7bbcd2649d92723d1141d2ab115ea2f4492ac6210e05100d510c05a18507f983ffa91c8bbd63e898d70e87d5f7f97f90c44a345339f319d56df9611eb4e7e915c893a88af4295817fe6db3c8d33f4c327dacc2c08b8ec1b9cbd3c8ed079cf6388aa815d269dc144770194a4ac0f91a2eeb59ae1caad7033151ce527bc4ac6a28834283ed82dd8fcbcc656121bbcb6e1b5aeb92188ca9adb400ca769b23485c65545ed95a55bb81561d316c1eb9f6cc5315e935defe7ae12dc33fa1495d6c01cd52bfd77c78fc681b67613be429ce6d53116922bc3d0234328b792563a74b2a614fb2421f43f3c5ffa356963199ef295415cbdf9a2811d60e93c105ed23dd070420e4b6e667409a3184532b622d27ac28498080e418835a30b5479b8fb0de499b1fc80e3f42e4b54d0bf3fd1851ec1fe92ead42d50c6ab54e781de310568ed41399df2d478643c5aa11249371596d77a86b31124ac6c944dd0a9145cd2b67ec0cfdf8e3b69a7bfdcc66512ddb7e657df1683888331d44e65ab17fddafaf5cfbb3e0362cce8bc66dfbcab67eba0536e88d5a0abdb266d2347b029cfc273afb498cf8954bd3f210acbedaf9a21ebdf72103b52a7b7102504d52dd0d20cf7944082bca52a74ff4b55907c48927b79e1e5f38d70b9de48bf0181ec28ac1b95139a3cd13dc57faaacd3c18eb45598612ae8e36153699b1b528ac8c5665b3e397c84137afbf5b479dc22d6ae84770f1b67c6c3262596178cb709cc26667f1d2caac1608772b6930cd23c3e800e084f019ddbb0d8de12532b1bc08406077a32bc451f22406e59fb055cf7dc0a16861d9dc680db19d93ac1ac0d1c74272821a1a6a53cad80c6c8e223f45b2f1e09ea79bc24b2ba4b56c8a7ea8213e341884445b15c6bfcf7e8166684a94f80b0ebdb59dae8faa5222aa6812877da3c7f4790375901c5ed0d1b152f42422e581ee58ca20c0ffddcb60c7b3795d5c989e6c647983237cddfca4fbd6f5c94fe79ac2633d15c057018713766cc4e3dc64048fe79894a30b3c0221f92d95477994c32ab724a9e1c66fa68e73433a2a89e1d08c712d56da68ff1512b5e5a36dd0c2414dbb39750751c7ab3b59902dfdde7664544d0fdb8d02d002d4917b4c39a0ff0301b600f2e0d501ec6111a7be9a7ec61bfbd5af0b8a9e9e28ac8c3d508d174a21b74f80f24708a9ce52aa104caa2e4fa38827c09908589d607e2928d8716b9675f6ff2efa00eeb1ce04719a4e7d834dd37edc8709f84aecdfe374250a82d3b488273a633f390a38a0c51f1e7d5d515b04d8095d866b8ef06e96691cd690a6825ae92dcfdda05cd5354d49f2a01c6ea20e0f28dd50b4c118fb1cf2957e00608d7ea0839ba8c27fef304fb29f36ca40695c98defae48e8ae7467566a2233fab24ad5df834bae363d6bce1b4639b3abe7e984a9a687dcc63a7987ac4d0506a516f41b2cd84bbe7c66d942f650e936242f191d79ba72cab6c7e970524c73d63ee116fad4d8b1f8658c3c48871bbbaec31d1e4059be678d3f4c8b40ef9d0e3e17776068636b7a39dbec899ced2a8773a28e91210b236b4f2be6c5368a730c016eb8cf649561b694aa72bf5f58ae1c63c798027938e3dab525819e7f44c609e1c5fe0a32f6069ce9982c973e5224f921f25388760d4ca0d8ce0386266351ca0e3c4222db7e72ea55638ad22c74a57d53ce6ba3a5f5e1a46005932785d0851ea1a6f1e537d145eaa609d0ca03530981532fd0a04a6b4309b85281156c6e700e536682fb7daa26e40533394de5fb501527aa918671ce1e3a1227b975064bf41ee59a31bcdbc37082012d470e5ebf79d9586f6a2274acf5bf8b24ce15e78395740a66f87024500d82048beeb7e720f354cbcf8941be0cc2c609d510e0ad3157120ca590ebaa437218e8dc088c4a431911caf014226ed4ee2ae1836329a9c0905cf736a96e72532009a9e612dea2f3a501a9c2064d6e1ed02464a7382bea98ad208a8193a2360aa30fadb820fc416fcff7f4782dca64ce1ea177968d1c20d0276ee573dd98f8e2528b313efb26a0c05f7df49b4229ce9dca97766166abbc567ca1ff8c73a75c54dcc3f231ca8eb99049fedb3a21a9d00ca4dc0fac401105520cf6c3364a5e223e46f7343e8e27f8f8016607185a54d8e957af3a3732c018026fb0522dbd01913cef0f0c9cd6e0a53fb63e2417420d97210f664d205e212860b38e7c8d58a8bda31226d781812307822ed8546bdb7870333d9c2383a7d624b704f3ebac798e364dd5cfed960d770fd34088628fef15362ed32bfe6dbf53d62052300c9ab35b1d73fd6aa19888d212f6aa1012eef5624e31c69c387c6be3154fe218c5903586961eeaa296f170b295e23317a1503d4adfcf20348f2317c32469765476976644e05e2a9b63be363aeda872c73205c90b7a8d312dd8fa2439ad0c4c04c77239dfbbb5fa6f311327c6d241dbbd428bc707c72e41f77ad2907c2351fd02f47029f6eba31e737d182f8f46fee73aa2f7db0e6d130745d3dcc2576e6c8bd9c37eff853a285e36d41ec7dc7f7964311f80cebcb5266db0a48a9bf2e7632aecdc86e6a04124e890d03647c9b029fb3cf4a5fcffd2e4fd379a34bcc5e2cc52f392ea8a7620acd8f4c548ed52e5d9bbf4ab4794117c60c38a30022fe932861f62a3cc432d0cea07f8c5e2524a84d37a232e870a81cc3522f29df0b94de6c83547a34f7182069419fcc6e8c5b0718dba8d8e1eecba729f4b29b58d198854d8db401cfea8905fb30883efab5863cd17430d61c3807cf4e03cd75f5cc39705436e1139a0509401349ef7e2a3560a585d8e0fde8733fc16dd98163e834cf2b4e34f151dad2f09e25fcff4439469ae678e730f2c6402762e4d184804b07c88d7df017e47957423064aef54ce6a30d2577917cca79c116997f237c82e34c1c91f152cb25e6cd8dc38fed27922ef985ac604065c5ae5bd2dbbb0513ae2b6c80f001d71ab882d24e294f55abd4b4c4fd31c8960b97cf4226d1531baa897cc01584aabbb7a85c5ec55703922db3fdd7f5dae9480501d8b66ddf6c81bb8e81be69387c1c85d61221685b82db91822d8e8532b2c77bb4bad02760bca09a9ea341e8699b22c8d1986bf1813ee90c1029613c5bc3462e42a47102a7ebe14f4100c7815f4aa70290e683a88d9f4c1040ce706487ffdfa86210373d926256ccb3cc506d44b9bfaf77d0a81ec20f87c744691588ee7ef1c42f3bd44c755d4661369b6c45f7c2cf8812bca8e69aa0d7d3f817efe793e07bf904109af190f093bfffeaba66b6f0f3b51867ed1af86f649b7eec5fd7861e1acb9660b422d91bdad796afeb441837f9d7182c8b670c4b546031591220706ca905003592156d8afa63f8c1dc1fac676ba257bd55bd3212643bb95a1162f9143c9c436be3701ab6d8bc496e0fbb9dc94828c5885e8d045aeb3884cd08a1ef822224387d02a8960d33eb872668ff53e340d99ba243ebf8db5726dfa52f3b9521d1451daeaa2cef858c1a27b5c092c2f22ef74091d58ec1ffa1968b316d5b597cf909e5a5c9b1d9eab2aaae491ad87cbeabbabe42eeaef7a48a3762abe8f13d63867405ae6ff25d6f6ef0dd729be01391a8b52f16cdacd4a5d24e9f798a5db48eae76435583b5d7e44bee70b68eaa78631fb0cdf66e21e510721bf7918d8b85c944c4746b6b4688cda0da913201f1302df90623809ec4d2e64fd50d71124f4a04e420da47b44a02ed2e1d723c0f9c7a960426cbe15662b15219f88ef463b5359f0394580d1ad666442bcc4c69d3fad2939eae3bd6ec245157118d53c6c845caac80d328412355e1c33bb8f66e4b7dfb549773cb76a260f36505222af4d58cb58b3ac47295096a29d644526b538c819a148cf6464c5d3d54e2209e5b4b688f62a8fb3a0b3922e1d3b945a5eedb3369d76d731f536107d0402f9d5f60d11ae067bd0a6df04ed9f8f8d216cd290a7b23f43e2d6524f4d17e94f7bedf803c2497fa202ddfd76b2271e9ef3b791ba4a014330465f6d9be68b70560a3c4a5c7a19d45f8c2782d61a5cdfd738eb4fa202ef37737d0c1ec1ac51afbe203940c978aba6dec1832918074ac7289bec5573ab937697f42af6cf25065fc532d983f61034dcdc45b5543cf1345f472090e212ba49f2e82ffc54f442d2629f02eef88b44c48bf18702dd69fbc61621fea404615f888584f6f007afda443d564245029d55c8ec31f9409fad5a27c2c54e8666bf571209f3f532becabe16b7ca0fb34f48ef9c36ab7d5ca3a1ef4eb5abdbf41da1351d1b39b7d3f16807995a501eda3bf6b110a5bec5739615df0078663d3e53a73efec50a1519f015b315be005f9ae2474be305a4bb1d2eef89c83c4280d5b7aa87eff4c36459684c37a1bd4a66659a5da343dd9cd9dda9507b917c3b11ed9c4411d299675e9b27134570a92b9b68ebac8c3fa0f8f166dc68193da21f3780464fd6267b634982ca6da1513fe03021b4c6eb1237235489af974a600430d3706a45c3b0e34199961d209e5442c85ac62802b516d9734571ac34c5d6afc40db8a7b88f156c329647d4d0ea01ad1d4b166cdbc04fb8de59e43e4f25577c05b6fbd28cefcaef16dab5645fe08ac572f7068ad2359fc9c3bb51886b640782344e7921bad8f9922001cf0a751fe15f7caa441948b870e2ce9fd6d6c803ff7892bffabb0c0f48854287916cbb0ae71890aceb0d73cf0b1a03af6ce96363e9ec46959a53869cb954d2fc5d068a90359cfd7fdc86c278b1d574657e0ca4685661fa81d58744301358e60c3a228626c4ac8894569892d2a8f1c71cde57a94b2a8a88cb9a2c06822539e1aad35d062096f816e3384b92b5f5433af902a2bfd7f97b02c7733c8f8f8af1e5f8d773326fc20d775ce34e9047c4915a725607157aff08f514d1184ce6928abb6b0d39fb6b569d1391fb68c83ecab34a7ebb76438db59d2ff6e567a48af888f60c27b70c4067b20f75bc7a07b5cbd1655a768de92ee5b2f5476bdd815a9736158c7c757bf4618d1d18d2efc32fda7f3d083354ccef84b7a4d1c457e9c5e9ff01fc0c2e7cab690277c5cc5e72d4ba03bae321472a89d2c54ae3cda7195a51b6168718c23ee689d4cef1d765eae266bf5426386a6af8486e9ed0b79bd66577de2b69bcf3a6b7ba12fd672773a6b6986d7fed0724e3862ce34c2ff2239903a2498ebe2e652b172a2e8a6314608ab7d5ea9137fa3223efbe7c04a4f23f0cd36a6f0529952c25951c458a83ba0b9de9f4b178258286bca029108e013362bf2312ecaa5b12a5a5c3b6a1f1f774d3dd4e54072f2f65d0e5945ff792e05173e191624b230da7a20aaaa514f8e0df5c213766980d38ed5102568916a877417dd5041c950fc5c88ee898473a10a0a342f74fa4e832326caa2a8f16a200dabd671098a36a9091d5f269ea23c23cd26702cfeab76dd86335730682f54d146dfde1c2ae92cd4863e4301edc51afa9e8d7190e5fbca1580053e714542b7248f632153d4954d3aa1c597c923b4252aa841bc45d124dc4c8d54bb48e89f3d48c649d31a1a988146fa72f4cbd7253f081336d624b14fc2b62b9cde8696bf36d480e1cf62a30424946c06aa51d93d0953aaaf543db15766020e4888014e6aed9eb87084cf80596cd3aeaaa910baf60ff55cb086c1a1a5ee91961627cc45889c3990fa842c6c08c76dcb2b9115bf0dd4c34f420ef6d927f971df43817d7dfaa2a75679756ab9a990e22f7054d1915b6ace483c12ae09b4e09964cb7724e92c928c988ceb063b1c6da6ca599e3aa1c064a6f00d6c3f39d6837e5b787400ed8fae4067552115681e3ed505d4c7fec01b0cc4aac186c962d010ba1a5c972e7c57430a228a4487497f6759152bcac87570e4644657bb559898d272fb04c9cd314c8700ad6c4917290cb58d34ba989896b5164291dba324f5af2339d7d9b825f4748446e6680f0db4e3a7d83f3175ee6a077c94801272c3452e7c679b2bc9e28a87560ed884f349675409aec70d5c53fec3f980bba6dc8e681d8d05b8c42ccae51a204e7b7cd8cf38542abe43fcd733cbc172a0473edf11aebf7be106b8c0f9e5bf52f14ff80f83a164a677c2cfb016ac30ae28eb4fc8a7a5b2401a50ac882b223f300e0b22f5fed4d99b887805e581814265d7e730bf1e57f41d3865bf842b4ae80632e004b1b8a21bde42c776efe64be3ac68d5aa043283e1390b21aa759d57d89e817e7454f95ed76bebbad9426114963eb162c92344b3041bf729bdbdcacac07e714d16b775d8839cb432bd9541e6873ee7236e47ee27bf6dd0c43cd01b40703b0b03bb243323aa34df40d213a0c3fa8caf5fbb6d3d04bec6e5ed2f1b2754e5be961b5e98c658fdea053561f7358a5367fc9f73f93161d0d49807b20100dca7da6ddde64a9e0f15e92b523f687a8745b8f11ece51d37dbd11a094008ef235c8326c7bf09e262759ce755f7936878ed6b82fa57367a53e243977509a0602b59b14786bd0f2ee2b1c909cd7bbf1f597e9fd55a8d5b6d87f07b8602006c55dc2cb3c3c03c1ada255117dadf5064f43401ece3c8c2eb69684aaf34914793ee5dbe7bf3a5875349daa6264b55f9e3f88ccfe567b68d3220942e3e3d54327fbc9329de1bde43c4f4fda2f5045f51ae7528ea79fc7be871c32a01da368e929bf31b7756ca174b7203fffbdc1cc0fa5eb7ff71f066530c5b8154af1960e66db0514d0cc0734bc5e7ff0d94ce19b97f4441d793e9eb496f480c4b29d7d2e4efb862c5ef4d877e6795e77cc39e6314a42e160ef51d3f16e90f75a9648c8a4e075135e78eb9de38db2fbff5cd203ffd4ae2304fd3777117fd4154d618579dfd2955f5c88beae3f5c26b892f6bdfd811c974c7210b4dc83260a5d4fea4566b5d6371b1fc2fea5a15c801a16fdf275e17014ba65113c77d79f7ca0ec170507da136006220a24dbc23949bd644c8a1b7d26fd40c507a0a328d8454b55596046ed3305bfc22f81ed4bc3cd88fe8b0c00265f7d2d83979bba4f33be987f2af6e6d2201521a06d3e805e1c7147237b309d9eb7ac0e9e93f0b833146d6798f3c8f2c5ec742b43a2413de78b9051f8aa22b1608f247d979663670a3e2ca54d187ece2734413d79c79e2e74bdaa9dfedfe2b9304bf46d5d3830a99edb9f9ef76a086cb06816d66abbe79bf711dff5bdb72d2fd4dd7dc2de0fe88b06dcbfb614d035904d50cc3ad799f7ddde0a75c7e081c8165c29b608d816840a5ff49e66aeb68a6f482b429358a8e00ead8364a78a441074e3183a9da92466674210cf93093c7ae62a175530abe7337c0cc21b152b199ff471071dbc1fe31d150089ff7338206fd9954711fcdfaeffdb37242fa757fbb192430e1559069b8f39dcab3945eb75b5cafc46c88fdb865366efe5fa516581bdf7301817f3f55e68c47ffa60a4ab336aa57e114bfb83d2e6fbddc5a1d9dc9e67f16a2fa66886cfb6a1b5ebb5ae8abd8a1e6824b08b3a98f9e9f8f2c2c20c8264f0a24334cf3380909082e4e9df7df4f387f4137cad1aefa28da7f78bcfe3964005225450bc522464aa646cb295ec863c1b06645cf590de5b344612639d96b73c30250e6ad691eb214b07b5859f253456c9fe757bc9f38b6d63a7d5341774dffc1d004359e88987ece05989ee9ec2b33dbd732a7ad35a267fecec16de07d321e16241ded0ba67d34b99a11bcafc577cb49ecc3d241f57eff58ee8059e57afeecfd766232a2c18cb06cf22d5323ad3708c77bc7fcabaeaf94a2ab3ef4f58d7626dd513931f69379479b74f081543ffbed38db4a61bca6c9c1cab30e5e6c07833f8067b3c92e216c23318d7cf677662da646b1ec91e9459d7367c03a59ca7f5abf317cdb67840fbb78ae39ea6920d49aa93449568a431686c9c8028ce29489ef977c7b90fd78fc58f09b7403f4c0430075998a41b7aa7d18dd335c3ca0a47d74f109bb9524aab6a57cc019ccc563bdbdc5d00ca097cda449f2e92f0459271939484aee83fd1d51f6a7519fc03945818aaf835a1ab726faed994b6b223a8341ef1d09085513872a2055b86d2eb9d20e986cc9a2724309838967271942bc78c68c6fcdb55953fd9da2e6c97d3791d3c1942967fd82424b6f3fd4a8db88c4f948f385fcc69934d1a195091a518b0c7e8fb35c60ced3fcc545edc9929c1a8ca165f59cfffd509ca85ee81d6aa3ecfda056b69b9defd0a19795dfd83c0498831763c29c8316912a55e45495cfd1d2118a2b6efc117b744ee1f29711a1c754660e570429c1829a5f8869344634a9d6b05b6c9644b61aa8e94985ea5ef59ef5a67b54f60a4c450b850a1b22391df37626ba5c8e2c0f2e9ffa14055513b47266fcbc83b94153b366864662646f9068d32575fdd73bf699ae90a7b20723672180492b2ea3525861ca0e6014cf98a8c9040a470aece911cf3192737d042ec851c9665b7f8bcd830040162c594b354234f1a1604ddf8c3105712f4703310f4bf5efed90af739c85e4bb8f55328f4cef5f9fc3bd2c11b6a751bdc96705af171f228c473e2bed244103ebc02682c633b3188389cf8b8896f0c847b2e3e460dc3aa4ca80f52812517fd9375231178dc73c78a44ba8873b038d030154c9faaecebd50f1da10f1eb7f69729554025e88dfe9c1cbd137ca9e1ea4aba164863ae4b34dce136292abb78c072ad94a57dc5beed0dd8d6401f7b527722b7175316165f47b75c0b072f16ccd768e90c8c45278e3a91000192abcffb4d21e8189852f8a3f949282b618cb34ad5253d7342799692c3daa5ad070bc006508fe1af4b74ae7bdeb856141f93e514cabc3c834c5ca1b8755e0b7d5ce1c6ad6b07df4c2a0e8982fe91c5c2a67643c3c3dd2549a573bc14c6b22f87631dc01d4d3a049bb68de86f5a04339d5a7c9b8ccd68c7013629a2f850cecfeecdda5f4ea36449785c0c2a5bf95b437e873a5ee7fe6eba6436eca1ae50c1b03f47d49325d2dc40efe8592cddb7b3e1b45e3026aed7aaf5e48da524b0ecc9ae23bdaf29edb767f5a26a331bbff04ddb492f8a64e2a83836d9ce136910aa436c85b94161d95e43e1658323f45ee2229960d7e7dbcdb3c42ca206850f93c62a62295a7c638900b107c37de0811c8840042eb0a412ebf9ddcd37589a3303a31c373e45d79aea6dc1f39aa54dea88066f3fc6dd96fdbfb359b780441d6cc55042f562ca2bfae51fc854271595351e4b8f33ff5676e362a6125ae6948933698b9b1a720353fa6efb4b1b62b3edf9da12240a9a401b47de63744d0c05f070c83f0246c98b92ba58facce6bdc873f1e23817988da1232887cb26115f65fdf03f32a551faae98d1beb2bcff64390b57d82b671887820715b043cf87728889ea8040e0cbc17f8e1f03d6c2eac5d8c1de7ef8d98e645d383be6c835f03bb300d58f102d629c47a85f8777999ce2c34da9fbeefd3659993b93fca6d8013323d4b37ef0934e7a53bed3251e78b36af1fc4d48fe3b09f6747c1cb5d60336e998aa2fc593a0a9041593b79d419f394d8eaeb4cc6981c2c7d80660134120b7091decfa710bc3ba99cb92b8f0a090e39aedfbdfd6ddef42ac24c5027b50a1c4a8c2720a8e51ef90518832ed4de913b6375c3306b80a7c065e1844f8faecb5ea5f55ff1e08977741f0e9e2fde7be3c0108e5afa93a3c70ad72163d4ea97027c3ff2aea2f120837f41f616b48473b79df8cdd0eb8892adc2f1b17f37980e326e1ddd21085693bde25b9a3ddedc0c0551af368b0b88f98893468708738500c1b15f5ace015796b38cba948e7f533bf719c3ae414f95c39a3841e5430f93524c3e38f2996fbe93ade8dee9fefe89b8e1e2576d135137f33e5d669ee9a56b9c61e05e97e61da3db18ae7bdf239fa96c8b4e114b97f02f430d02f87ff370f51fb3890ce9ffc9a58242d990a93e9584d2e98e2d9a473ea70b91fe43818552c6c2cc5c1a2b02ea354b27cf2f990ab36b0da8b51076e7c3b1639c7e81852c255b705b96df329941dc49ab8fd475f2549125ed27d70f306edd9a4eff8b79109506d9ba3709bea94fd03fa4b7924dfe3399aa09bc7342eae1109cbb5bbe4002ce11e2b38fad73f2abc6c86a7c521a1ee8cea929789d39ef76624e300ccbf422325fe99b69efb38c3fd420881c02eb3e4d43d3ccd6814721fbfdcd914a02f2de106320e7ada640e9668a54b5e32480f1a9da13411272aafcf202d6f3c96578c111cd4acc894319b27b94ae244d70ac21740f12432251071ffde208ba19e4986e01066f70ea7f67d8c8cc78c34f0378884362379fd124ce5d979152fc22b2cf4aa630d5bec3020204574dc975f7a1df3fbd243b0e934c6e535231434304ac4a291f5a2f4e725b0648b40ba8d9843cbd87c4f471980dcd35b18bf4e09c9e21852be7de289303183e7575f38444f058ecc4cc6a491cbb3bc0c2b875da9c8c05d66ddb09e4c2d8b5cf6efb1dd3dfef0768ebed33a9c4bc832b2239d0f10062cda84041b8882da16a23d1237cd4f70288638cd85330e97aaa90800b84f05eda706f012cc442f3dc3beaf8088b1f3145ab54c3f9a9558b23bd2f1ea4883bb64e8ee5f38cd25f566ff570988b7fedcf25c69701b1f48c7d96c2518754996f0fee2ea6f9971363fcf3cb7378add722801b5fb731e0a197e04203720dff274eb5ae75a8b91be936d5c2e0d1d78acc6c16dca9174097a85ec3108a03f1034f1aa45e0022651d678d0cd18a04a84d43d068ee2566f452325662d274c2e67900a85ecc0476f1f052f9fb2913a393f3f2c0a6118939084c9b9936134881acf77de67f3cc4b41210d4c984aaa7c0b5384c8ed97d9e61be5ad2df0e889c072f84ce64a5b875e32a7ee0403d843dd2f56613555f9919d3078cbad61f059770655b5644dfe3c05bbaab56b21c2a20bd15dc85fa56e6517bd343097f6bef4bf8e710adeeef020051eeeba7c10983d8e82d474774b052cc0484504a1a831a1a9888c3f7128251b95363f4b4c07d5a7e89ee555e1bf2b1c4e9c9b030715e849369e8c3956d9c654779ac06f07c1ec3879fc76a401a7f8aead108521dea63a252fc0a453387c2b2e8a5d9c267c538ace8fb66dfa9b21c6dcfce0f9cad69f2f56c2e15c35ada0937078fa86d689bf132f599c3ca34e4256875ce3745cc8bc7434581f9e66683e999369f5c75930980e367d99dc0340184c6771f4d0e5a3f9c7fa2d382716d2298c3e6029208c50b3e73b32dd4a0af8dc71ae9e85fa03c8ec81c56cf369eeb60faf7f9c04f8a053511dc943332018372729fd368840b925e73777a7f177018ae09ca095ac19eb84cc52153fb4a61384cc11059f62a2728a827c5ce390b280cce72ced14df6eb3bf2edd9892b42a384dab92a9e47f84ada74a2588d73a0e0d645885a81a08881bc6da7b89c48a16f042e18b07c12069ac97be7bd49740a5e61e918843d7ccdb41b41073670b798a61e7ec5126b60bf443b768dec77cea7f0ee89f921f4e20807f58037d0a9bacda27c10c385889bac0a0838a6ee245f69be64b956a368963d4ee034bae244579a5023b7f34a1c9eb63416204ea38a52d240a0d89d6e9ecfe38661209181a88109daf73e3e0d1107921c9f235e0c34f12db0134e090bb0b7c3f579e3e05caf931f31d3ce2b905ecb39131737f3facf5b26f4fe7e6b8c04c84a014864cac690f9189fcfd25db6f85b133717b483263b4d36e59f34b3a3d9103922c5cea5349db183e881c3ba97d0e5091b27a9eea32c62ff8bde0d526c633fd08dfe2a581d9f764ea896c77acdf4e0790d942b9aa8993ddb8e923e2d6f5c4109361aa00579472ddada7bb82390c0b8eb651ff5b1bd2604fdfe5acb6c4767ed8e057c01f34ae6772e8e8b23fab3cfc661474624fe477f4960cfeb884fa353983725b2b2b4e94af1a2c939f8f24ab8ee7ff36adcaf33b46eaeb29427c57c49ee3431a027b635433ee893538a2054db5641063858146a0f7f1ef039f70c0ecff47e31ffc53da337a302aec793ec52a2c510cbd57f2521645fb87a4fde6ec2af2958d13d462747a9a5a86fa9fa0b99fef00f829820fb3a38f2a23c4e38a468be9683ea87429b9abadc38c4427cbeff6b5ce6db791fb633f888a2ce1501360d121a3529f1e5e54070a837c9ca44efdf4667d6a7f2f235001345ca372c6eae26857ebe89973aff7b17edaa29d05af280ef3bc3bcd378f90d5cf7ada6955dc5ea75070af06b4b788d39f9b05668e3413db5eb15073d03f8afbf43871f6e0214f9b525d374b9f72c3bdeb6266c88c5c92779b2a27397014158985ccaa84069a064347df1c1846fac4d170318f5be1e5eb56cc61985bf5243c3885e1cc1449ab69f31c9c261a61dd8a2f0559c7bcf9fad0cb5ec185b3c944aeba2a9dd3b8cd83d838d3ac641599a72c89034ed58d113348ab64adb0d26554cfdd40986c7bf7e1f8ba2db85d7d5d3cdc49ac9e2f989ed13136a3f01a7ae460786347a082a347a9454141c718000c458a4c5febaa45a8ee4bc9eac82f31602a47c8c13d94be9e9cd3e741c71a6e2a90687082ff2ab3fbb5cfb09d95ed954fc2b02dbfe41ea90b06cac6a69dc218ce6c6193eabe4af365c0271ebde7746d47474c385541a698baff630a7e91322a6e425241a5686d6f0a21333fe0a7e87e1dcae29fac9545859b7e91c23ad042df0ffec48b03290a4f78f080e59e3011f13c1325dcb1af514eb19cf4159741b4befe620486377f5f8b0994d19991199a327825d5ffa319f852522c45e21683e32bae8e1304b46964562f0944755d64b45b8e8ada1ae86993fc95d9aa179bef28e74c30e2983628a85a36f4796315f514894bc0fa33971c25bc3fdef25ce4c605d72fce41993991b62f35b74d2c6c9d91c3463a35b3f384a57b6468f05c63e06b711cb34ce621d7e989ed212026c83a9d71d8fe6a211d7205f428ec50ae048e60651cb8b776b75a160b2ec371b34fca664348b5151b1b52a8fcb352f4dd2c264aa13c0f973c62a28d39e031ca875c1f0413cb27369a495baf622b519082946dd111f3256a5a4b316768a9d8da1b9e6606e279436b4db6781f676e2e51f0035944b83b796c4f4150cbd94664161873cfe8a8be4d6443f0aa7e048a08ce2f736e23df47550245c63c91bf0c590b3832c9acab6dae5ee7bf3f210175e4c9461f75c4ab93d425fc63387697c7d70ee5d9a38abbe986a676bed2fe4d2750fec5607418ebd0cd82e36d93108b9a8e55c6ae0fe34dc6bda482e31799fc2b095e332279b7dae068c8af9b01069cc3d1bcd928c1e3c815fe98e4077aefb810e66aa40c471f68375e60f8a496ba81edb5692b8575d7abc8c0b5a955dbe6ed69c7781343a891a59671f48287f466ec02e3bfdf9527290d00b46bdd9f84dbf3b703e55b97b9f72bde3b1dae0f419fa40c0468fb727e090600ed503a0162b711f23daab2d8027c75801e12355686594cb943441b088dce43c582f53177a4f119e97c02e9a3e6155204199c80832fef00b046fafc8b1bf4f56088ee6077f6e73981ad5a235adc22d79ca70b5bb6c3918956e8d27aa39cfa1876680302a58584627516896c36a2666db867f12074276f985ba1267a696603ab7aa25b2920b204c621ae740d77a143b0a95a6d264aacc87014a0610c1e92a695daedc44192b7c893b4c16aacbbb9e12c9c3f3e722d617f70f4a5af6df88003aa8f037645b70c9ad9802e788223153dbc3b115ef5ebc6eb1f2536bc8c9fc190fd565150ef4b2f46b79c4ff7aa256d8943c626631a738fa1eb6e7327a281b7a4bbb53fc340ffd8ab47298b52547a04aaee5d1106c81a9e9fb1b8ffc16d8a40d0bc83650e42485daeccdf108f363a983322a55c7a5133483af8609d56860e1ef5c78fb75e05636a90a3641366dfa081d836a88e440416cef8875504a3c5147ce98cbe05528a1e8e229b611e3bb1a28341e47a196931ae1fbdbba9a92ceca542caf4db7ad4a7dc99a58ab8aa0d24bc1429162bccdeb9cb30530b9e5cd3ad4d1618cb29fe3ac0726c71ffd4b19cbf61e1c8e3d0867340e6ba57340502207589c7dc237a0409bf1b1fc6520b372e4e6965bd5def18342a8e8c907d2abffe08e5860ba01de9a2edfed52cf2432975a3eff07bf3679b34e872138993a4e5310a2b1fe5bd48bdcc481a8bb4143389bd73a7e7816290b33b9b609301ea29380fe44ce498a671954ee342e55ddaddf8d2cb15c4a3ed82ba5c5165854dac4f7fc82f82c37cd77022438a517fd01628f515e4c872ae25d8af1d07310ae848c36651d834fe4d1fb8f68fdcd2acc2bb2fdc9bead38713e9668b520900f531cdfd272ccbbb1b72e6e677aa66bd538c4f82eb3a1d5d349febd312dc577458ff8d397c3d4883e21c8f6a30cc0918db0f457900cd49523b067973d599de240ec2cc72c0b7ecf83c1ec4e1daeae01773b839fbfa7a38d521d75e18d08799eb645917a6aa95e548e0d19e0fc516b1f962da368b9dc33585f4c6243334d721d31ec8e8066cc924152fb52297aa3099da70d27aea79f482559c47d273d07673e0be0178d90800bd57e979095688ce5380d063713cbdbcc91afd044aa169e49483034fa0b83effb162071b9575b18da5aa792310210cacd5f06b5431d8392813aaeff41b4b52c0d1b8a0fea18b84e0ef542aee8dcb2272744eb6d44849e0a1724120f39c9ce3f5e92ce72f78cd9ded2eb0368dd331e215a619e55ba41ba651779ad324bd55b3eec020df8b3c5bb073854edc765d2cb7b8626506cdec7ceaa61338df51e137d69575a91e9d3f9a3a1bec997cea751080ca195b19483ebe8ed1ecfc2c7af3ac0b33693f105a12def795cfe64f0adaf2c2a8cc04194d6c88351fe077f0d10c8af5cbe57d912203632bdbce89cba418dfe6a2876b287bc5fa8dbb21ea4bc167b19c92973eca612694972d2f9321ab8b50269c3ebef7b3310204942ab828a2087744b445c042eb69383b451454232fca11d333426ee9d234af604529e7899048f6a2490ed8a78faae832d20ce3f3b31cd1c08eb816c8654822aa6a7e53bae05db4ce2894667a07189ece585c684b0d66ea7f3ee24a565012eb132af3686c9cd777fc9deae96c5347e292e239509e9a0943ee7e2a677d0bede172fa9ecc2f940e8038c7e04583c1887021f6a8910b9bd40bc557f6c729dc6df6b170075f0e2df1a62225ee0ea55fcad3aefe7c68a56f73408fc718f0d5a28aa3ddb8252e50fbd6986788d8015e365dedb90db8873317fc472f6530aac84d869974a0cc69be77959a3529836ab2cd5ad13be0b7b99949ccdbc320cc3b07df37f784c5e57f4a1fe5f38e3758cde0743e07c7e419d97a26c9f2d0503eb98aba575e723ab0c22f97c7320c950f9f2ca8af1208814f391d1beb29463fa68e3e5fbfd035b745477ec012c51cc8269d638689392a2ba7e658bc84c5bc8d0a0841843e79795bd323fbf68259b0fdda0c5c952736c6f6ac133f5ae4d5472c9e3893ff81473ba53904506a34640e3f6b5cf32719923eb8200607aacbb821d97fc6bc2abe0956773d1f6c6713ae40cc0a806360e838d5bd9d515ad6424a6ff3fd04618fe36bbe06ff8ea461fa7589abaff81ee8d4507eb1abbaeb771043d2989acebad62c6be310eba069e57f0269b5dae895e26498b4b14bae39fab4625f31739611f7b6024a43316c223fb158db6b13b87b21166b7d5e6f7606c61a433d7d64a173c696a39ee79f5b3b777e20ee67e9f01fd73e2ce587bf0f6d52c77e4ec22b69481134d07dbd952217d3e835dd220d595cfa7c24768dd74c8a79e63391d055e1aa9e8ef04d0291fc594d8cbaa596df39fceb4bed1ea6a474f4550e15e377f9c21a6eb31a97c682377ecaa5882fee86de1b854dca73b0d9233923796d3364fc3c743ff62d94201cf0f30c5cd2370a7454d73489db1c13c76c5c0ba8d18984cc1515e005d13aa83f23a670fb62650a576f4c9c298357085dd8d321660a689aaef300024440ed6206be6c034dd1b63f2bfd5e192e592d1793308e2d64096bc57736e9b4433424fcea1120f7b0f90cc1c30d507e6215a81913301e22eb1cea93af7fee4621a287a00c2588208ec024d5196ad82f34a8317457292fda110b7fa235a7525e758365f56738fd180d5e1b48a784203e0554f30521a834e837f2bbf44a7db6b275be2e2d185d9dc7ed7cde7478ea523ec1b987edacea7de36a9728a8642729adaa35c093f22ea7aee4427e7afaefdbc27487d06fb836ca7c7944ee6d0041cfbfc9634ab6e2ade2c13a823cf00d603569a3d0c8d8b251688860e9e225e300ee3b5699d0fc69afd6e6a95292304ac4152311359429853824dc5703824eb29309d5781aba626ed73337dbe189629248a99f28482f4157be885429c89292ba5ab7b718c098b47bbd57928c8c0a1261602ea3e866d3113354b00127b2d4d123dba66bbc728f7902440a3d89e9c4a0ce39b2aadf6df50dca410d5ef42e3c19fba01650c2b1c3be5c5ada3aacaa78f06c4f06d6b4bb887818dba24ef35e48df618b74d70cd5f32216b07d68eb88c621a148fca0df027b9234fd6a8dfdd5c31ad44d622353730af211761c518058c379ee52fe5e48250e885ae5d70175d768f9b13e40e4067bd75632c2ac3dded4587d9575b98bca7506061b4d270827ac7fd859cb75b3ace21890ba35a4d0a69e4738beb255d10192f64bc13ca2042393fba8398b28c59ef80245036699da8fb95228e29f682fa549c4637b8f2276250e923faa944e10f947d7a4a821be89943fb9f1911fdc38b430a3f3077a4bbf5a8617e34f2299886a9441466cb2af85765f404c837861ddacaca14c32e31e5e5bdcaefa9186fd774bba26863fb2b8becf7253ab7ba019541520c81b154fc9fadbda940f61cf42169cb27ce500d9f0edb6f3dd8217e0af71b662e4426d2b3b0d7f37e935a94d17b8a4186ed544d6879ed22edabf946bc3a5f4535807f7670c007d52bd4f466468d947138ed1a847187adeec84108a1ece2b01e184840a2a24b07fe60cb0de83dc76a4cf99e3f4fa5b4a34b340fe9312bf305363bb8d97ed4973302585c773d97e4374d0e0d5fbf208d716a77d44d31497f5e80893fc2d044d48f91821264968f2d9f6f19a2a3be8421f4acaf6459b455e5d76610e443ca66f9fcc659b4304133d5414a8bb875452984ebbc5e703328864bea78478a5ed3897a296b0037d90d151db3f79c19c64f14adfe8539a5463e2548236085075002cfdc6a543719dcab52f9c71a67015aa0a0a295e5838965a109e79b2975158e2567c0cfd11e51fa9d3ae9aadf2e1f9bfc76a0d4968ae2ca1a2f90fcea9689578b8db443086fc17ac09e411eb0c25aca4ea9c58fbe81ae7c62763d02026f1c53048fae4135e7c500b5ebee3e599e29a735abcf5e8ae43be4878be066f9c37f96c727c65f7d525ddd273555e0abdaad4a84dde0f3c27ef099b872421b1dd1dc53879270dadb699adf06ad37c533aba059963a73dba4ac9517ee9e526a47282ce14e9de4fb2195fcdbafd5cd7be8fc008c198ea2f2c02536cbfa0c7d9a80280ac6fdf6743a28956477bdd874a1ab2ddc4a6b850ae75d5eb9a10a5a891562f62eb6d888b38cfe879a45efce135cf1397d004fc36a1a1809255c85c55140a610900de2a9898dc490df6e01c189d5dcf7338e2851455dbab25d94fe88def9aabef3334ee4a1abef1bd011b49c733da7bf1cb1111038889c82039cacea16ce858002eeed57ab682055cb78a514846c29a8387c863e49e31bc7c0aa4e1b83e52e1e40de5e3eb52fa43d61756022e82b26091c2c5171746ff28b227f119080392384a55764e35f50f1518384cdde3844d90da4b99eb4541679e6d063eebd9b7d75885fa6d73442a94be876ff3c8c45e67a70e9947993a756a445589a46a3e06bad3434a89519f71d3ea63c8694c583420b4d498e899637102b137e0e30f6c2ee779584a9655a31bbfb3838ed5f0184bcc8e1d74282245bf4eeca888ed708ecd35316a74bb29979996000f90a6e2e68d6bc75d689453be5b9d13ee6d87bc647f52fe98c51c1950dbbc015e70be8b4f80bcc82da7d5bd0dd9d29f4726a793bd6735c9e56c7f3b233e490325c5ee23a66441abc2bf3968f4e712f115a154576090055a53250d52f0d16536cedeb34e389112a25b1a0cdd0cde0eb101a37dec22546157704f411a7ed00175555aead7f0da932532adf7e8512a3dd3f5bd911eec74a1a2acf8fc699c43cbe7c54490b88d3ec4f4cfd08759d58c27b380d05f28b6d215afdc7f79a745dbe3553145e300bb017dd2f0a1d8bca99b2a939229c68cae867de88d8a17dc0d26ffd6440fb183516b384fcfdbacf27e2d0e6fd05822c886f872764ede37ac1005405f918b590dcc916089fbdbfe3266f7d0e8c453fb74308a736ca14e46e04e1645ada74309ea90cdf9e45fcc2b6b80fc9e420dc8cb90ab4f4f83655345fee478cd8b020f500be19eaa8ee3e741fadc57a06f81caa08204d5f98356eb94bfe786eec711683f89a047d04a6ea3217566f3f25efc9ffc39362e0dd5e37260139f13dceb699153cb33a16bb246ae99c2cc2ff6223b309ce204384bb946a06ff82c4ecdcf5b5ab0e8cef268af51d8d4b9a1a46565785c5095071e48fafa3875e2c297a01b04b6b8e2bb56a7bde31d60462e1e4e28e4dd360b762b694e17c96ea150339b417c6dc70166bca55cc2639a71105366537b56d93a81d1594215b46fd0d13c12b099813f5a176849660b686f5464995050581da69763eae0871cee2dd0576b62808af46b46120d2d572d049c2cc2cb90cad13860adc57c5160bf3c1265ec28f1741a5631ade49c354cb05fb8bcc2bda74e625c93a4e5a35d52f48de12b4475bd4da1e824207d520942d1a684f4ed9e6ae958faac307fcc16013c9075bdc351d7daab10d728efef4dd1675b94c4d0aab920afcf7b86461da940a8856be0485a6dc2ea3d33e246d8003948d2f0a5d439b7a8727988d3471fe89616c69bdd9ed831eb19ed9a95be1d2d77d6970ced3557cc0ccb5a0def14171f84d2e50cbd4d6c0f36782089041fbe7af430408d1579ee94a443aed3cc782a96dd1e8e6c6460b261026f4d41bba4f93a14a18af6ffe9830f2cfc341330626685c17b10c592e7e4df47027db918bfbfebbbfacccce51177392acc77ff964e1698a88166408d18600a6220f3b47a97665e2d451a2e6a65eefb6826fe9fe88d7585177357aa4cc9e27d7791bd1763f26ca6db1fb0d1b837a3304ab5965ecb647f706d71f6272977bcb7ceb8e2354db9ed5bdde25f2ae531848fd707f8f0ba7adf7f099c7a454dee7f856ea1c31b06d606ff97d6e2454cd366cd78bf04c6f22c8b29e440f9017c2d9181253d76ad9017c0c7c9f233f404c97081e913b8310e937c9eafa57d53b85d07447a81866fb17855c8ab2b8781466df59733d46a4cdb4472d77cc675bd2f074d9dc80d7b06319f14f4462c48cb6ae27dc625ea8f2e8ec99e9fa95c14a7b0619f82a1da97092b2b1527b77aaa7bf222358e4012f0cf65def2a460ce3213e77513c405587614418f68e66e824874803311df3f999ab7f404f03c9230cbb6773e8c8c4cac9ca0c603ad1c453633f902161170f784ba0f3313e311d89620cfd1fe5c73967012b81de8d1860266bc739139895e911f38ad04664f7ced96d4394630d4d28d23e40a6acfad442ef3044ea219504bf1380b1202b044e85027ba2f150b832165e90958ca59940ccd552aa7a092cc85eedf8077c908482494faa30d0da37ba05d8f12d69a0e0d1da25a451dd4720f0d25ac863a3d486be908a1d5a17e35a8aa0c89a0903af060da1efa8ec99c4065d726a22766620feebe9e9e74d7fb2ff917a279ab3e45ba2f5906f8d55d518fc00370f112a370edbf3f8713fae71fb2b2621786c335d14a49f338e75b99d6e514616244ec244a66d9e25dc3794f4b5bb52f92e42a309af3aab04ee66987a8391e746df02c286aa1005ffc7c1371e1cafc120eff56494869567b6502166b0293b089f3066603b042679cf92fffae2ac317fe16bf4b87841b23a1767558bc9ccc70c8d050ec6ddded14b9683fd28a783198366175befd99302c25a4e886b5f2de63122df975a704e1bfbf5b97696f6905cdd1b2b2035814663c59039b23ad60a8788b6816a7891e68bf12f2e299deb4b401d151425bbb06b4005d4f8c6d187399adf053163131fbd744851aa9deb41bf1b199cb9db9051d13350d9f75daf35e52bcd8a79fe505fafc960f09e54f554b3c2c55f68eeee845e9c28506c543c7fdbd95211e55300f1aa41c2f45dfbf337b2167c36313e879aa8ba21ea14e38da60284fb37e68eb58fd5b57a2ac205976344fb91e0bcf15d446bb32d85f4f70dbb6df52428289a5172134c28f8cadebe84984a4a6c82017f34a780611531e3e1a491fea603c54cac59924069ef6cfb800d201266c45eccd40e93adca972449c8a6672337b2c254f6e1e1adb857845b4d3322c6376406da41e0c174a002a13a5f0738123ea8218a1ca670d87f1658d0ac263764c48e23c3065d564619e05a68632052688c552a6f15e77cfc9f0652cd214f9c0044463460fd4b562031d842da2e40f58584614e896d0cedec8a69f4021aab53b942b259b39e8c42ee3782165f4dc43acb1332fc580fa39df89b55ea0f931238a557c5b6d88ec93291ef0eb721ac7d7bb33c74443644606699822e74b32c1de3fdf2530cf44cf1d12cdf76460be0cf8877a50c075648b7303eb9d911e959511b026ef40f213b1cf5f56fb3bdc44b66a49e4d627ce35e7e52704db1a19fac9350fdaf64c6acfde2c9b0633e8ae8b6be2ff36b27ac43cac1cb2515220e5a87738972f325824fd22e6b7f8885c69e3042b7191d61b004364d89ed3ea65a1ae340944628a3e6f90c4aa194bb33730354d7711b16ac8cd7fc94c1b6589b151e3e0d00d25346654c9103b9de31166288828e105e0ee7b56dd7121542ec7c0345e9014309f9e5f86dcf932b7892805d856171551ab8840559f3e7f0d24c63d900163cce1f65a5873bdcc6546902a1957a68bc1407b7e52e90cf120ca87e05d41831339834858ef80db09fac0f7ac672761bc048554d8f1f9d4a03020d27b1af27e3b2b2f981af778ed674edc8165745239177d9613f72d6e5d65875ad5085121fa920b6769a6824485b8a73352f602ebb4ba36c452beb37c52f0f6a8d9fef3778f531d8ca712100bd19d36bf71ba14dcf2c63060af9c3d73e58dd67da15029d97a6cbbc746a84e8600913b1320f4c86dcbf278dde947f9052c4a865af96426c0ab3629ea190de96cddf59552e86e151a200c5ce043535fe10adaee7a537a9cb3ebfeefcd0befee356719664f43f6fce44de17865fa44b430739caea90d49129b841e6b9840faaf7bf319c6b0ae631c28764c719196f3454a2619ff5db129616ccd6ea684491e83e2ecaf26d1a0c00203de21af9cef4509b79961b0c3836889ffaaa7eba7fe8588d691276461612240477e115add24f036438bbfa9d2aea987000cde69bb6a72fb2dadf4aa66ebe3892cd88c34840f1e11f6d92a55d90306dc44d5f2fa5810f5f76c848d2d07ad793b66137a1a9026e338aa0c29d87e1efa095773fc58f4324c506bcad8c3401bffab14a606f67dc5bcebe14af28a5d94c2cc2a112a4ff156a2a901394fed2889d0b1f2474792900dc0ce619cb9fc681d01065484a8e21402476a1cbb48ba9e7ff611d969f839b9259aad21b3cf08f6522a2a72fe6e246a9c41bb2c6a20f28341712ac448b9ff69a352bf0331921932c4be73e90d063f543644a96f76724abb6fc1c6ccb2a141a03b506fcb8ac4cf929ed51c084ef662903b9704100540b55a488356dc7f082e1f0975556658e008b1b15f165c7619778e5c9d8b582468fbedf8b4473b4b4f175aa128ac47f7ed8b81530b81123820f09c5524d56b03ac7826fa3df532f89b110c4fd818382b1dc74dfb5421dc351e03231a3ae21aa500a68583a769dc4c29e6254e13616fbb41c9315f02c13eaece9710cef714357ae4ae8ea14a27adb6332847ac19a906a97fe12f91d367911a4c470d6c7ab1e4778b3d915a93454a7e4e59bedee0e5e5a14dfff5a3cb6208798fe22ae54a128867ac81f9a4f452808111459881a02789f266b838cc1fe7be3ce8569d2d8385fa19449c9884342249dc2d6985199a74dfeded4ba3ad0724308d5bded47e74ddf8cb78c1d4ef631c1fb143cc168d1df724e697bb7da3b8bd3afd3dceaa3cb29d1c2aeaaea024ae9b9f529628010f8afc4130f8e3287688b8d9f2a823af8a18cdb4819bff816ed0fa95048cb5c6ea13fe848b468883c41a09f17e37cd1d018437d1df080f507c0c9822cec49734568e78bdd684bef6b8df10cde6d803aa8e45593e8bec39a1e80127a239975046f1b19c6c6702a0e8070eae103cfbd5515faca38f097102d22b09525c7a8aff0054f77eebf5fce9ba00a226cff44384d256d2cbf646760b0a421ecc25aa96d1647649435ce747df8fe1933272f44139f2d2f37cc721e013015885add011d0208d0795c3607bba3fe1127e3a603539c272d62708d52d2f37d880e3726b0ac55b7406c1aca5038d450eaffcb31c88b71e91104bfe90190e03c50dc485131f160bcf75811115f3f57a3c12c12fbcad9a25685004f81b3e4e422a6101282afc7c3028b86197dd7dea1a61b5cf1575e243dca003a50930cbc517e7d8538606233c32ba37f7d8928aeeb5d7320c237255054409c105c2f75c3c60a36d7cb7a1632b3353cfdab53d43d73773e9c36c5efc847e0a819f2a340fc9e49907797d535e31c8a651ba480af015c98600346e04a2a97aaddcc2aa47af70d8f828b86f11e1cd4712dc4c46edaada701d62dd9924d7bccdef6d304be2a85656e12e175b76a6f353d8f4c6b0a941f2351f619c5e5740e5d9aa1dccf99a2b68c5d50f3ba8d167840e3faaf3b1dc4d0ff979d8e2b090ec916845229d18725b06f597b2f2359fd06593c9057f1e8a8cc475c0e4a3fe745919b721ccca99b888e444423c3a1494559e9345a2a901ed7096db378b5127447a31c518acb7fccb20ea53b613575a3b078b9b5eaf24b045f4ab110d996eeda9ec15d1b7bf89f4d548347849549ef480ef0ce0bf7ccab20411531220a20d3d77d876e105e02cebf2f129e906106912fa1be7f020c99e30d35fcba4a8b5ad342a228531d257ee47b67bc45398437b6826913abd58048399c490e033b07a917075800359e6f8949060e180a35b7d82574152a1e9e7998391f6ddb5b157003f17ad50c40d580ae3fd5a320b30da6a9d5213ecae2fe8215f7d0a26acb85f0c772d5603438a9d0edc7cf420c67bdac978d75ae132a08e518c77315800db2fa4c52871450a2f44eb94d70eb3eba47c7a28e910077db28a2ce404a29a9130c61bdd24cfa06ab6df2d688d7bf5a5a8859098313a4f057165e8dfb73fb9abe802cc8690a9141a6e5dffb2f508720ba006915f471ec2acdce5aaac040438f094b0ac947786e4360e5135cd229fe811520863d45128bccb41413d17d32f97689a1189964a009e0caedd78e264a2341b0481e5ac9414665501bc386e657c79b371a736205b770a67ef25174176893a0c9f2709e14363252a92ec2e10918a8bdda5dd8db433e0241a3cf1062f064b534a8c2668dd5b7dd4b2c1878a9f9c510b55d2c990f819d43e438d8e03c75ad39ddab498ca308bada6d51537826ca755870444b49bda83c51b4edf6283850d3465a46b7a5918f296c0b5040934dd76874f376a83ac3bb74860ba07ac7a00b267edf2638dbb85cf293a281fe73d058af830aef9d87c0170fa790c7bec95eee2595f64471993171aba06dc0180a89a2e29ddb6674d1054186e82d20d4f8164e164b078ed49772b78080cd5b955ae49f7bcdae20e45320a4be59874e7f591a37b46303563e99274777271316c9006d44737d20811ad68ff462d7cab94318d33e936fa4cb07d1a5c3d490c72e7e411e18f0647400decf95bc540b27702313aaa60c21c28c608930ebf40d629b7608a4fdd962fe78017f0fb0bd367ff2b258af13bc4d1e0b7d625c90d0213cfeaa9331ca72a1bc70c910deb150c0f5574d10324b6c5b09156eca40582bec81027ca271e4b21d1af2a4585b337042a3ca8b8cc7da9d808051db1ee8aa1c938894e54e2d9e2563d4a59d467e2a8a357293884617148c947c58a7464ccc57470228e7deef8e70146530069aa49fa23975f9055aa6b735a27ce4bdb0783afa24a4adfa493e1543ce6a567aff2226ff3b6541860ca091171a33b7ca9f4df459e8903ff845a9fa4d87243810d57d7ffada6bb8f24d247cbb36db877df7bda28ead8721b3ddfe147185140a8e9980631625bcfd8e55893d103a32e0adbc6877e28a3aac50bc0e86c65378cd44e0d240f4b78566d92f83eb0992e984cbc4f286aaacca4d6dfae22dfbc0f543425fbc903478dbab3343fdff9a94336f154c06127f43db2c87d3b0aa52e3b20639132b56bf01d871ef98df05966afe3cb60c99d0b4c785c53480e5c6d5bd3ed563525cab0e6ef924a158f2eff7a27323fe8def7763762a41d9b92c8f5eece23cb596efb5683a44bd490cabeed49e87ffac64e245a3e310e50547fa21a2922e67ea2dcbb9df44828a9af319771338945b16816bc0cc70a2d8ebc166d4ede75ed2028af56841e943da9e4d0d5dbc7520bae4c0de828773fb53cfa4ac80d920e1ef9db2216fbe7dfd15777833e24c35e9f8a8d13bf9e11e8427e5d2c791662e4c930a6f22f54e68538cb310bf2f85de14b76f7d2072a4af3fb17c5f4d2184ab904ffaf6353615e06ecf0c4c83efa8fbf4bcc6e40328abaf1403c7885a5dab800f2083f4e7a0d415bcb8101e82050a2f3329c82a3ea96e98888330d5e9dad3926189c03e8cea2f5283ef6a17c8dd2e40c8b328a12981b867596143b095abb6203141e85c623d48a67ca8107ddb7b3278d4aa0d9e2618f7d9edcfebc594d5c8045e8e49668895f1b1f54feb519a6d3d2cccc4e8238bdc354c92db4078995de9c5ce02d49f608516c7c4b4537a2986db55369f12b72b4a5114139829fcbf10f08b777b494fbe7b5fc6c8c11f4758cec291b9905d25ed3863514fc80470f0f82f129bfe88c28fcec4333686526f389f26cea3a525fe887cea7cd5d4a70d44d076711067639138539097b5af5161f67cde416e75ce085285474e485d1d59e2d003bd3c778a78b023c7b1387097dfdbcfd6625f16e435748c521ea2a4f452de0dcc18bde63533bb837fd213265c38f953ff8fdee911abbbfdaef2df8f5de6bd9f76f56fd72f1f2398b9aecac4e32e2f79541ffdef3105fd5b296705b925af93376a68972bd882ee81e3f4ffbf60c1aeca6743664f0ee5133fb38472a6c39f6317835e28ace65e7474e99465bc0c235819ab61ae6445fffd0159f2bf11da187ed9c9cc87fe10b67319fa6bfdf630602860985ad4784a18c9a36ff3f52a61ae28b21c9feb6a81e05085eee3d8c6cb9cf893636e5d1fc44664b55f1005f35b4eb9ec3ab93c4a6c01926c85899d17a437b7c7bd745fa2d36775c80597d43845884747f52720bbd4d9ab2129b120fb5d222908af7c17c68453bef0544646bc9b52492b6d7851837ddb1982d42c6a8a0a735b8a6ad9ee4e346bec0143619dfc1194860ad9861a8d5a477558952781b84481085e6be1765160240e26137f9fc3ab7fa7f745cbd8e9f97561953a9c02f9fc2d6a3c264e2096479106d956a69088c54d11655246cd93e12d4b810c33d930d9524926309874200a913b1c2755119f3461b39fdafd86d726887a8b0218c84cd78b716a55e10ff5764990d0870a58df4a8ac99ce847e9d9b5a61d1eace785f2280f460481a9501aff644c28660c685ed057d65f7465504273d4eaa5b3864439f23b1cad7489e5dff0cd567244eb0e49c23141047e6336dd1046bef4ff17e949168a21df1453a62a2101b179e2fa1acbd5474548fab837d4704d8328ac181b4b37f4e491b9d6c6821578fab7807c8d78642eb09535ddf778dbf7e3c1a8174a7fd3c86f90547da5004f371dc794a1f6cbae88effca0a6dc590d4c3f4b31c245e40e4d401aeb20609b41528bb8af929ba5bc4003972594b65571548e264a9af1f6eeb5c8722654d6d81b4a61aca5af2c42d5db597b8126a1276dc860342662f8228c1a0cd2f13c0709c6b8ec68e46f894ef28c775ee049d4daa253d8c78c2c2f77adaa869f68bf5c2b83826c181ae59b73954f131f4c3651d7ed0bb09d51f5893565574741a1c9e64394510d9c233b5128a06a76382daca3e18b778f8be8b2febfe94ed782f5baf445c41acb8a73a65ea98d8820823beac0a50afd1252a8641fcb8800c2e0694e185069929b9f8366450920591506b440b95ff6d931b818f6c8539c125a3032e493343c194fd5a506e7de9717fe8b43888d657d63bdfcee3bd19c3d021238c803899fa60d24e33b5c8263c434c44336a63a5b11713e9d748be5db1de927c7603757e127e912abd8fd42d3f9b6ddcb4ad2327462d1964cca8bbaa28ebc296a5de7746bdf516e82bf3065dc0c165457d3845258a6d819350495b2d3e3c303961eb8ff2460d9794845e5494f731c49940134a64fd5dd0a92958eb91ca13814d0c4ed78ec0004a581231438b66aa117291228abe2f585ccbf634e63516db435671f803ac3157005de9908284cf932fe373d18a8f0e0277312d5c806b4ab5f665153399fa7e1278f3d5a8eea451ed8c5d7d85fd4da9d70af5762b763caf15a1c0e7dae15779c285ceda55081391b4e35e224862593d219ec2d1835022a713958b709ccebbef3bd89e9d6111c6fe3a2e5c8d04e9485227396fe34fbacc317cb738451562f292a12ae42b106f7cccc1369990b95e5a84dad998e1c953177a40076759502d224128c2b9ea43c984ed1dfc09b6693dc2b4f1b8e399cb3dc1ceac3dbfad642a883023cea85913966618ae1648a35d4f4b292833e63449e42401fde88ccfb66100d462c9cee7ff211da2c09d26e453b499919936ee3493627ad430b2d9667016a6e94a65cc4c46a7d90235cf4a585bd552abcc841925b3b8b30b46e3cb7649c738f38228efd0747e7ebac029992b97c52654b26fd0cccae9e896c936025c1ccb9c4005ad5213ad1afcb13e97a60681bc50c0519bcf70a1c1dd77590a2b86788459a47f16a97909f78dc73770ae5de15a8364bcbc3e35b84a64e5e26d857daf71dbdfb5a55985579027e7a793593e393a33e22aa6959641305eb1227f43937b592886c52abd4eb294dfd22475b98e3a5b431ac678a2bb10f9967a02625250431087e5d13e4333f6c00add16799dd0f2943a1a68b032e7804d4ba4cdca1c2df58d927e122987c62091c633e33f5b133dda892b25ce8bfbfbb7520e77b4b6205a5cb0e79342f928f65420329477b4eb85c1d876368726573bd84d7d16c08351f793f935eb6fcc615d6d4472e7f6285f9d1727c6ef889301f3839c179a7da1159cf1ad7d3d4d576215e8152ec6fba631113dc69c03dcb95e9f8a06ea97f596dc9ce39658803a35eeda7880deda2eca4d81560dc0b80f943842fa54e81d78b2eb8285ee472368c3908e6c29a822421d6e434c8dac773a62e8237d5a99d2dff0fb1a805a08bc23bf9c737d53199a02e7f9ab6728433720fdefef05a79659f9798e8436fc634998a6bf77a0921268dec01a29e0ad821600066705cda322b0942b6a5fde571a61e0678d80ebd0908230757f6142129ac318509f59d04041249c505055e7d62698c7006d610f7572f6cb1a025124cff694152481f4a062a7435eb76759c4c8c60b0906bb8230e1addc5c45fa645e1b0543e1711ffbbec4468b207ac1ab1a20b54ff0e79a9412044469ed2fb5e1179d92e24be3dca770398f794f6f5ede03d79a7108771b1d886fa7a997b41cfddf52237610ebe1c029a8f89bb211554a488387298a3c21fb0d40c96909558920b2d0339e9ba249019ae390ffeb99b7cdab6d33a392de967400f7f024888ecbf1115b3033c948c52663a79e840bcb3cfbb1d20d631fd4ff50db0f3a745bf8a98c6edf330c72eae6f61b93ac97b93d6f55359ddaf76d3eda3906ae0e6ce2465a0818cb55ef155389602bc8e4757075e18b7269a264b321c00ef58f274f599a77127041754133c5891c58ca66c9e671e7f465a4bf7c027dd1f34182d9fb153816570f6f40e602cb2250039e5999424c738698471cde073df46a8173569c6db0076323ee137b5164db77c1a7acc560d77c9177401520fafa9413bac9e23154b274c6023399fcb301cf901099bfe0dda78f8fc8db75765d3a857e4bfc5cb79295cb13a7a8c654250f9d6cdbc7a326bc416eca002cbceb30f4529d9dc36d7ca90788174e5ff26af9a45764c0a9655f8d8dc8458c4b2af0a92d75f33a511554ad465cb3ecdfbd45eb2a5e91a2b74f51cd9983bf92bc2d32b3d4e034bab0479304e559e908305fa7add04b986404372cb39033d9a164695ddcabc884f72108b6d30239d4f8434e53527a7aa8a0c6536b86029bffb9228473df97462d41de9d5838d02f364d2240f2ff5046d4c611860c8bffecc35ba2550a2c447d14185bc09ae28bd59f2cd1969ae4d8ae010feab22a71f5dc4d3cdc5d424ef1393799ed5ba1f23e33cc93cece99bea6fb93f950b377abee6c80505f0cfd23acbaf5117fd54e5634e5bfa0a1f1208eee8dcd096706ac748005d7c64ae940dc7d72fcb849f142ca3fe936e72c84d4d521aea97dcbba3a74a099a8a8cffe0f45b52b09391413883eb161da7c38efe86989974d059c9f842a7b144f0e168349fc571ec2553d549f0de50ff478fe5ea0a24a0f106700e8f56ce22daeed89574087f7fa6b634673eb54980022c68aed03209c423a4cb53a81baec9e4b44f91bdae3006fcf61c9d661e4d9b342cb5a614a10a2d8fefd473c3ad56da07179083be44aca65bd15d999173aa933c1daa50258991f1cab2efa04cbaaa273c5584b6113f6016b8bdf79b8ce3e62fd28d540fcee28bdc640725b7ca1448d8fcb7571e30e91f5a6ba0b23fdded28858400f370178722f5fb70538ccf202e6beb26d81293227c3b651650ba9d8f2f3d61acade1fea2463b38971bae63298a6cb2ef4e84d9c8f21b2680d495cf2dae338cfcebcb3150ca238e2fa34173d5c6409bacf91eae00dc8c4a906e06f86a41ba571961e79634d0ddf4887f9f96d291e3da9aeac649266762213a347c88db941d3519249f661915bc24e82fcb0faabb0bb5ac30f83ca7f1e826e9828e7cc1bf480e710d66cdaf124e1bf8a214556ee67518131e4e7bd54527d50c3e1535cfc449e8f5a45768845093c60e9b9628c233c92bfc01747eb181a64d165776d0b22ee13418fbb1a172986b3a20a24dbe1165a637ad3e990f32a50ca8818493c062e1eb4c40a562ace5e5657cbe31424ec248815330ea675cc0a291ccdca40fcb5831a5b7fe5f2af6a52bad90ec2113d19569fdcc3ab1f045427462610610cc211b83e8cc62a3274dda7c07faecfe5a94a41686afca89513f265207470495e741b9aeae82690ea82c3c57d854766f0b825037652e87902eb676a0cff77cce229bbf0f5f9fed23aad95b55c13677ded6cf1be087137880e06bd0cf71b8ed39ea289a2329a98f48bc4c44d4c54061da9f21dbcb5776ae3bb7a4b7c0baae9ec94ece7ec8a7a8b80a19afea7da117b641964c94b9667717175754ac80d26002f3736e1482db3fc840a5da348cffe13308c22a43f4a11dcb9d0800af0b7c20d4640ec0b6cc2342af6490cf3017a6e518a198f1f2290b11ec50db7512961467c6fa9ec01e841a5b84fd1ae0abfa5e6992eff181899e142a1662e529f7a4b96c2aa121b97540aba5ef9cdd14346ad3c166c7bd18946a2fd8a2e6feea7e5238a2821dc0059b6078120b2f8cc6dfb65de819224593a4dd40cfa811a210f8073836ae4e1da694e72e342718e7dd355256323c11ba386bacc59ca502e401e3257f9c2e060ae047dcc4ab0325a6088708a6433a7fc00e2f0beb063b7578b381001a8a711a98a05dd2b591ecb05b464a073482db1fa11b49d2c68cf71825668a3ad87e2521673128cb306a815548d5e1ecbe66c0f74e426c55e1ecb0e12b48ad5e5b1a44b4280f10aea59d290e27059595e92088cd523fa2db62275624fff44773993fcd116cbde923274c58b0ab45e32c1546c034a158e6a5b30145ea503da7996d0e7ad34be5c6d5bb8cb595a4b27a6ce13003b19ce0bd01fe258834645ce122ae22511c5161d628bdcf0f801e33eb7bbde4ff37afda35e0ad72ffe8f269670e1bee17d834a7ffce22d3bc8de64cbbda54c29a5cd0683068306346421ef166a21168a21c68f6b70842ab696953f9439628c514a295329a47260be0ec373c498715877c55239b8fa67a91cecbf37dbdc5870dc8cb9c17f3e5755d908abfdb6b586bca687e8526ef69c150041507e45a66d69c2f9f29fdc04bed56ab558469eb59b80f06b3748e56b3fd3600ac71c2a9a48434b46488db33538f252fbe79459651a354e3885a8475388adc110f08f5262526ea80f3b15b4dfde533b50bf7d9cdae19f6ac76c55ffd9aafefd981fff07aa92406307744a6e668750ca47fde6eebb6973325bb1ea550c72a8e1004328575709872f0870021cb2f0828315e011c5ea2ae1d0831516ae6931238cc023acfc35e933c3a44fac4a9f137b29a7c4a4f499c9a86931238cc02b50c6cb74333191b24c37f33134326464cfbf71291c8ce2994c866518f3fa67c2180e4de09fd96233d8a20eafd96e2fc60c931ebb3119dbdd1d6bd9b1bbbdbb1ba63bef86114497c8ed5162324ab92b252633e93353aec6a1c2f82ea5e4dc93acb56024c7c86566d8cc30cf231789612d774a96f24377f795bbcdf5203d62188661f10a0cc364c4aec062160cc33029b12f24e65fb29c207ac430b98aa9ebc36b5ac76b5631468c433df699e3ac0ef73634d98732aa8e4dfe7ecaeb788b07c4f3693048bbc03630b02768ed058bfc30293b66e6f828c6e9be7df8f00192c2e19f0f12d02984da3239ce2eb2931455c8b0218a183728e151d49095e090430d798897542e7ac9e0f0030350a81728dde0440d99b5a2640316a6a2c5450e95f9aad790c3912d9d53dd38eb423ba523575653829c4471648601c81083f8d188961aa7a89186276a0cdaa1a3e1ec2a73d5abc94436654a1c894804612938e245415eb34a35b4acdcf080238c948ce0e086071021a186b0ea55cd902a90f88113c8c30fb6a042b3ba493ff052032b66c8c28a1c9470c08245d27ca6a25543a6a255b51857a8ff8186f3851c5c23d001ae1c1274d21a657cda3851a671c08fdfa790a08cfa55fd313f7bd487ab1b9c4a617ef6d9e4388e7bcfe9e7487051ae598eece79c9aa6693eab99fdcc661735962dd89666052e622b9b73c3c9d628616b74cd987b394aedd63e7b02c2809a00cdd7be0423ba757e3f4d7ae6633f7f9a842a28a002592cf505ffe2a5fac854f91a90f50522a06e7ed38b64585307f303bbc5c2d23ef38f88e6a9fce5664212babdf64a4680e021b2ad2781f918ca53f9d7333f95fcf9cbc23e55f62c60d9639f4a3ef6cb6221fbf9f3fbc1c01030f0e243abc5ca3e955c96f6bdd7f8d70196401419b1921c3c3d0a68c8454c1e1134ec22958bee927f0c8df3d3386110f971510a09aac373baaee1efd81917a7d59d3776c7766e5eed0760c188d3eddedcedd47d77fb6777f7c605c70884b8bbb179cec8cc3122f18845cfc89c25c6e8ede8e87883ab78459432fa17af702eb6a5a9dba0968d3916a4ec97de8e8ed7fc40c71b5cc5ff188966dcd238f1080c74a87119290284225b106088224e45b21079d2220376a40b1aaca06c60ca860021635ad18e6e51036ab5c56be3820a27451732c0be90a2b58ae08ea4b80a2353617e4f5061607e12a930325ca9300f238503a62b402af51bced4144d4d7d4c7d11414da5beb86a4aa9e5434dfdae004449b16d3475b3a9dbc7eda79724eaf67448ddbedbbc58aadb838db3495f0c31c56e4e0c153930e20b220b787531c4c58bae4ccd9ea8d9cf8c0b126c7183c5f12e1543610b2432cb22801a54fff954c593106d26af0ac39c161796640386618cdd4036d920a59472092c5a920829a1c54b1750aca0b224d960050d590d65862c0d01ac494fad17528d3f6fc4f5828b11473380410e929c205a22882d3ecf2cae1ae4e83a0d72185feaac68e8344eccbe307e3a4cb5205269542f6848690c61894ee188af56ab55e428c9155c38f1e2cac11169440a58b0558c5695115de934ceb2fc38c3801ad2744982290b23598a6accc2881a93862003e84ee6933927457129129465d1b8e0500336b9f81024776c119471118286a804e362c411d762cb0e2dba48cae504397486147772692207def1d4e4353bb9b84068c7109c3a224e4a337c914a32801758d440802050545da519ba0ce0896e759566d0a244b5ba4a3334e598814969062230f0efcf565d6f6babaea7daefbad5c398e83ed7908584d846ccaf8c671e388732f3f22fe77c42f40b79a96e128c2fe4275c2ca5eaf093da8c04887d3c8277016d905543a061ece91ccec2d33898098e3cb1836e6d79c2b21fa76c19f6d987e9c4784171c207c21996a19ef63bbd2bd49199b7f21ac6da6582262ac60082d228652c21b1262645998c22d98c61034f4e46f2d46234d1260a45050d5d028409456d44201ddd8004885ed24c9c4a07b93fb953739566299aaf30169723b99117c98d932104c4d0122a538e9870a9182ba80161f63c0df2c8fefb917d3c7aaef037ab071acefa537ff007e9d8c91a769e4a61fe8e6facc5afa381b6a22520e2487b47b96b8ff25ef02f3a2f1470a0d03930dfbfc5878109b30f39f662e488607edbfcd9f3ce87931f11a5edccac82f13ffcb587e1af3dc752f3b28f44f40b7a16cc47157fdd4cd7f46b2ba09d1419541745426713db3eaf4725102f3e225ea1eb6d6d6173767936085a4c4822b3f79af92808ec6f0efe52330cc3b22fdcefc06f7ce9c110eb8ed8bf2c22d4af07a3baa7ea9fb5bf393d100790e62b4b284ab08c208a96111c69ea8fd9dfb93144897bf8de434b69410d57df030dbb97122d980d70659a8ef10f7908480fb53044c92eaf0024862f08d78486eb14841fc837d72de58361c762a93868832cd4eaba2a46432ca12449c9fd8341dad81bfe06ec092ff8172f3bba55e5d780bde1da5e07ba4a4f05fff2e5cb97da5f03168c2ab8cb4f676f646dd6a921585986d2b0d3b0659f61588c40acd1b1280463be61e9004850595789071c146009edba4a3cdca0c30250578987293c18d5f07b8ba416282dedb3e4ea4a1e1ed7d5de4041c36deae17352da750f32ce32b8cfcfcf21013a122833aaf23659a0c7d688cf41a8dd3132a7a47b60d82cb4649bf99918638c3ed1fda36ec4b634616caaf2b7ce3e9084adc19f01fa518bd2b2d758d3b44c7bceb0d8621b581c32c5e2f45377b1a07c192f624af582f2851a477bf911091071282e699cf9dd854ccbf862c47c5e44bf229814d71f7b0b68b8efad103d1d373c14741a94361290e0cc1cf584f9974dcd999cc9005b835f3ec83632b7c1179996b49961a856a2cdec51dacc50dacc309436330cb54ccb0ff3a9df1ec59307745d4f4f4f4f4f4f4f99cc27e38bf18594c27ca1cdc77ddb3741d000314954326d8d661b315a557e7cb23596ee8dcb9f93d2ae7bf94bd953f9924a83724a95ccbb9bcdcfbc179c911a1c82ae8dec896d645f346a2eb6067ff1c9de7c91696fe44b25745a098c14c6bd029aa0303fe3e5c72316274eb1a07c39e38b465acc17dad0afd5cd2902a500e8ba19f12bcc179960d080c6f7efcf8be44fda715e94050909090909098983268a6addfc4c3ec641937e554013348c46ad2a3f1a21b9965e4c325b63a590b115e4394258f2a390e74496fca8240e7d2c8a4d362858edc7dffd5412908f3d0b8e7d404d7a16c85f7eaafd88b25f96fc653dfb11ed9837a605195e0bfa91f7145846c0c2753ab51ba10723f480668b369a9d95820842d0d09f78dcc96b4ad8010dbb656f1844a914e60ed8c5485cb4af255751d1f217c3021abad04e7b933b6571269dd76aa99b406f2667a55ec8012b21d085804cda096d8dd49c9476dd3fd8af55bffa1583d7c407e235d1998aa6a061bfac6c4e347a6d0dfe4e0ba5c2688a1a7f33f21c9a45a3ae24ac3cc799bc26fe9c9476dd3f08ae564c948a100410cfe9d7cbc90926323de938adb2803abfea406aa30353e3529eb3d8a1a01da0159b6c036324f6263e17f109ce4a7ddc44ddc87368c450a1fe5da917a35517fbe411f5efcf3e9992c0b252bf291eee1909fb908b7060518a28d3aa5cb492de6bf7b51d0150824d6e1ba7fa63f4f7e132fe7cb84ac21094fbc17ddcc17d5c887dfc2020e5730a07c7d40a42eac6defc622a05d48ed3e9612e770648ccc004b57db8da334002864bf5a76385d7c2b362df2f5f074f8fd4549ae6c3473e906725bc447e10b94d44aa0c2212878e704b57ba90daccbc165a537056290456aafc1b8db33ea8f25dd8c1098b949ec2812282c68a83bd0c8e2ca502f6330d764464fe3958056eb509c12a69c815133190f27584a046d91648849478108251015d25212521185816ba94e2b81e68ff2a0931a9d8af6f18c6428da3d2fe3114e771d8dca67c2e224a3db37e98c5bd4c0ac7fc28edbec33e1b50b56a50feb2745637b06f6713e1075a7fa0d8739dcf2d240d2a69500a3528352bf46bc8462b603a66a6d0551212aad86fbcc92859888d3c466a50be00aa501551ea97c53dcae3e9d1625640e3b1044d793dbc463ee7f98842c36daa12ca12757e412410277655f9233f062168b84ffb1d7d7808fb9529283666a6d99b1eb21f7d4e4add6d36a45bb338dcddbf0f40b32bd95a93d2676262626abd8c3c92e80ae1fcffff9f3c74f0c0e44f791a696664907037604c1d9fe051860e51c60892cd33e3d91926a349a49991e1646a68e641c9b0e2bb86a780523495d93c681f3a7662f849229c4f413334b403ddb523c4483bce42317ef3056f194e345c97cf8ecbe572b9a490cf8da741973b0d6e41c3e9e2a01df6666f76d9fc4960760d13dbb922ac18f4536d1f4f8ca7458f025ac40202e35371d1def4c3c0dc97d0033ae39391c105c5d88a3e1e0eaa28d58e50fbed53ede0df9e5f48155277baeba672506fcbc2c9c582f196a5793cd4200a6c834bb027f433d1fcb888461ba59a4341d3aa54f854fecc04658287ca5f68233343433a8310ff1ef9df4f93fd7afce3f7f32384a948912d32d4a7715a1c0edebdc0daa06117b64610ae2964ebc2deecd3b08d0bec09fbfb855bc57ef1eb582816317fa78f7eaacf1f3e5ba54a75ff1117ebae52e5a8ca67cfbe3b85a3b32cee0fecb97e347aae8ee8578e4a49daf863588f9f3f9583ab0f4c642a476318b61206dd1b8975330deeeeeeee763b4de7d90467409b06411bcf46468ee338ce9b7783a1eae158f2632592df0f0858d46b38994a01e3662a076bac699a37350fb5715b2a7aa738b5198cf0054fe3540ecea3810395ca81550e47f584ea0ed55d9f7dbdbe70a91c5db9bd49e5f0caed8d4771c0487130606052746fd893c1d1e58895c66c31a8989898182d26262666c6c46431588c8c311ed3311c7302bfd8c50cf38446514336e2a1d496cd07206088edb3623cab8028a80ba7a7713819266e18b8f2689c6f4229527f884151a4d07c94204f9e2821c5b69cb9a0092b4840b97b70c5513061b27df49db3bbce93a06d65a3fb1d25879928534cf041fb2c15666ef6d2ddfbab06757a1ba73b7e389d7a7737b66f9ba0057dbd48e04e9d3a75ead4977a0f9c301a5a52d42038a345431eda6716d72747c4a7c9556471c2a589cb15c58997902926f880fa2c158ef254c3a74bd35788c0fbeb4a297d77e3faee7e3dfb294a09ba27ed966977386b0e58e065e7c60c1d68b82e1d3a74789d0e28ee2e82b8bbbbbb5f5ca675ce3f7ae156d9dd940b3c4629dbc4141d9d0f596989a61a3e85120528dddddd1d73772cce06fdf7c6bb2c8d954d83fbdd206f3bb3733132d6e43b8e8a7083b92ba0fc73ce39a70735f161cb8a4667db2fbf95ced3689075a46c273c8912585c477614bfbb45a8abe4a40b126c9c34dc3e3831738f06f97d70f5f1e17e0f1f3e5cd0d91b7eae09ede183db6edab4695d274772024ce5e70f003f9290cd86ab2c450a17b91e9888a0438cbcb8ffc18ccf04e59e8d836dd7e5f4fef7864a7bd8a250d73d46667e0c8b8286ab1d5f89c2737431f624185058517612d0fdd5f2036b4728818222e2729520690853e4c95a8aa281aeb866239818824a08945c69024915282aa65eb3cfde8c42775775f7bb068ba06b43164e51fc553d9fe09947d2753c14c5a1788009e7c46c2b3498f1a8c094ca39ee72a171f6092447955f5d7a340eadccad2a4f20d95243bea18519ba204de1691c6e41e5dff53929f51b0d12cd5fc5b430c405f2573ea2418dd3534087a2108edc5d623724e6ee2ee5638ca57030f67247e28e64ce22a8ff7f838d6152a83f867dc488e66373ce1857f06a7a31755d47b4f1f4c47f148ac79c3c3c5e3d0db644794124cfc67ddb1666af6def1e797ad9164476332fc398962512ebe1c2d7e8f9e8ae9bf3eb71a3c5850665d6c37d9cab2138d3a0fc3ace5eca28d4ff553bfcb3cf9a48fbe8691a57d983cb85246bec065b92b610996982020a8dd31f3d09e5e6666460cd38a9410d6d666823115aad5641336040436e794f31826469fe6ab55aedcdaaae68cc0f5ce980ab07e90c82814fc4cb781a3df6b71f44dd403f05ada599a56e0a0dbb89441123468e8a1c0d79e9ffd93ec8d6e0efe7c0720ed0a2096d203e9e0f8fc70edbe8a0da3bd9cf148e2835ef9be1ec695a8a086ac842362d90866090bd41816d70604fe86f4d0b7a544316a2c12d579cdc9091274f505f3c61c26408131f5e0d2ecc0be8d72a3289155ee136c5cdc1beae03f766569bc69993c77baffb81c61ccf1e11f68bbd7fcd7a57b520e857285f549957a50d7612342b92e4430d509200a19ad0cb01326308fd979ca67d7326314b46d33c63b5d7467be34e360b1115435328b122d4519efc3d07e6b51ffddb6bbfed0dba7dabd0bf793d1af427a18924a954654b65a52a5dbad544b0df9e7a305ebb521e6aa2e69ca86ddb8c3a339a935277327ad0c948a7ce18427b66764e7376dd3f08ae56298f480af56d3427a55df7afad3414aa7bd25ce9289bb398b795ea0d45f57602c6f64e1fc6c873603c877eeb35309e4e08528db37d1e6e40088c944783609bf6dded2814aa67f6bd4429c95dbaa687e74c963b35e8de46d597696ffadd488605fdfcdb8c21df0f9056cb63f3c72bbc6373de6b74f0146b65bef6bc537fec07c16ac45e9b3888b26d93d8172e5663cc767fdf3518d03ae3ea5cd1073dcca3c10e2af47ba401bf0f08743ffcb8bfa908ec77e353edf874b8c2d54cbc22290906f47f65a48c0da5734257980ebf12164b4cc2201ec64fa741ef874c413ea603f641bc4af9d9476fbf5583197ff9f2e54b10af1c0601f9e964afe3ada47f343a67fe8d95ce8e4605c90674ca84fcdd395b4d7ff71678b6c68ceacf23dc205477ff95e76c1f2b995f94b287c7c7f341a1fd27a8d28b51a5b74b489654e96d7553bb37b2ab52feacf263ca5ddce3c6dcf3afb6c68ccaafb33524144e705f0cdbb75e83fa580814a2a4fee8f7d98c6be6bf59669dab95484a438ab817b2f5fc0889939b3b78da41465da52737d84149294992ec411ba4f7424370b9719669869716297a9c148df3ae55f73abc867f7d76097c2574a7174e15fc4b5d50872ff9cb2964ca2ed5ddddf1812f35fc69d5fdb80abae8d75daa1493d1578809932f5f5adedddddd9ff6a8466d956e8f8d5a4dfbeeb92f1eca300c23e6a373c2501a44560d45436b9e0685a0daf7a980a23e5c0939aa3fb42851da2729d79e5909b51feb2fd4deb5cdb25578f36db291826a2d8b14b8fa2f14285d52529ea4a43cd12289249ee8d2c4d2d258c9501aee2bba0e349c759bb33f206ba571c23929dd710ffc81f21361cfafcad1771f6c20e857a41454f9cde840c30eabc293199c407a6bcca8b1f6f311b5e75c7d50fa7df40616e7c7829da385ac038a66a95dcd7c41ff8e42b9621f0cf10b7d364b8dcf9a4fa4b1eb86b74383d0b75016640213c8c8ec1eb19732945232b38c531e716c7759d37380809a00654f81eca380fcaa3032fae7de70f4ecb47f2b30b30068a0fb11e8df0f05546a0876529c862a55765f3c7834b83c1adce769707757fe569b06b7f31aafd9d75e40bfbf705d2b2846825acccc2c9955df2da9115d59798286da5f1bb1f7d0f323a4e74748ef7e1c04ef0a614dec8b086145212cd5673df1e5f7133beff66e2a5c5b2af69bc4e54a9dbfbf836b2583515ad92589b667ec53fdf601a558d83ef5a90f889b5fa722807d60830cce5feda7170aa9a1f6a86deaeaeeee0b3f2108e67ae033f13fb29fff237b08ec6826557e33a9f2db3ef3683a677b17ba66f6d042c37dcd6c57270e7a784a32425d2514e4b0bcdb02ca7533b804e599066bd720af409edf1f00196cc006a7084f34039bd3c2fad81a5cf931b038d10651962455dea6ba5d2a7f0536c747f658d095e734c19e2bf77eac2d53d897419ca05ca5122ace2dd719f639b22f7bc9adfcdc23f27cba867b40df091535d4910197989d6de1bdd2c44e287f051a87824ddc6ecb8f908406a8fda1571b209f90f168b0f7b5e2b1e113da3d1a0dead8b08d04ec09fd08c09e5731a0a83a27a5fc3d8f5461bfac9edec67e56ece3b9c1b59253583e494a8202a5698b1042114350ba326504fdbbbbaca40b13264aaa50a7d6feb033298defef1f90d7ac8a05195f7ecbda9517d2ee419d9d16dd8dceb4caa2a32d550175a13852523718fe905570a4a4822e5e18cc0b6630fe19ce9959b675f78f20723d7cecb7e6b01f52ca7010ab7f22848c0f50647c80a2a4944489a5244bfe5c8f80c2748416a10a0ae84f038b653f9ffd1f3e8ba5fafbecfba781c552fb53450985727f74f78695800285092682824aa8abb484117fc1822d4f9858efa44b19dd37c77f7fd0cdd05ed6c90cea1ae999f891e5ade195df8ddce539f15f04959f1da9b22fb514d82f5569d506d45daa61a8ee60e4853f7b8b880921a0404dfa81e2cf0f9bc90b1afafcecbde51ee439254041819af4641f1f0828eb57f64c2a16a26abf9f263dd8c7e79ef8fdfc3451f1c49fc0b2a2b601c58f5bcf3df60179150bfef1e30784bdefa77e59d293f1531fd0fc38bf75a075e2b2f1901050931eedb1073202d23e36f21a1ed201ea63232ed8a7da4f4581f9d8f764af7d3f4df6b517c2eaaf67fea878522f84c57d13150f50931ed473a5c04f10b3b09f8159d803a154fbc1d0335ffb7e7a780dff0496e5e3e535ec427db84da9cfc96bb2af5b5e93cd07dabe16c21ea5f1872d5419fb80fce7a7daeccb1e7b1632ec81e4671f0b1890d7ecd74b610fa528e0ef4abc865b3ee42da45ef29ceea55e1687def21a969605fd1a7aab72f7521f35c84b6dd420ff26a49b0a4d71bd76f77f47c78d0697bf30e2a8fa57c6f622e8462d647e75ec34b87fa5f2f7f2224992224746a4808179b98290b06dc9d6d86609d6060a3bbf79a8a75e5f714531c462c2a47154dc6fddfe432ec291eacd9be12f64241aff16c2c9698855a4c4941a32d2875cc4b193cd0940d3efa618bf947ecca7da3ee637a0dba8440ff6243154340300000aa314000020100c064422b150389e29d2247b14000a73864c805234944643591224318c428818420c308400600c101a1ada2600cfb45151019851a3f4ca9642e3cbc9e9e230c410bddca5922151eb6290133dc8040710390dfa9d5f2ee64468b80d7bbbf9b50c6a5f8db9db7bc1bcdb5b99a8ab1417d21efb8839dd7eef530afce31d0b0d48aba7fd31c98afc201dd4ad87cf68586ae87da0b73c0051f036bce1c9f10bb9d9ca75d0a548cfc2f04b21e143bb30cbabc158702965b9984b789d054b0fe099a6802f25f61e62abbcaea765bbdc3e6cbcc26b135de1d173f2bf57e8fc0fd30dfe28c902297d465cd2c6071cc1711a58b54da2af8dcd35eff98c8983a40eba74339db4b835795e46ed6de5bf7680a20161c46f356cd46ec6ace0e307005ee094ef35939c959e05e7502ed346a00d948eb664b84ea0fd76602d2c4df7c0c0e85432409a2e4ff07d3efac79862deae4ae6633d0f8980bedf9e1d6d4f3f185b9bec6e75b0a20ac2292149b94301ff592d1152560019f0896466a9bc403f9a3a599624420d5414ebcbb4642be8297680a4394efa251dbb909bfb856a465519e302c1d58c73c26f1cd072508acb8e4f6c0de5976b654bc022c0bf059154ec50115f6a43a7fe5d5c351cc885a1c8a568492fc6688f56678ff62d926b0cd78a9db13e0437b320f81ae1533d5d9f233600ba074ebb18800db48727f031e718641a090c8c3051827e9e649f29567b897d1d03dbb5b1bda355624c9becb19a793a07af76844b36b903f3eed7d13bc65189837eb28f5a6ff06a5ae00af533206d9a0b10e636db6ea0df0585da3706480490c8821838ff5b65cac4af862f75ab69fb17df951268f7ace8eca935978cab224883c18b96d60c48f77c51cbd60b0d162becee62040fe7e8f281813cd569aee986fa4a2abdcd66322ea8891ed04b10f5ace5e7bdad198ddafd2634dac9fcbd12c25e01de377a1280ad60b6d78717668c492518025b6363f5666e28537bc547ce8f0b61814684452c48ad1b77e60a60f81578d9710730185fcd868486b2977a5b38bab058db322207ff6c23a064ce0472356f9fb72e5d0769ce2d49b3690636f2adb9e9937e03fbeef0207049a13003c28153d0762e5eb25e380af784f8966daf63e9870d52d2787c02fac858b4c47d6105379ae144801d963e187d1cddfca6730e8bdc4a816e28752552286f7d182c57429cfdc376ef3d673a9e8e43080a275dba9512541f6c2c8bdb9bc08e030479e366609660917d9dc516f60c1694faba7be3b49eed38f89322139d6bbf14204b46ed3c8c0477000be3d3e3a8529c1983019e5b87b7362baee849a4e7bc9e5798c2979f3909288113db26d78ad91258c30585b7fd390efa1a9ae0ca5af938e648e1a06021a961ea51a796e5c29a0eda16a72c8b298aad7af5badfb3dba5fd94f5da8ee00ea751e8675a6180e552e03d9f01cd087876a7bcaa3266fc40f652ff305dc5cb87b22b7f6f32c7d0a69ed5d56baf6924935c72733ec42e7a5342072a5e0c7977645060151b4ebf484ef608807c17baae0cce493f20bd65f20f3d00cd5857f5584a05863760897937d0b04f8ea5d85cf263fe26341e0d0896fcd69d58dbb6ff00514d4cb0ad7cdeaa005bde134efe0862e7ae15dfab73e63d81905206e6363ba1a3475e15bc721bc90e92568481d88b641266488435d6d3dde216eed4fdf199359e04c5ae0dbdf5c3a50de72f2f452cba382b003b584abaab53659757b51f6ccebe345a9ee57ac148f806c0f7a4b386e32a765651a45d14b7405708a8d8c7114db2b1e13cca7e9ed21d465256c6c1a6d0143bbdb3600287fac95b9d13b4cc504ab3e4e5d97d5fd028ae8a92557592f2012afe7990db1b9ee1bca96ede4d3c4bbdec8c979ce08569112729833c93d108d91b7e0212ff9f2e484f03d297edf234fbb4f1833a5628b9a1add0ce938bf5b50b1399b8341c17ef00520c6a10bcdb878826bac303a286e00be168961dcc83115f5d1eff3521c85569ea590cb4da5eff5c2ccff80546487f15e8d6dedf2a81c60aa8e103466dc75bf52c691f731dbbeb9044ffe12da857b36d23007136e7b24f1d3db28db579c0470ca200692ac2a3bbb79abf16aa53d97c3d4b2dcff097bf68563d9dd21be546e641da3c60689db8417fa5fc6aead8d4484fea1c55ab3a2b24b851752fcd4e74ce7473d036ef03a3df503c2947de0983e82648e7c9685b37f8d246ec786157689df0362f91b6887737efb7f4acea4707cae198add6e9e176aae46c956fd416bdf44e8d4ef0c1415bd8e305e8c3b52603186061dac74f078d86f0cefad81b6524dc9e89cde71bcf73ad0db24c805349958a17922452adefce8cdddaa0eb1f553b006e6d8825a41760241c8f45e6805cf5aebb45000187fc99f2c91879aedafd7a8eaeab9db19ae57a65fb9ace508b8253a279d96fdd3dfdcc9ddfa85e0a7fb57112417d9e741625f337ce2a6569362e8f87e159952ccf799783c830d5199443e66c30e0fc95acb1b431a30ae451a56c94e98039899d9f2ea24598cc7b3f6d363a5b6248425be3c213165574a24b8c867a3dc4b43643410a826568a0e1891131b22f42006136368ad666e5d429a28e46473f157e98374559d29223b4a5314c4072e1a8b0080c1c1073a484f09504e8f30264ab5c5c1edc05d8e2f9fbcd4b86be5b6774dbf3bf3c10c51705cde0ccfe45f19c056288801e5768da31fb4d112fb4a0a827164d33526bad5c4a38d966731f36d792f3636c50267a092c5f52150b665896f1941f2d2a6aea15033805ea2465fafdfa94d2450d4acfb45e6c91bc48c2807b50da164cca7d848e8211656ab39d15febff3678c214ae11201b4beb9ae8b5f075b4e17a0b08f1ecef2dc53624743e20eaf33da156f216532f64a4dfda7e2f98be5241c96426e9a4dfc500dce2f202e276d59ed82002528555407d9a8b216d7db0e4c79621cc76579e6cc7ac2e8ddbdf2c1aaf8f263f0002b0410a50cdda8eaee3fe413c1d5ff6c8b55666e6de9947c21b952d650f112abb16af715c9b3525a59415724ac4fd808fdef64de05d91f43a10a36da60d2e847e3694f82686c174a00c84de0207f9ba02d20b1e73dd60fd645372245041c0be35f37a46cc77b83240f882950a6912e1be9de86b355c99d87d880cbeea3426c06ec937927c65f4edf5ed52dc224a3d280714ecb67490569c92db668bb78c7ce42e41e16f28089611362e5ae459d1f105d11947dee239fcc91350de0e42946e0f202308a80445749decebaa4a7c13f634acf318b3b0a74327ef2f7890a40162969c29ed09152804966498ada0e7cc6c2d3c6345647c6f8ec41093c7e30b0022ae3111e80efeae238fd5eb426c3c2cf35f81fcf370fb93155754fe8763d7d32880ce330beefeacc904feb219491e1845e96a950e2523a9e6f5229aa90132d071b8b1e9cba1e29d56fdaca15c0b940731a31176ffcf6f9c3ace50877b5f3e2eead764a2b447442af776799df1092c83f7bf9b561783321e18ff9c82fa043b7067a06a1a7cbeb3a534bf9424a8cd89ebfd375ddab26c0a932800dd0000d53d4ccafc649d8ebcce4a54fad78fbed1f4616ca5b16100def77b8107b14ab05fcfac65f23d81abd3e9a2ce180e3c10bf60352d6b1b460857c52c3210baee9715b94b39ecd3c97e95f5e3dd2d7babb1e6c4eec7fed7c6fa55d5c8b5d615314ef9e36c6c34427e5a7e8fafbc99343030489ba20af84c7c3fae2cff247a234afa1f9592ded8203578b1f80eff5c3a07be6d3c0a94131fb4c10571c8379d0d422eb743a993848abd36accd3ed0629e262279b3950f20061cf3d99d8afb7c0918cf1a045cbb793b1608205c52ab32cb6a89361319f3bbd6b1fb330595552ae19954b7fca5433bc9e413ef398e41ac00e08c220f8b58eea709e4b90f8829b4287a2c770dedff1278a6ec97d1900e3c3e84e35db91841e11c3693f44e867f51c2188968a1a79d24aa8e41ea4ec0b9e6c9080922e1b75d8d3f00dd21cb468cc23204180659cfe07812fa7b171800367e00fae60590120ffba117dbaff94556f5f7dbdf5fd126e3cb1fef00c8893c4f60138f6863fc4278f089e247add297f86dcf4aa5fb0156196639901e183074eda75efe1c40b5a87f289f2e6a21c6213a8083369a1f835b74d6c8741eff024e7f1852c0ed554881327236c7b04e18d495a8e99cb22289207518d8d36e1b0f98522f4b376f0b30cdb1bb326f77ebd949bf354d052a1e52dabb3d0846d2f12ec85e44b32afdc50b8ef43e4661ee4f8189009517b98033f8fba3e58155fa77605fef0a0a04d5ae9224236d0c5228c695a48a67eb09d0c5a998bd281da0115c50d438f19331b42e51210506418e64064d11d10700c5bf87aed1e270e2b65052e98ddb6caa101c20b1a9f57c880435a6cf0a3ffea5c83694f2bdf6caf32e183a2b344ed92d9a54fbbc2d605a78edbc3bfa02b57da010fd9725b69f3863d0a28fa9f17ae66acfe5240d072e48bef1426f375c6d6875d0ce3c044eec0daf61dcab54aa04cd44f97fba40d4d88f30ccd08f26d24db57050c640687a9a199ccb1c2fe058325a4b9b43b3860c6abb49a6f85d4f6751f25fde8eef2241c31844c4bc36a2fa1f3e5867929f37684c1d14abf247ff53b1edc8507c0ff76464b68db3c12c3b5889fcfec2a47d0a35185a9615f8c8be63c95a7aff06f8f3318e5a2141746d8d41363251c386f09f4daa7a391f2e4c1a82583f4cbc73e9d5de5271786e73b2e277bb63d4a27633c902c7810eca6c2db134463b2ef38b21749c708e2d949157d97a645b792db50f23e0969064bba67dcb2ceb7d5aae4dbd60aa3097d979d361341146a7d343b42e51dbbebaa4eadbc21ce0f2815097cb0508c9e3ed6d8fb692d466bfc1edf1b2758e11f00acb397041d9f910aa401c476738145d8e2da15821c87acc3d95589fd293beca5bb9fcd1eea4cbec0db7de335e5fb5249b89a1688d9c40dd884bda315a1e55bfcc5bfb9370a17476765596d25dda2f889b8bc66868d209fc8638e415f0cada750ea232c6a793aa64e38c0d49a7412fe9948f31f867a0e98c026ba719eecd328b73c1f954f0b63085971cc1823be1ef9148c41c38777fa21b1ed374064aac6778a8a9e3dab4755928af5025237ff98b89661366bd702e2f70be7d67a4608828d86154271f9349b02751e0030a4711abdb4799d80bc9b34527baa6a58de8a1bff5e7fcbb71c505560c6e70bcf5c58642045794b7e85fccf924caf469f2e83dbd4dce90588ead3606c12afd46c1b6587ac8aecef66136370eaac6fbf9142d344448c9fa7f29a44320d8f3655847c06feef6d65a2a26bdc25cb2081eb7f98bb3f9feab89c6bee2c457c315e5d4b0c80c5e94b94ce295a31990d6a18b9b4fa550c82f1490a437ce3c90f3ddaca51e892411f7a4eb3648cd332b2f81a68b7a60a87879997d748887d5dd3a6a6578a98e8bc3eeb78b9e40544a4dfbbe2903ec7bc879f51b00e33e5b59defa5adc3aa39e668aadfc08b42daa5209dab4b9dba5d98c6a3f12e00a3c5b455d1506e110050a15f135e06790fb49cc5259a9eb616e600c4d27a279d6ec272f4b73b5a4f8165c2350523a1e0aa69ffff57e54147216c7ee780a0072513c430a29a1ec5ca7cf4ebb8e4595162380a0f77861316828ca47374cd61e3393b36e40f7c9e5111ac710ccf0bd6b0815061820adee301768752f0a759cb219343416fabc042357fd143dda81774a865dba41904349eda712121c5ded7ef5fcd131952c3d016775cb5b61593625aba23d041568d31cc7d4132f8fd644770a4a5fc9deb28d073f225a8ee7534701ba3d240c7a6605cbfd8155b27fc6799a4e1239e29cf110db55ce5e20b38c33b3adb49987dac8a5b877f7d067cbf721d7073879347270a528733971e87ef318d3386de7a77a87a212648f2fd6778de2988508bd9f4f2d99ef9a3f461229aa1d3aeb46581ec0f2ffe2ceb08878dd9c599a5b25fd13a57e698c332135f3707b5b9d64a0da08eae159bc9d605b683f6802bcfef7fab771cad584cae63fdbf9521db0e066432d8e7f17685e5f6fe92abe10fdde2151d0d2321c2a8148d10ff4138f63fb9b1c862c5f2afa6221472d14db06f9770028c9007c426e18658c24f6f4cbd06fbd1a5182c920c6cc4a2a2631fa4ddabd21e786ccb3215e87f24dc2c3159c693afca6416cb3168fb200029b728a23549635c8a8943b69ea89a113f57a448ac548c1dfbc747c8b75d888451a660a47e1c9278fbc5dbab6e843918d788c66ec634af895925d9522e9a060463197d5d80613841827bcc22d714c8643ddd12991da40d766314511d420743b59187815e1b06e63caacb6f673a944b781ae9d95cce0a684611d70e86428c421fa6134e00efab882b4e6e468b2018f6d59be986a198225ad01d20ae21a42d6006f5cd7ae06f67edd443201c274e99e0099bbc47c022ba01c6d8969872a5183c58397558e008ada6ee4ea3e4b80d9285eb390111fbd2a773d5e487d08a0748b5848240edae13de2db1dd3f0a7d01d8a962217a92003db2046e706ad27962f9f8fbc141aef1caaad7de40778b8b757bca3c4d340befdd50aed43b7ac2e1613bb337982884b47f75ba9ea8fdcb1968f939b2ab90f8ddedbbe17d3f345dca2921695425eba9d61b48702f17395e32d24263299ea9a35de8c49fd6796ce5342f1a2d26300d90dc789e3679f4109e7d0fa9963be5cb048786ff5559c5596e040290f1eb6ad1f4df3f93a01dbcf4855514919c2cfb174cc4f03a1aa3dc2a1dede485b16ac3a9749b9420761dd2d70ceaf04f92daff4be6f03834cc0eff37b38177a171804000d5573e2b4ce5998fb296070879f9f4571e61c2ed78598559c5b217c3c7866ce52e5998655c679f43ecfbcd055ac48a81af2ba7d151d295eeb933caa58c9f508c9f86ed675ba20b5cc9e7352208f939a103ca2f164e658dd01fcca7524e5e963ec9ae2517be1f69ba3ccbe8df1f65e565197ff9552f1428b0ee1445f01177f28af03ca6f3434c120f04154990a0f91f1090e9a323f0bae498b91dca3f14eeca78f210d96303343ef4235037418a9f7fdd72cccfe850a6e4c47ca23e4eeb9b6cee1f83647781cce9277b4f41dc6b7793e2b27c4c8c186688da8d4ee1f81f44245a10577440406ed496edfb96ca23c636f75489334a81ea58c438270d60dc8b61b5fa2f0dc756fe9593e623bfcb8ccd5516c906f9672c51cd31cc452606ac662ac1fe2d65c18798f40895d1016b98bad17745099d8645c16016153c11673d1cc2d05d083b08061e66a5a25ca6c07bf782200aa82f36d6e282f4d6bb036938e819df0247060f27a08e80b0fb048c7aea39ef25874af96b7cca606731d2315ef4ffae78280016124b092bf0e00c6d94c98ffc9a9ee11b02bfa403c2a9896375a501464eefe342d519541cb33d807b0ac8036d5f6ccf85f09cd8f79ade7570b7bce9641edd35654c38c3cec3b67022c40152d6d00e8d340025f95bd64b0132ab2925c7929cc692b5fec458a2fdc3817b24876958cfcac8cd4d3afcf79de99652ae9719763e3c4ca6947711581a25062f8bab47dfc0b20c171db507f67df9a22f28ac5ef24552535891fe7fbea4ef15242b2c4ef31df3494dcd720c088bd2cca466198a44f03c2f4dcd9a782b3434cb044e5aaa0f7512ef3dd32d9537e098b55dd33c18de4f24f73f7af927bba3c7915e1fc93a38a5b9f9e993c1c9a17b257b86bf3077a547bdc40fc9474384b0b50d912523add5ecb54ab1fc1e48b7154a381f5203b700616d3a34796103d0c49eaa2864ec9e4b7203bb0a3a100bba733d18e1155619b09619ce756db14e6384d23c2b4764a401285b2cf1bfb32888a1077d0de9f047a9cad26f6fdda22c65b947c521f247367586ba46ce3a5c1ca6091c677e56a5e0b9af919179a6cf9366722dc779ad4458d5adf40f6f0671a3f78d54a2631a6abaa489f9603a82f4b31bf70738f1e64bace59ceae66640f46b6e3f25dc051177594cddb84063883d6c6e3ab2aa3e2f5bddb894a16b25c95970a630e6f2fe42b5c1f11901273876310693ca6e19ed77602a3842f1b2069c01bcb13b16ed80d0342bf3de0b05662dcd10da1f5092a38c5894639a0db6a0e62058b00c53abd56811f7cecf3927fbaac1804853a478ee0d1b52121110e52ab8f2ba79771c864de8a3526f5430ba4ee8decdb81d60bdea0181b56d91a6ffbbb4bf0442f1926b3e8e1e15e71005e8f1a20e27e35ea76cc162497604dfd9d0ed3b542ba8ead33dcd7b830e3ce1b12fd1f0353f1f45eea6d62a423502b9b364ffa6b92dc05bfd3ab1e0deaa79a2e42ecffc9d57647f1f3e01ff4a3a7499f8d863ec7a0593a0ea4d94efdfc5fbc38c996df201f174f0b32ff6e8af22446eb9c2002d4a7b30ac8c6c5d77052bba7ca078af639a39f8a470870e57bacdf51018363cff4233633e5490930d98ae9471750e915d0a456e7f60a3f6c646933333c5eec11aa345457c8517bbd13acadd4bc2773c03ec7652e80425c68e8ab97a357ee35312ed0474bdb5a1539cb22d8e10a87c70eefd8b9f26994e8b3a14fadf39450459e4ad2136e58c5bdd44a861db1d8892c10e1523774f8321dca50264f6fb5fc4578418546975e68332dc42d884e5965be52bc45272020dde40fa65a0f67add422dd70d25d3ed54a14c5618b7ad30beaeaf6d54b9cc6631ba176a3e7ae4c6d4f70a8e92f2b40493da63b7c37a98861d90f29a462a30f5e2c4a7ab9699b0d104b1aa8279e87831e51ee3bfafc1d3358cb9ea7e3694269954ec3e8705d42703d664722059c47c1bf837894ed15e247e23dd745e3d8397cb728204482bdb5c614de4692adef7110af2958dde7144e0d5fa696fed12354895d931765794e2e4c16eb89b5b2265444bd152914f62cea7c9330dcb37f9a0e32aa0a9ff651562924fee39bc24eef1e5189f7bf3efb3fa6ff27c0009890f2db33c298a22c0cf419e576a058afefc0a8fb3f9078cf344c58f8b063a683f833d2d2fbb057f0982b88a87d2b3155cc32223d1893dda8a207f46777e33bae1f58b6973325fb613fe57e8001bff08f219cdb20a9314de5bbea6225b1e781aaf796cef47c3e826c414ca71f0f85da08b7fdce7fcd7613823103f6a17f4a38a87e144163fd8aa5bfb6230ee684210bd70f3867ee4154505b74f00c62aba397d81e42bb492dbbe697de556dd1d33df7de63ad51e02ef888121854a850f93d9a222629591e19ffe309bdb1b9b9fd3eb25dc1df0e8491c19cd6ff40f2b2da332896c368eaaf581c83e8bffbe8416c86c6a6c34de30966865e927895d4b46b931f826cc11b94828737435dafa4f9558dd97b6fb0dbdeb7b71397c106de0b04edc022cf3dafde623e9f5481a6b7502697268fd49fbaa4fdce873991b553d36616614ad0a0ed37805522e4af6a952c397cb54294f4480fd3a06655c15d88f1f8c2612bc696f874a128f4ff25468d726ece0a80468e08a2bb16f9ec681365690b7461db8ffb4445adddfe973b19bad28fef28d812069e3c9a07c36698ac665c9a4f77c57fb7670f9279a8b6fb030739b53fadd4622d9323fe0254f06bb74c23982b0e2525db8b8d0a370cbb062570a2aa64c15210ba0bf5a19052dcb86ec6cd2936e927a013a45fb6914a3318c59041ef1d5ac6aa08b39c0d5bfb5cbc28ac0e7da844b0ccf03db957900f1952c60ccb413f53d801c15bec5d7678fc9f496bbf36cd20cd8068dba111307d93428b1ce410b3e2cdfdf5493d43a0b3a6881b0ee411a0b16e3a4e65350cdbbec972903ef25d18c8470b3b594044766593d887b211aebff1cfe9e2f022a56ec4fd6573a04938c9cc554569f3e8e8d391a8defc44bb3098a63dcc9595f43d73da9e0f41554fc9d7ddc23f1ca6bdfc60cd411ba7d8bc2c4ad05beb66e6eac530df71d59287b7ab247e52d74d27a61ce98a4aed40ade9eaafdc282a8e967e24043f299b5ef2705b5ca5c1b34707c75976d2b0a18b785b3388f8b6ca340a7d3d8a5f7ca1e40e7a370d48066eb8a0a36ec4fd854aabe6bdc8f7431bf22cf31fdc79192a4003ef0bf40c2c3f4bea46609293d7b0e3eb8065a5d3cef62c4dcf053f12c1a857e65bd9458605bbaf99a93b9d987accd003841a32cb60351735979967cfade3c2a8a69aea7e9a0788b2e779272ce4e359d2e5359086f79aa56417b722f375b3477af4d2fa2df811a15ca84e2a2bb0445a452e70df980a8746d658a442415ade9985ee34159d30fbe95817cd58b9b27c87a077b011e5e8b68602533556d20e4d9d057a46a697d79882911c99949fb1d659f521dc3263bcf4453dab3ff94c7d8b12bd81d17e22a144ddfa6b250d6efd11fc906b511fb5541083bff7c71929575ecd4d830a8eebf03a136ece40351c6b89c2ad14dd6413031c7ec8c5407604f4c3821b032b280914ee9be88a57ca953ba77e3c83884e912425ad2d8a15a73b8307a72e696634bfc6b74c8da6498bc9153e8aa15383694d045f325b0765c1ab48ee88558366e18d46010a3bfd5d7595f9944e2e0f39b2e02a2190069f3396bc04d66ea8ee1aa719047a175048150cc4ed6b8745d147f1b6dd266e896c5ea1e93b357087837864f3e88fdc98d4ece64b14a19736483e664f945cb0e38eaf0cb50af122620833064ff7fb307b6f06a494eb6056b4ab3ab84dd8698672deb25c390b0171d19ee6623e4f47b0a9e64b8e36fb3b1abc2210fdba6f3c94138f66720a85be5e025eeacfcb80d75eaa9918bbebd914f998b9c3ef581b465445cec8541b96ec4d9299156730a0bca221fb38421ad31a90bdee4b4a215fe8171f531900830a7209a245b3a6b8d02854410b06289263718fc6d08a492ee5b6a506985ed8138b7e00000c6f4b7ded35e6fcea4f614b8916161a588355a063061c242c0a5cac779cf927a3f88ded44efd55f142eb8be316649e3b7fdb029a23d638abb0f68358877423c6caed110e57a76a051c287f51b87000acad0344270991de63991ab3ade4738ecdf6bbf48eac914086397b7032f61f483d83f535ec19a4e4a5eb3bf6dcd1efc4ac50de291e9a8d2d3f99f6b812b855ef641ad9ac86a9ac6336929de869c9ca0b6e2bbccd1204dbcdbc8dfa470f4742d783a92513f4a0cfd22731ef3b0afd14fbf05b5329be949ee4e3fd5d76c59b5804127cc1ef2c7ddeba106b33858f2f62305dc5b75951c395f3bf0f1cd4d54251db70a39fc6b631065f70d83454f6b5517ea49055b491cb0ca561b16d0ad241057f02007426e8148d9d4669cc47f38e1948816e8457152d3b59a74b315772f5a11ae842ecd978b150c20f336f6226bf0367513ac98201ba2465b9e4745740f3e46a920a75cc052b69d0d41a42c46695c76210d748f57e889dd77c0706ccb7d629a946a12c7c21d560b273618333411114ac4e933bae43c063e86672463710b8b57b155f96b2a8fe0b7614e0f6cc8bc9d76a268328a94b5afdfd134d42c35e6e35c506cf7fecd518e311063c929cee93f701844925b80503fd58513058e7308ba981b98fe5e23ded26918d81137923b5dda76430e5eb6e7cbf53161a160770f28601873fc0c73dd7b843142ca56ea388d8673a8ce160f4908c60ef0b49d2489f225c84f3c208c0a8e719e201801c19205156fbcf6926a8d60cf69d1bd28f65f80893a0535b4023c25d713ce9be17e4c839505320c18c2835237fdb6cc5e124c766e659a17637c6dad1bac49ad6919c8b7a1318c687513f876386da7e77a99c001be4499642d9922ebd3a302cbaee4cf7f5a9bd322e5c5ac58ab0fd250d4ce4987bb213ab5c3e75f07fe0d540b6ebaa8b0f92bc6d84770def2ce2c1c905e4e545118fd15383b8c7ace311869db2e6d3ea488509ac157328547c8cd2e50c88fccc0340c00948899be0306ee576999e31c0607ce173cea4853fb765f444a0d753e47f63d7ea6be648c1bfcc60308abe7d862c68a1a90a87bec1b8b15ebe16128d346b6dfb03a1a7ba90477a3d81a3bf434a4790a5137e1c7ed64304d75e026467be2423121e955a87dfe82fedce59aa263baa83a1da5f83c2dcb51292e5fad1cf24a93472c58160964f139e3242db3f75ffe4eda4825c1bde6ebd7aa2b503bbaad18072ef1aee2932cb7c7d854b2f4499ecac1a921e40c8ffb8e6fff2450d2e3430eb9018f8c69f2dc707513cf522d5734d2acb91f150a9ea542e5daed3449809f8e76723154e3d0c76ee4a656d07df3bb452bfd872a270db53e5439706fb6ff2dd88c435bb113ca57f2ffe70d9fdcfdc41340ad89803bbaec959dfe9a32d8138f176793b6040cd4c54aea0a34525f18efc6523faa6b3ec7e4b39eb491441f6ca53e69613d3418002d92f9ece907b50f1a8e3fe1c77368d05887293770bc692b02640d9e6f36d47c00217f4d199fadf75066f2fac4bd3a836de016d9b669cbb31c41d05a5c8a00b9d69dd8d1c94ac1092b891b7aaaf62c2e7d22766841a3bebdf390fa669791f24559dedff72c32fcc9c97bb9b8b13445a2d4f76c6971daa55c2284c41851629b88fb113f138a6a5ff521b34a845eed5b2904e8f5ee2a2fffa07007ad637fa7519ca5a315b536c909aced28a720d6f2ad62ea4c7b48399d27a32a20bce288e8ea3228ce97967043e7e1e06295159ab85d7d805e01e86f312834bbdffa02a5ff2601a7b2459ea9f030eff49df6d3962580917863f2c89e32c66d68b940c424f894113aeebb6d3e857c71540ae5c9a0dd96c491c43295946ad467902f196103d54a33523529cbabb8b82c04a875546749a7a975320d0c201ee704dcb30e91890573fe6348a0d0f37f79badebef3cd1306fc4dbb7db1744aa045eceb66fa66bb2e171efacb4e1f0758fc77b6aadc819b1a7d94d389600384b3eb4946870b5f9680c28e6734d8111ab4dcab7e56511d375aec6001fa7dcea48c3236dbbb80836ab9b6b5b75f4ec4eebe3d2e8d64c5ead9e6c0e6d98c89f911de90ff118bb6e2039f0dbb55bc820fbf9b436071ae80ae64edf5d8cb85fdb7b7a0e21f02d24df941da8c5010b5a27db34681e704391d3b4d771d7ccb471a303a258955cf4cca0146459c903d21854a91373d06101419ee3b52976496710448db0ed5f4b557f670ed2cf5a763b790e18ee88a8e2aa86e03a07d564a394ca4d8c98bcb2f2c48b9903d9344c4432a9dca485a15277155bd38a0aa3dd34f3b5ec24580b8cea5c45b2469ab8ba6cfefe3e7e639082aec95ca0ecd616ab9774b83a099c0632b4fdc2a23210486dd1b6889c4825e3285e0672f88f93a3481ed4e0545b85fc4ca31a2c584a2b4b0fc27dafdc337ef604c5dccebf69acfd0763c6d1b26c665c0616dee4dee5d2d7b80cd332cf84586382824072d7c3a9a71cf02f3406b7f11cc2004822701108c4636aebf80d2f07e55b38331b4e496fc05eb00ae9370d33720da213a1dde48dc65c94eab29da2268a1eee83c5d6801fbf24152fec6033c4fc55bd14b56223d5c48da0e78559c6f6bb31bd2fed400bfd6da3311e96839a62a3527a9e1f616124751451bf8e77561693f0da1f0bd30dc005aadeec77d4070778f469ea4ba277d38c871a2b8312f4100bdc2dd7831bff46ad639741fb1eeb69bd2130c3a20afc0ea4867f04c80d112909834799749b25333a238a434fe1b9a947110d260bcbd01e80b69dfd408101180aa984e0a5f99f2f6e240e3e8584ab53766170d13100b7c95960d0cd37ba3c85cf48055414c57ff8f94df64caa0d624d36eac6d059f11ef76cff51755531ae9dc235fe0b3a55e3a852e73481159dfb1471ef6ea06f97cdbf859045ff4dd7a89c2014b4d4925b96179739f0724fcb445bc3296afdb13024f9eb54be0712671d94acbddd88a4d27850b90c1ac76a4c255a2aa611ca2d16c58a383f73f86c62b61ef2be35864f9bcaf1a08b9b89a7605b93e6edd011875e7ca6587ef6cd2305199a5c4030c6341e559ff7d4cc87a87085e69dc70c230ca46327e718189dcdee089f7f72581b61e314c3b376c3072d8e75de464420a86f7d64d8245916e3d71fa7b1021f1bb1815baf4f4ceb1eb87a8dc136f17a8130228f559f4637a94295e9d951f1e3ac48c1a9cdd9c26bd407b6ca7efb78206285b7b76eaf6518d2decee7d6895b3d28e6e2873a896b0bdb5b18aa822e68aa9d91f1f5a70c489d5e3b7dd6815adb6482a3e8861cfc9610c1569f967607e0b4685861e6cab162d4ccc78072c72fc86e6325a66168442461eb5dabe01979f07bfaf80db00b0109274506f0476588f7c150d3c6a377c2aff2e08a7b316efc89ddde2b8bbdf26ed0876f478fe224aaf9ff74e094834deb59bcd3bea1e64c7bffd439d85ba11a930c5d53843701821a772254eca30a85cd43052341e72d19c7ce1a6fb91ca23fd3001ab526c1b9c0ed518857d18bbc1e2caa0b0b3a35e6a7853ef283f2ae9a2572d1ceca57b3169313aab34cd6a8d920c2625458cac4d57df04e48bfc16f8b974e178909535e26b965ae2ca251c881a995c6fb6206cee30a49dfb6e91ef822780527430c5ade57c0572e37f43d6a86d6a62211061c1b27cfd824320963cea0bfdc0e6123ef780afe27f4c0b5a3472cae09a9d1bfd5855ca6c6b0e214f2a2dd0104b027b518356adfb12dbfda7772f26ce6f9c98f0e9d8ef19fa4ff34677a3d233c41c0fa424bfa7e34261c39156d7b7328100db7fd1f3242db62172e3371b2735ca7d4e67d2f3b98e04a0fd74b9fc3f555e3ccbd3d024bb482758fd9acf44c8d88bf73105031e162bdb9ef7c2f9c08ae7f771c32bd945a0550e17c00f8c66835e9d7970f9850eafd31107efc955143254bcc9a67ba36013176080185504228c705d0a4e6c7c8f2c1792c79163206efa5deab2ab97b2986c4d8248e0b1368ef585981b11045edb837d014d0110c64d9eb5d79cde7192ad70d86c1460063f80abbd69c944ec1ac1758e2bd239bc49429300054f4bb0368d0cb30213b36d14c4386892fe4d10f19d30e075074f12a507714a853bbadf4f633ee90dfe85fd7939185afc14ce7621cc87e178ac6b9622e61fc09d29554bb5186f23447d8a35e9d36f64b2a0390381677a4dabc577b6dfcd942772eec29d51e1ff351e4cb792a234694da0a8fa4804d0892f4ef24cfadcb93c767484cb52b912a7d4eb8417e19406fa99414cdb410836a53841fe26ef0fc68933af2a73170c7fed35108f01157df71dd1156ccaf6f7540613e8af39196dda838705d60f1ed1a1bd8ad7178cdfe6e9ddbafc2e61650aaec18fcec6193ef860ba31bc6af99761f5dcde3972e45ac3efb17952a1d7be1792b06dc11928f60b54d856538f41ddb6d57e24f53c19983b8518c97e321720cbacda5702f6cb194e83d0a5a3d2342d262767bb78535b96134196546d064c927bb91b50e7e708f01948ba39158744333d441b68cbcb14416788596ce5a2307638d3b4ee925298dfac9d96475727a8e26a7b950ca53242e88bef7dc34be4461c703953cc3c2fece071e8d8bd5a74ede4b271735394725c28f45a3671dfc136fbbd19b37e834663a272b8421fbfc15fbcef3d18a2cc8bb4e9d9e8cad0f9cc75450148377a698bb949a43fa5067270e6c3f55a5f79da08b0c4a9d0fe4445f82b37497837ead2dece261244d4535e765c6f9ba336fdecbd48c75966d0ebd207289dd62fbd4f0e531fa24bfc4791d8ed5174367a2e16a43840c6aad41e3b93e09691f9923283d1115a2b451efe8a527e8f89b1401dde5161eb0a87f676894ba5145f7bc8b2a2a08e69b940d3b9ddafa9659ff272874f1562a2619bd04f93fde11c9648779c592dea291be88ae8da90c6cba989d911d0ab05250118e56e56395f634c2e4d45bd78d936dbd70100252e56966554caa6e51021d605bd76edffd8f61fcd03606f2318f9a408d03a2605117e2591a326f317dff9872b30104391a0a4ad3f54cfa769f4974168cba0f82ba17041a8135633708a68b665e357e0ad0cd7b1caf45e84ab0f1736336d08a7808109210fc5ad9814c1796bd82db351a3e704b5f123fe9f8f9d30d5685d16f01ea9ad21ca79c214d0bccc97cd9556e2e8d94295bee1131524afcd01346b482f17e3be3be5a9d02c7d4dd9b9fbfd6edd86f65da6905c3f45425b8582ae89049297d46363b7f0a544f80f14905fb306bc7fee6ac69ae40e1b24d9811f9661cec821e7df5ef5110f88d312ac5339a50a1c4e35251d94e0befb8967fa2b906744b832845ece13c1f8e630e1c281789b60ef09e9c5fcdef4e543f042d3c058b5a066772b240b5d1506d45adb3e8293d7b247ef76b1372fcb1ae35a16e24884204d62882f78d7bff054301027a5c6bf0cede50987f0b8e7b1fd76fcf72a8055e76bc52bc814310eb2c9f999e1aedb3766178cb05e81ca38dec64576cc80228e00f1422688ae1e7f56c4f6718692f1d7309f99cb2215b997012bed94b2f08d6a9f4b47e77452d50f50557b6e63d4f524439d35f7a054332857595f77b1ef290b42d4c31c1d2d039c69592b8c671bf57275e5bd72fdb56129954bd5fffedbd64402d9cf0e23060656f70b0d0a31e8ffaed2aa6c2a1482662c8f46b11d682a1835811d0095f85b0f3d30bac7b6784c122056d0058ef4406852339d8141a44eb7a01e4b50240b0b16812758d7e2ebf621afd8508bf8f427f4deb467574e1e9faea1cfb38ad45f19932eea0d97cfe312ba4295a37efdd62152ac47677754d0fd71ca9f355274246f366a1e88cbca7970d74e65d9b7ab5c1aa2ee4e950486a4f71ef0f992546bd326236bd1ef11a692f364788936bbd5a039b8e11df8b082a80737d102d88a92b79a8a151c155a0ca04d2baecdc0102699bb10e6b6d978714ad7d07e092e3a5768598071c76e04e187e285c6fc08caf8563864e91b4cfc884e532966049efb50323ebc8984d8a1170f37ff312af579f545ead37cc8eef25a52796100ada781da94c7b4d5a0a8bfdc1d6f7d0abebf4af09c70a1f9e22c4953a05fcfde3b16e7394e2a0ceca462ced744272ebf47d16d6063e87f730a673312fe1f10412eeb2a74f33410c6302bb4c1b86c2ff362fec2ba113538167cef340bf120a35ca65f74bb98ccc92f6e60efaaadd78fd5ac41432769266e7d7591269e4da2aec889a4a51cfb69ed5f66dab4d38ce39d8b380f7d09d17aaf2d36f0b264225e733581848528bd415474cf066a03503ce3e72bdacd10bb94a5ca304b455c1f0317c3fdb9ef75d7857cc4797b1b37cb05a32d05b4a75bf579ff595025390933fba4df0c9c4e6f3e9aaa423a7233167d7d7037cdab0f6a872c4cca02e35669bb252485dc0fc066d5d13b038ea9a4eab91cc5cd1db21615d00ff7f742a6b8a0df1712a3a74eeb38da4dea4a9104f95f3fe8291e355ac9f4355d4426fa57ac340ec7860043d027ce62a152d54d94e5ed143590344f664f1c0dbdc7b9ad532c277d76fabd94ff85b7f5feecfc3ff9fbcc84c294b073903ed3d098c2cdff1b0f2ee17f474af20bbca5084ddfe2301f0b7152df30e6ed3d7f2bd1c49bb320050c40f7c4edf9666fa385b458bf0a6a55b34d45f03fef9f72c2dfba39890428084c51a675c2507dbd760ac82d69119bda9fb7a35d321ee3bf12c589ec01ed324e05f8fb22f0271660972e363313a355f469b380e495de7dd510fc099ad40ebb169dc1a2112be88a0693cf86dbf47e9b81d2444dd845ebcd236e35e9833c08ea364c4c96456e44108264cba85fed342afc882eec2a273e9b83c65c97a8bba1f51ee2f4aef6f07a96c79933ca373ad08592b8f3f8fae7dc427b363bd8974e287cfc41c8aa62f666bb993d92da350fc1a0284524364fec375f98b9a757959ec0934a34bcedac2181d2ce390f79635b6fe0d3a2f65e471f65e1a99a702a5572b3ed3bb71cccea078c5aa020ca489d505e833c853dd155989f9dbd5619f621c579412d7641ebee51c2c548886a8a9ad18a9b4d4eb102e780effe4f8c28ee094a08a60fe4b35be16eb9c17dddfa30c24e98124429bdc06a4ed71919ffecdec856cba0ab2130739d9ae3267be008f4189a38a1d5370496e39c27d8ba01e975b55e9cc7518654c1867193d074a24b9416df456504780acafaf9a033ead10aa18bbc673d4a562199d32c08f0932fec0c81b941d8dbca840abe1babc68698ca2456953b45abbf823aa18a85a35e66eb7307c9cd4f29c29c4ca55f7f9588a885b963415adb22d0f033fb980398171b15afd2c52a8aab933c2805e32837eef01dba94012a18901e9ab0bdcca10eec7da348bd220fdafd8f35ff27f4a41deb57d04cf8b7fc12b4492f401b96724808ac44f263c40bdd650e945862a2ee90f556bfdfc540c4d43e49581460b48ec146ee9676156feda2a23390a03ec5afc990409e48bde24d00e1167e04f8a2c204211599d378c41cf0dcab8364ea75885520ab190cff3b324c7deaf16b367c17862338a1a4955f87da0a1b5da4ec1cb545d060458dd60fce281012f13e719dbc4dac4ca7f052881123ad6d4136d22e2a4225d85bb8333e9d1d124eb6b15870f57f63664961bb2ec86cc7967940f8c92d04191f2f9ea3ec4f963038bb4c36245e089815874517aa53cb20c050d6cbe57380a65d74b3ed83778602f3e53190c7b21819cb1f2168aaf869a5c57a997d9d7cb2b4df98b2cdba73d1d7742bcecb5beb234b00b6a79415ac596378e61a5953c801c87f467669b355b31bd347aadd7f4f1984ddf9d1de95bab69f2393dc4526db9d8feb911a9dfa805b462cdd825a8eb15864bed323e516fa2581880094463fca5e5f43467cbf4102874c0f228bcd3009dd05c77860c34767e7b038b35034bd705967ea781efa816e9aa97c7e93b4bc933ae9d418ceae0cf2cf42e9ca82b4a8b87045d11dd2c244d9eac00ad4897b9b83cbffaf46f91ee00092e0e6cc7cb533ff384374e05609e9192176f7665f938007fefa9750ecc4ec186d6fbb355a974dda7d9d97d1e9d7ae666b5020951f2d56f9885b9cdffb2f1b59d39743aca9ca6cf1988369e5aa6a0f065b1b7b9a1a81e4f0b77c88a87d709f94af9f15ee23b1c25a28cfc944f4b3dbab1f336883d86380bceef246126f0228e6ea8aa1be83992b91d59e2188a3c0ff1ea6a68b0b12480bd52720e6f2e681cae1ad9b98fcd03eb5d2eeac5888d50a71aee9f0387e09b1467ac24b69ff0364f3ee7e531d0f846cf37a4e36d98e1a7b608feaadce873cb6ef24852cb88043934c3bcf28c6488edee100de2c38af1f8b795f207a57fc5be0f8f81bb0326b8c3f738bed181126f103f20dc8c0f4a7a796fe89858e1da184e7676a2a38f639eddfb9b628e8cca1eb313b10946cd78b4c102aeef53e503119cd142093924846a51e32adf82e51019d4b27598c28b9fad71e743d7d2356dc984a544a7e32a79f4664a7a367933fcc25e818369f672734d7083dc68c3ce667afc8f179fc3876d49948142ce28a279a32a48241ee59ef957c14ddb92d327130f14c315945690c21021db1b571411cd8ae6ae61b042c046020301e89080f673ee0eaf721152d4386ec1de5f08ff8893f0b6bf3a665050703231bbbb9e516f057b56040e1e68e139d38c7c00321b648ee97ea8cd62c2263cef0f4da533140f399631fe3b8b081252414d8a7af9ee09989d1845f4c719c0f031a18f96ec086c1b0383b143e7336a910ca8183b112cca18f2f0e35da8d8382f89ef22a47070cf204c7a981b4288f697d4be99e7e6658652ea6ce4d0f91b2827e0ef18fa6531fb66ed5991218f0fae7fc27967abef1868c4aba354227d4cd408b1fa01921f6650983ea133ebe354c19e694450ae93f9b2ca7297bb4e736d8fc3b50868eaef9bd86ee2ef58ccee62917978b3d4d00dda33a215dfba9328c029b31f5f4e8df522ad3cc211e7e0a988c803ffbc812ea5f0173a2a4f907742e408498191b5a6c767cb377870df4755281d5a3ff99ecac9841baf88b09b45ed6ce5c976e4ef7c7f56c162b9098620b922a20c464d1cbe20d34e637f8624deb2269184e9bcd345b88c40dfa5918a5e4798206cb82739e0b1c4e9cb4106039e3b1017129288eb15a09aa50cc0375c12e31fe941cb6918121a2a1fa188ee45caa997066e256c02c333b3edaaac90b8199ce11c06dc62f18a3a51042957146f2cdeb179c8171f73f41a2694d6e65a79c41a2333e3686486137b1906099395164c3d845c06a30d2d3ea12eff1a6da440f7dd34ff895753bccf3130122cfd22873a4daeeb90732cb568ef8771f321d1c6086049765efe875f10bb7839d43b7dc974a4e3ea6b063d171a9128e4e983633dd20f04e2cd64584654b45e938d7ea7f08e527e2bf0f0a5b462db45d89adb7fc61c553ace880d2ca49fd869164402117ac28dc87c5868bab71fc203b84f8210798e72de57ea7de9585ee7f910f4e9ad053bde203cf43640496f3c73443fe4a8915d2196053ac175500e940f8e8dd487e84b5bd9e107b8ab4ad30ef8d69632cdf039e433032622b0c835fefafa45d4f0c41b2233e474107d20b50485da81339fbd20911d59cc7d9dd4bc2e0b47f3b1b3ad42374c0ad08d40626c076a1ab66491377d3627a17b984ac04d13aeab1bd4e43040060903d391c4fef60a458438d7c2fe63ae70b38fb8840c2329f2fa43aa03e562df0e1629abe281f63cc7c2d8a5ac7b075a3c2f162aeb086d9e54b0c5ef6134a5b4db468dc77fc1103a92570c44e648ed4131cc630c4f03e4b2f9b7511420cb4c00a0689964a070dfde5cf9a82357cd17fd6f574e4a26db6d8d8a78142fd45b5575a21447925d7a6256415202a0ccec04bac5a174a843b202522cbaf25dd125310a691bf6c04f83ae6c306b34e697b8337761eb6eff4347c62e9d035e1aa30be9b033ba311bf85cb1494fb70c6f23fe780f72db9c6c8b4f8c8093c516fb6ccb982db2eef75239e5579868dd55643c2ebe773d84b4c3b53feecd86b8ae70ed562cd9e7b4339fda497f2dd35cc8c30014654864a1f5c7568bb31f1c20ed38c947d63a1b34706d01dca23543b96eecd5038aec014d893afdb0179a73e5d7ce0287213013b71d6a2b2d3d3329482c9903bfb397f17d6b511895c0311840c6a055b445ea38c1154184fc64d8596a1db590d56b5b888fb9ddff83c083977a57560821c66414ec6de11f15a98a0b3d853df49d1c8a56026226e7e1e9bb3c3b716dfb864773c06cbd39c5009d5abaf5509955651b9f246d50f64f422887de398f92aa79f5428d4be9006bca81856210b7781ae9bc5ac9cf2de3a22b4197e57a2fe3619569283b606b446cf0422d314058f148917e9dad43265a326e590a0451a8a35dd9443269d858a0666f34150da644c64d8e4745211d013009fe4f04dfecfd7447e695f12454ef5b7c9f3350ff8ed0761ad73cb4871e2d22e6e749ceedd5321ce6012cb316ebaa05c9dbf9d5234a75315ed5df280c1ca916e121cdc236871361097716fa3b35a660fd5729bedbd139ce34db8ab29c177fc656fcff5af6d21c7c4995cbe4e99c75a567332bd842c339971b63faca21959943f7d2ce2e374286bb8d06a5582151850c71fcb441b50bbd256f34a23fa2283909e6f34559605293d39015f52c82df23ed39f8c37e6c15c94554f3a5e7d4c593e806aea1ebbcdd266584dd9148645c521261dd70a108b051d936a9207bb082cad684bcf30d9f36355c13169c3c38a279e2e257dce65d7f8c60ea11daedbbec5ef894adf4044260f15a2a9e4a725805d866121f171f384e666ac0169d0e0d5afa616e58f48c693263559aabfe6ab7dcd9632b481c40770b702346b6148b74b6324cad32b362398b7dafbdbc8633364186bdc20d0881ad338f73b1644a663a7f3c290a1f93f7e0adfeaa1ffb3efcc3c20006b3a4b31cd1f5c3c01db6d2ad1f418e6e78a400cc1e7b2cca06f8a391b1dd1d9bd35de692a06888d1dfab601c37808991d79a6cc5e87bf936bfc090865ec7afd4dd335e745523f8803abb9623d54a3a666d00d9b0353910b30f8afcb836ff7c5ec5247425984460b62f64caa234755d85970bed17782fc7c089a19a544a880b1eebc14c363ee50a9114844eb83cbc19fa662c39d58ef1bd82f1ac7ec5b29feaa1ccd3fcf197647048c8c9791f38d39c58d454cd7b694fe84eb67c3357336af946ea23b48f154c5512c21b227e63bcfeaaa04ae87e6027a380a5b706a22cf853a51cee12fe72e7ca7ec50de09676fd36926998d16d33f539dc1fb59e43a824411497b2ceecd1aef0615a597ccf57709ed27e7ae885e49a9ae992c9b5aa05165db4b1315bb997b4906519bddf1c8976ecfa6af7c9b7895272c2c0972203eb4d96247568634aaa85fa93e304e375341dad0e19d94eba0e1774f4095f3fd82a187049ed8a52ab1ad9422dbf3d9b6a70ff0dc527b19dce49b7ec49a0b0ccdee5d529a4062de19ee1bbd980e6adf3122d599344ee2371b4d7f15435a527b09d4ea3a1f8ac5d5b2df9a01390486a5df421a7405f806e4de1de8f46cc9e137a1b0b7c83ac53e4205ce2e7206cc2bdf39b2164c3734dadcbf2b669fc5b15bdcf4ddba31871963fe457857ddbb8ff884d7b0399ef0c604df356decc4cd68717bc29fb78fc66a11b367c1efdbca11f4bae259a1da674f5be6580650ed7b5455aa49f3ff325f9b370acd31bd359165fdbeaa13f31a64340ae631efcad27eda700bb479aada4654d2a88d7884547ed4fdb5849e2e5974fd7a768d6a740140efb3b52115675ed730c5f8110a6ddb6b884370eff78261cf9ff8ea048b47e2765d21126777f38f549c67b10e06cd870b4475aa9394c50913435a7bbde803d26413ba908cec5550b3f0e1d341e7bc88c15eb715925e66b3840b8d2dfa65045699c60b7c4265fcfe59e7868e6958174d90177620f6e7429744d95f4310320332dde683bc5576d9917c72a4441db07827895c9a80f83b5c9bcdddf1529cad3d7b6d385da6ced6ca54c41058c45fd624ca45acea8d4e8d397a9a743ec6b38943659431c2204d7d180684136a4a3d61b446400d9de162ad632f6cd01b48ee56e0e3b8043fc1a37f38115268ec2e3712c7a263e27853b6bcf28006b4b2f05d8e945242de1f9ac69dc96b5ecb6a9b6cce2cb9e61f4647f9065079f8eeb26b1842f4f26ff31aec8c9d601e2f3d42346b2e39ea550ac438a2292fc4b852f1ae43c67b25e30f101f8baf9b6004e0604e3dd88f067c0fc3f2f39d960f1f20ed173674409b6597102a9f6e14363f963d7ba694e21e574b397d501c89d7cdc1f17017300a9605e662759916c8c513243f786bdc6c5204578db07ca09f7a6e7ddb5418a5838a4d07a3f3b98d9a127cb75865edced017030ccf23633533455c63ca68b6dc2b046797c117199f4e8bcb78bf24c970e1d95f25bb29436478e14b1d6f353603f5a1c09302dc040ec7051fd5d2b67b6cd6a2ce3404f7c8cbb61b1a4a4fb27722638ac0de2f52f20839cd40b3de6c194cfda7bd0927c9e03beaf13d8912f0ebd7323831102f814646ae0df83f72b5f92ca8b0a7d021975bba41e1a6d6aed817e976c5c7f1409fff3f569fd91be85c415e1233be46844f648ade9e60a445b7c6d9819d9272ba4547a88299e87fc0ca23f61050bfabc553cab042091b71d813459328534bdea20cf55de19499be78a1febd20ca5220d90ba80724205c2c79ed0648b31e4cb357f3083fa2d40baba705261d07e24f0bd49c01862379b867cab68c5e68189aca39acaa01de8a864375e2b4d643b1dd73f92a55d94232e36b7525cd921f989896137314a742c402658590ca1f0a0e8233745b5e90ce628aa07c5a839a1ea6cf5dcc0191129022a06384e9852b5d289094baad6e35af4bc7a79237e26b34095e11491c9dae86468baaeb2026433efa38bb1f884db536bfb337e3fb9c42bbf53653fd3fabb9a3a1192f0ddfb08c1dc13283062428c3a3acd7921d1bfe0b6f3680bbd727feea3a06b1d00fbfd81df8670de150805510ccee254adaddb9eeec820375158e95d349fcdb57d77e37e4bf8f220cc7789e8532f33a24195e72af28cb4dfcdc7f96ae906317410faa957a77335271f67a11f06c64853ae19f0eeffd284e11a3f514a12ba681028b22825913816cdf8eb59b488ef06bcb118444a79a668ec6d396171eb9ef03adc121b9cd3436c92c4334e4d811fa59e2882eee1264f48c86a20db05fe693b61a38a0f410cef60bee734978f2bf38972c021f04e14b240ac9fde60399aa406a1245f39b5ebdf993fb3bb137f2c3941327e7b91b54d9ed6b1c59c95eb0d8dbb473b1442af4afa8689b7c958dc4579ecb2cf36253635fac682f28801f37312373147c8e7779b52d9f63bbb70ba58372cbe43411137285a3e783f150ed9b68ad4ecca9123cdb5c1e59551637ef484616d76ddc85151c5a912a0bbfe7e7c98e98b0293f86c5b4709fd1db455d6afd9aaf89c8b1fee09ccfea4daa25df9816a3a06ce1f80a24bfd1eb9f039112771467575622a342819afa2460a1b0d6f80d6ec42ca711d76cefea5fedef7727f85ccc09486a58b542f52e823ac2f34922bcb3135cae97bf69cda06853935ad638d55046894c0dad57c8f44807ea144a074e2fea4a0b8c8cc2dd3ebaf9f4fb863c1de4cb0dd7203adfab18cda6e65c0da14d9b9d0e1b0e6b7e483c19aae9ebdc9caced6937cebd1e2e512479c062a11acf774e7bb8a379535eb9505f4b5e16e2ada1ce92a2e8927067448e958180bc76652dcd4975ed48bb37d425d0811d8f41b25fa6ea00c45dddd20db14b7cf3c0d10b38a6ffcfa429bde32419a6bb69fbcb70fe5f800ed529241314479b428dd0549fafdf3a55ddce521ec03939955a18cb8cda2f3550b4f3d9b53d8e8a9c22150335973beb48fd8d26a367290cabee0094be097d3410a44fb28c9a21b164bad8ebfc8045bd09eec244d3ca8e49cf60f0d8a9e8d05811d07b2cffd7533e5e0e8f2c4631802dd9cdcee2736a142c7198337cb6e919eaf5b8337efc1449a1266d3369992436fb8ab8225c76594dd5e5ebdb0b5962bd9ef4f9e3718ecc1cdeb9f53b494b5497188efd2aadd2dd8fb192bc5bf14b1de22dc4341ad54312fb0eed0f902fce205d55055fefa45cdff123d7e2bade04c8853db7f4195c8c10804eb691d704b96dc6cb93259a23ae23e1c5f1a76ae9fa9de69996040c94646b9c9579f414b935d84d6bc0f70ff037780dbf987c23faa0535b898b4642d5145ae1b472ed5b9f57ed04ad3bdbceb2665a8a3fe6bd527d34913685aa5640361f52e00364de62be7c500b1adcaa92310b880306f5c376d7ae82f1b050342f28a2b54e28e491142604a43c98ab360ff070e6f457e51a37de4537e097b0e3ea2ac501a63f8cf97f3d6db198f673c10e29d21c688c2898b4488903c6f5ac3c4737b1d5004d137a86bb15c0fcd090ba5e42219d026f8d8f2848d31d0f90dac423cb75ba7ecd3700d6065c7b81d237c277d8062459df83d1eab50ba865b15c117983f8e9c40212d6de1e76b189b0ee108691d763d20229c0051247c30dddbdb3a14e4d69e09f914384fd5550b55de90a502db8f81df3d0bf33e8148e0a265373f93b1af792de3b69363f11912d170b07665bc849aba574dafeaed60a471255597ea544f6d5172aa43d3333d9f1bb68f9d8eedad3b741a2bd21f0ce6ab06e6c947b91a090b85c764231a898e7c315a9e1768b9eca83827b92aae43a771b7d1d66c8e844d36540d67adb50e19a89c9184ce7c7ecf955e7caf1f454d75044957d54d498daeeb0dcaa3ab0a5e6f103f6027b0c8e21e30b7279f06c19cc071b98746b8d2c0e149461372b430b0d3286262156154ed6916f0c8a4820dc8562399e971d4a12e89690dab4c8d28b30be170f9c8a534cd91d4277492fa45996083b9333e9078508c3ccb690c3fd423d7fe2bf594c8489e44fc929831bc199a219406885ed5f00b362aa15cc7604a17a38e85dc3dfd092c68038516f208fc452fb4fa88c9176d2af8557dd242c7682faa8da1e730168afdfcce77760de5780615726b025590d92da3051193d013699a5203571153e4be4ef16717c6367b61fba8014a301210526258d14ed6b73d60a365c5338bc60486c92a44ce103f55260c9896a069dcbfeb0e3834e41e494cc4870481e025d732e05faf0936884af1e69632bc16adc7ab70a7f955f7f82adccdf3e84e4249cb3559a1ea8dab4f732a3ead954279720de66a152dd7e6ac718381f84c28b42e64625a040b6de681fa543084d732d64a774653e33588cc9c8e92788725bc928bf4a90d122c4fda2046def513f6aed96d24c363b31deeaa2cd0bbc2167315301aea8a320778ac59a6a9a866a0638f6b2c8192d2d19a5d957bf8cf51036553ac474634416e14bd66324d9e6db380c7b057ba5813acc65b48ce8abcbff74ad0e233938cfcab854af10e0873a8710a5924ba4bcd07b5f1b90a7f8608608215062251e48cdd1f3eddcbb7280ee1bbb873418a12688109dd342dca4a07739e5999988e8883d13f5fc8d3b1dd2203092a449ba500cb1e25a554558d81b0393fc46d260452ee645fdd18eb3c7b0c68dbb87034c38feb61d85b762e9f87362208afec3748291114f64d3fe7a06b7608a0668c95249a704ce32d88c3886c76b025e4e3b11aafc2c40fabe81eeaa142cbfc79506bf292848d26c5e3b8c034e9af8980fe60761cba49c8d53c8c5f3d691a35178c40929a58c0d32889ad674f36d3234154e44f33907290c90e67076c4e8ca7e7dd1250c9e2e1eb010840bd276c6ee25e3da6eae7d8e1910a4ac7a42841ac1545b3d5c144488e3277f99fc201f129bd3aae73bd3c85c32a327f013e3b6ce40ade0819eb831147800b5745047a04b2cb07ea5e461e95d7dae88c499aed0488a1e563fab5da784f92fb4751da51349df5320a9b459125efa30e5ebe0efa55e7152583ab3dfee44685da5a8cc04cb91cb817cf3ee65e22762dbb152cf4dac949c56d4857616d74877b790f203f576995f85e31eb8c94910113758fb0bf671002fff176e06c4a3e2a58bcadb903932b727ab31e3482a386a774d6af6b778b552e07c6d9660d3b416e1c9134f9441b6e1b43a30ccf40a611b868808bb9c5447720081ed9a43df1485b5182e9071175e05cd65352936e2eb53ed2267e83b7e964d6eabeeec399c6432f30104b1e09bfee48ca514cb383164318ef063c8b881b35921c0135a310ca4f22284b9d0aeae16b1c9ee16094eb5e5e827442296f7c533e65235b1e511b31dda7646a4fd2cc1d1b67aa716c32bd896979f4d1fac53426d34d45a756ca25c1b518fda847a511fc3c9ecb3a9b42e2eadacc210eb8599e19f4f7b71e05d21e576a73ab0fdb4b829ea4a3853ccbcaa897b277cb0bca209963dd77517e430be48aaf020228cbc70d6c42e926bc850bd313ba0f424619ec67d990cb5442a7a206aabad19580e64ae12a219e0ca366872c991e41b408d628ef858c208d6796989061538f736ea05dd600ef095cb8007e170176a6e3edb78b7df27f077cfaf778e219d27712610e2151542d873817cf377b25d266fd765de3b05891f83808c194bad871ff5d45514c4fa0db8cc5d87d5c6402e4c2c163e2709475783a8056e3182549847f899c41c6ff5f3d442a536488b12f76e84bfcd1ec95405c08a73c7183189d17a1f125915473b3a9998480d7256d0298de110854bdc8a498258f9a03fba0c802ca2ba1e8e3501c871c4a4a950314006d923ab12a39c5178bc049f02283dd1035382e900d8adc81581cfbe1b4dfb75853c010a30c3257eae070c0979180961061806d0918cf31643ec2d77a29679caaef3ea9854ea33fd34426e8abde615240e4cc01a3e8d4800837f290f31def003304643b8642447915c5a66adc13263b727f2a8b82eb516d0a4f4d16cc305648d9cdaba7e3a5a1d3e9a96e5bad58275cd3bf81d1f91f8c35bc1813e8a94531dfb3aef671bc5624212697c1d25ead2da6e586968fcbf5b9d7fb3337a9cee9400a5732ab2e353e42438e4a44e818b7c48891aad87199c76e57b38213e1739a0d46ee5987504810d96eb5a42a589e717cf832e2a675aa776471aa3e4d6625c12affdb37eeb0711babcceef5a72e38f4848e6b650e7eb20dbe6197bd18eb2def3e16d0ceeb0bdca7cefe194f6884e907172b2f1eac18ac62970b06f62d56a2e169cf025c13ca1c27dbbd109cb2f0862b9394a981ea112c46d054a8ac48587dd59b92c145da9d122203ee412871598332254ce4300794d219981f13db341aef8c36167da1fb862583088ed70d89e03c38e4e65fb44ebd12046ba4e5df539b5c887801f22c47e611b477d61c55b2ddd94557ec9fc865137c2b0fa1959d6e2ad0cfe4213932858a6cc4941509f2f20193f7a940768f59e400f4231657471762e4217a1253a47bb7ba45e0859c082553995305ea5937d36047e1040e5be54c21c578315b553fb39729932c57ec87abb44a538dd2e9a14229a96f0c866eba8a520e0c84ed6cfa1e57e8f81a8db4a70b4bdaa495dfa1c976e8b5c92f2e59ed30d0bcf266809abc7857e795951c06d80deec776d4067d1553fbb6a4c696e46ef9b54b54bde4e9bf90bb68a952c89d99cc7cfcb00b050be0c9a476993c2c49e4ae5a54505ac4c3104e6fb995cdaa591658c4ce02b5921d121247224a14591598328279848a05daefc1a5290e0741df15efeca455b86bd5e615f233006b94086960c088b3c70bd6f972c89f3bc2e79fb93368a3e7579bb074880d0b51cba2a4658cf83c6a6fdd6d3fd54974297738b2d58be18c9e120174661d656a45fc2ef974def5c93a7b2db5e24481fb46771bdb1b8c1e1d858b84bbd984ac13cab19dd8846c14c643a83721093c112dacbaf87a74ab723909423cbff584dc07fbad16f981dd60d81178bd76d23566bbf766e77518cdd350a0199ebb6bc32dfc695e379843f0dd301d3d046e35a51fd7ed9ba4fe1e9b9bb5689899ebff137120af01a2d1dc68e08bf4e179c9418883ab82112a553cd506e339a1b48782c8891071796755dc713eea0c20a3855a69a2cd55aeb93ef5d442b139f8e69dd1f2dc78a4ceee2b0c9cf0df3ae1e9bb61ec21ffaa567fcb8d50dc174e343eb0ca3718312bf16888edd414a3ddb1d644087ed395d10767031ed792e0cd591a55028828a257d4abc7656ca2fe3ea0dc6ac609176ceb92fd629c28ee0179723ab8d174c821cda48a91a6c317e178626e53f16fb20b2742b8dd73800df074756eadda83af3009abcc19eff36b80488a527ae8bf5719a12c3b0bd4e5a98b5dfc04ccc31c23df32888ec1fc197d26f2e484c5519114dee59529425b481906e0cf3239858a986c0d9e93cbf28773a4e1f133444ca12b9b934ba6515239551f4dca89652285c2993d0f4360547b30f20e64548a4ebf2ca44dc0b481faeb59ea5a6111907b4ed2d1fe84148189c8b1a8d84a4cee667e06b1e2d2ff677de30e70923ef554f175e9011a373be6e99d8a8299c13db923e3f2f234d8477eacd8ac47a9c56b97478431c0f7993065177a1a1522cfb1c88c1e47b9a0d8b4eea8b9a75d35432957c5fc4f9a5b15d6b68d0af483c50d3e97809f782f9bdfc025c575ad7759546656dd39357d050de280852c6a4d3f57e037866f9838ae595f637d4bb5fed90a38fee1c4fc12baf6db24e83f6b11756a203904db334b6df046451ff267de3bf2138b61bdc5269b538a7e9895e59411a84bf147ae9e98cfd0cd221f1c40e9fa7383372a6f3ca5f88d43eba34290879dc7a9f69cfe3cc2459b819b61c627243bf58aa5c6a7267ac78cf042f46853d9b06c963057574fc01a8db60a3dd886596705cd280d543274e3b8f8e96623c1ac5c866ee533667f6497c312ad9ea725ab6f53478579fd871235a96181e1193637de84e80dbfc105e7572cee58b0188d7f1f6ef51f24e8dbcacc0232833af1324339273ae3eec10f8b0cde8cdeffc02c572ec49010786319d463ef2513f320146103ba3b82745c308eba9a0ea58266fa7dc08955740b5c605360b57c5f66d484a679b773ec9080c49501be08c87ebe00cd3cc310ec0ae14caa4340134e3a5eef9b4c21c36e17e94fcf1adce9e476981795bd72a191e668c416d2f6eeb6e59652a62465070740072e07dc0bd93a300572e1e675c7820a9d5bdeadd42b485ba43cdd82ee47b89784eea7d7fdf723755048f7938988119095cc0947cf74aae15538971cd6420eeb7b2794d3ef9813d40cf8a98b8a5cd9d6a71df5baec791c28a43eed7674617361f251c3c6b2a4c54e9a2e29b0ea59df48848afc5bb693c3dac9c9a9072ff221284f5072e64bba27a8b09d5af4204a1d095585448c88a8fed5bd9cadbe71f8ea42229a9733ecb416815aac34208f1f0e7b5195eaf10761fd2afc593deb71c8fa9fd56af5abb0c8ccaf1e874054cf0a8918adc21f11bf2a0c419553b0e3708ad11ef49d195d56a864e2985505c6de6254ff2510cb8d64b26e92a6d3ac67b319d5e32d79227dface5c25c03b64c6913bf325173c36d2152cc1489f1476c8dc60e44e3f09f43da99346bb81bda5b33ff6960fec2d43e099bd1f7b4be88386df8e077c3b663e410acc7ad58f8dd43497a8dd36afbf11bc67f2d175a9cf7e273bcff3b13d15f2fd043b157a4beef7b8e46e2cb9bf91c03413ad7f0a5d216f2473cea80b55d4471794b885d39e9528da09a8ad74522389c136a42e22f0d8484923914ab57aeba386af1f8d444b809b16cea816bbdffe8065142bc98f51921f230f4722d60799628c688236fb2912b29e1516f99945b4223faa67fdcccf204da4a22b27122ba4edc17cfcab1f659415385ce118831d366b4d4b93c98fbcc621817d24d67e8eb65a92a4cff6d652912d14965a1acea4a31a064f30004699fd14c8811df772468374cf853f463ff73b4ecefc7e2a1cef0d2507ba30806176286228b8be9cd95a6e6ad16e16c98643e05196152061f6adb5d6edbfdc9398f80226db2ddb9f5062748fcd91fdb9c5beb4d6328151629dca23fb938afd293f13e48e0d9f6a9db485912dd26802bfe8b3dec88c035fd47bfa9ef7ac9008ebbdf0e7fbd41399f93ef53faa13f2ffb4de7b16f8d33debbb1939e03a0626a2f91fef67be051a01e99ef53cbc87267cf92b9933a3d77d2034effdf673d6fe3fadeffe8608f09ee681784ff3fe3f461e02e9bef53fded3fc8fd116026985f77f68ae7d1a5ab017befc573ff3ddccea675e4030eba9ea59e05773813a2ad44c1fc7182c6746f4f3fee52110eebdd4e3f881c493c91cd61cf8833a288158f6a7e028ba9864b2679e91ad2b145d4b29e58b0a9e7276695a7eb100a7e020a5e38c1aea9e9f4535e35c629ab59e13706ebeca27305db8508a23539dce01ff7ff53466cc7819353443381c314e38ba38d77fe128aac21a8e327f854953fa1196118eef5f138e622b1c63b5a69921d6100e41f07e27794f083812e64f461613bb7c275d1b7a0e0040d9b4ec34da2686aebb4d7bb282c060b87bf794ee02edee6edadd9476373872b9a7cf321f8539d9d32d09dc6b4b8f05842be12f5dadeeb59dbadcab7d4aeb04ed579a6f485d2d23309db2c55a3f2d787e8e9672a72f0d3fe70d2cc051eb53aef56f0872ad4a3674c9f5ab7cc09b7190476f8a1a92100293e96fb8a3a8354a84926ca5b243aade106292e9d35aab8e1836685143982a5c706156eb0fb9d62f5799ab0cb629d36f117ed46a24268628a2706109125866b516e54ac549ae55860f4383951c198431e7c40cb6e97aa93db208da9466004388f67042b24c5a70a62a044393a002212a65c9dcbe6cf9c2a54eab4403112f6c36c460c06022d7748928c05e9659b278829100e36499258ba83c62f10ba727b4e5cab20516368f3fa5dca19fa3ed14789c436456b42642f6bceabb4f2993974c2514322d273c00859fe0cca950f6e7a3e33ef5db4b0fb73c9ceaa1bba2543887b660224666aa4fed806b1e9f0b7fa8c2c0e31ca20d557082a13a4818ad4d010593964c8fc8f4471911f4e7049a4095fe03ba47cab7639280c9c2e9697ecef5ad222929bb97dd6f985ce9095276e9495b949e38653adbc79c20384cf2a0603b09da4cbe6829207bf27c7f14b05fcfc969d1715accd101d71f71b2879fd3a23f8665ff6d0478944e3eba7e8c752e830a5dfea20c4a64f7d9b783c69716dbdb3e2549292500b2a5d6565ba96f1b121dc8a38b07198490ed1e065078c4221358059afb45e802dcefcfe19fe2c8602f13ebedaf17bba1a45f0fbad1c740fba04438ff948729d057e1e62977eaf75824fbb70d652cf4b721d1fd5a6b7783a0088f3733d92a53a6d054c184a60a2636d890840d33ccf032a74ed1841f1434814e2174ce06cc16a5218ec5feb5041e63fff37380346cfe30014ea5607c4808f12121440baa0d50903aca1160a2d86dabb556bbd99e5270dd68583efd1b06aee1ab7fe60e63e10d392738f64474cace19043583dc45e089007beae7e7108147093f80cc94edbad40c21070f1083ad0dc4116d282be18710f865503850ae6c99504a41c19f9b5639a7a4f425f09dcb90c8becde958770cbb2b05430d47fc426db7dd22d28be12f29ed6ed99422e1eea8975d38b4c56e2a84a951151b266fc3e4cbbe9b531a7ad98244f75e4b3d69690949949f63ca29a7cc3165eb88f6e30d30bfeed4dda5b4a981c17db395baa49c51c3454e96b5c67a6d6d12d34b73299de15adea52cdcd195a7faa8089f8a8ae0addcdd6ba5b5d64a3b9c929293f24ab939b53555069d73f21081ce10bd6d72a6f794524a29a5f2f502e1480d1b192175e10eb9dcefdee1f8fa1173987c569eb456bbdd71ec57e5afcb0e4af9d4e5e3ebe6da79524a29274d4a19a502a594524aa9d7b5524a29a5d4fb542b3cf37d18a86cac5c18a75836683c0ef42eee928b044770aca19452997f83b97524a594524aed6d5fdde01aacd68c67696ad4dc8a5975061c5399db6a64cc70d9bc6478121c0130c3456dbaecdfdd6c90fd3b9c9ef18d5073879edc49659f8181cb868deb06a76ce4fe8e86c7b97eec1feb3bed9ae9775d336db029a5e1b5b9a95123fb77e1cdcdab064e8b8667737f0700ef29695455cd8df355708ac320a536b36bbe8865595d4d4777772ef07c1fa59452ca9aeab5e54949b3497a299da192b2384aa9ace102bb7baae54eb5dbbdabcdd6ceabb4aabcefb374deacc32465e7eea56ef348c9b1ee8c47371a8f4a4a6dabd64cf95eb3943b94565aa90c8f4aea140a6af4dae5dde6a975ba3ba6b9bb53bfb91100986aab9d9133f65f5f0f6c29ad332d1a302d9a992ff6267405405691810c6a6bdd2a4e8d960694564ab3b0f645ed97d60be31b3b43ab9db9c27ea9f7d28e56cb62b1baae7bd985b24c9932b6be36d059bd6e7476543796565ba68cad3602b8e1d9dc8875ee9303ae034a847670894c892385060e0f2c0d1c0f78aaad0183f3e2e9a1d5bfbe2c0daf96563b64da4a3ff09922c5cde3a4fb767476a7d56e38346eb27c7a656d819c84d940a062cefaf007c3968c97326a70c277587f4d173c7ffc57e80a4000bcdb354d19c8c820834f47fd1a35d4abb5bfd91a2d0dea8b34d4bab442e3d3e12ab0228c7e58b45e18c33cd8a7637b1b1b78392d977f5eac4c242c66789b6c6021a12934a9e0a821f349cd04d54766470644f4be173f1daa176ddcc0deeabf1e7d801956d779988ad7f94af50d994fbcce0415c8c88070a9af0d7456af1b9d1dd58d8ea7a323bb4957d66e98306f34ce104e269b4835cfa46945c804a1c9ad5e304436b9e4709c5b643602b8e1d9dc8875310e3a0eb80e3af0a4f4b9dd003c297d068063436a1107081a383cb034703ce0a9b6c609e7c5e3d1ec49ad25266ff5822ac5faea9161b9483497c93e1df46545b2cb200cd9b639adb488a58f9037fa93903bf5034f4a1f1f4f4a9f248c5d5eeb8dcfeb66a63978824e0eb23f75f798f489c91d9f14088cf1c54e0bb3c316960d3c44d1f4d0d492e202950f543a1fb2b84b5d23aa218fddd460f21cfb293799281fb8c8aca7cd63e38a79f5d28725eeeb28f900743be83a294de48e0c2e410f2f5c2994789062edd74f8725c00e284852da61092d1b614daf88be3a8871b5e8a04408997e875d2efa2e7a058728a40ce145174e66f4c5e6a9405cb152e562af66091e4516f20eb976453a28c1c9f4ef3645173599fe96938229327d6a37a5211e32a55fb9e4e420e50465327ddafda083031513e4e042a6ef395ea26891691352e0f18a3a50d8cc8cc04d578c1607585b68a0c4e0021e9a8122f4c28a5e160f4c544d2c612a4e3e033411b5520af29c545328e94690f44141810ba9273c2859b8c07550bab80618c1500a4a18306c475c1420254c51624862002786a2387161a916258a0b062041541422036ca145a1c2845e2e3480134b51987819c53aa6650b316cb8803924b028304cc1ad2cb33cf9a08114d826cb2c4f48884cf08c2cb33c49914197272d32e0e2290ae604af90d4a8823f2736ca60d6908d21f08a080d76c038a9c613be4c3570c03335510b5e6599258c164c61c0a8410553174416b08d013606e69e9c00df285b4809e307518c510d1bb097651631546a1c65119374a41613b3c5d6a493392924302bcbaf5f18065f292fe82370bf510a5aa048ee14787bfbeaf7d519039d4722790b715a746f5197c5c4609fc205c4eda2058a5db885f108c214b1618c714be90616dcf09447fcb48ad32d98eb965d0577376f5c33601fa9c733a6e011a7bebf9b9e6cd93e02cdfea927f8738e965212a9beb08884a285312420a168610c5af6fb94e3387ffad465a8c54240e58e87f52be55e8242dc3bd9bd48909ffa1da9972ab8a42f4122cf41dfee0d456858e7f841ca0f600b12794f411cdde37d7f2ce6b21c6070151ef2289b7498b8269d2b0afcae16a58bc0c3257379cffd9bb70db4a0dc3102cb5047eec8afdd5feacd5d0098b08ef4997912f1a72111fa5eb885dfe22482df3f4ad5a9c019e5b04afb81c4b1c3eae3f7503aacfaff784f7f23a13ff5fd2922aaf0e77bff2dcc6971ae5ef58f55ac577d10d6ab56ff839f151209b2fa51fd785618fb9574588ed81830f4ab53a039a32c14a1e14f051c169ee0b0eafd98d7f6347c6d21fd1ffc1ed2573da534a4d1b0c8cf1c72587dffafbe9c85627b30df7b2b68ad8f630c7d7f2449e87b9fc4ffa3ef3d10ffef5b416daaf0b5d5d716fec0db130caec0090536cd61f53f1003e5fa9c18dc42f5c330b8fe6c9a4935e9db42da6227bfaefb0de43e9532d21f391b7881c7f76a10264196c9aa26ecca4d690946269d4128773f16c99386eb8144e40b8018439b11790551153902055ea2663fdeab422233cb0e3800cd8a7020050c41b38e6a0ffae5ac88e442862a42332fec0f9433d79125a425ba24c70b4573b2d2626f791d61e9deed515e774322ef91bcc76ba4f99130f34c016d246107da88c2374273e98ffb7602c3a979c6761abdc8a19a67742427538b1a3b6a49f38ccd25b7182ec678ffd5c3bff63bd27b91910374a11f8563913cbfa1644079826d942f28c3d85244cb0e1a41e28129cae40df49745cd33bfc7b778911fcdcde57228177605d1bc47ce80f2903bbd8ed80277c2118b39798f87c31ffc1f0e5ff3677e5e53f541583346e16bb258af7a396b16e84e0ee5b0ef3d509643d603112322ac377afdf03e0172a6fa9aa74335e0091f58019e54cdab7e944d56d0680eebd5ff1801c1ef7dff83c339e4b0a079e4b0315ff89a0b50bdf740beaf098918f9f41088eabdf766dec88c45f35f8df747e6ccfb1f9a703239ac5f334ce187745802e4cc0487f51fa9be6936318da999504d5fcdffb0bcc7615007d15ef3ab79ef83d4d484aff935ac67853fdf7be16b862f04785ff341bcaf097f8c80cc7ccdffbcfc695eb23e48cd4cf872ef83cc3ccd4cf8f29ff19ee669bcd6d3d474d00254bea505ba934371636067f2a5169de64beee454d4475d94db432ceed44950ee1464f5a3fad53b943b2d60155220a73477f2aa38aacd3ea7e9984b290f94339af43ad2d1dc21e9eebed7e5925e28a5f5012dbabbb7839fc3eea639e48efc98ecc529bb3bec965da48d7877347436c7032692e6a18f3f2665b247ce205ad417292515593e0a0e90208490a70e52ac40210cd5202ba58aec3fa5587fea604576b17e92303ec78657c8b54c762bddddaa6e7882dca92fbde46a240716f8a3c97348183dfac0989412e63547f697b0fa29b0eb8fecdd7fc20b914db7392f40261ab4e840c68b306ea8412cb14d7aa82f7ece5b31b48527bc58b550c33cc1b48277d1c2e54038c3ad6d58704ba48262b663b3d25a690d16f097a59210458c21c4942d4244b13428e91c2658760068be27440bb93eed5ae9bf8e00aa1845193d512962d43f2f9411982deef9a51941e132bb7928eddcfd7a97a500168a64f76e760a159986f386e3ddc2117b8bbea82c042656b64d22348f540a6229cf20bce45492d29424733ad7c4a9e3155869bd7a3dfabfb3877bf94f2499c8ad9e5ee656cfd4864cee06b2c78625348c3e0d65c3c601f08c2040691ecf80a4995640fa804e7d053a54c20f1e4bc6abc210155aa443c20a04812f7d2f2e2a32a514082fd1a73fc42954ade17e377b7bf9e9f0d1dbc66ba7bd96c6451e71be933623df9f136886938684472fdfd4bd9f0af1a4f590835d54ffd6d0fefd8e227de41d7bc98ffdc40b7b68389f72bd3fadf4fd09a57f7669f55d5cb66071519953eea7eed3200273299003abc0f38fa84dbe3f6fdfa121fcf23bf768173cb7344f33d5ecbd6f5fcb3ce21291efbd6f8ff09422af0b04d8887b276dfbbbddedd29f9f2c5f51facc21b973ffbe0264cf8442c29898b46891573ef8401441d0c686c5baf77edf7b7f9cb4fcd7730d6dddb5928142fa90c3a40fcd15cc60aeb5d65a9fbb628bc0435ee7dd6ae55ef0e762c04745cde3ea82bd86a5fe0643f64c2aa496fa4c4c5ab4c82b1f7c208a20686353b93c674deed4af453e44471f9252e4ceec41faf4d76642dea85f8b724861ca9d8aa536538bf53beca5166b95d4932e0bba1916a64c64cf0974932dcd5b30ff205b876cbb06dc2b8041a579f05bd6db6f26b2c785ba903ddee430e943b34dd9af35acfe3e0b9c605ab48f417b05db22b037794f7dfb2e54e59d496a81d2619b17712f7031e0f9d43c76c4f387a25412b875381572c73a90f441923e7e8473c081b43890088236360e2404044e026f368923913bf6534dc224789c4dfdf3de24202bdb5a3b9de40e7d9aef4f02a3e030fbf762ecae1702ead30f529f86488064b3995772672d18c038bfc8f6bbc8f683d0a709914c27c9817d25773613a2e0d65a2640b98588b2fdb63fc14481ddc99b869ab2c5d247faf474923bf6b3ece91a562061f69998b468b922af7cf0812882a08d0d8b85b36dfb6058fb36083c7ad9be0365fbd6eb99a00cae0041d320041843d90801f6c068f0846590400c836fa8d0f0430f5e7e1012bbf80106b10abc7a0116633420c236592a159d40dc01d764a954c484175434d001b3b2542ae2c1865091932745405ac4d8a0c953161867a944d4e5044426d8801605080606930649b863a286126c97304289e8034c4440d8d082b72c958878f0614eff6eab57473a6520696459abc9f293e5947f6c88dcc98084f573b1828c269cbdae7379333a9547af87adfd6ca5ab16f67ce5ad4a2ddeb6b0042379ba2a75f9f43a4ecea7a33e6bce1c8b43591c48a704e1d69aa0a6bc413d29592d55cd274ef73c2a6578d2a3299b1befbe365b43c16d9b7f73f391306987636978423a413940381d9d8e3f59432303261e0600e87e8f36a98c192e9b9b215907fe8694fef0b1e6914a4a185dc9743f980274c515474041c152a58244169dd36ab7f196b0b91893f993c78e7443cafbde5bc311d370e6de5bfc28b7f42479073ef83043972fb490c169e61ea81285cdeeee2d031e316e9c7657f3c8dcb31ebabd79db7bd2f3878c6a356d4e9f41d3c1f1a64079f8903d43648f321b903d3c96e691251a1275df605765e50196d0b0f9dc93710ee540bda039e49ec354c90c85f69caf21dcca5269862a799c41b98416271641997beefdab7fb7c999021d227de66637ba6ddb6fdbc681258077ca56cda0a01fd913812119909e0464cf1087bd181ce571b3d611ab40f9b5825c0a747a9dfb5bc2b7433e51f70d689ed8090d6891c70c2b37067fc63a416207d528d149efe92b5f94116a7532bbbabb7177775f8735a6d9eb6eefeeeef65abcdeddded6058da4694de48efc9512980cd49353d214ea204a29add45b4a995c1aa294e21a9e2f7f8eb329cba7b44b8bf273b4982b78caaf1183e5d734a5d49b524a699d492df250f711e0299b5221f49fe60ddb2f3b245264e645ba6750e041b55aedffbf56abd5fe3f6989e9ffbf56abfdff77d004a189f4b964ba073b3d413575116e72393d54510bcdf0ffff1f4c172e5b269625115ca97708171dfd44ba40ddd3b55aade8a8a8a88b7e740d045dab0975a935d56ab55aad56abd56a35ef367501438518649eaaa8d56ab55aad56ab79d01fe9ec745aed76b9546767f267e77d95e33e15bd57b5f26da3ab5837f32cd9e4a2d39680986a28788f283a2c0578662061f55960fd16f22ad21b8a0cc8f6eb513beccda709824b9ffbf26717f9134b6c224d2bcdc3bdfc7ea6a79b9ac9752fc62ed72ff912153ca548ce225a4fa12cb97f9c4eb2fcc9448230b1cc1bfd92e674c57c856aaadb50ba85baa4165241518193502fa95a28053912d63d0b94123697963a550bf92a945d03f2fd2976affa7a7c4e85aacf87ab64119e3fd4505aeceea1bb86b6e22aea1bb078ae610bf50bf5ea1b81fa1337fc277b0f9617f39e6d06b56a0cb0102247510b5ce00596284f3851c4154e30e960adb5b6061f5cf08219c22ca104083ac9cb096e1212a37ac55092263b34f1a4cb17274e6c5189b842cabdc208870eb2b8e00b185b64698111f5083741e1c15eb1c24cd312375ce1845382c3115a94184af08014461d02045c962748ee155090d45a6b2d81184b0606ebe58a1a85972c668a349822040690c00287114c11a6c9163329a7796e9e33c9262182cad01412601ebae01b9e10a203415d82a3329f3d8284e65176c90e45a61ae571d226d05c32859c8825398fd34af6a67214953d004d8628ba72e5ca0c2cccfc633c4e9072e4055f4039e1441033ff19348b3cc9aa8e58248bad73e0459dd8d6850a76d8c24b91951cb4f8a18bebc08154134a6e70128515485e70e1160890baf9f385807bbbe97dbf79de77537f5f08d86c98fa1b522e05e688b5d31008f75dd87e432e1c63a1c3a6ffcf7dfbc3fd06e4be0d8170bf85f8b3c02c937f8ce8ffd84ffd6cdfbd7cff5e08b09f7a20f653a10864fb2e7c8771e06bfe1b995d30f5f7132067ae90080e2be46cfbf153b65333fbdbd726a6a47207676fc0097247be6784e7c75a942f71748fe01987dc915fbfc0217da8b4b96a0007e562381a70824c862079b6cfb593390c662061dcadc9a59e2c3dc81c09997ad0352a1a19302053ee3db04648a63f45ee7b0399faf07cbfbf03784e4d231407acc608ee4d11ab570f87f4a13e3bd596872cb616ac68e10bfd23a4ca6502b422b43801921034e952a72c81258621ea0b2e822f5c1430d45a6b350192db4215a0285a40e22f7c0ece52e9a8288f1fbb5e0800093cbefccf1175ac064af866a97434248e81b72c958e6a68131c31b9329924b11c1df132c6568778ca5d964a4378916189b5d6da301f688d59d244eb8b314b527004e83b526bad958b0e1c145c8078a116610598302ab8428c099284f1c3064518474a66b8ae219686b052a543681e2ee575aa6f05f290b0fb52ca5b94650f7658d3af3209bb72c9089228e3910273ae091cf852bc2fbf1ed4f3f6f8debb59db63ae902b5117b61ad65a74a28eccfed441c47aa7bf43e6eda6783856ddbece3cae3ccf48f6c231a65219c92a8cf11bc9d88570bf92592564f51cf72bafae563be4abbe7d16a8d330fb1514b9d48b62f35831d63cdc5bee6e7fef9c77daaeed169dfd252592f288979440ca7666bd68cac9f62f879f7e3a2c70819953bf43666ebbb5077f5c0a9c92b2147024a9a3af7a5538aa8c641a8e3ade774672178eb1affbcf48fe7aacc6ef57a191bc0a475927a4be4a0a517d55a55eb5a382ae56ef90d95efbd95a6b3710079939ef9d3766a1aab413cf5a67752ab3ba2783a58023b516a50bc7f2c764217c9db34e20e89c73fad359ebac4dab774e3178fc1ca7230e32b5d6d818f27ee02bc834ba3fdf2bad94d254caa6524f53a930265bede05d1f62caa72395024900755cf04542cd1ee851fb77bbee479c5a4cfdbdf47e4e419939b0befcb617f5177d9a690c31269c20bc796013d162313451327b05f929229d88528299117d2f7c059929303935cde67b2ee6a6eb240a542a0bdccaf2bbf995febf101aa02fa8b46df844b5643403000010042315000028100c87442271402498e8c22a7b14000b778e3e76582c1a089324c7511404418c318618400820001162184254441c0020516c50695ce0c5a843790fb716cc6ea340f88e8727bec67ff44a591a7d4a03d016515bb9882701a944cf604088a9ac816dfba7aebf6559b1951f11acd87833f99578132e8b05894b0396bc3c14fda0d81c251ae4becb11b87d6df5b3b22abcb0321eda997ccf0553aecfa2271e5203fbbb049c307d2ddd77ffdd1754039b8b1d2194851b34e639d94b16d7181c34417a142328fc0043766f574ed165c011b932275e5aa5044c2139dae091585a8e578a2d1336986dcef41d8a343a2909289e66c6fb733806b46ba64a4123c90e2d87cd49fc6e03bb9a0322f89e04b7144b6a4664b0e235b373cc9dbcc5d5e9d5fdb4c8ed074022da12347a37f75f2637d809ff5aaa49c1207e4dc0ff36febd6f733da9323a466254a02390fdc1ab8de241832d2227f81dc8894000d566a6afda11e08d31ac4a34960b097c22b653a056ec1c9659af2a2c92d5f952168d6d5986da6a861728ed695f7c6c98bcca5dc585b20d0518e6d7556507c6ccb4a8aa2567ab12d6b5f718f3e062835b4ed068940d137ff25650e8471bd865f927fa139ddf988d7bf7af073e58f322439d70bf6c7bf81e675361d6008a9efe03c9fedd952df8c548de5ae9927cff1c0ede0e57e01cc7b5c0299081af12e7d99a239d46af049179cd0789f2245cb38d45bf2015786f07f8e1a444d1c025635f92dbaa09a50a1de1fdeaf02ea3ad1850150a7045f6e050e9a2af0c47432503e80f843ffd477f8bce44b7a47a9ec4daced89ff4d5e0b1d45d5fc0c678f68eacf4b061d677700538d4a1cf10b87e09d69bf802f9217aecc4edf23d0ace0ceaaac108501a41eb2d5ddc178b53990499e3bd7b804cf315ddc373618138c396eb1b57f2049a2483ff4f90f0322dd830fd256ff00c58a483c6fca47dc0dd3bae6e76f484a42bfe1f7a8d396f725d1c9a65527795a846f3d77abd5516e4b1c1648c87d555170d21316494f28c21cc8b32eba08697c5b3e01b72b4be9a80c61682a1861b4266e0a026a09947b0c78eed58bd7b674232d34f3ee7f09b099ec69e57efc7cd1c6a0907d1d0b3299df18240ac9ed79905926e52d70c2b08e8326c3dfcc503b8f21d7e589eb1260be009d1fce33223a67972f8dac80c55953eb04bfdd6b53088b008f77a3471df79b12c164b189474cf3efd82833d3db6ed2baccfd79e45b364011f2ad740de9a8407745e2a8d7de6218527b48a82ad9e5979aadf0ad542059db4e4eb07f06d3b5a0f0311f719d8e85d7f1080d21523f8b68c310950d4300d1814d8d7b32127e42d4b5553eac0874ad205acbfd234958e4a54458423f57cba213eea0326806bfd7a5852a4fbbad310b100e89ac16834a27c0019f7406e91b94b91acd056b1e086f0326a5e1fb51a64bbeaa56bafaed72b597588ecc825c9f9f1d18b473276ebdea571e43284a417ffad8d58c788d207cdded3c885732d27e8ba41f2c5a5d03f1765913064f5e9dbd73d28da823dbdf12dc756b1106e6793d369c239adfb7dd33f786536e4189798ec9f9ca3cc61a638e4a5ca04083d6548ef7bb3e1bab03d208abb117d6662c2e16ed826661bd35e3aae3426342d13bb8e7c569d7d719931ec6d173374fb16bcecf9b05870168fe1508c6eda0ae5867260ed3cbeaa26c4815302c657c4915a5af1328cdcde240804e073031cba83425810c6b8013a379c53b30b17e3527a427b35937213b184d4132e9948f5438601f71afc250e2c874f691eafb9a1a88252063870888bc49ccd9e60c85ba3651afc0b875d9e0f69f5910d01be54d96a5bc92d9dbe7c20450de810987c49b1ec4a39c71e988f3981762514d65a19446c0ed02a648abf4b43e7910c4ee677dba24382c020ccfe9f8c90c81c12fb4c9a675a66fe31cda40caf4f4698734d3d8d1041ab89e910b5c700634d049f665aeb12d6fe1c771995dd38518b11a01f0fa0a3ebd4437b8733e2628aff07aca3fa00d3b69c9fbcd178bae094903a04265bbc15b8b67701065c920096c17a21aa166da90b79884decf2d5da173f54201b7919997b71bb9ab38089fdfebe4cf5c88ad97802c2ca559d966c49b1caa2065e3bd18cc909659a7da867a78ab4566445521db5e200f5698186f40151831a1404ba072a1cdf1ba4319e93458fa4db89c9679a2b4bbd895ba381cf36372b3dc9bb3500e6dd863033007b6874ab93f0e2d795e650d0d768e9eb827b654bc44a5cd6b404ad7d646d3ca8917eb37868c8174fff3eb4372d147d9d1ff188e24667fa9ee0968a7366c10e2c4cbef1adc26085982e28947bbb1c907cbf8363e5a3c4a5daddcf20f8e96edd4c5060ce4b4d5102f4dbe2cfdc6b523f559a4b7b4df7592db24bb0fe1038d4813adcaa8b42055120979520b5ca66ce2dfb229f4be442cd08941a1591ad89622a79db854716fe4a94c5faf8e129cf94de03152c15338c9c68a0790bde558927e4fb6f28b26fd68c55a61a1a8906bd6302deedc17b2b996b196186e54a13cd3d7c2c407a9e284ec8dc8add9b6fd1049892eaa0451f25be43898ef8d567697653862cc6bc1628fa5672906520457d2bc90a4df8c8ba0d041aad13904562a33b797b1bf06b63a33bb5d9602cab57fa57b4c9c729ec3691d09be1f09415dad8cf364190135a7898d270a88c1c200671b8e1c767971b892a02dca774301a69c277232c08c7739d1a0ea04b05e44f67a84c08d1900afa40c3b704c9b44bbef45b57eec3fe374b339c86451ce7300f0d58c0c92cfc22850e9c33d3806099e4dea1b02589b7d8a2713799084703ca7f4e5ac476d70fdc7a6979f264d810747871fca9237808392b5bb4ca721f4c99a7a82070c65e7794c4f35bc4bd1aa66fe42e76a6de91544f5e6a63d7d77c9e190d0f5c00c91a5bfe856dd3770c5e8b44cc5a6b145eb348b578e9e2c74c6b9abf4e4c67c473c8e91b57f595d54aa527c8cf69020f5c195dc4f3cb351a8ff6c5aa761bc46aa706c7a7d915363791a760476223edf30a6ce021b82aa8a7c3aa20603d009d37640a3d91e0e26b0c0eac4d5165ac679aa2884cec34761f38dbdd1dd2ec38dc3a31b4fb88812546426777cd3f8d24dd4840b301bd1f0f7945cdc8efbe6fbaf30fcb3f6033def57b0520255f1126e4605fb55d2544a1d3df0f77c64eef6a49dc46d89373c6989547b44d06925186815edd9cfb0197be2352f67b36f602d480af3c620ed5a206320a36b1529ce2d9b5038061bf04e5de27b0eda846f6623c4a221fd76652cd83572c9f2391b4600e92d9e3729e0c005af50d79013f851d7c98144ec7d9733a329861b046ae76e4d228129d8d46fcfeeea1580586971509264008285f2bf81c6dff8e9b3efba76dfd97bfa8fa2400e1b00a77a75e2278d42852a52d3037e8897d437e1afad513ba13b24821b0f604640821f003706f93e6f1936c0802995ec54d54ed25b18e5a9e4877c72b7e3f9b2e61f8041f3cdbdb019f7f89a0e1af3fbbf76140ce2bd03b89e16b36e0d52b1704d020a129bb7339b01ac4398c614162c0be8b55792b8cba87f93bb602ef2ae0f499b9191132c82edaf336c43a81e142947d037e217cbd06c9256fb496e75d4cb0a48cedd2cd3ce05691a418996e99ef4734b59626ff43a8677616ff544f830985dc9ff8e4668a5ccda95efe497fce8b890172f6ed0d254119ae31f69affe67fe8251055c84bcc7c1cefdfc6a007dc9049518ae28c4e559c733f96acb5e5ce305cff268f0e234be81045a5e9ec4530f2ebd060c813ccc892bf88d395782fcbbea4ecf2f9e95f91d090f47b2c9d1ca48058de4fdcf60ce8ade0916b2cfe757f6feb9d2bbd9f2f66990ff89d46eb16f31827665765909e4c5d2dc21d2706cc273b9e69fca00db21273ed7c06effd3a3de8ebe8506f5c5626f40927f7b3061172ea62c176c449fcbd5c9f41e30c4f8818017b9ef54531cf731415c7e875f283e601d9d3234f4fec46018ab325e6e9fb0dd8bd58f741a7f7832f8bdb81eff1b8e30bb2d955ac7c7643ea6d1a99779963d6a4d811629cc1975b20f9af9eac32c67eb9b67ee3e18d48ba7c6d8cf7ffdfeee7fba579caf0ccaa756587dd14e6aa8e49e8d79062aefa82e723228a2aac0da806056f60346e1502c376fbc55e1c7223245e9af5b09312f819981dacfbc1105996e88f27b6d2a260f2b6ab12d9b3386f80d78b0951874f8cf63133dc63bb2ebbcd76fc2e8805d8592c5685ca52edbd920df6a4b53718ed2d791f9005e00d1ef679edcd3ebf1719f808bc9c700ec06ace9efbc31d32fe3d033560c3a88cef583e0e2ca13b574c13fb9b297b9d74effd5a4640313abc947bcb48235e330b49da7720cf9fcccd159616af63ab41f5bd0478a8a602d9bc9345c76a1f2c768d0070bc2df3b9762e401c97e8bb2f1d1c6d19058897f729c16fc1cd33a788d110cef8c3e94e29b425e7496b49b33c89321d1774aed8e672925c966d7903d63a11b64323fd284267a03a1d5fa3925e58e785e51b5fd4f6fdad90eb72e7815b31d30f266b8c2f81da0d6983ab8c9e22618eadae426de7031deda7ca17804ef99e46544911d6a769f6ac7b23e441bc96319da1c8323726704782029267afd29635a373c2f97ff12136392efd0528bd44f635503d2b6a7aa3dcb7de011973d9547c7339209d46e40af776701ef86499c7628ba36146d1e12433b552fe630ac42bbe30669a6e871ef3d47e93023ee883ff5300c865707eec9ee9a041f818cd4188046798c741828b83c06ba351ac3a22b6c5d6e905d38ae6e37c40f0eab05871c69e0fcd2a190eb4311cc53219b458caef1b33cf7a71a8e80fba422cc9bf201ee431f7a0b6e77f411ca25b0cb22cdec8c9042bf84d26ef4de0256ec37278ac8722e894c203f5feb8ca2797a02f9d3845afbc130b3d9ec75f427cdd27f7d0449b07dd2a95f73c79ce9038fb03d2af94f4745114b63693ed184d4443adc1c26e7d5f5dc574b4ad1ef626146834229e5c9ed63185b7ee020c950d1ca715589b0a95cb61a2637b8bda10120a0335f616e821e4c2882b6a2bd8fa25bfa88924d14d7e2292e54eb4f7233ace3da17fa6f32ecdf3bf3a4794438f3b9f832e73723d0d393d5596eb48501bfcd3280e11c7b70a73b08927a43c4f28ae722771f07780a46e16bab5c3c937e23d8b55397514cb3a5cce89459f55b72b4088b91caab967ce8fb007747b3f38a3377c599d1fbfda1d4a7ae65002face8fdaca2b083553e87de3f5896e02805156e0d71ee5944fcc450d3938016013a8d0d709d97fa9948ef9207cf2e620eb3f2bedb7529e3901a75719cc88517f5102c4614d6253d2bd9d7f3ef1a96687742503a0360a71dc85094c76be8cda0590c17f0f5856b6c8e9c04d9816f8fa53b6c8394a6c2933e093dfc453042707d7f22f6aa79bc4e0d6fe2cdb17eef233ebdeb8570bbf30a952a69d90df002c1a0480005cb8a6a12713e7de42142ff5848b3fb7ca268e3e2a3b68876b6393064d894b7326f428824b0042c324be77ff4145704f90978a4a6277695ee7ac18805e2ed13220491286fd1039bf11f3b1610a83beb79f175b014af4ffe380c305f36abd6dad40e8e3339f4190bad78145bff7d0ab424c4e3724da2d3e20512c82eeb3075a5f26fed40f12974b1644aafa62b1e97558fc072255533367b0746defebbaf63cd091f31e5b1f0a80e5c22c4c34e1ad68eb0da9b6e09e9df2e4b0e440f8f10812b210395bc14e20474f06d54d54ad78ff27565432b1ac53dd1d64e3d7e9ab7f50875a3c330e759e76a60d351619070e8a1437715316f07157f0333351c899deb20820ea568cb675b71c669325247b479216461feabc23f2797848c42651ab3f4976d9de701e71d5df03180524ae6cb38a5c900f8924638d9271e1d4aee733217a2220062ef1ac5a6bbc00a09b7bcef4cb41146fd734fe0021f35c9287fadb76cde9ecbf00a4f8639982f1e20e837f12e970b55d1111850b10aa575306cc6c88937e41ec789a0f81da85df593a2c7ee0d7185a37efc0d726ef8a8daaa73a9f1b88eda2da7a2624a503349499692a1686c99990affad100801a63f31e2500cb32ed3edd8d85746625b5d94d4225971d6647cdbe4bd87d8bee7d788c2e16218e7a432810dcd67bc6a09266c149f3522282231aa885afc0dc742dbf2a0a645f40e10621d709016b6dc03aa38218ff47f8449dac78300e3abdc899cc161122be8f82e7d86395571c8db99ddfd8a92c2efcd3c0e9c084420cc8b2aa7d4846800d08002259b3ac371590cf50b80d50abae4dadc004c6fc387daf60d0f73e51a4ebbdebd725381e06c13d8afaad461d4bdac6dfb347e95fed32dd84707d07f32ca6244b938a2df10461f6158af9b71d3a2c966fd4e73dea272950b851a9846c02d36ca02d0b4c621e92e8d7300e05c198977b57e34aa1f504a2cca1f7609b776c55828c90c35a604d1f1af9e1e7815fd1dc88852026cd817d3d94a7aae6155ff30f6903703fc50f9ff9eb9f32fe84aae19c40179be7c0e0d927fcceee2312394cab7500696461cd20543469c71922e4c15f3a2840d5407946cb9c13cca6667b9bba34ef5563a2fd26b26adcee9eaad40c506deb068c87c28a25ce4ac7193fb1981c7e03c56ccd12bf8caafe96371002092766ba901f13c105ddae20b71281e304e62c78ef5ff360869eb60b84e979baf76ded16721e89990fef9757c959cf270fdc9007a92d0fe5860f744b21dede2b55f9f9facbed30acb4f27b4623add5a6a1bd44b4074fd531a3e8219129ecc41d81e185dc3b0467fb2b3193cbf141a8f30baccbd51f155ca065344ce171ace7d4a80585a11a6c073a9e3282a338de6fd909d7a9acd2c9685806d11f6b7a7ec843690d08de4758ca4c016eba7dc9475158dd36f00990189bd5b07a54f0256b2b59f1f41a361447127df7aa29af93fbbb1ca757b2b221c4ff0b4c464656ba560250a491a1fddf9344815e6eb19820539aeb0d3aa57ad05424a6be231b5624c67f5a3d28fc18442dd08512d909714dc8874a1c284a204882677679e184128b933d9e96c3a196bc83fc902ed313405ad257de8eaf0c1ef734314afa34d22b70319cdc419cebc698275ad5a7e0f7d0e3ea6634d65714e8183f24c12e8eed247cc5246843acba50287daac8dca394037d93e7e675890364fade86dcf4d2f603b7ed025608e698181ade8fe74a183a460f203a03301d1b6d687b5cd9af18f1266299f29bbebd3d393958679948eff17f5d158dd1457c15827d625e69fb0d0994f255bec67998c9ed902f3154110514b6f2984cf68f5cb7832b6808238148056ba51412fb86afb38d65140d111bf3e1a0d6b5febb1cf09dee7ff98f06b893b65b05a6871d696b1708848668c8621a0858a0aea2316c3a20e1e9346114f45f2c7ab3ba6529b167b7dcbb1f478316de045103127f2830ecd763d92e2372dc5be9d1daba5e0b5dbec18763e8256adcd88c32cf1623a6f54e8bcb99bad1a52ad75c164fdde84c114f6257022b386c038193941422130a3cfdfeb95c416c53b25ebe54777de417e7a79865af4a207329b3f84f366d0a115a3919490b917ef14941df2c6f27cd04f0aa8106e628e92c76b386abf9a35580c325f239808d13633d2359c95f935634f16862110ff3dbb64eda2e78e8b3408b41df9a142ab8e066798910c42a2e2c86f778a7c4c39fe0536876d398fb901f780516ee6f9ef91c001a22391747873aa6dd654e70d66690494da4be7e5a218b911f7c3464ffff6ab5c1ab906105991e9bedc147b01a25e2358f3e3eaa9f7e2cc1d9d06870495f6b00a236a19e17dc205baece553bc2f94b87286bdb113a4d907e11fb802b7fe0dc3748c6ec3ad468e4b3ed691b59714e2f8d78834f7b986706e245d9c5cb9c345d7bb1f6a1137232585459feff0a33b540bbe0f55bb801b70a63ee3423c03db16171fb19821ea326dfe2b6b058de401699069f75d3126a97a81111305bd5b336deb48c95a6c1d60130176523c1a6c1cc658912e047c54912e0da4c0514ba39f9e0cc0d06cb97dd6c367b37d6e4b20fd160b7ab8bf4bdd8fd4ac9920bc6742307d7814a0d64e44f9b0270d492111e8cfc43606b7f509b96ef2e9b1afea5e5b380a4cdbac54b35c5d77e0a53649601884b4e9dcc7265c8e498f944bd43268364c9c57306939b6bc52edec8054d740555c151c6b366a55014353356c4151efe858e441b2afb29f095e4aeeca0a9ac9c91e50b5616c75e515fb0bf67b528f3938124b02d10729b82cb0f88bec6836f3e3548a278eaaf5e6adce52bb018bc2404dcdbe27e4ffbebb16e9d44cbeeddea399ee4662674a28a2ed795576d3dcabc62044de2618792823058d130f0f1509dba8dc43108731970f7dbd05fa5ff17b93b6ce01e5141f63c36b34d11cc29939564804b9cf98fa249f296e16bbef9e1a791500b98c12d3713c4ac9a4cc2366519616a1fa155cd1146e33d8d35c111406c1e900cdfeda1e2bda1602fdb3479910d1254cce02482bdac45fe2188feecdf23492ab460f7765237debf4fa8f7440004671866716f439c3939aee079ae57790828fa349bb9d263a6fc53de1aa65f7c8343b6522fc59a19dea1efc54fd92e99485c3eaa8bc392d5adbe0d2c742cc64d08d007bdd0274dfbd7e4e16846dd8fbc017e984929526eda1fe97c23e71d8381d45648df37bf40dc991d9685a022fcb2430f73a8d1b755e18dc7a335c21f25552c127023ff180623d74fb8dd498c7c0c53986b17384ca4e0b1a67b96217030aa7a24d6c39dc41cb2103491bc06e0cbf638e0967e4d8961d5c5371bf354eb9a6a7529db08ae3ecd5bf60a94215cac55d92a107263f92e2aa3d2f82b120e70737471560f7b132f5d6195b82ceb476ec9a9f86afcdde12742402a5c9b227e582e934e83f8e04cc31d5072c195b491a00ec454738a82b297e36e1b334539516d6f86356708a0ad91bd17a3e2861af30ca145f18c7c98b646ad40de9478993f9918c256e14240ec424ff2200c2c2e9ee77c057e3cedbc9139e2b92032df6e4764cfc00cb65aae672077e2949452beb6341536ef657f79690eaac86aa564a4ee53279d7d0d1bed754bcbc7a245f24a7af98b0d3441b6a1916bf360ebf583cb3968289a564e3bee2055ff209388f81058b852e52243c1c49d7bb9553d1a7b649ce25e6c4a9c335932c39808f37026ea32410be16d7f918bf9d65221268f8996c39bfde4374b02342db7ac237feef2f9ce33994f69f633361f40cd70a9e6550e6c6c6336706df0950c26c55525a9f44bab34ea4a8afd1217c9e9d685badc00a47e5b009e6b15417f3c4591815b1640ce00f2774ba163c94449cef009505adc4ba48b53c434ba1431f1f818916286484b6ccdeb4f76c9259676a760d0f2e9c4695fecdbcd208b0e41e48ed125ea7a28d9be7c7e9565f5e8c921f2bce7c1fd8b03702d2831c039864015159fe7ea8654fde8f5fbce48815bf8955762b616da05f0e0887f2bb9f543611ccf635d94c3a751da38183f71316d079c35b84d7a9e628466c05a04bdc88d3979fdc3fd67c08e578541e6bade0e3161a7a8670a9d294c18f38dff319506a02f9bc8ad80b10d6cce1fb2e68f083b03d83cc02ed8640bd439808fa0e902e9b1bdb51c9db84a41534b246d4e5c3ca981264787129b1164a8d6456cd57d4187f155311b785b7f2de477dd1147a6c114e445221a6ce380101048e1501d44f5898136505f6841ce181730c0e68bda980f9804f9de6be6d8c04235a470124c35c3275b6b78017d61b3f6b8d436161f09091c9ae7db61feec1a27c02bbef8b141dfb41c8e1e268841a225e1fdc6237f6fc61461c18aa4161d06920ffe6744c87bb25d75a6308343d378e13eb44ee71f45f81b16a12a7f16725efc8cb585028e814547180d708f0a2c98d102e0f5a93cd99ac08949ecfc28accfe672a8b9dc0b44fcbad8fd1d461c76a4785d57f3b04ad5f994c4f8a3f60829484df216ec4399961eedee8111bb59b041e9232cb2e5993bd508f2dd3f02caedecf428c0189316ba87f4fa5819c0a9da6a8396dcf9874c9bc4455af3a5263274cea2697faf1f10784c703a3a8079ccc0f26eba12497080e1e73aeb9a8f995a63cfe5a93ead4e1d7ed9921c0c21b78af7ed9d9d516ac8d00726dc9d5c7922829ff2654d64ac3df22dc3e9f27f78b38f3f6a80d63e1ddfeeb59c42768c893168edc5435f85e6a135ca7173c5eb892df138fe7099c7c8829fe128ef49ab75ebc582d3fec530e87b688670d2b3f51a59b437289555cd744da04f10a7100f8080d8d13915d5029a6771b63da6340bc2c2b6cf1e7d87b1df146480e60fd6c53be531c02d7f31a4c50820e5319c61b4931c81b57f89064d8a1f5351c85386f431286892426ea9e95c099215f68c23817d38315e580e39936975036569855f2024f0f339652b4c51e85c75740ae3d9fcb882437dcec022489ba24b4e6993678fd4c85cb6493e69b4ac192fd4f77afdd3e09c51749d9b93a75d90c5ece0c6bd9eaa3a37a5612c74ba301f3eff94add6417bd2204c220f90dfd1c927d606604f87ca2dea73556214ddea13d917414d96099315a11c3d302b2b70961aa432ee50dc165bbba49cf4481907e71258e3e5a0734d19c2f008206abe48c8ba99067c19fadaae9a0899c96abd2ba3ab69162c91a215d5da5881e614f751c69a74c5d8ec0541a44321a03bf1bd64ee391915cd5038d361e37ab2792ac553080363067d2aca54e2722fc544d63423332d8bf308cc08e3d08c33f425ce8e346d51f7e7d94c3cc1d1b7fa20bc3b0b457824f69f89454ab1e1384c73e0e64fd7801919cef697dd5c24df6385aa71062d7e3a04952949e71af3804bd0b3d400cd8cf99a4d4460f3a05c4942d15477e4143f86439ee2be46286be9d90229b1d7881036e0aa80270a7e47164d5b8fea73ffa9d7657d06ce2b364414c833e08604ae54943f49c1c4f7c89eb0bad3a643f4a7bbbd4814726d02b7bc29f6731ed9445a2060d0938178914b0beae8f7e099838356247ea574a3f9f003858424155aa5ec5f318ac715bd218531d2626e1eae94eb99eeb1660916db862ed52f8fbcb132f1c00e3c1376729e78b6e1d22f022392c56cb67974b5fb413a1cb33ca5dad651c35be0ac24951fbaf1c6a8b0e93eb9714428b36af1a3c5f6995523ff86ca18ada0e1b6cff976b0cbbdae3162c284d0474c76219d3142c86f1a0f83351ba91fc487d863d747aaf3b0da2d72cec230043712e2913822629c2d91c62a5338c173fd7228d4769866bf789bc1e85307bc81fa78b8c26c24921b415ef83f2ab4875353c289c387a9e613003ceca0ce96edc0430c8f7db88a81a27067ae909a2b2cd2c8b292459df237653802698c8097552afb80ca8ce6c782812248c4bba259aed93063395176eba28cc17072f5e74c42e4ea9081ee104b169026353b9b976470f4c72e6fddd8f1e26616b5677e805d3d2ac71d51f895544efb86f0793ff0c8b699ea4626fbb2336039e2fc34ca11fbf1aea1ff22461fd60bf7d86bcd6f8f9ae30059de7583b8205e240f05a6f43b61d1a23545c3d531801e60f5c0794345072ea829a7f5084003caa1404b90c9ed84876b9c9a7499308a3e0241a4715f779a33cd5f302756b22df7357fb1a26bab7bf02d2aeea1db427a784fe1a9d878806a85b1fa13fb44416ebdd04746a4245ac7b06423ad9b21e193d5bb0ebd73db5fe8db522014398110173f5bb90341e0d9d38ac4f0990d553be5215d6da88cc15fb5145562bd38466a40dc320aa757493a26e4bd8cc12c5200f4c601ec99795c9210c916bb8941452bfca5eab46cfa7f1f174f4044db3d25c38b3349c5675e004c4d29afccbaf0a363e9610678b55dff82947071db794d94d186aedb80f6ae695c2194f3c7cae24d635670899d996977f0b4e3d4ef54190f2e9eabecb611d8e7836551dbc35009415cbba97e50b5a864094a55b5f20bb49b14d7e15f64cdb496bd219f8267b205aa024299fc8a5df6a7f3f7e94a12bb25854e64b6e281aa943854dc3c31a41a6450c3e1207acf8af9259f792fa99350769d58b6df6dbd1522e7596b6677b66a3f76be6f030e06acecf5f68d8a40c61d20a2bb01c22d8006f467573cc7b600f9bf859aadcf1efbaf2efe1590c3541f316428d05647046be359a52d6328fecd3f17c93f8f6847b2314e552497b4d47dfa1d5c91966a806d1636ae7df95be10bb5dc3d0c5b3aa1157770cd26017947593dd2910fbee83996c68d2ae693c959c7a732c8f3d5e9298123b66665c4cc6e24cf14022179dca80aa8292124653762758480566c448f9079840b2df1d0b4a2b50f644264db1291326804cd95baa7bd0cfa24e649777d366b895cafd16a72b0208812025fa3752c8e5bc6818f5c8ebda7fdd367d7bcf3558e3c7e05de9430f1e5672e579c507279ade88a4b255c3e593f410732bdacd11f0d6ee8464b71c0023ef79ea2a7a406dd5e1be32e97c074e302f73b5d99661b0c36efeb5c721d8297b8b55f92ffe75640d633ccd3a44a2c29f639a6361e462db691cf6b32444d6fbb6c88dc21d63b8db2cda2f012b7b46bbe2b253f4a63e8d0f5c2f637fad48f901167ef8aed89c56b4e7bd5f515c605b809ff0f41fa93b1eb003b85f02ae24deb775aff054ae1a8ef034aded829c7a1f7ccb718d58ff522da9f9393dbd1f130bb1dd5cdb6ee61ac3822826f9f61a678d6f207f3edf9538b5b9014848674b5071b07307b715b5b6f93c871ff56b835457f63366df690e1f806609675b9b6db0af3571b0f04420ca7bff53cb0fb062a0c609fc715ebcad55fcd9497e4e898693c690d7153509f252df84b7e9df9533c8d022876f93c39e017aaf07be45c268241c50b613a830b550dd77e7c9180ee43bdaa5916cd223c1566e96044b96e8053556bcdbe2a5c3b903eea33055eb817d7c36aae87d795f168247f29f19c195617b2e40cd6179ec4bbc577f86cd74d46fc1dea01a4f31f0cf07a7851a87fe99d472bf65330d376ea7cd3a0fe1071380d19a87dfe20e16e7399a10ef84f1560b71b9edc08d4e2d22a6f78a89e383b1edec4140b84191317eeb39055ebe31782fec44a591466b45583cec81642b3a89a6c32881be04c743bd5483b7d9757e0cbc73c3eea1d1155f35bef6af62a5a15b48e58589cf7502dc6432c0da755dbb264a596e9ff0ea95e14e0b0562b6367b27442107acd36a6b2ada732efbb8346349a3cc2b148f8e5894cddd2dd0fa54087e800e8bcb067228008870660f41e9614fc98335cbaf334c659e3fc72b442c32f9f9e23840b860f11fa5bdc2bc99beeecb108f33be8fc359cfb807a56b5b661fa08b1cfd2ad182b3eb3d0f32cf68dc0ba23bff5e92fbcb72b133c1497be6a76886014ef1fdd09dcdd1d58094a7ca599d2c0fd99e351d9695d3dc6462e97fce7b823665d7c94140b893c51efc054de99e2fbd28fdd14b80515a91c98254199a9724b94c61a4d07c3cb19c8ebabe8e3d1fe79488b4652dfe9c0a491f67094c6b0602ac27d3e8e59a6bae0f71147c1d6da1bdbf6cb046d5f7d33d07d225e9cde1d3c43c479ec8428192e2563bee28ff769ab87badaea5a9cb2478527cca698fae8bbf59ac49fb63b13e712d1bc2591f2ab0abdaa9d3e11d44521deb07cd5705d453de9339dc37128e7ed3a52a8e8f8ae270ff56b3e9aa27b596aad85546b9f393cd7e05cf82d89f46848855f0d46a375b08c35fa8b37023f32bb39202bc853543d2b26be7e00dc077438d16d4adb5ca5d8cc13ebc0edabedeaab6fb9229a9cb80e6a4ca9af6df21142f93cd4773821d122a916530cc504f05a0e789dc6b5c4d45c0c3c587944c4178e3685b2c496e4f523d2499a8ae5741501b48646f4bc853c7d6ea48356c717311763a3b16e1e8119f78e78835681cfcc4a1d88308e58659ced19cdcaf467c6383ed4f522cd1292b6d920e4a3e8890df8d0a0beb3729cb54ff02580747172ed7e1a816d35123e32e336c26cb58e608705a78c6346d54f105dd93b8849f1a13da4733d8a46a65b54d2af3399994de7fdd3a6f05446c6a8ddc0e9908c15dc15cacfe11061ac56d0501bd066dd121a212dbc5dc880b641977c325fdfc57cc020f8ca1555e45de688208b5d3533425e706c52bed8dc4a47d5dd7c4bdab9348f25d3cc78f00d0dd9dcc4eba2c731b3f2a7f822858930eb8f8a5b24c8ae664f3b736fa65a9d7cb44e9d7f287492555acfd877544a9b8e83dfd1c2c53a7eb1f48fdb7adf90333a803b247492f5212cb69552b7c4e185fe58c45a12eeb2975309a4cebbad6fdcbe1b25d57aefe23ac25cf7464591e8abb495b4a31bb4ba73d06e290a70055cbda55a452ad41dd15add8b1ce9f8b1158bbf5a5d183bd5280393ccd0e3a42d1779d5113d01cb1539dad3aa061b9e30093babc42a2127fe57d97063f7798610b747f02c495b55f1f4a03a38c706466cdaf789eebf82cca093071bea8499e16fa2c9b57c964415419fa240267b33a50031f358b83de58360e209e0bfb43fc69979a47a799f8a5ba91165129a9f4f59e2d30d61fd6787640ae1cead847455f7d5bc35eb7f29ca7441ad3964ea300e5ef3ebba2bac00ad87d1886c8cc178bf4a13493b29332a54fd01f60405551afc63ec6f9fdff2b4a75c95d80d8d12210192192c6ba568b2d93069b8a8956c10b867d5e442e179426a2b88b213bba8cc037687aa499e0aece384522a29388718309f40d5f82942e2a0f337296f3328f75551eb46ae97225411cba07b7e4892d3331b9a570f154ee6cd99293d4e7d8525187915f47af3c6b395a6270a009b0b258fe00cb0dad6f668d1b71a335a551ec3530321c3ab8a04085574af56c120880866cb76a6587993ef5350a9642e810d2f4f32cd927575943b6834ea1785424080958a12a918d49d2a6be5c1a84d987a5fb3aaf54d8c51aa439b29aeb7d901c9d0107f42bfd1833a87713aaa22570a4f5f96103419c0771f667c33e5c4d444c38406c5562f7b2c145ef83ed86bf8913f5f070f3e0d047c5fd9106249524af2ce9f384926023a33fdf978a4c6df9a03533b524166c5c83334bf89bf4937ff87a76981b750070583c7919014c5835284a422a9cb317cc2fd629746718f3726df44b1c9198542d805a578327e6f1fd548ec43063922866ab83303c1ff9275319f10729824c1fc63a4a9d9b0c89040c238079202a7d0ffb2b69250761152e280c439a2248a70ea2cf3a5a03139a7509e1e3f7f59b602039686a616b4f5f9205e13084a0715fc243b0b8f36239c78bcb3f5fa7867569fc3fdf250e8246dfd16d9601105480788348641dbda7250e6dd392e8bace96ae0ec21c21ed4497eea5da02408dc13a9481db8e0f166cf55f9f01bdea053be32c85d1fa2fe860ee6aa0b9eebb58d8812cff4b624c8a3c1dd43d41e7dae38e94ff6df8298a7fc060102b0fc378415461f26c79721b8faa27f2bffc059f603501228034c3430c865ca3def301c5462462777aaaecb279418d7a7b7d688cc9574cc3ca50094ce3e4393100c51ba8d026eb1888cc988c6d6cf36d056b4e181798d92b630d43b25cf3f02195aa0d4883828a997c9616601e8cceecbff89af12881a496fce5ca5c218c76cd7511add428eba094f587f0fd928198e559c1583e3cff159b1f98af8d2851ee7191ed3bcbabf45348451c26d16910c2932fed577670a07b4308c53ea14ccda7d415d5498c8ace6a6460bad15ac5dcf1967edd2f14610e57630a089742f8a9b13e549ede8ec60dcc72d5360c1dcb25d3ebca23e3467b8830cb08ebfdc9d125fa27c2e588d08f20d2a06632d94224626f56c524e9368bac3a26b52c9a6855d47d72bf04ec0044f52131a431468949f7251b3589fc7549a89b931e9df73ca42375802ee658763eeb567e0698187ebe5f7c15843b7ef6c2f9b375341ef43cf77afd621ba74be86555d996fe834d8c11c1c753d0789ba37669a0996e68b59e35ddf31edf2b04c571cf2433c5727a0b32b1d159f77c60e29e556bb81bdfa3b6b3346f88a0d55a532364d5fecba74da018e715d91c9128acae6558a70269fc85e1d904b20b0aef87fb5b1566f1123053c9dbe3db0d4933a239d53170007ee0119558b90cf63d961f5c15c6992ef22c95b022134317106c7d0c56a1036ac8e167b40d2a44a4c62cdadd5d3c77b74a513b7401f98c682b8b020215be21cd5111ef0ae699946c75f7bd5577ae152761ad8ba03fc9f2f097e265a379b954e2fca6575a2e60391e2e84fd160447724e743ba2571b85126a1c76fe514a1c3de9a781b2da681954eb25662ac8715f2e5069ee3752e78185ef019f9cdd6da7c7dc8a6723ec04ff8f543f441d2661d9a808dd914b8cf7530e1d6de2d74c6a9de31cc5036250388ee29851f0e85112066f01a04fe1ee405592049484b0793105390ab6a5dc7168210d89269914eca8fbfea500c077f28a69ce1a366a38fad2093d0cb276f721ffe4c59c1ba6126fa8ee071af515b3de22bc96b8dcf6a4ade847a01d7e4135292718a2d2e0add0384d7a79d3e56cfd25428d885e55ffae1f5556d0ee2f5587346c220e8003bf1a7916dc3ca915a4c8e71b2bc18b5edb5e934e8625bd7c7c29189d842c36baca0a7c06b4c1ba8f1a3579306f4caf559f016df8a5c5ae96a902a7c040f91e3c5fb9848df1702bf09e365c663061b02fd199f3d162d24164533affc4c8f6f8bd8bdf3b6c901e2178e43a27301a1c5902a1eaf1fb4f85e50cb5a2c85b4c02d20a4a5bb47b118072765f140e32963e40f5557b9222666ce8641b8bba8e5c592efdf3d38c801c5aaeba71183ee74c05d48de3da28b21bf531eac910008b6a7c3baba9e60560f036c32c16e6bfd7deb9d16896f5369d2579dea22aa2186a3869be52b3f636f34ce97c0de6d9601f8bc195c59288260b8228852f382aee59d7b668a1b763ddc3134f99113ba7afaeeefaf674025afb1db183dce84c915782a9228ca94834e4cc1f265b5fedb66504aa60d1cd82d548a830e8dea02aca52ec47fed7cd5d296e693c9f7ecfc67a80cb721aa7419db0ecdc2c08d6ec1401428972bdccc593043a5aac9bf824b70ca074d7f63aacf9ba6e72c9a248f78753b509971f0aaf4e79f386e7c1811e8699d46217d87a31d101becc98f8f8c757e510dcf7826f05b43f969dc401b814051845c36cff8c00fd1331ef31efb95bfa324c0cca391282cf75258585e3346cd91b21fe5da95ab2caf814a6784396b7469f4acbcb3603d5af5bcfb15c84f3bf4c6754d404feae786d2f176fe7783effc714a0f7910cba6f00bf6bc4ca2da359ed3734c5f28aa257b84e3a0776281ce2d7902a65c96457c311c89041abf41fc61ecf7647f0712bed908daa0021b0700b1b0c68bd720bef443c118f0baf120fe7c5fa213b5d23c017cff4692b9dd95df857295628c29cdad5c08cba7ce5ba53514834d74a4b660f9f1fbccca1e83e10e89ec0578c0959668fb436e51189053dc331d42a1607c679e4090c6017192103872cfb02f300d47343d7ea10117fea905532dd6b61630d189c501325e06b64d53602cad5aa31e1fbc82c2c8682fa16dc798b0c73216b402a849b564a524e27e620e0855102f3b91be8434700030511c12e84a21d75dd77f95f2f05e1de40da2578d4875106cc53a0864cd573bdac96f65b36950b00ab1cb04bb2e6edeb1f6c4ba90ee0cf09bc347dd955379566a24c742f3ce626edf6fb38ef185be73ece603ca1d3466676a39d692c74f04436c495d269b866c09281724f914bfcf6d0d5be93159e8abc18a72206403c0b50e5f271d7d66a047584f1039157516e222941ec506620025c6981f4a6585424d87751a7eb762dce3a2ea1207608e229a3c72abdfeb845a2660b28ad6393c294f5bdd3ba0527022580a06847c71c7d98f16454a88799e90a43006d69ddcbafdc6a5eca74524bff1002a2ca910682fcf5d991e3173ef3fe1fdbbdde64fe6b2a70ceacfccfde4aae81e146ae88426669d7a754ef29fb52315b25c48e2d84d65d9bc3109bf3c852af1a87189891c9e3260989ce8920dec1fcc835c959d088fa1b5483dec5a5fb397cd273d77942f7389a656c00fec3284ca0fddedb3ad337e8476c8b0eddcef591187079ba00a7a14e1405ffce9f50580e6aae652b7f12c1fc4d514c239bf2a95559663cc0fc85be6c58b023bac754404064b778205e52d894c70d6b31377ad734e5081d885060aca23e4dccd3403c9d535b8557279fed82c690aa12818c3edbb64742ad8f092b6046be6148ccaf2e0363c7d85330eee4afa7237802a6820221863e51e3fd6f9f5c3989db6ebebad5017e3490e1b5a9cba19b40dc91b49f9e914a4ee728e6a3213f33e1c94be3eaa61781603e32ba41ad8a4c5afd5cb9a9f3579e4eccb60e4f8a7739b1432a81a63fc3b5258f0e791d65c7cc97c94bbece688256fe0bfcca66596bc717d75338d89925da126fc4b43e28b0c02d6999af0c197f7ad3d15c4738aba0092ae1952f60891813147fc45c8589f74aecbba9a0827c72bf14fc06253b1971f276c75eb4c1536cc634eb220177d8035cca3cab29519b34cb2d55100f7498bc1f79da8533100e7cb7e9a87b35b5099955e5b47300d6a5fbc880aa020b7096a66bfd34ec19ac5467fdb43552b501ff4a4de5548a9385aa40b3edbcddd0c6fe3702c6137d40cc2dc28974692ea53048e60ba53e777e7ef3f4ab010c57b996431925994d498b6d43c15960162296a1ccd0a4499506644b98dec60f25e7e3ddf029ff067f1b499d4537ee4627537e3b3adc02a3f46cb0588341f116ab5d428cfcd860aa4c1e0d8ab668e0e01471d9597e7e0c7674e242dff7bf02a161d79303d0267d6ffe279dae4e8d0a9be9d9e6c057c8678b79b8afa40e9ea24387e2a217f6c2c4a1e94933567a43242d3a9856c3eb5a175d445abc9a8d09a7b5c586b22d8d0f535a88b6c64b46b4c2f7206ae474fe843962056d41c58a70fa86dbc83c875a6ec6f9cd9a879084ed19a3999aff795a996c9c084b75b33e88f5f374fa92e1e03193c6e45a02ffac065d5ae1bd7d62232c4dca862914b2aeb724f14f498f11c528cdb68b16bc46482c5e5b3d13634d3ec8e67c3e552b4664fbc3cfc123082dab5e560c1aff0aebcb9f4b6ec8dcf5b1b231baa59c32b5578ccc54b109e43e7160ea7207805dd334c63cf758e04362c69d093c1b68c6ac2de3bd707cfcd8da8066765ea5bdea941139c0db092dfffea54808cef8a232694177ab17d7f5c97289389347b83cb33dc72ef157b298766295c4111f8ff25f8f1b38ba00af6074eaee86b17e192db2932c3165eddaa1ee46d355232ee844456497ba8e103a5f6e611e7fe72f900798b31747a88eb6800d09bbf09d34bad628dc7a1b00e1f81ad874619b5f1a8852aa0aef05fbb5b5990e672ab6332d7a0fa638c14a0a0ee024549459dad99a125d15af537c977802974e4944d1000633b8fb48cff0945154ee69047c5c1050e0aac8a581f89c3447aa458d114fb42239cfbd132abdffb87b08e1e15f3354e4944f12f4e85037394897ca3d0a512183ffca8cbf1092e98d3abcff28f118a3a72a0c4f6ee83db674a0647e513684846c39db1c6d4f061eb3b6a147be006d31a3eae30bd86082595a0f136d6993e0cc071c81c9b9112528383107648ce3aaddb6e7be075ba1f4012c601a514368008dd85b2ea506d8719b805112227ff171b2a6c4aeb290d42437939b2442592cdfe67a48ea5227388026a0b21283a8f870281d2fe97973738efb8c499aaf3ded77fb2819a82efade8eba95330e93e2405fb3b11cb012bbbe3a2197220eb55d9de7d63af674dbc1064eb63ea6facc21cb214a1fdf9d8e96f05c7946005ff67294a825168fc654335ba99bb381fcc4216b76da9ecf19989e7097df11dd7e6a4915717d7f8b2d924c35506e02318ee603c74061c9fcc813ca58c1af09d21c4ba754f020bc4609b728edcf2d7c2e4a3248dd5405719c9e98df80bbb63c40c8e8bb99c233688a6dda36e873189e228c9574d37099dbe2dbb8f318b86af32aae615e67e46d290b256fd26a398d4fca71691f8ca390b9c7af221f079b2e02e1072bea6b05be4bcf656704ff2a980bef27498ebccfe51e289a86fb44a365419be647ebd08c180e2d256aadab69c3080a499f9030dd9b96f0779117d964c0c8d0936c88f132cfeee15365592e46daa6f1f5c884264af51f876c169010a69dae6fbc3382f048de9bf61338b73f4ab5f02d2ca32f84f91c45a7ef25a34a9d4daf98d36a26a1592cfc366999369f75d1fda2262695fff49a071a14afa7bbbe72385e9be60a9b21df9e09f435e88c09b615185c564375cb2d1433dda29d0a9cd5eca59376dbe4ee6b4f467e2296a18aa4f81ac02213296990b283a1d36c579e8dfb8f846e4330d139c598fd94cfa777f3081f2bfca1cda029e63da1b946f213f9da70cc6e29afe479444673a73ba945a1802fd87f7f299165abd1499c79da2684f26c901677ea1e453cf7a39e774b128905eee31cc996dbcc17c040c9359a9f1bac8dd063436c783b225e722f0312bf93730a1f5cfe16de425ed030b6065e85f8fdd6d7734ec1981d52205fffe8daf6d5224b8137bc05981ea3109d4fca1be0c810e99307cfb8a4e131f1ab357b785ae0425e8868d71724b79f5a71cfe61b8cfdd9327de5a1431b1bc77fdc804339982b96e026d4ce8ad1f53cc98001121e2f5225b4fb84a22469deab4fd2780d8e76b3703d467a465634aa08f79f01e34000bcf3f011b009c28b42c75a45111ca824441c147a89a7cdde1b242cac3e6443f8c2dbe8a20151f4962d6f62364420d65fff06d5f034d2da4b2746818b286b09ea7bed83fc13b256318e407c81384a7063382ca1f8bf6bc4e48517fe08c6297b06d0cbd6019414690a29fd30cd9c4342854e4b67f347c861beedf4b02b3d424cc0ac0a4b78410952cf11b4f2166f90f053cbf38fd104af7161ee364fefd5211423bbab5449cc5e7f035f2a2b1bbb313e110d0ee4d1b6b58d44c1c3de90c0fd0beb54ad1dc064b6b787c8ecce420137a3ed3417039de9765813397e3cd8bdb4d0ff0a2b7d9a6ca0031f1950fd96f9012f35f4973175c656443217d9fc8dabcbb458d9f112ec68a7987a40ca812b17fc5bd67f6ca70d89df2fd88d6cbe9f44f2f924f355860541ae6f936a94a6fc65b636c0516b10c5029573b44d9a529926d1ee84abaf68daacb8d4af046de4cb1747fb7a8b9d23052118b534a81f5bf6078bac85b7666cdd3e3f5294c198a43cf0e9edc3279d288bbafca0caa7ba44c50d432ffa00869c0d3e1a859c73bef7c9142888e02a6188e5aef0f762b117949480a72aef49fd642f2a7a2bcccd4a20a0080b249aa1608392fdcb81c6249d32d21e83c2d04c65f5542243e052756976bf7243471efcbace1a614f4ea7ed4de64a7ccf7a5900212a51db03b34be2f41b563ddd989fd079a732d01569dbf802727ab65aec2fcac2df7a1b7cfd05749930a77644d4d55c136fe5aa47a2dee5d9004a373c0136c9e2385c666fd415dc1a4e4d3f0061d313db364f6294f60f2f0ee974bb3662bf87ed336634c4531f8b3d051a9fce19790eb924b833ebe8c045ad312ee7825df5b41d45516708d2f9ed2831f2ca1739cdccffa17a318e66b94011c975c1721d8b63593596450b23d0e9b6cfcbb9ea1c1285abb561b1cfbb96417c8b4f922f6ab7f2b0ebd44b9c3ea59178d252b384387f44bbe22e05b00ca713dc5e67367f98fb8cea641c7e803d7493737022d1ac1da6b41f48839342eabb19687401211ce6f77d45871e878f9d2c18b1b837d4611640dba82e3fcb827ea1bbc432541546c2bda81a01879bb2fcff748711895c0ce8d47338c150faec01c85fd8f7b8707f37707474b9fc378479f3f5b93e593102acce44de8a84fb2c62c350716904f1ebe596ff6874ce5cc800a16f6af99dde74494af689128fa7b4b0ea2d2b986504cdc4f64ee8a74462ac3b51824b59751aa3191bbb0e70af3a16a865604df4356e8b3157aa03b55f192b45f72d95fc552c96e033a827c6f5937da44d6b16c78c5d43824603f495ce7d309ac420e9061dab768eafa78c0f7bc4cf3e57ef391bfdbf7e74aaeabaa204e8152e0061a6c2a71be0e8aefa0fc6aade9e994bb5439b7ba8de53456d61a84d1d59c867e50ea969df1cebd011d801e9a3139ed3bc2d0524f99c2234461e22545a408d539650b381defaa4f9a35106aaf89c038acce3623a0e9d0eeb3d3471246e03720a60b6c748f3368de922502319eb716bd260d74cd03a364c97f76bcb97c70018dfe9e26f6982703eb3e3ce831deb0a2dacc92b5d8576e358da850fb49e084a202fdf5d97f57dd4d145e48068c85a0fa46ab1836e560827aa32802c61544700fb0e0a97206ee0dfbd650645e99c0a686fc7b5f2d9fd95f693ff61dd34ff208cd4f3c26eed4a6267dbf574c3f60e4aa680e741271bdc522d21eaa5ac46fdce781b6c9a380766e3ec3372c75f2c57014a42735d20ebdc007bc41dcbcc3a808ddbdd24f99af727c1e42b24d9d9505b3973164e6068ffdd8d172f8b1204a558a34d38a743e5cb88797a53bc4de440feec468754caf0e2c341679e6840dcb677103d87f343db996a5996a20e60af6355c6392af3b5c90ab0fb180c9a20960d0e07efe1df80c242382306ef787514f4c186bdb9a514f76cb587dd556e793f36878c9c6e725db870ec5e7c5d06244cc3e4e6d1c64bde84779756cddd44f66391dd7077618d51985ca45cb8010681b75d7112f4e423a217bbc403c3e4432225afb5356ab59f57109fb3ebdcc919dba08b8e073123a789de7669b91a50dbdbc5b866b23c783198f4ba3b555c71f2ec457c5974f358a687724f111532c3d9ecf3c947ba5c1476720ff0fcea5ee031a0f282ef3e319450b873705f0a12d108442166e4494f4d82f2d89c3288c7b7ac5177037682bf9d0e0f404071f1f2dd1848fc8df11f88a1f5be4b4fc098161b2233d17c92acb861e5e78b83d2add5c58dfe591193fcf52413ef7bc7fc3102feb4c87d8f0ccdf64177626125f357470ee2766f9f806e8ca4bd79e2311136ccc045bad10ab2d691de1cc6399433e4b1f77b2eb47f3f39d32a98f2c96a93b0303c96fd8a2d8ac0a37825f07da91a8d6a7a270f0d43717402620713050032c60267abfd294e53a0a9150eb65445455e32e6ed4dbbae7858be4d8841e28ae254101843e3f887e369e7668ac383c38924ea08a1eea05051ac7d754e87324c60e805bc12766e826a6c7082d65a9e4be20c7ebb4511f6a642345129e55156d5d57442846aa5c83387d82cbcd64664cb737a171cb1b6ce97b174e37166aaded1ef2358695be1c94ccdb91495f6692e1114ea21bc920e6380fd997057788767c30cfbef53b81a9f2289eca0a4804b048f7150b844cc93e49c3911e6257f9a3ac2ffbd669a9064ff28556c04215c11ee35d110c7b555b0ddddf12078f2ec44d6d95e3d0686098a6848f3c6a78b55845443ba6b16ddfeef16f8c6015328ed8d5c29ec088ecca5dea9d0cd9b68fa4200671e553c2955620e651ed6fb4efef1846a70878639ca22622116f5fb8b7617b348dd54b60fe3901027444abc18337eec0936a3a880b01a74cd97ee2be11d8972df3af7b2f2d384b22fc6ff64264f698a3d0ead5aa4e63d913c93f13bedb0ba8a5f7af021e9db01fc76c5e4fe944ab6b7964baeebdb6dd3c056e20b70615296a5061126ee1c6f4947ce69e08c4b99c4aeaed95e91b99aa0336c2ead865cd1e507aba16d2f88fc695a47ddf946fe0c19f511602d98ffe48b51ffd11f3353dcd139bedd76969ce674cc201d681c2ebb7fc5ca21e4bc53864de4ef0f96c8c1513cd01e26982aea0bec34c8791f0677bad5ef617643321e164506ee4c16cea4a2070bf64b42002c34866ab19360ddc3557576f9add31d6feff031b49eb6e490922dca732e7a368e6b131910092f574b5573760ec0cf788a16a40dcb9bcb91e2e1bf455e3e310563d0fc8997bf67b76f03b109e46e862bc27da116018ca32887896bda74a05ea5c111daee99100b11665670fa740cddd8278ca3f9eaa110385b60f11db22479dc7c6cc85421681278dd2200b23cbfa8fe618d275137688d335111b2823082cb66c37f76104be175c918f9fdcd86cfc34cd8065524ddc8e741195f7a9785b8b791d996dde34e1ca109887ee18def52ecfb4df4b759483442f4d0112a357e35321dd1f325e5e30eb3c97d8230d1e84c5ac2295f54f12608c78391ae7a69f18c647cafbc20832684d3c06f12e8443291b8072c4c99e1b8cfc1720bd5e19beaff324ae5f874cd0af84ce694d00dd84bf894122bf6a53199d2ea8057db37e14e9a057be7a7dc82a36a8b50bb9243e9c61b9843cb8867c50ef273781088640da142595f80997db8b485275eae9ca772ded5f9fd685ff701d2ed3314de89634274ffb921639ae2b3b2e6dffd395ba0d77c0722060bd2d94ca323b937e2b8056ac6dcf2afa5ff00be75fb102e9e7c947066001e80c7a519c3503a727a3df72ca339f8db338a7a6e2b974d68b5e4a2f75cd283571ed90916b2c619b09e3c9f4102e74fc9b479171f05676c35ee8b2dcac462c8c223fa371d7b3c1fdbe4b04d20ec20075bf13ce68a7d1fe73526ea8cd829f32d79e0b1eea0ec7b7afa64fc135f9c8cc002d2e2a90351102231ec9a2962fb96d8d8f4891e2246ff9130197047cad5adca757c74437d21bc9c805a837a4b62636b5149e15c02e26ebf6ac42383ca48cb489a5c08820deb1bf9a309e0111b3d42ea3cdf09b581346ea12c69a80cf47e7b427fe0d5c641ed1e23538b315cd23d267931875064a8f537965db436f47269a60d6b6e1464596d9179e3c82ef4851c9738c34062613ded7d4cb8298c60c9f7a96f4b109bd75dbb9e2620a1a9e8954c3c68034ff67fedb3adcea225a5d96a5e03dbc81934f53406b997f454af585772711a7b3cc9d3535f66c80d2c12cc3e3d1813975321fde4493058b784769d137e9ce2a4a66e511f2c327e93334e40cc3ea1fc6f03c2aea330ceb0dc3e340073948f5d991cbdb0d2715dde35a11949f013bbf3d4d90749db3b2849907eb584edf1cbd951787be304de7989053b9e384ef79278f749267ab4c62c946a260eb9e66fa223992b44e564ec5c45edc0355c3c0370a9524e4429ed68c90cc30d123bf40994bd14c25a754510940cf2ee9c14630de2b52efb7a3b8c7781f2ec77c2193a8a0941e37eca682b2fd337c74a4bb12a0f1477758d9759f3f07424488568e1ae9c706c6b08ba1b8b868a9146b9667f85e41b9b7664fb433d04d67ff32bcc966df0d2044ffe35ef26bc05ce25917c1b492822e9d4de0064696d9df6bd8b280e1dfb7610715349ed3ff83da7639edb2896ddb0ac3be364a6369e6449a0ec7fa322a11b6d66a83c205378391d746bf7e12bbb1c7aa988fe8c08be9a0d793ef08a8f3ba56f32589d7a2303d665c4568616a7e477a2975a1fecc8ae785e61ef148056da1dcbaae4f2bdb96d37bbe87894292dde0eec39c426a342190168a17698ca7ad319cee9ee5f26a0c174174588ba1b61959206ed371367f505759d6481572db2376a285d09ad2f92378797e10881072dc8463f4a2e00d85778c46642a0895f65b071b1803995420fbc871ad2a698552a936d99e7ee844b306c450cb021fd073532159225a4ce29179c47c506b9429cb28dca138eed324291084cbabc2c4b3c724d1977d463dcfdd439435132eff08401140358b5e7abcf00decccd5df4012ac2530a2990c6455664eb910c589bd951c91a8c30c7eeddd785993d835d1000f87fa1f046c26fe7a034b14f9beb1b1e89d68662092e629c149e423a359f7659696f27457496e3e2289c1d84321e371dcad42e5ea4cef279ab217b78dd2df8eaa6586f08b01a9ac77b200206e079f6ce107464f3568d586e9375f2d383a182132f99ac15ed8c2d15b75cc4e6c8c3148e6e3699c12251a83eea859cbb988ae03ddadcbce8b49d04372a319a446eefa6ee2da51c6342519363918aa982b18bc5700a4a5f8a5c1a77f38bdfc67fdb089df5380de99ad73fd168234569e22957c80e214b52f698cc912a0fa817c4ac45cf732251e4ac8180c015ddf2728f271a0bb63b40ede29c23487e5dd5d7f3b75836693ac86ce070aa6def697a6b13062f5e6d6a0822a5143a14b28e60ad60ac30236ef71e96dcde405d68b3071941b79c0f70cae1905a78e7ef9c73c4c167743621afff5112adb2488ab866e35af5acbd6bb9e0fd2f8174feb0e3e3dca055ba9429705d6c668d8ed95c88561c50b84e8fe5c69720d7eed3a83237963f461e8627a0b1ff92d492842afb7a14eb436686ce71e43df5b7fbe7c4948ceefd6dda4509c836d46d619f25690c2b8cc1f2a69a20456607c8da030ae6f9508d85508c22eebec9e79505504022674a2a9ffa6bb1e54724326aa91d41883c53648b077be2e9e5864a4d5b5bf29bbb283db8a055020c877aa42b08a957206b8b547f34b5b692aeed043340a3332b229d6824575088f84851072afbb648f8a0ed3ab031f3134107ca614880eab57acb8ff718a2d23b6b9b0354f76a1479fe00fc676a4659bbb04e03bebc62c60ad9f56b6d4b5e4c959e430947d35a1f75638c200c71644cb4485941e2756dc00f9df4ea80f8ab3f86af5a7eba9481116bca9b7d24b74cebae16955fd8ec94c1d3a2d957684188824674aada8da4f87a5d10683a8860a50e1e9834c6ff5544dae0ab7be4280a713ace8cf28b405f8ec4269767a74649e12ef07b5a19050d218c530d6c29ea1b18d2133cdab7f0fa43661851b6da737116e2dbc401d208b2453be61488c657218efc64e520466f1c21892710ebad3dd9b8983ae22c92ab7004ecfbd06933ad5d31d3094b0131825b10499aac357cf4908b374efd10c81b5fc939b6c5a3107a2ad3b5f4084ba4cdc24d13e43c57e2ede44e60a3bab70e71f709c4c0a8dabd805adc12c73a9b01e9ba9f4aebbfb478677b6f6460bb135297dce487435f47bea5e4532e3182be4d2ddd3f2f06440a93005e4abd6009eaf521242c6fdcd1f2eebb3d5dc853f591835907b414ad9b16287f084e8fb174dc7a696d70fcf195d4a511c921dc79e00659595b6550edff40083121a4c8ab8ab7875be3813e1c34e63877092b656882cc976f995a34cf117cc30e30844707e4164eb91bdff4c166e262b7dc128b2e87620fe26d3fca32a9bad41a95d1df3ce2881bf832416b5d6692a128c3dfa0a1b31136f669b4dee3ecd1a7363749172cffe0787cb6870a47e700f2259d43515406836181ad5776a8ff3cf5915910f586ad919cf875cfc3d35a3f814e21c9f4d921956a29a1ecbcb9033b54a817eb0725fb3931db55a027a8fadd840dd7e0e0c691a67e4c1adb61efacca5ce07ea28bfcfe5112d0e6c896e5687b236ae1f0c949f0c89ed968f07fe49297b2680fe27428de7411d3932f50a040d2dd4bd89d172d49ff3fbf993857eb30d0e19763662ee4f6add3b37e273ce65ca70b2693b88e508b53031ac7e5290d114abdd77432c2f8a7636ea85a2061337365374d623ce9812dea8d0fafc9a660aed715a386562846ed94a55f3868e0a151c186032f68fe65d038118f1b94e1f8fc3ce80f73af3ea65834d8556f459e9929086e65b19a44cd97081fd46071e82c841a3dcf2d76c1b23160f54ab5cd0912bfa3a23af989069580d7429db033ccbd7d5a3f4fb66f258b8dfabf16d52cbf992472b16cb8a193456e3c322d5f736984f7daa2fd5b0e63d3c191796954326321b8e94766e9644a5f79b3ca394bc1801a8abbf45241e6a3b0c36dc59030af7e385591bff1a54e6b622f888d034051a56c7c3d650ae8431f405021ab8949c8e750bfcfed5b3f1bf58e174e9e43f295198121a2fafe3eef746207baa44d77e3eac97d47a901e7cdb769e9144942a282cb7682351a744af2b8ed865d21ac51a3c331b63ea5ea00b35610ca36a66e9cfaa87dcb546d6e31684bf197221d16141a81455d64e628a8677efd0479cc0c47ba845def81d7e79d86864652099ac6b02ea28c40d10aa366aec23a5326b71b5e1fd66d78b813324008538efe2fff289e51c461a7cb218a7c80f1ba0869f89334564c112251219d7d849c944d57614ae5bb442268e24c9bc069058122b911e703b2c24c3e24dd65bc8bb350eaa8aadfeada52920d779f13e11b2687d73ab80044965e09268789a6c090969da3b0cada66c38bbf1995368660b35a83d7ae06a7b843ce2bece287ff51a02abdc6b378b9d65199ef0a72d20219495fad061224d241165a544a7d7df22322786e74f59199b682bb014a98c170b1a39e52e9ee645184637613838b0bcee7f792d0e03dbf492390f1790c107a2174864ccc009e34995b029074e0da5cb58f52282adbb03e9028c0abd48f6d5b7c9f01f98617ada1e93d0d45a79a2718f3630cb1e3c51846d0612e8c08560b304fcf4031ae96694572056b24a07159d088bb37ab4d38d0835da51aa8c37e30f5a145d4c1f95f6dc3df41cdc7f89ef4d0f2b5a280998d1ba9eb8412d2862063671b8617458bcf0b2f0f1ec2812f7f2761e7dfffffffd4ff6265bee2d654a29052f0909092809ce0c050a43f9ccf8d1c44ddcf4352971539307e1f0516742ac3d6a5dbd42724b7dd9fc3ca8fbeffba17383d983d887bd51c70d75eab85023759a5d17e2f0e1e0416ce54aa7ea1eb041aa30871d390e0a6a3f053d67ffcb2891992425e1cde6264dd3b4ef4971d4cb90a3529b73e0d8337e4ca0107165e241dd771772538bad43863772541f018ddcc568d62eb1ee9ba29a9aa2a2fa888df6a14bd045f40aa494b2e3af518110203cedf9c9987f64f899305e3d5445e1ad90c4a9cb4c9849163281ea611f1c877084a96cd42d1ac2b6d57449ed1f4965186973936ef5373b912d6cd01622691af600e23853bc71998a780884890e15deb8501cf3e9130927c0a30f5b1c72802465044a9850b932f11828bc02ff0e063434a82b266aefa0f6e43250672797b75f9ed05f000b51a52376c09efe3eea3e2266ef9fb94e0cade383c7beb277cfe33a23d5afff0e9d11eb80e13430e71b9c4c46dc83ad48791ba31fbd1a43e37c37bffbe272409de73136a845b01d436aa2d322d890b29d76f2203e8a2151a49c6e9edff9ca2a223b5fa444f3f0ecfc0fcfb42cdbf99dffd1debefa1d2794f27213c2d884decb6f0731d3afbff7dc04695e32135be11edc85d9c94a759b1f3d1e48ddc426ec02d6bc0b1b74816df917e9d80eac2316557301998f79ffde52cb473794783c3ff2110f0fe223a46ec23d3ac63aba466a529d06dc15c720d6b907af8e7ef758cb239a221ec4aabdfd349ff0003ecf67df4478be48892cdc164130ccbec33103b59f871ef96ad7d91d3ee1e19fc7860f79c2a29eff4109d80b75e67b106aa05977f5fbde2a88664f5bf43e87178a586887e71b7cc2f319f8c4033c3c3c3cdfe11310f0b0f33c08ad6a084f58d4423b3fb3aa31e11111c3802fe048a3e24153537c446b67db59366512de8a65124edf18b1947e32cc69f2be7e75de56bf9cfd59fb6ff8851e73ee5e1385c73e4516575cb982a972303844fce910c77149781c87f38437e79cf3bd07daf371e1ae8be33ec5fdc671e17844acdc770dc4f5d4719d3490882b8d3571dded5f778f66d6b1dddd9e725f9d205efbbd7638f650a9171cd7dd3dbbbbbbbb7fdcdd6def6e6fdeedac05dc7577777757ce4ca3a9996974cb34ba750bd26dbec875edb7c1d1aca7af48a5964d2a25d5b2d9867b1bee6db8b7118458d6d3e7ba66f681d9febb1b11397f58477f90ae1b4d6faba3b5acb8f087cae933ebfef17136862e071151e1bbe1e9f413e9d40bb4ce6696cd9612bc5977c90a2c5450c192153c5802133db0024a18fe194b4e9bee54ae7a93744529cfa49487aee88af2d015a53c5c4ab2945366736bee91fdbae473727e952bf0ef6b85ea95ab0ca0ca5f06d23ced3dee91bd7c0d7cb1454dd334eda56a487b5074e2699ffd1845f65ef5e4d4fe47b714c3355442fa7f34ab8064ffeb929f8121eb604de1f5e414eb90bf2579628b5286485e5213545ac1e447e218c21be9d10976000589082780810410d60b2a595260858923a27cb1031e1891a9209531690172d5a985b15a9af2059309aad49e9e7c8a55952750a8f2fbc91be9aaab02085594f09c78fc19674870ce3a42c2ca61d3ce5e526609ca30c489976551781e645dfefead0d2a00b7fc671886ef0faa3f0c3cfe1838d411c22f9f439db9350b695a74cf62e08d2c030c91610daf9f25a5f8f9fea19c3635ad8a25740828a92a8c84d08670da88c888d0429b9060c6b42a6210845400115332294700e19222796b992081028a60f2a2601a9c24555125081a58f0e4ada50ff3c34fffb444e07575ab40614104d4173e8881020ea0b4a0700694127c48c38725218c98c263eed147abf6be1d3e2cd981ded7a2949ffd942c9d78f2b746e1c9ae6357bbe31eeb7d2357395d7ede1a9ef410c90c8e81100294cabf2f50d58f2ac74ea344a5cb4a6e97fe3a92fde55355551f1d5413eb9c90a830421dc594142a3fd4714775679f3ae006f81085038fdd3d03def2e7a4e598f66662726a402ca5c494b4af557b47b5796ef1cbbbcccbbbee2f594a29a53fbbcbe94bf8944b48ba03954ae876ce5156ded1d7dd7d6ed7ed673ea1a2f639e62d89f1111bcd1a780cfeb64422146a9af1f33da97ec8321f7461fc90c4053318021b48b0f1c4162ef025234820fc208d0dc30a2c54502e62204608360c2a94e820a2a80111413461c51629e613543cc992bc20aac9921c3861841c2009c9d45da2e2045418415997ec52aeaffb0fbbfbe24ccdc9a5e694bed3478b3b7d939967ef99d30f86393316acf4f9b548a9d47c6a99bb53f7fc05e27f546366667a84d37eaa25993d70f70b7082f0f8a1b668f16056ee53cdd9c185bd9d7c7f22d520c1db976afcd775b787fc662224b23e89e92c8085e6b3d00c8f3aa1f93a4160aa3f4cf5704c529f7c6086d45beeee04b1723034cbb22ca39452174cf1831a34955fa3495514c10a57f9b31774107e90aafc13092a5e9040c2a0326f7142e5a5f27753073989caef7d4a4cb85229156b4e9516540e42f570fc9a9fd54032955fb008c112a1a5e2a3eed2882bdd3d0c222485a12eb8a89d85d3c3f1abac22bcad445cc765ea2534163ff6c5aafc3204d9170aebe2e7df262a767fc0b053f97128eaa0258201c870aa2cb20462142af38e0dc76d5a29a1b0af7d16703b65f33c4de129970bed7aa8bd7358973fcbe51ea52c5072994b1135449f2975dc2ce28e9fce615ffcfe1c730846731e86d7bf54c695daaa20371e185eff4ef94d4260d2fd532e9722597cab8ff53378fde1f91cfe04d90d77f8ec87496818d2a2ff0c59a101dc86212d36ebb4dca1c8779ae8209ea45dca12abeeee51aaf7cb65225c8a649101240da4e3d3891cd471b354c7411d774bf528ef70e4a3f61f4a0668a0558281d2376178232321212121f506161529215f7e92da034c93d0f65c4759ddacdab1fa4383194461243662a7f6b3d20a414a93d52285c6af528e924003a1f954cb32b044a7a713b51f072ee30ac99be1c849d38974007054e0c9dfd1416c44b776ecf0f161b1562b24a4f1e767859eb61a74eb679b81f7c3492218346852e43b25fa026fa49e5786a7d33a5078d5078f1778238fca38108166566c70813ea7d2c7f3993eddd215e73b28579cd3bb5d91f967bef2ce8afcddb6f85795c70fc2aabf6ae367086e7f59e342559875f9b30e73577f1fa52ed5ff874850007649698b231dc5a4388247f5e75e985e411d3b987ded7bdf60e99ccbcc54db750791cc5dba31f306aeb7e6fc49837431b8658d3f9472f85e1adeaf385948f0ba21b4940fb2094b5a1c5551a3cb4c428225253021e1042dda50c284c2092d2fe20c1b6981b0c61426a2a8c0093880811a501c21460649218f5220b865ddb4c06b4e22c47df645a9df3e891038c45beea4d39fd2e94f7d12a1a26d2bcab62442dbe72d29bc19c6accbe927e4de7b19702a9e0c9d0af94984f8a5b7fc930811f156f69fb7fc95b0818b94b0617e1616cd90c32cd4b1613eff0c89784b4847fefc2a3cf0c75b2ea512549f413f713390992a85711b55d5811ca8937d12213ff256160e31ea286fd14f228484236909a698d00a29c14f7f8557c286feedc322ef3bea578876a863c3f6fd423a94071dbd6a8067ba4c7e5405a5a19199c42d7370e3c3dfeff6d53bdfbcaf9d97cf6a480fd3d81e9cc43ae4b7e49dffd13796ec8093665b37b887f6f2c66fa0b7e28d1b52c78d1bcf205df1c68760b7e28d1b3f321255bebcf1db3be8db167e6f7f23e4a31691963012d3be364a299ddbb67d2f1fe6c79eeafe3d4339ccaf6b1f78836907eccaf2c6cbf0e5f7dc06eebce83fc6e0f871ab39defd7380384016c89f55bef1db86cfe0b8559877d5d08d23620dbf55423c90c5194c2085cf71770394350c290cd34ef4f1ce55439de893fd8f097ec4e1286dce29a17ce328979a1af33b6683c6872aa79cd27307bddef847b51d1e77779e2b4c13e4df9161864fa337f0805ba90c2e77c04feb181cc51df0d33cb06b71d5373031adfe7b8e763facba626228bf116e9449fc49c2d37e14abfc61256cd00c0bc5c43d6e60daca5032dcc03d90b00ef9854c4c5ac73c2a21abffe8af7e5534d0ff543330c8460cf5c37a16615ee4466b78e34679686407362ada818d36b063207701398a8bfc22483c1b703ceb7f3497c4f484373253124331ed0b2ccaf13afcac67a1acbb01f67c08fe6f20f845907096653e335343f33b7f464ce13371fc80be1fbfc7ce8fac9aa5006edbf2df0177758caeeaffb5aa8b200aa0d370870682edd0ff5441e8f3f71f1ba578c0aeeef473be2807eb7960d1ff582c168bc562e560e5c0f139fc7b5efe4bf0250f0c4ec334790dfcf9687a402f07b8dee209e98a86b09d704c5257211bb528657e5d270cc7233caa7f4ec838e11716edd0a227026f6428661e3e70f0f8f1791f8e276fe48e7117495ff33c1c373734a43720f736e098a3662111d780e357679e061cbfce844c0c9594c450ab4ff4f91199f5e327036f6c26947a1eeba9b34050a6004419b2775d53aa5c2c90b048da97d6473eb4230dcf816c6c5f3eb89192edc147ac43be6cb922d3d03de297c2470e76c7806ce5a4265a9453fee769cf494ef695bdfc1e9c6f633ceba16a39384cbf37fb1f9e038e3d95be0d387e5b48c4ffa37b3ea9276435a7a38537a5140f62b54f95b3d2df2143d1fd354d63f99016ddb5a11d2dca9faeb9bb873f5be53bd287513d3a3b365fd26cd3380c9a492dd39848c76ab93e4052feffac06daf9d5cbf769209d97dbd39ac7f9554991b23ae44f1b2d6782f46dc0ec73b80de4ca03eee2e01c58ad9353d37eaa86e6c3681c27b32c530dd1988c66dc38e0c8aa33f593079cbfaa4dc3c18356dd62a9fd9864f5dca986769e53694f44fe88e3959f06e7573c5b0f76621d47583943783684445a944f1f07dc791e50e7370e6c8b9df8e504ae727670f1564fe5ea6f562b1cd8487e28b32ccbb44cd3f833d6f8358d5552ee93012a0fa932540efd351b671bed1d84edaa866cfe47f37378e4a7fa3bc80fa312e2cf6f03f2fb88dfc762411d83693f323bf1b8789a114e72a285fc1ba83dceaf6a933a60afc0de01fba88d5a94eb922fd286ff9ee7a438e1f4c0e3183bedcb5f7e0fd8f32cb474c594aa42dda5154851b9addb01717e05faeb8039dc64555936e7bbf365b2cf62f3733ef54c56cee7fce855999c9f116bced36cdbca79991cd8cd4b1b4e4543f60cdafcaa82646ff33f5a03190a47d1ba09a640afad0292fab9deca09c7ef8bc0d7e12f4a22d4f33cf43c0b656fd3036adf420c0ad13e87172a7fcf73cf3bf8c4033d3d3d3dcf604f58d442e0ab6af8079f9be0290d84f3f2198a9ced2585e12a6f8f6d75f07b9f037e20b860e76d215d1787e31766fc37515a942f6d42761272528bf23d203cd6d802aa1afe8bacec9798bf87bfba813776ac911a481ef991d956edc11ab0e61d1c8754c93d0d38f654999f01c7afca844e440c038e34f5a563dc3b0c3f5a943fa481fc191c7f5b4d49234be5a74758425653d230a332cb9a00af0784e28d0dc55b3f2dca90478b92478bf25755030bf5bc149ddea1c435cf6c0cdef632b353daa66c383938211b754e185bc22276c596ca2a205d659ea1b8ff088e58aafeebb4c9cc99f7fe6ba06d669b993321cf99f7dfb6779006fc544333cfcd8032328fa45dc667405957b56d1f64fef632a091e9acc463a175550ca9f79e9b41e6b7e75a45c3cccb84d1a5cafccc732fdd107dc9fe12a4f9560991f9992a622ca937ea56f1a24b65150d313133e10e560dd53cf7a3e5fcf6b481669e478b3099df3126a93ed4f0c69f6a0426138e49aacc1bf991097db4e8dcecb6f7a09c9cf047ba8536e07c4ef8ab67214ed6e0502465e35024bbe4c436b0e655aa20335ff332a08f167f1a0816c3ccd73ce772e7737e2392b3b393f3ae1ada5435c83af3379f6364e66b5e82453aaf63130a89f91c5ea8db1725115a3d0fab3066cbf92de765c0271ec8c9c9c9f94d27272cc2791d24b26e7f13fe34d04c081b3949a68aa126dcf1f38337728c97c87cccc77ccdc7bc3fd79c7fdf8facbaad827e7ce647afdbd374d00f6ff96fbf3d6f0f1c5887ff168e5e8bdfe69f8dcd8dccff6822fe3fef8f03ccfbab54bfc950c65f158587f3dc736c5f32ef3ddf0703859301b932946d731970ebb675db16ea6c32bf2dfe688ec96ca11099f0090f398ff31b119c2f52629bf99c9c997094f96d7b9c4d666395ccacab4200ceefb66270de655ee61b88261cb91ad95edac8af79ce8dd8fcf7d90e329ffd28f3313fee506dfe03479bcf6a6ade553170ddb6c604a9091db0dec27919d026ac0147991f699d792eeb6a40f93423d79b99979151e2c1e3e74746e6c7af9bcc8f5fdddcabf9ec6dfe47df803a78bd9101475a657edbfe876b5566bf81317f038e3bd49ab789a9b951d1c01ced6ac0ad34b44e70e498ffe13bd418702b0ee88123ad5be8fd0f9fdac3c4469a3a3214aa316d3101de7a8f92670403f2bf6eb8aa21bbad9543926d1a94825b16b7a5a0042f539c52cffb3ef932e54ab7e422b74899e5eb0ca5d3944e9eb73a54cd19c6d055a98e1fe52d8b7d71d9987642e08d1b535454038d2f53b234d0f86969a07163aa3d76571a287b62f251c4a819aa8de8981326df82249bd857ffec0bcac95bfd947adef7fd8fe2d6a5c5dea2dadbd868a1eef3e8a0d4c684d5d1bf5bd4133ce9d44057f665d4405b7770f124d4cf23f7a02dca5bfd0fe54bf2984c244a3deffbfe9d6a3fb7eafe76344de8b180fc37c5bf0522bc19760eb620024f470759b587c1544d8ba241be16eac0d57584f0ccc0a548b8ca306aebe2a481b693500dd42e7582c8ea2fab87230f955f9e6c946852a71195e792cad3a8b2ec52f925970ef22950b349f5291ea4925d5cc988698937d59e46ccde5289246d4a9bbcd5b4c9839e9a9a68136daa4dab872a25dad48637f2539353652b4e3c51a88164f7d41bdf206da5b3ca999fa90a4a5b825b964ef6fe498424a89365ae436937dfb351aaf245529d3fb27cd449b5ec4a9d2f756ae8976f43bf0c8b9490df9f8536f06f61913f7fd315ae5ff66c9dce699cfefaa66dbaa6bb1ba669beb3de3ad55c77adea97e6df51dba7368bbf797e67e6fb69ea841dc30947efe36791b986959861f8a90bc78f0bc74f85a398312b51de58d2ea8423ddcf09470f271cbffd2f1cff261cc51fa7ba5f53d4e2fe0ca8e44f1ee4635b1b138e9e172ac184235585e3b79f0a9fb670e45179763c6969387e9b71d4e7ad56d5aed439e182b4a7bf7150aa53bfaa2156b7b4dfc06596377abd55b603c1f9737dc415c5d868a4557214b7bb9ee4634be14029a17400bc99a4c2913a73a92c95a5b2549651aa75777777a7f8658adbb66da3f9946af324ea4d5a8c62448b1eb6931671a078631f31a9de40485bab9e38e19653e0ad15509c547f19c340befa56d92d10e13943e1b6527fee2e4005b8adce5e554f5587ee45d60eaac2b4aa838caa7b8191b158e5cd6181e7deb5db17112b551db2ca441cabb0172ad3e0c52a7f17846395b35851c6165354e134c594de6f75ccf046f1f3544e58562d761005a255baf2c21bc5da3cc43a859452765048291bc8a594325c4e825b393993383314fe2c41b946b8ed9b167838bb5c6a531651a0c8236994e549090a6fe24ca2b858699212a597f491962c549438899b7489aaeb5477fcf0f30e6d28a9d4556a719f1966c7cfba606ab4f0ba37088e1a2dbcfda902c2e14ae9d239ced65b9bfcb232548bfb315ab89549b2499728272b4d4871245fb2450b1315279dd4b12e579ca634c1463012d491cd42061c33bc6d91856386275b5cf6177e0e351970db6266f9d2259581d7ff5503b9bae4cf26540cbefa28a954964aa354aa4fbc9c107851bc7eaef25bdc178cab873eab7e1fe22a5fd65042cda50b78231542142a8b5027242317eafabd1ed491a6f60f03e1858bc39d91b4e2806cdd17d755128208f56b71eb2a095184fac1248cdba83bd7c5ebe290430242d65d1a820f940d982d57aa4a8bd1db252d4cf503de2e699952f7bdee929626aa6a5ffb75a3b1e2cfebeeee761590cca0d2dedd2e8174b8b29a823e5a641e73abd7f3b36d7bf6766f21799bb144b62a866c6edbf6ccdffdd9d63c5ae4267125b81567055e566f3450fbd75715e466e4d4151ce3e12d5ecac3a5cf9e3b3f6564c183673b319596c9679095131b4827487728d6fd4f12fa78a27d87eff3f2c9d127a43d4df7ff4085b4e7ae8f635d387a14d6c7d18f90f6fce00e407b6625d57d1819fde009bdb000e077615be0ffe11352c2c31f2db6774b2e8389b68294272ddf500401aaf2b3b80ca4ca3e95df3d26f73625b8e94ae4b2ac331f16173ed78c460b3d18161b48cc5695b3a7bf0dd45ef7aa81565e85611fd5a3f9eaaeb81f9f25d6293baa1ae232eeb79c4c35a48519a53506ae0dd31da65823c193a31f5cc8074d48891c64edd8910f42b481bcbbb329a56caedcdd9bfdc0c1ecacb265f6655916ee77077252ba37e7a3d56ce53ebbfdb33a5d35b47582dad66db3f74bcf54190fa6bed4ee70eb56372584558b528aedc3ca2ab7fb6ae7491b48ae9cd23d7bd726336bd9d7dd8d18522ed7ace1f1eec32491695cf71b854152a5675a8aeb568479f985d9a1c2bcbc84635195a9aeadeac027319c16e92fa970d795fa1457e9ceaa2031af814f62429a6eb1af74b986cfcc27959abb160f975da35a66c8eb9a5f7d672699596acb9ae653669a9639e179443eb9be2b3aa774399dd022ad780c6e2baa72c8b60ef0949ad4b215674a07b0579c9916b2104443f2533b32cd69449f9fde8d61607efb1770577c81d9647d79f9ed25942d6ee1762ad949e66457aebb751aa4924abd279ec6592853d02e8986fce7d3ba99f4a9fbacee4e93bdee2fdbff684d0b97abd3cee2f187da04b9669dacfb72594e4a29cd6896895e5716b981e68622abefa3ccda4b3976ab59e972911b5a24227be0655cb783ebc6d5cb8f3430d91371a7f09f488b383fc8324ddb3939aacd15a57ce75f51be0682caef330bbb06da90dae0fab90685c00ced48c36306c2758802631ca1e145e5f746fab4051043489a4ab324e5fbf134ead9ccb299c2104f4d68e1d2930b6a963dcdb3b2503c42cc5b9b83079e5677e989c9138fd65d7a427a3afaa8189c94babf340426754324fdb520ad90a1c4b63e4aeb05174d57f895eacb65471db70b0b7564231e3275e4265a38195577271b388d01060bc05063290c2a6218218695165c811a03690c294b6364c182022c3ec0f224d9f8f934279c0f599665d90a7c985d202105d2873356f0124402b6d8c1144b68d962898dd9832ed030a2ebe20c1904f1a403277cc185ca954bc8c1199feb8b20787c51459defb3088d104fa4c106133c28411421c9832526b2a480f036005ec0a0cef9d40ba73abd061a797ecbc593359c40a50d17b0e08a286e708457c45bfced130b31d3acbaf081a6caa75e0aaafcaf8b23bcb6041e1f7fd44a0e9614a1c9833cf6ac5071842c82948c045e84a869e58a10bd058a9c568850e7e4a57286940851bab54d50283c2a5f166fa55b5b47b16a44b8d2add57858e16202056c69e298f8f85341044870e2815753b70a12889043081e4ddd2a4868238527783275ab4015b1c5f3ea56814a4205243c9bba55a09c48c251168e36d0ee4eb99276f777f713ac245169beb06e953482f018143985952080becaf9ca853ab27cc61d3ebc1b9b65b700403a2f6123b46052fd084b5a3061c907598c60698b2b517680c552d3117c588ad20265898b2e4b3f687a028436765f9303759f7a0e7e021bae00c2084f0841064ba060022107180801064f28d9c11231777767ef27ea589cb999b9a04e46537706132a68a209f729f5f424babb3bbf3b3716777777ee31a4bbbbbb73636131199e497777777632ba63edeeeece3f72952419eeeeeecefd947999bbbbbbb337167777e777e726a3c570f666777777eedaa18e907ef9cd8e458ed14c6e021f00d14c58b25041d1b4250b2c47685a38220b348ed020d1a8e623e6880a0c8ef8b842fd8a91f6d405c9080b946c09131b40c1b263c6c90766ecb822fbcacfcf2b9c94317184169c2406d44684932ba0b04829a744c2fc058371449447c42f852e66e0c591ef8a966dcb931b68c142fd4877a4f3b94182cb123e57322fbb728575e8a93924e12da8c00041451954904c0ef2138cb043243d91f4184c2f4da62481090b1289448ef15333832e68f073659d382e74c0649db0f0a05e83c838b1a2081e481c898fb16259414412ab7d67e993f3baf63cc2922112e62b417e0ae9e124dc9ff3eeb7ba5b802b929e01d7aa96cf2a24bebe2a863252eaee5ab7ad92322cafc1254a149410c75d837c4512672409ed165cb4408a10e74a9a100613a11e609a8a580444f08249a8879ea4c98458194a423d30b310dc72309d8163513582a4ab94a10e5d8d64e1760db8658dac04a9f6732fa04fb73e160aab56fd4b0f1cabe3a543d104de56191aa13c84b755d0b852fd99634cb1260fe21897e618972eefda208e3df9a0b168f4732c8d6d6d9555352cd30f269efc6d823128a02835d2902a20502b14e1414dfe4c6e4a8e9a5889518ca981baef29b6f34fe6a7b1ca1c638a516951c95127c18561e49852ed576a208d4a03f9c7a05a037d939c83f3e52526a67350a3a99c0de7600ac7c14ec74155652d1ccbd262c782b0313354313cf1782f61b8dd8aea493918199b1c1e8e3d79100cdc77dd4f57a7027df625bf5f876b7b541874e8f87170fbf96129030c04e851a7eca01fdeea1ce4aafb9299191a9a2536526c6c6e6e8e7096c0c1c9c901627583d5cece8e6a28e5cf4d9e4c535982fcf3532ee5d6e01f0487b891831b2c160b05265010455185292a743e5a3ca8475d1d66703e9d8f6a48ea00e2ef9896da9307937442878e9f9f12b0a003163a1654433eb1206c10c7a0bcf5145bc22e618376ebb65a50d2826a8895ac88f0465612eb3a72ec8963593a8895c4941cc5b6d46625310f3aaafd635d4d04c1108e5d1d57c92b22a80b520d718c4b8b354835432a1c532f3ff32d16c531a8a6e71897ee59462584fbee635441e677e1287f863a466648b7452da8a35ab64ab1a8065a185aecef5440becad0a6053eba3ae3820bfbdaea23e48dab34e4070c36c4a0fa09a87d71c7a55e542f324625c47fbe2743ca4a90b8f6d105c7ffb5b8a4c509f3b79e9c224afdbae0bc1b5329ed53dfa9972afa23f7dbcf7129493f05d2163b74da1d1a91df8554be67dbcb37229fa6a47cfa0deaa0d5961ae552dd214db19462b917eea6b6712a9898999aa6a01ab685648716611f0e4131fce392bf2135ec36e5e8403118a98eeb86e873373743eccbbb2fc78a1ac87f6a6fa4a808c9b64313c996524a0f2606a42faa0e4c894016c80631605b41439c01433c08b62d1cc6f0a0dc45a08c064e4c7184ca7fa31ae2a5eeb9a8a3e361705ab75a655a7c299e9d8eeb7878523ed85628a26763aafece5907ad76b4c52692d57f2553d9fdbf00814603c1182e641686345fccafbb71e3c68b239dd4e958ac1c2b48da71e0d869121bec720c29c263ff1cacc5c3e15540629cbc71a1c623ab9a3d677cb4c41f899452ce0e0520bc8eb1f68cc4466ccc190d278aaaa199f14b0ec7917f59cb40e92ffd0325bb8208542891dee7d1789e2b498c2580a18329a260d22cc836c0860b90886289255af083904b41a35377498b1234b8c815aca0026ffcea2fec0bf6420cef3f807dc10600c3fbbbb02f980b42efef635f301f3fdebfc7be603d06f0feaf7dc15e3ede5f00fb8209e005f4f283f6050b5a97ff8ef707da170c685dfe2cbc7f00f6050bc0bafc7fde7fc7be603bd6e5bfc20bd682cffbb3b02f180b29bc3f00f6050380389ff5f375ec0ba6635dfee1fbafb02fd80aebf2fff777ed0be65a973fcffbfbec0be6b32effd5fbabb02f980aebf2cf79ff14f6054b615dfedffbb7f6056bedbab49779ed51d8170c8575f97bef9f635fb01cebf27f797f1cfb82e158977ff7feac7dc158ebfa1bfb82dd58973f7dff705fb0705dfed9fb83fb8281ebf2eff7ff7dc19e58e02bf016086770fc0c7af9821101e97dc18864f8ecf705230af2f4f705232ac0a77e7bc188847cf7dcfb67fb821119e05f7e5f30a219de7b98178c88e6b77dc1880ef0365ff3fea97dc18868f8ef6f5e30a2219ff338efdfed0b4654c3af5e07468480e7f99df77fd9178c2801ffdff3fe30fb8211d9f0e183efefed0b4694e3597fe3fd63f6052352c08b8fc2fbcbec0b46b4804fe15bef3fb32f181103dee755787f9a7dc18888fc0aef7aff9a7dc1881af03fafe3fd6df6052372c0b3f00078ff9b7dc1881ef03bbe0518118f07fa00bc3fcebe604437fceb05f0fe39fb821141e07d7c8ff7d7d9178c28023f8077e1fd57fb821149e07ffc0befbfb32f18519117fafafe3cfb82114de0617802bc7fcfbe604414f8187ee861bf2e7ea20a843f2800f6ac8b7f0220cfbaf88b803bebe29700180150675dfc100073d6c57f0388b32efe078037ebe2770068b32efe068035ebe22702d2ac8b9f01e0ccbaf81700caac8b5f0160ccbaf86d0061d6c59f00f0655dfc080055ebe2af011c0272ebe2a7014cad8bff00e0b62efe19406d5dfc0600b375f10b010bf041405f17bf0c60af8b1f08180319957fe885ca0f0396ca4f8001547ea1312a7f75a1f2ffb852f95f18801895df851e95df471895bfc7abf2bfc0a8fc021040e5e701eeba824220a7ca1f0070d7b5036c21a8f2b3e045e5070050e5ffe9a2f2eb00775d2b80bb2e17b8ebf2015500f953f841e56fb150f9452e2a3f0ae0ae2b07b8ebc2118e9eeb06b8eb0ac15d1708be0f2a7f0fc8cfa345e5df59e9e46051f971c0ef8aca7f9342e5b7b1a2f2d7b4765d33618cb7c4ff52a5f2ab72ecba381c1b48a9a8fcda8dca9f4dc1df2b0558d1c8525b485ba95c79090d2a756bff04fae5e98c2c6a4edda53396a8bce1d45709e9a91c7e8ff3e4350b96089113cb51f2a4d440dafbacfe924a3765e164e5e94af54d4b6d0f37264a3def7b9ffe3e4aa78731f4fcaf4b675ca9feefc4240a977538aa746a71eba26d51393b24f8be2d6a6e514d9452598ea234715c9840d13d1941c9625f502f46e0d07fa1b28b67f4ed6f514c4c4c4c4c01a3daa884cdf66441ec10d1080000004100c3140020200c0a084422a16028186ac2b07d14000b869e4876589889c32088519431061942080284106008010081a99a1a00f9eefc6488e4606f630c03b257007b312e2ae872714fe80b28e7b11eb8ee7de9fb51e6850079288c27a492b5b8cc4e0ca9bb0b089bf9989a40cb37aedd12c2b831f3c51c25944241c49080b87349c3b3196f2756f4dcb3d198e2ca92cdcb0142ec2e6d9a85122e32f3b3add43d7208e66a346218d43b459036438066a326c6bac0197ec1a6520c2e8177586b9871c38a360c139b33ce1da8864f61120b5b3b2150ee3873c08193f2949d54853ac1095ba41d9b08498ec8f5c1727ac9b53ed393922d0d19372d94e093d1a003614dee8426b5a2ee7a151f27bbd18d3abe4f18e3775fdab7e6c3dc5ab68d610427098dfca8290f6bf87df1fcb8c19f3f5470c50ab5092b3b91e26fa60887da360a52be693d1415a9a9b4578876e59f20d6152da1bb68e17b847b02ea233e1e05fc33147ad4899561697016d0ae5421736d6450c4788038dbb671df1df7d0d45864706ea12ba9637766a89a6a626c072680ae5847f7d2207541c40690e54b32c3cc0b56d824ac5852bb0c6dd0736b673ff1903c942b182afb33ac6d1d7227518eaec7d4f2b6ab2111680e17dbaf76c521d58dc44ed52898414bc34162d8b886d5c17be1d1913a10845f76c69d02de0d37eaddc0b966968e51ece602eb2b6e5dbff1c89d1626cbc02416219ac459e80dff86eeb4ea4f6f02732c4450bb31ad8aa620a833d6f18fc5c2978f15c36c5d7352b7a285ca6c824933d01bdbc28bafe835b5eaee12535a7d930c75ec6812c69bad96de61e4e0e1b876a6dc03d3df6eca4951ba959ebc6004dbdd9e79529d42d151f3ea4da13185da3ededf38b31a153b2c55a8484415f44dea024194b51e77933876df34bd09b06f0266e5f9cd888db8d8d18c699f7cef8b5f12a243ab83e1628118d96012cbac3b7782f5f40b66e9ce58a3252305acb9042a757bac77fcb6d75c5614eebb15e9259538483d592525bd64ca04f641689c43cfe2d1bf972a108a94a555e3fce690c34696ead7ea767bcd61f08ca4236318919832d3828f02b1e4949dfab3a0afaff772198230a1883356505b8c45802ffe1a54d5ec1362a726f07c98c54585572940f8c54fec247823cea4e16379e0e25f19ac40c7eb86c431d1572332914274e5def29ca91e70cbfd20513ca6683ad34c2ab64ada6bc3620a8784f67158cb47fc9a3f3aecc7bfdb47d4d2c5644e5225f7222dedf70bae09f1c2fc1432f051c83cc8c3dfad0f45f5387988768efa311aa88f10c9fc5a2ef726851c20bc7d2e4405d39d057c3428967017d04d98284bb7992f1d85ca071555b65112092d52c7015e4ea5d53aa95f27498b5e20bc9be0d88f82633bbe908aab84ec82d91f496ca4ab16bcd68b6f144e1c46158a7a2d738b6dd9b98489e7b655454444b1f9b044b46977e7d1ad5f477e067e20dd9a6c3d0e364303e33c65a092e9b6f6ebec860a55f0f9de0ce7ad3c54d0f9513bbc754574b23e9f157b04780733720161060a77eef886c4380d5a3f33540ecc2dec2015f41035ce00ceef0460bacb043f6b0f7c27b84403513f0761dab0b0231a8b42dc3889983274a0b525c4c89a73b6982dc600d5be0f354aee607f9493b4f784887eae02474533726db297d12ea77290102158c9c490613faf2a861e75309ed024bbe9b9c708a79da204ef695ff0df6a74b70c0871ffd65672ac0b7eb68920e9c031a3f461bb613aba7b1a2fa8b41d178002e5b3ccedca14dd865f281f9078b7f50a41029688ea389303ba059932d58a0663e663b275a8e13b1df3f734a14bb94ba7c33799d75beaca92a1d490897e38b2cfd64b4c0b788475362577926fe0921033a0949b9a22bd037894db162657dae80072abbe851d93bfc3e781b07cbc2a50271165bfc27848db09f3f223c43227d07a412d214578360a672b0f9b31c2d5ff4f74c88baa2ab6f141d1521525f4e08e9bbfa201c89bbcdaf1495af381bf3069f145271671a8191b17422b12292a9a961087402df67bf614660199c9896d6f5775e7c567213d4c8ae730cc42221055ff0f402c902a7e6c875859e566414a9f56b5a1745a81122f0dc94265205b401c0ad2b8ecbe818f4854ef8ab42a0b53f3cdb4a84f755b75126cad72242d20e5c6337928e939902c24af9872da09704a499f320f751f0b2fbd832427214c3cc2118de8bc28425fe1f2d1690077c6a9a7f59ca0a2bf3172667840627f53dfea699579ff59f7928f3cb946c22cea9afbb0032008baa6b79ff8a00c3667ccbd3fa1c8282c180202ae064f858e3156109c5c79c3778102f78806289ae434d4485e0b5f18a4f82bfb40c60191411f01d0631d3dc190ece090fae56035c442ead1f6edd0803ee7b953be3077b134dd02c65c163b7cfabe11b0569d68b37dcfe6a7e7699d667d91793561df202c12728d18db0161e2bcf0e4dbdc8ad74542cd6c3f0811f2b1a6f2a40ff9c8073ef5299ff98cf1b1b468aa088745c1f8ce38da69915dd4134eefef453338ede853eef7f2941f48609b454c5cfbef3eaf2ea21db2db879d8f3c39f2b4c2cde497c9b1e84f28535a747aad42ebb249aa31c0cf213141734a510a31e002355e1d03902fae08c22ec0859df5a90c8073145ce05762c85fc8c7cde1aa96b76eb26fd81eb773abd2523acb6dfce923ec8f9bd96a727931cdb5b724e6266825226795d48c2d19d543270c2ce777f91524644dc32433de2f6153f60fcde82e95c01c379056fd61f34ca02cffa4a67381aa0f09d244b816e08168f404fc930f2c1f9783abf0d22a948bdeb9b8376189f24e6331993837c1b232eb140589a9429fa5e4928e627a964c2c97ef85d6d8a3dba18156d06b42cf0345ee8e120062bbe6888c552adce5bd291efc0618875532201727df082ca2faa11dd46262c9a2070ee5de89189b5fa9a6d55bdad20d79369f620b1da05ccb366b3a37aa27dedf55a4b4c6b25305015b29b0323438fa08b07666eff1ce21d398e0e83e00cd09196ccd0ee46de74a5f1cb01059ac03a3c9a4a082b65a3c8988b9eda1108ec9403b9c5de265d8efcf13a387866484fac43407a92385077f9b643d9a386149b17b7a477750ba42c7c2a9a77b3e4b79e61569902ed7d4173cdfe2b54a31dd6b819805667954e5a4751965ac08bf9e713af8aa85f2d6f8ac1b78bb0b1ba07cd5bf08527f1a4d294733337e618f0bb259f96bd7f2ee4a32a4e4295146287d4664c82e39a09588b403a7178b9aa8b91e14ba3511707660c2c703e306c29d199f0d9d953e5ff625c53fc03eda24dc81d0b30d537178b1908e52b171b9009f3652a26dafc8a5cad5ef8a7f1be640c8037b92294ce3a51dee1eba66188313b5ce45d8c357697b607e24e153a4d91788afda8fcbc09c134498c4e589928bec3770c5a6ecdfdb99bc73cdf0a911f4ecb0e75e5338b93557f2f16b1987ac160e414943238aafd7bfd936b1792adb65449ad6ac6bac2bd8fd289a0211dd0b4ad78ce3258a55d24560973b48cf55e5051b32432411b9d0d4b0e67e4ed9f9937aff6861c7d2d0352edd2cdd760ccabce0e70198442eca8df812948d8481bc978264c5aa9f26f5c01f5aac7d9cc563c09d4e1b70bce7c3b1dd66e1c26163b609890aa0f800ee322bc22f85875be551597deb6eb7094ec0a4eeb1945136be237bd1e009d463c8ee43488352c73cdd96773a7dac0f8bea55cba42d0794b64a73d2e980816cfbaed781c6aa06b51f659dae1c81ed85d36e153b57da9885a525ee9120489b23c276bea0e895b697f72c31ed88575475858a9e42afa2afa1d7d053e8d442676106e7c8ce4888eeb66149ed97d5def5d62b09c077714ab6dfacad816f1a1af166b6b2014583d5bd93f5339524035472d1d75871a9e68b6a83a67598284b1a2d176ccd7d9f5456268e12e4a6adc6789792ca3b01f29e3dc857202a600d6d55de5c07273a86788e8ee1edf582cb9fbde07caa546e9005ac7f1c9138edd6cde523194bb7fe258c6fd7f4a6ea0d409ddf62d6a53ff0b4c264b89dd520ebb6dcb16594959b863d38ae118b060b7cf4c1e62949e437cfc78e46c6ef89393f728459fa8ae08e4acbe62651f2c31c513b49db553df2185d9f12e23d6127341507a0a3dfe6e74889c072681955c5cbd2e4b0ea8e0430ba57e159d157ed6a156f3ea0d2edbbb2ad3181b4dcdbaddc3870acb39f0cd9c57024c4870ce01f883ca9b2315b980860476fd4dd4cdc5284bec02e60e95ac48fbd56ba5e71c16b9364bab8ff688f16d61625e28b77db4f7f17612f7b76e3798f95c03e7fdb8a4cad466a36e2f0a3f52cd2251e51432f6a69521846afa678f18f0b8e9b6923b4bb1188d79885401e82fa8090cd7d53d2a6144687172a51e6572f10cd5d1b0a13c8b9e2be11aed72f650471983eba2f1535dc0b3d3841947673bebc42caf1a57723072c3f0a6fb4e8ca8ead49941efa7f452b5128c1d8a4bd58be2174a2349c0b0d4811bc5c51b1898b932ec9d5e91f43e6be20130cdd2a1a675084e75c10e0ab6b8c2c1f6320bed5bc0ca2ae320472303e345f7d0639511a2df7f264cbe7d245bcbc99f16ba304817cb57daeaf0d8508a4e8f431f7b351465902aa68fa5c8c919d158e6a1410bcc3cc8ff50773182a89cf92e5dad4bd7ef09b1b875d11bd1dcff16f2c3b5907dc0918b1a86e341d3cbd05ee0ada485d2cae7e3a288b879e77c1db3cd04210bb2c88f55864b6304f44879f79473446bfcbdb62ecf68020e12d51b7e2398502e8f3f006454534f913778b33cfb280ff6af11da4a0190a74ff92c27e8a93da8379e5c5c9a0b9c617aa27d7590946cef564bffffd3df3daf8689e29810456a6243810e2f2421cf3c708223711eb42710fbdad89b38cf2ebdc78dc3d188c833fe8b4626611c9c373a4b3c08bbc0b51e2bc13a76047a8f26bee0332f72d3889a34d1969809c242d351106c2b97b1b23cc816693fbff5e52b49ddbe2abc5793a96f369318ac083a04b383fa7148e83e71a0fe972a368d910649f01642683b900a7d4abb50013c72ac97b46d3611471f6a87d3ed7b7204c68729557d883469f62a96e911e89752c798a0f2853ea596b982b4ae8dd6d92cf90ad3cfc796d05965b52a91f2e65a1167079043ea34ee9ddd40a19d7e7dfdef008e5a3b0745bbe6439af15b14b07872aed34d68bad17eb2c3f4fe27223222870c5f48a7f0066cbf9136387d53d7f6ce32b8afe50e4fad9a09c812ab3f0770e1e01fd465b212956ad9325abdcf3278a81633b8fdef3841db66daa5d6eb4a26a418697355f3cc448bbe0bb88c6d37b2c31f0aeae963eb307395c065d7321c459dc167b20b9882f47e5c56b8b84f6a8659c993b13b5a5c0bf7cf641ebdfe3a0fafbbc07bc76636ea1c0579078bb17eec81cf79402e009d68279e7506d4d13dc0556c98dfb0ccf3c855cf16ac55626658f47055e77125a488234a347f862ac785f936de0c2b22459cf21cb8b26d8da80ab62aebbaeffa78a291f15562c46bcf813fd75ec18f7a7db6044e4f70b4eb3707de20844f64408e98b385adb9a131800987ecda89bcecaa57ce810c9e6aad1575fc8296bab0e82e36b5ce272f8a36288a8b36603e951befa3c4578390ba6dedc086f83a2fd7181c8c3b3f17384b050b49a0ee78f606c83280616e6a0e7d01e8ed0d48312662f6a6933e2ff3bf89b2d7fb194ee0f1c374ab69334e65ef795d9d483ae21a57115084892259cfaa7a995e7ce72d8869667ca217b9399047bee81d797f5f5b4d657372620d8ea2f08460e0c1f57c4c78c182b517e6ac1fca82f6f5e736feae807622129a7f861df57a09c9b5bcd35a866bf7ba81f2080f8db1456d397d0ece0d0cd29825a5c344ca7ae9436abd65e2f0c290580ffde2ac9a7339faef3a930fa94703e1df9b91f4708eb086f1e44fdef492ea567e4f360596f88547a110caf8be7614b347c9f11a1b503794bb29ba52cf13e4094075ab0609e0922a7a35540baf0fc774517278eb801e7616336123d375bc427dca20a6673344a030dad468aae6260323a6ba75065b192d897c8049da355bae2c6e72a98c6d6a637c26009113c63a9390fd61cec4f583d2141a9654b2f176a6c257885d3a3d0044db333eb8f8a5f60f680fdce7e72e702ac750ce9b221047c73de797910218ca882e3a21c5b78fdbf7254d489a291d089a001e171d6e1fbc2897b33f193e3463ccbfef423bbc8cc2156d37e6fc46577a1132a1bc2147c55d8b320fb3c9093a92af11a55370945e2168345c6173c748868676e4f359c901e68214bb43c883d94cd7e793cabf9469c024c5ce585c0085f6734adc0eac894f07303377bf4a1fb731db83346691a8e100eaae3ff91a7862f5805ec70a94f268f6c4b4b942e933ecbf6406988f7acb525320cbb83f08dd27df781403de7095d192e9833f77f49ef347b4e57d79862a600c790a5ee528edb0dcd28be1b930e9aa98a96e3527adf0afbcaf029dd8d9909650ffff17a6ed426861c53d0901ca0f56fd995fc04008a7eb5a290c5e235a4de9f5cc5a7767743eaebc0b36cec8ccb52c71ef68625c43253dfd6cd2a12170cca252f22b3ea541cb23bddf0db0065a3fbf3527d97e009a4d3f4693b3e5afeca161e0b8dca863691ac7364ff9bdbef4820134278bdb1287da0da96987f3028e000bd93145b071a3582fb980d2d11b57b5a7f063523dc6dc418188916a990f023b01ec20d1ab4d1a31d2be8c791276c027eebaebfc6e8c83154e4e34618e63e71bf851bd8091b8e20f6aacbf9031069ea5ba6e9fb3574ab74a3c760d72340d2004040516f60e1c4fe96b7b61dc0a665013c2259e69954130e24a600814d502fccf0656d7d697d818afd17ab08558deeb858a242f58851649c3644b12144d55cd3cbec6a5cf4a6098aefcdbcd0bb6df5252a9a5e5faf3e9695d7cebf410327438924e63f3670631bdd0e432434e0959037c2f8a085447e563b3bc141bfc14b3d95f66cc0cf1ac0f1d7658426e743742504d482462496d63d8c567a5ca3473b1ae488ac243d002540ca44d1c8817fd53b41231731fbd8f1c36eca96727aa78b6c256dc5182638b420e7787dbc626d2b03493a9d27ff280718d0f376bbf4ac6e576101885938487dd9a3be01d7b92e1559aa9e2c2d53f02f91cbfa691a0009618a2297326c819b2c350636d6938ef01404a53c90b4a13d05a548a402c87d8b4d4aeed19f0405989cadf35f52538fb08f31e29f30a1f2e17a226628b4c57a0fcece4bb0caca823db2ea24306f25a54cb41831502f5d94c510dfb8c1313ba0063b85282bc10edbb50401ddc3b3a3b78799412f20d3af55ff7e300c06d37a8469944c8c79f4187411f24dae4ea3736ce0ce41049476a877264d28e853add467063c518011a45e89baa3d09ebb847059b9a0c68148071253fd7a0844b3bc830f27b3a937e3ac187cd8e8f3d9b3fc559d6105d540dacfd4c69bdce8180a8ef7211e3c2731cf0a6ea0d29f3df8ce2089551465a32a1fec8e9724caf9f6b5960f9729b56d51c26c0e3e64321589bd428e8c7338b346e4ac22bb360fcb9b89cca0be226ba870e6c32146304991433a06a222bba8e49882772dfe9541997fcfaff30468faadef75533e3845f7cdc7970e458855567e68bbd289b5349ab79cd19567fc0baa93894b2d18c4188e445c66d1d323de802cb1a11a251acd0d9498e2dd446fc4d0c3032b15ff8c1301fa474c37f7a646c9fb12883b3450af86a2132bc6de7f53fb7c01f90797ee618ec40642e1386c2a33ae710d2ed616c613b77393be485e45a6bd065a55ba4b0bd7febacafa65477fafc0855ce0cb18124666cae0b747b40243f07f6c4b6b26e82563d7528a60fb4158d90d82cb7f13fa94e5c4c7a7f3fbf7ee5ca1bb43f4aefae641446f00a160fe3a54671802e122e632010f52208b5529271b60780c328eaa1e11dcba426f9abef358139aadad7193bcbaf2216e9a8679489d75c6ccb5766e7355a5144c388eeb661d3a1b138623075a7ee66800709e73bbcb430d2ba48830cd610c225f002e4bba40621c78b67dbce47bb925eb7d9258d548bb593c4a2cb1d0d1034e53d4e79f0979b90b795defe507eaf8a6c6f9347a97a86c1fa5035042ac1abacba4341db92d34b8b80cd509ad49feb9c9bd6e4bab7db0086288d704be611d42ec8b1db752cb0b84fcb012f0080f68cbd8b8fd6c008c7aaab58195b592725b2bdf0faa4fec9a63ba0bd26d171deac847696d21ebfab550aca17c8c3b5f64982c980c5cb230a0ffa18bd6e545e63dbe763b1f8a748a9676e61565b1e0870538a29d9a8bfa545879e246441969c4b8935e6614b1bdbf9b2d45e388413cfaea829489c4b3c8b83462c5c2e2b6d4d35aa9e8bc5baa7436fa5e8a9e88637e4022c06f06bc5106e48834a5f8b07400c5ebbec14d4817d86add15679174dc482a01463ad6387765bc3b23d5dac8b73578e6f88714638316d26c6c540c8eee972d4a22acd04483ed7d9ece3c62fb5b26596004fda624c29ea860bb85ebc04677dd4b37b3e9befb1c8bad691081b349b2695c2d6ccf483824651b259604bebfebaef1b5710226c97dcf9e0803fcec037709fd757545eef2ebc770698043b3bb7fb08b120876bb88e4cd6d678dafb77e31f606a0dec0b4d71635500deb1650f55eca1baac3961b0a85cb556d80466369c2952ab1d9af45676986df38c404ab0304d4950f0e7469758ea3f4ecae494704e07f55ee1c0e5f74ed884d1a6020efddf5ada633448315490f69801958faffd25bc17e1d8e00702d1909e01b6e929a79626b5e0f25d62b3b4a41ecaace592cd78b07d17c818d903e64d50ff820dcf75528e8773b7f77c27c2feb6fd4937be255664ed8e79cdc1e4d50de3ad3a456356b6b550d66c17bf9a01a5cc836b08dd355efd7914c136a56b960754f56021268a710b282c072a260f5cc2c506b3d223465acaf051036f1962ca6ecd3b769c40233ea1388c8e27e6fbff44390389a7af60c7c71f252f993f11aab8b1e74818753eff1c0966c55a6fcf94ac237d3469258e753b08f6de14361d6ce50e58d27634ed840f71496cea0793b80a128414c4fbbfdde27ffa2897c94d63edf2fff9d097c4cb3bddeb5ef7bccff66824fd3b6d7fbe6ff34d9f83038ed2b5c8e81d8156c1687d78e18db2f055087f08043287082b4b061b5bd211d224a1d4eedd93f867b88c25fff88dccf87bdc74cc690d08fa162d9b86ab650cd8a6ae295561a750aa2a13070de131b7a55913ec3dff0f4188bf5748954bea5c7e4eacf81bc17a6a184ac632bea9420901a2d108d1a380d6cbfae33d0342e108d1928512e9f7469a0695c20180df06dcf58d73d1080327a3e3291d77ed418a963466fabe6b6d758370e63f6fe3dec28ad829ebac279bd8c6d838de95e91f98e020ecee5719a5246ba97b8f7572dae58fd0b6993affcdd6a43e983f20c54533237d132dc12ee4f8c8838502e70080346b24d697d433ef0b55d11624f2e4cb651eab2c1fc2896ef6ec0010ba55a8e820383439e3c5f42c6a43dd4362c87a3cf1e50bd6bcb3e9194e6f164c1642129d684a497584ad71ba09d1dd0635a7260ee724078c2b558bc5be82d2b4fbd86175717a993dd06fd12db08085ed7467c0bcd872cdadab301ff6e27b9101f2a6ff4d8ba8704312e2095f504569e87822476261e61e809778629cdb5dc55219a2946ea6374db0376b3f2904cc5dd2b501d07ab80087841334518dfc75f985c4a834ba4dd6e863e4345e3ed98341e5fa42f858b3294dcb80bad954b8aa8c0fe13c8c8f704239f5d4df293ea6c28240240bc637b9070d9bc2d7d02e32cd697d1d8521d3d2e34ce46e7003c6ab88e7a6af2a4021ee0c984c62ed3b927ffbfb26e8c8d6971193d2f1c5c01adc17e631cb359c73015735a3eae6f2c519198ad9f42f9a1217a964898cf6f7ce9c45534497db944d5e99358580c2d5b566e2cec050a3c48bbb12c1a8ca3e9235e13d1444a80031b9d362b287a3143e6c86eeff4eebf207160a949dfbf273bb6a794cc701077326da9c3e2fbc208d63348daea79e08a8a040b10d38cc7da4ac492b6e893325bc6b0d534dcc3a4a6188c6eb580b53f505fdd798893acffd0b1deab8767c53cda342641ebf82986382ab531eeb875fac03c1e8f4418d170eeaa7df3247727f04c7c3dfb3598a3c33e50ded0bfeeda9c0b0f87a0bf7d06ef03c474ba2048c0a2353b7c85b00ea7937bfc48d442c7b85f3e65037fcf2415c7d38d447983fde0323c115b45020b2800c2f1b14df26f9f93c250f0fee7c367c9fa13984509933d653f685a040d3ebbd8f0f91e6ab89c003b579254c758270fb2e7984c0d1c0239059a8e74dfadef16ef2864d250b6d7e33c902b11491d77ca0ae35b33e0a07762ad06037a1244103429a3c19c023c42c5c0412101076d6988d04ae24d6129fc7301cb7021fda98d6733f9d6d968d4ef1c53554ed63959b5c0dbbc4f4430a9a1a288bfd6a98319824ea338414b42bebb84a2a42dedba3793234f828336d83c8c991d386084a60598a4ef671d412e5343367a5daadbf539272c0c67f323e6aab78d833b378144ccce6264d4ba0f5f65343588ad626f51f6360087e93cc8e82986456f20173ab4fe75cfe6ee70c9178ed24c21561a7415c89cecbf6e3d16a51063a45aef0cf534dc7ce32ac8de356cc528a5aa0fb6ee16542842adb549669c141a50ab2d4008777827f1cb8a4c106e3e4a37eac07689cc40192e910d71d5d96b911abb75033b6b91a8ad824ce7c6331af35805076d3fb0aeb20da0432deaa61779b3fa0d5eada633e1ab410bc4e8ac05a809e4e4b90f3005ac1fc6e0d34e9154ebb6bfa300022b28ed9be72e3105bc3640b19595810076f3aab0314817979526feb6eebf7868aca4ad49b1649a85f228a1a7804f22551fe9da5510095888600f7d6abc7303420398f1682242ce20f2b7dfbffd5eb6c215bafa7ba553f71866b0eb4e47d257a1810166960450917f769c6582443126c0241185f7372e1cdb77ee061c6c2ac43a0344b65f6387e83084712137e20fc2a233360ddb18b0cfd10acbcd5ad41080985d9b5cab7965c2ab27a3f0529d9dd6d07c1d6bf0d0be707b5d69c683b6eeb6e6a9e8515e42a6efb75a62fab2361f235fde9080fc7d07895a7d65edf77d9f1fe52ce12c9de1a0570ad7716088da90b9fe7a8527999325dc9bfaa9078197efa95af252bd39ef924e96d1ca8e0fe7cff1d12270d396d09d1b160e9560181973cc70561c65eb6cf8ffe3ad236ee7061c4f02cc90089e10906300fe4c173cca890436a8ae6899cb0eeaa6c99a0fab25716e367ea814df9f2ab2ca5abadf652d70cc591416564165e9860da457d370fbe2f69d219ba14f6d74e2c4cb42892c0853e1dbb028cb49694f4f633eebfc65a14fd4374d5a34733e288e3ab314e922e33104f9bce6d137edf119de8ad5fe4bfcc22b3dbe2d78f515b9f098a768d2c032bb5041026579e46e422dd6640d27d802f2b92bc125b9df5b2bb9fa36a640290f1d4caf2fac484cc06236dd14edc48ae1c028f7a0513cb8c233a0b153021607eaca4c94290d816884008f728fa85c6a321b595b8b4fee7701465e0a887b34ce401ba93d93866cd9ba41c12c99b1ad32d7919df403ee2cd9e4d40491a4c55eefaf5108299b0ccba5c24e16eff6cd88c545eb8166c8374c73588d8104aef40806354900dbbf26c25ab866665f424995a0fd5cc1b83ea7ed4b9c24426875f90e66e8763a71a01e15c60261a70648579dc3bc55228bc8c31903350a34c1fb31e389824bdde9e6fd45e876931f54e988aadb434e8553a6fec51d1d14df848f5b39525bbffeb45ff408293a6fe090607702248804fb3b8400f2ea2ca89af7211fcae41bf2676c57a254770fc9db0cfdb4551fd382cc2628738f898aca16996fbcc76380bfa17438fc9bbe21123c81d5e0fef80c11398cf91c94905d6a8a2a1ded801294f22383fff60e2556c549845dd1848b96539a212f87941a02d6e15c16f6ebf063f91ba840c4372152220b171057ca18ac6e01805915087965ec6c621196193a9a1e285012e516de7da1591166c516f4d79e720d1fb2578fcf25941304843cec79647009dfafdcd3be4d29b1b2ea47c4b8181d8a641f01297f052c66c56f9dc7a0ae8a8547dd9efbf6ad1c9f356986143b7ed6504582b7010423805e114f7142bf1351a616184518425104a67591dc9a5b04de73d42d29021b34230f542f38442d10a1fd4b8b9c080290bb801f7a4689d90cd6d851aebd95457c39e807a13caf6ded826a85a815ddbec8100fc9228e3ee8588126510eaf84bad0015083c719c3956636e2d921b4f2df56f48b029de0b48ac5b236228fe083e031fe0f925b77bd26c6a6053d0077be8c6658728823a3c2b925ad82a628f658fa5f44b3ef8b478b8d51c85152c9e2587ac7f9a7be4b101a953900cbe45b246b0e34cb082187843a752793cb002710253fb2f7aa45e8da27edcb3ddb313f7b094c9f54055d2b61f501351a5ab2aadb0b61cc80ef314ff4ab783a0ae16ec626265eadf8c5d71f89a7b2a936209dd8a3e5779903480b159f6ab0451580983fd2e747f12d1c00943483d09296da2690cd5bc545f152fbcc022861901a4da55b5c74bf25bb09feea946bb3bf94c7b7a96c5e554963638e40e088649163bd41b05988490131af951b80ac287f9aec86ca7a8faaaf0e88ee6ae090972ab5d8b3134aed521416ff4fd5d64871494439f1009b53c67e7f9181dbd68d047b05e64c0b5a89446eb7471a00abc6c6db9c0cd4f8c10b8d1fe93c5da0d2f0c9a59ce4f5bacb0a6840fa2a669ce1425d6b7f3577b6fdbdf667a98581e89de94c9cac8139eda2ef1d769421fc202d869e6edfbe74a0629158034f404437731a2144f4e03293122851c5941a96f9da3a57e59aaada82cf5ae4e13266b0db0b2704ce674a03cc99b0829bd35d88577db9ffa83b2d461955140624d8cee3723c44ec857eafce821e9d5585f6c414d0f90103cd1aac26e5b0b08c69d0068e5b59df96efb50fe27f9ea3aaf8ef4366f8c884d573b9e7dc819239dafc88a3911cd3294966490a404cfea21b803953fa5398b60796bbd86a070dbf95b2b32b75d43485c8c0b8e7cc67cc4d6ba6cc4ff5989701e00d5968a4856bcac825b8b51e9533d53f583990c3ebdbc70f0404a5c05fc604ab73b245eefc092023d94a49998255c4c165313985e2651f1d8cd9789b77cd9ec772ff2e047c46aa9819c5ab461cb052f1e04f5e8764b08dc882b70d2c90241527f53de8520f1b451df0a5de2b1ac3fc70d58d9de121a887ed0be9f4181363c6ed3d346a863cc3faec6b19e476d29e134b7485430c7bbec1949173d0dc1500c2c8df96c029a073ffbc2e9654b9785beb439d203f0b96abd44a63c551a581acc088cf3d18d8e010e72c18a0a8a238a865b74fd47940afeb524338775c8ad9f0bc41c15d5fc473d6331dc94462db9443c20eada804fa2dc046ab03c1d8a7472e72574f924b621099fcd72407464f46100c1aaf40ef39ae23eb92ce237d2ec071ae441c2c7f43e8cf9dc4cdfa1b16336c57a53d474cffb718e75941df08670953fbeb05dddf38fcc6432f2dff5ac80f736077746014b75f77f1188a117bc5c42a69d59b33f76761e6bd636ac5467b723eaddae97917767a9b4764afd5ae239f9d65e9a5ce982e6357564dc40fae15b92764b568aca946ec6685957f99140b098d067c8149877d329fed61511c444c684c67664ff362fa85b76b99fa97cd155e3e94e0ebcf8b22805e28cbdd8b3c8da2d47106e2cda75a6fae759f71e6b6c33dbae16a6f3c947123311dfa6717883eb2e38f24867825917cc6aab32c8a65881e22c628a0d51d2f6aa66897b70e4afa400389ad59c31c530f7153e5a69a6fe296117d8d9d60775020f4234d1be5f5fb11ad42fd944ada0be201e1c1f9d32d42c4c9c496f5d3e10afc540f02913590433038fff6f909f74ef61af49719e4e273a0cfed51127490d9c8831cf2e251ae621c9b3cc53e8192f969047d187e9225b439058ef584b3ec937d948644022d099179b862fcacdbf88cb4c385baec8d5470ae8a43e8b2d04f843cb829c759f153ff2f2962ce4b48d0ca6f8c3187436daaac1f8e763b3acb93c5d36b28ed82571a1dc23e18d28a75fbbd163c5ae51e9ab74736fede2b11c86ea792d4b8efef8d806ed0723ba9b9471a527a34ab574044a22ae4e5e23d36a213f221ae8f0f7c3993b5c3999c2b7b859e0386e4065195d9a1816ad0905950254be89e7b597604c60b385e1d40832e8b90d5782d6bd600de17050476f1492aaad58c33d5c34686b9fc297aef57d8d7a29affcd6801e8539980ab61dfc8cd6474e18ac0123c6794459210dc763d8d939564974fdc4e1e48de9e6a72059717bfdf76939bc52c2ce104d519e4be91691e8377f29ef45c7d4ffe8edd2d9673cb86eb25619bbc9e40df2d2dd678427283b4e69b4c43ac9c8905b8ba26113031ff381999cd07eef14b27e39cdb7c614bb39a7e1e2a7e831f4af16da5dd432424bf35aad0a28da8de7039738c735a39c71f0d3a02a754b3501563311d701d5224692fb40fd43466b81d53748a6f55ae58cd1165ae2016523d31a5a7242e8ed5a11f162ae0ebd0f94940eee4a909620d4154121c507b01d38a9093cbfc3d1324407c5eb5927f4b349ace513f906fa2af708d88f9dff4ce2e78e4fbd4a9d7ec3e2510e63eaa1227e220f6b9ecf112188bd95d213b5e19e6d9fdf6be208c62a989a31dce9c06cfe66e2db644597fca6763d424ee4896f7d69772295ce5413d14525c0b9929e7f8c39b3c742f8d2bc5796080dce4187661fbe67215c35a0a610fb03da8374b0ee051102b9a3b72ec66798750f3c7bd6c874da0eeb750085235baf4a645800c479a2347ac2db015a27e236485496027de882f1a8b8a32150bcc60280231d6522e1d20651d591f0d4cc1c0ce23bb0194a414f4186120d5bc6de6d8140c1e2a8b297624fe124c18056b02c346988291be19e089615a37e2a1b21b1ca01e6c1694345f49196f3dde3785cfd9876f8bd8b5566bf0dc185cd26a5b1faaa41d8e248cf76aa3ab737bd5d1d83182d7456b747cbead6c4494aaaf93848c4d7a80695d5ef46ce766a58fc5ab40b44f5ed5d46d83a280a243f1a93bd0938acb7c0a5b2d1e26770c65bfd2e2a149c30e4fed0ae649fc5fbe306a77fb243e2b01a399639eaa23922e23ea13990daa8922522c6c3e94ac880d8707606971fccdd7aff6bc30fec947b141df86c838c9c2392b68d30ac6d8d3bb8e0a86b319d0d2502ba6832efcc8a5600cd1586d31bcba10ee66080482abd4fb46ea4d3678279c018a7399db99f81233c39e5f0723cd8897ccf467c89260c326b9c41e77136af26a3b972cc61874bf8c4fa6cf02c11df424022a0f00776400c49c1b0ff8c630361b9e3067239549e250dad5be14361bc20242bc0c7886190eddaf7e3e3a9d63ce6734457035d02ca859beb04cd0841361c4b39a754a9d33376287d90647e625951b1eac1c5e64b520509b9dac34e5fd657322142fa119fe1e7eaa9dac1a44e9daf93cfee98e6398c1f4366f82c4899f97c3d4f1b8b627244bcf13c62399a1387a8bdb82c350258edcb5509b7db00ef35082bc9c1cebfcba4d5aa3ef6c79442b4ba809915b16bd346708c16a02a95b220dea6abd819ef265d0e83cef9ecfca8e5b6a6467c9b167d18524e2bbd37ae05fb700aeb5a7f74f5d9bda2f1d686b3a54a254926db7b17427f85de99e442425fd723a0d5f8359d604533f0bbf99a0762767fd89941ddd922539469150aa4753110acd9bd52c35672de04d291c1dd17a0c4d01086ac0afd947be46c289eb8480c0f9ce12f16b9ee07b50d135fb404270aab9db50cb3a73bbbc1df7f4b29db6b432dcb6e3c1b1d261f091e5eb83ad5fa6703565567b9143a2d0fcb79a1835801ca29764144a769da946381d69d642d555e26c064ece57ecd1d6c11f049a8215fe35545e453868bfb9158f693c03f737840bda1e72d66fbbababfc4a3b0280634c47279a531fed08030e50186f01b0d37590781ac41eedf8c50ed160954606e26334f8bb34f8afb3e953390b213b55e6c436f557667f7e87d0e53f09d0a51a2efe167df0b362f9ecf0b4587864b594739c805c61428054fc40127b4a89661979808036c7a8794548fcf7ba76c9d6dea1990fcc159177ce34ce0fa9ec2b6598cfbb2c8325a2c49321714be67ace643539e70efa3998992c2f235c4de5c6e6be17dc873345f5ab9f75d6891de7dea3e3c7d89dd2d13d6d03ddf6ee1fd6763cb8a4014623ca256af7e7f9dcaecaa487e82cf163191d5d54322ac0673119351ca4380ea6d909dcdc5e6953246b0bcdae7a38a2ccb5ecba7521fc310656e6359d155cd6d976689036dad860a40a57f2be2c6e1928871182acb859667c3edc337d3a1a25ffb5f5f0a732c4a2f0adeded62abe871816273726c26d89226a3fe4c612ba633c329a9f491ca92faacfbe3d5a5d399a7e0dbc03af97d0408725fe74458e2a2db05d05c96b03e33d064ee358ba03e3df399962640acb927cfdeffe993716d7e125269755ab1bf500ae9624dd1c881bd8b74bf0b0c49959460af1adc7da2206d70dd8dfdac74415e3fd1011d9dae8b89ff0e04ff1344b303aad860aa2d248b78749548d467b78509e4f92c3e61a2480a36486c41fc9c3491cf10418d6fc9e82c97ea2e9819bd63c79b0614c82a4c1ff79746ceb4b65fea2baa6f7686a7b9389dd0ec2647332a50de73ac11c459aea451b949579cef6fe9af50ff37c36fc8f61ab484d6907c34fb994e3f918e54264e03064761fa1e317abd33d2b74684a310fa876e97630a6667f9e23ea211e4b1c6a494d5a74aee9a7bba607d657d74f96b735e3b0f5e21f920bbffe78866833c079e538ed7f96624d4bf98b94a9c9b549321ebf313e745555bb4d53b4e7cb48fee313b72e64b6acd240d2277fa2e695b538e76ce6cfbcddd61ffec232977ccbabe80df1c229ce2189856afee5741cd37dc6b6df01599f1ae6fb789f14e9ea2b3871271f96141b69cf7aa061dcc0d2b46eb76eb46e71980f9f0d53484a1fe71f77dbc9a09476abec4e3ca089196f10850298cb63502ae7878718503bb50bac7ce8586a7ce6e712e63f225a52cb6e6012da9a3aa43b4c30ad819c30d789abcb9177a902bc9a40c9c079ce4db71c2dc429f3196468a3a7f13570ac5b7e7d63cb1992d602c7822ce274d23c17de3656245b06c6e4733f265ed5f361a9431d276f45f8dfa79953be544377398733a8b3e8f2904452a6b159cc54082a3907786326d1eb864b0bc618e5ba79ea8df84e37a42ca9aaad10ee11249b1a759817247da7351d3c9c7b640560c619f23b30ff08e68b9b18ae2d94053f5e9309478f00a222c973ec9279ab53c7bdc16eecb89f53e3aa9cb38444403ef52d35c69be5a828417190d2fc315e30299b6991193736754659db25f16763ed5e8c37b0c0ceff456c5570a2a578741565b825d17486694306f2b6848069c7f3c19ffae0ae87664bb0bc9c22c23257741b33c5b8186fa8a03125861777e034ddb2e8b2424f73cc9725b118dcfb0065ab64f47061b7d7f45323b8d55aaf60e193cce5c104249b33513480b0f65bb87803a4131f839917c738295de37cfa3b1548e584f4198c055ecf23b2c837321d9c861d1ec439d0a0b9b85d8a268251248f1c329dccbc1c2f0272abc01f145e784d1ac05c1461688a5e2ca8a14ae494fbd187f847c62446fa52a20c97be9415c4beaa69a7b8d17f145fceb25db941fa401173bf618cfa47366b00249b193202eab9f1e80339d2159859333634f1c1a667265a6653b75356c8cb6f4400a6b884e60ec1dafb7aaa79f09320b3053e8d3559b0d68e7cc4d785febb8c0cf02eb979aac9e07f12566fcc2a9cc8423c1bb77f95c4af60bb1fe945222d1207a64a44c07bf8561c7122faf80dc0c12d1dcd9d99beb7b2cf80dce237424df2f13e63f1671430d224003877c21cc7b4e25e5501c36fa1d11056b5b866a958f3b9e20b43f03d5047c11547958962f6e96447e5d1308d720fa774ff67314f8cf7c973667e5c673fa08f6960d3f243d74f777ad2036253e2d492ade5322851df4407180a00189368b1b858417c7207a728befefdae6bed13226e41506232d28e1bfceeefa4949b4dadb720cc85424259ad5e858d8f267c43c23c660fdfe4566745b6addb15be8c03240ccf353dcf0fabf7b7947200e9a52dd02fec5a454a152f00b10e24aa89810ea6707ee057d41c883a5893dc933a704e1134cfdb2768f3131234582a2a0975357c0e1a5c058a6114e0ae5b06ae7c1267ec5da3da86ff8ac861ccc7791ae7cd5fba1fea287c2137456a51030fd60f62db750358c84bb708195afb69116ed09ae13f963bccda18a2dbc52403ee6fd48f4f3403619a30305de273ee783dcf033d69b5d2daa58fb56832d3f28ac9d869357489602e0e52dc5804bc5dc684abd43efd682e71759858a0020c05c8b5188538817cba910d721867af7dde666e9a1b6209a54fb5d8c3f4656a96c96ae3830ef2a2c41b8da17e75e60a8745f52bc5934eeff30685508be9ac185c7d9c4979de4b33cfb266993eb579f21eaa0018725473368a422f0272d8f090c677c8099493c16915ab8f45e7f88370afa20bc714c21b6d028e51b34b3607ebbb00005c5d4157a7b1f4908a9487937e2de75b33805eeb6817b144d4c3b9626f313cacff3f7971a439a41df490b29e3ecb84461b3b8fed352aef0880cb1b16cafd3d618d5e63fa4f09e7cab2f5399cdabadaee92e29e144bb0b62416b958cc0ac4dfa72dfcac18c97cbb75069d0f38149f81a7be1a98a713ab792b4eaacdbc7d6ecfd19d6f722386246f1e08d84b97fe53724865afd5408f2248b721480a9663fa88a55418b77df3e1cf26d4f9cc126fbc937992084745797e5a44d326d393dae0e221bb09a19c4aa23cf8a30a8d30b54e4fdf678cb82df834773af527fdeaa13df84fa2308fd1196985623f755911e1e0853ea2d9abd7d469d82a8cb63836592715f5d8520755b9832430a508fb476aca2d9da8c1bb0c30fa3981b39e7834a456e13de0f19d37c91a241125f35a34077f4b328638098294d7303092435529df441595886c160ff2f558b5e0c342b514f32736a6079c11eaec23e986f50ec9ac4d70f91a71c5587758089e17ca857412b5832f899641d6aedf3209cba44b3082a7ed574b3a5dfbf5369ba002554fdcdffc5b1f1507e686fe3d06d6271f780781a386f472400fdd5abbe9ba9747e9322c562b18333406326806f2dd31636407a19246d2f219e56435c7a72bd52d4ce3aef8002f82e000e5ba7694a17744ace5c107913036adfe8237d697354714d5519b848ef6e39b13a9886f333fc674d44ca5f130d57c2798dd83a30c5f3336d995cfeb58a4af7570a735fea9d66e846693ea2c75a102b63a0ae7b953c51cadb05fcabdf84d4520b692a74b840d10b099f327fd283559775c30cdb82fa93f2762f95ab04584ed72f7d829971a3cb955de0a06046020828b9d32d6de7130ba5068031eb9f055ecb91fee8c58eed8e9f9cb88356450c620ae8eda543c53666c267d839389c32b7caf1e9dff661cd3b842b6e8b64af819de752954e643369b669861a0d29bc5d8242a9caa64d9ffe1bea94687fb2169b6d3a82219d95652f8e78f95ac2b41a57b2c9a5512e7322b526640345b9200ee8f54ea0a91278ab849e943ebb390e30b95f1c6ab3f0c3a9eb7df16b3d6d570e1f99c7e10ec65fb2edf08a97cfe6acfdf911ce92127d0eb97d7050100cbc2a853b91281f56da2a38b8ea14f4f9fc3439ede7d2c1dfec4cc9e5320c4ef15aa351b02bdca1831248d2042bff9656cd2dcd4e619fd11a66586a88d9fc3447f437094efaba76577e1eab4e17c4a56860c9f989925b8d6e052f294a2c8e4a0d4bb535b82aaebd60e5f55279a1d314ad4b18d9b10387bc3694eba406d60f2085258c387575991f709dfba278ec8db674d2e9ea12fc2bd0c30d742977bfbee9920c24e452f4d45169ad7996779d2b2a956a3caa932b94452f3894a59da1c15c3bcf77ec6353ca6e3381eb121492cabe9156b8586d8b5582b33bc53b03c8c6821626f0185873fbc58bbdfb31072a9e4f410fe1dd8d542f735eadd3981eaf29d6ac3dd1323010c1b94e258d27c215c088933f81352bac5decdbafeb3abb243100f18c609e140d776682e93b57efc5db13c1df64417fe89c6b7704b08fb51eeaaf66830c823e02938845456ec538a1c0ebf8f91e6fb31596c57c49140c6370d7c153563b69f935d05ac705b60ffac7108d45f33ba436f4beb6f436563d80341fcfc3cac5e266cf8d564b9a1d1c897947115b09968a23d4e30b707d0f195c3060d6b71d4b367bfb7656258a767185f9f7f69d5bd825384d7132cb5b87fbfe28bffae397fe5c4ef46051e00dd07a9b72cd06f573dacc0b426b42981049a287dd7bd0b1d41988cc027699e6ab550e8fcb445759a09890773e4fc8541236f1bdeedcc7932b8944e19235aa3c65956fbcc78ec85c6b0fafc92d61fab74eb0b2d2ddce333f4289e91791a55070cb537a64b55f53cd558af5dcce24ae30b68b73e6429842836f4b35f9eec1f0df48beeb6fdf5ff79508e830683c8007c230a51dcbce0ce2c22291080850ae5a9a1349436b0ee3ecfea689bd1b3c16993fafe59a850a2c034f02a9a71f66873529b74ca318c8834986125f6795bff498e8a91e726fff3ef0aa3ef3b5fd028d23ccbf3e07a125f8537812b694e828edfd95878b0606db73339a4979422b5d64f42a01a68e1b8a16641203f01443b33fbac2a062a9f0b65270cb3e106c84f502b823cbaec2dc26ed0a8b698afb39c685ecea60e51c35794af2092ef085c1df74ccc3cfe188c4466b7a37e0f1d310e1b438e10b2c7eac248594d3a8adf9c1a68796375ce682d452d32f7091dbdad105a5581c8364013d542e0b3a0e528987c3c8d1d8fdb4693f216eb4ffd5db84e4be09f79b95f1d6bf87b529fbeb3d1327ee4560823ff7fa6c4b1202ba1e4e4794ec472e7bac40a610c451814a77b2d950146816617410804133272a09902bdc75aca7378202e100fe28eedcf19d1d13477206a85dec5cb72b95bea22189ce04608a39f02a6b45dfd3e68b8532076d7e7f6a90de6fbb242999b890612b057398dc0271a9d0be9c0ef2c88129d0fdfaecaa383f197bd731ba37ea5738ced3abe820f9e804b1b588368dbed309e1a62c0a5a3c71af07cc2039b7f183fe40351d6d82a0785e085ad31593ef885a53358b990c4cc2c650462a05a3e963a63ff2b5decd164022e07046205611a485f3704ad821078410afa13af1205963767094a23233c585473f1002b79e8c1f22d12f241c48078826c36a492b0438a81c414541668aabc1c3066eb36da4a77bf7234336dddc5402a03bf0fe3503de1faacbbedc358ce719212712d5dae67c294508a4cf7092648e738be41a9c4a48eda2e4f386c187c851255390630029e21a92caad7d54c9cf048138355a38408d1397e6eb4e35e259c95e271b815d682e7f2afe741052d1b70c0876809277e067c62211a0f3a2921b2312e4bcf4f7aa44d0b57ec3e1c8fdad372e13a94aa9366747c52554bf7427f72c586b8191145480a7cbafa2c47862783a41a0fb2ccb1f0036d0e9faf5e5631a35668beab75c36fd5d6e827f05a6a1e5c714f3c493870194d35993218a55790d5af757520d484c97bd9640bd7422bb1d42cb2bbace5c6f5fda69840d95b4d4e097e657fcded22a9d297fd92507d8c0ec7cd9371b704133acd1db8bc6c3e1ab79f15e985a12349ed035bd02ea14fb539fe51233565156a9bd6df98626cedfbc934b9257554472cb75e6b35c986a20b89d41e4039d0f2615345015fd335187337d48d43a2b32094087f2466356aa54b0099104f0a95f92591cae96be5761dacc8c28909ea7b0296ee4dd651d9557177c6fbac2b549f9904303f652d8e808b85051b3078e68c524dcb64f4b61805f697948f24076667af59af26696e0e4cb59581497f9828fe61a48e547c60f782a4fc67e84fc9ac9784d42beb0881345060d544fe5fc3cb0d2846e732b3240caffcc60ea17429cfc9277e6515170afc4b9ac4b4f9c93f81b8e556af197bd5bb16186b690bc9f1cba7d2a683ea5deab15d10ba4d09c66fbea91a03c2242a4e1a0733c2e029695a8fd10b18ae74ef255c72a1a9ee9fd161d3677f3bc4a2ce9afb6233e0b9f9aa8b98325776be92498eebf9b2e4e443bca3af48c4c57ec280a68872e52edc9e76caffbc2d55b7033161617880cebb31241eeac80211643066b0cc04e1724e48dbb60d545db168a55e778f902971ec6de93db1eb56600532ac31f28fe4133ee902d2a88c2947907d036080d4da0d35ec811ea84148a98645f7ff9716672dae14c0c0561d895b5c17f13ca97eb0120987c4c9dc08d0e10bc86194f71e7ff8b5df8b82253d08de99f58bde72b765908d4ba5cf493dc15783cc46e435e4bd14a02de3bb1425861674c903a3e884e8d703294f68ed54e7e3ea95038b2cde679e91d7b25c33007a41acaf75ea2f0dd5f75ff8393fdfde6bbe300d66a95618ee036f975ac47e8c9f4313544e0f3d2a4287b82b1473368304d21d1914f5a92e2a94a3382fb9d29008950c7f70a5106f36c910d7d2acda31404a656d92f8186f27fea35910a43e22fb2377254bef888ad473091d7b51150ac99efba4b1b6c0c7889c86c27c9cead524481344710a20e5beb252cc380479677690bd9d633141a8dcb3b9285304f43d390b62e37018900e3b512871303f60e8d9cd1fb6c054b902417934e01f3660b0cc8886ceeba4d13cd7b6bc7951553ae520068b110bc1cce3711aeb01750c8c1f31de6ac7280320135f0fb5197c40f603a46648e7325d45e3df7e21cfda9d63226d3d5cc2d810556150fcd89d32747e1913d0237eafa57ab7646a15e1d0f7e928f19cdabaf10c089226bf661f41da524553c29379b763949f8585561392d604de93a0194701a7ad4824779aab316b452c3d61245832b28f67b7116d684d5ee495a49b4676028abb3cd18a0d1a44946aa0764ab0d592f2967c8090f4c7b3ea737598e7771a59d6fb5527eede2bbccab8231304b8eece0870966648aae87450c12a457ca021e76a7c0419551e9a6da4b6cb07fa53cebfab1d381b577207849e829fc85b26aef139d3f02ff6a55276b53ff6826125340c15fddf869757b7585e72b217e43af610c81729876da5020a81615e65d4b392e02228d2d498c301d7be3350919efc6283a51ec580136abd7373844676835c2acb575b4de25ea6cbc245bb31f394a93e39cb53c4cb9312431f58c4b12cf24b3e399844f02935c1b5cf0747ef74256084628427e5dacd6a29898b1d746b20bdb7e6cbd32a00d5f02139d3b679195c22f74a63dae4774b4def34752af12978848b33aa92f47632375db472f05732adfbb2ae4520e6246081dc2c79275daee00d32d8bb1176d7ddff20700b2ce913e8df552e4c8610ccaf03bcc734c04bc3888264fddad1985a9cf389d56df72e3335e08b265773dbb273742697d6ca04f3c1e7411aebe8d56b428ef06e3324026ef17147e11dc17f68635cde19596806996c501f4b60b3f6fcdf898db9086ccbcc8e37d87040534d3ce3276956c96184a04f2026327c26ac9b083ad4fa37749affce8c434f65de20c83ef62926750628674c9c2d8d32fc49e3bb0461f0486580582636ca890fa84f202e097926584d4e496a7f3da8f5a34dfa565df0236b5a8aaa117f773d2dc3899d9382e9bf5cf07c429431fc1392ff3460ea28353cf8b53ae210911b72b0f70ae623fcfda213b4d5ec7de833dd1b9c8af60948a422b7a9c1ced2a3151c3a4ecf657f91ecf41bf5a825611c50f691d1ad49444dc6a8496de21b2568062f6dc6f7dc9662eb9d3302d316282b22483012d595be867f40f69feb582b32339b2b97590a509722cee918e409e8daa367d5851d12e23264d3f6d073d81c25bca2c2f94993046b571b3a636ca93cee0db21a27a90836831d103b22f772a06ff5b61e4e074f00c0cfb8fb15f108585960cff591eb750f91365622f60a6788b460b253117e2a5055228272f06c436e470d56ba961789dbd2ace13c127e3ab9e600728ed4acc51c0e04ac2dce67312a7cc8903b5c0eb3da16b12a7f1dc40d53f6242491a940f0990cf035cf4113c12edeaa9533426627fa8207a78af9751f09e4c9c6fd8bb039bff2382a027b890b7ca3dae0ed1755c202088e88e1ce8384a66e6a9a4b46261e0de6f02b91e7e38a373aad6ec7dc9b08cd31b0bca184963eccfdc0f5f321c9a6760b933a73cc00cd59c16ef1b35506899fe830f02f00a2894948c36f934d6a7ce046558d0fc992182c9ef8322cf96d38da0e2cb9561306a7b8c48ac0f55a54d48aca0ef32a8dfbde94b278398bc645e2379dd76ac6981b2a4dcbb994c313d167d6468a27a8aec462031529d543d7be62aac314d036c2dc252b905344a8e278ee4ee181f3097f7edc64d289b148e67b3e3593ba59eb2adb7ed728d464a9cd06de9a410c2d2fc9bf31dd4897ebc9ead42ae4a8d201cbb50d207a7429acfa30347616bca4f497715a2523bbe2f1cc1ec0631885ee1352fd4e5885a511f85674a423598de4df2edc6b9e956f1ed77426b83825d444e461ec128b58d25176648b07f82e6269aade0b346da6781fde324a19c029e543fdc5382f8557046ec60be8e9fce64b36d20f9180f1ffb07bd2878f522628e6fe996ebd7cae35a713813d0b2a6e49b4b0d2fada5f9a6645342ac876b2aca5ea064fd13d9652b007a365370ff13f0bbbe7dd010fd7b294d091ef0de48e30193faf6d0c55e54d3b9adc1310ca826e64261755e4d5034e56a1f0d1aa13fe38c5af61105430fb29a09188e6bd23ab2b66819a5c20155f7d1fa011de8d6240e76808a8888ceac6e5bd67035e9711a26a117d67c5c14762f3f94c1e0ded36adadf680b3a5b28325331c9ffde477699d0f03dfb813176b8c4e7627959d1d877e474a738993f46137ba1a297b2534e75e4f908256ceb87792aff2a1f11ffe99ec0eff0e2aa0e4262715de4b79833d3eaf5226abc5846bd6cf061bfd9583b216cf248abaf1fd6070913a3f707ebb26ab86cb0b130871b2f616e8f5141378eaee594765b8cf649f80af3fab7be17aeeb753aa64ef8ec49cd32fc20dd5d1dd96c27d3cdbb581712da6fce8f987986f0deb441f3ee751339d439cfefff96560b11842f861d5354ef28079106adf7eb8088560e4a6b22074a849a588d5c75042203972e32b2da77bac9585fb23d7db17d42a57bc60b7d08054d953e64554de39a04b9c24d7945ef22d7cad9ddb5856b03aa400feed5aabf09d1bd60d06f089516383c311f7f78ac4c6acdb68c419e039a6150bec2e09046c2e4995f5bce65dd36209c3f4e2cc8054292f9f009e5f2288da554c560d8d024430d22d8b762a16d92cc457243442adf25d219a0fc89b78a293fdefeccc77ebd918629a947aceb601de8258fd35ac83b5fe228a0f328dad21b3e75efaade1081ec3b5a89e615f2489d72261356f43faeb0c0e02484623fae1d293cf55210752c0ddc40265ec0bf90613c142577b0c4e5faac573d715287bd2c21454401ceecb45722f1c144530374ea460de1e6fe0c3c3f2b3c9af1ecae2f2cbc3f5ecc10060a080a26bbeb23e1aed0ddea806df98cfb8fca05e9257e1139cbe7210e427d6af98b5ff0494bd4edffa01ce8d848efc1e34498b8a9e38e8c0d05e87fdecd368ef87d9845d2b0b34706cbd67c2331d22548aa410e88f2a7596d4e2df9d59d165b2bf4fa973386d8a6a7d15144cccc38a436554e0399a74a854e375d2faae9c987d99cb436e7da3ba0bba64821e390098571d8c2fa65af64681e570432bcee2003ca1c0b2d0115e87648948fd30b6ec6edc1c05bceb6d4154fca13da8b4df9208be4c1f33933efb2556f88715ff7facd00044defd8cb25a65c1abbeeb4656146fab35f054ce56ec50f1ba0c512c52aa02e5688c5069e12fd97d802895d459cdfa4c06c71552f75c1fef78f1b2e5911ec819a004ce2ad3c5548b49d52e09e9dba0907351bc4ba62911eff30bd56a95358cd3fa08f3e9201e85069855657eaf5834d5d52544248e08d387d6f75c58d4c02e2c021044fdacbe06eb5750c4fa1d18631af2d6ed49d79098774d4f6ce2a6e44d3d27709e05331b8de89c57a76cc1c0336b35a70cc4ccf58047d204dc7a456bfba0041eaa8e35992ece03f2982f97fd0c5d640d1c550c4f8b8ca071dab771364b32407a967741b9ad744972005361f29fad3d36a36e7b7f476bb8b6a6db48e02beba9fd4b2415b71216ce091ec825515da0251456ca44f4a2cfbc00edd6507a2f44890ddfa91d96c234117f87014388b171ada3bbec39e8109a96cb0a1bbd6c9e2bb6223b64762e0be0961b7e1805e82993ff9dd181f5d13e5ecf52d67a763cea9859603f27b97bc54ce62abdd9d1e18a107147be07c8b53ef2488c208ba23abd504c51ee8796b24ccda856bcdc24cd2a82524bf032d74b502d14588dd3b4ff3b7e1bba334393ed6984406714eb0a67192dbee2ba5783f6b2c20ccc7f4d0f6651059c548f99e65287da537d0a7ef056d5be81031ccc2229290053dd106232a517d40013143ed9c40a191dd8dcacdbcd7a85c0ff0342ec32f8e2f65a8ad45ae53bbe4500cb9ff783cee8bef7060d1c202354082fc8ef0e8fda0b09f29144210ab08386d30d85872c603442a19fcea13d58b25af1abc43e1440c2c1671eaee9c9b8fdfcfe78e896a0d3a08917826db2d815eaf9751caee6230466f25fe00ec3f7aa2ea033698f68b830e702c170068b51c3b80270ed68831eafe352a5bc4d5f0608808bf2300d4517f620976234e846852c629bf5c1f0e836280f836d336e0e674de2d8e953ca58ec744fa4ce0f6166a6519d8881c37d3ad4babda1f1f06dc81746a0ba281d85ff7815c1d35d417fc7a2997f8120d1df0ef67dd5ad22ad6668aec5ad5a2d240254a74faf79d9f90ddec61d0f426bb1828868af387edf13a3e87e0409092e6564f80370591b80a078a2479aa6024a7223417141dfe94ac6b0ba87632773762db9676db70b390f0a2df2f63501c39195c3ac463f1aaeb0e3c05111217505fe3d4077b33904d06fdf348aabef16d160fe25bec9db8b6501ae4cd50fc9d038904b932fba76e68eac89a9e675226da5bf35e16426a86ba2398cdb5df39730c6697d5b0062cc12f256bd78e83b295be22181ec09280621f256113204f8e34c49acb713f850b5649eeb55d9580aca660db1ce28743ca196f7b26afc5b7b6b6a67ed140e4713c37b3197010166d05a53d27f5ad16b86491753d3e2f391a48359c400a1fb9a7403735323392e539aaca2e5cebb545a5a32017433245e5de1248a1d6955e09edd3114a9a459482f356280aa2bb98fae329aa57f85ab969fc55c11798291d3cf59b994dc555557b5795c9b32ca1b9442d99c19210aeec001daa39d94893d6a1e29a831f34a613c8da73600255999931d4c7390e64ad457f9b602e980400572e39cd1b88e5c9f052fd930db7b13e5016718384b370cf7edd755ea75a73c736436a19d03215fca359f663c7af0f16818115b9033cecb7072ea4560f21de6d44a0ec1abd6d9f3af81404a78d6bb666b5912105d921fc65febcc9f272db2d30002b616d477eb18e714866b6e41890aee1f3b4061dfe4b3d23905a67a98a882833acf6261ae426d0b4344795e1748248bc3e89ad48af708e13caba08cdee3d3b94dbdface923b309005973861868e7c9295c34521e0906ad854e2a1419a4e5b10278da3345fe65ee728c81a61dd348e2e3604680285d2402085b52009a98e1d4e61f75e17eef53aaf407bff9bed5b07b891a7030d7eec01a3c3289d749a6adec6f78b930b702fbd3a8bb0c081cb2e11cefa88c0c0c3e7bf036aaa59cfe626990dfd3e85ecff37a0786e25060b91933a266451ca90d03c73b174c7f00641e2999a7034344cee08fa7d44043dc7db3676a00a5dd586c4e6fddaaef302db3694e511aaf3302ab443525587ead793bf474c7d3b6e4a3192351e83275319fa6cd042f962cf82aadfded240c0aa2dd9da2a41d60c8ae75441575a7d1e638a797aa512c20ec2acd380c3e77d321660ef8eacfa32a4514a28fb601e8f87f357eb7d82cd167c45c4969a3af2a0b6055d046d866c5d9ad8920eb90e64d7a2d4734713c0915f12444d9782e768aadebabe43373fc139fbd605c4dcc64ed934c2e1130b2ee25bba24fcdb1d1f5559a55543bec4c60fa68ca079ddc53e9dd7e4f447052dcefc61ac20f8c0da7de6dffd62328740522d9e5e7e8cfb119f86009c0a0c72dec3a757ca64c64495d9d16a1550a3d74bfac7aab8221bfb6163d45b0a53009fba81f259d09fcff4a9ee3f30b4303afd87a23789bf1a63ecaae08578d09190ba5f68de5efe8c920a922c40373c139ad601506b2f4bc60e2129b78826b17ac5d954de1ac14f899a603bcfa2ca18742b3d84a66e23da145b4a3c42ff5c773a62226c8d6a8caeb50a208908222b2f601ef3c37599a48fd505bab6b90436c5cb2189641dc542603de80c1bee938e68a0c28b48e6857c5daa05ce25c4c84b589b3137b280c1df8adb5f4417a497947f05217dc888f684f6873793d12caf19dbed38cc967e408b900d239694a982ec62b7abccaefeed39feeab13aff90550e70e6e5b97c2f664e8b09d49df95b3729ac67ae5086f03261c99ce9893e7b7c1972822bb50a06395a4319405ec18a632b53ba958dc67ede821bb0ab7d7b36afc78a9722eb3cf92ce6619701f55333e845b22969d4a896b8fc739ff61ab78b66242f3041400e8045eabfbc66ef5c4082b2c0990b31073c1332480aad092714d30d082c5ca6a74b9128c413c873726cd010ca3ad4dccd442fb8551afc2fae2ddb82a5622677245814dd6c37342af69c895da809f94c4db3ebe4232ee2198ff218b17b8fb9cfb36747aafddcc32a02d91ce5baac5fec92107d7f2a891baa738867a0987a92f8c2407c8f54d74a05e5310a2da05643be465f374e90f8324638d86e7aad04f8e78e58532eb0b1baa849183849482f33c2660a9de2f5e50b245b417ba2ea706a8ce83c55543fecfaa8816301d98f187670088c9d9566cacc2941a490b470867085ee2161786d1177d07f673e2c0a8651d868a4ba2b976e0f2f8dd06f2281c2291b6a92844ac498f929687965d36d896adb294ce9c643d0435c05979d56d159ada4a441f6101b69b8bdbc114102f63bac7ab7ae99d62f3237d4fc4fefa46e8e44b0f64c847cde1ccd209f135b8c391c4a441bd2c2813888f62b903e46e6d6ea1f835818cbef94196323d420f5a89ba871b54982115415735db870d14297cf51d844e6c059e8fe85d6edeb533217611da6b19487b3aa91d41a006447654a4eac0a0f286982eaa3f11d1ef4c4309ab532bdd7202a4fe76543a2c481d450055fceb279621e445a4324b4a30cb73bdc817d6e160dcd84ce914226b992d106e291267e4824eee77c0a9d465bcc8caddcacc50b1b2642c8448e5a8a0f826ee8300e2e0890ba7c84500c22a0380a81c759852983bc24683ab87be4814ef38e2ed55a3e00400c3b505dd96238d178af20e18b40a622bf6974d7a3a95c01157dff989f8d2e2c9e75312064cbb8963ef7f34ecc400730d482c3e4a9aea1ba95ac8dfd0a264c43694b03542e04e9034f85736c5a14a6741115453c244c33d87d9829f102fd9f2db3546e166b3fdb1ac0d4e7f49e0e7cdc3e97e9b0a9d2b968ebc04edb20bfba1da7b56e33d8a51345864119e91be84653069dd51201cf312abf895271e2a37311dfb3a9d16df93f669992c6dc4b208a62254e84a5b65377632bf89ff7083db0ff0c332e9064eaa61b39512645774d0e229333b48aa845b4f4eb8f93b8e69b360db8639100db2b50ea1d4b0c76b8b33c4b620cb528162665dbb716581c7759d6c9d2cd8d631b594a474a9e21bc65c048c9f6716cd4b9aaae4472329f49a7b9bf8c5b7dabb606cf6e47930f0df472f604a2a62e03118d07ddc31746b9aed06d79387de62e286343f00bb5fd56bb02373d25c62eb8b9cd082689b50bcd40aae1b9782406b789695b073c271d4ee38b94de5c7d178b8ffeff91d46eea483089603f37804bf83962e656543c2324689a71d63423f88fc2dca29e319045b90c6050f19b74da2b9845723bbf2924208d8b65874a13aab6805db757a398497e9a31ce5f011d3076e49c6a271ae7dd147418b061602753ca51e6a2f7f4e366c2ff4b992719d174bf3c21dc1b286800a6724b51b1097d1912d3ca829da55ea9850e2fc19aab11bd571fb743fed9285790b98402741110da9e3899321f0647c243d5cc2c7605286a4475108446b0d46c2aa985409b083117aaec0fad22d080401735358cd4554decc2d09f7640b8ca7a719db6b129f72d298b6381d24f5ec83e4e9e861300fb2d6c00f34fd4d78b619383106c3aa5093274bebdfc230b8255bf44c49c6952e1414594f66af4361cf24e1734a3e36553297e296496af7d8db57c5af27243b959d51f20c7eb4654a0ea2593852adb900b5c90c17d03aa8bd8e6b9954ed47653882157d694853eea42c8cf59535e1a81f7c0567c45441d5a9b4fdd7bcc2ffee32106a88bf1921d66970313ee34652c7b2db0c41fdeae14d3c0b93832d497bb572bc004cbccbbbe704d10f2c7018fbc2aa4b7ff151e6eebd78d87c010c88c11c2e799e9273ecebcd3b2b4d7eb3be350bc15a8ee8d648cc49115a99c775ad63349caca8e261316b716a94b99dcc9b00a72dcb9cd8448e470cf5d90e9c5a6883390eaa4bdd84baa353b949145c98e6ec8b979ae700ebb7c70b0a2f9a86cd3d94bc6188fe4719afcd7394afae850b8b8a57c1ed6ae883a520084b317667408b69296bf68a92c51e0b00910f11c1a066361ab7cc40d01d83cdcfbad8efa6400c7b2b7df9cb84b6049808a74d860d18fa8f347274977067aac57790114c6ab32bc74e8039b06ef158cc5ab529e8b57b9147575f9885846d0b365ebd0e54b3d60171f0bfe7ffc2445f5c610b8d00cbce00e62b43e14dc55d2a32d63f795746c0d9c84a09d19b0720b6522e490447cb42b4619c3fc12d125e0484836180364b16ef6dea3403c74d9f92d93028102134dbfecc0f17c46a4d6317c5cfa69ff395aa84bef9d4ca8e4a81fe5b9e387e8663083d098f69e666294620842b804e0b10d7e5f0fdb2c30e7b19c5d7ce9b0bd54f5f5c4ef25fd8e83d22dd6201cf5008a0957ef1610e8868eff4b34382ffd76a5ad167718a0970451fba13a108728a21e040e8ddb9159e2a4d66990f6de00e9f4a49da729bc994f32fd21ad4379c602b13edc5ece29cd88c161fb53e7b5bf221fbfd1544b408cdfb9b69738c0f444c38af947f04eef7224ae440e85ce81132ed20fd6a08b7e7c7a22d5d731145bc1af3cba061f15d7ae04e76aa435bbf6d5a20cd051450cb00d054926f86e832992c800f82a449879454bf11d111e40907e146d6827956a0d0b635c054e844b43b8b8155af0a47b7c1b92f9c177f588afa6a15e7f2c318bea4268bbc11af70604ec9be9f6165d827ad68d513cfdeb919beebfa6f2b92d8692d4abd2c7e1c109e6c2513504cbbb6cadb2dd4f45504b77f8fa26581d6a7f5d18250f8289d705dc1d8bc2d46c8c8b56a3b6ec5ba60bfe37b8cfdab5e744706f4fadc4814ebcca050dce2a784d8fcc6c994d4854f977394212aaa46f915d9825b331f921ec956e6e5a679d0b0e4a4a8e3b80ba385d93016fcb835f415f4ae21fa8685c8df21ccd8c4ad0d20dc4cebad442240f415d6839c597d10f8117d059e0533017288bd86258f90a03710924b1558970333af678dce4bf782cddc68e6c849612a8cf84d7ee199579676266a383fa729b69c1bb3fcc99e42506f55293193accfea1ca602199655b13b20cea5849144a48da0d2bb7bee180f0043134c7496603a65a4863ee49c0d77b724096229b309eb6101274202e2accda05f0c0c3b034b533330c6ce3b3149bec663e2ff0ae78e2264739ed3f79bd4c06cfc0f54cd25f655cc5b857b92be8cc846f037fc398a656843de93789529a672d354ef5053ca722c71a628119cdbc89539adbc011256f4ef4013751bf94622331b18755b188e32079e0059158dbf2fca29fa918ef5096a93e27ea1f9e7b9586fb0db0e4ce103fa71927c5a30523a4a1b557ba611d5181049f87b5d3578efeb15ed62555c45c95e739dc48d5d89b1a19346eee9649720ce20be71ddf7cecec471e3790bac553678cbb848f0a2321d57063ac65bad11fd0fea13d44d12222989482291bd690760084e07b0073203ca3f72503621eac4f840c0f5af379d7e867b4ecfa8437fe6d613874d1a6b4a8fcc7d55fa56383125ac63d7755dd5d0dbaf32f63663d6630880bbbaf247949a2e65159675adb56fb19bdc7f89497bcdbe0848763d92f65fe7eeb57addae6bd332eb177fd8d192f0b2d30b76e207f8e362e211f4b1711fe311d1043bc62b95abdcd33c8d5ee2499df89c0d2c184a1d4b7b9e3427b566fea491a86661463b9256423ac16234e0e803a683e455310fd8ea0f9fa828ca96ef590587e2cfeaa3ac2af0a5a2c71b04499ae9ef859d197961cbaf681bb1b634e92f866dfa6d03024aa53e6f67db7fbfb36ddb7e1b4a42b76cda4c992933fdd7ed4c675baddb5002bcaa3c0b226902acb7d62f86bdb5d6643299be6867d96fdbdffc75fb9a724f19f8b587d956b4b79c846e0dfb2cdffc25d998cdd56399fe35bf7e90846e5d61e79c55aa6acecf3dbab027dc39d20eb955b9cf97347b8e30aebbb95ba77c2eb54a1527f6c42e480487e4c79f28a0860c410d77ce96b342183d9797c72eacdcf4da2aab8fd10cb3f7fbea150e81e14f5da137037d78402f7e0761849ed72a6bf4aa2a75304429c03ef62d60df02b744ca92eb97d4c72e0da50e108c5eaa8a1504160a61bb7d485eeae89fba62c04203e0eda6674c8c7388e34044fa56ab351d0825c4e8b3aa755befd65b5e1c41ce96357abfb3054bfd59f875cb4737d473c884518694f51656cbb2f4071f47f4e1d5e73edcc1e8b6657dc51b96bb68647d9dd6b2acafea4c22ddc15495e538ea43fdc1b774a53f77aaa30a28a594d2ea734faf023a84d0e974a702858218ba6c8f12dfa330c07a9475fa8c925616ad547644e05aa5cec49565d518e3ccb9d785510cc32686490cc3302c6298631886c11a42955583449905b99910d72a8d6adad4344d46d7340de20bc3988d0eaf0b5bb7d6420cb3f6664259a669dbb64d6bc7971046cf9ac3abf9b6c19979c41056964bd5d0b48728c8cf77fc32b05d6f189b4c27df3dddcc8c27b42324ee1cc8d309e108899b833cf06b788c31c618b5bbfc19a7749f4b61be54b992f4c481982fb0d003949a77ce2b39135ed9baeb6c6c6c6c6ca2436d03521fbb00906a3acddc1e39a7ac8935355e032fed83e1749a99e1381a9a1a35f0c6aa689de130e73457484d07d40175b1734a4353a3464d4dd779363637372854aa67e762685574deb821a35f35375046ef6cf00dbe12dab0216dd88836bcda6442379910148ee3407983729c6843dec09104ae40638ef9835be24ef5ecd41c570e1682bd317f292171dbab23f3349d6d07e6c163c29b96f15c1e8b5d3c3cd5e27158a37d45fb5e871107077338703e5b08b5ce9183f32204f403c210421041870ecfe33a211d6ec70e1e3bdbcece8eb6b3b3b3b363632313ba2184c3a3f615ddb89109898f234772dfc91ca1fc5c177de7e0703964f41c392aed33a7391c73721cd29cf5a633a11c5cce0de17a16e48a0075441dae83e66428cc9d5474284f803d4f4767c70e1e3b3f42266421beaa954a553435654c792a958226ed2bd2e1e9e87411da910989bb0708f2b83c78ec509e29a3f3c0aa7d4b3c2f13e256277ed43a3b78ecf08c20a343c8b343661d3dc6e831422b7ff59bd0dda7363f222866f3d8b163270bc22313a23c3221d72828f8bb0e631129401581e107459e11a4ec4164fbc748d4790a0001c884049009c11eefa9da5734c2087284e8b0070a85d4beb1a3fe260081262c8c6e44c6996c77aa69a414d248e98c926a0de91473ce49941373a0110906d260a7f657043f3772a31d03f6f73d938804c03be0f8dfc78813638c313a86151cb2ed1923b7a5ac01f5e855abf5b562dc75305715dd441ec444d8092184dc7dea5cdcaa28a5d4a97b2c62d239e5c3af43f2ab6ac99773da9b1e2f289d93cea9ef3c83fec420c5bf0ef94f2d44df7277cb5d4f49abdc3306ab307f5214a8be728931a4958ba4f690fc1bebc72b095b0f777c5a7754e2db7591d4aef4d07c9737d88ffe0d135809dd951ea25aeaa1f83ec3d2972caa940942861bb24c1720e1e1080e2e3e40022f5d0081cb126362161d30e388279acc3082262418244a62e0a5035998a84103369c71045a31a241135f9e30592209337e904598264884e942c90c2906121b4c0cd185164590994195320a10850c252652c2fcd0c5bc922305195e6c20081f34d1032ae6480f61c0600b285ad0031371cb912d3e948004484835f8820c19908104298d1ea028230c2c494954073598628a256a80d2039931908821a3054300010aa32f35d030530922c8a032c4132c64446024c34042811684e940131fc22c9d012684230f0021cb18198ac082e6e0c8ac02c9092ef0618b3159a0e10130a81847ca78312687107421811552fcc0831eca50d9e28b333e3066098914400105151a7ca1e18b1c03893efa000f9618d3449829611cb1028e61860e70b86203165ba8902408c3064e0091a481249070010e8a8408c1126472c032441857c0e8c10f860801164258018510f308119668a207625809410c6e9853e091a9a50b078a30438a1f68918418f40bdc12850cb4b84203661c81c313934a1a5794a0063878f24412497c8104822993c609c68ce0cb1667502fb48031c313204ce0050751ba4092c2165d6cd081862852ac50a5235420819409242d30b1850a25c48069a265a6801a01c41622e822461844d01b1c992f80687c6982e54910aabc400772043f88c00654b4c00a0e5ba2e002890c63c268228827be58c2872d907c51c20834c290c18a3368a05e60900ca2f040822bccc0e1055a403252762042074fdca0c50cb309241698e2041fd042891b82b0c2060f38e38805629630a3075e680d669214e3e3012caa4841175e84d1046a11812aaca46183204ee00507ba1c296201106980b105193a5cc981d200491454ac30da010f1ae08013740631d00004305ca0000733a2805e661648341bcc20450b30a688810697b802314a3ce921cc0d42d02d47240f31474c3027619eecf81188f8e323c6075a01e365c7773137a72c29fa7895e84379b0e3fb951c36ddc1beb82cd378043525c09f2bf952f46ef08071fc3ff635f237778d370229c6ecbbebe6ed7e6642366f6176f3a7fca5f6e96f7296bf157676cadd679928b5b38f9910f69f27d5f8a4d3d1c912f87327950cb8c6bf67416abec607c90aa3973d8ef74eff383e6234faab1be37e467f7e0c247f6ee898e1682875362db5335dbddf6c31a569ab54e9d93769ff883ab08a8d118b91d43f5ec7bf7127db7abfb9827dc79bea3f586503f9d20fff127d28fd1ca3edc41dc7cc97c2c09f4cf912944792ab9faa554b4a86061a68f0bfe63412e44646bea05de92fc85a7de7db9e31188707f8835a64f6e3ba6ac5b8ebfe33b8af8d999023f1439628367d0c6a195221f14396a44d6b75749d4201eae931e14dcb2e10166310474675fb58f153138cdb6b6fb529b0efeddefb4375fb6aefb5d785b3bd32cc6a1b5c98fe946127d3fd7ab7ec3bc3aa1635acfd479fa86947f7de7befbc990d2e2c135a68616484e52f67635fa3cf497f7557bc4df0f49346e3199a65cf68d9333371e6bf222af42b38a33fece929fb36e5df387f38f6fd4dcb593ee2a9093108adb5461b5fa6ea4e297dabb2acaa48ce105007faa81fdfc6c6042f6c19718e990026ed6cdbf3e3c76967d3b2aba4b28ab01859b08108b344f73697aac9356832cc33d955057d4929a592beeb9ee8590f923a99f0965d8b51ea4facfcf564dde34fa24f7d8933b5397fecd9137f8252330aa5d78362a27814291d8a01dad388cbf9fe010155203cf9032552f4a9a46c229bc826724acf8532f341d18b3ef2639229e22cd0d81f8dae2a897434f6855536d4017fd5dbc7feabd087c7587f75d39aceb47fb00aa55a89dcf46da5844aecf38954cece0edeb4eca6a20d49db6e94e6bb1b98053f2adf649bef724d9e791aeeb5c76ff115b072fac32793ddeae55996657fbb1aefbad310d6e81aba66dbe38f3f61968d31bc7dbf313621faf8e3a4fdf2a7fef7fb7b47bad8b24a4846f5dd49f4e2e32ff873244792187c17945c3fd951cc4cbc5d2cccb9aeeba29452eb9a3e57a67f5dd7755d9665ed58182db263557fe5b96bbe95b66103feeac4138a65f1a665106e1d1d1cdda6bf0eebecf8f6b2177677f6ad738b9d1ccfc39b96edd8186d88db9b18d9d37f75c67f382fc1f4f4b993def8b7b75b166d599f3fddb608ecb2bfa2287b28fb216b6b96bdbdaeebd22eec56edf433f1badfeb2f7bfb417263d7ea0f76b96e3fbcdf4bf06d6b6233b7aca75996595d62972e996bf9da7a5d6da30b2875826203287655a16f3f888691b5828454a7acb08e38dbb9ed9d9bde5d7f443b1bff7d7b73c5827d63ec462f76545bfbd6d3fc153931e9aa318d556ce6b4693965d921eb33df9b56e464574af5e6dc78fde7f4f70259a0ce71883afe34436aed3b86d94c04bb14814a50c9a1d276a0ee081503fcb90f108d1d7d9cd817e4cf49fe489de851fa0d903f3fe857ab8ad3afc3315be2aad6f710faf5c3080c922a92dadf0ad8dbafd25fead2f067ef5bce74fe746cacba2e4d94b3aba34d8ba436d54377a691fd4d5dde4e4eb5d65afb35887dec83e2951fab3999f6d95c4e4311100c981e860c98be060762d24b1c88e9fd6bc41bccde94ddca4bdb2d7fddf79f8e1dbf7e50bc377b98ddec7abfd7fb755defba48ce1eb2bad3385a89dc4355d71b3d9ca26558014365432b631ced6e432b6178b095c43d4497ecfa18e68e25895b49c5f2f5156696c6dfc470ccc61ec3bece8de9fa7e6928a7d4fa44a20fce1ce74ddbb7b6be045e637c35a6ab43d7f9f0671ff5634d4718c40509680fa5cecf20cb940122e5f31fe265caec21a222ae89fca1c0102475744aeac82aedf7dc00266d7a85942c530648a6c542f7a3eba856bde97b0f8aa345c5b3735b6b71b6cdc9d976d3b2ebcd222cfa0e8a78d82da59f43297efa3350fe70dc9f3ecb50d9cf3c0472d24b5099462960db6666def4309cf457f73dfdf60d98d1a687d9111666fea497c02a75502b68da3b10fca8161c087e07f2612d053564c8fed5307a1d04a2d5e8ddaff9734ef4b0d4a9aaf937ce237eecf40001459d1f55918df10808298c5fa94fe833dfbfca775da55f5c8ae042c49e1f87442e457079b267915b5d8e31613552814dbfd60af557814df557813d047fd2eb3fa81dd312de2118e052041727732b997beaa8efe5520a5ba38f125a2bfdfdf6b1d0a36f037d6af4a27dfa1df4713d7d6bb3fc18f6f13be8436eecafdc411e0c67571fa1577dfc0cea602c75aabf740779aaf9357fdcd657578da315ee64dbcddbf53fe2d88ef9176dd75f7d0a03ecfb8ab8225225e697ce96f988efcf8fe60f196387434d9dcda638e83bfc0972273b48fed4a50fe370ff00d4891f97e24ffd751b092edd80392a9f1f595d58e8357f3dbbdebb2fb72fcebe39fbeeecfbd04b80dee36a9b4d99c6efd94353c61868918d3108ea55911d2058d29e32fbaa7ddc5cfb8b3dcdfe16524a7736f6f52bac6aec87b2afb6b705c06f59c11e33219f655b5dcf8454ffed6c0f8abe594b29a5d4dddd35f6d907492dfba699fe7636fdc135fee0bfd4c24cc80ef601d285ca9a73caf8517a9c310a71c2aededddd7166c09f57e9cf4a0404747a82458716649f69ee37cbde5ffe9c2a9abfd4dea6eb6ffbfb35b9060dd6327ab5ab65d909706b7a9e4cb46e5a6541e4cf24d5964f935465ca94a95ba45160d93ef6f7d29b7d633e5950fd97fa56d8b362d8c2ae6a55f267554d19b140daf32bfbf153a832feb9422985a8953f98a4e5e200891fb69450e290b976717dd79f7cfa36cbd7d72cf74df6dadb2b13d22eedf2781dd92ef616dbaedd58f6f5c8d5b2b77f3d561fbb6c9642d1ce78e2ae1f5f72ee9c007ec88203cd2ba41894b6f555cf18eceed42184103e9c4257fe9ec89db8932ddd0996f9d39a724a6e4ba93f4b3ef6d8755ddcf5f2edcc84a4f4cafa2a3e5137777443767029824b94524cd70594caf17672e4ad79a6653ae5ae6fe5c5393b2998049403276e3bef964d6ffaed31beb2148ab6696b307ad7d34a7bc8331fee9f3fafbd30fa571577974f63956d0352749154b1d839abdcaeb1733bcb72db78b1b86fb2bfd7da6bb32cfbbe70df6cafefb7d033a1cb923f6fb8bb7c1a7386e05029e38b0a0afd59299d4bd38bd8bcdc9f385d010da3870202fee6290575fc973adc45cb6e129654df924f89e694ef50cca5c3132cf214e914f1e33b3440922d9fce4dbf4ef74ca88a2f33d1dd3152ea35fac49f918a20ec0ef4240584b7c3e3e04c20993157aa16dc450a47f33635ffe10db91f1f38ffbd0f8eff727c6efce7f9d8f0f15f6a93f01fd01f798f12508ff2d13dd41f4dbe79541ec0771967d764283e5fc3fee4018c1166cb975c0daacb10cbb6e1aedb6578c5e608cc4a972115b562dc75ff51ee141809fcd5db6558a52607e049c841de4716f2353200fe270b3d4e4efd08f9c6f7641c2f808cfa2e432936978f709fa4ee1e6f6fe4111e47ee795416001553173813a2b12e244319244779030000a1548690077a3d2cea863702576f97e10b6480058d11f8abf8d264eebb0ca3e09ee66d6cb8e7381bee761926e54cc1dfecb20178e872016cba7499009c179adbe51fdb5e81bfd9e5126ac5b8ebbedf9e974a755efc6420df651fbb264339c0d3fc7c8d03bc09f9e7ed4f36e10f90a3bc0700d2d5f0b0cb24d828e3f4f183628c31c6184f32292949fb1a244934c4f8f8a2143d2f38d9bb401e2d5227cb95ec4e64a70279b4d871e6e3cc7f914b0277f9a72607d4edb20f764597078071d1e59eec5f5023f3fc4fde8f93771e95773c8eacf35d16c0b6c947509fa46e1e6f3d5e2e43086b32843b43b8c3c3eab143271f8190c7480c465be7adbc34b9a6e66dd4bc083535b3cb01202133f1307100f149f857c2dfec3200382df876394526ea24e16feadbe51e9c14396e974718d3651e202575e37cd0c3e8e1b88142039b508f7a9ae7dea9a03ebebd910971a8f7501c0ad3649bdce51d9312feaa08b7cb3c1e6254f6c9f931972eefb071464dd6f135b2f73f39e8bbacb3ad4d969b8b3128bba703d3641b32b5cbdeded2c58bd29718268e893a34206335c1dfdc71bbac236b419745e87208d6043cb7cb395b086a72085f23e7fc4f2ec0e3e41c7f23e74765111e47d60f9409f05dceb1b90cc5000678287f88483fc238e9e8e82893f025641f06c84c7ebe8607f2a3a5c02772f44bd857a91c513942bdcd8b40f3dc5b2f13b2d129146d08211a9506f60821e7e402641873e89c6d641f99840ca30e01725cea94701712f28ff7914b781bf9df06d5657d9552b7cbb9ea80bf0a80dbe5d7b2a58b8f4c4206ca2ec665b07bc40f923f36cca872254bd4898f83237b97e879c9aed4651c1b33a2cb37503de8b95db6b19fcb507c7c7e7072cf002e0e6a7b54ced91598f3b95d46d964a75293bd4af42a19e06f76f96673198acfd7644fca5e253b8d8fa692e2fec6e6f43701f93354e213aff245208e4c2327b3e35f2f351379141fcb1f66d4a926f2285be2e003d296a7a29ea8821166694ce1a5ac17766528d80f134e889ec49e524a31aa6d76c01fc678d04257b042ca0b51ca082c44ba1c5ea864a4e3f0822c2ebc07c2d09903936de32f5982e1143938b1bfbba39414fa70337607b168f8ef5f1915c4fef5715f9f659402f0df4761ba05540bdbbfb5305b80c6850cae040474420a2c044d89492bafcca4262fa015b000da3ffe05f9037f85e853450cfa1416b629d1c7faf8275c81572ad00f79cd8b5ed575bd705d4a1ba752de77152e2d0002712a4878bbf4bd9db0c5f8180f49f71ee194c14058941fa720825dd522123dba2fe56cc72943e528c658f557d5917429ef9d4424104fa6e094c147181416bacf0b6b8555b6a29765458b69d9a11069d179a5624aa6a495722c4e2eb6edb2b0edb3b7d9b6592793c5f055ad4bd334ad5a18ce9f3fc9b4ecca6a666536bb19ceb62ccbb2ccd2d6c3fa4b6dfe24ea443762c7d732a49457bbced2d5aa1615d2487fbe67fec6dbf64b6dfb0169f64d883f2e7cd5277bfb37b20d1c8ee66d7297617d5b6766ac9a1a341cde5c309994f0df87d643ed743a65990e7aabeb8e968e8e96e2d1921b19c9997884d5ac565c6b05dab5d628d68575524a5f51ae2cde188f8ee2516675448a4947b5bad157603086611886bab1e930a3a5a4384d3e20a57af294d5ac2e549fbfddc88d6a8862845305555512f6769c28874a49a717c9d94352d7eb2e830d4af287685403e6a287f990b2f43fbc292a7fc6915ffefcd31e3b7a07218ebf6f3f3b8e6cca1e7573e2a287bab9c16167ef4a5fc6ec48b323102612c986a92a33cd859d6938af945856e997bc6a8555b6cd43f2e7e7568c16b6ac9a1f7af531a62f3d87c86da94091c4c0202c9fbe3771a320729bc0ba419c49b5a6c41f0752ab13d1a3bec5b7446f8a11d047dc4044ef6807ccd5ffb0172f4b4a5e941cc90b4e5735aa732324952b55934ac2a95143662643af8c3f85d4a0017620f3514ea267e56ac99c713a207a2c78730758e6d0e03ed4d0e2f5442fce1d60a951190b90e7caf6db4490092bd4f0823fa8e4829c3ef4ff5fce6a42f4cac0df4bcf8464cc9965e01863ec2612d6d34bb8fe8b615bab3fab8a12bc8f5c9f046fe83dbef70b277afed8855595aed14b5082f711ff24d84bf0aff9bd878c1173c1f2adafe40c5275c35bd66412d630849694f2f3f0756537d72a3a05014e10f0e747f15f70ab7a3742637f750355f94a4a5dba402db54a596b4de29bbe53aa5128e8214b13d144d1f34ff544cfdf03d890f9c5b0e5c3f0dd0f03177861cbff70f67cf9f2cadff5f5ad4f6eebb3b6f51f8e6519b176d543d6e70f495165af28f0bd37a386dcecefc38dfd25effd7bfd7529662de6ee1935c4fffa4b0f5dae3fd410b92f6d7da67fd56b7d51b9ed3f5fc2e8535541719b3b16e176d17477f23bc659ab1860df9dd481690499b3aa26c8137fa681e15bb9304cd74b88dcf5bfd63a2bc9559dc6950a70bc4c948e3ccf842b4c9ec0401bfb947b54b06f1b23d0864040de8ed6dfff07bb482995e613f80baf9eb63f99b2c72eec8d0a78e5aa441e992d5fd62c5a556cd2c2209b69ff75d8572630aa7ed1ae4bb0ab2a1c24ed6f2b2f1d117affabfaea11df56ad2c9d84eeaad2a82173573f77a551d517ed4a9aa8c636f08728eac80f6242068e91df754bd004a5c90ae2334e8d023ff6d2eaa21731fb1447c88d5e9cd782f46de5740aa13f67177db069adfe7ca3866c77ecad22387b08c782546afa714e3b5fc87ca1ca55747ab155f96bfcd7c33b495984bac936b9abc10eb05d7f5516d837edb1e7d7d05f0f0e68467fdda95613ceaec5a84bd9337f3ec6b5fde7799ef6f171601830b6d01e422bb6a6e1145ad52c4dd31e4aed09007f807e401ffe9aa601c91f1f03ea646000fde748408e84bbee3d0f2905b4c3401e1b4db0fc48136d0c7270c54a1949fb53fa7120622cd5d002fff5d6d78f5fef95b1871b7ec4aca1f9f3ba3c436168be1cf26c5af353520790528efef75fb73b1b9a69b4faad0aecbbb24c58cbaec5ae8a54c99f52dbb6ec2d8b94dbb66d407b4b6d58fef89498923f15f0b2457eb0e2aed3df7b29280668cb16ec5db4681460ff20e9ef4a385e680cf9c79f6f59b7aa1c8582fc0f921615e3c4b6d9d08a182d56651109817b88481691f38a9842d42e54a99e05384c7221b53dd79e9f702935addf58ef4f5d000442c48958fda0777d1b46ee6e79162fc1dd5d471b46d4a9ae286d1245208417e12cf01e368cac1feac3a969fa23c2b099da1ff6433a1b811afb548a2815c4faaaf5148498fe52d0339dec9fb2b7699e55d70ad999a960952953a68b3a7115020ba10f9a65fb4b27b6bf10b7f24892fa4aac4f808c53d704500d210fa5b9fa2b53c15f3e66c4dad588b52f25c3cb7677f9f43d53c13315dc359e720bf74be812eb2d4705630f3314b09dc1c03d0462ca309c9e72798994164e6ffad44e459f4ca36af4a2ebfa033b03957ddf042e34157d3ea20b81cc3c0ca6e79e9e7ee6e90ba9fe7a9aaf8710d2ba29b5374c600ceb88ecac8361060629dbc3c0bd897bd3b3c069d36f9a85199d653bef299bae7d135054a72e30f884a01c3a60cc5941c41bebadeabcbc04140ab24c19e9310cd6706e8771155777568fd07b58d1670583af84e0b437e2eed6ebbaae58aff40266072f607630da514341b1b0952923b7f5371b71abadb9bd4e6d0c2c25be5bbf7080ba14e7e1bf1dbeac2afb002a239611e99e87c059b763d1726256915f6613e93edfca34c3cc1a328dc8c801998618dba4628819620b104cb144c548ee6049054488913421bc4288a5a32962f4306f589268c0a008b7d86cbde3b0fde368e5555565966559395525bbeaa165d5b7189df5a77f16a4c26e5996cc558e87392bc3ac5b68699f910f87cb84dc5dad2bf3b72324a4da15f2f8756596f541715a9635bfaa2a2d334f4fc86642e49e9047e6af0add29f3778570853c75b31bb66ddb766ddbb6d56db3b66aa373935bdc7ceba12589515828a79c724a09a3124cacc0ee417624ac2884b0a3049a907ad47a208f9d99901f417c4ba9a1f65279d4244621843da7860a42bfb9e1a441023838314e4a679269c54208218410429f16662d66ede4ec09fd5a95fb5b1e71a2ac2aab56abaa2a286755559555ab5511e14c5ab9af555b4eab5955ab56abf20a7ea5616559b55e17d600cfbb989d93e60f0bd19cd13c2177ed866ddbd44429eba729ee13ce39a7432ef037b53cb21ea594525ed100cf23d275d67e73cf39bdf2ceb2e6acaa5a41f841b128494cbab88b5d183666f81ca574469c1c58777777d71046f85083b156021b67430821c4d9fe9002a6d40fd8e3eda43e1d5c08db2bae77c7d66cb14ce796dbdbe9e142a8a263621633995278f372204ffd4c77367794dbca9b6977c7dfdeacbdf6f7b34c639a96f9be7342c8536145afc82b433420a89431b32102a4e2a8f44e164435656648002000000043140000200c08868442c168381c1266557714800b7e8a4280661fc99328885118a48c31c6184200000000006064a6888300b99eb317ce9b79d38f19cad04833b1c8ff42131b0f32e2999964f16c2d046d4001a38a3cc705b6129d10be10723156099b1938d7682629f39bb180e7a4e2d2c460f8679ab9eb21c7e75aa9be2a3f29444e4abc12c4357b7388ca019d6f0536016a4a6b6a2df0c952d5a04727c83bca2fd4a46791d9583fc0bef459748f5aad60cbd08f630ecd1bf3e78deb71fdb9b88a488d7e56a2c31190e808912d857b89b2e5e7d88d13b607671d0055a047d0112ab65471546478f726fce304b44115771db376c2d161300de24a17c947635f8a08372eea69f7d63874235ba36f11928c8102e2d83a0b319f9605352a11ff330506663565ea2b0683e34b8480c03cc22410f2d752dffdc6a6e75f2e6f0acaa709710f641e7ac302d9b58d64e7809009f169525f499a0da11d9b2ebb1ed9804287635a3f1c7fd481be2d9f546e5f1eeed2beb031d6df1e17c534c4397884520f796cefa41de72489ac8634ded1b5de383636fb96fdb0e943039b398741ec865e9bab63873014c78a6c603fdca883ac74969aa6a9d9aa8ecc840eb18fc64f4cf1ca82469952bc2518cb80b12c5570c69b39e85843c18d4e585596eed365c90fe498579799d9993620c0be9121b5367b38a0d0c3cb5acd341f42a2ac1ce50681c68b60529cea113c53de7244aa31abf5f90f9768e2fee773a0046135783a1854059838adfb0205d481ef69461b784496b4b469c571a4a847451729075da4a38519b77ef07792f65f062481d79fcd0e6703ef3f37c09551b96d0539db6e832cb1a875d2e681078783515811b70ad77d8d1c89cf7c22937c662279d179915282dfd73d2a3b7cf2202943bbb2cb2d4b13f2c5c28ea5780ec033a514246f39863c5c889e1318a98d2dafadfde32a76da48dc84f0bcc13cb4493feb4847a22f2efba30b6cc1a396d9d191460f314011d98a13f76eeff5602776c6f393fe2e448e64b5a75daf31342dc435ad5cf831aedcc2d644f924464787187b896bf375023fc83fde3f1ac645db2f41ffbf09793fb3cfa13b42e9ab0613846b824c7fe87e11b8dc976e4e808d1f310cb5cc9e4bd099dc2dd6c06940dc3c1135fe64fd42cc3d414af1711f4c34796904ed35fbdcfa61bfc93bfea10bfce4db3894c6441230c26656b60c249f3234bae73084f2544aa2db933c51a9e337513258dfa1885f5b5bed36ffbbc3a1a7e7016dcbddc085219ad490efb794af754e34e9ad505975b89d5fac7fdd887ab1b4f8c858c755db5901678ca35840a0b4119e2298d90d5393773172fbb46fd5a961e0d688d0cec930db2eca6a999b6e071aff0beb04c9ee8c0c95f3c12e13583607e022c73030038396d0e61a889e38bd82727b4a2abf82ac1534fa47d426f855a50ec8e4e2f12a1be4f82ce814035c0d9b00139bb218e4da797e182b160f42a3f7fb8c20078fba474de297aace375ceb374e32a84ac996179336d731afd90a967f98c835f1e143de1950dd86014171af2ede66eca02362cc1ea2846a090c39b9403360a76b24283074e9a305f78815c42882e18fe63cd3603647af0bcc5c1e49ce8af8cf5e9cc29fb524a9fb6e77d5ad42601d58caeee6a8a032ce33af7fc2af9e3ff3aad83fbeec2a253ae6dd00c5a444f39b125891f9f81be0596e0ca29a5e9e95435912a4390fc43289bf5c651cc768ebcac84453f2e569ce56dca979aa0c914f794878f3a62793b09037c8f0658015a81bdbd83e4578e37efbf969f1f71b770750dbb8f8b92c23d1226c15ce474955c8a92c7717c31513180820ecd1ec0d0ab7877d414dea391fa0aa6571ddb028d2725bdbc5958877aa48b31983b30f7d51d3057e84db622004103688962f0acebc063ea55b806c152345e113a8fd096f542a52b1960f9c9f573a08aa1d73c2656778a9c46df9ef4924c5241a6f9575a5929fa0c09dce942cc689dd8712d33a3dcecd4a6294e70a0b718872d5d055c893ace9e74008cc0ed83dfb78020b32bec9ef40f9312bc424b0cd0772891755d5a5f789cfa31d18a39210624270c0857d85b2d561c35eced9e04186a19499dca5c2f7cee1b4ce2c1aa34269bb43f8872143c18010635beec9acb090f30051de30754d3f0e70bda9b70e090dbf10d02a1c7f87089890d07b41056c2e479760010c25e9d9e62725b9cbd0dce946b56b63a577e44c0c64f7206fdc814cea47594d266ab37e84946bf68585542299070162c63e4509677e0c98a657df302f302e024c32be17f36483ff47a3c53f933550398108b945cc74b75abaa3cbf72c5a99a5a29c1d57a49246667e07d462b05820099f7d848fa7df70dfb4ef5a8f4a5a3dfdeeb72041b424d620f94a2146e79f187527959348c3c09d41d7521253eb3ccdf8b1a7fd8197393eb51e5d3ac04c6f35a66a584b3a33edb06bb365e1d271761049e28a04105ba24588ee70c2501b55507d45dd9361ed1cd26738746092115dbc9e52783e22590543ef18ab2b15ba1038bb0da8329f99b7f505a6ca8c99f0774f1ed00ad4a120a05295abd4408bab8c22a04956d845c58de8fcb3e42d46657d10a96026dee86c581157c78ce6fe1af30ccc2c4209d449ca8ed025b0b2a8828a945d3b900da61609c544e00af4a0bc2fd827862831347c7983c0b6acb92d0a1a6badf0ed93b7fb35a9a54c916bac9767a5bb71088229472fef590d51dcf300154363d3e6f33a833838d8c0c5e05866571441ba315915654d5a51374998c18d2ded47066e692b6ec8aa9c6226f6b9effe8709b402ef81f9251552bc7f7d59498d17df6c8642fa5422ef28569e8909afc4484b1ee3c83149ffc643cf156f24e1662a998da5dbd83b63a15ff86e8dae5e0785f67c39c0daf205cbcbdab1ee3ad37ae23eb915083bcb36e4ab4add7f87fbd8b71946f600a6d4c15037a06bbf43c00b6813888eaf5af34d9372e6578394ba6a64ea6bef3f9acabd656a7ca6f238775e2895965412c414f7b75fc8790ab7a9f3ed5a2c8945523b866653396dcec6bced98392eedef3e3cd05bdec2b655577d1c431e6061be6cf25fa43591aed0a4db74db8fce72deeb19d48a7d12eaf49db8f5f983d23369a8fa23a3231fd638dc21f2d2fe3ec882b6a660085d3bf9810e5573212b061a03d0dd510882336cf1c57474cb50d0b29e912cf67edf09817affeba1cf1349cd885e5bebea78c52b8fabdb94173621213cd04802a45466a12d5c880f21365115fa914a46d68ecbe500aa537b818d82ba52567b1693ff9af1e5e152645a3131b42bbe5bb9eddba2dbcb67c62df50caa35210c1946c439ba983a79b2a947d5481b646ac4e25ffbdf552f94a9a67d78d9012e7c2489e89d861a81362ce9832a7315f1c17cc2154816d4c606d58538f178d0f528d3f70c47c9654b586895304d42c6d77a800d2e0734b0b9d184b89328d207056a4aa52828b35f72b626fe6e626331b166665148dcea3e85f6721e9206d083212db6773841ca4fb34a442cae70e4927d3053187a3761842005ece952c91b224f74399dc3895b2e7cc32079b63a73d256b987a4001df2606a269115481a06b8286947efe218a7940cf896e017c2c8eca100f805dbe6afb6962205fbc03ed798c61f8a42f0d423bf2145f8c70f32b3bae9e46735e195a4327cfd05712b6221138d9cf86a76bae042b4a5960e389bede0d80d5341f6c129fc9318b13308a012c77fc6ad0f0d95853e0a77b262c970e43631ba11465658b176e0e6450d70a08754bbd8b4c17396aa1f0d25ec1fa5d591a37d72fd9eca151a8d4b8801c78ac45912942d8c9e5a4b46f030f055fde15f343d7d1e6fe103e639254b342ecba69e5048ab0d605b88f7d32df24ef3869de4cb0268a0e4fc9b544e651846934d8703235f9d604e4cdfd15e6b4552e15f44265cf4229449ca9430523fd125da087ebbacfce07959863acb9a9f946c4f5b91106167cb1f4aed74661a4d46c48d5da407058b6b02e64568fe1cc45433f51a7a74615a83ca4ff58e4f070796cb4ce4c553b88a59205c1517d1c72e607e47e09a4d009ad335a5bb846d843e41ea5c4f0cb9f1c36de3dad3c67b9fc335a37e9a711222997e0d20c6e13b19f04a08718b8bb8c77da05e25088d777661c588beebaa10ebbf6e49807b008215a6aee5031f8613a160f99f6310140c9b29794b6b8ce91b8d4cff4ade7a970193267470b55853777f6fdd953d74ecff7d8a001f26bca7761041c83f35ce36697f865811ac6b5aca776b035307a75432d9a3b72a17fafe854d44aba7fd5243203faea55ad071e492b27403a554d725bcf3aaa2905dcb9d1bef3cf64685d80fce310de97b92be5bc2c3d55a51d4973fd60e5e9c3600f6cae970c2f58830511fd5ceb40ba50a0e270286e6067a65d21e7638e193afe5b3a99b59f42a9546245ae2dc99773b291b7d85fc537bdc3ccb8c9ce9825ad4f8a18c2eccf386f476d9702e623ba28083251ef712fa083ed3598b4c90182d71612d14465182f8b0fd49048a27a5e091747e47682cd8e6197fe0366e25378ff345d531e34ea3b761aa39b545cab93d7d040c2a1e254e1d9e3a68906140dc237eca1aeba020c6ab7ead9295ba8509164571b5ffb10c1fb6e3aa333140f870f647125b07c5d17a18e801c8aa3d6044ebe3718f2c41daed1568968ca540a3d78733678246244a2b841949669e0d2751322adda0e6a0ab14785bbccd4151e89dc61111695fbd254b1d5a33b146c9742f811e2e30ae5e63b370ac12a2f51aea517b17c23adfd0b20c0bf6911b6dfc23b3709d2f3a59c59f1b6dbf40920d05432013844032d413c07543425033e30ee4551583b62f611913e2e1de56c4cf1f6ed9f5aef7bfe7bbdfff3d3b25de134d3e1bf7e79df8433831ca605975b997e295c38692004043d0c0fda08e9269abd52aad7ae03256eb66053fee125cfabb04131bc56aa00ebe350d23629807ab4e9e93e5afcb42fcb72f5c0c545e2935ef17d650ddca3b1719cc9118fcfd62dfac7664cdfb0dfcf43403b69de86320102014c4fb0391134d6463c8045df4c8f118411a308a2fb4fcb97190a35d6a83c199195ee22dfa342ba317817db3e4c6595828065c4c700e9e3d37fcfc888d7ad85a30108e776347a70386a9281160f82c1faaecabd40d6c02a81b2345c122dc7644cadbc3cf8a23114216312da2e0a3a3274f0d942a73e553cef868a0dab8a4cb1795d54ad5aeea151b603f65af270c2ce2dfba6725056b667f2e2745661415e6a5a26b69037f9527bf9e5da708e688c5be8a6cece7e94ae555095ea2dad49c0f30628ff1c6edc840b1c5a4b3f857b8a573e35de19717efc83796a945825b099d376eac2cb9dcf76a4c687396ad4fe18d260db60a976ab88ef6080b33941433723fb3d94971571a61804115efae603ae575b619e005e72f04722f589b30c64777dcf4d79763fe9c06500464a26aedefd2075f0c007e64fd8b3200c634b369cd22a3dc916e7f2ee4791474a33106c0c8fca1b4d70fa81e42ff989e520362f7b0ea08bc9a0ac1f420e0ed93f06b2a99efaee2893e45452fdb27d1c8df09ae6daf40936a894bd4880d933b9648ddc14084b5a4b3c3845c1b9381b831329ef1445e1b13bf46df20888263197b88666f2c0443e08aa31ef3289e3764efa6ffd91ccfb9abb5e4ceac0a71ff0637368a71e6d315c7260f435dead76b200ee3db34d02c05a8c01a231d4833b4800748787a364938383374a19c602ebffe0e4c8d497e682708440d0c114aa444f93c83e03b2a3ddb3d387319482fc62a35bb93242726aea90882c53aebf01fe8191d93280eb6ca556aa07b20e088b78a880c24bafede68da0b3f9da7e5e91b32f19b32d839d2036f1373512b90e7d20384f1300c8d23835382d70ab7a1b49b048f96c62fce14e5caba34df71d8591580454c4931acc9e1019b6f512848ba03fac040fa15eb0fb372369828e71b5e5763dc6921b32904060ae63f7c2032d783465e2c1ce4d013c10d5c4ca996033c374527560dc0981bf81a2688abda9421d62e30c371a99871544cd46fbb822c2c444b5f10a8096e92f74d12bc56c28eec9fa581c4e97062e0de451bd807edfd68f5b234f880a90b46841b08fc2cc4924204e8eeb1015df476961d99cc607b1cb1271f2c55f1c3d22208306cf99f3bbbdf8c29cf04e3c57cb047346c9273645e07e726be99d0f7206bca2a0ba926f227573628e295b2dbb725d939932429412b5d9868c73579eb1f24e3da71b8a47baa6cff968723b0c330ec95019cf7c1268c658d2975af238653650ca84f80dc5c86969ce1fce802c5f84e63158ce087ac4053b31d11374fccdbcfc6b0a4693293693908683faf26ee7f000ba79551fdcb208adb2be718f16ea802b1845462cadc7be00c8905a4cbdf8b07f2a8b900e0b9807660e760b25fbaf890b772cca97150b3b518616ccb0d02361d86341226fc53a51787348aa1d75771a7de437cca05c38f75608b73c71f1112d81e90b457a3b61544d7a928310091871ba15ce31815084dd0e590bd1d192b1a29bc187623768576eac95178635e9ebe757c92518a368fe143d9bb6920278dc3360568a352359977ccd59112072c3a91857464c4952a885f30ad5cae12a4100173cb1600b552a63dc0883f5422e26cd4ac6bd044d1e63b1ca9c6d1471c60bc40040771e74fb11a4b23f2d4988069c9bd276e7773b437f4f69fdeefae14a5a9924e28a063d97b42fd843e81ae8c34557a988ec6a210719cf8ffdb5a9f9e918d6694e64fccdb915fcf98b62af8b40b79c6cbc2bdaaa6e4fb1c8a957c0efc09c61ba19093b07a1516a96e858fba65a05e7cf16a70f117cb6487704a865c6bf6edd606cb5eb6344be7f72a2ccfe9fae24ec93b1b3e5810146af75e0653b343b2a8897fd398041c9eb9f2f537a96e27446ce9efe98e1bd72439299cfc46d5da6bd520aecb4bbae01212b0c7672a600ea6295f4db58a5b9c363d3ff7349a0317f5986a70e9bc52f0edfadc2a0f61c0596d3c50413f50f56c4e4c51849ef403496a1f22c474d0812a73b586921840095c093351bfd29d4bdaaa840c94052670729b7b40064a28609ce26f3362c4b603d6360be79ec1b67847b69510db70378f9230d845b106f5550753ec23b87c8591766494d8fb0552a5e4a437bc62cea06ad937d72aed82a790a9d03a589ced49829fa30dab9a35e96e6ad6fa1e9f8f9f021fc7ccb921ea6ee43700092038f24a1e337dba370d90b869ff2ae9d307f92d1fb7be35ba88efb60f0bc7b32986fae188ae5c990c747092ac447850645950ff40acf7b93f4210d0090f33b9e946821a1d5c3fa50f20d2e443d8933ba42b6be7d9b8a6d3858467c05e47570f207ffe1546bb581f7fb3e790d838adca144639bbed26a8e629ba878ced081b9aca610b25a2f001626ebc0eef8823620ef356405cb6ef2dda04dcbb9968dfde6a8d82d50ae1b6d153c28bd3d4580ee532e802c3ff26f42013bad61da5c54ab3ba5a6d42ca5e482813c52473c6913d35f3e376ec87015947394d749c4b9c952ec50a00d13668b62656a7cf703b2a5ed0e628dc196e80e35b317e8d1b07edf7cc1f17f6403319c6115b3a28e01c6757dd4509495c6d60b61d83fe3e921ba351caf987b34bbdc5eddadc457f8dc06de9f2a19f8971bb7517f2459166947dcc8d516e5897956f5bb0b02d13686d46bc44459cd770a20d7e7c120ef074212e6a1b6d41d62af94aeb428f4f4659960c88ecabe4ce91cc9744b8caa596e6808e89c9264577dedc235dfc2e66b8ded6c14aac8e166e0a37ecfd4b9b83b12a52256a4322b04359070c7b87ec62bbf0153ae810ff32777f3e6fc552af48fe6da06b8ab2ec8370322dcd5bfced48497122a8462e0d97c7d401267cc8fa43df07e3c35bd7d7db9afe734bae24029ee0f27a69cc7dd5b41dd0904c73dd33898f49ce93ce0985b73cc1db77e66f112ac2db6c3cca9b49dbeb188fbf2c66ce01665839d984c87793e28c1199f2ce136b82f3af6e4de777e1e3600ee06ef1b56497220ecd0edf2ee279fc5bf24ec9dc835c4d55adbac878ad7485e442dc44776bb797ad79ff97aa0b763a72cd57f766af9ff69ebff227ef453661417b9d33c53f39f7265c8db667a99ce3c5bfb46e3df1fc0bf70b88cf2fdb59950ecd9eb1b7d0043be8a7d956d175e6116aed345f9ed2ca638f9d27bf2558aa7d8a7b840ad65f87d4d5c0481553dc9f81ba16ed72fbd7d053a7b5897a6f46d1f94e27a675be71ebd5635f1962c2a6027a97c44fc68488a1c14dc378bd1cc3d1b43757f4ae40b2c9bb5853f0a0efacb75b13c8aa0400672655c46f05012db3faeebfd2e088db1b738af8d0bf1fffeb628fc38a694b0fcb91cc544b7c32a4f60e024dc5540bbfb81024ef48f48392ad571e17da4eb69201c47cf5c37b87df77f9865eabdcb2d44c70049b4faf25d220b5eb80ec617041750e855f4e6687628bcfbb9e2d741d68b61ec99b0101206dbaac3821073092c0e1e00ddc3457048335214471d16b07da708ccd965efd74ae15c5135d172c4d36f9b1be0c47b9698abfe904614cf3a451c92d1ae2b0d5a405c8a86f2ffc54b82689b2b0bc7f06df474055da040295a87235304419a86fc42f93c77d8fa26f1913df8d8885a5ccda66f2a322958d80fea2a472f6a333c8ab66761b5e7d776527224c0185361e0ff97d92a8c89641190a0d6e2bf100e1d733154fefc33f8e0ceb84d06c8d5388c831a512508c03593a29fc360c5332222cb47d3f76395a54c96585b46014d66816d6302c31f03888f08e6fef60e99c347083d686c53e66014b2d7f3aa6a40faa7066cb0941e9fb0fc1e45105d6661cff1df877487dd0405b62e07650c704de170a2c4350780848148270b78d4ee5dbaccfb8a3239655fc7b1f97c5e4d79314af7156063ed6abd8eb567db3d7bc64e0efecb94ee6bd6a8da21c8824d6a8199b6c3d3043b27e8322ccf665126cf77e56be0f99b3e618cc69211fe20144a515b5f5aa9f992b7ffb08b36fd95e7aa3948024d7d424042529062b4fa592370b355b3a743591f9916b06aab3c03760093de1c6d4aa12e17cbded4f4ad9969d1eac0f06d09fb04e4c3868323b3d3b247a144d795a936f5a9fd5ef8e0cdce71d4b68891fe4ae046f192f3a241aaaf4ac6a8c16624679701a439ccd1c58a24fb31045d3f84914bc5aed122851dc2ec9874e6d3c0f0ce4a1a4bc05a9b532161dffb13fe440406735406507259db663d2d1fbed42a564a445eacf62a7cbebe791c0723e718177c0eba5d032e1e7a681ef1293f6f9f9f9fb9e74bbbc24eb88a70576d1a05913d5606564a3214d94198050946bb09dfb8657a872c2274d67b2b9446c74a6e9932d4f91a1ae45108d83d450ee37037e0413f360a6660bfb34fbc11f74b4cb2c08007cb5f64975889cdd83df3af1c046ca98eeee5a6d61757272902b513c50c2660b4522956a22c7ca859b1f2f19563ebcca604d34ca5a279fe6fb14338d2cebaa445b95c36a16132f750a5b38c7119fa504d877dc61f228076e56deb965cd3c1e0a119211cd4046c72f6467375d0697a549ca60617b29d60f5f5492e6d24b1dfc7659ac44e24f69f49758507994ee1cd5c3203c2ef441026c3e04a4e54c4bd04c8b18c8f294d41142f20a1372e27e07c48897ec7b87c69ad28608c46eab274141075611c9d38140c4c60f4567a4a086028eb46c3780ae886344e649a076edea083c1ea3f66a7a9bdb8e21aaeba4947bd3cbc2dde0764b28a744d622873cda3f88b65a454288633935a1addb590eda51d04548d0cfe976f2a8bab00c66f16775034b13ed9e9aa509a3ab4524c5fb58b305782cd345a4eaebd31076fb6fdace4916229def1c7cb8029da8eb939d63f4fad2000152b351edf71249f0b2d17eaa263f137a89ad82c5a94a9a388441bbf20f4f2a40694d54b500853cfb16d1982e2c94ba1e7b2e1c0365cf71c696b4d6c848b5e3240fb7a071f52a9ed934c56d2479fe0abd077eacd60bd4dbf16d451b6842411c9fdd3374184ea5215e4ad16c20da9cff2a005f3036617eeb33b50718bbccb46648ba5e2f6a16914d6f9ad2867f612b81d50cb9e5d63acc04891900a0e311ca91a9ea5d606838622777f96688a41a97c7fd095d36030ea05c5840a13ac48c9a6d45dcea7a1af0349f8981ac4b6e17c616e70d19f8a5e73454c56f498c8f2a29552c826c0066228a5008ad43bcf2395da2980ab23dcd8b49732ffbc7773004e1466c8b189040c3e7f24bcdf8ab8452df50699f1457bd4988ce941aa1e09d2cc8d30c99d8cf6ac6554f2a53f00842131021c14ba6ad314ddd5c912f12d7173401e16f04c0580875b3e2f45851d03f7296ca22ac7a4aefe6e919b5ae5c49f7c0d394b66b17f73ef2ca732b269e4c17324fad68ce4e6d4cf5339f92c9ec33a61afc76a573073b9c661845a32b661e746474c17fa574f194da3a76733f944acb529b7d0255ca7ae62d01b9b7405cf08e6d87f48277b60830e4fc70f893a247a080211ebe3f12e8e3465f4970f8a25adfd4531368b847d81a59200693ab4bf6bba2157ea81f2fa4a4aa8b672282035ff49e7511867a59b150da0cdd51e9ff4f52d4efbfd24b85086ef4994d6f0a495c1493bf36e8bc3a1a818f0cfdee61b623c248884acbfdf6c4500c074121a98e1682b0f7a1b366a72e5ba45101bbe0175e32e8b134bc5ed847435a7d06ce14023d7dcd0bbf2cb716b88404a286476b8419e888ee6beb0df853519b89ca7ff6c0366936caf064b1c5f1b2f8c09457d92ae1a8146142001bc60dfc05023f9127aba0f7a2b8dfe5e64ee53f29c31e3893a12ada442423e190911514cd040f2493563837a0aba541012651739564d2cc57b86a75661aac4a202eda38991f8e126cf74099a4222ed67d22b3e8a06baaac3b294d91379deb6fb5ec77c179b72631cd62460902ac8f34eaff4c40c199c0f6e75e68638724bded50f8aecd1183f4ff6d92455a4009857d2b41778faea65b53a570489eecf07d94b68013c3b296a59ccc39d12e420e02668a4873157e32de3645bfcd77663916e80bb8c92e8751f4a03a071f14efa11c01e42332838c8bd8d3c3aa7f10fa705f2ed537867f7101c6f82257a0b7552da28b4473ce54408706adc18fbbf7049ca5b4b511f4d1bd43438c1d6abb963db66cc378caad73431b1e2de595eda73bcaf5e2ff872fa6313c2bf673621b85ea366e315ca38520d318445b05b7c4585f40dd4beda6ff7847d50b6cc0b575d391bf8f083c291d288568bbccc0da89a001d5038900a4ca35f3978b4dfd4e064cc0945b2532c3e799ce52e36b46ee4cbd6f36b1a1a6da315d56a3b8948e87b6340333117ba62e80db55389517e5eff846210f3b77159c687b3f68bceb817181695fd23fe7470d719566c0c62e5cd69141c97c4f538d56420bda604900f48525179c7d4cd514206515d5722697c14c80674af95f37f6acffa2317ac376533e787db1009c49bb48f6acee3ac2370b2780630aa56862cec984b12d12abff05637521266f7da6ff97781e1c869f7298e320c31c30b296c064aeb5356b6d7d5ffec855bf7eea41e4bf1936b5de845e2975dd16a0dbfd44d16e8354ec76341f35ed6d7f795e4739b9eb7c8a8864d390286deedb7ebf8f97fa790713599f9890a2034044a77dbed0aa84b375589e644650632983e7a4e5d035c56ff29f2ce79181ef32bb67c888c23d85c9c360328cf5126c309aaa97f041f04bdd4c3be3efce04eba510afd55f7e9c2293300cbcf32d1d082dfbb7953b114517b3d2d16fb6f3a4b31295a96fef3606c1468a376fe36ec12cd93771112feb1a81588e040faced0ce8f08f3b3931211b40556d5e4b279831a0c0db6d3f612cb82e252c0487c6a115aa42983a06b41c2e8d05c44b5943163e80b2cfe5e70fbba3aa8633cdf268bc435cc422be60673819c46d75897712e1bf83ae2fe7c282eabc82e3a3588ff984eb3ee7afd448e789758a6f6776c4a27eb335c529d164741b4cd6a2a4c669fb64b7be6a7b83684be167ce376914fbeccbcc322577810241b0aae424b64580d86e1632be5d05d3a6b7ddecf61649b06b3ca4e44b0126fd6d1b87882acc47b88a7f95748efa7480c80c0a2f11a03d19d5e34b9d4aa29e482164df30021f1e272f7972b44aadaf7b9297af02f96a4eaf303a743829c675c4b71d777f6f0f4632914e31edef7a3226fc32af38816dd7e971f5c4a32170517f4941d766176a1014161807efc3a8a23e5e42a1d6eb8b1714835eed4de404eeca1349e3f077e09da66f80edfa9d8b82b15acc897ca200ec1d68948387bfbdc01e44b4e13a768dbb7e3102b7aaf6369f5f280a2d45e14bc35638d994c44c7c71b0006ab9097a1db7ce419150debfe9798ba93364c2dcfb0f909f71855f232360e6be38bc597790cda887e00278f5792fb53cc61773040782e728d0be49021ff68ba4b69f574b9d7d4c6184564d08850dc2788a90d14755538412278b9fc8b340a11ca64ab3edb14d95701c206ae1ee36d5d621e744d4394a99eb0002bc498d67e81faed6dc91c69f8f5089a68c8b01551edd80acf0437a7e2b6936387179b38e1fcc1d4ea94515abe0d3fded7b171ba5a72fea1fe1a1201947383f525cd41639ef787c5bcd22bff0982949d6ea7c152a990b94ba60c4fa0ea054102d1ebcae1d0da2af52b94424e229e2a69ccef43a11ce71ce7f8b19e05eeb1e03438afff407d122c93d430d8d15a5dc3c8d269fe104ffa09d0c7d6a1640ffd7aadcba9e5897d966f91efd580ee2a3757ea53955a5509b3d65bae22210e0c0bf9520f11295a53a4f573197218f5cb167b5cbc71b8ea2a3c3e3103dea21c81f6c0237150b7b75db481321fa39c116886ef957f7b328ae5f74bbddca7b6f5344fd09b1db1c69f820d503f49e6a7cb8810ea6ad87ff290511670a4738b6a0203b9eecdb116d4d80646f747c8d97ba311c0764581fdf98ac28c76210d4593d81b3d23be4a37ddbddee67e5470bacff2761551f00ef5d47aca184cbcecf6296137e0e37df8b38bb9187a6345336572a1cc34096771ae6a8698a68e5d18ae3d965cb178f347f606939b260e2acede0644bbee10189ef89abe5b0d7fca0d4020ee4dc8338d09b4d6e17ed2aa611683e6f5420f1da711cc5f5c9c86423e28253eda9832dd8db6233bd6e4e7c468f6cd7c1c03f8d53889e816f44629373553a1cdab5fdc48851c0d0b5c778784fa7e5c85a3e7e72d91815f6ae51423bb985ba596b1dd28ea32d9a9d344300bf54e75bd76bcc1d3762b57bd9ea6b90afc445764abd8fa4f3adeac6a892ccc91b7ae8b56ef599b0df8bb4e384470be7ca10f866194b55b90d12451406af1d447b14c8762f36b13e5ed937500a9463462e16ee2be628df16d1ff7855a8274010fc8e577c65a7e8cd6f2b66a4a2c848b5b6ef99ca7967ad81ebbb46ac16fffb7b235b008b1f89e20e396955e050c60086021833c3fce2d4e36b95a4d8faa574d76c6fd147a1e04702d3da269938fbc92185de559ee53dd0db0fb96eac950f01b39454317cf454fbc75ebd1d7190f5bdb394bf997386fe177aabb6f60b4d9a5b99d464f8c8b10fadd7fd029483e1562dd22da7874694d392103f92dd7ddbd4d89e804e6133495d48b0a240c97b9978362fcdb18ceeb8f39c64d4bfe4c58e6f7c7b69d73ca406102966e160743cd8be15649d6408e4aef42162eac6fffc0de44425cf5debe7de5534a3154e50e3a6a789d965242217c8b464480a4ac41050e96404913441f9b13611192773423fafdbaf6885252aa3b019bf35f325d3a5ee30295fa524e52ceb100b5df4bdc087e6ee439b2b2186581e0c7049abbd701e89fe00bda5c7c2795d30026b24a464b5e654bdb507e9c9c482a6654e759c998c8206b71f0a9627f59b0344f532792b55cb50f4f796c2b345b33940be328a27e1bccd1298d3ea569848652542a314acd926cc951e4229d1ddc4b2f728c58248f6258b153986ab68417fb008fd6d3a58e3a8d47249d5b055cac118afd30adba1a9e04107d04b5534c5cb77565ae04958ad52a709af8af0cff5ee8b715ce97c08f821627b17537d6008684f31de2a6c09c05655ed87d315a36394669f10dfb07d09f1008fd87721af0aaec924d82c8d246d20ef3f158aea12687d5c5f4d6cc1e4ecfab57b42e610cf870a9433781468f94fe50171b35da3fa1cf93e5a3ab3e8faebddfb1d566becaa841e0980581981fa32c9f8e6db4dd169d66052cb9d4925373727953a7fb8f19b14d0bbe703c93588e3ff35054398b27302b087d03fae6d92bcd29596840ce942a8edab1fcf4be58f3e3db8b52d91b243a8620390ae971908242bf7fbd5360faeb19c70baca3e96f3a8497acc08cf6df4992888edc6c67244a065169c118df4dcc6be1d44068c39e26693fb64f8df61f56c6c079e551f4ba93fe60842be5f61e015a21e43884f6caee37f962d3540c8d0bba43112d012f6d567f98d9fccdf602d123a249270ce2f59eae36b2a1f6bfcfbca9d9f7f44b13f70612366125fd13472b1a63708cd7477e3eea693d7e4eab06f3b971e2e519b2220189c406680668f9e4be10558ff819b58bc65fdc7587de86440f1623c3bc5baee3efed42207283b67a2e2f0f4f705de34ffdcff4fc5903d9aa358c3af4ded11743fbe071db7bd98bb9ce40f9d18300be2af0bc2341437e4b240728bfc42d66fea9e9ca77024c2bb671dd142047885293192ff78f48fa582763f3428cab6d6fe9770e90833b1480c914f88d0d77ed73aa3cabd85e101a9d2e8f109ef134893b4c840c15c06298c97d590831b28be4cf20710f89d3bbb012ac1459616d50b2b4c221b7f363283ddaecc9690e66a419c52fd5e84c228681300844ba7925655bf98d010006feb986361864ac1cbedc63a4139ad3a031f8181a0981e6a182dc7ab6cff79496b8aa4aaecb2b209f2ade21197413dbe7c7fb9a5eff83807657af64416300935704677b44408a6415d523fd027dcdee8a19bf969c0cebb8a776348c7bb627022a84d873bda054c5a23c1ecf3224ab2719fbb9740e6fda9626cf229d4ee323809d66c30e1fc9a3bb683c0494ef7f95fb2b060258a7218056d589be600bd8fe28a151581751915c782674e6ffb623294023b30bfe1d5f9ed3ea15c0d94fe2527148a4b1fc5458522480363b82d0aa9334a239eaebffa5eee83c0175c09fadf69180ebbda91cfb6d3c67effd3a7db74d6f53fac42699e8ed4024b1e85e3ec528ce53c772d9e483b249c64757696a3a389ab7562028a671ec60ec8329305ec4a2456d9eed294f0146aece6a59b79713c3db73ea49bcf0722ff33eb034147ffc5a175387e5032a4451d9947ed8652fc01f44e7f967de58c7c94f525712e92286d57397a9b19f63419089c836b68ae9e0004c2eda55dd4c82c4859d3ece3e6ade01a78b614ac3fa4ce12fefb52a0f552221b57a08184f021f71456ce7cb3371d6d94cb69e04f2ade483c7091360807caeff8e204a482e4181d2011410c78ebbeff126703844f5ad32e4aeca8b4eb4e3f305b8106bda8bc873773b81e7941168834604a42571596ea245852fab2bb293819247f52353bd9ab2450510f710eb540cfee3b50952eac8f0ccd3ded4089d4e2603691e8658832932946beb7c4a02d4db161cb8752858a2ef236c78f807a5cebc38b05435b6b3c5616304469a9c9fd245612bdd066308232e09a94485708497472ef2498e0e875d6707a68e35ab7f4a22633cd4b8f69f1128ffdca5c0624375e6e8003c0191e48d08f0cb659b0d08f7ab0950aa1e20c897c561a85630a3e2b18f8d37bb1f2a756ff8c927198d2d24584099fbbdaabfaac20274306087bc629269af20666dd7f3524c1bdfb8a1e49541d1df30b53459ce64e6cff92050837fd4fd93cab47c80e3b431b941267eb4cec6720534528d3628a6360f53144610fc4aed0fe1f931a7ecc9a39c2cb7ca603651d14c1c2aca9bf0c61069486d708ae2882f931f39ce619a5e70cc87e6368cf38ed97131c1145c8492ddef5676bd56a0cf659716638c7e7e8df1f1ea5047a45f8e5bb1b6045085504f13f518d410c7892e1a36909c9034fbaf63db1e0896337418c11c686d71d142bf4b445ceea2daaa91fc95fa69610f6a1950f02ac5db4582b9e472fc78f5eb896880b4a74e762342b0145927d6b5f9a6e43c6683226958b02e0fbbec4f0f3c96353da961fcfd1c39f9c368c2b0cc4797cca794037f9bc06da7db7bac34d203a9c06788649db16d1bff2077ecc6220bca84de9b2c183159f0ee2b5280ba525bfff3df986157965284d1890b3287ddbc664736a5ca7eb25e2afee50a940fb7e3a882586f6677914fa48ed865154753c7c524d63b785d374d4f53bac436b9c1760f55723be6d3f9d46604cdf32bf76160427b338587d8c0f46e06d367530f2ab4bf0b2e69b446f177bc75da7185d47f5dcf6ddee7350275e65fe0d8470bc5623a3ad6a0d0902bc21b06dd8e2a3abf905cd410de32925bc716a3d86267c4c04115a21a0d20dbaa7d3e96df04d8c7598f0e8fa15d2b742657e1b6fcd4fe14d2fc39f9aa6219ded46e4d3fd876e02e4aa7e41f148cb7181b6168123b44401b1188c7ebe7271d44ecf7c42c8b6eb529970e9557c202b4a553411367ddc656f85a06cb8214a4b20f7e934128af6dba4fcb8c23dd2a5bb15385262aee30602d13390e5f7af58d0bdb01366b3675cdde503164b9a75975b1d96addf1bf02bf2be712c259b7f3c498e77cf011663fe9e65bc98eed0a458490d2e621fe1cd87008a190b09c2f50e68e5167de078331734608aa5a3efe994d0b832370f99bf3e3a67a894707f98a2faec0dd8cd48a24d98f059a23774f793bd33bb9f79972a0059bb340a6489185a0db6c74e76dfc0e08e0621e56143b0e0f1a6c2298c1d76a3114510528f2e08d901b68d07772067170a05718fde10d2476743bc06d8e34a317ab2f4bfa927a1507e1ea18ac89de1e33d2c3f6da054d2c3ffe0291dda8851f1019d864128ced7bada9239d9f0afcd9b753e2c442eca4bd223bdcc490b42dee88b6f63edf4c94a4505bf8da54c080402746b217832c831e3d587e0256be3a82a3a9c2906f22298e1e395d5cb4131c5ba91657135918464e1e18386f3cac20591d5f9b8d1f0e89904fd163f3fcb631a1cd77bc082e6599a3f2a4f4c8e26954c7600a3c504fc05f7d167290b1774faaf86c05394b553805b7c4d70865c09230a43aafecfb1272fd4284419521b5319b03a598629a005e26c8fae3a9eeea510c3d761b0f53cfe1b4061d42431f48c474b70475b4abff4b99820163596fb38a4d8af197ba6832b606c1c939608cf1db118e3cea5670e4d1e0fb2471cdae58a626f4038a684686c68ae64a9f2bd74759f0f6f91ae0add030864421f0afc8def56f58f3131ebb02e99bd18327ceb0c3e7ca22c08296a5318ba31a0868a3e80bd4ef9ef8f5a63f2951efc71bce656b1f891b766f0adf619698aff31d5d11f02ce4e93022296c7abba33da3e83aecd24d791d24642ce0f88fb6e8c8286ffb887d22452b4fc262d5a6e915c72cd94c424cc98771194ba74587d8984f42dd0f5d2cc1a7e4b32d7ab0893de63ba3a20e54b266352b800dc2de80fbdf33598a68cb54ab9f38722c78ae0b425ea6ff031fd51e7fd0b27dab233ebe41e1b892f606ceabe49ba1cbc6edc9d2fb98f7b57e78297d3d6e086af4466bedacb4ca09776a12ec2b6949265a49bd4b6ddce37d9bb20aaf44b7e1284f9c4f5276ff8aacb3453fc2d2ba51c9a8e0c50e4fdc278ea5d839140e527de30726e8089e3c0c5c9f7d4b3887ecc5618b53da00b078a5e2bcb0c50884356eeb5594a1c595c8f74fcce6632446fab8dbd306c6d2aa59f99a01a35126919bcae6cd7a825a2cda0b3c2e542f41155747998f13e54c38f75d9e281205c4796e2ed31a08154c99653bafaf9d7502c69dbd0d3c3a740f3ddcd3b3e5f2786ce0c42f10d8e951c2d6e255c02157a94093cf4c4619b6651c44f3046cd0a2bd31ce0bd40f8cb2151dab3e13ff7acf1d2c3b82198abfbb861422461d3066cafbfe77cc489a52d3981f62a5c766ff6c2e29f3349c48c1c0ce748e2255e85d70c4161cad2c8acd3528889158ca05248b5e30d933badb774cc585c0a187a4b5424c9b15a322e0c5a6320ddd445eab8881fc7e34a7d751bf20a0a4f8fa6c05b55ac0e7eba2cfea298f5b3939383c24ead1a2c83bb5346958a5fce57c0e299b4fa4fa5601c06b96cba86185dd0bc115e215c7c7c9fc1d78d242f5cba099283619e7cf8aff8ee5f82ddcbbca6d33b869528fa4e3e598ca5d14b6251ae4ee0dfdab080d825abd6d08b91c28cc34cad010a3e6867c87c0cd14d00f2546d75e027765f88ac9e3dbde2858920ec6c6575ea103006f19955c3ac3cb5a8d41d33b8475bf17f05853d1b8c09a1b25784a66307fe7289388ab84bc438a46262f1aece39e3ca57bb1b2abf550d063334a1546812ea9d6c8a205e0e45b6ed2f6e115819a419c9578b1f2d1afe888c4b79b666937ec56d2b3144bd26adf100e41172bdaa1eedb2df12ad8006a66659574c006c344702e24b54fe09a3fd7d2a8a87ee3c55161467c80e26554455d2a0f0e4a4910c4bdecca2485707658734a6fd64483de1a901caa2984be1d108d66a9b5d04f6c2326b6cf8511ffd7a049959e3383604068a3e375f950850e356f5d2573e5f77a4ba2c04d04ea1b20eda36b88ea044f3706abbd37840b5f3787ef14094179129b54c283393fac80db3fd317a2b8f553f6459a7419d8b158589f04c5c70260255a1425be6a2de5dacd88961fd5ce8f49f278627b4831eeb3a6d735688b7a34124f935e03c60714db3ae3fcfdad8c8dc6ba4ac3cb206fbb7c4cd9310bfc0786f1b5e815b5360c49ee7e8d26f933823f05675343d7b9d53e90602b2aac9034a94c55c2e3210a6a9b6344e6d2ee78dc77e31fe38ce639f862654488cf0bb548eb32fc4be9631583c6440edc3327843cd80c96d27cca7cce4094cb60e3a701f845b02e9c91fd189dd9ea29c9e1e832d15084b59fb9bb9b213a02b70cd81c4328748b9a8893cd0bb1f845845ee25b9c1854f0166512cad266bf874687e298b8f42785c2ea1014d25e3b6565a9116941be22b8cf919327970bd956cdcd3dfd226c80e573079116ca1b223adca1264ab3962ddb96d0693942c0f33dedb2c9a662b9e3d0577c2f5b220892cf439be7c91b9fc89c270bd4f781bda9c1b97a8d5e650afa681abd0bbbd8c4c49641c0912a1a558a51243ff8a13fd7a1e7d0090ecca7eca19726b082de1cbf65a747b14a77889e1e998d769fa068f6341dfc433f85a41a086898f67007a9579ba3c29b5a899892221078faae6fcea923cf067a7d4484c1e2a412fd7ca898cb1eac519c3e00cbd8721b4ebb99dee40857a36c4db9ca470f830d13b5893788356ad0da70be61b0cee21197c6e74555fb5dfda90320a4284ab13daf28b1517552f50773421aaea469b2233b54bb2e7a78f526cfcc56c4d6040394b9ff8fdd1640d3b2bdfa797e66c22d2b29a155a2c25037ca0961dde875ee5f547602c66c609e8f6e53138cf986d80c78d0a5e8117ac743617797dd99970920daf81ab550f6e0a4f1caa0fbe1ac3f52733169a8c3a4bb8d684958a8c5029be4e821443a8f4145a04993ac4e20948642a2f35b6bd54d477f704a8ff3c7417b142b2b2e8591a6c0cec5c2de996ccb2c042d81e137e5b8c945e4cc536e678b11cd5c32be80e86d2f1ef04c897dca657ab54e4e4defdc425742c0dfef9383cb34c07b4ee36c5bdbeea8b84b0d25f58a3593b61d9a80eac846d89e50d9518ceec09ebfe11ac102547149125790c512d72ad759a36de382e7843f62758ea980317358daccb191184678632b5b5f1bac28e31ba1ac35605bdecbd9940ef1c7f252e73736057c43dc3cf543f284a4252f5fec770561443c5da8fe24e2481dca7fd0d38770cdc8299ea63a3066033626d8ad96b5393541a5b873aab6b5d53f8e911d02469ffa36e8c19df658716d0bf2500f3513811b7613eeb49488d02bb490858e2e017b17c4156be46083bb2b4e77d57cd1a716d0c249cc14ee368cc830c5698020ba66d958a59d0c1ace285f2072852158d12a856e9f31df085ba114c9a721e81447a0e2b93744e94117352b29283f8b541a1bd92f38221b339b3cefe0855819315b104d4cce7cc5881ba176991c26f5b3fb845416b30e7a3b2bdc139da18904c0161c42ee339cddaed9e88933bbf4c101925da4cad0ff333ee312e0decd57242d5f2e6655aa4b6afbe36b2ac9914e7bec2dbe0f8cc107113b5576f3c8a4ff7431110e59b26352e81c378118fbd9f70c1da569b62c64c8c1fe47da2deb45d10192a234d5089fc44406ad98596d915e87864573f2ff3f8484888c8fc5bda034b998a2b71450891b70c2257aff1a81f5ccc61aed5099702ec7b60f12985228763492c18322534ab3afb11105febb0a3f394a5b1e19540ec401127a76b16707273e39e80888231e373ec35a71c711626beb21d2bb07e413926454ad3d4cd8dc9381fff122a73fdb05d54b0b02e4aacf22321e2ff19a7e6bb9015f6293708a953d7c16b245a55e17c946cf08476fe4a0899f6dab3c14f7a6b284cea90375b9f3b7724dc781498297a398cbe274eebb29077002e863af2cba0c82e31562ac05ad5dc2c86331251ed000a1c830984e3c777df04c6dc178ad935e7683a4ad43294d01f6edb9e1797fa15c9191f88f6185992dec6ba7ff961be0c6400014790b17d50850406bcb019b0d0eb628f40a3b4366d68d7fb4d0cc4aa706bfc3c8f4030915b645af3957f1b469189de2cecb86f5236e225db0696937b7d3d56216548358530a994fa7fdf2276ecbebdcc42493b4fcd2fa5c71d9d6f166aa0b225b37e8031f67da4fc222164e2ba52deba42aba3566fe4a6105214376d70d1751f284ca131d213cd879792fd7ff1f2e9b1aa9f896b8924ef7a8e45dcd8fd97b9e92032850cbc3ff76d330dc40b45d46bb3543bf69f051c598e303b568a0e1e53a2c5542e8ca32f4336011e36a9805ea5fd446744a4e5ea5f55bb7a773899e43ea13aaedc9b53bc1a1073c3fa01dd01da8830228726146c8de594f386a4c920009602807bce027bbab820c95335269406bf82e703fac04638089b38fb446ea734d1d178fde7f1c4e940d2b52a8e68145445cc38fd55968e9fa3d8feb9b676d080750fa7b698947971088f12aad99ddcf41f1a5c93ab9ac679edfe8850c6ea425ac39c72ce2b5b814bb3adfb2f347c3e54fe9adccb4411f083338eddfde64ba2012d45a5058ff1255163dd71e4fa4ae4da46faaba14297ea9efd2e6baa41a1edb9508e3b67e3bc6e8975c0a29a2fb28fba630cad14773154d2b1abba50cbf7ea2108d8e0a8ed1593cb19c506dcb42ee260114e6bdf8821146933cf7f5e3272b13dafda40c0169a98218d85eb79672bb1b2e1cd0853262e944ebd01d21602514a05e342248d4b08e22eb43f8546b4dc430cf8a8450393ecb1a31b9d0dd8a2a61da570f94897f5beba7a462c9f5367805e043f235782e7e537c70eb4531f3d3c3f1a39be4fdaed6ead26b1ed761e539c2230655b14eebc7541b234a14370994e7d6c78af4d41ba467807ce2218c4d82fc1087a332d35d99b1176ef3696835e2e40cb4c6b7ebe60edb414cc331e8be095a3ded7e6bf81c5d0dcedda76d04c2aa7a1a0688db4fa6aa98f3c45d61210d974c0046fcb5d11904094c6700b73d1c48cc20eef16ca8dbbc0181e88d532d18ce1a2f74b5296c1c58ce32491535290fe453d41413d9449d0cc5fcaa79b88d8423569cccfbafa3f502d44b056b689911612580699422ccc95022fd7ab5919c285284bfecbff3a04e50b7614d971b542b4c4dff36a5de5de251090899c8a99b8b2ae10121dc2224a5ae9e0e84338545802c060681e0ce5893465ee1d2f38a883f85865d4b43c2a240dde6857ed476803c60dbf578d8dd1fd2f32172a9d02b3f94c95ae5f2cdf2b065452615b8d343d91a915516b930730a58147428dfa48064e4a99fe91d550bdd03812a92333e4b3a78649d1f69b484fcca9a5371c6367682e864194a4ca01d90eb79ceb9a35e34e9a58adbc528268d2e1580fc197a89b6b03086588fd187cc073898f437bbc669cb128e7b7cdfff8544cf517f2b833cbe1233a9aedc78a7b9f446d3530d1decceb6e3c1e8f5d6419cf025d289d75badd0f3e18987558f50b526cafbaf35a6d913aea65b16db180a0cde4c0ba6b463730267efd591483f515730fdd8c224950870f1049d3a0e0f1a4c4d2efc3f125466c1b318c394d0f134d919c289fb21801438fb85ee4eac5a561d20cddb2c176733a4b502370d1ea802202948f44349da347a7280f466c96c5242756b710a85d2e88f0251ef70031e3e85342a0a960badb1a693dedda6da76e02d2c0993235a9367a14e38902903663f6b3bc7033108de9c170f68418c40a3f3b9c90254f7f4372858715776d3905f7e2cc4db9dc83f2c9242f4d73e5cca68273ea8a5e9048cfb50091944f7987974b0d8d9a89fa6c8e81456c4f5e1240e889f36a26f526b753ff549a7b483c486407d719eee4855cf8e3d6da9b7c4ad92e2cac7612ef1ff41f5264711a8a797d6d424921319638aa1652a77a4c109a607182f9a0b22b2baff5bde75c20b990697cd60068bedf5463181ca2f820fba50599e12eaa09f97cea7f7768f1526c4dd39c5158167182c1fe9b82373865a29ae35e1d76956ba68ee21428da18121c268ddc9d38a2364d695a13250d139ac47f5619fb8afcf04fda0ad034cd5971e1d06038e18f431e4c07c3953f792d40e26c10cdfa523be712bbb263cf089c353df708a60d1e13ca5ad964ddc07e979b15b208471676a0bccce2238b2d5e6710a175d31eec4688a80c66056ff03fcd10fc64244551556fc2059a7c5058d4124fd39a2cb493a13309f1e49d3200f6e0436e0fca00fab147443b7fde8158bff75a24eb7c0acfb4cd047acbab1735b61a0eb6d61fd81f9e606a0cbf94a624f30649adacf1c742fafc048c25c8e1c08543b105bd7f576b6d38834673d34abd69007f76c311c4e902bf80464f914ae5acea4a4fdf20c1a67a41e6153e3c87ce422ad85c3595663c108bbac3323f791d275387bcfab21666c357078436d9a9f9ed2208320f0cb6322c32125ea1673579a3eaa76a8f0e726f9bf2c0bea7abf25aeef491fe22e674ecbce9a7831453771a1614cb67187d419a1ecbf8ffb5c108b085d29867d7e9846d4eb6653d4d99dffe46352533ea85e793fd39386e312ce8fb5cfda468903db37e52c3f3281d889acd0f2df8afcd19bc29b4d8aec5f156941432d679804700c38d9c07941fd17d5b43139f192effe95247eba61647b77caac4fa21584ef124b0bc24dbcac1adb18bbbe264dabaf339650dfd09f5c0f647915c15be98b165a8007e345274b0ae5a72883141e56722762750415c47d6f36ce0b0da24ceb7274ca6e1be5ce260322b2a698ba737bf7050fbebabf344a09f1cbdce722e7f566af567dccb030fcd51c9f667ce744f900b22ff84fbd3e87dac73e0035517eb2668a14726758cbd9710c944b9d51502442be1db150591dbe1b078e3d7dc020030b32feeb27c281600c928b3a36fb04ed2d077d4dab56e97e9c2707a14553b158d1692640ee8345c3fb2fea77d25e4a10ff8c2cf10df133e888d6e9f23f14d0aaa2bb7731cd578bc5bf541232736022dd9d0c7530b13059465556cdd0e5a4fcbf2bb92021e21ce9f4da86dc3a93f3eaca39dec791e11a7e6ca4f37594f36b1619221e90b7df84ddc509b920a610b61095788677c95f09b4867f988e7e3b10405f19ec6f21aa120c26cba98f05faa090a50d14288d5c6542fedc914db46f093dd0df6c61bdcfc5dea94ec72e647af7951e8e884701024296417074d71daf1f269bb7f6f077f76a3bd82f272c6849719cf20ef8b0bf9bbf56f7ce92ca2c17f0a217082387668bcfb0cf272312155d8a28a45d3fc9edd1e733fdfe1168a96657cce44b4f891be357f75dc98f826b4d4590925efaac589ded1edde8a25c4021928b612cbfd7c1bf46a7ac8f8813818112eee90017cd8a2d46436b6ff39e169a8869f69773f653ecc2032f57f0725745c9b986ee452a7f064284628f32599d3a88c429bd34edd4a489b5334f1f4dcfea84badfdf5311ed0cfb48d2bf4a9535b3c4a5b648e8085896783845bcd0f53bb3eee625082e383883a4d0ea9b3912c088eebde91def124e4cc76f808787156a62fd041cccd82c79c2d1ba2401661d22787125542e19655782b635b1a6f99cf2503d7f5fda5ea6e2a73b6bd5d291fd5e916418aa11fa78c2c68cb6036805224e562df0ac5ea32d3972450f5bddde9f68b7087328f846fb8b6f81b2ffc41fa3e1ff6e3e52a2ba4fc56eb8904b832a4dd51a31799e4aed56acde29f080e65f6388dafc04e0929ef018234fe9183c41b0d41694070ee547e18e77758a574b98518e1b5fc037d11a307ffc2af06c03dd84d68cafd7129c1dc855b0d829fc163d15bfa82fb13a929e3223e52b0a8b46e29e0a57618064d62d5bb301258ff190132728490fbb4aa5a45e741eead75352ad2bce7dcce531e20b9e5cd2c3390f1d2517139fff5d6b422e383ce9457571c8a1732fc160e02aa97816230adae105acac57345bb50959dc3f1635194c467068c4c05d4aee649594727181f8d8492e73862f5cd477f5e1823532ea548c301e85d372a72c968620546494e902e25d7922ba2029b7177cb8296b58e8dfcd16662e0d878c5b33c769df460822a6dc6e9a63612c2d439aee9bcb48bd332f99d1df7314a01f25e35cde0d85e89150e2039b0ad69fda9642c5095cc09f7d8ed98bd01caaac4bdbdb18e4c8deb0ad1b632198053546057cacdeee19b503e455d424c111852c65b1cd87dc726b9c5e6218ce5340d446150fd3e2317479120f978ee9bf60420033c040dc3d667e92885c6ddf33763c4dd15164c7803158194ce2194e88e94be3548225ddc1bf29625cc0eaf498d97ea822cf1dd7e31e67ba4d51a94dc327d85c4cfbf17340b8d99b73248d3c3cdc82442b338271a0fa01897b4489cc5a2defc5b8bcc00842c9cb252a60a03588e1294016b3da55fe866df3509cc94dccf0a410ce99e40afa883971bef29944c619217975196ac4a78166343d899bc0e76f87842695320178999c0ebd8a241f39fefafc583f2255973ce4c27776c36dd1bd7d78d1105686950561e9dca5d172ef96908c6ad7ec6f563fe314eead35309ccc54f983a0b06aa39f68ff588a982c3e1b23b03d4a7732a8324e2ee50ff43f98b3158373e9b470794c9b9bc1704340c05ed490fd03050e0a1f91a2d4831d4db04ae16db5b0117f6e5d81a463f52230ff8bf52e6797281089b4015a381fcdf019783c291b55965fee711f1437089a28d338722e070e8e3e71909b1196ace829e45fad7365dd8270f4d4e6a327725a1635b33b8c4a6734da08322cd7397cc6749342883c7ff136f0932286e41a5120fb12c2d1d18b23500c608bda0029e41bc0d6a038452a12d34641c28c6d42193ba12bebea464eb1fc5a00ba6df921f415ada821f2c65d87a254dda1f4a0fb3c9448e3e8fc4fa2e8f39ad8d20a91f7bb65f7c4ef62417feb761913fd68860b20978da8e4133a3ceb95e2388ad1a5bd10388a795d9ae8ed3cb979763f42b912a411cbaf22842607bd27417fb7a200e9f61133d1b4402183267f99bc0369f42580d9e90819d762e5d5b5ad0182cc1acd4f243f5fa1de20bcb921d5845667c453ad3649be0316e54d17adc98bea1bd4fc46a303c2ad18d1a81f721512be64fbadd6ae367c52d6c91f663cbc41ff79aef786ca552ba820e01280617a83059db9430f2cf0e9550dbc890f0af1309cead5e0f209b0a329b5f315a0c8df0408780d40f1c876dd6d7d973ad67818a0734da102ac34aea624e3bd6a54815e895cfe6f32a9f460d07b186c59cbe7b0ffa7b91aad31ba977733b4f2fc3bdb758fcb9c31eda20f69c346368bf1713100dad1932d0cbea5cd8ec141e68b5dd5e8c5d1205eb830dc4a78fabc0b80ab1698ce5fbc7e96abbb2a629b74db6488ff4559050c79b54da564e5305e21b10f799cf54b5e347b432ac60021ba63e53d0ada9e384dc2cac71afc203e2f180773c5a510030765143a7319a2bcd86513238227c10ab23ad11fa8f5628e27a555d548309017f61a685ba17ea7f5add012607a1e9ba3ce8f4999a6f12526628f7ae8ce0e709867e7c550d026ba9728a9d71a31cc110cc202d9dd4a61f091cb7852730fcb24b491e079198a4913b26c2b0f32deba055cbaba8b184b8f4f5a90900e8942e464ae1e00b52ac29f3e40b7704d9d074ed8dc368e08d46954a53ce64e0f3d99daeecf4af88acbfccb9a7441958494d18cd0e3f3f2bb704815b1c595937852a7a26c058665297d195f41b1cf3fa17a3e7f66213741450116e043025b6a56c1fb837c641b00cfc259b17f47b367be1fb6949582a0a0f8631f2bb1fa63f3b6f089b3fae8acf289451ec8bc2f7c832b5c29e415efe905d3aa3527b5761b4473b480e00e244d990100e3e88632491ee5d7bbdfcd69adc481a15098e42cf36694f5efe0882b005c5a41903f0f7f905296c1d3787e00282f164c2aaab966a788770263f095adfb748fc416d63043e45fe3aebf159352364de4c8e6275039b1d6a2e124280a03f5e6d26529d855f7aec10f8ce40afa49054606028dc465c9af853b3145dd61d875a0958a521a18a55f6d286e60d160b83f2cdc27b4235e650714ad9c7d00e0c347e8071a1927b880596e745354b28e82ffacfffc3a59a006e236586cbc74f1fe1d3cbece560e7ed8fd1fbf98f0313d3c1c0d9d34115e38d07e831a8f87f01b695cfa39ec8c3ca4908de6abad71b9e3b9c9c24e05358589708d413934ab1bac654ed9e05c96f3ee89b8070c022d6d61a6f7c55592e8c7565323c1bb0fc3e30781b485090d0757decc9ac2b3d09a1894aa213b74d18b588cf2f935528e8053a94f940fed7a03042a109eb702513fd9b57d467c1a27f27d9586d09c337e34fff214cd8cdc6449dc220d581ae25e2990d8e407a66026338b64a1842d57c292d466e305ecbb87580584136b28b3b8b95f573e723498e2a4b4313e0fc3754fc9b31bdbe7e1237f30aba8b6c72b66f3cd4bcbe2e01ed602c88bf20da00410fee28c37def869f5d06563cb232bd8d245f06db57deed11d1f59849f6b2ec8cb075e4b9c76c48b8ed47a1818884d306f2734aa8389c5cd28fa0dde97c13cec3c18cfad30cccb11ed9e213c79b95124ff1297b308cde9ab4ca097a0fad72e480b95d06784e572752ec1d31e0297326dad5725a8c0de32ccb4ba5d6f2af6f0e0aad26e0df52a25eb01b054c8e62e68081bb606633821f73d84c2d02df1dbbe98a22d453113448873f34e875d329e502a743acdd0e6f3f492f5874dab25d3c9a13b9237ffcaafbed1e071443c3b9eaee983586663964538018b2e12053a147584fb5fdbf5e51bea540c912f75cc332acb2884c1a3cd192b5026abe19e01724d8c9429b6450c14f4dbe59556c33d4e324345c14af86cf84c17bc26d1971752687f1f535065cdca38b7ca3a9b9ff6986b4f4335f0d1bdcaf6bba96482bb56384b727f5ea82b01ab96f86ce556012c03f06e4fac0e551a417dd43e9488869d55929df97404c29da98ac4c1d4952b0b25294a3ad89faad5438026399620ce36103497885a595b3bd4a0d526a04480dddcb233f07464ccd0b1e362a01365516deecde5ee9e28b329e2179504515b1930b6107a437a3d65a866f206708c879d88682c74b673f2f1dd99d24908c68604ffd81056a82a2b315b8abdc828a735b3e5a6e3dfe66e1917a628017a0f2856fe3002574b3c5d46d5f5b48a971a9063f1ae592d4f456f7411544c103d578b3d82be3a40c90fabead4c326b2e359ef86d07bcb7fa31ffa43b6bc96dc750aa05c4e7b3b4a4448457d806f9c8df1a5b0f53833425ae384e48bf565ebb45d119414456350dc8bf033dcc31663b2e0fdf523d8406bafa2010b2002b82823f15af74a3ad7c4c3e87fa4e03b63ba54465d5af2ee74988cbb32ee29365ff2083e21d85da37efc84024e6b51b541f8103a3f4eab92172f527d12360c74691acd3e77f1106849b51ff7f19a932900b531201875b719acc448b6b792741020ab055262581e78213a028d13c3d901123aa2c8ab098271374096ce0cd3ce108ee55f5e145c1f2a60157851359b7e5308ef576f08e3e9227233e868220ccfdf6ede96b6344f3541a141d1044791d8f08c30773a50df496cd3c4ef93e014870475091b88e36373e984e89994c5641430ba57bd7553582bc42ab21b88e179354b733c2e6ccac454b283ef2f350e02b0cd887fcb8bd9e8cdc70ccbe8024598fc03ead9a6019e866a41590211ea6a1efedbb79433e6020d83d6f690624e7ed401d6e90384a1e85d993cea9f83c199e16e462be0f383150186cb789dbe08f7999985d028b0b328708fb49bac9309f99266a1977b450abf80e5e59990f0690ebe02916cb5b2817982e40bb403afa0cba3a58f81ec7827f61484fdcf27d1169e597f2252c2188ddb984c8f4f0e8514f1fd90aff02e878401efe45b92dfb6ad4a317454776067fba0ed215a01e9238790280f33bc782272746de898dcdd85436a30814318ea9410618f35cc4877c7cad245548eee207d8225919594a024b8afba397e6d689bf4c15e87501e923e810d234799b415bc869a13fe4b1fa4deb99234ac7f561894783a90e447654df6faf1d98a9877f61a148aa1b2ba37d2624babcc86cd63497393681e70c67bcc959407ccc0600dc1f20f8770953a4f87a539206941ca30f24cb7e9d6062f8ebac08d840688818dc5ca9f98054a25af61310817e05765198eeb76e7c86487bca056f582fd1a39671f70657f1f59ba5622000e5443f6a3c442eb4315b6787451321f0e5efca5d19bdf9d0897b2e71d4c2a7095c2a13bd7591e1f55e7614d9deda69170ed7d1111f2c6216d41e8ed050bee96c7cfdac1318086c2915b955bec2821441269a2ed0cb5b114a82a416a5e61e2a3aac6a16af8a4854c242cde70c27ac553f4e939288e5e85c7a1ff319e5ad040750a69ecd917cc87418fea409359f757f46a28160fa2b457e99fdfdfa8ea7070adfac3eb5edd733c55e929ac8e364470da2ce336b8db6f55f3276d9da172c8a1f397bf59640307c2679060b7a183a6c1f4f1a5ecd19bc74c82cb7883ac9baad7a4c11cae903186766c33632bd780681f34bc6991c0233310b9e8ef70f6a946bd1186ad330b1668bebdd19cf5861fb06f4078f5fdc8df7d4893f208ed8be7a0050a5fd52f76337581ad61b9a967105e5cea8336efb52cdb3127e0d3152d4d1df52a94cf12a23076da06c5f63c9e725a5c23fdbced24fc4c8af680a56196dac59d8f2095124c0ee825b54ffc3348b5587e075a6fd6aad72b19a40aee821deb17be888fb4c0b3eedc467dc76481e01a506422bc1f2d977a98160923d3a75300934132e2184b80ba5d93b93fa5fac96db9eb4e43057bed1654203c2f3f2baf095fd335e970772e52e69418d363974d82829674ba0a3c064fa407695fcf82f1e691b6297df41d5312b8e67adbf4b2404e9b66e747cd3aa25abb9243111ee1f82fe560dbb4bbce29d9689f5f6da7e59f96dc046a7f7d85633b7210e684a767bfadc5ccd200f5649d0985229296971d5acad8fffdc2c1afe5b8627a8437e16f754dcda395d1f49ab7189988e3bd9fd26618659a50ac43b1bae60fc304e0c02ae1868cf7834bdaee9a5c7fd0cc6096eea06d17e85ec997dab35352eb77af98236451ca72018a5aab42ae11b02fe99ed0bab03222c82022e1bc0b2b0267f7572e3f8c4f6038e82642b023feafb046d7fd3c116be8fd7da587881c0ffc5ee8796613ddf4f82df91398587a629961ffd65da28963ed2eb25fe33962bb4b86b97849f434d415a21b473e6f0c9257ece9bd99ccc9cbc2c04da63a093a1cd6840617407ee5ad5a84dd4296d09ed2c52ac376e4de4303a4e3bc4aed34aa1aab836386f7a6658c3494b9f2dced9d9a96186b89c889d20a985266bb8aeed13de92a03e903cf33d54597003e49fb427172f988ce4aefff334f84f213eb76a2ca398b8c1135fa2d70f74f5e52a695f9d974c3dd69f8c473f5094dad7fc92e092cb212374182639e71cf99ad2fd4c9b97dacfe3e367ac6c5438de6169c7cd4dec5551bfb1e06be18cfa45b146b08bd3f47a6f105e54496f5301cc358aebb03d6ea5f7919a293cc41fa6c4305a75379eeee9080c2b402cfdeded5802e1c7d0e3dae484279350e1fadb6206e12b8c2be0041666ccfa3a927bc0267371cc849cacefc73b5ad89295708113ec15cf83efc0e76ee14d252ce68b2072b25b8814c2533c9b387e344dbaa3aed98fa6e886061ba3afaa42c566ea84e61d7ee0a9e1c3dc5eb74a5d818ac0356675715d48b9492ea2f7f18be5317227d7e0bd8163eb2cd7cf018379712ba3e23d47afb61c270c7c4cd25321da3669df270526dcff1a489fe1db9f313f8abf0e3dec5e7ebf5b01693499b011fa95eee93e3b471506597d4f4ff37e0d2bc9f1dcfe9b259baacc350f4d6ed4bf7b891f6d5500441bb3aa3a9fe7c8ba49faece7be1489c463664797ce8e279a4464162c22706888345828fe810774e4f6b38885810a1146e84e845bdac08a3eb5f35fb9916c73b0b1ef4e3e4f4948d3272169977558048fd795f11c6519b8b63e2d05d354d24fed29f7be3fe302cda5e24c7a52ea7d27b4f7988375d48b66d4dd0fa5da3efc27b562ac95d895ce51ffa7715566af1cd69f7336572ba4a7c5280a15f3373635aae65f5201b6b676c86dc124d85f164dc759da2d5fa4efbbbc5dd1c4f91413854a15876e3f748d2715f98068581421b25f8ae29ad78c69c4416895bdca8c46e03aca97be88e2ae480449c2640df963708162b07b6200297c07c29f051de67d817d3988db1a879ac6167ddadc78b4e61b831095e4e309a7082784d6afff3ea16ae3f35cfd7ff1288067ebfcb284b4f07c61e6feb52750c79a069a27398f4759838e6117290eb37fdce596cce00814bdf6fbdcce3af8466de3fb9da66b9d2cf9e09bc2983c0071f28ce3c67513f8ce561ac395ae40a1d7740c6545c667f94ab2301b361dd6925445b4c558d02a2b7503d6b185a5026001f7ea6fcde53a88e6f9be701b5280b5fa57a98abbc6578cbbbbfe9183ffa71d3de546698ff0a3dd8c85e19de7ec210443d5e84c0f774fb699c25ee8c20210c51c28f001037289f6d27f312f5f45fea8006b110f44c100fed60034a299e4b9b35f216d905418041a35b26140e196fd72a06c77f61cfce704164598b54f27b9959723aba4b8b2205a086141877b223f1cdbaf25f172565ff9b7cf077cad9163b10a1b68809ffa3fde074fe796546bdd39fd8138c5c8ebb503d69595cd968995113450f87beac4c6fe2b66251029a43adc74ccb5d5fe21993315e3434ed13f2d8e81ed7dd60e76fe52f347feb704f036470c720c28b965fc656808c2393c0b6a1b517977d54d17dadf34befb4fa25ea6c7cc0a12a4cc00aae7a174b443e483ea686f414049286f627a3aca5589e935fee235c3518f8f0c7c20d2319e8667dabdac051178d4a4cbfe77ae67cd2ab45aee7dd200ea90920efd30717f8bc367b01ffaa0a6bd3c0d8b8bf8550dd81ecd80ab3d1f4a248d2a527386223317471fca78cf6b619ce7e36f052882ec1dcd68b212727de8dbf39bc9c3ed0226a910bbc6ffe5097b28a229220a6382841d653707fbe69e03f6bbf280dc353d887b88a093c403629fbebf695022c720887bfa65772233ba09f782c8942a90cb1dfbd635c59390297111e4e646334a669c5e573f2d1ea120eceadc5da012b584acd9237927a702ea2f97d172d4f8fd0f900e6a1874800bed1ddfd771d644e99ee54c58c5e32b500b8787e6fde59eca28b8c114d14f834c74a1f8546fc3d3bc745ab9b423b369353d0b73a2b9c9c1ba3839b3b91a557fa7173fd8ee029698c59f0de3bfdd4fe0f70714aad4d743b6657f1ef7fe7f1e794d2b33d068a89a04d8051c858f90b14f647c5b1214e25ee8b68ebc1ca8edb6e386dd18ce9b45fae10e1111317114aebf4051acc57b53fb8812c68a8d00deb63f130f05896aaa38bbcf6f563aae9004a3eacf21874f74a4120aee8380ad2e459c28a3ada04ca520391d832e2d83e5de943b110679f3a096407dd3de0ddf802b0d98d3c1d82ddfbff4e7f3dfaf23a888e3b917ec717028395ce7372a8f05382201ba57d1fdc37126be791e2f22feb0777d4663a940561a2c457d575fa57cd5596c99abb3825d187dcc7e42cce4e7f2f644b6636cefb479f7f9012b7f0622ce5fc033c7fe846f076808a11918afb3e4355d223abb820c741f03375303b94613a16f926beb660ff832f46db3677982ac8967af136b65a8f5dad46a506485e3cf24ba69791961704161eed3413c376975940a190d2152e5b7f3cc7660bd0667adb8063a90d72da36ea8017647547bf07ae857f5b36d55e23656493ce74b4059a409a71b054a8bed97acc3966334cac1f98706240204f14b433e3d261a7b1d08a6d73309bc9fae4a3451991395ba6e565816f8ce4e752c7072d440a41fe121295398de1760865b178e10515e3cc3608139eb711df2fc9543a2287791342a4ee66ce97d4967d1b200f549fdb3a43479195541896cb4bf5aee709e8116c93d40eb0ff3b53519bdd9818bdecf69e7ce0013a4115715ea341b746a4c0260d3faedca6b0b89a3a55c7080054764d4e7147c5193e900b7400735e040c24e0f2023266b9f33d4d9d4a037b742a07ed223ff4640d512125c2484caf71e5439097ec2555377a3780e788f266d9058c33919017843aec43710e98f204fceafa42f6c1d528df1e2ce2084958060c6f078a4db164b9a4eb7c3e2ca2bb35ffdf49b0df7740f21f0c80e5ec59367c2d524524d09f32529eb4d3af8dc0f08e65b2277c3f2fabe23f3d347d8e3598a110d1c66860b2147e1e851a07270c4b052460c32cf4a3381f13e79b39ffe91962da126af94c9bff80196f0fef0a525eb4ec9f2b63b76bc2ebd3df1e4a3467fc88c12cdb62a24ff01b80eed8303564a02463c0989b52f669f70c37045823d470b8602fad1a40681e7b23effc6241df80b61be2369bf1580f260a414b5c87343b26e8c16fd510187904bf8fad3f5b1bc2ce905416e0aee0f64988f6269250882cf9dc832ef83b4cd21e035f7ed89c11d351c9a2971f5517c515e88eefa5aa76d65b90c5752550bf9bdfd0e3ba634129c3c5af487f11fcd480d82db932caf0fe43defa070a5a4a099ee2ee033054002cf5a4cfa7c97ee8eb9afddfc0dcbefe3a8f56a9ca3027669060524e79a6ba13c3eedc87cfb051346b8146fda85329ff6765a983fe848ddeae3048aa8911f322580e5a7dc36fec224d47f15a324e43fd4a091c691c28f79828c20461c14040ad48a9059305816a503f2460d49daa6f7c11696a91b2ace1fdec5ca0e4acd0c517debf1827a4a560c79d233ee01188823eb83f6e31fbf2120e805054e012fb5b9acd453c1ec3e0a9eb42c2fd3a71e37b3d6882464efbdb7dc524a99520a8b082f0924096ce3f2fc31b04de9b7ff0e70f90bc03f7adcd45c8699a91835a697edb1593aed47abe99f085a208c03472317d2f3921b3f15395a4d0f84505115284d8458b2fabc6b6a22c4922ba4be4b57eada51f1539ef76f32d5486986d5ee5372499fe3ee84d25a4da67fcf4947619af8a4e824eb2d7f01763cc4ee6b14dcf859eb8b17b232277cd1aca2254a04ab387b6444a21b185525ba0437c227c2aa91c58151d3464ebb1fb7286732a83097871899263e864512f5e3160fdd4d24953f3b69647b0bb0ca83a898c528dcf848fa870f3407c6f1c18403e3c88f5f01b6a11fff48ffd070ae8f6f3da83a0263e81f9aa5ed237299fdb88b25da48025e82bdf8f448fc4863afe0466ec59f338051a7d5712fc608551bd3f931c79d71fef5eccd39d342340c596760589504a2f8474ffb4892823dda477c2c7ef4e6523c299aeaab3577592d05553d3c444444695c807dc48f11034c13ffe32624619a780315d5488f7bf157c840cd3ec5d33f7ada477c9389bbe809e34699e44d5a4e44a41425da673dd9fb50b9381ecdcacfdeb9202de9921d4c7630e91d4baabfe60e37e8313a6c814629c76fe6523691e88d3e3f66dac7052ea55fdac1a4b27b2ef6f3b9f4b5b8757d7dc7924a5feba6ef14c228e3c31bede773c568dd7a2f97872e9699a664bf24977eff88c1ab24fbd5113733837b300693bbf7fd70778037da1c6d54fe90cc5c223272965984069fe5535aab49723ef25316f56b2b577e3de54a2b526c2f91d85bfaeda5cbcbef2aa5ce887bf2b7aea7bb0148922c27b9674e015c6c270de49efc1b3ba8d98fbe81b6e81e67d93dadc76db8bff131ff5118d5cb5fcc46476d2fb76deb71373bbfeb46b40d712eb9d0d8f60ff9b1c42a0a51f1a9cdbb17fbfd42ec42edc267c906e055fff0cbb4bb18e5d1f81ee338d3f4e7a1d806e2a061fe75d94fba8feb2fdb3ea4c52105a5683cc331fe57af9cec45469960a49561e662988d8e9a636818e39c6aa8cf3d03483ffafed6ba5652259d6a7079ee8bc0fce874aac1e5b9e781f9d1f3fdb970dbece95443e9b9e789f9d1dbc02b2641949efb20627ed45c90530da577f922257bdabe74d28ac4d8d3668b909494eabf3c4ffd17eb43457b1f97afaf591e5289b91d262ed6870a8fcb97de06ae2fcf3e80eb5dbef4fe3563b8d8afdf6342e8676fe4eb217e3d3414961196e632073d7a7818bd26f486a2853806b7213dbfce0c6e537a664e7d8c35f22fcf8d9cd47594daf5144a6bcdf8923aee8ede2c7bbea2b615292addec575df8650d5cc76dfae9477b3ad5b03df745467f03b3ff6e341eb7f93ed3b4ec6f80c0cfe93182047e0faeba2114037c1d0dcb201c753f2bee7f5640dc8395079eed39bbd9c02b1db8d91c1f007c5e610e2d1595dda3d67fba64cca5131a1fa065646ea497c43ecbaeebea2e4a4d1ea40db1c3184e5b2adbf90c2fef27949ea394de5c8a7d89d48d3a4dcbb22cf34dcbbe3b2dc3fec22c4b8f269899f9e740154a6b894f4eea4e3e7a9ed1e85fac0fcc8fdee7e549ffb3d26a77f25277727f97fa31d607e6ebfbbc7ce98847edec8e1849a24e08388126a1ee94591e785e1ee679b081573cd8007f87ec6de095cbc3581f9f9f950e1456cd66f918cb2b98b7a71d983f65d6065ec1d8d4cac57ed7e7c08924759dbe5f3ebdd4f1aa76bc2219711b6ae3cf41c85e45738a452a85d16b4af786c20a2b806c5a86d16b426f247c8c1bcbc8fc78771037373032333d6a6a328c5e53baf715db651b8625faa70ca334cba80ccc81af33037c1ef833f0bd0ca3b445c506ee132efccdaf0c5719d79ff20cd72c62422b92a71d86fea477f9d38ecb9f6ce855e94f455625fb3fab51fd6a3fd2e8e75e2fb3a4d27f7e8c310c7b86b0ca0863f04415517c981bcb9847be6919f642ae2d5bb6b461c31f39055c9ba9d248230e3448c37d1b3532a1c243df1d601bac2bf935eea8fd66bebfac0bed3c11f981757ba0173e7f462e7cc242725e14cb8000c9b0ebc7bdc1000244757343afd93df03c39af99197a4d197fdc3b8ad643d492c633d767d9c32c756fe0f82ccb328f8bd13c26bdc6dce8bb23d92fb5731996f83f6ff4fdf57af8a774a07f8fc949cdcda8f99db94392bab687a8eb2b0ba1761bb98ca2d55c9e7fa9a82a7bff1e32c398dd8b3fc81fe87dc557493f320e7c5a03d9356b3e1b172e818728855dfd7ab8d1e7c69883da3f82bf74bbaedf5ca575596cfb23a8d35205f81a1ae754524ba7bb41a51fd4b1419dc1a57db40f7f26ea217aa21d9d19dca6a18ef6e1ef704bce0d4ced238afafdf7a0dec0f3c1ee3bbb8da8c76d3ec67283c9543dc6de41c9ad37c4a836fe31b84d9b4c2c1d45d4af9a58cbb2c630da5996cdcf4e32649f39d76599f6cc651af69d61df18f69de6f33dc1e73bbf7f7e6f9bd6652719605b1ffc9da35b859164c4fe90c48e59ea4efba56e64c991be1b6354fc517c2ec6974c13396b993ac22b47fa909b3b8e2285a8332ea4d18778e10ffe23bd8928d643ac228a262e57a106d1355dae420da1abcd8d8aad52b799736a327e47db9f034f50a532cb94aa3019a6653d1cd146a4116544ac1e5f613a355373a660ed69222d510888a2101951374ac9d0b40c4208bfd4d58e348241240bf58854fffa7e97eeeb9503b9209ac6715cf771cc6d9ab669ad75d3ab75f7f5fb302f0e3ecc8bc3f51a65ce24e3dee6d20b8eefdb2503b45f920b3fd2adc298e6d53db7e95cbfd60da7c5410608c60584fa994c8f6ddd551847f56bf412aa9af6d95fdda7b19643ea6acfdca5659ed1ab65dd977d0ea98b437c987539a4e86557517825a8661442088f5c11218cdf18c42086c53859e8daaea750c5fdf526a822fd75913a18ca6d5e8d4bd858857d9c5807e328f818db4a837a59ca2b2c5169d462a4f3e1351f9e88f80cfca2664f214c72a1fde80ce0d7f06f866118b6759122b9f39b5252f4895009245ae7cba9e5f2155f984194032713b58c101a11bdce06f5bbb9fe566aaabbbb7b8ada2374990bf2566ebc1ed7ad855951112c9229698b8c7c84ddd9a0fa5ba9fe1f17b5cdf7503c0f591f640955a1d5242474bf2b0b64614ea06ab2202a42b9110b9a72b5645e7c980b6efcefcab2a36981a80883fa4d4dcb8d3f599355194ed68dbf234ac52edfc089d01d627141f108dd3ca8a87ff9d2c0f7cfcb57d608e2c6e7314585cf438a28acd13dd078e693555a1746eea018d48f85fa892a04b1b4206c412bb55fc0838aca97af44410dac9abcd48dac0285a75c58c19310b0d0a47a603e6149994058e124f017ac2c454d60c284279a587914ae7f8de222faa9824514222d2d289cb8c2440635c0019117b3ce14c040e3410aaa002209fa53646967a235c512ba5e6e4d31c6c52eb7a638632ee1964401cae2074638e2889567e00b368a5a555650831c1011456bb68c52469413aabcdc12a2410b51849c702688105b422a9861e880460f5cc084222ba2285d6e0941112a020241ce979fb4d5e553f9358b269c70a5fc198f16492a09130d88e81a0c31c485156674b9e58328acc009723425891478a1c5d009b24c2088b450e2074b10f14bb2c052ad27435c78b9f5a404330373085f620330890c942e7c53ca035888f0f324063e40620c278e085263b25670834b0bf9de9c5860190209126230c61a5b8c20011663e0e00acb77b0022e8eb82e27818b9607d0b8dae5561223b8dfa7a4179ab713ef543a33ec2469263ced7ce3369f0a08dc72bf4dc53852de7a250a625c1cb77a97ddee76e8eb4c033f36a1ea406666da1d8bb40bcb5ef38dcab95ddedc15aa5cb4bf6ee6d2c138ea9ad736394d9bdc77525cdea53341d4f59adc3431aa76dd8cb445bddc26fbeb395bddbbae87a155e15ff1da6a37ca344d7bcda52bfda8ab245bca3ea3ddd7d787783f1dae666d0ff1cacf58e8d22b73c9a28114d757dcc69d57d362db42125d8fb7ba0d13d10008d7b3d0d80b26975b5d10e072ab0b2b3709f44117f785cb2d1f44b9def6d98cc63b2e8344bd5e931886595ae5c605e1614acba8f32737445eec35312a256dc184228e0b82618df110ef11243dbc9ef934db360c8b379bd0b351f6b48cfad55c49ad8431044693fbe3728b4807d7c3b2e36661e53211164358586935717d5c6ef580755b5f64b9dcd222a8a585932bc513222b54b4b0b4a6bc6cda18350ca1fbc2e556184eee4d182c30b4c46ced3736a216308a89a2a0445554a22b626eefb8deed002304444caec96db8d583347a6006902cba3352ccffa2890b80cbad2f987891c665e172cb0b2d2ebb4d0a5b771fc52e04eec428655a7344cd6e6efa0271ef86c76fb0ed65b820482ec65650d3e5bacb7a7c3b172b3d89e3b867ae318c7bf7b8cff127759fcc2565309051b1efdf3ccfbd1e34602f93511257847d003e54faa998d83d17b82018666a1c9c69078b5aff8b97f437489f034725faa4cced4d7f4f8f7b2cc3dd998c2646cd300c4686de7284edb84d66638744cd7ec4da9e3ef6c17041280b580f0cc7eef180e168c85e875b3d381a6e68b820a4ef3b391ab2b7372f7041483fbb9fcb6e43b296723464efbd4cfb7976db60ed788897c3be2dcf65a6c1be2fb533f0509da7dcc51e062c286b815ddc90ecdb520cc37e623c37dc10eceed434e99e59f36c2b526e3c2da37e3757cec76c534a7fa326f784f808a1769895916f4fa0d27bfd8672f98bcb2d2eaab804b8182764be96795e4d0dd6a3e6eb713d0ec37e731b18c69118751bd2f76f15a62717a473903ad2b7979e392f35fd18a71f439b922aa97e8d89e962ca9db9dce24204976296ed377aca29a0ca50a737eb4edcf315261405d1ec4906ece963f6c4bd3d8d9eef0e90f41a471fa3db69f4a3cf3a24a30eb39799863ed67d29ecfb3199d49d76c6bd1bdde584c56245b1cababe64308acda069d42dd63031f9268ce2abc3c51346f1fd523a5c848069f83601aed61aa715f5b071d7a02f5fab8fd9cfbb18d0165d5c9acbad212d9752a1e532110d9e98d6b032a58563ebcea75926c72c05d2217194fcee8eb8279f0764c02b81189151b8f275a070bfed7e3c04733f1ef28e6ef176908cfe00714fbee7d5d4f4a87949d57817e769cdcdefb6c0b443e2cdecc634da0f89b7ed28fbfeaf9b1bb245f7346d76231b8d44b20f8485961c0dfdec5e4c74d3cc8ccc0ccccf984c2d34c60d696cbbb98921062031b8e4c47013b99b1e82ddccc29045fd642ec66dabca588692b80db786547025bf9becf4e830ce842ac85e3ee16adaa6a3c3c3f333f04851fb4bcfdc901dcbe39eff484ec7bdc805e9b1359765432c3704dee6283b8e4c4c83bd10ee694cf7c120e9993d86eddcfee6b9d9f76b5927432404e532d11466dc7a99688a1f5cc62244e6621b0c523037a4da9feb0f611827db8128f9dd3b5095044ec93458866118cfed1bae7342faa74c872475373bd37ddb4bf7f5f880dcbc97bac9d1d951f18ab254cc758ee55e8d769ecb9739a2cadcdeb62d320efb371df9b8a75ddb75514a63865858a8c609d13ef3ba947bf27574a0b6b4a9aede6064324ee9fd4d2c73b7d7816930f5291629a5305968a42f94d2178a75497cba6b56a963a6d9dc2ba27e48646ea5dab6e1c802d4dcce713a9c2c09e2b849c905e976db4cdc93929503ca57596e531b4afb111d90b88d3b71c20549c283ea0f01b7d97a6e30e2dbb68dbe63b8197e6ee7b8cde8e5c7e03693dbb01386b59452a68a6c6580e8ca211fb7e116104eae7c20a8dcaf9bf8fac9958fb5c7dbf2c1930bc3e5561845578b1c91fad4a9b3cbb847b226a6c9b2ecb70e89877141bacb76ae7fc605f1a75dbc3cd63b24a9cb29ba318e0fc72a258c922fdb7e321c1723ff8b49e29efcce89ea2f547207cc40cb1642b707781b0890107045a5b2986480b52a314e015a6700310d544df93e3ff0184e3061ade2fbfc302d15f83e3fec006a22c54a5a2afe3f9c90e0240aab68a9f4ff00bba7bbbbbb9bbb25d3305b33d0284263e85ebe8246153097afa041e52a216a30714a64326e702ff6304dfc1e8269e23ccd06729b18372b56b86a004f3aca57a144acb287b8f163931bb5dc6fbb3d04e3cc797ba02ad54050c580f9f282ed610c685517d1a8f8b451f1dbfbacd5a1c3e57e0de4d240d9fd98a853b8299864ab6a1c151f4866858b8a1df5e9b86dc3eed9fbd11437451d5a82151d2c97c8029b3aba74a3971df71adc5c84b809aabc99fe3143fb881fdd541fa6bc51c9ce10493656fbf9e5712fba1ced304d7c6e8afaf2a4d7a24296444a4d6a924f44462f474f6464a52881f997973d2fef43455a986abfd14bfb1d692ec8e8e50b67bf929c82c0ca932f6af6f1055a7c0d08e3909e5f875f98e8729c139e7bf0fb53504260c6174330e2076aace07f12f5a331a298c62f147d9900d195f642dcaca85ccfa50845bdfea3345c598681a88078afeb3dcb32bfae8797e501cbb21f825c9d0f7e31c62c8c9b7b1d8ca3b668cd6235fb88b3df79c8fc877b79f7d34b86a88078331ffc660c337b2f8e645cc805d9a1b708f99f7b7549ee9675356754aa79ffdcee7a80dde44b72e35f5434fefe1d30a8dcddcfedab76221dff41a02a56b447f85b33619c7e93cc9bd6e034cc30fda076c15ad498f821c0aa9fe123ee39048c98a0f6efc06afc68e0be76b5fbe8b23a308d3c03890b8d647152effc9ca2a09f73e67c966b8822212834212673ce391909ac1b4ca9c22ac210583810ac882d253cb04407a49452b2e042621221a594920821823099fc1586c604a65d6e2da16289152d084153de4c1ce932839bab73d30e4302872e5fc07ae372134b5b7ad069b55a2d1aa79cf26504f5e316141d776fb54c5e8eec3c881a39a1b5d3cbe436476f416186f0d84eafe8b4af1ea259d0dec1851f04a1402743bd03cd6196805e58e1f5c743bd1399a81f0f0545c9d181aaeb31acbbb9baa11eeaa1dee954efd01d541fdf990981cc936ec26468c883a8388b70b0019310a310810842601d6c00160d018628832068af92f04fd22ff767ff588beb115a71dd9db280b852807e35ad8ca3dcb4c5c4ee43d0428b085fe8dbbf75ed4c4878c1002ffc0a9a8fb84b957697339c5e466e1eb033840bffc3b94270e749c5d2156239c2de11a8a233720eaa2a1ed94280050b96200e64a1290e409287c1e9bb3c2149bbcb091c1a01bd2f6aa47fb4b310ee13d158a224d1f2b11653d5125f9878423e8d523fd6f24510be0c909a9afbb1961b8ce4403a618cd02e1731b61e333230148608cce5089cc9d832f68b0e3e2ebaf0a111f814c6ce2463cbd84d90b15fa8162ddc6be92088824f9b35a596244ed4efdf29a5f0af7f9d2450e55df65dac549ac4b3e2a5303d519bd0a2458b162d579a802549171742f8b109beac8d10cd43a935fd27a07f6054a856415a523fd306eaaa53b7673810b921f4d239a590decd795d7f79b2ebe109cd34a99fc908f5335d77db6148d4bf9f77eb90c4620713a66a6194f34a82d218e5bc28966914ab584629866159a66d1bc78d46a49ac154227db58d1bf568b4916238eeb71189546ba9e4e2f2f2020313c3059111a2a670828a0387c9044d2693a9965c60626e4478c36fdce81ba5928bcbcb0b0c4ccc8d1b26538e6b4aea5293ea1b3f986e4c381c070c4c4ccc8d1b3870984c3972e8d0b163c78d1c384c394c39749cfa9443c74966470a9d5d6106002cb4e0a15ce0d1a3c7d643cbb01e3d7a6c3aea0623733ac9ec484185ffaeb3768515666600c0020b2db4e07928940b2ef020f1e0c163c483070f1e3c78c8ec4861c78e1454f8ef3a0bbdad9d2315989dd9f9bfeb989979054e86a8020b2d78330480112c1851ddb6d082e7a1502ef0e841e303a3970f1f53fa88d07db40f1f3e5868c1f35028175c7081078f1eb2478f165af03c940b3c7ad0a0e49cd2615c30419927d5ad0b1c91be3d54b0525fa83406a18931c2b8bd20534475eb23150001c0d030d0d0d0f464a1a57604d0c44e53ea2f4e48b576f0f3217c1d05b043085d4c103d14fbb8ac89c7b46cda0183eaf282faf1d0ced0d0d05016cda1472882ee7403bc4cd47ccf347acdb75150cc8d989f4153b02a49146c23ffc6cbcf1903f3da283ee98b8c1e3e09be125237e1dec9dfad40d4dcf120889a2e7467cfefc4a8cdf1475f04fe8b55427af823ab840a0fc9d257c2308524ea07d52fbd074155a985588539d1f532ae1a9182b05041198c93cd3bdfb340d5280860f0c0abf028a8b7c0b55c9aa983e3a70e5425390255386c433171769b1ed3311c754d0451f349dd7cd9589ce5ded472a73371d4f4a02677ce6c0605050505ddb933fa2015044d79a9228a4934499fe32f5d5771b1429a329af34b9dd441fd3cc8a3b8cd97bae236e1361f5fa9122528ca6a742364481097c6c3863e83e80d44314ae97f24034c21dcdda1b7684d027ff83b3d146015cc04d826fe02d440b1d70fb91a78355f8b3fa80b80377e0ff6a633b88ce8232957bcaccfcfea212a7632399dcc41a5514606be3ff48f1f87a40fe66b0f5f4a7dcd1d0c5631f7847f869771e79c139226e9739c3422b19063c1e17090a036fc18db4ec76243afea9b60ec72523b5055faf93f02aa71554f9973d6e0ab6a5b0b44cdce594f1c08aabcca8c325f9b92cd06a276e55560155877ea8477be5b619c22a88a6fe241c5825671a7c6927d24a53404898afcacba055156b8379f347fd4cd975bd4cfabdc6e5d2b6ef3e1b8f3e7d756dcf9f3bd8a3fb7c324cec7c13393bad684c65544612da6ba4d216610f793b935f08a096ac70b2adff95feac6eb239f986f7c24442e50a2b8aa003db46125b2da38c2fdda89e6644b116df3c16c3d4666701b6825063789fbc9780aaa4ca6f89aa9b6a03244c123d0623fffea4e6e79307bf213cff51462d863cf2b2a4fa8ee04edce1188e215c686ecc4a81db12098213333d727b5bb9b075a4e0c53d2bf28d54107a8468d393ab80d5f2918041c85d99c2c4e90a81bbdd839295e161887e03e10830b4c8c1f18218740c500aa720835a057d890c17db97c850d297774f90a1b4a18418b9bec4c321d17449d7115fd7adcf8f165fe8377dac89e64f624c3bb83cf9d94ba0d845235339e4926422168d7f5542c503108e96bbfbd4eab590db400d6d095fa555335fdbbfdbc5a83c6f0bb9b7b98377b0cc3be31cf7e0713f54b5d8ca35c71ef9cf5f961c57d8e675d0f06395035ceea78a0726bda689d00d1d9d318994da5eb73520b600da5628c99fde0cbd3c8fa6ccdd1906d4fe9e8475d6454fc4c067a3f9f9b3d5b0fc69a5e4a0b0002e6e3a108bbcc651513ae818529a7f90f4fcb8fefe3a7d89dda9e6a80ef5f24beb44aac1225fed002271afa29e9a1dd81a8f927cdbb93664f0c900f5fd3ac0f0bfe0ff195a4a43d69f37f569b3d6996071ef9dbfc9fd5cf8acad0cb27fd977a5e916c0e0e2719fae989483ffdb6bc92160d2a27227de9f7a5f644447bfad4e2405fb35709159ef8a45772d2de2a89f674fd4923d9d365315b44c6f7374285f6c045d7536b011f08e143fbc3e8e147ab0344cd6738e1977d0ff05e492ef673aa21f28c3ebeb4cd8a3edba44ada096cdb411035e7d7a021834ef4e5a9066a79e49f78e25fb6ab448e75bf168aa27e9095e33a6a8450b975f97e70680a54f52a0668c40e75997250bfd8795abc15523cb1c216bb16b819cc6cb16301005bec00a095a07e94852d7633a4245ad862b74266a57e3176b6f542282b958b6e527f1b680713ea4763a782f6248a4381414d1cd58437c1638bdd8e2b3b29177d618b9d8c1604510d3482fa511f5bec4edd35907b4fdc6b92da62a7e3ceae9d74fdc45103a0976d2088f214aeb4295cc805811c6f95d413d032cd4308614321681042c834d43d18a78410324fe9ef90f414fecd5950598a00ca08a10cf54233cac0fae95fe1cd1ea39cd7d636878e085c18c39ecc21810bbf3df93206870bbf2b506fec16a31c07cc3108eb978fd3598860ea7672351216da404848a1ad0d40b91f674983d7b8bddd0b060927eef5f17a0ac4bd9c105da6a93a228b4d76a3e988a10bb3d48f7d84509531704be2800563a8e1a40652ca78c14a422c57c600ca957fd9082f74d03ae204373ebd62239ab1e2c65cf9b4827165cb881604910f85145bdbcc98429314dcf8728bfad53bd345577e943b50a144171f8001129240c51cc2054f5c90c78d50dc184d26d642064a6c37625f98da848171c42cc2093542965611683c2122cb101ae04887208a39d064060d40d1c0086628424803538c98818829401b116f6ad305e594725e39c38b39e7dc1202477114da84a3e496275cba90e58c222967248104356bc2fd6a3555982b50d0407d31a668c1779b1391f9e3c49dcf949a482e9f753a5c10051fcb16edf7e180848beecbe700affc972e076c2bba97d5b1a4c2fbc5e81c14a8327dcc8dff2a0e1badd501deecbf1b1c94dea875c441b9f061daa81f5774e18f9ec3c238d9c3e7cc701b9787cf157164b88d6ba5aebe465f7244b08ff2230dd84986f8d8c7c7e1e5a37cb12719220ef24b2f5febad748a5648e9e5cba7f44b5db51f0feea8e3a12f673fbad9af9ab6a2cb5a6f10420cc67252380a72562e8c10890a3f76f386b6606e6ae5b2501ac08c4a9d97e7cb37995e4e8c820f63fc669c1e1a4aa9fe1fe58860d76d756bea72300d7cd9e948d598dca66e9c05f5fbd44d0e8cd2f6d0d9f5cf201bb186eec052fd53eeeeee5f5cf525821604868a6a6aa3eae0bfa30815a3d79411fa476b819fab83ef284265efafd4abc0a1bf01f601ff45d32e3f64557740882ea264546a5ffe6b630cbb54aa948c6114fc43328e0a17c20ba1055282cbead800023f16b2018a0f3fe38244185a2be300c13832e3867037da8c4a85973929d9cbeb7229d910fa57f7f98df2e3d55bb48b034c03bfb92119957a5d08c4ae99465a23eec5ef537c5e65ef2ca86e84280650b2930cf179e2cf3dfd4cc3256a0ee318b98171e2c36f00ff507259f500154ca6528961b43e4c036b9ca480b88d3b61038cbae3dfe3957d270b1620687606b59f4f1e1f5a254a564aa215b2e255bf9351bb655ba8e3a2b2ad1d79a87340c6500ef291c02d5baeb4523cb2582b0821dcb265e55bb6a8608d1ca4c86732ae14fe359aebe118e0459ac96032c84083e4af792785452507ffa692833fbb3d11e9ebfdec3fdd16883aa51b5f23c9e719165c22e5b4532d7d7ada81d60451713eb5a79db9a24fbf57d4e12ba1d683a808df2f7b0351d1e1f717f16739e40eab10c10c6a53aa5258f2990196158b48cb8af6546415fbfbfbe10f90f084751b0a1ad30cd1a8db44d88d80160eb2dc1c97afb0c1ba4360528426975b4320e372d1e5161945b74504a13b4b77be469acf3ebda2fed12dad19a36234da229ee7d8bb5dd2abeca36522c40156d803f52a7b13f6d967ba41035a1d889ad9d78c7105d9a11f29fc48bf5f89126a7b6ac66022fafe45a875ab258916fad7f350eb4385c7bfffb2ed478022d03750901decb52c5a9f5e65dc8e0645a3cfd9688b5809a201f58abe6619a278a0f56122c40156f4817a757db44b7a757d0d1995fef5f1a137478fa31ddabbd5a27fd9d30eed55967daf32eb43c5065e3151424549665b6360581a0b44c167ff22bd62615da06e50e7e5161144440c0115911842689d9999bd2111124a184550462a0b8d67be54b4ff10de80c6348a20d283a296106d04418408c804d41aa24882c0d426178470c6d0d51982e8679ec0c48d975b432cb9dfa7588fb385c6333836f84acbae8ecbb0e6d0f12e36bbbd020f6a578710be91d9f5ecb8c745468ada4a670f59da9caf75bde209ffe32e43adf3558a21b7a062d6870a8ff6d9fb68f2a177d2c8e415e43c2baa7dbfd8d14752b677ae48af36ebf3c34ab3b36b2b3d05a2e0639d110aa9b568d4af592c0a37eb2c6d0438b6ff622ebffc41ff9b5c4b9bbd69cde2308dffe7c275fe991856997ef20fb9b10d86b33d7f896db4cc740056298027c09effd55120870ab00f7f78861ad79f70dbfb180ad75f07721bd75b88eb708b3567d4ecd93d6e48f6dab5c50ede03f00eaeeb34ca3921432e4ec80e8d456e988d8614512087f6e17f791a5a9e70fd75988debef5bb2e06b00ce0895c2fdeca400d115f7b2930254571ceb466b290bea47a9e6970d349ee12e8fa3e27677e20a4854f8adc58f85e4e7b88c3d76c73d2e6af721349ef99ca734b3ec295da59b7094f7138ef215a8807d785b7fbe5c109bebdbe569e116f5f3a12952aef721efc26da277e143dd41f01f541e5a87fee14a149181eebef19477468eb837c56de077fcfe243a40d5cc525d4d5a0a520a1da6aab8d7c409fecf8516f62a767de7f714f7fa79056d80ab695700aa2d5d8ad1ec2b01b48a95c8821b072251e5f54fa42083fab5909523f0fd752000a7e00d3318eef90d91bed31eb9611a2f2280d70057974d419415586ab75a0868470e2a7f771087304608234c615829478e48c1a85f4f99d21e1dbe13582ea0ae7b8eeb5fe93a659c78994bdcd59c91011e3a08104ce3ef4c7383f3fd9b4c371815f5bbbb3bfe8fec2b0dcd538c43baf33dc639ed29cae799ab537c25d7f34b5b43ff7c1e2554a2e5e1bf5e49ffbc94cc1d58d47e36991c06acb5e646a0ea9a454a8c1cb9809309b08a7610377e43a14d8b2660e4889306e2099742f1208a7d84d11c88da99445ad48f8b8cb8cd478f40c06dba280235bfe61bc7385ff64def97fd67d967178bf1bd0dc6a4c5987dcc3629a1d45ed3ec69085fcdd69c51a9f63f37a319ed7a80f7b25d8415282cb8b204145ba4b18a9e8a25d0e0ddfa87774b54e9efb90725848e43fc1901bca07aeec1a4b5a834ae9574410c15d1000000004314000020100a86c421b1602c1e95cbc2de0114000a8ba0447e529849a32008529842c610600c2080803100032033325b05e52e2b6ac05478bf273b1cc876a547901d81ba146452eef7bc0a948c6ed2dea62f4c9784d52eed030910924114fa59e0de1db03f7be46813a14b0483308478a33da0abdd88f57483bd0929767d894aa9d6a74997a1d1efdf20adb8322ff4b9f2db32957ea26f2727881446ec4a0366981f409e52a16cba27c834a97f45c2e8d2266ddfe35961756aafff73427e714d0be498bc34156c2712b34a8c19376272f61ccbb04846d1069abe353cffe41950d37bd97b971f906e73df893077e4af3278a08a15d69543ee8a40d25557e39c1447ae6f27d6fa8623ded381c5db8e2645ed5362123465a0da19a66d735cd0901b33250d21d3a40c601e869e3a9b7e400274800cf624a71aa248b5af2ddda3104e8262d332a7d4534f1d695510b5435dfecd623eec499ca60a19a64b673854e7e8b8351a8c1ecb49f3ec57b9cfcf6218b3142dc652067ee3018ee3f99e4bef8a6bd3149fd698085d9b26191563177429c4204ba735ae485996d66c534f02d8bea5a5f99ebf4df263bed1a7ea3db6ddcb779e5035886f68f9ad01e7e6a411591c11a285e9d386e9b95fe3849b3b131296689b60c7047fd6af67300e35afd4afdc8b1af0cc57d479aaa5bcc3b0495a6ebb1a4dee9fbba915a5e6b9a7b7a83e7ca942115f6a4c7636452c6cce9b2d3121d0873852869c1acea97138132297234ad9f71a7036ed93dce4a3d06876107bdddea8a2497b7a103032e60360b535ed44e2f434a3f286c8db3040a7724415e7855431fd9d2550691537de0b6b9ac00cf6060fe1dd1914837aff900d09e14cbf9b34ce17ad80f44f4cc1c7bfecd97eb4ccf1e734863287b6749e0a597b3217d375eea163f35075453223b0ad0463ef194305c5e3ae9d5d9bfb431a0b34fc277c567413af7ad0516f20f7526b81b41c14f0285746e9244f91818bdf417f1fd299aaa46dce45ec861de8b6ecc22c1f9bb604676a3429910131b10bb7fb15b3b27f806bcdd4dc9918ab7e5c3bcc653d35625686ca8a00dae6407f0e3abf8444079703b0dc69b0aebec2138ed0e46f218f23ed8fe9337ccc1d3174d3f22d25120b373ebfb55aaa7927d9e457a984be67937bd4400b158c16a7582a3285187737220644d1674744542e2491a3f12e3e2c208b0c3e6a31cdfdb8db67d6d421b0db3c3561a3deaa9b3300382a6375739025324c9f99e14007fa8255f8a775a6cd7b7ba1ed1430fd3e025ffae9914960d95dc21732ccbe6af91a7d969d7422103823d92b876a54989366723d29155b1b652a4d0713868417e99da2230a84b62b9ffa95df646bf920c6f5a5a209df264518f62e82fd04b877ec21c699d05a8fedd529a529a45777e211905de71d67dad532308ec29c450f9704cfef7205cc1d5b01fabdb8235f93c6b229c1b0ecd0316a9a37c2b468962deb93a00266bd779b973fb622e9455b014f10e126fde906222f62ed50787f916944f8b3c326ebb16f97c21ef00c3a881b683c196137cd1dd2181a9b61d00cade4d67256ab6c36811520dc8e8f598eac6b96bfa24807d0a526715456ad9dd5392e45d278fa52db44729ca53d27f8c746fdd628e7680b1ac639c0b4479ea1832dddffe9310f7cafcde26b1ce83ac0aba9fefde4f20bdd4a697e5ad76b4658292129e9aa3cf3a3c5e64808cd35d65d1ff1831043dfbf4e30da8f62e853e320e2ebaf6b4074bdadb306c5de1c6450baf472f59d1f579acf9cb60c940737e52f9529d9d54980e634f15b3732c56dc00204014a399d294e26a748e514f939650c25c9e4833f71bd3294c0602053a530d90abefd540f85f5e707211f476e865f51315c05ff6706376ac6b493cfbca1cd613bb8704c1c043003fc100f0b0c98d6ebde89a300ac9ff3cb4d9e179da4e307e3564725bfa5470c94d164049b5828ff385689b94f3f892c0f8a4de70594968634ea62f95b603392e10f934458131cc2829fb71b91d5ab7cc5ba8fdb090bcd6462d6d6b7112c209022d00c703b61ca3f70769d25dd7ec93c91aa1a3aa08b1fc2618dcf4bfcc7614dd6968549b6da939444e589d17260dca0d9defb984bd573771752bbdcbdeb245fa129d25aabf4e755a6d2ffe4a6070ead45120df5eb2ecee3b1116a37fd61d0bde355392efaed4f917cc8029f80aca4a44bab6f04824e7de31648a6a7f1bf33665d0fc8547a8d0cd6d5ce61e82974da717122f615cef89cda9cd04100a3f4fa2fc88e870b2d10d7a4ae535e15adaf48b6941a754789547fa6a793c16fcf49acc54866c396dd637c756f06d458caaf97b08192b89a957564ace6fff982c7a17a2e31c0e4393eaa2db87b007be308595948fcc286d4990731ef073d9cb7a3785dc08ee79f883b352a2f98d000978449cf4f78fd59966e09315f00af3fc7f9b408bbfd74fc03ae091c8e1ac83859f9efa1d1f78f1e10db9accba489de6a94231165a627439d5e81455eb98cfd404f86fe605e103c650133029087cbd2aef653dce4d82f41264787f5bc94d02006231e10dfb31802e9d52fb3d96277c0add8219480b9ec5f6b7a21d674f51b46d88d0354a802d758d6d430bdc4d9050da6b49b7f4b30ac0b552c13985651d3339aa0c309281050b4ac8cfea394236cc0da609e7e904b2159195e69959fe560b265d7682d212ed3065409136028c1381a0a6296e0b1c7c812f55d46b07b0fea6a3c346c3c451c03b24b260f8fef63aa97325c0246fd5ef1209533ef63d32cfcb5606d063cbed33632929786041d91eb23c1b6ce4f8538f013c0cd045ac3a21e793ff965ec171bd0a0537e42b9642b34c221238dac2a9bb72073ef45cf5f82a757abd14608ea9922b491ad78ba3bb9fc7405c6077e5c40193d65d9d5ff7e750ee19d2e361655c4e5dcdc4e5f09357e400891556e5ecb61c11823acb329a7ae7e864e5c6c8c23d75f74b9b5ab47844fd31d2aa0307b2dbee95a1d4c53cd2df7de0159c3283ed866c9232018ee686577dd0adadac3724742074a9a5f37a41fab171400a989cfd0c878270414f62927f78d20875e2028ce5acd0a66db899a666ba5aa361de96b9da3f26c5baa4cecb276a4e5b79978f005b3c25b44f3cb2edaca9b53fb08fc9e1084eab2d037ceca42956fec090a18a154383bed00d6a7d03ccde11317107e09c2351e99af5eea103af304365ec0f94b65a30f7d228c5bf72a36afd4c24c1efc99419f3a0c0fe5db33dd2358f60f78a87c52402324e1dac9722d94b5dc62f7543d5a09e03dc74cb3ddabe0228c297a720f54a740a663202a68d0e04d1367602598a391c92ff047c8d34f4446f95dc3bb60e0e5b86a49ce615ff5df72bb576a04f11d13b706aac6f23f4c81e540d31e5c0cbed861ed42e1b2a948a2111fe46a8535d1f168f9de235ca0c1807d8cc2dd870b0705520a0fc511a2fe5d442972e5d88a1ff98e7965ac31ca22d3ad1ab59b99b12703389017d6c1ccfe2df1abfa3da2c94e9e106b9bd9b64d112e9a703b389c8b3c9170ffd7ba022d5255ba58b040b37b066a79a934e97b8c14e99cc02c64d5de8051d715edc14114f4821039c4a7103750fab7d994471a32b9934018ed0c73b1637cbdbfa5ac8276e26179f5a8826018534ef1b93aaf04b00ea485c9d93accbeb24b6854fa6703077bfafdc655c67cc7565c94a39ce94922c5d64e5ba933bbdc1727df3818fda7d1cca32445f04abcf1be64a10f3d70a47026c02201fa35cec8c5692b88ea2ebcb178a51568d406e51b3a418c592a246fad460028ac0519be451405a592bdd065125d37818f459c1679adefb20963759cda88b6f52afdc628c9f1bdda3471d5b02344d492da4a48a83befa10ef1b8944782701b3c16360662ebbdaa6564130847ac848941251c5b41301c42a43d12e0c6f3defb328aaf8287fc051846758c866c5420f50325ce3a81b8c038780f6f81f11b83250b1ed750f0d2732f332abab1f854f780c34ec4af3db42b048ad3377828785e680d43e4da611d579e97de4b8b2c7c7f8e4caefea89e321b5fe868c617e68dc3ad178bacdac9c04a71a9f4f6e0005d1755752d04bb84a239b5ff2cd50865596899ca1cf3e5fe2238ad0d87e60f9316e150c8d873b08f7a08cc86576b2c79d5acc09b8adb4009c6528a54041815ad12a0042d1a7f5e3dda474554576152339e9ad1faf866494b9dadb37ced17c7c4d0ed7c8ada71d3202246697637015ce7c71d3bd6f1325abf119eaf2fef79e2c15c9fa7325a1a638fbd5028136684fc7e76092aa31c3f3550255fc22c9f1c89817236b743bfb573262098a462b22a4596de23e096f79956d744e9026aecdd18fe05af37ca753c6136534ab3de739f19054798923a4bedc1984f5e92e18a090ade04e7c8e8d41171e32d38e41514000bf47d3b57a52a07405eda8a9ae0bb5f2f329467fb89c10164176e2df92ac84c578c384f9bed282e0b07e3e5a46505e2d0f8e6ef0afda3d054e7e86908b1be913253285f1115b4e9931aa0f7c11823936d2cac2d05857e0b4bc0f558f2523a93f02dca963fb21a3eac080c54cda404946b72f727cc8fc6990d624b86f2d92ebc50d73eff95e6f3d6b9774a943e9c42f027669b6198a80fac4bcbb12b6df2fa333fa408dcbaef4016c3860b18274903728e23079b04d026968e5a3a07282190b052f0fcfc130e0d433a8eb485c318bf20e6d88ab6205521991bbe3adb22fe3c67eb88676c5fad8b9b3eb4a4fd405bdeade12df9fe364edc2114449d2620257ae4c46d534e2a41e5d09707e814995c550c7038d47c7249db13c408c308f782bf85f55d97f897e37a61e813f28e73824720d7517e9a17cd5320f8edb31ed5980ce787d3bc4c490b1067caf6c20448176731f37f323cc8a1457c04f7f26043a3f9d1b8d814e3c62b7c454b36d158da504addd16639b109602714fa48cbd1059970e4b7a2d4cd4e07ea37dfdf7373e1a18fc6a9d5b31497adb38cdf641a8837ae31fa397d79a303731f4ead154cc48aca45f0bffcd6d64684dd7dbaf5c7b87b6a04aaf049400d48c1a297bdf2621252653aa9e6638a24d39c06fbcf75ec2f87d72b15614142d422db44cfeeb8a15c73890a5b597664220c451cb0524579543bff334149951337c918623c4bd5a4b4f2327843ce48cfd78e24b716f18e2dea98361256ef990714f5db2f767dc5343ffb88ebe8f7861d07c9bbcdb843b66bc696174c421a27bb6e98b1b114fb515bec98854ac57d9040de57e57130816135731b67295d3923796e16aad075132da0947464dd314b4b2646d4e2ff48089b4fea90f0461d6b4cbfd8100e64523a02773ce0a3fab64e6955b2dc76ed4eb52e7231cb328c714bbe4ffc9caec215593343167eca95d80de326b113b0f1352add7b31d634103b7100469be7264a03e31a9e18a44eb0432510b6ebc53bad80323f531a8108c7accc67da2c573fce609ee4bd78cce03f17c6e24a31f37f2594b5d1ba0d4b573b1a4341635da765363f2840c748850c44c5abe535e0cafafa284cdd83facf9ea77ab4312dcfbe7079430c314c669efc11fa9730d3cafdb5a700bf5c1dc58443b76d2f1ef700f9935a57321f382e44e6b92c3b700ccfa43e6b9c4caafe48b19672062a126e26f3092168983a888cceb61799fdcf46b207075d13fdce31ac66a0905b6bc7fe3626d19a51b461b3a6887be4c55ef37f25a431daaedbdba49a0b14e9bc0ce4314c2dde4a2f7e8db506d6655a851ee2f2c350a78a5046b25dbfc326643802370ece24a4e445d7deb158c71a9bcbb02e6e180c00fb9eb3859c676d9bfb5e6415e93505454adaed082eb2810f364a619b37a69daad3431e0cc185d5fd28294b4e01ceda81d819f527f032771e97324cc8c94387aa6b67617ad4cfacf611eca215866d6355b14a6013cb2dea0c203d685bb19a6ee84517863e21c9c4ffbe2eada1ddad0430cffc8b49a6f118ebc3cf73bf846dca495129d3be32f45be73d2b126c500fd6e4fac65e5f9c7ae21d922970e43fdb2c32d507c99e60b2d67a5efcc1125302bf2dfc6217123bfe65005d9055ca9659c0fe162ac480015502b28d1fa26fa605e6a1c409096c70e0027cd9d214c8d5c82b8ebcb06cc80c05ad7e8e18cef5974e9f07032f889f8656e7a8187146f73911058b549f4d673f378e07be6dcf456db0f6168fd51fb2916d6081703634833e860f601737315c6ba830b14a3212b7e30d3b7d9b7dd7ab340037b2a9a60715e175acd103c6067dce1cb6e65127357410a9f6bc4dab2980c3bb30a911623d193d1be1162243e4447ad47455db0e3eb7e036f1ee08bc825ff2f43deed1791a4c9484525e3f4feeb73cf85a3cab289544c588f452e74beb10ab51bde1d8cdf162cbe246fd0a4958dd75713cccb3ccf6027f71144df0263c46fd652f25a15c81fec0739798a593dcdddd56db573a0aebc1556b45da8f826de5bcbf40b3760f6c8ae86c870c034fd72dc27333da0c62e04b858c1b0bc2e04896a7edb1bc9716f065f681e97724d7b653f8952b3ef9dab0fcdc95709064aa66041c19153ddb10183132ef5700c1068ec7669da674b56f3ee2111fb33e8d02ee44f8fa49353011cb0ecb865e52d0116480b9673d063f9ca93d33cc429259b33dc6ceac1d09e8bd113e80957871b327b9da37c9f1a6eb120b46ff416836669400c587eb62c3762c35744c22494c6c97c0447ca67b6e60c7ce7aa7444046e40849b290bc8b37208c395251a26e843977eb2fdf64a9cff1aad991be60d5a17d1f74248813c77863f37420065dc4886ff338bd69cdb46346e2d5107b014f6ab990e7169760cb9b9aa42a19f6428ec8fc640a8978b1564427dfae96f63602dd2646a14efb2b1bc191d364bb0c8ef68f1301de8e2edd98260a2a98034a2606dc383fb36e208524e19d799c18a913ab05ddce6e89915e29a26df4be867b87379d22af9b0b60d54a7799782ca38a1f390f5da577087def7a70b9b501729ca66a08e7770fa695aa0e0789415d7e6dc901ca6b75d769a52a86bb42d8de711fb3b83c4931f07638bccbc113c2b5de1126a45d0ef455427a22d79c5c22876cec885b88e80e40f6dbe3cb852057e0610bee421d5b02ff0f956a1a027ce331d581190187118a7988e594c16429df372c76704bd81951bcbc5e109fc56336b71d4caf960808092b06d3bf7301b4839954998e16f5924996e79cb5290c81b96a34d6e067f894cadafcbd2e2ca672cf96352e6064ab72cd3c7be6aaf35a9896b76ce81ec1afa927a30c2562bf7982aae4fde3ee893ae1b137d9c01cf19621788ceda0073592ea93b9dbcd4eb9f8697bd6716c6b3a9cb9efe994f1924f8306c34680f71042b0804f4dc0f600721efdea709803520bb08bea44d79e0aae25534d2e58ab3e564ed356b5a7c4bae03fb3e8683e0e507b37f7e9f1008ff0384017ea1ff45f2d46b725c10ac1b457e8c0dbc245d3b630eeaa26e7177c92c0d3b02c7a364e3ff33bb0db938f51de7e8e5933ad8ccb64613246d12899651599b2d35dda96e99a179bb4b15acb1a3508d1f7b556408691c5f169123abd9c66237443d96f9d4d148bf5c199cf283b5db45b0e7183e884c43865c7f3567d2f7e937198ef87a6266697e3daee88a68e2d374eb7b4636acc77b9e7a8f3cdb7a42fb43b1d531b2011d8aab383c5ed3def1059c01245a681efb10486e94570191376bdc20d663188519153dd063dfab66bbd551373c0672a3d9487d029634cabc5876413b4c7785c51e8ae70dc11f050e3b1a64d02a683094124bf966628b8e068390a815f7f79358729a59ce44697a9c11d2a43a5cf1572287d3835614391608cbefedccfcc730b17c489ce03c5d9954f2f7a24a11236a346feb1d3f3250204fa0eed4e8e8f45bc8e8ba9b10aaf9cb8c086137a75589328d3657bcd94055b85de9971b430508f1f824e7b8fd1e969caa6acc22aa23fb2e904044239d1779a0bccc0f6525acb21e760b624ffe5a645388865b7c5db599d6096723f1e0a11a8109a734ee1f21e84058bce70a939426bee69a1026111c802593595c890746b195c18cd42acf43986405f82389520df7eb85605b81c3d5b4516d771f22a6a89824fb651eba0a60b624c77ccd50a1249b6ad692183f25917c96e447cb60122b5b911c774692130347d8deddf74d9281a088b929047ffd07fddc94f6f59c8a249a7d0137f038bc0c7ddb825a6351636ab377a54217c148ea145fc2545f779b4181b8403fa22a92389685c9a8542682534c26bf4a1847962bfddd31fabba703c94619ad48e4c982d5e71643cef7e1259a7109d9e5a7d281a0ebc4347120a4244192985f3a5ca245e0f8ae86700ed946f00a02599e9bdd1d5dd3be72c471b0f3074a15461616ad8f8048508354b727220b2959104d84b80185b159302858c7a139d2b17d0a32c9594f4207ade5b51ca0e30eb67400cc8e85b50a5f28feef9b5be983bb277e40c09fa40520957205cbd7f3e993383b518d2eac89c107aa03299086ab82c94002590122d423526b08d0e6fdae4b4b2c7ed2b83da3428fcd8984030eb5bfa2a093a9203b6954ea25cc151d73c182564d38022c89a43f236e86995f82b923dc5ebdb0402826c969d42fca782b95fe01ed3379a50239446922317e67563af0033351bf28416815746cebc787ba436d66ba23a3d0308a2346ee384b94bb48ba865127928b9d220b48c97efdca93fae75e1433df6f9802bcd50becb760302e69177285054448c61ee5f76b9d570f9066220534a11d86deeb35f7ee18b9d82a82e06721c1dff1fe039cf0faad120edb8aeddaae051777bf11aa57be06d74615d0772cd1783234d8fdadb3743057f6422e6ad6125ed2292834d149219f63e05f7cf258f0c8f5e5148409116ab83d7f731cf02a553f81887b3903eb4fab00aeebeca8cd29366ecb3c91580ea15adb83aa02e02e07184df61ef5f15985e1ac6db9d976616ac85673fb471c2eab814a2d23c4f83549c1ce7c0d8dfbe67789fa2b0b09ddbb01ec673e709059306244e9db32a7cd0f4f9f2cd4658c68a1fdd8e6010e1d026bce66ab451045e18f861c0735c3a60d6f2bb220111e90223f5125166e66282b72db65c4f4f581eaaa7f2b79fa23e0a33bfb27f561346031fb0812a2a1c6155af99e406a80c33baaff903441c69d96f0a3904c56c7e35ea3901fe440d13c6716121fa25d7e49448a88157eba6f650d50e02ad89d0e8dc02ab765488e049a1e701afb1061de9b4390aa12428020f21bd9a0a23f1b73bcd8de32a4d076c4ed6d0edc60c52fbc1cb0c4cc7850f1d10755faed489edc0b925868d0981540afbe5ba5487bc28d6ded347b0d0a0137d4732e5cf996161685018e3c7d2b900330f2667e9a82bbd074b4ce64bb85e6f2f3e28785e6b0e2b99a4785c3bf403eca880bc787965b5079e63f5025e4c4b3cb3ca4d7dd53b4c30c0322b1370ce06fcf188aa477bdda064c09cd63ccca775558d45c9d127542f3b63134b80f82a53b75091b826dd0d446feaf9e97eafbdff7b7eabd33366b5310103c652141d439f577892f5d0eb154eecc3ade4eb8ad9c26eb314d8ea205e12d17077b752e21292bd69a9e3a5ba9b2a786956328eac0d35432dcab5b009d03d35f7a34fe39c42fa9e49d5763a734e8b0d3f9539d1bd0c3288bd6c26c4d6a7c202286ccf43145d921d206c7206234557603067703d32c5257bef912083ccfbaac09bb3846417adb8dd823a047e19bb001633d6591ff6565caea25db2121e10ab7a7b25ce6b28b05b821eb41b5d1ad819fe036fa53e8817df628b4b7681810fa8dd9f2eeb6197ee37f12dabe44791c2063ce607c874e79683fd441243d54144fd2a40475b772154dbb2be2330df1fff6db04ffb82c39c8bce50ccead992c56c6f09dc36197221b7fef7ea2bea65b7206237d32430578188a4ca203f7b1ba94b012d16bcb1485d754912f53749c8d760aecc70fd7f8a35b346a6efb530aca2d1a7bfafc3404170650429b07f09f72140ae078798680edd8071c8995d0cb9796a691907975b6ba8168d7e9973c287397dfa401e8ad47bade0eeab76fa47a102e707c147d960aa870f99f494c4143e571ccbdf32f79cf6134187b3170f5618ce44d5be290d31d9a19738319a00e66d451987c1acb5bf2445fb02b5771193aecdcb086e1281e6c15c8c13c7f8b9bddf936d8ba73c41335b3807f493a4e581e8b7f8b066c6405e0562d0f9737014be10faf2b3f36dd0fac95ff0022083e00425cb96bef9b6477dca946fe1466c367662aac4e83c2708b9ebc283e4de28d92316d62d335ea005fd531c96dc34d10e36af8e8b3d8b6a7912a30377c8ef8d0b7fa914b95ade0855ef8457a313ad35bac31ad48059abda2ffb4895598d1ebc2bf805627f193a4b2bc61f2280fb75aa655b0e427a14a0e79abd5ff2344c24478885eedfffd461216c5627c268089e8b5a16a0e5a41027543e0fa31480c212ec46cda9dd4797edad82c9fbf385825214d9331362824742a45970dfe90b3a21d9ea124ec478f86011689493cfec428f9e78477c42340c207ccfd9088861f9897815185850117b8fa94e9ca4b8684746816948d47485dd40708bba1c218e0da74801c05b190e0412c20eded8216d4871d6a4b869e65a1ae2462f1ff983a71b757c8c42a8dd375130c6a32121d22bda395dceadca9d2bbbf0677efb43fa0ded84bb0f40aba920317f0436b35f96c0d76ac9be17bb87886d4c745cfd416c4e1b10aa370ee30174a760ea796a2d265af60eae5f6a6245bf28a8c3be279d4a1781e7e1893158f133ebf1d0d7460817f465765a0e545c8d61b0d2547cc023e62ad2ee741798cdaa218bd753b6595c6076c8d1f0da89589ec7b07f3671d098a0479b70040fbf3437cbbb81b60433434f2795328a0e15f58aa42a61654e29332cfe10d6f25efc1b5d40c0520b94344d9e463a501b9393e6cec1fef15a55807dc181bd0b75faf9d0324c9c216ff41813fd617de51c93583ec0123982bf6c1749db84152357d2ea545087d48b89a033f4f54a8372d4ab56ce3b1ac450d81f69053ef372d379a1c7a0540ac7a24114711e08f85ead3870bd92d92db746df7cd7ba24bc6ac19eb8e1a08caffdeca19502f4c90337077113f211db1055bc0dde8fbd8d5be02aed29fc06962e91aac9dd3d8858374f40dc06db90f9a9e588e6f6fd90e20b9063e57183cb544e726ec5a94a02839308859f2cc3a609639647c80e81b0ce86376bb8b1085080f705295010f1d3e3912634f6b603d158acba7abf7a9f815e919988e16aa9020e927da69bd4adeea9afc705d5735e81e5adbf47643e88f9629a46b3971299bedbf2e05d1c0ec7d4e7c3219b256500df450d9042c2b2db7fbcaca9fbf282514d673b03514b03c706504d281c1fb9af02419aae94e1dae558341596867ad56a2e0d3a98169499b61e9c095be1ca01b09be153adc014935b2ad29b40ccb45f52c2aa089d9288f5409038acb2094078045267b96bc6596e498ff730a34f6a4fa6e2c3828de795c649a2866029e009382fec8a0d92e90da0cda6c2b84992ff75dc7be6b8e5f39be7c1ad5c4fd4ac5704bde5a2a0ed77edb3cc47779770ff44ac4f7be53e739bd0799a420f46217d1e6a9fcf876111c796708b2a508b37088aaa3975ca087a05ae7c259fcec9d83c3153d1f8f5eea9f17a8d6412950c45c04e91c8738793e8e21832d7a2a2b52755452dd17b53b1520d6868a7119f94b56ec3bf9ec27754e1f8ec30ee56eca4bdc4009a60f05d3618ebec78d266e4da293bbec28b05999fa9cbc8abf8c2a95634d1996c1745d8654e0580d41d48765eef94679790861f22f428872c64180283038dc0c741573e28686907140df7d5e299e6c5b8a2ef05ac1ffd1950ec858bf4780ccca2bdf06b42c20c51df415976a08fdb1dedb0fd7d021e3e1c4b2dcc5d5b5d77a24e671260a4237b29981e0a5c43558a1b56e636f97ff5169966a2ef2282a1ee075b6e00431a936e130e9a820a8d9ae34191240e7102eb753c8263f83afcfe1624b4065d3cdebf60c476c1b852155f6f8fcc3b2bafc64d9382d1cbd11d6e59c36f1272adc52ce743aa3c3d9c96b99be2f071e2704b32291bd74a80c2ca9ea9a26e25475cd658f864678efffe1ff456d9276370dc58315333e6096c1f3ffc30a1c4159a64c8591a4b997c24c3a32ce7c1bdfe84eaec3a07d0b7b6fbb8e374864cb49bfc3ade10d9babc5fafe88279ba5ddb805325d88d7bda0e4f229cf694e2a2187f894df0fe1465bfa997d8e10c66a35ccac58dedf0d3a0010b24e6a2c12867e83edcad13cf7663ce119bb8d48c0c977e3319fce73a6d3fb6e9b10a7fd9893e3d5d236c9cb03b0b0ed3680404075212903fbb664189ab5b9d3c5489349dd64a81dba502dffb2f9ffe2e171b36f98eabe52934f7d58d4a893da075e9cfb61d7f80d53668f764bbdbb2a4b0822df2df6beb583810601d36bc0c180e3683e3cbee52cb4ded0e4587c4e86d9237709c9e2c93c93e133136c4e3188bf25b8665368e489bd87c0e407faf38ed0f8f526d25d073aee60fd01071defb843bc933eaa99d4c1a5bff5a650ec5143ecd050a360f9e75cddb7f711fbba8ffbd2df4e509f0d2614d0ef85602262ee633725de6d102101ef6d8080c0fcbea500ea1fee0f981b53ffd6f77b735b2a5522b212d201f8a7fbd79081ce748a4f95779db0aef77eedc3afe6fba12fe1a6414c2f0ee5133726827bd1dd2b788f759cddf5b215878a2cb3aad2d420a6574352d733d389c02d19788e4bb9958bde5cb86dfcad33c24d195d56728b15614ea4a4553e290606bc8f0103ff3eef8b7dabbf1cdeb0db1273f37de761261bd966393628017534dccc4f3204588bfbc37760dc4a263944fc2b35a787acc4f6c6e912c458a08ce238ca2e104b6f8d7e7d43dc03bf26e3ace8ea7170e18a55256cd694ab3f32a3d838351ec47add1443284f26f0f13656efdeb73ebb211cb726b28c5f1c6519193212b8dbc8042873525d136da06596a3f4cfed931766ee502e6a1968b5ad5fae3e23f41aa4eb59ddbdaf57b75606eac5d2d8cc14adc5be57b75738d49248e2e611e8e5d88034b2aff775df9f7d36f132dc2cd385089ac4e61c331d30d995144211ff08eb37b85f8aba618c6d3102971f07c0dda6646de24e3f92fa323a029611f0b4f9a5ccd6e14c1429e4e10948eeae99f1b40e460a17e29cad00a11d88f1a4fe7055e0131a7b2091cebd4d2cf1e0c08264fe128cfa2f95a2910b37d4ac2c86ea313e45e02bd49226c3ca7c0e8e3573b788deb087f94337b62c134b12a3291de3d35848974f950ec4d77822c8d0fbacfb3f814104fae5c3c46bdf0907617a07deb27bafb0cf0e82f2a103c0daa6897e9e017d988b103842dd3c258b4b5e7a99f77ce3da4985507132212e56558983ea53e23c52ddb4fb149daf24cdee054df3e3f3863e40450f2ff1d892306f934d98e029fa929fbc799010883e7f5968d932bae83613f008043a3abee220b67315e0bb8c6a89941de6d4b90e1664d88cbbf4c9a78eabe9ee1809fcd8b87cd61e8caa50b663e6b308921fe509f29bde6deeabf577cff906883ec57eddca4d29d5bc4ac010ac5ce2a14ece0fb834e5e18b7b26ac6bd475119cf9f0421625071817b146c5a0e751b952fac022192f78050370ea198513055291067c37b37dc3b51042815482f41dd007a5b7c80fff57c941e1d7b1f01f0b196257e536541f3a29a0723e718a19a188aabe6a20d630a466cac365d1f95be9484035d100b48b29e141afa16df78d8e3f0f1c9e534489be19d2ee6389811e86207e601fe5afa1824d730b7665c0ba55958d68f7af6a7eab9ed802cbc32163a2418fef7276d2eed8210729d0829d63b1e5a5222f55dd2b392a8da58b34754f3606cc2b723a5a3ece8f6389baf21c95d91d4743e1666643ccc15969fd5141714b30a9a73d647f7dd4b4b6ea2380b9b2a33cfe202e2ce94f615782dfe4f4a61c0868be12d6debaf37318f32d3c59812542576e32ce58b4aab773f2d24ea282acd03fed7e727bb407b2da611f8c1f59ab4ac8cb515a1cd96a39871e5bf0cd7237665f2b6e7e3a805839e3bbf2aac6808e8b0434eea516d7255366e13754cd3cb6439b6dd03a5d1f62aec269ac1cf670d4bfcbc297d4418e823e8d63f2a256a142a31c327f3e6ee40368f465e07255484f8068a1a46f5401c78a17b8a4c0c39402de3cbd71cb294f91c5a3d578fbed0207a363d35a8bf7fd5ebee5f7f3f5737adcd4c7d390e04a24b87137b36a74dd91ec62d197570a677cb4bf4b626056b51ac28632302761c27f6e8f4814ba7f88ff15fabd97bb8a4f9872cacc1e970f12b118f235aabd43fa8d5a5fcd509abb03d46c26b300ad24488c9291aa43a086e0180947840f0f5775e8c9b4e5af33e4897857875e22c35de80b0d249c0faa929f73ab4541fffa518549d436de8caf339b1f3a6456b35eb199cb6a05c82fa9e96b09a68f930e635e204ee9038e280094a783348feba6158fd8b41e3f8c66ea32e071e066c0b9d048caeccf5be097367484985fc5a843d5b0f001cec072df05745d47957a68a1121b0a7f94ff3d732f865b7789400641ff9a545f2cff2a750601a287c880f6b7276af38c4c7582acf5f41461df3fd5d2295e864e97a1533bd725654f94291737eeab7629ba4750f9118e8b131fd0682a253097fd78fe4267b9662cd7acbeebc82318abb7886688a835b18fc85b4ec91ab0207a4afa13f6ad192c09808fa5ceda217b17b0c8d5e7e20ccc7088ded78678f66300a2a982ea80f0534290694b16ca53e9b8e389480e7c2e2d733dc9e8a2378b7a3157a0bae8233885003ad7ebbd501fc96aa7cfdc08fe688c06dd261dac840704b43542b9e5389422846d5d27d1950c6a40e800f03b07900fd9c6564cd312480bc880d428ba8fe4812475a41c3f301b4af8f19ac43d371687a11cda8fdc87d4868f43c9991e94a9b53c51fd67b82d559c24451933eb22e9dede2e0946d9c61cebf2bfe09d94eee6f6e410c595d2e770fab529b2a2f9607b9b2280e320d7d6b5ca1cd6dcf9850aa300c5714f4dfcb6320332552bb45667b9aaad4118faad946cb3bfa1c3daee34b99756c7eb681d116e418fc697e0eda2d872b2962701caba7942467c097f3bba2068860181e3f935d04292c19816a4d46bb1dbeccede72b1b00474b1de160731dbb3029763efaf1dc8c5c6a2ea43e15118896686563705eb7c364d9d800912f1447dbe0a5ffd5fd92234eeb1e312132d7f1c7cbc80065252137e7f842598d870d800fe2c540285449058c09ed2f1b7f5171e8ad80d18000caf9840ed78eef4e07914efc0b3829fac53f21ce40d17bbd8c2ffc9ace978909d5dc244d55fe03bdc9e1844696b4f4d801ae426b0ce8a86ad3e16ad7fb324039be10bd8162d933b09ae8d9520be283a500dc9353fe8898b70bde56d449fc091389ae4cbe96d2c5ca8aa791f838d40dcce19b56ef6c92d88d79b0c9e7ae87de26d47cb540487b80ec513c7793d904038891068f0cf1698819376fa8b352ce56adbec09293568bdb4e099a58c716ae617b69c78c731a7038166a43fca05c2eaef19caa4c425053f957a47826175372a125220fdd58ab6f0d02b12da8b56926e04ec4a8edfe9fed0321aadbdd501a94019c2bb96fdea3ba2645d1197841b2add2fc5d5c837b3334714ebfdd60ea9b6d021fe7fd468cf58edd8c6ed1a90222c9874f3de69a26b74d322bbc8942abdd1fa622934526a0746b69b2483032bc7a789fb33bc94d826ae63769222b50a0a67be7f804ed819eb556fb35bd260cb2857a50cef32164bc6c414a78a1504bf3bd08059109cf57e9611f55934e1179387266f1ec47477506e326f7dab99261d568f659379fbee0cf38ae81c0cf988e250466cd033a70de8dcfbefa0c58c2ef707448cf1aef0b7be9415b08e1df101fcbe2b49d1ba5e1c22db2983ed9aae7a6502af143a479cad1c3221750fe03ebc24057c111f856b36dcc3b01f127bc283c69a54ea4b423767d06d7a535f4c51d648eaaf655343005c03e4713733f39715467c129436c627b526306527dc8d965421ee4921310441ebcf07dcee60d92a87e0f3c11f1d436681e176f8e81a56f78b20e07608a114653800c8241194c14217bedb270d0a85e61eb993a29576cf77cdaa2c79a4c9b5026e1172d0a30a9c57bd3236a770190846d0be519b60d058300a18481c07cc0d342691179e2ca010aead2ea8dabbb103a2a14b3fc8aea0f9944f75cc2bc48cecbcd0d254f89fd473f2f19ba1c40cd0e2d26a1b6d98fc92e3d585aab68d2b38ff988f7a16c9064f9bc968137ed1c73452c009a228b8ac0d224352ca052617734cd24c610cb1492250854adcf81469a4701f8d0d02efc3e944dff76e86efeedb3d8c8e9124b42fe6c81a946841abc3490341ba4ddebc39dde83466e3918398f393d66f256664bd89cb8b57eb423e425035bcbb8486a8715445c80fcd6c8dbd335465fd4530abb41f6105525ab9d83cfe30324fece74f59123eee3fef4f25fb25a9189124b55256fabe9365ef435e16b48bb78e1b75fa6a0ee1e4c383514446b4d72e95c2e36555a3cad7001210e4fe7a67c36cd58cde12a657b1402ead77dcc32db34c1dd34a3628c9b518e5c2695c437d9d3e60792960a7ed673411feaa3cd07209dde7e6c0156283eef6dda6bb9aad4c57dd05c1792c6b607825ab0b47e4a9e0c267748328477920056abde478941f12b0a8a38fe9bb5f695b84b82e80f24a74f13e96b1a8e0b255022170b2eafe70d3ce53f65c9afc4fb8348b90598a9617b66591634b525657e3e24b08710c06c5969bfc6ce0d24ade764b4c2d857ef0db3e50b5196f1c5f1a827ceb5c7cfbce58ab28d37ab1dc9ef3a0c8ecf252b806c684fd4f75b18279bf812e51e4350b4069c9e2ae22dd8f181cad06258a8c4543d88f35bcb540c95e13347d560a0ab67a5a1c135ccc23c490c7fa3c3e934020ab6b3652fb1c6b5c819c514b582ad5a66c4194ee2a5f4edde7d824fb48e8371ca629667b84219cc30b0fff6759aac367349d83ef960ab6865acb24a6a7cc7eca1e8452012f01dd20d2b467ad84f033c7881c262fbdf4e60c071c112a9962102c8002d3aee0bf2378ca56f129da8bbc9c049330010936b92dc63e9f5a21b998630eb5882e2b8bd01517c0daaea8af9aa2b2e54dfb53ad7852c95c3b32a3a46cfb7cae9fd5340afb0171f63ae53744da451796bc30f3aba41f2bb99bcca0099fad28ab7a813f54677c639b4bc962b5a9b77b24e0852a29e4a0b720a926bae75202b9f2a44d811e7c823b77d8219fab97015e10d8e549aec085aa7927df32b558c02fc4db9c5c7b81f5f3d9a29663c3cdaac81f0f1c167405ef2e8e2abba60a463ddf80d1337c55d133038429ab6217a81908f5b9b9b23517b964a37fe090ef1efec62ea9bf2a14fc7e18ef3165dedd63d3f1bb2c64b925b6bbf51fadd04de5836e74ceb5cd57e2cc8a741b6d6e24145e159d1a852235366816b938492f085d98bedfa8a955d58c7cd73d9ae548a7e5ce6d0c8b7291548280e3263408800231299049872da1e42116a7bfb7afe14097301e2d0926116728eef9db938d209d888921b8aaa12993f6570e728081aeb50bda2c6ffb5fe9e9d98e33bc7df9d952a43e140d6a3b06e76220b769733d9b81bc6c2c7b74e81c33fa1b31e0dede5df22b7c189e1848f704dc7051eb83334187b2112a43bc0628f802356719b0186d1caf84238b2af6cf719e61a27f640b3ecb06d33611f929f6145050c43ef8718cb099ee9ce4ce008bdfaeac68b59ebf36024393e5cf679ed5271f8d53539eb40c316ede5009962324cb1fd7a8beefc1ed507d97174cd7e7cc5a839f133dc90d0fb171a8200c3fb463651dd033dab012b34415ed13a3afcfc25ddaa462d1420c6a86410be35776359938bf3ba99cd195eaaef4709754cd6000c7f0e0ab62f49a92117f2ba9c603ea143f24ddf45069b263db0fdfa2f09697ecdcb2da448f9d53e0c029e068e539b8c2dfaf76d382f9ea8d95304f57c5f0171224e85262052032ea7c2f1a0083bc4822480eb55e2e09b504a5a8bff361e3378c38fe8c20151cc774a8af9558cfcde866f858e6459fd3608b1e13db70ad36cce5298769b27a8bbece2c99dc99f91089a506e36e42d6baa71d396735f3cb2abb0b3d6250b83c0528c2b412ba00be3c95ce0c83e50ef944f05dcb454bbf7c60ab8ecc2ae452d0beb89693385bda25e7f87e19a0cade78ebc2ccc1416076092a42edc1b52ad8f1bfeea5ffc8f91a245cfba7bc607184bdfee0033361d118fe7371b061395de9c712bcc649b4a95dbec8a29ed3339f83d5418484730916d243f7a3237476e588dc8a5f6c72e2d4aa88b29159d5fef08291ef07444d588221a63af7992fac83ca35409e09c5bc23a72ad641221eaaa098c90cf6383dd0219c6fa8a6efc24cead13fe4999642619c61f7858b484264fa17ae8da2ad05e86f1a50b537f1fc47ed14579342f1db00b1b85d2cb9cb5b53590a0878cd7423866961ad5b776c6828fb819d78f5a2ff62792a53e8ce6d2ecc94a3a1cfa635b8bf9a5a3fb9e61888299662ae648047151c46e303264c517b5447c3a095479edcb64c65b76cc7c5d98b6d191797d9e9605b5b4606f379761fc669ecb196aa76c9165a8e80e2c021b36605729d9243c2b6f0419fb9ee1a905cf82adee5bf298d297156f1e6d943dc70a3fc40c0e07c59e9a9866f6b3119c7549b05bfc0c1bd3e652f4751b8d56cdd52060976b4db19fa827e895efb7698ecabbd038c7456e29de81e1e061f65075f4c8244b8d4c004943b266402deab8b2921e55c63c5fd751782cd0201c78070b68a5ae6a2b21d9fcfe3ec6ed896f4f3386c4365fefde1b6de95fd9c185238b206ef6e10ea6dbeb4e1f9ec4686d6c5270dbcdef08ed73bd33053e2f84df5ce6bbe5d4678c07df817f9e0f9a9baf629483209dfda20577bc5192c09c89238e8c98437e22a4b46692f003028a86f8fbd06f251d6ffc0e9207daa01de51c1563843888744a73d8b61a505fc576d26265e4c5b5d232b2308676189173f20d26127276e98d40b9a3ede0050b2d7c381b7c157555bb16cb36a9498630a6aea33564bb99bee57596f0a92de5f3da3f8801801161375ac220c96acd41537540fc6397098681da7fc45d7b1cb940959f229320d70ac517ead4c59077e46e9abc8acb386008f2474e8adfc9162cce5f7375c3e001e84f69498b4c7b67b64e62996e033e9ab04d7b439a04e8ede2510431b08729ece639c07ec3c9e5d7dc4ec82668e08e1b7f5d6489bd065e8fba125f505301951b0a985c7f66cff44cb49c7b62346c0301fad1a61c6db6f5b09ef16ecabb60a83a24398412f43843ca833f1f363f847155d5daa59c17728f8146b315d12ca8c238eed165b0fb01141b9bd65f0e6730a32b3b6aef82aeb4be9f14b993e7041b327fe9f6142ac7fd3654c271005873a6a41d4a404bfbe05b77c3d94abb1003e7a9daa5f6e52bbdba3eadc26aaa4fa43be755a6634d5cbbc6bcc87668b4245d8076af5defee1593d2e71e0ae0b269b18ce6051a6758669b4eb5a6276d280d7f870245c3b185c92166d43d6f026050714332d109fac8ffd3ea3ca511740b6d1d0e4d47ca048761a79946aaf5177c8335c3a622133500d192f412973a8160e464548a00e3261c8ab390fb2474ea18dd716bd9b062261e7e8f6e99249642e9aa618289a3fd9f6d1b925067b0580ef27587ef3fb9f23db0bd91b3c166d1be5e962b9320261cdb07a8f9df29fc698078a46b9c200ad9cfa94077537d8b1aba332f3c361bd0f8fed83762cec4838dfb2d861f48f1dc41636994641975336f0a5e667964951c40aa070a4812bf1fdbb01d8d0b73b37c3886837a06522a61d8f396e4509eeb0d238bfacf05ee7afec6b713a22be268a8944d7f0f0a44e3480e922bc0dadf40caa44542c5a2759e4331a975ab10f9094f1b56bf23cbf8d15386ff9d0c5c47c6e0cae4ffe5046c4da0ed542ebd3f8869fc872b1b71a866add2f050d7eab7d293eca5a86b072db2db7283091c218eb969220fd5a3f3d18253a23c0852fba7520593d00fbb7b03a783bbfacfea0b50c41d4549a5c3582f0299f0d5bfd0f8724f06fee71eaacc90724271b09b482a3ac4ab3f14b5c4b356a0b87bb83c55bb812130ac77fff131eed246bbb5575c355c241787232eb2c85c09079d01d20f1dc3f04f58df90becabe2ae8e4dcbb450b3e207d64be969a4fd136a2f8a051240f38a6f65210a14e3ce9eb575fb0774b838a8341fe90959a29a80a892f5e86a819bcc41120162f2248a13da26ef90785f240bd398039063e7d748fd124885cd07ba3536280ba47baff810a84a828e146b5219bfd08dd867ac61d67a3a85ae181f3be78e15d4eb74737bf7f79c168cd836de2c8bfb2e21d4fcb049bfcc594607c425de3ac4bb1459e07dc1e28f1e02e547007825fa1328034e7c2e18d03be8b713b4f21a24cd132e14ed7cce02537fcfe7696eb7b95b8ae96c0b6a8e003c9948517fb617be3ea21f5678336078c62c68b460a88541e235890a90b7282ebeac89c44b700d3f1513da84e1c9b8fa5819f5e6dc916acca2723db81fb1557659c8ccbe2b9e35b997347c4b5dd168d0ef4113a60c1e1216114d7d60585ad20f651c76abaf908d6da96c20017f26f6702ae133d2cc70bc65c43bf1e65f697d2e916007cc0c68de275055c71b0b4a35dfd21fb7d64633a04db23f49d20bc194fa4f72c4a5e08be701d0f325a0b1340e3ace5c979606571cfe042cffa80ca1eb922d362d1b968f8750f1b95d200c45e9ddf396b9f5563d7b47a1f1fe7db27d31bb6f415b9de9f32950ff0b443e35bb8d974d1fbe2029657c4334db586e8c440021b1119a8c87a3430e6e8d05978a21ffbb56347c176834fb1eec0da0a6807743e814e575f3a1173d6e11409af62e7ed7d160ea76499b3849dd551ba9ebab0a1e4f7e89da279e443c112569c9ef0848e9b88ff4b72ffef58c9eebbf0073fa80e4f38892c6fddf1e9ed68a44ec631e06fbc12cc8106d7ce3c89172f5fc37e65608550fbee699a7e788cb95e0fae5c8a36ac4f47a6207fd557fdaf3cf465ddf79da157652a67562f66683668990200c75138a4a210e439aa8a249e804423807e69890ac91c33febcbb36a947dd85a2106f22361e9d93bdf7a259a9c8f9b4e0818e432ebf4ff1290b31e282237ccf5cb17f42b8cc57b9e2d73db46c8d8175dcac384283f3d841c802af8ab43051b9c9ffac2148e8da667ca6a2b10ba1ff67ee4062bfc5fa66ae5d7a542dc197bd3bac25055683d719bbec07689aaa7099c3c00558745e7c1cfa938e05ceba3d5ee9cf2e0b7048750045011b9133d8d63ab2fcc076c41fa26bce3caabfcb5949af058951d9ac53c22c838d68a4221c28b3180d38f1c8b46f3cd4d9f3eac2b941dc718d40916f8311380703518ed721c1f042d7d18268f6e2239166001ad003339fbea7c3fe9c9a203a50e3433c8fe633879918975a8cc8a5774411bd959f69d573b791a2360bdb8c1ec23f7d5e0427b7e6780199c81530dc8d21c12f14a024f03e220a49b4204c88012c48397306736c16394d090c096fc0d75f5f1347e128077abdc0002016900d5fd6ff70e360b6ffcc1f2bf3c03b6d5e1496cc58e8ad0d6e162847c1eb282b5909620187e6800a636038096b4d4cd9f097b8d2903e531bf674e9fb159e34b1b1050521639f9d50f083fa5128c1ea11cff78f022f2b9c6729a1732e93258cab6f88502f6d7a222ca9ff41cb81703726a7f250193ce455ca70f3f918388562e19ae35e374d6aebd4763d226caa9bb28915577eafecde1ba5f28b47caeff0fa4ac42608066a6ecf646ea4231001d0386743d6462769f81f71967deba1117282c90958d42bc335215a451f3fda094e5c6a927a10c10312188944cf17a4706c05ed4e344c37d3f3e0b50e6f3abf3138f3b5e2401c84e10de31f09754988793241dbc580e656837604d156e3d5abd96dbd549e9d31c04b4ec33de7418904545294910ed2f60c70d3aaf74325f38e853b9a4beb41ee442ba49525fee31c2d4e4f2acd9913a7d584a13e6d793818b80202ed4571a626e7bc3e4e9fdcd3f44521049f63bad551b6c733f37545abb4dc07668a2f51e99f35d4338de4638588c64d0a17619c96f6920884441bf7d563c744681108fa96223862ae7bdc4dbf46eb1c4adaa31a40ec489ebed66921e3d51de1a31dc6d9aab594dcf94eedee1ec71ca4196edc8a7674ec33129bd56a616339bb502113e16c4e888b5ea4aba1c5520051dba1b438f691deacf598c3c9151c28df5961fb637feea239dd576582a441787b5f364c864fca9c4aa1679fef747ae3f488fc032921a30be9ec244585a2564eb7065fc6150d1b621b4026013e5abf5d057b53190f08bf10723373487a637355cecb13dfb6e29313157f248c62d3dc2308daf3f254f06f3f70238e671e7d9440d80e6a8da5ab67db447d51c519121fa412fa23d011afff5f8c5c0be0fab2b2da751d0d16adaa32cad97e7b753a7ba0111ce340114b38145c66af14b10f34d600a5782e15790f72b7abe4b214d040f843e9472679fdc9df40679c7da2177a6b9cbd087dac25433e9e7e549df68eda3221fea3f30d081914b7c9a204986c846db6ee2941661e60874f8b752afa147b6440c53965c1aa75d3dd457c9afd7dc687829e85c384efce6a6b0988789320372eddad3e957c20b7c03ea4e777219d0b636442f2477f060dd6385946d2df75bb47cf4f7afaeecf1e57b74ed179e9aa025a29e435fe1e7f7b7c3e8aad1e88c6d608bbb49bf0c07457f9820d8c9efde01ef6e8e72a8441f6f4b98e02c9a527ba270bb0f922788b11bfdf93fae5645dac0a6352bf39ef36729244a0245acf3ebedaa4089bef9a624ab56d18f03e602f773d8e6280ba3635f55db76e6a00fe2bf95e564bd954f1403dd3be0cd9ec81f185298d9ca704de1ea97f7694a973b1f5899bd67f12efe210fdc0a670cd4689cd43ed8e56383b01b84074205f22f47b8933f5954018ac8d98e61c6573372978f177938c1e446a80284e0c28d23103adfaff4b27d24329d1d685ad791b957dbfb0fdce9d208adeb927d9874aef367c0004c13ae0a86fc3fa18497c5fd8ef2d92efc176feb21ddddb02510e9888070ae8a517ddbc7742bee4b3a1a03a03caffdea17fb3c886de783adbd0750e388d207babb1e7de82bd80ce0bed9e949fae977dabbfe6614a4e881d0a51289672a5ead9a75dd32238660e11b59c81e48df6a45407582d593f8b3f34f79fe26aa040c5ce6849287c31384326c94edbb2744472929b3412b4b084b996b987afcb18c24b8ae4e0550b5c0eda1110111a011ea270c18852e70fbc38b29722e43fb0db79bd7736b1f0fc519e3ce6da2acb6f297bf610f9a7bdc60bc318ca762af290043af03e799962b1018f497b132476b87515dbebb7eb14cb1c28e587c58cbce3d33d66e9c90ed6b768795c83542308246582d4333971824364a40ec7c3990e73bc0b9f5d4ae59145dec0809fadc3e0160475703aeca8a9088530bb7c95d4aff4b6ed6c9d421240b7b815248c823f03397c85e2a41c29a94eb3eae0232027c3d82c9265dc480afa612fd78159eff068e81da3acd5a3aecc341431e9d86a610f2bb8e056707cb3b9f044aea4178e78bc7f0d062b51a77b41e6932f133d11075b4861ec78b9c2ed8994e2921597a07a488468ce35fa15ee4a5115a5197f62a66329a7aed8962d0e4fca1e4e3e7f92286fb70cc29f96fe414f43975e9f1379323f2cdabd545c5e6b6391afd1f2b30ea39c5affb62ee9f89ef15277f7dfa2ad35921f0b3d2b7b87df6922f8dc7c4524ed7bf955a554bd5ab27b7e761078daed1dc56bff2b50643c44ee6a54dfb705469fcc90078438e330365e89996268fa47d9792841c7b09f9df2ec14074af02cb26b708c85943cd94364167e06231e4ba6c31e46213787ccb67e6fe47cc5e3b6bdae95d6741660898ca966bfdc8b434b673385ee702dc321c93e04563cf5cf29e95e190411f7f1519b0a3ce6339759d0753b56028f702dd83be8c7db0893ab19dd503967060607b7425838271edb2cd2dc74dc530760483186771ffd0c9bec7bb086c4f420bed030b5424c1f781f3f9582156f54cd54a8eea0371bf2a39fbb647a9be623314c706390d2f1cf636b883c543c08ac7ba16aa77ad9a4667b93cbd15769a0cea2c7e92d600cce287f8b73c11497ae1f04b54a482e9a7573cf022c468a2a8b5b02a714cff14ac4c7bbf127c0fcfd47f23f367226806faaf7682b73b178e13429154edb5e544c88fe63f4305ff4baf5e7b95d0e53c4885053be32053ae00db3f4f052d4a30b05486a1dba7c1ae2aab3bf215078dc9a632442f09d8b08e9b7f5106eb72db85f72d7c493624505abd09c32e6cd49689cd0273510ff736057bb1d80471be62c7fc1507c11ffe57ee1147eb8d3e2cc2dfb8a3b6006d9fdf8bf67270535d3ea01fbc055c7c3640ffdce3a9cf878b0b057517d7fa73ce7f752a731676979663b6321f93e6c32cb615ef3c3b2892e16a83b1dc250f8902d28ff9163647a1b2531d843be84368ddd9ae942aa1e1a912462172cca85e91c173703a90ac2d0a65266a1828639a47313bc239eabe79412b44e96743a004299cc418c7a733d5c1d5940475d0898c96274632f5811cdcefdf03ec5b1b852b89a350eee2b0eba0ba749e872bcee48b8991781ed4cc5cdc4c5c7942ff8429f3cb818307b3e9e359cd3dadcc8dbcb3e0de0dc05b0bb814d065ceda06f2d07149510131107202279bdc7e3bd2677d51211f5865da3c003ba4948e5160db9404d879ef3d19f6b420c1613f10a2dd068d0424b18b7dcc36535aebf215aba4ec8246fb4c833dce17c83a06d4a1d00960bb1c51af5d1c57e5fe237a8d665197b2e42c956f8a1b262871ca2e791d1a93918ac3450284f2b143197a36e303a9bf624a6d445384457a4cd8bcbecc86e83af04a31bc05723f1e6cc7728360f2905e2586fe02952dc6489e33859abb869df56b6d6a46ed518a7bc9d221e58ee918444c0168e74ba8ea96415cd1390a56837a2b41a6a975af0c830bfca70a4f25c644a5c83016fc3b945f40b67c40d4328fba9aa4e6b26acfb27bc3c9ebcd8efa820d133cfb260101ea5b83ae634200bec90366eab172bb63cf01838b26d2004aee5829c1fcc1269863bf9ac7836d1f74f9e9ec631a9513d2012752c610043966be300618ed5aaae82b05e2ab33c1e0297fec247169bce5b62ffac3614721f4818abd7943eb6e6064fe2eddaf09c2f31572e26ae93bb008b7ae3518346548de1db3676bacd119f3c2d2c9d35e3794bc0d95d788b785627f69534b48c82b073d39ec9621821f0221cfb998d3fd1329e0586fa1909553da42c83af706365a35db5cffaad4e830bb5c71f77ce9920a4c7029a406f6bc022fd1a3faf7784e6987b8927d4e5e382254cb38320fc2b8f2a7491b29a5f33eca1e84fc073936b6b53356a808934396c738ba00034b8786e6a8868512d614efe9b33c8682ae3e56efc4832a1b4cdc178b0f865e3eba0e0721ce80209ee56f076ea7b622c39981a0243e5cd7e378d8832637f13891a76ab7fe9d8a5774e5bae530dc96bb60eb81ca340177e51a562a3657b6d51286eaf050dffa9845889ec3a9bed78fae9c0dca40e52b31e04cd752aa97c6779f0990afc40e679fa3d10ede239c3203bf17464b0366172fcc7647c72ac7097f79a822194c0e52fec351e9664096ab892be59ef697786a5d9e1d91c768037d13b4a289767bd53f241c499a13f13baed4b7a09f44ae5b8f2d4c74f1e259f9fcfb987e33772e1f0424e9d0470486df547e10617e8a08f1fdc641a83eb4aedbff2a2f9f4aadf9f6d1503719b862958c42b4f1218674b47929b136aaf84cff9de88cd10954e2ef9481715f941bc38a8db262635971e359a3b1acdd6856d148d63696151bcdaa1bc39a8d67e546b0cac659531b07b152091549c06cac0213b78e07aef383d4f5e0753e409d1e5cd783d6f9c07572d0ba1fbc0e7cc05be707af7bf8ecd479e30e1231514c69cada36dbfd902c8f19a6143d8bea66a014fd10a01debdd63e222e0f2b33930c137ba7be763440d00c7b83d756c89cc02a6060450c696804245d50ea43794cf10b03db03f21ea3c7a1b122e464cadf9ff1400fdbcdf1c9e4f7f043b4da142a898c56af9454af79d857782f7636e58b4c8b5d41536c325002a5be2f4f864bfccf4ca293b152b5c1a72cc1344e64996d167ff1cd4d774134e2176a01ea4f9f678f3e5ccbd83e3343782d9f1c87dd193828aca06ad874e712f65d9629f929ca9d8fbb16ef6b4d4cf2b12e84e91ba20281cc94adfe7db2bbd21509e6e482e004853fbe03f5a0e422173e95133eaca3d979fa0336f0477d478651a9a9011f48aa8b053e1a00a1cb6cade011b03225cee9cc0227675e31d3e16e0fa102c2568f577d0a1613cc4643c24d0417a7e0b52f1d038a361f0722c10271326eebcde6236144bd1f5518c3dea46eedc3869e90942de91ca9bc2ed7ff2428c6e79380a3b1abfeae5dc9a358887f90cb10188e164e4148d8b97594a01b85f6815e2a483f19577335e4d91bf6f784e9e0ed0d97dad7bcd7f0ea53afb6be6717f8e79b6e86161245a8be2811a339dfcac83db3d8e4720baff9e0d5936b79c75713ce2c68b5ef389cfe8fd9d683dc112fbfeb2fa5415c74e265e4e9fee8663093eb4b48bd4f681800a6d6191d17351c52af7ffc8d2164001a9c4b20d9be4781ccfcb0a8ef2a54725d3b9e00568bc4a818cd38dd5005abf2ddc3ea2b79378aa0f48424ad9e0e7a09c8064d2a20c111afa95d31ba7113aaccc9067e6c8549d640dd307d79c53727e6e1ba9b854a3204901ec76db04eee47e17540c092c4eb500ad60e228b8a0c6d5c8c0ee9b59526b2128e1c33253624181c06b51f0a09fad74efdba1c2121eea0239cc40e9130028bedc45ec61d975ec288fd0e7d2eb5af9274a0d6f91227d9b1ccab9d0154845b639b524ee5b5a91b2eaedfba29c82af83a616b9d31e6d8efc9dfa4d2513e8ded4da8b17248e2e08687ba6189f3a96ad847a26de7f3659b89c77fb972868e1fb547e080edb9c42edbbec1f422f7d46eab45d1ab5713b516ad95a22875906ee8c2857806c4ee33823fefcd92df0cb8658ebd950de6b58be2a1cf4fe9aa827f06622307924c1bb4b1b3b59e7b8d5ddfec7322387820884cfd860174813567db4bd4027a91a49a7801504782f37806426f0e19f74a4f59c2004627c1df0ee635b2fa6b20f3a82dd761ebad1272e58cb1d82f7965c320a0306b3d767ece37077d5cbba293078d32f357f0eb0b78ed9cdcd921b5346ed56fbc43e18918e8c772875ac17d3b30658a5c90c0621b22d2e4ae82b8648c146bcf836673f5eea9ba5896051416d84268f7c3a5f941d615f3107d763a26d914c1b6f04e59fd8b3e88967ad9f94fd6f455cb8b571ef473f5ac9a1e44b760e4f1ff15ad2ade6ee0104a53a98af813119d4aac13624fd6a466195bf6505f6941f25d7730bcc2e08bd0c15343665c2fb2fbcefedeb848994b6b0a927819873583a27c61a18cf353aadd06d2426825469a1b4c5fa3851e66d82aaa6783efd75b88738e2ca7156e209f8d75355572d5a65dcc617122f112493ed94f263033ca4e908ae38046c3d8f2bcce0ff1ae2c1b26db62f4db4e2dfe08cfde841dfd2ded1a96b6c15ba2ddd00ec5f49d6ae60496bb8b36806469ed07a2391d2d692bf3bafe08aaa1b2a5053eddd499dcdc9b323ce93997db5123135a8bde95285883f3e3d0c5ed3856a52fb79ef0cdd06914d52fc9c1c00bfc16a9e9248b2ee7f85ef7a1c1775a02010043139f828239b722178474a97876c431302dd573bc85f357eedbe6d71a89c2d07ff155c62688582d18cd591e351b3faa04b17b142f16ade4a93bc6c1f01c2b542baa8d92b59e11a88d34d0b6f47a7665e9174f7bce57e62ef90f7c939f2a87266f01b400788defaffd5aa46631ef391bcfa234ed8179a9a4b8a74d19bfbfb87a122abee14fc047e65700e2a3c0c3c3185edcbe20c65318278bc1b90824ab1de9a32e1f805afb2c00c0a156c5fed2dc98601534e145903518c896071d02e65a9f7e9453e39d1914a78d11dc2ff8390272e0225a32f75dfc239f938ca5ca29e568e99ab18a301071436ed07f672e29ea893fc1aa78368964a99b69a4820fa1ecd2b5e983c4b1685dce83d01b301c3a146ba672a763dcaacc96bc7be4ee0d54dbb35bb0c4a23f5be655dbc8e61ab15f9cce82e750673df208d78ac87fe3a149802951309f5e7b247ac1eae45d263e8905bba61a51ab771d43c2d23ffc00bb0a4fe9a8b39083b31dae12da68c408b61a00328687fa847cd8afb8eacd465fbf054acb2c674c2c244ad50b4af5afc9c1f666eb836545297a7060bfa7da8bb58300e76e4d31e5224361e4b5e45ea3b3ea172586f46a95901462ee15ba77bbcaa867aebb39b656523f6ddeaa9b6a9dcff8c12433380fa617996c1774ee499986c7e6b141e37f1d095f2e102cbdc4b06b655d5e03de7990250d3f478879ed20eaf74d9285be921c1f3472befd87120eb9a968e5c6c3bb772ec329a369376795351a89aa0d294f16eebf4bb50418448a7156dc385a5d5f5f8abdbea74f13ab2681ad49d4a7bb4d4d406c0f2fc3f0993b498cefd1991b1f75c0858f96c2e49d0124aa0e2ddbfd5b0c5995db19e23d02a222db6978cd045304c266c623fb5e4311df671f70dbacc03fa16ba58007701f6374fce0ca1d8772065779e287442a30ee2bad4e088c503d85d2a4e71d2d666d170dfeaa851a38188c399344ff04fc168f902e9bb9237e159d3b48b5c5f609f147826967f05526b550f06d5c2cdb200126a350ea6b54c84bb185876399602e85fe9a3124f04dedc454e2e8ffdac819505c6d02ac0949ef4f739ddc36733a6f7520846d4dd4aa8e618977a2343b2253d0f7e617bddc79f12b0404b6f6ff839bfcb00498ba49afc0b3f7c4001da0e7556418c0bb4d5cb3771c88573a6a4c8457abfeccec09215eea152c4831c1a024f20897660fad3ea0d2f678e9dd897f73fe8ce398babf8a87a00650a148de1e07dd59ca1433c15ce95cc18e65dd55a26f0776e51225ab8584abf80752f44ee6e67c046a10e37360e196fede0fe1038b5d2b6d1243d8a5a6a5b8168deeb0204172cd553ff26861d5187dd0b1848a192f7efc1e73453ba348e7f788f76449696fba56f674bf9d59818f58251325a4c5f10aa2812544c2fc806a14b370b9c446abf86adc2c98dd83ece888a78a8ec7407895cdd33d8cea1b9cae92e7f9f4e8fec81232064bb7ad8c37f6258d6dfd0a760ea4f4a695d734fb841b760789b1ad3c8e7934e5b36cca5bdd53dfacd927a3abad36fd7122722d0c614e4d282b711281a1ea444275157265c6b7714f6276876c5d34c8ff3ee5243f800eef3a1132cd46067b39caffaea48409536fdf4b09acc148472185d6ce77904be2a7f25e24f500527b43beb0f0efa1a4bfacc3c92bfc63a8b3f9c06759b2fca2297b65984dfd4ea47c62db8a08395a99193686375e2f4ab81257828e1069e95f4fa12261ae6dfe55896bf1c4321eb401a6945c98e234b312fddbc527e367ec353fa9facefaa4af46d8d4eb4376dcb97dbb74f90efdac7656938555eb49b47ee78eb81456501ca11d6df07c29f19acf71c75d9868d3f6a346642aee4d1701963eefec5ca446370d11d7eccdc098220779e359418cde4527a0115c1b0b9d3d22800da87bca60184d04a21ca40015b01a21813115420377200e3284805600befbbf0506e61c9408ecac7873d75c36d222463fed21a0935694e159c31293b6adac5e28375b6e8d8f8ddfdd317467251da698b8429c019584e7e1e3c7b62b590d1ef9396658ea5ce3080697b2d0352da18366454938e8e7b6967489d75e70628bf7e02cc134956693a4e575156549ba2d2607108bb34fe78186fe4723941d11132a799e7b6a6e3042dbd6070a80ee9d048e7ddaf19ac4bccc37984909e4801772b7cd1491def5bbbe905e4424bd8e6bcc19a2d7e7cedb793d75efdf173b0b17ab4944fd7cd7143fb786b67a3d1cf298177c0cb21e82c95fd0ed039786c5240eb9f2b504e5262eac612f9872fd781eab41004a72efe87ea9dd45fdc17085569afdae8fa4fdd1cecb5e8685b544831171aa89cdfe478ecf517f6e464fde1987cb019fa3ef4e83f6a9909f7f879723085aea16a374a2f0ffac47c5980711b12f8676fea2e752ae33252f626df3419e7e358a62054335d447329bc43860836af0f8b7154d2c5dc0ad05d2af46092d0959208cdb6d5bd24554fb94bc2a9dc4960d70bdd673d6e03d6d1d4964735fec078158822b7cfe44e99ff5e8249854b11a047c18971a49cce6b061069b02de621dd49060e9d8ef2749dfbc1a3d10ae775dc7d9ace45612950fff995d29b26de8c6bf1196d4bb52e9126201d4878155131f45d15c2d58207387d6fa28ab1772a5aed866f4bb46bc1f16894589191d423379b27b37a5ab4f389a49a72f728264c92eefd8c04afa85e8d1ceca4eebd7a1664b48ba68ae99cf01ad4b861cc533b83bf6d4d679bf2e113030fb2be0079832fcd115a8324bd1a7fc6a9b45723520371f3595b21c95c067040465a69e7387bf96265d710d6cdb4e089e35add86284b09d46b6f3a5d4f7c7aca86ec6913dac00b17b00975ad8b34c07a2deba83bd630542f280b22d768e9fcf7c2a4a3a8b86da35da3e3836a0b71281fb687de0e6abb54440b77b599e58f4eb163433985b5543dc9dd784d428a667a5787a3f0a11c931011e137c607dc3fa9f04ad95f6279ba63957cd576add37bb27cc52c0c127e25f7ad67ea4db2bd43fa52ac3582e159d726c0d432201ddee8e36eee44a53ffac797a95d683a9b42488f2c1896a773af7aed21c287b678045a99f16f724b3dcbbed1ea075726b40069a31a8bccf178e12cdb11dc3aa47f494ec00015095e3b0c586b79c46f0ad7ce1dc362f518d8ec4c628270417c565b6d3f996acb7fbfad6f81739681280f7d3f2e1ab93fad83c74e070dc4e099c6db654e9a0f7811ffbac96e853990481c833092b788cc624b0ecc0557a529b771573f664216a4462a5af7e7fe9f904ea42112e75f4fbab958a2439ae0b624141d1eb5a4e5cee7a38934fc4b9483c8a1adbe2bb51933a21adc42b1b0245cb42825fb5c6000574f7d0f86d41695d05aec3f6308fbd3b3de47f17e23446f2914cb83c462437a373c8522be3422a96532bb254e3fb80dc74cfa5f5af7075db85e8868f85b72e5a9c114e8bcc5af3d9680992312a0cb90fef5e29c0faa58fc72c973c56e8e24169171399cee3359587e7ca71a225d0932131587174f4419ad995d433e24abb8b156eeb38de9515448ca6a820aa9beca337b53cd666b6503e5b01b08925dae3d91ed9f878895ec6097885c2e795acb11913d93a80ad2ac4e2fa2a3ca209197db4887a4909664feddd79f97454ed22c4a02d9ce0181c4d466acb828b794773819e80f5837f6fb957202ab6410559a32a97643e40b927981b7578af8f4799f19178353ed0a3b41067743e46ce76ce3befb6bee86c7d80f32595c76e7ea33d4ec87d8b19c6fa9b1a2d3f69858db9490e2400ccb71d7fa66cff7c1e669711abb1bdfde74c14fac9d04a126caf9bb5ab5a84110d5ae16007d46b15fcdb46c0046a1cd50048dbed5effe502b5858fce71fb8d55686e6e59ae21f0477f687e6f33a4df7e6805a1e4176049bc7f297544ea8aa4915b5a6730e8b2c3b2d200ff0b2054baa6d26cb46cf87ddae15aaab8cadd5c1e2d835adc7c0fcd81e42a6a72698d10d889395e4d6deba38a0bc77ff9442122033e0e247bfdb225b825f2e1891dc57b958e57a83b61083da7d1829d235e5983cdb253ae86b32bc4998c9b00a664e471163d80cd352c8066528ff34c1943a4a07322bc8176b3a9946988d3f494fe5769b9d97ebb447a4b5f60ca80073ddb6e324b8fc73c959131f1b5823bfbb85c27c4ec7a25e4f846b7e09afc532386c77ef36a5ec108e9a999c0c768acb0b653be3451f989dc2b83e0dff812bb86fcdd4050be19bf70b5ea9553e10b134f642f1b6ef2fc1ef0aae8dd16782ccec29588fb37b4fcc3c58b6ca06a948dcd88198ded0ad67cb45410e06554f9856e51880f1911bf3abe0c4c27663c7f8480754587990f23e01ff25920c8996177d652a2b8900a8c28d61f7ec89caadbd843d1ba7792b878a7dd119ecf37845ec9267988c0f3947af2ff6e118355ec3aa62bf6878c5bb41015b3491e361c151fe2bd4ba6162b93872f4cbacc439507509a418f1fd05a9aa2e77d5fecab00554874638061349471f2a0b9bf4058dadf5fdc8aa236e62641a90c2e5ee315c377f9f52d83811a97721bda5ea6a326d397cdbd17be3a81e4371ab8e59dcadbbc9ac94da1c50e4b605d5431338ce34ed9aefe851cf15f8e029c702dc1ba355f5deb0068dba91eb2c3054b42ded2ac2ba15bdb3baa42259ee1cc50844f020022deb1c72c3e7233dae06c19eb4dc0623c3b9fc9b05e6c4cb1f4cdaa33bfd033fd46904275c5bb873064f6cee7a422bc8569699f39adb506341c6f0fee328f35d9a966e9320e4ecdecb3045ad2ae246714b103951e55031a610bd89be241bd8921cec4307d29da4e6e03e89087a28d7af8a104ec1c0795db59ed657c459ad73a005ef9759977a213b95ccf20959895148d969c988825a75e0da30e990573797d1a16adbc6372ba1ea149dd10078a1cf817db91b32639e9b7e4e0d3d8080818c1dc44ac37572aa5308ebbbb9f804c85136290c71bbb7c17123bd4e8c8922294f4a664ab15241ca9dbc1fb0e06850c7d4208f48d1b3b3baef8bc2a6cab91ee60a7a8e9424968532d1af40e6c872afcc7ab75fc08e27784f13dd4f729502566a138a723137cf026ccf275cbd4c05bd7f5ec14e24ea7fc0679e5acaa1d7b01a783325b9b1c5cdc12e30045a1c4a8b5328376b252d93c700544bf93c224d4a29661e074e05b80c997ccc3f869b27287a575ff300205abf720dda05442179b15cc62f4c1e7099b664b095743ac5d4e0953298ff7526950c1a3c728750fb93a77abf94e66defd6d214ae0bdb7a0fd7085bfb850bee5407f3c9dc1a973cd8a0607edc5e042939c59c49009bd84e2e5886427c7b26864e1e51e53b7a2be111be3855370a067c22f7a65af10c5c7307db899944755676ea0fc52a3511c8c302bf6c2342369bef5b265b11fec35b850233673cd70a0491b91a777a3ef3d634db61532158695964da4958c9b01b66e08b0dd44eb26c744535939c9865445c80b2f6421efe5d75299afd016c8bc60aa1783bfc0a356ac17477b2a85da4622d3cbbd496feb5089a7ec7b81db171f97277dc24ba4fd3fc464d603c1f49ec032d08e742accd7542671d5914c163af8208d1aabc614d264623ee8ca4c44359921a77f9ba92928d607815b8c6461f983db426d1d0616b5b333ae1dcd392977ecf181d5258d5550d4b6b39bfdf14596b19bb7b6d77283fcae385eb5f1e2363cd66987f2774e6a3daa64230328d1a8ad6a8accc6095110dc05d4a52b4cf7d8d6aa7e849c51ba043e0a823f57295f66caf769555c3e24df49850f388912941b94648012d5be687e576d3f5bb586c56654f748b48b26195e3f52f18088fb0beb82affb87d7aa0df53fa49ca086edaa16b4614b543d3d6652bfec05f654725d0b9124c03d278efbee4e6ecb80875e511a58ecdfd7128ce61744963c6e8f07ac783cea320dadf749066dbcc391fac9a9bdb651ff26838c9747b7cd4876ee717610ee7865ffb4f6cc853bbb5f6db5fc7f0b89d4af15500f2db06518de6939a10af925da60cd3b235f128bd1aab5e070d1b7643cc7e2b885be673d3c39ef359c6bac70c3104a3b5f03f3121537c78fd7a8aa6a4cb3fa77af704301b0c87f2fa5224f87711772e62e2e9747e52b7edbed1d8849e03facdde91592090ba9216032cb8aa12f76621d24bcbe42f40247e91562ede15ca60e0e73cf36e34eeec7d0b972db486382914e00c06b540a96a4a1a15754213f8e9aeafbf78ae17fca807ffbad584ce691ddd116db74608a126b4b2bb7b07280925093009878f64c89faf29e986c70870a36f874d293c75f83515bdc9e1e9000e7f0570780e85c363130e2fc4e4f0480270f82543874761c9e189821c8270d8a1cf811c5e861f87aff201d209494a9492f0806489c861cf7d1c7af097971e58f038fcfce8613db487df083f720880f31c3ea6913f5fbe3efc76aee3d0bbcee12597095485c69c1c5ecbd20978890471e4a60568a5c75a784e6e5280bec94d50b4d2634f7e23372140b372d301b4d2632a7c959b0aa0b9dc64a4951e23facd4d457a2be0262ce040501e04010f3ac08914e0468c7e24173d96b50d4977412731403bb9f4177b082edc85ddc48501e80fc8052231fd0de0db85105cb811222e0429e0420b88b5a0939c72dc8fc845d82100fdedc75010daa1a9e0a024a7adbf1d990206a03f146e08f73bbef7d69f0917da424f7242417fae8b1082fe727e11427892d30efded0bc004fd091d85c75c3872895c2341416e420b408f692a5c0b26c472dc480b381ed482b621c9e94f720aa23f13de447fb10fe024402181059d9400edd4d2dffd072c18394c53b92c10799213131602a03f120ec402d01116989c080b1f0480c883b0a0bf20076ae1421040c2139de484a33fd881682af73bf2c308d049582204c87fe0273f9ee404a43f58d6c2d07f682a9789fe7edc25b0030101e92fe84234150e48c8939c86f4d7fa124d05ffd0df8d7fa0a9e01f1f007d48c8979c04168280e80ff600682af7c87d0284c89320fa0b3a094f8290f0242798fe700ee4c9cd8d3c810179921311fd053913fd91f0007cc80186aca0930ca09db0feeec7e33e3495bbc29127399db082fe863c4853e1562012e463051efae37e64051e4a8e9cc80afa23f2a027ff29c010157492938dfe4ef85ed74712fd057d08921f1f9a0a7ee9cfc77b682af8f524a720fd21c99ef4d0542ea7bf1e370992070505fd04fde027e9a1bfd579f4e0f1242724fa0b7a929f23f990158c9c707d5c252a10d19f910f5181c89027399da03f9b2b51c187fe587fa9e0e3f524a723fa23f213f437e44a5e82510929e8240268274d7ff73a9acadd4d295c9e148ca460444b21058d3ba2a96429e8efc88da8f022994ab69b8a4a20d29fbe0e4de5f2e828c11629c2a3a960ad3f9eebd054b036a2bf9aa97075ae692ad7d61bd1543823468a1829f224271d3afabbb73a749ee454f567e4b5c8ed4bd054b2dd9402bd3c97a3c21dd11f7d099a0a77a4842739a9f4a73a47c4a33fee5a53c1db8624271efd24a7a9bf239ffa2be1f442b3c90004800293000c2d394149122426e4111ecb247c67a00b65213f9247780999841bc9402f92859c481ee14332095af2205ff0411948c3ff64215a02215ff041f2085a2ac917bc0879e72164efb00c0290ec13634efe23effc83ecdd47ee79650f64ccc97be49df3c8de79320074ce5566cc894e72ba863bb47422efe826a2eb648f4877398ebcdd9553cfc9d97172f7d46fe48c95b7e39cfa2a6757e50ecba6a5969466cab4dc225fd066bb021ab648b36bce48a0c4022936cd330b0d5034d833db1d408006061269861b2b0390fa059b1095741312923f14683bec0bbab7d6c3251f30952f68067fd08c9671eade9b5f73f6744d3f037fd04c14970b6321f9032bb53686242fc8577dde00a65f50845d1152cceaba6378010afc052dc52520848290148989813c3546f8bdb0a504a955fe1092af0d52f943deec801ffb87760ff5845b9b457bcacc9eca1e94e5a0fa2053b21d81b9a98439828881bfd4a68f6bb6fc96af6ce71e10d1ec18e26e9ac0b65dca6ddb9036ddb659bfd42715e035e814358928d6180a5f767d9124b33f986606f8bb512aa828a5690618459f484a67a500d296b3d62921851b9452eb5c00471d0586cfb2419ecf428966d494d97996edc44bc9a4e4de235fe9710f7a1ceeec42d2831ee7b81e3d1ef34e8f2cdbe9d123fb0ef723eea8c175e7316731c6b8f3e57ce736eeec1c764a72ce390046edcf4a972d25e731ea2931c61863ddf9dc3bfaab42b9d89d9093f3c5ed8212235f59b7f32c6f3b99ae54c897dca94b70c8ce65a6eb17f9c2227f2a14cf79e83800bcebe438941cbeea3bba3e411f8946be7ee0b2736c789e9d9d9d9d9d9d9dd73452e0fdd5331b03816f7cdffa3bfeb9f60ede3bf9dfdd3bfad3baaa4103f757d15435f2e78cfc992ad04e908a334e789eebb8771c5dec7b2ef00936fa3b9975a83594af9defe84a867cc119a94a3fc121fa3baf3c348ffe5c00d03af487f74a477f7773ab1c38f42757aae3ad755dca75eb82bf8894f445fe7c53693fc91ff8e40509b67c85923fdff2144afee0b83c15237f762e4fa326508fcb53a50924cbdcdcb8f987f78d9b9bdfc854e97a87fe5cad7f5309c7639764e7b0a34ad04747850257285d01b0843f59e6c975f91e19caec3b5996c1b98efe2ece3dfd619ce728f345de8bb1cbf5bf5e30d817b423ec7068fde5dcba32dc391fc5c91fbd915a608837b2120c9407d7a78f93576518625797b8fdd5a5a56f9a994a53c96acda30bfea81255923f4b6ab63c851b045ac86c18bb376960798bc42375aec02f36ba2ecd6a96d5d71398db10ca026178d8c00221d8df6f012b78883ca899b7c0123d7c07353c3019ac70c8384f63e424a464245314d04d0c7e8b2d180c16020c0683c160416021c0603098bc71ef4ddd7befbd5ca4f04e209b9818f8a548908bb1fcf9512395d3470a31126675030c03fd91baf7a6eebdf75eeea6eebdf7b2388ec25b44ead01d1e3e71fe7407f2f011a2037de25d96c3ab584b1583e7689c18771004304c1783d3255f31062790168313281583f7d4c01d776f90345832cd73624ccdb4ffba344e182c082c04181c026130d85dd96b56579140aceaa81d63d448afb592dea803d35257e75e1daf6b5ecccad5f8aaf47256522ee3a0bea01fb0204499e783abf38ce7d2ecf5c5f3ea51af65b97368b7f66a2909fba0c72bfbd537bbbeb4529adddfab8704cdd4eba5c15ef5be226dddea7a65daccd125a95aa5b5d2d77dbd347d656e9787069db2fe7eb384d43f1d7c09947d2645ed6618a31986d938a29860a8992a023c85fd9285a065032d6e9cc0dfcd1004db4b93e1533ed205914bc041261ba1b9c88aa399881accd13c643765d764d37da6f458762d27ddf058a6951ebbba6a164733097bc7061996c803f4d1b265cb1c76803ef2ad2a7006caf121ff08c1e1c6bc82ec1c8ee61176d0c01fcd22d01c420e8e66187ef2389a4168858066203b8dcf179b067f540747f30f56991d1ccd1f442e5aced1ece30648981182b504d30d24da28022bd910a1b45a228a85c40d2a2598f0129d1250ab2d565880e34246b505aa025b5354b7050515d09ad0705bc4e021c504d4b685064b978bb6a58d1e889a404a82071fca1041c46529892474205ac24c1250e84094849a24ae50524a02044a444c984922cc0f444d5c72d0783f2c1de3964b2703d2019e293c2df98a3aa49981926ad75a5b2e18b561176994f100e9062f2c69d6e841039cddd0a305b8ab800722c02c0cf808036b4df4e0a00a2270b621183442e0031a5bd88059649090907e40a38c1eec5cdab08b36c6ecd71768a4410234d668c9c10e5128a17936c4062184104208218410420821841042324284f1a201df15f830836dc07c8044163d5650851558db100a8926a640c28331f0dd100a09227ac4e06c43282480f0629352ca29a58c5766526ee84329fda69c73d25aa994724a29ad94126fb9240a4a4965a694ca2ba794320535958b0a0c2184104269ed9c41a6a5f605a370a296ffece79cf39bb79452fa694b27a573ce7fd99cb37ed63ae7dc2a47d3e06c2aa7def47b0d01ebfee69c733e421ff8cd39a79caf5965a5130758d21aebbdf495c4a5524e6ae9cd6c5d73e9a51ad2bbe6d24b335bcfd09bd9bac6d6ec525bb333d5da9aada1d7d635975e7ae60cbd6b2ebd34b3f50cbd99ad6b6e5cc9ae94935abc532f6c5a6d16630d5b461abbd45a6d4699905e88823489b42012e88b16a01fb01e286f8f84e5095165d2c2c46491b0543da318242c99ec329753a9a65f28e87649ee6f778284d9ddeea2180245a6881441905ad3bd1913d2182631910b8d484abc540ba1cfbc4d9a8b71b4914b47648184d2768408761602117e80f6c7ed6a64d7236e30220c1641881140ec29718c1016f4579669b892704a08e12319f8c988a495b5d6c2664f7cace2880d5ce18123a8382266add2b6d65a6b6d50d06b7f2da62c76e02f36e5590113103d6bf0878384d9456c20db6a8004f3bb94527a420c3050031a41d040882e4a88c97410812f6c43c51a5bdbf2fc8837ec2f4811f8655b11ec0f8eb19ab59dfd6177aca5d6c62d2dd8918a6db394d9568b6d7fb1eb2f180cb67d90d01222226eb0ed9f403962db4779c1896d2f0306ae40d262859219db42282268c0a4650c9722b874b9b22d84ca0017f6622f62b6b50fb2d65a6b7b64e1c0bd9d076012a679f1210363260566071ba6cbf562881a0629c352460e148bc572831fe6089e6a96a40bc826504f7488206213305db238819b8c008d7429fd8075288049d8186a18e1011835baa8a106163d30c0aa0dc1a8d1850f23f0b6211835c078f980ef8660d4308303141217c8d9100c1b5b94b0fd6bc5bb6950a2440d0b54755cc76198109109a2cc182595627e3b929b3eca5e77b6b4cdf96d9bd56e75d65a6bfdab6e72665de04fa7428922034483f47a990934ed0f50505faa8e1ff0847042a8a5c45077f698c2b4f6846b179a98ce16a4b2473e35c67ce268ac8184a54b9d99cd7296d15c245f2ca4745c8a4af0009882aa81e16397c472306315a0062ffa090cb56f179217f38040ad0c7fec06c47d7e3e19c357e5bed12f587be27927962e775838252ff504f89387eae2cb9697f67572437461c134a286e002239a2070902a03268d96c833bb21b9ab974a5d0e490b16c102a1845862df6cb92447d8f2d5a60ea14fe5eeb32cd24aebebddb093ef5e9044c70f986e4be40fd556432d44f312263045a26b75419f3a035c796409f3f5d556faeb512d1443227bea5363e827b00b0ef194c46d2b19ae0e6838d82e1b0eb5d65a71b85d34e104c5e102693629a5843e74d2092f6574c176e50f84b0a0bf30b51267905286b1d18927d0937618a38f59529b669a3e92f747f38b503bc618e352f67b6917a3d0de69aa539a462c942e118d80116ac9eca187b14d6608a554c9cec84a4ce84911282fd4280c0485444949f7d99388b6db0c6348287dead2141b78098cc92529ef0b6212c6e6375967ada78f59c4e244c6a6ebb387c296b4826c7d1ae36a4d2a8416586ed8794eece78de636bfcd6f9e91fc7699394f49dc5edc72c3edc566f6e2535e6ccb5ebcd985a49682cd9eec3113ddec37cb32884642b1411e2fc2a889ea679452a289346c90e766cf3aedc5ec475ed41e91ea29c098eadd8faa38191d6557fdc8a9283beabaa77495edddab7057dd4a0cc660ec1ec6b6d82591303c8049dc148624f644a90bc978b3176b517ee23951a9b25ffb5de9a3ecde8bda48fbf58c52d9bbd76d4bcdab5c5a50c6068e422505c1a691524a29ad144a144a29a5dacca44501a5748b0d0689b4a1b673d8c01149860914af1ad883da73729f7ad17d4a577182af72e474a43a3db2bf87faa83ef5953e9a3b5be0d5aba84e6f57ba4ad59e13d5e9bd4d17a9b4b73dd1d7a752afaa2b94fad41ebc7609460536f8f0840e19f822765f349f7dce5bed44b347fb4b0d342640230c24ccd02296a9741558ff647595a96151474e45a9cf1fd17b2d2a0663993e4a69cf89fdbd077591fd7d51fdfc07d33ebb14622c3b9c324e95071f4351f6d4bbc77db3077fe4b4fd28f5ec474e9d2ea2bf3fca9efacc1ed41ea73df84d17ddd31f51ed412d03d2ecd17428616ff336ed39493dbb51ea993efa117dea463706b5a6ec4252bbd7525a5cb249d4ad84edda29942812804bb5ca5a291492b5d6babdd65a5fb3a7ea084d69eb6b985a19207f3eefcbf142945a6bbd078740b873c021f465e8195bd40287c82a1026f100a39658041c120f213c03a11816ece18bc0a86311d0876660533172cc025f458cb1650c228b0cb6bc05e08b7e0661c6968f715f1d97a00fb5400db67c84102ecdb02712d22c6385495a3a2595b27e61938254920542e3820637a8ae6c61c5997a450d2ee98cae0733d6e4d0829a43adb5561dd81c542c11a8ba484d81820c18d134031bd460072796a05e10517be0806a731b4205f1441a323d5833704825692b488091c314293893431850c82eaeb85c9c01020b986146cd813e08a61fa99b1d90b698316306f26c6e674ebeb07cb9cac03c32e6e00d4d087da2a69312d9aefc81504a2965bdf9fbb561841d84a2505c00cdea05a00b019248427290fcf9a07c8970f856ecf0ae7d781da1c3bf051e067c012f177e2800f6c307d97148857cc18770f822120eff04e8f02c08393c94270c48c0a144913f5f130b4f1d3621e0d961910f3924f2a0c320ff6152618b017e806f874d2b3c75f83515e0d9e157a484c34732f2e723a2e5927cc11b397cfc42fe7c418a1c3611bd0bb596912f49867cd517409f7a9d31f017a3caecfa28a64c7d952f1813c9c817c021364731d58ab59672d9edb35b2dc3feee69d7823e57c7a5ae49a6a5dcdb674357dbfbec6aef664deceff1afc6f28573fce14f71ed7b3b2538f8114b37021438fb1797602a95c588c56adae52e6ec121705b6db16427e4ec387f566f5b8ae3ba221ccfa1ab38d9c3fd45d9df1457a577ca989a65bc21fb794d4a8fe178130e3d0395426892147243adec35529ccd53cde56c9e69e4eb862ad51b7942654185c6d96dfbc23d51a8ce091597d516ccc4d26283e50610ada51b1e709472925c9ccd1509c71a39d4786974bcec50a1a3cb0e343f93cd6832005086e70b1e647a8cf120ea25a6078b0f9ca05c7e9cf1e16c9e6640d802630a418b085846e06ca64004e16c9e68e4ebe69b10cee6f9245f37f7d10dd93cfb06c4470f10204080bc80dcb46ed8701b10203e3e5aea0201726f06044896d90a8290114408418810988f8f8f90880195a6bfc9ad9c314b6391af8a5bae1db18c9005c3583d527d646aed2cbb37cb62a09bde52aca97c6dd9cd0f80adadfa223457f4aac8d55b6a7596c5b8713b460d73b4e02f46c52f7ef922ab8f59764fafbecf3ebba1d68e5f84dd907d2a73406b47fd4dd9574f69ed98e9f845fe7cb41b8a5fa895765a0a63a6fa64d0da3bfad1fd4531bbe6c8f214d8bef1cb06a486fa4a757d9623d1ce6e65c36e5edd85eae805880f187f3a9773bd76762ecb2df9aacf9104cefe71bb56224bb2f80241807b491623803e707f5b48de7b513856ca6eefe918357beaeb925e8a51f255731481618cd5323beacfb5a18f1af88b513baa4645b5a40757789c00771b42618145191f5c808a170a7085c203344d6460c134051630b0580a8389ef2d9376564a2b9d954a2979a49411afe6953f334a29a994f272369093569b5ff313c279b3219c509b32c29b26ab66361a279a29291a0821a438986dc468a6d2362a3d234633319aa9b48d4acfa06a6cb322118295ceee55ede479e6b287e59bbb2648d7b8eebd37621a35b95811850ffb834f104a0c0a9ca298d00006d03cc1c36cf292e68a2536231ac8ac5146cd0d67ac985cae5043857ca0a905300853060c282618b7032ce056adbde280167b75ba5a750087bdbaaa4bb282647457acb1bb735d920e7eb9820a1d5a3069a82b7088612079e1e588e8851559d02ff78c0d60993744696ddc0d285dc08b316b54c181304e40c5ec54625b0e6cb16d6a5b6badad628b12363de5a1034f154d6c7b2d151cb0d65a6be9611535dcab04864958e67401cac53e09319d18a14622c91eb8bf8ba948c1929323a27898c1131531d062861717164a2a8049188f1164a0870bae1b82d98193193b90c247961d6851811d98000736c2e031c271411457ccac59139b37aab7d393a79e8c41d86403c71c5faf18c5e002671b424df18507434031850a5c504a0821a432d628bb9871ce99d93a29a5349b76d639699c73427875d8a69c137eca0c3999e79748e78c311ecacb28c116e99c93b26084c1e61ad8a54c770a241ec86092228d1cc6589a820725319ea600a20230589ac2081ec6809ac2e90632a26a193268c0e4400d17186f08260d1df6771cd2c08018692cb1031ce016b918bb18a59c52c6edf5028128683e79f5f888446e76fd5dd3734a2112ba604bf92412612182208fef16391a6f2bc7c2b3a8c50d053b5c601965193c378c0c782106195e908f686478216628398a9297d4a7f6b844b36060cfc33875f001dfc727e910e2834f332249b821d004726965308d724e55d376d919c9d8762dc7a739b9cc1c9880f69cb71b45b24408004a48d769bba9018ea773de9c118b04c9d79c954a092f9c3d70aad9828a405953546ed5d4da2a9b3ec218dbb2d67cec7a043cb6ba2b48fe84005fa99ccaf52134c15be60440583369a780ba014e6d0825451a3e8690e28c1460ec6e432829a2aeb665f4a9d4a65d0c8120dc5259769ba57eb56b7a48ee2f6e6fbb67543f9f42d5d333aaa74fa16a7b6f964d2b76862967187b6b96e1cc663c5b4afc7876566bfd3785a7d6ecf6fe8b99f6ae1e82f2f54de1d936d6db5cab151ba70e5bab556374b58838216a2bf5dda44024983e9e9eba4610a3f6b25bed65ba08ce9e59290f4f4f4f7018f18293524a338dab9e93ca182319b576a952d62e55c71438be4a69350c744f3d05b6e52c82ca1b1b3480e1c3e0cb426b0d1c2fa7f0ec18e3149e3dcf13a714f16903f7e9be60eb42afb843b463522960e9b63293598aabf976d92929678c12069b3adff13cf2e7b6648fdc1c2e93590d60f9ec35f37cc600d77f98eeda35a148481084792a9b64b2ce6d730432ae7602d011bee6ab6c4277f6fbabb1968f99eeb867e4991ab73c805fd76d60082505d37e9a3fd58b33a4e8210db659e3c504c6673e4872c1fefec396367cd0805b5b6489c2cb52144cecef4544e103de36848a62a9e5a262a622a5f44a09e79c73ce39e79494d26cd23969add44e29e5945266f2be6094c6ef7b5dae9b35b0f8e037ac5f26ad36bba9596bb5f225ef8f311827ca7fb5555fabdef5663745b53937eebe6ed00666760c7233b17bea267bfaddd45aebeb9ba7347f5987ba5258bbd93247a98b7694d65af5a5db96c6255f50c5adba24f05072f3aa99bfc9755be0c8d9dca8ad16a594bb9956df0843d549c9cd0be16d3229dc340a21b4787230c0f1355575f637e7cce8cdaebdf207de4a7180a5a473ceade3b0d8b009f8e5527265e008e19cab2cd35524105b21b1c6524b2b0dd4d635965a5a69a0b6ae5943abad960c5bd7d0325450c69a32ce9401633c53c6cc4119136a4d171c37395a5bb5569bdda036752e417e7435501d2c9ab05bb2cbe2a214a4c496ff766cf81d48246e8920c821104875a82ec378263b60e7248ba57494d9338613714b4c8a4848a94deb5210c5002865b48debd2f2a203c5a170bb255b077b71af1712a15be7352d15bb244d97e7aa150eee82b9588129dcb0eebee068c375e1c2850b17c8850b9c40383155c76d5a54266f78c117632c9960192424a41b9aa0816b820ce73406eb092b5450a4e0c6179dc4b277ec8fdbdd6119bb3bedba64815b74832203504f8800a7f9b89db556e044164e423441868b04504d54e00699a14698113c098162424c1c038a1928818118bc98c0024b21934503496819620359d81c3c80a4451f3a5cd26c7afabb04984d8f97b0c1a63c6c8051118c0ecfa64d6b36e5e2b4e95d9fafcd8383314a9c804c53139b5eea005320586bd3245ab029941248b82e165603aee86a0527581981034427040e2f749cb1c9a085458e0dba2daea441a3b855dc242db57ad84a80a30dac04ce96ae0d17746d58e1eac1b526cbb6869a6e0d3170769093a56bc30cbb83141b2758ad41828b46b5668bba0136d4746bba986bd4c099a00d1b562658b3858574c5f502098acc0b1acae03594e8aee83ac688d41536c4d8aea051c65e69b9726c08e5010f4499800607f07737f528de7e105949795c3b50603829fe04d20e537fb2e93fd134edddbfdea5bdab6f2c51460aae6042aae2a4e9abedb38bb9632e45027be8efdd6c96dd669aa76a29b019b5411e3c81644c27661ef9caced26480716c18e80e627d09910bbf68d3de3dbd8c3ff29c5c6de419d9cf6b8fba48fb165347927b11eb9cb6124be922ed5d113ed71dffeaa26df39cb05e5fc47ad5de2dd2eeddec292df0b32cfbcd32d6b58d9b167792ce98bd5eead888754d7b29dd2435fe91bdda357d548fb5778db6b3b41f79f746dab973fa086bef6a8f88c5fa1136d2479c3ed2ced2de2d621deb2a4ef7ea22acd266cabbe7aef69cb058f89c3eda8eb7eddebd11fe9177b551f7edddb7145665a20c65f664d7f20bac55f62ecb328c6941b3278b58e42b68674b4c536a4d1be4d956abcbaf3a1b1b9bd56ae5c47b77239823078e635d25e7385ec57b8e5b8949d8c91f79efa0777ca39cab728e737ed4ddf3debdc87b77a98b72367c2bab17b5be7afceac6b1ae62f31bafd2bd752b31a9d25558c7afb2baca4a0c77c72fea8e2f8f6daed255726ef32adebb5b896115cc717c231c57e9a39ce3c8398e1f79cf7118935d124f7b91ebaa17e9b46ef491cd6f9ca5bbb7eea55e74f3d58bd4c70c7a4ca27dbcbf70cb6faae7dc087f471fe91c3f47e7f847aeab72b2c77de730e6658fd39e13d7736ea4f31d9de7e8fc4875d7a63d4d3b715d7503b8b4a7dd4aec06d0d19e86bde39cbbeed2559c8a5cf77415a873e81ced11b9726238349e3d32277b9a2b7b5afcedbf6718cb89da8b5bd7dd888573d63b9cb37e74e369ddcdbb1be1b08ef38e759c1fad7e93d24e6ebeba016eb497ba95d50d80a359bfd15560dd9c1e91cdbda2ee30c624de7eebb2973a8cd9642f05e4053d4ef51f8c2a923d267adb2cc53ebf90a1e46c639927ba70810e9e32ed31a1b7b75a4ad534c6b2a2c9951a2222e882572f3902cf675789dcf544f2e7a2205ff0dbf69b67fe22929ddbf6cd6e5151db3fd8e6dab66ddb52598bb0bd7d9e955d13c8357bb61c047decef9c73cb36752d9522ca02a77e9ba4e007a1b8772b9b1cb77803db1cdf86e3baaee362ace3ce3a8c6d94734d208eebba23d6b9c318c775b7d968c7499b89595fddc8c6e62b7de4347fb4ba11be8d66d91cff88f5d5eaac17adcefad445f8361792b24b01c66e646f7e35e75cadceba951b87bf916d329c3dacbca93a4e952f9e3d54c70af0fcf743bfbbc10e4ac2a8e9a106259a6a30c40e492d08030653982fa830636fb03a2d68c286304a6394400aab0318558c1b5610b5c54c0d586ae982dbc2cb952bb6060f2805f50086085090051a25184115b11578e0863ddf72cdc3a0b2508305582e13e6e2ea722faf27a8a079844e912ff839e18c9762ec72fd305850107d3a3229a5b4a5c33329a57386286f1adbd4b822f88b4bccc7bcbe809171e67e3a1066308319dc6aadb5d65a2d7de40e63174e7f3344cd3066b395da0f8aa182c6d7b64f368535b395521d635652334869b3c43441676064bcbef818971809effa8179a0b4caa0517391b09274c5a5a02818547c8a5d2297c804d1ecbab4e76193d8658628a6e8c40c63b643910f0a92d0ce9066cf25f055efc248544c970be309e565cf29e1ebc99e8f51863d9fb62836388120661d679bbc719f6bab609324ffa26cd5b56c73b86995feb46df3450922e7375025e0b259cff1b2332a809be7bce626dc59df62d62eb3bd0e13e09bef759800cfdb6b9afeac703902d31b8ad175d80920eaefe611a05b4a8edbfbcb62e521eddc6db04d86d0475bb1ec6a65594aa46c36e3d8617baa57aced3677dc37eedd6137b45dcbdf0c43da59f66a18ae24d25c71336c284aa4ac0eb7262db4812f6c7889a4bfbb39dd1d4b24782eaf20d02449ebddeaac434fc926a5dedac36f96bd4dc45ad4f4070314a41d03dd10b0f138373404ac705e8e81f5ce1b92c27dbbd552585f5d062dcb2d7f43aac3a8bf21d576a1b9cdb0a36c2599d35f448236f90171d35f44da753b772119f12a07cd9774c1107713d5211c426f1f5065775f6596a6b79a9eb03a2b4b4969ebc5572fde3ea5691886b6738f7a6875d6ed3f2b48dbea08d06df5d097b6d552bac32ee7782a47a4cdda3547a42de5e639cfa199b09e73d90ddd3ca789eada6dd6f2eab06372f39c9c9c7d31d055f68658bf39eb25c002c505991d332e764d6e76d4526c0452dde0ec7532de2a8abfc16e88fbea36774d589f8da68756d71a2b472fb3dee5cff5c9b0216641c882c75c406d94bbc9ac1bfd459b3f6ce1d6c9707299953f2b4838ee23d2bc4b37c9defde6f84ede6e471638daa7e2eebac76fac5fad752931d0ddfa77e3f0f6563f40eeb8d29fdcab6f5cfea06c2e8a2a43f1b27795cd0b5bbbbd97a1fc91e190b5ba71564b47206e9ae48b9bdbdc856412ee5df6ecf190ea9e3debabcf72df70b657e5d50ae7eeaa5577782e7fac7faa73d7b2c7d24338f7549e6a75f89caf3cd5f16d6eb377e3ddedb79c7c739cdc3ac769f9e639593bce8da6a9f4d0cd3d8ebbea387b9c1e627d75789ce377d95bbd3bf7cd266fc7695d95bfb8556f1d276fbfb1d19f95bd1d6e57e5ef861eb2b9b7fa567a8875acfad665acca71af6e337e97ed6d32ebb01b6261fd5959e91828d7e5edb06312c28e31c429735b1d01b9777400efba430b1c0fe7032c7c96e385663774b3e373e40e33738bdcfe5a0f889b76f837e32ea5303563fc1253293d3f9d9de97ba189e92facdcec4ed8ae6961da94ac54a7dd085d707c2a03c2f12c098eacc304584a03b27fc39de9b8458b7c55fa6d76f84d38eeb5c7b93d0ece715c38872e1d97628775131c1db1e4fc669c692109378e2cc9903d395a96e1e814570bfa581d976aa10ea894ec98a972182a44230000000000d315002018100c09450271300e26b2aae90e14000e7796406c5099cc634990c4300a82206300208600630820840064942aa20301946a70aa9e4126bc9c963159da9b7e6a1782514880c1f32f774369bf5052c700b13e82cb399fa52af277b9f0d0be18b0876bd0d1747de2522fd6b50b1a412694da9fa8f606ba690ea60c289d1859eb9757a711b4702dc182bd32a8bf5bd29f58d408607197163c02efa19be661da82597e4de90c15f52dd204b4dccbb155ba44abc55220889d5250d440e75fd6a27da565ef7305e2b31502c2c19f7d8e10781857526cbfaac8d603e3898e6577258a12a014bf51ec1e95ca69561c00a6ddc5a608be431d301860c8ed0e9787ed2406c2825bd58d10a623630f58985a1801676ad2893ee0aa3da594a1d5b4b63cb02e826708cd6cc5497ba94dd1aca2a9dd5dc3dd3ebba452329d7322174473a262d4a6f510c7818802106581ca7f830da512e18d059778e5591a15aaba37ea057c195b8ab37314dfd9e7993adb4ab593cd51fa3c57d402a5b839d5d9a2492cc4404247883acc4420601484f3c3e32509d7f4d2c15b8db31be32fde779d62291ad12f7c08e24d5c84601ac8688684c6819f30fa0b6392a7619a5db3e8078d97710c0c3f517aaa1510eb405bf551329e288bc2ff9056fa88ca11fb7dab724506fdd8fe764cae53dbd5447e6898da82e3324e87191b76b3fc09ad65d42f271fab29f0b484c439502f24c003fc647a0bcd03911591df42bd02406a38b8924d50c05a00f190840ea00711de30518268952e84556ec3413eb6469482923289a966e568a7dc7aeeefdf159baad3f4b8d5e50bde370db8674310eb77e59379d9a708bb8de482ce0fe90e0eb41e9f366bb18a15b55730320d591aada7180f4708bae3668f6e0678307549de09f455d8c0b6cf12b9aef5a36b5c8e461425e7cbc1261836083b22a328e9ccd70fe11aa5da44b57014ebf535d503372bfe085f122aa26f168e462e048cae005da3d801e6ecdc0fb443e894dad8b204ee41b52f491bf611459364f61598c5ed6f56646f12232159dd37a3f51e093754c77ff125fb62f8a9a21c86073ed636a8306528554bca2a25db1278d603e83e8a7aec0f352028a6792710d15705a2807129821033548d75ec52cbbf0c7ccb466dd056e40db05d28c9066c9710da27c56ab21b26747771cb5fd6ec1d4afd5824a310322a27c516079ad0322ba7f33d30d6d017b8c47e0c635085a7904eef619e2333c063995a1f648d4af8bfed8937aadd61cfc061820cffc6434bb763c34a9469f74464d9b11014c0d82b88f6c3275a18af3fa2b053eccbc81f34f059cf05e5fa10286f6b4eb64fc53d442c55ac87a72a648b153e835fb66d132b61ad1adae757066402db534052afde3751c88106a10cadcb854350d5eb2d0a31d335feffcc303e46f324740124ff816f40f4aa2d945578ddda388c22a4bde6fe2942a09285cfac04877883264e0de93c8f505097a28be9c0ff28e7fc4ac6c8de4b23292e46474a3888090fa88f0a431e962ca8fc4829dff3d90755f0dba504acb0ff256e4643d7c8a090b63591f5d81e4bfd6b04b0041be29c93317113bbcfbb55815384933a3291b2f08297ed41297e88123c8732329ddbfc545915e56a7550fe97e658ced39b28d4099f935b00b0f5e443b20b0a2cc3f68fb1b4e3f42936b35be4836c0877ab9486a0f5081f347c59d72f0940ec17b1deb8107098a7392149972c8dacab1655b33e7f99a6adb094374b432c0d9298a45e82d9906443b380d9063ac1eb9a80363b5814adcbca7232f47d5cc19b98fc726f8ae8f807244683456a59b43994f645e2bd28e0f4ad7926517f646f4998c70d332c7a56300922c1a5e3797e0729fb9d1f8aff46695713a835c773c1451123e07a2a04b04f943c88c9ee0b687c1d6aeef18e71e4a3338505bf8109201099ad46bbf7c2837dda08a6ab02508bf0b3d5a1ae930a8ef2c208a23340ed3ad630e46967a73cb17c45e148f5c1c9a9cf4065f9ec912ac3f9ee6d11830f61eef026e2365957a02f820415dafe6ae30738c188b31204a109a36d95b03b2215fab322183f36f5934ba754137d1b0ef3c4afa1758f90fde37819d434b84c74011bf0d6f5883406a5742946e507d3c0e5bf204f09860bd9d2f2ce7326f982be1383b0d8438443745c9eaf514c7ac95db1d521151327b6c8d50063ba8a5882fc7372186824a45a886b788000e2db420d801a31c8fa1d76bdf45f84ed82478a347920e89bf93e1e4fd84ae03e90aa43c32a7c4da37295fdb19269b69b50c0fd179dfbb1f403f33e297b3bb1df44318c470ba591bb154592d76eef54e5b91e54aca063f1505188fefac26c045bd6d53a82b32c5d48e6995950a0a5161dc71ae261c9772400637b1f6bd1d3a8c2c58516d98523e787c62e072c7f421e206552147ba2a8286f120fc768f8504ddd869b109e1929ce61a2c7315011398dc6b07cf5f9f80647806d0d56fc90fcbd6967940dee1e67a841c703847d26dfc27babc58244805092230346d4b6c81c9086625d49577f793a64fda86db5fabc144d5e47de5513b60eeccdee0159c5786939a7224193acaebdcdb915b3ee50f2c71720b3158c7fd940343018f99931b24577086451b9856323104308868701b0ea87945cba099cb6e789a1fe861cb7a2336cef279581d2e13c1b889714b908074e2028857e04be0ba074e77f7edfc0d4022476e3c2034199af049d206ea9da807521d3741495685d4d77ce4dea8ce1854cfa64592bbce8da72af921d075f4fae73a15beb57742f29773af7c84e298ce4496ff7ad524ad47b96d3d46057b4db5d3de2bdcfae76123ad6456fe4feff92161ec38e7d4374d572448732fdc518acc302e148ce9b98951f47d092036369e59f3264b60ee3423cdba8bd1c846425ba95cbeea80b7e3e296b0badd524bb8dc4152fc7fa8e9f95434e31c54367177a2960930e2259e490e9b3b03298787912c0303d3b43585bd119e2686ab6899081d3b6bfcf5bd4d23a10d760879f7d574848956e50e411c831b2e5e698828b9b6171471dbbcc1f9f03ab5c84d9d5f7760b13797d82e5755b71f7017e7d60118f914b1926e8ef11c59286b602ac20fadb597cd132fc4c40c4594d3b7acc7e809402db5066463e7e5d48c3d8bc678e8519807a0a8bce6ad127a1e24d452d4ca096b373390265b2954b8ccc8d4b974fc361668f8b47580d2ea00c879dc83e700c917592d8b91167bb59981a29817f69b9ee6a806ff97ca8c821180d09468c0106221275b05042773577f7eb8fef0f3fbf7d489b68645de51e027a1a9b1c9ccf2616f613e654ecc0082bc844467a52a42f2c00c1ca99479ca6fc297dc4a235140cf204ed843676cac14cc7e770000d6fdc65404f03142fc37d715e945950341ad1c755fbbbff3702e311cb9450f23aef20dcedde5e52e6f02e4bd2fbe7fb0c6882ae633e0626e0f7838fee265aba10dae4817d1eb425c0d77b1a57846c2cb6c15bc93833a7cc250ee94debe58db9a8c0a6d83a014bac2555eef64801b548eb46f7ba60d2993688d86fa79cabecaa0721be4eb4f521df625cf7fc864c188afe2baafcd7e99e3e17730515795485e99253cb35f7b10075c878086ea5b58931bc33e6260535fcf1cea904697353ee7a66969854768685b721c4c67e97f950891cf6631f34016c8004ffa45ff2561350747fec1604d219e3b26e26de4a9882b55494af9706cad4a88f73e1f9574cfcb85db1e183137ccafa14d378701222c9be12f621639bc9480cdea0707a13208a91ac6b208c9d1f20981a3163c3da617b87db3a526af0625acd3331a73e0960c6110ac8fa81d80baa82b6b5480ca1353523f79f5f314ea0a8334e2814371860230a1ed33d3a98efb10b4a7211e67aa1c5b9908ba1ca54c57c877c42d66992ca5e601bb3ad8c34c9d8305b6554552cf3de2f6f15a1ade069c88f83355cf4a839a04d83c11e395888b6275f71518ff1a0679768233cf483ddb2bb3d3e326e6166defd884c6c16b208ed2eeb989469529213ce01b111826905af023fb7fd6146df1277b309dc28e102203045ce2080d9cd81677fe30b1731997effb4fe988f0b34f96c8920c117e18485cd32eaaa74c1c1f84dbeea2cf5096d66ab9cfde0e65cb24c82554e9165476e9d4b935570cb0adf7fe7c15951bc03c26e12295d8da204220424782647902575b6560e172535669f034f5664e8d9389e9d93f58bfeb290c4b5d39084f924bdb2456a75b7dd6a568be9531f0a69d372011842c20567a6f1ac496c63ae4f9b48bb1d285a412afc67284a350d5bfe18eb049f43268b998e6980155e8f231c49a5bd4e8d4e8aea4b2ea83d252c156b08c973bffc8b4498bc9ab33bd5b0fdd317e160b031bc5753b6950367b082867da2d11a5d34c5355dd642993c54b5feacc3b1448cc72f0ad4df1159ea12335115e7bafb71bb0d76af44c9bedc2070fcbbfb36fcb88ab86684929e1053925736ad2e88011c731b293e0fa73c202fab60adec36dae4cbf0252d6c46ea76cbf8d2f59122ba5c01057595955ae2d9acc87ab821c423460fb5be1034fe9aeec9561adc80d95387d82b0e924c6ac4af58f31a20541537ea762b2fab57422b684ca95204188d823d2f7c9c900e0ea445863343847e43520938bab887d81538e8eb936bc4aae9b8a9be5f18cec1ad2cf1a767b2030d5f1d85bdcfce8bb6d21806c9e7f0b9f77b86be6f633d91ae2ece2e826ac4c4e31b875e25e476b2ea89894b6805d349bb99d41c1108cc84af010bea728dc5768a9dc8a3d8f977299e0f76b3ee3bb3d4bd727c569fbd855e410b93475dab51d61e42a40753011e3190d58b53e4f93b6d64fc384e2ecd106f16fc0afcdfdd70849d953a037b60e9eafaed1768446fb468287d11f4bb42601f8e3e41841ac58826c6189acda3fd0a70c9d7792f368791418c8e39e4e26eefadf0ed092784ceef4799be02370b075032c3179aa66558db0a2397d5c8a87b50ac49661d149e32ebeda5b0edc419afa4c63ba19e6f71eb3a1c2d2b41d5a4e357eca4c3974bf00fd300ff66722210ebaa53fc0bbb239ebc3b778e603c36337ef5deba04ca0c9d388a917907ef7539abd1cc32f9cc4f364449ba01e3b7c11dec29590ead6254c078bc35cc368b88a9074775575c4b084718b99af999e57599e1c1f619a740200aa6caadff73508544da8729054cda08f6c93ec723ef55e7a737fc8d35c10d6d8ba7930755c01014d1a930faf638b151c41a4d93a982645264c9c6d1a5dbe08b4d937bb900e7acb4ed2560731fe6bda0f946cadcbf4708fc2e0a2b097b0f259ccbe97460416baf5dae28bce08d04050bfa6cf886cd577e3604a42af3c3507587519e0ba5dc98eae3c1e5e95925a5de75320d65ddf7163de8d203d00d12cb197c4e1093638564893641620fb3bffdefc88119cb59b7a4790a5cfaa07e76f1d71716da62bd8c250e082ea9470df3d462259532917fc00b5fa8d9f9eefc917de2483cdf2fb5f6a34c0fcc3bd0030b7fb0661486fb452f6c508376b55ea3c0512aabe3cd9e37676dad4f1119aa4cb12574eaddb5ab31a4f0caa7bb268493cbdaa9e4ccca2e1082565e55b6a3d7cb33282a6a14e64b95a7c4272c5a6e43b1213e360e6ed236d447082d97eafa04a58645371a6990a78a2fda40f12ad972e1e5d6aa9f0cd3498b93096ac25c89594dd6f262e006f185e3a0e811ce53433dc0cdfb887b3856044e7f3e105b0f046f564fb1c9cd8820c381dc287e714e0cf0e14289fa7db38944ac40bb9a15b285aff73643e5a83edceb5cbeda46b44503638bd7fdced406e75a00f1012f6742c4395dbb78d0b62073c117525475de6c41a9979a659ff6062790c6cc20101e43f59026320631cc26855fdd56bcfb43692f9e85e9390b9e10d720b74c523304a049f6d5a25595cbf820c52a41c5b683af0081a627181712e3597b6d002a123d6a054bfa532eaddaa1f9c2fa43297d1db09da529ba77277c7fec848d095121bcc1fe0ea2e4d71b7804deeb1194f65b3a3defbdeb6ba0e8d7be27454f985105883d9f19c009c25ed2f558c8552055d4fc4e7beb8673e5feb4354df06238859f31b5cd5ca2c1985e9d7dfd6ea5e4cc78b32783196a30052813c453d402707c9dd481d22d66a6c454cd65959d106b3961c1fc04838219b66f3a9c0d745895f849a2d68e8bdd2768ab90099289e4ff875b174dd9d0aab3844220aed91f4ce8c8165a5cdf54cdd40ff0b4b683708b18ea4264ec849a159cf2500a62320c49be9d0908afc423d8ccf40f6f16927c7c9e029ca1e27ca8963c20a8f15eb27cdc542102bde92dc18bcab89fd3cd6689f698741cb659681d73beef9a44d50cabcd6ebdb92a88f164b6352d93b05d236848089ee5f1a07598f33279907e2c1b9fc55bb73df30945321dad79a141916b23296d07b9d2170dddccf9fa146534333a9985739dd620fb3bb3c88c2822f7bf4133e9fcb6cb960605fcc06cde5e5b94186d045bdccd248845f7298358e49832b4a3ce2c0238747aca0e883ae39af6f4963ab029ef3d78814e6dff8220f5ba41be765470fecd3209ba44955d00eccd9fb924ac175967c264c6a445f8fc5ef76651d571fc7e4ff731f0a564b408835144d87b883d7aa3f24750404c06d78c9f065b57a7033331883a26fa1d3de69aa65f453f6f732b623b23a21d6cf1fd9a35ed77b144ccc2cb0ae39a7b744f8eb4856303818e5c82d2018bf22a3cf078e359753930dea267f48e4e9d3db1d5002706c724e494e462ad471f7eccc734b7dd02a384c4f402b662ff33c35be93c06889897d57657e7977dfce32a0f6d02ce3adc77b34af9f22263ab404f88d1d9573e6a1f1b1607927e81fd79a4d1e8ddbf3a2c8e1a92f8141a22c1a22554bc88ba5be93af5a54ab608d1fd8cf2ef04404b5f8aff50c82779c3e0e68150535ce4e04bd97aa28541bee0e214e14a204708356bc113cda25fee0b1e50b9c00645de6cf6ae8c113225a3274a6303b34aa7408b8e5c5e35c5cc80f10f24cdaa6c87f18b4774405a24e301b712408287d9e48a72daa726d863790fb46dc3543c8b7cb7a3a1394b70afe84867141a6594d2d36040908abb65d6eb539929de81e27217e49450411fba87c8a175df0beb3f81c64559f45532bae17626adfa837056872bc8f51628726817274d0c17b6703aa0c559397133aed1a7b12bb1d6029112b79cf5a26529069098aef22f0331c814159d4bae0cc91db603c5bb0e3481b479f951c67a06f075937d19a4e2d4cfc7fc2e604f59c383a88f1775fbae93a4c22c529a4581a0ceec498a782cd6bc6991f4c08133f7b14a866a7b13861ca448d738ab9a8e60a2015dbc2db192097bb1d87df887f85cfc2d462cb6e1c54ca4090374bb12e91d331c83da119cc96c8dabdd859546c3c69be55a6dd44924ddc6941e219f2880595749d9d70f9ead23a6838d09a5c48cfb800aefa1d9978105d344d13eab180a0e578018e103145a6445950fa86728cdc7c59ad19a7030f34b25f27f7fa0651f8b667db49140dc1596c6fb969a6fd2b99d1ca04e3b380172b77aa7262d428127937d0d8dee9f40ca82450a11a197bf7c4b5db0b1bac56f7f28d629cde4694893d7ae88b29a01bd2a2944a8afd05fbc0adcd3c32e58047433ac6449c48f360bd922d28f180b8c88629b92a95bb77501769136a98b3f2a12eeee8e53804cd74351a6b2264c2444a240b25c9330580d820ef0cbd726f6e1749f6faf279e37d1663976312a4b485f1e18abe117d2ecdf162a1d116b18975bc27b6e806df24cbc0618574485beab41b8dabcfa9e0530fe93d20147ea837038e13072a496be7c23ef60a074574888d979b6a690a4cdd5b0f67921f20177ad9b782d86ac95c2b4acd297fd34d84e81be44750f0503ae406e6d909e9d0f46a9009484942124af377600b4a3037f68948f14240406a38f501aa1257f4936d3a0736288938b80a2110c6a2ad1ffe29445959a62ccfa95f719235e4cd94c83a863f75098cfee97cf6c7d5b0dad3759b35db5ed8128cd0322919e2fab0b7d08ecc302708b99df12232d1c824344fe3670a0c21534f89e0bdd2f7740dc2ec794de2728657cf141e0456cbe33026be29b8e544f6a4e655bc6506cf9e9540d80a3b92bfc78729e5523c8f06d4a942d72fb1bf7cd3451a01c0904e7980ee45956d23cfae32144941d336cd397e37d509e6124216742ec8548210b9a6c9cece18671639c6d704f63bb6565f7690f7678721a690af9fc2987d0548595fe30dcecabf6192d83c78f8189260caee6bb691d9e5e1c388a1a4089baf06861450ecbcfb02efdf7cbf0a8ceca30eb394388959f2f2375cf46470a9dd6671e306563d697e89c7b427bfa7897273292062565a4b0a3f85fe76a015cf2ed6e4e33417aec98284e41dd54f517c69324cd5892b9cf478a8440b876e37d2b6bdf2d6833e91cc56071aff6dd82038f0a88bc643f7a64bc074518f8e200719813b7a096f4e435f632ac612c6657a4ebe74d23aadc5b5134dd160a474a1a0034352b1daedddd909917d152ceb277cfa11a74973f15c2803abc6d71fe45cf1a879adc8824246f99a8c3e00db7b29c5e1b3058b7878fa9db805fe1da0f2aab3e50f687b5aac7023f69c779d41110cdfb54beaad3db9b7e139be161eb7b381debd203c96d3b71dd5820e229067e67bc44cee6f5416fe2043f70a46a9ce7a88a4a41b037f501374cb9968144aa8606ab69096c65d3b6a6d6d9f9bc845e2d09011a0961b64011f35a737b46b4679b68599013b56e54b5e277eaa384b819ffdebce902a64b8d002c094124e91e1f17d4b2bc8c20d23510b6c9817e45ba782a94284683fd4dc18e474dbb636981adead3251354106dfa25c1ce77da0c0130ad39f1977d592629e1125846d6a56336a105d8fb58d1ceb641ae013772cd3ecaf0b48acbc4bd3ff9b70565709f5989960397a587c4812e8cee5d01e27ece34f5b16bc86c37312ef8cd7307aef4e6b6b66ba1fed527dfd5ae2d9c77f3ae61c6378422f422e9ccc85541904d391dc4fb7a0153baf24700fb94965adf575e1596c694a3d3a381c6d2db755f630c490017e9a4ddbc505b0bae695a6d42dd2a492782cb59c5d5bf5922af9b5f3202120c53b3eea8c9f2021b0dcc3c943e1ddd0e843a7d9a8ee0ced8dc87a668f6deebfa164db991e1b032fb462585933b6751032b651960d0f2d026eaf07565ffa40cb8b25ed15fe84544923eb111e29d2efaffdbabfee193a5dcbcc5c30def70bd7f585d37cadf6f2a8897b0a5ace33f8302b64b284f547a59ea976592065a23280b35f2780231becc3198b035913e200e6e78f38a3ef9ae646877463bb09c326537937639be1320652dbbc72cf2b645055171bc9601cbdcbaa70eadbf64c54fde5f78c42f17d03351f529b2f3cc55b1bb9466889013c6074210694ba8c3944ddfa8722929e668ab163625f7cf03d3a61078fa779879d71879d9f35c1829c26e55e83adf9cb255ff4bb0ff7fa237899ddbeb2b71fdf93fe59de5f6418793464477730cf1faeff90781cd1ae17df7ed625dc71e3b4256547fd8586a819b0f26dc7f49adbe7f09fd7260259d5845b50c43071a2b2346410b054df91ca0b1ef371adba99a9d556be71a95ad49980d26185a8c6ae7808a999a34bb9375b423557648d6ec92d1a68e8aeb3152257fd3573477ef62471562ccc4474707c056d612e2f1863fffd44a0685990876b1a7c1a6c68fe27a1127102413b432700ea794187c6f042718ff6f6c0d5a532514fb5c83aeae80856d64f0d5c169e4119e56cff1e2f878855bf37df1a5fc22cc0c6c98a933efb111054a7538bc1c32976eaff63040876a34e60eb67e442f4c126442abdbc764ca1673e9a8a45a766e22c30224a2c41bc9a86b10d6d741837914eadb275ada129bf185b0b9c46eb35afaa91f133d5428d1fc0d251ea7e8e1e9db869301e22078810d9a459a8974cb822724f588298a4b0b25c69fd6888c80b94df1086714c726af358b756f1fc6360b469571aea4556fd16e8a2760a2507d92a05d2eb7f6e35e9ff1ded52175d7b163de694a05307c59ab70071fc791c81f0b8ff979e164e3d0e1bd3fae6d44677e4024273174119f23bc87abf1189d5a34ce780d754415e295301f711fdb51c80dac45cbb17f40095220a97a113c50aea2e979e044aa17161b2ae9289f408cea251fc0a36f84174c70dac9d7d4aadc4c3ed722e7c2ab3362e7e02751cc9f7145af7821fa032d5b3aba9e7fc3fa4e358501eda77ef6138ae9ff0e0d1cf1bfa184a350a85b5fe1e75293357819acdd3afd62137e1ff59077f0301d32eb45ce0f98d46a4d46727b091a64f9a798093b97b92eab9c249b00ad3674e842c58fa9329f1378297a8a75f1f41961ba3d9ebaa2ac65354d92af723edb1140eeb2b557117f04bff12fee3807f9545998edb4cd24ae37ffddda6a15eb750be48630bf0147a7c0f44ed909d96bddf04658fe009600344284124d14327f0724732cd16d26d9c4271653faf0646318bd4c9198fd8a7014341a0a8bb02aca93268aac4b99da82c7e5587e2cd51c45214cb7229cf9b43ebd20c72bfb14f73978d1a42c23e4a19434d1052cfadd44c3b45122ae519d2023d8bc19f61fed2f1cae851b94ee122aed9c09884b283524967ef9e0f80fda203827de0562e198c2e1f0936a1d0dc14c53e4a64e2de08e5cd384e32caf568e4954579c32a2fc83b6aad4adaa702b0e8d64ff2ba18973ee6d49a35f3c805393b71a1c8a3429d2ffdb623b166801409c82f00374482053462dd309db084a50b73f5ee42de462c1d4faa12d3fac9ea167dcc4b7803e2315bcca7a75154f5fe1802291b5eeb94647c580b297d485e8cf17d47b74dc55632fe149cc098dafa4a8c577c0d713db689610726ef5bb95f3e4ab1efff63516dd143f51ae6766f91c826df31f9a80e75b5ee97bea1e04d80677ea5ab55e08fe736d5854746185d1adc0ad50f3867058a3439d6d38618d85018251831d37007818056263c73993f21dad787ed20e203e3673dff800071902fdcc2089529557c86a5b842e7ef5c7f84022a1149122a8e17a059c551802f07cc64bfb93b69b116c247f26b3e6bc5107af75af33383b87313d3ebe6753b6d0682f12a4ad0b79b4e23a8760a8bf7d03fb4cc6e65c954fd578471313115ce7e2d22898892ea363828f9f1a5980509bc78ce5d32e048a0d86533c881edb05847e2e922fb12283e738f69c17d79229f848e923062247ab94b8d17ed6012d258695917cbcdd64a1913aace0b10a61c6c947798f42ec81d84f2860390d48ae9bcc269998f2c79e66ec5bea917a849283c3c705851b90043dc9c784b8e5762c99b03c4696258c194991e64ea43ae20dc996f1f86f9db8e670e56054d126a679c15eb911fc048700299b6ef609c9719e946381850d8129079a058ceb6252aa2322b2dc797415e196663f7cd40c5edb42583769dd8a547a4a6cf0a1d7f169796506bb6cc9eb1e6ab4badeb91d4335e6a9f680cdc4060b9e2fbdb87fe950ccb19928ca1742f99aacbb63c2c0a64d7698f654745d34155ccfa44c18c3a841390b6d38c97c0c2cd0510582ecc6bc3ad17b26ca34a2fb215b1a6e112ed79508be134e09ecf97a84ea5fd9eea2c610e4aa977da1cd9011207630af99bc0ebfb13da475e51a8b92bd80ca80017c1adb0b53d66d009cf97e8598139cc072c423441a75501f6f45ad4c1afdc6b7c18ede322a5adecca571632a7ca23e259d0b3aa7f207305f23a17e45d4a20deb6e684c9dde60ed83b6e121ce158c704ac6ee642644befb05667a4b5fc4c01dd37e4d476adfb6ebaa138e93648f17f90c963a989aae13e793d29e1488050d44ad528692c5ef8444193c4687d984ea17efedf49cd452264ff6916c5c33a5306323adc1f4859fc30df9c4a09dff6eae7240a7ed4d6885fcb63ee56e975eb90915dbe883501308aa36b0eaefed2da7d5f5e7f10e37c544df6f643a7611c9947346b59d71cc60c46a1d5d6c41d450dbb410cbf79f17e202c43788d89b275d838352962450fad12b2348404315c347c994688b95544b9f85be0cb3ebea3d961b99681a5b9bd13c329aa23d0a6d2ca80551323394e1fc76ef27787d0eb4b89606161cdb68e5f538a41c7528bd9b525624db2efa1dd18be7f14e7e858cab45b2306e726789d1776b30347fe90d023495b923b74d674739702c9b9901cbcb9a4e7d3fbde930d6ef6c1775597df630baaf859171dc51d1d93fad28e8a452ff234801a9ed7d2cc2b1684453bb99527263b9a8c11d654ebaa5c4d098099e49332a29dfb6113293932dc50d822bd19af295c1fa8265262dfa0a5973e750e33ecd037f8c76538ad373ad9f63b9e40e4dff4b85e67f79660e27ed1e45d10d710ff4b92e0e0a887bc72c915e5fdbe6a5f2648ac95f163a8edd061bad1be3234b27308c611b91043d99acb0f64ef6f6ad04d56bbc4e779248775e1bc128fe0118e33d3d6a44c0efa759e7d857a77b3436f6f03d455a29286c20e6d9162cab9a5a0d24d1c31fc7db8964be9f4fb6d7435a0f2d165ba0f50010af81e0527a6170e738ac0d3f3c1ffc77b2cd750627a768cd1200c86597fc8d7671a41f1fe151ea7437534874612c25cbe5a29bf7192c5670b807de735659a91990d10938e0cb80e9a3ec6d5f53401f3670b9f3c2cc31ed0e6cc1311a0eea6989f92c9e8ce89ae97073a0e84194827076ed2e7e2e540485e5c5cd3c68ba16aab9b28346116a97cf101c815257cb0012250658c798a256a8e8144d3eb0da89423721cb0a25132217968207a076f8e0d40dc0607358a35963e6e74ca502187012cd8405efe5070064d9f403f79cf56f66a0c0225a7c7a1fa97d0ef6563bb6a42564e43539fc60006a717829a05547a3b5af02c43cfbd40f196ccd5c9e4f037042c46439e805dbeffaa7ad0b5d3018f2f3dc72ec8521e1c5fb974b90503d5c76b1a80404695f710028f69e1f87d34deda7b7b28058a70ad53a5f74eb429c44a52f046500f5fc9eba780256c6961d14835dfaab413b21fde04a2800dfe89096bbc878648bb6880680d9047479687fceb201b1d57c0fba429aa967c96bef8e6f0ad7136670656078e3ee3fbb4d65cb0af1d4f2a0a1b85fe8e0862267f748390d8d45eb1d16e0fa3631fbe0933de0894d3c9697e5ada267cb8c050bf80906ee0cf5fafe4517cb801a1951b17088ec2512afa0f4be5ace3ae61c343c627f78e354bb97cd0629d1a6e924571008a63440fad7d5f69cb6378a2f3f456d2ec4f617f5e8ba8504dd783b650c988e5b49585048602970a1b5642a00089405d71ca4f7b40f617bbf36185784fe04ec4d9b5a83ec0fc96e1c76868e8ffae0e7532d6b7402e5864dc77eadbe9275e403bbea8ada205f2550c50880e9b0342851c5c53007b7d8520847fa489c60b3541aa4c35a7856af6496392486cb14bf83a271a3b693f742bf102c2635b03c601cd23efa33646f5fd9b46fa5e44204727ccbb221934309c111ff8758719693b6ba2e89d12a3ab6dbc7b243f4bf6c8cbbb5d257d00e40f3e1fa92a9b8e9e46493256de71d1c9163922ab0b2a7d0a9f5cc9a8ae335d000918099ca029229a66de2aa651815c8428bfa1b94782f799057549f606fb8ad3d58cf1a37065da603094eea4653bc593ba402fbd7b20a3366c246981378dd291aa7b44442e78bfc2084ffdf38ee82b8d612c7f020babeac14ce5e3ba1fb707dc997652417564188382db5c25be645a6d41b16e817488c1a5120fd866885048788d075226599c81c1df626c59c5add1e5fc1962baf239237f6430c0fcbf97ca33111ab99144d798e18e664d5f8e852eb48d85396620b0f19cbfd12e0d867aec51d53cb01a81382e184fe12b8e90f7ba568dde8721f7abfc30ff322cf097b48b8eb1ebfd004fa5aa9600184ba35118a8cad1620626be68c7bb9592970a2785759d6e86b80a0d39ba9ae6823d4c810a286bc913df00452d023c6e0eb2f04453fd514b413683505c662c005bfdd9be192be185add7af4524807145492000d2ba8426b0bfd8f5de09834e0ea1f36cc59e79388f0c9b695fc273858ae101d3bfd2464bb53854f9a82418dc01f374dbdfbc5655b938c3da8dd6a0a0ef05a0bdf496a7d24a919181709c5ea58313e4f5aa1c1cdfcc38d146b4d784bc92e95c47a132b7023b613795646873fdbce42803e05d0cd01a9456a3144b18020e76e185d232c6edac45aa67b135c050526101ef051fbfca73b21c0a02cc5a9516dd0e04ea10ba00e3fa2e674c251450122b9f63a24cd1f262344f9350647719dd8fa4c24eccbaef7c4768a043cae22a5bf7a659198f14ad7cb7533818cac48bb6fab60a25723aae79572e14d3ce7bb56f96c38ccd7074a86c5743ee6ce79036e66c7dcf7e119d5cb789e85bb10dcab84b35900e4d40d66c1c34c4f2f821968b3923fd314bdeb55be17aca04245380daf4d6624866311133b40e4993951ab5630f9940e8ae0502f8d62678ed5278773c3faf6fdf7721aa02af6bd7a7f8cf2f71adf29087aa8b6b77715765826b9f7cfa73934d1c16c50e8f9101de132a073a7b3fdb97ba216314bef4a53bb8dd17bb72050d5e4a7951a176a57d6a9b4eb16bf4aa854210b7496ab3a461c29ca6bed739e81f59e071b53447c40be7ac99bb6d166de1f99e073f392a193bdaa7eba1ef3f7f5bbe1c9e92e063a8a816e8ea3f3ff2e70ae67c4dedde7c332d6b01fa00b3e8c7b168791d82b8be9a15d6118cee92786ac1743914515100db77d168a298b3034ea20e4a4d5d024a470048598a83695829585f56d995eaf536ee0dd0089fb9c28184563dc83f1436837b83d7cc3729c3e9e10f26fab415d501835712bc23eda7a28c49a63a5d07d202aa2f6fdb1da32dc38bd24110eb63c8102e11d5ed1280b7ec3f741b7da61e7eddd1b044a973750132aee7b96c2d839e0d3d41d506bc4e2cac0d001170cfab6e2aa593b166b19b9140a4f472f02a51d0b38e31165294dc7a274ea029eec584048b2332d551be042a60c59cc91149f59b46162de580a2dd2e2e7d225f60a215f7b96b89968390c1496c075d1015fd598842b8612607d07212a77294fcb0a3ff122eff95e06a5a208bfd4a6a91622d34518b43f5c869335d82009033422fa0383c9a47c21a2f00a80dd96aa3545e1928fc0e47935e2305da3e61e48ca4d281fbb197c0b91c43cc1696ad70d51197847dad972cf9238f10ae36552ea649d176f99f987554654a6b24eeb74515a2e909a2718594f4a3b47b385aadc00ea8c6ea49e2c2f67233f66e14014592f92cb2851836052b393df3df7690ff668a34144b2fe60917fd8ac04d177c3669d12cff0be796aec9e94ccac0f0e024803def499f42c8edcca491055984141164ad60c442a9e344b62ed9d559095745ba141602fad45d1b0562d185e6bb8421ea34106620010d574da18ccfae55d55f6a596afff2b474b8ad57793be1d888fe579e4eb6047f7356e68ee30c442403bba346bcb94d66620b8d24ab0382e818fc5de51b503c6f8485959aef311a511dccb861f546a9f074dc0ed2028b02a44805efd094051c4a1e01d221b7bbac524a60cac58667888073bf6c4803e037cacbd4736bb1759db6fe3ba8d48298e8adee76750e04a2a4cc2c3bb2292f3122468a9b4774e4e91d088fb524ebfd01d29e094cde2009fc7ad0ea755dc1048f53dedb49bcb3d8a128f61c8f6ee56d8ec2355bc5af5e0672a9a0f41349dc3a8abea87c0d9deb8693180736adcdd35e07e75c98941db24d6fcf50bfa9a76055313fd48a8b6f5e2ff3312b9c492c18ce7a02f6cae990e7705512441fd1ce32c511127be3b5c6041b76d3bdb196affeb68a85dd6ae813cfc7ffdd8488ca98227914a2bfd21edd4e80e091bc8c3258540f3a9055edc0321476f940732778d9108ed69971c0c79a603cc46a5530199d638aacf3edd41c8d3714e6d4489f31aaabf52fa0a0d64743e87ee2e5d8f9b1b56365dda61731c39f528f477c2d232d62c25ea7bca7eff94333e9cc22a9c127b9d5e46fda01fe421fe41d7fa742c5a847bd351e9681830a2cfc31ef7dfda2d8583bfa70189164754ed51e284893471c2c27277a98016d5a330930fa3247ceddd90474f273a09f331eb38d09bd3152b1c44f5fba780c90be1682f4315836691597fb9f43e8b3b35240b80bee139034eaf42672b3b19014954e1f04ce9552d915dff0a9492a37f6f5337d4df34fe112d808bdf25ebc349c6f39ecc1cb74af5d09c193d11b3c798f07254258fa60231e6994b609c0a8688d707ed82bbc1f2c86ccfe380785bab3864d9de6eecb703f2119491ac75ece3b445323b0eb24c81b6890d5212664a8eebf31639d2250ba96994685805762541f83e458e8f92d603c08ca8c17ed410f4807b06a68ca6243052dba3d3e6a6e4d7ac1160f9e83a6c4a9653e718fd8a0d5d0200db4f5695ed3ce9fe5d74f104b509e917a9f537191e36ed33b7b42100bf2eea794d8289967b95e7e37d79be102ad82ae718160f1afa88c76ae2b6a617f7e93bc7db88e16793d2ae0b400860a8fc6eda1952c21931799da4d7475828ac4e29daef9c261d69c4e04aecb4340959db8705445ec0069dec6130f1d18a097102dab338325abc82800d14818e9924d351f44f95773d04f1646dbffc889a88bcd28467d6eff739443b8823d9a4cfee693a96fdc15da5a0c17566ff6dd7400ef44e48088d52ffca79ce68e2e23d73458f65bf9467956c74bd504377b207b4e605bbda5c8e6750d7b5d7dff79339e0895e314a3b7bf063d8aed54dbac394b6efdaf477768559e5241082529a7a1208e2fd5ba55d85e992ce90d1c5e44a2b47a97ee4887b4ca778d408fe721d0f9354bd53cf17c969f398a76e721a2f92e0b68e4fb10891dcf060102b484532149295345eefbd4759c0db7d8cf3dc88c6fc34e8193e93abba1622f89840f2d21f72ba4ca447e0b6f73222a32e56b5193ae4f2d2771120d0228072d7218ce77ee8197fc01397ed084346eac458ede2413e411fbc95b91e78da772091de8592d8b4356d43e81d1aa8651e463c219a120e154abab04ae4568b463f104b57296a9bfb39100d49c28cf1c719806fe0d79ee3d5e32619b9fb41c510fe83ec729f218884e7bd181eea68f415fa688c4bb37316878ac5c4c0d666a5d8135a3d6c827a00e2b9433325ceb6d7c0696d8feb1c950fb150ed54a0dda88a563a84df2b5e37ea0b678cab460c84411f1538d0dd65a3ec5de4cf0c3ca8b487da1445c6e1a02b97982a719828c486b34c59ec0c16f140e44813e2c38e1da7f54dcc7c878281ab1492167021ffe40a9b5c56715f051bf525becc89bd97e543a5120f916aed56d69019d8c1d703d1a19ae38f1791c4da632f9d0632d000ebae327488bf46391d0abc3c1e98131e95823c083dae1a30860761062cd2d3cb9c60463cbcb67953f019077f52419e385f410119636220194d6d1c48cdbb04d933a1e591ee8f3df70d33a92841a57383610298606a421e121aec7e35f1222585328614fadf7674414e635b36459bac721c5660a70d9293f4fd64d9ab6265e7a4de49c205353c8f20327dfc910d531231da5a562a7e28ae1192545238bfad2e616d6892532dbc09034984b5905956b2f2794bbeedfc3678764ec104f8507feffc79df90c00d614914a394954f45575f67fe4d6a2f823bd476d5ce8d252b55175f698d725bada9424d08b47413abf077ec37c03dcb1da1303b8d97e9f1a1c227a51101f6d75921294074fd37370a0d65541fb9fa4977de1d542b98d94742d08211b97a483ff63e4976a36f51ddd197a4e865ec7c3bece84d88fb3659873e5a2cb75a18288204276614bf7b516fefc2300761dbf29007e1dd84db6a51d5d02dd5ffe26010f2ccf569eef88e331d4d6e9b1b6d3be695215ab6540b5335691721decb8bc1301c0e4eb547d008dfb916c49debf5e3d5c77a5b97cf756459c5bcde33af75a1c9f5b432ee3a79e77d36bc140971d256e6a211d5fa17644a06cbd00e7ab791aeb804920d8410b5b79b4e90cb72a6b29aca3cef5576e268f812d75bc973f604e2b6b4e5327194ce84fb7b284d560589a67898df7d06f950f1300de90fd34dc1d247abc374610ae63c971482350d986ce88f111571a4165661b91800b72be620aad9fefc82310034053811a08f0f0aed56a4d8f9206f11514d1f0ac16db842515c04fc15be54b047ff9dcad7be144dc765ff566908f0044293ae69f991733cbe38652dc66fcc9413af71f4924e36add19a907756c38b3b5b801a561953994a3befbc082d13941a26ccd8e97b8fbe9d9edc7f1e827b0ae786657d97e9fd106d8f91e6897ce945c81932437b85ad516698b6b1447bd8a5298cb87cbe8616e69017a2314f53ba2af6c6ecc00fcf9a0da605a1dd220f483d14593ff533bb2e92cee4746b4a833330c9cd3bc648982e176d41d0e965ec1318ea6809e1c64c63417f87983714d25950d26e0e56fdbb8550baade8448fa485cb2d804b12016be1d9af962fc6f715af9cd141fc0b58f3912f599ee1f8de42053688b0274cfdc207c413296a3a768088e1f4e0bf6e45a89133932e978dbf5e3a42f71781a845be8b484f40114be285a63da57b6e9815bfb9062dd707f8e1716f7b527550b807bf6285b2707e9df9de14134906eaa0e7409bf4043f20671926abfc3d6b417d748df1cc1be5c688fcc91349a224196e9421aaeea1bc67845c58843e1a92e37fc903ef76e52f1b59018f1e4b1178ca28170a622bad08664350191cf3f90500244dd754327407f8ed1b3629dc3e8c7a2ef525899a8ce551972cb290ce4b0006b9d45e44375039b0c194d1ae29381500e3e8c51d3fa971bf48daf18c8e8b9d0763b8f141961e80aa2f1ca4ea20fafba97909c669fa4fa9db27cece60092e3ac5c7349985d925baf86db82c86295973d183cea0611eb57b4f9170d6a4a8f066230dbbe15ef97d14f22308496b62b16423af6c4e3d32d97539c01735a25548d0ddb49119a6989196bc81f372e2ede51187d0f1d1c7789f744de4a87de6d0112206268057e7fb982681acdeb6511bf2da70ec3a391f1542228c3a23b9025c158b83e00f03da1bb9e3ec6c2fe0989c519a9e9e21b4f0d8e07d2367d1d5aedafb38e87be4f808da21ff13417f8be908181af67ab3b51c8c121e8174e13af04fe85b93d4651f541f6db745b3718883726a25cf9a0d9283d1e1e8d598d121859e8b509da3e64aa798ad086e29028806c2de4438d3775a060943d0af375bab9284e3c3a131d981c8cc3785faeae24622e5f87b06fc83119f3f728400fc7d790e70572dfe909d11013218ec3e5ba52884bed9803797f11496292f73d795ee0206ed23225b5af1a9e8c722cb081cbc97a68a450d455e382fd2755aff05da5bab498c90abba44b3f03fe9257a4cbbee1291429d986f105d3d8aa736bdc624444740e3c744576994fbdbc7a1bf949ba99eb113cb3d90ecada91d6b758fbf07fe79c56ced06962a3d51181d8e47ff0a66bea5d4fa7f3d4d9a7681b99b497e57af3c437def6360a44f3ab9c8b7d3ba0f21d73eb093336846324a120e47f6537f532a8e7a328f53a9a8be269318f31ceaa25304a0c4db6e0ceda2d2dbc504cd174ba6f864510e628557f13643afd593c2e382339ce3c6fa24c00221250cf1a9e441a35af53ea6de4d014e37a7cf5484ac45156453a4c5565e74369115fd505e2ff7fe00a296712612d3e9714a6a38dc4bef3c308f0a62f5095588d2957f362fe5f440d820d94040e628174b28450f781771ab234b03a282a0b93b325fb5ab4456a32e071ed83b539efc35413e5734fb527a73e4e094407fb8e1dfe2cb5d7e6e1e4335291f5fce22afd1661185211a5fb0f6497f331f7ae3b061313dc274763de4ed1e7b9feee9adc1d319fb2874ac162d99cb4ca56852017cdff765021a388689ce8ac35b771b5acedc6f12e8d377a3fb10c126e1277a503af594d6976c6d010158ab9d8023ad011742b7e035bf9c29d113912b514ac01eef3d90a27845a4094ccf63c8cce7c3abd5aea13aa45a18bdc4aeb6fb72e489b2285cb736f556e712a6e1088f977bd27c953385a4f1db7cb1a9dfe14774f3b4dde20bae242d388c90b4ea63fd515330ada29a4b0968873d14cd98d0cc88d20a67f0444dd8e9486b0a957cad909885705deb791089b40e5e8dc4f21d830e9aac746c093d2f1923db53ee725f22da3ed90e0121ccd0a42e169586e0fca06c3e4e9fe7dea2c232496c625f6011b3b6bf8e21d2bb61aaf28f7fa3afc03b7e15e5bc40f858d723d1367e65871d8b25b8b917d8009084e69032c0a618e7b5b218928b01027b4cc8786dd2f4d6a846cd8e22f585d985e0b8300710396beeaad4cf252a27576f1459bbc3e4eb7c5f48cc44c1d5c1adc721c538c18a432293a310e9eaea5a1d0736bef4bb64c6dec56fcc2a0d75ea141722fd2f8f9ef1e15b70ba4d678fdb167356613e4e264181fef776b60a605a39629ba7c8675c456fcb211203b34ea72deba70129d399bc749c0411c7722cffaf43359c113454c07c5dbfe846660e374bdf84f022919ac66f9b73c3defb6db5849235548dbd857cea9e3005a31a13ec81c7a08e14398ee23f54beff73d8a8eaa0d7a658ea1142b219033070b373bfab879f5e5ee9a9dbdee9060d68f5e04742a65365c23685db4d5ada6785ccf70c96c185eaa177e407236e27bb4d29b011a76be2f323601103524a6678d4f88df32e5855b3fbe59f0b24ec285e85576fc6538a7e9cc75534e70816766729c05198fddb6e9d6c248d4cbb5492f10f8df502029027823f808dbe6b42df07953648d789633607a5f1d9eb5e97c54abb1c8f74f1fc14279eedf9fa96a2090083751e866af3c9ee394fbc464bb5a5922e65722ab1523502c0e88077f7700861148da0410fabbaf00ada3c88eec1de7667cf5be321f77838ba587be1414e9ff540ee4b1829d38d06930369fe3b3cb206157aacdbc26e446bc21a14d49034627bb476c9b620091431ea590dda99280725277e81532655e7f1e910470eb26b33373e3ea08d0c76b4424ecb0d79d78734df5934b548574b5944310697556b7bac23071ad838482192c44f7cf829c1a449d4d4661ca3a6862350ba1078e63619c5198378cc83fc1df7168f3d4b775a923c1287dccb4b8dd6280c5294ba3e59dc04adb14f461c1e5b7de9ea9aecd4550b85b681b66c6b637d8a607142f2d69ed1c25d6ae0c5525b48a63a13ad597303b451be63ba66eedc75ccccd40765fd9fa853a81e63e83292c2de8c6d6f415d8e6bb7d6c4bc070eb9a456a2cb5a6f59c532aab890a2f9dba868a1125817231eaff7e59268376eb51a2dc920d182d176897d5847b49c217f0322e22c0aa6ce63d67110bd3944a982125e1216505da7bd61cf036a548197034a7cc58612ea387a6a9dc9fbe14908908f40c06775da13e384ac2ad72e404435b387fe52237082e8e708d87f29def0e6f44f89e9eb85f3560d5661139281699a8f970408881320c1402bff78c3569c9484e13398030a464d8d764f6f70d137c341d5fd111397a9cc0deb4fff2a253a6148fe01ee9676ff1ad3db52c073537e72b869c4d247ee53461987b433d50c176b1b26bf032b8384944290d5fd8f6c7e9c1e90b91b1c15bda0eaec5dd6aa08b9ec32852c60ad47c4a7c846d6954e88da3586bcc26f1271e90888266f54b54e3bfe31c02a88a50aecdca378cd81c02189c8d46436ebb4cc9695347d33536bacb80d6666b0cef3f3a3a16a4b631d197ba1212aa92164d61aaf3bfafa3bf7e691dc2363f121db81e95c49c8f84ba8e26f54ebb543bc7fcc78bfd3e83d550b30b7e55f90b1864aea21c4babebeb3a09013c37a02b193d15697104f8bc56fe431f655eff81170712f0f269812600215c68cc1ea446548186c3c86c43504cbec79a8a53aece6c9d683f5de3c5fd588ae52096e3d9c1efab578fa0aa902257546d73420bf6b84954d7b8d9997e9f204279dca44742bdbe9e2ec542e69ea41927bea276dc091dc6409ce3dbcc514944961ca08e5be73918f6431acbedbbe3ee1443345a5142eac0cd457fa51671150092f3f9137f83866abe5e8a28079b36e8cf042c122d723f56d7808ecf26b1e2c3ac53a12c3247b13a13d5c0790baaa883e8e696b799b23ba58ead308890676b35c466106442e3201418618589c805b7fc2fc2a6b023d8471dcd6c083c3627c90964ef5313771e414cf48cf4afe6b6508a99202bc95eae717769e52ed24452c267b6a789329e351aade4756027b14949a248aedc23aebc17afea089924e913c6830cceff3a670460ba0fd0d1cc6b96e0cb33ea64ceb5b3ade67303547b7330c0d9ceeb6b2f71e6d60cdb2081982483567da1a1a7f0a413b4c6e720035550eaf902f34594addac78826b09b7196952eb72d924782296790d6734e0e3c29b414224564ecf307fbc8466b70ff638238977e6b2b1bd0b60dd0f1949adbaedce51d778e3a92296f96cbc047007c457de78093d0c6072d4e61430cc89167fc073d2dec81923acec6e5a896ece6307b7c4a62c542b4995f3e16a81c6fcc70b58c596c3e1879fed05c1e3639ae61504c48ecaea18e2f255ff09ce0568f1ad9ed298022b27980fa9da7b5d2a84e4be56dbc6f3813bb443892bfb698da902a9d7b3f85a86b9e6f34172e6be038704ad825e8636cf341e9a5b1c34d53b7636be62e2cc3168fdcf99c6d84544fc280918134a5a6b35fc3b817da4dd28711ccba44864cc4f74445278c841be91d4f8f8a6594a5104199e97575938dfe086bfa4616b742409f06f7df7da00ca54b986fbd20bed4bc881050d7b5c62a9633a778d15ff959b2832aa5c5565a55c5d456193ff6befde5f7be58d0054210fd9579ca64ab835cb1784ef6028df3a65c236c56ab5e960e1d8b1c7f2503f5cc5ac4b25e58ad55b452917a9f62d98e94d1fd58e2eb2a52f9269c14826cfd2e983657f83c1536b25cffe5e5c753aaf6a6ceea7c94302949ed7fdaee5feacc2f5d4a5659dd673d9fb45b948e8c36a65b1aa1f2b90c94a973938bc185a87d8563f9a9b3beceef98d3b4013b31f4fd9c92c6cb61bc65617aaecd4f5ad3dbd49bf93520a77cd506e41c28226aa6dc16f4c25bacd16bc889161b9ec39446b1e88e9d65b1dec8d575c568511d748d1b2e3e977b3fc91f2fc1190f0473601628284d2814dd681197b9a5244f379ef286722203997978cf5f830391ad1acaca6b910b28a3a894f807d02b30bdbc8a2bfa649b1a0b10956c055311facdd3d5ade6339834c085543ca553d7008103f43b58cc96a4211f35f0de33033d0e73d8c490e83334d4e7c8b0a8dd8bf686f4cd26e79d191a6675ed85f72c52b4a86ebda19cd6ed01692fa9263ae453462e331961b2a862ddb0b79a3341cc727fa27d4202a0bc98cbbe698848b58a0ea195ebcbcd2b58df7e628b69615ccde5aaa14f8eb9869769614c64e55355e7a64fccd48cedfa2076831a0c0420d736ad59ed31a65e55e15255729e2eacf88ec62f0cb69476ecec16a814f705452c5ad6902f72f8e3559a838fafb4acf35d5edb502b9e5f2c5c1517b616a1eb76c0f9d6240b76bdc5ebb0ea3b40145eae000fa9d42412fd3788d9e7817185b930a6eef4895c61c37fe7cc2e3f8c71e5575cd44662e08381f314e3251e35a24a680b97af984818d3eb8871967ff84c0409c89a1c70511bc3455379204aa6f2764eef76652335ad9a6d1632d782d3b955081dc72f9e2e0a8bdc2a42c95954d9f7935d0598f104aac431b09d73b58cac47e2a36e4e207fab3773390cd83e50fd37c0bcfb587ac99b6f30375e980a840260b203b79a7afa81823cf02287609d4fcfa146e6ac642b4158149f7a4cca0557a69d3ff5f733edf3e06849a0845742e0e11432d494b6bd65f3689b2a67d531ab7c5e82fb70ad2340e30f2c49a264496d0759224323f63a1895a43fa3c44c83073d943648fd414b3f74f10e46f770adb19f5470b7da00abf5ced32b191e3decac62d7a97463ca5244b40f915955df7fb20f662431676038156331062ee94e1347c5ca0f181a65049218917bc12405e33cd2fe3ee1f468e0726b0c409af029bf214d61dc0c0cdc26955765397c77a12336224854e61959e735b0be7b501e4271f0f19b2d6b570a8cfed4093062293ec7c2c18e22c7cadfb4e2fd62f5179b32e60a376cab08319b6a348108d2a9deabbfc07b9526d75a32ad05085d9c3a9b9f47e6e0410948793a11c96bfad2820c6dbf540a60620bc0efc338dc9522be3e8574c422f7b0f4bc128fcd30dc95fda6a4a73a5c2887620e5192a54339703d79b369117d603c9e1a83d924215c7aa3eb12bed2a3bab202ec14067168507376f9fa2dc4cd435fe57559a934d0d50e8574f5b811ea881ab579de04b4d46a55539326847741eb13dc4b400b5cdc55367a0dbd46060ace696a280f638c7956480fda1a8bd91dc95607f2bc00c2247b9a5eaf478eca8d1d8bbb312f9de172b5b6f120ff914c48eb7de349a497f4461a02f9b5e5eb43457bd2240ba523ca04570121b817d007aeeba11c17e756ddf3364bff5da359806c705dbdf8cee8b7e48dd417426de632d27fd140a53aeaa62293c5dccc2d8b6f4a9ac9b0734216294d209a58a788fa18c75ebfdee7a92268f108b12f4c1b83c9d5be8fa4e346877075b41d51a7c6c5e9c548b83740995a87fca255ee89ace12a6493c9486eb7dccc9b02d67f53b846bb05afc56b1a064d86080258d6175492516995a19a634c37707721209125d6362cdd600adfea90bad40b0eb3ec7f8d9eae2488f5a86915a29d3447e7597478530a2f086ceb2d4f582cd676467804fe98e280c381dcb2932889578ce6a8990d57710ad256a6c8398ee412649c14fc7fdd1a0f3a848d482d2e3b770e00d5eed8f26a12f044b8e57578687d4c93bfb88df125fc104de081b3a5b801e26e2edfb4da4e3257fd7d10515a2ef164ff78c627ba5380f704c3bc0c093d9b32cf024487e491f4d2beb110b8aeb8ce70db4006c240088f4d1a60e414a84d851501418b21eb542bee74d24fd3a6b7524b19491ca8724ecee9ba9b96b3f26d3e4776ffb93148c45d493a789d83de6bebee24461de41e017039d1980b67eca5c8489f14a4a75d2221bdb6d479b6bc9814e5b312d2aa485700190a83e0df213fafff6e158e50cb05c570f29026ad700ab9508df1c1c10abd505952ca0e6c0c6bfe4ae3b9ad7d5110f11325650a41cc050c28e90ce815c0ef7fb4b1e327a5cc2fe24afdf46e4db41517350372b77381c69b8d00a98b4ccc451814feefa516035f0b2a91bde09db77ca8057d4266b2951775955dd0541cb34d74a4db39d35de5f9291f4655c29a7babac2dacdad8cd37033b9cae554f05da38a321b205ec0a0805b85edf40966b9acf362ebb585c58bf467e4d5025f30dc1d52b997acaf80358711f41c4ee3da5c7df582e4d87029229471c5d06ac69cb5f138558ad1a91b2c7e5d5308856642827eb4799233ac8a58048dd2ee3a254a5a13250328a35ad75c505aa6ed342d53d0ae11b2e91b32f97aab90b0318a6be6742987eae3fda663b44812b8c924db6c539a63e74c1573b22b4b52dbb1d3a6e64c2a07248e0af5c7f446470615049e9f6cfadb2989eca66c4bd6877cdc4286f4d0eee92ec82a8185af5203ee8368730dbb0b9257afeca0a34aeed888672ca74b2900ff8204b8cad939d07df4c215732b11d4fddbf0fcecd2f41bc3028674bad903e4b0e2e362dbfbcbe471771de895363937a63cb5086678e3594e7c09cc29ae4bfaf2137e086d5d4c28a20aff0e24777f5c5aa0587a5a3e82fc009a9a873a1f3a06fba77772716228f1c7c5abd2a1cf38de455ae8bc2c5b08e9fd2e469c4ed41bc27de3caa3f82ce00d8f2d76089ba66d4f00d13d0c5c57287aa6b9fa1f758f8b76caa09b662964fbd719488ef500197caff04c751384a5a83e4efc7693bc727862c04231f9d1ae15b38e70cc710ce6d4521bf6e4e7b89c0b369aeb0c8c6afe240b22d814b5738936b6495f33b5f5cd4327e264a1acc9f7d2080038694af34dfeb4a69146e8b872917c6b5ad755e4338b3a191fd6ab53f465e571d18f5e8cc22f4633afb92d01a8408247e5449f3a41eb66c959bbb9ef416a0a790503f534801a95e41dcf8284b2ed1d91f2a4bf174d264a33ac7d82b188006c8510b0e394fe60b84f352c8f67029bdd15829bb65413f0a650ce13170c7a52d61ce26cb36679ddcecbfd34ca9a934bc5a801ffaa8b62f78a2add22ce17015ad01b06cfbd1c5c1c00ee4b7129ed0a142394784535ebb24f2028d9632d3743c63429e5aa5ec2f0bf5939632a569cc31faec9c0f962678c64615f7eede107911a7feec98884f94160e2527541c728e620f708b647d54d96e3c4e55e85807783df46bf7b5a9640f71c8ca1b7f35d369817625ec824efb6f64aaeb98a11f3d5197ceaf3f2129720536761d3ef4e0aa6e9cd6201b5393e55ea6570849cef792461ea65303edd41e202d279555107e2a8a81e135be8acef324c421d19335d1f63f7b612623b46a182a1d38e9f8e0475800e010f586ced1dc8dbb49751023ba70c27e4a7ac8c6cfc045b65fe54d7842b9eec6768d024670413c49eda57d780e3a745bf8fed7490fe974737a943cdbb9a1c7e309fc31148f1bd0aab135e5adf6e856af3383e1d7113491751638caf37f2ea9de3917e680c77fd255c9d938a0080bc9560bd889ffdecaaaffe432e4bc8adf53b0f99015756ce4c5e435094c5742e751526a59c212e9042967502a53cac0e541ac50fef424e7b19bdfde79c4d13d53e467892c91edf86c69446a5940ce242a0bdb726ca17945544e3979aa8591a090c27534cffe9a5aae4bf50b39ce66468bdfc7601e2ef9d47ea32f63e3a91c22fa4960332565401c977c98674d675c281ad91842aade990dd7325360aba6a77b60ccdf76beea285c15a22233906ce039b524d730af213b3c5139355e8572ec045d2392c05f0a1c82440b3df97b515d912de448646f8bc63a710dd7c05481eae14e120a25ce9490f7000d134fa9cf3e5904c7203137e5c6b7999d073950166a931c06454014f521c3c5280395cdf99786d0877f51f800b92774853c0f30059c8423771ea84e06bfba1610257ca8c989aa7ecd5e73def82b538d2986bacb6b0f458c067934cd29ad551ea422742c3e12924a7fbcf1165beaaa039cb5fbf55eb05c819ce95f3f4ec4b11d2c3655b856b53e106607f9e9c8cdefdcc88cece54b01c5f81b46146cd146b7826c7d9ad93fb9c186cb46bb7e258e5e83a905348171b0b0824e7aa121c53384844e542dbca334b7310436c0fe4d1365a2301e78f79c900881e124fe20130319dbce3d4c68b73290677495eedba5caa53f8ce246a400412f5f1f4be8b6f13f6e575c1571d5ff6c274a8064591eec224ca81146ad772d3603b10db186d22c6839597d89e6436fb28c4d8677010e7458a65651f928567d4dad0d28e1c4728f056dcdf30cea688d929f439986247e173c685394b07bf4b8d26e916874af3e0a6e650a39e2a3fe4a9816016d5aef84e3cd99ce6c1e93d7d56238f53ad78dc0f4c386a5c21d45b243902607a9cf730e4183518bd2d968ac6ca82b2fb67dfb2f46bde8478e5c10a5cd7167221e392f8478ffac9787408f35c64a3009e904186b1179b94d571a5e01d790dc684eec09828914f9c05facc660b003d1b98b9301d722f6198d040377f0b3e8000081676ccc0add35383e5b2adf3d3f8a461109e678e97697666712eac072090eb94511f3f97e905186cd32eaae0e6f196db5c1123437884480b2ccdbb95694bdc0feaf1f2391f020c9457b02d1939c83b386759c47316d2cdbe8c765f2e25df05995f8a3eae348d3c5609642417015d966aa991974ea66ff3176d08d00849d88808a21028a8b6ea396daa24d99330cd1d3f390db7ca46c0b810be0420ac4957a0e14a453225320501ca580345cb71b3b567b3e487cd764cf441fec6246e89b129004182b374ea4df53bdd15f4227dc88ae00c8216c184d75ea8aa4a5d604b0c4403ef80f42c7152bff9ba9a22d30e34487bf0033c21a29d6407154ad64e87e13cd4e2c0c6d0ee0d59421f678252840cc19723ab54803f1adb66eb9aa56465c079887d09101e62b23c4e513242dba9994dbeb241ca16fa8888617b6cac2258d507a4bbd8e428dbb8ec71d341c186257cc8c0a657392a239c9e2c15771d14e83fb8818757704d07e07887e106b37587cdf9dc269a007a31d5fab398ccd4a09549ab9718156a892aa82a26327347da40a065ea5838f4b208fcaa462f29f718d981253f769071ded21064702f49697ecee70965466d56f6c4e961b2317f379f657ef561a6d86b05535726e79cb89a6582ba228f29402913164dea1580003ea5c17e0bcf44a26d21dc189f1b5996351ebe9a9ba9eb08675d167208e1f7b8f3c655b05a67468ea6c7d8612ba0b7a7cdbcecf735568394b404c0266f480d1800e7935342272d346405ed2077d4b16529302cf50be2c4150a112bf770068914ed6ee2cb73b4ce68c80e087a31dcf01f53857ee3f04bd3d6385bb3fe4eb47aa682a9633f299ab45504fa30bba25a20181ea50365fee81889443650d29450a0329046b6fd2852c97fd42a8d6288a74733fb5daa8a5734901a1e8b0e40602a430d721efe6d486786ce9b85da93d80e8c0c12dcc87f72017ed466d1482344eebdb72444ee2da54c3205c10a8a091d0a1308cba1b64dc68eb0d714614bf5ab5e0e1d6dc5835a870e09fab0e97dfbee9de3d9e45bc132489ce3d1114e7ff1e30f3cbf6f228fe7348ed55471ba8b0716decca75e101c250c8f1d613e9bf0c40b7a03968518443cc142842221b0603efca00584161fb21bb020818926c876c08204ce5dd4576ee07e61b1015bdcaf971280d00de1d323134b99ea51a7582855d0475d3ae9bb4164e7c60e2ca3b1ffe43ff91f6a471dbd02d4e69c6d4347af002f4ee3a04038effb86fee6e104b1aa94ac815299e4df8c73f6c0b1c8e284216459c214ed20adcaa6ac3d928512848a7670430dbe60507c5005113ae860adb5292f70b6b8b1e8a2c5931f9e40825112580f561c618c0c0c1d72d87a10460cb8f8c1890d37f01026c9078717d20b0b24271886611804a6c082071f2051f485123e8412b0c801ab825a11461068b0c10b0f7c40a58b2864c000dbc1042fa31f54f811f358688ac30eb04ad3a04783fb25c50e1842083d5ea14165ce89655224ad70bfa4d062d24aa552c954a158cf81af570babfc8395d3b66d474cc22affe2b61991b84b8da37fdb5880f13b8f368ebe24b0fd7a15d5c0fd7a49c14f8750bd94e2c704710047588afb2545ab251936e84816fc19c5129cec203d4631466683fb15450fa2c892443d5284a31d18010544c85206abb528acb8200b31b4a0610c1aa81811a910e560ce395357c06c81c208cbb75108a9748840c83be79499084dc909657b944c53652050d1875e06fbe1959e11986300810ae718700f7c7989a832c5aec1fbf4522b36abf2e71bd65885e3c5994e5e3a70b53419a3d795a42cda0ca0d71357b61cbd9ef882014df11b29425ec54aabd5e1e4e81568e9538161bb10c202a0e8af4087e025136ec0b1044b107e94525a81a7115172f4e6681cf355c0b3051c6dfa663ee7cd1c3f5234d5e444707cf8cd99b95e20220752be1062092928c0747882f900290618866158bca1e70d3ef002888d0745d002872776488253ce2909a0c3133e5a580cf7cb892710c087971361d897135f946007a9c54910aa1356387105899a52428c51ba7faa7eea2e31eca252cf11720501fdc4169824a4a32d46af22a221215710d08fb7c024211d6d317a15110d09b982807e602b499118601812a407cf0ecef72a4be30d6d9f2224c51525080ad0931f9fd90a03e64b9217a42e475cb66831caf2ba526485a8cad0142129ae284150809ec81fe9235b6130982f495e90ba1ce1c8c5bf2d5a8cb2bcae442b18be4cac2273641cf20f36a055a9e7c0c7b056a95494cec7eed481339940972b68d950f6370ea861d80fb3a8ab2ab61fd288f147e3801826bf3bdfc02adbdd0dbd3b5651a9e774e350bbe9dd6982edf78657409fc6d1bf42c2c6306cfc9294f26569963efb5aea52e931997d2c956ec81c52874ddff44b69a5c280b319638c47266e2fc678638c5147e3d0c2c647c2aeaad8f89d819f4ffdc78170673103b2f1e96331fbf9547ed693bd7c2a367751cc30ece6ecbd2ccbaebb32170aea9bbe34c677ea39100ad1385429f78edd1da571c0d9ded0c334170cdfc6dbf48dce417333f5af1b626424f12fb61552cae8d0217c6c4305dc10e78831c6d88ee35f3f0d42ad34424f7637f41a6608a3c396d808c4f16626d82f74e853d8c611e3f412c4be144208a97cf83146195d89fa594a8fa671cc19259533f60d7a851b8d634e2d621fb10845504d1822125eb1ddf276479af50eeef9a7083d6b658c56222cd5186354417728638cd325ab0eee170f5e30f5dec6bdf8589884e49f8dbb5f292a65b15008ba7ed502d4bef49ce784fb2ecbb86f4c9534617141b8cb7de699ae474d5ce9b94c268bf52007f227d8ff86e14ffcc77390fc5d2e21fef96b5e10ff6acd1238ceb3d38b306dfd80f1561218a4a4a38c3e7dfaddf46b2398443d4aa9c948c42068235cbab9c91026d246f46256544158f82ecd4d3ba8f33bde28638c32668865308319cc604e49cc331235ffba6191c7de4e187032e45f3b0cfe3915eb5ce94df533cee6f937717f1edba1e4246e9e38afbc99480a639e39a9fd6da3b54b395b7677cbee38e38c33ce39e7752fa2e085ad31d41b05a41217f221d991e5ae78033f85969d0f1f7ef11c5984096a7002777f1912496929ff2004821204e4aef81e04545d5268201272f9073f432ad65d10097ae9241c5da631e2cca49765524a8a69190644624d85b9749ffdc5a750662944c77cc8d938e263790458becbc611fd739904991cdc638cd15d42f7ee6e82c148c559d3e590869e02f78b065ce0eaf0ab77a418ca17f2414b4a8fbdbc13a09fbd054a8ffd122a42b02ffd92ece92fb9b01597d09ba16083758c29814ce800c40f2bfb2aa9bfcf9f71f698b3747bbc9218af0a089b2110108540f1e6aa58603304a28fbdd35f82fd5c42450866fa55fc25f4aee21582bde9b1a75fba4bec53ec210a4eb858a5a75fa262601727de380b99a784092c3a4a428845456585092c42c207894505aa9480503c080bbd4277bd826b627705e75dc1f916c03e7b0bcca793e54a661006146fbc95c4bfde02817a2b02b56861f8ace935cb814c4bb877b7673de7a440d8ecda60118a63d21b8391a3fe61de0e367f37b20da689db8e4c857d8ac2ed471388336c8ada36d555f686e794aae9bbe3f4ad058861961dd91eb44ac76d9af7e8b0e96df60d91fdd1f7cc945d29318d086dc77322c690a27cdf7c4079537e63a39277020725580d840314d6b6040e9660d5504103ab9e208955e32809563f4ed4a971031a585dc50962c0eae7893a359a3062d598020c568d2935b0fa87449d1a47f8b0da280545ac0a861358fd45a2ce0c0e5ab07a0c560f01074fb03a0b568b210410c2b0fae11735b01a0e5181c2ea87425147c715376cc16aec0a56aad503ab1f16451d069c008a17ac6e2e4760351080c06ae824071eb4b01640469820b0ba817004563f4c8a3adb1090b8c2ea8760a2ce0c2bac2d095b7c60f5fb4fd4b1f185d50cd0a18b1eb0bab9d081d5efaea8d34f6869620b963ff1a18b18b01a5e8185cb15ac7e278a3afdc4d018276075562507ac7e7f459d28041a7c7e585dc760758d82d5375a2005ab511083d5ef495127e78814b0fa1d4cd4a1b185d5363becf06383430c58fd3128ea94acb04e5a94f8c26acd05464060592b395ec1dd6ad5d062e598c5b672d412434551abd58223b072ec82f918b5688062c4cad1cb5cc2a8d5e202042bc72f9468a8d54a4207568e61729c50d46ab5845859fa401a865a3e43706165f964fad06ab55e50042b4b2825318c5a2d22a22cc1a8d5ba8207569652a018b2610b2c7260653905cb51ab25e50656965588306ab55e70042b4b2b520747add6105958595e916206ac2cb35001d46a4d798295a5162cad566b4a1656965c8060d46a4d9982956517295cadd6942fac2cbd4cd751ab65840f2bcb2f9507ad56ab0824585986d14ad06ab582d0032b4f9f1db45aad2d64b0f27c5284abd532e28795271428865a2d2a62b0f28c82671449ad16951e58794ac15d049ce794c8c59b121105064ab8683084137e68a1e086ee07a024474a10a3862dc2d0a2450e48c440e1435f09e20b134e98f8011440604f4a0003ac8a124cb181e27e31618299c54998cc09866118564312a4644e5c590d4a603e3870e2653a6902f37182c5886c87ac86221f319ca8c009941a56e083854fd0124e843003ccc70a4c8ae924cb747202d30ab61ab0d87c98e0848b520d5e309f273024d42838273d30dd60d2a20626947cbe2825ed207d8c40392182fa184d2758780d48d2490d309f32680d5a322735d48004adc2e704196a092c2b4a90c29ad86ea0e2414703550fba329ea072123334c1dd2ae6e177f7f5bbdb737aedebed89790ecb486c68da69d358d0fe64e266688257a8efb1df3dc779317772777eccf7982e1288ebd7fa266f65bfbe49061f9a0fee63bed63aa36e35dee4c1168ed15a78f3f29199af41e36df733347e06024d5adb68fccccc8c47bf763450dbf7a3be7e4dea6b6f3dba4a205dcc57cd43691705adcd3694d679784b79a798467d95b79bdc6bfdf579220daf717b9ef5aa97a1501268bcd2ea6bf5b91b33540e50a8dafde9f439a6c66bd7decb4570e5acbdb948cd6ff6e65ae365319f9d22865dd73dcab35ce5b6cf9eabd63eea3b7b5731319d8dd96e8fc6797b24367077572894e5663c279379ab1e8d536f3fe6372f23b181eb5d71cfd53ae3ae667cf6b5a3a152a95434ee6a46ad3277d575d90ad5dce937191999e7644ed9766580486c60ae7bae7b8ecb2bd423b1814fbfea90d8c0a9bbdab2df32eeb355f7dc67dff6ae50b747e355ea7b621ef5a998477d4ccca3503116d5bfdd1e8d4fd77e67bf7b6bbfb3dde59ef372132b57546ee308198d1da9ccb22c9b32fbeac9995189bdc96b20d208c43e661018f612a9c2cd07166594df110806047b1963bcd9b1863bf8c1f027180c1f8b3ee6bb40b38b4120d35b09e978e3f21e8138462410c326d4593ff328eef0b67137f372924c71a642666e8d6c7bcdeb18176e5ea279a8d7bc7e2de6ceb83083aa713bde7030cb31cca83f83665e04647ec6631e90eeb7afd0ab368a4a6fa3c8bfd69b9b208998fee6ad7cdc9e52c43d343e2b7de5beeb7adbb29ff1ead665decc0cdd4cf79907b9ef381fdd73d9e28c898ffa5a7df8dbc60477db37ae5f2fc775377fb769db6b703b3dfc158faec77ee32311c2c6a1799ce7318ec5dc9c3df7ad3dfc2c4391163e126b66840946b1e038f38c408ccab8ef47fd8c77243e5cf9b83ddc779fdd1eedb7245d9793601822f5aebb5948d73d4fecbc0c5bd87ef5320cb82d77336cd9af50832dcbd16c07ea65f5f2aba2f5ecb79b5da8f1db6f31a713fccdd3eefc2ce2d376a7e6f59c2e1288b35fa14ede0af5d99fbe5e197c74cf3deafad85efb2cbb4822ceec0fce6e0ffc7ed8c21a677b647eab3f63860b333366cc98e1d1cf4af565bed2e7b22cbb19e2da5e861477ab9ff92cfb1a5e6f40b6ea75f576bf09e12ae4bcecfb67b84a5da8b1c9788d6be94b5fc38b1b10fadc975ca871b99bc84526b2373d8f73dcc3af35e67b8e445ce37af5b2ee6b78b546eddf8a6054cc968f64db8eed396f957d97f1787685d4d8be765ec6715cee3ea37efbeaad3ad40af5fd32df7d7dce5b718ffa98cfbcd5e9ed675f65bcd4b6552ff5325e4dd5cc6ddb738ff2561beafb538f7a6b7ffb1ae3699ff2627ee5cda43c2d06e5c9004f57c8ea57ddd7f899cfdd1552e36736eb75bff2666a78339f79dd5b2feb4d488deee6263337dbb4ed884724e2ec22716c4309ac09eb0fdf48f64fb1d62a4ae501bff4b5e4d54e48295b21f6d27853aa9f6d6ff2b8bb7d7ccdeb29bde94f57156f4cda735ef6dc9b5cb0b7238d3726edf6946af7b5a4752e9cdebee6753727c10f79e2f6d27ee769dfdd476d092e7d73df516e2e9c6ec79b8ebb99892dddedf4ad952a8f92e7037ec97a27ea82fd936f3c4a3f6b12acbdbda5ef2fd19c04e7fe23910eb14bb0212a0ff826887de6955694529e689ade95b4a7268ee39ef332cd4df0f63909debc9ef9be65bf651a7dd373f44d4f4ddac5b6db33bf6eb908cef47b66dbb671a026d99163c0d8e72218bb997e73df83bde9b96bfa8e01675fbf1d7bb941a0095e75a6ef4ccf5d53fbb7dd9b99e04bc4e9a58e3d5d7afb21967510f7b6a374794cf8990ff8f3963c8857a65ff9b8d8c49e2d51b7a75f79401ff4e13b2e79f9c31a863f4d25ada4693717f91efaf135edb5dbfed5eea10fff74fa7af2b20a9fe8d7a89dbc06d2bdfd9277bab9082e55d5e312f7f2e310acbdfdb8eda8df7d8c77ba9989bd72f3e19876d7f431a51ae371f5e2ca83be0ff854f3aac903a27dcd9007fd69fa7ab3e91e91a5928f1e4cf001302feeeedeb50df6ad7910620d279401e2f852cacffec88633d99836bf62a68961d83542b33b03f63360d894917a0c43a876dd104a2803c4fef1b13fb2612cd29f5e9c7f8d6417890772130c679833cc4772c2f3ce00ffc826af1107c3c33ef6d682ec913e9f05bf0d53c8472046e23fbd8629e0e8829a24a043f718a59c13c3324a4bfe512ad15dde4ca394d11d4aad524a391ffacc4d5a18c2f70f2787841f3ddec0813b50d4b699c1ca145c7ab9054a165cfad209c3557c8927865b32188768290e15c5a1a11987e250f63568b08da314fffca97fdefed92d72cb9d9fe116eca85780d86112eec691a11658bef4f6a48704627a73fba77dd98d4798946a8306b604553318d2b6adca703fd5fc53f506e5b7bb175092a8e76834bd83fb5337b04fffc3c154985723088bfdbc99f6883a4d55f87495746f6f4b2e36f76b02bd820c1070fc20bd02f522bea3e0c5f2f817ff42b1f187449d8e415e9166c8e67e0d7905c1b4927743a757a08ec10d48f6f2d634c1e62638cb6872608564d96d9b1e4651d5793bb17ae9e75f5954c1a67f6c2ad53719cd943e9f4aa58770276e3b7947339db49d9d5ec171e95f88c173e2973e01ad43e34de96d13a552a9542addf0aff4d0abf793a7496347ed665aa2115e161e9bea4308e3f6a3093679d2bf4ea202de6067bc7400d4ada3d34d5c83de0f65613f3d21de6261df5e66821b89c4f3573ea00b4f29c4b2b039e52502c3bc8e37f1a64b8c3addf166d88addb171b401ac804f98e8934e13db13bf33ee221d8630c49006dcb73d24b2850ef767f92b1f262caf912b300ece5d06ceb1210bacabc0426323b00cdc6d44766f2c50ed8533cd6b074838ab6854dac9f60a2aff3aa8de48c10e58c01becc45db443165f149c35ec7d053eb1f0e59d510bc0c58d1e0a40040bbfb5da36392bc231c26d488e4038027928f0f78490d2c60f16c3cfaa9fa803595a8df30a8e39d8c679fecca9ddf9439b5a193f3e1d22a9a492528993c373b2a7b452fa254c353b7fe68fcd8ab227f03d258000d0c5ca79058531ec7c41f8f13dc720a04f02277e4ae5396129009ed8f70fca1f2fc31ffb36b039fec420cff1279e13dfdf15853c67e58de1ff60f8ffe339fefd8a51081a57d81efdaf69349988afa5accd9b70b08fbb0847881a7c7181e784dde9d18f43a343759fc63fcf47bc4a1370de91b2fd5f08ebb9ecbcaf9ac2e66f35bf1ff03b6e780eec07ecdf63becb2fdaf9f58d63c9e2c252088c8b0984e5f4a1819d3f77b600f0c4629fa7f7640a24dc2f2c493970bfb02881bd28ea74f424cff9e239d8536aad4af59f7dc99330c6f82c60eed1344deef14449e341b192c6e873ba43b1be333d27fbb983f30c4df24ee6e520b2133774d8c05624e227bd817d9c77200b6cb6d8230f2a9511a4607f9a96299bf96d039bba0afe190faa3f4d0a435e09c8a6704bf1830d70c0f862849f1d0ca8c7173b3a3a0b3684fd69686cbadbc6a87245a11f8233b0425f7441cc2dc1660c0828eac496c4801a03c2802612306582c568c0fed15f13a971fc7847d88c8393031ba24540571c1afa420bf64f55e9621176e872211f7215fcbd1b6c76210b7d0862e853a80c611f5a41c83f77a1298dc387a20f6c8e4371c8e3908d2245684a169b5bb168b6aa0f95f9363c0bfbb611b28408c75fc5c07a44fc359fc8c23b44deffc1c691cd2aa3e789371907e70b2bd83f878a46472aeae0dcffc1661cac81f7c17616341ae8151a0f11e239f05a213635a968a9c0b8b0bf121ff9363c8b3e0621ccd8c4300cc3ee4ce22a804912755a9c183653087443f5b1e16790abe02fbde97215fceb0d6c76232ec95aac1575e43bd21637b253c8735e5f68f11c0f8a32c5b93061734cc2fed5b760376a1cfe52e6f862e1169cdd08c98de4c55aa61cd86c53d95114b66dca46f3a1225f95020c6cee97e5c2661ba5b0d94ee1fd1042082184dd72f6ecd9b33b1e51c28521e7c3a3961747d83f55e408f491574629a38c52ce38b18a6118065d49112fc93dd247b08beb7ceba936212da24256db7047b0340cce30c8837e9e508d0642894285f5f716ce306805bfbf0a2f84b03fcf8e0bfbebf0e207b3dc85c0b9afc8ff6c3a1fd82d7ed34714c926a97a00e65b7ed33c55fcf80d069c80f19c24f8e0238e6790b874c2400d40b5f2c40a352712c28d31d0b2e2397d8597271870f2c573561870f225eaa0be7bd95ff2eb8eac8b78a20e8e6f363552d8fc7f6505406c38be6f3e6a188c79c4255fb00e143086cd4712c2fd42e27271bf9088f0c72094e765e9674b64e1e72560b07fe45183b1db8d63debc2409e725449888bfe21005fc3a0d540034c2a25aa9c23305431d104ac110429d4fde07f0d44461db891b965094420bb500c718a54c410a9e7640eba85a075509f46bb0bc9988bf70bcb4461296c61b252c8da276d47126e8c0e5d55852f033c452d2647c91c31616930d08b6a0f809623181b003b56d4cc0840c8e581546814511ab8d78a084114b053c60e16209c065049722569d5ddc40882156c54cb04412ab662ae04110ab9b8002c688d542b0c16788d55f04e1082256ad5af4025084a41b92584a04d022a208442c260bf029c20fabb1f0c20623d6f7050a767f1bcfa1c1fed45ff3af2d27e5552202564361042d7e586de3d1871a1920060f492c252a5811c6118b09aab5c5ae8448251e049630462c29fd8bb025bc42861118575094167c253d7a83a10130a4b67130411404ce1667095f46081d32a1b60d2d515a8247248636efe0ece8f01f9e03b1a79023855ec133d3f7a75cb31ff4e4767568b7fdc6e10374f88d27a015d0381e4feb04ec65af5083fbb71da58f1efd92e7a3e1675007bc3ba723acebf09b1d1a50b025d4b6f96edadd6472ffee99be898ffb73e933897dfaac61449f4253e9a6fc939a855f189ba9dfc08fa988fdaa1a47b4c266faddf0bfb468e2a07ae907ce340e7fb8b1007deb4ef9d7051715f42256b547d7a9ef697ed3ad00c8650c9c1d6741f8b0858ba3219c298e9716a17295ab5ce54fe3153aec57173dc0ac975b64caed11f6039d8a4aa148e44352e89314abe1353affef31f9ec43ef51a9f9f69c9a87b0a606974a5a95534c2e29bd42728a7f9e9442fec1cb43c2d2974a39353fdf8f681d2ba7749caa79a5506e304afc9b9fc4bf195f06c1d02b34d6817d53f3b34b566a3ea7bce6b367993e64e3fd08147eba3fbd816d024f14bae0599ace05db76d8a8f16abeb71d36fed53cf4e4973c16e04b1ef03188829721aeb936fed53c8fd7ac6116b96e1c352fb51a221f721b5658d3ffc0ade636163ff38691c34ed6c6dbf879e239415127c99c70e298b88753382821b5ee39350fe1eae1b683e6874005603fdf850c748ee9e767ea7db618d5f0516ff2627ff0318f0686ff1d84355e8e2f74d212c6e3317daac18d855a9a621a1212f2a12a442f37f22d6ec5b3b8162f9a9e93b10fe2dfec998209492121cc83b8cbc67536de8643b75274c58750f81a358ff6d8781920aef9209e93e10fcfa1475a2ad745f1cf6a5306c9201b33b0335ef5331f5f0a094921cfc15ec7fbf9b268d69f2fab78ce7605cfcf320b9e443d1febac149242728a1c62c1b124a2c9a7f1d987e8cb8b04d2fbc33f1b354f1040838d5d3cc7c6cf8f4851e73f3718e9aa79d37ccf931b0268b05906f504f16ffe11887ff4c8284151c75d320837f42af3a14729b1e9e62518fb98e4dffcf7e217bf99d9e7f6dcf322cfadf837df5d13859b29ae71570d2f435ce3b18d4786b11bc348b1f0572ff333de87b46cf19c159793ed52cfe334980fcda743f2ae543ff3b9c1dc0008d702f73e047f760b1c1288e5cdda97bed478c653d1f088f89fe1c9789e0c30c6cb5ae643783eca93211b1267d723eafc9ddca659f8df377de502c8416d1b79b2fe4de95311b083cd90c8debe90c8b30f3de939ab7879c4b76f79649915a845eb582f30169180319965df798d136fb0a7168b5f33af6b11cdf4321eec9bf8292fc683561a75ca2ea47a94274f39822296619909c7bfcce413630cb55608f405679969ca2eaf2c528be422bb74af2b451c07adbd48208fcc73b02dba544aab86f2a015ffb0c77995ca62367c605ffbcc7f8eecc582fc27eac43cf60ec573a2788efcec841d798e7dd4634018f3208c611fe36547d4b60c83b3f7417a82b39f5070f676fbd104a3ecad5de7446cf0ca08c4a74722717c231d8ea887017591407cba19da7bc3bf18fcc39e03fe61db860027367b286ce5348c728d655f3b9e7c3c27d3bab6297af705ffb0a71a3d71dfafa32f3843220989b85849ca6d74c57330ac888655cc84758fa5fc9b10a848d4517552c47060c0bef4190da1b044cbaaba5ff58924f19cf8f57dd4afb5d65ac3e0fa4d1fd6d7d115dc5e70bfb2d8822bdce6170c3f460d7a595ec1b008e248875863187d2638bb32a9be464fa9571657f0fc1dcf51f1788e7ffd1e5555359aaa5458efe15fedbe81945ef93d6afdb6a9b707b6b0252e300327607051c51554848912813862055bbad8628b11c48041104198c11170f02148881daaf051c1ccc28814203184215cc9d283186300318f3065052a3f4f4822cc183208c2420339ace04b0f2508eaa10a96021370f92268e04cb1e822bfd287d269d432460361c4a8ff0c4db089b5d05af0bcab161cf3386e8241cf72e79c73ce3c21c5f36146fbaee4cb246cc00afb3766d89c73ce09348e7e991c6c8c3d5b7ad1b7146d79d11d5e5b68c1bd4516dc2d01937c93d79b04a8cc62fc58a2b494655966929b04fc8bab52896634e062bcaa69b6b5afdad7faa79b93606fab45f0f6f6330ff59d1773aa7faa9f699bb6755e6e125304f7ccd3e87e86c6cf68cf3df184c6411a35be964a5f4fbf51ede6ed2bd7695fbdda6d0fe16b5f3da871a7aafd8909e65ef37c701f03bfbb99d6705caddc37d6b6ef3cce9ba1098ef99819dcc77c6f5a0ff68dbf4298bfc678272fd73fc9a03a542a95abed6eae1f83656ca5b1b57e198665d8845de68427e88261199c451815a51a9e0076d12ab53f60aa2382e1cdf32b0438ede38cf7d4335ed75d8d4b693210aa64361a3366d7fd065f06de4c24055393d31ece7ad2b4874422707af8dc77deeaf4f5bb6fd7b4d5e9725fbf3e470477b0a630f7f0747bb6ef52b8bb4452d86e3eb6db2a1a57ce9832a914d4b40e7615c22e057f42a85d6ec26e42082184282f13c1288a632c8e89f91a73baa70ff51c17f3a76fcad9989f93a6f0bc99480ae56522a98efb69396ea6344efbe9715caac3f3bbc97199480a6b29f88021449a0834006207a926020d80a08208462919341428385ec16928500e10a1409161a0a86cae58e9bfa3809e9ed669321675b279a1fbc8c5a44cf6a22e774f73ce79bbdae1a8a2a15aea53aa97b1aa4f69dfbda6c99c7ed6ee352436b47a35cd7efdd879b9ebba17509db742fde93b4a354d5ba16efdd39fbe3ef7272fbff0029e9afdaebb446cb8db23a379446cba4bc4065b1999542ad5a53aad6adfa53aadaafe55afa2e9ba17e87ff5476783e21ef539aa5da5ba99ce90b9a993bdf99ffb19af370834e11ede6c83b99b89d8745df7bd751de7e5176c1e431a0c6930f7f6db7354d86bff50a9d4ccc39f79eba1663e26e6a2ec678feaba1770ccc7c8e7bc8c7acdcb2f74977be8698ff24e27cfb166d3a3bd041a732fd8f080386b3df51df7d6a3b14d2662038548f53b48e0e265b383042ea4a0368bcddff78551a1e70fdba1cc44d052e7b7077fe51f83707c611eaf3202e1f6a3f8ddb862db8e9ed3ddfdca7ee9d0fd219c4d6210c4ad1939b09926486e2d10a778800a683ca1d7dc10ac651b9a54d6f0b77f98b3f67f088637737f02623f88d6533ffec7496562a6bdfd55894ff1e5576dc710863fc385e1cb7cad70d6c80186cd45f0f63602333ef5aab740e055f5d4b75f3dece373430061ee51588668e1f9337cc4fcecde7e05f290831ce42007b99f0fb98ff172fd917aed2377737cb1f36bb511e87ebef6a7b7945abbeaae8fd3d56e1e82e773f5b31e10a7b2fd989be38be5b8db937aedf6a09e7b1eafdef4b2bd443e9c7a5444cd78f8dccd7d258d7b2462998733785cc6cb4cf0b4d23f0e73af453c2390ebdbe7aef4efe625986adbb6c3f44022de2260aff48ffb7ab59be11f893be66b0fad7fde839dd087faa64fc2404c587beb0dc1311fb71da6b6c11c4d4e61eedb5f7a2af5b6dbe9db3d4f4c7d90edff69a0642490d46dffe03545c0f4d56463eccb08944c9ec5e202171ce1fa36428ff3f210cc7d47934c8cea3feaccd030c9a86e7eccd1b83350375b999b8ab9f99f279e3c2410c73ce765d467eff6ebd7efcd879579ce47cabe7c6e0886da43eff4315ef78e4f5e465d5a737dedf49c37c487c675cf133b2f33c1f56a57fe87b7979b29fee4264343b0840800220b128edf48208e3e64acb0f99f86d34082111536f70bfe8e0e1e8feeaf84a3ce6df1bbd83d957aebedae92be4d58a62bb59b8fc4a01804c4bb441e2250e4e19b51a21882168c833b8a214809426afb90d5316f9f55a800ee4d5b3ee2700b6c6bc184bbede7c642f7f4e186e439d86f2fb71d5b103679361fe79c318495dc4ff9dbb7a4bf3ddc1e6e011500f1b67ddc766c4d7694baae7b16fcbbcdabcf794db0c435cb3cacfa54a27e663fc76664b1b4c78f209e331fbe0e16f59aeb344b7a2688e49f8ccf04671e12962859706309a20b5e006e2c41bc009f1e7af9886f9edc76188165e0550bf1edb310dfcaac04fb5b8ffbdebc0976ef8863eec22d600a5a15ac3d4fdcfc88ac127fde8629cc9743fe491f700b9882fcb943b5b63d932acdbe09ae52cb3e635a9db89a30186b0eff6edc10e0868773d338fc336f003005ff8a6d3c20748f374e4f320cfb52c55a0bf1b3cf10630fe3bde11f8df76b1c3c7c45b388aa695aadb53ed5a6cc5efb1a3dcd93d9c758327daeaf51fab546198e64b8745be832307d235d06ceb2c46e8271082c3070cdd77cb09f0f1f43081bba3c1b9e05855e76c8c6095df1ca30f11109b1d80c5d2f03c42e1d58f80cf879d67cfff7b781d3e61bba54345909be242fd8ff864dd9e4584db12f9b2d24427e5e6343a737a85654060e4e5216ec9f2388902e3aea9bde2524e47209b9a440178ecbe58a49415651d8243c858868ad120c12f2cf8d8ca04ba607d005849424c465250616167e4c7a127bbc7afc78c0d10fd5878af419b5ee1e416c606310608f30ba60ff1f3f640f56f3cfa6781e8025684a1ff578ede8c83255a881cd36017de34f593b8dc38da4c80115acc900230e6ca62d486db05118f44d5f4d1e863ffefdfc98624d0aac114fbc811f05fb13ec57608741a28e6d1fb48ee91d628161d185ad7ec1332c77c9a8a5fa968c116cc1a4cc08368ca01bd9435711ccb3e159548a24b1f1163902049b3ba9086c9e8f3aa55799262cd18bdd8e37f9db51a4099a8b0a55183e54a3a13bfe2561338d5b6cf7079f8c2a5d38fb910c024202fdd01f22ea47447e9421911ff99117ecef5ddc0b9574c88f2891fcf123223ff2a3272da5ab8bfa72c7e3c934efb8c7d71be1fc38f39ab08ab2ec2ae97893a3500c6ac28a40334dd878e54b62c1ae2c8a3744576cde21a23f06e5080494654747961865099b77e27b32409c77faeb5ec2365204f2276ca6389a3472c7be4082a14a10215d62908b0ceb4f630516c628d115831ac74c1376826142e3f0998414dd592e5bf18a85374b2224dc464141f3c8bf56bffc7bfcc05a3d5430ae42eb09d6679eb0f0711cccab83b0bfc4c971251e6d61f3e73f5bd5874abf0dcf2abde69f7b3c5e0f256ca6168a221838c00323f6b1deff82fc117cb0bf0dcf03b4dc20826a7ea38ab7fba879e2d314451f30700073ec042d4ac148c2fe5acb070a1582dda14f6c862df8b303ed1476b6eabbe969bd41a2e9be406fbb7fd65f94f0cc9dbb53bbb0721a1164084c0f2ed8ff07929730ad658b43a65716a424239b61bcc2e608b47df7a7ec43d14571910a84bd077424ec434343eefae2d50822253dc6c1acb77e1cc883a0f52050bc29e2b697ab8bcd146b911221e43f2fa129561c0a7c1b9e657a77a1a12c363798f8039bfd487beeb3bfb68fe1155f18c78289ade8f0667be1960c07c38144b6e1e6258937fe9a67823ff1860b9b29a65a12f58c09306058e9a29ce8f57062b7c4de1277b06048699982fec91dd8577545f6937039d0904b4a15a3e8452b6c7697bba45004fac1591205cd90416404042a8c3081135b8001f4431345c020c51006fb13f9b2a323862265d84cb514582f5d5aa6a0f4b420db02a42d43bcbcb0ff0b54a3e932c43f57c11f853036d3a8c5669ad48497216fad228c9708ec9b35b10d88ee8e2a15fc197498e7f3b90afe363c8b4a868fe3dfd71e4e7ffefae2dcc0f95c857e1eafd16b6bbd0461ff94a4f24694c1c1e6ef7e9fc5e68ff6f7e9b8b9af7cd8480b0fca947ec1fe5a9047f129290bbff2d830f66a1cfe364a80b9a20e46146fdca3640f92ed4921a2a82387a4101196539e0c2baf0c722914848786a43c9248f4775446b082fd69bea688a894ad7585452d11d10c0000003314000020140c094422c168241a536565fb14000c93a248745418894990c32084900100100208000400000088c8dccc00bcbdf5763e6c71bb01c0cee3087158de58af47fafc668d52d7008b50c11dcace6ef541765362c9b20775709e16b79d1e2c8ca5fd113d585aec72495f95a9b562d016689e6e6d922c58f60627a7e5170064bc88a92bc017595dde71fa0805c6b5fb5338e888b1ce8242a363b4dae59a0cfe25656837fa81860b6dd383116b0544ae81af24ce2a5bafdc4a8308f5741483cc46319365a504c6be0e5bc65d12d3daf2fef471af7f1d91f59de9ef45639e56ab34d38417e9494cb508995c9744f9449a6a3909af86e09a94982a0690e6e8c28aecbde3bebd5e8a9f54cf5e83dd01c61ec3403c0ffb3dd6b1f750f5ee416ece557ddd8b94243f0ce583c9acad7be96f3249ed9cde7e4707c222cec723d0bb89738586c6904206add0bd82ba833c64027d57388382da5eaa8340c150adb0b3b07b53699df40684ea7d299eabbe986c4f7d87a0c0d05cfd008b8dfd5d85f6025c6f6ceec522e21b48633100332bdbe1040cc59c693db8a589a7dde0c756affd0bc1a6fe293560497f05b6f2870427302c2298b9c9dff58a90c1563f85691b21146af1fb6b6c2f7efd8b5ffc321fdbef62171035ff6cc51c694ac1af619b8a96c0c9d84000fe920376504d4acee79413ba024f8d9cb34fbcf2da288c33154ff8e28d18176376dd4c91a0c3e4969c85ceb9476e2574164263d7395f3a9fa3a7686eb5a79cada1dfdb82fffc84143d670e47677262eaff857ff6532badcede4f8f3ebc0f8aff899d6f4b46d11c8a819d0b96ed2a7898ad8b98a6f6965b06fe988f04efaa17a1520d020ef7cd69d983ee35621a4ae0d0f997742e366d3ec9c6179193ee51c54aff24ad0479472076105a47773dce41488748fb927472b8eeb82ceb988796236ab76dd152ce500cf95dd060a41556d6e03ff9323729cca2f563c671790b4c4335e868ba18d520c042d23214509e5718dd5e9a6a6b566be52c1852624b4e9a721df7cf094106ed7919aff9f1f071f06bc886188a6388081bdeec4f752ebeb2879cff93dc511e1fc92ad38a3511a483f971918cde9ce732846bc7cfb927631b868a5571f61539dbb0e13f71470ae4ccf9b0769b06edf3311b561bd0f337c9982c39a77680f6fd7483b10eaf55a387369f519d6ea5769b0fa9a5b6b0216d737e565404e89a7a8625a9343e25f753b87941f2bf64f38148b0bc512cafd94440e136ff4c6901e8a8ee9e1fa149503e02fb40d9b1476046497a64fea740bf5c9bffb48fa9756d1e32328ccf4af0be8cae66c24fe16e3ec865fc28df801d155298633e82815a526e2f779ffa687a0ee25a9f2f15c9ac3c0e7a65266f3467a6292e638f1ed0745895ba109b088a6074749acffad589c30ac95b854add954e3dd31e384c874ce359f09ea159a19feac963e71c660c392a1873510eea586f5504ccbb0b53fa2c2ab43d3cfd85a7aaeeab5785cf7715c6534b1c23af9b221e53910aa53b475a07810bb32476b1e6001b5817cb5c9b17c719a6736118962623323c10e32a486a24fb9cffd444c3397fca3a52cd70f0bea66e38cd39b1fbb6e22acfabcc9ba169e7e45f97be0e9711d0337f89ef6340cd72ab1e21e29e81a0feeda5064feb16dfb9bd6b128c405ac79fa01c6955df03f79cfea36f52f7079ee5b4d1ec9d50f149f1c0f6dd86658f832d60e088d234e3860a66423b3b9be9cb60d3d3a2451371c8bcbd32bde333731b619d906a8d341f009362dab908ec4980607b93d3a94001305c7d0bd5822e959bbcd2868fb30ff3b0dc88b74dc559a8f328fec37a1f39bbd06da88a34b31fb030b1e5cffe26e22af74b5d1e45a689c9811d4c58aec15de935c61d40463f52c8bf9b1330fd0eac0cdcb096a69c0766b745a810a546f79e91cb3ec8fcdebc8985e2f7bd05cfd34ffa1b62dd312df30fdaebddefe3d495d032dfc4496398498b61ae80bc23e89e1fcb58aee1052ad20d5aa1cbd0993abb70fb21fbb735605ade496bc58b80d1963aa41803105e44a49e782b48602fb8a26697874799b3c4a71bcd2988d8187643241c341a6166f07156f5b41303f713d488e69abe29b2d413bf940df1e7f56c14a7959dacb56df8c9b85dfd5e4b14cee8cf8a565d3f9fa11d3bb9457a3a782f12227d3ecec7b87b706c9135bad7415c47a48bfc682326992b439349301585ac1023033cbaf14586a7dffa9d1d17bdb975cd7517aa8c37410cde23c208f28783a0972997a22f00fea8051609f5ad58e1d8b47ad8ddfe1c64ecd3a6a119e75e2a1004b24f15a613991bf90411eb3461a34ee642dd4a4b9ed255e4ba05c64ae9c8368c2ab8c2c39bc6c44bca8aade4cce4235c2391de27b35db5d113c27251a382e4336fe64804d8ad5b13f161233d29a034d2257cea0ea8664e0d4b7662530a2d4a582a7de90239e8486faf5dd8453ef9911ba36eaad8631a5131319769c4b0473e57bb92252b6490c1cac908bb23adc8a9e830e91abf3a24576d7ebe5d8213d8ff942ac1c5c074a675942782b2ddaa1cd08605b3952af210c2069706d119893499d79bcdf9018dc59d72754d0e398e86f3015909e70d13423543ef2782ac923817c9059df621323f33ea39e7e5b3c4c1f614dceb990ca6ba30722ad6a7e183dff41f72ada08cb49426c0531f8c37a211b13d1b5ce424212267ab333a4fd7c9819b40bcda9d15516624df0a46ad4ce98e0e5eb5c8dc636fd0d2d58ca86c3ed73cae0d307d72b8d703922c848148d41040c6e4e7a1f48192f34f5ae45f79215c30df061682a07c3fe089f2b3b6754cf4635c5d0cc6c70501098278e8de5d29c8f0c6381827bdca12bbf22d84217eff3f7404ba81ae8afdcb818c64d9bcdcadd521281e284adbf2cfd9904696189b8e11a370e9c2fcdec7b08287d4a26ebb8f0b349121f2b9165ab0602a2a0ddd4bea3ba918c5381042bbba75d0cab849d66b1851677f2d80ec9ddb9d3ea4980451ca5baf77e003fb8a0177d2a4505e439f5cafd53ff5dd2073e1150bbf84366d79bde689588fee9ac52ce67a67446aadf09bc379cb106d1ad60b902956fbcdf3537e9309dab6be41b135e86034955f0a108bc753fdb584fbe2dc2fda70029cada1a8dea300b986ab35f26a03ca6853829c84cc864ca023c3d26752c1a2db0ad89a52ad9e3932a3f0a7bcfb5faf5c7b9a7772b708dbc86b2f6a66e626975a836d85f676f12e4c2227ed68311f29d812191224f0517526739bbd30cbef7de5570093dded20bfa76daef648e194abccde1b8f0eeb6ca48371f62f25929023190d0981f7dfa946767405ac0cd840bef0dff841cbfec4fbee1913b65405b751e6c103957595c9b2024437de8685632aefd073825c6127d4bfabebb3fd24dd3337302a9e1d7e48a7968fefa6b015bea15f37216868eccb46c37faa5b790bcad875b6c98d3dbd9fea891a711a50f77f2399c0d73ec528490bc1894b0eef3582d5f9f12c76f80e10ace64b4fb189b09d1f3f8b397d0ba0dcdad2f84c257ebe2313d3b7e9b9d2e98cb80ab06d8a60738f2ac258a52747b5fd0050167f5efb745223e512fa089e6d2736205c34939f8592a478e94feeddae146de36c96159713b85f8fe6eb75611f3a376884071362c27414d16bce21c536c7b2d54e2cb5d5c94401091f497d088d88202bf9409590b3f67545145e7816932e7e7afe262efa42c874d4c136b94fd46ec2d565ca8acea621ed3843e4d59bc831c4d1d554254fcd417ea6d0224f7ae40fc02d4fa587f37bfc605eccd990f8d1f80e95a4f83a15f4d466f92c87b1372befcf7ff9bc278038f2aa00aef575bd28045660ed57fa98d93bada5a14562397179cbbb048769f7bf888d8a8b7fc6266551d8c396b35b82a09c8514edb8854076b8b7c82f29a46b59812da87560ea2b934f9cb062b0390be579df51869a11aed68f06cf40fefb0d1e9db875a9edf413178213c8e717a8967780e5fad8be9c27926ad3438e85bf8d98780fbdb35937a0b571d0b755f010c483c97a16fa67730cff49e55b38bd615560da418c0c73fde0cd06657b1b78e2b86ac45efe18ac892bfe01d0b2829039f75b80f66c172ed913235c221dd7b2ce73546a9adbad89667b466603168f529acb08d2b6b12bef714af6437797072a58277e402ea2c9eb7a64c4ae5912053ecde75f5497957eb98f90a0fde91251e4dcc12f089d4366610ceb8178baa6ed38ee129f83955949ff37ea7dae43456ae2d875a9b26a37ee2f69a4c97c3fd42873c5ab026d9dac78af3337a77ea0b9a094913b0ebb9c840379795e061cd88b5ad0229745c40b9cd824967801d4b75f53b1c6574b57fddee2d9209c9646391f643c939b48fc4c2ed03753fae15da873183239cc943d60dd7e61e1446f4b66b653b7cff29f481b0398b82c434e919aab04f2fd21f67c097f71fc3651b5cf772545614f3860ef8251b76da66e435a68c1a913b511d39a9c2f141d4c9f44dade3c4f0cfd2c4bba2443248d45bf242836440dace00c92c106c5597cede299364e5248cda8a02c2179dfe03365ece914bb80090b7e3367a80c1b9452014cf7dc5a1171cc0af17df33f618557aeb01ef14a7d529cf190da28fddd1270d7f1bc4773cfe665b1f1d9020c4a35e32c55df1d934b98c8879ac9d51943632a67b0b84c77791f813833f906deabee4894c1793655dda5fdb72ff2778aa0828ffad5c6b2d03eab0210fc18f385bd319d0b8a4df5d6af1907a2030e497c9e104110740d0423410c5c126983222aee559ca093b5063894843abf799b46d943b2018431edf113a6e6b9d47c30aab91e2760ef7be455040c9596e9637a9d061dc1bef7ac06a4bf5c0c05155a5bc5532863557ba890bdd350f3b81406a042de67f8b320cfd50d4a1f6e1c478ec2ddfe7e48f3e1f222d4ca2313b09b39b4cc57256056d8e760bee7cab961b9f4ca7fcb20148cd7dc0e39a87e6169ccfab6b10537702ecd7e60c503edaf671d5796319db236c3b9432b92b621053912bf51fae699800d6045c8a5c0569c5664c6959a02cd172dc55e5e0a7c29fcdb450d10658528b28e9089972695584dee4c89f1602616bc765c57aae40662de3f6a216e8218678c9c6f90718cbfb40625b2f377c262e862a71af1afb431405ffee10f17d790b14c686fde64bca4455eb755a360353a81c1c3f3700b7c40bcea213a0a2aadad071fe16a37ad5e8aa28295b4aeaac4891f26fb2d1f2266da1f73181df6ad8cd76c2d89512e12cd2a498dfb0539f8146072f58376138006177472f901a3a5e885b5da22c7798e0f82b50fc3ecf53486e84f3a499d3444211220ddf027e64418f8b1d603227ab351e564a486f436cfc6e5f4ca98c73670dacea3042df1a217343a6d97d8693a6b115b9a7810af3b4432b8b167804a005135895d1bbace946ba8bbc199f6b0dc2c333ecd2e054db3b4bccb5f0a380a776c05ca1dfd8bcf55984a9785581c2bfd0ea79666325038ad436b5a627dac2281defd6a352ea7bf1848033b59653e9986eeb4b173e72edaf015fe94d1406bed8af9b3185a865c34005460c67463b42ba4143181da0d584219a0fb6d0c2b44d3a469deb7e3e45793663c837ab29514723eed0c88d734ed1f3960a04536a3b023b5021db3f3b05acc76b3194242a157414c37920258153cc9aa3cb1a9209224ae19f7d222015d37313c76662a8ded9bbfcdd564ded0c693d2b7f637ec601481ab1bd8a30158782528c3ee190db110d5244089ea11d5b34e3fb196a644ec97acf61598ff7e57dbae3ad27c79be08f85e0b4add6e2d845863c3a4e5e361ce03f3f60b32d08d97d19efb6f12aa4b6608aa2bde3353591ea0e855429ce829d50d9fe7dd02c5d4544472976b9db3b89073241d899236e1c7f021f2a31f5b1bb927d6097b502c62ddbe9f438f32302f572774ecdcf25a5e62bb7f72762781c8e28f32d056642de8fe2168be17e77b96c26bb44da5088487794177ec8fd1e3fb03ae797705db034ddaa6c421e090be3f82f805f5a721520e54922cfc4584c2da675761f0b26c800dce8528ef89ab60d8e6c962edc2e8ad3b455051ac350795f55b49e896243569540e38620f58ae9318c82513425a4e5a0b00c880c8df865bdcdabec578c65d31a7766013a319adcd5e08a7c393744c04124ec55506e093e8a10bc81a1022c500660c2b6e11372a852aaa75eec54f694ca101136df74a591fd3076d63eb7068186711e3fa62100f8cd583044dff7717b4382a46fa60ec84ebd6de0e5ab58759a5dae8e6dd82be47991b72e33195b76a49ce5549be04329ce0a5edb4f4a441f481a1fb6630befcddb44646bc7ceeb49e0c1051c04fbf9d1afa108e789b22ab61284549c6d3b43fc8abdb64d5ebdfd64b1e2239513ffbe136deea5e41cb046ce5bcceb09d949d60cb224562673e000e60f28f86ff0f64a4eddcce9b1a63e58a0d2dcb24f89df13202f5baadf62964d6fa3a6bd092b9b516efc9c2361d403355beb7a7e7606420f968f991fb279cf536cdab4310324fe01685f5cddf0882e10a6b5d463668a61ab986bf8d5cd9876a11f6f290dea7f2980ce94485ab250dabe997c02a473e399000cfabe4ae5eff783f6d281e4f57e909983c250cd3d1722b0d6c915d326b4ad57744ab6fa07adb81b578de5fb8d3cbaefaa4525a8e84a9900f2ee7a4ac2f2fea36137964de3ef2a524a30aea830f4680ac29618ec860567873e82c30bb54cda869e676758b27a360bfc99bba472b505dacae2a0c2b882413f8d737fc882b57f46e09950adec77578cbfc8c4a9facc280644d60b5d49be8ffe70479d610f50422f813aff62050c56b53f3dd860dc6ee6d37aca382b673f09aacb9a195ff80ccf6fabf93b6ea79212a0dc37c4c7db5cf95978d429977b152adf80ca9956d07cf80fd6fd3a69762ae4fd39d382e540e837d5d019ce8299178db971b7dbadf2b5a39fa342607eee133fd1ed9dd0414efe3c47acadee50ba6205f69ef82524c4cbe793cd73bfc6628b010a9344d626f85076b62e41afa88b7811101f6bc02d89171c79145ed83bc87328ae8886ef772a31fa4270d487c97f6290dce582056b4e3da0b60e666a9f9251ae843591c79cf7f4d519e76baf6b7171a90326ded473e6465785bb40eaec41834773adfc90ce8ae00d76ab1da3f16433b84799c26d1b9090e65ec19bc7dfae3d403b1a8f3592b02196102399580887b4117cf8a324fcc894e4fa4adbb83737a66e5157d0e130254fc2c0d673bc48b34fe46af4cfcd35f8ea6f8981a7afc32f3c592dd2a37cb879a89a1b5a54d112b29fa26e5ebc95d10bf443a691e3c1d91040fb3e5477f8a8559acd64c14d970bb17bf02b04184d426a068df17a5e31605307bdd85f1542510732b20ff8dcf39427563d9bd147c5b2e0acb2e8535a6ffeb11680671d62126e5baf9784993ad0f50d23f98aa56755585898e16d2623230f584acee1b1ce551b3e32e007a2124c4afca4970c48f646725aa770f7976c07d0a817a2d7d778fc4f5261374483b5cb6eb46ce340b68cbed4ad9ad300a86d5ae59da4132340a3514911f7deb56f4fcbfc88c940eae3893ddac04d0990c616f49d262b7bee75c2269121d9ff9bed49af63703d6238d4263f59163e2fdac8cf598e628f80b320517ed7ef93036e27b3526daa65530063bb707cb7eb5a018f28151b090f053804486272ac002764ca34e2a907dd091755b4823136a525b5c78e90f95b171cf8890524394912bcf068447ad868f0d4444d1474e4e3bcae03968dbd503c16797d0542aafcbdfc5201e26465560c2bdcebd33d0eff34536670327786342855c6c64e7d224eb00091a5fe8f9631c4f575754657f51eb2a4ef2ee780a0c2ffb13400af9484d3b86642649d00740a26fd0c0ad8d9c26f56f9b83bafa44f4fb7e0f6d93bd4b7d034f95636ca01566e60fd584c4fd6676afb592e8cc86f6c016c4b6d2c31ebb4d99a524dd063a7791de64f796854799a825ebeb537c10c91b49023c77594625d2d36d3e06365977e2863f29f8f1e6254879550f54a9b90a64650716bebadc514d06e3384380c9003b5290e42989d4f28ccb4bd733a0e5dd88e08edaf1aabb02aa09ad3ac24835b8043bc7c580bb9d061971e4fb334402ac542b17b54a641c47696988f3ebcf9c33980bb39c73d005b3b78619454ff35e1ca763443958441a1153820de26035086c0c012e787e797f40351738703850a22f1cc198a37ecb3a07e2b310ae52b57db03ee03fb27602d6530dcc1955b696b2ff0c27646af7e21fdcc14589c2f3caadfc98b273c9574b1931991549cff4dc5b657a51419e2b19135b07caba82a574c092313188015574fe605c3e05a275603f3ad7a0d50955e3e29df7ad8d91a28372297fa11a1f45249fd7e173d467f7fed9aa699621c1509875e2096c5ba815507c32d33a99ed598f5a14830fb4d4ab9fc1392cf97043e6ee82adc5a8eaa91af973b7dd19381a2fa81957b4f921144d9ddd6bd61cc4f18f432e932fff65d4088f85827cb1c5e2d34ba0267f52593aba9deb026229772971d928ca843aa407f027137dff4b13eba0ebedd147e23ba8a02c03eb65a3dada1bb84205450a7a9aa25d92ef5854d54e783fc2fc445dbd04c1fcb8bc73c85579c12bb271be3861fe027c39fe5b1cf080a4d79cc7c5eac2e896aca823fd8eb09e6b0704c1a086b54d9f463540e0191e000b74442d695a1799a4e3b955ebabca6b3034eca7b6c2b3bec138022a5b25c8011c6f5646c81c3fa844b9891597dc6539987ee13ba184238f0f2857348218eb79455fbdd88e500d5ddd53a9ba62c881504abe4cae3303daf32d9113bdd196a02077b24c919c2015beaab82960ec3b37578aa4de809a62bf3e8f7c63ba898bf0c9f3cc26914bfa0479830785cd17578ddf70306b4422bdc151047fa90386e8089386adb24b6b8d15572c7fbf01026c5af2de7eb0c2b5adb36c25b9c74dcdbb061b131e38e0bef894f90c3a36634e02851212fbbbf8ec840a06893e00d5fecd986cb7f6fd24c5c473fe7f5f66fe582c52e2b7f23935f19bd81dd0961016839db5f21991a58d70f893517121404f8a5622d4c0a074c7bf6f150d3b373626a8c88f27d5308e6d48b7594147a1f16f88f3c8f173a5c8e4390190d6cbeadac1e8cacf980becd5e9ba39d3568cd8381cecfab96dfa91b10b7b58bc89da82659afc7990b1e3e97f1e035e92449c97c5f6e7acbde920b652f89f785207e0b56b92c8db69d80064817bf5ba94a32227b959755ed526e7e05e98581bf23b9e3a8368b03508ca034e49005c802cd4490aeffa99db98a33bb15fbe8f836ef5752b14eb7078a1c43225c3d2fff9882b6895c4a3bab235804e6cde26d6bc41bcc6bf0cd72d33aabf709645b3829428d9a39512b1e76570af0822f8d8f878203b8346174a61638943c54c4a2ead1b40e4320211ab1d5bf0a0868346d582dac8986ca3b9011243c7f85a851a72cefc6d019c5a82893f5b84222c512f5763c73473ff3577a9274791eb64f101b1953e0c22ee1e30b918d815690c3836e779d011d1bce269ba653c4985b5b3e2ef479d2418b081064647d19b84aae48b889e39c943316fbfcf47ae349b2417dcc27eefc2be900cdf9719d693be3695664a53771fef8654bdcea05cc41004c378fa12a2cddf50ac98f43265e3e29328cd8a2222dedd8cb2d0a96563ba029b66468c7b8a56c1f02579af90519a0d2ba936922a254094ca8edd7ca4a7ea9f0807a074ad8dd9aa03098d469fb5df074d6da54fb92968572c024cb923006c87a22fd81fa59c499a3d0e773b4e68bebcc2455756380fe895e78b014f0545d3af69778e40ae15ddd4532fd3460808262ac9d30ea1994c422785cca3e629e9867ecc1855d80d799056ec73326366399e8656c693811c8ce653f1c07756c8ef1097d3b9496f1196e0a00eb7924743b2b8152a4953d11e42ad9abfd39499f4be64a833dd70daddab9d88e0ea1d46c50d83da768497574e74563eca8bf5777be0ac635f584cd65b9e9cdd064778df888e18d70f92a1574a904ba7209a61ec8e9ea2db350b2b764bbb78114e8c4c40d7828399a097ceda9615b2177c239981cc333a1eb5e75b14eee591eb486f87e41559658fbc9f3a83840a72f79dc19c5f30544c80212c36cd7c633c6064d527e3144907f87083da6c76fef47c49d85837bf7872fb5a3fb68ffce50649e11ff3632f2130de24fcd2029101c40a517b8de2ad59ac9dc7b5e85b514e8b47b281ee310278a5a4085633c5b16905ddea50fdbc8009913260e8065655320de44257f6bb86c6424acbbac0fe8839895d4fafaac62234d33125b83082864c40749d805fe81e70d4e9f6b67c1574e82d0ae40a8a829adfbe0100cf122ab347a56239a0052a5d1c1734141c1667fe9ec8817d2f6d7c62db5e3b1726eb44de3624e9d25907093d8080c56b1dc81858b6a36d8fe49cbba0291713b03cf99ee70030e00f3468eb2a1231d51f18abea950ded7b3a59c28714476b38e7f8507281315cced5d2130ed5ce20b5bd82004b3836f98b6e3172d971ffc5ea0b3276e6ca3bf135c9dcf49da0fa7336b68ba399708c3bb89836b104fb69aab8a9e3c431f21453c013b37a21d25ed2f3aade04b71e1133b36184bafe1d4c119642d280d81677c5867ac4d418fe2358ba8296ee4a8f0f2cfc9e9226823c2a5b36b1558fa19723d5f3723dd3cb2a57ac4cf185e93a7d91bfc4d4833c9b0cef64222965c9577134b3f5399c2e4bf5a6d3b74143bb20a04530371fa8612cc16e2c26a279553eb061504b860e838d85807a4fe685fb0b8ebf112014bee891d7786eed29ae0d6ce127cda968be7faab74a86761d727fbbbfe483630b54e1771a59fcfe7076762c00f27475f9d9bccd1456e65f64c9f7952f3b8cf5a61025961ab9c2f28f9322e95daf5de131c27f026755bee9f136230595c0e9302a85d1115ac6a8e785b4db2cc06b5e55282b81c720ccd3a5c6a4aa2a7c3661de3428b94782e36cf5e2dfee4b58777f38496da8ffa05483c22cc126d4c74af752cb35d22981a3147767685e515267b275320877ab5d69c66c8240274233c04771b59d4a9faf952ffd8b48a894e59087d8609285a738dd3faa752c2ac53a195dccddc5e6d4c9089507e2a2bcce59310c2b7ca15aad2e35b2f302936a0207ccf1da58143e4705601ee50c6919e430d6b039d4d79805614ee1db5ac9f2e5e0efc603a3e9b17fe90b60f11a781038b1eba91949c04bd49e4ac62d60a8fd374d287c649abe7780482399d05147a29113b7fe23bd5d3f9723fcd6adf25d5771480b111e7cdc95e4f538d7d6b66a95fd994256aa795bdd59e7f3d59990a36392c19baa6b0f77280f13c45eb0d73dcf1da213e1883256b7c71a00e8480605c0241f5e8065ce15200203d55bd87f360ad5b640e84aa34120614a0a5e456fa942aadab667848337d5cc9a117f10897d8cff7164300889796776de4267586dc7f647be27308af6aaa74147b31955c9ed5d6d528db089511ee643ee422b8c68ba8daa06c463f175a3639439fea3f1eb5a9422d6da4430b93bc9ccfd78c1868216c745cc6a865a148185d86a13040cf8f4029e99fe8511e69d52d974ced5d8737f24b5410529c3de2ef4221231098eb8fd4f42dc92ab85b027a300803647f805bd1838a707658a76f8955a7300dcd55539970dac5466345b9b697397dfe73dd8a9c33b6ddc8d7c5a0e74c6964fd7bfca9ecf1da92efeae0fc0c31f741c1ee1771a9ffd78f0c66d009e1e0e7260029fad0b242cb3417ddb607f20b204b8b8396f25249e18c6839e4e9a76d36fecbc7f813ade0ac4b68074a615c0c2d47d98bf12b1824e6187dd0a27bef1b0ba43e257624aed64c7ebb66f6539246cde441526fbcea52afa6485049cdb7901db46aabb57e6862af9bc93c51a4e104384a9e8f41c5b49dd40afbdda07daf023f8fd1dcc294bbbb709b8a42dfb07e46a6696e7f6cfcbff343aa54e471e2ebbac8a2144f74fc6b1e3cc56a71f2f34c48193d6c9fdb8d6b1f21c27ca74adfb502a81c0916ac79861090cf068b4a77cc07dafd7b65d18973d3b414b658d644a66ceeb914b1502de40dbc9e8d4fec7f214c11a8bc0c940fb79fb2b3bec90e0bd644d0b0510df7e7c26e759e8e867d657bdddc42a5b3b713154b64b94e0037a05f18e46afc587760a6c5bdd26b50d74253749ca59afbaf37c90bb74a37bf2ea46b37a9b0418f7bdead514d04fef50eb1159b99dc9e881869e071350f4fc21ab915a0da775ae5f61d4c7e2c5b3bd94cd5d39678b511b3c546af275cbf2691c692c7d48fc04ea632842c16549e632d3f907199d84f9caaad40bca46b809f3482870ffbea262fdac543f19d0fb176238dd863018a7a4ba2bb6b025eda03a8561e7b3f54ef0520ab683e32ed13c4e085d00845bc5580747a032c29db7e65d5e65dee425cbfa1a170810b5d1b0bd6b21ec90bb9f60c6b2e1653dc07df8b1205419eb7d174dc09d8b0a76111db1d50996385d3605e85885d6464ce1a0136eab729452b5adebae5addf0e1aa1a8bd61388ebf57a69f3a1d59fd4a2305cef3d814beb1dfc705656c003a0fba8b0ccb9e49e5bc2ce10dd2c0289b9509bc925e431229628ac0f26e2a95f59aaa7e188a2ab64b8a4114a8212c8caa7032220c07f5ea13a4e4870f92f2f35083443bacc68ee1c94b5f9f0ce784b5b2b6673be54a913ef889be364e1e2313464cab6738f7a797714894c3f48a1374212714a6ba2cef2251871ddae1abc1196146178b10a6eeb7fcd5a0186cd9475960133ec2e0e235c485ccf1672f6b4d0c9869979a50bd02574c77e36da2eb2c85cce22f3a4cd6eb00d1191c93b3c1c0af0be5965158e153c873ff8086b5a05a2d06a3a59502a2b98b7f7f12025e72fe85cc511f0396fef2053f9875a4752e429c7a11097edb0c56e0b0cf8eeca88ca796bb13311fc6cdf3a198697e5aabe7192e1f666cc86c08cfdaec702a506d8c46e03ee9f3513c9a8002f3786cb5b4fa83234bf2671c32b65745007c99c02a8827da804deaabc33ff29c39a25aaf6e7ce24510e7c0522cf222ecf793d018e19b4aa639e930b9df07879c1b9891306daf1eacd6b0eb9164df44d6e2e033de5e70173815c310626679f2b20bba7f03d0f1830856d970acc922a04f4147456881ca0116703379429663df745db1ec3c4bf370390bb00a9d8df5317f1f0dbf458629d0ae7ebd3c1632f39fde2ac412eda147d296acbf6f681de73b78c47ccd037090f51511208eb6d026e499af8196f6467ab17c0ede3c3f50b8e01f1d626d49e354c5e4d8ff9ee839061b92079a77b9d6f0372be558dc652c0f9e6a788591f64aa93abb59cbc014459c423250e06835f90e624b73f5f5d1a1e84c37852edb3c26c1f4abd664981f2d5852c9e377039bf01de7918687c8d901eb3a1ce1984db8f968303ee066b6a912c51c046fa7832df2b660ab588bba9737dd33d6c15a9bb5da75246c86520a8a0490148e078ce25f25b674cc05fdd1514ba073408252f414eb4d3c791845aec4424770b5a4513cac9d416a67be8e075b3dc5925ce50d663e6108c4eba29144adc2b08eba0becd5a3d2f5e36683e7aac4f453150863669c5072472bd230db33d06bcbe0e6a8eb602257c4f10cfe03e3f712c238125c587ab72bcab0cba1f21a2ece27431d3eb12c760eeddca04f41bc741179c3f211619fccd0ae50379275b4cbfc4ba6570262bdd8ba3face03a6e65d2fc6bd9c1fc4856a279de8a0c5e2ea58304b7af1b95a5ba6c2098a0debe67315acf99def2bd16adf079cc9532fe3f50be04123445ad2cf72e855eb36ee3ee3af5c958ea6d4436f397bf106727bb8dacaa0a0a044cb31f456a3eaa7e2c96800a3c59b6c3255ee8326545d956c9119c2a0a697168e06acf621abc8f4b81b49d40f25a1df010bbb1c423a37e0425cad5b2012ca5d4e3a0a33809535c4a730221ab583f478be52edc5f740adda94558c02a05cb0b56c88690e729bc549b94abcd6c2c8625ad95f31bcb22ecbcc88543bec00ab75aa7dcb1060bbb0577317bd8cdfd0a967d2654543e5eaa9f33aae3e901b2e4f1a97f7d374918f86ed083bd42c5a4b996d2739b7b038bdb46bcacaaf79bec7578ab39d64ad25f73f65773e859e2256f225d23fd74ee4ba350e12455b79330890dca9b7f42e8415bcf418991255b2df27434257b5f79831b7f2c19d930405c1f06b5e75a503e0e68398b1b0023e21f1923b34a75a1abc787cab4f2f71cef7d63915d4f5603d508159e12379ec711291f68b16399504dd2b1467a97397febe16770c0f2be84e1070bd7fe1e8e1e5ed91ad8d01ff3d9fda9380a4549d1ff03ee8e7199adaa900de48ba7e9716dbc5037dfe3dfcdf8287e58d41ba0b0974b342d201c991870db7aa1025987f13d1684998c2349877e37d0870fe0afc7187a0cfd23a91313c4e80ca78d029708da936e8b639735f06ff3dfa3dd4c0b88b836295347dbfe18db44f88f48083edcb1bf8d9b6e631c8c024199ec4a742276a570b12d7f6d9817a641605708c51d556f44f2410425b799f17c9d0e5598c89c75c86465e1a7c2fa137e45e7eead8a23058afcbe34ae1faa1797524ea3d5ba8cff0d807ddd6186280c5d452a60ba9286dafaac4d5462a6ce0accb9c7f2d9a2dff6f8e655d24213e46593ae40cbf59ba930203b0494d8590ceb027611ec73cb4af2da26f59d3158d51b921011e0513376b951babe06657128980117b3236b8a07e1b6339518c4bcf802621f2935e2541ea1510604ed5568a79db93029ed547322b7f491d814cc97b3dd98e957eb595f210c2a6291a01afd7f7322ca4547445fdbf605986ebdf5c1737dac4e0a070ba15efcddb901c24df73ee1cabaec7fdabbea8dbb7a21962ba70d042eb7eaec4d3d6a4b2c4ee8f17a12b7ae6057ae1d8b7f5bc74eec9501c25193300e1281f59df0099b98d44595c0d89e54c7ca284127fd416fabe89988564e4b669135d83f9ffc5c8b83049e2f0e8bbc813640e5953558df94f3dc627e1da26a1230f6caa37681bf48c951748b61e686c7fe2737a89680c6356ea4ab9fe392bcebd71d6439764467b3cb33758bdb38ed7e5dcd9d5ec9826a81febe0f5160696ee01bd105f2d693e5b3607a3e60b370fc8213065ff51080ab42c1bde746d3be6cf51ff385a9cc6b6a5ebc25eb4f82265ad6debfa04af85cc0433e6bd81dc9b841c618844604312de794c2c35a40b00d44f295f7fefc42d6245c853c9700dfccabaa12921e732e3bdc3316ae6d2288b5229ab0994ae45208d8106fc81be67429b16e51b58c2526a201e87b0c3b592b449df3c577d71f8a04539b6db1bfadd365e8e1ea1f857b310a7269f8ffca013ce0040e0a94402d721d2dcb7144842230d8ae5ba6096a0ef0e385442a06cc3a4fc189cb29ba7c73f01bcbe4578f2220fa8e9d8eaf2b3b30e44bd345fec1f4465cd4174d36df8286691f7de610c68036a1da277f4f4b6f0dbb9af096e28143741fab33a66dd42986d0325d7db58f8f3f1aec37532b5fe98f4f6712b05132edbd7a267ed2b61497fc5326fba562c135c5e3a7cf6e69b5c79d986fdeb5b5cc4dbd2f2feb682ffaf7b3db72c769a910c38a84479df4e6f44c7d965313fdfec9d38de5ab865afc6bc2f54d61391c793408189158dfa73e1326506638c269a3432c8a6a5e419617a7703406c8ecfd28090fa106b6fcd4aa0b694e2fbd71660f3c158f1ed1a71dc6308ce5e20e554460b5b6aa556be16f32fe045605dad9f9284a2bed96c0b38a5d4e3dbfe65669253d5ab09fe7c3f11499a8fa8946ecd4a614920d903daf0240cc858b286627860772bca0fe65cebf983a77b7e30b505f9f441a956f3a6dcdcff57d8185c2a02b625ac154d9a0c6bff61ae24d1e922c4356b5ee11a261034ab120f1c0d57b0e0ff17637de91264cbe05dd5bfba08aa52305499d3d066024c992e30ead93c16a2518dfa4021fb0642e0840e5b278d7b83130246640a831e05218332971a8f3a54f534eb50d421b7d53b055a6bd8278b46dfe7e5815cdeb6246eed85dd5fd7f696b988dd8e956345175dd20d87a952fa740653813bf5d6b61fe75d4f22cf02fe8b6f174f40e3fc6f5bffb2c390a69b8d8d4c2b57eceb9ff0cd485ef96ba1806728d714ecfaea3ae799b20a9005f3097fc71a5a35e225b8ac8732a79ccf701472f36e3f4e4eea47516d88cc64c1392908e19247c44fb364024b8d423a8f38c2fe59c47dfa238253a0e6d79301d9d776320b921936acfba6ca962596d9dd78b0988a802556666f5433b3e2f6eac21af4ca7913798aca6e28fc208aa14527d3073a77d12624deb7b20815ab75e1813c3519c1c5c37520a20b6aca1725d068671cb5ad166759d49905853a92e6c2490f2178feb5e8e7a215abdd4c4bffc239804416b105be934b40e1541934858416ea4cdddfa126f4038608496fe05cc14880c9686f4cd2e5c720282f44893c8b1ce3d65a78dc57b40bdaaaa452873b9cfdf65f872bc031a2c0c70191469a362e29b856639a90f17f131393ffeaed7f7d5e60bc82c8f7b1aee3fb798511eabb05e370cace1a987e43fda50243f5f5e7af26244a28e05f3d530fe25feb942c82d3d846b453a21f02f8003ea688a09eb4cda85f5db4a84b92a203adb2b91fcc1e838beeda0a61bd634bb4d7f3e07d81e70ae5ec0bc7e19f46d14da93fc3aac6270c213b42de1dfcc2214826946a151df09f67e61465d77b315040663a254059eaa2b2f7442217898c44e916ff6930ae8632d576d72680681391edc4aa1070d28a6984ffdb07fae5fe720a84e655682fccca14b3b95fe45e3534d2dfc9a8c33af0f85e9efbeea970d7ea6cd67615b3cbd1ae6fa268b3e944a1b257542308ecb256693482c425a72058f851080a90de600d140c17db9529c5f1ebf25624bcc4fdf21632702463ad80557089eb12bb31f885231372294c6b89be502b9fb67970b0e1342eec0f2e79a978e3ece3da45e3710375d4574a7d37b7ea180012f55c028287d3f196292b8f15cc730148c01b945c159079253081b0469f3f173969d10373e8fa3e1551be375b6c7130257dd0f0c64454faae33038fc283da2728131ddf19092ed4cca205bf64b58efde89a5f2588c80813b57c5eb62935436ab33317d14326d6d1a8ea568fdc2b6ed08ac46ac01a7c6947b5bf12d025d82b0d09a51d51b3706b8029b2db32204e8c14c5419f7277aa22177da15b9548ef6a1a1021c546c0a7ac5a55624793ba578bd21dc25a704f71dfbb7e00f0bd3a4d66f2052810cc522e9e6e2fd1fba9b82b60aee239697fb49c3c5d70552d7f5d19bea8bfabc0fc2b0ddfc9af698f200d9eb9c36c24743ffa456f09b23e9e5ed53aad1d7fd0580d173ec03e6ffc819e846c1b48e11ab6f5affda2359252d08c1d6e85e3b1ad4d54b987a3972609006169090f3a2ecd76e36025e1a63e586f9e7e3ac7056dee318a69c14d43dc3e8d10b3979b0a1ea2d5d295e1158f018553ae51bfdc0dce2773b4b5b40dccc626ecfa4315d5ceff2a04fc9bc5cd17155260dbbfb6aa4d8464d7290cc72a8b6dcbedff33af42ced74343d79ea8b0ccceb708278046f390b0e4de0174542c8b348f49e974dcc7fd668a3b60584681de095c4bb2459a0b4137e64a3c14254d453902b02a538db34632bfe1b01ce2aa901669e666a5a729a3418750525523195c1a880397813006ad911821c16b8a8036775d650b3b4171eeab7e2bb31cab766b05f649c881a2ed1e7c75c14f31b14128c4612a88809e212672cebd6e33722be749fc0802a2327d7cc5754ca6c4ae7da09a891c1f0fe58f9b454bd4e0a51af5e2ecef75f772b497423c4c649c12251070f9ca16cfa0738aa38968f569de57e21d23ca41e19f2575b819719b570ba228fd43bdef991de75303c8ba5293209598e9ff6b0f526ef6fa43060f12746dc9a07c8b2a5280506d2d499218a00488ce0e065ad8863dfed034bec077bfafc3161ae11163f774c9ec139cb2d5645518a76590f1bce60bbdac2d1cc4fda17e58ddb79968b07490841ff343cedf3ac1a30457350b99fdbc68e947c76eb6f11f1a6e0a5b5ae848e1bffe2dd4089d334657116ca14ffe2eb60d124ad10c009a9bb07005b3bf789ff688a22326909cefa80538a43198460683a9e4471b1a53bbd8866e349b387703335543677d9a4a54b02491062ca06643ad4a2f7f24b43dff7cf10b6143ad67cb1b94057efa53d0176317d56de1f6e281d8f69de842ac03dabc5548a7c980f8c8a21f6b3078814fee14aefba6045c5be1901993d17487fc98217755fbb946c6c411329b65a23f1beaa30c486814c43435bb9c359369b3f51b18f1a93f5dda68888037f42830fad7cd6950c6a76caa3eb0aa1553ec0154a844d5500273429f0f5099cf157084e086401591b370bbb965798bbedcf959deb54a07e91ed9a85943f7859369dedd6d94f3d6544386eebbd81189de3d5d7e804ecb2743fc9e2b1f55d390ecbf8923ef407b8891b187cad86a4859bbad945a5bd79d6a2c3dc5ea744dfea26af63501160e57cdb707b757c2b6f7aacad8fa76e36279837d4b118865a31125bf98e4772b2bbb74a397d1cd0ff53edfd81498facdab178efc1abe1d446f8d81074f6ed8e0e4011c36de9f15ea607049fe08e1a3d5e9edc7474ad2407c1d239ff4b0bc3678446e9122070ce4adeac8f87b5959189db3099b04c8eae02728c87591119273e30f7a02d5666093552ff32f35887b66daf533ab82c2988d4c1c6a5beea8a25a66d08982e842b471793713aa60b48e69c0a2a0e8e3d844e287e928afad1e0182897b98cd191355c60525231682082aec10d9edbf30243d076d89a3a9b10b9852f603b6d3bf65bddfc6dc7a9759f11715cca376b9d9d5e6fcc3b32da6b6e8e06ee65eca0102b82ff39f059c6891caab193a428729acd9d4bfc23b7c215c7358ca0f72994cad2a3636f244bd555399c8fc738cd689127fc465ae80fb0c14a23cffe05e490e4b2a671236d64b7f8bff6dc556664665174097238b61ba621725dfd58a6fa1c5b75df1d7ae3a10174c558603399f5c3ae3c0f5bf15a307d5c0cda1fee964db22b8f89768254c97efc8142d324820a856b1a00ab6aa4cea9bf90a75c5fd2f4e896c198a65b3b502722d5f5f333c066deeaf55da4814831026585a4bc27922c3f4b2b3c3ebad9fee018d5c454a7f491b09093edc15283e58d3f1f864030d00374f745f38ddfe4c28dca9943c9f5b9c3c368f8cfefd411a186a12862e4cc28f79b594c44b30f5b3dc42bfda773ee74147176acf1a2b1589a03243cda07a9508a02c9fa7d1b3b9b79c96b5c9f2d3f5ca7f88896a7f1f652eb43708d58a65b5b9db09456f17639dda832f0996f46c15450a8c404dad293f53a5b51b5201d72fd818bb8cd000d4da8c724eedbe4c84fa14f136676a679252d945d2c7e3f3349f7a94f9beea5afb334d341079e415b691620f70f04e0dd33a974800f6a81b68fec66b060fb7b80f2a6be16d0c484d78c2c88a129cb2caa3d7324d82d42a70328bf8262d72271a79dbdca2c1827292b4bf4c19cac9dd90b150d1179c4299c13a65226bf94e2a25cb5e0a44f2739f49c932539721a425806efac7923b20e85931eb52ebe109ff57261b7e026e0ed79eb54fba47504a94089da386ee0975c206cd5335497ded0352ee7b17aabefd6c059277c127397212d0a2619d6a3ac15409bf529a1bd7708ac51218b7ba7a4385c83bef7c2e2c74c0d823e220c930507d243a2b9a5c2bb944ce17ea5a0bac841d96af901769472de5ceb2dcea0230b7cdb19d76207f06815eaf8a6e9cb98ff004b23bd05db6ccebb87bcce47052c18104589be143e2523e7c3231874ab8ebe862ef4aa39405b87d512e4a113588aa315e72a3ca3ff692951a38e7532738c4f7de9f903bcf4b49ec12115caa2bbc765a706b32d9c3a7fda899315ac053a1b9f0882519ae659be9325bcbdcb0a5e8f781b88442d7cf0515fd7350887d2243e28e51352adac496b8d3f80a11d5de5f029b6c847d5929c985d20ba849ec6b29ff50af08b7f8936806281d2142383a45c1193efeb21f025b3581d5c3e2c2a025cb32e862812469bbe785cc8f4c9f5f33e0bf19827380f193fa5b4149fd2cd0c3da989d7130f4090fdb16813f460681c915ddec339f0ba91b75e50556fec47a8f3ff98d20132a371b23747458c783c76b3cbb991d5b0d65124b21711f927a5ad4ec04092a709b53c5057dc5d2996b50ec75a134e08ea11372f79ff577607c973cc4f8ae6a659d700b81d517a2e4c8ae86ae58e270cfd8730007945a36e2a961a9ad62e910a2f49302f72e37b5da2b96509ed24e34108def9699c60d764a048f4b15bd8c6dc5929832bbc255281f0d1b565b3437d8d5f79c38daa64e202f1e2486b6a225d84b6fc8cd10c6a1cfda57615c56b56493c513528e1db1f698336880c37dc6f28f003734293ec044363692ae938aacb95063b6e836df1a150ae99e4b620500ffc6f02d3c2c5ab76eca4e4f5f49be4b62b9d8429f7b119dbbe8f5eaf32378c6c974d08dfc816a3adebea48ef26c87f6a5a31ef4baa4ad2c5711bd842fc4f35b5b6bef928bc034772e29d7d12fd3b3b61cc39288ce02fa2aac3f5384d7795d09e161981bdd706ac5975169f5564fcde8730c8e9e333aac2f6b34c82a265896aa1f0cffa2c3922661c287dc70d38775a6102b0362580cf630bead344a7151c89a78b38b32e14e69e7e9225651d4d5e029c1e3ca3dcf644d57ba33a68bfeaa1a0774624230c57310576a5763e20461afe83d0aa7633b40abe05035e1227f91f23e20b2d2fb35738ee96a9b25cc1f2b4d5fe9e0b721c03c2658362cced80d794c73fe4987831793fe54fd9e8ceec69cc7f42d1ce401f9ff3ffc46a6b4a3def35dde3169f11afe2f511bd129bd3b98cb50a044d759978ccf24a5b2c36735f4a8d1ee949d3a7d2b2e6fa6e04c773cd9a9095188c777ba2faf365212be1a127917c8890e51b967bffb5d795ea2530742b83ebcaef03f0583b5a4b25dacaa5b0ec576bc8c8d130cb625a00fbdb9280863228a6175d163175dc7bfdad5c8e0f0d3bbda73b69623b29362c63783b428f3d7922a5199dde691332522cc5aef067f2f08f5a50081e761c4f2913036f95efd24994adbcbcfcc7b67f2e954c773e824d3d95f8aca04cf5e52bc671387778f56ceb445f671dd88f421e7c434b4977ab40ee5f5608f9b7ea08b23f2d870dc6266c3605194e09a9d6b9501d488008e1395ded04f2c8d0d744e23bfa87052621fedd6fbaaaca5ae1b386dcd2261468c7f76b2c289ea6e72743e3fb43f8019dbdf0b4504878d7b69528f44718ae4cc75d8038a4c2327acdeb3c6a6c59245c59c82f2120b46149093f23a21709d6c33e8c9df6fd25c110e7e4e248f7e96b1f914a6a53c431b0aee78db8ee06874dd6367473594005f6165249a87e8d5393cc1e1ea229a97170b82a5690513ded5b63712d0ce5d205d0024198f17a228d8f22bcec62a047a6fcbda1963d5d21832ed074457f62a30bd8f21aa1aad4284515117ff9607538eb51d51cc531d0fcf88ca9900bd28a07ef11551a114a2e691d76822e62a6c6274c8a57a33513f4f08d815fa6d6c4e69cb8c0fab17a8f8ddfe12c19a92aa13223213437ab2c1a8d60f4445a4017f2939598dd3a66ec29b695e89d79a5856594134095eca45f19823022a4c667b5791d28359c317c523090091f4f931db7c78421370ea8a7db22efe62cf1d571faad191899379ede566f02ca7d0c66215a9af4e8d8eaee682e4107545233283eb5fce62ce0149a554abaaf182ce649a4127df77911efb59e15b5ae5a98f481bb0ef1c99a95952def60ed376b73996903c459aaccae7f91011a30d6f7012136000dab754e0069367732339d2facc095341c57c88862ad0834fe7ac044dadd64adac246ff99569a120d11ade2f87666c8f801278075d0789038a7f70966c77d3e2eca2ddfb93524ba5b7b7fcfe082e6f3d6886b3b42137225509d7239e61520e98c0231562b6c1a48bfaa595b97eae369d9fb867b9d2b518b5ad89d95010aa1603afb5131a64f2c77524ef052659fb2d28398a995494ced22d049a22e76ea742391895acdd52ad57392c0b5295ea0f3188329614e748262de426f468b782a8be5fb653de30e49a986083863d93a004bce83179b28551d2d637f9ac90c28eeb637138b582491f55ebae4caf8fb76fc4614bfa141f62bb84b3e2ebef9aa8cd8b3479500e4b8c90ee94c49e8568d48f70a97f810b3f92a302e475bd530d5287bed51551d208922e93ae7dff3826546786d01ed0187a239ec9b8ad563622c4d849a7e5f74b7e1f2d1d13eecc1f5eab5ec6931d34ae1cf0649b4cf3086e85c48e6af65d3a2c97ce4b90c21c1048dbd9f76d47f3d77303a7d4d4228ed7329207655185cbd133a401dd27d6dd8936dae049bc6fb4a43a661700d94cd8ff9fd2a72a5a1037d5388662543abbf6855c2bcce3ff48a120208fa26491d12899d0c65882f715ee6e93f28bed2679a5aa7559b3ff172a82a96b1282f642d40fe5ed612e91680c93aad62000baf15bde39069cea3150173aef8acdd9c97784c6adcf93b5dfff574021eea110f85e88b446ac170a5293dd211ab2b12ed2aaec3114f309c2b4c13e883d91327ff45e8421ea22af943ddb9c214dc95a94a7624dc40faa378d1ec3c755e25c30329de3398ebe0327ee892ceff16b5adee16afc3806f8b6bd25739f23907521c06e90320bee22d3f754551f31555653323a9220070efa5242b183fb3365a7d8fdfbf8a95a3138cc71673b2432bb2b54ff07c12656c1bc10066a6a0120fd437e91ded602f30e13510dc192d657d4e6244189caeba892edda033d490732f8fd562c1f85dbe9310cd7df7b12cec8c21cdd4c9995de536055cabe1913b4d1d991e154b977a19512cdd7427b68c9d53bb59be4fca63a8b4d4fe9ea2714ca07cebbe733bf3550b1a9f62105ed08e7e1b329fb0a9c4cb7ff26a9470a29cbfb283543aef326aae261555569bc0efac348f9677f67df59455ac5755720b9d611d1b571db4b1086d59b8ca443fd1eda4197616bc8657e180ac710c3d8f21ba56cbecdbdfc4336755fc215f552fd1693e37cced71a8f242d3328456d0ad64f2ced4c33dcb08fe1dfb71fac591a99c151c8fc9017b175a21a04aea05ce380dcf14aab1ecf42e4487a57329b73f176c9b87ec17108fecd0480ede99343ca5caad7826f11d8903cf63b10a1b5c2b917ce04001eee1a7fe8aea78e1c32d0cee443b16e6d785111ea8813960469687e1eddc4d8b979be86295df22e6918045cf3e533e9f93a100ac582e3bab559e8bec866405f9d55369ed8768448232a148336d1253f6d3debffa81da1069eb1de59a8d955f8e00ea8168ea8658c16fd9ed04892e7af2f523cefff25de209e56e9c3b4c448e7e32afb5718778d306a9bcf61e6677aadfd604f15d433a567671d63f43019e94204a550f4b356273e5133f0aa468623bd8944236aab1c5e19c449aeee9c620bd057218a9c6cab1e1bf80d0e8a6ebe48a0eb35204d2e951bb9c752c71acc3259d5567c8f82babdeff387965e59caf39c86c53ef1f400480067edb79b70f388417f09ee989d306f35f8297908629f13459d2094d4c45f252fe6eb9212cb8d77960191d71191c03fdd7aad5d5aa7afa696e89c99d120179732aa8a3e6ac933abfae0606fa0e078f761c1f09f6b0cc64f0f8e167545bb22232e773fd268bf9695837f8ff3fc90e0741b4fa71a50cff68d9e460e851089ca1cf66640038782fd8c80738ec6dc1855f74d0cccabb4d84e5f2af83a98a44f2075759b5c23745d0e33b730cebb73ab9ed8c8c6e0bdeb4996982b13694d66d6bd341074e5b7e56a1466e559807ba23c1a2e2373b6540f3facc01aba690805205a8f11bfc74d4b2701688baabf495d5b87938f0baa45fbac3736f024880386b85009edba18285e07a8b46d7355d246a1bf846934a464a611e3a230512fff853999127e3ef347f88b0c563627502fc3de9b11a4a80e01e14fa6f1673c824eefc0b7d3f1aa1a8549365a63a95ce8bf166b8c8ad282a1d9a5b06f0132059517569a5a8a2f7b534f822c7315536b0a88a930a3137892a6a06c86d2522e013a4eac9832fa08ac24e462417e40a005208eb86b691d58f4c8bc82b1b75fc6d07b48f56854db1fe061ea5617dc1cdf3417179056abf928eef12563a60360d563c9daf969cb9737a525cd4d974592f16594a4375480c2eb41978b41e03fb48a88c0f2daecb9376ef900d4d47a7dbf7d1e3f7e917f889a3b2b4710e595d386b1e1a0680de56021a9487e3f9c613075d839febf48c5c3744ec44fe6552b11a6fd6fc485290145bd831a9497570557013b7067486df6ac1862cdca39fef15d500b7e28c2595923735bcf4e3ab95509bd45e52a4bc3b9ffc38d25d3e27854a3ca8e4e26a4866eed9c6e3604fba0db65a6c91029707e0067163fb52f72abf86deda90c7de18237fd17660ba92fc427806ed598d4a3359729750abf70645f8d3cdc5634d60eb338bc2281bd3710fbccab1247cd3eb7963c9c46820da15cf66e1fd5cefd9ff7f562f4a72aaa15abda7be8dfda8435662052e36ce1d1f4fef6c1111650267f682402ef3f9b97737c5af86db8c0c246ac0fc99c43995eb8cb5b4353079463af2a90b865c2041a111916ce0830b195f0a00874912f3b771f39631836bd29057b5ad4dc71ab517c396cad82e9d31d86a691e82afabab71340dfdab0b2677ae437ce823723902a3015b00edd6639b1d36f669c67934554ed04e7beacdb6372fcccea641ca77779ebebdd308ef4c764ab61f71b27caf467fdcadb2d36bee49f103c4df75571b4257c2cea459c15a2bd52f2c2bd7df629ae20c9ab853f25890be9dae831087d2161291cccc48d6bfd4143d19bad2922a20ac0316f29b277dac55017002327b050ba836131257ab0db76aad90d2a17183901b325c6cab9861d6b593aa447dd3ca07ad9e4658af4c51d782308b1f83e892b04c749ecfae959d68f12150cf309f90e8247eaa7234b68025fa40728422af00ce7d27ae78c646ddb0083eff09f72450b0cafac998427f618cd1715ff8c18ce3205cc47652c2c993568a40345f5eb72779b0004fd86eb2c1764525afe3d44d1e5ef3add97eb3ace00e9347afae4cd5f9511c33f807362e6f855098d3aa38bd3d26128dbd8df44bd80fd95ebc643f328a62e1a2f2421642a0c95a7eac4e85ebc41002fa5cfd2f7b40de7aac2c749dc7b65400625748c463add68c337ea116fe396e13ee1ab6ca65108bc8427dc1ee73983942f75538651245b4b6ec931413bb4c13a6bd514943fd65dbd27171183f6aa2127c8449369d30b6f87c8142f7be3fbcf1ead38ddf0c6157b0df3f852c1172663c8de5823db9b351429a6b176687428203e0315bfde28dec6596b15ed03be9c8b32fa4616dc8424a332aa680f9b53a1502df5ddb13bee822c83ae4fcc2f332e1d3a57fd18a5892b6d5b8639bb5f1813560d19240c3b4810faa1d8bcabeae02916d83b83474920a261d51bb09a8b871359647d173a61cecc81336c525edb5dc713e8d37046da3dc58687a93811c13bc4c0ebaedc5868ae89f85b59da4b02d751af3e7986556a75119e41753d10ba14a1116a127c62bb841a668642b763eaf92c03386436e1be91e3d10e6f83106a446e96a338e2ea698738bf6b8b34349e56c0dbd9d4994f4633ba2962f0cafa978140ad480dd24c8a521004c373f3797faeb90e1e9ca4b3e4b5c470a39ceff250c59248714e0d0d6e8381986fce4c510c3008725e6c1e6b04fa9dfcf572e5f1a120721472dc512c74d2ae082a4942fcb8dca9d6b3ee1764a0f3c4c212a8e30260f3d098575b04fae84a67f97e5fe89ea784a0279fe26f784848a2e4212b492bd6e24bd4cd5c14d0cc2a3616202fadbc1622e94bdd5d7c85f9b88c9a0e8ad273f0591c67ed80e626bb1e9135e137a0a49ecf77ff6cd310973c6500ff9bad5b5787b15e49179987fa88f077fd12e32e9c04cc217b587fbec7ec833d02a131e705868ae52eaa64d83aab95dd497c681b0d2c7e502d371e776cb27038fa7b094286daafbadb96429dea74f4d8e8f8e3df30e72dc6120509f172383d77d235c20373565d566be43eb966f8121fe23cfa3824e1ced9bb1091631be68f79f7a0670446479b462817c02eb3c32172d057557dc3172b12dd868099eebafcea2e6e738d213108a4faa0a7c30d39f5e9552e42477fc0704b9314b14cfdfdbfd6854d00c2d4b08cf33c52caea7c264433c68c41c6e80c51911c70e93f9c6d338f50d19965bbbb6e6a37167c0d70f2669d5d2feb413f7245f90ab387378d8bee0dc4a55fcb5760f235d0687b51b9e2a66cdb9a2b76520dadc3b58b101da6092bdefd940ede63791edcdd93bc71e82ba79c579e631e0760cba65f32417d977cd339660b4ad3698cba07bf385b0235fe192739f05167bc26f23b33cb891db00ab20dda7aae49d8eafb080829705033f324db6eeed74e327b98c736e8d91ee9c98ada6c686ac3e406771b287264a3d0e53095b835c723a4dade439d8e51682676ff8860b94499e1407dc1d523e8640b7751b2a0fd376cc50730cdb65551bd5f64dec28f7179538337346787c68e0ee50a240d563758714b06ec483e2486885d943d65ed65292434b69ad965271caf1f97d62380345602075bc3a41419cfebd0d88a681c4342b9b7753a3634fc19d561ec449598621227c032591e40ca818edcc5dfb3aa86450c4416c3c92a20f48bfd1421a9b208f56ca8cf8e58278c6077a3f10ba37413eb63783aaa089b217e755692f1b0d1e6d7bc4455153b60d3e8bb420968181183967b4b942fe0db86b1de6a7c1ac63dc9c4227a5ce1001950b6bd1c65cc8ad1e67e3d664a06bdbcf820e3b473cb09567a9d6f93bd24be0880165ecfbe206fcc5fa3e2affa5b682337a7c16c377e9c65500a7119f621220c68d46d55e57975a25b5ed45184d7c6e1cd95432db77667cf31cc57f6f2600494c1fe51be80184222db904ed2861a59e36fb1ace1ae02c068250ef9f4e51c2c235fb2f94b3b00f7f1802f962578723dcede3ef035980bccb6d38133c7936b2e3eb49ce18c9f2c0965ea153260e59136ab627c154b84c9403d45cc58e882e1cddc92add480a26ce86b8372848c3ac8aaa2e1c320220b52a8eb08eae20ae68aac994e2a88824a5eb791afe1447d443447c15852a16dac0f102f6ec6cc8832924983f4070cd22551e7ebee86646707b7e3b1d7fb08b816a7f77a68d9e28ff43d3264efe0497057676198446de33f15baecce729ccf3cbc77415a5d64af8d3a0dfac6d0c042ec1c811d7ec4e973049dc6a0eb9e0b04c91ad08fc7e0f4c08df76e33986c8da0c7a97eabb891fd996ff3f02e104b5dbdf9b7831c0326b8c48956b200d8b95ea7fb30d3f345a0447c39a3a5db56a664420fbd6e4896346f4888653f7d72e813cf8174b385feb65679c62f0f95d0fd3f88c4601165cc71f47d43f3b801a4ead5876e08903b2f523ac97733e25e5f5e74b757406165397a0045ee3b3eccf8513ad704a08c732c921aa775c7e36c469d20e97947026abd1778493790367dae22b9d70e04cc6ccb76b5faca3e5d6844e0bc50b7c2c910c53cc872cc5c010874379875a83cf0abfc92e2c4a57b644fa0ab02ee43c7e8cc328c8ef1cdc04bba8a29c0ead76d08963d5d089c0dc31aa4968d634f6dc803b7f7ca42fe10656ecbfef6f7f98faf7024a6d5f5049d3d16a97e23f366243806c58119d2b20188d0a9a209512ecde8fb4d6a1cc3b3c12ea4980a19eb3ccb7b53ad52209856cb5ccf01b73e420ec7e213f24e47bd9198f4509f9548ed496250749f49dad347e4043f6dce0b9735826d4a554fc043be7dd4d722b61aa64c7ecb3fca0eb59da5ebec9664b5c3dc4755d2647e4d41aaa9aebe9753804e38b5028096f964fed9a5c86c68c642a3b04a10df45d79cdc1a4641170e84b07d7067b07efd713c11c3c08bf401cb185ac46b4d4f50d69c5426f180f5ea342d7cc38e214d112c21a5b2affcaab8970480308cd3289c468b83a4f5b8ed822e2c2bdadb072aa5e8e3c1f399ca90d1de3f4cd9a00d474ac42e05295c43e51cf4320db89f78a8a59caef7f688d9a20f42d20065d9a19d3db3c9555da4680ae3562a7e2b612b7d7df47d5e447ba40e166d365a9a4b61cadbf99f16c3b75793b43751df1fd5547fe2fe44ee3824e85a54f30d0fc0f0fbaabd656a87a197625e1724737c18017109960a68f042148cf554615361fb46909140dd9ba5e0165279211b909a8d0eae444f9a099751d0cd60cdfe4b604c26a05850d247587165af630eb2688a9bb0e86a23aa7370408c4fe739bae2f1a63ac329eb81d076a8ea3f57c124d6355b44f35a2875cf390cf4f62a8bd1ddc14b825e4bb18a4fa236a949cd991efbd6651885f9b0caccf96c8e504be8cd53c722ab890870816744bd8ba37b25b59503a92ea64c13b296168c9d25de7104601d726e6559e9eb466d1777e1f79945b63eabf6ea511694d22d915b4313b9fdcb34ad9c2d9d5d450fcccbf82d1431bd991f9dfc05cd95d4fd877473e8b5614859ece1d79584ee30ded1e5676c76802679b69fd6cf9c9413feeeec8fff29c5b3dda9972977bd7c096cfc83ea76475790f04a3de4657ae229b7c225facc13ff83a6599aac01e25a8697d487febba0df9bff4339440462996045cff0245aa5c7d69b0dd04af41d0e238f92be64bfb4624970907077d2029330b864ea99315d9811858d58ab58a404bbf5485161a1612bc47e6a0676e451fbd209cfd024146d456f39139b50cb5f7df726be05da8b039bb246307542316fdea80fd80ceea02d0657ce2028021626f9abe05757bc020cd009a7a764ae70e82a917ad45cd24a193cb048c8d14be9445b63b7dd5f2fc084f309d1bd9b19d093e7b09b5cc927894594ab1a683e0d2ff510e7c414e30036c95d308c5a04f88036606ade109e013e48019612b30097e425c282368b5db048b031f201798095b0193f00be24099410b7002fe0638206686e358edf16bec1afd8d4ee3b7f16df4373a8dddc66ee3dfd869f48dbe46af1adb0dfa763665178128689b75b0dde187220af485a14dd085f09939e78cc17a9c3c7e66ce21635a4e93d39722d798395b0f13e3e7c89d330d967372fa9cb863c6d1324f18be47ee9861b60c13e677e2983246cb71d2fc19b8c6ccd162e6e4287d2e73206724d8f2a17f52f89a38c6ccd1629e18fee1e0486e091b4853770f65f1f97be0ce8c9375aa895121d573ef05cd9e76df3799ba14a82dfc5053b97d38009eacdad67af1c8c53e1d92883a5ffad380b420cbf229f56115f427e85bc3d2c87f7d1f293b507bbccd5667587ee23b807c1d60933f0325954c18f2ef11e725acc54a522370da8206f7435630a88d778e2b60aab653263f866d7211eb82031e018b8231098cdc8962bf5d82a539c7ddaf7494f2972a24d1c04eb3012101a0f3043e2959d42764987ee2f5d1e11afa4ed1dece78d48118c83b8991810f822692371e713fe66b6b2912e3e04a4fadeb90544590d3e7d18581f773e1e56f61641acc0573de12d6af6a0d78a59f4037767d25e33606496cdad5a83d215993fc27270dd6d22ba7927499afe0f3aa77af935be6fa7680965757c7cbc57c42cee0ae6c7833cc01d6b72eaaae5180aa3e852b02c973a85c017094b6d0f05bea797a0247fefa4cc50a5dce370471b0d9f6d465b6d002af78089e6aaba1dd5c56279b79c0357350f8a2eee06d2084140c4b1d805eb670f6d3bc43f1e54d8b391898aae102146e2d10e5e1cea833c895fff409fab2b184d9802e5cee2483544d2aa06975b483180a0f4fcb2928ee5ab0c1c775182f8ba15a882bed8c18f54483fac31f9bfd65d67c7d3c56f49194a88e742f9a92bb641c829a6608558975106ddbb6dda87a00ac68a70d12e5e061d2ee0674031d836b29db95eaf35676312dae63eab2f5d48c9ab1840e06969e395d80ab766927e3475ee314249585a80749d980c51c2e0f1d74d63b9e6835859f47ede59bb2c80814173d427d94d84741945cbb4f7d1a2a3bfd01fa4b512d40e1e36dd8c0c05554378ca76f78865f39458902a6f3071bb5fdbe7cd5f86e2511f5b77b2efe85eff72f5f65ac020091516dd31002f052b539222fa2f84127c6ad675d7b505b1621173952d648942805f969d7e4a3f8bd9cdf338b5f42f5f39a80e50345f3dc5504707b78ba7328379374be3c4344101f7b24e78ca78f6002977546776606c0e46db31b84757f95e10959184830e28ce5ab43250401e3b022f7340dda7db83bbd4d4e81456f6f82d1240da1cb35d077cc185d141b1c7ceb204581407cc6a52c813b618a04c7f806caa8df3d09b04a1d1ba57154867fe95318446e12aafb1b0d77cdc0236af234f7724a65454ab80c144f3775c92cc15006975936124b1c7cd40cd6c4ee3013195452dfa1341cb50228cfae44bd87812e15a0e514f5ca09eaef397dbcb84a35220d686f59b634be8810cc306c03170223c95054b99b8f33c1b14b20233cb3df430a868cb390c1ec34d3644fbd6bdfaa555697d7cb5cb24726dee2f5ada3c4da530ee15a693ed31aea1bf3a5e937adcfb1d68ee301ef9e76773c0674bad3d45a00adafc360214523581fecdf8464a40481cb22d541abd2e40b8ef0c6b2c64f2bd60ac3953522a148321ec7ff786a5cbdda9b39a791e09dce1fdcefbc08bd787c5aaaa79ca9602cd6e0f78b959163bef69198ac99e8cd7f9a8db0ac46df5df67960829408e2fd72ab370d786214cd223374d57cddaa898df01f7dcab64767004b9bc907a697cf090f10447c46b41506910d18ba78b4920dc3924dceff96b412bf23688150348a0d51cffd1d413b1aca1f142394e3afcb46b02a8682fdc88b15ac753d5b6f2163a9e5b1c492861478723700fab7aef7f9c3c7859627491a888feef4943067df6c42040a9ba8c93acdbde4bd03921b6278d39fa69e13dad6ecba0b7464c6b70ec34b93451b05f4c4600098e8b600b4681109a2c7340ebed12e62b301a936349fb7dbf7b0e4e7cd1ba284a71797a4dec830c731b37cb65adfc25e8fe8b27221b9debbc7084b026a1d9f53b0cdfa5fbc066d5d2d97311b27c8ae715085a4cd42080cee17c742163be37a9c00495978f9124df0075a2d8d77b3b575c96568a64a454c20c733bdaa3108d771c809e8d4a577d566f6e071f2e68ce086978f01af5eb88f80c990bd1154f98c607d6944bf6ca5984a8f4298491569d55942a62734836f07b17303723ceb98880cd87f3e0a82094cab9e73f7973ce217cff33510839860ea318856af9d58f16ad101c2a22d722e456f77c5b5dd27c5e22230a384496832e095297502587130b11645065f821443d336a74f310b4add2b779c18afe515f513abb14f1aef373d4f20532f612bce97183c56da0fddb77ece6313092d8fa1fc45bed5fdef6f0dd3b68b82024aaf760625dcff38a9a49c8c74d0cf8e1e574ec4e614a12a01905863b599398275b16f12e3d997c5049550196a893bb4a2ec5f5b6eff2bdea83b986d1e7a94145cc256979b5f956bcd9767498fa281c368248c8ec512a762d76aaef4ce388c4527d7c7b7fef2f5ca4de219be1f66189ec17409a0818efec1e3b1dd77c15a05bc63d0031041439487a46bd48e9d05a352734f3ba923d262d0af8a69ba2b4c1cc58055932742516311aba55c8b8196837e8622e1fabcf89002496e234019ed7deb3440a910209f8917e2ed152aaa86ed67618de87795fbfa3cc32e15aef20c1c46cd599cff0b030dabd2daef1df37ad186a75e2ce2addce2ae876876c3c0b823b30515f434243ce88baa3b9b881a669ab4a75630a774227a03a866ecd04f178be1122d2e99b5e00d5e0d343620347ad070e341209ea49d52914ce47111c809b802aacb43b88bfbb9a568211df44629f642ab2401623ba348d3ca60ed8e619005e1b9290b08e04b2ac7213aa7440a30e903847d6eecd39f7580eda3ee9dce0ec220c05fb2c51dd34725acc8ce054226c6426e942f7f53f24efc8b1a4605fb4e6b86cb4d6adcaa8bf53a68512b1814773b77557d8f6f32caa4370198910a00f99e9382967342e214d981edbdd03d83b91513fdf576152a2e7e70500c63f1ee95962dfded85fa3047526fd03398c5abcf3a3e1f02dcee7dd60d1d2d0884dd6631de69037414374dc5667e1180790e46449e10b637610e78e4600cfcfd6c7e1207300b0e1dd01c7a1923269269c866f8b6f075f3d5ac56904516f9ee9c5937a2002e66a0ff7c9c4c18bc9950c9a489974581e781d2779628435592d6f4b6b998259e910b67df459514a19f9445601155232449e94d723a6f9b92ab9d6727430c99c6282bc79944a43f2aa476efabe79332e9baff489d26676a4ef05f07964008361b60cfb10114efd31a910886d93d72ec3605762f722b55f26eb894e91db206d060ee4ea8e9238b974c465cea1c14a6fb06543629ee1165a34ce39bb1ebb617e96d80219105c3d35e3ddd246e2357a1c893e4f660cea2398632d567c28883d2e87d99baba04af7bf04542c24b2058ce767cc05232b48ab9d61eece5868b05533401dc2ec8bd7682de66ab711e89848bad04f56732803b2c3fd76080f299e7224e05b0a9fad8fc250c608b29be452ed8d8b6306556acf9f389a1270836a04413609a1d1ab6e1dd5d9d235057235390fad6faf8e21fa6fa9fabaff3fe86ae8e16ede74fbbaa32f73ad664d9c495ac98eea0e279ae266b9be1be102fd47c6f91570a91938ee7d3b926e76de3f3d7ac2ace80d4cb2d12a735769c2113368f28b44ffce9649faedaa6b98b7469a2fd3b5664608d66d6154ce85e4330bbcf3abf9d513c40d3d9da9801482019abb7fcef4e749ca616b0978a982d3e9c866bc8dd77f93f510422bbf4a5d47502761436d0d6e951822e396c3ea2f8e02b8c2b14d00bbae9f9cfb97c9d4492166458be0e3ca2e31a663b048bafc4cab50015039f67ffc3ebab48fd1ad68fc7106b4f36dd6f69e6b75264fc11c5b0c791de3ce77f9ba2b7239feaf4a87f7afc0bcced94842ff29d82192cf7daf49dcb93c2028b56ca886177fd293591807e18384558ddb900316b04ec3d623754250071fb8b6af2a4d87d18fedfdffb807cd408cc80f380030762e57a05d375b465a73f5fc798c68f54b4e809a4cc519618f7af1a468e126ba73d1a07906addcbfac2296f0d03de079189249d13c7377b9968a38ee2e0a2f6413a0c8df57327b2ba920f7595cafdb8fa79b58ec9a0ab4f5604d95ad1f697ff02e33c5f76e615fe588546fe0645ba6d1af5b6ca803184912f778b0db503c8e9b44ab8f98089b7294ef0ac01a60a4f1187a34fe4262909f561fde3d3ed1e6a5283c15b9964b198444d106e50998092d80a547d492e12f41a0c023fdc80ee111c946dc629081a3cda10a3b1e85c424ad107a4f6dcb99cd9811e6b225721990f41add00ea8b35b85387e09132f7e05e3a0ac49c9362a2a56b63d10f7c511b4c20250e9cde6d876114608e5d05eef5fef43caa203487dc81f6b805f97c80a0569e57b159e399600614a1ecb84c013930e49a7f4a9294f5c0b51e682cdb43676ce46f299b344ff2a8ec0b8dea68df35a3b10d5a5498a561a9f73f8679c7ad9fbf213321144d11ce971fdb9001581a8274a7003bb88259a7079903779b33dfc77dd5e2c4e247448261498158c4a6e2cb858a29cffdf2449b5f66584447d9a0381680f490accacac57bcf6c0ea0815357ef47bf7427a59d0de069675a8c7772d4ca9b6f6489b1efec5849c33ab7fc125cb50656e7ebecf740ba9ce542581c42a27bb853517d283e0160e445096a44577905f4b75056f4f86ee24e71e7a26fcd67309053f7a27cfd25d5e25cb7e152b2593e52db08390b96e867ab683cb6bdd64de1fe0f3d226486d5260e21c98a3c1fdecc460aa4589c9c7e2fe5c773c307d0a126c0ac11a4eb59e36214f7d9cf588b5da94fb963e3ac5e1690bfb9e794fa207e2a37bb1c92da3e0c611e02c73c9800c8abb6e3e96e9914e449d4ef6a1f531cb9c04b8bb0254dc6b99b33726e85d243dbe6afe96bddbb7364db8f90ddc2c55c56b7a8787cec8f99c2fb3016637cce6cd02d4c8edc45dab90e92470757516ab626ba967a81fd753c543e85630b70d7af61653abef4c880877201e7686d60c24773bc15c9a8fd5b4a2539bf3570ed1794069d31a044eaf39408a99bed0502aa6de4356809527399936eb60edc68b1be4921f5bbbd45c5ed17540886310de573e9024bcd290724386bf95602391dbf5c2a3b3c232d9d38a67422c80dd2a46f04b2baacd4b89c52986a90a5bb3a5e41740331f57e28f4acf81b60769c1e4302319c427dd1856f10704a8457ea09a50d7dad41ea1b7cbfbd428f3c7c2baffe07804800bcf8aa33785bcc42c8c910bb16217f466c237eeb8c9650d606240dd641329c2c4a641807a5cf4af5c070b261e4e3b3db17af687e2f946db01cef665837df1cb5ae982815b0e072ccc5eb6ea4820a553460be7344177a439c41d4eff30d84d8c69b360cf1dcc3c571b4b37b685ad6af7e7f30a7cdd4bedbac884bbd3b2d6eb4dc4d68779abbd387eba064596bba0c1765171b336d0e6c69a4be90223d0bb6f287b517b76b7e1ab65690b6e9cb6c2a71722ee3be095a78b3d4187e205c97e13b2f9212549ad7ff06a72ff5d0c7755feefe737097489ec6006b38a3414c8a8993f9f10bf5a5a0e9904edfc24584a06992e6de2c6738370cce0ee463df57aa4b77a59aff5ac9ed54fe137e5c6bd996ee8e6546481d5baf16fce1b74e3bdb6f7ee656f0aba21de6b1c017d88b85367f14f656a5b0bffda996dd180b98fd1d16854290a47847a04939bc1f9f6081828da7351104faf120eb2338274de14f873d7a7a969857b31957f1e323c82184b50b6abafc0b446889e2712db8579f42dbc752eec51e7a1bec5de6a4b7a27f678dceb3128d7b4a897e49e75b84352cf4e3d9374aba3be893def7c9f20fddde25ec7a05edd92f6b385b3eee562c585c2df2cdf2f41fed0d2abe7c2e2fab2e297e15907cbc50aa3f4e3d27d89c21f593eae1bf0acf657c5ab7a710dc14a736771e5cdaf90c060a5ce37dc5c518c66dec5952957538a577ba599cfd2cc4bb43206654af16aacd442b19a798b2bb9a8a614efed95373ea3999768259a942dc5bbb1727b60cd0e45375756db89b7f24a54fcbff2e8e8028d9f433f905edb8b0363fd5fffb90dddfe47466656dcf036f171a95ec15a377913e0e325eb8a5517b4dfeb54330b3c9e039aa3aa855b3052aa9a74ea14ae59b46ba470d6de23dbb6e9045638eb56919daa4b16edde55cadd2669b5a2c429a0621a8c1a841fc2100400529608e28a8c5c5e1ea20781e27fafd7eef55e12c6bc4fe8b1caae37b3b6d612a2d636217b6fb977e508e4071a08d3d5c93063a6f70428304134ade323c3ab90c4aa726154ac90fd26ee31c4ca02051e68c07c56a746a353a650a1d2f05a5792fd581347f922b613726c3134193e653493647590c28e0c9f2309f6abadec35b9d845c49f179b712d57aab7c34b21c37755ccc8d0c464f8ed03351226c3a334f003a10e0a199e7b7951c67824938ee24ffc9155bef803039213421d9ce10f6764bf0afbf1726e86af49d8afaa60049d3c8112447342863745f9a123c3bbd6b0e172d4ab65b75981ab11486402f6e8d33bd12cdbddc0cad938f1c795e1332e70b82a71e28fd59125fe1870f3848f8ee943391ec77aa932f48c92c68606f6822a00e00a226fb644596baae596ba6a3031352bc4d4acd082878367430cac5981082d980183e3f52b9b34934930482f47469c0d334a22986143110e36dc60030c830866942237ff2cacd79ea4b36389b2560abb59aa5a666a1f1d4c6c73de4c2980f6726d75777777b79431a3b3bb71f79d73c6ee8ec51e514a306c7c3f4208514db8bdadd37bbc72856d430c55518ecfa109413e44987ca802473ccaf111c9a7a5813a56ee5e72779883dcbdeb7e1022773f80e1451047b0c1858f4f8cdb5879dba8e46dbb0d236f3ea4206f3e4d70d00417b090b5c336d0c828ed912965824fa64cb041a66d84e00a0ebc9a1fb478811442190abde4243cc9f2564a964b4862038d2ce5490a1940b104a38d04d5b26125890c18174c36583093e784a922724ae8000e9450865d2204f2473a401cea92e59328813ab03f293e225ff211952f0db046fe88c421007cc93560f2d540470d24a5b5ad96ecb70e2c0cac819747f2104e2c7b0b14d8efc740a687e99b4803b38940e4696d8f1e666eb6daa3ad4ce7040206eac82f85dcba17038170b1c7bc95f1e6c09a590f03759460a58c929bff4e799e7042ab65ed5773e2ec0e869929868135b1f4ec26f172b64d579c2c5cd77ca90d3b7f8900b9d820cc566126550b2c0e7d13719ba065467b1ece0c4f3ce95c99613fd86bb5b6d592b03c3529365894bf24b0cab550a7b521ad8a7603ad8a5625571f6d48aba255f1628311484720df92675865fed9dbfb0f8349b0b6d24674a8854025a5437428d3a436a24374482bc106fb86cea6d995f436195ac928d7734a49a59452ca7e46339a6536349b369d4d2af31349da858c8c12d205ec66dfd992ba9c4497a3f6baeb4f292b97cd3eec322a3749adc8ee6e39a7fcbc72ba9e645795bcd3f2ba1c7541a6eb8926a59cb3bd98156d104688124883d50f5e6dfd633769ab924e94ecd47c581626d8278cd504ec8985524694230e803a992764e8c29ae8cd63aa0242424242a236dc0013e20398902a3f5202a56f909090909022ac616541ac0c3c071c5720f08aa214a1a13caf0cb1c168a9a252b56aba9d97e23830fd8a515830b231a2318ab245571e08a2427a91e50d07884068769a8e3d22cd545f1401348f4304d234d3b2c841ab2a14d4920cbc52d5aa66da81fda051a402eacca01ca240b1816ed92dbb65b76c198dae1a72c2e0c0e0ab6f61366258179113904498bf885d432ebd7bde943833d6dd46466b7777d3ae5bb7d464679dcdaa6514d367df289d31993541d5ea49fcd25efc8095313c0476ce395bad5ae984dddcc056fbe6dd314653de24d7a5bc4d4e526ec21a9ae54de3b2ca69336f25aecabc99b8d2c699386eeb60e84f53a96ea7086be067d10661a6076b20aedac4301bcdfe699aa6497a654728259bb3c8890decc0892644232072e287a8893432972191134300b52a154750031809694058102106900d8608030968074700418a15238080046486116140e9170c324018525a5fb4b42108815404243c1a08f10321bc60d2da322412628bb90358cb22592003322db0801416f0895181dd32240a228d9717b6cb902888a3208c0e932bb89665190f8ca094d23190fa05c748aa3efd823ffd82325158ae06444dc0c0082b55e4cb5b020bae341124234413506cab89272e2840c05a9adc618433a0384a810704bbca70e88c19c83439a307af32ce08e3c76e190e9d518433d238425249ea17f4f9017232001b3ca12f1f9200449524606087164970923d20609905329a65b406233489126589295714418a200769e4e00a1499cd3ab0840c5c800552e4600b1870f144e3828b2856605944404de45386444045e4cf7e8600a21184d08f1292f82162090330f1092288688827800c1044510928853434308411c4f8c072190ea521254a1a53764c61b30c87d2c8c11a6914e5c0b41ae3bd980426d7971a6918e1215c202221a55f5068a84a919101c038a23979280d339a20c1450f9080381a52034a9e191201c144fe9e63d6c46b85268d6a9a0788d08630541a011199107caa0a8aa05682b42b8698568a321a1021855045be604dd2c18f5012183f0308824f52108418c0109eb4981cb1321c4ae3072220903a0ed4564ece6896d11d32b02c19121921450b234600c508275e51ac29432223909899c2d60c898c18228527b6942191113e438a48aa7d038980e0402bc321352c906986444c9068b083ec8b21542a08c328096900d10408d90b8260d37082524a29f5a10645449c0f42d0807641240411911055e45586444240c9c0061be76bd958637422e67863582d43a21f1f3c614b39466984221aa29f2d887e84b2cd90e82708099d26c020065460618231b6b002762101318020c6154a88220650aae813642ea0598d28d410418449b135c321353a60a5e529cc73d639e9a42d3bc3f0cacf4b7b764398bb7be291a452ca86f204310a6a6db568b4c9df12aa840f980fa9048da22961e3db4a53ebc369b610c6186b8510c28cd65a82b07ea74bf7eb2157ac69a734f6a8a7771a654a9f4d082b841aaeb7f488187494db89510c3a3a12231e5589c10e9c32d4ca964a14231e9dec91ccc596b5167f47e8e930ebd262eded6157e4845b495aadc3c0e9dd5bdd3bddfe74b256d5a24552743b9db6abeec7ad4edf4eaadbedf6ba52e75028570a0f3992ed37fc1dc991db56aa956d657bc2495a79d5b276b3276b397bb2f69e77ef301175d90531ad5e254e8bea36a53aac3dfad445fd645d4e27a96ab5be242d7b249fbe42a14ef4747a94cac4fae9aeceba4356ad2399a6ae32e1242d4a8f504a69abd59242c3913c7f4f4669e960043a20410ebe324116ade4562283f84bc2e5c943f6194f5e6997b48361e2af475e6d6e938bf2ae3e6f5744c5624d6b97b4ecbcfac7d2e4ed3798b5c7169c211e8b1aebdca7655d6a3bcad5e567afaaf638777ade263a224a86441e18ca5ff421f2405046d939ef1019a1c6d98b8a1135c48b11e3af872c53af29db4b7872fd112526539b5a08cc8d75e0c94b622e9d967209efe4d4c07ef028d325ddf23e7d9276a1e5f44794f0b0b9b0d8b05fcd137a347449cb9123fb459fe8d2e28297b476a54a9c167c8408fb4558e4431bdb108158ad830748d954aaa1d6fa392b2cbd5edbd0b0255c85fd603089e3daaee5489caae10a68e7b473d8b51d265fa68a2319b0c6749369337da7ab15ebe1b767fae5c242261cd668d8e9d4116ce9dbe72b761160bedeb56123f334ccbb4c97788a02c0189379790ee7c897e93058637a16b604435ac24876d305c2f4cd74984dcf3293e9f14a1384d2643242c34ddba0098394601f83ba54a511cf8305b5621739d6b05f0705b9b8b05f0cb22252d12e98b029c3a69214b2aec0d22089bf28f412d4d2500029cd32186986a70eb209547b2624871cd8c6a15a39270b8311c2881f10a3917cc9d2e3c53da55f42edc94fb902cba47fe44b66b87ddab30200f892bf425a6e47ca1848338c0e2437f87a81a82fc5580f733d84b53edeac529afd19968f6cd8cf47218993235ff252ca8db2b0618d5a48ee0c657767a8a83d9823cb1af68b463627e7cb89460be897bcec97b4f25808b6d7b0972b38326219adc07eb625676715daa8264cc861613f2e77e9f51c9c0a308a9beab36f56577d536587dc94df917d6b3abdda7b755557a6306c0f6733645f222f12ed11ef40b3499b37562b1c93a53a0baa57f2f3f26ed9252b6a3ad4bcc34b86404fd62e85c0ace1782a6fbab2934175d3a5c49bfdbc29752d85e54d513b2755df698be52546a2ba09236149bc446615ebf5dd11c95818ce4b16d4ea73b58a744523356997a7ab29f134e16fd219e349c618a3f693fcbc277b59f1d7d3b7f6a68baacd5a5d1586556ada94f3b0a39485e55feaf5a6b7ee57b36bda670c167f3d64fb1bf47e4a3255f19055acc3c669b1f0973afdeaadab24abf08704667b61961d0c31b3e01d2646328964d7aeb14e57afa7f67e3c6493bce9daab6eaa3e753b6b37c99bba260cafd99fbe25d2528c7a4569d9e3915ccfdd8f875c67d681874c7db2e9d9e9ac37ddd2dd81568c645ec21bbd7a02deb8c2de6897da391b141081c01ca3ea281c2916d1135572e9b36bd7ab7a765195e5d46ae138b1a42a4b6618c95ccd194a574d24594eaedf2267fa2667e3c0588643eb829c2e0fbb19703cdedc48bd85e5b55e53ffc63c0ed527fe9278a8cf241eea15856754c9d093f56c62d7eaf328d5b3ba425d7595eaa2eab74e6567611b346c868ba48ec2486ebc9378291c6f1029ddc02d38585866df49eb1b3559e6e3a90b72fa9ca8393f3360513f1d09d667f774d6955d90d33728a5f4b2d56a7559575d5befa26ae16869c1d1ab54b7565917ee7476d865a5a350cf6cc8cdc27acbadc471b93cb1d81676d9e17ea96f6f8c2423523a0a6543669d85bf245e5f55cd70afaeaa73bd5f0a73a89f90d4a3bad6faac7ad945827ae7c6daed4e579851f7f452a705d990b598a9e6d26737a41a3520a7744bae971cf339ee4b75f984e4093d221460828a10a0e4d96f400e8e6ef96122216501e3d1e4c05e2cab8f40caf4ce6d6b1df6e7e4e453a491461a69a43021763ba158261c2d2d2d1c374c2cac154a754ae570ddd01423aba5595690f59de6b8b3dc387545b673f61c8d34d24823a5f6f4598e7e3b6d1cc77d5ea69c7d8a3e753f2179bbbd9f907cb2dc763f7a14b641c352ccb19c4b92f3519c2427af72b8961ba7e75a386e64f6593764ce701a2267e04ef614638ca79310976ef58d863de72454876c9556d1234eddbea45870b4b80ea5cb057fb505e3b8815930cbf330ea2f3939a7d3e92424c7c60606a3a1f13c1898974c5329fcb5562f2f17b645a55eae4afd2585ba769b3a9d8464d555f84b92934f9fa7f77e51084d5d6b734e54488ea739a79c534ea6393d14010911410e0c511221c892e505dd7769d71064e8eeb6e96e9a39a5940d9bedcdf92d838778d2b477f9c93cbbbba59415ce43082184b0b1b0f15edf05c3cc9d638edddd52ca150864a073ce49e3e1acad496e42fc13b249a79c3383c910692279341952da40e69473ce09e19c734ee9cd39672c452a71b43e73ce6932ad86a8539bb46693d60c0b4d8cacd6ac0d3a6bd6c69c342b514a33adce4cab6d64339b5ae50e4b39d59229a514cf9969b50d9ad579941dd92c7bbc966571ceda4696c11e95873933b9711c47b336b6d66446a306bd5a67d775259ab55192198d1995117758946a7d9c8f5aa4996cc3e462b29964367358b0df4c6c3dda68464a6fd9c41efdee121482d58ce4c4d2cc5a3768d846ce49b312a534d36a96d1c09bec309842f7ade3b49c1cac65da2cc5eea62cd8a314a7a6695d106d562a618fd852cbb21964ce88c879ad0b5232c98de3b8ada78cad96a6698f734ec945d3a4997c74c969c51efdd3a90b92fd3425ee6460e3b78823ac291d962e21ac29cd5caa9ac45940df007bf47510d0b2a1c8b4997c5c6c6cd94b86bff0a646afff132b371b6736246a398116db0c7e3a289c0c32ece0940c5b9e6d6db0f863b9521619ce3bb3ec5ad66d935ca9656545412c323c4b140875e0155d90599a32058532540520c3774d562e4c6929b2df64e9b490210bbc01c4494b0cfb554d27c7aaed08800c9fc30cfbd5b354605d707060c07593e1cb0a554c3fc86153e558c0bef999f4c7cca6f853653287f98e0bbb212fece1af872cf3ff5b22730a7fcc85d94b017f3d5906c73ce6dec3dc2f49fe51b81f0ff99f401267c624fe4e6f18dfcb7b7859f2c539173604fb4da01374c49e03c809bdaec7ae4b629a14a357fad52f2161a7933b86cdfe4da01a76dec265574300ee32e2c2f333e6891828238a50cc85f7c476e4cb85b9850b63aedb933f28d4ba9f975db838e251cb40c3e2a359dd8fa5fab4271348ca513cfab8fcc5a389c50368fe68527f60ca03a894dffa7ad2480b6d5c402816007c172e8cb57061acb5b0df4b3e19a2d003d703a45f58e2b90f757ae4fcfd55582925cc95dc3832347d03899c90c102bcf92a111368e43e0b5e041998729321511257f2869af09008102726c199675c02c4c185fd9a8ceda6331d8d3c3d2aed75dffee263589c21911256e4cdf428c4952ec5e50a4bcf4deed18af6e6e9277b6dd0b0d9b9974ea58e08fd40760de17014eac9aaabcd60061f108aad2e8cd13c69c8d917d608eaf4c82854de2e045ff35ba954aa37a7944da1de57ec65b5e74a61183aa7acf4913f4aacf0a489932c63f3a97b031068dc1b7ca4dc1b7cac189aae2954faa6bbe89b2c0bdbbdd59948891f64d8d1c0e43a3460fbaa734176dee83edf4e248eca9a7092770343c982f1178b2e5ff47da13cb5d0679b08590e91e74e9f2ebbec27eec6a1f66646e9bbcacc0a2091124ff2cc3f4646454748502091123e793e5e699c199b2c325857a816167633c8dc425c5724fa904df1ca7663924b8cafbf7081f5fa2f096c521c457fd13730cf2efa665af1a34a1256a41c8a55da9b309b88058c859cf626dea13312fbeef371a86fece72395be41f53773f7ee1bdc9a333d93c25dee54a8bd69cf5dfb93b53826a16ebcd2836c833a3023319dfbec21cfdce1ac339dbe9ba1c3a58b8496cec52f2ea1444edd3324f45c9472b3675be4b8c89db647a510d93e01a3bc3d0bb97604b0c66422c385c0a13cdfa44a864419a0424786444d8272ed23230b54f90132f1404a224a1bcdd9423e453f5434d013560bf58d8b0623edcd33c9f3f0eb22f2bc227f2ff98b4938cc17cd204b398b57fac5a47f7a3b71d95dd4549a79bead50c9f33d7718f9f8f8f8008990b022e94a9e9ffcc9f3891a59e44f2a416f2a6531a96fbe5894e75d70664279beae31b90d76a54b848abec97a32ddaced8264575dd9d1771d91e893296e9f7825265161a54fdf449f3c332b4d46dfc8f94eea9b2c0679beaf40ae0b925123f8ea8250a23272868d1660cac1a8e298c48124141fa9c2da2e86ce3ac4256425b0665e754b5ff0f0d0de844935f47970a804c10ba1580f2a2d84388a4d91447b16a970451f1f2aa21441e30fa7ba5b1a484231d8d1eff4eac258a4a26f287629311b294f3aa393f6e6a3933cfb531e8711c2f089b5d1eb0914d4c9269d51e66b03e3d1c06ce8945067c6676159edc5576d6641676c1b9d53ceee081f4307598cd0dded75c37477b794db0fdb766d64f2e7f23e578d5b6c9b9492b694b3bb2184d0e64e09d31ebc9452ce9b29e74d7777378b1933c6d8ddd9c60454d671db35a5a8a9b4954cdbc695b614544d2ab1a026163060177a3108c8b22cbb1a8dc0d4b030418ffef480d2cd4c3b64f938e98dd09b593725b69c34d36ac984ca3a6ecbc1d40d39caa6a8a9b4954cdbc699784add90996ab5d412947153c1958eb449b5504a0f4367162fa66cd8700ef98a93cd9291c5524bd544e965e9565abb212518fb5431a52c5a76ba32bdeede012b7f704a6b0651b4a1812a489841132bb17eeddb1f7253a2223090e5a7a4d99338ad28899092270df294b80cfbb5e2df3712a7c2e25b0bdb928d484404144ae1b4b48b4c7f8fa8064e64d99c19064174812c88886022cf4b0ba02053fa6eb528a5525079decce844885ad9204c865289f8eef21b0a36b0dde3eb86c21636c3b300e35ea49cf234f9949d7e3a9d8ef4cd119a4ef58f85b3faaabbb0bdee50da0c7f47724881adffea4dff2250ed2b9111488c3f59266529e31131b4296fb0a87d72761c72b0a1872f720f4639fb7a28ca59b7d3ed451fedddd50195d39d7d3be12fbba6e57acd27d767328ad4eb5d40e3a4b425fd2acd9c83c499b1aaa484848d4eee18361e0730723f8d1f2107e1d45bd256354dabb5d67af85a6bad75d62adf46d0d7d80a81e54037c9357badf3d5f45a7acd6a56b39a55ad6ab5e5663a91984b47b0116eb29eca6aba34d55a6bbdec82546bbaa9be845bedd563262c4ccdc0d0b22c05b046fb27a59c00f6d00e1b6a34b0466b6523ed69dfe917d92f067511500766ed3d05d499d71ead0415c52fa25133c9da95aca19135326ab536d33ad6ab430c30974e24e61aa98841b046bbe90856e62f0611a9efbeae7e4fee21f55ddf93af4bf3b2a6bd6a1046c3483a886eb141984f46d3112c15ed49813a11eab4f27c4ba9711e28fe54b15f0775901179be89140ee4393b0479ce22604d0e1bd8f8af6310ac99e768e267add606750e1227fecc39e747137fe6eb5733fc593a23eea22b869d8f41918ac681735a213527991af66bb5e47560fb72f6105bced6b8cb69ca696fe65285cdcc46515f7e1ac9043ca49f33c2181ff19c734a29613361d30eafd596f059649b854b1a47083d7d292332893fdae96dc0a16ff2b6c939bb66edb65cd23b3932c86e4913994c91357cdf896ac27e1d254e429327a641c80de050922349bcf6280d0f4f90c6dfe4c951f69671a5ef745f54910cc7d64aaf9f37498b7cf759fa2cdadd8dbf1b3fd21569ccca6296eab3342e229f1599d73eb34f9361f5794de2c8c5db1fcf0ca8f75177a1f010ab952c863cb95fe5b56f99bc0adba061255ed2a60c23493deb159e384bb57cd62d9bd5b1e3e4ba23ab2fb9ee2c4efcc943daada4edbb7fa4af927e92f6e83b3db26b181b84b19fcc9f39334a5bbe4f46c8cb1b833cfdb431c3fe30899bd5b2b5c4818e4a803929aab0cedbb9ca93ce3927b637d0c70b0ff207f3923f1a14963841a66f7d8c4c899cb8608923583c60bf7a030d00654a89342094e9bb05b1408a52831f2b404145d91414f06056cbe5d01c019b1865589eb9c670c6457c10d30ea14f64d84e296c1499cfcf1623955fcd0da5644d395bc258fb2666b03dd93489ad5619bbb9da77e609a314aadf44ba34e37433510961686c5e28945f6cf4924a29a59cb2b1946163d19523c8404198ad8b36f1944a7db04e75ab92f1b46948d8fa79170cac2aa652e7696197a7700bf3a45218d2ae95da5c6e4fac757b622e41628ed7aab575f26a0efc822d8cb52e8c9d7e52dd0f16a9345cbd7e49a011068a98f205ebdc65bdf6cde95bbc2c1dfe7aa06caad4bd9cfa25cedf72ed0ac75d375c5c386e6017015a7f790d2ecf812bd07297bfe00a4c61a4e52eaf80ebade85dbe4e77b956be4e6fb956be526fddd6679363927853a943a39cc22cf5f67eb08b7c8268a4bed35beaaa3ebb20aa14fe6656d9afaeebf4d5a395eb3adde52f6f5dd7e9ade7b8ebba4e775dc75baeeb8461e051866df9098f462f9f393e1fab481c1d9fad4f97d5a7eab3e5fafc093a72bcdc54aae59eee725bf7e3c9dde95d27bb225a0ad7f6ba4fd995ce42dde20f1a65fb6d83028bf2e9f5d6bbbc27d6faea56e2b854980626aeb7bc75971b69a9cee3c2aeee3d312117ccd3825ddd7c4f2c5691afd9c29607106c8ebffc84f3205ff3e799c288cb5d7739cf144674bc75285f2d98670a232d3f01f3b4dc8579a630e27a0be639825d304f118f10f99ad7818f84fec12328a70bb6f2650f632d2acde578e9c9b09c041659d4d5eae95b6cb53cde8a0c893cf0247f3143220f00e59e58cbbcebb6bcf59e584fcce5f6c4b6e65cb727d6727b622e37c65a2db885e3c9f4ee96be23bfea1a1291588dc3044c78518426a18c13e209e50d7cae0fd7cac9adcbe43241800f251f175a38fc76f9eac462219cbc850b633344171197eb30bb9eb9767cde35249b3962279c4a29a594524a4c23941c3972e4b8cc711d394eaf0e281ddf6989c216f69b4a344eec32c05c73d8ed38cd611784c7bb570c8cca9c1e7917c9eb3043188cb91f4da6df646ee797fb45a21f2b59c7656afa08befab5f6511fa150a878b4d91c7641fe83dbd1d65a9965be513222520c71f3ae87e311ac690e8af63428da13584393b2271914f40ad499aad3a45bbb6dcf41c57eda2aa35264bd7bf8f3be09e4e32426665d0c32cb7ca35b0e1bd8d3e351f7f2ed41b01f4d0282afbecd5b2d2929a4d0accbdc06aa3505e1514ac66ea35c03f50d8c3906b79356a2bd0934a5f44d6645df08411deffd7905d489691c9f4050a7f51f38fe1d078e7f15c7eb61c4a142f2d527cfe5e3f92ddc85ebf2811f50c3ce33761969c1c7835c88cb078e22860be02f3cbf2796b1eb0139a74236f807feeab1900bc3bdab09c19a7eccd5ae006279e1c2f018ee0b177235ef76197605e8580c587bf2c2d5a0c070352903fbd52a4faa6d5581817d92dbc763de9f494420548dd803ea7c22017500a09d51b54308849e71d8d5b07397911682e0d9c27b62d06524ff85bf8079048067c62ecf054304c0231b30108a452658098af5c4a6d88f266dde8579fb71e58f1f3e6e43711bca1be7eb5a46284ffda4f336b95f16eee30279ccd5b97763a645126702c9d71911084da26a4420da13ed45b4e88cdcdf00c0c2ed27b0a60fe43614edf575f2044aea6b4f2290ee40ecd11a4d6a0ec09a06c085f9476fa081daeb9e026b1abbbce7bb30f3a556f40afd88a9942dec179de0098499b03782e0a4f0afa270085bf986cbbf13f28df714a813f3be975957e15f0bb30efb887cf559ef22fac6c7bdb7cdfb50e7c76ffed9dc7d857f35775d8f7f9d4f873918763504e02e1862f69ecfb34d198a65ecc289793e0f2c0c1c14c5f25d784fcce64ed81eec5bbe3cf18735520014eba19e119be2df7e7d7c8b3f5a602294f3a54b10e113f37161daa38771fda211c80d5e017f35f7c03117079c041c913834fda277a187c1f4f42908d15f8c8f54c05fabf56da3dc0b7f31bfa4e7c93cc7635744c765300c33af8bc47bcc3bb286e63cbcdb93775c9867ee47e3c275d510801674f02314e371e13db06640149b42e29c980b329f919efcc743963bbc1999dfefb4f43c997fe6c2bce3fe97b95f4fbebfdf2287a5bc0f791e314efa464a1e972a7c02f9b8845d7eda5ce2efc72790c4d389777aefe27bcf3b4cde07cde58ecbd3ae08bd5764e63318c21a19f997779a5f7632d47ce6927aafe3d79534a7f7bcd72576edb8bccce975edf8cce90e3c44e6339f91c1de77a4773f99a3e0d57ca729cdf13d8ca4e6331809ecde775ae62e91d9bbbc5f0d7ec1fe7747e4de7bec86c03054012f91d9c7e93dfcd97c3ff01299799cfae0c1437a7f7d7b5def255f3352e6de5f3ce469cca5f45e9799c11f95afe9c48977893f27f2530999c71c097aa737862686493e8f6fb18361067f3d7966077ee11d352c9acfdc14bcef348ffbd5fc7afdf5172eec155ecf778a9ac3ae480d7efd15f37b1849cc656264be2369ee4e7ba7a7f9eb13eaecf8ebf599d35cd8deccebf51e3dfef1f83ff31d77c29a99d7ef7d7b5d24b07b19995318fe7ac8b0abf099fbd93c739afb29c934df71d83731f7b1037f4bf28ebf5e7321ac79e18f27bf7ce04f490c0ff975d8373f6e73087562eec3067f3ce41daff98f0bdbabc19f92fcf2813f9ebc037f3c4ef39ac75c086b6af0b724bff0c7e333df9134f757a1e630c37ae01d62e621e36124f432f732f432ff8efbc55c739afbf19067bccf5c9ad7dc1d34f7df71fb93b907bb22afcfdcbb1f0fd9fbeb4258e37de6e55d99ef38cc01a13ba8846d979435eb149140000000000315000020100a064462a140249808bbae7614000e7a9c466a509c0bc44112c328ca20640c308410020800c6001821a21901b02068fa44c7b603af965f4e0776b3e92439e6ee0df3f9043d0ba2916888a315e6157695466e2f4a16c7177c6a1cc7c508d3950d20e02481be892c2660f0d4ef419fdcc044cbfececdc2511a38f95a2efe2825a2e2ed5e42266650b9a123184c883a5985dc84eabce2305f065d9498a27bbbecd7322f50b349a2c92f2e591998dae67ebbb9fb5a98498346369818f17daa06af4ea3b9e2e3ee3d1b2f9240adec3664146f8bd6d5695ba63485d14ca530f552cb4c6fd15505d5be01c3bc03cfcb9d94e9788e729dc460dc8fa174560f28a237f4f44b96f716055e376589a1544f00059fc8abca1c349aba8ee5ec02610197c6f217aa1735a350b00aaec080e719a366ddabdaa7ae547d03a1419b5dbbe2c0c01dbe09070e1549ecf5f3cb5f819cfee76ae6d199e2757e38286671c5e0f6022810b3f32a86e6c3fc6a4e144ec95162ec4bb6bf2f85ef10518b454c17488d565d4221ff5f65c52cacfc016970e7b3140ee3e25f4865c7613e5397cdeb5c4db0ada37f9bc309934cb518f52ed3ff0146e557ae35776bd7e3deb7018a63c34eb7b4c1ac7d263d249e85fd60c762948d33bbcb8ce8946607312a51685b29f83b344c73b300da18ef91478956b4fd6377205d8c0a72dfca52cdc7fe47a5e80415542a9c802c4f94d679a9716dc78ae3f102c1653b2adea0e183061f3752ed685a1d88e2bc25dcdd565f0f2a1b81964c5adaeb4266dbe492c2269614ed8c80b0fae7642654bd006fefae302f749c2c96a2d873b9cc1786fc2e482c6326fd0c2e36e18618dda6b4aca0597a408a3f78815d2e9a00590a481de70484cb6f8d6ba4d0023d6b0c22a14d5876ee92f73c7b703c28d6ba62c4a9beeee1ec4a3e06d529de1c31e19c342dd879ccda2ff965a389b5c5ca79d834cb5fff56df25967095f1ff54a70d53b8983f5dd55de7cadaa146e8916d286eb4833f1d1a123bf24e39e5db4936262573fc28fad5369a46bc26dec02a0621ee02b1e13f7fa5896ecf3609c4c8ca5fa93695324f7e2d138916cf3f7d57d070ff0a99d71ada9e80ac8b9cb366cc399dbf0b8ceab1f55c7befb385a686eec46363e992967f1ea8416963410bf4f09ca5601112f1a0fa208e779d3f869a4493b048be70835bd1f6d6480cdbf0f75a27dfd58dc3f32ada23a9bd1c5b1ef15fa442cf400bedf203dd468bcb41c911a33837d941f71a418a2a96d3daa7e235fd29e71ed169f77381e86b1b2a5cd05fdc0896966360e1c621ea85e291ed2810410e98916b25f054327e2d7a5ed50d5fe8f5f3b5a93e52d6a6ae004b79c272918756ecef181daeb60355d748f975a7bad227bcb252f700e5cfaf9ecdb6d44b17144c155e2ef25f6eefd6fa166ab5fbec9900b17b4a9ac4313f0ef70c1dbe26a7469db161806c76f41e4f67550a101151da22ceac33fdfacc80fa9db3da808ad6479a05af102851e1e1b840c572ebee8f06eae4a6fc0eb4ac65f7c93144d98fec669b216d1b140b1f974ab36eac82fd0e1247b03bf2492b7237e6b7412b64f566d79c3ea4ddcd0e41013ee3a51d10af92f9a2771245d1d39a4c4a1b8858dbd38402f77427f1fdaeec5575d6dd6c5fca8f9a092f760863dd6e2b4af47e5f8e6050396de8972cd01d24d2bf9aaf82f4b1f9b9df5f217a21f4a22244b7f4f0745a3d5250e36ba70c5a592832e39960c15793debebce9dbd577826d60755aad603239865e8e4cf58851cc09ba5c8e6a2581ae77dfc27739f94d0cefd8e5c96bc4e10c3b253c4881138c0f4baf9f441e5c16a46130a90125618ecbb923494a6c27ad25e0d7c683706c3b9fb186370fb4c813e580ab3da85243d3b67d57b34da8f1b473b214806209dd225ecb78840b1c15cc7bffc78cdaaa108af8ed90e48e9fd1c7e6184bd1d328bc8153ca03bdbf3c2de2c50b60b5d06ec36080295bdf9c1c01fba71ffc84c06f67102f109780e0aa37f88b7c4e105db150b328c4fb0daaad6fad8368cc0b38a96dec46ec059bafcf0c56faf5d683a41226754a5ea094c6e05dd889b59bbd0a39aa8f870af1af6c19575a83f98d013097e00f1dd8c1745a6588e4b5c8fe8cda2b5d1e092a7923c62308bb7b14e8c8de31908216d89caf7a5524a030100143944549212aef0b9a0dfbbd7503f78003bde88f82d2ab8b55c555989d7efbf6b3ffbeeb98e8cb23644c0b5b9bcd2baddf06f1798d07b484cc6a6ea7f38099f162393b6867c91dc844cf7ab68e200dda96fa22b835aee20a135a349fc91522e4939b0a2248fff9b982f7720d0c4a1ba5a004eafa3c4f48776cb6027ad64715d879259c02660d2cc768cc4157d78e33a7c460b270cc8e5f372459b094dd6f9e36dd99101d1a3ad0370806813ea517d860dbd89995a2ef3aabafcaebcb0b56e293ced9d4aeddeec9d84856c52779acc58e39ee0d223debf7141e440ea059713e20bccb8e292bc0f0b51252ec61ca8663581f1280f81c245ec1cc7977418b4216fc57e90596fd21f8ea9c76d72921bf110a570a7d5aeeca8678de1425c72a6fefc3c7d526a557aec32801de6effab5d326c49950e16a56915182b2bb77ae37a2995ba27d7a5e7dc4cebf07804ca590e512e6f0497cbc8bddf992f8351c5013befde93cf3ce1ec75530b77946a453ba6882e26f13fd280c6d2c2a9b941e8ece17a4150f12d0a7861796e4461283eb77ceccfff0c3e4119dedc9785e19bb5b232c3f750967d825c20509f3090bd2b8d5592d298de1bcaba35a86998f366f484e85c9f790aa64e1161b65e314c551255ee1cc975f91cce014173bf4f6393e67b681cfee8571c3c82fbe7287665489203ede7879c856ac0ff738e169c68c47ae597811fc1a97fdc31c8ecbe470604d8c944003875809ad1f07001d117d4bf41857a92e9257b229b5f0e3318f1ec45b2ac903f3a4572d2136d37d2e0ba93bed7949f719b95d5fc55e45163092bd1fb729e78a9157299862fccb460d12b24c9edd78512a725aaafaeac63dec0cb282bd0e7fac500d7a9d9357058482800c6f5de20d0034bcb860b7e178165ecd39d90e1765bb39e3f82694a29ea30589469ee19a8a3af6d06a1edcdb574b8238b7d1b60a1ee3b0b02a37db4bd5f068d36cb2bc070cba265c377010af6c8669addee3d1d16a836e666a2a1e439307d036be7ed505033db9dbb60918a99360b296529bf9fff472ff87dd20283145cb3452e47d540833cb244291429029c3e71855ee3cbce409e16553e1baed26a875957b7270910a90ec1e021015e6b8836af1e01bcf6db986d23800d2c0b5edd2f9467b2e5fee8fbfc4393f15b763e8d2d9b0d1c5d9d9223cbdf06ca6dfaba08dfae1b9bda5d35eef451dd920383a6190570c17d03d64a1362ade067b8e975165d3825983264cca8a17eaba7dddc8a3b0b63bf1cd0cfd4e28f2b275a0ca6650d1f999e4bd822715c4148cbec4da862377a0679ecc77bb38b5ca3082c4446d5af019ad54a74526c3de0b0d1d637f3ea900bd0f1e776e66b57f97a80a3eff39d57c45393bd6a2ced250544e518cf086299b6b5f296d4130c9d9e80b9ec55a27cbc8680cf4eb0b55512489908ad637368b41bcf4ca700ee22c84696a5b73ab419913e9b3b64d6ec5603fa793f7fb4d24cbc5ada6f707b029f8e87f8f574cd1590b0880296d27446cbd45a38f532e4abb51621b40aefe864adc4ca0be1ec84581f2b0aaaa036e86ca1876bba5a30556e50981cc483375721f0149ca674291607e98ef668094e200ac068fa3bad6e6d046d1ea357ff37f743fbd16408c3e68d238162ad19d0b4273742a2c842520815cc3954bb9b2e0eee5ec8ff8a2eb86463dff758d25182754e764cbac00124b950667135b4e9a5f1b66eccf693dc8e3cc8ba6709a8ff8c5668af6bd15ad455dfb8b1cdcd295c4ca9937db9b1215cc07faf0660a4d0e9ab56fc481a6482e17492508167ca0041b812cd62b4eb015061120f2f775a1fca969af74d37da81a5bae7b8a318a6260329924495bc617cab2942392823ef4bfecb5de493a6162049225133400d3c10c815a0824a8b937de7fe7e836878d9a13bc5cce7a15dd2228e04148aae1b38382cfd7fe21a922fbf24e79515d01fedc6d677c81caf82c76976e8a55cdc40054dec6a240019cb5180393b207e357076f05cde25057d3fffb7181a273dc280cbc4260b7cc1356b76e249b759197ef93f1e3638f7488af8b46adf11bcc19887e8fddf322673de1c7bec2eedf12f31b9ad0a3003836452c572b3202562c8e82cde5071ce422396c10ebb4a6168742ac850a430f8affab0182c4130484d95e7d199a629c8c8cd73062c2661c4d143bd218c32e2cfe99f07923d6adced813c0afb41d836ef6d6e6acc09d375a63a1607f0340feaee97def24ed69acacfecde6dedae6eaed93b15677143ae87da89da0792582d9437a7c23be25ffdcaab5985ae65e26fdc262683c3c0fb892519ac27549a32d5271919e4676313224ac2755b6132e280956ccf6c6d6a6ebf2072cde802a3b5b0008372c4b6edd349408e74106f5b222d6136f5d6add4cab9350698107c1e026f8ffba6c4e75f070fa84cdc2ddb1bfcefe156932bddcda48abb79370f3b92079d35c9c4fa50d24a344705b227ff5a50d2e83c26088526e5f36745e30d1200a407a0147b889d7f05cf5825fcfb53c4c60e3388327a471fe42f91dc4441349dbe205e76e9c993feffc43864c591212b019558eac49692fb46949e6242d63bc8cd57b5e14d0170c27c569abd1cf025bf65a62b86f5a6340b4f03e265fe14ea937e51715f4314ab830239220c504c15615a643da015781eee3cea4a943c7f57b05a409245b93a1985ba856c0b50ec4779fb3e55425d4fa3defd0c5bddac73977a50543c5913b672ee039fc54e3dea3524caf3b7373dd9a4aabb657a603293b800b6e87d7b38dfabb00eeff5f6b28af5907621c89e5d82b6401403aef75a7de21a7538cd39dbb3c69b81cd452e8bb1e510025d04e7358296edad4e258137a2146c36a58731a9a9bfffaa915b4cf3cd06329012428317524330812978d47acfdc3359eb2400a5898668ce2807413fc3ee2570359c260d4c487debdd38bf9f07174f7206f49e23dbf6fd5a8490f8bb90ebb97af23ba7373ca85e8fe1ef1c3ea5b5df1b44952b850b67d9f68b83fbfc760b40357cd3eec28f634b25ab5c358176170cbb1c00bf74d4bd3f7f3e1ddee2417c77bcb0267d55db500e398c3cf6a05407ef0d03c9b04243cae235c4d319a76cb26e007aa40bf2122abe7e70c1a1d3c308a2c523a7fb4d1a351664e9106cc2674255f7df56e8256ce2dfb03e8079dd127b5c9c36502a9562f163dc76840d594785978433128b9b3eb835c2992650d156763670139fcc2768e9c2cc7056c7cdc09d8928f7b26ce7904024cd3a34c558df59368c563f7c917235182931c448d523f278dda44f0a3712a8a5ddb87809d2d72478bf5d1b466ae39f83c648959e191173d04e6f42705d6a281a6bfaba156598f58034359d6746261e1439e3865130eb07452cf218b39cc5334857ceb5bbd33c2e35e7090149de3bfa9c5340b9b646e817ed0c5bcd0f36a3cf1650b2490ffe9ac2ff05cacd54208e80ad08e9dec17358093dc7eed1192173e62b593286525b865a646b09266633336c06bcc7ca48504094d935cbb6290e1436ef075fa26db2902265f3d46b92937d2c7e1474cc8a4b5771279cc7a595153baf967ea9a8b50c84b2eb41e30e1dc1d4d99da4a5a8ad4c1caaebcd144ccb6b3846a04079b56e73e02e8b15d7d334d8f40a4aceade42e3333d32de4a2310b14f1a3b91cc6007b42f46b25a11f4839db46db88075cf5c01dae1af370580c601577ba06bdca77e43b2059a15269ab2c48f70d7d137361cdfaa5fa53c8e6292006722b63822fa0ca3b6be7dadf4b1d3600c70a77fbd24867202940b735c04813dbee21bb1b94d696eff9d7b9bf0168938580eabd7b2ad8911de8949511bd92071db1d0dd4c80f95b09e78f637f06d112a11ec9fae82a42150d667b55a4c03d8d61cca31ec1899993ae5a66bde19ed685e210fbdadfabde97ff5e01991a81661a227ba94641bf9da21095867aa1579a468f3fc187dc2c7023a7074548ac090f68cd1926d27aaad2ba709d2ecaf13d015787526ca3e474016e9aae3c5950c2d581805a1202cf5ff54e16a601d422065c4baba8ded193d825f3e9ed84230d7643e5b94505a732336ca7756ad47549f7cd06185dbf17312c0a285cc36d290c8e545dd9f63d9a7ee87b7f3d761b781cdb58abae61ddc99c5202d804353ba22c53cfb79066e2b4efa603fa5edce43bb5f4beafd3f0469f996ba161a78c893b2c28f5da804f84c0fd615941028714f3133c6692220fef1436ce0fce5d98a6aa38c16cc18a850f2680326aee68ba3f8d9d53b6cbd69167b98b7bd35e992d88e27813980f32218a3a66a0ecbcbc959db9661bb004c98596bfb91a61358d87a099b3aed0c4551a5cb42041149f101aa2e471818f793feef44f1174d7555b69179b7571af375ab28ac8f8f1a33e31c41335a8a18d8cfee8373c7845d5cdd3975e7350c6224ccebd87c3e70a81ddcc184c8ad6114159be29ce518285bdeb5808fde507751b31807335727d4fe4cd95cdfc384f6a4d002ec60278dd209405be92d4259a7e38229f3d50980c40e8e9141d44e2592c092d11d63f0360fc83232b6c074b7fafa265ea498d337ae6ff9349807e688668b5399d690292931c86fa51e33ca3202a9a77d68a9cb326945c967376a97c3d3938ddeb0952a492eb3b16652d2d473af01a4b0027858bcf837a424f989081634bbf7a11b2aac11f86eb03d31526ffac2b82dce9352e8b5ba1f26aa6d477b641a59ae62d7af011feb251191a627382a4c3e2ae2d8c05c1279439ec1793e4081db183ff46569500a9157f3970f642a37dc79bef4ad142533d43a0a24d75ebf7fca1d8ea65b1438dac006a74e6d7a8b238c64e000e846e63f7bd08eeb1f1d3e4ed812c710205c106fbf6a7e2d29d03ee7cbfbbbf11415fa5430fcddc99a95bb947153dfb373db0c0723c299d7cb3673fc7db6e4ce7a3d0076f7044b6c39667bf435dc5cc346d94bcbb05960045cb5ecd32d12a29dc4f984ab8c199ab97e51f77203b22bec7795071792321d3603af129574be29994e96186e7df2f5c57c9cf9d4cafa34e47054261e2bcc6069f094e5c1e1b1e2cde17e780ba90d113b305d8d9bb5913f7f3e489c0ba1d9868f3b816b835bf242ae9be4818099c2c8e6dc6b17e31235949ca12b9242b1a05323da125b2816710255280f0cfa6b768463bc4017b82305bb6815095324ccf5750c2d829552d0c38527c00874bbb6d6a6a4ddc8a65392d3bfb1eb6418be3c7ef0b464bb3d42bd982cefba7cbef003e4cb4c0e1ee01cdda7a0298854012a826b4c9b61cd1d4d0351a0415a8d810ac275c3e365563d8004ee64455b13e044e1c8951f8b3d8f37b0fd057da759ecfbac0a724e6abe63d01c662df91d42b8d1ca2bebc0b9b601fbc0194f49a7ad2fe5fe1a9136b0abc104bf2a2056b15ac89bfa2ad91e0ea53b116dadc4b4467d3b6bfbeca01e9172618f2654c615f4c61523f7e0a7ef9ac5b0430cec126d63c7af3ef0e0173d0c333437380175f68f096ede2f42b81672d3fe4156ee26a6c8dd4f241eae5b2f2a2f7cd8e544cde8813cf45fb96031970ce7632bd0820f2bc77deb00477a490eb47e2701d83456b2a08c4cf3158c455c8e217301ad11101fca9c80a1ae0da80ce68928b70d70a6caf878bdad5736d36a9793d0c8f605101aa4818caeb61806dc6ccae7bfef71affe90c02583e6873a1e1ea05319952a6561f8631750ba03c55f83698dce94ae5a8c7cadc299fac95d54e738e22b0e88ce40a330619c44a720c1ba2a844a07d6655dbe62e5f40fac450ec50d9f22404c3b624275373288065db41ee54921d27e4be57e1c0d8bb01471d7149a452a8d0d5a731ad11eaa1c37652203c88d2bb84f393f3f59898e48518f0ef98d9d6e260fcc29323efacd3cd5c17d137939c20b20040f1328dd98e33579f201d04339ff4017c95d243df3aef5e566f25224311cc6cb073d92f584e4ed94d0265b53a1e0208a6a4c996a3b8fea42134c42a6bbe74b4545c31142fc9ff13a08b0c0535486eb5928b4681b92482015c14ee9ff7d10791b55cb8725a024ae8c38d0f449205d38a198195d0fe63bd72f6f408b626126c93dc5353752e1a3c5c591e9efcd33efc937b4f128f48f9228457932695c3cd7f27004fab7508d0b2d3d539684e268f4f5906eb96337fb7aed9a89eb2c1537f7471053b9bc4a0bfcbe488d6f75fea79d30dd1793b00480d8e8c3da3e32acb1269a1c0f7930e89043dff22ce348f45a3d783b239c8e22967a544f998fc0b06275fdd92a0ea1a06e1f21bcdb68dd1f2f782f8db3df79af89214f2aaf20ac040f0f7cd3389357ed953df2767015479284956ff6900536feb77524a738ff418aea4c04cab2bd0d7ee14d356ebbc9ec07f2a7dd0a7e1ab7a65bc64d1bb2b0863835b08420669ea0407c0e3d37ce99d460e0030475e0ba4a470a07903d82981787ed991c565652e4c4ed6c156852f305a749e46c241e848fcde89608f68b823d08013dfb81342acf7ddba874dcc144c10d8257d24a3bcc8d2a936d7978bf89f6efc4db972e6321b9060a8a59c671348d3d9a2fb6b1a6a7da31c5a58bf38e01245e297108d0db23e060e19538eaeafdaaf8cee62f1acde682e041baad57d55b2f4f10773af3bc098c0772e45f4e15f8f4aa3a7714cc5c6b3ab22fb5bbaa1b16c11549421803cbd486009e5bc2734f3059c39479b6e7a9cee54d42fa56b67af70513dc55fd823c2b29111ac96247c4b531478a82d7102555114ad92185ac0b1cced4b084bcb20c5cb8f27bf85738d7d99ec2da8f5596cb5f5c5d250148adbc8634a17e68fef426b25f9797a85c2c6d9e175e96258af56656bff9e820110769060218a383f7f02a9cb56a5200b0b11893dac17a4d84dd2de42143ed0807201cc328d97c1645d4a0c6ea9ab7b8f7e9c09d3f13b00ea9c812a860af5fa1641b171e032aff3c8755b956a38a8f074a79a3d3571a1dcf10450f997c4c3a46c4485dfc52ab59b1216b5428e5322824b24012066cf2c857f044744156537ee79ed3fc9a2f94a8b18b1e160bab61e43df306368d30594f25867e4b220ea4640e11a64fad3fc3f94b537fd1dfc1ce268d1ebc5be5762a03de9a10058c137f913ace1121e1d11de1c1139693aff947e1fe9d734244b0459dfa2efc19e1fdae752d6c53c2fbb945cee06b882210c5db15c132d2f1f619bab4a734b56319aaaa1ff10bc0821d6634c969b0b29fa06432f2422d1dfd82edb74e482df624d0721a88b846d28d9296402eab19d0ad6f0a9ddedba7221dad00c84c33f1d16715f9842b007c8dd7231cf75310cabd2ce5d3dfda69daa7ffa79ca9f23c1a64eb1b66c070b6f1c7b9a909d4cb830c9582c6169dc100b188f1fbae69450c80a319533d4f2efa2e1803250bfbc6ffa61216af8dda157763ea727ef9b7a5173e8a884f39ed250ffb64153316130021725882b3752a37169df64b16c88ffa1b9cf1b784302eff90f006f02beb80e0bbd760fca8a2cd6a235d85d9dae54e384484f1220ae12851b8514e69d9e6bf1a475a8adca139b8fd7443aeec2dfab20ff7c1aee889e572817ded39fdc9229e66cddd4fa8cff1c7bdc5e58c43f37f9b6b7ccc79831451c53b3e7a17a810a42d1b8322da0bd8df1aa3e12ef8f305b1dbf8fc5a4c54c7b360b3de04785e97f1e9202b361949b3c8aefb3f1da0ed894a45e254bf20d0fe716ad321ef782fd02bdbebf3f25b27b1a66fcaae62683f6c8cb951222c03274dfa0736ed5a7e117b321e3fe16a034c40517aa4386d4e1898d8b725f298a99cc4eac79074bc99c1ec31a638c52eeb8ac6f48ccfb245831c612e81b733585c6c0cca2be6507d9f05e52e7087c64e004a065c845a7d724e786a5f7528abd56808b91b04f644d54aa09e1e5970ccbc44a36616af429b902b2c0e3e461a6cd492c69f0367446c9da40c3b09370b00f9c72048bae54d2b5300c5753c87389a2b65f81d636b5f9836751b7e34be400bc29df146bf35e8f78be6ef5219699d05886a315acd0c828cc63de998ca30c6fcdb285d05322c03e7d7f7a2a33ac2d7f53d2f063ab9a360511e721d47aec7e6ecd3ca3ffe28ed76bc7ddb89e0a64d3be9073b22654564acd9f9505e75c2728533a9671a127113cc9256b1557a26b7173d614d5144f6f66157bc2ec287672b10b1d3122f1f028a79bf6d4e74c7d426d2dca4e086de05401b0a9c8ad7f15202132b1761682ec6ab4a0264ad49e5c74146d40d4b92880173d9576243f578c641d63289eeeb22eb9e12eea32552d3ec026e0e7d89035155b8d5e47d7b607eb2fb2bfca7fea2c81ec52f1182cb1421d057a9079a420ea274a93c7b6fafdd1d7dcc886e4c8c3479515faf485a07082d5780992f524a3a674ff01523ac6010c453978eeb06417df9c72f486cfe88e826ff24ba2738c39d218b395ee884b772e14aef9bd615bee5cc1e9e8cfa7b4b627367733e755c44ed69e2321107fb97c68b39bbd40e54bced37b16655271c9a6d575e433156ab80f9e2be2d1d1f55ad959d87dd4bbb1c33140088f927382363dfa681710517d850a1171589da3b5df4b691404f733070420c7e9bce730cedbec68f032d352d868a815ed7ac43ee5b26e0189f62aa67989423d8c0bb8240398fef46469b9d016e3642f6a976ebacc63a2b6de541638d8ee5ee16777f78a7b62ceee5e71277752faf85a78c82f9b38a0274678964e9f056eb843e9bd5b06c50c8236c71f19ee0dccb07b2cd311affb8b83b2e4bd9a8ca6385a1494726986aaa51c2959e791f1720263a2e3e1fa9b26be238ebcd524fef1443a5874a3bf36369b7dca90f3969d70b869a6bd68374844880e5fb849704073d16c0877b35539f94e6cde74b351828d87eb4ad8dcda85cb84bdf3d8623fc6f8ec2a623c2df5025c666ef5c637f70b8ea471bad36d909d54676cfe99e56e500bd3c984463082ce1c58dc80aa7e577ec9ca3f9c73a0582f13ab5a86cef34fadd02fe0935667515a2a17bd6146f0fe878faf163c0172ff17f46eecc87192d23e961fb4b711da473a2166ffb21d49cb647a42bcb09d98cad42f628f4bddd12d09fc8731322b9f45c7700ca2897761e81f98d03823e4344bae104143574ca3ecef34f0d048f48ccf5889e0898df0527f9032b0a4d62c094f23fe38c78c9d0b9ff6a31c6a73cbb06f09e16d81b28e34703d869cd234532a4f90a91968560edf633de1ef7edfdc02157632debf0c71108713b30e143dac30d5ba72a55027b9721b7b04818d46dbacd8c6c9b2c53e3ab73f1fb2232118f5e5e35353bcf59647de5e41347aa9da68356a6df0ea20a50f236bbafc3eeb0421e2832e6de699a4287569517aab185b5dfa1502a5ddf6324e3428c90e97cc5c69f8ada10252c49671b277a116af7666f6c649570e6933f58211d8d7f50b91fbcdc36b0b84c89f42a7e47d68d612920c454053d4b48bea5f94481fe43476c61add25f8ea9ac634726360dba16e49f002fa64b70db2232dff0e020c940c441e659b9eaca5478fbe3345b2afc961b1418f01f84c61c24fff478abc556c8cf9182e7421ed7d5ba3e353770f60fe5d15c4839f671ed2c816194d64a588a24871a59e6a168a314b9d714db9310d6f99573a27c7a17be654ac317ecc9fd6ef11cf828a71c7b4e7f62d3398a759ea00f9dd82d94928da72cb5fab68da11c2d21e64d23f96d1834e0d0ce8f97aea3f24cd735903bbeae0cbc36d66e3ea96e7f028d066361c306aa914119015c316ab6617c0f932d881a518cc22c708cdb77157b96dea6e8935dd7243c271045fbee044ff88336d1059092067ea51342678ba9ad0c285de1165632fda90d50e1b7209c69d3c275404d3ba2177f6eb63e3fd5daa5fee0a7bc8ee9a1a54ba4d7eb2358a2048f8019c16bcd7578bbfa48488b59b8b87a188a0ced4358bcec8d86599d973899c02c7e16357dcee2d54f7aeeedef295685a3d2aa2bdd8dbb4eb3293755c3f02b6f76166dfa9d94157874a8c48243785c590303d3334a8841abb29f287841b2fa7cbc9ba280de3883246a91ddedd47c67b9d013424a055c0c24f28cfe6cdcaeccd56c5c744b812cc1ca50a6c27086ca610830def270da47468cbfb4c4d1f4260f208d36324787cdbf27a666009f760f4d36de1d9466dfec6052f80508e3fd17981a349b40e06ef05400250df235f6a9134a257937875bc11bd55f52dea1ccd927c51489ed4e8948ca5b86a8315e913a95b2492e725a029d69a13cb646b044006c93233672c9a586a803109b6d0d208cbf8def49d2897b03ed20428c4e2b803fa0cfa37d435d31aecb57737e76e4bb76679e4c7435d2302f77eac817650f735f069730d6cf2cc64c052ece401cd22eb4e24f2f122a6f0c16f56b95802d516a68a017cfe9d50d00fe396885d529006ccb32864d1a8b3041c149d3514a1800609f430caa7e3775e45f629b8a8b882a0a627b9a791ddd3376b499bc5edd20c2f73b3963876665434767afa375e1535699096bd9b63b31e43a846fccc5a99446c9259ae26cd2ab6d046f1b40f136ad4c9085c20323959c775c575ff12a1a7f3ea338f991e65822458955ac38f9bba68e34235e02db4c68dc73a70ccf4cff33636b02f34ac21025084bf42048332e1641a4c6b4b11caf4187808d510174c997261fdd06a5a8a0443051edcfa0428f94c32db3e7f89fb140aaaec66e2d2af45d4f7ef224d488cc488d17a16615d986c76682840f6b08bc44e66c60e8b0c75e4710ac75354783c554631a8a3e0607e090157e3a476069d920ce3440351e175b960f5d542362d11cc6f10be071d1b4ea4de1bc554402dd9c9af70e7265479ddee7aa94c8b97b7c424e666ce5235b519c478fb450819519c2f1f1054351eaf23edb19092dc5b96b674fe8ea22622481730f3d955183b5b66d663753c19d3182b72cb8344e63ddf0d4da719d3cbe513d6f13ca766982648ac48b669072157753abd61ff11ccaca0922c0fb28790db39378143cde2983d44479fb9c2fe50e87e83f11078ddd623f0694bd13708784bbfbfc46b46c17e0b5fe87c210bf3034dc3d1a9439ce9004019c138be7d6f8ec5bc010b4aa7cf01ecadcde2477964810d87c52c609a25bcc1001c0af10525f9654138dbdaf25b24a58a22219bcb2640f26cc4a507aa8024ab04de3a07f34032307e1b8d11224080724be7bf4cf855ae2a95e5a6701ad534149e920bff64a31043b415cbfa7470091a8105091065a4af8c7dcbe489b2de24858aaa9245d8b287309ef17f86b1e570cdcfb01c7ec82a2f61767d1c94e47c5f0bb2c7510063b63298a1e8457e5ac23ba3726d85015ae83ecbd60b1415e9c94dc46db990325e022cca6de063ea9215a053389d7b49b35276a49325269d0f94e96862821ca4c655977251fcd7fdf6ba895842c782c2c89addc2f89a5026bdbb9f48e23d942273621210fc2d5046a07c156120e6b04926d83b593e53469c61cb736e6259f95fc6576fc78722a05a1382c7be2df1fbc8bbf7f7237d0c775af540046d53ec7247c0de200c70150f7e7fd5127390442da085bf0367af3ee2f89142a561ea05d4775c4463d821d92ddcf3bdbe60cc776d97339e25dee77bbed116f4da22da6a26e30bdfaf36318b528263d71a2d07f1db31e18421c5d6a1f02c6ae4c4ee723489cee042e21ceae0c3b1da6acf9b2d3298ddb0335d2f75bd9593006f22131c6fcd30f57411c00f4fb95a6665edf27979c6e911387be4322767c88844b431f1120b5fcc595fcff81e5c92a3d1f8a1a64df3e82722c2530a8f817d481d231590ffacd4420607df6ca37fad9196846ea5b51d62f8a9637c40ad852b5eabc1aaabe12a23988161c0ff30bb25851089d8641f11efd7e8e7146030800a750badb7e4ae18910b9c796c1039d656c806fb38b0a3477da4940519c800c473b1dabf5a9957cf236f97eee1fdc002700779783379cb577c7cb3b030cb9e56dc00fb7e7c265317d7e96533ba78c01b4544c1e7171b9758e2a465950559ac6e902574571b553e8c0033933e7750bab6e785ad66290e0699cecd744f86cc1e3a28a2a3f6e6abb557cec7613cc49c33ff13a82b127e2865005563a44dce0a2a114d523f24f03f4b372ca2c40f5203f5858a9d3bc6e97b31600ec94898bd3bbc39d76dc8ee513aa7588ee3b152790822963a341285685c9c8cd095020c74ff3d1378ff9ec6e52d80947f723b438012d01590c2d897dfd5cb778ee793dc5ca7d7e6e44da4c0d9eb2f5a5d6f376081cff9ba45175677dab13255a6c0498c3320b53353ad4c9a4e18972ab2831e9ad7b4608657b1add140a8aafa3d4c923c04558e1e30e362219faa771a5592e01c68b0aa4149cd86873a8805a38f69008f1747e6ca3b6589d5ca524ae4ab40971520ad293c96e01ef592188f2ab977f674cd1917d30e911411ef7aeddd3732fe53c5bc49b72d90cbc09f3fd116e11438e061500c0abf121c5926f3b7f209d86f4dea6553c5692fa0b903074b9829b1ba0d1261ce7a7bd9fbcfe69521f1208d3d313130b21bb95cd5965dbbf549d39079973a237cc393218359cac66a14eb71c414d47587a4d8ee6930bdad911a3a2e72beba01293ae3781f4fa442d440edaf36a75999aa8373e565d65488e42e2f536031caf9e90a05aff63a621e4ae4e7c41aa42561db13cc50b353bc08d8b1625d33e46e6325b3da2058a3b98eee5e0566518a793842f2665cac31f32e523728a45c62cd19012c11b8877d84a0a6cdb0e74dafb450ae330a2317d174bfccfeae03fd09aa4e264f31df64d28dda21578ca331bf8738682faea06b7d45fc36bad03f6d4f0dbfd44d0697933e5577d1ba6e4537a7e6b7a89979c155b01bd8dce5867e287c4c988ea7d748e11df60c9c40e5bca48794f546268fa8ed0b068b197badd674c75db7d335694736869e557a6591859039cf1bcdb35a2f3239c29c3818457d8308a623260e56370861c5d1f91b7cffb07648ed4b3b5d51c3115e4771725986c33512f16735a5d6da85a040cacb2e84147c8af0e3c800fc722864991ad49259432d75e0d729a9587a681ef98d242b4db20bd95df1f3c079d4c98c05958f809cb3fe9d9e487c68edece4c489b6f2aa1887976fade781c44236e1d71de5cf59a64bc8f483384264f9ca1697dc5454c027811d29ae28618af915b62b2ac280d8ae5705d879103afbf99e0a86bf24f0ce7798d61d7efe5ec7a26cc95d0264e6f24300c491c89cbb52b144d873072fa34270c1aa25d3d7b4e2c4520587d9ed06126198fbe09fc6d32ff3f786ad29a4094c015270f10fb78cd4c4646cf851f903162e8608b69dad535a02040e933b1676c64d675c64f21e70428cbe12c06be37838bca025caf060850b217c46efc0f86c9a8478af759f71cd7ec9d5b51060d755c63e8e1761fc1feeff4ef3c93108d3666900ca89856d0c8170045850dda988b1122a50e50e5dd94cf39a98d28dc133457a230414d86c91824a4423498512fa1e9dbfb1dd1467eafcee2078e5189c4c2c131d3c7046eb1777f574ca7660a84a895625edcd856bf7adc61de7ee5806d28a399d54310f33a8acfd6ffcaa719fe13949f2b2af71f2df36043920a3abe327558193ae4022f196e26dd89ba84ca78d7b29e2487bed123cf01f32e9b392731cd0af8bc7735e481f670ee52c263362a687f60ec00dcf561020bc3fccb073de519e08e5c297242d6bf7f9ee3fa434ed0269f7ebab64e0a69c72e693e48204ff1f3e55ad59cacaa88f7cbd226fe11796217ea9eeceb06205cce67c2d12bb05ca7c6eb97d46c743d4a6bb44e4b891c5c32144610dff67612ead7ba95aa5e9f25d5b32b3c55197abb85bae026bf2a252ac28b79eecfe6096b08acf263def8fae9e39902b6412e5bcb3d5026d78d6c28a9823fea6f3b4c30f3b862c6c9ff50686b06c23d6f72f17a17d3735a0a602976856b086f53ca34353ae9e4bb0cc4e4a153e318ff55ca27c7219f7ac44db6f2906d88f3fdc382f4711c6f40dcf25a4e4dac4d6f6b1c809546c234352bd805bd5cb222e031824e07913aadccfb5737630d89c8c78d0ff87abdca010fa12ef0bfb431563d8f582bcb6c3a809af0d6f8a492e84056787288dc7f5f1c3e50b0ed1847cb7ae2ac003027e04d88047720076c46f32e11259137838f68bfc98c55637617a6f6b4aa570c0f182852f01be59242f525a1eb54f922e38695a99fef75a40c7f1140b6eb9665d30c3dff2a948882ac700c83669d8c2cfea21fda7fc2582829ebe923a810a8627b7cc7962eacb7048f2051344e2e656e357d4992d095e60ea0a52e7b4039e535bece44a7b42830b45468752db46c0ffc7250a71b8c26581bc3c89f9f4ede2b8843847a8e64e504352f117f026a5561340765a7901a71221d02bb3fd4c64a65c6200c408ae71e751b924bb92d5482375264e8ef531ae536cffc09c4d2fb3bdd1a2d727e8aa5c428ff47f69eeeb22b65820d1980ea8acf7b479e20747cb207c2a3b64ee49982346200461b8280b5bd1b0f9510214348582ad93b821f6dd69451c41356c323e9b75ea2b891071e1a858beb05e6e7658101b743013801297888ff787758c0adf91a5c3b4767ae292d5673c75a418c07ad272457b4f4740e103e9778bd15bd741511526fe62e28f6e0965b50a829bda3d69a6d4bdf318987a8fa66c76cd228d2e540dd5c4741a095d5b02a417fb22d7ca4292f544243fea08c42567772c28485b514a16c2077a4b9c81df7a8c57497e01cc5291fe29e05f2a640a03262920b5f2870432dde660c4d99f10a2f94b640c972c8c5cf27d4053062884958f496638de088513398203964fe12b51a08ead32600d9e02e4f50b177073b25152e53c876add683812f6ba6cc44c87807939f048baa221d200735c02acdd02c58579a01e5e3bef97306c4b79bc58eab3cb12b513791822ef92b84211318c1566f553f41fd7108b495d87a9eac0817ab9a34f3fd7f1bf94f14ee0a834d0c01340af85086367af9b47d4f0b0c8a784edf9dd8de2e697a7363d4d925402b43ad4ab08a619f6317e666d504fe06a2622f3fe449cb6cff387e49f59c641d7aae56cd5025246d896958951e4ff1ac80e83f35623d37ed0c517612be47d96f1005b21e4b680a6d6dd17492587add0c634f0e67488e10c5edb30abf2eb7015daa3fbccb94d8d81973174ff86760dd78b47bfc3a957977c3a7b39ce558e2353183a50bf9eb72802f3de1c06a7504608a4cdc8f8bedc3291ec6152cbb71603d0155684e29a02d218925086c97ea100e5c280458e9193dd949230f5d4d081fac95e9d0d62a7916e8e271dca11e41485e6aead38da1b65766d3d312fdceeb28c6fcda1142a1f7025697f436fe71919bc47b9e6e91723b6096b4833510431143cabbbc579500ac15ac664ab0d6cf3b43ca2a8d4c086d50b9ac8ba65b5caa0300aa23851c8498471038afa8eed0f78acc1dcae0ff851e530ae22cd32580d46c1d26a3e09deb6ec72aef402e643f63fe0e6054d0c8f413c9ba1a209ce7cac41a742244785f58f30f40edc3180cd98d8136d3e816aa4209d2d46d9edaf44736f1bee359fc8ad2f47913fa4c76dbe689f5d301211b528c0e8b364a790039c228828df3eb460a982b5093f1f47e5f4090a0dd1150440a2f26b63562c8da0f0dfaf186c8b7f7868189726584eb56f0171e1d4556d209b84360e97fd7240caf04885e2746215c7a09b157a0cc8cee307bd4db08ddb649dc1e8f27e3b81bf5d42865ff07fe31f1f4230c11f4d1bd065f1f9f2de940594cebae04412500906897d400312b36f1145f372e23175646693bfede6891f9816c10c2cc122219fa35877b28bf9b92db5f4d77f1639cd12fe69dab78f3b7c52b83b6131daddbf204978b220001590833aa0744408b3b1092c12aec207b35fb49b5dd9eab616093d709a4280510b3bd5b3eb02d8b5d5d75507a33d981cee236ded3df00a67e0bb2b56512b5e0e8b848a81e34547675a0bc88bde54bacd38062981339358f5d3b43e02a5e6bc004813b2c5baedf4449b2f7ccaa56c40889d1656f214b62d79feb3638b936315857dc31aeb6f794a93765dbe470179e4f1e17f0f452540dff1538b0409bdfa08197c51a92418c91c86c097f50b3b4981e293893b82a8fcd4c1e3a693c057f480f40ebbb8e0e5bbe72e07cf8d70d1966672560c79b9362312ac623b859f7c7e6fc3c680808d344c82946e1390c3f94d234451a936954db84095cad206d7a781a89c8fd6b49dba45fc32e09d5705717a8d1970f22cf3b772f4e87bcf483af6f25200a0b6e6bb250ccff9fc4c03aba70351910fd5b42dd293e999c0d3d514a698b27fbd689a62411a68d10255931f0bf940fbb62746ff45ee238a300d02fb11e2b85266122237119c0c4b37f18021f015eb2d6fbd6e58cd3de1ad5d8156c4692fd01132389a3df001b6200eee64b43dadb077fc8b0f8ce3d714cc26a764f8b7a3d8c30ea04bef18ab8f6189687f6e589ecab22b9f0349a61ff695555571a8de1eb2cc07ee3729e393f83c4171030d7321b65e80ea3cf71a1c7740b20400ba51c1ad3b3f122a4f83cbb1021d1846ca5c059477d89feb81d55dc74d389b4b7abd76d56cae32a9506c1198a8fe2a168ce27069d16a0105b19b226404ca39010dfa5da48e4b2ee27545c288d96ed643118a6b0916e459889d14a2105bd6ee75c65dc7c80b072f989e913ee159625eb230b2b30bdcf153092654f06693475ff7bb51d5906b3f9ecb74cc67f46047f98baa8b44a7542ddf776988762a6d66abfbc8dbeff6c3314eaeb9ac9d12971d92a689d58e8fdb0f93b395008433ffc876fa4ab638b874e8d404867da41955b068b59f990f265bfce2466899584d147bb16b96aa568e3ff2efec3ca73a8d27db14142d66577e4a0cf79dd634281bdbc9199e303b374ec928beae8d162c9c81ee96ddd9e5ac6ab35f88c46fb0753e7658b17253ad62039c6f843b0dad17eccc6b7bdbe6e7b8e5ed9a717b9c8c673e9370d21903f4921b85e982afe49396e5bc35686eb499d99cedb4becbfab9442baa14d200f6e8e7977a6db458b86eb143a55772a9a13856371a73b8fc846622ddd61d4cb4fb18d4546665692c91697b9719f22e9ee7d08119f76dd3267b8b9337e836e31894a07bc41ff9a84739a00f8cf91b51504ce4d6e538a214566a8ff2dfd355433fb7f1732c358a4409d01441dca68362e22a257ba5d723f7cd04669c09b47633c8b25ba49d3bb5f0b8f233ebb875999759aa1908368a33d068415394fa2e3481119c00506dd26e8b4e1c6d3177e4c3e75e14193bf933887d798a02219676bd71429bc1d10e176765f71cadd8e0fa549daab12193139a263aba7f24beb642d7b1002c13a759c30840978c4ba097c62331d61b281db82f2eeb29b92c0992cab28bfa9be1d52ce87ec06ef848f6943b6d2b7f872d19753adfbbbe95037d2d4d057872be6993884a612d24eac7fd854ea7e87548e05b595085942e0281cde4194c39d88d7f681dab247acf6d412885346f4707ccf2c5dcdf7bedf5dd002c03001d3bb957538db3ea7fbc793ba2cd37482bbbc3466aaf1344226fa3799515777dc0225e1fbb54e22d921ec33654102ac1e8a2db9b7bb4f745c317ea8bb296889d75e19692f86b76ee90bb266d89a2c09fb02520a1c581378226878b1474f50660f78c3eeaf3c260a4b3f30c2c23f38a1ae8a8ac7ca9222b417a796a021582890c817ef97ab63fbe5466255a0c3f1b684f8fccc7e6eb3c47a435fb8d1cc817421557bd5331a2862134aa7dabdf5e72c4f595aaba36d8447ba617722ec28f9484738ce3f3ff8c3543c9df0120c37f9d303181550530b6d36cd7ba0b719dc0eb47ad0c4c9f2cbfc1aef7b96e80d215f4426b34f6b2ffe33bc2a1ec878d5cedbca4060e06db58c129fb3798ca7ee07dee4914667374f93813afff3f772b6249bd649b781d2941f049832e3771fda8c5fe1d0c891c991778f63a7747cb88b3e05b8b884828885440f2cb7ab021d330bc4d4d0d96ba6e470bf7318e6e6157e1b3addeb2eab7e6b2299743fad1cfcf03fdf026213ce48fac7f91693d229e64f103702f3b1b62a033a274b08c765d8c3791dd4db8f04022f28f57ef4cd9bc71616db93d1d07d7207d3cfa3c83a873491095ba3acbe5da1a05d3cc29f254508ceb6476a4a1bdceeff6ae9f9f31450afa97f31667e1004329f9a9666ede9e806caa4ca1efb2351f7a1af6b378ba37507111c56c2e4d76b5aedcf944b9b6bb6fb793aeb088513836d475a20fc2ef361a1280e1079d5747027a5efc5d623941d4fd8d3579cb17dc42f13e538f5645608cf85ee5895c195325e247e5824e31ec5f83fd6d5b868036bcbf4f2c24be4100cde8178eaa66a034a357c9a1920bc1d70b238ed62e33cf0e37f42a49b8b2f9752433711d94a3e6ecf9dcea9b7c8d4ddb7a7c0058ae04bc61bfbf7a05bc7acfc1823d559be4dd06428cae8cd392eacb5896f2a6a4100b3012a8ae9f4f400cd1c88a02c68eb916021891d882afe5e623dc27fe1abd55d1c30f901e40019d65bc9325c10ada4dfddf4b59dc19731f2a0aae1385ac302c8f5f65aa73bf7a4582881b3d27b467d367ca2530b40864f471b57d13809a7dbeee4461033bc99819a926a084b735c70369f9e61dd347c97a931fa5167c3d51700d7bd79ad25681cf152ab9668dc982309076927a1f85e08e6f551a3f89c10add3602bb2f5e19a12321a0f204f7bb8d8ac5a3be4eabaf01cee1f687a29b7fe33e84436926005e4dc311ab8a44e581cef9c88638d5fb11274d8b1ef1e6e9064f409ac0b992d31e99d324031e09a1cd0f82855921d2d2881f0f5a4207748d10a403a04d465c008856251c91b0f3af112b6afba0332f621c6d25934a273234057948019dad33947af6d962e226857644bba37e0c03151cd3aa38293aa3ace9e2a9bdd16469e5634a4fd987f30612ae45d6a067edf7e51e56f10016a4752208096722e8fe6dcac78f34a975250869359c87ca8eca7d230b01e659769afe11d4fcbe4c964269734cd7da3598e3fa6f42303b19c450f983d1b973ecf774aff043864df2a2d2b31d160b93824443e4907bd8ca5c3f07c7912101510bf13b734a58d86887ea95b5b9baa27c38c487151b07d3381db4c56fe65b49abc9cc76db119fca588c8ece62a6aa28b00273867918bffb8796bcf3f0884287d8d7830e4c3662ac45c1823f34c4e5bfe6a98184e378fa9153b1665be9e9f0fbc610e34754aaf5c86a9f03798e2487d0c61a53413e0dc849a0080dce9ec665a04b63152adf34737d9d3e6d4c582d593dfe9c2d3ace9634555f339d3ee17ae4e295224c6f1643bd99d04eb33ac7416d041e9a496491c241ea668a806534e925a33f199a5cbf83392f4deffa37239ca8e07c7f171358415640ea4683fb80cfde05c6f30f3e8f9d2f15b8c3a0e0ca3b73f95bda3705858bcb4947686fc51c2fae87bee5726642c8b1a8154990961250b6cee87f9eb1a32b3657cb5ceff8048d9bfdd0a502ca5271c0c56e3b237a782496ba620809eb15efa34e0afe524a1a0b56db7c58d066974df6c1dd24a23b4a0a48bff6a10592abc339644316129611fe9c49c0f751c44f88195fff0353d69731c0a444e4aa0f7ee350e1fa18f12e575978e25beee04c2b042a0ea206ef51fbf0cc707e40a904a83e2a19c8904d3d8bea774934f138f720bd88871ced7fe8a1811a68d8df742a608849aab7fd90b95eb8a6970698430a3c720e05a2fd3b174cb6345ccbff282d7da3356d364ea437f859c959b9d10639221c6133c94dd357d45080d9645b1e804ac5fc24e751e624dd233eafd9a4bd46e45faac314e108ec77b940bca00be9caad4671107c91883dc79078ed9d242214bd5696484d8786fa7bb4b303263b8953a8686a2c1f07f9e306d844a4afe6c245fac954f8d667a09b1026cd8d67af985fbc8f969efa19f0b666fca97553a335a06e12df3b583f21b8583a9a79e8372e1a40c805c70fa402573beb132faae42ca492d80fc1257952c24ff524025716a9dd5461c89af73c9bbcec7ecdb7b990a85489c9d9960c7bccd8e745b880cc709e7687027cbf02702dab7260000df6df86ca3314693964a7147de667560bb3db2656ccb2cd1b7493220a9488305617330ccad252db6eb094b581c2a69c06cd773c3c611a33ce5bfbda061378a657d1f6c31a2bd1f6092ee403156ffbb3334cd49a67e47a5ac9b8b751f2592ebe512c3da705d99840d246dae7bce7d8154c2f35f9483d0e0939d1b4ced99b6a47afbd99a0d3c4a6036e7af1de05b4f4d2d1b32cb7c45d198aad21d3fc484e2c0307b89b8628dee366ba2e96b0c2a1f580a38255c17192792aba80badf7e978e30e42b346e8cc93474df35e2d0319199c0200e2f0c168ad9803aa83408ffd9c458802d226956c41913c17490fc5003e00e67925de798b0cda8d5eed7431f7535d0f1d0f052c5841f13396998c49a48a37dd00a4dd03a4d29561f9b311f436fa1e5740ec6ba106f1631d0e652278cac462e6afe78082a2d18d0109b926633c410153e54eb9beb1a1ad23cf6f1e577ac8f1b3546bea0c6d0d01cdb98cde4e356ca1cc2d0d0f897978c6d1a91fd319ed55d914169d32c343406945bf228ba2ffe2c0c7ca5f888b19f9742435946d01731c45944dc6d2c665625f0d6587ad2de39716aa244fccb73369412bcad4ccec3237ad9d0aa63009eee0c9b5a0f334eb31d73e415be6455d70917d28b6dd632fa973a1a9c63df2d45ecf2c4a921ffbd9b4235e441a568c8abe79927889bcf7e7ee417b2f23d3c98eaf770ea9cae755ab006cfada004af056026f401e18ab5b5937f0034641c92b417f59c627ccf2539f2bf5c4064767ab39ed6c01dcdf8594085856064481b430f8b2cc1c3d167ec61f22cbba8890d5f17baf63bcbdc505776797c635953dfb126624cc7a9ddffd784963de0f4f3b300ae5728085a8e8f2c2ef9618598eeb1b8daf5b31e6eb67eaa46f1521e250257b1e3188758b78a21f7f1144943b7e4aee978bfb1dc28a95ea03b6321a0a0e6b5f53cd1d10527d4176cf93525085e97427478cb5ee6abb5d6238462df3a2041b9aec01d99f20219a8f00b011409ca22a7909f239b1da1580b6edf8571af32ef8874c0a3780302b83c41f7ed57e30c5828bcf4bd04b8d9b293a31cbdf05516803134eecbc0df37d697382baaf8c66f9cb06621c23da3ccd14edd41428af45302d0a0ca353fd16f30f8f318c0fce43a6bdfee2c330f8ff0a80b91f3273e37b6484baf67a1a3945a394b944f3d165931ea5a4858c560800af2eedd82e9c3812977377c6c6339bad9351e3877cb5864743b44befb2a1a98708016247f8174b1413d82efe76f887630f660ac3039f4101458cd25b5c6a05e7bf31024c78d36f3ca53b5c91f672a964956960c775e80228c81e73171e5ca34c2cfb15d98f78b270a93b82191a0ac5482d882884c4eab21ee7f5a3f3158fcf6df191a93ce10bab165b5cd33eef7b3675ff2b2262ac5f2fc9dfaa9f5846e0a1c8eb23ffda8e459860426f1ee2c49a5f4d14b62d80d48d6400e6a42fef3c77862148924258fdb7fa4b0be1dffcf25cc8ba475c7d3a78f051c20350c4be802608ca1d4fe8afa390bf45e03bb94846786e42e03ccc7b7f842cca21545df417eba1e7469273ae38c4e2117f81f772d1acb24c4acf0c707a600654b21d96f9ee1cd82577d650c46b2fc243fc8a92e9c4377f25c8256b981afc17281a2d977578fd6e7e5ad2d5567b2464996508dea7544578541efe250c95fddbf958a373b80c57eb1d04fcb13b14cfb3b5b8bdf76e83713d1a4c320406af41fff1ee23e906deaa6c0041f1d9adf5fb1bb56237f607866b7345c6557bc119774f7dddd676aa0b1efa4a5ba8f10d7b6741c67311991d239e2318db93651af27e587d3f5604f5a0675d24b71e931b531c7245fe27d248d5d5ae8a9a64d62b341b039f90ad395a99f7f014a3daf22f6b0d24c1a38686a055dcf94b2d8572cf6d382444cd31ea8af32c1bb011a98b8b69df8cd243511310e481bfdffdf59dc9b4013ce32b72a29497f527c0be9b2393813e7b55cc0f5a1d3f9037950fbc53af8b0c185c411f5f880e0deaa51287a719fa18b82bfec6be3c1af461ac16f981cfe7ca86c60f8110e3ea286fc0da5dcf294058f73e5e3620cf552eb074a766e2b054493d12341c299afac1e4037213af44a8eb785b2b4bcf3e081c49b9685d3e7e0c0b7d9f4bb50861e4e97a83216cd1ead54f12f894667136d05abcaf09dbab318ff0904bc0368e3805ac82d7df57b57a76ad048f8a5c11c11c23048cb810c0515f63d8e3b960a64fc4d09f8a491301f0eab4cfcc505a86df794c892c095af8148d84b48d4635bf7405dd5ae9f35fba1de27fc18209f8b924e0d9be53e172ae94aca3bb26dc07f650c12614c479b1163dda2d08625c1881272be2a36c6e63b6412a67d85d9452e5a126c1f46d699b1b1753ea684cdc30a4777a4e520ff0610cfc484ff24f4d8c29219f33f660737182befa6e623963890ff53ca1e3689e9a0509311ac7ad383a17f95a6343234573f5c62970c9c3fb948fea27f995fffc4e162b55896ed0526e9fe392c077da2082c68fef00e433168ae3ae8fb6109908f0ac9b6fcd409d415e45375f0e6213e16533d626911fb7b5360c10e328c04423a2ab6c106f94ae59e35bea3903e235a29f4f10cd642ba33b09bc7a88e4903ab6157cac5b255e161c43f252ea6d26453128a18f4cfdf3b68e8e7cd61abba085f7c9d99c20f4b9116992f3eb36331f599f6845c4a8825e3d8002c33164799075bc1f9f3373ff49771179ab89fc7aa56cc60af0d474390761114c38d71870fed3fb9462bd63c736966c78b45263d7d26e17981df2e1baaba9dda2b24d2bd5591fcf2892f9984d128084fca1475467d2d1da996848948c52f8e7de949b9e03cc46612ed03d1dae1c704d17998771ce7af4ef8fd1188882497323dae7136732c6332217bea2bf2481ea3b4e8a7cc0596333c5a5a274e3f9e29096d3ab72b3fa231d8415b2d65cf362ea20bf43e3141e62f7c3312b119d79d365a93cde83494ef914afe180b7178864592e3fb6dfbeec3fac5b8bf680ab6edf411335a55e939597d0692c0bee89402384896516361ed06470a3e325e9d9a4279a1cfaf0652067a2d413f0471c4220c5cf8e8291fe8369f6ec633c9f7d9477b07aa6a7a10bd1da89565df506f25718716080a2a123678bd00e1557fce34d72793f8d1885c05f00ced1cea309cc8f0c69e8003675230a0ff32a552f8270cf5dc81afbb35ecb5274655790030677e8dc96474a0ba38e6661b573a873f4b0d7d4f75b9cca52cf29005222cc8211e194710899691afbc33017e9d5948c1cad5592f100ef1c603d7aab6c80e486f191795922c5cd3ba61dfe254adb74e76fff95c03f6d2e423a9c62298941ba8c1a2a42a1411005f574783983b6fb1ec8758318f35588fa83e8dcb112ad1558838ee0693c06bcbb1a7ee5461f882c292bc6f415ef068a64a889c1802f195fb3db1526494436142a5d3d894e606c4c33917721928001a5ec743fd55714cd366a71774b0df8211fde296c86eb9d174b1347cd51ed7fa73309e72edd4a93e3502cf31b1bd00a71e6a0af65dc8e4030e7d4a6ee469a0c67a9bcb2e24873e972ddbea021d65ee11a67cd296a4e365a0fd13e1ded90f219181ad20ea7d3ee2b6e773fee709439beefd52efff063776bf24e57f1cb9e92edb54a8bf904b46f70efacf844c4415ecc7413bf5711a41c1e12f9044b6a882f900facd184f0abae86dfd84de4169f4c508162492d16d858ffee2df7f7c4bc6ab0b45874c700c4636e706a283db902128d610e55e1dd3c41c694bdc988cdbb592f6445495c64cff52e3e37235c3de85204f6775c82a0810f39b0968993e4b7b70480754cccf08ce92770d60062cd4fd68c0dda4472beaf89fb2cbae928892146d4643b8fa367f503ccbc0301a83c190aca98f5c878fac41bd25c9149e0cb4c2b6247dcf99f859d307ed7bd2af9f3988b1079b751967558c42ef424eeeee43e5439a00d16aa98f9a727c699f033a7cb2618be02738c043186eea545597050865c060f5b0a154e494974daaaf0daa8ac4c2cfe1dda1074565c41412902e8546d9e752d4c352a0b4b5d1f4ac3292b687153ad9fcc93b2c3035532c26a96b2a7e69c5f982dbfdc2655cb3cd1f889a2a08bbf883980fc41b454b33572fdbd6d9ef24cb080a03f8bb92a150f9a53c12f4b393051e0516cf233cb9583abe0d26385acbd5bc1e9c67755112a739b9534f4c00c9a55c6aef0621824767528b11e3c066c9adb185efe676fb347c2a860ebe8e58af54d300a9b304d17b38fa486ba36bb7b61cdd655091451bf55d2143e1ec897cb62a5d4a3456361824e428517f5af97a77f69e580dfe6b82842fb89d0c49bd3c5f36922ea7c890c55de4faf2e7c02282c159d5734bdc4c45a84f292c721f2f36461b9d5ef6c107663cf30426d4d1f3160d3f86e101dc7f1642b7b092e4c2ad91c7b8408935282197bf974c975d201e95b79634e5c33864eb958273f781cbc5c6a11fccbd9a306e048c6d425338965f9728ef992a969720747325af16b48884f3a87aaf8d438ac9bd906e97b82954ace7e2ba378db35179f949bb09854e7705fa1fda630ce122e880b457c68670172050ea4ca02f2be8743135c77d9e740bd26194ea78885476dd6ee42125b30eea87102aeb10c3841073436a7d1402c69206f4f0802f9baa8bd67f39d0c27de9db3a5089818a9d2fddb2c348a2232dbf7daab43bf5cfe4d2f73f32a2ed5c5fd29e4a36a25c8eb6d07421c6de2a7f485b98f9baa861050cd7ccbb541368f73668e93208312138a528bb2336d5671a429747517c712e452e0cac4c18d9503b5718c8d97d6eb3a5b8e5923ba106039bf4dde3ebf2a01879ee3b668d9e11ca3851ae06bbcc74802c2393c0c7996907342b4ef20606cb52a39cf591b3fe72d67a34fb3f681de528ed701f8a40e0359db72be58f12c337f8bc7135ad3f3f15385a6148d2255d7a1e5af3c5387d494c6b97772bc9a7b974c46576719db46d5e8ba12e6c15fb3e4294428170d9e4866331eca07f2872ae69ecccc33456ac6855200a7173fb0aa4fa828066652ac1827ea4810e6d5daa94aa30e134cb9c841e6d85d961c2d86c38019dac91487936f77e5658c3234b54addab6502b8870e91df3b38a00b3e41417f55f49b9a956ebc265b5722dd684eeadb3ba279d0222b78964d9e685846ea4a80ef7d10f575c8ce21b51a29e81aed1a935341ad84cf4ea799281e035fb2f6e81ea599950509d224b8ff372d1997cef86eae563bb0a3d887a737045930675553f9200e48c9dac89d21c1a154bbbf54cb9703f29899032d6516e9dcaaca79c75d2dc761816fbb6875ab6c22fb79b9917451dd6bf9ebf0ca8ed822489056a3befa110cd8f5c95225395cbf0157bead8683939f48131e5e76ee3528a20d8323ae619288b8d77dea8b9964b1c1b92d2c49c459614ad50190616339b8281391a5b6bee82f2f8d098c9bbbcd9947caf711366e345c126f6a2ed9852eea45175ce0c0c07d089e70b7d8ccd3fba09f3363311ed55904aeeddef3f00dc3352bd18e24c433ec658dbd02f3a013893885adf7b96b4e1d899bcc91e0806790dd4978d8c59db5d075f40e5744f576255bd7816d8217cfb58c35e4a16f4b1018d528fb3468b5f4163969c78f45a0d2d5a32a281fe9c492870eea5cbc3d9d5f151380e46a383add0c5cf1ea679fd026ee68f42dbbc53d973cdcd530cb381aaa910daee7822e423564a6a757f0160745033b92854ed4133523be8d1683d369b6d980fc590606b3ec3a3b201e6fa64b4b1e02d3d2097291e0f54b4a059519a7b1a4347a3cb4e288f8125d357dae726638b95d4136e5222ed1cfd3fd5c62329f48a0fea5a1553a2b14cba21f55dc969ad86f1d28246d2945c719acf5c590412df332ee4e4fa1dbf6075c46b058f1cd5d873c67333c12c91662062fe879d6aa0e4fe330ef1ed06c92e7a9ed6f74d8d704b79fd37f9343e76962267ce9b014d51604557c3cf429fb43690f4891801fbb738a2901c86a64fbbb08825c7986052786786dd5d414c32861f2ae4ec2e0d0438c6a146764632a3dd25e4e3791f9b3d1e35ae7f4ad6cd17f0e004475781549a9c971954390f3ef0b7d310ded069e6896381ee5dd8183f9d69adce7f222380d918fd70435e5088df77150ac73d820c7d353b6a9f9a8d2a53793063242643a17385555e0eb9163b147fc9be7e208fbed7406b155c4336afc7dcc7a671a89b7daebb6a8574a95e3af8d73b7ddd688df10d0c284a0afe6a64299ffca6beda704ccbd12b24b6176eb888cecf2219c7b0c04b495b334cbb7fb2d82648229856f71419bc62f494d51b6dc9937caa690394fe598f3182d11fbb527e12b1a8017aa004f64ad4dd2f9721d88a2493abf35f94b65d025107d0d1c7a466a08e90ceac13eabee18337a8869507fd1146680ae5c66162aaf64134957c7592c485eec09a15fb31a56a6ce48c54daaf542b2878383b7687b2e63a7f411eb805d1700bfc56d072c9a651448073615590c70eaacdfe158067512cc79e6e3261eb13d55663b82b65b18282c8508dadc1b36776b196890e47cda38bd521ef61fbcaf201f432218df35bbdca3be2280dca04fbc575b5fec3bfb4e45505e6f4e03dc5a2295f2cfdd929619c3a80a92d3ca9e799cdcc6ddc2bba412c43c568aefe0909857824b6176f8728627b898e99b1683b124c65c82bed4cf8e5f177a87ad263861a0ace1efa56d171ec5c5bab5a7d70b4b1e609e70733ff1a72eaf1516202ebbb2517c1ca2a5c44f9f7e72282127882a977cf64faec89a235592698c73bf6dd6afda36cc6f5a9f31220518e956b3d3ced3f35157854c4925006d22bb394e17ac656609acf1f69b0e8c6ca12d63b580cf1336f733e34ce992a713ecfa3184e506c80be221e500c383112008750e509a883d70e0875aefb2029db9689a9048ab9bd9a1cf5955682669f85e164ece85ea1b3296e62edd4f22654fb26bb4758339b66f242faf49621dbb644b5a6399ca344099d9fa48e17aa0bbabc6f9f2c6dd1147dbfc777f53df961eed49ddf126583585efe9023743f14232b1347a183dd76f3a45c5b0afd89896bb12d5b702ebd31061572c10f894cde200b654171027b610c193ebd95e82565b5538bc00f69769f409b40709f969a6530d984e5ea22e0f689912b09cd6f796954e15e4e91fe09a862fb2d35fc38a34dbaa978511e74d0a26011b121c07ff2dc1172a23ddbb6303233f2ab7cd7749f54ff2723673d173225d4daaa092af0b4158830397061b2b27565e1ea7fe2dd456994f32f5690afee26390ebdf8dd67776d0b53b4634bf81e2fe734580efaf1b8e96d5dfcfc51862e12273270167a2c6a8ddf808f4f8459eeb8c0dabf70f39e347a38a943e073375aa435a8b6e69bfbee85320a82952e32d3839f56d31d647bde2c52422dbbcafd0d416c3a80956b1a946dee704085f4266b0a1ba43d043a1a1f9a5a305c15351d9981a263f758ddd46dd4f5f7dad545b35ba6d52a844a7eed36a439734fa8ac5fbd02c2071e99211c00030b60ca0084d1bdee9c330ad85c00f4001e6d6bf884261f632ffa08f661bf35db96969a889051237bcbbd777309f508dd0914239d623b3a15fde41487a563d4bbbd77637b775defcdfd60c3180cb3d664fa51287aaf77d7bb1b932fd5c5342a7805bf53d74d267b8750f94ad783e8dbe5556f5dfeba3eba4eba56377bbb6b92e3e17615c3ac35997e14eabadbbbed9aecee8750c117c7a651c138f6e7d5d464abf295df2136bc826d64fb9b7cddb03b664366d1adf683e817ee21fa867b8c7ebdbb3e62f2752ac2a347f96b4423a625d2e57997bd2eefca7e5d5e67afeb9862ec2a81bdbe1bdac8df65c3dc1f3f44895e5f595c9c9edecaf920f27e9663ef2af8266fdfede554e075f1a86511fd3159723ea8264ab668717c1aec42e52d4ec3f2abb46039b6d1295a5bb438cdca555ae0d8a92156b00a8ee91475717f69bcbe2a6f7ae9d977baa961ee53b2c6a12a571c62217682435b42e17bbded1db9fbb7b82c5fb9f82ad7050f5c02eacaf18750b98b3777cab1727c1a95bb68f17b9a16bf2dee7f4fc3f216bf1f82a5850b7c67963ec48902c22e30feca695c541bfe62081bf00b5c6f8bdfe4ebe2aa1cdf95c764adebb29925d75d931c0faa99f9af7c0896ab5c72a71cffca698e574ec382af72161617c72c180fe102636c3b557f9323e7ddff342dce72f1f1102d70c4bfc9337366aea8dcc7c8d0468ec72ca52da9948f3e28d38629603fd891ac795506512a67c823396229bbf664a98a41a9a44962cbc21695d4c28ecc17f9932f4b620a841ab139383ed6c7e463c24c39312726873227f644ccc7fed4253144512cc2d86861478290c8217246fd15521b65117246edc6b2882145f4758f75aa5fdc920c6c1879ec44a15e8c883076a6e2651147f0a1961563376e1cfab8f9aa17e56a5cafdd5267bef4adeb32311cf3b22ade262a66091c8da1666248bba34b84b13145fb6e188e9457cf7c8142cea0aff5f2c93ee8a504ebbf7e4171f9cc970b27d72b93e0e8d4fcb513031b4a9e70e664b90509836921ca5c4a228c4a7ece0de4190653155450c8533221cfcf9c1a8f1d003aa6145812c8224c66b060c8510b39c6cb0d48184c6a000231d65c3df345093e3972b561244f8ee461e1c99949266a5e20b64c0c3420a6e6656a0a24301561e506e6bc0c19b173c74513368463a7a475b16da2304f368526b5276b9e4dbdac96b4256d29a93c6273e1505a7d35166874935c6f0f36543860202f8bc82132070859e3001ea6c6b14d727cfc04b2a625130bb547faf03411190a9b086661d60ed9b2e843968caa92216710892a18a88e3d2e35b0d1464b53c5228df1891d72bc8b0c1adabc0559289040598749fbd8a64c122986c35196d8ba381eb24ce32dae064663a634d6fbe2a519d85035b34d548c14065bc91c311f1a04ad5eabd7b5ee9e3cf29440a84b72d7b48f8d3eefe8e3a3ca99528b3e78a6009d74e80f5d45ff4c54979460c3b884dcc74153f3c3290575c91591bb7265b3edb4ab8b4c14bdbcb1f796bb2524d8f0cafdf71160e3b2648dfa0dcf5ba169337368d533a07553c919d9eb89e4199fc81816976057765d5886165556bd33131533511876591aa31ad81e206a7834cc77611bf3a5071c9fbdb65374eef0d2325ce24be8b3ba648c7b56ef4dce64c81821cdbae488645765a2228d5844cd5bf333da8ae1409bf8bbd7b78b75915c37ec93899cf1913e1fd2d19641d2bff9e678c832094f2cd4209d7b64428166e9922e0ac644d1e310e110f349c0cca523368c3d618c0d1c34350ee01181eddee9b7399a30a589053943e659ba71a6b267573681bc11e95abce88626f0d68899043e720ba8f524d2eb4938147dfb453a463a7612965c0244b71fdd2f8b6eb2f5b66fdc76356d6241a289f96419a536537b943342df5ef1862d19437be56af4e9294743db4626194389ac6a9a96b56b59bd1addb6ed35e837bc4d99b357ad46f6d0bdc9968c512d2a35496f1039ecd3c890af44af9b8659c7cea4f36e44f6b0d570e863b368bc62be2293f9729d0b5dd355f944d5dce1512ed1c0d277cc0e13e67b3daa5e1527cc37fb56c819327296e87eefac6bd866e4bbe876e02b26422126f23562f6f0c9be07760f63b7b7b8b83d729c8f2d6f585a2163843eaff8a25e28f039e964cddb7028a42787dbad87b887369abb6fe7ba6fddf6cad5e87e3d05e85444ce88b9eacc977a9f1cba538a89a2efeef49928ea44a697c3514262c319c47ddbeef6942be6cbfcf614a0f912f3f6530ae40c99b7538ec66671b766d775af31dfede4add3e6c6d5d8cedd9bec63eee40c9f522063580fdd30e58a6c552443e89e2c57b161ac6a6dde2bc6236f8fa21bfec81b0ebd87a4b6d96fdebf7ffde1d0a6e6efdeb4d8fbbc57aec6e71d7be7c8193163de2947c3ebc9db75514dd4f579fbd25b6fec920dacf53a7f5d47c06579de64e27d2ef1de24f0bc7b21fbd0354dfbbeef35e6bfdf84cf1ef7cea6660e6fa11a44262e59f34298bc4acea00fa9f6cc85661a96216364af9d3bcb4e391a19932caf092b31f19c3d7b942167c89cb964a793f220afbd86ccb2d06916bac936335f58868c41e911edba76dd38b1df647ac3f3c8b15e77562c63a63b4ed98436fb864172bce24d8eb74920634c26b9df37979439a031a714b0886152461f9b2c420e298249e3585da04523489c884a62f013951811224f6c3373054cd9c694b3bc917202bf028d2db438b5162da24c8b162c2c518685656525caacaca8a844191595d329ca9c4e2929512625050525caa0a0984c51c6643a3989322727a55294299548a42843228d4623108c32202812451991e8fb3e6ba38cb59e17653cafeba24cd7715c94e1b8d8b26db165ca685a9645992c0b85a24c28145b30ecbaa2cc75595694b1ac5aa34cad94764799ee39a3cc9cb145467e5ede486909c104e8a70a287c789e48b2736489247472884821b26c92c515414b9848f12325ce1563d12bd30341a91461bce28a44b04215991e063d55ec9e2aadd78609c33353071a4329c5e982166d3062c3f853310cc37eb09f8e91e590962c8324905c226be426251356e630027b2387c8481f1313132fb52ceb9a40b5704c471965bcf53246a5ca22d7371614f3d496b1ce6add1c88b0b5946d620e43582343b055080707e41a56a1cf4c17d4bf19b1218dd9b558b3cc14c7999219111acd71c26c745249295529820d9f290a063da57f31bd2813e7fc8dd6f5a17b93fbdad48c61193246fdbc8dcd46422ddaaa181e949cd5a2966559169667a439d0faf29a942b298388af51e6ccce224f6b725f0338808359b81034777a16d19158c43c859846e44924cf2b7c4cd49c3c988e649922c655cb25661892a3e4287e01e3666640cec9040b47004a120435ec4451038b0832d87440822c18c18a220b491822054cb010638cb2bb37dad87c99b13b7637a594524a29a5ddb17b069452ee1b1762f63eceabf21095efbd76ef09bd61e9cd25a0fb09c342144d0e4bf701239f4e3b03418ce9ef3d39dd996949890a9ec8f5f4c5fbe4f4c43be9520b96d2574a573979a9f4caed78711baed9303f14141b504c9fe92b5d7b71633295dc0fd4647aca0d6f72cab5de5ea484348b5cc0604fdebdc9f4dad47cc232640cd3eb0d5db2e9338d82e3448d6ebadf090e61e412e9c689d2bed1b649ee878d3b0fa1dc9de3be594b0303857af1827a1e087ae1e87b41a905bd172f6e9c29cf761a0d8c9b0dd7d36b2fb237fcf0c5855c476fefa581a59f3032f7d0bd4b031bfa80912b07235399b78d865b16343747727cc46e2002d01460dc4004202964f93b6d3802f7892c49c581a3ac54ca48230b8a3e8d52cef328776f87ca4f1aa651c19ee6554e3bc7d1c44e698f9daa9a17d6ea795ead9ee9a4e4795da779ef3c4eeb3c1c59f4d1e93c3a55ff712a1de90453b92715fbbaee386155a72a27e26ab5a2d368441ad9fa5315590e3c5591e5b8d355c141a3824fafb59eab1d47e34315444db3548612c98aa84a011d38ca4e4e4a99157db5d6d1886447b556558761d69a4c3f0ab579efea3f6b2b0571d0cdf36a15e1eddfbfaf6a15f7b0b5b31da992ba3a1a8d46231044a12794aabe4ff483eaeea24f54323d364c4a8aa9d4892cc5a12a77e0c88a4ea3118ac99e946c6647d64a1c22eb6d9b8a7b941908c2714284aef34cf5dc8e2ef33653ceb28c4412812392c7ed40b9a97298060577f7c07b60e76d998769baaeeb700ff01e281a91482452d7913acfb3342654d7ed309d8b3b4c184b795e77af13bd870dcda277dde8ddb59ee79148249287c3eff624d2f72e7e64459fe9a298ce75dbbbebdd5e2e9ecb36d3fd4183824d9c0da5d96a48f32b83165f70a2ce3ee3911b87d9bdec72cf3e10147d190e4dd144b1567bab918636b0db87ad4ba4087e66a6b86061b32cfb68a3413c5b20e5a1e5ded9ad9769efd7d6b2eeee5dcbb2cc46f4ce3dd3a8956937d432dc63c4d1daa36c949548e006825a9659dc0dea43c85d7b86411f344cbdacaf69a73c3051df1eb8043c466c27e7dd4d33ddb3a311062d16711d531c87439baa51aa510f8737dcbd1ab0dcdb02325b9f5a9665f778e4d6de97bbb5a91aa59a46b9db542eb4a959c371cba1909ce1117978641b7a808b92c06176a2b089e298f0de81af4cd64e940ef41e078410e00d6d3278d1fbd8d75bee3a3777cab2efa60b66a2ce70e33851deb6813eb64d2385b4921dcd9ef49d466f9525adb7eed4022d32053cef74020fe2eddfd6ed7d8fe0d69d4de313f813f8ed21963f7c02b18d981dcc0e3ec3e8f7ed8636fd6dddf67e05718fd2777d6cb97bdfd062afd495e8bb114923913a52e77d218fd49fd733f4ee3b9d2fa47fdf356aff99b87bdb4874b2ef814dddb9ab8936d2a5fdafffbdf187c1cdebbc5028cb361105414a3abde1e85696652f1da4b7fb4e0f7e7be9f6f840cabdbba29344371c611f5bceb230fbbe7df47636d93b78698f0ed35b1f9ba5f7e8bd631f9b8fad1d00848d9cc1143370828f2d5b40ce608a194c71b0061a8eac659444414ae9290ebb6f9556db3d76c39470889146f560b5f5ab187b2aaf44aa28f444d64fbb77dabee3f495ef60b94a47e9874f1b5ec1342cf766da0bb7c74feb28d52a3e59ed9eecbf6b9dc9844f169f729cbe729a130d8eace1d0541fee2152a9448f128552cff3a84769ad59adb56ef68638b2cd40100c5119040f5ef35431df907f1cf81e7d2822d2e9f41da313dea182a3cf36adb7793872d7fd2405e524238128267b52b299c892ac5da17693f1047e74d2cabfbb912ecde923f0e65059b122ec43a5cdaddb56aeca4f9765bb3954f0cabd4bc382e35576e52aa759c12a98e684bdae533e545127c7f88855953c8f69a284e0bb2190fc715c08a4e32cb5f6d64e6d3be9edb449a7a5531c8a9a36f77a8ee34eda28e57ef8fe59ee5e73f6961702c99cd55eefa9c3373e0d73d7b8ca719d394cb9136cd35c49b471b7d72c672d77bb71da6739daf566efbacce4c9effb6e770bea903d72a14dc665dfd7894c9dac36fc914db7131c3de68ee3344dcbce5dd2b37b83c4ddeb6e3df07e3814619bf6ba73b7bb373ecc7157f36c9ac33e7e009196069ab76d17512cdbcff4774578b30dfe7b87b189a216f7681bd2bc61edde64f086417253d228c3dad4186b1c961e47f4deadb2ebd63fd87ff8068edea3f5bebd36959c0fdb1b9fb4f749c3372cb5d76ebbcff2287e05efe11ee06ddf90721ee79d50d268e4f5d6dbd6ed7d1bf5d6bd511c1beb9e7dc320b96d08247b07ad873b7a20f9fb4c77789b280f7cf70f6313e5dd7bf779d47adf4bd2edfb3cba7db4f33c9499eebede28d5b6cdebee9dd2eddaefdeb0946a1dd5a6b6d13e958f2d1f6fc1d0df39cd0b92696d8be93bea7d97dcbd5b9a17cf8536f3f346948eecebedb52e37ca9d62fa10f743fda9fb0e949fbe43e529b7f76e48b377eaf0a7f23d05d7efd486dde3f70bb4debd4b6b101fbc537cea4ecfbdd60e9f72a0fc741a144ca375df431a3dd605c9b5b35564b75b7ac38aed462da5d45afa7978d451da7d1ea51ca59bd5a4773311a5d7d2c7a3ece88f6ed6729f9974fbe928df7142d9918225f8a8a23693bb386b6d7c7d77b96bf6ca0e7ff5745b7fba33fd598cbbaddeb54fedc41dfcc87e23909bd67ea6439b69efccc2bba1c69dba7fb728f7f41a84e68463a3fcbbddcd91627f7a6bd7c65d8dcbc20c64edf494d39c3c1a149c929e6ac319b50182591a24bf344fa8d0dcd5b0de369bfd13b5bd5eee9e69db7ec8b09da82d7236d43b098d28c64a1ae91193747bf60377efd96bd753876f70d8c391defb7743eef16ddf1eaeb7eaf71f3ed4537cb2a7f7bedd933df72db3f806777a79db876da8e5e11ea25bdca3f4ed3393bb9496b651a4a40a8259b6d18df39e7d0343d9768fc361dd6a287ba8de1f39d4358cc966fa0478b8628ab9eef7ae7613b5a139f49885425b88f36e2fc7891eefdd74b14e79f8a10dcd75bbc6dd1ee063ce32108719c8e049f76e77431eb9b321eea6100e79944e4a38fc91edbf874c3814dd8b273547ebb32c3bf8ed8a0ede1ba21fd9e3eed9789b6d34ecb7cbfdb8c16d59e761198e1385c30cd02c7328c3a1cf4c798ae3478e8f41fcb0a4f949f1d988c9d7f7e9d58ae5f0d73729babeebf2baaeeb3c7c5dc44d527a123d985db71dd2932befdde34a7ea661bccbdb6818ee339d92ef6e4da77870d8466c628a4159ca08b4e19015b6626ca27866628c266dd22ba48dd094c5b044aed6afc6a185758e8480340c860384a988cde9db68982cd8503ee1c08ee1207285fd66c523ca707986308f4ecd03e9d4bc69e60cb1c252175fb0615cd2d6112bc051a2042272e844d949a58ff53a64be504bbb8f9462be08315fb29989f326a6200b64976098b526535c92b5deb488fd0822c2480f84423f3a4513c0c5a01f5186cbf4fa44a04e94b1995e2a1165ae402f8970090399864c1fca3164fa5076215329852ca74842a65c963ac814479fa892a9f5b09deb126fd7bc3f36943a2af43b3586c416fafb043b846297f499424829268afee8a09a3cc844a9a53a211d580b63132575e4a9951b1882944c21043948304308da27b70fd044054d54c7051b4aa06eaeaf4929e62402a353856c222ccd3e5186abc2a2204e27664e9461c9fdd93d6530719d3913d55fc9819539081334dcb507d98e8368b72692b9c444293175e6763bae260f620b1aacfcb952d83851f28a896a30581994fb73620924a1882d7d202020a03ec6e44661dbe78a4109a494b25b36edee96e10e748724ace1880db15c84d6311912369446480dc417cb23c8f4024654c7c49656c2368e4e755eb9810d634c0d13638d189638606b20a22e53080af632c1cae7d0215afc0e98e4013be325cfcf2000888619000160dca0ba005a1ee3383cf5500eb18e43df7ed8f8882d3387088a066c3873a65c71df68e623ca649f8fc9e1f34088ac8cb758394bca63343d4610dfc5637f8fb1616450a772b827ed3a3cae64dc93864f3964dce53a72b80e39dc25870bb1e1321e5777795c692ff029870e77b90e1deee2722101b80e38764ac33a5caec375c0425077390521b3f65006659f993208c705c6f8c696f95f20266a3e07193776aa050e51319d9a2c388c91658c1cca1d142a0587bf099770682d883fdce1cc0396c31b96475c1061b55010190efb584e177ca8b0c72bb30a071c7050a954383cae04704f9dbaa7c6a71ca994000420800bb1e1a947ec12464b4b0b0cd461a00ee34202f096c7d50df7249fc3e32ac63d497cca11e332aee386e7808500e0375c0616c2040d007ec385d8f0183711a0c88c1d260a35800be3dae8d4fc0d57755b6e8c8bc3cd38dcb852ddb88a71e3ea861b572d37ae60dcb8ba6ecc03a83153b7621bc6c400f4c53200ae0dd7c5ec7a9eb042cf135638810f0c0cc330152a8cb1d1c34f8c12248001a358ec819d748a9e3040a6101335491e2801b69a31cadcc0fb94353632c6943f0d037e8a5aca020cf96a7b289bc8f31207d200db470fe5111964c5555d49ae069781c4969969c17af77bbd46c05bd7c8106c057ebb427440b5fa3ec4aec003a1848a9f6c3373c5272c6f39c87ca9a71cdbed4fa1930e4ff4791e0d730a611ddbedb7db875227f450e684b045c2d67b8b74f7547fb3e2eea9e209d07057756abec34150d8e3805cc38a09eb71b53d443d5b6df71e9aac0d441932e4c981f842447cc9260b268e9c6123a708220c378fc8b3a661e28a1447b2c995a27bade65db9d3a91bc496f9eb4a2457267165114964a2e63c42c3b29133e4084a105b72e8ca5c8361d95a12a2c2528cc3c6445d2558f9309b1a0c8a80c4bbf6ffdc4a7c7a1082247890a80286945236866158cba6dd2d553ba07aa28ffccf44c5989999989923e4e4d0443125f24420030e7549b17a58d775cd5f3c72c7eb560f375986cfd20b368c3e34354772297354a2842a72d330810d314a4513ba20a2020c83a80917801f20428250980daaa0e9a805d49452411c74c5c1c1c189a886b1d13895cab91a89c086126789d9b4e79c162a478e20c6e80b4b1c598279491c216cf8bf982d67cf77b71665a62414d8a9c4199ee059459410d8b9842a46a0b3924300421474565189108ec0596975a3777ae0034728b2babaf0269f6e5839cc40c630264a7e07497a70566d25923f471ffa5b3fc1d573f55cb5d65a6bad97cfce5cd26dcd25b5a7f6486176b7a58a735e2eb55eb556975a65b89c40c7d2c9eda3840db71c755a4746ebb44ef5913b5902c9242a974deec82676e4ce04ca5d8449c4c2049a4016106850ae3ad3886d64a241330434880659249e39ada83ca8a1cd933ba886a7791ed03ccd9306ec48c67ea8851db17ab6755380381ab3bbad6e7aeb5eef3bdb6a2b05a84522c8735a279d2b03d9c2575b97b6e0a433516dd5478aa38c98b47a685c92650e8fb8e4013c2a0f2be877af29b6cc6b328a177cc0a7872592f8acb4ee001337f05969549ec00849f05969b5e7a70547569ae5042c663064a55d5bcf112772561ab60149c1b3d2b0adde134d0d129940e4089e55454d948cd911988004243b44622044d5348a61d8abc51e0a65c65e6f45f7fb41cb189edb7ca83ececc8a6d990b43f7369bd1639ac5a4155c8dcad19076648a17ddce46928c5d912790b442c6980f61184603bbee0eac0402ca92abd41a4111180cc13ccc091802e8ad6953656b94a996dd588f6d974e1486d5502814ba7693af4b2e4e1476b2b01d65d942a0efeef3406fccd7e79b9614b8ac895dd69453f6b02c7cbaf1d97362cbb22c8c7aa19a2fd3b22ccb0aaf8ba27f81cd2dcfda018cca4a9bd2534a69a5b23695b9be6fadb5ce1ad82badb4d25a2b0cb6a2d9a78956276dd95d67d3ee39273eddb8c2be2c8cfe4d9b36a530daaa1f9bca6682165f8419a5216d02413fe9a7920833833a456fd109058c760eae4b42b752a0dc9f411d6d6d7a051b5e38b92b9389eaba24b6583d9dea3fd7ead3934319106c587d8e4c597daa143f5950cb8699ab89335f84c064bd62a6ba02a9c0ca26dd6448ee954ca9414d727f0275aa59a2b0a16c02947b7234b02c9bcc972c70e68bfcb5a467db208727d8303619126402992ff4dd6f988a598093a392152891c3d81395a8e08a091357f3a1b5d1b9c646c300d17303096c189bf467a6cc01d23038ab6e15489181f851d3ef1f551d42a8923a3c35353535353535353a74e8d0515353535353a343870e1d3a746056a5d9d1a91361d69af00e150cc334b15335db6aad12c73376fb7d1688873db1a7fba14caa4e81a3930eb2a87ce5a39b43e58461262ae4a715dee4ec212b6485db0f1277214da35aadb5fe264b59bf6119f2862ed946c3ad6eb20cccd95e10dd90268baec53967ca34cddb9626839fe91f7b4513a5eb94bf5e1a581819c60c7dc0f0ace63616154a555cb0bc45fccc2469dcb56ea41c05ff403ab7e3bb218cfc7ddff77ddc51fe5d7b7139eb9e4e180573971edf1e46b724fadda2f42b2cd7acedbb28f8a44bce87ef28f8548f727bd23dd57b2761584a4a4acaa9621a1bfe22936e714893519e82439a9c72edc5a9742747a3f4931394d3afd3c9c9bbaee34eb89393128e13757f724d076fc82393aec9cd0613a613755fdcb89ae97b4f9484618c4e718fd12deeb18272c38a7dc0f856e88a0b96d7d3b75061c1a1cc2a57b1d7ac8ab5a00f16ab60dc8df644a09d74eb0257fd66e572c36962fc86cbdf80c3553808ea383c48001ee3372b19f7242fe337ab1c6e8e1bae3acd0d575d5ea5ba0c1c0400573d880dbfe13738a860c4b8a1c58a2013c523771afb25777cb082dc30bfcafb53672a315fb61e1934711ae6f44e61d189325c6619819d79f495539ffebd61b0563daade84ca4c54131657465ae982275dd19da09b8e8e4e5ca5c4d549461d2327df3c651fddf4947bcab08ed14d271d2b4ff9ca532eef094bee58197c7a2ec98e53ee12ecfc699fb9a46156c209c40903e28a470d5e7918814ee4e36af430fed8187de561ecc98d250f228c5e4294913bb12507730711e6e43d97903170d00521c288c087272b57f248cec8c953ae3c5d693252fae476581c9c21fd8e28ebbf574c599749b4f46918d23b943ff2d3a7979033641216b7b85e4c5967b12e77a24c8bd8622d911b473c7ba6ce9da73b713ad54fb9132574d3a87f72a576a513dd133b05fad0c82e87b49cd149e4feaa74e38a74e36a74e30abc713564a56558eec49639244485c5b0c4012277e2e6dd78d343a2c51761c5e9e6e9d69945bc775c983af3257a98c5a2a9105b0a39c345c628437c41437ce9236223117b07b17d109f105f342a2219e48cedfd1e4394e1de2d3a0bd974c58b1332cb3b0849e40c1a19830511a6a65344fa501841471379896cc402b1a53fd7106180c89cb9634413816147c4549f67e6d24397f4eb82b7aee8d45ef2ecec441996fce5fe7c22a50925a223cad01314f9294293d026624b9feea89cbb31b69cde82e5ca23220c7d424c519f4e5135649ac54579764dff9158fcfc5891a3613ab9d65ba649148c541a5deb596777727a826e42a49b944824d98488dc44a0373a6dc22b92441699454091682659913c512672356acfd979a73b0d439774aa0a3983662163ace02574872ed9c9134f21f7357be71222aaffdd898488f291319634cc8c22a65a362137cd625291db9b40b1a53f9f0841c1ca1e9eef4b1a66a3594cda853c0aa91ae47da88fcc51395d79651228a66b335140666a1ee7e7e4fa285d1ca4db0316728604628cd9303444be9025164d64938804223662cb3c7861c8ef456c51cdd4fc8c99491a8bd8d2e76e8f21b6f4b7db6490319e1051fdec3615b1a910532e72464bf1e284dcef20c4543f0ba62b4c468022a67710db07b19188a8be75fb8888eaeb6822d3c8199d8405d146ce6822b7409f202ff1851cce1d34c4598688eab7b8f3e72ec9730d3175c41772bf81763ad56f2372bf89c8fd9d9db91345c5595983145738d13384123d4284a1064e044d9c23e008e28c789f997693b10a9ad812438018bb042b63da0c7194fbbac194410b42ad71b307c7449d64287778b7a7e9fe5dfef3b0e9662531695d550c8aa14924cf1c2c3bc2863268c917ecc4456822163f57f830a9a24891bec4b00c8aab89716856c8162a08c68499420499a4496654c3c8d5270e0cbc3083b4287a767777239948827690c8254c41f2874221c2483004fd04fdfc502c836415f45dfb72466155da54042919423e620a9f385f26206f83e509d8d82c7d105bfa920731c684913b9bcd0f28acf56a447bc368414131413287f1c746187d76421782854e8f248b7c801c95d820284b4e869e5d8876ec4242cf4e7368c7ae23f4ec9403bb761dd835eda1ec210d9be46dc8277cc427b2fc4c1256eed022cb5f3631280605d13c658eb56a1017689d97143a4a7c8ee8d66182c57efdc77cc18c881a4684636a9a0830b84294a1292da74882fc81d40167a36144efc7663981053fba10d149affff9a9a9694084912d883f3a37b042981042bae8f5a7799ad1c1d3902e7ae44e13e718611007618206bce83a48d8060e0262535c31a1cdcc17d90f0390e56d8833a40a628c3e6647a4cbbf8832f4f2a4fec804da9823d8981d6acc6067cd34733eb4c8da8fb78ef4a4adb15d5e9e6e5ce217b1e593f235629638a4f9b352fbd4dedd6f363314ea50167746091595914e8e99b19161a973d56031ac424dd4d502454d1d6f762fc8c15982176ee0830023da6d4c549f6a60c3c86363c665c26857990608f20307a771e41ef33e54f9d2b02f582c54354723b47d08eeb153563643eb4395352c6b59166ca4481c59e28989ead9d34f744ff360938707db393251488e44196ed607f1aa77337faad66bc534df411ce47b909b5588cad67462727227b6f4e3ec79e4889c3187e496526b91687411e95e0983251c4464799774633ad5a3eb7913d38c46d6da8b623ef06a7434127d640a32ba27bf5b9ff634e02df80f07b1074728d14d28d3e88ab0195baae4ce13d4fd79c57ce18932a1dcda73b6b68d63aa8285827c820aa89f9bb9e9c3710f4598c9d3a966429e3b1665b673aaccf950a5f05899b54f80f61139033322cf6f9916ac7422893cbf5db3b6d8309e05bfef8237766f573e617907af63748b858c22f81dbc8eef2016c2040de9e085c44e7d3ac07fffb01012963dab4943ca9f3cb17c42c3fa137d9f083cf7378c45babd90d2c15ba4dbd3906e71e920b60d630fdea29cc803ef8db090efa35b17f54b570eb10dde3b0de85d748969be8fb010fb9177d169bc8b70ec14f8efa11c228b8097c6298777f034de413c318dfd085f744ff3403ad51360405c7d380810f866f5b8b28f40a25be3ddcad8192957ce876885acb5d44f9e7a2ae4fe09a70f0ff3dcb7abcd356459a3bb7c8dce872a6fdbb34b6dd2d0b013b7cb5f903b3b4d828096fcf8c81596f1e4892d54d81096488e4c54b73c92fb579ddb4ce9014e963b71623151f44d66d0bc42c76727f3c1ce8e8f4f94b93f55e820622193cc9c91800a9c30740089945276cba6ddddd285ba58392af14952440335c6ce52e4f0b109108ddd48f639e79c73ce89a53c92e7e90d6dae4c7ffdba82f0ba2f735e71e412ec2573a80ce51902a28930f597e71ab2c441c835e41313d8d02501d488f6992977e6cbd430dd7246392a392f68864fb28fd91158ab4a9e248c01a358b52eed9a9846bb8957d42bb6a0601cb1e13699ac0d7d62d544c584aaec32511d635355a1abc246faaa186ddb3ab3b6b7296742b034dfd0acd6758955666aab1709565e073c2d833e7264a29640f54347e20c2901349b0911466aa18166048a2d68b0611fc97d7aa49768249d2476f7916f8fab1cddb7ebe8be5d88761d9c90ed9926638c38fc68ecec9eb28796cb30131ba23cd61128a04082fe749289a2bd83a491ec20a1d612b1859a7e620b7d88084b7f58320dbd4c2189f4ed2c456ca1a71963622d1c62cd23c40ca080a20a3aa0a2044248a1831c244890f8f4b060618dd0914148924c89058e13990faccca14492f9c0ce1c4a2448649034431259be590645999bfb210f6820f73128260a934155d8cbe201425225164d8276ac8462a2ba39196465108c9e257a7a7a7a321250613be7f280165f348f5944eacc588247a684953953c26648d896417c8999a8b89a1151fdda84c7090b6c189b0c6131c1ac41c87a6b96481aeb03e9543f74b1192d83886aab890ad5c407045fa062b0d288c61796437070e490a6e8a8740d97b4450b158d0000000083140000180c0a874342b170409ce7e2201f14000d8ba64a7e4c18c9a32087510819440c21860000000019001860b48d00628607bdae1afb40ffb997e327352707c5c08a31b0c6489061496de9c085263ce1ee420974353c2c846dddaa2970138d3b18366d0fbc58a44e6f2755c2a99ec67717316a3968f5c2933e9d4a07a9509afff7b4d8c0072a1b06556ee68ca99b16357f77514715f4bfcec3981594865e7c74ef684e03124c027f2215aada7ad1c71c1d48158e77b03cd4fc2c5f47fca94f3a3b503a6f068dc3a14d770f61384a75e19e8350a5c96202734b3c1e23cd2563cc4858b4615c368ac40e99074db6073aff19db91e526668a4a7072c223bd6307be64872dc40879a83d1ef899ce4bfb6b618c07a9be7434516b19268ca6a26f768c7541a9fac9b1395b16992975874c8297f399d93b2bc8546075c5dbb88b3094877b48c6ce5ebea85d175ac86f32b60086657cb4dcd95ba2c0381608813623b9345baa6bd30eb626d18c83cbb42ec939fb0fc90d535306a2a58205c5c511a1a5091ca9ab75e852704458f038fae6d9bf35f610fee3ae4ea846008f79f9c09d96d92200c10fc09486385854f58036b3fb8e650b2e1ed5cad70fd2614b82dbc82c225195a5c037425d75298ec532e34b3dac180fb07c17d37d9907ced04282a239fb43ab9e2727a1fd3026154f51b048ac9ef95c035f76782d4c597402d3a9d849ae540749b0f83a42a8d6d90c57e6d61464600f2a1f95574651e19dcef569e2995595c1efee95463d23adb4e1dc57d1a2de6e3917041a4677841e0d66b28ba49bc5175b51c8543c4b9f85fe166ed878dea8ab12655e8557bcb1afac9ea702558d69e64262721add1b9c861405efbf33ff7f7cd13d4cfeb2c795ac646914ad58a8ccfb8d15c581c7a7d40f073cfec2318cba85327ba13f730c068da5b202a9aaedfd3268591242487227c417d30b10c7591f0ac52c27b329bf3c217d124c148ae91b67433e3bc51c1ed8744d2289ab68817f53249a9e0e9ac40a71fd9266f51df2eee8a13697d6c8a226179a17e5640b9319b345329d930945838988a6d2b1c567ec232cec72f6ac0c7b9341589517e5ae624c635207b53de01dee30683cff6824f9fd8cb44cc91d345bed990a0c8dc0dd2545aece2162ac058f5990a5906c64d92d397ac8303eb0409117a34282b1c09f12035caa5027c31cfcc875681038f0e955ea9954fa93db312722d52529df8292fbf3ffac215e7c5615f635306ccabe11c97c65045162946e63c9057a3898b4e1b6782efa7c93a4ec95be695438ab73b740398d623f8d223a59820819336974526c021c28877a57bd7797f39353d1fff4350d8e1cae2164946f6acf09304d23b83869f0d0486503b7be90e812aecb82af5ca668363cd0a569900275cfce2ab009d49336b63c6a101e24932b70b82e239e16bfb2795cf7261e54dc7b53e49cced8d0e171a252640fcef3768e04be57755ddf9627e0143dcf5d536e1254271380209a0b18a602e8cf3f9c4d1efe12272acd42c954ed60825dca15a191e53d4a3a7385ba96ff26766a173d0794cc660df0fe26156fc029fab5ccb1262bedae6bde670e071cc74896c7f38fac9d5682547ace9172d764fed0504e834d9629ca27d0201d5c920e42c882c6485eba7d9224c6940e44220959dabb4a007a6eafea42f4b7b83cbf27bfc8705919388248198133531ffadcdcbcd56f9abc1822647196122029a7be49bc44c70f27d12df41546118e97af53939bf11e1cebe8340b1782d65e3b5875633abf152357bd10787073e6740d6ec3974ff5b4e4dc5fbab4a08ad7b963ee6b44f8f9e2fab6e2a120ac1ee66b8079d50d8bbeecea329d7f8f4cb4abcc816d77d9a3a407f0c786f636303394212d41cb90aab2a242cbebac4f6fb8b68f862c64f8995485fb4d4c566c09c6c928cbf6f4f4f775522e4f0671122003f418dfadeb5849d0ce0d775d16b852b500ceea511325f59d408aac02c3eaa75fdcd034ee001821539ffc9d73c79918ed6f981176616bd19494521bdc5834977e4466b16a8493e390eb3dfc251ff5ba78d2f1fed70467b114f50dfeb7969c8561238d03f4af733406d58a33b385cdba9062060e76790c65d4e4a652e92536c0249c3bbdf6cf9bcfbeb8a2317257cf0f0bf72bf651548189d29d586198623adbdb8329db4b4102da44fc92c9101fa8d40734f338817a3873031052d18e4e31cc6ed614822e4ee1fd7330e85259e1f6bbc3a49d534e4ab8b95882641385884e24e4cbf0f57a1551935c6c313910e4d24d957e54cd17522035c54238519f022732cf265b1fdbba166561e8f75912cc26d2389e762fc476b5eba6aaefb2cc6d87fb7742ab16807a8024882462a0b81f5f003e853a8af3760165530ca366954ac30601bb138321b6091c7ab1771b82736818a41113157ac72e446cdc877a21884d9e049dcf0a1c8ec227d75518a4baf78bfe9c60c8a51da32312b2bd00247b101c3a0c83b8677373f1b5cb4c527dce9df333139d690971ba4d263c570d21d7e14e22f70ad95a12d3710215d0c4ee0bcd3f475c2aa0550934d93feafd5052ab294d3885f34e0a33c1aff9f8442fcde8b8288da1144f2dc59cbd148f0ec47199e49684cc99fbf0f9d34cb47e86d0b42124188a2a9608fc1412ea4dfdcaad5a170a62428036542499f762a7368ea7b4ef9929636000e27ab13cde83b4c686b35f60d700d9b92b8c81684a068730b64dc00007587f7651d9316341b6707be0d78ca87c031bc46f60ff0a6a3feb8fb1b15d0a8b3024a0c20cfa818ffd458f5f386dd84e71df6b8561f86bfa9162384394a0fa5191dad7fa402ceb7eaee813d7e708a166012100651a13c761f4fa95355414d5b00e99116730ed2ec688d398b195c8691212905c3604e4b3fc171aa9098f86281bb1f2fcc8b79bbeb33a876a292bd1615ffe92f6875e6bd4e92e30350bdb859a6a6c30ed5ba14932b74540e29e3393735ca1805634b22e24f749396948c614e402f7221eb8341db72904d642b8e90f9d81b4c19e7dc8c6b9044f37755eaf65836cb796b7d5b2f7a57e79e95bbf458694503e43010ecb7e15194e2e5e8abc69d410e9bdeb47da050e3cfebed7bb28d6a0eda9dab852211e3f1c8aa61d4a6b87ecc2c0cc3d96200e086cb06a057355030262593a3aa3aaf06dcc05c091e4115da068d87211e456e48e8670f61537cffda54792aaa078bdb8a58f804948875811c155f0c5c6bf021162b14b78f017ac709d942374e81675084201990bc04711fa700eae9bb4139622beb02511e0368077aeed34718113eebaf255c0cd9e84897a0216f8f0d80439c42ce08b641eb4609550c1a8dc839c583a72b46c259c364135cbf95519ba2e6c07bb1126cdebd02c29e35c413bc09f3d2ab7192bd49dd8322d8c41e4246273c63db828c8c4a871590115d0c47233742654423fc0565dd3f745f59ad2800020eba82f74049a69fbd2ae31f4719b8744594a360c7053e621819262fee971119ecaee6417c5a2e40c984f8ba0511ce55283841a48ffdadde6034f69a0481da5356d607128adf1239e86c8060ae2ff24a230a3cf6869e0c7a1dacf47a5d7b523542d17349c9f5512b4ed8d9273d23684e6c953651c35a4aec9ad9d232fb29ec33f26213e242950131f49b21870cf5d13e943f498db245856e3e20631ef9e438027d07f35b8f216871591b2498410ff4cc5c2a49fd6cf44928ecd20a970d1716e4e060066dbe4465c5475512cac110eaa9ccaee36bcce727f7571b18b702ffcbf630e2d839008d363dbbb8c04113077513cfb21d616b9e8a57975615e217b90194a05f6e20959125dcc43562ac889ef8f15d87f61d35acbce8484a008f1b3addbec08bafcf7c5252c390ea0102a4d8ad9286f1c33b23890c77628a1f1ede59e88e41df705e8c7800435e2a33026f0c481eb8fe318112365407d4361c47c2fbc6afc9ff2a0eab5312528a3a090eb894341c9e9a56c496620f617703bd1dcd92d05b2eafc65caabc42ce362a121fd3c8fbe59c3263abf8dd979c0a25ae772e1bfb55a153566093f4dede7ecceeb347b07d90ffa5c990a1226ef0398666faea318efe3bed2be149e85db476684276718c4247e04f7970af61adecefbf5d971c639af891e5e079eb98e8e3eb27a8d1f540e37fb815a27205661236db8425d2c749e1a7fb1edad2cd9a9ce07ef05633e0be4c8018196f2f738e1f1db99e8a3f21655858e9309016c50007f9f38593bb32b81286d4ee4771a64bbc1b59e259b467a845383acd5d51a285d68e63e56ad0c58c1819459aca1af798c53cf05bf7bbea429fb01759ecf44521394c9f69b1c1edab754c8f752eb80942976c1f2ab15ba9f956d347d036d9fe6b1674dadfdf48c127bb2807d227612c209d8c370eb07c5297abfb93d671c7969004f132f4c01a378483b45fbe74bc9dede740bbc3a04be43c19e2f6baa03f662661e28360803f26592a234abb6c8852f19dbb10db288c75f89ced5494a66da9eb9e44d4bfde85244d64702f1182a9b867d22b0cd8690b37ecc1ea0532650ffcc3a03556e49cb0ebd03d5851b10fa199244231dff624088c4a9f6d8f622b14646a672e4c6fba9ea28bb27e6734922b49398f15d37ec9b6ef7f94916abb4df63e5c802d0ef67289a5d157aab46832c5f281bebba26b1228b94baf9bf8f8240c3088c86c6f089da104c7106f78a3d13aa6918e5811cc74508c82ee0b472d6e55421d64ac22350535c4465ee37cb3d1d062ad3bd5e960ccfd89905b62684f9f063c239536c8f370964f866e7715ad2dde7f03729dfb203a4849d3320dfe406bada3363f2fe0e9de3d9a1928d06932471682d598db0abd0e28bff96ffa41b966c8b162e335c1ffafe241bedbdcaceee3f695c9bfe9381f35cac15b0c38a578a0da2760fbf93f4eabd2d1ed969caa04709f57dc274de1b35120e30cc68825660a31e2a5134f749b2c25fa4273d21a51c7a8aec8987a9780c1a4c69440a37745bf360220bd646fd06a710c3f9be977b793ed9a10a89372cfcbca3175001505b4f2dfdb4dd6c00fdfc623299202b95e1492935e4eef5241c75919cbe1d62ef7d49dcd22beda0da22c26db1a98c3250207254f40e2ca469788abe28e60541c6219357e7cb6058521b352756f68d28c883f70310fd94e01178ca2925848cc952f7b55fe3f5b2e00592b4a3e900032d46d1bbd40262c05a78ba3619e26aed24bc4b681ff97e0515e909e26fbb8270a4c9d97829df39d22f1036834d31a7b06a9a398f6018cca5a04df981a30ebc332ee016527a101bf9f537ac8ef50cb5bdf83d409fb1a96d72608da24b9993687560c33879029266a53b397bd6621856e510280ae19da8dffb1da775a51857979aee9c1b2812f7287873e8fe6b8fb3f95dbb15d233a1f3ed0a818ff671c3a395ffd9f954674800c3af45f2d94b8443dcc1f3104766083b71082aeef22f40e8abab5208af1f79ebcc19fb841b0f3c0ebe5ca636a3edf111e79404ff15cdb62c9cfc5a3d39d76d5f8297a13fc11d8da2e40ddacdb6f4ec0b52bcf098d0b544405b1b243131c23c0d48e9fc7e7c5febaa2a2875a8e5c421045d6dadf5b904944468f5a0fa93a71b5c41dad3fe19fda92723bb4dbd86e4f7f3429e66fb326470daa4d047c3eb23c1abdeb3bf91a16b67e0fe3ec023f76fc99c329c2ba05d75812b313250beb0c05a049c04dd74f9222db0bc29c14a2fddf76a60012114f913498285289cf7f96149c1e66bf8ec66201a80ba7b479d478ac6fe18aeaeb96a692bf36547c78ba32e97f59eb52fdcdc7f1cbfcd9677cb896fac05b718cdd3492336468dac9da2705b63d08ebb5cc8a9e52983358621c5c3ab6701d80e7480fb10966b6a3624d1a1bf94f7862477df7abf62af5965f984398216d8f4930e3c6160c0b9c9bbb771c5306be56a5a10b07973207dbb42afdca03c045241077a37151104085067f980f54cc70544b16187d45231a718018fc8131182f3c429908e426e7b8ead2439d1d4761b4d516dc89a71b6cee25ca89b3083944b19268bb4b51a2c3d49c020d9b1d1592297553a38cca8644e2231983fc526bd7f9a15cb36888f5f08a6a8e21df4c959b1f6b6784d8dbf7479821c47c27917dd804b79cfc96986ec1df61b8bd04d7637ab6b39469a773acce47ac4d34f072c54466c978692a1e3c85a7975f90fbba33cc38b257638f1069cca3b47ca15406fba6af7e8ed127de7f3074331f232fdb18f12a86e29e7f86ed692c710c6ff74e07ee390268572264eb0df42e504801827821136c2c20b0cd670e9e92b5fb730ecf6c6abe183253916875f1c37c40f035befa1050afda8adb3fc28458aa113810f2922229e229f08c299d4a8a8ce0ce1866d1a0dcfe7bb27f21acf24c43033d295ea8fa097b94c83f3816eb19045e6b1b39ea906d251993d53d55480db661563b1ec6b0cb36d03e55a016cdb89292da34e08e179e2eb28818d95ef5b881cd035c3dc559934b9d8bafe4bde69b865cbd9be2ad4ca7fb234274d95a2b7325618d106e54d8b4ee736132f0e0854727c15be2794b37c0414a54d89e60cda5c7189f213a28025646c555f2640759771a6526538db1c2a41c3f95e6e231ec59e6e0c64a3f9d590bd703af29e7546f8c8a4d680e8bc4a756e0557bd719aa0a885a4583d9b1653f6e01fc9e65b225c12333a3709809e431f8327cca9efb862253c64ca2683773eb78eaacfc1c07bbf07cb0b987f0bd82f2ae3ed7ccd3493b4151d7748fb640b8998478008edc8ea9c746ffa54703f235349a9f040e6866b1989113d064d0bafea15a88625ea7d09c923a8940b74944c73bbbdc9ca18a3ce4ca53102436e24a8bdbcbf7e2b9ebe3a9db201bacfee7a7fc532af8e73a1d7f5917f63b52bf9c36cb5da2c5f4c8d90218b390ad98579f7f661c2afc818015eefd707c9386629e8f4147ceef50e4a4a9de77a574980947bd891146c0f88fb6636c1025c3491ad48395fc1104b4f819124354c26347a5b03230cf0c0eaf54269bfbfbc7cf3ec23480a6a9909c1727db3c0392993c332c9efef8565624840dfcdfef80681c5d803009cd2abc50e0d33a5c120ef1b93ae73756945ecc203967f25598a90c845c2049f5fb8da3bb952187946c820faaa7bdd84f24bcf7d6b3cb630d2302aaf334651025875b762363f3f0d896c0fa43bca885c1725411b32619c47927d7cbecd6e16e4bc216bb0c6e8fd85fcbd9786abfa4fad9f0803ec11dada9a971a319c17e5f4266ac96251ee9a30beb28ce8d6cdfbf7c25596a48ed12112499580306b3425989eb52ac3439b96916467af337b6d6831de854af6e81884c80e187b9975ae6ad9cb9779fb310ffe17c9b2efdca7a835cc3532883e36c444b9909910108a65e033abbb7b050431f5ce27049108b97f4a3d8b5efe5e2fdaaf340429b8e4c548468f1bb312b12832c1b8dae39db1a438b51bb4ef492594664aee7e694c278b8a7b77de51fabd9fd938265dd22289ad49c5d340939f9e950a7e0d14473c7448eb6bc8ad2131223cdce37689592259ed4e6dd0e32e8a6344f88928ff66a1f5136c9c4b980693be0de0af7fa5cb0919523d55078a17eb8efe8f6b5b1965d35f5ef237eb8e46e2336cd437c57c892393259f241705b7bee0dca7b7a80cd073ae8aaea5d8a6dc89dde5109be94a2ed11b35b4d8cda6f8d61c055492e92517aaaec534ed527c0fefb482c8a2288de0330d6ea5094ad2838aede9c554859fa0c22623d18fd120166e49ecf970e63a1357ef70a7c830a8ca64cba4009d94639b29e6c95e3925f522bcac6b91b4d5ca75ed383f4dfb5063cb3bef9ca551454c044d29f618100a7ec1a78ab22582ee6472829230fbfde79cd54fbe284d893b5e5e2742b60f43b91528f91a1da137d64a4a9585be30b30e8f77eb1be799d8097a8990c6ec04c9d6f7f1f99e8678cc4f21a26f519aa3c3a16091fb9470f882a95957ef828c85c6415925cdb80b4b08b706e25dfacac1748d2cf3d77f96db445be5aacfd4ca5e755606e2601f042c45787794452f91d7a91bb4f4c5e42861d542b75ec6a10017436a247dcaaffaf751cc0389bbe19a40991c3c33ae166f0617d0ee1a013c49d5c4159f1f068f1456acbf894413f8330b027bc5845d93c84a5666e2943cd39b0f4dca5e87e38cbc53aa5e904d6ef70bb21f0b6b2b3244161b990d808a66826d04eb60f50da8d071d7f47e4a5c3fd2d9f7b4e1e0d8c0bf8a96dd7bf4b0d6c10ec1fd0aa18f524d97939b2749e4be3edd4a603afbd8be4312467102d1c5ef0f2107d514bfe681f5d5b64702bf0d4aa00643d1e13b30512ab8e61400949639ce12063e6dd402666e3ec437a24aae3e864835d4fc6fb38542625f60d5ab26bda6d1806e4b70f85b872819906c3a43f5a23c084962958adfdc1eb9a84ac70d4ad690306ac0c33ca56a76d1bad5bae88feec72256ce13578550e1a6b895ad964073ea0c2d571aced296e48c92e1fb358af3f810656a0da77c47a681eabe1c36069b4c7b0299b0faef33ff828eb1761f7f75e2a9cfe921d882ee73d262050d383335e924e0588ec6265f1b380b7b3957ef0c9ba0af2a51729a0d16484c9263d7c2a8e960707416ace6a1f31450c8263c3531beb2ceade9f05737180cc2723685368ae1302cd054111ad9e82bfb0ac0054c1946e81c720c8f83345d749d29562debdc520d595dff094aecaa3b71307017e3665c50f5044747a4116feeb6af777ac391d60735d04739d6b6ffe42fe970f01aedf0d308d965cd4bcae1083d6b1fe7428e8fe6e6003702571e299da69044f30f6547cc7565be556c517e9680ad87fbd339b48bdd93afa66873ca2f0e3355801d64d7659a050b7704fe37acbb43a237bafa8f573facad95cd93aeb74e850ef383f866db75ea8672014e23d2a1f217e984d2e8c1ccf85dfcd9837ad3143d3931867fd56d91f118d5888c04267a79cc408890d8739bafd490bc3021d5738497ebb59952fb28d18627692b51125a36858dd7f121ba7b8e2533fc70e9959c0188057b24c853c5597cbc484fcc741d16d30d35a69abf55471ec44cef6a7c28e04134105488fa66a503d20253310828d89aedd00137d1c24a6b311603104696dfce1ab0d69729d676acc8613b8c2e718e601debcec66092ee4727784e94355b6701d42de6e0605d90a983c6635a74dd9027bc5f57b969863efc1f6328fbbb1c8f2f1237382bdf13c01b1a68729fddb928b73a23e579b9d60d9f6f6a13348218f7bd20819e9a9293ff7c2489e4a69f98f77b12eea61bb57df466960334794f41589fc96261f28e7cb3c807808f18adf09c4fd3e6dde7500590712400b0d3cdf905a24b1c5bcf9a63134aeb1827d71debd7cc6dab84187c7e3c379847de41a796567144b00893d94b39df68efb733746b0f8028fa83640f158ed8b40bda609cb7f53436cd55f9499a6daf7662cdcad645e721b0813e3f4bdcb57fbeee427ae10ad2e9ac1e852588cc261603e8b984f5e4e94f3e97f9d8b4f6bb44d2b0ff7e9f93468a8612a24f0da13b94874f1a0096eb23763961a99116ce80cd3cd1ffcefc8ca8b33100cdca2f4b0091a4c05800a4a60914debae28d5707451154a325447d4cdfd6eebb9488225ec69cdc962f93b7e1f952ef5c6ae8f8326df8e362d6c1ea2efffd7579681734c23b637824883943b588a757eef5de1181081c07495c7c3ac01092c0baf4d648a54adf7ae347ff9c6359c213b49a81a795f64a14400b5a8fbdca5333b80122195d96709f8c9e3042c2063c8587e3ce9fcd1c3ad0527144b2d99c95cb1966b8c2648c9c11c1a30ad7c5bc46dd168aca9d4527466b2862991613f10fc96b8b225b8bf5a0c941e0a7a47ac3b19fa0f02b888ae93c6afb0729b52c1a3bb038a8daa25b73695d8ca4a960331a65267c0c13ccfa0f234134ae8696bc7846e37c744859718411a7658fecebf6c371d1ba114dc6d7e19e92e2bc772bbcf076fefa78ed5bf916c7431490e0c49801d2eeacf3d8e9f6bbbd2673c7836c4db574eaa25fa0626b82085ebeb8721e98dada40716b49bc47c77ceb46a40c6ed8e575e75c3f96c3fc186e328050d687e57fea9586bdefb1f29b32fba775fd5f7b2bff3f5f109d243b5f45516ea67de051c45719003d14b7940c4f5ae016faeaa00e7d9cf900309370f48f76973a6d41817cee190c4377c18e37639673936e865ca289b498a64f1457e8ad064151e87ddbea0268786fb15624ff1b5027fcedb9a1c7919856653a2fcd76f5286965c6b5c284691e94edbc98fd19cb81d92b1f11f9202464084cd3a645814e0d0568396e02ca72e64709c0fe891678b2a280d78ec435b5e65cf80faf27b67b31ac960098bc9f1539f5ddd76829adc8c84f529230d97a601ff8831dadf23a927826b169b4fa450678ae6876a81b05168381c21ead4a65a8475b657e12fed4eb040ce8e4358621e61cbfd79762478f948c4c98d90867d244b10dd3dd917c844f111f683a39922a2ed0c5665b1f40c17c21c4f5e34d4ec1202892fd68cdc390336fc7635f067121eeff5894d696bb22615b9ba04b08aaae208e70056b5cfb3c7f037176951f0b42719a1871ae12635ec3faa2740cdf1022a6c7597d0d09f243a19b2320c4e4d94d6e1bde4af0e310ec4796b178af415b80ba4780f045db65a3b8484f65556d88be28624466a675d6ed55844afc335a9b6a35c14d5218257b5bdb2bb28f481e5055307a4792da78ebfa5e5bb1b8aa77c55aeb27c515ce57739dd690ed3b77348150467808aeb64dc2252d8a8cd83222b599a173363ae9f40c1a48ec84e93c0009f2acad20fbf9295d03cc597e28ccb27022f861b8e0d895b28d597ead89ad120a269cfcf71567f984c1e29071bd6e4a46f00bf793a16770f899f2c5080287495df92945972b825897c96237b2d42beffe64621e9068ea3d83d6b75930d57d40ea0fc88dd22e5d0571ad8c181ebc05d0ffd8c7aaea29eadd323c57b405ca2c5045ff53aa3b12870b42ad5af5c69376ed4c128213ae66dbd9ec3d4444fad85a7075513bd444e0f8a7250dc0a3741f2b4af687ca3251e9acea3a5687e4748f00a06e4e490e088e40ce20b732a3e7ebeafec9a6711db1fcec9333660171aab313aabd25696dbdc6443e820a5f1ae43a3a9f411b321e0ce47ed072aed688ba36cc6052fc231427974a93e83d91d25ae8d9322abfbec95a875df97fcf56bc679ac7f062584d3f244d6e28bfaaecdd78c8674e88b55c2c97730906c3ed27d1cb97a1566b9f0f00ebdaec9019df914719de311e1a98010012b04db445539417487928dda744d5a72daa1986921f625d0282e94fb8e671d8bcb76380a8d475df23d3d60e7bc83e2361d860be83427592e15864c454eafee81397d5a601ec49a5fb5e79ba18722bdfd556f7978c0afc7bd15d0b01b2c0bea72af2383dafdb9f2729b2d976b71f28e8ba86b8c6e0bac7febf26b6e2550aa2810f2efb39781981ce990dcae355caef5f80f62824cf324f901c8011b404c708997a1ae19864e3f11e050959ec6b15aca471b17fd62a46ea7625f4e1b01cbe02b3a511a185960a715306f3b6658e3fb2fec74a1da54ae2a8132977bcf40759617e3094457ad059f36a2446e1f4745ca015cec3ad6f1af4c7c899d258af398b07c484b9040e249e0ec07d0b7cc1a4a405824a1e440cec3814da7af763aa0c42854161e3979b5d74de5a4449886ff8c36e22859072351901993ca87422fe7ffe4193164b185346dd82b89a2f7ccf60237c3bc52241cf475fa2c073fd639869f07a89406f75bf97f1d6a2726f1f6e065e382f700c4b13977b02e26542bf9608668310175ed9f69ef3004ab41a3994319a9fceb397b3eded87c3942df923a102e913e92d9ade92d6e39c7a95b3de92eb6192d5d3e2a9e81df30a9b807a51a4ee4e89afef2438bd146341b5b0c21b863b821b0a6ef4c36d104ea08f9d294e93059400bc9e9fa5387ec31f9f1b81a21e331fa0b96054e9c554f867dc40223af5cba662018930334467196fa3ff599e0dab1522c9beacf43387b0cc8b34f033627e81439d3f8fa5ee3729c3f57ff6e937d0952150ef75c728b3e6d67bd9843482cf48f9aa1d004c24977b56aa024f7518ec7d283e83ba8f7e511f9c0f50baf1368d791f805f52e6b8822f98d9bf91bee8832ec104233cc007700b6cd8d8852a9efcc9ff5bc8fef8d4041207a7795af176472fb0da6aa9a85f8502b70b41c2fb70ea286a1424e1c84537da386753c3c2a96666c521defd8be2082768e90f1109e677c4c836819cc88d2ae85cf5431a0872ecba05c421d0c3ab473c0e2c0f7c63a9fc55839a70b0b93e8e51c25432ef1032f8eac30e43e3aeb7df872e8a87feb378637f7104746ba3b77e1a6b3304ce5aa88ba42d8532bf064a911589b8eb8436b988a4bcf4174a2066e714d105a6cc8ece993df3a6d91551d858603c853e88fe1ad59cb64540e0ff0cf53da6258c87e5862b8d8edd13fc1e4713fd16f2aba3bbd356af62574d3c0139fc55559a6066d908551a34bbc576e5cb688cbff6acd00cf49cbe1adb5c4397335d40b0071e247c903eacc0e4a68ca3afb62e4c4a650d775fd5e4a4dab5ee27883ddaab2a1c0b5dd7d1998270e37ffed63f220eb1c6d9915a78c5cd2b3954c3bf0bfae030874e8fa17b5bb59c141046e4c724c2e20daef4c82e1306484923990bf7185a4bb8c2ec5595accc2e99605b865ba8dd15e0891b57da8264a71ab3fc267e1a32d2054d1817993d6b596656c65eb635a8cd0c2bd255b381dd6ca1d73753f20b59178cd1bda4d6a612fa15fa6f62419f5ca5947a5f666d32d790e8d60cd064373654ad147a47f401cc37d800311dbbd2ae7dcfddd1f2f8d95de384d6efdefc55e3dfff87a111195be01a1b59166d8016ac40695e8b50e30e34f1ab02338901ae5f101f011bea97f90386dffbef87a6de33b64b6a6db42cdb134d1505cea1aba117bff7927b6d32c4d5720c8182f699c1d3cd073a68e6ceeac122c96d1eff180ece1303b0ed8c254501da78a1c2f1abebf8e9124fe81bfb08c84469c200b715eef0d7ffc7871ef4ead83eaeb961d9602769c104f6d37284f4a7a5a9cf13596bb34fde37151e8df0f21970a3be913f52fcf9fffed0943e4fc59275d2291a87cbf3e71738b359d5b7230754b68a4ce85709ebcdc98f4e6f52e66a02f01daaf1d512a416a375982d138696206c89f31568c8fad663078d804bd53f657de6c7287effff7de84aa063fbb8e646cb808da45d12384e6b84d0adef87febcf70c9891195d08d4e6bf58d1a21ae983a01ff8a0c4b1a59970aa892722f4976139dd51304fd15b291e05178d4a63ac3655845f23bcce9e1ed9eec8026ec74da1fc3cc12fdf59df342160e1829fe90286226758fdf284e4d6e286b1201e2161c1a7534bfee7885062c1960d390de077d0ac3d5895d8b43af33c4287b34e5fa7841ba73722972d566db4d9fd28276ae28c3bef3236fcb4c6c7466057fcbb73ab9b2ff250df546101e259bef6b91b9bf6fe354b45660c5b05c36bf9e78c7a9c7269cd1ffc7648b285d729240b1c183bfe36c9dd348def7b44bceaff1f1b43ba1e94878722fd1744e24097a2bd67a760ecb8f31b1d506085028f63562b716581ccce300ed36f9b87d78498bce9cc63ad17c58cc6da32bda4a63132ea3cec0de5534c770c4facdccfb73f97245a2700929129aa3e774656b18ce47f44f5ab4a89ca086265493e1f45abdce1cb727cbdfe9dcf90da5484788a7b330c3d97d01c7bb8d4e051b6a87159079599b4f04b15e7f08ca4bc7cb2128d018c2ef5ddf4517ae5f35f05bfee049eff138a9bb8a717997c62ceb77d91cb9b1f517c0a5aee084af9f7e22b586e210597d33a5d392217f97e95cbf30337dba09ff5555631668a87ece94740ed49f475b82647209a400fba51baa9e12efa475ad5a456359be11f2f9e7180a61dc9943d5ca236b5f9b4cbf7fae8be445cb1d189c310ae8275e6b24696d1ba5a9b2c12ea22bb10d80438bc79af361c4066492b3d4ee12ae3b1d03dad55f78803a395e30573ccaa678c54cc6aa92cceb5d90d5a90d4063f7794f3d111c8a413178bbe4bdec5937e668268f2b3dc8fd5065313795b6a25167e3aec9de7c9bd1d1b10b817bc2c34c375fc71f479d3051bf6b562e013f9b0f99c2f67a2278e4cb75a7d2be0c2075fc8b5f33857a54ff423922f4acd89f8ce79e3ba4fdceed7719ab91fc361b647b79dd671175dac08b2e50f0968619bac5659c591e35c8f6d3e9a935b8ab8d5d82e0f57bdf9fef91b9fd6c0ed88a20571c619c9e5eaeb955db03e94eb2b1a435876d38f8f767c4d0366ffe8963e8154ab042fc94f4001a5397150b12e169d154930ca42980c41945b31025369fc40b839c275517cf4268e84104cbb83a5e85478d22181537209e56d0d37fe4af4d162ae371aaf6f63991f8233d77dd2a9d2d66c9391cf7f2af6f972b82237780303ff0acd31be0bd5eb1f37711868d430f000d4a338330d917ddbc8f059abdb0581005e13fb645f1af29088ddb3457d2259898c1fc54c83b94bf2faeec7ccb34f40df3511c88549703c0b361a7b0c3261dadd19f960e093f01abc235983152a9e14ca00e06d9cd19220170d90b8fad7e87b68a6b64611dce2ecf05d54ad871dd4684cb57330e5c0a8b0350e1610fbc593125a338fe97949ab427fb3ae97f33d08e12e4d3b74302481691c06fdd3ef1ea631b3cd7ad9ea1dc2689081e4f609959359d9c5c4ce268ec23f967cb2ef53af6f9d04029f05f7fda2d4a22646cc26cdafe5c0892012fa0a6753407fd671c1a59d73890f6481300c04121e5ab354448bb34d9870c1dc3d69c75abe124010becf4b456b444d0921ce64463ab12e933c971a930ccfa1678c86b9f7ed2eec857214f463b43989008a5c165b0c24cdfeb7e1860990b7135fb8319a7ccfd9a1104ff3ad6b5d1aa3ad51a734781d1e33dfa5cdd0bdbee9b26999a3f776fac94cd39ae19914e0aaa0744eb422e9b98d84ad5fc7b47da148c88926c916331a1d51c616352cd4111ba3f3d77949347b844432210af0d53efeb1ffa78d30b3820a08ec9913c171207c56a86a4e3ff364a4e8774fcb1c30c85fcab65f4ee540469e1e85b4f03a167940cb6099cbcd566e6197dd6f7110bf087ba164479c5fc203fd6c4661836b4dec8808a7597d8ccd43dc086d3c0fc87885546b21b1c58df4b1409267f82b4c196d93924b4bc5885fcd17d97b2b751791fe64fa21c1044c9b905737769917efcaf510a2b257a2ed5d197f536a009bebfd82c5a3c754fa5f365daf2a075875d92c9df63dad3f2c8dd977803a46c7363eb45dffeeedd59bd2fab8dea7a949aec59f3fcdb58610d1ea35957e249b3ffcf39491e4cf50b9fcb75815cfa3a6d7b6eebfc61e8b226b054f1347bff07d3c681fda6709ebb1f54b5a2eaa087c7a48ae7bacdd8a6012b8e866ad8e25b5d271d11a369462582a686938b79162ca33b8581242c40f8e623d274b6b030808daddf556787808c28148457a3f4195d5bdd4c60d8ab9d2add4fb49c1d5ee8630813ddd8d4ccac2bcb5d479db2f8d0756acac1e4b84db705d3fc54d0f78c16d343ea84d8e4f6dbfe64bd6ef6982dc2814e19dea1e8b442784e86bccf37118343ae302e95a26005381d43b4846e5873e1c815c18f456270f1c5ea4fb9601d01bffe4718745561397f3e132f14df213d42bae99ed8b13c4bea4fdbe026ab82c345d19429aaae2c00f78dafa8a9799486c4faf4f487c91b1f4f0de324b9f580989d0631f4f74cf6d63f9dd727a94a94db30029a06770f11be353ff5e71d3635d47592fdfb1bed6d1cb940eebca73c01c0ae17d7b9b803c7f9ed8b1e333aa6deb53a72b804843a31d10fb74375d378843ede6186da44ee83be5e8de78db31e58a1180f0f7957d4e21e9c7e5ef046f6e2bb291205ca674ea22915aa36ce9faf73a856b63e010be1d8e9f5924f6668d2f144c3f3f35614dc808101c0793877b3f53a7f8b96c29d2c7281f45450c27a3b6f62ff30bc51d3667f1aaccd18179dabeff0746117c47247a905a4b564c4bd5d1e5cfd2b9667fe657498026ac77dfc22df02398351d82f4982f7741a6fc9fc790bd3116b210c020d7941f7404a4733e950453dd04a8e9bbe48f3c2eb3ed7def4be2f172fc69eb551431ab0e9b530c4eefa7b5d5e42f7f26c7973f3eee7dd5c65becfe7387d9b2ee3f6fa907d19c2df3ec01401debfecb1d266eec8283ab30401d17d462a667df3e920ffe9af30e2259ed8967a65921988c96850e4786da3f083449086d50c02b9593441bb72ba7c1b66455dfeecaa1c79f021e3ec84c1b580d928a2e3901fcc05c2f43eca28fbc12c3c8a33a0ab94ea3e53f52e270c024494b9010c2fc945c5e11b3641c7112420be99459fdc2cc9fdb7336bd5e13882d6c2954819a04a05861710c4eef55992a978acbef0e040a0408c836dbdbe4061a366c36fc6068e8bfd9c7ec889af00e72a81109b0482ccf257b660ee7b5d20f85fa8abc3333ad29e1a70f8d2221f6989fed0a4951e3d663374e388ce0dff6fe171507e53cf8a8fd3c85db761ed251fb599d7d7515a657a0e2400f20497fe7f51fbd8ff9b1b8c67c145738ca58c57b2cf38506a243370a3c71fa9d5637a337855a8b78cf610613c94c419447526ffe84d9226c102d2f29daba57a780f1831d10264baac003bf984b3f47f18e37c37cd455781d7b3a6de687af9dcf18ba8086f1228f9c49dd73818793ff97715ba3dc67693fde399a8c6f0ba498ba420cf2420135214cfdd89011f710fdd80af0f288f4061b62dd24175967fc9045203f01e7ef298092ee97d64b8db07fbc335acde38ea0e201f83185a3efa0d87aece6dc907365070ee5dc5e0e7c5034e9fea5a804ef7eece687d6f088e7adee2275b2b888bcf0d510b3ca98d550fcfb7811306d8c9bacdbe6109c66355965bcf819a678996009a8e8a10b41176a1e368bbef54ff0a128b2e8c2d4a52b31243704101d71beac519ac3f10aead0e9ec6a5e4550fad8c54151f35e5e4b5bba53fcb20abc57c413a2607db266d6b5be8511dd1ee54bf7c83313acfa2c606305f0c701fafd50b58188ffbe11c71f50875c5e9201f520aa7f0b6a9dada402fbf6dc3548b15317fed91cbea69c8fa3a1f426e206c5bbb3f7506002824bbc2b834f28bbbc6689fedb14d6e14ecafa532d10b8f328a1cecb28402affe93b5664f5302a76bd085d124d656b6ccab8b85d1ba21c287d68a1284777de096be4ca8f89e98e4ed65404f5293f966d179300708f97c7c2ab961d5e1202afb389445add2318ae66b554b8d91332a782e4e49e6a473fb79e8466b34e16d8f3e4864a31e53b98840a65cb50c01c8030c7952966618d8a530cfbeb29764056f2c168efc00774512338169e582347617ba91bebdf60ac71b8371066e1b3f5573d3c5df5641f25b57fcd4b572f8a5a9c9b5fcc57ba58778653173d5fdf71aa87e8a8e7e8a4baa0002246c176efbc41d425ba12db094b8e64c706865931268c3330fad6effc93ae9e662d2b99ce5b51c1fa265005f25f15346528ba902fd30a0e3066b24608d677a850a14373b904e1c38412ac7fe332266b245e166301a26db75baff4a675aacfea15b9c64cb9add13b2ceb5b588cb3e7732a8546d53321002a384013319da24ae808d02b761033a6ee1fc57d430c54b4a0f8689c344e9ee9e5a383a832c54ae5e65dab3a16fc56f200970aef5687587c055e35a41d4af49dca9425950c7b03fa04eb8a665c34c1802e257ef3df5b002ee01a709584ce6e7c230ddade4691b50622da9d0f65cb4bcaba29b902a2da60eae7a467a9e71ce51632795416d279872e267b26bbe98396b9ea6760459fe23eb1af443f024f4b47fa5a0b4ec2766ba9e5ac8701ab033b536335917aa21024947d324c04057eb812753f8b77fcb0b0d490cbdd5c487ff0c1b916fb1620e4d6353873bc7775b755626f827352dd3dfcca7057d05e3db356f8519708239e63ed51035742498451878dc444eccd3ab5775b6450cda8742de5f380548f5e769fdab294ab3b4356fd91fbf0a8bc10c2e7ad3e2e55c92156d046af0571d9da3b28d460074e35478c0df8d7902e12012f8c61454b8399232538206deefedf20b0ef564a4eb504bc379ff4fbf80e38d5fd03f37a8cfc3b853f7546c879aaa6d21c99c9962555dddca49cb2715cc86f28fc868ee023dfc724bc89f075d7af1d81ee88bf4fada419e2e6c016fcc5073369c186f4427417e150e2879c86112c13f61bcb9a97368832af2a9e06f182ad3556bd93b434f03e8bc507dd231d7d56de8a0de4474318f9b7a613ddb4357ee4b37be0333d0f2c8d747ec185dfe7f69b9084d5b6b53910b01a74caedcddf79bffd3f035cb1d900a38739d7f45b29e9f7418fa07353f7a3ff07025d3fbdba2621b6c7fa0569e0a74292fa6d792af2b25f804176651387b73b181ef324aae94168a8f4f81d318f06f9ffd617de22821bd28d1b9017c6e7bdf0ececfbf18fdfd7bcffaf2bbadb522714c3d67e7aa12bd20299c20507abc7e2867ca6b39d0c253ab94ad8ccc02688fc7a887f802fe5f5a8c284a3be640362fa8af2c55a9ab38e923c4246603c39521a751d04930b043ad947b5022617dd64ffd8982c3dc153abce2937d5c544994cd69a2d54302e69e97a99e9f42ee2003dee33c67545c6b4e57b6284fff0344c7dea9bad1f014b335d7d39e2a240b6183e17dc9a0db7c17ba5cdfce15eb1f0733d059251e390353211db06071e909907af6ffec9e52e02eba2def6e40e340cdd5cf4dbdb1aa9c3c257cb22930936376b16ef0507963a54570e8f02c7e0525e83430889f33ecfb024ac44cca9937a9bb746a8ccf279e5d7f748d8558a774aa7e3f2803f86b0715d49345fb36724d06de20f8b0606a18451c662bd35601dce441b86ef1907022ae11a7c87341f62d063e5dfd6be5dd1225101f5412d340003248945c9fb9df7fa265e84679e600a1abb15c0dfbf45c050331f43675d8ba296ff00530754fe991a46137c216298df5706588bfa80fb779ba20a3f1f94c14f5832e6ee1afe190a1708c773796878f9cfd4b5a6f6ef531a31ce784f5d531c9ae1cee7c6b611d17f328e69953199c48cf902f5a206865b5ebff55090c66710084e8f0372f80c51419a77d12b388c00cc840428809a6b83050a2a660e3e5367badc8572db4ee333beeedb0139d72e103c9d9a03ed7bbdca9d9a06f9a17d4eb714cee7ed62df778772e8a81896454a1cc8f58c34e3fb74a60b19691bbfa238691c624279862ce434b8ac9e786734e2fcdd8acfc085860cf992eef37b5def6085accdf6f284a824984cfa1600ea710114949735afee0951e9fde04f09761c5a8a6e9064ab8f69bbeebecc5ceb070af858e9837c0747e4511542e21cdfc99556051ac94fa44ec01cb2e14b5641e5e33a229dc858246dce5339f74ec46d44a5e1dc8b45cb5b51e075c6b40d395126c5883bb87a4c62cb13c2b7d9a25a47afd0de4122c6d15cb4578539fa51a43f1cf6721c770f8fa4e41db134df9fd1af59a4b74cadc5c3420aadf2e02024780ddd1e320a1af632b002aac3635e75000feaf41b5758cf62eba81783bb7a3dae55af842964ef46d1747390d3f1c80e774e42f53fc760e7da7f097fc231942e06a91deaa8b8d18316e7d610a1aa27a73a58cd04381e30222c033c3205769b4be4de8545371a9fc4b2626b4b165fa08a7d0262ef024a1724e06077f1b54c6c4ee5dd9dc6f3e6a22b17df717326f689cd014fbf1e14800f14e1d4b04225288265d303ad3a167951599b43ae2d0b0a111cbebefd654926a4774eec0d3b97288167f6bb27e0b96a0f82faa8b2e13d0d4b8301b16aada9478cb8539d3da5797ecd60206f6295dac05a809b266ee39965116d346fc8aa4e2ea0964d18336412a14d1fefc763590d972acfd70e39900602942324b7ffb2142a1abc461dd50717125d06b953373f88bb64c6f72c4d5ba14a740d68733a11c9a22f386979ceeed2653c5d5b13b61b8fb3c67560a0a187b443e4fe5aadf7dd9dac47390c4437569894e779df2b5a7f57d6a4ba449ffd8ac9438e11fd3c88bd327378b4dc410fd3c2358455f1a9bec3241dae84b3ad5b6e847c370b47fe2d82feb88387887595ed99bbc1ce21dea7b189e98eee403315b48fdc1dbbeae94f72c9cce4d8a6bcf420c57bcc13265fdc9ab4954f52aedab343de063298f3ae6d2cdfb5ddba3ea6e27dfbc07cd807f2f2b817e6cea1f9be30dc53ed779730973c903925c69df96ee75ad45c9e01bebddd27b72995eaf50f70be3c6eaa85dfaa490ec1aed418531475c64231c2eb5fbb9b070da55a27191703502c632eff3fb6e8fdea0fbd0866568105b609b9806587af021b0e1f2f827354369587d78b5e7a7db95e2146887f4d4ce1022c670f269a2abead3b17199fbaf0ceed703e06d6e56891d6ab642782e7708917fc252d0aa663a8c3e63d8b5deb91f1b548e56c0aa7192e82826544aba0bc698e10cb4e9d1c0eaf9bbdea40ceef248bf896f25b40c7fa8b762d7572d197f4ee686e018bbd064f29f2dbffa32ed90726d183e05cfd02a84767336a1fd7c23663815093f2ead7620cb68f0760f0c2d736c9fa79322dd66f5068770fd7eaff4da3a96c887ab32f2d00454efd616e464a4f3518491fc0c24d2dbe0acca9aed5fdec2becd6910dde915dd61956685374929a46573a2dc0beeb81cf90f799a1adcd1324f547d5650978a904bc17270f8dfe584f6d3e8c67a959eb2ab7b952bab14511e45922a05547d128d1ec686145c53c3ddeea28a36bf219e18a95800f6231f833e113c0c832e21bd480e6a906eae3cfa060f8831e3856be25caacc7f8e24f9d68a18cc001d85722fa9463ac83eb58945d778c474bc1713df6a0b7a00877ca660ce3842b31f2540288ecd9f263d6d4c5d7739a968edb4aa81f7b945079434c09050ccfb2052492239d0e509590c731dc1ed1596780c94cbce128954f3ed4b5f2f16a280d1c5a0ed3ef01dd9ca46cd0d9930076c4a36f95d15e4734f7473e9918935b63e9529d79562f4fd9876127d95bb6c3400fa97d2b756856e6ca37a645c25da54aa1d785afad3c78f5763e4af2e1b038c02e3e62dfa549d230206f6db499367703bd96645701b1b82f2dfbb5fedad839168767f3ccde49841f8d901be51c2369ffc9b86a7b57b58ea47aae7996c80ac16beb51ec75a8fbe390a5f1d566c03947540a3ab66f7c0578ab3c5cb3d1b599cdc572d6e425665c1122b3cb52f82073c679d6f8ba987c3c56c3aa3d9258e10eb988f595fadaf7a8fb714486cc032fb53824922ec3d72f13613dec139e19c86297f5b1b80066a3e7c6b3d875ce6bdd0a5e4f59512ae4fb5a830971e8ac84609f2ebb0a9ac0c1dfd7d7e475497d42c11a7040ecb5b9e4f9087bcdf643fadce4ed61e6c17aca59ea785bd7f4f6f9dc3eb675bda3269cbffc212d62b0920a4a947815ba31b22a7068032609208024fd1420b86fe928dcfc91cdd7b306f70a6c75397da793aa2eb240ac0499aaba8ed640acf6ca08ba70110fda1c68839b2796014ca340555d0ea0bff51a555d06b2453cecfd1c3fe040457be16ebc0d967fcd158437846a4e39a6d094294b018a2e3ac7d59e105ce86035f05c938f245ee1d730298cdbd17c55a4213fa39ea93efaaf8e0212750ebd525b97b5eb24dbaee862cc7de73d9020c85bc78cacd74e6aaf500ccbb657a9aeeee9819824ef74f6558fb850570dba49f38a33510ed58d40eb5ed181a347e8815abf4e7caf5707b9257554d49f0f950c76b047664e448687285da13d0eb8850b5fde767208872ab4b66770be68a5594929f497c64a65d2658f007b70c17ad8e28ca3949400a8b369b57b595bd78a5a56e12c58fe22ab7b8a15bfbc2cb33c4fc03beb67cf206bd86809d09b7d98e669c3eb26ba485f8d5f794d0046fc360aa4bfab02a50c129b7b390b56414eea376526659e01b9f1b923965c25b1404c98bec2b654576aa70b30214b4c6070acb71ff7e8dbf145b0a912a829940c6ce1cb2e8da003060d50118ba6de5946039661342c445000c91f4bdaa7a343befae0498e685e8c4be658eea3c939322d3177452eb0c1c2b39a13045d07f336216b33435c79aba815469009191840ffb406c6fb583434b3643d5d921c4fc5408de8e16430590a4e6681532cc1690ca642ddfc79104b053e859b4645a9f9a1fe4b27c7f07532d8588b512e0124326405eecd1c5377b22619c6e24f29877f6f36a0fcac1a7a3f8eca614067a55ef421497d32506443d5b1052f479eb164e908172796206286dd576049671a6ace25607663c262a0a2c06cc0246b4a1853f26e53f00c5ee4e3cbf2940560545c9ffdfb9c60f2daa22d0b2ac7977676e6ce159411b00147a51a42c7f7b4c9e12cb0109921cac212b9ccabb2e7b10e17f570e5f2b2d95a9e511a246461eea60dd847b70645d1eb8536d01bc0816dfbe3317f74785ced5409624fbd81c53c49520c4f0ac13555498f97c38c1eeea51ebd20fb2c126875911478662a22565d50071a8b85e560781b0b50a49783212c8c65af3650693129bafbab400a3790e71d65a16d62a00cb3e64cc0b36f22d665a666f73e28f8accc080cb490b026795f3ac4a49995f6f364a2c1c8e4d2ab97c1d2faf12f4ab92d8e6b6e35e2512f70c67ea236a05c55a67ce2e34ba708f324a21ef50609567d910cf2d0079b6418a758138f755a1e848d198b9c1a763f244436aa7305272fc5a708df17fd982ea707dc08045b9a2cbbf2a8a9f3adad3bae3046e42ac0654b468366e2e88943cf33a363f29e51c17639f5cfecd9916623415abfc58928428978cfcdffac16600477796885a2e3eb75ede17cbd1ee4d2923df5be3e94dea46e47261ff987827c74050368e6acd15aeaf17b8301f60905ecbf50274d27dcfd40cec0fd189d9ec6fbc1c61d593ca8701bc32de304eea365189ad683195fb42b7c62562c4391b33eb960df11aacd957d11955671a741af1fcd1834ba832506110a51453387c7d68f049905550120684db6093fc2e376ab92726e944272f92c54ed9f108de09ee8b8fc8762bb926c04e459b476d88fb4b9304216b5c2f738def7589368849250026f14ba30e2073c2b83d8f75f702318a42ee8aff18fc6306c6f73e39f63671bdba214045c8c508936db83d8ef349b7b12aff222a08295618f1222b40a2f30b3626fb3930ec2c8445f902d689761d7b71bf445006e3c723c1a40a505198e6285807898478a5d12763015ba061bea3341ab38faf0fabc9b8b1232c2ac4c5a37da047491907e910ff3d82c66e3320283ade7b87a0fe48aca078952b4af222fa48e8a59577c7a9d49e0a814ea0b82d1db792e2a218c9a7dd92f69d556eac2a221d430443c53dfb9e766a07821edd4bb66400be005511986dc2ded50aa9fa4f5a4c466ed5ab0ae34a944f40a6c06d4862b848df4b893deabd4920a8f9a0dd99345a665923bf33790b35ce07b64b2e8f3f6d2aba5f7e75345fec4630164643cdc5f41fdbfeef62384947023cc67375febb2cc75e5c83c21424a5fe24a15b511f98f2981306628ee197baf77d7830c298e7df2744913a80056b9d040aff9af96896fdaa437b7bb82f64e0ce61aa06c4b6634c180a6b0da2d68caf2c1e633ee9cf704655f48721eaf962494d7cae0e7fe1cb00eb4d298c873bc6d761568e661fee4fa06638fc86d5cf25a607ed1d53a40109cfad398325e70afdc48ce9bbb6f093890f3967cc2f6d9b111b4689651dc209879d00e4e68538da47a9f067d0a11f1a0ea353cb93a4d182e363d673b0d3a59ef13ec08ab6c4898f8496a8a09f49e9cb728284b1844df4629c47d09c90991d20069dedf75f889fba4704c0963e27c7f9a4f6a7d06162dc6ac10cbc07f4fd0e0200f34cf26bc24d782d0a026e0e30e8445e9390da239ff4f00486f162c45b86da762ba40fa36896bd03b190a50a06b04d0a05ecc379014f4937e6c98429938084b45ef3bd2efe03d19879148692429ee40dc9bb4e476511231e930bf054e5474032daef52d61adde609f9a84973890783277862188dbb69a8613969f551f6228e2714fdc8df000ec92a988d1882d865c8ccf1ec69b034d2cef704ec510890e845d099d999060f0e96b5a10e88d556060745c338533eb7d0b838116e555818cf009735b56cbaa26ee2cf2b4a897de93cbdb0d1453af75f5abd20e2619e15369dee064b555ea1113a1e28c6e516ef465823c781c9b073600539376c9db1a829b1b0e4db98fea241a1d81857194f9f0e6e52a1b9b09c49f46c8b08623865ac8042a58eb62ad996032f86fa38c95a5951aaa39674f83f82cdae16468429e2c3282c63ddac98c38666b076d704dcb4bb72bbdaed64356a8c56000b5453fc80ad84021dea26fbc9483b0bbb0f993408918de67402877a453224672508dd36972c00a78adb2004df56ecef3139d80ea9c2c4099563738dc152b7eede3413f938d53a7c22acd1db359070d4795498c8cb2330a5ae21e56ec9d6d66dc590ff49c0441879826cdf5d3f5d89c8e8710f178e135bc1ac8cb24de7fd23d350c2eda84b01a6214a746efcf0dae462686219c3805ff66494ec4d69cfeb7e608d87619f9f3d5ccbf019e5d228c6a1d9a15d902b60dd4a6d72ebd7a0c0eb6710e5ab013f0613faa090afa930898c25cc09528b44030d2af60de0c8834a51370f849cfded966dbaa61bf04d1b1d4fe485f1122b3e6252513bddbbc5a3b5264c759a49941f7d7e214586ca401cc9d4d4dd1bfaaf32350fc6486bb0d22d0e8851afa22dcd0dba8f3d0aa60190169b0980216f34252187a5bad08b7b19e2a2f8e59233f69cdbe925a2e8bbfa635071575e30fffd6d2ad0dfc864ee86d9bb14513cc8202aaad7f82120d525b00626a906b7d852c41a6df1c17bf1073e109232e30f3db957d7e7566b7de694d0c673754298e8765a9d97976f44cb0773e0566740a1e0489d405219a1ba19fc5cc9f8abef8b7423862d2779b8e9abb19b109dec7b5079a253609afbbaba7879a03da8612221f0c8a2c4c3d204cc7ab3a8f1965374388a9f7a94c1f2cf022b3fb5cff8c0a35d7ff0a51d2f902a295714621d819aa7fa60c1ed787dea6ccb3961541a26769039be9e9ee6b7c0f1469ed8030f9d64f63094c4ef0502b20f1fa9c513e65e66829b1e7936b18e9eb9f7c180c80b025c96d49c22feae016a16650a5b099f2c0ce4db4bf5b86c97467cd37345403060825cd333909978d93e57a066ad6899acd09c5c517565202812342cda186889f80391cd41a0799d657388749462d9ce25138161b505fee4938ba17770d04c3b689eecd51159dc0c02d0962a71e14e0426f04eef5ff5b22d4d1cb5546b1a58b26c0e2c2b5bfdbe0992c51cbd7767600fbad66e6c5dd182681fe9c613d68f31fc00bb00b39c681e411b2396d125b852c2e0adc29c04541354499feedd46329229b3ffd412ebc37646075fae66368eba2e237ba646c61e11b8e14e1fcf9abb1495bb614d1d45390ae4414ccc2c991e6b0a1c6fc20eb4e2c3dce8db1998ceeb607321183e4ddab3ec49bd2e94de4965f43aa0de3b6eb7632f8ec3d8ccfeaa33a502f7a015d0b79681ca9caaba5ad6d182d27101bf14b5b0786cca9a3ba025ef9e5ff4df7598d0462ed92cd46a0bab22793148cca27b85b1ccb470b05261f0c3a39c4406de6fef7f6386116ff5b0b5b56b752fc8ef18194ec4d799fcd0c0c6f61ba22ebb374a01783dee533df1095cb6e91d775bf1442c8ad7ac447768f39eafd2058ab8e91e2604e0bf82e4405b386e92bff7bbc11f1dcfeccb2ba3470ee5fb8b9ef2f550dec104b991c325075686ae4284589c69a07ff948f9d9e4ca544022a7f6279ccb2ed352ad4bae9e6e65e9bf34e6de1941209e93bd3507acfdab285d961d473b7b16d9d76fa0a5adb04373962582c83098551d512a6baddfd23ea4181e401647b799c38dbb9604072d617edb9601cd7bfb6dc912f96f8f19de6a01e4f61806d986737a7983be290e3b417a45dbabc81dd355f38084812ee0e2fb66159fa67aa63efbbf157044ea181062b9a85d29d26de6301ede0d1c096a9ac16141850e834bc6905c6ce17e12c0096a28514463fc576be070ac037da5e30454d24369620b5dbd3b4ed6829d3060bd02b5a9fbe10b18e49eb926d1f2f6cbc714cf49c2a0046c6da30713d62f44dd7d71e53bd98a6a86e1f446c325bcbe1290d598476aa1a3426b62a7e248559bfa573d03268f9d2a8fda8138efdf7b7276ec25a51ed1567265414af8631dca963e38631e93df9e6a5be373a672760ac6cc6d5f30662dd7de7dc7a75784fc02bb9fb157bc3b76d9027bdd5e195905163149d795bbe36538c00287f67406191a462c6db3b3d62740d181fb6a7697ddce33c50bbe574df0c624085791db6a8fc3a482f651fb613f562eae59d23f3dab0dd2cca8ceae4cdfead67e6bd9b05a2c82b832e1bfd75c1cad825e7d2550b274276740889b18e5819529a98047cf3e73cced1232151afda058c6cfe5bdbcd6a230c3ec0a63b332769a30124806b1ab73b7945091b308a3c8c7c452a6ee2526d2d1d043518282cd1dece5b1a778d978ae3a1eab2b96352fb124704ff7a6e20f3da9a1a6123f4e984d33e9517949eb17da46825c5a83e4215446dae239a015512a7851632a3a202f0ea8f8b186f4356c6bfbdd05a87e0e67e78f713334998990ddedf2000d18093088372202e96f22ce482ac68c11d239c5076952be9548dfe642824905b24ceb58d49995ae0214b655630b44473c0db8b6f4f15160d936cb6179b43ddf380acaef00875f0de106c747a3c88d419fba00135e3dd579a71346f4ce33cc2d7a9dc1f1c88d2d585d74a98a63945003fc6f9ff471db7ca582098327f2217c099843bf4ad2f82e12542fd4b2900289a3aadf1e81c745db4f50aea27a196057d68c0e7d450f4ff72a460a512ca60a06bfbb4ebfd1d844c5a9c1c5180177d86d40efd6ffdb47310cd96230babd22ba62e5fcb879e39193a1abfafbab906f6b0c14fe2ed9f2f15e76bd84d2e078da2b61cb13023e941725d6ca63446eb370ef99098d3ebc9c6b2e5605a3aa24434ba202be22bfc9c10ab01f110e0c7dec7ee0673a087703cda24e68b33df6592c62b3aa55013a49306423b269b8db14ea2ed051c839ac3c5b57bd01d717cc04aadee10dd53e30040728e723185b9bc9c9b813fca7b9d8f0e06b665d1add0390f369e31f0034e6b7f93746407abddd81e54e05c8167e6ee2c21a5751680d6d64ce0925647a50ae00c9434c80bc34224273bd40722b3680fe26ed73a990f20bdfadd20612340a0f8dec82262bdd910175c53c457f4534a14351a4134c213965c8c5fbe9e776fc1abb9c9072af9616d2e934928cc6b4d46ce86f6bfeeeaf059e3c6c67b726f3ec960a74dea364ef2e607e276bc10512b6add49da43e47de84f6a1686cae93442a740109a251e70463d79bff20f6a8eb31238b7ad0fcb0f425a1bcbe6a83e1afd11173e365ab8b9191c1b70eb3fb979fe8a4f0c959993c44e68789a89f52b2bd3cf4d5a19bf85575a9c97f5f66adcdd24416185ee936c340738f68e3b4cf3b06ffa69a74a4d62b966b18387311fb786d6361b53a2d4ecb7e759011afa0b6ee86103548f48017d5d3028df992e21bd264b033edbb0a1f2f70f6323eca4a85fc15e5fac1d3d047fc5e762490255ebd8c0683976a6f2e6451325d6e08bbb8340a3cb871b26693c6796e268d926e5d54fa1a8ed277989e1fd86b892e152a106b2d6417e4566540040ab1ed099818015dcee788d7ffa55610d63a31507e66397adddcc35d9f9a82ba9ba4b5b1e0731d63fb1126b521fa7d758c329226f029ef6df9ea5ef787b25ffd3843cebec7b7111714e06501f4740d5ca2e61a24ea7f7b42d9ea8b1b38a8e001d706326a6015e3dd6f77604c0a19c532661406c4905a5cd5d616c483c7d1363dcbc505463f97652e08ba17326a1e807e3055e7b2d1ec775d54f668799a9523cdf8d2590f9bfeea4de6c2cf8c3a17334da1891d57a9c42d8185e425343f41a0ba3b98ab9a4d003e5d0a4f0109c5f04c6dc48a289cd85078539ef429297428f5061c65325528335a7b20c867f0ff38dc455b583bf1f4d83815e2a96eb34c966af1677e36d9bd6dc5ffa9314df9a1c9e5963ff85f431f4734ce22d3a8be55e9ac810016573ac31dee82810be687d8c0d45d439ff32c7eee9c34a55f6f20d116701b08a3d48aa2b99feb410a90abcfb328ee655b6f6f2de5335e95069c10613c8bdd392d08e77f629cf6d068b19e4146e5d443b48153285d633f9d1f1484c2dc75e62c4923b74f392afe401f215d81d285dc9aa5b8bfb6f43eb2633613a4539e1e5dccab933bd410f11c14853c60d2f73537a9821d230d7ea0c52f75ec64ce11d51cd4f19a5509c462d18f153d5a56a8f9d867827d80eceb02e7d439177a5d3071049762228f7d6d6af60f1ed7b4829a2d053e1e683cb2ba12ab57227f894ead70204618ebe08d246c52d11cb70f15e698302ef7b87ce31c5aad0a9090aad6589160caaceb93e8299f27e5715459967f98e577a20052c2bc96f5e5a4df606b05dbe961d90a68a71a55c31d8903d489d7078f8a9c683ed70d4352430478fc095c57ef58fb322560a1501ad71b809046a763b8c70a43cb983ff2a7a1415c6b07e991cbbc1a7445e0798aa6859735428ef049363016f4d988105cd61e3c9908c4676badc587b6bd1a26105057fdbd1e699b9a9b1f2b12c526c2ee279ca7dacaa990049e7ad63f0c53a9914b010164382c2f9687fef7b7af337077beb9d640a1c9d9cade1a972b1ab129efcb9fc912a52078d03f98cf330c7afb64cadfab2b93477788b52f3184fdb6bb6f712f86982c7c1eb2803a4362f3cd218e2a7ee80c7633ddb64b087092351ae700b38b5465a057e2e8efdddfd47a2e367af903a313d9a8df4dfe203169e7c0df1f881c4ad6ffe63d2a1610ab2b147b47bb9af58d3deac4771d64a9eb6e89e0b2cf20e683958653a18e49dcd69c16b36cd39034700d28eae67b15f05356c3f3d701ba69e71bbd9ce66395f1915f92039c0135790dcd492719bde78cfaecde9c6a93803e4116c52c67bae250e605796c7b9cb141cdbb8c85aea434e8388f9a84357182de00297eb62e88917fe1b4b5bab71fd839918ef48d6022a5cecbb706b92b56e1c9fbe49b9405a88a2584340c594bdc492908ba41e7479c479df6d3f6b75ff88a4b86ea6976868d66378587596ce93faa25c66a837795c27511c4cb3f6fde6091614f4cd567bab274c4993448de70f80044f008c76ce7174d4f85625fb4dea6f5b45a28eee96122f2d3fcc4ab02663687036bc3d9608e9ccbdb0773dade8cf4e911884d9f1572870cb913caa319ab42c45804a468414f3d40113d1bb04950bbe93bf4ad809274c76ca502b3c0e5db2172b3e172e239b5d163c60f578dd934100b62fbf009bc3d78bb31b4673d7213a46da687271ecac2d04d388653094dad14c81c147f4a49ee060f38b5173b4128b3474eb3a81bfb1f5846c48801ac068f0e3225a38184c1cba33f91a0a09c61160974ed849622312589a5c7da85de78be4768e1363ed1fe5218a26ba0905f6dd7fc7b111f050e9408adf80bd00f8deafae2bac60f19ea04b664fdfd9a24b9ffeadb0ce78db4a043b8f05a8f178adb10ba2232e30bd5d7cd80999be2cdb89ae1b18450a5a40a13373c2f232e3774c9166dca8eeff625504c8d4d5458d2da0db043a5cb190829cf5d090b3a5262a181075bd071610f1a3febc70b38e6858714508a25c712b8ca430709e191e5605c79c82abe3f5dcd156b99dfd7c53c0da886e979373e141cf8977ef2fd280df6c977a83838d08558e78546c3d0a93c57338aeac138c06c26172fc4fe4b38497eec5f834caa65fe4d5145b3048fec4f812c0f66b37ea11d201dd0029783b900fb21c0327cdd166a1e1c307c84364d012ee39fe04059112dde1ddf05454a7871238e45e69645dd649bdc921f060a2de7b68a8d7015350333450a3e5cd57187e5228cc9b7de5ca5d428bd61c9fe64abcf1b43bc9e335a76f3885a0ad906476904b1dac781fa9db05a3d1391be2daaad449cabdc483a79350e909847990eca042c538c4c83b74ea1063a47112b6af25ecc3add7cc6dfa563adbbadfc63e619d9b063a8098a819cdc45194f70bfbdf7901696fc0daf5e407784c158506d370564b1a814a4a7182e2509ea139beac8e44beaccfbde739b6cb3ecc6019af8ac6d115095cb56f039bc2202868f644755abc9c21e60cf48b503e853d535f417c9171757d716ebfc30520cb4648437f9ca3963b04c7da77e5fbf4f7b63ebe14bd113afee73dad00557547482ba7a5e0c46efd5af86e44ddc5332bb1403684b537f1ad9d7da06d00ce803b1934548378d1d06cec777b0befe9257e14d327260ff3201fafdc7444f5b15c546e9d55363a75302ef6b184358c678c7f6afea592d017abff6a67ae1df8083e75667a423cf2033b83678f2051d98edd63f56d3c5953351871486e5bca5df552b7f888f53e2d087ef1457f5813ee8529386587a762adf2c802f0767cda402916ed9586f5f8bceee5f433adfe7ac1119f656aa0ccc4cb046a18348c61471f7986b2e84af3353c60215037d5b1386b6cd95c5ab37d215353bdd321fda85c6637626f86294838f21b3bcd6bab439a592784fb83247345c51894b8fc83f39b5db053107132ee40090799cdc41900f577d627062243fb0f6ac2fdd021a828b48402c46ecf090dd94978fe11bde4d40d0f00405340280df5cde43f1ed2a025657a744e71c22d25e04bc201ddd20beb8eaf32b30f690d6fa9a1a02cc626704e8b32138ddbda631c9e9620d70a3a3e83280dfb1487bcb16c3ce81a810e1611dbe675f6555d123ae87217a27095f18b47b8cb58dd44e551eb4b54623c4282a69b88d54fc6e04e0a13d51dc9461a938f931f7fde18031bef785aa16e3278e13cf3dcb712a447432570cd78707ac98661033c6fb22fd44e6adce7fe30a1e308020506c5c73d25e0fe75814dd831155cd7dde542a6a4f1287dbf9e1ea79ea3dea1e78fc8d4f20c79ba0747d187d5a132024535fe86334aa388f762eca0e4ce498d978576f0307419e74c45998ae3e73ddefb84de251dd37bcfebb579b95ce8664d7056260f5bca0e3768d01b607c11321a2cf2187c2ee4f318c7ccf4dcde900b3c659727747d2ec528f3c9c13e76208f4020778d0a3c0c51e16dbe653346ec71d8cee71630ed69b4097b9f78cbabd0bb05581b8956dc853cb9a3707edc49227656060c34fe3f60b994f6e487e1b1047f105487e8898b30f3ea1cc2bc8e78922f2ae82126b7d7af5596316c4180f1e0a1bedcda9be7e82dec06e8db6f148030b832239c6b5c629afa53225ef50b4f02cd8bc965270fc814b67f08b76dccac8d8f2650da286d6845e603a608a455455ce66a02919faa01612c9f7535ba7fef713309fad078f2e157740116d02f17f14be0f4677fc5931c5d9de49b251811fa03ddcc4c5165136e41bae56a1d3ffe83bfc800a263dc6082fe2ecfe15ef5353567a824dc3703a6afa96dd0fa395758603a064dcfc72d8c4149eded1841efe314a01e9914faec47084272cade2bcefb0ef7b4d30ea927be12b1551d2849b4664d955a381db40757e530d7b4a3f6f86d33073ba4333bdb907fa2a3a63568b217bcd641b8fe6ced657055b31fb9f037f706094d1df567f60f39850a936d0ca4c81aa4532e987c72d30f9e59ba57406f7dcd1b84017affe2f9af56ceeb8fd45a3d9bbc98545a65bbe48712be9fe960c63a25ab6a6999b54bbac29e8f1f6315dc302541a060a3715bb2f91a949cb510e48ea8bcf4cc1c21768bd3d2a12d40d01489c910140c869bb9897594601820ed3f3feccd57b7b3c503c0d930f1182b1b1a38aefe13ac206cf910035ee7e4df6755cd09454b5b642d3a21a09040d6a0c42cb6721cd91a8c894b148c232ac224a41f697940ecb4aa220f73b001efddeacbb642d4f56053e67b2e4c560e7377047809fb85ac622c794c212b85f435ad6c4884e132f22c474768b73fa5ca69d763c78ae74192ab88f7c8f67f8df8ae381ced2769d67e23f6ed00d86473c003609de6d07a3d884a32f9ccf8684652eabb3dc08e0b99f7e7f5b31b83d2aadc707f536eb9e97f682e46509262337d1e5e17c627f8ded0148b15a6764708b00601e4615de3027212e4321abfa73c622d85317c88e5d9584614f4cf23680892c1c506c11a0908e7e6b793ca49191ac00038a7775e6ef0cd5f3e3c7314ebb16ea6698dba5e947cc808b48b300d7462956f6a3aa1a49db126d2a612b3022592ca24638010569d2e69d43843621e8ab09f4cbbb66b8734fe2d8df62807f20e17b21502f9052a101e44c87e5263a40021faf533bfbe313974b7661dc2598055c55c0c83a660f9b1417aeafd372fed6a202344e15e4c8e87fb0cca3869165ef0f36ad7170f57c09cfe824b671be17166e360dd040317fa65b6bbba50083b3d782d8eb48692d646700f431793e29d38ae8df0238a4f5625113e79b98e672130b4b8a0196464627e1edfda6146ec714f906083b54bfdecccd65223ccbd07fd86870cb4656acb541007021a7bea23027c6be2f6e0d4f91d98766f042fef26998b50f52a2674205d22396a59eaf2b8c71649a8e056189c0deebcc5f405355333ae3419941c74c0561774b0b14007ba9079ff9f40c4df4d788a094bac77f5fadb24aab7074d76622e47f28370887aea4c6d1dc87d523b365252d9efb86fc16fa321900616046ad41515e26c6f49d3dd3f560ccf85aefc5c48a04320019bb596fb3c901c766bfc86757f4725176382b301b2d360d9d120c16180ec60b07436b371757f4e824d53132653417600e15775de6f1c8e6f36dd5f1e21f71d0f50dd116a059edb803cb789d03c7b431c0b003ee483bcaaeb971b072382b703b2d761d9d331c1d67a3577078b18789a7b940f17a643429b7192d3c649b89951286f1275db9475d55cd21a6796a68ecb0fb5776e0e1eaf9f2a76d808360ef6b3c51f76bf1d768c7e56df7d677018c76ff10aaec414d58fd882dda02c230ea249ae1e0d1b886cf1cd93d5318c4d7607b577164c8b95a819e4487e99da2763e6a6d55f4159f66f186092d80f93a8dd4e9d8022f075cc01b56d424518bf05fed964fd8423cae7dc25478968f5ae8448bf6134b1d89731a69c3ba730d505987a8fae1ee1759272f6c5fd112b33a4ebca4e122ff67475f659e562a66c84ef9a6de37436a4acd1aeb5725f8c6831416cabcf8c4ca3aaf2814fb5a7a10e6f94a77789d01d2b71fc9396b3b6d38003be261f7290be1ca2c1018f432c0951a0f1f2a9e1208558e4563227be3c332da12d26bdac7ce02edc29c34da7344600448b04c3ba059dddacf0be424eab0ef2cab9e4800eddd247571cb18ff6d07d1d4a2c01363d6a8d19872d748e29cf9f26b3800310769dda6ac68319c5263ab0711c9a0fbba4d271334baa9739e4ce4450e38b4517d572498585b54613a9b5ff94ddc35c1ce11d13f3eb60332962022318de3141c39d000b03d84039d9c00ba60b676d997d99223eaeb3fda3f2ff36f3e0df25c58e4976536b8b3771073a59215f4aba9c2e3e1713bf6a659c9a06ae6220794de25fde6555341e00aadbc806e442260faac721d9bacdd710e887402d99dde28284ac60dc583f0d36f1fb2aa43b8dba23581ddcda33e26dc5ae09ad356da98940681fe519bcec25aef6132e54087f437ab9d941695d9c92adf9d8d904e15246bf2d9cca2146a29b7738f71bbbaf0f9a44aa8564d0e717afefe421fae29a841dd9b1b7f6baf1c1e688d7ed23f47c0c8ce5189acdef3422ce7c58b01177494da04dd31ce7ad3ccb9f78ee1e125d2db4414f5d15c7f09ef036ef9f2e94a0f80c402f0264d44fd9226a56f229ca6c576e2ff71cb86441f1c689b06b8ceb0dd7caf85b82e3a9efbafacf34591dd73d689fec463a1f11f2a85349c7294bc99a6585c1032db728cc08691d99dc5888f081601243ef02484e938af4ed38bbd6bf0d349e425800a2e424b602088d67c8a9970b158dadbbd2779026fe1e877e036eeef79ed82f258ad63cfe5006174ec9da4fe9d22c0883be069b9d20eb127308d31a363b7844aa5c3c3e405bfa6ac2dc5ffa74be0c58ed62f1650208b0cde362cb9708578904628c80315bb0d521f79dcbafd177527cc690c702d9a16a193d0b655f8c3ab92bb22843650dc74167205404713f6ea64fa2d0b70e8a0098af23d6ede4dbe26fd38a02189654ed8c523fb3d12bcd3665345a071c6159594a84044726ca62012d9547fd9c5be115c85b1b8984ce0713415773c0a51b8e135aa4dfa95568959eddaa3266dacbd5fd106935e285a894a9d7d0a9e5ac28d63aa3a4ab7470b29b6e1cadb0a3111127f96ded162420edb795c13991dcbd3971ada597a0a4f0e895dfe518776e1e9b61939fddb0123ba5d75501ba1983b5711894ad4a4ed17edcf5fa9a442930c2630f23d80068ef6645b7724e9c3b0f1318a0ae8bc3a7c02672281edc9b16d630fd4b1d84de422a783b7ffcd758d0b04c684b4854a09b2f0a39470f2555c858ad088f6d57cd03a9e676896510c15cbb44f2aed2ac5138c3522b54cba4dd5a53bd5a02f34d40d61f254723b05557b0e291faae9aa6fc056b6473601f8a882a261567979df3b08421dffb10ca6296e84fea9f1c5bd3ec6d011bbb6f4924a73f39c3ad1cdb011847ae3e9b9842aa654f4edcdff8a63e17280597e2b2aa5ffc7a0d8ba7b45c68dff41ecc6fd99c4a75f56b616d9109c7b86978b11ac9d8c1a4e4ae280b9712024aabab8b22f5f56304ea6ab78e6a3b029d5c0a2e61234463fe89506b44a4af04fa3874c86f6ebd0ca96fabb25ad8fa0311906e00fdc65c0785d9e9a3bd053c9952e5a34ffcc5d298a35cec3cb9562123a026e8f1e4e0c3839cb042afd09d35ecfb25c61f332521359aa7f6c9240f9cf03e82d731f9f5f487c6352aac0314d3021adc555f5d30522a9b0ef1e28426524ca8ab663d160dba674e3ce9ae2b07ef3299aa251505685066cfd96aac86c2e88aebf742986220d1c260a817bd5a040af1300a49a1878ac3a36ee8c6b98ea1cfd6ec45363dc2c3881006697befbdf79629a514f205ec05b305bcc1aa6f321d9658d2df45ec244bd23699d3b4134d6c46b5ed88924d4868a64454341372f992679b6c33da8e6c421b0c969c6626d995bf139e127a45f589e44e9cc9694e482152cb9d546772a6ea3f7da6cc6936b02bff15c3f3292bb72935e47b20a7acfa2f973306ed4f6304a095181512d28c9413261f274c4cfe32605e5c5a586241b11382fc6867fca9e850f00d7f15d19fd819234b125144900aaa3f92ea7f1a8d6a5852044be2b02bff203e1dc6ae8010fa41142f96e462497f1fee7994a652ff2c9a5ab650a5a9e536096911c36215344755152ad86847a5763763a2ad7e63d0d94d6b9f20744b4edcbd930e688082c61c6b7287059e1d9511d485c9c3d3625848335f3e561f17cc916e8ed067128428c8d177baf9afb95bdce11102ed6f74706c1e4f3c7ade77ba59c0d25800696767fc4b7e17d072a1b8ff8e1dde9722eed0817a17e6a7fc875ae1e32aef8cb747d5c3538b5bed10d4b7f1503c3d288ebb33de7fe20b5c5346158d0951a211954f51e93fb15869a7917d5040594dfae7657ff81e3e2bfc920c59dd0a47f73c4a6b18ee0afcf04330f47ed206cbc349b2bc479c26fd6f9af45edaf116bad5dedddd9ca404a9cafcd73e511f9c73776fef2697d58ac024454535a31e5a8c2c94b6265ca9d53c218618328218b80bde82c80b3943414008f1d9284dd6090e2d6029bd89113257152aa8cf76581097299c4d66a276c9486c1f765de735c88a60f275953b13a9b00d3336628193daeda4b6f3a6b03577cae4c632c54293debec6a063f7919055a8a0fdfb251b19ed380dbf7896aacc7369ce1d168e2a3f4fb7542a03d134bc03ad856e6dd211231fbe823f5ad2911ad42621a63a7b5ddcca335fb10de81ed5ad658afff58d41474fa401dd2f3d5a0c18f5ccdcf4fd295dd0929b18caacc9229f752b759310e8696fbeff6e44108340552b8c0c60dfe6994273543e4785a69df1dfc6f042cef33cefdbd7f721d8034e15f0555a54a15248814853535393d89432a2787ae2a94997265331bf339f128e5fa94923b1318d59bd99a8de43781f48d44bda08e56d14f6964975eeb899c29c4fb8ac03dda4a127d5b9981e4dce9f58932a1650fe79b58ca4d2f78b240ecdefdffa8790eacfea968f9e4769ec4b560a9e47e79093ba4944c84ea89b34645439e6349e47692af54fd24a52c7d6f4cf3f000fa9738917069dd58529764cf56b117b8ee4bc8c2edfd3f2348a501dd7e1f710ec979f2c3465748a1a9f54c00a1d17957548175dbe4c81638f60046d7997f7173ba6ba89fdfcf21268f99751022ebfbeea98eacbdbb467e4e56d34cdcb4f16d2ab493a6be46efc948b4aa37e98e73c75ddc19973ce39e79c5d4bd7c9a5630a99f3873961384ea3e226a7a2f2a8ef49993eb5e5e72e94da32ba5646fe11631c63ffc6719a14d88523c37666e280f3e7fc9df96541b7295a4165a6d71c0d7474c7409949e8349acd8ececef8cb0826b0d32c74eb7bcfa18367a88e584644cd41d5391acdc66667fcc313db6c0daa04c28279192fe3431aa2ea05044710550fa8f1345ef532f2a8f134543cfe47f8df9d5919550b68797e7e525fe8ba81ae726056fe960752b728288bbd33a597e2400a1be0cad230ff29fa80c9e543661a7f5ffe357e5ffd32aa1ef05fe379fcd7a8f13d22fcd7f8ff1f7b667c8dadf1e2f3f81fc71ed5ff8b63cf911cd5ffd813f335c67df1c85166c840cb55a25e8aa6c02e28aa964b5bf958f8de4029632c4fd1b2352c5ff2104e78e28c0354dd405751dfa807bba0a7ca309f82498daa1552fff22aa4c66d52060ccc7bfff240eaf730e2e732f234b9b38526b75a001c3bd37f125d402cc460e0892181681d4ebaffd00474541ae2be4610f71523ee4bf579b5db978e163398a63fe1cab8b8870c031428309cbeffb3719ae7fe24daf8f046da7b11d2041b279430734300374455f8ac07f21280a80a6f7c8e00fec6877fe3c6b36ea0f040588fc2e7b01e85f1c71199ff71c2b364c61cd6a3f0288c3fc86701b9210001bc0922eb4f106f3c29a2f0366666666cbc09e30ff26dfc8f137ee68198f0404af89cd597f0fe2500e04d187f98f000f81f25fcea81bcc22e4124c09b200ee04f10713c2916e00b20aa38a44d0735e941429b6c9b55ffada85ba51fcdba45f4bd1f756bcaa6d256444b9739cc5d4602ba7de92815168a0afb44856dd2fb243b653dc6e6e019ec0d7f0fdfbfa3fcb04b363be34db6a66b939d014717ab9e8630b963d89533d9b08e01f1a7a880d5324505cc886398f7d33086a1612a1eafc2f97124e75ba972def3bcb1c7cb540dc0717df58d2e5f398f8b391e4beea1fa566bb8bdcb33a5eca9dcc8403be33f846e23ce78d3e4d65b1647449894c44ec0036cc9107c9061a526fe61d09295941aa502d7fd2a003c9abc05ac96bc05ac763e36af79881562613db4ccc51b610d1bb94993fecb83eacff15619a5c29c356c14f79d08564f754c0bb5ec09a526bd95fa951c1c42a78f4749c29559d7d1a36b7be609db85fe685ee84f6ca157fe9c98819df1f7440cec0d1783765defa679c2eff9fef43de02f9367e4ebf7449d1ebdf2f0f4dff784a7ff9e47f8fde9797c7f3a7d189efa1576037a5c5512b45c261e4ea77b50605b0758d27fd4b133fe9b8b72bd35e91f9c1c96252519aaaeba494900a102cb8e81205210c3d49834e121d03b2684fbc42488ea34c94c63e11a93a6a1cf29292a2a2caf32aafa577e5f3d2e9f32aabae579a47ccbcaab7c4fcba7742ce3ae8cb4855d46d95c79069ffdb949b7fc9be55bbee507cb188295f108f840640da482a3a3de1f48ff27d3e4c3ac44600625163908d5e2096419d3f1855ef17b3bbe62cec72783944f797e1ce620670939978ce4a4b20e8bc5c2c961d96091a806a3bc4e932c43b8bea27aa139ae7d7aa9c7acf2ebec740ba6f2c340e303d68c80a23207618450e5e7e1b6f6a1f2f3ac80b29af4b1355bb97befbd6edc1718841a89fdabfb7e1b4dd37127f6e895b7d3640fd761b58d6e7d651f652eb8011353122d60814cc935a51a55e2d7f62f5f4197669064ca508ffc31095ab23c2f06ceccecceeeeeccccececec3f4d9ef8c1120c8911c90d03bcd9d9bddb1b8b203e3423f18a27962cf919829f109205121a9ccc40d4440a2366109a2205480cad00c80a211560b14b8ea2348164288a228de44807283baa7852e4480bb890a17a90c44fcd071b92340144d4440e4ba408c202206a53d8c086fe6a30248aa1708a2234253f0005315bf2e467c8cf2c92439325419014418208dd6700ad0ea9adf833ede73add15ad6eec93d965504f3407da64044db5251d74380ac2c2892896242931028a2555bc000914330025d54cb08276e2892f7a7bb777bbb7677bf7328e6ea5e65094a41cfcd0474562dbdbbbbddbbdddddbbbbdbbb35318a6c3e0b850c507a77b4df6cbfa3cd26de6c37dddac6f279e38dc51bb6d971c3db363b37f34df3f6f6762729a9010fa1fc2bc3738c7065ca19e379a9909190883890ff78fe333dd2c53db72ef315f820f8a7ef091fd503fe49f56d2dda6256dd8af1c7798977b12b7f1e5487e24cdc97ce44c55951b36e0d6d6b386762695a881d52ab25252d13063000498ae28c192b2bfec38d2de33e3128d7909a74ee3bd4f729323561df09c249b757211cc1ef1b4bf0bdd1d5a40df8a50b649b19edefe19272cf7395bf837ade7bef5ef7fffda2bb54f7dee55a66eeef7b15b67e63f879cfdf89464eefd234a7e79ebacb5bd79237c30a8ca458b2e1081b64d58b8a8a8a3847c7b89bba514ea44612edbe8845ff6920224affd91a21b666bb695f9b118d8b84d0b29b98748be35105ee69547d5fe2201d107eb79db8686b9886add815c91dbb2b716d0c42b92fb9569980231379230d328fe6b1c744b4d3149a327e9616626139da1a2eb6e5c5b638116cebabc1c8b652dedf89587f626b54dedfa1e01cf4fdbd880dc261dd8773e4185547a2820a040f41aa7f87d151fa07953573691167fc27a69e13617e135f9e672d24d4b3ad49a9eecf21a12b5f6e34baf2e55caa48ec846f30f9ca7ffaf00d26a698524c89c608ad168b3565b2297317b896dbb4c9362396d191c21431e651a2ea19899db0f44c8414a1991251d14c28e64b9ecd52336488f0cec4d433522966f2e11bfe2c4c3ea713cf58624eb3c9b4d81c9b11cb268bc5e60c605e5e3ad641ddf4662e2d2cbf4b61be9a49aaff36c36e22d84d86b186a5d964be82718ecd886ff8a302375f10a8d731d833099529e6e8ecd6a07e64e2d6a854ffee616bb83fd6e4b83bd3429a746ff6a91ca549e6906833b1c307f2f2e7ffbe0fc71fdd7f3fc0f776290a98042cf749d79f9f213fddf7ec13efc1b11b7f80db0528dbe709a862f04fcf237cd4d8e385370c68d7bebc574ee7ec8c3f4369928beaf705dd4616e99afdd5e0ce35aeb112d7d6a64316d25ce3a52e7f546ee4d919ff79946a22a209e7740bf8fe5493ffdc6ca265ea26f5a38afbd2b5286e544057766d0d379ebe24ba8d3adea6d3f188a3d3e9743a4de634e93839364dbab7747af8f42ec8118de3d435a2a0dd77834968d7349bad112b5d9f5f14fc83782f7f478d3a76e6fb8276638a8e59501f62b6851cc303cafd4682ef32ddeacacd61836ff89f3e9c4d22c0726d8db73cd82e7c7d5d8532154b20d57b70c7b9abea6f8373acf646006ad7502453314dcae040b9ed8659d8db5077aed2d5bc28540a503420f1135b33674a093e12c40e218bdfebe8967faab7a6605229a430bbcbc36c9ee3f2309ff3f2a95f9787791e2e0f33aa1ae665bc7c6a54f5ef4b064c932c1fb67c384fa78d85d296959516951696efb422d2d08517683d3d7f8f2728941304ec8c3f8b07d81b2fe28dab6b580f964e53fc0441c50e3f4d3c7952cbf4459d7329e5f5c8d3e4e4f131392e683fe9abb94caf81e5d91a5ae7b7b035f3a7d75d6f403dbf471e2ca83fe934fb9aaedaa3aa7ef5b301e5c61f996c3184a157feac49a2a29e3957f967673ac811184d5b88f301d1b32e6a1943018202e463c856bed334bfb8891d08317bbd66b32e6a23f07fb6860b4f10083f3c8da2e72b70f4888a7ad69dc0cee76ce65238773559d433577fd9b36de49f9db9b1a9cd3c31361c20f8295ed0a288ac269bec221a6d224d21f307e6d3640a3893b6046d9395dea4f96a095a4ed884398d7bde37c392aa3fe581bc548d5219fba76ca31a34977a3661d2644d9cb48954fd5fcc1535bbe8710a9593c6cfbf094d19bf50b7d8f368bb029f859a94cda029e38d43a5c0db269b42e537e9a22f35e94bdd2a276c0a75ab74da1c72a739ad5b4bb37103fda269a949f70eb717e107da2f739a09e3718eb359396130d50ae1cf9f4d544e581b9934186dc2605ddd7fc07ca1c6d904035afa12adbad3684bb425da52f5e762b4745a1735e9bf421335d9335a1bd168b4179a2bb139788cbde17f7a7f37da1a5e62094eb21d25cace84e015d33b5117b05998000a190cdaed395bc35da38c9c9e51356c666666661e4b162ac1064110fcd0719af410f652056511fc0ec3adb9707442b25b5d99b9bb9b6178a1f3b156734078cae9953f07e27c238b6cb21b6348b7626b38eecb0e22e18ca3d3834611fabdf7fdd327f4f91ec461f38bc27c4f0ce2bdbc07c520decb27c8bf7c82d01b042867eafcdd0294ab98ebe58de2aee602c6948ff499d0d92dc5e41ca8baefeebe49cb5630123ca33d763847dbe0c2f6dd871cc74d1f581141dcdcedc4af9ab3dddd45207377779fcd9b37770af72278639962eab123b2d0a47f221d83065a0c4124690a307c50aa0205330cc1233aeb3e0f5fdd75980ff90816b63531b1ad99df0b09e14043aa7b91128e6d0dd7fd37c28c72dd976a1b550ff01e7c1ede83e1e63d0f301c55db6824e5f7857af067b5cd27e6b0263b51b571ddf6df7be1d8037aafdac69c6f546d1f760f82dda8da461cd49f3ce63029e8fcd261dd7ffd4593ee305fc5be316837313549035af64c24a2a5c3981cd6ad6d8288a0ea5dfd55a40d87910e837143ecca1f89fe61a2a9899734a9c32322adaf4e25082ac776c67f08e5d1c685e49afdc1a07bb7fbe60d04b76d034fa80de4f0b481fc1bd8830a4f1f828f7a1ee0a3c653f827149fb6499511dd9ef3d8fbf80b41af1b59a4cb0b9237293e1cdf0a9acc24740393d0fe44564fd9944da139d4db9753c6c44253c6513e1aa8ff2e69d26bfe7dcfa32379edfb5ab7befdbe5df9f721287aad919a5ce2481f7f1c92d71ca95bb56e95dbac2ee99697be4b886aea085aa66ec881fa6fdd7ea8032c00aaccac270d9b51032d1bd6b186354109429747fe1f304292c5308ed6675d9e688114a5f881996b35a41d983908a9492d46c3a0297ada2f29cecfdd5d13d0fd263a8201121c363b6e6ca80eb45c9a0dcb85c4ee76b1a9269ba363aac95e124ed0316c32202de1e8baaeeb7e7b9bf6bc6e75dec6799bd76ddce62c1da5efaf29d5f28774ccccbfd3e4bfd840cb55e57fb18167078784176c8d8778f8197a9be69a060e9479773218364d34238872111045b3a259110c4533a2d98ca8685624039a01cd8488848a8c8478a1fc30d18edab9e4ff264926654eef6f83ecd6d25411ba35cd02e367cf903fb5710cf364a2fbada496293545f4f62be02a2a189ffcd80e0aca485d32d2f6cc48ed791cdb5533d2116db78924c4b4a36ef5126666e6187b50d8083f0943b48f5033d0466ada8f44747fc4f184d6401032d2cea800a41af1cfd95e3efe08c1cbe5aba01951cf84d0b2675dd4b396b5d00d347eb2240041f702e1ab66f469aa49268e8a08b978d3e4eeee6e775721039224e1323bb7cf8deb3ce5846e935bf3e6ed9f8668ca555325fc50c20f5984ac9202ea620141f73dcf474f8905eaa72eebbd238e4e4d87524a757056cca9f5eb34b7e1e8f8ceea0f4b70bbbb2c8fba76b89c481d22bf9c39915f8baaf9208a154504a55c43d4c7225e607676677766676676afb150e369a106456c8a2390581f77a03d7a23120b78109e7f1e8f3c9367a7c9de259eff7f1e5fda6181679b3b7ec33bcdd3c26c6b1ff3a9d41441d496b400fa82871f9808a5bea281f2c840b3f907887fd88128a514e88789fc004d77ff719afe2939c63ecc3eb13f516f7e6143bb45a98bb5a36f5650a9dcbbf8a09df84d6e2e624c933d95e09fbf7371b04df7418fdece30b703fdcbf4b82bc474ebd4a44d7b0cc29529d746b7b6da58afd5bf2fd336627ab5a586a0278f8996d45bd24fb57ca1ceb9a47f7b759630d4fe90674bddfee6474656b7df19cd48a86eaebad18c92d4cd6773fb6fefd2adf9dbafcc06841b76288285926b89134860f1ecb25ed014093950fe0ee830ab22072fe020ddddcccdcceb62c540ad20e2c4122d6214394110314c6f6b31e0d06464440f458ab868a2429644142a9210516406126858f213daa0ee7b1c6b1e19c6318eb14f73cd6db1e6d9692a22abc74393a7d960fe556c51cb57826e1ee7799dd771dbb6b9bb4fe6cda793208313473b14b5348184431bbe4e23d34bee73415dac19ebc00721eeeeccce1b4f66f776253da91d014612417c3cd07dcf4ba57e64f0191181388c37784ec42b8a9408519188a00454f480c81731081a628914454a569820091a9e7c5794a0464407198d99d99d7dbabb7378c40a21b57caf1ee1dbf438cfebbc8edbb66d7edfdc260f68b948373898210521995008a1b933cfc9734e9f93594da8b8412d7fb21b75ed535a9951f76f7cd53a9aec6e1860e4d3344ecbe9d636418488466d76f473bd719a6daf69a71a8711ef594f4bc5a880f21351e0088d2882848e5e30272087a39a0d6666f73ccf73f6e9ee9b3405915aa650e09344b4248908a8d5b56c752d5b2dce61b444cc0aa35aa66642c4c2f6be267a33bdfbbbd605922ddc87de6cc9bd8f364d36c77936dd363b96f3fe9bee5f990e4258eb13ed0889d6b414122d6c9e328aa0f375b68679bb14de4057b98b421c3d7030b033fe2a4ae8f6b3396cf20183073eb035cba1c0564bcaf3a8bcd3dffa79bf4223639b9a7cc8f89e948c6779fe1e984f7d8f8c7f7916984f7d0ecc987a1e735ed8c5260533aef7b7fc0b035bd39e4baa49199514d1d5e46260c579a2a48d20d06d3261b174f7245c19274c4b5b33756bbde7b8aedbbca02ed70a3a4d2ccc1d1a45481a8dc6756291d3eccbc325a7f17cc543cb223cedd74bbdb494fa9c7bdd9d4be19e6b7323f3cfcec0bc1bb613ed0889464b21d174b6c6bddfddb1fb1c705c5fa57ce5cb5b4a1982da8ddce6b51729c272eef771db6cd431f55b3be543433ea55c4019b56c847bda743f25e81c3d1fb706749f3584ced5a4ab28a1deced20f1ffefe3b3c5b73aafe18d89aad66becbd4251c4d93d35b4d3f2a45a69629d269fee43852622d656a7f7f9abca8142e3745b9746846020000d3140000180c06058321915840281c2d7a7c14000d77984c724c98c9c37112e3484a29638821860000000000002a008188010df3fbc11416fc68e1939ba6d428385c039439c70c73e9987a22a438b8b27cbd3f0ec0bd2f1f22d8870c8ec036211322c125d046ffcdb2a9682ecfd7848c359941eb62eef31ea41a0e9b0f22ecc16e6be837be6b49fb4794791d7be959424e05a7ff7975cca5eda5be88d77d379a1029b74aa3b986c2e6ab6052ce5e6d389b260c3852d523674af5e37e735140f685ce331425c46ef50458db95b84efe0fd76345e183d6e036bb9725c2e9d85b0a114569fb336e135508a236340e3d4f9a84c68fbdd4043d39cba62339f6697f30b53d7440adc6af45b42a9ef1c7c420053c20e4b87035ae92f842a1980ca84a01b4146da423fa5704e52259f53c57affb6d941f5ca24f58482a051301dc8b753579501af73808271fa9c0c101de25bb1341a86e21ba0df56907a5f7602ee0ca6f61158c2e1171b889bbbf67d5decbf929e574fd363e6f34f6f033bbe9d0ce6ae59df543f4b5ad0f5cd38eacd8882e9400b8ca96134338d0060ed4598b28d11be4b90407759965c2031640a104adb086765c590900c830007eaff2eb4dc9aeebf581a4dffdbfdee4d2df10eac3c7f2dfd6ff44e8faa60729746b02a1964910da4b533abb72d90939ff7afb5f288cbc1bb2c8744846e69967ea7750d08d87093ea4586b234ac576fb484b9a2b67f5000dc66bcd8d11629fbb0868d2861964711ed1c7088495f57397de8d4a309629a1d60c37c9111f46aaa07df2f60a789a99d601eb52b2b87eaf928d464531cc7e616f056b63c4425681df837349e18ffe0665ae9fb253da2fd7f7ebedaa7053793adc4433f30d94d30558bcc756befd89445c16753f59b64fa10fed62d23c4cbcca728eb1fe505c37a1dc8238ce0b6547026e71310fe90e73d0c730e421eabe4ca58f290e85bfc7207c840ef50cf28491560f6d9d8b4b19799f6d4d1cbf5296b7227dec1b4af47bf42b52f3b52852821db91d977c65dbb011e82fbb65e80d1b6b753668d8185d961abc42463504faf64a8ccd40d40da7a643e0f953cf77738fae3b8450dc3f88744e504222eaa0c036d13661f55d427d44c2b46cbcc2279e9fe2d9e92494a6bbe651ccd1d5af1906c83f25a542fbbecf013867219334dfd11a35417be63b4c2bf85e68ec4c21eacfdefc7902456f12be23e185e177779c3f78d9a0803cfbd8dcace043d3c748d10c6cd1fd9f34b0f55003326deb343fe8dae37e632b0803713f5b0473dcfe09f2d421053924c2eb654f1ef0897079a1909bec637fee543fec201de7c8caa3ee2046af66d309015204a001c4ea0f83865337b95722c98f149e227d09154853184e3657e2f15662ebeb3477047081690e22c62b91c12207ffbd4acc6a948974686815598c5a787fb28dac43ee0d361bbb0d3e945ac7c283e46ad40634900dc1350ff6f9fac9c285b9595ad7f4c281831772578369256fdbae12c7c01f0a86554d72faead2dc2d584589a82fd6b3739ae140685a093398e39ab6da2d3aef3bdac73a219bce352b3ed8a71a64741e8d500f011dd18ea3b2a211737d0d6b9ceeec07f7f58ab2a8bfd17484cf7484d9f9edc399df64d1d8329e6ee816adedde4596aa0ed2ce129ee8ddda18fd757f64023078535d1c109bf4eace3aba2b11e824656104e1bbbc0ad1c7206f3255041dcac6317b8cb230a81ad5ad58c196afa96b160506dc04acec05d3350029c34483d9b8990c9d32aa309adc08f7b491adcf3e47a45ad764f6024d1ec84dc78dfcf17038cd800167c74bd155f586ee9a626db3ec90c8a89cc5695601388dc52059cdb936c6c1281642042e301eb352ddb5d6a7af88ca9bd6fe37567816108c9eab58f80525ddec093759e7e9ed9d5f14954a5b9ff4cb93ecea763485445cd3ea8ca0ae5853ba7ef3fef741627d1fde17d3ebdcbf5f48bf031a2b2f27bd360a4b536e4efe4ddae0ee84e3b314c11f98ae123c429195f4fdede52e9e6a7f7c0d867ae158eeda51c704bb242a5548f92743812c2124edcae58c59b47cb3a6eb33ae1aa8f309153c7bfdc3c07f5f9129f16ecca4e9616d0ae86298611aaf0939b63e3e16cc5811e971dd290654c5506ea473c3c5a1a21434f1e1dd52a42951a9923228637f30edce85fb6e42209967c60848484b5e8db2a00c53ab31863cece850edf8ca16109583c72b0dab416c0f9bda585e091ca3829c40c0b9432203828fc4b3c3db08ff4093bc61e8b02a22a75de6e7e51fe8a4ebc88b6217ca056c90ba61ac70fa9372bfad57a9b937d3aa3fd8088df73cc272f4bd6b96fc5aaa1dbe4a61720dc781225d90b673814afa0ce53140d51ef58cdf15e7533dac44f8d8388fa25a89b94f235a44935f5e75ab342908252fe5c5c0ce5700a8009cb8061de7a99d0d6a56df6dc767e725ef29978d1e62294b940a6fe088b1b9f29f3097127957996fdc654a89a6e4bfbcd04593f2ff565b9e794030d3d9d95ed54703e7a0e4762f4a05f10174f4889fe5126645622b1e311eeef268d62ed3555e1c38529359b29cde014619720c59c0d2e8f7a17493a140ac916335708ba24eaaddf103ad728f2e7a10b77b5c9a737b76026b17acfe11e6f6779852dbf661d56762db623cbf2b8050ffa974d53dad7aaf9566b919b7774c0efb0212a41dfa65e84c27bd2b5ca9ae31ad02a34c7a00db57b5b2d81f113350a10b5fbe747f8a51f74e02ab8b3a6238e47a8b877c9c63a66219e6b0e440e35ef9379467501042493ab185098993d052fb57bc502c01e9f2110c4618c72c4678947ffaf2022cc0d86cc64634f68bbefd1b0fe8a74ebadeb1013db6b19a730a24f0409a85c80e5759d0f8d225288e0430afb41c6f48c8d9bcc1d6acee1673388346128589a3eb01e6be135d13eb4c042ad5b1fee5fc7b8407ad6a8ac11778a785105e0da8ccf8b86155908791f15f11c93e4dfc2c9617e4a0b246a3cdaf7d7c8e31800d588090eaaabc54490705670e4f726ad1caacb41120cf8062cbf3e00433aa2855a9cd4c72aaaaf9d85c6f015d7001194346ce6a9411a74fc147068890c2715d6fcd06e5d36cdb157f6e206062edce0499fc2468dad53d73bce1016f06a5d534cb4b9b227ef86445db74de10271c7a88a014c344e6911240ee78b4c1621e1b1f7a87964034a6f5bb9a7b5e8d3a7931a1f53a748209e099b771964db42dfa653315290639f3503b06347def8d35d579c9e0a6fbb0978615f728d1eeae36e6da27f945cc05c8b29d2b0752b68c04880232cef1f964e66818f6d1a2a044030d23928af467772af42de8023e2f503a37bc2972e2ebbe8cbabb05f130a2f4db22b6f4452ba201ea3c16d9737a898de8413056b292d1e93e18b393624f1b6af4982db65dc955ed442d92fb2d4c44295480a50f4a6763c960f656ab6d82737c5b4764317905846e2967fd1fa144fe84e828ef904740b2d3509a15568fce0733469a0af51749040467c9d8abdf3ec86678da489a86c51ccdf20d9bba9c9a10a21493acefb89f4124a01ae9b5c36f2a21321b192b18c7910a134bbcb8a326d3a6ce1a65a4385aaf1b0b5c1a8130b925c92fdf42c98eacce4d8930dfd0459bac17a15c2275d1f0e214bb9edd2b674fb403bc41598286f41ec868fb086ebf84341617d1c820cd5301caa7eaa34906278e4d4f4011aff783948690480b6e30b670a58955b24a82f8e8a940a2cb59dd548066e16a04ba71cb36f78394bfcd1453f49415dc2855ecfdb4f42d28849ed44c9f51e23a53a25ee003a6d933cd0781ef91d7573db0f63ccf87cf0ca26be8495eb1e06d104eea5a87fab87cd974c1e626a745ef4685de7261b4496e5a49462d3b67568ca821d8f2f65c9577f6fd594ef10a414bcfaab2d96d556a4f8fffd00cf0b3fe662de8b9d178203e0c6d861d95f4c70e8913a75b38f60ab00e3abb0aaf7b5de3629a8d448297982a21e20a019fac1db5e10a33ba3c00cc301a40af6cc506deaccb982b981ffb64f97a769b91b4de11acc8ffd8694e505899da04900f87f65d37986004c1222a81ef06be634aef422a700bf783c7b3500b2398d3ebd6024a70cd67e3ed21f1c2c27668981d293d9b0ad3c9b59fa1a2b38b32c5e18ce0e5b9ea9491807c5caf9b7405f5e6a292ab53334be0f03f8d750f7f82848de80519b34628e62fbdd9585c772fc459802705df60fe0831dc399ac70db73c6a3e542e320c9fcbb80dc4a3e29a010ba6b5bf5f4cebccc06ac54f1c33407e39a45507e2cfb3bd5dc2e451e36d7e1b5950cc3640840e89bc45c0174c59fe31a22486cf2b62dec2fe1a9ac65ee04c82ae9c3946d6ddac1a8053ec01a19a5cfab8afca6f3e0a7f9bfdc03c568a5f12d166e503659993e619d3b145f11c7254b8497961848cc62c47714d43cf7f7b84e643dd1c2c363b73383393b10324bad722fc410b60c6d38b44f009ac425500636acf2d180b34acb4c72b3b0a31f2be2eada2c785284742f21b81938ca1a52f7e3dd27412434d316947f9c2457ba69b9c5ac75cbb81ced1dbd0fa701a19c76d3942fa5e381f2c0c4f274cec4458c4987c3d8903458e47314903657956fa29af88a22cc49cc08ac33a9678c5f318d4074689d12b56c90daa79cb65e40025946822e6103e18c8e9b8910e7a59fd788c31fc30d51a9734eab0f25e9090e6a26eecbe8da317d7d8a8b99a60e2dbf698ef4bb406d391976a69f7478027dd3d5db0ca93dfcddee1b8892a4ec8eb8ec66fcfee2593efa570ee13fa7d26b7d7b6145899bb7c0ee822460ab2aeda0b219cbe3d678f6e3de043e3d76d1fd1d233497dabeaf31cc47d48591677c3033e7b0fde8047fcfd1d12415b3dee8d6f06199ec55c04904dee665234f66f59ebf7ba840220fe5cbab3637f4ffa9e8a9c59da675b25001136619807f7a5acd1319ff2ce814bcbb01c3928bbc425c40caa166eafb78278b116879c98756018b8bc8a94922f4a8eeddcc4c5c9c3de741deb995dcd50da11232bf78e242916cba97ea1fcb7ef479d55209e6c48913ad83c8f110446f7a1166c44bf180f1bbaaa104158ebbad2ea2a4236f44e658f9821884ff8f90cfee783d4a161c9a0d12386d3e27fd98a27448748ec9612ba99a66258300558863ae49d1ee342b9be15b06d4a4de1246d8adebb57ab312861647ed5ba9034fd49c4971346cddb1b47501dca38fd799ac04c0cf62a765cf339815d62915197eba18fc5959dba18e731419e55eb081613cb29db10f4769ed8c796a4fa5a2f6df7708aa7ad6b831efadc91b9013ad3c4c976ac2c3894096a117aba338b63d1c61ab4e049606b054989c751eb89c4bbff00a5aff4339b6c29e421e330014253f3358bc34926ada2b54bd483e12a9800e9297e91bff59abe75cf90fa2c53779cb012fd061b25e5ce26370ea529c42a5ee0bb88961a61f4d3dfeefee4c03480c6870bcc18e42830b5bf7028eaca7d9f6c3d50378d47c0f7b354ddd9a260e9ea118e411b644082e9a92994e94e665bca2d0670db440672c70b0027a8ac42ac6437f400cd99dccb6c74089f382f314dc486a2f5e3af36915360642600f87070e3bba4c06c6840b2179d1a1003ee9842fecaabe753511835db8df110998418100b370cb6921e37949d9771b3111c2dc74a86fe276d68619a752f332201ecbf315138f377eef90c7761d78c6e268ac2b2b9a9299ca316065f6a1b75defab79ff4aaa3d1722a406b0fae6686b6ba8ec1a621f58644ac702182bf5d9b274b863c83c7c608df188a437eb6823b2049135837851a590c1c728e5b745788eb0f4b5808975b31701f4941b40ec6e8133b80ee02a69e14e7bfc1149fdfd10a62a70fed82cce1e707e32ac6a11f59ba9ded4e25796024b1c729b0e9eb1a9e5f28f7e29ea2a7f2c37474df742470a44ddf75e180414b8a10290cfde0d97237c67395e942d233be269c6410554e2dcc5ab313af66b608c2aeb861556b383ae4629ce308778595f389b974b24f5dfb9cb8ac9019650f80ed15f94c67dd048a858f6ebbfd8551b393bbfd275495eaf6c4229bdc9bc885bad1a13312a8c6e73cfb003b18d924c02af490f4e6c86d3b8cc83b8f493a2f89a22380a5d9dea0e47a68d950b697ea7bb8f1a69878b6d870f14b99c446cc67265c2c78152dd674e4ad9ecb4c76b62b77c0d0f58655eb1b1a0144150a7926bad4a49c39b6ef8af0218c05affa96b0e31ef895f9ea0a684c072c18cdb7c3a6d833230eb9a91712fee75167242de473aa6e5b35e6782982ab068a5984aa944c7e9c85bb1ed8cbb05e5d140e0736fe3b4b774fb72428d714a7dadcc9b5779e9b7ac2c22d0e35471af7d2a3ec91bc49b5b58ed3c85e415407df96cf8fb67634b8b35901f299d421f8d7da1041f09580b2babb23fb6e8c93b16c1ce6eae2c60720211843db7a5f857c7b1ac0a4a00515a138934bbf88774314ade4b2beb1ed3f14dbbe19792a026dadd2c3451881689e228cd57800950e378647520f372b9d0b866d953312e1b8e9248cc12951b4cfe3e32940a3911efe1773dc191f220a154fef99848803cb8784cb8d8c882c8bc7c15244251553d13167e196446b554053df7da43d06042e5ccb7a30b12a6e9eaa6a988c2f6748dadea5c6ee8313657fe6ec84d5567cce4b24ccd760fe080f4f465aad8147d8fe1a317803c6d2aaa841f9e8e85983d9dd9ef13ea14b104248559a6d4a790ec178f57fbbeb14601983daeaef49c06b9658d34599b596b548d7d161482392eec030769aea81d1efc9b2a77fe0ce54394775e9b9fd4aafbd44db4cc79e8787c862e9e8b3c794e9200521abc41c4952d3ce651949685340ffa65219bfdb6d9801c26f58c9eb53353e5d4d085720e2d445b17d90551572648b6941544171101571e88216b74b077384a465568801c5e6ff331bdb352f2e97a7539c446949560dd1516b092caa3603a946218a40b8d9fe36957196de6869564abf3f47aa19e833ef78e90ab46e1590a113ee67c415576651f3e91e76481e1919c35b12d2a56755b8e5a44127162cc2abddb09e09052529cc6cdeb3e58cc03cd0e14fab33d0afa33a93e170c6a0466fa51114a1f5f3768c1f23e4815cec692d8662a0bcf136a623067a60f1c9093d6ef8cec51d4b3f65217b9a9b6f8a5ae6598004943279803464c95fcad3a3a000fc1f9fbf002f3d26873b4406d6224c261085d7fc4c1ba9088031e5b0e5f1f483d7a1a4ea80da9083a8d0bd1e397ac591886f855b2de7c375f0703b5398e0b0a3440b19f3cbfae6e09f492f4328067205035224b6a4fbc44233d78f18cb43a13970949f5834c4f40b1495b8e548efa78bfaf29955bdf5746e76aca1ac9f4b15e4184ecff0a35fede4c1649c6993bb28136b88929f0dc17260419ded7ec09d8d1e19b4037e48f57d2de6ca730eef147de7ee11336b3594356a2ab2657f2b1e720e69663d3fe36882c5ce9daa39a988880b0d1ad0fb73f660e15f6ee0e6cabbf6624669964f2d1207bbca2bedc8997697472588cfb9bf14f993adec19cd118909c29f31416200e89b843e74d79d0df5c610ac3c5f6ee48889c7e1fb01490cb1a8256ff117f837ed28fc761e81049eea7c45f6d130b29c52a065645100c4b000bd424249490a1d37b6443dd88601288d22f39b894501d4c1c8b64495c2df3d39d7efb21540f646cd9be060fc7c389e023752955d64bf53cf5da8b7fdf5552194bde3925aec7d23d1b46b814bd0ab50e82da3e777a1d6b278b71ae994a0ab2e140e14b0659979a56c2d45149dc04231f9b1dfd1942fc36a95864d4fd4da580e187c3b36e400fa8a70f193fdf727ffad0d95248bc1e2ce03ec11d5d8d3e1e32f331c047cbcf737da00bc35460330e473ef7166fbfc75dbcf387be533b00e9615d86a430fba7663af55690463d2f715a8715333b1ef6aa2e0170c4d2e3e912df3221e861128efbc10eea160079bd593ec5bf4af22eb648c8b45bee1b2da6796d50512177a8bf1025f1a4da4a144a5d8341bc40d4d8837327f36fed53eb1eb9e690396539f699cf9ac483cecec692175d619371b974e3ae5de58e2dc082219fcf1f033664986f15bfdf4941b48686c549143012e42f6123f4d8be8c19c510f3b506a1b68c1eb5437dba20277c11d94bd94a671b2f0f071c5b43c3c1dc2005007022e4c1b5c45564005f5bbf67b8a09eb06ef25b36b38945730f1d903fa8445295c71b9a706212cd02cc04c9a7ba73025dfcab49faa1776fd64cc2419501071d20d37c7b001b5b0a4b21955be26d966eb4a731ad37a0b9c8cddc0cc27def34a06a00cc8edc2d982c4eed931cc894cbb3f4cff3933b7151b71dd7f132a195ab05f9e420f3f6ee5a6bd2a189231887b9bd3b46f3a7b8864df31537c50ca7500f13692fd427ddb1453dbf872dc35c36a7f88bb69668d8672b9b48c3bef9e99e9a5e1e4d2101ae32bd079e144039325070725f0609aef3c552d03e5fa17041e3825db33711064a59eb06c2f9b7e36834bc715a4dde151641832f11efee1219db1419c1000fd6f221b4ba9f31cbad579905c6ea7dbf142c9da8950065a69819f99dc4862146bd2ce2d48c2a83d5ce0b1ba64d7baac7fc7a87254fd1ee0f762e0aa608338393eec2424f6fc169a6a6969a6a682f07a08006a03c797c0ec2392813cf6e75fda81bf6c3c93e844b61747a1c5d72b3bcc9982ef8af861e5299fca2ad589ec227ca8b1030b63a8e83e4bfdecc7abcd1864be4b3b45267731dcbe4e8d9752413689f2e1c50f009f438fb9ceb0e39296c816c124d44caa09bd2161db0f8911a094c1b487471575d552dbe1272e996a0660d2daa49fb03dff9b1a1252ecaa70971217b4533a0e7e59d8f07871c69f8ffc3399cd04af434440a8c30ffade43a287eb3117bc9116626f4c1005652d28f5468ffbf4f4a3f17290e27b06c1a0f4a37760122d4c283be28dcb9febd4b063c1a5343f134177e152e99bfda3fa150d25c15b6a18c69b8a46c953026731f4721853fceac236415266e898b105db0a3121b4d682d90f44770eee7901096b539863155e3e28b8fe235e5d474b4b0529f0611f060379a3e4f37d8e0eb397c932a01ed678d9018242fe6eb4b5d36be482b957c0d11e7ac0cd842261417289430d12c5d081227d207facc291cf02d22a75087ec0d9cbce192600c32fc62c5ed331a8fc5e463dba0d4a0711a1545b4a50acb31a43f95991d9b746d162c099f7fd8f1221224a8c416fb84a589056def4002369655ae7708909b982b4e7487b6d6089d9d0a9f7bf113468af5364ff749831a6c407cf782f2f99927150d93ca91b8587ef3223f2693fcba2074ac93fcdcadb7e89ac564c4d16a83975526e813790aef8851ac4b6adff1e1c41f84ba7bdfafa026da3e291802810610d78c34329825710724dd9a5367515d5813ed59b5c8959392ed4c462537da136ee3695e2495a737e5ebb0508d569ef820045d693719f549346aa410975f73a1b2f062bdb21da90df7b420a55a0b5948b63133ca6bc586d5c4117d8f1877f3f13832b0ed040127ab0873a05d20fc06e857fd5d43400a8e6623e5253e0a8ef4d85087bde4fd177122448e6abcf6803832ea731aa1c95fdc574f60328eee7304754f625f27681a37264897c84df8cdcdff3eccaeb95051646187ef0b716d64b5043189928a3710ff9e2763b91841ce42b10489414382b319a65ceb0a66571213ca6d2f546df4fe7d8668188389035e5b435d5d719a83d8c44079dfabd196f61fc60c26fddf345c7214cb6cdc80050a7a1212e9cf3032be97285421af45af006c4a28bf674e487d13653d141eaec1b729fc085faf2d6c6f3dd8769078bbe3aa86fb8b4258f6a344a2cec17070dfc698413a5db57ab9ed6ae9850e6b8e460b6d6c08853d287950af928d296fe4bdc7ef793f811a326f74a23eee7166fdb83971e174f140f2d243c9f98a33cb8edbc18faf98fe2637196898be92a3c94aed3de3b5a30d233ff5b4a22600a5b91174c649e5e956cf66becf2f9b741132ee7f8391ca5ef43d3f45f96f64a00b50b9e087589e5c15c2f42d57e0a95e1ccfb449a032b6f75a196323eaddcc37f24cb75a1060dffbec358a00b0fcecea97d04d09a50a578f14c92c71ae60ea816c4b8daa0e43a61c9ecb19c2b557b2637445416e91b1ac0d7c6bedf4cf8298e1d57dbbeb25a25e3321c2af5803a4d1a14e3921e4dd681ce948d9ac27b82a43f6f23119b0de4ba31108cf02ec93c53038a7163f2539588f0262eaee92e66ed030cf299fa03dd74a3f0571c66b5e76f95ba204de9d3b955354f53bc7509dad7f8e7169de94c534c0cbc3bca43e853482439b71d5c67a01bd0d036d65d76e5fe1854d0e923985cc151abed7e4ae614cb4f20aa988924f0b0bd7ec597629640001583632bd388419db9e27947ba6e93427fc3082de2dd24a2546cf3b7024f9eed1b42df7a56b588c888e88816a1dcd43df2b0793856693bcf97abd227ed703653ece68694f8d2c07495ec490c722d02331b960d59c9c0fc7ae2b55c4da7ed976918924dbef442795c2cc922f031c995bdc79173a291c0e13663f964288efb98d839289a615f8ca700101a22c7ba52934bec4f54fac46b11f955469bc14bed644e40184d12a353945c624a4c04f2f8ec36ba18b1024f4b01698c1e5f644983216ce2e3af9a85e2206a5c683c013c1e9c06ef95eff5ae4180e3c9c923eaeb40e7b57180702cefb6d368de9b81f2f6cea761bc7a4f55fa60eacb19229e5026e68e0892a7dff4183db1ba46ce0bcc19e0fb994accd11e87915984c1a508e2c3487fcf240e721b0cf35b1439a51757118b1c1481c0014e1c9d78d7303623d9ee86291ff9589d9a82c7e2d28b14955a7e526b096a8b96df6bd71e7dfdbe6a0968bd9d283bc7b347c39854eff2d18407e77e6d4365230ae1fe5e3e35ed5f49ee1e0b8465004dc2d0a3a559615b511ecb0c0d88487908ad1b29f9969cbe2935093c030dfebaca2454ee37322224fde714d23e4262e08f87f0e063a0bc9fb98fc9e2aae10812e2202da38311851983a9d9c901408159b6ddd435b87e4d29698496557762d9e16bef2b71260ea3d507a08db74187c1e8270dcda32bd8a543a47b1705df594dc0d1cff4e0e3146a0fc3b0778d912e4c8e34b56ce63e880558e2fe6263a4f5a80e963e5b0ddabd64c5bb73a6cdfac1bc260447d243aeada03a64d8dd5f094a2636bf62421f8c25d20b4b26d913508c9591420143211f55929e5b539882047029dd47d7fecd7809fc434b1c3fb8a4a940e9115d2081023f38bc76faf1dcfa48b46b1e20e6915c18ebf4328ca5f54858fc2f4816df280569903e81e6f68db31796c12d24223487aa2a178297a14e4ea390fe483bb8660f24e962dcf05687402390042d30a2c35818fa9de9316b3c79627400688daccb7d23d96e6fff42d7f63dc560675861cc35f5260f6236c922dad351e69ccc0756f8ad67b6e323a13faed0408200a0fbc0dc3780b22e7677cd3b232237aac64f862f33f64084ae221348546aa298c789a0d17c1caf968d3a262a08ee9bdd7653747dcdedddc3dfbd79be29c625f919f786811dd8ea280a060b0631b69941e50b0085f1dedd87ba954b097f5cf7304b2cf63160351c78fa4ad3396b4e58de021136df7c042e51440bf92556677cd630be115e14070e272fa0ae6a6f9fec24bca37cda4a40ddc37c9c204abfa6af193787b6718eaff64c0ebe362171dceaaddc6cdb3b88d92613cecb7c832ab7ce503aee2a0a64ded8c213b91ef35556b84f542792f9b5321002197392f180ee9a78cd21cd98333c305eb1f53372745721af6deb742a1aa622e7dc1964e377dbb9d319ce33e94d11a5d211964bfccaa969003e1d533537ea2e52d46f98bf8917f57247a4fea49c91f6711361f04bcbb320dcc97ccc81c84eccf956111de122cf40fed5e855841a1b4546af842fcf0a4d1645c3fb9505e887ccaa61389e4825dbb23ba77335633c895b41279e46279e02b18e96f566753825a7fe98c2c62fb9527edde51e43ae85263a1ba44096ee8135f2030c7efaf90720e8a7cf44a58953d3d6903d7390dd5dabd20ee242877b680de21fb206a75bf68834759d4a87d31dc2719b513ef806da4519b6271411bfe9afc5b8f7b1b6a0cb0ff02895ef908066ef2609a9730be939a87ce91cbb273e7c442f724593e24b06a9ed26d1ab4a009e67cb218ca5798f35c26ca5b71a2b065c7f52070d5f5f6ce7389f3654b49e888bc081df70334bf20e2c7b2276c07dfc2dd78e0fe6f260f2205c60f882f14180ff33400f5b9badac39d18f13ae12cb7654028ba0d88209d560d02dece6ca161f31249b7282b149b84d973de88b45044d236c23861fd6bc3884989f8a667dd7226a65b7419a1be57b9f50d40c73006ea32745945deaa4a7cd2cbbcddfe101ca46c72129a295db4c91f21895fd63dd4bb9cdaabecd500475633b252144fc64b93ccd6815bbfa47e73833511ac69fd38559a9a08fe6bf67e6197f2fffe35d51b0dca43059e8e54d206b7ff5fed050e71462428f233764f9cd883067ff7477984140b0acdcabc8ed97b6c001a6bb506571f5989e750145cd7182f8217b1e786469987e171b8dfb6007d39873a0c2088b278a1957d20d06073cf723b09c01008c52f118d5886749f0625dd612e5681f8ffe209a0124e6d0df07a9aca39029feb3de5840e3e61754e319a7628628ecc7312b19ab64cba12aa665c25348be574315432a751907eee057ccb1655b97718795713db1a76ae05bbeccb77395c9318e8fb539bc6790098a7190775ebfeec78ad4fca06954db4a18275fda419023f85bfd0a2fa705d335333ade35d661170fc0898a8f0759d3b2bd097a2080119db3d99493a626e3d0c5e23e797225824442b5935c28e2223020639764006eef088eb8f57a9d129859025f2e1d5cf16ecb8a6bc6141866192d813765ec3c215f2cad6c0de3cf190d94da301551af1847db2e0796aad32049ac830c25a10fe15fabe4fc74af39f9285fc19d6be8a76e55b190609581c8d070d0f708b8230bd269ea6c1f2d7e9681009511c0c9d4394a90b6548963b35399633bbb9b054a6b36c44f28cbb1860b1fcf65998b991c981b528b27147e7000001ef66a784360cf301a1bea9274bd7ca70baa9ecd245bf84fc825de6e579c629aee8f7ec0e867b30f742cdc2e45a9edc8c890b5075a8bb4e7c2df6c7e4a4159c989d941d59451bb67695a00dc60474134656936efaeaff697739af4a57f9272a9a6aeb2507b4b536be4643ec2189681bde910fe99dca4479c6681937a77e4f1432261a064efdde8819d950b5b00a4bcb1a4eb5b1a696ea43aca006ae917eb0ff5922430eb1f772f6b97ca30a578b4ec97585ba188025fa12ada180e563e3387a2e2d875e6db425555f31b79dccb1475a24fed96d52316aaf6a5cd932f85cb107c7f9824835859b396ce9302b104951c9c736befb0704ce8f5947894f4bd204065d4faa47f212dedf21149a602d261954d7cc52a896e81d7b578b381f9c0bd7694ccc7bbe1806537cd04354c002680976308d4f637af2d4d988beee962611a905c8319e3d360445f3741e7977eda96c0678465a7e08f367be9924f75bfbdafcf078b89221532a0bf145e6b5b9454498d4b35c2f993a346b39bfe603c57969a17083a49d724b09b6e2b92adf050c6e40aa8f90d38b5bfe7a3385764c05096cec3adb24e6e29fed5199b2966911bb70dfd6801ba3288ad9728f00ebc8aa431ee24fcde9f0457780e88a57a7872734befd65c282c5385c13cf1b7e20dea9f92ea843e015f2553c27a8697e0de286f011d7de2e5f185bba452553ee65bf820a04309bd75dcfd79eae5366060f09a9836a0723c4e9beaafd9f59ef4c2adcafaf8d0446cb7f84699a7efff1d32411d807e771e2e36b7156613f36246b20cc94ab67013d613b6b38cc7799445b435f1f8c0ad3e8d2a051575de7f44e10f00f320e664aeff8d9fc5f4ef2eac3b64a6db536b18d5e135d0dcd30746fd57fbbfd3c5c26fd1062e76e9594cb2dcc424cc8145025b79eff727ddfc86b24e3bce3161eb5a3471a1a60a12333c7c49496ea072ebee09659f78f7ad3dcc29bb7dabd0b1a4233f623519f32b6604c9feb7391181b2f6d304024dab983b833dccafd795e83f1817a87d00618d12008456ff77f440214ba82fc88143e5ff403c07a82a3fb39ddc2544d7d45ed2ffc267034b3a60291be53480a266152a8a30c16789d4f90217a19f7e5b4fcbbed992bc6b064bf494888e01b2b91d04d362478b4f6a653f4b7bba916655cbbebc8bac47745b9a16e34e4c709b8b05ecc39eadb585c847a02bcc593d964e63c423e414ead3113cada04b6fd6db9fec86f951f3a7b51193ffd63c8f81dc27106535c05c26c0efa52303114f43ac43a16f757a8a9e67f4d85f1f5cddbc190dc4f58f6f6333e0fc847ae275addf512e75c638f9bbef4461a0be4eece9566d315e9aca6265c8ae288fdfcf474c3e4fe3023cf1d4fb04e1222aabb1920cc118b7f489da1a1994649d644482b00764d04064ba7d23f054957b666d8012eae22e413485bc2a8d3ee75fe0a8bb80582f50ddd3f5d6751d44c63f76344f6d220aa133df4de18d86b5df2fe00c6a2fdd0233b1849b5a644dd3fd3b3d137f1a4597402c6faa9fac072a9f9c55106cfa8f4a36d3be334585445be77da1e8c072b20d8da1d464ec5053cd0b562f183cc8d8f1a1363aac40acef5dac70985f2842507870bf9dda91dced1a5c2c9a74eb0be67ae46e4ef49945208933da97b2a177ba5525859524f4c394295cf25fde937e1b4c02441d128a4345dfc4eab765004af4a97e88343dfd3e93521815972bacb25ca5b7226feaa98986cb2a1d4fa6634f04232adfc92cebb9f66b7bd5373c4a37c323f3301fd88708c52a01201ea30e6194ff2109128b318dae1af48bf420f4afa8e5b18236acd8717fbb265a7a72bfe1c631906c4b794e707b5ba2f94d243709a599da6e28724bf5a080b193315f9bb3f268f3f0a2980aadeceb715d091d83b5f048556b8c65adebea09ce19c6a526c00f44f18cd92a7ddb288bde3c681a513c099031b9af5da8f94388e36d31097f1dd3c128b3a88d941841c5afeb9cd295752766d3e85353ca02e3fada6f6c785d63f715bbc51cf480b4861a3feb90280b8b1276aab953290e8c30654f6fd3d11a6dcd1891dc51e6a51e5859a49c7e1fff56aa0fe80d9eb4d97cfca6490ba583f388702a3a41b23787d1b4d6aa81546e6eff9cb013a3fcbcb115e3fe7e068d8b21c420dd364283e4f1a36bc68e9139476546dfda5982cf3aa138181aaeb04f7d2b2c49276e90ed4d438214bd8d471df05f61c706ceae72ce548023919a98f7fa3169d0d467f982154a0f714c1f7eb547a58e98b57f43c4c5f33f6ca381024499232988d1b58b565ab2435e6cb9c35f25b1209669968f2f587d4a73aad5eb9144dcce87c224f6e78cc906b9525cb50775048c6a36263452d3af46260b8f72a15036431a1e6830fec2f8393935609f21f119798baa429fc4a201fd789dbc597fdc1691e8114849d2451cf3772b9178fe2712b59c9745ea4b8cb103924d3b7db400e3d9ca1bfb912daa478008c21c2345ef9aface9f66000388bfadf97ac2bdd523d7da6f48f88e828bd30a5bf9e5751a096e5de821a194d30a48c430c34da648eaa5bcd34ea197d40854be0e927de87d5e3a93a8519f5b56e7a978271d207eca08f90e0197bff84adb1db5c48c1c899540f2066795462ab2d86a01870eebea1f67cf280b03ba5ba14b0ef7cc42ee7083aa1f373386abc9160c50262d10f93556daca5a180bd1213564d6bac95973d0c9519c0d8559b38a2b334645a554f2d563069e7b72e3d3bb89a89ddda15b31c30c07c373e39b5e674863b72ee4e1fdb42265febc6c16a9df5f2f8819fbf7666f967007effc78408f46fe50f619187349984d3f59c7ed3b46f27bce1d9711ce83e43a6f657d05a47f3f5f4ca39da20a6a947ebeae524270ef6fa44fa952dce8f527eb6bc8818319e73b05a063723d673108e2820b30285d8f83eb689e2eccf6ebcf2ddd63e313bcfb3e9497f814993a251420e79efef3004cd65f44cd16ee16c4777dd44abd9eb8301342b3d53ff223973471d2ec5d2720810eb5e1da51ff9d583e1deac8d97aa84da47e315f31942480d10b8e3f7aecbd0b160a11084df7b12259a0d99ddb6e606f1439551202b33c5bec2016815ed70de6b3009901855c7a3e90c515a8662bdf4827a25ee665ca178c151ab0ef90f464e42b9cfc00fe404e2629087cdb0b57210d77238fbba36f7d53bf5d302580c34805f77a32ffaaa06df248fcd36edf08567e5c99286b0ada10138bb8db9ec1e7917e5303eac1d3b7165aac99d97095718f43d1e1e21f961c8604360639657878cb8d2a988cc6fe14b4838471e93d9b5f4000d6bd16096b047656f0a3c4a6fca24b4ecfc37a1e300fa3b13b437eb3db4112ae99913a82eb91ef2dcebc719aaefc0e0301a1d18c76b31ac25d20d8837c504df01834f6a7a03d248e4bef6deb4e409a82fdbf2cc780073f4c748503d9a881cec4005eac9951d46c53b792d3c6c732168496899510370765aaa9ab611210a35bd7bfe0938d4a685ed62e1ac8a09346973a91a5a8c939eb7243388edb0db00673a351b1733beaef82776b4b567812666fe0114ee0617e2340b0d4f0d4358080c7a09a961f25cfdcc539ef61621ad90036cc9e15c009aeb6b252452f3e5d3f5d3094ef5c23e793a22fe130e3898f7632c0278ad9cf005ac99510a95d48a03afdc33be9ff03cc32c40af01b2832ea1f51d181c14b186f5d155afefd093e31f94be008be92bc005260751aa4d83009b20357749053ec65d5aaf98f595c1f185807ea0ef0ae10572e683284cf7f4dbd88b4def0249eb4f946a578153bd4866ff0ffd085d7d6768c37c65732b9355e67356034f17a9079541f243c462b031951cae285944be967cb6148781a62b03fa70a7d4dbc7a1a755c2b4d1e90b0d47d97c14c3272af5edfa3a6fa87f3c0a80879883c2a4cdc96c406b3e461c7281a6c26a1ea040428e70d2e74caa11eebbac4639f8decc0edcb82ce7b68c590a9b4dda57744bde3d7cdc9e3c274ec5b73db9642d10e3f47cccb4614017154daaa39991191e2f27352180cb10faf3cceab4dcfb10e5234038d9f61c4e06106ec690af1cec6921170f0c623e4e04337a7be0ef7a0ee1230da2734211c5da6a171237cee84686c0ce14fc6553531cacd0e40bf13ab6a12841f6833d39481fde961702522b84588f44be52b874fe68e5fbb461d716d7a9b49a923f02208ab0f55920afcede5c53f3ee39e083c9e01b997d9a6e0f04021e8678dc8f6a3648f8783e7734c6cdc9b8d7dd10a4e79435b3fe402733bdbd137db27667a7266538da8747be52d6c9909721f9b9a13bbeae1c7b014423a14f18913403b0b1bbd2ec02f1485641a9286ebafd37018471432318e0871b29d78683042d07c6bac0a083c06014dee087606b92c2e9219759d7bf85673c7a398e72682dcf681f29cb410db429081be670285e91eb4ac28c70d5a9504eb9a502f6382b9f6f77c250808b97d1f5071b1015d55002acf2f9f3a09681050c58f9b70deefb7addfc0d6b02057f60426e21f6236cedf3d9f54eba4a743f5e29d1139ea8ab6681c02bc728848c03e290bbca49dd959b82ad7defebb7c9d789696dc215215cd533684f108c8d24b2016cf0f39e0636645258475393cad28f784371b83c5c3f7772a4a9f7dab0d241694cafde3a086230b668b27391220a6af86bd93c4264d9a1b676c320626ab14187f51caf9a374a9961ad5064400834365d01f6f43405128d12353200506d6d3c3bcbc184c7defe8346c67f45a8fb83b1b679cec59a613f762c992583b577be8082fca01b3b230b4546301e02e3b389326ca9eac9abcec968451540b68171a2ec2b6751f8218e2063df99b88ef45c76447dc1c6a6bdc886ee0fb7322578d10acb78ed89f2a9a06890b80ad54e0b48a6dc8ac41c04c35019f06a57bda24a7866e461ccf5055832ca556880bd87a418065eabbd111f1f6006dce20aa55efcda4387ba4ab633d31679eed833ea693f82c6c6fb7a9b826fea1b3d3d1655b442cc4fc08eed39567688d5a10178a766d115b21a1f2e59dd32e0f7c6a0d7c4f06de1659aa683b09962e31a863dc582b2946a1de2fbf5c5aa4d01df379e4a7b78ada380cdd52ada2fd737e043546c941d1407e156953a217cf7f7711aee380bf4a8c6bdd176efec9010a614074131beec2b52718696f623212a6c01d18ed0e23c6b8bbd3fd63e531999baf804e971e1de1e4dbb439446c59f9da1b097a2a95ee30bd0b2c7bde9a7d03c46d8e6ab01d7a59e5267704fe8d4668b5c82fac7192d91a60d547b123dc8a8255ab43672412f15b0f1db95f0479fc2297017f4336fcbd9faf54bc5495a22de5b0d359c6c33e872ce0fac226d0a1fd042d0c6448282955b92cbefe9844d7cca12b4a19167461109b20552387d25d3a7ade56ebb79441d50497b923651be1551c5eac20100e88492a54bbcf211861b0e41204c5336671b5123d2317e45489b45abc79fe55e0b5b9972d21f0199994d979e8111caf33ae07d13a15853f88aee26a0460522a3f9615954e35aa7a3d9fd064951b960a9a15914e2965286d56639043f5d4dd29a364dd73414d0643a9550dbdc940e351ede8c5bb304db3158c28dec2445cb016896227985d7588fb225afad8707771f0d78967d2eb09f6efe21c8c648cc8867914ce68e5590d396c74bfdfd20fe8aa53cffa8b14b3091d466139a97c82b6caefc0ff078818a18f8ec208c20c84fb214b2fae3a80d2ca189b181d6f2a9850b5d79920069086930a0298df90a71ab052d52fb2507164f3c1b7518c71fbaf4ed5e12d4dfdbee5b0199f4b7d0cf1e237352891439c9aab3852ddd268f52ce00464f03b6443aa40e4fef5838f2f5e90f3dc05d52d8a9e2d7d279615e5eb321260fd19105023763005ca06728d2bbb5620abdd05a5cf0cc8c0c24d8ff86d5ad0223b3b243bb50ca3fab25bcdc39760c04d8f2a0bf814f19c68119b5c8f0fdaa0bf7aa75274cfc30b1672c1810a7c42a0f9ecb7c8db58786ee6a34b91f792ae2f7a19085890aa653f182c844819aeb445b387341bfeb21129731307fafed2e5177b3664611e9b805e242207a2090498f8d3b41f7b4f03083e21dcb35713fc0759fa9ff6f67319c2f6377a7a95895e2fa699737cc390bf02d15be435e2ef4eb4678aec76e69264b880090eb241c04488c94ee9beaaa43e3f6c40d6a8d637a048477170818d598394c88540d07c155a3b1baed30fd878edf0828862e5dfc9147aebb178beaedc8e3919e2b33e5493cfb79f8c39267c8a8ed757a6bbdf93bd0d2ba6e643d076fe1fbb5746bdbe755cb2a665cdfad65fc150f7058cb38e7190095fa859f9d51abddc858cd2c86330b585d53f80d717af937454e00f735ecadfc0ceff89c2a0d9e196ce794d25e8d72a55f18bdde7fc8ce1943b08721bf63789929805d48a3ab52276c320006f6ac1e0db86b8703ba61986ee8950a2ed1be38a44defb2db55393de7aa1486a1e02cfacec5d1465a63007fffc92c5af01fab2c09451eee72fdea689806842475a2a518a982df3aa8fe691cab893add33330d7e8a17e1f3223a4b0c414303b7415d90fcad51693565eb4b3fe26812a25befeef5f5b73fbdfe182f12bd73c77061949c82517d30cc1e22a49dc6198c4211af38838ea5b622e5515568b297eb1eeb2639e09582b1a3704b2d636335d85e916e08a53b1f8f175155a098cc6330e6307c7466f8e790833be31ad2bda23d935b7fa5f68d74062a8f1a18c9fb7b0f80392ad1f78cb5b40f61a7220fb79caf4b80eee42b0f6c17df375e0b4fc9a7100af0c9c976cd33a37189c9ae39d853e4e9603537be8c69a6eeff1522f4238208c0beb20ff3d474a47196b0433ff0bbe60ec47e1157bda2b753de0dd8e0784761f146a80949dd0bbf526b87879ad9320635b3bd9df280018b3dc1c65f7c848dde78b2eb20e7981a9ae7ff7a91f2a8f5ba347680408afa6b659749bb26c9c48f72665d097445d2e7e4dff201c0ff010f48fdc207837713eea25af7f158f73eb610e53462024c2c9fbe75ccea90d13bc7f1e448c4b36cfdea86c11641f7e1922d00f2f9e1d4864c91d40607c97ac8e2d8031ebc7f5ba288f5e1337dfcfeaf0d3d5a12019c0fe4c76371811ca54069801aba595d32d7538ae73707f3612655ff26c88d4cb4d8831d5afc0833563d4ac2039d2ea97363434801717a8769013c11ac0ed6ae54b034d4eb059503c60106a7e21fc60c36b599fc90ef24603d84dafd0c4176e38c3ce392f7fc0060960cda47953c2990e57ae671ee8378368294ee13b3d59439897668c106385d9decae81d59278fad64d85ca62f08228ceecdb38bdb70f3f1197f809e9a9a30a6234447e6526f07bb7d535471cc348e7012623b308df1ac4816a19b529cc81bbba2c438872b0da2afca4d3496a304c56ad403a6070ffbad1d02dca4c3b05d90f54f1d82f20c09a1e05c7bb094bbe282e06ff6fb91bd5801229eaba3c1d71676d787b026f485785e9c17993d7ee3a27d53736e86c814a754cd144ffe2283c1359bdbb09422b45c6d29f592cb46da5285927d6546b4554da13cc65ee1fa22740161bdfedea00c7466b2643f0c3005eaa968856b49ad193fdd639bfa7d1e3674c91c92b9aac2bb01bb26b0a6225e6da9ee4f4ba6dd4d75d593ce761abf0998d6bd6cd2d9d54eaced69b7423d572862cb204970875912faaf2350f53e0a0d36e159c77a6f91603a4902b2519dd0d93b259571604dbf3d55765335dc752fc94b23599b08b050c2ae0b5448f0f97dba61425e89fe7d4f692c3e57d0838fca8777e9b514e9af1ea5b4e804608a616539000d469c7d6b33ae34f0f729c360f204f912944639c82ad312c4f31eedbfee0e00b7834297eed56e23388fe37b328d8ae927b4a8efe216611d8d97d8b835619f899c9581c2e427ec6915b2d2a4ebcfeeb0bfe9f9801f4c0275d10144548d8bd19c13e712d93349e3141c881a715d76259441ce4a2195ef70f99707f86991fe35b0a36561d9b11ca3fc497f68c613581ac83b8cdcc3dd9d1bc6eeffe13dddf0f6b95c135c8fbae10b46ba6fd8b91b427cbf79dce92b382b5142dc4469d28a65ec97e83913bea81ead74abf065ad254eb6d3bebeef60a89f5a25cf5d00bbd09ad583fdd17e7a6f186f8179df9d91919469b5c82e9045c8dcc59aca244253ace5f99963aa04ec1b91588041aa28566a89a220a3da54eeaeb5f889d87c1d75796bd00f5437b901c80da7cceefa3254802e8e2d62050984cf78fad896c8178049d84be4b4e1d6a1960795bec6df3e9be32b2c7ae6d80041627b398600d9eb6b7d3a25f718d40b5f18f5384d27782b4de90bc418b5c232b1614e4520b9fa6b47f5700806530b95a170921e1a53c4fdcba30f9aad59ac8b28710208d5860a529e1a1ae1208dac52ccc0dacdba22230d71b63b32c857fb1ebfe939d5fad572ae0828836a8d9fbfee7b880cd3a4278e5a3463b394849e731c6ddc8387ab43e443f6beac6971730dc49f700632d089cdc7e00deb0593caf0ec76d05df7b192f73f23184d42b4f7ecff851adc419d75c077eeac863014de8a58f9fb325ca546421fbad6c62aeebb8959f51e7a1ac9d29b9910ada085c85d5f1837e1b57ae24b4b93f5df9997cc73e04aa36d6a07e0d550ae270cdb3be37da01e4af63c3931343b912cb7debbabadb7b522d5541c335ef0a5d0c712d1e5d38de53f40df5585322467df7845f810c68c76dda9da9fb5a6b7d92fd5b00e9019dd88f5579c552ff95aa491df6dd2fc09cad9ee085f17ec652a4a385ee91732c0557620bde0b8b1a71d7e6103a8e90330d7f82aa9872d9202a630e76ae9c1737d1b658b124a124bb19e866afe9ccc25ee99b0e00a8214fc37ddd4600b27354bb58b332c9d6d78e690052955f4abb8cd7492714c59e1f1a848db44fc601834a812196c18189c36c1fa60299c464e1b246264be61436c4dbe08be8f782c1d1383b32b84e6fdcb922d348c2f6273c4c8ee0524989d1646388fabdbdc56fda910ed365a5cc8694d6bb314956ae4b39dbf999381cd7623de15b9becbede367f99c1db1d373769d30db38909b162e4339603e18e8fbb08d1b416463454ba419d9045a350749ce859abc5cfa94364b688a6939f88b325fb96301319cdaf405354b9cd62f8dd2c2fb9b90189a60bf9ab11f3108cdb9bf0fb5d7537f67aeead166028662ca07aac57fb86704e0d83217d64bd7fad12acf24dfecd197e25ac6bf9cbf0cc65c9bf148ec0cf7fbfd71dd6ab89358a7510a4f014879568fbc7aa6c6391c19f026879578348a59c7d35786fccac19f0bcc5a7d790080459e0b63d50606a551bce726cbcae2c01949aa3d35d47a5aa461d5301fd0b5069c03439c8304e5e76258283ffaa5b01f32505105f740db868ff561dbb0a45b2e2b72362250481d05083b10862da728fb926bb0b8ddc35de8cf87d4169562febd1a524e9b533ad75b41e59e1c8a7c1cba1c9fdcd16eada51cd5d86769b9073a9c442e7acff625a7dd10ade5c05fd17f1079c86334459d97ef4ba29007a5b4a64d804ce84b38bdcd8e02c61d1f793d50c60c7578cdcef582ae4dcca74625ab6eba6a2828937c2f9e6ea9a56ada503ae4d900b0d4ff84f7b01c51972891285f8676c659227ae3861b0efac63ca07668524c3264ca2d3ae502a0a342f60856bdc840d4a0d81f4018378b36c0cf7805f6b52405f25a29b75417622f25eff1ea2337f286acbae0bfe368d0c4580b941eb97328ad4623d743de60613f6cc48f248905479e7467abc63b1d0d232c3cbdd3cc0b05a7d93b49cb47e1bc20b05e4be2c807df9dcc11ce60e8f85c6d8b2cad1e9fd424b5e65078c778c41de4972bb1136dd8acd57fcc7f5f62d57585eb39d43d807705ddf6e0b25bbbf0ad35e417c713aaa90d1e75a3e9e411b583137f019b9453bf00d948ec7e9b88bf6e193e0dd3f8286bec8f32ef8ac2c8588858bab1c984295b7a44a0f43be0a3bdd44cca25f2c6e344304047e94ca94bef7d4567f71e1cf7660284223276374c01ac173b543217e095f77ed05cacff9b88752b540c300f6ab1612f8c8009e470f8e2b7f3853244fe9342640b5705949f58279d57d5a41e2b73ed2942981cbd13e6aaedcb0cb56dfdac427700bfabe36698f757af72b8ad9ba5a25eed143c1bfddaf0f0a1ad613d3857212e6a152a0bd13934a7f9fd567a5230516468f2deb78fac82a90909ce81073f2ec935291c3f09b3279609283f490fc758819e09d92de5f3ebce545a35d564e576f67f45158da1d4646f8701bca2063db25cb02a087817da464a2a48102e3877e02aeea535fd4da1651a1dd565618dbda9c8de4c4fd77c41818a9050688b2578ccfd1b4e23c17de61ac40ed2d61167afcbae548a807fb67c010eb26b9fbb4ce3791f228e70e06b48e8bb44086dc5f4072352bdcd1456582f206bb3c078d09787ab047ef547eb688f07e30c7dc30870156bbe07a2cb6f716758274632606f0089d4ecf3d73658cb392a0528a80f19779e538d600323ecab97a0e33e9a25d1817902306e131759c315b6857453287c0c46930b4e80f0a7fe4ee082359b21a222a1bc1d4566762e9dec8f5dae24eec8ce4ae9b51d492a20e4f923aeec1b74660d4b5afa370eeadd288e63943c6c25806f60a77137546ffba9091b0ccaf2093b6ea353abbb5cd03c56ca06b08a4743232cebe01817d8f75aba377972b0c7386814b35c940b5b1243e75dbe67d8f434ec204223092f4630adc1ebce4f276c2604c0b9785106138d63df3fe69681d790d1a054d1c18d4ecc2583cf7fcb087d5311404e5a8a51613f932174ff93e1bce5580b80abc9a025281091d46340a90c63a0ae926344f531487a6dcd78a6df4dd7fb8b419a6c9d2ca3031aa8c28b5d30ccba9a0ec5922617dcc1ebb501475a21a6bc70491b98de1303dedf668a235f05dc25451a34654439ef38be72d3c3d1e6cea9a2f3a7aa3040a48afb45665745254483e64dd3bf0f21a021ef8af767beef6fd2dade7b6fb9b794324919670867084508159ce241391f8a15cce82573d99e4721215b0e69f32116492f872d7b82b1e7130e23ec1d8a6c5761cfa71cc4d0c721fdf555917376396f38e47c05a91b08220404bba6b0ebcd3b8edbf88d0d39a72b67a753994e4d3913131393eaad16325f2b538dd5e9baf47495313131c9549ccd76739bdf820809827f88030df156557df97d9021df97f3f6e921425c3349fa97ced70f5299aa4e22e71f80ccd720383f3ecda87134b665dbbfdb6c1accd7f82017e69036af43dedc5811799099f7b75a8c968b5aa53a3950c5189732ba36d197ffcca9413a362f833ada88be74727490ea2269527551261a5d8e32bac4b54a91677454ce5fd6589783973dc3ecf944a508ce133991d3245a8489ced3292f60a638207b782bcc2115e044b3ba847e7e5aadff71ccb97e2ee70d290781726f8abb6a1512fa11125acaf4b9a319cf01e3e75a2232d7653ae21163cc43a61b7f0d32027feaefbcc7737e9f66e1b0ff8d7bead2e777d8b1483211bfc683c4af9f45b2c75d78f44e63f14642f0e78526267470ba56561a0511b267ed7ee62df339dd6920d3b6e72cf2965bcd04ffc45fe441d8b1952157ad80f1ea3ce6398e35dc98c70935720005f53eb814972e5251f2a42f4f33c98125792b47d3189d51fd64cf9f547bcbee40d2d122cd9921cb38214f5697e9aa22fe39ef794e0aeef0f01dcd2ae2f99de7016f686e6e6e685c2c0ae1b5f3532ce2f91d6dc4d22c9adf791e2328453ccf7a239da74639cfa3270d196408c9d344a6bb88e76368232834cf13e38f5e34ba88f53bbfa3ffe8455af03b3f027ded3c110bf45797b3a6ce4011eb6368a30de60b5797ebdc6258f05acfea22f5cfbfe6d14444a014fdf3b09ec86b9e8fa17d54d78e26b2f33c12d8d19345b2a69e3734f3e666ded0cc247b3e157948223188fc5bc062c578124a510ccda32d2089b0b4479f8764d17c8c9faf1d9245a3591aec3ceb79f07c0ccdd2af2745f67cfa379466521a1a4a3b3a6f665ee88d66d2190d79c81d92488c67e9fcce4b20e7799ec863901a5717cdb348223abfa369e88d2e799e88cec77831e7795e7422a6b5e753932e36bdd5a0185fb67462b030d68941d2a51f37dd79fa19c88393a44b3436714c2239cffa1d92f544747ee7a994148ed40d95da8941ea3c0f99f3536469a0f33bcf43e777348f9c67fda4d134a665c89c8369ce5325a7b11c927271973f5905cce2d0db796fb5bc2585e3230da494c65458d08fd14af3294c1b3594066b01be699ea563ee3987687e262fd190b5c8f4a15f436dd414260dfa744697350434d3a7359cc77ffab331975c75d618095c69a8a555afb5d65a6bad4cc250e7ea129fc5037cf1411edf8f19c4efb94ed0ddedc67a02196f501a9235dc55b1cba02293d60aa91a214170e74136220265e6dd841944542f3083beba6acab905de4e65a02eac204e2f5e359ab56386e6c397919973cefcf44b9a65e67c99cf794e994c43ffc7ff0f22c4c8c78cd498a5b254760e09aa770c31761e78cf3d11d5ab5eb45b728e4934876ab63f03e690b7c73999f0a5cd73439e7bbe549ab5237c9f2a529470c4fc11e44021777b4fc1a713739cc8fd383a753a6e6f15f520f248407ec99c95166a6cde62e17f244b0310d4b3ba42fdbdf72c1edf7bffe9210ca82ec7f97ecfe25ef5472f4fb32e0f56f7e37bd5177dafc29d2e12fffb4f1b893a08a82f77b923a77dc31d44e5ac95dcd37d1fecc8f287d57d24abd33c42cdc21f3eab7bf18f5e1e8b8766618d9fd5e9a2f0456d04a57ba30ed447af8f7ef0b3af2e77f4e81de09da20ed6dcf66a16fd72d6e8d482fecfa169abd17e708cb9734f054a5d8f53e720f27c23a55b7da54c1f865cce5a8f1e07b0f9b2c70e4bb78dced555675ceefb9cc39f9a6c2197bf417f7fa10c727e19199907694d4d4d4dcd1fed1a7286863cdaf4ee194d004a23d778aba7ccf8f14f31973d1867f0bd05eaef896a06d2336d8fbbfcfd26230579bed338e7654ed81caa2d6ff5a81c9e400298600c24597cd5ff84b5a6227790020075eba706f9f8eabcfdfcfcd4e3fc580522c6d179297871dc79a794cd49085b4af0e18a06e8a65fedfb73d0cd2f69be317dfc9843d5fd68535dd20c4c1acd8714752a66d55bf365a871a0f11de87bef6b70e06e0f480edc8d835f4562ee31891f879c791539f3204896cf7a500764913a640e39a74b66becdd3901eccb77970d2d8d0d0d0dc7d43f33536244d8d98f34a8be2ab4abcc3f99ffe911cc99ed68c1a42b46cab8c29b91cc739c739de382e019c3f7b621ea3b573a649ce9ded4fbb4c707eaffb3c4f5928b6dd976ad26cc81cf222ef3feff1732c0dc0ff5e02a09680a785b86f85dce99f96c692e7972d1c5626cb0586a6249854d75a16955cfefc30115fd4f993a2b69ad0aa7c9a55b40d0ed9355c7df82a92a5c1eac3950e593c444a021977ad1f8c1bd4e58e0d64dc5de7e9ec2debdb3748c351fcbeea12c8b824cf5de6397acbdb75531aa30375da03efe9db0781fcd8ded34969800f9640c6fd7df71fdda08f93d2a8ef7df7def4967f4c545fe341aaef6ab8cbe61a845ff6c7834106152239bd14402e5d6c5ba06a332c539c644f9230c59468d294182f37292e5136da6ccf396d92284e2f66d25470d3443c6923793e408a0c14e61bc9656b0aa1e5219583214186ccdb10212121a1214184dc820819626b90213ecac965bb73e9600a5187c900ce9eee098b11d410eae004f9870f4c6f4a18e7dc026343cd98261f64c4f063e70e358c7bbed39eb40c310224ea8fa48f15b9be9d35deca795e1921c8f4e73741f10ceafe665fe5eaa2df91a3eb31d32c3cc9db3be77c3badb5f6ae6ec77d3727be42ba7d6fc79153dc2f338932c05bb5ce5ae7acf34e3be79c13055b6bcdd95b638db7eaf8f3738d07e15725725d9b75d639c588961662a081d6724d87f1e8f3bb3927ee640c81a95bd1b39221b79eb4e2c7176cc894882cc3c8c4fe018de145a64bb116688c2679e09772d9836589d326632b4c1a2cd86c537559186c069b59d8ccc26616366b22d3a99bb764907053ed404377bd12b99cb01ed56dfb615b9876a5f6a9f745f7056e194d7269c19e2419e791abd5a095e6a654535c4d9ce26ae11457fba6b8da9411d989da2e51b9be6572a0259b85b1a5551f32dd5cbc55bb484d9fca79315dd56a6e0a964beb54dbdcd4ae5c6d3b3950978a85ab511bb689d2a8514c1b1d501af5837e385057a5e610f7775251a718b7e428efc2843113a5b3aa5845f705fedc4cc06d39240e26666afad8bc55bf036ae37a3169d4af5bdc755740c5ae17cce865d7e7b22b4db25daaab3ebdddacd3cd3addacd3cd3add5ce64cd68969774c9cf8476fad2e52a95e0cc53ff2de282c0a8f9ea8c2c96892cb7a67170bd4add52099b7b65ddf3a554bab41aa9fd9da76a95b0dfabeb6987e698ce524298c731ec77f0ec95bb5e438981279979cffd1e66033651e3919b5b134673427cb7a756ddcb57132991179cee6d75dd65b9d554e565df53137e33e094e46c1e92d3b9bb1e8ab9e65ad18beea45ad7a2222c521cbfb30b47615eaf9b29a45f59c3ef44b9f85abaff9c51aab41add68f63ceadd6ff38ca623333dae803afef3fbae5ce2e964b232f945f6bcba49591d689b4b4a66d6dbd55579daa4cada58f8d49bb3e0ce39cc7f16b9d7948642a65f3960c156c5cadf39514f58605164eb3d96c369b952e639a61ecb719bdcde8cd6b22d74a4295aa37f0e7f392e99e52f5bb881b8cb01a3366cc181ef665b5d1075eb53e91db29de72a95d7acd69d5e518e73c8e4bbee42191ad936df296bf0c156c939d551a387b26b561bf14aa957e65a25f659b665b6bd3a60f54ad2e511a54575d0a3975ea692157cfa272d6d65a39ae723adb8c33ce18678ec6808ceb679cbdf5b80616ca00d32c0d6f418328eae1ada794524a73b05f605c6606549c39cb71d776ff5383ba9f5151c85f98c277b2eb2182a00782df78f366f8148681873bfa8f45b6df3d7d20de83e39ceb541ffe286c485211a50e7e08f93c1c9233dcf579b88b6cfd430e7c70e01fd698607ad8aebbbb5f5b0f9bb5e500ce1e5b6f489caf64f717e4549d4af5e148a9be8eeb4221e28d215ef27df1c3f70fe242fcc12eab9e95f3ea698c6e0cb627f1f126c47f08927f5ea998e03ce87ddd6c776fb5c01dfcea5578ab5ea5cb957ebd77e28dcee66b74996b3eab9e136fa85636dd156f745e87f3385ff3e5940b7a5651ceeb60b104ccec959375f6911cc9eff90d828f7d71c89f19def2bf194c1f7f2297e55b3b20eef27a83780b4847d627aa371e791dd7dae5c774f95b5bf30c360fda58a82120f84bb9fb297aff1b74a321b025d9932948494aa0f55fcadc7758b2f7436ebee36ede717e14ed88f3f6e7fc71fb569348320e79430e7120f0e983460e3491863890ccd33772a0fcf4296cf5d4ea00bfe671805fa3774de99f679ee68866c65b2b585efd78ab355d572586de83159c02998c86d050197d42a750249a4495c0ea59b0bdcf14e73c8e38eff842c89e0d91db904614667443da10551b4cf66c8e9c1a3284088aef518daf9cc0492bb520644a0477bb373724ce0be15485c1781b57c8be3343e2663dd7e49d913aab1625a34dac69a9537aef0d0a83cb65655df5bfbdb07bcaaa7f854f5f2b4bf3d5caeb05b32390ea8bfeca3aad766ddf03b5c5813820de739ef5dccee37c0f9d1f9fc82f4b039ccf791ee3b334119d1f3f47138152a4f3a376223b8fa367d5e58ebd7a276985cda119384f593c5fe218ef896f693528869ea00ec9b279d61fbd7648968d6669b0f3395fb4f3396f63a38b749ea58d705ee78dc6dff9a3978d4c4d6263e3394c55a66b4f4a28bd0c8dcd8ddd25072a2f9102aed24d427fd6d97c5961369a01f4d26a9095c9b0954d1ffa443e3ece4f7107d2f8384f6b8ca624b0d826270762fdd4a035879f0c84223082e390d7e62f17072aadcc81eca67fa11c683e1d9164d3bf3507cae9726f5436fd3b75c5781012387b3ac2894d9f43f2200b6637ca81e653d4d4a67f6d35887bd1a7b1b19c549303952ec6c9814abb64e640e58dd1689c9403b176143d7120aeb669cd61534e0b962807e28ad8f471988ca903eaf6bf4b3568d4383fab0b07e779d02f548680e16818cee3e80fb09e48901fb50f0dc57ece8f5f4e2928464a694eb39ae7894c7ffc9c37c27919231aab2efaf9f3e3905df2ac2e1afd95ca1c9279fa76c981689efe172b6f2c77311b2edea22fc5066fac065d8cc7f1ffc67c767963565f30a60fd78593f2168da64f38313b2b12c86772c76d2ca7ef359ce791f3e3f3c0799636ba800c45886961d444a014e16896e76896eb1d398ff3b24f72c891ac49d5451f87f4c0c8b6c9ca2a8c3e7943f6a79756832617382449a18b2d7ca952993e14ca8322df9a7e21e72faf8d78634647fed5e3c8bffaa36d146e9ab7214bba6d7e454e9fa2dbd4c8bc2569c8b267cb4cd7add9ba4f9f1317d0da20186dd583dd8ab55a55195285d5a4ca549ba6d42ab5484db2b2dea9de82adda5161d5b54556ddfc7d7b4356a4ebb72679ab223d0e79539d36fd90bc01c91268979706e4d1c7974683705d6115e6f75eec15565dd32515c67947362e002720931927f1cf880f6230dea6cc271bc46cfbf84bbaa452894856eae9862a9b520c367dea54836848e0cd061836c5917a9a12934da1af12718c2fd972308740a03bffe775b853ad38ac9736fe6d2d7e2297799aa791c9e48aecd103f45820f87d0ffa3528cda6bfc34707f48178902a03fa440da00f7e5ec5f11b8421db3e91ab2cd8f38efe434bb69a49d2bf66de897c86ac71ab500d2b43de0c6a58fde32d2a02ede77afda9d57fc22f403c5b38f006c1687b886badb5d65a23300218a72a3e052cc24c728f1d38640ce8272b70a9a21e357aece851eb9173ce3d7614d57614f5b876470f216fd11d0ed48383a639a3d4a9d42541869111b8121a62d304304c774ab3830e5ee825a4160cc8c129a54e67b0369b0d2ac80bb974a6ed4c381f26a4b0810a909cb0c194131352174b4b92a49e9cb04198272b389cb04117b35188bbe7930964bbcc2f83821fff01402dcfecf954430e4872def3a9862700ec90ed9e4f3530d16252c30930b89271f67caa610a0cb8c8377b3ed5f005064932b7e753939809983e882376d9da4118f1f3d4e4896df77c0a22cb2effc72211c2fe8d6e416f357e684de6533f326a432693c96432994c269b426cfb348a6ec102de2aeab8dc17725c48e61a2e871c076ad61742d1eebd31bac51cba975cedcff3eea55b68b227f7094b8a9555d9cf8fec3ec634aaa3356a1b41d4dfafb26bf316a63525b9fcd9f6e7caa2b2f7fe6595714f3c8846d9264ed31ad6b449466bd40ba5516b5fac179096a907f8c1efc41cf8efddab2c32f7fed88696cb9ffd8910d0811ffc4f977401f8131d007e1962f2febda4ebf89e7b1c9fd6e57d0ed08d3f141fff10f086d8032f28d6f01f070aeb1377d9fd5383ec4bacb24f844c65a0906f8da38597546dcfd21a9555998ccb94d04daac3b4265bf27e6e8cb36c2cab7d8c7f7e644b41e66d6aea66696dde682d28e7f5bd87dfc3182fc59498c61d5a1bdf5bf6b7a53177d55fc232d90f77d5bfe1f903ab3f4e5e1559a65ee89615d4cae742d16899e63d7eec698ae57b0c7edf7bdf73ef69968efd7d9a45e49f8f92ec3dfe3cefaff7f83d7ddfbb98c5d95a17f97e496b58bc55033ffa6546a35e6acd05067df095a0bbdc4235c87b8abb77a1246a63ca31c65dcedc385eed49d3870a2565406dcca7424d55897d1afad21cca40d51cc7dd0feac05df62decde3fda97e671a636a6aeb6193d6748dc7f1f57bf7a5939be520412fc05e5fe07f7ce9996dabea44f92cc913c4f644ee7b195efbd77ca5bd6ae7e7a6f6b49dd9747ae7e5457fd624e306bbdc7d883e9a0df7d9df2d6b4b86e6135551bfeb2da7c78ec8703d9c718df171f3f381590c59fa28efb62102bd47c78cb86399bb6e9be242bc7fdeeaf76240c2359de6dbc7b64c873a685a9fe7b5f6dd8615ee891d5b38fbfa55c4e29cf61db83d5a095d6512191579fdfbfac369b03ddb78e64ab5230aca914b539aca43fdcc81ca298f3481c7acb72da6132b070da5e68f394a907f7bfefc41cf7f183dfd1ac412b30c4a2f844fe7da28ec9e56e100c6d9e72a981a3fdbd0881fbf8a9a8e33ed6e2026e0e6ecbbca72120fef7a07843f51e693748c57b498f043db2a45946836086035446fc4b8a1f79ffc7c6ef91e5b83d2aaab4e7912009641499e417c9efc03359b7b8cb3ede3e6a107e85d5e642f6245d4596b97924b8b915595f1ea9da5ecbc95671b54d1ffb9f44c67fdf6e9b44436de88420b5648bcd1f35e847a806e159fe1ab3dfb5843cfbfd2f91ab6ddb47807d960eeef1c330fe74b5551bd374d9c738e7d1be85652772e96050cecb3e2659dfe3cb912cee3bf10698b3bdc061298b124eb25011c5cbcea72a4fb6ad71e40f3773577d1aae65dbe8f597dc559f09cb72d3e8447ad9f57b68c81ea334be8d1d40c5ecea91de86c1e61006495ec4811c68d33fda251583e9944c88c3ede202e866e5c07fff6a0a06a4625e3dd645f9655e461be53f7aad7e54d74c4bd39ee20d16d644afd5e7bf1ac80cf3020a609b95c36efc7663cdd241a996dabe02fb2939932b301e2b8703e87b9a95833bdaa0b8017dfdd08dddc8f4194012d89edebada6394467d0b033d00571ce6489e54679ee4451ce6b0fb778b035d2ae5405cbcd6a25d5a752ad77f3a356d2dda6ad1a9d61cb25ce89649a5f6dc6293e026f0290d0acbcd974c706ebeefb857fdd7618efbef31c73ddd9c7deebf27a737ad0762fc16bff79da8c33ed656b3ec7bbf7aef891c7b7777f0c3813e6ff5f777d4a05c5d36e5b4edfb7bda68511a57e61be040f9ef9713887dff670ef9ecfb42431910cda1f0a7456dcca8d1337cd34c99e11bffcccbc8e819a51fa6192b34cd4aa1cdc29739343708923e4a72f8f8c507c3f0c110fc50b374ec30fc4007a859e0afb417053e7e9508be07fe07824f37087a9e66853f37793189c36421fde3adabbbc8dc7f24ad79ab7b16dd5ed73dc61df54269d06f927151497775e8fa56037463fae007a0d8179f7b20d6f34992bd0faa4f926c27deb9e3c8f34466d9b7f9a317cedb7c11cedb682328f68d6c6eb4d1cd8fac1cb583a37df7557220d5dff1ef5359cddf2f2993cd25aa2e990761dae821c481c4eeef1b7d39b9d818ecfb3fe690b53113640e797f7f86f418a5e1e37ed09c5b5cc5c53dd277d7819c7843fc2b36e0886e8fa43ba434fa3e6a1c94f4874d5f6a5fbf403cb12f9d4d1fea4630893fe78f5e2c5c84f339361ae7b12e1a6ff4f8472f1cfd63247fd8903e4a32cf13f95fadeabadd83fa4afefbde5ba129b92626eae0bec43177900f381fdeb24fa5541e328194feec1e634d044a91c703130175d6ef1d49ceeab2d406f63ecffbc00982a27e0f5561a87aac33febe7b173ff171f7de73f841a29f5951f75e0b3f58ce19f73d66e9a2efb1ce2208740c8bfbf74816a73350e4fde769efe70b7b9df6e93345d007d0079606dd7bcff2c7f8e3f19e03651d8a1070cdcae16fdf6e513adaac1d451cf4b01ab841a78f156ff8f4b15fc5397dacb621fd942c9313cda93ab5e122581da6ab5aa71ea65c72b53974041735c5944b677272a6ebe4f489495cc935683aae39bcb7de516881426f81d3a77ed9ed59bfbc78bbb73440434f674b52f04aee3607e806627549b707f641a863c64c4ac3f334b65ef747bbd3737bdace21ea85d38ec95032379dd2b0356ec67536fc219716466f30ff0a951f67cd894bf7062edddb126c093687a610484df5a32a54857258ccdf22b92d525d04a424d8f4a9e1835f86f75683426d911cd4585bd86d5b98087259a796a6e6d017d446ddc22d714b4a21207912ae23389dd93974c31e11e492dee88dda006361b0593dfc341310cc5d7299bc75932c29792b367d02fe2ab29b2ddffe73d2f007a56a10385dfe17cc8266fbe3f8dd89053092bbf7bfa26692f42f03fcfd02a0904b260678efbda73a039656010510720e4a5597006c752a80ab0a352b87dde1db1dea92c89ef2d6fd21d2c5b8ebfee7449dbc75df0024ade2aefbb8bbe0ad063d2875bf8252fbeeaa2b92b7eed7f70fc37a54c369094b407f70b5e78d1a5bcc9e9e16a5e0ea468d2db2f59608d62099caa4b6cba0613a08e298f3fd0390867bcea8135c89392ed8ab8a63ce39e7cc60cf05503de7a474ce39ab1017b470410b75bb2e8d4400674f896f168c07e125eef2b762ac1824a4224536bd4a5769d3db2eeb33b164cf2b7b3ed9a43678410bb509492e31d4f6c7500e549b1c33d5251f6e870ab515e32d5f926d937bc923b67a1e554a4df8be7e5fbfafa0934cbf76b5ab5df7714fff821af205dfbbaeebba0f042b58a93bfeeebdeefbeec16f00bb7bf0ebc00ffcbefff48c06e85abf0026f4743c20d9b2c17724501b7c47e26583efcf3de824d39f18e76c671096c9d9b30024e4fb17d490edf7e0b76a1087f3c61bfc48b2bcdec23fb14c8fb7bee79eee398740a0377fd101fee0ddf4afce7101cde10f3e48410a6a0ed00dea06685b0013aaeee1ee131c0c91448230823852041058182145f45b1533850eb31d5e68f2058a2ec9085937ed0e6f29ed700205296870d2430f598410a22b2106ef488f274640a2c5114d767842c2b64f63bac0965841142f4628cd89050c2b4788e08624685c3a101851041fb1e285d203591246872637dca0e48a0ea966457ea56cff61c8fe5697970b058630010f5d58a01dd1a41ba126e5dd0bc05050124b0285a8147422d46c58cbec06a428aec49a88a10ba196053c62830d2928a288305844d0a183d576a0a1476a0f15a69890984a32c6c68da94de198e4a815ac0842052b5d48490aa31685b3b956259a8070fbe2851794623a7814b518564990a00b1451b4c46ee0c0f0e891da0bb7c9044249102980e1e94b1556c4d490d85a922a27a93e4e8044851121d030821b56501be132a9553bc50aaec4906a21c4f0851630d65afb46f28eb1ba8ce45aa9d0ca83521213145844b0a289175abe702e7b1b8a5411831329a418a946b4508195b4446103432e47ccc930048e0d159640291155c44a186e4acbecbb4942a0a549971f6eb089208c161cbe7b24532d33d0e4249e444b0ba1529416116c8ae06265e566518497ceb3057ab86551c11547c2e8418a1364594060c20aa618020bd74511537858977e6b0a9e84cd051b0951bc38c20ba78222b6747ea4c90b51b531379cb083162338304520e1719574627b62427241072e382e94ace005081f76f832858a6fe96e96215172052d0460a2102326054530e52bf32506206e43d41053b205e74b59e856d17a1223c4174d285061845b1125a86ef55202272a2588218c089c1663b02b390b3cf4c0c50909214449ca62e64802bef80085890995159c705fa400b9903282929426b65ca14316599210a960295964b952801e9414e1f4830a9880e15464a1225ac942823c44eb10173c48d990c20f27c8e2258b920c9309446df1c4c6b43404150e6a0c9e4018148288d5848872e3ae80020372d34a1434ae64950081ec3df244834c0aa72b2a4ca9370c111ea1800e26e410a50a132454b1026aca4a890424a258c941845b9410705da0986aee110a85e403b27e641a51220cd314314f5e64a9022ac67147fede7baf9523271494e0e10729da123a380aa0eebd7763d764cdf4f1b7b73c87ae8bf92c3f846003942861603b7054101106c621635cab942423584871e10a264b8480438117d78fd401200166892c4e8cc0040e5c88d862ccd3c7c6841a5875a18b2b218922060726aaf8a2045db829a0f08e14e96207134819610a14332998e8c00c332c524ed084165d4411757d3a81029715580821ea85239c1411b4d06a21e20a771d8718931980b08202a530382888a8c2390d242c9488e24452d416dc13449400ac4cb630c97828e10712e08965b6f260d10483ad8a2a49ccc09d40866dddda975f212289c68a063688a0092648c022b6026e0b11307ca9fb8c0bf188148d5b6a654631d101d97be413620431b0c005942c60a858640939772b26e894acb5d6e71347381183a2e9052a489c280178a402575491c2298523312e4d2c11876841c458487001092e464040e3981822d6b9d2bdf37ebe3fdeff5b45b02f09dfbdf7823268c073885e24c0ccb09e5c266b7d66a1457d7757cade840acfe7e47499afb676de5c75b02a7cc102172938114105596c4fe0287984791de167937a6489ceda24e53273bf4302b660e2842b5d84601ab344ad6b22e2e7a8290c122eac70c10a09342580105725c83e5f2da8d5cc5aa11a84adb5b26de8c49624820f25f060c5cb72496cfbd4c3b65fc381eeb6ba0432330bb9c4e37629e0cc1864e1436b86002c11802f0090426b842727d70bd99312002926188491710c00a892710b4764156a7882b9a2a4208a36050094c8aa3d9f68494cd17ab8e04bb6d9f38956c3055eb2b7e7138d89b62484ecaab0f29f3dd9b7df696387d2a0efd5bebfbfcf397d7be9e307d874cef93bd4460694067d9ae9fc0ce8d379c3891c4fdd8e727eabb575fe4cbc13a3d571f7bd960e28dee8eecd1cd97117efe018db6d0f95ecf70904573dac7a08c1cfc3d539bfe00ff7feb8add53bceddbde3bcd65abdd66a2bb5ee6ea79d6228aa9c521a1c9deeee95d269c15a6badd6ef9c40f54bbc7184506a963cdddd67786b3e56d27577da8eebf0c59ef5be0a86d37edf773f50bc4f2c8ded8fc505d8aa050c7113f3fbf9de5d3a5b5dc6a1f50f745eede52e77b9ce76b8ce983fc36e5a71f8f8b10801bb3d2ff41e04c3190ee4aeba4419e41aa48090da30402b4a559d70b57abb7aa562ae4106982e7f4fa62b69585d6b9986331ca8c39d9d1ef550208e16dfde67163fa420b3fdc71f9670cec7ec72e5cb9e60268df98c12c1fd73eab4e79411255d3869f20313a957d41662d3a84d8308c116df3a90d0161f146f882a104cdae18be2e73065faa26a47fc4fbcb152893a0376871ac89cdaa01e91f87e9635fbbb32667fdf13104aec0f0b94fd3d166f7ce3f6be136f7806c0f80a958da5367e4ebc8127d00092c00cf083086a96d96c5b5cf36dafa8b7432b0a12c25851e40606edd2d0848f4000c60e2e3c4d75310b02091fb6503a6bcab3f594a504b1fbc41bdd986d1f639ff2230863892b6ea0e104501c314495afc3d16996945cfeb7ae053b3ac4b6fd6c9f7c90b22dce6073dce7a80d04051412dca0786284941767c4e6fec781b8afc1bd02e6e68e0ccddd75dba78722db5a2156d7ca0c3be9e8e704166d267c2a98855114f1ba9802b338018371fac29410ab12c6065cdc02a103a8942df6553d0b11d90800000023150000201008054462a160349846caae7614000c7f9e487c54968ac324c861148490310410420801000000034668688a036d8f710c200871e6e8a3c2fd99197feb07902cce524cafefd92f2272bcd65401e29fd44a851cbb690287d35105a34ced90c269de87d3e0be909d91bb5fa76f679e3117fbba73089e70420eb9c6e748c104ff861eb8ca2b4f51f3746c329ef600837f76a8b554fa6763110b7f4471eb75b4a8843c73b2372d6fdd865942867896a2d7345abc89abcce20d52a29b6128bcd81db8c86442338ec234cbcb83b6365398fedf854fbe56c2e36f1919cbee65ed49651a84b2d2021950d80245c84933fb059f494e33b854c2b17733857119ffdc11fbc0a82805171c16ef79e67f9e508bcab21dab9bd39fdd34e89117ceffcda36a55d60a51af47ead2570ff91d6970548457d049f538d49fe984f55a7448217630bbba23ee863dafa605f916929aa8c9556831477fd2d67fdf87a78a645e24d71f83fecb1ac1c4fba479b8a441b2ac63d25686ba86877030a0368225201cc865e5de05230a1a5068326f85ae1db86da83a1b84dd5ac66478224ce7c46b31354232fc493dd4a20283fbc2611d6b827ceac5992aaec1f014a6f3c4fac1a279c44aa76864b811808fe53ba7669060cb5a591fdaa5d1593f25a4afaa50e077acc90d1386c54e71e81d4c865a2e3e2766196e6a177c2e6d2aaf5f70402d7349561510db41f2151cf10e2a10b00f33e25c212184dd76d121bf4b8884e12590f16df0aefe8a6304f006d9693b9f6a73f5e80ae38a013717e144eefb77d3705dc29d984dc27a6cec0ee48796056bfceaedec36043ca5fb045d17d472061b98c4feb21138944c98a089c2cbababfa11c4827a16999e6a3b28b1b1342e0f87680392c503abef768825b451e818765757622b81ab5e217f49e4da8db92182f14121fd66bca5ac8726f3ef89b8b271097bb930e24d9eef729921c195378342661f36e92d849eecd130e7c7bc327653beaeae6f6845db752730f65a72a78fc49768ce0112f6225a100578128f489e79d1885b9f7bb00c1b0dd565cc633936e97440197f426c243ffb76c482e9826d733c0e3646f34fc6c67222cd93bfca368aac23def846c5728ec3b129774bec3e2e4d0b649c49368dda9644eb1b9b48bab135c1de477c18ee7221620335ab8a53350ca6867735764d98a5c238056f043fb133de1817074fa4834fa1297161212ad602aa122bd622b67531cce05f4db869de9249d103eff160a216b67be296351a73c72c2a1db5fd7291fd89b5a4b3db780b28a22dd354c8dd48c5db792cd964413b400e6d521bedb08fa8aaa006b988ed2eeb0ce3d13c48f88270cdf57794d4a4a5b0d35288332432c4e6de9dd37e9323f52637ea01d43b4b4eb213b224211288d915d5192c82341d15eb23c94591665a3b6007d41f901e3af918fd4be2e548e833b5c30ab5d456b8b90d58a1b11e01e170cbf870024d1e774975734acc1670c4f50496653161b7488c5c799244005f420b4e0585e7466a0e51aa980f59e468eb3f42eb36006b50aa93726482f5569b95312cd5489087d340e3b00d339839f8f88fdad053e7ea13d8c9031b388dc5256f34874541a37b04672d2944331b4eb190e0f665ffe24aba897b774ab1170dd37eb49c12b83ebee61887d905bca2fee42a7b5dd869d9725bc5f8cb96d3af5258c4e73e9759806f80bfeb254a4e61cac8551876fba88335ab9cac5c2ff0bf3d0910cb132763f313fe432b2d06c76b958cc9398e9a4694c911cb32c6168567e2874c415115d534da8e3d836bf9cfd92f7521fbe09297a3dea4465612352a76cbabc51d4e78925eda8a98a86291416b539ad401209a7864744a5a3013003c65e2ff738b6528d7b8c404ff0637ab0bb45f3b8a9e4cc9f0593981256370007c416025a8ca3f3a329754d015ea4ddc946922488b0ad28efa94a8f453a8f6657241b86640952350a862d412d01c35369833306f0889643f44a46a468659483a5d84ef7f2aa297eb72a8aa46c5f7b63215e395ed2948e3d05cd5e3f2a5ef6bc28208d2186b29fe9fd4dc77494f40476dfa33314401025e02da5111fe31baf7155acc08219680ddb1a54409f1b2510cc6ee9d202e3322841bf706824106fd43652eb3dcb47c204d3ec8b905d7b1b2f2031b13439eb7f887acf40d21a70fb149fa59c93cdf295a897643186806b32be00f7cf31ce2bc369c9d4f35356bb187f51c289e4b6474b5e2062c6114f8d95e69919c89b352f09514d282bc828404c2ca8e753cc7b705dc7b2471c693b62e9420a6b981402c1aba62eaf8b115d1f53d468bfafb6d517d1d9d6a2501e571d509a3eff881e11de5b7463775a0002d7093b55b24ca71acdc3be4b8f474a6fa64bd24b98a5aaf99027aec3e0ef6c4b7833c81ab30b7edea79ecc071c2ea37038870a228971b9311b9ea2ee7910f26f5bcf29655e4b85e89031b5f81381fb279dcaf80242a0bee71db5506125d5285062f242725ef1e2c30c78abdd8e7ee8b2d374a91e0243d59c7acd54f46d2be44c0b7b27cdf1ac684158ab40c58e6df6a2a3ead8469e3163be4178ecfbb53a6a43b7a4c895246d9109f0e0e58dbb7e596217ab5804742e86c292728964f7de04dacde186db7f09d2522751f7e021596fb0d4f8da8e5df75449f170178618fb34b60a24c43586d6217183e275d9325f509aa248e94c9cdfd6c1c2bd2cd3ed692ff0da7f923146fdb2b39ed7a835aa9d174a672adec0d8936cd7222935e0cf19db4465f0c99efc30418fe5b15f8eaee5f9021154af5e8e330ee0c2983fb1c0d811c7a2bf6f744ba0d54b9108a13630dac02bab1af867a87a5d53402da985c12b9dc7c25b8eb96024a864b3988bd2f87b917d19737f8f2a2ef98a492d7085fcb34a90e9e09657061d901522b85e4c391ed0c8f083c7774841bf96ef6b9fbd4aa248e42c3b4cc206d5d55040124989029dfa364c8432141044e462f9f74329e06031bc263f792c4d88203bb0841ddbe2c6815fe09d01c2ddc6de133771c4a536bb97abc1efe29c7b970dbeb30e7e6d6a9d2a88b8419afa7c9d33be8092e32fbe897cb11a2308360a465724d24b35cb3e7cc167193fd0383b9144214092eb5964e8ab220d5c4385d6a15620befc840c3f1b6035aba29d32d11e33a14a7dff61bb931429c3931f29a994b444999a4e25a0114ae58f5e406f947acf1e494796846c1c816dda64d6729874de08856120e43a2db6120af832ead6bc970323e358fa5358b5cd50e8f194f9e7af149fa7be620ed466a74607c66621292f0adfe88aa038abad0086538bc9038ac66c41fd1fa31be8901988b219a5bbe18615a36fd6940097221161d7a7175c87f99b85e48026aa096c8454404da8972d8bacc0ca388c5d64e5ebfc9d16b448c68be0e1d2ba9ba2e3080a23f41623edfe3af551659af70b9524380efdce306a16f46e3c409195f195e23ed018fada946f30f6e871461c0b732d16f356898f072022ead6b864ec4b721944d809c6ad3728e469e0f375b4ebe0d1ac2e1f8b82f02de4f023fb37ca2466ebb0a0c5c7da2603bb893e566dfd6dfdc1d79dc6d2f4e07e197703dc5501e476e68ce57bf2a323faf2f08a6f86933d638ade6fd8b8b7e6e78b81f78169ed0ce8a3578a6676e518006674c169481a8b30be9c541519ae1972961e2bd8b729810dcafab18b580cccde253f6bf5386fc86c44e95071b47f632f19fda19f2e805858b8973bb426539dabc414195394169b693549c9c2074ac903f0245e0da0ccbe553bf07821208bd1f823940bb08e175d42a68ab2e4faa8588291332694c31cd210ee6e3a96ddd2c4d5ab7384009e6ad5a6c93ac577593037626fa88e7cf92672d52d324c5d6c96088c37a6f5fb5bf00b9543cbcced90e4f84904da2de0d46f60ed4415fcd54b8fdcd0435a8d16d5d4010808fafaf9cccbb657014bdfd651e5adc7c5cd75d514c1ef36529c6844ae9b31ccf9a7c4b6efb3670e11f2b53307f0923963de024dd8fb8180deead008069c27b10d299a84d9ed1be6d545e560681688a0bfa8a030a1995f838ad76724519024bb1c4a5f9af344f037cc6f48859c9c2f44d5925e65f0d48aadede6812dd5f3b77e6f90d6a38c5fd0cf474da55c7b768a6b0673454eb32731f17f4f8140ca2846a640c6d2855876d4fcf9b4df27197b167e251837b7e175aeb37d945980bcbcfbb3ab07b350ee533fa234d0c4bb22ba140fd9458b1fb63029c5ea1f7a37416250e553d6b7eac8f53d4c79154134c91088c5c19ea7276df25e519326bcbcff9c10e93a2a7ae5d11b3d7a2bfed0ab03cbd130a10391f87b1e8562519ef4f5a46be5e5f2ec1af93ecd8ec786104230bf4db371927ab3b0323c7cc853adbdd7bdc025f08887230ad5144f855e8afa121cf0a919b6ed61a1ca4d66ee6ad03a9374ae0b46a0d7932b700191a815394efcebea5e5ab7b783845ed7a72fd88c9d95d35b9fecb0080d36a5f92c8102a6182c0380aa1d61f3d956818174caf9f764c8d22b1e5039bf27844b9d4ae4d8a808e08a984a384dd3c99ab9a21b4bb9ca29dbd2fb3aefaf0ed3e4117221cb8d9a42c72da1640e6a6667c0195d92b54d14b802c961e4f31e7b3138245b85f9872d36624cc29f254d617616ffb5dc348850184f162305622343c7b1061ca69db8baaba312471aa376df5d78327dc650704987df93577c0fe832e32dd2a6cd5b60208433173a7d41bfc98947a727c0c726d2d70278b9899ca3be51271d4a9eea132d2b7be91693bf8d17347ca2a34ce481958b9c06589e7329b3192160634a420ae91a14d62b01c01622994da47ac829b4159762d5a45c456d9f5984fe08070a2136323d20831b3f76c492176975158148989f1064b25d2e6c660a7f8d6fc1c8d2cf8986483a2963671cf3b628752e265acbd42669eecbb6217dc5acc344920aeae4ebcaf63252835efca55c6054d883699aab499087d42c14f46c96f0f94825e0519e47aa38d7816db244346fd4cff28e9ddf5fcdd81cb525e7457deb5f4de4af15bf410d113111ac6b87b493ea43948c2422d4417143680a5f56073cec1b177d12aef3381a84079785f35c8b02da768ef2673233a18baf719a00f6b6049e897a377604f01b510a3d668df8e7ee6952464396a451223ca0429eaf7efa3d25e267ca04e83dcf350563cac94046e59a8e3679fab9f16b02813ae0d4e98d5f65743389611621f6051afdec4f697f6fae3367c7fdce313fa19100c6d596c33937d06ad2a875b2a60d3bcc90433ee06e44162ac5ac41c02f6f96e2ca1e12958893104793125b10c0d891577ff0c18c6c4a21573dc159cb788c67d8862f73604cb5d50e75421a14a4147d62f6e2f0f92bf7051aa4721a58e208e31c49037979472d1557514b7483534a21550498bcc95d88d3f813d5127d82d786263e77939904e550d76f72e8b74aab3607942d9eed3e7317b1e98e5ab5cc178e1f1d01757f49bc3c20cb1ebc546d66004f303a981333ab505889b7320a029cc63fc3a337750a876c65bac26e82976778493a943deec4bc73c1ebec2c284e57a6ac0cddfa6c3c5ea55ac1c7dfcce9b7a5780e535be8331b323dd7286d8ee090ba4c6c9cde7d2996a38a0698cfe9813f3cab6610d4f974c964e41d85233a6c8b8c05b673fe67eb04fc31f19fb36f503d51f3679933c137fa0d0290590c18b32620155b1023c388808b9de48df91d1dd87780b6c70426da691d7834550a2016158e3256354f58a082b0afa78671a0423808744059d32990555fa91b6b6cb80be5d9a7b599c764450ac90a4608ab145f80308809adf3dbec8c2d6146286d9c7dcbaf1b07da8e11384f603eba4859326d156ff6ece92da8c6e406bd3456bfb315eeb386146708298679951248c8caa31dc0370559407c32e899673b52922a7dce31d52d7d35f0291768461d326722c9074c9b64618b4f26f1c57f17bc0a5607e0294850ce26dad78e7820a866f2973e5852f79bf3cc5d1449a39beba67408b5a42c50c91d054e8ac9df40b01e2d20e212a97d4259f0a88808cd0defa879ef11c3e4ec28e9acdf3667fdb86658a08cd11da9e81610f86ec02125e81c733a6b3491dbc0eae111b6050e594da4dc28310bc0875902ec4e1b692ad73e984bbe83a601910115b6cb3a4ac1dcd080d3951b941d55914e9293b33aa02730b2c232694da072e341105a699575cf523ab14044927cc8c714c0e0c26da6352e627c76670cb35b876cdb04c24ab7584d07cf6041830cd0578f380df3d9e0e0586d2fa8a1c029703d6429317e6cf0dd08ebba8cf243c9646fb3b6969c97a233816686b72088732ab2044209b1550a309dce7722289f3bf8aef8a248de09c7fbacc20e7fb775ec535b86bc58565426e5df5ecefd09d29564aa41a5f707f28be0d1531fa17c41e87dbe76a74b2ce9627eb190a5a8a62f6bc2c3aedb778378f18b5593477a45942b6da568eb2615c47f417cd0a954b3bcd884f680e96754dd20e0b0577dbdf039682875c0c6ebe801c5821a776197d26f9f5337b4a9c217155afe6708ac80d55f9c155915b68ab8730983025824f3d712fb8d787780d6b4f7219c21b77e2e5e32579e63026066d29e68d3baf8e919e54e1800edbcd8e104662f69437f217d768c58e7d09e35a09c23748251392646e1b56183cedf2b3a44ed73d74c160e6f473f2f002757b0d4a79527641cf89fac7b4202e9c9b4ef1f1e0cfc59b3ce9d87cb3fddb6c8be1ee52c5b2166d063fa64b8913abe39e4e27288cece83d183dd9fc8a1c6150dc0045f2eef76a206b60c154580e39f4c5ae5bed93c282a60795905a2aab3c9fad55e4960a30db96ab82d4d91c3f93a36168d8b5c703c2abfc37c69a455de463d2c31596cdbd768bab16d060810665c9df288da236319d763910b5cbc549f4a88e04ba39041d55be33d1490bec296e9bd74f3d27f90f8c8a7e595693367a8ab7cd19bafa03a9e0b1b1072df9014ff2d91874516160e8035439da747e4e3a1de180509e3660d077dba87dfc185a2a0d8d4b01d84ffc279123ee7fd619cd553baeb6348341f391c6431515367cbfba8a4f9abfe1d345a283880dd26cc29bfb4e76e2fa68c3eca4518f1d4594a1e6d2edd7c8245ca90735dfac80dbacf99f58d063a23f884913f47516a157106a122cc9de5d63460ecf0f6565380e9610da6117378590ac4ae726d276a69beaf2fde81b8b0c2326492769a6fa57af0a62ab5105bdbe3a765b8dfdde93f5f89c762a933463b412497cb0c4659c673050e12bbea44ddc5e50432b690c37801dba76c973f096484723726ea2c1d3e1730f2ce7a06631a4b0f7083a5261888fc691d3843f29f631781f6d4e475490e8111fa08a3c28963a52ced91484441c16a5a5c1e1abd0a7254b621fc7c7c847e975947de3318d52667add960d7c1a659e347eddcf6d36a3c27edc22a853d734311198959d471b20d6ac00148c48828c90ea6cd7142b83a520e522fb7f72c89722581cc1de63af0b058ff6dcb86ee09f0237fffd486cdbd1e4ee818f93c1f8c99b44632beb11f998a9d16e79930cba43d691729bee0379dbaa8058d4dbcf45eb7500e267dd3e88bc696bbfb1e2feb6c60a022a1d7826ed24ea77de0038578e82809238578e88b5a93720dca22235a9134919e0ea949a0f3db03283b7b0bd468f07b143f56f1e0073ea7fdba5d85088ba210db497ab80fd7c68dbe409c4c1853467d0acbb5cc21a442d49cfd634d1118a251884becd7c27f63b002b979b1939cd9ca0937248ca431020190e2fe7b3d10090ec1a88b3117c7a1b0ea28bb3a391fd641c980ca5d0fe5c4c90ad02a7915a9758d28d42538e3fccbe117adc740e3acad8caeba6a4a6d3414a39850c749b4d2703bc6b244b5d830c4ac647e4b6ad74d7a785acc28ae0d5d85e1e90d589e64755ba6b9c6ede53ab4a89b84b358cb82a794bc2f8faed871e0a7685e059ecf1618de400afa4526b43ed5de41d767c6b827cca2792d3112f5b5481cf86527919ff69b064935feede3e023882b2361c2548e8a9c66ba34e0975bbdf2a5285366762239fc725335b4cbc2412d1018e336c0a484834e7598d1eb147cd7c46257178b34012aa80f1a9c306c6d63d4ab613357f47090fd42844e596a824340b3680489457bf366085cae375733d30b61e4c64f4ec6d833d1050e120badd0259df9f1154de9865955b733738c8996aaa1cbe091966e68cbf13be8d9ca71ce17606a9738bffebd651c38ba6b23410425d1bb2b8eb91db957a96409c33729636345d9281c1b320651f8427e4a8a97282cdc9d57a2d5ad34e1e579622e9e48504aced3c1bb9c804e5d513cceebf69c67b6e6efb63c9ab0bde412b46a6e884a53f98cc2d817215302c7f5e804bbb9d7434f551f287c419635faec5497de2bb7fd319265ea31cf8bcac5f4b9fc52d5c4c60dbac2cc244045cad802b64d0310881ae4b811c7d70e70a167a31275e12185fb901f18dd254b79863a352ed85dc4a1dada9c7143b189710bf845c32f5685f872cc34921775abfb74f17a32f85fa7ad99a78e0d9f502dc5b479043d531d84060c454ee33697f3fb87785225091e6460b48997a89bde974e202e57caf7a6e4d84b555de206508655deaecb02956bc52a50b9dbd102b73a2818ce8d5b24fe28e77c10969539505d5c5a9571139882a2d2b9697496914335120c26fc917c3ccbdb1d4fa08a19f9755be20e44409fd7fa6a699198aae6314c2be68c8d17bfcd156043347c335804541a288e0ed573177f9fe336755b2394de9bd9a6046ad8fffc825de8b6507774001fa222dc46ca404ee0f9ee05b032bd900183d587158c4aa81c80c5be47099911e36dd6e1ff21e6cb36c258895fd616744426461f9c441e03bc8920a1df2034eff5de2a8f6b554c61a437f4cdb552a04d6f62b2672f23dfec82c71e57c5c2ac5d60812d353b92df92b41877bc289423a6485b3cfdad755210248ab7324ecffae6f0a30feb9b26d0a4f1749dbe10464de05c20fe8e58861585010b50c6ef69d84438265a80005aa960ea610d425c433f4fe86dafa281860e27b5921346eef35596eed0a3372324e98a3620e684096b49b32cfddddd03423b14ec50847c12480153070b4923fedebe2e9e74e29af29fab189b643ddd67b3af9915286c13e69bd5c8da852425db90ef02af3eff628d3513b8b90203de9c28b7e4a2f191b4bfafc65efa0db26fe78dc60ed5a95403f28f231fb05006b75ceac5f1cdde6d47c73058480bb8dd6ea5d0527854994cb35d99842b634249b01e9360aad971fb54123f267a2cb78c90bc9394f516543d0fe79d5bcb447dee6d13ceee72470dff088ec66e67981b40b50bd90f499452480d9be1220c53d80eae6d5b1c362f4bb8e3efcfecedb5fd621671e7c32dadc987abc3a51eeeff0b86c8097eedc06210d4177a959c6aabaf0ade1332c7abc33e267d1f9cdf0af150d87347b4804e15fee3bde26bb4760f58f5efd6733b47b7e21b781886eda52f2d20914c871bc9aed6842218a47ecaad0932cdc6f4a71a44166db01f873b5db97ec511448ae13d7a18bea9c14ba4a004400d9b9f4bcd59110ed1b8ce6c0ecd195dab4ec9fa98da84adc0c37dcd0ed9cf2f82625d90449a78d34d09bc7346f579e981ba7d21c29aa748f7815a5aa8c7ff6a16fd90ea4169237690982119dffdc63bc501fa4095650e8f6590e6c34fdded79eabf797beaa983ad183515369235cae4312ca01e3920db2a510c17c298fee689afb94f7f54fd79f05a8a46f8ff3364549f1a21af4224c9bad5faee050c4fbcccb16b4c832243f7a493e8a71c5c26e910bfe08dd322572a85ea26b5efa2d630fcabc8b54bbe817a72fc6981e0ba285f55524ba2113cb19a009b68905cfbcd6757fb75f569f14f297cb6ead4c7402c301262282a644081a97b35e0305febc42eb70e132c9c7e2c6e9fe1db2865f796e8c4fab8062c16a3e8ac69a2749359f68c465a1a42dd3de2de2af20e473c0d85f6df729b69cda455f6784f4eeda12e1f8008b436405e5877b2d2b2cc2f71e1822049cd117660f86032783d892b040bc52111dee68b8fd05950adb710b8dacf4b0f3a732622a22d18eb841f0df15a70365c4242142dd0670cf257db043cd878cfb6898d3a49bc27fe859db052d47840f8e4f406bd7ecc599a93533928910dbcd45f871475cf839fc643b470fc8b1c89805e226b100ac2fa986710e1720266d7148d2a55bdc0e70f8a2f10c19320f05a9ece04d13631599749bd954b9813ab11960385a9e55e04090c57b4a4a0e4318aed26a947aeee94e360a72ed4eecee06e7b04b24722d5c4808e647bc6e8e1dbeb3d5c5b7a4d842c4b7c2e0ec7ebe99137fb0c238238fd34aee8b21c45a280055da9204c670a5df10901c8fb228b38ec71427dabc1e54c8b2601ca0d9e4fb6198b08385011c97e4f74d6f9811b17237cf0d2db135a188c99ad81736fbcfffccfefe6771f2a60e98ee426292b92543abb636b1a2a8244106f2ad7721fcd19ca66171c6ed70322bf162a705ce8eb7a95a2d0494881ce5907cc328df0a155cfc453c0057f405c10240ed393e898e8e507e2e443f663fb4508a9679e70984d6dc598c4f1d603b1e5e8605d70a05849059e6dd6caeedcd5dbb051008a81fac4513f74891331e5bb94150bd0dc55a87e6d5f33f7740e051604109564b8b49c4b9c518b726aa45f460c9aa33efc2335ac8573edeb3ddceab85a4a604684ea15248d4ac273359b83f45032c7ebfc7d0d568557d261ac2ff01a42f0f3467583837a6011a62634323b59b107957daf7f68fe3fe947fa2ce34e591dd3491890c1ee75aebb9ba3d90c1674814bf8a5af169e4bf4e00f1e732a78c9b0cbe05bd01b8a704d76777bee7c267219ecc7b5affe90b02bc7e09dac7f4d1975c9a8e7f6e66351112cd80bf16e44ba13011d2a0f5d011badb03789366574cc8f0e60d29ad93cc40f58360eaaf619adb6df42c4d4e0e6639b429647c9f0c4672a5ddcf7c7204dbb1b0d568e08ca0dee4b5acf3ad746a0a13f6f1600d64216c34e69a920616891de81e515d884b80f49f9f44aca97859e79b42d3535a1f2007e83cb70d247be91eb3aab89ca9b357b0ee84f90c9fe3717480185bfb7da6c27256c1fef6607b6346257df31eb705155d27bd341647421e26667dc98482ecaa88ec4c50c84451a0e4952df50c7c540a09bb490ed13b0fd6686bc1e92833c1806c67007f1fba87f10c49a20604eb996cf479a8543bb003111baf87b8c4316620f360d492dc26f11c4101cc274653dc155cb045f9f9bb90f17b9bdc54aa84ede78f9837e4816ba654c213634e5c55b8e5a0538baa4a51584f98b4b14186a70563ae4965a812a6d290fe2d6b02b933d012e6e06d53a259777a86a5c8d40c496c8b6851db7a7be7505d74193d4e86cfde7b5b4b147634eacbd96f0ecf8373e702119357b6dbe10e43a51887a52d75007cf1ac203c162f802f77465d6ff9257339231577b7e4388390b6a2bcd42aa2a7b27d1462df3dffd00f92cb372ee8592cde9fc4db6ab044308a4709dd38d85bf319b090fb53011ddea6dd4d703322f8014f7dfd7c9e42de6a98490dc36919be84b09625ff99593a81607a21ff99d80ac5de1086828d5e10a45d500f5de27d91c041e03dd348c7adeb04aa11efa968eebae1012c79cea5ea6de996c4f8b2038dd579f4afc71873c4fd9dc4302854a26e5557b5e2cbc0047f9249f269fdfae83388af2e5909f79b1b2df13b2f104f998009dd206140519f8267f284c80fb535634f289f81a81d49e7c2713afdbbc5ecee769c2e26919a5142cee8669879c467d6fee0089960d84af82489f0878742b61a9ecf9de3201609bf453f482a6171d10d7516f0e4c93aa75d629435b71a352f47e9f08e2d6c29838e9e23ffcae87cd3b70886581210558242de111134bb7584a2ab3f9d168f18af167059eb2a2af2a461f300c7518b33c56159d0d978a51a1a096389fda3df65dfaf59488c862d2be5762e1a34bbd652ef43a7355b50fa7e47f5b306c6c6816d98fe1b0f0c6f2e12f981850268419ed92ae5ef29308c7377ebb7d1c9ccc2cac28edd3cebed585c3fdffaad14f085b43e78ec5b1274e910dd72e11720a054e4c117d8c4954d120703aab5f42ec2c8fa5ae455e170f61d2e59e288d21721822ba9a6d0684f015e36a60cdf80ec50d28b6dde4d572dcc6263cdf015e40d50374952f8f8adcb41e8760b9de7213825123db2978483f9d22c1106894c9e850c4759a8dd4d592cf8e3d2b964b1ae1a2caf9571701cc2eac65e1130bea9d9dabec0c4498f4300c721491b3aaf95f3d54cd2a2342750c8beb5c35c289d96e61ecdf84d482237a4c233eb4c9bdc5005b92afd41fe9d2bbf6fafbf3b38cce7250f592fbc52c90adfedd5fc4a2ad5d734c3858a0a06d553a0de4f8586b8655321dd980652a9bfb8f1586fa61d3332d3948e1b5738ec7a2a73542aeb36efd8ce806025c2a29fc21db88138ab40109526f1514ff1ab0d35d9f323265f4bb09d59769acaa6288da21b3f188e0c62f4c7307ab466a6daa1518cf375a9b037de6743700142c23d9f1f11a01a78ed735104ce10a45f78ded08cee6d4e0cfe7d5d8af32e258b43c82de6ec22cb43aaf3ec33ba4b19752d4f8e5c04245623e415e17b55149b63f5db00889d8a451e158ba3e867290d6816f33ea5f10d54bbfdce0a6cef939db5c694646f85b0752aa6428a2d05d2ed8395e3d3d476692809a7b044f0d4fc417fa741c5f837c609934722c0bdf518599a7509ca75b4ab4539c6cafe484a9e9610bcaee2d9c17fb872aa0c23d26b1fce5c043a0d174a5c90c33e3e50fcbc34438f15fe7c3b95b637922d2cd4448680ba54a3407d3827765301f7a00b8b15280a3a4fe5327a6579c31b81c737b192c0d0eed19486bbdf532d4adc63d10e6e79683d98583213522c0c08c1528b88f51dc9529eaa5fc2e1959a28385a5d6a48d25e891d8b033f378695c0eb15523f02267cdd728b3fd08bb42fa3d8f07df9cb5aefceca2cdd1a106ec25185b75891e00761a78160dddbe03e88d7597fe0613a6e3486c341343f789d68f7f2e372aa7688e9bae12136183f6f7a92bdeb67e881bcc38582ae26fac4f8a9329fd751e93331d5fec6c7ac725098341daaf34b37480f8e9cec1f59c9095d9fd1354461578aaccf2843249973c4c9ddc9bafb33ce3e0c4d098bd079ea8861a7f15a019aebe7c62b0d4e242679592eafc949b84f04d7e16b89b3da40c83d607c218d2c374e74023a7f44bea6810e14126926710e5929b84f8cac7fd6b59fe2c936915d7f633cab9d400fe0cb3d2a1b57a5b34e332395453172e9e05708d5e5b5bcc39c1321df7f071236380fde011dd26270500aa519b2731c398a384696c81d06a3022a6293b5f7587d5ef3112ecd748bb950237f4937be3b3eb206aff085485e5dba38446925ef4ba835a196b0cc0126f1aabd4b4c07823a12ce845452d334582f6bfcb6a1ba5ba612b9175990eef9606d6f47ae4661e97868a89b4c845f1bf950d4f98fbb51b1ce3305a5f893dffb315c4cf95900a0c2567a19913708405c0042e8dff254dfa600fd76c4a242dbdfd08cc06eee27fc3a2f10048996755b18b67ff419c1fdc04abe3c3341c06922e83da7997058857f7e79cc50b16018f309056fb7118caf53fa5061bffd8bfb35e9dc2ee93e73f235c1ed48742350619c3e99fe321c4f96731288234f801a076e7ad65a7944519f70dd3d4314b5a5c41c1113889da04f23db4c87915e0124e066ff9ece35104f7217cd2ae131abd9d335ee583b9abd66b0b56719e0bfc242c98ce6cb8ec78bbea43f6a8667b20ec84037fc787dfadc9c0d986f8d9c4d4339d0ed4bf86fe7e543297569c08a71e928705bee168d2412a016dad6c2b5345a51df60f9288080b07b844ffd9cd41998a9c7c7ee05d5e44d0807880acab4b39cfaa44157fac4a0e6ed29938a01fc586b3cb3a32de53117aaf55b650441a8b4bc2eb179fcc87e1f50105c177cacd33b9751a96315a4869ea779257f4cc9a4865b53ae60249db0242ac9d83e408940675e22347357426d14a74b68d1a18c788e30f35c0706a322bda97f2069b571e51f28e3c3c59588d3dd24a8de4c11af3a939e9a0e60248eb9b323fd064f08e88cec5647d2b14dbf99473c914cf2952982388d60b3dec2124b78d2119210d326fae7e2e4988ee40ea7f138925e3e3ae884849fa290f00b62965ae31db3c2bf13d05daf792a7f51302da1e2719613bee873331678720367c6ef152b7b34243a406848074f16ec6a3eb40a7588a6c8e1f4de399b899eb807402fcda1fff38b1580eed0f5fc0b47da9d526e8a4031939f4801d10a3ae242a67e66c24116065849233e116d74c9d8033354908aae13a73cf137c6ec0b40fe464836345c17628dd7f586bdb45a4d6c2c86e67286234e548e46628595d2e87ea12ede97cf2c652e54d99da85b20c150309211c38717f31e3517a0ed4f294d9055bd3459e755e2bd1bbc1cc462fe1198a287a27165ba3c6c10a59050f91b319454f80e72f39cde84183979a6102333f9c403b698f9d3fc01c2449bc8a46d3a469210553b227898ae1036e5ce814b4cc73c8a0d6b412a79d769b31f7a1fc869570f75c4212e5dbb6be6b4dee99c5b4b656376f925d079fcb70605cb936096d0beb93639e115ee4810b271ca59cd55edd4737e761eaa7ed90a1118621542011abbd9e36ff4a9964eee76ce62b6b17f7b1dff4eec31a7bbcb40c497ec175a81dce25e7008932facbd713030ce1f75030ddf17db37a56af37c0ff28ca8c1503f526384ee4a2e04fb1081efa6fa34d1586de26c6d6f43a99b08e0737523f9d47a0bbe20070cb23cf04eff3294f8c88df955c18ea2cc91b263a9fc7026c568a586b4c1ae78e6482ee154d1d10c95170db63f19dae95cf08871d959dc56f2837cfa66a9c8b1d61f012480822d831165960c4ff9b9681c566472bc60f5fa520199de14d2bdedb624cca0a9c8d24ea21c26832b9353a48729affc205c5fe039b9b1ef52f305038bd97bd4b13cd7b3a247be40148927f1ed4c194408965c0927b7a2966d17a4a178459b16c01ebfc4fd4ae043cf7754bba6a131c080c9a2151799a1870da1b79da09a2583f4b3147255ee66c6e23ff9454b20ea6726b97f6614c139a376a49cb8fee32ed2441c0b4154da16ad885eeb4e2631b5da6c40d44ad475baeac7f2ace1e7901f2c465957f8fd929f2df134c6ec3b0b7e953e5d0ca45a1a2a43480033b8811c3bee2f2b29f62ba5f36f4c293299c9bedf24fde4b11b4ea9e83001976ddf4b760a07f4097bebe0a562f666018eecc31bf67823dce1c02d7ac28096283a0d6342a8f4a237a3e154bc52d98c381082ebe1fc17aa6169ebe3af05d0aa35b2cfb4efbc6a88c006471847dd72bc4c3057498b1c79f5da2db6386586ea2451bcd500983385aa7233440fb126f352068b06e1b50b477579e7e81743a56f2398a65494fbfe15409f4bdb829b69e255c26102675c3ddb8c3d1cf0805ce6f86251602252c366eb4d3397767b4a0a2279118b4a1e9b34336dd679666ae3ad9f98ce959b3ee4180904ee9a40c511b808025b18f71c55d43457b8340358e3e8aeaf2a28093633020d404780d89b28eb12bb999098cd4091f2cc2dca0bbc39e5bb07be190c7bb2889264dba7bd013601dca77ed76debcb6039a9be329c2257d709fa004095c8666ba67aafc0e63f8e0f0efea3718ce2a1c7255f20f8e4bbb7459f480e4b1c9e7e910f99625da242c64180a8a3c153519882b1b836ba19244e1170eb94c5b3145507bbef996412b10a206c648b716e1fe9c085d9f7e660f2e21b1d1fb58ecdf8721cc9bb318067f9468a91efaeed88462584c340ccfbd9608ff46fe2ce7f6b39030bb6ab2f1ed2dd3fb61794d48131a17e09b664753e3f60bfe441597d0125773e75ebcde6f526b98c0e0ec3d59a406d51da3d1222ddb3940f674c98bece6fc8d38531f23f876e598b65307b66eb3fc1d23f21eaf406b6467dedc07dfd10ff36d0849b4262dbb95a172c39251b2c00ba2d109e0e603eb0addaa1a21dcbec670d05917ebb2ac95195d35d0008fffbbc0047fdf8cec334e9df575d3ce6cda5ead503da56e489d90255e0e872d8b0db0635adec800fbcef58138c39c353144012007337fc63f38dfe4e82723ed0b09287ea2ba6bedbe05ddd4257429aa3304fd764c3b47282fe00bdcadf3f37b730193c343da06c80b9015536be084d3e341ce2b225e037c9a0bea2ddb76ef97d57cec9d7f2601802571fcf5b4143aa35183cab80c6b7ce62fa25c557e61009e72ce9fa5898c6578572fbbeb6591cdf5de9bbbd48ce89f1d0389d5ae22d465b6759d17258453577aeaafb9c6750bc155a29f144b6cb68d014c39ec1e4099d201726271e95ef2e811eb047bb971c1688fa4e8d6eae1350c50dd60c3e296c1a2287e4aa14e3de4c5de840284a9638806f3d0206871856b14f8bd48747bf1ebb7cd5283b09c94208b37a71c4cd38144230744ff9d15054e5484f795c05c7d25774bcc89fee821d095070db7592ddf18a84aded3b59169696daf60c997a2a8ad2847cf72bbdbd0232f73882f8ccabe44aa102d2fc61efda093fd21e7b57180796032d3c35e0d684fa1b1e0bf83fe84eab8d3f865ca56b54128c8328f77cc936bcb65cef8ae279fa62085d34877578e0c5837b374dd106fbfa35f955c40bb5a5f87ac93d3c1ede77b8ed85368e9c14ada827a898b2b900ccb1c7876884e3d3f5186c5f31ddb8d2e9393e277034bff8a0f91dccdb00047d80aa1feacccf1e1749e5940c5c99f85eb4ac1c0256abbfb4264d07a77bb1f7f3d7ec6a6883b937fdee1f027cbaeb4220d814e06b66373768c580f988796132ff93b7e9f2f318133d286e78773f058d0a8d5b46fab4ce94720adc581fde2927fe0ce443577c50a7aedf8fe75e21d98eeed93567833bf8c878b5b088131128a7456b593c21c7f0b8c80dd0012cd65dbbcf6d3f132e097081f1cb04c9385e1444cdd836e2f019702fc856a3ed1ad0188af8637f830320670f0b331342fead9091f1edc33c5128bd259d9a8ba89b95afd984e6411f7a2ff19440657edf17c8fd071a119901de9faccd44b07bc9197b5e8d72bf587a583cbcfc096054f0f78f0f43686ff9e7e95457fded4ae03359cf0db5a98844e7a5b563096f92f0c96c463209a51cde59c5ad4e3180628b7a2912e50362801433629dea3d3a9e41438301fecdb9150bed31b03751d5861f604f33697378c396867988f925953a2994b93cad955f42f8f07048a81f58d47f3ed931cdccd80ae8ad54d063ea0a0c5d3d19edfc72d777276cb652d90b307f2d1021edf9212542e54b1dd7c3d2efd90f81831d8801b68850b3471536298481492ed68d2940a140f8a2b4796cf91d151eef277e2eb0302c64212eba6fa5c0b38a1570f309a2f79e4372d09dff4ca193339f9686c635a7cac4929764d1fbd1a1d09b29416b72a7d3bd0e82567842730562cdc7e6ea759d79eed85b0ef9591761af20ca076700e276985e25fb12ec662f0db86c6e801504857202d6b50facb149a6f445449ce14f62480ae455eafac6bd218873b10daaf77fedf387a71751418bd7a9df80501829ebf41b4edbac835a7a602b1cb334798d0bc7f30eff00acd3502fbf153a91bd66e37a372ed3e58ba073d2a06dd1fb539cffa98ba07cfeee901e1ec28e121069922a5152793c5cf9fc180804a0e726a8a308167989cc9654b3805762c194a693acf66c3c0e34e7dbad11850f1bb6fe1d408364c4cb10f4f3760b686adabb460bf486844bd2e67eb69a10eeed5599f1bfe41e11a59110451a1e914d6dd4e0832ccada086a36bf620eecec50993f63be23304cf04a0cbe725a35afd39abc971d049b65e0c4fb18f285d382256260eccfe056b839b8fdd70b2237f7b060b32932aecfa2600452425b2009bcff687be3814dfee877b012bafcd10b851a9e44fc1fb135408e9b1f9f3a910bd0c1dd88c9496b45fad4dfdd97bc51e86265d863cbc328b8ed8c18e511264f894d4c668d178b5d86811e6bb726677296265f5e494fa9a15fe058628c06f87eaf3bf88e0c2036eac63e0c91ef34f50b0595bbf4072f7224f83664695867ae1bb678015bab4035e2e109b949ecc6d66a341839dc7a25d8fc84bd3c739b90a1be9e3ff519571d624952e46bafff3ef676debc25ecaf377055694cacbfe9acfa7703c946da7a0383ea2eea88cef330c855f7dd8a107b31e45619a4a9c5b15cdadfdd01a5891c289b70372b6837a44517e56066bfaa205928739260e66cd3fa8e6925b1b1fbce097d3e0aa33eab0b7c5ea4c07e422449081da0cf1771b30515bc63cdbe82635e3025713ffc0f56d6d1900748c3244887d7c68d9b94da5cea781599621673046ff43f8ecbb14e53ea300921b16e5b03deec222193f52b3b325dd9ad631c6e933cb147d83cbb355ced395242260f66e87059cb03568922dd0c4d4b20ddd90f3594e823af705800bc4b4ca4b46ed4544e9f3ec5dd01fcf74e28426042237b53c373fb7ab2ba08d7784b2ee8dd6548c3a4f1234ae6b8e3d630b52e61ab4f8b031c349f124caea74ad91ba16e1ce341bda6abde7b1ddddcbad2762666762cca329da72292876967ee170366736cda2a40e9e3c2b3cb523d29a7c4bdab1b8e130d5b493ec3d7dea6a920dbbeb0e51a5c55a6605b7125c8d0ce45db87ed89582803e338efff9c748e30ba310384fcfe1af1f7268c5fc5f7d3cc280d6c903cfeed9d66110a02af41a2661128815f02498b1d48b0d8a9eea79a54ddea152b552b4e566889b5003f6069e273e49ae9437ae5d59ec71ec0cb865a135693202bc8c646a88256a0cf712a8b1d3bd57345b148cd4e53171af122dcda5d0af1529621a0edb20baad2accbde7b45ed1f02433195802c0af09bd866e6fa8fdf9e2ad2690dac35c5dda13f24f37e2b91a3b890bb53814b40e32a963771978f5264235dc7f63fa82be5645ec084dfd211f57c5693ddd32ef309ce0526e2d226a56f498962c4b7bbc054e8170d8f8855dcff4ac4245d64811a2e580dd662575bb33a2d72973736a41bf55830ad71148335787eec433525e068093e8cfb2bafc5b9691c3ce2397dec4b1402682a8103b420be13475ad71ba9f8a9aed8d94f7f7f5061dcf987eb2d3c592253378fc14d0a3aa0d10ca2cbc59fc1345ede6b5e8b9aec74194974712a33a46c853cdb52d61c6343c784ac5e6f77be5263de5ee219e9bc670346edf8677756635c386ab22913393c9fc2ee7916b130897a55e2b9d322a1185212556c16b92e45ca748e0eb0b0422e27503822524a7c9d23db635a49ddca2b07864f2ab00c0cc0c97e212e2d35db65102fb97fbfbf135a6cd391078f7fb81c85cf2b7f7c9e36b0d39161ce7f4b5ec9a63392126d2f3b1085a10500c2cc860c8b24ab5c14b996467aa3c1a45cb8f48e3d9935ec51df6973fbbeae3ff0bd2bd1f2d42386d183c2ae4d966796a6773e4da07b73b34881c627ecac67a7bf3ed229ed927582558d1c75fbe91588ab00b2c160de0a456df45981f73dc98e95be68899d8d13c7acf6017f02802fcb034e168560d1404c5ff9eec40adcd935180b9c33ffce7eadbf6e571d741dfd3c0e92403a109ff6ec9b7f70535c6df2c1e60537fb3fafe6c99ca6c8b0acd6c2b6756b410630d3b060b3a58d0937a9b042b6daace8bc39a0f87d122c38209d96553ca6c745d74c6ea889b7dfc20508033b81c9aa083a0c93874038905878fbd84463427651a32acda86d16cd58f92e2bdd0d97a46866ebd28cf428accd2463049144cff229dbf3368a6867c3c2b90efd2dd5199fa10f547bbbe1e50e0951c1bfd086d5947976d04c2fe4977fe644319cfea2112622176327f4e129714d5dbe33cf8bcb95237a7e510e1668fb7f5c51023ae3db2b8ba49ddf9f0eca1efec402cda3c2d054fd682187693578281022468b3a6a604adfcb66b6a718344fd0d5a1ae03173449ab78a1cc829980e0f6dc5d91f8a07d1ea32c31b1ad785205e776638523f788c314347c11957bbbd80b374ef397e5d3a31a105daf920493b9bb3beb701ac738bf906b4fd03ccdbe4b09f923e5551f7241f43381cb5a27602af570624c14db3774dbf9747fd800249c192e67e9e63aac9cac9e48057fdf155a577fc35bf9134317099b64b85a8a5744ba9b440872ef8e6d7abf35acbd04861c2d59b53496632119b0007a89312cfb97cff6d4f57b2fe35793677261abe12b459edeb996f74c30650a0792119ef9700adf973c00b3537aaafe3c9b448707c100b30a24d3f012d414f36cc291b6af2ff94cdb0f76cb6ea6b129f466b702ccad0fd6d8b99835ed8e6cb3b481426c2bb11e57e117fe590091c4229924c34ef030c1144dacab32ef4fa807afda534eafe958be8892b6e843f0deeba39d2f711851a4aa693feea33fc437744459e105712a2160bc5eb054c35c35b424fe6c8760c4bc8f925ff452b7913b4e416749ee48386d36e3e6e9af29d9feafe3ccf9cf42194b2d24774e9da182a59e14268bc9eb81cc2dc0cfc232d5362afd0da1862d12b0264a62c0a9ccce61648967759e0359ca7f0ddc99e25682de13876c551f23cf4336f5d88716008f9526af3f14a99e1514872ca14569d290c9d9f36f655040820b1255fa0e97b3f80e17417959aac383f8ff197638a47624a058f704e1439c13fdab94e900836fa3911a13328a2347507b0cb4ff63c686a122e23b8ba0ee8cc21966aa22db1b92d58c913aa876ca8a9dd60853a4dcfb760ccc9e50e710b4339eb01bdd9344f2a30cefa95317b017965bf447100b703a07451085657c8df483679788121d675c2820ae1070248b46284036925edb7a06132ce2a943e111b585123be604d8ecc0b1777af93a540bc5f9e1e7cdc5799c65d7423fc518a862fdc698c5be32bac20fbb1d0f2dc41d011d034319fe02c2154e064cbd204fc0860cfed60aae55a8ba9230780f31f8a9631c9acf94ee20730242f7b695fca20b002086a4e04a300166947cb6d7812f754e5a83d5c76faff07a0072b7500c7b125e2e2ef15f6bf2498f4b7812d2e83149ea24a50185e09ffe5078f9da944a60a391365c0ffa96e6055388fdcda03eba851ac03e5d736651ade4aa54529d0612cbadc5c4351d28a5b7dcdd890d0dcaeb5ad2d8b048e1cc8a4466c149b577aaed0a357792bb1c26419fc750c681e2b5024b1392ddbbc84b1c501fa5c622ca68a4ecbd62740e5f96c65387846bee10b14382e177af167c12bbd6756a15e64826bcd3df531406022af9e179ac496343dbedd3cb7532cd23c6f3f429a5ed1d0400f42eafddcd34a6776372416486b5009cba5ff45a70c3104aa7eb6a54d66ac272bb83c786e4e3364e1e786f57083013d89721fa7e3a192e1b8633c40cdde621615498ff3c5f1793b704a27bc6f36580e6a2a5c1799ecf3b2fb1c6a516ac4a12c45c7ef87f19bfc750cfffea3b64c34e9d7fa75c8b7219b70d92c6cab6c13311850d18eefceae8df35d00642f3a7f79a8de06605c93fc23a9ac45a419e4308a89382675c9e79aa7833d9f52f895b26b0309938a7af24520e061c984d3276a136b5d094532d36d452537325942e7e7ff4c6ceaafa25ffebdcfe1b5b0cd7e1fa084ab3d18713cc8295edb83c64abe890725728f5459c01f9d46595013c41fa752db2c6aa6653bdcd0552384ccf118ab95d9d232c06df5ef249132161791026c1500853755faf0fa6caaf099d90526e7859863de08dcca5a5139b1ee568ae9d9e7f0093971d883122b9900b382b612094d05ab9746b332212b5aa40d02003f66694b1a77f52af97420a43f2df22bb29a4111a4912bac8fc8bbc4251de925f96561df87e38875e6b9fe69c1053c7c3019993f1ee0ee11504cc0f19810b0a43ab4fc2b76e71bd1fac498cec8a12509e856d6011e9881304cb23cbae4f84b5aab03de24141a7fea7da0389e61e37497a878addc42b5c8dfff061727bf557c580472b3351ace57e162b1d731f1125c5ffef82e93bf7bf6b7b4de5491f39cf1de74aae13d6e1f1fe30235a49080046aef913925db858efa3012f9244bac90106393713e26cb871b5f27171c1dea719074323faa6a5d900409e28500b0f057a3b576d045196118a634446f23802d29acb8dba93922543e846f905a3e5b1470d30c9d95b808c913a6ae0178d0cf0d8481e2cc478250ca4b44e333e3d6c0dfd7bb8cdbf49be5833198708041afa67e2bab4ab2779fe9c34c4b5f5f3be759a5eb9d9ba8d50671bb81231317858daf82ded9663245d1dfcb4164ce8d738f02ac146cc7d008c1fdb7f54c0f4803a0dbe5f8c3e605f2c547b89fe3339864ed1b2da0bd991ced317c40376c5f2a354e4627881315db417eb20a85c08d1bd5c4c6955273084307a62b9e42af0f55262e54c5981a6e110df34e8e1fa0b9904628adecf83e4fbb2866f491c85f8106aa1030aa96146296543ec21e02945003fba134e46f6e25f393dd0a6612aa102cc58965e9550e48c389c1c04a326470cebedb427e442f8b848df82a8c5d55eed0d1446c6e5d6e0ccdfa2d219019ad3d400fde350d690cf04d083844adefe5069c7066b0ea24854ef3f5853328d7bb2ea735b370eccec5f0f777a467c98f040c423fc4c3df237ee8b1e9cee6c859c860c0297667809ffc0b73af9815b01384834fcb56d3e782ce11ac9124345a3d34fc22ff7e0c3149d66f7bc8feb9743bb54405ea88902011cfd4ed07ee19c6b8e6de6dcb08e2e86427e5e675dff052652af14d7af936f032bbbe508c54fd4dfbd16921e7b1c1471e96f3a521b911e32a5888b5a4083be97a3ab843a1dacc19e60f161fd84c10fe94c9952829da6979a83ff25faea14df6f6d5c876f3103a8a93deb51a3834c9da185355a8b189585f7c71ca082295ba29e326e60b9d08ec5386deca533a03b903541380cdf616135e348c6b09a5cd4a074d7c2e3d794e44a0c4ab8537f3f53b12ad2c2a996c5ec0a1b6d9a25d920a782bbf2120262a71f816a66ffdfedf5e5dbb868d37517607e880d697720a0119077b19df4e9e8709a177bd25508b00c6c79d4b1c1ca7f607aa7b18e6f93e40c8ac9d8705bd9deec9626cd4aa06491416430f1e204177b62d1bd18e9fefa0da4d6e032f785851dcfdd3e2a2058b1811aaa976c30a067d9accbe4504abb7c2a39492889fe518dc529cfb481320dc05a785cdac3fd225936716b149620ce252d079b0f14a947bd7efa17868935b6483516f7653fe108e5c1da91db5a58a3aaf920ecfacdaec9cb997d80860e966fbc4c2cdc52f41fd3dcf8bfd70fc4a28f99128b1b5e0d412c91fd59a9deea1d9b5170e92e1ba12064847d72f9ed9a58874ce906252c6679851b735cdd5f3f17e35e0ec6117e83b9718e85bcfb608428bf03df02e2950a07e80844403f21b8b0e6ce349c5ca2c260aaa780949050d2d9fb90f890e0d33b4a8263b0f3ff72d06ad34072f3567c85a6e301d5b374d9a78a94e5a3523735e3f9c2db0734aa7c7c5787879687b485f1fce35966c742b896aee8f0361d98ff221b58f0746a0bb4ff1443b1f21eb26e1503187f52903a842a278d3cccffe3328876cada9acb5f109f1679265c39ff58a2f5f63162117f63556389d00b7ddb9cfe0346c62344ac0c9f130294d0178425920cf8c5623e09bd387d8f1d1bc4a7df18f8f38f20680ce2734505fccf2d7e13a0fa68ae5f7f949346bce6896c992cff605197740913534fc38ab50d679c92bdd04e6682ffb8581c3de476b13bed9e72cc7807e6ae6a0f0fca5cd9a03086c1a5971991a7e0a074c128727a4fb8e63240df8d4e87ba2077b50ca0c1de5ca6b4a09fd2d16022aad1342b0dfcdf706d13d433db3f592bb467f911fdd09969d1fcb4fbe4ac156a4227dfba8999642bbb7239cc6bc02d4e1cc5ffa47642171b9807bc2e62027befda4cf5d0b994e36b110580f40ae0b8505bac989738219bc3deefb4fb85037482687f8f196ceed78ef556907987d952b042016046c57e36e47e9d5e4c71d5fb7bd2327809e4663d75a402c9b6d89857d2d07375273e3142dbfbd1c4c658fc64e2436ad5d8a714d9a626b8c6a26c3ca5cd8b7bc75162e5ea63a1644e4365ed6b16107b8462e7186586b0b2c43f526f0656c544b70f5e59e809462b1e00853cae8bb57e39c55abe0e2435c53bf68c0dd39e3bcf6da3250f4ad1d47f1e9813b22b109c9f2ca6b06b362f8a0c11774cd90321561ea5633ae94828698a5b87a338a0a1ee58aa9e3759a68ebce835ab5bffab1cb564a704c220e8f451d02ca511d3a61071e59d7a638c6eba218fd186a9abe7144e21dc862d71cc14fbe19898710ec7321917cb26df10994c2d4980eae0c9c512cfaa4068fed52d0c57c9dc3fe75b51f333210839a37ff90e8508bbe215d7fd50cc4c90daa00e10194fb660fb38b9a85be80afd5232edba10ab7c98dd8e5ca4eaa6fb7828b529711682b92e5c980bc877a83b9d7f0b848181110e370bee7ad434463f90c954705032d56c0b86305b83f61642daec190941c8b687f46d70c0c0cb4d627c0af930844189d3df40c1ac2c5e0f19e598bea0d6405cbb41e35fd850f26bec7aae8873c883ba0fe69c268839681796ad11c090e891f6cedb944fb4118092d8b4397dce87fb4755b1ac74217d12597496c41370c4653df24c3df308c2c9605efcaa3e8fb55250eef97ba85bac046d6aa82d249fdd348bae7b1f6e658b8072a2aae3dc22920e419e656810cf8f80398bd4dbabc4df89b4b46328524ca43edc03677156dc05a215d2c504db8b28e876a1797ae0b57de85f634151a8bde6002948ae1f540fe4d5f53186fd979992d4bd95c2fffdaa0d02596e17b439ab392ae0f50e6bec0af1ca9668890801d5dd1c9fa69c06ef9fb04b9b0260e8279bf93f1fb0de27d60b0c0d07329f986aa78e6660a8d0785903e7bd71fa74fa1ad87a952a22ca0c215d035817ef038624b5445a326d84ca96a7486058add15801596906b1d78381b9092f504db0008628d32fbca6471359d445a248c0019ff3b8f6157b7b45c14c76ef673a927ac5e425c0a2cb71cabda5b2f323aa037543ffe1c84c1833ac61c016bbcda50b219bca8b2d210914e2e6aaf5483c943fd4e7c68228b26bf751cb466667a66529cc4c19812a8306a25776f5ceb24a601baca327cbaf470a61955474f3d9ae0aa8fedef83fd62d1d1e843a835c3b993a00f09faeadf015cb28d01b01fe5ca49864b667ba0cf0ceea8439d39cb2a9ce71f7b3a5a9b2774141bfd68baacae775d48ba40cfdeb1d1018f77ec090a44ca5f4672f8a1b6110421edbf5014dac6469e980d3e207f43e25353c1a7d4d010974e145a7cb8a5e05d7d79c7f4eeaacd410dab582adff9b9ef8ffadda3682651dbd8ee69d60464070908bec020c622cc00cee15aed981698ca7d413b83b78fc1a2e6c85bc11787374342b243093d26301476c94e671d7008c7f076dfc7d5ea5d765cc4e82b0fc85ffc8c6637909142f4f3fc943170002ee6e4ffb8a3807970aad74a2aa0faa7a3bdfe4c925757497aee9bd3c1ed174e3aa9ef62d6c8df963d0272545e3a19aca824d7ebb9e22d1818f67e98d5dc3e1b3c45fbbaf8a5e053db3fa77af51d975a22ab70321bfc40af2e3828542f4236adb4755552c9437ce84d39332588d33eae8fe5119eccca99d74962a3c9f09ee67eea15f24e58fdeb5536db348f335c67ddcf19dfe848cb1bf5f2be87f5641032816376f9dd3a983822463898a9ac4fa1c88294747715251561bed2933c08be3c006f05a7b3fce71c179e9fc1bb1de53392ba96d0080179c058c441b9e370714526fe5a01dd1ceb43fdbd75efa6324d799955a4cf9441f50c25e456c6436f95fb183851782552a4e3ba51d2597225b8f2b84dbd01ab4bebb18a49712ea84e86297c4be4e394a3d88646bc8da23d09373a2534fdec05540253bb9435ce0f9c1ee444de9557f880d3bc81ae16dee47085dec4022057b0d3cba15569f542939f58609cdacadf9d5055a9b123be4fdde7985a8a4eee0d37032769527587fa1e09cc7122c8323d1c7ca23a98dd63e970031d8545288d6224c9cc034e60731a9212a89fc6704e67f4ff3638366168abe7c5300fa1dc6b95f56e079cc9b97595750031d8d346244a5619031e924c5eaa8ab82200032737621f4e5684fa19c40de1ac18cc6d416ca42dc59e52b07e1a69f3dca3ce63ba55a4c1a3cc761148f83808c62b840b9252ec3fbb2060b9e7c75f6d94891722056d24771bdc8806d3c5124153b2e07ccbb16b02987c0e0ad70a29b48ddba6a3201ed15f4c055ce2b9e3feb5a7ff082215587c9d891c9c02c2eae1c5efd8625c6535ec57be13465f5d4b5acff1945f0a7a11b0e41546b1e8f3a3ae85fff4ec1c89c2dd44398d04e7689464ce2c631929b4652c9e7645684a0857d6c2cbbe2363496c88a5d05050fc76d488ba7f953959cccb5ce8e062c203df001a542cd5e3ec4fe97eb15619a9149022c9ad71b9de36a3a5d257a0d3ccca684666a703ded560df69a53ba546dbade63093831c306d04bf0ab91ef00f96e22edc0e9745ee374693ea38e7c9a66f766d395be678036af3520d65e817f05c7a9e4b5ee15decfdd2c40e6a75789c112a2cd02da7e7aaa27b57b50626a8f989630b47550d39efbdf17d08da5e066039e2be80c51a0221853d0d840fea4e5d0a818de468b455d1a99b98b69ba89c118ff0bdcb250fbfaef760e3eb3098b92512e0cbf2cd32052281727ce17a1d55824fe953029190dab087eb179c5981c1e785a2400bcacfb5fd63025983d3841b2123e21b529bcae8f9162068db42e1280053dae8de583b3b713f2f78738df67188b7a01f40f0918fa1e51ddf85757ce251e903bb996d87ae4c845a420e6333e0a3c292521190d1318d4840446166d1241f4a837b47179ea554e144991857037225cbcb44e782a9c08d58f166da0e7dddd3b05ff2f7cb5ca53e445a3e6c06a1e3e03c7912619a8418606b4b5a6d8df274ce2aad313d5ac4305024352e9219046a0ec8ff68f6d7ce075490b9bd41fc9940f8a73fadf6577a4742f08d0524f72500d944e950ec1a7b45d2bdd46df4bedae251dbfd53c97a4d3c746de80214c46675522ca77fcbb13500597ad629d5625f9c2ea4c38d1334225b00ec20b9127dc4a15d65f129f4f95668768b51b02341df16c8430c163878ea13ed24b683b993732cc35b987c78e2bd25f1fc6ee4e152bd489baebe997a247076d380c092acecb79c91213a29ab370776cd2c3b3871204cd156e2ce3ff091fd31b65cfb824f14f400f6d9bea7894b8e2744e60b68cc0c05084c024e1cf64867a132f7429c9411fd0c9e225f4828bd9f523bdf3f5a8c21b09dbb8f4770bde3a488928ebdf0ff3d2c300bf6f4eccc94c5b1e4551ef25d144cdf78fbab3fbf37f01160ecaf91b153e6a9322575c082c4eefcfcb41f606eacbc87e9ad7022a0916ca782ba8a2bf4f408d135a1605c85ba1e211a78747ffbd1ba7c36589bb7cd801166efcf55a8e2e9e24bc6cbcfbf1ede191a777fb4a6a67a39bb92498b8d06b287882c859d668a7757716572334aa19f4624fbd7dfb3cd42a34f6f12da60c850a21a2e9998bf4256b961200e57621dff71ff89860ab8f1388b889e6836fd22f120d9f42e08f4999454c0523038e056404d989a3dbee88cb59a57efd7c5bd3827bc85a0bc8c02953ed0d7dcaa108c115a48ebe00c19ac6a0b7daac1b1468d6d8252e93f061bc381523fbea0f248d4de1945c704fd01510d54aceebfe791ff1a44852613dbeddecf2e7fdff1e981cfad3c615f65ec413546c787497f2dadcb2022a6a2aa463bdef07ce1f303b06c8413357261f8d662a71d344737504ba69b8be1ea8252e6838ca8936dcd7041dfd6a646d1cc0b12436f3c89a7feaf8f57fcd34f860017798b1cfb22395d2f2836dd02988ac37178f82e5c543a98b8982e59a0729168c866526ce53173da0b9300e6c17ce85a74032f052a82142b290911a0edb93bade04baa6e061678107143823fbfdbf3c06c0dd0de671ab6567cc3ee3a657e7ecf6d10acfe4ecb89f9698307623643468e0ecb86d9d9b18db9ebd3272d674b43d42784367f2454b3759ca6bfdb30a9001d8b0ec48ed1378d40a33524c3a81de9f331833c8a3e9cee970f651dbfce88b26ed8f6a4240fa2907529e11a44d4b35483310d25e3c006f2d7d51432acc216d43a4de48db275262f925ac1669a7e6e9317fac48f5a8c60620767062e78bc4d93c3fbd5dd47a332512d2fda7447f76a7badc77f862f290ee4b89804280f591a6badc290d3e128c46b681e69d71c3ed2a3b6cc4c530e0479309d6287b692e08529de31d830126afb4a4652a8aeb3303d3547d00b93b661edc1b226d6d79a7761fd1e43264a090a0d8e9cca3454ff74b8257714e299ed3c6f5b6648b9c26bc78ff09121b9a485282e4c5c2b240129ac0819c8532b0b9cca4472c180836f7285d09386581375779cb546d4c8ac6043b3255ab1035c1d6e07647f453130bbe2aaf04e5b7bf49d0cd6474c25a75c67901a23870ae77c32e61af3ffea207f8749100649c3cc054c36691d4127bfc7ad18e1f018ed75f0609001dd83e41d6e2ac66964c248eccb2802c378c9252146c8674ac23b81fc13b0089add0152a1141a6472370df94ae57e54ab1c3a26c55f24a1dd0ccd360e794f0a63987a08d50ffb84a76d3689ac1211ea5d8917dedd6abf81476dd0ac1c7017aee6abc9ee1a41e6f5edd0b89b9d99983857dc32914abc1e20c29c2c2882c21923c947c980e43393500716ba97ec56ce33fd4d01240988636baaf5aca649f87fe606606fecb888b6a7c62dc99688774d648982ce1cbaaa3282467050963b31d95c29f55d427d4166b142f767a695ee5be116bfc9455f405c12a1c3e7dbb14564f94c73dc0a7af0aba2b89c172b2fe5f9c059c0a51fa792481ba1fb6f97faed51fa1e1857eafa818290875f34d876e2a17e5adcc7bebc7b01b941b9934c2e4942e9064d836f976444ebff2dd6c52f44fd9132f4a4a0ab659f052f5b80e6696d217568dea33b7a90302d011384961f7809b0238ed7e26a28492676e4368ee5548a3f5be6b7c3f4342ade03db48e82bb247dc95b52638fc38802881d0c2691f2801d0be3a66700ca06e22070d3987ff4d44db8f952832f0a74e43f77b7874bb68fa67435fffb3a5d98b034ae7766999e8c9563366a70d86110deff01dc7cfae0391be8ebad2fe2d816a06daa82ad16587e43c91dcad74b672541420d12c50f82f737de005ad7235436f404e87ae5b3ac732a92a34bfa3c20f267fd4c7ab07947232044ed716b52a0eee6bbd8388d7e4d15c904a4ac17bc8a7c57032a9e8e8a5c30ceba4a078e335cf0db5a938e3233d9e16a503d741755da53cb2b848c86c25199e1245000f93043ed0b8ca80200a4d1cd64118869789d5e90f2b393c38faf9492f91051c29563e737b8d7c5c704dd199696ecbdf796524a299394015b080f081b083dddfbbb0e92e54cac171d082fc24500c43d3192e533573280171d8acfb0e33fc3cc2ba48f17e79700bc38bdd079718ab17b78f8e26c5abd38b570f0e2740200fef30889f313080d369831481685caef5a062fcea0a9e47b518a91645422baa2362f4ad98e17e5171e456408b2077fcd8b52a900dbc50e7436cd8b9f6366bba86dff1cc9aa4168760028e60680a22e0104c59bad251901c5cc0050d40b004700c51b8d480450cc0a00455dc4a5116dfa2180e2cdce50208062fe0014b50730a84d3f01a078b3f3880050cc4440516f10146f68363a0028660380a22e402b1b6dfa4240f106cf7c4031f780a226c06bb6e9077961261628661e50d41d30316dfa406694857f80621e00286a01f88cfe8ecf70cb0728e60080a2d631c2ad4dbf87d175ba30baa20f0050cc1c80a25e81a2ca69d30fc7bc012866ad0128ea1c5054c1367d1c50bcb92ebaa26f3300c51b15088a2afd81a2a6ff44f90614b3e6018a7a0798b46d40f16657998cb26c0d28dea87480a24ae70045adaa59e300e9cd162d28de6c51dbe055ba1615499d99a40227a67136b3e19bd31a5112b09766d4d42475269426457369ad198cc2742a8f5dc49c9868100d923ad9680924d86ba63edf5c37cb3564a1ecca2d2525a9c314862ce6e4464652c777b7e1177e022761240c0b1386c32d5c05136121ec72fa7c6f4e6540c96257264c8a3109690ae5ebba3f5ca32b044605a9336363665032398620757cdfcf375791ac601a93449c2d933a54db5c446c2fbccc10238707fbf9ae9f6f4d4657f445215949636df91d8d4d8fa40eb67c20b2c73f67b1ba7b752315f46e7bce0eda5fb6a9267b2d49007b326dad71b66912d4a63ff67c516362e747142005d8b283098a40f6fc1f76fec654c294404ca94bd3d6db9f7ef69c2a5a7a983d147776a84a2582ccf6f7917252ea5cabe420875486568656665b9e200fb1b0b267ce13a6e7d3393fb9bb3d6d0e91aef9405461026da74892ec49bd6c31f7b03939e80955ab5beab9d30f7e53eae1299cc4113ba16def4bf92738cb47bf50d65aa5fa705321fa725aedc559dbb8ce4bc9e899ba6bd2e66cd0dcc081812a878e1a9b1d3c6efec3ff9bcba0cbc02b92b327160f2d0e4e475f3467ad73cc3407e3ae38a741e7f3714c74e57405e6a17d24586ca645cec5b99c27c8593e6f61b287522ec63ddd7baf067f2f0777f5f7de7bc3bf37c8fdbff7de7bf3f7b22ef8f7de7bbfbf97e7dafcbdf7de9abfb783cbe3efbdf7eef87b815cd5df7befc5e0effd7175fcbdf7de1c7fef002ecddf7befb5f1f70ae0e2f87befbd37fede9d5be3efbdf76e7faf8ffbf3cabd7706e0de7befd5b95368e6affe7befbd3deebdf75eeeeffd1000f7de8b736feaefbdf73e8de7c1cd206783202c9e0e80fc188000767c0440a7070034c0d10087831b2b1dc20d34c8c1c9c0c6df70cfdd703540efdbb8edb79b8d9bb1e96ab66db3d96ab64df3e0766cdb66b3d56c9b8c6ac360db3ea523874c25c340e6d1641be3138d8d0e870e372e8d8d17a7c376d452b9361db455c964797399ccc7a7f18e3e6ee08ca6b5f6cbe59a1dd49f6f0ee394cdeedd14f7b6e7eddf896526f9d898eca1201c398bd26a85d62b58b687f3de572ad2a702ad5eac55b6f7b548f684ef7d6d39ab6697e76d6086f4a9473c2f5234b677f35e7dbd9e5e605e514ecec3a30ae953953a78915ad1247b3e2467d5714c1ac791e98af37c11d2a73e0179911a01933d35ef3d1d725695c968d191f754c87974bcf7148af4b1403f5ea452b6b703ca59d6356b79ef609cc7e6bd772fa48f3d7ad1c1d81e064bceb2af57d3cbcbeb69741e1c4e481fab248017fd0925d993e3e52c3b8eb011c953bdf7ae83f4b14f3b2f3a0fdbb3f19e9579900f156d2fbff7538cf4b940d3879d63c2c89e1b31675d974be68272cdb6477385f4b94701f0debbafd7547a2dbd9ab647dffb7984f4b94ad387d5797126b1bd1aeffd2472d61dc76934bebc991e2fce29dbbb4fb23000785186b1bdcf80f4c140f3bddf80f36cefbd0ab207bb64ae984882b3b0cbfb22d2071f4d1ff6a5922702d9de6b04e7d1defb10644f7def43e749bd062f6eb0bd773c7ae08b747b9f237db0128eec71161ee9cabee7fd943ef869fab0ef79af81e78197b4ab8bb2b8eaca711d4d1fce0acf1165715cd5ae97d2f4e15e1d286dbbc964a36c94d5a7e9c30101a94fdb7e9551d6368e553656d9586540d3677bfa01e4a2acedf572bd5c2fd7d1f4d9940670f4a2accdf57abd94a6cf762400a56d35996c948db2a7e9b301edd8a76ddfca284b1b472b1bad6cb432a0e9a33df900725196f67ab95eae97eb68fa684a01387a5196e67abd5e4ad3473bd2511a292bcb64a36c948ddbfe7d9a3e1a508ffbb4ed5f1965e571bcb2f1cac62b039a3ef90900402ecacaaf97ebe57ab98ea64f56e2e0e84559d9e57abdb2ebb5ed63a5e9938fa6064a948573d65886c76d1fe7e39e9ea64f069a3e641508c8b7889ff653d9531995ad40fb3494d98083715634c801713200410ec659d9f6736e523c38ee75f3dc6bdbc7f9bc97714037321e321907b4ed6750d3e9189f6a461de3f8b4ed833b389beda554b3bd746c2fa56dffc360c3b1b9b6230c36178ecde56daeed68dbff1c9a4ab6016120c321f3641bd0b67f6323e7f1c9c6e88d797cdaf679dcc034da4ba96ba954faa5b4edefb8976aae23cda5b934d7d1b66f53c3ce649906d4b564b22cd380b6fd1a239dc7a73c8ee3530d9ed68b872fa5acc197d2b6cf693a2a9d4cbeb3ebc8b52d78b4eda738a11c3e95641968fa6c2328aa545a63d9ce40db2ae98f7b926de3f4e1be481ff66d4bc5c5b4903a761bb77d95f7816f1930a78aae9b6cbb93f3881369c79c47ecfcf3ef590478fb53698e7329ecaa8baeecbb5c1f3817fbb8274ee6a22c0e8cafec87d996737151dbbab898d4b13ba78a1637d9b6bfc99c07cc06c5c168ce5a4b0ec90d50b995742e666dd6aae7643e2ac3e2dc323f559a0c78019c1054903deeeeeebec3f3c0531f0a1e62145cd91c6c990505aecde974f373ceba757fcf885377b73216dbf5f3a79d6ea79b1e50fb1944e1c62b32c116e6b6e005a48cba165fb88eb65402e8aa3fc5acd0b10279c57568e31ab4f15331d2474a1fdbe3a761644ff7acc9346663c7130a8cea098bb429f519ff6cd2a09851e0e1d2fbe0c88f15ea7419e5219612fcd1cd8fee681af7daa6713bb6d7669ba79b1fcd5aab7e0cf7dfdc600acae7e119a9ef3b3c112a131393b7349d4c934903b9209d134dcc06e3c73b4c745535d734cdb70f3450771ee6fc6108c4cbc60fa429c706cd01e92efe1adffcaa5d8105bd2b2075f05340fac05545592af80abf93e8318fd9e0094e210cbc22149c4473c83d83f7834c1fb9e3e1bcdbf4a9efb258de728c93e1f08a5cb07a78856cb3baedfa2777cd5da76d910034dcf950f594898eae83c81eb977360d695efc1b3830f091db878ebec2ab1b9a46e5ab95d672784634217494d19ebe9812e9c8b4f1774f71784552600b73cb8062eabbd75ee519d1de035b981ef3108b1e63fad1ea400decb4ea7d0b75e74722b3f3dfe764073e7d8e7e3a609a82f0f45e58464270b8f3a1ca5b9476ef19a1413ce4412226991327041584ae38cd30464a2e0b8235d1592daae17970f347e319c9e01c0245ff4964348de88bf7690b48c82b72535c900e7ff8af52693de60ca1ef4feeb989bf7b7102b16b7846f2fbcf18394f77f49af144c8294febf09b4393a8a3e338e6ef5e14f2c022fe4da26f0ee550c18f82d4c1eeae4e88b350a02bac04b524674d58ca1fc0182d4e214b97a40e7efad151882f31fc9f23c7cc0c550167d7b450b73f1299edf9b387ce231ae1c04ef4d745b6f7231c38893238877c0a4d21222e7bceb30905ffa43c6a26a78c02a5ed15f1dec116e607f953ef9e7f4e7d2ccced81297846dd0764fbc40eb60bf18cbc4f9c401c89418c266c638c9fc39db79c07c85d1a7822e4f7bf224773d65a2ce4be14e877812d878aa64b7404e188068f70e0053cc4cfc2dc1b98c28f17f0a3e03cdb63cca47ddcf6e579c5c6184856d24baa9f4c94557de5df650d631ce2e778ecd3af7e8d4f888c64eefc3b94e54fbec20f66e3a8240fb33106daf88336fe1f4fb4e87f57a8fee4f8bd22146c61ee0c6ab0fb68cd15c6390b37701247ac42bbfefd797fbed350d09eef5836fd1c22cd45a9e09df781ddf9a5f529377c737cd022654d222faa26bd9484ecc9811e217dbce88acf5c70e127e8338a44dff31630ffda22f3535e91f917949bc23aafc8b49bca7bc11e1e52b08e30412959142657f591b4a45de98823750059813ee2ffbb3ae82fe93fc41dcc41e8191235729ea35a93f66d39cc75643ed2f695fbfaee84ece9be7e37df03c5e9b2bd790b98bf7945e63b9483f1996c86690c6afa741a8bf5a0459fedd8b3524f531f7df21585499a7a5f39d59aaae87f28f34b1ff19887f55998dbbd7828ba93c3809c4774a75dab4bf6c8fa4960c6a830bbfe0f18b4e84eeee43c1e73e9d291a8bb23d125aa44b160f19c4daf7858fdb9499f3cac150884e915c8c34a6352a7be10fa087d16a62355094495c89eedb9dfb6bf9fc881e274d9e6b0e8ef3207e361fd9c1e747d975587c252a9087675905e79ba3f63333663dda657a897c7b111298cc2fcc859da8d5ce25abffead4857a44ea558bc68fad023a48ffa957af926d592a64a49489dfaa2e7b0eb733f5c5aa43198f388f4efd72fb2c78f50ff90c8587fa7a1a23ddf7d3ea5e01cba9da8556eae503757bd4e596d8a7a719e1e3416be4ad39f4f9f648fa493562ed5f99e9e8775856a77f6d01271a0ed3b149c3c48ee0fd164687c04c9058f50f07ead427f86eab306ab874c3879438b9656cb3af3429cc77e0c170ce11b2104e7a9b1e007b66efb41926d2b0d61841c9f5c51f76ad4ae4f6badb2d65a6b7561df2c575cd9a21ce5df0fc179ee8fa0a239abaefc6ab0fe21839e2d0fa5644a638271cf33342e4a29e5e74c8f3e2769473f107ce30fa2895cad0e4a991227845215826c0d04d96208fb88fc4e0c617bd769da431b5fe34f903df9ad9e2f93f26eec39ffbe8d1a9fd42627f3a53e51a5f70557989f0a415436dc092dd0b267befdd944f638cf7dfb53c8ce2b2205c50f6c79c54e20e731c1431baa54f2e7bb6690ec9992fbb7765224e9c3bea863b59c55f3d321849e20d878686d9289f4f22d9d394fed0312a5f3d39f4f73e6e867bf15ac7d77495fcd7befbdf7de9ad4791ff8bef7de7b6ff579e9bda9fb61ce5a7b185e9bc569698ba1d427482badb4f2f39772b6b4f33895f1192dd55a6babadb5d61c1974adb5d65aadad44b22db35811dbf6a5d7df62be9fdcd509cb96599cae6cf7a6b8ed59634f1d53f64c4daeecdb6cc73c45db97dbbf8ad98413ee0ff10bde90e9743138b9e5146999c50a2b5b66b1e26873dea9bce8a6a524d1a7a391d9bc907c2041640f1a6364687fe44abcb1e9933da93742d40ccac3a54d43038af5b52bd0ae11db63173127262c5b6b50a4443bca630a4316734aa540d199f6eb8924249895dd75a0e8aeed5406942cf6b461528c4948dbc6e1d89819942c67242b98c6a42b9bb625dad93b5b4be36850dba62f725bbe4f9e3ee8ac51482964382b1572456b8c8c8a85d64d4f0149f6bd56a98e7bd22dbd9a4445b28238e0c5da43035eac4294f0623d8204aff1fed40cc942c1c88bf50506bc589b2ce0c51ac3086ea30ac99a2e115ea42950c08b748b222f521684e0ba08c99a30105ea422f8e0456a020f5ea45912f02285512892359d10f0229d81c88b94ca7e91f630c4535e4896b70ef0a28b618017dd8c02bc485f1022e38464f9cbe745d7d2f3a2574180173d05415ef42725193209c7599208be3a68d0f225b883657b9c33d775dc10cfa2de19c43f846e1e601ad504a7f6947e62b735aa499f6e339d765ad5d1e049aba6b1d91857156caad56854a1a6654da3d99a06567b6f9d9fa837e6b4ac69793e0627c6396bda764268a9bdd652fa73ce3927a53f2db5d75a6bafb5d7da69a7b5d65ad05f033bfb48926ed68871d2d68a55e8c40e23a163bad79b820e4ed061462bd44de3e10d2d7a6aa973bf86ff2a95be5ef40929489d8b8287f77384d0a2def763f7fe910d50d6101530207d24307ddcbf7f5fcf21b13dafd8f367128b9b4ff82183963d74df9f462fd0dfee6f1c0625dd91308d9fa6e0f7526b41fc9c6704532a653b9b42e5e94634d28b1bdb8dcfc627e5782754eeb49c2ad5dc4013385054a924b881db089a90672c386b8cb2868c4e20fd46e0e40f710a66106824db390f96c9f9358953923d9e13b22725f3a91428cefaf2b8fa929d95ef7747cd987bb31b38db665af5219ded189d51564542ca39d248cee37bfe48c791ce2315e6e1b45291ea8bce26fe5918a82807b3e7ff8041d797f36cf4079a1fe22c1af071e813f5329b3c9c4b37b468fa1cfd56a8938629da602df270cea4ce3c729f85b96945aa583aea3cb282a92c903d5eeabdedbd979f98023d707b2a6e4f917eeefb5cf7fdc61487c1b2ed3737fe56f02d526a86ec997b3e3d63b26a8caee6cb6098d5c99e55863d5bf8452057f34db0e767d9136a4f2e629dedf99c5791a4cefc9c299a22c5f6fcf91628569f8a64aeb9fde63c582e6da24e1e4eca654fba14c659f3e9cc79f03f8eca662676f3e992cfa7239d383634b469be3365cf033ac58abf89e59b41334916c6de2966e447328ac8cac67fb7ed3e12996d04ff055b98437cfb8ed0df6610c8c29c51b2a788b3985a8ae9a455fe10a775d3bf20dd860ce930eec08b69e8af02de2dd01e73ccaef4936e7ff6f0d07bbafdfc193567d307c8f4d1e56c247828e5061bbf9633b246eee654fd9c01458d6303c59f3efa3529545f8e5c6dafa596bd3d069f137b7b1c05d8dbdfe8607b379201c59c02b78de6dbecdbf87e6c3ccd097b1349d81b68e3e5a64988d8b06103c4913a1b48f372d31f9a772109119ab79686e6b7ef7aa0b5294d0992880d319c2158c1eefb8979cb9ff4ab88b3e55b210090b187b0fce9729e2b7fb65c30611b412a09d9b549ea95c8a46472a8294b6b194957a9d4cb4c29864bcf820553f5c019811f28394ad1b4ebcb3ae794b5f370669a5b3fda39f6c22581edfa72f7d8f291d81739b03d10891cb37fb0f162fdfca1f31cf13ef450a652a9542a053ee8396947322b985f4ad943aca037f39904afbef74368fdf29e013d1089f6168362b69e0732bf713232325aa60192c8e55effc63da765b4d6325afb8ef33eb1f380842593c88dbff1338f648ed95ab6f748e698a5ed3da62fa33f2d23da2da3c1f7d0f33c24f6c5d4b740f70f1dc0f172d71a8fe3fb99791792903003fe2469251909b9806078a145e4c7850f8c59420561948186983144665e49122233a0129abf910291d8f7b81f66de7e343640570e22336093999f81ed0cce7c3333df05e8ca312801a9e3afe399408b322684fd99b742ea27765063066ca222a264e66b804d32112599aee42b513203bab055d1e1081b6658220a23221f904e2f314a9a9eaa4843082292aee42ba9f14a667e03945503d47425df41155dc997719926ae8a2a3bdd25655df79a4384ae4fc2f431926082ac596bf7604a1d9f2931498d8273ed39b779f9dccd6bda8df69b767301674d28bac23f299eb3e6757c8e573d063c387edea0791b357ece6821431210c20824384f9680b3fee7a7e03c746aee19d1344d48065050380370c240700a7da0e6f1353cbea6be6351b4555b66c1026873b5dbf1dd3cfdb4ffeffbfafdf0f6ef979ffbee771ff7ded77dead3fa6bd4781a9ac7f1dd507d187c8e4ff53abe1cef9f8eaff9fc6d3eb96f7e884f580db6d9f1e1afde0778dffc64a2fff8e70ed0a6061473ed6abe9b9f3b87082d4ea809f5a263d9f8455762e3175d48083fb7e39b9b47cddb7cf58cf0f89aa73cbee639ef7688c0e36b7e88efa8f95a987bc7cfa8300e14f443fcc6774dfd0bc8953f940cc5d9b2e1f1edf8b2873b3ebb6d3e0fb4afc1afe39b613cc49fe3f39687f8559f0379881f83cf5d9f077988ffc6e79fdbf89cc88b3ed79fcb7cfec2ef7d0ef32b8e743fc792e44a1e8efff9927b53f61975721eed77fdaeee5aed27b5cd1e11623577affed683ec5aa767a4babbdb26772ffee4b328143c6d99a5cb95dde5685b6b6f68d1d803c1e737a3b0bfcf3c0cc63b34e7bc71536e5cbf9a9c358c71ee7276d0339d87136a688a21595a9ab131c638632fc8e59e833b7586fb09e53cf9797c267bccf846b0a0c433aa89640322d84c318de5f01d408420a58a27050900e931e29e160eb0852440f2e0dfbc6eeff0fb9187dc73dcbddeb4b7f7b6efb64f4db1b2e4bd8cf6a7d3fbd4adb53a6ded3ded53e3ce4fff62b132b494df6508b33508abe831d163a2c75a942ed5d73b897414a2ae1e3836236da21e1803c18c93e331ee7307e278453658d5caa55efcce73ca4459381ed3590d6d882a1ca03f81220d0a6f809906f428edab0ef41507e617f3c679de7beab74d6fdb96da5e664b6daa6ddb3ec8b66ddbb66ddb96e319d9ba6ddb64b6ef3aaf03c189e319d9c0143cc45ffe21ce851dfdb66f6e0dcc86e99c4c9db75c4dbed7a14a148baf9cbe90ee47a9481ff8c8431c16491dfcda4789fcc96555360633141415a39449f6d0ad514da323dd9af653fad071fac0afbd967a24323bf5be395013b2a54880edfd8e8cf7da93f1bcd17b21cec3bde7b3bd2780f43e88ece9def33ccf7bcff3641ef48c78329ee7698fcd3c967951bfcc8d5764060cad56eb094d4113aebce5091213bef6de7b2f045c509a26fbb95694ac3c011440464b3c26d65a6b9178f295041365021261804c482208ef689a1a3f4b96905ba8c0b0d87105587111490912ca4c7ea680090a98c8518a1f7cedbdf7de8b63df7befd52266b6efbd59b4e82c29a8416ef1824836114608cacb154ecc96f0e0f262975c5faacca62934686826f304370dc99e5cb9f7de19165f49a5a526ed01332f610d1dc0884571c117504d88dc1df67dfd65df961833049530c43873d7f5a2a8cac507345cd5015c185da24a45174552b80294305151f282285230a94c38456152b493f1c516638ccf10a22b99f3cf0d32dae414443023308808dab6018c600c125f9c44b0022074706d3238e9321be221bee00756748318980f485ca1a105dc1623c238d9a10902a8254304c929c080c26310e957d1146ce402261915d43003bef6de7baf962186f6bdf706cd24b0d8333a202bc5ce40492042a889097624c3740415453a218b714eb0b04e8860ad566b0a26da320a588bc849511dfaf071feef903bd18c4411bb4e6890c517638c3186a2096a639cc31014add2345adf5087cea801430e5880d1058a9f31c65011c20816dc07ec300baaa207275c15474f3efc4802821611484cbc10b1c5cf84c2618c1fba128ee0a18624ae1841144ae6932e320419618c711090af649091a021adea7e5250c49210c8926a80a24395a11b4034f9f071fea160cce42e859f31c61896e42b393239d905c062a110205c3c18e1258b2b58680f5d8af0ba94c0a5559a46eba5314362965c308c31660213b431eea1cb82461951b41f262e6ac03180382f78428b2d404c61e50b26921859c0822c323198145d2c90c08c20ca920ce30e328da32516482d58985c18635ce5c3c7f9b7415aba5cb10d6d0da0220811784d00e921a78d68cc9596eb0b580e38074b74022a122a87555e2b4843a9e80730309528f785289632e00a59138ca5d8bb64ee501c7c1e91341fe7c3c7f9af42450bed89b5d63e31f2957c6598465225fd183ee009d34e102fb90aa127202a85dd42d3b8269a2685144d4dbeb811205e55a986a46ee9873a8009d7bdf732f1d68e945454996d8cb355420b0d8c1d722ca850c2894b8a6108638c9d6839c00917187ff2f4848a1374618124c61833f9f0713ea84b0a0aa32219c688fa82a50c5c44654c92a6699af653e42b7964e50a16a5127e9670184230f1e104569c0cc1840c430a1745d65abb84155fc92b198b56522dbd91259ac29d2ad689fe9a74efbd5a64f0b2ef3dc2044a206901c58c9f228c83982c9a946c0892df5a6bc388f94acaa08a84316bb98a4009e12064c87eb44ad3688d6fd0966d015ddc34848238e8d1c245d40ba2a2c002862e36fc28a1699aa66521e42b4964f482212519c9624ceac249ebe2cb931fe20e5cc64c7162cc099e98627471e24a54f5408c28ad20664c5c60a96734a518d074efbdef23048d9a664ad012941d6ed0678c3176f94a0a11d9225b18fd1845c8b0a488a84b1337bc649210d22a4da3f505bf20995165a8082943d8862dc61a59b640810e5f77982e8b2f166ab55a31608c31aeb131c618bbb6dc2283d0c6d8b593c060a225017df83817e3ba25cb0d395ca37ad444ca3d62ce643269c8702706891d8b2fc618638c316e32c2cac6d80a4d0ba4705ca0c829622fbc6028081fc4bc8892b840c92243030e5aa4f03065054a44f105d7d02445152f0a0d5cb23c63a4186717bcc08698983fc6788c2669204dbc61fb846b63998d31187a581b20c62593f029484c1c146f26c5698b202fb27851a362c0d7de7bef55c0102d4dd3d2c3089a3811c2e8c7059806241f2a52102e269911cc7849914c235dc96cbb9c819dcc2636bc144394b404132a4ba4ac00cb11627cc1642597a525268c317e828bf6908d1248100514315aa0d81002a3218c5a60b92c1947284a10dba161009391d5b20570400206298a20818bc98aa19264c91353d3981fbe98155130b6502e387cf838ff4d59c420858849c489549c1882660b4b2d529c5ab70a30568c2a3b425b6a88a2822f4870c49319943c29f1a24a9221588b0a0e60ca408a61280bce0b4d0372460f49d0e0c44a165e10c153367e5db497e8a00417b2041e8ceebd178acc86dc321446b68778b652f45333a8035e18b5ec4d4fb49c8a1f2daec75c98e84ae6265aa569b4963286a6699a56e42b7964e50a16a5a5052cd19414dbf7feb8039a8062b2538788f94a0e21cb4340e921662a225a4f842bf42efb4ef184114245f98bcc842f505a0b0b70d0863e7c9c7f210fdf7bef76b7eb5234dd1054a150b282a12a6ff1c518638ca950a2b531c63570d1fd6895a6d11a1301652230553af8c08f1645428c71c4c513938c222b5eb884a317141c143f0049e1d2c36c630c055f7b535130ba925bbb4b2d8021480a1aed892c964cd932cbe2880722a2789112810a2334ae931ff287f7091a829aa2e81283c18910d5034baf2d34887105891db00c398c51daa116162be2e1c3c7f9bf181812a30727c0b852051522b7a6b12f0e44eec5185b0d4fa182102c696202511469e143154fb4cc10021aa6e4f0650fedc841e34806335e512ef8c20823820033b524b19480a21ec000d3da320b8356d1524516a9a0d1e28b855aad56138c31c63936c618e32d474c1be36cc7259a949d291cb64f348d8a29464f90f8ac598c313ec3e52b299489f403ce3052bd6be609eed2e2a29950303ea93c542e4442331d232ccab862044c284144858b0e2e4e8a1aa880e2046bb55a4fae6482b2e2c485c9101eea92a4699a06f395444a1a999c620f1843e62bb9c52049617297178a6820818c66354dd3b4fb9ab7354dd3b42366be922d971091d16d00122f8ac3fdd162888240f518638c957c2597624dbe9256ab2110415aa569b4c68106dc84039525fa6b0c3a1830851394fd7b31de72451a1bdf8dc128c4c4ec96518a14a37ad444886dcb134948f91d7c826af1c594a9d56a51c118638c319eb22d9bc288da188b2562d8b62d4cd0821ae38b26a204e1189ad208639bc64499819e41b110143f685439da4952e4840f3f28e170839527a6174c70d102a858abd58a6225153324410521021fa298587c31c61863df18638cb36c1ac18f56691a4d0375103e4041b1a40b204d9f08f239676cadcdf9adb5d6da28a85c42d4ace51222ca259061a47d9a267fce5a105cd62a1a560933d8943a672e64bc76cef96d9ca7dbf91f27eb336625a0d17a2c72b6399909d56ab5a4dc2bb534d1b4ef6c37b9768d2c6440fd7815a3195e4489bd60c51437c81dc408e386fb2f7b780e60c6921b6078418b491573563486071b3235b2e4a22b99996427185ba9513c11e48442b9f77eb7afdf7b6b2d4307269e68594195344a40e46229fb76a1b20315306b5dc539bfdbb8fe9481914559ed7b1cbff2c5108d0e3f186f50687124b3c86634bc38bf7d7db981bf2ffe8ca1f8e2858d9f461546c9c66fe3aca0c5a864cc184a7b9aa1a90100000000c3160000380c0a064442599ea6499cf5f614800e6596526c50369d86b224485214c510a3000000000000208800829073b4a3001789589a955a9b67b75d52f2f90cb9b4157bcdd2c16ce3e00a990a31292226c739bbbd9835c20adcc6afa81012339a8037382fdd96c7f08b065c974661e27fbe4b6b2600cee951ed6d1c1c96205aba8556c83643ff8511e10c604d7a368661f77c56de01b4617dc87331da1eb9a09829d58134a28a237f74e4ca32aae8855cf3505a7cdce072f6b98838a5d6a375f2bcd63d2c995f60756cdabdf3d30f62ae806482f2e47fd2d0745d633cb442a43114e0ec4bcc81e0860d4f474b978ff8c71f480d3364e88b3bd2e3bab5e32faf69da18b2cec5c44bcde9d49c5e95099b68a5a701e4e6baa1272bbd14fd1e7692dd4b3bc99b8fba5a9c3c8ef5ec7a01abc045be1013800ec5369816f763a72e882d5cfc32bef807ff526d70d39601b99b926465357582a9a4acccd80c1d7c0992d1a68bfeae692239d12300edae46f6ab7ca0bb8d1ee94cc9925dc131abc92cd9dec37e20944b2766e17a123882e69f99e7e34aec1c67275835854084012c2b051d2f3360ef867c98be957e8668364aea0a8a4054494ac64b56fa0f73e6a633ffda7d13a6344c142b028d257aab535d8cb8d4842da4457587a87159ef481344ed96963c519c67e13addafd15397b633a8a08a34b8f0ee2193806ba69aa9f7974550bfd34c867623b14251abaf7165845690ee8d4aafecc1a9c3d4cd2b5efef7c82a8e9adb37d6935613b7d97c1ec4c8d7f0a486aca200fb12e3a03bdf243d0cdf6b57e274dfbed096f8dcbef9150e58292f0d7dbc28fd5854239db3400c10d241b4e16e47881bf28b7815201a36e38c706f89ee09557e7df2edca497860a1da903fe008c478d59a620c59a6ba01f05cdb7e18c0433643bd3feed737260631c9e07d006b5bf63808adbc7b45b7ef99aa0e5083a693e85183120e430db11e3e40907ea4618c467097b8074336ebf41d69d1874b8927312a54df0b10ad126090f2f62175a70ecad31d6ac2c30535e3e16a8ddc8948978012eaa875417b41318f703dd749607b67573e026a9e06665b282c4fcf8e299fcdc5c45993af3108d9f7046db141719d84240fcfdd6f09f3a1a9efe7603bb0744354e9c20019d4e9f5e7bbd596b9fc885e9e5e36f9fc8a9ab77be6c6a20d05a692df0b1253154b6dd6d245696b2afc72accb89cbd07d6ff1f4797a35be9f69ef5debc61b848a4c37341738aa729631219d35f0b839edb3b0d2e07523ea99bcfbd208cffd0ea2b9bbc9596451aa0dfebd42dc888495b4cf1db9a9ad6a0e38963ac28bc74e88861bd68a7ff8fdefaa4de013b5af3d5f2a02ba7e43255b2022065fa05515dbfce106f54db4f28bb7552e39881a4cd65865cf8fb0c5a1b38338633248e159842ba32e12268214f8a898b87fe3865ee5ce60ae80503f560080caf3abfc94ba346cc56d73435b2a66abcc7a44d1a1cead361b9838097d26b0ae0d8c8740f7ee85655c34356d631faccad21663422484ed4a4f5fde07582a2273f61178228dcaaca68055963f8e756ca37296d4b64cd06f6f05d172a7ed8de872a3081d11de94aa91798c980f1db1d6cada53246d0cfb194a6f62a0241bc0ed903f193288c7ca587c734b5be99d57619649cbe0f4c3333ece7b34b58c9b4e27f03f5b974ab95e9c89218d10b1ec4939bd4884953396d851d368ddfb7f13f340bf227dfd1741bb8fe5af4f3ff34e5bc49884ab6eabc5254af84399184029c3e5f463426b2c7c695e5542f3876a1597d79e0ffdff15a0a423cfd07b6eaa2756eb4bff2e7696b6fcd01092b9f5ecfa9e43cfed87ea1b0cacaf0b63910f719b5b5424e60ef026281698ffadf90c95bd336d7509676ee0250887152e543fdf4d0ce9b2835c2d8cd087e5b6e6f6c4aec81e1da1d356a58ede46d3f906226a0e856db6ae22c73f686e3f4bef09d476619aa291edf112a6db9eee92f22dd96cbfd36e35c315f161f0b46d324b0f879bcf98adfd8eafdeedccf22c164249ad8ac917983e181f9f3915ee441bfb6ad680c9b45468589bec364fc56c0eba51a864602bb0cc7161784c4224ae9089b7914eac4ac63d78e58190f1d462b80638e0bda7f4b5021af785c2d7805526776e6f60c979ce3d52ab4432dd815e35e4a0c4f94a25c16741d6911b6896fa3168042e74e8193560fbee3803a5716ef90d40c94fa423e994f9704d4563e9c484af9c5410bd89c4d94e3b1fb3f4e0493d562533e9b8a33f7032a42b646c56afb7b85d5e98267d4435a07e53b1f84a77321bca95925b94017437c005b39a486aa3415ab3194553288c478e017678604c213751d05da19359bc4f7ace368bbda50b60392e5b505e63b35aa39bd0d7fb811f2ee6a0c232cabdff2f178969e5c7fb3bcc63d0a5266cc2af47b925b1fb997088f34e21bfdd7ad8fbe7c0d518a52d68a54158b8e57d8d853c9d7b41062a71f60a10af8796db6cf4f0a7be6c8f36d4c199cdead3c01f747b2f2b830947dd087a8940e63b820f4ce65f5fc8b2e2d0bee4bdf30ab550cee9425a937136018405d5ff245d7ad8c077f4018cddfffab03b49e78750b570a49f50eafc38f9a12d526bcc88b46059a4c234ad28fdc13291b2e6cc106f6b4f5aaab4a50201a6842fb2bb6ded57dd6ee06b5567a8dcec04917816a71c1be608e44bc836ebe3958ce016c3f9857777952765a778f18874585ff4b64e6cd430e319939db0887f30c11ff5528158b08e1792ea4cca196046a792fddd925973b6012e7c3441355007fdabc21890579fc706e18737901ff960b62c22d05b65ccaba1d3d969ead8a4af0cb4bf12d6815562c66d6f3e13f2c54fb4b6ed0eb74c3e5a099abf3f3833b79d176563c9530bb040f2cc04db2c351e6f998d0e69b4396c79639d498a5b2dd351e306d8dc62280b9547fb6615e3cd399f5be9f2f5b9f7dacaa9699a7068a0361a48466a4c4cb17476da2f5f47ea44a089e4849c94e3d0d3597d7afce5193179f4ebbbb45296fb3e1e059b747c7340866b8e310673e1d5fb4ba63b2911115dbfdc595574b2fe99dd5e26680acdceb8e799a95c836ab0d95ad4b2b908c03427d96985045c49a4cab93d0f609765b4210d4aac2933e935c8d6fdefbff8a8f753c03b457ea60173cf748bafc448e1b4ebc7fd64d839dd7e7d5143dd05c1b32ee9e004b6c6aa99d00dab977667a1bbfb1ea856257b7c49ebf00824f1aaaabdf5c31433ff30f503f9635521c3bb9f506bac5431512b0520d378e0aaf4d90fd8022f72d806b13fb283189e59191a3e6c091c75543cd6cc87466b42842c45c1c1e8d0e71e93536a3fdb4d1b8b998dba6df603ce243cf117eeb6817d587d830e262b6721cd541856c8a0347fd4edc940436c308b33634fb4e99ac15d2d5f6931fd3c1c26026f0389838850355c373e04e41188ef2f9f49cbb6951ebca41ed52f8cccb902750158c937424795facc0867281b3268eea29f3f3addad0ebbc8840512141a9eeead73452003ab6759f4d68225221076ec90ec1668c69650907f7fd8ee3af136ebf9e2b6681b7dc42191c1b33dc6e669eaff2a3ed0897a3808ae34541d35f771594ed5b8ee6fb618a21cd6c3ea4006d6783b9f9a58fe76802bc45df94f7f5b16767e193a3a9af43cd6f0968d75e8a554bc605cb00399ff6365158bfead1b489b280ebcd5ed20869684e1de3128354aea070461f9c7c2c9634ce70001e97bce1f355eaf9948ac0330701751cbe76efb18859098b1b79ed39d974a016a58dde34f0e0c39ddf12b8ecbf8d7b40d7697e1a5424b94d7f062f46e184889e7d4be6b0fcf064bceb37c45909a679d3826a0cb8936ac8b26a0e45bfb0a4d22689f3ba237fdc72e41bfa32b6346ee399f6e9bc1350b6a9ab827f80fd3cb6f2004a13f6e02d567ced5c13344306bbdc43686c24447436d390603ebdac40a0a44c8f375e1f30a5d02be287f97b02fddc2aaf64b879c398ed31eac6f900ba8ab2528816cc480fb4799602d3fdd8caad6684898ecd63211cbee13733b51ce5fa9c21b97bcbf4ab59b7497cc855e666d904deab169136a81c1b34a455218a8a74388eaa106eb05050d23cd599c0b1b91e4e39464527a120f8fe91a612f693794c90321131a6bd42e4f0c08955e7f4d9a2db9112b83faa8317cd39fac2cb94910b282f74cb23dce4143925841abad3ca5f1dfc098e2165c3b5abd46d07339e8b1737cd4f7ab84d3250058e04982db947a6231d2ba7698b342020aac7fae284ddbffd43d9e816a87a3de6dcd0aff6ce0db0546392b5fa8b0e9542b6e5fd3c944ef5eb794f6aaa5a3589b13d059de1d2c71b6ac6cf0c0c5d72449d795f81883f62dd32c97bd8ee704a7d4367a014b589bed95bab6110b91a8cf39d23635d994c7c8780437ffbd4de259f678358f3e0e2738adeb753e3396dafd4ae5a3b16f2f30894027dff081cbe640300bf93240ec925b0bf86a6efac326311762adb8167f316cc358293a39821bfe952bbd81b4b6c2dbb51619cd0d6106261c7323a41ca0dd5667c1d9c7f535caab2da27f06787de384f4ecfba96b6fdf15f4ab0e08eac7fa3f6cc713b323c7361bac2e96280bec301cea58518c880e4db1cb61e9ab1488abf04ca7c0920c8aa3bd7984ce1587e6660f2b0dfa42bb0c5fb48eb78037d22bf0aece3dbd3f15c8e073605e04e427f4de09dea961ea93b2a98966c2607436d0a554619bc09bd9de262669ced06e1a2b0cc061ee782dd2e0f851c74df6467246127020c73703a1ea980fef963cbb9048867fd464892f49cec9a1f5ff783117af870030c73c4c37f5d99daae862c3cfa322734c74e760c8ee0c65b4ea7fa5e74934166754317c63ea0746c6d434b585eebf15dc4697ed53f178dbdc65a672853f4a6ac12e7745b94e53429f3bfae444d989a450304f4a46ebc9c491fe7c812dd6c941342b3196dc54fdcc9385e2939da9fd842a90cdd0fbd9348eece2503f9592ab468a8f864f6d41ef735e0380ac00e84e11d9ffc7ccbb16b35a83b6cf030a042873c97dea4a22394a1ea657ccff9d20b2515e133c75741df6091256d2c206b8510ac14ede483a066513e26213128eb84d4a4ca4d9442134063bdfeb22e64e774ed8f77b9be1d70e9bf37454037eeb53ad91c6bc1df58342348ce0ded737d76df5a3976edf231b2df75e38dd26e397f2634bd9acec8cad7dfdb84fe4ba971430111f13619fcc9344e55fcd7619dcfb4b427a1da24e10cab86da1785560eb19d8fee95ea9766f3e71c0b87c4b20ecc1f8e572973cb560d5d3920b951670218f17694b82b30506aa73890abcc8b7300384bf6b258932d1f9205c1494e44d981b7922db02a1742397cd3d8f66379bca28a990a2f9e387fb25e16daebe96fed5a79e729851c9eec0ddb79f4b673b6a9f4ad2239a17ffb39897185b4c266d39778f7bfd4d4ca694d5c2c3b4fc2dad44465aea4297525e633446c6a57e5f781983ee1021776ae690926950c4d6095ab7620b78ebc894d4f8a1339f109a79956ea64caa05acfddfd52c5b2af1488ecdcb0b9982297219c97846e9c14f7c6b2d561059da05febffc313935ab09b6e3d3e6fa69bfd06cb36ca4add2df7e66cd8d5bcb0a6f1801d39b5eae9b1bb218558193518f763a38c698a702df231f8ead8bc9d6ac55cb495488b18386c6ae39b58433ab9114de31ff5d1f4b7a727aa9979e19c75de1cd68f2e01e3e4f3f3fcc104e5361fb654c0c2c0aae4c202f308f370da17e580750c075e1c2cbcaf86101a7eeb99380aca3a15c0465b9375b20b912bf46c4ce9dc691f34cb057d28f458be7b3b25956b8b0669d234d2497ed1122ec3cb84aca600a4111ddd0d13073647b901ffa5becb4a8e354435a900668c127176ca3d40301cfbef411a268e7218f7cf23e50af1e0e4e3a2b2c323d3a4312265cae7a124d426a09dfc6099eb50a25099703c7da69b261dea18cbb6455e2a6cb76d283ddaab5328afa244588b52ad98df7ae3200e1558b00b1cc95fe3fd5ea8b94ac8b1f98ddc17581c780394bd45db415e705914c22efecce660f107bdb2ddbe618168781ddd0142890026c3ce6f55278c0c5911d3e6f9a371e5332f3c5d8c707217a9529d742266b51f8cf069f3471b78feb66cd8cd56ad1e78a873e44ebacae533e0ebbdd7e118d785a67286133ca6023264953a19ad6a215bb961b7b1350058e43a35e6b22619893a16e45c8e0575ecc3cdc1aff031900e37c9b8fca8b1265fe15bddfdeaca365ace8cf540189f30de1ac62cf4688007a52a0ca3199eb76b6180ec718053d6cf00b116c20b9203de1ad8cec04d0b8dffd63b28aa32f945bf6703b0140272cf50939a40f93d342d2cf143c3c1d38d573d0599cf963fafafbe1672d7587ab6cd9b7ee641f038dd12cb9b93f94cf7541290d1ddb0258159ec7105697facfea65202212d3f4c6549731712c6186ddd32888562aae5a3aabc151fdb64ca73b84b9180b1a753e9da5ae2eec31adc1440d814ac76b75d0510f7251a633234d0801f812dfb00b73bf1608c6471e0a127edb5fd6cc403d0c30cccb13f2a7918a6428428e11f40c90b3bd7121d717a5032e5791c714fa966e258c99c8c529489ff5606aa729cbd7f865836680a8edcd0ff887766e65ebaf81f215009b466ca1295afd3626468d7bddff5af49e8840da54e7901691308b91e6619afbac60f621595c6c7ac3ec7ddb00343c1e4824653b9c6aab38b30c052236b0a39910517957c391bc801fbbd8505b9294fc0c9682c53537112b056537dbf7bf2e6d752d349a679f0a021585863183dc88d5f02faed84cfeeda1fcbbe2899e2cb38098b5d815d408bb03d3b8b5a6052841f0eac59b9914e783ad42ca8577caed35c3eb485be09b41c43d08fe53acc92b763a1fed1f8a453de2556860c3b521adf769252364068ed6b730789fa7a0a66fdc475a61e1a93c0b8046e4b6bd11aa54726faa50ad02f00936eea76063a81c2a22e2350dea6d6d595fa30916d7f1e80ab7fe82c21336cbc289e3c5e08a6c3f2e0d7426ab58e2b6b953040a60bd8376710b639f5408dcbcdd1ecdb3501a3564ff3beee3a5d7ba0a6758bca2dc81231e0233217306e6283071a93875903b49955ecead296480b233d18fd9e90dc1c06dc621c1e1e37c8f6d7bea717f5a48cebeec09a7cf974ad3eebdf259f9731ffcfc732855afe4217b9190d7473185ec11bcb2e56a42cf4d57932b7a5fbe4fe0900e4e1c0afd7ddd3886e4564d801d9bc023ac63181ee9f913a0c6e013c317474340e8fce98d6e10837a197e636f782fed760c1d21bcbc473f8a18e12243a15aa9bc69124080c97095f74544a121e55fcf38c4de25e97d7f9ac047f3927910d770dcf00d0df614e5d3aa0537dc4b695525805eb702025228c0cadd5f7bec55e0aa4b6b64d4ab14c6e41ed9771f07b6fa135764ab2585988bcee7ff00f6d4451ff7f4ea4578244f5a848d496cd4ee1dc9d14d4b6109be34551b7d781d92058c43b8f700ce53611df569fcc1f615479b6b31dac4a62899897dbd3d066095a32aefaea928bbd9ba5e367406dd8359b9ed0c1a8c15ace934c229b0e8f0281671b316184261549211124506650e851c03036b1ea8c858c428de10ae205115a1cee0a593d4e37ef14eef1582caf7a8a96c52291772ba28a51b5df6ed897527aa45ee514a6641fd3afeb29a390247d9ff9a3b79599ec9b38301b50ca505f8e5bc9db5a69397e36a663db6524bfe555e9ee726bffce6352a8877ee90a17ed44da4f4028892ddb5b9ac9073635a79c7a04a62ba8d3a196654e07ee37fecd2d94a4bcc10c81923b420d8bb30aa0cab28f384d2e4433214219d123c72474c1e8cf8203d9ae303a22a5d0c7c8a29cccd9e357e8711dce9d01628d59a5f1019a24c518c02865ae754996d5877c66ee5b9b8128314485706ce39a8a59f62198088ff674c9db5304feadefddc6a53ff5753855e1743124bae4215dc1df5786896e80330cd8205ba3921a1f7800b16049dd546ba937b7b1b06e0d92f4e496c2e5cfe16eb2de57032cdaa0c92840d04e98c5c58a05821d4d29b6370000bc76c7bc9a303d4aa336b6798b0dd11480d6916f8c164502c38a598bec0a4560a6b7ed4dd5fe37343951320dced3e2af9c44665ab358d9dd4466d9abc90e06b32119e3ef818a82536be931c2c1bee502b4ec8d0293c78c5e78707d370b2495f52c60149a5de65c05897e1db3aa52fae888a47bea337539644803957c5ecc7969473270fe7ca7022678b75e6447e7753b296166e8c0c0288aa5dcbae9718ef1003f5b850bc0e09af26ace3b98d6c94e5e6c3b31724f87091d8f9ff2d1892afdcf6f28f44b0a4fb1cb96e8f9671c840c20a00eabf249c1b2e4719f03d3ff9216616e617eee4eeea27dad466666b181fbd87a26a0b9acfb943b803a80ca30125506721cabfe288e8defa16688228a8e977273afbeb419d400ce206614c5052b257976b522809d31aad04771a44ef1235c3eb4022135ba7393fb944ee74f767f899b392605a93a7b2c1d6ed32ab85699afa22194e6c840b680acd09170a72357f7716cd9ea73dfe565a6146de9384834c24d60a176df7ff0e7b1fd2a2d7272a7bbb47936f108cf377e0c157eb8ae1a27278d613ae701dca901e1a567bbf152845744d0c5df4e370013e3dff3c91aa8d91088d25a3adff19d341e0423d33117bacd8ac2d3b7c5ec8576c8e6008227ca1bc9c645bfb190970d69b54b11993041dfefeaaba69ef6f988e71f4512502626b07201d364c84d56c90fc3f619a9b24b00f2d19eef175fb6c7c9db3703019e000c10c5ea0be93c3699fc5b94a283ba89e13f2b5a8afb2a3af5853d5070ffe843a1e9caabd8f2e3509da9316711ce0d398dcc19c3ad271ad5cc3475b5c11107f739ef604550391d957d662fe4a50e34726a73fbe47120a1e247b545e8def59e39976046985750e79abf9b4c5477cd508286e1011c309539850ba6c9520bc109b265b6302a0b170a0bc35f4f59ac0244cd82370abafd888d4ec14f56e502d53ef24c03f30793c010daaada864dc5aa204bd4a30b7b243ff1152533a945bc4836f89cf813e10fef31c07b5b7d0dacd43ccbea61880c8bc35c5f0b4f5e59630a8f1aeb822febd9320285119d72f15ffbaeb11a4324331e2ce0a9347af1e9101209f680e00fabaa0b4645a4e04ceab5e373e54acaff45d57717d929c69cc0c14fa55abbbe0312b563e829e464aaf3d6635ca1cd3b2d2de4a39e79efe3f55b847fd947c36a13447afd162213f1edc32e61caed08ba90a20b5e6da074b74a2621a0eb29e6541db16ab48534b772cad16738898bdfd3e842b890a6369c79b399f730a6507b4087d1c5eaffa76078fa59623b9aa813db321c290032deab6718561743f2eeb1853ed0315344a00ab4a423c8cecd8d146b1535ed25c0a9ac2d15cc31142e7ed4cb4151a6dee7a89c36cdc3dda901a771b5d23654f2fb767d2819d72d20c37795e493fbef4f9add9c6aaaf9103a6c179633a0c10d7b176b265ad039a53e0e4cc37057a2aec74f6061e2b3ec963f18aa9b0c74327c9c80a1afbf5cc133c2e890ade8ec574fe1001752d77b49e83ae1982e88f0516961b742e0d5044a4aa62db5eee43b47da06be9839efbb397d0bdd8a174e4ddd364e5a42d54b15dab354199c7058f06817686f30a907385fbb0ae55d72e44564ae994bf3d9782d1483d2180633772d4bc2d742488b5eaaa7fba0027c3460ad5b487be964988395d633cc33a7f3f94eeefb22db89413618f0502b875abe51a563b8950aefb3f57c4bd270ef316d762b7d7ab329e93a19a5dfd506ec63d200ae5a63d6e02d985611481c64ba2613238deddfe28f1eb0b2956934395b06c5a61c1bdfeb857736a3fefab01756d581a4cd30b136f763f6cdf2569456f4e04439f20fe90c1485031132a9552fcad82a3899445923a5edee0307867e96ec2e7541d3b5897b0de141b01703a312e0c2a543d9e50df7434fde4857117dd54a436845d57a7ead81f89e54ed113903277db3bdc2a233deda93ad255f118748b2ff4c9b8e190aeec224a0b0ec9c8e3aca01beca1f3435584fcb9dc421c808410f17601c3c4622cc40e481dcbedd3a18f464794159791bfd98168fcf5e7c9a2fe2a88cd955f853d0a690e4b53095c1b83fe1f72d918431b218f9f94f900bc624bf65f6e2a5180f95bc259802aabbf352c83a2a2cf586b3d4cd2a5282cbc2c96aa5f402954d7db7224c611a442429c39d33b0b6c4f57f077afb388b46d666d8a9290cddf9df890856b65c71ef967e03d316ba7301edeb98276a745b202e45e1eecc6ca12e68804626431a4de55328eae00dc317887a8d28a234beb74a7cd19650fd06da3ae4d006c0e850f09eec6d2d5549e46f0180a21e6ce0c8d997e327787723caf2e3e346b23a9d309f0f16e370ff47e43580429d0888ba247ea44a034f1a7a9588982170130c0c03edc250f928f669734fb7c1e90bebab943662ee26c2344357632e7aacd0cfa5d47c512edbdfb70cdd173aac1e70427c81f74970889e79110b91d80c3d6440f49bae8b98afa20a27ca8fefa46baa837ff42a94f952f15342798e8ff3f9fc773899dc29a00336144d71bf7854ba10142ee4060303af38e77a3e5d3b0832ee792228e2c707b03edb572382678c336979426834a5d1b55298f91296e9cdec3e6cefecd6c0f43d9308b54ab9c5719fc0d9062eca721844d4f6eb6fea7e959d720a06d48100c4620a3274615178b1b4a4d7b53d713f0139b51a02cb46c1488b587051cbcd70cad1674047382e9234828ff8b460d5e15e194498abe6e51143f6516eb11859e6c8e8e8dbee3c976ec28e408d81c9a5d390a75e5a5e2b06fbfee77d4d380ece5015ff9e0d4b9154d3160f627fe2bd847fd1298ec42eefb6d029e91cd7f2060f08270a56b6c04bcac807ea68e3537b2c4d0f1d4ae41d0370089554c840b586e59cadc9594dfe893119d0acaf1bfc1f65b83392ccdf8f1b847644c04b4d6ad7fd5d4ce17989dac28253b6e2f3232883f2d8ccc30581a68a5c21c1b10bb1c93a8936a55fbea790fb8aa7a1b8a5f31c1e39e040d2c5b457b67c3bf7e4870f4677f4a19c58fdd3a6c82da9929b4ad5484d34d8219db0c9a4cbf5a606232c40a137fb50e0c2c85488b1430c5b39f72674c12276e356a270cdfbec9fa705fa874653a611ed8e245c7ccf69f9d1454faa1c3dd1d6a94397de4c79d2f0902f3a5262a16274edffcc87b631b3948cd4cc2947542cae2104d86ac5f896115c782a00ee4a89177da304ea6ee50ba0aad21c80c5c34f787ca23e1003fba884d2625b3a4bee767a0f10b2747ca10dc81777d797312079718ec227476d6550449152b3daa840d252f6f5b10e82f25bc9c17ed61e1bce605eb46ce8758abe9f0dd3911b66b212f1390d0506d2c11857bab27525b5272a5a4b95a0357ae5f0d2c4a8350b2e8042d740519fbc09de395c010ee6b4e22755e694ad5df71b09b033b765aa3b22d527eecec48cfb47e39097770a09141e36e45d12736344e32ad630361134448d3b126e990337d485f2279f0fca461c0fad128f530fc15f8b923ce006407785fdfe2a06d5f4194e016d6f3c57cd5ac661ec10a9a6a8f7ed9f69272d136376b182fdf60abc24f497116f4d572a1b636f9eb7e026ef184484e35a07eab254173a83fbe147312c6106a646d9ece9d448e440045e1def6f90b74466721029b409240a849e98ae9646342e3ad809641e74ff6c92eab02023255043d1f0e0e67168acb766272c1506bc14e2164b4ca7101ca09d33b6c3361ce6c2592526bd50990ee93235853096f573040e6daa11fe543f02558e453fee17af8c669890778e7b2c887b3ca9af3f419347050bdd07088063703ba12c100239ed2e9d56c1ee7d00a832a0b5713e5c0f2f45fd227757aafdd15938fde3bc5b417880b7e49c89eeb35a46a68d94468f7249077eb55d1b9a39db78d86de774aed3e3e7b574e61363daffb5bbfcc7dbb1f049b3aa9e1949dd566bf9d31c9ebfecf8b1c2fd5a66253f62d554c874cddf04a4e879f30f0428b6b9990b36d68f1314dbf3d1070c1ea71745330e60fbeb19ce7f9583de72b7cbb76d79b00991072505162a4c4eb6d70444ca030b88416de653057f9f1c6e1df800e13ef3d456c6ce9eaf825faaad51d7031f2a06f51d23f475e89a6621ed9c2d6a9c38998ac10d1fe344e90a106e41843d1176883a62d35dd119102fc7428eb9baccfe4a786dc0364c5920501a97e176d7316969f876f6739c4cbfab26e1251cf021cb1dc48bfaebc7c2a1661e27221c05315d1f41220f8c2835dd4bcc4b78567bea10c8ba4090021bc650db5232ac295337e7d40d43896e5d733f5fd8d95117c707a8d5c662681f4f3bb9bfc143d06a2d248108fef9506536d4cd3980881ca12035c8604f2f32161027ce85c4f7507f0873e2e7ae53bef9467828504d4e3675b22909502c79bc87394d48cb7bb209d60dfa89234ebd8eb3772631f80f01c85790db234ef58808313f398ae307c6f045a3f1ebab74bc9d09339e7770b569e744937bc2763cc4d6636d3bc682573ef2b996d96fd699dc7cda1c7c6ee590c6366666636cca774c5156e6813420e5816906a7a41701fa0dca1419b42d543b2695d649ff95f67ba61807f370200635939b47dd3c23f4ce54b1e5c2e155e9496418e240f31c7b2462efbb7579e897432e4a1664e357374a246216ab4426f97827616306dff2c7153692b3a8f433e40dd47ac317836e98ab48158b0daf241273c5b1998eff9c2728ba6575a8de0d4e5506ed77fa35c0cb61e4f899c3888eb247b615ef28ad104820a97474f8d5b2c430c2560f68b9e27b8411fe0fb85496d3c5b508c7828d3c3a536412607372ee4ff630671c31047b250640e72ed825d012aacabc7950998774a54156f78dafe42781fb9a8ba666fb8c4ae8a4f6de0e43508321dbb0e0a243669528246c8cfe34f41c9e1f11295c46ed444e1825b8a076b0ef8376b6d321ae0bae95d83ee51f95336304fe008fd93f82b58b36cbd5f822dff0c78d63cf1eb2d40e9d4aa7f365aa688f6072bb28f2643fa25816012b3d328a1f24e638e4c016f43e31856744d88586d60ab2c6072f897fdc64f9f3bb1850bf400f4a378dc6bc46833dc661b1e586a0a869c826b54d5dfb1d7c2c9f2a21bdc44792ae0dbfd8ac8095f69b919d4f58060a2e88f988ab14871c0cd63f0efd42403d717cdac51f26443a69e1933386744ec296d79562831dddbcfa541b5726ce8eb1b64cf3ad9b35cce735e90ee36865fd75c97e4abe6aec350fd9e043835ab4b026857d392d8b09cb41d5a4cc9a35346f52abd1d989a9bb0d62829e6cc4ae43ad77095de51a73fdb46afae55203c86bc182cf1e1f22981e93851ee4e88e1b9a7ca2ca8d1faf6a9576bf6547b6e63d40f188b1c52c48ac51d7c215ba3fc77c5070790c41a409a2541979493c9320b851a44767df89a11912e661a85acc95f226283ae522b6ae63592fb868b6b74a622d80e80e96d4d9663eb78ed2a40b2d824a4acd9540db9a81c3831b0a06aaef679994d5f2e10c4d71264b7d41e3d9c67035789034f91c479d5410df09ac25deab0238987124a67770e26ce4a54e42352334fb10c9ccf3a7d0b00c34f3a2e75fcf1e00e52678fc3210c6228fb8e510a0318075a6c0082fa8b8ce72ed2a54fd8904734f199c77ec18d217a34d1a225c2e8c682a60599f0aa0af2649974306992da04e251559a4e7382f1fd3d8a4ac6370e46c20abaf6099d2d84016e9f2e7ad6b5cff332fbf7abeed81798cfefdf44f2cc700e6f62ccd5a2006922ff8461dd0d892630f3709aae03f3b36daa95e53b4b196ceb21ad33f81ef200c2e57b83664e44279bc9f4fdfeb5e6fc92f408298ebfc144551ef4304019ba7b583111f9c30ec66082de8bc081b90ac28d273857f285e61aa311ee13b676c4961a28d3f102b41be004d188ebbd6ff37feafa90bec272ceb2e1ec33a0099770c744416d9e5341c1ccfc1a588b6a8ed54fa65e78466ec6995df8db07a0d1e44a801adf1a85fb14b19d30befa0cd0bda14357ce81536c29445604f3775831e43504717de0ae52972832c8820d74611b1a2bf0ea6483dcad463f2d0adb56d6a45b6c4281e32c715e9709edbfa7089629dc2dcf70b4949632ef32dd77f1245a60c9c48b161fad4c855ede1c7ac0604324da651c362a776bde28fabcdbd30c5108855420f776d40b10c9d5dae25c1ba3889f8cdcd54dac626df8064bdf56e765519d82faf2bd9124f804a58b2fb0fec80bda3bc0ec798848dae2621a1339a1bc2802a628f5259cf00ac225f6ab086b6786278532562970502f380d49b3954da170581d96b3bd1f79d34afe3886eb49d9ff2287f1b5f94691089d46fa9587799e8718ee1789515ea918f42f8b11bbed6a10451ebda1d12be87cc40b3582971c9596df7827b1a32fd45f3d479967ddc34d3370f8e12b0c43f5e6d49a87b2596c20a6f47a4612bee31ac43da2f96ec073ac1da3bc56b731fd774d3f822008ed3969df670b48d7223108c3451d193ff1dfc9de0cb000642a8f188b5550118ea17c95b21f68507e705d6d125a078929fbccef65f63d16e3516e1cbc4e80aa894dd00c2afd388199ab9de1d1e7352d889c8b6d3a637453d0ed844ee3a01ba52fa16a147783217a2029cbe4680d14fa0b5ed0d8058073c18ae9851a603d9fd02b8912ccee92526e75f0c42d89309de25c7a3dcf6c3801de6550e908c58537a9e41864310661c61e94672375efcee09389dcdc5f66717c86c744ee8d50940f54c85f2fc9a8ee2824d22b362c507ca4e9b7dbaeb0c80864c58a0d3358310b769153eb580d47913127db0287d75c1e84dda7f1e8adb3c457e010231e23be631a2b806724ca20ed9581920fd857b32ecaeb0a1006774e1816b983bbb29cd0351c6d1373aa10e8923ae9fc94ed108a52fabc4b0c5f1544c59c2e0d4447e50e5db7d8d07024d204d597e0e7ff9a4fc7a9e5b64c171939c21005819fd344ed80529addbcd97083213b8783a0d35328a51954c085bd1fb7416e21e4ec2218a2423634bdcd969cf5a593beb36ce4cb7b0354c6c42d0e4a870332fb0a4b6da29f5fc4bb5ff2a6c355ba6825addfeb60bc0c287e97e6c951cb19be1371a419e5bac0b9bfc3f28690afc62aefd0e9f18b04dfad528291efee35fb8b4c66fb9bf954b9118f2ce1e1276385855ae0a2267e9f8e665b2c6cee23a5d7b4b9a7d82409c1b1cd2fb1af8f0ca03442e0761c8f4e3ea25e86a46174ee1ebbe84613534f50e4e1ad2b01645d9122082cf84d589198c717c228fff447c95be7b5e558a85e52a2e94c55eea20ead7fb64e565d32b50b7c110bf4b8505bc2f1e07d76b363472db05391359fb902cb97dc265c6cd52727704e6134297bcd346f58d4218dda55f9da213796d347867a569c5105a40ec6f7ccf046aee230a361082874e115264bc25a270cfde7a198052a3c24a6e8e4f40cdfa66e9cc0abc9410fe492b4cf60af66437d5897896d8e5592e86cfc651ba058f8c87d90d4cbf6270f1e46aeeb1c4a3e77847b169b27c339a87b91d66507156f3e87a6331ad5e4e22bc89e3b6416739dff4813680a8d0fd9bf9ff9b52191dd985754f271d4cd9f21becb512408d8531304d380c80da54ab02291326d27c6defc6aa9ed1cbdc51c05cce30238fe112e2f3cc326877d6aeb472b3bea01b9909edf4fc2c16a54d9bde746590652bc643185dc07f3f15347bb2acda8dfe1cae8b9c914d4a3c8e767840c7ffbf0381df9c55ede8ab9298aa18428d5feb46410f388b846ab63da3c946309471f5b0a982686a5988502d6e8f1dc74c08e7ff1bd320bb46e1780776109c2208eb1417dffb95a487597740497726180bbda7dbb831979ea8a51b44d70800022a8b4223fc942327e7c5754739388a7f76d4c397805dd72887c8738756ad7ee74939376a8d49d7cacf858bf0a08a5aa64ca0caf348114b309066c67a6868255465d31554efb2bc42748dd9e69484573a032d9a0c880a90e3e12ad2dcef8ad970d8b04e3eb8bd48e347a658a892c73dca1c9748488ad029173fb7d58b753ba7dc33005f4e8d3e5f3e9e442da81be733bebc9733b95d55ece240f71e891c79a64bb23a8647f0778a845858ff85ea61aa4a926cd5bbbb9d924e76017843c0e35186f0aeb8ae12098c4caf06b2a5331d83006b47d39f6bb84f5add049e7b46c744ead670ffd58a2ccf22a618671783c387bb810662f1957d4e079e2de68f1c421a6ee779019008a2e39814b144a6578d579e121819799201ae4679499b01213c686037a6c28c35d5a1b686f1a623c89191a19358ec71bef62f6a04c4fb52b9e1399aeca00d993a5677e3d460200cc2372ef0dfb911543e44165453f1f23f6b787dd77772c9734a80443aee6a300da711e271c9d70960df3ba5f5817321da3d434d6c1313365f709340946ebd6b458a061b6eb73eb91459b00ffdc300bcbca89a16068d22d3e910624543c395fa9b28416518f4acb060ecf8cda51427c5f15b8a63f1c0262cee1e8a7ed95d7264b5f43170ada9ef062fa6a3f3bbe428ac9b42bab5bb8c6fdff66310611422fb262f6c5e1c9bea9a2b3a45c6b1dd8ebaab36ccca1a99d75f82fe1d1bce7c1c283ccc3db84842ccaa34245d895d7f67fb379cfd6613226ee557a368cd37974f8eed68e8be29321ec737d5b524c1e73a25f64f1589679b2ad1318d6dd2d825d27e5abf1dfb89b8587bc288d5015315f5a54e28041e73749d522a92db017d75e1475979b91da947d821b21723f3db9295671fae647e0309611ebea3620bb31d7f0aebd4655df43ac39515daa521dc14f926a59a5177e338b6f2a38a4459581af11b73f58b9cb2e7b05797343ed813bab7d56b4576d41f3bde6e27f6b9ebcbad079f650b66dda0518f4b2c86db180d81e8b5eaac61da76509846def8b79d8b64b12a4e735c16af521cec3ad27b15cf44e82c46012ead88bf4485c5b60fa94110f14b54f12c21c3ad3e7114782a589e79025562d2ef3a5d33cdaf40ced8c094d900824663e18ae84263c07840536c220a17d5c43a6e85fd2cc1462bf1bc690f48c273bb01b4505a8da50464523e594c34734edd07e31e8f93163955c7ca056a1f223d174272c59725bf2a6ca33084abbb765355a19f9839c3d6d87f7ff2acc55a79552b52211d1acc5017429875516336307e3fa8fbbe2cee7a817f2c1aae411eeef09ac0a4ef27b4ffa4cf3a58ddf9037fe984af5d78ada657a779e3eb3ee20aa910e1ab38681b03e1ec76e7613af7ef9ba47350265158fb494687f2cc55bb6a2d67e0b53a334bf585243e13af5c2452c5e0d2eb6aea38cd91c4275ac567f8ac729d47c61335cdb6bbc4317e9679436e5bba709654e49d96763063ffc58282a4fe1883e4a7046913bd508344e2e4a2bf6f6b62f6ab44c099d8948988d3c214179389f9bf2d43a42c5ac20ebba0d56865a292f1ff3c93d178df2ad6b311021af1c2d871aeaf2ea40b1768c0ff3cab3da038b08a45e1019ff77699096470c044a48d727bcb7182193401574558fe58b61b56c7ba3585a3f4400c4720206ab3b0570e881637a0ecb05885458c5cfd7929e13ca5a14951b18982e92945e1579a6ae36884547c38e0ce353195ec03e374e07f65dbde85b2e8f174a0603a579e2132496c52466d1125b30e68afe2d96b546135cfedb8adf98e8e882f2d5245939ca446df3985394ef080dc324ab9eb061d30873734f572e922d3abb2faa370f4fa27d59b1362fe09a9494d1c1f015120e0219a610c8a582b160178c142eda3d49e2f3e44eda428ffdb546b7af3b13aae2e80822c3752c041a3932aa0bf2e94492939a6cf95961328a6450beae94aa1bf0b5effb754c98cc1cf492edca4859c5f4b26fea5cabc9692c8dab6308091691426542c378737db809e28da8cc34a699b75427a76e2f2e6493c1958a35fb75665b9efa57297b107468c987c12031b34fd6b47084b59f553e9833bd42c957faa1125fd1981e644fb2e738d30dad10c473949dcbfe1d3855c3f0a32a2268b990c7443ce0c3817ffe1d0df8c74428ef154f0f904af5799954bcf60d85137fccf076e31124610f80cfc1131cf42225945f469c878573509c0702920cbd0e1ee56ea69a7d490580e0aee677ef78eb05020282e97c7b2548856e825c67f0c35fb6185c23da3777acc48636401519f28c93c93b875e8c09ca28d092315189624c1deebe190746df0fe88082551b308c6303a3417ed682c9f1716b94adc72b80787f0697a4062e6f891b0701a7a1ea5e5bd66c9baeac354de33ac65e0d995e98d91fc98d79c350e29659dd93c7c1ffaa83c0dd5e70312da0137d228abc1f074fdc606caea84071a0d1cb0869d705137135746e68c05260471ee501b31bdb490e6cb7d6a170a87274cf30003d1262642c2372fde55b048486d2dcacaecf8cb280fcb530a3074bfba8b8e823ba41600428cf91605641879aa3d1622b5be95b98751166a27011f6debb0803dda2305dc5c3120986da95839ed014d2fbbbc92466991ab207ffea54f17231cb2fac40d9682c2e1df2f48417e11feb2679f20465b474202cba751a60afe8651da7f84d118e50b4d38f275aecdf2ef7fd89022e3968074dbd00d14e23ac3c533a82c1daeec2ad0a729c0ab65c5c0375c0234fa9d0cfe4b4a89c8e3e20cc522b18c73c56d62638b19cbc7f3a0b5d03b108fd1b912e0c5458b14f3cb6bc49cf6158a035a77cd38af323618f5c08311d77298ea4324f08266a6c561c0a0188136c4f47b16ea3603648432f45764eec0b090b0ba6fe03bdb057e1474e6cb369fa78a2ee484a13aa2bcb88452d7977b4fdca0d28829ed07f09d3177fba494240d11bf0433cbaded6ace02fd2d0e7303f0634a00ed92a6377e48b14a0483d560bb94ab55a4adaf5a34e2338483cb14440e9f8c9b172d52d59f31aee3f7b73f1f714048fe511e496c8550e06a700ade3b983a0b426d5cf4f6e29746893c8717946c88f5249005a271637ead003df1b2cd41f41b08dae54c00d2d4d8f42a3b100aed136485b260844d9927126265f7a1f05d301499df38d4a003d27a22e4ab0f382b559f66a87624ded8aa84e7e623730f26da39f20075f6231852f8f1004b1cc032395bfc362aa9c067209ff305ef02d2c6644579a9664781a903c2a45621d8ed70839ab84f3e9a952293fa5e82915dabf83f07de1ce2652e0b5506cfb20f1d0648ea33180f477c69e451a7b58856312409bea0f6e2274e65dae8420d8bdc060adceb745251edc9fa068ae23006276eb161b7098a5432fc9d81e81b0ca498b24820e5b53704462a4a655c0146540ca16009db6b9c5af9b52d23b05752d548596c60834878fe92e070fbb5daac7ada19a6564d4fcde160b013f20ab5786d29ccb5d05ec4d1a10368c2ca362b935d5b2aeb19ca10120f34403efbf78b6f425070ecfe16ddbb993dcb5519adc999da7da9a7e3dde8c2cb9dea2fe843377c538dac473e6c06f812ec5314376ce44fd69b872ce849ae27273c392a5965a03674da7580a229b73263d4b7f48bbff652cbb78b6e69cf9e0ccc71363af5a23a084c6effd28e59ed35dd98ecca00e2c3f866a7a692665d3f89899d95e8ec7657a7955f4498dc06e62a4687655cd99c119b468e804b0307ac311e44aa3b007e680098e1f1f24d4c8dd9fafb3676a45212d7986a5e2cd3310c09ec7daaccac3590c8a3677ce9c10e20801d47294dc0d74da03b6fc0bf6bc22e6cf576d1ce6d25c9cff9c2369dcbc99732c72dfbeb7fe361fbfe4b2c4a11f8fc51ff74f4e4cb51c428c0133020a005bc4e94807c27f921a0c8e82b8154fb2df29c56aa6ced8abfa6439b8d02d55d3fb5b4f381eba5f3f536573c7060849301f96ab71dd6cb24f59ee5103ecb2c426803595d3ede6979f9161a9d7c2aee61463857b7f79da891926eda4b73b87d794c9c6be9f449ff19141cf65b29d4e93b39c77cd4358dbc4cf6b4d517cc52b61382f91ab660195aa7a87a4a28926b3237ac437c7b9502c91e17bcde2a847e4d19b0a63f603da66dbd57ac7c11c74ae130db409f89e336cc4d86bfcb63bb3f062b255c54cd7d6356656dbb3c77997c32b36b126343eebcf0ebe2762ddcbfa9ed03166a55144d630970207dbacdc3d072172b9feac02046e8ee44ad24d3caccd7fe2491cf998c16061c78819e45952a040e1d1a17e56e8661cdd292a7b6ca1c27a475d1e0850512388f29063d46ac41f2347ad28ca1f4129104685b2703c07dbe18553a8225655971bf1fa2185b414fd12ab568ea40af9831639ac47532a31c62e9f2c967eeb4290c44de9ceb868fac83a15e4b8e5125163c4bcf6fb7ef57554d65dac7da1c15a03a4a981c476086c201919aadb3931f35609cafd067ca20fbf98879713a0c87fcb299d710060c274cd3da7f0a4f16611cfd6873c429e504474b25c65cee202c2779de260b7c42d202609125f4a9b6ffff35b97f2c3c21fc08ad1523dbdf64bbf65a937ae8729371c039b59a97c0ece0c438c2efecfcfaa941f96e0802a464ab1f4fa931d03ce0c07040e0c03f33da93132116f6ecc5dfb9fdf9a94272ce8802a9414324f47e6c14617fea724e5cad009c310fa03073f5e46c3d218a9c7cd5f5c94adf2d12f26023c70f70131e2c2be3e2a3b8f73a62123ff1f9871f9e7be742747d5f8825d5c29868c6a5745ba28a55d7aba30fe2caab02f4ab7638107e4cd629aca00a87abe0b5b81a86ee00b7f5d577a38b2581b1ef34ab46c47e3c62a4fef2cc02977549bb691b55619ea0d80c6ec46814a159aae992d400ad34ca3f5d719ce9b97f61a0186be9ac02700494bf4e0acb11ab2cb4d833b76060475e49600c3a30df85d221107f8c3ab0e485e02f41907a1be6cc627e90974060c54c7928dc3b5b07c040823864549c52d100acd95263c0f78405389802256be0f66d36d0a78a608d909b4236a5f59ff1382fbd2b7fd5c5bb6d1586dd9399ec46b415f6330b2bd9b83c2ee55dc045759223f394a1974dcca9bf72ce36ab44f7f0671f894c47b836c4819b6fc47916d9d20de9a727d8342682d80d22e2ec2ef56afef612ccd31eaff59cb6c451c5c2985c50e836b65d1e22e05513bcf83be4f9d9cb44fa54859d38007174068f305513f2e00d43cab5abfb108c16e39c41f6cd19d2ac91970867433db8e17be369ee72671a052ae556f8466aae55ae132d5b939b7c2848a6c884fc50cba5ff01a7e942355f825d8340bf000b202c2be17de0cf0bebac8b3f6dedd69c0640a7a8118a823210440739526302cb9c47706f50dce50934dcf4e5cff93c5e8b9043c6d9d9c18ee15e8431b4f12753f2557882fa29fb4e80d72d8db86877e4e17bb135f62fbb3fcf9539b0307ba32d1fdb14d561a464dde926e626261c9c63608303157b68143136213dbb413fb2d347e396f2f048c2be045b059c60dbb255171dce29e764bf8e961d12c4efd4d83365eeee69ca83635d7bdf185ca86af01fe972df4ee0ebf7fe2c84a98cd2d52994131ffbd34b39d8e5beb60312312743946e10dbfbd44c0aec1412fe265fd0a65743c52366c4989bdde2dba576777ce939bd132a6128cba211076a45c070b5f918942b7d5e0b9cfec2695eb6f8ef4cb36f98ffc4faef6a661a64787d9a9f2299d0f4003d375a29d527259a539292337adf7e389415ba9f73135e8416c589ce0477dd9bc5bfa92d3808fb5bcef1284ee3082c53efd4b3bfd2feeb99817637b8857f14a80dab7840ed30ab4584c087887806940d1e3d8e86201e9e97112cc9c7c110ccfda590bd825742733f437b9888f068a70fc23efbdb950930ab81f9992c341c47b73638827e0ee4cece8e3a1ad1a63414e0e854143102ea69dfd75ca1741496ef2bc9408541e1ad6f6e58b93217a3ca8541dbf4585e282b4b277e7154b9b805c43b33bee0468a650914f324feffca65063107d770b5f3e87fc931550b2918af665cc91d180b2f51910b969b2ac50562c16996c9fa0a160c22a19ad734759747afe6cce98b9ce9807b07601fd8fb05c51f4c55f46f2fc31bff122e712e51f4d5e25cf58b52d07e6a9e51cf1c1c28803d4a330bbc883a08d3840fbedbad55a1f0e4a89c25f42cdc8cf3a4a862eda5c0cdea2ba741e00c31f218c94231c64d475ff24038b85a09dbab0692342cb30685a5618a3eb5fa322e613b896aa3b90c9a57ac0ed2adcf4ac64a71132223222e5904a8cb391f1e1f297da3287cc276a054a4fa0cb2e24a1166f2be2ead1d03a55b84e49dd283c387f91c0528166dacc5231263173c48c6ddadc01f0e8aaa79dd00a2ac9c05ba432c2057ca72b9d51fda11038fbaf546d558ef17465bd32fa4dc1484e63006ae48b113c60c6a5f0a440af934349506a7b57e6c002493214713ef762b9b0c4dbe15f63115aaef3af893abb55591063996f41fce58167b74a303b0d5df7780d12d558ddd0ea7696b8bcb509b78e1bd8fa9302a5ba3943fa28d9ed46234e8c621174829e22c835e3fd34515e5e55d2b65a4075235543d58028c4c74a64f28491cb38ee45617fee85984c42776829f537c0be85b234974f6a3e8e7d613c0015b817eabf2ba2fdb93262bcd16f443c0ede0078550b362e849f31c4d7a3fe6420b6182177634c1dd57f3aa998a01651bfe33b0b81fc7a18c48515870c1a1ae88b4158b41b5244f89dd9b5159237a8123be905a36e8b40e5a1705ce35fb74df9f8919e1132b2fcef2458f05171082a0327818affad2fa20d0bce082b0305728a008c03a5990a1ba9b6bcea0792889c1d62c2890f4042330bc71a81c19be930b9faae1356287928f2351867c811ec40c82fcfe44ab8e5f94901edab3889cdeea6c9aeecfd5506af9e849d2f79cc765952fd6cbe79d9588ae3bb33b1ad6df653e0e9086d6a3dcb84fb6f2dc9a8637996684518f43e2672995b6424c0936a95b3e3dde2669353de7a2d140923018a452efc8e2f4c1fb4b6bfbea0150c701788c07600cc1442f73586dda14054a97bc2fa5b881d9014d8aa4971fa487da281e617020c0b68d4e2c48bb381965b63c5e0a695d5c58d0671cc496e430c787104e6fba2fe6f29d34f3b1fde236579f52ff44ce57f7149d8bdb7ed3f7870428ada5055c921dbb3b466adb907ec6a1b6a990aab0d7ac04e6e6ce6df49eabdaf7ca43b7b1913ca94e8dd1b9401205aa90c4b36822b391329320c9539478c1e071d77e8d011071c3becd8a10e1c39e668393038d7adef08be63c71d39748443c71d3be8808372e0d6a1fc3bccf22a388987f307072ede4a5f8e4df8e2cf5ee527baad4a855f9b59b98f7a82d4cf1756ae2955f16756096d056c75e1f012c1cb93e7d6e271044171d4e2a96d09c04545d23084a3152c267480532930ccaeac78766da09b0aa9159733ed4c092e7bc4e6c2054a1d9f2aca981eee39afa134596875af74774bb8d4ce720b594e5a73d6ac07eeca4a08adcd9a61915b49bb949519663cf0165b85b26ad61963ccd6d451d69d31cb8cbbb1325a2bb366bae456d22e656586190fbcc556a1ac9a75c618b33575947567cc32e36eac8cd6caac992eb95525a83c1a7048b33a1bcc50f975c53ea2710484f4fac26b5b69d5943d2a3f105ecc467fb9e913c3669e39254a7be09664257a951e954720ca3c00de277ae9b976411645e567df59ff5acd045eda356aacd8969bedb64b6c9a756dc5b4ee968bb56cd1ac552bd6fa719451d959f12542f0dae8d7a73b4ae59b87b22701e66a075f90242c2ec653ae791a9d224235fa72ca738273ee7261339b12c2afd6d63092bc9806aee44e00356d86b3772f6569b2e05219310f0872115a38928b10d4dae0e17ef053494dc4c5886c94901ec8213a50ba90a0b39afb1aca722edb1c801b9daa513fce47ab708f90c2aed1380f51b362a19c408cef9e9874b45376036ec1a2f11288c07ebde8948b57a4d2de8c5c019e18db290e1cd28e50123eb0fc2364b962b8745071da645ccc002b69a070c48e080d49601f1cefeff5fac933fcef1073cbb7b33b9a77ed0a83d1eaa8b6316622d4bde0cb1f03153adb0b1f4cf6cfc55d3e9c019112e55b38ac7e79ad21a95f930bcb651c0bbb24528c474aeb49eb00b2ec22fa981d676968a07b14c55cb54728d31e6d130142b838df9ffe0773354ea5816e40c96f5bddb6d0eacab6daa465ec3e911d378ef8d33a746ba2439badbf72dc0dfd020e980ef23496df2a0345b899921f73fe8cd7604be6751d89ece9a2f97bc57929c985633c7c3203f1b5fa81a056f8b952d0cfa80fb73c93a50e626335b61c70c40fc813ac5c1b1b8e68552e05e2e974b36c32add18447b2d2e177b1d14f05f3ed31042e8eb8dd186027b4ac3e2e4edf0d7bb2b2b84f45a5b51d9d1b0f0511bdecb33a88fca40ccf9bd601d2772319555e43858ae9794786a41c85f1ace26db60e4a73da45eca6d70ec50188855603818ee005100c3cef92308b8db5b70f11eb1e0f0ca0dc758992a783c8119affe8b87871040649c5902be2e2e4c860ff47b3f0e1e63bd38d9c40720139bcde1ded593f2bff48333edd8895abc437d7825be87b1976c0d15a813d4f22055293035db3e895038c1c31e143361404714eb59e27aa7813d3d2085f61e18c174c2260689f317ab3d912e5f0dda6e9bbd8985d3401a4059e4e5ba0f496c36008773ef3e4d3e2d298947882372b6b5cba7ee2a2709ee1b1a3672fb4a5a1bb124d4240fc64afbaaca3f0365acc1f8b03ffb723ddf4431bf3e7430b97092c2f7dc31876c101f114c3abc90f4d2f6252ce98149ecc5ed8acd140defa71dd636ca1455be13cb5e9cababc4def79878e231e33ff1d7fa33cdf18befab12f3191839a49dc568e4f3883ebf7b90d9b0b1d63a8b95c5b5b20afb6fa3b0cec9e160773cad9030412343bfb00b5ef33206a03e5d03b661e7ed88613431b2040eed0aefc126997e7336ee124fcdc86cd858e31d45caeadd590575bfd5d0b764fcb8839e56c0c02099a9dcdc16e83f6c40b35061946a6290149643b4578388b4ecfcba63701696bd947ea762ee6861bde1a765ad8f5272463887f756cb8b3e67dd97a5715df29a0e0c5d339a223f3d9d26af0b3b6bdfc5cf5be095eba5a84dd27928140ca026cfdb1065040138038fcc890b0cfb159dff8d76385cef2e880b7091d06da2810da3b9d68e30f4be18b8deb236b5d16918c458422d83c68bd878e9410a2fe3a4a76ca4709e7c62febdd8608748864c5e6a8c87f49e25193061881e7701527d99d4083633f1749b4a6d86baa84ce8bb79a48577b58b8f866b283c566230a3840b26a7150ace4181b8320e06c07bfc1b181cc8439aa33ab0cb9a890238d60a96bab9e0a1d157a152a09f17e4ea331a96ed1e031046450025809b16a26ec3c780a4eb9485aee49549e7a9d2bc505cd06de08b3dd0ee7d9a474bbead9791b69b68b64d0a23dde3b17d9a16bacf56ba96d857b561310c53ac43dae331958f2b2476ba0e0428ce6f3417c19b8258a512175b58fe9c75f79909bbd4ecbf0033479461f63dd19fe943dc395a0d6e5ca99c2b98f5ce3ce4f9f3a60da3ac0696bc84f04634c159501c5515f4eb2b7ec8b0e3091a739a0b8259673959de6cced29d11c561575e34588dba84c7a76665f90decdbc1f9d8d841705ff4a688e0d231ad4ecd6a1e8466744b1b4240a1c2f1fc4cb86e19a0ee2943d448a0a297ea7b27a9e96da16edb608246a4d5d3c1fc8a7a5349aa46163423eb0e15fa8554454d60846a3cf767a340fcd2f0b35b456c44282894150461685fea1cef0ea0f316fdadb6373b7e882e835b7025a236544b84e753d6a8c1abf1a60940dbf970be16f8cf7b5a67139d8adec08bf3dc1d4afdcce654b21a3ddc8fc4a9741cf9c29322507b176991554ef53a71ba7c6068f1acad74da87a6a47856174631ed7e5a20bb122055ba38eaf43fd69856bbe98d2fba8cb8cf45e649a08c3f767101cc014c46aceb07561c4c04a67a4017995aba4c3790325af2b52cddb4fd990aed8464981ccbe9c4483ffc9f121c579047ae82c9282ab67f83394ca0b2b013c5d010af4dc355770ce61750acc7240ae50e5c6eed0e64552951712ddec19e28f9907ee30612477136af386f61118d7dfb570de7c4c681f1a17cbcbe442e5640ae7627934cce10ecae6a60ee50db66f3adb8ae077af16e826774a726fff1d310353034603bbd91abffc38f9013491ad3faddd27ebb42e0a815ab25104e6c8c69b1841e3436badaf84d45b4a84c494f20daea8dca3b05a62389b43522d3ea7e8c72edbeceeee454bf596369d4f280845d13751c939e77c216eb5eb2cdcbae49c732e06d55b3a241a8fc8f7504cfeeb160114632a525e623a322358a5206f51e99218d7dbbfd8b1ddb54dab893df7fe5ddbb45a4b654282836539f671ec9680792cbb1a42d13ccf6ac2076868beef8e919022393c2e4f366b46f1e60d14026e7c26b97d77f7a757bda5c121d108e2e9f84074adebb60994b4ee09aead75dbaf623173aa4ac22c2feb68df5f4d0a526fa9101152fe208959b2b4c64d388e3c5e3d40215b8df242415b3846476f06a7d06050573713ac8cdad0ca2006f3ffbf4b918434501865e6bddb3e0b93c403bb9510dd21c32b47a7a9882964f4a5e4a4fa78d7366def7ffd9b2ddf61fcd4bebfceffff1fa0cd9cdb2521c396bd01f5c13313beaa6214a198f8ca5131817ccfeeee6e347c71eebcb603b1a123693161a59c734671aab7f409fd0f28d1dc1bfc0f29c3e4c7bc20cbf250396041e15ddbb4bd8bf07b767777a42c249c7b4fe7eebe33a1213a24472867e3c50b628e0b0a510dbe6727e672391c77777777f7202e45a2f1c4b907714076e7f9406f79efd96b3877770722aab7d4a839001db5f6271c9c3bace52ac6d58f7a25963688745f6cd88d301d399ad1e5ee633f50398ee4cca880445afa1191437d91c15ddbb4bd995eb6e9459a59bbd62517311185a42a2c9f2a1f8f9755c60739b2e433f4734b5c9beb2ae97a9a58aca666347d718506a31f2490e5a91f8447166fd9658097845112381fedd004dd4d582da26b83dd12d7e6ba0e5cd15a6b2049f5962a974de7f30408d42b70cf2f7067edc0427304deb54ddbfb573282918f530b41bc1c434b30a6b2dcfcfeffffcc1d1edc7fd631710861884168bdce05efdaa6edbdc232a237e3e07b76b5c5dddddddd3d884b959ac4e02f75bab2345592daad2e40b28ebc5ddbb49deeffbc5c89b95c4e664d9734904b66d48b5fce90231f4515d8e8124b2fbb62964400843a939503ab36b304cd8a22b49195861d58402c79027ee1220691e97892e1f3b58b8699392504b24d5b62ef481ccdf07bee6469ebdaa22accc2ad8fdd1a6e11b78c5bc72de456d24ddc8133eeee24c434ce4ee3c01a27d6383425232e30d6955b3ac4c6c7552583a9b5d33484daf9704319c673e7fdb825aecd759943ddcb4fadb5f6edd45b0ac734451e10bea09c73ce334cf5964a5165759dcc889dd0ec5ae5114f1844e697ecc17a1159660c3073d0d3c00a9c94183c3830ef4e366ab1b5c23291c31eafdfb3bbbb3ff5732765815dd05299624083d05411244c4d5490cce869986293dfffffff6f2cc5b890915b41d972c29b8246997fe55aa429168b3cc5a0a25091a88854646a560928eb55aa9135dbd1b0f1003272411f71244e73ec4312791ec1c4258466bc51878ff7eceeee4c285e9c7bf03dbbbbbbd18c13e7ce33519fef7a4bdb15b7c4b5b9ee9531c32c1c81abec98e80549015271e532637be0947307823005757757712084ef7d72090af311c3062a2689e297fdff3fb9ded20c9c7573ce43e0213bdffb493e7c21592e930b38764ca86b6b63e085e6d18326b2851d764b5c9beb12d9620f98bec1f596b659a78265310192e20aa9eae7ad1a3e65bc8899c96514a2ac788ebef0aa6924516e4c315b286dc9744f392ec664f411926819ffabbef5c4c9b80e69261ed30a0cd06ddf3f5725d55baa5c660e554dd7b9e00c9390fd40babbf3dc6cb5536f291ceb132b1aad81447cc35313fefff7b9998318d0dcfef37c81102dc6863a44468071d9d440aeb04a61ec040f32c566e728c4696cd8d5530ca291330386870ab6e20945e5e55f07f724393c1e8ec35ff332a5ab088bd34d915a109d56bf3361c38eac6b6bc788ebbfecdf2d716d25399bb43d77f7a41a1a9c3b2cab81758ddc32153b7ef944249d6822a1313d323306486fa6f4815f1519083da22dd39d791585553c4392a8de5263e6903cd60280ea322cd3911bea04800a0bf2518304588f1d3771115186020d4ec0e44a70d960690153ae40116080686c5ac134d9fc40be2c19309bd1110ad205f463e1844b8b1b0818f05a19723c423da990fd789249326aad354b53bda5ce27d4034b34e701f8aeed0666d2bdf5e9a6640a366af6fbffefad37c6a06cd8cd1ab6407ae4e55cf9cdb8d0ca11c118cd84181ab934c1a69c463f6c58cb2b513d97ee3f7548f4dd5f49885c386106754b9cedf45a1ea9c771a8b523f366b311ddc731eb04a3f9822175aa01cf02459c197ebb756678d7366d6fd7efd95b9d5b92ea2d55b61d5a96bb16c248840550aa0b860dd205fe2970fe42585860435081e637b10e25730f28c011fc6cd7a312523e7777f7b8c697c117ad91c5c1f596b62f3976b76b9bb61d8ed16affff4f51aab774d9747e90f2f4921b37d3188b6ac75a66c2ac20502df4cceccc3499c68c18728c6e896b735d1d31b3fcffbf2a12a45e51ad183b6ac4dc58a135c3bc514fa6920afc98a4bcb4442075df33d5e399a6ac66b4d65af7bcde13f49ea1f710bdc7e83d47ef417a4f32c984738f73ebeefe434abda554595d1d7e88ed3a54c15fc10a6cddf663fdcb56eb0bf4c05ddbb4bd31ac00b0ccf994002061c7468526a08f538c98b8c5c56d75feff0fa2516f699127731014e4debc0ea9e248584700f4065207e44a41e8e05ddbb4bde1155c7777e5abded2e0507fa0246a1d858348486444c72b16d1b2820aa8a753cc8a698d94a8962bbbb6697bc7231d4c0c77aa663a1440129dd24e13834ec693526f29555617089e18887717ab42761d08817db4708a95814b24b0495334e9da7819feb9b2a45c87a477fb1e4e617f20dd3cd98e3094268aac64ec70295dd860b1462c60a5bb3b8f8010402eaa601848979ca1e342e28576f4d3f56c555fee9085d46dfea924274bc6ffff1ed3d38e16ce3de21bbbdefbff07aecc2fa432e92b6c967da0146559d98b09d22763cf2f6719e6d3028d4c0c7725aa9bb66b9b5693edfd2b091203014530203a3e2b462ec213575f31173cd08d207aabb0686c5878666830069deeeeb323142b091316954284104aa68965450015cdf32034eeee4094989669c8e9be6bdf1febc50a6ea74eb3ac36dca25f1a172e71906a5e1362553f532b869e47096a6473584efcff2fd930e2fe338fe5a9649885d906a7d74bc3221ca524c1403183a973f4a29725fbffb96877241ca872ea0f1ff9c99261bd8481129f2d0f832e25a70b9c17e371a5015de6b480493acbd199cbe55ed4232e352221750c03ba25aecd75571ebc382ebe50311383d34c8704616c0af0a0e9d803babb2fed1071eebed4a38cdbf7d7f9ff7fb9ded256657bff40adb536a2516f6991274808841191bb3bef3dbbbb7b8ee77a4b5bf6cbab60a092fb3c1c5945474bae1b37b61e05ebdc1ded162c2a63d3966dd7a089caa45c6f01adbb7b902cf596767d0822b683e30c7e84e4eb5d5b12a77b5cdfa3891584172873f88efc766dd3f6ce3f150709a2a88c651485081d9c98c705ef02f72fc40264bde00b3c7ce01da11a3122d6236b66246548887ae755ed150b295750e7b925aecd7575bcff7f9f32c33107e36628e377241bf13462e7844c0ac2c5b8c2ed8861924437a42899c2ffff41f70e46a83becb2cb215459c3eeb8c6cc96505fce395329d55bba6c3a9fd00da8a239126954acec11ab2073a28627a6451126299e8f4ccc8acc8e64d218f62ca2a43453d48f180e50345b9ed25b2533072be5762e38c32939e79c6984d45b4a84c494a2cada40d38562b66b9bb6b78f75e69fce9945a2e085988ddde9ce5b89ab556ec5d7dbb54ddb7b85317410b582cc9325684515c49a31a26cd95d31c3da646d7a01bbb65d5e6979b1c97b4871746df091c8c26e896b737d85b58e987a4b77704c53f413238fbb5e79afd65ab740546fa9f1884c9eb4a074770756d07ece39db20a9b794294595d505828dd8575044f8ffaf9273ce5f39f596bec121d178f4f08564c36e9e96d4647c75199e81f550656042dac84e988830861eeba64caf67be20d9a35733f6a3455cabd81234bbb6697b8f2d6742d7bfde0ebe829bc54ce8738189e853b3719622f524d51d0a115b2a502d18797e85d602ebad0fa452503174f0f8111183215b412648cc1fb690d1e77f001b2e7d252f7cceaba98feeeebe96242aa6ded21ddc012cceee6e8d3578f0d414ba2619a880089d1c3b7ec2c246a4d0a79b212c95f79edddd1deb897307aaaf6b6389818ac26f23e9aea991109adc340d64793430674eef6c802e6bccffbf12972a091571ff4a9c056a9bb36fd7366d6f1a361e324052d21328b97b81ba7e5804edc080250cd103244aa80495a36a840a6631035385d09d64ace4ae6351d82e8851c70fa8488015b7c4b5b9ee53f0c52d716d6ed4f94e09470c39edfc8f58002f5b6eba444cc6bbb6697b67e07b76777727a025cebdc689c84aa70ed912aa3ac4a54ba1e7cf4ce5bde02a0b6c05a99899a13fc2c8604442a849e83e29022c5feecacbab97e37d6c6624651b881cddf3d1901808804a1e42b2b0cc6617785cbf614909b7bef7ecad9635b5866bd820789221634a450c142c1b303f6a52b462ffff19dec761e2d803b61d8ca2be357d6a0d7b5390f2a8342d9e46c5009d00331a041c41c3401cca12b9a6031480070d8890bc7888d02c1286c6c180480c0086024100180c0602018140202c8a817096ca62b805e646dbf3bd2e64f64fe4f004eb23ff0e699e3247d24b954b5088a40ecaa685d8258c2a3eb4ecfe165df5168aaf83b3641af522ff11f7da40c0a2cca02c46d2efcdcc6a1175a1daa9d70e2a750166303407f0b645b3fc83a82b1e4899184fb508d9357cefb368f6496662150a6f7e785018b411225e0e15f5890e2d8d344d1149d7f438da024305fadde9c440f6f31737f3568755bb2fe44eb98682b9ed86ba66f98ab4db8a862750ed262b4417862278d552ef5a1ee7874ac9ff53c3143d4951a8845e4981874b338fdb6644167f70da9070c9695afbc2886b3fb9fd8c545bb6e2da3c96ac914c53d3127a343d6fafc05c2dd69c4ce918a410957a367bd3c9241d7c1218cba1ccb4637b47115544336634360960ff0568b26be93a44a1a2d9f59b24d4d66695674084fdbd875a244b6e018a06c2095e2dd4ab8dc170c6fe37ba6bdbdbc1e8b152458909ab6d0d8a7ecbca1261aef5c8f04b1c3068a2b35b45a74db7b089e3dd78d2b48c6259262ccc5d1dad46da316394643eedd95a6410cd1e4fcd54fca74e1f6da5b8bb3250970d8d5cf4a4a195d4643556a2188b7bfd5559311193eef6871797c02bc2de8bc8834292b0731e924411129b9ca537a6ceae2e270dec2c56a22b96e463f562dd90156539a401cfda7ebb33e130c2b32ef4653f2413e0940f5b53b2c237b31677e5fd1a5ba367da9a8f52f3ba211cd0a86acd14aa4534574928ada454c5c91726a7a4cca5c9e68a194a25bdd2e1ff64f5ce58c21b4eaffe332f7dd0630929ead5abf96f88b98f4712bb4d25861070fa396f6c3f228aa769d1bef21e9e5f3ddee813d442ae61f6e8103da1331e1fa9e78d1736369bc1bb1251fb2176cbdf28b32e55ade7e471266c81a4dd06282c44d1aff58c1627dfb68302d90a51f44d311893b313a8307cd6fb1475788acc3457c7b4fd399f0880683d5c650b11cd9d249aff68132935cc4ed966f320996adad48ae4546194780947df9a4e180080b6741118468028346c2867ff5c8cb30a14e029c09e75d282ea573c268928293a1f81872649162790292cfc5167a458b89fc6f0fd6686b2a058e8390076939b60b212624324df61daca31cfee89ab31cb4570f2e01b2296c28f8a721385c653b853610477395dfa84c8bd4a47210579b988cb39a3a2c755a18cc1bd73f346275a053857a265e82b441021e8be4a6224d4d03359ca241f3d7c14887a47646ca2c411139ff02fd8d3318ad02125e321b6237dee5811d423c8a9a8510786e2f6c731a10a01da3d9a5796898a7ca49222908098242196da2adf276c85713d91c840af479be33dd44a5eb0e00c6ea0f66ace750ee1db88d1ed6f050d177a8d4d6c6088a44ce2b2a490949a94b4b2a527de01514f2f3a3301a46b8f2609de770961ca6bc649fd8aa25cdac6883f60893904bfeddb91fe918bdfef655f3c8e517069c457ef5e66a650f89c7757ddf4bd252eb8bdd1c0613bdade3b21caf239f0030c93d7aa99a04305b4a17589908f2b2fac28b7981b3ae9e762258d3f881e1aec599b58884cf5cc63bdb190a6736247b98d5cb9fcd2610614e180a3298dde507fbebd8deb27dc403ec12cd41cf3fd70695f9192f71dfbf654235c6e90353490315fd6c832bde9802d0853ba985356e9db8af0566a27858c95138b2db3035d7c7a3a75dba3b647d4c995ce53d2c5b4d91dc8ada94cac2660ae2d76e22ba90317ed99b94c64fd6e32287beb800bfca12f1d2a2218ad7d1db5ca5d3b15a28269a39f7cad6b19a4b66f7e239af7f89607a8a796e0afd971daf7767d82898e207218b3bc828092d7b227d770933e0ce683636435391513bab68dad1389cd709cfd3c40e78d02454f3c51050c97d335cb8a9278364abbbcaba81e076ad8261218b934eccc8c43dff240fab4aabaa8d5c6efdba7c461f7be65bb39cdccadab8549a5b52571d0cb81fd05257f52bc54670ca95a3f890155712e5ed711a3a30a6ddb7ff721dc7d60c33917ccde9916c22a0b4b04d0af2cf4d33c4e6e10b9e3dce44cc35e553ab56df458700e79afb0220d95858da2acac25d9fec14943b4a5a1fff0bfb26a4dd03fd1d0b18b36fe593955a56e6c0b044fb29e7ae1b62415fe0edb3738f03ddadf16285f195300a2f2ee76deb793c71105df2539ba939f5340d31ede2c94a4d025862142884f01f8b598b61adddd5408ab29283531086f384921340b5dd1eb61b37b68394340723ded2dae6516f96f14f7a417ab1907ef8f3d8d002807e59119c18490349de164614cf2a4d018c482df8a54fadff007d1eb27bd59e53fb0f0af55089995afded158869ab33264e0d9ec7bf7a2abfb5b2d0686615895ea0b03f339048da25177b97eb715f87d1b76e542097067eb609b821735cd01863e577b6046e6f6ab46eeb5e81bd192f6d9586dbe510289c53f0e68887b0360b42f22b057fc969c9d4526900a413ef5d1d03f08bfb46d36078b080c9db4de95ca92f557d53820708327b4cadc8b2892f67e0abd2f158e8c14f38877a6bc6b9c4f3276af85a56859bc1a55a67fd2bec14f8b438d341d5082006a530ba240c0df3f9c5422ddddca3933d61c22138dde9184ceb36a9cbf6fb9b5fef5e3ad28aea8c716ac000560b91113db931cc3057892624067762b3a6a9b0941a5a9c4c7ef8dc2f56ac24df912b4161ccd44b5ed0e896a88f89219c826ce8f87bde318ea29d098ca286bce340d0a3ea2b03a4dc786543814d0d7e91bbd61729a3651746d1fa26c0c61c4f34605d342b5c3ac9f66ac3c78bad3d11a88b7ddb2cd19c17b8dce701d600e729e31978ed283e17bd13975471a3cc41380f61b06e6398572c969e0a97c8f0e0e1ffc1e75de3e8ad321dc86edf9aa0ae222941c5ad99472e7b497fce170223b142e1d9d710f84883ec8f038cf50403ac8bfa5be213df902c8c309038fd2b8b108378a2f35bfbd9111e646f33569271d6b03fb15ccd2e646434a6bd7d12267fb3cff5d27d2e98334a71d985bcbabddebd1423a96cd10e7887b26343f81de4cabc0c072afa62e8c7cb05c6aeed6bd1769bf89179a93f1a6cc33976e5b49095f86a79dc57f7cd358d583071d03968b122cb8d09a05fc47adec2af778011f7c542ec21fc2ac4299c316b9b112b064e15331e6cac305901a167eefdd1defcaf6816b685ba73f8b3cbecee1f82bdd2b89654323073de92f0279361ddc40b851462f2bef68bf7c6c788e0b05565c089e13c681f12679ab7ef9ba9ff896d673ef47529ac26095eec0fe4123407ab6faa661484aebaa842b7201eb6dfb528c06d760a637fbae62f1d3bc14d90c54b814df5806b6921652d24ab8e6143eada637b0cd72fa85511925f5d25b5019bc983960a35c72aef5d1235a162eea205db3afa039ad0d2e604bf6e5f0aa5b5d8b602d54635bd41d408a472636a64855314e8282d9b4bbf573350423b6d42693728633f2df5fdea4fc962764d5f80192fe48a89bfd148273cb239add4821e82f9643abd542ec7632e379c8cea7bebd05e38fb9e072b7da4c52bf436734d31fba1ec750e77db919b597124bdfa5214b2c8ecdf37ee72fc8b79da76f87306ec947a989a549238b1e6af86b9577b39aa4d7f14d3acf0d74b922082611b0eba19c2f31d3580b2505c2c15283ef06b9132264df40f716c2c541561bac5bf141f24d724920545cceede2df3f42b39d5aa37946d4b5ed98f05e1fb0e30bee5a504e93f4498f0e111d342b496ad2f4e1f4ff849c982949182dbad8a5fa4c9801369e0f9fc5680685ac05030ad4c4241faf9eb0a0e17b0b25f92004ccf3f3f5ac6bc5d61ab9e36c80a5b3397a18d538253934ee2c38bc13353534c1106bfafb9dd6d6cb96c74f050444df427c6c0ae8fd0b2952172f5f981c4cd6d23cbd4789c704e0d6f09bc12e080065c7516174ac9d4a35b5035767f959234c16fa345d631204cd16fc04323b557bc95c8ccc5953e3abab2b23c449f7f2660da91a9d322a49ce4fb65751590f6623eef1398865d64680c9156e7910a949b7f4048c7010441292de7129ce5036b030541da3d701c3fce1c711ef2e44b0e8046bca4094dea630ed38264db66adaafdbbaa81a47cc44616ce544e1419ac089e82c1be936dd76769eece46f515713c1f02649320b810a4062230def881095b3f4937fe3b0e8c6dbe3ca7818253db8ed10c6d2eedaeeb1e1ab8f3be1ff8f77209a1a6e5c21860d572e8f0300173fc6c2a2347e456ba045efc66b1abf12b2d76760aba0ec363e19c1a04e44733a3ea7bc8ad605d8e9725d0d49fc0c25d494e0344c50b616f398b342edb8a1894229c75ecd67eb20a2d7687cae4c330d13435ee91c21c74aa81054cfd8170ac3306e3fb097327717c6a0cbdc5de3d921fd7ef7a56c2e839d01a4b883fe558446cf79df45115ae624eb16c1960813dd326f3cbf8594aa969d497a53f2030e1964eae09908068ffb047e7ffa76a9d4564c424e87b4d7e412f2dad17699342f204022683428ec9295c3ca27e0ddb0c2f6e11701e9cd20969fd2f6c41a10902704f0ac8769bd1a50d1832c23d4aa888bf3c5d6bcda86761f92709fcb0c60c26f20e1ab9a0955c7a446dc5a28e9e1e371b81126b7c9588b349d0642927c3c733ce462d4b41fa86eddb5f655e5ae883ce7799b4156466c33b15f4e0f4cdd142eae599fabe121b1cd09c5fbf759726074cb015a22dc7dd33f7e1dd1ee44b9b9999cf6b7afe8b95e1331cbc12822a14a6b76411b37f65ffbff06f45ad9a19d4f7b3dc8c2ab945aed68f4d6a80bdddb98040e8fabf9ea2e33939ed1f67f68f7711d1ba6b4090d8e1ad131584f88aa1b87b0d1794ae4e9eeffae272335d065c65885e150a41a0983350131a91f648dd8ed9750e39c62b72e532def6ea17e0bffd88aaa70451cede72200c471d3a5002c5e0f6fa24180d1471824492dbdde688bfa41fb4029e138da56dfeb755a3dc949d459cbbc5a31c0aaebfade577cb36c49acf1af887f6679dee08e0e36bfa2d64938bd418cebe8c1067b011ea30f7dbd88d884d65e340493895c03c835bc0ba48e1c402839721a7e20a414691b12ef4ca1ba04fa31f71ea6a357967a29919bc7e7fe5edb61ba0eb613ccec12d7779d4cf61a6380d3dec324e84529b72deeb6bf2ae9b31323744956ab86e8d7bc0a41493c245c0ca0ad88cfea98bf6a97582645ff908de9a238ceb9c1415b68eadeb2f8ab10624f72c6559612ba7fc1323dfeb15bea4a857a0f56ec1353ced24deb1172eefe871e56575a0bc12c3d50b90bca175f125b9a3da0bf442cd46a68e06a86a547ffe5c17cfa11b977d968e4a02fbd41d07ff9e4d54d866965af5736f497b826c02f6d9d3e1e9cbd13fab1286ad5c4965502d99cf32622d97a200ac8f446cd0a477a938c0c13c9703a4dd57eecbcbc742fa1944608a93744ce7051996ee05a4239cfda769080fa6744df4ff541f1d08e784b07876778caeb692bb9e788673d9b17bf49fc5dac918d70377f1c6c587b8ba233cc12320a303b55b31d2b34a115e96a5eafc5da000152a60c3294c4817b3077df6cf4f3b60db39983e05f13e7c66e084105d287db7ba5328224be105f81cf482361c6d34632366b58484e8d25ec257da93ff08871708b6dd9ea121730964a1b8ca3e88d1063efb192853e840942130a0669a653da7d2df75522648aa574bd3a29257594a111c53b7421b60b088916063356ccf5d84fd6432eebe295c3552803800da55593b9f378fc8ffe76e2371bd072d3193c91b24adf9ec7b751630309762c578eec13a747e353128e64daa4a423933ef1e90a451973330c923cdfee5d7712d0ac9426173e69ed3e21c4b2cbc82d5fda3292b2d9a5799380030ab75cc9f823bcabdfd466e66a4f8ef611c1c7583d93470ed5c1d64217769222423cf278a34bffe5e1c513f0fcd84146f85880f415c520cab65967690184994116c5216fc10793b5c5c415896083570e317e7d7ddeb3719e333f36ca82805985976c9e4b50f355f9f194840ac79abd232f7d7d32f9a6efbedbc36b661bb782ecabbfd9ce877b745b38e77ce3e681d601763490bacf0a99d8c177aee097ed7eec233aea98077c7ac2b979e385d474805fab5aa88bcd8a964ecd4957841b07361c04408e03909bdb6cf698070725ba56209131b194cb54404694c68f6c36a071ecc559dc54e5b87c7c05264aa022c965107a3ae4cb2f0c72bd56eb113534f7590d4dcfb928264ebfa28f548becd638e42fdd4cd72429abde6d3bf20c95220a5c6a481da5ea48ed54da96b1e8577c332d98bc5a6b6d73267ca80bce40cd021d4447ae98300aa46b93c2d31a2d2246d8c45411993f7cf9215b7624817d8779a3c2db8328d10db2204bbc787500fdbc5ebc9bcd71e28038a7da15324eedd453fb6a54e921c908e3694405019695788ecca1f3b46b20bf381b859732ddd868edd1a7237ade96a05a5cf12e093438f1ef7f3b33b5cc7436835a6db765cbb14643b682b0ff9dcd4e4ef8dbf1af4097881b93880b6456dad962ab116944774b732b3f1c45a0520ab8514a0e5700cf36510c31584b061f1836b699c521ffdce1e99c0e89b5dcfea76c532f34f0f92d811440128a9bdfe03e2f4d24683d7fe8f183977ea8f2d944bf544358e0918041d55223dc07b43685381e118c6a3ba1a4fa713d1c2a4a3a97839c994f20c3013ebdddb59b65bb0011f6051f586c24eaf547bac67197cbfb47e939d5e9b7dcde3c5d4ea20b1f7c060741c76b732e4bda7ff60d96ed4821e2b971b86bba909b6939b71f8608eb662e62914c0d4b538c147a086beee2d3dafe979001300568cf821027573870356c330c6e036badeb53df3d357b97f1c7f9d7d370119e77913b12bcd79dd62c0785216292327e3a6880af7b6d7807929cd3342eba9283427020456e980d1d643f21d73522a0cb0ad4482931688409d813baeeb6ee34f654c2cf8cbe81eab8dfbae134ec60deb1b3ead5e5eecfc8cf8c804c49a988d5bffa77054d3b6fbe58bd941948de3e200e1fc316a70edbb85925d469c5e2897465d7c3e5c010646c36e09f1593e3f51735adc6bee6f9fa557169481a8695dbadd30c6f2dee99e6513c54376ede961d573c1f3cb16db9bb8185c3b908e91bb54be0225aa6d51efe24857de5891a7709bc9eee680c756461af9753bbfb475daf342e6ebcc6fb748536c58fd5b7dae3d2d8abdae2af7f8a116bdad5cb00d4a8215a349bd917ff1d450cae6d3b975f40630270d820fb983a30d602c66dad4f0c1cad0ec3e58a3315bfe59bba5018e46b956bbba8c77281aa25360bc431f499e549e8f928ba59527ac5cdcf39c07d3042e86e39d6a6ae8ef0f70a08d1fde3f7ec1bf6f66b9dad0cf8ae90428b8444168a90c0580156220318e5bf2e8b5e70e2bc6ece9cb04fa0bbfae26f607b804aa5736168509658c609c86a0cce70ae5daa08b14feab81e48c9bb3c59c1b0f62ddf690d91db364ea3286cf219e29f0f005579897d1bd9a8a1c97a41b800825c44be6c736fe3bd7047d0a2bf3124d921b7254bfb9d5993a440c0954d4c6ec53301b96e1735344e1c425a189ef90c7293dca0312772189f5c57ca07e950dd954a766d5779a191922e19966174075facb6308c5726174b9510075770f7915f3b06f658ce2a5c7b60d86ebd88574fc55cc1c02b4ac3b4320748eeea6132dca3dc6f5ac179fe71d6bec523be767cd55a9f31f6289966041c98313d957871d67fd236e24cb549ee258f7fe3171f1b09ce4b8f4d696fea15fcd087c75248bc919c76e974643797a90056c9b6398a340bacebab26a790fac76ceec942170938318fd9cc51d85817315db8580f5e34d1a00c1af6d05a5cf14e76f8e84477425ec910a3dac1e6c098c1f147c127e95b3f4bad2e01dec8c35931dce2c7bee53598b6bde7973071a0a6955d9cb9972566a80cec26f0e8ed81e7951a4efbb575ad6610a864e58422045f40d1f252564ec548b5546695e831bfa1fde8b6c5f919eeb6c8ac9e52753d0a6c678609984a35f7b19cad9d965d343a2b71f34dc84040834cc3d4e2fcce21788c995a6662684ed2a4be0e04f9acac09651a0754727b7dbd694d2a53536b13af58c89bc8f73397012d16edaf370a3bdcf4a5328e898a1626611c9f10af07b53c1deda04033e1b81101daadf8ff6df92ee534e5c8c3bbaa20b44253fabea55b28d22d2391346911816d0d8cc248a2140fbfcd8f2d0fe273d0e462acfff6244408d2c5b54e63afe35b07bf388cf2d7daa7fdc18785549b578d659486d0fb1a18d1809526af40485a1a19d2139346285d54edaf80860de4d4ccaf17529a48a69c4e4122edc0994dcfb1a90fc88ee511332d5337d4508933a67a95d0dd4a23250ba18c0c1235783de853b9011daf25daaafb7eb80b34e1f5a26cc4d3512b453fa11825a5bebc5a20d0910fe038ad381bcfdd14243566610fb1b5a3352cfa6b5be72c1704e45c9c956ee598be33456ae20458f125abc95b84b80240f89842a3138b5ccc9822bf3179799844872390fb597743cd1aa9d2b44d4759fd48e2d162ed7fb41c0bc62122f892364cd6b72927fc6061d4cf26958e1ce168a1919b6d894173dc8d85412268b0d379eba4528ce085e30955786f12d57962fe451c2d523d51cb9baca878322bb7e297b4bd87e43b7f6801cc12245a7bb8d7cfd9ac8ccc44795035eed38ad0ed080afb4c3c5485a52ee4f5e620ba11240addda1868e97c3bdcd8a83282330f2597b97030d425ff6092396afb002591b82fd07892c47c68bf3f62e4081783b7a4d67486693a735b34f2eee3b1746714ed4125aceacc82d19c9b343f54535b23619509c2cd0420c1cb025183376bac82afa30eea09ab0c9ed51a644b4ae5e5a863a63f7654adb046b295240b0e88616e53cf40aa602bb033d908a5444e5a8b78adc19930591c01946db369fc3f6850c874119197ed6d45624fb2a56890498be906d1ce405ab12ff4ac82ce1e23002c7a366128a2f758c59bb3d6bd306e7f4e8efbbd3d244b555c0a5192564390d69a9711fafb7b379ee72889f1f74cf58806bdfde655bc93d6b07831bf75cb4c71033198f2e8058f188a297a486a32835104968cf14f3d755d9bdecec0f94035c8679618a245f22d81a0461ad0e024054dbe3016f1fcf2a879ac891fd5106608ffbdcf3d11f45ccee091dda2cb13f2aa44f20f1ab83914b7b0aa2ba97b88d928a4b8cc0290f25af77e643422aae968415e4bce91a313487745c8d3c0505cef3be10c1f036a336c9eecdb3d4a6cc3d0e51cc8d0cd274f0e7242fe5f3139b383ff3f9515d9c97c000128f1522679070c725ee9fc00736a3c7441915bbe9c3c6ea7bc38e42b1d2d6f17717519c1b81961ffe69773e700549e494b90ff1e010340a9d813f2eb6df8887acda12fb90000e0e505db744670a3208f4c0e7e920f7ce35834657f4ab8c0184cab5bf9f0232a88ac0051e5798174988806eeea46858b5ed68cae539ea970199c98b3207671c4c270452761cfdc2c7119139629d19215776be4531642195195a6abfe50b50abe36bd26ac4e9b72536890598f4ccea5b5bb026c21ba3eef3f14875f10b37d783f7120bfae425dce01f2323a04515a6c9ee957f91dea4811d11b7f188ff5a272d89bc507bc2eee213e03917cd2c8c8fc27cf6ac5fc6c89dd8b629ece1f6a754feb15d595bf71bd6efc3947040427ae02fdada3d6579900ad5d668c16804ea9309ec56a54bd70502cd7a8a787833923604a3565d7b5fe2ff4e17e53cae04ec8f7a783b4fff7744826a42f38d87fc31c88239e828ea71d96cec115c0fd62a611daf325c5b310ee38c6d306358bfd6c1c6943b37aa6463083c843acf5a56c29e8ad8a2b92972d33d2ad507858986e49f9d4b578d2d02bfd5bdf320bb32fca19adcfdf3a1ceb49f3b1066b5af0165e8d449fe64a3e206270fbea7495ee99a4abc3eed2d591e4067a1a5a47655eadf13388bdf7305abf9385585130b1136a61b853b6e18118905c18629862ef04ce1f9139aeec31c2b763aacea6371067789a8f58c305fef29f4f6f8cdc789e5d7755120169e858363d8ea82ed17da2381a03ba9a4d94a8ec3bad452f278bfffb40a2879205aef144deaaebe4bcf2ca13d15911cc682f0a0cbe43c023f742dad5ea478ab83d98aeb6ec983b57c0011f22db7a8cb99f2782e7d055ec5ee8288f62d240627c95521277bfe3d2e121ceb296baed42a2fbc8819e343492a39730a110977e7d1d8054f6fad40ed6dac8c31eddda1205b087243335b323b969591237811282f7e83e6639672f9ad9fc553c37d93d946de542851b058b3020664141533e76557d75ca8fc5b0ef810ec596079e81d1460f3091bbda7a7c1efa3aed6003185ca144617f87e3a7ede9f743e6e977786f6fe53b4fea9a3619261d783f946a13c3fb9114856aa06f18b8c3be73ed7e2866370ab06f7979a58c16f7af20ed76d2d6f91b0af738cc5264d6f2c6a786aafc1c01d598bb8fa84f6a7e454d0348b8bcd41f3ae1f7b028337faf664209272fc7ec0611a8172dcc269acd9f607e26acfa24ff16d8e772dfda4283a63a73a372ef55226ad58d19144a526ecbc8419646485e042106076b482d87c9648963d2368ade1b834caa97552b417043cb900136df1c242e3f7eb56d79ebaf56bdeb6e235090f971905b7f2e182548929e025697e2edb295f3bc57b63a16f9efa707c277dccbe9ba94087596c46f533dbbd05ce3a6d605f37f1d3358776ffa50d7228d4a5237d2ed02d77a834fcfa7fc44c1102aad4e244a6cf26724aeb15dda5981cf8177623f249b8b763ba4edad621d119c4b017ada842f58708e25a503f6a3b75858eda21f429f7aa0d80f9444ec0bf5ab0cac03d0c682caa3257748598db2963fb767ee8393d7c5f631bbd4b858b236b4ce4599c576b9d8801cc9dff2af3ee5d67be05e4a5137c263b04d64f6278490f802c202f70230305157835e2d6174702ea87ecc213b267e7070ca091e77e6726d5951d6937555e6f6ff3bb8c59c9f73ce990712a59949a5071e4b9b07a42e674ae95cb0544f6722bdc59c1e8e471d4986c04cced04526e48825672ccb4430a78fffff4d2ebe953f97b541d6065a98a7aaaaaaaaed8ffaaaae1106d0e6eb05aa295befc88f891210a6745865536c5cac54244229692549abb2964c2477944a301972b960cdb411c2216c8a563645f5c99868533389a46555d814b635eae3ff3f972e83e0eaad3f9a6be0040fae9a96872786232aa3a3af1ac618bfb428cd7c717a8084bad60e4d702bca7ab2ae555b582d0d8d20451897f91ad2605eee91f9d329019cf1d8da8367b0bbbb3dd1bec88a61e179c191fa6c01ecf88211c312e300ab0cc74156db5b51d693751dfbd1fdf021d5c2939c2140d61b74621372a222a25122e1c2ebe3c6a6a6f6bbbbbb3ba010629cfea829943526f115326b5dd30865d5b2a2ac27ebfab076002a143a70eb122f898b369b6dc5995c318b5043c9169d5bd489546fac0a9bc2b2972003ab13461ea28c32ae13c8140d63580153dddd352bca7ab2aeed29b5b505c4465c3f13292ea09e8fe3865b7777d48aa42e2b63570dae271ab8da08a9c4058e4b77b7cb6229182d3696dc9278dceec32e5ab66c5ddbffbb2af84ed830fd9284c0d29a5e52841d2fe5ad47940f175dd45392f4c678ac7954ddeef64c8110774337f6ffb18e28cd44263d60298b584b9c333fb843b537e79d4bce39b6d6387d0504f3ce30012e3039f4aa0ce994450301de8ab29eac2b0f2de608012128bbaaa1a94645950c4de4d443b49112e0032a9d4bb76b8ac061bb9935c3929715653d5957fc12d6c7ffff9e77e57fa744f0007d88ab592308930ddf970d163234323864f87f14c39c7d5a5c162e276fd99aa41bcc38b6c0a2cd669b494da72041e0180faebbdb4ddf0c052676400b30785cb07462109da8ce14c12dafeeee0f3d1dc61b5a93b6ff33862494663e19ad368861eb1f72b1f2e7bc588c802220b960ed9011290a6a1933b8009821769ab090d8de7f96ccb53bac509ab9d5e56187d82c67360d4d76dddd6d18aa4c69a6fabf10d562fbff4c4294660e3308a662ce6fc953b2f7df4ca621b6a47a6b8d6cb8f16289dd97354f0e8ec063d0e45804b3a2ac27ebca7b9b73ce594594661e91496587aca5ad8396eea58fffff3860702bbf0e1b2d8b8cd40c59fa4b793897125d379272c920998f1b215217f15694f5645d77217cb6a6b6e4a5bbbbc99029cd549f32fd60e175bfacf8733ea91411e3f0ff8150261ac4feff0dc00986d588592e07dd750c09142f70090d21239a351853b06c77f7900fa5993f6088a160568f6aae45edbe6aa4436966cff7fb6004bc0ac618639c5bbabbd95a46a1f63be3ee6e2b94666ee10e325d286ce35815368565310c4ecdb1350cb41a5be3bbb229dffd4a5ab56555d81496c5ed77523d9f6d5d328258b2c26b7ef9ffe70280e9f6ec51eeb8c4136d58fdffcbb91473d3b7b19aff1fcb86d24c5d4f032cdf8f76769e865c923bd2610fb2fb6079fbf8ff0f2534b4f2b7b8d6ddad944c69a69abee4803cb37703c09b84ec171b390caf16c22ba89996a797946606cf30ee8131c637cabe59368ead71748dd36b1c5fe3fc1a0728ecf7ee09fc727158f7d41dc7b52a97aed89d7b61cf20dd7ad2cbba36f310b6a42d8ec8e7f032e7bf55f3ff2be9509ad9f3fd3c5002fe3f6f841a5b6245239c747c332335f5cffdff3d6c28cdd4f57cbf103d805db37a8b31c61877dbf296addd880132ba8e242ec618d718a234b378442695226a2c557c9382e2c17b51067892b62bca7ab2aebc921b43160c94d01325b613b2947104caf7bb3141614609163bac5e7e3ace760ad8fbea1b3b4598c7aab0292c5b03005e77378ec40b39dc4995245b7c97430a9cab1897c5fdeeee6ea916dd4a37c61d6731631fbe106be707a29e9a33bb73e6f1ed8992b1f4f1ff9f461289e4089b9e8eb6d7474b12a511bba99c730e16519a794426952182cb1aa7deeec52da705590b8104494f46ab7bf06efd3d4f91c32c901b784f8b218e9a8c68a05c0cd13a8f3b7eb83a154c62329634f4248f43ad087684305ce398f0f471146488cd022bc8f811923b2292c3e3a846850efbff6f3184d24ce1f0438be2ff322b9ab44769113c76e1fcffc16a5cdc92654a33d5d95bb25c4f36e89eeabc227470569fab730855da6cb69a99596c912872dd66deff77e8c043aaeb5f1e6753532f898a2bc8c66206f9b1e85249810848d68b209e196228fa884ecc540437f0d2d5e9e888712372bb3efeff5f97338e8cad29221a6c36ba860d163d97a5006ecc38ba526c94f08731cf3d41f410b6d8a4694811efc61e308dfc5a862472445a384ee494d0f755c345219b825d5cd50659dc11917839a71042af8e28cd4482b84afe38ae942b3760e5baf45dced852300f0613cd6870bb181508993671ec97ec7e79250930206408955717d111e70c4eb930f2faffaa224a338f1eaa9039dc345ce668055f1ebeb12a6c0acb0a91f4b4d7dad16f7a8325af407a5891347700cdaaa189d1825a6e93156528cdc4b52f4e4f0816406d8117071a8c31c638aa09001a7528aba5458f251c48bd4444aa5154342d3ad478a4fd7f18d44be97be9eec6f86d0b3f2576ba96c8ae545c8105d970c09df8cd7a5cb09afbff9584509a5994f464eca0648577aaaaaaaa8a337bdf5a95daff1f86446966324cb9862d51c46cac984e45ac57b3402522449e488f9501820792373d2db723c1125a472d406ee648ea5815368565956adb4ef0eed4d0b8015b21c319b60454b26abfbbbb7b92509af96414d16385c2b6dd3e3b2990a2ce8ab29eac6b1490b21cd54562e66c81a7d301f3824caba8c914d21b3143c0d6d4955113d412a8e753c4cb811398b2b46010f278f05801416163fe08fe3fcf645194c143bedc691221bbe15b427edd30b6d2afd8c7477d39c77004df6e47621cb16952ca51559574238a2498d24cf56f4dafa4f9012a996b915d581536856571cbaab029ecdb4c5d6663d1c7ffff1cb61c22872e6723e4520c1d442f1518bc69acdc7835e49d36ec9e2716d030a88fffff01ef8fcecc06d23d4368853c3e4470158cbb0257e002a6c88b5b8fedc724e34176cd7a39d7c7ffffa82572e5ffdbffff3bf5509ae9fb013308a7a0caff12e0e4c379f14ceec9399b90455ecbaab029acfae69cb38f10a59943b5b81e51902c083e49959a8bae2ca6254b6e68d316f5e043974b956a50ef58153685655b75c74077edbcf08562c44c52d4901f27b058b28bc2b12a6c0acbe217dd993986b86555d814961debd66505807a594f742bca7ab29a6bdb8404d4ddad43820bb025b29b2043390da51563657adf740b57c3d5fad121ca41e4f6c562654a33d5decdff5fc48d62ce3fbefdbf4c12a5994a0f64966f115343195239bcd8755dbabbdd54f9b7c45bb0375bc21155228eea85ffffff15302436214a3387c52332790f6cca9fe4869f7ae07e1cd0bcf58aff8c4ca78fffffc5b0b295ffdd4035030fd44c6f85f24d81f5758e7530b662d724fd09d6201fe3a2635a35e6fc254df00e05feae0257316163238af8308a0103ceab86fa529aa97eb744db59dbc7ff7f61cea80957336e37398ad408eaa7e12e9733054d3e2762f070a167c609d70425263c7182f39bf5b8bcb5d4f8432cd5b5efb74f27889baf1baf28ebc9bace786b075e60415c42e38e19352a88cbb3bb73a8cb8b0b7c90a674c4909161a49b8080b93881bf9b09d9ef37c36abf33eeeefe4262115fc995ac8acc07b79393d14cfd55d653dec0dadb060e54b5fdff1fb72c0df81e9596924f3227118d12274a4b48079f8527231f1c28ca48109934f460d0c1579ffbff91921ae9a9918c8d64d5485b8dd4d548628d54968998ec54555555754bdda563099408c20092540449662868464cc786d5ddff3f0a08a5994220a28a5694af92165e50f514b946388854a72ea6c80cfa04b595ba6ef75b53fb9d7177b71630a599eadbeeee96b7cfee99931cc298d8e8b101b4aa6deb1a65a4ca5bce2df43ae59c734e12a599ca10394b9baee7fbff16530a08885b1c331bb639e79c5f21946616059020a8946ddee6c40079131a68040d0371248cd31863001400070c6a94b4787808311687c5c1a0480c0484026130180c040040a140182c0a82d068aeaad17800a9362d9b755087dcf8d252e1468564365bc5a23186ea284aae53a43daa469d13895e5178dc5b2b30f6db8c5b8ee015ec4a8f461befdb5090b46549080152a5f5c6c1719314fdc262e01b2f7cb846499bac1e5a5c8b5520cd8497002e3e611b62c8d6356057eee490bdaea48a573a2d93e28830caef4f278d631235b561e51fce0ed32674e53f5140a552cb7c0d081c6388e0e53a5effafcadb1e9bb7b2e6da0865e6d8d3fa48fdd8523785e51f71ea1a27128cee1c5d7b313a04ba1da2b55f9be41aedc5ca165f290751cf0590cd0d4fda27e79761ae35b87b26687011cf31c28ad9d213cb6344da3e3f74b2b3537c3c235bd069f7683ed20d21d4b088ed678cb5fa2a8b5490f1b7bf61818323e03ed030f223019ad1775bb4d2eb1c7b0de8168040063925f1d163b92332dc60a11e8fa243ab93c61fa4c3ddd46864a2d2308e8fc72fba05207a5cff261d3ce57fd7f153a8add024690786bf3c69bd9e960280f148bfdd347b2c4e8917a4c69317fbdbe47b65fe1897ca90aaf0343c7295c6066ae25db25a775eb1efc34f746a1c8bcbd876ca1a2cda61554b1aa040360a9311f60f9eb859eb6db7cc115a2a1a8a6941cbebcaf6f168f51d1ad31f04589a44a940b87979d0107e60ec29246a8ccc420d8fcb4e3ea5c9ad027bd880c3948e6b7159b4a8a37f4cd55e4911a95427b5d31f4d2e256e27bced380dd8d246cc8829b585e8f429a07f12dd81c90e4aef2cc53877cd856996c1478ea4231f03dbb9cde6d8de7297ec59b50b45e032049ebd53d24e41279dbfbc974d67b9938564044581bd86a8ef7d6cdc08a29870510420372809173a9fafcedcec4568d34eab4f895b5024e18176a716b453bba8d17c4aa98641e0ade052f9272f7b879a028af2df79c3a056ba73b0dcc0ab1dbfbb3ecf2a45e574a9214208b332241ef642a9b3a700c8f059c4882a07b51c53c0c4c948530ddf491f68f199e39d885c90506d27e3097393314eaf300cd5dc2bdd5d2f3e57a48999a80f83cbf9c362786b75587cc2c110b6df4957d4e698db840b57f3990871489c67d1bb9709db69cb1d53706044b9c4beb1b1adb6a704c44f90b01ba8672f30afb5ce0a199edd47bcb8e111e93344e453b4d2244f262a824b6193cf528a7639103ac8b8f2a9bf48c2343523120f50b2cd953e8adc09dcbbc14975bd51999a584ada2ca8feb61edad30207495f2dceb01a900e462e6039dc910c907c662c6d15f58cd2e8df6e596b650c42f533dd0d81d1c710855ed25db4128e89420b34545bcd5aa3e8d1c07cf9370547599d25c9fc3535068d70d49bf3178596ab1957e640d3c1c9ec30ab08cf814acf3bb05ca64ff945703c097977487372036f25de21d993cf004ee36e30c75fe07c8e237a9a01dbb35788df885ddc18fa956f48bfe02d9850367135038276ad7ac5cfdd5aeaa97facc69751b681d13c3fcf0f0452f8018b861cc8eb837bdb995d8d04681627cc7ad38588b3024e671d9ad1941ac2b52ff4a94ff9ec9119c77e26f4f16b2da84947bae7c04807e6d7896a4eb000169b8967d635e87bccbb421fdf28d726084833494e7f3dd1f6aa5243fb3ac63ed839d08a4bcdc162b3595e9d5ebf4459d602799f8bfbd5586690b47ed354eab043c80b429f3b4ca1c0e42edb66179c066fac66bde8536217815d0c77fee1a07f688191d7f3b54a0584cb0b21db23e415fe7ad635084a5e405de7c966d880a6746f69be38a57145cbc3f38f131b5b21e5bdf0498a9e2bb907d5aa73183bbd5e33089b4311958b675a65fc285b577710993c27a5231644a4e96ae90a487ee4b5f25548fd8b6d66f546e5ebf31b5b22d90630e8e9505e9479a09a0b589aeb9267946fb14fe12e4b5bf927e8662b339ca794bcebe7924a432b6b215078fc811dd261095648c9f765445061abd52791a68bd1ae7496b0272b2185476bc1989a6dba82cd1e6595ba632c3c2539e2cc4490fddc1983701b68a2790f7ff8a7b6f3504497669a34a6b5df26ac7103b1be2d273be43d06cfe8503da2511ac3b9093abf2e5a23c034eb8629158e83605bf704cea275cba29d285a1868e5d6848115adca25851956892766d702a8f8df05f238a80c2a402072804596d9116cd5da5f2fe3f834001ac6bb2609735f829a9729c75aace0d836b8065dbf5c8df4e036076bdbc0eec5596eb839aa9f283ab945c837d4e89aec18423f40e74d8cf50c31ff70db8457a528c77a3e540551713c65e776e3272224a12720a9b9e434ddd663f81bf7a6ee289d5fc5c00297698a96aba2e380fea4cb7fcbfc438db3b037c9112df4f081eff2c5bf86c1c8ca5e279d4970ce10ac5b53260a9c2fefd849d37021d84db480268086fe18e2e5b029c72a3852341224da2635397b4231b8fbd5efb58bf18e9920bae9463a4980e06a20cf274249c6005bbcfe7ce8dd18c24732cdb4ac1bf83d11b657c55bf551d7b85cc81352d7a7c53e89bb842e069f8b2c124a6af601f9b69bcef5e6740a0ce981c6c7714b376ac1ed6ca411b2609a0d4efddf50162a9a18c4213803c0ed22e26c04dce7b9032a2229a2c083b04df26a7f4c657e471792b80fb7e08dcdd5298ea718e1805344b41e197f95e6edea21c20a06b24c5f28922d3d784a3db550c565354db5df30631d0935751bcf76da87e0e9a011f121f4da51412404c9d533ea8f1b47c2a766ba97b8751079d3abc46d9e1afb396038767c27d5737cd76cfd19027c2517ace2a75d1f2d7da2387c4a568d9c5904311c9fef21808ab53b5830728ccff0c1a15829d66e8dc39a93d514b76b89e25e9d555cb043cb9d3a0e67a77c8ef637ae9e59c1be788c702cc609d62950454a5d9c578b09ceda25e6bf646822edea84c8e59816c400a69df0178f8bda50a373bfb87b442a100764cf27fa86762ddb6f1c5aa225543fb481039a155063cef8bb3ff2e592becc16f12b8f93d10ca7bd85a644beaf8ce26b7b20a3ca57a6780188e2f69f9d7eab8449aa11e447e81c35a2a2c7771cdb03c1d4f793c81db60088efa7525a972757d5d2eb1776feba731f8830be46903f5f1411464cfc60e10d96c79d2503bd6befe426afa55f50d91c298ecb41f2cc0f06dd7fb4a868b05a8a9ef77b074e8fba84274b104ce035f24e70b17b13a5dddc4b3ae4afb24ae106e84657b1ff6c49fa936154f1752f996f6ea52be089cb271a71c6f783c5997e91a0552fac57f96413a7df75af1f4f8a66abe2e4135ccbc3d8d8d6fca963f9f533e50307e01cc56d5bdf4feacc7a481144a30d3c7c55c6ab2a5c9ac38d13b0cb04ecc556f816d52db834b498546e7824764d532fc61e67023e4d178d2707147b0092326e06550ccb01985b2a541513973be2ddf77c2c98099f8990cf5b973b5286c9544566989fb38bc5247f2d5a1236d6beb0cb0f494e67b19d4dac0e73700df4781b55eaba76e47bf70066d446295b25417f50d0814e4b3530c7024fddb0944d737fced13c0d7468f2a1cae92ba079f3a212f1c0875d95c9f86399f8bc530c36c8a3da191668369fd1b569cb210f73b09820cf233bbe24d37d370caad446009b2e668b8ebf147e6fee3cac7025d0a2ead12c4e9e4d048658313f79ad5a630264c542096ffffcafc920a94d3ded10ef4a19a576f6e80444ec71712de5894aaf9d467b4a712365766e2347beb00c4b98017a2fd4955a3ab7285639dd392b77110c9c1c1b2d12b20a6db882c00473798ffe2d7b3ab67acdf9581ac9484a5000817f0b57a48b9ece8473f75d62ed4be91653391c90280e4be7b125992693464a0a244222174232851f3db684db69d822b1b8c75f36af99cd6babc646e9796a2a2e1551f9862c5df57abbcc8b6873a900b24ce7abea3c9078941bc4807f073d624a9514c8b2146fb8ed92221633ea1b5444cd927035792ae8e2c22a206cac941f7da4616aa0e32cb533bcfc704b421a5a676a2e93b0505c95b550d4c544e00267dbb6f72c08576e2350e1f469f3e98483749111862081de8772d4b56e7a49e96a234abe8eeea3e116b5c24746bdaef6b7d3493275a86ddaff53e254618fb4a19fb07b06e30ae735850e508df75c9f19de0ef29821309f3215956c124129bf0e4098b807229ce8086074b272accd3281655a57a501733a1da0399981da2ec635447792f9e548724a19f09c3fdbb2b78e747385b38d78a995c203d80254b4994420fdd4e01a32d812921ecc8b9c7d183ddad7d23d1f49477977a961f6ed52ee658fc49db2bead3b00d4445d8cb97b6af667936aac950647d04f7dec399d5bb2afa1d386b5c29a41583892242fac073acee0c7740470225faea9d56a87c6215b60c2c7ca9734afe6bf501ef2b16a25b8c64276475862d9a795aa5e5e334442f9a253d1aa5a930b88a83970585559b7ee75ca8a2fe119d85d7b8249c9ca40a079b1b873568e1b5551ca752b629be3e06ff7eb0faa4b490e11f169d15fc97c4dfa13f10fa031ae24e8080137e5b3690ed6ab8a7ecf87c7577fc2d8ad055c8214e103cc8920ec43fadb5e332b4e05261adaa0a2413b37b1ff24c2b81ef63b9bdad754cd1737d28904bb5670779d624f5bc1068cd0801e6001b8f0306d27a5957f15f60d1f3b443ec1b2d9802710178009518133e01a4fa23257e2302ff1ddff9750f6fc024a837c6af43b46a17aecf7bcc0a5d980bf7e91c36b631cab928e7652a3e5395289179e82399b02c978398c4e4796c2efa5a6cf4fd704ede56334970e33d447d6146bdbcdfeef36d319c0d40d3cadfe267a4bc688acbc30c9fc52689aaf22b132504da6328d3d259c692c8614c6f114c2136c651b2849ed57681cbce5d7ec868975d13f3b22e2bcb18c369a150158f43c588f848518a1c3503f525491444e881a8696f16b519af71ccdd9780c76e973e452fa293057a143030a0b4e6bd895823cf05a6dc82cb945740fa2e2e85dd61fcea1f0fa746c15674086a9839964f7382b9a0ffe83fa03816808fe035a21d6a7ca3675d7b1bb7c16eadd24b159d2d42ac8cfdc552389d1980bfda9ecf64ea08426a51851b7d24f05511f813af01fb2d15ec806d423e72ed88249a22b5c3428e0e51b9d1d6b3b180430513c2b90157403a533edc59300a243854217afd93138c291a9d91c861a66597f1c0a75708ce831bfe516e8a23f9eead92a0086d518d7da90b5e096652efffb956a443fa022a07dfd5aca652255b4bbfa4d6e7bb38778a0ecf9441718c9fd6e352c12b38112bb9575bfd5bafbfcc2bee0b8d36cbdaf4d8a279fb2f2c4688d7900602553a9d939afb7bded4c3c37a5d2fb7bd02ea964bd9a69a5c263234759936adf5f51f07cd2cdaeb75dd5ff76b4902adfc34dfa2ba87d1eb5bf0bb7d3aa9ea8308dc0156b5ee68c85c67cb39352aa13391e126a2308ca6a4d75e5110b0e9ae17cb0c50de55f41dc61f0cd5ca6e79715841d7bc10692cd9881858bc51c94e9229bf1992361e2e2bf02015ba3a9b1cb2f04f2ec93a44956c4af931d28f597f0c6ca20278ea4d5888d53971a147aea2cfa9aba84a0e82fed663cc3f65ee777e3e125eddc757ae872a6b7dc2560d07201882badc1fd2affe4b7775ef80d45ff2feb7cb12a9121ddd54807c1587bea92c8ec3bb40d154828071b6e417fbd5511957577aacf68db03863d4776bac2cafffeb84b7b9182131aabddc536355432bcf0f696a9aa126619489e1c2f837e56090a568740e2d036e1ad58ddc669f3eaeb25d781b0ca4a2309e5ffb034be64faccff6797b8a4fc845ba4f183033f1ab983220670ffc2231999ae83ffadb834c048dbb4d7fa5ccc3bd941084927cabb0c7ae5e10f7fdcd441232723b42a53c91c716cfd60bd1371d858f58b717353649911cd818916db570b2c071169ebb7653c9c590d438783eaab595ea2702f0ce7b618fb342fd2e44324ab75a30a4e6d5d41dd8d926328e96f99d871e4a368dbdd0b747bb8532b48be47f39a153c69b843532a8e93d7af5d643312d8e5b5a0c4a25f42219acb58f2a70185476e6e08384c5c6f49b77819579789c11ad80cc72568b6c9e9ca2dce874dabd6bba4de1b94886a49fec7cc5493534bee914bb968949d4e9831174104147cb09ecb22bc02aa12f5f38d0b5f26f0053046901c43f244c279943ba89b11e1f1c79b935d56d06f6bef29bb9aceaebb31884f5044cf3a013a91e663af156b02a26eb6f83c8cfabb0ba9646523a610d6fc98009973a394195fe11da460de87f866fe5573402d801d4f263ff9965a7280e28bbac1fb3a91532b116666f1014580a361bcd554368c3ca907f8255487d14c049ee329f36d1c965f0fb871c65390ce44bb2842a5678922df7aadef656b933226b0e5f49f1a87934e662483344f5b90192273be59a78d50521104002e0bb4d70665d566e48f7448cc15fea67bc89905dd64d560c9edc3772d7fd0fe79f04e1e16e153b4c198788d4958a48c5bf6907e77553abddebc4d936111042d296b4a8cc2094514829e441437056cd6627d8e24d3402595c750e0d6bdaccf61142b9eb40d792fc1263427c75c4804ff7a085386eb563553020d5a2d91f2b938c451d0e1e46a5e477f6fdf6230c4eafbddeb1e129692601de45a6c59a2902133e5f6a230745579e1ee33275b7949954beb877d6213b8f9e936bb6029697b62096eca3b90903a67767f7171721fad61db7398a629fc90e9e847224950390feb0d01424edb4a4e35b638e838aa595cb525d25225e5b021ec60f55019655ea536c72983be55d13bd4e96587c7ed40f3b4f505f0768d27f3233e3826a779b6da96ea128905ab30ae2dd9a9274f0d2b6d99e1d25bba5b08dce4414451e17b3fa4c6859ba8c4afc647dbedc69b6fc8b76d45f0224eba4fd5c40dba0b542bf719df330757f504b21a1aad7f1d401e2a5f83d2c6d2def10155855e5956be4409a483234b7c34f32756ffc36f090c50992fe760a384fe8b8b759e16c0e65b8ce2469aad7cc75aa3126b186eb7be7f494dac0d612e66872435f5ae50ab6971f21e6e8e22a4029135a61b7984c9f5f7c4e18a0410c3badf31e95fac7cfa3d154312c3a4682813c11462febbe9dab5402b434a4f05e49f052ff85a0d4f45bb7192106f45466f5b20c3c70847587331ac70b6d0f4bb56230fa6e66c50038cfb4624fac635162f6fb87cc1cec3726c00722b670a1efea68938df478446285c70505ffceb73aa508ecd914b96c4918556a269d38f495a8251b2b0be5adb91bfec46f849b060967363139e2d45f127b22b0f8439cea55ae51766bb3b92cfca3f4180bc8a1ef7f548bd86c4cc348b8544cb3db6ee5cffaf1929356d9288cb80407e847082711ea1d233184ae64a78a6a46ae59a4510ca760ab19d7d4e0ca3059ec005c0e864e5589b654150b015d2d314b519eafcc0b80c768df4e54836a95ea3ba878b035b0a05ac8826c5306e3659bd8126f5a261dae5b3851472b3cb8e118dab83603a556232584de2ab5d5cfac6d967120e469e0a249c2a84e7c2aa22391db067a3a275dc2a092b81d30f0fdcbc34faaf08bda5adca3346ec6454a80d366e899c2f7cadb8f4033ef6801f4ce7505fb9f5e9297932d4b73ff34b69074d344473edea2d1c4925f5c2b53c8436839466313c99b431c4a191275219dcca464842fd4a8352f4bc28ca6816e5564428a218d1396eb5f4fb77fd978bb38af36fb6e95a205e34cd60cfdc31d8d3139427e3707d7c278e09dc9b8a779e465269b1a008776d0858f259f86cb188578370b958c4bb8b76a169daeffc32533e6dd1c2de30d379e0bfb66a448b0f3060859cf1e061ee028af35bf19db4166d67846564c600ee1b32ed8ce2f2804d5646aad46f6f8777af521c4dd6a0bb77abcdb88c74ed3e9aa987517d220108b1a922ebe9bdd0598967c5d22003d678dfb92172a40a02c641e9346e75e2312cd96e7ac7691062d74ed5b2011007f14b9d6efae4e95b3ac039efac873f07191ce29a3a77aac664ae8246c66268b102f78c60330563d7a56c026214a8af6f2dab6207bcfa4f7edba740107d51fc2eb52afa264c2ddfe1827d1a1d7748cb4445b2f45b4bf953239bf7e60864399f74f5d24c1561c1176b8b564bfe086fe44fe158da0ec3a66ebcda0345bf73b5dc84a4698bc1c3b5bf5181f49cf3c818972d1d5b58802a4b7314b83be9d99ec89bb4015c386d96e87e99b3ced7eee25b9a7a22986e0843d77aef9caca912b5d0c88f55061380ea1529cdf84a222eff2e5864596c8cd9124646384f0cff8ce257aa2eee2dea3c3845c968e7b1c794963ab7e0908141a0d262886a99bb5fb9cc2ecd67c5574ffb4e7cef3e257c8aacc503f343ca9f02380b6e2726d982d1591818417dfa0ecca45fde0ed31a94b84e858415e52e22f5b9766a6daa8ec656da88c25c5c79700a6b9a107647fbfc45bd95232a2bdf60db1fb6bdf309bdb0ccccad1f11efb5dc1711d7cc3edc0caf0ca1909cc8283cf2a0042aec2a386cf7460c95d20944ab34213b702d777f31df7d266c3b12e63de1627802154a13eca949db37729d8d5ea9638b3e2706bcfdc5f20f2f822940ccc657083040464a9f93aba30924406880913b6f50cc7c28ca331d8d1d02f0e1def8a485517c0419fc11c39e23914fad2699e57923472d7145fd0f06afc16b379d8bb8a69cd0273254d470cf70030ce3fa02f1baa7213f2c34953515ac2e0ec98348f36fca03d91e8697cfd74614cfccd74c7e4798cb3d28bfc961136e2ac71ea2aebacb81bbb0829a0c07f672be14b67c03d8d9f31f0e2f079bc71de86b8b96a0d04e057fda6d35a7bdb49db820fd89817a7a9a28a5521eaa2d59858b96cb65a380b589ad04836f715661cd76a7eb5fa6c9f6d0a2d59634a960fc11538d24812af0cd6afc0d4b093f1801b6d001c24ce443e21590c524d303000805b45bdbb0e03447da1360ac21ad213a6027bc06c3e10587b4e26967b33564b96b530a58e6a5a8051ca179fbb5547e2e57a0d43287cd018565b6b75ee05ae07b8016948de2c4ca919a920991e025149b093a8c2fdc9ff78c7cc9406c25da988d7193b2bbe45cd379fed3a6ca7c322b05e4bbe017f1f2fdd3b2dff9d641e99a3d566d6134550196467e4326a20f8d1b090b8009c3633d80e776b2179d52854d461e1a8929d1e5096dc8743cdd1cfe7ca31ae14ad046ca127e58a3097e81c1dc164bf8e17d4829cd8de665a551a0b1de6c4d5e094ea71ee568863068de987841de2327e4b70d7b87d846fc1e05d1939bca72c93146344659f71332aa2166e1ff3417077cb28429b10d1c22da1a2ffe7c673ce6ce8fa1e66f22b1e28fbe63a915a507b095a8aab9bd16244cd369d39451dbb5db4145a583f48c2d2a7365424c4e77ad4999163905a029b4ae74f9a8720f310a7d4012a44aec6af7f92c71f53f5e9a9d92bb8329157068338468af607b2e87c5e3a455459dc62ecd7a00fc3a18cfc04b5e46c352bd863720b26a9369ca080274574e2766041555b8cc21515907e700c78a89e0f619a757e999b034773ba04951e3f7b70ddb668d91c8c0698815e16abb03d03ca9813aabf069f6ea2a1583eb4ef5288d43257e704ae86f80404db7822f605e894c5997382d6adf78ad1d86fec29589e76e887142ca7caf53df09fd1390b84365b0ba89bebaa1aca0fc5510538954961b137296bcfa152db73535223a74a4ebbf9d25eb30c726e450229ec2bf5a7d06026856c6281c0a62e534a486ea8f80fd2ccf5356a8e50f54fd2677db304d5220fbfcd29548d41b91a9971e84594ee5bef6577bec7127915eb0d24ac0c82b0d207e565d5b130d4bf2f1b50230b381934c79ef5cea9f8ec62c7344b17c91b3fbbf0f85753f70ebdd44d7629623304549ba870cb87bac1b9343d114855e38c4d9ada3d145541990aeb857eab77e2f70e400ff1a8bb12a429b3647749339e20a044d26bd685974d10be43e38266dc96e9c543670040e9443eda9b180d4a8a7d95f7d05ead92a4ac3d23723de7658e57e3d5693a945dac2d5962852c65fe9eb597ea9b06b3395f5d1132bc756c03a1b5da16d1e87705053bd9ce85a9d73412ee9aab365298c5cc7b0dc456282424934ed9746e084c088c62ce9467c5b0b06338b6dd9215b763372b481fafbabba955234d57fb24d9e93bd9e06afca8855a6b057f998b3e58f3d5902dd95cca4b81591a7bd3c8ce56b2915d27dcd51679cf75d43925efb841a040bf357f0d0cc86abcafe2456937483f7d5b58ddd0dac538fa3fe2342ae65669f760a288f9f523bbfd1e24dbc76b196aa82164a287a63a2970b881454a346aaa0dec14f963cc01bf266e801828d44584e73d3b94320fcaa79691c947539aca8a24bf6d9c9c693876e5f9cf7cc807051bb4d4c21b53bd5da722bf7f58a36b964d03786e4f165e04faf96b68a74e0f09a628f297cd9c348275c32d1dfe014aedbd76714faef4d670835d13d71bc14a868a5249d5c94c8f9a698afdca73b3a0b8808c4ed165f9a5552a9774963112457136bc5be16f2c70510dacccbe8a8dae3b917518f6af4a772d573e18b947a8af60a601823eb85ca0d83d429d7ef7cd186b6f555203a9729c067e422178ac293c12158962c6c03842f021ac12960562090d1930e50943f6b202ede345de177ed4ed3b36f485cc931ca5eb7bb0efe1be5bfa857a41381c089f7c31ab085328e55aaff6455cd76bdf74cec0ad2a706c47222ff2aaa7de08e034f88fdb6c9265b4a29a59452060f064f05e8056fe9929f4ff23cb951a8526506cdb77ea32d50a8e2350d30dfd61da62ebc4e6eb2a432f6d8715dc1376b49e5eba796c7d66bcfadaed88e55d08d22ac42d349a0c736271980c342bbea6cad5334dfac3fef37eb37fdeb60db21ea53fca9befb767e4c807dfa1011ccc62113037aede8fa0875db05e091c8f49f3a6680e9c8fa10127c18e2c310128c48301f307d82286c1c8eeed8b4b3761405c2911d7958a2322a53b59487274e4960c4a06f735d8ad7a4d2086b243e3b0ce86bff94e8db98f08baaa331e85f578200d37ba309f37712d276eb49d5f1f873c276eb2e36055d40a03abee3766fbe0c76bbddf62bc6a027d0d7fee3f9f5f99e6f9f3fde68c2f6ebb5ea288c18291ee79194c18cbf30e6d66ef7495777dd5eaf1e23e98e3f4a736b0783578192086b6b558cf17d0d773a9fafa3752c924915063d12104186e973249201a62318d62740ffdb19323d86b5adb5adddee2b1d79b0c9a0153fcd39270913ac3e4511767392f0ed38518281528abf5efdc784f9b583bd734ad5ed18e38e247debdfce6ece4942f50e6e9500d46f55013c6ab09b9384e954ed2f65e1ef18c3c4d7516b521b7c2c4c9f63d57427a4d2d26eb77bd2a25d8f419fc4fea3a4a9ff589faf02d3579faf441f8fa41d2140abbd38574defaedbbba1edbb51706e551d7a77ea2675e10d476ce709c9b945e2276047d269cfdcc20ea356af7834c13a75183a9f9f801d61d09fec30ee6e97f4934713b05787f143fdb6dbed7e97f809e01146dded766fc71feab8dd6ef7e16eb7fb3a9223d8ed76afa34ffed011c9d365afab4f479d12fd3b924c33fec77a0c134f3da9baf730ee6eb75b7bdd8f1d91ee6e8e2aa04e794cb79a3e7d822e9474da6eb77b3a6a65ea79a14a7053880b7bc2f0525532bc33be513c69664aa03ca7f9d9c0565a6b6dc38dbe23377e7829a648c1a1e6879427301a3b8ae8e0338315192bb12d3562778ee7799e1785a40a4d1db4a2744520ea4bc8961874e4889385871a58a21c3132b342738351394dd92f1b5821f6c2b2318354a13903121c7632c49adb9c1ee004e3032d8d0b61d6c4a0e5c0522bd346cc6c5d34ba72be72846c25192a6709c207f69ef09495f6d219e79c73c6b203c9e76c85735416d09c78a05f727659da861cb6160491fa9a210c980db46e121b1ee440eed54a6b1cd3ca87d5102bac2dc46bba57ceb060396d3569af1abb26298a95f31496016d870796730e2ffbb53515f62009db4c59e51ea2c072ce5987a5b185c5c985fc14e2c29e708642e4d01e58df7703dfd05c36ec9448648e95225934cc98c1e2a4c79490106c8cf1d8820108a719dcbc91e2c3cd072288e3a508950f1fd28cdca0851b865c2a62419a3cc881dca93cc881bccae9172cb2b04748539c1c3abc6e13d61286858700a283e389d5cd063872ce19890ecfcb996a4e7d4d894d8d4d954d9d4da5e170ca0ab03a6269c8c25b6bad776455a1b9c585e5c50eb01c84f7de7bef1d984ae692cab173e50712ec39799003b9df9cd6749855c656396e6c9db5d65aeb2f3055689299e10c7ca179d72d87f94e799ee7a1d1aa42334ad797d818129ab29c6f50ac0de5fb0a2cecd13da692d868c0f2c2ce9a929c73b6a17b6435e51db308980f6b15e2c29e30d4509e3170669f51f3a4425cd813864fb58a191f39e79c438be79c330e1daad0d48ae2bdc0d1e520543583f2eaaaf185c52c3b612a32990a4f210085302d64de10b1b1a6254d142968b059ce535e235a588295c52a889919179048299b52662fa4d0bc6c28d953daa3d20526c4ca856bb5ad9688588098f51045446dcdeac992303435ed2b2aecb1c156b69293af88e11757c6c23651c07ec0e94aeb41447b29e1f182f274b5d65aefc0aad004436676811d5a0ec218638cb1a8d010c5a13144091324374c512f4faed8b8e0799e6725aa0a4d1d3e866029c9ca19b0b2b51583b132ca0e0d8d0894a3acaf7cc656b87a54b3a979430e0f7220c7e15b67adb5d63e7455a1f9855ff820860b71614f185a5d1e39e73cc40acd9d33946faf365f61cf5c43c32c076160a69cb9b141a8a992b3508554716ab86b1ae7d9b5eb8aead2f1f365ea862e555e806839d124376429bb6d74641bb6daf03ccff3920ca942134b49d6169705926091e2f9408b0c8e140e4da684d1209f3d0ce41d75f5ef08f28497f0eff2b8bf8bb3847ff4e6e23cba5f0924eb493dbe9d82483dbe470bbe5081e98d88befd13fd8ea4ad033109e7b89194f1382fe15714a3fc48bc263cca8f4437218e4b23584186fbac215c17dde623d82b562775fc7a093149c9fe2091257cc745d1667331898fff884a1d8ce4895157bfc7af9b709b97487ee867a965f7624fdfc7c7250fdcdd472499dec74571e90317dd821d9081c293f8b8530a177d042b8a4f7ee45e41f71e9164fa1eff7c4423a2bbb8820c0f5c1c771eb8e8e2e89404b799dec5a524db93e0760a1fbf8e134d8ce4f5126f93d1236adf587cf2230fc62437e711939464bc55a2494936075d474c02475dd55510c484369f7f9de66c5e08a4aede4692c9366d22dee24cb28ee9cbc84cb8aad3e6b3bba7064d1ffa219c4fde7e7efed56fd4d5cf9f4f1029467decd99132fe3ce72ae2cff3a8ab3bfee9781ec9251df1c98f76becc32bd9e5d0b923ff1b3fcd2f2dffc6c37193b62f6273f5a41860374c61de83ba3d3ac21507ff2a31d9f479febaaf6efbbe988f3288b641593643d2e25a5907dfb1e5d909d8e3094ac2efca414b26bd7a30bb2ef11468cf0a92e7c3a82a54bffadade9eacf1a34f7d6596bd1a2e0a6aec1f036ab8a15412b705668c807ea4655450e22fa6e5a67d7d1c93fd6ab1d9a12e2b04854837c070d4109f5a894e2b5ef3197dd8eb80d4d09adcd37ef8f7e2ac8a3cd75f5ef6d86b7f91fcfed5655648cb348a9125dfbc93e9f29b7b5bbd8a31e993e8be4d267d72299fdf6e59b8bebd86d48b7ce4db36f6dc2fc3cdee8cf1984abcfb086b5d65a6b69a5420ce5a0eabed65df53beae8db71522f59ca1e849f6596acf7448d5d5749ecd5f55d7a6facd61393741583fe2dd9e6f644281156f0a044b0ad306b089e7b62f5db6f9deff883649dcaa84cbbd6b16fd4d5ab49fa4e3576edd397e8d2d31208aea75e7dfbd6d37c5bd259cf2fd0e9acdb3c46f53ccae0698ceab6915cca696f73bc455db535ebea6b9cd3da27282655a78e41a48ce9d674c4baaac017d709d66cc23c81aedda7a01e93aae7d18278d7a01f3cce5183f926d0f4eb79c612b02f62d4c7a3b52246ca4bd8b5679164fa3c7f89f41c8fba6ab361512242e8ddee0f21f6bb2f98cb9ec5189e5f18d975da2df644a5f95a544af176d4d5af172ca12255c7e30573d9b32761d7d5cfe3985d571ffb1ec9ea7be9eb579c382425ac0ebea83d385bebf883547dfcc17e6fd97707209ce59b45cf27b8f1c6f72798a95ff10af200f8595ea97aadb7f92dbd90bcf5ebdfce0ffd10da2add493afbd775f5c9eda0ef7182255ca4ebb691b479f5adab6ff36f484a9874c78b048a4950d8595b5b5bc339bb4dc4f7e623ec55242fb9f4365b92aeeaea83180841ffaa67723bde23597fbb57a3fc0824ef7f1ee547d701e0b8346b08365f9a3584ea37af3e82ad22769b98dd139564bc9d3f95c4a9777cd30066429bd5818b5e502e2d67470146418e0b6fd43eb2d38d58bfe3dd7fefbd3731d6628c2fa698e28bf1a423a65c18638c31c634bfd9b1d65a6b6dc5855f3dc6feea2754b7e35093903ecf4f33326d8ad0a8b1153c61da396647d2da91720de120fc7e9657a27e3a53a5b71cbe09e4d488d953aeb20a98a75c4fd1beb4a2e4c96dc5aca472f6d689e8eeff05e5fae9942ad13525a0a74e9d9e5ed15987b2c2595ad1a4a6547ebaf59b751c96b78ec2ab8a59768179eb406fb73c9559a4442d28012ae5afd73bd67a6bf5112a9d32595c914e9945601d95f653b7930575ccc23781b8688b4a43389d1a992c54a04e4f8dcca2e92c54a05366d1747a5576ed9e725d3de59a2c5498b3684af93b2a5d9172cda239d4249ccfc34565b2983f47af348474050a55b24c21aa02852a5c66d07cb2443f4b32459e0ca7e0286e4d787f966488fc0b7808cdfd2213e47159645ad0f2659f40b4524b2bad14db4aebc5bbde6a2badd4d24a2bfd284833ddd4a3975e5ae9a596567aa9a5955a5a69a5d8565a2fdef5aee096c5695500e66c0ac0dc5cc19caf259c787bcbb9bd53800230972911270073db04604e8f71a19edb24a802fded2498b3360198f35a94a08e718d4004604ed7b1253c2200735e084ebc70020463521f70d3e38131617a3ae0c5c381314e466c80c4cf72cc11129ea701132898f8598eb132918131347830b07381bdd366a72ab7b0402de1a54405c05c1633a5870245ec1056e5cd981a54da1ccd29b4ab5e7c5759c504ae18279f04c05cae62b04a44404c90db096272801e04c09cb63c7378906e6b6e1e3601cc691f311f17602ed7305478aa4ac881396db5741e400298cb340c92f0280c91efc3f4b079de083a57228491d2a9724003be2b068039af0518c209ab588039afc502324f199e2a05b0b02bb6f7c5236d2ac09ca76d08604e7bde170f84045c30595870002330a72f98ad112c30402d401198cb3e477c88866e7845000d064810cf95e709008c140fa90390d33784131e01c008e6740827bc126d0827243da7c9f4785ed61f8039ed0198cb148c44f103e6b415a2cab6b967f34e8039af0af1e46301e8f916e96b1325c09cae42e0f020096a16b807869e9e1c2484d8f1d8353b79841d03c32f60b71d9d9fe5172a3a399d45ca93c57305f2fc2cbf64f1dc2e7804ac9a5305b6d9b6ed67f98588cdfba263c4fe3263a785ae56cd56a9c837a3e52b15f866b47c47941961c190a0ae6739fc4892033956a094399a5368d35ba5955a5a6da5957e14a4996eead14b2fadf4524b2bbdb4e8467b80436442ec57af303ac28e9b2cf06ba2a220be7a5151d50f2222fdb3f4d2f57a0f81391d6a855a679de990171bb6b641606e5b2f572ee8bda900c0dca640800ca06616f20bdad620fbd9f8de3aad12a2ebd7165e6ab8c06f9de2aa21604ed32d04e6b4cf522c2dbff53a03055dd41643d54bf3be14b616f583efbbddbecf368bf22cca0e7af0ad9847da5180df9a2fff5c151de4b107abe63ec102b7efd58fbdb5ceb3487b9e45791669c7b328cfa2ec9e0952bf76b7534509d0451e730394313f67d0fde1d303e6b405261b1cb85c59d2a6c6d8d9d19c42db00604eff6774805b058180b9ed731655d0057d17d6d6eab9972fb5950073b69c776f60b75b09f8a9d7122d7c6ac8155ef580b94d02cce9902be41971afc29cb61f0f5fd501c19caea012f08ade28a8048401cccda2ecf7bb4734053df75e679db5cf599447bbb5beaab3287b9d457a1665a7b328fb9c457ab4d9abb61f90efa330dcc03c6e16dd3cfecf52ccc757c73f4bb12a1a0474819f7a16e70b600e8435e1ed672906f533df9eba531f6bbe17d605eda12092756c2faeb859441d378ba6634ad388cd781223e769ff2cc3da8461664d62c29cc48499691213d6252c882c61c2a4a6be84b130f5258c888d2f6147a4bedc301e5e07a91b0bb69f651891c79561476a7801ea92c5a52bec8bd70416c407e6a50bd7ee82a509acece2e6757e965dca3ce946f889cb962d624358b0167bbc25eda98aa5a23df8597249c24506babf608489ddb834e9b02a3a5c747e965c5830c285446e7b5c452969e28252a48b930b45ea7a9003b933c1ee41976aa77af47ba9950b632ebca1f1264d7339a27180727707b23f4b2e3c9e74231c85b9e8a0c1858a06d63f4b2e505a3603669415fba8dc5256966a4358f0254be811e40895314ca444d16052394790148c703831c61ed2788c4bb0a7c74d47f88e55762ec1d6bcf7b30423b36686accc6d8354e0b2f9da7bed9b28cbc6a986383acb9e565c7aefed962599bf77a82b9ca11df3cecfb22cdff6b32cbb7096212a5f52004291b5660c884a0a463e346839928291d84d6bbf9e97b35d6d133ded83745d7b76d6a09bf6fc529c8fe3dcc7e636dbbdf4ba09b789267c489be3fc2ee96a7d1f138e73138e53e1a3a5ebe95f2d5baec7b7b82392f7775c4724975ec74391a42a489453412848823ce15e0e020c10609ff6db7bb494bdcd7b2ee882e9716e13afcf6bc9d0b7dbdc8adfc5b93b6e0cd96755412fd5d9b75e7dee7105ed19037a9c56c80a51eab75e2919ec2d3390d82d631f080a7806ec50ef06fa8e488fbe0956a082db77443aadd075901e55318b7e459be79b45ed37f18a3de3d4592c5b763e2470bf7c73c6b85c732ac0569a53bbd3715352ae613d39c5f0b55bc7dbbf4058fdbb4048ddfaa66ef6d55c830098945d19fb414a199b1c46787864d4a2e6b8409416465504d60f31305c3655a9e6e3ef258a23809fa5da1335264ee4c08173f3195182e7629c091d520f4ee40e7676b5811fa4f8f974ac93f0504c5b7b6830a76a3787aac6d69c1d95cba91116e1b4d3ce9aae579a9a1a358d0cca2b2dcceb428b2a02088e0808341f3888aecc1e7eccc131258e952c376c1c695d706940e0f8a8d1dc1ac104fc00132210e44035688407a469a5657d0e923c693425f4668892064395b42a1fa8421ca449ed90e694b5c624ce12375c663a1041c31054c2d42096c3161c80e8c1ca13ae1bf8a0c4890d9868e98065c30d34fc10e222368478089220497c34b1dad2c1c3d4912828729ca4c8d975a53d6944e4240edacf6aadb571cede5a3b9f9c5b2b6e1dbd1de28c11051152a15cf587195fa3ccf8ea1fbe5dbf275010c484d6ad6b3047b30e9b3c59648c9da4d41bafabc0f4d7317d4ae10c29e3383db9b3d0b6beda6aadcef4aa6489b2d8fc6d60cedb1ef69c8e6412f6ebf9d314c479dcb388fabcde2c7a018b152b40568cea0aac2535d850264c0d607b6ac43d6dbd600398dd0b6bcedce00104b5e3e7aa488d16d09c9419b3c58685001421bcdcdc20062e3548dd70e81143181c9c68b88216150000881b6ac7d5e981c90e438c64e192b59f7a44e07186eccc17133332ec1aba0612235fa4685185d94e24ce3491e18c5a94263a84d84d3ce8931f3eb2667003856ac8a6915d20a64717acb118ca7cd93376806ca95135264a8d72ef78ec10e04401b91a0325e4c99a138979099b51840d5f566a1e600992034c4790afb1393c3e48116707355b7478128395b41461b45a984104d85a0c7276a000f2c4860f1d48ba1479128707cfd65690355a3b9098ed008747070d086288ac356072680305ad040a2e4dc2d8a80147899c227cde802468c264cc4a0e6590b81971f6a19064ca922142e03809d2c684561a1498304b98e4c06687b766876d6681c34406316084f8f2658699587821082a24438ad090a5e644106b80f08222c30d333748c3234cd3c30b674d5ac072068d0e9117998eb4af1b67dea8e932a22b4195cbd75a271065b26d88737c31c645583dbe3d38b28a7111548f2fc618bbc9222a52c4eebe41b3d68d9bc73f4b37664f863e2767a218c29c513833f33c22ced0c0d24d0d1c4432e833448c8800c10043d566ce72d04424c428c4b90715a0c9bd2900110539d33ad3218a5e7b56c313d190eb40672c9cdd78d28d6adc13fe555ab3ac01332b239a5aa39bf4106bc8f29a34529b524aa9d2b54e73e02caa3e8baa4fb1cdee6910ce928dd9d7323f59cc59e267c926cbe38a588326c566061b29363b9ed8f48022b2c126091b18b2d7b7066dc6962ad9ecd03f4b363d2e9ee19b75d61e280be41ac1b71cbe9f659b27f98631c6e2cc5d2bb6016b436593f859b621a36de46c9d1fa4fdd6ebdb919cc1dfa68fa8ca66d1c5b4379e9f659a1920ee6799a64a47fc59a639b293a6eb71651a227c843f4b35509ee7d93e355b267e966ab04010d4d9517306809fa51a2c5fcf8d8afeb334737adc8d8a297e966633f4dc48902041a2c7a73413c34d16277e96663e3cce6ff3fbdebe1d4915be7a6abe59777e6e21b3f138141f02ba6e10451901114519a1f1a25243d3c44a0d8d112b35ff59a2817af0675916a70c08b5322a6a6550d4ca70a05686835a190d6a65576a287e966536ca769ad2595429d2dded763b8cabcd741a00dfb7f43f7cbb31ea67a46b2bb53adaf588ddd65a9f1819ed8c88661035116146040d22a7b5126564b839738ce600cda13866bec8ccc0b9beefbdf7cd073fcb3354fefe2ccffcc0e5242fc1676a88ba6ece5c455937e31918a2dc9c6921cacd191e4e6e7269268d99312b381c1aae88331ceeececccec86eb41650ee4d8882dc847960324ab01e776ef55632b23d3579aeebd60ca64b995f172a30c9781722b73a5ac24f3fafcb3249bf2a41b8140d839555427edb573ce592b8cfabafab5c5bdf5ad935557bf7eb55043656988208208a3216ae08166082238d00c71e3bf9fe5103b3321ca6895917143e68ccc1632568e944132c496d9c5f7de2f7fc9b4fede92cc87bf40d59691d1e17702949ba8c4eb9a2a6a1022c50810000000c3170000200c0608244194244110835cf8011400095a924e543228a10444a130140c8581280a621808821004621004a3108603599e4379006f08f625a52f948835d9a91cf4e87e805b4d6f4df601d52d4ec33bcf3d2d3cb2ef4fa9b91f13e453a7286cfd7e8fdac537da566343a7491b1cc373e4b609d88932d64caf92684f9c1034e1d0a249b244afb01cd0faaf5e890543d89466a24a107bf452882f2f7655c21e63184f5a1211b5b7854fde71975188f7dfe82e7626de93b73ab7205a3e88db850b9ed2700fe052e8227d43892d0f9e0a890df5a8292dfcdd9c319a368becad0b221fe3d33c420a543c767b20ddfe5c764e092255a42feed35312f4bf3144d892cb770951a74d32648585e0da50e8ab43760ca2e7ce409b4da4706f4b8b06731862c939f45b5a5aa71b3e8867c6f5ac641db00cd6ce4e1b222e12dfebf302f45ee3e2d9ac0cc6ad6d7d4ab823b4b06a5fdef9ad22c8adee66d72d36d8ad786c782661414b245898c148db51440d011450f010ee8398131faff942ec5208f7e5ef2d1ccc21a262a20cb37a500841a3031097ad9f31483a2882124a7d18101198160045036a53e505710e7a3168e594c5dd7f64d1398afcdb0fdc23f5ba786357702997c9c5ddcd6d5dcffdded81ddeca7bbaf9bbbd6df7bfdf1bbb83b7724f377f376eeb7ef77b63eef0566e626a3f0e16c337fbaf1ffa39f18cee60f6c5246bbd2b22f01f85bfecebee5079eafebd571fff9aad298321a14848d670ec65890022d8cf7d4f62be8c0b3618661945fbb2a405c71d2c938fe25d95ba286e9d4f2331374906c68f5be2daa789e8528d054e053941107c14d5c678e05c3ead5a18ec07b3ec040230766313faa8069b20c3fa51d5e9eb27931cdba7796860e2f58cbbe8ecf560470f7310e3cdeb508a3d87de9a87aeca0e102834ab3e11b9296e0a3a9b298010e095f65f4ba53c2c2cf8600b69d2458dc159b07a96aba364a935308e1d0268d2e6f9bf189eb43cb4d61926a1c0073c3823cb6b7d376abd199cb3532de9876240c4c7401d9f8193c9b93ddd927f3807637c0cb07eb8e2639ddfd99c5bd22df986b29663626a20a30ec9ce7826e278953010f7f2300f5556f619473fcf97638470f9d64532c1b2e142876991e660667e5105037cfacab5670b835c418e009bd1fea3aadbc60b0118995b0b90fcd06d804e1eaa2005c4baa5e0ec0a7ea697e289f063f44252ae61e92d5069a44c3f3c0f2c192f8fa8edb0c10b20be72a73b5ef8c765af2c9941fc0a8db7d2d321d8214fe2c548ba653ec3cf7c25dba3ce1155eb54748f790bec9e87d2d11f41e83414c1a35d1a17c99e47ac3bac0a1b3757a0258a3aad9b1f0551b16ddf8498b0eb2715daee53d45e4772fb3dd9fee4368de2ea00fd45bf955bd2b4dca24bbd71975b113df686187fad43635358bf0fe976cb36f3cf86a3de28fc03cc35f141da38c9e6450a1f4081578f3f04301d68b7d5a2800960bb15471668714417bdb2039d7b2d2789f11ef588a2381ec7f122d7eebb1c3157087cf1e884ef48f14b7a032a4e607fb04706330273e0dabb033e68fa6725ebf0962426a4d04df6f55eab0db04f1c406dfefe849aba0c61ea22ffb307c79d75940ece2f8cea004b9826b80a72533d1a795a3244c3fcfe326120233d650a87a3b4900d8ee18e7b59a8f7ad35e513acafcdf96cc1a5283cea440c46a326f85bc4d489b05d0de1db35b54b76e4b31bc76b159c3f7ff51e1660e9e326cfea4e88e5e376b2152df47b7386967e694e57f1775a680f416f8bb63f83ae6219b423a1f5739e91e0f645fb4b84a2fba1039459fea0e70a618044bd52f66be2a7c6b2e2f8b9adf6b2a3fe8a3f2f3a7ed93d59eb3fa9eb137a246f69f18415f05ff76397fecb955367a248a54519099e6bbd81a0b21fa5270b0b85ff6e7d993e6f75b7f67aabd8f9ed41485f237278ade530d445bff18c75b85ff7fc2f9de27be68f78e665fae71601be0dccdb7ee91117f18fc46ee142690239f18177ad42eb53847210a930bff3a0d56d72547cd9fc03a30dbfb49dabf82fc7bed842ea0f92e9d0f90d41b320c2e329d4690cf682e8ae47866d63c0c00bcb07237ebe1a216ed20cd2e9570d3efa86ff968e2f962fa923e2b15671157ab70c8fdbaf07bb229e33c2d132922d035f529dfe292dfb8956c26c632bbc66fcb21e435e7409d3d27da04ed2aa043ab300a267fedcf7a96ee874bdf6ab1125ef22a33c8a36cdfaee5bc0305c94604e52f2a4da592a6a59c1f4ca2c583f0c87459c07c344b4a48de1dcfd77d0f08c464f42ae4e62002637cf83a0eccf104d644ec545c9582047d19b027738d00f2ed5510b93c27be604146f3d95e207f8dca8eed6cee43786779a57831fd86de207a99c683182ee11bb6e1acff97e521abdf913497f063ca2e616dddb6a2bfac013dc1a982ee576bf4565af01f4cefe7412c19ad9dd912fe737913110040c4de2d85ab80db42ccab34779d582a09e8522a70104c8d88d12751c020224d481dc7651f0bec65e745638835c539c06a90165d6def00526e1a641277fe3d17aad37c3229f345c2deee09107fd449ff066d17201a95e194cfcbed970359ecbd949f8a39a83fcebfc10b75d046603bbf8b83f6dade6e002116f63d82f71f9c3784abc1c3f2a252faeff43631d7818bfc486e057c117587713b4b5b11c6989e10ae4f565520ef49d5811721a5e2dc8033c90f31299b78b83721a3a39dff6dd94a441374635b66b3ca41fa23fc105447415c0e561e45bc2755ea714402b7e2e1bb4dd55a6866781b6dcf21d705221bc764621fdc95844111d660191010ae80eb3170c3a47aefae9de817d421010892f9af0af0086fe30884891fce2f9f14f4f8cea0edc00bc96bf4a3e32704131b6aba03055e1135c25687890a19cca4b8b63f20e7842048daa4534863b80e3d39a73c03d12f49e8f265262a256f36651730e8c4872ff782a1200097d92203e24e1156ff35937922443dfac89d4b6ec80164959c4373830417aaf5db1ad5df4b2561695b89b5dae157857c1f0b69635107800919e869959546152853edc074579282773d03043e8f9ae5d1e5f4163700e5441bb6fe4c9de9a663dd70d03e7b0915db4a6fa5c582c71db6b0a0948c4ab3b4bdf01d249a5cb5b38dec3da6f88c9e2186f95c3ad0425ffece3e04e380fcc166865285e67d20f4c6e4c4addf7c05fc1061f13841a2982ea494a8354d27827790d5589d111516ae393bd6087192577c8d57dc9969cb9825debdfdb12fe70b5134ea01b85b7f14ac0bdacc11adfefd5baa661de989898fc06e6592c00e29700e0b32ed9bde950fc166dda832ad7ba4331239a281e25a61337fd5feb61900e036470920aca9e2d67c2aad8cf4727f4e613dd3f02c7f802c19318df719d543fe6d3517ac181a6a347b4ebb2f9507367149ff3895d96740aedadbdbd2f44066c564a8036f731457f571b4c0fc706b476c29b772ab2aba1e8f62f9d43a716fc497b602f17cb4708555721f80ca5a46a001f17dde0fdb01c7b771e1f02d3cb73b833f601f8d5d108c43fc9479017dcf36f242a7c4ff8639b13585c9cff49e3d24fab2e47253d7f39cc9a57ad2546d5c53fc6f9516a2b14f1c31f832dee4196f1edc98d6402c949e3a1e7cee8bde2880bce3a582f209ff609c7f1e285ba2c60c6886b82d9b8558c6120451aeb7bc254adc7afa8ea87ac48a52f2b949173130f1eb32d208a10671872194d3cfd8d79fec66015f1ac3f384426c6396eb9eef3144e459c539b68e9fe79d8f0295c504e78d58a5e0377d513000b0d28dc92b67c765a906168544ce77bcdc3b5ccf06758c27c1641103c5b86f0f5483424d44cf614894a71e02801eb2fa757bbd5c0a661d40047c8752ad9087c3aa2e42ea5990d41a63efe3f40e15f44b2258e3adca0c7beb74b35873a70395eebb7b138ceef7e8c02f9e26536f1c4ee7234bf51034ce338f65c04fdc1c57f08f0a72a884b225e09833430f5d2565566edbf0f28f8d7a16097e31711f9859e7c9815c63f17e6f5e4c8b3ba1ffa74e64f602ce27fd408967b8d11264c8b0f283fbcaf3a4751981e45d2ede514808974f1599df6516e71ad2c8a0ede32a0350d1abdd6d238d537594124f384f6dc7bad8172ea026a376b5d4ce47b144f6b861249c80af9949c9807850ac769d6c7d57bb00960185c899fb79acd3dcd896756d5842fbd2937c437d3413d517f06d79df13d9d0a82a310577f76115cb7ce8f183a0488c29acfbb2270c5dbb873d63e651fc08a0a2ea50b9300430fa204f4d527c93bc13a78f8b181254304aec9919c15a1b27cf16e80fb954c301857b01e7f438effe7bd7d9f1d9b77dc9d3fe6ff58269d59e5df21f3bcf57f2cdbc4cc43bba61feaec9b6e5e360ecd3baec94f689ca7ff694bae5b1042127e91897e3842438bfb517b16cb48c9194b7d7785cd6354bc336d879323a2355751bf1d66eff21d7393752a040f2103d5635c1a8ae0c790ac8de30878b64ef22a5bbdc5fe652e9668de6c7744b258d21e2e7e9bcd199effd4858c2956fb182175e66c579809dc0b0abeac765d1b637818b6f4f32510c672220788b7a25b4e2bdd2e430f69d893881d4ca51d274e36514a3550436939f2a9c0bd90ec3c53fc63664a4c3038714a5ef0667cbf5b318b15ca28eca3c3c5cf206da3273f211cbf2e9f8dbf5bfc651ef5021145594a72cda05965ba0d5800692a8b220f104db55839af75c0ceaf16f4d499025f029762a8276271c3413a21ced80f784aed850c286ed166c69744c0bec04b0088202dd3f3cbe6a7ddab11bd9e4919eb08510d48d32638a3c97d01eccf7aff0d902d7935616a35392fd9ff1ff6c3d0b05bc362c63d466f0f087015abe01b838d07bb5ccda1a6c653a6d3d912098b8414c63a9bc263260a889259724a895f4623008181bee3bb060e97fb40e9a1c45f92876d28281e855352949800f2f41410638338aed668bff597401d05a4b7132d88b4494adea600b8e511fa8103bc62143fffc39ba50b69a32f1811fd4f05c3fb3f45e312e8aa374494acbdd5ebed202d3e5ad841e35568e081091c1ecca26a4fe73c74c644301117a3faf662b3dd8dd49055d05b1691958eef1a7cb3e95455d8712745743d274070b67654a0f242ba1e3c5b7d94333aeb1886256290e8b0383326fac8cf4d4f6855316046979c9c705c4f6d8f85dcae983952f8a5a37466220985a8db6c9c79c81308fb1603f8afa5f631d01bb6b1ed0910498fe369f44cfad48fa7338dbecfff4aacf5b4af05bb3ab2bd779c46c139175c39b00d03844580f37bbd0c3974170a42ff3a77781003b754ffcd2c21e82f7461f0522396e0d3592ed83ab75a7ddabd88ed66f08e5b48c6124963897a829c8792771e13b8ae9eb53f7d2d3b05188705678a5f4a432cb55a7674f5cf23d34994b377aea71cb9c5b570cdb2c60fd22103c79908875410eda70aa732f0b9f997feb18761c70c9362f0d8ba5294b580f534d3925f35b0e7d3d9a1250d7f05830894ef2e45d06db64355b1fe17b0a388429ad61e864c93b72a1ee94bb5c48c02941a578ef17a81c0c965375f333dce1d7af1b58a1899265dfd8d866268ed80ddb500f320475d38a06459d4879be976e8fda7f657846a8e822293dedb4e89a93c7a965e48e21b58df6d4f019480120112204db01082eadea8d3587279845f21e9fca1ff6ce0425adda94afe106f2b3089ef95e088eff329b3d69b1e68ae5c78836af78e2af38f7bf3cebbffc7ec138bb4cba69fb5fc3354438a394d721b5b2bb9218d98409ca79adeb7a8ad271abdc95e036a34de06410d5187e480ef7719a17902fdcc970e27903b58d10171efdb31067d98f72605021ca9ba6fe8316d59588e410edc4e21a5fd58687113823b94f49b6f8e67d06391640dde45ece52890794aeef96927d9c6f826c584b880d8b25c0702b888558a8896dbad6135035c70c2826bdce0f8aaee34beba7df23a229628c9487c9b814fbb34384bc14e0f9d1a8b25519c376017ea0522201a9002ec2f0ba8b1d98903c7ce8387106e0485fc0bf9a25dc0c3028ee35e65d53e7a0348892393e599761292b3b4589d231998ce01d7d70813711dd4e8543bdd9c631aa84d51462dd4c85dece81a6baf4791c0f0c74fd7673827b6e8068f4313b96f4006b7061fbd7e7bba679b3c6cf1a3984d9d318b2faeadc4db92dbda621a0f8fec3b8887fb4332ab5dc64aac7d0e9521cd3a3370c6867b3cc5846a21a1649a76734af2ba22a2852ce15b0ab53b6022d3f6f5c2c5d52f6d20299302e737ab6aa4f788b785c19fdf6284ab9bdec3d55ca22c9039e83a809b2cae9ca098013dbf489fc3b7e8a3fd68ad92a2a47ba26e478d49f9c55c0427a9e2bc970e8c80465b30ae794be41c338289ab6102a4d108059e03500fc88a65b5307f4efff528134fc3bf3ed0b3f6dda14faa9a5218e194d6d2beeef229795c8534313b9be8a29e56f3d0363cef8814a31a13b873615f56cc4c4ca0cca8013ea56a1632e52de396aa9dab565b15538221aeabdd3094e22f9554fb6d84e3e2d39fbefd30adc835b8d0b9b7b96ac0ae194b4e2612a466f1078bcc59e50bf17330882382284735daf404e55a5e710cb2f92e8e21269efacbfc9171798ed1a39ad5bc23a59613ede5be283750d64b3eb62cc2b49e8201a62a2a3f255668d4f75585913144c832becdccf64a1dba7494d94716e6f695e73185f0529457e7c967493cfa6fb365c50df115c33aef0eee52c07ffe50384a208a9662347cce083e28c48bd4ba36a9f185f4ef91a3bd85fbf97b6e1c96b10f9f59ce03468035899bd61f9753503a4d74105935ea8c2cbd206ddb97d5a1fc1f4d4558041f427a0c8219aef47a1e05109dceb79e3eccf4090d4520f599ed31346247c5aee8e09fcfdf8b4d84cbce98bf32def5a5c2c455c672ce30c1f31f2d3fdc21e5be3bd85555052d991f125e4509826ab9ff190ed51c7b959d636456f20111a569fa29075d44c58df552227a5bc2815abbca36f535b5ef380d14ac95826688542774e5b7bdd7f8675e6a0e4e9ba85368164a4f508023811c835df08c85fdf908c4f5f5c099ea6225c7a1380914a33c65c5287e392993afc3eab4a91baf82c4947ce631d09648998f534f2d2780d4f4e8b2464cdabdc7a5ad5995735a44b080ab6b82ddab0f4f36466665929a9ff34565ff06159becd0f696d7ac246c750e36d7a6f7854b9df58ca295dad97a2066af1ca4c706b341b8cd5d90c5c5dd3f85042707b66e47405c19ec9a37a7e9fce015207a761c932f11cc6aad441341f29dd6b6833d490d4c6437cd36947fabf40cf55ca5888498d774033adab5d92e766807896948cb1dd4029d3278370a24e8e28c8884117195254238d531f6ddf04d634f8239745707938c581eb95658582266563928be82482a1f22c86c4994a14c3c12a01d70d827703e090b0caabe13f34cee6e1bf6ce3747ed3835589e7b1a0e4d0207e3bf03baee1a4f88b1cd9b9f229ba0f47be70e85258a6759d36da31e27c1f017480295217f2a5f6af7b026246696c99a7f8bf49122ceaed3c258514ee00fba085f6a2bee10d69f2574c27be352b5389b1f7e1232c055d8fc5ecba40e36785dba784f59696f39dfaeb18fe6e738f2896b3849a3122cf36292fb9ffa108ee0a140b0a5ed177c06939de4ef1db3b6708707d16b094ef7ec3059a454d8d443da37d1ab0fee2bf4c0cd2c31cc6a667840df26d690dc65c78e14d956605ba29beef803b87e2bd550e101b0706cacf77832b56674d5bc429d5b9fea85a919e12f74d64ab2851f54821b9f84789b187dafcd813a4d73f9bb7a869ae048d031eacb48bee13485b910d88268bf068d753ed9b9bf62d2d2bbe9229186e82b3a24a3aa10cdf4045484ba4fd0b0c96119535c5835fbe17d821fa3e76e016d5a67755f9cf9d98010b50c95ebda505f2754c3ee2d7b38bc398dfa81e9d4b0dbb3a38c0cf2659db4ac786a216fabb604639ca7833e7d39011c742a12c7dee8cc14a3faf8b43d2a29a69c6bc3e1eeba9ac3469e4dc672b360dab155c84db6df08ef16b263f2ef264bc56092583431252e1bcd0c7e4b8b689535d6cfebadd0eb04998ab505d93e3c2713d4f74ba7fa12f429b674c3f3fd2b11369df79667840c09d0c53259edb1b9e99ed7c9da418b9ce3346b03b80d8d5ed68d36745c12339eb03bfa0f9f47581dcc67393091525429b08842a16d53c57211e606cfc9d2c64923932bb2560885f8ed8149b09ffc2837ac7f654ea49ea2a03fc457fa3c98e78cb4113763aa6cf85a6559f4842269fa96b19026a33e0a93f7fc4f42405eaae74f2f9b3de7582af42db3ad747c5ee6a72b28e36ad50bdb5ce98d2f9043b6e42de9954e15c8f4f1686ee2652273b9ec7527b800e4b2279dc242d4c653b7b8934d6bad3cb56fedfe5ff560f2328160d4ea4f30704026f3974125939392d595cc7624476ae9f66ee1997cf0d3e395e67d5baa43af7dbf596bb3380341314081a3d82a0726006ccc1f4c5ab85f70585d7eb402f2a13535776807fde8cec59141882cb347633c198cd31e6a60664c4e749f18443fcfcdbedd0e52c4d1276440c47d8ab9dfba245bce3681f83f552db95d4e9e95883d007032b2638ac1cc972e6a796f4852c5f3b69b7eaa6ebb26ca62b54bb181533fd6ee5ad331cdb711227589ad63b43254284f79fe478acdef813cd26b0f86b3b093325f2412e1bf68589c401080d833fb97113e741d0e427dda0af9721742e2ee89badd512d9effdb9cf8bbccc1db77103974f07ac4512ff07e39473de93d8593be55cdf78c88fc91575aca8e387dd5c46f152ea3fd14ca040e65e1d7e48e74716ec3a4df6ea7604b5dba0eabf15017cf221eb846a7e9545953906e3d868f366017f08f76d53dbdc550363c6ac6f57e19cb34d19acaa6e8adf510967a1ecfcfc00bfa2667a78103d3be1fccef7d0a61a66ebe4294c7563633f99eb50c38c4dee1f1fb9558e67478e072efbc257a454a716cb1fb7bb1b9905c2c55a9ce7e0f0110fd853793a1c8082feed4e65462e3b9e49eec511e0da82171b0baec5ec8073600c5abec0d3e1d482a71f73c42cfafa8f1dd0d63fa3ed483dc1b8a87698eee95e6b9323dbdb1f2bbde05f48d0d9c7e4e596e30da07422f458b3cdb8827b41d9c9d3089bd1cf1e9dcfa429c6dd5c2f8fe5f20d151761a73267e07ae3df15aa6ec951b0f65d69db94139fb9c76ac6ca00db0893dc880b8fe81e8e1f900787f90596aa97dd72acdcb00ef67438046e38096398c53349fb95a6919efac8d03d14c41b183205d5568cf86f7e36ad2ae17ebdd3abe6ddb00ab775047d3cc8807c21cff016025ff9f145ea3b2352e975cddd8bae00f08a0c123ec9cf2f31ac75f45d30ffcf9b5d65d7e7e338ff5f400e80b71ba45eda3f60be08d71c484c8268b26ebeef92ffb3baeccbbdbe0355bd5fab1220f29c08eaa40c96a8aeb53fcdf4ac84585dc372e95eb1e6060ab8c6730b4ec04d05690966679167e79862304a8fb717f4d05432a9ab6082f7d35e8646cdb3eb69a31bba7868870b7871ed44826d4fe400f1c5c43537f80173a49a1088f8abdbf171f16e41368d3dfbb8c7b1cce0a85232440e33dbae5f61fd7ddd17ebaafef2e5e06617880c0054e000b2030fbb5ba4a02073aca13eab276c1e874c376e2a2b76dc7d4923d6905b65245297165d41a55e95c30e623c0b2d8815b5c9986bcd801706f6b9261fa9b0d26c1ccdb8e283639600a9d283cc8e4bbc4b9564ef7df332bc4f9905797a26e05e5cd7af38fd655260c32ff83a26ef1746433d23dc61259ec835af1322767f06703f2e6548d858321e4ac4939f8c2c77bba97c91677b3607b231d0c774fcaeb9394dfdf96c9a899341421c90f4e14758c8a9a048d125aff20669fed7b0d474bd44caf74b52a336a671c493db06c7c92a8c1f379fbe2a8382bfac44d244fec0e84cc0d61a7c30798093b78c538158017f884aa3347092aa17ea04a0e3151fc40fa48543b01e00b85d8a71f6aefba7a299a49827fbe147f9ade3a0f052cec21a0b5de196599f4fda1f050e6633fbf267be3c63d997e12c00f9c84e322d22c6b94a226a31dff4823267a748cc81eb9ed25589685e524f629c5c69ea8a3fde99e60f68bc92739b5c6e76c6dc1adb3bbd7ecab4897e753241a8098f1c2b97dba8bdb0adca96f9ea5e608509c4d44dfcb60eb73f40254aa577c1bcec7eb270f9d07b4e5dde04b9cfb41df49120dac2efeddf431725c44bcabc887a98bc5d5bfb7e873e442bb1dee089a00b955970bcec608d2851637fa5d0c11c88b5727c11fd2becd04cbd493c666b77eef24949390b5df72ce0fadc30eccd3027f67a2363fecbd4285becabbba57688e361fc1822ab6d1046d67ec5c44ee785a1eeac309296fcfe39b33c275e7e502372bea67d7e4b8899a573198e0194ff835b19bdfc91ed42687dff87fcce6997338d735b1c019194e72f9efc8aa4a2141f45371790d2a6a4c9b5b9dfddd693f556cf28ebf758ea235268d712fd9a9f1ee0e7efbc51f7ea49e15ff3cc3a138c00ddd0559e6c9d93f649937516b4d630667a2fdc345c1bb1c1d218e5bb96f924271bfc2c359e6089f136c68330eec2d46c3afdea2ef18aaf9c35f5b12281635f88c8a6ba24b62dba60682027f826b3117365b3ac7b37da680a707a9f955f98fa417fdb1589e36a471c4b7c7f66f9cf73a619885618466a4db06782bacf095a564ee030959ea4a0c4e18f861e0a61c657c2afa8ee3a97b98e67bcca8bff16d76769cfddc16d37d163f74691e65e79b790ba4d3624cd1f3afa601b50cd72a52067077d31a24145638b9269ffae4ff9564d2388d3f63f917a95d3407850b3cc464737060a4bc6bd79937ce2498fc21a0f56963bcc95b34e578621b9246604a6eab683367bde78ecb4edb56aff1e3f11b71cc3d5bc75279babf9bf726c96ee469eb290793d075066e2142fe4d03c09f9e4da606077404f91b0382baebe1513a7c9e78fbdc9fe4d53bdd50ba2e3d8e2ad7039e61d23928247b29ed788c7fbbbf2748197c4dd173c5576c6443d630ba44f702429924ff2751666fe2d34e266eb3234fe3e9714c66aa2bfc16cd54bf02b827a6f16e41a67bb87c8a87ffe9233faaf8c79274eb1ba74fe85fbeb8c2619975e415e60df508bfe7e8c8f4cc26e34f0367aa1070505f414fd9897f828378f7993f380e0f7b2d672dd2fc5df4cf200607f63d5a4b0caf05a001a9932a53b00a8370802fa03830a95e4ce2578f304746103c5d9b605f0d6bc60793165b214dc65e507c31dee160af1f207ca541d98cc67776368152f50ca6fb84ab326283d00f220a93e7c931e615feff41bdc56f73a73be4ee12531407f25887fbe693b0a4b6aab279ee25858e139838c1ab0404cd9407597d45c833aefaa2771760946c16f1e3879a9b4f29dd8c95d8e713f11a3a49406bbd7d6d828e0bfc98bd62cf1d1bf8e36c4725fe19941dc9937e89e32f0cdba3b8946c7da54063260ed9df879c827c92a529796c412ab0c889999c50729d28f042e0112978e7811e2a5c42fffec9c68668d577d89fb78229fdd5d97238cb33259b33c700f8ca52a25209ec3e10c742618e219105eb9bb6735cf6f1fddbab1bfd0c8b05c6e9484ce5599a819779a6b81c386730a87e39ff12023df3427bb02522f80456bb8e2c7bb6d948b8810d8a80acba3a34ccfeff4e31bd1c2671b0e555abbe6b498deb0a0d7d07ea096fef8ce84e4986eb8b7004141642c85faae28193616c2fe7b76b9de48db86600b8981c5f6ef747df083382c2f47aef577cb4346547b7f43ac0f41a7372332f2f3234289daea64c95c769769895c7340c38596cc9f5e31bdb5526d9bb24917b5ce6d354c4186632a9d6299e0c8618b5a2fe36eec5e37f2801fd6d84e7ca462385a1ac58f486fc1c9d1832ebbbadc41a3fd0f82503eccf798388548c348210cf69f4dabcb6f3e70c332acdf7a5b54a022e98a81fadca535bc7440f4a6e2aa361d68e3cfc733f679cfb2120f07f63cdadf67f5bf748a71d19d664e555f76a3c7e4614c97555f232439625ab73c0d8feab4f534fa91354acc90dccfa886b3e71e3454a0ad183c0a486c219122dad0c7488d17c88f88f53d65ceab9834eaf8166a982539b69b8bb82bf0c3b30e9a2e61ca91202752277e207319a35691a4f347bf1d6fc56190a3e43cb59e447c41e2aaa2054d3fffcff323a42789e3f6218a4c4162bd1e574121b69294acb375c5da3b70b8b010bd8a629ae64054ed83d63802813bc8af9782146efca9565d7d32ef466cce972964afc1b6e1190708292ed48ba12085844f6b3a9d5a31b0b2641271378b5e5d216568db0e19c735932d15ddf7ec63e91a59de4e3797dcc628ddbbffa20af29563e64e78313e4f2656c6f57ac414730df464ff451e603e5bd2d2b8bc6ba62eb3b2e1e710f20faf2a0c232f4f4c2053dafdb14bd6e4fac6b212e81d23f510a4755e8dab7e8f543303a1494be1ed505b366f28eb0a93c476f02605e0ca082c928a91057112c11d02a602c7a37623cbd4d599da03434f1884fba8701b9323c642f0dcf983e39b5f682e014eca3ab06d1734aeb415a714dca15188dd88b473b5b06c985cc481f4e96ffc4d54f1774d75ffa9a7d58fa7bc53d5bc7fc4e465a9d8e105900ad074a46ad711521a3d4d5bf278acea9a887ef789d962b17d91dc082783d0314f67e4952dc5e0cd507af0d98cc92ad91f6e2d1b14b395c70f22494713ae3cb38ed9e6028e859bb379fddde512295d8220cd7d16968dc3d7db1e81f6575a7a63988839cca6ad3857f1198b2054c4a775f756d2c3fd60b922ab2b34fd3065cb487ca5b0f19a0ec198a45fb2b4b9efaf8dc82a260a741c148f22acb2aa7b6ef0909eed5f7292bdba20195ed81014e2582511b88c7c30b7a0334216555d712149fa73c7cf034a6363c3fe1e18687ccc22fa64160ea2165933a4a7a09033a2a4f71945ac18e70aa68be25493f37e19d9e2adbda64a9b3db6314c47461ef63c69d024d5d1c9bf5ed32a350ef6787b722bd483e131a1eee097f49508e45fc519b2c0780bc95f0caab77379de21097aeab9e2cfc5720f47fca642370e17de94b0830632b1ad3a28c98c76776a019d3708d0a6cf276777330385716cc014e04894fdf4c0b52cee7d30bda21a1dd22d4756847447b57975ad120205f30ccc1900a5a0b9b439e46428b168c2c05350ee1c4061e7c4de9284aaca9b0e2ad5f19fa3314c26ee93a79b560a91645ed7a6774a2af802865dcd6eb6ed4621f96ede841c6434803764c3bcd27cbf92ff7ea5b76d77a40246c274cd83f37d7f3ed70481a387e1fd6deb790004dea14dcb062f3f5975943ea801e12887f364a76a8a0ece689b2c1d589ad60fbf6b1e3105bcf3b111cbfa39f6b01af73e4cc51f2162631e79202452c805423938ff5c1685e26ba5e0882f6d9e1eff0c465a5f571f3a181a20dcaacb49078dfdb9bc9aaf63d25d46c9cc683c352e40d1e19a929bccdc4a6b5125d2a7929477d57756cbdc1e9a3e72655b5029aede61c395a29f566ee33bbe66b0217b04c2597e4cd0218b436abbbe6d024238d08e4cecda778d6e3e50a5754689d3bb4aa8668f1bfa0a101dcec9edbeb730c6dbc1e83264ab96b6ee75f7ca748c876f72e3bb75f053c879497bde09092dd653237a79515b4d856563482a13e969ccc9d37a8627d7227fa78a7f8a17939bf92574aede9e7658a80dae2439228f95b2e3e2d26e29583da6b80d3cdd3d23f025729a2322dcea557d531583ba9112dc0e061bda12a9dc07b420d6f7d9ed44e0f2eb8eef8fe34a96180e4ff7a3d51a365a2cdf8add5a7569f0e01a2398c1413d3bce43134b0a43db1dc09133ca6b7b4813b7bbe553aee80265f375a0e8b0219bc710255e9c52199b9de6547aa4da874aea2d5ed1552e3cd13102ec625861fd9c0d25c9b7908440c582613b4a061d8b19611b0b25eb7f1623a2584ee9f5a64fb9165047756f7edfdefb841b41844546f918e694e2c46b278f30801e370da56434239909ede42d6f5b61276759949c9f9ba347ac972de480de83d49d55b2c10749f41da528f1750508b263a956a5d3d3b35417881bd9044a97dbca8c956d3719e38f34a9767082a2eb3a299381ee90cb65485f76c76848bf3f47ba156fb9f9f2f0c869f163b54f84583fc84e74c1df5f0e5c708afaf324d24dc20ab3f8d0516f30df92f869c4a4100e318abba7540d5ca3bac2424cca56c053f0a5837810712f9462fa8ae765a5139f4005d0b460f318aabff72a651fd6b4700946804265eac12461b7703386c04fc3e4904925df87d8d7e35e9bebd192d8fc1c04854d81f9b94d4c3d2196e4498f85067fb1f97fe7030262991fbefd912909e6041cb7def18c7e8ae85aece40418ccee42cb1f1843327d60f1ff419316584a2a67771480e89334cbd1a6b33fafe419f10d55dc34c597003f2ba75043be6a725f83aed41ca91c8d709fe780145f4201a76a54bda0cbd22030350e89a3116da16a6a6ea7b763eee767206d057dd10216c39bc1a51dba4d007b23dbf2cd6325c8ad3aa82d6cae6a5287806447dc143273f500998b85400cc27b350c27c262e0e38f0a50033e5e4a9cc95587d6098fb1d2bcc104df3f1f5e8989c8dae1a48540532045e742987591e2bad48df05036d30f35ef3aee01c10d983dbeaa944ce5f3406a141ed59d5fcb1561397129c48323a965dcabd89127ee444b01ecc83aef5a2466dd2fdc4b59a5ca3abe50477f42bd881bb9abef562a7761f9eab54c04f6af33eeef4bf240d158b0488c4c19376ddad59c4c01e8d59bb022824539e7a00c67a8ebc97a3aa9f582c3ddfede0fb47db07f297a6340f0a8e9651bf416fd3ccabfc12f69ffa81ab0cb04817cb566ea7c6f2e98109d278cc6552492bbc8b6aa67b885e9f38694f970f7504cc35091f20a97ec324b8e912aa3af3d03701c0137826aac74c548dd55a05c75323a0f950efd6d29717d2ee7414725c5da0660791248fee222cd0b0c02dfb61597e0ee9e51b809586e01c1390c60564554f1b9d0f1ac86a74fa59834d0ccbf386a0cc6cf644fd97b4e795990e53a5cca75f7a86dff1ef33b8deb8be9290a7da49805921d3ad50db89d1a7b3ad1c7ae03e2ce9642f69993c144cd8e5965c9ada5c5360098dcb008d84bfb33e10002b73616e34cfc076ec826d8cc02879b42f6fc94e501723797dbb816627ad5c48f7e352794feda0cf77fc1c65e4dd6e4010efa061c09d56e7ed6e8e114676b50a14abbad14cf2a664127b9199d42c543e5ef4692b9ff5821da9f9b6891bc74880d07a0953d504ea3b5d27fcf6d062d1ecd58f495a60458a4061ee440dfb8713b34cb5065eb18392851c69c52420a5b0615ec80c0ad1e54b7297504273aae6a4c434b2b83ebca82f80870862959315e11292a5a8414c99d6b1bdbc7ae66ac0468a39ac90342357159307b1580b2883b6ff98b4e0caf6f8816f94e94a0390493629de113ee80cc56670866aba0ff70c43057b0921eaaa3a313cd090d8862b60ac688c16f2731051c1844eaa168335b6e884fbe093f1ddc0c707b714d750aa4909a91523a8cd9504a2e3a20c0bbffb753ba4212cbd3c3e0e0ebdb6a6be818a149e114c5fbaa9831ed830d80196a00c4be9ab8d4e2f3c75266288936cfd0b27fe1adfcf500f4d2cd736165e80b765598297a57f28ae75e54480c96d3b4a39206f9f900f993909c28697b553601a150d33fd921d36425483618e00d07b953ca7a5eec7b9e0cbf187b6be811a159d0d30bf94e3e03f209d3066dabc90a71c92ab37bf6c8b1726ebf32adaa58b8a9ec1ae9d3b0d5df3a504f2df55f72c2c4c7d24405b55f81430a339b74e40e4ba5adb599ac60b1934a785ddd2b7a8140896571ad23c2038464c8f087d4d3c81902a14b282695f3027ca72add8388c5d21b8257243d666eee44ddb1b36afb76c05361bbba9087ec58f3a9f5a993fe467d2b8fd674a66cf05264c09a52ed99342145c9615b3b6e2eb85a6e2ef96fbff37f0286fe2189325627e8d9338f4805d089edf52626d7be864964406fbd39ac2ba5e3125592a7a338d4a5808e9b3961de474701222ed554ad18bea31b4286b9d2f2f2a19e34f0f71ce6136cfa5849f05032660014660e830cd012dc1445ffe19ff4c158de1216496446ded1793c296578baebe6c4d2e07faf117cb0a52250589914f2da356311186b53bb6bc2a36f2e43cdbec8114489f9e1e128f0eaeed7b59a531fd45e91f423b7a26e3960ce64cdff14e48898f806366b1ffb6a00468e6095034103464d86b589ff2bca59d92467f245fdfc69b034df08ef5f56445abd9f50cbdc19e80f0e55c6dcfc6d19ac5bb598e5183ec69d7767f5666599eb295c1ac3bdf2e735d86f094955746592928aad4b2ef59cf815107248a3cb00d62141aaae8f9c3a84322e25f1802030ad5114f6b4c7f20ae4d70e1ca57b2725e2ea060e5a49fca82bad1a209e6508bbfe56607cd1ea35ceba58d02c45c036ab4ae8e5710400b398d01e149323e741ce94282775c1cbe664cd0cf78bc3d3e3038041707c220e96dc40f08e2196ce00e3a9c734bb965461c169cfc91795d7063c9ad56944c24484b530c129166c027bda4edbdf7de7b4b29a59401be0976083808ac9353cd9e9740ed11037f37087ed23e38a1f688859f341d4faa3d62e2ef1663e2276d76729eb1573e727cdea8f6b0f7d159a07a778e3c69201557b7b97570cbac0320ffb02ecb3f9975200bde9083fcf31d1dd6330e1c30182c76e3062c0683e1c071a29a33396e1c7ae7ac4c26dd9df31da24a61e10db7cf5d2e3dabcc759ac970bb7c5cb7d9e7f52a16b9ceba158b62076db893797ec5a29d83532c729da8c6ec9c7356ba52d9f890509c89e26c0bc5ccfa4c0c75e48c0306c3913fc5a29c43aa830bc3ccba8ed0d20c7e9073ce3860301c19fc3399e40330b3fe41fef9160efe65d669fe60b00ff67ddf7798e5e0cbac73907f7e7078457b9bb778f0d3e79c33ec200c070c8623e74c2679107a99750fb2d65cb805688bec9e58c4fd070cc5a22d003828166dffb1c71d2091615907aa1067d63bc0f63f99836fc9b1bacdb1caace7c85ae726a918ece02a1c6b0f1c27ed66c57cceb3a393734a4feb653528ca681f168002a954e32880cdadb3f278904e4ac18f7aad95ea8626996c1bda27cf99e78c757bbef29c2e9d3d653cf94746ea107aed613faeb85015ce5d69f5e34f0d975e6350e0ac330093a513b0b4e795bccc4f9a5417327016c648bffa9cb3e452250a971780a85d239aea140e58a26d57e2eec46927416c192597a62d658ce145470f863e51b1b0ac3d4b2c2eb858cec04e9b0cdc0e9d6a082f54e28b022c431688aa3d4b1cc850b5b09a325e61853eb488c81197d031b353f278d153e61003570e3678814eb0a8180d3e586cf070830b8e4d887360f297847e224727c50f7705076b3ad8ba0000f8464606101a1ee810e703271d51661b0c415c0d3bbe1c84b804a0fb22002ecc00c6f0d89e00c14c8f2a7c64f183734300170c6d6200c16414603bc30059d608c1298814224e866d032dcb01b61f10e079293242842d09214c8c5066081509e0b020c28502362f16805fc0806d8c226518d9c106475c20817bd28028231a1cb0617980c743095d906c4440e00813c444800909909980190aa0a9c01516d0e2026d30f045065ea0013cc606c8e0001a1de021ce094e1e8842c2705443920d870ff48002e60202292525588204d298149e4832130215a8508a60e362052f580869ee61043d8841821ed4e8818cae5645ca55f2a20564e28416319b3e5c4ac3e446dcb3d402a7052d3770e173d2c483a1e9b3c1c9d3f224e5c40828259e744f4091224a29650553c0a062c60b3eac11e504860f86186e90c1d352456a06303424514315ae89ce4a1457bc2a6cd8e2062fb0747b963f8081c30f64e4f0031a3a401967a9c5cd9ee50f37e8b2dc273b6c5378d8828593a187eb458b962a5f36a53ed8227eb8466ca94870b967800869a64fc6596e11b3c970d72d68367d1844b9e58a2e21cd5bd4d02e34080a04e542b7d01fa80f540bed81f24077a059a80e34078a03c5426fa036d02bd40aad81d24067a055a80c34060a038da22f502a740a9542a35028f40985a24ee81375a24db4097581b64099969828d5483002165610810a21484a0169891210a0f0812447a4074ee8000736a0810c60e00216a800052620810898000124253cc001460d20e18891220c588002882460c80842442842c001689b284808062800902102fcf0d103041e03104000847604cd747ce001908c7ae1e1059c75f686da4a3fc51e33d35d457a2a7a818728b168993f188b0ba071e88efa5b430a640b412eecb20a75c80debcc8bf16e3224aa219e43ddab8cdcce11118990606fc799c443ee3eda6e0f762156a1ee6e88bdd4aa30d64becee463bd61280d4623dafee7acc5927903a91e81eaaefe69c75d634f0efbd07f1ad9a5cdad75e9188266dfd148be6d0b5b4d2004e2a83fd5662a9b2377c70ac3db66bbf7dd364bd1e527f74496ae935d3e6c7062a6e6c90e2829b2b6b5ca141b7512d464bc616639581b5026705576220b45d79c10ee32fe3eaf1c5f89663b86779858b2cae5841668a1d5dae33ee4721acd4cba8ac041ab88ce5952c54289c999a2b51b212ae4071569e5869e25aa8426f996ddb368ee3b819a2700933581967e08267909a82c50c59f00c3e34c1a2099e5d51420d6f3a2c35c0296ba001951916698466694a19d29431b86056451a5f182a2aba1b64f8029732bc6046c5ce9e659518ca2a4d68b629a680e14dd40da228226c6226862e3786219a988941871007331886336270010733314811c312294881d099281bb80045d40c9e405146a9894243e687bc67f608c65946899965d4112fa0a1d2c5940b9a28f1829b5bbef0c54c89d59e651497282d4d4b44e5f0b4448e3dcb176cb0c73dcb17c0a863c488f91123342ba2a4c2460b9b4549c58a8dca1927a0d4134ebe259c7861ba22382fdb0f984a96a74bc586272a559ea85079a2d2c2940e0d318a31a24c61c113a9295c40494db1028a14b76739e54c9d22834ba3a9062e70cad2a40627dc7456baf8c270b20418181833c41a6160d0c50c42d4104319058fb809d700d54df9d24319a58c32ca9319988e8627700aa6e012b426103540e9f095529e3c990921658d2dee594ea161fb01bc1dbdb7c746ea78fa88fb778bf591fd7634bf4ca4de9b9b7ea9a3f489d9974a67523321b66a032f332f5e84bc04f113a5890da0b0186f9cbc3650d438e902a58aa72e50cc38e952425162df3d4b284868f9d12234fb014a540950ac64114b285252663ef4f024ea095409e504ca05a129a2c062b6eb02ca666bc289a7c56dc249699b70c255819b70e2546736a431830e0a0264bc18a18316694c896206275f6ca5131840cd6ed061fcf62c9d14b1c96719597b964e76d8e438db611cf72c9dc0d093c6c66620b15a40fdbcaec92c90fdb474d746210b641f8b19e14ec2a43560d2b8739ac802d96fd6dace02cd1891796d2fa5df178469f12908f668fede7655f6c5fd7473e380f6a5145cf66bcfd2ccd49c7a0b1313a918fd3c08f3415f8c731fdd237a3c841eeb9008fdd535b479fbbcdeb269265228cc4b5da1d8fcdcb121b7f4a1ae22117a1bda9c635b6246dbe79ea209760d18555aa06d5a69b440f3320b546f81de8c732bb92cd06c02aa8fc58c6c2761d236dd8049dbbee96981e683da4c9a1bdce68ad0951fa1d1f5cbf0b57736c30c66348c76cff22906fff9f62c9f58507d289fb4944e47ccaadcfb11cc0ed33483a17c9262877b964f4ccc62289fc438cd6098c9308bfa89aa325b69207419bef85219b93d4ba72f9bfc65253871f9716ab2f19e65d31a9bbcd0396e0665e4b8321568a229a149cd78abbce9a87432b8b965d3174db328a3d093262eb4000b16512e3811830b61a4b890830d38f62c5b88b3557b962dc8c00550dc38712a5b58d33473ead9b36ce189eded59b6204605b3a69f0a52f108f7edf786650b58c0883922617ba76bdd9ca25d1dadeb1ed3bad7365a775288a375277f4cd188a3795bb6dbbc853b087ebab644fbdee51aed4e8d7cba0947eb6a4e4b340e09f77a63f2aa71c47326db66d26efc4ae90de396b137af88771dee1b99549f54ad97c9ba79e0ec8d966ec62ca60a764ece324a28c7594c0fd2a9a9da23e73c94a3534aee47b0d336932fede9efdc3724d6078d7a3da6c91e982647f1ae1ead8647df05e05b4d0ec1c7b714883dd59eb524ec1bf73a1ed9f37c251609373ee5a2c6bf34d9b3d2a2ee71e9284bef82e915be4a14427fe469f122c523eef44bdbbb7af48ada8b21ceb2c1106fa1b5cff67787d9de7e3c6108c1675d27733959759ab7d71efb23aac7bb73a86bbd63fd870d7f58efc7eed9e48fa8f0944671e948a1ed79da1bb577f26e6f0c0a8414dab85672bae101c27888814f4feb022e3dbe97c9a4290b747b7ac6118ef72d098f1d9e4cc2638f5f9d14da5c7832a9b2b26bcee83b5148f8a35193747b07cf8945c21dbe262d816ebd3cb6f79516f51d8302093599c2d2f60e7e78db1d0b1b1f9cb4623c04dc9cbe63d01d9b5e72d17341c20b12511b5c81734271c76f1229081e6311c4182b31d97e1f625dfb8e7f2f88cfc4fbbde045503f714a4cbe5fcdf43d7ca89b9eb8dfc7eca1ba8334226bb311fc2f7bb9c9aac39f342e370942c3bf796efa096b16ee2d65f2d11a46100e73da16f62ca90ebfa1b3377416c71c42c281e3c61c42ba71c3c61c42b261c3670e21f9f8c4e610522c069b434830d86b0e21bd5eae39abef9943483d3d3c73088967ce26d2ce8ece1c42d299b339849493d39a4348ad166b0e21b190c639ab5fcd21a4d54a358790542a710e218962388790c2212410fce610d2f7797308c9f3ba39abdfcecd21248edbe610d2b6e1398484e76c22dd399b48d6d6398454e7acbeced91c42a273ceeab7d85b3d972c135a2f1990f6501adbb40c23a53c224b50963065182c5041584a1388d977cff2082c6ae89a103b6dca54bb9174ed490b9f73257c235a6dfb146b58d76ad3027137028fb7df1b8ddffe4d7d17f5953252bde36e24fe1ee37f376a1d1ffcb273f0463adf3e6a1ae57d3c4b8fbab675bac6b9f97eefc11b71bf1775cd5e4aa5299a9a94d178d55bbac6b4bdf51d4dbfe0e7e85a4bd754ba268affde690bd4a48cba83e7748dbbea2c4db35820fb51ff7ea56baa4fd76a9f91dab4405246dd435d0375add3a3127b0bc46481acb54016ce54944bc8cd97f11d1a8e66d9e074a3cb0da74734347c995a4bb4764d5c3f46a130b2ae9b6166ad79c86d7aa2d56eba6bb69bc8d24cf72b3709427b95814dc50e956fc38656a25fda75b777b0c87b2b9374b7be4cae003ba973925a391232b7f7bbc57b393956ef02e77e8864f4c76ea4e32f5d938addc675bc6643d79ad0383429fc987efdfb0d55dfe1519de7b121aa87573d3c19d3aebb32a94335c904c9e8f51b37fa5f52484636fefaf5d44a2f5d7bdd86a66a5e474b82ec7c09dd54c78680e739781eddfaf89dbc84b28680d7d1b24dc5a2159c39be79e99abd05b24216c88e87d16c82a6af9b60e33cda8c9306804f1accd69e4e833df65786caf1d89b6c5091083d08c66207ab88a4c9462cf69812130e0efb8d14f05eda266042f2d2359fbf0ecbb5251aec20169134bdcea483c360afacc4c4e730cde4f31bbfa19b9e72fcf598911c87fa39ec93168bdd464c3fe5386c72f0bbab26b98b26e8e72cd1a658046faa49d53d4d2f8e5a05bb49d93eaa43b62dfe836cc402d97b909158207ba06c010b642fcb2758207b00acb0c90e72931507fa29c7f57f72932034a51c9a05ad270dcc643da23ac96eee5527596ac58a15fa653fe5c75eb7b0db5328ebe3c6ed6fafcae48d5cbbf1a77c92aad9b406fb537eedf5a77c1baf0cf5bacf6119ea751bbf91a15e875dcc47cf50af4f0bf43c693e36b2a7c9240bd32a6c9bfe95a5ae5e1264537dd47d4e6daac6fa88b9b946d0a8b0ed7ab049109acf6d1c6bf0b0dff807e5a39570fce1b43e9e9a04a1e1b88f37e79c739ae08c09ae6cf086b73e9458a0d1fed833688791a46194582ce46e4f937649907dfd84e3361e821aa9eefa271c879df44e52355b3fe1f8eb9f263d9d6477d52a6cbbd35b7068166e5c93dde8d22a6ce44403b393898d87607da48fb6c07eb7bc8ef1abbe2ad3066f9e531b9659989985d7412a1a79e94e24616a4fb1c8c84b57a65d7596782a2c0a905ee602b3eb7dd4d8f53f3a8ed8f561ddc048bab6cb045e76bd8fcc882abb5ec79d4dc0596957e3f515895dbf6202d273f182a67a7963a5a0ae141a2c55c6568513d309f1c6abf20d21a682437c117e613262d75fcca22ab3fa0267acc222224ccb4d0e1167e858d929228c104f11687a8a28c38505cccb8912c08ad8f58f95e04c47c4aebf4f09c2a835f4e9421b3f6a0f72b442c75a6537ca6c602465bb04f366d7eba8a51729bbe6791e26b8d689ea14774e547b6253f43951c5b1e553b1e8a7a27ef7916635f9b32b185234c1449b4cfbf5a0a89174fdbcdee6f8eb53467afb23fbf0a7f6f8d1640e9d446853fd7ad594295f8b5a8d4d93aaacca6ed8c011e28073239f60238c18cce7f3d1590255460fcb6ebcfdfa2b1bf5f0b83a179a9e3c02cf199d9c1d6e47ebe49ccc1a5b5b4b68e4a1125778a563d31f51067ee10d35fd7c3aceb3455e38e293f786db8eb3cb41555e8461776b10942028425a64e0ac207532762fb08b19651735e6ec83336fc410420f82b5522b82dd5593b2a2dae96b6fc539a76d0a620d4ae9bd58b62ad65a8bf1ec02a68b178a8f29bddd5c24e8e244e57400679d73d24fd102f1660d1067765dc2da0fcc998228c38c2f3679d7ec3341a02008306a04a125082c4148d9358816bc33d000c128206e00820b07486a054a0a65a24db5246befbdae15949cc0711cd759dbdd7bb9241aa8b2eedafbce765df729165924dd08f75a6befbd5cc6c70aa8b28a801f171299cc474703fbfa24f1193b34ac74a3eb32a11f96c88e60c422b11a489254abb4494a558d098261245dbbf688e1df8df127ad8393e3f6bb37009cf4d931ee7773dc274d567bc4badfdd019de4b163deeff6bc4f9a071fa1f6887dbffbfb3e691c042a9fd5b1988f5c958d7cf46bf57195c4354e98365a693289cbba88f6bc975e3af2d49c12a441900983cc1764d69464d4b852261921c818b15d5546a689edaa32b1c85a7b2f1932656243ec26992ccdaff1043ece4beea990797baa91867c46363ed212da66e38b30db10d96a4fd28d978cd9b0bda4c3be22cc36334c2e3d41c6cbd681e76da6db6791abc95a4c84f94d54afb8648526175a60fad1bcd54b6a9bb47bda1e829c18a3904481c1519b4e61242b6c1c45a144d1a8bb46a98413a5182e3c6e18bbde314a3258ca27a22e1c7a4b409b435caaf0eb36a702d44981602057870c757e18bd93a110581098f1de2704a8d36a08f5aeeff8e0b66d0fa8174f42bda897b6973fef987ba7667b79d6183cc1b4b977f4c87e567104a23d750a74177520f8caf6ae6c9f936fde41b3b9c788dc73bf9af41e3b5704e3e9ba91bcf79c80b3b95b27dcecf017f69b7b6ef34a2ce285178570dfb99777deca4721197e7c4e0cf6b95d1deb5d8ec1fefa3c7830c788848f3d7c4cc7605a84a5adf31891d7592cfbed3ef73cefafac7357d6794f2655f7ce938f5a9fdc773419de7b8efef169e523eff9cb3fc2107bfa7b9753a0db1efcee0782ffe07c48df93b60dbaf9bc10b87692eb66701ba3c3fb262ea03b772b825095ddcfa9ee0a38c1dfed6e9be5acb55673f4cecae3c7be97ead4dfe625d4356773da30f15d749b4353cabbb5dafbf42ac5f976d786f0dde25ff6203123f93d29f528f5b890e46e3f02026a8feef63aacb5a30b88917e7a5d9559fb201fc6b9ef9c33341c131a384ab0eec2a9156a0f4ad636f7a9497b255c469a5465f5e1deb24e95e12b49f2a1da5565415323793457034ea2f10b51982f15e3cd23d41e56d7eef3642b1079199520203c3d39d11059fb638739d4138dcb5569d78dae5fb68530bef435c90f5a65ceea83881875aaac5231922ed797129cf48571962880736febb69dfb100410cd213a87e8a6dc11d7e31289454b689ceb537be053fced604eeede7ab77db1f16344ba6fd779eb5b26bb93db5597ecbed3d444191b0c37b1a8f52e8ff7597d3b9d7346ce59158b6c45c0779a5c0a7f445184a5cdba4fed71bbdf1355f137c75acff9d4f94efe740e5e47c75a8f11112fd2a0e60c00d9dd9e2727b3deca222c6dd6988f56faaa7c24ea4d35a867956ddbc34dc7865c2626bbbb734328d3eee8c6224c279898c02e2fa17190964c384c4c3ba9b5bfdba4707f4a7687b424c84edab687e43d692b6281dd1dc792209b8a0958d2c16972bbdd0e7ae208447b4e1de417525184edf76ee19cd15f1e73ce48d52e1a3267f44ce8924eed986e410f0c2d78ee734f8fbcf7265dfc39758380b43a317e155e0cedb55693dcf157994719e3eade571f3fc5d57857f7aeaeaa0b37f86111b8d77349b8d6a515b55c942870a3ea3ad5491d7cef05bf5d95799431aa1e923faaab4ab27baaf4e78c3eecf2b418d3d1b600ac32da755dd7755cd775f73ecf3b97bd9fcd6df73c6fdbb67b9bee964cf0cb28fce08cc24fd0970dcacf4f10f7feb85c5d5c231365302106136b9a687ae1327166cb6a8f0e0926c4f8a8341b54c558c97ba918708a609c251352f62ca7b26c01ec598e19635b4003dd2d0aaa629c5546492a72b4e6a02de3fded829a18f161468c6a8f4b373ebd32268c7d5f05382b7ee7bd83733749adb5f66a926a926e22916f7376ee3bc7b845b4cb0a1861eb98b36a64e69187919c6fc8a9a6ebc6f122b993562a543fef18368b9a33f6f72c91107382375b68cff20447ec316bf6077b964ba0d92092da63e277dd3924f748a2ba3c7af7529d1e46fa2934d74c09d41e36ebd833828cab7707df913e36fe23d341f270ed1177e1a827d7a9ee6a65ad95816098b9306fdbc3fbb56dde0eebc422efa0e775a0d779777361b661ae9b2a1106d9a031e3fdc765cfda5a67fd06054f2541bd7d77c73a3cdd778e431d34c448ca36d639c639cf39fe8f90475fb14887874727e11dde8a444810274e1c347bdcc93af9ee9cf0adf0ac1c7ecc2178fb2ed424f80d1cab6cb4e1528bda34c0ef344f3a3339dd6cfab3a9fdbe8368d22c99710eea2f1f71ef4e43f2d3a4d0feeaf45d587d8c3e58b2fa31cfbcaa3a1eea805f69f23b47bac60dea2fcf4d392d748500ed838c18c77b9ff60ad9b9432b1689a08eeb6777dbb98fe3b88dd3dd9220e3eebafcd34d9ab78d9261789ac9ef902e0972ebbd7462d5f689d0ed4de669f267671f8ed3a40edde8ddbe713f8fef62c662d1d6d11fe4ea0ebf1fd60785a25142412818e7c711bad1e5e2b237c5bbe81673901023495baff5ad30d41d9875aa6cc35e4ee2dadb7de80873733ae9120912274e9ced537bdc5d6b5556c7aeca683767219971aca2111c0d1262acf73e394c8ff8d1d212850c3f5c497eb424e19b8483b4586a6d9b5b83b4586a2bbddba7a236b80255d9674feba3155ec79539906afbed765b47df6da758f2d177269b66d2ee0da476bb1dbb23d0de6f47e03f91ac7583a326936ad781dbbdf86a122fd536ba6d14cb26f1bb7c64cf64df7c91d07724adb249bc7145c8baadcef656e049efdba6491a3541bd6992d3db266ef6dda59bce57c786d0df22f4f74828140572bf697b49d6712764fb15b7eeb2f4d86d611e3539d708e93eb1c803c13cf7ddc07cafddc11db72ee67095bd1359ba21494aaa6412ed3e7d74c9ac43a15020780d39d71cdd6fa7dfde515c414a528dbbe3cf7b2b4f0b744cce351b7f03bb7fc7502810aac9ef9eb7e1cd6df7debbb94d53287407be4ce892aa8e2640b3c34d4f8fb388b1b241d8b34cc24d125fb66ccf3209a89dc4d4067778fa338758dc75f66c82b067013a0ea60ff0cbf5f54862309705c1d0f33c2fcc47dfec3c2f0c5fa75f62f751f8af087da7c9babf8727aa96ce2cacb53f569aee8fb4567bfa2824bd935693176f4b35262b6cbc052c30e24c9318b65c41850aa2a8ae6c19d326aa0d531a4be8a06123031b19b059019b2deebd3b76c0dacc0e1a54e082cb1316fc0046091a3a2a90ec1a356bdc4cb1a9114cdc7174d924467aed9a3454054e382976c884146c9a9cac0973860b35d600b1c11cf6bc55765411da820b7c31be343466b0823245b0f1024a67868d102d3653556ce0650d2d35f0618935d6e852c0e6068e0d0f52ba30b808830ba61d3e44c1268d931d336cb1c69a1748b005182da0d831650b279aec88d2dab3dcc2cc1650ec90b203ca0e2818632c05638ca1f0ec596a41841634dc90051a38642186942cd66481e60325c66ffa510b5b4ab1e73f5862ac65137bfe0331e5127b7e0e81dc86b76ddbb66ddbb66d4bb3831b1a7cd12587285eca8889aa200c4e64740146142d5aa03853c375bcb8811733dabc81c1541764ca266219258506db0a153da8c1e50657b0a07b028b3328166840b14135c801c6932e6caca81203369d1358783143100d9ac61a039d2d60d8d1640cf72cd350b1c3290d133b9ed29c200d1120ad61677de0d1de90ce3bbbe9cd29ce1f0f4ca0fa273218b6d0aef5549f80c6483fc27d9d3540cc780e11374e614f7b2bb52a72697f01ebd7b4b36799064b53cf9e651a2718c400c60e4e51bcf083161460d1c5c3020cd4fd7f8ebb26ac7c3c3ce1eeb550601175b1a8d2744518ab2b6c3083156058b105973328b5e18a356964a046898506563c61c598d91560e4809ced79f2677b9003888ceea827b3d783f4117f58a07a12ef793a8118a13bea4998b38a4fde15c8790653b7da24655a9190c3364281502cdd28f3e06eb25b6d72b4fa225183825bbac5943161a140e814dd515fdba841ad78a18939ab27690ebb0a608d917e09bd00d61845a05e689b393465b95aeb69166b7b90581f9f40f6554d0f8ea9c3fee620538725daf653db32794d6698f16346694596b20a2382c8b0e2cb0b3228abb0a18a2a33801304a78a261ce26af18558bdb43359497a7f846f871c71f7fee17f07bf4ce3eced1fdd2038456b6b772ea9ba6ad326d58da92882e0e7ed4f18aa549fafaa9cc71849a14d647d048931f250a9c2f0f334488cff541f736aae3e7e3eac218c9ff3a178f04eaad811f1e08d446da4a2713658c322234da29126279553a8418dc6ab1d0cc02ff6f6895590666fc74b58c80d0fce1ac2ea24f74d2cb27d92f6e2b7af32d4694b35b216c24ad76aab33991584fa5941507de299c32e5bf1f75ec81d4caa966e5cee5ec5a2ee134f1d23b22f96520565ec1558ef9e3cca18aba55badf5081fbfca2024c4a6eb84c04e889b29352bbaea446e953b0be4ddb31b05d7de7412d70ec573a73a488b91fcc1719947191dd771b6be8a4482bcb12a166b6419b13ebe356aaa5b44c273b1d811d77b1ee3deddf66425969411eb3a571a5f93325a5d47d75a5fbd9673d57b726c7b4f6cd3b123e3ed1fc07a8f566a29f5dc7ed2d46cf19c5256ea79ec48cec79bd0eac95259c9953b0be4fde6696f6cb2a302873dbb14c447815ca8d2b5255a4d8aae9668abe9810ef62cd164d968ca6c3176c47ebc093d67bdb33e4656cc84d65937caf99863d43a4bd728ad4524dc44234daaaf94d493747347ec5937a1e7741cb7d7723e6a23d6afaeb5ced25624121ad9f9dc463cd7e9b119dfb36e643f3e288b31545a29f55ce52adaa4c0abb292ea3b42c4779abc9be3b873bb23855c737a625e42396f87ef9680d968751dae735920bc6d22110fae08e20a9ee7c87890314e1a8f96aadfd14a5246aaafae94f3d675b492eaab9332234d4e393ad6b5748c7352e9d8f758a78d8c629f3ec2fa65fdc61e30de7ebc655d95c757d15b8dbac611d9952ae9824b5e650d31c5384193b7674945952e69446931861a4c6a58d03101a6c9146fa6704393b2076b56aa9f349b4948816eac5370c0a435717772128456cf9da8727702c598fdf6bd1a71ffea3d13ea3d5da3b4dad43d8c1df13414a5c58e78ba064569debb1b7d6288892cd07d988dcc32e211a11ad4867b585f754d2a76a49ebb513da76b52f635ababeef4b440429b6bca75db0dd27a410c8149030f52bc55cede493b9513fd6afd1ac0e518be9320340feb23f49e56a29fb42526daa7d8804933526feb9644c5720488c65a29a6aa684489c93df7cdbaf0d138cd74bfbd8e31fa983edaa69598e0dfd18ed955335d3d2d90c5126693e3cd6ca9519aa7c4a4bbf70028136a5094d6bd09a57577a13b372f53a7a5ee39cd8426556b914d934b8e92e0578d023ebd127c7a229b56825f7f330a98da59af6a098d8302be1a85fa7a2676c9d6aa86d01938e0f77df105f7867b33a788b271e61451db942cdb942c47490cd034b5efed99333a4abe8d82019aa6b635f3e628c9ed42aa33b366571a7669146e17524c5b8893c14c83022e87a926db9ea51456ca28b49465c204855146b1840b416bca3371ce9c31069c3f9df5517f4fba40fa39c1b97acd3529a31004b591ea56d7a858f538f220e3fed34d55d7a48c787acef3daceeb29fdbd11fdbda7f7b491eb56d7ec5dda8805e24e754dc802713cba46a46bb740dc7534f855a86b52de6be1bf7bda687515f7d5e9a90e754d8905aaba46413d2d10ada7f5352923faaa6b4c54d72cf0da78d6d428c4faa44d375ceb9346395ab8cac9352923f02d5da334f0abb3b252f8ef635692320a35cd6295c2f368b3d29a7eb1403cc818b5524d8a8449c3df3e699f56c237d2544f53c0250553fb0fa0344c9b3fdc6ac9560e88a02dd86cb185150f82f7de7befbda0787aef1559e238de0b8aa2a8fa15c14f111441711445d678a20a8ee3388ee338b258add63bebe3f5d6c156265da35095b56eebf82f5d65e32852718e5a3cce2c16164f1031c6d8a51297c2f054960f2af1b67e652bacc9d541bccae291ead4b5319e26c05658a54ae2529565b8ecfb9db28c15d74ed8c3b3dae8576519a8bd7a584271c6bedf61a9be8a81ab71c43ac6d23150c7b491cf61f778cca408ae34fec6fa8db10eae56ac1b815ad4e409fb7e458ae756392a955e81fa28fcea44555cfd86e1d5a46ba7876747b55aa956ab202edebc11bf3a61b36e3beb03f6f1e098b15ea9ce3acea1e8da57f599335bfaa56577257189b48442cd06bf7a3de7ad1c4d8e2f55a71abf164bcce40946ad7c04a65de3a793b8c4d545708a4531f1ac079cf4a8542cb7953d4d32a56844000080048315002028140c88c40181482c4dc32c647e14800c8b904c6244154a22418ee32088814806a1184388318600630840082169ca46001418201158a2d577ecb846043cf14c7c438620918a066b84dc99b810adb5b4fd522608dab7562a9c3434482543684e2ae184f7720053e0fa25bbb099c630e86ea9e253d24e22cf2a5520fb06205a3b3072bea38bdff101383d761ce609962d3c15cb319fbe29163cfd34a72b841244ec1567e48281e58e78dedd6962e25c31f5d174f9984e107ef44b6d9597dfa579430bb81e119fd5e5ca611fb0048bdd20c01136cd6520cd1d5d2f7680965d00fc0dfb2ea7be4641e0fde1537a128c00e5a801cf37a823355a3366cfdfa1373c326ca6440f74b9ecdb7a7fa4cff0adf64c808f8d8e820dea28595f6a786a5019bdef8f85b0dd0b91d8ad6f2c15b117104d2e9800f1e4f54331d4ee7fb973f5dc16bb608988c721082dcb6c09157725a4d5ada288a1613cfad6864e2b49e5e6d61884974da39bb45d670f293140fde30e14e353c9c228dc34b30adb9e86469172b7108f28f01d92d6ad27832cf6c4bd1e7f026f380318cfa1f1ea6857111a25e84f96a5eb799640d1836f89bda1c3b99c4b4a188072fd52e4225eb2eebb54dba0bb4e5771a738717151e011e3e7822503212650da0f504e75b55b6d0672bf9b9e38684aa5d5780923fc4ffda11e942e141755b0d4c3db57c73aff42cbf65bddf4d9ea6226e14a93d5401862af123730a1d581ab5ab4540e6fa0a46e2ba4cf3e1ae5568aef82369a1505e04df7939b6f3a3a9ddcf5bba07370867aabb44bf228e799f37739456c8c5472c455441d03e73192f4679c9155d22dbad5bdc11690208bc3a31a55c2672d0bda8157957f8dbb8e178c961c6e803e4b1fa72f35a52243dfba9e6142873785c9643631bd9acd931d0598658d2f025e1ae4e36e6c6bf4afe3e3c0b4654e3361da24632834b6c04764095429bbad47d91ab1e92b163266d15577fb439948d46f0e6b55dce9a6c32dcde79c6521aed209409fe2bcdefc98b4cbdbc5b23c4cdadc6d1c3b8faa7ba3e387c6b1bf7f1193d675f9479417aca3d35c84145139815c5943950309f8b5767069cf5a6c828a2cfe29f5dec48261ed07d416bbb18931b4a70c3b98aa20924623461b92225dc71330e809ec9e420a6cc45abab3d36c9055b31d17ce2e59a1ec4f3fef3fdcddfbe8e784dc7a03318a3bc16f6965cebcabadc0f45734ba6c0a7828239a31d0d5e29b2c83ca48cbdf03a5c1c0dcc573cb47f073baec4a8579203466d78788264cdb333e353061ef40b0976bcf502fc2a95a18cd877b695c574000df50501315e9905e2a0e0d0eea9d868795231005a79b337d7e4c7bfc50de8315579b2ef2cf93c9feea000cf22632f0a3bdd2f7e7db25ac11a9f2b9520e7561eb6794217968bd43d754cae53266c9ba7a84cbe3e823e2d4ef9df0afa1d6b7fc9dc719a6933bc89a3ea6075dd69131473f3a15c54f8a59726ac4cd86ab6833b4c77f4a57ddd59ccacd97f8e81f52dae0a6feb685684bd4f798dd99eb0b492d364b22304da8f2fd6a6f342a3ee8cf2ce8959f6078cc9615537dae85888671579d11596cd552a32ee40982e86110cdbbd534333e5b4b0d4dd821d83fdb99434342e0d6a4220a5d991cd6ed3f1bd32355552cf0455d48161ec5eca4394e0d91c76b41c0f5e86cc5cc808471854f70a0e83bbc80176579824aaa1c05a121d56bbc80abfd80d42829f246270492f334d6590c0213fc29e1630bb7ae9d2169dca6a4e62624281c0c7cf88ab8d0c95b4e12ddcf76474c59a4cd54918fd262a38a67a4ff30278d39a4cc396b0773f2845a70d8dc884a7a4e94ab1f1699e044458b466b8f7926b6762e5cd44647bc7977d9600407386f4764cdd8d3fc5a6141246a6c1916c75713d117a8088d5c0911d5589e13a9f905d9691728878f3716430500992e97c55ecf3aaf48426eadf3816bd7015f66d469fc836fa6dbc8bc9763f9b34929ee790370359082575303bedae2ef7100ea15307c9124af2b487f4c36988dce6dc4c1110ff6cae36a44dfab582f39bae77ed0bffda5875a43d70b39df6e266c190b6664732cd8a59dd5cf99af8d22c50550ded7e01e467aec7174e46f0eb511706ec5bbc1dda545b963ae2be154d4867522a3ff6c4bde7ef707051ab4777b96d2e3796cc529c578f57007023492e112defce4105e17836e5dd9faf2392c9e152b364d24f29196bb3eadb04e26c8b120eb458e02d5570e745c8989a860cf2bae2d7c527fcd78fffa2a0ae4a0cbcc3e5dd689b4b15e4395bc90a990fe72c06c49d8d57a74a838c16f50a422c023201350c8e2eac4c65ee0b6ea579a611859be6da66b3a8ebe99366857c2cac83d6303b83a1beb989b578e79c505a0896315688a114a406c372fd4a36d40ad32c24d29f665b90db211a8b7311484049be543d6035c27f10754b1bfe2ef3dcc57923dab2819ce3c2de0002208ccce3a89c81f3ee8d88645bc2c3bfaefddb1c286269d6aaba2966de2f305a97b90c64bb67ac0e0933cc4cdd861d27f8c54df2e4d775d8d5ab7e48b825ac5aed491819c0a74168230109b7220a1ce231a59dc2c77149997806544932a2f59d4eeaeb15bbb1d4f064949f863e4ee640babec0d969ed3c9f51a1721015759d104e9b6f83bdd3f2f4eb557ccb8e9ed8afa8e211a48defde0c42e55bc44ad102611e5104370eca4a2b28bd1216debc0a0bb659fe6a8d4b40f2813c9aea27cf7c006386f049395bd50c77a0a83fcafbfc79600953a9626dd3ddf0e30ae36e7827ce8aa93aec9a146e04ce289177cb2acd8d38aa80d2e7da2f6e6bc688c46ff53b5494260bc9ac10ae3b9ad4bbdc0c2ee156e737dbead3861741e58f12b03402c1bda38ac4b9ae58b312b468cf7e03e7a3d0769724fd7a24c2b6c37026158e80ff0fcb65a31cb1031f471dce4f2719bd4cb56773b013326b18cc40e1b982a374ecf29673c75364da7445a747e6e2bdf2428c8e7137bc5ee923c60526eaac1d7d89e77c983a9469a43299272fa4662f8786957720f988e1e49071002f79c4536547ab25f50cd969ff643cb502b64b0a7e70668926d1b86d0193416498134febbeb97d571d89e79fcaf044908a129f82e9b0e8911ec39bb08061abe4e224f8487ff0394b22f2f46de9619bcb45042bdcd3396b0be0d337dfd1433444775e6c17be52892cd9d65428db381c5879bbcd9699cc0f16190c1ecdf217d3761136ca413878bb2a874f2c5a5ede8c4c1940aaa66946eac4789163c02dfa94e3245aad9b124897c8a9098e444e66e1aa93990f1437d62b2d95c62fbaca8615e7c0ee5ac76887f2eb9865b3dd9b837adf70c69bc516efa27db985e04bfc04944d5f1d81d6b270ad73cd80b2a72c4f96c243ad7c57014fced287e3055560118a88f8c4f07c266528686030f458f58dad06d2e6e5040b411213eaccd3a820bf7d82fb109b8af28b7b86361445f0488940b6f7ca48fb0fe93c716b6c3eb253888830e42681674514552f80242fb5d08dd0752374e9eae6ac68387d7296c62ad4340909c900f0c25bc84b6fa74884b502787256d75a6a74d780ea423fe456ae079f0da730ab43b0970d0e55514f9acadb6596ce46841effc8a0494421cd83d84da3d50952ddb4e9f3dd2cd4f7d13def6a6960b3948dfad36577137c589cf2240a95f60928676ac26b6f03c1a0771839728595c2bcd42e0c4b0d205f38d120e534a69e4dc4df04eab0a3160a6b81b598f620b8313bd4c660ca0480f4a5313b02c324a169b45a5bbf506fbd36b269bccfca182c9edd56139f1bb574c15569ffee7097b54de6cd526308db0392cdb9dcbe6586a013d4d54b0d800c1143cda812d4014206724322e23089c2cbb3dae362557b0d5fbe0db21a4b8cd069a6bb435313c514b6cf1bc984758b9054a5b741be6a67da1e3f13d3b2657633b216297ee20db866a7ca34ad6c9a011286b180d5e89d450854d21e6e26f06008ed6b486bd635e50f6a71a04467871806996965195405b05586ca45337cc5245210597b0770d6c9fb087f0841c896650604d4a5be54db55b682d726e0045e34888c6cb3f44ed21b78e5b7583dfabcf1ebc46138f6b59a30f816ce2ec9288f7d129591f422e1264018696828b2e5498d2738403ed8f280b071c74dafeb0ab27a5bc22b70c1214301cd0abe059225c572581aebe581c7b71ecf2cc7481f0acbdcd3e8ca0f02c829f2a9312c5bbf4573783cdee6df8aa512db5e418c11b9840b975859a9ac3bb962c74f92abac648af97556b435159b6f83a4cd98651fcf45633b749aaefe26ad15ba565d3b922c927538524f2e0686e6be7e3879f6a88436a4b798bdebaf461c335563335d7ec4d4ef810b524d4c883cddd8c1656fe480be8f63bb03569ddddfaf0c2880dc1d17530d9a832a5bef9ff729aa5cbe59c75372846a79ba3102d47cba719215c25652ee3ac264fc1b496ae668d85cb7083d4ddd77c79280f4f5cbc19c5c1dd39b1f92d3acb8d83d865927e873aea288941e04f51946ccce313c62eee9cfc26130ee18bfcc5a02f4ea19eb3c0f2f4f740366abb1fc199d0a603c90fef13c3b3ede3d4422b714dbc150ca278f50a2f7132e0b6c3d68dabcb3af5e2bd93ddd8c013ccb24e3e36cb483ab1f5fad65ae8a24a135aeb4516cc29349de02b2334fc42e92ad9e106674ce3d4d0287d80293b2897382b954f8f040e67279e4c1f116b6b5b777b51e2a0bc80438dd2406c2da00cb04dbaa2c3e9ea9cb7315022fe5bb03025fc85e4b853e5fd49f7ae0f83f83addf427630dafd03c5ab391734f255510e166c3adec2325989a51810d715e031979de12e289ec574c04536aa56cac1a1bbab7de94b918738cf103b427c5751e95da33b2a760d41148c411674cf6a0542954a44307ebd4bdc65a653af4f80165e60df92850dec7a84588959b929f99fc9432ea48df5a593fce625d3e2ef433243ece4230cc3d015d578b41f183e8d07f1e999aa09e8beaf6827df7cd003e430b11a8a89b2097b84662b77b1a24840537f1906c183a34f7e997689597db11e924fbe94c22e443fafcdf2050040fad4d9d8ff043643a136fadb908f8edede1bd265b7cfbd621eb9676d934917726cbad248a53a33caa5bcbede8cc2901136bcd575940e08b076b0ce328b516f9d496a21ec416c93249275e8db92d267eddf462c26b36caff620ec9ca86b48fdb624a6fa65c2b86b59345be98ef171ddc0927b6c6e009c42d0a32b06721b798e82b8ae916435f93fd95bcee28a8b64cbf8602d11f48bb5bf78f10e331701629ec2117bf278912667d8c628fbde47f0ded3068d6a5c4c575e7b581e920ab8341bd7c0d6c424059a490321185c70336757bdfe1df9c4ff85f4e2d9cc6dcd82c54375667da9f20bac3464386d65da88e5a709231f7115be4eec5059ae911adb158b5084448aa5fe3426e4a2e492af50ab050a146e7b89ded71c1d5938fe3fef170b84c08ddf2648905bd214df6dd94398980d2c6ef7ca0e8f35a3b4d2c78dd6b95fa31a7d9fabb35f215dfadcdef395905b1389aa782d163e49626fcbb8b8187ad981b3800d331f2a384198b98d4c6e095db5e76c31e0949667014c98efdc882d184551cc1af8f608d2c18aab8063491f0aa27206ddc796aa0891218c583e67588164e6ab23f3c18160c143ff67638d85bdfca873ea2b7a95262648cdb8a3b2cf64c0db22fb8c848d455c6f575d2e9af63795b44b10eb773e293757b14c4ed552517f9baacfe780932df19c18251201ef67d5a56666e4fe7e06c3d622fcf2c6331fbbe5790353ad622191c3145436e43e8b33b8c45c09db93f80b77b23ec31f25f6148c466f41e4d270b04d4c0beba7f6a7788f79c9e7f1b4ebcb06634dbdb20ca283ca8a8596b28053e56bdd4723943562e542c2c88d73689e50b096d78c74f04390e3eb10f54097a91ec29928a9207902b73b037408594195ae0b9658f3cac217002e5ab71e5b448a32175e4cd164e355f11ccd26441964dbc3db7eccfb27bbb65679789a10ec109edbc60a2e8793c842d7b0c0a2219ec550c8d9d04381a431a41e1d4e5c7f9f9f192be4b2f188a223bf0f9f109396eaf57f0c55a5e063b34114cc9df22d8ae2ddb49e0c360079a10bcbe59624c96bb6202a50bf6428c4363d516ca8b33e750614ca58e1bb72717060220fa2d2cf3a2d4e72de9173a9eab61f8f464a1e56edc1e1d0280a2f7594edd1abe3c6ee2c8ed41938d4feb4d50574d49b1168e2bff7d74d76e790016faba103c30900278d58d5ec2327bd980dca03c7211585f13d78f06df3a7f54beac95a8fed34d49db5a080ef5d4242236ef2208d0fa9e731b29c10e500972d776aa751db54ed50a79e232b253bc4652656eb74386e08c5931e016adbb3d46d735d1172eeec6ce23b15a4de1c318861f5621cefd514f798118b52766f7245f93bf269f7a6eb501837f38134c470a4fc591c54d0fcaad7984f767351bafcf222cc1916d1dec2bfa0f188b2e62586309ee71268d6e4a2c8307f44485419bd5e3e36a4737425d4ffa2078ec0366bc60bfa4e0d5179b05de949651af3ff17f593a07442d2f407353f0dea9154f620deb7927b5854cacb40566bf67c592d5896012f2b8395ee4cee2f65a723ed0c776a90c2c24ca457be678511ec67cd7a19410112c472848eac9d020e5bf6c0d88b2606806722dafcb323325703efb9b44ce6045132c3a5cf93b355d1d4762dd8cfb590df85e192b8d675d8e54b99446e915ab480321634036277003cbe49fe2606f5366955787a23ab085a59306b1f3d3aff61b5ea80a2095ba25936e8b6822253b0155ae797262ebbbf49253568035cf625925c07087d8494088f983d8a3b5ce31749d8e42ea0a01b4892c48a6224a17904ca21798c4ccb9f12b3cc39b9d8f756701c0d66aba6c60043a012b81f6bfe850ed993211a5df900b6a8f473d762b778680b7a049ff91ab97d520cf4924d5b01d6bb42c4466d4d2c63725f83ade648f3bea9aab74f96b58812ba31876f8d054f32d07ceb63c4127955087ed1b53b5f6b4d753d274d1790d3795b994a860002f97f369ce6042a8c434111caf0ec191b8b171e505abe32883419ca136ed99d77e3429cab897d5b2a46f77dddcf15e81e4c292fb8130e094a1b13158b4d315fac1cb56784f8bfa8cc4bac21793adfeaf43e3b72f3b458d8d81066fd9d636d490f4b733ef160cadc8d890592727e5fa6a393977b0c57696511bcb776ebd7f976f322db442186ce6fdded6097697a686535d09cd98c0f6a95f6885d761fc7f1f105d377f85584261f750591f1f94249139367836d1387dd25ec235c1d700ecfe4fadf44e911faf1df6bc5e12eae2961050a609f99fa4c3f66239bb980a2a492b5a64eae164324b5d7761b49aea69c8adb37d832e7032d0a041d402201e718e29fbfe3eb633185995e1e848da250b7686500c132733b40c41605077dece7c5fcebf10c1b83976f9dc912cba624a08b64cecf20df211a3490bed2f093edde5fc6d7e4957d9c74f09dc88626a6136bc3cc55f607909a1e9c5af38d4d9ef16ed6d92e2600ee55d130872db418fcbbe23a8d37bd4bac0e688f2d669858b4f5c258a5af97b26e5440b13f7ce517a9eedb4d6ad897403979644596a1d306f02a277e1c9c76d89e9353c1d7045ab90ab6197a0647a433a6c21218795b57bd0d2427962d057c1b013c2b03772ed100242fe40818444c4398293ffd87422fa2c9f83548d9169e9e7b578569a05c89b245e22f59f4c55758e942fee57c42db33d874993d496263fdd146162674343e5852e65136b23b98a46ab0c7a907e3c8d175e76fadf384bc60993bdd784fe919f585f6d105c39b299b80f39cf4a4b44decc421371c1db23d7cc5ba70043f73b4501a47e6e43e9cdd6853c182e69d57b657a370a80ce30ec4d81dba877bf005bade09d84f4e4ce24c3d47d180b4a1551b4eadab3ca8c0bcd111501c5ef9ffceb915adf368f364c0f4abc48e0e32325eda3e139b904a2b01293a88c8bf8da8b50b2bfe4da64433c66b50a7ba47d56882b81ebb733b8a4aa5d16ae8de623485ada78d5c87b2e001c783b8b84cb4b0c2b8964e985f04e0218c4e8da8fd5576ad25735fe70371e065101982f061e9197b75a5fb87bcf7871479166c1eb420f96985aec42e9f56c01acb10d7c091a188caaa7758449fef068c420ab9fa7299618899fc4d3a0dcd00b8d7537f400839e8e28408d55f9a99fe6d0050a5de6dcba337544c108e2ae71e883e3aee780b812f88edddf472073c377c5452969952a537e5de6372da1c2689c18fe038a472ab5e742ad61c7d4606b30d98d7ed0843d7ad4690f489d901fc333a893a3e8fa676dfb51494a94665d6e2f3f213b8c04f516704a216dd47c6cf2162085dacf9c06376fe60f9e688d35e4c97c8d20386185cc48f556f1cd395c7f3a492cc2e136959a4f05cb0be84708ac56e1aba75129f1456d874b74f1788db8c8d1da72183a5b24519d0264eb7a8ea863d96b2603c76e592c25a71cc0d22b7d0c142d047a867e43d4fe21b39216dd2a2d4ca4c8cba9f5a6bffb1799bcfbe3e6e5e41dab005d285e6a744d39e0425250b4528244b80eda2ddc4d2686dcdf4120d9027b14bb70ea2e03c32a68d71cb586feb421fb806ff089b90a9eb5a809b96ad9aa8ece3166c7f415c2dad714fa14c6f344155b567ebfeba835b82bbb06578a17959ec13189e44807354fd6eac811dc674ac748c28b3b6b20eec3a97d42d948f8456814512f440eb16344d79c5dacc02f9e5859afe90e051e8cfaca03218c6695845968181991f5869fd9d57fe7ecd53f5cb2c7141dd5ce9d9646954306d07efea29fce502535de8953d5ed681b1872241eb7589ca5c79f0d42ceb08794c56b7ddb869f75fcc8a28245ce3198d4875b4739b02ad28384c65b8c2740e43914d591d6eb064ce622f95feb007592082472c02a5b44ac2da580f5a4ca73485803f4e814ce40b65b71586231de1829694535980c02ba85566b9e54bfc34a81277f0bbef96e4df60546382f8a1dad379549136133da853646684e36bd9993cb6692668313700ebdedd683a65babf356e9436bcc67e513221dcafe34a092d113bb55223644eca266129da8990c3140bae2af9f6a452e28b04298d988139225646683112c64be939c2f7e5335eb328e265744103723aa3f30c0c4e1e1c929a6c96290177cd4e06d2b44a671c0d8b45357cd1134d57d81acd39bd0ebf62f3765038bf621448d10b0bdbd858b1073cab64a6c1bf7c39ed10ec1ad36c946bb09c71a66fae7a9fb5a013aa2f45e4c18d3a3e76d9ca9c381eac3325ec67f2eaadff6c01ce2fc0ee08744a34d447fd0a52467a8382d2ec745f8bc75cc57ccf53196000aa4f6da565cd8faa726d0f6dee6264bbe46400bdfd2f6ec23f1972ecdafe860d76f397bd135d3a74349767d5d7155dba54c409c15e6e3c71212225a1b0f2039acbaf8883a7d6bc0e09903a2b2bf518ea391e897e4426c454dc570946fa7440bb3ccb62e9225eed0ba25b35508f137627d46114fe3afb1091d85f7e5c1a2d50ea3d4993aeaeee101d7289e74b8b40716756b27ae4c9aa5e3519d059e303878a9cf7054222af30afdbe743ad99f53058152c24586b06133f836c6e16c0cadcb9ef41fe50ad84f7829f216e08a0aa25a3828c992d92da3c72a1eac348f9a136935711fc83913dbef91e4121f4037749868819045d4c97e9c8df1b348e8ad724dc0f160f7e9ac50b7546b45fe6d72cd91b88b1180b80e7e87b261c17cb4c3fd172dbf078f71cf1cd60114342dae02810f2c390f9cb920451438b811c93b68fb0d8dc2878833930d27172ab53ed1f6176e1bb20513727b5ae557f3adc57edf1b7800238aa988699de524570809d18397ba7ce4b30944a91490846d550d0ae8a762cdce2df65f7915191bd2f275245026867150a18a51223585513afafcf13481921fb3f61dddc35b4e5454d6d11762f2306e4c7e0838f05542207a1254bba376137115c24bb7a4399ee50e2f7dcc668fb888ae82f37e2d594ed567387abdaf284d7ae0e4e1c56fd75d8f5b24eadd3a94f107b02f02d37c226f679348cf3d3c0d7a42491d21d3f98171e75e0c208a47ab4b4a32050c3317757a4cca29fd0d8c7c672e94eb02c85696f8d985d79c8b21f624c31febab3153aabe275b1729248435e6438b9f7a8e2e424d5754d69b44fc73afa6b1d23a7f19617c1b5a7130a902a267740a5f7e5da973969ca48afa4516e34ce2e1ad9b4f52a6ef197030bf27663a34d673fa6ced37fc82a044af5f214149c2dcf99b10834866512b16db42ea2f93ed44376f88b0844583791ca04057545e66cbad13d2384b5ee738c47546b64c9c765ac6cbb626e52401da95f315a172a284a8e4eca5aaab700d9fbe90101144068ca09940837a1a5ab9f3f494801776bf5a9750230c98be899d98b6d8587f7e5e2915a161287170c9689b7da15d99a01a9a3eee6422deaefdc265cd65504531114fd30d800225efd3311195d0975b448cbf4928931ff70f1fc1fbfffb33f8937e2c85c0a241868329d434182959e123b420dc5004580d120fcd3c8eda29a1e98ce03e780881d06124c559fe0ba64058d82ebb831732dca707e54ee41bedf0d2f02823877d015d998818a3a63cc845f6afc6c82023ed95d8b90925c6f7a18edd906da0a5cab62c85ae9c04c209225948b3c4bcc5c53ebbd872fb3bf281e5b00721f9dd2344f0c0b5a344f0916d02e4ed0ce40a38e6af79f156083b35e1116223d5eadc98ccc9b3816b88257e6187a0372709f26f9f2256fe744b7a49885e41b434e0264b441aa1a98f0e4d915d89856d1af9179298a7654851da3b642d9cc4131c9a52efba9e1683e772a793e4d2edea95b20eeb2883d212fa42b4795be85e1580f71ee2eff8458e3ff2a1b49fcc1a0b4da76e04ea6ca9b90507104d5bcbcf62318b2877c62c24cc11eda5c1dc9c1179412a4054b4f2028193a67096d2095256e9589791fbe1edd128ecb805beb82a37639c6b0c243b351f93b0fb0a892061eeaace2fc0256c84ef0032e3a8951d27d1550897b07a21f5e2ed31e671fa198c76d5bf12ce1ff6f109c79cc48f8015af107f77f2b862a9a3a12e48e4a6b4bcb74968be534688958bf6cbf2f694aba2c0e50068d2dbc9978acaf21e33c2534a48ed044735b1a57fb75a2abc68a317f0beb8e799e3aecccc5198f7b39cfc1f330c66583ffa7c3f66122d40c11cdbe53818a97856daa051e6e2b03d221f9fec210822bc8705fe26e20c0433a41ea1082d8dcd79e0adb1b623c78257aeeb6c79abdfa428b436ed940c64f0e40ce61e20dcf14895f1c0cdd80a7ee22a09d3fa91316219b1ac3725c7559b18873be6c730d65e7e2ac1c2ea6c228920531adcd85e66daa411384fc76f780ed06837b331607c8d0d1e18d6363e6e5075eeba2212e985b6af168ecd439794c183d38cfa6b4142e04a877886f80a578642a1a55ee1573d5ffd61d682ab2cc57dbfeb234915dcd13bd5ed6a2d50a8022a2eabfb118135086a627c27016b1ca17475ec31fab5c73188e67bd9c1b540984bd4a70e46a62917a4500f0b5d058c995c74d5ff2676f897d837e0cfc11fa8a408061feac5a8724dce74cc41c91eab62a48e2be25195d66a7f841ab135a56a5bc9e64ce161c3c156cd9bf707055bde6cb889c28afab349a93832303c08b6f82b7a7572d80a0c0efb6edf9123a3c5a9513b53b13eebc8bfa5da07b2a5a72f7391849e472820bae446d0808d5bbe4613d4d8b1c98adc4e6206d90840ee460170a9cd28ebf41cc126b54227adda5dd26adba8fd874dde316852a6f27d7441a2a3221fe46ebd5f780f21d77abe0916a086e4968c964efa937f2f2486e014c3094dfaf186054babc7864af938623ed3c0be3602dd20e37b11bf5ec588c1e1e82707d9bdc922baab90d8ba78c96e0e45556a40425d639e3e4550ef3c0698e541046c47b85917b521ebc18c8398516c0da2ad35f0ffda6fb9abaf0b8b6f5ff2636e5b5086537a6f512a2137c5b209bb94f7b092102067e52426d02d87622c3a86d81fdcaa9b571fae25c5f50aa7f2111859b9bb6b200f838fe36486b935eaf20611f27381665a97afa43920ce3013b62f0160dbb52e64dc9bd31675567b4c8b97419fbcc1bbd80e342847de462911897583dc57898ddf4fe3f9d2fe6fb75187b1021ac35c2c10e4dcb3a5cc2b15911e1812b921d79b3e9d1f39d5833c9de929d0d06ac6c9b71bb0caea6ba90cec9f5b3977d83fcd0412289c800703161cf40b7c89740f7fe1f03e226d97a30474f851d402a88cbad3e16de4079f22e0baef28003cd11a8a82b8f489fd9df0c9c713fbc348202e48f3e24bfd4e8094701159a97f35d378c4f926f535a11c251c7372b0bc6b527fded5c4f3de11d6a120bc44f0525858d99ee036aa3062ef140ab6355000098c37c14e167713f485c28ed1be2e35df98fccc84805f15b74c262beb35c9c148656086a540e2b027f491b6e08ba409b070ca0386940c1cace44f2b4e4a81e4d38b404506adc094402b6beb329c24e578844e0b0913398bfa3741f64e371abf3bc30b737e6cdf1da88eae298f859b5d5937d55cd680bda55811f9f24731b4997168de5e896c1dc83032712044ce90294a54a5d703d40ba73523021214e29292fe4217c53ef313c286c0861ad0b424b76606c183cbfb0af1cfe945b0d117e58ad30bde837887171dd11801ec082574f8331e29ca3bd752582cf4e6559644af3808580304f0c2fd5343b69c9807705fc98db600d52c9cee43af5de176495ac7ee9abb7886f31a1ec5ee60321c4096bd7fa513d82d4de573ad6d91fb1dc8a57ca4d24509d20997618879a585f0a06ee639ca66ffa8a78e5fabed09cfc2042f5ab71e2960df79936d1346a4a1631ce44993bcc6fb53bd2efd5770853b081dfa6944879d822abc8984a6bf1d8b4b190663a001dfbb4dbd2379ec5c21a0b1309713c0a63ce8e0db91079c46525d0f27434e3be2dd52b9dbac8d9dbc5a0dd613d5a3fbf8bd279679fb019ba519fc7704766bc44d997eb98efce58bf02a2481eb83ddd23259b14a9a92bcfa0af23e4739264df77238e2c25a0a26c3fb564b2a6aafdbb514917559c7376c07c62c5aa3da013b9a001b7f19b0db3e6d8fc0727cfcd26be6929f721f204e40dbddfa2ffa45797b08f870f6a3f0ca2738507d98be8a80c2ffe0b8a07cfd80dabbb48b9b9ff9b7eb8ef113973307e8e2c5a50f261097d54c0e435f6418148c733281cc31bfc9ea53484ead400d4462927cc812c5bf2aa664bee315ee6b409900cc7e71baa640079768b7aeed6f41f22efed0792493dba054f7e43088ee9332c1887af7d4e2f5edb9511294f70c4a1f4ff82e3b5fdd0bb3666d92fb93b65590c7b068cfa378dfe5e653f8be329e0f86d60775bbe4fb665c6a20be4d0c995f0e1fa060d1328802fb0846baaaa88fc736bc6d73986c94f9234ec521ddf2fd9fc32aa851b38adcb575cca8b61bede1e81bc531ef2f194972bd712e8a3b807bda5175799b2f9693261316525a824f99b7b0bb95483213ad8c153ed0da04c353399c26f23cf90aaa2c0da4db07c1272c4db047acb8e39636a9dc0d61e5d2bb3b4ce8321146e823a6692c3609fc0b23ad060024c7c8301d99a05f7c418fd2202aeb1724ad969fa5ac66761b1a4e0dc0bdca8d5133f2a5275c4f6fa6362f428a18149a8e551fd49a90263665d82c88363c201e451f79906f5047ecdd1409f959c288f19a5170cd15a8265ae0e43a8c27f52811da31f5a4292ae01acb9e990e333976597e3324061ae3c258069a8bc1696b102014b27dc607222621c7c2c37d3a0185c555903dfcd69c12cf7768ca6643a59887417ff0cd9bf90fe8d3cdf14ae074e56cec4eabc51e723c51a35008124d0a4234a4240003701b3ea2d9639847f2b468a3324650f5a537071f70f05c3ade0bb071beb12c6cb7ca73b24bf4d5e6f4910a8225e62eafe155730cede643cd362247d42b5a200e23f7b6fe46492f911b01f910c05456c0b210c0e697e4a4ad432094599e1268a7088cc5ba9a6ef48b039e418ae512d86e96e86e7e50608d3bda774984e2faa22e2703fb2d1991c2a48c4da7b80dc28d722d83c3369a57ebd8a96c5d88deb65e40812872d43cdbc2707d0f70c67063f06c878010e11b7bb58f863cf545b81818dcb14d6171edb7e4a2f48ebc81d9d1113d95ac78be7aa964b53b0630e680307c42bc2c1fefe16b8e0e748685d9719368dd1b7ae53774e14bc11cb22e6152ceff88ec343e56462344d79785e60bad0a081ff058caac14814e8596b977c7f924260b502170e58d0a3c387b50861e4c615735f69da69301e48159cc60fb238ee2b378e51c2537781bc32d492a0f57aed8e12f296e20da5a001e9094b0e312dec8d0bcba0a60a0efe6044ad3a94553266559d86c1a3a8e4b451fc065aa24995ae40c5ee381ed82a580d983d865d83b9997bdd02c570f0a9879d1158ec059c0010569831e78eb3c482a77f2c1c8fcf227f0d7128a0ac460fa1c634e4e1d84cea337ae915392ca23d252d320cb611511d0c9febd06795c54e744f2c00227959a67029f340f8e8bc51837478f2c4aa5503a03774e03926419530cc3c372fb8249a7a2e5370b22cef2110712c2ba151dd6279a91a8386cbb435bd9392f22c508304b79fc0ee10b5497b4a28594bb697f01c4caedb62fc3f3be271b1c092dab0a4b8a3d9ef890bae7284a0a562b115c5ae8d86bb508878059ab170ac245ac291c1406a79c1edc7d233d20298fba9837868a42848540f6ebd8a06b04a1e91b07f4900a619d8012c4d1145edad88f1c07d49214dc5b75b516aff81fb237d2849890b5b3a711bc7c661e9635d44cb550ea8b883289ae737bcdc871e76dce438d2c415080d4eb8841c9ea3d72ba0d5a493f81574e256bffa7ae6848ac0e75aa0e0248ff4a28af4b49396290600a29a8dc88f4f47ebe2cfe06a2e2049a02f4e45dc4bb1801dc005347cb83ee469e32bd301f2144978a5a9018a0b6494e7cb6bc4918437cc82fdbde1139989cf7856ffa11e400901b009f45d150d020f5e74c15a2fd1a4f830e650225c31604b74afe17d662a568173590ba710edf45edd4769a5f42a709901a0d9132789c77a19069ae3f5e19aa37ab47cb5ee3a3047a6c36059a88e5012621737dd004639218ebb134c45bcf09da211e6dd592972bf3f44894be9ce4607014e4536dfb343898762436cc712947905cd7e8e725151bad273cc7e134bb53544855bd903e19b4e200cfbe4527594d5733937b02e171e311b2e2cdb5bc0989af370095f9cd03221dd0bbbc9933ac862f377dda023ebbe4d1e940875814da93074d84437018cad2abc1a484a26a187d5c126c2fdfe460b46c89976b02857e086aea2e61fba5eed0e4c4c0f1e843524aad3723f5d55180701bb94b87229e9753fee6d56b03e8966697e69b605b941574ecf0a733941d86861c16cf935a2a514f88ef40a870088789e811a43462a81e5c85208021086f6ca5fda9837051ecf0a337cb68ea3c136762b654279c8c54e590041f968e371b802038e36d8c5df3570141671b5cfeadbaffd7fb269b428db56d31174064b119508b971e7917ce6fb5497195a05ce5ac8975bdc266732b280638fe83968a65c7e88e62e97e0a9a17fa728824ca35084c55d88da80d7872caa71d091774707b2a8d3e93a2292db0151f5734402f0008db4a08b7c2d8be43859c006a62f0e7fb6537f6ac8fc43d09b88f122d7c5432d06460b30c2001e340fbb4a0f323c02b8b412a447181a116844e1e24e11887971cfba6638ed6d1bb13062e85f8623e6f6936415eea6fd264d9a8e3551712ef325d48560567a96c6ffe962d00f5a059d7bf33da7fe2279eeebde8433b00ad5f810d7fb625e6b8ff205ecc732434406f51a5b86a62a33b3c35a974df0d0e128f47e5d49c0d2b856718bc9a30451d148c5f51e77425fd6a1c37b0d797cd6cc029a8ddedc020518f7c2c102a34a8b416dd85aa7bfeeea400ec3eb47405c0d611547925780f6a67cf6ec26464b70d8927a20d1078cdc01909d1be1d52a77707355b61ade20b1177861d8ccd01c435d3910b85906c78e6879c02288d5921ee560d7906f18223ac797160110207082dbf5ba5faa0203332d3eac7534ef46162a25742a440b13a882838b091e2ef1eaa0ec1c6286eb15f18c57b346dcb058d93a085ca04d7b24460d148395efeb08993bb5a67c800752d4f2067a00798f67453a921e5672101ac6f0b3dcc15e6cbd97f3dbfefbe76e5e2768d2272ce7782ed67188bb5158f769771b323e4fe838e566a508e3f8bdc84d1475b449da6266a665c098e195ed38c7d54408c954e59b78ae1c0f2528d779380f6a502cac503f89c02f5d1f46a8c56867e5526b0e604dbc1a2195c980d61831ff9831b8647e20130c5f3c900259e15d1da5695fc89aa2a0b1f3302c3adb87f068f868465af72d2c264a28dea23538cbfdacae66038d525c9e6f5b4b1dcae87ae93635308431adb0f887b8494c650b89f5b33d25ce5f5604dcd87cfc4448ec077ce6a152d0c954489c8be4909575b0052fd516c5305cdd9e01d9294878a4e01ed1cc185dcd43f318c79cbce8d09f47e57e1da7fb1741035de0dd0e2f4fe8dcc184da5b4977dcb84f94bf6e3c5c1ad2850e413d075c1f59b376cb0bf9c3ba1aad0fb4870945c70a4f376f67e24b04a640d0c4504fe5f13a292a32e54df1e396046768c641766cd5bff9ba508fec52e54ae1b05a46090004a69995b01d1a754d3c2e4a5b686f413b5a92e2b62130f37f1dff12d29e9861366a1d379a08bcafe3b7665457c56508e642bce2c202256dcf200cd7488f3348fddfd88529b0ab754fa9dc12a5b545355fbfbc65dd206635f5f44009a1a6a4bfb99b0d5990f33dd67207c2f14b220012cebec72616ae02f60420ca6a6b861e9613d4413977f618590e4f5849a82a09657ecb51477076b1826a6861c21755b9e25111417c13aff1d109f3611102f514487b92700d19115c9d0a24593dea658c53a061cdebcc2f93445565d83a1eb2d8fb8e5a300a98af15b30618237416ea8f41902f6f9b496d31e8d6c24cd8f5e9e305e0141dba80c835802e8fd4a86ce0517b2b90ead1103ddf455a75e664aa3c13046eb53eae20d1f0ec2171e531245e571c25da123dc77e1b06063bc2d890c870fb227839556505a418331498820de7f84d0a7eadfc689f63095fcd0a9b96d80e20a96e04d79f109f59daa0dc831b4f31667a84feca68d2c9bcd0ec2df902f0232e05dfd8f80668f0d8863105171586d83e878d3ae9e87562e2e0be0df4a7540bb1f62d22b28975dcb143384c9ffb7051a7377fa848816a1a6165216f299ac9f0eb3c13379a9a65a37c29a08f7b5ca60e703388040ab2e0f9f9edecac72f4450fa95024c13532a6b7679e1444e62fff8a9f4382d198aa1c0e4e7d0913fd01dcaaeacec8411fe98e9772d2690ea211e8733b68e596295fe0bd30851e067f3d5df139d10e04f95182923dbc7a04d6c17de6a5f6c18103cb4ba19d0a5262f85faba3e9aca6cb5fd9b4d3ffb29ab2b45afad0a6d0124b57629d0c0b1e2b71e859fe745e9254dc898a282beed28c409adc68705812561e10ff93b62177f3a71620b2aebec38c32ef21cc0a76591b5d1a22674d002a87203ea46e237119404ed6ce8ae1b39b961bb33f6eea42d498ace063f1a1f2bc32a123d865c1ba36d0234e472b9a5f7bc7d37d40cd10b08742de7d0923ddad89ea3a503b838009acc9561881044293aae5cbbd4a19190f23c064e97eed720669da61f7c0752ac2a2cc7886e6ab17453299409a888059330ee742b6322734b89791f550bb40bb6cd9998ad51508bf2f47e660dc2b3f922d45e58b98c0528ede4515d416b711c7f4a12d30532aab07aed285075441aca0b029060f93b363fdd34e704ff392c5d88ebbdd9c93f34a06842252d65b63b1ec5ae10c3b6d76c35bd25596fe83515d2423c979cb01c199d2c657ffa60acd52b6dbbb5b5cd6a560155c79efee534d6b158c0a41811e292878cb2f01e257b200730a05c943054e2ae1726ab063ea6780f3838782f41d8cae302566cfe669a47ee88af71320e551e06332a6bd73038e08f24f55b0a01425b1a2ef917f3217846ef50b2dfc6ebfbd9f105c66568c5e5c7551da47065e5d659cd92415b739257a668c958701491ec3bb4266a9061dfbe8be448852f25d525debec0316cba2cb325d1fe09dadcbed33122953fed9b0fed4bf6319f810f45f6b1f58a5ab2dee38b6e777161af5b8ea60008d75154d7d7354ecbbb6b7d4de39877797def1affd8b7ed4d9f0fbf43e43c7bfb116b76ac33932fc27d4107fbc987e42fb8597d8c4bf8cb26af6418f2102cb245a9792760bbdecab359e43905034e646a4affada4f844e4536d3c411e9623ab415aee61f215922b004d98c18e71b74ec2cd92d58433287efbb9700ad523cf24aece6b30d8965c4aef6cc41972859d0be6473f5ed05f476295ee252b5ce5fceb6c932d3e2bf695ba16716b8507a87db37545359747b77426a969d7f10f2ca4d06fbc73bd752949be25b6a56f1829087827b2d715ae272b90d5bc20adf6475fe1aaec9cd74790df01e540f8fd3e93ed9441a09eaeb52c73dff7b71b3849b84ff893a0391c9f0085702b11f16aaba8ff0e3604fb50835b140af2a742b352179c89bfc0d4e013a98bc0d816f7d9c93f37b40b68d3b12835b3d1a759f50c8fece6258b5b11e2bf0bd0f9cf160c5d162b51755ee79d26218120c03909aee1633c3757a3eb91cb3a401a387ff8b24c18f6d31f6c92abff1b7969bbc4ad2d5b7d45c2cea1cfa1e622935c00539f6475204b12173b017887401e4be0ae67061c874d90b05495e68ea178adfcd1328ff7c08f01d61e4c389f1efbb1b462ff8e205bfe74f3c75362fdb5626e9f389455ae4caf39b00088fed13b1c3d43644eeb04f070d57e6b620a6c7cfebb6016c0897f4bd7568dc50cf105fbc9311391ed6bc3f9a93467a151c353986e030228e5d69068b9111dec876a91f4afc5c1c13ad3b90537f38bd235e915eb0b85168199f58b4c6474504bc562771f0833b41a632658b5bee28f371ca848f1636b73fd8dbe0fa1bcd66814b7843ed042d6743ebdd707dcdcd39bcb330774a616614f698a01f2617d236e2c8891d4860373f1917d3d4de40dbaa2076d69394033d8dfdb6caf37d1f53a030955cec1be6fc131cbe153cae0df6cc8646e5cf289d96c4e7f07bf035d10702e39742cb724f55299ab3509009c42934188929030682a837e984135e84bb8b08a481a948e63016477d93a377adc2a804cb3278fac40387bd6677205f9b3221b2ae8cbbd43ea3965b58c78be4f09c71ebaffc76e524aff609021074ef9b09a274b7ba62d601d05a50c31869fb23315d6c5d195aeee1171e15d20454eb4da390970222290fe81b0c9c795ab15a48da09ec80edf7067dcd1e488677b3546db280fac43a7d1cf00af8e7ba02538e711329d1623d925bff89b63829990a1e878c38994d687d46700e2417f18d087ea7ea9698c432e3101b16a0a4377a356ff10838e9c358a38ffae21e36865b199a215b9b2332bd7c920603e27367724c6c2df1292a9b13160282cfdda2518838b1098ab036b4f3b0b1a2fedb939fb6f3e4e5f01317da779f0e780538334fca2ea1bac5821f8385ec1f2ec32b19140c1c6b02860fdde082e5e446c2c08060bda3223c2e8b8d5d2648744dc435d2287c97e31d4ecc088fc2ce16bf4c05a8acd1d59071494793b80ee41d44432de6b8480b664df153a8020e6c140d182561b8dff0edae34acd750c18336bf9edbabff981c2ab4ef9b67d6e16ec5975b93575221e1a8054c811da5dda424dcb9a37c873d6d48c7b3c885fb395892390fb84e3a38fa142fe24f0ac0d434ab14c25072d2de9cad4943718fe1b228592bdd69964c789abf7390c69c1842ae08ec325b6422017d5d23bc69484b70815219f3077b966253dcf87cb17250b4ef00c621b25e1f5cd123c30f04a99516a831e3ade53cb3f224cefcb900d5207e26797d4a44844451c0d9b067485f68ac6fcc03db623dc99bd6395cde143f0d2a3744eeb1597435ff1ad5bd2b50e8a5ed591b170b35415414ce271129aabfe8fa9558876ee508f92e94eabcd2d755986d5793dbe36ef83b1117a7264cc4d741aa6135894c5f5cf751d4965fd55e3b2e17060d33f45a91583d9f08278e4adb71e0e26e864e4e079a064d3583d96871cb60053f611c0284eea9bbaae7202df7cb3bb10e8565aa827c05b307209c890f73dcb4ea156dce923d578fa16fd5db779597454264772701fe9e9f858758750102f7da75791a8a1294e206e0658efd6c26e8965652d4892b7514c70ac83f0b998d7024ea34d515ab93f85c82ee17e43d01f5b7c48cb13b687d1ca54b1640141200800a2f56911a8b8aa82853069ddaf66012cc3f6c1f8a340bff67ecccf45bfd6a9f031f6f37f87d6d963e7f2e93c557fd3f7b3b28f4a672c4ea00829584abfacc4efc1c1ff78574e5b02a8bf9ff229bf1e50bcdde0603e3cafdddb374f19a5dbf4cdc7ec994745951d71ef4f39946dedf04b483c4e8d9e39da357bfef40ee0914dafe5369b2ebef0cf18d4535cf0ee296ee3bfc6bbe9040f71cc361bb368b68e1f3b38a5d0f35b357d1f3e7a54792d9b1af5a84f94d3616e5b9c577d42072adf36e96d8ce1f56151f7845991e93cd2a5f023c42e254cad1be990a36396d0200a21116a7afbf10c308dcb202fe115a264f12084b31b32e1988e892556aa14b68c83d657cb9fd74d80fac6266c19b17aeccd579c48551421065f59f90b0eed6e51a8d381e3ebd2a5fac1e93edcc52ba959fe687dd0bf15a62d271691236bfa5614a2d4bd80a91900b91bce59b227ef8b8fbc2bb3c221b1c9d4afe1926d7fcb90a5193671d2c0bc7f0f9fade4a8c742d8e9a8252056f937a771d53cc75ae83824c404fdefb0dd6dd4ba93acb1c6fcce3b7e0770705d6cbf30c9cdd9a02a6158afa4d92043ac6a2b05dae97856fd0008e417d6345036829d8cd37be6322a20bca1cff5ae6fd08c525c8fda31a151fb1661080cdea5858a99f3a5e25552b194d025048441370bfd12bd187aea4f08d8d340512e61a7823723b48770c7fda02cd45101b1c276799180bc375a6910383f93b60e62789c3407e587322ff0258d8c25b5ca3800a59d5d61655c919dc3ec1d2cc3de6da90a483b23c0587dd8060f586c72d02525b67f6d3857eae8e80ff881660026376734314003ea52e3a3654ea6b3c8b0877266d6239421926fbd2d53dd87ab40df0c19e466c623534acfcdd593eb5f72af43b400712ab7799aadb6f6da7e95c97310aa43d9451097f077dd6cb601b6a4724410864696511d90ae181b71b23af5bb7a2d0129da6d43ab643a93748c6768b5f5e91128106a363e5e020342a7661e8455dacf528d5b876b59a711597cd26110a0175b8daecfc4c646b395342debe32b4028e4567b4d7533b4a5bd22a7eb48187b1257b53e49356e85058dbe0f02a1d4fd1508319bf588ad3e4bc77a04565a3e27353784a3469f0752ed1bc76b49bae667e9d6edc955c53ddca6e9bae21e56dd0f4128f38ce76875ebe3238044eb5668d0e0f730a5b9e1bc2ea5d57e226dba3dbbaedd866cb4ae57aec32633d5fd150cb1ddb84aa5b77d4a686f0a071abf1ea6b5b74e579274ed0fcf408150d359f55be735298df6b3274069c3edd1752e7d732bad8f8f808110b3d94fe1aae62789d6edc95522bdede3293020746ab6eef674ad7219d6738b9e31a7cfe01564f314eda535a6bd02c2d161d4a8d18df93344becfbec845f89fd4a3acb91f32e5f7ebdc5e2709f29f0cadf0bc7dfc0759f5707a7bf03fd90a0cd1dfdef8db5bcfff255bd090fee84dd827c9da6ed737f704e010c4e42ec41f7b77e82f320b1ea2d33fc92a70487f7ba7fff4be1f8028cdbe30b103431fbaa0ab7fbd88c6004fb9fd4af5e0c1be917cc85d73fc4163f909542ba244883507167566c96021699e0754e8d9fc0f5edac2c2d4046b4a192a2681e1430b18d11d2454965df7dbebe52e9c90fa5e0de7efa61f5576fc316a36a17166d84f674080348781eae1d840772156751734d28d90cfd8bdc2cc791f874dfd7afcb572f7bfa39b94fefa9aacbeb2e6d8b11fed667f56b07329463e306c5efff263ac4fe08deb47c963970032bb1160c1d422119b9ad2497ed8a37e040fb983ff5af2b1fb7f80bfabed6dc251e13015dd984f99769bbaed1ec83c941d7e880834c29eee585be12f8bab6978e8f5ee0ea216f27e9daff5079901da399756d327c192f6a48365d869880322e18c572370fe3a0f724bf22fb7abc157fefada15473cf55fca1653a56a0464150784821d6fba4b0b0cad77b38815423bde72eaa24b5eb38a67eb1549061309d134405e7b9fd1d8a27af697beebc6dd580c624a21d7acc42a5624a22ce972f16a4a7c9c401b73501a611e07f285f42747c157ae801b8a2de289924794f86779ce4725a62d91aead5948dccbdd752219682119b45bba2d0c6854b04919639c40074ab1907f894662c258b4c6268f2ce49acc42c9cd23a5c674591dcb8bf0476481d205f8dcc8e8d0f3c89f0c2b5fd1619be27f8accff0745c3f9525a6865b10885b359a4d42f1ad2ad821a1a64818cd3109047398d50be4a96e37b6f5e9262853ee67371d1f8fbfa4e4d0ea4c31cfe6bc85dee47fc7439fa2b78ce2803172d9c5b5962665b162b28422cb943cf1b5b9e78b5baef3a517a9a7dfb372b6a7b8685c5ef8fbfbb21e8000d7be14c738ccb66a631ef7584aaaf4860d0740bfe0fc21dde115d4374e8d5da5d58e96d319179a91168d93c79f1d621bae6d1b792bd9f90812053ca4ed4a90502cc2536cb80008f171fddf736df8a7a62986899c8fd7cad17028b0ba10d08dab614602261ae2b98f31d3f4c47d68de2abc3eb6a4656437eca6b205bea11d53e8142ae95be95b3da8cd18ef76ddec7cb851b7622d506a87aee324bf452277d932e4b7f795e41d434ef7058459d3d0eb7ec64ee8d4954ea0c4ac23a448a20d5794dc2c380d9bb3cd28561104a0bffa92c15436b516a7d459e265472d9540c1c849657fea4b25db5f08d377f8b0a1dda891a8f582d5a585bac33aef7026b17b73e43d8e1f540d990ebb9fdaa4399a9aa65fd4b406bef88025aa7a191dd2554c88ab39a93b696307d3656fa01474cdaa63fa00e04ef19ca1d428e60e2daaafec19b7b505fef43dc6731a6c9e3b8bde6953f40b7678c6970b825e62efd77987ac940706b21f5bc8b4e69a19b717a4bfc659f88d2579cf97781dbb9134bb82dd5ff48752606c331234c1a71bf3adb953b59c563fc752e0fb1e3982f83d01845e654fca040e700e69b193ec82fe3e38eb87f456078e88d5390f0b20cdee94b3ec55c343ff114e57efe2fc35ef73a7d62848ff7dd405f6c6b769349df166b12aea1338054674c358903cf8d8b48bf737394b7f744544d2feac34c37e72c9f5a59bc2d557d23962623bc62fd3efb72b6140e3abf81fb865ca7368ed6d46a7a85f224ee5e9f6884aa0d9164302b3f80510360bf169168ec1a5d8b38bcf19e32d84fcea3be09d1bfc7d701b3fb9ed1d0fd27d9286928501bfca543ef61ed20a1d4bb7631c925b9ac320c5830d2cd81df5f8e8e0bedbcee622a6ffd305a70de82a53b876859b3abebc5c901de69fea666d7e609a0891b7ff40f467483b87bd967f0c6cdab30795e5d715d559c9fb8fd95b789651ab5318a1b92cdd0db88b63736c3f12e009631799c125d08ea60d12ea03e806a438a3557d2fecc8dd28524555f863638676a8df56ec46e602e7122d517ab4cc876155f1fd07a70f50f71cf09a230f5c8864f3f8cd2325a822734953e5bd85aa3ed48d4772516d543e691a7c759ffbbc39d0375e4972e4a8173d7edb990a66e54fc1212888ba79c1581d7bd47e255084917dbf56f8d26058f929534ffb48ac8c558bfa9a8b9db2722c52df3085e1ac2a87660af55c4d5685d8c849c8634ea0cffda4d91ee1674e2018cab89a554a6f8a7d974ecb45ac30513631651af6660f9f45c7b1919bdcbe29fe62980ea659c28e58ef0f6440d2a59b764c30901cbf4afa9d72b9ed69d275310f02fecc99548619ba50de5d1252ceae54035be7437774dbeb7799901171b54ad0d6540098b1667e450fff2ab2e125998ee843e44e9a6ccbaf69aa42a7108ca0ad3db02fd1ce0ee376ed3d0300b7fcb421f11af3330032b4d9a7f22415f3cfc5761776e880566d7ebb32956d0d9a33534d1c3e326b9faa744da12c1a491fcaa50fb5271250a65ea70eb7a5d67523797dc0ac05b7593602a46634c29781b6325e36949c508e8af3e76d84f534a897ab4ec3c124abaa0e367cdf1d06b97780efac5528e477e88ba1b87ff8cc8901babf44e0b19d6f2f0e551212d12a7c995638ed8f86457e555586b1d89ded3506731853815a27fe195ab9dd25788de93121aeed1eb4bf8172ee91990d8b7c9b3dcc48e6ae6456b68386e3c91761d6bd0d43371515b4134bd8a59886633ffac12576c5f3a09d7424de3ffbbbf4793efc90446aaf3684ce09a50e73430aab60a5e6b588c99da6fbe825c7c9ff45449df600b20bf77ee9d039497d61e2d8ab6ed6ba045828635d4907ec5c7f580701c3049b80284817bcca4506eb12cc7b54e97e483c21ebacd67e2ca1b565e119d49c6e84813ffe9da21faddc3c4099a151cbc04f76f22472703e6ec03f218c3e5722c66d3e0988b2f49108a13f32f5445de7e68b10373eba433ddda86816c6bf2acdd40bc07d9cc31f4fb93e4f2c4c0c41d57daaa55b40b8eda685bfa3be43ef755d875e4150870f48268eeffa84e9f725ac38360fe6c036d711cd0d67cbf85522a2c3788fa84d802e485ecf7b241858c48097f055432227d19ad9b1d8a0046ff16f668c50a9961e4d69fe24f2eb0f0d8a215c99e104c785c4f26970e14a788c8ae84f3b3cf111f016610b17805e6bfc7509dbe5111a3f69f7281235e1e91ec8acd47d273ceb0b05740cde61c2c8120f0f110808bd24ac59d11dc3821aca83849cbf868118bf0d7d3f98633f4a407cc4ed7a43d3ead57bdaff4eb2e5bfeb932fba6af2f7bdd0bd4c60deb887a738fcc0dca647b4959d1ec76ed97f1e0b72edd5a63924e0119a1e0bda7706e1122d0d72c3b7e0802876cfca8714a0dd5fde04bdc655a8b8a984e063bb256ea33c6caf8017a2d3b6193a868f6494b506c944c51740c6e1fbc69be9c859daf3f16d2584e374f35fe6b8521828f6023f939c68842198291ec47d82d13c9355a837cb49d75475a6af0c81b1bdeb81c42ddd4b186ccea18a89ee699bf8c0bf77c626501dadd9e59c4ed5aa4d9b03b8e89121bc67dd8dd84ba0f3c18014b75d6a7d5f0eb0981546063bceb4fce36e1d4a869a4d35e10d9cf3b03a7ffce7e8dd94c45f83688e1fe1a4f8f0b3712865e2ebf17064cdc3dec5709d3a1a1b2b2426f4846fe4c19e7791b9b3116a2cdc3cd84cafc528a3bdd167a63b372f9721a46aef15663c7e7615d6023ec6f3a368c1c24661a128d0fb5f5ef0a34fb7a68339d0ad5a78bd3a1fcf0561291ada4fd1269709e02076abe9eb848fffce711b73ddd557f01aab18e773dd45825174035165107bdaba788abae04bd3b2bd56fe1b4107deff3e2e1eea6bfbbfac25e1a277c02d4eaa3f9788a02750468e6b09a77083a6a047e7945c50f979a82f21c49b4c537359682549599251ce618b011554411cfb1b244d6980da2a69a45ef3d1c0a708003e96e4de7e4796bc52ab1ea4a2104a50955d5cb989469db0f2d83230a7024c2be5108e72a04fdeefeddf883ebd6abbd52f757d6d7f25e51b7bf181ed348a838d86c4a54d208a2944326018cbb01fa3b254459404c31930e92f708f42ca7254892a7b48a3d650cda9c609b016bd8103ecf350f35795247f6966aa65ff1929d68ec07e65df15ee9a609331e46676e78508e2bf29a6564abb910a462d88c01fb43d329d436d964efbda59432c9e20370049f04f603021aca40426d32bede257ec8f48ab60a81aa4157d2ccdd0d10cb4ceff566b5e6b9905716cad83dc0e0d21ad9839858a2bf436640a637cf6a0d93600bf996dbeb02ac4405742d234975e5402412c50464504480cc5a6b2d50ad592f7119888307d50e90fb8e186480ec430681206dc82fa0404005f88024401e12db5af08548ab2e0d13bae60908b556fd839229dfe8960a7c7001103ac0554bca21df9c3dafcec16bb797dd25d28a446b06b6edec1b570f6cb01561db85a264ebe11066b6b62052a135b97a259feab4d43c2500fec1ed5e85cc64ece02c6b00aaf7822ea2d60a921c3292946f690ae2fa976908fae1af59e2065204c1592e69e41bf8a0830efa0c04414b53d15e10ec85e400f2e74852d8735fb200638c31c618037170dbf75a7b814a24510014cc8081174a5a59df2f94958562c837bfcdca0ae2b6c13718d61e5435e811fdb7a1efa5ea1544b523093b8ec837f06df50ac2da0dd5a94e6bf7f42fcdda06e1738c3fecded841f7f97dd8bf8afdd6b63e0bafab9318804c6f05d885dc640d35087f4023e4a96e8bea3178aadb92915dc8f549be799341ac576f1200f9067ead20da0b05d666da4276a8d6acd76acd0a69c9e550adb5bbde0cb97a45412cd19f33fdc412fd3fd95620529f8c2485c9183e02a86660cba50c456c2e324f7568bc7ee8a90e0dd5d3f184f74563165169108d8038d3695175104559a64e3d3104aad72b8ba73d05b22003183ef5b61d54b7ee8d2558fcf55bab5bc763071b209ff644d7eb4ff5c1edd55adbc482f6f5c8ca245f5a85aaf20c8492db6fa05fcf17935c2298e905bfc51f13f4afd3a00dd7e96f28d17fc90bbe4978d0cafdb70bbec1bf8086d000742f19e47311155ffb915f4692aa640c1f416b0637f0bb56514abdec81d8b5efaed59a50967cabd5a8b5f65e8bb3d50bf16624297b9d00e2aca621f25497060a83270106d5da750e252e3b10870aa2faad59c1187b4c53d1df1ec473ab1848ba3456df34aae3f27a3a5692b41949aa5a37d1dfe51ef770a5b49a91a4aec7f01152d891a4c09a81e79e974b39c8a3217646926a135da29f66fa095d095d39096146bfa4f0252a84995013dc2b70184c82de0a21279e8cb434835e07fefab58d2ff83cd208ff256f69895c8b73a5dd80fedeea1863bf98620dbe1066d62a5fb71a84e2e4b6d6f6f5be77f6445f3fb982f06eb55ab93a7decb5d6ea4454441a7433dc5a9b0999c94f240a29c9ed336befe7e16bab9610bf21e857129156db7d868b16d2ebce84fd6df6f5ccd6d75ab5745a37bc445aa5f840d2e5caaa2b57c78b935c560a4ecef4c89a5241770296d41a158ebc11d3e58c1126a9ac5c162e86317cabdd2ed06d696eadc5350bb0a4990293142142c40319c4636a6510ac54e30585cb26c34c149d39c296d284174a2d28a6aeea6f6e53a273e46f6559eae810512acb058cd1a93107690e4ec69c11c2847861533170d812dc0d9382b3615c706594b892c2bc4018be5e589a7d61cd10bfccc890993ab2b9954b1232ee4165c303abb284bd345d1b52eeac031b9351c360e0c8b026187276883aaef7f585f565c65a7bf157d8979a6fe6799ef7816036c090c2300c65229810b01e198c0aac0a98979f9f9f9f9cc1bcc0d0808dc1d0a04183860a464adb86e9086b12755f3f92bea270412878aafb52c266cd1bdb13dc8604dc068f0fdc26076e03f5c2060449f925c3502e99626392e304cb41222748154521ded49299941997b032615c1efeb4441b95af1f5f510f546b12f8baf1851bfb1b18f65427078d9c3272ba7cfbac922410c3e8cc419a830b81ad6a8a4d08d5234629cf17374ecc4c098788e001cdd5e71b449f398b111b3e18dd8782e0504dd0af510f35eaa1c120d9c7212888839d7d08b3f73c030db924914762cba5ab0a98fc817cab0501790909faf1d5f38826623fbdb42bab6bd745064806441b946c6b926f05b8304010e95714ba2e23d6b69567344457ab37f26c9c2ffade888271f6edb55b7c5104dec8fb69916948445addaf83f5da10883626b97d66abb61f41a5add65a35bcf55aed07272c6a42d040c66b3d14eb060b55cee6d14d74535a67ae0d9493ba99727572907b01038f4a8e474e890c3b27d8f9e5ac9c2470b016c02a1255c74a8f330e948f25a7184e30e70372755e9c7abaebca19811c97ad3337766e39c99cb95c97b37339b293f8e4a29c5f7250289e3a6387c971a08d0b4d6294f92145eca90d1593932cd725b40e387dd4545184349533399aa74d2873684ecac6022f098a4e812125e5f4713a97b301b90cb9761246bfb8fa044aa795a8988db38d20c06a03a60db927670b66fa85b3079133b73586926918b4502f37627a085503e6dc71622585c8751634e700725761de50aede42d784625f504c60319090ece82221e754e46c3a676ec9d94072d4ca996b1c58ce3267063406addd99cb79d13bfd8467860a678e3e69ab14ec60da0585734c379d39386067aeb3c6ce386797e91044a95c600024272dcc7d9d09c869c9d19d9cce33078637540addd3317427fdd24b754c8f8c335752acb042a72e1b3bba8a9e51e3e53c72fe6893739c233820c849bb7214a4f172774e30c7845ea15927f5b2878d99d30590294cce496cce49ab206970d234f77e3afe63932729cca163e3d52442209783a2d12ed66439c3a8983387651627eacc39e1ce38556270985c4c9933c2c3f19ee73645de9b31c2db21a7458d156c4128141b9053a4ae9433945983f554b726ca8f4adaaf9a286974e50d3b1998e2844c580dd6a8e60c53995b03e4c7a7ba354ed5b6ad55e55936954d69aadcbb01351580dd76c0c2097df29708e3ae569e7a74f0a07a49f5d587a27c78fe8d627d6dcf6f50ad559f40b68e1b9344d7f189ebd80357670f63a9b57660bdbaadb492ade5d75dbcddd7fb3a514731c1370dc4175f4cded103f286ffda296289fef60c3654d043105c41677fbdd28a0278b4c88ee8e08c5b688a02ee9ab01cd1d9d938c106d49c393638f8032fbabaec50129ba366840d97bcdd7a20fb74c794f5796a58d1c082038569c9c834e5851bcc0404000e2822c606cc489a1f7242aaa75b421213d3d10c0b4e06a61647f7de3434dc5c11588d45dd71fa121287ea6a6c097735c2d0b0b9710fda3181799fa73ba62a7ff35274022956a8844a035a98e244513903c74992375e5ebba5b1dd52938d4d8804a703e378e06c06e2ca1a720e8fe07078876b4ab271ed70562f80a73bdc1010bced374afd5a15d501df5ffdf12561bb9ba4fd2c6e5737698ea041a3956fb91a5df022b0d0a0dbc988b3938164cb1af2435503638cf1ed70ea94f1c0b5f8763392703632bb195ffee7e96ec694a4322cd8c6d8c6ec94bcc031afafcea12d50e37e754aeb0fdfda1fa291ad1be991d65a6dd0c7ba881abe25e9102e5bbb530af3e2d39d52162b0fa8c96262430718205be10a6d90feb651f29eee94aadceeeeeeeeeea63a6a8d3e25bbd80a6206d415a8167d6fbd679f375a073fafe14802246bed4d4713f5ad8bdfccd2ec539b01032e7a3cdd291d79513692189293c3d184b54e7a60146cf28215db7bdb12b5c57e6ba7b576f3a8607baddd293d398db0d65a6bed968c9fee9470947894722b28c9f091f7fcc5bb24342f7bba4b129382dbb2dc005b0ecaa15d1294b74f77494efe56ba90e46fa5ed04a932861f729ecca35c799524c3b694d4428d18d51b130757a9848c102fb61956d23ce14155fa50a19c03048a470a37cc183196cc3c315e64b1c3244e0a6aca2e664a295faeb0983daeecb460735ac1dc09f92ac17684a3ac8241030e0ca43978ca3a5f43d8985c593274e52e0b10296617931f53259714be4c305fd0b10389a9dc428a619a90472aac44a16b4c2b29cc912d245009d3c47603898985c8181fb67387c9e6a849c99152a9678f39858e0dca4d0b68ca27634aac2e495e306f58915162a351c47c8342c906aadc72be98612be1858b72471d17e0b84893a38c090396c9c295f20428659e25a610236282bc4082798e50da71812bb5b838ba72078a9c2f6bcca918cc2c30b61830d8784429a5aa4c24165018d2a3470c39b0d43099762d605c19b3f5009b6a23e74c29b6339b6831974c797281c891b284a812cc092f9c6cb83d364cab3d493ef4849993c5ab44b265961163eee11255a58472528a49a2470acc0fb127734dce84a1474639a6a785ad8598e9e4cd132e3364a47809b3624679526651c551c13403a424c3c336c20d332acf525925cf0b5b0e3b5de2984e6a82982959f8f294432c5e7278651aa932674c955ea24a273e969e909c34c696cc2263472ae0090266f2e82acf6cd99ec6bcf0a2bb6233e1aa6c5255de99ba1365d2f16112792a879c65f02cd5c073545ae1319bc06c4d5d65922daf315abc9463ae985e57260955361c53e59e28b3ca8789e7a954e1b4b9b8b364cbdd392aade03901ccacd2d5c25679648cb98217dc9512cd559baa335368a24c2c1f2d9e6c36ce387696ca37768ecc1c1e9b0e302a5d495b25d718938917b3ce95d2cd559b2a38536ba24c2b3ecaaea71a67589d251b8c3a475478cc12c04c2e5d2590ad126c8c69c38ba974a5c85549a76aca1495a812061f604fa69bd34c23b654fe103b3212ed9e5bdae798835aabe5bf0736509d12580d3a005aa7510fd5ab530fd53fccc822ec065f39f8aa0297b556bbc90e94be1d010d61bd7a394443d0c7b7471b4c82bcbae184e71774a72d4f773ad63c039eee743071acf7a7bb1d475ebc333be219fe661eed5e0ad0f71cf44b43d06f4f71ab8ba8200e7aef44fdea462060f1f445d4149e57cfbda741f6e2f0edba672f066b2de8b1cc2fedfb482b0b41ecd73dff2ee897e679d05f32c85aaa3abbbf5eabfcf5ddd31a11cf9a7641152b8a3eeb4645df5b3ca2c0d6abd75eff76704c7167753c71ab4822530fedf4b675f2b9f7f50718d93a55cad741bfde3444e8177c9987b4a29f6fda4d067afd79f8b6980e281db86ff7c6beddf37afa2c76fcf8023cdded40fa158d45b0bd968d24ba7be620f8854dde46bf79ee5303123978947a18fda3c93c9016f41f088e34702cd16e5d846d1c1a5ddc0dfa6d44e1b9d7f5236ab7fe91e2877b3cd1ee919e75fa91e8d0e4adc353a71f60e4a29f6feaa1dbc11c93173d0791a72f6281c23d7d1c632ff3d0739079d143bff9f82d8721a9211465b4998fa1e8216de6e38c06bdcc43da8d05d8e1cdfb79a3fb335f711f03cd380061fc83431f1f692038a290b948fed06e78863d4f45d1087e74a3eb9ee823f369998ba3e8230d4d84a4e83ea2288e331765b4cf7de8480b7a198dbacf38862842b0d6c21926c70e2e7bc1040791a7cfe28b3ace53fc2376a03416df23099ae74d54bdfd03699edfebb74a3159d46f9d08457bb56c70407d88a7bb11b27ee714e694f51d3aa8e8dbe79ed7cfbb794ec7122568d1a2858bf7c8d9075ceea7ee7d14d3a0ef403d50f77639afbf4ec35aefb8c147269bb94fb563079ecf3ae4b16d588915fd9f7f7091653ec296ff5c7683cc5ff1861ddc121b464a650ecedce83ea52e8e764421238dfa3b45ff8cbcb5254bb47b200d6560fd3c046927bc15fdb3b65cd7ed05afcfb07b8e6d4561dd5e9a11ee6641b463ef89e0f5d89b4c1396af1e3279bb3b897cf5d0c51fd0fb1b4d84dd32df50d44fdde87e7bd1cf37e9e2471a759346fd94bc591abd61577122bf08d543ff42af5eff0b7d457fe8962422896827784abb854e43af2e86e058f4f32250eae1665358f2d63145f5108734a3fefa3d82e486131f1149547d453f2eeabf41441a74fdc3f5757077425d10cc65592b55dcbf95290ef04d0e0de0c38d6cade592df62aa00a7d4baf776f616c4758f8487e997a2c5ea15df4a5e3a14f68d1eb0f803807e1d743c9e188bdaa81a358aea449804bd2c22ad208aaedf0bfe54500687d935cdb94d5d1f3edd35698979156a674349d3111b53029023a804cc983162e8146d800093160000180c08060422912446a250dba90f1480076ba22a604026a74a0261280a83180662188461000040300060100041188ac11854fc696ae111e10cd10d4adfbc73855d6c5157cacdaeffab8fd83d5225acdcdc68de077071832af5d2cdfabc90ca8e2f7f8c1279d154a6e33d9d7558cb590c132fc61a6a10901aa598ce0cc1f20c0ccb2640a9b6728ea42ba70bcbbf03fe651d285140cc105c091dacb07029941d5b2f1e33e25c8b669a1dfc76c6e6ac9840555cf00274f7292556e0b781ee185bca54e5e5559c2475ee2120161b6c648dd381deb760b75ee8d7b9eb6ad3e9a0d46f6f4b2f1cdee79429846ae5f5beaf9532df5bc74d7d3181fd89326ed2c0238d99ba2300cf3b1c8729d8563f61c925b8630918259a2b756a1069717ea2177a486599dad36d5b4743f8d45b02eccf814f269d4916990b8615c0150c1805a6a9cbe9367557b336dc615b3773ee07ec408d282987cdd98a249f89508a3bed15e2d030f1b7c65196289326d671f83f4c878ac08855dd3d15145450e449dcc2e46af93e83280e881ac1020d2cc3a45c96ef1714c1c9b4ce3e988238eb9141308294b8486afc40e39761217f810a6ce77e0eb6bd62d73bb0bb5e9de13343551cfaf0293203fc8ed9a3d3179c0fceae403a7d1ed6aba382889dd9c365da81c119667005bb2a6264678abb08f9c4f86c8377f47c0c10759f5adbf434f2d7a12ac4ba24b2c88528832468a6dd6d7603127a32bc643541a8053100f150193110540072110aa43d4d604e40eb86f280a677056eea8d98a8091b66bf68ac3d5bbfce958c2bc68ddf448399cb0e2736b27cbf2c090e7c3447f81609b8fa5236dd012b3b2e7092ec10984d1d100d3e4cbdfacc0a81f6b55b82fa622ad9fc8283971daacc47ac8a602cd2167804472ce35b200b78f860d56d07c8bf43cc5c36226dfe2e8603a3e007e1fd3ddf6f00b8a51595b6d6bcc8f6586c39f7f950014c6acf1d7ee5dfc5b21e7639f2faca85c490d85232a757185e1379443f4766b451b3978dcf28afe121259f5a428cfb9b8a05fd9dfa241b6f91df05bff4a848e24d692ed71484f1d701dbb6240c88174a71a434aad0b97aa508af2a69839902773466c15aa40a7e8ca38ec26fb4e9a88d3ef3543582d0950342440f1d07de537c36772a18692039a61e08724eca09b2e20a6bfe040f4c0cd8cc82f0e68cb5b8cb10f300857a0de483f3e358fafb7ca02f03c68657034be02aaf97dc25cbe11021142143908d6ff1517bbb0380726303058f17ea7a30baba110dafee98c9a78d0289b6ab0c425e5b131539ea8010898a0ccfda467de2acc708de1b9305bed8fee4859cc9b998872d7c3d40427dc96ccc69cd5f37ea15ab0c19ba41203c47439b7dca07b3e5849fd63221580870aa7f1b82d297dd3be103b97117fe3305da99aaa26500d855c84a1bd93cf9264cf7434dea47152942bc4684482632cc0d2a8da1d03804eb8638036b6985d590f6dc058877b64e9487a434499188dbbc8fcb1a8e226da167e70e075fbdf7c048916f998a9f18a96f32da0bf692e218396ae83dc27fa11a79077bb774e01c0526fdeb10ac2d3c9d01d230d23de224ab256f81d95cae2704eb805268241aef58b49834cfce937034b68750c284ef428d3655ebf60466ff44253edeae876ef04a7308533c65f3a2191604fe675815ef8ad254ae12403751020103a396798a16f409de6c177c113fb874b652893761f5aa8c06d4372431fc9c64b4394024a02263f7e842c4a28b36ec22ea43c877f561526c6d4223e0ccaaf6eab4b6d5a12e11af82674ebcdb3e5889b5ee4eb65b828ceb40c77c219825f6613dcff4ea2a0e0d16d1664db8be1aac149300db70f56bd3b7d8406a156b11107e30d626d10ad5fbb75bcca7bcd41f140fb3421d85e5103ea54945bd62d5749a7a8423c7360205160497a5d01cf00bbbb96cf0a03812aefa0931a6d6917321ea4591dd0b0511ecbff0c3d2f7b4c230ffb2ffff626608b94c6fa52a698bdb39feb55787a42fef2ae9f537adb7d501c308a5bdb9b989a9fe6b57f3b49ae23be0e1cf1cb01ddfce3921218a2dc91280dbd7b89357640a411a0b9f52a181364e7790298afa9213bde4ea2c53f71d4bec974d3e234dc72a791404ec71b1136e8c7613bdad0a6905f138d70b201d85633374c3f9731ef882e7a96f0939c5238d25c881cd8050ea74cf1a34c6df452c976e59fd4e40d99066c1ae90d6dd1352bc401759f0e42a8abf4adf5b6a0631ad27b030c6507a22a05c8971705026832d817aac4ea137775eebf5199d576358929b989bd6673f3287903d8509ff64299b3ef273ef634a9e55c20e7dc0bc7199779071513d208746ea4342d61b51297f052a79c589f141f6b48fb5885a62609d4de4aba808de60b2bea5497b2599df07bd949890766321d1fd058489cf8c6007b19694f57d25fcdb1a1742cb12875d87a381db63700d6f236b9dc7a2cee5c5e7f93ff13bb92852ce48c39ae53f3c1440ce67f81a7744082950d5d7e2a51a26fc946437189e0e40de978a6ab75ee422d02036efbb1b301b35b071867907547f39288f674ea7a324062ae8cd21a2f510d52a46d6ffa945b3991c109be2ec2d87bf52471c8f25b4c44964ac3864e66c12b6cc4b21198f8ddf31b33da55434e883a41ac67fa30a872049cd9cd3d8845b4de12aa4f25ff08c414f9e142d4bf7ccb32ec6b4830a392ee26f58b33cfd46426017271918797bed8d8f4bdd09569ce95cd8224c843345b67e4d1bc6643d39e1813bfeb1d249249c56e445d599ba67895a07c43fa7164723078dd1d15c1e9a6bdb2759666c06d0a48b9cd36ebcc7aaf844dbe2783cbcbaf3826f36b7bd63331829a9e5a261044adf67f1cc81a01331cc06ee82b106540203e234cc3e20d36c6c69d5ac98c930b87f633efcf8945b08d4a0c9a8a43c37d30eb00a4dbd7b61a925a5ac77bd835c4cd7e3ed79bf85bafc44ec9d609af201db1c6bccc60ce906ad489d9e9674a526cab6d1c23321b4c097054f62f65244e6c0c7b559d85a45a8030ea72505a4fdb5ad856177eaa9005d99a8b42a9885af4d202eb0bd029488a5019b0f31abac32b9376389d784f8d4375dec91a61cba3fda995a65e3d32adacb5ad33e1819f843c288e2cbc0dda463c69b0653cd530da60a1c59792b1ecf899bfa7a9d8fedbca79893e047a31e925855e70ef875be3d1eb4294eefcc6d1b38b092d854eb75036bc24bb5475a066ae517b0c869eb91caa8a24442f68899ac572c3a81c16eb4921d276afb4ce383f741f8086f2210e3f8797928702898b743a53c5b4d59d8141c420e221db033f651634ecf23cd438eddd1b3d9517f1ad3301b7d514b68d7876e6fb230092a1b5eab1f8c9dc942364eee66e1732b188514d13dfde661ae15713916075a818e245c694e46fbad8a73e80f074caee4ec23398a30f83b0e76731f2524a8e1893fbbb38cee05a0f159ff844817bb5e22801c6eb222bdd7b528476a6c1920008cdabace58c39f5035be4f5afcd1a294a801a6f74d42b20aea1440aad492cfe492a60c503f4eff54473b9a1bc1aededc5249cdc72c7d5bfa1440ab67ca8f334ea48c93f7616a9d4b9514357a2e55b32c4f63e698d22d754b10bfb81c97966f138222445ae6959923db6693ccd474dfa64767cdc863f20f2cd1682b1a82f03e652a9c5f080e660ff75e4549610143e1e35dfa75d5bdb1c1bd982873057734dbb6530894b52e6c9912c8b9d45182d89d03208974d0b8749a1099cd4a3c3317a5c8bed30eebaedb7dac9ef639f070642bd6013df7b5cd1e3b71685bb1297cc5853610912173779da50f3f5dc400d1b30f55208ef98e7e401fc5044421fefff76913d8779e11e93bfa38059a96cb755ef7878214bfa9d04526be9866ec0d1c136fdad2da0d20b60e4d5c5d73f35dd8684354afb2b4a44994f63846f3a0d3b5222caa64010772638ce33f271a7f03b649bd8ae339b5a2c18fa4f87398839c87ec7cb41dcda1fece1a80ef23c340593706486b07b1e18d80f827ceda83351477e8ed76d2375135df7626abda085130034f22880e054d6f84f18528d81c5adb32cd85275d11758c30ae049c7225ee1e0311d04db57dd4af396edd1bbd36be9ed649f12c82e1065393afe5f314c8db69cc2b4f8811ca4e63115843018ebdd64a6879c86fd4db45b5e452dd8c3b58490081cd7b08c9d02482c9c20c3d9bcdd15723bdef419732b5c417dbb7f9f63d471a287a80b8563e2c19692e596e5038abe631affae8b8866e02085530f33dc65ef6031ba69c318ee631cbc0515c723d82113835ef1d998c264b4909698caf265a53630897a2a495c5c716d5d8c542e4233ad5d542eb18eb04f0d00791e082b988b574bc3f128f9704ead41cd77a9426844103a98167d44d97ace544a52243e87c04e2d94d18cb89f0754e6b9a69b19b7c7bf4c58b3a37589bae0e8c8ac3e927a4b25190d030b0bed72c0ba734409e3b68097504ae3b1f8a48ae31e323b0fe4e2a4d7027d0ac60acda63a2df71d58b61c418ba08b0ae987e774c204c8ec405126d35e30b300a838fb01444b75f7fda0e2838a3c749c6b9c8cf04dd644420a278bd85a41d38b81376fd08300f263e09622509dde9e1d751835efe0d7d56559986d160d432021dd8df83f3e41e32a9058c54e60994f8cb24978289123316b9679a738c056994a4ca0b0aef3fac7013f7057a4bcedc14765d0ef7dc85013dec130b174e3c13e266cfe592d74496f1decd8598c8db4763abcf863c878c6cf804f4642f306171163a8ee22ac2d1ccbc1474467f20f508bdd7098f732c60c8f41b303fc6113cc74afdb0d8a8af79ca06ded9c1497f6b439bef2e08d0d36a6a03fc0888bd6574017c5c9bb845aa2723878d0857f7ad68bb4a9695c7ad8f94695d6d7e4a38e520ac37b7c7c1862419144a37df5c014bf1a6af88d38b2293b0b2792c52a82f7c90081a0dc47cb1760521b1e52259aa8452a46de052d92140987b1349d1c58dd979e0254d7f54ce0c772c3dc9f5364f3fdb2c89de47b390fe3c268438b06a516647b3aba8e9959401ed982bb16b901f496afa453e5d6b32bf9171c93f48cbb3a2acb7c85c2ff7989c71b011db0e9b6d61b62acf96b3f08619e84fb1a0a5cc13ce9aac1bbddef4f8ce4f285c1b975271cb9c422f93cd869019817d34a5eaa920faf2d4b24df84e4a0bfa8670911c6f3a2c42d6d46c198a021dbbde9d046e1451c5dd60c5b5bd27344f4a80799f54c7526c7f4b2746ce44bd45cbeeac757c26fb9660a3587353c0aad0633aee0e4964d08e25def8072bfe54b420b050d282a0c3aa32fb2b721e96d09bd1f9c48d66cf325de169cda579b32f3ce64c525c773d0f79d54b7e17e0b17eeb4ab505d72114f250d61c5645b96e7f612524deeeab54c6a0bd71bd661864fb08baa6e2a078df09d9c683f13249f2655f4d018a83bdf4562e57874e1e34323d47a49e67cfd546deda6ff61d1130b1da5694c65723f416081d3b6d89f2a7cfb4b0adcb46f6e4fff19877ae73cad32226ed0458479ac746d41a3c22b45f1dd622856eb457ea1e4a0d283276fa9d91131b4e4e02072a17cf9c2b6e5d4953de16e98e34052b61c3edc5efdd4a22989aef84692c3eec2171efac1a43d46c4804b506a4cc3f20efd2e1a8383cd313bdecb2840899b0c49d74f753eacd82fc3f1cb1ee71cc385a84837be940b9a5b16da816af903ffcece73d13f6e993c40d7e9b9190d917046adddec151a39315bc2f9550c75f0c34d67d42321da1b751fcdac4c4de99b907358a19584069f280ed63ae55f3dc88eb41bc1a75abc9490c5a8227dbd6a79ee2d481c4fdc1989d3c4f751a0ae5e14b9dbf4ed15de08ef136c73e517c36a28ff34f6b5e3a4c940e6f5c07990eaab578b23c8faf347eb4acc01177534c20596a8792fa5661ee71b96d0dc71419a2fa94b71f0641058859fc6273452ecaaae827f53be886484806f7d5764fe0c38ced1bec1763a8c6390b2563ab10bd05a245b66c9af386e6ca65d23ca45d8f8ace2fd12423e62e9152fee9079d7cae11ee0c46404c63f16ba36d3269c5da10f215e23e5cc3bb1bc26bedc6c97e77903caa6f4933c07629f00943aa6f11a79c443bef83a0bb521de7439a2e061cc09ba5d8739a15a5196e7d58c9a45f178c59dd9162efa08e0837dd0d3ffdb3f8dc0755158a8ebd9e7d482e1221b461966a1536855eb9333e1abc4a5ad08e5771fbab8389c10e5d13fe08f5502abc93735d579031df138cfd4655067855640cd072c7ac4b62673cfed9288feaa01a539c6e1c2d0783946eae08666b6efcf5ec235a83213855303ca62777f8a70dbd9588bd7b2c55f4702e113a1442f600ebf58410a41a685c4d8a99dcf81693aeb1d7fe9647aac1cc74fcd4f9d3a40047c4d99f562a720041283d6325943605fd7c171ddfa2bc8c82cb737beeb172c02b4ceb2bc618e63a86bd1c3d95cfc93ace95110ba10286d1830410fd85efc91f18a9cad9363b419e3a28f62fbedd09c648f5bd30095a7ac99ec7fe4e9ff83502a40a6581eedcf45a2d591bb0bfdba27f6b2f27486ce5a095102841bca9e1c09043f23b71d2aaec20dff05c63c222536acb6efa65c672062b23fb3f3f334108f6d36e2ec5fe0df601ebc87ec3a22a4944b6e0f34256bd081cb00673e0c6fbb9f47ef25965bb915629560cad0a42028f607b5905aff98c05a7e2ae8f57249a5040da96205f343ce035a89809c780b81e47aa17243d11083460aef2f99e399fca13aca616b53b2f895e37aa65efbf75a30277b8834fc5e873149fd7c666d2a6fa281806736265093ef5ee44c3ac18a198bd0e7b582d253388ec7a630ec1ee924b60721f0b48eec1851c2826900b68815eda050274b4f6dcc7c6dfd4f1e0cea735a12bddbab9a9b3d977907889782200a117f75b1b8778b816075e543571dbe5c96d11384bce3f971772bab81c616dbee9f29a78acfa3c5848b5837bad7bf192660a403dc88ac997c4e941c812dd4889402a349e02ee3f56ad1108e8c824c58f2b8ec01582ec8239e720f0ad16f10b5e14249364631e181e626ab5b04dfba6caec86a3f05f5027171c62acf2e1c2246e4487d39655f218faf1519a4b6aac9eeb5a2b1de13c2a8591c234a89fe2e04891ede138eb07296704451920370205497dab2db1055167210c6345eee3aef8045d2997921ef2a240d9fa8540b8c183c1ca36f44d5e8dee48a79a20a5a314609e767159808b47a4c2e2c0389ac983be28ada68a5be3db009d2e233058a0e9eb887203061f5b0b1a567ae91bebb30cd7a3dcc9b86782b838fc2509ad9ad6cec539bacb0970f19ee0d66d95ff0a3e7de0ac74037b8f9e73046e59f95bdb146499a176687bbc6f582dcfa49013d47a66a0a1a393c10cc2efe68854a1e66d3a25c4cf8854409dac16c0d82a44de006faf8133b9c1bf2ac77aacc6809707416b037a94ace98895a81e7f3b815a2d03bf08f6be3cb2a5799fe1d46fea7c61dbf9f74fd86549e24c686199fef9275c49ecae94726cc59238b2ada8beca99b882ed9c6b0b6ae9829ff8401b8d28edc4d3996bb17f209fb07f446e0821b00f1dd3b00c78c214c09d2aa3d769ee8539a846b1dce63d83e93ff6ef37b4e932b9fbdf5c5c807d02bb9f9e26ce61c44a3184f2754d61a5e791cf609813e68d498541ccac3e5a4fdc134e8fd5062fc075cecfead1b846be30f65e15a95619fdd85a11fff33eb5866150176209bb004aa0070190cb867409e6b01e969569b10aa9d9846f32209423de08368ec038fdd46d29217c11b408c08b003499c526c21eb776ae72370830e2c7ca05178141f819de12234413218bdf0fb2ede2e903ee0610af440143f41b30411f18e7609abf9dcdbec32dfaeed8cced654efe54bb2e828a2330709f3d3816703eab66bd880b27ac724df5108de342f9d13936c40a84de311a120854373bc648049c15579f3dbaf3e13ebcd62e703e6de78f8816e64f1a9712e2fd08ca699f1a6a17899f9a438b78ef5b01c1672e762ef253aa0e43f7332c07ade707610e2808fd8b66c29c115f81fa6a47418e0effaef627bf0e43fc33b5250594d6bb759fdde53eab960702882158e43f747456e07faedc73417faeedeadde2fcc039822196112f840888310501c1a7b97370d11fc372d02e458c7c2ca89bdd92d667b0bd25e8020d2ef19e789ff5ad0f4231021f041b44244255841e842322c5113f0df3cf9a2d0dcad266854014e4f35e0e63f629ddce20d4053a8ebb6875e9afbafbb2959bb2deb13039ee79d52811bb11e088c0207c76e05820f8d49aa54400fd7f5cdb2e9e3e076b2c849fa4db59c43bc4388269884d107f10e940203e0283fdd96c592128a09a7411a6407022d409c102e1134327b4f8437351237e1055bb5e7e6a49ebd6880b7d29979b870bdf02cbe7c78d22744238431c8b3081d08cf823d485c00f016c0486c8cf789d15621f89a344ac4e88a0cf4f7b4b4704a04f3e436f17a84f96ab4680475c422884f808210e61265c248dcfbf8b17741c250cc048264bd21dc6c2874edbf6574b3446a74892fd915f8731fa99de9e0262d16d5c68ffb88f352df89f8a70319da245d6c7f706a31118bacf263a16909f55e383501881f808b598fd17ec2673f70e2de957be63c06e932b281f8c5383c010e88a37ed6c8422e21191e35f3721fce4c2816a7fbeb462207420441719e14054a1502c84b70d32a2c5c347e39e42d4e9074dc999136707f904ba154658f14aff68b140cbb5ef2bfcd06e2915d1e2ff09b6abe2f919b7092116205e208e20cc204c1b01d4f7c96afb84a0c2f4415a3739ea936d6d1174b1baabd20bfbc7eb680c4a1f49bb5b5fe573afc98b70401446e023b622a0405040ec8350cf8816a34fcc5608840294d4900db0df68a55fbafc8c65cc02f5e43cc54d5b118213f14e0446d18706ce0a854fad43477c10aa362268fe73e0e221c48df093f823b841019416a6b9e1c4533e99561501200816970f953a6a9d3e15d92e923f2bd70da13804e0d715c924b9f94598223623a6b7be0844f976408d98a1dd828db8618c9cdfd743e1db1d73004ead119cc5fad16eac880ac4dd0807083128be19027a4b71258e1ff68759f0d66c994b3d18a323dcd18cd3fd406a67b04d11f9a6ba33f81fe1004676014597d65c88155df8aa582d9ccbe104f904bbc208e5106e448a44b460fad41c6a08f17db5444ceec813217e562e078218818f48d60f8a7db20ea351f273e5ba1157fc73551fef001839445f18f8bcd0e4a3d14d5431848ef013f80fd7883081ce1ad144b06810c67adc093bca4985829345bda9710f90e7d9e0b721cb61c9668aeb3366c6c2656071dfc0de396942d496aa8534524d91816a37785ea7b69e1632d42c2a8082f6c12f6023922e74ba70508c6c3d8dad4b0feabbd3855e720de3e7c033df67e219269e088187828f76292525dba9f2f02273c4fa3e72acaeb1f17d5d06ac51f942519e752883cc8c104a31ca6dbfb0d0ad27056cce2c74281dbabf04b164849eea78bb0d563a40e03af63efddf22790ec5ae19baeae5f51c9ac1cae8a9668937d4fa622593724a7cb20ba44965d7a2e73f0a75174dc61806c13c60756e02f90537bc085b4b5bc2f02329b9850037f6e4f22f9af210dde652fa91af1d5f35a972d2c2f29b3ff152ca6208cd670a662f7f9ce18c40877aab9f5a23f04a4b4e3013263b42d0be41490b6735c105bb62f59e221a3f7835e5a12cf6781d742643e8c94c4581d6ed1df6022d46aa8a570c44372f61d8473c759e464480cca582c34cab1a7341215aa45f418e9bd52486a3e347a6ead63944e7dac11010cc17783a52b2d843d0c56cc17d75cbf045e3773eb550c54a4d7b3ce7ca5f0c3b308e821abed32e312b104f1977cb2ae372e25ac8bb2bab65c1bfb128b14497321398e3de11c120044641a31b42fef43dff86cfe76fd9cebd7f39cb4d455496019d4b289f5da96e04d061397a11243a1cef3080f5e1a9c1e15da744691101c4795341f017cbe057837d3978085c2387a53d0c06528895e1e428fbea0f59518a7c0d26fb2674c41453445fe7e7beff06ea43a92e791cf61584c5adecaae6922ff22125a0eefe3fd6b102809473f59ee10b63178a7b177b358d86db064f65b867ca6e8bb5002a921841ead9742607aa4d03f7a8aa58b66c18066cb0e22572294f6ee02d45289e277b0ec81e36d3d36863c9566473e18689a202f15a576003f8ac00f240d1b0fdb6bcd0857a6e7b86eaa8d277b99e50c9399fd48a1cdaa10b63c57506a039eef84e4e922c267376159c66abaaffdbb186b6d4f691e88e01096f081af7add35a6ab5d5bd259549e9672d48f7b1c8be26f6de0cd6fd3eba1220dac1b416752d3a4b46ac7713fa55b3ee3f300c2df0f08eb5992ed682098e77128e86de69978032b80a0f26b909b04c3b546eef6e727836a12daea981ff85d0f6d3e385c7668be1d2e422a859ec0e921e7dd6bccf144ec4fa805fdd037905708732b7f5560810661d6678496bbdc706201ecd62c2b1a02302605dad60517727a20679aadc708d1023db52dac037851174654d5aee99c8c1c633e150c39a0cf06aa4dc5e2cb630f4d492616b288f3ba90cb38dbae6ccbdf9e038dee09d196ee63df81b309f644277cac67154cf54da4eb71fcd3c1f5789e73a8f9eb08d579e2b5bef842f0330ccaf29662ffa74787ce4fd8f1e29dc46133088960ec5cc62528f4dd0109f5720d5fb88d13a3415c1be9241085cc1bbb6c5e7e13cbcc1d5e340e91037b99f62001dc4288ca577e6586e5fc4861e3290fbc9baf51d78ef7f46720e16bd840c451e99ddcf172f27a7b35c6fef2e3c82535c9aa6f9d92384ecd130a49f6454c16060525529f68ee21c439ea9b1193f8a5cf7af1d0a09f4516a905b138283c05ec1c03aa4ed05d274155bbf5d5b7fad5b1ad1218788d6646543b7cf5d2b85cd366c53ce0e4fd7287047c7b2bf1d2a79e956f0af1d99ae73c92dbdee061f71e4f661646b1c8003c4cb356b5f25524ea1fe5ea07196b40c2221dd2abc4158059b9122be16b618c64d05a763106bc07882ddd768ce7bc0650ae0baacdb227a7514bffb8336b7783c048603927abc8201cc87214e24a7b0cffba678726b8d4dbbd590124811b1427c05fc205d37730a9914140ddf0cbf8573b05753da8b48dff27b6f7c7dd5679db2f1dddae9c7af267c218c62fb9a7729c846e2cf29a0f11140ecd658b5ac6e36b8ae8490ddb84a07214e22824bc1da031cb9fe4549ea348434b81c43c153a70ce1cbd08a8bab1c8cfe4b0c052d17ea21f209e1118525c287ae01a8dda41e658d16e8f4c015ba3fe94002a376311e901a18d15a199ab6e16c874089284775ce7594970a56836ca23ce68963c9fec58e96590a81b41b37f17486065e0e3f472549d33683d2ed59d6f968e08e311ed075b19590760400b20c23aca3d19ce1aeb9e844a68602b4515855e5f1b24ecb1c2d9aba5dae071fe50b4863e3e9723be9fcdcb60da082c68f3d7758b48333eff20fa89bc0aa46db3fe58df6a19f7d1d46ed781522c7cc0abfeed35736572dbb640fdb980e604b4ae5c6aedd02051adae4d77c9e3ee6985cd7542c50bed2aa89658e9f3522d7f47baa55e9f13ef23cd98b79447f27f1192ef038aa2bd2cbb70ff4c05e27dd8c645dea92bd070675cda7d7ad8bc0c2e3ce6193428815ebd698c6700de565f4ce8adb9812373582755924d124f5a8dcb9d81b2f44eb2acbb6d73c2b272bf310bb9e67acbdc84f8a6c260a85344ae80e3850c9a0cd28d2225f0bee6bb3023adf19fe1c224c16d3ad0c238b5472fe0cd50963c0140e592e9a25ae7489ac89c109492c885595f80b538264b2b04b96e74b57b9fade342c1c9b6b18c9149665edd7698c8e446493459060e618d80a9b8d6619a0b3c8b2d621f75c598de46004895960b53f09fa9d8cfc9d3d110f0deb8ec5521d51953ef6f5be2b1a2dcda9a5c4cd3452bf3f13190916eb4a5e1d104f1506bdc8e8cf770ae7a2bc2d6ac5b79eacbf4c6c05c45bae4f447058d4e1fc6e79769f0624ce03b8d267841ac2d2fa3bc7c7c62e1a634660ca15eacf306932c5462a6005e08aaacdb4fa24818b911629ce0294f3d5026c1f53a640ce2ecf177011235d0b119c3f957e07f1b41189a265c89d11c904ea69bf9c3ca62ad86a17d9ca1adac34d2da70756712e90dad7a4a66fd6bebd694088b53e77b6ac51a9396af2356a77c5e67a6c53abec0a6f8a0526332dd61942a4cad5bf7a9a8ab88aa5e5fdd9bec59f9a216d90162e1d64b5742ecff9ec71695a1ce4067978eecdfbe9e02a47137370bf21b931963b21002dcd74eb6d227419154b8ef69a70eaf013eeda25eae5e2137cb7e56337b32615bea5c5745d20da9013f264ee084af59f841b34cd65228fd7226611f2827be14ed1b0f5c84c56f3af448be1e6facb0a9dbfe1dd1c8160d56824dc12f5177861c7496cf06868e4106d7e14eedad125f216b6712818fe4ce48606fcb79d6f31a56606384d57d5429394dcde3da5c62259d35262b5c5e6f89c7694e03dff1adbd75687d829a46809679488135536786406d6dc269d4c0734f04f1478fbb1cf39facdc42bf87cb10450acd1c9fed1f5a10e56be65eeb4ccb19f4036de83023047dcc2de521a38ab690c6499c113c0751a8b09c73539c16030e9689d52bdbd0cd8c4e96cef17b8b7fbfed1f6bcbf61f9384aa415394febcc05b1522051710e4647fc027e8be625a2133c691e48a309e6f03fd81af657d13a0b243f5a37715b31d9af8d0e45d98122c0d1cc3f5371bcf25ab655a3ba0aafe770f0ea8d463f18220a522b0827f52685695ffb9d470335e896d8501313ed174b78bf98b3ca6bf0a0f1bd34a814c4153ecbc4db6f4835aa1302b2e41f15cf1d5604b730cc687f502f73dd15a84d490b298c8e9d77cf0d3e78199f63084760959e1ec7fe0158ce978e22e99714840f1f425ca2e3fadcd58b268eba294b89f5a6e799b71dc4a42b47376527678ec25558a98ce88fa1d0db7341bfcfcbb94e1c520e5c608e6417a4ac1dd03d6c6143097460de87e9c5a3d880b770a294140ccd9b4fd4ab73b3b4b31833a4350974b438378614420676ed08f09d0db01b8360f6d51a721ceb74d91bbadccd14c122612c3388942f7272515262179a08aa4d9ce0353c46ea7aa09c4609b7d4704106941a5687148bba795e1ffb2cf3e922ac1f3fcc448131cf3f9cb21b157d88fd6bdb633b8e216e4b3f3e6680d689f11124a8fdf78506f78682978c367354e234dc8dba6ac475e7ee6fb3c9878e62f9bf09bed28b7899423c99758fa49ef322b0851fbe24ebfd2314095c9ef755895b25439a5f7db90a99521d1e7947db30efe84c51b5983329e62f99dfac60327fea0790031d69e1f3fcbbd2b0598b9c6f2d318f26476e15627e26b0d6b27ad027a50a832a892f1abb7cf21d4bf9a6fcfa05a62fd4da6aad5ded61ddddf405196a55fc552a782d2ed840a065d0a925a1b626cc83f3d737e9d09f6af0f678609f301efd750755af7efdf383003f0d10df0322547aaa1cd2c0c19598951da7d35d1abeb3ad4b720f1dac250075b6fa5010573fb8efd79ce826e9c97cd73d78f088f4a13efca13751095d35d816235ac5ec0a324277032bc9034422e354cfb62c12218546c9896316b456f2473f0647aeb29aed0463389d1d98c92518d3081c49116005ed6d9011d45049c448fd8bcb6fdcdf94545df8683984a5c762654b391d629b68ab236b62d1c3a00e42eb673a2ffb48b0b36bba70dd2b1789431130b0bf3837e302d1dcc45c5bab0aac1204fa193ba45410380b4d3a958292b819245d14f8bac8c1917fc8f55059c341d6c367a511eee873a983b4bf2a3ed17923ad32d6439de64465637772e31287f89281863798f56d40659be0800f7dd3d79b10b9e5de726f296592329909670ac40937dba261d3d9a871dbdaf463fa7ed51fb5404a80e39c9a0a95e63eca79fa33cb856439389ee6e070a19c108643c7d400c7c775e792b0bf5973a1d152ed32d7856e48ef175e172d154887a8a492baaaeb615a6e1ced3beb51c93796f6c1b723576553ae0acd48f92dc65866abef77a16743997db9c71fe21be771f4bcd13734a8c72633aeca0bfff74fcb3876b1ab5cf66ef7d5a6a676f797d3b2ee3babf1d55ed85d3b2ae1b2749c032fb0fcec72bdcc433c39dd75e5b58069f4fa4e00ef9c57ca4efeb679dfcdb0e3244fd7fd94fa765dd8fda5434a1d97e4f518d49cbe2e7aafa79267be9cdfcddf5b379299aba352959f8bdecbdc79b7bbf7c7bb3fdfb230b54a2ec27200e923c92453503b842d6b59d66cec1fb54ab6b72114fb5b28af8b339425a994f2503a36896dfaf82505cc7621ce7b99658a6b997d0eb69549d9f7bd135bd68e58b3b3d0b6fc62cb9a14135b695f7de9f75866297dc251dc7648f7f73f5d44bfb189b8dddd9dda9724fa729571cfbd7beeee491c4f8b85116be6951bf1d453a5d0b55472e4fae34de2deea3185238a084ae26e085a0d8b02fd79eccfc3f982d18e76958523a02240ae6ee0b6dbc6e3658c87de997d12e028ad8aa82b1c7fb6cb8ff8228791fc9c1cdf2d6d8cf3321fc14ec04fea66521f078efbdee3f81aeaf891d2211e5248cf04627300ed6b0f6bdf56ac4039394d71266772da9a356ace9c3143864cd69831565bb64c59b102e5e43465324da64953523ac104139628519204638c43115ca445d2470810fc187e8b35d00fe06b6323aecd0487a00892c867cf2417381bdfb81096443e42a08b509268680ab94c336b9a914478d31d379bfe5ce342f8a9cfa6ef4c2e347bfa3e85be4349229c4d71a8f3de4b99d6f94ee31d7aa6af8b5d8ed7d1b2c739f04bb13e0f7d25cf9440ead7d7d1b3e994da5f28a54ff534ce773ae7b117a4c726df0f0e7e9806f1fbe3e8cf458cb5f7327bb77ab5de2d7313d7b6619023c0515a1d7121efe90dcceb91eb73817af4a94dffa547579edea6672e6e3a08c8082af777e40757bc53eb48c2c65ff147edc45f7bb0be17e4a005506e22225025bb3e09bb86586afcd3d34d7ef6fd9824badbb669201dc0ad7abf69ece9b1674cb26baddb05e201dc9eabffd551c9c63e5b126ddb5699cf86c02f7fc7f8af27a1c0b93d97f52bcd37942ee2f00ea15dbcafe0ed019c7b0e000fe0bb726f38d2edddafc3b3da1b5ec18fc318e5a143d208080bb83dbd1fb5c2dddb755dd775f75eaeebbadbddaeab33ee76dde5e4b66db7ebae54aab5c9acca29a59cdf757a84edae0b9dd039b76ddb6ed7dd6dab72e3b83be6a36e0451f472c582e50ea516fb47abb848ab1938366a6b9b61cbbbc3964584d9f793b90817e2efb3fab571feac9e3a838da9576aeb66b9ed726fa7784526c6e9c938c40fe7f85c39477ef0f1ec9bde6f3bdfd41fd6f9808800a5e8e6429ede42a4ba9dcc36738a0daff4f164432892f77263f19b1a96419e6fead92b16f3f14dbdf33c3f32d2f7d5c551a9aed9536fb0373dd6bdbd72527e309481cfc4beeb651bf77c5617b1a16ce328f97472d1a56fe4a31c7a6175d1f33104785dfcf14d1d04fbc13ff473f2910d83f4641b4e282b59407f11007065cb9c645db4e19c62c322cffbedc73905cc36248239f8a65602802418c8373509f9c88623d44c70912e01ba027a930c3030b5d28e137000bea9a1b8487f837c64c314c40db0074c216d0a7df4779aae80738f730aeef931978e8436f87c88b988ef219eef878f259f7ca423c88faf271ff5841ce8f80048073f40be00007d2b74908bf806e1e7f3f2277dbcc701f8bc2ccb49de6fa1ccfb9c2d807ce4e120200fbe39c585f2910df1feac96b522cad838d90bab6be3a16f4e11ca453ca33cc4f7379fe81be5232f9c4f2ed6a2a6eca9736c1ce483b2c7a27c64c3f9f461cff3ba7cefbd2e6eb337ea0d0e85e1f01c311d3ab2f9c18ed9ec0339a55c5b28a54f372a39256d3f43d9f6397be72967cb8ca4fbcfc52bb95bef379d7400e586dd0db65724833d36996d5b6d682483edf5f3e873ba0bc79fb16773494625db86b231ec579bc1a65af6499ffab216b5c496fbb5a996b5a82eb675b18636c97e8eac1151266733813fafdbbfbafe74004309e0323b8ab69d8816ec9752ddf5939c86b2ed9fb3e9d109e1092ed207c12631919ef084e65f7e1550ca70e3a8d4512ff67ece106807d0e5d2b15d86e30cd39ce459eff364cedbdfb8017e4cfadc07f5cbf5f77efaf3eccbbc05491f294baf69d57cdf7d1bbfc077bf7428632a298fddb8db79f8cbae1778e30607862327474c878e6cb6a3c7eb10003b1f978106df75218efbc73df9e8761f11b9bbf0473632dbb46953e41e4fdd7803f1e3348f8f1fdfa6710f8fb8810619ec0020d4dfd3c36d3db6d29e1e9fb2a7a703977db9c61e93a4fc15e692e75d15419c01222a0832fb67cb5a10426c22b0f68f2d6b4358ed4aa368a896a5965a6aa9a569aca5340dd572217a75110896ba58b508404080a3acb9bb13b9aa56abeac90ad3f660cb9a1058423c6d71cb5a106bb610521bef4f6be317de91b01b2fbfc78774bc0b71372fed4bbb727264fa755dd7510976ddf7e1f8d98121930fa46946f052ad3ddf8ef2ea7b6b434b6d38564aada59b7dca86e65f615b6ae948d5d8d1777e3a522dcefbd1c30f36a433431a8e124be7836c33e7b7e1927b414bd350ab471c618e5c84bea568a6106badd61e73502dfb99fee4be28165a5d2b1ca19ddde7e40871507a63c9a537cc09c710c78d90a6a94fd65a6badb539a4692690ede96fda7e1185e91b389a7bfbb582e04534cd8759a25813699a2c5114459aa6880e2da13cf563348d28ce5c9caf43bff32c916662a2199a86a6a15a340d0ed7314505c22116fb99b9bb3b9d651ce642561508876a95ea17f5b19444cf66cf9768b6dcb20675b5e57355f6ac01d1b4e78fdcf7c409b767524e09640338fedeef42236c4774a17dbf3a827ae4be43c23df732042592a64a6f3b241989fc2d23a13fff0b6b0d61341fc90956fbd3e624fa3017a23f5f3cef3bcffb8e8aca0a4b92d9f275bacb5926dd7b45bad0b3dd7f437c6fdbb99fb9c8e52e0ef7b9396673dbe6c2a03520f76e2b13ee6f112ebca18ccb479c6f6ba3ecdf2a5137d0e770b8dadcdf1a7dfb03d5b6bfe16cddd6c1703a9c9b0a62b910dd32270f99569b0bc7efd6fb7e7383c97dfb37b2915ce4de2bb77411fbfef417dbf901818892254d52609af214e5bb3ece61f317f5753776df9fc97dceb7ff26960bd56c64d67ea8dd5ce4825f918d7a9d925ad7b47a5599f2016acb5a0f637aa8b2ab13285c9b366dd66c7f2272bb162ceb102c1dcdf61f97760f4ddbff89cd7623f2e73be1b6943e54c909b7bbcd3db513c9f61e72db943f7fc2c07bb276ae7cabba03399807529a10a6cdc659898d4327af36fbca073dded21ff57b68199e5f0ffddfa34708f5df8308fde043207abc0cc77ad41e3ab1f04b1554b024152ba2bcb2658a45318abdcc0890463a51ae0bb1904a4ec223c849d8564145159f638d2063abf3bb15d8aff81c8b4cc2ec672f33093b7e470826ff949c646dc8491667e160430d5938d54083163748f7e123d320a50454a4f80c4ea6ea471650ba0ffbf6addea26ac76730339a9492006168b31f4880b39f99843034991f10022d480d58440218275537f0f8d9f3d060709e879ee160d72f6daecd0eed248dc81dbfe3f10e4d250c4d4a0250e1f13ba8ecf8998f2410e677682a3c2210829492003cc21b763c952aa49404a062444a49801da14ccaec67dfc6c63cf4ec77e85908267361b513fb1d58da198cfd6a3f87b222b2cd76fd93d1dbf997b62b63133871bd077a6cfb733a11c196d7f0678c35dda2d1b0c676db77854fb0abc853a0d16834fb3a44dc477d223323b28d8d671a8cb5386cec0a9fe4d8f604d73de882a33c3e831732cc204399186488e18ba6189ac080a10986305e80e105332ebce082184c2e30e5246cf318519cc9a3d88c8216d044692127657c06c7340bd3d34c775dd179aceb8e6969a413429946ce42b664d0622f298fb3e0b49c9471194bb1d7797b060296684b46b12f721dac6b2ccc4ecbd8a66085366da05161b6c1861950d8d84a23823342a005822d47432a85ad355c05521f58430d5f81d4133562e06aa43c100336ce022925363068810b3048c3054c69bc604d9417acb1f90527a8b1066317e4a46c711aaecf2ecd819b972e6e4d778d73dfe04c1758db829c84b385c1065c9fed962bbc925b7057c06ca43490df6e99915258dad98575dd32e7f08aa43c210b7252b63929631b831524e5c9af66056aa8b00215ac01c31bbdf04650548086ddca001b18f0362e205d44c3db54000d2d9a05fe7b54e0c31ea1a43fb472923d232759cc0205ce48d3820969cc8852821968982620e98ffc92fe40930217249082325ef8644b76fcec6558864309ec0867a1741f2e970be1327292252327590c0304c838d314813328888104148c21c303a4fbc82fddc71862cce00031cc48698099306818210c306a6000185fd8b0802fca4c5140192f46a0c48b2ea824a08b13dc808013d49c0e20290fe5a99900872492f2982087241370a18301b8d8a20a922dc890e0089912ec60a4045af050002db2782a9245560f44b2b0f001098b2b7e18225d0cafb0c24261399a5600414410578488b212d3d583ec635ac410f6b1cb155abdb4b17f33898b5c4ee262953792b8583f3f969e8b888bf57318640338b3c84778661181e509b847daa6cdb67f84cc45f0cc9a581c1185c511565c215584155255606131a20a24b0b2646b8ff86a7051918f6eb25c4d8184540d381f7531b3f1e3e029e4141629a6a28022892c502431e6092590b84f28e18418a025c0515e0de990479ccc540d60ddae2b464b2e62df158eaeb7a1554eca3fdfa56b189cbc25090fc2e423bb05cc124a80c94776892f390967259af8c2449516aaaa26bce4249ca996e8c00b972e3929632e4cfc74e9c2252765cc0490172ef9e8a60b5513df9d01a832c02472640ae926101da101260d47c9c5ae9ffde64e2154f9e8c64b133909e72a2e1d34f185899c9431123924529efa92a80322457d44fad4072285a414698844f2d42e57fecc3dde2b8998c049782e919332ee126609305bbc7860b5258c962aca23e6d69f5aac94f8e2123de8eb111b1209a201ac5b9c4a88c945ece770cc8f13ce2472120693434cc37c3a74acc8330637ae7141b3658dcbcf96352e519b880bd95dff48123a54d5d068b42b46b54af2c831170b242379e4bec20bc923f7d863d39f4ae423bac19619ebf81cfa4a8c0b9badc196352a339b4b95edd4a963225ba2327d22d3c79aa34bf9a955c66fb5efa598c662635aca5e17f3c774900f4486985319091124f21056b224b1fc9d452227d9c7e1a8c2c63fb34c2c5336768242f1053d05fd008ee2ae37378f6f6ebec8a16c8c839e408bb5d537373fd68d83c3e69ddf7600a9ee1c7ed207f64875db10c7fe9c19c97503f637b42ce7717cce37a166ef6c596b628a7d5d283fd012201d123de7cfd13623c1be1f2fd6370bcee320995bae8b593e9f8b29d68735ed410178e3c3cdd7b7f928e79b89251f49e558943dc2da27827c005f145db48fc371ee6f1e9191e0178dc8491c11172a221fe530c4633eabed7e72f71756176995d207052570d3ef2410fad3888cc4ed22425991fcf4732829a51308293eab7d06f181fa4aec5fb1cf3199b18ee9ab6ca372127e1b32718d4bdb85e9148fafe424fc396492dffe242227616bb3ae547c56fb967428f6ddc7f2db70d6a8a030cdfab0e6f6cc45ece330874cb6d436912d59bbfe91fa236c41b3b7ffbe9f511909fd2f1c71759ac5949b9d572af519e552aa45946a7b39bd7d150a5581ae50976075ae20065886a1dab2f6456b6f59fb5266d620a0a67489d6aacaec9b2d6b5557bb56455535a5a5caf6a3a5cd05cbd98ec82389ec960db1db7fe3426b61dbfbab412fa007023501facf5bb70fc93c8c19e1b7fafb5c8cb9582b8db65ddf4ecd8b43eefbdd9eb761e15e8a73595db57b8abda7f4066dfaa6b0c7ed95e81eb9f7be53a2bbf33617c445a0312067eff6e4f442ee6efaeb026a27773f99edab9da4b0bde7f413babdedfd7571ebac68b4cde94ba3ed4ddffd4387ae91bd4c8e65e3fe93443226f37dcf876d39cebacd761b4b1fefaaae9bfede76a48f2d22bb33dc913e1ee4a27fa7f78f2b70bcdd7cfaf631ddec36b739e76c739e73dd7bd76dd37a0145b5767d92e1d844d4a25a55d48698aa597112291a9aa6a6a5a996c416d5a25a5ab82ca022c0ed81b4803a404180e38c7dcee7bc0e3438723cfdb94676adec1817ea1e470eec6b3ef26ecd431cf6f6efbdcf7d3afefe876327e771fc38db76ecd9361cbde7381d1d9d7abf3ed2fd1a5a3dd6d9cb8c64ff5bda9e92ef998ea635176948cbb8e8e1c08123680d98f3f5bb2e27279cdbd373e7a836775716def8aa618fb7afd356eb6c998ddc8761acc70aa4051c41a70ac79f8df3e07f2106bf778c3d1fe5d70b17d1ac713cd6399f8b1f0dc7d9867d125a5354ec211374100c5f5f445f300b1ba2f3301b8ebfeda8e4f53daf8eb36d4358ce17b98e7d986b79ff3dd6361f61dc853223dc778fc47df74bfb8af9f3b7bfaf7adcc11ac77ff5084966d55c04847deda7759ac0b685ed1b8e4db6cd099bc070be623ba630e2502a0e6c00c759b3db47abaaa8a4a4a29e9eaa5029540a6ddada62a3a585a64c991a16d6555515959454d4d3531597e252bc696b8b8d96169a32d686b34c6de642937b202be0c855e1aa38f7e442e0d3e7a05ce8f5f4392b2e14c549f9d08ea7cf6d71aeca85acb8312e247bfadc1587e5423a4fffdeb7d6eb3acf52ab54b74c532c2b058d8bb4aaa96bea194f5b9a65b2525ca48fa3ed14eba46d156d9fb485d2d68ab65156ca4e511e5ab35476ca46d9a91b3b65a5ac0e930b8df639269db1fb6dcb458ec907d07ef73a9e4917724cb4b9e51c937352c66c66e88666d35243e96f6c249113a5592e44b35cb45496ca5a55b9500efbf629968b54774fb35cc866bde895d534cb458a44b13ab9eda5575859b6b3d862706ab9d06d92443852aaf8539453f995a37136be459ba8942af48946512a498463775c0ca0ff5d402d0c3261a009238c23aa6a5848dd1a16524e566a5838cd1c2cb91ba08b332b5844050d415f5a3b6b5830edda021a3a0c7c7a16f5c349a3dffd5e6e8519acac8dadadf2256baed7ebf57aab9dd03b34b73b739ab5da61ae2d9c5b538d9a352019e7a91fc6983d4edafdda69b1c3a8daf527533e723dc2c0dd645ba7ae5f7fb5cb0b5fa112359cf6a68a4fd87604f3169e3102c7993545d6aeb0b287a851a5bb3e91aa242ed465b1eb2b39c1ae3fcd58b9c806f4e6a472201880f42f1d22522489fcc798f8b3a590696602a93f694276f8ba726d210ec71f3353881751858cb1ebbbf628e953a79a1f57388aff0a69369c520ebd201a45996d8cb070415580726fdc1a1c7e21d32b1c63e36fe12882e1f853db4cb5a16a63d5e6ca6ad74b27d977e9fb8552896e1cd2bba51ac923ad607369924736491ee9ffb968b9ac8dc071aa715aad6d31edfa738d0fb9118dc9df3fc7d992726a8f5bd6b0ac6c9d1080b286e5b41d8b861a16d38e6d55b165cbda14517b0cb2eb1455f608ee3973af428bc27adc6546eccfa5cf6b54646d599b226b0aaa8d5fdf77b511388a9bca5a154f43d4883e08b4d61a7e77cbedefb63d2ce643f7b77fdfd95617b9589fe621419840b9e70701c185ec66b939e75f0bfe136c848282762af5f7e2a12cc0192c1d6389a574f7395f4ae91ece2c5f414fe058eb9cd405c614b425352cab3b9d56bb71f7ebe494f73a4d9973765d54b54229a59e67a9acb516e3acefe3388efbbe8d8bfc755dd7e56ccbb83e8c3176b9ae18af2fe79c5fafda9519afd70b046b5756b5ab346ee7f2170bae685bd6a4b032b4652d0aad8d5ff2af5700ac4541668f5f83c114ef9cd86e345f7e10bb85a00dafd89f3a0853d31bd970c779fc03c179fc7d0c326100e957bda38348008e4182b87b6d02120314e6fbc25550068dac7966bbd33403f40538cea63d2ad15d5fbefb9979668c33f30c972a141403388a206c2db0cf19fe7d5bb775e307acd8b4eb2cedbe7694d6bdc56d928edaabc5dabc7da79bdea8fb4d2fe0d5c58a28cd493a7bb56cfa553bf1dd81a57da5690046f73b2da3f7a3bcda307a611add67ba51b8f04b9ba512b828befaf241d8cc797e5c4cb3ebff0405b9d2f446f7cafd2d518c19b3062881ac00679248a604bc4f7feefbfe600dc7d8f62dc4740efdfc70027c62b713dac6cc9e396c10e6b37eb1988d7d92886e0973ebb9c8cc61d7a7da89ef273c7607969ee4d8f49d706ddab4b195e6a68f42a561559b072cbdcc24cc9fef5b14dc753da514767fdbb6bad5eae0cc1d080b1cc59f2049c4fdac2ff6d46a7d73f73bf7fcd86ff6b9cce51acaea2f6da4397fec21449440e68f3baa3f28615b76bfbe33f1eeca9a5f5e6e47fa6c9bbd57ec09b29bb538a410bfe36b6ff7b7c7d4e3aaacbb6a99fdedeb6452dff7116cd372dbdfd76df58ef4d9dccbbc50d43d4175c666dfcf07619228ffec7e736baf75ab5d2e5babb4dea7e7acc6661e7e0745d49834dbfb3eff700204bd2f3ba0d2c097f9e8fa3bf7d51f77daead82ff2a3ee6dd697bb1bf7f6feacefdfe9edafcecfe9fbdee7eebdef5d7bf937ddbdebfa786edbf6485ce8bf415142ba9ff3ff1803e6f979168b6dddcfffe12eb75dfc713636abb7ded8ec9f009df4d8575e7fa5c91abdbee7c7a9f72f50cb94bcfe755f19ca12a3d7cf4c41ad02f85830205dcc21942546e0cfec7f5d1a757afcc2d07bcf3dbf9e87c1ba3b5d77d01aef7bbff7f3ffb6cafdccfe557a2d0a2b1bdcb20605d5c6fe79cc4519c39b8fdf96b1ed5560100b402547ba1eba9c471658ee602969bd2ed211047dfb21e667d69d0f7fceeb2e0491793fb7bd3f2ee49bf7d4eb3acfebbcce9b92a86e32fc7333b1ef9f93b9f187d508feedc96b7f8939d7f7957c63efbbcf7fe622fe4b7b7ad37f8c01f1df4fd7a357de5e7e9288e32a955523db738fb47d0d47285fb5b908c65daef5b1add4529713baeb7363de4e5d36fca4cffc4ffa383ed38d9956b3d2799f60da9452f167df1e637b661b561ab0dca9d1f98db5c89da87242ca2e722149eba54377da5cebf4af19c9d29ebae62217fdc56c51316b36a55fca88d932375be9f41eae710321dd02cb2ac64a90f9b9e3ce29a55dd7751ded3a988b414f200a75dbcf5ad84be8c7c5faf25f624cccd39cbbfecc56ead405ba58ab0c226b566a86dca8fe111772d0b6b1c3ecf1ab5f3f4912dce5234abd7c4429ce479466bc6d5c7e24b97328733d931cc402902eed51696357e7d1a58d75936f7be11c832949fd0ffb7da2b6bdd6c07cb1a75fdac5bb74a1944efaa4c7eec0d2ddf32f165de817b098569a26e8f2055017d8bc617bfa056bd33bdee77ebc746f5eaf745456570da7d432f9db1f3901de97db6545c227a3127d3752e48677055fdadcc9c0f8e5e3a01ec0b1eeca84993d6bd8b2b685cdde9ed2bff47195d6c68fe3ea9edea7f46fa6d8d3f9257e9c70ecc01275590abed2ddafc79c4fc9ad808293d9667faf74f78dc7292022bd2ac80c084686f3f6f38391e184b58c04c80d7f0952011846963ff63a1f46e7eb62ffc2b139e76c6dce16678cb1cd365b6bede36cbd4c11e369cb9a99293355b6179a1a8b93858333b6cab8cbd4d660cb5a97a68d7f83dd54fb22b5ede32f4fdb7e96b2edbbd850d176065bd69ab0b263574e4ca8d9221a34b52f5b1bcb28282d5adbd2aaad9da9b2367efba5ca6ae3cf531bbfc501bb954f63fc1e95876cfb3106f595181157a28a30c28b741f477491e222290f16aa2c4d4817916042d21f534b24b145521e25b4685142bac8c316aa2a2e5c7838420a4b961f9000337dca9503ebd20587892e436cce63ea60e4a4d585f3765b2d613739385ebcb876c8593e243e15745e1a61397d4ae743269da598c69ec467b502965cef3e6424dff9259e5f7e25745c3ada6aba16595db0776b5d39195655758343e501972e60c48409e3250c145658803dac26d0e36f70aa5cd92a1f59d88d0d9580b09d93f3312ddd0358cc9f90d3ab0be775b434b25ac26e7270c488717db9e9dec5e423d71739d6d13257a8048412d32ac87eba4c014b46b247802c64922ded9856c092512cacee817d9a91dcf390b9f3c7ea7477e96c9996ee8195696984a54b31abac2ed74b23aced0e02421de18804172b4c1f49a295489ffa405bee85015d01ceb0deb6cc0f98dde0389820128459920990463a0a582241152e545c3eef522527611d7212b631adf3ee057bd5e75f72093dfeffc3303ab8870ee33ae4e0841039e0f0441038388d0142d21f3fb2d30d5040f90d4e258a0f7e4c8192fe90e2ff6325488944f645fe2309b0c7cf5c421835324f20043541628045b2843051be00a1b5d63d5ee6231d5991bf0e424a22f4837fa8306af43f54086a663eaa40987f0da5ff5f66134230a343203e94edd0e37b7c91b761a4a3230b7bfcebab305162efc29291ce13a11f40219d90244aec75429912ae8d91ec9ba064239d5f3292329d708afc61d404fe1e8e75bb7b38e7f436f0fc9f17631fbb41412e607777f79d9e0f8c92b57b827e071673ecee2478232c71f1e8494a915b6badb5d6a7136d322961c0c5265068d4cc336e45e4c80ee0085e38ceb6f759793e9a735a2f66f3519d765aaf42d1683423b46a5a66b4d00819414b8d04729565b1f5e1c393d9291380df0c7b5b5a4ea0d6534c8b494b4a9bfb094d2c52f4979edda6d068b422d068010d19d0a04234021a3b481fb94751ab055a6a481eb9399e3d33cff65c25a536d3b96d8865e7b6e196e88564382bcee30e05e55330169ee246bc9f4ebe23d2cf0a8fd70eb97ebc9e8fd9a69d52f9c80b4f00facc50f4846ba7f62b1fe3ad61e546bc87e2a27b3e6545a1fa6ccc7d77737ee5629a315b5e6d5933c3873464368f2d6b66d036fe3e97669a3fb5008d3389ed3fb148b712f233ac7462dc6fe68f227948e83fa19b89fd8c94df4ece1bbf90fb201d402617b0ff5bda198e998100fec044cff3685704841446d8534f2bd1ed791b80ed26b0ddbdd5f94bb3c6a6d9b26730d93362c860db4f73c6a6d1923cd2676357d46bcf252490d7e77aeb0a7d0ae509a758a1e16e755535c6cc1ebfed55533e45737733cdd2c52d33aa064a1771b76409a766842556b5ed242c51c3850e5506e8fdfc51a281ca5ce8563e46cb6ace3d4e2d2b9f34b5340a75e70f77958e4a3292b5f6b367ea0e2561560922c58726564f0f0dcdd0dc02bb7704c31915f533f18e985f31900235e5d12268115e28a5cfe7539268066d012671d15fa96a2ef4e69c33045d7a4a398ffb7bd46ef2cd4d697b3fe73767c6a15bb9e86fe4542e84b587dcc87dbb4f8d0ee5504d5c68eec7e1940b4df7749369bd30888b6eed2cd2b6ce992409c544927c01bd1fe5d591efb116c5fc9ee7fd8b5380dedf1dd145ff3078c10f9ccd84c6ebc16658a0f75d6ce66fa3820459017aef85452e42d9f6c799883dabe9ecf909fa71d1843ddf5a1be4a2f778fa0407aa021ce7cf2817921a251a6b59b027d6533799f9d4389c9eae7b84fdcf1e61890b49179241c41fe95947326c596accd4d04c810ad22148871a1a5a2d055653413904e11054058a4a5a535881f3524bc194329acaa8613f399dc97232d85032d46c4a51b0b5291952bbfed46345e228a594ba4615b6529d61a5563018e953ca29ba65ad0c2c9bb3e252ce329c8ef02d6b655839ad428e81e5639469e26063bad96f62ac2579e49a2bc616c814932279e4185434d8755a33341a2d8b917c9b8f26077bf470b4ef36dcdcbe2f06bccfc43ecd48740d9540a1fa371bf1df68341acde650060b4b8951b5b777a92d6b669a6c186cb4dca37fe6be0ea003c1796c102d37b2db7eec8d4017b228a8b2ed1ff1a16a44b7fd98b51f34b3f63d23b9e1f6b022efffb9906ff14f6efb757ff5eb827800ef57ed142b5502c980f49164fd5bad24b25512552a89a84b22aff5c8927c77a79bc317c6188763936f672028c0b933d52f7757f8737bf5c35f6c02f1ffbeef8b4d21b319def63b0912e19a91e8c63fbb8ee7f7481f7fa035c0ed69917b7abc3edb9fd317e62edfb66cdba6e461918f1ede6aa5a5096c4d1318f6a7be54270a58eecc2fe809b41873e198c2fe0b8e31eb2485cd8d2bece984dbdcb67163fd5a819e00e757f965297db52bce34f92e8dd66ddbb6edb73265f6b66dffdb6f1fb4d5f6c664fc1932b15f5fd8c9acf4058fbbde538ee3386e72f3bfc97d94523ddf6afad16f7ebb8eb0c96d8ee3b86ddb40342ca5da7e2b18d097f6f69b06b29a77537d7bc0f3fd3fd8fc7009969503e36ad39f4d341a7403385429f79de6ae7451d226b00f89d79cbeb052466b8b6d6cbfea4274e24e02d938fab8bae4b63d92dc8ad89f219322f3392ebc2bec51896e2e8d335bd6d638eded83b6aca531b5a50bc9dfe8f66c48916c3849369e646cab4d60347db1820d5650c8c64e2551ec2deea4101d1248fd106c01942e521ffa55fa50243982520a906e7a933e4b9b7e5b248fac926324962423cbc82fce482934c217670c7153341acd8b9114b265b6954a81c1a80206141851604c491ec964fecc74d2bf014ba01580b2e6c5d31ec52dfa9549840f41ad54216c101b101cd4fda1f3c1eb013f7d3ce41d5c2478550175b891c30d0e384eb01b7050c919418e29311b74d4a043834cca6c861d32f088a147d3c3a05f085d0000d34e940c5ad060b2b0c1a4896d78daf0c1c68fad9e357cd4e0200640d8fcc0a0833402f002a035412ef0a005422c18521364051fa880080d215a209c21803403302304344529d865189141803322a0e0688c2162209921124611300af085913247bc40d285014e90544b6282037081802d124046490914a0c502b26040d6085834e00a0758f1002c12aa80001511984202574ba49840142540418131263c5101272c802f6085811032308051004c4068224403441bf88003414e1872228482071d085202f240009e74f0819f14808080835d1f87c067d7c722e881f243051fbbfe0f5e816749dcb40d360b1ab49041941d2600b810bea061f8a61e31f09061c70c3329321a746ad061436c4a8e11e450c17103cc0907879b1c6ee800567991c06577701ebeb99f640fd9872f88cab77fc0501e107606918fb60f62012cb28209f105d1bedeb007a80d38deda15185bd6b8300387a53976fd118888ef471275df105d6c15c5ba58b3ebf704a92f42ad9dc069d75aaf50fbf381da502fa4587ae5036aa3678b3d3f364a04da026908c406387f02bd001cc51e203640a02d10280d50ea88202a178b67a9486c53d7fb6c46a2405be07c117ce886d579b65742895a6dcb176c59db62cdc69e91eaa661934fa422901ae0267d828c00fdcca7e59b5abebb059979b5658d8c947de9508fbbf291e8a2ddf26d81f948144ba02575d8b2a605995d14debac45767be5214a108680d90fb1da02cc051dc3bd37ead61b5e18e0b855a8cd9b2a6c5963db5d8b2966566772085dc90407a7e2491c51bef0f943e1f13f9888614480d900958133954312e3a5d66db66a9171e55559f8f6c28f6c400b4f38bf82504b353c36860258af1e144cf131c8cf9812200510449217415640a222a40a86200584556185d21021643b2886451002d8e94c00064926c8180cb8512132ca036c2091cd00509d38b08dc324bbe28010c13c2b080190c88318ed104051b387302192894a1948227685230230469a09cb182160d8d1654c0b48217d434b14086164871410d6ba6bc804a1a4e30c8814d9518eca0c6d31a3e6c41b111441b56661b2268512c18d18254942c4c532e28f1c216189868a28aa18b0c5533809162458313358cb1218a295723a0820ad60d573865e1a0450e6474e0a24a8d045dec508607309eccf430860f677e28030a0d106982d012420556d40cd10222d65c49238a4d116a18b175c46c438a86a5852c4c48bc30d594840c4a48d152c396294b5061c2a9891ca8aa70d9a1cb93171faaa0be0401c64a1822aca2c418e184d41359c64c41a144145ba460e28a6a8a2e5454550106cbca0a27ae1883451459575950a1055609ae2093b585165c90e9e1221fd1508c02e93bad76e36ee7e12fbb5ee08d1b1c188e9cd90e1e3d5e8700d8c940830d441e1f3f7a7c3800f2d3410080823c101a0af201911010043080108ab6110144381a8244a448018c1c416280a42407404002942860010c18a1010e78000910888004964ca0040a9850010b5c000319189934d1c00638708213143aa0e481271f480104211001141556589ab4c9c26c6146994cd385f9c2846136cd18a60c73862965d2306b9836cc29730493cabc613a4d1c660e538759659260ee3079984fb387e9c3fc61424d206610538869650e3189985766d42c621a21e71153cae5c40719fb0b03f2024a3046a9ad3e04969f9535b140b3e79c73ca39017caf5b05a4eca854ecd8e992562a9a110000001a5315000020140c088542a1509806622ee61e14800d86963e6644950844511aa3389261209a310600838c013023403052c200e2bc81b72899f9e7cd6fd94238a6202ef7316b79e56720c2df59f15d4193a3422d7f5c7fd6e72626066d5eae68c65d70846f165ad570db2644f984d2952ba1f4e0e586ca8c371cdb51c4f6f77d77b6616085a60f624cdc9e0dc6c06f929dc35e5b3213203a3748268a061ebb5924a00487d941f763060fc7d3ba613e0a555fbdfda1f2bd8633d15304cf0398122568d56bd3afce8293915f1dd891b9ec8eb639b13be4a9e945db66fa17a9b3bf4a9e6e04f2513a4d8b368716b6dc3fe600652f29387dbfab43bdd8c698d5a0cb29b303139af69d500d30ed69d5a0f3cc21a78306b43c8ee9eb42301d35d3f111b422b84340c03e52ce0800c03c5d1aadd1103ca840326ad89d14edae928aeddf06655fd8054580bf7fab038a354b85f296a9918481b5f28945d9dffa1c53f85bee953d5863a4601803ee49643661d45e041ff98531af7f5613b878f8d5d52e46a3e2865da20efa1102ca37fa4a4e02cec7d743f9475a8dcaf0e14e6fc3f4db09727d561b4b742c5a77bbacda1dc07866b5a3a32988de12b71c0b9b48dea7830b802e65f00dfc029ad1f82f5f7feda24371e01287d1db568c0255e39d00983baff1e7269ddd2618c5bb79c63a748679a82debd2c32c79b9ac3f2f755277b8fc2ef4a11311a5c8c0e2a0560a138217524d607c503ee1a4d9efd70ebc87c96655eb7040837e8ab04919e28a6c623b96b0b54313a53227d26357a8ceeaf5450a9699dc13a7d5bc691205c0716e5b6d42ba580d86ab6232670c5c8d1a06b48a0d346af5be24a4a5440b3e93278e1f1e152bdd4b198efd6f8cf45f53ad1aa69852b31c8d4881c38146c0b028b21603bf50a8f0cab564026c09f369ab3b91f7c962e517675f7c23f9f3c44b7c1574b2e6799a58d462330eab8c25dc34d6a9b2698575f9c379eccea95d9b3ee5c14cc0d3cdc078604a30c0aa075d0437c5c5d3c50504ef991ea190c5ee833435e538c176c606662cd193aacf527ee6cf4fe6a2852ff3d025d218a75801f149a5484cc8d703f25ccad9a19947fc4b56dc33cc3a60a2d88f42a0375cb49e7f4a18c5f6ddcde3c3b479fb9832bbde149554f6f0d7f1ebe1f3a32f3d722c90bfbfc9f25d95ee9fae61af2f68cf847731a078558e5f9858d84fc4628356dab389a8d38cb6d26c8fcf6311a43a8de227c46dba0d34b1daec67cb564618ecf124c93eff025b4955a2d3f738915c805796a65e3a6e0a7674ea6a89bcadd5a89b3be58fcd3d69de8f59370814fb7ea02cf7f1b00694e9b31fd00fa807b07d10fa4e9f0447df7e93033f2e0c3c36365993e1da49fba9173ab4eec947c54e6f0f2c184d855e9725ebf48be60afa19053011a43a0353fabd99c4b43676c5610a55ea1bfa35ba5325a750f315f2f13d06b113cc67a18a0d547a5e85b02a76b01b1da7c35eb0871af840d7b91f2c60b1ad80e5351a6a526f49115c3726f0ede861559fc900d65b5c675bd0e548220760d68d41e127c26a11e1aebe2c9628fb2735676dcd6e423d1303d46a2bcee761964ca712c3ef1b58f8b12b74fe0bbec74da5bfeef9416f90c34d028ddbef4c31a6a5a39e36fc311c9eebc68dc756398c1eac625070c1acfa8dfbd737ca4d600064b03ade029a51040f6d7efb1ad94241d662dca5776f80f9518c19b154c8b064b1b87fba8981f0bb3ba40fae8dd4c0c74c2c4c2baccd0d9c97446dc773b4d53cc9a60d72383a78acc78d4e598702bccc80dbe41e740e60ade3c209b57cfcee2a097d661a57f9788353118e2e6944f81a68a750c34635025b81047c3433d011b8ff9a7c262bc1f383761486ba3ad7cee4ffbac6ce04e405e454e9695045dcf28706c5fbfca4e6948cf41cb353b9d15b983130a1099f708e693f8e1add347df153023559984cee54ec537866262c8088731f39283370ef6c9cc245d2e4962e3f09646518c53bc3b61188f5c044e45e91260fcf9b7bcf6a06df0c35902601bbbcba0a0da24986afbd612de7f7720a8f1cd5145cc91358ddb0bef95df19f6dbeb02135836a1f405dcf40b85aa04e6ed39e907429dec5e1cdea3472e0b7ce4938b47012a8d0755857b8e80ad7632944e3f322ab2a7fb2d56160a9f3e1358f8584c399bdd8b103afc04ef958704f4eb73bc1ff53b89a2782dcf13efebe0ca17bf3957df2466148761880605472c82f24f3dc662575c9cd8dca3e65f68a713321d67177de77e55a965644712ee600d17a760e724c5da0da5d41a5a799449b9370c1281ff496e14dde1f5069be1799405be2554b72d4bbb836a9e5b06d31288b464ebc5a6c76569269ff06e52a409b6dca59a37fc7a102e8d9c359d447614a880409e8c5fbc5bc7c3c46536103e650ea0e0856a5aac4a5e1147c4fa46e9d7eec862e76ba00664cd79aa1944130162196065f914d019bcd1b55a00d5cc12efc0b9f1fbcbf48790ecd4c5ac4ebe89ad469c4bfa4479794b8114f1cd04db45ac61aece26bd43c51e1156b4c3c499faecec5349a97c9304edb9dfb44140dce5b07cbdfa8abe5fa7869ff93e38e09b24467a9970d43c77e62aa7d2020c6e613183d3ef7a630ef56446851267735e272af9fee95ec17c39b3e589b41ae20461847f342c8d22c4b3c28d6d1d723fc7d3c8d9ea04365266ca2f6dfaeeba9662e91c82d820bc157e222f70abe265dd3ffbb236990c8fe485e66860d81286a402ab310950e700f60b1f4ac262a068b292b3e3cd558bdf128a0643590b7aee983c538408edc7dccb1a8ca5791f9ba5212e63b6a3bf20e51151184497ada94a07f3c1c2b4d0aaa2422b4217cc9e1cf4eaa66a8bce14cd267bd6e60d13fc343f221852206855b9f71d7428936b37c0411d29eb12fe61da96cc93b5c4bfee701c875e6e79f4629f42ed817c38abfdeb87d6be6d82af3a342e3ed8b8b341776b23c5edc42fc1e9db4de12ce3d93c9159b9f6b6465e2de74a3d496662d0290d8d11efbc0a94a7da4b84d63838671389ae4aee356740782152d9565383ea3a22288649ef2b7045c9c5db760e1b05e9e112b6e4b50e0e9fdfa2cb9e79d7204a42778af7b0fbc061e16aa4ff9ec28dd39a248feb2d4dea6e84cb2b5c6d4ce19a453c1dc51d0f40c3065f7913f7323b0e79122243e8f6e481cc5058fbcaad7960870327cf722ff0947a260c8e5f71c7f72670f7883d64ec1a2fc45c88a2199f84e7c5f49be80d1c1392259b7580268f38fd5c41b06d0202454ba5e79d5f6a98bb412b6639ff57020da4b30d7a13a7b6d0d86685a55a629e10c940a8d2f58ba06403abafdb4e916c697dec40ad9b6c2c336a1676e88c0f00c65e445ba53614c3064658fe9c261781e36afccd7884808c97604bf4d485be8198d19e4ba3134092864bcaeb80f29cea2973c17e3d7873cdbfe54dd48ad7d311002e1c9365e0cd7bf4ed9d94620f6528c4c2cf3ffdc6dc82efc1a9a1cedcdfc230ca473f5fd7e83ff62834d36791115cba1e96a503af9d223eeca1c8ecc9f830348963098ab221fadf84c87c2a765a45570d4eb50d7f830a65ba0157e842a23a8f9abd0c9ff73348735d3ec253cac949a5eb40bb5ff23568191d0b6c02e2c8925eb976758de3e6fa4d73c2b409207bdcd096c1f76a6e06b30217eb22772b8ad39bcc819f97f91124240384ed84733141a4b54d5b96759bc4e90b3312c9b7771e8f535c8986d931a0a9b365b101920956af64c19f449ebcd678bcc7efc5c73a92197f5fa5629227d883c4dced4b2fbeb1ae49de71f6d6ff052c815d537f8b087b7c6b0cdd914b88cc104a10355ac69f383d3e3d0456c1cb22d3772a750b3c1626011eb3e36191baf8de2c459599cefecf5b8602917f15c8eb3596847b2f1f21b58b882995023a5e7cac2767dce1a8f9f16a5e8d95b8445b4e949ba84932f0b90cd15320fe3d237dfde415e6ab17d9f3a3afce9cca17b5ae3a2e706c0faecee3750f125cc104d5e95a16e6e481da1c7991cb9127801e43c3e0ee0280ed0e1f276d93da76783df2d360f54962d0ca421812e4269b2fe3b43f86debc6bbda8179326201011e62e6fc5fcf48ff268e83ec4cb3b1f44a6e0e4080bb7c3f1bea8720e7620f45f87cf35dd3e05e80f357f87f70db8b095b917b38df685a4bcf59a4686a3847828a571d019550116edcb2812f7e9a04f0d6267380542503804048a6ffd2b3b8f38c05db4ae9f462cc0da1a963ba847b0df8a0ec775f7817b3a7a24b86c7e57a0a4a10f19d9509415089557846623d1ddf938e1d72242743114aeb0e4c23afe0d7e56638747dea688a4431ae834284bda82f6cd161c620f6601ddff296d6c65c4a754e09f5ca02692d57705c944924b46aef351ee4bc2ca11bfae85e06c1dc4c59de534875e42a14c499a5a0a55f213adf2d4da62c1ecd55e0dafe9756133e86b3a038b7ecd0db0f32de7e3af94eeaa0d57653adf62e131b085c757585a7e0ba0be4a25a8a23df3de50d8dad786cef7142b2bdfb24d4b1fc205f8a450ed9e858d3f8240ae1972f3e906080f852a926bf25315031950d0f1f66720499f819ff31da02143f676a5318a04470038a9f3288bbadff3e00e028cbc9d1077b201bbe547be96ff810736205ce889171f2749ad182003d0ec8c8ee2a82b395a41b3e8c90b48a937605a0d90a3b8da2b575fc5496e2a24e04a4c2c8465d34c99ee11cd1c7d09b3b97dc65837547222c25eb5f8a9b87095da22870a2b1475c9306f7134a6a23e3893a42f69249cbdd3bbf97a0cd4bda7b64a8366971b6c215494d6fb841a4116a5b0f9c7c68cea28f1c973ff276566544fef557c389b13846d89d572094f8786e6d19858c4538697eed2dd0be18d2a14d581137ac04a21fef59a7697c6b37abdfd733a1c7f5c9aaa69d9e1e69b6b494ed95eb4f1a577683e94b9bb1631cb101284c2c4c9bc394824e1c3354a8215b9f512147e5bfdb71c723a7bdc60361c0aa41c676d00a2b7db66e93eaedc344839167dcbae76bb076d3d1beb383d8b5406233dcf0439af87f7e86bd73d42bd63bd86d47c2c4d8c7eb223f86c400b902ec0d55e3bb744eb2fbf8da782a49dced8137292f34623b034ed6c9da3588b1ec938cdd0b894407e1f811d5ad5d61b84ce5f9bdb8007cfb3520d857f9765f62d8ddda5f0973a9ac2cd0839190a434e5a62c7f67ac52560c47e2a2edbe56f6fa0660d8652691841966f69d88856ac048b93d1538e7ec7012eaf9d3af9cb716a1c13c9e20caf1c152ca5465a1be6df36b7b05d738c009f4dd60d720526d772375b058457cee3825413b021663aeb17fcc26b7759bd0f5e1f1022d7623bc47ef50c86ea07c5453cc44fb9452deb8c11ee8c535b52901513b031101c28efa7dd0fe62b3d53bb53f5a6a8a5ed680413c2e722bea9e935c6919fdbda6d5ed4bb8f9b891f8f045b60e77ad31dce4fd096011ec46a95f1ac1b7ffcf39184ddd4eb7bd82e49af45c054f568bc5f22626c512e397ddc93e023e7379d357ceb73a6447e5bea952f206553409643bc7bf357ff60860de76e6716306127e580df9e25ce2524115b0681bb4344bbeb76f49f7591f842b1ed698e26b480a78f6f0c5eee593ff2c5a8114018755abcfc5bbd4f11b3bbc5590882f8cb82c1e00f614db9e6b7773ffe1cb84d0141a6fcb85cd7101dddf7c211de38c05756ebd0b378884e28de1ee3101cf398010e5242a1f2d58fc81bdb937e76c28689e0c743ed976bf23de71ecdd6f501adf74ba9f0e4f00849b98371b3e330e49506bc13a37c5520a5bd2c3b78c3c9ff1ece4dbb7c87c99747627de3941dd0703a1c4c19c42503ecf6edabe189d8f2ba864fa9f052585fbd82fb9d863217421de006d2200b4377880232a199ba26e7c39627cb2fd2d1e16c81f96a5b044878a8319ec215b2182df011612e3bd1e3283997fd82725181bad0e48d7867d3ebf3312aaffc0fc9b8d48f61afbb590b197aec69df6c0968b90ccd11e45a560ec4aec522bd5440cd43d3542b37aac71db94355e8cea6583edeb465684b99178d30e2de6de19a45224584c49cd531e2d81d3bb95fa97569d2a56c39e38c9e89e46ce130e6de1867ffb2e5803f9e8805734a705a699666bcc0ade326b6236cbbb056289950494bdd34f0d2f6ec26f88ad67fcfe028954557a8a939c42484bfde452b644e63fd2dd404e6e172088810431525f89f7026e8f6bea92a27af34032955d78060083fd40e44bdd507c011c4e68eecf9a13ff40031b102d60a7abee8bba18a57076e3a3c9b070b03a6ca59684ef810ade6638bde1bb863bedc0a1da6a8278429f41e138a6766ae122f2ff014864d3d6ca0e17293d5baf400209a633227e9e824737576cace05089c6daba68a0600d23d4d72150bcedd66a158e2265a85445830b5532a67e9f000436edf6ec90a8d2a3554a1426c38ffc750418dcdcb5db40c1241bab2a1181c2b5cc243f4740e146aba55d3856f2a44a050928486596fa3f0a0ed9b058b242e1a54eab6b910102148cc87f67d0d0ed55ab050444d2bcae8e142a58c948f07100176f5bdb5a8522250e2aead060c1744689df83c0c0369b9d351c5ae2b0b212092344638cbedfe67840e0551151c5ee111b76faca9262327e697e398f59fe54fe1c3e196f39bf24df2cef2cff0c9f14bf9ca7bcf0c709e9d4a03d30f960487ac69389d2e20bb9cb21c9f288f2346fc273096c34f946438d861c0d3f183e26cc20b47168e390034347c38f84180a371c6e18e260f8d8f0815046a18d430d861c0d7f53031fbb670c01afa0760822d2aae28824b125904b23b04874faa18979ddf2aa5a31b7b392c7c9f1d406517e9ed0ca538ed43bd82b53a4e23010c6a8ed15ac7b5abdd874b0f7fa61cf9a1d267dc9025c633c5bc5855a93cb13c5bfbed84e9eb51c0ebb85fcb41ba980c40457629d764d09904b9800ddd7060ec6456c11384b3c06f4d4da0a22b942d551fabc8ebb6e6d0e7accd4168b6449114bfcab358eecdb0c0ab0a07af0e4c840a755152d8af1cc9fa9fafbe5040d191a1d04ee13664c132867aa8f079898dcfdc1db1e0f60d73aa542b75e860d72dc2df1020cd8652a6ec310cb6f143ee63b848df5ab40b254ffad4f3f2a33bfe7d88a3251630d93be51cb333c6ddf6edcc6a862c3e450da8ac972a306e23b74e8275117fad9d89b00420337c66ad01104f15bbb5824a4c4c608089730b4b0c9228075365139fcd0b9bedb38704fe1c7c28c4e80c7965d3751e6746038fc9409cbf32ee2f0d3fc911bc6da33ed04c7155800a800929c3763ea3f2deed7fc97fdd3f61686b14126a995f074949e622156fca4c88333ae414d1fc8e6b0ef9b1cafa978458d0174dadb79805743ad61ae0c068c5d1e7ed40f1767232ed7067f004ea14575b20ca0f04898a73b789e1301394b4b8b91989f38d36f6bf33725890bae0ee3994de5f87c60b6b68fc5df2999055468af7e00003c1a99682e2bf05b6ebb6815f67f27ad51976159dadeb8de690cf2635a9f8ea67d5ce848369a1941e00e2f815c8bc6199effc3c70b000b79917fb1a6107ee7e2489cf11d8446fa1ce223eb29698b484d47468e3f4a828ef49aa9277dbde84b6f0fe436f6d95bffaf40d592a58887b1c746a660df8a694d0ac050a9d01e1b38cc73e80b7ddf7aceac7c0139de9883ffbd9ed2ed57bcd4b91e6f24b0aaf15a6dc124b271a91371c862575ab3fe10f4b963211fbe877e7f6f09ee3d72fc000ee43370d138c5291ed3cbe4c73a4c3acb9c75145916cc3fa9ae775443c177584949c0c7940090525dda2343e937ddda34467563d703d0e30d8ee3a0b80e8af320380c80d360dc0dc671a0b8078a7b001c0cc06d70dc06e274509c07c539001c06e16e304e03e33a50dc03e2a807556c9ee940dead9fbb2b051206fc950220a85b2067c91b5b9d3e5fd100384de83a9aab7509608f2a5b54479e5d0aa28d47495720adc03482d00844151c5da0b402290aa6100c45306ac1a805a4149032055cf4c2921dab2f2af9fb202f833649ceaa9749ff7cc89351331927b5c5e4bf3df264a899d079cd12a97f8fb655fd42c9ff4ff9996849e4a8ba90f4e7b3fcac9a9338525924f9eb915f56ed449dab2c90fcf4c88b5d6b52c7b58b257e3ce0c5d42ed969d565a9bf0f7860684aeeacbea8ecef87bc0c342438575f26fdf7515e468d091cd42d93fff6cc2ba306d20a26e0a4b298fcb7679e0c35933aaf5920f5ef313fa686099deb2e4bfcf2c41b5b534287b5cb657f1fe1c3a42dd1a1ea52b9ff0f79b36892e4a87291fcdfa7bc4cb51371525948faef395f46cd491dd72c90f8f5cc1f5b63a2ce5597b5b487f05f3957a2e2bc3a19115fb4094434904e5513d1fcc07e9720f58bce8c56f56f9a127a3291a103a03fa19da6a481d1b667639227cb94274dcc3f9200ff85a5f316e5e2547fc8d7a281cadb2300401732b8b42a4f28d77d30731258b5b647e1639700835fd4683b59d99a50a28e5a8506e2133753073b8654689ed0dddd208f95f159f51caf8abda5cbad49180528bb7ff87bbe4df882a563ce084310b3b3e8b85d559ae817785064dfb9bee6ccc6f8b3965aac4f4fc5ffacc6b04bf82d5949d24ddc836a211d4a8bc5d6aefb50f9e3c058a910a429a5a5ebee014e60014fd62ca0e52b2657c051464d83270715eff06f62ed35be36f0d5b534eea3217368f4729b88ab505f70d821e26754b37f5e46241b30bceed67a401bacd48bbb2eab814d5601040e0123b3b23009e84f17a6931a59688cc6b20992d08210e88561646c34968f540c471894321444c60e53ff66f4caee184ed262684ae6ecb0bb45065b056c77c16eba925a13b11b582562521fbf94873d619eeab70531e24714acbe94356bb91915c0fac77c542a93b488724726e8d6fd9e1a49216a7631e54a89d4da83b200cc283bd4d5731180441606e3d7cc53ed285a6580eb22dc7c814bb801b0fd45c3a95f1d881aeb23c85cbb818bdc1267304b300fa1931a04c97265ced83100e11f14e58db4695f7c1c8f9154906181106d9835d501370c59e9948660ad847152050f176cf790761b770943a707586b658461134187b090bc5d141d0b490e01861f715c3c5723190abfe31685d8a2f60e098b82359419927ef08cfa9f1257c6a0c43e8a1e375b7a460c2084c5c8c69dc9315dc12a80a46e5eafe083b67a826015c0ad9d26a66fbdbc2035ae9cfb0c37387c1bf329c9827c7fe557029b6add91d76d70298e123ac84fcb22ea6ba6504c237bb872d875024238bcaffdc7da628e79d15d5b93620315093de0b9da45ab349c77125e0025d3e14192ffdddbd78c992ea16c449f177c70db36dc6ba90540e44ad7eaec08310b4eed30a3df91ac1d72625c5f80f1e1c68b700c63bc1472d7fac01e7b1e1e1d5cab15ea14c89bb6cd3f14a7e2074df41270dad480aecb3004e0041681fd598297d441085ee3104b634c22c2b123744afdcc0a9ad4e782f5e7edf042f138c6300dbcac674bcb1c1aea0445cdeaf7af129f5d9a11807c3999068be878336933957d889cd239c8a5d84869ac317676cb639f552d1ce6872a78a7c307e1282e4992e07d906961041e389fb11d767dc59235451f269a33781a175ca40d697112c4019f772636dbc157e396be82e5d36fd8ce34036fc3d0e34f1824c5206f6c0f7ad4623cff513d1ae8b997598678ee300ce48f30125de34e5ec7ffe71ad0a71b18c0b9a297fe0db5c3cd66c66b940823ca88e66194138a1c93d979f5c5497187c71a826d3789886a1e6723ba6f82a1c11cef5893ca3373868fe4625ca454c482d179f2d961b4724a0d372e84e8e47f24c2c08c32569dc1d69dc6e9f000d4939d93d25b814ed3b709af4f6e2132bbf7ee55157c27c9fe51f9bc8efea51a8bb93aec27ab903a9c277db20b8dde60a96d149e539fade01961f450c9521889251468649401d99e3538308dcd721a4092ff426d1dc4e52de7a05a902bb29c8e6cb4c6b400021a4be749c5117954894d4bc38d041c2e025eb89df769703c125d2fb449d3b9f825e20e0aa4cf309d77cbdef8d99d7d19fc8be3c44b942beab9e2dacc55fe5dcaa3cbe4402a6a29edeb54433a59c542172be559018c2b2cb972441f3078cf0f478c4b3ea98573cc54b9d39c7a69c7eb702ecd5ba52deaa59da39c4e6db914b92693c743facf9cab8481815aac13f7d9bd8cd655aaccf55654a1fa188a5167a1dd5c7da4214970dd09aeb67dbd7e6de7b9cc72a491c6d0e443f655c03fb3c9d27585162f326ca2bea75cba0676aaa1f7ec5661c3f898862cba4d0d6390992b98d475930ad4219128f516753fdec5e9f9a3261f88c3d61bf3ad11795fa5fd8d13bbed798f3ae5c2ab572aade07c861c7199fe5de3e246d6bcd7685c0c16cbee624bf8358efe934a0443d68be4c9be174e730b76c0261e92439a23dd8562f1e627c3a72067ace8fcc744fa54ffcf29a98ac765225a52e5c64f165bd3171e2256103ea07815e661cafc66621aafb037eb88be171d14db7b3fbf322f2ee8ccfc69e40cbb637fa6716fa5601922da82231017411fd955f291ff5b60f9e6aca056464fbc8ec546f582eca333af1de4f8be44004f5f49e37d8629824a304d5736822ee25d045c4a955c42cc154e267ae73830f73fb4400ca8662a96ccac90561a3651a6c19723c0b279ec9a6b10c600ffcf6f08802846d2358ec19624f369fe6c05a4f5c5fc70f1737911e444edfa7d1b5c79630f852ee8593381c1572ce2a01bfcca1b7d0d2760d39e25463f917a216217f95b7480f8c35d1ea78fcf2399c6e8cc74486bd29a4ec7aab838a5ddd2da8336f85dcdca54ef3e71ad737f8dfb02eb7cd92a0bd07e861bf766d8a1f898cfba50b5f9da3215224b78b2073b94e35e81557b6a420bec86ac754f18d25a279c6753a20e9cd8619cec2ed7c5e40f3fd0d91deb6d5b695c30839cef5afe5694ee893bd8c98ee16837e97ff8619d76678fae59038a343171f6e48881a14ded0777b8f31d467ddf88c7396e3c28b5a0c0b1130bdd357d4f57543cd76bce087367ddb90aac059bb9f7ad5b7b7864e05dcc0912e5e001fbb32cdae097e6f7dcb8f8ee8abc40d111d336e43d78600ceb1654c6ee7a2cf58a117111ee599ca301f8e51d390694c6852b1258436e3b04ae4dc61b19948414e7769919d74d76466c0c5f085272b4aa891b5615a2158fe04e2c0bcf9947c9d22d1e7c08a194ed6516285f5b22743f1b3219755b0ef53d2de56c62207b9865319c97aa71205eb1a538f1dcc31bf7d1acd549d4316199187d44f553d8f4ca4b7b37148ab57383e182e2fb1df4660fc5acf0218b81df436baee404be7a864e0456bec5e71e16de4a6da1e46a3db9692ae2cf9b3eef3be15c99c5d270273c2822b3fa32a769a55b1bcfe708df6e2bbf6b0da0711953c2b8f0c994d21a2b6a0141ecbdb3461eed3f8ec0d40fc4cd5f41728ed510676822062f80bd7b6b3303fc0b6abd4c540ebe99cbf3cae1c2406285d4d2d8e196fe5e32471e96ad92874b4617179ffb70175fc3faab89ba677b890e7b54eecd7b940de69829815257d0d18828705ecee8d1e1ada10e3c4ca96662d1987e879c69c5fa8ea3006da4a3acc9ad13b02cf6c9d79cb094ebcfd47826f4afcdbc443e6cba6e952acd52dcb85b5600fed6f06139ad32680b4552d272c4125d6f87e8d6a10aa2aeaaf64b83f21fbd4bf11b7135ae9e7160db71e7c092d171641ddd2210aeb44428167e1b1f474942481d646991391424788d606f8a12e0544bb11edf5e53413b556bda8acf173b43bf0a80d59a65678c5435a356746fe56990bdab94a57142e3d472623cfc1d71cbf21da931ac49dc89c53c667928155a945770d529bf1335a7869bc80588461ff00e7a4b7be008851b841f29c2050a0aed7bf5d9c8fafcc42baa72df290ad1460150a57c55699ea612977c7200c375657df1acdef3a79437858f541ac3d2dc8702ede5f19fab9913ab0983f77e0f4c5c0a7842fe316c6094f303cc84707f018ddb5fab080a201762fe80d824b7be5e314a8c0d071e20ea23f470162765fb29875637c24725d919eb3c9748025432e9d100f2ff89c44757c2511ec3fa40c4f2fd3f78bb6640696eddff515e7e79e9d2d2877505dc676e6d8f20375f7c126739b5d634082f53d68a29b1929f526bf701604dca66981f86a23af3e80e264f2750cb38731807453791178c54456fca431418662feddc54784cc29a18e5942485f609b4250c7a439553b91b4ac79397712b8c711e8dce38a6243495c741de7f4ee93b3022dd89e03c0ea25463854c1c6c11c6be59a07833e5b21d671838420c4a23d66dec9149024d0425e86718e431fa799261669ae56685a03c2b8c21199162637f1effbd81bc538df7cb13e204bd2470b042f2371b542231ff1db1437efbb1a7fa53dcb25a1213c96ce28db42568cca10984c75a1a8a2c27176572da05cf340fff011c729c307ce33bfdbde6d7b315393024c2282bc5ddfc46814a12d41760ec5f96df39c397d54adac182132eb666aa8766ae9f5f680128105f99410ec7f50859c95f61c5269a63cde2bdd02361958a9f1ba3bbdbe5197113579560252aff0a57119a638af448cdc2ea2fb021e9dd586c6b519b73d974044fc3d1619f30f3e28219e3efa78f54990ab470b95bb035c8e01a31421766157e5544f5c5d615890fa801adda41379d19b1c5a3cfcbe92128644abd19ba41779d93590e6492c8e906e7454805da0cd2679ebeaff1f941a278e3e34cd2cb76918dd238faf48b943d4eec898381394a41bc3328518124d8b3a954089d52c9088ae045065fd54058d9bb60516b11a76bc3c24389a0901f80747210278c631e381384edd8308b1c7f866b30852a49bcb74411cf8fb2c1901729206b55b077c3ea573a6ff8d26e6c808942ccb88c0222670bf09b3df601cd76e344a20d53feb9f016cd34d9394412dabbd1bd7fecc750dc6aef2a40230633318f76019b0e4c89b19a17d3c63b6c73b3ef5532f67942bb4a7f4a16c16a0d60c412b311501d0d51f3a5a0aa8d692539b87eceaded56ac132e2acf2d9738ec4944a45a44c40a1eabf38f1149be81277190664186be65eb12f61b027c3d3a0c842819830d212ab7635d58c976c14784e414aae792c9d283302a792809b2c02e5db13afd385c2e6625d9f79c07d58f6093bb4653d3d0c172a51c94a49c0756a9b7f8533499bbf3384a925b153d06169c6e02367f8d4ae0facbc659ffd89c3121efbee219445f61dd6eb9a057e199a973627288034013206dafa58b194eaf76090d801219e77cd01df6a1504d5f57ea58d351fdc20be8a9ad5ed4f2ec78320c47a754ee8b0ec4617a3935ac5139d188a575c3fc01f52334350e14d65891dfdd2615658da107bb3b5ef1bd177828c96c3d9df2cafd10487eca304507ef4ef022b157d4e2830eaab088f6e5151082f7f43b0dd0a983acd8d50862058db0c3fcc3fd5863bd0c7578144eb4e42431c2c4d6f435ce6f795adf34e919c367bae02b5241a32e451c8db62e7a1bf275780b85e7e0b8996a0127d920398a6ba60531d7ce9cab62e3d12c634f9cfb015cf027364827718d40891abec56e83e4ab53bcdd1da577583d8b2ead4380bba0ac41e8b817b310254a56957e14255320257693c97fa87266b1aaca70d561cb397bfda00dee61f0488c7e01295375aec4fa7483532aef4c6d1750f8b9e2f56d1816fb3aa83ec428485c02f2170249b52d0c24bd5854c8e3a46a92ba5410b709952e55c3673f58c7d166d5bc0bd547b7a17347ae9cae38e121b5c4f182a955e286be5ffec09f1032a063c7d48784518df844fbf46cda52aa51b1591514f4ebc0e1260219c372d5cde8c922ef99c5e5f5517c62d73d0591626287b34cd1ccaa6d35159c0ffa71b16e8eb13bc702168e33ba90185c946dde7a7a08c46f79d731d7a6a0ed0c1201094fba0f53faa6155be8053aa1b1a7dd85cf350332a20084b86c4482af597e17e3b3920fa2cce942185c9721636dec466f6f93660b7464c04f861d9aeea848617792ccaa7c5d520381bb1d360d38b2794b1ec9d9aaa44094ca90593e9ef3d7f15a0601477cb852a8294bcd4545727e98fa5d138ecf05f86c6f8723e886985c09fa9d6491975fa00577529f7b638f6d086ad051e3d952f215771cb4abab01758fa1711ee5313270165c8bcfdeb63c8317068d9268b0f7f6f22108a16bf38f02697b873309489b038c6c40280bd28bbaca0486a5adfc90dd0017ae736ab3bb0bdd306b8003c5d413fa2809168bc451b6b61c310af53f64b4d784bb43c532ee440d5409dd25c0303b4402ed7b67b94231a0a1d86afbf5398a48a2c024ce33238e93e27673f3526e87da6bcf9a16e991ad0d13c81611f4d5650d77366a17de0462de76d02b82db9357e23171c269c65dc92b215864b5b4e91ae6dc23e0bc3643a90103b06dc0c450083bf1767b2875fa0c7c3e264b91e3a5c0bd58727282493c2f87f4af126172e39992b8c331ed13e5048e8fb5eaa3efb74032fdd44e007273274d3662ab306bf8bebdff987815ab0156a6b8ffa0da1c7b79b86ab5192fd30972b1c2032eb2db38e0809c44c76538fe910e1cd1a4e785ac2f5150a0752d584b2bc658c8a01b524d339a4bb970bb5b6ed43e82e986a1fc048f9e2a491cd9bf2c78b08ef486aa02e3917217c8b671c7b45f8c8ba700299ed127c3d0fd3f12e8bffb7c03647876fa96552241c9eed3782df6315a43252a4508f12aa200cc080c7e3bb8ee8b8810b8def132f395fecee287250f6e7bef415ff10119afcbfa5ecd1be4add1ab234fa30b8fe5350c13d8c17908e6728bae1ba4fc1e1c072b8c94f42faf58efbbee59de4348271fac73e1dfe7d33ee46b7558f5c4d20bdfbcee3e82cb9f1618256d501a2e0e9a81b8d8f0d23c04dd23fb6990c884b9e026590f985b7b1d31d6cad366394c811a88fc52544147dafcf8a57bc068a26949fc0c26256b9fbc7c3f503fb9630a2dad9f2802495eb3b898cdc6aaf95c1c70bf3630edd9352a5faafdd8b59c78aa4de6a33af874ed960854ddad1495940564679810673f13cae7f9cf014664823e5d40ffd8fd6cf0f053f6d4fdb8a938c9b6784c72659ae660422036e822910a608c50087de16aa0243f3dc44511681a42bb82d9d608ec7b59f56da555af749f0f1a524d28e4610ecc15817b9f4da8370a5f98e3ae3911b0fb12bb3fb1ceb70323214537a74f0516aa8726468636e5302645dbec7b1fbec1f0006efc71af65f4c54d84bcf7b33f71ce6e233ee13c743f169279595000270ca94757f4f6a3f2f23f636b40bd317fecec2243fbad6db8ffb3dbf1a50eaba69872cfe5c2e5eeb6c29d2637faaf37aed8639fd19f8bdc51f9b1341b98ea34baeab3ea9689dbb02572dcfefea6efe9eba3ef0eee9d9c569472deca19cd46b1040753a4967e43b4e22243ace19a2c03e5d295f28df8435253d1f85abfd4dee5736a31ab10e155d39544596d82845fdf3aff5fd01e9a4ab2d3409ee730406192df3f389f53caed958614f1bc1e69361012689030b0ee149b52d508ffd7c21905d1a9050709f6efb9c53884318428c4858d1e84bfd64d10f1d6a601f320ef75dc27ef429e329a90884e58fba1f772fc0f5dd7c210f3bbdc3ef860851841fb59f2a26d249150129dffdcc5ba1fefeb7fa19dbc64b08bd8e4410b456ddc15b59862bfec4086dcafdf66f97f538585d9ade8b4735f8d084c9407525491555cc01a798c5cfd8d6915b653ba1421e095f9f36d36d9d54314e842dfd3e4845af1670a8b444320281f2100b47dcaa3cd6e88f414716585a23bcabe91afdc83aa9fbb4d781f7cf4a93931f424cf7ad41d3f7e9f84dc064ce7c3166bee18272e8d234196161b5f3700aa67c2cfc2473bf94adbbaca9a9a5e6d2768fa521fb6359db929bbe74eff0906b27e5654c0aa82ce381dfde34df49cb993be982fd633df33106db0ea409144e9d8af5099a657d6b3e7048111ef0a8856b7028255e375a118f55aa4c75ac2b912aa09fc79e8ffc4b9ec686b2b7c5022ba457fb392bab81e9ddf9cf7919a07dbda1f41c7ee671f4473deafdcfb01f24ec3d74992d38883508a31784d8eb87d995275d791bf8975626935584fb06f55c3fee2769115e970228f6b7f4d1c2c6428dcdee9083a82026346f49d6f21927895cdea9b7d85d8e79b9e044d38d72e1c925f6e1fbd26958299c4a6c2c84205cbd03a12a57526383052cc0c24c90f62dbacbcad10c44de686572c99702552f8b1b37a9bee72d7f2e7e20aecdd73046c95c818e66b66e6142a8523679822434c4221076fb208746202dc2f8abe131d096881c366668de033d150164ad7ba27ba1a3ae5eaaff0b994323413ab7198536fcbedf2ff627a7cac37bc1dbf624eae3f8b7e8a8805fd163144ff5b9356c87e379eec00102d365a4fe0fbfa650f0708340a39020d484505342dddb0f04658d637f106642c9b55fc6f26933468a51049b8ad3e59b05efe56c047357d553e9f428c4b44dac044f4485e5c85f42a394f96532c795071021e297290f51724e578b741882ca0d4832bbb48dc05ff6f542601d9414462538b97e3df592c901a4e754b7e4a4a76ffce0dfefcff0d54264302a83fff43d7ebade7d0930f5fb038945503c360d5bc206ff5ee18369bc7aed8c57d61fd12f04fe29c8a97c14bf6b434223105a7694cc71d795c315f3e37c936a20cfcc42600d05e0d0b936a2059ad9eab76815c6a938bba286fad6544e463b660065cf476d600ff0fe641cf3e1ecab36ab16e30892ee8ad8c18a724b8759a7b718ce9ae94728b2dbdad7198cc3ad36fbd4eeb8a1855e14d989888b6d65b34be223d6a152d3757723621886ba44e380f2ed0082086126310996e82ec742d3d52045bea78dbd8dc37c5303e583f18db09f8e075586237f08860662393fadc0fbc06afc49a57ad50a7fe9e7e9163566ff93850b988f75a1294bc1ac150be1f449883bc9590124193dd51410463aa68afe6c1b29f4509c660f86e75dffdaacb14f93188543f695f0ac49d11380853c84e2edf88bd83ed99dbf9012f91cc251a6856a240eabc5755dedbb71e30b8330b80b41a75f5c40bbf3929b7e99a8ed341cbe01bc1f824b8c0701e3c00795581cfc9bfd4b5f7de1ce533f9e60106009a1748f5e1798be5b3184dfd696dbd4249aa32e6846cb5817da8280d221e03288b93eadeafd768f4b0d2055ef2a32369e6f71eff7d8db951a88c2c2cec294842de1a62ac0a7c47ecc6f3c1f9eb1337935dab2fbb8e63637cfe067084ef586d862e2e9a48d1875f9b2df6bafa846d10810d6ed6422d8e3f3115f8168597f6f0d7d87bdbc378da3db6a32d2d162502a0f9eb7940ddcf532ab6182f57b7bb62317ec7cdb6ec463d6c802747482951a55bb7842247aa2e847af215ea81e93afb1095cd315b839e4073a97f717f9cf251374fc192ac190390c66451f1769f2b895a63fe6092ef8f8d9ec09a793857ac85684e0df92bfcb6a8fe11b69577b23b0addf2a6cb3806c7c643397de7228e16ff1b4fd8f3722d5450027b652fc7c48804c71ed239b773c48b72594db00576172d345b50f287abc1284ab52c28b818b1906429594439344c6a4e5585a229b40c51565751d52e659851fa1ab908d237e649808be24ea99b0405e8ababe1ca765307343531db4187335b096c689d668d582edac7047878825840ed90a00f8ef6681dd759f34462992265498c09e99f4f779829895e02041b45d43b525bcafaf8e600b33fa5b4f8012059284992b1bc86bbbea350597a498abdf3effd8d31ec6852fed4bde085665bef81ba98b8c9777450c473bc033efc8b7ce275868d1ab9517abbd105b9fc2504db4476eb44203a62aa451ff06f8c38697b7aebc416cf000bf6c17772f27122ab280afed2a2a81705c7fa12754d087973f7011c960e17fa3cf4df062a10882a923b035edc3893ba9d2a77126bf1ceab18b383c53e3f0f81b0caca25b0ec797312a8d57c1e02c096979b40d9e7e625a06c2b6884f990776698c2a391b8cdc50feb8773050fe4c8112f919d25b08647e972010000d2fe751f230b254e1c2e7162f552154ee96b0376523227ae1e8f3602405e3d0d0769043b35c76ec6ca95d9603ba2f8214038b98df3d3e65502f5f3105616d003b5d22e35a91563fd0b2630fbe67a14cc1c130240859c88d04e194c0db43c3cf40cb408ac76ee7e8a761c38c3e90272c712d1254a4f63d9dbb663c7e4b6b7c6ddcb6f9b45779f73fb6b748f1469e55c5970d2fe586e601b75ade37bebdae9fcde5cff7ed381d00f5c40d1876f5b79051c8c040aca7324ca7f83646348f48c1467e15e19cc18e4470b2d4c73acf9d72df9e3c8a329b951ae0da3d18da13229b40197f94e5aac6a58577c7be682b66955bec4f2a0c8aafa07ddf5efcdaec4f35b793f17395d791780630cbf6fc5fa5f1e5d15bc7baacac304111f49b7140c2733d98166e027945feae464ab690e085f60a729981d8975e68c2cdd5fec1ce27e964d8f7b5d8a0a9c23eea98c323b36287297a4bf55a67a6133a7ca4dfdb90d42c8b54f4a11f9e76e4ab3858a3828a9bddcdaa6552b7b64c2571f0464898c05b6f6a6b747b4b5d30c156e5abf1f956f6e26914dd8bb0f42cd8eee6e9c5f2529d9e66e27a61d76e4e0ed4a0196af29ba99ea099453bc7f5529d9676ed2d80f9f270feffd5505c99fbb99627f78de6cf8f75728257fd66d9ab2878c7c52597a1a983d52152027aabe702fde2ee6f65f1539d9e5b7a5da9dabb705fe7c1489e497bf9568f7bc9e1d78f3a12493bffc4652fb734d6fd84d8111480a44b634bf8ba2c214061c08c5c742db378beef95f8636321fff326c5b249c0efa1d682aff0dd9557bfac0739484e920afce4f1c01147ed3661e81413e6fc4c584a48ac7a54e9d3986cc87a81ae2edde442ea4632ce4d0a6929f5856a6af0f56eddbcd9ae7b8a668129fcd2d23a8c9bb8da47d4d16ae987099d1db582c719f7b87d02c20cce0ee19113ca715f61e08b0510174da6ff7d18f7956db67fb09d7987d98aad837189535117a8637c0f15d67009477cb2d6ae2c22e01c5d8d892456885dd30340a6e327eb032138d28c4fe50594e6c164419638a1d74c7afd4132b53b7772d8aeea61ce16159c97867544ace78921f2c1b4168eaf6506cd9514622a98eed4cd1ed3ad55269e2382448742a1c7689484db4c011bafad42dc73d5d64f93b03097a0f9ae5886745283616a789d2f1e5e0d88852acdfbb920581066f3d28336ba02dd0887a79f7ef3b2b055f9bada3d5541f4fc7cb708a3a03c112c19c3d868c525e4f9063946c7740195b7ca0a9e2ae213f4d720ea413b9a2e3abaae397ab33b06eaace27b8c3dadd840cbf5ba6d0dd6f19d8038ca627b818e3fb9d4951c7da80ed3bcfbc046910776a87389f367dfcf3b24c0c1312f8973796161ee298349cd2b5175cbab35f89372a179fcf2ddb5b798ec6f9f4f6f389c69bfe99a1394020321916afa277a4bbdf2486bd5f17d1babf8ebd59f4f2f8bb3bb7719ea973d7edf2d2871e6c796df39fa54cb17aa50e6a6872d4eb9eb8e8e8be4a6a24cb590ab1c5e517c7b18625a022387c174d22b6618d2f582ba289852224c9fc69cc3207ea084305cf5fc1301672e2a809331fa7ffefa04523a67b6fc43bd5b5319c4ec73d10cf44d74efacaf7939a755aa0a683a1aa5db6388174242194fb1bbc69602a23241a81cfe574e5245c556dbda03eac64ece5a5b19461225e3006aed1ea401a5137c07a50dde03604889e7880917cd7da84df57e9e70b41bb5e2007180489fa8bc11e4e8b5a407ed72ae35b15c0df7a0d3ae4a532504696e61ba6f9bda0166b2b8d7fa49ffdde1eb2414418e1df07ccba396dca45d2cbdcfd72ad66c54a74f9c87d2d8fa006e1ced177a8645d7b171f1ca95789a8413de4536d70eaa16e1c24cb1066947de1f78a3bc61c60d43a7a259c3fac2c88ab1acd05b89d7fca604c872103ecd34120ade48c48ec79b0f934c07e47b167163ea3fd0e07587cac6b01923b6ab899ad380eef4221f5b25d736e590f5e6754b8b526b3f3ef2b0f3607c3ff3e8ce465b32826e98132d27039d605b9dd9879f12692667763020c2f10976797c03cd1d17181f0966b1c28e3ecc02f21e5ed3c5e06af70544eb89ad87c4528a41142a17f64ebf53c37b596fe249c24c05a82089e627cfd0833878b6f0e42fa30154bad0e8e60d86d917d300a5813967eede2371672ac81cecfedb7fb665c905b4b82749747712bae563e28afd0464039f17d232d581f42e2d11d6fbb86ecd97e88c260eed466455c4509de45dff9b147036af7b13f2224bc02d95d399279ac5e4be329a76bbef6cacf5135988aad925d772a87af5a5edb0b4afd1250ad4a816ddfb33502d620cdf8af3cd12a99bac594440b70b449a5b9cc554a2d346a41f6a66573fddd506da59e98bcda9f3fdfa4f2e0f296c427f320db8f664ea695a14c39e5fc6ac557e06d6082f62a185e6b46028ca4cd3f5bfead0113ad9f5c5481ded52605c2253d698e7ea006260b63377ee59c46c62e8f88c628c09bbe306fe2d2976946b51eb0c6ff710e08db721f1385101ac163a52149970892eea45666c2b78e941ee62e6ec7d9a66828620fe053b607fb5bb1634a5f4a4890028f14b8b4a835ab988ccf2159ce73eea956810dcc221f6c88cc43f70a8724c6c748123940cc95ab39ad8d70e47aed04d303f3aa07d87e83528fa008618157ef03ed4dda648927cadc3ffcc0407f0b8d66c80a6b158115659586a5ecd8b68814d246a9fc4674578da4299a27eb1618fdb5bd4fa8d188b84116d4e4df7fad24b449f54d696d5344f4a3230b29e5db91af1d6f2c6249146b1f09444db30add7f8e88ff56644e834ca313fb7cb25e394af3bce32102f9b362d73aaa16b9cde0d4357fb3e5161b0b4ddb7c351321cd904626be85561da98739397c20339ec68289b5e58b83e0467a0ce8274e6832eb6e43650224bd2974c867ffcdad9440dca8c9fddbdc8b6fa701206ae776e55908691fd9a2842dd136482f139e1afbb4272de27e0b43df896a91e0fe088a4b2c2bf2d33f11c30c68a19e196cd3ca97331f742249d85e8a35c6fd685f28fa3e66afd842b8e28865035e071ccb12f62dc7100ef6952c032e1178f8db0958fd2b20fdce1b5ad8c04d65410646bef32a6b28709b5d8166e302a6e8e97742e158b353e26b0e9adbd6c951dcb4fb6155f24c93f5eccc17bf9f20b8751ada81f2a1d1d2489ecc3df5e8bb7c288fe91be75c22d6a4b3a33e58de84f6bc2b01a637ce05cab51484ed0a166bb966cc23ee56431200c1366c6f18f4fe64a382aeb357c7c9647c9340881f6ad95b6fb66b2d3e33e6aa1cb041ae66024b0e03ddb2fb17ee287be38977d06c267ec9025bdfcf9f347bb9f1490f2e492c788910cbf486a1b5e87588f4b4d6c31d4f140be49b8d0c689adb3adee6a82e89e9ef1b96b3f00a4b3a81853186140aa4cc599f61882a55ab5cb8a818acdb15a6e6037f85eb0e411a85ab26da0f994c16cacddbd562dd5d9c11b64e4d297bc70cf39c32c39e5b514f30442637573a2d5d5bc45367c74168e68a45e830e72b165b66288af8e19d8d2465a255c7d966a3ae693f92f20269ca9588f4ee5130c91f8cdb4820d022723fdf40b916b2d1c06cb2c9e5708e35c726644dfa2b90fe627befbb83b30a5a59cb119d0f6c663d7b69dd5b4bc410ce5050685387610f70f983f45e5d798b0bc6845c6998d7888412bf77967103b6e399099a41feb3166a887ae81b1b4e649341c9c9e51e6d6108f3bf4ad754598ff0821673ab777f87f861a09fa27096be0ee0b098377719fc331bce8bbfe02ce9e2b24f767a56402ab456f37e0eb21200575135286288306fc9c9dd4a10ef4572a7341cbeabf61d6d5ddaad70eaee1a23ddab6ef09b9c4d1d61807439282c37c798894d692030d16e8e98b9e18e1e7a28934b626b4d105e22494ce31642600badea37e18b34866762aba2c8f9dc4fe641e99c38045b426d6e40069e08378cdeb32d0abdaebe8851edf018661d4da4f875ba70ca42fe75b48cb0edb58e8952f04d181e5ab76413902e26fd1a0e93382b2e87da7a5aa1402b94ff02cc9d2a13d9b56b65feca5f5089f74598e42a5c91869c25c432482fa14f218b60dabb5f6bdfdec9cd2df10ad2d750570728fb69e244ef6734612630215ea29ae0c0c02fade927e1fd177ef2892b95fe9392f13550ffbe0900c9a6f7603e2cb13a77f70ff1fed2b4f4efc2396cd00dcc344809d8ac9f9b0517ef6b9839430a1ee307687a72e588fe8a926da4aff893636ca2f8ce337c7d8e30e7650868e440edf1e1f1a0efa9810626673372228e1350ab8179ea03b9dfa94e9995b3a3b6121418b48af77a4a2c087fdb014601fe736ae80cc26181978f466b221967a2ef7351d60c7878c2353c8141a334c6ce5521b8efc5a15a0b31e6152ebffb9dd5c3ccd35a5cc4d39979a1db6c296a171b5b4e62a97000ddc05b6f0a9e93590eaf8d09468900a2ba254a9dc21c8579009c427b485e96406b5ec6fe0d6ddfb165eb5714aa64036b1d99db667b8e66cc196c64827d6d967c693c8bbc9015506b93b05b317b76ec0eed64889fe618dff9aecbda004915fe88aaea7d9d06b4332245e660571f4fafe4da9e84d32261fb3216bf3c2355cfb18396844186eb8f55827beec0530812aed470a68ab3fb9442c9de9ef26b3a405bca2ad5e97e4c352b7c45cb32e890c498bf870804eb68013a0b3f8ee810182e4aad47d1d65213d3ce905b966726392ce69cf3955198bada521cdaebd77d538b3659c6ea428ad96d7918ee5b3d5d50289add16e33378f28653fda087a527ea08f33e8a1b7241a3e6770f32f0d9b78acab098f8eb1529553e88daa6d68619337a1651ec27659ee9683f36db19086fa73be70e04548dc10235a9a29c18c0fa48d6c04dc134dede492089619a1824587f1a9526397483f13dabae8f2b2172496b66b8c5d860d940216313742f3323a9e3c2b03e59dc7ececc679c49407b056d6c3806b9c8d0123913b6510314e2de36953533ae63e76a5d125dea4da9c5ea42e9f3a9e25599d958b216c2e035c13f04b2615aec119dcc812a6b17b1ee4a09340acb1846521fd056a366c9c7479b49c20731f886a56c21e0796d5ee19c0b6fa4547fd89d653c56e0cb5f3847c15b29eb1b9863982d94f20be6507823e57ac3e92ce3b10a5f7ec1398200a1fb9555ac267625f9868d5301a25969ae2a8d7bc0d19fe4fd8730eb7923e30c06e8fdacf345d2bfda7adfa2cc5652b8abd4ebef29f3190c3dc36f85248876fa2a3387d544ff00f64df30534458aa0381028baed1fda57a5b329ca2a628a30e834c6f7e09af9178fa2eaf2fc49348dceed4f9417717142be3019b94ea5a9feb4b2fd082e1b099ff8350ccbb653b8370b4f9ea4ee77cc01a4c9f4894453645944cd7019e4a09f647024e843e4a0a06f1b639470944c3e9b5f40e28d49858f86dbebc5db762bea9cddafd721e09b8762adbc1eb3f8c0a026636e1a943874b406804ade017f5fdf223a380321c5c98618afb3364209ac28d130f3471e4628473d2a3b23d6329bb11e2da10068d1d6b8374bb4f740919bd7f8cfd9a5de82236dd38332acc8e4440060f8be477c7209a745a4665b8bef4d7629a18813d7bd24ccbfdfed9021c0227a7fd1ac755f644eb46bc9d18c8ee4da56d2abe4595594fa68b54c09502fd59694cbae8dd33929c59fdf546020954bc63472b26f28b3e321f306c91256be8c02a7cdc99e6b43d350fba9d24df29fc8a93030f93776590a357e49ae0d03c40b5b300e499e90a2022cb8743b9e1af3834b633c8a8a6320f34c5d9ca0f298c6a17738ced89c2b4a1f826a3aaa76fa93303a979e3a04250ae7b211cebd2d262fb4533c9796e56d465e1a4f4db56c5027ecfec255186b21e31b5991f615164b2682d3706374d6caa680423159fea37b475770ec849f0534c9a516922989aeb2e61bd965ded4210a2b28e7fb21effe49ce119ac426e181f848bdf3fe6435bcdc9e114b5a6b0576adc87231ba064798107f311f292bde1e62a0f6f79c33bc7f61820d90d4ad01180a4a7096845f8ac9c2dd09c941843688cf3168216ea6e8bd5203853f6f6b5ab978950258a90b2bcb637ec844f9a96e8a0dc4ef08e4327e8e4a2ad493e1560b2da6645792b08d316c40bcc6c2f442727679eefd8fad4c19adb18e07f8bd74537f06eb9530330c0b992a91e0d95d6e62b3acb7be3bfa50ea9d83ad1d00a0b594a813ff505bd01f55381d386c0978bc589cb4028ecd7519d91144ca24b8b7e699c1975c5d5193d697d0240a382051943c2444c1a58f5867f364cb8927cb55b475c0b445f5a91821b175456bad3a4617d4e09ef4ef756179c06611eb4a49cdc0be82efeaaf5cdac56d3fa1507e285155d40212bb8af207b8bfde03c4956795f187a121cef8ae1750865d4e1914bca7710927441933b80c68ed16cd388ec6c8a132573a1e7abba1ad17e9f8e0b9a93c9d0db11e406c7983c42e394f500bf20bed9cfd781c9d57c2c3798e3b52722cbf8e603cd82c3b7692b38a02f42ad838a2ff4930ca63b8fe6cf37a56d9a48cf5878d23ef04178bab4855283bde449035a147bb4d108017f1aa777a72272aa7c389fc5a8db2170fd820991d8c5070834a17edf818828da398614b6aafc9629e4bab6c1547801a826dccdb79f78ccb38b8eec2872c5bc7d6a605831bb2c67a8c8052a65a19eb049a63606a0c1c2b67d82685dbfa6a9b3ab76dacf611c516c62fcfc8de84825393a6fb9d42ee38d3fc3c53da8557769b5a98c6528c5a50146c61927cea5089e9c4d596b529e74ddd3d9d13cee41bb744db68b753894486c6e897c2f5392e1baf303290dd72a530b8192e81c25c66cce8dbb0ba02196aa855bab08ab92774f8cd8262c3ef04f0658f30bf56142999d0f75997a18ace4045b5d1da4716ec64a3b3725e6f252df4134b2e405b41a06d669ed010ad204fb250861bddffe08f5486b81a01d95c5e5dbb01022cb05094c981e73a5c9cb5e9e5d03df8d04cb8129731b93d2f8f9916c2303010f75a17ba8f54f05a5508380159ff21084cda8d5a55e31ea9784b666c4306e82a2115d19f9ed4979b3774acdabfe5bfaff6874fb5c24e1053b42fd5892a9bffe38901c8ba110319cfeb39a03f769b67aca52710c7e88fd75738e1aaf37ed04b2b295326cadaaa6dd7346e530ef88484b1bfa769f50f672b3b82feb7d11e946dbe8c050cecb6ae9a441109ea7a17d7ca98694e4dd149d1e292123e28b31055f320b0f4dfee8d3e6e2520ff74245e1bfe344a8572c5b441172adc12a8f33b393bbeed8c0f7e2624b7bcb57b7da8a1f53fa5c8b599b7778bd85cb1e8b90cd987dea1170cc900c5e80db6450acc99fa4c8dabb159ceb1140a9d2aac75468400494e733781294e93b38273324cd3b9260fc7053b0ba0c69d78bcd230467a9a4ddc5d8c06fba4da7e2e4983aa63498dd69c04a5feae7a93f49c8d25bf83205a2cc0f6fd176d32656387f33c83ce4eb96275f532358b9e45bf6a2acfedf0147f17a310f8549884c3bfd80eb110ec8ce29cf41272220fe960ab2c59964e20a9d4d2186b84b560c40167412c0758c51503fd0ba4d3ba864308742c75b05dde782ef0432ac37deb30add13dac0e6021705649e82d2cb8e30b23143e04c643738ac69cdda9cd97f97cbfa1baae2b076fa78c3feccd32962bf2e9339893301b94f30fcb31e8564afb067320608bf2fc177624ceb4a1612a5ded969beec3a10e00b84db5e8180579da0abd40dcace57de8705d80ba468a365ccd0c8c29397fc10a58101a0b71c4524f8b8e3e85d6b720f08507542e71b29501daea58601a2f8c9ec9971cd07b38a18f3f2bc68ff3b6c7532d9de6c7f0a9a69637f427f2bc787eb8ff8e40bdcc9bf18ffad53c3610eba57a53abff388e44db0da5db1367e80b51fa709a30323c59ea2e0c4bb7c9b4ab335648d49149bd827e9d13fc7e7c977aa5d38dda79c7b9cb600b73a115989527e80f9759ce975fc544bf5e00454763bdbe29c47f2cc7d97aea1368fc44c3fc5d9115372a9e429188985911900c62fb737308e290cec5dd26a37a1d835414d620f17167cd15dfaf2c91c911c26ad604b79195bf96023745a32cff21320bd862cd4b8c382d92e8d1bd75e120e27905ee7e1748507fcd0fbd8cc395c46c641b4d881e1f4a7380a7abf9d64528ae1a0bd256c41baab928948172a5ea1c50862454782b70148575c771211488a495cc77e969c74b4fafe09711c6d7093ce993e1f190e4bc9645352354517c34bb8ca173ac6b7f6e91e56d16a6ed899020cdf524af9e93dd333b09b48764117ce6eceafa4a4a13702538e667f8b04e99ada0b28902161f7edd4f0aa5d13be4582d4553e409425091f71ea261820277a1f3b392e5e7bf6857c3aa5ea07f07211f31203572012654e67223fa74f351475492bfca950119b4a456c0d9a1938a56181b6ece68e5cb76509a6ff4ed0a797d5b55536190baab4be3855014104c153e9e00853e9596f5ba6e5fb6ba70a6c279c878609faa35744aeffcbcf3e230a0f945db6c042ca2fec4ba59e8eec387f50a2dbf815c10a229a659ec44b63b3f866979d17c97ab4d34f0e0819ae8f627bc5a03216b7c1738513aa8905c8763ea82fbf15d4a5b2e543a30a913880f81702e8531d9f9e3ba5a2aba1cc21a1c1201f9d6d3984d6be271c24567791a708e638ec311843eaa32c93b89971d0d0b948d414899597b7808d7360cd5cb10eac20be53dbfa3ccf25984240e3accb26ef25a55a3d4e40f3f83b978032d24a33a07c78b3973eb5ef8f7dd4c63c8c2fcad8cead4589323cdd8ad1a4ad21b9d087f2154d954c959ecf3377c2e3665e9adda15310fc12d38cc20ab519f7ae365737c9b6ff33512a8f82efc44c9b171fa73f85b7fb8241ad0a4d545ddd6c606cc18e70006e4e0d534815d66d7911161ba83add966935550e28e1d90841a64e494143b21c5ce32e664a6487df95e2aa585fc49fb8cbf32bc2be86957dab37855bd4c99c45799a1d39835a02f47f4bacb97aaaf3b6f19a82816636a2f80bea9e4942e18087dbe52b1ec92a8663ac03fecb21747e7b0d2da2cd2e9bb80cb5840c0c27960a577b4cda60e26dd948b112d9ae621d81e2a56f2ee0aae1a270146179a6593246baad2a5fe5e65d097c66e90eef4d04a0c2d4ca9f9863fcc54ac54d9065758b8609d958a5c65b7c49de60847170dce5e6edd6590943189853c27ea5d049dbb21ec523d46b5e0d14a8f528ad5c750ce35580c3a61b4a6e6ff68a6326b9677178fa67e84c60b15998e339492af73ad20005e7b0ae34c7e1146d7ecaf4874fa4ce97dc541b26aac593349b32020a8a6ba57cf188cf3607170fb101f86b4310221b0c20fa290d96e9c42111a286e64490c3dc45f2e8dbe1546fbede92aef6a51fa8480fa5b21785f59571792ad4ca1d7d6b3a5117b5d20c728eaf627ddaa20034a08e10b6538096375847427270c646ea1a797ba6880a0dd36e5d00490904022f9643f0b8fffb53ccc01546726428cfde3313d66d98468914c75230fbd51e112d38cc50a9c27e6da079282c651f9eacf760e907890bdd26f1838a9ff1915e20fd357008b0a166934f8bc4f83d8a71adb96ec23c6c25d95812a28d8924e8981bad767ae1e8e426b1af0dcb24f7306a4617d25598e3188525caef981c4dada077696cb01c2d3edaa301844ab3270a22addf3e2a8b59927e4faefe39db21ea7c8973ffe32ccfa1a245895c513d8f329c6a5d25126eb5e215f53554dfe601e5032be3b7725907d4c5b9c3f96995f5970c6a2e353535626c7e3d8a60b4f402efd6183a6cfee9139c5724dfe2bd5ea8e9c70c3f52b2e91a23bdea04675ff7651c06dcbc35215e797ab1df2a2ca2fd6f0c9aeed0700e01f5127578e807c3cc1d86d41f79f355b0124e0af71bef97f0b3bcbd17cb0078548b656eee0daa5cff37c2298827e7bd3b03050798b2517c069ca36c644bc8816d6c0875cab47d22fe0549d0bf73fbcfc44bd25020e502b0ddd32022b065a4b9f7daf4964d86fd3d8584856001e6c480cbb400da434149dc4b71f6b0d234497f840b36ff8c1da4638dad478c276773ce83ec65074ffc67ff750c22b449b4c40c040cb4966e9b7e56456f3cff643a34a5a135f976773473fdc3e159be69b6b87604e4b04385f9abe759f4b7a5859ce79531880c78018b2277113bec70c9fe48693c53402fd4c1f8cb8c4a371be0c46cb074312b2a2a1f601608bc56d09eb47c9010a0a0cb428865d521ff17b757f6c9cd25a9cfb45d0cd751bb4676869d73aced65105a1606d94c9a023731cf4c01e9dcfabb27a059678697ffd48937d81dad0bfa98590f977e248b39d17aa2d9fe2edabf51a2283f8583e17bdb0241992fd89a9007f0a923ba675320a45daf41b7f0b00490a107115362aa16f1570b9acefbf06645a41a3c868774c7249ae2b77375c94e93c4e9e2a29d8c43a60af2c1f9c3dfaa6a234810105db3795ede906dfc19b7e9eda26225e4eed4ce43e4a4e9d41a71556f507e78b55c018e6a6f6997e3051bda142d4b84c530181b93920c8e258c4991ecbcc8a06eea8408184b88def4fa906f59d2eb096532ea2ebac20f4cb79efae1814086516486f35de3459bdeeb8d9f12d5e95a08141638128c063bf2b52d044773427ef5dee7360270b4a507bc36d37c8881f5a86a99ef3abf51594c9bf079f391b59464c96fc2319644a5be30a1c009ef9c205b86ac903c21c11092daba944714d2d997e18b2e3502a7ab56661501c4c7cd210678f42b6ede3005168d7b55e3c5e70f8770243f9e1be5d489b090f30d9ec24a31eba25be0524fbe5b710306395bb930f7bd3ed4ffe0e2091be6495f4a40ed063bb2bd5ee21193836273069e9a82744d37c9d31b8d10d8b9eb4a87d6c8fa47b579519c85ff500f592df69984d18d40ecf2f3f593aae4493f84c69a6f3b6f09b4dd9bd81d3ea079234cf6ee08281cb5de7c6f1894c5d35757d598535a83aacf5352f447abbb3ed109c1d3601122ef7f6645bee1426f1039aebefb95737363a73999fde4655c093872dbfded9053c4752d364edc0a1be8668eb8278004bc7fada6e1f286512219da67f59ed3ee4562b4c3ebeed8c9522d32db4374feeb79dd4f9256ab82104d13267d0d5d05ad4de6c21ee569f310158116189063624cf8f687d8da80d2ecfcfb5390b568c8c941bd30b7d7d2ff1899dd792138601cda5046576ce52b82a112745d6948cde41b28493571dfa3b80b0ee792468bb009e9c9ea63c6397242dce0cc71666c25deb59e1b4f54ce16c610670b4343bdc5acf74c36b32b5a06f3e6cee020e8493935cadda985761b567cd3b394ea7a1a9c19cc3aa64fcf817e4a96a7e7fb7c81f6860d66213cf187bbc0dcacb429deaafdda5757a41d02918a122103cdaf0aa6558747fa4c32569e9ae490913828e10be0e6956c7e1317ce5e46823f9df6f275cd7eddde90f2ecc1ad638928e4f89d38beb5d7d661d44c3c099e22d5af1cacb7ceb3584d095a579600af5e8dcbe0aa166024377debdf49cc82cf03e2b786fea659f3e58c55917ee649b530caa93a3dc78abca9d0addce4d17bf5e74f34719e58249863107751ab8e964acc9749b568e811bc71c35d67faa6e904397d57165c09491ffb2bc69f7394c9923e83cd39337bdf7982a9ddb7adc1603da7e9b98b91a98d0f960386fe0dee54f01f3e8ff3af17690af8728ecbf7ad2baff247d9c9cedb8e07e04c7663cebdfe8f47d200e119d7a1b43d2e482ea8d9425f27fa32746a3a5cdf86fdb034d182e5ed8d6de535a8a16f27f361ffc852287fc1f8ea312737d35a0dac8ffbdd4b044ca5b84f3299c900854576290dbc266c830baa9966ae14b4f81260163ca8e9d0020bae9b32ee93aa93fbbb7a628e23782bc002c1846b87ccee32199a208c6bd33bc004c92a42a56640fafb6ddd2f34567dc5d606f117c5a6895aaa5708cc2909a761bf988c6e033be00accc897f2f0000c5a326d0771ec4008c649b4f25501305f7e2e6312c142ee4b47615bbd649479bc2be7d8572f091acf1358309109d61e47651738a4ff4d5d619cf0e6ae30989833ef2377ef907159caf89663eff8703c112fe00f10e93fcfe834addce21061a032aee988c762ecf6cc2a1014b9bdda2f7739425e0bc25a0818b2860b16ea7377aef064ad52e85f7ea3398ab808374d3e4efd9028028085ab7be4002b38a09266691bd868718505c36c11e13478ddc35c7b5691b09300c92ba25368fbe11030a2bb832adc916840d5069d92514c3cf50ca1b6083100c88e92b7cbf84051a7877033a754c4391a4d0316dc0f41308a79af4606db8bfa7aa8b00ee274b2b149cae04722bb7e0c701a088bff2d44399191901c69a394b2988f32b7e0e20fd1d0fa8c3772ea557c39c9e8fb553327e8bda430fa2aa3be8334156dbdddf01ad0ea21eb0b9a107e84070f1be01080394058be145811efe5a5d1502fd37c9082b369c40dccae3244282c08241d092872f204ae3aaf7b21fec48530f7b981f29875cf7d4a0ad91ed091ccd8266c4e45b93acfc37d34e81965d356ed50aa22bc7de55b26f49642248bdb744605deb38162d30fc2a0b24502df0c95d031fb3455f60964987088fc992d80bcc52f55c66421d3603ff9eb1555ee0e9ca4117ebff8adea3c2959c1ced5f0cb049613168fedb8aeead139b57284a1e5a62b56fa88ccdc54ca34fe7675d0bafb6831fac4f96869a717b688fe82f71f4117b846d1fd80eb692cff378cd599ddd4a3445fb898502a00abca687187461f2d34d8fc08ab5449785e395947e2ea5d6a817860afba6cfbf0723d100163adac3282cbbddde96d95cfeff4e85da9b4b6965bccdc1ce203c10f64a5fe6dc33a09439cbc5eafaf7d104c26d36912fbe55a7eb02aa0f260e9dd0f763d44753836033309bff29aab095be0fc70d944f494f170621abf4184f908d78fd945d44df28171fe43d50bbfc9cbfe7a7b45478e3d8c0712c9e6f8e509a5610cda471e6dbc1ebda75aa44ba0821262b16f9fe71f2a616940556b7d116ec7c0bbcb560be6c24add594b559094e0234e9302a6cfe8e38954615a3195ea7cdea8b36929506b793e50df0d3b98a89a6d823d0ea8123815e8f297250d33ac85ce0df2e55f01c338c547450abd85542382cec31a165241a29098ddae78129196488981e1b5e9995df3699f264e3470feab7656598ca52ae1ea71c6cd1c3f60491026bc4dc2bab9bd929fa5bfd00c1c893f6b7b4f04bcdcd808a619776144c89e308fd88681cfb309bd2dd7203da1ddeb6c08abdc051ad34e3adfc86539bee35d5a423ae301396736da34189d96982adbad2b031ece7ce3939af8dc4de689fd2aeb2e8a9ac6a2230034d6bacac920588eaad65a4ec5eb0e39891bec00a59b7cb957a0a49cfd0e2cb21fa43bf2ed23174592a41d33667ef5ddef028e86f899cbcd5b78873cfa6cf27c1a918cde36ff40d0ddf646c9f7d339e1a0ac0040ec096e5a64adad5b347fe40038bfcdf95d9a99d003dd8eb5185e0d9a7b31dd4decc53af4d2856649e62ea74e2f2ef373aee9d7cc15889473d724d809b2bbd45f7ae7a179ff682f29aafee556925d1c3080bb65f3db3388195d04958d674fef3b5528284231c95991735aa5d1b64f9300c8980c749d1cab0dee9f89b621299be67cc407da1e058d21e7df217ac41e2a559de995930b10342bcac95d02c7c2f981011cf505592aa2f9f4bcd1cb3028d1b2a82a79215daef167014ca99949638b3ca5903dc073ea50f486c695a35b43b98b6600a7cea88aa6ead88248013b7a48320c1bb1fbaadf40177dbfa50d2f32ac8f04bb85c2942e50f9a6a0e43d208616f32c26b98bed6a34ed8da24071facf8e199ca173602a6c233a40268bf9c9b4db9ac16d0580789f42cbd13331945f54bfb092aa2279e4f032e92cfabd04805a670ba89eb29349e015f36d34d3c9aff267f90f45db44489d070f39fc787de66dda5e6c32f371451af3c6a68417f6de7a4ff622ab3367dc64acf039266559628ea6a73935560b439d2750418678b18588647ec1c7a3cc4307c32f55ebf73480f7b5c43fb56d8c49871374d85a4f38c0fa2df8234b5056efb854814551030ed6a3a0c581bee38d40832fccd155c40f303b5048c0ca7d3e988fb81d36345d58afe29c46e29194d64174fa891b4bb45f88b4f249bce8df5e3f3b0b70b13abdff33aa42b5203fbcd31b4fd40c2ba096db2770a1216e814f9125e91b7f27c3c1b2fc7f3bc27de05dfcdcae5bd40eff33c98e7b52cf87a78e0e7b140cfc987e3adbe0bbcd5eafbc00ff49c7c9f17e4bbf16cbc17f8799e07f3887c37ae9507be40cff38aa8f703c90bca6a0396b7f26c3cf087676303c3f922e402af08e87d5feb73bd1756308463c5f33eeff33c2fc85d9ef30fc8786abca8e1d44b0f6778e185870c1174a96328b1458c303c8a47030ed5c3041eaa4ac09f7aa04287271e9c454b0f61d43855a229587ab8a00456ea9021273dfc107252751c5124868e91229e1baf89181e0a9accd6ecd084a6c0c7991c1704cd88f880c2100203d121241bf000b40606339a8301f5b1e33cf000e333560c4ec132bec17d5386b72c77ca8c6a7b8bbb23f98b9b1e87a1741eebaea5ac65e626832daa5c362e1b50c7ab89cb66452427ca84a69e974febe66504e6ecf0c09c960cd4ad74562298a6cc0d552d1d9fcb0604d22162a444d50d979c1204d261c2472484b505f45a50185015054b9258e6036f402c3f27a802c10948bc30c163c1440ca698f081415641398f470a6b832faa5a2d0c9ccc54b0e30885551513005005c4a64b4e8f9c1e2250a920f7d2376e5441d936556632842e9b950e4b0a54a105135ea08e16116fc71213ccf0c106c905ccbcde18808e0f873545743901affc17264ee0c1f2b9a172a3410b041089cbc90952f450e504235eb0201c32a3436259e18a2a9cb38643191d253b3c2e43564f5c409a9870e372d2ba79e958152d555911b9a1e246d58d6b4907ea65458812951b1b2b3950251429aa7c80404d6e5a301e3aad1b1ca59e1084a8ba7959b980c642156b15b2bc9696d60deb490b8994239cd3e6c8cb4aebc6054427c9c608d864e3a3c7100d825880e4b5c195270d4cb8798dae253a4b8a969c5c39a02b080bb66a6293031ea1535c36ae1b50887505349ae2b184ac7858160cd9bcc89513a5273f5e3716d8149980d48443f4f2018d80465a465421d10126b136605d6063041cb223c98ac80955a390b7aaad82c0156b849e10046005be4b28e1051a269630028815c89040a5a56a4fce4200e1030fb86c8172c2d2811598d1121f0d322842412c1cb0660d1198c181940c7a820071f110012e8610428b1207302215e4e0b4aea0220149103104103ff4c0830e5b7c8e088d38dc1005b5660e13d03e58430d05c8b028c30bb626e5c98d8b88186028b2c9409a2288803969e2a307cecdcb35440802a000e1cb2c4d1d2c5151da21002a0060270c26552ca1841164ba70296af2a30738012f4ac0454a942636ae56132924c0091f6a10000b231460871d5ec8d224e5c9911c4f8e551cdf1ba01aaac6770668c627062b0c4f031f06be0bd87c9163816f029f043e2abe26564b7c526018cf8887c18b086b880e90cfc75781d743e4c1daf9442f04757c38ac9bcfe6f5fa5c2ed6077a2bcf6bb9ce8e9590951555a00b5520961612eab9da302114a28ac5ca7169a00113c01e92803e728038a2b5421588c5c6829b213fca54d978013f585d80b35b392f2a2fa3d6cdeac98f1bd61655af28aa7a8060824dd14a073672c0a862ada962e504b94055ceeeb1a2cae6878ecff58425c49ae14c053840067002d842d50e9e1d3cab2051e8f5435c73026b8397910bca6ac70aca0b88aa155312a1d64d0b89aa154e2b0808849364e5813920d00d15d6062e2fad20ad9b56989c1e393d6c7ed858e0f2b242c109ad202b264e60655195411810476519100161393b5a22e8ad825648a0538e8fd6e7eae212e26a6255a0c36be1ac5860ce6ab5fa56aed56b657333045cb9b6b8767638dd88ae96cb5bb940225008f45e4056424cb0c1807544950e244c105ba09057d209201827f4c8a8af498119194833012f2090c569838a0106a5230ea214e1bb861a4247c21d2fd7970fb234ade9c20214c0e085211b0630e50630302081072800014b0c21346a50c3b95fd0b90d12a8e1c0171670c001c8941002081f7890a5a90a150c2ef061011553905942891248901119822f063ac0f080185cd59a149cc00d10bef8b040c4c003b0588002100045132f04400559085eba64695a9240175844a00a1bac6c4003127880031460851040b080421912a8c1c0170ab0820a27cc547db9a424eaa829830c3020e0802912f0441131b8f0a52c0410be7459527a02fb117524d0050474c02106335f86d0c11215a527301d3aa097418604bad0028b2912f0441345c8100033603a588af204564494e46747047d4d196478400b0860e1802912d0441132c4100017cc8c210303020742e31c7260b9b243470786c0d0020b1e7419f2c10516765449d8ac59a5e043014b8e2f8ed711a0115f11df109e922fc96ac81b7182561baca805187c433c21ae202b20de0fd08767810d8f9d9d5508eec8d111ea04c9018233e446b471bd5aaeafd562b1569e0771bf09739870779dc73769755f9b73425f62d2de9388bbe7ca31e32d0f73b884394d618ecf0ff5a1f44babafa5dad26de9935daeb9de485a2dc57103878d10870cf719b55dfb371dfda151a0509f2850e8b5b6a7e13c11e214e13ea3354cb5a57b4703338ee397252bad2043eeac273dac23ee8e818738465ce7f1e6dfbbe684f20641100457abefdbc0431b316cb8b876eb2f29ddf852fdb8a43f3e4fe613ebd046091b1bbcbcbf2bd5a1873654e5fdd0868a0d1135690d539a712dd7ade9db6ecd371b50e731df48dce3849eb4a6b639c1dd2f70b719e185e6b5596b7fe61f77f771f7235e194e92502934e79344e2c489919322274d9c307142e4648913254e92381972e2c4c8c8a8c8a88911132322a325464a8c92180d193929322a2a2a6a52c4a488a868499192a2244543454e9a1835296ad2a4099326444d963451d2244993a1264e9818312962d284091326444c963051c224099321264e888c888a889a10312122225a42a4842809d110919325464b8a963459c26409d192254b942c49b26468891325464a8a943451c244099192254a942849a2644889932446498a923449c2240951922549942449926428899321a3a1a2a126434c868886960c29194a323434441ba21a7a7717e2a10b059d47dc798536aef6199360dc5d03f0cb0d90cf8d0f0994043a02a54037403723504a2975f70cdcdd88bb17717790c7354461ae9c1908c29606b27077201eb69698cd28ec066836a3b05d7b93d29bd9cfbed96ca674d7def4995158f9a6ad355da34489c2a3ff46ee8aebe1095b3b2a0a74e408dd95962f45da5b732d2777582bc8dda9872d1da7daee9346a9b67fdbfb64d2e19cf151c83ac37d1cbb70779787ac07b072f01f0a050a4de243ff34eb149dfdc54d335ae9c574f6e393ab59774f18ec62bb735966b47cd3ac240cee3e86e01cac9355bafff8e4b735bbef974b9bfc30b42c0270f72e1e8273b8cd82977bf9b88c6b66c5d1a4a52c45ee2ee4ee50dcdd030fc1289d474de6ea641c0a2a2d0edafa62d2dd7b90b9923966b3471847913966a424c9eb7ae4ee3cdccd7a6eb296bfc9cf51296d6bb349b76dbb8f45933976b39df82a6ddcb47192ed5ad3d61cb5db399cd2cdb2317eda5f65dfdfdaea8bc9bbe4ee629871ce4a9ff1862a7fe7ce9c3192fea9fa584a6bd6a9bb9431951ac6d9e97e95ecee501eae80e83cd2acb933a65577dfe1ee3a3cc7dd71dcfdc693c1ddb778f899e177fb16e0ee14a6cb7b621aad61ba4f4cf196e93c0e8d49c62441faf78e26b4448911f94e68a513274a9a90e42709c26172a49db76d6dbbbcb5b57d16c2b65cc951a84a89a02d4ee871f82644a340a1fe7a1955e0e1477d5b33a7e96cd7d98e879e09dccd1a840f0fbd27dcbd87871e0f1e25bfbed6dd75dc5963bcadf358629c10f953a1e7c191bb5be0a107e4eef74d0a853e8d96e6896f9afe506d7d28d597d7d29fc2b8cfb25cd56977b771ff4a77ffe1a107ea3c6e5cade5ee9e679cf3d35b69f9379ffb33bdd8eebaefe3decce12cddb6e64d6dd7ee5d7119d768fd5aee3ec443a77277d1439fc1dd75d8ace59fc274b72d597395d479247f4aa6ab5988cc5a88c4a6598576b9669a35dd9db502ddfde3c0cc17073840151b1f6890f8410004c63875c08aa89a0488d0c831957c784060e4050fdd6b8cc3061134992a006163d4f35380245ef000b2c2b8cae924231c843983c20faf0a00a98a02c7d15455c57c05c48c0d38384467bcfc4b013473c6a3291085600d2b72de3e622c1ac63525c5a25e071e134355d5b3955a3d521db4284b0a4b6b4bb5a817fb5c3ddb8bd9ec10426506779c1d3478d4eb99c1a3cef3ad78563c5b8a45bd954dec6bf56c2f06ae89b1c01e2a7c7bb1af870a6f35021c213492080defcc19907ed4e3317306ec49420c07522b2ac6d174c159519c55cf151c5f8959992f332798e07df403bd038020084a7dd4061c33f55156cf5e51d62ae6d1970be49162f5881913b3e9916a51d69415eba32fa957cf981808ae562b70058220b85a510ff43ceaac2270dcf3bc559817b5b1a1ceca1ba4ada98fb6280be411f32326f5f578cce31163c58bbdc4ac3cda23664cccd52305d28fb65a3d62563129a71ea3ae7365471538424000234408e9f5c011a265b5e3078f7a3d3e780a30b3a26652203a62d13154ad332dea3a5bfc8845cb90a9aa02573cad9e174f1488b3c307779ccfd3f1c0a945573cad568be2b8ce961665f5ac7870583a4e2e123ebaead2a2df9702092dea1d7d2e176db97a52c869b5563c600a24b0a87704521c9c1565f18c2173c43a5af5a4907304d2291f4bc989453d58d1564f0aded18e35472cb0a70aef49c13bfa7aaaf04a687d200e38ab2216d107429042c1a1be2ad2e1f9705639383cded1475f3d551ff5e88bc78f7272a88deb06a4371ffdcc8034877a3c24d850efb3d1a17e94c343a6aaaa8a27050e8e56f486c7cc19ef684553e0e008a4ae23440b487568d4ea0887474787dee0d033ded10df5e88bc74c0ec5f17848b8a19e8d4749c0a15f4ec8a323848a8bb6a45c3d43ec3edaea1962b7a21cbccce0d033d48c0e4d811edd504fa7a76a453deaf59859d19b9e2a3329d0231dbad2f940878784125614a7a76a4575b4e844ade877c363c373c63bb2a1383c6652e0e00887e27c3c3a2b1d25215a40aa433f58d11cfae23163d385cc914e0f0994841b4a020eebc686278524c470106b51ef88888d508caf89b57aa486d87d74889d102d20fd68d48a7af4e5b4a274f5b5a4c0214a23fca84789ca086d70848000867aaf55d19831257c74454bf02848c72411e5a22d3ac6cc197a14654359b48417bda13e26057ac4ea1953428bdef49ca1472b6ad353c2ab87455d3d25b43ccaea29d3f26e06aa8858c3c31a1b5060460df0f33ed002de1c4f78ab700e1318f17e2001fe00636172629f8ff7792b2f470e325e46af550370d05cc941220e35719cc1c6cf8e385a8863863872880388389088e309c7f158211c73b88ee741ab1d8671a461f580ab1c560e1c5a787050c08343031e1c6378dee781ac9507470e7000010712703c010715703000fc5a28a0f15eafd70f9082a0d11b676220f8860dde8a7e3a5756d4a3204501e7fbc21ef405d27ae0f84794055116a0e7795e16edad413dd08d39dc308197e6042dc4da30b3a24f629ea6046956ab96c33cf6a238613eeaf2c0d8176bf57c445d84ad9694778515868c7f06d820063aac0d11ecf8d183c562adbc1ed08d1871d88f188b4533f0271e63d1230ef3d80cfee36de4f06a0388b00d247eb4f1046d638a232c26aaaaaa8e38720aea286d10c3017df5e908332616c67b85f9562c23282cb0e5020816b96898bd22dac24c122b6a26057ad4ea49e33908e6803daf2f8ad6ebd57ab53c25cf080a96b0c7aac56ab58c5a2ed7b76ad196165e822c3e1c56192008b672a07c3facb0022c232deab2f96c40b0f5d2c971b9e84b47e7f4540163383d2c0f02691530e6eab90163208e0dbde159c16c28ebd371b128c8638487d2d0c5fa7c86582c106c5110a42d90b66e22f0b2f93e9beffba80d0fd0f7b32a8aad98b810ebfbc0d647592da0cf670512f9a409d18055d8785ecf8fefb55af5f8b4284be7f54d59794e73404f07a43d3c90b27ae440f3796872c0f93e96fbc4b4cbf5ad58ac6fc5ea01f2201608aebef0c2c603592005592c10044116c862816a8a7c7c7c5e2478c3f5234c8f21b1154841230e6319b91c06d2211f209f17359263c40b968d0dcb8605d2cf676504054b0fb0e56ab568185713578b7a8cc562fde09902335005c3ca87e903af7c14a42c5087e5e2a161fcf359c57af8be8f8705027d31acbcd56a459b4cf97c5661c80611abd54b07908d19b13044b195b7c3615e0f140f5a515087c3be1ea75032107ab18fbedef83e8ac3e209c3a11378432c4a8d7846565febd3f97ac2901a617d4394d230fcc162b1a6f8a0184531f2fdb0582c168b0d13c4582c8ae5e5c35a7d3e465f8fd1e7c3a25f0fb562c4a250b084445f93152513db1ff5629f7b01c6c7a24ebf8f05ae562003beeff3becffb28a53f28b85a7dabefbb22c4f1becf410aead06a79200be4a2f5b558dff7b1be6fd5fabeaff57d9f1cacef6bb1582c568b25c4cae359ad56463cf40182e2b55a2d6aa4b55ab5807c82a8cfe7e3d35ac901ba3e10044110044190822008822005bfeffb7ad0ac84f0224aa91b3c0c7d4386b0f156dfe7f91a3455aed60742f1a0d52a8afb185d11be62af1e9607b97a7a8c7c3ee12aa4d4c8ea034d80b302f220162bc87d5854c7a31e0f088a7a7c3f2cca3a0ac3f8c45814e88302bebcd52a67f5d1950b9ee785a18a85d92b4fe7079c149c112312f33428382386f3e540f97e563a4a203562a4275c03430812690152d0e7c7eaeb6179d0e7638445874e80650804b1d547575f48519066e5a373586fe01039200c12c359812b6781617c629ed7628134e61ae2412bfa83e54d88b8cf7745e831d0d56a40f8d12ff662391112e147411e9607b128cecb49c00409a220011a17f298072420c27f5ce90b12033d88f5d9bc1810b25e37397ef4830436c45674489832622b8a839383b3001d1c34e1ab47478e8e520ece0e1d0a087758118a6115e18e4845c863678a1e3c1250410f292ca8208ad0870508087ff870203f5e41807c3150489055ec3544089121de054430b8c0631fc580877a3d3c457a3e234532300245e8c5400d32008f68f0f239f2c5c01f9f55ec85e4c7db0089c73ea00dbc20a06f0c3a40e8c5c098d0f8443824648030c9902b49e22d51f2112d71225c31216aa20993a22646454e8c604e9ec0a03c8902454a140ea4f8140e9a884d398a211d252129255151aa42c54a95252b1d2c79573ac07285094b13539626a72c9f16a7272d504f51505ba2b86c61225c75e1e241172f1e7ce0e5cb07207c01034208606421cc647546ab24ad24bfacbdad76b3b9bd85b152619630a570e6c5e19bc36272598cce5b9f7bead44d51e9765422ecbc114418330209634a20814c0955644ca83ac18432279829838299145000400a6700f0a9706605155858a105165c6821002ebc10802560782106186488410032cc20001a66a8810625c2d5006af06c1800016cf86e20000e37ac72c041871c7c071d0ab0c3c743017ae0c1871e7ef0c181f82108203c2182580d210411437811441851847784112b248ef0d89704125e6ca544125fcc975022897015f3623945433e6f091d252442228e083feac57c3e9f1f5f8f9107093124844e15108cb55820cb83be1e222342cf0b42e7eb212a22043d26dcf38cf08ef090f092f09af098f868921a38fe799fe7b570c6f3bcef5b83873572f82e80e31f0e0f26741a6081173b40b0461b62190b66f011f3346a8c50b3001e70887e48a3c61b3e9e6d0905c230ce819847b178e1feada07c3e1e1aa02120cf89ce84de43c641f0cbf11ea0c762008ee779dff7b97b40e0e0b80750f0267f8ad69f9bae5660b028baa3d1f2f77dfd39f7d98792368737adf4feebf6d3a8edda5cae32d1716b6bd299942828331cce358afbdba6da34edd6f42f7e1cd6f47525e9b574eb334c0d07d9e8c6970a1fd1719731ee7141d7d2b7e56a562ed8897e356bd7d2d75697ffb63149f712cdf46934ffd45ffa19d73eff6d97b7d27b526d29eeb78529456569a263f925d574a4589b95026dfd369b44c7dcecf7493ed5cfe88e46f743d1b17cad9fc439476dd73e8dfe6c4bf1d64774aee27c68ddb5a49a8efaf1a63a579980f2dff6dbf0a6fbcc99f547ffded1e8b52399716de3283a262de56a9ea4ddb9e668bd96ee7b6292acd434cf1afd5b147d5c6d223f07f5ba7e26ef128ed2e57f1395128e7a1c46dae6596b9f7471d3be2746aafd13ceffc1c54da6a5629a158965dd1d8b874dd870f7809cb9e97a7b7d52bc29fd1237a13005d3665398a64c99e264cad0142153804cf9e1394c7f32f0a1302a447f32a01428030acb610a9401f5a1140644c17cf912931c8c117290c58f4f95c1a8b62deac98baf0c06d3175b2dfb8c492d2b7feb33ef7bca7027ce5e8b334ffd7947deb7e5c7bd6cbfde16473bb5145969a6596b325b5050d0eb7acbc9ec364f9c4c26cb057d142ca25c41f1a67f96b4527a4f4a0d308002a8a1608a7c09a354b9e3bb7b29ba7b29d9a6fa1b46c1e2ee3f40bb97f259dd70d3d5ca0d06236dfefbb6fc657d2bdaeabf5f85fc1cd49317375d6c757e2e545152e4df90b4bb7ff1d06805771f8f9268ad96a5fc8cb73e738e7eaef4a7bcd527ffbd16484bd5cf694c5e4c526d6f9bfe131393fe9bae56e8f8e3f3b72d82d574dfcff944a2e3c6f8893e3131d1ad7f572cb4525d6f95eef24f298d74eba7d1bfedfcdaca68f9a59dbab6dec86be9d37de4e6bf45651c6eb4a3c6fdb61953fd53f5d26ba9ae375ac3389bb8aaadac56dfa465593fef5e4af6b65b6f24cee69c2cd737495892bbfff01006e44e6174574af1a6bb975aade1c4012ec3597cca82aeadfb9e1817f4a6547e5cc6e1642b94c18510c5c3221e34ce2f02b55dbb332fa6657d93e24df5b634baef5bd2d66aa7a6e5ef9abd69af8bbb971e36190a8baa0c2d094109bdf5b6a9d66fee6ea5fa71b9ea13dba9cf4ebb3e6de7fa379d475a509322dc71145f8a420e6348795cbd34474f283a8fe49231c9b82488fc1293413f65779db2f94b99aea65965baca6ee4ae34d99319d77010ce864cc6b853d89798a46fd2ea8dac9fef49cbcfbfef5398596ffe7dad69da9a7e5bcdc972f56fb2fd5a4b917f2365fbc45f6272bfa6b2b5cf3999695aa97d7fea65b76d7532a9ec01c0ddab42a14c0aee1e0965aaaacca040c68cbb37a68cbb7782bb47668c092578644a70f748f0c6d8b48a0cb183851934eeee1d8800cb147fd99866452a2de692df342bd2b5369bb3ecfb534a2f55b7be5bb6ae26762a5fead6276d62ec84c34d17db8d999ebcd59a666c6b6bfeb6b72eb66b37e662a72e4692ca15f74fb5bc9fbff64fa5696f4836cbf43647fdae1b6a6b8b25ffc6a7187bb76cd356d9e5df1b63c93826ad73364abfddf7c44736abdf5671f6b3537ef32cff4642d9b8fcd36ebf2531d46ee7ac49e5a74c8ca4f55f1c2e6f7d322b6933deda5ad14fdeafd5b2ecf24f6152dba4ddb67fad79b3e096707942e94dd6bc2f46dae553d7cf513557de9aab3c0df74cfa7f6f8bc361a41bf951a625ef89917664cd24c67d92dde6c94415b55febd8be8fdb55a728ad9fb4e55dcad99bcef8b6cf580e57b7a6d5a3ddb6a6dd5ba05aee1e0b74f756eedee7ee9ebbb7668e14b83b0ae658b366cd9a356bd6ac51e3811d41d07490f3317a18a2e6cb1743fec5131e8a5c98809167c1030748d8a20a0f9c8a2b2e807326e70c6f22072a649600c37d882132f8788115ba0e4faab0010d32ee0250535ac00010b0e22c2469428a32f3e0279c004a04d504463e8213aa31608059c0b59a2b72222079c271162c6dc1ba800baffd60860d178dfa4c86a812c86069c13fe04009ba0000f9866f21a10d1548f0a83be5a4e87abcb8c2af2ce14060e072e15598406181230120e1484e85788c0039073750a0044172e44f9caa8457c4c086177571802a3868428d139da06404272035e0496c38a091a901f27184391e20440a667c032a5e90522543e93f1a4041e29e1eae0102e698a3042430c28d5c1eab2f4178c07ba86c81238384294ea704e141024202fc020fc439c2a8220a1fd2c2075cfe00250fc281344e24b1011138102a1ec482a478c07d3c008c27b528a15b30fb3e1d01c2f00a74c24c816abe701e5d5c4089129070f8ce0f3e2230fb32858b2a8469962815e021990330a143180df88e146e74745140e83a70a0330001c305ae630510358cbcc0798e1a45e028536081aa1c243b6f728348154e0e618e38be38c36f1ca0c119392d3e54ddf400f5883aaa729b33150880074b44f8eb0d165a0841115ff82ba705193d607155b94810a2f000244bd0b8a83ee019c00808d0b85c5ef870ca41cd94960e26151376e4d0b49c3cd933709929ac0d14e172058f31ce3a018513725ab8d0b0848c24d1c1ce195560184dc810430b4f54813588a1c38e1826d0805a2e0f4e4a48e26068010d60304064ca8a0238802047192e61ac6c6040991fb43853b5a26db9917a5a4357421828e9e18703f44b811a2c3ab88d876f0237a87066800c0f9f106c48e0cc000c345f095ec430c48c32fcf3a2230401d040c1ec6392c20f09b373f6f5f8f184c36ecd14cf04407851c314aaf23090e3816c2799e24d41b48117b10d26bc1ebc0f5c5314a8f2ce7c30479014270c79627e7cd08d71a5cafbd265ca122c47428f8a042cf000a80683b784840278f174c6cce3712ae10c1a95175ed8442a031c68000f9e636004cc8d4995ab910304264dc8aa7c0c2a940082891639ff620b0c0930a2829167214512d59305d4a9d800174e78651879134d883184a7a5ca87180241075128e0e43a3479000910350b9fe1234de004151f67e18887324cdcc08497711d893064051e7c042b535ea43ce1e33a056084b89d271c572400739041430e5e63c283924106239fedc0438d15de08fd83333c2a2a6aa2f02d67beac41abf0c29d44708df0050b16f02b5130a9c1880788bc8a94595e8304261ce9450501243471c63910cdc05de08a0e7fd2a584264c200081177d41c68925e220c389ced470e4869b1c3c096e07270b8ce1858f2600f1443411c2375880181d3cd57082ff6c808010c4f18305ae01154e5c51039a13dc4836c1cc65c108efe9c00d0fa080c790d3a4d66e882e0bbfe00b03dc2813a5880f81010423527c013d481844620fe8d1c0812c4981104769ba0f2d1ae04511111db78096002f661b08f10a76c4c143842058701e13e08085a33796f84e1020284981dd719105256bbc1a21f0d0040490b141d7c37700600425eca0a1e33a7230233785180db88e021c608610379e3c670d288268c30584e76c500230644fe538ba015356d834f11b2ca6b2448004a5df14b111b1c11983dba83087084a700002fe82c30711e05c89c25f622680a68808d6b88b0d170604504214eeda6df1441ab013b8eb75844d50ad89b776805541f24410de82f58862c464c7591bc8c0136b5838c1596592fc80033480b384b0c0608ae6c241319676590c2b1c1c404e052b601839a8a50d204168910107431a84a4b921f45505766e5d2c5184af08a0040514e078e02b9a15b80700b1c65742277c51f2a307ffd630d930841948f8370136b42461060eff8650b23519f1c23f3217541942c60dfe79e172850f4e49f8c7448b36c41cac7f3dbce814c1f1807b2610634a097e28710f034a413ca00136f7a6085341014258e25e0f443d7007d8c1bd332b40a14651927b62b8ac50822139ee7d31c104213ca8dca3e20606d248d9b9b7e407d7132ad8dce3d14ca0f161cabdb08b0a42ca18c33d9782c50c104bdc49f00309317a38701f230d921305d871ff029b2957f0e29ec5049608634607ee54b08145911cda706fe20164f0e8c47d0825286e7c2b771d685ef8a2729fa1c72b19e1e1ce02540c60b2acdccbf85072021408e13e4297d3070514e1be73e4b0dd10c51d37f40517ae22dc6b54907152821ddc674558808b5c18f70f4a108ad0e4343194c6b9a66fe6ee4e1e1e4912439f949f4f9bad5d4c525ae94fd51bd594d58618fe73f34aa0e1f6e4062ddc2b4107a327554adcbc12361005ec880b508fcc4f1a2713f821c22303001b8ce038c0cd2333471646432870c6ab72c1a9484a4f149e09517e349931208d77828f344cc8a489c22bc34345c4030ad47866ac0d4bd07031f25090438d1230aca01e00cea049d6fcf0f25688319184522b9e0b47c218e240c9140f06285e42217441e3d1b0c3692c41270bef865a55900eb8303c1ed8b00244c5088c3c22e60863030ee8f0c273228d131239a060f0ac20c11b4882e03cf022a0059a1f27ba2a0f8c149ce1e3010f67786e6c21e288ce89303eb10a2b1ad470459a6fc9076832388006a2f840a02167c4026fdcbe17901051c4043aac7c1170322bc2834e5901f142448f122546ab290578c1a305ca6c8506541a9aa372063cc930c2e0052726583d51682e50e28334ac36c4f048a09aa2777fe562abf543d9f2ac17e3ecd32aedd66cb35d2b75f34fe12af96bfad61c7571d3eec6a4aed5f76fe4b6529fdb45eda87076fa421f23ee9ee3ee373e3d7c42164280c14f664139c2dd3d0f244001267e80f1450ceefe79c93d1df1458f352570f78f081f8a70e231451645eeee0dc101047a7a9082e2e6ee1e07327cc902830a3a50e1ee1e0356642ad0810544b8b9fb0780223d0af0810cb4d8c2dd3d032841731d2a84f0e1eeab3646108213483880002370f70f8b120765b070848513b8fbaa8217bc50630036504101776fdd40c31b9e05602998e2ee1e196dc430668e017ca0c8dd411c662e02dcb6080386fb97f8067d89afbbbb77640677271281f727376871b331ce3a8f34a12ff115ba96e6ee42a8c119552fafaaca84aa9b2af7aa2affaa7c55e52a54390b2cb8dfb88dbb9f715fa1ca6daaaa4ca8aa62a1cabdaa6a85aa133c03203cf0bcd048933baedda52f6bb6e5b66c5db1d86def9208d6acd75251da99b95c4cd79b53d4932ca71f57ef266b0e87916030f24b4c4e2959724a91e5cf51559c14894d5a36ebc65b4655715415475a7d6dde542f7b5d6952942c39a1e477a2aa387ca3703d61f23b69184c8ac4e69194f273399bb786e174d541c9e2218f936ff273c624ddf86a4a6b96526de9dfa2e893992c63d9acfc9bb6d7d668fed2b4e791cea3de16674ddc6fbd73f79e7c6bec846b776997f1aee5ad4c66cd9fcb62565cc64de5ae3ae9f7829b16e0ee57dc1decc06d75531b8662d179dcd7e2dc9271282809f9608ce813a3f38b14287a579dfe6b32bdab39adab89742377cd699ba47535c92efb66b3afabc2dd3ff010031a4c7bd2928c49462541b8766dd09b95d4d766b5beedeaa4f36856b382e0e105398ce37864bf09b4eb671bddb8898e9a9ab59a27695692deb6d551dbb5e53de9e74abf0bccfca9376555df9a374ce7f1a6ebeda6eb8dc81bee3be39ba618ef9bae370a7b9d7fea33752f7f2abffea7ff4c85d4160783e9fb5278c3605a9fbb6ea8276f35ebd1c556e7e702e5ee4b56623c5eb9b4df34ab130e43fdc54d51ee4ea99090d0ef9ab7a69d5a88bc3b1d94cb5517b4ffbea5e1b008414c868476dbe69a2bffa6ebed9e30d8ce38973bb5ec7135d7de5633de1a067b9cddf7cce1101e9cee4a7fd7ada9bb2be94479380448e7b1bcbfa9fe89bb87e0a1102afcb7fe2bcbbfad0c87734d467e4e0b913f25b4847c1a49d6222325342743b4a2225a7d2323263f4454abfdd00f91b526444e6aff4542e4d6671612c283bbc7dc5d5f6c37f9a692c6b926779fc241fed24ee1ec54774d72f72858e8f772f7206b0441836ac8c756a39a624a58b264397a52aaa214d5b4b47454a569e9290a8a4629452165c182654bd393d21295a5a826a5a4251a85a4d4c151162c31a5a724a5a8d89312d3962625232a515b94909a94b66851828a5282226d7edcd9e4c424b6f4381b8514b5e57136aa7c11ac59f3dfaff226cd6acbc5766dde504e4c47417ab8fb17da9465292a86b484c5c92906e40cf72f146989ca12929213545094074a514d59908044e08af23779e69fb2dbe26cce012102481021901cdcfdc78782f94295a2625c969e9c1e67a37ed7242af74dd97d53f6bfdfcce1307997cc4ada8b6f252f6e622a6d16772f2a2d2e6d16dbb5f9cb9c653f5496fc5359f297f59fbec44cb61af534dcd964ab51eedee4dd9dc9ef1dedeaf095ba5b6c35ca76edb515f7d9dd85ca2f31f965ddd5dd898c6a7b8bbb8fb6baff342b17775f72b1dd56e39cbb2b49e2eee5b5523f427717bab8c9ddc7a0c761285f4d0940081b511039c8c5b54309a50deec2401537ac983272af0cbe19c0121470971b3c2c8d300a59e36b44e0ac1a58285aa2c600f7a810d70ea008ff704f96e860e7e3ac1a560d58a20113677d6044d20898a8fb8f0b090b1b487197e2428b2d6a80e15e03c8c0e044cb8cbb801c81450f736471d0660133c81630e5ae14b280018438d6784b0b4e8d92c51a7757fd36151ef817022b63970a38714781115560a6a4c1a24dba18038a35ee728205c90394299c65860f330fcd8f7b44f83ca9e056e12b262d7878a1fac1bf29381d1c805be32dddc203a6ec74be9240129a55d593af9c9ca6907440046fe13083064e90c08b7f5128b102ce41c45d28d0204415961ddcb546083954913373ff2288395ef8a183b7841ce940070f4c38d0b559b3be0856ef13ef2a160ec29dedaea66ae62e9ccb4107a378eee2c12b59a2e7f21d1ecb024f87f7520216f96a06f002d7f77ab1c095e7b98f6ff4cf3d2d20079ebb9eb07c47cb73cff3582ca20fe773cff3569f15cf73799fe7ad5a227cdee7b93e0b9e3cafe5b9fcf374c6d5d76af9dc500ffc3e10060ff4bcefc66be3f36c9ce581dfea3d2fcce779df6bcb27e4f3be16f87921f83caff5795a3c1f9eb7fa5e0d60ad5c3a3c0b3caf82d7cad3c1fbbcd6e779df4ae67de08d0dd197e34979792c23ab289eebfbc024ab9beff37e7634f1460093e05059397d0efa178407ae7c40d6e7ad9c45833786e79f8761e89e7ba0f7796a78af0f89e77dacef5b79de124fc87b7939dff77d2d24efc8f7819f37b41a7180bc34f07476827c03f0581f100ff4569e7f4e1fbdf140ff6ccbe9cc7361e53c0df07c0a16dfca6b79a0cbd3f156367cdf0bb6f28c56def781f4cbb1f1f1589ee71a02936030e47d37add7e7f23c98f77d1b58b53c9b0f5c4d793ddfe979ab20cf06e7f35e2eef9bf25df05df01159f9cabd1d5eebfb3c1d305c811f90effbbc9607d63c1b231e0eebf3589e8e2221df920bc7e6f368af1cd7e769f15e9eb7fa3cd0b3e211f99c7c433e9ccff5b1bc95f7791fcee702bd156be50543421f3a3a3d425146868bb212b8285be3e26c878bb31f2ece885c9c39b9389bb938d3b9380b808bb302b83863c2c5191a1767127071c60117676a5c9ca5c0c56a818bb5888b55898b758a8bf58a8bb58b8b9574b16a176b0a2ed6195cac44b8589970b1a2213244489070274890ef0499e23b41b804a9b9fbcb46c78d8e17d0452f392e7af9e1a297222e7a0172d10bcc452f4a2e7a6972d18b072e7aa9b9e885ca452f29b8e8e50517bd10c0452f45b8e8050acfd90152e53b4074be03a405df013283ef00e9c1778024e1ee3a383b3b7038e3210e34788803101ee280000f7170000e5e7888431a0f7108818739b88739ec789843110f7320f230072477b7e0a54347c7cd6b473cc377c414f8ce8e10dfd929e23b3b3fbeb353e43b3b567c67678befecd07c67e7face4e09beb3d382efece0e03b3b41f8cece12beb32385efec2cc077762010eee84143141ed2e0000f69c88087348ce1210d6b7848031c1ed6c0f2b0061e1ed650c4c31a843cace1098e0d8f9d1c23dfc9a9e23b394fbe93637d2727fb4e8e19dfc91980efe420b1c3fdc78d0e1e54f4e10a226a4972510b948b5a4c17b59871518b005cd4a2838b5a9a70518b025cd4420117b594e1a296375c7ceae1e213918b4f4a2e3e7171f1e9baf884828b4f33b8f834848b4f50b8f874858b4f5db8f8f4858b4f1e70f129042e42b180fca88085325c64210e175bd871b105212eb630e4ee366278d3bac9e942878b5dfc70b18b222e7641e46217555ceca28b8b5d8071b10b9b8b5d8871b18b115cece28c8b5d04c0c52e04e062173ab8d8c5102e76f1848b5d38c0dd71c257053b3b3a628e4e8886150fd180f2100dd24334b68768a0e0211a347888c60e1ea2818487683ce1211a5a788806181ea231020fd158e3611a403c4c63030fd328f2308d240fd370f2308d99876988f1300d321ea6c1828769d8e0611a41789846123737e08e1cf10411b87842095c3c01052e9671b95886878b658ab85826c8c532442e963172b10c928b659e5c2c535d2c835d2ca373b14c1917cbb4e0621902b858c687968f17a8f0f0050778f8c2161ebe90c6c317d670771d3d6e76585e7c8765f31d96f61d16007c872583efb076f01d16112f177a78e802110f5df0f1d085200f5d60e212b7b8e2e216d5c52d762e6e11838b5bd8e0e21641b8b845133a3737ad1c7104352e8e00878b633e17c7ec70718c0f17c7f0b83806c8c5314d5c1c93e4e2982617c740b938c68b8b63662e8e315d1c73bae3d8bc76a060e03b5090f80e1426be0325e63b503af01d285b7c070a18df81f2ee9ec3c383c4a07818b3e261ac8b87b1301ec600e061ac079b1cb101402e3680898b0d90e26203aab8d8002d2e36008cbbbf5eee363a44295070510a175c9462002e4a510017a510c245299670518a2a5c94620b77efe13f2a403dac00918715e8c0c30ad05e2b8400063a81266a8490a8d2dc3059c08f9a963339f8f0717777cd016483bbfb8e009039e3ee3e840511d2ac59f317ffd7644a5e15544c910029bc6789300ad77934cd271100841705029e78e2092928b2701b28c078d0dbbc83b874a1a3edce92b22c3d2939c994aac49eb24441c9a2b06c8951514a82c1727a0645df56a5ee792369f974dcd12815a48d9bcad7fdfda7ba6bd2efba93cadfb8a98673c58271d4a6fa7d3152598f5c8c15039c711f67abf9960bd25e020c50827b5036cd7a84136fb048276208aa4eff547070e215549af646864d04e167d0d6b5f6fba4d9bc77accab479e8ee3226d494f8dec0040c486552f91b731162d49a56690d676ca7eaed69f4379eda3a67fe6dfcd9d17cca5c6b146baae968bb16db2ea6e34dd75b8c8eb7df980bc6517a772b1314b08912403ce58b60931841120a4802091f7f7ce88f0fd57d936f20092cf507210f930091c000121170172a4205891328d535a764c9d2eb5a0ddb5e23f1b27da6478441614fd69c3ec201eef4c17ca1528228982ff4733bbce9085ccd1141c4d027f74d992c4a141a8587de376532234e30a274f73781a8b6541bf1b9eb46fd9a6a7be2923eade633661bffbea675679a95ea53dfbfaff18da4f9c45ee8a8f5b96baeb95c4582a4eafe888e9a8a036d8b10f1fa4244263384156f8c33caef04429c719caeba7de456a41b1d6d9646f1aeb67c1cce527de44d5a8dca475493d8bc5f969696718d6a4bafc566ad7c3deafcfb7135d71cdddd8ad35b6c43667dadaf7d7dca64667d0dd31ac774e44869beadd1bf6d5cc6356d561a366db47c6d29dd991796c3597a71d67d6eb7ebc5b7f699ea2bdd6133f7a5ae369dc7cf35f7390783e9f0b087325f62a4f16963a67f23a9e829e69f70ed2ee174d5c1606f9e2566c2e9dac5490b1e8c0c50001378a9c10ca7ae9fb7b7410188dc33093b5c2067964a36ab754f5599469df1262b95aa6449794f9a3f77a464c9eea5663f3f148802f9f8d4f006944867d6b2acf4568ac9f29bb45963b849f754308eca5fe62cb52cfbcca2df66bceb52fef23e958d9b1e67a374180bc6510b88000e2f57c2d96a22c51e57c93f0af34fbba5376d0d0349e58abb91f78fe898df29a9ee9a34669cb33b7fee5a264a55cdaa318e665cabb4fc769c5d3ba3aa4c33fd3a6ce6cfe54e6a566cbf466d75df27f3e7e8ae4ed726e56878d35dae96b4b5bf4fc3367f8eeeaa3992d534fff6b7a829c6f2cbdfd18d6f4977369374fcb2e234dd35d1ec74972ed6f59fee16a47f7a2a4e4e9fcf5d719f9d76d54ae9706c9a066848a26599818c7a8ae12242d10c4453ae8305dcbd04016cffa41040e841210313ee3a94e18cbb8fe6b87ba90de8ac5cfa2b33fab7dd4b5d1dae7a26bb78762373fd6bf5a92dad371d2d77eea57e4aef5e4a1fd15d5e53dbadb79bdda4c5e18bc937f3974bbfab25b1d631dcb4fb2b7af75770d391f085ecb69b6f32a7e285efbe08f83315aa2fef520070eeeec2085c9861bc27ce9d52189bf46f51b18d9bf25f5d968d9b5e6fb94b1b37edfbb7e2f23bf5f0705a00c2dd6b184f27ca9701c0177a9f4f28d3ac485a7f2ecb98cbe1b3f37d2e2fa80a095fc28211cf8a15b058817a73783f4c48e107ef042e0498c0a4822f881745dc9dc943326276e009cfa8f11d15ceb91d6766d079a491e0eebbbf62cbb12b4e001881cee3eea58478f67ddcc50e819cced92d02a0072e4fed1545e1a6b5091d200510dc69d50be241e122582d82d594fe94dd41543b482827a3da55a6fbfb39056688c0e9aa23c778688647ccc657f7170663b2b979f2b4f1cdb3c43819add63ee746f2a97eeabe8c6a07bd2dd71b12aedd258d9d6edb76c93867a5ac24954529eae97fe3a9d2c432b36a5bca64af710ee7dc3d339695b9eaea2edb1cd5cb76b2d28410689bd54964b25c95e92a339fbc95a495517e69a768eefec3dde570f72cee1dc0ddbdf2e9cebc5d4ba38672756b9cddbb97ca670e67ab49fee75afeda8bf09f6bdae284486d7125249570848434db0b220c770aa871b754ee4454b80709c15d47c8033d9c2f4410a3830d170fc7784182061437e93c925fe26bf3f642afc7aec434fd4487cda751d9b57a6b6c45ffb53b87fb6b83e89fd7ee8b49fa64b773b820bacbfb3ecd616cd28bddc930c3dd87689428b403236cd179cc7fef99938c433058fefd391725ca58335fbb7b30fc7801f40260d2ea3e71ee9e0b345a4b0884225819afcd591d9a703747a5b82a76402cb14b9231fdfc53621c257d28addc36eb38e04e3ca4327f9f544b5419bc08f65a9c2e8cddb6a6d54de1ee473cd4cd4033aee9a0cf3937743aa478380543fe6b71e114964c472ae114f8fbcce130199e599c30c0f699dbe76ddbf0c41285d2b1fc6c4f3164a5b5b367cf41cb3769f53ea53b8c4dc5487321ec5b19f43947a376583fb35208676148c9994217a1612029108549a114262b479ba5e9253da4fc325752db9202510e804c327320cc298cb66b6fba9a9a0295f7c435aaf3088389a180bb0f7928c6875dcde69fa278973785c9caf277ae1bca842abf0c736ae8d717e7f4677a6d7e27aaca14f526ad72b15daaca346afa5275eff6b5414f5e0ca4f7f91b4f51dbddbba0fc4e6599abee88eaa7af51f356fb7c5e5b6d957ea678c360b32ff4fe943e546f186cf685d69668d55495a96add5fa02cbabf663dc53ccd585baaef53d9d6274e464fbc3be98977b4b644476db505ba4b74d457874baa3759f359526d6fa5c553555345e5bf96e969d44772b8dffb75ae9a4f3513ba757db33e0e88c99b395ca5aa7f8b2a4d7cd39f6f514723544ffebd9fd64375bdb6f6e514ce395c7d5d6f495f947136a3d54ed1fd1a898e6fd2acae5f2be9d36cddfbc891fc37f235dd996625ed2d57b30defdc2e93b4ee23f7c926bf56ab3463bac9cfe19b5f9f41789f95de5cc5ed5e0af61b5f4a85755174bcf8a4b66bdfb4371d9de959141df5dd42c75d29ce34cb5bc35f31b9ab398a3f1f79dd6f7b8ad15074ac7457d376ada6f5efec5a3a9b7d9efd0001f9cc806274fcfcb7b2fed677898e3a6c6a9bab4c3aff14a6dbeeaae9cecce1acde96026d5d73f4c97e4dcbaf541fd9f5b681663f3ef7cd71465f9ffb48173a0e01dd2c74dcf5c949abb634f7a4b65d8bc39b3e8de24df5e53df1d3ec0bd5968299cdbee89d79b3bc2dd75d7eb6fa934cb392b4bc95a4e3c5b9f3fc530c05ca1848cf28ae7ede3a77d25be9aeff64263f3f8eb45be36babb6a4362013e34d6b65d097e6597b7de65fa23b3357a52eb68bb354fd2e9f9d4cf3a4f2e79f5a9276d569e37b2b92d67fb7ed72234f268ca3a06a56b25d9cbb986645d2911bdf74ae5e28dbb55a5b268ba39de5ebb069c6366e32cd4a6586048ed27d9502c0c26cc954107931ed6ec9556762ec443ba1f643e5306eca65d16fe2271363a7fcf72e99183b955fe6aafba7ff4ca5bcf82848489b18e7645756c4dd7375e3ab7154b9a4dfc64c249d5faa6e285db352b984a3cad7b5cf4eba66a55a96adef92be18a966a5bb74d3d584cab896e5499b9d70bf9732a6a243305f5c6b96f54b0a547ea61bd3fc5219ebb014894da120770ff2108c096688decf61301f086c80c001770aabbb96753f8e0251204f05af052077cf04ad71eeca721aea6302fb86dcdd8b8720d8b8eb208d735748ef70b833a944dafd95fdfa9f742e577550faa9fcb2fc1975cd5220f2b9d0f281cafad98c6ddca4f56fcc0587f7ad3727d94fe92a1ba01ce10708f88008779fe2432fb696eed8aec4347acf1a0dbab8c9abc20f2c70f29e3526e3505090c5e9aafbf1d9ed1cee65da8e5264dde3a62af5e36a9396959fe57118aac4b88a69c6ca9fb24ffe53e885ee6836363637e5d32ff46f5136363637509cb68c5a9b39a08c6bdb6aac6b19db9c8b518fc9582bd578974b5c6652a432d6ed6f2abfbc273e82f2a7989acb923f97abb9cb8ce27ddb676c46cb5bebeb2850c654e858e9eb59fe5d8bcd3e9f24599fa65fe3dba6ba52a0197eda54df34fb5d7176eba75a7fb6e19cab74bf8de24d4d5b6bb4a4ed72d5fac98d2fcdbfab49ffb6819e3c4b9c73b6ea28ad5fdad22c4b8bdb9937db896ba7d5f47537b2daaebdd7da3e46475aded7146f2a85a93eb22dbd91f6a6a3f9776df757ac94bf2b69cddc9984e361d400a27451d89dc27c288551dbb54f140c857d110a1acb2fff2f7d1add55dcd66798b2d2181defeea5e8678cd3b66b6fae5dbec44d4bb67a0475a604a81c42dda066545bdd5f0a446d9546f1be96525a3e982f3487180aa0868271f75a70f758f054f0ce3ccde1ee545b2cda568fe8135ba595b6746f044f51dc7d2c5f0c1d6d954677556756baf589bb3f656d5b5baaff12d37490b6559ab6260cb6b53565da5669b2500b07dcb4b5b4f8a6a395da2e696dd8a4ee4ee5a11610f49f5adb1bf99beefababe99a34fee3fedf33965f5fdda97b4326182d5d21264ccb852a730ac1494131a77ff1a7d6262ca389c530e7ed3678e3e313189c185061e308ef93535eb7971497514e3306ed76ca92dd04c8ad109857c2e359cb1a69feb0e67b159ebef9a1f775e253a6e6c6afa38bb6979ad548c8e7a679cfbbc7b29aacb8cc9cf949626bee593ee72c5d99cb35d6bd66a1836654f310f7b5aa555006480bb931e4a796ac279c8e484dbd8d8dc8c363636373f423a484893b80cbab6e284b01d474de2524808a6737bdf7cc0e82f1487b73e916c6c6c6e64b251976f9a1569772b13c6519576ea5dce2c31ce44da412643132770318be2b5a23796c0506584a2260f9dc8b0883263de00983061019fa6ffbc946f9af68aee9bcadfb5cc6df9122369fd2479425dc9c07dec000519e7acb4e4610740b8fbb8a3d1a7d15b499a3f47f7ad36d729fa1723996645723262020535da4ab754c551bc69fe32637aed896995eaf095da965eaceb3fd191fc9cae26f925ddedfc399c73b467575cc6548c9868dd435633f7595b6ac4040a8a96bfebb559fde5a88fecaf426949e34be1a96be9ad24d575d712df74b5b275b6b5adbf34b10fcdfd4be128131d7127ce5255dca8b5ae340ad31ad02b7ca4175bfab7d9e7dbc6b5bb14dbf8d29aa53fa50f7d6d562a749c295972cea8b67436a3bbde36c59a96678ea263f9f773b97aa3e7d6b586e96c369b7dc61b8a8e5b63933e0d47f579db369bcd9b3e8d9aa6d5515bb31b5f8aa9feee8bc99abd7fdb74f6faa4afa3354b5f9f957c1a9dfd507d79978060b0289f19fddc6ed37adbfaf36f6bdec8fdb51ac6694b6dd74a9135efb77953fdb6fb536f5a930cda379b35a9d661d3ac54db5b141df17d129bf46d95b45bdb6b71f9f797a6190b578765b8fa5bb65fcb642fc3e5a9c5ec828725b744312110438628a614f3843940613f35a5bf335e1f10718ebb2ba1484a13e72a798af95246fe9490f65ef8bce4bc38e2fe49e02ab96f8b532a31d2d23be17e5b3a56303318ac66fe43d1516b4bf749a3d79eb65cb1e05dee44a8e498b3b129af54cd6fbb18cbb63636f8a62b6f2d1f77dad0efa269362a574ab1aeafabcddbb4b5963bf5b6f6da6de96c47abd1ad31d216b6eadd54fddb94121dcb92ea4a6b56a73f8916d1389395de1387c364d54d615aa51b5f3a96bb343fef4c2b423569f9fbcdba2b2d2fd171091de9a8848e48744c4261356c4d13933f4f5e7c295069653e375d6f96becd9b522448487bf1c617e39020a1556fa01d8dfe6d9bf55a9bb555b35631cd8a83aad5cea37de66e3bf749a65962a42f31924e2aa3f69bf6d625632afbccdd25a827d2e67094d2b5f586849b4cf3a4929431d25d2aa38ca84431d94eda27956fef273d796bdef7cf7aa352da1667b1ecfc53ff7497c6a0cf3224d76314121a4537a0982ee1ad31be91b4ac345a4fa09d69c713ef6805dae7111d3d8831c1604d929cf5f3b64d929c545b1caed666651d957c316eaba9d051ef74c6f93fd0549569e3a6376975e7f26fe4894dd36ea81d15cee52795d7e20e76a619d37d13aedc0ff5e6f9a4fba62e11e8c2c4c58d25d3ac485495699c5155a6d99b38e7cf69aaca649ab111cbd3165aa919baba6bb6d18bafc6fd97678ddedf516aa3f8a6fbdc6ee39deddff47d1cddddfae689f74f05fdc5d4acb67e50fedcb9f357f26be69969d2121285a2e2b4b4dfcbc64d3bd37cb25d5b2ad55d7395ab63e56f6db16cdca471bf97ccbcc5767f5b4dfb2ee58dedaa99d336a9c4b84a979bae56dea455bc9fcbc64db17a64bbf6fe94adb27153d393ce4f83884e1470c2c2c90ad1e9004e41884e40388d426140b4e695e194e41fbeaec99f326d4def6b6b5632eb59da29bba54cfa7878728011b35bf29e98fee2268c9f9c3c3756529e54053c046207aba52786942859a2ab4fe512d59757ebc72200bcdf5e5bde4ad3b67cf3dcf771b7caaec56176a65965bfebd49bffa4ddf8caf67d9ceca7acedb3dd52a4952acb2ad32736cfdc99497dcfb26233777e8949d3aca4aee5ef1b79e2299cade50b097959f0c690103b7811820086b20c93c8c8156478f192c6dd573a579c33775f5d40e5f396086854a102549859d02447142d2531a85a491c54dd88415e8460c498c921012bb45c85850e0cee5e1099fb1702980f0423d18a189d472128f2a764e5c3609f3129cb69a95c10ee06d5f29458850cf7efcb0b5e9a0fbc78f075f9b8b8fbce7a678854ae70779dc71c2e7285ea8b4d133b5524291263d9d6cc4195b996b76ea8df780a069371d992a4757512937444241744a4a224aaca34eeee9333faaff3efccfc5398de4a81b0366374acd5b08931d2182445d61cb575a5328e3b73df273fd37aa3d5762d05caddaac36128bc2feec4587e632ea369ebbe4f75b6625e5ff3ac690d54c33be3dbd36af8b18c6535ebcfaee17d1fb7c97a95c68a4dbcabfaa7ccd7b8bfed29bccdbdad492b7ddad20446f3d4a6b9edcfb63e7a8ae21cce4e4e331a4433a64f6633255dbb945b572c331a4461fb7158b775f97febb67fd3edcc52b7b3d570c6a4d604a81a233f7931b9b48fdc99121d69f7a4f71655ab54a540f43fd7be56f5eea528d0d7ea54141def163afef8e830962326282bb8a97cbc9f0beefc8b9b366ec24ddf943f97db62bb387779d24ea5d04b551a853d65797a52a2484b55b260d1e57d9ba938e1b5c0840c77a7957a669830e1f92032a1721f77884ca08ca5a5e9884473e0fcb9dc8fb8484445d21a221094b84844dd475bcee0640cdee2c5c50d606711387c8002359ec64712fb16a21206f82c6a466b67eee24e5d6ad3d6fd49356f2a25b39a6f052a3feed41723e576aff5934acf830ae28fa954774dc2b51b8583192949a2c3d72693ddf6cbf096555d92ffb6aaf5e364b693f6a59192244a5eaa9a34a94a922fd584891299927ad3b29baeb7276f95edd732bc652ffb8bb7a6e1f0d6e1f2b36cd7de94e96afbafc9f096ed9bcdbeae6299b632d9d5e19bae3799b6d9acaff799bbf677ddd56ed3ac3625667d9dc4acab28442053e7f149f9629ee81367b2e2e80cccd47dd99722b39b9cfe9d619f7341bb52b6db7667cc24139150e12fdb6d9b71988a93c9b6ae35b3de8cf74fe1cedfd5f6e697f7d45b5b538aac264de6791f8ffbb883e0e29137968c4a928c4341578733eda6ebcd027b3582149aaba44cf7d71b722f26664085bb5746ce4a337a8f84a399eb538ca340206ac085fb78b1d5a7495ebb6ded4247ba2bdd57d4c0080d78a074a741d5b559adc1cc5dd4c0c8dd450d76dc8dc62441e44f9966c569318359064614c8dd5b2e66e043cc20c7c81cee0e44a94a0ba39534e3702e178d84e114a6716f7ef95f9ad8caae8fcb8fcb1fa5fb262e195f9bee9e99aa32514d475cfea8f14b4caf05c2f94530cd9a7ba99adba273a76cc4fbc7a7bcf8c876edc65c46fd1b4f9176df6ab3365a77b4ba77ddd5f2e223a47147ea237f73a73e127480714675a54a546250b9f33449aaa740e5c5e443d1b1e24ead2bdd99db92f76f2533a6650efa916dfd3459c5b92d74fcd9da874add9a736790a634466177898ee5ffc65c70d3ee5626fd1b73d1612cd509476dc9475b9f4cb92d4f4875d7a4df98cbb54fe2902cc4214cb88f60be50994c1c8254fe99b740fd99a5b4d5a9441282852b45e97ded587e06434eee9b95866daef7494da1e89804a6ab619db18e3ead029d5a5bd95012ba35c6d1bd8792e0bda3d53069f7e36edbe659fe9959f5adb3fb393ca3b7da5d7310de417a2c2d3d62620c4ad9f2a76cfeb2b4d45a4b8fc44cb3e69f52a29d9afe8d02d5dc89b38ddec8aa44c7dc897395af3d0e9354dbfa64cdbafc396cea2fcf7b8e26c63d8fab3629dd436bf8cc659c4d8c73380cde26363176c251da76b1f9473bd33ca9ec6e0c1f4969fbb471d3c64db66b77386ffd49394bdeb8e97e2ecbc64d5a5355a6b7dd7a2bd24f552b1b37e9c7494a493b53eb37f33b55bb7375422abf2c632355652233fe146e5756243a8e74e3a6b734729ce9f09dcd92d00da89e0599f54baa93222b8db630eaba504d9d5edf6cd60ac651e597a749be49de2d4f92a73e731aa8fcfc3977d7f1c8f880eb74eeaee4ee11f1395ac3f4f5e7b28cd9ae2d317995caa5fcef4413738c728af889ffe29c9576db9af5d4a2c3587ed7a412e32a5787ef953769758b8e5155266d2bcf0ea82ad3c576d7a76d71164b69bea50283ed70ed2e5dc0bde8b1637f3ee428815781cf480aa23802538457c3cd8a1e2b7820031e2b42308128f643957fe57629bffc9c549a59ca2f6d75aa59497c69e1ee321955c56da1aa4cf9a576b72ad1f1a7ea0dcc175a67b66b67d91ac95ffba4fb53dbde13d37d62a09d59b37488e20db4a3d15d6ff868fc9a95f23be951876f9ace76eeccb42ab35d4b9ee5e719fd4a9f6649a819f95cca9ffd6c9631ae6adbadfdbe35d7d336bbeddc97b2202a85cec61f97aaf9e54ccbca1ff3dbcac70235a34033aa2fcdba7194ded7c2664034887e99594c858e3b7aed98f1e7988c3f3324549569e6437f664832a632f3a1fabeeeefd03834164d69bbefefcc7a2bb5edda7246e2fbd987eadca969add5309899ee2f0c96df566f6522ef4ed36b75a59d9896b6e66ee489d3959ae6ebea4d3fd151df9ad374ac396ffd379bbdd5fc407a06863e91d9ae7dd9971985697d32d18262f59e3f3e54e34e325bb2ccb8ee68b4ea6ebaceccf2d65b26f363a6a1a1da121d1f97bb7de4d6ac54f3436121fba3675787674d3e74d4d966697496df29e3a81998d9ec4b352dce6a3ae6af2d95745baa976efabef92595324f1ad561d3dcd12ad53847a544c719989a95806810ad59e9cb8ce6ff817dcd4f6756a29c9492645e9eb244412d59998d60661a067bb2d6f2ef2ff9e9583e59f3e7ba2d05ca785b0da5c337a09a9f966fd6fc3b303318cc342bd2eccbce2c7f77ebcedcba62a1637e5cc6545b186c46afc59f31131d731547b59dfdf88c3f3e7af75230d8cc9a399ceeb30dfa4c77401bdf5aed4b4ccb16e86737dbbd946c36f536efcfda666b3fd75c5a3033aafab76dd26ad0c537577137bd3381b22df76b8bc3e4c89cfb795abdb7ea7cae74a16399abed33c5b56b7be84ff9a70fbe14a8b65471b61587c3e4d32ea6e99e1e5abe6956bdff6efda4cd5b7fa6f9c4359d0f35eb8d3e79f3e77ea7ebd3cf47767fdb9a92cf65898e527467d22c494bbdbb313ae2ecc524d5fbd69c1d6fba6ea88d9b8eb2ad4e171fe9cf98093749ddf386244562f36ec14d547054cd4ab52ce58d416ddc74dbb94fdae95b7350b66b97be1e95f5c834ed0d496ba41da2c13ae38d6b29d57f061a7a4655d6569f0175869433a09861821faa2d50f93ef43735a30a3372a035bf19db8c29666c60061133723405d259e3dca5b4fc0d822940d082ebf0a59a4661b319bd5689cb1254931215a5a4b17e2e57631778088271acf9a16a7ed96b58195a5051861265cc8037fda1d7d26b6906e60f0fcb3075191c543347a3902187b364cc408600dc69143214400d05f3e5068b6fc903bed50616a020021068a08a3044f02b7a946002d896d21381980fc75c838b18b450830b2118101ae2bd207073772c4b3bb2da1e8bf6606e029dc7a0a08b4d0fc5f02f314e3ffed24e6d2757e3815b7805b4d8c0e3e113f0882ef00037c3cbc019303ace4330a090dd6ae66460fc70778f7a4b55996a98aa32d1c7d9a8f167b773b8af9bce481a4493cc7ce88c9cd16dbfd27476cae66d5a5aa5e1a7291dc58eea789652a4cd34ac292e631ae776e6d6d5047a9cdd77fc793d9b51bc4fbcf301ba38bf083b6d6f7f6aa1e3c5f4d637cb5b6bdef7b7a53a6c858eb9936e7c81a4347dda8d7cf25a283afee84cc378d3abebf8a3f5a1e553d91ad5554777399cf73531ee326b4a12d434a33b13a87c2dbb78f69a6afb43e5890bad741fb9b8f431cd1cdde55a5e4cbea65abf794ffaa479e6708e3e4ddbfb9f3f476b96ce1e87a16654ffec72cd3887fb283aeeaa14b6fdbeb6cea066411e64e91245c7d9d08ce27dab69d68bf5dfc8faf966a1e3cc4a549526252cb2a82625a62a4a50b2a62c4b51485b9ea2a09ab220c99e94929ab6e44e5ac3d706e52fefd9656b5babe1a02f6bdeb4d297aab88b2d6d22eb7daaad3573b94a475dbea9c3572ae85a4c06557a234f4df56b9ccb676e97abce3f55566d2b694dda99a3fa27e862fadabced97b2a60fd5f6b3aed476b1997fea75f84681b48949bc71ced16bbdc49870f937dd19dfb43eb125ad5971b492f74fb376aded5a9386ab369a712d2a4b138d82dac274920f458bd01109926cda7d4f3a54feced479d7abcbf2c5f01d61e9cc34add48c664c672f55f7ec46e29cd24780717fadea9bae99a4444d4e5ab3f4c95f4cd4e4bc9138f72ba92caa9800cf6c637363535fa5a7d5239d475aa5790165bc56e8d20c6e0850e1ae67d44966bb7647d6d296b792b227ef89efe729d997b25bdf24711859696526c639d9ef3771969517d3eac5b4f24f99aee6f2b6adeeff7f5773b2fd78bfb63299aef965f8ea376935ff35cfa96b65fbb5ace697e9fecacacff96b5fcaca8b699f6fba6e2dcbd5cf52a495d2329969da1b89c3a4ec5a9c6c67e672350246221024022fba7ba9f2a730131721e0228b17c1227151e5eeb66bafc597c2fe9e19c685c94554adbe49f16ee2a2888b0cdc9dee5e6a579aeb9b483a8f19870bb798dac26e11e5f4a6eb4db6efe79aa354e31c85edd7b98a93d9aebd67ce651caeac32fd26794fd97e9dc5e97ea58d33677c60c226c783591a16a248410a6e3e8454d0c3bae361a51ed6261e56260f2b081e56ec612de36125808795080feb023cac1c0022a651e4621a486980e0621a615c4c63bbfb4db86347f8c4ccc327c278f804091e3e0183874f14c0c3278cf0f0890478f8c21a1e3e8185874f7ce1e1136578f884093c3c802706c1710de1808b43d47071c81a1789ec7091088f8b4490b84824c945224f2e1209c14522d8452227b848c4051789e4e02211215c249200178960e1229108ecd0218e61c6c5316470718c1c5c1c430817d30071710c03b83846152e8e81c5cb25fee02efef072f1071e2efed0e3e20f485cfca1c8c51facb8f8c316177fa8fd70baf80309eeae73a4021dae1c20e2ceccc51d9c8b3b542eee14c0c51d225cdca9c2c51d0ab8b8f301177748e0e20e1c2ef270177954e0220f1e17798c2ef280b9c8e38a8b3c40709107ce451e23b8c86306177900e1220f285ce491051031bce262287331a472771d56887cc7ca91ef5861f21d2b5c7cc74ae93b56c4b8bb8ef08b91875fa878f8258bbbf31095d81e2a01000f95b8c143258cf05009273c54e20a0f959880874a6cc04325d2f0500939dcfd95138a3aca7051c7085cdce1b9b843c7c51d405cdca1818b3b9ab8bb053f441cb68b38ace0220e3bb88803142ee2e0007767f9d849dabe93b4f39d24169272707642f0c07742a8be1302ce7742d0f94e0825f84e082af84e0835f84e083cf84e0840f84e0848f84e0850dcd8bc5ca22836b9808b4dca70b189085c6c22878b45372e16edb85854c4c5a220178b602e165d71b10804178b6e2e16e55c2c1ac1c5a2165c2c22808b453fb858a4848b450a70b188022e167dc0c522365c34f27604a8c4a804f06da5999a744c213333321009000000931200304024180bc70312c16c9e86ab0314800372a67290521d8aa32849415219c20c0100000000000020981a02a5295a29c7c8d19282f33e01009b2b0265b1c6599152c7f19b177053c43555c0be14b1bf9c5fad8f1a6dea9b6020874aa802915f6811ad2cc131fe698eb2978a280d50a1ef92c4c70a46efe9525d1ac4e81034e235d5337003df3edf50b9ecdfb7fc52a17fd7f4086af45247e6af2f529cfe8e3149cd0db26bd903b6e488f4226b19e01250a3e9a2110a17132954b2729741f1642cb47251420a7add4522169a8e46a998080f4d3c70dbf53a0f36dd9ed1c8f0df14b9ebe397d2791b889d13924dd5ccfa3023e766edd6e5f676fa397900b4def30b070fc2477525eed178d3873c083c285cff25a8309d66ea8a70a0cda27360f908165e7a25aea728e39205ebc3182a9f66d740cdc774053a8fc169e04bd9730ba7ae045646414bb46fa4aab1c482844d99f544e36a4259f867339763fe05898bb9a20a5658329e25a8d15c75f9d01add8f8653879714a8aad6362c8b67c86edf38147d9b817573d83271a1192d830a836cba0e6fdba0230b64a236790111a66f81a5c10025160bf3b1c71baafe84642c27f24d5aa5b18e4a0d42349f848a78a8c5202d01ccbbc8193300d990b5dc5ef3a30dc7d2f8c94a8fb15806e435a5310fe768b2f226898bc334e1510b7a2d8832e01c3ad6a8577600183ffc3dc1aea0c6f80a6ea843ac6c2739af045a022eb631c4714cee200558fa4f71291f4ddc0f7c327e2b8899b4e1cdb3329b898df6cd3ab645eba7a92d95ec51ede37df57e99b801ed5c31978614f484bdf085cf2f9379c6af1120197c6cb5b66bd50fa4cc28e8bc48e48d19411a1545469298215a4902f6e8280b71a16f6ca743e3034371caff99d6ba142902ea7ea1086f52c049b0fc08ee310b25951c59f3b14f485ccc16fa5ff90fd808deeb3a1a08e59eac455db4ab051a1e400c887887a0bfb39a36a4e01da402a3c3a68f6a2efb681b4cecb44ec43a9ebffccc0595e83e47958328886dd0ee15aacd5d04cdba3deaab3a039a5dc52f0f519ce93515b2dc2513e911cc68f85a50fbc8fbb01215320a1f629f5a82146128b840010e72d8235bf803c66df8c2769a9b6728b807c3c830ccbce0954bc0b7a6c81a5479db1e6b6a1c1ab2054f8ddc9786ef7c608c6aac64feca2dc8299441eac3ec4006dee5b87a887605520c18f44abb9208536d5ff3a004775f8087e46a35398e9c9bd99239b8dd985493b305d7bc1dfc36a84680bb83712ea93ac6e77dc19b02843dc5658d2a48c3656cdee3e633a8652e69e51d218c104c913ba5229253f3b5f86fe348a62ac219d79ee8eb07221073e3671eb8a0e38b5b1be86b644f52ea8aede9db96da275c18687ce2625a8eaca81e37b2c1ea06d007a0eb32feb6e9ee7fa8ca87d8a12286ba76c42793dcb7842e72b0161d36b22fad1f79c893a5cfee9a3e5bdf39de13c96632e5a4dfa92d310fe400b42884e1bf8bc7d66877da31a00477e4e039009220603780f1dde98ee7f890819d0022e88a8ae4203cc01a21c1e19541288e058e01e7a016e78c7dd60600bce0e888096c3a436ff7ebe513b3f3a7cb90bd6b244751329e56b5e45f5930781b959a41239a2796118cb91708a260dafb8158d5bc416e3d8ad1a2e8eb9a4695851d5583db437d32eea0098e4efff1c8538d7b75b7b179ec8909901f5c4bd627463240404c14ac09ebb49dfa20f840094e90038886fcde1a7fcc3dc8ba721a727db6f1d62f32803a81673d13991381179cc736790a9155f57f35e2266486d9f7b1bca38de118a5c8eb9098f3c9de038e6af2da766307d48efae1b6e13f86d6ab2585d86dc3276cc781c28cf08a2ec7501620d10b0e2bd1bda1f7c9ec93531806e46d096a4521a3ef7fb00b084a6549150e5f2463db5db0e6da1a1c2d439b35f1c7b7062be2c5a844adeace61be787c05ebca890a291224cf00fbb807edcb6cb25f99ee38d82d40af621a3611f1685c7b2af18bb111591b4158ef6f0f334cb1e205439a8a88f00483b1421695df54f7fe4cb310dbc651faf56b3c6089113f87bc71e8011b0eb24cfeaa13e71c87319ac45469861e8ef0c66dd44eba1cdf368ef2a4a7fb53fee63260d5f839034786a9388b3d635b10174966d94df2d14686954b5e877c1bc53e2f96db90f8712979933cd632179ffc90b229d0bea9c5472297da974a00976f8de68b1da90c550fa7f98ae401e0ad26dfc0612ffaa83cd97de3432c98f8e8840dacedcd49d146b2de82944d8bb8ba11a581bc28573335f946148b0fd5aa7bb9162d183911dadefa20fdbb894b5578203e7524ca6d1869e0296931f0cce558f1431c54de2ce131f31149e4445db510120612a2a2ff227d3811547ca8f1aa21936d55b39b3ce73b42347802869f2287c36e9bd5e58c0b13e5473b2f08361a2e82357501170d42d7b3ad97a92ccde36342c70b4b442b8d351931650afa7340eb4088a34907604de457bc0bd4e77e585d152591cf9b366dc3dd46ba6b64777e2fdfc3e35e71e1b7cecf0730156c9c5c9ab70412c47c1be40be0da9e5dd53f4e357538d3d62570ada641da09a5f071f27c4aa9ee8f295d61b1aa2025a69a62468270ceb18b6def77924bdd6e97ee68d29cddea60a01cf9f529e77fa3498499ccc9dc7059a0bfa99d54fbb93fd9316266891df4f2429432624cb5530787f41792c433c1f2100fa8165b49d4ae8fe60fde9ed641140538a16078310cd2bfc96f5447273741d92b0eba157fccc94a8c22483acc34d222f5df2324e2dea7fb0367e354e8d76565969d2cb84dc91aee3a58d28ecdba617dddd6fe34f64deb4455192ec92b02fc8d757f90caed2538567840a37ab042fd0f91d221e0c22ee41025aa123f5a0a6703855edf03e4ec821f2a06ad04872b03046f0edc776d0035040448dcc7f29277cbb9ad186731b0ef6556859b9da7b5ae7651af672ec568a241597883a16f9a553d031a5426d87534edd71fc0d8c1de4be2c5630cb4781a1f40c770a345bc2e9d3cd23cc154028cf0f34efb0e84beebae9ff904d60ef88098bb49138caf8d30e15e2e8cbf035939a9ca1c1607bb793ad8efb3221f86c5a0e80f85e9ce1b5b36f69acfcb5890cee7b7043de4cd954f378b5c218a1a5cbd28585f7f7b527d303f92c92a5e2b7ca3496ff9cd2fa7fe91b3db65acdcc4df634e483fd35507818e0848bf0c69dde68d580e176f59aa23de20f1021f2eede580327e2963e955e0b57ee1b1bdf42cd74bba8149927cc17d43a69e12d0ae8ae63b550780397835ddaa317434d1eb604918909ad781231636d1140c1b3cfa67530fe761ef9b2a98ea0cde1c51f1769845824feccf0f9fd54f12871cfd878f0780fbf1d60f4ef606df7e0d4e16a36d6439c62a20a8a5cd7014a828e69af6a1800089a0671460b23438acd3796f99864be1b682eb30f5d50e90922a99a35049934a92238c8dce91cff51de3dfd934b783d8ccd7be13bd319551841047369a7d41671cedac2ff1c6da4b0f8922d4a394d442de5fa35c64cc6f8fcd322245a92cfe6a7b5b7fb10e81ef4e587994876fc98b3a2fb7c02863ec020dcd82ecde9650599cf0ff767e152b40d0b1cfd91b5007911aa8834467ab8048eae88771918c100245fb8d2c3a0e110169673a9b96c3fde2ffb930d2019db13224023e8a27f168e14d59166c8183710ead7229bc7a3e6b3f780111488e81897b0aae6c6116883ffc1192c84e6890a92148352b2c5d35466abe150e5bae7c34ccf91726ca13cb2e3f1e1c13af06f3aa7260736b08ef9fec83988549592c14a872ec98e69e05c11ef3e9564a6d90516ad899bd304b88d8b75a480ccd2e1c7a1cfaddc05a3f5ae3427d6079b01ffe349e67495e128abcf630ba66324532bacd578adb9cd99086dc15994f4d1f79a4bd85eb9359e6b0df118198f55d99d841e54f7fca270b7f48e927acf9a7daf36a5cac2ea0974045d4811f97e21a61c4d30177074876aad26316a95eaa476beaad9678bb64a326752da93c346c878c071edbd15f39636dc7da9621a8a6ca71973297c94afa2e5580bb27f5a3e5794f6be7c5dfa2a1f71477a0c5b8da0461d4183de6800c3724a4f023fbdfd1c70b9b7acee58d28cc2ec9c81996e13ad4e09c771ed94503fbe24b97f30215c7f1cc25315cc01b6d1e7bb2b28b8c6994561c4ba5fa605b35f358a0518b14159140c06934cfe69cbf0b86730630812fa559818e81608a55a02af318528ae8fe3d5c405708c9329bd78c36b00e3a2b45b31c4982513dedd629875a026822fc2e54697ac53b636ddb016519463e1924ba9640b02c1e42eace837c8b3892a7c0200d97d54de3ea9cf1c38d6e8b5695142abdafca574dce53086fdaaeb4bbf67690fe105df6319a1aa8d3acacf51c58a8b279faa6e7688613f822b87717733da453eb9ca6b52861d13699bc35d3a4de762515c1f0098218d6b8c82793f899343cde6823fa06f12a2bafe42185f8897a7b8e0f944cd0e510f3486504eb821cebbc22068640a3160d34c41f0976cbb3e710bf957012a322cf32e4e8ce574d1e4a2a404484d2f3ab355d144a703781422113c92238adfef0f48c356e9017455a77464921212c1cf496a528c66333d3c7804435da3d4b6fd8dc197fdb3b2f43908700d5f619ed33ae395a9925361f82a7df1bd1e8b154139c61cd3e8651d57b2cc48ea71a1411f29084c65ca89fff7661d0d2ad61a6de140e82448ca7997c066fec0eaa7b58387d7108a8c1bfafbf54e8bd1299e2608764891abf95f6eb6f7d5c31bff1a49c216b7ce8aa00773547cb592c57ed96ef8320ea846810ca8a5ef45e64ce028663af4fb2586f22cd354a86750cd9bee1b345ecb213e36ca183b3b538b928a54cddf5484742e46e920ccc42438580f71cb8cc9410e884c1e95191796b0ff55f07024941630d6ed2450a90c5cb8d3dbfc41b8e38126148635e3460901c2e9d2e3dcf22f3029c1b01a6fa8305524dbc8b9f52c3a87ceaeb3ed09a74221ecbd19fcc6e4c21d92855e936a902aa6a724cc817c08e5668ac0c7c10c2bc4278d8e57ab0c28094ba3ac20bb5692f4b7fb35c30aad25a952ebac0fd084cdc29a499d1b74dc2472f23089ea343465a12094566a9ae347fd5f38a78b31b62ad89ead323a884983d1bcd97328fc3d08081662bcbf0c021e7594624140058de19c854f9fc248aa069123e25218884fa4905dc1018f523c8e05c9ccc241f143a17b214d4a7099d7cd4b381c603b9cc94895d58970422c182626dc44197544388cd6b92a9b0612f683084a53b114c91094b2e5dedb992f2bf4de0005bf6deb0f0bdc143b9757f720778c692b474cb985d1022d2d5e7c9b639911bec47134fb36a3160449ff29823dec41d34c035476cc4406363d480de3e12220242b653421a15a5ed521f3d89e95da810e47e87a356a9c0837f19d72c092b2912b33a7bbfef0c6064828675706d9994ab3ae7dc235d9cafb852356300e951c8b662b1719382a78dd900856fb9d6b6a59557f38f7516ad15465e469e3ebb1707c97bfb060e48e71b39e2f5173985b27242d4c12a00d755a50f7336bd665bc125e8a756faede236086949c3d5ec911ea6a0b6dfd16e4fb2e4050686c38764a35275a0506f65a920254c173243675610d5b5e36404ec005e93e43a3482972e500fc9ffe124a0133690f08182e830069ca1310c66bf2dd407e8160034ec5098caab0c84a1297dd45d59d388093e9710b6fef01ec03556c745ebb103c72a805f058bad4de22772743a34a6d4c4d3b8a1116c7d4c06229ff4a5fb9d7e28dae5b4915c2268c0b9e8632a5bbe78913f569325ad9b329b6410a3cac52b8927548bdc64d00652796ede21570f3f2fc5c0cee8c0a2c2a3f90b051a11d7812b1d30b1bf8d544e381978b903f008cdbf3a0d13008bd1d80b0bc40cca00ee27d2fdf56a677b1bb9e757483e09a2df3de737c18286dd7813efba4d9525309b54d313ca9fc01779acf153291250225212a284eb69e5b521a11fa2ac38458338725ba40ba2dd9d7b7ecaf0efedeed42c03007458ca80f6185db70bf1d59b0faf906fd07a821fdddd4189a1cd360cf76fe4d8a46823d16726e2715b68c6c74f826cbec7b893f2ea5f48abf73109c2dd111cedb1816510885154d17d0935d62bde262898d45c5c1265a7bca14ac19d5d1a5ea251592828a246d17f9d90cb99ab4626480cc614a8812004f88ebe8849a830f6c29d754bfa2c732f14f3557f4060c2a4308b93536304d19626656af1622784cf0e78ee96bef16c465465c3d315e9055dfd49497c12f6228da394f56d95bc0f0644260eabdc14bf0a7ea4142b713113541880880405656484c378b00ea9bce23bfe17c4116ac23c0d8be3ae81138d83a533d45f311d0a10f8df7813dd3ddedae798d7243deb938ff57541e3625036effd654d855f8e459b31b83bcd6b08a6f3946899e113c9bd1f119318063906d6e2f0b3ae2bc9246e436073a20b3061e223cba9c51d8d7f7ef76e02e01e14faed7d77e2cc5652496d850520e96f86ccd3df7a03a946416e15e72de9fd83dc605516721de3767af2f9e518067105f4f87bb4572a7bf328fd390f1ed2b3ee51894deddc090188a1bcc2f363b2bb2f3d307254c0d8243056c789c395dcb1562c8b4addb53942970d4da5fae223045644c5fc6dd31697d648f048362059b5da8dfc6f652754ada18af960e30de9ca989bbd83c97d301256b37c92ee23bec863d9a7f9b07e28fc754c189a50bada349e56f95e326d75066dde76b855e16f792ed8c0178aa992cbbf7d0b14494d7e85ee60e9d05615d92c0e4b16f6ec8d9afdf610bf311c0a31f23db028c46296de47355db2653b57562f35a8e905c19c9e126a43a0e07adf810a5d66a12c9623ebec70a1d69a5ece3edab920b6360099a9df2f2088a1dbd2c8e0dcc9d0fd5e5949ad024d0d82c402a506ab8fc4d25290c5f20548818bf6683d12761d566adc07b26a6231f39ec1c5b1e26af7d594b17313101fa188fe718b009677dae0c8d53ae3e04142da5f6d3bd4076c54f3775c792d073cd84da7d7025903c5b908cac3456dc8c4a7c60a16af90159fd6ea02f0744b2bc702f1ea05646683a67648c7981da39354f4d258abc3aaee0abb458e39352c0e449282c57033d189305ab766fe04f79c35e02dba19dfb56fc3e6a75b3315c59430baa303324c0ccd8317482ca5842d23251bcbff6fe5b585b8762c5b906cbd60b16e0ca0ad2a837b7fdd86047b63e1b239fe2267bd4b61eddd6bd0da6d5c830a82d1035d1a30d9fe73cac1120e86f1fe8948764b9e73985de4b542c8ba75b98b275ca4878ca9025d8a3b40299849f41b7f01dd3f456c11fc919721b9c06c0dde4b6d9a22ad7abd2da1e99729bb383bef075e74ee91e41f76695a467f1596ca92900b6d3064edd5d3f33a7805935c02d98ea99efc922966d0d2d7bd6bf87fda18937316d5e5b7c73ef4978c34e4ad41b96fd4beba2507296ead3a778bfef7e1b4e1be6dc856dc3d9102304dfe139a2fa8680e5de887d3cac6418ab65f51f03b3e7c47f57320e3ea2a16d5b660270189cd275fea9d6386a7d5bf491c161bc28ec2f3663446fd0e4601e832257b976a08b631a4df8c9c4e6278c44038ab781e02ab1a43a91bfc2e6760464cea889a51f1970bbc07588a9908a7af5807963306ad4a57cbe6864d5d85e2598b9c8e5223e1ca1a1522f338edd78842ebc824699e8697f1f708252b028dfc4c7165e8a56b0f31da73ab71eb160569f8a5b71d8c101e79754d5d26230d80ab5d7a005ecdfdcca1c203b7f977dac8744901efc6069cb10674d2884baf10111157f76a10c3f623bff044a0d7f271b4d4e12c3590628806a43f3c2a88a87f84e9949369ccdbaf68a879740cf6f38e18b8e5247558f734a9ac52ae94d6fa159bcf5a3d193898c4349298146b8ade3cee785f7691027815cfa0690f7751e856517e1ad27ecb6fc44c4f48ccb1e6fe45b00b556f1f8170afddc15f31bca3cf78a23d8569ec74f8b2022f0700f7a62328a11945163121b79decdc5156ddb05e50e01c3aef189b61d1157386d4049098b5b94f04cb4046038145a6ac3fc1d144bf9877d9da82955461304ef72d9cc75ed5d81013f92461907c8979e11cb2f301250e0d1a05dbd317312b6711f344571ec461a3f7455af61413600390b751107c90c1f1affb88c68d3481071dec063cbca549223b6d34a1631fe1d2ee644cde5af17a06352bfe0fde4d7b2da0e3daf5ee2fa07f196c15974897bff81d61e435d489b27d2af986be6e297564e520c167617d323e94d1c6de1e859962a4b32074a63d8c8046fba8e3eccbde89c8c65a8fce93abf3db8bf2dd82a68f38744cd98c663a6c1e643b47b8ced4e8382f4f9232ef24801e6f0be047252cda4abb5d78bbba4145b2c6dd810fba1ebdd891ac38ecb7441ef62625bc5c86ef723965af821210f2ac7783e20ccff44fc0d60b258be4f3078499040b033918504eccfd647ca4f410a1c7eddc080e3421f4711933928d5af62f489dc09087393bdff1431ae54943b3d88a8882e9b1292ccbc506384b963915fc1610a1ecd41d36504b7cb8a14cd5ddbcedc487fc7600ee88249eea728ac6b8b78fe187aa05e8ed8216f9d107452a1cc0f05c0483074c5ff949301f9fe3c3942b6b80cd55ae5e1c7e18401809a5ce6b1ff47737540aadb96f106f7691e931709ebda44839852ef403659d1583f5390e5cf83280e0be6ee837d6b7566c919c95696ad77aeb91301587bab76b564f3088cea47caa69794445f5c2f74e4d1a034c3661a32ec8270d2d45b7d9bccc53204e57eb8874b932d0c4933535106e0e10593c95e13bbf42342209fe73ada9948470098aedf8ed810e607adfa7a7b37a25a17ec5dacf3fa4525d3f1a029b7ac08b64068cbcded6d7266ee2a550e8df04a1561e3ea2b1d9c0e7f1782f3838bb49441119ed74bfa7702e54a88354999ddd77af9325e073465fd0628a627dc0159a7391da9c322a6b15d802af107069d5ef217338767259adb17310c4cdaf9913d82d395dc7e827fcd0d27c493887247a9cc9a157c373f8ad9d76adfb503c03e44a795f499b823f7ff69b9c479c23a7f11f776436915cf735b96f07b2d63a52d7bc834f581db62c36a43346d7d4218025550935872da447019bc06232b34c1f710005988010cdec2eea65df145025e2c6b55c50b77a467b91901ad36056b203372be10fc682d64d7bc7fef30cfc0c0f9d20dbc14aef366739e3f9677c6e3c00c371de4e70dfff9369a230c530db6293c4fdfabd16895bfd64b44f703e9eefd42f8d3f165140316b529244787d0f11e321e4d840af54b0e2de66df5ed6eeff61b9825894d7dab9e9ef31b2a5b3afdbbd81e9ea7517154725317107ae2b530838061a34f0c546a1325cda3658f00fd7858e0c3a476796434d16f057d1188cc3dcc9b0341b253a19a2e8965e3f06f61ca9d3e8c9ee6c084ff5180536f3052eb38543076843e08fee0d3f62bb2d7bd3baeb27528bda8f39c927b2b2bfffcb9df83c96302ed5e82c4342e42cd9f734b8318aa69be2e9e201d47d78779840c179c8ec37a76d750e09dfe7093674021b4f55b708cff85a11388254d88830d4e6d1e8f63ac43b2610f483ad4bf95309d47e3583825bd10104a1ba3b5ce830e8c5808930ea274284c0941304ab6509c64e90f9aa8d8382d3c3bdc88ea2fd9486e38c93772665d353d2426e32e69778abbe50a342174d4b25ec58bfe550f375ca786e6c8f3d5661a1339ad41c227f8ca18f476bc457257d6ad6b6a9fcc564c6dd50aab81b2962ff5e3d034e1447059d00c4fa5d4936ca004aedec2fa03259317e05daa1e5d04b1f77063a4b314a937c0d04426cd991dc05f68dc37f99f151c6cd4ff7fab42ada690df2332724dc168ce9c5d33b6ef201b358b764b37c51f6ffaf884695caca94f556087d26e82fff1ba2434af893b9052aea6fd1d37f9cc490268535e6064f07b7682dc8f709b5bbab8867e940df8fadd940a8865de41ed839a63290e35dd577dc2a89ac58824e8cb9ce37a64243fe5447b68ec3a56a96202232e77196bee9f3a8db17f7b3854dcb871440b43855bce9d6e1fdc9485f59b2b33f8a8e1f8a8706aba83fc199317b8fbacb1f8b278c6a92558ab7b3c005a71c22fcdc766d71416c50e7e5905a02b4b90ed6350f22cd012007738df16b0d473c31b4676dc1f4a837d15993193be17cded6e673922f043bd2b455ce4807ee8e2ad64cbc45693182239433a83d44a8648120c66247c7a530c23b4c478600878b14c74686193f5382e921ed7c1d5b97d1bda96c1e2e852b5be654df1ff2a3ea0a84efee9c70b20909697a2e2a6ebb2200de5e82e8600b5b39261e9ac22b41706a02b0d371c344ed7e665bcf55dbfba1a78df805f1431059b499fcc9bbe0d835470bcc224458a89bdaefb2592531535f31b61ae10904f533be9890e0995d93590fbb4cf5dad08d3c16cf2a8c5b3eaf51b19e3b66331f55a2321e1158f985955991b794ce182d52a4fc450bf54ef735eb7c7d84f256979b6cb24b527877cc01ed758ae28850e3c514fbd9848f15135ae7feb59470336d008348c7b7f293611f6d3c439060297ae29016f12085057487388e8dc333b500d59a0cff3f2f3cf5ebcd07ab7414cabdf15406dd99e22c629cea505742622f121a21d679a40b559143edd23041c6866d33df1a1460b79853ee318666455ca8abe60c2a606b3a13f3be46d15d59ccbe4db48fbcd19ba517b3e9dec272fa6b200154117274da09a43d9ccc93730626ef9a6a40b89449660c03f8285bd03f16652884116e02b876ed62e183f5789a580763efd60fa8feb4aa6ada391b93c868089b4658c8a795fca8e4df7c20a5ec6bce3e63953df8a0a5b2593690d0f061fb9b0e8a13d4626ba5ce5f5a2a5a120c4e9f601762068c31295ac0c2206e6090f3758f163171fef3f1842c8e48ad21118ed83fca30a53388987fd77bfbf0461ca7be92fe4c77ddd27d3e381a87a8b3f93258be15e43481f43975df687af40b743d6c5e87766cec57a0d946a6f46fe9118f6cdeb68fd1650bc74948325fdb5de23901345b6d7958747c262e79249b88b3c423d5eabf767a3fcd6ed80060c1759707d24323f41fab51405edac29ed4ee103bf90c494c6ea381954a2f0c268f69aa394808472e0f5c64bccdecc7b87e8fc34a6cb81ea685140ace3d0eb36cb8f4692786da468aa84572b06655b1d5d488f4c35c958def19a31f7a3aea1fe5e3376f8238b79656b54a668808c7f043e42d4209f85a9d95029702e5ddc9f5ec38e4b09f8baa002809855e6c21c15883c8da6b95acbb99023ed0276975052022109844d216872252b3bf3a2dbac0b2d46deb08fad4fbde0d980c740147fa22b8dc88c8ac26ea98bae55e6215caad98a84646105982c15b879c83c5b6b6a8faaa4010f0e11244c8125e10aa0d6aa80d2b0c5bed83b554f813bf95ed2e54e6fd845ac6106b32c1921e06274280897936a262bf86f8634b023982f166a00a54fb4c3a23609327e2c02c00021fc19350fed96e111fa48912fb2a250b2f0f6c850fd698ef14c7ee9e764451e50ffdf2e17cf86cb1d4bfd56929639387e1459e3f3e4dcf0c2e0f7af233b0c90ce49f0a3d8b26b8ae43c4e2ddc4e59e3f9f27c759afc68c58956d3172c0967a3413a231430834807f85f734459b8552b33b45096803bcad2a1e04079fff6984667d0581ba0221032500c173da12f621606b564b00e5f5f57fa64cf0ed0c350b1357aacff45c35925f29476bb652b8fb606104c07245fa575a5fd00801a03361673721af9f2a0031cc4510a6488b910d985fe560062a65f8833277ecd0a9baeddec616cc5dd8334fd1778dcf4f9b66e71e69c96510f3cf0ee848dbd73d327092640187220e451df2da4c531a1022848296cedf69fcd50f6bab042bab36c68ddd0843d2612ee7c92fb517ac3b1ab37fb99c57d4bcc02d743d985380921cd4d8b0a78063026c720af59e05192c973d36463a5561db939423df2fc5999e89e863538df06fdd8a42fba346be291ba10b16b35a14ca539db0b4a0317a9527aafc05c147bf80f0f39387bd40b950c6b94e84216867f98e2c59e5b53e8c42141a0eb32016e1cb866a25451a0e33444f390a87babfbbc1784f54092a41685c0e78eb9d8413eacc21ffda28365bab4dc0023aa64e725a35d1698995aab2f268dc0f870650701717151bd860b4f962273e50936f6f2bc733a8091e4583d93da75b194b724b78146057eacac9c35f93df546c7e14bf3dde6464f85859d046faa98a437e8a136e10d0df5b95365939fe61038ca788038162c12053a60223e8cec033d986c11e02b17a56e5ed2d9cd7e6d0b45fefefe86a21af0a9f0e50e7afc8ecbafbf25c53f88264ceb4650790abc7b6a5f7cfdc8ed53643e16586f4125ca3cf7af1c88a9acc19e2951c78d72f2af47020c5b600cd8fac92f8a22cf9a270caadc88d1663a63e3289f304f3dffc26f1ee79af36ee4d6d5a5f05fe6d75ff65473d26386727715ca204da7eecc2453a25101afc33901258cea2a825223368c13db01a4135105899ee2a4a0c0b41b70cf2e4cc974c380401f49c30ea7b270aa0d922db7c72ef27ffd4c8bf2a10c9958422f7cbc2a7b94d0439d6a17157284c1e6725a338d38c1ffa4f6ceaba03c1774dbe7a3e0bc283c9b2e44c94ca1d16f1b7ed85cb1abb280b6bd82efb3020671b682e071e8cff8f38afdc68ed8470712fea2b908eab5433159f53314f28869f8751afb970bee9bb769db23d8f3b06a392e7bf5050adcf841c8ac1f702fe0ffc97e3a8ea77879e991765c2a20d19628dc69f6782c1d23ccd5f75ce1c8d81b4694894d56f30613ede0cb37262ffd109043945b9e6facc2238a5cc47f61ffa5ccd73988fa83629c6cac00cc7fb35728253405745c91a11380e476bd01618540e8443c3301ce825ee418ddcef67f09d70bc24f44b826f41db1c6698cfd4b8a046bea4450f0891565ec3b7efc550d01cbc8f300cd2dd9ce388b43a3fe94b0e85816c4b92f8c33f2b762a8521d962dece5df34e99a3ae686aea1f168d201c65c5cd273962ef517ad83c8cf6ea259c75b28299f3d9e9088847dd365240d0c0734b6bd91231d00b3f5776475ce9265a86ca4c13d747597ccc9dd0da897b14a3c5e46227d697a7ec1597d018b325e8fc93e14d1a2de9f4ff22066d7ebb8318713e3f4fd977f9ffe94b8c5305c8a2014fa309fa3f7e410d48b954e88fcff301ae85e1ba3e855458789d3b197495d069dcbe936324c46a5cf12507e2bebfcb98329c3f8f941bd2d8878f47438c00d5f879db370569e0f13740d3e1d798fde52a9a633af5e5168ffc88013dd2af1d397cc8408672a1ada8905a9d0d8f43412eff5a893fdb6a653d768199ff98020dda889ee9081c043db59e09e789622ac08b99c87d03407fa4bb6de3a7579a5d756014a710d591b516df34501135fa3195bcc6d6b198c86e44f54ba4738af34003c85ea49be5f70bc3f1c95296b6e049b8b88b7650b11665de106ceb6fb48ba77e81f07e0bd69a1a30f4d12278900db6d4cbed0a950addbfed611966407a91e0b7461c88332bb0225c2905ea7d2552b2727ac332268ad8038afd2d9685fa15bc6257f25c9423e3aa1c4b4b05db0f7b122599f2d4aa430957accbbe8a243246c78082da2211fa9073155e6e3e1bbd688058941d131c0e71cca84b24d41a9ce4476a2e290b02bb835e86f4cebe786a56429d71619dee7a0c04930af14e4bc4bf45dbb8b19e0a057e0d17469b566f450afb6dad06ad08cde0dd414c67b49bdd490925af05e1d5c08ca5d518957ce39354cfe2975a2803b6e949bd61ab16cd77db6a76c1579dac5e7a0c17165f7641277bf11b86ed5705bb66f1d53b2f40fbce1f4b3e55f8b0817c7125e4618c93b9469e8609fa82ae220e50c32b4322f0ace8bc800167498234a4633da9a717111f984f0719b405b6fe8a3ea66b181591baf4e6dd4187ee0555fddb0100484252ea8c8711728073c74dd47b45748edd9c0cb6ba028f79cab38d5c97d478745e73ee64b9a52c52ab1657a56c75cd312a9df548e5fb084b7db3585e0f0756415cae17b10c3060eb91889d66d84eb365c658c16d856991a33b2d26cae66a0e1367528297d40c93e77ec10425463c878289141df2661ad374005698e2544870302e0655a32f45007fa69cb3499964240c02658fe3735d4907a8cbfd17daa80e3afd991cad35748cd248ed4a973d3c74e716215833df7f4d130283269a48c9e662669c56e964be558c0d2d7bdddbd4734880e341acc2a2a2fc26f1bff619414ece0b6c247799d31bc6ad8cd7af42013d99eaf4cf7341580c909502559ebeed4463233df5606c6e8e169c3edf2a5410cbb0d13b5ebf02ddb823d7abf05e932e93dbee65c6aebef06db71442b8c1c4b0f1ac6098d32d017a05d3cdd837f7ffb335020fe2db8d0fd4073af82a3e40213b5421f9700fa50f747603a8e5fb7f82da1ed61cdf3d6a57bf1efe4e01f40ced79ba5426ce7ab5bd84aa783ff5623453afbf19028615c9610b09e4813b39bc662dde8d5f5f504cf7cf2b459a7f30c2ac81272904cd1ebe600ab92c0bd12b2883eb7164b4d505b2f27838b1d66398d9a10eeb9bd212736d555abae41bb441885f7a070a6ec6b68a951b37bc7f63eada6ffe696e460ced8d05e2bd6ec8a8186409e63b762c2f236e9e9c2b717e319d33a5c6c172d0e36b2baf0c677b868039bef68558d0ea381006215d09174a586def6f309a5d7d209f3ffe1685938043bcc2ca972ec7d4a1e418e706da36a1dbafdd4cbbc0b187b936af694f44962c38d8ffb3a8386dd50b44ac7dc2c7298cbf2219d94cd18019df32477eeb8f7b62dfe99f268b8616e7e7577db0c83b93f2771025280e86ecdd9ac94e940e99141778a53deeef584b99a7eda0e0def498a4bb9670fe149a97305e9c804055025720ca0821082141bec4589030148c093200d5ccd98e49409ce910b29b1821af64a1d473c42e17fa713576cb7a620ee32b3fdcfe3c3bb38c93090c77370547a5e330f368bcbe8d46e54918085506bd7c6ec03db423a7d60fe0db740796d211ecb51d640aaf1da43a753c7ba4d14666da9bdccee1b4379881776473bd994f762fcb4f211d0af5a3599f657408536ffafe15f666b3a4db544744e70f22fd63f446d3a375a77782aa2fae9c93db612bbf508e0212dc1025fd5b93f5865bdfb7fc48b7193399ce21dc97e1b3e839f39cb72d824337b1c926643e87ce835b1cff22dceb4a87874dc790df12b5bbd334f5a471b3ed70c9d44fc673156b727256c3ee0b961977936f068878fde313fb0e1e54bce3085ce62ab3cb4037bb3d57f51def027acc4c8ec5a2863d1fcededb5b38b2d94c322176edb135fbbc966f13fe2aa3e4eb4497df8684f75affc4765eb386969828de234775d3d9f203c60f81829f41cd66a1f1e523f53c702a5fe2e4d9ca33d022fd2bc09d2a517772cf978f3edb8b107ce37a00cd5fa31b67e7bc7a6a6fc1cf48fed7470b5d70d4c68fe4dde08dd4533bbfbc28bd725c3176663e1319e90792078e6b7b6672cf569f8bcd5603749053dec3b0c60ba9861f38cef523974018f38c52f7d7c3e2fae39151f5eedc5efc1b78916ff651cff13cce3da58b657774e2408ee20a74431bcd75ada8c51236e86e0c89f600d62fc1c0d81e6b983b8147fb5592c3401f0ec6a17be3969ba705785e6890c735dda9791b9d3115ebdbb77e13f13e5cd81345aed5d5d9a75ddf41ee8e17c48f9ef3c7e98c8ea57e24983283b868b6d44683ca8bc3bb347f4f6964887dbaf1aad183f2038ea4f6972ef2db371a470c8f40700ba284ed93dc75b7541c299694cdc976beab9b422a9b147a1cdeb716a26bead34ffaa7655379532637ce0aa6ef5905f9a5b229947a10c60d5efe6b51c0a5913cd40376036200da732f84f50952d1b507adbbfa489f58d49275e084cc165a62d3e3f7753a1dd2baab16536116cf8d9a73be3957498c471f407656b3e80a730a3ce280b2fe5f88242cf636e176dab073e0fae4e3e0eff8cc41b097b8225706a2ed68b355626c1c26f2f16bee2dd8f55080fdbfcab60d43d0a5683984e2d05eb88a773ec27d18bdaf3606f1d6eb9bfaf4ed973b40ce05236283cc90e50c98f0f94ce62675f0bef5d522441e03c0633a3e59aa681778b8c14672e7714886313a55ffd32dd99f9b9e7155d99a052b48b7441117581af151929d5c380ae0fa916596c716889514e6925ca2c2d739df4d4d8186d4daefef2d5add409eb980ff670166d286ffbcedff087ef85a2971f3bbf96ba315f9d50bac0c7fee089107e0cfa54abcfd8bd2092baff6ed93b621204b8edf9f3b39adde28cfca3bdcf40b2d06de1b1efe726a4d878171acd11f96c5f4d46ab9da20ec2040fc42a6d3d8ed1a7fe9821dedf2929e3c10f5590510699a2328a046d545c71d1b8aa9a953c046a8bca0115c3daf4707caaaede9c552515ecfb40e7690a7bcd10d70b435545248b87b957a74d8c4f1320c7bfdba0453ee320ad832b2a9b3d9da7215b584ad709469a89ad272663efb4b54c9b1ede8cd8977e7d9e3f581caac677e4189f441ea59f96bea003f8f7a5b22838e38786d7fab8b2a40c8ea29801637f7915ee6731535eee47acf4a88646274d3280edbb8e27706b9c92550e848662ec0daff0b1c5b274765223d376061f2328c817b6bc51c1115e809ed41e1edcd1e63c2c2a14dade148688a15b881ce83df9b4ab7d0149a3c8e2305f02fa4f8ef2e1b5492a8f97a0f82728a0c7bbf0cbfa8dcb4882658b950fda246fd78f77bbe7f1e626492f60ab6da1a02192bd4c814121cdf169af1247bcb0e4eb57280993ffad34213398eef69e547ce6a5fbb643fc658b618eabf3898b37d7a729168068c786049b9ababbbd4d964eb22adc3db0c78c514eb6360402687ac02ad42644b14d07da89f1d07f101f3a42ef5f5e02025ee41e4bbf0031ef283323d2257b3ef8eb6ab03c2eac79a2387126d5b9f4b1c8448131c169cbf3d9f814e5881991d6981750d7dbb5df57ed15da96d5b333a8a1f44d56b0b4325556c44f56111a95e193b7c713f21de7bf791cd82f09e0118b0d22132ff9a6ab406a27c82afc57678c33f41a36c019c952e4a8e0696a769bc0416667b7a839d7501864fa622639e645c764a1b9609f371cb2e18e59fbcbfe1f94b2c1dd66e62038a4188247a2d3d999fc99414b307c83d8121a80364597fb125187484e676fd793e69f9b9f93b480353b8335d7f7d8d3af8319e5ec694568e83799b2ffa553f2b8dd2ba1606a53bbab07a16b2d99431355320e81004f18c73d851504a19764c0fb9e00d860ef5ba38051f6cf9c5e3a9155b5e5fd240463cec544eeaa23f5a3b033faf9c05f2efe42f78ca17c3d63ee769c74b0dbcc8cbb10b199d4b250dcb15e1a6aa0f0772da15690f08097ef239b7492d8a1f698debb94e03cdb3c28369afa037149f8ef4bbba748bf3c47542a97cc6bee1f9182dc959e4a1d1f6cad492c8ea5a8509a0360984b01ccdd6650f8e56328c6b3ffc0c0da123e321fa79e017fd1ed75d84c446df576aa241e70dfaf73dcf8708e62bfb84ae18661daad9d9689e9c2aaf5c341b8a861072cd961f8024576615767c78f70bc63139d4f19f86e7adc0ec0c2339821441b74b9af4de5c1a93056140e5c3bac990e692a75b941b36a33404a069ef2a30db953041beed4c08f4da8046696574d7e16ec20792e87c885034ebc1c272bf7f70b5b3dbf0b6f4aec9b742f9ff569765300c9489192f01a9236798e51abeac7c5cc7aaccf4cfd142ccfdfb37ee800330ab03fe8e5df92b2c2ebf768a463040f8d234759f75f0f96b6555e161be384229cd65450961bcbc5f3ba0196283b1a2b7bc33312d396ef2466b515fdd3ae713bc7a5ea1a7b3f7e8657112109210fec788e5fd705799f8fa0b286c401ac754392d14e3eada14edf87ec881d5fc1e90e3b097a272a56001773c1b111003232aa31d44491e80d1424dc182998d79c3387b1d98e63fb804d8ac59a41b97261b2ca373ca784ab9186e9ac0cb6cffef6e283384d810e68afa646a1d528ded0da549e686940755a125b2f6488ef2a3a1d16628a31ba48a9d2788c519956598e695a983fc583011f136f64794719e7e11407e40d0c7362048550f8f2c49e4130373a2016ebda8eade3804f73c874fcd4d53a686ac7e2545c803340477034d120ef7b369b245221e924194d7f587bf62db6767f45df9613ff3363510db929f8aad83befc91e50335bb13dc8c3bc3baed84e10eed5e8d20c8d099ea33e7a79819e237ea46cb6c090cb120e8c62a59a9bafc45c69843d3f0e7cd6e22779455f2fef10f2a367abc72631e57084d20956a8217c0e0a97792105d830b85038883b0ed2d4886650afa0582e16b677c4267ba46bc3571ed7491a2ccb28621892af552c4425ad933d443e878ceaa7d1b70e16e0ddb0c78c10c63602d804ca208e3b348a987e44d36aae5f02c0a4a505ee5ca9d8c8bd5c631ba0ef37f4383aac774b6031d0fc0baac33b83e95b1854fdd261e0c45cf297ad9c931e4c04100a25b4289dc5959fd48ccbd4f426e0f8f7abbe16d32399f0a1c6325d3b6cda2ce53c73bb7f641542b0ef8bd7cbcb39c4c81831c987d7ab380b40e91813c83c561f098c6fcf7f0e97614476c763f0950a7448324e155e76d4c6f4b685583befd23575fb8684434e26c0edc04eedbfe6a8bf2e9a3b1307f29230005559742689b1aa1d6414d5b422e0c86332a9c5a857c6f1a8c5b911c85018d6b36ec6b5c83aa75f9a90c6c7c025e88d7081adceca07ab1613cb4611869e1d622f3b33d0a5d166fc4c3b4f7b42ec46b76c1e34305359f33268d43b3db5ff2800889d8f43b90380b22f19c07c7c38f199d859f41e470d4501c5e29c51dc9153b76964a2cf7c054d360e472260a363f5dc859ef68eddd7e9ec5c1cb127396a517be0b18370ee509558817a622035347efdb1935ea02cb9e654e1c1ecb08eafa78e2287c60c9f4a946be43f7d14adf8c303315983a86d7f4e4c1588a48064eb030cc05c2b66eaa3af6aa51b8f32e92f2e6b5fc55a2ead9fa72138e2c547cc18ab96ddf1794fd0bfe13306123fe54476b906d5423cd05f0dd72b90841afaa149861801cd2cfc0895d1bf2d0a2e65453a2d2ced8682e78e3d8a76255da354846227be9eb18a98b346ad7266fad0b70c9a1f7cca00484c79cbc383ae39c3c4aa1ea7992ae0e40b0c94718b95171c0c9c00273eaa24f81aa11a341e6210048bcaccb07b8c73b735ee8dbd0796706df803e2a5bb8b825991cc2dd4da543c110b6ddce16dcd2b81411f4f1a3b5f5dd1e5f7e8613e14dccdb32c215230d72a949b41e5eed74c1e2f330bc812cdb81211a5bc16b02d97a547bb3d5dc3b1521f1c308cc071144d6d6195c460c0080c54f561fdf70a5607f8a7090edab11e2dbdc60dad6d8ba940bd975438dbc1b6c0b595d1538ebae52b3860f569ea786b75cb7e4067754b2479d1ccbf9886dc2da6cfa6080d14efa3dd4a952d6fef83643ec807b383a9d65540e7f0252f8456e1095527ce440565152fdc2bae1bf1da201a4d2905021e33ac0692e300ce5acdc4cd316cf9296506fc0c3d1d9d1d0c9f936d9c0bbe7515309ce20411ef4ab77dfad988c38d96c74b1f0efab33fcabf7eba317c929b71704171e13a108714b4f45e09cc02406f961697747667d5db00adf870a115ad4366c96bd72bd009f6a1a194d205efe8adabda68d96a526d1d242856f28d6ba70b9fb7142f2a15ca1201ba572d6f61da6836c2071535accc9ffbbff37b71e5ee5e5edee8c941ec8482ce04f4c7fdafab9978fd0763d32888e9803641e18e78dafc0f89791dd08f4764140ddd6cf2855cd408c6dbbff117ecd2e82c05444805e57f703ac8222720321cbb4743efe56a76ccecfc226e4b287f75a0e58209f974a5da6a4e5d0eac8c74957dac09960ebb102b2b05ed6738adb4c24c14b24ecc2da436df960103bdc5d2d39e5d032fe162d205b7761cd49e966b83118f74bbf010cef8286790db3396ee24ade17720f2e2670b2083e1a069941b48de58a1872ab0116929b5bf1fcc9cbdfcb1d61f22a0634d91f48c056184f9c99a92d47c840469d32dca7c0bae9572c9d082604c761f0af30c1a45689de4dd4482653162324454e0d226407e1b8ec08d57ea9abe7eb3af3d5768c1967e091af01da1edb98c8ee581a6a2d3434328b5aecb9c66bff89b60d988ff9fbc9488e514e828fa6fcf1cf219f3d49ccf2805c09be8fe3a3da368f5319d4d16725733f812ee8b187621449b8a1ddacd7039d180022692aa95ada864c78994f97fc7220eb1ee1c762dc9e4910859c5d5fe7e133bab771740a063f9f71ac03d32c138b13d2872d569b58393b6cc5734201ca4a6820739df66ff041944444f4bee59ac051a33610f49f9ec1e857b61eea2ef39eb73425aaa73a69ff871be0d795f9efa9d52b7a8d40dd1cb2609f1e3b718c531f416de2d142ebede5edeedf53586e907aef3a54b333579c6b677ee1f6ea111aa616ac05d6892c9234c4f348de55abe4633f1ffd9fe1b55b59599d2f0eadef785cb0d419779b2e652d1ed6bdef3a9d57e2f4b98672ad88a3583a936e38580fc2dcd0ef8311f79ebf607c8d611d9554674dad6c27e3c05d8d318a1ce1f73188d9d327b10fce1a709c2368b6e1049d0bed51e2913dbc2de7d348a777449a5256cd1158d40ffbdbacd222073591f572df5f1ef1239254b17e50f0b7b0e88fef73a091f732733cc95d69d319241a70422e1a6525239ec872f0bf670b7337f5f785c8efad9636a666cc0046902eae8eb0e95d6e40f2c023d5a405726a77d1a7ad3ee9d6344ab4b48c2bd441c1b83410bcbf7da3a89fe3a26bdb079c9199a4067c9616c411af9cd97309b7122ef1e1fc7590268bda4837bff7b4e4d9a403b0cf78bd09ea63d5ae74df5954ea57d6d403cde7415d33cf365f921354f7243645b9de900480f177f983df3e6949b79668679552d1870c5968ab79bf751b1337c6eae8089ba8262367c4867d8ebcbfc3dc470f673408da133b67ea51bb93ea11abccd5f9e7735312454f604c2a692578ad619e8ba324dc5e849a3c8ab93c8466f0ff22caf67bb8b03f743af0e5830747c67be40c9c28ea584d52f69a869dc0dc14516a9a2b679244b5b70c1f186443f3257b6d146be78958decf68aa1b9d2de88bc908746c2d65a31a02dfa4ce02af64e38a295d83ecc49834e2f22df173c107213cd41f95e3e0453a6d536599b52f11941ef547b181e6136390ea8e8d4824321dac7fe143211af79e4903846767ee2f2d6a78433fb2af5ae29c8c930d2f16616d569d7824dbec08bb7108e9c621d364af3dd3f56bc7afaa03ecc232c0371532dc033fdda996a5d51069875623798dc94b4273ce6192e3a60bedbb3c0c7f2d487656edde1a2cad5a8ff7d34b27dfc579c8de7448bd2621ee1e47ac6d82d6b8eb90576477c209541c4f6067e7a0aafc1ac90035032d82dafe55f29264b4863ca5ccfd383357acc6b9a4c69792b4e14e30aa08f03854509e9040e5b1fc12e42ac6fa66c32324352195138f0880d86dd83d12b0852c75b5249b91bc339a5ed86f98330d064e11b449be44439a0529b556b76ad7c3405388971cbb083eeadd1b07b67c9fc660e852260e7c6bb686a2c095cd023a630a5bcf38a51cc86ac7920d3adbaf9c99a44b61033fb25e53366c67f1856aa6bd5c574c1b55f43f0df311df44b9e567a0350bc32fd8699f1ec5d2fc03600a2dce51917278f94f71e429fa273662ab5fc250af96b6854d99075458e225c1cc0d2fd5435e2126fca7aa6ba7ebf8e1a74f628ef71b98487bc11d4a3810492a14f09a113e6d191630d1eb4d44ba4d8380844e851e4881f208d21176c3d91509148958c6b5187b140afe3a8ce1380ad66c40f17b1b82a876c7d71cccf2b04b588de6fda296e84a71bad0c228d08ddd778a89bf075ed3326795343d7e0c046479c779d8013d217e559709f2d51a02024be9d861ef1bb072e973c62274c02aa6b6a49502537e90913c0e17c504fd6e6a586209b0452e6fb48ba97ff8cb162aade0f0d8542de017ad79d37979ca42e03c8ae5bc556faf2510661216cd6338e474481656d039c04d48eab98a09f7ab2c479718bbb6624236832defbe44cc122f5c36c1a178c1245b09c7bbe06ac468f18b085fd9fe21ab917d72c92f31e4a5be48bd2490750084eb4ed06a9a9d07ec6bcb4e34a903f013e7f429f25f71451659edd2f975ad0de32e05ae3364bc0979a6aafcba2692a36c79ea44041ec40d0059d5cf73466e174610de40335c9ad48167a0f7512d97a2b6cb335ee992d83b639c01d9a8fb01a9cb9598629172829f8989f70a365bddbb97d44aa990c5947a9ac07e671eefe3c8682017850d75f460afda209e387084ad8e11ed5cac5ec3eea25bd24443ae1869b030d6f41a6ff573048a19f45c463c7d122ec16bd7e32631af79e16359464da9380e800373dd4e5e844a5634bfa129e015663540ddfd8b4da3c5b9ca7f01131e151dba39a208cc56adad9cc70182205ceb56b9046ace1e2d6a244d548cfac5aece3a0077990b9915d3778b7f2441380f9509fcd89f0af3dfe54d44d05a31198716265637d75b4c5088be49930b08333469253f64dc15ccb9b995e15433d0087eb869b9e8d4dedd2bde5d1bb4eecea9b20c740f8c190f076dfafea718a3667afd9d8d9e2b2ce668ff6d346685a307d44584684982ba84cc3e8a213e005922b7777c50d8d3720fcc5649d9219d065e98d212ed5e989d10f96a7aa5921a5ca3f362c30c89d805e81f96922686377e4bcc5435b82ca75f3587758440af27687a408a0b6a15625424a9ed21c1ef58c7162d7a703bf5e36c061111adfee4c099351537b5d2a355cf4be00cb17832a03893de4543931d1f6d3ebcef84ef61f5f609ff7fb9f85d2793a787df83604b88b2ff7c6ad2f6598abd4d39596271b930005e23f602d042e4fdfbcef9174fe0c2b061f35472db3e97f10ab09a1f4dc3565231b48d39e51e002e5cd644a08e18db7a3be901b6f52571dfea13e6c7cfe179b52f8ef6423e3919905bd5e04daf08827c9bd13f6e1488cd0a04cfcd850443d5389c4ba251a3c06365e48cdc1ea5c2af27d262eab393745d1592c211b8dac952a930c3a2e24707537033da6f8d6c2e8fb07f3b0b0e6caf8aea09c8a105a8b99c2575ad3a1a4d7667e7344c1e6bc1d247c65f8e9770fe0c7a9951b645167c9cd1604abce2fcfb9b30dc15cd9993d5ece2203dc7a0a8666ce3dfe87c2ac8a6fa67a684e012f0a9bcc5ff25cb334f4fa9a76ad3514ff5114664557a32bc55643851f21ef644b0992d4f28e533b3ca43f8758cb88ea7f989d96dd91b965ef639ba60f14b892ab6de99bfba5c437dee44a6b5c485be7cc82d4a8ca08bb0de5c7987122a566589bc661e62792fdfc168c0fcbdacee2add9789f2e5ebc0ae92d0a235ecc7873ce1b40bcd74d1c3b6d5598aa0ed5b5f5007e293e395f2c2921a6e7f446a836155e4cafd075b2f3cfc60ea07893ef8eb40b9d59309b0601e3df57c2909340ce8089e9ed2325deffa7b310cab43ece4e4d0d27c773c10075228ab59e7f8182965abd0dcb6b652050b2d365e7b1d05f649b19ce7b62f47ff95a31d052ad4ee397b2cca64e292c6cb37dacb1aeb0f547ef44c998b4b1d7980441e01b7446e164fc643aee74afe9a6c5a8e69a0a34f1829750167641f1749da69f44809109a2a4c5d0312929049f38f9929fb7191ad69eb2da3e357757973d86362bc6c9511a347ce88106bce57e35c4dfe9a33d5d76a1a6d7cb74766356456b7a15a66b7d2e483647cb594768c48402704e09206985cd644a3e61a51bdf1c1f451a55910932e37e1d11e7e3d60929d96a29f93c7c382870d29deaf4666f9c6498becb1dca7a0f03a63998377b82d587aead568928700b483b71483f53a2543c1eed3b9b4bafaf2d45e10ff99da3943aa77ee5c2e1a84a6f0578654ed576171308d00096ab25c93f244ba3104662f94298bcb6a7fc1bbd7f3bcac219b574146ef64bcf0cd1feac4b74bc276102781f62ca04eb2c6d085012e0d06a2c2412ab1be32698f304d73b0a533c64920d8b33530b65e16fce14b4d615f1bfb236fab226c9c90b9448490db19bfe5d529963885ff0938a175e112d72c6c4327cef3f44702cdd7f83ba63ddea8565b001d6a23fe51eef3471f828f5568faed064ab3e2390c86882b5a6ee8782f0ec6c37d98acf968e5bd613da46c36bbcf9f9f0707590a19c28a509b27a8bfbdfb730032a64bbba14471ebea2c398a506612b785922597ee76139034cee2ff3e74a4d1eeb471cdd7f43068bad806a26c8d86412362793c7823e1e500fc4495399b0011a6988eb76f3be8047a849951eb253ab9bc2767db88e5cad1100b1fe331b68968198a2e033211de0c804009f95c409a4e13210a30cf12d725bae62b6f6ca513b8e7d9ca8eb0cb9b646bb178847fbd01b44b4fe1e6b15b0ab7c2962874d5fdf70a455f03d2e4454163e89b20e6a1d8033870e1e177cc6d856457c3624dd76227bf6b5d4f0c2243dadbc11235dd58a95a272903af1ee6671b636d8f47e90bc36d5c6e070d9067e7d81d504f566d040c3f193aee5b48195fc5910ecc4926d1ebb121c2d451d3e99a2386a69104bb5c15171ddad5caf8e09d7a051b33c1db342cc4ec3d81e59ff6f19983a44ca609a48d86a053d635ea49fd90b0bbe55be786c28205cbdaee73e6ed957f8e93b8f2a9209555609d3346a1b044750221bf76b3d1c10504ab8aabb28c0aeb89fbacce4dbc40afc27e0b3b9e86a3913cbcc9bdd343045e0ce24e72c6f52b6852683fd9a61533e5994c107ca65a0d81d4ee5322c0f7168e4c2b32eba8a7fd783eec9ef68d7f20950595988bf1f857bbd3e184aca1ee2e7f5f71fd30a1075e59ef1103345a8835806dfc6a8a246dd79b7551c26a9b16a7628dc65ea8c930abfc7a7cf04f1e475664e1373cfe6ca0396d4c750d114081f22d33d7981eb536e60ed2d3ea5fa72cd046c5fb110fddfb14466f0d8c35b2658eb69742505e7d1d4161f1d4c1b9af6e373fc984baa35f81392bbfb56c201ae31e2b6fe2a22680802d51d9ef98e7ea830eefa07667879bc93921d4bf4f117fe0d328d1586ad150b58685eaaf61e704a2fc6ec854d19ac27a9d236d88a1fc310c23255187c88a5e2f7684a02098fa671d68a592e2096466c5b87191efc3163193123feeaaac57b4fbb7d78352b01f5ddf29563946a45c325c74c70e2af45167619af91d10088f0699695decdea4b41d43be14e0b0fc95c150e122d56dcb90ced5efa1ec926bcb5eb55287c855f215bf7dd0159a7cfffab8b8f897ecef49764928f3792c5e100c8a3fa3044361276a2b987f57624a509b2a119c12a678d25791101d182af43f1d44749055116496fd0ad78598cfd78bb185d0a5b02fa302f3559a5f952b9ca6e639da088792470e04ce9d76c431d94f0633b7c9893c3a72e01289b8a7573e60cec814bd2e2a553eb1728a9f629cc9324f93f7e440a11a39a437bf3ed1ed4ae684904cdc4fa3546e583adcd55d48a8d0ad228e4eca534dfa0cfe35dddc7b817f9a01d9da79ea45cc49915a2935d6226b7e0b99417c55e29c070eca6c394f3994026fdffe5382a05ef7e348dfa260c790b9549d5ee560c7a83c1ef7f413a46885df2a15f14d81d83d4fa51c709d5ddd62a34b6a8d531e04c48920e525e98875cf188e8c800876a3186d081472c3e3c5180eb3f8b1dfe1b2bd18f271262211601f7b0a7ed0620c5dfdfcb981ba7a33b8b10af6995bf36b19889b9938a460659e2454ab63e1e0d423ad0d984d4d3c0874aba21623d301d12f606fc3296c427dd4aa1bd6dce71c0f8b31b1c2be774382b8db3f518ffa883b97da0dadd6dfee0a647ffaf1e89515ca8a6adeee729e35a3a3b43cbd4826397b4b7b627e41ca18eede322eada538090e4b924104dfa67909d1a4d4941ac4448d911e21c6068c8d094fe3359bc8a26ed66962bf618c6c93f9177d5f93527789b89ba3d68a9e1b467d3616e26af40dcf7e8e71e6fd1b88aa1340ebea1c0e8ed4400f13904be8e90cb4af01bb7be6b8843da9f878948cd705f2db20ff131ed1cfa4695d6352b78a2d9bee47e45f19a30cbfeeb561853cbb0ccd307a5c95c9824001f9e74ca4cbe5ea9448f3ad32cba1087603c3627ec1c11ce2d2a8692240d650735dd67199fcf92bfac80b38d535d4c40063632bb63ce185a3c5aa992b7a28b761f0683010d3a3c058a07d8dfcdf7e9714c9c639cfb4de8a8ee7bf4efff8c5fa8ded4d8d5bf9e00efe6edc2ffc87b886a071b6e65465192361c76ef37897f7eeb2d13fc3ed6fb02bf2b9b7dc973d4a5239cef90bf5e60fbf5d6fe601963d3d39fc92451d5fccfe61d8873bb2ec8e386d2752f7d3d64f3f01b90f6a8b13ec9fdef7842f7d7efeabb2e6dc7a2279860fb434b71fb32eb73f0f199ed35e4832a03f1409b38eb0b76df9f885aa7d741f777b24feac604b4dee56aa9412461c5784182c78129ade4459596463f7f53eac7e8eb8b15c2747a3dd1a848c6a5ce7974a54d6ded7b739ada83925ab0a1c7cf2cd2a1871513c77fc80f8ac1c8b12ee425bbbeaad522e8670902a42a597f04db17ce3394e0a1423ec869dc9de9f790da539d84cdf51c4b98c5803a02c6141d1b42c2fd896e4cdc9b9fc2854f5d67da69304f70bc3c4dbafa5354a0b896c60de031a0fceb8d8c1c2bebb7ebf1feb0d549dcaac1ed75ab7e4e6ca0842ba63a95fb17ec222dc836f37171981b6b15f6680a67bbead684b46ab654d35843f036b0a51c24a73d0ad34104b473c59cd7f6083cf94079024b5f18d50b9515dcfb63b4440189659718bd1e288348ecc7df7d80a9e8f65a8611049fd9d8ce67e831283a524fa8893c9d0d907c05fb8ea777c015a1b707008dc17fd1c2646fe9e85df960eb1e8c00e6dec6603ad15190860e1f1cf1f61a332f2df442b7a48e59fb5914ac307fcccd938ab4eceafd708bf0fde6d8017ac1d2e00cdc3c240978173f357d0f80847edc43d1498c1368e8251fe4ad885606a0078415e17dd3dd3ffd23d1385c5a02fea1688941bd1dd7e547001ae785bed2b7d02b117b4b665ce3306a37af2017009b41e56ea7b23e8a7c0f8ec0766a690f0d8dfb105156ef8042413af70ae21d1e75bbc6cf8df1017a144d736241c745774935344ee98b7c964c2e522ef4d2f71f7560704a505b14fb90e5b1fabe63b43a17c3c242dd49c46135d9cc8e1e118d401b64410fdb89d04b851870846e68db8351733ae52d52bac06fdb52efc13c8ff37187a755dabfc3018f6efc4fa1fd06aaf544f0f2333083af3dc6f335a957824187d3988ba57e605e43f68deca71724add64be8cfb852099ef7382343ffc9fd367e881f3b0aaf60f7c4d7d5c7b38f687be5027a7d675b827e4aab8856986bf77858fb039a83dc9cc4b10d281a01b026aa81cfd5ba674039c9cc6301ea3a7f32a4f28bfb059bc530d5ffaf4192a0a9eb0fd1137380a195ee1f3ffe308843862a6bf97e4a071f00791d7e7ad63f83ec2b22e3ddf41437fe96f1f32068481d3108e6b47849641eb7dc8e969a596fa374e1919517129d9d0d6d78056508c39e0df6b9eeb2982c2d98033193aeea3ebb47d7ca0663caddb4dcbd63fa8f6fe4e64427bf2ffdafdf4b89bc2625f4e9fb31e01e894321a337e3cd977aa1dc8fc5fe3fba2d504dff188d77e898ab92cf566377ff837fb106b8bf986c903053ec44f263acd65661423d30c33821061f32e594110ff80588f33315b06f6bb1893c25fc0a031cd0cbd3370f532c5572e06dd70ce7f3e9a1f0595c6ec10f5de3b2de433dd9c99e5cf1c6ee3762f30dca011f14be2629f56322724fb5f885e3785914a1bcbd017bef734471916ea0fc99cf8fe21fd6120ba7fcc1466ed1d7d570ae0e4e5dbc7602331de15d9ecdc821d65d79da065a8744cd47f37eec88287f9a1f3e8db1fcc7c88913afafdc66298b6f126fd1bee2fc3b0735baaaba2a324d607ba179b396e830e238d8d884e8d7bc018e1d731170dd447bca53a2b5a7bbaa8fbcee62bfaac97eaa96156d67395cd5140e54c2d2a2af27a7e2441758528d65e5ec7de319fcdab11ed2500de72962e81ea3d297683045dfcd54856393162bd9fd2a25313003e10d822011f3d30df0994a752c692c6233f60b2c8b3c0529bfcc878685bdfd1aeb6028971a0b16b86dfd40f6f34943cb19d1230e2ee8be4b346748377b4dab8de3a2456c22e06e0c0c72a54207fb0896fd02538d305e53d20b0ec8b7c8d506cfbace3c43a778f9e60b076ee3f6769cb070ddb077bce84044b24d69a8bdfd91738f48b62d1cdac43f20f7f56ec55794515eed0367dbac7d45f2afb47c04491455d41c5be1b78c410bdf11d4ad2a53b4c854f9b111babb072697727aa0ce0fb907f1d500f8436b57fae4511fb63eb9f84bb327cbdc939476cc577c11e6b4fb6c02f5c122e541003e2feef34b763424b3f66b9600dccd931e38d2475b0edb929f1288515b644abc3327e2136944d835814498caf7553c3f724d4c102922a772db3536562766d0b06b8453ad78d139d426ea5f882d11d24bdd728e1432ed77c77f3fd55b740c29187dd6f2a12d94a1a9f096f5cdbd00d754f24a23efa621338ff70c9aca84e4c8673e6c20c630d3e315c223fdf15ec03d1968a67b7593d1fd6676c5b586a40352270eef173badbc307a6be314255c84414134650469a960f0978dd09b711ad5d1dfedadfe916503e9c7d2b31b170012a7192916e54d541ac5ca57a4571c5aecdb0894084d0b95fd4673c630f7b5d55681174526928b8a9159fecd90c6d8e50c5f2285c1a10de52e5a3b8d273e075bdf8eeaceb75da6ad8120a90e252d9880271d9b61469d08c8fa02b4ce64a3379c1bbfe1fba817488ae9373e425e0f1974a9147efa9ead2d4105662eda3737edea4c9a63d17a8e567aac50897a0ecd72906c28dfc2e41a5df5dd61c17d7f6a60604fad402c8cab492d26f551585c095ce39c17e0fc598a3140f34aaeb6e486b2ac5d458a2f1cd1c54b503d34623dee4b93c9dc02fcfbab72f621cb0e90256ad537da4a4afdb38ef218922723d1551b8bd581027ac79c5578695975b096d0200d48b0ff1aa6548badd57fadbc6b60648a4f8f4ac2699d98343e7dd3d0632c2a0cf7a6b3813a0e21e8eccab9cda6a91dc71c3c42f3c2f564d9a998b107b93211ba01ef7abe7bd8e991bb15daa16745427db628ce4cb393599bde748c1731260609985c0e1b3dfa512a42f051a7510dc3e26a387ecdf236569ea6cb1b469a72336489fa5e9576c3d93fbb9d7e4b44216865aa75afd9c27c3fa497910acb90d1e36d3e958fad04fc2a4f33e25148ae183579c210fa8bed9aed5661943f52dbb362e25b036aee90ea2a23918228e466e645d878670c81e4b1f2669c1cacb0585afb9db3b64b7ca2f948a48d8204fbfdb2994e1e87a7d2a8a7bc49e553f844b86cefb2a414972f2a95b6b7dd650b18298de4122a258414464a5df39e162e4cd4d4de5aa5340605813ebe403367d7f157a93793f595f53aca8e2a4d7ee4074012a02cb5323a417d8eeb494eb0cc17033de1d08d65c4a4f9ddde4cbf28698699cc94163a910f1de124935da8a45019f05898fd4fc183863573b1f0d67572e29f8b97d6f2472f8b711b7cf173ad7f50d3a810e506a2ff93e270281a5ef40dde744ca6ca4b71e811c76d801457935455bdcd5f855c3d29d2a7d3b9d78b5c48b88df16362af28d795643c440b4be67229f7ba80c4bb4881cd168195b3a196bf2e5531c60d60dc6793fcf3866d691cf8cae131be330ac3c01830c027ccb88d1527d6425fc37f48b27e8afc958e277c4113910103c7d274b61f22b4a04f7b0c975385979fb794c20dc9b2ca5f8cd90be81aafc8448fe77ab128f429740b51918408ce4b4f3c05423e52a0347bf44ef670812a7a9c1a9bb93ad9854f1a5af49d0bff294229004042f513808a35fdc15d07533ec9f551ab32623d2dbfbe12029110a141e179e4d2efbbbd6e4212fa114b78ee6ad47d68534d195204d625040354bcfc573e98073d8bdf549a6d3485c382716bcfe1ac369898258ab299ab2c1d1ec2f3d79482903038841b46663e68ca4d6a4789f0ba25598530bdafd0783c2bbcff336a54a995f8f67d092546acc1150fcdc49b036bda364c1042cd0a88a19b9aa890001178a8b63edc7b773707e26ffca4bebd34c8cde6362a4afdf31eefb46bd79db3f49ade0b7a5a9e134ec2c5d0104d3848607b04818f2d42c7f07749c4d571d550c5023442af41bbb78512eab19f8f7674a126fd20467509033cd228564d178596f90d0c55260a20e153a6f5c6da7e1cdcdbc5a192200bfb1715311b7ce8f379c802673459710d3d2682b1ace45be05d605fed6552f7f77a6de7f6eeab7da6e7ce8f78a69d67a3fc478bfe9d7fece3df9f8a13e95e0cd73cbd49b3e371230cde67bf52a34799f978baf0b5ab12e5ffe67c2f027a8cb8d59e610e749a61eafd76f165cfc1649ef71f48647b7061e1669de833b89d8b5cf95e3384ec121a1b741b13b7430ed13e5307ac34fa1fdde82ed4f34bb3164292f40a57dba8d8a34fb76816e746a2c1b85197dc3081273fa7d23c6d296ab2218b76353f59388064cca506d4d95e486ebadab684e182f53a84d851e0facac28a7863c485c039e862ef22a152e74c17b250a9a10db26196755c0938a193ffbcc80e62d93468ea1998481dc5062a3d89ec69a2ebd7e3cc9d739145bad5a421896eb7db228eba4d5869885a212a382dec9184fb2bb12f43d4a175414e6eaf22f5c77ddb3488e539a920284462ead356142bcf3041cddcbeb22cf6a8f9c5261f769f22b5cee8f77b3a0580b44a8f0a72ffdf1251abc5ed4926ffc98851e150de81ff441238c21a8bae46611d933c3fbb94fc198502fc0d639b45bb04137fee531b1cf9ea4898b52fe3ac9f0ef9004831cd34490ba5b957070f302c8fcb117076f67ae27d846de2ebf9bd1ac7aba319d39f3b362c774a666225f58652f7dbede7de62e5d5d0858dbd5c90be6aa5dda51889584019af8a9ffdf3023f686ce85acf977a6e2cae426bfbc516c432f6cfe1bcaae638808e992e1bb47b3fcab9b00c75a8173c74f589730f38f4d6087b5440f413f12ca5612e095125ac4b300e424008c16f6fe99898d129bf596bd25b17060ffb061b3b00d5c43454bb21f063c7b03d062cbcd6be4ea4a86b8deab28c7bfeb87be73c8a8959890216864a6e34a58ee9ce02d5999ffc9decef9cfffefba7afaf3d92b490efd4a83c3483591a2748b66228cbdd1e7420fd46f1d26b0d8dbd83601e15a5d76087b89fddd684d211da4fc42a611ddac22dcb3cf6d6fea51dfc20f0cd3c3eba248ea9967fd84c248ef6b434b16e0b50447329e1ed4ad799b1a0e1e89dd434cecae57d6949670520c67c9398ec2220a77efa2e1893420bfd9afb9d50b2d8e5173236941285a45670292538054ee4fdc9effbad56206d54a78ff9d12916ea0f1a44f8169e209a0a3ee0fa71fa1153ab5ac683770a1d48e59da4ff59a8feb9c364f7a99d25aa57cbfa45b76a010cede3ec6219965f0550bc1443f8c6010a8298339343a0da30712d740cbc81d24fd937674451a1993bbd75aea251f0b43e76a4333aff96ac2b34df28ec2a9fcba1d5a87884ee61645558b3074812f4f53b0884ec568f5d8517cd01cade1e903f784c6e78869bce9e2093253f6407452ec3ecd9657efd68191d648124c2392f0597022c91ff866a946a2a1fe2cf37d61b99ec177a85efc6cda315b1b3050bd70186123a8d1695e5d927ac39733d84024910da51c09a72aaf082471980db826fa885d6aafad98aa269a65cab6b0b2f992940c0fc6fc1fb6ba1e1d79ca2bb15c0580bff044d6076722dcf7f8cf5fba79411e6319ac2686fa8d19298074af70b8bf8a241076ce88b093cdc27699b66127a3031be25b6d82f0543a5006033d02d5678a3870635f651351448ad649e90092cbbca12fa80262b42a9c2903454e30d56a1aa586d20f2494347a5738cbb5aecca0d6b226a7be8a595337738b70ffbf523f47c815732b0c02682e417c3bd3f3d5984cc04daee30c98b5d497234c12f598c79040054874b3ea8e01d91b50080a498c2025cb49d590dd207a6ccc7fe26321814095f28518458d7016925b4b39413882ea1fb1b2580e58fa7e69bd549e1b0a1648440ede71cca2d68f0fba44283f498c3c5acbbd885a187888050677f87728a62493270134ee7ab158ea1da10e82f243908e25e8908885a2746b8e448d3a02c9c3d0026f36780c81cf052efd83b1c9ffff815fad11688a308ce38e52c632eb9e4cb59c26e22e8a01d8cba3148c1f7af3ba17597cd95a3c9b78865fdff3ad553d340782be52f929d83f6f4d6044ae82731e51ddc9ef43bab1e4ae9a22bdae4e98c7bd3de47efaf2dfb54719408e404da99e5c834b5f3b8183fa553fefccb5f2bfaca3a4e5338a7810b4fc1d0f97a13403c7599a607bc7bd121beb627c83fd37283487df756ea7d38b8db9fe57ba7f9ebcc6cab3ecc7d70127a0f0e80a111b4309ee7a6118085cd548e8b797bfe2c4570a9ebdbfc2c44cc8852f45d3f7a7e6778b553f42a24c6c299b5fd959a111cb9c97b73c23a13dd7e22b980c645e40cdbe23d0ed56dbc18b95d03ae0e698162182c9f6ba881a4849681c3ada9fb6c906e7eecfa39e3d43780852e42121622f84235255fb3f7db690db4c3d1fb8d86e8b8c4eed38e05864fac37d926c0a29c4aaee6f316e37bdedaf8eb1fd3d957b9d0a24197a3539bc9bc76bb314bcff9e84db94bfded0c195e28254e6042e6a563e8bd12793134a919d48d012fce325c9ba590aaef758e70bd43757a60dc65a6a9138987008bc14718be687ba42bdb10654a00bc4a644f65e00a61238e892a70ee5d56d89b1345789a6f7e5000c82e5f9763385e62e1cb0864e1a2e89a7be3073adf92c4e8854a1b336c8c5414a768f3ab4a9eba29eeaefc1f221ef954297e597ba3615d3e3792a332ac892a0899fb259039fba984484cd435c1d8bb01d4bd3e63581dc277440eb28be7f1966315312ed1500e9b07a39ba5e6ad63ffc146f1fcda7aecb8645d2a29a7a4128243041bc1bef1618de2f9746160f47c28f6852e466e2558ec0f27607e9ace220347b6ee85d443c8865c1c782c88f2cee8556f6d37b7a1de249d3a3c52ad60b4c7fc83fb3124a6c7da2a1ecc2e9a1f0a17a5568287e0404c60c9b108cb381325606fc88043352579b5e3c11e84478e8ee72d9cd989e4ff6e3aa1234f7d01b6cdc03fc7c7e1ce17bee16878301c8d2de0f64de9bedddfa953e85570aabc00df6c5e8844c4ae92b82b2001c16a60d582f960e73514e19a1d7d97fb1cc82ebeb0acac2c1960c8144a571076c28caaed6cbf89f803a96254ee3588fb6c5169025046de87a04460be98b2f22da176a460464229239549091ff904654dac96fee466eccb16247b4bf75b0e4fd1feac1a67548d055705e75f82921562f76c5d3fe9823c76702c33a8b0dde91b4e9de9541882b6dccb1d4bc1fc8bca7d7bbf5e930f94caca5a7d455be1ff3a05b3d3b61d6c5736b9ee8451623d443bf977f558f425bd6b9ffd58cabef15e5f6e491df483d4e1fa493d5415ddfe79e1de7b0a0030038ce77a30822d93ff8605625319f6d363f81d237836a2ea2eef526c53c92d7a43100f0184195fe42e0636c0d9e7dcba9f69d905094cf23510a63003a30d874f7aa670566d89ecfadfd4622987d5e4ba5223828cbb662ec7c2fbc881f427c354261d028688879378dd18a404fd82784e63b983968f3a8af2d76ac10c66f8c8cf336bcb4292ae1bcf565d0ac5760f324bf0a78084515c034b32c8d71fa53f670d0cd479c43f16aabce9febb19edab9b60eed8de41cd5989a2ffbb5bbf1e32936f805e0e3845abeadb68c05ab6b8205c860b73f76572c45da3cccf247d89249ba60d3c72cde0ab3ff9ee1b025b3948adbc6e02179905eb6365be80ee3954ef3a69bdebee464ad0f1a49584dbc88c496ce703b18436259bee9eeba3596a13ffbdc222103788ab1d322749016a8879f4840f52841f018f87f09efa5dcecd0e34932d73fb92ba4b9580261d82c63eca0c56b0f1a6d25d01b70f661fc0f7d7ddc84f14d0addddb46d8cda3aaf5c2a47152135280cdc9bc45dcaccd52714e209f848bf84d1a43c37b8fdf9f834334f65e4ffd1f6f18bd3a0479d008bd179c9ef18c8baca0a2dd1e4d79d85858304dd3b61aa7d5a69b3910780cb355f8d01f33e13f4335a95a21a6729857bf1b2397d9e2ad270739354cf8c06a3137d6fb74b872ec25ed45534881cd5818e044ebf5b540210913abd90a0b29c28b69d1856f01e01eaea889ac3f67e058ea8d83d5395e3ca98a89da33eec58ef9ae016956c3c913a647632e87bc54810966d85442c0050325cc681b9122a2fc5b842860491fec9eb277a0dd3ad7958d2ecf91bca76bc0374bea8a1caef412040258e846f2ae86aae6edf2c96c7f6df29b9bbf1fe39249cc791304b4b8a886adcf68af96bf853c6df5a1c3d48289ea36041113896880178dcfaf39f10422de08a79af3272a95621dbe26231e5e5e9101d632291231d127fcc4481f6238640038bd525ba5dc0e18b57661569bee11712711cd0bc4a70394f55207e7464c7caad5888e680baffcb2810c7d1e95314e322b2dea7e024132565c788b293162ed4b586cf327b7c1f3684161d21186f0e3b87f160517884e9f2c9340a8f485ffef92129024c15cfc82226102e74560bd567fe2559b679526acf95f6b8a75a0601b81a91dc6382f59f912bb40211609d5d8cc201b177e7695dd2a8b5bc5fa7c19cd92c024107dce6a004d031f217d68d86fe4685c850abc2fd0f34a6b6bcc654317b0b125be78b863494ddbf6519b245f927a4673869f7213c1458717c6fda6b884862e74b6523de7af15634197513fa2b4706da848ab6bf8280de1fcf7dca7d7b127075bea38de190a33d7812ad6bb09f05dd500f75fa9a1d3eb76a31262f690d359d82e437d4b752c4c904872144c847f0c7cec02ceef18bbcffea4f7b79a966c6b566bd0d5278d48ba69a2e8e286422d8df8647a78755e743e06bbc19cec962033237b3134de52fbdb470be8c6f2de7fbcb0619fd679b4cffd9c6f830bf0f2fbe19fbedf0d8f9ce85187fe26d90b3af33de3c6b7d269c1a6b474088596834cedd819c29566442d925481809a5c6b4177062179634d4c22ae52cf659f28ce0b52d79ead2b242e74c2d7e4e30ed7839639a4222cd41b90e166592ca0659449e6a6634cdd459b24487757dd2c21c77f6df3ec3bf3ec2e2d387b0f9f7115e3e834e4b58fb3143e564a689acb3926e42062ad3d4a4e6b0a455dd81427059aeb8977ce9f16e3f1b51cca924d96924abacd385d081cc1435d724ac695957a0094ad3d1b2ab3ee3d0bace40117453a2998db18a357bca834bb394230b9b63192b760725a0399956ba348d452cd889640fe592d9a7794a91810db18c25bb831c109c4c539ac94ad6e92454a033859a6b0c2b5ad725d004d954b4540293ccf7109555739550b61be7fe4f4eba0919a84c53939ac3925675070a4137194d6c8e9558b333a880e69434a791acb24e17424750e3bc1aae00be0f86ccf0699a5264b349ac63c9ba5aa0074dcd764f39ded9f7248184fbc73575917b750977d619b7d44d6eaa8722a0a8ad3148bbdcdf5cafebdcab4bb8b3ceb8a56e7253dde1ca2a742c21ee650c6ecc1c6e9299b89629b83393887f64ade69b7fd83bc9e214912771c7ffc63f1eafe0086b5bc28f082e5ec50dff10d7e8bc8fdbfd092eb178074f585b126e05b0b615f7fe437ca3f33aeefb27e147a3e5a5f873c6c4fbb8ed5ff089897770cb7fe10743dee166c6ecd51490eddb390e4ace73c4fc1f6b8b8cf9827d49277cf18a93cdd959fde0010f925ded112bd606cf3044294d4948489649e5bb3486bd5ab11fa6877828302ed88ef0f3ea1012a9c89bf504ec3ac41e20554768931d9f4d430457f5ee328c897c4a044650281a3c60d1a0effd447f59460569a605c6fde96aa58ba462391e6281c55872fa8c1e5ea89deb10c3b21e8a41a09d52a1cb95c9bbc2b30fef0a0cde320669cee13566186bed2ec1385ac7208d6cdfebe27d0fee09dfa9e73bd6594a84a343f41b6369736d6285a7da9cb5c97bd1a77b56ddfeea0293658c6a7ab8a822d0d928237b5376fcb37fbec6101e2be50f2ce0dc4e9a390a62ec6793e8a3ddb5a52f6a04e5a24611d3526c86af495d23553a16564e4c47e0896825eff448b00616d7d47323d4cd928b92ca942754a2e3fa3e0025dc855e2cf29b51aba72f549d44c1f737bb9c2c5594a073c1673a9dc41777b3bea2e5b7e01f8cffc4dc2344dd65b5ee655a95a741f750c53c74b722e582528b03d3637f78f320a84c0eea6dfabc1b095776570d3546aa9f695138ee05aaac3ef8427320ea2d225e279fd407b68ba4e017de3b4957a877b1080c2f051a1c6ba5551048cb481dc419bc348900023f1a70d2ce4fdf84b8eb9df6510e60c22b079c4043120119812f49dc52926d915c2b2169114b646ed29e0609211eccead0076a416c002b2fa01770a7fa0615ac3aaa63748516f17f0adb09130a980a3838aeca18bc5dd77954a53e9a51be0a3df0aebace697fbfda8fe68b65ccbacddefdcf601da65de797beb5423e9a2f5d12d2757eed2c530fbcf9ffcc5b2bd4986cf0458d243576d4f8d11da57ddc9ae961c6872e70edd264ac65ecb3df0c2b8d308d6fbcb75b9155cc26b355893443a58b31a7f3a75599fb99e50db65579976c55da23a4afb6a85a6aab12098d1b62d2194d74b7b3a60b86c12a366798babdd9ea9756b42a9192eec3eeed06fbf0bdddcca042c50c0194e18332c69421a68c31baa3cfac4b57e1f06dfed9ec3ebf024ae424d10f61cf6bcd6a7f6cd17b20d2acf6a7525b43a544d622fdb5b224a5f740a42246943c8c2fd1bf50cefdbf507873ad94087bb652229c2dcad67befa3f7655f53de2532fb2db942352c3dfae3ca9268a88665139c9344951261fc9277c9d1e37fa1cfe10fbd4747f86d32fac2e13b9917dba39cfba29cfba2f09de0fc4993626c33d89add274a193fce0edd3fb22f2cef926cbd24fc7368ca6f72add03c4ac2e13bc9b92fc24119cb218cbf7e964393063d96b5a30c1acdbfd1bf59223bab2e9b4c5e5aa593ca3e4868565d299b31a234be343dc2bcd336627889a1274615e3bb6f6ee8cdf5fde6c669955aa14fe9055e3aea2cc16c86e52c4d01d304992e3bc4a0bd048004448aa040aed140fb73fbecca9f245bf993e623e54fba7d76c5f09dc4f06dd70a11a28ab7cfb7cfaed8c2dfbf13bf471eebf44be7579cc5940747acb2455569be4d6687f287def7dd3ebb3c9974abfc921e83eefaa4ee3d5ca64386b8cfac0bc98f85e0a77456892b4539ee1ebcb9f3786d4c4d95272b8d6294b31c83f2e806e247aad62659fb82b1f0537ce34cdaa4200d13001105036cd077809d04e80691d66b2608d513021d700446741b33ad0292259e4075d37ce145172a480117345b74d3a0a09b468b6e9a2c684e1047b5b30faa61d9048661f6fe1518be478ac49c556cce07fae8eba32fdc17b93efa8a2f843ffa8a1fcd9686b3f3a3af88ef7f1fcdbef4b42693f53f2b3f5ca9a4b53cca2c27bef199f7387bb1f7bf5dcad670ae4275f39344f8a32fffe86b562a44530023badba34cb24799cc479af4e768d21f2c148045cda4b14963b02b76982efa933dca247b9489962068a2e0497f729228d664927a3497feb119efe370a6b59fb53cdad9ec2988f112ae56a852a248672beb37f9615b338dc63e866996f28abd334cbdb791c6eced66675428769dad46422e2197f8c8eb0fe524518cb7af9428563b9b579542799486278d75391daed6c3980a7761ecda8c3f0fbdc7577ed867f6976492c7db673af384132350a17193fe5cfae596645bf4f466d86799edfdb2bdfdf43cfbc13e10663328619e857d36cb608fedfd037cf46fb5b7cf343f9616e67d1f8865f47eb0fc2118bb59fc38f9d10cfb8bfb0afb68fe6886658fd29e1863bee7655b675eb0712237be11e360ef8fc49cd50d4bdc8a0600432278234b1a5d9233b11fb8af3d941450a7a8544a7c94782a37292acf7e88c5ba4679f643eeee754a023c3729cc0727c0a287133a28f199bdd7c3014a7a9c086c7ad64b05783c691f61643c651713f9f06841135dfaa7ad364de41e22a0e32b25f169f38148691b1080b9e1e5026a1db580bcc7739336089e0d088874cb1b0e1675b4f083046614e008160d267cd122c7e647005f0837365b70c084b0e504590a5bba1b8709299070d1dd3925a460730c2055595c701b264ac0305aa5b78ba6b100cd966e1a22ba692ad0365e9eb0f1d28566886e1a217ed050a0bb939e38f9e40df67f73ec9344fff7f533dfc6cb0f9a0948404b10516880c8d29386668a8d07c8687ce377cbc9dbcdc603583acaa4cc03f3fe9267f1916e1b0ff858628d25ccb0b7bf36cb2a78b3ab70ae7f731a5fc2a73d4fcaf08d5dc2609b2e46d41061d3c547171edd3518982140960b588002361d38e24193a569f5d2257abf9f1fbe6dca58b6d5d2283163eae59957ad27417bffcaaadafa184bcf28ff0d53fe244182eeeed136493c914406922022891cba553e74f4721f7af272157695d2276f3e7fda6e9a1fba697ce8a6e981c70e56a620510211708056e5e5d1f11586f114a1cd87cdef217600432e3cd02aad34276f2e7f89cef8e89623061b24b2c81fd84356c59cd4d0028d378de7d96c4cba6964d348a16e9a8ea6a3194233e48e3b66ea98a923d2c0984b4bf3a4774b867e5a4d805a4b908a94b098a167ae68a1674a3053848117bef131b06383012246f4002f790a158d80626344ca8801747b9e04a2c99beb3d2a976455f23c095495b22dc22e4f0281718110ba3d49b34f4fb3c0025eb28d05ac74871ead66d95f1a14e463b3050536450c4002a12e79fe937830c5f773efb323f452eab1d9d2753b2be64be6d36832f648f7eb7ea8f32ca15099ff4ecf7e2aec2e7894e577954e11558e8e5feb39ee954a8cd155465c55c4553a523ac73b478a449dd0cbe5e4142982e9928d5d70becce7774790384dc63c2f85ca4f63b1304dfeac1ccb661da6c9d80a77f73fef6bb6ae4be938919cbcc5146c885341b912254e45c789b84d4a8755f865f4e6bfd9a7b9ccb79b95fd7579b514c85df06871b95a8bc32ae5833c5d94165152e7337bffa3defdafca5c65be5f6e89bbe091266319fcfad96796055bd1db6398df57cda75e71a6f826674c93d42b8d5641b779ba3068e9954b8f1dc3e2cc7b8fca8c3b9afce96832469331a79e57fad3d616ce49222966b2348bf58a81b8a6052e4d0071c40608158008a1fb87357e28e3872b9c855fe52c95b3f04c1126f460b32442f704faa186279512c5ae739bbd028e8b704e12e516ce0ee57e5617bec92b8f28ac064c0f45b8c70e363c84a184fba2595d93c6aa92cd606bd29f1a356c32571750c436991dca49a218b1e3ccfa5f52fce8ebfe0cf2585f56a98dde9c52c96b515e2d0dfa4993622871d7ca68fede869dfefc5969cc257e3a6325ced4c7424984729f955f9f954b998a27e6d743cfe3a4313086278da9306ad298e39b9c7bdcf288dd7966754c3df0b63c1e4df993946d912d9af68856e9a43fd916dd97df24dba21e3c39393aee13c3ed630a9a7b1f533cadbee7c99aac7da030df8af3dc3e671eac4489cfacebc4af16e623063ea414c9968c295048531540492fbb5628683e4ed65ef36ff25ff3ff8218bb80b0007145cfc66e21bec91a715f73046de8367b9c2fa34b5caa0a72f9b5b90b65337b7f26a3332afb0f4fcfd6bc3ace0e29d5bf62af90bd7f004ab4642f0dc2b6a85ef0677aa085a204ca0844402a105298a94112e166670e9b8f88951e423e5cf727bfc62ac015dc2cf2c4be9ea8c8128bb50a4960135e0943c77110c98300c346038a40e3072c68f01044b541b865279834e90493725fe494e86e3bc1242c617682303b416c27886d722f2cdd17d809da092675c4b15902c35953fed03c66a15736d9d780b08cfd9d5958aef6ce6095c232f8d1d8a4b10a56f0b35d9a15fcfc6110c39e36c12a39992bbdd50bc696a82761dfbf0d276b19276b394676565d33a3991146ba5608e36ae9fd59959e26f1cce893447866942b7efc1403fd3dc232cba099d1acd449f8836b5836c1ffa13cb2b1d6edd259b541322664ab980bbafb15b127976e577aad385f56d0339551efcb2df1886f3878cabf1ff83689cb5582367806eddfe82be2c7587e61ac52da0eb1cbc91b8bd5e1ce67f3bd866593297f3c0f149af2c706d9972daa4a3c623550f090000f20a850d12828b589ca2b7cdb6781800089b406fa570b622c73ef3b3a0e8379cc347604c9ec2f52473149c1d2f8c6088038df558332e078d5ba4d37a0d1dd9efde48dc562b16ef0a1bbc3b7b13e4b0f577973f7096e40e1da283ef8f4ec105170ba6f368946abfc759e1c0cd66082e2a5bb3114af4d5088f4943f4d4f74e81e8a0003e2928d659ccfa7343dd8bca691297de9e6a1bb7fd4ecd0d77e4a44aaa5d8a3b61b58270cf6d59a5e4768495ce01b33786b05212347072963420729734337120bdd311060862071e4749038987490388ae8207184d141e2f0410721a342072103d441c8c43a0899b08390e1d241c8c0e0841d4e50e60520657c20c34577f78905091c7577cfac208709a94b371bdd3c4052f57c7af38f0d5658ca03e887470f8f1d1e383c5ae0d1c3061e4348613ad28126073caa697c230e903146471adfd83e42cf65cd50778d931a665e5034c50d13d11bbdfa51d3240662d8877fe65f7bef1213518d690807d350adbbdb5947aaeebd9965ac1e7a354c3f21b92664e66bf8a1060538eb6f569641eb2a9f954aba8469f78c0b78504dbc709171d5c01586fdfbb96a7ecfa4a08689104f7525b9869ce50ad2a48d2667b8ca95a8f09b9a2ca0490e98fafd0f66330ccbfbb6080826466c214573400b031020f4c5fd25a3d09b42551a87358a889f1e59729b91c85064f57364c97d566e6429dab01cf258adcf8f859eb13caa2e5bf4483533f0aed29323a69878a2e8eec7e050d1ec322c18acc8c89584b4e4098cb56488204c3c4033409a0ed30c3998173cfa015b70b48ed841d2d5b06cd2b9aa4a243afe8519e59df4bafa1bcd4f73339b42c5ffc20cebaecd3229d4d1e80cacbdbceb7c663d3a69d30c5cba632a7c1bcac39cbca96cf689abd2ac4a33ef936c110c06833d71721f6662195d0a7ef56f13c66306043128306104129c2146890148e8ee26a10914ec8c5087aaf66303b2813811471620345657c1e5fc280304c48d12ccd8c93b2fdb4ece4e096d4aa2834e12268915d9da0bbbb71b976e8cdf839992f81026c9dda624af243da624deddb0ff599210baedac5258994ea3c3f49b9064e179d24b7723d9d2f829121dbcee4672d4b09acc7e4876ba1b89b70c74846f83c9904577c3bc744faaa5730d93618a0c418d6132a01acb4042f791326d3a32e648982360ba1b049a235b1a85361df1da6d9ef2a77b660440aebdd787139311312623b51e130c5a4c4654353324311999b2d35d93a4bb064977cd901a196a33b12504a2bbe6484e4ebebf54adecfb3a10ae9874dec03762d8fd0f859a15e8fc2fe4e972f2f682f7782a276f2fe0584179f4658ee356ba2f3362ac718236e56409ab94535a2ff43c82d276d718e9ae2952b30202681c60abcd1a0659acf91567f4d3167552d65da3d35d9353b3020d269c283d2606b18c68648a44daffb332ec1566938f930f85860634ab15cc8c11868a0a26a0d04256c159a6339f71c244a4892e6284fa1a3338009165a6015f835313bbbbeb98d4c033dffb98f45a33249850748861425d81da407763eaff85d883504add5d429b502d136ac7934b30130a05d3cd0f6ec62ce9ae5975d7a84c37b91a22606682689a134c336e74175d9051230210244c3144c9d7621a23189248a1ba6b8644dbb5b3b6810986ee5ead5635a91d7f9cab5ae1948f849348dd3528a1992a6880e8aeb999b688c55a329b19d51f2c6b4add9dff8ec3e057de7cfe632c7576925c480db1751454d44262626ac1089bc9c3e8d6c00c2a7423a04d0ed44d5cb7cfaef7645509bb8432b64df21d3c985800405b9af464ba323d2a6a12667a41138da9b1a4cdb4615ac1d5b44a6158d2ee2f59cfb348b95ef08756a9490535babb67f4e8a9a4d1bfbfa4bae04fbc602c85fa2b3f7c14b1ff1205f151b4c9646c7efebee5319625cecfb628d779a3fe5ece8f3178c516cdb7d9a5478a8149f395804ca09da5d32a55455a7c57e56e3949e431e7bf791ae1b8acc7209757e93d8d4fef7fab188823c6a0f739ad3732398b81385219c5f247ca6287531e9555d0ca3c59cb56455b1eebcdcce538532131100bf186c082863b31b299e66c8b5ec816853619cd493130e85a21a4a934b11dca180c9a8fb3b32e71e52451adff592d8a14799c55aa92bcae73f993e2ce31add2d9cc76dd0d0a70f7f1e9915906b9ca553e3d3d375a4bfa5c89bb7b029cc5727f8f7e372bb3b5eb3ac7995610574b1f29cc7452d00afd25eab5be7f27b44ae50761dba6005c117f263118fbd05501f0e96e619bcc0eb9db6432cb20a41e21f868757748e7675b27fda9c940fba4522793fef43099806820aec29bdd6b62e8ae81a1bb7fd4bcd05de342778d90a7f73e36fd48c3f4434c37f1e79c248aa177a9b4510ff765fb6149636e3d70da5b4d8637e36237a31eca6aff71e7f829feeb441eefcd4c1db9ab1ce5d1654d76c14fc96375cd9f7549c69e87e9129df2e6821936c4d4800e1edd261e6faab181a9264b4fe08c3156b0032d32d0404031470a4c8ce916c8d1ad563830d8473ffaaaff199966b484d79a663ad34c4e77e70fdd3523c2aca09ddd6861f3e7fcd8ed592cd887733636ab343592a96d30750ddd5d73c95af2a62680a97fd8dc5183ee2cbfbf77c880ba03053bcab4b3e67dcb627df8654a76987ae98232d0ae6677a9d2d5ec2e09213da961d94408e9c9acffe5c79e2761303a96ba8215fc8109dd1736a78c81ffb0fc55603110c3e694b1fa3110c33205adc84147cfc7a00b06ebaef1ee1a166a56e8eea0dab291e34877c7db67174c8e0c0bc118f63c09837d36db94a1dddd3d58404607dd99e2ccd01ca9834c945e7a2f16a320ac200e3a6ce2e002840d1c62e048011c5c781873ef32818e0247149b37c6d8bce145775fa11856c359c3d94d33821ace6e9a1674370f1a30fab3d9bede4801cba1ee4ed9b80fbc9ca8b3cad1dbea671247a08bb638d2dd5fa957a91b5984a159018f14ca0d2c1550c2c68d26ce7a18cc0d1368957ef1af6ca34c1b61b8bd6d08c10adf066b0347168bd5060bed4a3c7c1becb3d9bfef41998edf835c0fbebbdb59e13bc9580ed9d7910dcb97cd608b8d31366c4051f36a69fda1f09de424910f8eecbb2b499756ab95151c9c9b95457a85de98cc15276b38e270382124331c41e22c6751e956ce7a59d491c103a5c47469cad5fd259b3d59ff734ffeede6674f36e95c7a3e458e20d1d1c1e97156b543808e907c88bf52e851ea819fe5ac9f69ec7e92a8a893429318fc2bab367cdb12a2169290db5cde689cefd8560cda5a845d46b3bc59f7d9cd6db6f869357c2753fe446c33fea84ccac775df0d8cb9ca2679ccf5b1771fcdb8eb3ae74911711e1fe244fc7f0643b912ff6886793ca98f6694cc93329812cfef05b2e658d65a37a875772833fe25ba74418cbb01aa5b0d31dd1dd5006352234babd175c720d74b8d02d8000536f8bae36ae63db66e031ad22813d3e09246678bd2d8498384ee1abca03b66fc93c57a4d178bf59a140d2bd028020d20344ae8e28c069cd1a4fb263fe31be954761ec6fe2f36430733aa98d113432fa9a8e8f3ecbd32ae28434b370dc6a08107688044031766d0c50c8e98419319b4c860838c1b9021c4adb34a79a3cd64182143003220a33b7615c459cf6bc94028063fe81203a518dcc480070cbec0e00a0ca674c72e7f52b53486de4dd6ce57f1bd4bd5f762fc9bac281fe244fc314b7ae0edda99981b88d932eb1864c6d0c018750c14b410c38a5183182fbc00062ff0d21df14f1cc69818861017d8e18211b800e602a216906941981674a005575ad0d3dd75b250de640dd358579562e881a10318303062981c84f1120601617aba3bce2cadd24a6fb95222167cc10213b0a0b6c3821f2f1bab5bb522be76b602225680c30a4e5f50f1c5952fba2f72ba6705595dbd600c96a5175478a14377ec028e2e9ee822d645933854a0c4ec3a0f63f86bf95a9f5915ac5240c7ac52958214c890821e5c8ce1820a131755b828c0166d6c91832db66c81650b225bc8ce579d12c79dafba148e2b8f187f55e2b2ce572ce944fc73222e9335cf37e9995679f31bce411b82b3cffb9acb0367df85f86bd9ad2c625a05673eb3d251d04201102da2d0226b21d3c294451d597c208b2759d49c004c77c7d0fb259cc398bd559c8dff379bbf0fcf5c33eb5dbe16e75d8797c47ce5b7ba3f3b410a587081851558502c6cae40e38a1eae306245195680b1225b81002b7e7477e4e1f9190dbd5ca3516f5639b35765894c5001135013d06002ef8eddfc2bdf9385b55502232588a18a31aa6041153854714345185460a142670a1a4ce1c4143e4c219b42680aefee88333ff7a95ac6d94b7bcf6619b4c4abc4602dbfac93996669bd18abc39fcc94ba32066f61959daf705f3b5fddce579dd792628a9b36492184149f143048f123768f71dff92a1a01918008cc1d603e00468299218a39a24041146114a88eab0378c6f6f318fcef91f3ac32b647cec23f2d51f6308d753ff826bcd91bfbf953fe6cfd60896716090a16406105144140f103858f66c58ece269db4f3afe5fc18cb59c10bce1cd3a0fb572abd557a9b128669e8d303c3f46fb2ee80d893372afbe9c957adef7da55e75cd87fd05bf6b9f10d3fd04982770e82cc312f704932748e858cbb8af2d27c2b49ce812e67c4ee951aec526277e447c932b6d89c0daacf23c1164114127829d10a4417b8f2ed12b65f83d09e4c362bd90e8809e040a4100be60f1654b47fcc5a6892f9ac02156fb8519d6ddafb6891540c00508bc74c77ac1f94ca0c104154cd4989031410213ed65092f4a5e927c208d0f68f9c0079078604cab5498e68f41f198315805b4a177f706b4a12b794c752c5606bbbf494c5561eebdd92f61fbb5fb3356c37f672ebde2e497e481214b9cb1c40596b86189205dbce8027639d279f2afdb7a1fcb9faef3997d7545d1debff2d11aae76fe2cfe0533385bc90e88a0036007541c0883035dbafb63b055942914be3435511c686103606c4089fe9f3ea361ac2a2951a6af28d17a43031dd000150d0809230908242193084006ecc88017549b32a083acfd05bfdb79540ae5bef355adf3d52ba793208dc66e12d3e9f3bddbf92ae20b7e5d18f358e990213163ebd9d69021ce6252e42a426a418917fce487b9c4c1e5082e52b81c718981cb09486cd11d59ab18e66432f749ceea609dafa2c73a8a298cc2b1eb280da5f7352c6b9efc6b67d585c40e1226f4116558dd1161aad1115f3e893b02cb6c1d71a46593ca28988401336618d0a11d031d064830c2099311b9eeba6b8196c4dc1bb113bb9fbf7cc2b7791e8ddd3f9a5616be932348409f77d223fb271790e2025cbabb94ce055edf4dae7fabf6d2a5d8ed316ec51e8a05e6b0c0062cd000a13659a0c723b6b30815148183a9889dee8ea197a3e1db6220063d0f193264487c1bdeb2c496275b86b6f46c4161cb08dd6d439b88a882082b2622a274f4bc1bde0cc6727d1abb1410caa873d94f2bd3f1554cfd12c595c5b214f6e10ee55d2a49c7575d95b2cebba4eea795012539110742194d2b23e2c7ac550133ba3b7a1e755281fc49157040a6b7bf6f93444b7c5e8f65edc3f8de252cd62b8336acc13e9a8730a3bb7b882fdd1d6d6b88af3b0e41430f4142377e1a0dc42d21c07816220bceaca09d499c10b58f662148c0996fa280151d3f9a294081ee6e1f97ab6a58d62630c50488304de0278044026848c0879b1b9f59a44abbae8bf597b494400b125a685a9e680940104f04d10501640a0208103e00c20820baee9066b686e4eeac95cf6c87e4441ce9a379fe95ade21092d26a6725f45272e93c1fcd3e5d75edcc57b1be4d667c63abf3e0befadf2c931f3cf003961f8e7ca0c387287ce0a28afe61eb01f52066043d2ca0075b0f4d786883071af000040f3c3cf0d8e14b775d90afdcbb944e902ba6ba6c6b18fb68065d915669b7fa68f66b69961964b9c294e5872c48225046048488404f0472202006021a80c01104801ea0830708f180dc035ed0a14c77f833bd506241beeab08a85a77ca45890af62a7b37a75917a38d3eea3af2af35c255375afce67b6eb522f9451e7acd057b2ced67095f6368a3ffad12057d77d20ad6159eb7c15f363ef64a5511ca40314930e26981c40c6015238408b036c1dbb178bf5ea3c097aec5e9d7bec96c48c1fc4b8c562bd3a49143f9a5755d6b06ce283fa68f6ac8df9e0994f0f6c7ab6015da84c9132c5a3cdda56038e7832c5612a53eedb09622953fc6baf06c4d0dd3e2c960fcdb1f4574f4fcefe789e9455068460c262069621b034e978bd550c6dfe5aced622e9b46901255840071640846901411d73727254393a4ec493b2cea1f82aa6507eb3b7eb72c0410e3030e570450e52e4f0c59483027208731082d3e32efc04f957235f455fc5940ecac8573e3dee4284c1c2b7d909a63adcd70ee5b996c1d674bd600ad0a2805a6d29c08454f6280de513871e74475c0b073034f6c2414b96d3438943cd16e1e009a0a39b4902b848008d558ab39e5b9b31f5982901347cb5a62b7774479f57cfcca88811f04a92e98a90e98a4d38453833852818e47ac8f5e44ce88ea99cbca1a848c12b9a8b5da7137f62597339fe3ac7d9a3b43a3df4268df14c1aabd4840b010e02381bae8437565de7333be94a4ed312104b499608005e017a31af62f628cd56e9ade1eca53da67e671ec154764186c274f304bace57b1abf4365b5d5ccdacdb1a8e564bf3f568ae14b472ff684c0b6fe9ee9609d3206bcb8483442aafcdb92ff2f161b15e3d336b7b72f6a767d6b258af6b80394c564670adcc4c565c307d68983e2e114b5a938138d5a13c530fbd6ae3f43c8aa357be4f2bb321a6379c307f55be124cd60a4b3bcada376d2dff4d16258dcebaae5aff9877e473bf47f64f303662b1eeb5f72e995557c6f6a392536452296224f7b39aea923beea0a9b2a68a88dfb5428d89c796377c10be0dd642cd1d4a4b92d400d15df3c38f0661e8dafbd3d6f8d05dd3c30e5e6c65ba25ee8b90b051f1c4649bb1d5335376305549e3892a5d5a70531559054a15a52a475568f09945b9a9ca0f13f582461163a62dd8ea59fbd5d430d558505b8195dfb54238578a69f227633a24677d5a6b6684636052f8d1179e19e17fa1fa776674ff0393aafcae15c26096d70ad95975cd02b10afacc118fe9e98158e2686de12fddd486bb8c2f99abc4fd3aaa4229e912c694ca149594291e5b7707532ff2fbc38a98eef82d2b56b0745bc9e9c6d40a09dd31ffed6693be32f10b135ddf97eef881b64c77fc9bc5368b68bb3e591ababbadc7a46a46fd124ff5ab4e6e6522a6556a8b3730b1bb69e9be4589d35d372f4c4789ab96b63c2f318fc86687ad4b77bc56565b29980a63d6b6d45502cdfe7e458c803e3e3e9e47633e3d30d80dacf4a32fd4d0a8fd5073d57e9c685bd0be8ef16fde7558ba2a762c56a5d403679947e2c752f68a5e77adc7229176518765eb32066747713c6fa6c40cca2c8607e3c33732679065c6a60859c812203b8a5385bdcffee73659c436c7f94b3c761e3f36b33e640828cbc9592d0c56e9adf321d1b152ec8cd817f914c786ba5b4e40da709249240c9d19dd0aba06743bf16b39e71a8de29ae4a924949187d54eb759e2d0c3f8c30a23a33baa42ef334c0758d7ed081083001f2a6c5031e244c501548ca880709a42c51423a604650c4ec7d2f3d31e3683c1baff507edfa11c5bdc4fd0dfdacb5791a8eb62a68ee3ccfa077a0dfbeb24650a293e48497280340e20e60058ba63175699aa602765561b4351e966b5b14e8ad2077673b66e98e30631372871bac1deb0a372168eaba1d410ca08e9069b28248852eb686b38e950ea800206142f1eb5b9cd2ea3352cbd2416eb0514fd890e9ec8e0c9104f983c01a234859255a2e1c5c6ab03afdaeb3f2976b453d54fcd28956a531dea97ecad73cf935ffd512c963c253520099624c209490d24213a7bb6aac0d47cd9b5286fb9bc6fc318365c4002363cc08604d87073b281c7f48c705fa472564a07657474e5c87674c4480d232e464418796d8b7c151fcb5c88a1f799568afb7a8b70d10aa7a21188a42092111960684888a125a7a11f273f383961c3c91627312721505183d7ddf1710d37a337cfb6e2fb9fe36a7f2af5d5575bc39e9337efbce54358d7c80e61e5bfe1cef3680dbfadf2ab0d61d662f9d5d0f1da2c9333294b723dd11d5d374dd4e86e277d6a72812651dcfef82aa670b514e52f17916b88c56a6599cc52962a42659abb89f86d762d9838c164034c8c60626322c4440421129c847c6867392b7c9b1773b5d22848bbf26775f92aa630c558a23cf452ab47422d096249cf92108272109446d0114114089205bd10040290088066402afc74f19325623b31c5adee7ff26b47ee3185f2bfd253b44a510e942a4219396bbaaf52a8228c3262dde8cb5771465d55a58ca7d6c9fbdd953815be56deff501efd985a55b47e68b14e34a841030db918daecf8bb1139cbd62b71ab866596f7bd9f451a086080384e06f0a2bb23954e26c56c2dd24feaf2a1f2be8f8f8f0fae96e2f91f88e55d5229cc47f64f7c70765298cfbc4aca9c947451f275b712a39e32dded3d61bae74bf76cf57c7dffb6ea53cf4e0f093c5cdc2ccf96ce8fa94cc9c99b94293c94a784ee8ee04d4d965bac2d5897d259a507b91cdfbc268db1765077b6582674f70c635a3370d19156e90c5c66f8669801b553a63b565a74dad9d9a911edd0b0e3dd3149991693248916ac94e48bf3948486a64bd5d6561215e2949f93b78f666cbf8be408121264104386214e3230408624477870440547b074a78c3e85a967bb1667248d93112f46964e466a30c2a373f29693b7979111124ca7969344119f8ad08a149d8ac4a0b3860e17295fcd54ad3772aa38e53020474999138e08706e3845701cbf07ded96a76dfca5ac6740ac524e203a2778a1f495849715a6d49e95cd00ae1292deef5d57ab5b39bf29b74b56c631e58eb4995864a081592eae644040d22491099272241447a9c8684b1be9ad56dc67578d29faec3f6fb4963d77a0e7f2ebd4306302675c40e29a0532ac829d5a82650b7136aa85340734a2020a0506256f7f91483173160200629a7184e80410630100183100c51062f2c717a819e5e18800b57b8705d4841081742721d23b61983acbf85a00d6bb8d847f387b3074e6ab3ad97d230665b48727239dc8c938fe15abc8a13b90a2cb880852a58c8e1c402664185130b21ac208315905881ae50e4a44299930a635410e2a482014e2af038a510c529052c93c67c858d7c15696c0524023911ff4101d9225fbd8a948c806041ae1f589416d18ce2e0dc6f347f96651464f44279ea076584fb4a8432024afda08cdcf3242b0534692b56c1ce278d5589420e28c8503889713ac18b13ae9c4e507242905301d028c00f0590a7020831010c139030a1869309dda99f1f6cc46d264aa11ca3dc71a655fa9eb5316ff9cabbb04a15add2e92aa992b44a63b5140fa088d3001230801f804e10344e415e700ad24310a5ee1ea14f41989c4a80a3041594a0815309b8127c4e25fc3865713a8de0a4c3c97512c134839309042713ccc46363039b246c8a4e36454e2490712241cb4fac208dfdf8ca5771e20c5a8bcb11488a28d6f26330dbef6b407c15511e4595c293c67eae5d79b77258b514c368d2d2669593c66a93c662fe389aabfedad9941d15c0152701e4208029027861041d9c465062040498fa34c2d0083f4e22e440042544304284a153087474a7a238113f72224e44b39e1371229451ea0865e4310acac8a3e749998ee7c9d4518ac869d6431911a18c5247ae4a619413392b7c2711678ac336e34c6f3e3db3525b085d8a42c062429f42e86208a8b645a7008411becd6f96a8f74e70005800401a27004cd1dd51fa0400d909003e27206b9c8050e004c4e7042484c6ff85299d94a7308892d19b20975f2b3f96547f84a71f379c7ee89c4088e3044218107c388110e50402cac719271f5dba5993fae79dabba99d1745d8bc293c2c2b7b158387c2791669b6387c3b775298c0adf96947b1f47f9b1e7a1ea635b3bf9e858ebd4434c0bf34f3db8749f7ae45ee8538f26ddddaf530f7ae251a61b9f787ce9eea6a0bde1c4034b6ec9fec9a9a6cca9a689534ded54f34204fa19cdf2963fe9447381eeb6a14f34359c66e838cdbc4089cef2874439eb0f8919bcd663759d0f8956362476b74e9f664e38351ba7fec0a96ba7ee4ebdc21d34b8838a076de8aa2cfbfcd3edcb3d8a551f9db922ce14cb1a823f77cc3b64b0238eeeaee0fd3c7365f9df5f3bc0d881a5630ae51fe8f3df8e9d2057cb8e3ac2d4d1a58e1a4e1d293a78e8a8f9c11a3fc8c00ff00f52c8f5e947657f577f319da3ce3134470b73f890e38b1c5de488d2bdaab64a582d0b95b1658a9489a1cc0f3260c848323b644088e38b3872dd9d42a95878e56e957c1559dd6757b63aabc37d6af51705cbd622dd4c2f18bb51ef6b705c01c703e0288203d5ddb9cbfdacd2dfc06f746fbcdee87963006f88e0031df860091fbcdca8c30d319dc28e33e523b98eff04f92a56231df0f619676bebff0ab9c1a5adc56eb11b51badd50a10d32ba636afe12f5da48a20d0474c7d412f550f331283fcf37f5faf8b8aa86650f8ae881941eacc00619dd5fcbcec6b371840767f0c0071eecece08c1d04b183243a2843075a3a666b6f8d783aee2b6c66fcb10ef7b5bee761a69fe57de5e4e4e8d895ecda9f495ca3d1da4b9b5d95a53f6d4a9a7f2d873e3d19d3a1d0a7681665099b486428d2440724748fe99883ae65ca010362a5d6e69bbdb31cece4e0c71a62566b6869adf175afd1e4263fdfd648a12785753878a34b9cbfd461896be1e02885c201ea961913a67b4c97a431b93eeaee380635e6479c4937b0a23baf79a8e413d7fba0756a4600002028931000003020140bc62332b16c3ee9fd14800162b856b05ea1cae33cc821648c21c400000000000000461b004c9b09795e5624098c79f82d8f62a2db4da8cb9481beb753c7d4fbcc0011a86a0442ea728843db6e9ea28405b06369186c3adf84313ee780fc84c70dd954eafb8e16a8e4389d4f1da75f9f31a087b47002345f0c1bbfd168222388e873103723ea63ca1e609a996a569696e0a3f60d3a08c7bed33fe313dbb6cab83436bbd4b8b9952d20984220b5d43340e31c519134d91a32b30f0eb627444280abb4106955136c0a1596c7216f454370f684804fcbee4ac7a7682ffe0d3458cc1405c2943dbd27b3325f10f50d2f5aaea27f2d3b72e4adc5bd847ac9a6dfdc7c27041afe45d39257f942171e1a335331236d26797a7863c63e830af8a3e51cb410fa0ac629fd6f4a50cbcc48f437a1c08bf086cf3f58163f9cb40e3945e635adbc8350628b3b7b34966a4b2e01bf64ec1854e4a8e051e4bfe512fcdcced905a14b317ac6a40f5b2cbc00f80c190bd944b6bb630ba7f03118c8a4273cbd22cc8f9e6087bddb30ebf7a6b6ffc12d590f83dab58de83b9a3782789ca57a4e0fcc97bf2ede6fe54c018879a7dbac20827cd0cd8d97e935d4be20f409bf7581c2daa8bb29a1107bf20d7880db2d0f844e075c715f4eb36a621ebe4123aa00c065e400bfb096963198a776e239c4eb1efe551a5c82b0586a3f708b58a917a50281ed99a5f7e1e5e2939348ff6fafd01272f01f80fb315c175e3f219e0aa4f88ee3094e8e263e282c9b577ecb4e8a2d9d0496310523ed58a01061e5acee370cf5a07ae2c32029e430d5fa0cccd63b5089984902d232b511ff0eaf841fa90869876aab058e62c0870d821609caac5541eabbb8e42da37086971958920080bab497b46cb2b4b68a49260ff7573c5c9d89804227f2851aecad918ffea473d6ccc8985ab2d3797b4b868f9e5d6af03906a6027d77b8d71126b606831de9d2036ef4ddb4d2f4ffb2f3f5b5226bc027741a26d284f4251ada6b49e69f9378b523f9c12ad2b5288de3218940d0866c2fdf16cc6fae6b6c14deb20bab4735188e10b5dd66fba11123e901c016571bc6568980c9d96d06a1d3181a3a6ccff54eb129946118158fd231f2becaa3123e968f6fdf47ba0de7d2268d9c0903346c1cfa6df49ba212a7a520e919f5ba354cdf68a17b40caccfa6e7e030248d47b152b4c69a91594906cfc4e562844088dc11cdc1e242e82275d6da4b42adad609c6b36451a54abf7dcaf966c0c7a723f476e66e78f61e497f9bc700caf7dba1933ad0f604b6da4287284346d1e129fabafdbdd33bbb7a329a50bd8a029ca7472185f82b83e1e5e16d4a754b7fa3b3ce5f9761c0c7563518d204319a113d57f10c8c30d5714727695f60e7b8e66bf57a61b0b7b0f366c1791d5fbf3ee4fff9cb26c000aff73799c37f20ff7f192b7afd4edf03f814d57e358a5c53422421669ca69ce5550840b8475b1044c1d1c204a61b61af3ea82cf487e90bb4684b045599e9afb1bd551b2f6f1571255d2bea727d2cdeb2bc96045e717d3c866a2afe57b57e43f018e35c37a231220d8c2e3b74a2fd2bae8cc5cdf5f295a3ed21bbdb415af746739cd5a5afc47932751450118c85348455d352f8d61138536c4f6eac0829a3d7c85ae1dce77e8477a2180176e6dff21007ec543ba808a8ee9014fcc8953ae3228ded0297b856cb8babf4bccbcc238e5646c06c88061f154331648b9e51a5db10e04805b189393d592bf228a6764f3fc123a1f6bcb6a5c7a0b6aa078491fd3a65b78381de1687be99254ec0937347f9568980e70652b0fef6901549db3442fda73af177c3e07d5a6beee297f16a4fd0f942a58447b84fd2f8c1d8f721c126c6815bc626cb88eb2d44e92f2cb828aeb9b5f82120e6f7c5ac12ca49461ae18b69806e75305cddd443ebc832826b65fcbbc911366466fd5b8621399cadf3f5e59c04d0bb89475b7ef43ff753e0867516c47ccd4881d1921591c9c102a82371eec375745867e51916fa99dc2ef666257c8d665e05d9098a59788388babe2adf32103ec6661d728f40c7aecc52defd20a2a640107d9963c0abfe1497f9ddebf50b0fb74a79d9f683d5b094760ca50883e0b9f6ac473e7b17535ffd1b6f0e1991841f89a8253278c4953d68994ffff131bc4d17f5f3db01e74df94e0bbb7a21b7821b5d8ab51ce288be1a8cb9a6b6943d252bdc6535a151e6693030f5faecccc008e18042b78f14b4b082db325c21f58a5c85e18248ea611059641e32f41414727278122948112a198d05d14091e53d46074dc24c7ff3b3e3ef8246c8067eb55505655ce1ed4c27ba980a17d52fb6f41352802a9bb3c69248706bbc8f96cc7b5fa03c1686a9b24f82ca13a9491cb727baa70f123f5fe141e90cedd2b2e3c112cf6c86699d24c829ab3ccbe3a4d93b891e8bb57e3dab70076e508882aba4b2e0a0235922f89926e5a59bd352b65343e8c3e2682fab57b36cc73b18141ad8d69ac1149820456831eabc3dd96f787b163b4c5c1e7c5c4e4219c14760a74eddce611a3a7be33fd005236b1242c368becff57eaee707e31740bd999bc1afeabf6508294894d57b3eb7aac9f5222ab1b1b314731cbc2b38a914c266d9ac507850da4109eae721ae79ee1b2c222c20306ab08e04d7af322ee1382f3520da815a522ba98b7a3b82eb643363bfbbb2d4492da5980923f37153be92be0074007448856a67883d0044b52c135dd7ec6804f2777ab7eb848773adafab7f2eb8b143ea30cc60c772ed3d6c97f38ac89cecf23fc41b975080550e7b8bcfb0937643968804a77d67a1757e6d004bf122554b31cfae2e3e7afcd5226e5487be980deeb679523c47f5b715ff96c69ec96f56c5cf357b06ba36c2afc30df38c1f57417ec03ed40913d6c490e4cc3f70e21b20913007c888aa63a7b39bd732ca1be9c8482b151b7c2ccd78c1db6c7483d6c10f7bff1dfe091db70b4b1903695e0f56dcbadf44e072d3dd6262732ab6d0f75264f3d6c7e05533f3988b9599cbe3c4638ff120ee6d0859ad23d1295689043680d7892691fd6444ccea62717e8e11849571c493b2dab75e7b62c3cab656430ec5b6bdbc1363b7a5cefa14ce5a4abc73a2ba451b333158e906ce1129bd9bcdd1e5b524a8d35d43c6f44c633564bd7a2ec710cbe008e89f9baaf3cdd27b83306d68ff1f85598f4139212a1daf97a94d0c12b4d0a4fdfffdcb86cb3a4dfdc78911fdf2d661057422739c62781c2d0985d66a70e40df538c2566ad29af2c75c90aab6aa4f1b2244e2bd1ac5f9f17f857f34fa692e8a921e8bd5762c74db758e23555ffcd8c17acb49e3f6fa41d3ed2bc42b8b2711fc59d0f4b787416f30f18b05db9edd3faad4db22f21e400818c6ac4ff389c9acbf67242b0da4652ac9968d101d96e2a158fcfb819c7d6a0a44607448150a16d1b5a7c3d4f53b09f2174d7f1978512d3f7b1bbb8d3d73c28d627108b76cc98403cf6e52374c0b976c54001eb770d821c59586c4c3829a9bdc765c410316401df09282195f8e2cfa066a3bd912201e8423121ce11b38fcd9853d39991269b63d2d0920cbc629603b68639c8175808f3244162b5fbce135e046104264f16a336f290bf9b339e6ea99f0e9176d0c3eeb11635cab78bb81d04db82ccf3ceef2fc97ddefb3b8ea30bcff557f003c8a464687bac1ed9e4d251cdea62dfd71a2151bca4a6bad751afd2e36fb60d4f8f69409acb329b5e58a8418242130bcc76cd4ef2eca071dd23d1c053a50a6594057e1567f4ada5be2ada1f1e206c39f7b7f80402e3da83c594d87ccce9f0fb74a39f900aaf5d8c2db75db186d4a3f6a4394f80193d7139710b50a59bf463d213963afcdb5058605e454f6891ba1d6c6a3e1d1046b47b83537a0c44f3405e81cada1bd7dace161a3ed676abcfc717ce3ea444b70c194899ccc8d3854d2d2f9445f1b2d4b0aa98da0b0c6236c8a88d1e7b0d38222057aa45e223f3927064629209da4cea3e7c5c1478817588b20202c5d1bed513a0af75aab15e24d40c8ade1cc8c066517a460d5c65d137eedfca6f9a86449a200ec12cd4ca441a724e24eed47e21c414093faae6a9c8b6ad50eb7f297d646637a810cf7f92c0d3f2cf7e8a0df0b1aa7bf03aed13bae12fe6a58bf1947ece4c780918b3b7a926125b1610b56ffa57dca835baf1b3f54c82f33aebdb9f1f0c9840c83e52b87304bda75842a3f11007bef835e8c4fa3358910e54d7c1208fc2c750bdad7e36d0bb3d2a8d60a5defedfee6fa28ccf95d430085705e03f890b5b2aa871387b1e1ec19123a6fdb1e0d3c319625fb7829b804d957a0fbb5f7f926de6ac6ba994a8e857e5e8cadc3885a4a0f57d32e040511fc3dbd86a160765cc251aa9188b267a5225cf23b20ab391cf41a126d70b0867016a3122e3f971308aa40eb913be0750d3522f03e6f0642f503202a4706f973392abeb9f161b5da47a2d82eb47ba57f4110ff5fe78366feeec71fc9fb21195d8ff39228cf55f4c0c2fafc778e1ed5e6151ca79d71ef52ae0a87f77015615658d9f4915d35a5f28d2778bf43ced6c6415981bdaae586ad182137c92b1b65ddfc9cc0ca2fcce039fa81e6e5c9adaa7dee49f4996d696204042871355126cf3d6c6cbda28c33d91fc311d9b870b6ebacca7a96d6d9467e0d4b366a03c535c1b76c11418917969af3d5040807b4588f90868a4b018feeaf743cccf0e72001013396fd42102340639c8353a9381b9a2797224dc589ab87e6d184386814651341e8aa616742e8972eb20194156d2c6a0001100648761083c26fd712a3c8e0a9167a70c6b8da4bb00f1b7ec03d352d2a3ef1399cd5cf3e9d24f970f773aab39edd1e9f6f572203d272b2a361977c81856a0291e106a298399c6b6c342f1d661690a3fd7a4bb6d46c180a99ef183c254330c2e1b0398110e7f797ff868dc323c632afd0924f195c86965285315e907e92c7603535db1ef2a7ebbe6b31266df92478a7d9547246af57067757511f6340dc8e2819414add8970566ef7b231e9a860fece979579836775f3f27af5b0a106eed61c579fe37cf4e40fe09e5d1b3b9dc9dd8a344b3baf93b51b6622b4b94309f6710c0fa7a756a2aa4d90102e4cb31b21b89e5a24a8bc4a5b73bec3a56bdfb82101f80263a25b70f83068dd8d1e64cc98e63b3aeeccb78d6c9e3878b62a9c41abda9f32e3164453e971e6acdf7f29f55818e7dc5cf8d5c1a7bdb1896fba395692a30dee4dfdc509a42c658e854c1bdba8dddd1aec59e43b8a2c0a6d0fb8865c98d269cd04b978eefcf844f76d99251a999e2df85daa8352343c13bb49a0d681ea4c513829e8131c939ffa81a34aec3aae07773adadb9660b79ee1f063b8783e5f4a833a405deb1f5a7991f87d0bd131d8f8168600ddbd0058c3eb0017b83c1b05588996f8ca7ce0562878a9a8266d889a03b5cf0f2fb63be78735f9544ab4cec7ac59c16dda5e488b185b62bd528e9e19ffd4a52e5530df56d0f0a407be88f4de93a16986c0ed4e3e6433a8158e71c20d23c0bbfc107c79526e4557e05e681754b0571f8e8a5f7b03bdcad40d29fffbd6ea56a614b41cea3942dd73d6ba7c347ea9471caa6ebf7d7ab348fcb822b808929cf9dad5741f9556a6c73af196d4bf904222325a45a9e906976e93fe647b8d8adf09e5861e510a821b54adc469d9d3eac678229742a0312da848336eb6db59955c445d3f376f6874057af80d7dec8bcd18ccf140fd6b0831148c775656fd9fdea9c539f62adbfb21f3bd978e3926f4e64fdfc806779260b650e6d6cd0a0d534449e428a18620c98e070876f9a3daa5e5c5c8363ef1b6f4bacd049ae85b09707c1a5eccb2b26e5deb424523ca53d307b01855b4b62f416e2513eb84ef45f6a4f2f4d6d03edbbba4b05b8501561907c58cf8b106d6e2ef3b4bc1605a2ab601c36be51116a617b2c2eeed06e44027bc7b1f4cb023e3aa5de92803782256b75c5a0c7e9e30ae6c0812ece56e00b160d1a47562fbfd22db64204ea2657f713ff995cfec26972b056dd41671e17bd693c81feafbad81f73022d5f5e955f13a1de1a6b2f4fc4b975d0b1b21b4a213e4c67850abd75569df51a3c516d11577f2ba23d320b1b2e852469f02d762ef1684d514a8de7c7c7c4068f2475c52d2058964a6fe272491712c254e183cc293667605b9afe4c7151d6b79d3c4eb2f493e2fcb1afe4753e212fea6daf32293597b00035c4a0d08268ed71fb9deb84b5e5dceb2680026cedff5902994a259c44373cf7b15ec29e0893994772278f74280f5068023a0ee7b7b03393f0ef95f6acf13b6f4f3d3543124c867e5ea070a4fd85fdb7ff604b8ed13bc6a747abb9843f55de90478b66a21861d86efae0a8e53d0fb17fa9d055afe7a9e2c8c3f007c874fb6814077fc863f66f4141a48600ff7236b7602666a599ada2d22e6e0a968c803153acc98959906c20e6aab31be32554f4719a89b1a2680d12e9dbec0255699f3ea87214c999ce0c86fb1a23d7dd6d40c225bd449265bf500f6d6a01d7b50883eb7e4d32e0e657b50e39e36e1118274435dbbd6b30ce624509cd7894cb910836478f7fb2a15611ca792178d57f78984459496e97894409337b6fba4fa1d807f21a1d930801ec10608091e3fd4768f5f4b513906c11c750b15e72d4e6c55ecc9f87ce9f4100a29ed52fc29d936356e72a82f24966ea33213db9ed55439f90e7fc720c516a68e6a740d0c08cbc83f5aca4259cba5b2adce4b1fb689ebfab5ac149ca9957a6c801dd93b64fc75b4fa8f9ac3930145710c63f3e78ca0fbffd058d447b941815fc38ae182c1ae539b253bdf1d3b43829bce332157d12743c76e2a30826cb9de44a8415097f876b6822c22d094d35618045444bc515aa0ca28f3f14c24f0fdc1e2d3e0f6d1410f37c88e1057c35d679908e8f50e40c91e350472d468d34590ebd05a11b88587b8da6c8a2be46370a9bef2b2d42cb30e87904b5f6e345d335336bdac3f37781f8abfe29f85b9a4cb8d450a78cdda1be4a18b3f31908f2ce85805a0365dc7677793ab8d68b8c7af6438afbd211ff9109f0d322ed630f462f2f954b63d2408c0b2847113a23af6d434d0e746ff24299f9eeb1647e1fa4da63849f01379673dcec6875d470d284a24f9db9ff890a47b1fe0b55755fa998a6b32b88102dbc84f4c5796e7fd2334b6f15335baced92ff0a4cf253a6676c71983cf893eaabd3e93cfefadf56fa4da19a0bedcc46fc5b479fa7180307071475cc03d73cb686f2de4c9fcfb87d14d1cc2bf4d99fcca7b2a3127d1d0738579b8651cc32e3778afd3c698c10c4c1bf2d64a1e41fd4445b1cd10ad427cfd91d0630578aeab84ab548d00ad4a03d85d04edc9f4e8def432ad47ec3ef7ac9d20a44623a4aa3b87cc3a07b14fb0c07d313d02d1bfc704e01999139813ef1586549aabc0c1f984d3cf7df11b3e19ce06f67e36d4093110303fbf0f4668d8dce7a512ad94bc7f6008c98c3b6c036a0c7cb68d983a3c39a7e0d0d63c8a0ee75c70da24dd1d3484904804ad6e1755c92148c51b8d9e90cb9289cfad2180275a015408d83bc7ce12207bc48a61d1b9519839e081390850d51319855e220c5df296c52f1fdb01e25db2d048866b58de962590ce337cf77f986eac751857f1392a64f79707a3ad42bf6f1186414c7514cc5a5e2394c4ce8ecafa598f4f0740b7e06c982da5f7f6c866e4f12b07db104ff3f264504643826048cf83355b0323765b9330293837056746fa9cfbfc423e7eb7e96d0b784e53679e557bd2e24199f122a1c849de09a72aac58c58a18d1f44e116fa914c129b325f1c2e01cd00a4462d68f2d5765cd794064c37e278b90f351057fc2beec202c946bab29efd3693ca8fc6904c81a8ef85de40e3c3811ac6442ded8051ec73b2c8660982b8b271145b8d68477764362962880474e9765358c39295a8fbbfaa0c74cc2a2081888d02b6f094f9d72a9f722fb1ed0731a00ae9d41937ce9a420b850066b515d6a96e209c03433857fce0c51bed1a1cc8e8aadb4a60c999b8a894e7e351f5d470c74a5ce15c1617dacf4cd5ad97d738365df496fcabcf37998b52604ac87304a0ad52b5ed19b720b66216f59c48e8ecf3dbe906b1b271826f2c5872c55778ba6cd9a6ea1a42fab8ab515d39f6c23ad107179594ed09078d4ba3c8c7e104adc9881fce03190c68cad30b398d88c24f4f801f46252b6f12343084f844ada05d13e1b33c220904e913a2dc63d3dee26f15c4cf27533a8fa7f8e30d3da3950f93229f4da06748b773c07c24bd0d59a0ea502741418a980389a52ae296a3380219457e9493b46400291732e3fe7ca259a25e8c58aa173ef66abf170eeb4bf1f2e591b4952182315a9860a117c97c3ea7fce33a1a9334d1b7d7862fefdff14f68c0f1606f2c51524bfec7d4297fcb2d3100d1a7aedae7e05333a16448d3a7f0b4829c60b330e672dcb38c356804b8790c478ef74f61fb96e3c90cd01c19f0ae0a6094b7c3089c6e1cc396573d8c0783d561b072a6a3bac71d8a391e69be35442737055691335886d5bf2b264b7771892920140ab9c1ba4d7fd81c6f561e8e1344662c1769566d87101806eb9e1b9e5eb21a7b92c2e5ddc85d98b758e8935a37dc86dfb6ec9f460f80feb6ec7c2c5b929fd6faa2d7d692377f3b8e4bb33c898942c2c23e3a332f2796e88e22f720af86f8650e7710ecaccdc5879bad1d5e46c41ff96ede80bc0b69e64d3dd167915d149ae8e7c3bf8cb5fb0911f2794ce0bc68237a881231990eb324cbddb9b575f86cda0678d39c0aa054a20b2521396f363198fd1acffcff81585cc255115c2fbff2e3bc218afc2b4da254ae2d337c4e1faefb532ee53d8065161495441ac587cfd391717979bfc274924a39e4dcd2554ba1533a888da1cb52a47ea8e082b4a18b86e48cfe3acc54d2f4c64c82d22429eba88b1e9e663304b95df3e22509666551bf971dd3cb5fc054a82b2e0212600e549b476e726010037c6615cab92849bd247046008e9dca88207ddc5cc36310cc88bb284d0836a66cd231340f36f3ff6fce1e5bbd74991ae4364442d04635e6a9d8fcfa52a4425ae7c82df238a8be7e63217ffd6ac3104c988e2894caf1a12450da86b29599c4fb17097e4f9a8e7ee167d164d1990ad117a08469aedaabac3c919c301b5babc1fef4e135382f3849deb3aba67a045319c5b2d61d8427f138d741b8179bd8f6d36e73e4baabfef963e208ff419e65143c7a028394e227c53502eec93591522dae8726ecc0d5baa77e73f5ac39707c27fb1004ae16bf10fc565d31d4eb381c6cbeaea0e4f3b99ab9f6e30cb455a017996c0fa7ae1eace7dd644f8f6ed2e9d9171461403977559dea507539d8157e52a698a82dc88ff53678c3d0af010a441bb0107dfbdf19ba403412bb3a41bfb7468b6258a77f2d1e18434b97e09385bb74e90b03abf7a9a029d780ba2cf0efa68700a99343152dfa6adad5123f70c3d9eb4c85e3ecff798e54045b3dfe0fffe428bf31c611ab08257d3a75b296d2da6d7b94c2af28ebe1fa78b4cfa6a24762cee53b29b85cf10f3c42b401846fa1d800e6e549afc70e9884237f520da7a68a0bbf765872b57f26bf29425e10c0770dd192a94944d50d6a0654bd62e3513bcfa1648e339abcda083f8a522e3ddb0b4113c5b8e955f267a5065b64eed0c24c983cedf3a36e101afa0ddec9e7a2c607abab235b13f794d2bbe88e585dcd959693a93cb0118f8392a649b26f16ef1f93232a1fd95c522c740393310ec318d5a37dc382fc3ad1fe3fdb64cf44a71053f0ee0cb60b57efb47a683eec6ef4abff5fd41d8b055abc79364e2b960376d26ac7300ee4ea583dbfad6f2784362e8a9489aef24c4ab262b63df667dda2ae6d9c3eed0ff5a445d4f031369dabc861db4a74b0c5124f082e864e3531d483c780c009c2a66de1d0be999ad2deaa746500c2ba2e4c797ed4f57376ab2d2ba017af1ccdc1ff343105e4450dc9172bcaf03966a065669982f443f3cc572154758637eb7b02f3c396249699b59a461a74df339b3f967b1269d1f5551e78c8a40bcea004cd0fd216664868867f29524eb75efd9bb71e0f08f9f21314803697c583e9384ff5da01b7692606cb6c51356ab399e3a41130e782422102cfc5a095c3a918b06b1e2869730590f408d5d478367f5721e368d54e75d727594a778ac4a3e188a44305f0c611cf1c7ba90b0f284f52a245ac0e5667b3bfe9bfa32d077124189fca04c8fb7fecdb48c99d96d497c1fff7945c48c2a13a9c4ff0885a25d5fb843e7f80e21b7234335141d008ea78c3df60959c8467398beb19c997128ed67b122def88facf5c52f86f7aa1c65ef017ee387344a35c6e2bafccd256f35d5ca195cc43e88deec202bce1fcde419fd59d3abf12067be1d67d06c07adc87eff05ef3ebed3fa5b9621f0f3cba6b19d26009952968f7596f313dcdcc0ca6a423578720a1d430582ac2908a7bd295c8992353bb14a092dbddc4a2b9c6264a4dfcbf26f0e8fa4bd8d64e97081c7d1477365f97f79f950df70e9aae1224462120cb029c635b8cfb39b3653f13f795e3f2094937cfeffca4ccc8c09b8334ffaa1ae8750024ad9fb89fdded472fbc6ab425f20e96dd2aea6acb4f2d15830889a0531cf9dde2bcd713eacc09648bb7609be257521d59f2532de6198ee98cdecefde9a1751916c76494ad36020b95c6b8e0a83680eb4f44297ce15fdb21c6be70a170f6b3813f63e1eb0ddf1b239e80e95c1fc49f25672cfc0d90f849fdde9c3bf090e6da84e30e999500ee7337e691d71eff4df09e30c3bb222a55c1850df266e1f74c2af02c69bfc06c2f46d8656ab10151600a57737588e18e3ddaf228643cbcbe77487e3b9b5f14d4c8464e7e980d406efb926d465f5cd51d1c1dbbf12fc3d8cd4e43cc8eb91bb477679b47d7288e8f0c3ecbc2e52df50d882682b8911f6c5a05b27bae01988015d59ce3c3e032ba4ef2d7c2d9514318021404a9cb6475c559344fb1450b148bd8de464b2ac2e2b89cbb4b7ef079424a5b4705817ec876363262181dda41d8001a071411987a54eee566b1608ba445bad5ea61eb6fcfbb219dbc2c5ddb90a2c502cc9370288ac84e3e6d54ed60c690f1198778c213f9466fe8dfd7037a13744da90bca11633cb1e4c23776b90383b5ec52abac49558aa2e7c74d1bdbfc58e39531fb0c312705d4ead7e6f1ecf709a7173a8ab4e97cfe5ebf2644cd4738a9dba58f948316fc4dfa301186144c8a801ca7f889ef6091c811d108ddb5721b4684acad063fbf0a28c1a1b467ead6d45d7077af719219078843f3885a8e711b4be17123ace7a5f845b8fcb4da74ae5c847ca4dd3e49b65eb28877f1c89731902bef392605724ae61300a5f573f53a74f6bd9ee47ba098e2656df384a4a1a1d9b04df1d000a89ab229448d7bc6e62f9a399e30c89476593f5116b67484c6396dbfa9c863342f2af43cb0ed016852c07a1a6e94290fd82a901d2f25d0940a4df13a90a82d156a0c6db95e7ac70e622b829da16f6aa1e3d6d50d491d735a308de22af118d610934a3aa71189c5c3579f7d256755cc6379cabc02e5941225aa76a406fd3bfff7040381c01ba0fdd52395cc6567860ae2c47b31d62e9637471072611c886201253897644fbafbeee42b7512381d3bcb76d63bb465cf8b52c0bb3138ec68f3da34ef533edee7fd38877fe1dab45308da756d0a0d4dcf636d6cd5c09c61114a4cc28548121e9775b72e9fbc6ea6baf2ebf2e11a650ace454382e9ee75185a79e4e1e8cccb83f9987b3ffd946391d1724dee56532b60fc5e9c304dcffc8fd6d7c2638e87b8e0c89f227f28962fa9aba2ec7daeb5fc9a309d00ab4e8e0c4ab70bef20077f5d47794cef872f463a70f1c2cd99f50c6a176febcc741c9c1751e9892c73bf40be3b5471fb7d01fcb22397aae5dc2eb5f86bfb5d1ae5c85a384c362d1f9e58ad5840321e911bee8c449bd489bd07ff9c7442defde6ab9827fe8b20c4b105750d5be9fef585193b761faffb2a82ce4b535f8fe30c77b2ebf178dde7f0e484a4be4231e00a31dd514806505c1c46b3e6882fc31305073cf71b490a1e6eca614fee30c70485a97d470e1711e7759fedae6a25efc99d7a2c7dffe2fc7ffcd17be07d5ed178b2611152c82c69181fc751cf77d3b7fe8a93c7a9c04df6d7f1dd3d3e7fb2da6077bc637cf9b7c880e21e1cca517f0817da785997eb97c99bc08adccfa5610b78653c20a12888404470bfc896d4d03d2d9cf6396434126dd326a97733998f11e82ba88c456a1a897bf512aad9fca3500dcb2528128101a395e63b5bc6ffd24c069b8f5efc7de3710f5f458f48e279e9daf8011b60936c982df8733c5c275fec22222a7101f5c22c985ad1b890ba73a82fbaa697952833745d871d710b49bc5730a4189c90c14dbdcc1a0a49c3535a6cba9d394480ab004d2eed7acac25ec33c0eb3cecd59e98d8db11a1d84c15b03779ec0bcaabfbe04939211e48fc40244dd0499c3e075753e6159e0df8b6cdcdf595fde2531b193e435fe0fea9aec993d7f0b6d492c656904fc509f847516510e3109bef7f93e5c441845250ab4cb3b3d2cafb7c0d1ddc6990f33f94abd402c1755ea57a2996e1b774e5ab144b454742140c7243f8fbcaac21a2308baaf947f5971ded9372e0203b26b53c379d6fcc30e86de854320554b32e889bac7396b40561e7276de5c79d3c871f33878f984af500d76cc73229b39f2f6604cd5035d96dc396174d9d854461042fd80edd7ba511eb84f5bce64f05efebe22d3d274f4947b5a12a2002174ca5ccdcfbfff1064f612a49116e17d06b2332b310899e8e04c2ebc55e15523d411f7bc3249eab2d3d0ebb311dd86f9fcc5fe81ea109f8bdd57aa0030de1cfb89eb916cf9bd81e786e29bf627709d335a20bdfcb332a7bac7b5bed134b90e9e094ab1c2c654c7898a5ead3c352b313095b55ec91cde6aec6ba0d4643a65266cb22668dd9b8cd8bb333c8765ecad3a86bca291deeca48a15d7b24ebfa96954f699d41d1b624b03f55322c605b0d3f8f3066b79e53d2c43315e5cd14b0d8411a5378a7afc745c5974799a74e13c5500e2831a0e7353d91b0fb64a2e4f7cc3ca6d29f06f489827243b0299d19665a3fbc1e1a4e3922a7b83177e5cf012601c6c4bc460676ef8dbcc47ce367e4dcb2efd596f0ba98d688e198fdcf488c94f6fef27d368a419684b3aa1024f7c7c0d884aeae60f66996b998fa8b29dd71e46d7a2c6944426dcba89e9447d30afe444f69924c9cbf9986577d0b9929710928da1cff9a8b85cefdb79c1b21bb12c513119bf9694884c8eaefba81dd4893c93e0d97bb8b70ab0843e0d36a24d17747a7e7dc26db9bb61316f94113af354b21e46b608e7d6a57b3aaadb3402f68b8151cc740aa0eb10ee8da1e3003bfb004cf0132ed0289fe784d7c8af65ebce7d86ce1e12d438219b85389e7c67d727c9be6683a12871975e3785ed7ea43f3275a3b78b08c8ff8bd2cf4c2d3dbec2f39544dc726493ab3ef2536f313e6a77bb6d623d8e8e1b925035b53a66b429ef77111b22d3f9db082c9e24d5953a28d818bd47ff27b602ff680bf42f98461e12166a841f4e1227f83a97d0ba85f057257243dfec59ff6e8a16238188228f8d416be52ed655cb0f5b8d7ac508023a981cf238d385a66eb102647e6e2185bae0c4568c1efb09af0cea464cc2673eb0dd5263e473529a6b66e643a68bcbd5a15a0d817ca9a10997debfbc8bcd4bd0ccece7fed8b3d5ef0492dfe676c7bfbea2b52e792204566c96c39154b4a62f2c031cd0761a21ac84a8a9c694d53251b544315675a40e9b407f4807b8dcb229be9a54fdb4eb0a8e58ef6e83f64e60c5397ff2e62448ca933009c111b85c53b247456a8e0cfeb56f9f0f31db62cfddcb24cf35a54951a7724a5dea6139df116a6102239d2d6b2734e0b9762b3e0d11cbdb7ecdf3ddc8262504ac39e0fc33de223abea3e3bffff553220fd7c449afe7c0d88a5218d28b0ae7c597da4638503d427903917faaf9df0df0b526bbef8ca7427706644f8fa3e83610206378234a5605d68ab44f7549f7bc04bd3786f33948b60d25225c619da3fad7b76b38cde5bb24ffbc6f36eee4d57117037851707b10fd5b2345c786340c2156fb785fd1a24277bfb9a82f52be0c448104281cdf1dd4fc44bbc0ea535b918cebccba708f78637e2fc23e67849ca2da7055977fa38c8fbf2420b3d68df73d47f10afa87dcbe4315d8fca16bc62ec365f7ef8584d43be3cbadba65bbd11889596c90d8765e5f632487329acfd2192b74c4bbce73869f68da7e364b1d87cdeccc48547ee376fd39bfed6791e9df7fb7618b71342c74d4cf9706f9a4cc4c7daf4c59e5159eabde73f4db0c164ad5b5986d614bf8263ac728375e2a722c1db8ea82cb74aa312b5d85b66ea1fdf6bf2a6c8e781303f51d0d89995364e86d46b70f72baff39b3e822933376bfd511ff4fbd877ded65a629cb433e8cb1b313333bc0336ea17069d8c460c9dd54fbe16ecb198563e4aca3f98ed055befe295a58bfe05018819cb973a327ddc44c0536c1a8aa511ca8694549dcce404661bdbd14f915df2c6ebe782e73ef988a31b96a025608d021882b68244c841ef86217ed97146e3d59e84dbc61290cb312d4c20271f55f2a8931a4b1491113401ab6cbbb94e8a0151282eaf34eb423b31bff23745a752e1aed2fc57568ce222b8efec217ab499146b3741eb9433107137326b8c5d3411ce467fcb4fbad9971f5cab0334025f33a6d5eac4baf8caa953fd20418f3a08296ed1e9c69ad84f9f726c98465cfc0c440a3ea6b57fc0f8daf160dc557219709cab043432a9dc01de9f8bf4f551a1ab22d802d66793c887da0c079b3a2daf731cbaeb58cb648c6e350b3118bcb80b5be4fd7f2dee182271e7935c0466aad2d31a12f339c0d52029b5108d0702b9ee9aad2c1d0cda345408f90cdd2d60ae9bccceff4f921a8a323d3d5ac6af26e61db8cf7e8a0d8f00c907cedd730ed13a3182ed2871c1c9a2e49d40f5454eb101e9cd94b7a805120bd0e948d34bacac14f96d8e3dc6a262f3278cf3fdcb0e460618db29ce2df78e39e83d9c7773b3ee3f8e24f4e985e78ba3e307972d9fc277b0687365208ea4c1d38285bf1b1ebd6c386055c20145d8e6060d297c67962d049aca38828fcfe5bc8786c74cc5c2c21c0424839984708b7170cb78577aed3690e62041bd03748448f749d169cac92db3e24de44a5bf5f108c379599d42cd898235c907357437c2367167ca841ca4652ef32556f590475586821270b2cbded67fc0786905064d14c580608bce0255d33f21d2949fcf1de07eeb63ac3ecf8b9e8d632fe5baa3997d7c2233a9c37bce1c3052990fe6ec4f1a84fb037fb17a2f0ff6e90efdb52eaf07a0aedb8f3facda4d59fc12611e01a90f71f3657abdc33b0f7d3d02e772f32cc8037ee3935d6b32935830d69c034a1877bb73da3844a5e4a9f5fc6cc12692ba6eecae7c89bccdb462dc7c81edb0a65a97ab965777f8dd6bbed9d734cb36d2493d64012589bd6f529b157c893c866343f17bc87021110dac1ccdc560f257483b5a9f42ce5645f4b773fa84462d7227c85334834764c2e65d0c410a134b5c82e0aa4b35ebcd80987d907ed47ddc5fc9a3552e80bd0ab51a1201e2468e1455f3e7b1ca9b63c6f2dc1641065dfbfbda817b65e6553d74a42479739426c495dd81ad0ece43abd657f564f1ad5360222c8da00d1da0abd66c88176dd4e9ccfa113630606d7817883765665dd308e3ffb5a44a99f0561c2842e3b4e0cefb64b6b01a23f18e5f6b55c04d5b2202091eb47bf66bf19093e0392c6b0c16868cb8e698554ea7683c516a9e6ca7848de0018b77e31d86dd3f06256d0dac0312ab5bdcda836ab8e7cf663a01a2a1a2fd0cb7d5c5f1a8e462519e58642d1f4ceeb9afb76f59f7635fb051e116f555b1378a4432a0633ecf57368b993ffd94e14407e35f9711aa62fef293e824035ddfc3cd5354e21fc9576326ea79121ddd05e12a268064e07d0e023828f16fdb72920c5749765a32afe788067d0a16f8d9c09ae624b065d6cef8e79bcc44c02675fe54964a8236fce226ff020aa951bd64826571ea289017e424a53997be347341abfd865baab5c76fd44475f885329fc7457d2cd24c4bef6163c0b0d294905ca9f3569945a2bf191f72519a05948d7a60937c73628493b0afcb56e30bc0cb43a7eaf02f564dcc00b87a6f18d3372cf3d795b5082e9151e0854d067ecb439a02b17b352ec0374c31177da92308e8a294a00f2b70876d962f6fa30472e909aa6ca540627c651e453e8a3dc8be31fc86b78a76d527596768d9dc328ab584ba9c3a838b71683ccf914184f02c9b86595b556edc67e27d003ece8525105a4497b75b2afa1729b6b3cc5fbe8f03bc7adf08bea68d4f1d1f0691b3dccbc1dc52b44e9247326ac61ad3034e66d3cf1f648d0e1cb3cd89df5fa1dd0d1703be6c78093da98bad0c6f1a5632415cadb8ee7e146804d37f48136a81efe221432bde0a79a0b524c56db635c5dfe6220524a5e2028cd055397a26f85545c7eca12b78ca10faa0b2d88717032d7e816bfea16f0f16b589770f19b8fc850cd2e4e84f8717dfe2433fd774ff40c53f428eb7b89e4d52010334c1f9d27944070c42c64b59251c2eb6117f574bab20ae84404836b346d8391b25bf4236dad98b1b63a7e68ec0aef40502d4f8fc7261d7f63444b7622a10816899e8b8c770db00027133d1cf56716172b3f639b59a701b37af34dc76a7de4776ca77cf504ced0257c27a57e77f274532f4b217177aa9cf28b6bb5523adaea03985391a34f67f06edb10f13e83e7a38279b893db6647c8845a4c0259883577a83e4d3e1c945f044f3d1cf1e687369c3ad036ddddca3b6eeb42dab8ee7b9b81ac8f13750324d9583a1b8b5322b47cd4a040cc5d9f823fc517cc2e3e405aea619c281d02727987a7b134a15de2ff0b560c1d0791daf024011b7340df5da612c44e5eed676debec01f2080390883290a1ca257e103f15a8288c2db9e230f0b004600f6fcbc0b1755ceb073cafe3745497d4f8867d2d109856a73e8d16ed037e07fdeee6e3ab7c67e6a59713e8197ba7a7e8282b82e7a0f9d5ddb34e82c20a3bca7d42a3386c233825b5ecae0800d821066169f955c3effc34f0badefaca5cb16723644d00e4c3e3c564ee266c9c53a66a9d9c05dc2106b15f0e4876d42e342641401e4b8730f323aefc626b4af118df949e027c187f312f8240545fe6f7f14f15fb70388da8805f16d27abfae51cdc10071cbb678b26f6f4299ac1fc26a500c0e9c5827c737070880462100695918d3560ef30a3a41df5f9b433da349de06762e0507e14ddbbd0962c245dcc2b9a060bddd3f41aea6824e2a160b4ce4983e04ff88a1e524c56677d71305ebbea4387e46b28dcffbc20fc7db41a85ecb305fd5f204320f0182fe34bc02ff9100ffbac7e0a6a969b621b1486b9787d4e4ad0543bda6c5e43debc84408268df2b1828d14d0bcfcdab1bf52051ae32df0baef37ea77a0e311b0dc817146643c1b5eeffbe85ad49c757291895b08b65ddb39dae54bb1e0639fdc948440e1a792e7d12cc48bdc7f5bca4cc98f8ebf778de000e92bc5e805a709cd9cae0f9830be3597d545561d3ec418e3a8122188d250cccc578600b39b542ea3e1059c2b563486c897842a89b5196a1c35c480847eaea307fc1ea0ec38d904cb0224d2cb8f5d53afd32b917a4c7fea376030e6da56750540dcf6cb23d760149f7c16344a42f7607e097a3cd985e2b35fd77afe22e04fdc5b0f1c2e483e6b7a05b675c9f6035e29723934d60f050c43d381d328247a17829cf025431b8e7c803561508ebb35091b790b72fa5539927a21ad090e2df510662b897307a424cd380cd252f3f231326bcef276adb13f3d52e461ecfefa94ee89fb3473afbb62b0969f73ffb99d67b21444b644e207839278c6598a96dd5fbc1a185e1abb6395ff4927d14b707a2f1d3faf58f85ddf6ecf5329d8561f814c51de8f6c1f19e07f32bf9323ac5fe6f5bace5b476c4ae403085110bd2ad0585b891208a40b54c1fcb84d33d8cc3d9c47cdce5ae1595c4f80007cf4b1df3b644a123076d9adfe65f2d6a1b22393e3d01733a7185b04cc5f8b6204973269affa3494a963efb2dd603e7950d6056610685079e5d95db507a5c935cd306f02398d1564103613cfafc2a0ecdf7f793f0c21113d2686b6362a6e40f22773b24009ab6e91ab26964612cda4a36bd20cc1e9615cd0f73422a2148ab3116537ecb468e4371b3b65c2042d5b8778946d00c8ed0f8ec2bf70e329b66bf0fd1679d88e35d1c72361e3a30495efc0ee9712edfc27f0b6d6fe539bdecd1d2ed3f40e74792e74ef74ee3c8704ca4347af6e0f44d7a622aa6c1bba98f4d14643754156300cb84fff44f40b36835090dd16e719fc99e694b982988d8f24e9c3a8dcc088d95a7862d863c426fa48724bb0b90f8f78096b59735d7ffd708754e825fe405d3a71c2dc42eebd6099e514dccbdc75ac613c194ac9f0602280a83f98a7563bdb7ac498ea6d024d28719dc3ba132f4a5087a1b8d5d0dfb10d837a17150d1877b87eb3689fb6bd60d373111ddfc6a434983b6a5c0533ad4195359510df316f64046c7117e19b31685e6c60d4d875ce1f216280b00a546b19307ad0e381d007783e58b793a3b5b0e6406c992d0801d0df6c99ea6d6d771d9256ef949b507887a923bde54b2eef110861d33c1558870321d30100af179b872abb3c207d311b7759c32ad6d06daeef3280264afd14814569eb10fa9a18a25b78ef0e2aabfe2660403075a0c9a1c6fe3cf9fe82d8dad96ffd3f407cebc7ed4704c8092e5a8d95cc2e438cc606ac1e092d6ef72758c2d60017803caf0ad413bebd45eda701de08717c768da7b440b433d42d04dd0f6f973df16506a246b2032cf24e01e0826a0262da609b87914d4368bb16ab0c35c16c8cfe3a3cc738ef4e3a56a810c8c62cdc40bb121da1aae6c911907e75f42cd5e0a756212135650e0ead81f63ac5f8c521e522d86f0ce45eb8485f9281bb138b93430395f5e5e7db556b46dabfd0b15a9a47f75d65264f5123ab95422c8e5f8ccfbb55d481f8532eeacedc4f45d86da88a31ae93a0230cd3e45ea2e91624eaa5bc3b63d74f868be2fdedd83c1fdcd24f5c9407e7eecf780c5bc74701b792c788a146dd1107348c8f4cb69a39a93081361854d99546261afa9f2e7cdcea7e3e361063ec8f54e47bfb5cb382690b5036d20e8127437e17053ae7dd9ef5f302e3ac9dadcc197e37a346b3845d95e50e2f023fb184c9948a2bd441d02d840b3baa551082bc50f6c2f5591eb2f94ccf04e2e92aa970d2a53ec382f09c3841f15452f331062e3a5041d89eaca6464d24171c394f3f568962cb119a292da9d6d0ebc0836bc6a791260feedd878947863fc2f30bdb908a479091a50f70cb363740add9b19a26056101634e84226c971caab804dda3fc9475774245ba63453bfc01d3a1ea4771003fbac56a7d9ed25c1032ad0a72d71490e9c0f1eb888c04ca2446af89f6debaa211f1cba467c66f9b6a7f4f541587414fa11df2593eaec07e4ff0702e3716b723e172a41a4e58738019e2c0c22bb8b0daa92370a6c2533899dcda7685b4878e452d22c3a679a60e4e8be9e9c57eacd51d914a3dcd28aacc2b79b2e19173d3bfbc47347ad9f79b704e82b4bb1790546763ebcc0e79965aa6b207b86922d1b24279c28ba44742bee3892b74bad562fef0477547190f8af031c33a1a2a32dc4de3cbd3ba7fa0141ec0d55fe0ddc5f23d423488e13811d9b7b03356a9ee70d1e919252d542f4534ad0836817c53a76ed9dc4d45980654952305b73a36ee7964e7f94c7f33c22ae2e9d385505ea0b89fde8015c7a687840029af9eda6b109a4890a5a8ee18842210ba13602811fbaed726eea2d95cdd7834bc9df1db190db964d058b1f985ceb10b50f94fe1a7e65747bbd457b9dff8f80eb00539a7336d2b681619eedf33a09e5f4f96ed3fe12c6e93a7e259386865e6bb8d0778ede5c08c95939e6958adc40eafd8189cfffb2c65f99f4c9344bd7b29e470f32c874fd102b3dccd6bcca3e9c191ba38e3d2c91a0801a2032907f7c2c920085ba8a71b7b9939a0961dc9f796c0187cdbd07919eee538f47a6bddc982cd49c4ffd129e76933de8e158f44e1353c704c26e42891897f58cc8b2349a67859289c30e9852c974c4030d398932ff5a1cda80abaabba6ce93ef20d8d8392d4a0a3e6c7121c9cc24190ab68dcc762df4015eef827acccf11f554ceb6594ac7c2cb6e51ec7c03c3e163b942a750bfc7f4f1539c33073c142f0b1be9a69965399411dd3f6c4df9f5d9912eb3ed09e1191e3093dc1496e88ecd03654e65bc1ecb14ed14a60ebbc913cef32bff7f8f063f43a242e4b3402afca766719d56fd5325b3f1788d49b7fa3742d5e3d1b0c8c7a1ad9ef0100035f7d10a50ae442e4d2d9c6c8417fdd3cb3919b9a2bed815238e33b1161a69aec9ca393a875fd823e8ce9221a276e2b6c13b3427167c99f768b31db70f8f56648071e73e257eaed4756bcf9ef34286b3661a23f93f41eaff6e00b6070257eb736ef34aca3e06002ff8ebfe27ef0f3d65411087707822f40139e3223cc1cad7af9dd21afc0a6632e0e87e838fc3c112a695e1634eccf67dea9e761fcb4c24f0a7ffdf576b1b1c1d5c6734a50b3621a1768330275714d8ee24e91dc05f7e6871fbf2a20b1a7346fbcffb614e251bfd8fef687dfff77d06dea4d1e09ef2fcdbeebe6ffd56f4f9c84ea71e97255f819a5ce34d406435f24d75a1e1f2454410768a5a780d6cda24647a5f968b418c5739aea413e21c8739680824e1cb4f2e23feb5c30abe397e0e0da979fe79918f4bbecee5ebde3df7ec169ff1001f6c8a8410eb5c146d2caa3d36e11c7ae20a651ff4c49999c0c76e19991ef4ebb247fe84970837c9fef1752cf4da64df791adee734ccd1703b1967cda82c63dac5979609062423bac67a1707e7dee077330c40e557b5dfedcc785a3621cc2fd423cce8928a314575b0e3c4765335e778be730f55decab94424099b482cfc29def59c8a7dd88d6799a77390c2fa3af9a6d7d60461a26be36525d32ea93333af46bcd989f50878685f61081e87d42ef12d8c8572eac67ec459d29fdcb1c19ce4429163f726b4d86de1cea274d0084dad4b33d7b1c09541fc568b5444593207912ee3023feffecf97234473aba21b7232e6a497f003be931e5542ab8932dbb9450515ce2daee75b64cdc541981cc18baf1dfeedb6d3c76b00d84f9aaefab307b02334e24f24124432ba8ca8d32b6a51e62bcdaf707689bf170571f2e647c8e020d5a7b0584127a37f91bd0577dee6cd8ce19ca30d65a629937811977d423b849c5be4b3871194d13d1c0030bffd4091944b0a488022c9de8898e1aef743643b1f9913d2c2ab610e470fc6bb314b7a80763ed6ee8f8a585721fb1405f6d0c6472c96c81ed766bd466729178dbd1808002445f9ada8057f9a205ff6d03c2abc99b34f9afec32d14342f6343a02656981d58fb747a3b75b15ad7eb40ddf5d366e548869d231f900e85fd774feafe173e23977d2211692c3a9b67112808758cb1c5a6003548a0d1dfca9781e5a9086e9c53be47ae49a18d2bd0ca12306c2ace63d73dc5b9c2948992d06b900df6206930ba312049a632877b351eb4d9846f5de4c543aea061be8bc207885324a38547e7f3d59349d1ec99162d72b78372230daf2a88bd5458272240a729c737d4da7e4779e26221f1b77df5a7cec0b8b205dbff86f71732eab9423b990f2900a7f1d7420bcc7ad82fed3c1b131fac61c6aff72897c9d01cbc8e3e298a00e480e129cc344a236a38bc6e2616df6abae7c1523bc294e4853441792d57728aa18e234c195082b140f8b73d751f18e209a04b2d246df6e50e78c19e752146d54174a780414bfcd8ac2722d1b642df67df3126720a5e47f9f3749f790db51967dd570d05a50559f8f2308532720ed24d2da0840cdf964b575daf006cb5ed43f0f4d53c03f0962c7ee926d6dc18308d79b6956489fa64f7ecf84e123eeecd35f91fe55b3d8a62828db98ac44a27d72186deeee284d268d951fb1a5413bba5d9885737b54b19fb039a29b2e493bd6177cb8b8b6cffb5d130b4c9653f1ee3046de38b05db5966be41298d0179713bd666bdc720a4892d6656f8abf3d8b0f072d070649f09080f687f63c1ed34b7384c3e6b0bf6c18807109f1cf2fa67f3bef9d16c1ea1c6bff3498f6492b1267170f56c789b957ae4561f3d123af3600beafe857d945e7c8433463dc1e965b03ae85109ce253d331dfa4e3332bbf5d443c29d1936e7fd37c0bf41226c40c0d4c3f8d923f16cb9c57db5f1ebdcefcade110f8b40406d8e4f63d89b86ef0a199d8e21b224d3394322833c95ce1c12c20c08dfe018b4c1e5dd42c29f953a1f6734af19240f4632d01bd12c897ab7af67a58e7f75430a8a4fe6ecab10b4e8bf556e4c82f1bbfbf875fb5986293f516c9fecc4cec5bc439ebfd7e16eb935f111e5eb20012fd5b9f0f9033421c1b6836560065d44084758f3bebf9a3db94e3922fd9a1e4d3fe7f334225864bb23f7b9a8597bc0e627669a8e7a748c09b83ee7b26b630eebf43485b984f6fd7865ce6359f7623d119bf6e645d34e58e2fc7dfc1c1d4baf8c543a57ead500ce6d6a38657585975d34cdd9bfea4ea6b2b46243545f914f8f08d8c1e1e15d3b0a6884813e0947ce2a3a53c628b9fe87e509a0150f32cbe9d2e8b056c2429538326e4bfb499ddc79dbc203f1fff4492d53b02eeb9320ef3195dd7994e1f8c1f293c23a76a3fb13fce83dab58ec091e667b16cc1c557abfba1adbc852abdb1960476099d3b01adadcb883c1023492aae49404338730b75e4834e12c3a3573219da09d93a296ae4f6b7f5b127dcd245cf2549c714a24ba6f411373e1ed0be7516296514a96c6ee3c3ef0a4de11b38ba7c6cf9af282cc9c45b69803e45252a35c5c4cc950bdb4b1764a371a103a0454c7d43a1f60a2ae90b246f9023a2b642382bed9b0c17342974c85778f0fc67fe577bf8d1f944fb70d7fdbc589547c5ca4221772a83e7636c87e29b9445d1186e9b8ad585f1df53b2c92f788251689fe36e5564806ee450c36f1280720d6147c027f2fcc715ebc7ddacd1a016730b03f637d519b31a17d691d0470eae8bd36f944f21317e1bd2cf1c27a8b00bd7b9040b88341dcab28c085564b7a37b6f9e9faa9416db9d1e45f25056c49b8f81520f0382ba1ff8b564f2b0163221e13b54bbdb745c8081cbf9d5a6d94961862696e973f84a009a309e5b6c4dde339dca1df35a2d7d09273e32b59fab9863c03685cbd98454817f395cb899b8e4a0650990d3bd7585807853f12c26e50e1d04168efe08843b49fe8331c15fcb0b7df197be691182aab05bd0de73f9b45fe874654213e93079b68b5515a7db956066df092ecbdb50856aa976e3434e7e0c6f93b478202574555744ad7a67412f8205e6fb1fa7001d2b8a78fdfd01455303b797b450d895829a4d5a2ba62b02a1699a8853e8ceff64576084917b0b9bd90a708d8c22a469a245c03c9c4e8b4d608535eec1c0a8d28c9d379f8908c7a87c2e3792c55a697ceaa1530f66e05aacb55abd2c5e8c4ece658bcbc22a63e6378c3b129887dca929ae39155d9d2a9085ecd049f5514f8eaee2a50215fd10ad34070b4698b316dc88a65f651acaa023288aaf4644f456c886a896ad93a369334ca22e6370f1ed929d48417e0aad3612bc022e0ffb52a21d1fde6602e1f59da088ee4558519551150a59fb4baa4c05bc67222bea465a8cda8e81f897d27dd35dc091c96972e69f0e0744932bfa36816796d83262378ba47ceb4e25915c68eb21d1d56840d6fccc3c681035d0a16d31e1581e10ac338f0db408aa5b29fd4b0ad1b31536c5a0995a976bb165d6ac0f90be033ba95716b36a7482315a9cc79e97827b1abc28dd232c2156f70c4d1a3f1e7b18b5ed02ebffaf7073bb015020725a9e26fd291d43a3a18f2800f2e61b1f38e9b76f9f062a093674dc951eea14732d2d2ac93fe0ebbf79f5882a7aca7ba57e0290a1ff0a15c5a1cacaa78d6b2a56bae3b79a1becf7f837d8e4cf9ab559e08fd3c8ec1f34e48ff4376525defefbf46a85f2325c913adedc433e2e7a4078bc5e2fe9d90b6f62f781a914127744444b7ba0bd67e38b03f38eb4c50fd659e75f6c0983368ffece99a2392fc42e23e8f3b173d7922ef3c1eace06bb8748c0aa13adfc19b2953e196aab2b7834dfdd04f0520c03550bcf6df4ff5bdfb7ce30adbb27adfa0ccd0e1d6895745a21682d5fbe0ad39f5689ececa7d1bdfc8c1b1adb9286a6f0e9793671841244b76e723e94216e9a4ee6f8d2f42843eadcddf36912504bde40e683a38cbf970af2d4183f1c78f49d92b364324dc35b0c75c8cc00bcd02b8f818ec91e1f89df735f933e4ff81fd7c2cdbafdbdfefcb6d2467b0b5910aaa84a051780cbddf3d5fd52910d31be47256e5be39e40fbac5965af40d199210a9f1b7e81ce6c47a4f3b6427ded880db6007a2bedcf66b1ba6a7710dfcd079f5176a00fccc25b12c2a66c371a271710c3dc70cef254c0c341daccc062dc7800570be1c12b082bd63d4c1f2ad7cdb1f08b5a30e1b8973ff18040cbf1320f0d0e95b564fcc94dd68d97a455e464e69c1062b85679623266e3183c94e06eabfc4332d634e727a0038e59109ba347ddee28c068d74134992420d2caacc2c1bb8cf0d8f14dcf8c930d851b08ef59fd13e3ca3c2466cd912a0091d2bceae98f102f065a8566b5068b2b1f5da2edc7406d58ef240f780b45448d432d8c780d68f6d3e0b11a2c07fd6859804c8e28ad5342c666102510082c025e0238991920be52b21a3356aca954bd6eb9e39318701395325c5930271206a7b6871de2a5c37037e45e07ad5c55624f14416063c160012a0817da1134829299e3e370e3181a17c6054ffc56ccf902c36a8dae8d5c0fb6e9ce87d395963012805995e43275268ea440accf2617620e7f14573de637b27ecfd117cc1e1541bc859cbab0158238c5b54da9561aaba7d1875a62264b7650de83b32e588c3f0d0716acb3a1ce6e6cae2a080bbbd4b3e5b3609234c41de6681ccf7f04eef61c9030cb22f65473feb7fc878a5f7fd83475dd2f4b3ed77815ac595867cdcf9a9060b71672024ae3609cadd62d5cdc24483325c58e1ad90f42f012adeb74eacdc1e8021c7470fbf122618bad4c88876ecabe808d531a85de449a8271581be4de728f73f02db9adc53e64d674b90ad61994a4dc4eb16d5e3eb8c20e997247413a366156a7a4edafe662c3c3c0801fca05799c4f878301ab0e9c9fa6cd40b3e092b26788189c625e59e2f69273501502c1a886cb454180812a93f269addf13657a67e282b59e06c27a0618c129497386c99379edd48c6b8a8a8ffbe982ed66f201184e1fa0d8141168211ef4568c4c4720404c893fffe02f92879edc8ceca3bcc7fb6bd62cc4368fd2aeeee7f88f248694e8e7afc4a5c0f5bf8d61625ed227a1b1a0b9e9358b1dcf92f2138fd483127ea5046888b389201555cee98439f08df19745a69e9792057a21b1f4e75e447569916d1301505644f0a8510e970fcf3427cf22ce6f28471d88cd6bce768ca7f4d0d449316b9581221ba501aa5d9fb58fe4d84bb068c8f5f20af2e6fe3c0a3046199a5ec2ef5d6486d7355a76cb5f8790b3415c0931ca7b32ca065e36174280a6ce2ddc919951a7464ac6a4db61ff61de1f8e6c89eb23ded61bf7ddcd32a4fc7db45d0d9891684cb414f759961ad5a41ad3bb14186261fced6feda0479b05bd99a78d639a3066df1f5b08dbeb0c9c27da8f7744e3d98b9d4082b17b10a5f0593119e0cc63c3cb48e253636ee70b3a84faf0876ef0b387670e641b5fd2577fe838c920e2e9b9cb98ac698c832c9fd54f5fef3fff77c06c41cd73346751d4a7c70fe5a4e41a05cbf9bf8fa4edebe16a52c4c11b2416d30537691bfeac03b28c85341cff57c7fdb21bb1858d14aea4e4a0ebd69f1df88770e2dcfa40450ecf8fa3951eebbfec871d043295c0173ce751af4e0650e9842a69f58b0a1a0a1e795cace27e05a821cf4dcef531d31d0ad20f14c75352f6c4e1af3d57ad52fd4f57d52992e2ca6bedf1a7d7a8e97ce59fccfc40976264c844f881b0cfa9c107f351ef2968e53f8c84ec5db6e40adce48a63ea09bcdced80cdd57427f643e15e8f862bb02adf726031fa2653ddfa1a30f9af08abff25da4b45bb8a122dd3cde29cdbe1f6b0c24b32a94fe483420c91e8c130fffcef401fe8f9ef0451036638f6650a337da5bf11d1237f8216be2b09f3c233672c1f87a57ee27fbccd3e828b72172c5f2872dc487665538c96e1dd72ff394598f69e5896dd3b81946ccbd295032d9815f83a0d026cab3c541a1594bdd3e7818b743047817e7dc11d50b0d01751be0525324fe270d7e917acb042f3a35ccdcf27b9497a9a4218908c3ba264e88b02cd43e6b8938f3c13f03b02047125f5f327d0c6e2125eef895aa3d7e66013556a4c56cf3494f20a5a6160048de5ff8e33f605367c062c23f17ce7f489e6d517ece617e1883cac7730f69baba2760b71484a2723a5cf6aedbe68a33ddc3ef7791279d16b785e094d6ffbedb998f54fc060699a373c7dedaeccbaff5c696ee854b6556e04505bfa761079b2c0cad0ab2cafbac49774a7050348adce7584e07df446ee95aa46ef26a6138641b099895f97c90120d3320d098259e62c2ece5025322272071f92a95161fccba3b73d18f0485d3ac91bec90df3b30dbfa6410bf50aa7e74364bc4f71797cfbc681886eaa0621159c0707262a705c8f42cbbd165fe83d4aa3ef8686dc3a603e7c4d192587fa809a7c19cedf30cb51ee58875b508918bc411dc98ff163c9d7ab2f12403f440f876fc5d14ae2cb624a2e7f11c15fa9f49105af3694bc88fe1b3e49997df81e58fb997d339fbbad324e626a583282279cdb5daf409bbeccbc080f91cfb4c576722fed3bf574d918f7846d857245fc73457e6532a1cf991f0c9a41429c3cd33696396a092f4f5aa84ee710d89e9020cc064c670ec4186b427f2c1e6cb6555d4822578236e48d70ac0ac04ef7bdd330ace409a38843ea2e4ace31979df7eba9fc74c35c149c7c6a88b357b92c1b75d59d512013741b45969c54bfefb89f7cff1c35d858f0f1c2a2519b46e33937f56263f6b9ea349760dadf7993966e557cde75b29ee0cfba9d3d7bdc41aa9cf9541695808b3c7833d3aab16352fd8b749e9bd5c457edbac0f92d4cf71a8d96b47682a78edaa0d467ebb9f355e6ba5e65f9c7ae668e30b29dd089ded68f6b2df10fbbe472617596fdda6c8e00e664348a25d8ae7cc4af4c7fb7ff7368f3b1ec0cce33201ad74a300c39067802f3a7669db71d875bc3afe73d429f74eb2cde3d2029fc82e867610dcb487ad1df03d3a876e38c496bed99c4bfb9eb321ee7ca7c8590839b66fc3a4ec78c335bd79153afc23b0a0978f052beb25d714aa11caacf44d80d0b8b97741b5bb84406b7a69c8d57acb06f0f064f9aecc4de8a2c2b95f1d8b8b508e9da3ef637028582f5baa7411be43cd8b143887693c4d2b0c7ca28b3efbf27bcbdcf19be83a27921ad519a6e411e9970957d04374d9d60f8f65774d1a760a9c1eef61ae07a425e66ca735c7cd0ba663982e23600c8f8e287586cd41f1a886d5c21b03a283976332da9781a3ff87885cd539b0077701406a6d62e6515da9e2a048491f05c48a49f0d0436c6a10b36708bcfe0e2df91f851d7343b05ead9dcceefab81dc74432b84687ffcade5b3a5d3ba8744fa58d2fdcb4a366191ad292ae840b9a71855db2c1c3fc2a88ca0cffbcf11cc12ff71192b37b5ac15cb02a1b8247516c52ec9e7e1a0bb82aea480619518057c8ac85799c60c7ac8fd8ec3eb611a467c273ecd9108a56d6029db0420107618de084edc93d09c83b6232f5434949898ae9f826433eb3fbbed52b1509bb48cc084c5acad143b0d62c03953bb0f0a17b7e5f7e7c63e538cb505172b98fff2e166ceb5fcc525a9866879c87dae3be5ab65e3d8d5779da23cabe64ccdeec47d382475412552e0541d460bb19a65a2356f27acc394d441341416ffbf8572018183ac46cd1280022115bb1d51b776c61e005559738821c67226b73beccbdd4b6ef9eaa10df43f76d1d4489c59eac32c2c6977ef2157f84ff7a1d719fb681090cac6702e9d914d36aa8d6b5f0cd2e6378bd83d943bbe8376575b3cd78a7ff63b4424e9a1f7ae415048ecb6202aeb020011108fbebde7cf001c03300ca0135a56044f35a84502ad4e68082de90e6006ef0f5e8f0d1e6480d4025696375cc8dc4e9fed3799e21edd5138d627152ccf01e411dca1f8a83deac5df4ae736aedeb315b8cff43add3ebc97408300ef9c59d20277f77a5b023b79f6979c1f13f8090f613de7b6869cf0366d9cc7fa621b1ea57a83fd090ef76c3daea76c43dea3c9f91b78f84da99882f6db30dc984856055eabcc486a2a92919bf9c9e261a2ae020f53d35c8397e8b5d7fc5d3534f5aa68ce4de91dc068d8fee3898c95bf568b4eb06445d9e806805570ddf189d08211827e90559cb7d4d2dd2b9ed79a2363cc42c151f3077a339b3e2b5512316f6f3e4a30921af1d37ef4c42e1b9888b700fba6ebd4c7483dcbd6ff67fd50fecce49f1158149a069dbf459618efb2d401fa8109bc8a305dae68341ecd47146d2345df8f70dade6e8ac94f78d7b746e660a1f93fc6bd68b288970c507fec3cf080a66f8b7e45ce19bb579a6cd4ecbf97976770074c45be6f7b3c9fd32caff7bca21d921ea418cf19fecfd45d2ec28f8dd8bf4a4485e4e16f07635cc1ff84a0a0baf69aff2f6df0e27aaa28e13add852b72f69979171b47ecc62669807c24689ef34caa5e960c56b802be3338cd6f81b781918f17d670d4ed66358fcc0bf4341f8ac9327f340e67e400886ef9ba03330546d586b71068bcd17241d7270886caecdd8db48b953c1a2a9d4e25bc696684801413a57993883018f478c4838160f4b193bbb62b401cc4f9b35e8388aace39f82be8a9cd704033a7c68c657bb1034802ec60969e1c3f11963c37473c68a6eff74dbddb4e5bcd8bcd8b00f8b0f0e4b8feacbcf7b51bc5ab13675e636dfaacd39606b38f1c24cae8765a027b26dd44da7ef872c20bd0d36e8559f372c6dce3ad666c805258f92336b79cbd96340710e6b1916d0f391804c9846b8860eace1a39cde73784533ccddc1be5700c608f21165eff24fcafe7069f08fdaa371fa84508bc1ce1d89c1c2beeed807e77603e7716dd0cc9824d07c00c829d82eb0da413666f2e1b0eca2ec4ae1a36c2dc6672f0b2ef442e5c0b18ffaa917fdc17d56ceb3512cca352d659dbf9b8629d292cc1a7a630c2648b0998e1b3c3b9bc169a521a614138d89f579f4e7c2714a4f57f57e38730707ef9516f753130d44403af3a277cf413dc3f762aeadb0c918fb1896acfb4c189cec9c36b4671d8803c5be4f1cc12d1c6983e95d8f10509c1f9a61b491ae689195987e856931eb384db3e9688029d3229f7fdb2f27e092a098805cb6e1a2323a63ff6c58f370fbcaac70a1daaadde1c5bc1eb3feb0fd6e68e44fa0280a9897cda9798235bc188622bddeaa401af18f60e2e9525250db8c7e56dc54cf00f4abdbb9a71e00cec93505a1285fdbbc5187567f5acfd81e5cf8173532db56da124a29938b7a60aff8fed7f4bdff67148cb38c6ce416e21c36d0398a1455cd037f537fcae49fa79de829905732728bb1ce510cefc1cd6cb389fb3e35627ad3767e89c03bd2ab8da14c69f08d76e7ce7bb97d941dfdef5061746b857d9993f835f9e96075ef911d65d05cd3cd09419c0f2efb7d9f05ee94528b1cf6006f30158e70a751bac1fc0e9c60c03c231ca8f8f24e438d3a3f3e2b39e6795a452b6d870c0b1f114ed9f5c61c267c4a377600b301b50cd29d29c585b386f9f7439b375e6876d44814710c1e2961aea3e2d23f6bee6077d02b6494e67003cde03953666a98f259340f20c7bbda9d183eca7e0eccba974474b59f00fda4dc586bdf7c3f330fa1a60464adcf296a057e58d090a406253483762ffc07996fb9ac58672030d46deea411067d60afa0aa30082949d64497def516a58d0e490c5cbc86f11d3042938f47f85cbc7ab6fbdffb418fef709f5e52a25cd0ebc5552b1ee1fbc81d0dc764b3f87d06b02e49043395e7ce3fd95393038f3334b41dc55e0ccd7cbcd4d9af5932f58ca0c3ef9d34a670956596bfc06fa066b0a1f2514c4d2f8c228a17c7ae2001c967b200d1ad2dd1f96cffa2edd21836bb2d4a7effba7c99557e14e589f79d6679eca9682f1ad1d2a502b85e6a682f3baaf030bc79814dd5cfb23a65a6cf76895f992fbd935f4d3832a668799d9c55ff087c8f07cb4faa8446f164ba5868164d647f95818287bc120077f3704d6a92257ab6947f809c13bf407ea1f26423f41dd980630610e391b6463c8076c1474e267688f1dd068b5a8563bf7b465d39d8ec1ff8f3a04e0ffdb4fe1612ade3cf00abd10010af1570a6c690eefbfaf256ee7fe32d5c6489f9796bdc46ef0d5cbe7728e204a234d273060f61c74b0219cbe5f3d8da244412230276db2585e4839d71f58c2d0ae270c02b9503a1ddd54aded0afb711f866c0f46a4e62f184104eafa95e47872f3b482b3d35beb1f62fb1a83d35440b05395d0bed173b63fbe4b554f8ae7dedfaf9b0c4a415520446e8a6d93b55ec9c418a45dcc9ac5850b2105d813b8cb335e6419e2b2e1b70cb20c928cafe61c73da6d28ac82316c43db0cb004c52a833b51e6fac2a23c4f88ec53fbe0a4ad71e6e6729aad5070fdc393ed6058b627b4b42f407c07ecf72ab91c237b6345136849661a57ae89b3ca933c68dcb8c5bd0a549ed900c49c0086bd60c3ab7f5379ff5df1148f98e64ae1ad1c24cf0e6fae5ffd9eb852a718df05ee56dac13c675092d7c664d98641c83d45c39c913f9b063670b5dcc9c5adda2103bca43e3b2e36db3d3034056e672c5fd5325e193acd69dc82c58b366769484d6fc2efefa31733418de6b12c725d15277a975623540f84d409405441ceb02a3f84108e8b17712871e22c16243300b42462384f391027f3e03955f4cfd2dcdbad39464a647a90755dcca10644858434f2a12fba3855200a6d8ddee54fe960e70195f3b20f5107e4a1be91eb88f996167dc6e232031b7bcbc85aea537d5907c2c2ac0fb13037b96baae283f6e3577dec72e23adf2de724ac59f52d44ecddc1b6fdac900cfa7528c8371e88296364d2a02c585638f1c759d942493072717e875bd3accd7c5b431045a9ea9900b9db2f06d2a04bda0088f73817ed04b7be29370439d2da35708e2898bc5d1e8434a8b4b012d971087269393e6fd0945ba1ebcd4c687c8ca50eed0767707f7c8b979ec26d2eb1f05620381cc40c537248f49b2785f133cb86d397b8257640dffc276e9462cfd1dd4233f7a95cf01293460543bbb6342ae6c798b95c94838a0bf01ea961453bb899edb63f59e6aaccaadcd2bc98bc9fb30166786921e809f45be7fdded8f031efaf70caa77b06b6882868ae0474c4ffdf190f3b364e3ac4a6fd9f9c1bc2274bd7232c10e004bc03247390412130923c92e5c3dbbd13cd8f8d4598ea616448e8dd4f8195027c241ad34a23ce720e740fd702af0cab783832304b91f2c2ddd14d68cb07c56eb1384768cdf40fc68b55a8eda7e4c05d89475419402b1c3faa212fcb3dcaf9705f55717b88629d5bc7dc7ec3b4b82a734fb62eae974ea7ec1e939372d3fd6843bf3ae60c6fddcc7953a769f7c28766dd1a9039caa2b6fbc75d40b75d87c5c1fb91bbdb8db5000978ce03f7c78aea767600cdc74ea6ae8bb8899979a6b513ef5add17b2c4aef417bf8ef80527fb0cccfd8173f562c66603f99857a2d572bf5b38b7615900ff334b8c9f717c05a30a041b31bfacb9008957f44679bdf2e8de7a12c28739e0114fd40ba21db041860f5686f40a2817b86984f6095d4c63e513550fe0610ea3be5880c43d8c48740ec34b0389a0aa9507f10c7c5640a1e85c852ee202a3dc9546ea9531e90b25c14e3e0b16709497e9ecf5888ca573b30f9f4e5a4f4405fd47fd3a6cfe3410ce724d1baf3117a5b6c8ccee50aa282b8e1b745dfa940e07fc8a8af4d2107f3d808309822774a502a8c774d0ae71b19a077bd704211756babcda608e0d080da536d642428221ed66d949b4d390b44eecb73a7ddb30c66a11f7717f70800fbd11bda5db75cffd68c001d2e7b14fcbae6475142fb33ed76a699ae0c5c2ae54f8c2b25a125d1936e9d707b0c24dfbd62579750d0d1d3c0a92c991892c88caf91ee918e458fb27e1e2fe6b462c873d84e37983fb810cd76204e8d328759a1327456b38336c22e0f34b468807ca5fc79946337fafcb87b06ae8dd93f44bd37771d3eb805d997e9e66cffad20ec9390d31c7d9335c652fb9c195d8f7708b7d3c0f394f828e25f5a653f6ef00d3eac410f65523a9448c30b9f7c8a7752a078ea248be98036769a119fc97909180385d6dd0b431add4d463816ffbc5b72cc680d2b859491499cc680474ad490b7e030ad92e20bfa2003d6f2e5614304cbd4acff73a3565a6afc5e832f9c654a53c645eb08a7ef13a635d5402fc780ac0dc541f1c593a3ce01e5b09cf93d664215400d3fa3f153c44f47e50ef988c73b4abde12e46d3b7b9197b6353204f19d91a309444a528c9937361dbf0f4df64a1e2fbd65ee327cdf5a9bec94996d30700aa5ffb25d664569f736d85cedff8d52c01f623a3f08b6160a3c6ae77734a1a098aee24e2741c28e010788f0042dec0653dadf42e945ae4ad1a18a5b44eb0335deaab18c19d04060dc417ce632aec07f8c665d8c7f40cb0398b2ad685483051c50fd7c580003130af0f687528f83cad622f55ee82d20de0f0121d0eef55d3cf194d91c074fce47e1e9395e4741021b2218996ac9ff71d463a0f083d3a013d61fcc7eb3efb5f915caf4e7af380fa968448f2f00841d904ef2422db4794771c33aae3105f6c9c4176480313f6083cc9357d424af6e74cc213b8186314a3c6020ad52a825ce16027342e446f59e58c7055633d468e1c6d4d578af479390d9c4bb7707ff4cefe279125a3613fed160f8dcff7aa44776fcc6d3323e38842910ea3497af7e54884712f4fecdc356f63752ecb27aa6be4a6ec6380a2e659be18d4f68d4d9fed9e5a8789413c52171b4512be72c62b9d7ecffce452a63ce3dbb6ffe7274b4ac0732cd900e281cdcd95b5410f126a3f6b0bf1fac1661da073b5d55c5423b6f855ff562ce88c0e48b523dcae35f47ec573b5f4d9a168bd469eb9c5eacf9f6b05743ffc6d643082cccf52cc3a94a793a844fe40da8a768c240b82f78310b1a03c5bbf230ffe3646378690d4687e4f30fc06f5310a1027e570be311b8669987c9257ef5eb7e7bc6850fe0295315275e6a37aafa8b1e2e5f93dfb46dd10b43f4bbf9141b116275f01556668f6c3000d3456f49cec0d7fe65a1e113d5893f0848b0da91b3f1208608d0452362081c5dce062d3e7c303b0b40b26c67c1a64304e8e56e1b921f7557650bad38e59faa5c9d741ae8e1fbf504c067f8b1a4071169c77a23e610dee5d87e52e3f7f2cdc9889b928ef06e4e2a78a1785ce1c3d4fae09febdec70c1fde4bc45c1530a4d106cf83b7c7b31d8b7e1f318520ffab2d78b3a68d7f0d28721c373606be86b8ed81b8e7b0dc0b3d5e51bd3b9a10f1947e31ce1514c95753893f7dff997e8f1087993118763012ee3fbca81edb1d72c413a856f65eb13d7613b2be67efd60bee9022b52cbef3bfcfa3539c987d7232770f142df7bfc557b977dfc157cc3be421948cbd6c91fbff204404172481d9d8837f127e7b7da2eda72fb9fbc224b3f841aa948e2d07989b3035c12451be793239f192bd7718137cf4a065c5e3603687393704326dd4abce59986f9c74c59aa6524f6fb490549e8e9e9dec42894d4e5d7ec5de75a538d320461be86979a201264f33f251c39ed65ffa74c57f7bdc803f0fd7b09250c61be7796b41c5e17231fdd706fc5adab8eaca494cc5f06b205c105ea8fe923273db5bbdfea62c3babffe72e5f49b7939be7a9910c55c8e32dc7987ceaad2c40001d5d458728e6a3d676a4aef296d7c3c255ed79a7e56ac50e9c0a376210be388a8676e121a7bb7da61d5ef0c6fab88afed2bf02e33854c43e8f14f1b7811021777bef2cd3f5d965979040b6e09d9fe5501c1612892933f30d23d529de17ff9d4b4718b645eae623f96833ed5452c8ed039a50779bcc665439e7db8f59fbd1325b36fa741d0079c431c1c1db25530e8cba3a7ce0e1bf48776260e1425014cf9a86ae30fe6c5a3fd0144817d8066da3b393514d49d025afca0c356f3e2bebbf8599632b4df74e8e8c52350edc41cd72687ef939269764f6c45a45a3fdd73483778f22053a1d9fd82fcf549d308a201d8dd126347e405a63851cf5554dd6459b412b3e0abd19f9fc9bb42614f1ef7d328e919991d3dcbc8c62bf7971ac9c82ee101a7eaec4e40398b264f35109cab8514d18ec1add6e04f127ecbdb0e8f34014ea340b18302538d95b8a95566678bdfd03213b0138676c67693367012f0b520bb3113645b62502929a944445cb53b08d1915a850e0b18a2d05679cc5c2c80e6274b638d80bee3f1c67572ac9d4b3e6c6ea95606d4c3bb83ba1e4945c240f5a1913ec683e8e9cb4209e3108ebe46ad5b055274bba1752fc606c2bac2b0c6128ca910499571d3a0b6e4800e42404b5d8ce49128d14f5d402f7a25bf298bd6ded4f8cc1d17bbae658bb05a8b69d3fabc7ccf20e173e5b5fe41d3b55dee8ddccb15e65b40126fe786f84eb4b036acfb74311f884548179b0d88dd246306ee42df5ea5913dbac269594b8fe1a0d8f0c4a39cc402846ce941393a7e4e45b0e2173dc1495cbea2913c46467068f06516dafbc78653be054e8d772793582e80e5573e00339041e4788185530b4fa7747d1b236c25581ab3462a235f4c7ada43f5c032e1d63651a3c81bb45f3c7fdf2311e56fd6f2b2f5eba59daf453d338ef5024141ea92b94ae2e79043088880a099a45209e52dd812415c90debe3f1eaa2a3ee8accfd405b0c06c7057ac396f2f92381b338893405fd2b4be98a37a1a9d89c5df54c54e3e049c2b1f8a42af8a58f0cbc272d887e89816b21fbaf5898b8e2dddc58f0974c68f3248ed9f7bd30b566b478d5a96f127eee13c13b787673953e0713a76005fcaf35ea7d3da343da225496a3634f65c6b6a4c8b8a393c9425af20fed69df27f6650ceb5040cff7d997c3d7e722792722472af730b8f55791ee78de29414a1deeea4462be62f9022771d1c61d30739f6db1bd0ef78f0aba2db2131d4714f7f1760a5193b1ea823aba146ebbd1f88d43f90471e5278526966f79bf03a676a11839f4a83cd80eee6c2604723eeb1b4d4b95538c6fa0067993d4bf8d0e6168c414112698bd7b3a35ec98144f245a99aa827d9121c92745ed7ae8b61475f5dcf69bd21ca4bc90c0038b53d5d2bcac6dc8225a182c671c7a3efec9b7e1387aa14f56bc9561feb09a804797f08a42dee6dbb652e90878330701cab614b1efecc9a69204ab859be2826aacd9a27d579634ab888333cfd319354c7f58c6856b583c536a5f09638506b864146241246f2dcc884cb61fe0463229d78f6f0af3857d09c022a59f30b4beeaecccc0bff4f6663a0e48d7dedcc8ead42ec383557f91d86f1e08b3d42fe10605b22e0c7280c69c4ae670eb61c3cc5e7f6f15c5f9f03a07a71ae2511c7cbe54675926f6b96c06b1f8aed70724122b720203d6b18c6af7442ac29f87d33b666743521c1bf3fd36b5d0ff730aea22e5d664280116832f8e16fd4096f24ff6624571cce426066098d5af78d06da04050bca5b4a060faa42e0bd156557f1600ad9978f52c3cd8e4a879910e7c320b971e61b755a2b930f2f150d9f548377769808a5afee0b2051a677b8b0d4d0daec9bbb78cdbc4d623bee1e224585077c7eeb458aceb118ce1bd49e43c2c578c11e2d0c6421f57380d496442893077cc7f0db3b5421d784c86c45f4ade46ff8a008467e4681126f6e4c912778e0d10f9b7dc4bbc4bbe4a0674b1dd0fc83705171cbd12a9f6467806d10a03b7c887c943237333891c99b03d6eeb0466d608ddc9ba7792cfcdf5062f06be7b6191a6572e1a8195aa1bea7abb550969534f05b369a4e882898b79accf58443d5e62c476898c2dcb768f4f348d6cb36b9aacef65658d2aa0a1297b734990108d0ff144c06ea1e9d3a7a79ed58fa3e1745da88a00b4adf3da41ed247e8d61dd98dff68352a157fae7efa20c175eec2344b088a00e030cd14225b4a4c4fee992c1fa7c64647977ae93e2474945178c9765a649f8f8549305e0196068661061032a37093f304c80e11d44eff503e3473bb1ced4d820253f109972ea4794bd0c6bc76410c1be9429d62d360b8ca2b525bb573c591988ca65452ba3b249a03c7d5199ebcc3ba3f79f0306841bdccc34623b5ec71737d06ae1ad642ec13ee393f4741a33a667dab704be3c037fd20a512b11862a897a33813738693e7920a2484f0294ec43eeda8812b5af0b4418387c53144cdc4d9198b803e933dbf23f6355e9d372589108e12f4e6c3c32155469f5eb601fe8537a67dbff3b3a24155ec66c103aa2979cd852421ecd6da2468c03729fe06b587d949835d7a8d5020d62144657cbe1e8db1162206f1790d898a8946f5535820074afc2ae6d3e81c7c7de63ab55ce460c56c2fd3bd29a366f3979e4c6c1910e9d9c9e4931240f6e8873a63c786aea91d678cd96e2d2400d72dab983c2da1170bdeda68bd359dc2f098479a449a62ac3799fdfc188afd96f8cb74f4edc6ee227c0152dae700c436082842c265fdbe48dd5d43f0e99e8b0ac4c6ac640ff3b931a5db2705a3a1f4ba6efb1a15c649eac8230930abae799eb8e2044df54f474a6165c47953d5e9a0dbdec4aba69671f15c776902794dc8557fa7513a33751b3dfb4499342edea0e97d422d196afac73e35e03dc38e2652961dc4dd1d46273574ca5c4b3d00f5b4c71ff7471e4626673f8cb59a27b9c6c8292c5606f7333a539b7eeca3a7ef2a938220315bfa5bb8f5b882723fb7ccfc19250b8391d431f4d1778dadfa3666e65db2bc5deae4a2e02e28f07aad2764d272efe0a6fdc3c0a3cf3808810eeffb207bbac00b5c0870a07283065e6fbdffd7f7fae1ef12cc9fc1eabbef49f286c28cb2cbb3025e866de0448b8454b7e744648750ca065e95579cc1ba156891bd3cd3e8059d2b861f9485e25c186263956337ce10619aaf48aec5e20a5a43524d1971b6200718c18f9a73b25e56ef73f3fceeaea66a0d3c22260f4886714feea12b51e23995dbdde924e184f8d5544a613e2bf43b1ee263a594f70ca88b33059a1d04df485e573b6f37bce6f62adae609afba7c489b67436e5cf91b6936cfe350441439e074e6a7acb27fcf33bb7bece54650d601d3f3f7fe6637504e5ea989001eeede4d6bb988ae749aebab31a933df7bcf6fe32f450b11b76813c2785ca84399329697a06aba3a4d5c69ce27d3985ed318e51908dec231aa343afca754caa305b714f8df450381e2e9ef5d8a11329228775d7cfa59c5b065f36fb4cbad2c0e7282e0db0891ff35367f512b39308b5d25f4804487e40dd9a00cfd71d9c3bccd5597287ec39405dead1d50d6904ee96629b0a3756f30af27d9ecaa8c937f99a1d70391834e10317d8e00e6cc09b4a253eca8fe42e68e1098d4ec9eca411e015aff630791ba73035858b2d043246f0139fe535fb1baf51180d553939dcc56ff930e39c2bcf6abe5ed7cb15b4c6a13fc95b0475ce69896fe20c6ad987d89e5562804f1abb452f2d9dcd16b5b7a87eaf54411ee2c48058d08073a67b21a935840adaf02496c1ca2c3b618c2432f4ae1bbd3e66b47a516281cba014abd6f58cdb590238beb88544b8c21c8b6b6a0cbccb34715fc85cda581604ac8822a1ed680ba9a5f922850f12b2a6e51ec2da7d557e14d729322db62739129624d114ea15c16027bd9248cd706d73b984cc59be405b25677b91f60d61c3aab7867078390c6a0c7165e6cf1cae47f9a68046ec85d10748fe4cacc3662f60397e856042c68f391de94d02cf0b62b2af4eff67bcef61dbfe0b62f061dfaf74ac383ac6713b4c1657abcdf52467fc4bb1b8bfdc25af84f6286864e1f695fc433d2d40d7adf5fe5f55572304c16a20eac4aa45ed8dc1410f65464b82d20b8587e0eb023324cc7709cd39bfef1f9458ce0a4127fb441ae3a7dcadb5c41e834e2c50b49297bab7df75aa39a17ae37d7441915c82783ad0d8fed51ff672f2c54e77b0da6200ed46cd4bf377248a505066426a17eac38ccafbbd40603a88e4a48bc596858dca7631d4aaa02fcc964f60c46a72e9a9f649e90926a4738292fd77f27696de0eece6ea6e89075843613fd5c5d2a413795c6b646eb9ad866303c9e953a89712ec529a41abd9d105cb0e77fd951a7257d5f668546204b2f128799dc7e662c73138deda8e5dc53358a67044e256092a5445f23be2e7c9dfd856439861cdbfc25c1993d861cc0aa05a2bd1e1a924407d85fbdac9d6eab266aa4082a751bcab26887d146e5ed381fae7f7cea4eef8c619138d470dc2c6faff92a762bc1d3465f041e1ff32e1611b303b2f4e49ebdb04744f8c96793e69ae0d27a915a4d966e7977d33af21b425132ad6743f6657d4cd6a786a7b902bfa01c038af536dbb3b7f0e5dd210b29b3b0d3364d57446d131de5510c0fad9987c8d6e0e1d81ed2a46128d778eca411b49539eb548024a13e7477d9a6f1a6cc3dd879f3cb2c89211594b0645fab966b05188b2d34a5319682b1dfe544a9453dbf4d31f6cdf9c4c2ecc27ffadba746cc892f7d2d2080ed858629abce0ef50d4771b8570b79ac764a3ba03b81436a25f4ff4a9b8bc928855c63fed5cd8679a68268751cddfd823cb78f65d74373b2a70334760bee2748c3d55a0a683e00f7f263924afb67dad80156710d28527310609baccd156f6c99629ebd3006aa8559f63448908188386caf629a05306aad3a0fdfc5135858413a3b296a1f1a75a70e1873618bb23f639d267a00c0363046d1d0f6391499d4d8f03503c4debc0e6225a40f20747ce70d8f2b00ce6cb04bec57233433ac958a570759f7c43842bd0c8ba9fa4e798d373331108f074f319f2b5f2771cea7907e9b5a8d4469b9f8966c2b803b47f080fcb5318abe4a0050d08941f0fbf5e0a20ca4cf4731f7263a1a8b7ed32281303242694f007e9846c5fb368421272e06a4af0da5c452f21f9c10acff627e0f106cf1328030aee69789010b87f1db4796e57f69118c9e062d80ad3f06d65c1b6729f6eef17017521956af10e77d6cd26985e5c00ddd29db6cafbb6669199dafb158af4e34b1a46736994323c3e2c09ae7f9340f955494e2758e5e1098967b15cbd9f46058f3ada060ee40d7191ff0930371c6c8d9fa95d593f07f1c5fe1612cb11d00d4b26d343b5fc63548d41007f961f1434dcbb0b6b9562e67deb7b13e40cfe5f2df99c26f7ea7882cf71bbd092c9022231e52feca39781e50e03c8e08e760ff9d9a8efd41f82637e7f93dcf41ffaa7276dc09a91f4ff23c0fe2c1ed4bb5b387ec18809fe5908b283064db48a392f60e03b7eea7f0e12a6dcb5c38689a8b24fcb7eea8407b8aa97afd455cc1a4b9ddfd30dde064cf35ccfef77e8034d494847b305d9598337baf0a386c909e182e67f75bc9f57c58398201a794c4817d3837b580fd4101767ab197e8484e8875ced2d2373bfc30c1a1081cfb74b6dc68046d9cd784d688894cc8d5113b9d1196afa6cb8a28df82361c53300a003000a001600d000202a00800316e91e0f0a564ffd00da939301c9295966a752d0822ff881f14a664ac5b74fdd6f1ad272e38b9576c0b4bcb3f4fa1715eb7f21ef2e4bd77cc0ec89d302fde0a587e1ff9cd07a11de95afdb1b9acdfccce99f743c7765aaad2061437e72fec1559fbf84997b9d05a31708f52d674c775fc479f78485597be3d64d87668f771ea4f2ea9ed6e36783b110b3134f1e12c4bee6e186aaddd9509c5ae859f7affc40c4161df2678c50a5f8a3b43b5586aaea1200dff9e224c42442a9edd96b1302e7ea5f1284ba70357eb185c25963fa94823fc17609e66266a5707ae96df9025570d34c88cc0fcaf6abaef588bded6f29d3f22e03b579db8e1aa0bb317896db3c237893a0323d9c7d69d6f232e807bff04590be0a8fbd74486dd8be2468966ef68ae1117ae4003cff53facbea2eb97aed4c0dcf57b225ed0c3356be957983021d41c14bba73a785a8ca7ab3fe8f0c3889fb2c7a1c96cddced5e6040f2bedcfe41e98442a4683cd01550f49939b4048b432009d36ae8b4997b2bc783546bbc569d8ce64c761937b151fac08ca1a091da6e21a3ea69940c891facb6d6e7ecde2b55a439a56290e2efe33ad89a10dfc97197486f74e900861d0caa6e747a47f9224d33b9d6492d87f4bc42ffd9759247add2f39080e72e8e01ec567dbf83b708d59a351ebec73433a1a19b79e3f3662f3b8ba729afc4a57007e80f044bc4349a880616e71f1c16002b6eb08f9f01a61793b8c133e1f72f1195f30a8a7db4c037cdd850fa1f5014edbb0331863d1692d65bb4039d29d812373d4896f70420bc6a3744cb43d0aa2d5f4f643997ad4fd98cf81081545c2cbfbe90635dae8e75eef2b695d77578390b350fa1fa4b64f226b4be7c54b066db735e4bb027b6e95900091be946d33e0f37ce0337a01e0b001e202d80c8e6bd3d47d89f7585f0b668d5fcdb66a48c0ec63a76ed0766d576f695e1aa12725a40ba549b1bca02a5a9db5038407ecbfa2f05aa8e62f37bbec4ba2c60b43b29d5c3fed2c8ed617cd6165afb60f3696f04baa98647eed8efbb8687523deb0abbb48a85fc20047d12f629d84826dae0a30c7bbcb3bf3787d186d86d9c518718dfcb49cba91be9ce48fda10fec5a78d40037fc7078a23c59e32c8f5cdea85e02e24d989370ff2070ca087a1617fc81867bf855c986b26163deca5bc745f4a25295a061db6d4819d8047cd5545dc66e67ecc24af55fd00deca200ff46dd0c43aa9383ca05e924dff743af420182621c34a3b465cb7b5557d3cef8caa1a8827b1795c1267ada3f2f37a0ec884daccdeb1ee61d61edeb3677d2ebe59f502e99ce9ae652883786c1fe657887824aed13fa852c1e0ee5c4706d583a0d884b1b2ee26a030eb44e9863b5375823f4c12b980dae77dd7c448a0228aea726f4e5a8e11759554f8e6f72e7592acd47a1620dc3883d4af230ca975ca87f03ea13a7569f4aa63687eac28d6dcf83966a546487797c452aaf7d9915a649d01f690bafd8d8558566bad9abfed313e293023d1490207ce971d6d85742566568e1f08a802d70f4f2070acd5e2e8f691b955fce22b59fe94d49bf9817a29c58c74b91a16c5ee50ce7bcff5dd5be05bf250698626f290b9d943fe319d563bdfc712fab57ea2aac38ad57236ccfedc378eae9046b09527d02b5aa5ce8ea38b6b3586e6efa2d7224ab0de5b2f36cdc05d3bf5e6f9ad6921d1671918b8653033828fea71a9bdd92a4175f42c9f634055cc4a89d950e6809350dfe8940b137b3c832672ad4e5664f9ce7213e3848e3f7d5ee88be2e9fc17aed09feda48a3a3a1dc94c9ca45ba0e500f9dbe231e90bec78f91b89336eaf70a90adcca493b67b44c37f8fd6a7f21afd06d6164c8e8af28c726460fd46ef795727b8fb030e5230ba72312dd9abf5ffa5099c1d3d156e1ff43ee649857417fd628c53ee78aa6b8f7fe23fba21da1bebaeaf183803f4dbc7e4cbd9ac0f34a9fc1aa37ea20bf8e78348beadc665d08a469d3d40ed5c307a17140c418ece6fcfb70aa1e43feec6a49762c3504c7769f27679e5fc682a5ecc6749acc043fda3674956f67f1eedaf65b29da8bc899db6d48decb44278c3c0fe17de1b663f4dec396d5d5d1fd352ffdd5426bd2cfd4fe38a026c32314c11deaad8548ab284a6c20abc53952dff633f99fc6163e15778f72314984d5417106034b0a671ceca2ce9a2dba12559014c2039c19c399cc55a4849ab99c565b14b74c0564d2c49f04b910054af2c500516ec8f22538f1456e06a3f88e7ad5f3675bd422fefc03405d594171ed4f9684958f092a8d16c987c84c3862b900a46b92444dfcc108ea44e249a6568dd0b4567ea70f375a5d98c25f4b9ed900bd76eccaebd9c376ea35bd0e073ffb2b7260509f3fbdaa26dfc1c1ca92c0b6f581078d86ada9f1a539a5f36e7f587534fd73078eef37bcc1baa69253fc724d6336c7e261369ba076b2930f708615e32e6e52ee8258a0390d242506cb011c85766f1111b00eeb07a6900b9c6b44f1eed594386cc0301d223a919cec928f18de709dc7906cc6cd4ddda0bafc40e6147381413d96932e97f607c9067754bf0ba9578bb21363e445626ded6c67766f33deae67cdcdc97571deb4eaf1901deeb8f8460ce4e1830b6bd58035c1869862e5e3a55ae10387e61541eaea8d4d6b861e3d4d4b8aadaff30ced160074544f941648e41b72c165d3160538113e7d031de33d89c4aac68c714c13b32c5ac1a8673028090762cc6bb893853f5e2c5dfa13e9ecdd6cf990fad7067c60194b585a11a5e68a767bc8e2c0f0da692d2703e6bf1044a329210dc9335291db43d619a9f94589665dfaf5b59adfefe88004575dc67276a00cd40574ce6c608f0b963d53801030f0323bbef84767988951bf0075d5ae995f86c8affe0bc9898e33bf4496d10e00528e30d669095d0c0bb68ce281ff04fb968bdb2263e8458ed215dc3bb682c916b70531fc9c1e0c157859f4f8bfe18d65ca7676299d2a06a3aeb1e9829a67c904902eca0183f5aaacb1a14ee40898651aab968ef6b3a3a94a6b3e86b8ba60318c08721993225d72840d7e651f5f014d87d6d96e3817a3f9cf899a8a6f40fb39287c8802825df1d0e0cee488399646f1f78a266c8226a73111a6d60b32de2cbf0cba142a640496f90a72b44df20bb41a179ad6011af9bfad62f4f5681104eb31393280558fed38752617d6d43eb2b7a02eb3f50261f4262225a1c49b4bf6ff3f6ebd6abf3457862c8369ed1506f1715d2a901c633af4cf378f757747ed57ddf2c17c445b910d7f6cbf789cb609754c21beedc871aa5ded75ab19f994949d93d06b880788353d908854c21f7607480384b0878fe0d2d4bccfb9ac9d7f65d318f71d4524aa5adc74b49306d200cea4952d60af73b817151bb5119effb0c3bf9429b77c11b19087e89165a951b743e7a9688a7c5a04d813d414c90c78dbdc0425c0bfe9f1293052ae88df1b9a60bab5f7b883ba0c312e234eb026fc0c9869898d982a3ffb2a98da8be4b5308e94e1cf72938a5a7ca0034cf14833731a4959cd18aabb95177cf4c8a092609044b4dd5ccbd49760b6aac03edb8379d53283e0e47e5719b7596db74f6d946d72a6b2b523ad5162aab117132d50ba338c69be3ef4a1f62f50702c18eb62971b8fe5a746beec7b0582c8c127ae69b07f7e6a1f8f4621fb8c1b43b0d157d47f948c1a7b1250c776649ccc9b3310f26110ace85c76a04db80604b6dd06e40000bb691e6a3890966dc50301df01ef9b2c3d2fc4f419f7d72d711bfb9d68963a972859b7972e1a0db3e392b576ca6e23147a232284ecd9494a75bd0e3cdccf63bfc7bec32404e22524557ac751b2dc6aa33cc3929397ec75a8d290c2e0a82527eac5b62c43e3b384ce3eb5dfebeaf86b55fd457161df2004d4c8419a4b3d24becc1f17aa2e288db63b55a96b3416d4a3b2bfc9a6c6bb8c7c1f1cc0a94273161888d07a91227387c33d240b17fb27c8a8071ade1f11b4073e6e869efe27347e52aef54cd3d482767a30b846f6863c0ce6d6c026d835300db594635392134032552511f85b82150d57ab3ceb49c803916248c1ac1cff59c1cc29504c1017d1d7b6789eb8858c545c2f43f8493a4bfd3d9ee9894a5d6cf8e5400f8f97a69414e680891cb32823e8113adb154ad77f02ec3174456121aeb04d15046018c376791155f2e45f02f1c3aedcdb5dc9d3582a3487ccd9a4cc71ed0e22b41079b1b70cc380e5f47cd0d2e627368287346d0efc433084183be92fef49e0cfea93d7ad341f119dd2feec3d19156250b7a31133e812511f34dd00019c5205934c22527f2ada2e0f99d875e3a90a0ca489fa42ccbd732aa3c99939183dc541223fd1839c6601ef004f51495ce73e86b17cd991086d7969f2b2768c1bd5d72c79476d491067443438ec60548737cf538081a99ca9338353b5600db9d4a3ec8b9d0c568965908e8d44f3467aaf654f592c9b10ed32b65e690172fe34828afe285e994f115291396530f30c82e8c283dd8a8f1b60427a928fa3a756c19a676a519c079f0a573d58551edc3dcd2fe69c78cb735dab07decb3b2781e6c41feb573e1f823ee2c13dae7e46444e892cc49ab1808c3867bbd6ca0746be316138a0b7ce661a87d183b083b75b922006caa161c5c08dabc0da06a64a4edc96c4ebd47545f378e40831468b4dc659a272ea6ad15b7e891c090933ef3371d9166b7dd71b0c4281671ae24bce535ddfdb13e43d64d500b1c1ca476a362e189d34ac6ba856c5e6832fd003e6783fed439026c0d2eed3e0df85fed9bc6a4b7f1647f30047706e58dfeadae31d0ba81d5db7c2354bdb3dd4f4dc8c6448a9c3a054a93268f4e1010f08a3ae782dc87c35491ce8f784e11da89c83a80c5d90e3aa1a20cd9e38d46ecdefebd25838864d442d26409117168fc07a14d71813ca0313502a8f3f9935d3c0017e56a77edbd19147296020709ba08fc083f94c955b36539bb7bacb187167b80792442496a923d747b00fdbfa5bb9d3b7bd5e38b1e4ef45092071a792891072e8fa20f96ba8cfb69f2ed636eede3227367a7585b8bc7173c4cc0c3c42368cb8ead345bc02da557cf3d585e7ecf2b9deaec73d19e8414940321241588fa5026fa438788866a0734a6776672d5cc0cec3d5f2edb3b9d65747cc99cd0b1778e4d3303cdf2f27099c3c0325f1f9615e9cc7f1cf378e6ce5c46c7d7352f121daf79915c0900faff7a479cff577247d6d21d64eeb863c97fbd77d0ff9ae560fdbf1c2fff55ced4ffefe424fd57b2cb11b297ecd0c20eabff5bb5a3ea2b931dbf7f3b68a6ba3a12f0f55647ae0e10eac8311bc5af0fd37155e938a2038239103047d57fed73fcc431234e135f75712c90030f39ccc831460edbff5f5d1c69c471260eb2da0b871a38bafce01082838237aa78c3ea1fef468c7778c7bbba07b41456f91e73d58d2c37a6dcd0a00d30da30a18d0dd810830d16d8386283c87f25733f9dc6bc5c6692e293dcdae7eb3db4e7f25549dccfdcedd945eb14cfc0fd3b6919cc6d1228cf3d074d1d058e01e05c8143548d7047b27e6252ef9c797127896bc2916b94fff5b5c61035b27e4113d79d1a55bfa3064e0d9dbe4b6a9e9bea91a601e783b9591a61ea2b0daa3480bebefa0536bdd9fa7f73555fdb74d1a6375c7e466f92fe0d7d34e2fc1f41e38aa28146d2ffde261a05fcffe3805863cc773820d667d470c6ec8c0ecc78f335783985555377a798986165860a5f6fb51a53c5ba9c1913b8d17243839b10dc7c196dbe5a736f6e69cfd645310f962f6b5df456a332b294b15406080878a30e297d66afd2982f9b1b78e0c185b26420800c27c858818c236db4da00d1864a1b2063dc31069c31c08c011c2303366cd818c18604362f31ecf8af3e6c8444b7aed1a8e005c2f4595eb39f48b1d8cd325dbd63b1255deb144669b02471faea7031a64aa7348dc26ad944352eaf2e9b99eb74e5dbda915b2b064e0c08b4cad0eaa245b4c6cd9aab355cd64cad317280ac034c1da0270c337e08a5d5ec3c1b199dd0173eb9e9a22f17ce5d1d1d69595e1cacd67307c7cb474b751f3b0e97b94ba3741b0ac63b5dcf3e8cf92e5896b7e3feffc9ef8401465613ba4d30ac4a30a66660b8bed8fae2ea79367b5fd88efb1117ed5f50f3dc6ad0d06825d550a971a901e285d6bf17545e3cfdd71d2f78febf6661bdce9b84acaaac5e9652175b5f499ca37c971878bbb8aab60baa97eb76d105fdca05b9378f7281f55c503d142e92ec6c01e7ff2bd98d6c81f5ff556a8baaef37975b24556bb7e0f94f03e7d360a569e1abb532998c56b4ab15e9b053afdf1e59d68265794f4ee6232da6ba163c5968fda6ac3d77308b25b2b05f75a6dbe4bc2c807c182361610725710e8b3075ebe0a51a0baaaf583cfdff6f2c8ca071534ddca55434366041834343bfd64ef2bb737ad3717685d68cee4a7c8597285d7e7245ef8a0bac00e3bf623ca356dc6085b642c87f1d476b2d76aa028c2aa8fe2bdff49298ac42c97fede4ace451aaf8af5055a854a17a4685182a6cfaacba29d89822ccff578ec9dcf53ed2f593da296c53e85ce04c0a3752c4f0bf779a16852e8a09b0f2c052022b0b16396ba2e3d010144d401100282e140a3cd1e68584fa130738a184134027ac13449a98a309ad87a242c76ac926e8993767ae3843c3192c678aec1860ebffe9489b68ac7724744442ea2b65800898d062020526624cb8aec6b8c2ba0ae2aab6441f4b44b1b384124be09608a2841925a0fe5f08f338fea12f9779713566855e38a11ae47a9a29591ab34a3d738f98a7338f635fb7424196ee68fa1c7137a374bbecf962a9ab53827b26a9f1d8318f6325252a78592c762b9ada4637895c1240ae7e717ba769b1d8cd8c16334264202103124596a4658931797d348b7ba6be74ece9cc1b553b62ea88a32388bcf93b79df298059000facdeec58dd600582d50e01b42040553d3a72d52ceed72816bbbf608ef69e7b3717ad7c739d5dd4c6a8b975b9b9cfb74d23dc30228d115346d022ba28224c114f8a08abc5fd5aa1201f1b2f771b840b72535fe0b983e70e565cb38bee1eecd22eaf06f5264fdc7f9ad4b8a9e30ec4ba4c56193265a6ca2c512a83001158b59b3b445461222c113a4368e9f41056bf330497ff1f62082021dcfc5fed08c1e5ab105688255508325aff64ccfc3f991ac824fd7fbdc11c19d74e105a40bc1404d54e1049fe7f4c9cffdfe7183463c8e43154ff558f791ae31a03e4ff81c8faaf647680a07a2034c6393176ece0d4f5c962b11b8ec4411c259391b458ec46d27cd8a4c562371f36f300fe872d7e70e107a31f787e681047b94cdce4030b3e3cf940c364852153751800f4c0460f34f470f64079d88287137818daa18d1da8f87ffbca26ad1a197d3a20ee75cc77dd8773b02cc9cb31df1466764cf28e9976180213074c1260b28041327193ee0bdff982bf4ca043153ae8a0c3eddf87cd0cc47a27073239ec7278e500e49f6ed3d2a0e9c5031cf6c081091c64c041041cc627cf5cf0cce932effddae80d40dc3075c3941b10b0818d0d3fecd8e042b52f17f6ed8eebb9027db8675a8bb3e1470d65d400a686df7fb5380a47f14d69808306313450d150c00c59cce065062019f2e842063132ec6428ba3f5d2673ce52580d9e395cde7e06cf1cdd669510552d544955415545a90a12039a188c88414a0c406f7d96c2acb61416f3d11faa712e667bc71a0643171892bce0e685245ed02f8c6fed6e53174c178ab4a0a6053228b430a585a11682b0f086ef1d16645de2e8f244972532f89d2e5e9ecb175cb47009dae14264cb165bacfebb111f36f316ba821d2b58b1020b2b7cb002102d2c6861d2e2da518105159a54e84923052f290420052b296880821d2850f15f2d7f5d9792de0d0507042080140420446507950f54552a8969d5874d9c3b61eb8434279c7042d25f18660a809a9d009c09802e000fec98b08709624cb0b5f2d2ad29edf9eef26ed39789bb8b9ab8290b145978960c4a18a3041e4a482aa1032c6760c1fa7ccdab71b9db5876825004b30461c121536d4c113175c314d554d15712e782d707abbaeec3666ca6c4fab0992dc53025b0d8ee08a8052c03840262f0ff3158b5b6779c0f9b198731dfc9e898e49499e7c691f9fe2ec73829a0ffff73ebf4f2ffffeafd8c72fe2b812931b199f55f7914f36be4668e316d5f03663007c41a87cd608ea4e1cc6f64c6e1cccd7e4da86242583335b3c091254c35739991b29cd546963b4b922c40be92b8842d96c212aa4a48fa2f81ab81c5eaff93b0f0d059504d904bb0289cdafaaf98df5e96d77769309c9af2f23f65a78404734031802c84c0df3fd055cbf2fa3adddba4d966525a7c2b498579a9258ffb792475c05712632cb949e7738b93eabf9e40d59cc2d96cb3dba1994d093a9cb093397b972a77c7fc5696e7ae93df25e07038d6bb5bfef45f494c7b374eaff4ccac6d57b45c09fab9c9a56e9b94c4e5ee7aebb6e6b34a86bf2a0ed35bf378b7dc456d29fd4bf235092c5bca3b73bf7047b17f9df274e69b735c37d04c6bd59da69ae9f17d6c7c29f8824a389803758eaa1dd998e8cd5294ef5e3bc7529787250fe5d37f2d79f6521496e5dd7217d54394ad5abacd282015eb4d827944c209ffff34db8c9ae5ed32fc0bde623159bf49b25b51afdf244ceea3dc940be839d19ba147ebf1f0e4e0e9c0a3c20bdac5f9d1e2acb975596e3df21ca9716ef4a9758647a51d98ffdf25c16ce01db00e47109259ffbdeb8bb38f0fb526dff5ab336de4944e8ace486e8d9c0d39107249ee19d789f05eb943f787edc262b11ce0ce0871070871617022e08258d9c38a15cc0677f98399fcfa6ea71877fe7cb7d77b758cf57e6985b27ae3283466cdf276e0e554679f4ad22324e6714b7d6abf3c9ea53e40ec4387d47dea3649833a1fa94f235aa1ec0f85b2b7d7793a5b91b242046a0d9497af3f6cfab02e77a8a1ff7f4b75de65cc7f18a94a5905032a5c5099a24205c99433a6bc306584294323c019a1cc085446d879d2aa50169fdcf45d12fbf0ad665c4d9de92eeb4b2994d5653316b354f0e9828ac52c151d27b7a9bb519e76788222a58fffeaa27c5639d6c0ddb30fc9d7b30c93fb88c453b7c44c25e65b174ab1752914f0947a86e224c67f9d39dd9c8e38f544c9238a9830cacff24b61bb5cdb6d4ad238b6349334da8d707c7323bc8d71eb12de8cc29baca98da61a6aa7dceabddb556fbd7937172c390e9663c799efdba33d9316c7bb39730a6b29cc7fb1d88dbcb857e66bbe9ae8e8e42269a43e374fe291678ee3b2be92215398df6da6a9af4c400fdc5a0ad37f15818cc63f8ea5b69226119644789a8900544500f2a1cd46c35732e36c08d4d8d4ac086b586a4098ded3b684c412d5925e02fa587f0529bd51a2416904a520509480c2a5c248de84e39d6db216eb274b3cd13d59e0ff13f8f0c9014ece70428493149c3439095ea0595eba7b79c78a6b1e6dcf2151589fd919ee86b41e6859425aa6edfc7f0c86ebbb4cba4a7a4ad2811202560821b83e98e3bbc95613344daa824d9af03071f353d7c7c40bf63149fa0f320182e4e6bf6a1cb5790ec9cb77a4a719920e3dd23afaf2ff7db7cdbecb232323378cc2184d31d2998151cf1da43498d39bc463e79bc4313258f6d059389332a3397797785912b524b6040310b4fe6b4f4fcfad5663022129048101d91ab21e42991559051f50f1726d4ac30f46f80082a233455bc2a2a8a29ea2204a7aceb775bbb414d6d343af92590c8f308615cb12c66e1506f3000b0f82a107503c3820c913611215ea8be2dcc5598a73b90ee074504407be0e8088d80889b2422217be9eba7bea3ae6d61acd3808830314420ea6381832b4c5d0008644181a82440d922d2192a0ffeffdfe28ce71939e3b6871bb8d1b427da8b5f487da20ae772138a110d6bf9097ff1a0a3d09b978fc066585415e8292aed9cd73cf80f8d81a076f2800c180747e041e39e2083f82a4ee51771b977c9bd7d21ded0ceb0b35090cced7cef386e9de83fac25008614d962ecd926eb4898912ed469930d594e8528d22318102657644991835d1924899109293a7334fe711ebffe48d5575b43fd2ff89f3b5bf30df3e170deafb1366b77f7a0fc4bbf087672f853e702ae953f53ff3b17df5e1f97f655d20c7e42c7c51e5a8694467aa8486afa7af7c53a1dbebff9f977bcd850574bd50cd9e4b59d1d4f515d152c4a988920dead8a08c7003321b3411e183c812447e4490febfe3123635654a595efa439bec58e6a89a0db223ee6714dde39dfb0e29c09030e110010c5132a4811e37c21e227aaa843d409ef6b3b4514a8fa6d01f3ac555ab18766948efa057140c2d814285148130833032a0fa7f4a474b61c172f3607ad311030f3058e002362e18407881ed8208849021c4082150421c1823b4404d688196d002a6d0820bc20ab0082be8153c5500840224420ac6841448a180011e2e7882b3232a31ea437ff02e97b49b3956edaba9a976a4c9ba8a58ababb4c955b3e3d854962e9a7b367f2f17ed14c6b7edb69fe58f8ed6065118b5bb7cf99e1569dc03ea7c7de1046e3e9cc08bc98d7c38416f827e811f7c28419cff0f253042825e28c14cdc0ac5abffff99c8e57f168abf2ada44a09ba813c609432d8c9b8464be29b4ffe3a74eb7c390e73fa82fad4ae1ced6ffbf041fee68853b56e14ed5d71d9beb77be2902381170f155262b9ada463257eeecb9b343f0e667101ca0f326d429a383756ea18e90ce030fe8f1c098f0812af505d38d30cb64e469a781588fa10354a103b6d0010dc206daf87f007cd8401a0d50d1400b0d9cd04053d8001006900819a8aa2f1bc451b8586c577335bd6c94beba111285d50e8391e5a6d66673d55e40ac5db41b099a3d77769be33cdea541dd1788024cb840090b38850b1c102a7044a80009a102b250019d8741d9bdd3342ae4f599b6dac2203b0c32250c127ac0411092da010e81680981140199204c008e300123c204aa9ec952582e4c20294c80e7bfd69e3b7b8880508840901001044200688500480300600800a010003e0784718055b52f26fa439f5c354b71101dedab89c95a8bf1aed697cbc4bcfa72f5186c9be7a53897ef0fe3dd2ef3bd9bddd0003d20f8d080364203aa080d20131ad0141a208605c829404c580094f0c71e5f7b13fd9d662c76b33e6b4baac4c992fa863f7ae18f26e18f22e10f0ac28f23fc1dc2ef127e511f73fa78f34fbc3e7afaf83957735298639bb3644e057320e0e3007c70a99dfed0266b852c85551826b70e669f6024bfbd9e3b3bb54da40bc62d138c52db4403fcfae868fb2cce56128d8305d3671ca93849ffb5cab1f535cb81f5726cf9c7c921c611a7963b0e20e29012c70f38848083eaabe5b1d8367376b769af3c0783e5b9437a63cd1b27bce17a230337b2dc38c18d1f371668c34c1bbb366e6cf4c1061998f34c831948ea4b06e99847dfa8738977b4dab9c6baa7cb3b1aad5b6fbbcd5186b1e4a658ec46c7974c26bb15f1749eba4ae62e9bcc5d768ec98b7b38d90b4ed6c3a98263fbafc00ebcc1f935b4fed7a046746d8daaa5dfaf71fb7ff2aad1871a6dfe5f8dad46086af0fc63a9edfb5d60532c7623c96bd338401a574f92b358ec66e2591ab4341a78a3554d7dcd29bc4d9b0de228fabbc03755e11ba537ae8e0619684c8186feafb6fb2cedddc45b771c44c3e88c38ff729dd1cff0c08c2d1c745d9ece52179739ea3203cb0cfb66e8287193e5c6ea9fcc6e7a5fbbedbb7db91b9b797d3d2bb90152fb2ed19441a68c5e19495f06fd100173fc63c90878820010c868830c2c3254f851a23c9d6d647c1b356d826883dbdc360d8c71660c2fff97e6ce265a6f6cccb0d1c286890d0562a0214612627431686234a0e546cb072d520b8916903575ac19c01a14d620bd92d1aed63f60aa313149bad198c48c90826ccff66585e80732a1207d79eec5f7cb0ad122eaa2353c009230f608638e30be84f114c61130f800c30a306000e30a1844d27c31c517515f846a9a08d574351a7841871761bc7812666d3d45027bd9209b750951a35dcdba68474261f4655f41364b47fb52a231eba25d88c2846c76b7836c19ef603d93678d846cf48706d11f6ac44f3b443ff880be5cb1d86ee376e7b1d8cd5294d69ffa53492c952f90e29cee76bd33e6b9cb37a96f173c74a1d445045d24c005125cbc10858b0bb808c2c56fb1660b14b6b8a59993c68e304d99344f698ed21cd1420c2d7cd0c2a605d0ff636dad92ab666db6bc9472a099b9ab66e9685f4a945a1b106b6a97ac925da23fd4a6041b5279575f5fcfcc409d0e7613f3ca7387f9d541d96ea95033e39ec9bbdad2213558624ebbb6487a5792e29c35c546f4977b1d4b658143165ab258ca22812c7e6041c4ffaed669cca7fbf4a9ebb3d95c351af3a1584ce98cc592ffaf4634163c51d0c4f90fd160fda321533b1a9d06628dc656fb4e86e68a2bf20a2ef55783ed25aae48a5e7805fdaf405c2c760bada8590142156b54f1a58a5d154e55204085175464a18257ad893b8ee3f245a3ae198b59badb2e5a5f354bb3c1dc1dc912fb7254bfb7a87e4d199410122a781eeba6d8fa29acc229aa483c4592ff1bd5bb146ebe02b18eead794428aaaaf522491590a200fd35b875184717f19fbee5254bf375914bfbf611421d60b2b0b8bcc7f25b1a8b096604960a9d0a8ee0beaad6732ecbb4b396866992c16d365287e2114c127e0fcbf9ec07aa2ea770f183ef1abb42792c462b7279cb8aa79e704d557276c5f9d7055276e1356df9bf8fdd7739b4d2cf926787a3e03a7d228ddd2992b7e86ea4cd21903a0b906e08275ee66802524135b4c50e193d1e8c8040357695ca1f9aff6cabcfae08a678937d5363d29cbdc97a05aa20325e850828750092c4a24a94a5e58eff2528e8178079c254146125e92302109a1248a98c93223e6ab6dc2516b668a191090d8fa4ade1aad7d4b9133247a40a206246648547044968fe9887dc4ee88080ad04601c014e0cafed19ee9ad1b89d2f96cb2978bdff2cacaf21ef528dde5264e675911f6e59b6ca4a302231d473a8e244d26e36637bb912226dfbfdfd9713afb703afba4f879a4b38fa7b38fcb64b7225cfece5b910e3b9134dc35228ede4658fdcc88a96a499a35e2a9067194b9978c20229b6231d9ef37eb9792b422cc22ac14a153268d32539479a10c07968ea31d6db794c911264f9eb86ab632a92e6a7b103fb14f98d01ffac455b3380546d998e4ec5846c724671199711ce31fc744e8f4c221dcfcff0f613544d5104f43f07c0d85d8aa24e6098146882a2184709181f35fc9585532543adc69bf3d324f644232f4fa82082308aaaf63994d7de61ec4d3fff374ee4100d97a0c1add49eabdf518aaaf24dfbbdd1d637f0c2d331070f0145e02e2ea4320aa2a1053ff0fc4d3ff3b01e17a3170423157525ec4f4fe5f2726898ad991117120945496f7680a939af6dbdc3680cac60f667ea8e187da0faeaf967c59ebf281071f62f001c90707c2b8e1d4e9e5e472da2676da26760aa31406d6431ba49b73301896d23cb8e101061ea2f4b183103b60d9e1680720601000060d982b606c602cf8d2e6cbd5971cbe00bf98ff3e3e58aa0c5edfe5586ac3603152df1d4ddf5ab1b9a5b636cbb3c328df74dcd1be00d5ae83153a78d161b799e84b9b394891430e403958e0058d971fbc287929000702843854f5dbbb4cb72da56467bee948626b39c661c80d5aff7fc3ee06211be8b0c1cd5b5c2c26bb15c5629d7e407fbfd0869c0d3a358c514398b0862e350c551286f90f47031b210d6668508186dfff101a1a98018b19bacc50e5eb8839efd25e5ecdcb4d333020835628830ea10c31c850f4d5be8236d0d4550d5195a5ca15c318313011432e860d609803862560c0c1c0c0e5bb499020e5ed3d9ece96eece1cd69bc4658e5f1d0c162c83e50b48bc90e505272f087121cbdc3bbacf2b5bc9c6c18bebb962734bd9ede482052dc4d1c20d2d3461610e16c2b050020b1bb000a44b01c22e2774f1e1d2e675366229ac1bb13dd3b4a7a5e696c2fd2e792468660da3946faa2487b90b898b932d7a6c59638b9a2d02d8e264853a56c0aabbcc7167b2244fdf6a07ee1586b4bcd1c2464b172d4fb4e8a870c70f2a2c852a8090421cf54561fade9ee9a2f6f573d52cced158497176ec7987b9e5e97ca9de3b5a95c2e6b9353fcd8e83b707afc6e6760a96e535352eaf997f578724ebd8dc4eae221d7632b7d491ec6a1cbcb25b51efb25bd10e67f6dd1b22ca587267e7616ce24e5c96389eeb3e5cea868832df53434439c84d8d8590e4b31c22cafdf4613e44943970731edf4344d9d4badffe0d11e5ce7326ee57f01051c65a9bbc21a2dc4fb31c22ca389eeb9c24ef10513e8788f2ef72a010923c44944ddc71a5b9f91051c662ea8688f22e0fe1424872278788868832ae3c7d4344b93ca5323944944fdeeb4344b963de105136310f87f5ee976796b7e338fe01b7c6e1a86be27c9bd49793e5c63cde71e5d56133981bc27197eb2c15cc54a16c2c86cdcb75960ae5beb393fa52286ba990d804ce64b7a2a87e6f51fd9abf6dca8af4ce26c6923bc692bb4c96a4f3d89535aee47025caeff71be10764a3b165d84ab41b567a048d812fce9b66e6408ea536b6b493c1d2de0b84b2b15854bf375f50dfdc2fb0d3f166caf73571184be636aadfdbedb8c7cb308c77b01d895d514633e35c39a375ebdac4c489765b6272b444a32330cd6e4c966a4ab4b6d4ed91af26fa8a945c94c1b2272aceff88cb5fd6e9cc7fbb97f7776a5add3d58eadd336d6c46ab99e92f47f5cb6fcfccc09c33a770bf3a9d9b4499f9a8a7a82424504102d557acf78c840c721699cb07f57d41599b92a5e2a21c2be5a7cfaeef6d7deda1f9ef55fd7ab6b35f1dce057baedef3f8cdfa7f1e99caa3faffcab3ff95b7e4bf8a3c9dff17776f7ed7b41b773d580d9e0143f90a041494548d90783ae736ff515a7905527eb1ce5076bb475f2e2b927890498864183289fcff6a84448325cedcecd9c5dba58f1ebba575ea2ad99ec72051e7842e8c4ed44d904b53cddb67d602b1ee3adf7acdbb73622ace776adfa9c5dbe526b93f360c6b8275e1bec059e19e7042ac6461e58c951e30bfa8505a6969de71d439868456116a0050b52a7d8855e254d1a14a09558a50f182ca1154aa7cddbcebebb4badb8db8974ce8c94d6cc79e477d72ccad796e71ca11e21415c42948532818018dbeb8d4970c8eb080f894c49395a71f296048a9bf0e8542599cf93be98e4999f91e8fe0deed37ab525e4e7a38b989e2459420a230450921ca04e2ad0af12680db78b340bc01694aa2c98ad85484290b97386c6e1c2e868496a54f4aed3cfbf8dc6a4b3e3e4386d40d3429edb9ee97ab48879d38362fee4c404498238255b9f9a637dfdd4c04aaff1ad4358940e4ff83b960cebcb8d3992d8eed8bcd494d4e4dccd79e9981dbc49ad43bb779335aef14a6789b1788758d4b2d49b5966fba1467a9ccd20baa0a952a2e1fc7becd77afbdb4c4f3d55a7a2989315752bafaffaaf4fbda332731b72d51d2f9af50b2a090f99f9308a50765498502646b2d7d323d21f364ea959e24119fd0cab1b99da2f4e54eacb6e8848b139f131e7b2f2ea948eb342f2fd27e220db869409292acfe6b52af2cf72f842842582184104200a1091c4da2109bb8f05f5ffa02b18bdad7d4f5b96a96d298bd348a4da6262f2672884cb4b699b7be3491c91626529814bda2f4e5389d7d4858482820e99018f8af51faf2bc39c612a5af7991c423258eaa8eecefb652946874c68804233a93f3ff412fcea818ed2b88627ee998631607afa5b05b734a1d072f0ef39b9bd987aa32ee1e904a153ae35982f55f73bf4becff9913972cd9b6253a48342a82c0e6ff65b2de6f7924db42d68228db1fc08ade145151e4138b9a8afed25e9677ecf82a794154b24509d0ffd77d448c85896931e6daa2075b3c30c1830d92b4e1bb031fc40e70073a446210392112e54054428ea8894804fbdfbfda2d7596c26a59ee18a9effed5b2dc3f3af67bc4d3481c407971688c212e434890e481240b24412444840e206445ebf5e532854ea10cc4a03541565f839a7a262dcf6210d5ff2cc8f6ff391168ebdf5e8ead080444f55fe91581aa1c89e3089afffad219783919e4d7d467b9a5ee91a96d1e713a52b134ce2d8995cb57a0ad1689b03e6056db0ceaeb824dfdd77e05935784b96ab97754cf9c8ae31a2394ceb3d11c5db573acdbe2cfd6bf5c74f663f5ffe20f95167f6cfd3cf2e3f249f37a5d26a20f113e4fff7afb344f8b3e406ff3f9e7fbf562f28a4074a1a93c4d45579877f5a0acc65044174f2d6f9f1981639a7bf75f0d887591208a9c453610379043dca0890db46c30f424d67993a0f1af168b592a3e35d31f4a49736bead371cf14897041248b480436248c2154ffb5a7a7e3a82e45af7939e517d75766aab9781687040d59a027eb2b25b3a53ebb6dc92cf61cd1404b832fa20651a20656340842dff8ffba4dfac2e11c6e9bb8a89c897d9857a1b1dcfb578362d8bca645caa04d062f881910612007063a88184c61b0c3a047c4c0820bacf8ff0f5ebca0cb05572ea0a2103942d87411b2a3512c79dc3bf6c2bd3ca4f2285d8ea2243633def1bdbbd8d7bb49a3b51bb14214b0c08c68410dffb5dc9b52d102a50af0a8c0870a441029d8a35a8b710772dccf600efb76a74714740a9c8814bc441e3e78c21079b2441eaa0a65b1addcfbd7cbbd6d531737757d306aeecd34c19c09d64ca0459c60e8ffcbd24742594b652483b8b7f53612253842022ba20440a2688688a5b099cf2b9d16659769751cc7308e182a218655621882b8a3c70e13e24e0ce2ce0a3b48c41d0d2248f32486e1da35597d8ee890fa1a39d6510e411f22044188105481800251e78da86346d4b1a2ce4dd4f9213e50467cc0870754b0b81fae64d4b40a65a94f858ac52c15da7daaef42a13ebbd3dd7de810f10110c4079644076a70a0141db0406ca08fff11caf672ef1f2df7fe755c2779bfa54c762bba9c49cfcc527ab965b7a2cb316e6b8e4b1e6f9b38736f2e2b2a37c7e6353bc7220329880cc082b911e31dcd7626932d90c5f3e20256e20253ffe20274b6801515b8caa2025bea2d881931c896204d82182002c1128178f9aab798801e62024d245042024e0944202220c78c8840504420c97f0fd5992cd28f68de4bf580350e10e200de01444403f830e08c015844034ad100971a05882940271640452c80e7ff672ffe58f3238cf843ff18c57f437c23c4078acf81f83a5f3766d273fd9dc192674aea2b85f671c11c3ce6383107cb9c2a73329813f2a1c587152af061850f217b68fdbf6e6c528bd03eda6c2dbfb406617b04d1830c3d5808f540410f233d84e441471e0408f3a8210fa63c20c0830d1e5ff050c19cc23d3ddba419caeab214ce45a96327f5b9e34568b0dc5ab395668bcb5693ad5702da4840990470a9346629df774c71c70d77ac7007d21d3f42397bc8b9928345ce939c0be4e8d8f1851d63fe6bd05218ed99f5d06de619ad3db3a7278a6f60b6ed7293a0295360a4632c265ba2635291ec725c47b00ed7ffd77be940d32fc7744c753a9efee9006e4dc93a879939707324fd575a350eb135a8349545d458aa19000000500053100000181c24140dc8a462c1644cde3e14000051b47468dd9836d1649d54c81863600600004000400002775171a3e24156cadb10d96309df5fbd43f80c71507817fd707ca2c8e3c1d2c485cc87081f139026bb817ed313d887db583c563a9ebaeb5bb7465f92774d263f8d759f1c612a3d75c6e395969eef524e684d403039fded06032b9b8b89b1ad7039aab78d2d2f47692ba1e789b1137e6601a9be07bc8d895542b0971e36218b2f75be69489b84c1fe475eb70f9ee2f68d428f3f249d366b89df4583a6d4774b7559d03c9bdb48ed737f74ed6c625826a0006c7c21caf0724b86ad3fb229fceec5e1ccf3fd0df78cdd3e6eee6eedee483f8216b7e4a2dd6eeaaed2f7bd3bebe526a482e5357980d1cfe321c504e645716361f4761349d1818a174b657cc657a067877a3280ac2c82cf37b81a2e08cc74e7f20c4ebb55bda8aa05e39fb1f2864b60b424dfe96a000b7f94d84597095048a0101dd28cf37f4742b1717e4d0aa7bb14e47820446962155d27e3b9561af6014400add1ce74c2806852823a07782bd282522c52989188714c5fb60f17be64700c3be4e71ad3e92bd352738e569f5248fde93fbd02fbb45553ea760903b68a5da9b11740df2c9d7b33225a60b18279bc82351f7f7f974a1683920d4c981b42fe32395ec054b2949f6a39a3ace33cd21b2e356352a0a25343403a9037cc39166fedfce56c18b2b50eb9f6b8dbda5265a0e0bf4ce92e6aa0aa908736a8a57602b8a15f037d8171cc42a87db3094f7166539737a90b43a84344dc96d1377cfbc4f181761ebf30d4837fed1d28f2f0b81a23b59bce23fb8fa34a3fc048d61b171cf93ca840a4c69395ac7b4fad4e17b519e9ef94c1f3936f56fdff8441122b00ac6e16696e10909e7aa894156852d1bb91404fde7f1cd93c394617050641433236c309b9e31659f93dbaf9c143e3626036d248dc84a010620012796412a8d6661c6ca4a8a81a74b82e95e32a80f3d7694369ece556fe2148be8bcb1f3e2d4ee2f78501e83e229e331eae567489bfc48ead1b6133be1b837cc62c0e0de3a38a284ae8509a241e0ea0ca3d65b2d287c6e38d0ff6c5cfcba3375cd7cfc2f82f6f26596c900524ef851710d66d278b03d4903f76b00ddaa26ef7fcb507a889d598e915baa8ed2bd0fc63e68aa2cc46d96b8fb92625caa608a42be71154f9808222a06d62f4941b4907235e5e0cb6fc428297fa84e3914fcb8aa21f35eb1f4e3efa48d33287e4b1c525426070d5ecbf09e71ddd2051dd77b7b0d7dedda1b2cbcbb55ab504970ea21c04635b7f6d536c203f3d8a4cbead514548e382222dfd9723479271b35cf7887374495ba6a099ee386472ff770698215588c601b4dba6a8c981967ffbda66cc348bb3639bb1bc38bc1bdd7048808057c1bf480403ad0644329cec5701f92c861dc4ceae7755e8b3596465cfcc913fdfda9e5c348a921d980833cb0aabf0d0af2d233ac23c7f743e86033314c91709ba6756b364ed92bdc9d52003e54953eb85354500b251666f971fad0521fd20812e405fccd99035add92a61782ae43bb93141232aad6cfd8ad71087158ccae296b54447278c839e8536f0e86a55e2ad13e7c86df20524abe12cdccd9d45b144ef69afb4d6b1e0d50b99ddbd7187b808395f77aeb60e6f042c8fd21e501147273969bc6b4abc81744d90005d96c48a4b57bf18b91fe7c1d7a5258fa78b2879d15b9c6491b336d8b5b549573ee5c65930f4049f751bb77edb9bbf836980e34317c2314a1abcec9b11beb4209ee15943d8bff61b0b6ade42d640bd7ebe44ad29394855fc3fe6b19ac91b4d55002d62887bfe83fc7f431fbc3b5354f67e420a455fae7b4f572cd23e2d8a22cdce13765a36c309f4356977becf04e0cd9ebe9644c939131b62502b0676e4b20201db11e5fa8758c84a2f739c6ac1da4462c11ea5d729b9e3a3109166e6da97a247816fd0dfbc9a49a4f8996cb12f007c272c1dfe870ed836a4bf793e00ec2728fc7f1ed814d35f9384dbb6fcad0cb8eb2adfcc713b22b5b6f167a81ec187402bdb1ba080fe264942221a2b9067714f6e71dc0067b42e36b36ca7fb45cccb6739f75c0773b45bfcc395d0435eb8f8a125d7f1cdd1897982fb7c2b5a18919b3ee6e490276fcfee9631ed40c5ce0d822c663d996d823da258e0405d234af66b570e482f394e9590dc7a45afaff02e5bb4531429ab89aff67d69a376a83b935a9ca5b8157b7549994e1a09b8ab34bc5f63f2414f08829a599f4578deee8e044d68354970f442b13b9614a4ae3b7781411e13ad77fd496a91b72490e754019a7c78aa39782a073d3cb5efefa9d2f2d5905dc7873499e343c3e61aed628795593bbb4facec798bc7a4496508809e61e024b2b314f4fb35136312fad3a05e615c1b9eb706361f10d2bd919d7f1ba457288068e3db68386d44569b480dea4d8cb86702440cef39b136f09491398c313d2d8696d268582cadc5ad2df883eaec5d9a6c72eecac5fa2358745988923db4f7d585aec6ecafd99015b41fd0c2e393d81f081665b89158d5f39410969ae340685babfbfc2049d2fae3a3e76fcad774217616dc9d659dd46ea19b43661991db2d885eeca836e411f7ff34c034102160019910e831b48f54bc834c59e19962e952f6fc48077fcedcd2695dd280a687bfd30200ee1aa37c8448a0c56592691e48d459834139723e0c74c8bcb420a655a3e8d01f27b54ca76e627b8df283d809da70153c5483cb63e9801cad5057d7d1e846b512f6efcf1fd9b8a00210dd8cfb2af26287610d0e7096d6229e759c87545c77429723e4b9b1cdba6d30f74b67e46d8d73ecb0640e483c4007b1cca60ce7618a8bcfd7ca907090b16dd427fcfc114f471bfa1d20c8faa9c1d37bc9d01bc9e746a58ea6304698e5c5cc9faaefdb5e0af3de64831f63bf00451cc1bc4b68fcabfe1c62e029ccf3f9d82edafed7b461a2adfd28594cdc9a18e47af01d18fc6c6154cbf9acecec1d4d94be7769cc7f00cb771f49cf6463ce00169763628784172b58858c64f2ae55561ac55372d9c8ed559df71f0d0449495c81f12b77fb3391c31cc647d091c59c437387d3e0c54b4a1d3cc93572d6f4b942e41c83f67f8ef69f30fbf3216acf155facbed553df092374dd21211adf1331561c033774120c487b4f8880993e186ceb209eb0f2ac68b47612e1b83851d7c0ce61f90e669b2e3e364659c236871ff0ff5ac45d51904d0bb8515b40d6cd2c2f9acd54917957ac0dfbe845c9e9c915a753c5c33ce3b6ca9297faf3d6c8f896c91c1a58492b36934b3ad9d0e29898e4353a958e67a98c8c5a5d29c5db1f9f28ad797380010600a83d13176b3800a36f1776b94916e4d9b2b86448587a40c896b1e266c4648e2ba99176ba86e42b251df4d19ac48921d7283c834d02be558bf76b9c06ea22fcfaf6a8f7a3540c46f73a7c2d19dbde919c49c1f6f5ffb217fa421fe838393009cda0d358f2bc242293f1c0268eb2cc6a534196bdcee5c5358662e5ab1db400c9441768d050bd24ecbaa0f426f437e03b94ace7124ac2d667106dc9df2e05923249cd50e949efa52ce557ad99edef7ddc48831be8926dbb9d63299e09a350d4acdcf7034745fb19310180b52485c68306ef97d896f010ddc39012ed162bc5c07e5b47d2fa307974227a5cd3ea77b1351e0913563034fea7429e3f0aafe13a349e4ea1412db71df8200fd5fb4db617c34b842bc1b500a60c53153893bc8c74039ba79115da275b0d949c9f4c90521b9337972eaccc7b2c007aa5416e163665b51d3b22c405e61bbeb2465196277331caef2092e6f155e8b4ca1a8fcab8415f3d73096f305cc4502bbab3503cd0e90acebbffee6f1b5d5cb12c8c37cabe37e2ed497a4c9ca3475bb2a4c285638979b04adc41ea3405475cbfd9afb140bd7f899c855547b425dee813824694dde1038c6f22ab98cf4ae5923ec5709428eb27eaa863dbe40fc4ff665edfad82effbb1e811a7fd2141a9c46849f63063689aae5ade2d51bcdda66e335856cce2e66b1385d372393463290cc4e9a9490bf7843ab38953d2ff9437eb9d27690c0cc955b9ba451ca57a628ccf47709ae496133c905cd751494ee9a4e68ac14618c51c11cb1e6e0b83a90547542073e137bffb261c59008a99f9ed693070adebacb8409c5c4bdbd3d27303f4477e9e2f4a1cd4671b03836165a42d5a18b7855600ce7183eababb78327e1b097d06df400a421d9cb6afc5d5c9766e943f4f2c867d4761d840f4b4e09d6cbd0ee7ff11a93d81a7b4103dbcb8639c4e2bbc198667a3af4413f0fecf1b029d757b60d9da83476a2ae7d4a688b5c1b249e3b0ac94f3b97d71b690398ee64a46bda2edcb2981d1dcd227cf429693721c9efa560e9fea303ae39671d1df9132ad776aabecfb7866319c38cc495ae9568c30100ec09e02cc67353e868ae452f3f8683fb73a630ab79ae08dabb7ff4f65b683e4423ba5fa1abd67126c0346e2c80c77f0f634ac16539f8a994cce7ea77e7f3d21cf518b871277fe1923105b6bb9191e50595aa81c0604eb3c57bc109927363ee99f2c4db9ddb7af2e2bb166aeacd4857962b18ec4e1af6c5398b7e2c97edcd1853dd1798e86900a7406967194318f950c7115b2277443e2daa6d1c028af35fb91d7268857122687b0fe6a8b21c962fb1e371d6406b390313748dffac8394ef2be8e7a8a5409de1790880aba4d90b33f9974800c05cda41e21d43ac572d5d9dc1d3d301064d20acf204e6d44d8a6217b63a8c7b095cfb5088f12e2821d6d61719d13a82374022551b8f6bcc56c1b502b84eb9fa0deb0814eedc76308e83c3d2e493c2cbe96d7ebde5269f457f3511e7efe6aba1db8e6b1a106ef1f64c5845d9d7cf099e5872bfae2c9fb752a057057997ca3a0a203e12308d67fbfd4ae34dd9bd03c9fbc1184e3e866f7101569c4357808242985f5d793e9ad5cf91b69be5817c2f2d4c8f01757861d62f4bbef7bdd043f8f8fe9ee1fa8477ac2d2da62ee0cad16e9aa10ea8a989c909c7c5e48dfd7d5e500721d07a527f4f860ea3c92b3a65223646357bde4d1d111ac009c065ff50e68d6974e32227193e0c0dedad1e35853ef3761b1e029babd9cca9af399e0061643c11a65c42af84f2f8e3f38aa69d045a7f38cb18302b5817eabe5248a8b8a0d5d8a3950abe3ff237c4de42d16d2c614fafe6f3007bdca9ec0d2e57a4e82870a06bb56bbf3c1329535beb2c1773e0f347607daf93c2771108fe77073d8abf04379c17bdd89f3fa896df8890853ead950a3b40b1d200d72ae57b999796a75e3aea310c8a78e7533ce3b9467b9b0ccdef0c506464d5d1c46b7ea7a4d48d721375d5eb1b055dcd6c676562305f499efe83791985f600f54dc91ea511b0a93baa7e73b856ed206e6321a3df0386b1367e058292818868e4bea19f844bd6f6eaf38896e568190de16a487086bf3ac279e482b0913d5a2b4c7d0641bc48ce918d1ba6bb1c7e9c0d58a0eabad985efa2cfe7b04bb23f5d800d0de0ffa4c6c5e5061c192d4673fb5dcbee650739aecc817c64792f6ed9a97705d75d475b0a908aade2948910662f85acba260d617191717bd2f8326d92fb1728e93198d130b6006c25fda320d32351f912f832869a9a6c31af5d04a038160b194a0480f692195dd948f07b848ff42b3c378898d22b7e33d4f8e8f29a083ba70a5ba7be9372ae7acf753e42f5ab88762d25e0810f847d7b84e5f73506562bb5c6d815c74b84de897e8989dfef4330a7c0d06ab5a52fa8fad16913d2df9cea779553a35c2e7f41c6177108fb31fb5bf953128530674d1d37c8ad88b7c60a051af84d8437a9491fc8ca0311e78646af93fd18521f3e609387b117d4c0207c35d0efcdea697cc0ef4c96bc7cd639c9fd21619209f11cf635a92e17fe39df11cd2a0f68d87eacd8967e5a0feda6e7a7b18ebeebbd82e5521f98aa9f50763b981c3551b22762ae161805a1223a55c5e919f2f36b4272c0bc229fe64781a91a46e0e96256754f077e090855b316b7c336060cdea31c33433a5b1c6ca7fb66a2ed8ab44a8c6e5196458403d36aa07d1c7f0d678c632fa7993b20b0880d58e611b801154ded240fe3e649f264bfb04bf377d89d5da43e14b07e113b3770fbe69a3ffcc863133f826537c62f555f0ce22ffc9d84326de3592ff116399453711b6978da7dfa4105a5c2e7518740990d91f297002b88718ec311988a157922a7407476925ff325bffea886fe94e54bf5a993d0d9ea1c02c81682ee1d388a08579d75de603b53f57e78d5d53bf0c5927ad7891c9921482b5bf6892c995e6810109197b42db6f3e2e72f8563c989a865370f050b332209c40aa0b273d0c923bc440dd7c1708ddb98e1f1a3174e25ca082a96607728e86c97b666696c4e776430f37f5a754ea6f5a73648f2462bebaa5167c23ba80065d244cdb18b10fef334d91d1969d8ca27721b25e90b1233e8b44b8e4894912bb698b6d680d5f77dd81c4c02065586147f1be5384c36824d550cce5194cbf1c42d3925fd0cd2e816ea209b06bccbfa55dac3e78ca5a4be0e3f33181e3c6fd9300d9031608c73927e06285bb8075bd946a51785dd4a9c6d5d7e7e32768070797707b9a70d45d5d2c74f1f708d0a69eb50c231a501c6702639cca7f5c09da976f8d914230ab5c5ff788fc1e4a39481a49d737408d115a534c344c763d94b459879174a05bc8240b439153b372f0d516f89da1a804df2b65a78611da9d1ff922afccab36b82f6eb30e6f850998fd335afb9d29e4ece7709b55c7f7bf8f5413a0cd236e3edd0187dbcdc9455eb35bf0bc69d785d5141e92c219ca33d09d64b4c14ed0d58d9f02233dd4ced9a379993c0c8541c35c79c1af4e6c60982dd8cb55899a787534a69c72c00822bd0df36734805a65419fa87c7103fad03264e11307d06e614c1a34aa0884ad300dd5e5308000caa68e812df133ca6f14a8abaa185ede3ebb59041f6c566af611c46d5fb7d2b24b1e0b92d9ac577007b8489e6f41927a38fbd5b8690328c73b8a4e65b65c3c01c205eabdc3207c167e07b08b88a2b7b26b01fd1725cff7774df0920f5b76275d8fa2e0d9272494260db19a2304c01aa9ecbf699a21e7c3f6532cbd6ce926fbd4ba2c3a58be347304dc97f99783cd174f42e53eb8a9e2fee9dd2a995ba554d7d4e8ea475725390888cbb95119d9012b2eeb8e64f749d9783c902ea548d2bb17160b0e9c34ed05e1af04ae9403d7cba9588b0f8eb7684796e4b04883fb5580f6142338d970303248f4af43fcefeaa420f86b4630fcda9d6bef478c15dfc0fb2e733f16cc0848d3660bffc3443543c2c15ddd13e7202260bf07e6070f035cf4de1bc80a33ac174f870f8c009c64a57c4d4e34a3a62f5af16289c8a69550c1bbc7ece2631cac9a2001bc1400549b4138a051ce3c0f654e360fd2c0dabcd50b0b7da3bdc421fd7434b0f43cacc242138f5486a040a41b465cdee75ee1b27733260234e164e529d10e187ab413793dbc35b3a1979ecaf13528bc6e65e358dcb53c725de6e3d370aa58e04f6993298b87adb167187715659b2e85f755dd0648a3f3f5f009cffd81647764e134f8f32cbafdd79b00764ec24b02dc02c582b23fad89c39ac54d531bece98929bbfbce8c08f4adfc8ebc0911c5988cb0df10d8feb99ae89fa8f77e0fad3a8228d2299db807a695632a047f8457efb1e535990aeac15be2d6573cdaf0f0cea54c7f0baf0d5280815c605470119add45f0ba2cfe6af5c18ac63c75377891f458381eb3a14cb4ba9ccc397c67584e41a7ec17ee2207d48dfff7060125a1006fb1a2096e20e94d75eaaa0771c567ce85aec684b405ce200cf429c702508b899c74eecdc95ee08005d0fe2feee3b15b07728535421f9ca401a27336aec80bfceb6872f72865b07b0f343909ee7457d4a96142dceeb161a727d23811c0b71b986bcd54d17977f1996eb6b293b896232303aa8200c3f277cc5a79a465e127647e49134bd2b47b7c6fd1e2ff863dcd29d77363deb15f098ba98d8ab34060ee7b3ee1e16edb09f83953dc9d3202763e673a0653aae4a5006e39edc963045ecdbab1495c2e44b36dcab62694f35b99f3552ad5d3af077dc0f040ad48206eaaaaf22020dce7f33153a31f1f1e2cd3d6a85973b15f320ea047616cf67d2007e6d0e8b924fb660fef00f2451bcedaf860e5389474abdd8f06e40c1a7ffdeb8dc6c189c1fb6c74ee7a0c726b4f86cbc39ff1cdb88584be247c17e4bee8a1baeb82fff42c1fccc3efc857047e721870338954cc167473ecec22a7552e3b16b7d7da5b82189fdff58b3598b892907ffb496f919a471590b04106454b22e490a7027e449ae3379193e4670891575e9dc661796a7063ff789883ffe7b9962bb92f4ed55520a14acdfe49ee9c563fcb1cbc006097f2a2da17edc7a04e07d17137f3e483d29f0ea420143c9c43ed173f52a292aa941c611f9f579e0282501e701c5fdee386bfa7e5b12ed140bd15be54913c94d358d95405402762f0c4eab6e2f2c21baba3bb722887ef0ad7eb5157ff07b865ee2525f27263101adcfd8e7c9369304c8c2bfb4de777bff0387e31361c5e28a65ebd86ab835e89b22c67afab7c76e7be5fa8cc787e40348607c3e0b3cc394e1453d098fb14c9e8973f5501d72077cb3aa1f82178b461a087430fc62f06163ff6411eabd8d7dd19f4c6ba6c274b1b1b016edad5c87f6fd16ed7267d70777ef19b19d8d40ad560d5e1739eab8cae4792a7b5d89812ad88e7c475a8459d69262be10ec1f91c3af1d67fe77a6fbf7f0d4ebe6ef0bd166de7dee03761812e2b1858fb944d7cd5a22edb8fa5ff83fa1be9c5ba8b8e549cec2505023d195758713388d22c7035dcd4354d7aa33767aebb2a2c587b7f42f70e337791afd9547af8fc8c4bbb3f80d2f36a96502ed3e965fdcb566fea2c8a2253690b9f5a3801996887af6e44c10340469a7e4149407de51ee2e9eab83fc854b5612c13d0140c2e4d01afa309a353d007e0442283e07ad6fbbdf2507d9cf056ab1de56c919c71823a43ad718a1e45221dc2ebc43873db969d036e0950df683d9d3273c08647089cabac97e551e043fc87ee82edca133daf03c00070603a4fa91280d6c0366f347795597334fb68ea882d87ee1f87f4d1a9f638429c3a75637d78262143b10903ac4123bb1e8e36a56473c15d490fa19066d17e9c45aac5c838cf4c8ec5ca20208553c672184ab065802d4c959d3c778ab4c5d1bd93f5fab5fb0e5cd2d12dd21cffa1c1bee77e29327577669c64f005ef8fd06d8c3a44e0f032b233c7fa3fecc6bf2ecaaf87948e82476a97ff2ed5a830af9df585ce74a097dbf04e306ddda7926c2217eea6c8daaa92a33f95799daace88acc0b9aebf0f85cde627d9a58c003821ceaaa52245c59670bf8de4190600af0283af4d86cfe59a8c7f90edddfbd9ae15ea04021f3c0b8bf9259f6cb9a454847708755e370094511e715aea178c5d3ce2fb3afeb3456f891cebce1ea3e768a49afc4a7f6828d8036513cd1bbb5d07a327af24af4c7d8daa816a3c1a9be94ed60f70235f30ae3f3df0e469eddcce81bd2c8473c1f8d3ef02ee93f93367e53ecd005cf440cabf0203c08b06cc135c0e892ea47e571af10615223522013ea483b35137b6c8eb492810c6fc6d2c2dede45c22ffde58a3902cc5be61cd95100c3ac9ccebce100a3ec1c315640abbddae20eecdcb04ffbc9c58b7be1c60a40ddb15cd640b1b048b6cb462bb1c0b055d29a27d1391f7edb4264bcf52c7c9a9d4ee00e8da32a0b6876e82b11f41430552363e3eae4c4435218d95a09deb2f576df0efd71b34410df5a81ab656d6508814cb4702e1b0ede6fd08c03d1f1499ad31e046632a0472d03297d86444c3c6bfda8a4b8bdb748c683edd71551b1e28135637e064f00dd2720206e471813d9908fc5303d37916a54fe4509790419baebc00d33afa6aa037eee719b95f8eafe38f0f1267393fe60c9c8a1ed911a1443522edef65e21a9f4d90068a878b7855c1d50fad3ad9881bfc14ca70c4602352e27fc991ece95b7be797939d6f2e79e94c41bb70c2cc7e7433d907dd7ef882f38ceec0a43e648b072b19efafb84e60be3f5ee478c235385ee3fa59a1d6a324781a1b39fc67c9d1a956163e20c2fb873e057ca0703f6e1dde9acb60bcd2668b9b4a21763feac09557918ffc4f4eea0a4f0d9cc44eed83429381337c8712718eb9a927ce6cc0293bf836cae45d535a45159196d4839700f6cc604f3d2d8c584c0155e30cda8c8c01717fa0c7e5d9984c4c14856f7767a6f730538e669de833de781c1b271fb9a232d15700145b955f363550b57452a63da8dcbe91e46a1216106cbd184e90eee6ff0d15acc2b25ec79a74aa4f71d6b3a5005fedac263db7ec10f5071ab64bca6b59eeab8e7e035c4ee68396e79c28f6cd911798ed0d31fe99f342178078322a49077089b0b03864874150a5c689190c20ff20d2022679d1fa1c6d34f62e26ce115cdf2599e9cee7c1793f4dff71a43a40a56effee4d863233d7a6241d1fa82146042cca02ea20d2d1602c6eae8f158c5a0a60be1360dcfee05a38f682a99749ef3ddbacad74a9d813a1248a4bfca18e199e164b58a4e919862a287aa91a63fc07f7a07e88d0bee25109f496f98955ca29a89738fb5b3c33a96f1d3ad6b2ee027dc4170a339cc9b6e0713b9bd628f098fbbfbcb1a3ddb9436628998e592f72548ca331cc564ef923f4d834cccecf4595071a8c235c1fde16ed8e6823b9824be2b7f030fbe256b0dc35f76eabea2e804fee81c82dc47e262610a7697e2a5a4bce754320d4d44c30859d1f49b848b0403ac81841b9c660718ca144d3a039da6e17c39375be90011f2099cefaa288f46623856d77f6587688b8e38a1a8f5c204ae9c2d88ad622e89ba77061484eb283625d18aee09a88d852db82dec238b5803ba6a9309297e2a37ec457b29273b2be5218752f5f77c2b86e755a05613055ea2625b407018b5d088328b92e49408263f8bc8fe4ff2ac70b06d4006baf4c7afb1f389453574bd72162b12cc8e7f173226d165af8735e024371b730f4674135335e63f0b25d131294b529d9db250a9fb84b16c7373a116b8c16efc1ef63525e89a9063e09d8547781d7a24126d23bf138049d621daed9bf5b70e522760cf5816f23b2031adadd6ed6378beb1d596f3f7b6c509eb57dec36c6f78decc1c7b4c1eec68941ecf57ea3d5881ceb14220d00d948b310348ffdc03557fb6184df31324ff5504c56f22f8c056410f922c32bc1990d1ada45aea152e8a52aa58d591da4c0562c8aee15182408f5172f8f5a35675a6776610ea051930b52b39d65da2d341b02fbcd7e84508cfd7e0dcbb5b4054b936d41c91948b89c00194ac8f23d087ecdb4a508ac1265422edfdaae7bd768cc67fd19fe75b43f70a8bbd913895cd59899e4f020a1c64ef2ac2cbe46064637873425782790c2e5ced53bbe8e83ac5f56f15de66ece8a748f15402bb7d32bd70246106f97f728e36baeba596034846168b81921bf21f90e3ade509bf411c9576281979e61851f85e5afbb1b5f591b0269582223dd51b073ae5106852a4dfac27e953fbb4fb873668aa015113c7613d56bc3524fcf02918f95fbba16661198676028f3a0229a68883a6ac6c8d8c77e878f73fbf84f54c5ec37bfb9f25ff0aa00f76f9a96217d21a23a3d627edeff01e39000f644e6bfffd25fd1cee1f1bdc3de6bfd0010708781f28d2bb777de718c22a6c5e4c6189a11719d2f24a18b55fbd02b3db45270d4488aec686b5f6a7afdc2d132832f6b947cb6250a0e82204d31e3933ea780b8e90b4238a3ceb483b0ffe4760b0abb85931f74f3211c33cf486ad7c7b8cd71d6662479c8487b6b92bcbd9c81b3236b497911f132d8566d0a07de0f8e6cb0ee0c80bbce90dd211bd0439d123506de95391bdf26379c641d8e577281d7719aea805e5a0661576ab69740fdb5b5f578eb5ffa614b586c7bbacd7269afa70ee2abeb92ba1587c5c923aac7b87512589eb92d1bb1404c9d1bd2b4c20da610242f4043a7628c21827249f6ad51ec799c2018f0a6c3c0b501008f14ee6942152f843569b1ed03d866d0945e3b9fb819e4438006513695915a3035e1158dda51a6393f7be1ad08ef88673315be260c55a88e24a89dda96c308afa221e0a10d08d933006272088972d2dda687f27a873311c30a3de6573ae3561e996e4b0b688e29e6f40b32f9481d70fc4074c975633cfc71a966f0eae175e2e74e3026fe4c9bdb1ad0734061de6d7e0c52af17648faff0b7b861f19a8c50e6fee04514f4e4d2095157f5366ab71a00495ac353a5ac6f6b0b0c56baf80080356e16786042c5e72dd5e29da871dec73e6a1f68148c7117a84bf6cd00116143fc865b4d431edd449b5a2963e9748e6d88908f7909318cd48fbaa201dc64b87d518596ec00372cd3638f7fc326b623a1922db1a59d77be8148428281aeb063b60dc8e0a91df3f2a49d2304575a5f6d9c2cb8e7baaecbf6f5961d3117436a829a43620b859a8ac4de1f2e79f72e30d08122fd0ae2e3447e3ce626d4c71f1a7a7c126a4f55ad6fd380ba9e99cca42a759bae5304d26f4cf1b53d88cb112269b547d035d482990125688a3082401a8f1ce8e3d20ebc5517888c4d180d44c5108ab013f55106fe1c8eeb4f4ad70964ae6dcae3b82c73fcbddefe80dd4280ee3818bd4ae4bde751b8a3a0747d921577ad0f7936019f23378bf850a6501e50b19344e7734cbc462e0f492c2d36343c13785988e617429b96166108c12920791a3ef18b7f5e252631831a9bb7664391a998455aa7d742fa6b49fc52c7c759d63e36152ca18c6ab846148dcb351b07606333ad7668a6ed69f1d6acc9a6ecfaa8515845469a426d64dc7483d4d90b1e35e14386036d680bca3632e9403f385c2b463dca9799a3e57cc31fe40b633744bf5f7cb818c5af7a8f27c9a4d88b7daea99ba1db01bba02002d2bec3075796991db30ec1dc2f98929c0ef031b7446206c9454ad111226f19614f391eccad26ca805f039f6d3a4d712528a00408045172bf502b5a5c90488c4f2c6356061f01ef33fc04763c086600e37b65f581bd24a27c9b39a7f0c71b9cea5430e36e091998b19afed0741a66bc5c06089689e8111aefcece76e8a5c3ae27d1913ded3d60f17c989d019146871c37bfe619287d227453baae9b2020f46910b821c276fe3266707a64679050650a22e2133aa7a0f16b34345144c4ae87134dacd0e1ce3abfeab8a55a7f9827b2d0892a369d4051bb0c3cbac10d04f254f0215cd1cb4438293c497cd186130cf701ab42e94ff165ffc43310fcdcbbbe5fc60a25a8546e4274199d30d213708a60f739f2cad37ee467e370a3d517bd96ff405cfe44406081334a00ac618c80a681892d6c77852a57ea8ea3a0184b8891f25277d80e941b4fad9b3959fd37e1b4af560bc46c08c868fad56c0d58baf73e6466d959e7fa4047aac032ef09550d0c748b045fd1799dd0d5a3274c272c7291af54c621c1d35379f8b17b5ee8ccfbbe94e88ce136c3d990b9c0e2e7b2372080532e836a6340f730e95dfe9d74f031fde53835a19943bce7b52baeba50b8a2111fa65be1e97b5b46c3c0f2d16105a191dbb0ee22cd5820c28e8020bdc2cc92b0021f5bbb78e8d5b1045b43c482107b6cdf2d0dbf8f9ba124e761136e84a1ce9b0094d484fa620957fee615abcf8441348e477fcc64bb493316b0984de66e4d773e620a22dc8919621606c78ffe63b4d3db468688a05d2c5060305e203ce78059c49118577d4548c462680702fb76910eaff70e27419cdfc7b1054d1da93677efd4ca53a0becfea6f2d33880c4c117e2d057e322a7608f7ae3323eff09622bbe1430ae4eb25f090470ed5684ad9d119235ebcdb3e3c2724f2acb589d57fd55feb38c51f5ec2343e1305a75e0660c875c17f820675af3a382e2c3e47e5347f4172610855131b863296a1f0b887fea519a57bc76aa6df23d7fa723d3a749679d5f599c76d130c9f97a66f8d83313ee7c0083fdf5caa5fd459a72ccd671c3d54cdc681cc82f6982ae84989e663caa45ae7346adeb36bb7abcc2736b763c7d827a97c2f701992f11b90791307ea793daf7b20d0b57aee07b39270aa754d980a0b600946fda80db8432f6dd1b420ac08242ca0196960d12c2a00719c1ae439b94d43082d2624046a2fcdb36a93826956b827e1c2e6ee8aef4a5c5c2d5442252e5fded5a2fdb1715943b656dc2e84643bbd1d7e85a66d55d6678c1314461a71ec7635e8f94acf22c15f903c2fe3df71203d07a2bcb2b58f76d9b74f5ee302abd2a0cac12ae0abb0ad118db49ee5632a6e3afae38cb07831e5fd6243aba101d532e58c70c5f5c4e6f9a30a7600e75254ffd463fe55f947ca6d2af283cb5f3c4e7cf1afff93c707c4d037723a2be99b4bc39e9940d1247c9f48752772e23344cba813cc76b9ef7dadf50b7f51e76744be74741017857c9357cd9c09910f34ac55caa1b5a768163a6ebe8b289e315c090769dff8c983ec2d66e65a8b3131cc81812d8336c5170671867990015d7d66d12ef26c17c48d40d686fdd8bc8c7f07e87d4dbc7583a7c3fc85ad396adedb961bce0d497c2384fc8432ef0ae40df9b45d5b09e811a1aa5152035b26d4f396c54cfa6661389b37ec2a48711c33dc258a1f53ae0281633a98083bb118a7508d114fd003156cfab92284225f7c9f2c46db167386f730d7ed1e99508baa14c300e337013a6633fea98b4a52602153186d869acc0b44461b8face84c3be8e1856d51b71f38908bb1e57b09aabadc53ea2445fdca47913840bfcaf2d2854a0f6a18adcfdf0167d4ccf450e4a891e3485f6c58837e983a25d310392a5ba70acf99ad481f1f830a3b256ccbaee8b8227a35e8a58b28dc0d1da29a6be70ff16734d580b26606c1bdf3afbc7d2bc21ffa79928e43bbfe1ed7fb481db9d1b1cf91c7d7abda83ff750db30fc7e8bec7cbfb369cb36fa021e943b6b47ca28c9c56765e9f7c61e5d5110d898b05918bc778c726a64ccf68a60a4d446e104a32af659fe3eab134fbb3193f83b3a9fd39ccb32f2e2dea2da23cf9abbdc8f15f224983506056f87469511bff2f01b18f25c9228f152fc2310529a28c5553eb71a7a6801aab79a472f5800c4608be08b59f9e7152e3687309383a2d174abc57ba9e7267c834e657d741e73709fd77f76c0289d568a7adce14331bfad9a0f33a4ca976804efe23db5ced0182e968224ce30c924bcd082e995de57faf2573d4fda0ed66eb3ae0d759865d4b7741dedd3c69981fa17dcf3b8ba773bfbf75cd2445f642225fce3203d24f965ddda233fa41d66710b6f154cd4958f3a32a819881fc2ff1ca757d3386d408db447a20b68774b0820074fb97481611ec3bf3e264b01481fd107025c770081994c532457386e1dde683397b8f28d8307af81e240eacf4ca8a513044dee4ab9ae80e89c23cddde6ad871345553c3cf5a80cb29106d71839d1085a4b710fbdc5bc82c37f033d2be65661c56f33cb905bf0c12b4bd18c8e6f786430357e35daa5693099d67aa69c036416c37519b933c37ffd02a5f63e7090771abcd90f7d9e01bb9a3ec919a7cfa5fe38c82a80a59f5ad1ada62613959a2c1f3a7a0b7dcc2e5a2a32fee6e3a8f58eacd2d840b624199f7d1c640bacbf639708e3c9025d19c9bfc6794b5c0bd33aea9a67d79897e8c0e48f2854e44a3f0f6a9928c3ae400e01afc26acbd75282f76e5024b7af66fbd3097f6081cc020d62773e03438bf0d1dcff01f272f36ce1de013cd8e10b1279a375dcfc95bdb1fc8361cbe102636390cea7808793be4b2a13744110a504731e6dd06f0b740d556ef5891368763ffa4126389fcc256ab8cb9fe69d47493a615559a3cfbb059f7eb8e1d77859acee4b6c48a401b60123d4ef0296a888fb67afacb9cc5da7f09a912beca4a62b023f10b3b64bf9e28138d9c01f87c3757cc8b3cfbaac6358feb11cf8fcea8515b6268c34f672a3e83de3ddef7f2c5b5488546d26108b28e01074f50f180133bf2ab757ce0aaed3793727f2e987fca522f29e8ca35ae335544a7b9cde7b8013cb9992d660560b5e3a603f48907773a405e70f56685b9c36504e30181c096a0386a98a03aec70705033154efa3aace2c4f39474751e3d34b084f692fe2b0069179f0446d012fa9ad591608cd8da48a7d9c3eb06721fdd00e020618ca20c2e9ac66c59777c38088cd9ede70eec1ecf8ceda63d73edc792cd4414360d684bf57241b5d2dc6b81b5ee4956a6313fdbd41ad6d5e8edd070a21e755d6528af5865961676dd9f5940749f36c41fb8fd8e51b83e8af26d88358526b2ca4e1a2e1bdb7f9d361e6b33dc095d18ed43be423d466d004be044083623d22633eec7af79711f9bf9b8b18b47c4924fa9aed721ce2663a7dfa4bb13f9138e28f91c9d05cd88c698a00e34a80d0cbc402a7abd1f00457f2807404e5fea8e51103140ae88a2fa49d76bd4f72d6152104376652bbda6fa30dbab2c25a0e3417f61c985d7c90af74313fd1da67ce86adcee4955ff4fc502d24b0bc33cbce06ce002b7e5b367d9de5ad44f6b676cf27db35901071670afe22d54c9b1233db73836c4e6ac1cac0090b5c3a7f4b51db9de5d1734c631f49c18ded45dc2652548a659f19baa99a63d62f5cd9608b8661cf7fc88ec0ade0d13568d8cc4091e07c7d9d8544b4b521e616ef141187ddcb9f4caaec7be8d90cb66ec8ac2f78a19c48f7d18b55d596b7e6aeec7c3ec1222fad3d5bea16033b6ea9ff30f94e97d661e922ed23bfb9557fb1742bc36dca6b202f9218b2ff870b64c7aff4acd74513fcb8b1d456c917adcc57a88b77c978093edbdf8a5d4cbca0319f731c8b61253a77077ac2d575cc29c65290174ab6bf04860b8168737dfc9102903df24368f1f7b2e178eb3a0867537fbf301dd75b00070e5715cbbbef5f1164c30a0acaf78ea75b958af893f4cf76def228bc6ab77bb89d7977d26dd07a957c35321ebeeeb8e8b784947a4c5c44c85ee3dfbbcf8cd429f2cdc161c5203aab4b572b63f2e40759197311856661a94e1cc9cd9aca266af0489cfcbdd653a6ca84cd1b70175bd6ce932840f5f9dfba39dcca3b15b8bcc9d7a077cf38b4e43c2d0579de4186a7db488367c2afd8cc8732d7b3dde96a334335804c0bba48fd0465286160129e4481274a79aa46b54e93c2e6b557fb2d2e72de5f0f92079de6b46cbe80af70ddc05dbf944d01ef405129b75cfae13b113425d8444715edfb667ef8228415d7cecb2402405401583d9a714aaa3b8afb9b9b1626e82f85bd8d23c1677f9be212935ca19d341b726495f50d178a17db767ee7b105b922361938e6ef2420cf5572ab2cde3a05894170bb10df9a35a2e5a0d9d5a9078f169825924259a9ddd8cf0b7284105c4ac8453aea54056c6ace84413998ee6af9e2d8cdfe06af335164e90275613a357765f1c55c718d037941820d837b766264d093bbfdc7b703e589a9db324df79612fcef727e912acd2fbc12c395e98c7d8b1278d5a3facfb2093ba0a2cda2da673c300c8747da11574389142f859a588005ddb716964efe42cab10f97dd4a04a3260a5a6026825e1129294e92e7f63388d2923e31d8fc74a34a0a42857e41f811d3c74131ab73ceeba63417c3b902d4b962a476d8c8323527f6af03dd7aa2add82d9e5d21d4bd3b63f8d5508cc8ccd55c07a3e10328ba0c51bcbb616b001141ad6ccff3f3a52ae6bd1fd4ca26c6d2c219c7bf9e79d7a2e3c7ba9257c7b5092002ecd22082564eb9dc786681fe513752b2064882ce7dd52c19c32984ee445399c00e09bd31682a5f0d7b8268c65436ba0d4356018998a8dc55b108c85c25e42587866757b4341222cb7008dfdcfb23e80fe0352dff5687b3b98ef8289650de50556b045ccd304befccdb98564b82a096291f8cdf2760984f3a5290a44e3871e8295d4ce30812799d74142d12bd245dcf315f4b211384f454e489e87a80855f5edc06f7ba2ebd1219103f1ae4c0ece8e9e7b86b196566358b05cc4df733a2ca3e5cab2fdc14807f1aee61f8988252b09f975d591c82c0db757b294e16594f050824badd4fdc72bda7cc0988fd65817435a9cfc5ecf0ae843a427087ab7c2fe99ff5d4f65861a8bb8355a059593c638fecbf1e3a826ecba88b6706a738c63869960964139c3d0270f6aeb4a99ebbb0167d39f4efcbc8d84c7b0935899900a22b627eb81ea21dabe8162c59ef159e27d7df1fc13d46305e063c08e38fa1a2f902cf4a1ef9a9283f950a2b9ce2ef5120a77f313e7e5b123c64f0262a11e2327d243d216cc9c58fb1ef7b3994793308c3bd16c10a0d18170e663db168a09583b91ff6e79fed89629b3d856c6602382e5409d99925aa9c119ed429896044003f6012d99094afd538de684beba6b7652791a8a5cf3cc39ca1b042183b72a4339e9ae4c3196da559cc8660297bf7c499e329fb91e7279aa905c9257458f8b6d393ccb510c8b509b941841e1961a04bd5ae7bdad1b7132039f8d7582d268021d3a9ed91be2b17950d7a099dfe963834521e13ec9a009ef037c908b8fd40e854dd14a69eb2352ff34b3fc44cdd4cfdc9b2068c69794998649b60252d9ec53ce26c30323a7be0a1d9d2e8dcc9241d66c4f8baa1878a66b4c3d20318f7cb8119a5a146e839291b1a2dfb1c458b63f01f802ebb396276b7631605d285d631b0245bbb3efd7c7e23feb5c8456d6cee8430299591b9e3b0aafeae5fb0349ee5408ea192cbb605ca9957d1edeb73c077b7f08c421c4156c966017978faa5301bfeb8174e71731e1e08101ae94f23449880823d054c3666ee2df0d44641641d218e3c297868bb7b60d9d0a92abf6f012d403850546b74f4f85c1a0b4216084a12aee858dcb42edffbac874d5913fc4c19c893c06c9afb179fea443106df3a19bee90a03da1acb91ce8bb69102d4fa1c5c32eb3bbc478b459ab40428ea0d9c4381b988e037b5714621a2c733015a3240eb88844075a1807ab8be0318244ee29076f71d9f8a70c88e30f36c992efc24cf97666adf3d19bea51ee0ec446856ea36020bab08b7a543c33ac54794be993443b9eb60dfd9e55a112f64bd2ea993a220a46dca03c0d79634f6c63396940b1e7b052747d1651306971e7ef68338af2c5dddbcb20bab86bba3c2b43348c31284d9b759c7a62251a47203ade31ce59a9ad379f21f9b8279d35140f3b8c1b02a0fb61d1c10f7f5f8cf8fd72dbf29fe5c51026a557d536d2eeb105b53aea8897aa7a6f0670429f948c44e550a0d914072b73a8014b2010a6188e915f83981895bd3f5a0a3493aa1dc054fbd7f9d990dbefee196519f2ca6883d1118b85ebf42c4c50b655a7201d13516671a134d50284bff0ad0bdb09a642f3c149d889eb587d73424b1a32debfac2e237cc88176630518141aa95eff800710bbe87ba9ddfbb24defd95f2b706d96acb173bdb27c42d9b5a0198b2eabbc80641676ba36470a070db368460d3923af702771e00ec74270081b3a0bd4e043147b9479bab7ffc6c287bb0f5995a3a23f49393ee0dc99d4f9c6368b10a22322cc73741c13e90ad22260bb6e01ca9849e002338e225d1603c0f31949bc406f8a9f5594225739d39227158c362c3708b0ae5132b2224e2d300ee728f9917ced6901cac10590fedea57360968d08e0134e50abe98d3a12acfd393e93a526b6d6cdd88673aabfe7bdec8abd88bd6d07db79c2025e19661fbf91cfaf830f763b38f52a7448f1398926105ba8e4df2ec3e8b5089a60e6be3b649181c949eb2f9852670ad6ab8a9b538aa4b69d0ef48b3b10b06dbc8723b837ccb1d522a7ae506a04b72f50cfa0d8029744da6d3633f95df991d2dfe04842c66a06639cd166f741b5d9d5c794fe3761022f13ccda325af6e7a574a012bc766bd3f88ff20248afee366c2787572fd475d9f2a9ece7994603213016e52f93b13429d82d26d13b2bc0b584a4b19a5a664cc0bc5772d40f77cb956666e67125ffa396f8927a77bd2512bfec6ce210515b81ed8f56b4be8b677895b7e98d3ce2eb7959aceeb05926b0b2cf7c47c32c93cdd464445b4983eaab69ced1c1e33e60aebf28cec6e2f957aa635516e881ee6ef78862e828859161a6f2cedba7422d1f6b35d7c0e6be66e29510698b73d202c52dd1e043800fc32ef58e5b08312f240765450dec88fec10d5131b04d83cad60f921ebd85b7379cc879a4f33ff23ccedbc7787005f55e0cf19c39af55315289af8ae296630e85ffb7b3df5583ef8616a39011bf9e3008e02148d589c904ab567674b2c46ab30be054f9ae23201323e58848f789ee48d6d5f335941c3bc54de838887327dbd702d2bf7fa861dc1421bf8e76bbb4adf1207a43a155ed98cfbcee1cd6cebaf351d124c1bc1179d3eadcfde0f22a88c8989aa9db91cb79d54171d796877822c3bc2e1562a2443edb6ab0a2a7f37a14e76b028a6590d4eb80c30ccfb5bc114b4c4153b94e122fe565db7be43655d8b88053aec5eb9e2f65bdb00574971e4b59cfbe40db65204821fc04df783278f6e99e77e3888ea5591bbce12810546d759d278f5c90ff46e33d3f2ca3651533e0122c5e4135590d486ba75d4c6c8013cbeae0786b06c4aac200f828c8a6961c6cd8b538a82717996fe49da94f8233ad294faf9c3b24ac6737ac755b44be07c2fc96f6b688663dde191507238f2bceac46760f726fae51697c06e7ed9b5ce2cdb499388067a40388f59f7d87e37cb9053921ca5a26ac03b1f533367da375c4a86d21d7249a66257a9f6bfe3ddc0c35af0d945d7863fef070007f71c151e1e22bdfd4494841a7f405a87fe6214276c71bac5a6f959e7439650973e4072467a063cd51174a4373ee278e1eedc3b0525b8ba74abbe0a51bd950ee7a0b7f58503537e2931561179fd81f6620d96d05a1ce12a9588bd09bcbd0adba6a3b836432dd3950c29c582df42872e21225f9ac6c24cc0cc81add0518f518b0745207957b9fd8d4f974dbf1367bdfe6a757b33d6a5507c9ae0bd8483e4a5333d164d88fb4bba5d5280b4fed5edaeefcb198ff614ce7a3cb765dfd6a339b1d1a97f9a3e030d8c540eb64322bdfd77ab8493c5b1804716a94e973faa764e88fc59f9557ff259c8cdcebc62c6630904b0baab372ed174ebc92128aa5f1a316defeeb9768d8953f195a8a08e29185c56dd5624f975ba1c500d9e21e82ba46343579b241998baecd1d9d840bd48f094573a6064612bb4cf730c76199051b14fa2d882af6c2bccfc70d068deb1c24dc1fc5ced0c4f967b5b58408d1e0475d7cfec7395c6db77ef08abb88f7bf2aba975dd7f733362a3b61a1dd84d0af2fc069d688b404d460a4661767b7c6e6ba056ab141ffd59e5a39bb96a6adb350989016f8c6d3dbcabffc3958cd035aeedafbb0f1e6976eaf42cbd8110a3dd8b6871779a9b4d39618158b0876567b3306c12a1027ef9a5c4cf74f486c6e4d4f808d4656625e7c05754a54b499ff679b9a9e37d376f67b15f10001fe2faf3fd9f89a8df44ac7bfa64a7901fefc5a4232201eaf8d61ffd33814e7012e51a7bb1847a35849f522a00889dfb618038d4a35bca21f6a1292a921e0e7c6b87b77a73d00585df2a559aa3061a851f40c4d2d9af5e398a792f09bdd8b72dc03b4f648cd2b31ddc8610fda382040e8a8262ef3100d158888fbb2aca235482c1fd05fbf5f15ed8ee0e39bd643f3fd0963e77669a72f86f04157134a56a59404fccb4f288cdb5dd6182523db42524102b46662d011f34240237a017dfa56f857e732c8071e6ed4d9abf67ecee7a78162ad46393da94945bb9e91291b15d63871848a79122f652cd1311b5fb1d6e0d80b47c27e9179e7fc00651a8a4573a71ec348fa120d90f27041cfac1a3c3df5ca7fadd77b0c1f64f6bc62af40f5e47eabe93e4cbe0e25442b0043e3f55b12fbbef210827b03518f8401cf9f7d2090fe9c889bacf0c3b35bdcdda4e22a0c098a72fe06fada48220109f57d30a56a498c6b5060629f5c0859d98a5a6735067cca06c44e9351d531a26362006264bfc8c1bceec9111b157d582abcef55cb9be5241628dd22bbb92931ab09409f9d5e04f90250f9b4f16c648781d4abdc988716255429a068798c64497d20b22d0e380afe29ba2ffe570c9f2509c434964869e4800366b89bbd3950233276fb561e940276338d5f485953b494c32509e14b7b584002c889fc6cc68a92f262498fe9ec3288d2eea7a4288377af78e6f29a8e2f68501a57d0d9cdb246eaf32240cea76f93145b24a11289e0a143346f4f09285e8cb6d64799a83b307f8ff50d83c2de70e4d73ec80fa8bd6f689e53e57a6f6e5dad847d0c0a1168eaa546215fc45ecc8662427a15e44c356809791542719226eb21977f46c680c0bdef68f167b67af47b7d8bc8128e0d5b1a28e854d252f5b20b081af2a86369a710518a754092d1a3330205341c31279a96fe04a60c9abe2b97d9b953978cc7a12f30d2a0226f8898f7807285da2268f78cab075cba6b367af136caf5024d717a5cbd15f99e441c3afeed3c6f92130c2960ba487250a1538e7e1aeff17ae4451a27d51bc6943a6b1f56f41b27a56c8914944ea48cab098496f35ea1b8d44aa81615db4328fd9aafd9488c5fee59d2046401312dd60b3efebfd18f8f156168025c9a1bd64bd79303716913f754b8f8ed156f617c0bb6c28e83998f2414b0a0daee0f4ee3b0ca936616c638f3022ca543508ab108d4bbd342cc4845def43cb89beea0106eb8d748b6cf4c95c017e4c4a3ac25d17df8f525dcf903650e8eddf931554b6de7544e8f751ed159c2e2f5b82ac46240f60867cf508df4a693813f89ca9d0dc54851e27491527c16f83e5249e4b3f22c2433080ef379b5bcfdd5cbf44648dd9559b52a95dbf395aaec5ab17a56f213c2c69c2bed246f161dc1cda431d606573ddd67de005b2c9dd71c9d1a8f2da9bb7d928d76431b95f3e60fffc6c8a52f4c534489db616f207aef8ace4b05e8267287cc63357e603e2c377b98e2470a7f23c7fe7e86e80df2c4768e64ea4952c696606c15cb24cbc32a69866c524166c55d0f81e3e46fca39bd4e5651eb01c90935ab000ffad5d6735e85005b80a4cd24214a5d6018ea4b858a2e745c7552d999ee40dee0df7ef9a01208c0094b1794871dfb90ae984ab469038802991a76687e68800a764ff3123b3f0da7a4fca4540b379c45a779a0aa9f935336a453f87ec801d8b00063867ba8be5487ba668bc881a6a704154756625499248912dd347e642bfc949f7e801b158a3444cd9f06473cdc06faa139a002c3551667f22136dde5ea14fd273509d0ea69e2a14712b6f151357c87d1c558c75586f548c7b871d780a425c14ef869e8816993695663e226573700d9006aa4f4535aa75505f2a144e2ed4134376485125184b1f73a9da58a34b12226c12265a0ee0b4ccf682c1b3779af32bae8be28c10822e4a027948ac60f2b20d974c32afcafe314563a939ad2d1a6bdd1553685e0ea359defa12224e5eac09504edc2f99e3290860633f9e4b63bd8f6e6aadc1ef4cba681aaf996ec242c3519e4a2fd64d78c9c8de488e96853f347dbe9ccd45899765898c7b2e59ad29ce60d2b43c5309fb2a70446e1c0e13ce58bd58ec20a69911d7655e984ae43f120684b0f702d870c6a92c349d949e9b39fde5c9b62978d4eb8a43f6bd41a996b60af63218ae4403cf764210cbef154efdcf6df34debd58f1b66ea750079f0a97b9368e0a360d92df70e09365714acf2114971e912dd5777d1ccbf2d2a83d5c038001846bb18837b74ce525150e30bc0b079a353eb1b27183372b1ac0be01fa3e7cabd34f92318d3fb5d33e6e8936787da645c29c41fb3cc03a235a85dc4bcfd6b4e98073ba2d51f14a70b65f5e62bc007e76d90b3eb086e91b6bde38fdbe70fde2dde1272cc665b4677ff6f5b6da432aa221ae4217aa11be315f9391895f8c17ffacef7630d64537896d79abe4731db3dc2af978b478f43bc7bae44e06b61f9a528035598837062f7807e51108822fce16e1727566768a157565b7369c6151113804459f7495c46648bcebab6d8e187149d98a2e3360a0ecbfc0b607ac48160418bbcc1864f2845f26712844c931945e73fd3c819ddb145163bc851ce598770d4fc1f1f298d2f32d76709df7142bf3f29c5697e7c421b0baa043de67baa9e14043062b53ac425091b395a975447678fd136746f08f592427478487c1e99e52e9c75c2d362938bb478333b6a3a60d518f8f15222cc17690396145d0d6f8cff859aeb94371b12cbc0dbafe8e7be138020143c1444d0211f3aea1f861ef1922d8a15380ba9b46e141255c15e9e4aa08238d9039812855e3ac7bc5e9bb84dbd3016c94430de1a0d53ca5ce8c135db3fffe2a53e44e1b0f29b629bb4f52fea7c0ad3dcb59a72b569a43bfa804e05d07c20b7813f1902fd2b07983cf9a13fa8655fcfd937344779f21d62651b891d95ec9520a409d2eac6d3d22466c8be96b65512de6fa4f6bc0b50b6e6c48394bfbc4362d3334812f328ab4fb6b372949f6a89a23f8b2cf6a1e5447f9e9a8854f462853215981056e5ac11ad9384ee58cc6e3b0c79b72c800288a01ec4a0172092cba8cdf5df0787ebbb0830296ceb513f491f2cee7e01c5744800d66a7436f01106966c5d9ae21142efa1c065c260d18fafb302f3d46fd7a010c6c546318021e1ea4167b89c43689bb7ecd0e6f6cab5fc5fdc489233b6ca24a210eca212d9245d1edb0b80df7ea805d6564a3ba0271283dc611e72cabadc61848cbbedacfc66a08d84716c35080f97988d217223aca933289717ac1cb605a80f7e692225504f8951b3bb4bd4cb2a7f62459bf2b7c976f4044fcce3a76ac1f7d4bdc5bb0b6c5c2976fc84b5e1047cc41ba48093ccd7b6b23b43ab8812d90dad273891877f558444037165d04f67b00027340f337e0ffd68836ef72be029b6b089f8ac86f46f9403b40cc267b7edc5e2ddb7815bb72bc220bb09cf91bd00828a0c3cb79d11b50e9dfed861d15e38b6341957f32f5f19222a18435d9d02bd3eea26b622a74bea261164a8130d977000d9f7b855c4ac05f6d50d43b79336d5bf7ebccbc5fc42f9d5049035f92e095fef308da00045dd39c8ff63005e488b29f6f7683210412896e631445f1d7fced33075cd402215a67d31767fb5c0eb2edf1df30dfdf6b73c85b3ce93cab4ca9be8c67d9214073e821d9ba578f059ea87c4f921e4fb7e69110ecad840ea011e9bef87ad8de6eea178256ba846b0916e1eb12b724e04014598780899cad7fadd7505c3e55d10919c0e0613af22f526e42ffe9b8d149ed9b1b003587d2f46038100cb3f93b4f2eb618df9f49af6e4f322183db85644a1bd13f333c94d7b4a05745cbdd8ca45a613c6f6708a0d7d0ed603b03f98e95f33a923d2909804c77dbce2aad0e329603fb034ae7ecca9e006104d4650b3cd5f81886f219344af5d823712042a726a88b301d5784d40c67f20f8b1b2a8e4c93dfd5496581505204cb7fabc772f393bb4c25117b5f322247d585cad46044c9c3069904cf25f91af792840dc898a0e8c83df7039bb17c433d929a5919a80b974c4b1823d9140094c82cdc17a800ab6c1c85127f9b7b9accab494194f216763c21c1e1297dacf22fc8f2f8154a9acbb2f662d032964aad0c98de9320da00a936efcba3c934657f2903ba410718864d78d13fc9014307a74d05cdd6d77ca055831f94905073b51dcf0b571360728311f78ea3cdd3ac35dcbe453e28906f9dea726dc6181ef81eb513c993ac531138935a3c10856c9418accfb0314997413689337e22407cd0a4a188778d25a5b557e141cfd5cbd13f5d9dd114be4df070bb01dd30377ef16675defaa5b2634d0f9f97987d9a33c5167e3cf8226c9c2f57baa730d3ea8b3be75ff9c7f51929643a770c87150365b7a15bdad94f72a526ead36c52e26fff75dbb967b9eaa1161746e80c62192cec76a7d5538b65f15af7580513134284d11eaebc2c83f319e5475980b605d152f8b5c0a34be43317ef664f4f00841135a93f1336bc9240fe752d4564ab1d83bdb21aa396d925df00975963088900745b080a8f6ac7217839cc4c8bd65e9e862160a12dc36bed1a7e0191399839c92099c85cc943a8474c0e4f0bf8ea04a10b36bb9e65460cd9306dd48258cd62805136a6dd0b5cbb9def29852689e3b7aaccb20cc32d14225f67be7ec94a1b739ea941455cf04b96931dd1d410387b557f9949b18da4ca7531d311c75b5551b744f20181513e250034d67b528ef99023d58a2431a8e0ac195c3b38c6731b279eab0bda61e37c29974c14ef036c25629c674eededc587df5bbd40529f3ef9b98b7f889ff056904943b07b805479bb1c6714dc8fa83c87a16091107cc1f4a3cb187f15c074e071d96b3f5fac79af477aa3b8b1a8691cfce9784a0bd73eb8bbf9d8b881e44fcf9e8a86f1167a97bc54d2a7f7b447398e33be97fd2ece3f8ced7c835f2aa344dd2a74f6ec88b2b6e177875c74562ab6567182bfa4abeac052b6afd7ab7bdd2fc8d364a87afb6efefd2d7eb26227de664942bb6b6f0191c4df8ed93d3e5d5c1932b08f6234e3a62e1ed49ff07ab498e3417b7920e17eaddf159a7417e6ff63cb6f39eff3d4ff5ca89a21120611c5677c2c0efa2b78ed6b35a444797dcaae8539c45a2c83c843dcfc35f833f10091418bced14e3eb7fe4c7d2baec7ade52b2ea1ed93f351bfe02d4389f51ffede91f5c33f66eb2693d0e98bb59581da7cbe951747105682d232e78f46f578303436c2c6c078afcab31957af13d60c4c31155cc97894273366230e0bedf8963a423d48313e250b80270d828ffa5cc9b50a708a4be5bc2f0318b80d5fb5de2d8425d5de2dd5b90eb5127a8c2c9956388391387954b1047aa056b6c94b13bffced9075ab059ee96ab4614bdf341e80abd4efc7d122f28787ca53ccec0011deaaa704ccd2c4215347cc34da525b4f937188dbdd137df599754d246648e0bc791d0cb215ed9e88f70246779b7db2985270a09812a0c40d4fb92522b8b2155ef3f5fd4678bbd58767fb7d7a5a7b39bbbc7be735d04f61887bdda5492d3a9d645ad176b47cea41a26b120bf9e2c9f79c5d0faa7a164d383852d3fb7ae5171d8eb4f77898f1c82d1a244a3e2aedf7932d4588f267d9b10b85fa06dcc4473a8ddf1614b88445a2aca1cf7e9e9706bd5aeb9b000a0434fc835404421a97a938dd017a82c1826410b590f457b284bc1fe4de550c692b20a31223dcaf1447f70528630b14a19b85d4fb48458f75ca34b478435fb83e13edd79c1eec1de17313c867bf4e00b61b56f633540552c6f0b9ed45230eeccc4921719c470768c45e48c209bc6fb6bd4c38afad91fdbe308fdb24a5df4b28d739902a4a7094286fc968438657e99b1d7b621f0c7affddaf1c1938f18db5ab59907114e60c06a24b861be315bd0d15f5292d0d9ef43215a895f00bdb1caef75b614839221d5445966ac0d030d9a4233b4156d8f0e83aa7860ac7967e167b21bbd7586e4965ac9e6a4e650b0d9aedb944d9862afffc270b5c6792c84761ff155047291402ebfb7d26b906b65c371e07a4a065cca6f8bb7f1d4183244c0c606bdc9ce633cded1cceb6347b3670433a942f2c18a877c536f775072677e25ba9cb2dfe0642d7cf8a9db7d628a69e15d4c15a28e034c8a3f734046b3d09c57e364b0ec4b2ad7bc36dda91f0ae51b0545a1a8efc67d5c13936358bfa6971c14239db16d21aef2944785371bf53c47669fa39a30ab98865b0b007c6eb1095dbedc267a820ba9e56cc3b9ef24f7a440ea970e0899b57ea5258c43b2b4dc02ae620ff65f0c48cf0c044bd330fe86e80089976599c3d91aca0a6a08f5f33df86c8e10abd7ecc1850b3e7fb7946f2dc763d6fb362db58a970cb7dd82e9aa6b81f0fc2f873a204bd35b6d1fb8bd43cb79cce8c6590e1c19e14154b2becb426cb685a6b0b98ef9e56167374979120fc4493a4275863c52bc41033175cf4e94aaa6944722114712cf0f6a571e31cd8144866aa2602879659a307b675f0e5793877b32b6d6db7a2db3058b1471cd270fd99ac88cfc09996f18dda4f9bd73d08cc72d39d8e54bbef4509a2f758cff232611f0474e336a6c42ef9779de2adf6c8361048a39cff98ac3eb37ffddfff2e68d8f1387678d839be716c4af8abc66012702f504edd87b227dfcd4dad71c1edc236beb3308d4a237c990697e194a0aed0f8ec71c140e90540bada5e1c19629d76126b2c858ab6370914598e68c71b026865df9d6043d2c591a2fafa927212b69666cf539a47b3906747d9feac5fc6e91621454b08c0fdb43ed0c0899268e16597986216fc83c79e1b266cad42b32d324a0fbfcd501ec044b6fd181f3e7142969996d0b7f93e6149955e0b9309fbc3f0a4d70a1ae6389c6688453b4c4f2a85e85bd0130ffc169b8583d694d565e58330d125b22d0d961c8638919991084f6d9e96fad1cd844977596160083fe7814ea6d4456389982b24a0ce6a39e5df2c53d1f7162c93d8335bad25b36898ead329848e9b6c5325d4a8583bb3ff00495d4f138f7733816b208edbcabf7a5543fa1764a27995129494895d02de29a10f12db1a7c950de8d31c2a86149c1e0396430a1658ca220a6755333f9178b21af295fcc8f5474e081d83e47975d77374b325f68d8e276672783ef168238e7683c8222e1aa601108ac7edf415980faa1e9f9820dba28d4403e2d78767564a3231241206ca6d12496f30314253b19a1a477e314a16dc8c0223b60ed823606d2a0638b19178a8ae690bdae60c403c76e46d8c97b1e010a485c9f062f0cc4b88deaeacde714e84306296eb837140a8785f9dc6acbb879de001f2517801d7e0ece131774fbb692932c2c92be824928adf23c24a68e7240bad554aa12a44fd5d4efed2d96b4766b4902bb57ec0afe0fab1a2ee770b191efe87395fee284ed376ca7aab68ab2370a6b52e49e10614dea151465a99fd761f89f31392da2d55ee5675918b0c1b0493a83970e6238965149d3bf6d3c16bc093863db6e293f31678f18073938584531608ed6e5a1b11c3b00228af7def4593494e9b00bdb3390c955554a6874267852b4b3d5eb5547fea55f2f77f868bae4ff4b505913147da4f4aa125540f128f9cc9b2e557583e0b1511cd3d8d1a96ad4b6c5d90629780f618e6503356159ea1121702eacddf6094079bef8e1c792cf95fa2822cc46909bc4e6c2c70d4c0b1075e4d9aeaca18d2422c1bc5033c84a2f2911dd956b7298c26f1f17f41b0ec0ffdfa1b8dbde474d647b59ea60903f00c33b44a6d190f388bea577c344c753b47766327b9f7bcdb80bbdfd5b309ec5ae66917998478a3c116f60c389e00b380f9b6a80ba3ab5982be8ccef39e30c396517050890d877c72f816e541d00a7d7c070bdda59408ffd23875ec2a0ab036e8bb7090b7c7e08e83d32924d33d4ead57010e4024df5fe4b02961ca44117c246cb442071c95f664ce7692e4be280d625adc9d3ff73b846a6bd0c8f73ae0a417ee7204433b5f92bda4c93902e46d6349945a86ce54c2b3b96f3ece4d505d971c0d73bae610f82c6f3d7d61a3fb468b8386299edf0f5c7ff3bd3766bcbbc8ab09195a66ec34c41c251ebe3460aa3c1eda404d33d5e910ca065b363b8e5de961ba3ba00d74dd0d5943f23b1c55d2a45e657e9c63833c2ac3e5e80591770503957c9e2ecf8dea6bd3d2c56515a273ec8994cfea9b2a9cc8c27b764d3d230c9af37f03d5ab0a57fec6cf4913418d66a8a92629d34183be83f700749106a22c193416030072c9cd52656c8a15dce2bd12ad638d1d9148861aa9df8aa1b57996af1bd945e52379a333d1702b3ee9bd5e73e993ea99ca998aef496b4b1d2297d329490ad0773e89f5ab38c9f31ebd7d136ddc87f4183374e182d6dc633f9f28de847ba364213c905f323dc221ee8f060e99fb33be1d767afdaf25b084b012850a0c6117e2ad7dc803806a5d2a983bbd3b2a23c0199cca25af2b66dd9f4780f617aed3e8fd8f1b9d73ac8f59415db5e97f14c204f710ca44e42139bd39eb3971e13e9de3f48772220b2f1cc517abe155643f8ddce3bf437dbd5184655cd8f737047e88301ce1587d069dd7f0521e476f29a9856def84c282c3f87103e0a51b9dc997cda9e24890a496869e1c444626470ddef2dadc6a5a2bada4ad2b7d2cfaa7d539c6c738ccf82df2b1627c28e9d729e49ab071459e1fdc2cff09cf47bb8a77c2d7375ba2ca98aac738f18a55b372b122eb19dc42d29aa356fe18e0ece19ad052083ead5f1a17e996a40ecad1a68e683fc9b419b27d8c00439a1448d8482e1029e6302b525070b7b67b4e7aaf3cc6b9ce703c04671c52c98689b35ffeba2aefbb6d6279cd0b6dcc88b9180d2a8e0a663e451ce733850a38dbb278ba4fe9482b2508d9eb164fd37ef25964e9ea7fbc8446b6c4346d51eb234b08cc5fb4e57d49f737b9b6119e051c1b0ba3d6c19c40ce64b68ac04fc9f8a97ef972ebaa0ccf017399af2e0815d518b8ecb4d19ed7db30e99dd62064b136f2d96e66edfc55fa20f1cb3cb70a12868ee1e5c17722654c15e74da7641728005b2a138e9f4b930668ab5163d05081f18290e766d24a4e34609d8b235a4d420dd1b54bb58d90e3b8f4682250b8f4f66c1ddd8dad6cd992f6bf1854a8bfc3a72207c95dcdaccbd2a971d28ff0cf690387235f7203a1ed4febc7e8a69e4e73b58bb264b7c010139df84c80f6c8b63dd277d0ecbcfd8ff93d66d66583d29f778b81aed1c11092868a1bc72e4634889b65040830362cd2773fd2efc38bc9457c8c75bbd110a079130f38d0057fba390e750dbdcaa18ab8fcc679664cfb0345eeda3b2f90f2655e8592b95426e1a91c2a00b1e91e1478d618c3a75343489e00789b311aafd4989291a0f95b05b6c642e42eceb6be82e3df95e1b1725db9c3dc5d4206686cf390f1875bcca454b5118277196222cdf04c5d8cb1c8a23f35844aa329ac10753d02dda2ec5f2b0b6283c4c91125f2b64c9ccc000ed29f756128551caf52368aeca6465afa203550640fad21c79714a3d0704a13e2bec7a89efb63c57664343a3192d43caa2f04e49ee2022e85bce5bd810358fbf90487e8d4011227c199a9c483066e4fb317dd8af46c6187e55b70762e63bdae226802d20f3ba3f6055e197465aefa6537acd2c0dc78c0aebbdb2d4e8b34ff00070e12ffca9748dfc6764482b1f0937080e4111de8b9a400e03590c3ba718e1fb7568d627b16bb52603751f80af05a79024ffeadcb24879fa013d7210ec6b5985e63ece346c5e7ce9713fc40bba189d7cff44e5e228a01952785593b31469b3269f483e48a30f1d0ef2ca75aa2fc2b4ccf56fbc90df8ea4cde65494e49aa01748521a6763926ac71b1ec8c26f66b06fbda6e8b43e43bb8368588bc61ed09c5efa72b309ba37076c0a0a4e1b04ae2fa4c2140eebbf19953639284b67cfe6ee3e0ef1c82f154431071650620dfef846d2bad030e6624b8392fb2e55cb192c43d2f0e373f7c694d1416a3350ad63f58858e5935823efb44ec484c5db24c452080a90cb24c7bc9ec20851b4c1ab90edee04e973809be5f748cef2f0758cf95ba89a71ba13d27f13f2f1db1885a56447fb79e260c56b8131905e9cc36ca676df6b4f7ed31b0f3f7413da720b83161994d5137459b0a6d6f2193ef3717cd14bd349f8c9c873fd594e7c03543139071053086089904502e0e9a41eb1f7f5daea68212ea0d6e9e42e04c0542ec969c7631ba49f3e443aa5c7ea96c40c60bc2b175abbed4e0ceca35945210f22d773b15009d9f5a616dd92946eda518b4ea9094c22157bbe71d4b0371c88e8e9dc0a79fcd14e4ca484f1eb7521c0aee2053d83f0b47864252ee1e983dc92bf798490fb7f2149d5733ce3db3fea3c905ceda983833cc07f319e20eadc69351407965adeb381ba45d80d414d21fdef32d062233d4b1cea905ce29676e99cc79dcc002e70d380e60f388d51acad0c5f778107c23e500d47371c9ca5e596ecd715ec4baf0d630a23a4153af80891a4e3b4cea2342969a125457135710796961fbec09a93075171ca2a98ce2391f02d5c4bbecb530930aa5671ff732d6d330d42eb82dba70d7bd5799b888026d53c5ab0a5d63c97ebe2ee2ac6a7bf3d85c8bb84d481306364d7401f76ed5e040500b462780616bfeb441ede9055bab0e410d2f676e68d346a4e5297b8d3ed0d239ab155728d5e67fe5d722154bc1cdc60f8597d7799987c0b1021a4c82c9f826b7a7e0586079f36d3c184be6796956aeeeafc66a0e99fedf0b6fb5de52c42de6fdc1e6d5c013a43ed71be613ff6fcfbb2164dd16d0c0765cfa9319d7fd0382792d3eaa2f2fe778e949d62a8a1c9aecdfdee82baaffa125b5522a0ed833d06b20aaed71f446628125747db601d03c7314140f8aa2005e64314f522ac6d7c82e36f2a6265467827e2935ed017e610229c13b575f42b2866658a6c36374b975135a37e9fbe7db4404ebf810ef7066f7c62ac1cd8c8ff3c15805370bf3510f2fbc87b34b4c557b11db1804422f332fccbecf0c39fe8571a2be6f35692121d960c8d8bd8b76e2b2430c9990b4f818fdd60b00337ca18d4138dabc61a40d575ef55510215882ab47bcaa44d5a993a16da446173d044a06e9511c83c2dcb63fe08db0127759b4cdb011cf1cc5d68f902cad88424948ab067009ac9bc3ebb62151e3b9a5ef92c99243f1d795d8407f7de18354da2b8c9b7349cda0487e7118927ff53b2dcc54a776222d502092cf93c12ca50910cae16bc8d57bd42b489d87865961a7f769bd325c4a068c36be9505e65500e453d827ec9b6effe16901479d78b74a816df89abc9ca93ce477c3af117fb5975bb11deaf0fec06cef16b86b68ca3f13f7a60b1e4929178d35f5e645def10791c560c8f064e3b8c3bc01ca74bd809ea5b74dc685b42cd0bc8b3994778cd912511cd0850069afa8d23162dc8609c82743ffcec06969408df0452437deb35614db518556999ffdaa311586cf7173c55ab77db58570168c273b829072819ba2c2ae355484aa6fbcdf5a553bcaaf183d194fd8c6ce51df58e0e7746272561ab3478b01145c5dd6a3746551e69a5cb75361dbd184a6fe3b65f92bbba6988cacf130407e37c99c6d57fc276eff14c40b3045862e63e63b5b9fe81f583f58d03d02ea1ba19c849d429aa79787a56ce6e7a86322535aff634a644d359889f0475f8e6b79800471304cbab32f0f3ebb733b325f5edb8da95df78ef6ceed92377486a88ec81b0c37257ca3cd9fc769f23088c3ba4cd3605f77ba308e97f7fa6766dd4603c7738c356e1d7b36f56d41f3c25a083e72dfd969a852fc190891a74214349fb69562ffb68b36aa231915512658c3ac9f2a2c1377712b50cbcbfe52403268c1f401a565a0641c7bb1ced2b6fdc09e4cc722ad83a687eb995598f8af59720d3fa01bc85b4833563f096a0caa683741f4cbfde885dd89fb7b20aa2d7024987bd188e5416825301d86123bc0ef39135c7a3f0e28dad8de98f4e02f0240554d25b5ca6bd76bb6225fa5a08e49244dc9988be5d1965fbef9e94495a6747298d7f33b9b8a84e2a4c9ef6af4b802acac18526987619e09ce86e900b64e83d96ddc3ff6cd375ffdc58c9f346cfe26d2f7b48563c37796df6593b274ffa3dc35a4dba545f20ecd6b2e4874bc55bcda23ef12f39c2d1e7ae8015193df44460618157465b60f6c1c2c0fa5046920504bdc10ed654508c4bee9e00bbd325f6d5deed02c32a53f3296e5654372cee007721f13b916e43657b06bfa66ea1eec0e2afdbe0707a064bb731f5e5802ce3900d8c0603d1eb5ca11bebcafa0bdfd3ce04ddae776707f916b27e8224557f806e17745ae9df26b413d83013ca511e96027fec11412de148d4b673ceb0c5df0d8812c13890d2e3cb10ebd460f9c620e1a354d58a36fa9dd6218ed939b02cb23cc04b087a7d4aa6d601d36f2e6e1a03e5f497c969e1744af136b51761eb3423f91c20b35b9f02bfe6d0fc2af37f68aa7a494d86118295b40236dddfa892dae337cdd2bf1cb1e085deee0d256d723d979fc74fbb7bfd8eb2a2eb4364ce95c63f5b742fb20ff7992cef6f2a22defb1f747959718a0269faea870ab64408df838c4c3edc618e18af691445f64fc382f84bee2f8b46b6285669de8a5178fcbeae44cde5affd52197f54c8ccfcc8468a53f1d66024a870b6c71664584f600e83029839cb8284bb774019a173665ed29f11cebaa0b387c074d6803c6e52bf083a5d2a0715f7f2d370baff7b35de4f753582daf8c247962b1c85ffad6c891ad7d2d0e22daea491500a4cd5a0cb525ac656598dc4c18f8e27eb90f719f8c3f6e7844d2a477767f7b869ff1045f0e6e938810d02a1bc4103d7d8cc204e075e65c47881b10398a570b50961b4cfdac2769c6ac3d388ed4cfacfe9587e5c4e209549684760b9f7d78afd8fcf98ec27b63885ffd7bd74a329919a57a104109562df538d05bdc067cb4ba46ea178ecef47babf30677fbf34d273537726702d37a0f97fae6d17443908af94a4ea457002e89d9d1888a254bba1eb5b364f4c80da30050484b15bb7935a06056143f32895225ac77119d25b735c1cf6d71a71f101a0e0856443170c834b344c18ddf5323e305d9db55f7ec5939c711334dce1d64f44787aac03a04cdbb0156729b40b64ee7e3e570a709b175cc5b8a7078bdf6257a4d434fc332df57ae191e7239899fd77cd598ec0fdf31460d4b49885a68c97a1933aede95cca5614d5e34c4cbd26c372d82f883ae3cea8a31789941f696edfbd6c7525db9858e0f82de4d019ab06c2c7d89a52db13867b6723966029b6dccc12ecdba90843093845bfd5b4a5d859788fd1d7ce6e28cbe9a5b40a8c3d508cccf6361512f47878637af8a7810fe61f306dbcfbf6bb88ea8d7f16d2ed48133c8600660207f4525fa236fd107983127afc36dc24bec5649912fe65fec13941415b07ec3ad859b05a695e7b2791caef5e49d0f508bcfe4783cc251d8e1af023c236c10456058439025a342962b3ea7e763610cdfc6b3a7c96a2b945cf1ff2cd2c835485bff97672439f2a9fcedfced9f106c32b09b59bc60703f6470087f62dac55e77ef457b53cf326127491e571f026c2f8cde2d3604c52e2a45832eb7647a5e2039d0d1f509834ec6e9d60e26ec5f37a2f7053fa29f1de51e47d130e5169de4fd461cfb4b76b8f8595c36b7bfaa07a0896a5b6f466a79f6c5b4974750c7762a8c2213ec2176ecf59ab0cc2effa63b113caf753d405f610b415435aaa3da48d75b2da2bc2d1dc3dc3c7e9a63e3cd6375da722ac5a73c4dbb05ae8fb602e85c67ae8d393b3ef70b5f8eda7eb93ae4aa0f824d540de5e91a2fbc4d25bd07d721e5e629084f71a04f1d67416b7d7185c53fe39dd436ceef9d01241b4cca952c3cb46bc2e88744d153f34c0b591fece10640a87211a2785892114c0f1daa26e722b7ee39cdcfc1c147f76efa76a07a855f3c3f0955ff9cd65fce8e24e9c973db5887632ae7afec037a50e17b02a799f2bff9685c3f5ffeee702e99c4dfc984bb58f51d1658103acee5873bf82cc3bd516e2e85dfd7d3d755988223f79699b9eb3125c3fa95ff5fed1500ed2b8b0cad571dde47fd5feac1b9f776d5c9414ed8d26ec04b2651e1e1f0b10e48119f9d59ce38dac16b6b3a80fed6fee2cc7e474400abc0e5875da4d4c40277101ff9cb3d6564ca8f6f6b5d4dbc93eb17f586283a6c2c33f036bbeae61e8008c62e7fadd92d151a50697c1f23c697d7a8ef38a1809ce5a69f39ba69f017272e7d34e2ad7b7620fa1baaa9e764079928bfcecd5c4af617d4ce317d562ea232a23b1b19d479d083cd57e87f55053c4120317557b4ccda8e3b19f815b119226dfd7865bd680644aaf2cf33a47da526a0e81c78c20910fcb669efe452401c53b57356afd1229afccbb99c9331148439c93c643d72b861838efc8adf50006e88cc8be415b64739d55786d83f641c97b685426640deb180c454e1372228c6fc6167e80e01777b975a22e3c48356b74ccbb399994a6f8e4fc32bd91d26d8f0e78c91d4c853c6b6ff35c18ed93a3b40b71789d0b045299b29f37828daf43d3d1ae705526f0c3d3b42083e847471f66de3cb018c3f50489aed65ea2dda7f8e2511eb6aa12388fe80b68d897db7277644888d8f7e84e39ff78e03bed918b727ad35269335e68555d822eab7c7b38639a4139645f8205fe88349326c8faf2e7737b74c5d60de2aebffbccbcbacbb58df7a5a74cdcbb5ef90aaf1eaafd862cc67f42dab73855011c043c78873f3af0216ce1b2b8032b5c23b0a43e3160f9f0e6e3e8cdc07457c6fa3628dd72b5a150cf3fead105bbe9b841bd72c9d801227a29e7fcb7288f12289c730bc2a1ee4a6878e56c9f4bdf2516239026b88d4a5ab0817411aed08b12dfadbc76e53ddbea7b615b9d87a4cfba4f9ce62f594aff1a30721dc374c2299f390fd4e3e9108bdc4281f85f068b8a832fa9bd64e712544b2315b42d81c3e335f8e5759ca5865a1b45ea466a2a7efa82d7f4d421960fa6c53b11215839e20d65ac47468cfb7fb1f333b25292d54f7842290e8ab22c8363d3212f0b0a165237294ab91c6f58bfc88300d1b0baecea2cf5babc3b6ef0f973a234ec80a7a2f5b559b7d91c99f82e45252e7a7b63f69cb0d278269bc523e16ef2d7dec10883f6a2220b1c849dc731d13abb920d59fa4bfdbb18d8a9abe71e2a31f3ee7175388785d1e44a69fee27a820e5e7785031a05333878183a4168480256406890125fed87ca77a1fab4ef6583b4cbecf1e7b2ff2b604e3860bb679a11e2ddec7f993abf2905e2ffd5ecd9b5711f0ee042f22240af2101b5e29e62985b1a2ac0c51c7cef44b62476410e3976b326db1fae13c4ab4b5f5fa6bc1e20d14d2c83943386dfc4040db1bec83fdf3e7ba7e1840ba74738355ef57a8aaa2712822247c9e3aff77bf59425458445e4a0a92d6992a7d0c22b97564f83ee6ca33931389186f759faa395b644086654bb9affa5301604f708e5f0af2441b269131eaa518572a2272d148d9ad32f56b5ace8dc96093c4def4d2a91c33998e0b18e09cdb1c2a228946655f69277224fbffe10881dc344261664ab005d0224308ad77b84c5e9e7ee7b71cc40cabc7a201086572bdbdb6d7a5b60fd90e4daf25778c7da75408336e93e00dd5f206a2e2de0c24284fc1b0a5ffebb36b766c8298ce231601677bd04476a86efe144fe6e580f904020ac9d228061f22136a093a343c3cd442a54428f0e345849345af104f6c0a83cb44f1bf76dda9ec758a4623a120612097c74aead060778dd39629b6c4d772116b48bbc5c7ed4986eec15465201aff25ec63332beaefbf9235e2162e9cccd5c9ad9a08e58c96d4075488d5e383086d58f1c2dc002ca94e09339fb901c3fd6cb747486cb37fe1f20041f9c6b2ee6cc746d28590a2bcd01fe04a3a801f081d6d00769255e584d7af5b1a043e4d700b7560d405557c3af67f1838427c01648847cb29d05c1693d5ea04f4ec3bffcd8fa938cd6de857a49193dea3a1050ecf5a0bb94213abce7934f31bf644900e9465cf865868edffa4ef92bdba5a16dfd48a997cc6c4b2b6c4d616b4d074c74e166dec166c9a4af99ed5692aa419485cd3d7953e18698e139ec7307b74d8b84c9f94d86fac73a5dcf407a2b6456f4a7a111001d3a48b06a881e15f171e6f7eaf519c813a9264a86dc2a7d7d45c702101366752bf26ac066cd33a337c65c76c93f4e1ad7fc9bb0f0ca43a83ed7cf35fe9ad932d7bbfd79340c3fd8d61f84b8ad4c2cb605086ed891c5fc3da0381183866a179fc955b0cf88f1460e620b492de69d53a151c8d44e35c3d65bdc527f1855f13b07d45bc49a48362a2d64512432c362492671ab74b91337fa6590b739483e3a3484a2c8eeffca75b0461628471c25da07ccd4db3909b85e5a20df09d85ac01fb545625dc9cbdf78806796b5a38e21b812851dbbecd92e3b3594c4bd8f39e59085cc642e6b5a1b2356ae15f4a00ff9cba9e7c3ec742e760e0e4520d9c3c014b677cf5aac74c1c9500b94b02a98a106d0e8357ecc2f2ab363ae0d8c270c9a543bb257f33469b02384bf1a4843890ab329943bb10c43aae35e5d358f97d5a2a8f2ab8c36b86dba276f9fa4e607b04afdcc308850fff9c3eb46bde66026c08c89dedc7b6d96e91bf5fb3eb550182b39d5c89ac7554bb8fda0037d29f89f9392a2fb35c35b50efac2064f9f540fa8b78307c3d7db0a0d292c602f23f873220bbc5a34c2d3b6dad603b50b0934c05a6db27e46c0f85ce7493d98bb7ac56b24c54e94675d5517a5c73616e178eb40d5833d1f021fa8baa4e86160f1bdc8ce0d0ca102dc2e36008b27493dc0436c97d6e2976212f229713a2d33ccbd13921ce0decc6adc61bd398c989b4b37208cca4d57c9e524bb6976d7042811595439f4d58a85d98a36dad3f4112aa44b13601d13e0e97de50d4922c7d6f3508147c93e620cccd4225c750a539c3e482707112e5f8a79a89980a3ac6f993f7926f7ea959970a7c94d8a3b11e52658019ca09c0e7d8a0aadc2f322cff6707a65bae011430323053e7d3807a01f0cf0a1dfe6b2641a0d3e2e63111e29805f95cc3475ef3115dde93d3b0933b2de91a73d8df686730cebc7942549476e81a42bbad9c89a9e21a23c975f09d64bbf2f92fa5db19f2945f723c5e6d825ddbbd6ad9b96dfd7d510f3092755dfc7b759d08f8c37aeb1ab8bd445af960d8296961397e063418a41c36275670e65e10332b7a43088218bd836d5d3b702575a052f31d340034f64a2941f261e537a311c2c56ef4fd539915c0068d7f1ad0145acb88af7daf1c6ff510b76a405644c84babd7931bf1c09855705f2985beab880d6a30bc9e29317e3321726d4e10220cc70747369c4cf71a2fb6fe4c4c8efae276959a4ab33cb909a1ab307e6639cc65641a55badf6eb734199213c440289a37a1d936d0ec9c870e7514c6eb1cc3130ac659382816f6dbfdcda1bacb3b0799a61feae3be4ee21dded12048e4d5766a3ad9237d2aa62cc636a761a28868d1be495206466d1a99266bf9ba226ece9e8484b8c5676f1e1cc2986284aebb60c94b19c531931e2d0c23f09a471755ea49d3d53c4e3e4125db8cfdd7a8a09ee1ef9a7b61db2fe122cdcdfa9b750dedc7c2f329b574ff42d0934dd58db76f6796fe59b7312545fad99b929f4e29f4adf3f5c68827b446a87e28398789b9c98125baecbfbfac1b74a0103bae63d9ada8bd72c8291c22432db0935301e7cc2cecde1ca47b27e80f8677238210fc86a624c34042b68e1589c71df730c42a3bdfe2ac27d7ea7d15ab1249d07c6829bd2a9bfe710f3df6a8621675d990677b2f3381fe1bb132cf352a36b557b608bbb0bc13adaa04eb7c196393fc09f5339afbdc647e8b6de66672fcf9a9983191de3ba96133dc3bc2cdfe9c73e3e8c8cf133f7f46e7c3f2adb80197dc272ec44f95176580b6eabf159b6cf45776244f3e96c8c64825a6eadbd29e3851ee3ae106dfb0ea304b973cd4a136ccbd70dec7a5a6234fba70b1ed1b5a676b78fa5e187d8ffdcdbf9ef083fbf5f0d1e07028fc955efee2d7d1fb0f94716cada0a610c98e68ccf903a4ef5ac467173e8e0771d39e1a2267898171d47365f2c2000e6d93930dcade2c56d3cbfc620cdc2fa9fd29b960c2aca0295fb176b1618cc8352a9b6f160f80d29dc29a3c1a5138d39c97c36c9f0b59a1a5769ca450cbc24067dd65000898b6ff3dc41b19bb9a17548f2c9cfe2b30e4c8b2a1eda017e22f884e5697aa8d89640f0ce10dabb4132c001baf860f070dd2581e1b286c89fa8eb84563483ce08372c6cf1310218027c28e2272e927f46be9c444dbf78e27846f97bece201152380c2bf774aaf6d50f68721f1044f3e7837d864233c4db90b40163171986b574b2b258070b6e8b1284763613d792c257a12f5ccba391b6e26d06e7c5ca7009ec4837cc0f98192a9875cde1ac1d229e59a765260e8fa4807629311d01c4fb0316ba857fe05f70ebf8e0f260177d9168c8c03ba732f4214178f0f8df92a3f0fa73962e6ed2525dcb49768f51dbb442768824163d6fc7ffb059a75f8b8ca49eaab4a2aa3e03bf66f4ffd91307d75c6f1b09b53b29f2f2773c4641e4323296414a83d773913d15f593cc07c0c1bc4abe486aec3a48c1de23164f2e229ecc48a24cf20581ec64dccef38491511f79c852ac2d5457bf003e89662a48cb5dd23871aefe21f155fc9ed8bf6fffb6c9e613f7289c68b3dca1b0ba294ff6b0b1aebfbb05fdd8a65424cbcab8e11736776ca3b3aabd27044f949b970509b732cdfd4c9419e22f18c266172026148d51f6cba006608e035fa1b5cd74ad4666e463c87ffd0d58c173d02c2c9da43bd751415925df6cc2ba6f68d1894cd38e44d079e7f596d3a42d135b5f700188dbefb8e25dd83441e75d385006d239978968ee3c0d183bf9a60efee98fb78d1a50347d084674944f78781216ce77ea4f52a0cf0aa6c264507f34cfc54517b4e07a13197e3c6438a96d76571c93f0e040591e4d1ffed0f1c2807d2138269246da0cfde522f38edf7b370e03fe1885db5d3539aeb0444a6176f4f24f9e4c482aae8fc4546870b12f1b9e418abb48c41e71528a4474f881496cfa32d968522ac9acfbf35d9104338a2b2ac0387d6f44677dcd5d3453f318d89ae0abf4c88a724eb73a803aad84b3dbb4a355ddd1eca51e3968df81ac779318bfa61585f3c38c30c026a08e033c06955f1e4b743b38466b6b7200f8c9252de85ca491888fb5d8195e7d11d8596e4b583a4e63b576443f446b9f46d8f5bb4949c756164730496240a54f85e416a5552c9a93f38b5929706e2903f52604077f9623bc7927081cb9722a66b81389462b8acd7781e10a9880b41a3882060036acc5a371ee26f7e29f71857d73a257ae7b90c09ededd1044da2dbb2576052ab6a51dc44f00a6982a7b38a061c59ffd588498bdcba05853faa5d50cf4d03960c9344be7fdf68b44b56f65328e90972c10f748a35251b4812bc1b904d68e9d055a6d913860a1e2ab4a0e87cdf0bb89c67893cb8203784e2771183a3da68a319a39e15347b13af0b8d0392dbce9dcb6903a4f25b359131cd9e956c935b0494966438932bbbcaed34b374730e0050b5ca3f1dd82e8db25ae72db57d744c1741f18b7377e17c6e9186b6c71a9d46313fcfaa0026b0fb62b601f708e860742e567df188f44c1597ad8ea2fb0060346cebbcd0387c1f17b4711abb03f3ae1afaf0f59df867a4fb5767efd9f8cfa9259dd29f5bbc90cd7873cc076ec1f6c3540bfeb9d723929c4aeefc02f265d40f2ab9c35692d6cb3ad954cc7021cdc2cf875084e3dc548db3a0c774dbeb2315f3a9aa3221c33923fbad00b692bb984f67a437dcc4802d6e93a801442f5a13234f487b20bc40c5edb0d280878305bfb8370dbd5b170adfbc6392bc396106b3920bec0d3a63e2c2033c9fc41cd79282087d46019bd0bb17bee52c833d998db6b18100a551887b080b3ed9442ba30af4382a5406abd472328602b9f5bfdb65ddc37b6eb419bea9d9d3756f8d384820af18ffa02e32de964e0a5d3b1b75fd048da067390b5fdffed94e5a53099495c3d5d728d05cff30658ab80eb752a323b4b3d1f06677e858183d0a433c031451d9401a9afbb0bfa563ecf11cd2922513b52f79f0852a07daa5fe6941863a300160bbe07cfc5ea23d438fad2e4aef262ff687dfc376e850290e472ff55ee8107d4e8466d68c8654c9b9fa35e1fbf31e1865c5d1a5ed887d13b32076d49b83099286c420ab69043b9db3ed1810d97d372869ccb53d4e0458170aa6376c4126be983e4f3211e049619299c475e2852ac42daf960112153a46dab256f426463c17629a436362b00088a953ce04566d900a2a0cb62634d9bc22a05c84791fe1af05493bfe59243d8024ca91d7b0be5440343dca336a71fe205e02b3ca39b5efa0979f162addf292e995229142f627437e5882d92fb9d541538fdf9cf9f5ca790272e12f691da14ff1c3b5a63d44f8e3bc9c693e68c0cde53ebcb17b9e30fe44f4866f60e23632bdc692ee9cd6a8e4e0a00db836e89acc0e44aee9197261569cbb3766c6c619d376df36fec7a77f083e6343de3121c4276efed0c43340559604083e7e68d21b07f1349483918cb0e8c651e1711406e492e567cbc09e3b8ff7eb25de7f14cd2e20d1aa2ed42eccf34610a64d2fe3fe11b723a8e36e3a95036bbbd5b8ca76bf44764f657add728d678a598299e53ca7736ab1c1a39fca0b72c3f40fd74c6739f5caabfa60afa45f463d5ed7fe4b88fd92bb5a411de657efa3312b001f2edff252677969e19f3b19fc41eaf9951efff7144160968b7334f93241b6074ca902f16d780a143c294ecf0017b86d03a9bca96822c93b9dd085038196fb82e81bb4393c175cb2a559c92545c48d346b5974816a67c3017688439f9c1c6d1263b7481eb83ac581a88005559d73ccf6f68382cc7800ebfb65fb879b4b0334235195ad3e7c9c3c7f45bec6d044c54b3cd50e8512ca2bf71c10888baf14f4223d7455ee945b431e23b01ae22af99b58422731fe1cc4dbfe75a36da9b44c0cd1082e941580fcc7b6df20cea445ec9d5c8ff0f318f03c0506fd330d5db6cfbba23c73d296a4e49ed8b9226b631b7e5d8fed080cf5139a1f8842d25c35c5a5c23e34329fee4e64a12d79ad01697ae68596979b1016bd13d6cd40803c147a5224d2cbffda67902751a154ea2dc10ebc20df068d429472e697b60b67ac023d8ce6723f457c78e93ef87be2421df03fcb841f8d2ad5a5bb9e2ccf9d3032537fc9db16e1b27df119aa30713ea5962850213164d32c4175e934c56c5a00613488375c4e39ae1176606bf79e1733750fcd8aff65983642ac60d1271a9c4365af7d48b59bdc1e062eabf4904e181646d49eaca52d071d65c4bc436d00a7b94237404953b8b444933c3c5ee9b4d0e18de4813b507a58ae86a037aa94e81f4e02b6b5e01972ee68d6a711c85dca653a5799247a10471d5b0fb48dffd0f3caf5c90201262df96240f0848c02f5ce82dea42eacaf96882c58dcb4999c35753b733d6009ac80e9e49f00cbe633b7f4249e947bfd5618130e150d292b12e36c6b3b3fe8a0b8159cb5a2f160e3ea9ec271daf9d3ce3f82055384b3bfa081b78486cb6846601341db24867505cebc9a508214e07167bcf6877ea901102ff99b0a21f58c92aab856ee4e5bd579a34b026cdc24d09807177580afc0f5d5c210ed795707c6101d119c5e7ca334b4b3d7e7cf664464994f7d44e74ebd8d1d6e0166e75cf61df8a3bfeb605b059bccc8b0ca65a20a6cd62f9c9017e62a24bbc887753fab15f5198b1318c4318b57ff4f6ef39f8c622fd3491829350fd765e3268684d40510eaf26bf68b3e1da64e26e60dc1f402dac64f6e3517ef51b37073c321db4fb956c14adcd5f5620d565dd8e7ec916dd14ba60cb51ce861c55b7d31892a79a8e0c42ca9c32e0bb82a239ec55ed3113aaecf5172492f65d26c135b977a4f5c3bb396c4a2c33355918da88d80b852c39614db94a9a3b95d4d7b16c813911f5710c38fafb709966baa9ab6b2da64b8e83ca4dffb33ef12e818405686cbf32597c04e114191fea64c5b398c0901a17d0d540cdb23df83ce0d94cb8d2c1f3a24df6af2d18776114d16cd48a60bb674fafc53bab6ba2f75e1325f3148ac83c0c91d02d02bf81f86fc01ce554e7126966a937cc7597ce63f86ec46cecedc21f1e08d3f7992d834505bd0f1f9ef2c2e03b063feac80bb57da9b4650ba5eff7759df73f074a0a5f3b54630b080448845e4a90df898c4ff53d3c02b91e5dfa4d67acf9f589cfba25d377407b79b49cf7c787da3caa93f42cba758a78a42797f387394a118f87d9efccf2c19be11653275633fa849eba096c8886c845fe5f922a2001add80ac2d6bf306b55a8b15db4d0c1b1c39ff25ee7b8407aef21772e783e3bff3f20be2f7441c6e1bf1dc012cae1873f57389863dd240c335372605a187f05f0b51dd69678d452714e151eeb2dce75c330186ea3e0c9eaa87c632218457c4cd1cf2316e70717d81cf5df97421f6d3a41cff1916b89dc4f50668c665ff0e873254b417eef95a88066b2b0a1f1a2801890b5a78e117d3ae1450981454ae09c7c8b8fbfd1c8f92f839bbfa2f89d816ac57d12c97a677d8dbdacb261310099b5c319b00c49ca4d73afae45c12e30dc4d9dd39f0e5c5c7aecb3df1b9db88a07577d01ef7cd9ba172eb0bbe82cc97b1dfafc8d216984c7e24c3bd6ff2eaa7f3003b4abb3b689b43c81d423a1d80468ce64115487d9fb35098cfc4fc6547664a582bfe94a28a0b97c97a839b7f49f4fa3aba2e6adf8e38de90e46a7ae1f7a791cbdb318777264646f27cce7f8fe9c0c73bbef402bfc7234238dee234bb1d1119828359a5665cc715b511f9aad8d3810a925fff520615a6f687d68e20a7bf56cade375f389b700adc6ded373abc4a979fd23f54663213c91026245d1d814a9bd63888e3c78d0a44d00f6fcd0837f651e3cb3760ba021e151cf9825bb0608a637bc47663e06bf29bc3cdcfcd8b0f1ddef13f684cb859cd9af580b17b0c4485e82202d43e92cf8ad3116ac168562507a57c0d5789e525dc108160f8f20c43bae08fdae24594b8351f0705162d86ab3ae44d511eb11052db378c42b1df8c22ba92315d217cbfb95188d58bccdd13d62deeab55def673caae5271cbe55f020fb7993320054d2b4d27ac59334efd384de0c953f08be8d05d437a831aeaeadb1cfd02d49371000a8af56253f53877b1b353163a020c3f84a68218cbb6c23150b6bdd57da061720e3b70d26efa31884a5b627aec0fed84cbeae4ef97cde04cb5a207a96b6dd9c7fdc06e54ffaa9f737306dc943173f3d601c58fbf0f6d49152e4a6f346b67487bf6665c3104efa6ef4830ac353a9ae0bd9bc3f38e96cb60dccc99ef8efa64d43418736e5a54304b9f54eaef8c625cd8f5d46dca98fa81178cbd12eb52a2b74f4c9993bcaca369af876fdf36f64c717b0fb0364f27f3fefec4d9e44fa666209d5e21f24bb1bea1ff16d4d776fb35f9b731d8a5a981f0cd0a413ca41fb8f77479faa48d542889368251969951ba302a8883b511d3b5e37dbf8d713e579e4dc836781d3b9ef11f707b708e7839720fbb0b96d48b57fae034fdc875bc5f6682fee2cb87cda41c214b60ee573e9240071bd34b6817729c7ece5122ed824131b1c5b3f25a879c3aaed700addccbba69b3cc1c830462733d7e2f489d511766038c2a30b982c46676153b1d7d6e2470c8b7e90748f9fec97379f5b4e37f9bd3444f7e9565246f3ebf72e2cc45166ec2b4afa3b94fbe0edbae7e6cc19c5eb13112f864a28da29760e7831779b4af8c9f0e44d6dbec2368c3d1e3fb6a7cb31e3c3246fca7a6671080f355fa489f2b7a1e9c9e9e9ef17b909b3b7573e3c089bfcfe43395f5e35ceb1bd5e99a1c7226db1edb4ab89e450c49a29ce64707b2edf45123baa59ca9f9f95988bc289e3b8f549617321f055105a6d94f6faaf2164517b99c001dc9a1504aee55acfacfe4848951e81af6adb30bcf3d80aadaf1f17337df4aba7560f0787fcbf823c9bf9bb8b761f16df481d6a36e574c28a5786c7acc41ad994eb74584188f57290d01c1db457e4f49ffdf56acec90fb95737722fdc70cbf6e286b37c985f63e04bc1786f2793a929fe4ba9b7344cd1f47a61bfe4b8419884a42084c2bc6adac46ffe216ea2cc2b487ecec9c9caa2c4cb35b5dbc3b29882886452736b6536e9e973ef4d4bfce1ea3229f9442034d148be8b1d00099b505b74cec877a6d39082da9a35b96982d5d2d894388b42d4ecd0cc66bb03daddef08ecdfe4fe53eda98d70ae0a236c2038ff39e4bbef85a79fd1a75dc4aec1527484d31abc09829951d01876d9c777abce7dba14e04df89b3da386516e674b95bbedc8a48b6276476dcdce623da8fffa36dc95bb6d22b621f017d544404265c8a9d81912a6ace036db7d5ec43347005beb8097a434662f5f56aef1a6c717a9d98fd0d4ff958a8bb2ec7517b715901d4a9e22c66b150451682f3f1f52743eed71290ad60b41daccec84abfad4971c5a0a91b2d39ffdd199cc32f16161ba7978f447360257ed3fa6f01fb61836dcf9ddefebaebf003890d54173a07a2dd1d9d28d1a8fe2fbb1936e63687ed46a6cceb1610cc57006e48b58db5ca9d1e6df1259098702b692f7bc04b1e357f78920405a181f95f726e017849b17939a7ec6f494f288fd003ac2f430612e4fe0fa86cdf358228fc0c9cef4cd07759a54721c673c14fc220aa51a3ef9943422c88e7919580f75b6eb4dad912cda9781cc3f549caecb61c387d2cbacbc842c13a8a6a3cfa8f16c86cbecd3fe9a238992301a8c42024690b88ab85da58a1d5ac5861a7d7bfe786f3b8c190b202c3893c2a1f8d53606984964fa073d6731a241e7729d37bf301b063674fde91b5007dabe42e897041081184c4026feec0313873514d6a218d6df6c6f09356ac950f237a65bbf48c47d73a038f210a1f15ef1214f4accc5fdbc8bf1449c390697b12a9e3d9b99db6621a356ea273d833057ac2c58ae0ded3678c378eba5e4885b4266441fe9f82e3c119ad0118bb940082701f7dc057ebd9385a42cf58cda71d1266ddfae9a1d2e185274c7cc8c006ab160a9cc5d8a77e263bd8d98703daa52ec1080cf71251f70cd91efb74ed4c439721d8d7b0504ce0e221f2c98f6bd60e3d5a3f002f91c7588b5d20aa8d9f7f6fe25680c3563279d903ac8a27f69de517bd162a07ea64dc775940d1594c7fb642f8e258c62eb9ab176a8760c1511e67df24267084f1165c137aca9150b5adb093275d9a5978904f79eb638219568df090c4167dd67cabadc2a432625d5032648b2d7a225dd36a031612326cd45cad626255d2e6b66dcaa4204f8521b54ff25a91d29e5b64bf1400fe25f98fdf1476e1275ca024f811947886ba212108f63403151e4f5e6484c3230868390c45833821890c36432197a253c51918d26e4a3af8659abe29b807034a2fea248ee37db7dc064ba3295e4b626021fa79a16f124e16affa3be43d057ff8042da38d59258e50db158bc553707ddef8fd270a0d8fb431992203e768a174c81b58f96c9a61cf8eab72544ba42bfb0be70b8e93c0ef131315b12d0893d3982dfef0df5e80ec8c231546eb1c066a830840c7237097f307b3bafc85cc1a4fc92491f601af9eb9c3ed07d767b92c98ec53ee9f0f0e15698c05d985d06d3c022ff0a8a8f17a9b14747da009c1838901b2ca8aa4938baa8c8b037e6644150d4410a0b5491bc3300c268688858a0aa6e8608e02b668392d8b1f5b631b8d9a8da5db4aae6ceb002fa27907dfba4d782bbe000f8aecdeb4339254de1dbac0bbbdfc5687fd24eb0f9e0cf40b27b08d139806494279d00c8aad3a5c9c401e9c402128d5e4fc4099aaea6bf5f12112f31eb922faac502f1a3834831084a8a2b63011e232e19c70e288609ffa2071299274d2d438695438693a3871429c38cb89af13f62389ed54d01f585c1c0d93054ffa0b4f883ad6c409fbe184c120a1301038065c86c704d3b448304d2440a1003b610938d69a9ba1288f50441c8250c3f2801ffcb0871611c5a2a1c415419024141e705ce1c58b66103d7898cf0c555b68261045753279608200ca8ce763c5264eac70e3c40a2a7cde43c50e1ef645d5858d2124e1a48a227cf1a3d0cb5dd9802811e599a128204a745205c70d921bd5733fb40849b2c4668a0cb02469faf0c614202a64bf9811816250088045057a51e5630a4754a1e9640a3948523592240d1f2449e3461b7b58430f92468d3c744213094a4c07e573324514275340713285025078509101314e9e473a799474f242d2c91b4992c60e92a4a983544d219d48b106a90627526c7122451927527c21492c28410a20e210070d1d2449330749d2c8210e1faa23d2c0419224cd1b4033f422499a34dc20aaa82d4e30c0058d1b346d90240d1b2449b3068d1a502a7081345688b2271710802445218828d488020c2751f4800349664c9219731285e8240a21ede1c0c49e1c1440f9745072447182b206499242a00f553f1d29c78989154e50c43841f1e2048a1440bcc1861a7690431a6b38031a50cc2a34d5cf48e53d749e40f14ea0d88024492b404149018a67164922d1605f860a8528fa441c9e08c2133778c206663c918227a82772fc139a930a2441b20f060a16d5dce20b97203980f00372949828c2119a3224a20f6a98d0c1640e6e300943124ca660c203144c000092244d5fd8cf7f811213fa509dd9f2269c1309404992649c44401392f41272c14904825085a659759470128129aa1308b4a00a4d473e238ee8c867347d94884e1eb0054962142b8ed455f93839e18124893e584c4e12dbd9545888a88f2864ff379bca332b556931252b40312314847c3c68e6658a4fd5794bb180a80f16270db0815485a62433e68ad057f652568846d40903129172c2800e9c28208d0cfc60499258208303b420018628590423dc2841a3840c2709f080a4714333831304a821499f190d19d080a20331384180002449bac401ec19064822499a31942000094728421124c90c498a410c66408624955146a8c7013a1d901a450a94cf7bda09013c484a1620090e5042ba42152e70841f42c8010ea42152910e50e064001ac9ce0fb91b09400492d448363c78542702c81180499c04000e2a50785c8a0a7d4c47b4b91fdaf122430101557054bf48d501f9a83aa0e901c5740010872405917a9c00a0049274292af4c412de529f138d0f4e341e49a2b6902aeb99eff2a12133f43c78d4ce0cc9d65a6badb9bbbbbbbb33c618638c31d6ddddddddcdccccccccbc7af5ead5ab57af5ebd7a758c31c618638c104208218410bef7de7befbde79c73ce39e75c6badb5d65a6beeeeeeeeee8c31c618638c757777777733333333afb5d65a6badc531c618638c31420821841042f8de7befbdf79e73ce39e79c73adb5d65a6badb9bbbbbbbb33c618638c31d6ddddddddcdcccccccc8b237cae396be62266451a01269a2049d20cfd15b5633f44a8d01b99f9a105c5224379fe878609a1e78844d4e7a3c1424b45b1549a2b4892c60a92a4a98267cad0cf4c21148b2469a820499a29485290a459d92a2515a0cfca8746a2d1ed4c8a220a7528caf4f18caaa9fa0a0b4aec9024cd1992a4818224699e20e9a084e40449d2304192344b508224699220491a244892e60846308134b2e2b2d1426ad1051016b969e9a2a5456ea410225a74c1c5c60b1f5cf8f08c2cc5051cf58879d10a0ce5e901472bffe9c07c241049b44092248d0f7a603731a3ea3d33121c2a764892541201a9e40c48a8a00a4d3374535513a49141621f0c142c449ff9e9c4744231a3cf3f220d49b222029a91e4197926b505cca7230a51d407ca147a84171a2f44204992a429a221f2224992678aa68a23b4901a8105fba11e709445fd2226f0e69c113ad0c1082f6c872ab2f220a8cdb8a84494a772375a841792f474fe506929623f3e66423386f2c82402119224c95c217ff8f8214af2a32e3e2b2a2d459ece1f9588f2b8d8a7c2dd08a50a77a31df552d40d21516929b2b92124a1078d2a44b8808ba8b414516929f2e94ccf10974a543dcc10106856a3ea7308151068f2e0b1015552891f2428c40089219214620cb09988008c20499209241d847843920a1137f693746e10e2708424491e8f6322a11fc283c7065411c223499214253ae288e30d499274c43102a90b38dad0a1b079535d5143d515b523fa1836723c8223d83c723772d781636510660091248d073a20499e5048564d0f0ef0a7f2418940332120a24f871a8281900f04310641481a0ae808440fa27080243d118427cc084403a44a93058fd04bd20c208af007454892540249072056159a38a209ba62468485864715fa4e0b0a473441281e8f0f1e3c74fc21057e8843871f5c241d6fbc21bd91224992157cc8826bbd850034259274828d1b3d9024c944d2c1072aa4246b4dcdd3b2c20ae7064842e181d2c5152b6e0c91dc409124e93d9d3b61664c1b9a9024e943a40d38d440d1b186019ad0860aa436bc90daf000cc075aa1f242c48a0fc582d286244928f6d339c286212410c5c61924141e5c8409483ad84832a4191b3b24c91dca870d014892f459d983225078d88e1c244972d1b18726ec218924edd88310499276a07cdd438a24ed40d1b1870668828a1d6bb081c223f4301d6ac5435923079224893e6b8024141e6b7821556baccaae610022920e3dbc21e9d0c31f241d7a1084a4430f71d4cf4865e6e38362599124cd8e25499a2ba4c98a07cdbc4892a60a49d240f11e3ac3e854df22499a0d5492a4d140cc7bfe41332f92a4a16214b3a93a92a4d93185243d6846f4a099299a97925334b5d0a1468a068a0c4892a491423445530b22208a054451422449937257bef248fb91a11f7725f443923418780f9d2fa11f9fd04824aa1f0251212d5c8288dec5332b25e4ff25886752ca1344f42e2a2a2e10ba40e842c4b10b9166765242dcada8a8c0662bd0b1bb15cd05242e64a8501049d24481b222491a2844d547923416a88024aac20043365b7916214244414441840869b6e242e483345b09030ce96ee5598408110511051122c4dd8a0b910fe26e050cd94c4524a4998a2848339517d24ce58334530143ba5311e24e4514c49dca0b71a7f241dca984e101d2ac59b39595951517222b2e4462ecc747b3955017cd56429417cd563c2ecd563ccd56c2f00071b712860888bb9521ee565656565c88acb81089b11f1fee56425db85b09515eb85bf1b81009715cdcad784222aac5dd4a457d346bd6ac994ab366cd9a356bd6ac59457db85381f1741e883b9510457954dca9a888aa0fcd6771a7220a81e1e24ec55a1fee54e8c8c59d8a67c4853b15241d2ddca97c3a5cb8534932b970a7f281e9543320d00c89a059339715222e2a445cdca910a99f51e8c5dd8a8a16cd549aadb8ac107171b74204c810772acd5456dca9ac346ba6e26e45f421d0b7b85301b284396041b21398c3169224e99803cf410159a0a0f0f80284c24556111ff6635eb412a2427280220e3fe320461cd6e4c0a18283186cb3111c5400872924a99a28554c33ffe30d492469d38353cd2d50aa8992451a37e022312fea4892460211903e8c4e15f3a24eb3d187d1a9dc504992c4bc38c2e79ab3221f1fffa1649e45a5ba1f1ae2a1286abf873b2af4617ca8cf045513e4c28621fc70598321d63004697a149967594305663649dcadd84fd2510951a23aafa53aa1ca7efed38179eae97c0d5194e77244309f0f813af55b5ee4121a0199992c3fe3230d6974a1230d4310511e978fe9bcd84f0704f6d339928646431c68d041094494a7aac27e3a47485082890a2beca7736487fd748e5c6ac60382cfcad70972b1ff79501792a46180660167c8e20c28d2190a80c22326c60c1f141e9beac87cd006049a3c78446ead435519a620bda8806086783a33468aa84e0b7d117826cc0b7911757eb8d64766ad0f02d77a725c5c6b4ae6a599cc6c6126335b1693992db165660b6c99d9f25a66b6b896992dad65668bb7cc6c612d335bba6566cb6a99d9125966b64096992d8f65668b6399d9d25866b638cbcc16c632b3a55966b630cbcc9628335ba0cc6c7932b3c5c9cc9626335b5c66b63099d9d232b3856566cb929946c8e0802a34a181051d687840071a5248d218a820d98f1955a339a4fa8e8e31144092c4700669b262d8c124aa3a42445f8961b2341b8188e488e34554910f513294108a7aa97218a21092247dba683602c30a2429471c3e3e44e0a83e3464109294431081908e544a8865f91025aa428fc443b9f0e0f13c4413a5d90845542728e66d17782049d28b2824ae39eb242ce43f140b17c2f080debe67f36174aaea61266853553d9a8d389b23758ab6108298da114d198f6756fb9bcd666dd6a68baccdda7091ea5b3c1e1fb5ea70f1af22aa3a9ed07790c0cc1f1f335d3e2b228a85a5d9880a7d7079b11d205c641569c6a92687534d4e911e3da0cba2191177a3b754eda1630a389024984f67c6e3f141b550a224a5240a0a40a0128ad8c2195638a20a4d1faa138514e83843ea3863c8342945015285263aaa2469650a1d5090c3ed702a8903137540c1495568ba42f4e98c603a54f4e9c074a81531a34f35d7c44850b8d0c113b220bda07c3592410e9327c427a048f6613e2820aa330249059c8d740227882449ea694d8c44fee8a2e5c5e58b12a9e48c922a343da542a2aaadf8743ca18f59430f00804d384392a42fde43911ce984ac98f9238f279f9615309427871a9294230f9294030f928e2688710749929078286a088b085a26912042beaa7c803a2f9d992454a80865472e40aa17899ece1f445cb208514078f02080ed504578f0d86c389b0e686e4055d58335379bf6139a1155dc3df8916c1c3333f3e2089f6bce9ab5c86233b3983fb2783a29f5928252cd2c8aa05401820d920f81cab084244d2865a0a1a38c468624c870021949282af428a03ac880128a8e17c02149d214eabca0063a5e9044aa4414cba4e3053b2617a4f1a1444f47d7053990241d2ef8a2ba940be01896f850a11f238d313e44cd9719832349938e31c650c0141fdb411103109224e910430b301f2a242302205d7c18a11e3d7af4e8228b2c92503f363233546d92cc98169ca0058f0570b0e0062c60010ba658011e56f082158460053b2469a258a62355473402cd78aa98993228339f593b9f09f2783a321fd3114d199499cf7c99a8a876a06840031ad08087a240339ece8ce7fe87faa8600d1590a1024b89503ed6043c787c353943be2001ca4b0a38a1230569e8484111244a3483f29c2f5270002fe808630961804047180f987184247d159b8dcb0c0f663a90a410497ea023892889053e9d19125d41a1cc7c6638a2102523aa461765a68a992f3ef6333955f8c8a272a95ca8f8fc40a9c2435174478f1e2f59802811109922320298bef8e20b2aaa0051a21d4190b071a49a2324399024c98a1085c40b898241b29084466c48f3c7080cd38fd18f0020ea822846644575081d151a3c78d8f6565e2e4ee765bbf282992f5d94b8415af66e2fd6eae8fd67bf0d92e3747ce3a48fba4b091b9e2ffa6ebb3e1f7df72d1494ac414edb8eb60b19fab58e3afbe98000aa213216a35b2e3277ee3984ce756cb7b9da1546cb6ea64136aeac513bafc7dbde9a25689077756dbc286d4a2b7d7b06591fba7a6ba3fed331ea7ca5c40c3246e896ede6aa776dff6590933ebba6d768db65bf22192475d335b3e5a8bbf442ca7930f3659a60a6689a426f210b89406848469fad85cf698d77353a06c990c51bdfd106a97b3dc52097d7ee56effae6ebdf711e83f11b516d292f4152c0901fd37999a6f788e8a89aa669822c4636a39230c4e55c8bafdd5b33d36b9bf2b2b539eec7791ca2904ccfddc0743c9e779da4040cf241cadcf47adb85d0310a5d48c917647d4799473a632fbab8398fdfae1620912991e843a2aa138a2f255e90eddafa59bf1bc736db7bbec3f248a8d09069e2caf3968ad9346fa2a40b925dbfdd26b79f9cc7d64e6b7d7c3ad41039d97f420917e4b3f6b167df5e6f8c31dc826cef3d76ee55e8d6c6398a619e1117d304f150a205d92ab5f1d5d78feb43879cc7475a8602b52c48b7de366ef4beea4d9f711e77362130aa9ea67783122cc8cb6ea9f37a70c549a95322c8cd239d04255790cbdb9db596ddc62eab97f3787137e86ec4dcf3a2c40a72b6af715a5b5fb3ed68398f8fd409f2364dd3e46e344d9ed9097d354df6f347eaa4d3e4af648c922a48f8d5c6d870d6f88c4de63c7671a1e999b57247de33ed23098daa6316239b1e255490f1ba696f2fd666b3ed6f0ab2b276bfa953c6d7be8342a6490af2d2bb608d6f756bebc209af88484854b96331b231414914e4ebafb459c7d67dcbb4e40c16978d913176b4a785c2bc7632abed1032af469f10695bf79cb9eb6ea55de204595d43b69e9b9fb6d6604913a4dfc996564ae9b3bcde723762825cf37fbdb858ec5fffbe53b20439e17458bfbfceebbeee4809d22d8495ff45b7d6b976dc664912bee37af146e670f1bd8ff3d8dd03c574181224c7492b638f526699d796e4b708bd0c25a44f507204d99885d727bd9479d53a61e747094a8c2027bbed59c7f9f3fe6a91c8344d53cce8e3588c6c684911e45bfd1fd9b6ae0d3ad8bc8408d2b9e172d4dac7b859ee583204e9b8b1061f5dd5edba0d398f65fec342ef1212b930bf90a862254290d7d5fa2bae7819df662fe731bca251ac60485431561204c9ec91ef751c2be5c83c66f379cfe31910559b6da3949714da4629b1bf0408727d5df4daf92cbdb1236d404a7e20fb56a66d5fa41432ffd91e28f181bc77ce06a9e3c990d1c8af07f25f84cdb117df9a3c5db49ff71f253c90f72d7d1effc5d0260629d981ac4fd9eb59613773bbfc79cfa69b16253a90be7c460a99df3d2f6e939303c9d6d25ae9bd1cdd2e4a398f1d8744150ea4c3e8d0b6bab8365a5be3bc4dd5698e253790ce46c673c567c8ec98721ebb8ff9c6cd6fa9daf98cde074a6c2029f5eacbb1b3175a873124aacc90bf9cd6d6e0bbccbdd8d44351748b921a48e75864af51fad1b1edd53490aed93aed5ccb456b9b35b72e99818ccdadb9536e0ed7bc8bf3986d363023fad6b50c24bb9fd45b5cafad5d6c82d854120339db71f7e2777456e8cd79dc2a2530906fc61b9fc2f916b56b3dcee38ab2ce2d24aa5c4919d25a16abab75fd5defee9221636d7d2d6d2cd2551fbf921748c7b5f65ab0a3b3b3d92e71819cf6db3facf6ff17f7978c21ef7b5debfdcb1c63daae084ac490b741d89aba836f396cc779ec992198177d3a1b3b41cda1174551cc65b005eeb11dadbe2a33ea9cf318368f36a2980b250b2a8bcb276d934d7addfc7436ee461be798d18709598163754eafecf69d3777cee3e6a202e91c8cccdd9eb35ddb6a5d2990acadcfe82cf79b963dc679dc5c98a128e6b22cc2907efd51fbaca3fdda99398fed6f9c5d8b3392521629dbd6377ab3d4f9b073c83455143a16231b9824325af85c7de83ad6c9e064ec3e44d59691357e7bee2de60b23a32e3616231b2f9044760eeb7af4d535db659b91640fe16af5c5791bf2f5888548c6e5ffdc8496357bec17e77105b9923ca17b6cebf5ca666dcf79bc61dc42f2fdc256237deb9cd1c89cc7ad0a3024f7a3b76f8490b9b6064110bae7acdab5ea4706d9a4a4f78c7f67846ed95bb582623a8c7e248c77bdbf8c3efe5be9c7c8e6f7da2ef66f6aafb7158f7431b2b5b05d643c672fea7e566ae733874cd36331b2b9472473ccbafb4e069945c6603e9d2371a140b63867b7566db4b42ba48c29d71df93d59c3aebf5cfcd79a3916239b1270e4336ef7b95557a3d72d384d1ecfd769fa108c74b6eb55f6eb32e89e3ae7b1ed6c1e34237a1f1fd334f3998cc5c8465ee97445ff45ddd1e66c9df3b889626e065e72858f3257e383d3195bcd5609acacf7fa7adc7ad2ebd3b2247605e6335ba6e9612a10b5e1c76264632b7b6c113ad8cd1d8b8cdb6f33cbef4e4ae36ce6cb79fc222425f4a29569fa109069b2df0151759aaad08b40d3cea9178744a0122550099fd97b778deef176fd50f1eba78b8f8a831588e231253f7b93a17b945d74479d6331b2d97cc19c37165fec059941e8fe9c57637451e775b1a61fd98c3b8b914ddd480b1985cfc2a60e42fb28e7f14c4804ab1af2e1550d4d8f2c46367e02c79039e6e6cd7163e6a037c3d8683b1bf95deaed1c13c86fabbbfda573f27a7e4b20ff3d3285b63d7576d049201bd7faec3ae8aab769dd76a88d6331b2198111f9e89cacad5a997afbdb11c8f8b6314abb1d737a1715e285f479eb57766f74ccb4af08e4aaf7c5c87e9bb1d58ebdb4b318d904292299766cecececb3aebd4d53880a857e9adc6331b2e91071ad57ece7e05b8b6133638fddebf2e833c2c7cc3072de344d93f3900884821779a3d3396375adc6089d398fab23f3411bd1c344b7d9bce748e86336f4486dcd626403c4455ac8de7270dd672b6cdb388f31d022adc717fd3686cfb5785d0824e3d5b6a1bdb4bae7f035f3907f0f176d96d77cf53b86a00bdb5e7cddacae56af375b4bb5b02c06eb738b42beacc245570b1792553759b3fe8f596ad9e43c4ef5d80979104e7eeb7174cbc276efa113c4ed0202796773b4f536befdde6d9cc7202a64797d405e861fbb317e0621dfc979fc1fca5337cdbc22df3adae2bbfcdef557e63c863fb6801c39bef5da41f61673b39b6290783c9364bb38cee66efddddb9585d1a94621ea7a40319d6e31a30f13c55c9920b2ae8efcacdde9566bffeea53651888a7c11bac3d791c2f51cab52327b993a870dc6bf6d4db7a285b4d32b64ebae5b61b376711e6f18b3e3fa48581740e46448adbdbed8f3d3d99cc79b66278ab9ccfd903e9f8b753ddb45db5f1585a0077cc8666f3df36963a4efadc579bc79d003d21d3ebbfedad93e1d759cc7905f072483b3ced5ebde1827e4c9792c438560b87bc837eb73cbe6536eb0c5cb791c12551c90ebbbf56dcdb173cc59e43c16c5dc48240b79dd5cded0b98eedfa659cc71bfb991bca72bf116021a7d7472b37eb687b66c879cca946a04d88ba1be7230548ca4bca8b9094fa45ea23d9c8ccd06b2c46364278c87fb345c8a8e5efb72ce43c0e4d4eddac491473a7e9435415816814b3598dc5c846045142b771d186937a3be793f3e02845a52525e54548cae6d3791d1281d887a8ea2c46361c80b23e6be37d675ef9bab9388f43ff79922e08e7746fb5c5ed59ca795cd9ff6a237a98c6292f41aa99b27a94e2324d33e54548cac6238b914d890c5c6ba0d9d780f3142c02dd14159200531a5812b8c2025304aca04015bc6303ddb91f025d400313a082023ba498428a0c5c408a2b1aa5f0e6391b0a60c05d052e9084921159200a0ba040e15a5b80613307a502cce3e91c5914986202f3433b2430f347aa88c01410d850f10051688aa638690ce880e954513880ab993fb2d9d1002918d03154dd6cf8886b0daa5fbd056c7628000309d86ca440c026c98c81e20030946703f3e9c0c0509e081820c60205e0cd87ee2644892605083000dec44c118a00a80880fdaf36170040ca13950666478e8dfdcc8d9bf0460325bca93a9b8d28c96340f249b0195028f998f9d1b0197d304001a4365ee0081fd20e7490031cdcc00666d480063390410c605006192f70c11862b480052b50410ac298495285c000519f18cf1114743830f76da5f38bcd094c500212181981a4a30966483a9aa0891c602880d4861860f02179200090e8801d24a96a44079248928402820e3c213d128a7aa8da630d3d9a207a981e64f4b05af448e9e1000e48e2840376c082c4811c70400c69118a901c6892cce2115920e2d3a158baf359c902491643b2a0408924652161f1862461e1052ccec02208120a0f2c7220cd7c7c4892261188a82e92260c27583880872624942a78acc1c30c28222a08ca34adf048398421a4dae1804254cc8c87026d409468f347664c54c34934038507caa72324824ea2094ea2072449a26207ca099aa2a2024ea02002af979d8bcdb7f84d19c8da8b5a56d946763dd218c8c9f8dde7bd60b35f87815cad39cea6abf172ccbe0c19977bfc98838d23fc66c9901de17d089d6defb5f802c9eebbceefcdf68db2ea02492b6c18977d7863f71c4376743a2b74d4325ff7e51043daf6bede8790a3b3d16b27a475b4c2656f9bbcba3527248bf1cec88d2dbe90996e42b2c5fe99efbba76fba2664e4ebe65cb523a3f4ae9909c9973e65b7b7c18e7e3121ddaf576b74d3c2d96d5e423ef7cbfdb3eff64dee6809c9ff0c5a0717f51befad847c37ce76935aafedce2125249d8e272fea209b4cdf2464d759f9dfa22daefa4d1292f6578ed6c5b6bf6024e45d8db2e59a29bbafad07095923bceece603b65661f21a765cf7fbeb8e0a5d61192d5be7fd9e4c9b339d808f92cb3f1da767667d76b8c90d1bd3dda8f7b3d48d91721fd397be7cf672b5f5a1521dd178dabf93367b3c144c8cacdaeb5ec22651e9b2142b69bb536b798ad6ca33d8464af56dbcc3c9b568786906d1d5aefe6f6d9dbba101246d6737e74e8cd1242b2c81ddfe30b59838b3b0ef9b87937bef7d1d5ecc22163bc4ddfed7d2f3e1d846cc8b7c5b6e074ccad1784a4cf5ebfceceedeae61c0819db9b2c5e7ee88dad0a0849ed83af419e75c23be31f24f3361f7f74b4b9c86d711ea7bc04892c46362c30f1839cedb2f5b1ad7b591fa4c74b1bad9332b6be46ee37e46d9451f73042e66ed15a01f11d98f0c1dfd1775a1983f4d5673898b821979b96dee66e7d5f5d534f790992c20d0993362adf5ad9fe7dea1a3664c3ba76ddb9afbb6e03fb0c267b90ec8cd558638bd0aba56bc89f8b3e9cf3d2ba685d1c4df420dbc15f347a9bafad852f4a1335e465bcaaebc7deadea6e1cd20224c5ae4cd3102129ce358b918dc919267990af59e85875f6dea06d95f3382482292f4152aa0f202922aac8e763545a5266422faca182091e24eb55fbf1a4eed141fa9cc77e0749996de62284ce1ca59529133b48bed4ad66f0ef7ae89cd641ceaecc7e2f76fb68ad7490ef6e4f7e6ea616421add03267390fd60843edf84d6a77b4b0ed2a34fe66b9f3d52bf1e0709d74fdadc2f16ffd566e120e36cc6ccdab61a69ac363233b4ba0b9337488f90b6f8e6ab2f360b997f98a421edacbce663c691d947a90b17dd5b98b841faabd1328b3e277bf33658039336c858a3ffa38dcdd896b187619b206c901056c8bcdc5b5edb83eb6e8ed4190292029b47292f42a6a95a839cd5a37dcf986b0fdbbd1640305183e479eb6c0f2bb5d6d1c7d2209bbad66ebb471a29f5478364d5e37acc395a5985ebb9c919e4740cb6eb7a5adbbaf96e4ccc205fa5b6b93fc75665ee1e91212665903c394e37a9b3962f7ded8c98904132c71afb572dfcf518da24d48f69b29f84a2f0814cd0e0dbeeaf1fd20b6f739cc7ac81613206d7fcd88b8d357d7ecc793c93840a8136949da6bbb1764e5367865e9849224cc4305fb5b45f5bac3de77d6854519e3a4d53e83d9e182aa4b21e17c2240cef3a5e70ae581fb4d13d189c7d733ab53d2b6cfef00b72b1757d7673fd66a5de9cc72ee525488aa7a33245c1c40bdc5c65cdd256a985b1b92e3c1bdbd23abd4dca1ce33c4eb16f9412d3e154139214fa4629cb45265cf8371facb71db37651cb792c1ac540d1888b8f4adb026c6ef56aedb9c6dd1a64fce69bd746e79abb4e3d9e59fda3d22030d1826ccb1a3ac8fc9f7d6fb61504932c4867eae6643a2b6d079b731eb766662c46362e265890cdba069d4dcbcf98f6e43c66579071c2bb38be7bef627f3d04132bc8ffa737fae4e8f7f97cce635705f911367ae15f375d7beeaad935c82c46362a26549073567693f2c3087f7af4782610b8e13805792dc765dd84cdcd27749cc76b39becdb118d9a4984801f2eaf62284efc1d51a3bf77dcf2d8fb53637635b6d1205e96e8b7771bfb7cbac3e108b918d8cc91972b1e5a08dfe1e3e9bd78251b90f1328c8cb3f5b651446fec93a4ea59f201d65dc3d2f53187d42a6448e7a6113274886f6e73bfb8cb5fa2ae53c8636860aa938c1a40992bdcba67dac27b747df5db498a669f2314dffe9dc3b231bc184097245a78b31857cdfb4fe388f3715ce783cf34e936b7d642d41da67b638ce18e37cd52fe7b112a43b07aff3ba2abc0bc69504e93f9fddc5fc39caacd6161324c8f962534b5dacd4f9b109f31f47c4e408b24e678f56efbecdb6d08701999a1841b2b35add63336be6fa721e7f189de8854911e49dbf9a6bcfd1c5a87d8b08d2fdb2d141fa66753152e63ceec7ae932cde5c5eec5a1f7116231b6b3204e9bc5ccfe9edf2377bbd0c132148e766ff73778cf673b03d4803932048369fb2d71c8b6d326ceeabc919f2363c630204f99cbdaf6db40d726bb5b24cd334b118d9844c7e20abfbaf7eb698e3846f721e3b2f9a890fa45b3a9973ae9741d87f7b205b7cd545fb2e65d6c1f64c30e181b4363ed61ada7676f19dc90ee47aba28eb782174d7ec7520dd9dd3b665cf368ff152931c48777b2783eb31bb22e3e7e2c28184ce5f63ef39dbeab3fb8603931b48fad839d28ebe9ef5d9e00e4c6c20eb8c2ebef9dcc15ae77aedb118d9704ccc90efbeb7dada0bdfe4781b6e4c6a20df3167a753da9c451b8398d04052d88cddd2599ff31856cdae99c5c80688c90c6074ce9c6b7f10765cabad685babf1aee5fe276b9cc7d3544d5343622203596f7d75dd8ff73d378c233089819c7f9bf9c6c9e8746c2d0c644fc60ee374ad52669d97d1984318dd45778e5f5bcc316ef1cdf687acb137a7bb266448baeec3ba38b63ae37bd85108262f901c63cfc50dd6875cdda10f4c5c202f75edbbe7bafda86537fec0640c392b6dd4b67737da7cb69939649a360c6d6022863be7b55c73ed357c9039b8daba8d5aa72f42cee3fa5564b5a413322ee7b35576ca9abdbf9c57411e259c90ce36666e578d1f9aa3209e394dd32446c926243f1a1bf2b51f1dfb47ab91688aa6695abce15a7562dc394d48ea169deeba7b4e48d933212fbdb1cec66e7d7ed15ac79890942dac7fffc218ed9b7665c3979014d2e50e2ea74e7b5d670969af853e9d9dcdbe52d69590df78be77a947cbeebc8b12f2c50b639d8bd955198d91eb570d48ca8b9094990701e4c59bda11813a1ecffb24e4ac8bbd236b6c424948e7e9ecff47d79e832ffe480192e223e545488a5b33288984ecf6565df48ece7dba2889f4e1a20510394dd3344d90c5c8268c1248c855175cb0dd9ef436b695f338446d440fe30c1fe347445f0df9f973065fb7b51c33c7d5f4428ed4fab5f03942ae76b7e79ad3679bac9df398ba9fc842d983665e5e63414923248db0b1fb63f3dd1779aec0c808591b65f4d9e95eb7858e721ec7182aa4521fe4b2796c11b2d969335bb718b5cfa822646cebd9fbcf5bf516991b414922e465cf1d72bf35bf794f4448f7e5fc6f63361947f74a0eb19c47e8abf98aaef16bcc1e650cd665dfbdfd9ffe40506208f9d37943d86075866f7e2124acec99bfc5bad967e12384847f1dfeab1edb743ae390f317736eb96773f6b21eea8628d154490192b292f222240534b99826d08ce9324ae090fdeee9a3cb32c83aaee83fa41907258390fe587baf7d9dcc7fc21b75502208c93f21b4f7576366cee683665e88501208c95ffd7f51870d99afc8bca9420920249c175a667eaef7f99b4c09257f90b5698dceaeed175f73c779fc1eca42d4104af45999a699d0342d1794f841be65b66e9b8fceda16bb73913ec8ca13de1559a3b732636f2624fa4817672a94bc215d64fdf74e36d763cb66737c908de965efda581d8cad35b8dc90b5fa7dbfdab1c6ff1c4e9333926962deb03312e656286943ce0a61bfbf8bcd7e3d1925fa6c28d1a7232a61433eba383a6646e9622fd23dc8dad6dfadaf1f46d8ba398f535e82a480a89016d304a242769aaa69aa8f6495ac21efe2ff77bfac46dace2ede70e56644bd84123dc8051775d6ef5ecabed52f324dd334239aa6b678c3a2cf9b1135753f9d2794a8216d63f1babecc2a3f742b461894e441de6bd9a3ff36ceaef7effd16519dcb8c123cc8562be5fae0ba6e417fb889d3b4d9cc696290c5c80649c91d2483d646da5f27eb1669b483bc953ebfeb75ba66b7da3a48171964b8ae57ea3532ff50d304598c6cc028a1434718577bee45065d2f876f45c6b6319dccbd2ea8d292c24222d01c64335fac358badeb7cb0c941aec8d7c26e8bcde96f31ce6318070929bb93f6b4bc22abfd70906dd6196d8bebbdbeb0716331b20941c91ba4a55eb9b11aebbc0c574d43062f4252364d038d23649ddf3e46c7ae1fda081b21a3ede9bcfd2dbb191a46c8c8eea3b4c50b2df5e7e822a4ab8e99f7b20e6173c740a3084967b5fdeeb17395e1738990eeba375dadad5dbbd5102161eb0bafed09b9aec9da2124ff7dd3f5c7387dd96a08e922e5b7babeb5dc72ad0b21ad63466f7b3769a5712d186808e1bdea8bdcdc1ce1f78cc3c5d68dc1c8adb1e7eeb56efad6a5ee3dd8e87c4e82060ee9ea5bec5a7737725bf7721e6faa8dfd7cd556a019847c666dc1e7bebecd5717e7f1a713f3a4a011847c3376376bb0d90addb46ff10d348190ec56fabe3d63ffd673721e57b5534dda0c9da0018484b75ad7ec6c43e6f15dcee3c647429408182f012841f307f9f8adf8a2c3469dcfc63e0fa2366f0a1a3f48db9a2db7dceb56576bd5e480b81d15347d90adb2e50aadff7d96b5c9dd469a37e48b7ff9b6bbfe3d5d35721e579bc62548d0f081a7a57143bef59e1bb4f645ce63c647d0b4215bc3778fb6ab76cef63c76e5d3c5345547288ae3adb5d6dcdddddddd19638c31c618ebeeeeeeee66666666e6089f6bce9a81a4acf780462f294384a42c6631b211800e346c48f7f6359bf0d9e9cfd5f620e3e2bfcfd56b3d46ebb8d9e84dcd1a92ad2fee3a6f63ad3646f520ad3b9f163e74ecae7b5ba3c6f2e570b1079b7384f1c566462773eaaea3f63e7e1102aaf8bd409307d9d3be6e3cd9ecea98313c48c69eb7fb6bf6838e69c71f9a3bc837db337e34fea26ddd0eb23a735e8fe9a477cdf60e68ea20ed73cfc566975d66f05a3ac8fa3ddd5747e6bfdeb47390f15e66d4c27add5bfea61c66f3652cbaa6d4c541def637c2e53436beed3138c89eec208cb3ddf6e3c741346f906cfb7eecf726cfc830529f4d1af2b5b61c6cf3ad7aafabd70dd2adffd7cd93da36c87f7d216dcc3247a78b970d32b668a79bf4bed77adb5d8384cf2efbfcded76c9dedaa4146660bf6856cb548df6f1ae45d0c23a4ccbae69af58b06f996bb95ae696b3357d73d83a4b4f65b77c1cbf0f6bf19a4c7199b7de7e5e674fa6590917d652dda66f6b9854f06f96ebd75dac9dcc70ae1a3212b5cdffcf15d47eefe31c8f90e63abebc1d8dcdf8a4142eabca67f43ead1551b06d95c5c3fdfa37ea1756ac120affde6da8d6fbe38e9d72fc84b678c76c667de62acd50b923ecbb4f2ec1b99fd58bb206d6d8cb5eacb7573ec552ec88e76b1b5d3f67df55ddd82ac8f29336fac6a41b265c8bee9ab1f6d8c340b92cee83ef247cb20a38e6241ba1aa15738bf3d63cbd12b48f7e2bdf0557bd77b736a0549ed62a6edec73dbdecf2a4846db32ebd6b3d7cc7d5241be5358df7c5fac7ae3390519d775eea96b8fe9ec35a5209fadd459bcd4b5e7ed4641cef91d6775bde0d7f6ce9035fa85f0d508e1bbd7452848c8ce27bb6af92db72d3e41c6b710d6bf3dffb2d8a213a4bbcc42a6def4459e2b3641da47e97ad0ae09978b8f09d2eb8490f56d0f2e415a7f73ad1721bbf3de0695202fe409d9196de7983b4c82646eb3ce7ed6dfcfcb201264b3f9bcd9fa864790d1c5b68d56462773fd4690ce1bbbf894de7efab408d2dfb608e3c70799ad4904d9b53edbaaa5add9f8e21064b53ee76b8ed54b2f83429097b63b57d7b7af36c320c816ad5bfd2e7f9bec1d10e4ac90f9b6b37bcc20fb81bc6e3d325ff7e9a48bf94032e89ec1f72e75ffdc3d90f52bafb69c756c35ca8f07d2b5f6eeceb7dd4819bf1dc8f64ddf23adf6efbcebe9404ec636c6c9de0bfebd3990b679edba66a50d69b338900debb2eead577703d9ee3eb76d5a6add84cfd940fabb5f6ffd67f75b73ce8cda6fd1afd0b9d740c29fb0b27a978dec6f391ac8f6ae5f9fbf9beed29f81a4f02b6bcfb1177b95817c7ddfd7357945b89c8d8174cbd8ec4921bfad0e0319ebfc6f6fc50927645a86f4b71c4f47a3c775a92343fe5fbaa24f1a6d6d97db0b6465cdda36cbfc2d57ad0b248dee35bcfdcc3563c8bbd8aaae27ab1ce784ae1143fa5ddc225bff1af4e8bc13f231d6e072d6debcce35e7847cede8dbda70bd5ed57d1312b6ed78617f378cd35d1332b6d7ec3ad8d5bd789967423e6be3ebf6d31b42cb1c13f21d73f5fbcef64bc86967bd7e2f83cc685f4b4867e17ff7476baddf5a09f9f7bdbeeb21656e394a09b9dc3abd0e7a7bc70a27216f3fdb9a316ffd6d1f9384642e3a73cae6eafb5cb348c8fbb73e67f359e7e6650609e9bafb3aeb1f6b3767f608f9fffd6ddd9d73b62de608d9dc3f658d6ffb657b1b212d85ebed5a333257fa8c9090619dff6b45d61eed22e4735b8b5abecc5fe354846cfada6d77e337a77176222465eb229df0355eb3672342ae49ab6dd0a77de65cec43c8c5abf6834d27fbc9b00d215f5bd6d969d95b685f77212474b4ba181fe3f5e6432684b46db6dff65ab3f5b28f43d246dbbdccad166be387433eb62c9b0e5aff87d10e42366dad5d6bad20e473eef2f4e8de318d3110f2efdbaf8fa3f5c72820e48c6eba7f0b36cb6dc23fc876aeedaacd9b3af3e60759e16567ecf274f7f0f39efa48369173f441322f8f6ebab518f305b90b39de9073725f9eab3666bb32c879cc2c0d39f8209f3d5ede7aaee777bdc779bcfa0b39dc9097327bed2edb7541db57c8d1867c2eda6efc6fcd79a333a79a5b8462b828401672b021d7b42ed6d77cb97563b59cc7cc43c8b107e97f9fe1b4eded5ad5ddb5de629aaa14205ca4ea6ecc626463801de458433ea73f2bbbcfcf1b7cce79dcfc1239f4206bd7e598ffdb4ba9c3c979ccbac83475403e9ecea7936eeaeb3672a821e18dee28ad2bde08b945cee3694a22da7cfdfaa13e33a24e10d1344d53354d4080cc70e1a323aaaa8f21326d804cd334d5ce34b9223f3621ea6e3cf5ed34857ec30800478e3c48e71832ff1bdfbc8e617540c88107196df51a1f8b34b267ebba83b4de0e3aeaac33c86b393bc8e5ee9dbb8bd55e16610721471de4bc17d267635cfcdcbf4a07e9ef5683973d5cd6798b73905c9f33b57e7fdd385ddf20871c64ac77ddff07637d74d6fb221172c441fe6cb7cfaf9baf3ebf8ef378f3e01839e020ed8ab3e19dac2b85eb43a056418e3748d7adcddb207ddc2b726f380db95ae40bd7a4d429576b398fe1e3400e37c8656b75932f5dd4c55579866eba3f44a6c9c275841c6d9097c1fb1c63af45ebd41fe7c9e460836c7575f3e8b1b24a1b6d1bd1c33c167d9098630db2f1737e6b756bcec5feaa417eabefebfb6c0e7fd99b06b9a83b5ae3a37da1adeea241526e7459fe37fffff93d83e4659fa374da7663f4f56690cdb3f931b33ce7b3d396415a0bab63abebaa707a5b32485ef3dbd5699fa50ed9a221eb9ad3ad6d95f6dbbe750c92b5f77c7dde39fd2dad6290b12fdb7fb4b938b9d21a0669179bcb2984ccd6d6af8241ae3aadc73add3bceeaf50bd2b2ef091757e610ba55bd20ed74d4b2f7ac1bb37e6917a483b6ce7f2dde8e943ee582b45da3ffe2c5fafeb2740b32aec8625cf6368dd629d582b4afed6b5a5f73cbb549b320a38bfe91f2adac9f6b140bd27eeb369f3b579f2da35790fd2d7a5dde627c0b32b5825c6bba8eafddd51cfd45ab20179bb53e66deef61a4930a9299bf76e7699db519e714246d6daec6fe4ed6e6d32805b95e83d456d74ffd7bc628481a1d5b67bd315cb1bd78866cf76c2d7ece277db52314e43f87d7adc77139641c9f2027d308fbbd06676d6b4527488793c6f7decd9fa50f9b20e743f8d8f3e89c65944226483b6765cff432537e0f2e414ef7165f7b87b335e7500992bddeeb7132d88bdb7d49909399478e70fa74bdfa2141be175d656c99df11a4d3a68b3238e9f5690469d7a2ad394bfbc6d56811648c8c3a868d3173ab3a11243386cc9e5617d7a3ed86202fadd0b6a5d3df53674d0832bae560bb752dc3176310a48ddc6bc1bf0f3a770804d996a3cc2ba476adc6dc7f20fdf662d3ef5bee6f6b1fc8fbccd66b117275372ed6037919474bb93a7b7651ca03795f73436bdde78b0d7b07b21973e5c8e2ac1e2bd581846c9b356df3bde5eb9c0319efbd8e3fb275f7d98a0309e1f467b13d7803e993ffd6cbae8dbf9e17e7f1c7cc8faf20870de474c7663fb61665d3a319b2df556be7d7e991d25703f9dec5c9fc60b3fb5cbb349090adfa1de15fe89abd33901e9788a864f0aa959196a22086310010425949150063130030302c1e8d86a3f178a2287af203140004597e6a9a422e124983c1500ca3208a82180662100008208410628cf14a116e00c03ef6a440347b8ef61d6168e8db8d0df74bf5611d510b68ad2dc4e0fd4d8a705a5d0d20b5810f42cc59fd9f4544d406b19c83a5727210ac88d8bc7a22b7f22c74413e376766d43f788a5fac2fdf055a20aaed78093242b7db8e7c7791f20bbdc6d4e1d1c0af715c1647479b78593ce764b6f93fdf909a5f5470cd7fea27029f280eab52b3137df15661e3323b8ff7015830f651a7273da49283635c46bc941e5f330b5c53695aa4c414c740ac11cc8cf434f43e3b88e4e300cbcf1b5855b61443e3b7cf3ae2f58cbe3a857309bbf341814fac97189f5c7dbbd563afe96028de3f4d559c637775ef79a3917c321f061cf708f244ab71818e38d3693729bbadf51eb454afaaa0d78a3f4d96679d2e21ac2a4724c040e4260cf2b64988d8840a4f118c18df8bb57c4b12d0f1378c3da0aaf7845d991ff3d2e20506a60f0aa374a0c8efa7fca2a0a21527897b47f660b144cda256ae37b42d3e55cd014e24343b0245cc00d7683431844a4d024634b43b04256600d928b43186524d014344b43a0635a600ad515aa79145472ba4a62af3940685bac813d562c2a15454487a9b188e64b508086641d025fc6b50cfeb6ff590124f46d0febcbdae95a0e40be251b52f6d3c1b83e9328941be548d995566b1a4bacbc4fb17900195418442a82bab0fe602070a2030b4eed4f5c941dd598cb823f387efd4d4632b82e965e5d48ddeaf1cb73606e2728a1388010a05ff86fe03848fab7cf105a2e4006f4b5c860909ce6cb43b4223b61ad1179b067e396222d21b4b2fb206a21d49117b35622ed207421dbb22a26e4e92315b2af3bd8e0d743812230636e22eb60c9c3ab2a2440bdbb494cb10a390de587a252ed413d3d1fe6ff0381dd8e5b83a72928c8a309d4fe6985bc7bfc47c0397c5f1dbe276fa2f2b5ff4b24dac5c183104e9264bedc585d4cb8a6f1d058ca38db8ce6e276d68cbd03a55b24bd0f5d2245eb95cd7fc4bcf0aad93978332a153c81bf241fd5a11d38da48bbd066e1cb1474aeaa8c08413c8ccb8a5ff1bcd97b5b4daf0a490ab1173b17d4c28bf2cb7e87f9bb272156230d209961ab214a29b2415dbcb2d9a5f38cb4feb8525bd6b510ddf74b7417f656659966b0d9b666a9e068e85db46721620ba2f4a001204182f961cef46f5396b295ef6f0725dcc37df84e951d1da2c706a31db74f290f1fde9e2a18c31dc6c1ca3fd8cd71ea7da9dbbdcddb6d970c5a861734295122e6558f85afbaa0ced3d0e494ddca948262bb01a15bd7ba69d12db681ba49b30cbdb7d19f28eb2710b7b85237b6b0e9d4bde82f1c80913ca03e9e787d9c605cec4ea6c6783853117b6c7ce70855075dd0ab7eca674514177509eea1601f155d06c868f7e9ac0a2bb4a93744b2c62e552a7df82c7c80e9410c6568f1a106f5926ebb53c43f68cca8287dd6264cde7ba3e28ed5506c217ce7c270e662b2b5907a87fe8cbf965efb3b7b4b5c7729ea531371476482df40841102bfaf61c052b0f0f36752491b2b48b4d352190a2dbc7847ac805d697dac9d4db56be954d37ef10cef6614f290e60e834e594ac79483a807ecc9167e8b4e7fc17e64d6a7197a7ffb60324d2c0f265701d05829a8c5336af89c889c2e384a5052572bc0366cc4b3f92f636866a4a0ba2bb4e41041b08b68d12286dc13911d2ed884c9befd5c8c24c76df134c28b0aefdbe99986f8071a010630bccc416981aba14c7171b16bdf4baa4b93303585488bca03c33f1fe37cec4ed5e7db1cd7835346c12ffd18a84c2146237de06cdcdc199f64778ebcd2534020bf1c675f868d73e0457b31e2ec063f3fb0a85487dd6f5fb2fd7689e767eed5744420be03cd8cc05d25fc961271803032f9c728593fcde6332a54317018b5a471ad5e0677b35288e62d90ee373d126c2e93a29f3d340ac41f68f323ae6e2f80e81b27bcb68aada9e470c4716f437ef848369151d5cf6d460e9a38c27532573379c0dfc3517c428f52d4c94ae18c3bc42254650002d2c6493ba240c163a89265f3d0fe4f44eb282f3933c701949a201f1c217b46b28d8f5f9340f6559debd6f3a3d304a6926664c1c7740d4ebe62c7e155015dcba450bd716f65abdc3fadd02458bd856f5b550c362b9c58c56695bf06b51864573ab2e5ad8b6b8d7e28755e416315ae8b650d7ea1a16d32d68b4e06db55c8b362c9c5bd868f5b6c55f0b342ca25b55475d0368f1440ef9b59d3bde22f31d0369abd85d6897557dec455c4cc6a0f8559e314a7dd11cc36957b5cb6c70c7015b75b281a61ea2d4062f8d92666d82865b3a2cbf715deb6b0cd46144d7a1ffad2adf582b639a0c6ab5f23da3b046c3335cbed52e8d6b32de6aa03d6be437b4d3509f63115927af415d07ff1a85606d26c3d91b16695c36eb171bc86dc4df0d3dbdaa93b17e8d9977d0a5959b8c626fd8908db0ce78dfdc349ff6e9ba2abdbc22ab74781919c3ce111c1ef12dfe652bec7b42cb849dc1fa7340d3d0f77f6d6337f7df82cc9804a31b7468715d4016c709787d4f16e4065c7fdb19eaa279bfa83073765a6739bf1351e54f40e22a2ed8f7640d0d477fa262f489c1ae543fa3dad1213ec7a51a841cd666717e315c756d879077f10f392723212f29cee423df9a0c0bc3faca117b65bf562bac05247f0d95d89e1da5722ffc705194fa79afadfc08b0004faca5e3497d63ae05195f38e2262756700962671bde531c050685e24b445c7a0a995f26d17990d010f188d9b926e1d70e778b0f1e1411ccbe087cbf73c6a8274169ba76a8ed86ea20f28f3d7f27e94f2ec26f5cc5086c13f48d54e9f2bb5f0e7aac40cdc85e5c5522d0d07c8f135a0d67d9ef80b87cb7c8ef882c1dfd379e4b1ca17ff286936d98fb4fcbfd43a428c3b888510f14cef3f8a1228446e62f3ebfbf801a18e91203712601f84ebdd7b4c8d53ee143988c3ba2e7cf07f0de2e122141d06a40c9bdaea3c5d667edada6624e0edd34b520922ba36ff7db796b15cd379c03b7eb0cb5923ea410a9d47b0e2f223fa4fbd6e450354e7f2504f4df5cf4e1ac89b8eb197ca51d44e6c78fe0d066e627ec8ba4549b6f0a72cd04ebbfe59cf1eebb1e294fc75bedce8f02c3c5ce6769e661f1af1366453ffaea09e3e2c3dfb8dcfbb9def19990f05124a4d3bd87cfa9959ca9249122ee17e94c077ba424750a2a93e1fbaeada94959aab5b77616f436a9c6f788db4ad2b58c1a6d0e684530461ea6ec69e43b661f939b7b3cb02792844409aee219971f726fc7e7d87c8991a18a7adac404bb843238f551c28e41c55f69e772ac4eb54eb212708e75e70f176c0addba40d31567ed46f177816bc26d2282a95b7ef80148e8d3b689cc47ce52f679a1435fca2503b85ef17607876b7f92923f06f74b9908c0cc0730b031422c631b3e7a26ad511bbebfe0a908d334737b839333df9933a4b779edcf934dc68fd7432a623579ebe5cd3188f5d1aab6bf1ce093dd198020139c92dba6a4850e0596c1f317978aa487884803257c71fb8e8bbfcb2566fc88572d71082992bff27a380da0e51382d7f438f4070dd56fa239e89f7e4888d5c9ed7685e2290dcdf23aa6a8c02fde2cd94903d347eb7033a77246c998f064b19f922b17855903e69d553d04a0f6713a78de139d6d1ceb4694ce727a5c27ea06a3249a2e2a559a6da78357142b20e0089356cc31a9083ae55380fa68403147bd78ece1123224cc9f5dbfa4b07e09f8bd21a114249896b4df49dae845a4cb3cbecef597936000d8be25cd19e5b88bef4a557c398606e21965771450f4a5aa10597598a6fd4bf570190c308bc353d738c6f7891c4f12ca7b93a81fbc00505211291fffb4fef73b01f66eaac5a1bd1756c0818ea8abdee109d333e504cfa007d240142d0039dc1dfde81437d3e7add96ce88716644aaa3e275acd46d28fd9dc73f345f6b3f66ab40446a8c05e06ddd0845d07bc27f6b7cad87d00408eae632c5022bc42de5f160def1dc433bb5fe55d7b31e80aaa249219f58926c5970b2ab480bb6f8faf43ca4d833d97708dd997e0897c4ffe2efcb8f305b23c2015a9f70502c42bc0e5242403c3c90272dba7f8fd2538604a5e6221148eba4566f9af324ef844bee428366f32b279beabe6d0ab7e9c63c7dfc2e59e9281e8305eb71f0391a8aab77a1fb73db179e58d100ad2b09be65dddae58f344dca000f71200e27b63e0e7f9563481aa3dd2143e80d118a5aca32c02782db66e6439c9cd38c4fba064de9bc0de147522bc701f2e00f04212ef34ed702e017b623e53f9e48fd659da91e073b3ae75d2861cb3b41a77770d3627fb83aa75a2e88907482fd8586f69c8acce86d35a3b515a06c59c3e1e16c5944bf4e1718d6261d46e2fec908b569dbee34e195b6d751e188d3c60822849889cde55ad4c92d74111e0ac2b65a50683789c797e0d99f3b8b9398b744d2cc17c366868104f1b9f9db742325431149ff2546b7a51514829021be68331d8dd47b31d3799476ea3020419016cdb2c37e6a0a96dd19bc7e99a554f2a2ca1227f5db47b7e749526c9d65fee40e3fa2d6c0a6311e014c430a0f3220de787861ea4478eae17993b2ed31ec8fdd1ca7884d399f2e31fc8c9fe12c6c38890fd6b190bfa1341e63dd6f167abe9986a0853e59c434b30c1582a5385524445e2d7beb7176add1b8ff3d1a26b790c03697bc14646b4429f71eb20ae4db9a8e6b2d5d05e33fdb4e71caa9d35f692746242f49b6ccf5d44df5fd1011df591a66e3b9ce474156ac66113d8332499af1a49a1bea188fed2952c70de93d1b7779edbcb4c5e51b5c3816a728bf0308616e637cef76fa6d26ce824c5930dcb0dc1782df32613e8c29dd89461967585c0073f204507682b1cfee09e7cd246e0259b780afbf3fb8e297b2df2898245b5ff37a816a148cb1c185a76798c4209ea1a6cb3bb71fedf267553e622a49767e724aa594ffe57652577ca2036b1429cc9e7a528185d4302b9dd17fb3ef69c66a59620a9ead454d36ba99a88a8b94b1ed22a5677ae3fba95d37a179571f3d4ff693c1de9a1a36bba217ac15f026aca5ec0e28188eaf2cc243f89bb9591c44da6b52e9d773d17112fd1eb4b9df655206a6b87a074a0c55fdf375e319590e62e4969c93b0e254a792ee253a25c9dcff4d506ed53961066aaa304f2b18d2b4f965137a6f668f9e2914cb8b78f8590d852023ef7afb80f030d5659ea1613b2dbecb41277da0def3deba0051b1f5e71c93259b7dedb64d844c61cedd5a8c377739bcf408afc50546cab65551eb3d8615e6f1a500fa5bad569a772507b12a557abbfef016b4e869298811cee56683b7be466088f2050cfbed4cd922dc70c3753a04dc841acbf06d11da42057d57e45f57fc304edf0d22a84a55d982864e8c754e09c40aa1fc9e134d83b965702b8a48bd9075ee7108fe36a68d18034e3f5bf1997d1bf273880807d32fcd6487bac28315d286ed401814f921de50198bc57604ef4674175d442492f921d0630d261ab364cb8057aaae69a6b334aa85d99754146b59264b6cf27be1b87cf894fa7fec72f3d4be3dba0344647c0dcd4fad9a0dae4e20a12947f02c2f33c9ee5110e8a83a04871538980d9dca4b797ecdc32a735a53528123741455be5d05e27968fdfdd2cb8f81e75d2d902be426a9ce9e718a14bf41134e6e93b4e3e0ae32dd9e1bd8cc355dc6c58095a4e90d8b3169fb0ca5cf2c76dd4b0cc5bc19b54665370d63e51191cf0c7863d68ebbc1f22335fbd4247b004a43ff3e5e398e32b2b5b00fe91668af55a94639d340bb836564cc5503e18b7423fbeb9204554b9b41987bbcd82afff1362d666b76baaa3beebd58451579bfe256c66c5291132383fe50a489c041394b6fa2501b98b8d9ad5cfdc79a3a7172817c0be07f91154af6125638cdfa772e5390a4014952440686d30e572d1242c68d4fa8e1e4c381e1c461badaeb023523944d8d49a3599240faa8fa8462137b89c17a6117f2b3a9114421b9a1df747148b22681bbe9617c0a6647584499be813f8474cb31fbcdca8572c269770c1fb721ed75c3be1d0bf36bccc99d533b007ba7f80ea2035f5c5587f28bc08da9185a7e80d62ae65e90440ea2df604b2fd2b747feb45eee25eeedff5ff7228f4823e108e7506d4b0b8a864065686a2fda4f6b056480ad750c41e436abef1444eb1201061109633e14a99f081d0df7ae3ed84a69f8ff8095191e9f35e7a936588e3bb6e518b1c8dd5520ad87c6662381c920a44b1368709cc922e0763574ad0f8a5e106b4ddf2cf90331013318ce0698922771336c3e778b6f92f8298132ed5519b82bc9354544ccc3d8413997b4e641973c296e87ace7f9d26cd58a13461fe902626f4972106d7c1d4b87e6d33ef76f8a840572bd0762a0273f4beb07e74e48e481c7d61f3c6c54e758dab93d8525966583625153c95e472d537b64b9a4f532a830b43043700aaa39c8a7f6e54bb1f3185200f12e9e24e31a827493a4bd3e44849844d0a617b77304829c986729ec4b6c0b0fd58e2703e6fe4d990328d6c30f0ca073a0c8da671939601005ce50221ba2c4a5375e525649a12d86d8d6b67dd4dae83d82f2d4e519410a4b7285480feb5919d995fe3bd95752841aad49190b4d809316bc0b658fc75b9979931c9eae19279e5eb6fdfca417fb9a9f6ea5efe4ef1a370e67c68f2e98a3695be1d099f8731f5aa5f5a14b534368a4c2b4c7b5b6b542709b4becfcafbb8e73e6ce0f7e61edaeed2dd28736ebedf03e8132c3cb8f3c917e0f95cb08c28b3c93fa4e1a468a4e967e8058ed173fff9bc1135503c50e7f6aa0b6a80cf1941a4bb1216db06d8a5d9387c8451f889420a5b9d78485512e496d262e2c170c11a5fb88abfe294daae3615c6234a3b443ce6b7ccf98abe848e7cde138095329f9bf2f591a577b1954dd07d5a278048dc3eb1a1ede406bb26b7b8def94b67fa1e91a49291c11225936b163cb38a1b24b1b2504ae35ed4afd2010d96493f0a2e8c791a596fad4dba977ade6be75e6b32d8592363b0936cd8f9e47c9e3a6addcfa17fce0df7b885d27a64dfd6d8b2ab779470afb259403799c9e50a4e2024d09b92b43ce18776002c5799925932a561ea3512179400436170d10ef6866a5f2cc22b97c81cb495ee77379ab21e4c2c4b5d150fe7c5327dd6bb1ddb9275bd95cbfbd760462a798f00a2787c4366d2942fa8c2a779441dfa3a40387e1b5831698a9b4148380d157dc25f9186455146cd767dbbf4b858576b03dae235e5e9bd54039e34f55a7e26c60b1ce8a51b4de9c0d82fc766a2d032de07011ea0732a90431bac4dd5abed3e11979e3ec6614d12041bdfbcbe16e01f370e9e2c3887385e0ea7f50cbc3cf6e4f2dad01c243cb7bc6267e100b6c01ab62b2f0f0367287fee581ccde8adf52ef81fa2a5eadebbdbc21888550bbbf25b110b3e8f17720570f2421e5ccb58b3c687f050a20eb9f853c9d23bc9e2a2c6a79994de238040d1dc7a0f266158d08a800eacef02346932bc301f712801f068d24a095192310014fb0d1723eff46c802169607eb100908fc48247546758569e9f109b1ef79c5c4a72cce6c4e8c841a88e3b278426c307c76872285f3a058df5271786c874c2afb1b2f8b1fc73bf7d72d1b341c6585f8f9fade1b6e5d6bdf442ae84a7de9d14c82a49bcaa16aa217dd2a1b625812c352cc0ad60a958382702c2f6903eba36872d22582cffec8d4885a1f7ea2a8c21083effbad3cf83d14b75e746c67a69c74fbe61d8c6be7e5455a24f92c671b98117011c1ac04dd9afb756cf440606a1ac349509f3bdc171f51fd526b06fa21d41a74176fc92029899cbdd311876cb419644facd1d5765fe24e06926bf1c2a3c5549383c287d49bb9340eafd09642634eef18504e04ddf0ccf62b06bfc0455f1c52e2978cbc105507d43c5d391fd6e60e243005886e9082a488c80f09564067f9329d546ce0b47435484e53bfb8a3010bdd463c8d4901bee7d2d21222f618e5714580eacbffe81fbef2739c0713a880e8ba7111650da432a158a6ce78f77644c1ecba2cf34915f50ce62d35dbc9103e0aede0442700e43935d1732f89e9816ddf920a10589d0502ff690d3e25663d2e84f49ed758909865c01fc44c568d0b8bba6e1f9bf59e56a146f1dcdf4e4d458e841d5836a6a57c2ae2e04f2f195093c09372dadf73ec1ef940daa4603f770d4ac65338e0f90cd03d758184879c4d17767de5108b0d4f22db99048f10f46f0d321284058a158a716c077093ca5215b380644d1d922e1145a7dddf716015dfd7499a381be17f4ab2ab9fae43d5db30973aaafcc5223883940d0d3b0a7833903c90904293c4b7b88c7e6a8fd734f5428f0a29c4648c418a6e0357f2ee9c883daa3135e28eca0a75e06b18b51f8081c452114027f1b64006c59047e96c200505405f048f82d108130e593f0190a0241d0178123e0b64200c7a9f2fb40a87ccf1755ebcbb25c509d595394aaae116e3932d53b538c88877f023f9863bf09f61898f179bc670cc5efec43c1f319c1ec5d8d737aac1a2286c1787242140145936f5397db79dc31f8626dfedff3101993725363c3246bbb538d2c454bd0a25cdb69cffb77f6130391dc204e6d7f6fd2bd7aaf37f649bcb48f6ebfb5533becf4bef2e5e4530a49a088f88fb1581d153fb0200621229d9f3b6f87b6d007c589f3e4b8241b5549fdeca443fbf6fdb5f3ca34f45abf8368f47e269ce28e1091d392f91a755e647abcedaf931fc270206837028b605727b0649f35f92ff79edfef7f31971628892ded4412ffe68702577d8c0a008cca2b21dbbdf19ab264a423fe5105c80880bfefb1b04635a45ceed05040a342edb74ab7298c817ec3a69fce4c638ef407b43a4c022839aa1542ef34c57aaa6f86ed755e9199adc08ec0cca900b9f9055148b23d931eb70a9594e72389e1e639be4641befb49b6283b53a6fa2b48a27bbc90dce3cb532319a6fbfbb9c132e1ed0e52ebd1d627472098d895c0fa10cebf8d7f3a3911e0e5def01884ceed6d2bd854ab07808e83942d3b37b0feeaef0f36f0a87abde0620696634cbc1466917b0d2ed67e70bfe1e5e0512cfcb27c80e8d7537cda2a9d93649fa61e2fc705df0b6ad3f520bd8faa12140f6b52398b8b0c503f11a6eda3977e60cbcbb8fa55b389668d5f6e258d8123608a591d9cd52dc24a7f7f8debf662dfe958de04526bd4a9c8c37b8c44b1b7ca7bbfff6357afdf6edf047f13988dbc4cb4641bb9003658e1c763c8fd206b96821d1281d2fee0be074c3b4b56a48850e09a8eb9c165631d805d85f6d238b847a676428dc9b04b3b742021d7dd890972be0a32abbc913558a4f417fbfcfb396dd189dde5623fecf9af4dda686518cbd2db55081fe335ad8081db398c83421cdcf230ffd96721e7d8d921092d617cac5a8bf4dc3380c0d83ae6f739318fe3936f4f021b45bf1a112c9167a48a04079b8422ab4e70bece405eed0cc0626fc4bb1e5a1cfedd31c74abfc41b64ec5b6a9419a002fd88959e72a605ed59206ae936b79ec0a9743f981e128e05f709a83521d048c3fc2fd7f9607042476c06ef5fabc2332c583f68de3c4bd884da90996ff53012dbd7e66ed4ae4ca24c7e5461b4221fc0e77752678ee914ec852658452bac7c7320bcd5c11f32b09bdcfa49f714cacb9a2076eaed96c46b1b95806c65e154516a08832d769fea12ed0504340d1f8799d77757b00f3a568fc137fd06346bde0d06ae1f50856b6c0d79c1ae930ae85c9b9ce4d3d83f6bed66187a6a6703346b27bfd6bbcb0daa3801ea1cec5af7b85a76c7ba94a3752ff3d6083e5f4ced826068453092c869d74847ed76ff96f6b8258b2f752d1041431af1d6847f51ad9911ced22d2c5ba38aa970f63c7bc28aa647caacf1c0db3a612a35d5fa9b74efc917b9cd8d727ecda576f0fcd0f92fe45e0be1fbcdeebf68f460d09511647b6448a2a791fe7dd2a392defcb3d7e461f68b0b42ad999d645549e2411ffba6f120fbac7af9c24e72d818e96a8884a75b72eff36d0e081ae6b030de0c3037d1fa22e8a99b29616cc7924b0319346d756f3ce9eb78f62d9fb0a6319845546cff6f395d16e19e0f370241eabb1cc453170fdeafbe019f0130e28814890900510e15cc9d3bf124b28bd4eb0018a8aad49acc320cf08d58f7d32f486ca56ffaa2c83b4b394cd1d5d9e39cb303ea2de75b2a3f5c7e3261a345f2a3919d2ebb0e1a873e9a76d568bcf8eee7649b5973acf71bfea9e1be04c6e36f387bdbcfb65e5efe2d1a73c70e79c9569724cc3fcbd7ced46ca039b2140a46307f86a172b558eac56da7922d72378db41c14ba8b0d02f70c436c623a01828d724342d000c5d6dc9e70f40013035e4d1c9a5559ef39bea42c5cdc001c6e735390bb9370ec05e99fd364b6b5068be035e66edbaa08b38db961fa35dbd2ab754f1f8dae74c8d07cd36520447eb6d52e78981a22dde389761af78e72d7bfa7ede68cc5cd4f175b5b6817119e9db4c71f2d4298bcd5223f37d85d72e5dedd8466ce5c0679e85ec930bc8da509be3654062107f0dbd5789fed93a1e2ff2398ad48317786135b7b10d3b8081bf62b3bf4e26f338bc7a38b8727e083d4ab3839bf8427135efd0d82895bbc9f9e5397b117beabcbdd403fc0c9f13006e2a699819352b73a9627ece9df07df6b4e93e8f8a3bb9ed5baff4915f9987dacf7a409549f77ba0f8e58b5354921994b0bf061a32ed41e3dfcf4d534caac4356eccae07c98a338af9245ae7e1addd5dd6c0c534431875f09cb334c344966eb19066d6b150b8198f40a6d66afe827fcf8cef3f3c3b2f3a31c992e11fc1fab3f4d802e4071ff7f1dda64cf41867347a4d25d98fd5557a34bfd07b77efd1796d92ffbf28bcdfbd3b8ebb38ae393879a8c44d60b8de1095c7462fdf67077bacc80117e78ad2c4cc86081f24fcfd1238d23d1d018e194e50f287ed4bcbc51aa836cff51729b9a019fba6ebdf979dfb7656ac33a5ebf12f9524af9d68ee00f30a1500ab688edcf2e495afaf7504a8e340e5bd8f9de33878933691f04c72feced32bbe92e301d7550b2217708cffbbe632094beb5a9bf23cfdbf5aff71d9d8556ecfefbd326ded2d331e1ad67f25f966e604c89445dd307500817c9c5f9d5fab86d44fa7ed2737c43d3782e759da40ad9e8418cbcfe50cf36ce4de3e479a4ac5e23c690b73b69f0d27c5983ba79f37d4d97ac3dcca5ed0dfcf65f11b6a7862decce17ed67689dda38a4df71563a9329991b1db0887b720a30f28a74ece4e1a96ccac07988f462854e67f9380c242ef09a8efe95a6be4c02706f8a767765b67a7bad4e8bb479482e163264db6521dbaf70ed6bff9820e3c1f850a06e9b37b2eb3ef95956ca3677c0c84ff827c61cd492197eb3d2e0f8910ffc73639e9fcc2978aacdbf453d307f5788445cd48e339a0bcd69e4693bbb078598b3370fc9a99ebcf8217dcbaf1e6df993c58d2450c4747bc637db8d7d6fda1a3beccc7b28ebc28e5638da8f94a997f6aae02aee6953dac94fe83a89800394ca57f00c68c63dadfc0476428cd7ae79ae796f362a21dacbeafe232d827ea9b47b8d88cb18f9ce661148c2dcb03e7aa80730bbf4b12c9b38e77db696593c1b9916ef633bd1bf164a9e70353d5d73bf6d4ba405b24700917aaa4076f11d10e9ef21268077620b0c9fd4075feb4d4c298bd85913b18d854e909371b241a2b4cb7b6bade9fb7fbc8dcb67f631955134197d30f13b7a8fae12b7307426f55ffe6c477d4bf90aa352da52402608ad4e91f14d414b0fda2cb9567643c8f6994a6a0d1704e7bbb38e9007cb4c52748e7b575960bd572b1cd338a900d8dc2f4b95a2029c99579767e666e17b98f2ae3e438f99c46a420404039b0d0cc2f151fd5359a1ce6290169a330b9f5c73b7fc705ec9831fe2b949869b74ec5e83adc3101a7a6886a72fe89a748eee48d4f270dd00f1e982fbe3da37c00062b8bccfef710dc6a81764d66f5d05906166d02da05b041e7fd4e890bd5fb63d717f5e03f6f8271f8e32fa46e753c073c878a0fc3d2041f4b1233e3f077e6e22b99265becd40641939794df96b46c6c78810fc45949b6054245f53ca2f71e2dc14f97b32007710852f07930f0b2cd3403c85cfb83e58e073719f05728cedd3bb2b3d194f96d3f0bdaac5fc67f3d782be3c84c7fba177c6ca61f307addeaf3931510fc45d31b9504ecb6baa7c2dcfe637eebd6d6203863f3fe95d91a5010dae7950ff0b6c14675dd77f8e2bd9b37f727af36be013e00dfcec11044c80db44288f783507e69878ce26e0a9c6e29ad5c8e0a181ee9ed023824f12035680596bb80758461dd835597f05605ef5756d2edfb8f1ede05351ffbc2752e1f3b016ad321a362abcd28e251fcbb663d246d1402f1e10990faf604733ddf1ecae3a66649f9dd3a1b9ffbd132d4bb1af11ccc174106ba9df3dff558c03489ec2446776e2e52190492e3677fbc865a4dec930d5a14d185ab7bc0284581a4b32fae82e1b384cce3317d7e8409fcc7201be49c10488e2288694d029070641f57a0f8142b559a5622366c4f91f8f41f315b905711d18a3fb5b310107d5d000dcd57a641e325a7aaa283301becbaee001fd693f2626aed0ddd517d39048fc4abb656841ed2e669be012e160271bb44479cd8dfc83ab08427e845060c849ad94db01bd5156a8de42c76f236cf1920e56b8f7798c61d1fef9a4588147b4dad0d3ddff7afc5bb02f4157ca808cfff53b0dd86a760db56cac048ee18e3b6d0887aec975dcf9c1aed39ba265ed82ae74101403e46784fc96f9a7af9444a96897f7a73e2d8718abfd497ec01215e841d0055022443f0d9ad14a05e097e12380a508e89c760496aa059c03ef8104419aa3f0292f801b06e1fe6c81832d45054316c108901d5428463b35885f8a87009726a1b3da1078ea367016ac071a0c6b8ec45154b369f48538087e65089ea88a4147eed153813ae0dca8722812429f1ac56f4503e04bf3d041650468761b3a8b56ab3bec12c0960d73d3631b9cb6c664d30b1b886b0d58535a0d22d42a2890e4319a7e519017c1c320f662000729470184aac04f835c000b8bd09f0518a0141500be123e0562210c7c927e0640a012f420f00ab85408c571e0097a9900c0cba003402be2d02329c68025ea6107c2780a84746a541044e419b9839fe63a538285e0e1ce0686965d0606c5e0fa05f9317632c0ec2a7f75871c9b7ff2569e640323df9a8af16a107e6382da6bfc5e59533c6f14cf03a726b0ff07358e2aa814a3fc686a78aef0fcaed790115fa9eb3264d024e82abd80d0f7a74acc55c46a8cdb3c593cf95fd08a08b6a659bf02883543418f71d2607bae5fed5207952f5efb13ee73cf597cb8c58306bb16d4c7f59d25c23ced72a6bd04b0ed87e2534233e2aaacdb04e9c0c77ff20235d952b1d9e69c8c7abbcad49ee595ead1070fbc4a5938bc1bb1b4ed431185dcd7b92dfb8d04d4fd0ebfc0aff2f17faee4309abdd8b1e6f2a995208112a5ba83d4fda2cd1491bc9e199bdca4223522bb30dbe198844c06cac52414a4b7f46c8bb4e74c9d4fc90483b53c348ffcf9ed89ff800ac23b2957a711031638dd9b21751184fb3b7c3924499647a200cf88888c0ecda7d14584a7eb5dbc02d64bcfc80eaa3d826c087a67e6c4885939f74f23cd37808172a3ae9b79134c040da756d6da5372617d339c8b5fcece04e71cd32cf605d7cb84fd98a3f5e10c6c844207c88f2ed27e838d0d243af92d9e7aae63909863d5493ce0e0ef45560a0eb9ae0243cbc74da16d171fdd1bee46a23f07c300cb726c60dfc23e271b623f185f69049fcd4921e50defe37c4ca777bccc8174fe80797015468743fa65c57f7937ed54214694d69028287e7c7552e976a23bd5c7c46f7f52d1b3473333e136048abd60f26d47fb65d7ed16814a7eeec98e44274b5229637ab96295fe0a579da178f26631d94cb012e0e1fa37facc309a51be243292a89d42412680d2329ec4b901747be18fbbb520f9a4f6e6c181881ddc5bd3f773658c9a160475b9b520a8cc5fc6c470c55e364bfe6263a07d44c8a7ed0a045456992116ba411c0caca952377d9b58b27d6758c597cc89ee5835f0848af387dbc8de13765e2dadce1fc03fec394a6d5b747e8040e08010ecb31ca4db31c7d985e7d054823549a65cee90d3d9afd64ff61b97eb7c079fc453a55c4d97379bc2bea3b92c6496a265b012a3d3f35ab0fb09ba21d3422896065612374eaa805ccc417c6c2f8673b9c33c8b5717b042d9e0db14b067ca06c4ad2f42c00ca7ee9faf87c7b6ec446f8243a85f218f4fbf77410c8d741d3b0463046684fb8e1af3991fa593d1693ac60d1ad5ab4e6b0982a20abb6796f9acd62ddc323d76d24f03bd37cec28fbda6430494361afd74eb3dac0c9bb227509b51b0cd5e4a4303844c641e091976e1bdf707114ecfcf919b0688038a73a1cfa39c050a4a4fe8c1403fefde5d778714353f6dc412f727c54a2c4a9180944588883af17b55f6644e906f7c5de55da56464604c647175a2e28a290ce1b284090410b8f990650c1da1771adf39d831f2cede93121b745fcb95b8a20d428103ff73d7578cd646f65c869b86b44f0b2be734b387fcb464ba2c3fc7b59f8cb0eff2c6e92e05f6cf5dcb173df2c5084ee3ca5606abf07222b057178d722d3fbe2e4f20e277b6f9fb3b4de253680b48adb05a8bde23242d1270b66989e17f365d2d3cbf7c22a1b11b52d023f1ea4119fb2aeefebe5bf7b7d949e8abd0e57048dee8979fa8f9a923689f5399e2691e91dfda84737a3957358218f174566e5a07857b28656c36f624bf23d917ecdb60b68fa859d0b0fcaf511b0deb591e137131542ccb16436dbbf1a3aacd7008e7237e8d58f9d026932331668169d0ddf7ab3a9c8d73c1fd305e7513bc7f12f2182f9b58bfdc36a56c6a6679f3ad8875b493b2c5bec3aa380788a6d35c4ce754139e74f2627efcba8b838ac86085f3ef65b12df9145656a71bef88ecca6ee97a02b79e2691e0e9036be9d6a3b10441186b426bd7338ce79e806733087a7b8f37e22bfb3247ba09399f6d696c85bea41b139e723c22f918fab56ac96075961f4b787ac1d0a70bee3736d882b95246ed29075db870b758b8e07e7e87e6c4852e3d9b45ead8383c59a08ac2851b403557dbc3b2237556e211e8f50affd7bd30c6203da89b9f022e4b267c037bbd31ca665aed9eb1ac7dc62769928695cf1556b17d16ed57ecf342bd483fff7f4e80db65973fda918844498c6fd469154941a01bb734d950e6b590129eb34626b0e3b2f6079ab3c41d6ce99f330d782e76499e23e6fdc18535eb0889759789ddd6b3a7af0a74a96a5fb37bd9a3c6c040ab2441f66a4d0ed1f14d1dedfc59af3f68d8fc3c98596a859033d7bd3c167e4313fb2d12dfbcc7067cd2308f02e73bbed98e412059b129f5a73fc6f8785c1708654789d09d28b46c747021d65f592833b9a7768bf3e2df0a397128f9f090b3011f5b5eedf548c04acca020192319d4c3f77d95bfd5f82ef1b2f96b37471c2fa0dc4a5a7c1cfa211e378e223b495d0f9cab91d85a2614bd1d6614dee8a37d496ab68538f788d73d28c9cc3cb1eed4a5b76b0f335c9fca8e68f37ea8d85783e7a935248f05bea224f1522797347a3ce77445a3434d5dde8e119f4fda400cbb37d91e6fd6bdbb6cbd441afaa21c1149b5fd04fedc83bcd6caf7b9421462761a29187c126ec80c68bf04de83339e9ab521fa28750d5bd8add669ba83d2fdec9a1e0cd0823f263e7fa25a3ae301731c4aa98bdea0d95bd4eae0e0630b73f315007b71ef4ef344d7ad62ff171abaaef55dfc82abf1d53f136cb859108cfab933036d3372c1e5b90d022737efe30c27f2e1c833fa655ee2ad5fa0cbfcf895e60dab807e3fcd3861b0467e3fb6f007658af778aa47a66a5b18ef77897989756c0c99461874aea86bce804951f47f86cc8e33da5f59f5565806f18066aff4ceeeccadb52e530849838132516863e7c44c6138f4f428cefd85952202805b7df9cff2fc7a9d502ffa304763b8ff578efc5ab580dc98b4b99fe5f090ec1c58983e340075253120916f10e6e496142b1f4d6627434094f714a40fcf3f8524de0ad21584b982bc3d74b3982e3c0647d59b471906934a7820f8e65a48214948b4b3f818b5af0b451b610cfac76ca0c2d301aa7eb92000a894793a057eb8020883764718075e0e2761cb025eb0b91f5387eb73c44c800038c182604cc096949dd392206804592ece1bf5ce6f195d83aeff758142cb7a8d19bccc43b4366ab5834638b1db7c2ba783db2722bc811b1ca4c61d0b14deb70fc48d8ab896aa50a18581f37c38dd83254d6510694daa145052c84b78a53020b2117168deaf9663b72d18e6adc5306662f1005a338e0a04020598bdf848894e1687f356fad082532d63e4fda3f5c796c836a1f2441b498767a52cae94b92207349714b4a7d3693e8b6f0bf7fab665db7ddb0fdab158c4141a7781c8a4c672f57838789925b812de7aee0f053ca88232ad582e98af92bac36f3943110cf07f96c288d3df98d8c515a29777ecc10c7aa2b976b2490df83365a5ddbf1994991e9ce856958325024411c9f7f78d02b50bfd9e73038af47bb1480d10c2729cea20cf4df1979f3535f3ba04f0b63c352d62230ee4e14c7032078026815295d3f8014b0bd366f2bbf5f91101fb2388f7217b072e05b41f270739d5bef78bb8a304265a9f32b153feb9dbf16be6046a15c917445ee7eb310b12b2871e156e0fc5d0c9c26b6e571caf9618b819e42c33a82b583fbb44c150ff333737b1439479f12b51352983688060b7c29cc260962432318a955ef92b2e811b2e89f6e75f20e1708b2022414f8aa5995ea3a15b13c25c6d4fe327aa2654b2798670ea8752c07fb5a47c6592fc2bf5a9a52487afcf7a2051d3bd53ff175527a0015553335aca6c03c55c177d9f94c88dbcfd3efee47bee84d36bb7c282354c7c0f84716084b9e754c3ebee02f4d027df4b08131311d05504f5c426d961a24e72e3b8bc0d717f6c3dd9a3991bfa53f4f2c448a18701cef19701eef285d252a85edbdb9b502b196ea77c5a95567de216097a34ceae75aef3c1360a84a8244381cdf0edfa73b0fc76958cbc2394c54c11417bf479dd86577dd4a8cf4bb52848bb9997263cca7bc9dd599ccee7d0aec1adfad55aae38cd38c5eb40dec8ae2518f48851129d3d7e38bd9d767b43158c59e3bdceec2fb327857ca6780227ff3937d393272989a76592999db2ac03af9261a0ae45b6627872a0e528b6ce6921c0e974678d446887821ae38a8798bcba3706348f6f0ab780b6c77f50f2dfb0ffdd2874a30b7a3ea6cfe38b75105bb34a7fbf39b482e9fb1eeeb700bd1a9316f6acdcd3ebaf6349460924e130856920974aa020d9c6295f11a6b1ed8dedfade8653233aebe4e2c0399aeef49169b6da154cc2471694a613ef60bf7cfbfd636dd1da0b5bb05b259715543710af6126a5242a6f7d4d7e324887a08578eaea5c8938cab7c5e3e4317122e7d08aade36614c01a1f5d36a54ba51abb90a433add9247384874e7d2e001d86c6600b85b2343b0f690e310b825873f91141921d9ca266afe4c63a244023150a57accce96947b3bcd3ac39125d4ee472e75bc831becc3c7c651aba627976598f72bb75834ab83ec878012c8355abe7ad876a2ef96c630fad84c96f710c1ae2f59613d3c52d38f054667c0d2a9259ba576ca828c9fd632178973386afb6e845c8a2e1e3194de0af1a16a4b04349c9d154a4ca39a3f8d8c4f138249e41d77179a99da09f9e4a73b64041ac16073472fdfa89d1ce7c15946595f0db3f9972484f290a9a91fdffbc3c114eeea4106dd91b89bb5f5f99d01323385ed83d1b5693733a5140b06d832977036e2d03721c7002425845bdff156c3f519d064e1df2873fe72a8375a50c6d5bf290249fa7a4dea6b840f0a6fd5a8536ab3238eea474bf74ced4771158a8c7ba1f32401cb8481bb0fe5d259a16abffea8f8ff1d15b0542122741c32088b7a705e96178daf28379ee9bc3df3ebf3e624962493f6750cf6e82009636c24f15cfdaa8620dbd945875664ce01688cbf318c2500003e9246495a6cbe91a0e0a41399b4d9d6c26509ace35442075ccf188d29dae494da195ae388e3a6c8bb29a1dba574a1130845468714d97f91b879ee28d2768960740bd49d43c94b0c002e93a52e3d07e0a447b26193ebffe2a10ebe0cd518d0221a2b118b3f6c170b0f185780880d7a2f324ae4e207539dbeb167b6b840281de93191ddc5d9afd9ea50838d8c3c64671047c4fad289d5b887889ab42e50731d16cdc1e630742bb263bffa6a56cd445766b26d1f7640f296a4bbac8404307cca0176f0a51f0d8983a0a7560f38095ae39b4f588d0de5ab01f419454c424064854ca8845cd36464300e277180bc74933ff8b15e0d4d47344e9dac182d686a1b4390bbb68b10ad57394f83cd480c4c50510e3c9038f56bd4d061e82b60681ee5fcf9a1c722a4e39c7c01d7ace184b9f2c38c8bfd5bd99682ffe893650c6c0f83178d0064a1bc2ee449e3ef2e71490b473eb80ec1efb95d5c3ccbf35fc755932528351aa6c50b38c9ae5eb58e8fa009b47be9279b5c3fd1bad68b95960841197d52ae062e0c4c865701f26f59ffb419571fc3c056cc86dc3607e4caf2406fd5154c064118a3482dca517d7dc6f6aca2acbeca999a3e5ad0df9cde74b1e9e728791ac3180d9fbe230c5ce73ebc309d457532e1d519a20b491f3c8282cfe2ca6765117c4c92de8c08ff9fd11abd2e5e1b186dcec0372c8ef3d1542a7cfc6a5344b15a56d13b06fbbcf2a8f9d416c98ddfe04d96a5d9f90d8c8e9e575d51b772302c41b3b16b9bc2ee9f198863f8f5ba4cd7603135dbc961cebfb34b473ed4a367666adf2b07e44ab1fcb10d4217441fbabea1eb428bc7045f6f1ea9e8aff9db94971de26ff960e4226aa964e21b8804d5536cdb05ba46acf8689183624aa0ef0465c2b963d1ee809379cbfd6a98831af3dd9d6629e3de56a084277f132b67c17717f385cda1566f9dd9a1daa4def780d35d5827dc0f6ac2639ab78f7f08a480cf18bef0e69e34ffe825884ea2a015fa5c5ad34d1f623f0822e9a15450cc367dd8078bd75b71002969a06734dbc47bf613a4c744006e8aa37e01eae1070041b5a119fc7e0d822e04660b21a16af8c077c59ec97d98f75350bcdbeaa548c3006da4ef08918ab26f16e1f8bb5bb88638a899514e0009573196ffbf510dd0981f02c61c569aafba7f025602aaaf5cbe2c517cef47a219feb00eb44119ba8b2df1109b655f1eeba3c4e84b80acbb2c7b5df040c303f311758e22928fa2ade189f1eb232d4940ac1361d17645ddee7fd893a1095d866e0d461201c08d3562b32ec556b2bbc2fb01db08c671fd1ff9a64d33d082889a0ad53af4d7ac0f02e01fc703a1baa7145e2e9123f903c5a185fe094233cf3bf18521960b11932b412bde418e556843bab311212ae173b6f0c1e11e2192d86b89ebe484df2f7c56215151f96afee4eef2eb1f225af644dc578821727cb4f28e19046c0a0d1be5c1bfa490fccb8ae8478d2bc424df6d34d6dc9ed8387d41702720df1c382c0d44bc3fd423cd4be54281e88a6da4192870c43c1f2eb7fa711fa4442a66543ac4f81e90483fc3b1bc5351c11557552732ebb7ef0f4022ac4d17ad720b3975029daf394684242fe4a03e94421608fecd0e51a0ecaa5d6e82e08485352503305ac470adc8bc90cae9820008abd270a8368871721f487a6c518603b7a5adf1d1111b2fb34196d35286003d19dd652f979e137d79ac4932d541ab2a0fc05855515bf0a132f6d5b1a3d2a21bdba1e6732c65f9d5304853839942e90184c5993db5c4a4a22a86cd323a89becb26a4a6de39b09ee77b798957db5a105c1212514d3470fe412d64979222d99c49e6114b1b7bbcf2a2531f5cded156292d56923e7e673d475040bdfc54c4b6b95bbeff75c686dc8f57d2cb7d496686e896635a38627e83c8de3abc2787f0b4e801ffbfbcf33628e816baed975bf2c60987ea3c6babc4c723c0f9c8cb91514deee9e6947246f573e4c7d773901e0ef79f91796abd65e0d5e732a3dff06a842fb4d2c9d8b8a7629190936c3fcf779fcf36f1451d55ca24194ce40fb5472cfb10cd51c69dd9a17dbb6ea4e1ed34f668e20ddb50a1142bfe01bba81df274a3855aaac96101f9ca0ddff95549483c6ff9abf6960f94b206c1caca4d548acd3f97588806bbf432f73147ea954bbd07f457292bca089de8040a0e69277e07e69a1cc9af124c1ec0318372cb8045ec7a52953c346eb8728acb1e2117f7c85401f322834281cfb982f24af2431b447f5f27ee579185f6e7c6e34579bb27d13f53b894f9fd9933ed8d1318bb06ccda1221af2236f9ef573e7ad68d6309f988a028ff863c275386c425812a24e18a80b07df91b9a316228a92e2da39a3e9f48213cadf61dc25647a16a2141a996a69d755cc458c321aba0c748f666112400d473d4c11617e70765e82832b0869b98528a33ef8ace312d96f3f4d25be8f2c1c66d07dbebfede4169174be0153cbfd9568eaac4f9ba065095786a87e5004f07fc71c085e2f5740698113dcef8f07738ebfed0dd736530d3931dccadcb8b772f68be37aac959a3ce9dff6180941f5ce55665c13324a037185720764f3737eb0030294b91ce519c05f3467e76f8164cb9dbd287e034b6b012f93816d221ad8f9cd68a03c2e3a8ca14bd40d79bdb1842e52e7cd094c7f329efe79e02981def22f01d1117b0650b0e04a2be79ff942c6bc751309fe40f7b7fbade6585f772c617e3c890c2ec07f980b16027a68b46c926bc8f205613c4f1acd35dc9158a4a6b136f745cda0901ea9624cfec022b8f034c55ce20a3b1a3badaefdd5e2602731221807a2ef05c68dfca3c88caeaeced8f973ea59828fc9b50b997d27caab83936ffac0de02e87b25b9e1133f12a90341c7df3917d21fa7ad18eb89f7b300c75f10fd712e6fb217bf36d3be4d8cab614ea644c026ec29e7f087a1e93e19bfd371fc035c519289a1004ba914541b5ff63d786680f7da09139a6397226c705bc6279239afba6c7f53a6416556abe8680eefddefe3795158054039e9c1095d23da86022bc49b07d2abfd97a94574d6626026768b21148068095d7669e8031e242a81582f8597aaf31325312bc2b8c975020743d0e22c9c47846e3c42d65d4bc26580d1ce392f629568d11d74456aa8609ddb3af0d9f72be147300a636c97b0aff027282e449361fb3c3d5f8f26978d09eaddcfd37327684eedda2970b8bc13608a547a473fefa09a2b242cfe106b75ce3c64e6c34cf1c6ca183c19e4fb92e146f50496a4764c443b8e7b2365b7a912454b50b02015d7244a0f66c5bbaa9a50377524a0b11e4a349f3720c2f4ad2e64a749d66aa9ba0eda7194e4bcd391ebc9977855fe2c9cdf41bc630180861a18f308727dcbd0d39b976d37a1dfdf904f77a6a40ed06dcd94738374389027d9018b1943c5b713325dc8b5de53e34db7cf819a55ea2fa52b11b05b2f06f31084fc2a47a1f72d6098df6e66181ceb8d40135120f055587a63e793dc731c3439b83d9ad34d6c234c11b5e368983e17679ed558a5ea7a3ad33d5b9ebe300778ef8b8f578f6e30d7363c82cd9f03e1d780087c4c182d72e0319acec822f2de2a32f24733f57413f6d2e693c7de3ded77e48fed03176d03e7629c68662b9410a68580f98cd4c0ade2e5d113f8d72379e78ac6038525b81ef549b934f85e4714425e6990805ea4f011f7e62088d86b11de93ae990135dfda335ba4d6899d2cecc2c7cd8497f5226b3c59af0264c537de2ee237fdaa594788747be37d35c4755475ddb9647ceb63b2066cd4ffd3500d1c8e023e5a04220b3760b46439330f0f0f0f0f0f0f0f6f4337426a6b9f908494a454aa976679010b644a29c99492d81dbc0b9c99f87466e2d31546ea6e34e301030b400bd30a89305b754ea153cc4f17311a1a68000d2d6854c0c3c3c3c38bbc0c801a6220c214d28388d6a39e7fa625c4388441e5edce5e2284ea63058d011b39ba7880214c3a9430d9298b440b63214c21c78b914df249fe104218b465c813f91f15620cc21871e5d6434b9e902208e3440b19a91e545479a2102310264f59952647c8881a157284188030a5e777f438191b6b016084187f30968e74f988efb9a75363edc3c647c12d4b31fc6076b7083243e465059386161e1e5588d1077357fef6f47137b6f3c1246eb35ebf9237ddefa26b68c06fd898c0923d186de28afa0e1d3d18e5524823aa3a7f3a711ecc5f174b955267a972120f8697a4b4aca5548086062440e3430b1ced12c891000b2851438c3b986ad27c74ad38f91b362002e50a31ec60be0c7df524667bb5af83792dced6c4fa09da6e3a986e5baf64752ef5e139183ce54ccb19a24a29530e26a13e57b8a89e9519d6588b83f14a456cb56ec2292538184ef6d8c9d0918488a637e8337975ebd52f23c70d068ba6bba5847e25f3b4c1782a629b087a7ad5c26c3089f59c82129d3c8851d7b09af89d69d3fbfb5d0dc6d1f62762470e252d4d83316757528ea8f360123418f542e3924e6a44fcc81990e79e7592d8f0dd88194c9fafebc329b7951896c134e23e23f4d998fa6430bd560e39a29ab0a4d9180cf2246987284292490cc69ff9d4ad94264cbe6aac1962848131b7d9ae20536c3430587a3cfe09791771fc4272a23de2880929cfc70bac96e87069d927e98241e9d349674cdc0575e242a272ac3d2f919152bd05decf52e447e9f4c1d58229e72454dae4f24ad5c982c94212972fe88d05632491b3d1174a4551b942fa4b5e9f1a1d4f3c620593aafcdb1dea296787ab7067cb13dbd46a6255a86052e6de267ddd4444740c31a660c48e14d192429784670d0f69267f4761d7125365924b5ff250307b2425df15c2ab3e9e438c2798cebc4dc6e52427182d8f7c87f2fc155d9b9078710fa1cc4c2618c4b6044942924b583ca565c7d2217fca9460b6317defb0d57f214930f68dca496adb87f00e09c6f8ddf3aaba54b61ec1d319b135ce74881ac1b8af27c1be6e2c9f72885104e34a34a14f45869e1e11c1f41971d72dd4ef538660505921e5e715e517662198aeb346eaa80ad2471b0483e855f79c4a6dafac4030999950b9206db573f20786f7efec4e7af744f6d00d317c9068a6965ddd0373b6c41c939397fb82789007af3e53a24f9c24edc024277c56ba206f92b6bbd8a26f241d982aabd675f47091d29203c385e7eb087bed220eec0992b642527cd9788353fc38ba446f820ef2183630ba6e8b6e0fdb298aceb521460d887f49f4d7280f950662d0c02ce6e13cae598ae4a1b121c60c8c5e3aa5a81246eeb8be8618323069cefde76f856889c5ba9f53d8cfb8d2aec1c254276ef73aebe597e91546fdb4edca31b57923572073ca9369bf4a2b0ce7a3d4bdc8c6fdafac30dba7baec905ff2bd5d85c1e444e5e6fcc83cb9c69aab1960a8a2ce761792852429684f2accf196653997fa4d1f15261d523855d7317e3a790a5418cd4ea2744c5863ad057e820fbe1b3672743185b13b6591f11c23966534b4a0d1821c5ea0c07451011a5ab4e0867f71011a5ad0f02fb8680ed0d082c69db5c02340430b1a76c39d8bf3850d2df3a251f05186c3bd68418e2c85414f7a0f8b2426297b5218d56cd4a8f4f1f6b98fc26c71d2cf88c5eed35714c6d1e965fdc36fe49ba130cfbc8f288f7b8b2c0185617f3b4be7fe2cefdf270c2e4946d0155a3ea25d066078c2a04694e5ed59d7fabf138614f22c56a8958afbd4d80d745181b3829c30870d911e72e6dfb29cb809e39c271d99a142de4713c60a7af1223444ae8533611049c5fbe69e4bae0f26cc79c5de7b74ec10a2a55cc214b45c4d9f92aa22644b98d46595136182ead866f2004625d491cfcfbb1682caa2008312e6a0ad2797ee5b93e1f8c8f3008c49186553c4055d59e46449560086244c1529ec8e55d808ebdcb8617608302261aaca9ef8b521b2eef187106040c21ce36e73278b47109700c6234c6d415f0e42bba9578405301c61d8b7aa2ecfb7b0145463edc373d8e8e24e05301a81d0191e3e6444790306238c713f62d1e43efdeb35d63e10522f602cc2544ae26e9b84a4425a6aacdd5084a954764cf86c3fe67101231126b566592e665c46b4cb4c000311066d912da851fe41a4d3210c7f61db43caa5b9681bc29ce467e498a51121a51026e5392e9f449810061d134a790ae141982508f5385721447a2c087329ebef2f5526e60f8439ce6ea464656af2640161b69446be8d8a21e4db3f987d62593c6bedec52fac164f7df69fb631f4c29ee6e65adff50b3f1c16049eb6666df8331458ed029b2249f5735d672b4e0468eb5ced10bf0e223c905400c30f460bcb4f1faa542ce53aac6da471d0d0d34600b30f2600a6982a4b82e5539b45c808107f3e81e93b318dec1a4646858588a4e96658db5b230ec608e26579b3ee26bfe5263ed830d07a30047af200130ea60103bc23f8556eef5c3737c617e18061dcca924a54fd2f75ba489e760d64939b722bf65cfa68f3b030c399844d8a9a0ff63df851e0783a58689a7541bfe4170308e507955fa6358f5fd06931033ea6bb47583f1d37376b8d5aff8691b0c1adace3e87f8b922369882fa4cf652daf4e49035183f2d98fb051d6f92d460887339fc7327b17f8d8b56810d143806baa8000d2d380dc6d02222d553f5ee99ae00030da60cfbf57af7703eca3318b7be26ee8752224c806106f359678b37eea9457b30ca60f2cad24946844f8da700830c067517ed83b4fe1ba53406e35ad871cbd7e3b29be50186188c5a5b37bbb67d9d3d6130a7883fda42ae99f6d100030ca6b3b00b914275ea60d6ad01c6174c9d5444af9b8100c30b86f43b97bffd9e7459140230ba60ead4157ac7cc264b8ad987a11c6070c16cdd162752f27a1bf9ecc3181030b6609049317a1e52d809920f3336c0d08229291d26ce8fc9979033fb30b5d2038c2c98f7e2f3558a8afee75830a8591ecb3d59bd3aba82f9564b7b5cefaaf3b582e9b7a3e413d23e29bd55c1f4c9b28856bb5890142a9854e764a53fbedbea3b05534d2c7d77aae2e7775230a9a06137d2ac24465214cc7d1a298d2c75d9520e0a062d93b297d095ad84fb0473cdbfa5abb658eed209c6d5b4504ae57cf6779a601a6d61ff45878ffa2513cc6992b07fff8ba054b40453ec0bd3d6ad3fd7394a30789add480bffd22d4a8239e8a860fb5fc94bad483089bb9f117942749b0fc6114c49d99a488bb011cc11840a2a87d1cfdeba08e6ad6c6a3f4b53438f4430682f11b211f3b22f3f028c21984bece28afc8a259df6f0281f8607430826ed4eb1743e136f97140473bea978d6ecd68d05046377f5886b7a7779f903c3488ab964a13a9f181d0e183e30d75d075d6e32ebb33d30a8b9a43d7479903d2e0fcc155ad41d988358499ae02af945d68131e4c73ebb49c2c4e57360743b717eee57a16aa3a1c58729da62cb60e0c03c16225cccc98c8ad40dcc1f44880525f46f5ad60626fd172d47dc9aeceed6c0702a3e8a4eb942be80410393b4483fc2d7e4251d9d81712b23a7bbd58fd41d18323005a97dff932a8ec9321646d3f2380f23a2bb25b0305df06afbbbecc9f4fb0ac39f4732f3d167b1a72b4c62a284dc5e893551d28286161690000d6d81005a6148fadada644c92159b5ab10b08801546133af5abd492d72cf00f1b393ef05620805598c2da6ee7d3a810376320005518e4e7be3ecd5f68130502488529ed2911adb40987aba09d8b0f1514c31b282801a0c294ee84ae4bcb97eb2fd2028f403985c9c427ff298b98c26057396e9696ecd1430194c2204566e6ff7bc8be202408801426f7bc6769a476d2e6e8628b1a450b0f8f519852f8879265f7a62ca6111e672887243dfc2e5f7c7461833b8ad0610643d075973fa67a8f9a40e828c32a2a3ce928a24e7e51e82003ee5f5e9d25954612133ac65072bb2f31cdd0b30b5c4287188ebb9611cf7f346ec1f9280b833945131efaf24608dae90083214938713af79c599a5f3086e917ada2aae7c4e4dbb9282fe8f082e15bc4bd54e42e186f74ce695ebac73fc905d3e4169973514af6f45174d0b105939294f522df4d9cc65a3098ce2945c991d4a0230ba634f12a4b92e4ce6663c114f428a56c47f44b7e35d6cc6868a0010ea0a10109d0f0f09041c7158c3a493c699153b357a264830225d9e8a2eca4a500083e0cd0610573a4ac9491a89d26710f0f5e0a80e003004ee8a8824175ca972e6fc99354d5584bbbe139fc861766aa800e2a18640979f398e421775330a470175b17b4e335cd8f0e29184777ac185636f3f9d482060768584002343aa260f41c6f25c5fd8ad599066868416303342c20011a1d502874864861fccc3f5d634d058e010f0f15f80db41b39bcc043c7138cdf5f51527f36d52d7e31812e18e0e1e1e18163071d4e309c502297969610c4af8e269844926a0f777e6a7eac4da18309e6642a590ea1b53721a9c6dadbf8e0251872a86441f95a12d26a724a30ce4fda14f14f27d54c82797420c1f82bea25071d9f4ec5fad071044350cf11092a4a90df8d604ed1a5478f96fbe6a4a308a6ce26259d8aa076f5c2367410c1e861c4e517216774ea5e740cc11442cea3152d76ca2d4bd02104934a95e6d564769c488d0e1d4130c7121533b2e59ce3b36573e80082b12ac6071ff57ac2439258213a7e608a9d8492d9fe8a7caad436b8f0f020f6611b880e1f18d447f47fc7fa5356730f0ce2a942a57c499bafc63c3047c822c67284a9b2c80ecc29fbe46025569e832e9fd0a103b3e7fc1232faa774e7e4c01cf793f3466a383084dcc93a25f5ff0df50d4ca9ca7476dc49133a6c60b29bd1f7afb14b538aa1a306660f22f9626db8458e7ea18306e6206b92a3ed857ee5ac858e1918420a7bd723c553493a6460d0f5c1f452ca1efb7d2c0cefb13be446fc8bc8c2c214b73d6ae7707e2987bcc27841ee5225a929617b579872aa3d15272e88e7a915e6d6cf9654e58ffb5cb3c21037437755ffa2e4945598ca3ebf8f885615a6cd946839e59c0f6aa258c82215a6cbbcb99c13ef0a59a0c274ebf6e154485b3e39a730c7ca4a4a23ec1b3958604c61f0109552ca1f254afea5308ff04ff18d70fe1eaab19611c88214a6109479ce3e7d7a71bf1b4116a330e58e7b1a4134925b4a8d355118c54f951eb57f2af13d01b2c1c586c270e2262d9bb4acd0528db58f0485215e4acac38ea8c6da65208b4f18546d3dcd495acff2d558bb40169e3065ae97764f1225bcacb1c614c8a21346fd9113ec52a6fd7d1865c1095359fc4fe2d69ddb6235d69c8bd37622c86213a65431d789fb6ec9ae1aab09e3ed44f5b62dd3fba61a6ba90b1ba78b2f361326bf8a1f275d5f5ca45a70234762c26041a50b2b571344446aacb5e0460eb2812c2e61fa9c3e2e2ad5d60879324b98455987b058c23ec4a2812c2a6108b2697fa6b273ccd696035950c22074ec7394093126ea933086850bd1ba6a24ae92306beaa591266143422261bcb738a2539daac41224cca2428c70df0f6a52e711a6ab18177cf257bec91106d331e4771aedf183dd0893f214e18410c16cd28c30e78f9dae5f21f5b96511e65329fb9cc9274f9e2ac238ee3da3edb7f2fc441862a7a0ec65e554658908c366cdac8dc9da499243982cce9ccd07194bdd19c2b0ef49cbe6c2e4d9ad1006d51ac22d564ce6a93c3c70b8172dc8714701107c0400085910c214a367e4d6764b8a21b40fbb2c0661bc783d31fa395996bc200c49de09f123b1cc4e0d8461ce65948e8a1ff40f0863a898dc172d79c59559fcc1fc1366accc52fe3c310b3f185fd2986f044bd9c9f7c1105b2f2595a4d3635e0f0f3164c107b3af873455d11e4c41c8d1f1e446bf4bab078369dddffd8fe855963c184eb52b5be8feed13c18361bbf3fa95f60ee6ca932d9cecb0371766610753aa121242aace33f70c1059d4c1d439e88837fbe5a9743a1826c6554ab24d5cead11c8c6f66a3abd255e4242407d39aa5aca7a7d42774e2605c0f7796173a7030ae99d9870bf274c4ce1b4c25cbb446abf55da5dd602c714b4145a9ba384b1b0c1bdb299dc50a1bcced3b22ffd55e94145d83b14ee48aa74feab35435183f452a593339c8b7d360cc095ff91192a48b241a4cf9447eca10e6198c6ddaaf636c9abf04cd608aee22eb352c9a50aa2a64510693ba1b212f7e4f0653ccb17062d26ca6c8c76036212df34b2589c17429a87e1ded15742585c190d3d6efa4ead494243098b33e77309bcf174cd9c4a28a27715e757bc190824a3255933f7ba574c1ec7f9def42902729cb5c30968e6f2642b21ecf780b86a81f2584b0ea13e3d582694dad72fcceaa77370b463951a5f379b29b5ab1601cd5599613a24d4af30aa6b0fd59478d6905934cf68f3b4a8ee79454c1b835794d7627557d122a98ceab3f2b9a369192640aa63d75bd5f4ac63d77523056866817f92267b68bc2b1c32585d1eba0603cad94ee53e8cc0bb227183e4e9e30fa932cf79813b4b2cf394284ad09c66d131e572a74d29d09269d3e2c89c6e5d32fc1b027df4dbd64cd1229c12446477f3ea1524c4b12cca9a76a5fb3c2642498365436cbda826b5716904216473075e990f354e794e36a239846082d22d4cbcd7f8a60d056ada0e324f5e7b03040430b1a75011a1690000d2ebc40c1166a4430afa7d8b6cfebaa1492c30607ee3e90c5108c3732d64dc7ee3295f5f01082498e65af74a3ab1e4e48c82208c68cd1d9a16a9ea51d0f0f0058210b2018eed273ec4bf331e12106b2f881219ad6aca4e2f4f42a3e30778970abafb6d037d758c3f1e1c517391cc771163d3077deceb58dce4ab68d1c669b050f4ce13f7f6d9b8b0ed9da813925fd6b5e39393e6f4ac84207a6246e23f3126543c63930e851973c6f527d4bd60b59e0c064f5a542b05c69a7a31b18b4424f87da883a216f210b1b98438e962bfa05a5b4493c90450dccdf9d45c4cef7d1b28d42163430880ba7d353d6f0ad9c8442163330c44b5de92da84f56a2608b1b5e98690bb2908131c3b5d4d743462ad5be102316a620d1935cb45426b65b2ec480854925c7d3f5ab6b4ac5f415860b2a26bab64711f95d61cacd4a4a08f1126df256182396f8925e49cd66b816831506959c4e091d4ebfa4508d3557c1163752a22ebe78d2858d2db640018e5e0189b10ab3255dd3adf5d5afcb3eec0f315461ba3c2b39ba92f2a7570b1a34b4a0a1050d2d68380a9a021e1e681f568718a930867c864ef19239f10dff40157cd8c8f171e3867f78d12858bb618018a8307f2775dac6235e7ec8294ca2d627a414e6bd448708314c618813d383e4b7fc214f928518a530a88dacc84ff13c7c0e298ceb4195cf8fdd859895e9284cfea984509d5fc4a5105198a49afe05a11e4e3ccf408c50985c4b948c999d94da9a82c21c44d0cad974fc42d0ca270cda542cff7896212fa29e30c514d33457b7c61a0bbee80f1c5be017313a71c8a6ad478f87306d08313861cc104965dc566aacbd9f0b000e626cc23cbaaccf36de1aeb802e2ae0e161ae88a10963eca7c8eecec494adc69a2f51c19503c4c88429eb7b4ae1930af3c13a25c4c084b13be7e87ac1930c317b78e4c0b105171e1e1f312e61d4f6bb0a8babae33046258c2786f229ef77fc66a8f5109b39a9a4e5ac3ccbc932861d0e72762446848b10b8e2d100bdc930d0a4cc210627f98999af02177bab0b1c547310ec4908461562b89bc7d593ad901312261300db38ed725499bb68504562161160f13df7212de1344ec1e508256805a0e1c5b70413a10e311a6bc2345655bc8b11c2a00f010c311c61f75df31ae5de72a1f311a6150dfeb104ae9deab1703311861fe523e267f2b4a387b11a6ee7c29fdc65c6dcd0f1c5b281b6228c2a49f133f8450d7d93e0163b06b542449d1830c311823a41c429a2d7d1f2936920d1961309d460e22d7c608e1078e2dccc820030ce6141d11f4b94ef81a71f105938c116df11452e507820c2f18fbeed674f67f4f3b5d156474c138f21e724bbbc3f7cc05639cf7288b2d5241c6164c414372f658bb5acb6ac1706739548a3769cb436464c1b43d49697dcfb7a17a1958308f34ede929ea46907105e39c1c5da645a78ecd56307c96be28afff6cc184b6c8d1393290041955c827b5d5cdfc766190410563ffc80e1d65259ca59ce046a3c06f988c2998d74cf252302421dac3bccf838a7714cc637fb1f6c2733e8f0d20030a86744a6a990433e1697f8239ccc5eb15a1ca3b742798723aa19d3dcb92ce5213cc7d715c46a911b1549860b48ab5adeb4b1eb46709c6ff5db7121f3c5ebc4a30e7d332d5ac78398ff20b2f92606ecf2d39c6073569511948309e8e246549e49bbf1a20e308a68b37799b2ef2846f04e36f4bfe2c7f8b6711ccffb13e92ea49189d08269d3121f2c63f04839c5d8a13a24230574e9ffbd485ad6406c1a0276a9927395a8940306d9747f8c85eeafc812927a1b4cec49095d8fbc06413a4a48b1727e1ef81219dcd5dbe9ede34f1c0785abd25f72ca47c7660d8fdfe55af9589b60e0c96a735442cadbf951c18e4ab465c9771604a29172e37b981a9cf45b72d5be77236305a4842a5ebce6b60aabbb3b3f78ff697cba081e9f63c47ca5f19e272193330859a9d9e58c182da65c8c06842627c7e512c0a69a74aecd30916862065724e69a7571873d5b63582d29bbf2b8cabd7a9b5a6e4b8a91506a5ea2fc590eb131756989359a7ca4dd6d3d9559824971e95f2f9a4e0aac294525a8b7ab721ac4d8551542f5c695d2935418539dae81021a354c7083a85c9545a5c9e780c292253985b2624a16c4f98cea15298f2670f2aa69228f9218571ad757f3b72eedca3309f49cb232f8bc2581d3af2e321556c4361bed355ca666ebfce939fc87e9e13b3f309c3856cb933e2d7f9c713a620d16f27db9d30f78ccae1479eb4b339611c3f933549ba095376bf2d9de029775213a648e17c6e24ebca9809b3cc5c7a8753553a870973d4eaa4bb737d0973c8a7ce5a2679b4ad2d61ce96ee44c5889c9b75254c7b41b99d122bb25953829cd47d98e92761cafe9096462d4f58256110d671a2e935ad279648182bc951dbda175b59818441ebe8d121afe7cbfe11e638aa6639976fbec511e6942645e5c4c8e26a238c9246a5b1b29326228c305f2e616245a87b087911865827743eed5811e68bebd039f57d3e281106af78ed517911612e4bfd126631b6c73d8439480c15a1d22d4eb88630453c3121d9a38414dc42984c77c87b77a5d7c32584a9e4984ad162e5e4dc0ec2143a65975feb69782b08e3e7efa7916d0361cad0102994a97aef0161d0b19444134a5abdfe07e3cec4cb0e29723ec90f66391d7eef7592eeba0fc60b25d5bc2f760a5a3e187e2e74a5e0374a64750f6611a52d29554e4f52d583c1c7bc52ce97e6c16012827e7d13d5764a3c18fd4556843e1d3f72f20ee61aa5ef2ccd6907e3e98513b93baad696753097ee7ca53da659793a18b4a50a573274b2d8cfc1ac716159576ff1477230d7249b5119119205c5c168a64ca8fcb1a363070e86fbb871153335b6bec1f8c1e3578a923b65d50da65c7a674ae9ae0a4ad20643caf993bd7472b6246c30ad5bb8e59b4ee126640de69a942729495e0de65441271db75fe43f9206530e42a913d16bdb7244835135d3eb3ad8095bf10c8637a1bbbd3da2f58666309bb4d116452b8341a8532989d1cb7e2a2483c1cbd446b8f14aed8fc1bcd75eb27ff296c4c560d24baea5544da91c0a83b92be8d23679bd94c0601ad393e2cdb466eb2f9845ad83c872ab1cd50be62de91ff183e75eba601053ad8b13b96098a0a4e54bb9db82415bdcee24cf23f93a2d18f5ec27dd5e9705d3e44fada15d39873c164c5db2464e5e8d35f915cc296f217dac3d9492158cfa15b154073597ee2a98e6d449b5f8ad242e5430b7685321f2650a06bd9552ca69a1cf220573300f3337d9a260b0f568d95c8382d962786544b9f330da134c41c48f7d2a6d04cb9913ccde25545b5049c653d60443d637cfbf9ebd6f6782c97eb4ab5eec4e3f5982e9edcb7427794ac98812cc27d62992b44f72912418336d6fd5ec73f61009261521a84d2b1dc13c5acc549424a22719c16ca67eafcbdd4254044390977366d224c98c08061d41ac7efcda11a91a8239e6c4ea24a2e71195178221659985e510776196060c2008e6fdcea346628dfd2801c15c39e4fa32747ed07d095d42dfd828aff8c0246fe16ff969db43ac0703e8814196840927c663a97d82ce417630001eb8225a3d5ef54d773430801d68413582ba3ef5531778662e18800ecc152c7f0ab2b4f7d44bc630801c1854687c9e5c153d49968401e0c060276458fefd907be1220ce006a5a553594e8c906766060660039365b913ff3c9e44258930801a18238e4cb83c5e0106400383b6163f378b1eb4245be011c0f5a251d00511c2006660f814b157d953ae08fb00646098d892b3e85d64b13716e652da7c929cbd4ab1030b738510c2bbea5252b3fc6f91f6bae315e6385b11827b52f1f3b7f3b000d0a0c315469dd176399c9599b66ed8c0f131015c0f74b4c2a04ce850b245e67b973a58619e1ba533f12ec9885b598549479f12c24e52d05176a14315a66842c768951f9dac4d854962a90baf734ad829e585a10315e42c3eda6ada276d5c1a10011a5ad0708087470bfc0486868e5318d2861a5f516df9c46f0a73e84fe91e762d8579cf65ec53ae3c499f5ce8208561a4f5a5edbc7aa98238bcd822070e2fb6c8310ab3e9edeb1055e31f3f36d217386ca42f7088c2f09f3b848e3bcac1c51625c8c1c516250885d9b3529061a7ce521a14a65425b98298c849253f61dcb1742aa9cb4a2192c40a1d9e30ae6556d76aa5147fd40953ecee70499b862ccb55a18313a64b6da9fb713d04d111063c3cd00d12746cc22827a731c2df83ce1a0f0fe42cf0227468c2149a963aeced99484c18ae3ae4ab8aa2924aacb1f6710963f5966ecd975029a325cca6e47ad2a66b47e95f09730cd36952ca497815d558434a943aaec4728667cb4551cb4fea63b44e5de77f564e051d93309879b614725ee949649230e812b2fa431821b1bb8c844977c88927c47dd01ff6a00312c611b1b3b7a542627798071d5af8cd9fb7c311c6399d45ed9aaf97bd1d8d30fb8cc821653f31c290e298bc93ba16473bad60e8588421a94b48563271f72b1d8a30c7b3fc20b612ce4247228c1d45f4e6a868a3bbef408471648a3839d96bd9e24a42c7210c3f5252929b9763fa39011a5a78785c87210c9ee22eff25154eda1d8530bf5e24ed22272f84141a5a94a183100629a3a346ec5bcad5a20047afc0c30305387a056410c69c18395cfecaa7a60bc22841b74cfef4d1d080046804c2ace2b936449dd5870410a6ce1dd15ab1c6d5f407d3c8fe68932bc70fe61479da4542fa60ec0fdda253ed7c307827a184b49c4e5edb7b30c90cdd2e916b7e62ebc174f9913b87388d3cca3c184fdcc9951362c2e50c0fe6dc503a6cab750753a40bea2145b285f8d9c1ec21ea46f588141d3b753005a9262aa2891d7430d8c955cea542e660d4d3d972b59a6e179283219e69b7bf98f99cd7389827ce5d7b4a952d7fdc0107a3f587d0e9fbeb7883d15484f82f67ca725248e87083a9b3b9c90921049316521d6d306b4891756a724e1c42071b8c23f4b9a4fecdfd0ad0b10673be7b48296adea7c4c343081d6a30da450e56b9fbc34b5a63cd16e0e19106537ebdcf16561ae72b1acc957209f510cf3f6ed6582b868b2f7038063c024320c0118c1dce577eb535ac7335d60a4d312010c008e6740bd1907d93f6322305018a70acdf9b134135d66a060420827962c65c14496241da359653172671f1858d1a19f0f050f3d3c7120438a4d1129773dcf25e40002130d97ce7b2778a1408100453c4c9aaa7957b963c35d63e706c0104536ddaa6c80b277bb25c70f1c59fa96941801f3cfa6dd573f09c6404475a00f5cb81003e58b4859121ba3dc90e6d81a38b2d6e786a77400e82003d30083d96a654fdae530a1608c003e3a57e1aa154ce65fadf81c94d52c8d949d781396c7c85b86f93accd81d192d01b42c6a4981207c648f941282182b211961b18dd2dc6842023cdc93420800dcc791d22972c754ab849011e1e384a170850037396c7fbe42b42bf9b6860b0da89faa193e9f119025120c00c8cd9a7eb525b3dbe3402c8c09456d2c5504ad5079dcd8885416b4cb58734a977e219b028686f31939fa4bbaf4862c7965ac4b4f60a2965862b4c25f94cac3a74098b7e71c38b3b2d683c400b0f8f1b284001eb0f66b4c2f82571acebc4f6c7ae3061062bcc15752429d5a37b3f5aab30e5709e52b2bce7742f0933546130ad8ff73948b7a4c244c28c5498f75dc38490ab919e438419a830887deed02927a475afc6da47b261a3041f38ba066f91805232cc3885299b8821c26e5e3efd1a6be8c3b9485d740db4a1811c5b24bfa18587070540f0118055cc3085b94d564e720a95752a2508334a61906b5a5a1f7e56749881308314062df1bf54e5745d4af72fb8680e8cc2e0b1bb4327468a284cf1f65772b04fa1e357426150e2f4e99fb662300314a63065a1174f277ebe19f88451c6434fcd44519d843c61566f730d99e3cee884a93c5aa4582a48eaf2ac31274c17c73fd207314956ca26cc9dc27c5d8eb6260c3f6e41e57abd9f0433615a7f397539ed56ce1f264ca523a83c9d439f50e94b9854c6b8664d48726fb18429a730e51bebae61d14a183e68d16e71d348caabb1f6c10517fdb11f357278e18905332861b034361e33cf547d28d38c4918c485e420fcd4b6fe481286b5fa8c74fa481845a724f14cc84bd69119903049ed097f2ab47a9a6bc6238c59fa51aebb43f423331c611e376634228dab8f90bd749fb6c61ad96206238e9e949794d1293fc48b22331661d2f0d1c82ade9e29a24b6a62673b2dcab22bcc48844124c49b0da12d9de820c224fa41c49ed8ea0ef321cc21c4eab54a13dc3f8630c4cbfec82ba33aa46c214c6ace62d5fb87ff132184494e777bc8f191a3c8660cc210d4098f587922fea28d98210853e8f5f8c17357ce1c91dbc38c4098b48ce714237eefc68285198030e77fd3d5bc325d769236ccf883e95a457c7ffc770b397e30a62761f1473c7f64990d33fa60d6dd970f337a3e98c7a45c9e442d0d33f66010aea53c6bdbde776f01175e78d1650333f4606e13af1fff5973d619c18c3c9c2b54e9cb18dfc030030fa694ee1e543813415dbc83b1b453e70e9f676a5a543b98e5834417651e4f82e4f20e33ea609891d5ad20f3437b8c0ec64fe95325516225a56c0ea69ce3277a2521621e948339bcf7a99b7822c8ea92e461461c8cfefb123cd672bfc739cc80834967ad9cbbbbc68bf4e30c33de6090ba1ecdde34bb196e30674b2929a5f4a53af56a6983c1e44d8f7eaf173d6283a9e3e547ec3416ee396b30f5e82aaf48a5238d5a0d268b1fd352750d6d350d06b127d4d5040d0d660fb338a9973f652d04cc38c30c3318923e09162b46cee69d32185b82969482d0ea53693298743cb9fa57650ce6d8ad11f546e66973c56050ad7c51e24388d96130a5759ff0b62518f0ed9359f51232e30be6f7d98a97e45dde0fa9c20c2f98438ee36d2945081eda195d309a1097c9e15752fde68249bc24b595976405af6cc130b952c5113bd24ab45d70266668c160a2257e4e938967264f624616cc9b577e73dab31f52f81133b060b6d2f37e21be2e9a0d1b37881633ae7045b2deaaad9067d5580fd7c2bf7174b1013531ccb082d9459e4ade39fe96622412985105c3d749f556b1e449785430078b71b361af12664cc160da258267b887ba902fcc90825154e5d55139a419a5ce8882e146aa8d6da90e95d70c2898f7edf4c7c64497bf673cc174419fe9a0ea7f37c6194e308c9ae751e1cc53ec74130ceb26f6d7a2a9347799607ed32df12f397ef2dc8c2598cf530e167b7a12523843090613d367128c3aea3c7f98f03f2b418229ce4d90f5249a71046368b5af390bd2427f8c60ace4d9a9ae7253f45904f38f989f50a7afa31f36127f31830886e855317b524b3afd0fc1204baa8948faa6d46f2118a4e4594f25bb73c26843051f36d2e69811049376f80f6159cbb72540306957123331e5a5c4f603c38b49d28bab3835a98fd445670e66f8c028294e6be59ce6b39e7a60d059462387d1f4d12e0f0cd73a314bed8a4e4ed948773698b103f39f8e45d62b91b4bd3a3049d9bdd0c9ddea7fcd81415d794ed73d75ea331c184e828c982af777756f6010bb11271baa849cd00606f3db53e9f35ba5e86aac7dd8486506336a60320b0f6926b95a142d0d4c6aae22da08f5fce799310383eeb0ac9c77a13b5f3364601259fd2c87285af9cc5818bc732e1fd7de6ef5790d3260610e336184901ecb40c62b4cb51a6af53f25774bb36980d440862bcce1d923495e6798c4c8b6c2f4162dc952ff64a6a2066e68218315a6decbf5679ea6626833a0058d08d4c0d10ee0f3a25180850220f878808c5518649f24990f931a6bfa0719aa307eb07c75a227e1625f63ad0aa981a36b905418dcde372ec70e16b373c3c6ef7d51010f8f1a38da013570740d09f8163734208174c3e3865742062acca2557a45c9ca2c55d758ebc286c93885d9920841a514bf7462de43c830852958b63f616b6ed9ef52987bb393474ba9d4682e831406e9177ca2ac6d895491310a43eaa0b46acd9808f9230219a23028eb683149e8b32482a130dfc5ea4f3c29aab2ffa10419a030041b4941ded7d3e4e41326eded53ffd6371bb9278c92fd846a9b14d13ea9138611caca7276b9cb71e38449e4544984d39d4d94d3bd7388b264d5adba0c4d182fe4c497efece51241cd8439f6e9a03bdba6cb24e5c9c084b92ce7afec98923c65370d322e61f034d244551239794e3901f21a5ae04186250c415b2bcb8b76391369250c7a4f9ed74bb4d0e651c298a15ea2a85c8892a449983bdeaafd841589b949c2a4567e31c5437b1991309fc895b311ae23d117820c48184b5cc9d1e6e31e43081f619c147bbb43a538c21467fc83887b712bc55690d108a3e58ab6f9113a5e486284a93a8c2ab91c3ac8b86f0a321661c86ef292ac07f3b858086428c2242c94fc7c0a41fd53321261b820395775fa3071224106228c1727e976bcec9e2dafb156ba90710893c5d0115e2d5d3ccb8d761c1f072d20c310c64e592f7a59b6c46cb990510873c81d2689d029abc70961f8339dd5889eab84103918c81884b1439cd50fe5b1c2bd9a2a9021088396edcbba957e3ccc390619813029b1772d3934d34c650908a3e8ac9dd35a589c5f760b32fe604a26f258a7dbfc60aa0f594aff6ca873530b32fa60c8dad1d2980ef3c1202c8eea76d0f649d92bc8d883e1e36513225c8a5631f221430f26257f2e6c6e555b8c0332f260cef693e38308614cecd9041978305ed6f3964b09a2fdc30419773029bbbf102c9a0aca4576300839313546e6a9520b7274f1059aae40461d4c215a58cde94ff16cd3c12444ecadea8fde1964ccc1a0bba154a7c98a8fca0153461ccc167496cfeddde229d37c830c38987b25560ad59fb3dcf806e3b9beaec7d3718351444e7a4433de93966d30d74f7a75ef9c9316b1c041061bcca2f4baa9f5f7e764ca32c858833174e4cfe78e3ce2924e95c544728f3a4a83597d3f9dbd550e6a3b1a8c9a753a9728ff0cbdcf600a71d1d76fa10bc8308339766ad3dff1fdf288cb601a3917226ad4ba332383e1e4255987ec1faedf1a6b1f3612a640468d87a8449165d2581c0a8542a130280c8360f97514c3130000000c1e144763f1589e29bbb20114000442343056343c1a261e141c180d04e3703014068403623028100883c1a04028748ea6700c8b0f2515e935d557e99e1353aeb200d9fcc6754ce80c44c8119e6eca14f2955f0f1c331dc4d506d130fd1664da9c86913a19b432400ec18bb911457805b235891c4adeb651768091eab5d77e70eb293d81c4e3c2663444d433d431c64abd4c5e2ac4d1c74d6a65fd83cc3375796e80d929b7b27a360695d2efaa2e71a4927e3b85bf4b25079595fbd2e12d5ce34315756e9604bdbcf2447447949e31e3d015327d4ce6ff8eec4b19a3a68e3a2824240fec1a0c4a29cd8fb6e60e69df702c238fdf5a221c2e4854653009cfbb492309094f03eaf9fe9a44aef6c32dd154193276cd51fd88a713bc8bbb72614d62280f0dcb61821b33646137b0ed5c93179a1cec5d49039ba3d9b0fda804b3e9f375fff67495c531f413d2479b2969aceb4e308b44c3595f73e813bb039d68c5d33d15d074468af96cdc2007853353c5e872a516d2328d89ebea6ff34492bfb54746e9263e4f46a88595c6eb656166e4b4ff48995183760f133699db9bd3f91713e84bb02dc6f0280d3e028b4cb443aae45f1c59f868e386af9883444a0c3313163316ca65789f5ea051f15275dba98b19f039901ed51a26979dcee3cc0057f7ce0115f98c7c50561c4c70dd3a131d688e4dc0c8dbf95b9318d566b8c1a7f13a1820aad3e997bddc246f0501819d6dbe2124d360abe4e6f8b9d368b0e6c9650340fa75193d3f6165c390a5645f63a4630ccf23d0e988b646e2c50832237d45d706f09fd133460c2820c85317b4b310e3f2236f200911d6195baf9b946e95aec8046f4bc1f070cb369f9d994f47d747526de2682ce100b47127ff8a3d2a827fdb6947e9232edde09dc9d118655613024789b870a8c4c4a9023cfda92f006b7e5c2e9d26fce8d3531917d86936c09666eeb5d85105f5d96a1285d0cdc6088b5a9ce6545550fc62a55a82a94c5285fea0553886d36acb8394807da585bc695904589de91399533c582c41d09282f086e43284ed66f127a2d58407d58c66b9c3921c44d3fcd24a15ae568a5ebe6f550257005784a41641645c8feea284388cb28047a9670165e2f8fb11a03a18ace39a114bd716a330bd6276af016d6933466fd716a0dcb83e56b4553be0fa08563cc701c9322b365491d6fe6e067f4ba7832e5027bb66a42fbf982ccc6768fc7dc748ef8e74372037cd9c2e33969a5a8ba4340cca6fee1aac57efee90f26fbc8d5fed521609bde34a2c38edbe02fea1995c710f46cd8926f3ee054665cdef666013642696a1346dce3d9b935fa5dd876d522b5059bc58d8f7019d0b133494c18577e1ade092c4b7e1b12250b93e882fcc097e2ae27503b3d2c0545f0c15adc5328f93e951e631230d6579f7ee5aa358ed8e6ebb9f50ef288a543c45723ff414f08891a6362b4a7c585477a951373813a589b3513eb6ddff4d1dc76fbea8e4b03563d4f4bf6943bedc84aeb862c66254a72fc70a4f997d631840619285488e43d4e4b0618555bf6ff7993cd9c8e83d4507d42df8ac79ecbe7cf2cd1c8d51ef005c319d1b591c3dcaedeee1909129f14831e8e934bd575423155c6daca0b333ac0a6288eff7190aa94d26df0fdcf706f610be82a7eb81c69d36165f0f97435d6808c0b1cb38c91ef6680f65f2e8219ef2f12c2412c80db41909203cb5da2bf76d21f0a6edf92ef1be0a0dc7415ae763989a43686280f82c90a64bafda406d829e67911fbce7e50f8c9d9e4886e2a7f0ae954326d3c32b98d18ea3780d645642a76850a5eb633d09e8062181b846d2463553631a11bde2cb0b24489d5c41f0e67fb1e1e37159e99ea2a66f93fdec382ed9b60121641223d50946ac1edcf085e577a3607d2305510bc6127b38b6ce897021a09a554ad83c3d3d47a05f281ba95037af91c7229f145b624c8e36600b5adef16bcfb3e1760774c91ec83d9675d492ff9d7f424f813ec8f343d935f6c7aa7cfc9c9ad4a26408f147452bee24bf1154bc1421e669da917700f30d08c8414dc3d346bba0a73dd70d13a03c2c17d109ed09a71b79f24fdb04b7e9f589a33452ea6200b3c60c75e108fb01d33f2326022f2babacee5cdd3a9dcd48a8142f5dbb74c2bae7f146779f26c070527dadc04e5142a12d06ac44d69c68bf20ab902b3411ca990c250ab4a8295f5cc92e01c46c6f8313e0730889f94103c04a271a1a9668810665cbd920688daa2ab0ac9089d20193eca01b8c49e910e2df46f68e6512ad5385b1363d016da0c30f6def5453d35149ea2f30c5454043b06f36702f4f07841ed2c652a2d80f84f250e051e9685d1b9bf4710af4ddd3b1d58fa546fbb26549d5cff4339a3fe2537e46cd1a727a1f3f31cace2767cf447b6a6c2b2cd19c2803d01efa9f731c22a779f5235b4e70027e715161c209e23408ee15fe61c60367185730afa1e881b4be630e3034af70f8f12a7a902977fa47676b95d68889364acb145d639177c06c402624e91f0de01b5dc7d81f6f3157d71c7eaa54ed09b7247420260af12fa8d1892c80b00edbbf50cff96ad8f070f160ba02ccb6cdc5422419fe282f4a314fc05b20ce8d96f4f17d56882b6ebf66059e8d107135521051db202c099b7307e57c67fdc9b27b44e03c49d1c0c37b7104c0a645017d4c3bbf39d81951e3fd03ba90de3ac1ec34e460461009e16a010e9b2fbf61e8843fea3b97269bd44ddcfcef2e4f50978aede1bcb4735261489dcb44ede40c69ab926d5ab441563a5cb5cd513c0f480d8247ae1b730a9ca315ebd32be660f6efd4c762259ef8d71dd7b3c4ccd7b401479be91147834f9d154b8f4bfd1783a4174d4dbe951736a5e4549c86cf4313a4b6b52a8645720a692995df1f2ddafc3fca341e4ef76ba08b57f15a397087c02db6ab1caa3c75426fd433828c9d4dff765c57a22196fac2487ea9d1ec49c876ce273a353ff85278af8ab87510bd80ccd5a2a3672c6a1cb965cc4b0ace8757a1d06370430b48829dc1d645c47c30e91d02628f193ebaaaeedfc51f1bda6474eadade3e208cee33da6295565679256c4d188b64fd6f31b0614a508f9efe35e025317eac65e6f1b12ff2ace24a92b0a39e8e280de735f5e47a8ea2a9cd582c7c9f913def21a62c0d9708ac19216f7f90ec15018c5730f95e1f3b416bff1787514842ab6e6242c89073f69b261dd381c169785b0928962393eb211141e728da5a1147b02fdc6cf000f60b8adde605862ca16e03b1bf6e64e4f14ce7584274415967a248abb91498aad5e26818ae60c8a3985822946614154bf53ec087e4a9f42de02d4853b0b5020a2650ef0c9a8866091ddb41163b0f292e0dfa48426251b06f839e40f4b681606e5e4991057489c916c23a1a10f111120ab4a0eea4af2f70dddbfec18ac75d8058ad40d59ef704ab045c8e0506e67794163844b9efd8016364da9804ac9febbadd75aff27748af82661223f915301a21dcc370238d0a602024bd1fd430247b53534b3682fc35b9613ebe0830be262ba420825ba247918cb8c481a0ee359042660b38e7d2380f61c534dd182473045b738b3bd88d0f7cee823bf926103a40ecf63ea4bd14bba392e0725d3e2de186a6ed7d2dd18c0184147882d7d74f20a07f02b5e7c63e49b7d6586fc4b740f60a502dc94fd264c5691ed44e71655069eaa4c6a162a7f9d272abc898c52f2ad1c7f8a443fa2a18d66d8e95035cab372cb177a34618be41c976fec7648352223915586f21a5d968298ae628298b34cc729542169ad6216c156184b117d152582cd571ac306c5c6660a165f72e05a864c8b45e53dd71d6e8f2ead82e65944f5b7e0a3d16f1b608bb280a4b308d129e041a9c05d1260d01661bba70b3bd1596006a0c0e61dce18377031308211085a10ce0fff7f2d175e34669d839a773b2ee70f4e5ac544f1096d2479c1c3d1e8a42363e4511da8a34528dcd5a5986636ac1f1e55b5597d2fb1c7e13d4884e80a663246dba34bad54f32c81aa4d1a664651e8ab850c73c754189b59218b021d5a99db2c9cfd4eda91acac26cab18ad5c587f90ea981b8b1105e91d4b568ba85fbeee8fa609f2542566d22726436032c6f448b381725f00d7f6da63a51e2e5bb3f2080587eb64acd05a38f7b5faa830ccf81e6d83f6050098080b0a6e49c80709e02b988b6e97c2361c40a28eb5bc1f3cc321f7b2dcfd0d10510144060a3d04a1375e0e0825c87bfc2fc3cad2be668e87590abb907db333a2fc263766775c14e4c38ac3f41d5effc1410dcf315b1eece3416c9780ee738e6d0855aeffe1097e9329fc55d3e9ca9087c6df6b80a17e541c786e827099ce4b58a149e602dc906d8922365610ddb843ae98151c14a236db415ee677135d1b7075275f7097a2c7db3723e3d758d21e5462c54bf262b17e835eb50eb854909cddb05de2a3a42e75a28776ce6f754706652b4c3cefe11a91deb97fe26dd998a738d10a1fcfa3090139df3e1792db3d3792fa1a799d5734fe19a0ed81c15a46af7498e80f9e7f4dc8631d6f358b4fb7ce6d8ef496d391fab6b460156a256ac6030b05a1b43bfa89002589276a70e0e265de40dc84a84e5c84865a088ac1bee1ec06abf228b313a4ebfbbf9dcf8943699c0804b3d9fd09db19451f95616d378139a8d9e406c494208525791223aeb81cf08efd360eae8862706d403ae2817bbfe4490fc935d1bb4936a7d0c9544246d4d18beb20606739bb92e84044a44f27a1510d425446305293c1ae2b314d6feffc1b34a3638c94be379af27d12542d4045a5dfb6c7b559947740d5a75e6c831d8220cd4cf8a7e00e3812dd86d3fffdd6d5fe91cdcc08177ebd8e7c15948781be697d412d29e519ede69afd26dbe7d7d40ab6ba565eea80e62448f634b9b4d3ec6d36086214007381ce5e45158e66f6c7617970635580749fbe6003ee96cc3aa74de57ea131aca128ed9258365d8c49e1ee9bebad8baea4ea045a1dd445eb9aa551bff1f35282303aaab55f3159c040cf6999ccc99b2c93d965f3a952315162c2efaeb5d8ba5ab5142e77a35ed59e91f440cfe965d6baa7c729cf219e87ddcea44aab19f5662da7aea85642e55cae1cac810e8ce49c94c99ccc2dc588be5b20033a670bad09ea292df6aed65a28001fb8419a0bfa913f9782bba69d9c96ee5889373a889929155af5a87cd6e6dc1f13309c0064880edea01dda712c0691a2bcdc7a8dd32fd9d35ca9da2a44f5592f67f7b44a519e663a2d9c5b17032bd5cdbeaa0d0a7d36e035512c2eb62b309c35cd4b9408d1eb36395c47f42b69baa83781988d9f9af68c9693d0a2cfb19685467f9358aec464b1a400e3e90b4d15b63f6c618fb20b0e7bfca8b3d223538cbe49551a50f524d8696eaa54bdecccda325b59721ad7040b6dbd9576c28307109f07c6a45f02ada4021f4c27c70ad3fdd457f540fcd71ed041b90b96e85629e021e26b91fb357836a29e1b315ff8a662ceaa88cbc2dae08ab4cab5781264a89cf863656dd54a781afef003aff17b00b649223c61b3fc4ed93210d4083df7f2054ad5f8916a11250776bb474afcde8070a03ac3ab4642a82fd0d8b21d44f9e76c5f7b4306a0afba43828c8f86006948b2a39793e2c5fb67cd36e357a3ffaa4b5257f13d519c84c7e16c014db804ae7b16153b2ab5159a22ee0a8e47d2fcdc0c58a6f5bf55b235a4d367064e0e4dc820982ec17c53e9e09d18cea18a9b89ed4cc921459958cc60da9cd53225ff0e63ed03076fc4a041e6dc7b4e4a14fac99986f362dd8951d8eb7b95d7a28611de36663c2ebd3653358ca005f881c3d9897f0a16e74072eacd5f118d9b2a5efdb9b7b9e891cc2303021a86e3a6c8a1e43f0838d29c226cf57ff04dec33e016d6a36252c36ea35849c8b21a9763f5cfa7921011dab0f91be0ad109e2b39683674bf07674f3dad160c776503f680490ccbce93eb4cfde05655613ba1a611f364a06e2c4a0adef6d9cb79d12ba577a44d7295a8af828c9cc08b0db413592262d83227468524b572695a32bb50bb6910c25f221d1e459e6ed04a760fa838d2590b68433940f58691bdd1f17e25022389e0ea0ca70c8f94b603dae629bccf5a3dd7fafa071d093a0b6d97fc204a4c3ff45e90b1cab00874ad7d756880c480951be64e1ebaca40f0d107a5da0f1d81d059d59379131bb2288c1dcc769827490f4395a5248b4d40e0a1738c6c7df960866c8818bf2f167307a65a474d0e4e7f121d42dae258bd8e368c5f2520a4508a530495d3ac908ef6073ff0c535069c532deb887e8605b2867889a39b28730467b1df045fe000e47e3989990ba1981973806ad4085165a4bc1593924bf2b67ee49a022238f35b57b614c78c50f3931289fbcca9cdcb914d25302c994c1975870e2564a21ce049701d4afadc798e713ade09bd7411a40a316586aa3726e33c138cac22a532ee7c0a93fc9aff14bd712bc8ac13544d8efdfef2e7843779aae61ce72de0f97e7088bb782d4c6e9896a9a7632a536222338323a231b66e690cf92f64e8bbb466abee417ee2713178169814ce3f3cab878fa7828da4eb68c204976587778f0215358ff93d86c9f1da7f5c1a562049cc6a3435ba8543f69b84b781a58a98b04a45c9bf1f81e90db6a5a88153d7df27f23b4aa50662c433b04c5b20103079344120d91c52b119c1bb22f9100ef26cc7d746f92798e276ff8e7ca09fd068f4be423fbf992c0f99d10f7766b89b22c683c64dc34cc33b35d65871eb3f821d063403ed749c9bc0d400fea5c9ac30075cf431c69a462b1a7b219f68ba782255c7e683e988dea42343b4deada812efc2515b95025b3c5dfbd1e36217cb6fd280f0ea49fc22e81368b2a4fc6950ca1ead6c41c756b5cae6fda17481f4cd02a363b2c0518ccb650065be36a855cfb91c4d72196970e151c9429e25dae3d601bcbdea7a8468b85b3b2dfcd06e1a4d8f62a5f9ba3c8de9dd1429530265b37467ac74b3bd920d6b3e86f06b758f4fdc869a213da35b2971ae65609c05d6d6084e0d06e1c838a1dfeb6e0e9981011a7c0e427f88380cc0c2cacdd5752df7ad611a0f182d975ce17712a9cc292b30aa502c2ee3732fa41b2645d9eb76b7d081b0a24508b99c398440d7745229514a28e27a06002167b822982287535039c5f900163da00abc06453a610cbc71752de78db24f47e2841492a81119999032364964a5acf9aec81ee548df6ab3843717447163c286d6a084cfcd2b9f4dc1449111b2b9368afbc09e623171271f8f9ae165710844a9f0f6990e8a43c38f90d9b11560ca380ffe0eb9b59b411e0f65e1c8c6e28f2a1e8049692e181536899aa314129127804e3cbcbb56df21fd5be2c03c036039669bb355c3162a2d55eb00a0c9ee55fdc4e397f151504888d76721fb5d70e156d8a1258c6b39e6bf19bfb5130b57122f4b3b31b9d227e542b7e08768b3ddfc906067efb8909062ae0341bb0bad6e9bba5ed97ed8236beb408a1c2934f37a12f3feb891a1600f14ce07c2e6a83553293ff1441a2ad5e526a9a1cc1bfaa2e0a0097797cc20903967660c36109c602819029fc977350b10d505799971085720cb2c3d0cbb9cd37ba15ebeed57a3444fb18a2c4a10f80bd3b80240124d00086ba8f8576700a84c17239c5732c7a5725b5a22133aa23f7a9d9de905924c9c82c19adb4ea2c5575e61bc497c11f0c04cc23a32fa9a003cecc551d9ea042384a5f201ad5cadcae108a6f41aa960b032dbbaa1a7911ac62da0d819b7e744fa4ae22652b694bcd044772a323281d90205c5d5ee210a6b82251577c6ae0d70c99148ada5170d36751954b0bca23d7de4e8d8a033919278656d6e21f25c700041b0d6296e629f5bb8405c4ff6710ee00e56c1f7a4763b50ca5f061362ceef80e1904b2c69529064cc6b7c5c548fb3b64f259dacf03b36d9ddf5429993ae44100a51d35c2596505a5c040501a0f17751d00d8588369aac0cb8094d3e8b7ae995e87a88d9a3154c393762ef11323a406759431b868e3836867b8756c5dfefc509d8b75ba9614bb62e242becc15a7e25a13b623c0906d6a7a563835424a72c5f0f24e9e428b113c6901459832a3faa68543122575a27282e598e4acb2094be296b260f68461de88f59a22f600c0d4faaef59df66ba38876544c45fbcba2a6fca748dea1c57eb3c297f76d2004cd7a6d2b1001d19559189f29df22407539e9d4a396221bde703d8a83f2aa3c7650da8986bf9018711c782343210861750e0a1ba40ff641ee85635ca4642a6950fe3542eaa1fe3fd05ebee38f56d829c4bb9774623c4aaa54368ddc6509a01ed3334701e80e6774965fd7ab1199de4f99261b602e0d6549df6895d56053b1a492eefe45a0f23c9e58b5eb4af03fa7d6d9ef477a23754125a9b0a8e48f0253de535443e94eb0d9603118d0079697ab395ca1f16c9160c73600dc4bce18130aa31073abbcc1853ebabd656e8d6b432b42cd0597b70f674ca63111b6a2ce57ce8a60fe24597b02aa58fed7bdb80f5343cdfc92a225e8b02fb39eab7c6ef4e5f3cfbbef25b67bf053f58fa5fdab7c4ef565f2c7d4ffaa6a45f91a57df278f53447bbd75979c211925976126a1b251a27ffafa7fb836955d0e6f734b63f4ee894414c595b994e62f69f5dfc09093d7a5a1b410e66c398bc6f4b47a5a07eb14f0cef5a8ecc660f3f7dbc9226d7409b5368f9eff0b0b0c6bc9ccccb0347cf5c992bb49e631458b127ef44c6eb62acd7b203d62621f2d79834a481646816d50cf5669330dbb8d911dff6730373b8ff0674dbd82b6d95485bbf93ae338754ac7d72adc3897e2c41f29bc42a124704c92725e30bc7044937127d24963712a3a2929a8442e22bc9d625924d8c4625518955ca5383447c24aa2bed158073893be9c9b8b4a6a3edb07970af3dde535c082d078f661e3eeec771f892a7c89c475d1e2d3d08f5f8eb61d543aa87411eee95c77615349bc7c523a687821e1e3decf410cee3fd75b7ab207afcec71d68fed4d21c73a7b1fcb800ced88ae215601f185c8a9718ca8e8fea2304402136852e773ef5cc6dc38154709d11ba8328f2ef69ba23cd8f38e0917f7fa4d3b17ab02d6d936067d42722c0d223844530d6951c4dbaf4996653eef3684b379659624809d510afd6d024c57b6b4c4f39aa96ab5c3f991a6838adcf05bd98c7e00db019324c72d133e925ecab8105380e606e7c17f6d8a48295206ef1a84518b7de68e2e209810874e1c2343320a40f1b4dbc21222d3592f062ed80ae8c9a5e8611c534ddf0bacc3d815371278144dc15602ca81bca77d12b599654bb48d3530dfa0894c2a0cec0a33f31ce4b295491e9a716dd2b44043f846b544cc29aa5b420353b830475b0ad4b1d921f2742b8475a9a468637eb2c9724e430dd83247386e389c7a2d01701a0b6127b160a955e938c289cf05c7b3e2973a37ce871adbbdce2e1ab2114a9165a43179437663c6b010db77abcc2786499a1254e337a76a58360c54210ac9fc503d6965dd62437cf0db39b438b5e38219f22413635d0cd2dad7ebb4f8f680eafc362daa48e534991ee59ff25e409cc2097a5bccfdbdd82d9a0af8053c796d80d2482e28b3e47db119aaf2e005942160600ade7379ecacbb61b786d23e501ce9966c9715392a9d0c443b8730c07e787bab84968c58414d7026386141914f631fdbf871078f5baf3e6d6c3d48e16f255407b8e434084640a7c4716e1215323c2666ff88b68b6bd9b11a482cec660cb8586519420036266ed50e4a46870e6a49be064bb1b2fe617a189964cc13a7b6f55350c9e47a48efd563925ba6b746bf34499f85b1ff15f89f6e9148fd39c4839b8f5635a0226184a7aa63ee8d26ee9b4522bf0612846a6fa71cf5a4e7e95cb70bb944e8f0a2083ceed422ca8bf291d12eadd76a283194730311534b83d63c31940547b61049726078751186f9f6808515936e46c375436d78272173d80a20eb96efe242572ba38394724d3b7affe1894e34c4a46804be6ae3a2ab85007f400f4d00ab092d0c802ee0f9f1936b154aa37814cfa7de1542c0e2e67328d7387b3b7615ac044b68e4871e358000f4eeb2736a2abbb01501f26812c729f5cfc034b281e89c10709c5000e29e3ac5c4e65a59f09e34a7257560d1493dc1669ed86e005e7c7c2eed258ffa9cca61f7ae1d1cdb600b5bdb86d501c78206f056b279093c4bf34f53a9f7b40f8065ac623c7389285355f30ae06b429715bbe542a81fb1db278e316c68bd5818da16cd9d2ef063ba5026008fe0acc34c156710c480da7fb0e34668e5876c504a10e8fb7c4e6f07238189ee2d273f5b785ef929d876f94422645f08290457f9b1233676e2b6d51c6525448b06c9988d009923c72398bf297d971300f41a14f2951fdb95a06c4961c8ada0df257e68371bd16c010e43fdc3789c5f671e770f36a86440c45758b44034ff1b16454adf482ba65c0f93c26af075296796c02ff744904ef533db4090cd329522b2053bc24489a4ce527f9c783c227482d9110368caf03081ed464811e98626af381b718793196e6a3439e036c48d52360bec0432f046263ca3e706345dd7c283151ac431b06a5d9bb21278077bb5be32ad756c55b166646b427c3b6a6adad3b7dd5225b3b9af5a103a7d6e99d328fa5b986427b6484f5c5b1a92390a2607ae0a540a68a1f5e8d9193a4fd969267aa04b919c53642753ffe937704d27d1237467a8bb68d66c881de86f74dab694b0cc64ca809fe4a20bb3b4433a4e6be4a3e31d41d3fcac39078512da528f71927d7dc0494c51c15a490fdb2b8eb667cf9e5898d82f57384295f5aa0d761a55f0915048f53ada6d1515c04f93a579fa1d761a47a3639708c398914f465a8e4c3061367ad1368a6cb4da48f46070460b041ff58eb43d232355da918aeb9cc26f9cab1ccee9352a83eafc84869b782abf711c145aff6ce44d10b77ec1ef51193420ced8dfc141387e2c201fda4046f30455b2ab0ddb4036c4541a4a690e27247c29e9e5bd67e90c1627d3e7302ada05801bc118252935b9d6fd729c58552b9d376586f1308bfcccef22092febbd8ed82b390135e3154ea3e7e0fae5fb6a088f70c5c0f2f1d711ed60598fb8e9f5bd388644d7b493591821bcda8165c9ca8d95185676b71ace0a438e9585b482291764a89f3a65e8d499d080b48c851b94e44a410f8d8c0407daa6485209474185cb1711ee3a1cf3ea0dfc4645478157512e0433e4256a180698ce52c6e88255648aff76ee29943c60257aed1187b9a5be03a71ad645440c5c22a8a4542ea834f2f1362820b55135788acba4ba50956084a7ef114a81f87eea84e022f79cb9e30175a4804c444969a55df25710177434ea8a4fb48337c90f0dd289c71f3d0f00214229f0e9a381ce1d38bdef8056cd6e2a67e19850308a02b5743f285e818c56861ea407b2313bf1e9cdf8ab7193622de702fa0e09ee882b84e3c2c085d42f326fc4c423f783fb2a93b223540823bdf4f3762589803485210cdc40243ca219683c6a0a372b6b32ad5fcc174375c931adb1a6d58574d697e45a66fb79181559c8b71f816a90eaad50be42f3f741fdc7057f5e9544c8b8e4d94acda85b543398d3038c13f3de1697219b3407b3519b8d266024ecbcca858d4c3d2788c22b0ddb80641b18ed807b5081df10982f55b10c4cc49ea976c3cff91c73449f665d5134702930e091782ff2f88d7e5ad6582a0d0492edc0f9c3a52f57c00fb20f08e607104f2d0b7b96e92f97211632e90998c85d0fe722d2adb6524728f97f6802c85ea002f3b884379fdf4f23f8dadf5c0582ddce2ef23de637d3bcf6fe6e7b6b495e266b758f847d9d83dd179e38705a9ab87fd8fefb850bb4038a460987e2e52746597357b121ba6ece14ad9c14dcc082aa3d8a5320ec01bca340dc06cd1269c3bbf151efff71bd48901bed4d84905f411f3baf9166d0ab7cd4fb7fd40b20f4cac7bdf161bda88f355d7706d8eb7d4ceff8b8f11a2fb87a852037dce3d5c5bb25d156d5c92020d886c6b87290b213a4308548b3ba0cf6de6190751fc72032ad26acdd500fc1a720eaa4a762a274048c70c3b8cc2c3ed7b7deeeeffd78ffca3dbeb3f8ab9ab7579653a85aac3ff87e421a62fb19b6d99adf42cf146c9967a0e52381cd40bc2d0b75b7098c37d644725581eb609e8cc5c044ec81dd044c49389bf0a85165ff8a24e593f4fff04477fc0c5bb2de8c423ea20969dfc5d95a4db48b8a18bdcb601bc2a6d66c0700d63790155d884e9b4fbad5242e16906233635d2d8d453fef428faffac90deeb00840d88de0dc270024710739a621fc6ac206054925b84a81d3e89f10961b21482f37482a0fe20d0842ef222aca9c29825469a7d5bdf6bff881e13124dc0c6e5402750450015da19672fcc76340c634d8037cccb65a58caedaf501b047c3c69b794a256b5857c0881648784ef3e1517033a6d15e33111774898956608481597398027af7cab65075a5ea87f8909b13ee98a0cf1a40c443a51fa3c0bdb119a11815c7ca9f7ef86f13a1c6fb4c8038c7961c2320aeeb4e758895cab3cddece684873ad1cba72cd9aa3a40283c117722a0d197dfc71833ba3b1bb164a52f4fc7a1266b8a840937a33eb338f33360d475859b1d0dfff8dc3f88190fc4a014cb31b55748203c6ab6fca35a1b1e64c1a3eb2217454abf630c48495fadcf049f13e3306f652bfd225de84581b01bbee778bec44af16e551a87014bf6a1037c61f558233492dd320cabd87ea73802b3237cc792d2e520fd46380fc17e089cab21a84e3aec1e561646071b01731ed38f298e59c784c6a4625ac65c1123505716eb5e22e8ce81d03a7019465d22849273208a9b5b722f77bd37353bb48349da92b91bae90a610fa435d58f7b4ada1e16909c43de3fc97e094c3de8843355c5c101c60a0767679c823b7d6b3b7bde87ac1f262c0196de7c755e705b049e05096ca9a6cdeb141029844fe645fe976a0553c32ece269c82370576322f4ab1d4d8858dcdbef59f6e2ec0370d2ba9f39b8ae1e30766c2cae199eefd86c44759c75f43a2eeafc5fa4092f909c967278f689a8384cf8b0dd3e040fe03c2598811955d1301ebf2c6985e70ed978b83e131afa13c6af2b5cc25ec6e97733292be305b9a537430c2a6ccffcee4904c813933dfa228373af89f71aa0d6d216dc6d2ffff748a2bc0c527ddf106149a52584fbf05a780b8f179782300377280716d916ac67813ac52964e22bf1f453b7595487f3fc078e24c4f35cfac6c27ad708ccdab1bf84a8969bcb8243482399106f3b0a3d280e4187136b8e65811cf974eb94ab2fcd433aac47ddcb36e61d4c0f79f2cf17269290f1f3159e2f75b1f0dee813eca4021e89848e0b3660b46439330f0f0f0f0f0f0f0f8f3121b5b54f48424a524a4aabd75247e420a524a54c2989b7483b7a3a33f129a6c9de6498f8040402c20bc70b970ba529194ac5532a28a5c7a80127ee5f214f5a8e783a3168c07a4a297878ca32d5b663164c8ed729a9f85bf27ae3396c6c60c60ccf614305336698a143166c66448d9d4468e4d7c4823fedaff9a34760c189ee1077731c9d745baf489ecac9cdb74757703a42ca15730a19947dad605f82662425ace3dbc70acecdc3d44790ef216dabe0934a4a664a4e1e3cffaae0a444492b62a954b09a76a742aca8bd6799252a785bcb1d59a994498c769c82ffa484d211377595af29f83af9a33f9b8f1252540a6ee2a65df797284953527016f4925c3f4fdb3419052f2612c54f6645c1f9c5dc94dbaf34e8e0e1e80805abab13420e25bede9b147480824d136356ebd99fe0d4fd57f637992df6da800b68514ed0e1095ebb2477ddc43bc1c41c925f98162dbe419c603d922e696b494d66cf2698e469a1e67e5737d2046fcaf467d7f6c7c8e94c70494fd9e40ea57dbfc504aba5c77b83ada714d24b30392c55292d1ef27f8a25f8ad0c169e1daa76639560547559b885790a756180c60942072598bc41529c1c3ad4e23e6346c724b8b5f8e31b31eb3eac1a6934eaa6d021094ef848c8e1679d69523f414f60c60c2f3a22c1d786082a9a6b4ec999ea80049783526d2288fe11bc8ed021c7ecd31bb2c8118cd60ccbef49d4434f7e8398024e021d8de034e4dff43da943ca0d6211e86004abc12b8bcceb9e47c72c82efec5082418722d8efec7927294b29c9b023119cea94dd4bc6122ef22e0e175d74d1ef051765800e44f01526d3c4cfd095cf6c41c721ceebcba2eb4e372ae83004fb1ad2b43f3c2479ea1bdc51082e67e57491a5ec20042ba23db5ad8e490a5dc0050e1a9e6c98391737726cc720f00b49a530e5a2a26e0c3a04c1994ab595f54d67aadf11085627e5b2720b992de21d8060628d797b55a9945448c71f38a1ffa305b788ada1593fb06fb62629546366d3fbc05fafb7794bb0ccb4f9c07e8c6cb2d4b4072eaa78aa4efa3cbd5c3d30da79a2e7f4f595369a072ebf267597206944060f5c063d12ef2f596a767760b4268d3177ec16f5abc30e33e8a8c349765042c7545a0ac90e3af03958c88a215f4ea2b21d73b0191d72603fc9d131258fef9713904003a0868e38701b2c8d5c1711b225b57ff1451b1278c1c50d0a748e66c0052420811933686400ced00107f672f2159d624cea94ae60a1e30d8caba958a752c8775d631b3adcc0d7c7e049d3db36f023838aa0a116717b3674b081754b225685a05e035b6eaf6ea2a63ffda506d663cea1be7e3f8f9b062684a42fee6890adf92fde810636e7e5a4824cb3b45981a0e30cecae8ae6bd3bbfb69c02860e337071623ecd1c3aa59c45eb858e32707f994d591695e4c46fd0485e943b420719b84b4dc143b2181c5c181f748c814d31668b90f24bed88e4b0a182d221063ef2fa8dd96ec4be48018d30b041481229e4244fe434707071050c5c98fa4d41a62b499e44838e2fb09147d4d94775f111aa91c44a0076d0e10526ad28d15841684613e902a7b5b784a4bb50a1830b8cb6eefc93906369e8d802a74bea5f67ffeef4592d30aafbb3d783e7deb4d0d09105ce72d04188125a648c3916b811faaf6a21bd4d4cf10aec5a0c1dc945a9521347d46105365db2fe0ec2bf62765805f6ddf4e7385eeb163aa8c0bf7d324b093a22f7d33105c6826e0da9e33987d0b09156061d52e0af920ceaed453fa64a0abe880257a36e528aa8a3aff324b0fb4107143ccf5fb5fa136dd0501e743c81f7495a993a7a9ac72cdde81518740263df1aa4c5b1bca63d4d60438f6bf64d4a3d05bf461adea083099c1cfba469540c9a7a61435b80bca0000ae00e1d4b6092d6e49a827e97b549097cad779654913faba808858e24702ad47b2d54590ee16f193a90c0e71044c8bdb1f65dcd11b864392d57cc15b91742860e23f0b529c4226e4811f8c937713787e7583a18860e2270c94a9d48d14e770c818d1fb1b5e4256971371a2dd00f740881fb4fc24e488aa03cfb0e7404815359a966f235d79368aed001045e34770a399ba44e3a2b56e8f80117fc3d04b52153238d469d0e3a7cc076a4944a074fdd7b658db416acf5800d21966bcc53513dc303fe92f6ca1b32d4b10326e6a6354f162fa7d420a043077c090922ea256f8624e580af983daee4b30bcf260eb8bca8a34fc449bd7f75dc805352d3fe7609ad4ad7068c52e33b4144936be91b1d35e03c09fd697f6b9dc65423cd4632d322030ec841070d18b7affeffb190aacf8213622a88adbe27adb194051bb7bf2bc62ad3696e0660c4824d69539e64ab1efd9297b0e0bdd7df630c39e60418afe043bcb451ff25e84b2379d1e45cc16669ab6822061932556d048c56f0371e36415465d18c16197080b10183158c655325a3dadd5b560b2360ac821dbd92ae2fa7a42a7acf8dee95ed2e239b0418a96054a4c9c9f2078931a660a082d5089e9d95a2ed22458b2db4d8420bf30818a7e093d2eb2d49957809cd14bc4f4e5bfae40499925a0abe45e69d2521318690cad17e72dc80410a368b7efd90745809114f41c01805ebd9eb7df1828aba9fc11005fbaf41dfeb4b67356d8d2c2c1a80110a2ec4fbced39b2b928ae2e8030c50f0ad31c7d4aaaf9553e4e200e3137caea67753be9a2fe8a400c31368cf76b24dda453db5000010303a91a7eeed0ac13c5e3f80c109f6433669e5c1e2a9bce826b86c3a98ca21f754a4cf8dbe40299a6033fe691f9591f2f51f061899e0da6fbf52abe4fbab6082d3bfa395426b525a62b904ef19724c97a24e12ffa025f810b47defc40ede2eaa042754c794bc36e9a98a53820932fe645162b973266b128cf726a96ff142352b0926ae7ebeedbcf4b596014624f85361a75b7df6714220c1a5b6f4a4b324791e458f60f3ed72cc19b9bf73c411e40fc1bd73f746b0a63ba3a6902445513a23d82a4b5dea679d37ca4570327da9a4529922d8a094f64f113dc97037115c5e6f48c132e76bf8886025e62b7dd63985db7b08ae93e98ca9534ba5983704db9382f9067d39f7ad8560ef93daf2b28d105c3013135372b389b006c187875022b778cafb7bc31004bf195ff3dd0895589a0ec0080497f306cf3c75a1f29a040b3000c1e48ea5cc2649f78ca32bc0f803fb9927e9896b69681f0330fcc06898876c17327ddabc0f9ca5b6564ca67225e52f1060f0810b9195d734e7db905335d26ca4f4018c3df0b962e6deca9962d10327a964f2daf423b7926aa4a5d4346c24d30318796062aac98a936e6cadad9176c34990bc0bd4010c3cd89ff95fb91e52793968b4e0468e25598071076e82d4d518d592aeb809fa0476605c84ceb7119279bc8fe100461dd8d2a419aa555474a7d448ab1bc0a0032b1a24a49cb2eaea8e36ca66ccc0d145172968c0161478038c39f071640ae197b264f2a01a69280032c090c3b61be32565eabb730088028c3870494d44dfa4a275f90b07f6b3a62447ff7f48ad1a09da8b968041018801c61bb8f83d312ff807bd34ddb08132100b186ee0b754a760992f681c2260b481d32f4fb596db647c370301830de5a997875f673c598db4b741e3d0c05803a7329e92372a4e022fb830247f80a1063ec4cfb94d6ee6268ba681ab89f599a496d22112c3051868e0feb285b28d24e35ab600e30c9c45aad211a692d000c30c8cfd071962d41ad174712307a2d18243a30cfc7b99672b4d3949ca910c30c8c0e6fb243379cebf51df301b03373ad2bd2e26494a4462e044040f7d15d1a46a65038c30f09541c8b6104769a81b0c7c753279426e48a9319906185f60fb5fbc62975a47fc6b24046078e11113c9fef9ffaa3287d105b6d428d51f5754d0ae6aa4599a4ee003341200830b8c48d7a98269ee18ca13dcb8a10005cc98817c035d74d127c0c08c195be03d87de9e28e1e96987a105f64cc7d041ec3e30c0c802e721079545971a4d8f1d16d81c796326216f185740e74c1db28bfd56e02a66f68a0ec96973ea0930aac06bce6221a6f206993354e0aa468b0aadf89a9d62028c297039a4d32a414bff27111a0f6048814b49640ed31b31e8e93900230a9c087a2fc4d39ca43d9f000c28f06a6a44ccc94d5d502a3304184fe02ba69096f49350e67921c070022342321d794253232d078c2630f9c72af37ba8a568aca1000613187915d4af36a95cf5daf8c2d1043096c08e96fa9873df35d26ac050029faf3fad093d31a5bbd448c3190148f068059bf52d66ef901923bf1eace06aaf764210b9c72a188f9ff4c5948c9a6378e0a10ac62a77084a4491f719d3399a0137f04805e321b2c6b0efaed31954b06dea962789a6b47c993123070e270117094fc16a8af92586a89a6448c1c0c3144cce7275f3a8ae79548f52f06ada31a4d51f7539b413f8000d16789082bffd0e3dd31e09ccf01805eb39da26ed639d5b4913f8008d2f3c44c1a68bf729df42279d6a90808b1b34be7037c1bd4728f8ecde762a4ba06072e61a75f22d9fe0f45bea88dc9954d248199e073c3cc165ab77d027833c61f94eb0773a832cab0921c939c1b8baa88852f24df0b9e2080daa214df0216c7754b724ef0c658293a63ab2a6ce23f53e98e04ab9e48b1ad44ab29c4bb02151c342ecd38b765b82c9a92a497ecaa2c6dd4a30394d7e68087aeddba504374a2d26097253fc5d27c17f8dd08ea0a5e67f4a82cfa8adf7613196dc4d24b88ffeff9699ef7e3190e0e4782c31cf1174102a8f60d7f3a71ba5c4930c298e6035d46628651db61d6c04971db7da649fe7df8e119c4a4149b3d32f82ff68317ca32711324811dc774e7921672d119c8e57e90c4ac8eab210c1a9a484d4f862a534bc1a695e3c0dcfd13772e038880bf03804aba1f7c1c79432dd202f52d080b3f430041b736f8e9c4699f6da0bc1e656cb1d25d64ab6122118f91d6f7d62e6cfb11e04eb112be9d19f20b80c49738f504b1de225106c929982b0af511b6904045f7921f7e9789327e80f8c6adb68c7eab7d1cec30fbc67045922aa059dd85d7af4e13cf8e0b1079b31060f3d9c7aa33fa5e47469c005b420c7068f3c9c071e583d3df244526d2a6f907fe1450abe01382640812db4d8a2015a64200236328064021fa021804a78dc81bf0d6e5b25a2259196871dd8fdd7f50e0f41e3df1e7560cb5377ba9c3f5552e2c276e0410746e926d55deabf23a95c0088e03107ded42c4ecc7d3284ea75f09003ab6a31d364c7a0db937160d399507949b5396c64408b2de0c05bcee94ba998ea2f21273cdec0e7ce23fc94d64d88f90624e1e1063eb5e670ef5c9a438ab581bd931f6a4c4653a173b4d8821cc2830d5c9a103fe4f4e59f7d6468f0580397b32521c57cf2070f35b0d92e53f576877c927273f048039323270d41b99fb7bf72f04003939406952f23581eef68b4c1e30cbc66cb6baa63c94b9d3703139210adf71d595a82cac0ae07e193840613912032f09d95425afd6360f2e4cd21aae7564c550c9c309df933b7835fb084810bb5b2d21002031b9a2f495745be53ff17d8531aa4b5e6eceb96e405ee5255b6d6dcd0340f011e5de0367b68470f1616e20227d2eddc37d85b6074eedc9c72b25a60ec46d5e999ba9c72cd0223ccf46de5a6e9742616f80f5a91b3d66fced75c811f11f57e5267d660b202a355edfd29248f6d972a7059416d95ec8c1a3c4205ced6f2b628d3794c810f3993f6bc9162324f57800a1e52e04b480b3d5513a4f5ed110576f3e514c735a45d4e99c0030a7c861063984930eb9026e4c2e3099c9b4e22688eceaafa3b81dba429a7984a9dab83155080210ef36802579b635df44d954ce916e1c1043ea46c9aa563e6b10446dfaaa6bf4a15aca246f050023b4282dede5df90725d982471258f7fe2816af3ddd5624703bdea7bfedf4678c68c1e3089cd064fb7d2d2286c9088c29c91a52d4eb0a1e45e0236e6886c7495a821c041e4460834c49176c73fe7beb31044ea60a91738a71250979088111312747b5adcc23084c122aa44cf22a0f20f02121c7b6cf4954f7a6465a0b6ee45063c3e307ec7dda34fe39a66e30053ee0dd83728baf21dd644b8db413a4007909bce0225be0d1035e350615834e212c49be465a5981070f98aca24b34da6ae51e3be07a5dff4ab958238d460b6ee428393c74c0bd8f10aab27257ea9f032e5db598a794e57a4133669475c10307bcc6fe2e3d6ec07e5433559bf2353da7461a0d1b393c6cc0267d6f955c9e46b68b9c056e47c3a306dc45ec51a5ac2d66b088c08306fcf7a6a74ee9e324b8d135d02c181d3529ffa859324991460e1c292841eaca400c59b0f9a2b3a59be853da353162c1c64cd66964ff38a41003169c46ba9c41ad826e88f10a2627156a375fd4158cf4aaec20820ac973e7857371a3015a6cd182193368588c56c46005e36b1152455256a95b05d7d93dfb3e6570f71055704aa64bb13685f869cc18a960c7dc3666f7a9fd9ca382dd08c94e6737113b055f6661f984c590738818c314b9aa55e52c8dd1d42ca34ed618d26dd6766aa499c0868d1a34ba485cdce1214629b8bebc3751ea79498514c4f4be979a6246c19b50eaf52b8735d2708b1a39b8e0008e2eba5080165b68a1c5165a68b1851618d0220311d0824999ab808b220a46a407b5cba6a2878c8682cf2721265332573140c1e51845e5ec4d9a945e7d88f10946342519ef3bd4b37ec4137c0ac9b736d6a89887189de064ce75fa3ce48f5613ac430c4eb07e9e3668d9654e21493818b07088b1093ed3636a11a62e52e50a1b626882d7789692a9a568b14506228003c71a62648295e456ee27caf276d4628b2e1a139caa84549a218f5ec9b900a315625c828d25d4a5b78cf55a1e4b1435a9d363414670e4701c38ba125cb692b13b6f55de2053236d8d023128c176fab84954526692a449b0976152d46411de16920497432af9313b4511033122c1a9bb2074eea0b682ed376cd0b03b400c4870d952ac8b56e3997edc0208311ec1a70f96a643e893f96b4770324cae5725a9d9444412a3114c6c537aad47a6f4d931825127db2f4af61c82ed050d37bb8bb10836e91c159328fd0e221e85188a60cc738a693fe2798960f74d88a4d01ef48b880836289d79b2e8e468216bc1a1c145dd03ee109c8a95b7c4daab9166086e4da84ea9757c73eac210a310dca53549323b48fa3d1182f114abb64f445cd42fc41804af6bde71b437444e108c972a59225e786bcc6ba4adc0861781e0be53d49ecaa2e91ebf91022fc40004bb9e556ff1b56bf207fec2bbd2c8bdb30c215088e1074e864ed0aa8c90009f10a30f5caab547d172ad97748d5c420c3e303a6811e11b74759a7a0facb85568868c9ea3c50fc4d003a3217bd6504d4b22796083f0902e3f2fe95c1762e081dfd35c53c29412ca3bf09691ded36f8e88fad8e18b22aa73fdf31a69756077e455363b9d0e5c5fd4117aae29a84cb939f0f6197244cfb9dc532907ee2a6dc516370b1762c48133f5a733f7a4706064ceafb42b421be30ddcc4cefe65b981bbe0be9e326d884fbe0d7c1c25b24ab610830d7cee0a524f6de7b57e6aa4ad81fffbecff4ce376e5500397634bae1d93c68d1b9e062e9d4efa13cfa0611349f7ca83e40c7c9410724e976fd4c5941a696660e4e94b2252ccad0c6cbcbe9c734ceb924a9aa3b9487e821b9ea39c200619585189227d6d53236d0c671e59694a2d0656638ab9c9ae114134b00431c2c089b098f64352cc3e18f88f16169479ab4d8e91408c2f302aef87d2ccb92d6e9404de8517f80aa9dee3b9f1235d606c94e609e5f5e29ae4029b73cd6d4cd828114f13630bdca9f10c95a216626881510b651d923784329d2cb0164310125c628658e0748a3997a8a0235ffd735760b29fda6ef2743926252b701f2aed2c998a355e57818da59134354becd1392a303a07d3f9da3b2429b11a6953e0c2c7ff3a6a6ecaa954234d0a9c950c49a7ccbc4446a2c0059d114385b4af13d51a696b218801052ed365ccb81e47984fe0b2b86aba31218244538e14d810410c27703a66a769319926b0a33d3f54d289099c6b6b277dea2cc325303176895e9126253022b609ed96df22799e04fe235b4e503b2652be91c0a5da65151162e63ca523f0f6499d5263954da79206621881cd74559335bc7b3f5223cdb010a3086c5ace7fb7691a3452fb8d3b33821844e04352a9e933aa246b085c4a7731e9979043525c084cfed1e29152a74d9fad915670e4c061e30c023182c06afddff5be8554c2d222030ec84004baf8e2040f68c08c19ef89860abc701578c176851840e02387b5c6d5fed1efb161e302c609317ec0a59b6c95b4e9bc9bef183ee0eabff7278d27460f38d339692d57a8a044bb80183ce04d73e59113a4694b290d2b7a88b103463d3b2fc92b0fbb910ef84c32e68831b988a63a07fc6bce5477fb49e4d662e080338f9c5493f73760e409adced33f1862d880039c08cf9b25e97bec3e158cecf15477f5a5af4605233f6ad67442648af6145c060dd994b6ce501353b01edbc264d2e9631d96825196ddad4a65fff6470a3e68d2ae4e3712832419551b05ef31d7c79052ca8f1aab91562307172b30d645a30c5170a9628c1d42893a335d8db44caa38b6033242c1574a224529710d3223a0e03ca449572363b02ffd27f810ddd5d77c927d9072514c8b0c38c0bbf8220519b8fb820c4fb0994b748a87529f773a199d6092f0fba821d489dcd5066470821beda5bdffe287fd65a12063138cfab497fd2fc752d76568824d21fd6eb5780e299a8c4cb041bbc44bb2490626f8bf20e4e4d23b694bc4041997e0fc3b8752d7cfb5ce58a212ec45d7915ae973ccdfcba0047b27c4d742f2c89804fbaa27d126e73224c17f8dbd28cfcf2163908c48305a2a5f8f4e823e2a03125cacf348224ddc2ec87804bb7efb5927e9e4b9ef0826fa9b66cbbe89a7f346706bd9e79a274670275f456d1cb9d79d5d04f717ab4aa915c16529a5cc3b79ca5ad944f049e93a11dbdc537244f05555715b63a52c113d04679f4fd4784ac92b260dc19e7a89ff1d3b3db68560624413797dc44ea247083e272539550461f69a41702129e5a9b7b1bf4e10bc650a2a684fd5039c2023105c7894689faaad363f37640082af3e15f33af687468e147c91e60f6cd75a249d5367b3f2981fb8cc1941c4d5f4411fa5566b5bf36b5c1c4f34bef01b5fe05824c8e0039f2b55ae05197b40aded84f25e53da480603197a60edc5f4b49d87a4cf3379487b9bb4ef3c92aea3810c3c305a53e4a9ac216e6db0469a17ed5d2075818c3bf096d3856429febb586d59906107f66a74529d3585a424c70b1975e03ce4f3b428f21a8932e8c0765f2a33515a3f9ad648f3c2067216b8c998039719d6d9e46a726074f342551c292a6e70780964c48153aa72678e1fd93c66ec0a32e0c09a0875a5335310163926e374c173bdafe3062e89147c9372977c226d603de22515c911e375cf062ec8f83942eef1d0a0b30626f88e760941d6e566d5c09d4649232ff4594cc934f05d2aa297ba0822f468e05cd2441749f2abd233b0e9af36f456e4aa57ccc0e7a9feab495f414e481978d33962b628f53e3224039b33e62c495a8b0ce518380d316ed5e8ee754a254186183820230cec6d8b16111fa920030c9cd20d79a695a1fd5f20c8f80217f2b95712ea933686d0f0027b1a3e3182b264e0ae0b8c12215510dae45c60359dc817af94b6c0e8a79c1bb5d4f77aa405de5cdb74446ada484159e0765fc732af57e70e6181bbfb492b5a934e10cf15d8d4ea262ae5ea50aab502174be68d21a8282ae25a054e0615d5be4f757fe7cc9821830a7ca84fc1c44598104a3a05b65b35f6a4cea14d4c2970e3253b8ddb8b484a13053642b45819dc4424cb4081dfcc1e2a8ebb2425234fb82f67ee04eead83762a4fd9bc824d6024e75869344529e5392694efb3658d29a42c81db10aa4fb608b5053294c0d6ededa72f51d1b93256909104fe5350a1a35208a9420709ac67b869485abaceeb2338d691d35ea669047ed4ffc9319d9c31e32c0e328ac0b85f36ddd490085c7f705bdfdd5279913104fee45e0e35bdb0b31b0d3284c069845c55d922230849ad749dec723287175c68e0466f607b200308ecc4aca53f758a3925f90363704b63e6dd1753b620c30736c368c8e841c9e0017bf162d555b56ffea406942063079c576b281d7453788f3366b4e0460e2f3c083274c06a66cc3984a0e1a6fa1164e4a0dc7e3175ff8e051938b0b345634e704d31fb1b6c29659b670649deaeb962c84f8b20c49b820c1bf09ab531638990242765041935e0b209194b8aa56c70c181e43366e0281cc8a001972a7808edaca79de41fb3e084243522869cee8490f990056b23729b50e1971c7cc482512958127d13359b5748830f58a0ef6a820aaa57d493b49a3ccb1e4d57b062a7720a3ab5db0a45957a48c242061964057b3a66cc1fdfa4986a6f7cc102fec286aee224355228212fbeaf0a540a75de49fb099954e03f298f28212accb415c93ae8ebd66e9080d8ad59093e4ec1a78ed0a31282d0112153707b766934c54e29188f144b7e1c99b4a73429b80dcb2958688ba697320a46e9fc60f92a9ed3591fa2e094c79f9433fb72d3130a56744e4a59e6a0d1e20414dc79a83e0fda8f4f1462b28db1fcdbdaac91863a840f4fdcd9ad734d35937a1df8e8c47d7082ed3ed11925d5fbbbffb10956c5f24788e62e2ab626d89cda749490d68f4cf031a78da619417aeeeb295070021fa021801b7c6082d3a172723b9d3ab1342e6ed820c11962fab804671da3c6eca492363dd6489b3163c68c0e68b1851612c08002dc1b90fc4af161092e5432f5ddd6a07f3c3492175cbcb1c0d3096cdc6840f2828b06ac81e2a3124c3aaf9843997f8e9bfda0046ff6edfaabd19304f524f8714dfde9dd2aa693241811c5837787de3d8f44824d31b9566ae7cfbaf003126c2ea5520ee54978883e8271cf9e2cd3bf594efa8723b832fff8fed9f4d108f6745a8d765c8b91941f8ce07227b73f09f93a7ef063119c8668ca4c89a24ead0f45b031f55b5626a5f9d6fc48041b64c829e59cb4acaf43b6f0810846e555d08fa1ea53c80fc16e4e272187e8c3106cade68e8a26f4c4d41f85e0b3a6ca9244559b90dd072158cd49f976f613fa921f8360b527dae9d54b3db9fa1004db16d4494c8baffdf98f40f0e1c9e4269deb0720186dadbd1d524c117ddb2f3efec0a80d322c5e103d513f303e29650e1d7699bcac83c1471fb8b8d7975797e927311a7ea38fe10337d69de4988a8468e11e78afa0df752ff8a107ae23951069554bfde9e0f8c8036f1f2b92f094f4c64e1b5d9032047ce081efca6b394dcfc23bfd710756cb4d6f527f69418ee6c30e5c52634adde8e8764ca903636d52cf723a912fda0f3af0312499f39afe1f7360443a2d3f21ed36c6fc871cf8afa064b2ace79dcef2110776829d483929992a09990f38302a26a1e3e8c9b13ac67cbc8151dd793ae712a279ff0f37f021ae96c689e2973c79818f36b062ff914c722af92967cb123ed8c0fe27fd1b542acb7c9f123ed6c0c9d8a984d20c491c5cac171f6ae0fa4d997e0abdcf7da6c166d4f840032f9a9521585ac82dffe30cdcc99824050fd10f33701e296f44cdf6471958eda02455068f9653f0830caca4d8c9d5c61f037e8881099af268efcd787dfb4718d89c967b9f2fb5ed8a3ec0c0e7a0524a8a9b4654ce7d7c81cfec761df32e5161faf0026feafea22eb21f5d60cc3f075315838841eb35d2f04a0d3eb890a6a45649e70d8eae912ff8d802efef9a4ce87e2c65f91a6938b8282df8d00267e95e35d384605b1678ddcb11fa29c898597917366ed0c002ab959b4b42eeed3ca181830bc2828f2b7039989652d32935d2f0c30a8cb0cbfadb552724c96ba4e1e81af751052e26f389969ade23bd393ea8c0a99c838be7f4a9c24a16828f295c7d4881539ffe63786f28f01105c6b5cefb92e9943bfe8002e7aba669924ccbf59c65c2c713780972926f50c92685c8096ca520d4468914dc6296081f4de0ececedcc474a0e8f0be183097ce50b3afd268b153f3880f0b1044e54b99907e996dbb4317c288153f25ce28d6b08258307868f24f01394298d6216eb24db850f24704974344fc1f25d2afbe3089c9d7b56a8a7f248b9113849933798e5ca471118a51db47eae8e296e0c143e88c0462e2d42771aad1ffd6bc2c7103895835d8ed61b5397324008fcf7557592a3a2dc844a193e82c0e8ed52f23d8af85b3a0c1f40606f54cec1e266d3d3e7fd80310f26477f1041552f1f70935f538af8d9470f88de1953cd552cab32b6c7f01c644a2aad91f67ee3cee40a3e78c0beb678a50ea6c55fb4032e551295830c2a4a2cb50ed8108fa2b565c9d19e02143803906f60c68c1933707861e32307bc85a45719f69124c4940b1f386063d6179d379fcc6a9d0ca4143e6ec0fa96fe98a23fb796f861035ea4a80fe22afaa8011f16aae3ba994c42947af8a0011b928520ae51fc63d299055fe7aa5e2a043bb1943b78c88211a637c87a3b8b6beaf400128b42a98d31e8178f153c60c177e8535afe1921063d7905a752b44eca21befe8ece156c0e52fbce621c25540c034660b246ea4d3ddfd6eb8bc0d9e438923de514ab9e08dc55bceb9359a6213f04467b7fc8dcf974d0bb10124a973e08bcd65f32ede974aa4060358a12aad631acfc01db5bd9da366cb3877cc0dd081935633c1573ba075c44d752625a76223c60bbdb2bfba885d276c0be08116c475d94d4ea8037e91fff4348b12d25079c1275e341e898f7c5019baafdb5d2ed4e94dc80094a8688faa7367fd006fc8e8b0879a38abed48051a35bd9399632b402d080514987fc591b29f7b3e072c71169b34f845616acd768659094c782334d4987da0e0bde4d4f92a04fc96bd32bd8db20fb3a23858b5cc1c65115720e21d3d256306e4944922521c81c6205ff12ad5acf4c4d735661b2e0aaa9fe2655f09e7f6df487a454b0112fa994dd3c882c49a86054cc1e32675db749d22998ece1a7b326b72c319982f5b8a9a28fe54bafa352302a640549dbe2dd3a22053fcaf49b0a32e42073340aced33f9b3ca5ee4b098982b3e0b14a864877a38442c149d09031e974b92642a0e0c736c5fc63a15f1ff409eed426a6679ac674234f70597db5bcfb62451a3bc185a8ee649ba29e082758f3ee64ff7b3a68bd092ee55431b5e8e4f94d4db019fdd3645e6a4f4d2638f59758ba2ca9fd10136c0e6e962aa86a3ad9253879273f830a5132a7902538b7aae41f9a45f44ab09f16646fc85322bd9634b7ae3e097ee3faebe9cffb133f9260527e3a2d6a234acc23c175d61c2dcfb4165a487015761f43c8a052c4a047f0174476915b11a3ba8e6037e6760d2286598c368293f43ee249533a9711ac9e5a456c11a96d2e82ff4a4205957e2ad75404a74ac6dd74ffa85f2682913104d1a33aa2990c22f8daa04ee792f9c6c2738833ea7bc7102891b1f772af5308c6ef53e9484944ca09c1760c4aa8d1f126c02018a55df42475775abd092008cee4673a61fe23e4a809100836bf490d299dd4baa0260020b83eef0d162d2c784e13e00f9c68eec578e9cb33dd04f00313f226dfa46356fa7a1d40803e70fdaae555793d8a960f7ca89c83c8a7ddbfee1ed8533a2664ff27c9ab1e182b8d225cbf4d4c9a07269e59b020647b87140f8c502a478a3596fdd33bb0218ae6ffdcf4aba71df87fdb10849e75607469124ae7ad9c7d3af0a92798a64f4977690e5cd0294ab6502b21c6c8811bdb507a648d3e691cf851b5a3e3a83c2584032333d3a95fe40d6c599239ed836ee054ccf27b450c53b10d8c46cfa4bb535e8e1f1bf8f4c9a37e1b9244afd7c0ad5e4e509e1af8b48dbdbb9252779706ae425c2de88b896b8d06fef365c59c381e72aacfc086dc78d994a87863b51958fd98eb4fbf5344be0c9c9b4e4fe6fd92813753e331df6fde7d770c8ce7a9241649589eec8a81c99fe65a22dd30f07e2295debed62475c1c07632f97f7fba5d93fb052e6e9eaea02c45af5c2f70be25bf53ba0ddd97ed026fa6f7d2225ab0bb2c17b8b4e69daa73251d25bb0526b59b97855467fead16b8cccc9723699294b4cd02af31fa885930192fb558e073e8eb9ca87fbafd15b8ac29079dc5ad2e7b2b30229e43b036e9fdf12af0df1dec6490ac224a546033849482f9a46c6a4a3d8d9b72ab921478d39bb3461b09ea465160db4fd53ed8a649395060b37c54f0c8392ba69fc089144aec4bc809ecba68f8abfdff649bc09d90e857f1e4df4799c0a88adfbde5934a2f4be0fc42e5de88d257224a606cd773b0d34147962481cb4f2aa2aa4dc5844860f4a5dff020fcb67447e0f45a963693a4533d3502e7172632fb7cb3e6b4084cd0542d2aaffba54d89f07b4abca0623f0436598aa2eb34a488bb10b8917ac1f4aa53043d089c85a85dc27320b0eb5b17cd6bb3b9e807ecaaa94b0cdeff29f201df22a3c9c8d9267fa807bc5e92d57f5726f38707ac8a4e9a4209ff08393be0f488a42dd557c8bf75c004616aa7195295da39e0324b1635ca2cb969098003d6c6a4e8e9ec66eb12e0066c90b4b6b6173b882c016cc056b0983ea5a8854509500376cc2f5945ca909f24000df824c382e6537b92ca59709ddfa53b424a7e1759b076a6b641c60c522bb160537373b5a5dab44ac28271ef60b28469935992af602bfa75bafd75c82d5dc19767325532877c3995ade064a41cfa3cd5534a252bd82832e56e92af828ff77f27732d784852056726fdad3e948e3f4a05639bf756648aa71ea182cde5162258c58b203a059f47f209a5644a326f53b057693de7c71cdee952b041e5181e942865272505ab19644753fb9c951c05ab9e7b629be40e188028f813e969292d9a90985070f9b369b3112aba33a0605df3080de9ad82b27c820d9ea2acbcc4ed2a9ee044e3998a1576824ba52767df585fae71823b4def29a538b6fb26386df17b4f838d95ca6882179d420a3287ce142d93894e49ddf7cd31c18810fd4bfee8a5892ec14634f330f75882d5887942eeb7128c58048fda796b2f4b09d64b42889663b77b26c1f6ada5e7ae24f5488251da368904275cafa4e45ff59c16487035bad56b928f607f37a7183db9a4be388213b2bbc472d48c498de0f2ef5a2df3525c0923389d2ac4f4b499b4bd4570a579d3798cd1f46e8ae0bf2fc6cfd024a94f04134f5d4cc92cf305218249e199cba2e6113987e0437f4fcadbcf905531047f52624816c5358d5e08c69274fdcf55999a44083e95a70f593364af67105ce6da82e0b296ce9cd492403021e8da8b360920d820f9435dfa482195e40fac961a651994702d11e2076e74aa3269e5153b47fac08a12cacf54be897d113e70faea6a748708d1f13d70da293394e4e49a263d70d9572b4d06397ea53cf0ba397a7b42dea04a78e0255be5a6e5fd7fe80e4c7c5f4d13f3b8396407fef692a759882d1eaa03ab55c2237be8c046fdfb1c648890b4670e5cfaece6e37127e7550e5c921d446853d58b6b1cb8c929489cb89722513870912708cd19a2e4ade01bf894e9bfb265ee0626a8a50b12b462d0126c03972a752911dcad830ed9c0af7f3c0f31e5f59ce11ab8ec987b29c343c8ba1a38fdb739bf47358ba932810fd020c100d2c09659ba9037d9b77fd0c0a88c1c84ec4dc163e70c6cbacba944e47676d70c4cfcfc94acc192d4b60c5cbccdf849cc92a62819d8bdec185449ddbb730c6c4a691e1273c8184d31704a2b881034ab4ac78481ddea949426ffd5b380810b1e3d8bc48e6842f805be4b822a617b810d6d3a5a43e78917ec029bd449cd1e6348ae8f0b6cc564a62fb40546a50b6943c94f0b40184016d858395c6428a1165387055eaf45555cd7d45777052697c7ee4f1983bb6f0546a89b8a14325ee8be0a5c341d4beaca2df26e546034d9d88754973aee53e0b54308b9a69b774752e03c6ccbe2e6f5e09e28f0d1ca74a6fa483a7aa0603372004fe0b3ed56d079438a41ea047e937abcba4e96f45e9ac04f2e254547caa55e6502e7d9efd746dbac93b6047e4350358f9272168b2981c9196a2f51f34a12b124dc5929a8a44c6848602c990613f61ad2373b029fafd6f92a42cc296404f63b6e124ae494497e8ac05f87b2e021a6a63d4418c0106c86090620044647b030192369d6741058fb1e151d2d6e9206022f4a74fc983b6e08fb078c48e2f53d9a6f93d6075cfe911ab3d268d5b607bc9a0c5db595079caa0afe41f6968cef809131bcdd2c7e854cea80ed986e25541c5d269303de2f8ffe18623a6d161cb039fde37a5ad0a32637e0f7b73f834a9d43fa6cc0c9f7cd394ac6b425ab01b79b7a5574a6d8e901d08011ebb4ff2131df320b269d5abf0c9a6a4177a11690210b26554822a5309142751f0bb6ededaa72c5b0711d169cdf7755f06841a8ca79057ba2927e4ac2e30a3e7de6f2fe2b916de956b063aa6962bcb4b7cab082f532939e2d5d7bcaaf82932cc1335a44ffdb8a2a028daea8b4b065e2481c0e0643c150300c86e193d305f31308001838268e4582c188a0c9c27c140005462c344e3c2c121c2222101a87832261181c08048461302818080302c140201c0c0fcb0a3d0f70ba8f5f491016d864f976f89f9f6cc6117429941c168278c0b9b07d0815e404de0c45821520e670e1e5139aceb8b6510afd64fcfb39e4ce9fbb2013ec291e18f7c24987cb2b154ec964de2daae97b54239ed0ad7351dc81fbde55ba856e92bb72ffbb4b17c79a275646910142c82f341eaa41b97b68e27ac682828f1c8ed83a29f60620933f7c98077ff8c5c23660953125fc191e84fbe020fecf5a5be93f0b2486d02df86a78cc77b6b8e483bdd94b2bd69876c18ea9c3e9b8bfba31ecae906f3034c80c7a060782f402fb1d7c662be5a09df06fa80eac0bcd3aae9906d46562c1d45d0c3f2365681b6c0181b3efa37c48116e0115b0e65eb8022fc6863fe4a0d763f8b5de50f777e8caca8096f7719c8de7cc137b751e9237f21e3cb55f4d48255409658606a28d3c6a5412880d5143821c3e4bbafbc486aec342c3dd306a78126e0943c014bfdf2fd9ffbc768945ee80761076b837d7b9864e17dc05fc42e2a17a082bb419ea09417942cfc88b78ac3db41025e402cd790bef83b7f570dd4f45ca0b35c1c20e81b9503d647a987a15f4198c099742e804a3b7063ce5b68c772b397239073d8303417a81d3ce2f0b9484a6c08f50cbb5f9557c4a2e5edb70cee08a250e1e1d374c4933347bc6402890220472ac522af9fdd060527b71f1474ca16e3143847d0023a34a28333400f989c245b4c8f72f13320909325cc1b101a820efbc43c2d5a4655adf62fdfc53d0f5b676af1c79cfd00bfe584299a141e82fa41eaa87cc1aeccf08436b9da1e03067d8273c02a7287f9a631cf4bf3f725e3cf5cfc5a076eaac93f035292c16b610ca441f2f119c84a661ab00cc102774121209354308a15dc876c2bf01dc48c5f7512f285ee09a81af08882f2eb120a570cf3f5ac4e9a94703e96d4c5ff2c32cec270550797e4294904b8893a0065426c1af2b1c83ec1fb8460349ff27e0a12b72a9f95304a5fbc2d961f4a20629415cc068e654e214fdb546c9c891cee1cca69d54c4a07118669813ce09e1de0915941c0ce00fc382eba0d3a06cb01a44014e82766a5c03693bfcd7112c0272d12f62eea86ff4ba7b6fbec6b15e309a31356a6562f1ae8badfb56acadcd8aacd5cc747f2f97081490c712fa1c5f8a39ee7d7220591a2265feb4b715eb5f0e2ab1021add3c48f29fa4b4f451ff77bb3c8e8c08701c73b9772e720a97b8b690712a86b69c3875324825807cf72b681be8888ad73b25e053ec152aa72a4f20447dd9e25f5c4f910f5f588d9d391373a491bd0f4807514725378a640fb1cd88b9917cf0329a302a1ba8b535dba013232201cf5a5b87e2974edb1eed80a2aad8f699e8aee1773c94cf5df2063acc00c022b9b900db54fb2fb96be32f8bc82d66c77e572182a8c777095db6e84879f0c1c4b91fe6443a4ad5e4722d66fce13534d8d5ca091de539a65b59985e316c2a8cae81fbcd2ab326f80100310aafd155cb3bdcb99ad4ed9a9cc445b593f849c592be9de4ad3ae91a3ce030e74ad4a5e55c39d6b5faf9597614b79322e58f91828ee657da92d9531ffd93648bbd4a812cbfe527ba142e6b4ed819d968642400a1d9e8150b031e7653e983d2209e94f8ca91f889e33ff6f624ae3989c830eeed45ef2dba9d90422194841513e6a2d06942a515724111cab1d812ff6057560d02cf3f4a90b1ec6bb134bf5bd0732520061c29e3113b1bc40f61607a7a08c1848c4aa153b27c708c8aba0d9dbc9f713e81d7ca9032d8af3396d032ac59ec61a1340280c58d192117ea89176d1b7b498168928e093ce7eba743e3ddbadb95acadfb5ed98da9af6ef7a3db279ce88a6a7e6af10cc06cdd5f2c32456c144ece54c0cc9190028d80926471a24623796b91389ed04f6c6f566d0e16ddcc8959a5fe8e509032ed539b38d83c9c803d6dd24db586f08fa8f2eafdacc79eae9d06860c42e295e0d05bae40b3e46b314daf094539bf80180c0ba573ba1835ce2964cac961a85e3c580c5feda6dbcaa94b5ef2850c357302fc11dcffec3860800fca504e407b72fd923b7cb1da25148ac503fc90d4b3b4e0464ff9ea0dcfd58dce9ee043c6f49b1ee0c1e9239c8c5a547805f3d4504601493944bcf9307907d60182d40802b9a1feb9638a14165650c081d046848e0811270465a18a423908f9115236217d0a9cde4f16ff327c68710f33dcbbd31c94af58edd4686cefffe637aefe4b6a405483c7499cc2e07035820a26473d083cee6b561c953d1a211529e8d3ebe7407ad73fd316328e48918d144de870ac3221ba37b63165834b3125ffeef762e3434340140c7273b808311b62dd835191475fcf0f3aa7c5aef663dbf6b955b3308e298e85e3acea2ec7bd46a2f949d805b6492bfc63818d05a83342614185ae81061a9a299a2851a5aa490088d80cae64deaffe05217fe3b47893f8664bb16c2835e803e8e9d1f3927aa60a5aae012d3c5751a50295019481192141219ca4ae09b6469bcb85f67ade63210000e10b4c56ad48c66aec4a5b1575b37196a23dceccd8811d41571ec328ae81eca57a7dabe1a4f635b5a10905ac8b32611af6ec7c027d574a090559633b95de2ece656234bf422f2f9621e535a6e3940b322791f5f99c4ada6ea2e1ec3e5b4e715a660a646a68faf9cdb92f5b36dd7d602bcbe6cf4390bd87626a1618c7d9751a3f40a926835c23d525905d5d5be3b9ad2c6d8d02256d755f6692f0f710c054064598e0df5d47e94192eda34b7c1603c8732d6deeed3e9efc0ffbaea61e78ecfd22a2214e25ce8150096d90ca5296849ab31629926554339c101dd6f88160be726314416170260887ee0f4834dd18684c104d2fdaaa53e351d64c034a730af7c3d3c8ba64a11d6c121aaab4919fa90994ae1d7443dc4b69dbd7daa9054592532b53c10e36207650e0630c1776d9fde6ed60a97a248e40f4a42ee555341d860e64a3d13955da00c5b9eb23d732a908474ad49d80f2b0d767f813add37042b30ce9dcf8eaac7d7f82f1100cbc123cc06206fd97e78d155decae172ae58a8f6decc3103587d4d0cdbc87722ad7f9129bb66ba0954f4649f4e224c362b9e31fa9f88538d8c39d3051d2b68475da531fc0094ebd60c52ac2e38170526fc4464d64cd387fcbd677f3ad0cf71031c179b0a5a1ca049b86bdfc1b55b8d926340e1e42c7e6d3f9c345f84ea7e75d7f9247f8e116d9099db5cb9d53ad727af78fe0347643149152c5e665b8b402a76cb87ece60107201bcccfea7e5df35d6ae7f075186a3531c667295af6ed3fad1e528325c56f5dab99cbb470d78c502bc7c43a63199b0b8c573ba3a3b6669dd25074bfd4e3e6b6241135cf710f0a496b9d9fa1f89d68504cf65da483262183aa10a9080a7f95c62ab7743b55754495ca2361141f35b27d13b898d4fe498819789574301584fff2be37d434f7dbe30ab11d8f603c4648e2a1c5e36ba86d0252a504ce2408cba2e9338bf0791b6d2c2a9af4da5d051c906d5b2f9e86cfe91abdb7ff281adf8f188dc48c15624d70f908f33d9d7e288797b41b5846f0dafa65b4bc8d81653346ebfa19f3cfec6e3c743c8306255eb6b4addecd55feb25392f55597f20db544e1dfd3260d71cb5d44563c657a365e580bf8df1f9fb3383ff4d1923012272d67427be0d275922c2da74581c7ca846600397a2e58ac1548343cb0b75d07a946ce2ca9f2cd5fcb7d3c642b1bbc4a9890a6e16093d3cc641443b7464584612baf3bc824341458ad8e02dab48a833d4b6bc32822a4c17e03ed5c4b0fc9cbb95968acadf06880ac2c6b14492faefa1769b704c89b202b27f93d3d2c675951c6f32f07d9f96718d55285f25be7973aa2adc73aa46587cd51353b1f17b3f2f5279aa86210b5a9c3b18bd4fc878020f0d2ded14f6011188453b857bff2161ba5a6c73040350dcac56f6a0611917619bd9ad03a4ab53ac8e737b327a2fcb86e38ada87f115058f64b4fcf2798fc10e690bdb636c2adcf0355b28b9b09110c19455d8aa6d7121b28d76797d2cc6ea797dab4b87c376127b7167d51d2dea67d7f288b4d10442a9a817140106ae9e3ad25041c94e40cabd467172548b8e5190b67346aaae4ab45253f2aa68cf3104d3982c2912e086d4681bc55984be9b8d2e578e69a8b2364dc8c56a038cc7d7783b5f67493afa521eaea6092d4b764854f9946100ddf67b775b42cc84245dfd1152893d2d11a3a28c42d52a72fcb1a833654a8a548d5854e725d4c09611b9f77b0356fbf4cd4aabe061134a0247667b231855219b21d394e66a3a8fc3b8d330aa1c60fab3379f1a93d3c2323c2369da8493e746af60547391ad642ca084c4cf179cadf35ea3495c2694ddb220395bfda006f6e31119c7e02d0d66cada4dade822b09ee8601c3a8d0867b09b7a3155749df05fa874d12ce557e3c9f9fb2518c31a1e86686e597e20a72b5a3931883fe62671244b3ebba5f291dbefb72fc9190ccb37016c40dcb635ceb0587a3758a6a3cd6543d5182f1982f0347fc3da6c69bde2b636f27cea1a4fe6d8cca77e0a54e961bb4a01164223862dd4181010e353d3ac76c414c3d2ba574f8a12e4d0da148bc0fbdf07f41f85b2cb699ea24c5ce5e8e9d0ec10cdcefae347e3c4f2dc7e1d36e182f5c3539a68c01c94a2d2616c626236b221ff9280f9840b299b1dbddfce77080029fccecdc0ca27826ecf4a2d2463ba44f33e3ab6069f4420ef133784a51e4c966cc107274824dd62d0caccb80b936b01dc483035a216c6c4a3c88274d5a2179f93c3c06b42c1a44249a90c60de23bc4314f3b316a0b0fa55568f668a8aecf609d501e29e9277aec0df93c809f9638c40d766a7efa69528bc9d140d52a9b453c939f6571c095113098ac0f2001c41968da1529510d14f915c25bb1a416e5de4fc818d5769f94a55746ce3b499e2199309f965543ea3a25cc87d35d8aa2e8528e878f0ab7bf9eb488947eb87551dee5515f45554a98d2edca78186a4127ff35ffe5b4650e75d940c2efa3f9da2572afac1bd884f1a87a6ca08cef4d44a065392a0264612ff45c229b3818c49a86d28f9ed3acc37400a2aa010450f186d58b103029dfc21d456be086c0f4d8aa5c8f75d79209c419c3a92dba7af37604205779f82885c043791c7ab58cfc4e5686fe831e62cc821d84a7a992d3dfd1f5528c0be028cc66a8d13b58b59a959639e428cf79b244e13b0143ca6c568e55000a3eab6220ae32552799f898ba569dafbfca371507e0799f2a873f1b8590dbfe9104d72f481b53e1264eaf7d617691560a823feb120806f0c38bd6f81d6b029e9fb0fcf1be4c6e8cb494f8ee4894ae4de48857a17a64ef09a06160b6a3cfd373f8b0564f6e364625a9f698e29c4770d7e58aca888c1d351af4496ecfb33ce83a385656ab9cfd8250d6171474f91b92a3a9f57312493ee2f895f6d2b591cb849ca9c4ddd2ea73e29dfc7a3cd7e70a9b08a601ca7f4efc11b1ee83965cfd819e3323459c45ee23bfb0914bf361928412b0956a130d3faff8a0a135eb985c1f0c2847f1a0dc1160072b506076f8c347a7381852e0083ae2989217dc6b735946d5e6bc029041e780d9d72b757e506cd4e08f5c7640c65c997ff331ca9a0585f63b76c38715f5dd4f15c82ad2e68e1e450d5ce7ac2df7d175fc65a0158dcd02dff4565d8ac24ceeaf885458782c7cdbe78407d742c099b77d4c3a3405b58223959807db53f9a3e62d9c1ecbe31fad605cfdd4778bddf4a4a8cc8eb5b4bfcd18880d8407bc56ed43367b6e37332ec8b9b293d5abd92aed8ecb341c526874dfb6d3ada44b409caa6924df96d72daa46893cfa61d9b3cec66cc096d72e42e2721e7ccc2ab7d88e336333af546f03374c357f152153c391abc353c518c94055d0fa1c072bc965cefc95e1c6471578def335f1a371d63f62217f7423ffa45e36d678c97c265598ee00701a19636308103c6bfb6bd220e5d7b71bcf61d3e83f1efc7cf9169ba9330c7a6330cfdc88404af186a05be6e90e38524a116786b4585acbd4026c64ccd092acdcad81640469df7fb0c38d690a107e1cf7a305e41fbfda779e4aa5a3cf11d3f0cf208d4a2d4676e2d123be85a9b62dfc6205ee359cc382ab5dde4ed6dc08fd39666181df734747610c207b2d71158fe8e75b64ac8de9528ef107d27ee5bdb83d88d6c328de948c0d92b9949b6c8e4b0ddd6662041da419b333240515dd66718226336a9728fb205414515bacda8e0e8888833465108b42a7da409b4faa1f4da78b611c31ea4d42fcb76736363e651c0ec1a097d47561b581ac3f580378ac39db31f9eb50cc7978e8a95c76dc702a4f83032a80f3721119e1a5c15aaac7379272073e52cc7079aa5638e3b0eb673c46c6031a58323be060cc195b388f0e45b1afc45e0df96f3ea6e2a955d97a47343e62ad193f6391301541db3ba6301b3faa16466351582d9444e695a5d178ce842a6bd6f7a92507c2f9243a3425df218082be8ec18f288384d2e073ecb93a87212bcacc7f4bd470f2ff7a4aa70597f52b4812cdb4ce79298246b2a6ac9b1114db1674b65f44012c6e204b51476eeb1879683190667d6e73a00158102033024595516da4def680cc36dda08f18113e6abf6124ca84915a7a810125d4bd0b78316ce44c95200b0f154699820411dcaf534c49b214ba6a218b991be40ab3b5e383db51972fa382deb818902d46f16ccaa034dbd26601fc97e33b5b536570db41eb00dea66509be6dbf65fddccb36194bf20b4cc371e0a080969f0fd65060bf0e64ffa3928e36ef5fd246cbce35539384836efd3d5ca23c473ebcdae16a36878f3cb06abe378975d565e0390c76bb50065d890dbd386d07a044f6354f9272812b4eca08bd9365b47b1be49de0e3b3886f16cf314641ffc15fc508f46efa923a094f3a8bc375bef412450298879b4d748677208e45769e5c8992e75a1f5642b2aad4d544bf02a72efd5d55e7ddd022f8b0909962a9b16600607cb0edfdbaa4b005b6a2468d51549d2cc3ae5764747baf8fa223eefb5e73fb886bb6b4137f7368b34a78fd16ac34eea55d574c339c0b9b48e37acb522f50dd37859a2573afffdd9664864ad496e8bdba7da1b36bfc3b626c5d212210360872760727ef30da783335fe8b1737c41017bb00ee45401ca59b5cc4eb9e92153326314b4469b3556eab840fd0c21e8ed94afc1585c2b84d973d007ac707ccfa198b0e02a4f1858a10a54a08fe0c67c9d61c280cb6a0b72649f15b6ba258e1b2ca093042dea9c5f46394541633b2ec86a17014d230bc6ecd105b753cbb8cbee3c07b59bb7c800fc0ebaa46f9dc0335ab5c13546de116806b87a2bddac8e24c609c0b6f5f9304197a0db82d6a3a4eb675212685b89d1a64972b656dc9c6b691f30713708628147ecddefc1a18aa860a8adae579c01463f9a362976d069aba9ef7580866639c7481b9ca9933445abfcdc445678839157645b6f9949b0dbedf07447f3b78b9352915dcbdf74ad882ef2c6054bf4d017e90383a1817fe7c9c5bbeb3c7a1976b22874570436d64332500b67a511d6308ccf9f1230493dfd1cd4cd03d3a6cc3ac93e14145b7e368d87ad4fa8b21436071b910215b571658a16647bc7b64e2758ac084821ed9f00122b45dcf4bac0039020299be99987d90443e68be7def628975479732951dcc4ad6b315e19519b3f7eeb329adb56f0af64168e669a8d7ffbf51d49a5e20c3a1abd676e73ea6c0ea9ac04f7cbe3efbc8007f219f69d05deb114d617d0ad815833ba716b12c16467222189bd1102ff13ffc759ead670b5b18868dbdac8a85750fde785e1a23def49794d5621f06f9826b78c9de596cacbffa02fc41a3e0797a160bcac175a710e61ef9e5fa8e3df44590bb2951fe048140cc9afc38a1db64005f3c8bf8006694eb8abaaea883a72ec2b002eb82d5d394c87e29754bd29403913b45c39169d5817400a1f924614cf8573904e5185fb575d2f4ced6d452fb7e8d5086676cb48efac17063a740666f0a2993ae9a816535792355a989eeb3265a1c62dc22de1a4a7648672edff76dac6724b005471ab3f62cb282f46b975eb4097ec61a16b15491a77c17fbd01163f5f219c1df6b953e4ea807edfb3813c1fb4ce69caaebd4693e26089392e6ba5b6ce4c8173220bdb8762ca36d53170f2f1ebc4cea5e71a82a1ae95f4ad34e81d1b01d1484fc24f4e9df436d0c73a204297ec1f716922e77e7d8769c61e94cf51c2ec5da082290d98c83304fb0060bbf7b33abc96cab0ab3117b1bf6b125671e7bf5a6bdcc532752be94c66d0c0090750151f90bdeb24ee63c26f540fe6020cdfc12fe2f9eae2af22a68d70b15ebdc4fe626a6a0de792d8a375e826f45a848181888b855b1b73b213ee52e0843550179e1c0a68c6b44b0ff3c07f309406e75fbe33d904d2c3c940c24281a6a46aced01dff8ff905128a46165688380e0c2d209a4a109b1bda1614a5fe380d4101eaa14780a43602c14358b6567ad16b58007a1a23d433124b0d888c6ca6fb8fb083f403010f3911c06a034c033b82162f797a4f99b7ea3b6a41c00053b4df0b803d0d99132ca704882dd4d20ee014e0de7e708f83e974657f0f6da0f8c8adc6455792fd900e69ecb115f9185c626d200a45851c6ee269deef68858dc0f5309ca795fd5806d6aa533e1d03383b27e1d6b300040f2be852349237d1ac4fe182cd00eb1a5c73155c35ee949e4846f8d95a89c7d556d082427b686b4fa1e5ee01da1a961ea52b7588836b10e6101145db80d327d0584393592bff00c37d0c7b0f6cd9805d1ce70bbdaaaf68c1753477dc7a175ae0a0254471ea334755e8f07104d2733614802d63b2772c7727e22a3d2e369b53f5a8eaff865a68f90844a65f474e0ffed6b9848286a93331f8b57a515b1aac94f4b1c4b75e99a7c5140efdfb2e82d2a4a08adc40b01779ccdedda1a5fe6a4727829a79a5d082742a0771ec88b82813559635d0e758ffe82c80991473f724bc61ab29665c8480e53e4d4bb24ec1da62984b4b7799a3c10a2c9bab4d2be89bd0b971d8af469aacd0673280eab61fef85d8119337f68795f02571822c5606e764a197534e24140636ee8299a2c66b4bc1f019f9aef0a91619cf8258f972182f4f0032c9dbf71834c41905879c655c06dbdc0b4f166f62b38f711c86952943947da12603096f5c51573db48947358515143519087ba37c1c07d6be56312e29414379b8c4e1882f82fc2da19e509e400167febf68daf17409795f045f1b7aa9a09a5c25f7f21e0074921f1fd0d0f7a35dcb91a0e1640aac10c004c131175f4e93fe877897378ee476b417b1d9a682edb8b454f803d681e7df350bf4bd9e082b48ad60e02a032df1586a11a4b4916e19803ac6a0e9b2f2ec24a1e0010f0b3e12d8cc7a97ac360c586bfda0b4487e1ac1f08601acffbc4f291016d0f510368a51eba8b8574ec2184e4eec92c311c486bc1188fce8027434708a46c2c3f21e23c47e5d5a49e9c20448ffe258c98258ca7895d89905580a01ab089161b1942121c3d2d154492e6500c30032b7f1f0734b2f007f97e089e18f657d045c830b8c63b159a62c0e2360a3081bf0668c8ad6004dd9ace0c15601571b14e954c64e65133f07cc87497d7548b2f2f0e484e2e7f795cd067c464686548668f8d81723b8427d8cf85d74ade7e3a1a36cc6d140f73cfba4fa88c2c7df0548762eca7ec398889d69e9440bfd278419e7bf81350c4ccf000f2e83a5e069e2839a6fae4f8faf1f1f24be217e5438456928a1835a9f5d02df7973421512e1c3a6f7712b583ebaf2c02764d7faab2971645037b17731bb2f3d408e4cbe348a730714c7942f01ea9e8187ac4b320e20c24199ed9b549900952562fbd7434579645c1788b96ee5ed4be32339a3135f52b209c90ec0fff9e1e26a908642c74a17b79081190970517153859d2029c148c457c04fe99d3dd1bac1961faf4316f2f30c221a26846cd1b0486802e63df3143f6144555c09349abe3b8521638cc37993c48555ea5f60de1f857bc366d711f17f6890ca5a22fd6ac4f332cbb5ff5ca6a9c1e77c98c06741a34499f44d8c6ae074715a0909283a28637c1f24f5e7381a1293fa8e753d36ed198e9ea70023c3cb8be0e7f7046382b1d38d61b4bbade954f907d3c420066a9cc37c5906bc702693d6f7e9d0666e00cf7d66aaa58d5097c1b63b20e192e11214076b048b7b23c765f3b379a00b0471a5a260aab879057cd630cf0acdaac222a53a9866da61c97841ea67050addf463d95efb1b46b06a21c717624864a23aa2c512c1087530c60549623a53df694afa694df24e9ad93fb6a2b5637a187d9bea30ea90cc0a245215d26bf8cce53497bd00441e1970918924562eaf68b547b0ab63d760205927ba5451acd96d80c51edfc163247c3f0d7fe939c793bcc06601dfa1ddb2274448c3a6279076df8b779753685122d2794a99a2598b14bf2c65b7a1645aaa157a8d002eb3304a59e0412cf8d3f8a08c283ffd9ed82409897e26f5c4828772659ab347e22d7e921a3237b51b16ea134909f332474f7cbb3658a9f57bd4f5e45812aa9767b7683102993db0616192740fab0809566d6fbeec361733b792e475d96b7b26bd2553d603da20f78400fcdb5965fd0505473174ef239cf39407c7fabae2f6662ac2e3ed5f07184584dd223bc8fe908a4ef10182ed367f32da45153e78851d45175cd954598b5263540bc9bc4dd2c14ff169b1d5aab148f0d0777c1c321776f0d5dea17437a111371e9e61bad0aac889c7a93f09693fb519c96b452a7e486fe9184ea4e906a35619ac5fa45ec82e07870f7090cc049ecc624f37516cd9107920635d45641b65b45b4a1ef581807774a49f31104e6971d4c71413156b29b14f39d5fac2180d2e6de38004296f63410232d95ca1c11dc9f5b546423f6e9dd8c6e4bb659b254bcc2482ad9328d1c44384237390af69c2b65413d703c9c9e78d588adc82415b55933a0d42d1dc4e4232039f2d369bb16ab214b2869ef1ff231d7f26ce8456fde1e559af494db7d3df30e3beeca0eee54c180e6c9397894c6afe93330ba25821e23aa9edb29aa939cf10eca3754da50d4c6038edb04adbc05d7638680318f5183cbed609baaf7e3c5bed654fb335ecfd76482a56b98005c10206fd665ab4407a525087a29b3d42e122a45c9e3f743ba6ceedc466a3e86305a39808ca56c04cae69a7a205ee907b72092d4fd889c33e105ed56e485e14bea958ba6f6cecc7cee673cbc84bccddc662c2bdd334752d9d5b1f0ecd19f8e3a01e69f44a27a7ea05e16ca234905d243840303498212a83f9615a984abb1309bc07eb64ca98943818b9de52ecdba481e46d4b64f61d471af7e0c7b0e054be389a8b1b7635c284000085d81684e831b977f0a18532dec98d1883d7561293bb43949408d057815d420fa1462d3b16f417dbd0d94474016c3187d406a14dd9cf2700f21ce0c4dc7d44e8ba2d66c911484b059e29392c845c795f5e319ae10bd6fe2815d6f15787f08118fd6047ce993441f85648e3e44fb802848429e33eb08096d46aaab8807f48ef8e3f79d602445b4c5816b9942fd7075b7336709e2232cda8415e9e224dd891441bf4849f9678362744983b0e2348669bda4206986721d6649afb7817dcc1f6a50f7a411a2241984425887dcc03b83ae5f7ee320f4844dbab088553f4058b2771226037ce7faf4073f0f6800ef4a8d69f73256cb707b152bba4e470d57ce9c142d9f288fecb1e41418f2ddcd5e9e5e4d3bab4a23833d5086bcb4d97e6b549e465cf603643e3a523b48e83b7ea2f3a2d1fa015f2779fe271c6e7efd34ff100048dd842571ab924add6256e142d5ff9f192349151ad215129946e8ac62263165f27cb58d0fce9771b92fac71305d48e56a627c91dd530e6dd2d8dcd4c2a8ce0ffdb1038e75d33e7cfaf85ee3fe31e21ccd5789d53c9c9c8ac0e58456e81ef08203088b04656a2f6c1772158a21602fb5ea06f5b9a85e3d033d9e616343ce928487d5fbb87aacebc0323bcac3b41faadb610aec92a3777686a4f7e9b72d358e7c388055975afdf31f59935d8f17d9019d41cd52a4da3755bcd07dee3829ad370808726e96a7689b34f59f2b93b0331bb068990770b5b7a74abcf79241788ae04de0a3b1225763ceb094535841f5e22a9f26efe845601e7f0fedf8c0fc8c4dcaba9c98a06b8369132df4254de30e5e641ba45ea43acf7c410001e92a8dd1017c4ce3bc09fc4f7ac11769b14e0a86626c7106ec6c498ea7bf3e975eb3d090bea00ea65dd7c91808b0af15221fe364a398b81bc02c4fa6c5976088717eb70603163870be2e2010359a1b18472194128c47782a80255c8b1eb3486a8122aa1a2c80a870b1d24842ed7367245a1177a0a670dc2e9195354056fce67b608ac6dcd930e007c873bd9a3b950b9cb0b634b7fd8ebf2027fbb1e8eece5b82580edc5fe1fb5be43fad4d1c4c235f6b8376124423c2b2ada5cbc80b0a23a3f571d6e9f1dc132c3a6f0c5bf03c5be074ca18c266c9ebcc9da170bbcdbeab38ae09d061c7060f1886d5c6fd292ab2ff6b0724683b17211393e8832ba08d6544a4094ddabffd05cae4206813246f5c6c20d134680dd3a46285810fde053033d8eec23708a709b17218338e15af105d5dc938c2d4c52bcdd903815630bd56ab09e79a1c0b437343d4dab09e282a56f8ca297a8fb409e3eb22c561ca4b9a30e5aa490f90811c5b2718c290d9b4f040df8a3d01e70d4d8a0581103cb713db0d670efbe41ae8dacb2408d2d1987938651a2c2e850f523a642df26a789abe881ae21d07fb17059c355cb0a945840866309e783c5b7590829ebb1363f7d38d0cee8f05c27e102e268d47c7b52f737e0a8f942846c1f1abc1a9ef4a099dc2893f1ca01a0458735765c8c3f08970e59a4a33c3f41b870d23d9d772956e00aac8276152022d503d578927b9a4d0618425d3de94bb6ff87601e68630b21ac07eef95c708b0ce07d90a80dfca2ddf3c7213140cc1568a30596d1bb093fc64f85ee6e68ea7292d435e11ee041e13407c11015a6a07386ff668ef2bc26a7af9467f672845016982dbf37d55f368487ec60853ae288ec3037bbde789fd0102a4b25d120210fee66d60370fa2c5cb6b03832094ca8b7c5db58695a0f55a0e8b80dd9cf61ad05abe543af922d094e8f9bbace9a66b18e8185a2717ba8f94cb303dced1e55cd0ce2740a822a44a71fb5625ed980872cd5af1f126f16f7dee4d591b142ecfc77ee26d8f89b7aa5eb9794dc1b98c7e3e473a04ca094ddc8f92abf9147b9dfc9939a32441ddb816c551eff16163beb5ac283990d0eaede71a5b27803c4e21a3fa87c633242ec80af7d21883296180f29751338d08a21072cf812ad73e699ec72b1f5d7e2c62d44ebd65a7540a0da1c514da27e5ac6d3cf13ff5499c161d86876f49659e7c90043b2324730db637430337939a52f5fc28fa2b870066e3b1053fcc6b80dea7b5a179233b810443514a2bf0b5eeb1f533ce1c9c3397cee5b0f5a3cde27d6db953bdf87a7c99d10d165ebe381fe6829f61f2c60890eb7956218a0d0d6922033f802638d5076bb9489a376b6aa8ac67f25c4280922dcad9819583756eb7714b40b86bb8adfc21bc4268a4f8a1cdf12708080b7b98456eea30a55a6ff8bc5097b9e586382c47db412e438de5bfad90266ee2639c3dc2bedb3a94f9a84dc0b8859014486015382105ae040fc2514ec7802fe4044df0a3760b46439330f0f0f0f0f0f0f0f6f706ba4b6d6368024a49424a9adf153f8ee9029a594648a8433d417ce4cdc86362184d1863fda080d02010bf40ac50ac9f499f2b5ab325cc1873eb19c2fda07c868051b529a92123cf3a59820b00219ac6064bd6b472a993a476d6ce001362820011b5bd880c0183256c1a43e4f3166e855c1c61acb9f53da53c19f680d31c8fc7ef9265430f92ce750ff21afa77b0a268e8a96c73bd8b6ada6e07a77f46be99c25eb2d059362481a6aea99de1e29b8ed9027e4cadd28f8205a9265d09e29658b28f88faf7fb6d9d3a67c2818d3f8666a440c146ceee8b952b0de0b1df904bf25748af61bd2a8c83dc1260b59c53f923e25f24ef0f9647a8db69fa4fecd093ed8a866ad64294a3a6d825162c9dfe228799a9334c197902c5a24277bf55226b88a215a44537f25e208136ce4d0f71f73e275e55c82495a21e85e907973722cc1badec678997542094d25d81d913975ca5ea276a504b739a9c99e96d6f58293e034b7492b957eefc59304a373d25ff59e48f06d25421242de9f881448705192529f839074df23189521287d9e2a6d8a992378492a85a44935b6ed8d606c5c536806d5604284119c34d3bd2d79a47fde8be0840a26b2e45c5322a22a824f1354aede4ba52e272611ec560a22654919e97b47049b738a0abefb15aed14370c13268bbff6032a225c3109c14d1993d665536e11582cfcb9f9d2ea7641082dd2cfa73cca064705707c155f610e99a5434b5a80c41302a7b6be39f84a4ab77b1c3e8588055faa2053bee003202c1081193fbf9aa3db72203106cfa9317539ac4913193f107ee4a4726c30f4c12eb517a55374ef4f481534ae8535dcf49883ac4088380a12351061fbe14f5141a5e3a4765ece1f275d3b496255af0764d20430f2729fa2495b6cf6a870e301cf0001c376e84c1011d1798808dcb01cc41461e4e061e4c9b335a1aef0e8c48cbaf1284251d499b63c781c0160c68c08d1ba87164f941861d72edba183a090bfabd066edcd8a1038c3176dcb8b163c78d1b3a5c0c2efc04376e7419c3860d6263d84036c6172d6807e0d0e16274c18518a70b07dcb8f1858b21c6e9e24b11400c32eac06fd22554acab15931ecf72d482430162635879e15e14d70146ea800c3a3041dae44f8d7539863e073ed6c64b6152f3c80fc981f59c444c1b458e4c37f9e313e8a28b311c1007d6439d44cf312c37e370e0369ed2759d296508a63770c2bf4f3cb6ae471cc97003b7f77f9db263ee48a78c36b0c17c63f9a70f2d1dae2081a12090c1067662b59f8c41d449f30332d6c026e9d95c443019fd35db21430d69cdc135a5e995430b87abe0ec28c5011969606c4dfb6e64730c32d0c05d4a2633a325b520e30c8c9af2717dcde61b649881cb9644fd5f1acbc0c9143f5bfecccb5d2237c820039beede4698f24befa731f039a434e919ba83369535c81003e3be9e3f8fba06adc130f07d26ec5e82fbc43791db820c30f0d69fb55792f294542c878c2ff0232baff6f208870c2f30c1d4b485f4503131c8e802bb49a8532143e9a867c220830b5cf4283107a53c684b627761811b374c05376ee028db838c2df0d9f71b3d564add6b818f29f7c40a53da3cd959e0e249cd8c604158d0278b50be279e2bb0fa95449f2e09c9feb50297525636f7f414f42a70f1541236ba1a29c5a9c0aea9905e9ffadd53700a8cf29ca2c4b558c890023f4a5f27939f4d57d089b1838b09686087efe080b9848c28705e22483b9d37275a1e0aac5b9ff6e54cda4dc99fc0e62611c72d74c6de9dc087bc632da2e926b0aa96eb25242526302a3285ab9bcee8c9b40446869434428852c93fa4045652c81bed6d97174349e02b67b4b43e993de206097cbc48e3e621e608fc85749aa2c734b333023978deb6089c58a848a9b359f24e128111a6eec992a8f5dcfd10f820737da759c960260aa1282a276da7c552818c2070f6616363397dcc07029b2b22ed86d2b92ffb03c6f622e5ec5bdd26293ee0c23f72fc1b0f41a67bc0e7f8554a1649a23b3ce04df379695bab8f15db01373af39bdde4a4a242142043074b126f2d99262707bcfb6637355183034e729217e468ac0e326ec06b72b7aab497954d9561032ea5bc9a9625dd0695caa841b6412b92d438914103aec7473b0b4e7eedc8d49bf290052bde954f23668dec522c18bffc94549f62400a1eb0e0a44790f69af335ad690b1bc40236b6b0412a60630b1b840236b6b0412660630b1b4402362e30011b71f078059354c8316b4816cb84af06011eae60bcb5caf2ae294f9e6d05a739ad24d3525975b783218616f560c517e25b5269d15d8f55f02571729694d23278a8825dcf6717d306a5673b20031db871a30b47810e1d607c9123edb871e375a800061ea9e082ce6f2a29e615edcc0e555470ff1949b54474d4a46a233c4ec1abee6866f28e872918ebd4fbf020ed8292799482bf0a0dba5ba204bdfc48c1c90e161a3125798c82cfd5a33e652d3d9aa31ea2e0f562a5fa1c52a964268f507032db574590b955bdf40005a78334117358baefec797c820d795355ec8b1e4ac9c313ec8590d247f1d31325280f101e9d605490da994da8bcb93225ede0c109369552d1941d3d356463f0d804bb492413dbfc1f3bed9a6025d9e59dd8a273867960f0c804eb6bc18205d1a14665c5e081095427a9f157c97e31868e9580c725f88c3e22c326059d7181c723e47d06cb4be5183a2af15bd8bd9f679b128c8d92b9baae3777d4bf1843076ac063127c0e91458a5bbfee3872ec18230cc22848470c0d6c2567815f053c24c1061f69226ccd4830ae39a4a037dc8404a3e2263565ccce27fcfd82c7231889c1435bef7604b71f6a6b6ff75386c9a3119c4efdaefba57a30820beeda9b97443ce0b108268888a87f168c828722d8a4f4c42da12af7c41c143c12c17d9b56e9b859a445cb0311ac046d77cfdf158eca83c721b890f2cba2ffb628bffa0d1e86e0a4d999f87757082e87c6ce924e242f21941e8460d5d3a59844dac9fb111b049ba2c6cf79d46c33d382e094509bc54ac4f2897904824f4127a154f4e7c8db01c1d7a63a9d628e1172c5a6e0f1072e0909aef9727f52e843e0e107ae3704d11b5f1bf5ad471fd8a0db69d48be9b4343df8c04b0ed3bccb252478ec81cd173be8d254e5d0c2d17d881d142430bab00b00103cf4c0468e6629b45f27ab5efce09107fe93c633bb94c9e2c8f0c0597253bfd1be6c7d2167048f3bf0716d2d2d640e4916ca2d78d881cf509d2ce5300d95d781d321655656cb972548b4e04107ce7474bd749df4e50dcd811f75dde65532d6b8eb21073eaf280bb2627c8fe92e81471cb8bc9e665f59d4697239e001073ebf9a8e1435291e6fe06356341942f28d091e6ee05bbd72fe0db24c9989a305270c331978b481cb394951cfbfb1aa325f78183bc6d871e5c10626c9ec5e4a94aa1ceabec0630d8ca757f430b563297335f03149fb8e96df64d27f0b113cd2c0f765fecffb3d61d2c62c78a081c9299a9e2382d23a4967606db227a146d89ec528163cccc0b82921e26e2c9f1cdb32b0c92f467190819139e93791e4e7381a2a24f018039b338410d67b31256d1bf01003fbaa498a5d503a3b84b6048f3070a66c930c1d47b55f0a0cc7943456d25d2bc1e30b6cdde8cde9b1cb74ee385aa0430cbd828717380f6a7dbfcad3877ebbc085d7a9884c4a7bd0e102a3694925e854b7c0f9980e52e2297f53d10a1e5ac0721e0d2ae446aae091053e6fa8648d1d1ad444565df0c08297aa479859fc0abc84a851cb46895edb0a7c90dfde2e32fea9a90adc066d7df24ab8fa54e03e43f57966bacb4e81f7493172aacc4ba18ba5722995321f055e3325896aa5172bf350e04db3f376d929a1db7f02a73a7947c545855cdf09ac5eea076dcda263f49bc004cf5144aaccd39f3e133855f12c4b0aa1f2cc5f0223dcf472c9cddf48be12b8142237affe78d6f093c0968e65bdc89b62d23d1238b9e329c935f99ef547603f256bf650933ea57e47a5c949d34a70e71d84ca9643095633b86bc8ec24f88c9a63e79f940497512d491db7d4798491e083ccd9d245de8ed53e0d4864aade848aa351748f821d670336091a8f60848c5b413c54e7c71dc195345de7666a04bbaee7495e75868a0a23f8d0ab20624417c1e7a9ba20661d73f614c1e54d0db6b9f636b49208b6d2e9688f31b6f588d84c6434134a7608c6538a489fc97208779b8b2d0c0d43f0d9b549ff540aca275508464e4a8e11062118cf214cc5d1bdafef0f824fbdfb510b7241b01e96dd3546dc1f650a04772a846c49f99eb6090204ebc14699aa49273de9fc81f3bd1391ef3c7ee07774e3d5fb875cbbe9032f31644a9bc6bccc357ce0fd5753cb93660f5cec8951ebdf54e8bb7ae0aba2a8542a836ef6681e8cdc12cfd7e28907ce92103d31787ee91eefc0c6ad1c4c5abed8818b39cc3e3de705cfd78157cf9f8489c6b4392b3af04175ca7819a4258d990397530a49454c264a47090b68c8819598c13e84150736554a4ab27a8d5b88c3814daf9cfbe1f71bb84b4ae78edcddc089decda0cbbaf74edd0636a6ca2fbe9577da64d8c075ea5222d89fda5e740dacc8f6d49b37a806de7f84083958c839669706ae2496d03946fe247434f09b4262d299fb5eac7206ae84f6cf6f1e4a249399810f22e554d9eb32b06e19926d940e19f8902c54ee8da977947a0cac78796bce9253a5b41818bb3ae175a623e78ce068810e31c2c0ae47fbcd29497eb01218b8cd67a9fd93f70556f32af57684c5909917d83ae59d25a9c9415845031a5d602ba5a6cf6a4ae988991d6870818f9c45e8df36dd10475e70b181a5b105ce6dd369519a94e8a4a3052ee5e7fdd5dc1d92a259603746caa0eea7e244110b9c5b6acfea96bf026312526aaa7117216334acc048099ef267a5142f48a30a5ca5bfdbafbdf5b594a5025fb16c83690795ad73f431ba382ac017d098c2e291228aa8a454d19002b71f4443d787a8161b1b78c016c50b34a2c0a9260bd1b41e9e46690c1b1798800d30d08002175fad339b526a39b883c613381135bff42e7a8aa71750aa8481861358df4f0bdaf55354d57194c181461318b5cde7fe1a732c956101183ac240030d2670da83c48c6e4a62eab30c3496c029ef13eaa9367b4990d15002a7dff25f3bd2e4895d0e2d1c6178914a79b145175f58804612b8d4eb4a492b8a042e289534ea0633a55febe31928a510a071043676964ef622358268530a348cc0adc44b7a22e6b459544da051044e5409cf215b9e38a944042ec35a74d774567c1110680c81afca49bf52c4abcc7aa9020d217039ba74090b324fe62a08ec290926c1454408518106109890e495e89646aaa0fe80afd69c534b8714ffb328d0f001574aa594f4ea95e9b422a0d103ae57af92a6d2ec3b960cd0e001db63a3b761c98249d61c81c60e78136197ee62e80fa937020d1d70e2ff3175ac0b3adf99432b0c2ec45893018d1c70390691d73dd3f512061762e0d811061762744103078cf63bcdba1464a040e3068c77648d314516c976db804f4b216b9b29dfb7c91368d480dfb6d23ebf4d3d7dd1a0011fa459fc6c153263169cdd9bb6dadf376139b2e0a4de8e48f2cf34cc8805ffaa9236d7f2657fdb033360c1495131534fa65598f18a728b4dcad2d9aec00c57b063dfa52b2c58cc21cb21cc68059be49769d0bfe725439615ac66b4ccd851447432550366ac824f5971efb23e6dda76862ab8a483074bd974275d71093352c1be86fa4dffb9fd928f0a46435747e750b9b5834ec16d52da1d4d57bcccd514769e1434799fc508334ac189ec7699b71bc2724a0ade54667c932034e576678c82db6891fed385cc1005a73972758a9332a599a8302314dcc8bc4d2a5eefa5e08282179dd926a9ef6b62ceccf80497530eb641095d5a3ff7049784befc38d2e4a77d3ac15f5bf747b335c78e0381d3199ce0b46565fe379dbced83a3ca143163137c648dfc9eb7ffda6a08d8d8c2c603b6b0c136b6b0d1802d34c1675226f72f7dbe3023135cda10845ee650113bba0516666082b56c11746307675c820b41648af9f653841cb28019966062daaeafa0aeda2cb4b1c5186654824f7192501339c434da86125ccaf190439b9981044617ae6312dc067da6a794d6955f39b4ba0b303e083324c196de0d495e3a1b21ea48b0935da2e64c419060b2281d31974ee2a6848f6025fe577a9852e121770413728aa5f8e9d35a4b663482d31bd916538f8e3083117c74cdd74e593daa25bdf02202691b8043cc58045bd1ef2aa9529e79438ae03557f2aec816edb42711fc5a0ed9d6e2410463216ed01f2166d6c839041f84c4cc546117ed5a43703e7a3a53e45821b8d0e3993cab4fd54d08ae8450bde412f39f84e81003479587d1820d2462c62098a4b1d2d5f34316e90b82abd49bd9ed8329b33b10dcdf6e0ebab29724150182fd78edede611f278f40f8c69ab3f75b671d32a40c1e62366f881f5ebeb11d2ea2c5abe0ffc55c7cafece5515743eb0669182f0f4901df2b3072ee5a818214e1296ffd3039b4c3f72929a5ef3a57268a9000538fe781738ae3a2001731580e185eb08402066e481d39a1154d2a022a6d5f1c05d06559363d21a9edf81ffdb20313ceae474db0e7c2cf1d7b2cb1dbda375e03705b5187445f5e9920e6cbabe9873fbd69412e7c0279945e65dcf4cc927a6fd8b15580000aa98210776426e491294478ec98f0327b2e385507582039bd386beab3db7d1ef1b1855c942afc8f7b6f204ed08c60c37f0b59752c5bcb95deb6f0393763d5f48b55945c6b0819359b2fea8fd2079b26b60b744e8babaae8d9b570372848c41e8e86f1a1899befdf2539e986488063ef6e556aefc9693b2cfc08714da64c87631490d320397829222476b4f2caa6560944ad31084480c79f46460cdabb35e8292a5427e0c6cfb65a618835c0c8c25193a657dc8b1b31e0636a7dad0621a4212afc1c09eeddda8d2a72ff079eaa3a36e4a2add78814d7709a61642aebaa60bbc78784efda6e102a37394741fbf32627e0b6c0c4942c98c76fad1d50223536df69f8e27c966814fea937ecd251618cd88a9be976f17b91c5a27f8828b1d3ac648ae03479da0991414665c81314f2999e5106b7df3de0596cfb002a736a7ca88a12be860e238c1175ca0209d40877b5186821955e0728e223d847ecf2552ba382ec60e1c28e8620c946563030f6080316f30beb89f41056e83dc8865a332ef1de98b8303477f7170b0808baff2850e0bfcf109883106056edcd0e128d071bc281670f10503c0831953e04678091169d3bfa2648614b8b4416dc40b966d6b93436bfbc60d0e9828b0af395993ccd2983a0a057e948aa62a3fbf3c98f1044e099154b9b27437955608339cc0bbea086d79a46e507130a3095c08491e6b27fead884ce0a3ed77e7cededb9212011da7033798b1042645ae98aa4c6707515202e79f747d103a1dcc48023b69b494bedc9954f410099c52724379d01dcaab37338ec086c474ee1743974660527a8a418847af084c5caffe4a3146df9815e30b2e3870e346210263fd357a3b9dffc5b0cc60c61038916b4cc4d19f35e9940b6608818b7d2e4a853ecf82c0a6aafa87851ac78e436ac7026a3003086c28c949691fd359321983193fe03e65f41cfc7447440f0b66f880519372fabc37cd49e66c1166f4804fca247aba8a179ec61d3ce0c7bba36fe48ad88e2f8e0e318a0161c60e184f6a21aaae9f04e1660e66984eaa246da9949e03be72c774e1a9ce269970c097dd56ff58325def8a0d66dc80112965b1a0aeed554b1b705a7931e36a8ec9d3ad01e76a75f913626d0ce50c1ab09ade5a33a485560b0319b3b0c3b36f5398c9dac5f8e2a4d3012bb2d08245b5bb78569b2423167cde18740e1a3b5870a79dbf6486e0173b5d84e185eb0b64bc828fb12f0184e025c5531a565223bac6c60626604307c1ba9f106db59932725210e64caa83d0fb2924ff77081f81e053df5396a067396777820f40f0f9bde6e33105b533b1e1e30f9c773495f75250093efcc0c7902fa5595bd9c79429193efac0a7d7575aabe8aea0c307c6fddc4a3d85e41e58d3b4906741add6d71f7ae0cc3a06f724624a4247ff9107c6266ba747dcc9a22d1f78604c44fecf154d738595430b8cff820ba2838f3b70aaeee65e5ffa473d36b610400e3eecf0f9a638d16dc4b31c5a2b383a70b8bfd58193c147a452f1e4093dd1814d2e6abb746ce7c0244d49f7a27b7268e506bc0b14e8700a9c073ee4c0a8512f21670b922cf42ffc04a6031f71e084ce6bff4da1b36f0a072e2328ab0a96477aec38f0f1066efbdbdb424e11512c6ee0bddb46787814d16fdcb831838f36f0e6c9d2fac95117526e470e1d384e7050290a6480021420a6c30b2f8a083ed8c0e68a14a93dfff4d28f3570b5d9be59faa5e5fb871ab8d6f02c916b64d221fa9106bef7bf9392b42f42d51f6860474566919474d37bf6e30cbc89a6cc6a29a6f4261f666063652d4d32bd9652df4719d8a4845f977a503a499e434b4df041065efbcc1c03dfab66427e4e36494d7268a1e08ba303c78718d84b217ed9b985d8df8ae1230c6c6b2e4fc1c3b4cfd361f80003b7a75f728ed61633828f2f90f369ce21626e8ba60221c0d11f5ee02bac56c453e66f497268e1c8808d2dc84717b8d2bd110b1d65ee1d2e702a9ab698d47e47af6c0c1f5be0a2a5b8a9152adfb82106185decd80f2df07ea3465e8be6230b6ca51c44b4ba5ae4a4fdc0022337d3b78eaedaef908f2bf0315f658ba57b52d2b815f809b2cb3dfbf85105c63ce43abbbdd2967e50810b5a2c988f58f89e3ea6c075468f9e3a434a7c488193626a9d7a2df2c75013cf131f51f880427e31eea952761727c761e0e309fcf9dba64ebaf7e39999171f4e602d87aadcdf4a11d9a2253e9ac0240b21656b089120a41f4ce04784452dd31c423c1502bb858f3bc894d2561c9d600ce48de304607461f0001f4ae0aea35958974aba52b4c24712dc16d3bb112a6e60023992188701376e4ce103094cd011a39a7dae12253f026b2e4994c80db5592123f09573cab896828e6b8ac0a9acf02836e61584ba880f22f06d2a78d6d05be1ba6b213e86c08798be1f2a3c4d16c78381c330c013172ad0e11a2895237d7174a0cc0d7c08c13d7d6abef7dba1a4021d636c91868f20703ab3b957a94060af445bd03b293d7d82838f1f305a216d52952e59d5ee0336a88a646eb71d64090350838f1ef0f93de7dcc9d6d5d7c4032604f53cff705bf1b1032e8390a20e387d4164c93622fb8765630b1b5bd8e8557ce4809718ed3bb73c53c50f1c70c2f4a4511d947e52495ff8b8019354445f93b89fab83884de0c306ac4d7a2d21847077cd7ed480fd125943ca8bf9e18306dce8186a84ccd8c13212851ab3e0a2272931c82c416551d240b1430d59702986d6abfcf70c41e9c51874a8110b4e459219a9d75cf72758a8010b6e75344c52a6e41eabc62b38e1f527b45e7ccb9e0b430d5770414da9c896bf2b06b7157c6f1659fa9e55f28face0e257084144ea5bf09c55b03569432c846de88b2ab8eca0294216eba81b4a051b64c648769a6dfc34d77109811aa8e0f5b44e8ac1cff2f9478c8370eca9710a7645c6cd8ba233342e7c8c1494aa610a3e7752dee57c8b399dc610354ac1e6502a8927350bcac73cd42005df159a6388aea87aba35d41805efaeea2198f47cf92d68a8210a26ed56a5e5e46d691dd60805e3aaa6f9d53e3540c166f178d27cdcdda2c62798bce973507ad74ba9c7136c9e7cd283dcd4e804e71233aa44bfd0a12ca8c109fe6d3c27fdfb20121cc46a6c828de6f76d3aed4454870b1d61580d4db07dffb9419b094e78d69ea9742931b939b42a063530c17a301df3c70fea4daf4bb021d8764848a633420d4b70aaae9e63142537422cb750a312bca8f98ba81af364419460ac430ea62fae5aa831092ea4cb9433955fccadd790047b4ae8f04832640bc2ab1109c673ed8b9ca06cd4cf1c5acb831a90e0afbb228f0e41dd9258e311bcd9b8aa988b0993780d47f0d94386beccd22c4ad70836dc4f07651d32a10623b8fc20ef42d59563c721e6801a8be03ae7c5494a868fba48166a2882cdcf5a9b58969e16fc070347f72916811a89602c2421d2d4acaf236e705003115cd22023c70c22631138e3a2c621f8ce7b4994d68a212b65085e23778f2cddd933a61405d42884f9cd27082183493381d15b83108cdc284ae4f4bb210779d526a0c62018c929df7e754a923e6b420d41f029c2bef2b90969a5d608049b3428a549281b108c5ac664b5ead6f803dfa731dbe990fbc1ec5e55bb27cb1a7de0b49bee7ade4e1042abc10746b48894d56a4165f76aec81b37613ab7f6b7d8d1c126ae881ad4a6f13cfa6b684d40535f2c0a778a523a2f7d608ef0635f0c0ad69932631ff8d3af91dd8eecc3156d96d07264b0eddcfd014a1461dd8607282bc92acf59dcba1656450830e7cd6c5a45d42e4dc9e9f0397eb94ac499e9d9bcb814b9b344aee7890691407b6ec4dd7f78dfa2c7138b051d34949195266c4dfc095e63d91e2686d44ddc06778528d1ce936f8b731d69a8f121bd86a1d393a5f7bbd92d6c049c8912bc4a44d7c4b6ae0e32569a93508a1cb4a6960359d8bf6efe7cb104203b7eb163347d252223f67602c47d2bfdb1c3330e66e5b1dd275828897812b2522932599f44b78c8c0776513ca3f6dfc0d9931b0daf9b2978f0eb14e2306565f5d6f57fc523313064e2591d7bf3ed7791c0c9ccabbe165ba52b4e80b4cfc1b61315a1ce99ff50297d466536eb92ef0a7dff6c13ec7acd4728193d183f9a515a13f64b7c086eda5c62879d2a6b5c0698aa2524fa259e0b76b6d62c8799983140b6c348f9f4765afc07af6fc31c7d3a52cb4029fd3f44893a0a24d50abc004212ca7ec954ac94da9c0bec88d39a81016c934054e66bc1249e74b152229f0e51a4183c8a54382320aac9b8514445fb9a832a1c06da860aa2c9d89d69fc09932adaba43b81df51ba62cce1e9d3a8097c85901acd6702a3a642be3caafde359021b2fc6603906d9b7a612f811b58ff9fa25940476336af85eccff202430a24c9608d9edb45a47606d2f7e0eeaa1e349d008dca60da57ff222b0317f478e9913811f573f9554fa29350e813555710f293c21307a27679f9c267b8c5d1058d5ca9072b4030267ef218b12964564d00fd898e29d2afb33a7d0075c6ecf65b2ca2fa3567ac0e9602a7fe2a4f080c9a93b9a49ba3c95db0ef818546dd7064df144a603c6bec2444595d4ebb11cb095cb4a72f6ce66711c7041cf7c736faddda56bdc805327b2a434211bf09fa7314f87906fda1ab0935b47ecd574f4b4060d38f513aa2f79c5b59c053b6a21efddc9a8db952c180f12e26de6c7b87e2c1811d2858a9be9939081052f31497c2f9d4235f90a36bbb3baafe94a52bd2bd8a0932e765d48a14c6b059393ca9a83b5ac60fd4cbd0a3e4b08376d49a7cca2a30a4ec5dc935372489b924d055b7d49988e39890a36861092734eedac693c051ba92208d19ef89f33145c0b6898820fd26209095ae3dbc74bc1fee668427207d34c2229f8d2f9d1cc64879c9a8d8253dd88792354be4314fc6810c9724d3779c943c18b44fd4e32dea0e0a2c5db20ba235d2bfd092e7708393c8614c26ae409763be4ce58163a69e67482ab144bef7258999887138c6a93d9e4ae4896acd9049b2fa6ee3e32a5c78c26f85839ebb3c61e69419960a4efe51482f4d2d7c18449249172df622ec1c9143cb3a6a5aaac5a821149a925510a82e07d726b5ef2afa0f94070266408f393f963ed80e02f89a0a1f4d286eefc819164eba15ba134c8f88109f69e3a338d7eae7de0542da7de562b9129c6074eb4a63d95bb228910db03233fc7de4fdaf4938e1eb84c5a73c84fefa0993cb02ad613634af1c069c72da59eb9acbf3bb0f97c82767fc60eec06491b5ca3d8491201831675e03a8a75e79c2157254d07c63206a5936c9115f4670e8ca7ca206388460eecd686cc263c64d17be3c0dfa8e6e63af9164385031b24e80f2a47c9667dbe81b549b9574fd44c65ee88e106f3fb6fe7f70b2e8e18ae23dbc06ae44c3ea2d3a7feb46003934efb95fefabf3f79166bb1063e8b07f3ed77b38fab811321e58a1213d1917e1a98e42243772cb9a7bfa381b7092149db889a75e93370417bd0d4694f3b7333b041a8bc1a2f8bd44b3965e064875b2acd8999364306fe4ec99222bdbbbcdb31f0b931ad7c6442a08518388f563fc294302d790d037b22af629b0c4174a7e4d04a2dc0905a7c818d18a225a8e4926397fa85165ec01468d1852b560c92cb2aa5985482a50517d2a5ca936184716e145a6c814dba6b9fbe628f086e0e2d1c8866630313b0b1636c60021cb05068a185d3220ba605160a2981165760b466cfdaeaea6b8bb50019066861054ed6d85dee5e5125ea2ab0de952e89f85a323df4002da8c0569508caebf2efd42b052da6c0ebfb69a5dfd96b74a5c008b541837e8f16b4a951e0b3e429b5dd5947d4f5042da0c0572af51aba792d9ec009a54330a1326f94667368556d2079181ab891650c5a3881b1caeda7164f4de49bc07a0c399e3909372162029bdd2445123a889ae812b8512926124f25707d2bb12cc34f021b39078bb1d4048fda2381efcf9e11d7fa2370595a7a1f9407f5593702ffaf49e974bf6b99ee2270359aca6dbcb75a6b22f0515f84a5ec8b7eff10f8d29f6ba38a84c0c6b21d592f9a93dc04812b619bd12a757e3281c09d4c3a7b24d30f98a0397ff04a412b7dc9077c8e7977cf54520fb8f748f5fd67a1829e079c1e57b318f1be436807fc4911ef5c121d305a2cde955273c06e0a1952c896d702075cf95edc4b934ce710a4c50df8ab7c93b694bc95dcd1c2065cfef71ffd8a17f276b4a80193269824cd7ac9bb375ad0800bc1268594de654a6d66c107ab7849c8989105dfd1ba946c9360e9df587097b935686adefebdb0604f8b8b77d03b4f7b5fc1267da3b39ff0cb5b5a57b01a74db238af58ad0b682cda3fa94d0e21f27baac60b3630e65c164ac28d255b0e1a643f2dc54f1185505576ba7b3aa8d7e8d9a0a36e29dae1ed724ed525470273db55fe490ad969e82b118628c94276a0a2ead56cfbb735ff452701e528a112dc7cbf9430a2e4dd4d39eb37b8898a3e02a2fe535756ab52b290a2ea58f299d122ae2d6a1e0ae4774c49c82f60c0205234a63f013fc089946a8969e94a3e8095682870ca242ec049b3f2775a2e3a7d61c7282cb7173b668fa4e63ea36c1778908955384741e2f9a50d2c84efe37964cf06b9d930c15b1eaf498e0db43ec4b37e61fb376093e76c8912442fccaad5982d1c8ba5582df929a9ac3cc7d45a3042742c42cd974c658a29a04a34aa62043ed2da8b52451b220e3a75e5224b8d6984bcb74a9535a48f059e47be8603e828f29b2950cd13cfae8087e35457d75e27b758de0933c53afdd63ed298c60a4879c91b2bc736364116cac521a74288b7944882238cf9932af3289cade26825395af6a3bc9a415728a08ce377656804330c9e42695f431c5c43704972ea69cbadb7527e71482136b112253660eb23d842863b0b89a9b6206c146755d13a1a729a95410fce994d74d9d8e869d81e08465aee6d1699f441010ac59778cf92b850afdfec07936d7bffb2a15acf30393d44573d3362de84b1f3899f4f5f8ed5e755af8c0b5bad5e40bd97e54ca1e38bfd431b5edb607ade881310bd3e6eb77af21250f7cda969cf8e9747a53e181abde9cce844a4d975377e06ceb742b857765b4ecc09a4850d1939cd4b2aa0337d1dd4a3bdd4a448a0e6cb699aefd909a03a327eb5637269996037feda6e63147f41ac5817135dfcd6295f47be0c009fd953d6955eccbbe814f4a081f0b4ae77817379823c970cbd136f01d5b37828a101014800dbc29fd418479148976af81b111af0a3ae389f4d4c08a0c7da79a9a543594063ef44ee6cd29b134b268e0f55465ce9ef9b7ef33b03af2ba479decae1833b0d53157363dd2b72b65e02b68d357593793c4c8c07846091e54ea1bbf740c5c9fea335da23fec1403a7424ffe5c4a448b2ac3c046cd1959ccfe4566c0c068d0567b4104bfc07586e0f182bcc02599428a88f9eb02bf751593d2f47181b3a4fbb2ea2d85e5650b5c65fd20d3a4ef85a4a205bee295d41331bb4c2959e083e5f62fb10d8b55c102232c8ba5ce26bb0227b3d4fdd52651619a15384d1fcbdcb2d9e8d1aac08d4833952fc92a591915d8da167df7a4a64c3d054e7f571231674b0afcb6bd8898c98927ad28f0f9233306f118a3490b0a9c485c09b9d3e94bb39ec0f5c79c325dccf3f5ca09ec579b664b3781b5d12d66723386f299c0a9f79026ba2a33be043ef8a4281a456c728e12b898ff944e891f1e9249e0a3889853c7cb413f8804b637447e5fff09ea1d813b5da739067d79296604764c453ce6a0725e844ca000456037d4c9899e2775d7446093d0bdf5214534290e8191e32124a4f6244d6542e0b373d404d3d0be292e70b818a71e508020a0955a52ca2ac1c3ddd328fdace06b4105000277a2471c42017ec096674ada92bf55aed1d1a0003ee04e64d0a1f35e6efd0d0705e801e7a22663c7f1b8800b0dbca0003c602cc80c936f1253e5ba450e0ab0034e9dc64b29b5c69c357643074cbc8b41df69ddf353b7a00039e02e549b524205c001ff1d430711537c741670e1050e34c60e6501175ee0f03f0628c00db88b1eb3fb4325e8e5779c85c059060a6003ee227e964eeb9492fd05a8011be2e94f5a2359f20d0b4003aead455e8a36d3eb3139b494371815b8fd9805db29e6383abd6e0ed5f9172b00030718626091057cc8828b933d66f4ca3e69f7c1b1e3c610e368a0051fb1b0ac7478081e3432f880051f4b6b8a93ce7292267a059f49a72821c6f6c3157ca5c66c6923ed06f9b582bf2b1d2a241f3f58c1e6a86f4274b86afed22af88f3c42574cf1c775f4a10afefa46a78e54f57ffb2315ecb95d7896d2ec6b3f2a18ddac9b60ca7d349a4e510ea6378a6ade146ca90f1643bacd91d4a8146c5b881ba6695dba37a4e026b5f9dec56e14fc8d9dcedd561105973ce8cce9db534c950a056f6a5f5782bec9a0ef0728182147fe5f0eea4f70797793fc623e3fa1798289924d4bc7ddceecaa13dc7a2475f31141098f7c7082cd223429996983d2b13e36f1a109bca13a3e32513e30c1c5a08386c4bc5832dac5c725b864ba7372fb6b89d1cba159a47c5882bbfa90548a64f5163f8756a9faa8045721b46b497dfba0e91c5aa4b6bcc1f8e21af04109ce638c28d174ee9849e863129cde04914d968e24d88a112346bf10178f5d043e22c1eaa411adb316f7ff3e20c195da7595eca08f47f0df1b838cf963b6baa00f47b031e45831a51311a34a1bc1bafb687dbc5c9bc6c2850f46b0934c5dbca4758c41868be02ce4adb4bd493fdfae08fe43ab55501ac2e123119ce6fc1ad48990d32d09116c12c1f7538d8cd4f71e828dd949dbfd53cc0e1f86e0b4585a2abb0d19ca367c1482495ebebe6fbba5806fdc08c38b84868f8c7da8a4f024e25824100883a1703810808102e603e3130000000c201486429160248db465fc1480034b2824443e2c16281c2014161a8744c24028140608038160180c0884c2e15048201ccf84bcfc23fccdd9b69cdbc999e79ce7382bda9ccdcd90cd990f73c6dcce96250f9f0356c899d94abb0c693383abc7709596ce29ca2e9d82b9731b616f895c47837bfccc3d8f7b0ed169fade7f1c99303dde814deb1166c45d17335dcd2866080662750208a22d4acfbd8604ee0af7cbdeac53946a23355256678910c3f65c9854a1168be89b326a1661224fd6afd2d834fa7f6ba163cc780669085c05be215e24f785c3c2091c82a5b011009d7eb9d6810d19965687ffc01b79050cb0f5b5b7672bd90d49735ed176c4c29d8d26ff6656b1e3c5e68d6ccf32d42c88053d878cb4d89b356121c6e908fcc0d1bd5cad382fb3b985f4189e1093ff24a0eae6b9fdfaa5c7a996959b0743986eb3e77bfe4605f12f85557bcef57a853fb8c2e504163bad26ee3c3ea29dc52ec3ff66161d54e2d4b1c5b3e2b1d8a8fa2dc1c74d655e42884f4d4810f3bc45686720a124b49317bc4b00dd21d03b6a1336613f500a90229a4311fc3d17d50eb0280a5da010519193d28dfbc28a775be808433e704c21984d39b0c669aad8aca0c5806e182d8d867bbadb9df3cc3f86b525e4119e3efb0c8d706a78dfc143abb1fe5c0be0c2c521203af53ca677c9ba39e3cbeca9f2bebc27be75013e16e90f2092a199c3f5820ba5d5bac5913d05fd3d76a36e59f99f62c3158687dd53c9fd0d0f09e2b431be040f1436264a3ab96e5837d71dee86d59bb134156ffae571f766bcf11e8cf7cbbbf24c79a93c40de9537d1bdcf1cfd78a3c48f9d5008e8e819fc591a6ada7061db859d298fb06cbd5afe4de88881a8bb791ade8ab79f6fc28c1d2a15f31502527a13e44de07ae7b742f73c0bb357ef11f662e12d4432e6e2d6e105279c8059942ec486ca86b68539070ff4f306dbbcfb8c7f6469779a9ad6d6e460e0f52feb163274ec32f5c5b8c9815381b6604c5444de1d710bba30f9860b3a6929b90bcd9de75673efdc656e3f37b43bd4ad706fdde56e6f37843bc48d7add0ade9271a6ee3e7ea8e28d8a169d272a257e744752c67b9c5f0aee9cdb39a6a5d6a90aa9876c593a757dfb6dfecde67b6c4b5627db17d51a7852e9d76d7a612591324a962f1a4ac820d435cb2b47c6a3885148b1210d1152344927471f21a5202279479bd1ecae196a8e968b5c85bba4161d4103d0b8457b982332b1d19553c8189acb7927775e74317ac0cea48f51a9c552f9a8b1e799c1364f4e29153cc4d252a0a897a4a537a33a6f15869f05fb91614864694b76b2e641ce1cb30551477508c0e4932148e488940265835ca018c424be145e26d16c32e43082fb265165683c125a0171f9de345d0d14722bf73ccf4b5eef8122d7d0dd48bb5130da3845b20b0ce1fa21a9263f386e59ae48006dbd0dd2fb4101030163b313ad0e806b7b9135c8d4e8b36d2784b8b4ecba2f7e6fbcccb7bc7e71d0cb1288cf4d76b2f0555c40df0435082727b1ed7296cd0a83ba6c4df8d4210763e4ffece9e133f723b60a90efc57503079ee3f01ea559081746cad4dca70c00ea7d8b58dd8bb06ee401d05e25a05eb73dd78d934ea15db7a1745097603af90d5070b4aea9f052948fb361c7552134e496f19f0c34dbb77ce8c0d557251e7cf83215a122f935e5bc50db6d668269bcaab06e8297114998b432c92ce1d823e6783c1aae200af5ef57218fa4fdbf9dcbb015d3dec5fa2e8ab104889334ca906cf1b43a385ea9c07b2c09dfba501a262c88e36d4460cf7c4c3d4c0552c389c1010e92b78295a6b1e5d9495c0afa9a342b588eddf8989866462f8b5b2440cd9061b5c69132b7c48b483c7767d28780369438019d780586ca75b854e7d910baa21e6ba3e173eea11140c9b570b904fd41ecc560a217958c710becbd45d5389aded202876af974244a67c73952ad23619c2359f59b6dcfe3bf27b20851dad1a8b476a1b437443670d596c9630e547ff648a3749d2e00722ef2c6299394c8e993409bcd1d51553acfe093925723dea2900c7a55f6702e5f1f0a5cb3a2e8c8da7eaf2b330320861109db08ddc8add9f8b2359bb21ad000cf634ac2f598b19572b5d7708f19919632f6ae6ee4c0193252aba1ef3f8d4c441fb35297b165a611137747194e85e0883819076371a71099cc6adf9bdf4987f02ef182fae849bcddee61fa210009f1bcf999142eb03226982cee916ab5b02d44c8638000b246e30d3df95dbfa1be68858ae49e3fd0867190ea866edc860df2691ead54994a8555a2810f9e03a87b8adb40b4b81bb791cf86d3baad762f010aeed10190c80f89f19d2021873ef935831249264f3377a1dc9c5696c5c95484ec51fae7c0ed7a521bd037d182153ddbb0943d6f5440c1bd0ceca4fa4256974d0162b8b551462b1798ef7f3d5d5f44ca9d8686cc723e80a2c24496afa0f1d15133b6cc24fe824cfcb0e117cfea3abf962e31cb05af36e1be6dda2c07ec38d240c0761465fa1274c1a449b078c7b17401a5866d7a3468687e756852de462442d1c01cffab5d7f9e8b21c98e0b29fb214d56d44b4e6d41485d8d840ea2496a5dd51c30814c6f83c87ada6c8dd6980db039807197050b388d3433f6c9168949cd2d6bd8e0a70f29b7535694a600fee9b95fe98d8f1a6058cf8907852b3ef7ce25afaf81217188683c5459a21db11b15543cfeb47038fe752987062bd70956d0fa79660bfe538c4d10506ce825ca1ec9f18ecfa36c6a13045040410b2442bd5599307717502e0e697eb016517d8b090b497808392dc5c5a9bc8bb9d83fbe2f26606ab7520f9aa8cab5345cef62ea4796f45b325e6350c351528a86e3341311be125464182f4c566fbee8a3685c6452dec82941eb71c65412a74d56baadff13ab9b36d9c4a1ee4ab0575c83e8b488d15d9d3da1728f98bf1c840d621ffefdc294422da4424ba5e55013bcca5d07a3841724605c56df971d060567a16871405fcd63ae10619c3b8a9cc4f2eb4f6cd9182de961267e1278c9d59e06d00f5ad3a38fc3f19846635b4ac57707981c1b374094bb306cd73a02b7ed97a5d36822429e2c784579fda9809789b0e06ae0114ffd2da224e36f20126057b42f015905e4e28c09a4c915f4e2cd73f5ae06e0c45fe7bfd04b68f4267c235863e814c442c77631c9f9a34274e0b1655836d63fd7febf448e5ecb4e9aa1f103b0aa1bd456b3727e60278f5587faeec1aef32fe58362324bd29f6e4d061b7a9535998d0965b54089746c243fc63d7214d999f9a7f864c94e08ad517a298a654263eca4912262adee08a1b85a85cee0b35e8b67ab9c8e60216e5a5b67aef7004410477468d6126bbc8a81240518a7332a8a205f5dada0225f270174a03284325868ff7e2e03d05ba1b6f23533bf0a2aa8b73ed36dcc197ef27d2842010caa5538c60eaa81338aa1a559043f5658963ee5da999ab2847181ec470666b9ddc796797f29e3ab2270833f833991556e4b030611163d0ec60baac74a6faa4fcc27c226b87b2700c9e5a6cb4379bd3aa6b8cc9254b43eddb05e61c43ee4a91a1311891fe33f358e8da3178d6b49eed1ce3ca810fc8f4675039a7e6af4340a0e8440a270e14efdde9276a19776a26df890ee0ae41030858a7bbb4db02d4ea274cd846b7151ba7449874a4c410dfd89112d21f9cd127049c80c59dbdc98e8a95e8d72bfed25cac77c01ffb338001e970f2beb1e1a1c812977ff27238001b4d8522051521641e1e23e3480896fcfe198f6855ba8f995bf1a80e8bad7f4adc6143967bb1806abcf8e590abf26801b2244ed42b22fc25a3f248712961bece57c951a7e6485e4e4553c6ca8e61dabaf409bab6bb65cccf867e69054d0f621b84066e0f219d3f34702d9aa420139d0e421509e577c275e59fcf874c6acdbe1a741a6102e9f9464c478da4f748e9e83c6c3853edbcddaadc405b6e3a0bb8cc7f1d1dea915fc142bb8868bd9366b852fd7918f263e359a32d118704358481daf2149749c8e0003034d731cc498f0963b52301352e8d97f3528518e120c98f967812fdb5e7f95c63f57ee74bcf85af6a46e4d019e8a4b4318db5023c221cc603934afb720f8d4dd6fb2ed54700339a87fdf43379ddb237eb207ae32695bfdd68bfbc8fddec44cb117b95a286d37e49eb5ae809417641b0e7ca3fcfe6c6eb8ff424da114e99c39f4674c7c55376e0864a7e7ed14fec299d727f223e655b7caec63ab0535a3d14e349cd31247c70b4f472f4577851691f627052e77b25932965753d54abbb43e051ee0082c9026c74c450ae42203b2b47bd9c6880c284a0530edba2796dc8962b62155ad3dd2d6f16cd0e7036dbf80976396180a58f54e25c63a46b57cea14db74d96ab12d3c5e754a7e3991a0f3081a5105e3ded0cc4f3e83e9522a11daf3d8876f3b1eb4da137463fac6b2858bdfc14b1dcb80d0cc2dc3ea1e6c4c21fb0db448df5116580b6e05c40590d9240cf3521a4e8c2352f837302892e1a94c834369f51057c6bd385d786d3c97cfa524254632d407bf81cab69648308f9bb6c81c8b1daffecdcbc1a04c040d53b12e167491343c9244bd10ff11e5f2049c6a3621a5dae536c88de633c4556d5253f9d170516d98e0d5b654e72527d520aa0f16ad7903bfd25a5b1837c20d7ee24bb6e640e5cf09d0f98883787fb0cae54ca35f87d3bceb2f08857d634e990ff8b2a32daff820fda3a9423459f74c0e662ec0ec29b68fd39ea8c840160a94ce98cf1dcb405cceccea4317f8c473c0ea007198e6880ed9a8fcf4a83c2fab7ebc7be473aa0136eec07269d701849a0563825409352a3b0104a167275254581b92f503b8c2ea8518f386c8b19623ac78d146d58447b1d32fc08a355c93a9e77e16e99a9ccbff2593a2afcd7911958e9c2a3aee748522a3927e5e8712f11214ee84a11aa37e3a19365e9fe1746c86a377a96207a4615932a55eb100ef6ecde046f73e6a2a5b309e53ddcef26ebc6eff80d1e1935d93590974c0f1464dadf78ac48c95ed67f996f064bb784496ccc348cbf448aa313222be76bf78f292e4b81c1759dce6bb36adc3548e6825e20dee8fa622b0991e17915b8f8c1fdac02257dccc73dd8f002ad3061af9497b795b4d80b0084f9db04fe7247c9c0ffa97804feea0a05bd04ef0a0d7a6287c003033e40aab411300e60405b63ce460cbb452481bbc0e7c4461c193649fcab96ccb365aec8185e03c7c7cd79c094ca87856ea12ddc224fe4a8652c8a4b7126d55c0a6b7d70d25dd3b9e0711489252245dc9bda42d29c1290e7d5744b9225d4b01246aa98074f3b4c08a8adad3d23eae3cb180425d25d24e5ba7fa1392e3c45e92c7298e5a96ca3a719510ea523a78bab45a4c5d484f9ce679f5c7e26339f24ab053759973a37cce2bfecacb5361c0c0bd66a9fd3105b61f8e6837a87f8a2254a290ea10a9fe2d1aa7f228595dd2fe6f670b2389c9baea04359da53f024271ef25fb93fa9aa5be2662a96fff3e7696a2686435b2fa4a152f89a0e49a7cada4b30ad8c48fb003fc8158cfe90d24b314a0efee034d51f831a85f8c61e2a596954d4d70803ab3f3ec1b4d73a4bf8e55ceff43120e5c184d88d16054f6790590ff38ebf95f2201ec106305819f1beec2b43288995be639f3cd3cdcece819ead019ed9c7ef93eb51cd0d6f8f755420932c72769ce1c4fe8f14356b5973fc67714335cb4f3ec88ec299de90970f5dd73418865d253dada3aed3f96b829bf2284bc8cebe52c673a8f426b1888e493ff4cca36103a1009f3ee2c537e14fbb89d81313347fe8370035d514c86d40bcd159683b6053302ff9c96d679a30d68f33e669c78a1dccb4f0320df894e9a9b54f462d27ec08834efe3e400d221869df9cd1c220c1d7e235636327b4cdcc1d085beaf1c2113c30cd4e495f32e2bc5cc99d1bc637da41ebacdb543a2660bc70f20e9df33a1ad3566dd64a21b5475efa082e88b0bdf3721601ecee0025e3dc4deb67907de0c53efef0de38b020d7a42e71d4c8898673d0e1125f36859e1f51c1c6c185c7eca1c289c5848350a435c048cafb790486545e2c1e61d0c5e7071b13e7363184aba2434849911e806b327f01c4b58117ad9a256c56112184b25ff1187f54210d93ce74256f0f48ef5393044dfafb6751e71d80bd8822b506472b54caa1199a8817f15dcb0165e31a1a9039a00f9797536944cfbffb99801671d38f2e91e39a4efd422a11d0d8715c17562f42613a7461f90e6c42f9a74d86309d63c1c4e4877bf145f5a7a25256d64268cedbaf2c7661ff060d8207405e31db6c642717a6316b8cc16c27e944218dfabdcff02df4ebe2e7e7165934937e983215e16314a0a8d79cdcc05286cb6cb894de0d24c0069a9d852e14bcbffc6077234a2366823ffecb7f598eeb98c6ee7039c5a890baab20df2a49e4b2a59766d26480ac8330726356198778953cdd4b3eabb5400e8ba341271c30578f3f7a18a7a7d6dc6837beb0659bbf598dc4109112b7251148c97a06ec0dc844dc50f234e5258b828d78a6f364ac3261e2d2a60ba478c32af82743548901490f42eead5dd515a1f97d7a11704265f15fb8b7af19608aa9fe8509069d66c172e09f8291af272c3effcbcab6ab9fca97076e60628f93afe921a0b7e52b3748f14d5e1e3491281a5621d096f04a066f9fc2e306481aa260acdbf4067db93ca7a3f06be8e6a61deb5a681befc1d310b60a86c2c443a03c720aae06a260ab51bae780a53bd0222ba3cb4f927769fc084178f13aef04b12f5d1f74e43c118a49a0d519508a115f5541c00fc904813f3300135cb35c21c806ae3ee9111634d7f9d8f3c5750c4f84a06b5f3c9e8744444e590137f527afc65c7a02750d0a08028c3321594737515e0235dc67f10339f949467c24a7c3d7e21eb99a524dc37867bfc1af616ae3613652010d5cd4d05b67e0b2165a472b8e07e0f35a4914234747f81c67fb88684cd24e66ef858f545da8249b63525d37ffa641c20c5d6bc0c7b14e0d3155cb7ac6c0c5bd7955de2430101f3daed09c603d7350df9f4c09a813579cf234f9feb00117b9507bffa46135451bd260b384aef457b1bfc377943099bf87753ba518e0a2795d583b017f217ad58e18ab08ef3c2757d81348959b1630a97cac9c233790d84ddcbd94a404001295a34115cd63ee9b6201c79d720014110c08f40664d240566c2bda1b5c7bfd148953a56a4f16fe1fad1a26eae501b49962a50157555bcced0460fe98e3ec22c20ad98b7c8aeee7c284df811bd5e36d021a8defa91af1177e25391ebd5e27a6946184ecb8845aaa2951f2370586cd6cfa5fb55a6b6f9539fec900388af9224beda6a9c2c8bd12d56f7431dbf5a701948eee12f1a36fee9997f7d1067ef4accef88a92088a254f5a39287927a0af24c43f9d9d54bd043c404182d8a7eb26a7d6c5406cb700b7b47ee9d0f21d5bb3fea7dabd72a92a41f5b877318f729aac74abe9160a25d123c13af47541a53479e17158cbccdab65970878ced3a0ec1bea7c997ba7e9f174d73bede04133368b3719b3da7b199f52df3696e6f7498992c79b6561aef1ca30198f2338862f1df0a60a61c10156025dc54297d3ce78d848d3209c8f49b24dd8a036f7e6f96b1755a8a19802e735a6fcac53c7fb899137b083b22e5edfcf46521b0e6530995ee7ae497010c462ac6d2ebb119a04487be53dba42083180fea1454b32bf2dc165dd439301729c7d0761e49dea2717f64673411f439057300b270c39fb61596b13d0c10ac48a4cbaad4a80c7ce6e4f80ecfb72a8504071bff29f75dba42709c43424583f4f57a6390c7ff28c4dd06b91eda67e497bfe01a8edce4f93f612149436c2368c82bdf9b7426716ac4fa1cc5e176126f9a76516720f119d6637f51bf27e1efe978aee0b513920d151fa2928031df16644c42b622dd6158f8274e2512872bbfd6feec1e0f4215e0995db5c179d4924bd25543a7bf9906fca12504fa3a394d413a56ea2c47a4d492c343f1e5b2f90241e66455d70d44a01b214061f6f862689c75bf0d80b1ed54b150fd5be1ef1757fddffc72716ba1fcce9a4f62872cbda99d3a80cb7f213ca5356ee6f36c016c52259fffd302f28b13cb23173f0aa0030abd1412f6d972ff5590f8d67e45fc7bdbb6ef9850e9b93b40caffdf968b97165dcf725c360df884d2810084e85584c8374c4b5c6f59b75c4362bd01d2ce02d2e8c9d662b640b0c0bf76641ea4d0b637b0a97b2e958f0160bdb7b17062151805156602f7013067b7541e85119467240c9124e239861246fc75108cc77596c5d5e63b143916f5e221175ee1295ceda8ba483f321bc5c275aed647182b655a0311b7fc4da579f939bb29e154340e7468adc46f198c96c64ba9e3914954704dfd6f831cdc13da1f1281a46879db31a3a5a9afcd38ab73d52521ed4a191a7df8d845c3b2b4fbc06585c322c4e4e0a2c48fe3833cdc6818b6f02ea9cadb61619c8525302055b594db7de4db4ded5b1e8442bdbe73a756c65d56d089c9535301867813d5c8efce87f78eb745981415a0963208730d204e2b912d1627c7a48e4163aec994d160e678a7bdaa9ea4e8659b924114cc5d9270d57a6e4ed1f34dc5889846260fb2b16420688ecd0408268014ebe2600eab0f03a790612183687b195f9f6975fec47c3146a7f816d1d1b23dd610a23acbbdf419c90f19c8f7028fb0f3b1c9a64a25cc2a7944d9bfd29f76aa05473cdb075de04f6a1ef2b809d816080d885c6036c25f7d26f9e903e1c18d9a2c690f2648d8bb050da8c4a2e310a61b3e61f9cb08f7fc46528ee248d68174c490fe837129014ca4e0ec3506b9f0efbdc38cd5b39be743d4a8e65d5063c1a880685899f465b4784a730b496863443775f0351153267d71300d5c79013346b800889fba4d8ee1512c6f92b317e50d753d76e4c373c4cc2e10cca8ea7c2c120471e93a32de5842ed50479e062816ac6769f781a2a47fd5d25b9dd7fed580f473052298b8770e50d566d2f9c0c8ff2aa036f7d6a48a1a538a6258e581a5f0e2cbd3fa9a0249c8d6122b60b6aebc811d2797b44cb80ff27825e2120ceb43e045140449c346dceedfd4f5ccfbc488d65ed8e282522b6b2946f00fb59979609db58ea6d03c2569ef1a1340719cf51190368b557ba40fe7e21711349b696b1dc0012241c428b9420b7c8811f71c35648c9da23ae92f952f8226a848ed611deeb90a5e209ec843d614df82dbc0a3fc2acf05fb8164e0837c2c21ba24cad43042d08b6824f43da41fe44ce9a6bd66a111c7ecc8a84100c0990f481cfb0b0754382a2fee9bdae163e7f2c24072fa4ce9450782f33fa58c63eb75bf7e2c420476291243c88091a2908a405e1bb17f54f675d08ba7c96204fb097dc26bae259b41ae333a5ecb4be0415020b24eaa09301498f69898642326b1d2aec9755f26846ee8cd210e5bd491d26f8cd808656e44eca690ae33e9b6882188fb299327dc88753a326de4eec2913dc8e5095d7dcd963872dd4e95cd56468a83bf42586b56803cb0063cef42b41c5c863e691d22102acb329ea2d47f5018fff59caf96ef219e525abd6a29599aec65dc650b04c327c1f454af352beda3a5e22ba32eb0fd7e44d34fd07b5d2b311def030f7caeede5acc3eb5536a2242406faa2ef235099680394da385e27887c3265959f760f80980c611fd3a9566627a32ebbe6a165d2c00d84aba57944f1ea4cef4d592179623fad97d2880e600e635311233b973952902bb62b658a7c5184a9b21b370b8fe60d56c3236b2a00327f4dc556746a4323b0d17559d6fa49878230f58eb4d01f3faf44d67e5009c7f33dc416c018a58c551848797444988cfc275a8bd2da85a363b0a366d9a52086722cfec3b418f8d4702f636938caaa574259fea6148382440c79c528fc09190b0edbb0b9cd02c8dec1fa66797405aba8d05a58328e3ce3b37804b24300a9f3b875a2d8345be2d0c30d9e2e40a55a5e0760de9f02a66299116412797f21adc770ee9c3e5edea62d19306284a0b9fb72c65f5c1d14b54ec9cfc9a5080a5c162be5c52eb15930cb3faae303323fdc3ed1780bab1721fa05c9b72dc1e01a1c55dc7bf16a804b31c75b800dd1c6df8ca914b40022f0b26130c1dd8083c79fc546fd6f8eec49113e4ace29fe1dd1b40a255c412c0986827e8ead4a25d0b36f993f9e187574e9167adc002ccb28fdbf0f1643a3a91621fdfc0d7e7de909600e8d9cea1b92abde5460f34b0d313c219a13d62137338ce96cf2c3dd6c07601270d178d1d95e15d042d8ac35a5f2f0aa294aecf4c2a681fcd1e92da2e6b5081f766f281bfc4d27af3152b82f1b1427a608da3dd2751b35b1c6f9ec44bd57036974ca64ea777ca0e7c14fcdb91942455d7dd46300c973166ce03631fe6bc8cb7b801a0a171ea0c086b474bf6786d7462ce501a4161b1cfec274839c29599c99eb10b2542a10f52fbecb082e9ad4b52657afdd8670043a599568836db4903b1f1b225dac8686c7fcaec5c47dfdbacf94954e506fb6013f8decf2620b111829b3902b0b1b5035b2d77c3d79ec9661378b51b25d8016c670a4cd0e68813d9933f8d024e4d4eec4ea895fdd6966ab3817a726cbaadd321f029015a4f65bf482190de98a213feb9815a65caec141e687189d56712608243c6982c7eb0109894967865003a63b1f83f84f39fb1031a1662b3dcee42e2162940d082a25bd3b3513a31b20c2530e9477a4fe9c056a49f9f5ef36461daaa946f289485470061560fc4b7bc110253332e90621105bca9d8d9b386a7ad1a675b15206daaa00a2887a7558d5e9e3656bbe83bf25e8964558dbdd2344a0d7c7ac3ce03750bd054a46fc29e8bc11d97c13cc71aae8cf9fcd03d8c784aaf62f39f438689035ef0f96ff406b4e4b98473cce6b9579eb16ec327bca6bfbb6499da22364a10312ca2bdc5b08344e0e1838797d282b8043aefdf2611f84e3d717e06bbe1f6a6357fa453852d4a6407f4f52ddd4537c6982a9e2af7c5901d2c43b1092f0b3819ef564f37a6a04a8d4d81a1fa7a346187a5ce904d719ffc6efb74deea9ff6106e4907577022cb1868ee833b23c5cb608cd7b0fd308f207e4b9491538069991c3d1e00861801efa834f6a89de69b647fcb9e648c231ae80cc31147fadb619e1b480dcdcb43b58c1cdd65e0f8a25cb4e25cea6123bd5ca4b60eca7b0a56a92c4bce58463ce48223e21de84747f308097df3686e91605f7971e1e108eb7b974b29e48a93d903d65bfca9557523a3140b35d7e12bb234064d7dd704e9e6df68785545f580356d1cbc54e2e53ada37445e24b173370a360ade6dd16cb994b1cc358c9eae0e1a2b26361b66ca45216dd374f8f9d13f6b8f871bdbb9de2445afb3b04104b479fad1779449a092b9f154d4302cdc0b02ac5f660fde041baa3162988bdbcc002de380e0bedc3323d07050045dd3c6beb68208850196fa08e75719335321bef6d8bd7a22b784f4e1712167cee0e471223c23a5c776ddc9249a5bcf4a71090dd04e188f7949481e21f33ef96cbc8c2b96db23b55f6f6358347108e185d2e4f93f0f1120aaaad6664dc4079e945f02553df450e07a40e5f8ce3ddca2ac00b6fef4e44e6a805d241a167ec797b702a0880220491597fff8dc17b098f00bbd13516c9469b39182610e92e02899852cbff53c19325697d34d573cfc48c76771155b178a3cc8e56de086fdb830923674d9707a3186b617b29e04466c919a8e40dff20c41baf878c79bb1b11c7ad855de0864a0d5b7200fddc769a6364a32d9c922c56242609419430db85a12518c273ae4f42d96cde2c90d7ce90f47b92d44821743f443ebcda91c62048588b59c67db69e7d45355e3727cf0e42ee7a87382c09f94631427b910681c5330aa82c01cdc0767ae4c9cfae5467371bdd3aeb85b2ad2ce4f864a9db95ce6d71ce22d22188cbe5b4132374ff52f40495c1e914d66e03ab65cf49f79dae419102e5c47305c04e98ca4da7c03ad1adc0ef4e3f841068dc861f24aeddb62b85bb83884f1aae70fa0d6100b6a087a25ae0098821562d46db8bac21b4c62a9d093abeaa546543429f02ef404f1a7d32a343cf94f468bc9798a594756c889aaa314beeff83a9a44de5efcf9ec528b738c7ff559be327244aadb8b67bf8868ea7a808a9767929634c99556563cbf7a72813e570ddcca3b8b6ae791702e38d793270b2426dabf358627e4d78f777969adbe8af345a845d211b3a44fb070cd139ca575ddf27f2d25f23b67d48444357ff888f60008015f90336a8d59969c005e0cbff7686203a95207121f3ec5f691dae75e29a5fb83a82d9fce81cc6e1f641d445380deb97657089c741218ddaf56d3b1c91493041bd1aa3386feef390d8f724f0c070da501787f361ea0be9914f7b08de820ce6d645199cd232cfdfd5df43f76d37ded55b4c512dead744f18755f300aa1676cf627a08ebb10e0b5645493d57ff93381ee7efa7eabca6410d49666e884f89ddb65ce67eae91725133a9cba5ccae5f4ff8c3ddd9374e14e9be46e510c54cd9abe842384b8973010117474ea30c673f0e0d6928b5ab803de511a18d851dfe4253c6ba6182d9398c2443fd5d26954fc1c60ef59aac3f7b9ba9bab19796e229b00dd517d61ba51a1ec230af124a97fd046ab2e9282a8d14915145020663b0634bb8f8b29c0a0e86c23145514597781bea48cf03f300daa13dc0c5256806f8beb40b65fa3f8503a59af32ba7fe79939ecbc315fce4f73ae7d539fc51df5c81f208094012c89023e1bc4920a3150b46439fcffffffffffffffc2836884b6196b5f2699a4d43fb65e9f93292599524aea8a507fdb7bb1adce6bb700705002370ab70a2a0b6783f633402006064ec07808a3a48a09795f762b7b3b7018c25829438599f9948102331e8d11b081a310e628ae57faf7251fe28430560a3955f2e8312999580d1c8330b9a85c29994ed23e98046112426bde9d754e218a0261d07d7969a132cd4407104693e521f7d357d7e40fe60ba2e53fb473d4b2f8c1a0f7df345674b793d70763e86041041737efed2c1f0c6bd97abda71bd6e93d184497ae9efc5c8c9f9881430f063993f263296112dd1603471e100d0e3c1872492a49b12d6b2a5d068e3b20871d8c132f3b826ea7856a1403001638ea6078ad98aedfd9a225a7834955a4eb9a373122c77d1b9cbe2570ccc12c794be95eb864acd982430e5d8bfa49b2f3ccf19a0c573150b0813478607860666046197130fe7552e3a1974fdfaf070e389842ee11d52945d7f7eb0e1c6f306e8dbe9896f466a204898101316c6c1b38dc60125f5ab6e106071bcc7d7593ef53487a13101070acc1bc9ae57741d7a5d21b047567dc020e3598d5c45354f6e3ed48c958ab71e36f50461a36520d1b67a41a957fa38c1dbc7f192420f63ab091032788230de61093bb64954b86771a69f49a064ca08292010e3498b387c52461225f83be41195380e30c061dfe9e2fa4b012a5b4c1e9b7810dfa0635920d1db0251b3ac0097098c17055f24d25a70b950f9571018e3218ff928509db5056bb93c13022fe95bca4c492c818cca9bbb2b7544c072c050e3198a3e536e1f14708cb3a0c869c336554cd4704638ca154e00083e16db4d5271d9f274f38be60f894945f9dd6923eb91a26070e2f985267c7e40f2a2718630ce50347170cbbebefa72b574fff655c000b1c5c3057906a7f41733150000213ac81630b465739bf1b09deb5d7c0cf000187160c2178fac64d9e4923e1c8827135ecc297b84ce0c082c12ec7df8591db298538ae604a5a44856eed2748638c31ac803c930bf1c55392048e2a18c73e575e388d3d1351c1246fb174ef6939a6604a634244106627cb13a0148c56aa74a9724f0d237044c16416f1da547fc4fd13148c21737f36436f434d4f3007a1baa7f3236278de09c6ebeba4d7e72618f29d0863ea7cc276ce04d35dfce533a14e657909a67abdaf0f2b17613d4a302515d45e5e11d2c328098657fb71fb2072b86023c1d43eb69eb49e490e3a828d911c46e02882f9b292522907217663250229824ee710cce152cbbe49eef0d86e091c423059ecfb750ed7dd49b5040504c3a419174f9d4812820c0cc35f28ebd2ff22ed41c55cd0fac258226fe4dd30f5c2242b2cee93887861eaf91369e3ad257476615041d72bf2a90b53c8ad203ba48d94839d0bb27857c8d6a6ed1e63d973f4c5195b3109e38db791831a4b06a100bc26cc7b5d8d7c0b835249453ce7d71686fc513c4c8749a6c5ad85717f84cc979b1626d9ff9d90d35c3ca9b33059c8b8f0105516c6f8adc94959c82657120b73b00ea33fe8242c0c3ff163c40e93d542f015a60e5a34b55baebfe40a536e919ebf9f43c9cab5c260c9266dc6dd5cd28a025861d0cabe52d12ec53dab30a8d9114ac7fe51492e551844a6bd455c3f1559292d3fe975428521dfa7a97e855c21994e610a23fb22a27fa776c9146657b3acbb5ca6564ba530a5ad0cd1331e24a94f0a43f851ba4cedcd24ef4761f2944d5d52e5a5f14561cab75a290579288c7212dd84b8bd8bb183c2e435c2528c2c132be29f30bdec7dee2f1d2996ee09d37e6f558ca4d309e3a5668d50677db23c9c30c7a9d23fcf3e56a9b30993d25b39450a61f683ad09739a8a093a6974084225135ad70861c23023f1b2043ba9e1954b98c56554f6c92c215ac268651523e71257c20c5921e694982961708965563a65ad09f224cc7e966c7410af2a2749984f6915356b3d267a244c324ab456f81bbfc842c22897bccff28ac7fff61166d1eea0ac3ea7a4e408e3248addd908437e4f759e57216c4698e4979658f2751127a1bc3c8408524598724a1059eceee74b4d84513f449c7017f4e85111611eb9172e589ce8f9218730cebd5d9e53223f7c8821ea1b359284b4904298e25fd8ab6f5d8e242184d145dac5f828a195e7208c25f47da49935152a8230d998aa88b6a022693110a6549e4ad47f29b32002c21841cc6bffff07c3ae78ab5ebeaf1ff9a130eda7f4b3de0793e88fd65fdac34b870fc6d221f7e2a9f76048fe313c62877f5b4f0fa65879a62f25793089ffb7d3e21659abc38321d7e4ce509d456e7f07838ef2cc0e66754f2289b7eb60f4a03da4b42cdd4ae12328800ea6ec10dffad91ead3207b387d6940fa2a5c4dca2003998fbf24452c943e26048dedba17f3412a4a100381872342de35b6fb9737a83f9822ef5f0e979544e6e30ac6ec9a888ccf5d1b7c1a443bcefbd9899be3e1b0c56c235363cc6f885d660c8b9f9e94ca538b1e36a308d4895eb2fea6930aee47cf1a9ffd3480e1a4c419c9ff9aa256db13e83d9a468c93035aa92d56630ccc752132929cb099532982607bb6b13e299a3420663878430a6372a5a5dc660f4dc29463c93c560f211b978fd881bb286c1385b51422a3d35b925188ea12a1b694f5f3077aa7fb76a7fc88f17cc4976bd85a958296dec82b992fab64acf3f9ec305a35795aa0bf5313ebd05e38d57e70fb95c49755a305e3a799eb3ea3afd62331490057387e4b69792d2e94fc282b1ce3ac9f8f824e2e8af609219aaa532defcceb702e2773c96fe1155c17013f594d4ff3c21712a9884d6c4b4d27fe94b5330e80af627642b05937cedd25e9d4c27d95130bb752cb3ef0a14be74332f215ee509865b8f717146b632632798f774cc12fd9eac83b609667935ed977a32c12cd721844b30b5b2e112cce925d6de3a68195109061d52e6bcd905e1d725c170fed1c727f9aa9690604ad53152f8ed9e9c1752c01130533119c170a942d07d9db37d9e8a6048c27a72ca257be3f40a208241a28ca88a91ec29e7153004a3a96895537f4a59880284604a9e7a3ec5d472134ac13088a50b297e47c0305d4af2c182d07809fe2f0cd739d4e979331dfefac224b353a530b7f6c278313232744f5e9842faecc5d83995f3db85715de5e6f279498c5917866c15c53a56f8503a940b53ef4e8aee2192880be2c214645e97e81423a8945b983dd6fb920ed726c01606196d73f772511e24a016c66eddbae461e634946861f0cefb984bf75039cdc2a04c58ce963c5bca7564611cabfa4c11722c0c631fe729fc75953861619411ca530435aff6ed1506f9f3a554541235b62bcc2dc122a41ccd3071b5c290a3479a5821ebfb618549fddbdd53bb7fd87e1506cdb8930f2a5bfa5d15c64c4d0941881cfa74a93045319d5efc42a830e9b85fa9273f8541f25cc85cd85870dd14a618e1d44ebf530a8350572e661b290cd1f6dd763dcde8708fc2144edc4589708bfdb6284c7a31bba183426190dfa1e6d2749e561914e9c4cbded922fc09935dce8e16b395728a3d614efd6a3bf2e2f5aed2099356779ccbe179d3b39c3049d4ce92266fc298b7d6313ff5cb6435618aa73aaf6d24874f66c294a447b1d4b09c53b5983025b30ed94a5bf457f412c6dc52625da3a3a65ac2e09f442e91c4f38e48254c395da570e96927344209e37dd09fb2e53909e34bfe78a6e22909d32789332af983a57889846946470d4f199e119c10f7d596c118caf4f2ba875fa64a06c3ac794839e1ef434cc760fe9338b23ea204f5a71850296c961695c530983774de5fe5c748f20383d1d2b8cee7ff0be62496e339a8a4eb6e73720ae2b36c85e5d105a3c950932ea9d86c2b3db860b6d149c731d3cdf46f0bd97552ab164cb26eaa652b5ee66264aca14fc306b2db814716d0f1f3224c23076714d3838207164c65256e94e7b42d3cae602e65639ea2468ab896580d53567858c194f74a4df8ab2c964c457854c1f8d1ffe2ab04ddce122a98cbd2c80efba78318a76010b2ffca76c7837b09111e52307e89119b76f9fcab838228182325fd9b955216f0808239c78b9e9f72f48f952798e5ddb479d0179961999d8387130c3329cae51cd63bc96f341924f06842422fcf621c030f26982485cacf7b48a3a3843c96607a5753b31234069f87124c51547c3cddbc637cc85813030362dce06d604c108210f095f64882073c9060be8e707b3a3df668c97dc1e308c6fc7cdb17ebb81c3f848711ccd142463df582ae24d2078f2218dcf334846bac6f8ef2e0410453e7aa4a975b1a824988bb4e6ff11082e1a4ee894a21f4c54e308c7dbb9643b9db48f081618a37b12e59857e61cc53162d5b12b71c725f186b3ed552c3fc92e5bc0614111dbd30ca8b0e49bd041d7288f0c2fcb7b26f21780a964cbb30d90911b4a4a02da8ef7591e75cd92b9872a1e5647fb612c7854105b311b9c27912b2dfa21c31f2a70eb3a0c316e6be9c5417fc24574a1203033d18630c5344472dcc9d35dbce9456684f6961d02968a8b78549299a85c15625260b53ce49a7d873652c4c3ae5ca93ccbaed14c2c2e069da74ce64e5f4b98e5718bbdacf7792fe77571dae30699af4371d2a3ce7dad10a434cffb8dc69647f7d32f6d3384304638cd1c10ad3f864356bdb5c0997d3b10aa3e5fba0eea49e19e85085e174e8f939c041a331023c0f74a4c2e4329f7b2c8ad0b1827fe84085a923567708ba7c63c5e544c7290c9ee6f24254ccc841aa91c68d33c8404d7498c29436fa417c45aacf3db071c6096eec253a4a614ec173e62d78e578925d1f3a4861eebf35f959234ffe2cd101d1c1758cc2a4c39d48e695547aa92c0af328e195b2495d0c1da130689c27bbcff2f711ae403b40610a955eecf3488aa1b78e4f1824071d545937de0639b041b6c3132695b835264f85d1a771e34590fa848e4e985e23453f51fe196798e0d4071d9c305dcbaec7db0f196bc4522a2303d9b10983f6a94b8a569d674732d68e8d336e9cd6343e043b681390232de8d08439f27ff220642713863989f712a29fd26562c2f4c94eb2dae9507fed1206dd79424a8f9c3aaab584aa23e62b4db850072a61d2da2ed692844cd94dad83128618579683b02c49e19540c7244c62419c4823e37fca27634d67604619356ef40cce6a7448c224af575db2bb3fde8f84e1841ed562112b749f206188233ebea894479867c4430425b28e30c6964e12b2cc8d3027dd2108310bf3fa3123cc5d2b41ae04a1e5aa2dc2a4de2ddc27e6841cd48a30b6c77f92e93a237212619ee41255b54584b94aa5646f7934d0061d87304dfe9027e6892779ad210cca2f0511b9301b3b29842959ff7e8ed157f33c210c9ee3e792131984399a668c87b06d7d16411864e4a598b33810a653eff944673e7c5e0161bc4e3aac94bef422437f30be75886a79b0cde81bd4b071460d2074f8c13cd79ff695ef1d731f4c3a7ae3734c5d7c9b3af8601eb153224da7875adfd0b10793698951e93f7e435ec618a30c1d7a30bb8952ba9245ca65e7c110d79385c8e94e2733e1c1bcf93d16376542cc10093aee602eab8a15254f7630e959f96c48899192b6a30e86a0b23fc71ef5cb693a982559306de95547a890be3107d365f5f021e7b782fa7230460e21fff563bca6280ea6b9601eb7930eda3c380231306028820e3898fbb44d77fa88625f7983b9e3267c7b753adc604aeaed6404a196efe28e3618741cf16f3a5eacc975b0c15c322a5b6a0f95f8411d6b305d57c8cbc147fb5dd5a106534e1777429851c971471acc29b376245af09c67d4810693b89265f1e2d67106731e0f3ab23aad7b3a7598a1a30ce6da8e961ef9e62fcf64302755af9274cb8ba5948e319894a5d457d9573d9a5087184ca6e25e59f2bebeb07784c17cc97b84ea297580c1dc9e6309d9d1449e24ecf8823154dab0681ee75e6387170c42f99ce890e30a7474c12caa62c988ab7570c16ce15497752a756cc124776fbc453fc2850e2d18af5ef74d05fb3897ecc882d9c4086175fa43b0bc93b156b2091d583078593ce541e92041d664dc681bdc48cb29745cc120b664bd8fb0a07492c6df60247458c1249e9752be824856e111dbbe362263ed460dfc8c8b4207154c4ae7f34a7491ef9b2103c10180091d5330c9deee284b21edd26a850e2998d2547ab31ca794fe3f0a86ddf2c841c72c31f291a1030a26a12a28efef70161d4f30d6571e7d227a6adc103a9c60f6d4a347848409b9e464ac1513424713ccee275e4b54aa850992b176b68b0e26984daaff4eb0cba3bb97e139406f63cd3a96607cf5908210da11a14309e692ffd68cdd8f5a0d6446d748c3df868d331c2f0523400108c6188334a22309df46d01e420551714400f0840e249842fc3ec9ed18255f54888e2398c37b12570949449f91fdd0610493d23616ef2f8fd277923d7414c194ac2e2bfdd9b67ae8120f1d44308b4851b27c5e8e4a7a1d3a8660f8d7c8edd194086b4f87108c592167f4ffb94bce81812318c6eb30c2e2538255489bc0010c773e8ee46f512612387e61b60a539dd86eca26cbe10b47cb9caab16ad4c0cb40a30c397a61baadf06217c6a485928c355e9894f6961c612732d65e0767d84083ecc2fc966cb764f9cea582347270460f1a0417c8c097610305638c91460e6e705217e6fd78b23d89989eefb3326ca060066694a183336c90a0ae56c0910bb3e849cbeef87061f25c953c67d3e9d3ad5b98635bf0cbbfda41cdcd610ba3951ed39da487ad7a6a610acbf38e60e1bb744c0bf3b55e165521b48fa924143866610ec26b525239fd39aae39085d9de544bf4b2da4a411cb130e8b855faf6179f4212072ccc398654911b59626285e315a612ad4ed656b6256b0e5798f4a7f411b4b3f5c511472b0c2ff973be37915cf671b0c26c2f42eca8a45444876315e66d13fa626dd35694f4c68d37430f8d326c906abc0eca4011b8a0060018c1a10ad3b6c9a7f6df6eddd2e04885f127d68358c5b67d97a83064b94f9f2646d0959392e31486590f49e280c314e6f46b4a59104ff1692e85397ad22108f70bf9107c3446200606cc18811818e8c018637090c2f8f964a8a8898ec214d4d57a5f885887958619efa2c83cd6fe509834b6d4723c670f7080c2587ad243d076291f1232d6d0b6031c9f307b780c612d2f7a47ed9e30a5bb1c1fbd7119a70c393a618e3197191ec2bde3be64a0208b15383861ba60e931c7b38854934d18437877140fe1ff276263e0d084b9e4e64f503365c2144786b22bd3bfc08109c32753b1d2449aabc0710963aa9ff097fc1de32e352c6132a1449f0877f996304725cc5f9574ce7f2ea38451ee2eb6fb6dd44426b1fa9998ee08faf693b1468ac02109e388ddd115f73f1a9130868cb8723a1f27fdcd0109a3e9f0ccfa0d353a35ce40c6f10843d2ce12ea16ff53ce7a60e3735002fc0087238cf1d9b2875ce2137034c27c65daa5df7eeafcba4119c8c1089350a224690ba14347ed171c8b30c8336d51fab4894990220c23f52585ca3825a3cd011ac57024c274255b95c389c958eb341a751a9d81b3438439c4d39c471fc958db47b7349694868d336ed80dc26883594250dbe1c43ae80f1b4c6147aa4593abf1c1b20653f64b951f5613c7623518bee3dce28abc9d531a4c924288cad0a2c198163d480b5b9fc12022e6b283f97d4a9ac110abd2fd7bd3329854dda4d86d12321852f27ca3151e4f98c6600e537fcdcf5a621783b9de47fe23c9ffcd1806f37cfe9f705142550583d1de4b46f768651208e30ba6204743ab68ef05c3c758b270739bbf6417b0ce26d404317a4789b96012c9ea2b56ae101e4f1b67e409630be6533284058fe4215ed1824988faf82d162b744a66c11027cb4e106e95ddf5c0461a663c89411858305e5b95eafa3afbabac208c2b983a3c5e88e65ba1d5b182f1f397d896ac963ba5aa60aa160b299274cba57c2a1854851439cfc147dd3305d3dd7b1493659182f9530a2e63428d82e9f4d9aa7cdfc51625148cb17f925372fb1df5134cbdd96155c24b92f085e104539ae7f5b0939d208c2618648616e126526ecb1e0cc26002f6de273bff787f7210c612b09453c4f7ca49fd26c377108612cc7d236e7e157ebc2c1784910493fca9d3eb9d173f289d9186191d20411848205dd6da35753a0c8871c836d240037b10c611380c23a8f9e93a240f855104d34e6e65ec056da4814618443098dac9a93a23faff52e36d80c60dca40038d36e30c33126da481068631041286104c31a2f5f3920e1f3a45c69a06c6182318a6687d6e23929c6c42fc018c740827dc7d2f4670f0f10b435061ed93529523a4f6c317c6f413c9d94ea6ff5b7a61ceb7f0218f5e0f0b3f2fcc25ce639998eff0b6efc25421897cdd7186c3872e4cb32729ffc80e2f415d7261f6eb38aa53e592f4d4bee10317862826afec736b753bb730974549410715a4a6986c61aad634fdf079265abcd4c2ec914ad6a79fe546190b820f5a9874d8b8dc7df92c0c2a7fbf1fe7e9e2c8edf0210bf37cd995ca444b2cccb61e210513172c4c25b994b6607dbcc2b415f9b5a4e7ae305ef0fce941eb34444a2b8c559b16174197a710b3c21455a26bcf9fac45c9c72a8cb2f19fb2a8bea99c25636d35f0a10a735f9a9790162d7a0eb1c0472a0ceed9f49da77b8d7f64a4518619638c199851061d3e5061a7305d4e397448994fe2ae0f5318258e38f9a92b87b7df818f52900f529852860a9d6db370d9761406d7d1511db449a9f0210a539e3d95f2b89e1825e64728cc215c298b1eb2a030b75558fb089553840a0d1f9f30ad87917849a924af2f9e309b6993eda4e2de32a265f8e884794543355efb635cee8313660f3e3a8470f98f4d98ba93c8ac905532d66a70a3d3a8516ae34313261d43cbeba578e1b3f6e02313e63d19c1d2363624e8c607264cba7d9dc289741f3e87c6c7254c29e5cb49930ddecde81b669c618605c618037530c618a800c0c587250cf249a9eb590f495755ad84c96425bba4bf38418614111f9430ede8a5511d2d859c3a0e1f933024cf8ff6f24149bc21b14f99928cad8183bf71fc1109d3c70f22debb95c6dfb861010c70400c0c8821821168a007e4111f903048cf8e2621761e611295b91a164e7bb54a8b0f4718ed3bd88e078f7a154d679c6183046cbbf868842145f21073f11da45a186110f727721e7b89f7e5224c4129ad7f31354518feab5a23774c909927c2a4cbe646cfafb347bef081088367f7202c99de05391dc2982ad142fe4ba4da785cf830c47d14c2a4a56321f444de9e9d091f84307fae3c158bba222ae4c2f0310853b84bb5753da7eaf282308a7653e13c53d72a1bc147204c2d9e1fc94b8aecf00c3e00610a6d12dc428c94feb7910334ce061f7f30ab8974fa6247c6a9948cb51ef0a08c5484061f7e3045494269fe763efa60922c626fe9bc2284341fccaaa6246509eb88f51e0c1f64549c9fb01ecc67b222f2e7c98339c99e252d953db6bc2a7ce0c174f59323c7506175d28f3b98b3a5eb10dba10f3b1896e245855d4cc6da1563c1471d8c15cf4c7c96243a986c52994d1a1532d66e2033fa0c4f061f73302595836f9c0e231ac21ea45106213ee4600eae5931b392ce103a7571c074459cffb87e95ac81c68d3a7cc0e1f5eb9873667d51926f3042ce7c3593967a4fe30469860f376479e27ba54c64d369433733f14f48bc78c992870f3620ff392c8d1cf93da99e1a3ed690b2a85a97730a4a203ed4905645f0f865aa19c23490beb6f78325870f34a0426cbce362e9ec1952a1ef74e912bd916f0d1f6628ccb9fccb778847e7f0518666b7829ad193c2a8c4c08018221003052010030377f82043aa6a219e923de1630ce82efdb394b23664031b29e0c387183c73dd0b27bb33d20b43aa2f1792b42fbe3330986639463b2baa46cc8ad9ed21044be1e1e30b065162559e23e9875fcaf80037e1c30b0695b3e4eaca5df615ea8239a8357517a16142ee5c307ae9f270a65aa9287c6cc19cba2d651bedf92ab5160c9264f68d05350be63c31dfca7a7bed2c5830298df89aee6123c6750573be8e2ea2a276df3d2b186c4bad2aac5527cf84955f86f041059350495dcea65bef43ff988229e74a9db746968241626b8a897a11d1520b10a2828f28782962425a8da806cc28a36d6440a16008ba744cbace4eec0b0a1f4f309dae382295b897f0e104939abd0c611e84c930d9f86882c707136ef4e06b50238c8f2530e0430908f84842033e9090808f23dce00602f830c28d1b6f038e8f2214e08308370881013e86501f42b0810d1a0310f00886033c8051a30c342c40820f8f5ff8e2d1195e2307bd3880072f6c6083f60178ec82c3431765a06181303c72413c702186c72d08e0618b5a24c08316350ce0318b1a65a061811b3638e30c122cc043160ef088057bc0a2461a08f078c58d2fa30c342cb0810e0f57d428030d0bd8f81ad83863056178b402fd0c66d0288880072b6eace2c3431509f048450d0578a062001ea73080872908e0518a007890c21c2ce6e7be2c29d6ef0a048f51182f646ea5e4c87fe692b1766383e0210ac34910d533b146e68743612efd1a4943e5010a939795bea825f4f8842188fd91952304356a2a62a06003c80c0b8ca145f0f08441447a4bdd0a69545f88e0d10973ed6b856fcf17365f74c605dc8c1c68608c1f7870c29055b4e38ea4cf61271e9b30d7759ce84e5ae5c08d31c6f0d084a95b2e4fe4f4f1eb7c076760608c3170e0910983b25d55cb63c00313864b52dc7c3b889f1cbe81c7250c49dec48a914535f0b08431aec4884e1da37b66b5107854c298a5433db59f2861aa39cfa5b233099387081e1f4aa83cc2968479c4c4c68275f49461240ce7f9644e529ed35307097358f12e91bbec3995c7234c62f27eec43ac7a3db081027f1d98230cf9449a96f9eed108c35c3c7d532fad6e71469894322daa1ed4a5057711a6bb0fbeef29238ff03c1461b2e8e2315f65e75d7924c2b4399ea59727951ccd0311e6e46e2a4832a14584ef3d018f439836e5c3488d943394da109efaa8daee17c274263f8f28bbbd9315214c725ff9fa3482463f195c1e83f0f36c49ed3c046188752a0e84498a560c08737b96f18963c2e61a68dcfdc1a43b82be9b14fea94a7e30e8181f6fd4c99cfbc4a30f06655afcd26ae8755ba306fd364eda7af0c17cbd22136b2f1278ec616d78e881a453120b0f313e66f8028f3cb89664a747ad8ebefd0a3cf0606338c2e30ee6203ee94f6ea2ab82871d4c7bb22fb6f809cdcfa981460e6ad4e08c336cb0251003036280400c1480a0e8c0a30ee630d76e6b13a2e731d1c17c67d7af1e3c8f39182f088ba24c720a49a1871c4cf2f9ab3a2996a59c338f38a4071ccc39b669b57791c71bcc7daf6e2a2fe8f627b3031e6e387d8affb63b95b6e191a4d54b2663cd6dd4e881196d34f06003713f69d3b6ce93dca0460fcce81a37ba3230c618376cd448e346bb193b3803a1c71a4c6fb9748732a9c1aca743ce97143cbae9a4c13c729d2a4c84892829683097aa8f92e44b1471ee194caab2ddd26a78bfb966305f4dae907a30a9bcf72123e6e1bab0248456c933e1c19c435b78cf967758558488d2d9c15cb2ab73964f12ecc63a98828758212b6685db74308baabf8e16f2dce53998e279793cc92feeaf1cb8582faa447fe26090951622fad4a8b41d1c4c4905d7fbfe10cd4c6f400303dc601cbd922d0989b5c1f4e5397c2fc60643983753d3f521a4656b30ae88ce3ad594d3613598dbd4bec47f7acf621a18800693d07be94756673044cd0d8b55fb494290016678bf52366de16bff736528cf579678f82af7c9603c393975f544977cfa184c97ef3987cac8adff88c1c9f1b63dd49f9b1e065318e97a39444f0c910306639d99327f516ae4ec2fa47223e547574b222fbca572178c3e422871cb664a81015c684f655d4656ce16ecf3a0f447bab72d5d0ba5f39c6654d6d6fecdc2215bd6c8cd8b61420103b080a7d71c193978fa5ca1ec17747c39252b14d143845827a2df2a5c1e7794120b217fa860921842bd6be9cebdff144e7edfdad1df3a2978c1647b4a416707191085435ab38a58595a3b28607f3259d4e49ff8099f095f1d8fd59d7342365676a31d235e450c6802327475989409e414ecd4bcbdc29b4b40bde3ed56deecaa90014af0d2884a27843a71332009a59633292a0c4002f2e3c595fa08c6d1972c45eca4b4b2114cd1f524c50929025a548a949245b1141b110c42c9f814bd7df259870143b83d82bccecb16b34d0c10824107d321b32b899fddc140e959f809d3253960984388da294bf40b436eed911dd717e6f41c948efc25556a2f8c1bdaa176262fcc1f734df4574ef1bbdd85af615226e88aab31e922bdf1a32d5a59bab97023e9911b5e41f85db8f092ef9f0a8d6fe155ce3cb3493b3a5b90e7f5926ab530d8a828c172e4f7f8d0223b1d2a84d12c0c415285121e4c59a43a480b1553fa7b2c529193fe38963b395868a63eec45ae3a855f61d2397c8ed45859dd15caa46829e47a044b2bf8be5049c9911c2b5afb4e6a3f8818afc289a9754a45d57454e1f75bfee55829ea5498c2e6a4921d0b3d294385c14743a7687f293f7d0a934a21757eb1cb7e2f0a0b30853959c69c8dd2fb29924a610e93e396fd8c07ad3f298c7edf4994b83841c43f0ab3950896c34b4dc4f84551bec88c89cb6b288c236eb3a22561541228cc412b451555a14f1892cab7b9e81f12f5e3098350d9bbde743e7afa74c214cf6d5bf2af085d36278ea434bfbf4cc90d954d18cd752d9c12b226cca73b2cb4d794fe8b33618871134e998e1f36c5c47a1d2c7c76a77bb92f61d44d3d6521a7a4476a0bb0844949cb4105f949859754c2146a65f2c84b29615e8b2264a77021494a27815097f36479fa699230473bcf22e6bafd4a9130e48e94cc2f04a57d26244cd5e7c1eb7de7477f8471c259289323c62b4447742179b776c5d04a23383bcb95ad14762246182ea2c7bcd32dc29c6d5bde4f8a307f9555b8f6dd5b3711a63f53df9e3e879e1043c42bf1b4f34e0e6a3b4431a9bb5f24ba7c0c61f48a704a843f1d6654089334bb4f2a2949f22d5563c1b0004218c2e85c219b31263b6510c64ba373d2058f2823fdc2020491cea8c9d9de06820f12a2e7ea7ad30362dbeb2c1ee1dcc72e7f5075745ec9048ffac12054bc4f1f9e758f9b741525870f86a0e452b22e8fd41dc28505ec61ad2d9110947a3858d03e696363ed3c984f279d922aad9d85090fe80c2dfe3d498864f13b20d2da32353b989386fa89abd317aeaf83a9374f74a8d27fca79d405cdc188223b25650d9197433237794b88fba97148a86ca9f0fb210d07934edb177c674d5aed6f604288a6748aee92f2c80da653428a9c644adb5cde0663a968699122365c2aaa04b9db1accf9469efad8cb97ac06c39f48a583103969b83a42b85cf30a42868682cf758844abaad319ca67deb1b47274a66d06a3e5b0f859d75b6997c154414b87d2ebc89029b12be93194b52fa6a9899dcec2627075c6b32aa4340a83414e6acba9d34c4f70c1706c91ffa6fe73aaacbef004b112c7d2f45e30e55877e99d4a871d912e6031c4ca88a813ff5f2e9c75733f29fdf3d942e761f611625eda73b5902e2fbfb2c05fee4fdee69d16164c61299994246bd7737905254553a3c368d10d1d2b982d455d2e76a4492b56613797943ae8a95088262c23a94e5f9a42e2af33e3ea2c2d05d3e94b252feb8b422259758ab8bd408124bb4edba40fea53fe09a674314b926c277095527487f0f14b13cc2656742cd6ae5a9609860b1aaa4f65848fb3b6b0802598c3cb271de4eb93ec4a30bee59b28426c88d1a62474399ea1e90290505297bc69c9439ab5802318f3928909cfed93928c6038b3f8cff98b6048dda5eb927b2298820a226b5c12b1da1e8249567cc9e593ead287162004931e35af95b907031193456e74c0309d9874e661ffc220bc4e47febca4ea7c61b6cb23ed428d900b61f4c29cce4a5744cdca5e7861ee8bd61d17f35df8f15794c812d68549a84baa77252717a60b49b2246dc28529277b95ba5ecea2ea5b9892127fded52962a98a2dccab7a9a922b5c0bb34dec54c14dbc63480b438e53114b446761d2799de593c3b996b228ba08eb148e852a13643c448717c1c2bc13b322aec809dbf815a60f4946da89743922ea0a5365bb9c9cf89c2bc55a61aa5211b34e1d46c594156978bc8c972454d7ab30e54ed172c98dc892a20a9398e0ed274723473415c6f6cad3a67f54186b52fa58e74e61b214bd6db9f4fd2a628af7de53bcc25218e5ef629e5d69e47c92c2789f5ac9e36514e6ec14bd7f3d8ac294963f8c94a82a59140a7d4ba48fe381c268ee6945825be8b57c828b5f732967957cf27ae21e2d173d24ffaaf0e984499f595b291155173d4e1884458be623b409936e957a50353bdfad268c575244c676eadc936782ff2a516d499830a9bb49f95a5498fc12bf889b0ec94410a9f49628ae47bddd5abba412c6f932955a8424fdcc28717cd3218e9787f52661d05177bbe32e6f7e4920ae3e4685302281c93ecb275de6d49030fba85239151fdd6e91b1f60843bec8a62e7e658c46df00c370049eea6147dcad2935824932e691bdab2a8597a0a1e24f55901f7ee5a61d86c10893a7702742bc24f36a2fc2e83977989a7db310175b43188a30277d229e68b1a04350224cc9f3bc696d57080311064f41a9e77ab50baf1cc2f4621e57c3574318249d909594c8dd33b24218b3439dc97a09cbde12c2242c5bbb6ea73cb9a04198b2754f6586ba76d205611256a35f94481372cc0361943c4997d5a5957705100639a264d49af40fc6d1b553f14ca77799f8c1f8b9f6e1aa651f4c91e25f25f93a1f4c49a848496c3c5c2e59187b305ce94e6a4bdc30f470505be16ae4e9f82935100d61e4c1702ef36f957e9382e4cbb081827c4018783068939fcc4324a5aa5abf096e9c51469211c61d0cb1f77cf34cbb8248dbc1a0643c3b9c97e585b80e26ebed1cba5e9e1cdc58d4811f844107931239e9fc217ba553a13998fb23cb049192eef33a0c399874df53437785187799a9851107a3e6884923adee924e8283713635df82ee1094fc6f3024cb101e1e73371843a7f0ba038d5ea8f4af6652612012070402711c045248f51e00c3130010404078441a8bc462d13c0e85e1071480035228245836301a241e18161808842351201404844382502010088541814028240a27e196ec03ab41f74a5cbda0cf38737cb323ed8a86cfd25657810116da0600aa70ce296e6ae67566a0e70b7654604720f737c5c02e0d64724730741c6dd034c8fc50bdd6880191268b4923507cf74d766582231df89f0599770a1a4c373db28b2b0e747984ad00cdafcf08c0997b5e6e6eea267b805f181beeb6aac9539bb444f24f37fc683c9ca949faf447fea535fe479cd290c5f455fae73b6e1d5cb06d98220fc824eb376fd0c1de1d4480b743ac6e74a47b0f15e183e4091e968a808de6f2541c8e584911c341ca0bb86b6c938d8b7c3c2b5b544b4461523983f31de5922592fc69c79a4524c8671d92de4c7e09eead39f5d4bfe1a94df4278e6c79a33ca999541f6dbce7ee7fb86a418d54ffd00120f8140dbc9d22f28d7ebb9f1dee3f4a15f72cbe0681c61d3aeb4ed422a08aff1d39bc1c530481076fad49d9cbd92fe58118611efcd5e88ef6c36e3b08c946c14b908e148a6dc8692dcdeb6d7b5af9ff140f940d20c69f84ff2d9748fc199f7c0bb77bbf8d53bdbeaf305628eb7dd3512db1809933c2bbff7a5fda6e21c36a472e0fb4d899ab41175cdde6bf844c934671899fafe9b6045225aa6d60af4015ccc7662a87ee9f1d9487cfe553ed082d1c63fd550089f109f0a6476ec7a7ad90111def3be9d273a26aa725beb92225aeee3fdc6b4808250dcc5ef550e2b79094d8a6a18a5a039dc6d8357c3774190f03370365a7a63c1c251171ae9748682c174f23718da31b7e8203a5cb808e5808638d4d6dcc72b807b6a18fc51b26e5a233c7511c35f57d8d463b36ca40ebd4c484661f9c80837d1b25c6513ac446e73ed07f0e9d13fd339a4114886b7d702ba65328781a479cb5bf8ce1ec300d47a91f363af189a59d4e56ea9f7b9ab99c439bd905f5c0513afead53f1b3046c811da319a4ac96a56eb9ed2007c14672098d6710e0e0debf6e209b3fad0c9146ff7e6189d501df8bdd8147ca7b8f21e8e05ea2633757f4e6f3966859bab60e8bb5c1be05cd7c762000b61b38b6124703725a8808cc2d040efdcba015185262701af9e67ad7d2d63104284feb64d6eb5f0993002109aaaac1112dd71c4e6e0b4bb5e4d97cd9d90ceb3f0e98260ce2bae69033045f53409dfbba11a06654e95522090e53da0559ce056640975de35c9600f50932ddd94450109a84a94701587bffa21592dfb9e65012a0fa4773ae11140ebaafebe8fd28132685d21eca13d6a10f9ae18ec94421dc56084c35c66e1d1eca59547ad0fc0ec170bca1abe70d078bd5c17ed7772e7effbd63e4f37c520dc8aa5b2a5dd5887f3a93080e6504827ece1014f80622f0586fd0d16ab76c4055f7ffbba49c96edef3a47c98e35851308cc6ac01b602cc3fa2f23a0a7e6a87f02ed28826339280daa37f1d8ef6e28012ac3b7992e2db11c3c4767b0fcd54f9a2def88673a7a85ad3d44afb14ac087e5771d3c87903115f818a8250e062f6d1ad0383886173cf08a56cfa2c142da31174c58dd48e3914fd2ed80b49b531898070f7670907e822dc10d19421bb4d67440104da63b2a891a3ca4d51acf651f3c71e361870a357836b71da9ee74a069a5b6fe107877373c9b81ac41405283634e106755661a13990f1ee43a58befc278558c50436c5fdb45d569720729a7cd112c1206b628641d3171a19641d5baabba99dff00902c5ce031d27cee7732841421211974f0002e3e1cb08387e50c1a123dd7dc2192f560b40032b1c1f30413780ae0e0715db9d5c76af008ef83c6ed0f548e6a0d9ee7a387811d6507cb7d0d40fdab60c7a3f11fc20d9ec428864318099b40e6b307b4583b067722f1f9925eb156d5cb4058ea76f8be871624460c1a0669aa32683c0155cc4212c68ee001f6e97a29fa702c27bb2822a855719d837524ec18bb7678848d649a3dfd5dbbb5ff0073e0de55a38c9edb7b04a6dd12d71b34ae2dde6aac54b5f57a3d1efb775e284666143f458a510dce73dfbbec702304ab4c344334181886046dc4a1c66408a01c8b2d70ae21424e16835246a5346d0dae1894169478c33b565351cc4ca7e176a8e929d2614cc0e98350313f9e1584987a8375820e80054cd8f0c08b0e06505803113633f98021e3e088628c88c30ad93daa20163c484fc40afd50a4bb448f3255450e5a401a0ccca1b83c4e32bd7500e94f16a58d3b472e6c8135694c26de69913c7710d4a8ca034d91f673434fd44fb3e5691d2add2003467379045a5d75f175d3db4231ae012afab4ff57c033658c6d6d4f6eb167658f7e374eeff55ed2110f629d4a028503cb647c662edf598abc8f49fe9b384c8d9fd8c05cd5af0d549d3c550297945fd5da01e83faf6967c602eef7ba0baa36279709254d0da59235a64a31b69feddba8ab7b6a2354f20fc11ebab08f3e441faf066b10ad9b25ac15ca5516837a0861300f507c4e244389afa32cdffd7e37eb3294eedd42b1644ccbc68a20f37635b74cb661cf4e9445865d99cbe342c009b91a06000b63ff24116ce487b11a992c81c9b9db81761434f949930bdaba7bbd6c038d55283df3271dd4e7520c73008b4737df2c31aa1888f3b0e1878b1cf0b921327884844bee5a714bccac1ea25bd7f0f11e1b6e82f1d96dbe6a0d516fe8d1912c35f05a0e75b787ed813de8600d653d9c6b17aef7d2fbf5809de265ff366719869ee80311899639a26019e509f8151c866ae27e19840b2463f1408e11784a253050c4c141771070e9670e5cadc8b03d1c743106f610bc51c4fb0a2262485030b4fe61fa81a9fcdffce8654d55a8bf96213db4db24e8f92428c50414d5f7ea1db0927440a7dc31df51da2554386a7a54a906b88bc36eae965fdd8d8657d007f771fb405e35798557e9a6009aef56e2fa71caa281d2d71190a7f09990632fd0a90bd39bf0d50cf8b1a02981f8f9c18c838a061083a9012486c106702d84a56ae81d3e989721f1561cb282b4b0546640a1ea5e6d8e9deb6e2e06331afcc76b697620892e0bbe5e4b2457166de73ab573f8611a1f80b5d6c422c073900b3116aad24de0f3a0acbf719c3ea3988b7180b8014c160535c3871bc6433615e2ece25ae9c9197d090c624b1fd1c0c0dc0a8286d070801706b12c6e587ff95a8150da4896b50d079916720ae98d2bef454ed81c969944bc4257c8bc372dd3d215fca33f816fbabd579cd2d0d56a60667ef624413aa08a31415638ea0526713b34d30661cb537620f9b9eca9e0ca09059b34e11691a16421408d55bfd206f0b868ebbe6e9524a87530e7eac8c8f0a3b3d3c0bb8ec320c000eb4b950a0f5a89df0e3def45b0507e33fc65716c7f25654279a5fc2bbb791669c662cd9ee4aa39ce62389a39c175a76af872761a0d7d6ba436037aa1d7973c62eda5b1aba73eda03bc29ad35bc4e73cd0d34fcc2344ae4f6ea2aa4ceae9b1271ca760f1dbc0a03bcb7fcf552b02ae762167f9c545a6a41dc9e7235f35e42152451c14d5d2e2473e2bb1a7663b038cf79f831fbf1a41399f39950df4cfe176f8f416ac5a09f7c098a38c98b3c927aa2fbb697f0b31de0df2935f1839ad316e184e6e2be53b26e8ecdd88875969f73193c263885ec0f809f6c4fb0f29ccddc163e0a369d4e211774edd66eca0ba7a4c3ed95a8ae40cb70c1c693aca14c43ed386b24c54a524893515afc1fe2048b2c806b04fe8bb54d320e34542fd88ba4066eb37e8d2dc3d1c5c0eb4aac5923d9a76f3f610fbace67f550b5203e31a6e93cf4aa2ceb2eb429338628bb8c8d74bde9079364008916d853126280f980d9dd74e40d3449a65c58bb6e46b691fb52791582cfc56098ab40016e046131a182c29043533120706c40423b3d7a72b4dd417623d49548ae078f503e39425e044db78c0b65a8d5c12b5968e9c4897ce33b75f273e1bcb07ba86b3680161be25abeb05cb2cc30ea5db9a3ae57f41bbe72e94f6d8cc3bab49f93700c6dee1444990c542a8153af88f10494ee60e068957e8b5f945f483b67ebadbff389931e049939a0f6dca66cdbcc92fc7af95ad9d400f09e415a5ddfaa0ab5b495c9848644c8e68e964b84bcd453f28e142b58ac7795d12f3f0f47f20d966f0252cbe851e5e4eb152a546cb880600923287414314b9bc651bf76675cb6ad8129fb192e57bd2a386935e1352ee250d3c45bc5b02d53f201f0dd3199001ac0c98be3486af99261294008cbf83dfcf5f828e8867b750a5a3f6199b715c2a3b2e9fc78cf446b11896e53a15d74145014079aef2c1db5058166d1039dae12685e5f4e9caa0f973d08ff0af43e3310cc9a5e573052ff7610ee045b505e49106ee9dba0a4070bb03f007f417c967e3c455356bbfadf7ec49e47a40c2852004a5ddb1ca97bdc04e43cf650f8ea68bacfd829b8c90f0c9b24186e76fae090eb90a0007ce265734afa1281e43bc97fd59f05333e36138d5b1e2f802f83d18091015291935b2a23e02553970a05e55fa032c6cd4580f27fbe48db17a7788e5ee6f4074a331de655c63453a71d691f68a42db119e9c977de2b076dea2d63df8373c0090794bc017fd689b3bd7bb3205c9c8b9b60ae44a9c961ecb7a156be601ea334a873a870dd16fde4c2239bb8ee4788ca3b839c18cefa2c59b21f019f0b37e30471098be5daf339f81e07688ebea1e0a691e6851d422d3b74aac8d33de2ec6894006daddeb1b0448d6165971ee04a4bbbb7465093ab6950bcf93a930e7c00f8356e9d1bc67da851e07b79e39a579b39caddf4bda6333dd9c46c2a72cb2b034b261e209c301231cdf434b7e828f2c7f4464fd6cde242445cfc43c77ffb02800603bbe3c6fa133f04203b8a7d5bd1cec0efee9dd082435a3fc13bda89336040fa736b11e51fe7aa5ccfc20a6507c42bdf69fab2221e1e382593c02adcbf45b5add7a506c92e9ac02f51e620d37209ad315b59ef012ad22d3b3bb85ae67a4ed1f1a4a12c901c2549273db085365ce1f769958c7b0f1bc64a66dbe8318deabdb8986dda60f4b6e648a3dbc21263225b8b325402b39f406b7d23937360fa309a5bb68c60d1beeb67800a3100047ab552c63c5f777bcb8160ed2d0bcf74bd604723d4fa42f45b13874e9e95186c43835b3b80b5b1028acec69d0f71325de08d5327e9d8e0009896f340190fc7232b2991e1bfd1ff4133eed2cb74ee46c98f7b2a170847355a911f9cdd4c6c13ce38cddf9f9da12caac149f750c72238ede31641f0183f2e2bdc266a4f1823b01a888fa2f31316897220b27bc7461daa80cf6fb489f53d9f93ff6482e016258325523d4ea4d421566ed4384a3db5f5d987aa9401250734f5b7352f0d87befc1dbe41c92a4101e73a0b485923ccf99520071d634a14a8ae50d44d118de7a11743a78e936444da33f07ce3fe6a5bac02c14ee24de0752df349db8d0b2c2ac6960b8c58d3338be231e3a0a641c3a8326240b4593cde9804adafed63a74f0fd12b1a9ebefe57a445a814301addd9afe8522aa3f6f7206153ab1e480d043dbf52f9057adc890c5942f3801b6852d1c845a1a404a83efa945e3860990f826ed5a85574fe5182748320a55046810e52e0494a23c9f83c18c71a462c071b3903cd222be6baa84c8b9e44de1be90a54b6ddec20ee637e4e31337b734f05942b1e473d587bf3a711b1ef22391f2f6601cc8ebc6a92d684e72b04a1c99113ba37d665d60d8969bc13a5ab1da250b79960f23c0eaeb799deb659c22b917ec462a4f3b1a2b332cb16885033f106b17d04d12d2821d354305e6d04ad0b3bd3fe31488089727e858e118a5882e59628975ef7ad0529ad1d58b22b32c00a852d7d66b26225fae6fd03791dbe0992d2079d71b5e93972423cc1c3b2c4750307e12b136b6826583a11450877eae119c3ca6d26d6660276bb2a2d51445e14743b1465846471ebc9a8820750ecdd4133e7956a89034b7b6b427c53840f5ba764501366f91bf26cfcd4f040c261466dbbdf1880781125f3c2a946a936a61697763341490cd65e0ebd9c712e71224408a6210b7762fafd5faef3a9a5871585a6e94033c199d77f8e7989771fee7191990da6b5afacf4c3f5c67e0fa39af96315f44d15a02fd8e7cfdb37831e87e930a81e882b293284689ba1a5c3e7126bcdb4498c5b045ea120e4abbff1b4eb03c1799ab56e1155ae0fbad636244d1a9323b50fbe84836e19a98e52b5a490432a88d2a294441f4d16d1ced6ac6e02040fc82a20cd1b63b2a87f13c12441a199da27b8da08a9822f645096078ab13d8ba83e78a970596418829f786a24274aaac14ce13bb6909a26a42ef5ca50e4af0810e51f85df0ae9e7e0f9a9e749fca9f2a7cf816abced80cb722490ce22b75e441342ef96ca933641dd02cb38aacf8820ddfd85b9385822e5bba7ae972a817df8a66f96db2666e915ae768423ec88f188968a321d62a8178964af08cd2e104d774a34a87c4d4c00fbbb3834cd3a8b2626b0a015b393137efc39fd82249d0b67ad09043473ed2316bc27c142f254b0edde9f1805ccfb2986eacb51f67499b124b08405fe7f824b6b39651a4f9d9ba8753a5b525b5a8ac00b4ee70f035ccd38751480f8833a71680278183e8aec9d776283fdcf445b71abbbd05a6896653bc7d651ba5c680841eedc27a3266ccc67411c0b458d67f63d5a6daa13f31b62eb8b55f5c155ac30873801bcda2c0c6726a64f54527511838329578edde956aa40ca0d8db018d20f5a86401b8f2f8d5daaf7edad1667e97da463b3451f9e66606912225bf228fdc820ea3db5d6baad7c2905e8c22a22ab237645cdaef6db8b36dc9dab536a4edb4b8fdb24f3f250daa0e47cf7924e1a51b890ba5d81fba2d363dfefd2e90bc52a74320796f53465c2683f8be470ab5b2739c76cd445a8f2004b672115ecb8a44c7e29e2a04b4b5c07a8201c512357b4297056ba1eb08f706e259408c3fe2778bfe47e5cfdb356dbee57a0b07a26938e43e3c81147328375778c26e7706c74920e3f8c416dc7fe525b4b781f7de7cdcfd38649ffc9e71914596cc2a1a8a9b1ca11d31346982a5e898880c5dc092585f19bd2d171811440a85995b8fde6b4b1646a1e6557e3f4c95479690c1357fda02fc43e872074bdde2f020ab9647e6c9210bd745e1fd1f98974459fbd8cf1eacef6fa9b5513f524b8e203631c4d520f7da9f0f27153f976a125374edcabb5ee2b6024c33b19fc9fe2bdde45f3619a50912b174cb0603c186e61e065092a62f25757e7a7512276899aeea41c12eae45a019dcf612222d2c1b0d273a91d172cb93288c354e1c76293fcc7d6058169a804abd08557db0a5ab1086082fc9a4b7a74bc324dc109486c8778003825dc43babf0f8f04e2df4c69863747907ce3acf49944c82032de235bdb5a32fd364e9f13812a59aa92c1471b97eb3374791cce52a1e011231eda1f1b87bfd4b192eee36f40b89ac4525f0803108f2738964fd711cc844025c304b5d48020616223bdf31aa4dd557ca1931068551223374dbe4f2668037d05c35847884055e3ab5c152ce466865d15a01d3d5c7b02f2b1c42db858cb49d39143c96426b9a6551b5b90949f2eb87631757679534d21a64ddc36db3dd172c3ab28e378646efab7b6562cb76fe7e54c62ad2d6f12e008c49df8e2525a89169d3f409075e6221e99a93a6a7f463960fd47524e9954df4f609c1ecbf7f23e546e6c04dc4144778635ba1794c04b00af52d6d32684898e9317bf3b460627abab17cd42a055b28fd6e2d58f5a9c6df5b70d09596a29272329197c07b0433454bdfc25c02934e00115eddbd462e4577f2ceb67c44982d2c2b84eca7652f46466548bcd9fb28a60eb0f2941fbb67b2bbfc6d21be3379eb37bcf56c6b44ef24f50861b00de64cb3d6b0c060d955a50f5582222eb2802b3ed1de51bb8af2867d5989c45a92e7c7ddaca24fa404690d4bf5dfacfac2a22c0b7252f2e57fa74e02eea5a1b9797490ce100e487ba3bb892dc693cc60c27720aabc9e8057dd093b5d4d20505918635a1af736eada7b781254afbbd4a94c720f1f73e786d85e86d327affc96c1ceec4e1b28c70b113a61d5a5d15cf859471f435ec632113db6421abb55c6dc95fc8740acdfbaca88f5f52cb5bc31314b791509b1598e3773dae0ed3df6e13fbb43d6b91a1609c5d2447dfd4c8032d083b921e4939953e954a1c63393416d3a1d83708a9cabdd1e34b7bc53c4983f97742da9345aeccf5ee4f454e77c883d2314b1c6c65c2a926b63776e5f2b2c95f4d47ffba37c9b6f722cce51252cb2db3d87c35d2e5d25f778fbd950aa35a99f94556eeeabe5e60212c8484b072b5881cf2791bb6e618d4a407ac5841d1d84ea0053f32eb4d4e4abcf8dd8adb4b8f7d8e4122b4ded650b64245d8363663f109ed85315872e1c3c94dd2fbc6841a0845564b617d80697d51267c3827b588a48754838bd51abb13825cd36b931d0aac8503dc661e99c20946f185361dddab351e32385fa2ceee6c618b20a4d58cac8efd71478dc3821f1b44ad685a1a1d05bfe0087ca31db53adb69e9a4373a72901da6b761b2d5b04a470d90d312607eaf6189a71e1bcf7f79b9a58cd4a763a225197c3578f2f79646cc8b05c435740658e9065bc7343a21c4accf676c40cee25ac331941db3d2b6e27b3a44f56a9019e9e3586225ddd1bc29dd9b1a29a384e151a30ead38fb03236ca6dce87d46081ac9c54ae9254f70d22773c86f2b8a151e89f9c1fcd37dae479dac3207c03324a6dd0a65bbbbd76482a02eba30b02f58699f2cae7246e94b5e2a98c206435dc03cbd31989c0a83292745c8b5c57ff0749402fc3ca04d964d99a6fd5797b90ad30eb9b7b31f30b9fe80e2e666475596f17709dbbfdb54212d0d1a99f1209dbf446610e7b7f15370c45d8af465fd70c690045e0540c0500a3b81f489fa60bc869957c5f51f10e2e3d38beb1f8cce010c5b01ba2422421045219cd85c8ff667c460c49a519b94da79332ae6af53c562859499f8be6ed3353721e334b5087eb2ebe2c1114d9180e9779a9d3f1ca20477a6ec856c423be0232afd67689ba661cc549e08f75ffbf24fc42d234994e66470d1ccf7c48f86a1b48a81c4d61181019518afefcc281180f5d19c45e3f59d138f45c6ad546715851dfb6b8def5c350c277d8af1b072bba022bf1b1f7e1f8806df8ed2d6f6dcc4b30fb6e1700ffea230b5874bc89e9102d1629c0056438c1dd1e08c00abe1c62cd1e48c001535326ec0727683cf4b60bdfaaa56b9f5ba5064c2973f1fc833b148588970712a192edd4ee483f698fbf81a6fac471423c4b97aac52119ae5af7846a74f314cf587c0d12466d756890513df5c7fa9fc18330832df9f8473bd3ad7c1bfb6e6207ed183e4d015c58b5fdccdcdaa1fe1e0dc8b9792fe1c8c5933d91811967c0fbb31678d3fc578f5546f90389e232861b30088774d8a459628238c8554700599994923bbcdb7137eedcb76244b70f044c59f7e105a3822bfbd42e8e8b73b93f2c54cda5835738b51af0782c0b50fd6464177b85e414aa2b50071e2949954e43b0d24711abf56d6e800ae6cf8231d20a8e9ef672128b1fd670cede931905f65c8840b4c0c99d70ddef68663272021b8bb387ff5a0d7ae1b24ba65ab0783ea0235f20b54bff568acf1ec016e7f6e4cf6babb5914c03d55299e6c6b84bba1e92d4fe9254b982bc3f76b53c2bf3a007a6be2e3d18c0b3c860392acbbfdeba93aae1d1957a59f1a809784e3a791f428a3fdf6183f99039506c64624ed6e74f263aa7c19e14d1dccd51635f5e004343aef20ac11ec979936715701a820f9b34733b456e29e0aa83e6d540ccd037f7eb10c9620686ff5a27ac04f2a71271908e01c6f6a07bdb7cb16d84d8c1c7a18dbed310c2610bf5695c3e95dcdda912cacc075c44714d4bd0a775f65d6a69ffca7a7e3977890c910ed3f27fdb2cc51605f7446d9fe5a7e13c48c921b2f34d70f8e84469e6d9b43b4ab2854a1caccd81ff6c2e0d963dea992902e5144288d16d0f8188d01ebf147849a7b1e9b2ebb155f8f2902cf5a7f4cadd768c25fb907b97319fd7e897ae89caa42d9b6a8c066fa17e3b3235587a0376fbdc7bac3afc35c8e16cc58e5311ac5beae69e8ca7e94100268553f4f76a5619f0c8fdfa18eb468af8d51b8928dd351ae37813c47afe73c7cbcf928c808df3ed395a0e7e0cafe003dce4eb74dd71cee51574eaeda133b1fb0a3442e710a6f06ab29e7f33c0b31ca3e3b41094bd4c48548b8cc1b4259c8330dc00a3dcd8ae70d0a77a6669348ca8638c116ba91e9658d3e85866f77bcc16400438b68a58707ab1fd4b02e53814a3c7e2ad4542224d5c597e5842224290b9ea7a9edd8978a8c8fb94f85f837ed90d075b7c04992a167b3fd3e1795b97d87c3a225961b1f4de9d41b6b81f11ee6963a14bc8c048e9e54260adbef3537cbadc8df12b7441ae6e1aa85a58130094f186aaea06607c1cc3d4bfa06ce304b5c268977b03d6416a6748ad3a5d9d4ec8fe94ded80c0a2f0d0cd3d052a69b9129b217819fc2c4150192bc729b5edc0f7609d31a936365ad1f306a6aef0d892ec27834b9ab217dcab7b3a82fbb2dc5c530dd7018b2e102b7ea288afd850f1aca3927042afb6c69937ba552121f5b2c9a78fa21321eb629054e83eccbcfa490ab27717d435126ef5c9eead9964cc3376221e000aebeba8c9d3b3b041be98e9073aa21758b5ea04d0832f04fb99377872248c54a67ee7bcbe82db24a0edf465d8654d0c3ab5c41aca66a2533c05496426e11d3c658e0a773ef5358348c3526acf586ed06d857a2b2b19044522f2811db6f5e35f22f0a1edca8c8d49ddb32fd47443d2394f556ac9710c510ba4d793013f3063c7e78973dd0681cd02a6209a0b4202b596720e93945e4ed1ccdfd9490327a9a90d7fbc23832472af6e420b18759fced10ab618baf16c4043e94d84e296d3e5295fdeb09fc8ccba2dcb41274cc62b9af00f95a0885d51521fd9727c9a24ced543ab38e436ae80ccf88c4fd2ab1f58046132470bb8058387e098aba5b9361a140c824c8ef3ff12dbb787c9d6b612eae4c248319c3c865dc3c913a47efddb5d202d61f45f921ec60513803fc70afb50bd64777b10f7d649554eec1335b980054a1beb72416d78a871fc323589a6aa87e89d07b6f282de5190cc753336c96126820326dc6755b92e70ec41ffc6a47856c204223924c42f7d67ffd792fcc3889e63f5c600258311b93510ee600a2636b2579357ddb745b8b6489dc1ef29703ea877eb23994ce8afcd7f6e66999f30a06431f46e14e3e5c1417918ed5464d2b723fd0c527ae1e8b04e8e6f1dcf5e2b03cc89088f7271ff5317d2239d87f25df731f2c829d2c8c5e57912ebb159b72827ee8389b35f75f29a6ad16fe6e16c44b555aa9944dbc96ae0b1604d59038216957ef4fa29f452b5b27657431526f66125cbb6c2a03610ec9b82d0147c6cc12643f1143a270b9dd52d57335adf404945093315295d7f489ff562949a17b3bf97e1c08ea044dc581cf06d94c156f831e137e0c928ec018772da783813678286d8a0089c0a3317bc723dbe8bd8610a045cf614309e0257014c5b4cfc82688b70127d68400c8a3305523bf276903dd471a6a6da0faefaf07f25d0d97c713c8c1770ff55602d7dac5ab097b26206133af8bb155783333144b45dcbfc574900268996e2477bb7d7fc3b8171a2ea12d04a465af84e82a42f53a555cfecdb13fe2526bffaac5de2197c3a5dc993ebd7c9c77f14b3e86bca1579f2eb38a490b700e7db049e685b4bf6ec9e23fe9910db357521408aa0978d43b66ad8d80d075f49f89147287d0c3089df397e27dcf21f70f82567237c0dcfce6b85f3e3333d4eeef15f53931641e927830e7a0cc89c5d11008edbe92f904218d371beeb1b4f9136828205f1cb710e29b8115da70396a815cd9112791a240742ceaea4caa9a962e5cdc1a7f753c20cc7e89026850a342758d04ee47b4814b43ceb5236fffd5cf328758afbb723f92557fdf70bc16b3cea036f2deca4f4aa2bf7a1576b33d79b110a09f6b292885bccf7c6805e21b0748488ab60025184a53a47bbee1fda045ce314cef2e9067044434ef088a12b3d6c1ce270f2b378ce9436736e21b38c92ca8244ef3ac14a3af6e5803cc8d4c81b0f3fd412f3ef668e34ed585b62603322cef5bd8fa79aba174a447c8f9498ebb8a951545a2a735e0662bdf7fd29cac541eaffde43b21c429ffa4b86ec1725d6e832116c3f6d979641778a698848cb70ae22b03b26abee697fea238f8f6c61649aaf73a199e9d72fd3e4d4f126a17c802a286803884131fc5d0b14e93fe56586d542ab511f6d0e762e83560a930361e55fd88e1a18a7cd2120fb875bdd120b73f3161908119fa0d709f304f9d87efc53a2ecab3f9055bba5a70524a91cd3e0ee610e55bf8be531d90db4d7d949ad615151ae345f0fa522bc393c02a9796d7bcab3fedf26f1e1662e319c12173b200c6f72cfec3913c7cfc58c395d3b025a6ae4a8135baddcacb538e195a2b5750f1cf7e90227273684425e01d8fc67c35dfc8ea2f3d768c3122bff90187d207738ee4d758b776e53cd68da3118d063a1d0f5bf2a2234969fe0d76416fb69693b1e6badc9160d6b36dc69121fe2661911e704be85a8ee1c6d30bed5ddc3398bd76e0180674c9aac92531dc4ccc3c3c1ae721c152258507a92cb3dce4c6668fca56ccc6348c7cd6dac295010453725ee9694c2ed040525f66690b823115f13838bf5031d7827480bba37a936e151d4a45215c147655c01b5ea6b2cc3928c21dea76594baf491c37ab402416b2a244c99b8ca18046c01d22a03828946c15246708e70106ad758347c2f6728d04028a278c5bb2fa491b30737aa950fb2482bba68b5c12a7435a515a8e890088c4aa2a615a804cb91d968af8a7a82ca2c455794fc53b357193a46b1ea1adfd640a53250b7255d2eeaba76095e6744c7463c031de7330c3d83434d8553522cf484a1c3a19750c5a17a5147a51e88f5c49183cd373afa0afd1ceaa9a3b094f7afcb701488a8655431d4b9a827ee08ed15531e869fca16a84cb08cff9f241f4ba8f0285f65c42f346ba943ab6fab32d1a244b1652b6c987374c8dc11c732ec5ad6f2fea1b02efb1dd8cbd1cad184519ce80fd09c1b9db7ef07ea3f7432a999aa46d44d422bf2c4f9ade8553db582f75f8fb2e47566af15f565b95b560d37a9a72e109848ac3633f5bb2a63d00c882c1a059c18ca30c54ba7284465a04e75cb4a8c8e4695416dcc018d169f8a942168a6d486701d30f79b58279cb5db3c09a632c18b06369a218be336273cad4b0fa10a9dc27d41bc0386ace2214127f248d3a4f32149e19d6e89dc6af5f07cb95bec3cdcf3b884982df87ad8609e354a6c08ca6bc63dc526c36e88adc6c68645d2d8ea6192838fc62780eb764ee5cdf44f346d2f41cf5ed6b0dbf0b46dc734563e5d6730a2d92ce4bb2a5c2a8e601923ae4604a3e05c13e81eeb227c5a918498e897caae8a611a735141f7b59ca22138fce786949d91d9c831b418506c1ca03fc8bc5c0c63da50c17a462d56fd724401c0d66e5c85d05a5e48ca310c2b4ff902402288e3a3f6030b26694086c9ff4c1f0d4e066ec3024aa10591d94008b37af412a40d7a0c9814b8095871b0d817a845a4831f3af5dd66be611c05b01d7977c159a1431f0dc1763b774f348c8326176d47460d8c9014bfc7263c1f32a0284e12c6a2b17e64a36932d79cecbdb41a4feb715524f2011b14790be7073739ccc10e38335c4566fc709bb14a447a85e0444b9b597196626524361376c9ef1038ba6cae039b315e6ca9711067e837c3661bfe0a721bd86d2cb61191d80cb6c5d5b9bd91136c399ee3d8b691d98d65e51887534f6c6677d6be0b9dd88cc9a128cdae8d7af166dc144cc86ae5c8c6b46caa02beb045f90d3660b0a4900330333333333333333333e3ca4bfde37ddc1ff7de8d60c232aa45279a9292921209ac35aebce01de7e01dbc8377f0d67401ed0da10d1f0e4d52abe0757486b10e62c41ca48223a94327bb321b1fa7e055a63ce1d2e660724e0a6e8ebfe737785c565f141c4b1e13738c50991e149c94426d5585f6a5ee098ea47c5b29c7098edda4077297396c821f2ed492e698473a98e0b57d479bedef79094e698ae918f197b1129ccd6695ebd2243829e68b15296548706a3e6bf050691b2d3b821f3ebb9d49eab09fcc08cec713724cc9f4712c5911fcee30daf6690c11bc4f93de1ee45552ce109c24b143ffe8393cfe08c10f6311d467d6233d4170e3fb6e36eb2b3b0304d7b3cac52c5de59a1fb831ba6a5f7ce085cba91a626726b7f4c0b188eed1d5b47a5978e0a4c6e6cb13d9819344ea6732248f611db8793a3e87b4505a7e0ebcf6d0217ad8e3c0cb4813d66e3c546ee06d9eb7cb1f04b081ab5d9eaed2b33adab5f082d87f94ef83acb569e1b6c725211d3c0baf652e4731480eb46659781b24180b2779e6c95154d58c312cbc489a7f2bb2fb8faff09225c9a1f9871c6deb0abfe3284a9fc754af6d2b1cf97854438ea7565b56f81a3de4f918415388aec2bf64112d4398e081aa0ae762aeb8acfee1a334156e69baef49bf7df944859f3a948ea297a7f02579a648ee5c1fc4148e678f9e2d867cab580a2ad4c986258f144e942011fd330a5f2ddfa71ccdc7cc88c2df509a156982c71d0a377687f7e8e0592d28dccc21dada625dea3ee1f49d947ac8924b9927fc8ea12558b020695727fca05eb3a74cc509672285e718de849325a7d4d392ae929af0439248513535d57932e1a71c4ff89c35740e0f263cf7499b263269adb984f763ee36d1e953ca58c2dfd80c7fdf1e5fa412fe86ac1e49ce9a630f4a38496ab2cf5c26e1ada698aa6221ea2b92f067b3860f5f8984ebc9936d65b5ed0f020947cee6db72103d6df2083f847f2c094f911e71847329dc86d481a7a46984532187240b33c2bff0d03767c851c72ec20b29592ffb304554116e064dcfaf19bacf4f841f7bf0a0437920c217b90b73c1e3104e6a5bd6beb74a1343787fa163f3cb66e1e342f8d32621dd29ff84f0c2079d6254f6993708af3abe93f1141fa515841b358636cf5aaa3981f0ca3c27bff1f3ce00c233ff20d774567cf40fce775027a942747cfac1f50fa66346abd14efbe0fde5caefb1458b1c3ef871920d8f7b0f5eb7e414ba23f5e0556bd01a3bf3e066a4d57469ed2d9c787043dc6f23fcc776c13bf81f77297898e2b6038d29d9071d07621dfc4f39cec17d460acdd1c1f19caa3e883707377c10739a433e084f0e7eaa34ed992da5b7581c9c34ab9eb482e58b191c9ccf9c2db25f8c31526f707cb2ed322d37b83982abfbaa4fcc698333f39f4288f6d92d1b3cbf98c2aaf755e6881220630d6efb848fc963560d4e48993e30b7ec3fcd64a4c19b481552485ff5c6340c178421030d4ef504dfd8b0ac40c619fced38168fdfcdbd449366011966f0524e89acd441a357b803168601a30c4ea4cc1f59c425bd5eac066490212f937073e943c618bcb4b8decc95a1ff3b2eb6bef0a28b2d3220430c95e6b0fea3142eb68c8c30f8e21ea4b4a9089721cc850c3010c3fb2455fd525f30a656c6e688be1788e497e6735e0b97404617dc0e1b724c4939d892b8e057e7cae361477af1e82df8ad193faf355ae1046468c1ffb19c3286adc6908f0c0332b2e08cb77a78cd1d7e230b032fb20232b0e08590c1be821ba92e68f274d1257fc8b08293c26a32976da4bb8e2fbcd8c2aca08b14aca00ba4808c2a781f89a7d45e953cbe80046450c1df4e9273e8925ce00432a650351620430a2d230ace5cd0147a26c3c5568d1a99749001053fe23f3e5189b858be31c87882d31756db2d212d4b8e2623c87042d540818c26f89299cf238fc2cc4dc6c542c074f1850714d72083094e6dee4de7d31a1daf8c25f821cdfc440c2a5143274309e590638979a2e3586720230947e6f6c163acb83a073290e06dfe9c25a40d1f117304c773f81023a6c4b88a11a86ed5f4f4be087ea8b6cf1fcfa9559808debb89440ec9330427cf769c329a840bb1230427b84b47f3b17e529d20b895dded953d40f03d677498f0d19c477ee04555e9fc99c423f73ef05faa8349ead1d7647be0bd664fd61ee450226878e0a4c8a5327b074e86f71073c4e69a4a077e900d39c8a164fb2293037f656cc35598780f0ebcaa8c0d9afd22e3065e4a15edfd4b82e71c45860d1c8d1e5f4ff239f8e8520b377264c4bcb1ce63b2d0c2b9f6d68aba6916cec9c7b45923a1a52bb2f07290104453864f6d2516de7c8e3b280d8fa25705168efdff6726af8e1e79857f96a5239f9493d4872bbc1e4d4dfb186a3d6e8567993e9ccfd979b4125678eddee5a1a9526125abf003adcc9a93d554481255f8697d36e498c35a8224155ebbc75a1d9ed9c1ffa8f04c730c7b4df6e6fe9fc25b93e41d95b973646f0a7f2cdbecc77394c20fb12395f0b1a884b449e19ca71ca588ee8d3b7b14defd871134ea3ffc220a3f720eed22c77328fc10ed339c87b1fb9941711c99c7c19f70433e881e8ba6d58678c28df6618794365c6ad209d7cc2549ce0ed207ff72c28b5531df99d4a3fcbb09d74396ca13a2ab09a7ec2a64dd0489566d26fca0fe3ce68f35cb6a30e1d9bb745f889472b0f5126e1e0d9fa36bb58417251ecbc420e991a795f0dfaade3e085f29524a09a723db7d32fa78949293f0dca26886895312fe69ae0c1e1d44a66846c215d90ed70e2b64c925249c1829ddbb33a5922e1fe1a51c87312186565c948e70a23e78e9c923252936c271cd718a5ad4a41c898cf07d653a74e416633b5c843749b3e414b25d21a1225c4b216ca203a99839897025367ddc610e39db7388f02a5d468a9eaab4ce1dc2ebb40e54428721bc1c237d20e139469314c29b4a3f214751199226841fd65fab669f2c293908af2e0495a0412a624e10defdcf0709afd61e7781702b4d88b163f848313a40782672f75761d2a4cc1fbcdf902b85c5f62d8b1f5c8ddc954f34d607ff438a629b35ab6ccef8e0c6584915d6d91efc389e1cba87b3ec74991e9c98825d5a87fec9c195073f84e8108b1dc777b6f0e0e794356f26bf15c6ba83ebf669726059b3a65776702d6cc2255955072ff769c7b9a347e242073fd688ec40dad7d3630e5eceee961e678b62b71cbc4a1a25a925264b8c83f3f663f963ea8bebe0e04cdf5f86fb4fd5aa4911e30d6e05cfa8e571109f330911c30d8ebce6ded0b8b4c19f2ca99307f5fd5f151bbe10ce53071d522cb9585d839ba14722db5c4c88a106bf7c443ab6b7480d49831fe608319a79ec65f5e130c44083a795455624bf60887106e72fa9484bcc47b61dc30cde799aa7e89872989ac528831f2d7325cdfeb125916290c10f324d6fad3706bf277ffa24993e77c7108317a1e53c36c86676334618bcf940ae03cd124cd3c4781c31bee066180b2ea576c966e20557d5524564bef34f7e17dccc79429c489ca70c73b1759683185cf0da5375852017184c83185bf02ace3f36cdac11fed1829bb53abedab6919c3fb64819c4c8821fa2e2be3d858ea7432c3897f264df1837358f71b1750557d42c64a4325bcbf62186159c1c6677dfacf6f5e657c1dbd8398e3368baf78de162cb84e1c50b900831a8e0df98faddfb7de0999c8217db248449a99e66f2c59182638b300c181d460c29f8fd3972d49c3c59c48882575953d7696da9fd5070d26a44e592cfeb63f182055b1ce58a184fe8b25648bbe49ce0d5f747e9552fd61a89d104275eed82cfa4907e7ba18156c46082779b43878f30cff0314bf0a254f5775039281b318612fc3084075feef9c24d6c8f102309fe4fba0ade59eab23b48f0d6fe55a5031569d31cc17f995eef0c8911344611300611fca822fb3f6a6d086eb7c79184c41cb9c4b5841842e8da73bfa46304c18f4655e5644323463e06100c125307296ac80fbcdc71322dedf8e08e37a6c5b85c7a40e6efcec14cf43cf02a25252ace63077edcdf9922bad681a329f2479be53843c639f0b3e6385eadf78eeb4371e057faa0b6de73032f8b86908378897677c6b0814925e7ca746731520ba746e2dd2c2b5af8173dad66e224327766e1d4473ff389b62c6e93bc19258e85f7e95aaeb18485571da444b779b5c89157b831d53be6945f336c5ce1a470999c337bc8f05be1c7d6d829bade53dacf0a37a510555931ab36c7b10ab7831c72982c5bc9660f55f83163f9b6844db726a7c29c474af2c72e7563a2c2f73c1fd541d3fc3f7b0a377dac1e3d336b8a536ed55c653e61624729fc6c39bf5d7497983325851762dea8f48e2c878f1c459646f2460ea273bc280c8b312387394a6ff443e1791023e4b01550381b3165a3867cc2c9f1519e34d2e4709527fc888f91d6f368ca612736fb73959c533bc6092fee4f5bc262ea33da8411368410c4e4628b0c03d08413d22f7d1061fd539e4c381f7afa1c652dd9670c261295d26097bf84f3398a9d27ceea52d2125ed234c135bbd587a152096f43fa8fde424ca97228e1e7d618553e3aae8f3209e73aad87906f3b7f1c92f0b27d881ac3a5657723e18739bd234374dc390909673407a17a62e411841b4d6e12e308d77ebd3e8a4eef5d69849f2ba78df0b072dc3d23fc8bd5dae571ec5c2ec24f7f4babab15f1796ccca525c2d97c215b9e17d91c8a08ef3f6b4c1faf5fe6104e84b7dca14c5b6df20de16be5cc8a9d42782a1d45d4ea3808e1f6dc6f068d109db3c7208e209e839298d22505e15fae79fbab74200a89946eeb3e8e2640387193ed347bf41fbc8f43e71cc9a3fd4084f475b91493c7edf5c1b5e47f29a7cd714735f3e178fb38b6700fae87afee20c5d5839f83d89a87b3bb8418427454f93e78f0ef53761c5479e41e7707bf2c2c7c799437c729b583339a3bb68cf920eaa30e7c8c8a31e530c71da3832ff6ff9dbeedd5b49c83511573dc217b8614b61c3c2fadd70a9e38781f793c34724f761e0e84a87cc125f75418dfe0cabd44ccb176f5c92c089552f02ca4bacc32a131c22878193af41c778c1de51c14fc8ce91d85f4b149774ff0c3d08aec0e7382975324f6f6868ba135c1174d299364d487d162821b7294a3e4b496e049fba87c903257564af05245c8d2ecefb72a097e10527aba8b69ec4307129cba0f59f5417290d271042faf5fba8c7418c10d1da607ddf3299d53043745998c670fa34d0e11bc645d15dc21b81e955d730826590bc1cd1965b662d9cc1b0427be83ba9f9b6513089eac445947da4af0fcc0f95c1f7da776b3cf077e84a76fca6678cbf4c077b94f159172ff8407de5f8e63794739c00efca8e3ad4992538c8e72001d385ed6215d8b79b8ca0172e0845039ccd9c73f29e40038f03dca41c2a6567b0939c00dbc288fa255d286f2200938800d7cd91c2b74476ae1d846b9ca10ecc3e769e19dd684c7f9cd3d3c66e14713424c394e9bdab42c9c9e0876962b7786742c9cc91bf75148f9c9372c9c35efe0ad738ae9ef573817c3c71b7c57f8693ac5a887a487dd0a279d44e720e5ce97352bbcdb8ad6395ac50a5985f31f4a6d6c8d4aad0a37668aa7cc4a332ea7c2f76023a36999dfcaa87063b6edaccf1fc7fa148ea57bc8a19885aa4de18d67a57043fbdcb3fca3284941858cc20df691d78c2b0ab7deb447c35068bf390812ab8282abb168159a7ec2f598bbaa247b2a0f4f381a835cf8d8eaf46527bc28293ec55776f992137ee8f7d6482321addc849b3caadf9837849b50135e8478554e294cf62f139e4d5d761c478bd51b269ca834d9a1b2be8413a2dd87d1375eea6a4bf8513a97927b9f94a7ae84eb2396ae634a53c20f52ca42e6ca2c1bf524fcd414434e1d95fa7b24e1a5d4603967ef38b427126e0e326f4bf44f8b1e4838993654f6795f34cf233cc93efed31ec5fa8e23bc10b52e6a348494368df02bb52a4c76480b1b46b8151a953ea3c2ad6611aef4864647b5390c1945f82942fecd914984137a2a6787c84abe20c273b7b69aced4f09743f861b0581fc28518b518c20fe672fc9bb3570a2185f0ad627658dfa7f21342f8311a72c60aa61d4c06e10762ad599f20fcee50bff271a1251208afde526c594b5c0f083f8e393a8f473a4dfd07a7cc3ca60a17c362ef07afdc36c264fae065c8c79afae083a7c9c6638cedc1f114317f242322293d38f741d24abfec6a1d79f0623c6aba089ac3e8c08397af4e43dbb22ce60ebec4beede0fb658ec3b5c73373d781d90ea483db95b263344799369e831f74bc695210e5e0c6d439fabcc6c1dfa4b943f1150eae654e92f9dc342a7d839721d9f12de5414abac10d1d87d9632b5cfb6c83671a39c741d2d431996cf0ac5243541fd7e07465956c1ec658caa9c10fdb614e558fe9bc4b83ff7190c3b8d5d67cd0e087f07392dd3378bdedd1a5ac0e0f33381bdd7bc3bc6570bd83f5b05346062f25e6495932ba778cc17b4bb9376214afaec4e09d057b0f6518bcecc8476390180ccefdbf77c871bee0877e29671b8f17bc145273f061da2c962ef85a23bd31fabbf35cf06354262651f1efb7e0a5ec142cc3460b4e6bc654a9e262684d16885e1d7c482958f0b5dd6247989bf82857d8ae6445836a0527749810217c7b1456c14bde6973850a61b64205e754623a4cade1a932055742beec41ecaceb102938a15fbd3af351705cbeec3f780ebee3a1e07b0e3b753a9fe05cd01056511b6639c10f2ebae5ac9247e99be06594778f3f8c0e1a2678b933640a1faf5b64095e84d09b11568267f769f1ef9104a73e7f1c7ae88104e7fa7344f5f4b1cfe3084e0e3a42bc4c99dd6d044722653bb06c566a17c10f513307496622f82769a93ea423cdd921f892751fe628c71c9b2b0437e58e62f28c06c1f730735467962e4305821f27c96129da64f8c81ff822b612c2f47a10a50f1c33fbc91b246687600fbc4c3158a69b8f5b451ef87d1a6fb9fb8314b20327d9c7a1e7f9dbf6381db831776ba596f9162f075eb4ec100f217b640c07aeab4fe6685bb63206b8819b5fca26967d5c6f001b781df97a35c7e553d7c20bda21244d7972eecaf058c93ccc5acdc2f98aa134e7cd70175938123d3bfe2894e68b36165e7ce8133d473e2cdcb056a1736d7988cf2b9c303194cb755ce16a85bef4c85208dfb4c28ff6917fda9e70b16185d71f555cfe2c4a8e55f8d7b1c74345b0e05154e1ab767c3908396ab44a2a9c9e994b97b7a35454b8f5a9c25a8edc29494ee1e49bdc418839c8111253f8ef963c8e42be147e8c9ddd36ea34073d298a985635cb1fa370bd3ecc3c7fc4ce1ea2f073ecb952ce23147ed0724b33d11dc530289c1ccea3f9c935a7f127fc1017347bc7ed61c69e703e481eb6aadc0937b9698e6cd2478d2c27fc568f327290183ede4de09303a9f50fd584dbe9cd639294cc5ccd8493e67148ee9a63d78909ff35c2574a6dbd6dea25bc99bb54b163094f428eeea38e2cf66325fc28b6e3d764172585126ebabece7c7196fd49f8c1d29b6f4f648c92f0d652847f0f6be922e1479914113465c57490f043aca6f031e5e0ed23dcbca5da97426f089a23bc28a61d474937b3aa11fe878c9d3c3a9ec830c2f30e3e9c644c49c3a48b7025b2cfa25fc44c114ee694e1eb2b89f02d3a8ec73c06117e0c3955d33c840e630ee14a6ad792397b558d219c7416ca3fe410b92b85702b7518c27f74ccac10c20da95f4f7910aea5cc9c42737f50124178919e6adff1658e914038e3b1fa67f324361140f871d47879349dfff3073f6c9c5ffe2d898e1fdc10cd41a3c61c65f4fbe0c72c6ad71d84d2f0f9e0e5a9081297ce93f57bf07269d80e2b7f90cf430fde86ca520dc9fb3f79f093bf44a494c6833f371e9d64b21bb3efe0aaa7e710edae1df51f695e8f3267b90e6eb7664df1618e89321dfcbba43ed391de4a9e83172cfbfc6a2c073fd2ae58173193e5c4c10be396fe29c2fa0f073fb4ed896e1e43a76f7025888a7bfe4e9aad1b9c546fed39d536f86e1ee788930d6e6cb986e6c91b9daec18f3247fd1e199d326af0a312ef8e47ab7325d3e0fbe5b0535a5b0f3e687025ddc392cd61a9e50c8e4d6a0e22df9ce4308367f159b56337ff0ecbe0498cc86f6bca9a0c9eca4756f48cc14d93261e3a2ec570598ebd30b8b93e0a9ed181c18f88ff5af7dc51e60b7e468de778096abf17fcb0a93f66c4f4a1ed821bf37b5cfa7555d2b8e07768161beb3129b305af42a37cc428b5e0474c512aeec982df9192da771c2cf861e63c76472186d4b9829fa3beebb11cbaf35638086fabe0a73877f31012fba6829f72ec9b704ec189704b69a191829f3b9889cb11053f7b700b4bf93ca40b147cad309adda33cc1cfc93d4c158ba810e204a7530869823716b3b2e4ac262d61825b2949aae6ef9827bf045f353a7b234b18f195e066f449bb764bc93992e07de68f526c4ac99303097eb2aeb5f18ad27e1fc17f9ff6a8e41d7dd846f0c27806499ddbaec345703bd88e93c6f441083311dc9a8ab89b5893cf1d82f3eed2df9999735e85e05884c672d70e490d829fb286c98a09047f237bfa851ca4cff2077e58e40c8b613eaef481272947c991e981abed9653a2689685077ed0d1367fb13f0eb2033f567c681b3d126975e0ffe63953150b90032f6cfec366bfb2fc1500077e249d9d255d3e89ae0037f023bf5c3612726d8a15c0067ed8d7f93cad3286ad165e6cb41c2a365af8519a986d9259a7c92c9cbc621d694bcef943167e858995e314652bb1f0d45f2be7e8520561e1b84792263d5fe5fa157ef0dfd3ada66d63b9c2d9f48186fe68ec2aadf0d62b47b0b14829cb0ab7630f2b7d24e12adc8c728b2947a80abfdea227582c9b8e3015be5fd545e5303a8e0851e104fb0efaaa62adc7398537f641ba2bc7b1bcc7145e6dc4d4ea94c2ed305ad424e37711527895434f72f5d1dd3c0a3f4fca986286cdde8ac271f30b17257d6a86c2eb3a3593cd80c29fa9d7f8cc7cc20fedb183af142a2d9ef05288b38b3df127e984177f412c956685ac70c2ebb1f338a6ca26fc186e42c2868c29af09dffeb2df8924136e6a8851e22398f0256d5427e98ea27309cf434b59f5bf25fcf451c75399551ec757c2491f6d78743c259c143cca3a940dd932092f3c580a9e9364f99084ff31855812b6634a1f91f082a58b1e3cb49608094fb3624e533fc289fefb0f153bc24d1edb46f8514cc5a7d258b95e4638eea369c5738e83f02ec29f0ed3be43c7b1ab5584efa16a089dd22a443411ae660e55d4a453f78a0827c4b4f92b26a3c27a083fea682bb93cb5c7aa21dc786bf5ac4d9e2f2d8497aa766df3b9ce4d42f8a9b9d36b3a085f543d8a09f2d6a320bc694ddd51bb2731108eb8e4b8de83b4660908c77fe5d4a492471effe074a8e17fd38c4f871f9c4a135bfbc32746fbe0044f95cc32ed933c3e387ee1de7bed324bf6e078b40ea2a64eafad1efc73efeee8687bcd3cb81edfe6af110f7e0cefce76d91d0ca9af52f6783b90e6b73ab81e5ad6e0db35b92a3ab81d8748afcc1d2e85c8c12b8b2995dd2671703d54ef8f573a38781fcaebfa63c8aa746f703a7a0e2ef391f345e70657d2628769a80f2ca60dce46878e1e877414346c7072868f6369bf64cb1a7ceb0f79de72f5fd6a703d7be4a04572be701a5ccb7739c75f4183bf2134a4671a0b5e398313a33d9121a6ceaa98c18fead0d724a40c8e89a7c5ecfe4af927836f39ce399aabf1a8ff3178926e2ec4f42858ff6270c2fc6d75dcbacc1f066f2a849ef09863c607839f525ef320390cf71c5ff04337d5140f29217d78c18f3653b8ea4bd1bfa30b6e48b19c2485b372990bce59f684a40f72d0f1161ca91cbedfbde318b35af08367faccc741d566b3e046bb1cabc574d074b1e0d55b78c755dd26ed153c099b434d9f90c9572b3861fba543e47ca779f1b0a3b4c20d99a952adfb2353cb0a672efdba8ac52cac5556c5baff63ac3437d31db3a10a2ff664ffcf9b6e1e7ede48859f2de95108d73aef3750e1c5ca1aa9627b8698be53f827d33d99f2fba5e698c28bbba41eb2f3c4985429fca0f597a23b59be5092c299bed8162dd9a370a3e40fda91dce5ba4c149c654578b95876677cc7a1ba22caebe650b829ddff7564c7b61cb2010abf446c638aea486df9849b428ed581470a911896c28627fc8f5bcd42a8eb550b373ae19c78960e82b1c50a0e521d48c20627fc2862c71d346724e0c5c6265c0f1bce43e227c7686bd4d8a270b0a109b7f307edd8983f7a8f63055e8071180e6c511b99f083905c6d5372112d4c50e92932965d1313193652f89770babb2445788dd259870146172940b584bfb221b572b08401461717d8a8847fd9f5b17b4e295157b4997d887a7a109d7b42cbbbfc4938eefeb9225473f6201e614312cef976678e241d093e4e2675f9e28684973aec3a5d5269afec1187f1b87338c29678abb0b70ef70a79aff1289bd036c2550be92b98472184ba1b8cf0e37c1693a6cfb1087f725853eb137b091b8af0673d7c18d357527f4d02612311fe9a7af9c7f9d307416344d84084af6934c2a52c1b61e310ce8c4c276d172f4def8621908fb78314a23c0b001b6c14c2db681e2ce6d01d734cae0e3608e17b1c678cae0c51a9a941f821a4b76c99b3e5941e82f0831c66cc71777ebd06a292abcdaaacaeac7c5e51228df87ff600e1af44358b31440c6697fdc10feeda2b751cf7e4982fb65081f9628b177451aa0a3b60c30f4e4ecb24b12f52c7aa45b0d1072f870813d9fbaa2ae40d3e2053a7eeb61aa6d26de961f4506334dfaefed88d3d781163aaec9f8fb1adc2c596bd0bc0c0aa056ce8c1ff402cb43a0cbfc8835f21e4683347cfc596a5800b30b6b00ae374c10518c9800d3cf871b9a475de1cc3a4f9c25841171f3841170fa851a3460dde2d54e08215d0c61dbe08030c177cb1c51602d8b083a7f59623dfd47182159814a4e0e08264d5c129b79c3938952437aa0ba81eb0410727786be6f76b71f54e7080018651c1165812d8988313527ef3205c7a6ffa2a0c1674f1052939f076112f2257259135356f96b3db448c1e0bbce00d6cc4c12fd390d992c1a3a6145b75a0cd7bf1451860e80aba48c11746058a81116c711b70f0f387db0c39763ce98336dee07faab75f8c1eb9e106ada32eee4ecb23d4253eaf8a791c39ecb68f8160a30dbe7a6c99f6d1c63cd9dba20b161c5b18166cb1050646b0458d0d36f89f39a5c89363b61e8b8b2d2ec070410a4e5a60630d6ea6314f79324586ac1729b80d3538d61dfc88bc5e5ce02eb091062dadd3ba34c35633cdb6e66290b953b58f49738213787101167881811a354ee0450af2be0883051b68702c9ac6a0622f7e1ee4622b055d187206ef425b7cf6278fe09a2f5a00066e6c98c1f7d850219fd4d25c9e8bad93822e0c29832713730af3fa4bea09e38b1680915c8471a80055f05da4003130822d686c90c1dba4314721746757c7e08ac66cfa7d58a11d31f8315b8e223950cb09831f7f0ea2b6e251ee3060f06cc6265708ff3959bee05784201ff786f178c10f7334ef318dfb8574c149e96f51e9a639940b6ece9ec1453ad58c640b4eca665b16ee344cb4e08b5d6a0a92d2a5f6f70e26fbdd7b2c389d992ed9edea9d2b38b235bfa1d6a3d86105e72a778ef139b09c1d557033648d930ace9b7cb470e9297819fee73cdb43b1b414fc9118b2759028b8b6a93f8378471681821f89c6a658988fb59fe07ab86fada8589ced044f52da48f1f19a857013fcd0c346abc87124394cf02d36422563489163096e481fc12347555a2bc10bd1c166869cd2c649f03227b3489535d521c1f5207fdcae1259b53d82e3a5213ab5467053e5e8e314db577711b4cb9ed006113c3b931ca6979cd9d3b3310427a70c95b4729c3aa4674308ceca7fe4f164f74fc9b3110437f465cae1a291f3793680e06d0e391ef994424ef36cfcc08b6079e22323692acf860ffce875de4198e46dc1b3d1833f7bdc23d1e581131e9f63348c45b703e762b4f7adeaa0a203bf62088dd530078e7814e9adbe0d1c789fea714ef213a6be8d1b782aee5d975ed299b7610327b79a4711e9e31baf165e8a0923293b8ed26b87167e471b169ebd269c7666e1857d1c449ab2f02a3c76670a1b2967b1f0259a8ca51c62d607165e0e136b3ec7ce9257f817f239ca945aa9e50a27e714d3e5dd61c76985b72efd59c3c692301d56b85146e3fa833a4f59859bb54d3ac5b8146355f84126c5d87452e15f7d6b06f3a0c20f16730aafc7dd6352f630a9620a5f632bd67df4518a29851bf31e2ba490c2b3f0968c12320abf26b4c207d1ef3f88289c4d3d69fa0c853715bd4dd3dfc620289cb6912c62295f0a924f7829115390a858a9239e707ab3739035b30c914eb81aae1e568c8e909f134e5a86ec3064aba0fe26fc38720fb1f3cd4bea356125bf9cda1f4726fc54291fa61ef1f83c30e1a6ed914b96dcc2765cc2e94b1f65d7b425dc0e72b678f88e1ea42be1db7d18d971e71c7253c2d39c695b622b33d793f07360725922857f9925e149c664f69fce718c23e1c61434e7ce3239430c09275e24856675966b1f4184fbf3924d1de17d14c226767dd49a36c215f54f6da119c62319e1a8c744d5ca1e4de722fc8f467324e36d174e45f841d2491eef12e16f4c1aa53ffa87194484f7e92d857d203165f0107e040b734136fca268083723e51842f028c28485f0936407a9912384ff39b3cd86078f633708df0397bbedc958a320bc8f2aaad53eacc50a849783b07eb36eeb6105083f9c995fd6fcc1fba01a2ac37399871f9ca416aa434da60f7e289363f48997d0c8f0c10932397d58397bf0a37a771817a207ffe8c129cb9d3a79270f9ec6589f6c62f0bae0c1afdcd9730cffe023e60e5e7b7cb183539a3b2454eae0873972f4317d70c1a583ef992a31690ae123998363f9a3935c297db372f03de54aee7d1c9c742ba6ea3d1c9c90439979a455abbcc153f5a0b28accb4ef063774fac852eed82dc7d106ef5d3eb00ff9f38d071bbc8f4e6a9dd3327af41afc8ee73ebe540d4eda8a9d95638f2ac569702673e821cd46839f912c26979cc149e7a3d616dac3bc197cb3dff064d3e797c1495531f75493c1b3b33149511d8393c94672faa468a38ac1491be722a1d3a34bc3e0c9e4e06d29f64a8e04832bee41ff57a4aa07bfe0f95a88d029e8052f7b9691986ace65ec829f6ae1e319f34873b8e0e7cd9888892db2b92d78b93fb5848a18fd3a2d78136361426c89e7c8826f79f278967df96b58f0d275fc5a26623969577022222bf67c58e295150ec248feee5855c1894924a6145eb93a54f083c9db1e3705254f8e9143450a5e6a5289e935240a6e482ef2713c1628b8c96da225a67f7c79821fc6c58ccb92db3e27b8e1710ed5e2728cd56982bf39ce379b63cd39c304bf54ec249c4bc8d6c743865109558ccffa7c26094e8e2a4729a305099e851ca61c5cf9d7468ee0bb472166e690b152c4085e08398e6899c2f5e58be0a73c29c7131e4470f37d184663de48d13104b743c81d875e087e5c21c79572e430dd41f0e3102ec7dbea1db440702d8450267f3167f3074eea891dc5ec286dd83ef07e26bc6358c90c750fd61c2a5a2c0d0ffcb2b90e3a8ea6fb8377e0e6aaeb491e1df8a6ea1f07570edc8eab3ca590c581f315be56ed0dfc1c269329f769481060033f3e0a59f2abb570724c4134a6ce725269e1c76130d114d159f8df79629ab01256230b3ff020f7e6138bbac4c20d19636bbab78f21b0f027d8b5759a0c96bdc2f1d86453b694ef2a5de15a8a11e71f6c851fa6ac3c6b6485133bf038b29854307115dee638248f1682670855e19bc731a46473ee38970abf5a3e920f2544a643856b1e473139fa3cfad829fcaebc21a5c542d29829bc4a2e5b29973f47560a6fc42f420ab7ad4b7286ef706a915178122b872963f7077922a2f0abb327c4431f0adfc3467b8efe79c20714be450a0bb93d5e8d9e4fb89a3656e4303a5a763ce1dc8da758673ef1309df0443458b0bc2177a4e1842fd9999673d4ea39b309b77275889af346b2144df8914afa8e3a997574c9846fffd92c5b65e5ab60c27331b32c0f3999e6124e4ae7ccad29470cb18413738c1243ae849761fad206cfd9b194f0d64cb352ead6ecc824bcf4edb61d7e49f869528cc9b28f849f72ba9c3e9258110f48b81d2654943693db8e47f89e82aa457438c20d29738e432c6af67423fc38fa2883947b349a66846b729eb2868ae93e7a11ae67d9e09f61430ab5229cea286bca5227c28b219484b31c45af20c2b394fca14b88d6371fc22d93ec3996cdaa8a21bc0ff5d01f47918b6c219c1c4426757c84f06bdc73902a1d8493d7c3741b9ded422a08ffdd53e64eed953b32108e66ef9421de2ad70908cf23654df0f30f5bfec1d7709f29b2e32d1ffde0888ba528967a7cbe3e78a9352b92d1dfb6e3831ba135dd6a5f9c670fde64694bada93175f4e098650ec5c62f36260f4e5cdd5a0ea3078f030f5ea61c6bee204436b63b7875de1f840caff0cc0e5eb40a390ec283c831ab83df1263989842072f4a4a39889123c65b3f072f7d98e39e88c90aebe5e04627390e6e4e6917f5beeecc818393c7db3f9387cfe50d4e270b6e91376ef0ede5235aa749744d1bbccb1c25a2648397c390cf18d5e39e5983e3817f320feb715d8a1a1c1b19f1acb1b672d2e0fa892509963b98074183932ae7e6317557cc193ce94e131e7d33a02165703c89aac5e8f155f964706ce63c8cc1f2e6c818dc48313c3226710d8bc10bf9d80e3eabc5360cbe44c8299face4283bc0e085c9e123491e31a45ff03fec0e2486da94587bc195902991a84f92d3053f4afa63c2528ec25cf02a7d18973d795bdd2d38e9fd2b47f7214b460b5e856745084133250bfea754b9b3ad58f0b4cfa34a41bd8297572b86902243f2482bf8d27188ce548b746615bc8e9db3974905ef3a96d95c15ea564ec1cfa27541baa30b0335d6e04fce29a79c3e31c73fd5508313323b7a98bd37c7d2a7c14b52eba1e71c26b9bfa0c17bcb29575a98902c6c6a9cc10fd45c2c977c7e50c30c4eb5a492d58eb5366519dc4c1a1d7358ab99f385b9e200c7e00bae4106ef3dc8df352b1d440f1a83ff95917cb3e5387fe41083ffb16dff88ca61f0cb6d523078b162eedb58096a577dc1691993bce0c714d27f7c1c540cf9d305b727d347b221d6e0829f43b68fffac3b47c6d4d80256eda66a9fb121993a72ca9152430b4e287f0f5972eef5ecb2e07dc584a5a5160029d4c082d71e76567d566feae4158c2dd917b493a68615fc1cc40edb516d35aae0dda58739f8daa648550d2a781d9322f685cad86b4dc133f1b39f4b661f41ab21854a225cbdc4b3db3f45c761f25ca79428f81efc6f76924f179f5f64208c2e9e6a40c189317956091ead553abb45d1a0c613bc0c691f9a48ac66ab38c195892cff0c25175b2970810ab01650a3095eead452dede71b155bc50c1162fe8a2aca67d00b7c81a4cc0446d6525cd3d6ea4da530ea15e61420ebd1a4bc0c3ab3a66a4bd1a4af0a3e418d523bf6b24c1ff782e33410d2478c95cca23357bb8ce41358ee07cd011933a0acdea670d23b839cdb6f2dc45bf0b1d1f6a14c1cdad31720ec254938670c0053588e044f5285ba7ef188217a3d4f26d9ba7206b0d21789b377e7387641070950bad2f0f0f912daf48d95463f0fce7670d20b8f943baa5af508d1f78317d1c8597dc686c54c3075eb28a3c217610f56bf4c08b1dd39e03ffe0f3b13578e0d6467d798efe0ebc4ff2d7b93e7fecb8d6812f2556fea1c8f9a6a9460efc157b8f21fca4f848db410d1c78221f85b49023dd6adca069cb3ad5f07899f56ad8c0e9f4183643566ae157a7e4db964fe7a9a685174d93254b9b5938d1cc276f92ee78a3280b37326bc5dbe5dbbdf3a20b1ab1f0b5bd43f4f54fb1013460e17c14ab932f890abcf8420229f0e29c8374e0cd0a345ee10a67a4a245394b5be1c874960929fa8b4a8815a0c10a3707d6410aef1e1e73ce2afca02124e4281d55f82d39e88b1239346f4c2a9c50cb7d11613c5f5950e17cb04a1a73189e39f23885e313293964ba47e9834de19da4cb5c67bf1e79b0145e5aaa0b69aa228597f2f45cc8d1cf7ab246e1895864b5dbf049461285e7bd1d9235191de51e0323d8a20b1aa120bcbb2ea6e6ccba5c3a68a59453d88e06289c641d2264dfe827f6ac4ef35a8f9334f3ce41e5f65852746c3ce1b4af64acfc49245cccd3e8841f29a7f021f6458f5f2a3438e15ae80ed3d6e6686cc2f18f5972e4f46868c2bb0966131fb287d9c74cb895d583a68eee474303c384118307c48006263009198d93b4cf6040e312cec73fd541ce1c96a024625cc2e34443e6b633ca448e9b5425dc4822f9bd2e4c0947aa7e23c3497e406312ae6a76da761b25e175745e1725e6bca69a48f8a1e55053884820e1a58491508f5a2585f8115e24f7ff984c39d2d83ac2f7d0d73c8e36a68fc735c2cf41960d29d46784f7b92ba5c71d5c4461e6716791f1e63dc9c358af082f04092a398eee72611a89f043aa7b54f76977c88108673de6f83dc474eeef1cc2d99088507eb51ed6c410ce673b0fcb3b3afdef42e4b6a22a59ef6521de5539a8ca1e2ca5c8488f107e1c7b5699746d15680cc2f3bb10fe628809c297ae18a5a7c3e88f628158a542522542d6ace63ebe903420fc384b984e9321c337f8072f49769c2b578c4f1de407277fce2629c4e8e9238f3e34652d27ef51976a5e26d197eda5154172f0c1fb38233eaeb2ecc1b1b4f133db512fa0a107d73bb67e992a4d1eb677061a7970ad2622bbe51c68a08107278878184248be71e3d1b883375152d49e790fddb71dbc8be930b2265407ff553ec8418e2a74f0a34d26edb183e409cfc192ad16abd6146f49096b8d918a395a0ece07a13f556d44230e7ed2ec5959b4c39472c0c1ab8fb6159115491de40b2f24805b031a6ff0b2e5ec9d3199774cef063f98921c42da1c297ae6f8c2ab0d7e1ccb79ccae90d35684061bdc482a41c634668af28a69acc1cf1e39b45384d5e05ca808b229d633a6541af2940fb9cbe9a3c1cd39a38f7a449be990c6191c09e571ec2853766c9bc15b7ff140727f06b9b60c7e871c7a90c10fb2cdf585bf1c61b531705fa2219231657116eb115b44424aa798187c390ffad42a0b4356b1769e325612369f11338520f6c126248a60f03587f8ccb3e182b8c00b10f080c617dc54b38f1eede8b56337a0e1053ff9df588748a769ac9d018d2ef8bd1e7c5bce2c122b840b4eff871ea22593c61614abaea9913497d4d8b6df88f513a9a6a105377518bdcef3a65c9366c18f5268cf97333b738ea48105bf2d6a7aceafb973ecb98213ca254be890ade0a5a70eb36c39c8c6a80a6e5db8e49155f0cec1a854f0e353796c6c7aceb1e262eb042bd805d098829fcddd33cdc4b8d88ac1910253321540430aaed445394b9675952e5170c58309e91edd52b98602776b5b25325257e3a7bd91557c825f79c343a8faa8734e2f136838c1ed28933be6b553f9c409349ae06a872d1afdeb3bf630c19199edde90f925f8e9f279f4b14b3494e067ea4ce96147a6393322a09104ff25bb47c1e3be889e41829b7b735839a87d84466dd553bc624decbb3607afacb9e6e3a36104b7d3ed338fa56814c1cff1f44732398a06117c8fe9e3991ccf07991c34a03104ec3e4aa6ee89da808610bc770d5e1ec60cb1262708defc4848fe7cf141f00061ab1b95956c2dab8de84afe33c973c77624971f387296d2c5687e631e4cc3075e0ee222a5b1e84d6147a00b347ae04a38891e476a8e83845790041a3cf0d64224a4740bc933b883c2d42a3ac6cb5536694c7a69e860cbccb8cb2e29bbcce8aa8c14c22b648ec3252eb668e4c0f9d06f1d7ab686988368e0c0b9f671f1ec48534e1b1a3770fdfbc4a3d9102eff84860d1ceb9cd13e6ebeac4f2eb6bc08630b3050701816a05560462dbc943752c59c6bb2f7dc8119b4702d3349aa68698d1a555f80b13366e1a5cdd41dbc86b270227c74f5314962e1a47c9329c33278871558d4a215dbd52255ee362f390e8f36f2fb0a3fb4d0719a438e2bbcfa9446f36d8c291fd30a6f4a63ca9d31acf05346d8a8b461269255f89dee293586c7fc5155781333bf59678af4b1920a673aecd248539f6c54385d696424b8f97d4d4ee106af0991a9d9716a4ce19987ac3158cab210520a3fc8ca07673e299cdad05bb79d517877122dbb32224f8828dc1c07eb21797684c2f758631e73ea008553214a92b3530f72e8f8849f2f8f6f867464966a4ff8416ffed0622abadf9d70343dc6b2c709bfc62b4fb466e4ab78139ea598796e6e4d38e79fae836c33416b68ef50fe03137e0a2657de1ea690f5125e4a0f35f96b7dea534bb8e13dc8c16f07aa15530967d5633bda9794f03ab68fcba1949370726945cf1463dab428093f8c65f9bd031ff1c922e105f7b0963fbe20e1fd47e4d4563fc2e98e93da54d48e2b48331ce17534b39e7e723ca311be79d49683f530a964b88cf03b70e9e8e55e04d9a723781ca33314e18b847ccb895ae78c6724c2c951da76d0b1bb72cc20c2894f95b3d2d9f57bee105e0eeff5ca1355529a0ce107b7f12ab318f3854e219cba0b3174744f88b32c4dcb3be32ea55bac374d06f3c8caa4c283f03b44f1118bc8917546108e66fed01dc2a7e5c01208af62d68890feb2ab2a80f0eb62b68f273a3089fcc1f5c966b13d9ef8c1c9e01fa3f45dfab0923e38a5d1b3797ff0c18fd44335cdc27bfa7f0fde8f45cb79fcdbbf7d3df851a4bf27f67fc5c89107ef3d0e9d2b4bee8c4be3c1eb309447d25cdfc1ad30f93e779ebef1d90e07d9265b07e7435d75103ff2331ddc181ea6e093d2d46673703cba972441e33f2296831fc4b4f153afc9cddc3878722fe629f7a4dc3170f06efb93f4ff779027fa066f2d438ee4a7e330f36ef0ff7d6dc2e5c891c56df063dfc810739633d8e047464ab9af424ed98233d6e0686c984b31c786f7c0196a288b787cb2b5310dbe475f479d91ef230dd1e084b449a288f765ca9fc1cf72c93c58c80c8e7daa9ca9528644580667d663c911aadc543a32f89d345888cb6163f0358568c65c89c1f14054b335fb6c0e5918bcaeebacbee4e69a0383ebae5e31878acb53d517fc943c0a1d741879c1cdd453c9c3aa762fcb8c2e78ee1b62b5fa9f7a79580833b8e0c7305ff9349b2db82eb2c12635a5091e99a10537cc7868a5edde285f169ca9c98e3e87cb2fdb61e1b2aa78cd4e891a29ab37b96e91f20aae45becc71b48c153c559f8f3fa70b39e5ac0a4db47c4aa5c7cac7bbf95f7d67474a05cfd3d7490efb7328dd14bc34bbd9f00831a637430a9e7b581dbb07761f75a4e1408d1a4e9811052755858d51161dcf57a0e047592343d966b7cf3cc1bfd41922d3d638cc70829783ce1f623af72c95ecc0173498d104472c46df768f8a89640613fc38b630591fc7db12aa194bd02b2eb6eab2264e666653c7a8b4fe511382194af0725dfada0cd28c24f4b35951ca2f8404cf2ab8a85a08d6a8b10500dc30e308acc86c744ad6c59667a894657694a24db2314930c308cea44a9875190bb57946115ca9243ed9fb23bfed10c14f512de5b29bc71e3d660cc1b35c29b7577d9c334709c1cda1c3346bbad4586d10bc105d913768464bf00082ef71f420da27e9f3b366fca0ecb2aff77439f5d841d4af48ca9fc2337ce0c7fa383b6bf7356a7c61460ffc9aa88f1d59c87970171566f0c01b9f0fe5993eca5d31e2c18c1d3839fd85e4b4195386ac03bf2ea4106be55353c766e4c00f36513296c77bcc51b89881033f4d4ae49f1ce5067e2c19daba932c821936f02c4c6c6b8e8a149d530ba7430ef28dc84f0bacbcd2eba3a3dc453c347314a29d2db3f0e3e389d948933b458981116cc1820d5938dd414cb5a33f547446868d58381d33425c7f59f48e030bd7facffb7e62c45ce52b7cbbf2f90f993762785ce1755de8988ad8a874e903e3e10182c161c16824128642c1cd7e23006315080010541a0c45721c0792381c7e1480015d1e1428281c1010120e101210080a120a060806060008060606000006080685414276608e65301f113ffb4f02b53e38081a6d1e2e448eefe4e0fb5cc5a118bde5a418ef40a7a3ff30dfdc617d9b34ffd7f073d12f7e1bb37969b31c27467445e227f755a721f8aaf4ed82f77e9665f5bdba1d93731f72fa089045db88560ebb5199a4d834c95ed3e0c3d8e404d1a98cdaa2134f16942e68ba9fba41b2ba300222fd6a06b1c1ca6a896b6ccfdc63360f18c3951a5ac915597f4aedadcef6e00fc63a94a3a3b4606bbf1e2970253b672a21a18e88f40dbbad6a3435a3816bde8308bdcfcb169b680e54db13f5408b1acb24ca84317ee7365b9dbc93794b5579120d7a4ae5240048fbc521b26c423e8706e73d5f85f5ac1c5afa60d3a589fa8152aa14171dd0cfd013d14c91443aa1ce2f0943e1a836035a3a983c7980437517be3861a1f8f79b8c1b1f927fafd06f66e40a472275af5edc8473ad22bf37e0afda5492f7681368876d3003b81786e5f64530fec6c8e0351b39ae5ce166f2c92c2e4f8d4fd982f223b601fc623f544a3904486588ffa2f4609c33ecec7c0752a2af78c9e50cae72365db4ffd4d9d5f034c4951e28cf8a206bc3158b8034ff1d147bd080f7bb7c5215e1bf86aa9ef40ebca6dc46c27dcf35d31a2dfed9e13d1ce94590fa7dea84d510c01c78a5e7e03ea7262b79991f097b16d45de0bc047f6bf565f0d5bd5466c0150d689bd21e2d4b011cf4ce4d925ee8b33a8c9d29b4da52c74554706903e0f8fc281d6b396f1f8c7a4b0b1c7cfe80e15baf1acb1670945e9f36ab648e2ae2c6d954997c2cc80ddee4ee6cb41a4e12ede533a4097a029fa4a4ec773ec05976c55a48b8f09349043b5b4a28a671479ba5b3069e22dc94788a66345e7fb8cad240ac505a4a328a82ff007dccce8d4ab68283ef9412e3b125435a8180fa0a4a56afb162ed4be7443bd5c403962e29574c00cb41c01e849dbb75a9b68cf96f89d63dd92d6eed27aaeca953f48c9963ea2c04db3bbe3d7f183d25a25d32a480d55f84827834a980560455393d3e25adda443cc509046da84f6a044407c91208f7a3f80a52b9c0cca6f2890cdd31822bc35c105bcbce2f53bf4d765625b1393ed2d44b9268cd2bc06ea4e09b5bcd5bac084fed0034fb21abf6115ab06e62168ddbf0feb95e4f7a4ce9cde2074d78a9d21c6d57f7b5cafbd44dfc3f328e2e5b5ee76589391d0fd824bbd2c3b7d43c9e8a2ad048888d77a5745e48aa7f2d7e3a12101ba7a136ec898891e432fcdabccf66ea0f52ae4d4dcc70754345454b8a8052b684ffff4a5f26add98134ee9460064916abf75c718583de2c9ceb02e2b4e15afca12711fe70cba5fb1bc39e9e95e39764a8cbcc907b0dc5c5486c44c9ca42be1102f402ba5b95234f000fe40158a79905ffbc14f40d2525f74f40a85166555322f1f70d2f4c06fb2b339a1b2af326ab74f181a4ebcce5d6e6b32fb9051a7e9cc2341be933e18cdf05087ece950e94975163b55431635214680eb1e45e63900ed1901c956df73349cc845b2a216ab50ef40049e2a0fc6b9bb803e146d5aedb7e4fdc789983c9ed8817ce44849c0ca78be6c68b159b3b8a97609dc37edcd8158226241d48b004d8f039933a65a25fa0236cb4cd74d06c94966ecad561f4a198f8487c8518669a09c76cc6ab824819b89d942325ca44e8dd2f9795174188ccc62a4d2ea26b5656cf15d7b2eae7a0bca35a67ae7e83d26ef945f036f900b1030d8f107ec1700caa943234993983d18a22a49650d76d20897aecbc70e29c154e2578275b2af301cd9257af42bda9126b6a1b51d3cc92457abbf8a38e9985799d8b2d951ba41710f283d174e059d883163a0ba2b624bc6ed34d99ce504e31b2c173a342ffb6f102b49e09585ad229b0cb2bed38bff2f439d37a65995dbae0abbc1048961f62ee362f04b4d213c22eb7ac8b7342784be7ad77a30a41233bf7b46ecb290f83833f9bc307696ea4777580c982a941c4f715fc34589d90f834a4adbccef9fe469290344b86a7dbbea28281f0561a5fbca2408e420ea552337eac8227057a935e8a52d892e0334c9ce596c635652108f790a16cbd412e96f3a9631fa5b76cdcd1d096178a1bca5a55a454cef8f0f51949590312af52fd24695dab7da521e9811855046b01d728180095e577b1c659665fd3208243b8f42903c07959e8901640a990bb89bc9cf2b1b4b0a014182183ea944e1013da0aa376dedf002b4136c0533c1ba5ef98054da57ff75b7a8ba7f0905690241fbebabec72460bbe53b34434e4158a7a4c3bf7172ab95a54de9030704f411f2e3560e193d60d7a90b8a68fe143a8300f0acaa5600cb64c89291f98d8fee99156c19c26cb4a4c86c005c5b4c74286f9e05416ed8adc9b0443dabcd45031a54a44c719b5c5a3f1d93b47208fd96a81c9eeec29d02c5bfb7d31cc52c95b380ce2b6ba652f96cdbd52d64d609064a090f33b5bf85ac07c2019eaee010202013b6c352bb2ada2e5dbe4661697ff80a0678af24fda14cada154ad109d768a34502f1ba57b035dd4df1e3662e40725b987da53ee41685d6fde29cc4b342adc9b43efd6690cfa5860dedef1a4361a948e62504cde6d35ba2d5a49d758aa21ec1439e477e9424faf023dda2409af5aec88c2b99ef188836c7cc52ba3de648ab5b38515a91687abe5cbc924935d37f1407150cd2345a7b90f4f2e6af4e259950ee6a07676a7f2301b1c4df9ebf65ec7e7ad5133889599596d0595e355e213ea6e7bf67101aceae57912a7985c82d11e8475c5e4aac4c3f01d09cb25441a6adb32a478309590a6e8a47d3a1c16a3c61608f78e70e7b7dc2dc45af4983f1c94cccf2669dd08f98f5563319a15505053770e6f11298d706013bcf3c60e3c727feaf918fe988819a1a215ecaf25eecb1cfe29232477c21f97a611945678d33728766099f9a14ab62dd78cc888b346b0709f917598638607ca9305263612d850c308be4401402ec908f0454546af35427ec40a97580069739498b124c803d968a10f1b8a7afa46ab84ddeb2511df72a696ca1b55be0bd0ecd58ec06909711c7b5a46a28d5547ee7cf1daaffc286401a45201e09ad4cec8b8c0513b6d0f097de3e6358420431f80bba358630827fa5459c551b535731f80e59c2cde40c25e39b763f82009b4f293383d5ea81074fda72bbc32106e688a10450914041825764d7fe7f58f2e0081c24e56152e6e8e475250be06c6d984c32752011dbcc593b5fdffbfeeaf99c5022f40395dbe3bec2e11dc014c3c3a2311c13d063a2f0fbad1447b00f87c80490824da5260aa5c85ca450b745158e263cab2ce3196d4056012db99b102a3100c6a3f99e76a64bac0e628ae133b3aa59006bd2d43959391a90cdacc87ac62a02ee4288121dc11159330b63de8a333fc1d77968bb7faa4b0166a25258b4e4310767b7a0ae651928a396b91d6d7048fc6fc437a0ef7237ccd4d4e66b00dd59f29ab01b4c9373985b515a7d989d8d5c8afad9b9b72a3054e9f8e195ca45e01c234ecb5d4994779a860d15374497bdee5f84618095df991e2744ae8a492ae497b846f48d88e4b58ac7ab46dd8912832d97873e79925ef0151a2d5a415c4b0de7a664f6a342d0ee6b501e22044b6513ca105ee3ca45117bee4e33cb01d461e78ed9c4204f99127636cd27ad2995adfe6206925d63354a8ce1679490e0f7895f46a9384f28f8c4a9cea12b48b675492948cd1c96aa7a9bfd9cb71adf730b7d83b4d41c28781d44e55213cfca21db544ed4b01a96fa24c8bc80f16b34abd5dd1b6899832e75082d3261a560aef9aee4651f5a150498e30e4fa30acb318fe21e917892ff3621c4646ad88b2cfa491a410c4a19df7c6091657125e3f49297b7a29809c2f7812f1e64a04c27dc801b6248c043de9bd5094749de19cd6007d97af0837aa29414e5148890be1f44c0550d3c8259770c19462f8b426bc3daa66ec46d72955555e0daf4245bc289eb0c5213e4353d5014c141575761f954003e3d0381c8e60a9a3fbe47607feab92f4dc8c66a6edad89ef52645c7d3f5570a112f49ec6a26e92761f6242c5ff7634567ca4fc4754e64e5dc591501639fd3c03633e8a2c63ede1316ff31e4988257ef77ffbcdf7a1690f58f47c9c42d73bbde0e289a73074cea6149252022552b3fdb1f9229034ea5747a56744e6707b8d03ec9245596b9a45173a2e48c1e24a0e1c0a6c41201584a458099c7f64a85d894fd7c98d51e352810e725f2a163144a8d3750888740a5e9439186063ba8a88209cd34aa2f4e11e91e0eb79f4ddba3e334eb5128b6cc825536940f9114ab0de49509212767c01867d7b918bd325894adfa7fab8669db630a03f7f3ea91182dc083cee7c83b1e644a082ebb1ad0b8ce949f2a433e7986f08c20120b1651fdc53667b0d20fb9a07bd532eae5700d443a401ba89f34502ed9f5477b62a52c0c666ae6daa0a4c659fdca3d28aa184d1994b09d9ed5661c919d488dd708f5cb11803e6132da66803d121633adb0b90039cf3170e0b37e65862bfca93611503c61074734b1535dabe239326746a2902cd32a92a0ad1aa9dab303e5c74bb4b2713989cee1cdaca26c402c1c868eaa0249d7ad4af0d6795e3d3680d09b79dfae20410ca217cda3c1760ff686ac454c08548961c5996541617154f0b87333c72a254de1e097bb386516a314600e041c444a7699478e5b34b5385e3f226ae00461af8b234efbf4b22d1e89710095321397a22a98179e92936eb336ba64d1bd35f7f30d84d07f344595035b30978e9b6c9311cd1f7723ed5346591f1188be49540c62932a08be7228441999a9d7a9075efd56ce0034a8c000928ca8416f91dec4a7433f24562e75db5632be999334f2a6726b557845a773768d8c9b8495dcdd4e474c6913676198968f139478a3f7e4da5a1821e8d25c52de7dfb4358ab744c8e44ed8a2e70a3a749341c53b230937dfde8cade31f4db385b80239c1e65f29b74681c5d8f5e876f113aac87ddaeaf0da31c1ef83695c3253864d4d8329a37741aba91c3e8a664a83f0b7eaf34b87b879b1757469a62410d51059f44711276347a1c5a3c7c7678d2f3a75368ba8c0174a1f834c1dce04c7c4fb5455f438e008cc656046e1ce7ff5c44b86bb6ac6fb3438021ecfa34b8e70ae7718788987121100e52f5b6300cba7ae0f7e0aa7d9326479bd643658ffd181b0c1f01042f5029cdc15d051113fd001a253c10c78b3f10357907dc7407ce136c8ce71052a0370a826f2a24443da59a7a38c2807410f999029f05be30586edd3b7c76dcdb8cf23e5c88df94e1ef26c93f972c6cc04283f90b5cc8f3afe258b0f4f9c19d1791ae707eaf9df318fdbf526fa68cdb9756d9f0ff85c2b923ef549a5ec073d4ad22f2904404ec439f7fb5898e27ac347a2b0b1a1500eb7f6f5635118d18852ac24ebeb50868c9efa0ae0cc5d007a401778f2e11cc6877d98036bf02fec3dfaeb801338993300e53cdb670634730fc83c9e28b1e80f620745123475ea5a4252ff5d807aa8542fb0c6f03bdb04e8525d45e9e91a3ec93c55016a322d8a7f02e8aad2b2be3d708ddd5d779dd63b89385111d5d8367e74d0f44be72d9280c1cc985debc2eced4503d3f7878fcc9b1bd1904df9d9f7eea4bd11db68b4f84df69ec13e23c66896b206517b34ebb6a6faeb6aba287327fb50c167388ca8f4cbb17044f47e952efcd10cb1e9d56c017fc51dc959d88c5bd7fdaf374f10fc9dfa2b812aa11ff6a9280e32e91b4a558c522727a8faee1a7ed56d7f00d2debcbbd3d9f15524c4491ce740c818957da3f17700e6f4d2deb0a37628284503368c8ad4b4a753eae0a4d637eb130700519400d800ea3c0c686825aef012d8b8fd9c8ed0b896918621602d239a05e24b81cbf602b9d0fd0b50000d3c38c7af7b035c6b9d8b56f782f5957386eb766d713d478c5f23e3e2507444eb57a78817369d02eed898104002d7ab2bf811f05f0bf1ada8770030925b691310db3640f63a41718a91e4b5d5a811222daf022e668e0cf15b5f4c1f40f4a14d36c3c7a7cc897444652ea15844500d1bda8c6fdb8c9946f094d1a96906f6970711a21cd58598c5d391bbfa0da0d26207503a85844ef6c57bf8683cc2400b9cb0df71e41fcd2ee2263fe17adaa5ef808f106af4cbb2a01c25b09da9e166c64c1749a1a04edecb6ee4285d50607d1a546040e8f2671d9a63500dc6a8577bdae4e8dbb37371dd292589c2163477b47401eacbb169348e6f2f1d141bc0ca8d7d2aa6246e56a4949c6e45f2ea7a064eb745193fd209a9c2fa0f38a01437e719a862ad0dcf6e347ad359e0685f6c6f138a069fd5dcc685f5d50031d0f9607636e61910b61e9e17ddc846dcc89508ad55a9045e1b13b70a17097c4022216d2102e80c3c17b6772cdd19298762b73ebbade239b2146a8db532eaf6d378ff39acc89550a640a46bf1fc8d04f7105280a6858c3e9100aa50b2f32b205fda164ed2faa9613b8b34b6ac1f1fb26e684c67f17ab955bc686244bd6d2e4124e669db06470e9c2f1a9804ce35a3eb54d1b3137bad0f8cb6d1140f8c235c56955be911004ca25d810472a90df4b6d1d0cc026440b77f83d2da8f0a17e009b6286dfb5d3f32e22bbce92081572c018b5839740794c965b8586434577dd6b4ddb3b36c6a77ef30745dbad89608b3ffd70f06d442ec0da09164087dba36f038c2820d3e6088079a6821e09bbea05c14801a2e787160dd9db28b0e2414990c6affd7ad95ee64fda22f1e1c8d6134e2054b4a7956ac8d46f5bf2813e45ecba3690cc10991684333e92900dd4fc9aa2980a385e63174ff12f998cdb4b39dd3cd4a9aa56d61e93c5113eb3473ec4d9a4c3b55d865d770c1dc69a5b6a8810e91c955d32f3208a86098500cbeb1628c9a93aa33a9b4eb22af1f7e33e77822d73b0fc3059bf9ba5f0f0726fdc4f4b639dd30a748eb8ea9e93e55cc35969d6d4b6c70345c5d16588c8233799272522d2725a20f106f60950a3eac8fc60dacbbf0e0e270a38f44f1820697be78ff8630b20a7386fb94a5ea3c5d11a0cdb9b79a743bf6f7f7de689ce18a6eabc4cfdbc4062011cb263a198ad9f06dc8364a2997469db87f15c8814167893b3c7b649e7c27ec59825a18a57a6c71852b23968563e12e22de09ac620a5db2036cb0f2706a4b579c523cf402a5b41fba1bb72953e281c457604453293ea7001e1b9147763d2a8ec587c2563f7ffb65c8f217c7395b56d648a779bbd6170c0e9b99337bbecd9ac8a82ec1b880eb4b33a5ee01484550b3a2456a02715a5b77c2c3207c6c158a69c578a549a82c495e5aabd192f10566b7a9c85941d39c1c580a6883081eb744b320304d88213f5fe64b0012f0e665dd7d62d9be9c345334a2fa71305ce4e2964071a768b7506f17b670a94ece1ecdf2e17691168d6c3ac277e2347525738196b25356f602a42400e3682b33f497062515a4bf4fed6db51d3933d5f4643451866922918cb67fef684d5022948a3515f854ae1d8e0530e84e7f274041d60005b25faa0f7b9e6137c68ac301c8dd56771048f7a4ab331d60a333053a139c4e21eb48a94dbd80872461441c324a515d0e0fa6c52e5d70e7d7e1ff1bbf41ab3d5b778e0e8c355e323b6fcec0eef53063b366676e23a35971d3510999cd83d27721f01e6ad1bb7b26d37ab5f8826089200e8fbb587294f18deb220b75a1b437dc747e26912ec11934b95e1551ff8b22e060eac8c09ae15d0b4b6be9afc75dda0deaae5e190305338f758410ce49ad9b9b75787b61a42e5dc2cb6a147a351df04e35d38c992bf985dc1cb8e87808ad4e54012de7ba0d2a593f142807ca71dbd6c5706194d3be79c0c6c11e99a2190391dd1970c88e76ed7dba93a5913e8bee33e0b6b32af9ba6f62399a6649ab915e1d6381083dea087d142d8171496ca623808337a0e0ebde307554e19b96ec224d0e9fdbc74834bd0a4a5f8dd8d93582a7634660a9a11252200046da4066c5bd4298b9669ee185d029c790179a43fc08b2ee170beecb6d3f57b19ef4e9e14720867500f83ece013679e5bc5ed613b8cbbbc4d5c9664aa790984b227b2d8df330200f0cc0a16c167a0225d6e1c1bbf3623e19077a6fb8fd20941a0b9309196968477e8c9a12e6cdf7c8ab8498509b2e7baab63fa76c25c4a5cd06b5069e952157203c83654f51f5a2b2ad1a434ed5ba2842e875d78d06dc8f595d91cb28b81a0bdff4da939462c9e045f8e914be8d359d3eed869d42da1694bc64ca56acf6000486c8e844982ca2f8ef43139f6e93d76016772d40177d16d7c457651ae4ae45dd2cd16a30f8b8f2dbf30e942c9011d8a2ae5d2a2dcf237e24e84445b37dd8435f4eeca89af80e7f6c0386824180445586f6ec821d866ac93da463624e075f1772cec40b134eb44786f78a96fff28e09468c81594d4c71260676f3110589e879aa0731a888f3b14428a4d5422d63f4076c15a77c2862b420ab1fae43b6e5f0c2f831379bf3af7fe9748aac1842d262487139e3550d54e1801c63445ce6602a56b4998b828a0c49a5485a24d2fe624e86b88d66051cc1a01b960f1cbdbe3cfdb50290400132a07819de3ae92c500584fa09beff22efd3cc9f6d7db49e5516f0d70b15b4168441806c818284fa3b031d5c5251a70e21e28e4a6ab554bed883d617c2418cab0310a7e6aabe1ff60e9ef71c54cf7c51e99d4ebdd9b48744321d5d1bbaa2ed6e2f6de673a1d97bec65d8abc57b7a749727fb5fa28cdf46bc475dd2fcb79e907491f6b935b90eeae631bb3f9576722ca14b48b7be2ee3aeb1d7bed76e5e5ddd6fba1f5dde7441754de9fa55bacb8751de8913bab1ba82bb94d37b5e0c1d5cc7baf6d3ede5bc2a0b435a4e2bf2eeb0372daf015d36b5bbfc43963ac8d635dcade75d23bacbdf7895d9ab6e48dd1ababf5c776b650691c7e9c2d415ac4b52d74e177a5d64dd8abaca5d8d783dea8ab3dd42e87011d2eeddf4d6f476e9f5f0f2d405ed9aeaf5ddbde744cfe0f9583720d17dada1678d5974ebe93ed4fdd7fdd55d10bbaff990675408ede6f4727a7d7a817a35ebadfbeaafe2a66b9be1facc689bf8c930abca77684f8956c0b8e719c67893cbcf07acd96a53f5706355fe36225188880a23fa090a0983b42efd80622050158e645920a3a3e79efacc0535e24664cb277d86a2b1fef7660e7f141ad76eb950045eb3a80522ad1dc22b8ab5b73c6c58ac4cbf9b9b927bb5045957a867ff01ed2017181711feca5a8f8696be0879c9662ba0fd6f2b3215cbedb600ebce62638facd876494f9e84ed5107e8e6d857f580f4dda4797c5757f5cc8de220280f2e4dda454c90ad1cb649e5d9b0d7d09af97b2e89b99a867dbb64a904208b51fca950279fd0046d09cd38f5ee40d794bdca940b38025a5181532d6c071840baabd90215e000569667e851533f098d91226053424ecc8565812c46ba5997b570300abb2970f659d5a6d528fa2578736588e78d00ed9a2555573bf7ac19bae4736776cebb85ef1df6f67cccd87173c51671ffeb0b2a98163707103cb76c5f70a4a6f42e04897f5d591c2bfc5ede80097d1e43b30ee56f59ff5a4fcab15fdd6cd74f8927b0eea5398ef55fe7d3f44d6bd641fff3c20beecee4ec0903f129e187add46db60bbd1da525e3033eec967aabcf936b6c2e49fa8003dd1574f501219874cedb2632f573b05c430c4b21e2471ff5086a4e74c6934d3f9b8368e66a687fb288eca34891b8448e8e2cc1b5c8e438694800864e62d8bb3d1cdd1b9f2ee83b8a2798a4a75dae39b5d0fdb0f59b374aa7e72ff32137519b284623602b02a7755a09f82ee10b290d1be4ad3d814fa6db0ccc198eda902a1181439a20f48686f5f016d9334c4c375937569b7ffd5523c106436c2fd8c75bb943e57a0c54429001ab84a78230814c789c1732e94046e8c4c017a30399598114fa5581e2126808ea8e405601b80c6418e6bff97423c83457052f37c1effc7dacfedd74108147102fd5fa380bf3ed070668e82ba913204d78e6272d5ffab557d7347489406e20b7e00a411a0532ed422048bfc0af00a0b1a80be0815509bd41ba5ee0270aa55ec546810cbf0722e39a7fd5ffc005aea5af11c90288bc48f03209ebf526023c0f64b247505134a600e5d7a8e7194f18a3d485c363d1b58e491b807a3bfc3748fc143b25120b08c5999247fcef837a74fc149423b1c2485860e00632697ac8ab9eb3c1aa39f64b0b029001c102d902b6026481a4106432498381eb0f049169b06924441db2e7ec6b6ac12881c31a647cae7bb34108826c1f85c3707edc54d8f600ad48d08d505c0632f9a6f40035952023490215d22cd0eb60a01e373c18580c2ebb02610f4d0913f8410135124ab856bbd78c8f1a972a8155098d446776e00d44a7a92750511cb095f42fd205d9ab573352e50bd60dac46cdfbf659e1d2c7807d94fb0ef2360932c11d28838bc08f1235000187ab2ba806eaadba654f65ef868daa2029c195d1347b68a1c87aeaad0b028ab53b972f4074904207f003fc003fc00f20db0889adb5de499429c9f2a95e21e722534a29a59412c3d7751fce38df70a4d134079709030935092849abb65d984491a3fee424a6e2a73fd8564f1746d50dbd3b9fb4051d2acb8569cee2bca8a43f8ee75de8c00597d4c6926c49cadda2f0b4af6ab999afc3166693740853f7512dcc277ff20875afca26b409c0600436669420081f1011392cf01a20e03043072dba55adbba8662db216c654740a22f24255981db3308aee1953e2d9202965094420821a23344af0e8a4ea90c58c1a353c7410e2e181808e5898836753caf4336ad4400974c0c268723ed9548b5f613a59a7962b2a115718bba40e2f4abea9e9a81506b93f71fb16962459b3c268b296ebe8f419f1d32acc419930419892df249d9781d44e154e03e407346e38a02315954e6a54ad96f11e21353c6c9c19666a830e54e8f2d9a6b16919e3a5599f3f5e44ce969119a9e314a652f9920a6d4ba2b63264809c8083c314a610a679b2c80f35cbf9606b187494c220bedddc454cd0771529cc7ae55f41f4543d3474002272a330a6dc29b92d1fd5ea1685d94de9c99f243b140695a49473d4149d3a897fb0257a07288c2e6245895ad3232ffa602b9f30594a1f269dd88e12c4f484a99389df9315d64f8c3ed8d63a612eeba4dd7992d6a5241f6c8513a6b53bef52ea3927c71f6c3a3661ca3b2a558a73fdea8cd584c92efe255325ac8e124a5948d09109f3ff870902e19d0688475a0a3a30619244d733bdbea47b4c973069359ddb36276809e21f7458c224b99f08ed163b23229530a7493a8a50514c5aac3ed8da2861ba50a92f9ea75caaf5c1662be89884d154c7bc18714ad8820e49984e662f947685f3794522615272ca387d79623d27618384593fdd95595ee41e61d0caf124b784913dd20fb6e208636f9a6625a1a4dc973fd8ce4464d89801f27b35403c6c887434c29cbda2ab6ea92ff7920e4698edaea477d30f223b7e4de85884a9c4f1f867e1977c4c14613ad1392de82ceae78e44986cc484e9a65a07718208533a5954f81cb7435cf77176b9adab62a525cf8ea13f091ac27c27ae5fe5523a9e2d84693e9c924d90760721cc5616b4bd9f18b24feb1884c184ba98af5d259bccd621089312ba3a84b0a04018554b892245ff75923f40184b527be6268a8fdd3312aa20082724e4e81f0ab36929c7cd9c5bae5c8c396b3bfc6012dd52a85a1377f4c1e4256a46f498d09d8422aa821a78c4a0830f26f13e42cdc9792fe5eb83bb6f64c8888d8e3d98b34bc9b65e930439793d98af32cb3a85f3141ec22c74e421f5c935b4db1380c1086ac08083e30735424254d0810783ca89a73b18b6949ae06f723c39be7630db6a9f60a5e44fcb50471dd00c2b4bd72a97b36c2ce4f88f2a41caec4e07f3dde75d0e6929f44c47c4d1eb113ae6605e7d0df5bfe35e6b92834909ea5f64b8dd5f34fde360f44ee2cd3e880d07e3096af4fb83e90dc650928e39a69d6e2fd5e106d37d3c21f465bb0de64bef954ac5b4adc36c30fe8d09195f4b0d5f91d0b10663854b265a54e6684b01e149c0c10184ffe85083f9d6f32fc813e75d4f3ad2601a17bdcc4b9ec3554783712c8993cb44cb9a1b9dc1d42d26754bbcd196630683ca9757fff94cee313bca604a2f222da7920e3298540e65c9dc741a135f0d19cce81883297fe7fc8d0e3118467aa83269fd92d8274e4247180c3aad5ce5e9f99ca7c4c376091dde9c86cee9c4afbf600af1966eeef582f9c58210e7e9a4527717ae7ab313b7994dad98756fd17392439570c1a44dc53cb1e537efa28e2d984d7afb8fa6e374bdd81d5a30ed7d527ae6dd3fef25c4fd7cc8143ab280a990915dead21d583049a635cf4787c99620918e2b98326d2d3ea592d74e4ac60b38389a091d5630763895b3b37c324c4a47158c1754c5d7621d543029c9566684c7765653c714f28ef3ba9495d7935f171f1374523ba460cab1f4e7a81b2a5ce88882c953b0f6b8b5143aa060b279cf13f3781e9c196a19e8788271942499605234f931718269b404dd1e4c124ac95213cc3177fceeb3f466e799604e41899730af6309e6a09e942cda2525983a9cb8f87e9a76720a868e249884db074f7e695b4307124c723577e4ee925462551b388e619254924cad9cfc388c61b439658276ecb929f972068e6298b4f4092bb292fbe89318a6f333311fbd3bfe05710cc334b7a2ba392ac9deaa55814318a693175efc4d46048e60184c67c9057d9ae3b10103d31d3c484be62f4ce2e2d45ce9926f2ff4456ec9526d56854b8b7535f2b282f7961ca6ed854910f9568fa6b2534962c3c6c13b0e5e98cf3e872d41d8c6077b17297da5dd84fd521766f99225d989df0825cec59ae95ad1dbce62c75b5792df4f52427333345c98bce5c63ea5a758da988170057de6020e8e5b984ee85293db45877f12c400872d4c7262e1653f6ab8273fd86c80848c88c858ae85b18332d554911686cff6ea9372b8291316c72c4c26e7e027a87d979c9418b42cccd9a4a44b905ac99249e2e00003472c4c9296539694c8115a270fffdc12b4b980031606a54774897657c2c0f10a634813b30f0e5798cbedb35af34c5a61bbdaca96b6654b75cf3ccdeece25439f943870b0c23c6641fbd4662e5c3ee158857176f4a792649978b104324315264d0f4ad250f231482e70a4c2b4ed39c4ce84bac0810aa307cf3ed87c00e21882d2672f23b951c34b1a9ec224dc67c9ab25c94a6599c2ec1dbef2f7e875f1bc14c6b724e50b7d5143059b145bae2eabb4bb751d9e3da51c1e85d1475b4e59beb38e2a0a8385eb9653ff3842612e25fe277f89bb711d14a6ca72594cbcb44bd18280e313be8f4eda4c505d042e9880274c27b7569cf8160c383a61545d51d144ab50ed45e0820924270cfa4d7bd28fe979d2de84f16af446b343cb9e18248980b489c80019b9a109639d0927c73b7b763765c22cfb6796e34149e0c084a95285ef94175fc2f4a6cade74ee78be74b1c16109c3e79874262c8921c408a4122629dbaf99f820b231250c26464428256f1abf4dc2b4b26179b115d44d2a09d348936276e364ad9f6bc9038e48987a2c6c54ec29c9b40477c00109c359b0923fc1843c1765d4a891c8e07884415e520aa9e15102b6906f157038c224267928f996653fe97cb089fc071a39333c6680848c74c88848238c96529ef49dd6f296bc0c3818611e7195f7d361fa10bc8d20c0c0071c8b30474fea55d7ab83072545184b94a45b4f8e2311a68c7867a87aa8572f5372124ed7111019365ec08108639e24fa872d9d43986a4457f024491bc29c946423f3528927d7c85108e37bed5a901bba73bf1c84307a0c7593d5ef20cce339f24e0ce5f971148449a92027ad053d9167b22aa881c7e1088479d4847eccabd97ad00d191f62839b0310a6d8d9d3e7fc273d6a7d8c1c16e4c7c8b1914118b9e4f80356b1ec6a634cbd5bb37cac73107e69a2fe317258c0c1f13132c2c1a17e305f366972beae9bc5f203ac0a93f6492ac928413ebfa930bd68115969c162afa830d8a7480b699652509ec2a0e24f990a52f468690a83dcc53b154f5c44a530e5ae20eaba39290c361f74bcaaae52988cc21cd6a669aa4b4461f435dd925e234a6a4928cc967368adb1d4410a0a63c5d2f1e3efafcaf409835dda2755923c6192c4c4ce897fe9a64e182f48d1b024cf0983c79ccfeb1f59d9df84b9a468116abce25aaf09d3499fb9519e4c18f6b26e9c7c4225318409839e494ae91111a7722e61b293827a7ac5e7e558c2e4392a8ad2719ea25c09838a0aafcb2f254c6fb735df97c4f1741226f5f9fbbe939230a53f490811ad2261bedd5d4be13a90308993d352546d8ab6ce23cc335b7ada29b47a92234caf7b4932370b96fd469894f849a8934c18614e25c9b13bd48a5ece224c175774db3d5bd88b220c625e45ceec449872927e6f225dc562441877f4ca2cff9e68da4318845736c9f7358441e4986c117ee9e52c84494a55c1e5469f1426218c6d3909ba94386f826c10a67c26eaa912cca365451026d94356c6c711e656098439fb870061b6bffe2cffa46256fe80074f1955dd0fe6fa792b15b7b5d3ee83c92e8e0e9bd712223e984e3a0be1fe274c76f760d029087562c57ac57a305f8b1e1d6b1ecc2e7ad4f9a5783099ec15bff6bb8339c7495a449576305556f2ce72296bb93a183fc95972796c74481042c8f3cf5acfc1f84969a8d5fa3442d57230c9a8feea8dd697521ccc696d9f544576551c0e462f9d4bd408bdc130ef234225533d4ae406937dbc29b96b0f0fb5c17019fa3f8657149d840d2651c7732baf3598048f3e7b6aab4e76d4605092da2739c53b7785d3609273eace1f677f5e643498a4554ad94f9413d9f1198c9fcc44d39db1190ca7f38c302fd9affc32984ed465a98eb7e1276430783c75d24236bb4dc6603a7949145d256230e5d35af154faf76c87c1204b67f3e3c67ad082c15c2697d2299a4c4ba25f30765730c94b5e30ca999e57f4e4ffc92e18ed635fb7ecc5ff920b66bf4ae2762ab7600e7d1d4a27cfa99d168ca2738e995fa7f27559308a2ad9e7795b2c9884efe027bbed15cc2ba78458e8c5d69315cc41df8ba59baa6052ded9d3b253d03351c19caaa37988eea8ea4fc1d427e90bbd242779232918ece4caae2ec9841645c1dc37faf7f6de2a28818271ee5a4d499a6ae9f20483bafaebce75ae753bc19c3c44aa5eba09a6607f1f3d9f5bd033138c6a32c593bb4b30d78f4a09a61b694a2979b424985c2d0927f2c63d8a86048392d23e8eeef079bd631877cf4ae82842c6620ca3afa969db8a613e41cd7897f061b4a6c43088948f32ae0dc36c5eda73ca63e8662a0c734e1f2b6997eb9e4a83612a532a0973a6835e1230cc298791a7f3bf308d6c8c7a2f6194ecfb829d7dcffff47b613ae195f37249d0d6f3c218ab5aa12e8db9eabb30fdffeb29f9dd924e7461d86ded24654f2ecc23f37bdbcbc4380f2e4c2a9e3b4e7dd2fa975b18fc527c7f4ecac2a5d8c264e94185c9762d4c6a61f2c930a13e575a18d552f6f924ad5baeb33096bc54a7722a0b9370e287fd598a99672c8cff7ad2c68dde37818559c5da4d5d2e5f613893f2f44f922b18b968af1ea65698479aa5ed9c7e84fbac3097a68a7dc719b39c5518ce7e2df4e4ad68a20a93a47167b25352618e514f4a33541843c9d36bda97baa44f915222fc047db229cc39a6e9f025a514e6901e3474b2f029aea4305f92426d864661364918dd1f11da9e8ac2dca33b4ee8bc1439148651da4de78a7cba101486731925cf7d8a957cc22016432825c7d013a68bdbc104a5c24e184fce29e72f53c1c7424e98e3bd5cbabf8739a54d98d5e4fd88993ea9e49a30c82bdd75c29e09839fbd27956f553909268c71a5f774782e618a919febbea48f53b184397e99c99dfaab84f9bfe4fcaf4b09f39e64e296ba9c525027618e3f5acdd3f98f1825615215524f4c353bc945c298f2a9c4c95d694d3b481854904f9d5a2b9cccee1126d5f93d7ad6aaef758e30e82c3541da9b6c5e5d234cf9f49274ae7e57d531c2e426a7ff1599351b5a84b9b2945cea278a307c8ad7e9de245549893056aa4ef52375748a0883c9a57b74c58a501ec2a0a4943f076d6782aa18c29c93bd5ab6ba10a6de17b724ec57384b7ff1c38330d7985c2e72bfab654198f2a4104a4e6a5a9403613e91f1e649de2f95058429f8772595a42f53d23f982d4992a0e412f4c48ffac1bcf9bb21d45c929df6c124d42939db9412cc523e184f8af638a54a1247b907a3a9f423dea2be45d3f460ce4fb597d3cc83d96d47b6bec9fb56e2c16079754dafab787f7607934ecfad346d3da9991d0c3bea92f4252c8a685607835a4bb24952d492974407c3bb9fa0533acdc1242e49a1bfe29efe921ccc9adb41e9949224d57130557b9f54c2c16469fed2c28434417f83e164f9fc2eba1bcc7e552a4ec5d0d1416d30578d8e2174101b8c57733d622d073fd11a8c9f4b2853f293ba6851832997905d49fec84a953498b37db455caa2c19c4cea6798588207f70c86ef4a65a7543318e4fa49eb6b49977019cce9aa372cc5899592c1fcd94c6754f2b4dc8dc1a0c45f0c79366bb75589c1247f0c154d8979f5255961307dca5652f894625fcad7402f984281c1b836d23a97dcbf605dc6bbbd785ac8c5eaf86c51f289ac4982ffc1565e30499d8332fb924baeb5aa0be6926925593e8f6122545c48aaa7aff821ac2d187dc6e74eb9a985bdb2775da6c6abd7ebc5d3f569a9da56160c2346794ef9ce55410d3c6a5058306a48efe05a5fc154826acddeee18ff90154c67294ec6e560150cead57639c2945052904851c114dac376baf2d3693b3505c35eae79de393fd8a4600e1b65926c4af688b61f6c782021231905c3b5883a412e37c6836c302828982bcd9224c90a5a6e4e912718f54a3a4ff2f555e96bd47082b93dc6a68d58dca86e06d504c3253968cb6ef557ca144131c19cf27a4b92a4be874e9ba09690a4c52a2c2518c3ed7c734dbe888e6f25c1dce7a6e494d57bb70b09c66cebb174c24d10fa3e3b86495909fd1e5c94bc26c518265982bef0dd9e2d86717b33440cd3a9ecbadb6d7ec8304cc2e30459329e1fc46cc230ca49f15db9aea4124f1f6c3ed0609843094af283add3c88d326098e4fb13c424fffc5c930fb682444066e42f8ca162414bd6764b612e41872f4c62e1b405ab245b762fcc76268a67bf796198bdb45f8613afe3a81ecf56124901e2217d1684ec5bd73ed8fcef5806780793a4bc4a76bcdbb8bc201a37928709d00ee6b0aff77bb2223550d7c1b0196332342f1b403a982dcc7f4e594bbe2e3938076349fa4e89e19e1fb3837230d7971c95837e1de360f0a482d041ac2465c3c124a527a9f49c341584928d1a6f307792f44dc5995cd51c037483418f29a57298c90949aa65886d305b3ca9233f55de6ba0e7410d1fd0280107870818816c30aa992c39467e7efa6b0d66d39ef4a8c5a806b34793b55cb2c8fe5b300d064fdafddf4af2d1602a9db486e797eeec9c3318deabeae7e33efea56630088f23f65bff83924f1a60194cdadc73d6de3edd514206939ce3def3d7640ca69cf3c8d28ffd95223198fc3b89bde25fa353270c0659420a06a3b598b0a1bfc42f98dd84aa28fb9f7126e805c3c45ec3c552b06daf14b4546fb6dc74494bd205f3dcbbe9d91dd11d6711b151c3a3900b66ad68d5237fadde1d8d238305885b3076f05379f1839ed3e1c7a1164c999697fb3e6300b39055d66856cc5bbaac7026a79cdf4b59c482c9d34e094ab89c2b18be6409bae72dade2bf080216a040042e98809a26d00a7cb977785d6d886c85d1258daead94c42a2c77a544f9091da9603cf9ea94ec789eaf94e0140c4add892daae45c4b270d11d0484f402998c410b95ee27a2b58ea83cd460d8f432460140c3aacadb3cefbc14603a1602aebf58a71293f07133ec1d8714d977f3d22726494ed009d60fc142cdef67e12bd0f0ac22698ca2413cd32edb4ad432f036482410997bd8ff9f62f7a1f888c849c11912598367dafa42474b76cab1aa804a3f89f244c8c8b93ea43a3c68c1935108660124cea5795df7f1dd038211e6a238804e3a86579f224aaaeab814064bc40051c1cf908448688d9cb4812101a770c63a95c6277d06fd501a146e2c103746424e5658c243744560535f0a8c0196359ed12844a7e128262182fdd9e891a9d2742ec32561084238651de2c98ba4f0dc33c6362c9134bc7eca84e1826614de5557ad4b5985f304c96f2626aa2c5c1c1c131850386490e7d27c99b17edabe417c6fc53dbf9a2993b8dbb3ab116eff255d3f13b7e9e9ccdbb5e1876adde4b12345e183cfdbbdededc85712d49e275094a5d1894d29f4d10a57d827a2f1706d5d034b58f7f4a3e8b0b732c3ff1e27b720b83e7ac7897bee6399dd8c2942eeff5d80515cb502d38d178f9acbaa07a5bb93c7a4f0be3e7f50adb4fa5fe4274b859983edb28397d9770b230f889a6ae73f0b8658a85d1cf47ffc84fbb9d5f5898ce4407b7bbec15461bebca15a6f30da9a2f7d30ac42e2cca8ce5504b277a95b4b2fbb7362b0cb282ca13254fee746815d65636bb9b4ba3f19d756fe1ec842c13cfa20a838c097f429c1c97479c0ae3792a49e7d36e264e438559dcae4b924c7a8a4259123f5318ecb7cc47c7afc4b74b61ce65ee152f67cb49795214b5bb3aee2bd7a76dad658892b398d5a33075da553979432913af1385295dd8863eb19d47edd9830b85c153570afaea2bea754440e1ba5b8a5a49ad4f982fe9bf699fd21f4dda13065b3dbd2b4149272849d7097357b8a09fa4ead239bf5e384e18d46bc7b84ba10f3619c7ecdce881b94d98d2b7a5aa9cdb7388f35d5034613aadfde741492f13c6aaffa417ec04214a4988e1e038210f72983098a5d56c0f51f273b62f61f4b10f4afea44a091a42219c258c9f4227259c9c4feeb815e12a61f8b060a9c3dc892fdaad0a6ae06183a384a9848659c951547616651c25dc24cc2f4ac57512164a9c931cc249c26c52c5933f6ab288ae46b848942b5cca974ebcc141c2a04baf07a5fd5dcdef7b8441eb99de7aadf4f88f239284d59ff8a88db811e5fa12b9ee107b7b59cd3ce11a77a58212de3946982ddde52aed27d494d8224c9e54f80a72564ded451179892faac43bf3126152feaf972daf890afa21c2f425871357f62fa9b97708c355db7fceb69e214cdb77ba5784acfcd10049f60a61ec38d144b124e57ac9470873e6b789bf3519fbfe06612e3be526990ef5d3f69f208c26331fd5e402618e3ab25f8210f5b59d0e0e10a9a552b1512bfb0aed4e69f13c07d3ae87bc0e745043c62d10ee0f6ec8b9bff6d12b91c1f9c1fce147e4ca8c2cf1751f148bb714626e25df16d54a506a3c4e759658f1f8603c133de588aab894f3116e0fa63ad94ecb98d827057170e8800648c88888c78dd343fa29492d0b7342270f57b2bf92d5925f94c6e121edb157d24299279d34031b77874cc35a5ebbb3dae325b19e46bff4ea23221e36446670eee0ec603ab7ec7152086509ae0ee6ea4f82b613db5309277430aa7b8e65793ee751627330b7c94a9e2773474c2707f3f625f18adac5c1249ed2d5c1c1e849e9e93149c91b4c49861026ba17dd3de706838652fa96a349137f5d1bcef8545bb939ab4b66d244ad6851d7e4d860165929cec7d21a8c76764950693f4689abc1a4be453c76c54e17940663ef2549c9374283a99327c9c4efcae549ce603a25bdc74fd946891e3318e647c7d22e6530ec08919e7193c1d41a97b28dc1fc39aec991264a3ea518ccd7e361e6bc8292c63018cdb4fcdb6779972e81c1204dbb2f1844ebe44ef67bc1b027ac855c3bbfbb0b26a5d484e90b71c11cd482103b275b309d64668210134f44470b06b9962a3c56b260d0f9d35b5d8d05a3e737256cc65730fa5bba7072ba24955ac124447a6ead4fd258f2ab60ec92fa79a194b426f6543048b91735da340583b070c19485f2517a2918f6635ce7fb5130eaa8d86f224ab47728983ba885dc18f917fd09269d24bd52b932490e39c1e8490aed67254d304965951e6b4cae799860104ab4a52429f7a02f4b30a7a6aaf6f77c4a3089b85df83709a696d71a1d91f2be1e124c49990996963c865174cc536951725bd08d61b494214edbb675febc18c613f6c4b3b29c180635af1794cacfdaf961182f9a7af219cf345d18c633f5f3e8a76098ff656c642bc030a8feeb906f3a55aafcc214dae49c4bb6a074dabe30a8d0e14e16a1f2a8b917c68bd6a2836b658d14f1c2a4ca42dd785dca268a7661146149ed6249b2a514e9c26c99a7848b622ecce19df359958f38e1c2b4fde14d56ad3a93bb85592dd693203d4e3c6d618e596257b9a96ecd502d4cf5be7ae2b9cc2749b4302729c5ca836cd7d02c4ce13c78ee139dbd735998449ed83f268a85295b49f23142b030456dcf35695ea94a5e6110aad54a1631492eed0a63bf9eacdeba15464be993480baf92c40a838725f511b29d6f5e85b184d01f5a7c76b316d8ba80d905eeea22f0a103101a17280e5e0ea34001021084e402fe22228f6a84d858000046446eb8800001781d9c1b3aa0716420400022218f6e788d101b09880100020000000040000b00000000a080f71a342e20d2ef35683480012b0262e32c20008900808848c24100019c91e31c0508c019395e2384e300001800041210f21e0c0040001e708020d8e005828cf800c477812023323e448e87470252173666a05c24af3123152071615cf53c13363d086dd25b00e1cc4804485b1c206b812023211f22323c3c1290b430c5afe8a973bdb3307d2749127a61f2a7bd6561aa3e0b2ab7eccd95508d19337e06cff8199bb1c8aa64f9bb1cb38166fc8c9df1335013168906c88c54807c050d90198900e90a933039efe53fce2e5e6346fa1839337203d90a0419f11a336e7878242059617259339959b26398f083fbecc69987bf1040641c10f436448a8dd00041111a202332406e241e212dc8558cbcc88c9f61805485d798910890a94840383352011215083222e3c60c0f0f04e4294c996b623fc8c714e67eef20634adaf81db314064f5be2fdb32895a693a41885716c8ac2943a7b10f2f4e85bf364288c9e2dc8bbd7b7fe17144611622354e446e315e4274cd2579f9f245e8ff484493095bf53fc2a41cb101b40f84e9892bc8e4f52d65f7a13274cbda6b43de8b44f3a64426ec2e8a62b3c090fa6e2b7d4c4952aa558a92e7d651bcd36794866c258f964dc73ce0942942270c1041213e664b2c7eedb4a55335ec264f52727597c63d52a6909e3765ae94f59a98451fdc4932ecdfd9f7a29611c4fd13357ee244c954f98d60f3296ed9384e1d35c0a3e62dedeb48c44f2f5ae2297d6522be4b28dd07ba71adad9848439bfcfc4550ba33dc224687a16154a6bfae97070a4238c955f6ed1ac64bb20fe60f3b05163cf04d908f3a8df761125c60873caa8ee9ce453d7cf2fc2f4ab57823a71f74b5a146192f784caa23d904c8449ae54ce9ba1eb732d8c08539e7ac9a3a64b16cfa143983aa7e792f25677bc3b6908e30533adabb2562a540883ca1bdba5122184f94bdb9b0e2ad7c120cc7f5549befdb5fc1c09c270f2e93022fe48e3200361d6bea43b7a98db5c8e0e006170cb5b51a2a585ca655243860e3c465ea4d81f8c6392e82728a52ecc637e309ca04a92f298c925057d1fccf94f2a4916bdd926a7201f4c3a66265f540e22eb0f6a84e8600fe6dd3693c3789204bbfd834d0fa62ccb97041f59e447b4069907a3c55392924eec9c04b58c0fc183c984efb2587ba972971b7807b358e9854e2e27fd441a20891d4c1e4caf6ea7e8880f505a1d4c9220ed9467e9d7ce061d0c7736d25b3cb6ce723f0793a404d9498e92fb602b72304949dd79cebb566a486226838c8371b6f333c7a46839367e4424657088c68d942a483898f20815d3c193f20daaa8979c87a757fecfbd56da04991d0e0e37184bca33f7bf62b6e19465477f967daacc68241b4cd963625e0304366c9c909155410d3c6e906b3065c4c2dd67cc254ba5de56f24dd492d4e239483598d693f89877d134985d3cefa9ac9dd4c8190da60c75722c693c4b797f06c37a9c1394ecde0cc63329995c921cce949c530673573ce9697d2383612ffcd8889534f623442e30432167390663f52561f721db90111b2906d3e7effc24491eb530988338c94b54f23269a604832673c962ddad5adec5ed5a56944eda7112e4174c3254099e37cdf482c13bb848f5f4c92e98db243769bba28dff13a8a0061e2e482e98542c754bc7452fc73fd86cac6dc1a467ba3d94ec95fd93c8d91101c1d4827188c0059d055350c2633cde050ba6a454a509f369547f2eaf60b090a3f27cc765f52aad6036314ae6b3831ac82a982ca6c71331f53962ccc54052a1b94aa55ea72d6259ede5144ca17aefe24af61c264f2998af3ca5d352b28a783ca360ce3115fcb2bb75be100aa69caff760a97c82c9478967f1b2934e30951244454d5213d7441f6c2320890648c88708da07b209869393eeb3133da88f950e24138ceb2979c96df15c82179eabe7243d359e0f360fa3412ac1e8a59f6295ee83d13c904930894b7fba6e3a5b094a9e4622c1bc2545ff1e773fd8f818a61b517aa55f9d52461f6c42e8c17b84241e232033decc18e6fb64d9d1c35a9f30fee0699462a0426c8ab4301a0f6880bc203d80c43056ffc9e1243fdb123e1f6cc330d8a7cf262bba73e3000ac3a43fa4cbfb97efbafec1e6f13e001939323ea42e18d6ac59b433710fb54ad1732895a4e4e2df0829d6c030f8a8784e2a5b481715d1b8210210fcc2e47174cae7259ed2657c726478388d2f6f230830f819274404692f03847d61d269eb63ae27a47fb017869357c4ecaeafa8517961be8ba6d2a9b57117a6feb292e2093a8a757461182594b01667920bd3769f24fb4fb034b9425c187c2feba756d589ad6ec1c69bab5a0adfa51dd75ef25e50137eb0d53822201c1c323e3928e0e07819203666d4401c1c2c40c1a22d0ce22bf7c2dce42446570bc3d5c591abf849848ed1c29cfec4ec5de66fba6916e6184b4a897f0e29a69785399824a8fc21be047142b1306a7ce509164d4ed21f58184c5578b4e4c19368e32b4c9dd4ce6d4cec0a53692dc93636bcdeeeda56186dacc489134dada88f082b4c925ab14f4ae9e0a75d5c853989e96c71848926070668daa80a9368e6a2ae63d2dabfa9309992b257befc537e212acc16a746cfe675d78d33c0536061561d6fb39d366aa77da0298cfd5be779f6a4507e82a530b577f04b625ddf4ea79014e620c65198c3a5d47759944461300bf5ef24e93db92ca130697a0963a269e75853c9fdb48f50e169003ff103f44410b013e911a7656aefe43349c809c3b48285db8ba5ec953a4775f1e0260cdb167af5834c13c6ad784947e4a5f5e83013869d5382dcd88c983086502a7e5749f2323b9730ffecd58e7f32a5e7ab21a3aca025ccf296e3f2f9c70e0faa0496bf4af5c196dc10c112e880064872e3053b05a484d1eca4a9f211da4eca380993b0f8d1c46e64953c3ed0c899718792304d89956a374c3ed8426c00e13d641c1f7c62244c76af5fb515e4724148ce1ed1382322344a900609b369114ff3a21f7e1f3e42b170e9dd6d2e887a59c54fb2ffef9ca90374844168d7b21cd637c274c19364d7297950254698e452be2df33f96b4651186932d5b8a3028d3237af47789308baa8b735751829039228c95e4bcfc5582fcf2d0210cbab492fca8723f416c08a3aa0725cb4e8cebfd0a6174cfa1795a374218439ab60f2dd5208ecfda56595171d30ad71022ae65dcca4f4198468bd82dd11d1716d141c8f1b00b84c1646a494a673f893c68dc08f1a8e108085332d1d3abb5ac05ff60fc2d495e4ada154ae68a7e30e9132e9fe8174fa50941807d30f6de9d9ede356444d33c66dca071c807f3788f2511d332a2f4b80783b0b21cc6b41bf22325b002eac1246fa851f2a8fc1425f6c126e2a1c6031a373e46540598878951a8642c858342d27030168c44025130105236cb0100e312080020601c8ac502c2509ecab9aa071400037044263e3c242220180705428138200a06c3602028100604018140301004851e12b5466aec6dd202d642c7d1043a3303790457422b52b1483765c50ec603e390758149ef1a47ccd51a256ad7a2e30d23725ebd5c390a40dda5cabbb9717f88fa83d8b896bc0928eac4fa97dd102efab30dfb58fa3bded1b9d10e8546d76a118e1c7db2e8731f9f7d1d4d1ccaa4110e4e65f18d10bd829455e32ffae1b30f91a700bc1ca8a529d8343d6a8c7151890a723baa76852b405a0c5136421b3b0652fa88f6dfc192d60c7b43bffdebbab681df7f89f73aea123ce3b6576a6073f0fc6250e4f2cb84ccc00f8aced3ac643766987c360ba84482a1b0f5c1aa89f0bf35e10272e09a962168652212740c44ce96238fbd12658eda8941beef21a08cd2a481450f73a0818bc4417dd0255067cf95fa01007124cea80f88831e7652235a0a50afb1d7e731cf341e044ae71b71316280a05e5c349e3fa2d75c7f7a3f2d8db63885800b15fbad77d2f0671046049a64c10145aa098011d16299e65000abd35f9542496231ea457845d2a067cad9e46a030ccbbbb8ed374887fe5c083bd8fc8e6cc4ebccc5cb17862b9da243a72582a8118a599d8b36ba711a87d89898b4002a655995ca2be404f2a23bdf430e88093b2a0690be06977f38b56e30d0fab96c7ea6cc82c62cff16440f2171544c2d025c61f1925ad00fb72917faa9302493f43b14ee2a6f4e310a7bbcef9458daa0e7863a7c43752e0fe720907224f53870c716e0a3225ffb68efb1cd035717e80f26283493f19f6d3b39b8414abe59f047bc24ef9d6d088edc2de906c7843cdd04319a535bfd982e4459fd26ca2b9b1228e28e41497eeedbaf08a387f5a87a5e51bfa44cb2b9465972c196215d675b0f2e6260dcd11756f37f755e2c86b95d9a01d8102b782d16da29d22b8ae7b4e6f8883ad1f322e26fa57c80bcae8b747476d411b7adac62c233c2619ed943a4b876ea232ad1861471462392ef62494bf68e048d312d54568079b57794281c91f827e3c0a18f157c5b0e1c65d24a58a827e17c1a5378c930ffd84f3238cd837c11b905fcd88eb61f864b6079f339f45faddd987b29f6f8072eaaec4800ddb11689b7ecd78fb5204973113050a121e0fac233b40a106490989d6fff2515f0da8486682c5b705cf471df6279ec4965f206ca8896e32b9c34d589a659f18aa264672d106e0e19b5d3b1c66f6390c4519a8cd6d17f805b2f8677b6a7a8bb647356f9bf3effacac6914789ef01a39d5d775d634ec2c8921437e56501c775ea6f98e4ef902b0adf5ee88f9aa49c5f7010e6b16e6efebe134896b0c5d3c43afdfc09ae7f0588987216b055276cabb102522c103b7badfc9c42befd4e2deef1f42548e55c7de9985927e5a47be46ce1ddece4bd331a29b5a9d035deab7216ddc26c9261fe9920ea204740d41889a950cc5561d63b0070a4f8848e66172d69fb4f4a9ef5ad9a29ac9fb3ac05e14932e6ecae241ff586980da5d5d4a733f2f2a57d089ef538953137aa0883dbbd042f48f1de869728dcb57129f478199153eb1a7fd9760b4d585c6c808a537107d605516310bec2e7388d483190439d129e099ad6b04d5548a42ce1982aba0223972b107efb78e2568732db94ee9bee544b10f31adb6b1f9d8867460ac1bb5c450e40a5985c0c316ff80aa34138a361bfb291b466255a3210c72f296335e37c5073a314e7775f146eaf05ee224dc4393f28a7e8ca114448643bc0083899467574d3303e26854d5aa238a4786530804fb26961674882cf1a3f164063260b83eaa32e434b781cfd15f4a93c3bf8358b63dee87d00e9828574a92a5d539b45c37f24bd7a8c5d683da32b2f45e6859b6bca23221cb529d871ad042bda4cadf28ea4ba5bf07521e0cb0089868bbac1be6d46010ff54b331c81164211d7baa4711a898b9b49a27257f7e4017886c659e9aa19e4f9bc9bdda25c66d0fecde1dd224c7b9eab77faf1fc35dddf7aac41fb3b8102a30b9442c76cb10dd6b614bf1e3e692041d902e9b4e035a1d82665a484b778bd1bbebfb73897f9e8e0f23423eacc2d750314760364849fc49bfe1496c7f5671daec006a8f4b8305a75c00b937b20c78b4a94605cb0ae9324c8529847636b603f7ad512d5e02c681621a52f767082127b737acebb3b5b11fd93d8039027f1a47afda0ee071645304ce4bd77e458ee384159e6b5b587efef9df2066adc1e2932155486c8ab88e3a39f5616307c6ecaa44b573ebc61c2081d89d8428e997d17d016ef43d30b788b71182ab1e471588c1cced97288a4640029a6f51a74a070490db2c59403c751c0aafbe6102aa00dc361b6bdec27aee50f94a7be8695ece5ec5dcb98a80a8e18d4dd63c68bfd2bc9e14d42ff2ceefa39cef1e11084f0f1a99495a9d4c9f412748abb5e2fd1e0f45c9bd0608118b0a4460278b3723903530dd94d965419d70ee3a751e3e04a9e15008f8e51223fd921cd8a55f2ca5702231a0f64920d6b8679e79eb2c9ae29045d1bb37d4905abbafa59cbd9c5b197790ba6fce4a497be58a6a2f7a1cf12591b29226dfb22d392429adb9abc66b59f03ee64fd6d081af2197e63f971f24841804c03b129090293e14dc23bdf2f50bcd29f3e25e29e31f0b9ea46ef955319c7d788e140e97cca1ad466a0785adee2a000653f7b5b09b13463c8368dcefebbb4e761c2941bf36b6dc215e57731fd5c6633297dd722db240eacc4c98632c89e6a23d3e925db23fa3c0d4b176cd1cbc307bd7b22f6081302011e1eed53f45c63cd3d845e220701a9600d2670f78b802e9fc65c602827741b57fa7653382338de1e8f7d485d20a0bcc46f2472c9fa2bebf602c1e04ccc41210268a32699e42e3b906e50bcfba8837ca9235d17958ce868c2615f02ef8e811ae58cd7ddb196f550b521519713a543e5f8a62024e558258d37082aa6938d7e701d01b83d938945a8c84b4d1cd167b00ba7dd9edfe07c50e653f2844167133d42fd970dfacb889930514cc0581bc948ef89fcf0bd66b7968021791b468518ab65870c72a1ba2ce420d3bb897c5a55d275278d0fa7f67e638e742e83e872b2302b4b5f7bbe0a70d290cac1ac56c52d24fe589f3e1d3afcb49127ddae7004546bff062c62ca2dd8885450a3219cfd50fd84e4da6fe0fac56bcf6f9c6bcf64278b465a209adfed5c614a057ededcb7bff2c0088965aa85afcfc4d04273366da26af227c9971d84092bebdbffd14a074121d1ba617910216d1bf8edb6371c10b601340450413381867dc080cc733a50fffefebfafb7f80b51b00fdb7cdd170e0f13237e0679bac452723101dc83234b5bb1196f5165dc2aabc208994c186295fbf700b7d18e255965977a86f0eef1a2fca416265cdc114473f318f992231e0982fc26a1f35c3f8f7f5a43736b3dbddb3d1056673b6da7f83a3b609a38a86d8abb86a566bdda4413ffadaa1d6551aa6a0317812f3fc1c7769a3b8417da10e8a08cad44af99a7a8b45329702d65d234dc41b0d419d5e12c5abbb88b95e9f8161b439610ea18a474f62c40284c81380bcdf8c038a89ae78c34098f036c5047fa69d3dd1b878c53dfe695b5f8864d32d390a5d7ac2f38cb4d087e5984056ea6afcfa9ee0234576a10a784af94d92fdc6f56543da896a18e9d798f36a8506ea22f48f3eb5c22052a76de41527395f18b92e0b41ce1e4f41026061715a73fd0ec0eed3ffc31e1fc66525340bae443a40628a57f349ed51beda8ae2359c5f76249fe3f9f8429858fa18208315a9a298333d2380014232466f68e3d545191ccb7ab62e2a2984d5bc7ea28cf47c366a6218b6e0a8f67ec25ed86fb8b580b2cc49d5d9fa7647a0ad14fdb25e430260a5c28218c6e48745e3c70a16aacb1e4f074503a254cceb27b9cc0fe3cc191a1c72d1771522c51ec0a18d9cd7b6d9991028474346be9c31ccc2cf988bd23c0ee7c4cc1f4f6ab499061df36abf8824cd42b292014f9be97db9a9331eeef10ee40cc8561cfcbe8e4d364cf0cd954ff8d7ef613bb4be68fc195bc2ef2477dc962cc25551bb74b22d0477100727b0964eb70bbc1ac0baae647db86ddc9b4ab7cc4d0e12f150e764f73ab808b767bf438e3a5d42f9fa298dc7abaa9639303301689d189b64235f0eb415965d1ab3d466d6c6d1b07d4baf6075793f83dc77e41e28cfb80885827f8a506d32265c5918d036c3b23798a08f4b8268671e8435a73d7d9b09eaf040dba1459bb5d3375286baa334784e1864f848bcaeaca8607d2d18571c48938125c65eb8dfec2fd33904df9d443641eea5c250f71caddca2882c2824851a965b2751e525cef9efdddc11c54158d7dcf74f83f29fd681d17852d9d57f3948befa84fbec052cfb8109234973ca65d8d9e6bcef4f9854e5803b3aba0f2e8abad37568cc5464bde14ca3c5e76839ae278c151449cf0bb104080756b907292fe9ca1f72a631ad64e02e3066e31aa73d1b795b1c0ac4939a7314e94416dad496d5fb159fe49f9a1e5eb428c573b8aa35b47385f21441503d741872fd1730b2cbe066093f3d511c0dbe264f381361cb6f93e62da6e55c6445320de65a10040c8cfba98f908752c813f049a27450466a0517d21ce714b064cff6992cb05c330ad441f9b7862a904439ac5ecbc22b8e72375c6fe8d7c955391cdb338bff23904a681f7176fc53f05aaa07bf301b23ee5bbae34a9354369c25aafb7a39a7767509f09f5a364eb3ef5918d91ec179b9b594392f67a8fa435de527bc133ad6b489b2cc523252e7101ef287191f1f1b9854e4d2b16034c533418f616e6c3a96d426c1e246a90e70b8edb2bcd8e6e21fba0dbf250ba4d465dc788d6b750c00cbfba7e2477bf29fc19015786a729b9e3058c35d4a87b0236f7c74341f05766b4a6c51b7f990ce6736332bb7fa53b9e2882e5ee4ed3cdd0379cc9711b47fb751849d1f75f8bc1b060da4c1fadce78177c2f5c4daa6ff1c6d23eb9d9aa9b6e71369f96e243fb31702478756c77a7bebb81d6d48d478dcc6f9b44f43f9b8f29626f7d994b2fbfdb7c55d4f231dda56dcb0a04bfae52a949e6222815543d7c8a555e8241b5bb7173f9dadb2bf16c6d359273bda357b1ad603dc39140a0c02de290e0ab967f7d379854037bb712fee010c1b6e6b09d8e791fa9f9cb3bc5e60486070ab8986d4b3c480dde0e139601c63c3db6e80381975661f74cf32d8af7b38a2c15aa16710675ffa66547743fedadcdad5306fd14dd7813f249c0ecd44af802d327629e3f81be6b1e6010e004cf56a4faf4880a5e88267aa3a6143b4023ba0ed8f2d6bae6b3be370c09e5b89816926aa207db24e6c87cc073a506722c5a2d12d164a4fc0b025df68d9a52341d4142cf498c1505cbd386eea446a0dc7d8882e70b3adaac404fb45050d1eafc23d4576b21188fec0d7a55ccfc5c0b11104abb3bef167a6e10db4168d7bcd61d62c2df5106c33f57ce2cd51f9c26a0010e084986ec05be05b01c67d8e24fa75201be42b8ad29d07e5531891819b74cb2e78aa619632a0569c3b08210530dca661705a0b594a0f7b21cf172b7ae737aa68d87521b74265216d15274714d8592723b617e08ac5b7080ff010818583fa4619a6327d301130e484633028ec95fdb9c1e4906da575af185d373bdb36a85b4544b350418102531123f04398b8476dea4aa34d8c916dc5766f20dc60760d6fa2cd0aa41b9241ce69291ae44cb7ff4c2570c5b68a30001c1dd0fa442f211b1033453a6a1d3dde5b2298cc981ef9156de0659c54ab5fe378236de6c201e347b168210166de6508e669563220711a4702d104c0553efbb62bed3c724155ee6b7833365d579124d058ef11269c5f0f9eeee6ee19ed91bd1bd456d8ee55ef52f6673fc3bdc53f5d15d61e617c144c35d3752333791a4327592d30f0bb0da70f402e6e2790a3fbf842fdaf8da4b15611049a6b1f4a10f5446041f13edc03c0ffdb413a5ffde64d99e149fd68d044bc15b2c549f6ca4ebb5a80e1a4f9123eee4d989aaf079c113557af7f72a2af066bb5f58bb64e75792814005e2040221f6560e26ba7f67e8f86d98916a0442bc6a16464423454616b05976c11325b58510740ab5b4e222030173489cd49ebc29db438166d9a4dc29c8dd41a9c909833e22a67e56fdd3ea909ec3134f92edd68f6fa546e32e9803d93be02884671a1bea34854efde78ec6ecbc2487b5e2e6e48ab7731f0463cebb7bb9f6705b7651e911ab10027e22a19c9dfa324bf79f58f9550a965bda60f8fa030a6b25d7066f22df78ab82c01273d5ef08059ac93da83b522fc007601385e234f9207022f1bf4d96ca922b3d0fbf056b0aa5917e05a89962c79944fa505135c0339cb9c0a628096b65abb3fe79304a144fb142a8e0eddbbd63220c0f5420e1245927826e4124f7c2df0c75c9d6bc512680fb4bb91bdb0ef343ca5ff242152ab8f9c9d92af3b9913036e290d36d60ed53254d15ab979b5a2069914a0bc11fae5477c133419a3f144dd01704a3e7394026ec52d8f0dac21633949149988a4313cf04aa59ab45a70e03cbd269034fa25297cd3f4cf0185e94cf02cf8def2d91642c560bb061377f9ac56471eb2e908e0717acf103b1987701ba470dcba4c3147be0a26cc1915c99eefc75186ff1252abec10e15a52c67179ec0a4ba586ea31b0642303260191e6e2d1d19deda9d37e4cacde5ca9526068caaf02b6233613aa1d21b1473d9ce2e5d95ce5fae69681356248550d7eb45ce136b8028cbe1df541cad7953c25b197ed3adf32d3f9dd3442552f7767fc5c25f445c1a7ea7461007a2e3c30d76123307ac379982cd193ec6cb1d2a109ec509f0588a1b70a4fb0def95285a750f55987fd7460a90a46fc30c4dce33ff4b000f0e63bb1298c4681830dcdaf23c8a67db30e028f07db816a5ea9606b94f235838a5aed97c9fd322b9d37e887aa7596c4d79b6c5ef6715f28c44bbc4abfa191fed1d3e4527f0e0ca7865daba8858234f57140e3cb1e754f5c78370c587dff4c6e5d8f2418142ab553573f18979b05f95c489377cfa275a50118d20c6a33bcb519bb26b5e2c495b9a3a6749b6b4f921db042f860729ba77af44107b6a1d676c4a7c99b86565d489f1b302186761f4bbb386773373ad5839b53dc23655a6bb4d20cdce7d4dd7c0ab8e90211b3cc0cf6a2308ebfc83fc0c1e834d6dde20581862b576c5179b4ecb5f6a04a3f784bb73543a44b59408ebdc6a1ac8031710cf5c31171493c14ac4c3f9abb283cadb04a5adafc9bedd363e5fbeba67692caa69abe260c0d791cfa6d37e1055381dec62006db84d9f47421ef5e7268e5f2a85b3cded468531775db7d6c33763add8c7f2b89682527c30070e44b4d54102b476757c037d26d21613222918291bd762089bfe886d8172676723bd8c176f67a69663d59d06d2ca0babc54bcabf570a740b848f8987c959eed4a236bbc73ab7ca7138cd3962e80565749aff806cebe8bb2168c44b8d2d3c1c2c7fe26078956a5e887925ec48289f394a19ad789321abd6205972db2e6144671c9ad757a31db7fd97091db7e875762db7c01b601e4862242eea8ba4d980107701b795616499789361055ea7da88d4b1ff4c0455740b9cb2290e2d6c69268f7596bd5889b86f0b92823b0e43c4955236ef6f26c6dcd4adb9917de652216aa62b551a55af86dab96f4263fed1278db316990c2ffc914b2fe6f424254cfde29d37699582021d6708ff2ab76f21ed6a39b13054b6b3fa60e9ed2b681b050dd4b0af3efaa0ec45a912e549b4b682d289b1df507464d66ff2ba8f2e45e9d3bb6ec63c10fbd82dd9a6e49c945233587e82da87eaaee4490390263344fa1660982dc1959f12574ffde37845983cca07922fc0f75319ab217e664ebdc79b194e02ac958ab816519587e1acca4fecb0bd963aba110cc0a754e3b1413448113ce9cc9dec2b2c9880ab7fb3fc4098a8d445926786c6669651713894f8ba69b0698d636d372b785030a76773c2ba0a11dadacb9cc33f18f76e9134898c88705e007f12d45c3f696de4481a13c4486fcd568b47437371ceaeb5c3bbb211b4f9aaef4c1e3a0f96683ef45aec90f51bf23e2dc2dfb9ed2d2cb7fb80c7520b9dca4032174de30e58bc7f9d9eaf40e869664e87d170c6953c16d12b4758d79324d47c9c34f97aad2aae7eb61c798f9af34c2b96625e0536c5b0931fdceedec387b929fb164a0d5715f16f3d2de3bdd5f7d282223f65dc46e093632d9e08cedb10ed5d3554c263aecdea0540a43a5d83c29314bad4497d3e7f1c1edde729ec51d853d29c15977801fd36064ec15ac8fbbd59c7114f4dde54835c9ecedef3255a250cbbbbcc45151c92a692a04141c321052343bd200faea101ee8c72d9e605146904c45061c7a3acf1d34627048a871c6deba7dd1a8e9801162eb2b0540608481cb0e7bee262d2b89f93e462ce078802405eb63f2695d4edc9d3cd5c02a22b6c7bd95d37407b29e2a113da40679f1304aaa5ca92aec08acdc985f77f232a0b0f9de32c0fed3bb13b859e65913248b6bc2b71c186f5ac48375fd05bf7f45ceece8ca65b4ce327e75264d1d12486b1b6e709726058d8a0068a1107ac1e01a1b6cba60b1ca0054543059e9b5da1ba58686329ec3245355cf99e2d04e27d07f2446e8fab54a0ee41cd453004aae1b66c5d69e7a2a8a9f87dd546f7321d027a2c7aa358d0405fec0eb110622567ce455278607f05c1b032c04f3f1220deb220e2fd5f5552769bcde517a988ce1354fc0425935c8d220ea3c853bef1109994bebc66f2c26c29614bd832f0d890382d35814224e0c173d2e83b37cc3d8c8779e6a272c324ff5297d09e2f234b3f3c256219690a43d4c2d585a94460249e5c0c09d9448e457cdd9921bcef82f63ff8c0c8ca4b410345011c01f28db20a6d39865840299fa90757222b5f0da0331ec443241d43b115a342ef2a6c5c3395ee0b243d2bb52c3b9a82fda19439d382d48894b31eb3a24fa1cd85f42983a9c3dc992a52230a8d91e0e4badd33f5fe7471d01ba4b7ae89b7ee66e220b4288403e51640a34a984a3367834bb2ac8db6bce2341b144808087bf0cc3de51b9b0abb71f75d34f1b124c4a6b5b1c95897b20d828842804c2141cda623d4a2ca134e219d7dfd0f2754e25900a3dd8a30f1fdc87e27f58958cd7af7d8446a7fb3d96ade5e1bcb3f015de47e3d24db8508579347befe9324125afada274e2981d0358d5248a18122e124b615985a6c0eaeb99689270c2626c2868649c5ba7f6f17a0c7438e648f89d0cc57e7463b43a9262f489b0e650b9fa04306300b20632a90e1b6f4e3d69b3a4417cead386a6ad8bac776f04447afe5c4d6868fdaa95000ad5e1ba60af4460e710147baf586fb7a8816adfc98bd6d43932cd16b56e1d04d9d5d8bb032f57e89cca12d3cbf259ce0a8b4e00f8341494a94aeae4915a8f8bf7a202a3ca1291fc211451a6326810a12e25b1e4f9b2b41b44eac41bb016ac6c0d8c19cb8558052632c3892187a008f60b18d9471c356e8082187c6c16af703249cb6ada558ae264398b686694036bfd2e64d93506574dfac010bda8652fa7792b4a1032fa3b77e7db3e9a9a9d665b50ec1491e483b6b93959870cfb8b9a3e2c5d724ab616f69b970a425ac3aba6fe3677558506eae0262bc934d8a1ebde696c56230e5b55ba283e9c44c117a9e745f38e26cf98c39a435e1254db2813ed291394a19e866139934a3623652fc44808d60891689b3d2a35be87ad5ebd891bdf0c03d1bdf495c5604e5461b57736aa4b802a43d9b406ca00adcd9f337f13b8c64a7e58700aece3d08afe38918b9e9bacbcc02e67a94d16abba965ec0c53090747b6e93864c03897375fbb6ed9cce93bf84511dbab07a8cbd75abfdcadd7b0e099b19bf371dfd0a", + "0x3a636f6465": "0x52bc537646db8e0528b52ffd0058f4e905beef87021a5410300c4d3af80cb5f7d3877f3b7940cf0d2f1287c7b999c7b71af4e246461b7d5599548d4040702298488e5fd3e3493c7f067db80064bfc2f3f4c3243f4d7288212f8d10013a79838636217bef4df6965bca2453dc1e7417711899fe1cab8054a7d56f2233fd397ad0997e8f40da69a598e72f7918f6d8e1522b77efddf2cbded35bd26fa779bf44bd5bd65cd6c7a2d97e8f40ba5ff230ec5188c565cdf6bff76ef9d97b7acbb22ce9b7d34a12b2f7edb4124af6be9d569e90bd6fa779bf44eded4c6fe7ef56dd327def9642b97e38457b3bd3dbb9472235d35ff225ef6e15cdf4eb6da7cdef1108c5d569f3977cc9977cc9977cc9bbc8311599fb869637690c61d89d83002e6d9cd6b99dd6df2390eab4fe256fa1b01d09113507460b104916244420a101490d48b8209900121b90e880e406245a90f480c40b922090fc800408105070240d109c40f2054917244220e1010916242e801007841420d90282991b085120c901090e204071048a2320386206840f1c89e28814487c3842c491228ee860240447b41ce172a487233c1829e2481723143832c4111f8e803182869123a4663802c3911d8efc70248623588ec870648622671851c1481c292b8cac60a48a112a4658905263648ad416524448a529720223664871c0081c29278c0851440d290d4859400a8b5405a4c248252125462a06a90d482921b584d418a926a46c9022436a0c292c8ec091d2e2480a52203892938ae2880a5254489d40aacc9115a43e70040529111c6141aa0aa92e8e48919a420a055221904a819414525c48ad2105c5112a524f48c5914223e5c5912d290f1c992265e64815a933526ba4c8485d2155841120a46e9042422a8b23491c41e2c81147c41ca9c09130488a301284940e525aa47290da62e48d940b45e018a941aa062930475e3872c5c809a4ba8ca0400a03463660640d2324305202292b473060440d236918a98054068c98a0081a52341cc1c1c80c46ce30f2c508155270a4c090ba8014135223286202235b462c602409234a184102490b485e383201235348652992c6911c8c0c11c508d7910b48c9307f288282226b489d51e4cb91101cd9728402478038c244111ea4de18d18011334526204502a91248a9216586541a524748e1f0810e1fd8f0010d1f54f94085a8353e48e183dc0728449d20ea4d541a5170a2d0887213654614185161448d208a8b282ca2ba885213b54554165157444911a545549a2834515d511888ba401413514b44291195449498280b44d51085258a88282e513244fd10e543140d5140441511d525ca4bd40b513344658972216a02514344e110f5250a09a733a25a8812224a0bd418506ea0c8802a03ea0ba82ba0ac80d2022a0d14135016804a024a0c14125015803a022a0c94115059a06a80a2016a06282c503240c5000503d415a817a05c806a014a08a820a08080f202d505ea07281fa0b840f500c503d404a0b640ed00a503540e505d504d4071417d815a024a09a815a03a0045064a0b140e503740d90055041411501c80da009406a0c6406500ca0928159ed6784ac193194f267842c1d3194f27787af3548227123c3df124c6939aa72a9eb678cae229044f523c41f1a4c513164f1c7822f3d4c49399a7289eba78e2e2298927249ec43c31f174c313d7130e4f3c3cf5f03481a7219ebe3c51f1b4839318a7319cc87012c3a98d53184e669cc0700a81d31927103861e1248513154e1f70f2805307260c53874901a70d3871c0c909a70c387571b28013979317a7179cae0c59630809869031048b21590cd162089a21658688604815439c1892012734864c60c896215886c430e48521568654698a3324370485a6143c4df174a6898ca6334d633491a0a98aa61134b1699aa2098ca6364d5a3471d1f44553089aa4685ad394a6494dd3154d5e3465d184a6698b261134b969b2a2a98c26319aba68a2a2c98c262c9ac26802a22988a61c9a5a68a2a1c985262c4d579a5e68aaa1c98a076c3c58c2831378d001214608a9801022848c1102468818214208e9125284102784700959420810429810f24548134228200403427e109284902084202164082117101246480684f8204409215d841c21c48b100b08d180101784c8e084849017829820081a41e0043923c89b20630421030241c4081246103082b0b161b1d560a3c196c53603931a52463091c154c6056608e00b06390c5840d2e2821200b9b9200c0ca65c80820bd0b8200da22f17c4c1a00a065b179c806905a52d18a4104ba3a703240f179cf193010cac3049a0870348634085d141194c3108bdd001063a70a2032590c4000283080c5019486000b121a2c00660845810da62c241088b504ea8850da8cce26c40c40d1a6626b0c1b9a105e90c1b163e636ee8c081161c6c4144848e25846418b2011e208886c845642384a4200485250c2c31b1a4c492180eb878ca00076a8c7010e6f6e054c606650c49d9c00c0e88b8376cc0c4061dd8c08d13955a151b7031dd406484100c348d0d80604a934403d21add0e1a64a181161e7ce183020dccfc502133b0f3c40e14482910aaa201056a53ccb40c9161480590a810009700841000172aa02a04e0c2cf163dd8e44022471039c4905f7ce0e44862e70c8e24845c18c2854482191a4a3efc30c123c48c4b69859e3637b06850463e02680dd30c3c9a506241001498a500488d4f0680bec8c106488c190a36a8005018b333c822482e9b0988b8fcac305b4303373c52927c087202a1187accf87182a807a1157430415404d0183960c8617058408705341862a7072137ecf080b4c50e1721597626b0e383101b84a610b5c100060c5ac0400218ac80810a1850c1400a06285c90820bd6b8408d0be05c60820bde5c30c6052478aa72011917b421dae1022fe6179e106c7001210de468c3630608173b34b083cc8f313f36b02303433f0cf9b063033bc6ece8dac10123617a6c71e4cb094257788ab8008ca72598ac0849d1c088212798a5c16466489a214f0c89228718b510ccd4d09104d311b313085901b226a9890d309004469213443c200581248491979a144340f80a1e64e18116d7870a66b83fdc2d1707a41e765ce0da9053c35006728c91038d1c6018e99023430e161e321b70d9a0871d47f440f333a60336af868703394690034e8d0a272943d8f0049123034376c841258714a434922490e34b0e2190da2095c103821c5bb13631326261c4c440aac2070d1c4ae0c881848194e10615ff222a8e8be1a30157b3a3650706ae0e1f48b901450f181d0ae80ca10346e78b0ed70d2e9d1c6e7cb921036de1d290230c1e28789ea056762cd1c1183b94d860090e86e040881c1a84c6f044c1c117a10c70d0c5e98a11dac0d5722770bf5c36170c0ebc383dc101180e7eb86a88a8b85b105971bb204273b92012c1f582688abbe66a41740551151708273417090e82e000080eb86e059eaeb849dc301c50e01ee10485900a40d834d9d0340354099a70982e409db1c1970b6eb88086f7c2084c53960d50403483ed061b0e4e55107911c5e55426071943343063e2c90dd1046e0e97cb065d426478a4b83cdc2c4363807421d401a127862630b4656887211e867418e232d483d00784a0b83b087140a80c101a3b62e021622704443f0c9901c8044a2a10e9909150da220a62c818242b74e440e44307636edcd0c1123e39a411107921128264a2078c1e374c3d901460c2c2544647134c5c76ca107131e930a40d93160eb0600a418f05989000228369cb05653055210407a6304c572071c154012157986a601202a90b26313d2660ea62c2401215a6313b6498984082c394c34e0798ba208980c906a62590d2308161dac00d1c98a440f24287991997190fb32d331d82d60471c1d401261f80daf494c18426c90aa01130ed902402a02d80ac904121cbfdc4013a23c3800749e4d8908343ce0d395a3cb0802c043e5bb2257ca09011d1b3852c099f2e3f61f46021bbc1470559971e2b645d3e1390a1d02385ac081f2f3f6d7cccc85af0a942a6824f086432f81821fbc1a7cd0f097c58f859c3c70619191f0fc834e0634516838f143f27f0b1806c8b0f1719959f1b7ecef0e941c6811e2d6446f8842113e3834566c5a7851f337c6a9039e153c40f193f36c880f0b9806c033e42c858e8e942c6840f18590d3e67644df80cf13386cf0b3f6c7aa6f8f1c2e707190c3d6b642ff874c93ee0f34556c68703320ff8c420cbe2c384ac071f2ab2ad1e2e7ec4f03942e6c24f0d32217caac824e073e5c78dcf086438f8949175c0e70b19057cc09079e9b94236011f0afc80e1030219169f0ac852f009239be22386ac8a8f0464637c7490cdd0a3468684cf123f26e8492353c207899f14f8d020cbc107881f357cd8c82ce0d301190f3e3efc7ce1a3e5270d9f0fc8b4f49cf941a3270b59057c64f881e3b3453684cf0ab2237ca29081f181e167043e63c8b87c9e90d1e093c4cf1b1f1e6441f8b8f083021f256419f8c922fbe24384cc071f1c6436f4a0915df1d9e1a70c9f29642bf8dc200be393e5a7043e33c8b8f8e42093e28301d90e3e64643af850f1b3c6478cec02b22780d2005d019405101632105c216e105163c8a4780281141a469e907a414a0246402035841129a4603072c6881146a0f8c962881717d8f0e381282b724c893ae247ca4f0a3f28fce47ce2f8a4400815d76267033e5c43aef49cd123468e147ac2182201a3208c86e81181d11723341889c2c816479630124208961b597ac4f420b183099e293a2083a70a1e2a7abe3cc1e139f344c6066a209d8009881d0ee800c1c365c70b4f186002811117d30f4c4dec90b1d38674a176a95e84a880648690ad1a0884d4c014844e1033384f609250d02943670c1d0d448189ea014a8c9c38395b72509033819c1972aab85fe40c01c40ba92b395c522dc4a600a226e70a236d72c07c30c3d318461400b2c590970fa8d4ce001901921a2e820e68b8200b1906c81717d4101b432805a119c82c640d3533640c445af8190104419403121aa22d3762b86183530b73889c188068416403531243a0b069f1034cce0b4c17e879c3e42566c68d2090beb065c1a482072388a131840231384d5a86c01073d341134c2ef0a4102be3c98ba6294c30109519c244531a437288da01c90443b2e4886188195125d0c08c0d841802c4d30f485734498029cb4f144f2af4b04152c3d303141743a8f48c207682a81c784c80c788271f86b090a3081fa323448f17405c08a912448d1e0f084940833186681962c68646930e3f668674c1f4e5894ad2147762c8123766806a63bb22c905f202b11230f100e4c5101d925a8891a0a94ad41a261a868c8184051397901d84ccc0e4449417e40e3b39100141d48507051d5d8e262a033113245511a282f48627c77486a985242b3d2948522107101a9091b4958405898c242d4d37f8ac31a485a41b76ba24a5d0242547981c46e4a840130a34e04208057a0654163a74f00c20adb1a5e941a3830d30158194c5930490dc749081a715989e807aa30109a228d0f385075b0c7121c71149599c4ec0044507669272c0e005243482a4310487a41938c8c20335495784d000d405062e0c59e3411c1d5ae8c842871a1d585ce0e6860f740ca7349844107b938388a69c93113c96b09dd14425a646d20b49316050c48d1a62675c2046558162a12ed017e815aa434581ce50733406ba434d81c240b7c8ced4192a962ac30d21a28248927283872416a0d4dcf8016a8b1b3ddc00e2c6961b13e0b1c2b495944342c15317cf0f486c926a400aa3c680540227227ac8e45cc971c1a6c6b6c50d2f37ba78c0856d4d920c493830b1c0f401a6179e28f05444120c4f44f07879fac053194c5124d990b482d3114f6372a87063872811447d7123072717a274b8c145c70b139927359ed2b091c3d31aa4384c5344a9e194844e971b436ce0c30e123b66e051030f1b7864f9a1e107d78f217e5060a78b1d2f76d6f4b8a2479a1d3eece8b2e307b20cd20cd24d8e04725ac8b1b2810d1be0b0c10d3f6af881430e3439acc821020d84d0804b832f3fc4f8e1e6b9fc0fefc3062b6c20810d58e01982070c0f1d786ce1b1c38f2c3f6ef861c353f168be8a9f323f50fc3c81030d0e2b70886047103bbeec1082c7023c4bf02881a3061c36e0c8f26c3e8c07c307133e30e0e30236a2b001021b667a98e8c140cf05707cc141011c5c194e5623a3914f90d3c0a0070c7cc0800b8f303c2ac0e3081b706ca861238d222f45411401a1810634e080061bd859a289871d267e34f123033f9c50ca416907251d7e8597c0b3603bc28684ad024a46281da11466480f3b67eca0b163021f60f810c347181a5ca101161aa4c1b1058e2e707081a303383e80c303368468fa62e34b075d3a00a2032f1d8ca0832b3ab0e247183fcaf8d1e607193fc6e860ab03163a5841c711432ea0a30249522485402905a5294a52ee0a570297851e59fc74e55863a3c256856d0a1b49d850c286057652a043029d12e0a8c09033701c5144435196a21a9c2ac03401262b98ae306980490926199828c0440513114c16601a8229034c58307980c908260e3c5d000a8b27189ad678daf2e484a3c047e05d38167e8567116584a771309cc278144e859b71103815e14f384d7122e317702bbccb9bf8608aabe0557c6bbe711422e053260a669cb986e7660a261ab3049ec23c63aa314f30d398269842389933cc29e60e938a999b58e698a981b981d9354330939817981898344c1ee6959965d630659852cc32f303b809a604ab26501a3082082130406a8992240b48c0019080706466e0c9b634a42948063263e0c1a4818f1e938bfc219cb9e703f1723a75b5840149a02c99222149927052119c4c2549022625d1722234616202036646717a0a6bc9945508428a8c5220c29310a644b0618482be7ac014d5d503a69c0c708dd668ab29ac2b26234c59259962c00396947082202335fa6a4a84274e4e60524292ac292b283f4669f49509584bb0aeaea6aea69c9cc0044a6604a7afaea69a0c19a1d13b4626e8331ab064aa498fd19bb62aa18412a0624625c06144829a91198d3575e5a6af985c3da00153530c68c0d494cdc7a80c212332a6b0ae1e703546094fb0ae4c68d35358263080891516d6921c2331a69a34791282cc288c6e0001462330948cd83469b22484264d96743082be9acab29aba9ab24a823535820da32fda8bb67ad28024574ea6a89e6025c10a61c9095349a64260620525c914d613274f3aa819ad21016b0427534dbae8a9a90624798295048b8411984c39e0c8888bbe6ac26409d6940849a6a61a6064b4453f69801326491e6035654255122650329693a9121eb024ea8dd4f4d4085af494084f424822c292274da09890454f612d6182e56409d695132632232cba4993252184b0c40acbc9930e728cd2f4d515d6d4d5550e32baa2a74270f2c4499225213879428010f29091154ca0e4075c31617a40be46220880119a22a32afa8429273a4654f4144d42084fa04ccd8cceb4950923306980932721246102254f316089adc728048de5c484272124991a61099424575653544bb0ae925c2db19ac24652f412ac27265425b972928409943c821326544bb00c206404827e8295c44c4f85e0644993250c48f2042bc9159613264f8a8ca2e82b11ac963860ca2ac9084e9888e0640a4a122650f25593274fa29c3029e10901b011140d8509095756534e1cf024c903a6a88c8c9e6811a69c8cc0e4ca8909584b427892c5c484aaa92458564fa04c59f5302ad32230498235756565420840461fe8ab2926584cac9e908065c2922423246102252f81228293255642888c3cd00e6002255b4d51593d3942e41a75a00d20556444a6a7a64c9832e18322224c8d30c29222161871a0afa842982221840df415969329ab29129c3079230d3861d28099d1980e81c99513265658274c2579401328509624b19a12a10913136c54213c69621332ca405f051939d14b92081935d125245982b544842558535039465d1060d26409132c264e98f41861a0a94278d2840149a6b04c0861ea84291da30bb4d5930ec49e534d18b004cb89090d488215c2941513119c30499204c8031d33bcae2bba88c9ad1576572e97a71605b26417b2cb8432bd2a34341312229a753321a24e88244592ec194799ac671c67e3d2d2d06c68886826349b117544d6daa6149cd65a4bbfb6d6ebda75b603bbed8c815d8e570ce8158bc562d52dd84020d8fd81df676de71ff8596bedbde36cdb54a7d25ab18f3b9011add5edd75dfdb3eeb65a6aed4749a71e250682b6a9d7afada59456ec76faf87413b49df5cfc7a7da39bfeebaee4647a9b56d5fdf4b00d6be6c37ad9d9ded3a6b6747e7e79f9d5dd7f9581fdb75734edb59d04e3badb5b37ad74a2d3867db6eda55dad66777dbaeadaddeb6bbc3ef7bfd7c1f6d4b3af50a7e5e2b58ab06d5db67e398fd51a01abe7bd4bd57add6fbbc92d529bd21d93ad411e8a1deb19d6d5b9d4eb76137a7b536ecacedeeac7f6d29ec735badd5f9aca53bbc3ab5ddb6765e2bb5edd46db7a5d59d524adda9b594765b4a7b6cdb766aadb594fa4f7fd6d6b6d49d7e5f75daf6d56e1b020fa8b55677ff28eddcbdfa095d9d75d2cf0175ce59bdceecccb6b53ddd61ed3dddbbadb54d41af1ed4594e4dc0baeadab579e88e0daf3672603098d5e4c9b11366a3bb3f4abf2f2787030e68b45a8360412f4ac1a0201d3abac85f4141eea1c37a76bb37ddcee9cdd03b0c3bec0e1b47d8dd1d76bbc3a6bb7fdeed74cef9757b87cdc3636367a78816d1a2a200c0603930182dcad9e931001b7600393b393b7a7a603d33b6e3a5d44a4de7dc60ce0d6aa5f47b7dd3bb5f95c76bb5b6baadb576add56b5ba72f9a9d3939dff7edecec74b4ca7693fe50f7ef03419fb3ead40ae5899312bc7aed9c39c31ad2d7f7a2b356779d8f7eb4564a7dd420774a015041132afaaab4a494c98b7eeedf0dfa53756a53a74e93ba52db1dd5ea3ea7d7170995eeb8fba4b58215f45a7dc8bd52dac19cc268b5d64ab6db5a6975fbe347f5eef1dadd64ad95d25a29a5d569ad74844a69252b59c91e9fd5a73b0fffbc01d3bb9a0324c129074110b4d682d66141d577babbaed66ac13727add5bb5a58d7d7d1740f6bfdbe76afb6daafceb65d6bf774f7cf1dac3cced3d6456f5815c176f7ec10aa3b0c66ab57fa39037a090c96a3545dc9ac14569de6395e679d496addddaf6eeab1179e7501b59ba7bac3aadb5a3baf7e747a6edbbd5a2ba5b6d6aed57aa5f6f57abd5eb1e93ee7f7f297c762fe7ab9bf1cb41d383b5b6ded5a6d7bed9ebbcfb62f6f874d1b4ebbd2a60af04aa90e1f5f10ed9eddfef2def176ffba6df5eeb676daae7e7302a01a191919d5ce76d63bb74d29ad3401df473f0b3e2a80ef45bf9c1edf475fb66953ef1e770c003a79c410406b8d595b3beade55fa51ead63fafd66ba5d646eddaf5a3947aa5dfecaac37cce0354efdee9ea48fcebbcabb556aff6f3cf29fdbecf5afb555a6ba59552fa514abd27a882d0ddd63ab5dfcb8f7c3fdf0fa594ba03e9fc586fdb4d18acbbd657ada03aad5ebdbe6a4deae9ead378d6e95d7767bbeeae9b9db7bb4fea6ebd565b2b9d75c260eed37d5277eff65aab75b7b6bbed7c79fed9ee9e73ba775bf7b66dddbfe973ceeeee9edeeddddef36bf73a678dbdbadbbe62edb34e6addddce7e35d5d1a1fef2fad1afd64a3f4b69db5aa9b5356abfb6d6b63b7de9b8c36036697a0068051564f0caa076d74642fa26adfe49bd5e377ebca98ece0dff3172e3c64ba70ed5eef66f4eeb0e6b6b4183b4d26aadb757eff69d39bfaf52fa35ed3afa7d9876dd1da5b5564abbdaeee96da9adb488016cd73a6b75ebeed6daf6eeea5ead7bf7ec6e9fedd6d297cfcea75b771ef7ae5ea9d759ab3bedd9d3b67bbbdbae6bdbd6d6eaee94d2eeeef6ae757a75ef59809a53dddd6b7b77bb7ba5b5db5aeb6eddbdba7badd5ab579dafd6eaddd3daaeab5dcc765fedb6b6adb5b5f6071fc500039d99c3467dd4daefabfd59b79db54408603b9b2306f5e494a3b35d0c8876b60eb14d94526abdadb5d6924edb7a95d217ad94b67dc19c56cfbdadedaa77dbce5aebd5dd76de8d84082446d09ff607583d2961aa042b9b723255c214d612ac2b0084bd632a6baa4992139694606384274d928ce084c908233c6902844193264ca8943c3012421b9146231e119a3021218424584d4c58d28029118e78de1d30e564ca0a473d614a04274c705c7023c8084caeeed103a6a89284c0a409034c8042b3bac221f60557575356504a78124212aba9ac27214c59eda0aa05e00228214c5df1b8e0860076042000178880c3076b89d59493a911922cb9122184a9244fb0a03cc02a841b401af0e4891594240f680013aba9ac0a984498b29a12c1ea49925a002e9862628555c12ca17bc79455034278d2a4c912211c504a58827535550213acbf0c30e1ea289c9aba4a52c213119c2cb1c23d57b40e6836119c2c493265b5044a094f32209b2c09e149930ac227584b4460d2644956922b26499c30594242080d68c0931b19d486884e78e2002ca225245c11512d09218429aa5a002e78d9053b925c3045b5a40903928ce0840909574b48f8a91298603931c10a7f8f066099305482094e84fe842912926039616205254908574c4ab05a827565c4730574d4173c7962154415c212063469f2c4aa82bc64ca2ae801535449b04e98724274b1a64600925d615d3139614ac8eb1d4e9e30c10a61c9959325565849b0989450c213dad8179cc0a401535650f05b2d996a12c22ccbc914e5e91d499c3c6172653595954404275350a02c493235c212ab27585749b04e9812ca7232457be86471ad899b4aa2cc28534b54d222c569e1604a5a4b4bebb3d66a85394a5a2b54d25a53eba6456f5a5589d6dc8985b84a9534ae6a511c0ea7e538ad8aa34a70530be72f9ce3b4b43c255a13a785036f5a382dda381c0e87c3e17038ad899b8dc3bd94344e4b8b2ac1e1a656a7e4366f37af4aa2cc28515c49e370389c969696d6c44d25ada5f529d19a382daaa4713857d29da7a4b570381c0ea7a55595e0260ee74a70ad446b5aad4e49b712ad4995b49696965655d25a5aae446b6a4d25ad3595e05e556677cf12ae967499feeccaf4edfd6e96e7faa1fb6ca4d7dbeeedadbae5fa5f39e7fd597e54ee7db8acf9fb79a9bf70f97dffa4b9bcd2cafdeee120fdb5622afa1453f53baebae592e67e1b27f4a7ef6d2687216bcec965f6a7df45e5d795ebd33bab90e50726d7ef9f479035975f2ed7a7e507e6ebcab4761dadb5565a3d00fd73f42e1ba664ff2c6b64ff2a667a27ad5de723905abbda35d5aeabd5695d144ecb092715d27377657193e7378c521ef56e555b7d7a8b90b64a29ae8ae52eb5e991bb8ba06d8ee8b4eab47e9e300b099e0ad93f3fec5bf398a5131bb3d83eba1b3612a9b95cee9ffd2d02b1fadebd18e5eadd49f6ebcfebbdbd6390f9fd60fbf0f07f33a7f9decff7f07c304f0c761215bbb0fde7ad4e73fb5e7792ed07472221063bc9672edb5b7ed9bf3bc91d856c942ba677666fba1366f27c9cbb194e1f9fc4f73b5fbc542ec47ffe7ce7427657163519fc34623298c50f432ace51c8f7afa70a1ffcd06f09de5953cde5f2f835d3dc631399cbe3fb9db93cfe92bb187627c5be7bbfb08fddd2eb18c41f86e9fb18c49ffc254ade99933fecfd61f8ce9cc0ec0f66c7419d443d92f2681b7d8f3d4c7c6f240266f183da07fd6e2432eb24fa220e82c1eecce51e85cc5c979c5f7292f2c8c1315c7ed93e953ff8a57f3f6961000441d0e71864be7b933f4805eb24fab14ea2b95cb5c89a43218f1fbec211c7be3be935c61e269634870f0b1fcb66d878ad6031f1973c263e2c1cc57f8522ee460af1eb977cc9fbfddbe7b7cdf130e9348b71ee300f6e6ac1dcd3124e2a64cddd95a503930ad9e5eeca322677120ecff33ccff3bcef22af8c70ba77f3735af7b3fbbe130ab27ed7fdd83e80f877dd8beda3fb2eead8ececece87cce931ffb9d9d9d9d9d3062b118ecc7173ffc582c168b69118621e87d18866178266cefc3eeeeee9eedde153bc9fb79e713a4f5de7bb17df87bdefbf53a10766f7129fad71ba4fcf205bffb72667f286006b113d06f89cbf5f52155133077d809e8f9f5e52b0b97dce5d7eb7b2462f30bb7d3ca2abe3a7f51f1d575d8cb2ffbf77e7deab01fd6f965fbd569d6fdbbab86354edd951d974bd93f7c89dde574df5db9bb6a5893bb9bc88eabd3acf56ed944cc5d07a4e26f5635c2ae23bdf685dd6daa1f765d776bf775aa603f9c0ee4f5f67d04b244ede5995d58b366aeddad1d48359f3efd25afb8c4caf5e7ed6e29e6eec335397c9a3d876fefccb3a686e24a0ebfcb35f7d8e4b1c921eea9a3f4ee43176df7614f6f0aeba9a3a3f5361173bd33274a956978336fe7d755ca0fde99e768bb3b5520e7f3380dbcdebfeef7f3da9f63d5f7e1c6157fa558d7089bbcaf1fd65b6ae5faf57af5bd25afdfeb97bcde99bfb7ff2ab5b2fd6ae8795f6fd6cc9ee77de8fe9d3442d5ef7ec9bf5befd7f2f5d3be5eef7dfdbeef3f5cbe7e7ecd55b7ec9dab7f15cd5e270e5d6377567f7e7dbfb3fafede87f57ab0e4fd0c5d9c63107fef6b93bfe77dd58c638525e62a0ef2ecb1094a9392fcfdd7efddf27baafade87df2d6bae4f5fd8aaaadde472194b277f4f2996983f2250c06b55c541f64eaa8f6533f8a5e7faaf6b053e96cddff7e89424bf7ec9bf5b65a38a833c3ba97e38c5d7ebebbf703752f53148f7f5e708c4e27abfef4eebb4ceaae24feb9b9e98b0bb1cf16937c7d905e931b630d664dfbe15bf131f14fff520785f97bc376be679b366b6f3da0fbd677b854dfc9dd4bfe4f652d97f915e0bbdd8cc618f40dae6904e035f298b3f4720f3963353d97f79f73b4929f78797745a7fd973b2ffc231f0bbaf2ffe1ce794ef412c735abf88dbfe7ce1522bbf5ebcf38ab704ff05e2b266f0c39f977a39b3f8e5102d0ce46e241197e0d3f056ddc0db9948cdb48ae68903499f14fd760eed2dbb9fffddd9c455337bd8821c4ef1bb49d9bb424eebb7b79cf36d0a613b8ff6a3c9e3f3a3f9a58cfcf6f19d34bf5fc86b3c7e34df9f0749387fde114875da7ca7d5cff63f1fdbe654a7e1128be6f9afe7f15ae8851e08e212fcd7839ee8350f7cfaa177670ec1dbe2cf514851ae4e7bbd773b8b178b66f0c3e93d29ac9dd6793ecd6b484279fec4a50de99cf6767edd8f833871e2e4ef627579f264b7b83c21dbef5b7eb9bfb639ed34efdf691eeedbe5cc55334e9c387172a995fbedc5a2b97f8a1d269df6b47a3b0b79ed337da4f64133fda20cce8e4b385120fb7978c2345c3208b60f1f60eea9a3fc72699b879d47f497d254a035584a13a675742e6d0ef3c4252e67791ec16ae6f92f1e900c45f11bb32aacecae2b7ac855b13c9f7eac7d340a327d3b35e84c4bcfa515bb7dccdc2c829c1fce719e21fd971c8a5c8f01525573b95653c57469ec9a9e1a4c366972bf4f1e6deb07a70635977b0cd269f2fcb0bdeffb3eebdf47674783cdf7a484ed944269993a74c821c4b226cf3c7fc97d56cd4c7fc610763fa59054dd1be5b2ebdc5d34a4c9de79aa7d5829e52efd5afdc5cfefc6164fa99264b3bfb5639b3cb97e10122ac8b249ee5e29973cb96c2f3e68db14fb735a715a7d0790e5b492eb97ed45ae7feb27e9d1195a90d80109306a72399bfdf9f6b66dde5c15c2851e52e08109db942a49b6f95b3bb62955dce6fdd6006cf3eddd1a80edc65564fe2d8a1ed59f666e5c45963c7ce32a627fe2db63a5cfe597cbeeea9a5fb69936810a1de8328615416c21c56bcd5086091d7468024d1125b0b5ad7f2cf2b99c6d5af19a5176af3b840f20e9510f0d65b250ee2e1a28909572d58a756d02eb3be93525c5b35b932bee6c7d0f3bb198aa0976f2f64b8acb5bae3fdf3ebdf57b24d2505cc91677f9befb1297cbee5235e935d9fbce49437125775f42205b0f3be935b9fbf2962d2ee753271b4ce9ca1dee1205a7a30a277454e1042e4fc8f4e7edaf07d05185135da2e07a8dedf55d45e3c4c95d72432df880658b158e2d4390c96141e935b94b4e47154ee4b23698d27542aea1b862eb2f2190bb147a8ded8573bdc6d65fde7287cba941b78eb2bbb07c91b166ee92f3c982082960e472b6c651701fcef5975eabb88492c722395b64f1430aa640ed648a1be75a9d5b21c22e2ae795a63c5e5f92b9ff41dbd90e2c629b1e755cf45fffb93ef8df1709fff5161701ffab21be85ff7d01daf6eabeb39dedc0db831ed50f2fade991f7afab448f6a0f3a3b40f8df1701ff05bec54542fb2106c1aac8f720be79809b1e755f80b64559b0d1e48ab9e8b7edf55fabc9f5af9b5c7f6e79adec362778ad9c5bd30a14ac359acc2b55abba978299af7e9ff75fd7b6afebbaeefb0ef0fa0fdfb8ba7f61193daa0568db5befdbf67db76d39dee5a2af94917a907952cae0079219ea1d0b611795ade6a33c5eb4ebba2eecd06f5cdde3c07fd18ed6ef7b03ccaffbb0bbf37bf45e97bc1f3d8aca16fc727d3a02f1d76d9b779bc24c3f9c6313999d042f177daf55ecb1ebdcbabb77b7d40abbd78dc2d53deefb97b594feebc3afebdebeed6c675ff7e9517df0cae85195e5fa16c89501c07fe128af07df48db5e98abfb02a8c0810dc4347a545f891ed5ff3a242220dbf6bd0a1cd85eff7aef75db9693a9ffe5a2b4bb727d10bc56fef0c06b65a349c0125397f9d16a72dfc051adea1f11f5bb7d4ceab52eac6513fadddbb08ab37d78ee0fc31ace9a4aad1db27def3d5c6a01912db6faecbd56eeb109cc1e764ac4fb0e97f63ddce5f57e4badecdd28a47397adb7bd30ee7baeeeed4884bec565541d81f82fd18e0bccf4c7a6971399292e7d0c32b37fe8ed93c24a23b93b69ca60a6d6aff56b8d014dae33d7faa18b738e377289cbb47e17554ca554db849486b9bb62b8426390e21605b48353bb1a762e9cb12418bdf04ea45e16f495bb0b8629e827526fa49f48e76c18c4649abb0b0629ba2f0c64727b1fac3b494a3726d6d30ab2bb5e38933b77f60fa9d8b9a190b95c0e05db746a34e8cf11887f8f4468d9dbc7ccfd57dc64a34ced6c1f1d91fa1497f44d90652c995555c7c9fe585eb61fd2d129d654fd762795f4bf0fad58db87775f85d0f768397349bfbe77674eddfb3ba6aadf7db6a39351ee7077127d7a3fa74d27b44c671d9d1a8d4cdfaf135aa6787692bf1d81d09f23115aa6b83bc9f1e7cd0a266c0f63f6bba8ecaeec34af75970b6b1a4c9e2311faf3e708a47fde59ff9c2890e5f7f05a29947bfc40721ed3d65d3070c9fe455ee3726699d3fcfdbd4b739a1739cdbbcb737b945d9992bbeb8537b9ec91fd8535b907e551e440ca99e9fb08a4c869fe4ef32af2b37fee2e9a44f824ece6416903a9df37abe6fe7a9bc8dc4f69537a3b7b00a65821f4b1bb977cba0b645c0686fae4ee72e186ea82954eac2390adcce3b4da5f472055334eaea390f9593aef8482ecae16d6c80e9651d6d0e664e189f3b660a66d57a9cff6601d96b08baa7fd3ffeec37a6ffdb20af9a4ece3522bd3c7d9e8080404ef2dbe69d96ef4dd46bd7bd3b2cdeadf9487fd128be68a3b5c9de6cf84ec22385b15ae2a0e72f7d3562fc5e5ccf5bb5bd25cdf5eef9768bd9dbdebb61e8b50dbec6c6fdbaaf3f86cfe2299fb06ceb5aa3b1324d4ef84bc864533fd7277b1686e9ab95c2e97e7d78b456b9e5feb9c5484fd947e38bbee29ed6e8bf45291def95a3ebdca0be47c1a50d853046477b5d095bbdc5d56d4e4d619332bfe7017d1134205904e8b85738aec718856ae556b4e26253a4832260c8d79fb3b7eaac655b8dc5ffacfc6edb426bbc29e1e20bbcbca98dc5d56b8e43296eb5b90bb4b0270720d678f4f5ab99d56d6ac95674847209d8f4f5a59b4dddf2a6466fb796d166466fb167f797e57dd875001936a7e49dfe7451266ce0e12f694986b0e63f61dd3af9df5f7da2c883f7d6abf7b2a6ab315f3922fb9d69c934cd8536418b3529fb426fe9c56bf7e184340152ed79e793e03c2761aa37e912c41565ae954d85eeb2e099cc9f4fbc5be617b08cbddc5021b2132b9bee5d16372395b7f2efcfe3056bd66bf5f4aee0fbb7dc03e0cb5c487ddee24119721902acf42425c7a0e7fbe784b5c1667869557b81c7e7df0bb7dbc1ed649305c864f7ffcd7ed4e1a71293eed3c6f9517274e9c14e4fae22db5b2fd1e83cc5c7fc9c3db19bc541567cd6cbfb44d9eedd3d1a9bee3522bfb770e7fde72e6f9740c621ff6e19d35e5d23efd390a11bf3b69fe125d72f156cd38f97bd89d8d42bc7fe172e6d783b79c19fcd0de7266fbe3d791487dfb3d02117fc9c39e4a90ddc5029a5cdf7ed8a18b3d0a193fc465cd21f5ac2fc31e86e7d854b3fd30ec11864bad0c7bf1667d59fcf0963387dfed43c4a5f84d7ce4eea4f0c35fa2e10d2ffd1e61b88a66fb40ec8fb7b45fdf8ec9a59043f0fbe72864c6c922ee4e2ac3f0bbefd183ce21ee467a3d056fe7d79ddf9db94eeadebba5ffb4b7b55ed34e099ff2a012fbfff69e8acfdb4ff2a702f4b007007d2a2bcc97bd8e6fca830a10bee93c0d7a2a363efcfe8ff2a0a244e5e781be5f467950f1c1379f8fc51e28e763f77dfee6836f39450ff4379f173ff65428be7ddf93f846be47ff46f1edc32bccbf7d4ff4393f7e3f49795001f10d7cf70f81f00dbf77e38ddebd07fa9b3f10be75dd93f8063ef937a00f9f4afd207ce3e1791d7ca3ffc2b7d7dff06ff7437ca3f46fe1cf7e87245fc4b7ae7b10df28be0d3df8247df26fe293f8d6edfcadfba3c7f137f271e01b0fcff7e05bcf7bde13e11b0fd1f7783d8fe36fdee3c037a21725fadbab08af40dbc1b79defe9f9d94e4f0ffe1b20f84443201882afdb03e4934349cf5fa00ffdc29e2e763bd13fa09c987fd72329097a3d6127fa00f97c3796d381af170d49af2747247d5e22508ee79f83b1dbf5d0ae07887e461590a1c76ef816e4e0008d8c768042fa3a3afa9bffd1d1cbc7073f8dfc9e265650c1dfc0afa082eb79b1c77f24827fd4d1687fbb4f33a27db11ef2f1570094f315bc057ff3790b8e8efe16fe118ea3b7e06fafcec828bc8f9fd6f53ccd8d8c8c2af89bf715e09b91510e7d0b70e018fa9bf843afc77f44f443377c2cf8a3bf01fd118d96e371e01bed6fe0f8a3bf817fe36f242efa9d1d077afc4643437f8388e8673f74e387fe96f343df1b3dd2df628f349584de82bfc5de8259f4372c78a4bff9fc8dbf7d7f441312c22f74f4427fbb2f34ff16bed0e398cdfe0611be0de1dbd0dff819d1cffe26fe6cfead7b1c4ffb1bf9b499c3e86fde1be15b0ea3c7f896e389889ef637faf86faf47c2b70a2af8227c9be1dbec77765e08df82827e866f42bfb3f3b3bff5fc0cdf82661ff437112ff5d1fca2b7e086a8f343f816846f413ff4a2f8f86fe0637cd3b9f1f86f2186d247f375de82bf81f8843e9a6f01be5580579847e1e3c037107c1e7ce3f910c7877f7b6110427c03c317c237f0c5d78b7fbb38aa8fe60bfdad077bd047f369f866d4f339f00de31b7e1cf78bf0edc63fc6b70e634a1a65e2e4508218b66c17042a6089428d326ea002021b95fb4b40f8eba3f917df1ebf0fee3e9a6f03373dea271a027a217c9bc93e08dfb49430420c33687e08020a256c405a38a460050c4e88200d343bd880fe9683657d341f08df64b8e9910e5cd272ff2d86c93e9aff833f7ad4eff3378a49e8a3f93ef8d6835798362a39cf836fb1dfc12b28d9a8d0d7c1b71cd8c7f04dcb872e28e8e2039c37639861a37d851b237a800107384ea461a3423ff63712f7e8a3f9317c83e1a64700c0658fdc7ff3b0521fcd1fb18c1ef5df1c2be9a3f922be8578059a8d8a7d10df7e20b1041943bc09811b216c2fbcc2dba8d868c2044760c08a2a6a8861a3e2effdedc3b43e9aefe19bc54d8f9270a994fb6f1dfe3e9a5f31498ffafbb528eec893e238a5944eff25a7ee3fdd9dbed339ffcb13cf9ce6d79f14c8c4e5cc4fa667ee0f63edb5f6afe11c81cc708a93d6a73f9f8e4026ee9983002e6f9c46c57967f6d1bfc78adb694b4e671961173514d94e9b3fc72027e4723914f2fcd045ffe60764c993e9fbd72fbf7e9990d7e6cbbcd6f566d9c8575ad9f1ccc9bfbe7fc558334f5c9be63b2efde77b608534b9fc726f99c9bdc299dc2f7a6db6ade4c9fd5dd498ea97c20ee205d93fbfc1b00940ceefefd7a72073da3423a5c7aa9a853a69e29e7766219dab669cdcdfe3d849fe6227f9d3abc2945cd6ec6be4f904d95d55dae4fe2e775795359fd83ee8fb8ffe74fe98bbab4a1599c769f36bbfff7443af70d79a9329eca252c96bf3cb2f77eeaf5eabdf1f3614e93f73d844c8908aedb5765af9897e44bf3f0cc3ffcefded876efd4b3153dc5d24a7c964cea3fa117dfa34b78f0f2f55a1a2933a979ee7776be0e1a52a675a47e7894b7f8b45bf3c34fb3b79a6f2279d467fc979bce6b89c6f9fd62fed771fdacbe334fadd159d463b9722943f297aad7bfa3c5eeb4cdfdece9dfb8753eceecc3dfa8f40909c467fde22a7d10fa7386fe77ac78adf69743241969f3fafb99d354d9531130dd95d55c2e4ce2599c52cf35a4943f2daccdd45254cf6e7f19a4f5b2994fd7b4440171f3aa9f3928b5eeb19c408a4b650d81e4e14c8f9dd35054eee6f58589f7e587b4be6715ae3eab4192777bfe46177bf4ea21ff63871a995e7f72d67ee9f5190dd35854d2ec54c5f5ca23d0299bfe4d56bfef4bff6d13dfd57fbe84cbfbbdde5884e6ba795b2ec3f737799b192799ce65fefcc5d443115398b086713e4fc167b5a80ec2e2c67f2cc65fa61acbf8bca99cbfe218f29f69d5248aafecee5cc79ee2e19d4e499e7fbe8347399e272e6727fd8231132d7a737abe68aab669c4cbf6fa995cbfab32630575c15cbf4bb8aac94cb8e93cb7eff25da9dd41fbad8770641ce9fb97b47ff1cab3ed3efb18acc140b396dfe92f76da7f5cce5bea145a7571176409253d04ce9f22fbf4ce953fa94d2295732a59452fa5d44afda483933ab20bb4b4a96f71acd6b6525bde65fe4b599fd3faf75570a56b2bfe8355a9bf979b8ad1473f965fff65abf7ff5da7cff2e724ca594fb86d69c5961e7f083902c41ce2fc5ec73ceebb92b67d93174f1f35a39737fb78f0290f4fb7b14529dd6bfe4a18bf3d62cbac9555eced219b3c43cdf1f166b1f563397ab38c8f3fd432ace4bf3d83eac662e577190b36c9eef2fb60faba926678979be3fac7d58cd5caee220cff7ef9148cde5f2fc259f631399cbf345af75f6efb169e6f2fc255ff2255ff22e724c45e6bea1e5d3b3083b7f5e2bfde9f707215982f49f5fd26fa7f587f47e4eeb8f22fde9f7f748c49f8ae2cf69fdd569fd4bae352753d8452599fddb6bedb4f2cbfee597fbdb79b41ff9f7870d45d29f396c2264d8d3036477a150267757ae4c2e63d91f83dc5db92cd947201305727e77e572d9bfbde6bd7ff51a7dffcf6b9dfd431f8178b8670e02b8bc715a67fa4108e8c2a5933acff1492bd30fa7486f67efce1cce917e482fd60cf53f58810cd29d54ce2cc8990509275b33d64ba3f1b678a63cbc2d7e44fffb485226cb9f4b6f4b69e15833168e35d36b726973d68bcd5d90cb0e4c87a60353d5745b6a787259af5431f50a984bdac5a62bd39f5c905d2edd0dcde264dc4da6ef64bc8cb771349ec6d9f8195fe3665c8d6ff1e078f1692637e19839f346cd5c33ddcc34b3cd4433d958385ebccc2fb3cc14339798646698396682995d33572ae59943a3547e99ce2d48ffd2c2c9d4c2b16bfcf8ec68f15a556c07df3c3641b69ead9da7ef59f101f0fc4d8a8d2d209b2c8bd7aa6c786ae811fd2d205bcf1499ec3d3158bc5615eb790f4d4ef6e383bd2d5ec07857bcd6836f5b40361e7cdb0ab2ed60af8b0c3da2ef99a1530de95f7a5b3c37b96fe03e2dd2f115a1104f9e8f656d54c5dce47243ed23cb89da4716b803d43eacaa6239ab27838f5583da47569db58f2c51c7a77d58557939eb27cfc7a23f321097393bedc3aa6ae62c590e1f6bb68f2cafa77d64c5f2c425f9594039ed23ebd3691f59a4d83eacaa38c8593b197c2c4bc6c6f691e5b0f69105c6da47960eecd53eacaa6ce4ac9e3c1fabcb6016cd605698415c8e9f1564db8755964fae82e572b90c3e16f5da47569767d698272ec5cf02cae0f7d3f661554573962ccfcfb219cc82651097e16705cdf691f579fbc822f3fcc625f84d76f28ea763737055ac236b8c3acc7dc45531d103303ff1c3b7effb2ca05c86b8cb4d4aec56bfdf0ab2bd3e2b28973b19c45536e2c48993bbbcf04d8a8d3871e2d83e8cdbb16d01d93c7c2bb2f8f61dbe09557c9301d928bef17800e66f05d91c931e80f9fd5a20ee733b454d18fa1e4499a93dced4a73cbcaffbecbd7dd992d7ca8f54e235ef7f78ad82ec3d085eeb2e2db464ef13e0359abd4693bda31ed9eb324b2ee435bfde9ac945f63ccbd4905ea3ef3d8fd7ea7b5ebba141843dd390f569571666724f2705f0597435edffaa07940a0db58f2061430d418a58ac213435981cb898dc5591e787b1aa99bb8acb89cb29cae45a4bad99535745ae4f8194575ab9feadea3871e2b856f6ae4c9e67bce49b6feeaac87e6de4390af9ac9ecffe97ca9de259d37cfa42e6538c15e633643296e70e97fe5933d3d7ca37d37bb36385b95fab9b9e86534a29754acd5ce112822d99c769d4b98460cbb68f5af44ea3528091c28b7dfa4842f5e9dbaeebbab102b1d49d89b0b36d1f9367ec02019bcc239a6193e993b24c9f8e9487f7f49184683cede57e5a94e97bd55af7ce76b69394e80f21adf5763fa7d775f6e97b5dd7d52bc48277b3bec542b5ba8780d249bfa7f6a97dea3dfdcfd2a7f629a5a1ad52dbda9ff667f567f63cabdf5d66a8d8ef2caeb5deaf93fabb0b8cb0bffbda3eecf777ed63e60c9cd699c965255a8a1f50e2017ef73fbeefbec7d1f7455f3913bfef32c8ddcfdac7ccddeb0a39ed7b8a02efbfa79fbb2b0a355936c7ef67deccc3dd15059cdc5d519c20f3dcf9c2424efb6ed7499dd433d32142fff941c0ecb4f147dd2791d07e68e708047c71fceec3f00601737752a9954bf141efdbfb7ef1d228dee4da495d5ffff17afedff7e3fde687cbefc50f1d871fba285e3083210dc76f3c45b1ea4a2bbfbe74c0095010275fb5192f5858c82f2ce2b21ffc251af60939bc1e7e0dadf85da7119727e4f0fbbf1b838019a402bf1b83df63d397434cf5bd7ff939f9bfbcdb572b9c550959ee3a522983ee656bb2d78eb28c677651a1798d3ea551a0c994d2ffc40404c0cc1779add49167ad2ccaf333c8f3c528bee4f9e42c9a0408a360210e146fd674599456d833148a3162321458727f98bb0b0a2e0a0597cce3269cdf45a5528994fd657d91bc4642bf9207c664cf8e75c89468e886a2b934f079adac4f559ffeecde9f7ebdf5c37a9d525c7a583b6babe88d04e8c46f24c0f7bd4621943aa574826215ab6657ee4e9a35f977df5d505cc9e558e64ab65fbf5620cae4ca5cd10f7cc9d433a51ed2faad253b9495ec4f3df025fbd35805fff5757ceabe7efd7aeb2b65903e3841da81147c2abe481f049f86773e58523b4a7d1fe5c351beb7ef8d4e9f3847a9ef0055a6edfb2855a6cdda8f62df1b41f83eca07c2f75e9d544b5e23d3bfd9b103dd836f737ee29cb757ca87036ddd77fbf0de621c68b3515bafef9eab8a83298604bf8af75ce1e7405bf7f563dfb903d70998c3176f1308fb3a0699aff3e29797aa49f8e28f4fc720d749f8e3ebdc522be7cc8fc59ebc55344e9ca7896354f36177168e1de04266890e60c945b9bbc8b821a3a613c33b838da31d3d31bcb3107667e1d88ddee8347e07c0642c77020bd0368ba57cf8a665037115efa7ad1b6f972d4fc4e12fe50edf6cf7decb625cd7bdfd1bee7b8bb7de661f6fbdadc355b638b051d1b2591a622a235addcfc28a23bf1b79428767e177ddcf89676187b5b664ef3adcf40867fd03a3bac71e07828d941a1fc7e3b2173fcaf8b2efb188ec457cdbf9d17e8f208c2fbbe2872eced7f78370c3d97011b791bfe43d168912f4e247213fe87b2c12f4225ef2110492035a327d0e58c9f4bbb1c8cee7bc78c787dd283b0ffb6e3c00d08f6f6f919dcfc137d8f77cb78f0f3bf16dfc0d06f423beedbcf86dd3b951c4077a1b370ad0ef7ccf8d72137fe7bd5b6ae534192877d706dce4ee3a0173f7de6d0273f73d1f86733c00ec7b3e76a3c03ef639f706fb9c27ef0df6e4f778809d07fa25efb9b7d8db78f16a654fec6ee2016e393ffe2df63adf63919d07c237f2471b37caed363ef9b3779bce8d72bb896d8bdd1bd1dfeedffe873ee746b91fe53fcad0df7051845ee77bfe26fb9bcfdf789eecc622b0cff96e0481fc1d7cd3b2c53ee8dea62d86bb5b04d67d0e8e427e8e94f84038caf8b0f7468b8bec7c14f1632fbbb7f1611817e5e76d80206229402f7e0ce3405bce8f1707da481f1d2e9572972dd88b1807dac4b79f73634fdef197e878a74dc89422f14dfc1157813d97c5544dba9c5ff210974ad97b109733c87cfade754263570ad0e7e09bdb308e32c3b7a0bfe57c2f5e29406fe37fee4df63f1fda16b6e486e28a6d614bb663c6e406419e5790dd85459bfc25591f8b3469c86c60035af206ac68200d07d670e00b992f1c78a381321a00a3812d1ac88d7133e64c0e45b1bbb30f3bbdb2fd99c1ecb1c9bdc663936dafc97683295d950bae5cb6ef659b4398d8dd59f7df9d75b829db7fe52ff7d8a4a30a2772e2d8b4c194ae6ca1b8027b1bf8366d23be5d6c83fcdbdb20c238a1eff92112e384b8bc277fb4409e9f73b7de96f3b3bbf536f1631717fb9e0fc238f17b72302ef6b11f1fe8deb46c3bb80a0c73557190a9ca9e3acaee4a424cced326bb5b6fbb7d3729b1dbd6db70e2db76fee7de7c304e14bfe76f389defc15b6f833d0fde7adb0ec6e9e0adb789b84a0e96c2812de7c51fb19458d95d4980c91363d506419eb804128a5c765dc0e4266d26bfd696fc12c5877dfda63cbefe374ac13ef624e52125f630bc9583b9ec6bd9ea7be39356b61da6f2b0112d1be936d8571cf9dd662e479ed05db3ee615fe56db0b75f42c916cf3a5c849c5f2ac9f3e737e511c351c617bffe373598f8ed7880cf8d2f3e1d8b880fc337d88bb051fcd1fa9cac224c424bc6f166cdeb49fc17569a00f87ec98120c57f4d244811cf9a3c97cbf471b95ca6a2dff9e5d493b36a6ef2fa99079d5fe277192b879576619a497d52d8188e3090dcc9d92149722727a6a303cb2161b0188c8969dd6b21fc5e5f8ae2875ccc6cc59411a3258bb162adb5afeb39aca2169d285ebf6dd364fb9fd768b61f5ad1ded7ad4efb7e1a417a4a53c7f7484efb9ee6b4efbf0f699447067ef4fd9741fe3e2fb40c9cf65580ecbe2f3368ea14566ae570e69fe5e5aa99cbe04ff1cefc67af9fbdf010ad0ce22e2a70601bbfbbc4a890bb4bcc56ee114888674d34bf9ee617c6e5d7e3f6f1faef7b92f298b6ef659487ce7fff5303f1bf0fc19fbdde0165b2033e9075eeecf5d3e6b6d89dbdf0075fecab4c5bec3f9ca2ce9db6d78d225fbca5039ec860cd21f5d9b4c24aad3c8b82fd2cfc9a699e7d90f3b31047e560291d07cef8357b9e79c96926af94698be11988ab62717297ad0c6ce34b89a5c05665dac69ff2e572391896e2c5b18d4be6cff132317f8e5064a6d9fb0f53b5d5eabc53e34dc666ba90d08284957c737755804deefed64ccbdd1709bde71e2b953ffd92fcd2bebf63a7988aac543c37957f7d3a4239cd62a6e492e429857287a9e877ff89b289e9ccf4a7069e299452ee4ea260c24904e943e4ee32a289ec3be4ee2282874ccbdd05468a262c296e72a9b584cda509306c20f7c726112475227717d7953cc7e4ee12a24c46cadd15c49b390a019f5093ab94806e74c85538582eb1b8c842b6432eb1bcec1072914b2c0970d1e5f24a044758600133b9bc126326f77fb9dcd81427f77feef719c2aa99bd898584df7df7debd9ad903711067b20556585faeea3879fceeba8f13772775d96f29a4c1db1fded27e577f0c624d1e1ffcb0031d08e8547ffc1e9dc6ff5efc79c507eff83e3abd82bc7e968e6727cd075fbca5e709667db98aa62097fbbf5b62cdace54d4a250c5bd4a2411d1ad1b2f947a14f85621538b0f93bcee78713836a944b20be745a4d60d77d5971f9ea2e7287bb7cddf7fdbebb523aaa68228eadbf765da2e01a8a2bb60fe7ea97af4c8dfa7b3c8051569a5a9d7b08bca4c9f441db953bb00c1541500497c8f4e7100f9b40e6b2e672190b04c15ff2f97d3933d57cf0f3f9d88e40aa80cc0fed87d3cd74f3d5bdbaafebfc9bafd7ebf52e8677e607fa71e6658d4c1ffcd98f5eda64faa228be288e60501070040283c18688be293644149b6060234c1c7fc967a437cefef5b3d9b733e4678666b3d96c768774baa1f7f9a12f5e1b1a81f0d8985138331be2983334fecf8f1f8e77f6c56bb3ef3ed4a19aaf9427d61983801ff47574a20fce311445a1110f89d7aa49247a31f64db0ff5e24c2624c84cd66bfe4e3ed2c74ab669ebd387b1f8978b62f743b8bb90b675f67e3cb7efcd056a05bce1cf43d1239ca63d0050292fddc2e8bd3baf7b9f48dd3ba7fdd9c5bdeb2ce2d6fe42d6f140e8593bbefb278cdcdf899dc3d7de3b5d777209e35d1a7b23f9f7e8f1ed8fa5fbc367ef7e1388eefe3cf0bfb39cbdd75030680b00284162f5fbc68f16285dc7adb8b1f0eb481f8f1edbf35c2397e288ae3f84b1e8eafd7c3fef5b0b74b780df6dd873018ec050b41508c89e293e0b56a02c1f0bf07413014e705ab7019f69d4158ec56cd0c83fd48e428c3f0cc69fcf9239e5f9cd6fdff3de11fffc538f77fefbd6d9b53bcdf5f2efba0f8cdd98d40ba8b875c3eca13db259cd6bd8f50af0ce2d20119fcb07d00b90fe72d71e50979fedf2a6f8b82bbff9fa369c4c092b33d9ed21e80efabbcedffc3657dfbb76d65a7c5fe87ab689cd783977e78cb13f2eb7b84a2e517a565a725776f9770334eebbeeb2698dc4d2dddbb9909a69b6172c793bb27ff3b773fbf7cf7a20fe0bfab6391fbff742cf27fc3fff8beed9a390d03614f25da805b72fda0efffa606dea7c9f4836ee979f6b00ffa259fbd522ea75256ca3dce7ec9bb7decc8be23f7181484840ad2be529e2391a02f3d8f73e2721c83082077277d5a1ec45ead3cefec61b70c7a877ad8dbb061c306b561e3432adab0f14b4e924444441f4e91bc4444ef231022184c1445f18732423fc5a15850eeae1bb6721824027d2fc4e2efb5f2bcb01f1f46db88b6b332836a2c161b8164f2760e67e21ce70b8d04e846024cec41f7b16f0d50e87f5ee87f8484848440a11f1a1212fa257f2121a14f08cf9c6cbcf836c4586c72097a8fe8c5271285be9cbd7f3806a13f9b59e83fda66a81b891cfdfcd0fffc50e94376478c7557624343e2d0d0d08d81434f4722477908cf9c641f7bd9c73e14ba56350b7dacf288368c188bc562bfe4b06c5fb18fe19913d0c31ee8611fc2aef842f7cb738bd7c4af1f7acf9087a6fe78678689b0db79e856cd2cfe283acd6c5fe876b638147f76837e8906ddce40d73be3b4fab26bc138adfecfed420f4d79cb6077c58996453c73f279d8fbe00f8ed3eac36a0fcda587c64393eb7f70783c97368c0d93eb7b67bcd659d9b9530b3973d95dc9f52d18afc1be7e48d9782d27070441365e03bfba3b19f07d0402be8ff1dafcfa244992dfe39293212d27974c3e1d819039b733897d8cd3ea87afd77c7d7ddd9fd7f65422fc1f96c849b9bb7eb0d2254ce691bbeb8735baac916bb9bbba8c59434df6c18c0f60b20f5b7c9892439d30146ff76ebded8adfd6dbf0ed3e0eb4b507e0fb3e0cc55bdf7e3314c5d7cb83eeedcfe677d6ca33a7efed0bf9689b89cb5b9eaf9527c5f23cff1b891c850ffbf061b8b3e2b4f0eb87e1373a19e570da9fe3cff913637986c13e66ef78ad9ac6ffbe49e7c76faf7db8b46afa3ee79bc8ff7ed4c1edb4f1475cd69c83cbaa99c7ff7049c24a273356e160b7f318ce1c76b62391a31ce29913a66c9c56fff541e5b746ae0f6af1da0bcf2d41b30bf95dba742127f6be73f57ec9b59054df772e691b271334b590f3eb87e79b40662c325bdc65eb6d370fb3e58909e46cb8caa6891b9cb04579c04dcb56f42a28d9aa28d9b8e67756bc46db786d662db97349dd642793eb7b991b94cd0d27e303b8514e2eb9fef4827d0c9e5c7c007866c99dcb2fd7af5db6de76bf67161721ef7bf6015cd9d431bfbb418d34bf1ba18ae0bf4fc7227fdfc70fda760393f468fe1c3f681bc61f3d9a17373d9a0f6e19721d61c4fa67b9bb7ac0e2b0dc5d3ca4c99df3babaab82f9a099030f5e3299ddfbbaf5364ff43c7cf31ee7799dada06d99a1dfee96c9adb77de2b7f536fb169775001fbe7d8ff3be3d005ed7c8b5ffa35d156d0f40d95d134093b13cfb164ae428535ce5e589c6ec390132b1dc5d13109379ded49fafc39b3c012fd93efd441094e870a6d6594114085bb6d00ad2d099fdfaa552ee3eca6b65114d89d74a9204af95b2dc7dd77df74f5e9bb97b25af75d70e6a72f71978ad43caa598cb2663412e3bcd9a0a72d96d72d729e5ee91bc56d277fadd9cf3e7b44fed77cfc7b2d9efcc455eab9a71acfab16cb63f47a724d9dffaf7744cbf81cc0fe7a5a2fff43d0671a23fe92de97b1f7ab78c40b67f8b1205f7e13c883f7dfa706983d8a74e1647f9f79a5ffaee44df62a7f9fedd0b794d4bcfefbebb74f892eded32c9e3b5898214a420f718a791faed9d71728fb946ea5f727b3d87429e5dbb795120ece903195221a3079dbb919cc714f0a7707d18be6e77b9872eb69a5c373ed59108cdf4c1db366fcf7488d60bf923a2d46e08b094bfa7a393c7b2f7e1ec6025ee4ab6bfe4a3074bf97b1f8538c955b8ec7d8f4d6269237b43b476c8df8754ac6310ad2db94a49fe3ef459e2b664db8d547e6f47ef13c1ef2582b76d6393bfc521e8b329acc4652d5fb27df2753f97cbe572368ae95875c2941450c865ab769a7d8b4bea23915a453315f5b0c593ce9f39950fc8fe9d7b0462bd8313b66bd192eb835aace4fa2f25eadb25da64fba1126972fd11873572fdf0bffc11fbf1fb7964425f44f39a7d7bebeb25be44f13d5114c30f63b76d3d865433a7efbbffbe0ff63d42851f08fbdefbf0057ee717888378fffa97f8de9df9d56310b0fb40f03512a90f62aaeecbfa5723912bad2c3e95fdfa1f2eed8bf8f59e56eeeef8e0d59a39bd7efcd78f1f6a65f1ed8d5d7b45aaf1ebeb6377ca942953625fa57bc7f46c7fdaaa74ef2869b678da9668d52d76db16de2a8ac40a727cfa746c0adfe272fc10cfc2ffbe7b1f9b463c0bb193f7f6bdb70ffee77d541e14f5bea6fa2f5cda0f3f0c6f29feecf53d7be120dd871fe22c86ffa2023fc4e5cca52512e2ee24dc49e5eb2991fa212ec1b77766f07567e70cca1f9f38357014723f4ca987d7286e6a812eaa10521a35854a942ca898b942850359acb1353da2924150840c65d8a4814613b6a647feedd869d969f4cb252db71f9564bee18b5cbb5941f657f25af9f5f01ae90135d99f87f68392627739168b4eebb098bbeb062b72c53cb39bae46d894c7911b133851468e034ea4b159294890c21a3464f8c014b6be81f4a76f03f9d369d4827ebf5533dfa6d6f40d42ba25d7d7538c6409726ec9f5db0aaa04f86127c2c0ce5f04fd6f20f881e015df5ecf7e08de0edb1bdeaf1b838c0f3ebddf8b37fc25fa85ffe1ed3c5ed8f52e96679ffffdebf513bf7ede0f83deabc579c77fbd9ebe3ea4d7ab4fcbeec32ee42f39bddd873d8ab8bc6511a4e4dd7a1bf9ed0320f10d17fbf600807f6b0f007df2e9d791082dcfff79c317af3f79db16bb5ce287f38ef87ee07d8d412cf821784b2ccfdf47e42877df21a1829c5b72cf2da25b17b4b28755bf9b3a3c9fdef296adb2beb718abbe7d1f89d07289cb5d79422efbbf5b658348f71397f4a708867277ddc0432eb57249df6d809369b9fbb013bd12cb73f7fd0d84e2ac0f53cdef6cb1dcbbddd3d1c928531ceb9f5bbcd6d55ff22d4148a820b13ccf9ca6ffe7596523cf5bb6df9d93512ea92dfde977b7bce5b21fcbe9e844c3738bd33a8b0898cbf32919e1fc2aa1f9e1eb853fa7bdbceab4d78731d7cadfdfd91f7d9f73ce7ef7aa5b9e2f22950a99d9fb79e70b97589eabe61aa1dfd23f8bcc4d6a0e855cbebeca5b03853839ebeba8ead3ef9fb824f3fcd72dcbb27cd5aa6f4a0a2864ab2c9bbfcff2f29556fef0bcf65fb773dfb2ca7393bbb72f2ccff53d3c6b9a5d01648f9cdb39a45ee42424c68c2ea262b4a74720569a19f64a4f79e83c7d1a7d9ddb94470f3064d96398bc263e7d0f9ebc167e5f93669341a5f0e9d3f1492b8bb8498f0c3e1d9d74b87420860c82f8f312e0b459db4ccc3d09840d458a3fbbb27da49287c7ccc99c8707f4c87e3b7d21c507c169097012822c7b4db6efb403d9de1413c2c9f62797305e736c3b7f9960bad40c02e551e447f6bf8f2cc98adb8bb245e3a404e901e531adf8917dd1be1b41968d264bb60f82d7c4b79f00255ef362b3806fed4f2ed68ad7e68bd84ab622c6aaa3e3765a5127f97757e65f26415a9b7da41ecea36df6bfa28ebe7d92f2a86fbf8b2ca69a5ddd06c4dc4dc4279a524a3bdb5dd7858d147ead1dfe994127b5cd7d0fe47c3fd3df75d7f577fd545d7777ada40b11f6d7d329ae947ea5dffda4ea2aee9982b08b405c6ad5cfb94123261be5ee32e34a36638d19647248c58e4bdd42b57896ec79d9622c19fb15a7796ecb9ab1bc746cbda73c6f7109d3f9f2fbce79fb3b1f8f9db7cf834bacfa511e3bffe393bf73db8f62af73db8f481cbefda63c7270ec8564091286b16af6c4bf4896203f8c45b327fe888550cdafd9c35422f66ac6aa4148c290583463e17282e9f20b53f97b4d8ea9e677d9eb425c6ad1914897a75fc9202d721aa589b2ecfdec9a845c9be4da56964b1272fd25f7aa66b6d8892c574c35bf62fa152fb91b32f9737795e125dbf9768e2391ae5c330feb7d9d60f22c67983c71e9796fdfad789e7defeb08c4eb5aa27504325db0d56b1d2ea76fb995a94167efdbfbfadee5dd2612e6ceb7c2ece1fb037cfa0d7e9bc93d9ca6852c7b64fa1fa5d16ed9fb7a71e7c2d451bf7ab7aba2b9eb68d58239f925dceaeeeb574a2dffbed3bbd6dcb597bdeedab9e7f7773f6f5b69ec5beec2d431e7f4eb57fa7afdee7eb5bb1a44d2798cdf1ffaebfa7bb73e08c4ff15c4c56fe701fbd07bfab0eb7d91d73c327f99be3ef0923c3e22b182b4ff12527be1a69e7d81e36d3f02df6fdfef965f299664ae5fe4351097b249ffbbde2d499efa4538d70abd967125f7bc3c4e93bdeb409642ff6389a989acba3035e85cafe4ee8a4b90f43b8aecefd3694e3f19c8f2dfffcd54af7575bee7bd5e9ef7f2aaad59ec775d195b64b069918e4d9586a9a37bfa7ebbaf65c502a4c34ec3d4e121a595de1148d7bddf7ae5849a857e186ad5aed26fbe5fbba544f3a6cddd3eeacf4eeaaa2341d25abf5a7d9a3315ad1453cf25f5125094a54951ae6f67f8894a5e4c57ffa39442296b20e753ac9a6b511852fc79f64bcff3bcaf5aea76864ed8afb8fc72ed9e7ed9dfddf74faaae2516cddd57211ea7f5771d2e95e4eeeb7531e4ec2e56f739cdbb499b08db47e7b28675d6afecbeef901490541dfeeae72c9001a78c2cd982dc5d6354203b96b55efe70b9f42bde7b17d2afb8a70efb7ee9db5bba15df7217a60effdab613ae347dd9faf52b4e73fbb6cacb56a4b76a550d34de819c5ff6c8b5eb470359f2d0fa140b695ad759be1509727ec993fd79f0b74508c3745a3bcf812c1bcd0fa7cd2eff5abbaefb9cd6d9ae0ae5f93c57c8f618c8c665cdd383952764b70039bfb340fda2b065b9e27266fbfae961e55936c9df97502a399baf95957a7420765282a49f81d37c8ee277ef7d3f71d968f2fc1197ade61371d96c405cb61bfafaf9dff7c233e734b74899def2234992ccee6fc9f079bce67df89ff320e9917f187ef59a8f40c25af31c6bc54d64154c11c41499d2af99e2197dadfc4e23cb2f3b29419e50361c385f311c0c27dbf77f8aa2f885cb56437eb86c36320f37998acb86d3646a87f1cc515c36a1e5a83902a1d803a7f9f7094ef31bc8f965c399e20455a021d5d7779dfd423114adc56593a2dc3d08beea7b1e2e3d7bff7df77751edbeab66c5e2ec0ed69d545fc869a4d32a2e9bf410675744ffc800698ca31186a152372ebf287737962cbfd3ead372edba0f43adda2778df2390164b9edc40baab87d32a2e9bb4994cdfdd8610fc6aadb52eb952ae4e7ae4f0eb2d7bd01eb916e519f6a047feb3c7ec51f6989fcb1ef3bd0b29be7fd923fbbbf8f19042b2a25c91727dd8b7d7ea8ff5bbd8bce0c3ee784ba5dc61ab5a7a90bba72310307c914ecb216e52946f62cce8c24bee6a7eddeab41eb059d184595da6b2effdbf64a1d3425c7ee12d7be4f06f4b1e42c9a1d34aac1c86b754ca9fd35e647ee112abcbe277625697a9baafcfa3dae67fcea3bb72b9dc14dbfc30fc70f9397cef962fe4b5ee9d1ef97bff794d1c9ffc52963d7af4f217c8d72379ed837def4d7ae4d87f35f0fd6397745af8dffd9c163e2c7cf2cafc280cbfbb3c4e0b7f8e4044fcfd127df092f53f8bbb629156aeeeab678f20fdc3cf6bf4d65af6988c6409b2c7e4726eb90fe4f725b995c17e93cb3a4720205ea2563503f1badb7976b8498f71c2bda0821370725773f8f5fd45fad75e270d277798aae28fe269e6e55e854b802c793ada449667cd4d154c1104154d64144dd8b824738bdf7d69bfed1d920272be7da7b2d89120fd71576e600c2f93d259c549c7c83286953a02a194d6aecd1a6dc69835792e1f504220535cb554342d6009d94c31c67cd9eb2e31b6642c9ae97b4711c61b28bcf6313bc93ba93fa42f34f503dd12368c23c2f832c3d0210c18e60d2385703c43a42418bf3060a09a1848052905184dcc0b0613130c2266979e2d3ee204c3069f1e9e1fa5cf8bd0a97ccda590c8d3c379d8fc979cc7dbfc3d786a1f34fb47b5d9ca748bad6c35d99b8debf0f7d7d13eea3f914b592e934b31d76b45df2aebcbfd559fb3c23bbb722e8754ac97288755ac3728879d58af2c8756acf7c727879f586f4f0e5f62bd3c792787a158af4e0e45b1de1d391cc57a95720813eb15731813eb0573488af5be729823d66b73a823d6dbe57047acb7e69047ac97e6b047acd773e8c3b3d3e3f303c3565864d6d1df956b0ca14b610347c84fee1d9a20c59e606cbd996cdc50ead3d9a099734e1f29ed664386cd185a6965a3049b306cbcd4ae766cb2646783850d0b9ded2c9b29f94d2e67ee30462cc8273c18063e9bc40b1c02fcba8422bd23d0228ee0ca081b6123c8a901ba8189744d8c8c91221a52a4931cc31c32d9bf70e27b750e99bbeb8b2f3a3b3a3bafef0b2dd9bfb8f245ce8b37f97b512fc2c83c3b22bd5eace111699a1d9d1c32061bc5107c7d1e0f4c27e745995cd6eef2628c176172f979c1e585979ecd46cd174ba0f15e1b80175bb28b79c9063060a9da925dcdf42e0787f2a062ccf87f39724b76258bb1593e34a41a191b7a54be9bcc835ef1a31ce5e16cfcc8ffc9c8ba4831f40a9b2ec7a6cbb1e9726cbadc9cb76ace7c85f268db47e692aae9c45ce9b26285cbd6d69629539c46739acbb2c61a58e0c0b9f2e68d15376e9c46736fe3349a5f751d76365daecb399b2cce26fb77b99e52b73e2be215120b4f169916a12ddf71e9725d64e0b8f12c6e288f6e4a67c54d87c54da7c54dc7c54d97eb24355d6e0b55b3858c1a31540d5d63a6bbd6c0c9251593fde7162e73cc0433c3ccaef9652e31bd4c310de784d7fbdfc2f79f39af95de9c32b7fca79579c56b6537b1cc2c5e2bebd4e2b5b2c803a1259e1e2212f8fa6a67671734a4201f209ff77feac804f578ff1f3e1e78adca46974197851e7562e85197dbbab2d46de9bc7460ba9c193fea3568be356ac8356c646bdcfc161ee771e3a3fa93a28c47a828f7d7a84ef2a7943afd3e2bace8371cda1397b7aae7cc93d695fd67165bb25338fd659ba9b8a4515cd2f2546325eca2928a41960ea69b8d83f180f2f83e9a4ffb94f26c323d261964f95e90fee5777729a366b008bba8b4b9ecffdf976de6f3ca7aa5aaa13cdc8d1ff97f6c4837b20a27e7b27fb7e5b5726627e3b42b944707c68ffcff653292bc52c6ca192c69b4acf123ffb2e392bd4df72593b992cb7ac54b2e7dcb16fe1d9a3467d4806bd2b079b559e3c66b58df1b38dfade1b532dec6d1781a67738688c8d7cc666e866848c8d5cc8280ccacc9e5d2dd7ceee6760296d7daa456116a4d40ad2040a9247461a8c4fe7cf3c6b588a267996dda3896b9c6adcc34338d4f9967e699b9861933138e28fa1551f4ad9cd3fc8315c81087ef5ab464c98205cb952b56ac6c6d4d99e239cf5d89229e6b5c89229e702e1c332036f3c2663e6c26bcf54a277909f2c28c1e32084e73fb84175372029ce6b229b060222b719a532f585cc82238cdbd1c109904a77938021064c94d9ce643b93494c8509ce6b024bac892b19ce63f2c8c11279fe03407b7e0604476375d80c9a5bb4193cb7aa55e11bf568e350bf8b592fc9caf953afffa5ab953bd7c5f2b7dfee76ba5ecc3b8ec9ee0342c284c4d48f82182920c12a07441b81f78e716a4bbf13743404240ef4fb100cd72405382808088de9f5e99cddedfd72022a25666338743342444b76641404a94c7121757fca8b380b8fcb6bc70497af970296b304b5c88f1a3eeb2b8fcc874b824cdf851e7252ed0f851679bfbf19f33c22e2aab9a6cc54a98ad2d3053a6d49c9735d6e00207ce96376fb4b87193c5694edb5c791ea66c9cb271329e57c354304f5f9898b8fcf8a1c5bfaf62f93eac54afcceae503c1bae5456b96b9862c95ea15cac6dbb459133e5513beaf599386a211dfd3a4a167a899f1fdcc9932b0a7649c56a6cc1827e364ba8a14c142af78fff464856e7dcfc444a7bc9ee65effe387afe170c0cf2083374a4a6e9ce6579462a4255a8cd3fcaa565c148682a92f24f48587878b286ab9ea3a4cb3b8fdaaf95716b717f2ab26a6ea7c45e2de72299b2cea952eb67239cd742965c9ce859aec64288f09c78ffc3f182e3f72c425291371296b3ae164ffd0c994be253b86337370fca717caa362f1237f2d1f17f28bac86c93ebd64ffa905d95d6adee42ea1594513640b0292c97e0bc8365465a39aa147fe5b40b6a0a1a1af5ee89157c52a197ae44342335caf64d9428fbc8211438ffc6b179d6ac892b2f19f5d90315cb6993cfd291baf955d847ee7fd691b7feac66b6597d98bef4fdff4bc3f85e3b5b24b105dc3e7fd6bce6b6517a027dfbf4ef979ffbae5b5b28bec75debf5a7993e717f9b94f97c969fe3df74706516ef2fc9c36793ec926cf8fadc9f3616af2fc314d467326cf57a23c8430cd8fe6cf405c7e41b8fde8854b1208b71fe152964b25196e3ff270f9f9fb3a5c92b9fc70299b4f7155e3e33d197093fd7b665ad75cce59a6939e808204a47f39cb5895e924fff9c434e347fe6e9e8d4c4df68926fb4f33c8f9e52ce36eea7415baf2fcfa659ba9b86c5cd272e3b2e1643ac320cbb9650b36b96c38707844f9913f1a346ad4b0c95ece2de5f42f69e5dc522bebf4427f7ee92969fe3b577673ee8ddd6f74777777f7aedc37b476664d21eca2d2b7642f3dfdc72ffb4cee6f58eccb4e93fb9bfcb2d5e4fecef9b2d7e4fed6f9b2d9e4fedef9b2dbe4fee6f9b2dde4fe9e65dee42633c774cd25c4cc3060e6172f4e1b5ffcd8c3be44ca79f24ba59dd7297b9ee7cb1e3feff3e50fa0977dd95db30ffab2c70cbdd0974d26f78d8bd3e8975d26f70fdd139c465fe8ce2d4ea33fbb584ea31f74a716a7d107ba509c465f766716a7d1ffb94d9c46dfe74e2c4ea3df7349701a7d9e3baf388dfece15c169f475eeb4e234fa3957c99d5b4ea31fbb09701a7dd89d539c467fbc20388dbe7867ce69e5cc69f15af8268bd7403758bcf66a73c56b1f1b2b5ef3d66c79cdaa99e2b52e8de7bc56d1ace1353fe334385e9b669c46df8c19330d27fb970d27cf2fa79752e9eb2ec8f9252d4f717cfa24eca9fd98f764f97dced3d7eb3c057fe7c3e7792a7e0f8d7ecfe5b97f75aeec929784dd4f2c93e78764c6e4f9df8f3cdfeb91e7db0cf2fc4e29cfaf4879fa96dc37b466f3a340d84565bbc9fef30bb2a4cd1190ddb585167f12debf890f606bc826fa8b000bdf5f890ff8fe09f0fe367e151edbf7fe206c0dc97e3ecace177905c9c2d74feca3dc448ce360f65141a22c0cfaf928307cc3719013b3e1bdff5317994c0c43f0e7a38cf8d6f343cf13838dde47b95f85c7260b451104bfd7df7670941bd0ef845e0cf651fe475014bf4fe815f4b7198e02846f44dfd3e38121eca300fdf889dff77a0509c95e7c7d414142b2bf21f8b7d7db8266427fb3c9fec1d77f7fc3f91336a1bf8d1f25e86de028444398cbbe177ee0dfaaf0d884660c20580307db0cdfb6866cb720fc7a9c4df63720fcfaef71b50c1152d86458cac4d138b6d7df70340454be48c1f683b9caeeeb47f1c1371c0771e2d87a30177d1e7cdbd1c15cf373306e62ae8a8bfc046e6490802d86b9cafa137f182e5c7c618361ae723ec54223e62ae9db2822bee1260b4894600c9bf737dc0c01952fa4d842ccd561b24fe046062b36f0869b71cef00019b617e6a2b84e23d6703102db87b926fe280b4894a08dcdc33c930d39bfac3dd3ea5c4413d6212befad60d98ab48fa593adea07650f63c9f2f758365bbdfe275bbd301699c3c79265f0b15ed94a2479b29588b1c80c7b2c591e1f4bcc56b117bf9fc72a2b275bc5301699751e4b96731e2b96ad488cf565f263565961b6dac1585fe6792b2c59f6792c32f73c564fdef9ae9a707258b20cf456586496fd8f1516996d74d2fca1d6716927cd97dd9fdbad63becf9d75d2fc9e1bd449f3792e5027cddfb9429d345fe7ea74d2fc9cbbd349f3c9dbd349f36397a793e6c32eac93e68f37d649f3c54bb68ef9e1056fd849f35f576c1df3bfeb75d27cef7ead63bebd3f9d34bfbb3e9d34bf5e5927cda7d7d6d6315f4b36e914e17bcd76def7afef17eaae5cce1f045fafef7b7fc2fb0e0a3534d0bd2d438b1834d8afb50c1152e4326b28cf2fe708aae83246a6e1537dad9a71e28021f85442422ff0f5dfeb7b2a1e1eeff39e8a243baf7b2ab16a76b834c146ae98aa9a6023534c45f5bd66cd85b47d5865c9327dacce2a6b96e76339f83d9697bdef2ca0ec3d56cdd62a4b28dbc79ab9b3cafac9dd63d9ec5941d91f8be64ae90cb376fef5cdec65bdb297933d2c3a2d66bf9fb43cd962d2693b3c1de6f1f9f1ef97399639ad8e42ed23ab27572c44e464f6f7269d21ac309bff14aeaca01cf455ac8dbe14988fedfb7e59cc567f0a5716509e5fc5b3752f452897cbd9aafcd874beffb39ff7526c84b6d74fd9ea6ce157a136f0a5c4d4e472b62a3bb6d800a654d1b1893fc6fa85461bf953b6a84de7ab74b69c9712cbf5d87abeff45dbce4fd9aab69eaf526d3c2fc546572e67abc263031ac094295540dbcf4fd9b236a0afe236d94b89b9c9e56c557482be9f6762b269b79b361fe80af58ef9b23bd43be6ff5ca2de31dfe7dae81df37b2e50ef98cf73837ac7fc9d3beb1df375ae4fef989f737f7ac77cf2ca7ac7fcd8157bc77cd81d7bc7fcf1c27ac77cf1c67ac7fcf0be7ac77cf082bd63feeb86bd63fe776def98ef5daf77ccb7f7eb1df3bbcbd33be6d7dbd33be6d35b7bc77cbf5def98af357132a76adc7ae75ee4d4ddab4ffb454ff4be5f48a87ab6ab94878b8aecc7d9e962845d7b727872bebf28877e25fb797472727e0b88766f7f0b48f4f1dee7f560ffe713bed8333eecb7826c3c98aba48a394d07dfb8cac9e3b41ccc5552914ebbb10bbbf58af7bbe015badf159d36dfbbb7bb5f7471560be6748bb08bbe8f2465b2ef3fa54ffcaa579f3e52c5b713e811a52fd4d5fa5b40b657950d28f6ab621e1459fb2490afcfc34af4887e0f7a447fe9bd866f51f4883e08f488be92f9a5d2cc4defcc84edb5febae3b7826c3225d90dd793b3030023d0c6d00c88bcf1fd3c48372cf82d20db8defff9f24fc444241de9303801df1c6057fc35530fbe929fa2b33ca81e37137fee8fb859292fe86fbe9c9d9c9f1777c99d1118ec70d7dd1f77f17ec50c2379c920eda0dd907800a7e6600a860f683a34729f6467fc3e9f81c458fa3fdd1df703a60b41b1700d54605efc3a3f3b89f279390f06d2bc86601bee16837ae8d0a3e48e6c3a3f3b81efc7fc3f5e41c612eefefdf703b2ffb1b8e16be11e612ff86bbf13930d7eb6fb8a1c781b9bac7d9f822cc45ff86bbe118e3bff8b1cc06e68a1161d2033084b9609814c2df6cc4424ef30f127191d36688654ef397dd703f453e2f2cd483b93eccb383b92ce6d1e970cdc15c1593f486d6e85f0da192d0c778489dc7854b4342447fc3fd3ca9f3b8598f40cfd564277b8ffbf99dbfe1661fc35cf471b2eff97e92fc91f1f8fcf838f161dfff41e4d4f91b0ef6b0c73d8d08fc18d0df70e1cf1e37becef7f7c0e5bcd0df70e207f1fc0da7f33f8f9b794079dc70e20f61aeef6fb8f1853097fd1b6e86b9823017f8371c10e6f25ef67adccff37cffa7f33b8f837dcedf703ffeb1bfe17c30577df171e4f7cc5b9569bbe17830d7c4b21d100be960ae1726733e5c44622e1ea7cd8f61ae263bd9e277dafc1b0e86b93a3c569c88b91a7339161fc7a3f5f2ca157651e9b9e161bdf811fdfaa568bfe4c9a550ee27bf2cfa6005d2aafbd8f755d8135e89e2cecf1508025d8d5d6e5b41b6a01fff0a06f3f9af8ae9fc3c9df3bf7e7bed838040d9ec09452936febf6faf5de57cb0025935b385d349f43b5fe5fc0fbe7151e5f8e01b1715ec357ae4cf2c483865bca683af7474b02d33e62a2707b7d3c8f7ba485c5a3299be1de33518be82c1b01db3c488afc611db25c278f19a88af44115b2f5bbe782dc4576188ed172e368cd7407c0582d886711a8dfe0b5fbd5ed813e334dae5e12befabfcaf3cec81719a1593e9d5fc2ac7545533ce557dcf0b2e2d18abd8fbcf2d48cf7568e074979a32f93fe76df1b8780df6b3c56be318afcd9da2305e137117305e0bbbbc06e22a1b3d4f816c3d5fbcf692894b78edc3429e17af79b2efa77251350acc64fa9e18af59cc4525e3a2e2995c54649c3871dc7cb002593f3b2e6755a6aaa884c9940ba4a99e2441a7109a299226003400d3146030482c1a0dc80382284aba07140011a5a2505ea0c9c32447524a19630c02869011010118009819802000a06437b3b88b06ca113af6e79862e7c185e6e24ef73a68c1908215ee40ee9f424725ce944890ff64131ba712105589b985180339966aad0d4de1852fae8208fe3e822614da9a080a2a43e90f76d244d4b11122ba88ba80ba7ccf79676208ed3e891802dbd010f2bf010da1366e975ebc426f382cb040e4d1cdc52c56686d7800d52148012818163ed4f59180faf03851f820257890ba7533266a8b191fab97c02c04bf85d1380863df59dcd75aafcc1e7b93feb777db5b0f479d7cc04424274331989143855f401580ba0bec1ac6de17090612f4dbc147e10fae016bb2e27524ba3c4575980275b75051c1156235e0b1b8805b7e5e933cc03ffee3777921ab734c37959e48d8ef5c7b5ade88f74c398535f322cd15bad440c6b3ea3c900d0589cfb94c388f1a1bcd3ec62eafd290bd4358cc7cf2d988af1f1c456c7c11ddf0d9a84f9079ad364c7da002bbdcc5f748641ca04f480784ce9b14dd54bec09eae53965062765ca8eaf151746da5166ae34b53e764aec2638a1b15e8a8de0403ac7aab25819ee61f15208908c3f3a0c98c76a55a53b4a2c73485b1720ef4a13fd862cb9d8da5456dc1c900ad5497686f4fcc25a267a884a0a2e5964bfc34d8694aef7023ccbb0d29ba04a1cc34bd1f04222d07bb2fdea4c31de932cd847358677d443ff753cf1c5e9feb182f888051afb9ac75735b5c3de2f7422c27853284a5171c10e6750a41e04b3d74b04191512f53e9bc36251fee3d1c58ceb12446461b06d48344396c2392a2ded3548a09c8672fd0f70d7d3705bc4ffa476469c44a5f9c9902172a6741c6a02284e9bcea3999c939a30d2a8517234a8737e6dca3172a51290b15a1be5d2e28714c1702ec11a90672b8f7cdfa569a2ea70e03436cad2d77a79a4f309ebc066050f08af6d6ea9ab00384751ecc6089da78b413b286cfa494baa894e7c271a0a103528b318152b337df6cca18c717f1a4914c68216a945aef297715e1ee23e0b66669f16407c089d1b661b106c95c84a6f0d09e644e29360250c7e7e4910793a97e7421be451f22a6243fe1f95adf1ceae0d558f23262151e3e83fb83aa1a676bb5616341050e0298e27ba6e0b7dcc9100788c9854fd94305a6a9bb0e057659223e99a5e37014a319b54a8bc1b8fcb818b2d145544f9116d1c7c7507ed941486ff88f1a1327ab7d5f0ec2610cb0c65b8d1fdd4032e9125e2be979a6f8bc54cb5309c83822fb1b46ec48fc46e2043d118f0478cd03c1bc2e10322252f41f245f2548f17e6d5b27c89e10d1d8b3fdfa4f1b0c8497e268418968515db5e705478405cc9c4cae1e1cbbb8eccc5432f64b5e67464fc1641f4f58ea7a9fbe40263f3ad5ec803c3fd02d16684a96238e7973cbbc9323793c1b1ddafaab2f444d4e201de7e4a0d4af90454e16993bea525549d5a3c2898187c533c5dc116bca764fc166cd2df22e8237455a0e54a456be563345f6cf44604c1d033049d67b0fb5b5a987dd6a43745187cbd0ece938a43d647c4774fc4c74084a0aaa7609a6ee8a8e8e9004ba37f518d778b78c74bf4859d03efc4a30db89eb57e4040457d8c75464ace76704d0d77c724eaba29e4cf7bdefe1ccd8dba4cbf5ce154ea11a3c3ae89cd669d1d21364fc7a7a7ad9f3a26bd876e6f047d720a3014eb93d20d08872b352e135828c9347518e0134db6c49b8ac8b263d46f6b86380d81ed57643a39222b390b29a9012f610a712a31ea400dd80ac1d0abc679001385f637c826e712e734c8da0d0f9e550846c4a1392cb084a83151337e0ce02b9d52bc2148c3c96535dc0808fba594073e3ae49919be2d7c543fc366061ccbaebd3a9262b001789b92cc5de4c0b4d9944b906028db1a55329c15da7f0c65886495430cfc762111152986e26cbf1e68c209989812733d04b8c96d3e498a57d628673fc8d633a1f6475c40c38643db0b24232e7b70ba7b9ee274876db00d03a76c8c6b1765902a0f099f9fbf9c23fdcf0716ce1381555fb44b5753ce9f50435ad69338cd57be9849c5862b033924a53aff3f770b5b82882a27da553e0367746368edbca1451105a40d6c771b81530708ac3a44dc83f0d8e0024a285d2cc60a95937c9186e758fbb8b8e3e000c8df2c2cfa7dda07e016aebf68146bf2f50ebb9d9f384cbd07a0c605b4df0d02536e898af7355872d3484cb63283235bf0de9904ec546067ce4a7730349b4b231117a73406158625d8cc8100a68c1a00977d0b74a2b3b71d5f3731c5923a8f6f4e3c4a68614ed26b5af5e52ff121d5011fba57a24a00cda962222022dd5843dd9e26e7511557b34dbc532d7e9fce175e11e1ef70e53759f315d165476408ea10bf9f4ddfe8955dcfadfe337cf5e69cdd167e3a4684543289a4b7a143733960b3fdae72e8754c8d9d914b67a742edd71ea7eb723dbdc29b352cd05cebc34f6809aa9b11aae8aa243052f155ad5a30e6780d0720def7ff88f2b1b1485e35aa13df472e5b80a0a201df5f30eab2104e864ea2839bb8013d711fb377ffffd43eca8d4093e69fab6973fcb17092a1ae4f50370a9c55b0b33063714340f227f0c388a70cff78726920cef5e237ffac950055c0561ed693349537e0a91f67f0b4b42b699074693c455d94710ca5c3685f8162afed875f308c03f21ec3333114c5951461e93d27233899ad4e6598f4f3ba5ca02ef83f19b8483883296b8b4b844f4da4af689ac309a6964cd1c0bb5dcac33d7a23d8d24e0512dd81fc4213336525b109b698c249f67cc8cbcfb9d06b31a8092c07547dbfb84ce60c9decdbaa0fcf1389a718d3d3b98479d04fe0e6919898b1ce0007b136e28c2bc4e2d2976969cde80a98c2a3b9675d75809c22ba5f48aac4736926033e1d22287bf40c13114084d384b08472487efe0971fb073eb1494613c323d1342184dabf4c80f381eec9caeed51fe002c5f4866d685b4666ba0936abac5124b51e70b9da59388b14322169bee25791878f86d469969c5592197b88d5d837503b39566e80859d523117c181355006d86b4db69c80e1859c2458e929ac991a86f46e9be88242822dc9a9c9ad5195a21227cf1e442f0712038c79534ce0080933cc82ad1c54f30e42f1892d240a75613289ef7a18bed291c99289ada3594e633351cfd390b9282d8d07e0a3cdb9722472b2e7c7b23c8200d7ca3dec7945036e4c39fc486331231f0349a50d7815750e235e80ceddac37f98c4490e3bb2eea9382bad9c1321c0be33ba55f486782edab4571dda3038bafc724242bc82cb8855cfe95d127a481c8ef2fe17b5501591f69b7ccec4d61895567119ec680618c9438f69e44416d54889a8fb8f50a904102b00de27b6755ce331a375ab651fe42ba45be13ceb169f1c77f4d16542ce9a682ca06f941d896fa1a656d17093baa3ce527f76383c7921206022d9c5073e3c1f0ab1db64c6444cec44ecf4339d9aee9a117f23aad230321fe91e634f405c871103a6425cfa20862b2c4b5626dbbdea8b19a608fbae91323864016b463fbfae5539768e7435d093e0d0d3a9b19f4cb9f82d59df738334401aa6230eb599bd3310ef6c955ad49cf15678255a9901567a4451b0356c7b248aad7468482fa531e936cab9e00f2fd11f30a938d98804a5bb5a6b5209c997b4342871a6174a87ce9fdff6bfde8dbe39dfbef22845d30039ac1a913488be56a39327121342e069f3164a1b1b14eb5eff180e6201f013eb635f8cd1c666e3321c81db8285659625261031d34cba4d2172a0c8c26705517a11a2404403e81084b4830da83eb1b20ad12a41537aa426f574822ad583f027abe7f922edd8471db6a6c739b7369f7a077019e14708c21280f33bf0cc4be343c9a9b3692ffffb76ec87378e33f84c6a9719124909e9f7832334f23379763a135375b5018fdff8f26d66f9600d79d770aeb7541707c500ad970e26b55127e6a3a40ca2fc5045567be4094ed5277df674c5b04ba59bfa5360b6eeba5802b60e43c96f68a33f9db2bceff8b1aa0f2906b0486e7623184aabbb4329aa85fd5db76205fd0de6393a669677a0ad8ad477a22a750be83465d6d213f6b0296218d4eea32110d68bd2347ae3319815ff4d509906cf784f1ef91f00b57d7e5f78043d2fc211bc756e037b7f984abbad52831f8d6b8deadac65b096db275c89fac56f4b5055b638acba39831db86ce2def983c199a9fe896712141e15afbb7e3db5906da355d04608dbba91bb44be74174007b37c0fd1ebef81d0727b492fca256a7abb3a99aa7ceff8b06e06f01f32ff8274831365267cba8bce93a17226310af477b61584bfb59dbf0cc68022445c9e382844377ff586c463b7a9bc30746ca66b87c1d7354999a951ed3038e56bb4446653d24a8a21799c5d08a79f3901187f80f9c8ec7ffb3dfe1ae04b52d8d953032325b824806eada4662c7626cb34b0453fe475f86684b0f8477f0cdf49e66830c56b040e832d879e5f92eb74167f21d06e7f00e990eb207027a43ac8ff12b1266cca6c1520e560c1eae3e13311897e2c7b48da5349e0ec93d3331c4abcfe51efd1b1f372bd419b5df1cfd8dc7048aee18054eccb1ce1345286b0cb4b2b254a0d8ee79668685a5472c25253ecd57f9de378549b1099f5513bd6588eee4e9587928faaa9577b1689c10ab973aa7a3030967e95400b14e1401ee21b6bc1d5770f14f23dfbec69b0f99cbb86e0b627e22618b8ae0f5995d1ec788c88d7da2db6c25feb917465fb3087c7c63d6bb7ac4de70404f5a63c4a11b52d8a39340ae7046d0560bce522b55496fd724111e037fe99374381b870cb878f2a30aa6d9b6a2854b7c620022fe045e1f9a441e65b3d29a0604ac983f681fe9696fa11309150877981eb92d1e08ec24cb999f8211d955e85bc0641ebe60a9950380e251053c3704734774c31fe2b3c950be2562d881fdbde3bc69a26ee5962dbc31e8fd52a108ff4575c5173c092d210c5c87dff750d5c23a2e150a045fdbf4d34194163f8bc1faf5ec41c82f3faa7b2196d45ded7c3ad4d7d8b49af18baa9a801582ce917587cfae831258c12fddeb2deeba5a3628dc7164b0a08b771568f97173e959dfed4f1eb9311763842e49116dca48360a343ba4f75a28d6ecdf5f7ff52d0258b86eb5df72a928bd0f32004981d154c7f576793c7bf7d0a436670d5408357aff4d24e8f54a47ffe077a2f8d75fb06f13c33a771ede8012060dcfb792fa3dd9c4d308f67be25cf91158a5eb35da18e34da4ba54bac375ad3ad6ca9f38e7b87f65f3039df98f9704fb2ab602ec5fc13f7d63a5b517d128298360f2c76287afbdc6f13df7e15bd86dc7f5d8a9a63973e81eeb0e322918f6d297bfe54b3dec6773ea58f596a111100f4ece1de560836bc9c83e30846befb0bad501e5ac15f681f0b29ceed312f5bb05dacf2c08624560a15862cc31988187dd1ea064e855d8dbe4c3b80d2b7f5c166e166cbb84b8c966260557501b456df1c27b9cc2a26eee6a55cdf11d8e56127b8570131973b2d4e1bb0cf77557b3b46a6287ec693c44e64f362c2dc1947c0a67d327afaa547c279d770dce4cb91ffe548062f7da0d80e9ff4a09daf4e044e5c47610b7a23f61e30aab2636d3b349cf94a23c0a46ca8fee08f3fde38e3d710c5d61e77a949f5dd2c3a00b24344dcbcc3e6b516aab89ac68dd28fd540028e99367ea479a8a3fdd701f79bdcbede694b9bdc52d883dc52619a4c7f4b5b15f26c6ddf4b39406d7d7fd2822f333a0bb9265f53fa279517f131b707a4f78d95b2a6256ce2d13d0e284db7b1b48c815f5765a176a52f656fe7b13d92370139a3829b39975f7dbf464855f4e81c68962f4799713e2ba3482d27157690afe465cd809ad85b7e675dd26f20e27e084678da8109a15ce648d3a9f10fb9d20ecb767d2a934de2ddcb495ff5635a27a1d2a6a052b904874946b247d591fa96f0b53bf1650e84bc0c286b2b707f020e6c04e84fd93b80b853b6330b4e2ba83572e254cc0cb896cfbc9970c773c31109386d454f1d45f2da9b01a5807cd7eb6650d0c805c600bc2ae922cd15a74029f8b6c225e4d2fb00e4d5b9c47c61d0c6042bc52fe893f303986473587a6c21626d8cc65b5e6c6182581a054e9482c39dcf1f88376753f16d59b749b8c703c6f1beb559e0614dddbca13a5fb6c0b0257c2c0d585a23b3be49b391269a04d33ff12d5e191160e954c5cb120db982dc170ecc753677dae1a94d291eeb542e068ad204937d2e7627295507f03ece6b7e18ecb770a8ae1828073a470147109e3c9bf1ba99364555d1ce891b094a79e91689c7c5a1fbe2c610139245b94dd1992a44a4ebea8593d1fff217b2ed45b1962141837ce21dd9a41158e017f545881aebcb928c809e61c90488744546f0628df6eb1f617412095a9b96898a7b2974539616ae55684b7b2233cdd0433311855ec25625349ad54df4b614deb7dae2a3e441380e4bdc4b127dc40c41c708ad7de763b1978d2b6fceda0fa560df597bb1beefce1b6fd533add2c558807f2e87b9ab7e380ae6dd5457e920d59ca405a24df416ec9dc65fa7bd9edde2ff080e81b588773b1819b173a146845224783275713cf477498624c24f59fb0902f061d5aedca94f53e8b0304ffce44eafc8f4e2b2cb51d845bba3ea3e7947c0bf456ad9de331d8e9680676610d52bb289f55ee118d9854b18fa13cb0880cef4299616077f6c49e507930021df64719a8f1313d374c2ae2121d56ba80950e4bec4874e87085db2b50e02031be314ab0214a5ce328011abd1233769f2056c0b820cacf93e92bebbc6365992270c78ee595e97bb2e3552b74251a15cb4fa0f22f489132b3820b98f00d3c4dc8b104df9130008f43b6a408c2043c54f4135ae162d30b8fec9a61ad0449a7d871187eab6b55f1066bd8ffed4ea1d8ddb0454ede1b53eb0c56036030449dfcb19e9cf4c58874bb7c7e99c3ba5dd036bd7d2155c786d66abf2ac0da938c869cf386ed2f0603ed6f3665c52c5b75e26e3ecf8e2378e7c1091618e38aa6e43f2354e892b9c43e27e00fc07d1acf6e10a0a3920642e0e95671ece36d29ee0932a71d73842df1512f4b645fff8dc1c4ffec189e62d32544ec9f2d71e11afbc975a861c267434a56e84b866ec7e2ad61b89e14e4ff0e06c9c1d081445d4f5c4b32ac7135634cc3f3ec5de5f982a319f5f857907c1d229f7868b05c380aced9f758a76065d83b12587b034405936b500553158f5ac1bdf633abe996960d73e16b7cffc69124203bb4eb6db37fd2d3ae6a23c7e0ccbc92eaf9e9993f5bede73a4d8191080b69c247031c2da591004a892d9dd62f3ff3e163c63ecd41907480b15f291bd9f15921db85d919b12093c009d49f0c041bc40a31828ee468557e16298c179e804baa23df6754cb07fd06e32f3419d153398a992ef3244cb33635d8908a0e2a0428a0581c07b082b824ea70f04e74fc881139210ca4424d17bbe9e2f05ea59222e890472b90fa9e1e20fdde6d00e61498cb2a981348989d8d5a72f3b404eae6dceaea4d53c6fda6c21923647922d326cc01868c267b68e00c0e4aee7a1f32028855a3f0bf9fae2a4d0f027d9824c0240c9ab37ae6cec21a3658ba1c3825caa7fd93a2b6f9fd6dbadb9b5ca4f40877271e64a3ddabc24b78260415def55ed37ba950802777d12be92fece18ad8e1153fb09de81ac0ad0abd28ae751f6a90a99d106ca5b75839f0264188dd98daa69b063be3308981d5e6642ed37049c0a72430ae97865e5cc5400eb7a0b34a51d0c7bc9c5e8a99dacf36caa9dc19c055aa08f173cfc4973e3a082b06053116e2cee8598d401207497606617fb053a6d8a364dba3f74137864c0f07e4ed37e2747407f22b608662ffe9948853334292fa8e78122a2542eff20cb598c0c9e55049d3381b8431017ce970ea528fcc3262905bebc85aa442d283fdfd615acad81156c4841f5e8405fef0cbbd0d9c9c964650a0b162f44a00338c35fd5f48bb06a3fb3d96a358b5dc473e645d2c14e629d24f2cd9f7c507fd6999160684240312907666bb19de17cef4d75868a232a384330e3582df19a9c9c7c0288d2bbedd6ae409edb2876d1db6aedb34a63dc064da96bd4b1c031b9b00099b706d318a262d6db1696fba193e3d8db380794107b00a2c293aac7f108e057aa2e0a60a1118bf99db227c46aa84df21350238afac5264d230a0eb0da91abd6dd33b1c8d4f4242a3a1adbb5ac54c4d4a9f3ded0989549db94f9cb40cf1da78a9cffdabe4c2dc270c59d5001a26ee99539263c0335b2b6105cf5e1c040cd37965d635b100ec86d70e41d01dc0e8b8a114f0197afb574e36ccdf86c625469c4ed4ce668a4bd4838d45d08be3590c84f96c658898c88890d3545abaeae7e92ae7e1daee86e953a8525ae9b43345183dca5640c5b9a7638f91efeccbba388039bddea3bf10df4a0e4afffa390e9f227ff18f814fc29d4298da78f1aa44c541d986e2b564a733cd758e0e5278aefd7d197b3425fde355453fb3f286d7c7aa725f9f1dadba101cdaf6cdaf340de3cae5d9997e8049205cda2da82d18229c8450b04168029d4c2b154242d89126bb60addf8e8aa3ead6fc151c1090a1e9451f40946bce5d0e875f059f3b6a662cb3840644c9f3b1bcbfee4134bb023313e73d6e087ade5280c594ebb8f692c6a1fa149054e91f3556f87f69e6fc714907e63d0e5c790e3988e155542b369559815d15eec6e9bbcf3135209eab32744139047c4a4b8a099f13532792bd43070e6b2106c72d9600445f09bc10620141b954a1584fdec7777852bd1a65b0920bcd3e9c7354b1d26c4181f1138bb8141bc5731fb50060de7e24569f49dfd382d3cb88e899e4e747be59f90051c8bd0760eb8107aa830d287756a13e64d633baac61dd8e781e681c8ad6691dea5589c53e5332971568e4bcb292a6f01ffef7f54e17a728348f68fb0ecd0825680a10d790ad00611ade2c209b217001ee66d85f10b9862506faa36100b25e101cf8c245a3a1c62cf61f17baefa16a3474bd725daa9854317cc07beaad1eb6747f1b3a3b1db6d00c34f5438124ac63128d0c4acd357f4e39fa54bb2649f4edb86eeb9d6b6b374d51cfb22df38555244518aab32e6247582845aeb82a8a57c77956a36806aa310e1084cd6a4ca861d4383968d90c6a49f98fd8c35f50e39bc0c7e4643e385b9cb165b3330bd86f06ae3182c6cfa9db4164703c40dc5bc73bc63dd53b9b0127d51270d6e2cb47e729c4c61e6743c70cbe074a40819d9a5cccfdeb3803e5c70088e1baf0dabd4bd66b34b4015f3c1a590cbd461a71f7ccc95051e623fe831ab2aceeb028d38da9bb8e8256e74f8d6af2dc6e95813214740bbc61c0d7e725de04c565a0181a5216183eef0dc92719f0001bf9cf5d7b0fcee822f6d8b32107e0b1cc0aaf8fcc6203cd48c5a9328fad74f82b139deeb0b01e9d1955ea1ffc5fa1579756d813fd22637986758d91b703510fe8d9d522f76edfb90ae3d322b9fbf5d5e75ee58ff9b79559c1319322e5cd8f88d2932575cc720dcc873616e28cbe5d20324ff3cf64f274388885a9070d6f73cd2efbae3b29c006131658ebdb49e14e1ecf24c77694ca8c50026896af4fbe908e9841a777c0261613339e75b8a034bec23b45424dbbf89e15c761a8219b5bebaad083531ea640ab031fcdc1eba622301a919bfe907ce3b9450903333def5022f13e33e87a89c12147199a263f59932e8f6142bcc8cb51fef3b8cbb0cca06494ef94dfa49b4ef0154369589c3d8948108ec887d62e2626b545d3375aa1eb552bc04603f136bf47c6176c42c81024f04a7ce0fce747fbf4b76697972e12b60acbcea7b43885b1aebb4c19839099b2a977aa3f4aa32c27a839b1e801fbf6113f94b6bd2b77428d4efb4bd8617e8c0fa8e05d3b1ce54cdcceb1d8799472389094feb0b4f7124aba95cb0cf970f3ba9f7011e0ff115f04cb4a6d37ccb8d2785276c3f24b1a9afb92b6546f44725d1541850ae5ddf58460b6c2a02ed94178b706112b12e0ed2f0abe30fd30d9129424203e1233289b10370478381cf1f088fb2472b097ac70b9c405f8ba220bdc5a8c501b2aee8a6fda415682c06b3b3d027a46006b1604c0a780f45c36c5792e55c1309fbf26ad619eec3efc8399e618ac9806cca0d7bb88dc4a88342101de4363aaff9ff8ea85939f34465bf7900aa4774b24325130ab183f58bb36ede6642932f247bd2e382b7836c03270d8c1ddfe6eb12e90e6cf7a84c0100c62c1e1270c0dbaa15924a4e10c6525511d7f16fc6708b0a6bd9a0405ec6f21b971c05e38b16d662a486e062862ce56effb3dc4370efeb7e0e31604a1f1b12b76b421de885c282eaa5f5d125f273be52c5edbfbc248ae0e13253ae3285aec87e5eee5d91b1b78d2b5215658be5e10c7a124ac6e30146ee88d844a7875fa1162650a52024a5afb1fb5a278b99b03df4d2d010ad7b1d670c8f28dedbe4be87eb4682650f5e63c9f3ae4909ef2f6c88b2604583dd366d8000670105c3be0b119c17bd7ae7db9c569c34b455232bdcd1ad65db6def6e605049d11b5fb597f45a1dc2f173a96b0b1ecda1736c13a516355816c95506e387aa8d79351478e94ade363ed5d4d5a2b4989e1af8d578b932f826bcfa5c4206b5971c9e77131050800025e15b3eb2be5cb1f511f2b16274882a481b13d85827e46aeed120a90d58c36f2892bae716ec741e66ad4b8850cc258a147f7bcf4255b18abbd60772dc0fe909a55272225ab690df2c75dc100a6c456d8ae1705e7ff4a69fd106e50f148f7fc7fe4446a982ebeaa580b07807305b00789e38dc68ca5c8da3f52ee9d92dbd468e157899140e654e502cb742af1f31577b76ecd30893bd08c6373aea343896364a1eef94ab79c00773a855e848cf6dd8adaa2d0982e2c9d91595d1986df402903cbd01774306432752bd2eb80742b4b92a7f5fd9d7bb358a5d3d08d38f98aa0128bc914cb7135cbc6cd3d218d19077a9b6f270be8452ce58551d79f206aafbffea74ba3c72d82660ae14d37ccf71e796619f248cc2864759e2f9720960b6b2918706a1b8cb4d72d7294f91499d23f794dc52836444831f69ed921becc6a65ae36f0376cdf22f251f1addf39879e47cabf53ac5dd34f32ba7f9076778704f3fbc6b0485fcbd022d4173efdbc5d9497d42d370d9d9f9bf9e1fbfe037adb997eef80ae2ad0bc0d34fa9dba87a23143390b02d513174106e9fa07cdceaf75e22dc0d44e89844d2558f397e2014e66e24dba57dc09664102c92da95cda239b5a981234f6305c164c8f6e711102ca4c5fd76cb4947e896913c169d98380fecaa33229ef0bc9737c0635fd93b9a7c104e1e54a86693ec567606ae8a918db1748e72705d1f9954af9ecc7cfe40d755b77030fd7deb67d6ab6ed95b6e7b7fbd5565dc7a4dd3681106d7f1008ccdf7a3af052b2fa594399a14647a9a53325fe3677da4c157320d85d5913c20fcbcecb823d9e60869f642298f0f8878aa10a2dd7cd5c9bdf60951c2ca331ad77bdb4e1c79daa1f7b33008068d1938ce7760804b54a38731364de9d45082aad816ed4bec8924dad5cf0e00d16405248bc09ce590b3d6818b2ff5220024285bee6e2d8f6b0c7aa9a837dcc8f926e09825cf5427b013eadaa823eea9d31269542c61f344bb1c606e1624e09553225e4564ca80325048c70cb38af521d8707a723faee0469c6516c56c24a4309b83210f80e00f8d153c53d3a18a8400f9402348875a548a92a05b052da260eb6702aed8e2be40466222019bfd585e9e94c32bdad487d426c8947f6db2b60fba0e22319cf0fec4d05be78555abb9861648cef8bae2f58895a5f7a9a1d14c38d4a8def5fd4850dc3c267c013cf31da5b9d4132cf8da93d1c14fe3253f614d2543408f137d73c141fa083629ecf05a03672c8212d4f3129cdb0652f24030d99ab0644c18c24124c53e8574dcb36d433918bafdd59da5b250d14db97c0e5d50c200950273f02297a4199142cac65d8da18e846c7e61be8eefb2360b67934383b81dc9f8b68b935a09a9f91e5fc0b43f96a97d67bc71fc883e998d8497e4ba5e1d9de8197101410642f2769ce08c7f445c88cdbf3ca3f26ceabba1af6abddcb1fcbe3b29bd40d3cae926d8e5324ad70d9f63ee508365d0d2067d3d45a55bd58bb1b955dfb23289da0e684d2690381a87dc2abc1be33ff32efb738b76fdf70315958015e2461dfa90fdcfdc7e59da840b0be5f26f3c789d09d60ef93f18703e54eac86075a6eee64cf49ca3e977081f9707711a96f33bfcb42e09cb340b0999d1998cbf2b251cbfe0f9ac977ee4a3e8a8884d634f35f18559b03f0f7a65ac8de241d6c3de80cb5f9c8c652bf1939151eb4bd91357d25fc31059406b884461a8d7030066e45b3805163cb4fac61dda176d6203180e9bfa4b2f9990454c92ac4ce82885e808a60ff2850f4e181f17ad6dcc82900bdc9356d4753d9a0481bcaa2329295e05cf0e8834f09f480aa0ed42ab6ecf4078c92ef623a9d38e9ce846b109c7426287d832e29e66121451a0ea1ca9974f4eaf216718dc5bc855f608002850b513d5e0983b8d2b388c59772948520b7fde56690c66015d8ed9ccc061978a0a5ae88a1aba0348aa5da98d8ca68d074f1798735d13f4fb14f9032b8e95580c410883d4cd087ab0a5f272905a07d6e7191295f49a14a3e87c94b86a3e4a1120ecaf72ac287272b5011b17455a5843d1a5fe18fbf585c489ae7389b9d4f64170735add806980c31b0422d03329faa097d85e5b8f95b6081af512f0615766d90937fff9fbb342180bdde34997ad7c275993a41660be04ce388a7351fee14d8d94383cb125ba257997a05972de67d633f062758e5d6ca02f923ec12004206bad5762538ab45da29f3d71c8a6b58c36a9afc824bc1583e4b9d04d2451632ae02fba62e056e8d6267daa1850e999bafaf699a3baa01030e7e17d26dd1e1d4b90fca914949e4530f36a32c48754382b02af18c601b1f8b5d8f20dd26213215f0b3457bb0c3abc7000a89360f25d0891bd6c9ce1f34b541945389d1205cdf81250062926e64702518f4d50a87b5c0f7c153fc4e6b2de0f70341aeea83345b0ea2b18ee21d427a71048f43e67fde21b881a3bb62e5343ac4bf5942491bcb638080fff4e5ef2e209aafd031c0b4abe34cd96f040b45c6231a20ccc25f2015ad208b3973e3e0d0a45134675d8877f74318135df48bd4b51691c524bc61f4b45f3f4662aa21c2415fb81f6ca8aa52a4c91fc12fe6c8e43ea8db615e6e340009705d7a61c0190abb102eb55d3bf054bef3371be79b1466d8e788e567cd5838817d83daa0774178f4391224d662fcf081e267d669a8b788aeb013a0b5cdbc82261760add291c42b16e4e500966c1e0f7a03b0f58af0b61ebc4e77808c5af4c68c41cd56c27f11cddac3959be3f8248ca0061d3d8ea36b957e3da81793afa4e29b3d170ac70099f40ce880dd7a8080f085b1f368f1da0a076b838f36413d9e5218fdf6f7532d771c3e4d8e90e6f06c7031e9be8585c3fac41a6029599d80419dd5b893d64f2a88c19ccaf4531ce13b33d060fb6d9fc07a0406d864dc08eb6a01f64a68b9f2f51458fe50d4411858f59e441fbe1cc2d68b8928a57579c858933e51bc717349a1be842ee5488c2899588154b58ba75a95a42b265633b1252996606e2d3fc4a81cec6976ca3cd5968f88af28fe2d6135a6734997806dbe338a497bab83f064c17385da75007986ab1462bd380eaa515b8260a5be49e000d5f5fa5003fae4803a4d08a015940e7fa16be740e3601d7f61bf8a2f8cd07ac89acdf67b7468c0136f50ad8947a62b7a5ffdd35e001be051b087f470e34da30b3b7c5823942882e4f7ccc74bbb086b22eacd4cdfc13d551580a365e51b835065261429458d06fd8fab8b1b5ea360f76c5114af3323ba1fe2a1458504a8532aa00ae431ff3ca5b0cfd42e4fc85809f20d4eed0c7f05bc019cdebb0bc15ece85e1f3d5d5508827df7ab1a8eb9ed27a2ed3f7f355f45420df5e73fa393a7148f6a40e625cccebf5c4ce22098920bd14692b218c844017f8438a8378c8ab10ad18dfbd76df58c56d0f33ce90618599781f8bc53ee897788d210cfb2fe286df55b15690347073727ff544134914269bffc1919ef2319f02362289c00cdc1c91b564a4bf4122245c9b5b3ff21056898bd556ea13221bccd545d2c811e5d8e27b9240c8cd08c86eb65df9fdbc9aa878024443c861a2d348a36c63841947c016de714326cb4a12cf811c9cefe4de0dc4642d8d6699a37fe88e961bf03af88c264116a43c41278d5f98fbbc984fa4dcb876ef3cf2086aa2ec811e1e9e106591de45fa09e6c82d483ab739882616fbd23314e7f7ac73df0e86b6768f47597c76eea13517828eb09a5b4ce5829a73aedbdd7b0024e4f1741299453823121dca3ed66fe24a577c21c027421a35db30b302e4e50704f7ed22306e5787d12db50ed0ab88b8de663b80b44ebc199bdbcdaf86e7daa5bad4489d1d2aba53498b4267ff1ec9cb60906f6a54491d0533d7a0b602fb5a00420ad1805355eb5d7c9bc7b975b9abcfb0688df3acd848a37962b39bce80391564cf8acea654801853ad55d0e9a35e83be6adcf1f7b2b8ee4efd348b08e407fc7fd8bed2afa0fec8c5e6f88c9fe5255d2ed0b090d33a718684d7102fcee45df4e80d3a79e1350e495d2393a4fd121e7d608df71e606bf59a5402aaf786e127e0483f0ca9ed099ca967fe9b65aa27bb1ddf18d2ccd02580d62b2e2a7cb6c59ee502cbee7201a018ab9e0809d21a30d9077b22bd2fa7b87e583a9b10ca244419c98ace225b7f0dfdee5cbec03d89879d7af8c814f9479e01dde25259f87d8a38107b19ce427b2cc03b438927251dc0dcdbedf3264a89f4723ef8280639905af863e04d0e48762628c1ce2eca39a97e7aa7810c42befff4ceedc203a8f1c2ea818b87f056496b0087d94d2ab89c72dc3686f6c1fb7f0e13c96c129483660e142bcab5bcf671bee90b3ed95d4ecacbcd967d635f2e5311ff2c12437955030670318370801a2cd1879070530194cfa4c8a214a0d372af60144eaf90f5b16f61463124e0853396c211f73703232f54113b9b5c537c00028b6beffe1de27d9c77463d7815e04fdf07e80bd2c8b490ecbb05f9616a0d164dd66f8024aded6b97b100c4eab7f10674bbc6699d5326dfced3a8972a43dc9f0428d00d56aca91b349b64dc4f942fa0b18d04ebd6b58ea26a0786a6371883d66821b995bfb94751d88fa70700b9b908798fb93828ad4825a6a477137c218c53cafade1c24fa68a320e863b6e58af3669d914dbfb18a4ad5e1108f27d173a3a131e2a00a017044be7a8515670241fb1d4a258addf698cd74e6f72da771363b0e88b4ddc64e0bdbd192e16a7cf58738410e434e821e8510b17de267581150619e8e59c6d421b798dd7385aac61692d23e7b22b5c74852fe59af38f9fa4872867de534533bcd8d612a5755b4b44a65fc51528aa1fabf076444d92084bac2d05c0ff1669feffa326069ff3e178d951d87d8a6dcf93f4982b8e382842b3f6ab34d155b44d3eb91ee5d4cf802ff25292f6ed22d229d4c54e8f47c74c0664fdb5d64e9ba0cdd9ffea4f233296377bad104ef191f710a4f7645b9f8e2e908ed871c737e519d6147a20a44e287b4e8177014b734103e12c1f34ba4a0f997337a9c0ec4989dff7f11efb4ce1ee68c5dbe0269133c118230f9c198ca558c8830665c22951d3bc8dff37a1d767312a181825ae221b0f5e192ad1f13835306e84fb055d209ba8a769c7a8a8d91326b869dec9b20bea154fd370e1e490c16adf6236611dba398234130824cd71a30b4bb347942fa31a4e10635a447b9668c59252288f557818825a8e7844633218c435ec350f5d31eccd27f254d88ef1fc66fb297779309e815b09efc89ae0c8861c95f087863318f9b30a0950084bc201d1588a8cbc116104451408428118320de4a414b23258d055b87a331d9039a050c3d1dbffe319d8692b220d0be8facefef82b57fc173270b3625edf0b00a2456367c9071e8e9895f8359e3363c011e8a5075076b1f43a7ee5a6ae84c4a9a563d62db75af0ea10909f950e43132717b0c2e437ac50da0b1fed7f183eee49e55d2f0f448e5a00e44d194023e81a5838e6802f758e74532e28f7da43dabe92b9773ee64efee38df188885a52a9558aa8dc42163d46b1000ba87472e9e61d8fb4619c5ba96aac16f4c4df731260b8ff0988effaed3d06ebd10b3862a3fe5a7ba57ade0b93ecde13f39901b71948f98579b487a1079321494fe42f47bca7a6b178619fc55ad1294150b3c2de93560b5c711a1d81b44d752046d1ee314c3520e31606983a46adc7749e06a6a760a353bcb8775bde2ecff511daf85dc3267af07dc73963db5a89b9dfd892b98001cb5b9d51810e5100a3bf72392587ad3f389c8e470f2479911d42aa6dbd605504e522401120eef5e716656d3e66b83cd54ba0ce07142d0f1c97abc8c435d72de48c0a1f1d5170cf5cc9afc7ecf346f0992ab61c173d0873cc9a1304b834176e824b68153d56b3bd4f333c78ae26a9bb41658d77cae8cf09bf56d726d1a07df16d3a92f1798540e6606b23609f803413d403f6aaccb7edbf08bffbc16edcb571d6608d0ebd395b86d9a39bb26f150ee77a3a1e1c3f989b1b9be78fa705660ea1556aa3e152db91509d039756050161afd41bb4b18012a09cc20297bd97d2974f36dd27f0458565f3607ee192fc43274826147084eb79fdd5c2dba8de2a4f24b837b07a3c52ea74ad725fe9760bb9bc5d2093d39080dea92b8d8e0dfa4c15a0b271fcbb0d9364405d216ab7f07861f3e544a88e65c8d5a452b10705b9bf3333f637cc2667e1d89e873870265125f5e8660f26afc3231bf8fa8200b9e387e18bb0d51919300b7fe3d4cba25e38e20dcc3b4f095ae4270190bde45a51211206c1624f44180645ea29342f181a21b7521e815eb09cb1082ba453a51a27a511bd40858232e89de8f88393cba94dbb77adf1827b73de86a554ae8537dae61af57a82a8636daa6cef0cf19c04edd6001d95232af5df5b5cf25edcbcfc09a08f278458890b4d6a6f5328f73f91f0b3cff502f1850e9b207084f59486ad1c6ab1a9a36bd847f09e1d562e30c580681385a440508864afd9290b03088212480f737b3c14fac20d31b59f1dae9c50e301ea6cd9077e13f46d36acd1b1c3e3d782c1a750e71bd37ea66094f4871f142b2946bd1a0b4e7b40801b96b8fabd650929f40a7b10b7982ece6c566c6985bd845be6bbc2bdc844c04003b7e840cf46398ea9e8c863fcc3e8a33716bc863add63cfb753dbf1da4551a704bf526ad5148db191e348ad737b15c44fcd80a65321c671f08c1a5a617d6750e05e3a2eb075a1f5cc24462cd13f11678afcac86aa523095b8f5855961cb8f2e1172e0ec7664cdb5ddcf07759b1757008b13961358c0e191db77d1f1b6c1e787fe9336fbee3e74977fbe740de5ecbcc3130aab8fd24314cca984658d12551afc260256fcadb4d790dd9ce68ad124d8d479e802060510cbe2785d520ff87b770a5efc0c1a5f338ff32c0ffdd6e6e8ee4ca0ffda9ee35fa3117f0ce7cdada323a824466af58e494103cd2a22a6daedc9c5341abad37dddc4ea0ba626b0f4f2558d1a6d4b2c86b856d373e741d1d120744e3aaddbadb9955c41c7f58b31edfcc61b4a258d36695d75488dbb47e85bb1bf520d55a60a16c79c3ceabc4e782a91e72dea496138c4140d2cb562da741c34bc8350a0f106ece16101fa593884adf51bda6f7bbe79c1ba4ca697f0373443b71c5607628a41d041611eb7879f9f52eb7e976eab16bcb40a7c2bd4853571a87cd66cb6ff39d37a4481ef2d47f5d0c153487b7898d882325f3fdb075985495a7ee1cedb768cd09aa3206a8604e67a5a3f292e6525baee4aa201e934760815f95e6451967e2c9e7bed1aa272c04da422ae233b510371c0de836a66780028ba2dad60dbf634c67547cbe06fc9f62377ffb8895b51aa98df42f9615094680053c60287da0d445e8e23077e94122d6189f217bd47003b3a68ad906cdb35f8ae58959026abf14f7fce489f7e5d739a4437210d716ea377bd43ad2419f023eda4809812f5f4046c024115511a500fbf9ce552d20cb6fa77f67b33e8461136f11b31da156c9f000c8aca37a06a2c7df43c71d607ba5d4db33b0271386976bf4e487a129e8a2d19f4fc866512207d789b47e983347786a278d544cab4d094fa66b1e7a93c30a37683e7307899b8f08ad1c3596a921e7c5308ff7b51dba094e6c8b22364a4c037e5978beaf0e5f4646f8cd9917af5cea29f3132a915266f10b1aab2dd1dea556f437145af0eba60e9b3dc190fbf41978088471ffa6e84c64c46018894315933bdcee474c3fc0c3b1d81fc140c75d041f0ca361ef1e163eb1c826517d9a43c8731458f8bc47b45050fb90838572c09eed612a6c4172ca6f03d9facd0b2b8b27c227aac59f1f8c45e9399c0b29b3cf323e101ec41c1938cbed58e3c51890aeb166bb83a2cdc1d889b01f569827eff38bb93db16d942e690a7210d38b0072ca0e37e96c0a2bdae85550bb7d16228c5e2e88f8a71d35ec0c196f46fd8ee7a9800e79f44a8a9263485a7c0f1e688140460813ae0a2116719e4d2cb0b6da83e2b9dc9ea833026dcf67674452bf6aae334500f5a30843729b340f31d6e614152a4a18c03c7a7ea9b8bb5f32dc817ca105713a90e31b42fbb0ed014c06835837189ff72031b10555bc575f297bf7e66fb984d1c93ad796493b4961e9393b5d2d4320f85cfca01799e7c76c0785c406add50f15e328c7909b8fd2b8f3f8d58e04337a07638eb3db7f01e70f00008028e2f5367ea23f236a31d85a602fe0a02eaec593b5700c39eb12a138e4262d37ce06c8755ae88b657fc084880f8b195c8610c911ab14444301d794a99cb11aa4a2eb90def070bc2c25427b1e8706c0a397c7973602d3b6b06359d6e704ce029f0cb0b920951de901329539a9607a9edc1928f5e67db870a901a497dbd87a5ab0187541822b46386343e81dd50a60bff83ea101e9c8374304c6a721568d6a6600f299041ba91a04efb848a5895adabd6a74101bb21272784c8a30f33c833ec99146433639d507e2ffb81084dc3708e09b7c93a013cfbb636247cd5641cab8ab75f38b9d651c7d03f0340a3ca06f18bc5303a2d7006192c098d6fc1e40edb846f2ad1b7b61b9dae53b23e02656bd39d002f46fd52153ae86b54059bb6f878398ebfde6c8be70567102215e582613b2a3212082e2793480bb9a8926f90135bfd978a251e6ec857686c9a0a8611b59e0eb250f5b7c308e68e20cdbb873f6c6a5db8d4c37b1d4c5ddbd8f1a964a2b77b1722df9b0e90b7c61074f87ead9bcb281d5c9980406fd1327ab20673bdc1d2f1c7e58d9e51513ea23f28aa9235ca9a6361288c6e3213c3c9f1b4787ab91b9a97c1f54b089bc9536042eebec9ae9e343a5d00d59c3410f2248860b6e432121eb5cdde68fa0da90c85c91317e8c97e09c5574bda6aa3de9ea78b174800458935842b271f1b2bf9ebf78e70df2f01047cb16735c16b51d629d626367eb80ba31bf247a9a586faeae4c72a58e3ee9b14f1f9f59e633ac25873f5027aaa6c3dfc9b4c2d0a01494493d7d71fd4bc8923d84237999c8b137a28e0d443f2465cd2f509e28c02ba1e1736a6ebfb26796d8cb9537653b0f71dfebcae825179c352e04286924083f6e0342cfaa10369c0fed7a9f6b5d1b85c520bc17fc1dfd7b6f19e01328cfe33a1524eb7769bc48a19c90123da8119ef5a9ba54239483e8e04dda18ed38675164a2674b174f8d80ca5e158fbbaa6e8d4166b732b1670833c4835abbde657e8d366b7ed2063bac598a64253ee0890e84ca074d233dc8843c87dec5a5a31c3b29649a6bcf75f92bc1db6320e281b5608a5217718f3361293c68b2cbd9ae24643704d78e210fc6beba7f94c92788aa943d418ac7215d0421b4716204644e57ffd099c4ff892ed6e3abee84429c2bfaf4c12ab170dec3a932ca8cc3d20c3f35ec4c50e30d2b6cdb977c0f23af2e497ddde0ac31d5ad909ddbff3c7274885c68ec1c4805834c70a250d69bfa6676788c328448bed3170ba681a745f9872468be888f9731879eeb9684d82e6f23e0f449528ac828b83400dc1c0f138948e93793383472ff89ead3a908db8caef5392004613faddfd604a8657c31fedbce34066546a6ee2d8b64a66542196aefe2d7236ea41eaa6e4cd49880f00fa555943d09138d7122e318e25f77bd29dd6f1da0305cb5664e8e09e8a3a7241bf6572399d05adfadfbd22010b29677c30db53f60547014053f4116059dda96a6d5133a0d37ec6dcb1fc18f5905ff7f82eeeb2a9983a8735210d0cc3be3d19e17a543c31f2911f3f915e8285540d8004e8fd5b9f14c7458b35b9409aa005e61f04503f90d59591e2e737e3043cfe9cf7b8a02c61e228c80b71b88d7e590733ce25f38c44ba3dc4d223b3be22c9b5857ffcbc15395e74879fd603b3ab14745d74a7260bc78c30cee9e0e6694e7e0213deeb7b8c812187ad44e1d3a9bcdddfb509c604a2e957b122fd08aaef1c5f0f2efdaacce0e7b353f6e9671193193c1f64fd2e0da0f6e3075d6ee31bedd7b670d6ca8ec1f9a563300f8db8ece3faee1d1f94867b364e0bf0f2310ac137859e80989729a360d7a7dbbbb2b7e5cede627b296aeaeba9b3fa4b379cb5d4476b403001cd4fbcab99b2b78bb6f5ce05084457c91040b837b7e9a684906b8606d39b35f8f0327720b6e49c095e322978e756466630b1de94325724fd53caba7aed2d9a3dd5bc377910925fd0882e62d30e74e90704c8ef0dd0d3e27db16c3b583b4a3beafef563898e86182169eab7251e077edd5ba525cee6e763360c174677cb34ea125d6cbcda0c424c8b735defec7b86e1c7f6bd53e1787793016b1a22c270b7856da9a3b33d84673a87e0046e910104086b12b581f80c00fc00541190b967151fb4b4e6886c93abc531a38c15852e40f3c3f99c1712bd665b9bb752e81df4ae160251592bce515ec2082a1c8407a81039d656dbdb2d19a696d90fef8b478d0ce2068317ff9db22aab09586b0e88c1e2e32978c0c25f0d4bcd1d7ab4614a6b195cb91642cbc943e18a0f4e849615679e3baac05fa584a9dae72da7f545094f6b80d263719d034bb5a5a1545f3547e44deaf449fe325e3d8deb08ed80f058b3dff6ae85ad46230d8cb82671814f40bd35761a00ced66bebf33b70fe11b1dc20b25b3c285c6f66f5b840c002dbe3b8eb05f7a6a1a0fab6580816150bd8fd8edb96a33d338074d015b42c13a3c240cf19078d3fbfc7f68209564f767dc2eace636cfe4008d1f22d2b2c889ad846dfd32da9f5e2606ee86b54fb39a05695bfacd81abedfa919b600bcaede581c9b49f7387c8e65ea5675440dccb98f136b34fa5661b41730ff89c98d06f8737b64623953ab2bf4e4cec419a8cad2588f084eca713103bb02cb81f268ed343dc7666e78b50c5aace070b80e1fb6bb15329100d0fbc4540bdc0681cf5e8869cc7498291c0ce58eb180b5f94880bd2946322773cb15a006e58cac03bba9eae5ade3ec5363547b59da41b38741a70d94d6d887bca98e7622242c14dbfbd0cb89387f26a407ad27c82e907c3a333c12010681f195e9e6a84478b04bd094e1555b448bbaf6189023710cba82165ecc6303e5f725ca92009237d1ca09fd85d794094790e2e609c045e2db4e209a8210231fc67f9ab2f2d5578563356fbaed603e09d1ac57c919a1f756dc671148c19ea5da30f8503262e256f1ff96594469a08e8fd5cc5d4d96f0bfbf443df9bcb3f69ff36defc58913a1b9dfc55e294c0ff227c4a4cb463acd91261a69d79ef8b48149dbd7a9f243bf44cce3bc3f1e74b67e28a9b49ee7c4599f347a0143b74459544379d3e383cdaac5978c06682c25d260f35be62e25b2ad183df0ca2caee69852bac9a617289b4013d490065a822e83a872cfcb509d52b1172e1925f06274964fbfad5bded804040497db6bd7e2cf975a1676be0f180f041f97e158c14251c3773fa1e8bcb14182e0faa4ed7a3d158dda7de3e83ab3ba291211549361567470d335f0eb4d04dd59811cf6c29c18931ee6d3e52458eeab5f7b58663b05e6d835a240b8eb6e2238d009ba7c67156f9dd2842d36b566139db447c240195273a8834190be92df25ba04f66b32c2af393b1028248bdb367c69ca42c5971bd04ca02a63e3dbb7dd5438d4561086853089e531c01a20f345f7ab27582b0125617df8613c958a4ece6148300281bcdd4ad4cd54832b66270d630fdd388fb33f83302ead1d7567836dd18de928d5f9e7e07d92c4232e6ba669e20f714e27b11a51e2db1368ba5b8c8a4ce41b6277e98e382549a262bf84d4a2bf8b5ba94bcf8342a1a307eb6dab855e9f23859d3d4290ee2f4d97d56aa2a4dc83ec43bf200613270198c924ef62fbbcd3d84d458d9789a0772da808643ee0ebe43590e2be19a850e55a559ea0dfeb6240e679ff3409d49da3855be5618b65c913e96349f54e44864af14e2e9d95d568be58d1441807d45dbc02e5c615c8c66f7176092dff94a1941b833c6ce071ca70c8bdeddc8bf242f1999241f5985248a0bc559db7aa30ea8495f0b58ff1eacc1eb492681dae1c9801f39c8a6bbdcbd6576a009586e9765b40d61d460b594ad94939e89691101511396ac4a7f781fe2bb46b4fff20afe1501244782911fc55012792f4b99c00b46d9b44587f9732e455959cde1967d69aa6b25466ff42949e31ce1149da13555789ea31953dffff28571a748a32486c6ad9d2556199b66c5e522b9d9f78e346028eed29d84fbd0c483333db167f0a5ebd9684c8439208819b29b243f153d0145bd872942cd077533a82ae7af69d0662fa3992b475f7846b52e596ca44721f4b675c0fbfcb093ffeb2a5d1a7bdebe49f57de01849215b0fd6d4d302e0014aad0d80026060292c2f95255eb1024666cfee5e1cedd5ea855ece52b9ce24bcc0bd0617debfb4a5f4c63b7690c002072d3b50c81577b94fbae3c61dc642a445a8d1dcca3446586105f896ae4c39ca70a3455ffa924cd0f365ca4c495a998009628274be236baf7eb12c75657ec1ca30d4f82f95257cb29505aa67ef9f4a3984d38320660bda2b03f3c789d7e100438902953eba0fc441fc548ac34baf9c8366a616bd2a8dc6ad632b7079983d3d532efdcaefda60378819ca7291ebc703765caf63eea88153ebb622319fab9455e2f79fc34788a88ba3cb0f42c95d76ff402e1119a308e8fe442987febdac0562c56c759126a153b6e733a7434490f8243cd38e11282247d58156af416c6de81cb15d2b8e4309d6b84d945b1c31274009a64dd8282be032ee49569b20a703404845ea6f91a19372c2c4eea12cc6f7d4e2c364901c583c3f2cd935eeb09f02f4bd04b3e9551ee257bb20ce3956b71146a539041f03c6c58e8bb47e5f9f4f43c8772702074ef9e6cfea60ef3112b6893c58b015c4beb79b7d8e2cca05fc97fed126fc28e11fb2a692c10861a4409d6a733098310f04829dae620ea37e64c01e823bab9ffa8b78622402ddd6217d18362eaf670238c2c0d229acc340de8d1d2ca352d88ecb576cf3e8382f72dd699ba3574723e0d18e0325754b15cbb6ba0baeaca33cc29e30507d03f3887f26d8b24225761960a51bc8281453253a1ca8fa75eb07be7f2e4fea0f9135147b7767b2934425ceb35181ace1ed88bdba4e0581032ae60d626af9c3cdaa39aea9c0a70c5ed7343cff7033523038a906e25539fddad011d4d06b093a613f808fee6b3b4804cd8086e1a45163bb84e516e5720f48a11a22fe97a8aef03f38b88064f18b34237273d9397f8f432e33187e62c068af7a35b6c109e221305231a325dba6489ebb36eca130f6c070b758e37a561ca125b05c310463a4f50e1962759905a4035a9f31d19cbddc7ecb734be4ec2a897641a541891f227202a5e979899bd6350ea97836eb526231f318ca9d3cd8eb78129d752be5f31c5d7b3458ceec3977db2d793d4081538bb9569764b7116384e31eba692d5e7f5faf071dfa0af256fc513ac56bd28c2b1a944b67b56a1e3473e0f5fd605528cd818715070fa7831e75c6e544b0d6c2c8b90b7b3ee522a4cefbd1eb4e841e81966c30cf0c88319a7165bf58d90975eb31c48055f0f425a1b3d024ca29f984af8546230fa9f89a20654aadae0ff997054e042c15728a6a2a00e0f673e8335cdfb040499b87ff8e9837f810d3d6085aa83611d05eec1cbc4b0b47a3b6f0ad11b9a0943b86b10883b4ed2659f43b13421565f72015bfccd9cf5a1d3ca137c43fc926439395a83fd9b51fcbe313e9049c7b4509605c129461c962cec9d7f9bf7dee7e6695cd75954f14b737dbeda412980cac25d411d5a5c7da81bdd5cba3648f2d6250d9c76da6a1e30003bc908338fa2e909b401e5ac70d2ed82b7898807968e6f985f9cb84626a44242a162417e8446c5097c904370a3971353bbc7ab4717dbc452660c5239ba7c8ad4f295e41b106efa8f3227dfdd2f3c4aec9fbcaa5ddfbbc8aa0dd9560aef413c2748e28a13e40c3ae665774b45efd3654c96e2101666dc85d8341501c5719ad29a393669816a2acba9aa1882490a970692fff683293b748e212ea6116321d798ca4784fa2d0d40f97ddc8aa1d22cd20e11d050874e4444342e0fa4bb1b624463134c2ccdec8348591074728da088f00d79765e1eb9aa3b3c3f41ea1b38f1cdaf17309fb8aea391047b5ae7a122c809f1d603e78be3d0cbceb368811c2b5f0010d51621738badbbc08b1d9c74d7a4f6fba0ee63de8f0324bc2331eb147506b77cf5c13af2125ec676bb5c7d68d24e18226372e5c601a1cbbd3aaad3319475aa764431c0ec3f9c3e03b2289bf501cfebb028352f13a06fac4affd1c51a2b3098547278105e2eef35fe89060c542c4743f71ee66d8dd8d24dcb157d8b1ae4727a1ce7cd09844f9da0249c2ef9e27a10b7dd8c64c8daf8b98a691c592d3b03d98a35dc0e14568c24ecebd8976b5ec4731b3a55cc837cb1cfe4c3e550a080b957914741329206d912ee54909840cea93e6b990bee1a5960f2f920c83e63c694d2c5df53eb001cba457c85b54e214cd8612ff6d6434673ea8097ba7a44b79831ef45cd41f19d0bb128f78ecfa0b45712e68ce90ecba60d800eb9debb2404c579d86f95081830872890ff4e871e490901ef45231ee9651cbc4f5faa787365daca9bf168688f8007c8caaa40cd9d8b2a8588a49f189acef093c5cd7e98322666617a54a3b35469abdd4ad3a1078eaebbb4224bb9ab35800bc2f5af33feb2394bf870f5ec5d56dd45f101ca3843f79a6f3e298cd285b708ea4aba51c1049d01bdb4a50d1c8c481b363f647a0a6bb192ffd982a59932a209a43f3ad12e92e4d2b6006bc080c97a4cdb0a5fbf254e3e6c5d2e5e6e904ef6a8551dfe81a557287074e102bc09e578bf4ed478c59de07324baf88c60f925576c3894dca88de96ef03532a21ddb86ca3bf88ed809e9d51221da309cb2eecf7cef91194bd46fb0808d144a2e606a41f12f1aff2737586503961d6cecf490dd15f50af18834a2832336a8745d55eb8562333519a0699b8732b45cbb1d7dc926e59fd3cef2883c52d14049465c282e49ef651ef2122df77608438199ded4d02384384e048ff19df41ebecc342758fabf78619d7c506462f5801e2fc4e64ee259c7eac72a98b143ef06fe9062da4f9ed964473200a8e9b5b21456f5a70da45d4f1260648d2fd168c461145be6103297aa765a1a747916ed04092df6f59742a51851b999166775b10ed7a1471830624c88d164e971a75dcbc1d09bab185d0a2a2ce3765458a6e6fe1742b5150b8991d2976634bd12f4715972c142e7ff96d2d14ca5cfdd36850bf049f46d90e6c3b7106cc5c61db8acd2cd7bedda75dbb6e414975e03ac027701ec6fb4db9ba0a07c68d5e6022e27373bde5ac2b22d05ee31ff7f420e7c1752e075d1d04e230102d3b524c97e97510405741d0b3dff500212c9d06da7c53ff9c46b6799f9c34fb0da0b077a6f705d603af16db7904ac989e3adb7ccb0a0588fd993d09b014a46e7ccfada5726baadb75ced71b94c3dabe2ca59be6b1b6284f64a30f6130f1a4862e1bdef44e9971dd5be11d1aa807f45bec755dc8a77a1fe74aa5a2048a8cc2669c3cc6e2553dc6218beb2c16a72d438787c8cfaf69b6f5103d00f473cb7a34c5b033e8821da41395db2bfd0fd94de607b158cd9716ca6cca6642b0b4feda61871dce070cc63f88b39d217c35230afd874413e2b54490e4bc8ada683a1a79625816a22d11c4a233f66e42b3e54f7ef80a61152b5d0b5a683e4f3beb80b3d9b6edbd67335874f7b47383c4a213303788dea655ae39f7338ad7b83d9c013556fc00ab774253dff1acc2df31af29020327bb6de424d339b541d898aa7356dd846e23b8dd08ce9f3a47ee4d4ed7c8991789fc2f66450c3ceb64aca724c5b64931715e6bd59b54a39961cc8f8b14f95715663ac711a0c05ab738d2e8a8e82b87ef97e7fa9dbc3904744542625fab8ea78b156b3fe9de561ac16f968c52a5469e2e22430f6dae9abb92be2873a5e13d50404552278589d35a3c901ed1ef85a0c152c8b991391f977bf5ee4a6a2b3e0b1713baef40a56f5ad212ac7a701b98acf3975eff207d89477f50b7422608a9740564df8690043500ee8383b774c3ffdf7e25189cfc989d0e000266fbe57d8b1fbffc2a129dbafcb4195accb62ce540cbb7fd581d6165aebaffddbc5e80e96e7e64fbf7ebfc0f2ee726a6b8d284bbcbd26b365487f4cf1d05e4427260dbbd32b51e70481334a06dc94a0466fd12606b4aad972b35c55baa52b760a8b064dd41fa49d4f242e78fed6d1405ce45722569bd8f3cb08023b0f866e93ee01d04892b22e27516695b582ed19e1d804c82fb2ca6c31682fdbb54a858bea83231167750dae5f5fd0e977be879774b62d49e9bce2df52954b88c19bc075bd20a8ead98259d8f59c8838735afe4de3eb93a9e7fdeed425ba630cf91facd5ca6f6a7e01f92aca8a03f3ae9bfc06bda15fd370b963d9f8c107439021555ddbbf0b48b09d328388a85b6639181bdd310b95c1a6cfbaded746baac56d413a436ce40a0d741f560eadac3a6b0fee2b986931049b1b5f6605f91009885f0c92bcecb08d9fbb7d2e0a43d9dd19be1a42bb659d63b9d49c12273924067a6c3811916d323ade3cb2002d4f66a754dd3f261c10b110043d1d60f53a3724b07ffc65b514e59a54795f67b1d17e28049b306d007ce27f240a081f6e5ba1020986dd0b2a06d0f1d7086b73d9d81663b306dbf2148188803cbd51d8cd9c5361b417c0b4f2bfed1d00034df3a37b804da007cbc4cee6830bddc9fff0c2f8a0707faf0ada1e74aa7b19d9c3969bf5650b47631eb582edf67e79c0b4f7dde76a1be1c92a5f442b92f9a20a25a5d52bbede8820db2cf4f398be970b8d39a8b97f1b101a049409d01b3a71cf346cfef91008437504ab78a233f81785474025cd81dfeb1137cfedbce7677597a51954197d18a6921cd664572ee25d32020c2b07c67a0d0b6fb87fbc0402ed0b0470bf600f57c01ca388bbc0685a19cb472022def02f5f03fe66a5f51269b7c3c56ef08315e7738017f42991d66efb39102e1b74e765aab836117aab117c42bb172db312a64076ecd1406362292e6e97cc0636dfefbe25ec05e5af45084785db6a0f7b9b5cc758770cce367ee76f7d9e1a4ddd6c088c1f3b208828a5997c7db1808d7b3a1397097a47f4d44009f3bff006de961460f112e0d551002cbc418b108beb8561b0b9488f435742c6aa04147b6d8ef99cfcb5566ee442e1937df465de269c18372d6856bfc52b29eb3acb14938174481c3382006fa58184e2edc1b790addf92d3d3ceed06b98cedc398b43f0932376fe475ad03bbdb443bd530dd8f3b715dc13cc35161b04f572c0b9c65a64cd1a514a43ed5c507bab87afd56c8c172a29d99477c3f2ea457f7cb68f70c1ffe5df6ec0a6fc4312d819ec7d1220f084b471e99ff422ee02cff3e0403303279b832749dfd62161f7af73410a2ef2409d54baca169ead532c631ce21b03fe12164ae4b5510819cf011a25dcb395cb1a44ac0029ab5ee546aeae6c45c556f3ef473a8a13709f981f969dd42d3827bc815099dda3c15282a2a71812b031ba3aabebc7a2fb7442a8604eea8b5b8e1a7c50347a23252af7e557cecb9cf492821b0c3c28e3799952c5c91b3ff7bfc3e5357e8fcc44785bdd95a8fc975674b10e51990ed8f37fb9e2ebe08147d8f2eb0e74ed796e8482ee9e7490d371c4918e851f4f7476babf5d4f3c646b09376035ffa9ae1bcf392874a8815b46dd746ef8721527612f2b11a38e43f4120d6344d3a8ea05aeb026f5a20c74410f64b3505d1d62fc73d2396de316ae4a6227cc5f4f76bbb5a9e46eec050efb2280071c8a5ca6396e02510e0fb151e0b2f4d439b903a610387b393e316c07e8d734c70f5dd372ee9f58e9ab8cf186ef360049d82c1dcf21be27cfb8c7865d785a1f0de5fb4bde5213eec76f30f936850b9c1e0d752b7f5f66bfc8290d47f02689e8f0a5be6f85ae2c657bf80c7402c3a554c9f4a93320794255e293801d7b8ded6c4e6017b873340efaab0f7ad56bc94891c6f3f412672dcf69314651a503c069defded9738ff83d866947c5ae4c4fe1080548c2fdd6a51118eb9e84ce0010dec0b0a817567a7765f9b4f28e95e40a346a5be11a7e1f80a067f22de266f9d3252030d5c6f8a05f7c5187d97793a2469f1d467d6a1a5a4bdc2f5065646c6f10dd645c098fa4ddacdc0755bdb07d0c412f5df7c6621190f23f04a3734d565871239525e9220f8f6c879711d815ce7c8a8e40dff69ef62b96b347ddda1195b6fb9854015b7aa830af36947f5e60ed896f59fce0b117b7e75b58c83d41b0844addce2a3a1e6595056e4d99e68afd5abc468024f372fd5b123a3d13ca9363410830ad5e89979930f159a9a58b1d96687ecfcfe74f328cb29003a444708dac83575f158521aaaa2e161d7508248a40d5a37464bf5ee1ecbe1ab9f8aeb06e549c875b7d826fab3b4937e81da398c7e84a6c563c6cf280c0637845cd77317176e84218dc166e10aae6920d1620e09a0e88fb68e7d5ea87073bac93bb1d3b8f1fd200b100c4bc43f78ae9aef0d54780ba7a87130364053c6b993357d6842ef9fba681e83dc1fbea5a49736f9cd7de205127b2edc7e2980a79eb67b21dd82b91dc80f4742e911df89cb7a3cbdf0a476d9c01f4212f9b453cc2f774da0c0ed8fcaf1a2c117197696a4e601a7ddc31a74889e04f777ffef4e730738a7361c871ad677141974e005a9ee09886c02d449b28c7ea26689c9e55948334ed7eec32f590afab481b282473c58789d1a333e343146e0a5d6669747c2d40841f6a1812691002d904f74ad7871c1c1e7ef481c84798998178c109a4e3a4b88e23524abf37138696cc11f8f84f6100f7f9b4fac3f01e087f912b9757275e2e62927b676bc66d165b219347db9b9e872fad2a1658c1b42cd7ab9ed12f95600c4d69047ea80ff79b8c51ec76ee8afabf31fd03803eb81ef86eb8c2adcdfd26f271a414e7d7af600a4a77ab75936f72fa8bf735f7b847943ea5162371c67c55bcab0f2f45551970d5a553498d892f733b52ade5d1a204b01dda43a4735a04b9c7c9ade543409e2364774172f8b0c64ce50f0c778f6e90570ebeb1cfde1e61e7d4fa6030a42f3eeeb5f22442f8542eae3407a6d6a5a3461b942755705419d7cd7217bc8106570b56278c00e04b598b5cb0019386214cb792daaac06fbdf67411022cd44b83179fb2e077173f300bf14ba71c05c5f5c12d794b598fceab411c1e9d6000b85d072fe453e4ff520cd5702861b1afd1ca35e4acc209653b2b7fae3712dbf8c16853a3821a4fa1fba1089bd9159758cfafc168252b8471cb0da8a12af9af69fa1ba6da1126c0d14f9a020d6f05b28de356441c9e2d3319818fffa48bb5efd75c2dc508b8d39fe946e8fdb83b37dbe6eccd3f92146a304ac63129690e22178e5f1bb24493cf15778ef7c938d55a777cead4c1cd579753d0252e85a2d6056ef0cfd95b1900ab86b447214b7c55bcdc35e4da8b36bc3f0ddadbca0bfe0cd2138a422cca0cdc78ced35c9aad0b109394619ff2c799bcd8364a81e9f746af19579e1fa801d1a1343b6f9ed172e23269d54bcbaf61115073defe5f83000fcb96b9a5ef59b86bba2bbc7283140c63dbe24ca8f1e3ce418f7be8e6f0a0ddf3d15cff05e16a3989400c9289f468af2a131b660b6210559ef93494dda87912640c14486465357c6b21857b1f44cb3e430923e5d6992822b2a9ae85b22d2f571e00589b369915515c4964ec8d2c2d07d5a9a8cf8a0d9476bd8892594cad064390e92d9f8a6ad4601e3914698360107150a2e49e6d59ab05d8fe2394f7fa8224260012aad497918bf96e2a474a580b78cf84a803555bb597b06994f520c3a21eb64c874a1b510e200346a8807f86a5e85503139d6d938fe36575c98a264492ae2caf7f01dfd9a112e4a8c5549be02e9739d192a4e97f6c1c044e12843e0d5a2090ba9a0ea11192324c77fa04b8f9c6ad75b802461d4e34ce88c4150f27401a4c4801e9ec3f8d1aab3860ee462522c1dc950b95ea14c0da54b1bf54ed23af400da20f8db364a3726d44d1fbbf9fb490b677b7bdf7de52269902cd0cdf0c130d47848104982c59c8e82ab068114506133040034a0bbe2c6e7c01c6036afc10430d0d1d9210c2080a0c8ae042046658f1050f44844f4a5466bc005383fb29490d0bb0c6e3b1397d6bd10bfb19666178342206b7e318d665e98cc79f92fc80e9121aa594f2f8d0cf3c3d3e655815eea7244c70b6b34ad329bd10f753922578c3fd94c4059ccb1a44545454d4155c999cf1e575ed3ae8c2e6719c0fcbf406f5e0df5c20f38dbf29017f84504a394bbf67c0f42909e929a51b98edf25452e6d1bf1986bbc0464a4e28e125044e5b0c31c5154630e410c4194e96380a230698ebd8e07e421206dba8b17361a6ca105fd4a0929278e1a246d8c206173cc9b0822c59d0fa1b034f2e7c7952b2c6b4c1f37b667ba6673f1e9b9f5f787a61ad6b0c82611f1e8eec31630b8fedb04832866d6cad4e8973050ecc0516aa1a017609f6b187c115fdec638f8e8e4240cb8da5abdb7bc891767b7fc256dc4f485680392892709cb7d53bab78c273ffd14970b21cee272435eac56bd71b4739d2862eda3160228b0d59b62841e14403c060e2e405455491860b6855061d17b1f68b4408ece17e423245c6b957d143d213121d927480fba9053258c4fdd40219b0dc509405811faee0d05910f0818c978d410fabffab56ff8e5cdfc3a54285a04b18f5d48212ce303c9f42d00567190e9c79f09c65aa54ea2075ec1fc4b1833edb557ebd057606f7d3d1173ca3c05a7f8f73cc1c33c9348ff96940e1aea551c3d9a5c0fe20ee5a1a486097c2a19ac77c7f3af3241df3ef8ee50ff7fb6716ae2c08f8b0a456c6091ef2314213ab2002a6a202b82ba475fc9d8c6d9c2713fe313f17e1799b49f338325f08883a9630bde3efdebb1a96de29a677acc0fdf4020dd8d9984c34e69f6d1e4bfc59d6937ada3bb8efde7f32d199101af33a993699aca7e7bb4c1d47d22ee7bbd7b1d9c39f023d6b9aff68ad1a322803bb0e1ea23f718b246c983a3dea6a284343992462f0caf3c8c6df3d09e4c457b0f75d0da460eebb0769e8914e45573fc5e5fadf6fefea3e755f43b8ff9ee32e50f72e0ee9de738014db5da0d0cbeeb9a76209dcedfee28cf409c8fde83bbe065d70fdad0656e00e70d7da10028334e4c8c6e3f640f2c5f1f28662908f05811fa0dcf10271efbf7d382fd076bd06b0bde700b400b5cca3c6b2ad20ca0c52b400031830685be0eea1b34a6b160c91c30c56ae98218b2d68fdad01907ec3c02e2bcbf31286fd8765bd7c5dc1f4d51788e3fec60209173c5f88cf68cd9f480452184ac2ae43a61e0581738893844b47474747b4285d231305ce1d45e6069c3bcc18083c692221d0431309811e747c47f6c19ea70cbd450b1decef52581f204613d387c013285e36deee130e8772377b5d5910f8a18997edcda5343c05d8e97555a1e2faaf21930957ef1a991b708dc26e4fb9cf21a62bb0dc6fdc036d5fbde4c48ac515f794724fbf9b1b02d6ca7595eb8c74dc7795db6a6498e0ae75dbb2e3210e0550ac606609ea6939c942821e28dc1d86e9bb539c2965740982cd1cc0e66ed7d07778cf711cc5dce47ed6ca711cc771dc76432feb7b16dbb87ed8b0dab4460e48d5556053b86b6bd08073d766238dada1f4c21a2db800c3a2861a4a302c3507774d8d2d7806774d0d287096b5a0d63cb21e2b5e14f58a9e2c464960518230ae5001420c2ecca8e20927238a500285a905e2162a2c7ab27861096bab4458130154f57ac3195f024c514c1105c6941d8090800896f890e4021a9cd184152f8a7a454f169d349c90f400c5175bf800802db8c0610622d2b0010ca70d09d18a9e2ca5103118c1a466040d656896ce1a8c19a468a10224969260a0d56f27b87e6523085cabc0f54b2af31d8d7bb27821ee9a1a42e03ce23c6e434059ef471c1e947cfc1167a4b31ffa6ad8f0c28f90aef9988d578d19948c238fcc1371d7d44882b30caa2231b9cf3e447a7cf8cca3f56f648f8ca76716db353668c02cdcb5357ac061b430abb4fa38df3c26acece1f172cae82cf4d89cb2315d66f3e8e8e80809ad7e88eb8f3e6b5a6d2cb6710ee9a54d1288b08d6d70d7c680c115776d8c0c7086a180db2858bd3f6284e9bc40f4bdffa175fe1652ea98c3dc77f3cd538808730f9279fb0e0d297c8c15f8698005fb8f34a8617f1c87617f908a0aa038cf4f9142147317a802993fea831be90a7d05f6fb56c0f7dcfff814876cdbcf07a2ef7d27fea8a17575e28f8ee3b8edb99b81e86f0f447ffb29d2df48a0fa35f4d9a4f94f119c1c18b069d0040b00774dcc170cae1a36829eeff052f0c97d47e6116f95cec4d9277eb7fbed957aa0efbd4f7deffd77bdb2bb3905bc3d779b08cefd4123f6b729a73b1cadaaa7c04e3c4b98789e11460c17314b675cc12038c30d0469fe2327ce478cb287c517bf6ffc7803c4fa16c82255ff91763e4b0a667de8e40c1aa8194b989a918429e5c21687a8deaa9083c1b7cf890a683d8bf51f9947fc7ddfea1ec008832cfbf659ffb15e4566d7f71fa0e6572c92f52d2660e29aff71d67f5f39b104d5b79e45e61430eb39b184efadebb38759aecf16bbeeeb0046d8f576f5f65b478cf0ea762007bbee0b7ca0d5bb1e5cbdeb57ab77dd7275730aa5ebe61470eb5bcffa1fca22b3eb39d66fa290896bbe45e6d6abae03aad8d65540cdb32e50cdaf2e50e8228346cc7a4be6d60d1a71cdfdc2efbf2173c5e3539184f9ac77714878ab97e2fded5937dfb8ede5f8d5cbd196606f9ed8e667bec5126c7ec686cc4578c63eeb411649f1cc835bf891333fc51272eb59286017a5788a2564fbad67516c73330b78e6b7dfc4121ccffc5782fdd675ddbcfd10c5339f2dcdcd4678e6d2fc46f33ffe91342cd665fdf62cd20155ec10657d8a1c9a98f5a5c0be4898b8f513b7de5ef1fdbe86ccb73fdfde9cc22010f85e0ab73c3162983038c512c0f73c126c91aaf9de1949b0f7e08857ef22730ad8e5c2f6db77d8fcc862bdfdd778b3c5f66bde866c2f6b6eb698f53324ebdb67afafa9b9d9c3ac3bf32fb23d3673b387edcde1affe5d24f734640e1a71ebc357912a4cdcfa2a0e71dcfa299230a4f5decde0b75aa46a8a07306a918e5b374fdc7ad5afc899b7a4eb59641e31ebe9ea81ecbb7e65dff5f65db7bd64fdea672eeb7f688b74cc2273f8ddbb08c4b1ea5b421abf5a0fc47afbadeb802df63584f5f659577c2bfe4afc1f575d20f0677883460c5e0f679e9cc28fed08078d5885398406cf1f7df503989b7428761aa1dff735a43ba8afe0fa1bae2d9b78233d85bf8ec34ee6108f4eebc6854de68ab7e964b84759016173a872918615dc52dcd7852edf917388e975d91c8ed371a61f529c43ecd87ae915bb7c47c5dd3b2c60e97d0da15fbfde5c31bd4ec5ce37c2a917380cb67f1ce312e86e9c71d6dfea0c371fc0ee1db552efe18efb2790918979f8e79ee490f70effdcdffdf5765fcfa73864d6dc884eeac21635260c4ec1cb0ed777153a0ce44f8073ce9965988897dbc67173ce39a7d75e6e410ec429905f2ff4f207d093b0fedc11de1a0a0ae7b9849b6cb734c9608f3654c73df9fec7fbbbedb1ece1ce67193dd60b7578e66aa83a191fe256914045355d3833db3c623015be38bd045dd775ddf7f4f4c0783ce63e5e7a2a7bcf2249a062c1ffbc6e76b37b5537bb17bb0f27fd711599c75c62199ed7480553647e0cb3b3d6c075a4155ab0749dd701d1407bc9eda57adf756f5d388f61ebf33f497a1acdcc671d2ce3f1cf5e7d42f3ac1992042af64bd9bcbf8cce6adedfd2998bf533df22ab975df729b2c7cbee6dc8d263ddd790edb1c6a95246672ed6fb977446f3fe2c72f4b27b4bfe78d9fd8af4e165f72ab288975df72119012fbb0749147aa77b1ad2f358d77426c463dd8ece71cacb41168877bbebb57ce3b26ddbb64308ba9b723c3a5e22a0a7c78ba1063bddb110d1e3655f29613cb89da08680aa4780fd3d5471dff672deec7dbe1b4efdbcaf21e0cf9f37bf7ca8e2edb3bf1106ef6b48f820f8e1355271500f0edf08839ee88950b8274ea542d20339107c2e77cd23c1cef3bef3ae90eac3cbe6b8df38ecde1bae5eb193af21f5e8e8e8683ba235ec77928e8dc459d7c842703b0f767e500feeeefee91dd756b76db311803105c1f0b6bd97fda157ab1076fe967570bfcec86d7111d01f29ad25f62a7d2588bee20a85f498a007572d08681e9324ea9d9979baa6e3b308786cf68cf912464c0a50c086b97ca63349a0627d56dd089b61987eae11c7fbede97feaa6bee216bfd40d0ab1f779a537dd07b04bb0e2573c8bf86cd668ecfb84f8f01de04763dfdf80bfcfb31e9349e7f83eebc09d6158f5b9d4b199e7fbb6effb9e041d5a1441d1fbbe39bfefdb3eef9e6056f99aa6804e4eec7d15ca74ea3a16479240c576ef31d83c97e00dcff7ffbc89dfef37b2829f90234096832f8a77a8a2e06f1bcb4a36e254d0119dcd9ac7becfdef72ee5fbe67fdfa3f0fdf77ddf5087c5dffe13fffb59f31de17fb386bf70ce1bd45058fc167f88158364c5a9effbaee0efbfeffb867d46df4cc1809638fbe0fe9fe6c181de99df2b1c2cc3acef7f2aaabedf1b7558e4c4ee75ad2755440e2cc009ab141b8475051c84358a9cb066f9b06221c30ac50deb131d8455051616d62b38c2ea846d2f3d08ab150084f5c99661adc5c2da4400c2cac407614d816d2f75c25a6527ac5404105614e408eb12b2b04e0121ac4a8410d6240610562478c22a4547588fd8310b6f1c50c54e289c3f471176cec26a444f588b2040589d788495881e611dc227ece6419fc31e7dd234e6336c5811c21a6584b042b10508ab1076fe84dd3c7e0af033c28f083e3d7810a067b64307cf004200419643003b3a1f04205602c0031cb00e2ef9391c6c80f3bab931dad4fcfcfcfcd0b87e7e3eaffbf9f9e1b69f4a7d92409f5e2760c3c01a965ae79cb37ed3c6a7313a76992e63f18ca2b317fd7e2f74f6a2f7b580f9db9b50bf2f0bfdf5b7cb429422fd757b16e8376d7ed38410a1311a130014f6719e35030461f3ace124512988446098b363fe494c93c9941f46bde3ffe3df647397c13ebf3f8c0f4f324881fb09f7930c4a185c814d67371b6cdfcf013aab7486f3fdb346670ece52df9f029d01e0fbe7129de57cff9c42672ffbabef4781ceeef7cf243a13bfc9a7f9ee3f81ce66be3df866dd78d8f7af406736df1d7c8f24ec7ef002789daf213bb848b00e1ec7b7480f2e52cc832f5f45de8b24809daff990242f128efbe47f24002ed24ecdebbc47e65ca412001f80efc8d745bae4c39e2337b8482fee298973910010808ffd0d89b4c1739f339f26e7719ebb4a3a340ede92483957e9031a92ea7370fef52089847395686848dee35c2515ed7f838b74f3f66f9048e0eb69de4522bd687e835f9148345789d290c6b71bfcea53ab077f83abb4b39148abab24020d29fc1cf02ae1fceb2ab96848dbbf7e8644fa400057e9060de97b9cdfb94a1e0d89feeb2b895473955a34a49ab73a5769d290687e83ffe02a7134a4155200aed28b86c4fd2b76956034a41b6fdf8317cbabb4a221899ff300b84a3d34a4ee71de83ab94a221cdfc06cf22913a78244846341c57090034a4faafbf57294643b2797b91ee2b4d5aea9d4442826444835da5116848f673723e7591681ec9f548338fc4fad67770956634a4d4e3dc8bc43dd2f648f5919ebc4a4e4362fd06ff2492ffeb22e55c24f091528ff43d52f7de2b4ddaeb3920915cbfc145529a349c8b641f69f548aa470a5ffcd745ba79a41b8f343e52cddbfc0fbd216f90258df58f24111aebb72157a0b1fe1a7232d1583f0de92267c81368acbf45ce231aeb6791b389c6fa2db9227b68ac5f45a24063fd22399368ac3f24a7138df583648afca1b1fe8f4c81c6fa3d722ed1587f47ce2934d6cf914f63fd1b59490ed018131aeb7772d668ac7f92404f3138e1dc4f4bc2e0218a81e68f782cda991e17e59851f5f967f842a915adffc3c86a352790d79e03f22a381b904f19c3d403b914570ac89dac07e4508c743703799311faf5d29b339033ad6eeefc0accc7b0dedf9bf9ee2b65b15cf7b6ae77245eee9b86a926ceebc29aa25faad3c1501fb78529afabdfa7bab616a894d7d5a609e59489db421ddcd4d4d4d4348f9ae6d13c9a47f3a8b5cca313bcec69913916ce93c9643299ecc1ff3c8fb3db58c7d0997d7b1d8b7dd57df1e631b429cfdef65847dfc7d8ec4ccee44ccee44cce1446e53ca0c0f6a727b3731348f3e8dee1563b40f31b13e99dd94fb8653d9b4bb667530b8d51ff118b9d4b3d63496364c57389ce38d031fa6196c22c85119ad87f2e4d2d7446a463f4c7d15afa4e4e197a87d2528ccd530bd4a45cf4c4e00c89348fa677d6bf71346ca663ba700203d56f016d3f73c4bd2b49f73449e1d72c11df6649f5230dabbfd165ecdf00b1fef5fe148ace5c8bc7fc3fccd835d7a245cb8b9c37e4bc418efe36e46c3299cc255a582495c24b7f4b522cf40aadd12a249d42a550270ac5b5d0cf4e8fb4607f7ae447584747c79b9a74bcc99bba77a61f1df909fe9e67ed38d2d6527566d6c173fe7ca1e9649b3393783e54eff8773797d869d34c724aa1fc6993bfd399e465e94ebcf4d9c44b17ca5ee90f6492302794336cfd3c93d6b05f7f0dbb0025dbb86e980acd1a60fa4f4bb8e07e5a2205ceb4e969c913a64dbe034af3a0f566aaa038c2f48b348ff932ace3507a6726d1a3e6d1988236357e9ecc8ff8cfcf548b93ef009a976ae9a28a142e6d4c89aad2a5e6e5ca172c61a4100344c700513265ca90c1f49d063653aac5a1f40ea594524a6b60f3e49204d39f5c645efa8cc7673e1ea3efc363330478ac8897f49d3c0d9b6792ab4129fde944674df3eca439cdeb5a7a873e7d57c3769fdd494667ddbea96b691edded9ebe3bd199cc63f4c19b3d3b36f5ae1309b99b82070877f32360f4e1a5156a2f7dbca44fc22c72463df270007bfbfadb91f7c04f3d287ef8a2ea57acb7cf9af9d6cfb89ec6fdc268c87797cbdad0336a4d3fc2ad5395d33668a23ba535e986e65f035af84a5234fafd5fe9f54b54c43df72bfa5eb72ffadefb7e1caf1efda2efb7d1df5fc9a415715fbbf7e8f7bbeafb1779cffdd67d51eae92b49d9d6aa7aef5fb43dc7fabefb22b0658bc007554a5234f122c9515d2439a92ffabe75954c1ac8a2cfd52fda7ef5444a268da808fcee95a468f6ae5497e8ebdebd2fa25f3fe986268617bc9dfabe12156dbfa5beeb3d51117def8bbaafde1d278da8a8e32e6cbbb588fa7dd7c19a1d0ac04a4748baa1d14b249453d44d41a39748898a463fa9a66e485665926e68f48990e42849fd56e9252a12bfe691ac926e6837ae965581ac7085e3aa69591538b3628d352d97558134ac19578dcbb654e0b77d11cd53a19c1a574bf545e1db2752924a7995e6b72fe2c2d78d1fb71fc74b54e4a55e372e5151aa7abdc6120da7c6d5b220919214ed7591e494295386766373898a525fe36a5915f875db17854f9fa8c8fb1a57cbaac08f7e51f8dd131555ceaa9ea868f560f745e17f3517e63adcba8ef9aefbaec35dad8bc3baa3bde3eae2a8ae4bbcb02f0aef83d7a66e7f37f46e751df3bbebb90e7fa222ee86ae63fe5654afe73ae6d35b5d877f7fd16b7e58c005285923fd42df0b792fd4bd10f742db0bd5173ac2c191d0910e0afb1fe91aa6ffc348bf91bef9bf37f2dd8ce3bd11efe6b17b23ddcd2eee8d7037dbed8d6c3787f58dd436e24fbdddaf0a35785e9897930bb08fd4f7fec8f6df1fa10ffefc23e2abfe885d3debc84ceb5d7fa486e66d8edc18ffe608ce0bcd2b9473e4f51b080901990f44e8f542e30bd5bc50eb85562f443f7c12be27619629335f68ce9b85e66b839b715e37ff7873f38df1661c1a9b9b6b686e1e5bae9b675a37bb56ac9bedea661baa6e16c39b43fa2adc60f0e614bd59851bfcdddc359c55b8c1decddd14b813ca51e106d79bbb9b02d3cf431ca657851aec178633eb0ba0cf2f157e2b8f72422bac420dde8ccc0ba35c97ba3829f0bba3a8f22c6de12e45d35d6ffbfed7766bfd268502767d234375eb38cf4b7daaef0fc150257ebf65bd11d7f7bb54b8e5fa210ecffc500d165a619bef1f434cf34654a8d8e6872aaef92117162a007e0db5f0f8468652f8c61b5181c3af1f727c6364c8620edec8908737789c1f1ab110c539468654d8880a8e73aecfde2129597b673e0eb9f5cefc17f9dd905eefccbf41765cd83b606aa5122dab5543e3ea9d991b63efd8e0f4ceeb66030e7a67be93461c4c3a660c301c37060705d3283041c0bef4502d5f605f7a1a8a0b133ee400c58b207630726a42468b367a288152134a2d28bd4082a1c69702ae0a32524f4ac6780d994eaf21ee5eac5ff762fb8db0119ed708839452a65a2b933937dfae276581b2d5ebcdc78f102f67185e0f180a830f4a15831e304e8850aa1880214295825a471e99c705b705ccfd997eae9f3d6fcf3dc8715c8ddbb6ad31385bfc414456524a898cdb666b6aab24f51ccf09a402c54f3cd0fd875b2c528f8e8acca3235af75ea46bb4ee0aa1b1fe1ff7892bd49312a7035499c14b0f486cf832c427c6089aa02081d19446920d34e9069a2e605cb89f94ac0083b89f94d4b838617fef62b387e7143ae3666d62e1382d9e14d5b43905853f9a4e341468cca3b39156492234c602576e64d358bd2f132a0bde575ad368443caefbad7e778bb8afdb6fef9144514c98632011c511cdfbfa4445dc77efdd22eebbfad599e8ac89ceeabb0eaa258af4262f1d0a9e7fd43466c2f6dc6fcfbd4ca8cf11791a73676ac2fed973c2dd41d166e4ce8d017acd633aad1f5c35e1135a3ce1c7676d4e994e136a8c1f4d2c5ac2447969da341664da37a281afbaaffae298d9542f11ef8639b29349129e4b2610819f7ad69b40b4faf0b937227402ebbb3f817bf17f3cf11ea4a411faf637fb2d9e10fef646848e4c2c24c480a6a99e014d6bbdd0092f13bed47fdf34d5092f13543ff33397055aeb06712634369f455af2e5cfbd110da424039a9644f5df83533421f5dfd313c413c01356d793686cbeeabee88b4f0af1a5ec4c502f7a897877a4b1f9dd2d39f2e597888cc6660f9e6f442b5a1951efd400db61b030b5c2e89462390df46020fa210dbdf7fa39a8077bff3de8916125c3d6cdc38da7a80015667735d0b3b9bf00d666c28ecd642db3e9c2e610cf7a653d5e4e1e287e08759b39fa9d0810f4497a94deecd87f0badcfdf9cd23c8676cecd0b39f14ba5523345a9f03b04b67b5debd65c539f5cc7040457fe63455560b377e50627ac9ce0c97ae2908abddea9a56eb0b936c184095250c5e64ac5660f054b4cb1d963c2c4664f099bbd2490907284cdd5089b6b114e44d8ec0d11c5660f8a10367b41e0607305e204367b4d573ec082fb3f1083cc2736d71f4ae083139b2ba63df04077e0117f0485d89dcc23767777fa1b2954847d368f8e01e8d0a143878e0e2ea943870e1dd4e708f34e8f09b0890d4bf187b7794fda0070f68fda8e73891b7bd9edd387789ed84180e7854d28e09cee94d6ba6d1cd989411c0ff54e13e9bcb049ef0b9b4c89411c13e99d4e8160188a4daac4208e757aa75bb55a59cb62b55a3333ae2669c4208ebd76cdd4d4d4d488352198aaa9f9bc9a9a9a1a9f39aa6c843b1940b0bbbbbb57201384420be9eeee6e2e40e7b89b8738bcbd6fdbd3e7388ee3b8a26a83f5ebd19eb48b6cb4f98ef3c44fe6252aa2154df711808dbbe97c019cb82b786462208eeb4a686215fa3dc99823dca2026cc09511203db81f4887fb7eb841ae568ee32a57e95565223cbd695519cd39c7a0b4524a521250f7908a40b6179a6530b7e1f960a5d5676faa5c846befcc20399436f67c07adb7f64e18a0df66cd9b8d8c04a1d89b39e607a9d8e5a5cfd93493859d3e4dec349ab385fbe94b94176e2b226862da513d56bfa57899fa2628ab264c76c9cb1f4fa25a814c2b284c874297af88979e9096f1ccc04a178d97137451ba7122a5948adb8722d998db489bea68ae70fe9cca5d2c168ba562b2d9a11ccab53897198ff5d98eadcfdff5fcd0f76eeef92e6d5dd5655d7b67c8ece32e6e9b22a5575d7b62f3acd5b0487165033b7e29f3e9d900c7da71fc2f653d38fbd210e704a58945b6f5f9c1e6e9e434a58a94b28747f6e2c1d997ba9011e5e384a9898a6c564f1419674445457d1146143d8a8a7262b34735417182f3baf9924786f3ba1927549e505eeb42c617367a98d0b0d4225bc5c383cd73698949131a5e5fca744a1d9e2533692669c974b0791ecda3da4cf2b2e3eb945ed217bda1d68ee3ff181999153a1d1f6cee301c588168681cbfecfb38a32bf460384f284fe54b3a62c204752f511a82704f2f1456871ee8128d5510ec0659afa258ac93a077d02e6de859d731d19d668f2346d886b355c75adf6afd6cddd0cb2906a165ca607b7f668e4ae4fa929795c8eaebeaed05c00e168514822cf073f3373e7b236ce6a09f22df4b7a436fd01f3f32cf30b8d280ab0eb83e8b6c2f7b135c1f24b30b81eb73640e2abd7441c1a337c3301545511445511445511445511445511445511445511445511445511445b18bd166e9670efa20c5192914c5c1d99782605cb41469ffa8a8a8a8a828256cf6a830d997bc7ce972e36d3e7b38a397e20d1bf1bd6968839242c80cd98da3851d3b143fdb304fa8c6c1f437eae322bb1f36a6c2061019c358d708d2d9a7c2b24c851deb23f2e5c3ca8f451e31c22c223961178621eb723073d47f3a23d22ffb2152c44bba54a34b53345d9a50365fdf357388e27b149dd9dcf698f8d56b2e630f8f8c866c978b032a38e0c0ce1ce2578f89d963c2f53d59904ba784d1906dbb78e1e432547fdb6a5213ff78592bc885530c3223fe387ed0c1cca263f57387e9bf667a36524a5d2358b1057ff5ad164b00850809b30da6ddfb128d55d6f8f47bf698503347fd5bcdb0b40a61fde84b74b6ea189d3d424a9ff5dfcd8ef3843a628453df5e862210fa3347fd1f3a9b50adab02b7f19b2ed1d97889d0255c1f84f2b25a4184ce3cca63f5ebc51e0584099b2794efc81e9565f99b380dbec3fbfa1ee53b3a5cff678fc6d54b91f4660e71fb905c5a91ede57086cc4121ad214bb0173be69e869cd8454e3c434edcad8959e4c4969c78454e0c4e3cfbbe63fe008bf67307581c41efd4cf2a2cfeab671e4557bd43f5e2cff4cce6c50f670fba3473d4175ffc2a8a6f45d215c68ab5be78478fa2b3094563f5abbdd95b45e1fa7404acaf4f97660f22ffb3072d5306d39c33feaa67379e3eed1dada7dff5ec467cfa3764d731f15b24ed52fc1be4aa63e28fa4f856fc9528feea7df52e9620feea865ed28b89cc1eabaf3fa1e86c7cfbac0bc57ad08695437f24571da3bf22bb73d0b721bb8ed15791b4cbeec512e8fdfe8786e4f62059ff23bd3ced18d2ce68c6a7120e9c8eac7a3fa90f50561ad1b2a5f5836e6f89edf75bd287c7643c1c157ff48360f6edc707de848a3a0cfe9e149af9559fcbd56799f783eb6f64c87a239a28befd2262f8ac4bc4faf089ec8b6f444b816fbf48ea590fbe7d15f99adf7a23da8a7ccdfb5ac0ea555f64f5aa9fafba4451e62da2fad6257acdb734c6bd114df544af798d1469fdcc33a069493c1ae3defecc25229af999db32a2adde88f64d637db69863dda6d9ab229b26924d0b8d6829d288f67d2587b81f7e85902f2a96be777d7859fe1096bebf8cce7c788cfb10ff78c9fd0bf61bc6a58caa7b4de08c942876a0e161f179529f9879415541cf0be615107470c2cec00a2bc993083ad45a013c9862841e4e44f0791c7a882083c7c33504016637f4f82ca9b37781b7c3e60a1d38a8e001818801b86a35041c344c107e0c198f12e4c8814200344eece078a2f3012623000368129b452973c27800800de1418f5ac531e3c17c50503b9031f1ee23a9242dcacb84f07266ea0d8f326ef4b0627c810d0e2b5e4dce139a1daacb00332d9f28960142e0d923ecfcd54e1635ccc106f849a4682cf0b89c23ea364386b6d8701c464cd809ec7c1f606c8f20824f0f1e1f06974070924bb86f50b8238d2114e70fe0f870068189b290986cae1e5461b3d7c387d7c1664f84259bbdba611f186cae3f854d1636571c56d85c4128c2c5e18949fc64f0b021270bcd151c4db80c9bbd01e4301b22a70c181136d7279bebc41e7e7138857da8d85c4df0496844c8a2f4143ccce87185cdde0b08c53478c338aed8ece500d183cdd5005df8786180165e4372c52ac02d05ee37c23c629089856619bca3c5e69a830c1903cd053948d85ceba7308f0df3e051af4763ad32388eb0d9cb13c370b0d913c1a7078f11685c055009cd32f835a4001fa637b380fd52ffa4349dfe98fe70c016fb4b640a74863b463f4b9829706b41e2dc352f3fbd43ff8b979dc4cbc6ff64498a05811fba78d9fed4a977cd8fe80fe9c34bfa3e65d8dcb524dc8fe38bcd5d53b23bbce73ceef578c3997b31a069a927ea1acd03df7b20f5ac7a7454bff1f7dccbbb4452b769acf1376e244db2f5e61edc4eb83bf890f06aad542582abcd7eacae35e3a2a9b1196fdcbc7036e020e7c9dbc1b7f803f63f1efe78952b5dc24f91417dc50b8f60ad5c70c20b297da5ca4fd7c8e880837530846d1ae29c7cf88841fa5c12ca8a9574a587263e4e84f480c9e9f99c24542d275948b0d43399208027cc063c1c6c808438a3a5055f60ee67129e25446461bc64382fa79026882b845841368f8ae88c7143e7e6c612a00d0f628808d2117342e9c5a61c6da2a46e48018614cc3d0a41a59708c0664003aba191f2715f2408c605858fc1cca7c8a1cd35c38427c44b280be080d17d8a739cb18acdb04f7dea611e86dc839df823f4605946e003e6aa4f100ee66e0a6319dfa758acd15a97abfb58cf893f3e19eb63f504b964b07d8a0c72616b2d576bea7bebc216360013481106b69bd5e1803503fc143954f16ae58521b8fa2afe00872a5e8dab59f150f845f5293228c4a208a6de9b3dbc9983537d23e65cae1ce2946afbc4a7e20f555088c5f74205f415415c21041655e25d01a7665738b2d210ba80d1ca85de6f0fde8fcb1e0e439cfa1ca6c29bb9df1a7345980a4d4cef10c594de0ee67502ec9f1e4995d8fe5cf1d6643bc176c3668239679d73d68dc994c166c35682ad868d868d04db08b619b6254a67944d862d860d866dc9f6c226824d69045bd2e6c2a66443da926c48b616b6106c47656ad00619cbc61a6a8c49030d4b0331679851461832c600f3c5498c19c8c04b1873ce35c0884197995a027ad033c7f460feed1ddedb9ed9397feb1eb099c37fcef7d923f5134825299e75ba532a06f1c1dc83ab897dc70340f0960d83cf1e2e533a64295a39ae6ea94b3a76cf77f098a5bfbf8f11b0ff1401bc4d63e5f6d52b686a5fa9d4dbb8edb7ba7d00d3219ccfa69c85cd1ee5cce1338757e214e99d63fb8facbdb395db7b64d8e5f642e8cc766c7bff72f6d83ac7961f6f5b87b7cf01d8bebdfae0b77df5493dcfeb1915b76d401df5b95803574db76eebbcdb28f5addbbaaddb38aeababafebb6be750f9d99c37febaf4bb163dcfbeb78ef3798fb4c836930f7d966c7596702432eaecf75c9a55420bd4bee3b0e731fe0707dd0fbbc8deb9b16ee14eef7f6be1fc7ece53b812124de1ef4664faaea3e4efcb13dd86d9552d57767ef708e8b3af1c7f69d18c487bae7759ee7cd19557773357212489692e20b3bbfbdb0f33bcace6e1e22e0fec97d90c6f3872606328566193c67e5a2eb81e38d760c2b0cbeb0be2015562e6058b708c3ba450cab16aab06a5985350b1b76f30801832c17143b9f15562c5a61bd6226ac56b8c25a054d58a9a809eb143661851a6f84dd3c0250ca6ee06ef23b86830437c2ea829bb0b6e015d6435c93930faecfb90fa6d4098fed994b4c382f9f0753ba44e7652bcc231d5c9f2b7582a818d81854a2e0c5614528178ae355a8fa9c5b2f08c7c7cb49bd51e6e5ac3d412e4c8986b0c5b02097ad3f1466221c7a1962ba02ae4fc91b5617db3307a59eacc60450fcb4017a26f3d87c227ef3889be65e01fdf1210401d4eb0f5b90584102289c80c96c58e9418ca62780604117a5aecc1526a8a481c3d1910d4a22a8818a2a74486a214a8d2e2dd4c0880a0e58701142063246ec500494116d00519b41195bd868c32887364ab085072d57b6ecb001199e5843cb0978a83121a623e3e5c8298d249e88e20b961a6ab8c2c6981f62784113301d1b5fd050420449b4f862e90c231f8000638633b648a2420518dd1a5b64a982098a123f00214308da78a2862f4b4e90a104179d1a186a0c2f3ab4302509227a4b1222b85469620b1762a0c5985a122c90b8628b982e82384208306630e30c1bd0c8a28a34587042aad180c5162f513c4c49c388358a908196315880c64d1518aa70693a22883112e0c2861940f15005186c4041032e59a4c10219d668e201872616d0a0848518463831c393189f1a99284230e589175f6400861490b18410480431069533fcba30c50c111c514697219418c3a012430d497820a30524ccf81122a36b90202a0820a8380a0387b642072e3b303145130e30105186cccb1e4a7f9cde76c20998da18643c21a2096ad4c210484a4c29c38b3374a0d12f80a085e9d045c2105685fb898c2a502e2e6ed861061b9ac45043932d2368b1e5045b72d812658b0cb670b1a58d2d666c81d1ba719df7a5c05054ad5808209242509224262755bcf49a57ce4b852adb1a452d5efa8be28fc905276c315ece31b5a7587c36c58881c2b37905fb53279fcd2a1ef39f4d268ff9cf66129fa5e031ff2a5398a0cc244c5e68c052d02477e23b9a5cefef507cc714bfe23b3ee7e23bc415ebb97729d8bd4acd67afd97c7629b0bb15a347ddf02f37ef63b0bf3e3b19ecffa38acdbe6405de9183facaa461693a13901798b062f08e3cc479121f01c793a60e546c9e5db484f1f1d2e5cb6a6905364f2c55ace891020b948a0717d83ca1304de171822245645ac2e6b99404fbcf26b249838f8033132e6181cd2d661ee9ac3044048a3f66ae3399c0fe4081b580efc841257e92f4349c08f80838ef7f020abe63e6fd7152e28f9911aad89a12fbc9eb43d0e2f5893f580588c1869ff8e4e6c6137fac9caccb13ed931b373af187c8c4e274e2f864fc10b418c116581827fe139b0f410b9b4dfcf129617536b17c52532385e5a9a2ec090dcd1686f5e9219fb83e042d5ca43b19e10ceb233b53085ad8a896b3b03c910105ebc0fd348618fc3281a848055154d468f49bd658688dd2eb39b4173d3d5a94d8c2e405302c19a22b411333d8020640d46086195b1a2190d19344bb80ca0ca02c4d11a5948522810249061394008718bc5882f3a289018cd193041049a4581af384b4850a2a708419334cb1459313800963668d0280e94902c360450ca2105306136472ace1d402a8a62c3ca4a00b20be2e8cd0f1a52709271b5a8852c10ba89c40050d7802ca142f544125042a1053c7e00e04dc8981bbae4bc2688917a0d1440dac3c95718566e96ce64a173ec0e00b166401035af7bd04ee3adc6189aae18e077733c05dd7938437821aa4b2009f923eca2405afbbe4defb3c8fc6789f3bcc1865b5749f1bca93e59edcb5fa58c69a9de2f4d40489534c455147de66c4f4b3d19fdb0b6077f7e7cfb592b8fe04aaeecef9cddc77cd71bfcd23dcb57e77fbb7ad6b1ce538fadccdb5f6385adb9be7e5e760207abd5bbd9c69803d374cdf7fe23adf015bec6c1eee802d76368f19a4dbe956dbaa3211f6ff827ec3b2fd71849db89f64e082db4b215a83234cb3b07932512e36cfa316ec0ceea72f3290c0c58690c4e6ae3d7d51426960f33f89f105ce9e830003dbb3871f616f3670ae68d889eb572f2910e45c3a3a3ada8136e79c7336394d99b567dac8246fc91e552f61c6a040b17850ade5c7ebad5eca7a7e862153bd3447b6e97c4a3f244fb82e1d1d85e089d6b539c5a969fb99348f50e8f6d261462d162a3796b1c7cacab63f3debae7ddffa848fe8ccafa04067ee643259bae279b14ee86c76e979a563fea3160be549b08c3d5696cbd15aecdcb5c2cbc6d9bb607fee881aa2f0026f374fa62ebe63ab5e9733baa0020cce7ea55bc10c33e8026777c29d91822d32c0d9936c628450b2e205ceb34be5c29d81d4250c9ce7155abd56710add2ef7db13d5e7bc8d2a4b47b46ae4bead017e2d8567a5490a66e1b6f2a4865bdcfec77d70d1fd7c58777f84f8f0928b0bf44748d75121021f9f8302775dd73dce378f89bbfff15248d775deed9ec4b882bbaeebba9b83605c4b4ce5be6d8e301f5d5821efb3aeb52f8dc133b89fc428027fb89fc468c259e639f71a52efaa77e60fafc24e9c5778feaa79f490a6f4b250442bfd16ea13254d5abd5fb46d5a686c83a2b159448ddc372f60c3f21685672b61c2fd94444b47e17e426202d3a5e6416bbd3319e0343ac56360bfa4b30faa4803064e4734a326cad0e6afc0e386289a6a47b469449b3f97e8644267aa27a88862e988d6b5f9ee4467db1a63988efcb31f254d14e810a5469bef4c1c0a6a8c172d74e651515178fe840ae3130b9e3f9b9ce69414e88c4ea1b1f9f389d0590f20a09c68f34f40c1a7583aa34bb4f93d74366953fc4ec1dedca2ea17f3e9f7fb379e5f8294acefd1594963f3674fbd4f63b41c3258fbd333a3274b644ef0430ba2663883365f48cf8c9878228d20c808e1431333681e05ecd9436862232a087578e2208ddb670f1c20908e016ea181593258a9c43038045362e08f0becf58e190d06decea0bdd36e869833701703cc7d81b73170a55fb0778167efb415dcbd33833dec4dcf029cf35ffddb376dbefabe16c0bdf72674bf5d16b6efdebb2c4429b27d775fcd42f7dc7df5378dfba6719e3dc273eb9e38cdfb1f1f6189ed9e7b1c2dd88f248a5224f5db25da3ef544df87cf912f7ff08d681dd93df7459ebb4451fc16e11ebc442ca41e7cee8958885224755ffee2830f3e0baf05849ffa22e27df9ff801fde975f2345c217cb5aea53dfbd114d9c1fc6529f1ffc2c4ba53cb269535c80d3527774da9872ffa639ed5960214a91edbeea7bcf3df72c7cf755ef6b01dd6f5fc4bbaffa1ca0b1f9e51a61a6a041173d886185c67d775ff51a29d29d40630e451648320c21821cb8386009dbb4ee42f32e11111a9bdfa1d0611a8ad634eec1920193b6fd48a77bad64d2a210d916e0b4ed7e46d5b9329e106ca0d1859ddf6a030430ecfc146e2b2e7801810ca72f6660a104cc154849408879fac243084becfc8adb4a121bc4b056926e08e1053bbf63811776fe0c6e2b2e3001a10c10dab0f339dc565cf0020433b888c13e7d690a412969042120b1f33b30a2ecfc4f862decfc16152bac15252c2063e7775b8c61e77bb8adb870040831b0f355b8ad24250921c98a0b56e06e57bbf08faf4078817d12a30cee12c0192476d0c0f369aa3330a80e420e75b2908890830754f4e8c1fb1c44886176a6dfde8e29e9f3427d28cf068b8aa30a109caaab896a650463f0903f181e35e460a1b182e3071c6600387833283964c0a2d41e4d50f159a2ca6cf8162a6d081994a68247981e55781987135e4e130fd5005cf874618023cf083b7f078b9a438d97426b819723a5ceb4dac05104ac892a89ff39eb79cdb0d683744a5718eb5fdddd6975d56debbcea793efb46958d3019dc5fc7d4cd7d4811ce20f070b82f3553a994f7892e6fd24a694f5a715c6188e3e588b3d5d56ab55a519f0daa5e45441af7b588e6d1987765623bc330ec4de539092b837860188aa24ac6b3d5a83207425154b5af2cab55a9b766ab3b551612552a277fb856629015f656967392e5ad9b83ea461a391949c13ee712aeb3ba8e8c62cfc3eaa5933fac57d362d5d89a9a1ab0a6a6a6265553f37935351d57b3d5545ae33535b3a607a0ca47703fc55430da9c45023a7d239dcc435e6d48849d529f55958d78f03c9f5349ad0db52140475686d6f3bccdeb509589a810a58ebbfbdc3617d7b9acf8c3f57d5e0782dc0656eae0047bb599316e009cee1770cdd19bd3e79c734e9f734ed7e84d9c2013bbbce454af211cce2ce0f9eec515bafb48a7fb0dddcd18009b6368fd5ac04b4b435a43d70fcb755d59c4cb49f2340882e124ed2455aa49ae56d6b258ac563833e3aa93a4a19935eeeeee16f0b2278d8d8d8dcb66c6c6c6c6a665636303a66c3eafb3b1b1e1369b4a6d7c7ae08901411b4e77ea1a378e0badd7759de77d1f91540a0c43fb2354a99a5cfdb02b168ba562b1582cd656a9b366dfe0964cfa3ed2b0f4e7ad5eb60fb96676d9dee96f126c74db7c9bde90cc4b1e5be75655afa7d7c7a9d481c14a1dd8166eb6ebb8aeb35e8afafc640041a794ceeaa3cba69b6f3302d3abb46ed4e7b611e12e2bbdb0d6ba893f388e36b17d3defeb388feed0f561384e37dfb66d6efda9320b4080d6bddb499e20b33d27ab935b0fc711ad807389bd72c1fe5da7a577fca75491e24ce652183141427460de6428a57436edde21e3a57b1227bf2f95a2a9542ae5b3552bdafc94078aa67758c0bca494faecba61ff5a0438b520e0e78a77f939c18797587abcf4e901bf8edbead7d4e797a2cdff8ae6a44c80ddb3bdf43a6b6d4ed534dfe79c5e299d32f0c24a696f12f0a63baddec475e24c3c7a9cb7795ef53c8ffaf43caf2d155d83388ee3b8f9ce558e9b73c95c6aee665a9de39c6e1b0fee1e0cd79fb4d65227c3b0bbd7c9d5aeeb68d779d775b3ebbaaec3a92ef0c24aa917561d59d93bfddd5cedbaca7151c24927750058ebcd4121e5ac3f470a15e14a6bc51cf07272c0cbe92e5c2b587390eb876ef4f6ad4028e6665dc29d6e7942e1f93ed2b03ec91ca406a8048bd82aa320648ca1190106000800f3150030381c0e0b85c2b130cd43710f14800d88aa4a604c9b8aa32488619831c4204288310000000003423053db000d68f126976ec454fc4be728212e748966cca6e1750febf1589ed3339cd995d6a655b618244586e8a9faf4ece9fefdbaddaae6cd1ead174dc32f37b8ff972374da382f5be1ee5824efd15658e9272e387b207dcb59add9cd1354e813f3ff148968b8ad926323e2244338e04c39e85545797696637c70c3d175e09adad295fa1e0129a27ced00a6f77a33d0dcd8e1ef50d2270f17147b00a0169319d883b9c8ab208266a0840ba2ca15e0aaf5ddf20aeffe446096fde519456e83fc3efc7978399384c5b773603057065c3c7f0c8282836f88dd92e3ebf8fd82482da5b2ab299403030ec994d330b81550e689fbe400af1bc62efa22aa33d4060af584c338212c52476bdc4c5576d4e0c804c5db419c66176b8b884b7003920fd0a102ea658419252667004b839ed4ee8fa08209c00e1fb6d4c8ff3fb8c45a0db630314f581951a8ed9f507555b13f671cd90b031deda5d181742f5b0c66a4d75feef13b14a0b21dba24d7282945c179616d30dfc93604fdc5476f7fd5e4101555ca678acb8cb75247efda3218b84367a547a8dc56355821bab905fa75438e887d256e17d77f98770d73ac2377926c27b91196cf2467fb0980ca86265bc728727f47212ac9824a9d4021c3ca6d4e5d700537589c591289ab34ab42bf6d0d9081d1c9ef13a7506363a15c40dfe75460f43d0d4ca4017d71a7cd37854888ca8ed3963ff606dca4ca04ffd045b992cd206dacbfd4e3bf8964b801b6d6b2ad51ce47872557a05e93c73d83bcf0afdb289c6351c1dcade1ad5f5a44f103a326aee14415b7f02dfea6c9838f4e320799e4888ca947933aa4678835628fd8e7d8337630f6a1839b7f17b703c78540700b6cdc038b9b407039705c07f844d78c2ce41ccdb43f94c4a5ed97785a7f6470bd522454debc82929ae08eed93199d2b61e5a4d9399f30ead5f5695b80d2d4fc03b7a1b603dad443a55186e4656350b488303c5dd5a22bae5766493bcb0aab345bc7fa9e41c4deccc5c4dc2642c2feaea53fbb1185bcf4840ea7f8ffd942df655bd6892415fd703f828afb014cf66d90e3810cf18da5b578bd6b6850a1a3803b156a26ef55a89495d91b8654f71b13ba3584b0667c9f90801f7d6c3a57cc29530e0fdea10337206aa5ddd1797b3a5e6947ea50ba9b3e0b86952584c78ee91cd97980d5cc347c750afdba70f9985e587d758df04f3529a4c6cac966f4abf7453a70671f52d40e1a3fef8b52eb4dd92335a16868f34f9df43a4aca9e6ece70c2bce73b7a0a157e8894868c6f8d839d25ab7f169012691a4c9ffca35ecb7eaf20dad982d4321c775d0a4a5904a0e7f4157d2cec559c10665346a8d45bf8a68f15ca4043947008934c7374d1339c1bfeb200b452cff7218b8910fb49da07ba2c17e07d67a02eb32579d4b13c3f61727102061b61a6a9fdbf827bd70d20c310074288bd9fe0914951c98b28295b87eee8d6c6782e1c917c741213932bb4a2f478f8f0616de440b88d9802b771d8a41ea096fd98b2b1f08e48be5f1442b795be4fce3a8c17d47c43fc55d8cac8c2fdbcc127e56d2c383007b75dee8a66945d9019e11882780bf11ea874891324547d6671533fe431c0d625b348a641ec7b217dd6b34cf6d8122582592fdcf6a34afd24119981e18f0b06bfedda9791dee3c80fdcd6a7f7239d30cd91ceb9665fc6cbd571ea3c482285fb5f92c85f317fc02b81330a958f664213e053fe2be3347a41e6903dd768d540e22ba2d9db9ae4248291f6e8999f2e02963f7fe738e759aad07945f5fdc429b9f1415057e78807f45904ff5f2379a755e00d40b78135cbe9d0064b99c5051117b8f735adde25e3e0b3adf9013ac3402583a0b552e547320cd870f0a0ffbc027a3773436ba266d11074a8bd92868e19e962e0f1d33906233abd8fc976ffe5e05b49595a2a364f7887ce6f1d99675b1b3ec0895007f695d690a10681473e8930fe9e60750eb629c193779f23701d3bdb55bd3792192607ab1ecb5e84eba3e4ebd0996facfb5f837aae5aaad2eec97956854d1b420b4682c92c991569a2fab2e0812143906a36d44b54b0b912360e2cef083c6ff12164a465b994b5ffa325c80cac947b740fe0c6b7e51d1c36377a3680359ce930b80417234c3fb9cdfbec66147fab8adae5c2fb3ac18d80a88c93470c600e90ce1c4aa6bc076a91d2cf52cf6051355ab4f65b1e95081f264fe654e1c37beb55421369b05a6ceb2db03d3ba4cdf21e292ad5e0b9587d1b9ed395e1df9d05bc2379cbc03d98568b1dfe3e6f45f2f65047a177adc37011cb384644fdeb488735e6c29292e9a349f4c22e5539bc0fdf91a3a6e65c6188b55b6c7f18aed0697e29a92159ae701129f9608145c5ef0bacc9efb20bed3c4d27d98171adb9b4718af5e6fbc5de4cd8865e44ec19a929141caf545eb88d45d8c969e8002075088bd05c52dc893d268447c1e009f116bd6ccb4c4fd8eaf6010e40cca062a1100fa355928a9a1dcb3c0ef3a9d37f765e97a41604d11c95f1827ebb8c9edd5af7f2c4d3b0429680bb2f2f23604452100cafea2bd9ff1e3b5b7b16f2039755f47d17eeb5cf86c5439c961c4a1454592a4c40ae353b4718e893de8db9625d09232983e6f9c81f2715b5b006928d85d265711627569862b8dcd865a9cc9302038d548c961aacbd846798c6a7a2eb0b4776614fde6b99a3fd9fd1a80047aec720ba55fd54ae706cfc5f463339b8c1e40c9bbdd9925f6d0ac4272bd12a77f8ba006c97b49a83801ca0aea461a1b269e563422709c3fb6a0a1b6244599f964d131a0a2be09f7169bd2c7327231bf0541a281e371cea5d8e0c1641b51d2670575a74c2ce454b7394a690622ce4d0fb50293ba4617a71045cf0a46ae619e61a0e3f236dbbeee543556acc0e773438cc9dadb73c8a015c282b17c9de7b99f1cd1498349e9cebb24b34d41e9b88ec1560fc6d7de5e61cbf7b994862f5d239ddca24e7ab93cf083681e1783bd3366d3917d7f90bbcc4d14a1a20b09d79b571cc71b04508f718e8cf077c7c23bc897375612cd4fc085a3b3225b03a959cb880b20ff007937dc0c994f1805780de930f449dcd1c69e006d92591e7fc1c706d1de10a2bd1725913d4e8b56b4c34d842b8268538580586d0bbd4aaa28ddae7c3e697c261f34a71f8ae2d15e4410df20186d4f41f2acfe984e4d126e37d0c78d8afa425dad682af7973cd6e938a50a05e15c64636639226ab35d4a2aa9bdcec129ec39ead083f533fd4e59a0153c4dce4b4b953b57746b6c85a6b58f53aa130e50b736843edc886144cf9cd47b19ceaba40a88add1a00796193750f2db4419db345f78eed1d4a2fdc355f2c51f537d14af1c9a0527737ddeb090d4a6770e99af0ec22cf660e55259e2051e96823733f83162a7804d5dfcdc4ea1aa513b15cd53b902a3e403d1b1c89851a9e162188e2e294dcf4b69b6916bc0891cb6ec87ecc221ca8657b174c5b424baba2b4bd3ad5f4de2bcde8c53bed6f48e5aa6ab56ea3fbf01b8d85249321e0d39c1494fff7f8371f0d41d31573fe6ec41086064fabc356b41dd37be78d926fb29ee80d3ad524e18afd9df351dfbe524f8d274245695770d3522850f5f4eb5228cfc4ffcf53255afa339d077a5aa69535cfded179149e2c5440706044cd4abf9d841241d9175166ff82b53b28af25284d7d50186bd09822817af6c5af9f9924311f0df9b2d827c52465451026bd5674b92749278f40f2372a56aac36527147a836c504b2b18a770802509bb7acc667192ba6ff2b1e653d839ce573fd92ceb44a8fc7db8fc40a06bcd873c69e5690f0d36c3cab850b5e9e1888b4a020244e2e8083c2bc95ed8bcf00579c1291ccc3ab685f26c2e19e359261562c9a0ba58a0811aa9236329aa5a47da665514f27fb7ff39f1fcb5957da470c70a3a6d212910f6cacacc0275ae4e0c5f585409f4c33602cad99f9fd42e50551f95dcb551c9cf342879898edd65c06c4f05879b548bb313737ea3c8ee65b17a38cfa4218de81e10b7cd544eef0f1d88c016592b62b9546f2a9308122a3c87e0ff7361aea0ec7e25effcd58f0a1079a580e9c4ae796482bf72eb8a378d6e57b280a4c144d61825fe59f5d85db29b84f60a9209a66e3f095ee0d5dcc2fc67052dfdbc12af7cbdd07bc37d4bf2ef9bb15c44936e5f9eaec801a797f6633343a296108183aa601dda2d24ba7a5dd2d3e4787340376126aaca7fb8ba3178694048a15a22165589855db62d682066a1d8c4d6aa007c70d79182139896dac5a834a890b2d85a9da2bc96d647147681df81589b9d13b57fd084231fde834fe83ccd6c04f75199b486483152381cd4402e6eaf273c25eb7089b2c6aeccd943eddbba1688c908b41df8b082d66f0e91f4c675a5a73ad392c3cc629a1f7506a98b033d00136dbc1f9e54b6a9a410cedc895f6fac0ad895e01a6391e70ac406178ed02ba48c03320ede11cf63888f6ec1f63b8587da5c2b3e82286db4f98065a77fa145f21bd002a33133da3090766c2922e2fe1bae7e7097ae09117093e411ea5c43f5798d766845a95c3c8860eca1840e560b2bde73547d91d42196664df154ce70a729e7daa281c5336fdef55ae6373917d4e231f71f9103562ca328c9ebcec0efb4e781990634710348190d68ef596c22ca671b41909b21374629a064c012e93c4d5c7713c9e99c1d9fca8c820f85a9709edb1f4034efaf8001fcfc270ad14676cc6fa08fa285c9b1206d3601bd677d8f2b2c4565b1094c08f4bb347ba40360c07458fbe6645a0ab824036f79a496b7e002fca0116660457a383de2eed9170c14006934cc86bb28592c81c9a2ca97f53b61933c29d08f99b939e8827bea5d69f4490a3efc039ba400560a2db75fcad8d35630c1d79c820f392d9e28c3969a5e8a84593756718fa35217cc536f15f7e873ac007542b0251fc411bb37d7f211cb49245687f4494260ddfd0fa1664954c1285895cc1447de9165ef7ac34c2c631e28144c6b3b5d07691e1721ff1ad2936714f906a83bd3c351692dd0763f5d144c4fde745ffde1dbe743cee94f8a4c6d39836773652930b3602707e299a0b4a0bd07f7b1e5bdbff8dfde42bc4b1506c46953530fed25d45d66e437ee172c0dd35ec2552eb584fceeae6e68a9852e84dcd3dc0588a4f888a6b4eab4dcbc1b0e975539a5b88b13dbc5495eb4941c3de43f4543eed59ddbc54cc707885fa079ec1a16fce21cfc8c8c2e213ac687776cccd0e56a412ab497ef07d056731ed77f081392c689c0bc23600dc06ecee6b84fe6b16cbbe400e02ff23327d15638d07edd8e3887534e81a405f11df4fe828f6a43336306b58a7151f97b9be526d2c2484425f9171df557152d7bb2bc81bc2c6435d10db1a11e8189420fb9753b3dbeab43712cc75ee353e2202db23010ea297a7fb5b1cf789e6c5ea0d93d3a7fbf1f4e2a1a663f312e0734fe1f4ca4f221cfa3b83d67cc091e7e409508b76bf0fb81ff131f6895f71a29c3b64112cf608d0017104d0d2ed781b5f60b760779c1bb36775cc6fef9f40ab215e092b0f96cead71dc2f0635cac1651233af39204faa5f030e3d6d028261815d96e420ae6441e1fd45105d112aab7205de3e2be8dcc865f8c1f9ca05b95b865060b5f681315f2791073fd20496bcd6ea5b241b54210b4e62434958ed01bd60a25fa91221a112bfc193726350d9291534cc340db639dd5050a4534a15bd43e7f867aa1b669f9c3c5e2a2d1cce8b64bc3a8675181574f2cd6129ba9b9012b9586c1eeec2f1933e6f90ef7b5a87ba745b2e4ed85f7a35a5ca8fbc8782cc4a7ece4425db228f1d0c0f204809785eb9e11cb327e07b82ed454d0a25993b266333aa6067c715fc1a57f8701ec6a3ffbada26f1e10a75dbae509832d34b7a8f6227a3c1145ac464976400283da89fafa4a723d521ea1c56c1be46132ae45075ee40e20244ba2feda129e52926070e4499b68ea326d744c875e1857c9a049088113302611637839a20e4d5fb2d5e68b5ee2e493383b80765b76fab0e326c37aa117ed309af6cae61717560fbfca90d223025bba39064137340a3d278b0ccce9c0ac64e8783dd05c4ea1e4ab0713f57c8913701a8a53a60258091c0152987ea71a4701c94e1126c14fc40b3faacf84fac05b46cbb63019e3b9b3d84c4c353c9775eaa0025c32830c69f23506977a9ac649b8d675e5647f226614173c412bb0c4251bba6251a140c6830405f21f941bd20cdc18fa2cd21f0837e8df999b2102e198b0e95681f2b7fc87c922483e663d0b06052ea0d33d8878f780c3de983f66e02250df470a05c263ac510e68edef13f69a0f915a066cb571df0798b9963b8611350ece09b973ebeb3ae1e15f64a8d8182b8662aa2e2277c1b3846a2acc6a715c1f585999c200055c3409ff07e52113ae526ab42831d41923d736df7835569398b12885519ecddd58f9201843d7ad8a135a9925a36c09536aff9502bc432bb8fb5ceb67db2ab0d4067411f12e81275a29bdf855f728ccfd5a0e6338df50bc8d988fc7c5ecebf7df9aa368e5c735e04271654156ad0d9fcb118f1142abe025334d90bd7b79dd67fff33c15819f8d03b49af23cf47084956d2bf6e51f0bc0590e84a11409297c639ba7659e9eda6e2e9395284b1155d337fe263f3352482f2d584de1e4f4d08d83cbbf84bb8d45edfe2b064dd54c44eca332de8464b1d6ab6fbec72d02d34c5c33ecbf33a8357e27f10d4b7b26c55372506c98cbf3b555dd01b4ba2eebb027ab919f1864d886faa41f688b305140979326dda15dd15e2dbf925a95d9f15f51267d6fe623c9b0198398035224b844e6903887da58c4dbce4709235e91280d0c6ea1fa1275704980574e0fc68b260f14af3d539aab1f592ed013bfbfad50cc36dee9b9caf42f8c97e6f2f30a017b8564e530f72c0c68420381212369cfaeb3eba78836461d811be6f953c0cee6638bce4da5f824c832265fc3039cfe1edda55d00e4e0d845be5a5eca87c74b4444d98cb3e4ea50bc8e3b139c7e11c625de5c0b975fc1f5f909a701f9f85db2229a8633cb15ae5037ceb887ecf78a37a3390e3e0dba5d4a103621c59044a1105acb7be82546117d941774f68f1919d2404085e75d4a6332d79e70a71fd360d7b7592e3a52618302693418803fe42fdf5d2b69d6fed5b8fed568f45729aa8ec882a280fcf41b82766d2c74b64a09f405c88d082dc7cc60cb001ccd46b828e25bb6d4327344332e523013f7c17a53ebe7c8a33ebf429c134a63cd307d0e991cd11c32c9379dc40c26020df1ba85f850c197e3816c88cfe4cf1a889db984ceccfe6499fa21323d6e2d596e4d936e938a05b9db03859462cd5f6457d31d2e85a3fb924e16187cb385bb79f1fcb3a6b5cf469af59330e4d218fa11c4688b886a7d868c04a9aae58fec621cc75d3cef3e2e08e5d71e1a0d720a9e5d651ce9048a6b74c550fcb4cfc545108ff3654e58d1040221da5107eacda3904bed49d3b76fd017e7e79a1f6511f40c054f4cf9bd1642d74c4023de8460e4570dae9c67f9fc95eb8bb2a80d982232df570556d9dbed93c110a1c5f363b0c0bd7bf9500ed14be8252e991b4c76d4a16621e2854889f21f3eba14ebc1dd3842d1ca8600db2926d2790925608e690b42be557317610efbbf4e3247fd82ce9f6f7927b64f7b228efb08d24d93d0115c6565d6ffe4f5dbe2a88282303a6153c279af6355a4dbc8bcfab75cdd28ad43d9170ae21d8ff3bb8c709baba58627837eee0986187fbf6a2e5deea1ee559c173bafe6c09bdab8b7aeba01d34a6bb20c85d41d7ad97b377b203c7eb05c333e7aaecb8fcec47ef51135c5625fc3c7c1ecefdd554e7caa1a409f007ace72e982f1f4c1a3469b394cab9a1740bec9c50c287230c941b6320564811a0fa249781fecad4d816d975db7e1160890176d219e4c834bc6aac82e618cf65a890aee703039183175cfbce670ffcb6516c9423053b2f6ee004afd70982a0ca4789093db71c18cb1070cf36dd2b6eab70dd13d22c3fd010085866137fba8d469c47e6a02f2bf6bf47b8add51a7cb014bf0ab4a407043061f8e00857dd2d15bc5d3407a1a730862e191a927561785b015dba55a0c71a30d63bdbe98654a72df620fb9dbf05f38ad7d45bfa7f0f063c0aeedfa0e77a375c940523058ba32212d31cb4c71caff2f078b115ef4f1a7db94f1d34f78a018ff00332702a63cf638fcc145916972b9ee12b8d9f93fa63df69c13aee75cc9f8937c0f5b960e81938e81a8718ec7ff6a5d34659daad07eb184bf407f5045adac3e340b75cdaa54428ad0dd4e5c6ce67c5027b9ac818c5689d1ddadebec42aaf2a16c907c2f332e572885603ea0104ccc88320a4ad69e315e24d4ec08630d81841e3e02be6d4400e5faf1c43c85345ca0d8c35518650d16373daa16ff7b87577bea3a90c032283666afbfd71976cf7fa2b5d271fe2ed31c269c9aa13d79aecf46d47b0a1ba7ed59b68601ddfd9a202074057866d9c29d5956191129a3f191bdad9fcf31fce63d01bd0699e5d1a8da55e152f38d285ce1b90bf289cd16fa4cd17acbe2e4432f83e022d27daf49ed8afdbc01a60e10d186d8d2473ad224eb5ef52b5592cb34f1e889efa5367709a1adc8b13412bebb6fe3b9ab160fc87f56992ec0effb1138bbbd6c58b247bcb20492181dac6340528f6424d197d4a079b1733514cd7f8aa9dde531334a114b499521bf3d0e7fecbba3896524a76fc53d93cb485fd8d08a71aa09c3da2d2c1446f30dfd25bee456119cfec5c121ade66850a0bc100933e3cb1552e4a0ef02d848c1d1906e94818936c95c570340c0321670891044baafbb10f9009a808962b18b71aa1572dd11bc0bc981e8f7915a5dc83bc13152ed196abba3eed80c46360b7a32984100c5b230f4532d92c9968a689339feeba29053947a0d149db69d416060205205bd07a57758580bf176b520552d1cda7b48a05a7aa4d5f145e50afd0bd3d745af80c26263725306455c9150341201e4cb415a8097f16d3ec439a8eb771e09b0c1f5b815af88c2e9678e815a5770b05dab3008031d83656a4cd31df79460d6c4e9a480162d1c2d7233cb339e7ff0eda6e65d6e1a35a304b8946dd63979d55c0298c44ff3954cdc3d5e801715591812125099bd6da205dcb4d8b1d0648b5fd515a569a6d3392b9f24f03baf7f14a20512803b4251784f1b53180cfeeb524f8b5c7aca682503d214d42f563d48e99f5f0ff85a7baeb07291bf6f5d2079a5e2f5dc525ce8f1c4339b3958e7980a932a096371c556f40b43bd2499ebf6e946f66a5591da6bd85328e20bdbc529ccce3bebda08340af7f842cd9312c2e6da2e05a412929edac85f4678f1a65a326345c5a7c9711e997c8998554e305fec92ce575c74284f6c6ff857358e7959e95c1f4b215acf92faf459ae91e566dc8f64ecb2e53f4fd567b9cb84825e91438b5dc6b44dd9dadd539e4e522787fa2c41e32e8507722981993bd288e06decce25548670124f5a59f695f109e772caf10e4ff5527cbff80fbe482e7ea1e07143240c87dc221af5a81ef9fa3440bd56111ec2699420bacd9cd8894e31662971ce20eaa4c68bafc9cf41154a77056ea0467132a14e983eb1a1fab1765d21fbd4275846b9f7c1f90dcb7d357a47b2bda79a96c0ccc996ad7337e4741ee3f2527b2d05c2aeabe080779826754ea2d30858498d4c5a8f4aac0452aa5e5424af9559aa25170941d4d7f8eebe6a218f57161d0fc22569dba27feb061c89e58af2f7a824796ce148b9407468537d18d58445c530ada13e09d0ebf33a7d7c6323bd32cfae5c9b9d45d6f77c23f000606abfa3b26b9aab8a368e1a28fb8c334a93b05c61c4c248a6476bb7407a31bbc18bd1ce9f7f36df27b0f69cef1e2fd6d0ebc75228c06dcc113dfebf133ef9b0e10942f08325ff58f82cd1348ab2c04e335f1317c683fa15ab6a69c3aaee84b84672429dee91e9865ec5c41a9de2d785acaa866f37a3695d25190e6bf8ceeb6cee885999b52c8d25e8d50bb26c38cf829e4649c41286e27835668d2f5d285a0a074f14967060817134fc5f9ed08c84fe6830bdbd9c919a33a4d5de4d554a100bec6f3b881cc36d92f1d8707aef60ca2a49b490e73209ce38a3ff6b1301eac873f41c1f988a32cadb81f4aa2712ca5181959b27d0e57755fd798181f65ae07255ca10528984bf8e7fe3cfad8b70efadeb76eadc1f77ccadbb4bed9ab7ad1618c1fd98278bcc9f4f7f533e77904dbb09788d6a874820108081a508f076184623620bd8990cf15cdcb8aee67479d9a03414014c3dfb7217bc0092e4a75fc1125872df46b75a3a2f6b58fe223e147dd64093a4fc5a588a016fc5605917e3805bc6e3800e8c9465bd5f0bb6fec2f5f63c7bc41900ad11be7400aeb530fec482af28605bf9b668b8e44c91b92cc6cb7b57112b104d02794af18535b4bf4c1270c3c4383c16aa59c500bd44d1bbd0904ad785158ab2b808619d14f703ab8048473eacf3b334b2adec9d6bfa883a142a68f4eafd1b121b4dbe69f40e9a31eedd5c8269bf36bbdc69f8e9f4880b2b9e9532b77785a51e303684f1ad7ac463cea28353c049f89bd5ca501eb2c0fdbaf15ca6f9dcea37130fb40678d0f50bc4f4ef4ad0a6612b0bc5aac069ee1bf17cbb8ed6e4446e4d2dd53baff2b69f05274cd0066614325a5b0ccaafdcf01c8bdf4ed8b6ef21d3ac3a5118ec25a21e8d162e13761acc3f8c3e00b7e109d038bc77c1a5eda5b38c6f0af2d939bb7277501179532c2dbad4ec48679eb768b36ad6d98faf7981da4f21c55e6a19a4ecb21fc819df3ee856dd55e11bcb420868a86199faa1ab41795ed3b01dd825fcec6b85b5c9d507a54eed6b58f5a4dc7426227efa9b1c50d83d5324b6821ac0d2916324ee563a98f2154a9b07763c90ecb52094356412e36eb0fde257f20f111e90b5242aeae56b30a28a02022953201890c0d1655bf0d59a747d283b23fed14c0cfc6b2148f4dc78f79f7c094f3d0db3a454c00930dde76fcaabc5127ec70114237d8249319ce45914025a4f4cc76afb24974ece205d5e299c9d1e3aa63da2f1b7700c1f062e96270ed2ef710c80193dd874745e656e93ef35495d944c3628b4d1aca4e66748b06f0a1bb6fdf06f969db5322a0e512dc5f2068677f3b5332236b64b5480d929438c9c47cc3ddafa5122f6075f114df81d76e1ecc9fe44bd94dbe75bda9c49f4bfddd3825fdcae6f74a934416026093dcff749d08d0aa6a4f21e02d2f7d908d6da117552b7b3ccb991851dbf3b9431b1c02de276a4f7e72607eaf2f3bb550619b3531a7eef88c118166c573a6715701e024ee7dfc646bed7314ae021f172a27b565a75fd6b4422f4fb8d648dfc00f747fa59f4e0f306bcd268a33e99a4c42b4d31b72d64daebb0682f64e9c864d8c5dea8acf9417ae5ddc661212627523d6a0716f627e8a921f23fa4d49c40852a29ad7430d7d1581f8fb2f3a3fd212618f9ad01686a430b33cd0296f86a1a0f161ca423f78e0c2971912b9e48d977a34d387a0786fa534a2dab951cbe13a5af4e830e213bf181a057a3896ebfd1040847f7cae968a8efb22748cf46d1247a5cd4d0e155a7a315dbd104d9208de9c18ab3cf067c703ea1c989dede581f35e62a74b5a18ee3cc8c21c7dec62680e795f9d77a690bda38ed6780e9a733307a3d5c5f562f501ab81cfc66bb2c3a31ce4430120458a558bf28f5f4148d2caa7a9a6551f622e8e93a00e58e202d62459ad15b77f45f9798c9a2478d7a6f18a1f62c35788408eec8b788e85112f108903a41056c7590fcefd643a7c32e7aa2e512dc0635eac41710b0603ca2550ecc0fb8e5b24219d7989854ea5380f7addb06217b6352a3aaa257c6bace1031b261c2702b4a8bae3ed41f6a554d6027d10502562048c25e6568f2de0a16d14a9ddd19d686f4ceb83ef836e3ef1eaad049be8c08d4f8c104c04b6d8322f0d133920a9dd4a85e5c8c0d8a529004063234dfc16b4a4861d71c6aaa905c86a373686bbd76a0a82bb02a2ee6a0572e4348f9bae2211ca9793c543f15d8f902e76eaa9634c4dd69436d270df53c551ba1d1203d28ac641b7427b3b134f3a3467f2be52b09b9988d8aada8ab0550fff9808b07a4638a8e04c4b355b2de3d896ff359399d5202ee8c402262815d3cfbd8aeaa2b8d47a5ee889232db93adbf539eb3abd9df41d931f861055a677cee6c32cd65955094feca8a7c286dbc3f9af637d67d35b45ff810dda5e78eceaf3970641aee6af803be11c980f0bbdec70f37e768eb5d363dcd443f59c7a27195e9d52bfca2d1159a5cb87ea86e8d6ce61c28857f308e9b67c261a083ef7c7b646d501cd55ed2da93fe9869e587e88d88897803dcbed79a1973e178b8e16fffb1dbace94290421e020beb84f2b46f38b613e93ad13948c38d6ffb263fedd9e44f08d5b9e2c1a402dd0ef73a5697c079f83c36f2f1a958df3d17afb86b9020eecbe3834622d6538e1757c8377c9bd18bb54b011f26f47123a1840801db5c4141d3ef4e78322538ba155bae3904e18be31499120691ea47a942d58fae58daa6822ece3443773cb33444f01b4b03a883e0a3dfa7b9131a130589d23ce6393f92a999a12df04cdb27b3848b8e2640c9f6ac0da42170e083b45c809fda8aaa1113163a0161ab3ad0f143a187702255d1241dbf71d248a40953c5e4edcf1bfc3c03f16fe30e8fecc23fc1c761f94b57e4cc3454be49b10ee66612f408346c8315a7be46a9eb2016952724be39009d04daed3b48b8f957d132ae2c63b061bcd2eefd5cd6898b53e560aadfe02f4e010eaee044d5a1eac2f1448af1a5d19cc1e35fe669fbcaa1fcc27cdcb1cd840bfa740763830e8acccd69c65dc040436ff5823c91c5920e644ee2355e1fb463c142373dfd1fac51b0d3ee2f26682c6774a779498009e87f0408a485ef2d8b31ea6f823806b8d788f19997bc9445bf20d9e23d80471be32fb3b31b393a882e7cb7ce2b5209f4b494f8d29a4d5da028c44948742def6af28272a1b60a2b90d4e5fe758240092e828d9f5d6b2370973bb9ed383ff8af4340019bc5f980a7fbd48ea6f17d5097ea25b53c004bfca04b11730cbf754939d08ca97397521ee5246c6a0a7b20f705e8da103c32ca32114ba4e353f473449c67995ab2f67f29a35c0de40950ecad4c73d1dbf2337a3772d44c4dec0956c5118bcf7bbca0379ad18c543ee0eb80bbfd554f4817d63dc1df5863c442b431f9ef8d27a2624e27a5fcf7b8db9d29660c46db2c573de3beb91c01e840ec01509ae8f0648631d595fbd55989de4e2aeeb776e16f532f2b6f430e24f6f1201b42f7a42a70bdd8485c1ac0c921f03de55c2de2383c7428c825a60b50199d088e0391ba2bef2c9d8e7eb709856440ea1eaf0d44d23c203d8c219ff24a17b4389519805c099b48aee6d1bf0178f55bd74fe779bf88f637ebfb39a61fe9886a825e30a85d7aee5919dcc99e9f5c2af4c2512fea8ddff2ef766a42933986226ad85f723baeec43a8289caf28c5c77103eb722a83ecb6f4d166441e79ca7f97f312c54f566ce9344aa078f16927b2d5ce539e285aad6aa0bbb9f6ca3bd430b24645e19b4999e1ffcff6b0f607eb17f9c63dd633ae9b36df0a277dd2a80ad6b4894974d1ebc68545f5c91dc427a7d65df12f74f3913cb1dda7793d075cfae347e76162c81bd59f6447b2ba8bbe308435784db5c0e1e7c7d4960d1093f968211df27f8464a045e743a9ea3b07398d4fec75bc28df0c291da8912e1edca340f65b3b6053ed28c38081696d1483c1c093766803e001a9f6948181c0e96ca3f77499370f1445efe01c9509c831269dfb365e29250388daa4137ff60fa6cc1a22518a1bb759d201658c87aa9885b0fd5c779c21e487357fdb28bd10776ee3272f1186f051df672fe3da3679eb930c1103fcc17edf755deabb980c1617e090790ac7edcab57bf7919d6d782747e3d9c73043f821ec43097f3d7f3e68e1cef92780bbdb473fa31619beb480c7cc1300374bed7e4498ddbf2b0e00350719407e3cce4d68241a7ac0e89f35f38842fa298adb60fe0e354a534246d9f629a1d4fc70a6b245da8dc4a355267514bad0fd26a5ded880fc847f301403d13fe8340228e9d41104e20cbbf7747889ed5ba4cbf7b18c8f592d0b7af8a8e888af4c35ebbf566e9b04807f2addd75d0fe6a4426eb6c9705e0380b1c9f2b830467257b03f88c62d418954d0fbbfc3cc1a6007c8222e1e98ef7c09ec01950a4d1ce33e6f9ca82ff354bb18cb262426833614d2c0ac50e18d24e10ff90b6403474a02ca9a7482e4c0163a9fb356a862bc33da3060e279a86461c00cba977feedbba177e016ec664ee372243f207124d9f34d9443f2b2f9a60ea4024c8d73330ea60501aaa3f7e07fe8bd847f52bb951272b408bc128a12fe2a44bd776af47d04875c50a6075af542155a194fe50c778789c0498c548eec7b1f74317005086932de2a1ab65310965e76406af9e5f6ada46bbed84d503c78526d36a0f5c0e639243c1746900a51cdc6d15b77eb5b94cd6a7c7e3f02882b1528519b3d5844608c71e5b9d1babc2150a6e6036669cb3fd58a16cfc0ffb5c32cb62d895f5e777ce360e4c02d3c45a9705b95f238a46326ba988c518c5cefacd5032dd3ad7fd096025937a212475feb0e08fd5081dafeabb01fc9731424fb12a0a0975680d995a341f80075e85f6032331b2a025c6a7670740e8a392871a4cb8d45fee99dd29fc65d60c5c729ab2afb7ac03f0acb079aac3ec017f0f132aeeaa741c381329cd79def27075d70582e932db78a82ec2b73d810266ae4d7cc82c5daccb2a2c0a2d0a3272e29d8494faa97267dec983c1f4c94a3e6aa18304eefa6e151786a3f70da5f62b8dcceedc5ee426f1e34cc02eda2a4e80bba1078d17fad76c6d972b0771f35e5ee1970d046d2423a00c4c4f3299c02c8f81723f520fa4ee62198e4d66a00e6141a9c8a9899d2f40ec31623efa0af9a420b687807caa97b231c9901e8ba8153dcabce71e62fb47c37ceac3f3f0813aa1345140deadd0600eaf18dd7449138de8d0e81f6d700fc1d9428c383870c84456e866b9b6672d2fbac6d5b2c17231c5dc3e7bde8085e5089d10589182faf45009282bd8a888998b428ed619e7b89cca7a0151c6d368fa0230212f0af403502c7e8e489b8f0d09a573cc3dee679e0da20380ccc350638320e6c69e71237d0c20e9521e2d045872a84e5c4ee6f51dbc5116e448f0392b1c8ad63925a48281ce06a0e6d79d36ab120a52d8e14ba678bb3301414cc7f0aaa2fcd499fe47051a508417d95fd60d14cccbf6c69025d67923309c6d01c7ea07d162e231e746e0384b24e217a26e0df220b1718b0346bb4c2ed19b1e5b064b406461e05aedd7e8b4e6320c76039cee280c90a64e487a2515cd9bf6057e060c320677e78138b63911c83213356274a1a460a38af13a3ebeed506dd71af644b328d5060ed989f0e0956b9300589bc6109bcd4db934221b2bdde2a93d0ab2035b246c46ecdcd0eee68c65fc01334f647b7de7e8a7197f0394dc27bacd8778e1db7c072ceeac757e4bb050e64e57e0898eaa199b17fa6e2544437bb9b0ff63ca590264376f90b4c3af0c004923cf3829761fe29d52fec11945284c89bbd472f133207d6abbd6aafc7e7c978443bb48d77ff5f5aeff0a7e69a085a5cec5e74ef4a48bdbc92300116364ecb418fb29f74d495ca682de56ebd59daa0423abc20648f0afa30a4d20de2f07fe980bdcaeffad3a383e4f0d8cc1219bf64cbb95c84e286223f0e2205803d7dccbcc772014f619a4157c0602eedc7caa966449bd170a50eb1f1c5e8125952f8ccea4b24c56587ebbfb7b283c112e1b6a0866e78ae0a5b0b4bc7628a28715494f55adfb86f57a23c5783016972c492665d23203ddf9ad8e18c54dd3bbcc606af23d9995e2d78132a284288749c826106b499aeacc34b859010ee2ef53147797d07470c740020fe110bd08728d436b46ed375e94055b950f976ef0d292fcc26f3fba4a92b28b105b5a46323a1b3a029260c5fa9b811b48cc256670e100f4dbef45f6bd10996d703c1914540eb549c599803edca3a1e55ea25b0f4c792c069751181f74aff49bd42c41e440e9b2dae767340cf317cdd66a7cd3a988acee59707b6f41daf969499e509315380db2824eaf81959fb150a3b96209f5bb6539756ffd6058ea297ef32c6be638d59e2ae73feaf8d1ef6df510a7645bcd1c2a689e8e95e0c474e34933715cb371d7e6397a4da66e5a344f1f3a4b837e49d08d25798c06ad88c3e973d05e2591b0fa6c71c8beb759af02f4606c8403bd614b0ee783ab2a175a1cc9f09e79ff20f023af876efa54aae3df989a56fb8f90fe51635f1785befd416b87843943ffab6ba9e947f79938feb32e029ec8dc1db805a0d7ac0d03509e81f66a975c21930fae949d7052419928d7e93541071dc0fe01e90f1e7b653e7c9ef573babe101cc831d4b75851b906aa2eeae3b8da0c15d2209ada404fc24c6ac4fbde916d3be16afdd9cb1f954a523acf609a34a4cd5afa3b3eae50e987d3b5d2f4fa9b46539176031256eb27ab85df80da0833ff0cabd42af081a9626ab16dae4ccc7d2048510106873853c3a5e10327d04d5c1e6486d9bc342c0657dee19e7bb99484b3d8be09788519ffda8b0cd1c8a90e8e8e83644fc9e529a1ab664944fa83cea157e282f5ba7ddcdfd870441df3e81dee9d226fa3ee8025808382125f8232a023bcc8ea76470b99af57332619c5295be1d9c0365af6b5616f03b6731a8071f4d9d74d7051e1d899a448be3515fb73bb30fb61760ce368255e1c4bbb5d108dff54d5e86c57647a961f56aac5748e97a837b98cefa75c6414b35c9cb12f17bf37064a09f435e234a87f3cab647fc5f7750c6570ff28d7cdd094fcb995103948a45669f90d93e3ba779ac4bbac2e3debc0dd30abe9a4f3bee079aa9a32e9fe4b237de5c08bd78b13e0bc3ed6a359adb2d7f2b630f8e8cd153f9f6c690b5d8edda554305a3d0e8073831483de92c2d59b5ac25bc764badaa1ec0f8e3ddcaaaa05bc65d8e7b8a7e442e69cd8193feac9cfe8d719cc40ac5b027e8edfbb2d035c35df4267284d1bed682e31c43b0fcf150c584a0126ff520c51bec4b6c0a08d6f6b9caa8e6183e3a3b7bdd13e9e590af3708ea47c21b780ef30f16381e36018e25e6302f17ecbb1aae024cc97fa8a7c439ca6134a652a927bf4fa679ab5d82358e063b29c2f515002a9543705dbc09e93790a6276aee8bd9e8246a3247534c916d575644b6a04b2a5d7fcd8e252a2d8273e268c8c99126b6c66a1fe324c6a28387ca390e55db06a90a8c752217447119301a629259fd90517f4255a9d6670e766305831669f7193ed3063a41b2044385737c956ab824780f80c2752139798ef5633cf377c71999b2bd77753878714463b04dfd622df331f1f4cabfb25d53a35954597fb80bb86332a1ea9d62fd8740ffeee4fd9f1c27250d36652bc13bbe7d910b31829b5025ba50ebf0320a74cc23a00f5ded2c607c89853cf63eccb02e74cbb9cd8c60c2a41cd23c3476036ca6d214f01e19233819a7377388e6fd80312edb4a3f1f708061c2e9e4514af2a7b50c5555cffbb16ede38827fe8d15ae8b8d82139dc58697baee6777f8e1712320ce8072e957706b5620a9ec4321b8a175b19ea8e950bd7faf6e26c858d572b6bbf795060a2c6a71c63a51ba3a1119a410d6d2fd9e41b167b0bdb5342c9a080f91db597025ca17970778bc5fd9e09d775c570461c9beb62d199a0d500812f476655ba4f07a678e6d072d5f8bed7a0ca31300f911f0ca007432eaf99928eba781209ba2639ba0ef516968519faf571789b11c34f381980d552fe43525b277e5da3bc20693b53c1a9ab1e257818978c42b59c91f4ad4e3a02a26e97678a4360d6eb3abfefca2199c8556cf7c4de848946bad8730db9553c2867c12077173ed6a1d675c0ce7b23b6ec0f443caf596630293a82d553406265f9e47bab1cc8f8b95700381895ffeb1c9a220cd30c1a249167fd9b72073112063518b44c0d5afb4cbf9a415e135335b85597678da70cc95e84a28840369699af01052a9008643bc4b04760fddf5aadd97c6511cb568f846dc56f0821cd29c7e4f48eed4885b301c61e6a22d0bc864ed9495579c18bac789e8040f118581bf09f4bd8b1a6a012610801674872af95580cecf9853e2d7b431e2abfd5c787ea84827fa861d00890ea5abc78e2567072393d860cacf390d16d06d08469b4c65c8bb7733aa56538f2f61342b936d348f50d37890cc95dbcaa700e4ef1aadc3fcc4a82604d9e7544daa8852c24db201ad492df7802f010b629dde3f508c1b642e1ef2d99b4d7abfb9e91a90245adf2da2704eadbec5a3a30f7b112d2e7a5329777b09e5bd9ec013def476d625477792e0475d6fb0d48218a17dadd18ba37c5a82408527781058939be7d2eaa2190bcc7a757d410eec028449cdb3eb1f862bf4a68f7941e77264d5928e5c973d41f45864fa207329ec4b5a4f988455094bc74c10d4cf30442375b45c0e3377356f7eca488102fe544a163370b706b5c2e95a6973accc9012df61ee196790309751d683f4434a669f22e490121b76815e6087ef8e7a8c68bd88ee208bacb88c3470110ac3aa2e07a9c8b56390cfdcabe3016efebdf1ba50a66aec0e9f1f3a47d991302b589cbdd4dea1c9cbff7fce35824d3c8b0b350ca2049fe0d3727a16f5628631486d00f1cfaaa9b7072037a40095e679d5a332be7183bcb6e2b5edeac1f34e6dcf5f50ec2a8e283856d7edba1821aa270983223e1865e83e09e8ab843fb5f93e3c5ef164f1bf4e673c690351a9020c8087cb238062571c53f5a454cd4fe0651e321283abc019d6daafdfff4412cbcf7edc6f7804867671ee8bbfe4c76e84a9e36023a08ae1636e888888b91c24c3bf0b386bd6c5c5281fcdd78ba5e5ef81a6c5548576c3da4bcad44f36e136ac4573955507c8fde1875e2cd3cbd21371f4bae309cc128dae4ea3d0d9bc5c27af7786048853b78b85057a3116cdc77ee461dbef022f544ce70395fad391fb5cfaad56856fde39537fd0d4ecde484aec91417bc728a1074f410bd5a7a76b8925a58f4a4c60a4f8355155fda686267e7cd2c2258fba6bc9d9fec696372a39b679a99652b8be18ff6b4c642569013cd8c11f695699dcb2679ed5185ffc8c51b55e8d7014599b864f130fa8d1e6726f9fda85bfebc64d699231c0b5994ffff63300f54389f52bcd427979b51c21d164752e0ef79c1f0352ecc8b1777ff46d74633a78dc7b47c6773dd01506f528d0a7d5430270adfa0918748b518d9115c08746f12c930f002e193bf1b4780e04a622bc62ce35d49d2ede4ea50bd42b7112bb42611bfa48036e1bf959b155cd8b27dc585e1931de2914667c65c0f43e1c5c6d2e7233caac25b6b0519d3ffedae520a6f9e851e10a92ca6d19302c20d1f6f73f1e74fb08c482822b723c645ee07884a2321c61ad28df1960e113b9512051eff788523b49dff03bb265a4de49838c9c116e351a413cdf6d2529f684815e32b92396ff920601ebc162466eb2ca10926abe11018222336fe947d47ac2fc91b4d52e79e18e78de201dd1a51fb1706ca440c222550f92c40824c5f423ba6b45f239183257243f2608728fa8531c6247ede3c772f0c8bb646f22fb3022afb921fd2df0759dc27a29ca81d11e61825cf5852fc73ed39f47ecbfe811e49fd5c3c241561a909c174abf15be4b110688ce43f416ede8ed327ef967211681fb4e174a3bdbfd7f797401b6a3c55c7a786f825be13ca0d3086f159eb9e242a5332e5a41be949778cf5606af05061a11368675fd2c06e73fb05909d9dab7e1d56517ae792594541b76adb5c97570a6542afebfab6695a46bee10ab3fe597d2c9b69a9842fffbdbf32fc768f41687f4823234e8a6a887d50ff8a9b4d8a1c2a770604b2eb8fec4832a5aaca14b862ce696d106e789fcce72cd13a59c14107871a43e909dd357a3eb0720916c840cd6fb97ddd11a45b910257b601074d41a17bb505e6c3e42a2996ee81108fb6c42162388f1ae2f7c3f34f9812bec9013932d111e03d20f29468c08ba635060bba4d1e4b8f834a16de23bfe8e284a859664747038f0ab76fcc1cfe3d0f1e4c71abac02d1ff877024828fa262102e6282d678473f8a7ca721494ee76c58164e064b580262a82f299d06c17b1cabfc6e78bb5e5fc31f026a24c03dc777e71c04660e0b6c65f3b1369307f88d9a23b66cf7e0107ff2f525f7c8048512132dba7ba6b36fafe8fcaaeaa43a59c99e254831738c54da53909f79be6f32fcc561c8910623bd5fd5319e4f8f595e95784c78fe94c192f9f3f2cf60d58715e6572453fa032bca5d77d004e96bcf423ec446c0046e4d8cd4e587c9424f34ca306aa39d41ea9615ac5a47769cfcfd233634cb9c22f54ceb2f77f1cd1c6647bc6e91b73b16c72a273f6e02ab198b8fed5590fca8e5a4aefff4707bf4397e37eb93ff3cf4ee7a3cd93f2e4a15340ac600f77736923c3dbec85b8eb8aaf21d62a9a187750f8f2fdd8846cc3f51f95ac8ca7e015880c9e76007dbcd8ebd4bf14fc4bc9978c22db0eae72a9332aeac7abc434b4fd3794fe7a0345e13c0052f625b8d0e31bebf395675daa00c63b4386ecee3c3fc8a84e040fb0fa49bfa3fd4f10b99f6eedc9a3cc4684161145ae7c9c215aae4a25a888a4c57e0b660e81666222077b2879385d5a905560feec764ffe3b9d92b36f6e25730d223bd2eafb1213f43c946edc65507ff5381df2da7300b37ad5d23df6949572ceb9c365b949623e51c1f541e88edcebdb2b378222461185a3c6d7abdf65c60c3d99eca299683258947ef1e32ba580f08bac98b325d07efb6843ce641301b6f9ab2b0d248afdbae6041a25496f3a993df475b1be5ae96f2032e17e040b4bc944295d131d6901247a6f9b77bf10696a81cd639d12a587af5778d52e2cc1cae3430c9369b1115d4cfa4b6e1e3f8c605fefc44ed2cf4f2ba36f44f2ed826eb75b699788ffc2484892776e270f7161eb6b294a251810df8221965f7e7536dcb28f39b9b197be5309338933c0b983627d126dad98c37ba9471862126b03616c62cc9e90f6439881f98b01209d538650085b1af062ca24b76e12df0a4f653cb88dc5ea92b1196118c2bfd9746d2333f9128c5c390cce7631feacd9826508ae63e014fc69cd1591ff3d78200eb35e79f5a6489cc57f287383a1636d305432fd7a00a1eb832b07c240aaf0f74021f14816879e292f0caaf3c1e0abacba1bbc6342c090c5caaf49e1254aaedb31ab6a56137ebd7af617507ac34feca8fd034a06e217c4417531afc4d45b334b54f22846fb1a13817ba407380b05746d3326f6a9c3cdf9efb28d59a25811d01e6796101d84c4ab1ae658d53c4958354ef32a8b22d63824fb8201c7073605e838c47ef4c20fa440353e9105439be41af44afc5c1592edb47fdf0d2edd33da0e59893b0444a951d1b17036971360dd86722c8c74c9e843b43be002e8bf1666724af161c2a7e5c67a7d983075bbbca7e3a45c9774f2e7ceaa151cad114be4d68e4c73f018f4453d3d63772d3056b8fc8d9a7b631ce843f1f506a2736e10118894212c48e60d4c3813487616c48290639ffb1761973076daddf00d6f0206362f976847c4dd06ed153c3608bbe8701f4844c7752788df3af33661f0a955ee03592748b68f55ea64e736d94b34d3bd288a003ecefe7a4d4899f7b458b5bd7ff3ce0053c5e592060e52503586dc51f51e382685aad3485fae686ee407c652da9a5a74ef221f0429cc646ec387570c7b5ec0e22f5c6aa4fa1521877a6536b2a0902a7e218505516f05b2e9af83bf008a04b9c765f7addfc05d8155231a04ca01930490d0044637f33a390c8af51c346c71046f4c2cf5e6246a986d74957b989336ff88fd33f12ca3916cd1d493202785fe3b92e3a59aaaa927f77a830de0609316f91e207ab4393daa0e8e6647a2d6fad4cf38f085c30ff6507685f63891c0f983a46b3fbd1137a49a03c1bc57f1de132c2660655e97e12550712ca087ae46bf5d5d4ec80f39dce597c212aa868afe68df4730a8e8075169e26827f2ce5c06544e07ae80ac9f047f42ecf32e9bd4d6c3b69dba9608dd5a3223e348d278d26ffdfde668bedf1c71704b7b631b43bd22258ab15da6edece1c1c1a18fd35bb3a71e594b06b4c187e0ff16ed34e3f13947677ada95585134e7ee4dd4b971be88a1a6676d8071237152ce5788c4b0116656b28ebcaee308d876fe7653ac194708661e9c216d38e7fb1f6cc5f582eccddb5e4579f320a5f0b8c381457097638c05d00203c8080749065dd4e18a89409cbe2d43fe40d91ff2c9715c4739e62c1cb5e548847115d9ccfa417c837239e0911196d94890325c9a42be1989e60039ea85f8e2e05e73f8288ee73214f26db5a691f5355d116aa044379a53d978ac56a8ec8298db173f975baf99668cd8b4dcde695bf4d9de9d2652d4d8923b72acc0cb7f79880e96a60a5829d05e937f231c5cf6a84a7c3be20a500d742745859bc36714f3c2b6698853390bc77e297d16c76ef0fa3a6180f36fe85ad27a8577f1689c590b380c335857cd8f6cefa3543eee831d440472726696061673c6b543353b654095b8c1203feb162bf7530e3f8508c3bdbf2eab2a0bdad4056c0e4843791e23738a62ae26ac0ff7595c92b23ff2c9c60acad3a19f042634836932e203bdc95b96de3e6e5b8fc7893273936e39df9e7fbb55000ddca966cf6291e2a9695af9d88eab64c85f52a7fcfcb1063b582b25974ac0fd683fff06501476c2883684084003ac53616b880e75640821fc702b13649b325d5f2f10cc0ff20ae1ca1819baf44e0a86f522f2fac77f3b9920cea3ef92122cf4a982121e42cb5931a003e6308a0770ed44e323d63fa58477d5e26bc9be5cb260231aaeb25744ce02a427c2c807fb8a843d4646253a86e02d0f3694787204f91d8071fceb81578d353ea0f43d601cae583bf51d1d1d11abcf105ae21c76e05f55d0c9ecde434f6bc12ea51d89c8e339d53a49ef1e3993e95a1eadf0f73189f93970f5fd9d2be74c13d1ae83b8174f55eca4fba017be8250733ba840255830320f2e4292508e07ebe2f12067a850ef5cffb9dbbd0a494881110d78c72ddc4a77669660406c1c3c0442c495cf58bd872a0c67c9b0435ea284218a16fdd9c3426b263c76d19a265bd312e45fe103df6ff5c463bc9caf29dd8bac1209f58625045c3166fccda6350c9a7b8b8111baf1f9b143a0da1179f884f82aba9ef53898b1d00323455d8dd1c6c8fc5f31fe84898525987ac6bee417e7fd6856c23b105944c8a4f104e525697c3096e7558638459c7215db1185df3145a2d8b2fad47e11acb91fed5f5750ac3ea564a83174549f805dcb99de930ed5a769a36735d705a54312d3d3949d5b4ab22de5d93a95c786d00b476b6a82ff6141437446708dcb99f290185eeb2ee9ab53abb0859d58751f1184babe12fa3fa648968b606dc32d8bea618b0689b56d87e9f14762b9cc6598b34e3dc8c34dc12ea37d24d10f23e090e65cbe2dec66ca9595bbea4c7326d11c2c16e17ce7ec8875301f9825a9494727107dd4fb00878c929dbe85f53a095ff107930416d8a443e990442b6804799d6df27fdab56ea2e1d51ffdeaf52b4e4ed81047100b2352bce053889f423372d8c7c779bdd0ce6543b1da5d877fbe71c749df3300503f02587825663f223bb7d758ee91c905eb29b872894cbda8905a345bb05ea779e1860a59dc62f4e897199e082d097a9680d5f79a8c87292301b3f6ec3a782c5d8ae263755c35aca539a5a9e208c85099ee767816a8bc57a30e4270c358c98e4d783f871303a693fbc6bb6e00afc71156b3251262ee5c14f9e26b0d0853f631c0576224665f48b03418ecec132a8343b1038d73cd4de5c06bccf2ce48f708d085f9338960e96203838d5fd06182781d6340ba2fb63d0e2ea8e1650df02201c3c6dcd3f4d05bb9388c2347ecebccac2adeac4df79b0852d27890b0f24ec3eabfb7f7f81191a1d0042e447d1252552f5738434c4b06b5a078c1ed51dbc10678dd13f48c6b5ddbff73d89dcf9a949503b9e602b1eab6a27a30bc776d440a9433960a3032bf3bce912b986ad185a6f6dfb64ffc138dd00658e30d7593c5448dce63af9289e1614c13ddcc87dd42bd567e4d10036874d0427da71fc5d77b2c6feb770dc3b05df8136b80d305422abd0006d601fe08634c4bbb4bde06fa740cd66b74cb1c6a6048accab5154c1423a1373bd5670d5745d6e2864917b19dd4b31040de64bf66418a19d520b6402c3369b5dfc3ebf88a6c524dcb41a10fc2ebaa06eca3091f4ca5c8f69d7f4087e7f2f5f06803a32eb86a57bccf92081a56a8ac0ea22cc48c16a4bb8c0efba02e170a03939ee5f3f588dda77797b9bd34a85964fd8b932685cd3ad5371cc5b1990fa5b6c1c7d5c66c572385d646f91a56cbf468e963a3d65cc416e3de6a886f1a4e680b4c2be1c8c0de6b55c7f6fedad4d344b9b3033efceaa71ea2bb29aca97fb069efc4b459660a222acb7deeef46b225f05718b88c83d47613fd14417e868913401d7a34004c75631ba585c791cb708c975940f6ff23a666cc698c42c54b704cc553464e2b93785e3759877dd4892233c00428ad8b88cc5bed56e4205721e325f40e0fa14c1adb1daee6f8c2be66317c05ccc12b40d2bd069f10d6be53d9b9ca86c92b0392d04d679b09b22d93509355c6cf38010b6269f544d028d228bb50b92e64f0acd40e326a29fd44084da1d5281dbd7e50b3669454b7105a23b28d27bbee6775b28cafdb73e0d524cb0491cc4ee19d38dc1384930eef9b9c6bbd073ee442affc0d90c755c250f073c0cca26a03ed936d941216f763df7d5c58872c3d64b43f5afcb3e75713dbc9ea28eeceedfc7e927a0ad4eb6d803d2a3a94b4aa8f7f691230f33b9ef4332006e3ef9321385ef935b2c49211f9426c861ab0a2d32c2de6322e42c116746f52d8ec6e48b2326b91eadfd11db390c6d65870994dc091c8a01972665dd1c5d525047221e24d65b765078718916b5f8bbbdbc08f89c8f395b1ae6dd3423c8b4d833712164aef89fce2898ac65edd6601404ec593a0d9b104bcf88ac81bd8dd1ec1fd2a6ff788e3775d744066393bd8e22e24839c0231f63b0fb41929a363009bf46def57111e5150041fbb6fb13f30b672fc414399b189bb65db63907752676059354b17e415fa5caa7f228ee87b7572c17e542f945ae2b4051f2ebaaaa4faa13ffdc11ca55370e6c6c85f9428aad26eec77b94d433dced1ac0921c68178609b45249c7867b10afe94f8447279da9b8bb0cabc81601a58b67866aa8a558318a7f02d37edf2e0b7fea12c6b659a788ece52847ac05c5f4e865d71a7cd48dd7d872d0e44498ead3612637ae39e6165fc6ec5937461ece08f0fc58320b7e08a4900ba40963d80149b5817c93f243d246135a398c9636001d80419e5f185c79b06ba4e77d0f474874e4f7f68347483ae1d1d326c01d788ae336b783bb801d9b57c3f9b5dee943ccda447070f0e6056c35ead58ba9cafe67aee3723876313ac06aa4a73dcdf7b9e1e8626d784b7259378faa57feac5edfea71060bb9871aacc116bd4325c158d8af44703e15e8d50a288d4804836907bbdd9680b9fa4e250ac201d523cd458e0fa4257f2dda7e844b3ddf44f93008363ad2fedb178dcdeee144f6cbc74df3da7d3935ac5902c74eea1e2576394f08a75078c217cd911f705b2e57be7d0e6f14dee9ef7cf5d3ffd5d92db03734e1d7c076f1013908388915eb44085d5746932c4de8e9cb3c5e4921b0409e7fa21dc918a1c783f0322e19f487202a50e75d14224b78744d7a982416e731866f410f826345fe0c09d19d1a6c7d14eeac4b11ef73928bae7d022e730237b02b8ae697ae9329c3121e77943e29331ba8c58533b364cb94a653ccadd37c8a055af4bdd338e8091bf755bfac3bcc0935ef975ecbaa19abf015c12cbdc54f64173b121cc24e4d6ff1a2b5bae372e423ce944d11648536a1f9d1bf87982add073db84e09ccd98d78bf76e4965ffb4744d615bc5a2098ab4b88bddc94a6e46c05d0803499388f035302ba408afcec24b36203a5e150347a0960a56ce8797c323501add0e85f93f028d603278203d0e67215d2bf31298df8c9b152cde22e69bfc06939d2703f891d3add337ba1425ce50de8e32870b7fce581e7d194bec4b4bba8d4b9e1461c7d04c1719ccfb1c3707e517645ee7794dedcc4a8c1f2285962c2a1f5d257886b2d432800d1b977d44d3fac92e856df2a752e6d2095243969f7e5ace93488b3dac79fecde8d1aa47cee70c1a500296ab56ca24ecdb720b9f315e87841e22619622616c242854fa118142ef3de983c807f3971eed213433d5f63911d013e8fb14c1417f55317c1709841977be7608ebe128eecece2d18c21825930b96dd2fcf8272db56e2578bf9217dabd6a5161a3591e4801ef5200d2274501affe9ca461561d56c5494da56e6e8ec3d193b153ea18f320800a10a6beb3c54a23296c37c454dbab3ec46c60bcdd706f50fc1ca008ba05aa0837bd8c819476905aeadcdeadebf8df9688a11c2672477e5d72bc5a97975f60a75be7531eaad991d3d61485e13c7a01d47f77bc7ec32cccbcd4190b945443084ab9dffd38210bbdeaf744b7581bb99ef40a41f0908ba41e5c45057aae9c25a22a634ab050a1493ba9a8275b10fdd83085fb708b09663fa11484889fbfb6d9fb9736097b07b0d2116fc9c6548ece74fcc9ed44e48c44bbcb34e05ec9f5b8da7056e34c5d36915d1f79024fa5171141744930b4bfa2640fcfd6e593fb961f68efad768dfb057604a6104544756818226df3baba724033bd3f86b3731d61b0b40140b64a030204a156ea708849eb1ea1386d0e50f7a27b1a2fe73c83f1719157e4a6954923cda208026f642d0b0e2385da7c6e0477f4c562e16541afea1cf94314a8e45c6743f531310a718b234c26a9514143b46fed2a76a51a7ffd7f6d016122ee504528f8fc4a80781bcf893737f3110265efae09add52c59eb03a8a293663f08733d01bee9c29adf093d0e6653bea888276bc406c5a6503c13c491479a7a3049179f872d4036e21c6e0b4030342fa0586db367c4d1b391fcba54dbfa2b472ad3c9828b0a50bf24fdb4749d2357fae91e4aa437159d7a240c294f6f5b1a906476998ba16f53fa9cf404e906656d8cf9f217b41f8469e5c77af0da8fe70b47415c66e4d4aad911ef43efb582e8ab10fdaa450d7ddf489b5a4666ca7500202714ccdda787205425842ed90a6bfeeb3cb2c0c14d8226d3ac15258c647b3adad14db452c89d8a7f322ed21bfffbeb5288032c707e0f21ce13eaae1a409ecb5662f05a2b6a7b73b2f1200855f7b80a10166ef667b0c8bd43e531dc57ba72bb83dd5f3f78a96048ed26753031517d161906c573601e08374f93a322c450d241102e321a469464770f64f48eda690bb8ca60b4d0cd210c504b36482fdd8168943e0c35f45b519aa27f7f58142ffe5df73132545b0742280bab6044d9ab9d82c716ecfd006a25af30caebd0b4de87e5e05ea76f41b8c225a304255fc878c4dc76ab5297f410543602d3cc8b20590ab682d3c8aac1864b13079946495412251a3228a114300a36f2122195dc8da3f4883319fe03e2c8466d14098d67208d34a4362b41a197e27b7d47bf16c6feca97a4abe11b313a52163ae8a120c96833e8d9ebb335009c1c13a41027bc0ff45a34b8496c4a9bfad4d723c67ed8478537b248ca71166cfa7c5e8d4da105720fcfe077e8977c90d5ad75e5673c361bbc2a2fff9eb735da16297e45561dfd708157ee8636370fa5eedc0b1bcad3475bd57ab69710df2eaf148f4790a8d806ef716a7d0eabe3dc2273da57fcb6185be523824713965cc2d93a7d84f8e2a956cbae13a6821d99031cd1eb6384e788233616ab798774d50361da50a39c264fcb687a001d27c9b9ade8277463808c22c8d2521ced81afb066dc6669c01584d7d41e0fc4ddc2b5393c8e1e2210d65bf6f25d2d92f96d39ce22fc375be4504c294cd5a193f8d51c64f9991e7f11db2cb1a1a06f6f7923dc6cfec224910ac71cd7c0888e118fe20565af157efd10801c14f931872a3c52560682e3793c0e266082f86397ccfcc09046c7814e80c5499048e7cc59f134d1040b2743a0ee7421b6a58f3896b518f3ef8575bc2c226396aa8176ac38e1e0b6d5826d57fce28d5b94f42c52c776194ea3f0995c4052bf401e001892835eb1032f0b6acd863d3c8de7bcb2d032313c0145413377eef5c3259c8bc7d71ad5103d37ba74c5d9a9239afb9275df4de5946604b95267761a2ac88d37b87a93a537015b972c2acd37be7ab006bac30879cf10262a6f74e9308ec4dad0aeeadce4aef1de7997c26e7dfd92fa77e39f5cb3967370ca55ea9573953d565e6ef6ce377aef13b2bbf002e79b2c5c7e645ef7ce56f875b1127e011237ae7144b2f4d333b96d0e0d23b3385ba4ef08d3561eb5145effc45a3048f392e307adcd03b676131c22b451b8ea699ded9ca65b212f83a783a783a783a3a5a7468fcd6e1faad33e3b78e8e8e0ede08da00b11aa11c9b72466f1d2b2ac6aa701489d1b6a6b7ce3205377e5059316685ca4b6f1d6606362d1628e278bc68a2b7ce57076ba88858020407dc9dde3acd0d6d34448cdd200b3ba1b78e73ed32ad057ece33e799f3ccc9f992939393939393137699c2029f2846142312c9a4bf89555b442291889792b84c2989c0f677fbf7d8aa4daddad4aa6ddbd60d43a55c2957db52f5adbf5b19bfdbadc7317eb7cfa51637caf0908091f2a7770ba20c101155b4801cf9a2775b1508e4ab8d8e89da9dde6d332ec51a352f826411f9a2776be5325909fc21de106f88371c0e876e180af7eda1dc631f2a875bbf87307e0f5ffc1e829db953f35a92814bd37b6815224decca96892c48a2e83d5c0eb9991883060813237f7a0fc754296534c78c9440a3f710c5ba03c2268f051618bd87415a5e2fbc38a350fdd07b487699c8021fe70f3771f41e37717070ec70f21e3b8e1bea6e38728f1d874acdcf6f9c2aaddf385b59bf715cfcc67946c1f8f2248d1798df0abd71ac8e445099e993bb818489de385f84cc283342ee041817bd7198cb216bc25ced6581d31be72b014276803943c349df98de38cd0dfc41c9915622cadf9ede38ce1b97e946e0df74dd74dddcb8f0f97d7383f5fbe6e6e6e6e626eb9d383182c519b0207adf301f6fbda8fb11e3cbc9a6f70d567199b08ac017fe2d857b78d9f7d8853e727e0bab5afc160a8542bcc77a4d2f66ecc85240b933d35bb862cf8c2d506fee050bbd855f5b82805b023ff8a717d40beaf905edf21e7bf06f07e5cc583316d0c93a59a7df6367e5362bf780352d1a6323c8aa28d13bf8e5686d32b4aa7c9960a17790b9fc1d140b167f0783469efd63edc202c35640b175af7e8f9d2fc7981728d8aad4d09bb502c15d8db2b32d5758fef466974a5c7cb900b3f2922589de2cf345901d49d65c185912446ff66b0645dec89401db6282466fb6b94110401a65ae048e20a337eb64f19b7daef8cdaaf8cd6e3dfecd563d7656899fb0eff5efb1afcaaaabdfeb568adf2b8adfebf3b1af6feb6ab7e6ed556fddb383b1460811b4a5de2b93865913cc951c42c2f45e979f34d186ab4dd3ed8916bd57e699e598963432828ce9bd7e4500b02ccb8d13cd2a707aafcd3628d29a68b69861f45e9d8fb52e13aa15f8d8b7fa876ea5477c5badc3f9ad566d89a9cfc7aebea52a5d0a759d2a1e092e5398c0f404295fca97a676790f8556a57937bfd313bfd32db1f4a943ed2e490b2836cadce99d5abd881e6d26a298ad25e9a177ba4c62c0b5c0c7588fcf0fdb3d5407f808f58de5300462b84ca86f1470a37b61d4dfb8caea37dec2267e63302dcaccb169eb0146a5372e92e5448a355d41b4f4c6cbf700c7b797e2ad048a347ae3e6e3112444d8a0ab52c24b6fec7c8c6770a5d6cb84ba53963e2a342c44c4b0e83b16488aa8d1c1e6a7c3c0013951c6064895dee857028c2cb590a515492306ef3061a446959736217aa3ce67b28655e56a065c5f97de68536fd42ef512bfd1278947ab7ea35b1ffc8d569179ec32b81d846907184ad517fb013094633ce209158152d5c0c80a2a39bbac2b3c111a2b876c694ad982c28c16bdf3df6759173360726b3ece6060089c99738c14392c3a2a854ac014316b28f6c0dc35d1180ddc082537baf6c8e8699e21768f3a8f908c212b3f95e1e17ad49ff8f2e6b17ad425b8e87bd4a7724ce1c8bb5857ec7ad48b5b43c5ad471d4a0ddb840fcdd2b39e434cb251757917958f3a86193b7b8f3a061979efd03dea99cb8edaa39eb7e4bd23f6a867bf1dae473d9fc97bc7ea45de99af44def9f9a813b58d3dea444df2cecc475dca46be7ad4a56ae4ade3a793f7a84fd5e5adf3f6a8eb38759c8f7a541994fac62386a1841e74c01e750f25f2d6d97ad4a74c90c83be7f9a8bbdbd8a3ee6d79e7301f7509cf9cab475dc292bc897e50f21e750b4ff226be3dea18bef226361f6d5b71447557555555db54b07916c4b34e24265954a9fca0b7c464909854a37a8ce44d643eea165810af1e750b2bf26efd1e75e792f7a8b7742ddda31ed5f584cab9f6aae37058a2f6a87360cbbb157bd48d692dd7a36e44cbbbb57ad42118e97bd42110c97b88f7a85bc8e1f6a85bc091f7b039ec4292f770f9a8bfd9dfa3fe6579e3e83dea1a62c83dea1ab6f2c6713eea503c70c01e75a8afbc71b61e75e31e4ed5a37ee377e3f7a807e1509db48db1f0aadf089138f21e75e48dbc6fde1e75a9b2bc6f9a8f3a8f91bc6f988ffa14919bab477d8a2c6fa1dfa3de9495f7a83761e52d7c7bd48d81658fbab14ddec2af475df310663deafa2b6fa1f2516fda11dc7bd49b74e41da47bd48f5f79079d8f7a5392bc83cb479d08759e31798f3a4f98bcd9b747bdc396bcd9e6a32e0585ed7ad4a59ee4cd2e1f7556c92a1ff5a835b549a9548e685fed79150dded35df22a14a5deab50d2ec78d585c4a4ea6341c9dea36e2149de2bdda36eec527bd48d39f25ec568e4bd6e3dea1b5059ab1ef50de8f256f9ec1ef5292a79abcf477dca4e1d7bd4a7aae4ad321f750da85e3deafa2fefd4ef516702827a843579a7cf47bde895772af6a82fbda55c8ffa1294bc53ab479dc9aeef5167aacb471279aba81fab329196bf479d284bdea8dea3ae9f728fba663bf3eb8a2a7f5d1d89a1b052a9542ef5ea4a4dab0b53a818703dc1eaf18405972c7a65c3e62dc75c123a135ef4cebf367936e9590f12932c5484bb2023bc28955a75e185ba5a7596985489c9354a2c85e211e311830acc9b47ec51df3ccf479de7899f56479dc7cdc98fafa15f5de511e369f2c83c6af25651e7f1cb45be6bf7a817c564c04f1d99ba521394b838a45fefd39deb9154d3a847b6c85b7de4f2ba29bf47f9b7420d30a0298c1568c831c837be542fc54be9d2b7b445c2f9a82df2cbda2297f8b02dd249b0455e699152f66e5a0b4ae4dc9758d3f97cb31ab6c8326d8bdc8b22b6c829392d128c4e8b64935b64959d16e9f780bfbebd3cbba0628bf4c2d322a97000efe13efc87abaed49e1699e609a1459e89d022d3f624b44839f4deecf8b4c8b8092dd2cef97ca3c3d363feb4c8284de7f38d0e6f0ba845921906b548409f2ca4d022e9845a2497e71b1d9e1e1ffa656c917820e0535a2d9fde22d78e2d526fa8453279abd0229bb4723d764179c83d648bccb3d0229fdb917b4a7d4e7f442df26e8bf925d674fa15b5483323b87df7af2acbcda8456a396a9175482db2ed2da945b265a14f761f23576a916d965bcc2fb126df528b44e3175ae41f538b5cd3d422b708853ecfdfaa1b861619460f8feecd33b448351a5a2416a71609c5032ba51f9fde8ddad02203f930f6c3185b61bcf5a9ff3cb5c8be29ace23c6c87e5b09b5a2becc93e502db2cb09fc9456cbadb7a816998503a51f9f1e5e9351541387166905ef3bb448373f00dacaa129eab74faa45f21dc07d38d522c584f0c9429fec3e1e5ae493283cba37a3e18716a99637f6942f0b7d729a62a6046e0c2f72a82e33f60994e5d4f1d0565f55551fa13699fded2940ef1246dfb0ac4db6b4fc7a14be8c1fa27476609f618eee4d0e1009871a6f69c15f3f3d06ab967fd1aa52fc50056cf2e9315551b42a137fd14600fe700574f2e9b1bdf9e25b9babbf6f6db47ec80252f9f438c4c2c3da0b02e67d7ad4c16a62b90901cd7c7acc5858374fb7119f1e874f1ca7da8a4f8f3a5fa188b359d686c67360a2cdd6ebd3630e1d1f7148f39953f6e9315b31dd3e3d0e77d046b0fd451b51f6c32c3666e539dcc85b15db69c3e5d32371f9b6dc2b7e81b53103012e6f15fde241995d24bec2326ff5873ded8a4f8fc56573a906618b8bf9e931e78b4a86117e2c954b2e54c2d8a7c71ee2af422728f4fe3a4171e6873ecbac2707194b2b372119790b873f6ddca7c794c593451e90944f8f41165fcda0963da24a6c84ad7c7ac47910732885963dba40065d1e8494a150bbc28fc5d2d8b2c7137c40e633e8f179cb1e413082b340352ff442efd8b2470f38a0a4aa5095b78ad796f8f4287ccbabb0624573851ab24db55658adb0a05441a7828fa8658f1c28bd8486452d7b5c0036c2d8956120a818b5ec710007508ebd92dc7d1eb5427e55fa3d52cb1e4360238c9d4af941c430296aaaea39ccc85b18a5b41ed957e1f61fe0172eb5ecb1c9e9c55760d1f4c30b353e3d06558ca97032b5ecd148c9ebd323cf83b0cb5b1d36355554a9e0c270f6e9b19881aa055d0b3ea10647d63d08b9bc85efa4653d02a92e7c9c678ff70d4dd9df37346a3fdc40d5f7e971bddaf3539f5af6e8137406c66ea947de42f6987ba8d47c7afc79a1bfa8b64f8fc2b1372187b84f8fc1ab2be6ab431f7468d3e3cdb3c7db6406925f8fe9e7fd502acca747b5ef4a39d592f9f4187cf698c2eed5a10ff0d043cba289f0fb0a23f2167eb87961106d44915f8febabc77bd666caa747f625b00d33c4e978081cde5b824316071879ab6900503618554b7dd1d8b85969230d7d7fe7e10af4005606688db81d7e9af5598f400f5865a0ce30a257b40516a0985e8fea0c235a789729be1e1dfa200db63a5d842d87310e342aace010a31572c161884e5b64e6ad66f5aac452d300078abe78c3e5c095b75a6c85b62040a970b5e4a36844425be144168afba014ca9a40a5a88c02083863cb412b6fe167d092b7f02b28f3167ed1072a640b4148dec2e7b045c4aee85c9817117a886629d1a66d2c097ca2d963d3988ed24206981eaaed7a44b5c64e64e915bd2caac58c8a4bb3470b5c7a58d456a0ca5b7d1051f2167e0639a4f6a6503240aff052f8d034c04188e895070a144d032216bd0e5dbcc1439bbc85cfe1c5527b532834147eff41fa6117da0a29f216fe509bbcd507312583a8924143cb01c45bdec2bf291410eaf8cd4a17a6c631d6f0e901a14301c0792bf4919516a6502bebc77b14c055be8fd7e3d5972880f455a856692eaa15e2cb5bf820e2f216fe5060deeadf14eabaa5c5e1e9e19cbe9e5129fc108278688bccf2167ed1917cf3ead09ec1a7432d91141f1fe39d9b7b84557555d55555d3344d2fd4c54ae90c9f2c34c21dd2955d57765d5555555114458fe8df140abd47a8dfec4c78d4b70ffe4bf43406bef8c8d94f1195c2ca160bd1b9185f7c445174156223badfeda7970f67154d9943ec6178ffe75ee39098e234250a000d40ea2a7a8df0509b53a862541d4ad3af4fd3db0175555585298aabf2abaffef00e758c52544dd37cf6b7ccd848455140617ac34ab0fe8e7b05489552afa85f85a17d82af30dc407f86101840347d60f270616a494aa9431207a4a82328a3a7a20d8ebd032a45e4e4d83f84182bf3cbd8db66d906fa8faab0cd3d3e418e34526a728a9aca8021a718e147688808e94286a70eea87c0f0c1c39454070e51504f1b9c9ea2a650a90c1fb05f625e32762298d887007154856deef10972a4915293531486a69c62841fa12122a40b199e72407cf0d034c52475a1c31207a5a82428a4a7a30d464e451a1c7b06548a2883637f8a42a5304c717569c9d875985d203e7838aac236f7f80439d248a9c9a98929a718e147688808e94286d5c31453070e51504f1b9c3464b8d0e4844a35452db7fa32f69cb5e5614aeaa80adbdce313e44823a526a60b39c5083f424344481776a43a70b810b504a5f494b401c9e948835186220c8e1d0995226a72ec179a502926a7c78e565d99c9d88b5657521d381c55619b7b7c821c69a4746129a718e147688808091f590e514b4f1b9c3464c0d0c4849f90179a1ebb0bb051aa6c93b1f3c800557288823aaac236f7f80439d2684929a718e1476888a807ea698392539206a40c47188c9a8a981cfb102a4574c1b113a152169646808dd20fb0510ae1041f403d6d38aac236f7f80439522929a718e1476828d8e26370835352060c4d4c17841c89dd0310f480c9d8237000041b9c341c55619b7b7c823c0929a718e1474882860c18909a8e988c2e142d39f61f548a48c9b10b39f6077450eccbd87d38e84043060c4755d8e61e9f20a4a39c62841f7c1462683abab0a414c12708fb00161026639f7080056068623aaac236f7f81c19e51423e0b4f8f8c37461c948a928c9b1177b22f8a05247418f7d0a006b3276a0100060bab07454856dee312aca29de2c291521e5e41e54caa829ea4bc61ee414b5a4947454856d2e22cac1470a49488e5d88834a111939f69c8c4a158da0e7b123957ace64ec42464a4948474755d812e13cb1c5471cbfa8d49163c7a894910b5b548ac8c72128337663901f19151d55e1459936fb5ee4d859548ac8b10b51290b3dc5bc8cfd987b8a8e1765c24e74c42813760b471565c243437ef113d2b1aba89405c743b8674cc678c8c211464e95c59d9c0ac7a1e3d18d47a1238563d011e8f873dc137c5297907a842384e3be7b9f7acfd1798ec5e346ab367af5a9e7d4758e1be5fad4738e1bedfad489c78d7e7deaed71a36368d95f61ea3e4d03f0c0054bf40b43a93ae3dc0ced28e7be6f74c1a17df52e1f3bb451a5d546b7ae3ab45131b4f9a8d27378910170cb414a1939a4aabee2a8a6115c35742c2d9b6af28f01000035bcba354d9e7f677ae87dd5ac769401cb528365c70dbdafdad28b5697162f55d088e87dd5981c2079db4262ef6e6f4befabf63597369796f6fba6d1a5d1a5d1a5a5a56db0b797b68193f6f74de3f1fba67dfdbe693b7edfb4a22c3034e8da68e540a1f74d2300992e6e5b6c646ceef4be6914b6c288fd5595115345ef9be6010a297a6cd2ac6192d0fba63dc182030c95091d6df4be697f5ec064a4d9f5c950ea7dd3c2d0c2d0d07e5f343134313431343434ada686a601a95c341dbf2f9ad7ef8bd6f5fba23d9357e89ec0dd00b47bea7dd1acfc7ea420d3b6c5c644ef8bb61c7ac362e64a58913c3dbd2f1a73a9881917e58b1b48fcf4be685f28b081e44a859f8a244ebd2f5a738c15bd1844bcb014d1fba2ed9038db217176f6fb9eed589ded589ded58dd33bbc767ef86a176b876b8ce1e30ef9ee5f87dcf70fcbe67377edfb3dfd311658f849b1f9adef7cc00564d4a307932468896def70c08151bb618388290e97dcf98543d4ceca92d09b3a2f73dfb4a53c4cb0f6e6deb4def7b96a3869725952f459e38f4be67612e53980f7cecfc7d9d7ce911dffb3df61080669cccdfd769e3f775d6f87d9d214238f19c38dd90545d5169e97d9d5626f6b4945535b2d0f4bece347f56cd234400d9d6303d380366a2c616b7b92ebdaff3cb67eb19a306b30719277a5f679308165a5e138c0f31bdaf3383c82040fc06914164101904081020dc3054ce7620e41e3b88112068fc06c1f51b0488670d50cc402b32438415135f7a83b0b203abdb42e7e3cca93788250d32a6159d972d737a83a8f282469d980e269fde20963a9e5ca9f051f72389de209644d1eaf2b163adc611bd41641a1f328d0f1f7e7fc8cc0f99f921333f7cf8f0616cecc387153abf3fccf8fd41c6ef0f317e7f784ea0c618b44013cb6699de1fe890ec3841f7a4ca050abd3f2ca514510bab62b7bcd2fb0333ce69a2aeb962059cde1fbe9ca418d3e2c81617bd3f345f3083c9e5c894bb1a61f4fea073c683ce190fdb838e9f071d3f0f3a7e1e3c78f0e086a1f255bef2e0a10d0d0f5bbf3dc0f8ede1c56f0fcf1e30ccba946c59c2a54c6f0f56cf38b232bc2b4f5ee8ed010139f6fa8ecc51fd91e9ed01cb5759d80a2b7b56e0f4f63002af0d983d1d5deef6f4f670b960a97142c572c691217a7b7032e5646aeaf7d4dbd4dbd4dbd4d4d4545ede94dc639f6ae33585b57e4fe1acdf5353cf5d848e448e32384674e93d6545a24aeb2c071a3256f49e5a6e5093e5c50989156070e83dc5cc61468514b91d702af49efae2a24163ad49163b127a4f35a7e485613987f8a5d17b4ac74c4ac74c6a4be938a5b694df639752baf82d85f55baac56f29292929bc2da527b577c5485b5e1c0b1f687a4badb10d218347c6452e4c6fa9250f2d5f4f7c9079b1a5b7949831bc147132628cc0d35beaab063702a9c04023a6aa2a4d6fa9a61d092a3241e45ae4e92da5a3d54147ab4387df1d74b63ae86c75d0d9ead0c1ae43de63efe086a17474c03ac83df60e651d96bf3bb0f8dd61c5ef0e549a7409516322ad8612bd3b58c150aad0ab2207c44fef0ecbb8327b6a5647d698d1bb03734c951e54d228b9daa27787af164e8efc782ef1fad3bb43d3868e357c69b2eeccf4eee0d4a1e2a043c581c36f0e3a551c74aa3870701bfee6a0e23787abdf1cc43870e0c041cf4895135678259c7ce9cdc1ca4e0bdb1e999c93287a73a0bac31136232e0b5d11bd39cc5d5173e6069534bd397ce58489ca091315f53b2a872f6aef73f8a2fa1e7b549b295138c5ef288ce277143ef13b2a2a2a0a2f4aafc88cb32134dec49c7a4759519599d155858b1033bda3829450916665a68aad4cef28bdbcab2d5bccaec234d13beaebce4b9018264618b1d33baac977c60998998d659dde51396b50396b5050bfa1729e50394fa89c27141414941b86cab1cbb183826a6305caea379489df50257e433d817071d19d28a202506f28144d48c839adecdae80d75fb86b8e89aa17c6b43a53714d0893aab3226b0006ad11bcac918122d32469c6952426fa8bd232faaeef284a008d31b2a87c6530e8da7a7df4f39cca71ce6530ef3e9e9e9696c3fc93df627257ec2be9f48fc7eaafafd34e2f7d3532daccfa9034a153fbd9fcab6fcbac838e34ccce9fdc462ac8a188f29294698d1fb89d917a806055c0c28617a3f7df9609324cb18112ac8f47e7a22f7f52c2377b68686de4f67369cd9b0e1f706bf0d7e1bfc366cd8b0c10d43e55ce55c6d907bec1bda98d95025e2f7862daadf1bc45ef97bc3138996ba381c32d27cd17b435712295b682eb2f481d17bc31249a44d4b123f205062e8bd61abea6f0c0bbe2c47f4def08506c6913c2a6e7543f4ded0c49b91e60460913d167a6f203a71223a7172faed447c7322be3911df9c9c9c9cf2f29ce41ebb1309a7c0df4e6d7e3b01fe767a5e25e942c50c8a2c36bd9dac9c655a927811a1c64c6f27342cd2f0f98db0da91a6b75305f0e0b0d096805e777a3b55d191c5a38b5f1734817a3b356370b6a34c8b08970a127a3b916920d3a0e1b786a686a686a6060d2b34fcfdd6c0e6b78635bf3568d0a0018f026d5934ce8c31d708d15b8395945fdb90bd2e6b6d70e8ad41af6959e559a5d9b8a1b70621582ca0a0b081234917bd3520e02c0a590b17656c70e9ada10640b0687cd108d392e68bde1a883432106964d81988cc0c4466869dc1efb167503233a8f99dc1ef778634bf333c1f7b86b70c1932e411e35e849961e39976a7778634b63436dec8bc40e3d43b0300cabcccf485d912d3a177061363d05858d9f8e2c24aef0c5f506268cde9205bd33b43132d6c4513e797b8167a6768cf6068cf60c0f01b43eb87a1f5c3d0fa61c08001831b86225e11af3060f88101cd6f0c677e63e8fb8da10525f4d0ac5152997de98de10eee05141b4368c8d01bc3720278cf3eb62a38bf1f7a63609ac9c2f6e32ecc1b9bde18be1e90c24dad84891b68c2e88da119011d566d5662ecf061466f0ced5c533bd7d4f4bba9a56b6a6a6ada4d7a7b8fbd292fafa969ace7779399df4d657e3791f9dd54002f5fb0588961a54553efa63d2655606065f568c1d4bb6979d5b490d262cb4b4d5710bd9b9850c0c424015bc1438bde4d5f6757702c4953c3e744efa626142c28e658709961e9ddd48631b5614c4cbf995a31a6568ca9156362626272c350ad5aabc6c4f464e2fbcd34e6379398df4c47556b2852dc617d6de9cd04854995ad1f3aec5a98d09b69f9588cb9b7e42cc8113abd99987b4bb2136e4eae70d19be9cb0d88df8a13735daee8cd74e16e9081c3e36b61c64a6fa696c48596c4850bbf2fb456175aab0badd5850b172eb861a896abe5ba70c1ed4298df17f67e5f00f3fbc273865e893068496894d0fb425a19b03546a8d09de97d61b9249202cb95671710bd2fa86012b825c91619214dbd2f7cb125b14332e6695743ef0b3d9a4ed66c91b3a23ba3f7052b4b5696967e2fe12de12de12d2d2d2df5f52d2dc52d7df9bde4e5f792deef2536195c4162a00993a6f7929502c2c05cd92ad3626d4defa51a90d0d371a5756359824def2500dc7129c3a5075b170bbd97b088b88de0a3638236a6f7d2598d324aeee69a8ce9bd44a644a6a4f45ba9a9d4546a2a292929b9b929294951eaf25b89cb6fa52dbf952c881de98321a444569ade4a6d26e2acbea0404ba1b7d2128d8799aab5bb1c3ff456628a65b1c04203068ec799de4a5f2a2823654b89305d9e51f4566a22e1c1832eae8615187a2b0d55240d552425fd4e1a2e9386cba4e132292929c90d430dbb865d49495692f27e2769f99d94f43c53e4cb9f1519185a7a275931a1d2412347608d3cbd93c2a039f204475693152df44e625650421687e249e40999de495f315e00b98322c6a977528c3c1a4f36235e6e6cd13b690bd21624a4df487a487a487a484848487f7f48485dd8df48597e2361f98d84f71be989064b18961526d2d4e98d6475820617176e6940aae88db44cdb113824088e222cf4469a11e3c591b122645a80e98df4e57f7e6adaf485f1b8a1375273cdea8b8a29229e64f446323b323b3afa7de43c721e398f8e8e8ee4e48e8ec21c5df97d74f7fbc8caefa367d7981936276b549cd0fba8ad840d1445d27801dad0fb68b9f57c7341c6e71746ef230f6382644dcc9236617a1f95a0ae455b0bbe1b65b6e87df4030d9709b824725e7a1fe16819e1681919fd36c2d932c2d932c2d9323232ca7bec466060728fdd4849c6c8eeb75195df4675bf8d3668a3226b424439c58ade467e34b48494218b71a7b7918d162e74acb95131d3db68cc2acd189f98320c85de465fc7bf1b2aaca4010e59d3dba8d9c5c688b3b7224166e86d7473a6e8e64c51d1efa21bbf22bf2f2ada457a7b8fbdc80d43e154e15415159d05aa29a2f2bb88ee77d194df453f6edcc0e2d5c5e4cb0abd8bac7820892ba2832d860c267a172d7db848b88929d3d70688de45cc1570d56d4df90165c618bd8bbef0b6a29400eb5b2146efa2e6e3265b39ae7eacd5a0d2bbc879e384e8c60911d16fa29b37a29b37a29b3722222222370c759377934744a4a42292f29b68ee3791dc6fa20c4188bc209306cd0c0cbd899a2c39c3b291f5c4b2d39b888b890d20695c4cde00f5262a4277420c11314e173ff426faaa408c16765ba428cfc0f4266a965873638c99bc2f30f42622b34066c1c26f0b4d0b4d0b4d0b7e8fdd42090b71bf2d44f96d01eeb7050b162ce019b15bee20b2a412446f0b484698c96a5e5179a2b785a5918c4910b1225190acd1db02f38a122661d8846901d1db828f3546b2e4784ed93ba1b78504d4c51519a337038a99de166e68206f682091bf91374ce40d1379c344fa3d76a47205f2ed3712ca6fe493df4824128977efa85ccc48e2440d1abd9156284e80cdf883e1c4a237b2c6da902a5db88ca9a9d21be904cd12cf05191962717a23bfc8b86d055619b165426f2409ced694411126eb6c4b6fa4f04c05e1990a157e5710fa5510fa5510fa55a850a1821b86bab9bab9aa5041a955c1c9ef0a6ebf2bb4fdaef0244127e5eccc6f19a677052b16786474ecf0925142ef0acb1b4abf2560a06c21a37705d4cdc7db98abad3b34bd2b68317b40816bd2ecdad2bb4213053ff4465481c9cd00a27705a19321a193a1a1df436f436f436f434343437979434335869afc1e62f27be8f97b284a19ac228130bad6b8f41eb2aa0199561bad244dc0048ad07b6889e4d763c78d3aaf336b7a0f31bbd4d5b5d07a8a28d37be86b2bc6dc8a2a304e33bd87b2e0ed588a1803a48a84de4342afa3d0eb78fc7d147e1d855f47e1d7f1783cba61286199b0ec78f43a2ef97d64fb7d5cfb7d2c916287599891194afef43e5a5d333458c0b5b5e8ab1144efe3528493a7141557754dbd8f21aedae0845491a372a7f751eec489b635262c7e30f53e5e2928ca6411b30282a6d4fb1804f420a0fb6f172a5da874a1d2dddd0d4309b38459eeca3057fbed69bf1dedb7af51a364d2c449978d337abb0fb02eaa1358b2c0a0a2b72f8deaee6a1c8951e5058cdece0c8115d713167746bee0e9ed5f11d0b069c2e4a92402a7b7f3fdedc0aa119724ca9bde1e9c3306e78cc6dfc6209d3148670cd2198d76c6bcc76e74c350c13d7c84fa9e51eeb11bc78c67bf8dcedf4625bf8d4f199460e39117c4ce871abd8d5641c6d0399172c48a8bdec6255497138bc58814752ff436d2e004132576737845d8e86d5c63f3c2871f561992137a1b9b674c196941a034afe86d749a09990909fd16720a39859c427e8f5d4859262424242424248417e44121c8830285df148260f808f54d61ef836014fa1e3b05a51c85aa2d0a142850c0a3a017541114541114f43b28b80c0a2e8382cb20bfc71ea4bc0baa4af23b2828282808af99f64604881a9a2ebd83982dc6988d68e1a24d8dde415f6780ce0001fd06f203f203f203f27bec404a2e40555b624040404078ac931fd6c9cfcfef1ff6ed877dfb61df7e7e7e7edc30149bc7e6fdfc28fd7ecc7eff94fdfe41f2fbc7035964a80d99f1c2c918bd7faccc90a9e9437215634cef9fbc39195fb84859cb7143ef1fa601fc02abc448cb82c688de3f5f1c404b4395628b8cb51b7aff9811b92293858facd943ef1fb209641326fc9ed09cd09cd09ce0f7d8275029271cf93dc1c8ef09cddf13264c98807745c6a54c13b3282af0f49ee0054917345df0eac25ce83d61c9854f8c0f154f2434f49ec04c12e38a98932a369e0cd17bc2979429629e3ae0a898d17bc205bc6000a9cbf217a386de1358153eac0a1f9fdf3eecd2875dfab04b1f1f1f1f370cc57675f9c83d769f2a9f22bf7d88fcf621fbedf344d36382d702cc8a0bbd7db4b488e2428816ab352abd7d961cb4b2a81c9151a60512bd7d980da0a38b62a22ac81e1abd7d0e60462bcdd38b9595357afb14a985990b444227234b6f9f1550c20a2841c26f09ac5282df6397a01cfb2d61c86f09427e4b90204102de96a02761efca8832bb3537d6b0e92d21d7bd408147a707064f6f0946c4e0dd88ab61668d96de1248c0c50b498b355cb4d8e92de1cfa8189357656f0497de129e3cc5d8b07d4103466f09eb5c84752e4284df1156ba082b5d84952e42840811dc30d4bab7ee4588f0224290df11c47e4700f23bc233839ad58e305724c28cd03b82550d6c98b5b991d1c0729144ef084b225b7d3d6ea018ebd33b02f371190a13724ed49208d13bc257d109341766784459a37784665ae012269c963f40bd23ac6110d63008107e4358c520ac621056310810204050538320f7d821d480f0e33784b0df10c07e4378dec0295edad48ce838a3466f0856c1355b9a58c09e00b6d11b828b1b386af8705184f9a637041888e09125c9953c306af486f095630620d5173eb018647a43683ee6d1a6c7922f49942cf486b06af5ac5a3d3dbf7bd6ad9e75ab67ddeae9f1e2f9dde3e3774f8fdf3d3c7ef7f4f4f4e091103347e2b91caba1778f150bca9454ce32594c6cd1bb67a98165991f70814b8438f5ee615a2952c6844c1637347af7a87f32cefce85371d644ef1e09f85833dbbb7a01844eef1e350c8f1a8687e7378fcac7a3f2f1a87c3c3c763c798fd7aab58a87a7c9f3f59b67c76f1e1dbf79c28450cd7921f382c2466f1e2b193499e255c7e4cd4410bd799667aab072949dbd69d5e9cdc31481160a1250a67471dad09be76b4bc496195f4cccb5d09ba7e9c6a38d4990bce717bd79d4b5a2ba562cfe2eaacfa2fa2caacf62b158b4b32b16cf8a5ebf8b5dbf8bc56797135f589630f55244d1bb689554c20bd6522d0d1086dec5e5882f434e14b951b646ef2213034a6695bdaf2fb1147a17bfd0b4f0c861f6638d4aef221b98911f3dc25481a9d2bba8d2d85169ececfcde51993b2a734765eeececec8c8dedc83df69db89d1cbf7770fcde095c5965cabf2146a3b1f5d94e197e4fbdbbb5f9b57bcf9be213fc0a94f72b81efee8337f7ee8ee5ebdd8d9ab038df3d2acb8b770f31802ccf775f008b77e7003fdd332d75efee0108f0d33dcbf3f1ee27d822e2ddd118c4a4fb05d37480881413cf4029537618a141658609163e26579e57903c92a35bc42452d35d9b6f72140631d9a47497f64a8ebe2026959aee4868651193c6e35f0832e52f38ea8298bce043c4b32c9a6759f682b3ac8fe6b339ec1996659958364cebd91cb68f4572966d6259b111cfb6ac1936c959568965839c3d1b8135c3b28eab5867fd7640c5952e3b2e1759579a55a285cf598309644eef0c234857922a33cca6e8ab1b27a07ca9a1daa2f77d2ae08893c5171a1e50aaf4be7e9aef4697be36bd205df44695620d5002611b11430ed0076b02ae8c951a5f75ac8308527a771273f1ee71efee83f5ee6ee4dee48e621193ce9259cb18ddc7e86ef41046171ac558bcd1d116c4a4116ff754f91d84e537f2959494c2c0bcd28f25af040447d88f577274494c2aad49657e477df021024b4f4a941a3dbae4eefe7aa080f29794bcc104b04adc1122584949643e298cc72709b1b09c114365e26c854e0acbf1498eb2202693da6f72b5094ced9bfc7ef926475710934d12909090dc07c93dee915c88e483ed911c55414c2231f940f14c8e5e11934c177a5cf90b8ea620262fa02026d9ad253222bfe4e8096272498892177221f71112124a722121216b5e8828c42724f4424a42427e02212121cf320a0939fa2524344608c98584582121170ac9608d891625aa7c0521137a92a6468bba2051b4848452ec4003c67955830f89901c9c8a277d489c4f21675996655996655996655996655996655947ad884916690c12121212121292a326884924a3d168341a8d46a3d168341a8d46474b1093461d2ce6b815b8a626c71a250d3c2e44da7688407344eb86b28a952a3f27ee61debd8a6a8d133540b43c38edee280962d29584b8bd92a355c4a492f02c489b4f72740431992414414c0a41b9f2aabae7ae3a52c9290a4adeeffb96e4aa77a0aa2a94be576f54f5ab4a7553d5b7ac57b30a4635baeab8ea2aebd5b7ae577b54302a92ab8ecb54b557dd5e283c6164cc136615e71abdefb3c8c6cc081a0e113df0f4be4ee5f56b8aa17caa02c47a5499f0f202f0854ae6cc061a1f3170586924474242424242722192fb2021394a454c2219f117a3d1e833b8ac785c395333fa092d27745f2898a4301a8d46a3d168343aaa24268d483565f982ac8760dd039665bd0642422f242424242424242424e4218484849c06c4a4505252525292cf80984c72d5ddddddddabbc3b14b877970131e9312026d529575f2c168b8e54c24fee456f9af2fc6284625eb1e81d14918ac5a2505652b1582c168d5e2c2a158bc562b1582c16e96abc922b390c884925a1d168341afd05c4a431e9ee93dc05c464925048484848c85b803465c623390b88492496655996655996f5151093acfb3df2ee1f1849e34782f9c22b8dea4500804fd2ae4881e22287565d751510936a0a88c9225efb477ee4c21c7ff4a4ca1f390a88c9a3ec66e58bbcc87d8a8a1c59e44d4ec07c518522bba222efa0c85854f404ca17b54558afa8a8c88b8a5c98bfa8a8e8c80b3053d2f4b822a6a8c4162348ac9420fba237aa7cb2e2dd55f71310932e2c168bc562b1587413109345a351c968341a9d2879a313e51bbd04c4a4916559966559966559966559966559d649404cb2ca274120daf25ec87ddc84bc509bd70bf90888492167311776d8e5f7f54bfa6372b1d5f1c590a2aaea90bf3544a8c2d48eb4d1fbea7d70238558dd0d16555b7a5f3e2e6d2bdab2da643c149a35223172e8a8d245ab6d56afba088849751393457374bfb383b7fcce8e23953094aa77dc093fdddf99cbf23b3b3b793b3b77c74f30a766a798c5f53b77470ad6eff0ecec08f98ea36e3b72bfe3a8dd9d836b6137e6ed0c0d8c1d59803cb79c64806bf48e565918c0366548ace97d9f7b4f04132538a238e1b2b3b3b3b323e5ea858484843c04c4a450b1e83ec5e29c992f3a0888c922cbb22ccbb22ccbfa078849368d6a4a9d7373afba509d8bf2aa7b8098543b404cee18c590f146ce0162d2486ba9e5b37b76647625fc64f4ec4d596bcbe761ce929d03fca47af60e30d4e5cb372fbfb8fb3ccc587276342b17e51c83c5e761c6cb45cf8eba65a1fca6542a49e88dd26d00eb0bdd12357269d4e8aca602cfac0eeb0e88def9339f0e266a48e09991d1fb3a37e0e7a50d9b36620275641560a1c225a73604065fae810ca7990f33544aaa30c96456b4418355a4459bdea85807ba82fc1842d67535978584e87e07bd10f285fc9a7921a61712f20c03c70bb90f8c332fe4bee5e4857c03c4a490515a2c168bc5e0178bee2ff8be58f4fbc2cb175d03c464b1a8a8c31715bd20fb22365fe41920268bd42a3b3bc39d2b3bbeb3b3b3ba99c55549a3652dc6ce98391269dc485099edececb8ef78881df780ef777676dc03627247e9471ef4ee5a65ef5acc77c70031e9eb8d1515826aa7aaea9daaaaaaaaaaaa4a67c30e480f6696a7ea609c5e549a48f6a854557dbecabaea2154f74099f5aaa34cd55127d705884975e877cf1bdd68f42ce68d7e83bcd12d404c1a7d54965d59ba67f3acfcbe7e107ea355768f763d5be537da7cd659966559bf2c8b80b2ba352e33e682406175b6e8bdb5f97df9c2d41b5d3e4b822b8c99164cb12e7aa35f9f012860c2b6ae88b468ea8d8ab958c3baf2590f51f5ac7b704289f5ec3dcbdad10131c93a2b404ce6fc44b8ee89888888bc89c8f9020692b1215d639a48090b2b270e2e7341aa88f47a3c5117ba67a33ceb14980031a93a07c4245194bf8528ceb7e01220262d209148472291c8218f1cd1f4ac4780986455d5afea102026d5071093c828b90a45bf83be0285af508189df5768e2f615aa7c0577003159c187a8fcd0d0d0d0500eb01ecde596b12b237a088f2c90c49312557ee89ddf7e88098a57d95ef50610932a0388c9a1a80b7fecd1e38fbe0062f24863ccaf2bddafab10ae11f62bcf1ab73a071e18d7d54f5083ccafb7cf6ab9e5eb6a63ee579c75caba3afab6fa5d1dc55bd1bc5fa5fc46fd7ecdbe3aae5af1d5afabe3ad1573fd8ac57e75dcc44f3bbe3a2e5bd57ec5cf1788a5b5e092a20d1c9b2672028ec13a53a60891fbbc7e2386c41531e3f292d35cd2ecf951fd3d997aa3cd03b8b511eb8332630716bd51bd5f9d2f0a9b1e6862b05ce88df2fd8a99bfe2af5f9d6559966559966559966559d615404cb24e1d3c07630d055c179899153b3c58b81c09a3eb6262c44e0f122633b2a475d91dd9d991fb9d9d658d355770ec1db193a277763c01c4e44e9ba6a6aa2a9aeaa4aa2a33c8abaaaae2287b15479b57550fd135e2551f409792577d0154af3a02e8da0be677d4672245c4dc4c1ca15393e33e671422cec8f6aab82831a2b38d2b9ffd00c4646ebf587461922fb6f9a21b80982c66afe17cf70210938ee18d34fedee80420268d42211a6e2fe4032026850480df769e82fb50a0e048250ade44c1a3b248f83df5142850f00e28640a14283805bf14ee13c553a8f1d9b3078098cc411ca5e9d7758502f82bdc8c5f3d494cae4e96ed59070031c90ab3aabe2979d5372026554d4c52e0fbf04173223ec89f980c8a53f2400ee43e40408e54c24fd981bc09c8a3e4b61e680a687520a01d202039320f040404e4681650110808c8090404e457c8178b1e82982cdea8aaaaaaaa2ac7e355557510c4a4ea21aecaeff8076272874595c18b1737f7eb1af7e457f7404caeb9cc679f222673a00c2f1c7048d4aaa23c2b97030d470c3e1b63bc341b65ccb32e454cb2de8198046afaf909fa1fe4ff2871f8edf43ffff3e33f2e64abfa1fcf3e6c63ffe3cea6e67fdc6849d9ff78d3d3ea7f3ceac7433ccffec7ef9adaff380762f2472dc9b73cdfc27ddbb6ad3761a88bd7f200fc76a97d6b9d03fc94bdf50ed4d66feb45f66d500ba5ddf1d6d1ac766dc5944a658a768dc8b739ed93d6d1670a25d4ada36dfb49b0e4984a2f3165ba1dd392f3a166481e1bbdb313963624d2808ded50d3fb3a21f098db7a969de8da6bb7b050e3e3860b294a70b435d811064646d591368081addfb65d5b127dd1a388c9a21044d055739afaf5aab909fdbe7236c6fceaeaeac2212a7ef5ccecfbd57dc87e75bfe1f7ab1b0d71fbd59bd4e07ef5a81cce5f3dc4f2d7b3b1b95f7d01645bbf3a1431b9d221ffcbefa8dfa9b1c7067882c595950b7db7d1efecec3cf91d1b5a7ec7852994929d0cac1a3eb478f1d23b434cfc8e3f11933b1f40fcee095afb8d44fbade4f4ead4ab6aafea20f2aa8ebe57770c797547dfab5f465efd62f32a8fb257fd7a9579d5371093aa53273bf91d95801f746bb2bace9cbcd03b9b008b189036714d7ae0d0dbe8f38c1b7a3976289330f56efaecd9edb39796cf41405830b901462f8a199dbde03ebb13319997fc6e9fbd77239f655de8e359cf2c5a9967d3943cabb6e2cfec9e750d4d1988c976828bb79fe01888c9093eeee3e3e3481f1f17fae4b3f771c1e2d50caf7a1331a9aeebbaaece444cae1788491fa59750c6e525f8123129a1f811da3e823b7e5a3d82232344f0a6087655ecb2686c29b3c2a7238479f3eada2106c898de59ee23f82d7bf555572226d59b2617bcc0d0b3b2b186a68a0a131855289830c04ce86df4eb8927614c72ac20c3c232291bf22bd4963731c0314168ace975f524246232421404330fc18f884908c29eef797e4f8f237b7abc0943a14ba5527942f7744df1e2b79555a6248aeec992d1d6220d89246465fa5ef91eef09fad5f85be957b8df5347bfaf9a19901f3326bfba4f121cbfba2731f3ab1bb1fdea4d4ab6fcea219c447e752362727daa7e77d4abea9217a277448ccc8a393fa6de4d185c982013e3f7ac3245a3d162c2d97576044beffbc6f6aa7b8e573d8499d7ab0188512666454b99858456cbc25ef5226252c52322267bec9e872bef79dc0231c923a3ee833a1f5cfba03b52a929e85133467cf08358ed3948a1843ae81ee4607086de07798269c1d683c19d60d0d12faeb90fa2601f440b3afac44f6e18ca83a8dc07e93e78c48e0415366435c8a468079c495137468894263c74d0830b586306450988c64633a8468c52ce0f4cb92248d6a6a5068db2b1327aa3621f7c9af1016444a0de0dbdd12697f28bae161d494c1691bffadd51bf7ad399d656056272bdce9d18bfe343c4e40e5a0f1935969c99c10ad33b7fdb9e7d8b0706cd90bbb1235d73ba9dd1e25b3f1293edcf67bf32bc7c762726b3f0098f0af4aa1a43cdab3296bc1ae3ee553712936a54111e5a7c3848a8f0c13a9fa5528249db921331f4aa341b63ee5917222659a7404c06f19caf63c5ec753c8898d4a923f339c2cf51f239393941cfc9b1737e0e4f4e921cd67372d61cbf3956c03e6727c72cc7d1650a25d4398e6ee1a7fb396a8edf1c17a6501a4d18ba332848ba94d13964fc4c3c7951b7a24eeffc3971678a1c09032317964346c598560d1c2f98e4f0d8e3cac1bc02cb9163e54c3330ac4c94bb9ca6df3d7671afaaaa67bbbf571d8898547d7ef7fc6ae577d0d1af2ec44fab671cbf9e55d1f2ab9a5ffd87985c9d6559d6599f404cb2153e58f7e483ee434c0625109339f7f9c43a114ff408c42471c60f87653f744fa1847a3874a5a6282a487e38c54107374fef877e022a657ed8f74324434797f849f5a1a35943ae1ffadd28f3872e4ca1ee1a38351e66866071e9a18747c88c715de968e2e99d9d432c4e44387132660d4eefebf743adbc2c2eb8c69a70e98d2a7ff8fcb67508c464ab4549092e34849cf0a2773ef22a90932752d2d2d4408245ab2e4ebcea3dc4a43ae18354707cd07988c9e09b92345f543472681d598dfcfaa5e2ccdf0b21279a7a9dc1e6572f1293eb13f259ba34cffa0e31c9666272887ee91093291ece91c7ede6b8faf012d3a13d804f6f1c252643a4373b1de279c346a87088e7898d50b7f025f38469e309d3d6f6fbb6fdf1f0e1a3bde7eb7bec0600b4ba6d6dcddfb74dcc000668c36bd34b231346c8df08165ff4be6d4c0b04011423a635860d1abd6fdbd75a93b5264d7edf26cf26cf26cf264d9a14c0ceae4901643429b225d6e4d9464791197d55e454e87d9b58fd8d81538145cec7159edeb7c9328c49181326bf2f13b1f448ef321163e2f7d809c06cabb69810f97d991080004cf0766431333332c40d4fefcba49927a6f657c30c092fbd2f13270f89270f89e7f3f77df2583d79ac9e3c564fbb67de631f801b86e2e1c247a8f370c93df6010082dd27d9effb1cfb7d9f437edfe7f3003daaead0a6cc8803a2f77d9a79a27786e28a9b11bdef33ce079e153c30cb2052f4be4f246829b09a6cf44c8cd0fb3ebf92e4b5019304cc8a157adfa7b2858e2a176244b459d3fb3e8b589614b12c59f2fb2ef97b9c878ff63e6f49df922502e8eb5b22002155427edf25624b9e6802abde766c91a1b78439802eb4146dfeac8c09a3f75df25524632b92b1b1fdbe6c4db6265b938d2defb107e0ed8d2d0080482e5b90df974decf76503f2fbb2fd64ad31430286450a2cbd2f1b9a081b5ccaba1cd173a2f7657372f93126cced860fbd2f1bd30048c87c8c65696919a3f765fb6a5ba1a5c744adcba9f765cb59e103cc47d599950cbd2f5b516bada8b5b6f6fbae6da5477c8fefda9adddabe6b7a7b8f3de986a18a5dc5aeb52460da5dfbf1fbae85fdbe6b60bfefda3398620a5c9a2f35d0cc591da0cf8a5a0e122f9420d1fbae2dd37479530e5161a644efbb8643879f9935cf30b3167adfb52f2053c0c05c39b5a0e97dd79a455850bcb070d1e6454befbbe60454035453fb7dd58a4ab5a252ada854f37bec00006c72d57cfcbe6a3d7e5f35b1681b940be153429670c9540f361ebc351c7b4213385a08e776e4a937b0500084c9f7512e746a1927818a14e190b48c7a060b2f303899a60e46988c6d1720b02d59e8a194f4669034308fa0c48446463345c82e95482a0db5a044889c32abd03463c84ba0471dc481088d4d4a8278ccfc74e89b2035c5c7c2150916d884118c612a840dbcd09e0db4f0a8c5a93c756783aaccd4646a231c1e973851783712940889b808831a8e351651d7a6ea2204880f1ea6a43a345dfc3d5d9489fd07182a2b6f211d861c394cdec21dabbc85fffc0ff0031120fdebe9dfa14d8357b1d1940b2229525f535df2568bc8768811c05a883e7a767cacbc85dfc4465f0b10a647d78f1ec31b00fdf5d157cb595b1e7ee93b1cc95b6874cb5bb8f77d790b513083df3478142a8811e9e502efa792e4ad62f8e36b214d623d7f8752b02ea14b37cd513b9cc95b95a2b3b02405eb8fc0e87f83bcbc855ca6b6e4ad6e40226fe1fa4c81790b8f2dd67e0708ed2fdbdf331da5007d79ab5951504f1b9c3c7898f220210204a91e9ee24ed6e99043f4c001bd9f53038cdebce5cc4051f73be7f0600bbcb9ca4f4a0ca78a3d55ea8e0e0f133bf6311ca2b8eb3f4073b1f543f7c7ca06d3344dd3344dd355180c06831e02abc160905d6db030a3c38e8b8ac689371c57b854a0e88726294e388902f723c9de9835a7d79429327c8801336b6a297df4180357c5e965e3eeca953672589c8d5b103562c818f7ec55fcc406dba8aca62b23b4cafffaee5e07f73a432483aaca0a57945d51145ce7ab37cf036cd40113534c8d719d699aa669fad40762caeb034f95290c3452141d321fdf5dda11d1022587755dd7354d879a30c6187be0628bfa344585d9474d4d0dc5290f2894c56f14a3cbad25119425f349eac6960d4e3e4383872b0c8ffdf6a8c8c40c75195d7de8fe72aa89483c4e201289d90500b8cea82623f7c16a580dab6135aca606802914596cad01c6290f26a6f7277a17d02b7c9f57373f006c2441eef9b614b4f0a684212ca9c7ecc8c1b020e533daf1fb06bf65e61b07266269116a033751266e32ef92918d99beb58008c299050b5dc80a28104c878a613ab1bbf44ac454e510aa61060b8e503d7ccaef9b00b08f72612363981718e37e13c53c40fac0532a859c48241233074e4e4e4e4e52499c860c29bc50e8c714bff088dea39b167c7af36915aa4bb866ef06d5715870559cb3de25d575f088fec54f9b85814a24c0ba8e05fdbaaeebbaae18638c31be4b53458cf00105fe46fd847e4a6cd4f482af0528df0f14b4ab8b0394c9a9e8f82668309f08fa04e951d3970b243c0006708005e0a71bbf9ef69bf85c57a3eb775fb85781dc1c89d748bdf1bb6302e1f186a8824fd79b167cead748f5bbbe1a83f553d5c5227408838607210d1faae46b35aa4c8fa4a2a04afc821e6c6427c6f3681a02555736281406d9554d2d9ca5cde2a7698a1a7520f10077da7eafe8d613dd0a40fb1f6cc07481926e6da2cbbf8195b7a82623d7f97da3f37a395377e81b7149be50a9e3746801514d46eef3862edfd0e51bba7c4397e8720181197514e32d176f07f98448a1d421243ec2fe94aaebfad8d1e3f0914e24d2895c9a43e22995385350b18b27e60153183c25baa39a30181d1d6fde0529943a14223dc2def46c5078e33bdf0885c29c8343373df263afd3cfe977fd823a447a74bccaa818c6e991a1f06f97df3797ef04ba2da3cbe02b3d5ed7755dd374c8091f61273cec84879df0b0d37632fa7df19cee92518813ba54bdf0adef373737377901eb9bfa96be61a3621a3e146314c328f7c9aa303bca640148467d3bae018ad128c38b4cff318a620e522875a8293dc29efa36527dfbeadb078af59d59a170cd591dda4de9d06e6a423629518c9dc38bfeed80d9bf1d827f857f89e8ed908f60b2d05f34abe6df0ec5476f879d96c25fc7ecaf7fcff6be7282feba2aa603f4d7571ef967c7e7af078b13fe7a6a85f5a8df1093435af476883081ba8cf317cd845e8f84bf8e83ba9098440201c25f17a23e8cd0a2b703cfdf9ebf1e245679d4afdc13934e1ef51c62f20c4ca0049dbf4eac8211009f9c065c354668fc2092422baf0f029101d78c10ba305c520441cba287135af476682750977f867f3d9b60f1a8f3a03e04c2f9eb2cea12826ed03cea1188492e8ffa90428b5ef92126275097511ff2a4280f4f3be4e1e1b9c1ea0deaac7b7779ab4f2c79a35f56f256cbeaf2be7a7179a3746e79ab627879e3af2c79ab5752f24ef59ee48d976d79a77654f2c6ca372779a76a55f256e5b664b549de69932eef140c4e4bde69565edea9d595ac46c91bffc9e58ddfe63294bc51be12c2bf6825d6dae48df3fe2649bfe48d8a619092d5124d392e99c72b05220108879985486e7ce4e28af62af78c119790b1e225b254ae21eaecaaeaa47f893ac11faec4648a1e813cf8c37bbc8fffe21fb26bcab2984599723608fede25554dd16350c770886ac04de912c62ac6aadaeeebe9bdd8538c558c55ecfb0aafa71e02abbe0a80cd0122c0fad7efa5818ab238521fb2474f1fef19bcea2c010c200220e1fd760868fd10983ddee771912d90c8dbffb86424fb1f515951ba5883a2458693c4c80e352d5fb0f4265065050a217a6b24c0aa3ce192c33363a62f0da7e8418b3832ced8a7c767c27d6ab1117ed2b946b807003ac227c01d0036c27f8736b84b49b9bc7ddfb4c72df60d6e071cf5e2bff47668ef92ea4d2531e457d0163e52fda25c186a0a1fa9deb63d3d413be8d1f651abd4035a465d15b6e8966f1f0f52a81ce2c56b87433eeaeaf878c302fc5b06ff011e013299b2c2e38d4aa17a825e0d1e5b6ca43a7b548b3972eac27706f15a6488aacbe1caa2c79515aa007d085f79eb077305217d72ee59a986689ad3a3b4e92eedf0003fed9603e7c0ed60a53a364ad50b73d9030eb091938cbcdb252e32bcc8640bc5810bee128f9c7d6e07f4559f22c03d4397e991ea7988fd2ea91e027770c148f66088036ca4fa0f33eff6555598629489a2986ee8526d40ad3a74a0565587c3a10f87c3e170381c0e87c3e170d80e87c3a1e3ada1de70381c0e1dfd42c5d0e170381c0e873e1c0e87c3613b1c0e87c8218e4b39c9f7efdfbf7121d0d06f7a44971ee138d07075617ab4fafa961ee1b88a83e33838383838383838383838383838431c1c1c1cc75b387a38383838388e7ea162280e0e0e0e0e0e8ee3e0e0e0e0e00c7170707070fc22718644b0e2a18ed97b026c7455351da6699aa6e81e414f712fef9c7b304ea65046f8083bb28258de514f2976d56a781190832efce155401eeaa46a129ae853e7f8ea43bf3e3c0a62087278d42fd4f11ea141a2dfa50b58f9081474ec4127baaa738e40c1a100a4ada33aa75042669a5429440411b1a60c1820377a04e191c7a651bfc2e0711b7dd06f8edbe86ffca650c36030f5f9e17068dff8ea39474f8f828e120370e3c2d4718eaadf0c5362725d8fc2e0d0088c5e75946880096e5c86089f3ddebf60a58dd3f1b677a3eaea8e42892c5468e47df913413c0ad3a334df25d497fcb23faae5c6d50a327456a6d899608bcd581c1a215e68daaddc3975a479b2c715581576e3868a29365ae82166510c0190266347e56ecf63bfebbaae2bc6ebbdead0c546a8ce5dc60e020adbb028a43866642e35c95b15ca2b66293292b7f0afd1ed80ef5daf7a53344b0a50800a5f75d4874186e4adf658c92ae6c247aaabaae32ffc947a524c4e7d265096b1f2f1d010938ca64b4cf256ffa620f81f081f2800e95fbfffa80072fe0a69c9b70157af8eb1aad72119d040df60601be5e3a1225edec2bff8b1fbfcbd4728f1de1093b8adf023b344010c5576c5c160100d5efc586c1d33bcc81257288a92a0bb6efbbee18b2f8aa6d777509a620fc25078041fb2e9511f40dea33d6f586c1be1f07121f1557dbf83baa5f81e2b9003ec09154114001af85788e29be6603c960d7db8126e7fe14a94bd84bf7025723c1229968bceeb43550a0709206b5b90e0b0719b6895408323b3044b181a236ea419e9d1a288191100fab579a1c2ab0b96465d3d7e61a3b6bcd5b2bf5e014cee8026775093b72af657c5cf2cb8f94e3dfc85c5fe3aea4b5732082d79ab577f1d4497bc53bdbf5e54cb4b43f24eed9e83352fd45c01033cd3b541922d2398743dde9e1a652b63c2e4ed6bce0e0d0533c278619181c777022b89ecf24edffe7ad12d5f6cb453b7bf9eaaf9dc5fb722dcf2d7777e550d9354a5b0f2ce8fca55e092b10bd95d075126ef14ecaf83389377cafceb1dfef24eb3fe7a8735f747170a3c1d40c264e131016743cbe902c60c9f18768140eec67e045e40236353b765c49614b58dd8172b32ab2130cc021076868a8ec50aad388df6c9fd09c10a62a60cd0f3891414704ab218d1a82f01c93b4499bcf1db52d8f52567be8ebaa38ebaa7502258f1648699bb3f3b251d8c01f3d5c50b4c8b16944f55dd7fe7f714ead621f14b2185858e2d318dba510a55831b687d746361769011f103660cd697115c5f4a7255b3099d5510b92a1a75107b7963be4fd3271959551d75e4ed701ff5ec3302e4a7ae1e711e36ba78ef48ae7024e3a1ad9ef9eb17890ec18476b965a2c92c18cedaaa67a7b5822b490ce609355b36bca089b1c6c58510be2a1a25ce8ec4398fd8386382cc5e9cf32d850bae208c7c5375a3a5e2664d16bec0999183356eaa328fd75049be69b261b97886e3968371375ff9a68ea5cb412d375af2dad762b875c395856dab961c8c63f9b21a268836bc71f7dbc845d0452e5ab133c0d20085ac1842e5ca9532457cacd8b1a3058daabd35246cc40129e227e4ca6a840c24cc2a5e7c6d40c40036396346b5e34e58a44513e2c089428463a1b45ac41e6d0ae1d9b0c67088971e38cbecf3174d848b1b2839c74730492e1ad1cac2b61caf1c8c1302c1e9d2fe4543f125b771b6c12b214b4ff06884ecc9ad8f4705ffa2a140f31b39667891c1bf99475d2f9b0e7f675618140a879c82c728c0cc3e512eb3605859882428978369ec8b9c362106e6d6c90a402a4200f35a2380664ce4e108f649d6598153250b69049539c78bd5916f86b04b722ecb09cc43b7a05e66a7dc70c9375672c232f1ef591b2e4bda98c1c1cb37245a34b9b8a2bdcb394c962ab33fd636b9672c7897d527bb74c3a192d3bf6781716002a510f132cedfb3402bc11e99fd7b16d8252823ab7fcf02c3a420a3d3e32c504dbb23af54c4ae2c2c41545b2124936fb470c06a0c5128bd8623946142b731a219a5df302fab4af62edf54b538f28d8a1bbd2c7c4164cbc11a2c9bcce3d5eee59b26995c3c5bede26ec4e49bba9b1768545a845af2da17b492837fcfc0d8e960e59fbf68546a886559d88697837156f9266fa592d53043b41c7c225866ffa289f0fb9d5f091ff960a3b4e777cea8671f341469bf8d887051aa4f94d02fea1ae12d3a6116fa3542953e3ece17ba930ebff1d1399bf09c4fbc17465de70bf15ee8fe42f4eb852b9eea9385e847bdf0ba295fd8a37cd45112578ae7c9d3c4c4df09c45161024347172950f44db3ac2b41c2491530da51e6e52303e306d8e41944b7c1e851256726044ba3d85241d523099e526ff4ed6f9d55608faf153d00eb6e4af51bc5fbabfc1b785d78fd5e3a243f00b3a4c9c5699f144a47499838b62b3f6448d1b7e94641a205844a19316550b0c4c993be1251d4f6f46de1a76537268c334c0d94f0b5f9a3a145489b377d1dadba1d94f8a904512f02a10cf0138e5f77c109f0136ef3d739c04f18f0af87c04fd80bfefbebf93a954aa5db7554af8f4fa954c2d04d3e1d7aea6dea3d3e6e05d048e953271ace2be7c119dba737afc7f7d5bb7b107cdfbeeba734c3aa8ae01bb5da68d6d6a78e325d78f914edf2f18d7e814df08d8e35959fe2a44fd4edd39fd4ef46e79c28d0dea7a952cda78eab28f8c6561863dc832ec518ece81b8f359b98c16a43bef1d3ad826f2c87e93e758c87f7a94ebab1de9e05dfb80ffb7deaa9f2c8a744be53abab4fb3524f9931987c9a767d9a7ea56046bed3b1b4f9a9a74eaf4f53b54fd367eaf6a9dca7769f7a8aa7e4d3629aa67b47bed3bed4ef535795779faa559faa56579faa599faa5c9fbaca6c7eaa767daa6e15ec5375ecd3b24f5d759249f95455fb547daa6e4bbe5539ba4f5dc50be2f7a99af7a9aaf7a9ba77c1b7daa7fa7deaab72cbdfa7e96af5e97af5e99ab5f5a9af4cac369fae5d9fae5f609f62f0bd8e7d9afaea2cb3f169ba3e3f5ddd3e5de53e5de93e45b2a7e1931cf52226938a8479242424242457c24f4a8ee44d4848f01ea9456283848484e41709098900cb38b12a1a665659481fd67e7c598179f3210229094c9297a4a42ebf9d9a253ea94a13cb27b98f11b74f7227fb24376a3aa2a62b4a6d8ac8b17b5e29e895d288dc28a2e2c9ee70dc2026913060e53d064799c424861674ef10de95dc1da9849f90dcbdc9b1e0de797c8d37b97b92bbbbd791717931e30c471a9ff182879a1a675de61cea77cf27b5e8fba4a424cf58323ec9511bc464924ffea626f7697261538b30dfe4680d62b2c9db47ea792424252424a7477215c9853a1ec9b3de23b98f23b5e87a242c8fe4280d6212294a49c97d945ca8c4c2ca2b39ca454c2af90c62d299b6f07826476510934c77646fcc79a39a371a8d46e31d993772e081f18a8f3766a39fd168341ab7cc78638eb18b11c98d4637a27c4aa59285d1445c591e892f2ff2c2b4116b0dc95b99122b25f4cecefb7c42f6b6e5efcaac8c0fbdafdfc583d30ba3cda804c75a0c139a18c3a072549206005318000805e3409865619274ce7b0314801a5aae5e645017c8437a92c41832c000830c00000000000000402007a9222f0642de3d507adda33eab22c21347a5fdc104374dc685c48c93927bfc95109fdfe2af281e6f7107947b095d4219ea528e4511c04342d6f6f604eab31502a52b9a085dcba049ded914cd91501cff25cabf8398e0a40dea6af890d175ec12d3ea4512a66829e9b4632703627d75ab093d180381bc6868c2beaf6c09c78d8a7b6682c1fb7c85bc5322d6c03faf592d6295ff210ef71011b0fb5a8a20d617d4a79393329820fa8ada48f2cafa89ca1c0281d46c4f4132d8d9096b85f473ce8ae4172886e3cb5befdd82b5e49ea0816ca513cfa4cced9b1c9856b4a03ce5ede07a31d952ed69384a50de98ff281269d93bf1011283aed89e83ff751f024b33261238de17bf797f9b8e54e898223af4b619d43db9e5e41e7c18bdaba04a9b809a5620151528a8a9623d2b2d45c17dc57dfef70040ec8e414f6c4892a1631834202ac00ee787306e16387bd3ec4f1931f31abd7963050dcb2a4b37ac7db797576a24f2478d3c73216fcff961c8af50d7c3d084edf359edefa4ce8d2e62398e120b2ae923899f16a51101a2fa9ceb371115b68ecaaa3b486d5176598038d5f952145169538e8faf14e297b0b968667101aa508ea5981e80bc22997faa0ca833cb2072449de066918d88f4408bbc05b7b37201f55f923bba18e73063fd6ec215b377f800fcf291e2251518230eb526963e98113cb8b88384b4fb67e2f60b4ca1a3c16d4f6878efbb10fb2f2eae2f5ddc6c8b89f059fd601740bb748074248e9fe2ff32e2fc94088a1e6b24999558c1b29303f81cff7d846ff5190647dccb87aeb3de227af76e22ec61a117a2d7b4decb4d30bdc7f4b6d56b6c2f0cf782a6f4f3845207380c7ce73d4f8fb32862fc79f02729e142a49a6e633dcce8c1ddea95f26fc6e8add1d1eee895ce3710f658f429f77925583d99fb69c50bbdd8657fb99d564ceed5caf0b283bb39d1afedc11ffb72c3b37799dec6f41ad3fb1fbb727b5abd16fa327a20d403cd37d07f9eef2915db1bb7e28e639b061972a5fbc117429d115d8c1bb9bf2c6417829ec6184b6110c2bfe57243549843cbe54ca21d52262a4fee4d8e81b21c341d457adefaad4f45bfd1162852e428d32504af49bd4d6879c18692150a4b09d4789fad7c8d8fa364005fc451fe0e139f6a35fdc00f00abf6c12c40a951843f2503c4c112edfee754759008345af859c8dfa457ee59e72a532bdc1ce417f2c4161b802bcb525940748e9b4f1803fd3c98a998a7e10e30d40d892016a3207b7bff9d574ed32805f353229b59e31e19cc5a568b53c2d78387ef43137a80ae45fc56668ebb84ee1412339bb2d9282ed8425c5a71409961b645b694ba0c6d2f6a7947ef2a66a16e576f4e0b01d5c24f415c6f8bf26644b6ebd17e823de649d6b81bd77aaefd878bb1a64a77fce865de62be148aa69701108bd86141cfb1a1e91a8096186268097a43f66420d2c6eb9976117c3534e6885dd982be026bf2bbf3dcb6fcafe2efd8c4ebeb1650048826bb588446c28850cc2e26c6d4433418d1e80c7615bdd73bff39009bdf150eb9b671923e453a2bdd67e3eb5e25004851365ed72b0ad5a90f905750a60bf3bdd2a287dd2c48e95a49386cbc709b701f2ca6c5da4a7d65be04f969a6d88947e3b6c15ddcbd4bd0187059fd8cc88df02e478915a5b88df9aa3ff4eff95cb8c61f313786db40859b0ff2031d1fcc94c4121de0e559826336d01ea0d0d3f66865c3cc4997f2a58e1e571d5a6b000126c23f2e23d6f8d34c3d24901ca35b7501b1562e6e609f74bd553f101d05ef96529436b3aa3ea43b14117cbcdb88d9449d4ee76d2414f85fbdcbcfc9f67003d153bfcb67b40bc9fa9512f307ebfeb6dc9942508a5d21051ae903a49c811b592447c79136694e4f37f308a4f65b15d5c369e3cb6f8dece3ffee5d8e13e09c0308bfda461d0883fff1a76c333ff9aa68a806fb84a5034e6fb6632a5bb982490e9f08621ebff05d7a68bbe308e065193679eacfe6d1aea60cf7c574283ad1299b8311abc4ef8288c1b082493195f76f132a53f17087fdf026f5b727111eedcce1f08bf174ae81ba49177d18a4709a96753d6e89d3ec79bfa4eabe352e99b0ce8d9dc806fe34a99d9db2e2f62eb0c13339ade8bf0331aca2362407b9b18121a2cd443c4bd32ab94b94d0710fa822f8b7ee22a3f7442cc22e45b9fb2362311424a8db7c50be7e822c8b11dd7bc4a24fc686c88e6e7db883ee38dc3a41031b346a997552ab3cb6cb0997429102b5a32fce44e15dbe46803320b06502cb727302d3313e8103384c7bb43ea7d3d1d0b7dac5cd0b390fec0ffc9c3a84faabb9cff4b331cfc431ef3871e5f914b07fe2644287ddaf4834b0b73b6b7540c418b96425b1f9a66a89187b1c79277ab808bb8ab3669a851bab96fff23d512528f3cd6dcbc1e2d02f81f97f36490283a6d7faeac500e24aa22bb8353ada69a44c602f9e092bee9960ab5174efdb264424a92872093aa157bd20ea2a4a2c2807891757ac343d08f5e184800ebe5ad95e663b015b9c92cd36005f34b8e479a04141cbb3dcb3867c352fe9857264b4e5b89dd33b45a01e078f4ebf6dbfb487ce38308fca111d98f7eea2232b28b4715616db8feb62ee97b8bc1ffad6bef9035ba017b557c8b759cea63d70c6fad2ba9359d9f0e0954645a1d15e9ea483eabca69933663b4ba84a675abb7fb6859e506b07e7ea2441c5c6405ca842661d2152ca045f2fbb219098c087174e1dcffb683a5f385936bb8cebe40e13647a4c3e56520cd5bea49af13ff84d9a07799421cd5335f350ff172d49ca42a43422e2acdcb04e5cbd43667728db46dab8e098df0f16d3ee7467d8a96fc18ad45cad520caba268bc8910c2dbb6e539614aa82e25f0b18d670463ff9082e2fe531103aa7b1e08930301b2ddf616fb91ad4220d42d82bf95c92ef7fd49998e685444cf5bd6c433d29d0fa47e3dafaa1993f8e3e8c405ddcf8ab70faf211c41cc5fd87ced624b402ae5f8af6ee009ebe4e5f5714bc6437a5665ef065f1496f2e70bd3a0d81d2866d427f68d1ade70492b952ea88373a3776630cf6db67f5e0f7156da65abc3718517688f96af26cb5400ae670985556466080fa5faaa5398d90e45e2644ea7ab5184a98754f73fa0e57e1ab7eff7ddd6b126a226259858702311618a9ea1676ff9818a3e6bee664a9a88bacdb2f8ed068ea4a1c67f7812e4b5efb0ab0c79aba785778bebdd8a70e16e2676abc773d40a0176460444a0db672153f6e4b752d7a5dcc0182cad4b81efa9ad519c7c81c4b33574abd80234765abfbe8bb1d5b99b52e8dcabc4915dea087604220a933219604c58f42a82f5f7dac9516be105b40207cbc20f762fe59ada694bcf255e791a5d8a74d8a4f002269abad09c58b25f551038e50b788de26abb0a047039c1fba69ccba523870bf288eb9a583f2dd87a86b2b1e59b0bdfdfe122629528b4348c7bb5b53e9c3eef1b06711514b29291c9cb484f2b114c89595709a77d0131823f44c7ed9a0d4fa604ae89ee5a96d61292bfee909e731fd8808a00f5730fcedcad7e4fe8ccdc94b9911af440b8b8568b444af862ccaf3afad0cb19605564c8eab67d6be81cfd0fcae833fdd3b975b5476e7e4634438e4e0645ac84b54c026879c374c265bb14a43a1a575f71de494909b4888a4acd890b2ed6f3d5008775733654611d34022c112aac0aa0851a50962382fa5750ce3753588d63d02ae3d5a514b4f386ba4658b53dbcf4e8b3343710b4f4c6cbd2b97396996e082f91f5f6cdbbe0c0b2e9319885208f283e85207d165b8abb61d30c78d124f0e8c282136ea95834a9c000530c59a97e95a90c03aaae82e930d075c006a6946e8fcb3ce15c762b3f413edb82f9b57fdfe7a969ee0a04af1cd4a3091a57e0b70e7b7a384650ff6944a369273cf18a797d8a05b2305f548a90b23207dd84c33f20a3128ea5a6c8990e40e4c49f91704e1468770d10ec947827a92bf22e78e68b0a8c68481133024da4abde37c31bf462120d2875df034a99f760a9969f5f95b3e1b175ccf35f3b2abaff194e8722343a764a77ce394b521ce3beb20d9856bbaa5f9229a1d640992749c5960941f7bef3a8bf4314496fb037771df5ee35d8b778237dbc970be4661542b517248869d065e62eb47f8e209f0d08520c32ae4cbda0d22c6b50eda8a6e4ca020f289de7208f93d83343f86abd20dd03916a0d049e8a38290aa1a808edb5b4a14786b23c82019d17e56ecd8b1d16334a499388b790139c7101a77ba928b4b96a235750d8341e6d83cef99f7a769d02d5f8670a78d8a6c2cd6ee28cc0ec93dbcba0e5470a2c410cbdcaa7fb0d6f54cb1606f7bf1ff1c0dedb4a738ebdea02a34726d3820b255c5a0d6b3af99ed14076896f20492f1156241227ca66c34e6e16cb1e622c97f4a865f86c9bf9873848ed654fae118336cad34387876fc8535da91bb7bd52b4140b0a61a6ee02696023abac29d5f7ccec77c3ec82fcb6376c050c872583d7b022a5afd89aa7511bca88ee966fbcd5c2990840300118d11f68bc2ae5f0f4bb662164ee1f6490a6642c3e2cc91e24b6ff51edaedf2fb40e0c2678b5bf5e8cd0b3fb4cbeed8468982e8c20c29949b8d637b313a551534c6628e42f8c9070ef1e2903df73efba449be9039658986d3ea275b1e3ddb023c640a904410209f798c2095eca1a9b58ccb1fda26d359ca81731bcd7bfa8543f4352f5c817fcb5bbd6c6006c64993f56d534c3fb69917224b16df692eee8efce0c84238b2184fb7914fd3a53b5e06940f10230ae562a8af34b31d0c45e3ffc537a549a06dc4872d4adfdaa4d51d685de7d45a83f4a0105c90c17c696c3721441bfb2f07481ed81f8cedd6a80491d22653b1a838df2404de9923973f2664e03ae4a82bdee2076319e39572c20ba546a5b14d3f7e039f003412ee6896fcf0b17de9c38620a2f4243346d4f503cfa9651c69f4a2ffc72b53cce849f9bad5cd13c5c74e93356d0c0c6586aca3e993461276e542a06a94bcc041a24c92b35eeea055b5b402a8a49afec3684f74958a2279e3c7f775d09481651546445a22b43eed0fbfdfba5f20f3c1a57cbea7f234d9837fe53ace71333d86d98a341bac6409e0c09dfe9a8439382e26bed61e485971ad708782a902e821a885d058e40b978098ac8d57c92e08c5f6c34d71d710e5e54f042d4be65af0bb0a1d23792e176cae708411a1f10e4dd17473aadf6568acc1dcfe48b7da0d22b209dc3f4a4f52506e603a3309096eae1403d1d67a9b599289630e7c14cbcf5d22e999eb26566948d80e54b10cc8413bdec30b4c13ab405f9d5db9b51e36341ebbd4a933c7a42a675628d91591a4b075d2a521334b8bc74c892d19c88df1ac54934940f0f6a89f84b3aa804b185f1cf18adf6a753bb262567969d562e1a9e27c96875474a66c67492474007abd056fc9796bb434d8d25d5b12b1aad266007d768fa05b677fb21babd52165fe9b5055d0d8b5376279ebd2f9bee19d6c6bcddd3d98821868993d0569d16734175cf838cfca2e1a1b31fc616142eb73889c245e6693ad780de0b19f44a6341fa5bdc7e65e196220c599410727b9bb9d987d746997c15aad7463c3217e6be029f38c57c11ce1e5023013dc0c0e096f28ee1d94349a36b0a6e75cc30d741602cc00ed1f5926a60df1d93f3c6515c0073ac043ac2dc8233295b41499d11aad18d43f6443d9e8be244b490e356963b72e158219ab117f4e1fec97d6d41dce8074c97fcc4d1574759de76814a4058c979d2fba09809fc0a9a3e7bc1006a7a43ea54c77e06a4821838aecea4407f8402c7448a59bd0889f201396774fdfc6fcfba91705caa320977575bb616874c81dd00028c63bd812244a459612ed7ac0985a78ed82274789bacc962e2c4c685b91e9f2ec22ce5211a94893aa47ddeaa228a1c1a02531e8bd17a302c635aa996f84bfbdce21582e93c15d284897777ba9db35d3e6d9e7a0a0c1163d57d85761638cb2207d2dc871b41753f8c24029b6775cf14623c7ab0707ce9fa8b0583b91633169fbb8854229025d86111684280181fb7a3312ecd53272ec3b42fee3d99104f711bb52f13a6dd205e8a46894e7b20109d18ed168a5d314092ee9afffea6a43f8131f18e3b83b1552c6e6fdf5dd375a01ed36f6f36ba5a443794846ef850ebd2a92c1f84ddd341a6f78abe6800dcb98b05ecc252074afc29b06bf04f0b8eb66a792d3662473668f55e82e040b5eb435387b9de22bf0b8d147babe4ce62dca14497dc252a6344a57904d70b82acb9f8b808a02a74e0310bea1b14a6ac99977a7619fcee43c390241d332bfad6b05cf1a0257e1fefb8c4e733085a1be8182639f15b927ac6bbe8af8a3f57bb4aae031ee769fdcda96b0d0584798889b4de9c0bf01937baa60480428c51b4bbfda3449d2b84fae66f5057358e1a797a8a01a0be050bda88614d33282e29885dfa819500406de2c0c5c6f2427d4b766c6200cc8e42228be5814f27147c07c78178e6781c06bbb740ecd68c37852f5a1e83680f95c11e448d4fa9da1fbc1a3f8d37cdbf315ee646c65df85c468b3e7ee8f42606dacd969a35eae36713234dcc603e2d7f06699e4719aceb29ec92c9cc109c4af3ef15b4f1cedeb1d05ec93577149b8747f002967a89d612b28786ea0eaf376db769e29c1d3478cea1b799169df3a02d715f78f117105c5a2e858b778d25ddaab8e0eb9bb7f27e72533c50e6c75b3af8f7c16d05a8f9a9b8cf654ce22954436d221f58a4f3c277590b4acddcf991d2e511e9e7546683d59ed4a21ca875725716efe8d4e4373494281495682965ab21e5cedde7b984f34f4ef0482d835b8aa0910297f02446fcc801cd27c7ef12de7aa4458c2a0a6e7c8c8eddac535853afff5659feef2ae7986bea78b3733b8ebfc76ed9a64af60a8a167eea00afe217878eceeb0ee13ecd598ba46e4c1527c1040dc50d88ce9a02f214d3b8a26e4a8a132a8dd60151d937cd18a0a3659a9cd1e1450e72c218b98c44c4d7352338a6fd0fa69f83cf3dac8138260fd620f2fb06e86a71ec5b0e1dffa9a4ce2dbdcdbb6dfdcf88258917b8b42acf0947081786f073d8dace8655c14b6c5a1eb0ef371031ab093291bf6795c2529b5174680e1da6d0766af7e160338bd683ec6fb59f06d3f509ca23af59b8e896d55e46075fa143bc90815447c33b65203d707ce849f82657b9462fd9f329adae517d5f88370026469b3b448a9049bb267365384f8bc275c30cb48d95430b9375d42f0ec7dd00992720ff41b68a3f2037082619ff2e1e63272028875fe04300f1d68ac08ab22c040920b4ddc70de08f35705f9f9395a7c35130683ee4965b8951c6104e6f169e0a0c2290c2bdd26a36b1057d6559682958121a62900ee6cb49690c6d752a7c0ad88812198268a2e6ab6dd5a62c0d4e012e1912c591d560f0ad5575a7c780576125a92b75883c66ce5d3555efb31bbc0fbc89400e796aabfc63394d8913e114b024a8cb5cb46fe4310b21078c79fae216afdab60df85193173fe0f3bd0c3cdfee31d07c717f81c307b05f093fa7b558fa0b3d39d1db4280c0abd46801dc36308f12f266ddc550e143e2479005ebe89ee664dcde528e2efdda39aa71f0b47f3a99fda38b0d734c4c7dd63a6901ef1b243ae8b519cbb4d82d34509b9fb51608f1cc5c57eeabc8b5438a7f291e59b656c7860d3150d790ef03913f02b00f4a07401faf54bd56d4f84163a198bcf49c4fb33b1e4e59d9b0ddd44d74bb3f58ba6d809091572382a3df0edce5ae107390620bb87771195641c210d8055ef7de54d3dedca92dd7654a3a68c4ef818d6d0c7de59c0ec7e43535c29394a7904940dca55805b7e6c544c1aaf60c12bd1715fa06c7cfae7c3d695f1d52d6c021ff001ce1f08f7ce03dc9da63823557272ae93404add62b8bb3a468c0b3055502a48567ab4d9b4b8aa0b183c2f251aac11bd8b933bc64c55072c1bd9ba115b34bb087a014f41b0d59ebc4950fc79d607c179025910033bb31dcb958f9a72e465efd0c1aeee956b74f1b80e711e919cdea2879dad3e6f0bdb00e5c7ea8b217e286b404ec8d9b55af9aee76f1c6b3a4d80cdbdb8b25dfcdfabef9b478640fe0d68418699110ad67b4edb605b37c57909b7fa20f0be1a6b2a738a6468572d850623386d1a0415f4a59ad4c7512c6c8c0b9c5766b906979af8c53b2cb120eeb337901d92980dea62a328ce2d0a9f1ff184b28b1144f589ddbf43f7ed4d94fee27710a80bea5b0db9aac69580923dd080c07a49a047b6f76b5ec02e2916468a4792fa4e529149a4a5d5a1bc5c3063c7e64b6c69e9a6c13555d6d0f76e2d9f6d3db1bbbebb95fc7b1730e14db144534520311c4c6e1322c62bed1bd334e13fab7e3d3ade7f3867a287c9d051ddfc54f158d1dddcc671c74d87e693719d063b35f35668597bbb5eeb4f258b98812e6f7cf64beef197d85172b38abd4ee5395a835144405a0b7421c4ef15b2276ac78527df679b8efe91ed62784b2786404c9f8a4054182b19f7d19f76288d1a28537c2ef8c460fbebd018905cc80163935fc28fd2d8c40b3018e8ddfac214b6ef611cc990baeb9cf41d1fa55c2d279800e2e1abd8d41acebc9f49b70aade164128b9f7bb7ffaa7029b9605765bd2cdab95d80a33fbc38e9ac77709e53197a2c5ca63059d657c82d5b6b0353e3f616377db2559357c0e87696f509d10be74d3be4e9f59ab6e2fba953c5745d433cb78e60211b1d03a5cd8fcfd71121d9b75788984293d6851410bd8d6924d1577cd940661e14a343d6f9b036b9febbbb96e208ede8e6926ed2d589d8b7fb81b4c84f0c6ac74804f9939b6ce1c899087f1a4dc3026adac9f4c4d5843931c599ea4aac62a9134060009229be98945ba9d7f4c9e70e1c968315395a8ca3c00d5f61876306f61dfac00103a601498d1ed2a0c8ceaae2b5109a3e09b8dee3f3b678f0cb1795954ab00c041114dd2d6827f7a046cd51094ffd5941270dd7cac20d8bc78145dd93380f815cbabcf7ce57a8bf88aa9ec0c91a863278bb19de056e9444222038ba6eceaa00d8668b54576a870316403d61222c29592d6cc321916e34aac956a54b321f386b45a236beac9354f4331c359f4d9aae7685673e5e11111c812c825fb13906d0635c7715171a48caf5dae41bbd13102e6acf5d40613245f5c31cc280000b92e8152766ae6013b92d6825469894b80eb4ee4184757fa1f27672d9ccfc4b19116aa2a634e8e1221f1d6c949dd1ec02c2fe5c7dff0917eade49f84302c9b24f47124efb993e85c628247dc27fd062de828097e5cedf077115c0c3a8030b51e441fe25964ce1e09bee8114a68805198152e07ed84c3b64f616de6c2c19fbb2c94fb453db38545413f640440dbbefa9c60b3e131206583ae8cc5a501ab02a4a45f4dd22c92fa04941f85948243489ac4013098cf2ac60ecbcd57b80036c4764de72a3c353657056c06f2db161b6a50ab0241872a9fb3f4c861c4f4cddfa450e146c3019e9f8e5387de281192c1f96d0a56c07d5a648227ff1407965ed0c8bccc2e45afc62a34dfe6359c02b5237a6b7096e574038984d1c6c120166b62ab4511d54509db9020eeea9782f8fce054a87cc0b41a78e0c252647070881072fb197cf88fd935ac2e304d58de9dc1941174532a9b77c1117478bccd1f78c8b87bf304bccccd3f453afdba9b324be797e32ac5b7080291ef9080aa8243d6c5a52723cac1909c1a33c64d8a4b0b1f43d63005027d09a741edd536437e8190d94aa2f487ca395d812980b20e88c10f6b747e25e7f00c5339e4439a619964630805fba195c75d95a9106e59432b473ed9914c22aab0e8d6ffbaae4e7e81b2c4b59c23124769cae7ef58c5bbf8deedba22e4048053b8e08368390ac47884cef1c173f9f08a6d2f0eb97468c0a91df309006c6a1a2646bbe8b4b51b9812177849fe6d67281dc67746fff8e2b14146b4b87d5bcb8707004bab3bac8c3f9cdeec773fff17b942822c1d7b2dbe1ae796fd8a033fbe0f118d56d22ad5536bb00de8bab6b0de89f5515ca68c1993b5a06bfb87950f068265046bbd408ead1fbf8c85bff5cd87a7012bd3f5302a8c7fb4763eb5183e1dbf8ec121a9f66ae54a4df68dcc72c3314b990246dd653d3459ce6cb8c1207dd3f25008c17dd480237de4fdc35f26cf55ea65bb3d54464790e02f375db0870a1b14e88e5f9aa5dcb43f0fef70ef80f20b167a12ca21c3cf1d3a4bd93880b678a6f025343824eb14c778e5666270655ae11c6cf6b38a4f0870705bbd0bc96cdc1b52d367cc9cd229c119ed6e988450d12d60cca370d08695918a18b3a91478732ea6deffd31e02b20362c11e9ce24c0648bd9853142c7f76bd37b35ed828a412384eac36e0b454e1bdd327bccd63960a5c53ba8bb2976af7b9c5442054441695be40584665709e157f121afa2fbf201fee4c97881c966237dd02c2ec3a8009d6188b23434567e66cf7a902e5832eff9c26adf9e36b1185efd1abba0002ec01d3115bfce4692003c158930b27379c39702f07c11fec017bec4cf438d29331583d5cb9dc639ff206d9c91fabf2f148bff2b4ff1907b9a0864e640931b19510c225c55f14c007bc8cbae3920dea4804b3811b7a01c294e532e157b87f4040ba1e0a8a0a2b1f499b43e219f48979b160776183898545ef521d1da9f0633f03e9cc351bc1a87096be6d8a315234c27d4dea2291765b80db0a7698cfff070cb4d4c2e6c59fbaa34987eea7685925990005d1acf276bd70c8b0cb81f89c1d32cbb6df4d1facc82032221aabc467a20c3e0e5d3e6d0d75a1156e910ae1461bc274357ad0beabe08b3bb05609bfda00c5aaef3c106332a3bfb2ab3f9e75791985c7fc83ce344762f25e64fcd29aedcec4f97494a8d74c7bc758e3721fa5bf70458a2ea0e8920ac540783adc93efa423b7044f51b84910a0a07486dc92124e2fb333b798e0288aebe053811788c2e325d3bb5c1d462e4027b610792e37389ab53caebe6f62af3cbdce37b9af3cb4d63700df6ce3f88d1ff5eab7463b59d8b8fb4d0450d3a1202699041ccc5f2a4503caaab09003c57b31d7e37daec8737f62a5106eceab07b971d0d6c4c5c1e882b5118d9317ba1a32ab26c9cd02b2ab080851496ec731fa9666fbeecd0b76af5fa4e189e4ccb5f7d11088c8468425162d9962da8d823093952a85dd165b2759f811a862c1f2485914c337d2e9aeb54ee02f8f49e61d48128213b2368259b9ea2e5f2ec18fef363bd80657f975ea9dd50bb34fb1808f016346db8b23814ced722776f47dbc207de4db503c057046f47f49bf21703fc5a53d271d208eabb72f30792f2f0ed8ff48149aab3c19e15c60201000ca3a6d7b6e45ab48c89bc1e833f74cb03663fe09bc807f14f1129a1d964d597d68d2dcf7660f92b64b52c47c4a3192a7c0ad91079753d9c0c434b0d665d69370c6770b1c18acfe968d6fe2ca949261d7815957d3a4927a867d3319c35ea4b67bdabd4c9b2f3068a71de7f7aa74f7443de6429d50a62d962983440e65e28cec3c4878c9db79559f87784f0ab10e20edf9bb3b3b69cd03f3151d39bf4f267bf8c90bd591d777357b38c4864d39d7be3d6191bd874dd013f4ca065b3d74811e006c831f8c369bfe1606d173a419e2f8958cb80ca89c7f7eeb63aacbe298a5c978af8820e5cb7ec66ca9092406b65fcc4df2fbabc02d560549f921e124b24352e0e0417a90dac49890a6a51d2316ebef9061224621b0407b7c1da9f2078fe368e9952fd781e3a155829672021cdc08e666db3b3b41ce85d130a888f422eb24e55def4e615993a495f19b607d39e2620d34949911e4f9cdb43079f4ce5866b374f0c80f358698869f32a47794d7c1f672596090f3fbf00b8a624bb52e41e5efd1a1695d269551ed7e62133428704498ee4e6cc9f53081f86233eb6887118b2448840cc7d4a84e962b2aa354ef779307e73b22a91d7bb6c05f05e318b24dee7824a06ec98112c85b2a7e4638f71a4be3bb44201069584913e503883016740f176dbc8827d86030b2f1a5167652241cdc01b9dddd27a2b6e0aa4a59c3eff0c12f0c48f63fa11a0afb6e6b66a7f6f2be5e625884e56741b888f8a691671320e52738c7caa30a0378096041e2aa78b1e53dd8ddcc12c0fae1293eaa3e2834db11d4d803e744d86e922921d6789a19c3c52e58d9bf19ca59ff9727c1bde2079d07d38453ff43f4dcf779fee18390dfbd981298bf9acbc4a2d53634f36e1eaf4d8fecb4df053712b758920e76ce94dc3dc1c0b7fbc7ece310cf3f44cac588d63d35ac1b6d9bf84a00f4d10881d8119152d2906b85cb0100692322a0dcb76a3a6033577fb6c5b99c33aa76952b490572e01f178e79e01de2790a58080796fa1848fb71c737153b1f8812f080ab7844f2ea8a4cf0a2a8aeb3562c950d38a664ff2caa37fc8c0523da2b14af03e46ed691402ecf39bce2019476a02fd5536f3389a35e6ca7cc75e9a3f0ce3a31f0e89f3f75b307bd05588170f7cff65287a0c8e091540fef3f232c1063bfa0a3b29f9d78a420c1388ab18b6af14f9389d743cbf0f25b12bbdc0756143cdaf7bbc42c8d6b561df8ace66363c431e27b3c75648bbc7ef993c378fe5cea8bf29398bdf6d2ba1a85e7c143f5dfe2dadb1b5d271fcee984f9330e9c3b6ec4461f798f46f08abc7c601f4b7e183043371f38e3a7cf055f38413dc13d846cf5319c475710992671b5f571c625c679f243bfc85f25ae655ce205534caf0dea724803078ea51c0630cee3d093bd2f02bc21f4fee2580ee38afcfd5feac2dd54025c938b0f0d773a4e23d5d6862188dadb3dce9b6f3e125f9adb36b656a3bacbfe212b799de2a5e6c84b39b3f03c97712b3fe30932eacc32a944fef7f4d2811247b520222e4fcb97c2c7675e161995ac9e8be7e1e0e455daa2285539f36c0ec4feae2953f480b6eb4145e40b7290037c9aec222ec27e1921a5046172774cc49d8ccb27e6b5e737fac4c7b8eb71a48e8bc1e6bb764dbb705838d75c74191920b8b03d7f360896bd16e8a5c485d4a804bbce7ac77965c1c03546b9694d6feee9eaa441cab0c786709ae6695b42f203e15aa1d37e1ddb37cc34422d23a684892bba05991b08ced036c749a38e583727043afe3fbbe5f8bba7f2371bed4c647a31749e9800565116e5601d33294d12acfe2a9814d5754218bf7b6a9752065e6ef831de101266d108f9a3cdabbb26a7955b724b8efeb07efc1c2655795dc704384025ae8540c80c6142a80e89c36049eb6c46a468772da4dc8cc2a4618e06b5d8055338c3d5c35057515ead491dacb420b88bca51d5e9d489a1c3918b41f3a00c4680631d3854fff7c2c45a2559fa44b4d75e06761ed4b6c6c6a1dc15f7eb50264ac56bc98fa1e814a3ed725cddf162f69d9a7155cb6e775fad6f3706444287db67733169966712cc276e9b8a11e20f82b73c83e9fc543a73b86e0c9357bbdbb8d34cbe4062ad3c5572c376913628ed706073e72a66fe8e0a246e001a0187a8214ff8c79c84a4910fa2e6743a1d9a0e1a02482361a0c48b0bb164b194239b91ad955c28b7028e7b29dbfed663362fcfd982b2be213e29f0997f0199b527a400a4e313ef2fa6c47da8972134009c09d18bda1216d28a7c19c16aeaf065310d4862b7f28e4c62812ce9c49140ed25c1b2e9d9aab0945a9922021bccbd4083a166bf3d6969532972c96bdc3e663e8b712b777b56f6220ad50d7cc79e25dc8d447670c44d2773b3247d575e13ced21a76840a31fb081cd9174fb7ef315ebb28e4f7ead01a3c7879992f030b2da5a73447f894140ac9394dfb888c4368670b5a2fbb9e7a077111f1e4acb674f326ed49527557d81e480275153c340f53ea642bc8b57300197bfcfe8d0c5fd879a18bff052d7a3baa2a4ea8b8314502e99bd494b478e91985d9f6cb2d3112ff3d72ef206eb155f4ebea9c1e93768108689d80051f4db7dc9b72f649cf8e8bc9f651bb25e5e0acd9af5fa65652db7c3519163cc2f7b7d2f0bc38076037bac332f9b2221040f0044ec0244f631f990424c62b9613d3821bcfb8d47d12dd7a4147cdc5d5f497008ee76c6427b2d5c523ec75983d80739f018763e7514f3e23f9e228429d7f095ccd34d6e3bb1db6e68d1e857e07486caa06f3dd9af15e6e4ed3b6baf04470eba09c8563d91f8368fe6b16794f8d266de3d17f8000957df756f2a61aed09794c05d81335283c2dd11606bc1154a2bbc0bc4143e5b645ca4124c60c991cba028e6cbbf9b7d9af4dcb14eb4c8591b3e90b5e21619e9d97ff9e84d5fb4ec72b7577ce3865626db803a4b8d876dce7b236163e48570a21b74d19d29789438558a7b82b72a43ec460c8ce439a3ad97856ca7c1211fd5b515c16a1b05c3d77ed2012a87c2ed02a4ef6188e387e6a29f7e3100423d5fef8d2a9f2e0cfca1db41fee0a6688ef06debc36b9c5d3f50c355901eb661a580609f828015176025a68cddb695f810ade7a91bfc552f3e936ca45d1953b34fd32ef20f15964bb1e1b36ef92a54396bc11b100036659f40177eaa7049571043581e0dedd9eec1470c2cdb01a8a47049bf4a4924dec454ba429321b655214d6deb282820f563c4b54a0b1dd625d8b35f787e2f678e57fb945cf1f14b509f295a5c5ba11bdd4baca32d0600d89c559dc789bddb1ebf204ef02f95529359ee7c99d354111b9853e3589fc19f4b8d32383b65ff0c23bf529ae22cdb69defbf8c8b7e1e16b223150e4f1f20840889b0f9ac1057904b139079fc073c3474e44ed1e1c51e834d18d3fc92cf99de16ab674a5c7e6bfe1fcf58e1db1f3c6309b5bf6b515864c1cdbb77ce4bd83db8085d3640e50db760553ecb698d74d05fe4fbae176eb74a225a3fc067b7279de640b3055f2d3b791f17cf68a3dd89eb5489e39ebcc06e466efe1ef12ce70d6e676c36e6da9c35d6b14be95d48545475b8d8ccb02a75268dd40838bc1bd69930013edfa7fd5798d2f2be9fdc7edfebb343d3a56c58b02e2c620bc78cf4ccda83d83ae94adca5accdf57d0536eff02080a0ea4a1c2e03c0f68d3afc12c4c752a23f5c346df83784fa8b69b5325757608f723e34b2dd408c74574b564f9b1eca69a8921b1a6bcd2415517f280d2b0ca492521695543395a6bbdc47988e06c7ab05458b02ad9ccf0188434156d6b38275160a0b7bf103aceb5288ab4becbc8f1741bb2c8c49b1da826d01083e83b962b4418de57467ca8df46f4c72362518b4e3375adf7762a6455ff73ec2446e93d225edfec1c6cd6cf2b17d83586297e543b5c65adb9b5d6f466f8598248a7053ef52ee31ddaa20582a3a24970434604364c5a6c4727477b4cf9af55d8dd3e6caa6b50cd02a8cca2278d1f987bf403b9893a2978f730c5c9b52abd976951b9ad6b6f8cea8230ef4a1e44005539bbe44290fbf279112a07fb4358efbc17212ebc475272d0db183e2fa570cca5d547a6287e82ee1f0d2ff02a6b6f01628a38884f6f39cbf479b890df5f777477e2bae184fd256063db935bf9a2a1920e103ad3f17d6b592e7c898f2dc70416f8b2cf901b5127578b5700904b4400a1cc24f5e465a38532dd1aefb01e7752aa7dc1ffd2657e8458923ba07de6ba824b264531d9338f55010f770e9fcf89025b8ec02d6f0e2f5971147b9299e37a70544c72ca8b388ac551f0eb63ce79752496cd925f08c4dd2b63a796c66023618e2ed6431735104f4d6940c6423957105acccc4236e98e1237a6a4b2302ec650d836ef4c30c4c149c8c4b76ee67a15961270e3ae1140ada2d23182ecea35aa384d57085e8c9fda3d2f6740fff763289f71a831e8c099fcfe4a0d8273b28d4e2be82967f19e86f0c2ca9ab4f10aa2fec15039689e95fb569cde292335ba471867c0f6be2bae08361c485a9c841c4ebe0f0a6d9569227e8a986bbf677fe25e6fb8d14d180c0a69ed48c02529bedab06aa752875a553df6f01ccea29cb2374b41ffdd90f4469672b32548c283ac9c287cc0ab22e0b0feabd3dba9fd90d56fa6c1f62a3f9e2896f4dd1cf42493e9cad4990081a27c88caef9661dfbbf4b6c663dbdc12121f2a39734b4715e92473c098ad7aa2893096dc23aa33be2c1993959710fa7395ac23bbc2809003926ebebcd4049c6040bb088c4423485c2f76c809f1726596c646bdb8366667d1691fe7dd59f46aa684ab6c8c31ed3ca15e2a5255f3d294997cb3e219b35ff27bbaff071c8ba88ebacbb69ee51e99119a6b8c67911293abf4a4053bcb090ee14ef7b60583274d2f4b41a30d73a92c3fad96dbfe33d53887e3cbdcd0711e8c9993b5adfc8712102bb468a4a1f674e00312664395e898150a39e8ca0e666113e1b36ae0602fb5dd7d8a44b9b18f5bbbb65c310b28b72caabc97eb3b2e700d4bf59c4b553dc37b2b62265ff316173e40f4fdfc68608c772927c5fbfe49679825dd1b3a8dee9852f70680457e741101964bba578b051066719b863caa12c38cb293d76ce5503d42fe7b2ba0ffebfe0d4c22bea059ef022a151bbb55c0c28cf35fdf7ba22004c6e33abfaf9527dece12588df388f12a5c41c0c72e7fd1657d39ff62b0ad844fe12f5483655d1c47c3d6a2853cbe45811421b43d6dc43dbde2e3cd618450008e62f6a7f3fde8ba2c820aad7c0dcef0fb8b7fce956f4159e3b6ace61736d6ade6300a32084eea0490d3f13d92b7c3390783a29747254eb2aa0addfb10026f7ebcf027333c0608909c2664ee3e4546f8e0a44ccb0abe3a1484b0ac80e51beb2ff0e5b93bab5b498f693154179fbf6c10d257ce2319bc946c56d3c8789df4ad78639e49b7907088a99a0bab7b4ced2b72682165a09bbdd6506cd3b6fb7d4cef87ac39b685603a714f737fdba4a3dffbb168a73a4bc5300d170c5cb2826b843b088773114754614e510056fe7af95799a0ecdd285e3d6824287ca0726e54754ff16b2d30ed23d09fb21e8e92129dac75dfcc1ed459cf2fbf0b25ca9057fdf9f2ae01c129735d7755d53c97ff2af9c24ffd993b9b3db2641c2c237237df269d6c22bb8c91be4120944afb2120526166507f6ddc1cbb31ce6417a932334d0dd59a49af178519259b7a845ba2f07e447b909d23138ac057dca3c0471647c1d69ca7e28a04c9fc229f9ab94889de1b2b3fe13421b9f1d5eea29737953daaca4b3706fe954ac3d25e191081a065066595266945950a6a8c25b26a2805ef245eaf5581995d21b03ad269e332172147cb135c4ab81bdbc5697ef19022a47651469fc96c0770a9e70329677ee916ee878fff5b50b70432b4aabcb99387272238d61c20ee550216e0d93cc8c3673dee9848c239923ea58beed14b451b3fc4496752d4bf1bcef73040868a7abaa6268eefc3728d14c7d18070c2bdc8474c423c3cf4473e10bcf1a321364656595d3776e34de4de4880a1899bfdfb65cc7809f8901e190156798b9acdd3474391871c9cc04f98b3bf24ef7c4d587747fdc05eee40429d56f1251461cac6d64ca897338cddb56f61dc37a6ed648e508fb157163c00714de27312229e24736bc1e962933143521218bc1009072e06b3712e0d30606ca129343110eb68073faf8fd655cb16f82e8bd1634e4204776f66755979d4e25a0c93d714cfe9099dc6a958da426419033b377b8361129bf8589c5bedfa188eaca859bee42b4ea86f9a670fa5cb780fa36ce71a2949883c1ae740cafa15dffd8e9c44b88c7fa3ead280d9c623e0ef30f38dc9b0b09106bdf9f7c2447df741bd37d020400eacbd2e25c52d09566cb92f22405df1468cd0410d28dbc48bd1e2b3151fa9d6dd5b93ce27ecd35b9b6f977f6facaf70fce4f1bdc803596fc15a60dd37246ea140bf10ec05ae275223d3597c5aa19d4f0ce957000e886b4940c711c948e5b66f21dcb7472d340e0887ff04029f22fd2d8e9b404294b0915e54a30a5c996ef3a0eecde6f060cc38d1727292620b6fe2fa32cd71a935104c21230d8d1320df0bb9a78f56c6d35f7cdc3112f00472be526d12adebd3f0349dbec7128aedd917716c7ec92b5aba47f52207545ba2522c614ad462c660861f58bc235224969a9dc07b85adc193ba1a3373c0c0572a62d47b8fd57e1fa257d512a59d55fc883b076bbf8fcfeaee45b3c09312bb2cdc52755729eacc292924019acd6ff73064a9c6d4c497690cec0d763fe47cac8b9b6dee088ca0d0ef0607a4a7476556924a8dfbe42f52dfd7b41058bbe563c50d6184f3671562c564687844a460d5729c38d4050ac0428421f8f7e9b604d3d0942db4f89257b7aa93ce2bb2996cb34991543268f980d42532c9b84b75988406055f7a041ef001b8b79d0bce8563870f6fa193d03d4167026a74f5f6fad2f154d5fae917eb1a5d890688ff4f075f7996d3e967fea5b7c93350025dc356087dd97c727558a55403aff75a5a725a8ae4ccc38e2af21dc2ab9625ccb21d84d99105196acd49dca2faa1e648320dd8d7fc8e4212327ee54a83f91c22fc2e945b02430a66c08091451effe08f513e021268704fb2350f28464743c8bb86bda70e20d616a7dd891c3df1a0a73239a7a39a19e19104cdd7a3166019fd677384d71be0d107ef72ea0973b47d76f0bf4ac7e94e1bbe7dfbf9fd967e2cffdaae66552d955d4573e907c125d944c55a9f0bb5dcf833d96556947209125bf4c45c655bdb69bc0639d481093c5b97c0d7401b83cd6e6e603b3ff0058d36f3ae6ef087e6019be08cf87e8a55f56ef6351fa703f40b34430a890de383aede166547daadf6c7ed9d9b593efaed9212cdcea0026472fdfc1a8827506b32d0460d25156c4c583247f7f591aeb3423a7d362880d32e370868cdd83ebf1003b931575e673c700aa3e0b1532d0807489c062529f2c3937ca668a8a6c071387bca35bd305539b5c3b02c671e80519c4f2f4c32893c123574606ce8b0569dd3350c97350230f5c3218131158706856e9f8bfa8a7e7e3b7dbd0dc30784a49d9cd9ccd947b1b4756e9835c91f964314116589ab89816394e65709d43f71acfab06578408c3969fde6eabd0a05d0d5ce6e04a79761de023d4d1609498df71250c7049ea4c1fbc5254fbf6b6c7e8a7323c53d65ee5921722c367e27bf0de2d6fe3c147f46f7d90f78fa143533666693cb560e3415e365a3564100cfab98a014052bdae9c71cafeb221c58e98409f0f924cdb44484d6546a7a32fd0b6cf570a815387d48a59dee49dfa9918710edb05861dcbfc96a8a22106df4278fdb84a0482ec26487f1ed8320ade328de839f50855134a63062275c1b93990f15409fd6dd60e956e7fe23ecf69f7bba5aa94144df1387cbf4d4f447ab7f8d8630170f45d21aa19727157e19bb02074595d57b598d05d73c3bf468f1eeae732d2eb262f24a3039219c9c4071a2acc1dc61802bd815e7c03d6ae74417e0379e3a8575c625bf5eb42adfac8e6ca33d8ca386afc14357da0173730de4049af446035a3883a9f10c4efc6548b4200fe742c476945a23dba6d3737c40a0e02aa44ba4fda821c73ade36cc02c6fbf10aac577b7b0263441261379e3a4d782bb177f67dfaf568f92b336772d7707a809a7d3aa875857ce1a89c9ae6adcb0d010d9c01d02fd6b7c38c580c0a927ded4a20e020240118689ef0e228e6a84ab7cb5d88b7058fc2eb9e8f67f77a285c4d341e143515e11e8f9219866dabf30a09e7ba3de1cbbd05b1cee9acbfd825eaa0145988d5a8877abf20c207ef323c0d8a746ae3588589d62519dfd2bc2ebafc9d1175267dc1aa58b10cd085c1f17b730ea6f1142cfd284156671f088cbbe183bb36566e626c3384ff517a1428afaf5a08368b8dc3bb0c05b410f0d5d05b1126196ba6b76361366f7177efdd68257201286fc9477bcf6fa7d24d25afbae46ce3e3f37a5e7b0aa55fd54028dd344a0ae4c890cfd4924193cfc6fae4d0cfb8af38e2878b756c47a2ed26201ef471ae46c73bdc4c312f3e9b8460a2a4ac26162dda25ebfb7d3f09a96097ab71b9537b2e28b4328c94d29b91225eeac3349a1a47d1a10dde2a23857d7d7f9ba6c48169811dc902291ba6bb36f6933e17605cbb4e30a3dd34a15754fa9859d995100482f75db689e9d982e4534d5ea08f66911a7b0c229839ce69c7dfffc2497ff79da209741d4774d03fdb0f2c885ebc6fca90395bdab29888d54d414c8e600a754af666a0ad49cb978eff608104dcc73f4c830e1327736f12d4aca4b8d8523e7f624ba51701ebeaa973100e241d14d05418d929a5d1d801761abf1185690716a2ae681afd6457923f2967c864c70159bd126436a005b197fc9217212d81a91ec80ce075dbe12455e88764ec08ac72f04679fa698fda34caaf60d07b49e49380ddd4441458541ee134214e3a5fff705128987c88d16dc25772fd9cb19612b82109609a47b894d03eb3d2340572e013a245607aeba5e975e73612a44888a88da3e903fbf9895bb3237344ef2aa9d86b82eb9ecf6ef118e43b49658c2771a9d11f229b856b3300fed00dd3fb0de2bf4d7b1dc577712056d17f2d71717ff7a0196528687f540e7fd1f0627a61be6f4a58b8bb3244d39beb808c279cab6c370e2e149165d119124f4d9e0577998e56154516eb075dfdba4242f0a35c3f081c886337734649a04dc9848c42baaa06d712227ec888888c87a1aceab18ba4df215171499224f06cabc2389368bd928842e68c0776b41e0dc3febfa00c20fd2e379f26fff27e68240b301bcb21c9fc129f7249a66f1ccdac22402620163b5e3cba1b90f5802b320cdf687168e48b428861c82f75c3af613ba24e2a540ef1f7182269f524d22d648f5d2b81b3ad5646507e671493b4bb3cac8183dd411db242add2ab32a6e70b69353f32352e86b3bcf131b8b7f41d7d14751249904add705998f284ef3792eb76b5ba22d4d33ee2636a2644fe67d168462ca6388d0324263aafbe3875ac57cde24b7357caaf830f5f837305d8669ac385c0900eea170660b75a4accd6bd7a9fb59ccfd8ed985402ca2e3545f5fe8613582eb3bbb4a914fc51e17f76f1646264b82bdaf148187499df00df8bc182ec06bdfbdee56e8cd754adc5fa7556c426320b22ca1da379f68a0a7c5077e61bade03a29f001406ac6f86d88f165d680c6bf565d33a69309d3d3987f79355eb48811f4153758ce8c2cd030edbc65eba1454f567557be3ab98283699bb3a3bf38c9bba05e31e7700d2bef0456aedacddef05716d4027392325057842793c244a76c8d14e062b0fadeb838a19dbbe83c6bfe4ac5a1691b92e3fa9b9617a210c193672a4be2ce6d74cd35c0f33922c16c3d8aa1e18248c4d9fd1422d8b616bff15a781013f42d0cb3f991073aef4a808a9db34d297804c32cfa4fc04f3ae14c5fa6577ac18a6d8000f09e292eff33f3d0b3239ae334f97119e84112904485328efbe95d69a67ff5c2f659bde1c88be6e6a7ae90facede514732f736763cde4d8b4253a0638b0063703d062957dd154d496c7a7713df14441afae47bb4763947075bc9aaef9df92b69d967ddb073de59d11de21cc44cd8647c600e78096031a216d64e1949295633ebeedf1901cde3f300c49b228c76efc2aadb1dbae929112635aea7633025b55713b4fd1666fd8382e2365037544d22b3d81e0230a0324b0089262404e3effb62bb03c662166688f0aef12283da5db12e67df46b0049a2e1349ea74d859fbd43274f2db6fd76505c86c8ddd8e776fc796abf7841f780449308f65165cc34024b7c33aa75f7797bba077cb1428c495c75f1b91e340a2416c75cff1972ab5fc1b49de2b0f2ea8e0319b6edbe1a56f2e9faeb750a0fbbb5d95fd65a212c7df4b7b9b59e0ff5c081346ecbae9e588e673d0319d76272c3802e515f444d3d5ab4648897487397992f6d26bca4071bbaa677c5cef3a986d629cfa4e05f76e5655852898859e8ecf33aee9d9591824867cd12068031fe9f551dd9d1cf67d604b473d940f9700846fed2b33667b0c510188e11ea53f62e5150b72f9318799b4185d454d882cdceb8bcf9e86b1d6783286bbe83ff40c808ac2a073b61f80c0d72a326815671012c8a6a9a5ed456915bf04450f3fb7f106760a923a68165c5ce921ec8476baafb1dad62642b0d9d1b9e4f5312872a398b168ba568ad918fa4b7daf2ecf64895282dc20e2d151be036d82e8acc2f514a263b92df5a0261a201af7d7b71a2104a7a29f5095a4c0ec6c8bf43c2131d924fe58ca97f53edc4be6d20b777ebb2c64e0829d9c32bdae54b4282573a82e322a5f07b20adef06928a64e141fb4dc40009c48a55f4fc03d2d36906a47a6d2b43a7e70a619198c83211c55c38c742b99492f74897244645f8ab741afc8b671047f4c214ac881f0193df1e1964b4475c2cf668e76a3cbb211aabda17049ff7488120f8f3e5186de8da70bd2574c05276b5b3b2162a8a7d751bd71ff2667565a6e8a5031a5a8f2e7e2d084ad612351f33529affd35926f083440ed4d036744338c7d64766c2f5296590da6fffb6c32e8792fdde0267442769490f856aa7886863585009423fdb21a9769c6c7abf367cca2786b677f4eeceeabdc85c24a84dd336e084d0866bd08513b4addb4ee6824e5bdb3024ceaa083c3788b11f0fcc9a5a0164bb6f6939e96d351e18d0799afbe2f312b5293f2b21cbedd8dafb93b992eb2d47e0f3a6fde963344b4b8b77cf465404058458f21495d952e225d09f25ae716794d2dadd88ab8d3d4651b032e60d297fe89c9049bb552f712e7a8cc0cbae2c4a4b5d061a5e7502699686a5b1dd986a662254752ba91d6884cc68d5871a666def3275d35b3928f32d6e93a56a5a22ec0ea2e1fb8822122d555825424eb2f4a0859b906029e5c37442e174c092acfc6f4829a5239fab290bb24f4ce59a65fd4e80151ffb0817aca794759ed52803987d2fa060e4c9939a179765ab04e8e5d1ed4c0afd3a4cac34d5ab93eb93e0964666a9975b9026bd47bfdb1a3aa0081b989cc81d31c3e3ce0fa35d408f41f8417e2f787c40c29296b8582cb2a5e45e3fcf524fad9397ff9717b72f828e4589de08d50d1b73038d600b0c096f668c862674ea6c10bc068ee2016d093c2248a0c30fb26b5ba5e850d115f98077f61744cc5b4a1888930bfe2b9e30d4cdb096c7a1e31f3f0492e7b5158ac075d3027d04bc07840b56f9e768f95573a3a4afcb9911e4c8893cf4243b4fb8634998e2cb6b9a2c9da0f7d695a0f2c83b119e6dd962ff722275bda7726a85449dc789b4d16b5801f30474b76ff03647e8a2d71dde22b5d33bc74124ddf5e0a2976e8950d6117a5c2561464ae028668962775d890e1bbb49567e482a4c30ef247141456549fcb8d7b9aa23c75e74369367a5d0610c515479460ad39119cc9db96856fc1dde8517105d386157b2f6c23ed5502c2c2a6500df5f3db6267633032d18c0eb706a9e28ab79414e547e20fc482d0c470babad11d2265c160f0acc798ef6993467f5a161911991c25aa705bcf7d73eb50742e6553b24e0df7f6dc11727cdbe5dc9b0fbea24db182f5767ebbf0ff49107f436d0bd2170c8ce8d688ab796584f46d0d5c4703e825b4cdcbba5dd64ce9da831152ed92fdfaaa8abf468dee51dcdc7cdc23e13d0b546a25b609f49dc5af5d0bb12c8b892dbe5408570e4982ef7f69557db83b382f2c314f0b6926d829ce6020a68990e9870995cdb8cd58e8d841d9c552b0cb7cec39ff4db8e714ed40e0fd649feaf46d08c1ca17d40531e8fa2210bfae44e7e02917bb77d7c30529617c72ca3ea573bac6d78d9d094bd8e0fd200a856337aa600d70f2fb3d17079dcc227131c6e7abf42b4cbfc7859382bc9d4d790ad9f62f7be15ceddb28f240beec53cf3c6cd0e058ca4d70dcfc972c6d51420ba84de5d963e06b4fa420e2ff2be12cc2070cf8e72effeb186b318f056f4626d3d1af844c58ae63c622467cdbc482bd3901b1d128a7fd71e2250b122535df514425a402a8291538b3fc7396c81a7eca9863ddccc6303e521292f1d203027b0997e9e623d5c5a472fc450dc02772276cbd5189ec5026bc79493f0c53fb84c6e3c4b18bd974de29d00e1a6a9ab5c0cb24eb112a896e8628bf12b0f17257f6f4e48f9f5178a393e0858f3b5f2e3ed90dac118cc568e5cc68902a46a50d2e3eef41c70105e2ebfe00030c7d259efb46806b77d64be5ef547cd43c4e3c3b64829f8f0eff9675066be247cd744e3f1205333f7789206becc8d924594d2880b1a4c4f5928ac206f90b01a0e842fa7da8f119c7f02303e5f1bb62fc4f91aebc45d5e439df51774b3ecbd299ca5afdba7822f6b30975e786a6e9126273c8d091a14d6ec8a2a634fd6d58132459aa3cb6c71a90e85c9548aafdc9b4dc0936878ebb2faba02ce7ce8128acce570a6390abaa096aafb260e3abb5c02922576a502cae3ac1ba0a390a2a7524858ebb7290455356280809069921de0b2ff8ffbd8f91be0097855911c1f4c6e1b2dc622a5c6c9fc240bcdb96c4174d45622547a8c69ebfb617d43be519b152588c96bdc0024cd820a682de20493928b1d88914f92035316ca40b38a20bffc407f0e24221c633b2f3caee427c701f15cb3eca914d61b57ab567b6585e85a7a5683daa9deb1e6aa4d7aa3c793c2cd620a684644ed430ef101e5fee403d74a29b7a3960e9452041dbcc434f8e6fb000399b6681517500a50bfd3a46cb9013a56894e5750ca58ab03266dfb11d5eb65a82e695acdcdc876a7319d3203b56d5b8eef9075294f50a25b5d23e8351a18475888c3280204401200811c4a41b059d28a7f9984cf87861e50a1105d165fcfb9265acb922d654a49262965b004d304e50457ad1a435974d8f715be47326f86eab2bae0e08e7ee37cef3d6da48bdc060ea6464cd9134877011637746534686ab2475f4b03517cefa96838dffb6de27bef5d39a64deccc24475051b584007195348ac6b53889003bfada9da39e017e1fe1fb9befbda7699affc42a6546697e9acdc6755c82480724175473ce39e79c73eef139e79c1fa99243d9f8a139731c1a7d83ff6ab987d0bd46ca3507b88b2065ce6b57fb39fc799487c6e7209f6f9bcf798d61021a7e172916e33a9691e7babb262a606c9bc4fdb3f177771ab6fd1d6a94fdbd1ed2301afce6f6fe813723fa7b3d8433b8702fcc8714d216850f81f742063e257f5abf0c6778d3fe13866bbeec16d6c2f0d5b740fc913bf98aece44eb26d939d8c61b60fd76f1741cac9388edd13f7f327ac5695371c51f72b013cb226011bcc2255807ce4609358f0d38ceebdf7de6e091d77b59f509d8f9ce126ad6cbe4ca20bf39981a6160cc3300c73804734f861c1c17b61030d9c01b22b1fff835b32c1d8f6b981c7f1c326c98048830e3628801f21b0496a66071aaef4fff05ed850b37d4d4c7e8ca591214296001c3609d905b1851c0be6bdf7de7bef7acb8681de6e273859b25dc84ef81f2a706d9f0278302d892d1c55b0a540e6e35b31fe37e9967cbb2d0602c007e083c1821112922ffc1ce01193153b391208b7bc302d2f8c1d4c120300785fafd8d57aadf01f01b74482206d07163e3dcf34865dd76e0956fd645e61188661188639704b365c4510f3ee65d9771e6f0c29ac42e4acf3d854d6410c4c7b57f86ebd432a7cd73de13512825e231ff03592825c2327cc35d281608d94608cc051232174d4c807df2dd23512a4467e144f40ea62481126816903c8d0430e1924e42384e896c03531e4c32d816b3a04c42d81e1ba23e4815b02d71c2110dc12b81e864408098648704be07a0e71c02d816b396442088590072008a940d3c66dc241bb25704dd3ee89fb01efa924c720c660638001889dd4f581f87b704b4eee3a7852a07bb3da8f74b71f3228db3e27ecbdb785175107dcebb2e373008f58985ed9ea18ceb06578176112b82eca2a1b88d1b19ba5df2d522c16dd13b7ae761f21c2f7286e5810b60fb2420d704b36c04816e96b1345c407f102601383052324758851024d247e0e6e498d15ad61cd8303782402d6fb8e6c135fbb1ab6c95cbbf52c87d0ae892c8b70b049e03a380745dc4d32639031f8901e42c31c6c930f9b04aee5fac336718f5c0429c7225be4c3fbc13d7195311cefc04a8eb58f7c5fa79cfd48976de5c13f5e951d0c31c02315a4281835d430c847f2188657407eed964cb5b17505912f076e8904371a78e79948942081c8edfabbe600675d9491d16f9f8ed16fdd827e6b172b760d03fbf2f2a033d0d2c086260e5df7e484f83174dd9302cc1f699c914622d2280169441a9146a4b100124c76bab8b6ac1030f85b84b6c0898ec0f791c61f2c1a87bc4abfb54b9d4aa350ad6716166741f32b095cf76402a206a34b02d73b0328b7e2559c6ac4754f44da3ed2f861633d827eb9934f71291ec5a1f81377e24dbc491bffeb9ebc284274d7170e60c8577026be44bf3557a24d86203f86330cbbfe85299ec491f81137e245f45bbb9c880f71211e44ffa15b0bffff10feffffff0fbf07e8d82246a3d13d71395e841a2003584e39432cd4d9d64f0c9c16a6192589d95423479b74826e8a8b9154e78636093efe6c65ef879ba90235da0a2ad15e474eeaecc51320979c9f1d58b4ef8c076acd88cf632a7d91e0ef253f8d3abf277e4ff4999b7ba7f6d9b903545bb5721b6ea1c0d6809b360aebf4262616400b975c0dce39e783317e3e6bdedde7f59086c1360d556b44ddec587332c543b34fedbdf75bce9f431ba31cf823bd5163ae86580a85d0698999738f12f411cbb975e4bd87d2f1a859ddc99e3b2ab6a2ea45a3135eb690a34e28e618c52f49bb2ee86ed2767c6ea8384bf162939685f104c32a395bc5c84ab4912e1a516e686113b9ee616fca9db383d0b931c184b444430305045340322f25d662d4a436947b274d38beb1f5ee91e10ac702dce2aac86da775da8e40191c255b544f075eb8200a0ae6871354a634acdd5393f7de0fd3a846d0485d97a8c78db4a92f629eeebd07b191b2e06519f7ea1dd5533ca59ca19f1971c11452787b37a258e93e5221e49c73ce39e79c730d547d5989b8d134a69644d3a75305f5fa3b46c988b751bdd1306cb9f8f4bd77ef91ffd85fe3f88aab103155d808851052acd6278c73c707e76f7a441a3f984b07184e95d55b180c4016324eec2206b861e5e1445ba2da1233fc58987bcd33b3ae190f1e22d1170dc7d0dee0c26793a4a415613372f7f7971dea623a5b02e97a720c791dc17009275595c4130da609e85864f14ee81de549bbf63ea45e3110846a792e56094a7ac0605711322a4afedea74531bff7fef67a20b2a250f139e7bdf7de374d6c66f5f0de7befed949bc4e5b2ecedac50bb16df7b5f8f54100fe3383ede29b9bc99549eac53a923ce39e742cca11c819d3fbaa39ec02ce51169c4528ad53ee75e2f98a0d8dc62d6943bc86866d1e4d15b0c6defcad056ccb4b9663c3c3bc9379f1b2180805e233f6b5b510d9e8b1f0b27b8154332da20a5fde303bf29335ab4b0ea0d91938cd2988b97d2ccc85e0686530bac9a2baacddc1d64b61be8419a7e91c928e155a5a9f352ac100f2cf92cadf5a198426d1fb8034b721ac326389d31b57bdca35f13ea8725e7c9556b79f646de3fe79cf3362d4ce26ee5363e3ac52d0993b81f69fcbdd74399af2f5f70efbdf7d2a719afe32b77e50e266ad5e44365c4df7bef1cbff7de7b8adf558e7346f4fe2703a4839df5f731dfb4f472b6648e48e3af914298370780cf5398bd5cfbecba58a4b68aaadbb23a47fddc9d6e317dfd0e2b1d0d57bab454167a9f732a56f2735ed39c53c3969f73ce8bf18c7b8cb12dd29ed738e1839c43ac9333083de1f1ae506563d7e7fd7d5f0fe90d6cc48eaca04d68583466d05a5f51579296073a3406abb8dc8865b76339447549eb4b1da012958b9d18df5b77e038f60edd9d5dda3a122e475a4329816d51a13597b9b4a3d41797c2a6a05d00db46983df15c945d783b639121e385ee284a4e488dda2b6e147bc509b53dab5b18de540073332e245ee4a84e527541aa945ff02fa32a967a0ecc0c63736a789c1bfe4dfaa12d1f1d084814791527986dd0fee1d3286b078a8c331943b72d5ba72c2d7ae5c20bad668e6887eb8cc7044cd5cc131d9d89164f781f8de1fade7b4f7326874b21c365efbd9779080d8fc4ce19eae425fc308d270e5da26d97cd08aa2ec6ce4e588db10b60b48d1d796163dcb486d3afaf0939751ce7bdafbdf772ede7da17bdf7defb153323cee7103944a68d668a267644bff7ceed9e78491d5d8a678d00b6827bfe26bc140955984ece839bab2c398532fc4a55b24863c5701001393498fd0e93f0de7b1f0f6379d8e701cd7a597decde7bef432c0f64d2a560a17c9a7136b192d1389aac72d0e09a62eea40142ab30757f4f6733422e9c22fc81d5200541bda0d458a6e3388ee3f885b7361ea56cd6a29c2959f6cbbc722167fcd6dcdaaad6e9f15c7500758a116246da0ccd899aa096704fe3e390726f3e6d271e89983c8768780c6ad633dec909c0a427e591900b0408cdb92071534de12785538a9e81db837bc0bbf8b700a896c60fd3cfdb8ab4351b412d6f29ae76882ed851f738c7d6bb0eca8dd57b4ff46e411575336c423b1bad794e53300ed3de310ed65cefacdb81c6b9e9a564481f189388b5a1ade8069052c038f9a46a4ad009d4ae1a418f2d26148277c7ad337a204d722072c6d03dffa8a423f6d78f0408482fac80652662f6b616e79c7b1073ceb30d91736b0b96cff9998c5ccc0f5314892a4e8f5f94f5ac050c98a70f8d13abf5b60cf4c3c3c6e0caf33292e6bc9115c1d8594b2f8a14dfd4b8e6e79cd87befbda75869e5586a14a277ec8c9aaf48f71a63109c88e439acce140fcd0fb6a0921e2c6d7073c58377faa660387d484dd41ce29e5d5920159a0c130bc4792dd26d320063f4d0d9b979aef5bdc8cf5294930e8c08e818226944518a3e2f9a04d0f94059a5cc177f531a7b5a2309448c0d144326f658b6417dcb18349dab9e57d293d24c9dfb7eb3804afb825120a2f7134c655178c9942daca05c4159802484f68e9e9472491bb32ba0e28ae52ed2c62f2dd20ef97c5f0f697806878daf9ed4cce4c14a0e9413bd83bcbd2a61da3c6d0ce1a8a52dd248203d420a316a5c2962285586785d44987ac600f369cb5a9b4e3da34f3e5a5501048f0aa112796241352c56b2ecbdf7dedf3137894b24dc796d1c55596fd120bd24599819cc8d3919541657296ce8dd90f39a20ec2aefbb1552efbda76c357bef9dc3f1c9284be6ccb987dca12a49a73895f14fe79cf839e79cb30d65332da09f3f2d8ab7173da60eb9b50a38352cfeca9a2566b85171ce39e79c1fa39e43b9026bd71033ba2cea338aab2c4a338fb3610398b4a5ba6c27e7c49e12205aa4eeb65e404b58191044386d805b2d5c5497a96756d0888ff00b06e6c1e9496ad9818615a06caccf48ed25284bcacc72ea9b55eafb7aa48221bd32c37b8f2285a291c2cadbb34821f94671bedea44a96d9fcf23b4566c9a533311e3c8455e5065ff3c63f402c2e6b7b3581b3c207fec4c072c22d916e1e14591025013815645929b1161b209c6d220097777b445c81d3c09819ca232d7938ae3d594f1961b530c57cb146ef0ad8b3d9e4871df3c74f9601de1fa337c785107e72bc0d57aeb4fe58959c39e79cd3b5f7defbb8ed314ea663772a42f643acf59db1b60c335086983391d48184326ac2060f04f455ce39779b672f0fec14c67358e31e9749ce37e7fced2a227872c3da83e2da82110624b41362ea042095ac2582fd441dabe961ae8a924fc2d35658979cdbf629b0edf7c011765d7765726667394ebdf7de7bef50e79ce7342e17604a48537c417a39bff7aa9ecfef0ed07ac2d1c3a923abd1b48f5230b1fbc3071386fd49b2f2aa4641ab5adf67f83e6f4b5545f34bc2896946d73c533c343b83273cea3ee57eb525ce9e4b1e762fded1a3f042b9f849af5d70637b4550d0ca734394b14e1f80a1909a2ebf1771149d39c3ec02f2d5c7543eb4de7bef5de8b9495c79069d62e3da82637740b2567f72e60e49cb5e0502fbe8d064dd473c66dedd8c147beffd947693b8b2d0cfd9ab4e23a1f7c20e0f4b6b0711563118783f375b39c1231031335acb3abd24a9991ae71df6a095b442af43b6d8aa05a33aaf70f179cee1ab7b88ed489953f6ee21437e5bf2b76d500397dd175b0f2ff89230ca25d36be0caa12ccbb24c75e1d2a5d9222c07d75de9dc5c6d68e1c039a0fd934bea2bdb361dbdb75e4978ec341b6fcf0b085c1e586e109b0f14a6222df3e0a662d3f3db37ad02f02ae5b9d7c6de7b17ba82495ca9ec458f19d3ea1823dfaf08c961f8de6ba01635e5ce3917a1e19178c5a863402336f506164796c7226feee9b953c70444dae9483ff34643b2d6fc05e79cab449b439973ce7d8a5a4e3e43411190095befbd57d3e60ed518f4a661bde0f18a8d87684aebb46635642795e3784af18181a4a75c20754a6ac63ee3dce382b4095ebeed1b9615c7aa62c9eb9af6bb152ba777a6340404a506156736a3f7a09d54938b32d59cfbc14382e28da9e85659442b7444348c088c86d5cece2b43ce0e63a83251c16b47f33829a0f0b0e5a008720e62333fb52acf2ded875acf18debc094631c156a4c1662507ce92fb2190f1c8226b412c8e8f4f04092da91611effba49c8f4b8ca934ed76d134c6ab7b11d2bcf7f046402cb6984e9817232a40b97a35a2a34e6be964a29af6e29574812f4a43865ddbaa267589b8e2fc3c3d6d58cdd9c5bb4c580733bc49139a836a8165f17ae000be31a6a66b131ecd91ac4551fae324e418db15a0de24f5d830418535576c1d79dd28cbe3d863263c00ef926f2454d4c41d201030069e4b17975975cf8503c26e41cbdb00b0f0c4bd6e2b3096de872957ae03b0610713c8d61342e76abdf07915fa92a4037cbbda581ba8d38d134022de40d8e848c97883abc1dca25ef766aa58928218df5266e5789e1204d37beff5b08f4cd9a8f0a249851c9f30b08d333aa9bb169a3c6b566c8d02e08a2b46ac4ccc472aeada8f80d9b0cd93553df9fc3c983265f3f2d93313cc2c8300567014c02cbdf7de7b57cef3dcc3ec718126cf5459dbb0622009b9746356adcd8b155411471e4b7bae7e87c53ad961bcb6e5de1a350149f209ee5df360d50e3b96569020e91b55c453b6305b22ce39e79cbb292ccfbee9dd8d3519ac14d16cc580b317e7544b96881e3798c80c19616a28e8fe98185c615aa0d7258b17cbd950caf2f6b1bfa85a33025bf8f950403a5393d3838566bd7ebab4dc28809d473be8492884bd9f6bb8ed28b86df6a694e0f3e0436c6ddc0eb8a2ddec77ad3a571c60993f5f6c69d68c5c8d23e1bdef5dade38b0d1eca36330a60b3731518ce21dffa2a311bbbde07b7dcb1b0f774afda6c440f34da21e71d8689ddec4683fe41cd69c2ea8639522dd3cd2a505b21a64d41ce1962355a4833d0a5ab2732b32b2939a9bc08bbabc351651d2488bce68ef2ceee56448015f563a2c5a905569bfac03697d2eed320a58e7db252ceb3fcfcbd1e9a88d992428f8e66028c8cbc6ac8a668d4a04a353a540b30e408e8a76f868e2c6c6f71be617b07e7c82851cb689576f650c1d67bb02769df64071918ba0b16d2deba85bb2af3c5fd5bd15a77c7f726995c51d5f04b702546564785925b53f3eba9a84ecbebfab3b42367ad790879a5ad296fa5a3963936748d3d3a55efbdf76a149cb2dc529ca7073f9e60eb7df8aa6ca701919ea8b48c38e6194360da000000b3180000030018c5912c4e34b9ec0114800620caa0c094403c168c45c37020100084418190181806000000100006822088a78838c4f5c60acd1301250a43bc1ad85ed64131715b0d999a1a5759224299a31c443d5685c06ae47e79089ea6f42f2b18d9cd7b88e3548c8048bdc68eb9e9828391c1b0599d64c0c07da1f21e3e0f1879597a857d91e7a21d9b001cb4ec41666a211b767e5817dfa2ac5aaa1240df4ed97943d92e1dffb819324854fcbaf808e2adbdda524e12f7d6913192ad0df0017a6a421e5fcfb42f6a4a876c03cf490dd50adec10eb7aabc543be9eb6443d4fa1716104c1d7302a7b3c349ea4e02c644f18300ae5b67b0afb0ba56c80d553c07bbcead28c02bc33eb7c6c4829ec6284d5c947ffe9217291e5c89040824df8937e39875f9fd798e5571556749788364c8624750026650b670e06040268c79256157523f075fedc201e3312fa14ed561cd31ee4fa550a0692c5eddb16d3add875097c5ab5c47d4d38885a9f816d33c19963e3f23b3d6d4e0952f89ee1235d15c91dfee3e1c7aa9ec6556c3450452d3d783f0523cf4e6ea389dd658c46e04ed84c8ee0b7435dd729e84e901a8736e3b240496bc3810832d5bf13f69a90fbcd7448769df23fbf56d8009801c8fb51bde25c8d867078549b24fc2847038d616a9d1b15643e377274c66c6f301002f714cb29e08ddb634ed4680d7ea2bdc2c5dd422f2f3c42557d4e125b9f7ef436df72eaed57510d1147e58c9759e448ee88fcdaf2377f7215051c8376c4dd0b09cfd53f005f37d87345078255d4bd39b742d235ae9685b6baf3f4aa0f64c65cabd122c0c83653d10709d04f390454e248718e60ad8d7195ef4ddefe7c70e0330792b967df4f358a3c27fe7cb5bb3c950a330c896eadf59c7b349acce2bede82ee72780cdfa8a35a6368aa94131f5885fe375c64ac55a1430da10f4001b3c2d1773d3b1cc0623cb4b7691ccf66fb2ae0abad2ac7886350594ab429c3296f3a6e8be17e1058e8489c0c9c27aa3df97902e68a1b7046b96e522c8c02c949f5749c2a659a5d4f03840ba4b39801ee6a6955d443350a4c92ca0a0daa6376205a865fe0f2528f213058a194df7b05d028440b36c25090bcbca6494465e30a8b82cb372f7948f93b9130795804862e3d866bdc41f86ace7b884f5baf5cc91a75eef00dc2fc51bcbd024f2ff316bf550b02b07999b31f2dd82e92f0e2759730a39160cf4832f96b99174a339610dd580fb311a199e9dd29813f182b92becf2f589ce55627c079eac5384838f969658fc9647f2ecfe5b8d2e84b1a6bbf4c1998908089b9c3362fc0992f8c17610217cb11c8dcd8b5b1d2f56c2ca621c64d92ac8488d5c938c63933b84eab32d9f008e06481052da75780a14e068330f450ea3056568a211e52297533053c2131b1d80537412ffb87d17dc9618ab2c140c0c18f8d4f56b94a2230744180b9612f24ad9d0df605ecf789f9deedbbb3b07b3123235f44015ff06f378a3ecc0797a3a0925c8839fdcf6373b9da2321621b718d19704a8f5e6fdbe019ab96179a9b51fb7d4235b6a90643b1d2140a21e58cc908d19deda4efd6b7eb22f70c2c9b4b83cc5021895969aaa04aeeb864d9592f906ecfcbe9acd9663d5acb6f8a4fb36ba88f902450299b103ba9cfc4a721b4342b8229297d9bed837ca3916d18fd1f3367459842e133030008bdd01ccb21db3dbe63911ccb35f14aeb20e10e3a98f5e77b27e44b7129e2e0ed5113587f333b01daa19e300e836537151d0e1b5e49d0a4ccb3dc98c630438f08b9365b73b8d7f487cf1d0c0f50848ff46dc931a3abe77613ba2980b77536cff04d67c62e6b17dbff09a1de9f4ebd5fbb1e5a27a81ce93a5603eea61e05a33376524ee0fc7de32b22ba8644a372a87437fe053b8d3c7e7a4fd56e3045954c52258d39e71b98ab25f22f8a50f1fba47910781e2b342a1426edb8061b57f2adacda876d6fc253630d3453302c269d417f489cb91b1e782abf29deabefbf32ebe1da9fbf90ff0cf694e75fce83d0d64d0ce0acd6905fe4f4e79f3311309e43a00c758cfccc9354201fc3a60afcb3d81c7a0210e410df4006ac7b898b60faea62a96e602def71a37aa214945e1bc5f8a326ed9c17a253d65dee3e8b1c9391407b38e81c88575fb71070a01134b2c72b94c2eb20e6cbcd9a66143c5e3fdf0a5855100bd4accabd14e0c3152abe3cf745e665ec57bb37628377311336a184d82f9b4fa7236102addd90dde097038760de283648d6332806ed65490202e24a802a718fa3d6e39cdba0fdf4a8ab26d35917fa4a59d92ba1c6e7e904d3f7b6407baddc9936b1694bcad16d7525ab9f46684fc250ec952c140d67591e459601b95229a85064ca4c1be2d96ec0641950f78df36cdd01cf0d5b08232184f1ce3632fa1b8558790992bf2037280a41f677045bc29665297cc6d7a35cc1fa929d31718279707532c518511c50bdc8bf4b78530d421acc194df3769d9429bf790cfe6a8c165569edc88d65368c0866616f8cf3cf710f947128bcd8e72a52a23438cf2baee3d02e2e3454118ef51db662550f7e7ce2b078ec012c3eda4c8a926bb04ea0cf2f3f3733cfce960cc5e2787042b19ced39f86a4cf6c939dd7db833c2a5fa7e55f7b113e34e2080a384a2802987f6794fa2104b5d7e311456f687e4c6ab7a6d7f939dc541bc48abad4158d588a6cab55a0b5f920c18a1e77e79d086599f9358b28c9a04931b9f901e976821a686889bf4999cdff5e82c5a55830165a37274f329438e101bf7392a00a4c7ff99aa4dedb8473929385f2321cb8ff4f78b4b24eba86795b406981d7203d61b3992c3a4932290105e3a658dde612aeb9abe138eb86b477c01335a542f3bb21e5357a64a37b802071805eaddcb35759b69ccf1dbb70e5feba1cfb5fbd5293f9d12a719defd1c9948d3177fcfa32c73c6d3114eccddf7ca3585c9f03ea0ec49c0aa66a6e8f1e2e504ed605338f2cb90c29feb13530da7fcf9955427ef3d98dadeec46fa40ed418023009a2fada18235eba3f9c445332144274beb9b2e8e0e5b982bafc3862304df329e56c88b219a7045ecdb762736f34a9525300dfcde69bf716a08687861d63cf48bc632b71d6e838f014165efd2209fb19dbfd183b3774c863f6e9f68d65909053e44cfdc900df5aa331181456dcf7372c720f7d6d3f83fbc5e8cc119ed7bf115a2b90b092cb22937ded5c600a716382b0144ba52b9986178d8caac830f178e1af23492f0f606307fddfd353580988a692bba72c8a51ac991329920aabc3e2e6f55c46ca78fe2c265d42a3b883a323bf458514c7da115e2f8470389426b69bbf5170d6b45e31a121023f31057cad989816d0070b5a919b7c4cdfa7456e9be50b68694b1636d1417068c828b8c77aa3b95d5895c859813ff3858bf4348dcf8afd133579623b3b4c9b6ff9b2f5da44e7908fc4e79de2308aea9477653d76603a928f1a57aea61a4fa28477c622bc91a61633a7f7274290736cd9cb3e905324fd823b286f5d13ae52aa290a1e5ee4f5d7ec26b78bb87db2f003fd087fe2a420981c81b07e4c848b1432386cf6ddb1acbd951c4310daa833633302af68f9d3af4ea3f64badf65dac4cdbb14e1bca4d6af8ca752c789a555a19d6460fb95fc11449f96d3313480c8c65d3d9425af2c1ce99f1f4a7083220518b4dce51f84b512d45c7893225000b34ba7c06c45c5b8424dceb47ecc9620d6f4cf056a32221afefc8c5a35f6f2656346b968c84fd0b138b2057a474ae7236334169b32a31460c822399b93662fa809594a00ee35ae7f484b2645c13d5d700d50a9217bc9d1806643e862d85918d3f3de599e0c9ed010b2d5e6d324f0df81622a3b83eabac6602530cbd4617af47995c10066ce6a04ec131ff5d798ba761393fdcf10c09b5186a12675332a1a04e6bdef8a715cec1b5ef585277db8609a26b8286366b7bb09a4b71945224f4235f570e4525354acd59163d9b22075f5200cfa6f563d46386d3e0d0014d0332e1a3b121219e8ba163e0fe198711d2cf74e09ece57fcc7820f9cba11ccb20469162b94705960fc4564fc9c9ff13639b331603d7e7f183b4ad48e40923f99aba84c3e622b5872eef04c40398db4e87892f22f5f0f38a38ca655297d2c0033231b06f11bec2864501071001b8068a790747b84620507d08e0248d0fc7b9c96f914120c7cd92de55d59994f36c1f7a345d8587b2228e14d0f2f82f695a6fc6edc482daa891349cc22e0a8e2479de842dbc4635ca5112238e3d74741b5eb22073f55ddd30ad2631822c6019665e15055c03ee4a75123b17dbb34ab3f3e68e23ba6d78d9978727d3a27efddf0c6794a55f5ed74b82d5e341c5071bbd4f37be2a83bb11f46b19bf492ea71b51522b8f8f222de83f33a06c1b1f9c91c2e8f15b4a7e806068a2bd436666d06d3933dd037822ce93caa6316da8641eb829ec099f78698756440eeca4515cfcf24528c84b80d22f1865ecd932237b3e2a98c45953516ddf7e2e822ac882f5a451f7541399965e31b7e52fb98467825d9c4a03f249285a3754543bc4b4ed34174d20f48b2f28064abd68a1c9aafa2b02a29c30889f763236a2fb074945cafa2c4f5502c024e2079180e7d0b460c16cca98015155daca2fd43a0de01988450312f23b4a711050b9939e7f2e815c880864bbc8c26576c01cd992b2c9d32e1b70c25aa76ae71e427de69ab02c3410072c74ff4c72a66daf499a174d4511ace44fbb2355e5129d0b26ac647739686161c239db40bd1cff98acfea42af376faea51264626a2ffbcf66c2604691a5357f09fe1f15afab9d55960a99c6786c3f1b0b7194a8cf533d27332f517e9090067f84f6bc37ec1e60354df0cd4d2c28d55380577314c2bb76302afc88329d2ec8971db79cbf291b69e16f1295e68361a7149c9410983f95381f2672e897ada5bffbebb001e6182d0d63939b3adabbeb169586f1dc49495a25f11039a803192040fd5fc03aa95df1d4677eacb9fe0c1d4b3d2d4b77249515b342d2b06b742e5405ac864127d9e1ec7b986858596112b9aa9e21ebc692f17e57be7fcb1ee3fd3a16a3f36e3e679183140efa80b168647f7bbf6f3b39c96ff6adcd4144ced58198da0d6820823a0e667a6ec4f4d963e6d187640a011c24508d24d3b0f23a752d303b4b49cc9c12fede5110f9174edca78e0cdb89a2b08877463da16762c8c432164f1f708c532b0f0a184b29b8e2b214bd71a4996c5b3294917c094dad125707d721a06266357c563621fe4abaf2462342b5012c30da1544dbd9d50daadf4b97532f2a8f0f1f40eacb9121af72c4c8cf39fcb105d22898a3ae5e45ca29f547912c3511c94fb44c5218902bbbf00e27a0d684ef8c209f8aac90a67c26c1c14d3389cb8b5bbc15a928279041b4c7f563b2554a71dcf1e805b6c76da52905c29296b164692e19b6b80d3856a4d3721f86a7d8eb703c71eee413751a638a3a0d2eaaeb6f466f6a7e8e01141a56388bf7731447a13559b31034d13242897b52a77a1e326306a837df87cec419d892f2bc6548d8ac2ca3d5b46e254a322ea8a6bc4884291a43947e4bca5df9e988f62f99d225ed4122537eadd1e1f03180819a05a99d920a02405c84e6329aa19fe206879adf91c09110e9e65d9b90350205e7062a9aeb29a69f1e63a0be5c5f1df7b9f8aac9ca881fa3592398b3d122d4797c41f98a0c6c763f0d4524778f51405e8c2c1a13b4276fb808a710c7b3cffaf103bd096b1ac73881a9b568096e13e1c1aa1c17123ac88ff30b41787785753f92630d9b30294deeebf644d3f29209991328ce81c728996d5621bd035e8740fc9543b0d9d372ddba5fe3dc3b7e5c806dd94328975db5526b95f947b24e5c2a4701bd48eef8d451943853cbb00ea3c0c9c1950480725f360685379f4943ada65b211ea0206afaf76b856287ace74251053eefdc0e286e363aaeb6579980508fd1f8272f299261f1baa452a15ad55add9e1075f4ec01c0492905423d7fa322e87e22724bd1e7c497c88e8aec277e89e38b77e47ae9698ba5a8d44eaca1633d1338ab9a864294587cea9be830bb11f89638223d7111785e000480b97724064f2fd5854b6d18d167ffa8242ccf0fb150f4b9a44175f95bf76734e2d8b81539ac177357f1ebfe72db349579d4f2aa4c4a3f2f6a1acd53bcbc156899792271b6c336929c01b2ef13a00069857bf83e293db15c4934f7bb98c07e02692b91fcc1456943a7e80796cd17bc1b4a18fc109058f04112a80e0df6040fa024cc626c90f43f67f75b90a21f278e2be846d3ff3176288ae8a12f1556ca110c6a822f6be86193ec53732cdfafeeef2408c2d7989617a3a08827ef96baf75b303872b26a78feee79ee70230dc24f976c481aea0d6a700b33a05225353b9aaa1a35bb0eb4ad4acbd54494d966c15b9cd3526dfae0ba5b097936e82923db9168af403a587cd91f51d2b68798b76fec618f70ce99dc0220f4b1f70642d27fa43da5a071cf0e3997140a9b88a6861579b2d716e328f98a00dc379a405b33d0881b29ed48c280ca01d3e072276a6ad298c69e602f19468965b92ca7d4368eb4eeb18e1f6763f7c254d630ac74ac6cec7b66a647110a4cf97f447c9f312dfbc8d71d3c8c4532cc188e9dfe88b01f28aac70ecacf02a53dab352a585d48c906902283d6435b83abb341cb5ade3810111aab9ca0ba89dc910f8715ebdf0aae8bbf696e57931077bc5d96dc283031a688a3a26716c7bf3a52fa06c603d022231c614f42199e17c464ffccbcbdb5d944d997b4ee6c62ad10bb9008dc2c5060eac57782d2619138a926e6c9671b7c013be227ea331e4925130a144f856b03cd6d40658f19bffc3395ca9c2dd688d0458b908a733cc609c9601a0927863e7f10a6c07dae11a828fb52d29b809ce67838ee5f50ac0f89c1f1e9bc19ffc30035fbe7747aa05f4cbf06b32c8434d225b4c33acf45633285ce388e0229cbbb7cad2cc03333434cf315d9bfa2d3bb5c8d99532f895e6e591c187117a5c4a950e3922563919fad8843a5a000f6b89e70a57c1f15c6ba78b0469c2076e685826847bc5015f40a0877392c9272115de16fb2fd89be8b88f0b5899ff8b4240ab6d73b9cd0e2fe810e680d533ac7541bf8d4f2c283c9663dbb5c2c74754c07f9f30d774ad10abd7e34f8045956aba14fdbc85a67a8a058a28a4a017185fcb97c6ce0f26dbfbb889405c925d59d4fcfc55104a65bb24fcf8cdef4cb75932387259c852de1a29efdb0f8646c450b017b35e66709cfe2219a73fcb9f54daff665ea720397ac182b577f33add929d75de41281c56547bd427449a09999e7c6376f5dd2276639fb4cc41b3a23ad521c16727477748604d06e56c08d4a9369f9a3941578807f5bfb17e80a054137db124a8e98e31ef9b18f1f2ab1921cb3eeb650aaaaa64b639e2e9c555f52eb237b8a335394c13efcdda6150bb5a26cbc74dca01197524d5a2d461432ca898451ac8d9a675c5dc00bd82d951e8a4a64749769eb971dcb0e9e7f1c6a8b04416878ffd73a3ee7f50a4f1b46639eb32930538c9e88625125aa15447c3c8b9a6c838e11c0dc8870db8a11ae1f7c64436f0ee1dbd35a5b0fc8866920dda713721034c77b075e41ddc2319bc1db025084ca638ef06f3f692657e9498bfc21c29ec5e77f7760631b99c7a4e4ed8ef97f3cefa5565ef499ed93100110dff7bc9a9eb9f359ce255c62e9d1f48015d38db08cb4cac532897d51453c97e66e1ded88ec0c2e7c8573d2086d0989daac7ec08adcf505719128bb42f0e89715b08f86be0d4e143a7a4fea83207ff9c69f57b2cbc4c77814ca0c18bddf34fc68261caab714103868355d69aeeb561263575ef73685d443760860a4c4c43559f98993e9d388c96ac914e055b09dcdd2cd110fa4b29b2cf2179d831793e37b22ba1c9770e672b9338a14182d2c7309f630655653eb2e7d226783b4665b913d3542659268ced1c4db68928cd1d3b3c11094c23cae00053f7ea8f99938ee96c181640d3ad6827c652b244893127ddaca96e4fbe1dea68a24198db75aed33f5d34b49575bbb289b980f5deaa0941ce8dd3bc30b6cec0968653cf28d5eb61524c857e6b936757cf4128d40186565bb9bfe3c4d39f1ba0f6077325c3642013b7c10314c88524857fb3e1f8df306a83a9514b72592ac58f5494586826cdc652adaa17ad29a5e8405d84fc1e9ec3d5cd3b2e9329d885216190a8c59f7f8be43347ec50f9af8e1c9476ee2e8a471b7abe8b1a8e923110fd7da67ad3083e622e5a776e098ea04c7b9fdb2a066203e691785c59acda15fd30bf9d4b9b13c634b1e1f09139e4796268e56547a2af654a0c6b3b4f94494757ed72003f813a158a4af59b858630ac13f9731744781bc7019e9f139de9e684a3b6a8c75f7d804248812b9c15371f92b2c1151fb8c03363c2070eb5cf99fd033498a9ef22ff349460f62833bf967cba64432cccfc09192423c379329a1c0c56c6768f828b9cc6db10570fc580f41e77aec6a05061f257cf1fab7987933eb841382b4848efa2b5ad18e63da6099ec4f3a87838dffdf1141627e054414d5ed80d1d0a7c7fd449b8bd1b1485c74c292222c9ae122deb5db958574517cc0471c45d9ded8d383531271ffa66ee679d2b9aa002aace2cd0dcad2152521cd971fbeba9e5589ea6cb4d5e82441f20e2d3e66ced2540504d39101464e4900f475af90a6f821e746cf7660c78464a408b507bcee0640e324529d02a8866a55d0161328ba81ada389ff5e41b244e974e4883b1eaf2b53b1c905d3c8c476280769acac36a72a4178eb9f8d9fcbebac6e1d1933190e821029cb20c3e14a0479a8b5cdc92f3bbed29cc7567b7342ab76e9a40f5d1d1884563d538b678350491357cd617ae16fc45b09d6b038472fc4e6acc0020405825a9133af04d07632a9402ad7e80716d96a8865da909157c07f6d00a67ca6c9f7af151644e43666b2419b1cbafd5ea6e516747da59bc0d6274326b1691d921779c6266ec89d2198e3b498ce9fb58bb6eb1335f6cb58ccca628675ee2ad6592a7fb4b0c63dac22fd53080eca5175a528ed7fe268072efd9f323e2f06e52088787bf18b3d735aeebb03dd29c400bd57be604b4dc071e14e81c8806b1a75069019791a56951be189d3a7411ea5699c32ae4312607dcccb189ba71bfb35424f1bab6364c4bb543537a80290412766e22a03dbbaa43e29800c0c26ccf458f307811747df8d2903bb8b8c6c2bd293ace08661ce3d6a36d669015cc1456ad95ac930fdf20c65011f2b73a51aa3501094a625d528f7b1ae0c5f0944a1c9e847797e3319563cdfc20c9e853d04616580a1e318142e955d59313b4bd149d8fceb85d846c956952d3d7a9d8a64fc0704297c7c01cc506a0c59fff4133247858f9f2cc20c338f1df1112f916b8e2da12c8069a38837ef561d627c3b239f7c71721af5d8acde8f4cc794e10ad332ac63046a689a2c035d76dfb8cea5d48d1a1b2942972941e8db279d1a73b3d422e9ec7cd451b38d1bed4206292ef3ac8bc520651d14a4debbccf992c5ec0c3eb90b822edf640c46a9d686a43c0cb811a6d94b97e156402dd0e550672cc0a8e57039481cfa32849121138f6a90f0d1d8881e2e37de87b6062307a908579f41afaa4f2a42123ab133f472860455a08c502dfc9599df6669cc115752778374d4e63ff53fe7ac4ba549cf78978e9abbbb6107a0b3eb2898156848ec554a7b5c17428f36c90c4bda149c2e0603c3f9e8a1a03e1077632d1dad6a771adc1aad8a492796e02163da460e8cba51af575b01a31ea198132337521bc918320a8d8666f4915ea633cc0fc79dc5b1996ad59c76e270fc269f848a85e9713818f452c7caf385ee67fad17fe48dd4e0e25997b9812b5c3e3f7f6c3141d4a572f37847a345dd86bd367ca6d7254e8b6e66295f03db85481b2e1ebe9e5d48cfa4166b5a32bce2780901396fe43898e75213ec441940e089c8d28e44cb4ce103cc3d86b2d12c19dff85d64c3e8e957a0d6dd3c2942806362569bdaa77ebaf31c92a478af33cdc5e656db284a37d3c5e68f19107ea34ae72f47dff3ce698ba538599fb8852488e792678a273c83c18b921b2be294c70e527430b1019fe14a3eb1676ae83b05fc738687122d614f79351ba3380f5c29654710bd664030b6cacd13393d1572c0407e8c3c42a0a7a2ae272f0cc820b00fcb5609ef185b194cd22695d2953c0bf12dd8ce18fa469e906204660c4912166e666b6e22acc0bd0dabf14e670ca6ebeca481cd86a749de45645744e19dcdcec5be96655b9a42c39de84dba9036fc1c174751a98e68a7bcc92f1a7439df71e2e045e4103f3a2256b7753045f8c991253365989cf4984e6954d62c9174ce0ad444965321b66c654135440c1b2f0e3d807f003b2282cab63a9190e3c8f53f792e6043ac9dc5c1fec3915495473e3ccf9a356276622433e2c5f3ad79d22309acee05adec447d28c07ae2d5c49f71a7baf657535941b8780de3c1a42fb677c8168a699b1a66a8ba5fab99392e8a0fefddcc07fbd32df105bd897c3c58011d7bfed2a19266a79b7fbc64f7121092949a208d5af14699a7ec2dbc8aaefbeda2cdeee1ad220f0ecb41d7bd0571d6ce3de2cd0ede63a00071106dda976babd76878b6755eef5f7a1084f4ef3c61d1821d44b4bda9ea71a8e7b45e088eb3f6867ec3803bddb6813fa3d8ed177a9fcda807374468e117f0bd58621e8e6afc4595343fb28fbe67f59f22ff07c5906a2f16eb756beb57abaddc8a0f34f0437f63d6555af147720e25a6048c1282996086ee6d0ba73fa651634aa221509095152b2b6b85738f6ff4e73b10744740673e36a718c98a2271eea2411384e8d1f6f05523395bde5fb48f712cadbd2f6870bc73aa2278ea089e8b6c28a60f80a0fd61dc16dbe642b1efa466e7c716c17b583fc9191ce39f29a4c9a6c033860327fa6aafc3b2927be29bb62aea001e936edc2ab935c78ccca26e01fd899f637322b8a28541c9fcb0d4cadaaaa505eb45b51175f7c022041a5688424f61835d76473223c2e4f68063b503394edc2f1582d64a386544b7dee917c2bb2fce4b2bdf5f35c39cc8551243920d4ee8dec12332403bb7fee1cefc3054da9d6b74c0c1fdbcdd2f0c0532eb380c7157d1f976587eb94cf6d8f573d6fab78bd85ab0fe68139e957267ab4c0c856cc0f163624c4db462c2c8566eccc707f4cbb5082ab80a2f99f0a5c6db1ae564bd754f3b09aa24519e4426e2e13c97d0abb20a56f13afb1b00f1fb0992c687490952cf41898a0a153d9423bc09181a1cfd8bf08da32b843cc8b71c7ff8641de52b56d6ac637532f101ee7aa2794bd605b0f6a798c9b31d6ad57336ba184364799ab5176485599ae91040bd64ca4a4df37bf51771bfe86e4a201fc5f5f34a957011d5baf8a3ecf1a25bfa06dcd54337a5ee127d23176f8feed3a6f961908640996d5ec775b31e30ef4f2f453b81a0483375a825391777212584982e0338d02127b8d4f3e32e3d2b6ddc5bb915f1be2873a44a61acb928c95f8c6c13c953fd6167e61003ffb88e1864805599445550a55b61709b5c831dfcbe2bc03730a3a86c1925c407a91ab32f0b6a8212e0bdfbdef058309781195764807dd01b00a5787fe040c03019a36f991f2bc545282296ba40830e77706d89f9a3e3b80076e8e3e12ea6936a6a58741c79618b152f3d38563773f30fe6a0246b50dbdd5e5b0ed86cf979a289e08181c762aa5387043e3b107ccbbd7fd4f62058bddc5f7f86c40d553b9f1fef5c2d3fc84d44ad1df515fb44912268ce7a515c6c774fbf1994d64c2a55754c5990768f146010a052d1107130da23aeb0121bd6eae61ff8f3a5fc299bd6fa188a00ede4570455926b44f08ae260cfffd9715acf9b67286328acec9319e39e72ed0be56c3c83f6e5570748b8bdf141c708025d0e64c03df5c97f30cf29a4cc0e2ab4a261cc6113570c52d584875069d5b1762f76b4752e073dd79258bf427c921181f2e2040197e26fff16eee1f0520177c83fa9ebb4ab23eed22e02266b868ef4585f420acc9b35dfb7765ad00a04fc6a91e335070925f8ced094a62b11bd511c32f93e6d3be7401541db28271275a8a7ad4fc65881375b7af5412e959350630c867ece26f35aa7830a04a855a28107d3be9fc9c84f0c4635b38e927cb0da86c79e4e81792300b20780bf9910b0e13f008f20663b428b852062c5cbd658b4d9d5c47be4cbf523b16698937242fb01bba8dac77d951c9c1f899b9fcb3d57f81b27ddf9fe0f35a4cbfa6caa8cecdc913afa94c5d66cad0a6b04ccdebcc54f31d65ba8811f5189cfe7c5e3606e65993edb03deb3209d3608420ddb9e9914a32326e8a161b141d6088f1c96172a6a746f1ef3f7dc88b1093577ef7341c637287c23bde3a2413da10260973128d3391322c3771ea160abb7d551e3636c5657d8b210afd7dd30855bcc45f4f7b362b688c3a36ee7bc6ed23ce6a2e190ec11ab43ee3e2957d6d1a9e4a80fd616a8a43bea3c81076c809aec46b64fe919681cdd304ae9beddd8968ebdc0d181ea5f437d8e002979d31d446afa3bfcaf5cf9b1e9e86b150018e0b2d92dccb82c59566aa762c81cafb3a5b6ad4129043d37034432daa7880ab35f212ae528de91a9738bf504253c30eeed30ed8a4d1117c1117411c2ed19004f47ac5b0eba24092ffa2d6b0d1600cb12c3e4a42ec22c2403d2871f03968edbf293047de25ef7c8e17fc81649ff1dd3524b668430835723cbd0248f743001faac9c2756608e69758b4736519a09c810e612dddd4be8ee0ccfdfa84404dcd562bf8be6a4b144225358969921f917dcc13b3ef2494411c58c929fce2435f0dcc438a48e3aa9916419a695ad5492fd8ec8277adbbda54c5beebd03640264026602d6fff87f9e1a1ac1c1f5b97072b416fde6ff1c869e1fbe266e9489400d362b6c441ec5a3e1a1f7279e75d82bf01a8caf38aed59b549fefde6e065435322f218d187305189c9baaaa91978aa2146b046c31df5b466f5056bf8c6062a6a25a4733ba98a8ac707206109add94ad5a6b176fad65b740a8ba41442595b9a913cbfed3b978d4c06eae3639c51c32a518511950881a114520edfc3c16c4d5b1b6528b9765433b9977ddf098cec9afbee0fa4a6d5763b588741bbc2979e198e3d995f53ec36f58f07d59b896eea8d3ddc2f91cb3f4f8ef83899b37d9942b69cc22080b6377a526eee80b4c017bf6111420e12ec2ccc4688ea5f600755dc649fe8fb03048304e2f1bcbbbf71090eee3cbf6d80cf34161958a9b9a51d9b09470a712ee42862bed85f444ce0eab7615d76cb04899b560012563a9af3848609c73ce53d082f03bbf4a59f077ba0decc02ae386569699892ce1911626473e80614e8d3d63c5b5fdfcd7b15935b29435be4a383f03d65dc559e47c4660896b8373abc001c75a16c1be5df68849d4f33fe6c0993f38bef6aab891f2bfdc32395f569601e15d7b1f9980e9825ac2dd111f4a1899b9319c4adac61a39dd56faffffff3958e766f9b6f2fd92c6285f54baeae706c2f2a26363738aef00d345898c2ad7666aadb03d29fe7268eff69e43e2b45f45b8c979ae838998f33d2121fce3f055aad2b53798ad4584e5a2228361fa8111d6301a72368df0f9d182922d45887081ada3ed6a07fd814662c69b0a135b1a1c4d8d418552e1d0a4bbca362a787fb5fd771213148eb943202a50e43e127b9c060693af238faefae03355cc9f26b5a1bb93b0a8f8755188fbe40b4162346a8c5ff5b2c0262b1bd165ede912e427469319b199f7146ed6654d7f311ad12c03f1152422707ef8974937b2cf074ac394fbafcb3fd0ffff4f24ba246cf1884cd62ac466ff20ab08516103ae2a41226802746ca87bb4b552af751e391a594bb84f37ec44c29844f285e5b7a2c8047139ac6c367490332a6d4c1c4a6a2c6d70396a253cb9a56c8a11c8b93cb5367de9f684cf0923fdb23fdeaeb9daa50801a72051d2d95db3c6c37a1fd919c5c8804744e9658166292ac84ffc0e9b34b914a135b73b8ad8937f9c2684f2900fc33ee21e0d42c89ccd3c00f2e53f3af2b63f0c494dad5317e64e829a619bc5ee3d971c7b9140873f46ea8a9176c4486731125b8c742d93792eb96a78e92c5b84253c89ac020596ae643157cd1ece1da577cfeb4495aa0ad921c79688ec828b1b85d46d0eec3d8b7ebeb98c9c0b89f312a2d7b81da2998d9009646365543338a9142ceff24b1ab2c7e81ecdebe9b0f2151d9cd33286b9b0e012cb2ccef17a5dee52065c870ac79abd5ccd3f79f4564cf72dbea3d9ef9608ea39e0910f98731c56ce872669410292b80068a15ab8e0fe29752e1a8661a59392863f5c4df14c95b2de44a070832b0ac6c285db917983f92543ad8aefb2aee13db4f6de7b4892eebdf7de59f8855798c976af58d5bd9c0bdda3d1754263c7d3543b84fd64471d9fb83983ffff67451d5c25c599ff417a493f9f92abd2435506c9c0409d1b7b80215dce6401c5443c17ce759ab91d6949992dc1c0fca0432f72b0049d26af1238c0def1219801069e12399fa13113309e4180ec8a0df5ffbfc9a90aa6ab9eacb9155062392128516455b4caf993821709b833bb26623f0b3d566e842dca228e8e55978d8f7327aa6585f5b3b6ab2821826f8b02ad3bd73d395185102b3a833182551a587539ecf2f1e6d8b0d97ef38782d0f4ad1549660f549a508deac509a67639e209cb49b19640fd43396dbb66e0c3bdc743e1495a33c544adf676a899c0767c96aed63804b188b692493e506abcc8b9eeff7fc719ef3ce9ff5cd7e16185d6a495b1188b9cba9061c5e1e6c163f2b4c8a00d6275bddfb8f1e69c73ce8965b41befbdf7941fe23fda76b17befb40cb34938ceb1b78eeed1bcdef4e79e5ca5ed3e79ee0a483a429943c3aace4ad575295365a3e362b4a9ad0a19928392990f2b43d8737736e7e60ec7ef15dc242cfcffb95f3ca338591f801195a15a342049ca94ca5441913224a15919a65bd688ccae94473fefbac286d65581216d7393b0223e9ef4ffff28cbffb7a2cebad74936c61cde8a6832823848d293a4e5050c0cb6ea8e2ca824dec4138184d65751784323b6d3dc15ea930f5386463a8438a1ace8b596e1657242afa446a407c844a729a23a234787c964a3eddcebe34c782a8d99d5a6e6d7dafbff9fc999f131f6fe3f8bf35e219959a456c26f7a6f8f8637cecd3b1a4e54d457d6c4184c037b412b1194516312ce2d680f9cacb6b0802f2f3cf6d4b824626476d8679b45f1ddb929cf9a63cdaeae47579f7d95b52a54a011c64061ac827b618c2be19623cd89d66cb31db99e77bb8224caf2fbe4d1dc95d914a85076c1240aeaa0f4f61669f10e6aad9b8485872ba0b48c561db7ea173c0683c0c5a387da55c62cdb65300acf71f8cbd9b99f72f2763b3c75fb0fe408cc4177f26d9d377b68c05bcde1f9b264f08e051f1a4e3898ae7c30a11c3851c4053132bb010d3fefbd771bc04dc2f229cdffffaf6c9c9602774ab4944a83130dfab8570b42a94e3231e0ba880a610605086e2a2411bb671cd3c4fffff1508226e305712c88241185ac251f2592e0a8925269255ceaed474bb485a71b489af737033937c250045a1a7ef2d20224ee4ec8de737b644786217c3f86a9ffff44322e095b930382c887fb74bcf7de7bec8103af5c79cb70206bf58ec760414001774f81b79c324354e69aba4dd3b5a980ce92df3f38e75c854dca39b7aa5930d1c343299873626dc645c4958c19f2c8450cad09b2e37e9b8485bf858409d42ce15e700a4f72a7c0630489b1a3b8a7b50f5e94a2714f6934621b8ee8f2e8d995f76fefef3166b0f078b4398a8fa13d7112e1035048995000b19cd5f842e1f6a3c4d15a350c980b3bc1e1faa4825a2fb0f00b8f355be31b0fc37eff3ddefca4dfbffc28229c72940989c294a45bfcbca5fb286948ff8fd9e2eb74284bcf377afced46849734f0ffffffffe70dfca1f727ee7d6e7974c7815be4925d69091665bac779cfcb1150c0a28757adf454026110b502e72588aa6953435d3cecb7161e926c4855cdd48847c526a29d2c61f045c676dbe9d726fdf4b53bfcffff578ce3ff5fbeed1117b5051c32251224e88458c2289f66b8f8d89163184108869c472f354a45310f63ca9eeddc086199884273da56f939fd4afed0d48a5793137a2568701b1a97d1100a660787c9ee6134f3bdf70e1b2f14e7ff7fa10e8e41a356f2efa39f67809ada0d1469ccf88aa40d263420ffe3ff39c63d1edf2937ab1fcca52b341bf18ca52b2c6271096cb7050077a1d25c4feb562728809e9e028cbe8250b4018d9da864b0977c30005900d3180804150461280e3441b8071400040eb470d0803c342c3c2c280a06420130001808080081300000068381e150380c24088c0979d90015d8dd487812943343c8407f4f9d81c48cd7ee5b57095dbc46099ddf635d62bea10157584ac7c03a9578b059982c0fe34f1d98d62f344a2645624cb893382c017a6488ec84600a4eddba5d20fde291cd459b5c2e297e4eb88bdb09342e20b0a23da3e2a9ebc102d7db33755e8bddd4ce247b78e54967b180dc09344927165d49cacd4cf450b0c0c72a96ac84a8682821756d7651d9fdffd52ceb758d424c93234da2a703cc1b10b0059a2377651ffbb7d620fa63fdd08c3892447d03e46efc81c109aab6f4eb67dc337632a061a155cd2aac6960c2bc6d312e0ad22347020366e3fe220bda5bef53c41fa10f3dfb046577e0a6dac18d73c80f783abef2c911a7971e890d2d35383b4bc5fe91aadd1e26d1b1b4b68dc3866398c3f95623857582afc7d12792b89569b269629c7438a5b6e993661363d0f49694e7d6f193d9bc23e5565f359480daf9c428a55110b7e554466b1de0f5f9afd4a96e06bd8fccbf2b8c0b772a8f0ac5df49ecc115132c4fb2f92fc0612b214df03e6a6f1c614545a2a5ad287b9dbdea6b791711799c80e017c0ea91e6448071321426c1dcb1ebc0aebc04462cb952dfdad96b29733a4aeecdb80e3c3c5148c8e7ecb49294b2b424e4aff73a22aab48645025c315d0706e2faa0fc7c3a3810865171895193b440196874ac76b92535c96b156b0245c82de60012d7af63f91ec294bbad6b9131fb21f6531f2a185826e91bc626bae941a6dc5a4ef0b3cdca5f0e78ead1dc2206b27f5f22065f1543bc589ef8eda47111a9d43600a859de67e79a1e6fbaacf99ce77daa8dd35f896ce2dbae4c36088d3ca45aa997005e187b7f493193ff97589d6ab5fad208bddafa194600a8676d48800ea8ab7818e11e88d41215be8f713b34dc7c237e3d814f58bb8a1961758a22405d50e085c8e3ffe0ee7ca424c7deeff38e429c4e82f9c2ac85043dbd2e3ead3b918388ba15087463ae2bef1cd9008aa4294911c02fa5167d21b07d5a829cca143583bc78160f39ff873a51cdf44bc7f7a28e55a98c839f65c64a8b28876f161b135b760f06fdd7088a16f6d95e0b64f978386bb0161430368d4f0c38053dcd32d01430e8bce4b9011362459ee9b63404a118ba98ee57cd11b51d894f18fc4cac5d9d7cae6e1f5e44842609f8cf845294578da628d4da8a3c50085796541241327fd4fc05224522013d72cebcfe548104808d759805d2d3cb7e16a4437612a12569b9a1412aa9ac259e0f48c120530bdb4e91f2421d8d545c7da769e192fce1764bc8a530eeb4efc5aac945d2a08fc9d630503a4898aa19749223e1144dbcb8e900159a18d0f1bc6f47cedede121b6bd6a245fd3cac0fd5df45a6d937464682f7d104fba8353285e6c90c9b5815295874a4f1915846ad374a9bbfe6979f65b60ae16a767bc9c07604a8bca2096d2cde252d1e0cd8510f545e7b70987419cf0000c2c45cfb0ad4c19a15c060f7df6527ff0f03004f8806ece9db6c10759c988de25609168f00166805241fb4053b07f9df2e046163a2c6128fdb3813826a978a2e1047749e0771fb96ef2f80c98becf6a28b31f228840ce1ab3e7d1f4b2ad5821ce5e4202a18c6a12a966bc15866c048c14a65f758babc8c518dcb7a3df4b9b09b6e2054df4ca8342e5a95e1cc5ebe2569db3425b32a45d58a78988169ff1a5b22914f2c1d128b8f7537ee54f2b86114c42c35ff11e297386d9645f00991e4a109064e0cd61e98d8f6f1898fea38c95e427d4e34b9a2e83d82fee3f5e837582325c3de26fe238b44b0da14e00c9843144ca275167ccc85d088c52061ccb21b5c595a6510708e5868d652a22f59d5d81e766443fd94e0d0e40e8c943027ccaefd45b4d2e581147eb34c8b1848aa54d84a6afd888bb2d49361ed1dc219ac7f9a596286d57bc1bb4feb6b519a1fc60359db3d67fb61117ecceb1cb5b88f32f7bff125e7312db0a5d1f94a07818482d14dd2ca0976c0fd79392a6eb9538fccf4601ade8d3a991d4a8e144d13f098528d49fc4b33fa2ca300d30e52f33e031f19191c671928e30eef18e4b8c03060f2320151b7c961ba11ac71a552226c99a4a65e259b5352a5bd714caf34254a746e3f584bba1bb3c560ecd737b1ec45821c32db9d480ec144b3d9c388927952d1f4f57e2ee3ccff9b5534bda15ae89a73200b6b6e1f8b77d1d30d99087d43b551caa120fa3f2ef593c7808cf17d3276322c047ccb488c5a4482e72d6d8202c8f8c450e00227e2e074568b5dec82a3040f41dfafb9328355ad1dbaf018eb5082f0282541b58c4f8bb36ba56e8403d8239c688d5c1362f8cdaf81529fb115d1f9ed88dcb1241c86a61e85be2c83b5cdc3a6692a57ebdd42b72d23e65c566ad6858d01d958425f57dfc493460bfc4600e4c73ec2b9a5a3900e27a504e739c2ae5b15070111b8c0d9453e1b5cc7e3f3a8b64374b9d328c48829edb7739aab753b1b13d51874afa8b8f29c421aa78e5c9109e45d7265b451edabccc3702cb70a0c254be2790aa2917318224e07c69842975650478fe063cc31eaaa32ca9441a0cf731ef9838d85e95a638c7fa23584198266530bd763551424a8333d1ab7eabe63752dec37f755e181ee6bf9df11c9939b772bfda8ca4217788a72f647b11c840196e4eb49649c7d1b28307c105ebc301688c8a45ea10d31925cb1a0df0ebc4237f0a023206701205911f9dac99cb5519b8c2caa03aee476e202fec5fcb60c641b79c98b45c493d396ee8be2827de002aaec90d467fd09632ea26867f1ec8a7c9906984b24921e65a93355005e4c632f98a648fc86833999e2c863e580449f32dad5a86cac9c0a000e40a90ea6abb6868183a703739c78f95c2cf30a68c8f9711415f22e66af33d0b276e53f5c159ba16e57c170a232c1e0229cd0bf4b9471ff886db544c3285c5b83479cac358f62d99114d59e91c883920c554c371d142c55ae8c3129a98d65924e07af402e08c19276af0f69012403df5a1414c2cd7501775e4b0689890b6512a598418b9b50798cf2842d5c1e316e586590a105f90219ab1efa885caa8a14bb2a54c4f66445c95016d266565a01c9547a2409f05dc4b206b0b643e58c930bd2fc211c0ea4893c0f1a87b9e88d0fafe5c8a169100298ceb921043aabf1d659f60a472813860cdeef22bf1db703f6f238980e0364014cf6dfe1366eaef2b127232b0a4a3ba504f9feeedd9392225a2026af6872cbd44a2b05dbcdc6cf099c8b2ed9417d9a88e00ae045ea0ac99aa256081beb00443712da8361eaf585049d53770fc8c435b797d6756035eb7be3eda4150c6568146ee935517a476ecb726225070d258b155d624d5b371f335dc6a414bb5510a5dba7e140da046a00b82b34209b523fa578a7a48d8a03936ac8261a97ddfec38e445800f03d0e576f0d3c28ef40cb060e6532b7cd20c4b26a0e55fe92231d86cfce008695ec35bbef70630a15da8d04326d8524e8a63ccf2039324975139dd7e2010837216e46917163e167a90025874e468351f148e805aa7bc0ea2fa1735e908d1c838467e233529c9a02080ce53b8a991bf477f253074434a32d0bb08eddca985146a720e1c07f823cc28486aa81863d6850dc6b4f4299f90d17b3183f519432139e4eda6482517b8d0b279d3c9d5414dae2515db261c9813ad61d37f1e8286cf4161b66f6d4d12c7be94dcc92ffd413c6a1ae9a59b63f50d5b94a400591aac2c3c5e74fc807fe68bed7d5c17ee2b25f8b03519c6137aaa902e575b47ac3c6a8c3e42a8d3788d7a657e1e974d53da2ccbc0ac0c05e4dac02f29c98486055d0c4206412937e864e84c66398ecafba65fe948d89eec025f5d3e184d73305272ca0c36e7c3edc4d96d907335f103f49258ef6df8fef595d55cfb9501a24b02785bee00b1661cede505d5cef7da47d0987c087fbc450f1387f3288b0a9d8d409807f651b2e2223060348064f78da0c37fb38e19ecfd41ef1987b73fda1c1c5f4c231191dd8de4811c6fec8d1b317e7db58484a59542d0c5528d7d10b57d7dda7195310e9700683dafc771080fb010f77383809f36d8f700f4a00d7cbf51427af9cc28d0f74ac0ae0b7a372cdd7256aa764cbbf3172f8a975049e20624cfefe313f375ba5d6d6abc72562c19366c3b34a7049d25716ab50536edbee08e26acd489e14e39df9558252951d98874b334d088b869bc0cafbdc48313045eb5bb8da94cd2e49b04c3e5994a0423673384b0c2857ff45dc0da981729c32d871083b12cf16817d828dafacc6f0560baa97bda1d4fcfb0d1a7c01a93cd8e2512a0b13e56c266a7ab0b87d8d600f07a81874c8f2f49c9118a6ad0843cc62124ccd9e4634f2b91a209c18cec846768c615457080218323ae3bb20b8ad09d6c4082d4f75729aab4b279b26458720236c68245c3113eba23253166789097f94358924a3575056e086fa9067955047bed83ced5162dbab84c6b790a133d18879e30d24c0924a588b520c28daa030ee0ca5aabddd26638f961eb3efa229f6f4df03903f00662e980c20da39092e9f60c0c23453cd0d282e5d52c5f91dba2dfe6867e14a1573f1415c2e7e37ca020fe4333bdf2052d2ac9a5980e1a3447e64e1960517a442ed0b59711bb11bf286f0f0ab2c785e3253054e0d896047851711cb95d54c727452248af4953214c1c74c44dc573022ec226df6964e274e6e0e05d9db9487e18c8e424f89914a2b1efbd4710287204224b6147cc96584a07c3c2e42a46b9a9aa535c87175168c81c4613fdb633059c7e277cccc2b7a32a209a1e7b516b1d490847413d5450bf0cca91fbb6efa2e5f872a36d506757538501cb60333da2964d03ff6315d0f01ac0f529d42f7af4e826377ccd8fcdba182639267c4b48be50319a6d0589bd393582e055b166f073a396eedb725019ae5309b8690b407b059fada9116c974932bfbb8d24420e76acc26548a9419f42b076556cc70535f72acc809178c587250bca7d3e41e5013ca7aafdc7f39569c00b5d23a503efc767b9e7955821f76009d2ac56948d4a11a86602f447454099d3581eb969c833b2921ab5f3347b8607844888eb64d7e30e361d2fc0b838a5c894ae856be6847fd32d3e9c01e2f189b9f8580786200638bcf1d344ba25b55f2607f38807199f5c28cfe452bc888c6d5cc34ca19db0e030b9c0b767fbb89516962ca204813bda12109d9ad05bdebe76b3d431040fe8c71fcdd53b73bbf05a0766a1f28f5c67f98005532ccff3b27112ef4a6af55df76e09fe42cd4459e8690fcf34839d324773a4a4c17e9e92f113675db81b371567829c8f316a8c96c6e1ee616e4a576cc623430eba010b80e5e23e08a4461a53843619bb8add4264b7f34e6ad8630f3eec44b20af4d2a45392da96c43d46c278b8d595764f100b8b84e303be8a653a3f18d28e780a2fff5f4b0f85d6981b81e28c1ec38c017c0000f9293131b505b9883ae5cec59794a85e0d15bb971954b78c7a810351f8d3e24410617ef837aa284678141f9f6912d9c3c6f40e645cf36d595e5358eba1760dcebebcc57a220beee8d643c3df049f47617e7ca224a290adc4dab51f53a86d2b70613d071c72d0e4d735c2524fc286551d2b9ce98cfcba69162c6357472f87b5314ed97f03312866078da80b58b1c9403eec8f26a941db90c5b8301637945d7afcf7e3c0fcbcf380b39a37ea7730952b49101dd1b6feb83f15d4f93a85a1393b7860c258bdb31f9933880a77c460e564d055a6a6f10bd6f79c9aa2c003398c976709b3f101636625a456c7e8155145144c1b4323ca36299cd60d03f176f3aade833067ec3d924d36f1346329de0c55a914d500ed7d81ca74299105c8f1ae32647f0438a70586a94cf0882a5780ffb8f650cc9ade2fe6fafa832a118d792e087818df877a1e3dae84d39c749d4fe07ca0d8081c6e842c3fa5cb77c2331f8ee7335db3c07bcb6b08cc0fbbfb04eb39102c4d7cf20c701e0dd95244e29e15c6e2122bc41d49de3aedd82b599c9d9a189da12d4e7e4e2242ae51a16809ad9b6588caf4d907beb8a5a5580b25714c9dee3433b01c1864e6f88353af006a8593c89fc840244068deb421335484ba6ed22960f6f73d593fc6b2bb2a9c315b0a9e494d55b3f66a376bef3810eebc42c260fa09e3ad311909c209e2493d1c9753043bb7e7482b6c4c5fae9b09db590a620464a591a943afeb1472af24777e6eb0d30e3f03a6a08d0d4da4c5d5ff823871242bd2ab2008e4c36ee352f0f7a10b03da72a684bf48f69b52d01dc1ea9be8a83e828c67e96b0229cbd82459de695fec37fa34e59fc1e646bf7fda52d5972419ea803d402cd84c2cffe3a2405000ab211b4eeecca9c6c44cec030045511890ebffbf2de70f205c83f04638f8fb0aa0ff3adb72f74c28e02630d143181c57bf1873971747041f79c7a8209a04438ca41fa7406fccc0c2dd93010197396c27782c41d4a335c4e10748bdcdda106f62a8b5344b512188ae86b056ed38bb7c894c8ca5a860166767ef4219026c3221090ff5b068d084d5cba993764179e2a4c0c327faae89ac9a757b8e858736a3406bb142b132f94471c2e027279d242c7b419ad7764545ce0a611231944679fdf0e563997b264916b2a7b01fe97107bfb6b04192681a5b6197c0cc8253140ec3438672162e9070130d4857dc8a24013d77c2e1ac5ce560edec630ea699c3115bc2470495dde3d0d3fc42b405cf71091e5f1ee48f37a9fd9a8e413f227df7da4ca0de8821e8db89909ee78af7c1215bb3d4641a0f8a69feaa100305bc992ea878d706752276a14986defdfcd93a084944447b0f8c252aec1243bbc9ee6c1d090813d4c394c85899a7a0a80d3727ae47928b2ecaea3ad88df7365a62b6987aaac263431ee6e0a1f9abb771f13683cf29e26a50d8826cb17803c104e3a7cdf63d204032109666f6252ab5d4f6750839a6e37b7d37035cd35adc24a19cf958c20962c50d6734067fb374d964c0e8d18c1b83b903334606926bc094022c0bb049342a3d2d3306702916c929933e8e31771b7cea7fc3f046cfc466fd3b35d4df05e3d72d090917f42cf6b92154f90dac3aa83e7b2437b51401489b99596dd0a6a009dd7c745393475204513d27f3ee411b47e3fb191998c0960117796c023ad208a6a148924f483c9940b538e35480612f01aef3410049eae4b1616ed2cd6584a87e3205b5b5d488d64548b40bc75ff8ee2ce7c57b159c91860018ccd96034888386e690006fc336c8ccdd8cba18f97b552416d2ee62fd901ecfbdb4f13516fd7073bd5c91f6f4467b84ab689bbcc04d9fc8f8bea1dea73e5a9ddf74c1303c414d25fc5ac7e50c24803c25f84771b1c0e2260e14ea65d569c770b090a5673e88c84e01bdcbdaeed55cdb7662e10d05aa274f37374c10e69785c77cff4e1bfb897d5b7dd3b013508495794323edcd9e34bd8a33cd80bea1440dd5dbaa021a5265e188419bae3fb26e752e8f9868bdffc82508023ae79003a0c828fd55e94309ebc8d0871c3afc9dcad5a432edbc98137bc6fc1da810a9dbf95083ed73b7fc70e3c9467aa098d54771114d2f0b867892fe324da85a26a531d9e288c502d12c20745efb5a6fa78ef982f4611f8a07e709fb6b2962465048931a28027e8fecb260dfb9fea0725694928d228c247a621b2db5736fbeb9b9f3868ab43e1f1e59d2ffd3503ef9af8e5e26cba69088971f1a9923778bc587198959373e6366b1a97910891e9e46c6097bd8cda184613864428ac6476796984680152886e0eb3186244e4b7b480e81e20032137bcbba04acc13e7664e0a88441410310d25fa217d55d4f2d8419f44adef936a1246edb804f0012284ffa8524047772565e915f9415b4cc987ace1631014acec01edf1af03ddc8194609ad042faacc80e5d7dd12cdcdf8c680b710d86761b2879ce572c80ad12e8f5db6e46f6c85685fd9598744e71915e044e05662697ec8d4b26c246b26ae5fc6fb06641189131bdf00da9f36f2c57649a8cf1d937b8a8caa060d4980e5397b0afe156f22e0cd01082642beaef3b7bd4fc56442c3f319fa36469fbac7b70c4667c729a4b046cfafb71175dd4c510d88d3378777a74b680798ba0aca08634ede431f2b581eed62f773c976894668ba247e57ddd27291a0024c1f1a0fb121683c5f651a3c498add6b53b8994dd615402ca7c0a81a91fb7dbd4b0e6322a467b269e187aba09b66095ab172372f56b42c627dea452b5626aa12dfb03b871e22c05ad9a242fe2d719bd445bed8155d47a3c26011e07e4895855fb10df6f7ca0f3d60269380d3dc5942b454258370b9e20d6f2912299230529d55be718c0f2ac0d0378eade02dcd081091a4faf008436e8fa910a998bf09a46a474c6406d29f874d64018e6d1056ec4fc700847d4d7d8b3598944560718f4ebc588451c27373e68f55403286290300c6b80843b1add9196383cfef120cc4521a616325e41dbca3bd57a6e23716bc10c65197eeab0285d1e44e51885c379f2543e032631c975e7ba09936324cd3aa0c8a09a913a162c87c97216493bb5ad17f81b330468d708134f5bbe9783541ad2cc0723b741464e0d4d1c5145d2c857a1a9eb456890ea7b88cf3b74287a77ac6016f975209f9c3e1ca4eb5cc7911a182e79bf719d89d90a0b5b41e4e0352c6d28beba3c2ec202d1616cd91c169e3f071dd8a5adf48d1053d00cda6cd166bc9e281db6e89fc581d5a2ce67565c4e9a0b46d649cd248752fb9d526420d2046c68950aeebada097e9510f0c0d7c7139d61e0544cfb48ee1c00030b8cec4ceaac763fcdfb02279e1850136b177e060609022fbefc4a526745fd95582058b699c470ea372f2669cc53cd01581db3a88996c1cfaf591f0e76135975f9c88df3b36aaf52669882c6bb92a20c73adadf45351bb6552afebe668a13516082a508d19116f8e6266c7637cf242ef4443b7a310f0256f82368a2b8c11c805f0af61ee0eb7520acc2d1b9c065286c2644cb9bc64399d8d541582d463c08975af65ac05f2e06adb805a3561473cc471cdc60f2a3dec058522bea44a7e8cc2369626a5ccd5c181000ea17e33151d441ef524e9b710e1f9dd4cb691a58e93131b6ab8dd4f8d2561473ebe218373cd8a668a81bd054862fba1fb5ea32ff3744f64a8a27d8f5d539c2b6512b90e421217f8a68ca4a6ec1c93b328154b8cce331affd22ac375a5e73f323efe258c1b6c991d37c88c6db89ed1a46d46997ae9a401c42be04b1d083b8832317d669f055fcbf14ffefc79a37d20aa601714f44aed59ca2cd47a58e6e65323457b7f51766a2f734931ab7f6ada3fae82a56dc2ce951d8c48beeeef1b576213d092035dd481268d7515dcc4a7a17ed2bb892b379ed03e6fb1c8f9e19731f696a5c1aa3bc4f4c31eb4bb8145beb6fa5f4e5f804daeb60b1b9f651a9ab9d138265b3cc2e16dc32a29da1e2d35fdbc3ad5dbd5be1bce5b24b254a0e17281ac1e5ec165b80c00d6dcc204a72a1c48382ac687611f4fc2dd01c00e75227b3f023de097fd479d1a431938264d94dad05ed1a34b890136841f76b6dc4fdf52c005f5fa5c0023281667bc334179d13a9824ce67613941b34e01c2b9e107e68a90e206849e6e8f2ed70110fd2e800df3da4320aea49373104de2e86575b6138bb89a162f98a4d92d8287d503943709fe5bec7c6d594912a627c66f8bda06a3251d0687ed53b608f18f61bbd9f6b1010976c66a536ee90b9b114bd12084ee6b250e2769b435cdccacd46eccc99f7a97c03fd2ad2972e48ef68278d525767cf96a2348ba70d014c97b5d865e928510c7a191371aec50815fb4279485ea2dbb7ebdc023b9a4b3202a825bad144942c5ac04998e98855083c68c28d410544cf8252a44b658dca937a108744e78c27e34a45e80d6036fc2f8e82413d8082601ef61f7face77b50cc57e4aaf61e7fa54f49d374bc527d626a7b752f75bc8c223d2bc661a2ccb8e1b99f96b16e4ea47f9a252c103c3cfdda5e4ebe5d63026f66be9aa4c8bdd235c0c63744d747a7abf2e4e0e2479025c973a26e716431a6eb39066372f76909241a018a9e542456704c317517283c880a4ecde828601882869fec8bc21606b368c014ce90a730cf020d0c5780a5ddb78b3b28591b285998c8c91a6c83cdf2c2c97220855c4faaf9b99ec7ec276bfff589b585760977db7b4b99a42c21012a022e02330236ba109e4c36afe0db1908217ea488a6c760da3eb119a1c9c60955276a54343057464630e2e74ada06ae3392c7f8dfb1ec9d33823d609fc7bfc7cdb32f3b9412410bc7088ef0bf5de1e081be2524a66158ed3f6761016542c628652c468c2627851943746c4a1225e73de247151122c308e0780e986a38f758396ac5a3d33de252747241b6cfefd0b683649a895a491ff50a496ac884941a0ad516f1ffd4166750426aa3b1a46dd0d86501789bb3cb75c011ae3e2eabca5cbb3a0751f7defbff4dd7ec56b9cb02836f8fcc6ad82db29a21a79c99cd921668d7b073ffff6eef9cc33d841abb4862d13a296b724127a41b5952765d81a6b873bbb6f3de3b7654119ba2cd8dd76db28972756409ecbdf7deb570fd681b4acda03929dbf18811156432520e5170a8625d6c59d821d8aef5ffffffff2574d7ffff0fd32b2430863b57b6d3309852261dfa8cd78af5debbaef8ba4c2c5ea8391494d215351e1f02425e4043b69a6c48dc9c237981f40011e34b24df26b092ac4857cccd3ed86507ef78379823379a707b965b9bb2fdd880abdb5b911a32e72f3b92326f00921211a14571bebe096e2e20c52c45959016cd5a8a0d020033aca17766556dc669ecf6a363510095d204d441e7b710bfe0343db448b123c7cb154e184cf59028fb59826bdad81fdc628f0519fde3bca3f7de85c2ffb0defb536639e79c8b80968890c2226c119958021d6575a1ccbd099c3680384a251a2c3c8475589bfff573b0ca597557658fb54aa20285ae44793e6c484cf104973978ea09de67deea46bea44e361e06502c5e63ea90fbe0dd032068e8c27cf60a6687120ab685dd5519b2c8546b50ca5bbfa4386b5da3c31140910c0c3a14eb1b73abbbf75d325e3e4900d98c888311432606e14d324a3450d0c418b98039cdec95674fc44daac6bd2cc6db7b8f07c4f9e95f978e0674c705fc00428ec510fa5f658569e212f1e65390d8872aa4cec097e51fdeb124997888742e86f10b568d7d24683fce79eedb66bb6580f07fb62d99f9d507f7ded7de7947d8948c08ff77846415571fcc77701d3686da75fbefd8b2f6807a2974096f2ad4606a0ecf9f0ffeded9f7c547d529c982a2b5bd72ea49feff2d95035cfcc27722514396fd60c72904d12668eb4393bf70968042c97566c34d6975b655e0a5ac7df0c73af5694a6ea7a01ebcea4de8f550a903946c4962ba28bd865469879636b8ac232566e3da6a9628a71cb26a08704602e11f9b63235390e03108e7df7bef254be97fdf518dfd72aa976dbde9d3bb5bd9a45a0a27621b8ba5259822525ad5938ecc0c56899da20b11316c711105040a99b820e3408207080c4fc76d80caec4a66e8e8e92d08048aa94ca013856a5121ea71f319ab114bba7263f1026461a354e06a16400050dbfb1bc0ebff97fdff67ea0cb935ae0427a6751e4db3428ef368742007843b27f82936a0fe343cd7f928396ff6ff37595360178f1a35c3d0ce02483755834e060d77bc2a88993cd1dc6bb45521ab71569d268f535e58476a9dd324394a610a2427982a4990f0630dc0f6ffd51d6c48ddae9750be242bf369adf7ffe5af938b9ecfedcd7d4945bea6f0d38b75a11e60577d5ab1ebc707ddb4b0e0018881b88802dd8c01445c00f74fd35e5f970a26e2d1112b509259402541c15dd39effffcf6365cf95358f550aa8323d2dd16a43895d063483be672a5edd65ac602b91068382143aaf6c28b9aea6509c058d84186c182947d65c5879e17ebea9b8f7f518e205f5409223dcb9b8a75ba5bf7f907b142c5062fa505b562559e76630f5bcd5429982d4764c069fba9a64c531b6e8da7e215ed80ada3cac1ab7302fff915a98f11b3be918d6a6c6921768a41d1a7a243b498007cb84a10feec53dadd6d3b685400884937d28a762ba2657044e9993a5bc9dca9b1ee0ffcd754813f6cea122077d7e494a9373ae1a9547612caf1c52e85188e75def2ffba320eb4412958f96d4545408f2c9e8cb4fb81452cbf91d6d977fae6b43ea7f0e9d14b3188c822e3cc132640f849eceabe2922de909b59fcbdc728d2d0a486cc590d3d6b1ce905b3952c3ab0920fdc30d5b7b679fbbd8bb7ede7beb0393df1a4853ad1064652f662598689db005d19890424f47291a768bf19fe3ff04c8bf3e625e90528336e4596b1a11b7b4cab8a6fd60069057d46a07ad6bb3c8734d4fd833167d8863718b3302a33a5111672e471cb65c658b1fde16065de78ef3a82b21cab0caa502dfa5850f2ed88f1571229fcd45094ba2867007335114e28a2152b04721610f62d6646431cd0c396d1240af552348effaa8ceba43cce4ff3c18431f77c3c918992e2eea091c2d4798dafbdb8131c9497825138bbd006f541131c52c9176f1e6a5a662c87788a67fd8318819bf48c95591649560cb559c7cb4f90ea565b51407620ccd8589c326febf9f62c8f65ce63fbb814dcb4d4b8d181ec07258305b5152593a449f9b8fe7b91fa3d600ce64e6484b69470601b21b264ff0490686f1f949a062c7b6f1791ce5a3f2381f63feb1f95b979d65d39fb6da05ea486e66fe263c661fbcbeeea977c5fde4a590ff3bfef90e997f6231453b606a4f2e95a01b369b22e78d299ab48706e7db3569b1182fe46ca846d59134a353dab4ab9df49d314eea98d2adcd062f10fef64dc618fa0593aaeeeac4d299181d30916500183007c657122ad536733562c689891714e7a6b9e9c081cbd0d3a7bdf3fed1ab9e8484942d1142bbcb1b887a1987ecd3b89ffd357fb5f7b70daa33e7af8e246bee4fe90b8df997f19dcca771f364f3d736e727b4e7d6bd3a873a4df2d5843d3e78325ce6bc0776062ddb122e2541d762b322eb64e6b304421bf19c0993b16774d3b9f7defb5067c8ad9cbf44c20a35713d019aff2c003ba77b7f2540fac0401be79ccb3a436e4dc614d72d45ae3c73236af20c1ba5256953a7a9745253b2fc0b462d791c8ba26c1958ddda6cc837e20b885f8c3515661d2ead0735653ab16242b1421b3ee1e73832e73d5f1d7ab638bcfac82d30ac554c46cd6b724bd9e32a5ab98e7057ec76353f387813ca39d6248b6a8cb435c58ada5a4680e0d03b0d22bb63bc6412af98c3bd0b097bac4b2a9273de0035028c6fa87450379540124300b31800004000500c84813011f438f71400030bc064c06c4028343c3028140c8401600030001482c160000000060303a2602054109894e26a0340782386c18219b1ba0d8f9ed13f9a226e9ceb5ceb91e21e0087d849ae95ce2340e269503c041807e4acb5486f8eb9c9ff36d20957d2e2dbfe3c0285ee0343ef7628473c83168fdb04909216c60072740076efb3c45dc219aa69a35e56fe0a409638cff71529cc779b8b5ec93fa989c8166eaba458fa878f03d55608c93796867d31b25f36a476a26f2cd94659c56bf8500edc701c93698c5717cf0c546d5c2037150fe0a3b01cd811f13a39decf2d74edc826caf29de0af7212ae60c5801985247503538c89b00cd2e357a2f5d267bb88b62de66a31805bff9bb26913b0c9be09cfd4be1b082ffec7cccbf7d37bf422049e1dc01a723ef9f51e6768804a72373394371cf5acd03672e7496360c0149bff543b076aca2759c34bc07ad45ff803c9c7e7131bf2f8ecc4f2c05c2bb2abe8e679a201d4b6e3aac6bc8449ba69288381c31311e894d5cd5533640fccd2c1f67fc3673adb59cfc78a9240cf1597e7e4bc1f212e7f0d8f85b0dd79adc99c924cd35f3dd762dc9d55081bdb542871595ffea4e786b40c9e09e3baf00e343edf63a864f410b48ddd4fcbe22c620b160def781f1a5c308a8d13e31fbd4043dcf1d25279a212172704c0f0d4e9fcca2e04a1f239028cc11a033d620cf4d1f2172e00413f2bc86981539a067a33b92a0a7f6c559216a3af5dd397012d752e1b9f8412795c68d83a010f61edd3e75323023fae6e210266205eb1c708002c64f01a0fe0fcd44ea4f4a3eded1c0b85d50242b5396da6c90e0b67c8f92dacdd9c8126290ae00a60d75818e865e5186bbc87102805a2f69b4305028e8e005ed28f72e053f55777054359ee9001f0a72200a29a246faac710e5364b446b04a9aba9a53baf4de41dc8b96faeb8becc9650739ac77cf4126afea2a4eaf37230221cd064642a8fd11e7a32d7c5636fde6f1765686d4172ba85b36e3444d1d422219fc47c261017f0dda1f32626fb9c5922cc571ca7aa910f74fd9301a2ec6fa4851480e7c7df369b8e016da3063666743abd2be5bca208dcb984690714916664f61ff872b1017c2892ec11954133a819fc96298f9a4a26068b628159c573dc812a260ee860cbb461634850063ab4be487f299205b822629b22a6a3503404f1c927eb0876015b59a5671d8bd8af39fead519134490f85307ec527e9f124d1e490ce4612f6f2e64088e49e5738f70edce1484a28df5039bed079ec0b5012322da8414b0beb28cfbfccd8bdabf6b9385c7f08a25673c4bba3deba44f7bb09afca64db1640d3f5f98e92804ff02098fb44e8e3aa591b44e124fb4fb8d7033c0e36e9b8ef8f4e1a7a88b62edd5ae34c4557b8fa8c367070e24f6ce8748afb2c37ac6092e3311881e99f3e981a275bc8bbe802b2a90a684396198c7a8eae73a61d236b2257eea9fba23bcce8537aa449d7a1acac80a5121fd97d676cbbaa946160430f8126f64a077992f95805290ac2f916dbd5edfb3a812344730a3dd2b81e62f9b1b9fbec2e3476caee42fd2b25771d2116947ef696e14b4a0e382630423ea68b1606649a9beae125a76449a030008ec8905a2644568330c426b868bca988eb0f769bd6b85cfc78919db8c75184d11d02df61855d19a27d0290888acc4ff8fa27b452c32f4104ac5c0cd0228bc96e9da3756ba301b22120eea877636480924ab8cbf90a0ba5d9dbed17d516d179809cbad1924796ee4aaee921faf981a31abf06647a9259fe4d112d1dc139cf4aeab0514d336902619d73046abdb1dc1abc8de50b0e4c24223ba3350e6272d9c1a2f0c75b1f171becc1eb108262a01cca7f2640dc55f66fca9ae309788be4a53dca0811db504c1258f81db02242a5091451927255239a80257adee733275d201e32b27651f70912ffe3b94d2177b1270d67941ecf200f08d14e31fc44640c1da20178168a553144a1c2d6043cc2d8264913768dcbdc73a2bb716f8dedc1ccfa334548c839acb73bb182a5b8554eea51128f2f4b5c65cfc0acc17edc7c02f2f6ad45f9d6d6c8c146695cdc93680638b53f54fa0b567468a3a051e0fd44e54d9627412c03e25864684649e2fbe58f6a1c4da4cd5161c6fc5171e0f6e77628ab6190f3c0b4b6f2d85082d9637c7b6487a0017533d5f08864dcda81969be0a613a657ad102f900f9e924a23f3f2060e8e42eacdd62cbc04a2413de0ff5fb99c8d6ec4ac4e27231b55d43650276d4b6c4d211235c6e0c18c549b68aad19a44c10bf92f7d701d30a5ba3f6c2bc4b2320ac3ce3d8203658187374e26833e11308c7cccd71503fdcce50a1bfa91e586a999a585dea2789c86af17e05eab45c35297e63f73c2634fb0db2623246e9b7b64b69df221e27cad435b5e98298bbc9fe89e862d1fa4813c27e44449402424c079230fb806b150c0724dbb382f3386e0b072d1bd3403ccf3f6716f02a3b94eaa15111667f012f64ad91b61cff8426a48861a610070409a31e21c8b4b1aef8d997d47219a121100840b264e88a62259ab8e03a7336c77d581a4d76bfe5ab4e8aaa1425dff5b95c19236a17debbf98a130c362908c51bad8ab505a82bd64b27624da97c8f8dc4ae6dcf24d3d97b14f6ae2bad4b792bea96bc7843fb6b3c9692141b97b57ed19600b6eb4f5e0e45e640059a4c6a99eb34885a731c94dc57ae10fbe95217144c83b4d0a7883fd0f22a1a572f43eb52ed1eb18a60d260a818fd766ac60071224f1cfdf61db40dcbe149c1fef744aaca60e1c9e0d1af7d9c4c40c8828752eb83fed9523626d32a1f53531cca5229db392b91c2c89934af8bebd6e160b58103c6d20d773098f6f9ae15fb044339911e32dbd26fe6e4a4e7c5b04048240b2cabd796bae1aab24b89d1b65cd1c9dcc7589a88d326d5901b425aa04a1d08b75f9372861ce4c5ebb9a122064e43ebf1fd438de4654bd6c49997b44bfa43f78d353fe1fefa388573261a4b3f6eba84761d55574ba42f08d23f019ad95abbba1fd18e9f042c22bf21b34c7540555ccf924f916917f3f39e9254636d686d7d7412d95be0a1ca3458e7aba91cbaa411098292e67835df12f1381800012ddaa9459e7964529370e3a864d2a1079b0560348ba6a35e5df252985d3541f03b17271fb9123b7a01c1fcd8a855699141545a737206aee858a55c59698b1b43f9af126c788aa4d69d2993cfff667345d4fa128bf6909281a1d431fcf34808a08554c06b044435427d4f3a1a2435214e648e1e5c148e046490260cc81d6b561cf676d41933412e6b381d39be081be89b00543568e5e5d8fa130b017d44c193e8acb3246c52852e1799095c117c3e71461109baf8f71674fadc5545318b7a3f8af866cc088a0b0acfa6d395e629edde040e5679251e5266e226d8ff059224cbb68144e42ce7ccb8dcdcec5768cb94c57e0a28c9e28bbac20143150ec51a8066df0218ca693c2b0db8a5cf8c50438c83ae34578d598c908ea458016880e836c0bf54b9cc1658cb1be72b1fda5ebcb9336c86a374ed8c97ccaabb226e084440afe106d7c0dd0a0e3ed9546ca643056070f6fcfbb3bc4e9901886531fe5880c198879a2f1b64bf09d6904eaaaa97189171bb9795dbd661c3eba2d5841661222951dc0fed8cca961fc89e0b0e2265325501199fa80368f8893c0a345436d9a76769e21730aaeb06cf32e30d0ed009264a6295748e22fa6f0bb54082cb566a3098a1605067e44c4b80b0e305db4115fb00815b4851174b64f36ef0b9c78c9d2e499e3a709fb1e3b19fc7c8be1160b3695dd4f006f5c4675f073db25e404128dcb0c595bd46bcd04578161713a987012068361fae8a9e05270e3394f3b6cbd559fc8a0242e0afff0b6cf991a8c2735fae90768ec76b46fa1194239731d2b919c90d357a2c1b3e89cc43f37b5755a6ce8a5ee361bf7cc5033aee2b1b27f5ed43c9507ba410af558b914fb942394eea5ed2620978668bf96140e47724417dd1dab3b9ac62474629039acf584a58f2a83c96686490855d74bcdd22784f8ee89a5fff04f6872970c613e27df4520705a8f8ca1db5efb9e307d324326ab5298f7f5072d10dbf2eecc170187b9fc825eb8fc88eb695740499b51cc23694c9428f25e6e2607172025701b1b2264a9190e3f5bd0f1b0c3c02611f09b449650f276465c13a87aa55740d59fed03c67007f9a8a308d88d958c8327abc8d689e5c26d9078be1889804859f58111bf252cf4c677d776f0d3010436413ae00f28bbc0c142035cc7fc893037fae648e1c0c203a3ee91e8db30e7f9c1ae8bba6307f99ad0716d0fb5e1e383ba37bf5181182e912f951f630323a73c24533346d6eaa32a23567cedac1202eec5b0a39a43ff3063a5c18da009f3dce12295978a6554e20eaaecc68c23d3584337799de7c1f3db644c9c6658c0327abfcd7963de8791f783db5c915b68b99a79ba35306351c4f4c204123c395d1d74acd502c1474f1111904d891c294c179dd83f79f7f3089dabd323d9b14f8b7f972b78db6c299b52a6e14d903911a60034bebf7281a7ae1fd324dafc983ba32d0112b5769caae83769b08e8cce92bb9627d720cb578d4923b3579828037591d1fb49b44c7bbce13e89b08e7f9b38eb2131aedbabd863f86818a291715ed4e98074cc581a945d0a2897e77a7c646303c61b0f48c9435c260394a7a8e9685a9fd1ffd5487ed5bcabc00023917162ce12ffc8e0384d7b58db56a3f41ef4d63575833eb1201d91d90a29b74efdff735223ac0c8911da9cd7ed5f32314fdd087954c40fc1c3bed4f879d7baf3e56080594322d988383f516d7a810d761b60701107c7f0ae9ce4f9ab90ba46297c3aa4e1df59d29f4f50c0f24955d05692254b615c21372c963f564e6f7a995de0108792f85634953fc68fe89ba11a390521fcd3b1a684b916f73c0be5290d1a329f07d128acf823286f82c5c5a295ced72342e8c87c6d03cea5d2a01a88a6cb2a3fac8f07d1dca151b033a955ab222f458d0bc3555748b7e51cf7a72df90361269db034969978b154ef85448fef4066fa0fa003235280cf217c33af4ac206d7125b9785c811e63bce125c7bf48f42abcd2309c75ea760c615db16682215f4a5ce0eff18640f2bfeb5ff9ef51229dcb518de2921bc21db7b2f1eec2d515a9ac069399cce9e756b4e0b52c113ba020c16ab9e2292b8179496b28ad1824c9173f12585c181b0d9a6f8fa64c128e022680a64e6c21425aeb2fd2cc709d6adc88ca51d2a3de0192839ed40432542079a437f078dfa999e018902ff47a20110f14a514d4b6eb0ce3b2b65607e064fe0bbfcfbc01d5f84708dbc5b17d89a5085e1abbdfbc6bc4b0afcd3aa7dd3c143e5afd61a3528587c67640e0a457ac06479177bb71f09d683ecf968342b8a61bb812210c8ab6806412d861e9960516a9d1fb4c9807221e708352c2afe650932eb3178ff0fe6c60364fc86fe8d9651a7ad88756a5661ce742e32689c6eccb8d4f116596c189bc201860179ba758b592a8c2594e78711134d9a357ae9552ca2082af722a68923f6dc5b6c51e34c02f972f0e14daa02a9990a83dd80b571d0f1fc45d7854c12ea86412846ac1f9f1f4fe9fb69de4ab066e3e550233e4c251c0fc684618ef93f2a6492ca8e0341478c8bbbdb234d4831ffe26af20732fa4998560e2551dd26551fc7b52a459d8faba87f5b09299b855388838680f33314803f86b4deb942e84c2645c54da49c25976fd000fbe59ebb7d317ca2b402810db6c54118aa24aba136347608f5cde19cec8ca6b824f7a89e1871afa92142a54547522c40d2483f5b39785273949179c64de01903544bfccf7bccda193c660da229109b249d4d645bfbfc630649649bdbb914b9d189d41239a7487081d60aaf6ad2eac424fc5b4aa9f225cee899439a411dd01270fba5b26f520fc72f938313bb11db2df13d8280f9ae067f029c4f2009a19e352fc83688d71267811c10eb309864390261f2f64a773e00b754392dad8ebc03332ba5575ffdda44018589065fef782f9153c0149db0cef634743254720a6cea7f2da8c311e48bf4d859300d8162411c10b1175212704705b36b8a73e3b647320caa76c474a6c711593f1dbba9bbf35848fd2102e695a04137e26579d310011323741763a8253408ce89b66bcc7345bef56e05d48f89d3bd7b8ee20a9a59e47889b915f399d530824a94013955da13b1b398a0a6ac69d11357cdf6992bf8c3e0abacbbd7af69522331666076bdbaf91db906a1e4a275eed1b4dab7a4886a610d7c416b20802eda14fa84330dfe1394275358761863713a3887e8666e5df8fb301beaf0cceba806ac264a467105837367542221b4502878cec1483d81143f708791213ea8c44508aefcade4f7b60864f3eee460dd04c02509a38074b8fe721ae2e047185f3503b943b8701549070977cbe7452e7ec910b0fade778b0f922412382ba31b0ff54784963fcc632504e5dfefcd3b549e4cf0d07abc48f70d0f83b321f304d7c3a8d99e746ef8b4094daffb4ef1bdcbafc0f17c2d77ed252e4aa4737256548fc10762ca78646f2eda140e8b16148e007248016a1a4527899cd4941c38164ab5d3000bb46ba0141babd00283be5c34427201244940c11040180004fb12028659cc7ba2d69ef18f204bc4875c6640cfedfa7cc14a3c6a848d218c3f4630e19c543b2ef4435c9c4f7a90e027673e4c44b0fb14a05fd2c5b5518d5f80809f45e63ed2899a3765b2dead8898a1a5e990fcd030efe3c70ab96c5a122d70691a107704a032b8434a64e6bf29584351a64d8e2516cce6f3395bc57acfc1815962e9c5d8ce650c07b90fc03c54e2c0f1200a3c505c119c3f654d426dbed169d6eb943c1f4663495d21360aa3447ab6bc2043007dff2265ed1a02ee696f24512e19110f22f21d521c7e65f1ce265b4048a84eec47244a74f047a0b6babcdaf2e27efd2263da81cf3854b7453b377e6c7c5e83a2dd6c22d5c1199823b8139ad0c0a123196e6c6b05908d22d1d7c68b325f9edfa4e94c869c07de5688161542fc5bc8d4053e821c42ca149f637c0084c98025e310520849a48b009d81d8690483b3a4f93d86b406f24724bc1f4f0130f2ff046292488cd7236cf29268a64087ccca6cf7ea2c61a2c914d5c1ea79c2ec329a4fa0671c14cf759c31c999469f20ba09697ae9cb22bc19ddfa8021038f9618c777c533dafc2c09701b80b8d57c7ef404450cbb25ef1f7325b152eb260c831100c2e55e3f5c11e0ddb897759053902e23e29c7c8c09646af54b1a7c87ec7069d5e648ccf4f484434580b9ce48782272e00f4a7c0ac15aa87041965c8edc3ce7b074dc84e926e1395d6eee88a5c345cd3585be319e26db89c760b9505838fe68357376a94969956881964539861c92ca7954df69d6bb97b8c8a923ee76c9fe4466b41bd953927cf8b34fd5db9087f849751677f7fe59fbe62d4dd424dbfa116397d688d5fdeb854609a8b8a820c7c8c96ff97c929d6d0667a15cb05ef46e8c2bde416f049258649c1727a8dd5610fd481d36677a82c3e9029c1100b5bd1945add5647b971e2714996d3be3b98cad176f078f15a8e8a739d0182fbd3035ff3834420d2ec83b9a6f6ebf36545315b8aca4718546b8fd7ac97904bda6188260881e31b3c63c9879e3f4c3b0d4642b3e088fde605993529300d00be88e1ad25ed96beadc43b97e70aeb824a5269c77aa636c5888f480a21669bc0a76b2811740e8d36f56c57837858279f825ca918388b3a8e7537ac00d583d615cae45fb59c30094f35be8cd1820118a87ef4ee0cbf6e01e726b863cbbbf0d382edb90667f77b6775ae00cb26fd841941cc11bfd7ab2722235947317c5eb29b1528318bdfd630b0f7456262934bc5ac1dbdce1774dcc72c907e8a28cb1600565bac3f076e041dc94afdd68cdb35cb5b75989d522b75ac9a92e4949a5206e7400b0cc6277470b438806747ab005efe1aaddbeb4345fa910d8e2f38f8f3f85b0e60d4122a7a52904b902480386171ed3cb885f28684dfa2b02882e829d44e6edcb3e438be907b9a1536d1e421142115700f727177a5db059206fb1f2900ecdd094ed94d86da04e36a7b01a766a5712dc40d105d24d013657c705eca5755896dc4d74eb141f9265cddc6df95020a39936f0089db919be93e7f2959d8d401b11c8f31de79a40739cbef182ba647e2162c37a1d6ec039bb0238a807f3db90b5830816f1096078106937ed86e615b8d864c71bce23c5ae45348f66117775cb9dbb9a4c7f89e5bd595c539aa6903053473c9d84775b087780289a97da6a5b51c213a190b5eef69a865038ef05d2b32151db5cbc3ccfc795577a9bb5294e15d14325a42bb1e23a23a4063ee5ea8adca0a52c6f0c1a3ff2eee0138a2a4d83c93aa27bd6a4f7b295ca28379fdea90b3c02f0701a3e881e6c8ce2f3a3e86883e25b1f1fc296a05f3febe3a8d8fa66a8fed577b5472241e80e0b098ed8b6b2712d51a47e689e39545e32721f04afb00076e14606cd5322b6c390b3b6cd162ee1299e1b5a095d62294068e5c551a0f27f597030afcb923df0565e3687d46592cfe15b2ec63d73c56f9feef5cc776d591bb64041e403170e96c3ce4504ae12a998d71a8bd90131b49ebf0ae1832a07c8df41002aefcfe3231dc30a893e015ad1f1f32424235b037a141c33d323615f19133cbd9ffb7ee7448e93066514decc86ece6666683fd2ee11c1fb3fbf664c250433e6267acba5641c5ca2566054b77d3f02089b0f11261a92f5fe75ef4ff891b3d541d0941080e7c2020a2e8a0d1e0ef47e4c641dd3bef89b0a00cdea46f1907a1d1d88ebdb76b66bd425be7ae468b0a71d77a776418af0658945d900f3b44ea3848f4af13b330139bd83736f6aa9addb49a35fe007a70405bee44bff78ae04d29d36c0dc888704080817661e5fbd8c7a1e6fdaa3966a34a0dc306dda7e86008ac075e25067258c5d5124f618b0b5702a1da9e453da0970030dabf135014984598200f27565f7e5318c6e648336322064e3d598881dacc54a2baa9775d6eac434d528770307a046385a2d417a34432f1c83d48e339519727ec7e28f4942ae3d432452769068f5eb42a14e82a6fb86368dc5c37294704efb4d276aa16060d4d15c15f4b5977082e6448b148ec52d75e88857ae43c496e9590aaf40371c799f383627619dd684723482759d7124c2c4e5b22b6fe8292d140346f96581773089725c639cb538cdae6dc74dc275df269186829217145688c1f880d707d1c7f8237430aea8e4ecc6329e066148c48e3b79b4eb07c10dc846866ce1c22cd10b69ab5799933209ca727f4a3999ecdd5737b96cfd2472e8c07742071303a38c42647d6f6e916ede0962f6117dc170d4c19011a90f4205780cc61750e899a83ddfd834158032e0273300190836b612cee1a51ede660ac7340741c1820b67307562f980bfe3f09a5faae6a1bc35099eef7124a50410298a554a13f59bbf8f41b7fdc94c0eaf6bfffb7943249b9f70e0402f701ec015a7f41b91219b4f84e932b5e8f0210a3d06a54d9596374b1804275dd40b2ead041ee890550850f8b4f8e7e7140ce4b06550ab885f0ffb737978c7b61909b73374f699dfb15b5dfa25dad56bb00288893081e4194154ec81ea34a8a8c202d1a58d38290d9fd6f130c1849712981853da9a45c3f9888f9e204cb8efe3d29507568d1bd8f2fcc5ec8d15acffad3aefb53f99dcaa48ab7b2ea1a837d732f2e6732e57c7324bd05f7c1abed189a35e7b5fb3e87214d0ba61391ea45024dc2673328696329ee518580ce1111aa5080f3cb0009ab06b4c5cf45a74307b91e12256cac046386dad71a97ab5911f7c2233798820833b751a560bdc0af040bce15ca36d71398dedecc9c02664564600e5dbd31ae25e94dbf796f723724370870a8fd80b9432f7cf2c73388262738fd60333cda147fbb1662e211ce3927069f28f4e6762ba95d7f60c4ec30e7094b219b690fdd7bc405021d1136a4a4d1ffa97775683d1da2d3ac5d60f0b1435a8c4bf2934bd2eee2ba3514ae8ab8b76b9673d78603d049012f9161031a4743910900903c78e4a0e2010999509aa8b0332ee6b346d045e6c99c6d19216986985f25f4af330538f001f493612585e5a56ff6de0efc547854784e205d14bd44217b8a9e4a405b84c47bbbe9f05f448f0165da0a61b0168c9666f7ff2734ee356a51d534cdad51777e342895c66c4d355a1fbb042312e32eb1c620d75503cd1ba6e20b1f502c3294341a1e6c013841642874b6ba80da278f88e852817969e125e84b65c790458f652a32aa51e18264f1292a43ea9e7f773d59f2daaaad46b3089cd916de74d298dda9b88fe05ce69c3a31ebf1a60f516ea8669334927e14b0fa76295faad856eaf9fdffeb766ffb347aa801128ab21c9a14411dd84692b5248e64e0c4cf14201ccd33a2ea18ad3ac69776937bd7d3b4543168ff6ec1d392e7d428a7d6a997323f3bd3715e132f989d6b4db678ea6a621525e9479b4817645ddcbb5b760fef729b932bb2ba59d4a89973ce9dab9105caf3766bef36d2794700110d0c4d3f15aa259384122415c40a93716c5f105e94c4192db05208403a589439e72f5665ef9d789a11023b5bea9071b670c143ea7531e1db91d9c3f58e92e72a232bdd956eca8853edae76fc0a2bfaa3164ddfdccdf940d3cad41a62ed7ded9d5dc3006bd524e72d54f1abf78c73b1c2101c00d19641ec883e378082d2f2b32818936004f7c5aa8a530352770061845698b68a80d3d7f99873ce39538b0d5940b2ca5e9dbe0c01f298ee690609185d4b5925247c312bc44210c51d48a061732ae05a4713a32c03c03001800c75051abbbc037a9b1a3a6d584375d53addaee938e79cbb5fbb1569d8909a12ac334076efbdbbde7b67dd2cda0c88cd7c6ca9512b566cdb7bdf7e2d5af5e6969672f71fc067ee649871138655fb95275e3aaf1d6bf47279f9ff6ffbebe35e7922535987b067499603972272dcdfb78dfae9396c5a3f3cbf90c52bd6a38b516d9b87fd8a40eb5196a8ca5a92be5998d4b223c43a0a1355662520ca5a0b44b175259584432660ce94c40d61833eb9d414a419cf929832c333b319155f622c8b5e2bc211a15289fa5b99b1ada982a811c0deac0fde505ec6dc6016e246b2f7638a1eb4ffcd02753ac562f508a9d1b8651738ce5bce695f13e7dff0e59c69475701e7fc58ec6feec5e5a26f6e4399dc5041d3adee2d13ca23a296a53a7efba7b5b44f65d8ffffd3525e3e9e3ca3afd3c745fae7c7ef43dbb129a29eac18eeeda6ba5c92e2debcdb744be5c3160befc89e48a685e41da7389cb5e8daf6bed5dfdebe27ba9d9a711770b90bd05c92f60b282bcf26839ad4c27bd3525e4b92c96a0c997e56325359716fde3ffbef66b2a72532a9da08111885b100dbffffff0fc930e455fce90f42686de7725ee32e43daff040aad5a13f39fbddd9a0a063737106f0f59d50cd81e5ea0ea4f7f130eecc2d4b23f82b26cbcb7cb39e7702e4979641cebbac111f34b4a08b4527a8261a309c8f784b2a5e311a2391d64e32187de902e9b25ce6eaec054c0187caabca2768c9e38820168209c0cd4655d82401494237985c2e919dcc12f5c31c899538fd952e84cff40799e890636164a9070841365b334f88835f88e15762aa84d67f5681fdbf7de7befbe378d7fed9fd6a240989ad50a413148d231a312d5b13cf5d2cf8ad6c91d14284629c65a740c35f7dba623debbbfbd7db98c5c4f5c463bb7bf7a1738e77c984bd26eecedb23e2845c8da4e200250ce93140ad8a7e5418fd30ad58e0e27e551c300f67f9d8d2babe930164242f20467e79ce5dc55412079489d5645814d842051c1f6a1f6f8ffb7800bd8f610feb3a76e1e6c74390dd2639f246c34c3aac8aeb498c0ac4a20c67811779ad8f2fc525beabfdd663f147e2c356bb543a141b121ce27311b8d11fdbf9b680a2169e8ff5900a48a3d38064f2866507fd2df73ce69ebf2ffff7fffb0a0b478624a4c513da94e2021fd4a68c25141a4988bc4b16759126786d107378c3f48a872e9f9c8eae9ac99570f9dba5d15c7b4a6e4dec7a6ee7003fc1ef7c57ab71d7e435c2eda37e76dca82fdff2345dbfeeeedd3e2f3b2d98a4fd2cc4994a25496b3a34b0ceac493b3c771822e02e007574f0eb2c81aca6292e907a3d2b712a5b4d4d59452b38f4df10d849b102e4e333c9bab119aa88f45f7de9bc6b996a4d00f34511d49ce2906a05a624f9cceafded19310f13028edad112dee8e279efa0a2277b7f66586900d160b53530ffdbb5ac4da80ca0b221ba20bb82a262e2964a043048fb9c38a11a485467ad111975b528ce39c0d8cbca85431794d41c201c31800040001003110c6c1408fd35c3b1400030bb474bc70382c284430241c0a85816000300c1202024130000c0603c3c260283c149655f2f201c8c38e10313010752dfbdc08ae25764370085f4c91742149d5635a4c3b274d5222c790192e44ce2b451e34796564b6ff3432d26c1810b506ef095dfa8d1286f21eea36136d1b8ceeed8e481657bf018cf14e9307f40d612aa1fc663f4855cceebfa0e8686f5a5de955e10b538a90f55079375ec18028dcd95799ecc318e75d13f797a283f6b41168227f2f52e7cf2600276ec03a4e9b1c87a98ffa83b2ae03539fdea23e87044f422df9e79b8af654053910a7e4be979c1dfaf6d2cca350d394ee28add9372cc78a73ca149d1b4982b7725a0a766c682663d6444099a43fcecdd25c441c065939cdc34301e9a9ada4aaeaadc6b6f786a24bed4d1232189371499214ef400783c55d9870edc6bafb233c0177c1c4e7db2e112e3346b2173b05a4096af06f14a8a4c4f3c61609bdd349f94fa998b7e1303bca8326f67fa839ce037aac01c0d3e081aa869a07dd68b4c900a009e1d90b9b97e7a0fe6e0f7a5137b70a057c77a76b511f9c5374f83af399c0d871d44f1e8c7bf02674d5133d4b91e7c11c76ebee229833a296f8c8d6030ff104035d00bc8fb4cb3f8088de725a74f4c6e39992f36638134446b9dc73651604eabc393b1d48615dceb767ea12c6ca68eddaca3adc7c16dfc591b300fa6820513898543f336970ce16e756b628c270759b1eb9fadea75aee78e33be6bfcea6227aa7ef719628b53ca038d9d61ea529b0f3dc34aaa3ea8ea8cdb1bd626cb6aa343b908495bdda45536a39c8a8237c4ce007a81c93bb609ea08633f8383a11a90c4aeb31082552d21ca7ad121414efae02e661d12f1da851565faed8a232a02fb3c9acf85b70632af0a2486ab4d5bf01b0881a23f2b94f70d764698fad0f1d097206b1815fe3ba3f8c188c2b6412d4e22e4a38282851147999a39ed1e34c85a53f5a80bd9c758cacc7ee50cf79acefe0841978ad1eac4861ae6bc11755045098d52314f67fd002bb113fa1987bcdaa25b95a010d65e400d4d862ea3f155d75b68caef1a889ee5025a587a5a2cbe7c20232d61d2f1b68703a901a23b600597a4194c24a52b2c0a72daf3ec0252e830e99f086e828b19e77d18a5cb7f4d8e1efb029a2b8bdde6c651cf274370ea7ca59149f7dd261706e52935612231477a988f33447606147c53b4e08e3641be4cc0c535562fe4d3a6e18ff85b029c4751f5883caa67f582eb037ce9a1a951f59d903e580c4094073dbbe377a0f2f7058587a5cdff5bcf989f4380210dd26388b32b27fc4ae70e92d511a982a200be7ef6858753b62723c57325acca13ccb0ecd4fab302402f615e01261ca6eb7a45fac9ab5b3d4c8bb209effec56d62c65a721c6340ebf448dad09ea6b02e924dff7b64a775b0600ec77b5ad6cf652c609528ffb23ac04aa4466e2bb33b06825d03923fa2c115a8a0831df50b26d8bf3738fe6ef09da5097729008b91f81bbd1f45df7ce9ee106941c873e4369306b7c4c96ae4cc067ae5d0ad7a2bc8e93e05445fcec231f54fde7246a4ba20ced996931919f26981584626320e708f5c7584f9fb8ea33a9b2053465ea1a788388db989e377b2ea14b7c98d01689f9f4743f080e535728b4352a1635cf73e50ebda5378611416e4dddb9d0f1140b5810cfe6bdd282d36f09936ab2b7f771e0957ec0967cced4da44426309f1b716693b013ddbfc9109782466b848845ce4851eedc17a2b225fe56a97867a72f51f312f74174da9f46ec0ee5c8efba3efc5679ebd9607aed14c3f5702b618da4b2e3c512a78da4c338c904b92fc1c813042dec33b8d062411d01859c91e5864b86e2ca50c98f229405046d3ec8ae477727ea8d6cf9548f8c82eb372d39da5d0450cbc2af940dce3ff0e646770e0b499384926e2489deec8213983ad861a0f2daf8fa69912008980c73b967055a5a7a5e3b18ecd5b6a336a16ea34546a9dbc24fbe278aa8081c3cf02be8870600568f496696e7b934a62874d1595a20b250e8827ce40b089103190b29461a78879322988ff6e278d73f92629e0447ae50a523f10997614267d4c8e1940a29c04012478acf64574348bf430e805473a608ddf88ba9ee6a102371a5869cc681af7102fb3c033a148fa38a1422ba82b74a81416fdd8495c3d8dcbdea77b519098d566b94fbd3ef04786241f4c4c73ad67e26deff63b284db54193c851bb5025df010085a0596c503d4bf846875dada6c9c9101a1141627cf318565cf8cd438ee7097f29559b5b677ba7189aa5b665e62edeab7b147ef02a05c3a58ef85d097431c3123692535972ee6d44f14162b4d99e9da40265303843009e609532d4840f038301a990c6c051ad38b30bf449db03489d7e5b2761c600e1cad919476a2428056574ad4a039756a324f1eea34f8fa9aca252efe8e168a2d97e6b22232261d176b8fd1cf2f9af0bac91703b0fd27be333cb9beb873acd4f591db1c22f663e5b84a926ab52764981920dd20b66e83e80d5b551a2dc1d25dc8ad0058ba28528cbe2fce1897b68696d649880c97550cecab41e2289901b9a7020c46980562cfb036537a080caf7663560a5697f70d472bc07a5572df45ef3d3f24f307422a6fc2a6513e1d5499c31bb4021398a99f496d9c40ec860013bf2928d5bfefabe6b3edad21f75d2dc15a9ce83de73ca40150ebee66d8f40e2604f75e279058dd94447a4f552750276fb4d1578ee5f64eae8ce1464da0084bf35bd5216c3560249a621bc0bfc95f663971bc17e44e22c7106750d1175592f5503ef4276a11dbf5b546cc1250839413ef94887c2a39ac37f0082e6e83bf46f13b83147d0a694c9a6d7743e50d7b9800c05222854f46bdcb8e30ade958f7f0988acd9211411e0707d5e3dc088583edd10aac88d56eeaaf077183a4767bb8e478483871e6654191bd4e8534642b331445829110f3d61c40a721bcbd67db78dba0782f2d5c69b41998e76994c405c0315383cf5fe4295cd099427cf92eae12e04e58901e8b21d72886c7113d3cd46613ef68cdb3c53e567ad7c219c3611c7646f799681b8604172960de93b152d2debffcf0686bdf6cf907cfcb32e3e48dd10f900f1eeea96ef41095b044042fd05bfd170abe39010619a4b75ab075ece5b339dd394f01c15cc02e2fd0997196036e1c24998c10b7aa50702c913bac978082e54b7448379ec605ba856d6db69f8785a184d4db18d0262d197022e47e8dc3506d09035b37145f85238c1231593dc64faecc0e417465cc358708990d9144cf140325e5dd4e32d93c7b2b285d0300bcb16efdd87f7ca1acb37d0e514986fddfa6e2f7c0061a4ad705b1f4d4a71fb54fdda932a236940a643933ded760126fd43a469b04e973eb5a4983ae02096a8ced6b4c624950f3e4a3908306083e2fff1a7678bd3090d0d8420cc2cb9f23b6536699cf876252c2eb7aa480d3d90b878d6f41bd2e762b8d08332f72aac01cbac89e3305ef58a25db0361d0eedc75ca4b1bfd7851f7ae2903281d2c21f6f1478f5e18bcebb8469808bedcb6b0ab6b1d9220694b7aaea355857c654e9fc1ece982d4e4dfe37534143fddcb2f19545d447222f0eb9b1e11215052fbbd5a152d485dcc0c5024a265f9164b4744f0d7b4c27ad53bd2fdd063224836bc3834a658cf52d73131b53ae27908e60caa8ffc7b2e0e4c4d2fc70f380151ac469d547a226c5769a9a3fa349dcdc32b5da1e56ead0c5a0e439b7622473f13e64d6aeb78cc6d1185e558266b7acb6099a6d44f3ade47105e9b66db345fbe2dda1512247ce56aec3a64a6a124c0f928c2300024c5f1448fca9cd95e1d804d71606321cfbd2fe08be392c9e51c79ddc65d7e90ca268dbb95c274c2211805e3708d26a192000351de8bf59bca88ca644a5a186ebb4bc032c2821e73005a47ecc345ed60c4a08e790c4424d257227c769ee8bdf290f6e40922c2d183655590e9221db3a603d78dabe500604041fc122c759cfba846961b5e119958b2dd7d033085442bd3dad50d2c0d5ad2c77c4d3bb89c444be23c34c8f0689d74f860891e09ede1645a21ad3440de7926d872c10fc3580a8e02091db5ccab43b18430f69b2f15901e772fa09991525f7e0c27cc83826f2cccfd84997e2d9e57137f07f9c4e6b3ddf97ca8ba6f57061d87c68f9a0fd874382783108d1c1117ebd58d0d0c312a2628dce562ae7a5567c9af58228c2010f49238d03452a5ff87c33db1dd74ed9d3cc663cfc72b6f1672f1117a0e54da46c91e31db3faf0ce6929b2dc76fb5e992c18c4355463e2686a39f96a5ad89df9a096f9862ae561341f8d1b15beeb3e5d1306024d408fba13b1a7154682dfd7e2617d3cd352b0769045d3df2e4ec5d772c02ccd98ea83b5ee169f2185dc4de3523db47d5d44fa96cdf9cc8bacacdbc432a1fb065266324477cd6c2a61daed1d4d3591ba88d63dc11ec07e0b8157fc93d4a03aa71116ccda0281244cd5552936bcbaa45aaf16da65f6464de12663ca128cf78e46914bfdf357c0d4d33f2bbef967363c69b7e95d723ba0eceb38286d8a1fab0fa8c54453cfaa33101fc19a9dc81976f8cd76097944cf88815ce1d4764b7c9ed58252b41382a2ef55f97b0f8ea14305c8bf7d54700865740bcbdf2e992014ea4659b11580ba0a6349146720b1099429175ce6ddcf728cd1361a405e58a9b1e4bd34afe3a54db6fb205899d525b24a93aee852570b416114164b05d44714457894ba6c3fbec10ccd1e1185cdc5bf639c3ae7709af57dcd947cf7721d6eee3efb5a95429110a25655f5c2eb997548cca39c4ffbec1cf921e6d6f813ba49718233c113e03205de3f8dc5317557f5cc72364f5c7488aeb0ca411ae3384001b4611f9fd0102436899d573048b169770badecdea71a2303590db4145af027e077d132497af7b8748ac7f9a4160c4fddbfc97dc3760a14c31fa44a3d537b27073a5c542897f2e74d230e3419b21ec0c16386e7c1e7b71996c0afe4843303d31bf67073a4b72a3287ab46c1888ba4a6327467b2da9a4bc02c03d47ac1006b99e15b01658df5cb0313fadc9d6c96a60cb8879d25b44a13fd9245d348ed20ae8e981657f7314f9a21dc7acecfecea63525aa37b86b40ddb5cdda5a7754917c10785fcab5bc1b792ce75533f1b521b9c4106c6b1a2c3190f9308615d33b10c7bc2843cd21c069d0d9b23e68d37ea5cc607b025dd235ac21824f2637fea87367b954fbb76a7a63eda055116b70ed279304e846da0d58a08d6d03764d4354ee3b4610433e6051bd27147c004841814b866c3a6ad0bdf2e8115483f329d4da411398343bd0e9d31d847b1e857501de40526cb8eb5338b62984e1917a464470f2643f0403911e58876b1377833af5757df83c895b197e0124a231b914bf268e0ec61e03030cfa1253c371b7dda36eccc4f62a9b2ae759ef62dc78924426e61ad01ede640075c43c826a234607a64b4b9794ad4b432455f24f775f382ae60a89613088a4f4db4e4ae10e8129a1981b04575e9163a76d3f44b3c3cc67f4cba3e4db8d004443d3c8e88f478ef05b313d20f86c8d0ddce8a1d86c7e6b00854c9b3fe16d2edeaab95d5adc47afe0a0a7e6d58f6d3cf851bdaa8d411e5ced8ac574a8fe95384f550544b86a0c1259ff456fb63d56836d85f2738259035dfb0738413bb46a888283d8117ab32e84ab437a81ba8ab75dc9a3e2430ef7a7ddb98cb9b639d34403c90896da7c92abd173199799160566bd84acc4603f1626bca8c971758f7d02f1ac8878eda34a4366cebd11924820ca23a2d14338009b2140fd19f416b9bcc8b308061551e993651ee90819917f7fc98ba4f9a1218402255322406a32f156d53d5270d868542e52bfb1dad29ff750b1e9a911a5719e58c85510ac42d270159fbd5f425738975ad8a62c88c3a62cddacf32970b6eb19d6345c8c1f2161d2e49e779de3ae7db2878faca9c19688a2b4ed1a1ddec6f3793c08cc3f6d77e9369e140f5b4581136b3a5104e3b8d9fd38a7007c70a92998fa55ed00229c28b7024e556cb0a6bc51b8695a4329c3bb2d59752cfc341e2becaa09d1f91b94b784b340d419e4cb893030a763a24e009629c809c2d89621c2bbf760cb41e027924e4a97dbe68137262d824cb2f8c27d040f1df0f8b9572ce19c97453be39285b0411159429ce92466a3b9a1bb32e6de0b1ae4f0eefc0c75809dc3be818b345a18a1fc03b88de32a715ce57290aadc00a4fdf7b20a1282e2c403003a7bd01720cf4473014a1aa108497385a4d722a302314d17f7fad05c7cee17168d8b3571910a6182c9a0fd80cfd5f4579e518b0661053a2cc5b53892f844e343fcf19b99978005d6cd3e002987e34163610b5e22fa462e23f235f9d7050e030933a44fceac299a59fc32a48211bc91467b77f1037f83982a1ef42ae0048007a68340ff34c320d8ed89574d33e348557808a5f229eb2b71ad6033491eee35b764966353f039fb434cc6ef3072fa6f5921678656ad83ce4dce0c291512c6be0aa445263aecd781d89ac8f970b3ff0d78967c41f7a9c39c42068248488ce5111bc3d920e3da435f44066c06c917b7e862e596429d12ea28950074ecd2804102b81adb8b4ec2b931d1c4d1808236f21b6b16918f80ec4bd386b5497ce495fd447870b684c5835ac93af3a7cf5bb4f2346e9162670448fca58658d7d80c159f70d73b0c139fa619bc9ed38a194f012f30a554520c335730de9a415ada6d350c5bee050d560431e33a84b9098236e9054112637ea4ae08b229aeab55a19fb3ff8e207123c80a71e7a6f7e699c45181c1e203ff77c7b7b57e344c748d0ad33e9dcd7c1743e40fe867e252bee286def1756df3e12e26aee29a1d6740c009ea99c3709f00587f401e67425162da57b2e2b2f7a8864c7f29913192301226a6febc7a8ffa223f8aa150b233f4fd4fcaf451f965014a5421feba92128395606106532910d3d1db729aa57175b2339aef5466dfc618e1f24c23da38e713380ea4c4080c2d97bfb8aba8fae1684df51544d78c87031e604aa8bc87fd45793e7695a8d318014b278c6fd5156609601f64415cd2b820ed79340eae54d535b4231073e616e116380d185281f3c3466151a51b450360965ad8638beefbce41913bb2a89e91738179cf3295379933a73c19b2f99e4e806236481bb69ab1579d5374a12186b627b4ac60b9b21fc542af84c4bbee7f4bd011637c2acf39a46841f0bf35265f64552cb132d21ba302f2a3057c8fef1233dc189282f309c7bd2f8fde49b53171796b9c5e817ad278d3603dec388ea8b56a5deb466eab7057c9615244032986f10c53a224d23bd7b721fe857eabda0e817fe48ff6390e5e341175cc8d959f93ecd3063f42689c89efe88cc2d1a4603426839b201fdaa107392f8082e87f7ef9a37a333983cd7be9c0212727e32e12bd130f395a92482f096fb1317b5dd31c0ac54416c5e9f3fbab617d0ccfdf24f225f206c153ed393f9f6887f518e7eba40e3f48b33748f0b0816f5535655aea989bdc722d3466525ac88b8812207ec99f68cb42becfd9372b67c176390a8dde026d2f7a7224ae995e546a3651453e2e0ba2e2aaa8d515fe5d9ff33d2497ea46e85c0f954ec459b050870c6e6f9055913232227e78951ce650204c1b8d5984e2521e6e8a79b120a980b535717beceb15fe20306c5e6aae09515aaa5870bd424811a0e7b87d33e95c23706f212be8b1e0dfa37d1bcf0297a09458e2e0408cc5db3829cd6a61b8737f1b47b900e7dc1f349bf63eea12cbd177c50a793abdf0081660b26275c484399e27884e7b8e464c26772f146f9893084520cf332a936d143aedce43577a8532237f295d424a62371aeb1f59abffc012927519cb7a30d132d62f30a178b6e7b41521d62fc0643f8535955d012e7739babd2f5ae9f089b8e38a5c0649c322d5e117865750f36a379820a3a18cfe122b3ff6d9eaa81311f03ec6ceb6efdf46c86324d965e8a50e18bb30e2ef5c84306c1a30cb1ddc3240604b5802c1b996584d0f266c03e1644aa3c6e78938d992bc1f5884e45b488bf93499cd8162db4d68709425858098210edf79ff8d11f958233c18d2ebaeb42da525683965cd3c48e8a3f80b0146466dc581df6c1b6b8a48f68836f04725bdc4e3d67620c72a5c3920007d712b94684b91362668e99a74e7321c457d5c94f6f040f0f111d7a6de974d52e3fac392d34bbae9306f29ac382916ecf1dcca171e33bf9e06bb58d6a57013cfb47bbe9f05e3121f0612479e980049cef865e0ce5c93f1d969f57a6c372781d4fb7eb93264f1a8c1ffc9b408530ee9e06b898c463d043ba8cef57c950e16346149b33614a5e664cc444d5ddb80cadbf5f392d3692fa923ac3b328ac7842823a2349e6bc43a965dfe9820cd3896e9c5a777231a8cb0f15cc90d84e7885ba34214a36a941eed34122bb5a9ce8e08084eec99630839a9359d72b757cc807d0f143918df14d1aad1eabe5d46c3a10746bced1a35c89e8edde5164fa2269876e307deaf00f4c264a6f2aef99fd034601b242f47b1654689e0265bcb406343b1830cae34a5b0a6846e1b2bc142eacf82c10edd12d176158eab6d1ffabea19fec10652f0747ac676d63966d69c22245684ad1a5e92d24c149cd8eb4c1e65cb54c012453be4a806bb49c82e4128d08083631a7b5df70548a9c5b5c3e52136ac2a8297ba2a5ec0f0bbe19d00c5da1c047306850bba85504a603f2047f788b8533be99c8375e86fe298e6f60aa24808f48228c5da161d95b0f6924b9d5f21272f6f9b9e236a8ad5fe7a0e34d30e3b93d81f4054b64077af1603b8655b20ab5d2b7c90ba2d7d8cfa4265cb4c4748cf5341b403d3c452b68b10cae3bde8b97ab9a6e46ffeba6362048ac7373f45cf024c5d015d62d71ccab6eef06946819590da2b49be5e22265300c0c41e28cd078bb05be4350ddd128d2028f21c3832c624680f547d980690ed45535d6260a227a33c896cb30cb2b9e986abaa301551ad570ee1ce51259deaa12a5a1454b1bcb638b6c9b14e527aca7938c123281d2b35eeb81fba70f778656230ab203d7f420a54d99af848be2a37f4305a70d16183749e1bdd5fc03117ae51d6aa90c2cdb93338430106e07dc5026eedf7e48b8cd500774ec3df090d4cb5ea29d9197f3ab3570673592ebd13e8c8b94b64519806502c778f4f08d9960c137d9023b80ca3191e52e7a9c10cf8a76a1241d4f1dcca1779a7d98a8095723c06a202dc663551f3d1250385718f8c06d818267e979bbcbd7086672c081840a3ce6d0e0ea5fe0bb64ff36df2a966324ddfbef9fa817cb08981ae47071893ef6254bf5291bc9771322b52924b92f49bf09d72fa8b36c53f0fca7690dd41b281cca1801e8e2e2b7290a3435de797266a4bc223722c6a64ef16c1250d43e3d5cc5cd037792f41248888073e5ade7a6266f446deb336426cb22ea57a9d6e61ca1b3d0f377d65a023afd9fe4d446e3366c26ca2cec1e429183e43263d94c70cee9a57ef0579c427a6a6a5c1572c909d389468cf52b5863809d6bbd91a4f035bc70850df3313e8bf5a603117e79a91dc84bc281f2707575c33242073b2927082da9483687705d2256467917a23c3d108119f7d91c1d05ce34aac3d56b44c2191ab1d2974c541002cab8b95d5e300a4adb1c25930cb5a8f45028bc49d35cff99f7cbcd5f96509d551d3557c5b3ecba88aa2635e6bfaebb4e8a8a07c33a081ba140ad544a562eaea1b8d4adf71e545b1bfb0b714c60ae08d40942ff6eed0e35b32666bb6bbb7b4b29a594016a066f056f0543189de19386e8ead3c3fff061bf8a56c6d1307c335dc574e53dfc325d79b729990ee5173ac2f0b612f9f9aa8f0a1541413e6a06401a6058b431ce018257e4e7cecec9314e5575d1c6374aabe8e1f8ab7efd5a92bfd6ca5f75cc5f77ee5fa19baee16f186a71895a8c1b519cae61b882e905547410ecdfcf2a7a7e8b91ecce822572c80109461235094c86041104a949052d3056228f0eae69210b9730bd2845e82a100441106cb23536e9e260052a6a3883979e4caebdf7c661eb28292f66ccd7de7b1b95e2de7b6f5063ade08185836b87c40e22bcec29d8cf2a86234ba640e001301a07bb0b8d76a00e5fb6f0a0848519b69c5c89d2aad2e1684a14256e3077db460a04410c46295412451d3246edc2700cb2830fc66b129b4a10044150d44bf0d092e58b1a1b92b8a25b4f1e378a680d8182e2a4c7bca05bccb01b2b38014eed25bac80802791a6f1293687be42e47d9ec86979a357785a7252e748559b2821110566c0fbd215aa03202ad294234150ec2b6441719b1016c00810540f60d5c610fd7ed8a20f3c055f6c84a19abc65f4a4c7df9011b311698346350a821882c4750804a91a72b4b8c41f2d35e6edc68311fe6100029646ed60bdc7b6fdd13ad52bc223366479223627ed0ad67c7c15cd2f797db0a1a20309cf0054c939e8a592670dc3f2b4e46a55985fb403d85a5012b214a538668ca9143cc2e1413e57644126874984a81cc152474181e3b9e5e31fc9cb842ac03c7b2be352f500d972c141af3b803611886be8cb3a2b62f35e48d1e6aa91a92d7103c3a1177e1de6405458cd0a1b2467bc770ace4bd63d848eb1d0892e3de7b37f98d239326d04cdf5c361a282e78391364aa0a1407dce064cd0790ae108143b7b518f9fad660f6de3bd4927b2199853528a20826241e8630610709206559eab243882630543aa8bf38914d78390cc3102be36c18cb380da87d7a8ad62d0c6378ca1e9172c145a28cedbdb7a82b22872952be5f5593dd0b57447046091f5d6bb4175549990f04d10312321811c4088f2c245a58424735e51f1ab780a129f37863ecca0a1dc44f4f9a6bdc2f942709643e1046045c4b3878baf55c9365c81516988460044a1dd45dee14a62934cd85eba62ce28bc7de69067492f96e17242c6411522a7b81f2cadabd7a4ca054ce342f0cc330fc91f1b6f5f61e633a4030bcc0c80f9a2cf2d4a2c88e6f323d8492cfa400c32ec9499424312756e04109263fa2a67a3aed3322a5b7c872de911b06f245d513d528ddbc46496b659c1597c2292e1e6a31797b8349a20ead163ab87a612d4b8f4fe78f9771560cc3f1856b43f0826ec21425291c61492310a58b34a2c95a64e6618b872e9e264b0cd31cc1554e2da100ca6f64525382c8096160c861f505073321d071a647970a4f6b90f8788cbe1f39da675b484929b5c0f31185458d0f49425f18ae1ba133459272f0c014d1a2b5ecbd411004b5440d822008a2e1524568d93d7cda46019bf4302cc3100435d20c41a47004192351c618d9b223a74c00099613902053266ba7d35972786ae51d035243c8430e3315961c5a38a20b07943544ca1d8a04f85872c488334754dda0b104e90da9d25a86588120d78f2c345a53ca4c71f2a1e8052c2c44a6f8807503920f48121dd45047f4e6e2a14046f9e55ad32b8f4f3a66957298a4a7dc78d2044a0b2c7ce006176658424306c7cf8abe627b54f84b98499fce09403aa686c03790e0de6b07a972160382ff546c19d9610744105844e8d613cb6f07de1019a8bab8a0add478992656001b9a4ee01f4f4f509bc9123aaed2d512b59a5f0a637c6052050a1325616e41bf291f63968af448a3ab80b0bdf7de184a5794230e468c9505788259c022f8856118e223252f26666259fa8aa755d830b30503913057698a82d860e30a88941417315b5c1842f78eec64f1b8554ce3b88414a882110882208879380c4b1fc8b0078fe98bd20850b8a2001dac54f8712de1a307ad4160058220a885276a1004d1685e19be94c6d88ed9dedbcc4be0271528e1c3c80f205e70d848a2a1ecb80cb1e28509979f09da862a4accc090b42d52bebc4cd37af1d8bd337ab6f7de31bcc300972e5e64f8d2c5c9d63ee28424a682a870c4a56b70a19c0a9f5400731ef7d641b6d8c194551582577eec10e2c8de7bb310415529ee0c720982044791a1965f20088220086a208496a8a77a0451c18732589c10918608a95711131aba44216395c40b5134153461cfd44936031b4c369a4a281b494c9005961c430241264926b013bb140bc3300c4391dc1f0fc3e6636f7b5137bf446d37d3dbedc5ec610fe3e68f6ecc1ef6376e3ef6457d085f73c5edc5ec691f6396decc9fbdd5d1d25b19e326bd99b38f21fb595a43098cd9f3af417bd9c7e07ff337698dd9f35b99de5ec8bef630645f4b8994944f94c2e05ffb5a4a347bfe453a6bba38a2a5444a60d07ef6444a56a7d937c0ea6a9430fb595a420dfeb5a7a536e36aa9c518844f7b400eb459fa198771b6fa61c948274b9962b06b6a70fff53230d0838f571a3a68f501614c2d5685d0b8220a02f8fb43f41a61d5ee74081b75fbab4f8977103a3dd4ba2c6bb5f3d4d1419283c5f197f6df5e70830f3fcff05967f8f430dd00abf933b0d1c1ef87bf5a2827a4d7c51e84f051a758fa01c6e5c7b2fbabed1ac3bfbbad3b8ef789704ec7e8084969095f214d449e923c19c34b63847bef15bb08a632b09a878af0d5764901119558cd6106f7febd415835d153cdb8fce4cbc7c5101cf742bc87c836e75cb6e6ded74675fd1f6020fdf76f2fcc877d0cf361690cd807655c7ef1d7f15de41cecf393af5b49ae36eb5596af1f01e77276d7e828ff4dba4a4c42663dff25b2cb5f92af19f943c8266a75b0d7eb757b7dec958a503ef9b02fd211613597280cf361a999bed55da48ccbbf7233bd4618838c4b477885e003a7f14a6758ae9eff078ae70fcab9e7437944575bd5cfbe065dc0467dce61ca6f7e61b008143dd4654d67475551a000f1fd9d19e3f2aafacc1e06ff21ecd3f7d36ebe4857ab3ded61d49ef6e0d35222253729d1cdd7be4847cad01bf8e717e966e80d4c6f2f666ff330666ff3e0dba4444ac01486eccf9408e7654f74f3b30d3090f8f957b183e0cd7fcee13cf836f4b4416dc69919971f4cd7193e5d4437a87571f1570bc542446fe07fc6e52fd2dda037301501c6cde388d000ab3b332e3f0662df00abb3799c9488e826b51957a40b21e7f2ed7abed59de967dc7eabc3f97c93de5ce0fc2d9636c0ea70529b715777f3b7185777f3577793fae86c529b8b7436e3322e96bad89fcd94a7af743dfb88ae337c5a60a01d8a35d4ea64a8d5658081c49ebfc50662bf66087e888a3dcff051800d9231489c786a336e27bf8a4c1c6691637fcd5e9491bfaadd661cf936a89b335486dacc519b7131d466b20481560d8265edfc1d143e3f412a3200b50833cb27ad09fe45cb74f52167f8a062a8b16a49acc904fdfc0405815b3f287c7c2ef033e3e76eeddcabb377768af6bd3440c57efd51d16f0f67a12c1488310c5bbe306db9b2ebd9cbaee72fc9d85ebf636b73e4dbd102b5c057f1f3ab28c8cf7fbe4ad3444b7e57b1e7be8383bfeadb8bf15f0f8131b519f74a6f1602e0df6cea82fcd75b5d16332eff0b1d519e27dca61f6035ff4f12b75a46073f3fbf804f07c13e8dad5aab05625d45ec4b9d739b7fc4d22d8a73c705c6597bf3ab68f32bef64edc9dbe33c794b31758155fc26a238ff272489fff51ae7b8b5391312fcca4ffc7a926fff046a2d4e02d45a9c09d45a1cbec2bfece30add1576a9db9c048f9fc6083867e2f1bbc040af9f79808164287227cc1426416a310ef6e69316c57913288ed729b94f92b7c4419770fe44d7a27e9a2b3070d7749ddb75d25b0bdb759e85ed3aa9ce17757b4357dd6f3ae86a1fe7495c5ed496f343b8a8df50fccb4169ec6e4bb38fdb83f343f94435565f6fcd1538784693fd4dba8a36e9ca6b696971e1c76ab10f9f866aab863f43ad55c397a1d6f218baa230add4bad3572b25551b8bf8a040a1aa3e3ebb68e3fbcb6279f2a7fd1ad4ad6cf6365d6980249659fc37984539566fb05403dc611be09c8e110c0e70ee28ef9c749c3b227b5352be74fc3330d0ed38cc93a78e9f06069a75fc2360203b450354c74f748f70eeeaf0c32e900de3a4d7f1b7c0403a878e9fbc34d4ea66a8d5d150fb3334841e7bd29ab0bf682c85a10f20c3df45b73f9403f9b9b53d617e32e685671ba222dcbed6785f6b442c7807d39ae5d127d6c138fd361f5fad0f0556efb7c8392b9a1a800e80e2f7f5e7232ba92f18f85834a5cda956b440e1076ace89f9832bb4737bb4d9cdbeaaa2b65739575a1cf8fa77c0d7e0af36e0af1cfcb58210edb100b0ea002c4ebfd66fd3b550d7fa02cc81e5d16f01317c0656f5ebff31bab219c3ee0f616d55f04354b42a985acb03be88bb969024a4ddc1e88a42147316dfe2551c57e4c0b7adeafbf78cb4f397fd7e0e722ee7f7cb981102069afd7e1a1848f6fb67a80ffa93837ec6ad3382b05a7b6b3240c46aed6f68e75ad46d1e9b2b6c9ebc369bed59d86efba23e43d7efb3e7e82aa3f3bf4157dd6ffe44d7dbcfb7a1b3f24471de9afc87f00ca5fd8916758e43fb1b74c5bf4efba16c836aaccebe86f2d4627596835a1dff187f187fb37ccb9ffc6bae90a5228ace533086c24cb44c575deeb4bc4636781f21ed0e693fc06a06f7d3d32502e22b64c60757c8de6248f6aec0adb518e6ab327dbd47492c6c016cf0f5eeae80ec962c5e80721f7f28e3f29973aea281d521df902edf5d007cf0117ea4f01b0256a71b8cf15d94ef748311b35da739f348112d18292544c8c0030797138a9254999272640a4b9518194c2b942122041a2a231a48c3820fa91ea42875a919f783d58cd5dce3916cab2c841c42cedd2616975f4aaf62d4f3ddd273be523dc0f4ee2c0f0fbe5e21fa5bec219b651d1489ba32bdffee706efc5928290ca42d971cbcf55e652323777764366dd16243dea245a9af972a8368074e4f6807313ca11dc4900468fd1130d0aaf6bcfed0c040da4a87be969d4cacdfbb46eb67a1bbfe09c2b9dbcb7fad1002b278b13db623200b98dcf56b9bc3af635d254714e9eac6fc04ab99e8f23006f9c75ff998d6783dfef5ee5ebcd21b07d0bd1e7f89728c417e123d332eff8d22ddf844386a9030fe017445baf18732794d0d9c4818dfe99572a006fe1274d67431a6445717c5736e02a72d463e6c31418909ba6ce2aa4c921041b48c54d1e5d8d60b647a5cbaec78d2e5bfbc9cb3523d8c682284168edf0dbafc9f73f8653bee16c5f4c4322b6211e35e663448db8b616b099b5b1efdb12c5cdc32dbb3f9565cb73874fdab4fd7415ac8e6b4c5dd2b5dc474bda34318a64e35c617fffee6401c47510c6d587db151be272247463f2b2a3ca6a52d2da9a8244f484757bf1e15214c5c5b5452dd070599b597f0dfd48a5251499e34923ebafaf5a8642199896b8b4a6a9704276124ac2ba8de6dba42bab8aebdaba5eaf66357384e63b12bdca6a2b63c2a87e2fafe60d5e23a0a0ec5578ddfe254679d7586f95cd0661c6efcbae3544acc0ab74f62abf54d57229d73865d27527cf2354abe88ae3b5d7c91fffaa29871a2b54216b83df9d7db45317685cb52f1495d8a18c892312b5c7cf25e5c62f1498b6fce7a779dae44dd5a1e51e4c223aaf31e3e8933ce62f843b845ce8916b8423bb727f3743dbbe833531f59a23c7fe63b1763d85a42e7e90ccb130256f3ab39c3d2f534559d66dc6d52bc24d3b5ecfaad087744b3ca9b0278079f7750a73676419f4db15fc3bafe3577fb359ce319a785cadba351dc6d9ed269980a083bd79f5f7f50ce8529bf3dfac3cc7f4a4e00dba3df72cb85bafe1528c8f2e8c7c08a879f79ce05fde83f4ffed36fbfa8b5eaaafb15bab6e7fe0dca7fda206b79eefe6c2e60a74ef7afc941f8444a6e4a5a138698eebfe96a817e3f7c6caeb8223ae3ec1cd5a0d4198766487b85eedbc75728bffdd1e6c4b79f5ea1fd680afd362766dc057aac6a8bbb2a56f5c72ccf7d9c05ca56bde94a6377f06fb72a06c25debbeaa5ddf05807f43405eb3a6879fb7bd3d2188dadbb3df6a00824fd28b22e73a3a19d834365fd19577f285ec610f01feb1bf321997f1db0bdac33e86cdc79ecc6589de6e2f680f0b60288e2fb23461312e9bd16a363738a72de7a6634282138fa613ec505081052aee020000a0bc00f76477238407542abc1e6c53f65b00d533abceac0aa27c599aaeafefa7e0525da91f0d3c22eecebdbf222e4c70afeeefa7026f85fbebfbd39b75b17e37a0a077eb6a150182bf5d97cb8c9a13cd097c848dccfcbab0511292cf260523e125ac6466ca4644a9efd711c274028199883499b1020437257932b33b79787ab2f3d9a8e01da68279669cce1f30afefc7c150b86706c809b8d7f7dfe028ec33938367cbb1df864aca779ad95fb3aab2d9e2d9d84fbbfaf96c47fb675958fc8a770681d5f7cbb6b47c31ece7b80b73cda678b62afb6347465e4e218cfa7e5812928f05a4bedf5c52e25692f6974298684c6c20d2540b625bd2d4f7bf923cf11862fff864b78309b620bbbe5fa4c22b8b387de0f5fd2154cfc41ad2ebfbc1285f8dca86c3d7f76f2a292ce7d67e6d5505c5e6a3aaef7c957f659c4e2532cec2025226df9ccbf0b075206be5aecc55c604247c9d315d9cf50643717c91a5098b71d98c56b3b9c1396d39371d13129c78d4921694afb7c05ca15f446742508bd51d0a28303538328211c1d3d2464948b3335cfb2758529a9db1a2d4f7a742985e38f8ce1130f5fd2891a6170e365e53dfff499e64596c4e9e2ab040bd45d914f9f76b34e7468573395818e7c50ae59cb13dfbf7dfc0d8143921b03cfbb78faafe9fe72daa6f333fd9c5a2f0b0767d3fa6c2cb4fce1f0faa072ef19de9f5fd37ca072eb13df9fa7e4bfe092a29990ba711527dbf045655562c9c6b7455df6f425fe99f158f9dced2585626a880d5f7dfb6b442247a5a7d7f8eeed25c5c8d6d4973f5fdb62323b3cca966ff99843452d99890fa7e9c252572cb69a5d4f7df086102af3831f5fd36449a489e2d85a6bebf96e4693be19d4b3cf5fdb4273b1f0dbbbe7f46853722e1d994787dbf0caae73b77d8cfa37ce40b3df6c7a8a44c1f3c23a9be1f6655e543aaeafbcdab9fe6619be1d7f797595862b75b74c071a6c1eafbc92dad12099e8d8756dfffda5d9bcb7726b17f3c32e26a783f8cfa7e318a834958dd0f226175bfad0852df1f9266945050eafb4173cac7240353dfbfcd295e130c4d7dbff6f294e4a9efcf62baea20f9baded974ecc29ed39c9fe5d93f846d5df8aa63d4b78e11cef9c0748c62a4c0c96eb790a9a1ebcf688c14f8ee760b195ed7e99a4305e465dcfeb3070ef2fafe1c5e0e159cd3ba1ca8bed71c5ecfb1caa9a5ed664f66bb59120cf4fafdb3a7199119138d97735ab77b7d7f074e4f30d07a3b707a32f345f54d6575d56759b3ad59d75152df4b7dbf5d6942faa611e99b96a4ef19afef07d3581556f7c37eb02b9c83fd5e61bfbe1f86ce8460dccee98c09abfb6362f89af3033ffc75c6d4f79368ce0fe7b8119291916e15fb9af37ba15ab43c423fbe823d193a4af70c12a40736c5fbe0e3cdf1117d1f3c7711f4fbe0637f0e3cb029f4db97f1814d115ad04cb71f012ba46f4f7efba815715c002b01d42a5bbacdf5fc6479f25bfb15b040f788c5e60a8c8f8ae017e907095f6defde7bcf9cab313ef9f8f5e290e5c97f4d18e393298c575a028e02846e4c95ec74047d856ad89efc794dcfda6ae57c585551a74496e789c7087e93fc2ce1f9af5116c590856bcff165aa7e126c6e4c39b8272745135e3c47d7a9bdb8f5bc1db05dbabe226471fa49b038fd1d90ca6142d74f9ee8719bbeda2e0cdc7e6b58d53d28f0730058f86aab886c8adbb73559e05d5a736ff02fbaca58712f4a63770fae50064409580eae10f8fa29603370eed0f5776053ecd755f6878e25675384290656084cf9edd15f643960556dc3e2f408b7476b1d7d03f809f440060758ddbfdaaa206e7bb36b312cfc2d8677b77148b5c58683539bf56e7ef6341aed3ccff38b3a0e4e0dbdb9f913e706b599fd8d4d9a6db83db3afa12baeeab31fca34546395bf3557d87c6a78dfb04fc62e8bdcadbd1b639243f19cae258bddf5b518b616751d8b8de1f6495d5ef3ee2d8e24f4fc2437bec5a503a0f8888a4fee72a3bae7f0d7dc039230a8742cd8f5380d2ae5cc0c0000000103170000180c088582e1a0781ce5380ee40714800b5ca038604c208b0463a1600c08830201188402180081008601208e81000c63a9cac5071effcab56a5f71569aab549c4e260fb072adda57392bed6a79955ba1ae9e56d715d16abc82baf2afba566cabce6a6ba55ccdad5257a6d5e58ab012ad4259f95777396106a67d25bf0259fd7a657738e23dcf025b08a564bdc823bf36e0c1cde50c961e000fd7e9dc79518de94b8da08bbac7838a7a94b8fb745ea87f0a6c3a97625eb1f802b4e0240c27af54b846fa84cf7a5e1c2af2685c0912d5d27991879d028c13b8c5771179b94fd03599223d933e5ff4ce91c5c00dd2ac83fbffccf309b6c8141d29d81ba92d77a9efbfd00c8eba03fddfc487b5bc2cfb4a24371b310f89e91c2079df079475c2594c8ddd68e30907304c3fb852b42d80d1203a3669a53f7b82461ea3759ac3aed706681e8281d3286ccfe3b0ad2fffdb8ff84eb3f9e0ff712f448a3082d9e855951dd49d5b08b0cbc6c798fd53a1a8fd1079f93c0941302c08f35e25792909564151a46a357dc8f99c9aa0d7360829e9a93ab222418e74238b16400e7d8ff9af45a38221190ccfb66f1a31a41ab467a7bc21e19d3f0c9709c6b034527ba04233eaeb9b8405ba90bae58e17bd1f8abc4f49b6a81f2a9b9999a69fb9b27b3deb5e3efe8aa2b9a13d6b59e557d02bf3d56555bc12afa057fd56ae55dbaab3d2ae2eaf722b94d569655d11ae8a57d057ffd56bc5b6da596dae14ab833f85a58dafcae5f459635fcdaf0e1456eefd7329dfa00c5dbbf71b38be69d39cabd09c1c4a4bf7929293fb60042353e321fa7c0f0dd336dc9a326ba9d24522588d4ca9da1b640886a81b2171ff310f25d2d25004834345951eb4f25e69f6ba255bde884dab15f7d020d785088fafe73ed00bc2ae66428206e5ffdaa0d3760819dc7b1ecdd174fa2c231ce97214cf8cc992a76c36280f36522e5cad108548980ca3dfa1c9794637a12d8e1c90a7d470d40afd03d0c1843ebe0900efa9edc34b03109cbdd96d60f68f4ae06deef3aec3789eda9e8721e072611924db7b0659a19fb92b0c2b2221afc39c41b7f8cd16064b83da0c5ebdacaf1d0ff30d48af8ed92916ffb2c367ba26123b3e61acddc8f5d42cbe78548767e68996feb537ad5df1381f1653f8ed8a48fcf5798b833c2627b1f8cb0e11ff48af1f7591b3e1542a5411175290086b1430beeeffc2c24e33b146161795537256319b4009beffa47cd40a3bdb805a18754ff1cd212ce1dcb3fab793373738e1bfd011cecf9541150b5389bf0b0b4391014ab43068ae7752a26a36ee4e1d7d49f7d266ce2da3f71fdfe6585539ae1013dd85bbe6e1651c215739e7ff80f59683f2af23d353ae33e8f22c1fd4d0390034d9bd42df2338c1bec9732c54b919b3fb70ae4e4b9cd76d0b41b434dfc788f5c008474e4f23832ed93508ef00f30aa0384926fd8eb090174ec04afd3c0ba85e7c29f7851af9c55586314d3647c1c19db1beb5a4ccf517af5322fa7b3706f633ea4af471f620af8a439c63ea460bdab3b7d6bf2eb98504865b8fad9bedd5d7c56ebbc7bf5bbcd4986350afbdeb59104baa3e769c2125e545a498796f4620d70a6c356c3611435f68010e5fb4f0589ab1d09b5a30463333e7bae4e4767d534f60e5cfb5b89245872eca4a16ddd70890463511f2b248adb3aa4eafd6426fb45456822b1cca90a85d86e312aca594c4e91d1ba4b6a693970a19e7acf39b59f4ffa8bff2cc6a011d8b0662a810d0a80e3f2331f60596e5971dfe3e3ef8f0a9870c08455daeec508682a0b93897accdbf477516e34e0103b55cc08ab5711a2d697860196a3d6eb0e4b6344520c1f26ab45c2a024bf9730e0cd17ff604188587114609155874ad00ac7f617d1dc86d4fca199b33500633fe1ff862969b5ea8459d933dccc2427f70852c77aadaa6b47859f6b681dc80fa43fc61f015e68c3063dce1394a83a3076212dfdfc2850be0c19d2bcde998050943e832b7690a7d383ac70d465afab8061aca7e52ec9555784ee651dca67b87698b3063aa6d90ebe21a4786878896d1fe26ced244315a6eaad699e81327da47a0cb9b9e946d8a27c7702224dfb72887a3908ad705335d422a48aa7dcc3edacf418d2c7364072ee796b1c8ed8e0f436f1a8b0b120d70e0d6c8bf65d1855e52914973811cddb6d394d81fac4214defcfceab2c46949926283875b8a4fad8d1a701b3c92db0959e6dc503f36ef7fe0d3e22af5041acd45c19a01e6cf707105d60d050992d7e11105e1367e029ab6e939db4b4739bed56a537afb937e48914d12e74d12f573891500d6ab0088a943d1a371d5de0de042330925d68f6389a0795f9f19f40c814f58666de58d8f788c79c63fd5854fa0e34f7ffbd5a3b860865254262a184c1faea0c0d5b1d08e032b3736ba6642888f86c08e1a62b20914dfc976b61a8935d0175cb3a282675089937dbe92b27a97e55e635582ba9d13e08c5c310d4b34cfc9c1919c292d5f34ad0047ee221c7b0d1fb280e383c90224165213088e47d9c89edad370fe676faae88d3c6c27cc9cec61b3a26df0282dc60344119704df52c015a7e350d666d3dbcc860d96c77abc9e4c98657f92ed53eecc6b5b3ef582c809e1cc7b21ca6a10ed239dbcb334c1c4582681ea5932cc4b88490c02722e6e9415daca71ad6933b209838865801e6d5a95f22ac15098b09ebcee5dd5e9a6693a2864e207371fe6fb606ecad1942f24f53dea01761542c38aa8c392ea4d677a82a672134c720503d10288eab9fa4bfbe5763d3c66e175e04592d6c6a6151198a82f927e0e74a00e81724390219a2bbab8b12cac780a553c32b01880cc60b31f813c40e4bd027377c5234e834c265763e4a55d82c1dc7b48b9340a2db316be98d1e4be30f20d35cd0d2887a3e5ab7add8f9502b0c42ed9ef863ccdfc136c676c176e6847019aca5d2058701067241a15432398cf32e5412ecbac90211dba53ba1dfde52c403cceee1d3c06ec6182351e58226e113384276033f45843a79fab2672a9de09cf9f5b36c59d72a101858a2b9f61c3932f20a5b08c7355d67ef95fb9f2e40ae808096454f2935c010d00c4238ed766ec6f856492586f7ecefc7b9b36cd5f92ade17a6df4f71dec4b09427862168f1a3d674c05b2873bb227300de60269c3abe06bcd3b1258e6387c94cb859fa58fcdb8ad80667bfc0fdf04c60f500fb16cdee5e7080f9babd46d72a5bc2f44d4c84d05e06b6585e9be34d36dbfcc1c85996b14eef8a101e24d70a405c954742e65088da8e7fa32b0faaa598bfa4930ceb0c1438ee048d748f85eb0f44cfb6a1a92576e3c9868dc5ab8222f106a7fd90ac015f6d1c023bd1c27c13bf4c10abb48bcd1d37d72a6f43637cd9ac5297a23d1ce919ca5ac91e43bf438ae5f372c46b8448d3aea85bc279e94060d31c163a7ce244bb6bf58ae713184a06e91993721da51743906257b513d38073790e56ac2f31883221db6727ab8e20fb5bd54a7889f258669b7b6100bd33839a67dc629023230dcb98952fdb1978c2358021e52dc6c8c2b4560c4652f547364c1b2cd7f76077c16442cdccc916b45903726888a48dd5be867bb7ab81f2bb67d19435fb2371636c184b6cfc2f86d89e7b3e7bde1ede64a7d4d9514f981d47a68595073794b722082a0d1c3d765ee3e44f13fb6bf843d47a7a02464378a6f618b571856e2565452ea00cc97bdeb24a024b693c77053e5f032f03c6e3714765696dba62799ec84ce8d64ef9ef2ae2708eaedf89a7a598b4485262c2a39f8c84dd5bd6cc2aa9362d1937e1c9c89bba1a611e17aa38b8051b5b9c4392422b5da4b7ffa97c86e3452e552c015d5c8d17fe98cb9cdfc90f1dd823d42a736d8d4c9b77478c1c7ba80b8f0a4ac5e2ad4d87c1805617bdd03500f0f371c3a1a7d2147996f3e46a284d4d4b5571ea9776ca2a299a644a84324f1ce8726c4ad9aaf92e6dd98427a018da8c3935f6ab897ad8ff477ec1c7997b4bb854a44bd72b3cd02d9ad741266f78c65bc4bf94f9a298c9e1476392e21ee5a567cae21183a37ff05409c7291f0fd7da9f8a13df72b8c23025801e1a56e084a5c2e88e2c1a2cbf6c835b45f3f348f90ba155d749e3d6e765b552cfbc65214427102a92942e564992e2eda50fe4e467a86b8e298df853e1a9068d83d416c1b0cb4e73885cc44de21cf7a468280f5275239bceb64f7139df23d90b8d1b9d8228a06ebe4628b8a7cc8287f7988940aa1b53ec7c84ccfa668d1c638221fe266bd3a42eda546edd018884922f3ebce884fe29e965e2217b804ec861d152b692fbad91bc42cf1ce8b99ce210de946e84ef47f27a09595450dae4cb26c92f5c91793bf9cd472b295c92d4dbe9cccf26457932e4d42970ed5bb0d56ae00fda9b8dd1546795983575ca76a878a1560e93a9664dc85fbd10619ab73b73735651793ad08d95a4c763d79892dfbd2a40b932d4d4e0265bf98e4e5e42356160b6a526e4d88700b78b9da62dddbe919e29c883b2a1ff8267339fd79eca76c539a4f78934e7851cca74f3e66c7375f9f132e4ec56bb3b6ef7f668d438a1f143e650932f0410e679e367c763d392d4262a660dae65d7e30e1e597b248ef9113b985a994c82e3fb247570b6c11d93f08c71eb2abf264fbe73e52dec0b38eb660e162611c534c604653919466316eb49c41011465bb9beccc8435750f98bd173aab5b25d8b5722e8f6a765db3befca0f95b1d46142dc364c9a3be9cef7e2a66188039348074e240db7848f99039c7c8d03a48c03013fe8a4e6d783a4a2843a5d30466bd0941b3ea2a988cca78bbab40670c6e371e1e21643ac704801ae82217e66b08e8a0a0c7cf5dc84fbe859e2e71ab282ba6e8d2ca7cdd57ed08fd4e12b11f6c3c8ebf21d1479a1cc634638568b7c58bd09631025e508607f5840732962e1617ec2cc23dd7979f1b5797f8714cd2635ed856db8a1d22fc09ed25bc5b1ac38d416f0e2555244c1e8218937f389384b8ac5b4ffdc184a8d92c6659d41e98c9eac56c1d0fcede5b463d93c866994c69ba9bf7c1a711e85ea1790080cd254487144a3c7a0ce2cc8025b9dabe2f02f591416c322be9766def6255ff6a47d1cb40a617fd72a2c3be7e828e6a9f3c831d97ff907d4edd3debd7078d68d045cc48c8fb7116af8bd7152637b6100e4ad94f94fa83984048343d8aae9c6c151f4341b5dd8c8dbe3f7fc2c4e7c3ed2979a2d3da995b3a3f5bf6476b2b9edeaf6f8f333b95cfc608da32323927cea54a773114fda12d35c8f20d4749a7ac22b91771a197752d9155442e011b68e6ef5b20c80c9f88490b8ce2d024427b23fb25150ea0e7ab2a44f9a14bde9901d013cc58cc5df95cf759a7bca9d323bf622684d06a395d058190ab4e9b5be130c8d2376324bd529b10d5fac876ca396315d43697e880551127516762e46bc95e126b36366ce04ef0d5843b9cdfac8bd70b9e5ed7077df4352184e783881a7bc55162997657d2cbfe84b2585c40436f92fd378d2441c7385c7d5e3eb5072475bda8342f40a03b61c5d0f3333b010f8b68c5a660f0e1b49237d4374f6c4a62e9bcde10623b161130c111f5e59f6548c558b46d08a73154542fc2453edfc2cb2f69a031ee6f18781e43bbec31136cda157665b96e1c308a47e1356c4dcf204f0ea6cdf1c418cebb6cf70e9247c9d37f973442becfa35ff7bb4a1239df961f30dfe3cf85c77d521cce6265d2e13e0b43f51d727555a8f0e261f3d59e21d8995bb94660b5332bbc3486a217d31cfb99ade345460db2aa31da86377f58ff393fc479afccfc12de46ce1ebcdd2a35946cd6f7d370f7437864a71b8a30963998268cb96a1470046d7c7f57c86196ff6c9e2e6b8f8ff11d3ee0b699cbb5b975fc250d81d091e131d5467689c49a7ec88b054f13876a17a04455922516b278ee1c8c4bc6540f73959a82a434732cc0db81647ff90caa2e88e522746bb6461014d5f19e84f3be84958b990e1ea51534ee1f85f289633f5ce168d02e21b0017c0f7463d0b65500c50f675c81445b6ccb0639e88ce5d493a5cdbe71621a2df6245838bb66162f88cf4304fbf4753496d0ecb8b93ca92f8e6e837a14104ac7da1f4e2c57008a79095431f416d2c6ff0a72c918ecd8a8031a2468367a68f19a8fea12752879561caa666a0537693a6618de8beac3f50fb4cd0e8872651f987da8808ddacaea2be8e3892ae03fa6c26927a0ca8907a132c85e828d8208f4f0131e04c42c78750874d6960ff17ede62dc4b9f36004508fbcccb74ea7cd2222aac57e4c015a5ca327ce70fccf1304af971f61e031d2ba6027235b5a5632e632564859800a92cbbacfc34eb438c6c7036c11eb7291efa085b24cec60e845b4c8314924937c95585c6042aeea441bb47b8027a307ea38b3e360d80dac1f7b1176f4b8eb5005621bbbc4c1e334e2fd8abaa86bf6ed8b75dd4cb4ebc14347ab5a8409a34af9035d2a30df2022681e18b7d40f00b409caaee596f9cac3f670843d8ff95cce18b27b984ea2daa457316de510312d65329e38af1203dc017d7fa0d0437d371b296d083f868d46ce160255bf3d22aa50155bb2575ecb4bee4dcb7b1b95a054c086ca504a4b54e12262094aecae4040be5416dc84431b74ed2cd33b5a0ce09736211ab58ba4d691c7b64447e704635a641c25ba777863c0aa7f2b29f4807ba1ed235adc2bd009e430ee89f2173579be6ea2948f83be25ae11ccbad03cdf601dae3ff39a64e45b5a07e506d77426a00118457e13d335bd929e9248f79f31de538efbae4f73b80b0c62636cab992d9a2c71f67f7dedbc74fc37e0a0cd68735833c1073324983e45bf921a69b084fd492f48b725d3a35a6489b6738a8238a6eb82f952275966a24cf21a8885323fd9ab998331a21ecfc8ae546f4c425d2fb287c5009b6d27ad8a9a31790a999d2e1e67594a4260e172e5d9b29b94976135cab32176ae1f6970af6eab04597bf24315fbf965584463aae7fffe022cb76eb15d91eb60852e6d2122a63514c5db1e41b2e21a9f3c4d5945268891d2c71eab9b5d4024cb19352be4de4e5d2953a44a4116a78a3ab31e3ee6cc6c1b57b6d41fbd3eb931ac98f6cd6cc8279ef750f1ed17b30e55a1c22d173735152a3227de2dfceba296a0023fbfae8151c8889c7745c81ed63582c67c36c6a485b425d501df531c30d12c4dec50371e708fe4da9a24dec0434e47f21d0ede83c94e3e3928e37dd425eef3072b9120108b5cf2ed8178052332f44e2baecd607412658e4053a5afdbcc712b113590d619b7afb2b9cb5ed4d4df6b8dc9c117e2f6456dba99ad14ae3d341493ea5ca22d52af9dc4aead3b90375c02fafd27fcef3ecd183abc88bbd647d441b4d7aa4cac99c4e0c0a27fedffa10e572302c3b51ebedbf7e9ad01e6e099489e7b2cd057f729a44a3848e785ba07880cd3088383e03a87bd51f908207820e5e52bfa03ae2fa2e5b3eb5003c263fe891f3a0f630def46c59431f55ea59f2aa9c0520fbbb31a68980d94b56258cec9e0970d772792083303fca1b86a6d2bfb133633006fccf702492ac410fdc01d26614ae339c3ae3fe01aa4482e3bf95c6bf312acb5b52e888d9e2446971ebb8ac95b4815b7712ebb890a123c011edf22cc9c0ce4a83f50182ffaefd2315ce66ab3771a0a28e5c446778e939eb57ddb8cac909a32194489979fe9f8adcf178d03ba6ae9b50626ff44e4fe9ea3e324e0877d923d5320135bf60538a12ec30fe477d00985b2ec13a3ccd15317ed42b26933ef6f05151b7dae06965770a393d785d6cbef665d89a5695803ea612b61c637d303e12158c7425cac5f01ecbc27b00e6ce9caea18b8b61d8c79189dc59c9d773e00a5ae5caba8f742d9ad321b5d83d286cd3995ed83d37e3f30c78d845dd80279fe9d91651472d4216f5a089d83a435b1267c6d23f23232f9a260bde4af562b95c7ac6b28289e21839b5b2d5e63b349df8b874add251286998cd4ac70ecbf0c8958e392aae16de9a44f2ac8dbf9c288ff5257da6e4113f048c33a0d69e4383ccfc38c9226c7f90b1ec4f1e527dec90f014cc46f239e0dece0f5dbbe78c6d7fb84ef49f7e3f4ab070ceb9395ecbde4893bda5100a39e4f322b907531a512e1d7792e38f90232388fef0a63594fa2275bf9f272bc544b16bff8095397c407b3ff0bd2765e11f093d9b0c4fe5d967120a3ffcc5f50b81b7ae2d80a875d6c33096b4fcf91050da44e14c074f383275333a908a54027bdd0fcf88a7a47f6e336dbb2616babbd67510008ca2b2fbd788300d455261de0515b84f97eca7b5b9c75dca0291a9f246e8f0f107e2c1f49f4d97611f09fb0cc8f2724f5d60fb92b2ab139ad202fdc37f53fdbc32ad392792ee441f46893263e903fa5ed7487c4c7feea090c4c5f22b24308a656fe8b954837579acfa13755e220171831e700f10d0593ecd7ab8deee06b6897882b81b62564440d38b2b199d78429a757b72042407510ebe6faf12a0c34109804e10b6092d5cacfbdb094831b7881f7c5bcc595055e753c04c9a32659eaf62076ab66e72f6e741a34bcc6ac465ff37f340e5801f57001d0cf7fbacd4e33b898636fb45f55c5eac110ce6f523ce98e2ba91477c8c112299621a03f7680ad5726b9dbbe0f695d09a5d0d53555635eea67efbb3ba62e81de0bc899f35273042e6ebcc111446192952be3ecc5f3a77312d2b2f502f929bebdba89c4d2ca5a7e0eed5c91686fbbe0f9cbf6b7822dba67e18925193563487bdf9d48cda5f7b867fd0d9e946c2c3b65d8c7f5ef74efb2d94434fdc8f5353a358a7a81b88e7ecf2cda143d30aca5939693f79589131cdb8c9a333e04b61b200658f96319e4a0edb904be861eda5eb5ab798d15e3de869c79b8658d2d3bb508cc9678ce88510c52719244fe27d3cd09bfb55ed033099a157757e67fd4eb38709c5570763c05b9601d165f73edf3a8a571a6a9ed9c0319602f4348f5bc7e7ff9f835b63e8f24e30f48ef387cbd32f19e128f75973b0abde544209f4761a150059d1a88fea7c7f8e5032b608f79576a423b8b550071ad0d4e85f4a97476ad917c448d42c399d138ffd04615ced25c8d4c0d137dc1f151318c5730fbdb4036f11edfcf0b69f86dc6861ecb8f1eda7e9e6988f82ada026269f82b10fbec52b6bfc8527695a9787267cfccab8b82498f2d6ba781a0ec47061f39faa320d281f29963d54c5d535ba5a3466622610b69afe88d0b05dc21774ac75d893ae0e4805aeb66e9a44a6a6204518d1b08db5c75ca733e76d4d9f0e8ab5ee19b8690dc983a43cb38d935611efcff99a8ac060e300496ac0a4caca743afe923e1fa553f25f20202a5556b6d42502b0bc03fa11eaaa9c14ba6d4a91413647cb3ba5e8aa0d5445893a8bc251704cb550dbafd5464a533873af6e640804f1484818b564ffd8b11df2378ac995bf5e810af366771c3625d1e3890fab8f39ac566ed3d3a118ed95c8955469457961aa7c3cc96a055c6ae63df4491a4b2f6ab0533c6eaa2ad031ff262f4e30b373150a219746dae2e4c0657cdbd5b323238eeaa7c8a16e3cdce3f368a922e0629a8fc4459930304310991f738bfcaa572e2fc9e04e50d80111272f126d8bd04601fc3af8cd8cdc5822d22b34375ca195430eb8581ed48a68a6dfe5d89c08c463dfa18ac3ea864a38eb388fb7eae77e4a8bbba631694862a165e018b486a7c4206aca6aea3458916174efbefcadfc3e48ed11406877659c632645879b0ea30d15c9754d08d3000f90d84788118a502fcaa540107b5cda2aa5474478231cd77a43156a07a07276ed0aa98261bd31863689c09cb30986afefcf98937536c6de1cc0ececec5cb3c8da1a5e9fec806b025dc8f992aec8bdb49c12ec48212d815f40e71179cb1347b37eca4c30fc6e70be3ad3541eb8733de7f58a05f1768e648cd7d4fe29e9164690eb1c0b254a626ef4928bb6ac7c12c0d1773fb80a25fdf526b9317ee0e5d04c278cc2cc34c4b20be1615b413f80c4d234a36b4aa937ea8161a7b0e5b0eaa891794705562c4dccdcb415c0eca596c522238aefe72019f6e0ea32bc42337e82a3c312ecb8e300985359d2358ee5a018460e76ab0415319189af6339548b160c8e8b788c2cc11ef1039afafec2a84a2600c7f54bcde86354ead1d7e235146355e528a218fba43e483febc1b146db345ebc086430cf3c20afbbb46ffb713f85ed468fd82508899768943497996b5f00e582a4cf1f0948f2bef99cd5f07ecaf1e19f1a33940040164e7ee6b1b815071c7393b788ee67568158815d1570ea3023af81230e7c657e342d408d12275d3e56b807cf28e3f435f288fa91ff24627f6d6562903e36373e16a2889bd9bae8a019d6698b71e3712908ab5e2335406ca5470090087ab49bd9368b7bc012a8c095d4f2d241c03a541266f85d670eda83d04eb67e844372a63fa9a5c70d43920cd2afe8ec906421b92934a6abf61b97e92d912914996b769dcc5196ae0bbb7c7acfc86073c05347e62f9a42bc43b3f14e625fabcb9851d08f54b25da14d0c789739a57970cfb250e03404b726259dccf340be31aa0d4afd5d8ea0d4cb6bf99a747b12994b099056d1c22ed13e019fa12b61a83b20a061ddde88885810ba3e0e88557094baad1b60856c19dc32361b685345e3799cebd3baf1669e9b3168282bdb3ce07a631df91cd3fbc1da4e6afe23de9b5a22276a563ea6891380f4afc423f32954e163c50b100245e190c8265dde3363a9c9d39ec7dc0ffd621f834043df020e7a2947093459ba77279d6408d4208e917e3751c1638dd28a317426db0c959918101f70ca6a564a8551a37ae4f5cd0a326b8cfa221e204ee408ad8825595fb53391af493fa218611f47bf72e6c98a864dcdff110945bc75c389c07d30282dac36bac27580daf3c8c53311ffbbbb196d29ead7bf09e2de4cc66acb913c1f0e28878f1c7bb204ca7124b0d9e18d88f910e568ef3791c660c2d24cd3852d63c8b23f25846c548eddf3357904f21e89ee0e245b58a5c226e3947ba1b077e00a9e0cc87db02c3b8b11652b18471702747a67954a207385603b5efe59f1e52eda8ca9298fbb9afda4717a56909134603a589c3fe6383f46391f89403b369298fdb62e401800687ba92cce3b9951efe81814ff6cef68489c65b04b1f212d2a4a6b74c64e6ce52e8c032378626bca92a8b480bf1c7465c0115c0958810a060e7409e070885a54768648855c232471291b0794e5c44512bc4573a9f19d4adf83766ea9eff42bc9bca4ffd394693c0ff0c01a9004cca525d9d15bebcb120e57182904424d7a6d878e03e7ec310e7cff3248738cf77d0431688e84c2a01667a38278a0e863cdf115b5732c80d4aa71877e2c10d664f4d5a4800acf386d24343d34f0b2864ac702525b0c1590601e6e337b3718a0ece9c784295b82e2542cd9083d326bf0cc9330cff08ac9886c446ff377f66a4d462bd6c7df031a0364d62cc4a907e8d31855fa3d47e1ecc8eb24b574c23e8af4d918a82603f8a03f526f9fe14e7885a50c5463231f5b899983ad69a392b4179b01d2065bebaaeacc442b9f1eb42c187ccb1e25400a9cb79437b4dd61386a88ed98255590ffe125c074d05e16c8e0ef14d40bdbc960da37f98e7d31a5bdd96a63b3ed47aac9f02e293376a88302a7112d1b99b15a1c24df82c650647c7d389c48baf87cc3157daa4c5230292d25ef90d7d9362765d33cbe8d8857f8e2f765440cbd46fb811d4345a1ef3e8dcb773699a669a9f0cb5299b835206a6a4c6706839bb28779bb4970cd1430d6d804e656fe8b38b689a4e126d9135453d98b4663a22144b4c766708b355e83e74c2971fe5a4232a4f8ab9a6558f6fd84546af1f98214b559268beed78c724dc94bd89b31550eaf821d27f6c0e54d41ab79921494713dc4780b22668c70608d697f162896544d4e8d7446aca8b4c8e0668a5dc254d7a96b0537a4af6993181f224c109fea99275182e6a909b8127d4c47aca903e60be85ab2d8692dd60542c984c3712563cfa35eb9bdc88498654c63c590d0243e5e753e0f7c84c871e6d207ecd11200aff32060841a5661b0912587e5c6c8e48b4bee3447e5673d0e99574b469610b8f2254db8dc206372a514084bd9027b2f2e47936faf51cb39cf7cc349e4602bc920e3fef341cbc06e41b0430c000cc60b2bba7ba3c65f5becf1cb0c68fb5df6c62f1e4270e2912b37f6b83dcd18d849fded60d063baad10c62ab8d8063b9338983959baaca0dc45942bf80f935739c69d8e108b001df08073f11b0809bfeb59ecbba6dcbe1ad75c2324a6331c15624572f753d958d449de08269309ccde968a10b000549cdb8e4c8a8fcaadbc0378fac7b06dc8a916c7f683465f22857b7122a55f8b651f9fe20b8afb9633e5a5bef63349bd2968d6a9d1edf7c79810c378b0e309ca5d2f75131ed75972759ac416d17a17fcee881300f2b4f725ccfa2b8d8f4d293e6c4763a925a7b944b27554accf7aaff3692f7d809d8b03fa20221b20f4d8d783449c250675e98d11946b1dfaf8023aa97e7fd94d20d91a337a739542450aeb236137c9535e2bac22967e3a0b998520be9f1a46e15cd0d26f1b3873877b320724bd8362b38bfd63ebf503d1d5d59b71f614f344abc602467819c5870ecd44e28d9bbf292b8a867508214c1529b4c24a23b18c5d77b559348007f8cd74df6d0cb257c02f818722deeb48b8261adfa9bc3131f984deee0c523d00e7a39ab4babcfe2f816dca7e5ab80bfed4da417fe063094ef0290629561750055b606752fe4208e48d7e74f76ad7e6d4ec61efe9eb47031ead3d2f6004ff636eb03b9ddba88082a919f488dc68829fc692c8d6fbc2c3eb1330cb704c0efda0580a281c054ce261952db7d47da1df0e20a1bc80c0b795c9c69d9181a28b509d455926768f7dd84fc81e54bc114976f76f07438af2cfcfb4bc9fd19a07d0a26d3edf4e7a5c33befc2f253f6d68890c9a485e977944425c3ec9bdd11af95eee990ec410e0d6672bb9364d20d61a1a9c83914d19952a14b7caee21158e5a7e9811bc1d2722e6a4646e101cc057118c83ab9191622c524f7ad3011708cfa35d0c19d84d70e076331a6beae3c6242c3a08939edc1d50a2b9b31cb1def100ca59d28c049c74e00029a6524438c04100000d3cf23040ff3ee53c6215281e87e9946bb664c8f8d685f00321368913568ffd48acfeda45946610c2ef9b53e629973d5e7eecf95d70519a367ff8bca7933d7520b39fee25337a6ba46fb69c345b5bbd27b0ad4724a62e4deac3705739bc14ca60724df094bacb279f05b610e0957d64e72b1f8d2f8abcebaf251fbee41c1745587c155e63957d742a6936693fc532a69810b36c97f7c5497d7666bb7c210085570ba01eb08fa5ae556598bb01bf2bae5141e0690ecbef80cb0afdeb86464cde864c6a09e06607015701b1a66b3bd0f2bf5c5ed45749c2d81bbeadbf9cf038c272aad0b8f533c9e76a87ab4e50202ade356a5fe602caaef188149f8f313ea5f1a14dd03a8c3f3379ff5dcba5cfb2ba54dfa61963f09aeaa5e6cb7291de7a4696053b5a7c3f602c08d65339264026d595d5b5f212e95992261bc55a90e42e28c67babb2d5f40204f2afcdd3867e0a64785af8191b8f897475c212d6884d8e9b68bc75764899a5bbc5a798d251b86062697105a2686668a83ffb2c5f66786557b2810c11a51ef207d4317f3a5ba33ae454c9df254bc5f40824c4898145b5d3e9d7a71d8f4e7585ce310498de0c3e363ce58c3562a5095dc1a7baaccd48ccd280f9d948f8cf8e255c582824a3a4ccb0e98ecac359128a40cb1eb18c7cd2515a7f659eca6a9ab0b6ddc06f594ea2c74e594236483291e5ba6c8e495458e4405e98e9166983f378c74cc25cb5d83cea4d2e90f5ec31d344801e235a6ca040ef378aef0810460cf225d822f8488699e6cd8a905a9c0e0a1f8249ad5063b421cf5cd5029d01a66bd4bdc0cf408002eb02e9e76bea85529d43125467e4968a42c6fee658d478ad3c4cc20b7c28f40edad0efc31ef7b3b94dab0276618467e87f4aae3652340adbbc52ba39499c781700063026a9d3990ce839429198b5c638301b1083a7cbb9cd5e24c32ad8f98df6c3b4dad9999562a7f7c3bc49d986f98d0cd0074adb533074ca6761a65ab229eb350cb2324e70944b8e84b300f8f734f351de5ee366a33ca1d76b0d15dbd64517ea89269ba3d8b6a6efcf1ae43a31326ce7a9ec43b6af9cd3e05f4b1e3f814002d9e4d44b7f84f912c95e858d3221dde0ec33f2f53c6f6950d34898582329606ac732e7d92aa3a2d11bf39963bb17776cd2e8a557159b12691c827889946a1384db0957d56dda8180b0d31b132616f8597849558dbfd0573da12b5741ec09cc22e8221a6d60292a6d9966676f9075db21e322f0cc468d41959ade2c37a561291e82022b18b7cb0c597246043a481569ca22fcc20806cc4234fcb7086e197e59929c51da1baa18ca985a9637dde0b0a316f3c4dec9d69e4db4c61ec5d46ac2987822fc017d4dcd011cd8f7ed530c25bde1e6132fdd7380f1bccc8c8541ecdba7c4fc88178a4bd04ceb526bac0281c2848c37978ce785d1bfa7e9ddf048d5404692f554c6006a66fc63424707b79f37137120b4f76534e55b1aa17a2711fb8d88226c59730bb8cf3ad23f72bfaa46f755f414fd22a23c0f9050a96b0976da6dc0fc3e080d29e5e526ea80c6f1bd056a92a5f179904260eee2d418750b577c3a142ea4a617e5bd3d89e356fa7e17245df1222796e8e84f9a86c648e329c8c049a244ff5e4d6a43f17edb821c38e3695e92f8687a46d62d5511330e33d248cc9cb08b2f92a9a828fdd041048158cb9caa4783d2fbb1d35baa535cfc0c3ae5534f427729317d0237d1c301602f72dc9c4a5d6dc08d83b18be9f780ead36d315e3c1d95d17ba81eca859739952ca5efe1acaf3a43b192094f4c6228d8c1b408856ac71b2d652e0133fc847006581b5d03d73aa71c090ccdecffcbe3588de95604f9d1679bd7f59c0830f1c029d71979fae30df6046c45a753888eae500fffd042c41c9e86521c1f755603222e15f93446c4b81cd78d9126a9cb0a4e93583148071f61e679d9a3a514220298a882e431272094ab41f5e13201f968e83f7da9f3232eff6556f86c05ca7331ff49b25f6681d5662cd35436d36760bef9f5b1c63fc8f091a20aede7f2b041541a00833240166a8a46c1c95bc5009c84740c145b4de478914d9488c3e6f8fa8000115b1b2a519887346f9ceb76d487090f010d93ddc4e20c95d8cd43cd4fbd1af246bde638bd9194ec041ce4045e4004630d5720da55493af52067a71a78dc3711c3c2688383727e6d9c1214c8f572d68c2620d7b4d3e2785dfb55590e6d444d3a000e2a29685723e83fe874e809670f2d30beb87cf2a79b10f17e36b1ad6dbb354208217b93bdb7dc3bff0d330df90c6028e10b4baf3ed7c1963c4afe50b1e27ecf91064dec22c7dfb056b684ae1ebe804412a07802095376f0eaa7a00b872359240103114f5870f4ea43d8b750059380902ed40abe6003224ca4c089a457bc10e9f231061c5cc1082c9074b1e415bbb005511348c080e2440c014881882aa63ce1c8933026d17db26db65bd0357f4f344a371e768658d269e38fa872fa35dfaf2965aff0aa57f028e89d6ed984532aa5ca26b5109300e8da1dd3ab222f2a18630547aa127941edeeeebac566a3a3bb2e55276ca5e94ee9e091b4354ceada468a484a3d8544ea6813d262eb53b5edb63ab85986465438a15e71876e868b90bbbbdbaa48a1b1ea55ca06870e1e32357745534f745357cbd0888a23f95b1d513092686a6a7c81074f6890e4451117589103090ea280c1128c20cae2d541c0a678c93db9c8ddddddcd754442ee25958332a9365277f7d1146568541491fb3654f82475191a4df1856ccad0688a28550918c80191192089220757d4006e9104861327a0f085a52c5ce86a40d00c9298202105328870ed18998114b0f00517465062c90b1e42780be1618e3c19c5eaacb6bb9f502407b9234f56313a259e912776f79429920e25f76db2309a428bdc3c4410408646532021a332349a828836317fb25d2aa3c7057c748066fa4c1acc9f30bce084a523326a6ed8e04845a12da8083a2a4286ce32312ca9229c18f7fbade5aed097fc64cbc2dd31dc8fa5af83074e0e0b773b09899ff9c5fd522908a7adc24d3521a90cf25166392497100386d66189a425f2364f96ee19a6dc8f45e674ebabf4fd92d781d3ad7aeeca21b9849803cc2d89b0b859d82e5ddae73b0f7f40565ab44bf028af38a4a2a2d996f336efedd5634130a08c32ca906bf2a723d7c640563b4e6003265c04e539734410d4e4897f884f9a99869b768cfb712bfbfafe6f8c0c978198038c8172ed7743eef7f719b1a95d7adb3faef3f68f053bfd376f655296f3d1abc78260c04e10325b3c029a231e41e7887f989734e698b3091f1e31877efc4aba7840567c64b2922bc864253113261e0df186f8c9a35d1c508e0f20464cbcc8f170298a272093232896f207a32c413222111adead538ea7d1adb9c54a4af91c324b1a620e39078707649223133348e2e382a31f299a08c2074a9a5cc1c40544a4f834216298b785612907298c40d4bf117388393e255d37e077a325c32a9844c98dbf0b27ca024a18c99b6ace1bed5239c28113ff2395a510146ee4b8f9184189464239be3e28c5024796686d393ea65b738b1ca52025c728a956ed90b99f43e6be99d10727f7661cbd8ab7e9554c228f814819b4a08514274661784528c420e4441139c0011154f08a3c34c88baf6e286928c24a2be57536cc5d6eb8fbcecb62db2b79d3a54b65b18a87eda6e76cda75b08673b69b6ec23a1b8692957de795e109258bf36c3ddd20d051a4cfd649db761bb96d306b0a6583321fcd3479f105a5adf803227ff5d8b708e7eb63922814b38839c45c5f5f334c71bf99a94ce69a45cf9dd25f0cbbb5b6fbb6a3df3d47bfab9da77de3bc9d5c83ccac61d86da4f594b2cdb1ab4a99464ee1c5d76d1a1a60703f4845433c557051bfb7d7dedf6eb3e2b976c117cda292b55886594ca946d15324c32858904456408651aca08b9cfa6a83dcb6718ff3f4ed84553bec4fcf6133ef9b39bbf43e9d6c5a99bceeb093266f274b2f48e70ec72ce20ddbb3ed3692db62af348cca328b639215b4f6d5dba6c551e81eb9b791d783cdba509a1a33a2b9e8289dd449525a4a8d1a38d0e050a3468d7a54a7a84c6a519da216d5a37a448b2814e8124a44a1408968112d7aac35cb6aab6ea0fa8151ea551f464905e4bdd6acd647c122762885fcb48b2d002c9848b82c6929230048b004d11d6844ecf8b9f1d066606b2962f9c18c0a14802407262e3cac324784c080c51168e085d113ace8b9820747a841115d681185204031baf8018317be3003273bd8410291249e40062c3431862fb2e86e2140893c405001138eae40c20dc810050c8d450e80e003196cc10761242d1157728cb6c5926accb1d41d453a00c2174414a103325e5f4a850831a280832294780106affecc42ee6e15272cd7b846b73ac7d7dce856c442ee328e9061440bc8403ad22d584119bea0411251e8c14b28679864545484dcb74dc4c2d90c8d8a8238221a1484b65247e9a4e6a2955a8907dbe983f122f729ad94561a5540f9ebad2f71f4543f39de34865192f1b08380ea06f186b809a12aa05eed643a3d2f1e76117f2ab141e992ef27142971832f54e10a1d49e4a405442f14741132f04879c9b7a753b1f042c12a8b97e472cc98f0c414449b109890029e577b108b1ebcb6494ddf4ed6bc90440a3caff60c80f44241c7c8846600296e7c9d94e28fbe06db2dd94272b649a22ccb344d5b82cd32ef934ae4d012ac954496c85a6bbdc951a0683f7b5b9eb4b85f4ccc655634686ad4dcf87a72d4fba894334a9e6cda7f73ce890394869fcdb4e61fe8fc8070b99ed6536badb536a333abf6d48b493446b1962ae10b32e7cf2c327de6cf498b1b5f3869f1d5d4404992bf201d93a250548a4a44968372bfd4bc85aefa893f78ec9ef20f50b2ec84f018862cf704e5a6622eb3a24153a3060728f7c60ddabdd464db6cf8a2a3e42f48db4c835af560a63ff5d61e7633c3f5d683804422de005f319db8937a452512f106faeac13cab8d0ca242af5e4aec305a3dcccb01718072e33f8ecbe23cd283520a9fe418f10784cb344689516216dddd40dc2366112546c9418c32831835376c70b0c42c6294982be8c004a22dfef4ed158430c677378c3056b1a1b0b8356a206459cad2d6c7ad1eeb6eec0e9d83a07442148629cc6e358f837261c68ca010ca33646804854fde324e9bd35eeb6e2c8e3ff1ce6eca6d373c39338ece896198e2d93b74deb0cab1400cdb340ef36677a3418e9326d8e990e50867e8b796b3631422c76e67a80c5104e18b2448b1e4f322e2002fb8010da47ce103259ebc6063f817357b45e334413843f13ce5792af3163b4269fa4c903386bf12c4e44d639931fe501a817a1563508edfb70e92aef9d8e56c581501f8a2912cf91587a792aa07eedb373c643b77f8ca41bab8cfc3ae021c1e72c98adf70519e98527acaf52a16b14bb6392c4c11d22bf8df2552764069956394120820f45bb7a3b3c4f802282777464a27e681a3e806518d1a1a5d777723bb8ed22431cb8642ba1ff7d95cc7b005f1431fe6afe60fc21884902c822d48af209d18abb29bd2885d4e4a9730ef47afe02f90c4a18a70812838db6633a593e2f40a4987212e85bf41735968d4a0d12b784ae7a3ec40a63fb29c41a0207fab5e65f85eb1a4766ab43a98737e3b30533aa3306249142d284229a594ce49e99cf1d36bd410ee373384f48a6d83b1df2bf8b16428693784f84bd1cc72e93d6190066d50c6c6f91bf2f436b9a2850f32f55af2268732f558b2924c3fb130c264b31c176564990cbbb580fcd90ca316c2c8f0db0d94524aba6ddcf454f3d0480b486468d40513cc03a537e41ab2d6e5d8b6cd6479d07a1f9cdc1a31d30784eb72c88d93a6fa5a1f7395d71e6ad70ebb1c34c72eb890a907ab90b14f0f1a293921530f1e65d83d00c32aedfdecd96107a17511a061083f18a38928be781159c15f101ee09b08c03a1d68ec74c0b20f4e348f877c874d0f1a69a109997a386f1bd43669a2b7698a553bcc4c1f33c51f0a72c447b873b8464b39738dc774cb5e5ea65bf433537ca35740587295799eb20489197b8671c488eda03430696bc106653ecb03053cc43048af2834da42920cf3498afb4132e6c705e9153d76e8459ea2d32c2aa45774698a101d68838b4bbd62c0d06da50910dd0f4a998011f7b31b863ea4ab795ef43f3c0073e82132bdbda9c7173d4d8db4912e48f4a2d7215d36f2f0bc280f4f0f0fb53cb1a5143eb25aba455286465b1c4191a1d1164564d5d13cbde4822743a32d96322c4386465152903539bd80596a18295e64fa189f4cefe4ce94152eccd0748bdc1f15a04c558cf44a072f2e3dccb206191a2d9992a30a5051a65731d2ad98448c9d0e32cf89557e66487155f3589e593531bcc2094b195ee18430f2674aba539a45ffc40af783618136e00d0364d1c3988d9618c9376468f4049eacf2036dc09393fba9fc40a1fc9992568aa4eb4a6916fd25e3480ad21149459432451959caa82432fdb73245879b1970846bca135f2970861e01445c951f0a557e269085cb8364def4efc49369c4e224052687a4fba9fc046515f6213df953c97fd2a757f3407a4ac6b04ae21d34cba394f2bc2cd2ab894d5e98a29894268c52b7b067df95c272246e4c86f22a3fed9a3952015a62486549b7a011144a9db4240bba093d81287f2a42992e39ca9f8a924c5588325539ca549a92bad59a584c98249828dd9390a2f2a302d42b9ae18f2b92e91bc3e27ea6a9b2045609ea15bd925ed1e97d16e9460c4f6f65a85794e854858bfd74c5dda0c8d5c3219fa4b81f4c94ce13c32445e17ea6246caa98d47f30432a2654d54485d4430b2e96a1d1162ac8536668b4054f9edfb02e87cd152fe5289ee6a91425a924d92e6beda657fc0189c9f52a48d553c989c195ff549054245649f260a278304a1e8c171ecc52af60a4580c933481187c2a263144e644dd6f2549a6975f11ea155531e9565435a9dd8ec9c393eba5576fc40550ae9e0df964c55549cf3e760f983c3cd9be3b98a4868902a394e94f4dae89a857f41f4c526c3929566da66d3a7076861290642c57083bb899dec6a46ce0822a732d589004a3b19ad10520d01a344e66fc60dea8814218240e1b16238ca179e8c802480b5894d32b7a9c2c60a0047874811e2a64985104a4d872524c870ef48adec7ca168652516012901f4529316410205eaa183a027debf48a5e48911128119ed3929417788ee87119c2103d2d3bc622d107ca0d8c441f233f16892122fcc4d62109a0222222d0124150586083a0969346094b5bb0227f100946814a7049cb2245ea568c45d929928703f64a5a1e8a24d32b7a1d5bdc8f22d127ed3a11b1e8a14dafe8bbc8beb66036e5886de00cbdf578e8c0d12b174ecba3984386dda248361a00673ae71c898bc493ed0c5be8c29d191a5951247d7062451272bcf1c1c9d53234b202a8a5911546901180623042154caec0811116a0f0829015852081104a69219c73ce998a12bbc4df9c73d639e79c730989a5b20c8db4180311ba76d7204a5012062950b8f084300020c5155ee0028b1d2c2d618bac0a00d4da1d46ee9e9127e38c6c5a7c91fb560b2c649ba1911657684dd4474ae98c73c6f854ca5a5965ad12ab7690afaf405279ceef64ba93278a4e3abda635345366f625c86e802933eda58733ec5413e36418e61c48f4b25ea646d8e03bc31ce352afa21426b48a6e27196a219a5713ee175be8d2449a1b85a08d7e7cf7401b4540572c02b2e2a140d18216c00043882844843311c79e38d4abf89b2fb4118b8082462b27e4f8448e357a156b304daf8894d8faf13c8e3c987b35e7552243a35771da00670290e31510d32a408effba1cbfd90021fc3703ff21e053408e2d444e84ba65e04c44caf13ef48036a0850221528f76adf0402231c6295b473c8f781ca4a31cbb7bbc9c706be8215d67c20a52d0c00a442881e1158fd1f63ab7c43d7a1581b2186cb1bbc9de7de2faa0e4f68c31c68800316e073194057e5004be2f8184e455730269174ae8886ec56e82943f2e2f2175a18be436923b89dc9f4bb4be53eef7e85f008b29b97b294b0e0148f7a3c97d21ab5f038bba9bd311fadf29f73f0004da88198601922112911ba660bcd0c4c276046d442f661e22f1089f5ec12354db4856c71f38d32f62b284e82b9a3c23f60b80c4d56153e389db521ec91c6cd80725977b8e3c877590e4dc6fd7e16e7a4edf6f874390e4dca33ec4747b8fc22e7c993c55c51dbe58c7e93af684752eee308dacb5d6c95d6f88c91b62fae52e5f81cde421c9d9debfde10ee2a1ee4ef7be89b6ed3264f556f5255fcfaeda746559596cd574dab304273ce39e79c73ce6b599d58d4e788b9aa78e07e9fc3fd621d24f527acf38a3bfc237f36a98eb52b17a250548a4add1d857a15a392154a472f872e4ddc003c715fb00afb0b4efde53da466a4dec38c212ef892957dc6e1ebeb282c1ac9ca9e5d47b77ed8de3de32c6681fcc8dbb12f4600be8860b7f9017bf7ee1be66d5ecc5b7738445818cc59c6708663945ea1be82bf9957a4cb61dec3cb251e22ff7218e972f8dab0676fa50a736c3b8661c77aa957b597fadb25918aca3f5b9fbd05b3ec2c2c2cd6dae7d86ebf9331abb560efba96ec5a761bc9e2b552af2ab654b72ec3bd79b757d861b4c3c0bc877ebf0798f71b0f9187d1de30f2da25d641a235d6913016838181c12ed8a1c42a4df51c97ab24566958c5435f3e07e6aac360dfa4e77295f77218afa5fc1028696868ae64d5d74b7c79980f1922b18d64d5c3fc3b0e11121ad36ed35c6c327295455462d430896118b6720ce31071f9cbe92ade0b7cb978f22fefa1fb2fb83f447579f84279a7fee955bd4d5faf8bb44fafea3b8a17d85f0e5fa65fba5ede03cc0f83a16499700f2f87390c1ee2f217fc970a3bcc775e2aefd85d620e83755c1e731dd55fbef3d24ed3a978a07f7905e6635eb0bcea30d7f057138387b8c8ab9e23afc22aec7dd5fb2a98bb3c47f597c76f2e9ebccaebbf78301ee7e2e920c989b90aebe82089007c111982244775171a3e44857d4856bdcb6b780c8e3e9255eff398abfe451f2c6ac04024218106ec8223cf52ae33e0ee91acfa214886c07c880b8e409255fff22ff260118355380a49563dcc0ba6912c1c97d7bb78cd2359d562568354f8f840a32a20e57a9844aeb22757a49ea52a81b0d7278372bdd5b04f1229515a4206936e7d314a93273c92a85baa48d4ab7a98e392f750ed245f1779217f7dd485fcc9e42fea6790702f79ea654f7d2fd56f1153ed98197b8e99b1f691ae5e6a567dad6f1ee972797df748d7cbeb371dae70bf36926b1b69a06e7149b878f105bbc5d56f2f1e7cf5d2940d7f3b9aa6ed64ec9be6fdc01d66ccfbb85b9dccbdd38e8239246bff74b2863feef61f973bef872074b23dccbfe6c1bc7d722f5e3c922c9c9b58d4ab7a1e3e176697bfc057b784e48a2792e0c3c3532f3b150ff22ecf9177c1aa9cfe0b566158c5c3cb5d9ef37217ac8304bb8ecb5f700ecc5ffe82755e0e83775e1bec72d8edc5536d87d9b08a0797bf7cfb0bd641b2e19c97c3609d97ad76974974ebeb24b9be7edbde4bed9a01a8a73419f59288ecf129522f7feaa5911a73bd0c6a577cd567ddd649eac462dbb66d8776cbddc583af170fbe66ee2eebcc9b3906b1ff9135cefbe2c60149657bccb351ed805dbb863f0a94b1efccf09e7ab9dce0109164c428dd8aaffd2ae5d1a99f8518a0c8a2074820638926a03819834f931ab820092642f042230ae3d38b2688a06c3435374e38602263e84489947376b6dd9a373108aa7898553ac41c71e7983b6f70a6addd219f70a1084f8e37489108ef96b46274ca58732375850f56041f08a1090b9ea8410f1712d8020b3790a202288ea001d18f0bd1106c985c3002136480052ba8a044921fb834852130618b264e58e10555644f6ecc2d548135d1dddc152a1802665153d346b387c8ddb6c6092eaaa024ca0f92201186962a90f88cb102294828c3ab2b138ce4ee1a27ec1529f826869a24fba4b7124a2d40f920164b8e385833356a7a7cf7f041c9b5afd7be592fbbec6eb42ceb996b2aa732d5347cf262a7037d95a7405293da746ac700ac08821536c34e16751e4dd654686ba3086dd84332e439376a24b3d9ed7899d91737ebc9dc9d654f0f66da498cbfb8f5362d310d4537be6f527026c231322669b7ba45c3116eee59313aa789c299beec269ce963dbe59891eb6117c4e4e191410e521fb34dd76ec78c5cf147828c617a1b396da44194524a69a6f73dcf39e794524a2ae78d1237ce3be7e7256bc2895fc31c828847b7a0e4c1a35b10c372ba957dd3b81a089b0291ede3cd2c9e3540b8b3df359cb8dcfb9045af7910d2e064b9c3957d22db9368b3565218fb831042484d50d02cf30c484d124327644665083d0de4ad238c3152536348f3ce8cb1089d34a92c12632c021f6fe8d82d8bf42ad28e73824184bd8b6c095b30c91d3801086480018cdc5de38411648d13dd7d0e870e1e991548685fc44fca8983749ee7d12b781ca04c6c8343173874d1d2051b94d9624bae07b4d13c707ad0d46478a50eed369bf7a30697ee804d32c553d3bc1fcdea053c81519e25e652f61eb9d5a339b292ac3e0e493692484a1f720ee114b3202363c50b884c19294656b0800c2d909132257777777777932fac4046ca3c156e132de4eedb2a9c68826479b6f90b6766a69753c289edf39cf30135e41f62103aa1dc3e7a39e23773c4f5107a41da7e66fb54af26d72b8b2dccb7c640cc62e3eba9f783b5f0f439e0a9c55ffc08e24ea658a4ad6483328dd1e636d8e5e06efa16ed76e9758f1e341d7be705e9acca0e3f8c7aaaec3367dfa66657b3005a5c8961826e3f7e62125b6badb5f21f4bb6b735265b8b5d0ac9f4df8efcccb0c3ceb5bc7df57e90b7dfe4657d56b16a87f8fa1cf1f8931f41dcc9f5920784c09db93bf9209d6919659441e7cc1d0e118a67b722cc146e43a223d418fb987645247860fe8d6ec5263f5c4c0d15d9c44eeeb23439e2388c0135b831737665f162cecff979ac625e90ce5472cd15408b2b13d32b7998a01b2fdf2d6939cf0667fa90305cdcbe74d9673419fe322d1cf077255d5c0ee6558ff33a0cbea46773e328313d95fc76f8ca3c95e43cf8d20922a45bd4abf16ef42af3e6ed6bba05737723847ce478664b306cb23185f3edb58fdc1d040af27cdfa608f783443d7cc0568c10668cfb5dd83dda1567e0633405a2588513489a51154baa4842cad83645591e871115c8c8d2a80a23dc079b74778fc0e6781e8f480f5b2f96a2f333a6dce6c9dfbdf77e95b74aafaa157b0f1f40ba0523919ba53c841f24e355317ab1c892524a6107015a46a678054463b68353ecf9091fbb1d5bbba04dbb54d821911efbb2cf5ebd1efbaa87de87829ce679d967de0a6a5e750433d3ab76884099e2206219994afc752a0ce3d4c39c735f1f76d50e5ac67010a70cab9069f2b793e5234f861e6b36d103da88398291a316728492e37d802e0b59fd0859128cfcc1a254fe605117b91f231093276e3c2a3a401837ba629164f58f66e4ce42ee1e11cec4ce7146165490b41c77288a2237942c38a142ee7ff148079ce938a50048dc484694d2ab7e8d27eeb7ca0d21fe62bfe924ca11055b1896885e48540ed851ed8083c42dc9b592f4231e41c64f919974842489133aaa227f70ca5191187fe44fb7baf5c5e4a06e4595e5a4916e4d2de4a8943fb9448e07225e48bc8ff81fdddd1248bab4a2222d924092021346f820750329b0b8425112a220f414e9d21edf4bd2b53d9e47cca18324a7ebaea31dbe3a4c669759e7c9a1968f75c24cfecc1c581be35603d1953f70265e8899bf5e6a32d424c3264718cadf64428e2f40864d8e50945118a779f0b579f045834606e3b0eea68fd42bf94446914a9ed4e4120dee378de4f86964e600bae4546222c9713691e3678793e43e7ff227c778f91325508e3228c75eca981631c0c217b93fa10b82c109232e0823f35746ace3b193230e42333dd6ed98700440a766a122b3394057862fb0d127d6bb417d802cfa1e708688fba552d8532988c5eddab10d5fc9a2423919b6185655ac46a41e53061a07a4571aac016d681e802cad5b1c4793ef15b7a657da29a6e995f6ecd60bf907fc01ba686eb7b86bda39ef46af346e721e0e38a37d8b474e513b8f7825209a9ca81b7740174abb76b57f5b8e9aa67dc3b80690e172aed3a30fd5200dc2e68943057704320761f36c39cb57aea25d47b7b86be7d13fac85127fddfb4a5ca7a357da6fd18da7216b2d98059b4ca66f2b9e8a47df973b4290a9edd58d5d87e7f6961dc61d897bb9d3398f47afb49f34cd0677f8eb02a259dae169f484f44ad334ce03d22b4de3b47a4cc32c06b503e956bdf61fbfe14e1e91d357f0d70923e9ba8d7637dc67c76327773165a2297a390d480d597b7737b757cd712bc9d238ed270eab4c5c778e336155d7bde3b873da7f744bb53d26cf108568abc0608332267b8b57cdc2fec96c2b1a19db2ef6025918f6171bbad301fb91b8d811fbc65835bdc2be0026ee57f3c12538ba855d87e5e0516741813216b16770287fa9940759d8b1978c4d0c333f7b425776c8e2cab00c7459bcd2a2f853658cbb91bb046dd063918a2c44cc42c42c89e00c769b9643dc8f16c918765aa45bd8b1d39f769d07c328900cca6c96655936b32c9bda9c33cbb22ccbacb536b39cc5aa6dcbb2ec3456ab4c36edb1f23451421d66628e193b5369501a13523a69d49898d261c6ec72cca05d8e19580a4bd11c2938d3f37685657739b22c65976372b2cb41e14c8ecacd2e479703c299fcdd1c324b6c6a26799bce117f246ecd1f8d2c7f33632ed8b6538eb8a1aeb89fb5e27e13084dee67ab405101350520dc6f1eddcf5211348514f79b4ca4108511ea08aa08150514145050a096a09e807202aa0928221413504b402941c9fd6c128470bff9042a082824a08650474025817202d5042a098a09941166932bbbf96e66b7ef6f59111a00658937b924cb4731032fb2c4f36688b4032d50162bb0aea8ae3461b1df905b59851d22e1e0880c91709084cc071a9721d20e6a80b40322727fe354f42cb95e450f917400c6d6691922e9a08bdcdf4c1c0c8e14dc7aaa65b662dc46a7ecd8419349becbd683483a70926170a4e0aa6468e48550ee14e88033f3d1d332068df23c9d47dd35ed3484d336dc1d56e56cefde75a6ed46eddb35224a4d9e9d3fa6a7cad9ce5dde74ee9aa7cad17e2fcf61168e4a621efac59dc3266cd31306b793a4ab93d89bfa3a499eb28c3b89b8df2a892b2a354f4e40c55a1631409ef297ac99a2af18fea44feea6ddfd43ba367c1f56b2a43665eee4a8619886411b33eff6aad6e318e2de1426a57626db6120a65aad16d6745b6faa5b779b6eaab54a59b149adf530dbd99bb02aa7bbe9a621a8ee84fbc77493e92a57c143546ed2567ed2ec5730b45d667fcaac8a87aad66633f3b0ac1ef3b0faad70e26bf78a235d1df64056b55aab96d5fa16ca4cef9e9d32537d97619576ce66dfacd5b02acb9ed9cb22d981641673ff117dec13e8ba280940d7c54050508a15c8d0226737757737da715c1480ac4c48afb253c00390951d951d95ade04c860ad2acecf0280f48b3b22c7b76acbb59c1994cdb34af8bdfc9f7ae0c61f9cae1eb7ee76555505895a372d451a8b7bc050f6939eaf0a5f29d17a77297ab702e98bb57f9b52a98fbc9de64ed6d8b6759bc6bb7f6b6ee5b47d8d28481f42a7b9735808c0bbf15906665e7b2ec515cfbba8236b8676741d77de4695676b10756ddeacb94b290b3cce11f7026fb0ef6dcca5550bf2bf82a289cbadd4fa64ee947b75c727620dde29e1d886ed967e73cad88ed5a7163109d83c0d8d2c40267e23bb0598d46af2c01e08ca5699665c11bacb5366631468ca39c8da79b1ebb73277b5387b94dd3b46bf6b75b315b7bed36bd695eafe08c5d65ab6576f624036577006750318966a11e73006f40fd885ea1a00d157bd43b1aa1e27ed148467d5bdd80363aa38ef86a64d4a30a5e4d7151bf37bd53d16aea458500d095c240e0b7c1960aea5f0e19b5d99a4ce3321021e6b6ad7ceb6eb41720fde2056916ea10daf801cea0fec91c3c006fd0565890855ac12b38838af91965edbdda21d4326e255d3f9a853a0ab5655cec6e828845320ac79e5ea1c6b8f7f1309ff1d45f8e9d7ed5ad95a34e83a65bf5a8c77b0be3fd69c503d22b140bfea0948cfafc016750bf515ced998e95a356502ba815fcd92c776820cf6f347c86afc45c751af09d41763931d8aaac9751871d0e11183c034368edb7940721ebc58390b582bf1b825cbf751cec96ca0bbc8a47a357a8bfa02e040abe5e72ece40af3195f49fde52b30f89285fa8c95144e4916ea2f2b58c5729595b760151516ac5a59f98a8aca5550ffd1ad67d481744b3bea4074eb1e752883c23f4421ac4d51b66c66279666651dbc217b9665ffe85b9339cbeab17a8bbff9fa23716786b7bf36cba88685d841bfe304b9dbc9a4125bf68dbbe6ddc8628cb35b326e5bdce28655313eda2b44ba66bc32d7e99003d075c23a7d316cd6178970a1a5e1ec1f0443cebe4d2efbcc3ebb9b1a3893459be64c59bb4ceeed6b767f3aa90c799dbef342e1fe912ced17ab7250bfbf5847d5c3101614ea2d47696fd14e47fd84691a56d19bb0771a8677d08c1dc328a55e69da59bc9464655ff12e599996da56d939af03bdca7cf42a7b03c4b85af61a68233e7b02a0ebf4ec38ed8a3eed43ba4eb80490953d8399ccb20d7fd00b39130267b2dbb4d15439eadbfd294705a3b68b579295fdb46115a76defb0a67158b56ddfb4cb22170a77cbaee393378c5aea95863921dd9a9181b0d69640b178b1c3c9c1198ccbdf7c3fd657181fae881406b919f6ea321bacb7ce1c1e6fa894eb7903470272c03c7ca359f5d453ed883c39e2ceb006ce4471e9b13a5dab6655563d8439d8006fa8ffa800e04cfd5733fc6603742500b2ea6b0657d57e7ad9a957f3faaef45fc3d5dce0ea0459f3f53275bef177edac5d8ee748bdced35bf5aacac8c4ee729832c53570a6fe48dc2d7f35b93e534a29fefe3d63f6d2ee66c61b3ecb93514bbde27a15e7e15185427e334321e9b2123b7dbcad423918a611ab66ec18275675bfe3659188b91bad98d96d865539998eaa87bebdc543b0f7ce4bc6db47dc3f5895a3a3ea21d6c7c397fdce8bda6bb7b88332bc86a164f550cec96e9f618b21fe9a2843aca210420a2f8b60de85c2452df50ae2db94274b5a9394e21152131549a1a1dcb5d2a529b93d49248b727fab71ceca3367eda93fb3fa4c8d9b1e968429211d1115111521111d1d7143424041404143404242ddfc993e18cfec993c584f6e6c62d3346589262925294d495a92ac96a7f4ca22492491e41105924352480649201a8424648f88b27c11109164b5fc86e2680f8ffcf1912c497f240ff5913e599e87f6ac2c4d614952cafd793491727f7399b224a49434549444b4f48274347d8a88e64f1011d0516a4868290868caec019a3c4233fa47caa3ee691e89249b47b60f8c52d29425e983745444247f86a40c8a441248b2a6372414043485a6d7c3137f7c8824abbff31202c40f1ffd9dd7cecb221d49567f9b819b5e0b49560fe5fe460337e9560337b1633d709a47b25a47870dee2425ef08091315014068480628c8069f9fdc5ee491acee991e10edf9f0709006c04dcf8600dcf4686a6870d3fb6a869bdedd0ac0cd1b56afa1894b92d5164e4f1501f84aedbc0efb27f784aff691acbe014c1446061b77e7946149cd24f8240a94dd4352b66c6edaa15e4d8bc921299d48029d8843b27ba8a57c5d925e28e128f27af46af6218413fbc4da277f147ab305f186f93e85b127c3f7e8158c2d88374021d1676293ce530fce896b728c346cec82b06d5beed9518754cc65528fc9c276771f4ec9fd296592ca3585628c2d985c32345a9205176228e273ca9a5edd8033f03870611bc906653e8b235df0655daa080f71503f1dbe3e58447329a98d8f0efce8963dd4f0f715cabb9e952cfa93e71abab0a5dac13e3ee24f01d97e27d3e3e0c18d20ae563e51dbe84ababaa8e9138a245da79f304da2485d6485ee228ad414a99b22b5eb4434c98b6e4dc1887021c97c821d41a3d0254a06c683f5747cd2ad6d8b5986e9138a843d893162485852568b6a9174d522cda2b7f6de54ea5fd5a25a24d35a548b6a5165528fba054f5f9b20757d92bd26d906a05ab4d23a572b5d1449b2a83c8a37d093156efc766dc90d19eea90a37bb0d8e78149b44a498795df4c9a3c6e29eaeb8197d42917a559b64caa459f45be5340f87bc55261cae45bd82c2fde613cc0b5a248a0ff3a2cb61b3869196b01eeddddd9b7b6fefd3bb3dac27128918eba94cea516d8274f2ea130dd7223b54c40e29e9563f15433f8c22d522f5a75bdae9ab916e6da7b7daa3a77d3bc4ba5ab47995c95773d45c8be00cbd8e245c9861fe302f302fb0a576cdd794d48779a16918129614b34891a81499fc51242247449e224692582209a6045b8231c9f419ce32dae4c94c9a4fe893a6b516d5a24cbf454f88ed416c1622c85d49973ca2cf3c1c5e7b0d8033a6bce9d0f0511735935e5daab96658d291e3c3c88ba0cc0525f9834c025f5ccaf35ba4733e12ed60c12da2c7ae43bab4dbb98a4392353f6daa264f383f31c4774e6c4e20a40bfbbc10e9e29973690960f8e1be719b96f560b35be62189df6e30af7bae94bb9d7ad1c321d23f3e9265bf8305f783473f2db563f6da0b892e0d673665eda34dc2912eedf63da42bbbbd0f6bb9db6d2929dbc722fb48641f8f2c51c521925ddbb86d729bed1ec9b211374fafecb53d0464d917616390ed6ddb20db7fb0a879e08cfdd73cd97e654fc3fef632f650c6e21f9a08039a3cb193a1e101e014839f58c44a4bec2102923e457eba966b484745561b3ae1d8137b7ad4d3f7c0de724b4366f51a352bff9e638e45b478170c37f51977f9cb5b4e6f746b65656565656565a5573c9bb719a9abf2174fb5f2e82359da0a8e3d3da8eb7295ee0f682316713a9d4eb127296befa1dd87cab577a05bf7da519c4cbb6a7c34b2f66f27776f8f5b51e156f0675dac0a3ebdc5ebef47feb477de08e28d1b2d2ab7c68d1a3537725c154fc876158ffb6d39795f6c41d7d4b8117b58268fd6a6302650b784e87f7694dd2e96cdc53bb2f219afd766e076f1a2126f49c66aba63dbbfb8e2f16816f61aec8993cbb2c5ee01f2147f3bc853084821e485e86387485ecded5d9eac711b07bfbd407157cef22814836a70e959bc9523362e98ff6cac9d0e9dbbb7782c5ff15c4ebdedd1eb58dee2b9bc40715bbe72faf895dbf426f197ca35b228a98fb05c070bf691f4e2230937f648d706200bbb162cf631f4f8785152338e47b7826a7713836c5e6063c4edbc7296940f8ee3be556e45286367692f0814f004a1c3c39329de28a7794760de7947667cf362122f2ed12bec2e1e7616af46ba62916461d2857d56e2d941a0a98d414292458ba42bf64016767b67e7ac53f1b07297e7ac3c87e52f2f33524fe12133b00ac7c505aba2aa87cfc0aa88553cccb80b929cd45d3e44f519efc1e5318fc111e625a5729901e3c197ca83af944b64f156bc3bb9b1e845c9ed9b54f0d799f6401b110870063b86c2dfcbcbc5dfbd27fcd96c63109cc10e241583202087644a8fac60b7ded7f98b419b77a4e7af955f66b5695ecc2d5e84c10580945b843d063d0e49d7cab12368c3660cc370d08a27bb1844e4e695b33c6af636dd972753afe695b73c87e52edf6250afb0c71c5f55598ba7cab08a0798b7bc871977c1435c3ee32d7808921c17acc269b92a02f0d57217acca667c480b5665a9d47b68f90b1ef2f296a75edef2212998c357077a35033b8c07252b85bdc5c3ee82e4c1d70c0fbe521e7cb5c4a09924f707f6d12b0c7b8d23aeaddeca049a1104ed5c8c5d3763d36896f6cfd6d0fe5102d4096d5ced5fa741ed1fbd93ab420120e5c2e823b50bd11e79a00d99b54722b1a7bbf678245df2da639274bd3c557489be38647fb216354dbb6374efc77afa0a607fb9b70f2495bbd3eea64fbb9b0e6bda394f6bbc8233da6d369bbe93ab7d437928af047046a3de8b77a55c98ab9efa8cbf9cbe05e57d2d2d2d384460ae7a773844529f719467f3a68259517916c65a6e9be1a9508f3c92a51dbe529e0a85a5a6c2cdf05292a53de5695f8aa507b4510238a35dbbff5e7277ffdddcddfbeeb1130267b4bf28b91f3c2a9a9203669696cab5e3e4746b056be73cd8abd9dd984ea35bdabf1a59fb86e3a5df29ad0b57d3de1847afb41ca7f737160ff60a75156ff60a857aec74381d75ee2adecadb43713fe7c98cf2b65fef836264ed9df7c57ce2bedd463b8e6ec1eea6bbb76773c771edd96cf26687858471396cb5d708c4970b46e56f6af80789ed70dd39d9a04cd4d931f2b287afcf6477835375765ed4a675765e18769bcebc9dd726b9ccc3b478591c897a47cfb53810d5d3571c91a2c01a7f29e8842c0fa38be2cf461c922c79236e1c020a12225dd8e9e5638f8c4961b077da1e788894e3634d1939f6b8001058e418a34f2c12a311a020237274895308914916e363d2528ef1b079ba4564fbd747f8fcf4a08de4a16e718f6f25b19774518eefa3a51cf3d74d72fc42fe5ac9149b8c1c254f8eb711c67878f8334549142b0461498cd7d748392a95610c45a8a0220562787d9d942313f9f4d92d05e4d34dddcda90b4740ea82134528e10b4b2fd3bbeec6643b22787277aebbe966e6be7537dc46840779bbd6dd6c515eda2dccba1bed7a3953c1167276dbdd64b3aac0886a23e24caf40ed6c9202222d99674f3e458e064343434e2471626828cfbcf59ddceab5e46d72570cf79b59da6f34bd929fa1c9a56d5d4ec41ce29b255f8ff26eea50aedf2eb34bf91addaa288f251593d32b7994d7a359f27de569f0b92c33d5ad0cabb2731a5665ef7eba7c0bcc610436d7cb5f1668a35e7e9378d37ef2eaaf17b3c9d36eba3a745ebdc9eb139626af73ec76745efcc6793960cebe759e76aeb36f9db7cdcb51af698fdd4df6437698e194d49bde74725932cc5d59706f94d3b55328c309fe602620cb5b296439440a98c092b932b0c8dd51f03091fbf0458f39421b999551487ab18868070b2ece9474bb4d6f4031689b9dfdf4b06358a7ed6fb04facc31d6b4f07893d921cf969fb39f312ebc44f1d24da91e050ac135ff448b4c32e477ec33adb25b64739f214ebf4259672eab0d85700211f7aec4048d7f67a21d2c5137ba48bc3f1280e49568d5108270ae9c0f98a467e3e2e61601ce5fa2db68a54993107d3101f42658898492192556d7a471131d3284631a665d81157e9764faeb46ef1aa8ff14787740d394e8fd9dde04c22765e9e0e121efad891e434929c3e76e90de90044d7c44296968e0344557ad5c7a56a33eef39fd5417471382e4956fd869d90a938845c0fa36b4653fee20f4e5492acfa1d46dc2fc621e96aa2f6e91fe902f2d9a1b3fda68a403cb558d5431f7b04fa588743043b9d977de4022f4a179659fbccb379cbecb4f6aae27dbc304f15710fc9822f9b18dc9464519b9e1a68c38704407a308eb690298559640a675e94dc8f86a6467fda15ee94491999319226c7c25d16233ddd35618c2ab2090997cbd0688c28e48fdba8188328d72c8c31943f8e63115ac9b05c8e1ba3070bf66437ad62b62f0b4d4d8d5ef9e00534a8fe18316bb08479010645c81b504be385215ed0f6c61b34bb1b4b2359f1564ad3d4d4f42afe244916cc9646ba6c675de8c205a9fe33fc596b83226b83236b03a466c1dcdd8dc530a2faa96cef183cb56a9ecc2f67ed4d89714526e282400425167bcb114716eeb41c0d996d0862509121210614f9a3c938b82d191a8921345f3b881124332fa659f1ede180724f53a3e606b457956786466348ca5f8aa8075b8d696dc8f0917e36e43893638d29b96fd4c3e8ccd29bdcbfa24975195bfc163d9ab7d34773903640de4e4be4203a9832c4d1c3799b3156404a28f10f50c6883f29656a723450713f19194ae99492c90665be2d36276d7ad5b305673700bab063d84aa1952ce5a04dfd5b65cfe64a3a2fe9c4aa0cb4217f574683aa99b101e686472d310d53dc785386d1664a4a6443446483623670a60f89a00db864b371cad9ab86df4eee222dd8206dea45b8a227c82d1bc68e300080949b21153c4a79e6fe6968028a12474a54610b265e9d85143cf1040e8a30c60d5efdcbfe4ab6bc942e04ac6c7874d7c02512467b5962b451dc5883458e7f3c0d9a18b92947d98e0108b75bc6bec1cc29080f23670514ba907b253724cae9d1f7d1dd304b1193a5a491e50d008481832c8dc250caf25f1d91a59118b6c8f235dd8246539484614acd147745434e21c5c85286210859a6588ec0052665305902832f5e56ba14c044148cb0842fba5083315ecfe9e14347946064d8448c1e64791cf8030295b2a7f2837b5968ac68b4b8df6a1545fe58a4f0d04811ca5d9310a18b3e62d82d59b1bbfb70261e072e6ee3c0859456b2224ccb0a55c950a6650c36db2d083bce79e5e92d7435a5135bd93b1305dd4d834b27c5f08310c209655a4a3f3b431929c60621709b542f63992deddbecbae1b63695b2d730673d16db16b3f4aafbeb28538b731e76345a8fd238279df331d248699fbbd4e6898374967827b716b12e5c0a2784725e4e49a594523ecb54ca5a8a514a23593057ec25a86fb1b04f4f001562f801c893474eec8b99de46ccf4f4c2198961d8b173bd82a9d4c41f16846252ca2c07a179526146162ee802e1ce398140a41ce3e7163e723dc412c326a6f42c41689e52a6a057f3bdd6facabd86dbb47c760b5d9ac59c87490c7bc5b7571aa672ce1c844e9e196b6118156266faddc81407a179e2dab486171af81374f590d0856ac91c68e20d280fbeb62328d46d1ac2170ef9316fb0fb9d5eccfb2929ef7bc4777b284f42d6bcfc7c9c3e7176284d87d25e763a9c1e71432424a41ef131ef4ea3f22fb5f2efb2d043f8ed107693c5da15ac825f79eadb842d4ef5aaeb3ada755dd7bd7ad8af376f234f1e868fa03ebdeea9981884e6884750469e5835bf93279e18d78326e64023ded0a914cde936dd593ae7ec4ebd2062195f100c022e4ffc43f7ce8b191573bc9dddcd0942564ad2d0884f451a9d473f71f7bbc979e79452767733533c789b1e4b1477e698a9d4bd19770837cdf4ccfef4db9da44d9bce1d411de9f90b8567b3e64fb7e9e9611f4dee771ec6e1cf6ef8bb1afe525fd17c35d9de7239aa66a8442cd695558e2aa56866000100d314003028140c88046391603c522515d10f14800f8bb6466c4a17c99320c8510a19648831060880008000806024a800107a5ace6a002d651d532c20b0280d987dfc21fe6f577a97f34dc492f25c0ce21e49dd8a0e52e439a98c5e1ae4904ae53a9e34aa02367b6486701ff5a8bf5183c936d4c9dae0160a8680a5c71838ea30b8e2120114289b9bfc07ef482e8ae16d61838e69d4654097b9fd196264bd93ce426a9577028dd5604a099d99d72155b1cf494df93841b13181cec23bca41951fe9639f59499153354de76f5c7b5fc92e8d0dd1700539a58cfb244013db498a76261112a8eb05fbd65d5f6ae2ba782a5e5dab57e1c2eab78e277422bd460a15306db5fcdaef505f6c9cfe46c9351a0f41e76404a30cbc212172c8749811c74a822a0013f3229edfc65c6256d1a31e553781b896ab39c4ff2490a8c4c9e678437c0b06ff7a3ed6462374ddba6eb002462f33ea9f82d7c3cb4d0cb9c6d60f8d95d6dca4bab0ba3bff7b23428b8c75f82316ee69c3f136ddd43c341cc24a6acce4d620f0bdcbd8237a2738afb9bd02f6012950d09ee135a86e4f7b14317fc8a0ec874b381c6f714520bea498cf197442858521c23fdfdfeed71d1367c850bc0919346758a5d96125b4d1364d3dc4e7b54742f83dc3bc49b3072c041298303705284842b87b46247000f00c6af197f00b5590415abb2bb90f29c57d620246689934943cf0f2be3dda8cbbf41ac58439a6c25c08537e27818311371f8748c2f958682705f83c023f4439d295dd6b1dc00a563076a83e80f97386465840d7b4e508d1ac90d555d845b3e8c19c2a037e7d610d78f886f67e3f2d770bf7a91a55b210cd135bedf94f1ed850c55d438ac8a63d0e82b42b75b826a4e20971d47b32a90d628596b047c79f292725674414f9b44e6f890df14190f046ed8d4bf46204471ba1d6e6efc76a306c4a413d0c50ad235473bd2e2adc227471e04125f681154806f4fa61db181d0e9d62c010f8f7b9690774226d4bb8efae0762c5e16b478338669fb1ce08020f042fc6b9be0ce2ecfba084e7767104f095f036ad77ae19126bd43542ba8956493f97fa61b6f8313f78b247d730ca61c43c6326ab6e2e1b2976cca76985ae5476102f895463682cf55d50900c08fdca0cddbc9af7067e1566533a735fcfb7d9242612bcd31a2947eacd81abbc58830a51ffa4bb60e374ed071661113331107fbbd634a820daff54cd00092412c9a4e71df2dc7cfb1a7e863af431ccd17e86b3370c0a85c244a6da9d8fa26c8551bb046bfbb69262abd7b7946b768808f9b6ae5d326d07084620202c063a2fa34f48b021b4d4e0341f373803ff466017e85459c05d803ccd2c74a6d4322d4842de8e626fb157a2b296386d38065d59ac3e2f2dd22ba8a123edb64434d44670ac7fbb1c17889fd331e832f359c6d64a77d800c41c3890683e9da1573e5c3cbff06467eede2d317d913e73a8eb2dfc9e6de26efa1b0a364dcf1cb7b3df49fb6dea4c92c1f18e16641acca2612d25883d25bbbb3f01f1ac73ae453a89a70fdb544dc4087530cc3a1f08480f76f091f1d0d0b8a4ef70c7f78f7231a7d3cdff2839885334b5b59a36e5e0caf706152c5e29dd2b288b1396f5b917406e3f300ae0ebe063c543fb3eee1b7515e1918d1cc869c7cd441fd366018f2dd6ae006789c3a1867880dc19ec914db1a1f43887a391b3beb6e99e847983d5c38571be16dc21aae7d227931e8197fb2b25b2bf0a926d3ad7f6580a6f81fdecad569fa7310d9f81824a7772c8528e1f09b62b563f49a4abc4a492c19b74f7b59e4f64621e3371f6fd563f80324d142aecbf188127aad7885d07d29cec716009715f86c3018a9bd527bbc1c84565f67a7a92b94c35a29f1c70b7837e359b5e67773b115d67e5c5e4a82e03ebd7c2f569cec302aaac6e2a3ab394da869b6c9b2b60ad5e8d86310753b02bbef19ed84a5c04eb830ac8f47ba64b812a1b443814b0deffcf62d20542d3360df1c628da95e06a947893abdfeccad4439d7b47a55e7abad8a5ea2a20a75ae248fc93bd57d24fce5b9f1bcd89e0d5f07e28d01e5890554ebb014288e5bee25d9577ffec0044c54d8f2c9d56fe0a30e500581ca61827449149c5a519784c6af5797a10ee1cd5f269ae95cec25275b791a83b0206d0a3366bfbc9c900887bd017321f1f910aea187ee3659a543bdaa708a3c1fed6d0e0f18175025a4a8e88475ea45d1c490d9128679a65df93b24e1c48247735429969cd750f0ba9d290b9350c76cbf30eefd838493fc088b7280ccc5f0c92fe0388d789dd1164424af73e2283636b665280c520e346776922fa592cb5fa952ceddd89d7412f2c8fb2ce9cc079b7a04d33041dc0588710e553dbe510f5386311543eb45dfb5ab9096adf8598992ab1a791363be37f112c33cd11f63b04336ffa62c80ea5dbb8cd0a621cf817e301671ae108afe1441d6e401bebc31a9e4365af8419dae016a66cef51470ebfa64c56f76bad516d22a48ace528beeef58400f67e9bdea97cd10da1666258295c21bec1af045c1e48062bc6238d907c014a418bad39aeafc9a85700c0db7be96b63f1488e0d9aae259d317a17c6e2437b61b4f89258619165620ab458d4d0dd72134cfc9be37849c76a925318fe72ad6a730cd4061920684a53c673b9456ae651a9920e748d5e2948f9330b98313b47c81114f1efa6400d3da4ca14068d5b975d1bc5ff8ef5d8914b9756ba577d0d17e2fa874864acf9ec7b813ffb11f72ac5dc8b16333b739d89ffa5e138b5172011f6294defa2a491a6a5bdf7e40a3b9ce0836ece145d3fe38a9f677271321a71693505846bc9168dbb3c860c121297c7f3586bbf6954a5f704e0be3f4bfd7b1a3c5cde7134070b209d81b000298cc133ac3006b2a4473f03cdd8883deb616086012bcb8a0ebbe29dec5d47f169bd9ae1f03d77714edd452e9a7e03808d0012950bc2696d605cacb603b09753afa244b9b42d70029ba84c919ab261c11c225af0eff8d50ecfb7b57445d994ba29b201d8b033b8869e29efde72fb5c38c6456531229bcc8874d0914e4426a39a55713a538f100bd20764c1b1a34259f933ff83eaffeae374813a3759e8b3530c82814863c5fd8cb9339da36100513452b8d8270a0db5982512dc4f88e2bb72c232e1fbb9351786976d5d015381134e7453c2ca30b2a8f0417cfc87b6b82e241384e136f265d770dfa869dba9412d38723cdc79ce5b5a251faa7a7a0dd99aa161593c9c734db787d8fad866f325315af99e550a02852c117b2d5fad79dce481a39821134ef3e31e594f3b65e7d1e38ac1bd22008c0a6980478e3b475696390aa7cd83f40338cd2400b3c99c62d79d45888b5cfee1a63a99d613abb378e5af8e2b5c8d7b8e56db6a5454643567981757b4eef3232a49bc1f3147fdeae44784248ae6b19a9a6278323ceffb4aa31fe7745dbbfd0f30da8315d39d6ab0521fedc9f829e4e35281aac7c96ecb7cb549726397e36fcc4e786d30f9bbba54b433401296629fe4f7361a1efa3a1bd8d7dfcbf3178d513c635ac2d087a65d06569d1d23d3c2f7b0c49b540db1e3bd0957bb1115c1b2a34fa0d1d5ed5a18acde6fefc5f1bbde67ed83f023df07731c95cfe8767fa40fd5778aac76f20e1c2b0fc75469b03f05b41b28b1b727e26d3d4f9b41472feabd0b73abba982680d0208214839db2023f6d912718357bbb30d66120b97f048c49a30032a2942a4e89eb8244de159d7ebb31f92e10bb9caea60fcf8423d6dd5052bfba173e99db24c45636fb70d684468290342c32303c86d9d8c3f58596425275f56175a67f92ba575c452a795a6e64062dcc21b86ba5ff05851c527c8f0192a284010cdcfac06b6dc645941f7af6564c549e9cd053f814479ea7625fa6b78697533c544ff7518400e5476765c85eb041d26f2578712ff3573c11e97bb7a23c272a22c6b760e52b6b6a7fd07e49b32077ee8f0c1cf77ce23e9489998dc9376d6f4d575075fd49670465c10d31ee162419ae3517024c7cfa972281f32ee74d63592d7f44f278bace307d688ff430689d5d933ff0255052ca0865104089d5539b900e597fb1847a9f47f9183b482712d80c5ebe8d29f398e4cbab87cfbc24d176026ca8608b4584223192301e0e0067623a1d3c36a0a1ad87472e845f8c31dd8ac08111b27c3f10b3ce39d6ea8cd5196dace06743db450b424883ae4d9f6872fe794485a406359a61645c0747ad76c0bdaf5623a5cd350f6f5b101a3050dcde79905429941ebaf714ca5737d04f07d3c0378bc8b640b466f7a4da8350b3f62645345b635e37abccace74311d63074d9461c6b27073caac4f83a3cd1988c62b63dbe3971bc994b15652a43c39ad3cd5a292c495d2dd5d57434eaebd0ee5ed1f0c2abf93d075b0d70337f2ef773a498275b08050b0a77a5246230045603370c2533647682d2c989c27931a46b11d55ccc643e27f9e9451a22b05c9a4ea96abcd37b34f2c0bba39e033992f2e522e7f5b6bb2d66b1acd14618f18dca860cb940ddfdc20036de3f5d90d46122f0549dc55bf43cccb8258c068f2b69d0cc35306095d481b24d478e1e562408c8671a270dfee49249e58b2cfa6dbef5e6e2366a6b17f303eb0863add3d5510f9c847bbc13cea1b0957b67be051a07ad6f8c47fdf11b4ef801babe9ac7d23e8e58d0ae1f4b3767e297c84e579d2db1f69335c3dc5e52d61af93e79fb8550112717471e5241074e01a2d1e63b0cf0fed63d65225509c3bf7d84d876976f7ce72ff2ea1daef9418efa7cbbc2528e5d4842c6a706e49273dec0ad877c8922a2ae4e5567e01e5c44f4f12668c31d4e720d32ce5d7ba59110de940fb028b6a03fe2178491dda80c96f310118cf4edc5505dfbfc3e639debd813c56478e04a18e14f820e4f3754fac7f57ab0681fcf817e7f41f9fca9510a5aa30f6e15f20b65f783c895d04f81ed0cce82d5f9d1326dab4bc49fcf17f42d8c8c1b83b32df6923c4756f9300b9a8ab84473c2b88ec606f309731efa241daa1a57acffe97dc51a49db491731bbfaa2515dd8b5ad28d57a664795b55cb87f7005752d5ea18d17d1beebdf41ef6621de53e260341972560a24dd48c80b4778c12c11542b5a2b72bc07e032288d0a888f478a9445981cd8d78751a609ad0f1deb57f70a3c8fb96dc7022776db4d6b0b21d7487432168e4c627bc64730ad9b8c54313f880f8ff0abfe7694f2d24c64416698a599545510e2eb843036d56d9ed72e2364024ca77059109ce40c1b05ee7245c35aedcbde1d8b6308e8d814ce4c3963828fc361f2f8a12313103fda2ab1859022a60514f507ea2da9c91564f79e4fff5214cffa31a332310f869df139bbffe72db1c642ff05b5ae104ac1b81f9600c207ab71df841d9034177dad18fc446f2de9acb8f8f0304fa8b700ddefbb8ffba1bbdba8aabc9370365e8fc0d14a9eb0f2166112e6abfb38eefc025e9578ca2fb70436003c307fa2508fc1f1774411460b20aef7e9cc1e6bf4a897098fbc9c477eba44f0c3f14cb107cb00b75675a0edcb8d35e9d3daaaf45fbe6643204224608c660ca119aafea0f64437378b893e4531b0a31cd11efe6a8551807307bccb601de850b24517e808f5090045cf21a7a86fbda882ac972c35d0c0938375fb970b6d19e6b53f49c10f1292072f858637433b9e785168747dcc76924398788bce18763c462619e8d555f07c1c79a4c3304e99d53c575cbdb5cc08decd004b0da28f317ee7ed0a1e85e532fa5d62ceba12d9725cf3268474d245e361dc424130ff0b5afb134681b06914ded60e878551ef13d6cd8fabe6bbed881c168c89014d244d9dda8747d7b77d308fa1f8115d6ab3216d829670b7051d8c36353876605e5beb8e65d896006668c918610518dd32bb4e20a52e08481d19b7682be2615fcba2b418fb980dce72a3f2d85aca4802ff6ad861b200b6652553819ed307fb2cf3c4b66ce2d81febb0716dc3f7882191a4dfa3a1a59ddf8df1bbb8ce375bb4b3b6b60de6f0492ff2f4b0423849fc3237164c033fb3687eac77c58a300e5bc0a909338fcfe2b0bd298ea0323ec406c04c20acea0d9e0eb7ca3003b69783a825fa4e99d67a0d7747f7897d84d54efa558a4264ae14abeb4fe9b52694956b72dd740947e004cde7bdf5ecbbd764cd1b5bf18e8b99d4827b6278209b24268a240a1b78c2f710b0a033921bdc31d1f89904badb8b40edc5ef4e7d8041679a1841699e7193e7523c1c0948ac46b195a9e2c8e308ffae0fe5898c951d8d25f14b9455093210bc155ff4c00c4287fffd9bb3d7ef2e06419694faef69200e7563145491d736e26d397036afc76254c7fbc5123480bb8d40b850c79eb7638a9289099cd730d303c9841ac4925fe6d4b0e8e84bb44dce5f526f61c914062f19898fbce8654a58cb82e5161e7684165eb46a54328d0f83a311d98f7835fafda7ae3d449032cbb7981824e4e8200c781fc6e88741c613b856cd927761ffb4d679dc31a483beeb288610b32c5ccc42c3dff0f9e65ec7ec4aced5c9b115b2f15d216b0829d86cb5c29a5c401611ba8371bb9a8309b40df69412e3c982f1572c3bbb52cce924e4418097de1247b9db7182488e8d8924e07832f36f77a82d8a49fc5ba484e6286737c458d48f0c140c7048749193d2172033e0dce65d15463eab78b6191cd1d37488aae14fee60daa8d2d27ed007f004a94feb383de2919a6ba3377be2177e57957a8209d03c757da4a1274397e606df95f5e3e827fe1b7a943467223a3cab09f74967bb826c1ffb80e32497716a70020b8dd2c3da3c68f9c86ffc01c14d0b26f62a564848e263730e3513248f1a249ae9dec100c4871175de2a17547201d4d82f0945724eda3295e0a37154d81610586430612e365dd7342232ee0b7ad136d1b56f4499d81c4da12542cba8230a48ae6c29e5aad7700f7005769b05b1fdbbffc7c561c6c04cde566fd995f22bad951259da397d3d4f073cf9285a7b26c290426d07d53a758d883225c40bd7ed993fd3e91809e4c87d468fce3bf38bf205e4680883f52c0d329d37fe45236be202346532671d0461ac48a7cf1382b00f1f09d1bbc71bf3ef102e0501484800c27380c4e72422c9788b61a4d2bda8abf1363fb75b7293cdca2213c5dd5a29a4cc5d99cbfb666d81e88064ad129e1020980a3b7e7ef9c4c4253f1e16086ec05a1cb6ddd77c0e74184a4db2ef3c37b48a2aea016683e4929e165a045063525e5f6f7350729e7e9e699861dc84d81ddd6ceed10a3b5e0770ae672fa96e59ca90d599b314249bd530599121e4da7618438c6c78ab286f0810717ac26f572764e931e1e3375814f6fa530f3f37e05517a8ce5dc4d3778645d167397e476821dc7efdaf74f7d6ad6afd2ac70f07dbfa083f478acff99fa028722d2cfec4dce2a40fe289a6402e3232317bd5643ad3ae22e92053401b221e9ded74508ae7091acc9554b70e0c6577037d74f71619a2df5f1095b7e4c58dcc805e47a9d1110c7145841bb9b849ac03ca2ad243572eb2e21ba76c021522bec736260be63e56867d02190030531bb53d28614a03d1ac277df14ac0804a5c0c4ac893ddea2fdcf990f97590b993cceaec9759e4846ca9c29129f84edd50b51f67660cb9d29b5db884b22bf3e5d892deeea16ab93b1fc267d34fdc4d491f315e9e228ca0ed43567606d36b9bdcfc61f34afce8a4ef267c93143b6471818ec5db54129169dad331a752fe8169ae1918ff8579828ee3c7a255cc781615719443fbd46f675623795a3f6ca5bccd4f66f5c723710018b4b1745e2b4d3549dc78b0eb33e534d7c821ee2394c683f0507a6dd0132792fc3b02b57bb098f00a4c76cb8a8f6010d9c82ede3c20f3323bd44919124f24e7ad6e27b2f595c0ec696544cff94d1a2bbdff18191e291a40d14d08dec208728b0a7542746fdcf0fc476e2d66cb7b7a0514d110f949bbac09ecacf33c9d93edd7440eca91f15aab1e656de94e3a28d73bd4822e164394a470445a9f3e35c09483addf31fd41245add9cddd3bcef51d3caa2533465761c8c1b9f03bd148cbb5c1a9a7ba2e4eee9790b47e56b5375f06e8e4f8582661655be3cbc14a779c85f942439712c4260bcbd0d03bcb033eb57dc0505395094bc0fc35254d005571c639bee019a62bd45cfc22c37c837e997c3b0faccb445593e566966e3051a52362be0f06ec428138ec2901a6a27f8059fb55232d4efdf0dd5a56c417fb97daecbff63bb2e69e3e26a3137947767c3802745ed066a6536dbdc8a73f59aae683716fc1d6f2de8b9754466c564e90d2028a204a2da7a8afcf280d7d716973e6e12d7d1bba86fa44ff81a92985cbb598aba69017d41b64ffb7bb16b4fc20f986649324e09221de714e756030435ac3a29260aa61d9fff5a73fda7b9faa25d0c7d798cb37d9353c99d1f83e25fbc44a14465287dc94a11b82448be8b03a19824baca5079884d4818c468a0b36cc297e81882d226131c7a4e552b6367bbfaca99f320422286eff423528ae6517e60252435d7ed930c4740a9049ee48d5ff9cfe42c34000ff7275117327f96161845b3ce9d7cdcb5d0c163f5c2839c83fbfc6d8e101435ceba567c90772cf0e2690b43b4c24f551a267e98d9432666c5d4246428944c932f5204c8cdb4775dccaee38cc7b2e8d65d7e95c1ea4c4a962bcc0e32c178c7803a82852a536088653dc0371da26cc5ba20adea112542bae4e9e944b5976ace90018aa48442f7e07e1322f734b72eabe548645d1fa70573202447fdf99ffa256ad0eca14c58f9faba076e11f95d7daf1407d0cc4a3d89c50fb8e1be3b325c2c1e765fbc7719a0279e954984c16e603d9bade8959e1df187af9b9e269dc1ff80ce25006a5b18a0c809520ee5044fa023a369cf80ff1adcbfe1c8ed48bf0cd8320e9e03541cb30a1bc21ff42ad12af031a3c66c10932075f3ec35d8c7235f73430304ba658e344fb0c7d5e2d74390df0ce287b7d845ded229ded69e370b30a6629d0aa5e300c66fdfd9240397ff7081d0b2d7558c885b6d450336ff722334bc6f096bd1d84aecee9404e06b53f26d028a3d8353493024c609a3751fcf66e6b1f18943b7b82a28a0290d6e31227f02514bacd92ec4b0b92631b72254935de03113cae69bb11d2237eb86e5b3881005009ae8a43823d549885f972ea91334724221cd7c6f9181936f47f1585a4eca0e8f86a4f61c25ef5a35cacedbbc06ed00ca4c2d454050845c55501bab194382536abbd3e20ed8730d07ed01f30305716812de81ab9bc908dadce3d7aeef357baf679784840000fc16dae8bfe1dc535bec61c522e59c1d583f03b77f3037c1e2cbfe45a269ff8ff6c12205f926edd6763f4db4822d1c064fe27a762fd508acba0f0013d6957c435a449408a015fd51f0a2308aa1c10cb3bc178531707ec8800ae1d13d10680d07dc9b3e289ccf66acf0e4471bb66ef504c815bf68ddb4a378001ac61290ceecbedbe4a1454e83f59e8a8ed626a210a232e708149c0465bb0803f4cf5caa6f89d45a966093938d255bf63d1cc1510e1290011fd71b0550f017a7bb199803565368a54781d21d47d15ced604827db6b0b02ad0dd54401ac645288c3c549e14568e353e15f79fb4c64e7e869f2074833302c0400c03e8820517832fa2b4bf825af38d730d0e60d3502d39f7d22f86e077bf5b4718f792b1edee19a121ec7994d7829438809734a5cc54f84d9f584698e70f7374c334759b42fa87f3575b8a0f75ca3fcaf63e603e3521909f513258f243c3e21d290bddcad00c87fd716aefbdf0acc2c5e5b059a4eef27685460b4f384bb3ba245f16d842afa3a8edb2f8664ae057c492b662cbda5f4c5c5bc178f6dca69212c4dad57d2ff2535ad6509d7f5c080da1d9086ddc3c2ff4cdd1b154c6ffe3e88388e3ef7b185f7827d86c3118ca939e697d8ffa8682bba39f2f6174723bd9278a8cc2d0353d1bc2c6c013e8de8efb7cf2e6bbc4ce47ff7ae92888ead07d8079e45b10edb4321310c4cb2e32077a83f2fa4859f382df9c0933c77858ec55069dd0bac4dc3d33486bc197f52353a92110a402042566f9b9a21b278b99ad320df7ebd895d1ef886e13b8f7cea6d5f804df290d69abb26f3fa01445d810ab6c984aca7b99e38b32ccbf69117a07bde3917b451f4810e2c324e5ae7cebfb30b05af6da96431140336e2875dc7cde7f65f7e9908ed6ed7d13afe6e32b0975a68dfd9018b5c1bb97921a1bace3530a960ac77d968e79cff8269b4108c5a1d9f057c1d5852625b0f797b704a803679e4a86c1e4d6411050534bd1fa5fc53d56a05bb992c23a9d5d8bb0a1e50b0c9117a1538b1610444af91d05082b0040477213a77c2eedb5b5f069d241c5ef02187919d72f2ec6a33a11f5456bd123b8b21cb774bd5626dd3010c05999e3dd6549480f0ca2f26b872984bf9192205c94a41a38dccadd139f526cb47cb573dfd2c9298b8cafd9e40b6d1aa72dc46b1cb5546edaff9d4e2f6f55f03f428b9e8521602745bc5e72b860620555c3adb605080fa202929553cf1299fcee12e479c75f6d6f3c2f1fe2eb036f323676de4e291e97e0a1c5e6e1c92002631e91e2030b9ae32b933a990516856fc2c2398078a3d0b51ee753fd8f5fb9d9a44f7c2cc36e396ee338fe7a9738ad871a4dc6ba5ec26c527da007f6f3cefc76c6e204dab9f361721bd6d204ba1b70bfb45a0762c8395de35d1dff5ffe457a23e8c69afb979cc88bf5b85f2ef93eacd9514c6255e94d2d0f4c8b3bb16c029d03957ff8ea35808e6a4245ebfa004f95eb122d3da58548875f9765033c5e52a8ad25b3f5eb1d0310f8d1374a0271a91a34736148beaa4f49112f7ff0d54b3d1b65833d114b28294665552730c4255248a1660356f26829e88f50eae7152105c042a87a8c69417c1b02140cdc183e7672861e7e67b934510880d3acac4021c420dd02488c369e0636133d4ff521884927d06b7a33a6427860f8884ad8d73f56edf66462cb3913e683bc37ba38705a2c8f594432850044750f5a2ef342eb94203dc2192c19f35abf5bab61e0ea8986b41fd8ac98d47280a1ce0d802abe2b2e2815fdbbbc35b340b4f3db26483502864e6c15d42803c3575a64109991ccfef6846cdd8fda95b517c7874ae998a6a320a3ccd3e29c2d37415841ec1c5d2b20a1389b4a820a1a8e068bec8c5182ed60314375c6675058542223628cfc30c906d44be16e4e0dc87e1ce3a1a0aed480ef2dbcd2276221c8fc090f7ccd06bd34214e36d4d11119f15e8fa1ff9fac668f4766ead8b83deff3c7f8fa6c4ba56f8de2bdfc8979df6cd20a9fcb908133e6dfa5bc9766f67c95e2c4af040105a4850389ec990cef55dce3c833352aa11ff9f06d089094b778fa84fd918f1f53ce1902152910240f8519b0d5787c3ae9fd96f72a4524b6b85f0dd1fedd3db005e4922d2060dd287022800c3cf8ed2ce578f20bb2630e49674e34c1eaefcc875b87c3dc53736114507e0611e8f7932dfb5f9b35898fa01b541362f84d329fa0ee4c1b6933a05cc040f78d06526ae999ffcefc80ef18cee9df275830b6fa54ae93e5414e69a29cce6402be5dad1b0ac59fb3ab01a8b585936d920417efdb771b249fcf2b01d3e572de5e8223eb2ecd39bed5f3ff96961609569d59b2115ecf2269122c9108027553189acb6a4e40fb58b166fe9f2c8400a0d47fd13ada33437b74a310cdb91d23eaec9fc5a8351432c695560c780dcf7638ebb8a3410f292cd2b8b639b0de218e978ab1738a50821b6c195947e427cf1ae062fc0ecc30001f6edda63020bdb33a36093e4900253476f07e70132c30397abaf159cf910019f1e04ccae0145611858278e88d5f67c0916707f7375be868b4faa1e9791a4a6cdecf400c6644b8294324a1af66ff8a5a9842aff1755b241e34806ae14e27cdc84a491652531e079ece22cefc814881b92feb96e4621bcda96e8b52e139762443c7333058cbe748a57d38307153fa6f1eb5f0c78936a4a052e98c9a6d3290d203204acc81bcdf267fb7892c09aa4cf5cf696d02648edc5f3a2b2d1134749396a660014c635cf39e54b73d552180b9fe22e40534a8e320a0cc1ed36b10485bc69c678c1f529fcad2072998bf8d5d3c520dac540e360d8cf9138939725f7a23ce9c76cc933e2f76c3895a162f41797f52eede007d53c9a5f0e621737d1941107169281c6a5489af3b5473bcbdf96fca898ed3549e335d940a4f960b3069afca8ddcdcfae27a1fbb3f625e62b39703329ec6a4ce135b5eed6964ae98a3d98551c563ef296ced1bc672d677ab2f3b4901e4a9d4139c5cd72bfb9694803b0341b32f84d101cd409b4db02ba285f8174b0fe35e51d35bba4526be087dd11636ec1646408db2050c29338c31f88d8b1aab0d6140a42dbb7cf21ee89b7354b22b99ff275688a8e41fe0bdc275e9c68419f95f5df045b286c36f6b74cffcef4a148ebf1fda2c942f46d0d7a3d7b034a82dd5cc910d22828fb065c1ecc45ceae6cbcdde80a501eb63c5737d91d34e6b339a22d9ac9dcd396ac3d54fe0b5e1f9bc7cf5259d67391ddd11fb6391381b14bfb918ade53c4c5535ccc82006e4c7b02fb7f6474ac7c84c6f4d15465ffc05f0b9144f50a623a19099e071997bdf183e4b141ad54f038419dac3055b162b02201c9035e9e494253b97071ba9b279c5d6b8e39beeb2721cf59f432df7a3a15d7713f81850679149e02753938f6909e092f598ac5d93d9d9f85855e00fde40b6d40eb6f924a45770d004aeb64d6110258a0b787cb4a3a0eff08da85c764253a154caeb724b0bb6c2cd4011a311b556027927e282d0c00739ab6735b13da59b94d51ecb2816c886ad7d509ef8e7365f09598cc20660e5ccf36ca0c1920acbc7e68503bb16ba51132810ca71febea223553ffa61b18acb064e7e56a81eb67ed131209642827cafe8a8e17c606474a8a728a68ed524a821aa973a3a461cc738040261c8a2112598830e19d177b932d077fffdc6ffe1bd1a0056b93ca314ec48f9b718382f2de381a03c7e895d6291a7f536c139f60b380eb19652006ca0681f7cd3994c29c8af6d2bddc808ddbf54c4c1e4a731508ee2984ec313347b53ac3f436bfee27435073af58177559769af7f651415f8bedbf46b9f50a29cf869ba4af49f89b8f700b6f96e6ee8bf8c3ab9cd70d039c8fc2e1706b633a05c10a1504c4537b7d0f1f1103810b92885c0f630e0d98ebc9b67b0f0a206b78eadf8de013c4e34b479bc334637a100226185b469f1c29c48dedc7878c3c7f1493b0dfbd467c282b6de695854a8dd8d0085d7231d446a068622d64998de18c947ea6a9142fa91aab1204cf3620c1995fd07ba1e4e45358c922d43465898fff6990ec023ea38e85e812a808c60cd3ad1f220080e96c33189aeab075038d44ed08cd7ab81e5fb7661986a98f3233af6478f872115339860802271fb2265c80ca992076878d75dac39098625e84756c2ceb1117271d566e89a3659993f04209e7e9bce80f998f5d8a211673f45abb630202e8485eeb13c9eee22e8d6e38e08b64a3c22fe5f37a63ae5409b4592c20e1bb80ff34a8403c118dd5e4f8adf9644d7b16d470e1829e54af45d639226c72d1a29b7149c09d0733aedb16407b4aba566b32e0040436d39000f574a459e931a26330b7c2f66d7710ff0e0c118e201b9569ba110b1377cfa80a5083a1414f23df67cb4c982259d7e472170bd9258370f0ccffe472b06ddad359066da030bb8515f59b7a5ec06a18014b4d4297c49960f329616035f98103e6442c13721d6cb11e706f5b3bc840e51020fd8d15c7c03e017ed5718d4a1693a8d9617422d725d8c9cd734481fc8d80634604858702b8c85afa945a75e0054ababc6218c8651223cb3644afb55455e24ab9a3fd5e237f1ca84a6bcfeca2e29f998943d416f960183bd3ea20fed9c6d8c4fe9525889c0d362533a6b56b9f8a0099c1c0d39811f2c9fccfa095cdbfae109a96d3369fe6f74329d711179a2b9e101e8de5be7ee3017751e9126b3c1c07d312ff323705de24d0b9b0ae95a485a54443232df5150ac22e021419f20d96d5e577a895918e5d952b517994246319c7c9317978818f9e60df6d381cfa87e2ee9f493fa5d710b6246f26bf4714aabf0957f7948d4a2aa6b56771e3e5e60ae6646e3f2219cfacf0b0ab344707e046030bf9c7ef3232736102adc1db4761ca62670c663c8453c7132c9f9ee8195d39e1db9bf6f7160c9a14f9febdbd4a81ceab1066db6777c1bd967182aa0df725d2a32f711817ed30724be76923e94cfa09e3cc46c1bba5518cc5960d1126c24aa402c86a6762aa3a7938561d0dde9304145d45ace88facd90ffec0909881a6a3eec09ba716b1069ba34cb95d6447013dfb5b1f5e83909dc9d3a4648c4acedafeb07913aafa932839099043ffe4d45e8bfb78db805ed33e9d1d61719e90ced01035a0ad3213bf77f3ddbad48689acca843d32f8fb7d5d7cd114f5f67a74db27e1f00479c46c98faffe756eea4ffc8eeaa938727eea51577c07a9041f8728e12906b8c577cb537d31e066a8917faa2fa1bd99fdee39e7fd4bed110a5800b66cf55a82b85ed323e5db0198e3d836a80797a4a96188587542087af93873751b3411fc55d415067c3b9aa4392564e3a8f4bef99a4f4bd42995ecc38c1892bcd6853c7b8f772679fc473dd23c642f740b4f33315a203e7a5361ee27bf27c1f11a1bfa875647ee6f479f52ef477e2e646b043eae8e99d0b906623f00c9e2dac7ae89560e69d79c220350cb01e250b9b5c2ca9767b80fad11f4060d412490b2fc10d599ad39936fa05b22a5e9b23e661aad16518f70c3511139653da9f926c81d7fc1b79fe521f7fbf64705aa07b5e866981e2b7d395f9ee1f1582d6019ece8bdeae0ad744adf8c4bfef6ece6a3bd80619719cfe216c4053a6e12965e9b8ee3c64ec1f87344915fa259e3f52cb24fc3be699a06e68ea01006a12ad188aebf68b6187eea698c2769ae16cfae83e16c62d7b7e7145830de10a9bc91cef9bd3c0b0b4a51a40c6faaf8da299d221bb0fcd1d0ec12664fc5714dc7bba89b78f70be19bef52506a8d515c7a9e6d8490dcfc02d63a332cf07ecfb89b6f91df9c0f406400fdb5041cf3bbb4da8a1b87bffdc9db3cf1fa666f05c848fdbb3c49023f09942335c416d8a8aa4bb7ad38d049c0d3892495677f3798d62e0b5622f9eeb70b334ade61ec2f565098a006d460d8432879f8c855a13b4eedace4338bec18035d2e1bf48ac898b7672152cb7d1401b6118a9683bf693a19ad11d69b0d3696572abc8df1db2d18b8eace131ba73a7eb619dd3106c066db9776ebfa8044b618e26d8cb17632932a2dfce61cfbc5326fec1ebf06368076ec176f288533a69c28b3fc0a0d0fdd1febc36c7e8f51c6183c88c1b1b0216c7477160f53430874399ce3046de86f40504874781cc3a436432cbb11762d82135ce93c5033f9cab93fbd86d6b7e74487616b5944bafcf0e69c166967bcdf9b921310578cbf9a0eb83c0723d6116d67bc538a0bd2a1f5ca621c1f742466f61c3ef5c8773c4123fa6463bb9329cc9fb978b23ee8d431caa290c0d8161f01ec1316e2c68c03c8751b39a1a56d882f6a53587615b8473ff3503f4cc320d6b17626bcfc5a9160ee5c8c2781210e67da40f95cc4aad7be09a043ffd8a28d6d517ebd7df89c75dcdf63cf955d74e5e3b462f5c54b9a95403c793649a5bec6a8e59f930eb1bc09c271a350a9c77b911ad160251bd15e45023f8c3482ce04e72cc06f4b109531e02513903880f8f2b545c367e4f23d7e7da05af523eb7c9594723e51963216ac66e2183a9c6ec55492ad626a8a0a8e8b18cf7db8950c0d9b7d8b63e0a057da0c2d90bab222774f37a6709f8ec8fdc94c72befaf39b9a7b2b3a49234e61e7778f87edffd3e6e7ccf6ee07534330681e077fdfcaea8272134783ed2703cd792d78e4ab34db7fb0840b910c40cdbb08d0b20bc0cf161c2404d07ace3c3431210ecb147d7eff1a0314764fbd5ee7cecbd199998fcc193d496d96e23ed6dee054913ac8585aa3ecff4f73e62ae07c1d40bb40d62d5dd9ea3745025fdd3e76aa047c5a27d9dbc3c42c9feb1a42832a4c4a2184ffce6be0117dd93e5d9074577f668a633f32e1c544b9fef28251658a536b6320684b6a8549115a99b4b1fdbe0befc78b487e5fc35742363822639579300dfc072589f83a1579416c0f5e770f0258985ae7a15471ee083dca7292fa6ed3bdc8fb831d38d555d84fa77fcfe682cf42058ec0f3cfddfe7bbe9ef5bc00a17162b93b4c06a0e9408a259f3d1f5341134d1aaf81a3e8de301ab7be9238e9edd1f64a29866aebe476fe4b1f14376dee1ae82f04508f7cb4fe8a6613cc8bb4794adc43784545b5f27b39a1c5c040433e054c7880567bd6665a8bf2ac650aadddfd2419ba88ef8d426f77ce3b3d3d97809510af688c483753e9028be26015eb5a52ff78c0615150b75bfb1b146f66d98d0e8b4604497893d75661d18f38010f9209e473516a1cdc4173fff6c86a9dc00a8f000e2827c88c59d0c30024f4aa6d376519e1c92c9da8a2090381197b819ebab781037770565d79e855811588358f59a9939872270063a20c7b9acbdec8d85bc77ff045470538f00109a61520aecf209c02bc4d1bb23d2ac061948f3aee73a7cfae2600b7f09dcae22a00475db6ae5792b92151a566f80e20757af11ba9cf37aa675fc956728acbcd2835215f9bf4756987f4eb2550a33b643df494e5ba1cdb869b21060321adb902b579a37bd51c11e1432e0a3f28eb48ba0a231ad3c5409aead6a6d1176e54c61bd8a260e6cf9e0c6e07908ce88b11e12b51e5c84fa7a0304c5baae23b00ed0b9704ac4877d29eed554882f2ede2886338355aa4269101828e46cd3642b2b18f12c9488567513b96f6a0b7306d178330d2ff348eba9ad37accf43657adcd86c76c3023bcf9397f8eb918ce97cf36b95e9132dc5b795e70d5074c5427843c51bb45be5fce571cb495695605a975155793e8ed26e5df0389d1b33db759d64be785c01f0040f097193a9ecb598dcb5918bbb7fade605dc36265dae8a25abf31af4e52a0b2cd0ab2120e0f45c3721150d8e49ab4c3ad132f2a9141fcb5580b51c0e012009023b33eafe04091730063c2818f6dfc9c439e9fccacd50d11e8b1928bc0d4e7bb1e3fc152df44b08b1842261dbdf704e87a8ed2d2ed21bac3996a807916953883a260e33aa3ce02ff58fbfe58ed95ad9500f67d375e308b0a049969fea3b3ed3e04b234a76a647793f1d9df54e7b64179df3eb24f289b1c564df1ae1241d3f6d091d4b307c71b64892c7204e846f880fe936f3b22e2c84d84ecf433bd0e78ce5e8b8c7bc6c3af8697a87309fb6702ab92226ec234bc941436cf2dfeeccdf6da819c21bb17c4f7c91df64cbdb706e4ad074e82e16343648344682355d3f8395b6c1b21cc572687e574fba61ba6695d518772a3910d93681ccc108986b237f5a3b4dc9474cb5b47b9527e90bd00b80516909999585b9d3761435c880d41994910e2a71ec1b47f89359d1acae0cdec3506378c5067807cfb5705ec9c818213b72e48d071ef098f2fff5a3ef31c1c532173eb26b93ceb1a3644803e329563717d1bcc09e0feefd5676cb0176e55ef06aadb363404149645162c6820be0d7b7b20ebd638a8538f4fe8d01ae8f56d68e7a6a18a6078ec4b59b9f394d3a35ae071b9f76df0caf22c7c7783534c081f34d03384c29e05ba82f304338574202cba366c6d3f2b6a0eb583fbe929f6d080409e1a64362276364c11bfda483182c7a1d0940f665e26691c69570d4d2d6f9f891de28016a73e11092680ca4396b2abc65482b8ed3ace351774e05e3654f25908bdb465190813264a148c460b2e372032e57d49863d872de3a2c021391cf5aff3aa447446c673953ab0bb84416d3c972015601e1dee302bd2724b7d297c78b4e406ef6c809a7674ea651fe61d3631337da87142282d6ba40ceb5d4018744699cff62c1e60ff4340bc04606e08ad36cb005ebd259966c3dba05e91119563d56efffa2f5b786cabdc98aa4550d07519841c6874698add9c2b3f20a560df5d060f2f9d8dd15ad07886ab12990877b38b7c9c35b04017a6c40884d48906c0e48ecf26fc0c6fa9244d0c54aa3475389f70f38b058c9584be3b3169920b8cb71490acdced7736d22e0c1eb84cb2cec54be0de70dd2261e7155e9f9fdfda61c10575018c84b86e06f86eafdbb72c0c3172146cf3238db780e667b2e750fa17776a6e324dcb04a818e9f8d1487ee74649bc8a554365ca357534d2cfb287de78bfb83194c421a9536ab69733834ed3bd2574dc3d7d0c0bba0e0cf4b67da61d527c3d3841f5b3cf5154eb2441f5b8928ca583215ecfa2f5123fad4ad3d0753ddb6abc89496fe569fd264564c41da9586565fc1e24ae69c2cad203ecfe3d6c94074cdbd7fc5675e64ac1c6b20ddbc602e132859da7f057be5f519a7db2c2f273d7462521b017156763d2ae2e3e5e4fa63cc3d0f4b3b292dc84ceee4477479d3cb448176557f57c53042234ce7a85d6cb45e1ab10dfef097ad0829c91442032a960ee764ebe53147bcd3ec38a097c6ff96e473329169a0aa93f166b056072a2a5e4b4baa5dc9a4e5bc7b7e3c459067d58f392f7aa7338c2c94605a859c6434e0be3f1cf4a9cbe20d249bab942d74195930aea81d68ee2bfb1a963f00cc6105a6775753815a5531be30c5d01b1ba0797df1027875fd30d3082739d22755f64642fa39a0a8e5764926a012e7764659a5e8a17de069be59a836ec9ac92c2f212213e60ee8132abc285865ba0e3151aa800de5e9a85fa6adaf6d7078958229ac63dc0b47653ee80f06bd2907798bfdea8db7b56d970a26cdfc7fafe0f1b93a8a1cc5d798218893d2242301f6582c653a13963edc64173fad4bd4434ba97bb18791d1d31478506526bcfea179132b58c967be1e3b345946eda63c0f867b45452dd003cc0bddc4a8808f16cdfdec00c23e1fb76a55d662b59596936666463ed62df415ef0cacc14c0538ec936b02a602cd52c5cffcf1cedc8ef6a5beb6586550b1351fbf2cefdf9cdd36ee1c4dfd32c3b0cb629b5e49f19e048789556225f972812e4d5e639164daf7b57f8597adb200ebb5355839afab2c0fa85f6bdfd02b8545715815f64bafd379c63ba112d8a639ba91e00fb9d3c866668acdde1d6f99dba0de53ac4aa968f81469bd187a57ce6d51584e4c641620d79545c84792bc9a9d9cb5d5051739f7e90c9893baa4b2088eb728cfa3be674d9e3a5f136d448d8a96b27a33e33b26a0c14fcaaf59a9cca845e004d4b0be56e6b7c9a0f3a119f091ca00bbc47a2c8496749189528c8a1a3cf2705485c7d92d53e6f1e6ee3f2777f72bb00ecbad2998a39e9507376a0f79d8d91dcfdb8a663ba9e947c04b4e99cfe55734ed79b94fc08b72789a2e32da94022c7fd17ed8d8b6f16e9c11118f5cc0ab2a4645aab014b2b65dd52e357d7882f54d371d84789edbf8c18ea859d7ece8721d4fe0faa92d48cb8ff52f3d35acd8063d8f33a55c437fccff7347d40108a1834749841c162f1a934f7753217746141010063c395f230b5bad92c1f2aa299a74deb4547df9c608333674fab08666c9b06036956dfa1acbc2aed0ffc61db988b4c276e802a28fe30e2c4a4aa3e755e18abb29e6e97ab1444cfc91bbfc2f46b0816a96023458ab1f7d4cb5056e24fa7940b06ee03955d0ab2792718774ae52a9d47724a870d07fbaf0514d0010e2d563ec6801d111fc5079aa58aea3493a979e6a550f3c4e6f30d3425a6789ede6b268bd0c118962b1c8c2955c54cd2d4bb50ca2ff6005d5c5bcb712eaeba9cf14653bf74941ab0642fdf1a42453c339987baecb5c63ca57eb65154c1d57f477b3d0d72b1be7adfe06412ba60c1df23ebe708f2c953eba65c46a51731d17ec4a4cd62dda6d5dfb0825817fadb4f6d27f51a91b445b462f6185858f1fc36778ddcd8680445595f0fce76025225d830745c6ac6ff759c5d9010852c540c36efbb6faf8995a5ad2f1318525665984a14377ad855e5f6a7ede6568babef1b3c918ef7189036d0405f0b5cda7f8c3b028b3740ada00e54ae6ceed5790e523aa5df903880e79a751124f95e50037eec82312d4efccf28dbebcbdd27bd6d8566679093c17f9c7e06c8630df870acc9c4917dd05cf9d04d5cf79250b310046c55d1aced1b0c6c957330d3a84fb0cda72310ae166a57eb67c2153a0ff5851111dda43b5c12783964dc50db82b6cc68f82d9d2e6bbf0408a2321f97c3f61db4e47840f8f20f4622318b1dd073139a5c7ed029063a82a064685116ba67edcb5854bf476139ee87c33fc66d620499d720a63c705eef8b33808906ac47183ed80c1896a6c7da160d380eb24fd9ad73c4841588386c4d6d11f8b0c0b63f7adaab24fba47a9131d444365c950b4f9f88054fe0ad3316449695a0a94bfd65c723f8121f51b13b04342858f828a29e029faf505d77eb988e66e839a05f3a6f54e91a35df00bded656ba0d7fc8f8455df8851024af36f116b8e7fcff4850cc1e8bf47db1f102b8b6f9466a39e3d668aab657e7e8470212e0343862284e1ded227bea48714c4d0358c2f76b4e51e0e030b35ee844e2db70209b068ab87c4823537428dbc0a70b601000b4c39b9156a7e9de944f5ea76bac25ca3f06cd45bf29a53234144a0c8f030e9797eb8b9b3983408ff77a0fa7bd6a8fd3135f5d3468c2e632d9574d666173b02d119fa73e1715c3279f66f36e4d46259563422ab82dffe336d11ea59ef8f826217891d7aff3540f4a2e8e30750f62c7c4a6e2a73499fc3a99b873fe06b42ae7910eec7c2f13f9cc63d8afe76bd0822fab10dd07d753c1f0c4c3a6ffd5cbf8f5bcbe3bff1a38dff86c1300dc01632ab49ef11a914ce38044a47dab8780871132d00d782198b8181770b00ebd74c8062405417c18f5c76aebfabed352c6f002d4b9e28c04306c9f21850b480e0f9cd94872a2e12e18f099758718f974906f02b6f280bc498b316d6076e15029545404782df676c97c95a9d408e2fa8bed3872d6e330558a04124e999d677a41c6fc7d23405bd39584dd6a7e25a42d79bf5102423f96407c82ec8655014f7e8b18a4719a94194729030dd60fdade00e1b7cfdb234f1e0647d8dbdb973520871881311926daa6114a26e18b7d2125d37eea0507e7d69a2b09a67cd6c974d708c385be280cb401f3c546af243a66f67bb33c0e54f4d326fc07739ab960508905216061f154ac0c5d2a67b8cc3767c5b502ab75a92cf294e0daf372523ffa648341d2e4f3af0d26b4251ba1b0e00fd6f99fafe925068420db9eaea124fc859d9de13ccff17bf661bed4f2e73a917cb236d54c876b584a288a3772196a5e69fb6e00e52e4ec2da149ddc87d06f3bb067fca2b6c2bd037514d388e790eaa2a27635303fa77001cfa8120013b8cc0b6f88b160277a3f01f8faa63b2285e009b8ba8ec14ad739e569d40eb8f09c2a02df8522bdb4240cee4ed98cc49dc532dcc409e464d840cf97f4ab6a89154c33268e8a36d08daf347b98d9ff114d7501ec23f1c94fe3aee022093d45c5d1e92d183c168c881924f3250e42d50f6fe0a52040a18c9b7db97f2cbc50814495bc476062febb7d40a5005f9f789033fde98fa8850e41feae9e09fe7928fba962486d380aa56eda82f97994785b5c003f4d32a92b5630d3ca043b881cbda84f8c1b7a7bd918ec0b47dae0675d7d03c55f409f52404eca5f59b023b96e87f062557ebbb91a22041f892f352c7c5fb3bd26425e0fb6d7ac16075af92bc24663e74925d9260acfbc6b202bb890e74dbc4f3b2227818c30922ca1f1c4d51c264a55f2e05be353ffe933965579287268fe7cb01cd4a48f792cc2ffea82642d7e8cb381b01e1e1ecb268aaf273ef3a3e27e92105e7a771de7ab3c9411537e9889743111a6a3f1b39a75811c94568e2998e7f9750fbf80a43f62b3e9c0d7a82e24b3938c3f9b39b5a2e88ba36083940a8343e6cbd811410d0455d63024fc51b3e16e014fbfde8355e9808c74f2581f22d9c052f631296334ed98c455d5fa7080235775816cc90ea93d1621c675d11d9a8d847506d5814c547347c54086a70051956c22a68cf0d87d86218e018eca3979b68eb97c794e0d567def8452b1e2f834506353d5bf25421ec445154a472c7a76fc5cd4cb24cd169eab5687ce00d53bea055bbe21c3cf9e354532f83491be8912e1ad0ac9ad80e55952d659d62295bb04234e71c39e4754361fb12b5e17fe599b91281030f562adf1288835cc822dce2d7f61ddf5690c89e694cfcef90816402dfb30167e21f8c1d9088d567bc22ecf1fc2eb3243afbf10aad20116e1cc8c468a5c2b7027597a186bb358dcfa6387ac3f75060db38e76e8cce7e79ad932cffc5a019eecb8b54fad5a82a891bb43c67b5be3af934ccc30bb4be0ee5fcc5751f8dd2c58460320dda434116743b191d5c2a421d72efe38a9021b3674ce47b133b12685ab7a7ee36e584d6bb508137ad4ff6d9dbba82ba8a626ee59ceec9e191e03bfc17890641e03de4562f25a1cced6d924c28784396ca0c3b953399eb03cbea6c21b4284f87b9c24a6d722e4b390282da7ad7c0d8bf7a501e53601fc653fe62b0da2503054bca3c6fd75f9a327f0cac18821c3bbd26a200798598b02e5e31f5051cae73a934eb3cc3737ea3c1fc7e85a61ad1d01fe8ad29f44124ba2495a8e5daa38b244e8d32094f36764b353bc4a736912638030715d98c964b5d325cd55229fb4d771b9a5a023363fccef7eb4723fb17d745568a0fcc9e8b9c3b318a651e2781929f47593d8ad64cdad3491592aa45eb4da42842329169bc73e3fa8f6685ce304d577df84e8564249cdba2ba66cb18c3762983596d471152c34fe065912cc9bba1923edb1dc8c677c9bb8c9d2ab127d04ec380010f28d5bdb6551ba136a4756c96d050055ddf08aad0dec4a65304a433b7c529ed5594f47e5c04716f7d30124a888f847b92180285efc6317a7c862dd87ada8ed82864d76fc2e35e8b43497a0f35c0e4f92a489dbfd4bde888a2bf9db9d79f28c3628d645cef19e007c333b2d9dffb60b7c1e3617f7704a1964630f3f383b9243fb594f844121883fa6a3f163e818605221e020d402a28b6bc8437c9c9ea468940483d032bd4237c547e78032f1a00e818a5d8576bc3125faeed164a2e21efa1f9bade8cfdf69610115e22b3ee66732d1f5965e572b3ba62f6075c050f49b6ae1a31eb55087fc3c61a05d380f31dd5f249668da23543504769c0d5129b2f33e56a3bd8b195c92bfe49dfdcd287a6fef457dcd8376e9db99fd607130f503d466c1c4f6c1f388fe6e637645e7d5014b42671c8a0f2f248b22f9dd606ffd710d9bc50482e54b912f631f97f4b067858169b2023b4c233ddcf6e65c7ad94b10f8ba8ecbd32ed2212f3889a23b332014d9214d450d0d032d209299f4f1c37795f0a7a960307e4df33a65a0b75cd9b3b20191fe08c169b57d073b4a421f2a5f6c4cfe067d131eeef336ac4bef9f33a7eacefd39a5470c0a74fda68c9c5714180a2276980333a1f886b1c8a54858bf1a3a285f9da6e942b5351cf1f11f7ed2322b1fe2751740fc74b744cab83e456cbbe3dfc9e36cc7b4d516e26f995e44a857db274c08bc849f4dae970818fe3df46820775c40ae81a975dd8da2d84dd3febff009a1f34509ca33cc683463eca8d1fbf1bd6dae9b1c40010b01f192f591c2f02292661a259d8a907e999741e28a600e8d31d4c5cd0fce3f3e1a29a43d36d76c104aa7496f6a603606b19103c0e940bdc022939504c1e047a8b7e3b262628f25add2d14e4b0fa56886a2bab61896ed83ad22d2318187a82782b1608762932c74be32568562444654527db8756f112c911a421f797aa85af160ba7d762819f2d16de4ab9ee41d5bfab18eaf48a577a4fafd056c40ebd2cc299213459506d0044ab3961509f809bd52eee2289ab7416cf22ce02fd20c49653e2669069fa098e17d61d33a74df11b881a678d37bbc79f49fb3518829ae43ba7b1bd6cf4278331f70d315c375ba459c1afdf591891dcec6161b1ae8a3f08cf486a8d5b0b49a09cc925908803003ac0f2bd5ee66dcadea745fb1b688912e10c428c1f81fde301b553b454c3c1ce9a156889e920fa76ef295249c9f144053a111b847fc9886d83704539769ff63e3d8002030068c9b0d5a65a90acd44fc799b6b4a31de302a44b9a762b4b5296e11c04f44e07b888c01d8024a222d9bcb7eed193d30128efb37438d7a90a9732ccc590b25406ea57d074bffe1670efbc48c78c38c7b1500a78cd75a5991d5327cd919e7564a5efdad022d9c508f2992cd3953556534d8abffe377565d7f2cd5f503c169dfcac534bed7d8344fc2b2f25295692e7869e03418ca5ff2e46b4771795dc3c1cf36b1aff4a11ef5d2f8d65a099a133abf2601652a6d73fa499c4f824b802c12d8e1159e11f4613d61d430a6d6bac977b9e97b4d3cc3dc75ee79e2313be81602489cdd48ed06aff3eb71e0f5b8096050fad9b0450f6eb60b04c003a3adcd70acc3a5c79e3175037991976155c824942c4a2f493a2a391d77aa34d29c4b7b32de9b0e2328c3373301080a7d0bc90930e0f070479c4b1a017e1ff560cb0420f684ed0947c40ba7391c9a49459bc8bf90f98ce5d8e2dae952139ca66d2c723acaa9b9e2cfa55ad1aaea84313b5ab87798b73faf15ff9fe31d6c4ee95bbebf96144bc4fd7a72697dc4b6812573fe7785e5b12cfd10e8f499477769e52b141a1927114d21694c0f4fa61a9cadbd96c90ab418ae6f453f93536490f26cecffbeda662b4d520bb73457991b80a824aa0501eda72dec8dc1c13cd47dd0fc9450bcdaeecdcfb0a58578e04007e2de8480114b24a5304637c20db7c80afa04844e66c27fb1eb4a848fc181fdad4ae5aa9a33a2fbb4d9f621955d3699345c2830a8f5e514a946fcf2c2ffa7f97c154a2bc80e905e43fe57731378af169c8553c6e952e02e21d23dab29e051a3eb6ffa7d8456a186049e7ce9b9f760a1c0426dcbddd69973d55e900064b83e995ea9114c4feee05f44c812f3391b8f14f05f241a67cd358cfc243adb56d01c3dba7e6584f331129cce22dc2603432be59c9c7c666efa8a9c4dc4c9f1958341b2313f652156f86036c9e4a4160de4ac5114e92acf0fbd91ad0c627e901b638a1ff6dbec3ca05c24c363e658dee4e9b3364f53e49c59f60c15f7adfb5c68890738943204c2ff8c166b14f2a62252bc4310aec07e0429e6231799a017ad793cf6e1e0af1e796adbaa457c10cdfe19d05c03bad6b211a9b9176b72b09cf2cc28bca2b7f28933f5068eb30da1afa49f36c8777498e001340e0848b3002266006d226d355fd11dd9bd8c04b1834ac8abbeabf24b0401de578dafc84166559666443683156835444c32a7b3d75ee4da6177c00f52e81884d5dd1a55464c38b9ac0da46a5a48109b617f65d95c0d0a76c0268e26ff6976768b256a12d2506320e18e222493ba20c4727712aa84fef939e01f4a9a9f80ccf328b007388a1357a3417f68999dbbd7c8924a29fc94d9b0b0ac25c858e88b623e783c2878742718f4dbff296c1fa8ca350b22502a8dad1eed5d1868c0947369fa3a4425cf2d49a28c5676d05ac33fdfb6711aedf57a7d0c5769301d4c87862bf10a3f0eb43fb8da2096eb4020a599e9a8752214b12b7bef52317b6e368da43786b62343fb401f29710c8f8ea3e5cdb3769464d6e4a6c3261e1df2d8c2ac9171fea184340e6652f3f12f654435b52cf98e562760a012b177f539084f9b6cff9e690a0dd31b8b56b83c67175492d2ac9247532c619e8ae9c1063d0c0644d593c3a5cea15f458a1fa5a897c31cb47e5311ff7d15f8cd40472d7f78f1b9baae4cbfcd02e1afc12c83bd665f4ca898584bdc73285aaa2a1aae2a4c7d554157d908bd5ab5ba2271b5c40e3df2548aed39b651dd198735315b0a166d234201bc718ad6748b5d1541b8c61f06ee2fd7df38d65f0e97b32e790b48e9199d59af0cace481d1b7d47136a8d04a1c6758696405b6be2d50d7980f752e91d8cb9a53d4e069369f4d34e9a8ef5c326f483ba5ee4ed41261c8657408b9537b045760ee81aff027c0a845760037e9186b5a047ff92c79042793be1154d877f9a54ec85a78e2165da84bb9959d074773061d2ebd7aa0d58ffaf8208fdd240e2d0487486a59a40add747d697150bbcca41bf12aa6497af52971a8b005da5d60738a9f179670929589733add5684485ea15a34a7fb10f1fbd54a31f699f6ad2a874430d9c1479e4680f28dd383b7a5d97f8a5a39969fc1ebe4af9f9ae4bd489c316cefc8df05ead1bfc43762dbb7af18e04029b00e9e25e442e737623704e6ae31fd4d6bf749c06a99cc87dc8792d221e7cc3b23c4905934945b94e021be63964032d732252582224cb5191ce0e95afc1f633935831424d4a3b742b9e40ee74482fb526ea42c46db5fd47fd45ef37dd77435fb5768c3c6f405ec0f1656cd845e2dd5452ea2e9260b024e8e245ba9f83a351abae2b98ae13d9bc1c3b5e349951dbeebeab85bca77b901854ecd94586307f7580ccebb3851329e9cc097808789bbb491def95eeb33c05da1245f2317e455b51f2eb18fa513c650124738ccb02e81807e861e3a30950413865ff496c45289c5b97be36141bb0330b2e193d55063bd86549fbc796d96f5d7aa21f8f3b8f9d7eb63c9655172d63bf6274ccc7f244ecdb65e7638938656ff2bce007a778c554a00f11013447f00c73c21f3fba4ec714d806c568861d883088ca424273fc27f026a980a80ce61d8cbaca2df5f889de65d345b885543b943187b3e97e6a036bbddeb6864e6c156718ac744d036792265d952d6f18e1ce4c68dca4fad96867401e4e82528ad9a12305ae44a4d4e4d43287448b5679af9b0a98bf8d7698b58e0ea0381662451a64a7d4a3a91359d44cfbf62431ac4d1d5c5220fbe0ed6a9a3cf054a3179f469cecfcf051aa86c0dc6e688612b4146689ac1fc3f0c5b01b94a1327d1c493dd39e7213e5f41e2a7191de878688b16fe1bf8d518d6f7c8a5ed99823417b1a04712e9a7ae8384cd45d278f633c3b2b08cc2248b38d4263734224f157264b393e7fcaba027e1e840d96636bdc2fab2c33190dd14a48540003caf31b7fa3d3b269765ab6be4168c9ca529da6c8aa41a3f8a8645b31e3484c1495313ffa51fc60d18e487fe87737676d6048060d4d24a3b58e64149c24632b0f21b14a4a4125d2f08fe301a090651c974996889c32abeff7017df5dee40b406be55ac73ac942a6330da723223aff72ae96364f1e40bf169bafe50517c536b0b7b3947f0aa1a74ba36c20b1cd44618f455310ce5e461802d1f1d7ba893c2b5b19633cf9466addf3103826e48f11b3583ef10f9a9fbd645b545f1df79e2a694c369eeb907cab8427909e773819b21f118bb2dc78edb9e89aeeed102fb950d6fb2debd880e765c5c7d4b19bc8ccb459a9ab5bfc04aefd7bfdef826f950dd748e99f54588dbab10dd99960fb40a64884cde16560811f045e370a2d7ddb2e41ad35e34822e5caf04b6f2d5e01c887e58c9d32e144d51cbd3cf1d1877e7c3e3b40be8c9ad1ab8a29c1171e29914fc20e425c81e51353ca1e58937829a686df3cc841fe0721ccbee78a3e7a2ca794f959931c56a8a6bcfbb0b035804d7c3555746d9cb4a617e81a98302d211c1ba3f5552bf671605c1a3caade16683fc4a6cf6b50dd94427fb666edf11ae7b04a8c43c67c4a251f506ffcd54d9fefe5f63f5b175009ce0c0856ad39797f9fed8c253b2727dc7723fd84e5cf55bd9744f32dfca776abde03bb0d2fa6db2ddc1e986a3ced7ee792ea8b68e5ed09469f0e1568edbccca6c7358fb450749e38c6f2f0a42581d65a02fda2ed923cbbc94152c5d658018c6ffecbcb92cacb66267da468d2f4e25fc6d3ff4e87d82c6db9be401cccaf22ade27f9fbbe114d8d56675f342222c2d82c57e5d6a8bb9b354cd89ceb409102cac53db3d2e80d74e5260e2352d993caaf78a1606835a0959c6415489cd8dfc4bb2ab29d54fcf0ac1b6596c4c1cd352e647b3fad588a415ec4e6b7c11216e1634e61b29a2e7aad574e68488a0c238a86acfb9d4e3651873ce9f91fed3ed08f5c60846d5875ab0bf98bbf2836f419d299c012def7f2be26721d9522230420927ea6bd7f0b9648e0509cb214bcba4be33cf5b4c29c27cc6631e606f725987e200f9cfda80e570fb61b86a753c6e2bb8ca496c3a71ccf86dd927d57afb30fdd3b260d56c19f92230eae1f3a1437fb9f0fe16975c6bfd94746f7354388d6bc761e7390b194112219821e53caa806c50843c8c35639ddd6c9831fa3f0ea7b00c0a38e870e3e6bd4633b306791897db6b65a0648d77c68ab059d821bf4a77f93f6ceacfba692daa7c5169de9a40f9ed123b253886b177cf4e13b43118cefdfeda99643de0a6166e02d2fe707e1dfaf7ea6fd662a28ce79c58104dc4475f53d11f24ed18a65dab13698422e7f67c5c2f3d40c5f29424c9c782055154484e1f301556c226d1b991ebeb9b46e86e4b63e41589c0cc92b6257a4fe22975273c3f634a31fcadb6f38d123545be82cf756aa8b845f54a64e248e0e5510a5dc3e051f09a6bac04d20ce6f081877a1a00df4b8f516002c0f46bbde37dee338d1523aef9fbbc70c4162db6232a6af6e50d364c61f7d5c4e2fe2b56ed3adb91fe35e704567a2746e6a3e94dcc906ce14c952dd6cf0978081a6c2d2f89e17f4e183242db7131bb6467975dbc255cbfc4a0db5639022ee48339313b9708f89ad2e7bd9d3c2696eac9d4d9f690361e902fcaed9060d85d23be5db2bea937ffa6924b804857c0367ae8634c147b6883cbbbf95aa4f81ca4874bb5df02d8428ce090ec13d30ea5f0a0e687aed2a271034bea2ab622465905cb29a07c5e4c48ba6b27201b25adbeb149548d577c633e7247a3b401a53855cb87b15adc63a89fceb78f544322dbfc9a35da5464cbe838bdd9e3a69c4212282400c252fdd7d1293a9668286c4d9af9672f7b206be6c5046abf2eb6ac8a390991a41eedf4f84ff4d933f68aa40e0654c8cd43520b02f803268742b09876af493508c821b63844144466b4f16ed348feb651bf28afbab0d6b77e1bf8ef7fe0c2a1e92459b1b285c544d1a731b94fbdc0a17777bf20610446ca10d7732deecddc7bd71b4d6ef99e8598dbeab563e9bd1a94c64a576b9016032a1ee4fdbf61ca9652e76acf37cd7db8ecae525af53fb70c74fc692f9d72c4975e2547165e34ddf7caa65e73171c2f4c2d7bd70de576197da2fe41f49a776f2fe37fbd239304acb1c8414df096d047ec407ca6dd325113bbd716b73498f9a80d82e16c97a5d75a2faf52e92521997e4aad5a82352f178cdf456c657d8bf720c128e784e414e8093aba737ab9db9f220fcd70a92324decadd50c7e2cd4ab5850335468af1e3f3c7bd20040ed6d28514fb6f9a5b8c8f70653e36a353dac8426b5ce01a78618dd60bce88fe10492dadcd3100dc0c60a81c7debed7d8f3467783c8bd1facc446ad67c05153010d3a946f23702eb4ed372223f02daf7b8fed6cf60d3eb9aa7f6c00c71c7669692450fc4cfe4896bde89e188e0062e1e2328484deab95906c8c58ebad6c2fc6aacc62f5d4f1f72e7b3598cd2d67670b659de8ddc2bb4b0b8ec8fdb9300b526dc0c81781421d6cb4bc0994d0e0dfbb0bb94b1013e66118a416a403b5e4daedb1032c91f31945b946191f30f164e798ee48c605fd3667e1e471f57ac1e7c0811d9af093497eb55bbbcd9ed599598dea1dbcac5e2e6a0202ebe206572e7949b88b3362ea6c183d10b650891c5bcbb2b16a01bc1e4d32b42282e572c8064140beae57da7c6ea4dab9037e3b13a582f247f6ad54aa7a6e5c399ad9294e01c4c4b432a4a0cd06c66c996567d861656cfd905f1e7e973bad6e401186219b74a36a8e9f2266e6e650e60bb7a3735b316bee51a1386e10f471bd974ab8ee57abf65fe2ca264550a6d731f3874fb2df3204bc9411a18663e725cf6ca14efd7ced544f7c17d95e62dd2839a86ea12d7016cf600641484a5e8a938389e652b2a7c6298cc9b16ac66a5d234e5fb3242edf0b373304ff3ed5ae3e04d22fb09a6f0e2a78a5f16bcc6806f4b538eb9ed07fdb2fcd20769e2e58379ede0f31f5fc27a09ac41f0647f4a5e2b081df350ec53b10756485b9e36d34f7c666c36e834d358ad9444093c41a260b8329b1c1fc3c9135238f7102f303b17302814859c3649ace912c93e0004b8ed4f4777cbcae13f21423fa2c0f27d677305195ca47d26ac4d45ef0f51225ac41e1f7a4bfd59ea6b021c4efaf7fee7b6ec6d2abb71f17e3a5ba3134db237c28b3273658e1de0d193d55af51f94c089cf725c4341bf9f4bb19fe08b10bf2ee90cde3ae55538da262472db607f0782800f28cf4490c9e5b25a78c73b39163aa32eeadf7ab2860c99f0d5831c8240df9c9f318701e6ca3735331b8eb51f4aa206e579a937a356ad79f9d18fb101ac65fcd4026b79115d179447cb22ba265cc2786b8c3c4af347ac7ce639750501093133ec4b074def9d0a06e74686e7ab7967bde6c0867b99da9d04d830ba68457bbc13bd7a71bbb5c86c73a6811b6294a0465bc458032fd2ff12b84a948d507bac86f5f07a9265279def70db86aae515a83e55850a6a93f0d8a0346ddb3557c9787ef804d799010c5b69bd13f6ae9e51f18dc57b73079065e43dbfc279e259da29a3563915125e6e0b0a5d4507fe48cacc32776c194bb5d556b16ef3d13aff925c5cdd8887c3e3946c2e02b292fb71f5fac7722a5dbf6e1ef885701094d61a241d4e47bf368dadcf21af0f900329fb2b78780e84fa14991becf35b24d0c458e5dd3f05717fa27fec95feff3016d5d7fdcd99943a772d6d118dbed6275e2bdd5d26cceda99e3daa450946937d098715b8518e40d90e508995149a755c3914199ebd257f214900d3bf9715e44ade9f07f436b113d14de642fd21f6e3a1fb4921c98ff0c5dee81bafb4bf7fcc84f937c93c51a6017da1fe9050a0acdb10e9b2be39bf1b14ad4b83ccb780dbbecf583114387d6ae5fbb1017deb849e85fa40e6c73371993fe18bd511b70169f9b9a355ccbdd8df0ee8db27f426d40fd23f9289cafc085fac47dc08488be72663c5691896cad826c1833d7210bcec649a268bdbbea04c0f004aeb04cd292270b2c043077607f6cda8a1b39c80997b5e07ababa65dbde77f3ebf841fb11ad9831bf52656a5e469d44c71e663d4d0a14f9983566672e01a346dd2f16e51ad7e8a1abfaad66c9a99512031a3834e3ca7a195f2133d11182d191d7470231df428fcc193f0a4dd74d0fedea2f6c534d3e7d1bed2e786db0876d0163d4ddae359ef17bf4feea06d4507dd414f7a0d8007bef00ed4f9de7b57e9516088703031de06972fe5f2ebe2c60f83fbab6c2a7a1539598e41b84aa5abf0949211e8217e80a43f0828f2719371550e0be26c621140b7d5fcfb5f047c8de3933d007a208e2a064b83cad7e900f65493a47641e64f51c30b4599f3b8027d40e8b55d45b791b6de977cb471749fc2a6772b3ad57a433d61c5557fd424d456a20f043a742c154e03300590c3469fb9dd674dda82c6f3aaeb97be369c794d2c640cea95e2dee7f0dd265cb341bd2bd8808a309ea0d5e8849dcc2f4132dc78f45e818f00816c632564f5a7591b9b3807945ddb980c3348743927cb182388100ae4fc02d3cde4884cc582209a68308c45723e29b8b1b6ac505f12ffd65863d34a5e4c371ec141006c8854a1c6adb13bbc50f3378ca368148ddf612443afd0f4c6ab1c3a4aaee30b959d557ce3ea65fcb92718743159ddb79858b436b795051609b01fddf3994edf906f3014f3052fc69459bd58cef09da5c404f9556cec0cbde0728595ecd79a16d4b7793971acf473bfb1aea8c87dec1c841112000c7a6706dbf1f439d1465dbe5d45c4c279a8e0d222f9300b8f05e73a106937d4d5eb5bd93c2c38272a3497cfe03f0fc8e25bc8610450df3ad785dc438d7516340967eaf3360e7147547c94dfdbb6f7c8fff1e0313361570c48d72ae087139708c237efae4c5274d5145a353c68ec75f0bbaa4df9b4d0a444408053a7fd051e09fd3810d36cb7253f75866b84d1d4f890ebe58830c4d31454653f9e19c1fa8c8486a8a397991160112feafc598189691759f4eafa2ec9b517ab13568fe61ab77870b6a28fd5606391daf45841cf5eea6107d6d8d7602a44de2c4280b0294c1c5032cc306d0e95cdb58fb71e4d82dd9fb42d3a102b309cac960564e217e86f4bc3bd7161d4aa60ce18d4b9e7a85c3dca3249c455816a6e6004f14d0f5513d324cb16c2ccff513ee96d730c9952a24e80fc0f8f673262acd6aac7e2050c4cc005d14eb7ace9f8526b995eaaa8b2a8255f4adcc3e5cfecc25ca221fab6f6c12b2445a6796a1af5aa6fb400902fde3b109d798509a10db794d628c216542f570b4b03395518bfe19c0546c777d85565d1ef5ddd7d1ab6c1ec1a09072ed38aa5e9a250863ae3b0f772faef2f75f3c9b85ca3116a168e99072576d8d4e3f7af13ca1c67e7e5b2d192976e25914e6a3f2575da5cb516b6deee59b84e0d424e32bbd7f11cccde616be12e184de75524e210bdfc1c13b14354b9a40fa7debf0efd0159814ba50cf1c98cfb1073404bec43c999fe2021ef15b7a91fe71bd127567b4053e0b26265d7742608349a6ed7cce47eeceb7a66f661a6db3c73722ed538b66e23949c89106d0b6167ddb661cf448bbc7569566b0c035ba9df555a81cbceae8e2459fab52604cdadcf4d2ea9de95fedcb3d5c6e4cdaacd5f2d55a53189d8c00eb6ad6aed24d1f99b42a6929378f3bc8a68893e522fa37b42fe36563b472d38c6c36d019d96a19cd69d3f6fbbc945cf1d6b6d581e87c7243bccafe462863ad7adc974334e1bf9fa7434a216d9a5f7de3ec69de9e69a6f34c7a4a996e10522d78988eac4dedc9a87e865794c12746414dc6585569d04a8d700793866e9f8e87c6b1622dbb97fefcebef72cf7bcf6177fd379295e779237d517be353b96999e1f0dd006e0d6e5e84a169e8b5b0a4e5fbcdb9709d8d2ba3ecb256848adf79f0f1a83b3f652d18d52a22ce7418cf3a925a5eda3e7729ba815cd9cad3d1ae24d60e91eff38891208e181b877e2951c815d3997d02f37a6adbe36364357c71d433ae4ca42bdc87b91b60bdefaa11f470a77af35d42ae2000952d2262633452aca5b727f55eeada6d5f34afafc35ae5c298e8bd4f29b92fd7bff39f368e3ca1227f944afe1aa8005c62c2f149116eb28b58ba7eb4fcbaec6376619bca3d7604dcc2088e257e1cbe55dd54640403cc3963fcf7a4f1d408ff1702262a82a94c8d258e40903ef1328b182faa11badca20e70250e49d7107b92d58c994ea6b8bcf0b0e7a1f8ab65c242acec4b1d25c92f7348c2f3be680a4233802c0f1127cfd469902d0a23faf7c6ea1bcc145c273018704269957bfd5ec6db0f2669edab7bbd9aec174efcf423c6db2811289a8f994d6a823e0bfa70710ea01d5ef65f012a6a28ab3b4cf1c27e95a5d2d7082535eaf0e36e3ba155e7a556b4692279ec0f15608dcd017c1d2ad5ab23359e3dfdbd68f3aef3adb0449d29b63f84dcc09015950bd56312d8ec772e1ed2109ecf443abf95bab7755e0c644174c90d6db240691cc3a1797256e5b4c5c986c51a7d543ad67cb7b7cc68c7a63f362e2729bfacf7347144efec4a09ba89f6330ab270aa78bce1b8a4ba29f914610e27f1ef0477345dac12e5ac84b0701a4ce221824fc42b72bf79c3d23352dca429e09e447e68ee96e32cf912c937369aa4f06eb4d83bf88b6146e5c81e6df3a12758b546029d41a903289eb2b8f575f75da9106256e95725643ce183d5a43cb67b935a6d5c4edaeb3f9fbf041549d2cc82aea1d9e68d661da0add7cbd450857a56263452601f5c43fb7b30f2f6fdba7dedb96934f433a7f09d7eb862697fd66bfa239af5871cf9fdf0a6036914a88dd10d327f8e9c91ee54b1f6817eb68a451085c34ac0d6a0753a45e66c20014740a60a4d2a11c3a67ace67f92333991ea2dea5ab2dd07d777a70c588d8efc0e8b037c5ddc6b43b85c04acf254f092bcbcce41f8e4f19f8d1234370432bb4c1b7b0e73e090093923e09710df084a980eecf6dcad24b64d0dab675f4b97203ed601a51a9a781e3239f209fb8bf3e2a8783a964bd4205bfadc2e061806380f03434bd0ef22ab5ae71c7054588fff6206c27d5e3bd9229571bda0d324c3e20f24a4bb4e2a8b1a92c17772597e2065ab7329f864a26a07db71c436e912cee02ac9edcab7237e0494013533a1f9b23bcbbd999e8abc7dc7e0fc3c3f3daa2f4aca423e9eca38ad1644273fd6e2f6ceeeeb53c41d9611d9da7fce35816611cbd3088d0e854db8befbd8509db69532947da1276c69930f041a2c46ac673d1a047e6db11e52f42738593cca1a716f3c8c8bd8609313308c78919e52c08e6a5d8b887d80e366f2e00cee99e81fc0ef4c2852562a5b9a576252670d6f1908702d98f00153d17daf4ecce1641692561d52bc64236f21f51ff1d223250a39322411a687decd1736afb9be8c152e4e3396db5695c6e924c758f0299f0d7b2b52c90796a4b14d69d0b786a45a2a3d2c0347d93c62f34820c97b1e065ec0c2c9d1f52bb511387e9742d673cecb03e0882fce73104e6325febcb4d49b0c9cc959793c7c3e3202c82318bd6edd657e18f88d4421b7f673b20b62ad031ed17c43a80b6b1d5d3035bcb1e97079250730e6bc2e37017f86e5ec4fcda6548f574a029ed67094d412771a24b225281e828dc0628d90b932d35d4893c957b8cf06431aa5b9ded2908e18cb7f0d2bf61d8c521d1bbac1a5aa172de8c77ed5ab3058b7c0cb8773fceddb5baa9f3a6c937c9f6d3f910e46f6f54418d6ff57f782f912c09e70d9cc58c0cacfd763e50806f5570b129cedf4106c6c2cf43bfe485ce3c22cf642e8b80835c429a7347aee71efa9caf548db7303e065894dd10dcfb88f5471cd6008aed0a20f18c88a23d67ab0e610d404aa5efaa63d5454b08ff9f67f568043167b933a3fbde974e5ff1e0fca806b3a1d227b3b81fdef5dfca26a49b7138fbe116d3a02c1f0d849e04a71a3df7db10c00dabee72e65f2516770fbb2f8d39e8280becea6b18f379e92721c710087947361a0d504619245e21d5a846eae856123b9afad4fba372991737ef04a65c590207eb6fa981e97ee222d4d4e25c2810779f800f862b1bbcc85dc4d746c6c1aece6c45c47dabfbe11d4d8fdfe3a65bea2fbf91b88e2f4e8d154cbf08983c6d511cb18051be67143270a8e540a89c94e56cb107d0a436a840298fef40166943314827c6ce0f0ed531e897f116ae7221505c6446e75d66827c3330297c7b5e1068ffe299d06b5868b4bf56102d62e87142a9f7dd21d6650fbbc563f0894fa6997d0f9778a6285f601bd71d61a708ae6e1cfd9affee83a426779b89b909c8f9227d256d3c22a4824f1dae50d7163bece5e37ed323f0faf91e2af694ec6b2d81d7f8b872cb5f7ff73515ae88283ea8bb451bbd7685417a7a0ff19856a1fcb4d36231ea2403064c0e756d3915d1d9a2012b8cb8b66096d7566643768f949823a1d5306ead83bfab27baa73b4336ef22818c190b85af2cc9d663e743438862c0427309c79bb5a696404929d7f385833b4788708b6476a6ca0710405cdcee9d6cf56e723150da8304c6adf030482f42b21591a7389419d7f8dbf3db85567f61f221aa9b2250f6219f892104dc549d8beafd5d9e5b5d5b1973d6b377a23d45e650b5cc22d59ae0a1a328893df3b92d0928510a42cacd924075dbc4552d0f3f19e5e5bae97beb757a45d09e88f951981fc8bd7ebe1da96ee18c01892137132e75bbd83d8e03db828dc2522c53b632304ecd68a3851364dbe011b05fa836b17a7891db89b9854936c246b15ac23eee028e04af203c2b07751936f1bd104e6bb56596cd1475d925878cf64c1208055a3ac82a27ad54409b2cfab04fb7f1324f57e4f3eb44c2c6b097a0b7cd9596a9cd1785a04a98e3397a627eb4fb613cd61f53b2d57a34c87af70135d4b28c6141f5259af12e72679a60a7ed2c7ae75cafe958a4cbe4b388cfaaefab8bdc7d1a812f1ac11a0ec77f62635094dc29161456d7285cb4685e39c11eeaa113a73551bfd0a0d591256ed0ac74d77ca8d2f75064f4056c78acca6275e234ad83918693d7822cd9296a7622b2c05d1376555ec2b2ea685e5c4a548007a6efb0a233b5b475fa6b045165ee3ae6ef4fa77b79ad465d6229e9e532c4b2f8a182a4e47965583e45a81994cff154cb5d2ed883b94f251fca1f5c369576d50ebabfce6813480af9d298249124310a2533864e219ec121fa5d729dd94693773255c0c9dfdcb5b6d6ed504844e7e9e082d57ae2cbdf5c4cfeacd07d15bcca153d27b5d2197b9ba4f5c0f865219eacc24812e32e4e6f9cb1c281673407c2dfc5d63da29ab66df81fa4adb6fe8c25e3eb8a6629625268f2cb98ff4f2cb3481f421efc86f9fd86234597c1832fb8a2199b329a50a0a088d4afcf27154e43947165cca8d4ac041e993a5658b2db11be8709cae3da39afcffb7a486b9aa7795de2bb756f7acaade935b574f57f6aed463e566757a9ebc0cb9c66286c655dae830a03cf01b9080cf06d1063de0db0b783905f3ba939c86c2b15471c0d360df0d42467878f1a035965dff3d29af1d4ec15277c582a6a7c16ee20e0c6206648ee1f78603973f8f6dbd1c474b88b9bc0908cbd86d4310ef5ad8df775be13fb7c5afc1187ab6b267a5de2bb7abd3eb244b0fd54e52f2fd6b358173feab53feff07f1e712898eca80ec8a7d004ad38e200c9a73d939a96d943ca2d0b71587a8e66eadcfdaafddd620a6ff16d96b783e582cadada7977ddaca091de85b00d5f3ac4e0e5df89c9ad34891ae1b5229e9f5bb9a83bf643ae07945f59ccae6b7bf94a40ac129be2062a0cd7812bbd7f19184a673ebeaed95bd2bb4e591700484b9033a34dba257205e554d07a9de84bde500e1b5cf69f6f36bc3d2bb0dda4b59ba8f6bf2be6222ae19e9b19fef323818187effb0010f580ce2fe47595234d501d25276537f70abf41ddc5fe5227e76428f69a3c96e7befbda5dc52ca24655e0ad109930a27ef9ff2a6b0888b37428719d79ee303a85cc87acb27c6d06477d3b3a1bc81644d986cc2ae3f952059b3c655b5068a5dff4616f2e83aac227c56ed7f112ed696af468b7202fc455cdcc2bab51e5606fbe7d78395c146f1b00fea12fe6dd370386b5cacda3c42069dd5964f14156d27fdc5182b291ac3925a71cdb3cc86deadb5b6c8575722615fed3b241c55e471ea4c0fc98eafb8af454ededf14ba76c2fb2474d7ef5a74328cb2ebc818a90410f49afa25504a16f85216e55ce4aafa79fb48ef42dbf76d4ce049f282fd54942557c882621f69abf1d5e83947c659b43d77d533ac6a1618d583eeed75d0bd7121c7d8f2892b926cf9f9a851d525647fd38f13d6a284a25da78ee9b1a6c77cf5789aaef35445a70ead785bacc77cda96fb1c8e748f5e73835dbf148efec4aedfc27b6ee6c8c0c8d0c493f8d44155b7f62494618514b09927aec8d9f20932d86c185b3e418623ae933f4431ffa154a766d7aff3888b559ced710a8956d3e6115f594dc47790d2acf155e9eb4f97aff2d7ef36d2931ebf168e559bb408196e6f5b2ed6d26f61e9c1d2cb9d212ed692769d1c3a9227e471dae868abefebcf6ac4be75f72069d257a40f32649c3d90b4bc61109bc376180c82df3ee9e5d783f45a10fb5b11da6bdbdff0b9e5d6e3b4e158a58b362c02d5e3eb00d1fe5eee1bead9c2281717ebd71a56c8aee3ac1d8a5aadd6113dbe92b02535d55fbb1625d93a0eb4470f62d9fa57b3305f8d5ea3238de48c68fef8aa76010563c3c5fade1432c31ee75019f6c8b261eceba8db1651c4bedc759f8446c838a107b019273c39e3dd5a3b8c3f1cddcfcf7bfaf590b0ede9093461618e587624bed25e739dd17b76c5628feeb3abc36416628041098c80e0e33ac38c5502abc2114ac0c1194480c58c7d29ed6369df7e382ce79f0edf434c34ec1bb246fd93b0450a4968d56812430579749d1ffc8ba0ec9fa03c7d145d64968027c80433467815a830ebc1ccc9535dc4086d892bc2e0737100051682668a1881f2464c255dd0c9994179f9fd401ff5c3e953feb4628499934fd1455ce82230509831425a61c50c8a76427b23749839d14e5c3c8196a076a078c0f484592000443161b5861579749d1353286786f8ca6a14105b02ce53df5ff55da7beefd407f2295fb0c2ea804e43367190e7cf3d452759baee9b38bc97beca726aff92a501112f10ca9a4452551fa5626db7a462043d9b6e998423c6b0c7d9c4c7f8ed1f13a5be74d2e2353d8a5bfb5458c4091ca9f7b0c89cf1ef6a6de2e6edcf1f1fe9a51495d3fb0d504a985d44a9e81cbe555252885aadd6114d6c30675ee3f2958bd9aeef368ee32c3a535fe594328178826c62be1aa7cf5c527f0ad59f43beaa55ec9a929292e2b3eb4fa24a65362aa7d34485934938653398e4711201edfa7389afee5759002464f9f21b624e22674d1ecaf2c72a7ac4f9a4c79ca24320b2467d18a1cfac6eb25314d3af84e1cbef4708239c335d178692aabae71e462867ba2660fc0d0fc395efa617862b2f3f207c06c6039131d6c58f315052ae84d1de85f628daa7dca0375c0b4bef221c63a0c0e02d435338d693b096b43c51d6b442aaea77e1c7b0b3d8f54797779944bf8550960674d003263e60c2092220c10c0f5194018a190bb0701161a63e90fa41d4ff304638657416b9581f0ca7d19cb9589f14ce2317ebc3a8bf124aaafabc1be922e739bb7e0240908bf83b61dfff3fe081d4233167521a3593e79e45b3fa93a86a0ea46ea86d237216a8336546be6af991a33a829a3d7acdaeeedab53aceaebf5d0da6be0d5f55a35d1f480682788c89be9b44f54ea2fb44f709b043747f0bed6b21d6d610812692dc2d3fabb1f39c1c650a093ba1b03c0961049dbb3dfaa4906b54384ca342892b0cdb1f9f6ca9c44505245838c1a20a7c63070fa73f795b2a7145b1c753d0b5c2fdce5601561005212871c4073f2b8040139858c30c9a18418934f07c4558a957845b2a71e960735b2a7121215121b7d852091250c049b2b7a512249ef08094202184ee95495b2a412207dd0d9420a18331ce39ab60ec6513ce4e38e2828ad74908372851c452d690c404a6298a5cac4106253881020e8a1a5a481164a2020d4aad13294890a398b5f83101282b61971bc0808433f6b250c66a3041ce2785175561172f7838632f935c701368d0b9c0b8bcc07cd8a5090e67ec654feb88c2cb73c1694842677381717981e9b40e219bee680d2e1c84c31d5d71e442613bca828d1614c32ef88917581718971798285c51d85cecc2838a33f6b2968f5c8043a748e22a39450fce4749280105181ad24002a1181ac06023850d55c9cf1ec69bb33c01d6a00ce00872aa0aa39cb77c024809290654844d0cb9dbf209a01e2400099c185b3ea164083f1cdef524e6afeef92b90f1b43950827ae4be7b9a83fbcf7b4e88d3f63a8e9b61e5a8873710aa9a6f61604491659fb2ee6c51d6b6851387407c08a1aa29f3297fb60d1b2f2f26534a3e0d67d1f082a01a104550167e1c1611024155f3b57047105435bffa848111294b44808bd3dfc31d54350940001d7450a942a99a5233027b378585c15c70a021d3582c280808e874ba9acb180c8c28fa9837a8cbcc5435352b65cc748a5dbc57208285082dc4c9355b596c9986ddd1d92a028b2db3d8e1a2dc5074724b3d0691c2449e4f85384920d4256f5929a58e5d14320322f311a3e105b1aa4f8120da11546bad152360627c3a7d8c9425f234a9604ea7d56a176f5ce77d2430975a9c98505ca478dcfbd536cc692128a62c672927cf815095ff88da9ef18d8cf3090865097195ffd4395060d24e5a944e2a3e8008913f36a429355bceca3424eb867743a96690f4799dca0e2082905f048c8825976947b78cf588f17d49b53f1120eb0053f9561a3fdce1425cac5bc80bb15508cde15b484e165224a4a8a80825a468daa8fca0e32197b0a51ee2db83a837432224d11e2bee6c14aa7c97da75d461d5e79c1f546fb8c0504a5fac5567507311cbf329a594661f749df49544c2a6528f791cb5701c626938527983cad02b8ac7d4b6dd74d3afbaf329b68cc21e51d24589852db7b0bb8a51d245cd1ac1adb576eb3eb0721e296770dace729b66adb5d4c5923e3bbdce4a95d556d36abdf62fa5bace3944915d6be54c9f0beb75d52ec15501a6d8ca6d5e37e97c205e77af94dcc5f4b78a3f1c76895c5d74593ab9f0bccd8587f2d1e4ade96ae485d76115cfc599a21f8e1419641cb4624d7bcac34acddafbe1a83db08b73beb0565f7fc105f7dc8d8c75d4d6a3d5da7008ba6d37b56a37dc7d1ed802c56b91624b19f4c0539db67317ff8b847d8fb0618c613736bdef85dbffbe1be542100b217d3cf2a6ba9ebe0f4735c02cd7ef932e7ae7422516748306f190448dbfee2379dce98527a50fa93dabf4b2ea944217a9aa9f432931d6e30d307c92e8e2e30bb377fa7a5f56fbd3725f0a0d32d76df785a769f24ba141a63f7150ec52b4af75007f3cb44dbfdbe474d2d5d31ab1298e8a92d3057b4a12b7ab532627415190efdbf0facadfd62b52969458c67cfbfe29cb180c733fac3d9d13a57da81ff6b7f72153d545e1e748bffd0fdf73fa03dc7fbf691fdba37e784ea3f0772f673eac513fb8f7fe876d7b4f7fc0091fbadffe03de732f67482f67a8cbc58f1472a19cd930555d7ac4c5fbf8be1cc9f4475a339fda683fe8244b2f21df9f0b8b71700fc6c1381807f76cfb14a57a3c5c78377dddd86cb1fff2763c249ecbabf16094e51d89e504793740b78a6dbf44833ce2199ee12367e1f03a9038ebc6a8cafe8c1f6b121b7eac3d37fc587d36e9ab8eafc4277d5d42ca5c23961f2b139bf43547c6c878d2d796b3ee4e75d9ec1cf9eab390321708080d3319a3879c755d2e264d8c62be0aa120652e122452109231315eced26432980c4816d4e3ab140fa4ccada9f1018f8c81f1a4a737ced28080680e1012a0249bb4f2a4a72690321a132614059bf4f4888c4115394bdb99b59af8ead40529a3fdfc7c4126635e2c7196e6121a22a92c41ca684890781336e9fd47c6a43ce97dc7595626731e99bf48a627bdcb40ca68354e834d7ad791312e9ef45ee32c0b04e44780fc06286793509ef4330d52c632992d769c4732e6e449766747b653446a310529637f7ea8109331251f6759d7cf12d24fd2cf1f48198b64b6582441d8a49f3d32263fe9278eb3aa4c47b643e254b0493f5320656ccd10675520aab28f8f6af6112662d8a4d78094a94ca68d8c019ff4427c359ff442c8182acb44a4f7e1acba435596f43ca44cfd992df6e58f8df165939e86b3aa8bf43b640c7ed28bbeba4f1a6fd8a497359bf45f48f70c295391b0c898faa4c7cea232aab24f22fd9432b566b6d8273de9533e1c24d8beb16b74838ed9a06f6c86be31166db4edcb289521837f7780eecedf9dbb73a249e1755d24d7f5d7755d17c9b6df22c69792dd1a594a26bb35db7e0986b702c4042805049451dd49dbf9d1764eda8eb6a3fd6cfbe00b4e25f46a34249aeba4b934978664db27a56c2699562333c93e9956b3ed7f2e300a101312900908c83bb92d767e487af474b6ddd9d9f9d9f6bb92e6591792d3a7ad8ba4ad0bc9b6cf65cb5599ada9b22aab325b433758865cf778975420264040404cb6fd8e86f4e746297dd9f9d9d9d9f9f1ef30a5d485a4baaaabba906cfb38ac7fb7d6b57a4ce1f0f150edeeb950db1e9e4c4db87e46f51487b23c187d51564a68ca944e9446b62fb4ed4b9d4b58648f0e6dfbad56ab0b61b20946590ea31a4687281165e23b35c33777766777866f54eef62c1c52db3e8d703271957f3a64948567b4d64c99ee689e72ee8eecd7945733a32ccfe5aaa329e31da1733a651b824e0ddb3ee7b5640dfb252c727d0f86b1941e0ffe2576df201a16a9dedaff2f9cdb0ba914b5f7f04ab1f360daca89d57ef43d7ab06d7ff3bc2d8dcf9b353c6f729e43f8e22a9b5d651fffc8c96313aac78f616af8a4b28625d1c7219c3157591a2617edabc293abecdff0adcbf46c5a9465fa53aab52da5ef1e118b0f11834e6ec9c2324539658db9a76f10c703aa70d1eb7449834e2e57cbd5aa71495fcd9d9db9e3e27c931872d5518df82402062ef7711f1f82bfdce543701ff7e9e9248b17992dfa56f31d4ae9634b1fb6a4f6a8ce9aa22ceb6428ab6c5212431e65d1c7d2ca734b2c7162434b825e60441aee5fc8546aaac779b35d2410494401773924290004c8145d37e7d42530e431b5a5961928812177394090e7cfda244b3ce99c4fe87cbba7e99cf4b9f0c58504790477f000529f176fd408f5b5d00671a1be7699b4fe304e90c7bbdd1fc6c6bddc5f6d765dd77597c3f76fd06b75752a589b4ddfc34ebe9059ab513a7e849e3dfa92d06198208f7e04ec653f02c6369489255f70ed70cb255e6022e917ce99bc49b823a2382e564dd6a0463e248523de14c6913cde8d9f878b7ddaf75e877d4f4b178d6c0fc7ba7df4770fe5e6c221beb7fa37d474b57246b250ce690e5e687afc00d01eb5b73f7db2bf5e34792143bd60cacc955abbda7df572f7f6efbdd5f3bcd7e1efbd91ad85a3bfb6e66dcf19d99abff6a6512f982d2f9a5c948e86d2b195dac065f7debc12e4eeef033b76ecf7fdba4bc975a72ee47c0b2edbd8b9779a3befb84b6baddbb66ddbcf37b2311ef153fb1a36b235df42a5326dcacc6d1f4f99196321f1334ed87f4dd3a81ef7b9d7719fd39c73781b3237d6da6ca1f3ffb7e96ab89a66a5d66d6f434c59dd5b3d02d99d908db56df3ed3365d9dfe4cca6ab8bf757a890effd4d9a8ef1731c0782e0ebf007ebefadf3be6d88dd1efe0eff0dcacd0f67ba54266eb8e7bedbde76dfe9ec62cddb07ad5ded6a57b9af9c1e5f76ad737e1b6903b7ed41d2b76d1b17b2d4aab37cf9be565225751f676f344df33ccff3ba700b39eebd70ecde729d91bd854eb4f1b57f836ad6da25bafa92656efb32005366da1525eeeeb34e8f86f4354ddb368dea317f7b1df3372d5d34b26b38d6b13ebd8fff861bd97588efab03305be8dfa0dacbae7b7ef62574713050d0fbbed07776d1fe8a1479cc3ea8fdec673ffb373c3dbe6cfb9fc7ca9ef7a5f003c38fc9f6de3d6f6e0ff6b1380b943a4bd50b4cfe91c6b6ba033d1289f43ae426e9f1033b9bf4fe46f6178ebf3f4c0ac7efbfcfc8ee382d36b4b5bf41af55027d519f49611436ba6cbba5f7defb46b6a6ddf00155e4ea6f7d0bb3c5f5dc4167bfb394ce70ac45b6bc37d4a81240aa11bafa5d0de5768cf1eb90371c1fc85837be2f3ff9d7c896e110bbada64a8475be5ef2caabbd2c10aced01c2eb059d94524a3987508bd37563b787501e5d27a52a0b65a12c9485b2902c62ccd5059d7459710de7b4b6565baba65dedc89c2f3f6d563be72c62ceb7a1e3e8ba39379085a6d3e93478a83615ed745295210b8b369d343f07ddf35fb6ac9584e23116d9535751aa01cb986b276715b27c2209459bfe6f980bb6252c09182c899bb9e7c78470b68c09b9760e5bc6a818da75d76fbe376db7e9df35ac610d58ec90f2ab5e846e4e774affb6b6e36caa4405355b26614b254ac076579a419e321d58458a8c639beab1d6a927131777f0c995c96d0da1f3e494f24b8091aaa7087e346d87b9c10310be9abb7e066834d9b50eed2abb9aa5e182e744d9e7dec80c0e51f6b73732a3d93811e103a6aafa582f40ce64aa7a39b343dff001d49733302e56ebe2627da1e1e2cb4f1669ecea7509efa7f7d3fbd9a295e54fedf338fbd2c5aba1483f7f7b1449f710f77c7ffcddffa73da7c7d3ecf0f6f5b567d1e6bb46f9ab7a98efb9a3ba779fef6954d77de7de8544e6ee340d175d73e1e69afeb8c99245d341240cd6c959c54fcfee9e7ecc094876f75d8b569e2fbdd2962a5bfe4841d67e7e490d797cfaf8519fee216eea9e1e31eef498455c4ab988c7bfff2ca28ce9c2b9a58c1962166d4ea37a88fbbefd7aa0dfa138917e278a9b233237a769f8903f6eb2f60f5b422a2141cd962f4f3ac9327e449a941287b424a32a7f4e8f63102124d16ef11ba07b3ef723dec0e611ed925e6922d33d72ef72a1392d84a2606cd2aefcb9b6bf8d2cf2f8056dfffc5f4cc674efff0d7d419f90f7ee7de75f0ed96de167e9c7715c083e87834c8de2c1fd7ceea72662f7f7a4c721e9b7f0e3f2b783ed0f92f4a76b0a87d79379324fb6dd23da727f4425b765888213302924f102ca7a1976b9ca5ae33a098b0452490a6a36fddbc45773d36bb4e9d35dbffa3f98c8636d92010c5ce05a8005480528104e404b200210f807c800c2013fac3400860f0c5840ea470c1f340a50e9e1050f3d1270e281daa123070a0e170838c08c69a7dcd8c100a502b4b0211393097002c35a7d030880005e742079a04b0b006ae090038d8dc32af1061b667462063070010b00a900052620810840e0014038e08706f8c08005fcf041a3801e78e891001e3b74e4c0818003ccec1b3b18a0003664620800c35a0de0450001d0c1a505003568e480834abcc186192cf7de7beff59bc347c372ef8c67f9192c7a9cfb6a79ef129670eebb24e80919510c8a1933807010d1bdf7e2f0d15cfdf7f5ddd94952831f9f9e26ee45a243df2caafbe1df9a1ad7113a38362108c396484499d02ad0236a449bd02bf89671838f0f4c08b1202022acacbc6cc0c1c959414f12242d48a56e5e84be630cc160b0a1194646b331d8b85a57a8a814f9e8e8e8f8b004050939c19b38131f8ac2374a4692243c370082bd728082b2a35dae23224092739384c954d322f49d320483c18642264c6456b46645592895887c7474747c1e06fb29c21c125a7204df27317272745cf0e2d981c1f7e1c098cde4111637476acce079465ce81b5c11128a49512423a262db82521f0dc62e9acb4b8d253f365a68c81a1efd2a12c982c1c08f35c9057eac3d16f0f0dd0720ae250b880afc585d14f8b1da4cc07d8804dc9f0e49561111f8913281c08fb4c9037ce57dde00e1305e9235711cf02385fdf023056a80fbecf1c1256bbe18f023cd59c08f14c90f57799f423efc459164cd18cd8f3e53c08fb4d583fb34e2c19748d69cf5f8d18512f0a30ff1709477bfd9f1a337e147c6b8d8912cc7d1f1a3f3e4f8d15f38dcf4ee3d08707faf912c7f1de0473f32f3a3df6c2fbdbbd08d1fe71a5a104996c776f871ca0cf0e32c2a80e77737b2e13e92e533991fe74fcc8f730901fce78bdecc160ae33f7b640c49b2280eebc7a9b3fa71ee0cc0bd7f71da3344b2a80e3fcaa30008c0e5472906192ae45ccb8f5206801f25518df7215934465594863f0f29438d660b7dd58ff207871f6de44043b2e88c871d32a6137fbce186bcddffe2b0c818ed5d466bce6ca1eff7fd4f1f0ea718d017b080f661ca5c2640f4e81b088a2ba0474c013de609e82153e61249408fbe8ba0ac0b8b801e3104346cd37f809cdd4c993b04841e9dea3800e7079c06e0f44c99ebe343cfa6b7c580d7025e3f5e4253e6e6f8108a51964644135340ac073d8da68c76c4831e5d83f598b304cc198f39bb9932dad08e9b4d351d1d38397070e0f44c19cd07013d2fcad25a0778cdbcf64b68ca683937f4e8f43d46599688aa7688192056003d9eb6d194b136b4d1a696de4c196b69cf94b1323e8bf119017c0673c3d22b3d00fdd2b3a96dd99cd912a3ac4a448da64c3d9a2df405a0c753005e3abc5c748b1e4f19007acc356234f48cb22a0c67cad4a1d922a3acaa933365aacf6ca19f039de1a0672a3d13f5e837e8f1946dd06396b1e89c20265386ce828282e88c4918866118861ea23e1a1d862caf9f4587e1876118a4c3b9c320213a734213264351d033b0b0e8798930c64432feffff3f0cc30fc37ff1d184ff323e7c19e1ffff7f1219e1dc9f84e70640b0570ec250cb087deb7befbd17c6cacacacacacacaffffff8aca47f32b2be1ff87bfb2f22b2b2b30c2b957aaab1ea922d8f391d49c7a5393f8d757e7fa5c9dab7375ae4f8c542a954aa5522b2b2bbfb2923a7d342ba9d4ffcaff4a2af5a9548a498c70ee14654265d48ada9a15d12cacac50a218a16f18a1efeeb66ece6dddd66ddd9c172a2a2a2a2a2a2aa954ea532995948f26a5a2b2f2a95f49a9a8bc8a8a0a6c6e15fa438b3024b4841e2195a23e444744444447a8d3e9743a9d4e2a2a2aafa27272f1d1a89c4ea957f9948a1ee73e9d4ea7b94f3487ea5017d017e5a13b14062a2a140715fa7e01d386349806d360da900b14141414141494d3e9f4a7130aca4773424151f9d3ab9c50501e0505653637caec088b1b7a84d698e174d2467beaf8e8e8e8f8a4984c2693c96442414179141493e9a34131994e8ff227143dce6dd2269349686e930b79cca5f022973991538182e24129a16f17a1ef4e6b69395a4b6b692d2da745a9542a954a2593c9f42653e9e4a331954a263dce5dd2a5528967ee52e83deec412ff711fdf81c9e449888e8888888e4e72ce39e75c2a95be54ca2d3e9a52cea62fbda9a4c7b9b3ce79673fe2363e821dd7711c2f41a9a44f42df2d604330186c88f47ddff77d5fcef973fe4a1f4dfebed2e72fe5effbeffb64737fb2263547465cc8595b1d1f1d1d1d1fd0f33ccff3bceffbfefbbc97349fe7e5ff3e7f7a9cdbd39ee7fd80e1dcdefc994013099368c66690123e30f44db22d9b6373b86ddbb66ddb3ccff3b69734deb67deffde7e96d9b7b433297d8f37d66cf4c3299f0bc99437444444474d4618c31c678dbb6df364cfa68368cbddfdedbf43837d6181fcd8d8f662b0b9c69335d68d8362d658dd037071b82c160f43badd65a6bad18e3c7f5250dae15eb5a353924a160d484891430d6427bea50d695559f298383e64947c7bb6badb5d6da5aebd76abd8fa65a5b1f4f6b5fe6b62f302d2098005c648de95b0b7d7739782c3965ba32aaa2da76c118c82528489ceeee3eb330b7bfd3588dbd5a77a2fb854dbf34cbfe41a3ddf359708bde19be536cfa83893c8a7b3e0def24e620160ea22a6add7217c364d809e8659bce16faa3dd937565aea232720729cec741947500a99a4f1fdba78fabb02914b14d5bbcf925c0c8ae3f98b832fb75e3d95286910bcc19853210a1a068e70e6f7afaf7640d2a5d74195d32a531eea2bf2361123d8c5d7fa49e9a2df5fda6664fac31d6429e4fb167855dad949943b3a5fe953136c8a81c78cb3b3f9aa9b11683a078e0f79fe266199a32a16ca92f630ee16df5978c32adb5ba67e96ec3b93d3565e449fb31532db5ab8bf6eef6cbf1eefe44765eef7bf92ebe22812f5fbee775ac1cfeb404c746f6d7e9c5591487aaecd317b552860acd965868377d5156f660ad4c29c5a1db5ff3bc6ab58b37aef33e12984b2d60282e524e2a2f50a91518313ed43ec33b792daab24f5fb129e3f1609c736cdb3abd9d23ae1a59c33e672302d9e2f1e878496cfb1ecf8ddd3be42c1aa2f739841e124fc76bb9ca3e86ede024b1da03daf02038e3c12e168bc5409607bbd90c94f160f77abd5ea07eb0131202c3073b1c1004ffc1aea7078cf120379bcd66208c07bb1b70e5412e168bc5c0d4839c9111887a907bbd5e2ff0c5839c9010a8f2208743550e82e0e941aea7074c79709bcd6633d0c583dc0d08a23cb8c562b118687a703332024f1edc5eafd70b6cf1e026345bac10587a70c30141109c0ff6805b0f8863b158cc08c446607ef085f86a7bf0859031ddebf502df87b3f08baaac108885401cf0a5e3801807fc1ea40ff680337006ce40f039dc03827706823fa50cbe992df6c197a4191f0ed086d8cf3043065962b3582c36dbf6431924ddbd84ba57f712daf63ffcbec3e97a3a9c0ea7c3e97ab6fd18313c18b3ee66369b7537db3e8c952e15338ac56246dbfe0a8a7bc1bd84b817f7e25e42db7e4a653b71385c0f87c3e1f46cfba814ec629b7137e036e3b6d98cbbd9f65fa05cd316db8cc02dc66db198d1b6af72a2b5d85e9b10b8bdb6d7f6da84b6fd53c90cd9eef12ed970b69e0d67c3d970b69e10fc79024109bb11338ac56246db7eeec2eeb794aeebf4f8f2f2127abd02f7e5167a4f7747374da3ce337978268fdd6447c38fc629a51ce8244e0b9f6a185f0f7f92263237a847f0b55ff968fcb9ef56475cbcbffa78a8762d25c9fed55feb5cb6f8d72fd4668bb7ddd669bd185f8f3abbaef334128dd120201ecaa3859e4729e5a13c9487f2681e4782f1f5d0b08bd87b5268bf5b0204e322847f942077ffe9d8f4d8bda65d7bee89d44d7f0870d3f7be7b77f1f3c7ad56ab156e57d95eda3e9da4fd7f349fd6fc6fb838b5ff343d4e776ca9709b852f6cf73ccff33ccff33ccff33cef492b1f0e6f3699452d6fb63e0ff5f5f8343d829af4ddf548a17d6c81342286e40d7efe8e0b89e05dff0b89e4202936eaa3e91efb0abff87a748fbfb006994d280f64cb7d30a43e90352e877fec1e7338a5a33c379cf6f88a87bedc533e7f9020d3aefb3a7fe612babf3f7f648cf72a2aa552f7e376dfbdae46f7e1a7efa53e1a4e7bdd6717bdefbe9b5f8e209ea783903add3d11b51ea93d345c2e1567a77be92615daf79d0ab978a5d42f1e0eef9e21e5a13ca03da03df44583a8108db9b883b2a80f5d725fde774c29fd8f12edc474f67d0a43b19491abfa424f3e1a8a297e6f52ea69db53edf356de6d11823c56d7b6797ffa634dc1fe68b67797af6c3e7f3d36bd1199a52b328f059a32726fbbc457f5efdba00ee6aebab762a0010424df4a960592aafbf22d1458bce2bf60b360a960a998924e1a82400e4d40b2a694808c7915955269949fff16a288d4bdfd10e0debe7becab2d7cece27d4f1399aebdb156cf74bf0b5da60dda848c609aecfba38b38546bad75ac75d66a1fcf5a7f9420e31f72bd4cf6b5c9f6f7ad8daf8698fbfb3fb2afadd9b71eed6b34da9b7df5885ff6586519c9c926d9572eb9d6c77bffb17be7f4688bbcef3491b93f3dcaf0bad01e6da19d59a3d016d92059e33e175a29648dfb5f68a7982d42361612c11b6bbbc445adb583b2ec90abeebbb04dc6d174b41d166999845f0edf47c898bbefd7573d2263e8a62c0be4aed97249ef7a148265a388d4edfd10e02685727736e6db7071eaa83caca013501e6158d5d56239ad64142bf6fdf1dbfe56b2a8153246e33e8ef4dc93e4e6e49c9bf41e8e2f7b3e6572bfd69c8eb2d1fdeac238e77fd7c7815f8fef394d646e921ee70681284b56d70664b7ffe83708a867d1b743089b9ed83cd2f971d9111e213aab391f0e8c7fca68bcc79ac8dcdd6b5f8e191e0eb5ed8538fcb7d002d9255bd0f87fca19d34e8fb668df9f53f6f5c07a36d144e6deb48c2f876fd77689ac71bf8616c8c5fb2d40307fb44023d611a4fbeff1170e99dbd3b3090ea76c9bb2d9840eedfb4d94fefe2c7203b4f8fba4906ba1c59286c18082826cf0667c395c07f1ee0f99bbdbf48f2379f49bb1ee150affa789a8b40785750f71e3c79af2b878fd3d6ccaa9d3d3e0a12c1758063a053dcfbedfada6dd5d38c4dc18c855f731cef974b240db69df17ef73f5eb31b5a789cc8d7576f1bebfc6c339078ef8beef691536b30a9b9b4dabcdaedf6d5b49c5df06d95512bb8e8b536eb684863cdf8f7cd5f21557857c76fad98cda549b2c8410f35d7b8e8b9e531963a9f529ecfadfd703fdcfda771ef43f8db2f6ada5d68425cb8362a720f37fcb3dce1f3d28c7c53ab523e9a41da90f1dda010979ac3541fc87ccbdd1b1c2b61da98beacc36235f7947b52563beaf5f8f903124f049a4f7c21124692a9b9bfb68b6eda7dc1e956dee455b489b509b1b57c96c8af0925f65485fd4c7551ee4dbe953196de2ab4d6fb4c8574ebd8ff12795922662ee71e26c9b7e1db489fc6e34f395cdda837680e52043e6ae2e175dbb8eb566571923f70f13e4b1d6b0305515208b2c95d8b4f690f7ab981f1965dc5d4fe8e3a1da44d4e9e3220b1d72b1d297ac51ff2707a13f646effd1735641707264cc1232c6fbef3def6d387edad3b56667596be90c79a4ae5af332daf56b8daf50a307b97c859aba87b8635f8fd0214ae43990aafa3ec044d8b52a61d7772884e4d1aeb3ce3ae439be9acfca12fc70ccb9b7af7ba33fc371ba7c359ae8913a81602e5659a34e177c0c955329fbcc835cac2e64f44d4e4c72c7857ee462fd1f2ac8d4c757e3d3978cc15f9f0a41c66c5fe9fb1020fe687c0e21cb1814aded3fc3f95b0ffff994a2e88f28eadd28ee71e284e304aa53564b42f1d813e7c8579ca6e141f531ce99be3c48dcdedf6eba8748abb847fa126dbdd9c55af778c2d181f7a9ee97530ffe54f3c04310140fba7940808bf36128a1635693afaa8de72f848e659aa6572d919005a1bd10da676d6e0dd446bc354cfde7dfcfff5292ac1b54a57d4c35867b54d91acc0b7205920117b5ed6d587f0b75d8aff6eb573dce6d0488afe46b9f811b30aaf1b0859fd4befdf8f242a75b69372d6badb556ba6dd5242ed5974a5470b34729d33e084bb5f75e6cdb6b1afebafddb30f5365cebdf229c821b3e5dae23f47dd0f781caa14d51ddf44a47799441defba02ce9e2534c8fd2e24ff297c0ffbee5c5ca962e2f35a48c0fd9e2425534854249d9a2a49721f7248e7b6edbfece96afb6273dfd4a0aa58ba9f0013e19f528f9f4b7277d573f1c2494a348288d92ba8776a1ac177a3ca9e8319ff4e4f4f43e1c1c178e2f2fd4e3bcefac746aa7fdf08712593e9d4db65767955eb91f36b97b4ac3573424fd143d62177ac4287acc263de6935349ff286e4a7af91bf722177a1cb61fa7a5ac21f5c8b2ef97a3fe767fab9f77154709b8a7d170a1533aa5f5ebae7a3462bf98dcac932ce3acf293df494a3539a776f12ddf9fca773d7a4ffa4eca1d3038bb789f7bfadafb9031f2bb93952dbf4529835c88abf6640dd27be8fd49d8221cf3ee7ebc61779a88294392360901b3a956ed1d2e1e65fc457c3531ce599441228f28ee25953fce9618ee608951e1335dbeb23f5f3edbfef4f15545c3b63236c5cfb63f6b8e70d54bc9668c2b23cacb27593e68c7c937c9306594e58fa6934eb9f8e305799c3cdb4a1df2690ef9f4290f4672f0cc1ef9009fcc3d4a723c883b5cb4cf3277cadb11a3a4682955f25d682bad9c13bb57ab871f66e3b7b1f1cb978dbffa575dc4a1f6e1a8d74e79fdcaaf544bea6153fefaf547916e2971587149be54a244923d7d48a3ad3d1828854a6badb5d64a29adf56badb5d64a6badf569a55f2906b9d65a6bad550bd6530004440a60dbbe04e60e7ffb5422678fe256a2c4cdb65f45fb32476ecf162f44aafaa6485953aaec5b0bb3ad85c925f28fe2b64f83c5c5f9e2f3e043c6c86d279544940b9ddc783665f9fbd7ea0fc3ffff95954fa55e45e54fa747417993e94ba5cff9bfef3defb7ed317e2bc33bb1a43c3a036ab3a9ccd5711ca433652e2c08a6333bf044aae60df827ae52ca245c692b4cbad40e07c1407922c5995259b050cd7ac39442964a527064df225ff94a2ab109daf4b1d095f92aa2e3a8248bd9eb92a05444330000004316002028100c864482b12c08236172f214800e79a2445a589c4bc4510a2421c618a49422861043004006066064c401002734d31a47229058ce311731501086d20b13c9c76d18ea9c890f8268b4be475c3317d907ae2d9d1087f6db120fc76bb9380c158a180a44f484f817f12610816a12851f08ad4aa304986000f8dc661292e986be11250280729e4d403802a99062624723372b871511e0fa9fcede35816a6b56a99e6a927bfbfdc01bb9191cb62298490bdc046300211a96ed2cc6b7ec755dfb8caf800cf34afea323353413d6129dc77def4cb6a9f5dbd8d83a71e128a03915a2b83a543399f10b6fd24c261d1e715d8cb20824c4db44ef4e2d7a39a4f533a0d101e7d3af79a4320123fdd2bde7643999e95b865c13cdc39392841c055c960bcdffdd92b3564d13baeb41fec9ddc8feeebb7e619928208409abc609f9b9b7ff93de8fb382dd476fe1dde785b4c9663afc11670f454ee13868897b7ab915002289e2f4bf2abace12abee638531b84569609dac86b3d9ef1763fb25a784991eac43045f767052377435323eee37a1a638f999b201f07432b351d0f964ce763a72ac4307a1448242fd1f12dec0553e1ffe21b0c7a5efb838e77ae0b478e2929e5e7dd32673fe19044548dc0c928a2b5401af70f9272725a152863469a88b009a9904bb388fc71a418ab957512a62bd3728c4f774ff68408869c0514b66d780064f6e64036f39cd3921020ab6420fd897753c0b2d101b915601f999ef89b9011de16410a1a23c79a351a507efd7d888d4234ab64906d87babad51c20c07a42c8528a28908ea014a5c94810c79ebe4ed4dc6f2a84a5ceae66166e4165dec1082a6e4166dd932d095ed660b07a83679d8d9b35253a105c0179cd0338a13ea1acc17b0acdcb1002cbe89ec2db5758742905d5f01281308fe0d4b8773114cac9c30f202926100f2904af58af9de71a52f886fe6a2e28a0d53c001f766025c27d87108825f730ee2e8074a9dba16d2571dd75c627e672a35a31651e3106d633317f6f08d2478c02665df744343e69d804ed481cbc3693d009d9798e10280473fa8b92c01a57b78666282b45460a815bb4976734269aedcdeb79a38991aa89183ff95de3f490fb6d1a5866db68bea27e89fa39fa756d87c54a31f6d9f4900800afdfce63ffc5d82461f54b500baea3731b314fbea61295e655c0a4fb0ccc510387a54920639835a1fbb5a952dc524494f7e0e2df3f4594a3273f088ffc84c05545cc84f10ab6ef463a88851115aac789e0177fa87fe505ea9040f38f64e150c0bd587da6995e930de890e16f53a20c69ef5e434c95d5051247d8c200310a31207a081b132909565e96cb6379701a41ce80726d9f49059784206dea762e37a9c9bd025a8389bc58e249da7f3a54500b3930cd45f6f3289d9dc62e31f3190062b3b9d815bc13e133ad66e30e601272771a8e1df13bd98243a2f156b97d4b3cc3569e992d5a31ae6ae653d355f5d7b4d744843741bde96e31a059181b47ce0a47b4e38214605b1e790ef7638de507d6a7c049bfc0d350306b44c0980409556d88b1c5af2141a134d555964bc16bebcad055883c16c6d487a261449a8fced7d38d97acdf1bca66e528ba78a28ff857289668ceeaefc0604ead9e6f24457dea683ebeb89ddbf85d6e3bc56d11760044725cdd18fa26339f14b5bce315a7e209e90e4580b7a24c7d3c4cb6ec09f96ba89002922edf52efeac7867c122b22ebbff5ee9cfddcd4c251479508546ec88a99a0cbf03a199a00de496d13156f14f50f4f834f400e53c726a7d0fe20896693aefc14c056b2569904b1ff60be51e4f55ea3883e5a71c2f498eb8358a13163e12e3e093e3628d63ab8e561c9765789c226417e8484bc0becc4beaf6ee1e62066593042f339da68ea45f1f0a5a0557190f63ef3c231cf4669568d3af8682371813149dc84232158462916e3794702e2ad6d53add0cfbbe491e67ffe65e1c07ad6f9da9b8807d35f710eddc206a98fab7a404869e4a9a91bbd5b7cce21a2c4231f1316ed125391500504031ff7e02fab71a6a1203f3fd6d6a45297d7eb0655bb0764b2daca42f7d9f53d06b9423c4dcd1161e8baf37c5fdea98de510d4378f76aeb014e8728007992e2993725fcdb26a7915ceed045cb7dbf1862f5e0ab8e369366a0f5367063b13b73a16c38fa878b94879a1f4b140319bf3b55f3273467e35898a285763df84145f044ad46e9b23659b72711d6cc9e0710549596fe27e996b0932e4284bc519ee315e2dce64d4271b5583445f3150e39046c47749be942849723ba0a9115f12530a1483b0e0a2361e20a701d4c34c8685d64beb0045e61230176a438fb9408be1840f85f344e89af4894e719fa170fefbe034acb484798843ac7ee97d727bd50cbaf7a26e0f0bc8143eac3e647332d8ccadca044890767defb529e003e8e9dc53f09d5c76af77d124c55c5f7812ee84c626b90a618114427e44011cba836f1a6a04e06a09d7012522dd2171c6eb4fb449eecef264e860de918663fccd02324890907eb4e598ddc653f663f1d2e14812381a68ecceccbb1167d72fca12a5100961da1fe08567d1e574d1dc491f6c386ca25e9991f149c68a7bd3380eafefa80bbae9f3e738e3b7b410395f1376596b01a399bee72ce10d416a72af0ebd9429fcc08afffa93610eb20ad19ed906e22cdf00bbf2414677e0cc22dfae955620143731eb792c4b2fd223e509581e31c12da080eac7240957e9b787b28e94b5daf054c62c75c8f00c03aa5e7d09b8433a20c808830bca067bb480ed5514671f90610b3e2741503927ee622c969104b672e2925912f625a4fa61f26c7893d04be95035773930ed75aaab7ff02b16cd8f4571b8dea100064f4b91071b72d8f8a92b7239e56e51ddd33dc27f685d47b6c5ebdeaea01aea0f2f2b9e98debdffdb7dbda642b0ac2eda4ea429da118f52030ca4f466e3baa794f18b6de00e3240725f5ba1cc977d6a1402a87de4f6862a4d4b0257704ef539ab350394c8c8a6ba4d3689e258120249d684c84d8bcd7b4123e9c92eb4abcd617b41c9efe67e19c222e63f84a2bc5346a02ac965ba21d26d0d15efa8880245a72086ddaaff328a67ea55ff4204e71e601e78a17a96a33e67ddceaa09e65e556fd0994dd7c1189f8e1e926ca0852f9a1452b5e513167f352d8497af28788f9bb42b3392e8635a53aa47ec0925c1fc6fe8b2375d26cfcff1b24f2d27c6dd4178361bb2dd4c877e31f1c8a770179272e3ca5a68adf2d6120d7b210d11d4b183b3d3441e4fe1c24050c924bc0deb335d7aea2c5d997a48ad49b8da35a3330122d31a42213ae262317190ac17796c41a0a9b43188c6db5991042664299e48a199bc2b881349fea8349bf286b12ab340fe267c40667a0957dbee235c0340359b136893c073417773350543b08a119e8147339d883fd34ab5bbae066f44fa4b0b7fc2892cec30f291850834880286b7630d60a20d71d65ff45181f02569da5cec2f83bf5e49ac24c23ca4fe9bd1d96d6ea4b77c0b9451607c9d7a7d7eca38688272b5f850dfd27b8e30c762a82e41ea830d86ff53911f946da887e64c6249b7d832632ea064261b756ce7ccec43950d9b8423958c620b8824e4dddfd2d326364b5a26922db2681424e0ae616bfad088752c3a8e89b48b53087adba77e72a35cd8389f6bc8cdc5335c6aa9d2e9ef0993a16259f483cf257c38a630926680f4bc8506df942bae5dec7837cc02131eae452a37c00ca59c039542e82e7a6f786dbebdaefef6e73e1f28c37ec6dd2b3bc280fd338a9a170cb9e31984fa19edb82a6cb409f04bf2de614ff52124c2c16cca22fee20b85a3f7ad092043618ae8bde6bb5d0408402e233618e8d2d9e04b8970aabaf9cfc215d5d8882611b1a2427ed2d125427c0166361f512459182ab636a2a3b215117c718cc364efe7a3ce116e35cc32f258ad8bf9ce88a45245d5a5767e5ae3a4ef527560b9c529341267ed20119d13f21acbeea1c3b8491404a07a8aa5b6faca78458cfc9dc670add1d17227b2cf83bbf58c982702177d59f730d183412519cc7ec54c5c3e6b485e31f1c5f167fa96b8ef74610a988b975dbf8a508db86434809604baa5f4d4809a5c2cb340d6aa44014e887b31f4f3201939f4533dd266b16916f16aab99fbbe0ca98a6c46f29132e5c0d14d82d08ab961ec67f1feb8dee6a9c0ae8c5797e500922c6e314a090c3fe54b63e00e17930108eb14f18dcb5fd62215752bed33eec27de480444ea2ec2c34f2573933515a244d87371e157180f9df1153ccf2609e401c18b7317da9f445f23e506a0ed1958560d5987300a1d2c9c1a30b09f77f54c932687e955583f229b5b3325d3442d3dd97818f60672b96aacf6669980f88dd22fe2ec9cc5e7181d71ecff903a36b0e844253bd4a4af04c588f5b2a0697fc59ce02c91ba1eea17be12c457665aed2a60c0c6b010dd96c32f5aebc00f5ee44bca6111dda98b70b949fbac5d193301626ed63404e1f9f69945ab394e4e8d024073e009246036d49e55ef8d0c9d00cd02c060c3128e45aa24a052f5d1093a5bd5bd11fddcb3e1f14a884edb260fa0d079e3d1b0c92a5ee6057e7e018d32c1d8ca341da4d6d6b6d6beb2bb7f83913c3ebdb5c901ca556bee230e0ee393ecde70cfb617d5f0011608407b3966ddbbc6a2fee1456a19b697aaeed9ef7006a39301b6f149ea94d1fa4cb9c34911e98a551a25c8f4913d3622a1a466f2ccf60878ebdc779599be8c625c6e4df3c0bdc361c413f2eb05a2a89a22d40e35e80df50d53d3d29ea35a23ab6d163fe7bee8bcd3ffb4c2820171f180a56490e96d319aaacf4970fc388cc69b1c95ac15471c95566c3531e307de717ecfb44d9875c434d03ddb9d8b8050a9fc204cb23fd0cc366365e8703e5532bf9c96cef68ec8058a46218b7c52be85c818e1a2e06dbd6f769d0a39fe29d0d9c1bc43becb205950688589def26889f466b58b574c1a22b73704e653f344a8432494b595254814815e87000ca34ef7a90b90478afe915aa39002e7161f0d40604b1703a246d0a86703652d14002e4b0d0100ec1c6440a4ea53e294dac3d81c2921831001fd5eea82e5162d8065e91a927e8287744567a1426945471409f05d3df71e923b450a82dae0bff916ddf8a78201b66d15ca4e8107514123821c1aac0ab0abf11294516c031ef1466e332e3fc54412ffd5f070aa0fb8012cc2ed7e0e50c06244d6a70d6d7f32a2263204e5ec2dd5ed1e03fc7797e66e4bd7c4bea455c432c7fe88ffc2aa9735448df0f0a4454bfbcb60177873cf2144fdf7af1fa1dbc5fa2c0bab24d044ed1c29bf4e3d50850fc2b28c0827e79ec3f989c261fc7b36d804c8b18861c45accc19cf37b4ebd220e4ee0db093b6c73cde5d422973f50f2df7b3b91937276a1a3e5ee8039941df2966d97fdce064680a93512ffddff3420d6ba9ee840601014ea22c895213abdf1b9a007532e50d45bbbc0d4823aceeabc429923ccf578f64b0102f9133c41f0656f43f629856a516a5cd7a352c2a3bf5ba94440cdc4101f178352ea676aa22d3e520af34bb7b3e21540cdbf125a403d550aaa63558dfa759b7bb947842ffd0d8eb2116eb84b123525784584d1e4a1231c4d18efa498c8089084cc15f78a00a9525c03fe5618fae9dd35c3410c72c524deeefdcce546ce08ba341c092defaa44ca3ed0255516d06d79c4d8b7a667d462aa7fcc68a20840bb75c9130a02467e390390722352a801f7c865f60cae1e068d4630883e22f3b0b7082011beb3f8fa93c8cc1b8acf74744c1e698703c0608b4fd15bd2fd36801e073b0a906f8afa08b2ccc89318e91109098b06576a0510e50c72687db41e2918f87210204b6fcbd203c8f763576518c4acae3f28a0b700619a01663ae873f8fdd5a59a33aa0362b41ebbcb34a7b1803869c9e63828a5077ea67b75628081abe9453a265cfb0ac6a2fd07d2ae2ac4bca92e1a0d9d40c1202b8bb6f53a08f857606d40543f0128fa1e9712a523d919d171782c8883e10d0c25c0e084200cb9894c2dd2c80620cf086230d1ce7d52662efeabba22e2e3fe4f7476a09538c5286430e9b308e86df374391d52dc456c44aad4240973f845654a4fc8121585fcb559c7229928259886e24640e24db825a91595a1ac3904c76465302fe23d75640474fb18641348554649a1cd534fb77140e441a70413509a904fe4124632e5b778385209625841658003da3914f44305ac653d007bdbca7d4fec3fa360a7ddcc530449fbc2c0eb81eaa0379df30d002e9653013e8e39fa4fd99b62e047e4f91e8c96b1622629460506162339d8ca8c1a4550887d46636d3c0e811faee41e861ddc8be4d3737901b8ed134057b152517afe19136b91938b21e4b162f7d14f5cb3a80036334ba5abdd5324a52234c67ab9a7bb4c6ca5ab755f88558c413e9ece20e419ed3a81c65f0de64c9cbd5d53d39138302009cc95131cbe0078ee0d96264fc630fba19e0aa055f2cec0d323279b4e81621744a3a847ef3288c9cb32389848ee68f17917ee50d1ca4077e86fa852832aa3e891307e23d326cdebe2ecb97afb2bd92aeb06030fc7cdf5b1245e3963d5fb177bc2432c412b205f7b6314b519241ea64f4f695f803ddf99a26606354c047cd034b8b93233387e4a85559c8aa9d31fa4b9cd916470e7a7b5ea455477b3cc29666377b52e00588d01a0cea046b712b9aaf5209de754b2827975798583bdeb4db99f0e24b2e38fe865ba98c3873ab7fbd6a3c52acc924b063e0e9014085dc56c66bbca00b2769311a9cc572a02b0e00cbb3213691de710e1505ccda82ab6a552a5ad27f06c943118ea483ab061424474413292239481df3ca98610447b35899eb0f8db86815cb09843f7decf229b03da75ee440b5fd59504a118c49681b0fbd1daccbc28b1b845382dcd54f965e7acb6eb4a36e458cd3eb2845ed02fcbc5430463888ff55d32bd354535534a0aa493cc03c1a498fdaf82eb2a6fd94087d517f22d7ba3109af8eef23aad6299b9692f4e62d54cfc1bd34df621fd0972e7fbf93895b3f590b03e009466672ae4bc8f813b65f2d08f2a06134da32c136242f01c159ab19a155145f2a822b8fb2654918552d7227c8eeebe797a942768a0c85620c3a8487fd8eb02113524be99754df9c0b179a2942fac348d082495cf280e58369f1c08f54195f6a6785572a598f84ae7f2e8f38bc37156fc038d7ff00b220c94debebb24767f59a21974bd3f3f61ff6570c2fc5066c2a8f9dbe3a94a22fd50b2e7f7e5fcfd65f3f76c76411b9ac4a1034609118033e14a0b7abb19343eb707b62933c23cacc5f13735a9a158f64fee7dd9346906234dc64bbdbae8f1f53d8ada045f44f4ec64ece63c5acf26485260dddaa31f58c5d6ad3d8ac0bc6ce89ca755d548ee745e22615e1872ce6ba96a847b3a6f91302f0c39e6b15625d22d9597689817061df35aab1ae996ce5b14cc4b03c76968419d0d1dd9161fe82ce87107be663c3e183336348c0f83dcae29781064128a9d262d415f7f10411b7443fbde7b277222d9323911936595c1844e2a4326277292cc323981c96595c9844e2a4326277082ec3238d1a0fde69bf7df7df3f63b13ddfbefbe7bfbdd77ef5974dfbd7debbbb7ef7c1fa00fa8edafd717692d837468496b90d74606648bd75485ea5c954f78e6a0e45432f254462fad32c8343ee4360e9193578b1c972dc0303b1b675d5ec475110987e9c0ba91137ab571c9902449304707c7ed9b137b398dce72d371c82285c55d95aa6abec5168f3d51ef36e896419924e53001d50087e167801a4d651272cff248db5d24436ddf9cecbd41ac8e7b8a830b5e0c090f1a796058fa13bdb7c40bb96f2128c1cb9021c141c75a5206c93cf35097dd759dd4bbc1ca11a5cfe8b8ff22b8d897d09001b119500641e5c1a1ae5ded32d173c7f64669cdc230566ad409397cf2c867803907d9e94ff6be2daee37c8aa0045e43860a463d609cdec45e97c7849c6f1944dc4b7898a1d04b312e83643e7fa06b5dba4ef6de6645448967e9b8af18a4e065a8d0d098172c83a3e77d5077ddbb4eec79c5bea462b9e889d33a2de418e491eb881d8065c53649cfa5771d379f3ba26df0f6d4f3726389cb20b14fe869823ea4c43384dc577065c99424a4b48cd6e9887573b2c715623aee2b0d2e7a352c346ce48162e9648e7e8ac9a41884dcbecfeddac9ae48225b5006d9620106399fbae75f6689e4262bd420ae0d61df98a5c9a1649542bc288632c0f8e0f88c1c164253a0c11f6aa8350c63103123a3216f883f98e23498fc69cd8d59c01bd91012e31c6cc5e07a0f2ec936725f612cd480435b8ea8f57008ef89ec8111c6d41ed73aee39076e1eaf6239a6534bcfd8e018d0e86304c31d4e34fc667e078d6a0cece18e77c419f500cd3a035cc4682fe248a3a3c10fff1e610bf6fd00287e2b76b4d1c19cb26ff348103d8cd0b308dc4bd988d7cb432120692c882f844334666a03c6281b66b3ea51028c88f8f022461a331b87ca3cb5c5b1af16508211442845fda9195c8b7a3036d7b2783ea75e47100944e323e6d533224e384c4f628a339b41229111ced93c3a2fa3e21ca2566cf92bc930243c9bd3b1b0373c5d5180b14f103d7c4bcc9273272b01d7cbde7a4e4c5b350c4c7c3fe0a82f74e9ba8ce975c833340eb8831506e650e31b0256aa189f786a863694e369c0268d5d5c8f3e58be1692813c7103b88b82bbe9b9ba95e1e3993100a9fa130c00061d77cd0231ce8f5d2ac32fd048ae0d80fa75a769588214c076a529a67218afdfa951810391ad0b68518a065a1c6a18ccf4a82580b3d17fb06a866b53d20ad38d43367dc76c1cb20cfa4c949e3c3ea00d2ff184e07073ebe857cbeab83eb3ce7607f46957e56aeb09a125834841c6eb809b2030a0c7550c973de0688560cc16f2cb178b0a79615e440c34d81f5176f972ac935900b63d22ff80af10d6091dd203e9da81ce092a719b296a8fa09053f89f117e5f954af9529d5ae733ea8434d4071ccb4ecd0e2e9866b820276dfddcedb4fd6443f15ae74e53e4d2a6e8d9a4e96d779fdd6e0c61324bb4ecc6e06438079cb29ce2515e56878b94eb210c6e62c761fc6bb8fbb5c5d4a516f4456d1e30aad70a94ff09d5fdd35957242465d12e1b90a9fecd3de05c91109ff6541dfb79b85767e19d01090b5ee4c5aa9bbf1b0bfbf0f5d3e7627797df283abe8edd197433c9f45a6beedf1706a0bdf4beb846bd1a2da12c6be829f4c9c24aee881f9b74b2f462f1ed2729c9ceb31e9a0d6fc871de85150327d0e5c143d718f20ba40c249b4a0f787914c8e053d343a6e3d7bf185c82e126c1ae47b8eca3098fe48c8795498edfd972d2bc1634798f669176d69023e0ec7076b636e2057d1403234e31a32288bdd6fb45bb13d97a392188746246f144c77d4ec36cc9528f81b6ff8dc197444fef8b343d683a993b517e68d934a96464b175a1714b5f831b682025346bea7231b1b482de1e6eff1b832f899ede17697ad07462f136a5ae4d79f513eb9d171b632509a6fc27cccb9d3f6720c6224654e5882551061e2df0b387fdc326f5caf06bf6a13d1cd876320ab94b5f5389ba2236b62e911ec6543e4b59dd8910d539624b94815703fcec69ffb18bfd32f88e1d783b07b6f386993889ac9f8e62f5ab82e2f9c1c45ec34f9abcf3f040d72e366e4343cb66bf81aedfadc199451e2bbd8ba241a24abcfc3b917303c1e4037e869a2698c800977198b2d0762b0ae7ad61e28c3ac7b6916403d10abd7bbabe6d267526786b2faee740d769de1cbfbc1b50dadaa6ab78a418266110827406adf407c7232ecc87baeca6e534169538f9187c7dd50eb538f005d3eb2ec84e028e31c9d1c55c8a70b44bc23140f60f80330aab14dbb5caa2d5a7247a51e2f05b4a5634ecc0afa7eb8b7668c1812f6fc45de876664247e45b8f87932612ff0415d1683720b807bc95c9c0016a04993ae9c21ba0128d1a54a60195fff57a525dbf5b83338b3cb6bd1b85878020e1b2ee408f8d28371aab3c2b49b8e38cc76cb21171c1bb6637f4220ae79e95a84133d52420f14f574bcaed6333f166d16bfb223d0e9a4e66c6e8640feeaa6842f7fab54b2f9684d8b0603d6d22bdecf5adab530cb038d065b79dbfd1d085d9db80e3e766b25c9cbb2cc1406fd0be7731d8251a6090b30b7988bc531db5119a8c7f3eb1c1ff8926786066ad2dd1c8b77a41c05de8baa1148c0336ba8380fd351c181f7eebe6084d08331dcccff5814af051f4367d14d7116bdf2640545f24df960d457b1385645b87416698dbcc6f793aa1eb9b308accd581311e5e95dc1d85ac8195d5a421651630d947af25d5f1b433d8b2c093abd75d28be5a7bb1761c35a9ee9764d4973506d3de2b2d20d62475719d4a9e7f0dcebb5559390daeb1091eb858588546fdd3d79372db472ed1ce93d25db8e9808af0c917562ed0f998e868b03cd297e60959b9ec6b1f5c4272967405fc79e15b8ea12d6aeeafae2242b3ec90651422cd882d0ff96b3d9d0dc720f9f3f1078998eddb17e8f781eb1bd4f4810e3df0c59c85ec0c6e4e23ee28801c9faf47faf84f1bf5a0e0dbbd796063e942f4311c0d1595fb9dca09396482ed332c5dad0ed435fbe5a069d7bb94b495a70fdad26cd03b2c5d289a18064d1502c966c22e6a4df257bf4613accec6ed3deef817a726e1a229d941cabdf10bf0d5c3d16aba7208d038812102f54381d87b731d3a830396624b8abab6d911a787c7cd90e22e6965b9fb275c5109cb8ffbfacb9c0e78ca214afc432d987dea631f8c16cf4ee8d3714a5b363b826abac31ba6b3c94e2d73620237525ebde3ee9ca3ca58b307c790c6744d3d55dc1c8c4c7eff1137d233239db31c47f055b6b7dd1d28a7d32b340e3d251750c9dee130a9808a378c824af0becb78c3cda96b00e51948da3a9b81f77fda993599a35c9a8bce2a43e26b952b4586f56184e23f95dd4a750f4fdfd7de33343f7d29ca42fdefc35efc61c9a3144070d49af541eee0ffc13915853545b7d7c4644ecd008ba2a1171f5e9ccb361c3372d56fd917000007431200679c5716032869a8f7bbd422b341b9ded8747d371b3a33e5f48d51499c5d9dff22527989b8e5f3c7df856f3dea243526beace94de14c4bbcbe7ea0567fb97874cd342f17a76bbcafdac38a775b696484f8ca0f856bb36563f26299b293984f93c2d5655bdb5c969b6977a1746a53f5eb1256d99e2da3e4fdb5886328a35f92789f33cda690662e68f2bf180de99b57f7f28fbf48a0d84ab96244e395bfe5cfe64071ea2acdfeac3d8cf6960fe67f37ce40e3c90553c330bca5d3092869e48c1299013962e18c356814bfcc5ae8d6fd43dd1238e8930e391a18a6825546b88bc2cb520f2dc41dc5bdc39d466e0b855c40919048eefcf5d717e819427206095a0c43c2e7323cf16067d0bf2e837ad89ee32fe2f2016911d3002bfa225b029532fdf9130c920c69a899b039b3be5d74b81c650dbad99c99c44f997519fb78b46442753f692a5d6f3892e4bc8cfa25b446e2d44cdacdb828ae7dbc211eec43f359fe1b956b057e54302f189f4979adb2627c267e57a83c08d20b6a63bc5c54234e30166c8246cececb8f8cbe6ec59d0455cd734e2b6bb7aa8532a571b80154fe8373749e7702e3561a5d308f21f63bd10192cf33b7edbcbb67f1673b57f2259a34b88ed07db8c875e9b7d6d4b8b86df774448e9204aa816f723faeda05e5273e1f8f234ef87f21afd9b036c8b65fc83a302ce9b5132df600c0fb4d8f8271bd3504cdefddbf754fe60f2b03efa502339216e2a717a4bb33c901a0e4bcb05435aad8a102e76d7adaa12064cd0efa71d52274d01d8c772059a5f0c0e8de7abc5ba09d4bbd1116e42900f60577863d2424b6bc6a3ac88244fd227ec64006011284a04082101468d0820229a0075190b21f320c462b89b5094c98309d29d3263561d2b4a64c16d35c4d17f09244444f85d0ffe98b8d252e0b3c68f593a980c73015668cc87ce077597a02b04ca193f941af787e06aeadf1cd221a1d71a6c6cc8d62a5d7f7b40651e8639c1a9d6b57365e929db71fd3a3080440437b6a1e7196f2e3fbde92db84c25a0c767c05635c160b018c0a09734b8ff3ae395744ee210756e4b10d9f054d4e34afc6beb67346129ef36433afbbe1fa5ee425252949697bdcd2752a428a31c4fe94748f8153fd130af73dd84b39f479a515f5408a1dc2cac53fd64dc6d297bb435efc47219ba9683f5edb8cfebd6e16553fffc9eefb63d4fdc39cac282a87fe439e0c1695fbfe7b54fad348fff398ec282a27ff739aac8acab9f945141dcd18c24e80ca97c7ffdf2f545199c88f3628635199d34f76bf3fa2ae3fe46755540ee657454fc92a8216559cfacb3afaa3a6fbc32f27151585f643e7071615f5fdbda6fc138df6f39567151525f773e3a75c54a439d45008692eb9853954d92b226090872a2ae3f613ce4b2c2a83fe41fdfc3748f26729ad75d00237acc73916d500f8dfbaf4538df6f335e7141525fff3a3a72c2acaf3cb66f2434de1b76f8eb9a8a8d56cfdefd92b83f71856609531edbae984170d45d549b6474f7b1976b71112f1c8c679fbedd4a0d2807de555d22c2a4da42db5ae650d0bab925054b11460b7d5ef4cd270655199ba7bde2e8e5554035b1707fe121f6943684ca78bca086aff5f54e33ff9f477a4fa7b6db3781bd1c47f26a3cd0c50544915d089130011f65a0eea298a7ed7e50c3d6e57549fb8041515de6b28d5e5ce99d9a0cf54e59d2c86aebefb2e9ed817525809252c90b4d02f9e862bdfcb632793ceb14cc85c4e0b8eacc45e130432ba59adbaebc6fb9aefded017f7460b21c103e65de25371121f52e3d6a332e91007534191f9a1b151b52706e2e34adea42e7c9842031b4d8cf1861e96abd95e4569a3a53d4dd4f08c09269749cf15154edd6455abaee8af7c8ec94c84a82d8e54fab5ed2077da58243384312b47c2eafc24e6a9a4068d4d81b99bd31f33146306a7fce9a1b21a46e3e68a0facfa6ae386a90a1ac33ebc1071c81d8b1c7e5a4414358ea72c37e4a14d8fca2611f1fe3195dc2356c0d879a28ff47644eaf77d155aa2c74872295ad193255278d4812207abd4618daf7306f2d7ec7fc2fa297ff95fc227232c358479ca926b33a40b0aa86e57123668d1cc7025ee99d0e8e955d307fc39333c6b7605a9ae78209973716bcf801fd83afe054468878fe1174c89b579d1c06a953ee2af2e4ab431ad5780990d9bbfe06130c30a8e98b1167d49e72708d32f34dfd02272cd2be0a295d55fd9316f103585e7be385e4f798f00283ef5575c014c31a179e90ed902594031764870f8e83088c8ff4165f04174fe4731f232aa3fddfce058422d4cbc873b0a25ada91acfa0504c71a196d8c8d54f32cc73cfe97133e9922ca2726d731d6097be8ca4d04a3893a108feebdd01d2861236bcdae68845fb7b3a84b8610327ad1855f38731f12d5af14da5d78982eeac5ccbea11b18df9a7c326a013a22e0f02a34e046efec2103623c26e2dbc51c2839f3bac1827a28ba75a7b8c828a288fcab14fadb36de3198a55c106acf385c7a32e1d60ad7fd6d2b61ae9e933976dea24a62c3a92af9560cbd677f22e5950197642f23f62b939a018d1b13805085c46d26ed9ac5bc0cd577928ff47afd7d47b26f4ff81fb2b2aaebf62be43b611a9f57eacb72899a329e8177a5b534ef3a666c7c50280717276ece6b7ef132aae74eb991863dfece0cb71921676814cb72a0dfee76275feeeea58de14c5c884544585cf624c39c5c6558e5de958793d31d79595357bfef76e39f397c445028243a2f2ab19330f513bdc91f7c2a702dbe280c99baa3889627ba79cba5d3658639dbfe401b36919e2f4819bde9b38843db067226ffe33b657a943bab51bdcc23ee016badbd022e29117931f5746d008ba6229691c4ccc31840c9648ae29ba088cd90024cdde78551d80566caac9d9133d38c45db3cea06d9146b9e6d2c453d6d03acfff41899d68870ca31493b01fda6dba4e2e492797d47494dd8845304799fce00d3747046a55f53fb3448c62e38873ad31d970132df5ea064e7d919c4d2449bd76b17edf731a789171be1803593e07240dbd2359436c52a4148c32b54f9d3a05b1b742dea153027fa023350d8f38c5e9277fbe6376a35a1685a9719b323b96149656b4a1a7ae4c205c1706b34b448b270ab2a56b8582cfa8071b0e44e27bcc97c067dd35da4b1751a5b74d935d26a147915acc0b94baff07d4d7f1d7c6b929496b56ae2096c21068df0181fa2f92d972527447a22421c6a8e2085a1c2021a127127a7740f312a113f3e421c19fe641f3cc47abb42610a914b76762a4168fca0c6862447f1388667512dcc0ed33126d3305f7521e0dd36e32e962eae4c5cc0c2f22ca4e8607baf441b2ebf83b3f7fbadcfd7542f1e9ea1b502efb08020d4e0cc3d0e69a2b60632bfe4a7c6abc12c5158e3c438d008202399179108a80512300bfbd81442aec91b38eb8bd6b4e8ae7b274a8c28c33fcb3eafb3f8cd68ff726c1ca565f66a53ab40cbe9eb8b582d291f21923c573eea1c84148f2078247898823a8317a47d6b9115115f16391e5e1b4ebe8babeb9e57b370b696285bd72d623a0e41acfd73525e4aafc95c4fb5de24d99edc1e34207f177de4b5719d2f1374c7381185cbd3094fc229b2b5795b3c321cbc9b6721311175a2c85c291d89064448dad65be4a92969ae2085904ff16ba604a1a1e690bf09277b250bd7f03399080d2ee807b919d87f41650684f06ff8d2ab27239cf7aabadf508ce80b3142e53cbd21a9d03b36a74dd7fbba0eae5ebafc7b9bd3b2a5ea15c48b343d92a157254ebc2b70b750266f338626f3e3afab528c4d81656ce5c4b313e2d04bf6ff5d10379c236c23e775702b6a9b05361057eb58d1d2b924f7e2e31b3198b25a90655f6b3e2669e699c1d98905e18b692aa713e3c5645378967e7bf3c2e4da3c42b31360cdc8061f05cc402ce188cb37f809b44e7e68c64b81a0597d2968aae826a84a219daddf153c20687851ceed8821b4d6444205b241dca75b16da6013726f1737e1d2accd8c2d5b1c71cb1e1a03581d563a237be1aefc3f4c15c230e972986272e21a682343dd01f5807b7207ec1273acb6e513c83dc0eacb338788e4b735178ffebcffd3bb579d6d428e19ed91bf681dce4fbf0e9f395b5c692ea0cbbf64bea54334f62fc602d2fb43400febb176086aa6df3d1a7c0a163b165c1500c63318948e36932e75464256c713fabbb4bbd0dab01e8c699a1ec4d9d173c668367a6c17c49aa9a4944e784184167b2371941def8e371af2410b7489ae53e7ee34c0079abbbe6070706b0b0d1104c8178658c3910132b1c7c122e17ce748cf5cc525fa79595c1012d4c550b86178d257e17b0e2647f35c3cc40719e845bab92846f2a95312dc5139223b6739429ecb1c34fb675d0225aadc5e72a6e64e10cc4094a85f15f3066df8277260c3a3bfdc1e4cce3e0bd149ed996f93007b33c3e416af4a03bd84b79f05e891f3124ad71951461df327d7d5cff862c917bed9201c2bb05c792ea870cd9cb64a25a3fbd15af4b68e62f42eaa16684240fabd47b6cc3f236d8ba517c0c7c2a028aeb5d1ca3bf4df9ddc10eab951a7cc6f3f192ae3eb9e322012104f521d712c48b19c40b318f42d4afb1a06ba5aaf270b5871499be3c815cc750a4555c010c2973487635b09cc8a0c8888906a11c756a4387dc7de78ed41b8e9681040b555ea250a9cb8a52bf09072344f540dc6e86737a8987b9c88552421b58590504283b48f300ad341060f49489447a7e93a42ff97546ae20768eb9ecec9c6bdb5d891914b6df854347b3d7a1ba6bd9c581ec03a7e7c9690d423104400a1bb73c0b735b894a4dc90aa1dcae71ec22411393a4b4470b6cb2fee58802f10837f3de661b1d0fa10d266797a9ec5afd4664e10f7fad172f5c29969f423bb85affc6f8c62280c9c34c8fc2c7c95f77e44e7109b92123585b06f9f59345c90ea879e47be4018a725c88204217359255b9b905997944950eae8bc7108467c63a353b7394eca8e3de6a6e994687eb71816589a216cea0979e0e7635e82d2f6a500b9aec8b4d83294a05dd5570661ddbf6357ab6225a921d438ae0f19c58d37f9e357a8022fc4813faec9c2c48d939ff9c357ff68a22e9fa67ec5a07c1440a963dca6cfe11e1666016d5401297816ea759c9d30923732764c1c8710fd02a6cc5297c88cec656e8f221d2ef3f50e45725b944ccee0274771ff86e50b4df7d8abd9b0f73d0b0a1c39a0797a2afb9415837815fde56222f6a791a8c27e787c64ca8473309a710cac6186d68970d662a2bff2681b2fef425258353b122306fae571294cd9f089cab99cab44fb1e0609fd710170fbea019f522dff9ec23d323de5ffd8bd89dceb3fb5a41dd5cb80751daea4d9b171d3251fe84902090836c96593335afb9a3786dda6d37aab2b254072368e3718d50af144de0122c1f2effe93cac289a45194aecc2733ec818007e9476c0c51b41edae4d0ce970ef1ef7128f62e38d62f958b07b08c99c9ad0ac8a8f744c97a72af91a62a899a4fdb89d134afecfe1fd60488947d5cd2450b25ad414762120059e7f2ea3921f318eed03bffe6388c969c1e4c245ec490053ac7e55da1422765c08945722be38c67724861f5c7fa4f7fa7cb1a1eeb8cce0cd8cc7488d9864eef3894c28a312a8f7b2d2fb121b27fb1cf91b1d7595afbcf6a0b2d6dbbe71f566ced1f8d602c20a8fe249b7472fd15367e339b2867da390c5294ac945ea01878028cd764ec2a2715cb619166dd993b8100404880d0544360bae934a84fe63c36a1a0dc6d4f037dee0ed421cb4140ebe1953b9739ce5206b584f718872ed65ecbf9d43ac850b86768e919ab45d94ca2dc1ee9222ff0b6a97886854c921da3eebb52f8731aa11d0edc534da44d47148a0b106de67b900b80a79471acc11b0c84174b0a933ac57c806b679cde6bef69de048f37107bbc081b46c40c44a09f29b16ac680d9a0b8f9591ebf38a5ce7fca09ac05d2a29e2535a2901dc2fc7165be31410140e1a70126ef345aeda9633b2978fb4ca3191a24094ce8d30a831357249a1274b43a1010b418c6eecfa5576ccd876c13e66b616f70f2d55f9bae00db86a2031541aa85a74da869d52599f742625d7ca804e38766a6be430564061968509dd9a0fb8a5079e36dc6336dd1c32caaa26ac265b3f56e592085087077615529962e3455538d30e5a3e300cdc75da24b37d44c1e211e20d69f080fa8173f4d255684dbae1fa45d84c6e3cc6a103c39e1bedea8508e8bb830f1c8148192e8704cf0774d789437733927a2155dc7770bba934e2bf183955fd5e17b3fceb879a85dc9aec42db445b7a1a17d38d3872e96e02a6508825684b899ba94f927bc9113797725e0397d9d18c274d7f92d2fa9d6dab5344f7114fc1d902605f27d4b16874523c824624100f3a4c1b3980251a36486aaf7275befa22201673ce5daecb7c45d92b2984247b70500cbe228fafbea2775e1f7a3551626974e109a227f5464ad590e7beadc1c1d4ecb8dbc45b8304f31d8f141817d4589a13c45c796a18ca7d38781745ed20d6983e337342dfd4b72334b1a979d03ba760323aff94dd2ffda83dbaef828e01bdc8b9fca951347b968d7a2af9c50981fd4e5628b0c96ca2a72f764c60b792929c3305521226271c5a3494048f0507fa81f9b8d1043ef43bd2c061bd2897c36ed5befb56e28a2d133de0c52d4a868b3749a6a1370507dede040809ba30ce5222cc8f50c48eced8a8e88e3243b3f13b29e2b150ab5fd706a24a7f6dcb9ac3d06c5403ad281d75981089486275476b970061cfa4ebfb8f87004af26724f8d45472e0bea73784cbab0755ab26f70282f6769b809710fdbe8431c1dd2431ada78916c7ba11599e2f64dc58140c36c3870c52780a08208306efbe6c2442dcbb9fd2a62b8ded6d55077f0fb678b2920d6310ca89fd7ff38107ddea4fec4d9ed8c19aeb11c05db57c0e749b4099ced823c3af9304ab6a7fa70b3089e58fb031f70d759ac046728a0cbd7d1c48ecdfac1b3e3528be8ba3a5bacf332d9d4d35ffa5e4a1f5cbbd03550f5d4893329308df529608c434a567672719745d5566e1dff642d87dfb4b1e81ae7db96c95d53f42be941a2ecedf977b432473e8f9ab83f8ff0377329677ba17dba7598ad10dad0b2248fb3a0a6a041f64a0776f953a5d5029b7f7708788d746d0acdd70dac39a5d65072e97e800fb5abecd01c31a3a5de29b23d6613457888aadc71eaca5222b78fb082c58ce2998c4774a9c4442340e7871c8939f2ddbc6e30b92152e39dd4d1128e9850e9fcfb8bb2044d8de8be2613dc70e932d314eeb6ca0139121cb6e6dec483112abfc16bb83c17cbbc9366a1ed687c686416bfea907ff92935939844d594088c4c80165675cd2bf586eaccf2c72c6c8855bca9a10ad30192f14451bfec7cb7d8403da2ee1da832c3663e4144ffb73038811af0b8452e331e0d4ab115f6bc79381a954a263fa7c3b4c0eb88ad07edce03c1ee02296f051377e8ed61c2491ea36138fcdb38d465fe217f9429f4fbcab323947e708b7e92f33d0af8b5319427d4021413a3ce79a5262c6667761edc37dc740cfee67d4d87d6ce6924aabacb64663fded4762eb53b66f005ca3adb5015bad2212a7ee00c4e1e49e4336c1cf407e386c10f50d596aa54b45a95e535c8e4d0fd6b4486a213cf23e1c18d7c69f77157d8affdae88c2c627789c1615abd8cbdd91018aa0a7cff97652a0d66a61ca415ff7eb0f89e1a2034ee974f313c4a3efbef45afd267474c9f144362401fbe42d713158ec3f7ca80f36298350c8793769ee435dd89229689006424984c4583c93275c7590ef3445330a62c11b72b2943e5b14e160714e58554c45ad2b010abf0e70f59775697645434afb6c8e6d9903bc704d75b7493aa79bc3ac7f6917c92102b9e144cddb7000d59c7c6b089b5905a2738a41dc6f6bc1d8aecf9fd0fe0e7809da04a372f789405a574e6bd16cdfed2e7f5c34c90a7a1e79960e2281a90263bfb1466cacf54c44123691a0eb73c44a5643383e64a0d556adaa71348fe476433fc536166b89d87471baa2a6aa7802c557c8421cb99a8dda7dc7303a0a84d4d6a29f4489cfe70f42c37112a51bdfc4f6f47844a7c0edbea8f86a5db5dda9b94ab3477e12f9b143c50daf8f2d5aa943f38dbaa251164e4ada96c25f08ec58e0f715e83a70cc84d6e398ae4b369ba30730272cac99abc530a6177f6c723b11c696810a1c426f08bf22f95908787d027c16e4db820a1a86f90d72d7ec2e0900f51fd595eb4a35621e68f2c0df87303c55bfbe8a5a6afb4774c703c1534522e12de8e14c9ea13db874bf4aeb027c4da4603e18f5d08a2615e0e7b51019650a4ce50bd38b4251642fdc1180de27409e5296ec9ede1bf2af1227902f6f0cc90a832c1a3a81d2e8bfa01c646bdd7666235f2329af4fbb815ce45f08d8ae01e92b7edc1fd8678e39a1698353b375c3b1bf16db9c9f14a1fff5c8c2dc48bbfc79589000e12cc6445aea4e8f009f2ff7a4c39a5e34c6699fc17811444432de19ee1087b92f9c6137707ff5076a3e922f2c6d8858eb27838b9e84264418670d2d908e5f7b87dc609c9c9fa84d4446a00f791168bb96ce69bdfcb8b2d5a104af57a4ba4c243de1befbb3f43e544199fd045677217201165c14dd4ea3ab942d18485c2d1633478dd4e21804f481b8585382dc034069094b2e1652d728391653f27cb244f18a639adec243b88d9f5494e36747bdd0c21982e44bb964ab1ec09f290f6e0e343328e793a3d0800e6fc91f022a31ec179a9a1f0112ff3e720815f6e9eccf815226e487454d66ee307cf49b160be0f51637c82cdf2e4410b33dfa3ced560fc97061ad0413c48e016016e98d41414e0ef5542bc89f9ad7b1b57089c9cf576fc453a0cfea21e3fadbf4e415842ecc7b378767213bd7ce20141c11c41180bdc4c82e75866b08e0dea3e52caa09faee9cbfcfbcb1ee5703521c5f77b9f354b4cd6b8214df19fb9374bb7e282c39857a8aaf24ceac15ff1f9c2db912bb1e9cbc232d68834d34c38e3f9c28e5215e75eab54dbbf7c6215a27137872cd475c140a81b26dd5f478b9d93d569b7e6c6b948668207c7f72954526899aa674ca13ce3cace8d7ee870a7f85f96d40a848cdfbc0e18d6dc9799bc6943d76eb6445a49d9ec8d8e672eb7f6baebc23e2aba1e2046eadd0d02fd84203c4e1498fe499898a8674e32d5132005882b0682f4d3c4bd8dea30882864c35916f70bea98ac3e86c7982c5fa62509ca20d7f7f26d5f881053ec6698cecf790112f1e327c74d6c784f463a444289706f115f61cb33e2ee2d3c1e4f12d8aa98f460f4a763190e6c2bae731762e27761526a6f5bfc129e1cfee7084d3319994952c54ead9c8875d985eb32f49993a8a970372aa8407db350909b05c1b1e6cc94394c1ad3769687c8c082ddd08914207829f62ecd9ffde3e36fe33b1b96b50c15b5d809c854d02f9456c390a59c4ae32ed6e0fecd252eec9e58dbbd571d213ff848ae5b7a48d97e895286018129a6e59390ba4c4fa0651e41a2b48c1698f723f61449b1fb22268bae8fec9e0dbb602d53a0b632886e262b0ae8c5e35cbed87d0e373d6bc15851498856af54f258be40844bd53809b541e7c40945300d0a6897cc916949ef4b2213c8f2a73d23a8cf48c2476867aaaa2ea60dcbf88cc52fbfeeb359c5db9b35530ed9376cdd73d1ed285cba02a4dd14ec4d356c19b8e58fa0f020e2d2a1020bacfb86b3fff36432a68efe593d34aec302aa87fcdf1752f35e6964648224eaac74d357d58d57139f80eae2c09c2c4a01d4175afb2c53c40fe08a1c23a63fb381ac0249fa202e65c3bbbe2427d002c5b5b99fae242e2570cdbe671fe3339da8a7979651ee7603a24e7a2142677c2a488d284e201a931b90cd60695e43dc5256608b071aeba6c322fb19431dba07fae4209b072963e99d29b8467a412ad52474ce2011787291086a4c055673b6639def33298070bc9e188ddbd5921194757821d37302d90554fdc371306e668cc333ea470f336e3af4d707ee8ca4751d645320df60fc812456113f6a08d6b12332bd25bb4237fcba8db4ab37dfb84b2ce670f905d4c78008a262a494eebe7c0bd8b8f5cd2c7862053c9377385295311abd639b2d74e4748ccf5bed8b0a94ba4673866e23f9835d6c2d8d6611b85382702bcbb4182da6b5fa44b5fe20cdc92d50d86e27347454732198a142f0853ce1b6c6fd659bf2597c652db8309456984987234c49114d188cddc100259f6e99e131448b1a919a64785a23e05888373cf9dbf3de62da473342ba03e38071610d4e5aa8d5e2123096eb07827e5788f5324ef327984e5f1244a0f230f8c1a5fa5568e59c1c4bd800a72e485ab3fc9b5b71c546d84e3fb7dc2392f6d33faba2836eed2f97b9797151cce1024f3486d96ace3928dbf954a59a57ed4afbafbf7dd6953a5064d8d116a4b793b08244948b92a07f6252a6f0a757309d6248b8c50a72a956dd0383463b61d0ee89b80afc11cb336a3d2a8b58189e9eddaeb759cded0c6aa6d84f23e26691ab344a4597699a5380ae4cac33532267117dfad12799e2fe9b3cbeeeec3f3f4386b1164d9f8c14eebfabd77b28d254c7c63eb6f29518620aa6df2022b40a302bfe003da23175430b6645d135195a1f302430bf900695e0ee83781c991268a4ac9b0cbc05075c74288234d9e4d835c467c52335adbf1d9c26172e50d7b2e17f33f4b2bac14e9c062ba27432644d4c62a4a1a2ba2ce1489f0b8de8f4476a8d2c57eb0028bd90b7b1212b0d19625fb7a56616c3bfc8a9e090a15d0a9bf14cce5c1d12b3065f4580e67b997f76110e6a46e3f8b305b4d3a185a2249175a160dbed76e7de7ba98ecb7c187fcb1c4b8a8b55bb47c97cfd69e42473d820d37b6a1ae4c52c42b71251afe9e981f8f6f8c6e5b7e0f7a4b60e6bcd0c2bc09f55686e66d05d0ad3a240613e2e817c866bc214e998b2b361cf4c23a2acd92f44883cf1ff6a2b4472c4b0e71a0e2fe552a860962b6fca9d9e5316d416f6e487b2d6001570129a7ebd7e71c154c7fc4ea8978d50fe1afb60e9ffee25170f37f3e77d831e7e288bfe88e144cb9621e52eb28a80e5d5584e2e11b771a5ef841f2253f867625f2407237ba939be39874b1647d97aef74e1a7befd5a6cb82521a0f0cd00d11d12a2ede1e7096ebb10d1fb20fe6812e98bed3283de911c83da4f139d79fa54019848edbf78390dfa4c541ba5f36233fb7aad2e24ca3a6447c3d8f7f84fe85c0e39463b38fc96f016fdafe6c2bacd01c92c06084511e96904990dab092e66841a4baabbea453000f2a9da98b35d370278eec9ab1eace640f40c68b7b5a9efd46912409b01f55273c52ba46c0a2be24b45264b3ec54dd5193f87eca2146a2ee5431297f61661726db16262f99db89028716ea642bb9521ebee086cd2c9ab47328fbf8aa3a85ddc8a74322295fd8db81d8b5ed9c4e0b2291206b804e90e1466e9c107f109db91658d9e5e1a9f5a82ceb563e5936a52127167df98b2722cf9194e05ae9be3ce6601026a4367c4dea1cc6ec8938200cf4e8eaaff65e44149d5356866b72c93a4a3f4b203bd2695ab2c12c103a791a773b54ab3ed52f27af5c7abae03396369c6ac517353c9bca94bded091d3a37cd3688ed4e01c0650d382efc74f8297db6a2e897d43b909c8f22133b954daf036cedc2d03a0bf9d69d5258756792035dc7cba2bbf0e861f9758980c9e7d8ed829a55d52c0cef59b907de99b869f56c190e772f90ad7f40793c9a321a6fb59fc9fc1cf3eadef7f56eb53d874c6715a74b8b13c1be333cf810699570f8a9d7faf735dc4ab80d06850b6706d4fe25aae6fecd45426b1848df7ffdf311e380a846dcb701caeba460f43afeb7104b1e2473043ecf4d4a7623785256ebd4ab2a11ecae93bb507b566ad9a7c865988df3a2711b8ea68e51fd9c6c4ed298a89994d814bbf02f4d30a523b99bfe44080188a0d98354197394e563458aadba190e1fecf46f649e564d8bb0e4dafcca059e8a93fa61a6775337624dc17d4bef79ddf1f5b6cceac4c48e4946f00afba88dc2e959cecf3a5d01a0d31894a2c8ddbc3bf80992d7ade9a7369cfbbf1074197e4cb83d41b435f3d628d1c543d1b115828365922b141b89a401d8e46936ce0cb4d81108fc2c32803134324afdf59cb9073d4a5a0d179180c95e0ae563c2570717aafad3b0d60b763fc614258c60dfdcb195f171e0e8abfc8d71af0e26952c92abc6fb8327aa75a506ab3e3a93f285a51bf817a0a3dee951a389a0268510e8d0df7662571d6aa5d5bc905485fda337f25c151c5ba3953517d9093d6682f981eb3e9fd096bff4378af9492a6ee29c8fced3484979d769bbb9e9370ce897519efe9e8c54f0a7b4077b80ee2bf349b7edee1cb51d97bc3d4282349348c847c1f805c6dea15c94254ec8cb2ed695244235e94dff13d71bfea1a6bfe5559d7b5d44f494a9dc83eb73d757a264a6aaa9c4602e275c11396ffa16500f88ba3ccd93bd50e3d59e10c72ed320720c6d878b37165bb6aabed37b69caeefc2ed34beceaeaff276365e6e972ae86a61e3c876cd16db6d744ed75ebbbdc6e8d99595dbb7f16c757d6ba072acb52a65b6d5d563ea1787d9c9d7904770a887d835edad4f910611656009b411d85333da4ca802356d19672c0299c42c5555f28d259753a573d53470aa0728ceab04c74a9b713711c74c32b3d681ca71627a5ecddaa59a8718d8e176757b8da8aeab546d3b8dea9741abbebd8d24dfae2928039dc4ec555bf21a253b2b2fa5b5b655f24b09889158a372a619087cf886659e12e428573ae1a4a4ce66204cf62bf7876751d1e419b356dae72edc9cae8649e1d60fc69c1409893aea9b48ec5745623018acb629520eae8aacbc0b4712623bb34041d76ff34383333e60828ff9b3e6b97baa672274133fcd44e4f706156c6711282d22b88236c2aa27b9d78848e2897e996fc94f4714d212414d7c98b4e4867925fac6271f5ad98f96237a7d24b2c912e13cb5b88e385ad18a5eb35b27ca43789592c2996934ee72c414f53a175ca161c4a24f0ac650d9b376c757fa43ebda69b6a914104169f2ee561c8c10a40c559fa6e1a18963d6e64be0990a3f154180a699d26d0701830841419042f1e02736c1e9ef11e5af3fe08b0e2008f99c8a37ba38daeae56297ba21a58f85c485fe927bb8407651f156e27e871350ecdd1111f7b8c15a53622a96b80de613ca81fc395d5c0947b708d913ca6251e8dba14b3815e8df03d754bd690b108c88da7c438e863a297b94f8bc99339c70c520169980b3f159004d6d01da0db06f0750d035cca29d1a06487fccb634a51a5aa22ff2013ff3f962fbc5c332ed27da6f16b16f33df37dc0b9be566796d81d0569c3670bc6e880255959cc62325c8d9f7dd6ef64fa277cb9c8161c053c4ce3d149ecefb2418fe1406e7d4de1c96bffe50b31b6ba36e1a71eacc33d5e10795c4fe21c2a2c2b52a7ce05bea615ee69c125be3544d94ffd7235a6a7c8ea3cce5d5caa93f97be5f8b812a5f2cd28729383158d266248624c24108167fb60b5a2410936b25842031fa6224fc8f5eed1e936bf25dce59bd984b3490c9706d6236620d2f2d65e8737b8867d9c45c5ba5a614afd61105db8164d06e35d26a3c6d09edc12fc59b36d57b4f93b6e91e1cfa85fd8ee9a38fd3ecdcd0ebfff1c78033e250212ece2cc8860c3888be1e8e272ebaa6fa5e6096f390627eef8e06cb0b3829cf6df4ce4b7a7e4492735a0e7ff87d13a40757ed645aba85d3b107bf2294fb7d7a2d67fd35cfffd566f5238447f4e9c695563829003e103cd57f2586e34b3101850b70ded20f34be3cd0a7d3f2e9abcfd544a526ab0d6ba008a01626985742d524202c9456701329ce72f8c1d5a1805ea9168ea6ae28eb428c3ac85200590ca3c8eaefd0e7099bf312f2980ddca67f9a3ecf492bf2c79c22631e111341370bf085f7159a38587a3df88c3b53d20283bafcdbfcf45b1cc9117b815383af7c95582c5b0ad9cbf69b424e6993d139f865afa2feb52a212a4242074fdd6de66d1199d00d7faf587cb04d8f47df1884332684e772313a8d66ee95b07923868f2286ab6ec29d9e7cc7961e436c442a78613c70012d71f97e1e571dce880b052ac58f9a3411f1ddc98eba2c15b1d6c9614d117e764c12c15a1d43600960c0126e497e3f50bcf857d859e2f4ef384f10488b3ea920df2fbd76be4daa255faf1f0b794e505f1017b049ec81869d1c1cb0aac2610729abc9b568bb9b9473059143c9e6bbd6801e0277c0b89b0dc3a0064b816c64a0ed73fd8a44a66c065baf1e976524f8b2751fc15d287ac3dc79bcec9bb01f6f234aebd52b91a6c7bd63082e79c9e2ba6b7afea38dcc5203da405f916fc0495e526b7a81c8e2fe50b504db50113701bac2023716e76f3c79dcc24933b7702e6aa9286b67ac2c678da19a8aa680befa57cce26d406fd6cea6bde77bafcd6528ae000c3f26f8116c23ad2995e6505bd601683317e13720c14be989bcd03e101ccf0e843909f500bf5b8ea6db5adef0f1e8c1093c056b6898c470d00d056fe794a5b95beaa4f3fdd8ee3a50d0e046bd00c286099b41680185364e014f0ae15ca7e2f55633e1821ed88c5a182d3b57298568b847da56fed2ba2a0e71f21a5782d6d80d5b8807c2a2713249002df5164c378c6f5680f8a7bda68c5ac3ff80483eb3a89cc046abee251d4a6db545816d50ac4b72dbf6fd3e2e3a89d198d1ee3fadddb979503b40b714407034fcd88a9092b1197946d05723fc74f8699dcb17f9b1a9f09f3c129bf7e254dd7aede69a2360e724cc39001236ff16de998c8ce19b63945123dee68a12bef84a660eb773de60ef1383eb3f471ec4b3ff68998523fc67dff8a639a63a7ddc4b011bf3c090f86c580e4ecce1c8dbd6822434c41741b0405f8b661d40448a4b3b795742883b157e4ea1b2af3a5ef851d9d707d6b025748fe3231ae75c2252410e2bcc320f4ea40e8e9e8844e02ee3492e9645fb4804379722905b341241c8b4854f571c8d8543c9cd90bcd3d0024fd8c512dd055d6288ba0b3c594c2b9bfb09951d296f31e8a9fce2057605920d4416291b6bafa0b5aee30393420e2055eaa44caeef58abad66b296fcb538c09e48e415b5a7d3640e4a3e968fba7ab9b5bfce72234c2668b656e6d222a6ef823b513a9a512c387b3ad4a9060e03c2d87e44da682682a2186934dd4c081cdf12ab7a4653e120915108790028046482a93adb3478eefda81c33087cd159346c22bc3d262dce8b8564c0a3a02742153f062dc247dfcfa0227a51b8faa5283479d677015a52b0e7d37b46c83ee5c64e303dd291a9b0bc1d2f7a1ae4f4526853a43e9dde7ca443725b0e39ea21f28c3a2ef682c2f7945334afdc7c3407d95a9c6210fc8a1b4cdb7ed7668804cee4abd2cf799aced619581b653cb2fe80c735ce6cb784410513a04788d65e26f035f737661025d470395d3a7053dba87591984cbcf78317401776291d994968e5073ff6c89515e9d0df6985336c5d8d04f4c82e3c8c3bf9cf1f12b3d54f0c0c89f8ebd9e71ea2a1c9cd93440efcace76e6613a5af2c244fa9b21dcec55c3a9f9514d74f80238429d9728772e2eecb856b4403371b2645dfd6de9004fd17cba724484738bb3f8aa9ff2f8d9b34fe134942f9439903254090fb8d15b0aa7e094cbb5a6b89e0324e52321f28ef079e20cd2a91519ff0171b3da36cddc642db4d51de3cc45e811d4183372847209ea30f666f9cc263c446357252fd99838585cd3f12f1edff94e83f3f3b00c90adf7d9338c60911db51d142c5d3441c1b739e3a5005ca612a973d90727a35cc657f08068868a046511b224f281f73296a2529452fd34172bc90abe620f50d0b74c4a60cc691841227b6ed2e9167a8bf9d72675f938da5a9739be8349a927441f9f7e2eea2c53ac635129a0fbf071e08ee0e413dd4221efbbcbd0554b7ce17c74d08dac4291dc791617ad77fe267ede3788e6459eabafc2baec024cf78c1b8cec0e41762a5951695ae9e77c69ebc595e1b60e461644c6a6259e188a9b7911277982c018b7168d0a765a8df5cb6fc814d3d45755cfd540c41d6e60f180358e41288f6c0decff364b977c5990f7fbc2540a87fd35a718df8b868492c2fd55dd329017f998e044e27f4edb41cbb47e4f2f2f7551324bffd7c28db57a7f6cd7bfab190556e20bf21b078643d1c44aa661f372e8024b21732ceba24d273819017730e68fee3b4c2249d0003be46803b6b264275b32dbc0e6431452d0ce374e398f1ce7370c5da080411d69dbcdbe45476573612884698bbb27db7998fc55a26aaabb715b3972a518aeb75e484f0d90319442788e73295aa44fcf2f954b4800bb9c6058eb8000f1fd7c2ec03ef1430d81927655d80d16d8b3e7474d7b11e4438c78cc16a68ec708afc1f219d412ab154afead89312b7debe9ad50c8515cb67673eb30613edd3951a83a3c28ec50226ea7941059e0f1280e70e45451360628b08da608075020b24b0d791bd388c6bfdfe19796a2c887302ff9ad3b68e03112cd790b5aca750ae5b24e8f85abf546ca3f8064490a05dc49c78f74686b6975d0199c25c1f0c6cc1289bebb851fde86775e64c2e45a4cc60617097990e7680672ea4dd5ec92ba05f9f62a33a8068ac3903f642fd400f5966f9a27924fd5954facaeddc379789096aee86f44eaa54df11f28a4ac4188f90691497d02a89f6331d340d57dc3a32120124cb4275e3c0d1bbacc7e3cf30cb714e81a4e7b2cf9844a5a01195e6cb6ab35057f5cb6409fd7b0c1608e805080740bfd6ebd3dca712a1403e1873c53a2aac885b198daddec1646453839de784bbadda79b25b75205490697bb64e61c7b12173d6512013c2da100813da32a676dfa881cbef46bff749644d0109768a47f43cf5b6c684d71195326eeeedc35b92c8dcc22498c2442061e745d9ae071eb1f1846892260846689d94459f1136f2a37c09363d933e679a9c3332fe2ba51d704c3d55e2ed7d5e4a590ffc929e9357e3a3fd28dbde855009d06637f0d0cc81bbd4bc80da9d7c026c5862874a815e1c5c3394bce12331d72574c103dabaf28e5a2050c29a0eb79634e1cd25cd1d1d75869fa9f0e31a646f5c1e2f67e1472af8653274276a9b2fe5d669f553b91342db870e4c197103a1ab23988644ed4c9f539eac7a6ad2e9179c996776ed97125fc61074dbddb6dc5bca94640a5a080a091309b51a90c1620b59738b7489d2152fdb96d4ae6dc9d365db12a68b73d94604c6edafe1d86b0ad1105c7230e28933b2ae25b7c63a16b9b2eb6c445b5ccefdbb16d0952d227eb9505a2175f0ed7a5dbb0e9f03cc587eee28a5ddc42399d0888866702227cac99139dddd9d73fbb8c6073b0ae92937c78ee368f106563e57e629b536ab5135aa3fd426b5567fa846d56868682889509221da91378da35118281d1282a16947fdd44f59b453377516fdd44f3657ec085ea091487b8df31a15e12582d7bc96e4c5a44da2a964d22651d2249a4a29ae4eda54d27534688d59336dcc690347bfa72a0850dab481f274ac558b7ef3dc2208daa85113ca075bf62b1a27d1fd5293d6b04ff2a0117ddf54ba3362b0aa49346df8beef390f0499c1702442a70d92c7283be0a0fbc26983d4c19c628fd54ddd346d98b469438dae387c8ca3862668ccdcd7e52532562e9927f72f2f3d0d5daeb6cb67841cf7f629f5bebd07e79c5f555e7d4e75c2776728ad504160fef7df6cb15af4a3956ddd3caf68f45c2a5f25cd8cf2e9569857c9836f7fad2f9f1ad64f74bf5685c1a6c21148ac20ecced1deeab19aaff5b99ad6776b283bf91cb542ea90bfd354c543fb3fcacbdddd1b87c9ab8b8f7f36f8f5ed988853be7475694bce861869b1c86a06cbbfd312caa17c3c018be3ce1708b6bc1c823835cb8fe3b5c5a1bebf4a99945077ec994c16c6f257c6f14cc074f287d3a19ef48c867cd54a062b9f65cf644ba09645fa76e8413b2d5b02c99bbff4bfc12f6ff206847b77bf0c01eba6d0402ee510c7fdeb72af162573e2831cb53f1887fb9f16b9afb1821dc1cbbd0c7a192485e45007180c0a1c601e3ea40eeeb907c23bbae7deb274749c7b1f2f1b525c4e4aaecf4ddcd4d5aea3a0a45131aa3b4174eb77de3bd495fda4c1b428bf9b5cd75bd73db87edd9f466b464bd5aa21c3caaf59692224d6131bfeb0584ef3c2760a5b4c8b7e5d806ad77521aac5ea5c34ad4ca20664b1e3744ac17b22f2d61f27981953bdecbaa72be54f26300d4bbdfc2966368de11d1ff8dff7a9d60886a39c4af5bdbeb352f5e66d2e39949f994a5097c8cf744c35896651bb46a74da5a586d5f0d6308f772ca90fc2b33c70ef5df58ea40a53786ab1c605d69fef389dae748a5577b9922257e2440df3dead20d9fa75a095165598b2a8adb4282711e3c814ba2722a1640af5251ade315fbedfe053ad11d0f8da1ab930154ea71667f8d7d37f3ab528bdfb9d7e0aa79916e5d78861c7553f719a60aefce9d4301bffd1953c35ccc69d689ab132932691c77a0b76c907a33619d691b0fc852b2791f4deadb83711d3b026958ac753bf74a554ea5a528b4c7a92efd51aeb1e8c20dcb19faefc06f3c9288f39ad5df26bb5362aca6914a0599b12ccdbfd0868dc2efc13ea776109a48d04ae17a6e0dffd6cd97c3f1291b7d6f7f7291d6359ab6b799f924cba5236acbee51d7c6badb53ee7546eb102e1187375e71daa13dcbf56fed473785326f8c836c8b9ce65d4164cc02ef95db8a24e534f553c435a5cb528532dff799d0b2511e348cffd9ddf0bddfbeebdef9edf632fecbc6519078586d908e96e09fc0209429b670d8e16c1ff6c522f898e1ac6452d1ac13be49646025b3e5a3e2d8ecd4346491d4432f5b55acb62492fa479adac2ba3240f492475c8976038b6f466bce785468064aad4efb4aa8544f54680642a22f672bd974e5cef3f222f1c818eee28846f1705aae7eb3eaa50f55eab0bc77abd14cc3a557f6d8d7f9100cd926a34a1a0158ecc642c009231d71ae5962b570d633a5b3f1ac660bc30fd68912714d804a049f9d2fff3969cfd3746406259f498c76a2883befad59ab2d663fdf360c1d2e7bcd6c9bab325e3f47f13e81e7541e37327727777777777777777f7affa684ff540a1639266a6fb1b9b1b1e3c0b001d70b07af9391a66a346cd5b1ab0192fe5f798e0d330faf27dfc742c7cf9401aa692ae3a41f604e03ff80084247c60428b2a7cf0de479226699dea5df55e5f82f0aa96f7b31580fab5b89fd1fa9e466bc6db168daf69d9afd1aa791bad1abf6ad9e8a0c5c103a0d5c1b35a00780f5aac0ffa76df8efce87e14bc6981f036ad9bbfd1b2790f5a371e6cc91bb682a004e0597859f837464062e54ba48ef5cd5d1d6bc96ab1f23f4a34ad1fe50d6e67a65ddd5bcb62990147f182e1286fa0783f68f15585fffd08865cf0a9ea04950454efaa577df00108ad3e138526002dd7a28402bbfabbcacd686effd84fb753415ef083d6072dbe0dd5ea3336adbed1bd072d9fb53ca8e5422d76df41cb873868f9aae54a5a4ed4f2a2f65a93168dfc09929516935aec3e6cb996762d41a0cdbc1c5292800aa4c50e6bf5bc5a3dabc5caeef6267882d79d7aef531e4fd39aa8bbd66d74bb36c33ba0cc48242e988724827574c13b64bd35943567ec98f372af9db35edfa75e1e49a486253578d4b79a283be65c33b7fb6fd680f2481ef10e300d238263d6d952b99dbc72bb974cdcae7ed7effaccb16ee4983d73678b5c2cdb6870ba1d4ba4ae55f2d5a13c6ab15bb5e8d3217335ac167b488b92a9d6d05527d4efbeb1046acb3aebdda63ff0e1631c23a7d33196bbbaefba8be924ed28815dcdeaa5240fd5f3f38cffbeef5373721c5d6a912752c3fabd9f53eef7b504f3a67e04346eeafbab3adff77dfd9a6aadb5956aef507b87da3bd4dea13ee558ef50555feba73a61c6f77d217f9faa9bf4526b69a47e72bb57a96c4a15b6924f9e901abdefefbd0eecf11857fb812d7941d0f3ccd4be75dec48bda95dcce876ef7dc37ffeec5ffdad5ae7677777777777787aaf00bbdf0f354ada4c5efbdef542534e8551b4ef5b2e5627c8a2375f7add430ae25e07d09e4147a626b6d80365425b8ae8b69b19bfd33be3f355f82dc83f5bda61efcbe7e5fbfaf9f7ff5be52917474bdef2eb5eb7dbff7607d3ac1ff522a1b0d60ae012edb6830bab70b7eb5d13e11c0d99af189014288708071a28a18291255242a49cb8b7734d78044f9f981c28b73401c5c57ac1773bc7426cf3af9e8090d07efe81eafea1499edc4a0d38304560ee358cbd74602dd7bef858c434509a7c9f61869d8687d08e9f1f90124c810227665428bd6041f137a5889e66571934256a25a885654333a424aaa9d74a28811190445012a13dd25853a176ad89014ba75e9b2a86a502e20e2e602a52c5d0d27275eaa8c112a820190942a3e0c41c60e33b881c999da65db191a1863eeea0cd3b5676eb77f7543c36606ddcd4dc8d02ab0863084fddbdddd05104f2edb8028ba205cb619a1b99377f0fbfd6804b9fd0af8c24a9ee9139c393558762d2cff278425bdf85420526f37ab977a4c6dac9607b7e6d2ef386c00949d4fbf65cf70529fb38094d5d0881199cfa4985a592c8f51197fd7b043fb35c82c4a1e2c75703f1ae0321677b471b91f0f70f9bbc6953cacd4a1a2c0947d616d000d6c118fd5ca7dcaf3c2dab5660bacff0c721bd0a0d58a90006b454e1cf1c2af70504d5024e54006cb0c860e0b77f9ca0d70e06076cb218923221a0e5c09cede0ae8266657fe09d0d0e0ca1658be88a106202857e010c50b45849184c80ad26c48be7c16ba9236934666ee5885eaac616c3372baf26b50c3e4ad4357feac95b50001050a94175e5ac0042f0d91040e5e384dd18599e9e32b30805a14a5998c6ba5790c004f33ecb004083337fc20935f893cb633831452d06c4103961864f2ebcc63ec4506a831c4e8d043145864f2ab90c758cb1526c2a09141922c4932f9dfe735a8ebbad9e55a755613d064fdc73abb33c480155b6757b66a6dc2bde438aed6d9ecf2f4094e06996b679d12df02becfa9f472546d3c59c4d41109d231f9026d881129d43009eb806d4128b9fdb2e6d50e36ca283f50904134b9f5592dca14baaf3f76abcffdc7daf193af72b850b3372f6f07976d403cc5a4ac9feb60f32715eeade2dc5f3a49812df60f45a9f7f6d404dd2d38ab124eac5c69738274e5ad91c5d6c08234724540170bde8862fbf9fa0861f6315bbc6247bedd1863f98e7c8322e263a62bbf0b0e485786440cf0752fc17bd3b0ceb2beef9f6123d09d2a9e0f9cb75ba9ffbcd84c9acd664d64dd3fc352ef799ee77938c012bed0c6fbca3c2aa4fe7b56791d27c6a7ba8bc341b242c6da3fb2134371f954904fa45eee19c7276d24c0df7d5fbf175664479d225c67413a1eabb55acb6231d4a5ddefb40aa9f77ea7a5246ab16bd1f72848bf5a96d5d1b9b47a409529a53aee62190e929545a154d222fd9c212b6b330bc6b20217aa26db0f487dd4448a66c3618c0d87295856e0624a27dbbff364fb39b60228f2fbfd2b92d1651b12d11d75dc7ed672d9560498fbb98a222189b9fd13bccd585c29bebbf8c7ff2944747797eff2a54afc166d3fab9ffb6bdff0f1046ccd95d787a2fbc1655b1334f7a3c138b8e6c51a552cab457e2ea30a21a8208992e596854c364143c54603165f60a84126dfb25e4c7c5cebb2e4e9ca908833026a65210c8b65ad3be7eece85328cdba7493ed6930f2bf6621c2febae2e42a405f699b7d7ebf5a23ce79c73be4f1da4980da062fb29df6657dbebb819be08633e567dee3f9e5f188ef6ba873cfef35fc8ead210e8e69097b3813fd789a916cb5dee77bae6f7e8d12e7fb107f7634e8fe98029d6aec497ce8ed5e1cabc9bc13b52adeaa776328cc2e67b0f328c7bef99bda72a1ecf725c68c33d5f1bee5b365ce823842110e0821668501446922298c85c8c2827324bcc6e1043ca05a4088164091256868450e2c50644c8e08b175aa290f94bd51215608e8e8c31f385cc5ff4d8075e70c31393a32b62a09139192d9ecc9e98bcd0840ca866c41751d2b0200ca73264feacb2b1859d21b784c4a3725fd949c77ffce020ede387939daf9f1f2d3aeb3a808a1df9cc13ccbf48c3e6d73355c8bdcb92a1eb2b90f9ef780cc8c77f1c08ef78ae355bc9afce2b8aa53f4a04b0cb7f017cc5fd47f1ba02a4b0f4abd3a5a18fc9cd2ebf380259c67c08509f16fb81ee6bc7bfc7ffe5afe3356e069f0afcb5b66a8b48bdcc7272f3bdfa717d8e992bf71ef3b35a5c7d8b528ae5e7a7c18ac1025cb63d51e5825fb2b4015eb833b22475dddfe00acc71d9068511d716e159c858a20ec0869b02a24baa7af5bf384162431945b8808c1819194d780c404324714a33c41047d2605985a91c9d1eb727d275d9f6841577c6655b0f39dc257fe24fb6b87214affc2ba7cc4af9553e4bd6cb5c52b582d1810a22ce7891060a9313515018ac70c117525e904203941ab25abc49a2e141a43ccff362c08de1eaefc85a81d0e2030269da9aeaa469eb214d93a0db36976d3d5c71b9cbb61e64907af2d5305a35f19367c6891421fc2499e4952f59af0ba4c763d667fde6d24f82155f5dd8f1e6ca9bf95376d131ab1dba6ee3610a32d71b26bb092e5c664c907e0dc11cd791b85e1d8083bdf91d9cdcfed99cc4297d9277dc02304e4bb9d3e3038890179f496262277e6228396163016eff28e6bc0a208ee05052f097ef21092dee304ecb6c6692cfcf4ecfbc69b17dfa7ffa77fa7ba6181fe3f851c1cebb5f4184743702f903640140d831870a52509f0529ab5f432352062585f9401a96e3c53bfae72380613a2df26071fedc218171e6f380f1b03865879209e350617f7c7c348c09ef485dc98471267d9f8e25e0f683c21023d3e92899f4346cd4216132993a0de3a5a62fee08a18f16270518c787713e40b2364b4082f8fcd016eb86750312c4e78755354fe9f3ff58f670ce7153879bfe4ae20dc79c73f6f87471756e0eeea594524a66f1d562e3f403e958026e434ab79be6a4a1ba0439750962ba5248d29ca54fc346e6f2435b0001de41e9ed6918db6a4cb7df8486012075656b042390b7b63cc6e95f800f76e42620b27d580529e89e052993f5bf7c4001fa310224eb9ee5aec6591ad25fa41f487f90feae258f68834942d6acd1c00f4d6c4cccdcee47d67c1338aea7617dfb71f4889235e478d998c070fb75761ad6c16d9b0e4fb7dfa7b9d9d9868d5cc5ed0ed37514f496bc3285f9608b25ccb0ae5a948c5363f5e5dbee3efc16fb06e47ad2800b5740c3aef92c63c73a5b0172b2ac65938d05c2d4b38ca37010aad5abd571f86c2c6044963992a53e0336f23f3132239f18d9f7decbfbe12cd93f210ba6195c3152a20413a02a696ea8797901972b41b2f6620b1ba8a0c9e18616a06424b8708b12362a9eb64a65ea8dc95bb4e48069b9b285852d362d2f5cfa1e2cb174c6a550374bc5e395aea498028b10961660a9228b115788e0a1e264a14b171bb203158f8fe0ea893bdedceea425b73ba98adb4a80b9fd1ca878faa948d9c18559134f432c88401193344fcca0850a20280d4a367c2b255a908497db6fc3eaac60c79a84d0a55bb6d440a7f59c73d6a8787c8e9074c79b01dc11470e1e77ccb9b4c7a5205419638589952a9008424289248e5cfa5c05cba56f95be38d1a0512588db3328a5947629fd1efa3e7ea8572beb57a978fa015085069e398f6c2cb0e89c73ba4b261854b9fda97e562b0dddfeda6c364be2eeeea978e6df717533c21d73e4dcb187165e3a220c5808977eb53d5cfa2cfa3fc4a52fbea08b4bff05e5d2d799f2c5a5bff3824b9f4ad4a5372896d8f275475828be54f92a38c21156d2dcfe69794823268d0b3b7c510609a0222aba101384d0932534d019b63cb9f449e8f1584e8e0863ec989323a3f78adbd54efa2c1ac51458ead2ef7913e8fba054ce1f2b3843eb1c18d144b506c8f24916d8bedc458619344820aface59801e9768ef432fa4cc3a80c52dacc59435b39779921e836785bbc9d33dd2f3f04fc35e0048499edffc0b4d84c2df68d71baa7b8ab658d067c706a916f00cab0536c05d95bbed33edbc28a8d13ee59567b64111f9d13d6bbcb5ddd8ff5b2bad6cb5df2458eb674c448797259e9b28d08a74b0498cb5d5cb61d61713f1a1ca564a54fbdfd362c81742f9564fcdfabce3cd6e3f78771e4e34429ed44bd8030d4134371d410f94580040982420b088fc1450b35e8a2848449104c9260b183930b5f66902a1fdc771c7d191a913229e551cd42f27f3625cca75146196594219ba10a3240431bae524936bbff87fe0c8dd8387999185a7735cb9f65338432fd3fde7ae9b8abbb7fa7a7c9c57c8ce3bb47c097dfa75efe377b041beea5cc8894cd78d5b38c8696a8246148295a0209900e52a0043911031cca406246abbaabcc8c7b96947668e6317944befc2533279a318eac36dc73f7f29ba85ba8672d06b5283f0419f4ac67aaf761b94bda3c405e275e0865ecefb4735cf7755dd7751cd735d7eaff40f95f4b42b94b3e4d0ab94b7eaca2e128645ca92ae0322fd441831d7bd6d58ee35677ce50c4d1a2cb4248b2954b99295794a185134b6412e7072e2bdc1075c3186764f2e54c0ab1aa0253b6d33afee5312024bc6072040818c6f0610cd9a5018b282b96aa78824926ffc55a6d908b29be3873798ccb5378116501c945666381f9fe1eaa80fe0c6df859e6cf32a9f2319d5877c95749a92463d97c1ff93f2de22cf9e8b84b7e08657ce4ffc8dfe9a9f164d975f8faa8a774ad8d664d06098b4d048b4818490711d013a8a3a72496ecd0c20bb02a90d0caec60032f6835df3d9b6af4b98f1887fe4ee34459fef2c48c192398829802872bb4b8c1921a94b8410c941b530d2cec286f37301d4b49314753cc5caa84260cf254ef936e89d4d24acb27dd12a9a595965aa6d48cee90dd71b2233fb9ec9abbdada6e2a6b52363ddd78c112a9d7a61fe8766823a518bef3c654bbe631f9855df4c3188db9f4c9d43cc632237a631c5a8613504cd1e58a2534533cf680249adc92c2c0e2072c35a322b45c66e2b24d0a1997553c3ea9d088941571571a8e7eeaa5488bb88bfe7d626d3a2aa4453ad9966493f2248f6c52a082d86773775720f5365266e3f3fd171a913296bbe803c97096ec0a5c18c940061947564ce9400bba28f3058ba3a4208a782c15cea492ccc602291b9689eea29f0a6d26cb8060a0c5105b7021b4040c5ac828535184185d92c050a52666b65ea9968ebbe88750e6e501a73239d0608599205800c1135ac8f002449a2d6482782cf5f487346ceeb448e9e350b9c926faf289bebc55afb5ab9d8701e5ee3e43202dd21f774d1b2f7c40df5bc73aa02f99a0241a2d97762d68de58c882ce386a2106b40530940a5d5a8b3274e9cb26344cd7750f81be5d873e2dd29e1629fd072061fb3be9868b97f20ad919581074e4cab9fa5e57ecb8ba370de35fb528c7d5654d795f49765cdd8c372bbee32a2665f23f9ece3ec3e7cffe968dfbf109b671dc0e8588eca10de42882884208708a07c75abbae763785f99ce82ef9abf6efacb787ed4f69385b6449e5631c1fb74d772735acafdf38725fd2e2b4305eb341f9c26d50965ce553ca87405f3941c93c4a506f530414cdb88ddc35bb9fb997966aed9a4f5b4b8b73c9c9d20f7b6964f5973bbfc615763ea5358c12cde8946a59e1289b7a4a27792bd99e5431bb66efecb0c6183b7fa769d3b8e9ddd3e96e854a77e9d2a54b972e5dbaf4b9c40386954fa5fca7a7a626262666d7d159ad6e1a47275dba74e92db0e953817b7e6ed6755c8beb6c0e69513e7fddddcddcfe514abf69d34e6a919fb65ccbcb8a1d7b2679d097ef49aea5637da69778c95790b196225df253a91a356edc08430318400411ae8ecf8ea06c5cb1a3cf867c68f4590b29e16ffea6754c36f550c338215cc062459411949421bf7cbf815a846ee566b7c618db2fe4b1ae75cf7ab915521ab53232148d362525d56851c79825d34d2a4da13479e4463a41ab214a7bda953f9778c0b039a03ce673f3d86b3ee918c8aefea7a7a626262625a524d7d159ad6ec659eb59ebd9cc63f2e9090a2aeab60b5d8e23f35140caea33d45551c06535d441839d41b8b00296cbb9bd92ef4c36e139d598e96044d30d30f0a240a82dcd5c906ab2d9e014556d42882161a7470f272cded1cf38f50af39cadc93873ce3ae79cb39d5b4f8f558e6a6f5e7ce5e8ec80f548899a4ec3f832fdfcf861fa61aa3949e25a93a3214a04114284dd1555c44891a822519c54a5a925d19252132b44b527475392b4dc6a57851222a22222222249045ab0562fa2e8d51f205db06e7054c6a9a2c8ca31417cf5d8e9f1f1c1bac9d1228b25b258395e394451ac591aaa36acafb52da6616313355323f5521fb5954e6aa5be3598b1bb68a2a26ed24277b42ca30120b1d6b6d14d8e65e1105f3a3d767a3a37ea27d6636d64d4462bd6ca5a280fca4acc91e33715ac5567a645ed87694849a8c82c88e6d363820f6b59ac7ff17559cee363ddc5c464697664a61f2639d4b0d1a260e4078890211dd07efc30fd00f283e9a72634d3d1d111830ce132c41c39e0ea865bd4d121e187ce8e093e3f405008328427f7d8e9a1a3a3337b4ac200efe8a8274f464145456844b52647439408125c1027c4cdb827e724eec963cd3bf84a0ef368741a62726ca67e6a28b067ae648ac72611eceaa79274e5b61213f2f6e5f677e12899c2c8a631b7ff0b2799db50d3491051387293448ae56897ecd1232707078e6e2035f753727ba71f00c68ef3480878bff7243093693635ccf2fc7c22f977238a9d3fce23212d7ecd3965c05198a1db4e733a9a4d3d9de644fdcda3ef9b471d1b41cbbc4d31f2260514772a49a1e58e13cc649a4dd3693af771a04fa4da3716cb7e29f8f707fef785a37ff740d7dfeb3b2df5b5a6523ffe8ea75ae3eca9e2a9efad795404080a468434ccdd093b76516e7f0de7942e9c4713a946033fa00163cc135cdc71ae006554c1f5779abbfac9388fe6142874de6e770af43d9c4847642cb591004dc186abca431bbb7a1c2af36826f54fa5fe79e4fd738af7b3ba2310b2a05d95b2d509e1a54b7f82ec21f8002f76b463d04461260aa71a59b86b282c899defe3b5b68334ec9deefa045d72fb5f3926f0f7b01498420ba6228c6061852764fe2c8e81800b1d8cc21c198389309567172a7ba74559d3c192d8f12fe5388ed6742158eb1077511eaed668e087a016e51de2b11d76d1af955a960f450cc511312e17de5862a73baee072efe395524ae9f7d0ee592d521ffa3ff477e8f7d0b4f8665ce6d8c5dc7f73ce771e5cbbd43127996fba08362b9f5716f42f9345f0a5979aaa905904c12f1c8d5cefe5a7bc701661595cd921d79f4590c804a57321dbbbbbef4dc398457fa6dff3cfeab9e466c82ca652332575f473aa12e64d8555eae81741cc164a8e5c0f99c5e9cdea5dcb6964ce291f330f671e41eae051bfc78ee6d15247eac869f1d522fd9edf395ae49f5978ac6523f8b3fc44fe578e8ee4917afe1d92c77cfe1e92873f8b46f7a5a18a022d538575082b71b00e0264e07ad8e178d6419f0b3770c3227daa2a81c522fd7983c2f5ca2efa9f2d61b2825c9f2cd26f5509f6be9c771a99130c24322ba41c402427366050838517d105162b3c15d20bf643ea3203298ced24fbfa8ec026337e1072fd67ab03272b7fbe6566e67a995329efa6c08d3e393a03cf1322b5238b8041c54a5268908a4295838df21cbaa496784528011e517d451891fa525fd32b8a2551bc60b52833690d42de135af812afb29e0596c1bad5195215c71260942a6888e161f5040747d8d44e8f09ac6775408675eb9460a05c16294b3c6e3aa2a66a4c613429e79c57bd2b61cca019c3439a325a9c496521c252221d63607146061e5c304248d6ad1cdaa91bb802addcd5651b18239073d20f82646626be26ee869246fd12618b0859c8f8abcfcab5c5b2e2bfceab478418d81f273eee6a990831b05246799376609a04750dad0f96bb6c03a3030e41608d33b3bd974e0f303278e00af42edbc07c11c66be2632e5ea44d59d6b300e005146358b7aecbc738be8671e6f41fe79cd35611b2a8f28824bd855222f2ce17e2b7cb043c9092cef7d9523d60de99c472eca5e2e0f60793713eb8f26938b21207aae974ce3965cb19b4e5e3ee6e669e4f442a7dfd1cc7f1e4b870865cc3b850f580395db0630e1dad83c3e1485f39391a265f558210bff389f4a5f376f78cc30c04d449ef0244e586a318a4a0bd608588156a4e14c1050f49a034d180cff20e6bb184925a0db214550106688717dc6e685244142ca86202293f105154eba1872a4744505164a0c4182dc8f899f92bf3f30eeb457b630293949c5260bad9ac093103a8273330a90b84e9818534312c91248a0c498a23304863268c29b31f6a6e4d4120253141338386184534b002092c8e7012820e624451f444832358f8e6ddcdfd7add1a4f9f06a55c38d6e7ec8c56f55af3eb54f138e55a4de7f79cf5aa5aaf157840b5fd0a261fcc5c0f2e33f970d3f1a0b66ef7d7b0ab5fca1e614e8b9d9a5dfec9caa1623d7462e363b446b857c10af4b9d0c6021df75d08c5a6b6c885d647c62f5a96b79749b3e44d849af47025cdd23763e8c8072329bc0803894c42014412659ac08286265a5299a131869a90618916b4196a43e94dc73aa0754f8339b7bbeb96fd74baed09daed67d976774f00177edffc6055ec2fd4b89f04bdc7b9ba2e5e07ba5f330de7e72d99cac98206544952ba31c9fe2af325d9cbe5255b0e66e27a37f4b5fbb7ffe74ec1eb945b23d8754fbb1080d7c391088f9c4f1eca81b3357ad7db6ba4b17139c52d93946e4cb466743465ca51165dfee60f1a52e20da062e533353df9f4a4f441d049527ac91c94526666071d4643e9eeeeb57ae62ee747e2fb5e57eed8928600a458f9686a77dfe0e397ee54dd05e52ea594524ea91295b4d89236c5f28f92f6eca22ffe5c7ffa3cb3e193edcd715dadc138d4c60882eb2976d560172d81641cfa744e6e524addddddb9df71e6269ddc5c81a0ac31869d2f79666a494b2ae59c73cec94f67f2b9268e057157ff53f333cf180a9467a25aec97502fb0925db37a90a7a7a7a61983962d7d7efc2c09f495610de374356e1702afe5b1ab4604d79f5d5dedbcebec724e90d2212d526e752533f3286475fdbb2ee44ac1db5500447450f5b0465929bd699fcd9b64bdfdd565971b8051160c0490b1976d5f9e6e1138eac7a51a064afcd5ca498542b4890d5d5fb68236ca91bb8c182292b22190ce10c9a03045e04bd367fb4225d5de11b00b5be3b2ed8b931938d89bcbb62f2f64616d5cb6dda2227083aa93b95a1b775eb6dd8c7868f276c9ce5ee4ef493534edeeee3aab1b1e30ac7fcc875dfe2f76f9c7407777d759b973feb2c9bdbdfdbde9ccac53ac2c1abcf4a4bad2091f6aa490134c336e39a8e41427b2b8decf86292069864e1ce174b9096211af7839c2cb184d5469e2064b618800985295eeb8e2d1858aa55a1726d7bf591c934ab2eac94e0c1d3b9859e18a2c4c5092a0b981bb81b7386281142e6ce1a18b1ad00a42551071b105113f44918dd686dbff2fd0c002490c7ac0c1cb161b645d58c8a20b0b4c4931cc24696715e5549a5fe5df6ab55332df9420c3850a16325190c8464b25cb5d97d6e0c40eaa2bc2146230a501830b141599d8cd9a3c3dd831a75fc5d3e26bc94b8e4b737a701173e94faaf4c3a54a589880818918d880b081c1439fa881460076542e3c2c31c5edffc002d982240931312c81818a1e658488a1061eae94115212866f543c2e999668624b0d6e7fa26fa8a4ed9585390a95a91900000050001315002020100a870482a15830524471ac1e14000c7b9e44724e180b645992a3300822c618840c21c61043108111a12129034ae877b3aae3b6b03b24fc3a7c3b146de6e4085afd7972abc1c0192808ea55e091ea6cf53d4c35799378d8f543f05ccd67c68f3d75b70a7fbf45512155be294400c3b40b15d92d7fb1bfbfb09b9f1c0eed21e408cde766ca9caaa578d3839e6ad5c559daa721063bf3cdd0fa330be09f09bcc60b487cfffaabbbc5f205cb08eaf4c00d9384093c4888f7ff369907196fbd125a8c5d06e6f07df65540170e52070940f64b0077a5e3c1bd429d7f3f59277d2cbc9454f7048f7f9c2a1d5497b6715c7a9884edec7d2feefe9ea7bcf4291c433a24d43b856e45fc7378a34af00b3bd0ce349335b6cac7da9eb113bd502402b2d802652cb77581056fcb7269dc00f45fd8c3aa17b2befebc687ac974c90e333524538c4e57220218a59b3d32304dec03e6199f48ba811a5b941c4df64d19e5b5b838569f5c803d15a094847c5506997d5806a6cad35e0a69b7e7879854fb9875e48d892fb9c334eac0a8161b22680b7f273812a932485f21ac52a998f0164d7de89c06543a129c344ba54e15826c3ff7a86a469aa2ff54d3d67864d20b141e34b32c7ee481d8b6547040b3fc7e9a8e8ad0806be2b17fbf26769e6d567460b4728a0aba730ba77fcc3503fdfd8d078f1fc9914c803dfdfd915445754074f3d3c665cfef76e3a94b353c1e00f2c17e9a8bbce0a21375c6df69a9b59a7f4de31e3594a6ba4e4bc8dc0f68c894bc0d90b5f6b53f351a8f60fe15013bd3cde30369cb04581950e281fe95ca3d0c4fb30958fa04adf525444e86603272f8a16320e5402bfec2f6b696f325400b1c8b68d1105bbefcc6884304daa79a86d18ec03f38ec768bfad705b72a153e55b1d2877f8468fb491d168eba08fd5b9077948afc7340e8aa726126b3b94becdd9a0fe6d1c6c268c7861db6b82c2c87c634a40b9df810ffd5d1462987060557f27490589c181bfb0a4375686f02fa5445ec817e71a36b93102012e13993b81afc2f508ecf517910e3d1b088c7d005802f17baf7f714d8ef7c0482fd614b180f677fbd75b88f75edeb3c1b81553f6d186fffe0e701814756bedd10dbdeb8b9ef89c78d39c7a651d3db26c9133b8eca380f2042be71318c9cb5158c31d622d70b0702edfb84ea0dfb4ae57720d020fa18e330082bebcb8b1baae7330eddb0b3f2552f90b24f8856ca09b2bfa687b5a3dcead0becb3ac2b93b6661a831fc15674e75426ab4d72914206b4625316168539f2fff62b9b832630ade8dadf26c80ddcaf907046e21540412e4b9639de27dd2ed9938b90ff24e8660268564be4c58bc0b33e282fdbb0c9a57d5a38d5e55ab955047464532fce0fc1fcd749537bec64512010d77a613b3a752737e1abbc14089303105ae37ea29de92b0bf7d26d502e72f063f7acc30bec9a8cc0fa55283a80e596056122e7a8cc7ae8c85f5acf24b1241f8ec8e5fa9f4a252c7bc911d91ce0e030eced20c1e23133121334e991dc5d0318f4d55a0dedac923239b40461b866919746d88f6e2678d6ebb18fc209c605f227dab119b1f84d2684fb4fe9dd63d264d0fb29bb8cc71588bddb9297c899878605fe177ca1280c97ceaf0eba14df272d848bcb78ceeb648e2478ba6d7fde46eec8efd232009a230d1764a1a95d6c64b1c0f2b8422c554908c296ad1ce1a87c273f0ced44ba30df197d87280240caaaedabc40b85bb73f9362671f1ead25640ae6e8021d24d66c100a6ee6317dc45c10970222b91c04253dd904ddc860908818a308bffd5bf3c3015eb329b4e2d44e6ad30b0f7cee49ba4dc132a311d59599e3ac3febad0b615833e7c1cc923821a9795210bf4b14ed2214b3d02ffc2d47f9027b04f67d1811f1d382e4e375af4821e7ffdefe308711412ea93621bd126266be82fc6d8f0b4c77899218ad4b3c726d8f3741b0f1d9c9d3a067a8143c3e10383ced91294734de3e4003e302aa123e6f9f69b3326c2eadd7e69b58a600bd7857687f45ac0cf296748b636a0640b01f1cae3c91d1041aca206e2de7a41540cad9cb028e438419db585fdc4df9120d38af697a1413862578d2dfd79d028b3224992b662e70b9dcf85f76481ef4ff55707708d4654f79b1f8add10b4f5cc2545d464fff2269cdfa4d884f1dc5999bee715ac81dc380c68581d883d9147b606eec41383af680cc9642dfadac14d8edc734d8494e9df3ca37c61e948cd2419b3dce0730583054e9c05d6dbc56400fb30869c084f71c1a4c669a9987b88ec4d68fe8aec5086e050fd452613856be5254c7c32b259ac3d75c0f6589cbee66b6cdf8dcb112dbd91709abd4ac893ca098d3fc7ba7833ccd7899ae5393655196014dab28fed4450c829b7edb379a95863221b234f180ddd396a623abff50f61ba3a8c08d47cda360256432f7b089b2828eca15286ac1c82bdfbbfc837023abfa8b2261e4f58b47aee62e48a9eb00fab61842cd69601effe996169b55ddd9f193ebec8743efb3c539f8629e444e77d328c93f903de2f98ff7fa17d11952ffff2811267d584f702509238010339cdbe12a66099c2a4fb76e84472c76858d447f03bdb26ee1eb70e80991ec9b91911d987cd3f4fbcedd5f084ea60d59038529e3464da8a44ba13e3699762ee80732d7cd53e59e3e3a34b10b21fb2537aa024584ecc57621f4129e65aa33743df0f88b3e9fd79821da0141ce764b775a84a2b8008452d4a312f98a476e92b1c17e76431f6be7c8e975c0d3b49e8dcfd981cbb8aed3531b1c12779a14ae89e9dfa28e2b9edf8fed6a5dec89526a8d4ccb4935548d858b5b89545a181e7203f98fa52e730339c0fe4a8132259ca82899e449177e9990a60bb0fd83c4a12ae1fba0bd98141372d2db228640f31baccd48198199b5b78cad0879d9f7137e67a86b9f98b1849bc9dafdf627ce42a6e45786af4ff3dc93790e5f3c8f23c1b5bc67487f70f4afbf1d673039091237bc3f090183659705fc55a590436124b925cf11baca469248bc50f235beb60f508da34e859faca4cd857734e06c6c60d6ca8d3bc6dc1b8669814783e0a1aa709b05f6d90890cd99d97e7c0b893830095b7ec9a4c954bdbb8604b366be68906ad65f9d550bef90a52dd9f71b85d031cc36fe289691653b347743541ffdd75a1830bb96abc47f1efd892e9944a9f8a97c0b50dc0fa133678e1a528f52123e72f65baaf9e6dce1bd0af6562a4d67305cc4e328eb955d87e3f75b98b86a2328b3dfcb889bdea21dace76c0ad8e3ab3ffa85a3b8687526fe22ce71f9d115e705630f1e06fe4bf59c688175110d1550ce93c36ee410507e035b8d798f82ace860f4af71afcb04c4a3ea0180d305af217041a423f7825ce3d5f64296d214b9017c3ceede6bb48813b3f0600229de3e02a4911d52e46f2057842427658cc0f7c52c81897989e371b4b1a09bb27acf687a8a98676f13c0ad7cefd14cd6d04b76786528dd560a093d0e8ed15a15321fe40fc63336aa5f5b7afd81457523b4c76db058814d9712cdbf64d9b662a9cd3679bf45c54c9dfb77aabc6f5ac2aa5269913259a55b9feff9b00cbe12532bfe613aa1a5fc6efc8e1d684c153a0db502c8060550bf049b3b6fc457ef99eaf7723c7054cb1e2e9ea91f30d0f4081c57a69c6188b01bc52c05cc4ed4f55f27896be61df54c2970824a329245516e8854a1af1bd5d624bbcc554a43ad4f71e51b8206abc2482419fad18365b97ec79634e6bbc8cb683eb477d56c911108580898c0643b25010fe7078f467cc7135dbadf338167c615d720864d74ba12337b59c3ee4294c52b113473891d09dcd64b7996d47016f67f805361e211477767523ce88589eb266443076a4875a8d40cb1fc68ff2954a11f40d1721d10a76eec69eec654a5ad8bfebd205595e690f505b9c9077338e758cb8e0689fdfb28762f5b3e15f6e9b2cdc89350a5cd69488ed59348d2706eba59053779f37d6e943baa9825045c16b8d75ab45016ff5714a606e369786afe6cd4c987289deb54f5cd0fce23a673ce67ff6e137fee66bf0092d69afd2dc3c6f2f4455f4d63f2ddf524bd1c9b14a91f7d67d3b38a1419a7943d75efa7a25c200dc92aae4ea71fbacf41655a15ffc900545860c127250bd01f12613f14c179e32da2110f7a6588871b40f7118f84eef0a51cd8b9463eec897531a843a86cef3094d03539a863c49ea1d116e5d923ef610f32ef7756c6cd41174f0d2e223d1587b1d9b6ead26074f3542761767bbd3d2c18f3ac4297b5ad1e8b2dcceb2cdf3e3f7800b358155b19822577c608216993c82cadbe86ac4fa2d2c09729577510837345dd0067afafb297534256b5b3428b09fab27ab130fe38cd0a419869bba5da09cbcf85dacdde922ee80644ba3e5016774400c21a4feb81feee191c86736850037beca71b3292f17b7cb96bebf6457550e1200fe258ac71c7ef5990f83ff3c0a05acb4e5b4cf68b0a8923310cc267ea78ae59927b2533d2923b3249b6440d7f4dd566bc9524f224e4a240fde7fd6ec66b0b442f121ec7fad5eff6810549c22a87695c131c0765fd41961eef87ebfb4617aa824a9b2e1f35cd09bd66d0694b15d4c8fd4d26a25a33b7243625eb67368c204aab85007b7fc4b9d07a9bd6bb294515fad45a89e33ff006097867fbe58ab1c79b605c19339852dc2ec1dbe47ad15d6e9263c39fe6dbfd9935cb27c60b93b4ffc3c2ac0ef159f1b80c414305d14c69cbb4ff341cd33a419285053063119cf06a5708ea4b00ea932b8c018e53c16a2af43007208860d08e63344c52333e25cbc1c6c12a30485c63f4c31498d8f7a121d16d85c1a342da6543c49080653dac0e0de402367022e06bdd8d8009dd73cbaf0da9c17504b7071248e4d04e59e4558504603e881e91cfcd926ca80a9cdd2b76a9e4648bf065279faf27673a188b4694a51bd68a1cbe647f263a3c5a21c08539833faa9e9aa9d5b525a03fcf1d4a6a7cb875cff412d90167d04c81400547cd8897a9e167a261ac59ac276fa96916741586eeeb84050a1a7446e181597310d3aaaf596a1d4e318d45bfec63f7ce18de2686d7098a6cc52980ba9f76cbc06819eb833e9649465d73c086af649e50261a368fe3e60e60cae4af4c70a23f32b9fe246fa6ef2bb959fe959e6d8d1f9a7ce09122b0659940eda4d1827d92e0c2b9d780c1559ce3fabc5280141b8a0863fc3ab0e7a15fc22544843141e081c9ea49c135bd000f02e6b46b9d830dc474663c6c9b57634bf2142fc68f4465c318227cda3bc7559a21acbf65aa07fa4ceab8ceaac62b7f5a32eacd814a209efdc89d82182b7dec194dc20dd43aec75a2467e490afc9e1c310fe39ec9e6c5e179dba313fa1102a7958e6fa900541dfa542f75a0a0e8f85a6f648288ad688cade4a6f974fe18a7de6debaca40e58c040a2057c858f51fcff04201383b3a4f0ffd0ea43c590e41f9e480b70ce897c842818200d0450412bb79642834d45b5bfab412439fa4ea03f7f70a3a47ca1053772e3f92654da01b11f4cd21396845fb1a288bf6f50247ff0817d4010c8fccf67c4010092ec0f3e900e7c88dc47e144de89daef90757e67431b09b141817d226c3b8ba1b0d5ce9a7a05084de319b46d56ce36d9ad77286abb34400d4fa690e4b6bbed13bbf5dcae61b75be652b8144760fa6b6d9b38c9ada06f30b37a4ac505d9d5dbc7dd13c080e5792fa06753b1f3af8931dfa07f2dd6718e2adf26c3deee184b4d34d2710000f80cb330512d38f319391c45a72950d22c6d6cdbf84d5bd389f17e5f433bbf523fe1118cfa3dfce9d7695cecf43e50c5905a434a23f3af0ecbcea7e644287d08bea650fc75220f93562e56f35a026fc9b236b09cf8deb1d8ab8f373b79bb2c5ef399d6fafdba5d8a5d74b33b40af1dd3dfb47311d216aaa342a140701c89a59e5f46d3da9835875f2d086add94d83f281da2c4961e0c2cdc6a3ed022d01741f47f4f7a200bd8f484fa50edd32941d517fac9719801a08509600c1060e80d30aed47261199074c39080c318944311002454a26340d869efb473877dd898b33db6b2f51464eb6eb74547e3e2a2ea22d1bce844cf1f430c9fb485ec03cd29febc6e6b65f70f98b1ac6e42ec89b7956027964540c5dc95771de28da73b633cb926f1f9c8b7d252259853e9b35d73e27f1f03ea2ec268a0445a522400485a17fbb6e34b4d46cde054e54155e9f33e413639db0e40d285077ca0b23ef1198766202d0caab6e87733011cbb32e625e92420599f1bf6505edb5a394d23c253140a39cf858b8d2e5dacd2ca3deae00c82d9597cf0e80a944bbb0882348172d8fbd368615f49c10494d2ad8c1b7c924d0db0a22c4e053d892062b6f8c1e56ba58c3f28d119039b1bf3eabb0e666635b2fbccbef1bf8b386a86dd6d80dde65f67b3fb140984b058078549474c6ea2c883844849536ab1952e13450a2cce7394b243022986cd95bcc166f68573358dd44886b500b3124cd3d4176593bfad59d626eb852b7a031f9031e24cc7f58f2db61c5b0e3b511c6fa7cc84df2e580ac187d82282467564116bd5ef7281f6bfaf0f80ff82a4dab22025f80d9299567328dae72f4dff4141180bdcd4a2f541bd4447c58d8ce9817c016175133618d9b99c19f6a5bd1570c378f7b4f829bd68e506495a6cf02221c0d8930490ddffc7f3bf47446ea228eb14978d9e54f0e14f067cb6375a832d65fe98ffeafe99f4f64f9617843dc8102a2f0fff91aedfa1c4a7beaa1c99a28c1eca7d6f7269107009f137dcc632ad1e4f79954be5ef0574e595b26e135f97e8e180ff90c34251d63639df9388f446055830cd3f39b635084f6c03b29df9b4fe0d310182c9662c91e1ce51113d2acdcf6ca3ec4ee62d66c06bec871876b68e73eaa4374aedab8c7fee3968eeec0d4e401e8ef14e03a6e76dbf611b146279a2227fd931e38ddc9059910b2f9cc36dfa4ab9063638100df62974d5b430a94d5aa40d82286aa3795777e247d0f59cf1a28c659a8bb98e91aa145e9e7ef0a87d0370f1f9fd3b791c98ec72da876911644bf1441dc12921354af46936cffc8e071f523b215d3a055075836d8f0c65bbe1dcaedcee3c26789cecdd82580cc1bc21cb6f25495e84cb85e4c6ba15aeaf50e889b4add80cdf0e0195574d3f15513b0ea61db89afb47f1135e6c132df0c1e20cb0fa25ed35fc00411fdc2014eeec173f9f50e09747b6a8452720cd5793b25789437fecfa51f1a7f63fb2aa178f10ff3715da9d883f4f4a709d4d7d730f2336d08361473ee9e8c2b883227d8b107b962f845d7962ef3f254de3567f926357e3cb4d5eddc70ae5f5b4b8427e0e3e3c956a665d1f206a95bf78da9297fafc7dcc5a2167f546a5227c8983c0483c29b71498b3f955eefcc08deeb9a51010ec3d03a100c5d1d579239889d9ee712bf29758e629c767105ea46d5457ece415b1289dbe1781d99cce48c9c1d5b30341c77fea90bc3d73495560d52df59e853f02cbe95cd4894cdd32411cd3be8ea0f3c549df04d872fed82a5bc099eb8177c836ceaaa6b215923b53f1212ef378c0ecd1fec6a4079fe43946d6809a005bc54b2bece76322415963df1aab7eaa81ef15c1bec3302d18b902275a66a2d42c517869350ce88d0a878f4c0d0135dbc62ac20602c52c165412a317bc59bed4c93f16909d0af4d461d4ffc8fe9908e37510e5de94a360e1348b26eeec1be43c6ac05806a2832877346a74dd731d6acebe14692e625f4d79e01d704b831f1d6cd2a011120012b134d03bb3d24f797001fae7eec9723ccc62d3052ff1e8d2c4348e4be310610d969559a915eab8708a4c82564efc48149742dc2273ae25aef3552fa4ead7244bd6c63f553920625fb578c62f158e9efe19082dd9eb8ec22f496990c5306507b45ce4ff6202dc65c1463c46d05ce6a8eb47b870b1f06427bddc30fc97ec66fb3f89d8dccd609358e74498f43707df42a9974ef74cecdaf1c6acc23f66e82ac30ff60e55bc541543ed507f7772fb5410f82636a936cd7eedd86418f93ce705cf03199ff5c89bb83d632ea468c2082514355118ead978514cec215bea6651271968e2ec51977a8984d2c102762b9c7232e2010a2eb5838645eee9893f1dd4fe0dcf7b711c01534af19438c019b1c99304d023139d1574a12c21eb0abdca8e32da7b667127aaf34aaebaf715c574ba8fd1a86619064edf603741517a3a32ad9a83ee4401a630669d658772f34dfc031e5d27a83b9a23510c1455e4f57b908e0f46b4603989a2876d45284d67d2d60e858178364ac48497e372878c3a10ea4edf8c2f1efffa0bb22be86fc3df928527e40f610c2e2651f6f97d171a32758e384ce65367aa4fb6e4d313e3f0e5dd7376aac958ab64d73e65ceeab0e9e19746c167484746c1f1f802a65f61f60264324df12cd40b4f6eb924afadedf140e4c374c960e8268e93f9c1f26b272488ff1dec469815a8d1b14081c7086231e3a2add0737789443e920862deec480c31e57fdc470b825d854500cb85566250246ee1b54f15894ba8559b3b5badb0f0144f130ee49d620110eec7b0453cc538782d8a1f835ca9aab203b19c31c5237acf149fda65bc23a3af3812238ac3197238b417c56ee883ae6531af7db5ab447f7e681204d8f964a60dda8102c571700702bae326f155cc7e0b2e4a266ceb3911edad6eb2a3b03df716ec078b4c8081f1aca63bb26bd160184ea6708bc887c04f79c366155c162bf890871dc1e0585bc1558631ce7d7b5e03e0b1f07dfe04d3ceed41a195e471a63a11978286b2218292026a0127e7b0f493f85c62c31125223719430520e1553de464d641d4913fcfc0fdab742a97784f3caf5ce748fc1f46dace495595d00ef034c88a6b8bf8f64eaea880fc7efe6a5e1c3403df05a90cf88ac78a514098338e320df52526cb0f0b218527378d977a655745a0ad0ab707d33863fa6c23838e7791b3b0acdd414be868c506dbbda8536cf2e14a3e1e30b5890b1f6fadf79300b3baa2ca934e0906d640cb922b00000007cda4126643054f8edd5ac3b9b1b80a65684b6f62a7af47892235c8349a17d4418e9f6ad2c3f6de30a4e3d5b54578162153d64e27a2066781d4f12cd31474a7bd0beaa7e4bd21950b93603e88d1f30b3e8fcff501a46044476aa1aba12aa41bc56951ae348fbc4d0bf09d1382ccbcc785f4c1397221b44ca0a5877c2a562b060f839022d9b081f42b7b4d2839ccc40dcdd7253187af6a924828d57669e780499bd52631ad5a0edcc06a8e93cb3196de20e4907678862216478763944e45229ae67a12087ac2ca73d1cf2bb1a6492c0879bde8edeae2d66de7d2bb03c5c6d97c7228693f5ba7b616cbf0121209a7833d57b72f783870936f07fa66dbe2dc91c4382507d2d1f5d85a4be841877ee15a591ee44665f0bfed76a889d59a4304d2876d0a76b5359026010fef5043804abc16f8e720ceb7e80f9c02972ab2c1cd43573b305cf5b33828f91ddc7204019ebded908e9031bd0765dfc6bcee23b9eeb7f082be7f511f07146f378e09d6d80a8ab471299fe1e4c90a14ab456cbb90d8a6cb4b7abb20210fd947793489c0e2ef70bf1a9c581d7b76ab27f3ed815880355382de0d1c45fe090e42de97ec959d66ed38ee27420ce8068641c62c67c39fa6e18770bbccd2e09e9bddc1b1aafecf4d48c2630db7c0bc7b1476a74929e87ec319699cebe389a2c2afd36654460bef26cec01270235effe0c849ebad0594c0980a560b2897ba5b3a69e0cb5ca291f3b9512c7355aeb7485a47ba2e743959ee6488fc72bd081a667c9118e23925d4e11c4943ce7464c8a040e153dd191b70e7a95f4bc171c95b1bdd206974bd82a4871a45dae2529a5935743849c7725ccb13d9b20750878c941ae2bda7dd38c4fc67bcc2638a9a44c5302576096e1aa98a855c3cf3338508e220965008bb99beddcab8942fedaf19f7bdef2d036812e592c365944914d9509c49eea9ba49d3a2de6e3c2658e126ea2c6f2b7951401d2527f54ff55371df00394f8d45931c6272e6dabb14ff4b2ed0d85748beeebc98c02ceb02b584b94409c2e35f190f6f3e943f78787305e795fd1c0413bacc8fd6cea5c113151c47715445c5e98f0d21a2f3c553b91a2ece7c75666b9e005ee743ca8175ad3a22145679f26f9b0b9e3378a37d5cc5e5a397172140b6d3c50dfac3083ae241aecb0865549b8ad13c735ced77ce85db12449d41e4f4b4dfd1c856c5009c5945c36e24e9bb1b20ef3876a2bad70e5a53de858312753203119e27e17d3dbfb1f806d9b4522404c0c4fad1fa4144c369bd5b9c0d0c829504b0931d35031a58c7cc9bc1cc79b05b488c111f326c98c8373f34e4071d2b2608f49bb79c945545357d706d7c2f95cf835fbc40ef8feefd2fd1d272852ff3d324d5ba50067b10db4255ae51f8e52845fde3bcd82c6c0a3a3eacd60fee3aaa42c3d6b63f6fff2df631688cc82b4290a0bdbad0bc40ae258e9846e2a287fb3199fc8890319dc5f31a914adb4c3583d3281c84a6642c436354aaacb04f65545fdc5ab4487c83f75645501c20942b7cec09070b7ef9eced879453be9858c2b01954c1c2bb278964f7e81862eb8c9168744a22d507a422936813675e646dfdb7cbcafe8700e8c35f9b5b44c96ef26a979eabd4b6b4e9e1398089f50575463348ab21663637f747120812cf6912aee84f032a494eab8ae6cbe838bda3fdbc144d106c7901b8c37a3217057c05ada9d8ef81a5f6b20d8355aaf65735cc667a4a349ddefb339a1c67e2c1c6cd2d2beee943a1b9f252b50b0a542b631986343ec55c836f3c3687dea0c5e2b2fa45953b40fbb679cc5af739156075e269ee2754508e8b086759a76dfbbf871a96653140cfd13164291e2e42460e4739a1e21045aca8412c4584cb4ad07c4c47482307581a6d130049f3d1dd744a9ec73fbc81a8f3728d6912f3f118fd5fde3144b2290ee6194a1f4d199e3ae57880cc523431af31fbccfcd946e2723a6f9875ef796f6cc7c532e10071b8a4aee9926b1f06dd9c9f95fe79a1d47fdfb72f49392dc76b16a7d81e92b3a044d910ab0e4398f60e646ce3490b0ef36bdae7348c8dcacb2071802cd8b5010cc32494ffe327575e6177ed3f656b78f12e8d5904a0d941630acbaffd496ba42809a22175872413c3f0680daec25a3cbdea7e4f35df294c5dcfd7f4227db9ed13e5c21c89c9d3d886f47e115638f65cc2d5ed3b8dccad13112f69db2c9649611d76b62a95dc9e8315a25d00052be82d14f151660fde8511b58d456c8a913be54a9ef44cf5f95286085499906aa7a0530c30e419e3ff462e194ee52cabfb29e1949edc2edf86146741324549872456ade0c2ecf6f319a998fe3450d0980cb2f242c43b133ad952dfe17e046d5029935a81b57ef09951b719cd30bef3dcfa9fce1ee322cbd4bd320cea149b358b296e05e58728bc6e413e0b1daa194ce4bb66c5356a51dd27dec8b84a88c1f57acd494edb321202bc96115ef0ed3ef3c45ccdb136737f57bf974581edcbb804d33bad0e02549ad600b9d26bc68880d8c9eb93039c0ba10e84b409404f7b7f06c2ef9f3848184bcf03acffe174d88d2b76a3531f7ef597c82a930f1bf4eeacd65f05d61a3df2d049fc13c09a267b7c5a20af0502d62e99ac35a3b86fc7fdc4845baa0b1e4b44ce882e1c303724c7ab30a96e485ecaa826d05063f0f2c109fff18d7f4917686ac1ce44ed4bf7312ba727f52e0e07f8d40031cd163e6a6f10b23d28e942f1727746d0e124409b69dd76cc9069779292c006e4ad6ef0be08ffb74f8f9464b13fd0116bf4cd478c601e6437dd09af2c322b70edfa5f7d914a0b693dc267da7b9d04bd34304dfe88c808e86eddd9aa62c5bee3f4147476925397d650273d6a0c849cbe7c98bf32ca23b0a519336fc51386290e71c56502fc8888120427fa441b888896297e2bdf6d6a0631e1327d1ce99d42fb840be7e71b4fec45aa09f7e5b5d81c003797ed458e44887f2b4713b00825f1f9b65da8d497cb4bfca8d8e1e80be4138e3ee75dfb559b8f16655109dee3621b9760673d6c9d339e100a7b4a62a45fed5087dbf502128e3588a45b41b5e330a1d23579a540a7baca86359eb5aa08bcff569d5d032dc2d128d5748cb5bf12405ecd368fbe1bcc33a919e4faadc79507d682d3de19fef300ef7736c68185a03960a17ad81b4cf6c357ff734c93bedaa338a6cececa067ec0c816e2d62cc742e1544d6d2ca04d14777732595fd9da6fb3f2148c525bf1a418b2a16c11b2ae7400754ff1becbc2b8ebcded8aff89f73b22b671454a7ddf483faacb42c98a3e0355b1bdc88b5003a059a8f5e48d5d9118b0f962795a526d05bc872b8e6d8176b7fef91e1baac83d76d7a95b968e80adf92a3f3f6d952b9d8ca14871dbf9e64b45595f00942e4c4f1ba824923fa204c1cfa21484a3089b8f51e64bdf87377c250bc1dde26446e3931fa0a506a4e2c5640901313e104379c67c15b8bdb10b689f87a7a21bb5edfd787b9d48b89e8d39561b8afc63b61c2eb428ae0c1d1ae0d7ba0c744341408438404dd082b3c0c40487639e531be166d22169ecaec36b85fd6107a30660ce4d139d11a6c9ae4b9325cb219426533d19fef953f3c369cfa17618fd274152ac92c3f5b26a4eb2c23d07c0bbc772bdd9404199bc71fa8f34541e8850d6469000979281f08c5222f6466f7df71b4aa7fac549664bcce1585c47f2cafa45c826912f9a760675c02289b2a90503754b214369b40cef34b9d3ba15871811a633147a8d71310eb41ba775e55bd9c20a62050c424df110ce9a931527e7ccbe88646aab1682ce3ab08085cce487391f862b075fc8c73f69332f09e7ad44a79c9459804208e82996cc923d2b1196a37ae5ad9f8f9f89054aa4c4280d7adc19cb53da411842ca6f96e74ff264ee7013c3d1d7414e65a42c7378b99686aec4fa37282eed814814d3897b5a96caadccebd9f3104f24eed79877a796cb44896aedbd5260f0b61607c7651b0f60b38949f9e48a739633ae0954716e3e6e20d6ca31d0afce53ac7749f5cca8d4c10f44d706981644774ed4a19517a16987047bea685386295847f5176fd812c5cf5ea2973edccee0a9feaea9f38e1592c86f409c7a41101410b851ebc2daec579f99c4ae9f483985585a2675d4c87d60b8dafc8623cb2ceace40b7e366c0f00a1e1a1e69c0277f4cbbfc69039d3ffc8acbc491789f5138fd1ebf8ca70f914b7209b1d9e7495be883eb2467462c10b20da19296cdaddb9e137069931a760e664f50e32ad27dd7ffa9aacf66b6f758d434fedf05754516cbedfe6596b97305b6422005ccbf19611ef195558f64545dce429821be42e3e1d446e0052e44fca1983a2edf7baf128080333f5b220602007132c7903eb99ffee155101ec5e7c7b9056102c1877f83bdffc1e2d58bc6158f5f92dc090781c1d2fcc54a70a7de7d9ac8ddfe85a80062ca75127949cfa501e15acb33ed7f97a9f41ee340ec92564db58727c1bbf9b682684d4f5e050667eacba1c0546855e03465a14018afe2a615ef49afa0b62e2849e3111cdbb01eae290a4aa73f75c72f54dba38cf05b0c4ebc309fa2b647efcf4f9482439b8db7e7fa27bea89521a1906c9ce6436bedcca9d5ae311710f7111ca23333dd09a329786f5fada27c62153c370a5e25a6b7e437048bf3959452a1eb36a57cc3ab596a04679c4f0c11899256cf17adfd9538a529c32238aedd18dea7463e7d9d806982edbde3b15fda6fe703fc3df02efa490640d932375568437a81f5f1d6ff673d125184a53e382375223409ceb8114cf7b38ab051f99da427b4495fd3ab705f2d8ba38d3297deb736cbb8bec186a32e4e1556c5cf1c50e8140b1ca745eecd1d061f5626dd71448176a6e4f0aa5e04f91827358b70918aaed97e866c599cca7d87faf665c7f6efd5188781243c31d1b9c750c63d75d97bf1b6345ee41a8498080af6548d6722b686cf9efc41ddc23bc348750406d46faa0cfe608a77206fe46402990cee7af086669a766f7488b180f21f5b949c6aca74a578117479ea436e9dac749fafe3e2a8c4c8babec6ce0819ec82baa8f356d2ef2da4f5ae0a48b6d145cb0a8947aba04f5903ac30b12c0fde84d0ffdcdcd6951992e1ddb0a3bd4cdde831901450ec64215a8a362a8b762a558c01cc8fc037cc02e18406e0ca22caec0aa509b590d4dce506cc282599b65673c79822e6b8fb8347f8fa9f2837f58916b4fbb26936d14fc3f80871485a94ed4113dada3481acfa1c6713c9438c0a5d74c1bc9bbd07d6c2da26db3ac588b7c3204427aa13c2f9485606bfded0bfe0223deccf763948de4bde3f97ca510d60f37601cbbc569c52fa005629080ac5be95e187c42936a6088ec6c5e6a80db30a429808fa58e953fbaec39f93091fd2943becf378dd38513ff05537d24c637991feef5a7fc8e9163d693dffb830b46e72704dc92a44e2bde89b2ed9c00525d3e7a864f18ce2963f704d2134ab617347e8559a1a56d369bddccaff7920916f6d3f15ecb294d432cff9f6755e92c11e8caa6fe7e901fbb3dd3eee4fbee78f9b329f6647f04a87d3d50e95334e36e5d905add9f309b3a82bd6a860339401a28a3e35f08c189a40efff5c2a7eee2f526485ee48098b9fcf26862261a2a64fbea37588151fd707d4286275541376a0a102a1e5beb6a3fbd03adc618d22d4211daf414b0ce83735fd3ef314132d1e923b0fb54a5d98b709fbc4dcdca1e79061fcb9ab70b12863d46b3def952c4dd99bd3c831c821d3dee8b88b8b87834136d2b302f2a481b43eacd0d46b0702be4ff99610b953aee84f22a78cc5acfc7d7b9a77e83a7d32f0d58fe56dd050c43fef53115ab4ec60783849062c5f3fc04ac00f2e876a9efd54c4f073b030d3e4198a7ba13b244d676df3b025cec1bd28f1fa523a7e40cf5404c4ba7ff5b19722833ee2da85c63ed53f22c0f9dea790c9a65eacc150a8d1f9244216c5037a112fc58abef5929de9bc1cbac0d427da804b3199a14b65bb0cd7464ad3d494bf4e0e82a00df13435f087ae2bf38efac7a28e1897b8f045d5e843300058f1b96f786cdde57bb7d8307694fe9d5152b0fb905f037a2176ef9ee73feb1efa35e30d0cb7cb20c11d53851554aa9fd02b9f9ad8229265b32959034d72654d0592d8f42a9e96f060e0727e71c55afae97d4fa918a45822707c067d12ca25fe5e1df3b50adf28a728028ba86c1f519253b9900e58e95282383a7d226c29bdea407f561f02184cdb3cb80d695db10c5a13f34fde279f2d59d226734195bc0f41a39a7fd466fdcc12c94f8b21ca945402d0457113a6f34ff7c2be5e07f5f28af50fac02914effd2280482a25408a45678e551785dd95e065006b97a2da838465fc10b1b97f142dcc2b3c47dd5a7e8d9574e3c2f13efbce767134930b1ff984fa158c1523df14955326b30cc0b627824ee02292e6f0eef0d78ca803de584b07d5149b6f13884d81fc9638373cdae0bfd5a8835a95c9ba3125fbf5dba1df7bd9f8e3c584132fda3849182a8018a49fed85ed37d1d698fdf341c7ae05a0307bcd102ccb9990a86d01f94ab2f1d1ddaba0769d4cb108a4299f52e94401443253b1580916485ac6baac7f5389731100abbb80cdf00a4cd4c4f16a155a04f50db4b2e0574c298852c97031f63d403be200b8efd414373b489978fda6256298bd846a3f1f38c5be6c8806506b9f20142433dfe5f735809ecc8c73ab1f47ff4853cc9a3a4b119545494ca419720b9571975cfbecb28d63fc837398c0d275a603ca4ba9c0bd7a4b8ee12f018da5f28701b528a9406d3a18f93f5c039cab37c1f3d0f4e29a6d9dcb93441795d58468b0d7a4e35492ee03dd8048d87ef51986019720e7700dd566754cd5baa97e6db546657da31fc67906c294b5de6af020fd443068cf1d3ddd511e35d80d6d320a3d5346e62ffeaff349b5b5449b01fdc30db0165eb79c64e71bf1a0f9cc3a557ab0d09bacecd176633eb704d437c133e44fe0911c1c9d76268237a2286f2029deb2f1d664302623dd5ad590e04cf29069a78768b3c729aae149e6b7970d260a213423df95b5842f589a89878e4b53db237d4d94db673eb329b54db23b6d9fdb533e8924c7a88a2568f3e28b1e6a61f47e56a764e40309ca45ad5a413cdaf9314b437f35585389a367bf3a538df094378f23386b9bb37e95b87d1e4873e7644d80ff72aaeffedffb2062462f48c2fe742d87d4726432861436beca5bc7afe120fa975113284e36bac18c3a5fef7eb2277c25f6b9559590f51937a51a7dee92b181605bd1bc98f0947ec983dee97f57ea20eded3d04096c76b07bdbff34d1ae97da9c5f25ca9005e4d83e2118b1f228ac76162ffae5eef049de01a91de294ac024de69408115c0992a4634ada0b9b25ab69695f661656aac72c1828830550eacbefe3705bae6a8b8b53439dc72d53184fd6f48680f51fba94c528b2d4d91f85975a88c150ba1aad814174322185c97efaa85aaad227e778be954b9df3964d728f82a0b8367aae5f0a2079029656b42877e3042ac91454f7c37a71c00e8d269cb207300d4d0ac8ad3c378aa1a7fe057afeae6d903613d04ca3021bba6950ef6be66f2b599b6b87f924e9cb4ac90d3102bd27e9a07e6959d0d7fcb630d0b1820a7cd0ab5509e0af9bb52a356f9c1a9e24b42508d5f12df36af4c990db50e550a42a2554ad054342f15667995c58184a71e43b675f46a75ddbd4c553f543cb433dc25dec5612af2068a6d59e8fdc4860c549ad0133b3123415e39000891033a0a1a873c027ef0c37463afc6dc510941c2db315e4970a5203766f7573b334a653bacd32e9faf9e5bf8e1099d57ec2c3a467ca5ccac7ae91cc9181ec015dc7d636b023b503805cdefe15300a9c9b7ae1bbc953f35679a976d31e2964d85f82e95117bbde38f8f9a5b8b07cbb077878a8408e8c0d41e3181e09d5401215ea05e236dfceb67a8735eb7339f7c6b035b17482fcffa28d6daaa5997253bf5764e107d9041d4c12dcf0fa1d5450729c86f3bc1123dfe19874c7616863b56eb508bafb45b7072411c695d020cdfbec42abacb5e89a1c44cf793649d3274d333cc8d0b3cf741098dd58140f5999a778527c9cfdcbd3e81667d277ccb61748f2f3c16549c5a17868413366653f3ba0153c2da4204061dba97c3c0bc4287fadfe1c8e6c10c0e9d56a5d06a99d9822f19c0f011e616e964e0055597dc9dcde9dbc7098513ba5b6b728ecf301aba598fddb41ea8f2f187a3df15b0a00def9a8f39dd6529c58f979a00154bd15ce8908a44759b53912370b12790e509d93a536e5158de91353c7ddbf2b74100dc3c28683b6077dc78482f02ef67ed68088519cdc149bb1c08d9461e217079cedc2fc6d9624d91cadfe14f9aa41a122f02696c93922fa3369fb693399247162177eb6612fd5919b3820551cda2fcd05060d4101f5144d61841e4b8b11fe4c470eeccc7cbbecb9dcf97571c3f4714491185c88be13d1e5c1429654a68883c3a34bf73d0b110c6fb00bae07b5ea3f82abba236164d7d8fed51fbc4207f12a577e0fe43d9ef96f37f8efef6cae611da25d182781e0f55fb68914e59981b38b35290e2ac1ef172c296006b1a134a8f0538f5d89b41a2c5de67ead415d254043793a0a36b5c7a084c895dccdce8a886472442823bf092274438fd70ba7d1e2f48634385414ec3c4265e9b15e8a9cfa34a2a6d3e111aa0338ac0f51f37786704c1e09c7743e5bef432c021014dcacb1688120012a979f1aa9538b83b6c94b10293b863f70596ac03c3ee95e73a7437e6993e058108565be8c50953b9a6e87921ec28700b29a02b2a50287bc3bdf0e07ec34522b7d429af558575d1619025feb94b6588c34d562374c3fc378dbeb1b8beeb837aed5e2d1dbc3f7f9c72b1f893fc327c4446d30f94d638c5b2e7c90aa4ce5958d5b5cca70d7abc873f3889a3b0cf6daa739d44dc71d9c550cbf0722498d534f35cfc1264e4b1014c68228a4728e340dcc4fd3f195a2ef83bbc2f4c9b27839c9f43997002f7d2bc189b68a08eadcfc12f520205af12124b70551d398ee7596314d90bdd7f03d5a3cc28fce9ced723a04a21a2b81d5f71a70b688f1b2791610df8d8102d32f5897b934549632c0f21f17b4cc011f993412fc30d3ac826301bf306eddc014af5ce58d97aada25990487ca2c17f777cf38c20b7cf2b525b0a482b9c6c7c5850cb85445af7593d055109b75a3e3766d5867ca1e1560cd7bee25036274355e2a87765b367526e78c0ced003392051e43a004f420995ed6bca2564c1f6e7200a70bf146dc69163c26f52535ec52c4a125baf18b25c2670d3c5f3047740bd07878b4605c906007131bf0173e7181d47d1d1399eeaf6257e96ec2dbadc331c56429fafdf440ffd1a7096ac11e09983581da7390a0a5d51dee3e4dc828a5fb0a2280d54ec8b54f9a33544fd298fa2bce0727de2400c8fac3b6140204222420a7d15c3cf99c6d11645daee623aa0c87213e6c728bda0ca8db2a8b3275eb3d9757f58a54333e7e6ebc48da780385c663f0f37f8cfb81b5d782e2e50a727e52fcbe198278016f06c5faadad5a5d9e4e4463a77091e1acbfaec8f379eb8b3af35635b34c2338457792aae361c44ee49296a74519f8dceec526610e3b231f07d1c306c05f110e6191cfa7a0d823c75ec60e526f2d6a5d8134c3dd7ba983a59f39f19fd6da826487d592571f803eb1196892e4083bf359033110713d8c43b1581cc9908936e267fbe23e7279293484db065a065ba297435703d3cf4961e2b0a97d5a296359d4c3ff262b35164e0e8d260a852f33463a99738b3d72fa64962c7795e96ddf9321cbd455e31f5e23888de7d8a2dd21291676c270e2f28900c47dff8e9258cfcafd6bdce92dc05a089ec7cd002a0ac06b7c6b1837301746af43cec035cdca7170ea58e3209e1cb3100a367bc27b5d731f6f1ce8f7418fc74861cca56a521d433ff55b956372047f4ac99b824adae710e4c8ee7c6de20964b82da622e5e0d587aeacadba3bd1499f002bdd47046fc6ef304914d1a228cce9d12e6f62ca902c662762244af442f2a54cf653aff62f6053d59b75feee1d48d4c845932aa5b9c582e9cea4e0ed1f1ecd025114a0133c3121d4594471321bd7a9cb9cc65663bf899ec41000df84cd9e8d1c211b8c28824f11522ea174b129679302b82a70745882cc11f3fe25c7f92fe0e661a478da243d61b40cfa4feae64a72a689c04cb5cc47f1ab692cc66ba2876979317fc0246a2ca1ac2cf178934c54b982fb11a6619efe72ed2a5b6abcb89ed9ec265945b6973264d9984a0480a4576800c0d43417648676efce6100e8106320e75845c1dfdeda2673bd5029c7b6b1fc4330f17809d1cb0a38574c9f17f5d2939f3dc784708965f7be08ce70fad56cecbf7a0b2100664e4b59463f5ac946a39983536d335b236cc811b1e5152ba375ad3bde12ac83350a1008ca0d3678c205ae4a8bf831ec3d717c44b8073074b6b7acb139e039526352d85617b68f8572e776d0a291e604e3499a52091880f60e67c7841ae35a7c7eced99d99bf9c87c70c72e6bb04059c96b1a777ec69f82800477d551c3e9816d978c197498b3e7b8770382431eea1b2e6a5dfaccfc3de945ed6ba313ae07a1647afff28b42c12bca23df1fdc9cca3363062db0e8dd08d3f26b19b45dae2cd0fbad617411af5e5466c3fed82cc7d21ce2a048c9c4f4ad3b9e78fe3bc02978cc1bfd092de80c08bb47a316f092f03139819646bbe44694ee6e5af448de64aef1b9d34926f277936f37d4b47639db2072f89514153fc62c6252bb5dfc9a5e0bc1e613ba764c491183e240ebf28db263e1d1ca6b5578b4314d1c2c3b35cfdf9131ed88015e27a71214ca7882138818851fd0ff11f76f4bb38922c48494f4537c46b63ddd80963a9ef9c92774a553b2a03042905412c7cda91564f1dc00de4100bd6fce8b63aab3e857b7228bf5720bc0fd4ea2a147aaf6a12b4597a24edfef19f9c8a037a700f9f629a6bd8670f8b8f662946becff547bd4fa799c1711f3b26066be0f5072698d937eba4c077260d31b0eef89aafb3f4307892eee769be14312f83f1681480047d1a6e0efb30ae97ce1aa1c27af2410329fee61d0ac052e80c8836da568791316e44f033decc76d78e5a83381a3cab7788ad8230a9f02509e56039872e1b31725e8e6fcdffa3abc3fab9292c93c1d5f49448b21ed483ba6bba2a4e03a5df2e012231c5be1fa52d685171cadac2e32144be09633ddfcfa90381d2c72f5e4488d56cdc991deb5c5a91d9b54858727af1f3bf3c3aa7db02b317fd38ef1cddcebc9195be677feee7b13a8e02b5684d2d492d3e00b91d9aa38846120810195e42712ab81e21e769a22b97504bc31f6cff869bffe0f8c1ca0a00b4e3007c3061b096442202fd89375d00327b5e5e73e81bee2dc3969fd5e04f235ece2a27177b54c0d8b3070b362433f0e1dd4811a7cc1ea2f4e2cdb43803c41b5d80946a5abe29003f6b34e681589d5172d1a11b6a69ca7dccbce279801b5ab4f12b2b1efe01618aea39c36193260cec3af87209f5b61a186040aff4fe4790140261d690e5328b28cc423e921898f952159edd98125a8025081ca6245eeb68e9cc5df13f9df54b1160fb402d1e47ed223f18284b2cebcd71473875b4655c8480184b0160ab952e333cad117f6467bee2e2450982817809803ea0e2beb3c3e24af8f354ece8c96bc60625148ef3d130e18e9f24dc77e00c4b804a7b864e65a22b96ef2f1c1843f15488213b8c47406ebfdf8a0731d70f68704a3bd38e36676cb20bacb61cd926ee420099590f5f02a62f8890949d922178ea4f8aa2f4c8d463cf9b4373c9e3c2f64a66e984991689d8a4d057300e4a177c1ddadbc24e864884d4ba2e53eb316260c3e9cd5f0900dd6f5fafb2ddcee7c1e9077e7854ee989accf70d37c0080c24ffd8470971f4297f804685289ea1a600be3fefaf6bbdc5f84d3e58e1c26e9580ab8223992bb8fff0a2f2b02d1ba13b4a164061c377569d9c4a77bb8bf99de13bb7a4e733da5b91dadc43637dc8fd0e361492c135ddff382dc95af8fbc4333cb292ecfa227a11b8a4aa73f93df94596632e8aba4547313b9b6cc37915c84bd2d4222478959cd88d8f8c23348dcbe4524c7f3bbb05b30216bed8e0d7c3ef57d2c012948ac762170c7110008a47d44bb04828a442db55dc2de3f1ec1d83da12d4030714717074468941facb522b18b06aa4888cc62d44b727e2e5eba82fe3d7b0e39990472295ae18295bf25fdfdd435661a68c6d6b184117069d26b1bc784466c60d5a6caffa241f872bf394576e906e357844f7b6e1acc33658f596093a8c908d0a46568e00fbca34185506e36c7ec3c7ed61f26eadd3284b490037c1c77a5f687dcf958a0845c2caa975c034a85cd9b5aa0d891492b7d9681a26dd2a429dcd6ce962a3adf37bae2e9448725d070859cb28e4bec4ddc983f997683b5ac44352aaa941089c3a7a8ec420919bb734643e81dcee402e4141544cf42d813621d13ffd5839cc6f4a19fb292232415eeb5fcdb4c750091a57d5599cef414c4ac64ab5900a0ce595eb025c5d874e53a9f3140b67d320ecfefc6e6b1791505b101579725f373885ba24cf2eb1897f6d8cb6cfcec676a2c1250f06a94eba42382728866b4d63cedf50f015262274ddb274467842454e2b80d426bd501d37f71fcc0b80b2a0009db33e1c6d2a00938b93209ce4b12f47c7ba46f260fce28a10d48d491acea8875eae60c5e5a7a2fc9b796615926e7c1e536ee1f116a0a623357a059afe7cf304a6b638c80dfc2d29d3646cf60129856a5185b22f533af39c8cded9aad971ed3614835cdde5687995cad8092e02b4f7dba78838e7cb66fb315cc20d2cd3fda2bd15a53b40c3ff4932f040bbc8a2b78f3d8357db140bdc4071c1758e5a1be41b99c3ebe7197d290fa9ce3dc36bb4356014234dc4bcada5ebbe2229e8fe5329d8245e3c38609ea40394e7d9434e750bc786662297a0080945b2bbb2096c75a0883894c493e5ff0da3c8a17fe6f9aef87449ac080aaa34d87128c42ce86daeee5b48f5f9ea3e4f2f924f3ef604d4be6a214e4f40d0a50f0255271e341992215e22ded8bd2dd1cb6a7bdd513bd060c6303e45206972727279c9ec8b6a753b56c6f0062dbbd77e5bd72d6f9c63c203cb501f06e1be0e4b701568be0fe5858dad85539866b69b742ab94f2b7dd717b5c5bbeee230f1c3ff2e202c9cfdbaf729773a0b1e8be4fd798fc50e739b63fae76482243c811973d3c71be065def90d031ce19028a6964ac380366012247165b5854506cc60730077bea26b4149e5fdddd54c1244f24052efd9d97e12842608d55b68cfe7a01e9c5b5c3889454bd580420f789a1c6622750a10b5702c0d6cf3827bcc027b9dd8aed88c4adbb97576c1280c21ba1072903b581319ea6a362c6fef7d7e04b4f65638eddb196130f656d7655c6d45677b037943ee1f1f5ae2e17d6dea9a067116c3fa612dd5f48f8969b077ff22d98c609f72b24b76399e2fe5a4c66f9e1494b07ada99480f2b918a9e4a5c2044d6d1965bca499f1460114bf856f7e93d96ffcf6b182ea8b1a31746227f10d78c046427e85089db3e0a9a96ff42347dbf2d85a9518e74b4ce708f87f8cac25d85109e2e2ea35f2a47dee43e67d409f04841a0c1178fd1097ce9b93a9ce9b81815efa18c98b94eae6acf2cc0239da33e34fe32d53c42618ea367156822254b4da0ec629750f4bc3052d23f69a164d566ece92f160e16c61beb09221ac50f758a7930d1f2dd36c504ec4660079dd03ff445e56ec8eb052a2185c34d96450a1debf0c968d295634392b294ea2e9a03fd67b6a33d82cdec2fe0729b37125b216a12a505651fe1ad68d7546bbc0001d7e8a25d7e67c80a1e72f1a15b925ddff91501686af1800b181a51ca0779b2815ef1d89deb4296d78e146510780b4bd0b8c00ff219a937be7c9516256c00ed3dbd7082d7d08bfca909cf1ac7ed26a59b8dda8812327ead849520f5720ca61fe7687b1897cc8bca41ecff590311a520fe4323245efe370bd9ea6e014484dc10e181d04075624e874e932c318926e61d38f460fae45b7002bd7901bcde28800398723d044e368c21d8b131771d557c5f962b9e9e4fbf80eb4a32bf2f9733e9947ff6a3ab770fcbf592abee82b6c1d07ff2408354e357e2cab1be25bfabf900ca0479776eb0d4a96a8f3e481ce8aec5f41af2ab7d807514e706255855841734e3c5a602b5ccd410652e0cca0ad5f82e9a0c5b36c32e897bf047f6a750f7333270bf334207ee0f4f6c3244198b9d02ec176fd128236ff6c16dcb9de35854b40cd8c405db80ff081d32e27194c5581037bbd530b135c534c15177aad35463335f4f504d1c02493b07e99d24c05b92ea310e1abbfca85ac6baa56000a5aaf3c918239f444253886c0f2dae2ba2918eab790febedc8e92127573dc5ea29ee1bf23bd81467d8a1e822218f483f7ad695e54b59b72cc665df4c4cdee4c69bdaa0b6f5122f2d76eefb4b0cd9881abe631c9131ce46cd1094c62f90c68aa16591749e8ea786942a6233ccbe307581aeea4d464a5dcf3e73f8464984e798ce4879b099c3d5971d1fadbe17eeef41efc6a10c75a977ab4fd8492d31ee12cc3cec3d69affde441ef80a57f7854dbe0599f7e58ea8d8a8dba79117271ad5384fd94328c5436710d83bcdd13bbab7bc713856a5f56febd9e4af33aa0eda684adf2b0ed62b9ed451ef9888afe71795f10c61fb606b5bf673274251814e5d3b945feae0fc9816629ee8a2bbe328bc24b835523d281faed3c41340ddc5114e76db12388b0ade5f6083528115f3a07b3151e9a6a24ce8b71a595ff9ea224fd1435870827e81488bd1209c73ea887d66984074cbeb64c2f114037fd768933a5f531261002dfb6ea3af2cded96c06777f99754b1c916cb6db285e93bc74d017cb11202d47b2d9b1724d177c4a3e0272393af4101896a50f216a1a1d92d3e56b812dd49515415991d073f08fbebd067f68048d1cbf1830729d653fa084222a520eeef2726496ce65d485074b2b12c6916e6b5b5d0fc6b2b1d3b1d368afa2f4ee157daa4925c1b0bb40800b1f5e13c0a38ffb599584a3d96e83908cbf40c61199ddeb7d2d5901ef8826968e068158af5c086a8b23d83a48442ac1fc1a27cda9a5584c83b214c0900bc0eb0aa4cf503d7a436cf18ec1bab98535e72943bb26416aa9fd1c9b8382652db452dde8f33b6d464e8a8b730d33b4e7ab2d8739500b141fe36afe1aab1f57024e67f40180e5d8c13c9b3e8145b664280354a653e1b0ea74df361b0dfad9c5d66cf536f0f789c624171bd36f36b1ba60c543d94c47e03136272dc51a271e65d754a2fe41277bb2b76636839cbfce6cf73fc2adc3d33983e50aff6c5e97b2b3a577e19ca9fda510a92ef0aeb66d737a95cf28e468ee15bb2ea15c9c7d0882218bb73921cfa851e819c81707feefd7df59d4cb3d5ff47ced582e457acb145f314f5f053282c4399477fdb1b2083fc3689de10104e8ad67b837751703e20ea1f41fd31d73dc9a31aefbae4166be6134a1a2fd8f95888635751919efbce21548c7d09dec4201ce3422f9b571caa845b58f17e96668530317ae453fe7eca0ac129047e7e19964615038eede3f0006fcedba5c5db475d385739c5c9dee924664d383c8ab3baa3cf6db394a0168f27f8c261a88f1fa8de346d69fae58bd2983de20ba0e533793dd5de80f4e4f9e24887a1795566619f45e30dbb843462990ec3f3dd98012271d33dba87d4bb438a9acc274168c527bbad499f44d47512cf98ffac93a273fb7fa654e2020ef064ea66636d4558179bafd5522baa106b7673491a0620b52f486c60eb1876e1ba071561cfd904657f592d00caa7bc34625af8aeda52e2796a29b3d81c30e819d964016ba102317fa520b53a2e169a30174ed70d2494c0d6b5194c468065654de36580225370ba6bd4e908f87db97deb4d7aef3cb5e7a46e11fb0edf432863447792970030e5c434c31935d8ae379942ac6b40c6c16f0c24cc9f25d8a6f92defc969323e71f43c74a7ac7a205fb704f0be676c1d8799b1be3c1885495635b31a6370e403f9e2a81a440eba3831395745f92740b57ae21a377da0d709bcfd2d9d4cc11b6dc7d22e92e99fd46d8a2ad383fd433b70b511e8a38f8b1959fbfe79009e09830eb87f3a885da7f6c1ef5e3aac2af2640559496ae4f0392988000442705b4c511315b835b76c1b2c8451d5d13161542688a8316b3067dc11dc5e3e8e2f82eaf3ad2bc0ed66617227299809170653b969317904dbb435360f40e18fc71d14c16476ac0f31ee50e72c90e6a4ea25a99b53d6114e1f9621bd463e0915d11c14dcc392d296f254f8b7ba5bfe0fcf9cd42fb5153b15577743b79dc387586e5044c3937bb5033d97632054c62eb0a262f2d2101a6fa1ca718716cc693e5ee3ac5c9c17c5061de1cb78245ac6427972587114acbf26e05218674e6cf0d3b30fea5afac23db7226c9e2088161bac1f97761c2e049eecda93f5292a42cef728d6508f08874c84632943babe90d8d8bf85f64c19558fc3d7fee5f3b91abb6bd3ac1842bf4942562341eb56f5cc1cb36aee554c5eb75fd7afb97c0aabd903e2396431271b36369f188e4f2c223775e0ffcbfe1d6aa020404e66033e8ae9540aa029de496f355fac16ca6c40a2e741fbc588c504705d2f170e71b2356c8b857984be814d003ba17afcb158ba9336f9301b537560e97315802e64d4593a6dcf503226be2a15be046b93878240556933cf980e3d8ec0284d0a4e60b80dcebf007ecb306105f4767a14fca3833d746ff7d62bfcfec08a79b9164631125fe2933bc6a404dc02475fb35c734300852a9dbe365cef44637049a48f37188baa767b1c08cc206696bf20394400c92770013d533a133843db37506b2d85c9e9545fa106454c364dacecb63b94e46d438209fa09ddecd0337789b5413ec87d374041b50efa93f2ed030adf517157ce9dc5f0d876d5943a593009f0ee78421ad55205646fa1b3ed312f0f10e15d39b741473c07e200eb27ac38212b361f6ca9dc6a79b62f99c4ef379ea89c34f81e05e1205500855d821ca17beb9135d7cd739d5e0cce940f1b3d08cff3a58030323dc2696b8833b05b4f8274275c8b1226a56e149537511e7e8e35c212d0d4776c660187a077afcd3d088ef03820b98b5108fef9743713d9f07c59fb31cab9b8ece1a6a0cfff5d16381cc080a8fbee9eaa07bb36b824ec1cbace6f8954a20ebea4539d48fd06d6354ce9bcec480a6292a37ddd355c10c6fac303a649d36b48c4bae21e93c79ad9032dd33c73fdd8890134364baf51eed9701e4f44d2b7006fa683953d8fc6fc8e8c015bd8ebafbaba44b483ebc68c81434da3a1e8c7be31d75b1553e93f56fb468a4a64b6c782f6d8c010fdfa986e1543da0fe66094ea912c5109fd5096f611958b1f5e6c7bc1c30bd5ef849b55f989bc4b7e6db019ab75f34bd7c61535dd331d9ce64d26f8a0d1abb21bde3a1c01ed9cbe0b915f301ea25e601b83f2cc7e43c37e24c5620c4cf06ff37a3569fcb9b77fb68012ba5a2c7576dfb64c937da127d0d30bde274029dcaa2d34d371a4466a633022130bd00816a7558e721d9b6a842daee193bd391c73a87fa3ff9c24034f6d8998eadefb30321b9c8f0299ebb729f5d2a6c30eff58bad69fe069ded4d7ca9a3374d97eb42e4e6682f9400f71b4b7a54b3ec6508fad275afb5f3a9e6c20d13a4643358420c6ba5da609c387c18c850a4f9676f599b21978db476336ef8ac5e1194947c12ca4d45271f41979b2c46a8845a715278675d068ee1db6ef47ce5927a904df8682611d9c8a426a85e30ca50f7101ca8cbb10f1cd450cb4acd6342d503ddbfd876d4e874fc8c587f0a83b4ef5673efc13ffba497b5d8d60806c81041506ad52445a24713a301a2860c15edf81f80ea95a1af5b27d0b37da363596473513bc1bc90c50c42d0888c1e0c07a8b48a97c27a5fcda09ab0aa281426f127b7a51c7c3bef6f5db6c63d25cd8fa64dc997406dac4c761a37ff27c1a0c3634255089e99ddc575f5944c5ba75868dd26110ea777d451dbe15ec2bc0dc013d2597db6ecf68103c836bed798f7ae0fe366ba11a20007d070b20febebf315862232072d717a86ece1f6120b9d03b87209d4173e5137a30b8144b921a5274047d1b50c584b581d8ebf2aa43e9d431b844f686d262157b5494bacd70b770b9067e9c5267d4299c66e26a9e1e80097b886c0812f4a1c37611c19e415c761e610de1ce5e3326da531cfa37d66a2aebc751b48f5186684f39a9faa3a82e2413e3e5c8ec23bf8ebb81631b92dc68e51d0001d2e2bb376435d87698086ed120c5389432b879c4d7a3f9f08ba3a66ad840973ec7fee32fb294ea237e9969c9198f8d78fec78b151d673450f91f8533018256d123644406da0156d30a42ac3d4e417ae443c24c1238d49eb7f0951331475b6960669dac25d2e3535f8b8247a8970487444e87c202f20caa97acc55ae96f9b07aa882c7b0f0f7bdcf8ef451b1313f0a8c3edd9f0ae2017656c8785573c6128e59823aa265cc6ad95a9435b5d6c1f644e490f086a408306a7ce352a26a0f282c46cbef0d600f488e066742f3d960d0484e1227f21d2a70b132728d65d4984a28d5f34cb19a098463606edc292ad0d0c48e35428ac66fbb518c5d8d4d108856e5f7728598a7f71e4e910ad32a7bb76721d1d11ac7de5bce2529658a1c6fe91838cffd1d0f5407652cfa8fefb7e2c8b7ace97a61cb04b4cf3c481b74a84ded1b9b29f077515f8025f3ae5ea1279100ea1b48ebf076ec12c692be4ee64b58bf504b6bd1ae098d283562eb95a4bcb051c8b540fae2a92ab8b4de707ac4b1e37999cfb1ddc3ba472fa39e8036e6a5490fbe40aeb13b4aaaed94c77890a5722848b648742752c5c83372768be145a24652e4d489b98d29fdfc18c2cbf0623650a234a0cc7640fb403b608848e75b8b7b6cc56406f98ccfe2191774a43d68c77c2d6c32d06d16b2849af2783573494b71843cfc413b42880e179217815f3987086984330e830959af84095cd0c071a2956bfc711f3e0a906a0faf73d6ab9fd2efd4c06c2155d461e4517d47b2417de36186c7a1a6d228fc7bb9548a26d648afc9be300b18ccc7817ea1cd4855699e3b34e16777dd41ced6b6f81c3a67fefab0283f4587e0662afacefba47264239080d9e7feaa8595cc68c7f1a1d8adb9579e5f19e6ad4d232bd04cc9e39fbeadeb2d9407f2571d667a6f7a3f91cfa69d2c1dae5ba7b0c226ec5698cdbf56e9277fc980234fbc28c38c5ed6e98f30ba18fea06166adec319de2f8cd6977a74401d60f9e2f1265b65fda2a47010c7f0a90db84e46a8cf5abbe5e9efcdb9f60464c981d56bd84b352298eade0df26c436368962988425d01c8bcf8cc7663c8041b5d659c53f1bfcf95516abed1c12b5e5ce59a84bcc33a5a7a085d49c96cfc5904535d52118ebe93d01a3c163ddd2aeca952ef1abdf4ea8ff9ed0b49bea90d50473323177133e0eb835530337f29ea6b897ac0abaea7fe405febd91ff4b605384dc7939a635c508c32277c61ab0d4ace857069737e5e39f1936b5fb40d6b2a1b65cfcdef4af5c2b919d9ac012a3512b2f5f4f5fa7e67245334c68fc5edf08be31d8e0cbefd6eb00fb6fcb762cdb006791ac7d18ffa0a007598a3f7c9fc8fb679add714265f5042c5449017ae73337c19818818de7304e30be96c85b73a0728aa24c24ff486ff49c2d49e9972c1a8d7684b7325a9b7088e3fff849d6dbf519ca0ea0da3c817d91146c2623615881811e53304f39c57d47d750751141c06a41432adf84cd7360ea5dc9945684cc18bf96e61b9107bc8af9ec8f31fe37d522eaa99a920c2d19d6e283eef98152565be0d6a84a2c39ebd542935aa096da9ea147376533324b5f4283a61164a1fa42dee436be456d4b226ebaf0ac50424ebace3b591456afb181f8b9f71192ac9ae1e0ec0e4d8a67973aad3caa988698a5eccaf7691cf70c78108a0f2a1f31e3673a30b6f9c06b4087c4d531491abe2510f32772879a4c51ec3d253e2e6df3b5f1642f3832553a15777fef83ad00ca265b1ca2fffb12a8a5971daa01e67feecabbbcf3ce1898a5f375a46876ebbab7a0e26142e7a712a5477d93d7b6cb24b33e0a564089b0dac45f7dc39ff328b3b60d6033d11350933108dbab24b5b0a9fe9532c0df5c85ef1bde89059b241dc6c818c6169907556247c9b1f6e81b2f42f1edade5c92531d2280a3e92e88d74d2654803a38eb6c068254f09ad55b6211edc6f29df67198c7603ca2d20de6723f043eebd762211caf74c940e0c740826a7e0ce48d641b4eda9480163b53fc9ac8dc3908b3fc93e08397b79ac6aa267bd55e1beb683f702348cf1bd5e4603b02435a90647b67d4f38062c0d4209c11840caf4f80ca6f935b4bd5e56d0a7d0884635210723f6d280c2a972eb1ac544e18a1dbe629c5e47398c95320fa0c841f3063489f5fc8dc63811a39ce24dc4ff38218eff2d1133a3a169451ee52dbba96bae11e887f51e9d49bcbeef55633de9bf6afb38124e638454c6b8f557430a23cf36a29f78369a55b17abb2860fb1540acaf56edc38e35e31ca5767a4d492746863c0b2b933405aeb89b143170b3a44ad4a5c05e53d3bea7908d6aa7c211153595263f08459a2865f84f11128d8d25f4bf9bfdb13b36712b319ff7af651a88785ff7afe0fb4a86abee64f471881a81580a248573c8180efa0461b5b10442b247c5306da23237c3aeca8da4336610ae973d0361a13dceacab1a686855172df6dc337ad316cb00a368943252e0e9847b313b354098b69efa89435053046f0c2a07b102a9c8151f68f695ca2b8debdbea506cba55a9dc5bcef09a2f31a2fa341afc58265fad571445a56a6df5ba8b33e4c4ca42672a615d59bf086a55297e8fc9b7ebac8a53db53256b915578834608eee0f0a9c0d84c40cdf2544da5e981050c95c3a496a5a2f02b93be9bdcbfa03194db4ba449e72aec4159b98795bd801b5ace93625a155af90deca25eb6bbd8b720558e43c088dc2742c37a3b2672bbdf612fca783fe5d1abe59e3fef208e085c048edbda89e434b4e3ab927987f955c8dbe1e8bc110c6679a1c6e7face6b6fc8f8b609dd21c12063d3a5f160150ce6b88dc00c102aa7c00c681009e1147e432c395e086fbb08704928e98d110ae8f9994c423f19f2fbb7091394e091f8652fbcd7baea800097485282c249b63a32fb81b64e595c66fe2c15f6c271df746f9079cf3cb6eecf85d0d6d9d05dbb66c4abcd9c308406634d658fa722ac4a033a4a1e785a304e4a4e07bbfeff03cc58ad44e9324ccc88960ff89e1790b30c3dc539d7d825228e8aaaf2f2cbd687ac8f3f40bb0a184f0b5401742b65987d29fd1992572fe76f2070f938b82f45bbe979bdfa5816f2a8edb626b79432a52403970729079e071f553fab573be13e547d0da5931aa4dff3c6caeb439f4b6a271d73253a1583e2ad2ac00d9c18146f8c430a70332782f186322ee7735d30b0b07d2d9d473aada344ed469ff91cf93ecf049c08e1393229fcf3465b114b6ed7dece8db6228c5c3a0127567826e0c44ab41521e4f24b1585e857a3507c5815cb3abac8ebb812638c14836a114706bc821b6bae2f568a189f93c418053a287e6d62a3b8a6443146dc1d6b6ca8e3461a5c5c3fd645c38b8d1faf0fd8600477346175dcf82670128742074b901a8cafa4032018297ebf601c159f6df1b9169f9b64ad6a319d6d83dd629e9f0af2fe98d75f02f9935ad42b00f97e340863ca865f347f84f9e08481c0830253476c8a5b641c65373fe4dc49e6ce079accccfdb9ec92edfffba3877ce89729f258d3b4dca0a2705a2206998c206e80c288cdac0828d97cd87c22afc28a468011f13c43c6c6a7373ab549f2bcb05e1b22ec6aaa8d9495795343ab755557b59689c14574a452ddc0c4b0c38dd22d0bcd02bdf56aadd6556b130b09cbdde8d466881bc2ba2c76dee8d44649872090f8d39eeddefd523adf46e2e9d9968bb69ccdceda21bf7b36c8be4303b888ad882dda1050c4061485fabb8180a08432f675f72092f985cea7c9c6077cf9f2e5004e5f984a1781985b56caefc745b9593b9ef07c8140f27bc63a514a5815976c73c34a00376cb169721d0b9b34ae9e5dc943d731deb885a9e6eddd354c5fb6fc956d74b6b57a932e32c0c6e74be95306f48cee0039881f5058c3cab34b53b0626574ff49fd65e3cb9bc1c60fab67f9703edb7097ad5ce5a4bb752a315abb13e5906cb0df48753be7754c2a381c1728388e092e356eb500a92fb2c079a2868c942635c8c288c4060b345c7c101275240b6394d3ed88db5237206e4960605c88ba8ba0e0a1d8dc5db9eeeee76253ea725dfaf3fb1a5f58afc7e86c3aa21eaaf3b95f75f33523285f2502ae9f8c42923e8312c8a5cfd4d5af7ab1ac7b7d3168fe4a0077feff001a70fd995ae08bdc3a1c85e64e74590f2238bf00255c7f56bd62d09cd20307d897c7bcb97bc41a05c2d6222a23eced6888853169644e5a2aacea46a7db90dbf560e3d8b9c30d89d02871838d4d1921968248e93247088dc919229058f3c6ba766e745a73e6b26e745a03e68660940b48f024b941a4630d169e99a443c21585a4dda995d17431c6bc297d559807c56ffa4989668903ae900983e50b0e462c2d0932248a8b0c608eb268f1a6998ca2f4d4814ee9378874443051b008e304931a0c48d658e9a9034f14331cb1e60531489864f546a73554b0a83502495061e64b1422a46052e256c04d255dbe1061459a327374605202091c2553cd446726410107850a0884214920b18648134fbc90e1c8ea0434244f5f6e4b38718491234a68e55aaea9e176373aada1a179d96e1c24b1521dd49f82e759ff4c79439ec9990d2856eaf6ef58b2a12bfc312fcc67cee73b3fb08325b2fb19a99f67fd4c637abdea0e9128a9a4723a11acf3765c443adfe7d5da59fbc5c8ae8a41fcf18df216b6354839aac10e9604e04a0e28c0b2a40555684e054e116bce4c19a10649237950116b7e7dd4a0ff8e1136e428d01f8ad092fdeb2f6426ca63309fb20d9a90c4869e8d28f66fc84a3cdcdf956491948e6ab5a1eb1f8c1d7f18ec60afc070bb7c6337611b1945a89a95cb7da12bd6068b7a28da88428e028f06fd6fcc60c37aeb21f97f276b073395cccc2ffaf1f50116ee07f8ab43ac106c83267490bf98a532b52630d627f26f80070a2c3d77b9accdd681c3ba2e736af2c2cdc256c161bd6198e5858dcfdde8a466cb125dc76895cf5d3d88717447281dab77cd5f146a568d42fd7ebd827149cfb32d971a2c44b8e639a959c1113720cc10070423465eabf35a3f1e6562a5f4c3bca9e1a16bc1f2dce8a4e628891655e85363b256ae7a102ceceefebabb1d49acd5afcf69094287b276b8cca28adb3fab125380110346079a2582d0a4b9a2092c9a60f1459a2f773e511653b270a7a92e3c698b135c0df3f59938535ece50b9dd2a2a9d7f04e28f92a5fcc4d8f8f546a7334d2e17ce065b6f7442220314e346a72448c8993f7f5028740c850ee297929a9abadd0827c2991d45edd8020805a2a2a2a2a2a24c689083f893d674b1876214d777c487a2a58859b83648b9d97447443418cfc0f02b0a5fd81f6f0f1b3c58fe28c7d6774929a5548a4287055317dc500715446480444a0719635aa031664c8b8c129f192d891771283d649fdf7fe0e1f71a9bcbcee4b6cb3dcfef65607ce8696ed7e90cd2f53897a55412e343e9e4f2c75042b9cc0c67a6b4c4537c4b826293f2230fbde94649bbecdd181f5db831627c3533c58df12dd68e187688bbad87c1dad19230aca072617c0f6b078c180bb29ee761ede8a9dee5f9d6e5b93c2f7be883cb43e67679ca287179aca8e1f29059c1e579cbdac1f3f677583bec8ece0d5b77a7e9ee5471c4dd2133c3ddd9c2d5c498244f4851912a2ab610b1408ecdc10229574a1b53c8b92d59e9c6609e37f6e94f14d612027110c6e84b9829ee1413839829a610e2c29a7081a102004f6a5c53829932e7e492c39cd20037f4bebcf9a2e476532f3a4ee98280af6360030df66701a2c88d59a4c4b17163162950b7c83de9ee719df79d74ef1511002539d66c4651ba34d214421a79c38d4e5da4ae931727b7d90a474590d799e55f6316034054e1d26b54d3871004c3449919ba7881d6021844c66cf1c5cc911358210b63142d42bafd55caf5aeeec6a717647045552d5d83159dfa714a6cb623e240d5ce88a9a1ccca891ad4d8d9c30e1c8a2063060b1a6a51d0291d46a4c375db3ebd6082da73e3930bb7ebddf8e442199a021b85ea7792a5cb552b8c721c477934c80fbeeb095b1c7777b96aedeeee15c85ac17eaebdbfbf5a5dae7eeeebfef9f5bbbb0ff076c7d0ea21f935a67bb7adf496bcc09deff229953e5ed23d96cd97a5eeafe95dff7cbcee941f1692a5df68b07ad0ebcef9ea31a7f5e016a937e25429c202a2104b97ab562ae79c5fbf9bf5e5cdaed5e59a5fe7fc6451839e7c3abf5aebfdc00af5aa5ed58354f87c80d7bfa622b8e7e694523e27a594936b59d70f14b1655dcaebd5659518dc1ab7a83f02b90cc2cacad518ad03a8d950de1e929ef44f36f8d3ddf22c061700b7a8ed0d727e12366543795dcaeb555ef9faf1f83e3ce8cfb8aa4bd3c4b9ea8eacfaa1eac3b0d6bafa42f0aa54aa4ec5b79b7332a5ee2ebbee65f7450fb261a46d6f6f672929a594a33f0db28bd2293f15bcfb634e203ac77cb641e99c94523ae79cf4656dfd19aaeaf51887288dfb6376e1d21d03309e6c949e853f3333ffb8ac27bbe59dde0c5dd7bf8891be627d58f7e10737aab9f5c8a5cf57eeeaabf70945e0521983aa77ebf317feb8f419acf49d999999329dac12b8cb558e525b55602565eae27bcccac9f3fc4ceb3efca0be8b5760283acc4b5798fb22f731762aa694aa2853ea5cdcd161ad56cfe3adbafefe1556e195eb7db873dbfba2f73cb9157cf5c1517d70e80787fba87dade041fdb5391a696cc4330f8e6cfc4e880b6e7ccee0c62f5ccd29a794cdad3be59c73e5f4c6771bb36ce5a01fba38165737f6dcc87df8dd48e3468eda06a5af9c73b08dbea1bd9c235a6b7b28fe18f0dbd5c18511c1fe1068c836d8ce01dbe85cf2c1fb5e04a594cfc1fc6695f0ac1d3282fc0e833188207fbfcb43f04900bad2f5651ae9e247a01dfe5d14eaef1f20988e117eca782d3d76d6891771c48732b3504929b5d511275543f11a62cb9b34337019f28516cf892354e83439011c24b2dca67803c584347ac2a4c6d8798ddc17ba62fc1f7355e75ccd39fdcaef31a5ad3e555beda93ea029d6eb181441202e6c4fe9e473ec39552ad5bb9cafcab4011f3d4394112182fddd4996314a1dfa45cdacda3a3b2a150c54bdf7ea56205011dae3e817a390fc3c462e486deaa40bcbbaf1c9c88633f6c90849f395917b332ee5a453ba198e1a31a5735277fa9452779752bacc74ccd5e7a8648ea24056e94ae2d760ff297b4a970dc629566ea689155c21757c87ee39c70ad6bcf1c9c8c8ea091f7ac6d61b9f8c86dcd03e19b5609b58eec627215ec45a1108232c404817b7bf5a97e5b9f149c81418d5c66f7c1212d53e373e0919c2bbf149481167a500c66270e39310a4285b728f4ef8e3f62b610db16ec4104228b0310b134937ccc274b33081948529eaf64cd6233ecff6289b1f8da8610eca9f2f2ed25cb2f9e27ebee88d342b9befac10b81b3ffaa255d9fce6c83221d61a4ee7450b4c4ae7142c9732117411e82545047716cb5480cd6169c962e360b684063333d7dfd54295ebff44ae3f99800cac133386cbdc18cf3cb1e4d2078152eb51ea5ca4189aa3c39c3672ce5017ede2524ae99b8042c72c06e6e7c978ab9c242c1c8ecaea7100b433934305d672a40c611811ec0651085aa0682147c98fabca5833a2ca81a106db1773429062c983627dc241492284eb46a7253af4ddb18699637c216294bf3cc618dd99741c633002b47284b103b0f98db08735d195deec3a30182ce288eda6232282c1408e39c6586e4119ebf40599af5f68b195d9fd274e0f57479c31d7dff5850f1fa412e18018aa843912450f4a67e864a2e388a726988620ad40ce0d221d1cd3c860658d4ed86b01104cb4408b6b5560430f081c73fb65bfd7564483c54919db1b2f698e8eb09960063169d41c0184ac270fb79f3872db6b49185336048ab18caf17526edcf9dd6a424287bd96675b432cbbb174133774dc8e4c71cb16729c78c3c41b286eff7381c3ed07b92873fb6129b8fd444570b6dcfe119844a72eb2b8dddc94d317b7eed25063c31f737e64d1eb4014fc9e898d3f3fa12ad5e3ffc8d612183f11ff4f516e557926d0c31690fe3748ffa741fa320ec5abfa4a6f64dd1a33eb6e1aa40ea741eab72844a5cd83329863a5cd632da35aae0a7c29eda48ec528a428ad359415dbb32dd4dc1e6f0b319775756e270b89a4f3114dea213abda31bb6926ef8e37399f945f0cb37887eac0084465f47c73aa98398441c337412e7e0226c63488cb59e1281b0075d6f5da1ed263136e36947b9e0c39e72691b71692f71693fc198f2d88c8f8f3c88be4be7c397f1b9bcf27c21c8f330be50e8863cd5f385de0b496cc4399a8768833efd72e9f37ca190fdc2de7269435dfa3a5ff8cd74e97b5fe8fae968ab3feee5b793a2107d1987bcd856d5a9bcca5a3df7e2a041faddca53b156dfafcb3dd820fd400536fcb9f46915ea32151a62ac0e1183f8992ebfcce1b252839cc62a29d91bbdb0a1b15ad0c6d61bfa2d7ab9dd426063e58d5e6e696e5895eeca633edc4799ea6d75b96aeda692c76a103188bfcad295da652c97953c16654b77d66653558a423ec00ea6d2accda63965ed608a5aab4d55a92e49d60358a6ea227df5e8fa4eeb53fa22f8d3fe10f0a5742e4d2a0dc6a9f44267ec173294cb4dbb4f540f2221a922abbeaad4d5a23a5b57eb9a9c757441112fc93e4f8b6895e441f2e7c77801d1612507199018cf022582265b2579ac4b527d21118d6f7d216c46cf17be8ca65fd2951f0c747de1afa4eeb74af218118c2f2482f17c210cecf942d0d5257549577e046c940591d10f23ad9bcfb31b6f389fce9a2e1029f38b5188c3caf33d5fc8b7e7574811078cb74166b3c8b9970ff73cbbdcc37885f4fbc1ddd6d76307f77d20ceb9f443c05dfa13c6abe8d208d8288b320b846732d59107c9973cbbf543fa56c7e5817712cd2fa46f69cf8be77be25fd435ca63f10aa32ea0e6d8c0c5912699fc6af398fc2ae531f975ca63f2ebcd6352be6ae631f92a9ac76298db9426342481a3441732f9aa23b7af14ba586ee1c69d2fac3a5f68595fe8baf5c1d55765916502258236a344d08024608933b2fe7c4e28418cef8fb228e3b62461ab2daa41024845dd27fe315e406a4cc1822e321662fc05329a64313e211298e98469218ecce784068201263ca440d69f0f0fa320321f1e9107902032ff7c7818c9f8193e3c5cbf52e3054a881db63892cd6434c97c4e70202b3029ea181ad0e1899bac3fca7cbe41d9c115351efee2e141f267b83e195f581760c446599401f911c50726ebe00afb3ce4a320bf48fe08928b0917bc3a2eb2182f1a55087124f39278dace1c369f034adda9bf9a73491dc72b0af5108da3864a5346cc16a5a55a13d2ad06bedd647cb1337374caeb79cd36a6eca9a906b9993a88f9cb88e1b0424181a2a4b454e3b8cad1a9525dfaa6d3e0c2d8467cbe7ef9f3212194970370f9dbf93e3aa5cf395b04d27d004e96e5fc504af92c9d03a006230e599b39a7524e29a93be71d5f5128fe74295db2b7810d96dddd57aacad129573d4eb85d4ed54bca393847fdb9e21db8f6224e8be31bdcd04f396e831b2c739556d554adbc96d3d8463b8d73c4dbabce3bcf697ee4489ee4b170f0377f0820c23aed9de634a7396dc5059571fb69389df5063558fed069ab956aa5e334a7d1228e586f3d4874fc9d4ffc20774783dbedf4ed763a8bdbedbc6e5735d0c5186374f9a1bb47f91c859c6bea53baccd1cdcd365c36e76d60438d1cd9dddda3bbbbaa3d19fa3be72e95b75ffd720de46b6ac079f11576163736f88a2a36d3797556e726a592cea9aa9c06773e57e0fa73955fa9aad65a29e56f28052bb66f77c5a3fa0648a4a494ce545760b75679c46167d15d4ae9527293523ab9e61cb17563b32063cc7a5f69ed74efaa5f8e3898d93fc07398fb02408df5bfc995378387d9537532d460c4861bc26a0f56e7c62723435870ce1869a163b29c1750b4e1aad8d514376706a995125a584b58d68d4f33345144b5d576b57ab6956648add6ab4a24adaa8881bb42536931428f7072c40fd53a3161950826424d8933a28814e10838548988c32a11ecc664065b3d9b84511245da2a79e18a0d094d842b4a6f9358796284fbc1eedce8f464568d6c85d379c106ca522cb8247c28e3b900468c0f512b3956dee8e403d40d221d9cc18d4e29a0e243a7f1990ed1102af0181736f47e6ca071dd6b4b12816546856ab39909d2f4541c8a65ca8811b3a5a1a0ae7f33c5588be94ee2870225742dd56ee8e2a31bf2d1974217cb4737cd4da18beda9fb54448bdb3335ae2b7f7a46c4315f3e8d113847bf7c05700e57c451afbc6164e220ce1f1b39d877dd8862e387ae334f44dcdc7eeea7458c2e7ddee96c8ff9cc2ebb841184f3ce9f2cc9de834968225de7ea211f123e1f127c5e6f19d145b662e3139132977bf9d3f6a0df9f2da16ffc199b5542973082705ec997afa45f28e3d7437e3e24b4d7c6d275d3e7940298758d26270906247a5afa8b48134b4925a593e8c63120e160c3410b22513d74caf84424e90987a8d96cd6c2bc2109ae7cfe7c4890ef0cf871b19131c69f9633f31166a418168c4887d7f256373ec140c5ab51274c67b6904b589e050c192b6f909420c34314cb8311aff943144958e1059a2bb3283c30f1c414955b4153b954373ec1b0c415d5f9d031dd88345d91831210495aa497007894299a30496202324ce64c45216752ade361888e4c92a37222e949ae8a4018610115862312861b5cef7aa2c9b9f2c6279a17aea8ee4a5d797da2a1a1a1d5a09744f3a058db4881402deb79ad1fefa6e3c4f2dcf844b33dd1a08039a1d51863951ea368e8e22dc14bb8f4e3084ada7df906117c690367ca93244af410050268982cb9b14521cd74d4b80372a4cc388963648a9099020f3461a58a175b2cb1218b0c5fb2386a294e9852a68a27495394e430511004e9c88a23cc58a142cc16185837782828429bc98616a41336b8205b8b97da583416dd533453ed052180e8b8ca8d8cd41f5e89b5f0839794f2f51ed060f95d081bc5008621cc2c39d2029b1ab6786236f9a0a810e50d95255cc802871fe8947e834887d7f25ee0c1aba9a0e32895afd7df1ed3c7ebcaaec2840faa13a8a60f1a2cf9a10d933654d08491b3720209ad673ea1401a232544ac0891d2504685f185d5f67ca1e5f942579f1972fd2f78795407b943d9f9c277b93c6e929472ab157528efe650d5a1faccf577281e9347ef72590be5aebae6754da76b3b5db31ff21c6b2955ad388e53712b8e6bbba3e3ad62b0565ca792471e934b95e70f8ebbbb9b5b7294f26de94397754e2e5de70bb45e72c983dc996f0d7a936492b5063de49b5cbab11b8623c5d31754d1b42ed21ef8b1020d24a97ae2d5223774a3eb61234192481de4dff19cb1d65a6be5b85a5fd6d5279134e81c07c900c07491571fc579f9cce1d890e35cff304ecf8c82f8d25ebaf9cbed8813a71b1877f79e02e35fdcdd419bbb7b83e959ddf5795fdcdd3dd6e4174ea25372788293e6d3963f9865dbdcdd9b8bbb7b83a1b6b675777f691bac6dd3871f39e1e5051f7ee460dcddbd9d4bdfbacc0d4cfa26a59492caffc12c058fe131b20926a860e128f9a6862f1c65836259894a03656b2fdd42b7e0725a987181f978f978d510724b420b2c460ab8448149ada294ed0708cb911e7cfc74a9de856967c812553051a69767b3999628cfcc941344d95a04c801ea4c4b76971b306c5090b9f1355f1232303284e9eb129b74942cb569b2f9e0400613372ae0c079e65eaa77cf66b3d98ff602ce80324305f4e1924d2ded227f485b2745114836db0fae72f3c7d4c143636aa2a38b941fa5b39855c20c283353e4e56e1a2974b1fcf1f63b730c01f7483133f30db6ccdcfcdcdddddc13c5ccec35a82eeac8d40d5d47acb065be21bd9f99398339967fc9637d7928fc49c18a9dcd34b20613cbddf8cf57a58a55f5f5f501166ead3598585a8389adc1c4fac38ab0a12f71f3adb5f97e35a290bfc7583d449b228ed53b177276eb628a8d141adb98a82fd7bb498aeb2f8be874cd83fc43c7c200d5d3874094794f9fbdead5972e54c58e5074e3c9020922f3de63da8b8d8a6a70b8607343333546ea8b4d8aa8a6eb4e66d7df8943f11f5ca9872815a38ed5f6197b7b17d96006bbe431ef5d7e91c7a26fc063acf7da7d2efebe468d1a356a5c07fb55af9e19c164528744a7427ff72b46232c1f7154cc9f7f048fc967368a353ec23159acf151acf151acf151acf151acf151acf15151e5e841f13ff6ac83e2532d5c2873e6726c581fd1a4a410534af95ee84d224a79705f000ff2c1c70565a4f4966cd0b6e83b8d3c6107ee943c3cd7461cd1eba1187dae0f09e1bc31c68d9f8f9677d1c5558cd50e8ab6e7f6dca266e6001ba9ebdd5555bf63ce008d9556644d5a514135a85231775dd7755d77c7bcfab65c476375fcfbe51746840d5b2a84216c6859ca97e47be850508842fefe491e780e411ebc8266bc7866449b920ef2964a2106794b5d8771c54ea959a687a67a887b9f3f2463441ec41425e5b6ebbeea3e9f137680942076017af53fe4ed0657af273e26ec7cd7aceed1b10826ec7ccf4360e77b7ec8db7d61aff8d561a0417f14c4d830da747ee777be121475b13a1f651d4ea9160cb6691493f7ac8f2c08f83c80653d6f3fb220603f9f07b06ce73dc89b1aec91561af4e779cd290ff267bde6ed459b6854832e99ae77ef7c73014e2c95b9e4a375a11a7c9b982d52ab59a6419f5353aa41ef19c2aa3e9c52d77ffe40a9b81e6faa9733f590bf37f550d8b3abf3fe34fc89faa778542a3b03caac690d366d248d44a5baee39d26fac78e1c209738c31b21785fa6978f1828abcd18b174a6fb47883c18d5edc2c69ddf8f4025317bdd83c5bb800513f2c3113db3ad6329a94142933d043ed3caf787b5e3c2f593b78deeb1181837185ddf9f83a8f815abbf6982582fd1ecd7d2980a1dc7bfd623df762bd7392c7663cc7f8c2dafa420be34b8a41aa6715cf222b04fbaa9e22ef91dfd9977fbcaa679fdf79f9d48f977e1496f531948f931a74d22073121bf18c691d00c133feea2db161b52deb9c0fc7f51033cfcb34cc2ef316fee132f77033d762d8c8590c68369a91c0d12ef79167023d886930de10b0cf0918c8d00392a4994cc6cbf85890f132de0046b5db710630aa5d7f0318d52efbf7646600a39a8c05199f14fa52b80f7265bca4d0bff4f311009a035ab704dee1f6f744c633eb046e92c93841c65ff0177c2570bd8cef828f32679920e35da08ccfe541323ab802944134c2052f1ecccf4abcc4490ca5e399400f454d811e8a7f8bd1360d0b39b2e24856dfe517b6bbbbbbf44944e316c55ba2bb17f3918202d543f1e968899798a97f4a9f3204893848f0398104aaafeed5955cf54db399ea832716043ff0c182a0c74aa08aa9be1f4634e433a514b7bf9d046febe4f6d71709549f8f777024be605bd6f5acc44bce506eac2d7e4c9e24fc6c366b2d5d040a5947b5688d0d6b104a11077d1b96a82b97bba62a97bf436a70c7d3d1ec2259ea21a51e8a4f466e547aa8addc340d2a3538a9f8844943a5b62b0d06443aa9ab7535aeab819ce4645b49099d54a920796c2a4d246fa506b90337b62e35a8d4e00d276ce8533eb12ad51cc983aae4a6cb7de1bc1cdf2e72ae66f3aad445b9aa6bbafc0730b2306e7c3a3ae23bbb61a57200176cd8d55834560c1107f7dc74c3ee5e5e854bb10d7ebf451c53290a1d451c6c626c0611839887279c4a019ed7a8e4cd76453d08d194080000040053150000280c0a8803028148281eecb2ec1e14800d74943e6e50329807834990a2280a628c3186180008004419420c414e8d19002b6ffe96dd366308b7e0542bea00911b6f4a9d2a721caad2a02ca8931ab28a17b8520b958855a51a0c0889dbc7cc05e52407378edea7700f5446d8dcf6726242147f173f4bb72710a0783875a5618fa06553a6e9e68cb8e1f95ffc13e0de5152efb9bc48b703294ca44718f9804289730af3561d31f6fafca85f049a979ccea4130470a8a72384226c83519a9379ff962613dffba8cb0032a9cb871582288843a64b71d6edbbed61c90cd2715a32029dab2dc14581a71d2b4a7286949ced4d7d98be86bc8c23ffc36c53c62182ac190120921218a0cb3ed553f38863f9434c34ccd0f3d7595ac5a0666d61c6a709ae25161145478eea5fcff02ef99b443d8de2450477c089a62f1edfd76d7701433ea3ad3c509851d5c013dc3a32c52125149fbf27d4b8aa0be73fa23b9cfc028b781089a51e3913d89fc790732c1a0633fc4e839164b4032f797cf40a34e5ce31402f279d8b6d85e32d6a68efc00c8b4ba1896fb669801ab1e07a917f99a91a64ff4fc8bd73d3e863fa4de335c7c7856f14737f8892cfdea535c5b7e7b528b7bf6472ad1e8eb37813fe995957a41a0ededae4f8f5103446e05e1415508f0f7f5cd703554246ee3bf1b278192ef728ff5e81472febaa9d8882a77661e77dbe3d688772ec01808f280bc40497581e20431f67ca5361589f252e0c21845b97f13e8bd521d563471d94c1a2d7d3074a11151f1e714731a0bdb7e0eb2d9c9dc45d584bbea2c09a138f356efa38b0c3e07dd65e5e383154f13076a99d6fb55f75e0b650dc4c5a8a8b260b3243f44c42e2686edd49d8194ca63913d8e71a540bb4b7d5015fce312d4658e80bd78cafe86e56b9ae7731dc50eecb28d7edf8cbb20711d19a4bf691b8b705bf967c9ba8749d896c6a0ea87b93e7a55e927b1b4424c3c29d96da881ac72d2b9ebb65ed00e3f6ab218921582f92c9a32ee0735b83dbfe89543c030831f3d92c9bdd7c477934f280cb05e435c823f88c35cd6b7bbca76302be556261cb4078f1e1bf0e4abf4b155d0648d7db4ea2106ea3ba418896c60d3e7d2fce39ba77e825737d33755ca203a3160f504e5e735129f919ab7eecdcb56eee67ce26753c40b4205f594098c2d3df2aca420e8c8b8df2888642939e068dbdf39e5f1b1c7330102303f92ee3448712bce11bb49a879b1776bf52190788f8b50322049a34a57791f558e96a94c7453be9e2ab28c0aae630108752be724c1919104d993cbf3a29232773f75059d444ab3bfd545b86b8d3e5b350a6efe2b953dec4a7adc7d5b58f345aa412293082d8a1c9aaf5570e48abf28e3f87260d57b332cd1f75bbc08646ce8a82c89674a99101115eed65e3060a6441b81e503ecfa54fdd18363bd2e43876c9ca70166fed2d5f0f2c67a81b9fe2e749863fa44db694159e1e56569c09ed311411753577dcb968140b24a64192287ba961f95cf64ac458840f52bd7c5339434ad5ad45f3b13982e128a338fca3c827221ac96237181bd7fc7894167b24ac751725b652c7526e0d6bc279e38014b34550636ae4765802ac6f113e342b8b89b4356cf22116dbd8b107223840929557f5583a642d597c70b4fa8f32b455113057f7c5d8e31b530fdf2d3fd6b61e0a0e2574899465a0b688a36e7bea870995e043c56a6a4da97f54eceeb13eb389445dcdcde6a606158159c9034ae0160e5062639af61db38ba6a3486cb39305d9e4466ff473dad28e2532fadf231b916e75030242106c79ed00265bde556f67caf2cd2de85cbf527c90ad8bcf322a854384e159b29ef225c55aa9bfa25b8f83a7157fb682fbda26d27f6c655496a9f594f350f0a05a9267b54514a9db7cda94d553e44013c7bc80e37e82584736b50bf2654956ba640e7007aeb6b3e7db161a89f3fc1a973fb105a28f45faebbb3302a286b8108423d79b19d96231001a8f91d5214eeb7a9b1db703209e18456287fc457b10b940dc810e98624a37355296d0be7caf41a0f1edd5f74bcc21c2398b6479cd7078bb3230cb419d1165418d1304dbe386ddd61f996cdbc061a4c41cb4b1934fc500a8cb3ec2042b1b53be17d325e628e6289a0809022e0687d6a5a2e9ee5e5619cfe96a0f46c9eae1428d122c1915c51cb80f2e7e89485834ea09554cdf522a186b7fdde65a8a92b55ed219d3367a010c1ccc054e9e23a959943b7b73cf6b32f80229845f95dd9d7ee4da322917fb543a630c675b3d3f5b70d4328631350d1c3b89b467e5d9843d9dc6d813034ae5b74dfaec2e2da651d8b1cd4016da9d010d3ccf682f9d3868403d52ce689a182ece2f87e30c0ddb8fe3e71ec17a1f31d3783877d6e02cca69c77fe1f38d77e079d210b44a9bfa18a7fe7d8e18381d51e1ef126b6f843a5291095d4f978a1a64716b30d85f6af528fbf2fa3c76087d371ad84cd9331e1bb8759536ee6d5466605ff61b52a21b7722cb84f737816f153b696509458c07058015e910763af3de3c44e2c12e475e19e3a2b8cca0643bcb9fe9355de035c09e7a96316331c27208b8c4024f12d41187722ae264467e9c07a054ab6451a82c8242602af397031754fb09afd78eb5b4ee5d49a1271f0273d40ed39abf6a67c3ce32149a181226716ec741dc6acfa4d928038c67a0bec1eb219e13b7640b17723ab02f14906a988d43cab1449977bc181a98012cfb445a801fa77b98e5e800b81f472fa89547c18c9e8e1f39f64767d09073f9972b1b19b6146792e418756b8249d941708a494b2010553f04220a5a4ce8362870e3a9ffe068a631a2a60b2cfd1ccc0ffc88ef9d0177fe79a73569a01c8e9fca29ff09c391b27690f0744b20088243894d5a71549553ac5e15c503c170625e60ab9ce6360ff19513006234e41daae9d0875b41366cdfa7b979b428644e353ab3c3f246d1644633c2db4eba3e852c4aed1a7acfd287ad0f79f01207896f8f442f7f3a8fc23ddc76ee71429aa4a11c1cc16a1f5e551164f6aa204f2283debb9eebd85d3d3a7cd37c163bac559ef50e85b252e3e6287b308b0c3dd038897293d2a9268f2e9993389475e4afc45b1cb231248f5823356e50901049d5fe82a8e19d36cf40bb155344ec4d8e15dcfbb0a5951bb8adb16e3cee0c7d663c83dad3b53c2a6bdd7f698a541ba6e353b4c5d36835143ffd3d0d58f59d79075b18cff7e13db86d12d0c2e1a75a70eebc206ced5f21af8f82682aa45fcd5d32fae54501b1a13c99d2991f8bf76d5908927f35bd3b245b09f9a1dce48071a9437fd557568600bfe9437cf97b5dfef6f8cfa76683741bad84d5c0a34b74bd6648cd7c3a42d9529b782add61bb6c5c04f05b5ef39d41e3e0f9cf8d7b0f7891d8015c38b7ff951e9af614bb2ce51bcaeb058d0228790922a39f5db685162891582da6a79e95e38c9c6a94b8cfa21581cb8849d8b253ef64be50387666d753a1a96f007040b4eb52a4b10f0e75deea8ea7468a322e57887c818367423a6542ea2eb4d08afcb8e173ebea1c14eef57881a6ce796537e4b45d60390dc9d73f4a5b66cbda214b26b3792dde1c64b74dcd55934a41d2d42eb12ec24b5bb37bc72ee4ae1646e109fc43367183b2c2f967974f96b8ebad1f0ad020d94129c41db8ae055acf85f334cfaa571ce61780ef09af57b875831f485cf1708e4ef8d1befd9055ab509cd96623a6df7ce5ee901d44177cb0cc0f433c9098d680029db5402675a29b9504f58f6a8603457530be70f40ad26c6b5a13314bfcd344dcdced5327022d133bccc9859480f09375c2a1f12c9f5e8afe45a5f4362fb985c4c2939a288d7f992e8e36f0221028c2a09666264fe8ea004e48167fdd932800fe915258d0249441c61471808f0ba7b830e3943fc5e905daa2379d4f0582963fe4802b4661fb1ca14092a8335d26e40289ad81a43707cadcbe3a6ad0a0f0f352a482186628c13065df25b73d28986130a1d35733f9510d57fe540be232c23de91fb76db2ba4f85d456c2487080604f74e3fddd7c955e1f5353f41a30ecaa3a6bd8126b29605f749178a290b94548b35c0af93110ed3cbc5bbb4870115b6af7f7bf4a768be2de97ab3951aee9fdb78bc615deb5b10b792872aa74074c286e20e33f901d33c03e9305d17698040e379e4487f228a75c241e58648038483569bcf5910fb923403310a39cef236740ce07c87105ec26f7d13113de2103d48f85570252a4fae88667030618f15283d26fcbdef3a6417597895eb88b789db58d091c764bcfab0ad377e6fa558e19df125c4322058377c8ca82307068485bd4f6d790497b6f512b487db18249ce3b41cc8c656ee4f774d1470634102a6fc3261875701c4f04390c14cac4d6422ddc7e23a4c4b23151d1850e1ced1173d913898d4bc234f068d6a964e2e2b0a852039ee09072919ec733eeb3f79e452b9b94dc3ba817a747d46aefb0a7ee6946dc2c12b149f1d056dbfbf8b3b108b0f52af1390d3a86c4e5df60c7172f089580a8d45b933ea6e63c9896d965528112b6cca690ecdc6dc4eb46cd627354bdab7def42f45f8f2ad9e6adf4d5c5a493697b5793ff09256493f9730840d63b38e744346b48f1f1a996d7c9dc3b99560ec9811768f9e4b35b050165aece14673e26534bfb194494fe0eb2c679441482e9d7dcdf70e4ad538a54c20b2219afcaa504027c82d9959e6c0ae9d853148a725129908a8fb79cd1882a157bc9826ba1a646c51366cc9eff3b9b4e5652f3827b710cac3cae0b09713d5fe439deae3a91b731b888fb72328c38047d8d1b025fcd5409135c663bd11a823f879c639054ee204347b557646e840d294948472e5f909dffe1e35e7072c4a89e5326391e9daae7764b25ddd255a64de30c3b884487f81555c4df4f6036c90d09942dbe8a88affe175b2c84386eb764ecf4b52dbf587bed8dff3fd61da7fd8b4627462ce2c6aa9a179938071759e4722592333790e93820278b50817627710184e7652c97b74e8f6df5f1f12077ee67e632fe775ef1847e5de9446251f95a8d2d0a621ce165905eeee83109c1178ea413049fd2192ff99c89e2d4eac357103952892459092e7f51369e5c53192811b37c9f917beac07b83f2bdbb765b584305603702bd32473c175d49e914f16b64cb18ce7650b7c24a8df26c848b607d2f9b5254f8ace4f85ae63c62608609cdc853b9dd567f82034c3475bbf56b48d2a457bde05ec962e545030d17e6a822cf5ed0360e53da0c18b46c145f55cace37b6419001c7a769fc8191889b32a1f3344c9503781d20435219cb740c254519c1bbb9a28cc73d4e109c69956b32bc83ee7dbe1095ecb58c58c3ec4584a69bad8d50baeaca2e33a895b71ba334e8aceca0e1ab69beb31c14356baf492c8a6f2bb3f8de475d851231140c98f2493cd333602a35076e88d812c860ee48a00c22005bbf8dd5a6cd8cfa8af51ddcc9a658370ddb117aa29e722ecd1f632c24880f07e0cda0c14ffa88b212e0ae1326adf05bd6698a43f18a211ba60c00f5929ec5fd4fab264398a20b2d4f2fdadef1f91e6766c299e95709a01438f46bb68000bf8cb0c926a3170a8032b3384ed7811816f35614451faee63faa539c1b4f719478a03f366c23e6445a0c823a5a605661912a2fc4f3460ac5c5cb8497a6a028e20441f6e67300ceb16762934552429ff632739ffb3598042dd42749b6b6302564bc2cc6fca45b5705d618ab4cccb1b24137bd0ca9d3184dcc8daddfcba25f4b1dfa9e6889d53cf527213d39c7223cb186f9930896cc711330e3653710baf72be854e558f694b79b371b191616275a347109cc9cc2f7a0564c0637c14a6885aa0868fcf4c1cd695ce26fab2844b37e9449081dab3afc6a2d41239a69f4a9e7662c26fb89bee61d70875fff535e54529b8bef447d7b31ed10a4a81a41de6b26319e8ed5d6b890be38a6a5337ff147b46ee24323c00cf1ae97bbf6c859e334261f99d40901266524fc5c460f0263a80317948a73f5444174cadb63e121c8ab99afa0a22878f2be100a27a9e5a995aa4bd0595afc9362abb2e667da4839e8793e5cc992f31fbef97f514e976777851c66c341a1d979f254e6d9dc61701c5a71c249f7a196eb78cb5cdf23615e6c8048a43211219f72821939a4a5b13ce1e664a82d1586af1627c57611c085cdb6443691cb25f8600d7b3a8c129826dfa32aa4a342def976c29496c68b2abfc72e4338ff41a20ddc01084999ecf08f8324b51da06ecb745f32d48460d613b15de86d0efcb46a8da0f7aded379279d6780cf797207ac3b7a99043586b02969aae45196587181053f31a2cdf2786101943a748dab337ead0b11456704041e20dbfa4a46d4f7604f2c6531c111f42e88d098edf1c2200400d13713c57dc48666c4ca700fc16b4fdc55d2ad004d1aca68930e0eae1f6d11c59d497fbb20ea7228630f78522a44f14dfd275d902d3ab6675d85b944e9ecbd55c0a7c8c019fadbfbc130abb18d7b1870038593d95aeb643841cf30ccce555709e18bf557a1f9594dea329eebd1845e9be06d6369b3e41b12500875a7b6fb059ebffae523a56646ca18258e54a741e421ce3c072fc7d0b26daa72aa19328dd18d0d588ded39d2a43422edf2be80394033328604647892d24fc904539d4c9a8dc2f49603730228b8363ff36e5890cdf5963350aaef9304b35ca0020137cd92043b20c9359f023f06b846b0443a47e7c6294c32287941865356ae99c1438af40d46e9ced229b54670a909fa244999788d34c54c3fa59a6a9c5fcc0b0ba6d9a9b725f0ae568bfcd7997c031f1ad5d87678d4e46083402428a2e215db47380e2e1b5c3648d54b334cb8dafd6bcd43d2a99e9f2f2588ccd2551acb947ce58a1ba1d89b2c644a23808a691c010d896f728bc8d04218542879750e07ee2063769de0e60d8759e5a721667c1f5e403e61ce181e1338159f0cde78e5cf209501b01c8a00cbefcbd1351c6a056c9ac6826a9a746e7918a642f801d8d58228712fff43b4430dd5a9c93297b7868b10eff9609283e83b913b46a45490786e5b5e2cc895c3961c2079db6ad2cdb0679437446abe7129c123b1e8513eabc9f611e337cd6a601ac205c94b646b26683364b7d1a68ee0e61919a950b10af2a61ac07aafba21764685638501366194aa5c93c394f239cf9e122485ce0cbb6369e85ba5093ab1ac769daf3e59b08b53611d39b51e80382688163eb5fb4237a8f6af1f56d62734609ec087eeb7fada50890e150ea20220745a6d0d8e80361400bc2edb42a518873e49fbc49fa1e7e981547c0ee12822b4b5873ae53d681d661b11f09e15ed8a14a4779c037f670012e05fb6e68aadae34ec3562962b5601e1024ef011b77c10ade384739aa8debe19fc651728d68017dd6b88e13396e1c819f992122bdf3571fadcbadbc4eebe7e3abcc7b3b215fa6e37c1383c226f1530f7be2dc42e144c03109fb161ac46e8808204c3566a7321a9de1d3cfe8f4bd6ac8fffd4c06f5b5df8b2b79e7fd638d41b2bc5232643e23dad50b1d68a3e78e9373537f74b428cf062e7a8127777f0fac4f38cf4c5c7dbabe9062598960d7c310e9f730beafb9c38159ca9ce2d052d6c33a05c32f9015807743a978e58b000940e92405325f44a77df78cbcd715d28c9bd3c27b120f27e32d0c434658588ea61686ef22573022643ea32264800814655a8f90f9f8c6275c4fa7b6bb30747cc8afe0a534d7ce6f5c77246d0802fc7d2309d4a2b660ecb529aab3c6682bee9428b07a52b7b0d4b77a415aaca53ae84e89ac28a5d512efbf3c045a699b44293dbf043e45bb18d517154c25824a87f38ac413511c0e5bd321db836c18637777436147b20e066eefb8f137c602478271e90d32c10c9d32764dc9d249628efe5ca13dc1446f683d920700a584a44c7ea601f9960315ad3223086b184fbbdb212f95565861a515540695155bdee0a03651e8f668a4bc67067a75eaff6312b0d3d8f483703ce93f7e20907174d0f01ef2f12c55925a78a5036eef6b6130817ef46c96e93a11e483e59a1b4c5c20ea5da579db0387ed2fbd520595c7340ad2904d60d901f4c5c4dce31c9fc5c314834a31602af3f2bc2c00e791a1239540752698a2b7e5f7fdaf8376bb9563fc26acf68e3efcaa5a90f5a0cd32a92334107cb4fed38a23d1e395e6b4ebc14f85ea3d6dfe31157a6f853a5a11932fd81154225a422cc59f9a6a49f59042452ae669b0d1a766fda5ba922d494a5f0527024a07aba889a5b9df0fa13e5b73440da1110f3bccdc532f6e281acc9d1c3bb92db8a74658de3838854582aab148772337e0a85fe8f02caf12207b9526a9ca883ff5ad1371cb12bdb18ba721d9cf18493241e0305751add0c2fc496de57e7b8bd74d7170055a1c9ddac2a0bf19c3ba2de8143a43c7eb8ed38697d166586f1238a12b80aa7760fa0b585cf43bff6eb6de70cede5acbea68fdb8c18277b7e8930787da8d4ef848c59c8e5735e2f6bb68aa84cfecc98d629e58a19d6108913cb00716c75be6bfe0008c59faeda71a46fdbfc739e529fc24c72b742c5b447c4c33508f8770afbaecf1de6753c6f7acfebf367995487e579feb8ee23b26909fc7f8a86d42c387cb48510cdd2f2a0a071e8ad89a084834e496e4a9a7c4349bffe221ba2916a2cf1846024c401b54993cf5e84efa39302ea73055e05a88b80412702cd4c2efd76a90c9d9317e0092146c8d558efbb1bbe32836009ea5889b82ca488599c19131985c6a5ff6860d32bc370ab8c644b618c5443910f89f8cc8caa6b0767afb4fbf78bc1b5ff4b3d1d5aa2fa12bc5f65fc4541015ee49c716b3a264661fca78764f06d5c8a764f03c43a9e7d24f754209bfe6abec5c61130b2f101c1bf61495933fd092ae20ff2b442d5a424c937db6a1a77a790a86188bebc9c0eeab58c48740ebe59837c0ffa69d384d2647800373015e8f8451291042177adaba9db68aef15d70c1f3836428f75f99024398afb597ccc95b15b4aa424a35d9a930471def1bf9f1252f1e9410095ef581d0b733856b2edc26af1995fdfc97e1505ffae5f8cdd6aba800e98b6c445d979119b4d9f57340a70fe8ef6d0d1f3eee13bcf67a7196174bd72f424145dcb8449a76f01d12f4ba07b4a8b018f1164e470148a5fd49bae69dbeeb13dd944a03c8dc3342976eb0b695dc613d1a871e5cc72b5bd9476e5d438d82d78b377ea7ad3e7654a4bf53749379664e5d3434a8de87987ab5b4614cef84cacd4cadde07293676b8f33cd27742ed3c01c6f414b0ec538d3e11963e2dce9ac1ea25f705e9385b6a95b93fb2142dbbb0c6a912263c2bb5bae11b4a1c74a25da2c589ef37aa949bca8c73fa04466e17f1430395dcc3b79e523304a6b4646c5b80784a745102fba2031b81f6fc6966bea82aa5fe38ce5fca8bf7233002f138d81f721a363819e42b8f938a2c2d1af698bcc4832624c49c37ece1140ca79004f9554fe61827ab4c2ae9eb096927f9eef915bd929777fd80f5b107122ced0ead8b2ab00713cc9c02564959a482ee69d9b4da61d8c97b87f2dc43fdd117f21638ab12199d8857f93f738d20dcc164f5fbd60ac1f0595ff9e5999950bcfaab583a1ff7f4899aa500664a219540f3206b7d3f48328520406e93bd4885bd13c18f2d3849a934082344767d9a3841e52d52a052191c6cc33ec560d6d657461f488e011297ef4175559894d5bba8a292b2b6374de315cc2822120886e03f2be469dacf9d4c7bd2e6b77c3768bbdc8300005413974a6ab5f97166a9c05dd7bdb08da8180d62af6b611a10fbf6b406c50c20636a1c9fdff8fa46bde080640021c3fc064b0275b84bc56b59d4575d746469f3279d8fd1c43a5e7ca2fa4cbdabd87657223a6e810d4339ce9f170799812904fb307b611144679bc7ec94d84563c8989361fd27afdf13b5b338273684c655bbd5a55a1a02de94673c811a7ec5be2f72e27d8dc8ae037175fb62e7b4a045c6fc6c76d958b2225abfcc8bc362a20a52d8d6f2a5789e34c288fb531bac4eec7aa096290d5a941f01b2d10fb5734cffc037ab0c7af9ae4522c7fa7e101348ddf9989c79a3bf6fea4559202c30c36de64908e8ade04b734b83af4c4b220e182b23e518124290515987553ba340f660af9ad26ed49c891a245828cedbb34652f491e10f400818239a96dd3309acebed7b5f40ce8e39339fe8bfda6255c088543bdd833560cdd3df6e6b72eebec6d239409372ab8ee9466be0af8d34a062602c4d9b1f7f40a57e380e582ccaafc9dd9440e83a7eb3e782887280439e47089e6c96ae51e9706939e6e791951f2609a96c5e68a276c65d3497cbff2e95bf043ce2dcac9de256d53ccc1c461fa1b95b6c0cfe4c1c2984373b9313553fcb740ef60403d56fa397a890a393031655e41eb5a659a082e2d544bc02292aa2166e0282c18b7df7e31413ec4dbf7f2a9f7f7dd9d65d57145ee3626f5f5344153c7168a58aaea03e0be4908b79e9e841634d5514ff31d8bd7d46597e16eca8346b939118002cd1efc5a9c56c45858851c3c3701592eadad23a685f354c7222920115873ce281daa85fe28014fbb0d5e2edc60bb111698b50e70c025cbe0f0134ebd1e8af4c49796787f945c5ae369d6450b8d6efcfed75c23287e1ca411e64e0589766ea50a87ddda36b5e06782d830ccb5086c3b6c0abb0e1a888fe8706a8577108b981e33f7e1fe131bcdbc0a01868dacd5aaab9d80438085fa09bad6413a57608db69bf223541fc3570bb79d2d1a6b9a9df61439afc58eedfcc5e45d6195ac340f0a9913680c159ba99c15668c48fe85c4ac225d0db95f853b1efac337e5f495d5d1fcb7bb0644ef84d51ce585355a2ab0f9a46d3ee94760143b4e56dceb8b82bd081382489590cbad298306ac3a268127e2825723088d171356e06d1759a92b8ca56a9a3e1dc6f23f8b672c8a593115b4ff380cd7c7569f78759bf2c09433c7ebab42331d24441a1aee860d7c2d6575bdf4981ff472769c7a39c416e60772845e14135bc1ad7414dd2f2858e94335780b4dfcef927ea8589a276c13174d5c189d441045377aa37565c201684ccfb87f61feb2036f7bf0694396aec3fcf10b288afeeda663328a025d8ade1db83af919104a8c965e109d7c639cf74b15ea1ccc8f68bca64cab2597bc8152fea044d19318544719e25e85f68b7e36234fe8513bba44362429c787d25174d4b9e207794bc79d4fa413def4508d58a51ef075f720850e45abc0ab362ad8849c93508d5d1d0cd24c78fa3e2614122d7178b0496fc467683679aff787022c7b0f9e27033d297c414aa2fe8319dcc89a75608a5e9a4e4c1cdb81ab4b2779f41d0de5f191639dd87add8a3a752c010870a0e137d9ccab1d056e4aa6945627ba498bed3c0ec31dd63879d0b36045840b327a6803cc513358511bd7345911877c7c75e1618ba28c2f0745df3a248b568854b413e12c949aacbc7801a1e23850dffd4689a59fbd1bb359638f48cd63f16a0c2221d68df512cbfe46508b3b76b31f979fd9be47722923525744640e3b1b68bc661ce2766ab36dff90a64d849576109d2dc8a39fa5f7f40f93818f7fafdd07d4e93f8b169023498dd6ff8dee9b7853a71eb452dfc83b91faa1d5ed0a72d253a395a706aa0ecdc1441e6a6dbcef306823132d0ac11e354759ae373f7e7cfb3b2ea8d3c28a3d061d618fae39420255bfef9653ea62dd6f511b89ae33319c1875f4a4c02b94843e222bba6c2980cfcfd88de734facbe060b03b7a3092c2e295ba3677a5d5f80575c939108197872d86bdb208e63333588f8603b0587cb5e77e8799b2d5ba774e12435e0adb9e560fd85469ef3d54a6dba0439b0f10bfb9b7627a272e48d5774a8b04b9540bb3c1752b81afb77fde6900922c8f317b70a5b84b70568b9634b8f0dd3cda8e8d79e8a8291e91c462cfbc9626b9a006f49a7e65437c6797e54426cdc97408327fd60fd6a82e7e5605393225ebd9a58acc8f8f05bc57473326855020bc392f572f32e92d5a913fc199056785db7a691691fd14bdd201025964b758790148f7401a238a022fe0cdfda3e9e88ed2a1c3d314bec8724974ee38027bcf672e4f1c09ddc28ea5f93141f7c9f9e67c11dbdafb64f0e3cc3e1885ae47ed5aee202b06a3709066efb4e2916838195e19bb25c928a59555a4d1ea4417ce0979d30ab237e1d305e89997ad9a550742f42550d7968c952728287c30def7dd255039a275438cbf103e12e319a3595211e9106dcc5deba482231662c2e9ba112d992cff6be7db01ae1c226eb62b9061f5357b677d4ae7a96b8a0b1ac683cc6e06f350d66b9c5cecf3e4810e38e0e5ec8e2850dbcda0a9608e4c36011020955ca87d2b9b68e6ce354a2dbc1c7883c8de0bbbc574efd896df50d2db22f8a60135102592c1dca8a21ed6c55341e361d55996f45befc28b3db5f7fdd49c1ebb53177706d2934992a7a1fb1eb6f76ded7b1c3d457cc54072457cd287aba206d26707423099cbb54f299b23582a3548ac5e2fd24d944b6c1c94609a52839c9ee1b5e35250319270c6d0e70a34c2f18f2e8d570cd8354c7199c32f8ee12dda25dcfb570b3bc6ef6d9be93a9530b9406b5e022563596e88d2bdddd4a6e7dddd8c79366f55ed53ac61a9da7132592ec62af9742bc41d094b5913c8dc94956229972591121f0169357d541c702809e49e3854780a8bcd8b6cbe974fc95cc9ad8a57fba907bfbf20288c8f6ebb26953a5058467cc039d334a9efcd32664b52a18939f5e934a4c765e8e947749ba1f9493f3fa65fed1e8ba941de773e34987c3ebaf636b965bf48c5ccf9cc36fdcedfa62ac2694d91646703bf1df585a7bcc9df5e69d282f41aeee2ffb811776e871a6d49a7bb3a1876008e81a9b7ad43a8e8575bf10608cf4790d92255485da3c00d420be4b8d26e1f31c10f98d9526d555f2d2b98e6abbd1a4f91c545dbc2390ecc0df569907f4207dab4b9c7c6c8a54e72aeb568c43a20f91e7575ea612b2dfb5652c2f26f9d22547189b99312751122b00526ca5aa36c05e9f3783a0f0ade44437347fda1c2f303728c706de0f68b26f7ecb47c5714788e4360645fe92124e2503a18d382ab42ae586ef1c20fbebc8230814998493284f18f41e7f08039f26da494ad9add42d0719c549ce704cb4a6c7149068d1de6bce994c32579053e846354a2a7c70faece448ffe0eeef68fd65f6a35eeaa88eac4a234c079990bdb48de76936ae23706344a89992988fdb6bb240aee2a81e5f00ce1b69b2d04048eaedbd22fea7798c400d0e3098b69c21da644ef94b1c92be1f181362e410bea71470beefe1253f735971a1a332ece0c5330bf70efcbc8707c59193202436278c9e1fd3825bd97a655583642ab3d7a3b965bdc2e04788cea1b5fa025a83f9f72efadeb92bd3ea0194b53acc7ea9c72fb0596ba08a451f6c746802e1c4291f6b62d9c8a2a93343b5d7f5a18d6a95efa60f61c03bcaa983437a1ee1921c89e9b6e8acd7cd6b3075cc7d9d1c49b8378d21de953205faf6d2b6764703194936e8484451d3312dc9eeaf6b0041660dbc607af189c900e445b1d2261a20d47bfc034dd3f651b44bd84e73f78ed456437b8cf9f96d7e343bd6057c5c1f343358b2a28264dbeb260d22b7d0acea85e2335b40a60fba7d215e1ce9344ac0770cb113b3c913e567f058e5aec3f91c08a5a4bf2fac42e1a5e3e30d78ee6ba49cd2fb8aa887b416ac1a8ae392bceb6160640b05d0c8f3b3c07895eafd24064a40974e31a7336f8f9ab56d740993fca443a2538f732f1d3b43ba77e4e379bf51d98303cb9a4e3085cd3ef6295ff174e73e3875901415293233266a6d7aede7b0f5b684f15d629cbddf975785d996946da52f46c328a1dd2a8e871691947f8269ed4b06ed589eb9c4741486a84c59ed90499a60be71d8db0244f2533fbc331922d67f264270a6c232d0cac549a31b123dfc9ae8d5a67083ef0202889ead91f470864226ea23fc1b9b849e4ee727db0c79b09aa951b4228da859e128d1455387e82262b16844cb2620adf74fb21f95a75286c93fec6dcb3a1f9f28cfe56c56057f003c61aa7b24552132895597e0252205645f002850b8e77528790cbc3650267ce0a9420ad877dff3c71e05a4b99fe07f9eaac69087b76e0ca2786becf7a7090a964b3a8ae73db9c7cbeac0c67c1007896d1fc4e1fba7ae446aaaa33d54caf3efa4da83b3da64e0831fb4faffecd98d4b5a8bc2d0d55d2b7bf50823d43197eba916cf3e13d4120f636c52566b462017ecdbf04f6c3ac796ca9074016e0836f33554f788e27f914223d77b554ad3f15eeb2f26a480c2da9b53a0138d9ac129f267a4917ad7a977bda912270c224dc0075b628616ffae92e07bb59d4b8d7915b033252552aeb0dc244c9ac78db41ec54a7ab348a6e263b26862547474da8850818947756de4b0158f286c9316a9721a953070a93c78c847c171bfe4634d8d1fe3b424b90a0f204b1404cbba8dc2f932692582ef49c912239b194a3d288a288afe5588744b60063bdb9c93ca7a979f64424e5590b5a283eb85d9a4a73b8c6752836d1391afac8dce1d63299d491107618f7e4a9063d899c6a93c097dea625e4f93382e4297b48fd1b20c2a69ae3913d21c3674fb505ab5a9900d316deb8ea82bb8d4a8d7925cdae4450f646e3e84ee1a785e3b23952694194aa2aa4e677eb45ea9d592de0c65cc4fc9de2c27fef8a90294a46bc54a43704e7fb9961cc004f25730f19d5bf9f62bbdd4d9779b93bf313438d54f11354832cd7ee30ffd5bb08a74a2b8dab648fbdc1840e07f5a4af3018ff70f390237a186f22b0d669e534bff33730e33c0da34ce307e0929fd600d95f186588e9a2309aa6d572a87c2a9e8584da00b23505b9206508d26f920241795e18a488f4044f1e82028e090915dac4f5e9908cc724eacc0f84f3029831da7bfcb8270ac5e2755b5b6b9c0c39beeee8020ea5912bfb127171e9dde6f571f63fdb986e4dfd398d4ae41ca99a7b5fda32b26b2937d73cbe2d68c652d7df52f041bbbcc7c6ae91314bed7d7d164270e18344cb461516ce013da444c86bc15be6b8466bbe639d830e8d287f87eb0f8c999685d8cbdf761ab9b416e883de5654535cca292aa284e2eff5214ff3db88e9e8b0aff79494c12b21154f6d3deed1a2b29657853ae2e8aab627072627277851c4e071729641587a4558669ab09578dc30a53802ff6c21106ad0f434a29030c2336c58471ea6108784d6d7cbd567e0a87ac250fa27c71526ea5f4e79d4fa8cb6bead5dc8a5ab4bec3c019c63acc90acc700eac1321926e124b4f7f0f7a83f967e8a31a793d30d4ab698a81f9f4d016b4c4869f31471c9788c053b249f42a624587708a1522b942767b0175c9562312300cbe7afc9aca8d25cc54288561770ca95490a6c291c868f1b02f08b097160d633436120ca615edfdbbbc8493b2d4131cd85b99d51cef061e92b29ad9d033760de5a88b525450aeb5ee5470c5d0fbb6077131d258bde410f81a9c7ba8eb91ff61e11cfc8f4063baffd0bfd3898930c0c9a52b2579b0eb35d40fb001e2bf10cb05bec6b675105a57aee3e1bb34deb1bbfd64d6c03fe102b725b0fb06fa4547e967e1f96804b1fe566f9985efc1f32a56072e8f1d411a21e01a130f6ecc1542f631b391c5f8ec8646139255c6b769b9a3edac2871c2f23dda81a8e812f3f84e742a73fd4956309738653bc116800e3b6b9d3eb0a1528168f59fa6a4823f2492fa1aca4790d5da73e3ce2a6a2e9c1151fd1645236be90eb041fc3d69e1ac43add3399a5820a01456dbe4cc61f9bc3b50f966e337655884796d3810a87a9c3dd83496db64785f0ff84003cd1e0e72561b4a225a51e2c0a2c2974e09524390879c4efa1c2a093c6538b5aad22a1f443a5d6a2486308aa7de43cfc050b055d009694630d963c70029d970085c53c982ca3661b72a8ea4101af3657483783d4de932779d4eaf9fad3a56f7b179c1c9b083f2c73ca158b9da46ccbe1531ede9591aa82509da72437493e4444a4c1afe3fd49dc3693bdefa79bb76ea80bc681743e1c50cf23f3bde0db75dc0e0ec4314e70696290b29e77830948918c87a269f0dbb2015de453af47ba473fef46814089e199a8718b7c6471601466f7a5228d8486b4d8b18e1c38b6188b21157b41f65a329918d74cb34f3308e9882e0ae4214548a6a2e8b26e8a710827b95a258b6a795f0f77d627f05a3b8613ac276b515f61d4a7cd02726611f93a37cada83c8d3889f814fcde1d6129c5b2154672cc39e3afe925a499022730169f3045859ae8b397324dfe6a930f0188b0dbcb21851ce3b15143bea2e2d45aaaf9632c61896d7595c33702ca6f4aea9921f0f397e49c3f7f8cc65fe6639486bb7aa76ab2393bd606e7207bf120032094ce0eb5bdaf415c9fc3c311fe5b339b08cf428a9a58774462f231b4cf8c69bca281b26c14e96114cac34bd4f42250fca18093b0d1ccd9688037ca9143fc6430ef46732b4e430fa487195b306d9f1ea104e9b52ce441f5790d5a8e707d4faa76e952ea7128b241a0eef3a2f26b520d964e38e6ac44a1d6e25ac288d136904fcc883fa54317b8d37a8de57a2e50ba078c705b46edc06a2014d44449422a26e898c362c1ce287dc0c49e2aed7ce12adbdf1fccb7d9dad1905a938f5365cd095f911b6b34e55285c296e612df72c7fc409f9152a88ef425b0f6fbbbf5ed28087c0001d5f28967b3869c86e986fb71ed3660329668c8166e89fd4020c14a4670a2e9e20abe2f3a4f0e638ff459609eab49a021761cd781e378ae1c4677d589a7748008275278e863885499a38ce2007319994523874940062d3faac21691d8b9f08c0a472df0cea43061a1ce755d55df790030d5a329eb1430063955bd3e34815fd0249d25540519665cf424da448158d250e66a123e31a6281840e6aaa08e1f9279038556fafb882bbaf41ac1980bc56debfff1f24c2d1d67e22a31458c4c76150d609e567fde92cca8e7a689a1f64d13602cf09dc4582d5a09002f64ad19795a97ae771749ca9739af2816514ebea9c96ce819e3a5f23941dc91fe1866e5036ab510a170122ad4b090d2cad7f76ce5839f56332abe98ced53f912c5549b2fe59ea09b404cf42cddde02657736dd5f629b50f9805172577678e87911b739664f214fff1edb0fe3aec27681434c85401754e98d98e07614b4ef29bdc28503698cb3314c5e44bad5868788e5d74e6e6da47f3dbfdbeeea7a53e2cae52032f3852c6c824164d6a940c428037f36de42b4f21788b32378ccc55c2c96d900242a13561f4bba6e6207de286dd428680c7c82f9ce0a8cc28f4bc5579bcafc5b9da1e07f217b0bfcd27221cebcba0d5bab1ecebd3a80da40e7459a790815dad016c1e5170d66b28601cb6dbb24ef20ae95068efe9fefcecc7045e0628370c7e87d221c25d64a9c8b21ede583e76533ea5a6cf9cae7f28a0da71b051803349edfb1e8353556d6d22e5bcb9f924c600753c7a455a7964ee6402d185a871663c60d8c56a656e46ea113f89f894daeef6ed62c24ef4db472627f2ced6be049e57cc4d9802fee38d391e70b45b886bef4a44e6def21d4a7320de7c6375dfa04dc01d4193990db7235ae33bdd8a6d2aeffa089a36ecea957307f267264c599b3bfe1258e21d7df78eb40feadfed28436a22615d8a6046473da1c04e7da58f29f0773c753475776a3313cf52a9146dd5697052b6a2b171da57cf3fe2a8954efd6152b4957dd9284a1a25290b085b9ff38ae850e49dea97297bb55808b58d9dd1f161f02718f9734eef01b5265101cdf25ca0bee1f366c3ebef4d044328e590d106a4924d026b55f31f6520dac7ae9371084f8209e64402ac21877960aac8bcde7aacbe82877d52b64713cc5e63132de863f2ffe5d029afb273c1f4a65e0ea9299d6094b000aa8a65777158158ed17a16ecbf37db80112c732fcd5c77a7bc11b5e36453ec04803e92c0260ae4d81b839d0a7ba5116e092dbb90ed35880f7aeebb62d6302c67a35490e3b959c89325f996cf92b553d09e00ae322c48456f8d8884e4768527a9251ef95d0f400e02edeb8caa673742ea034c2f94412aba6a2c914a8410db04a9d14d1e8e70782ee2e9b9c20eac2f9f5dddf8de40a4391488bc1d6042185e924fb5be1ded13a8cc87e979a849eaa8b5a732a256a0d5721e17ff03706add6c6bfb92dfc5e501363b4f82173a4b55f24ff9e7688caec18c13e63dd23d7fa8df60dbadde0343bd9d967d3305363fe2c970a61c14601bb562b9fa1deb634fee13ebf8f8d25f2e09eb1454e5a9922babcdb2f5929ce6e5a18512dff2dc96921d6918f8b5010545f87c535668131e9122d503f1ea4f891aa123d9b891abd705b404e8cd95bc4786ae634d28b9c10d93a5cab3f0cf129314c0665924056e0cf0580e2124bb1e3649b29535ece1befc48cdd2c1746ad497d2b27657705e540ba186880ba7735a02f482be5563b1b83af3cc44cac33ecd7a8b52053eff2e459951fe61cae2a58d649aa4195ca50c3378873cad6e109c893f037de668d42091963365d04301614f82d6d1bc2506506ccd1aea1e7b5a69462c4474b605155e302fbe545b8b0aa2d19e4f76928742d2db37ce4022c159d9b729c879e6aff870ddc9ca6b49e5e4c5352af602fd7068401ba27c3935d2d8d9cff19e7203b293f895124058ec0072dbf9254538636a8e40528a703f284c245f0bd494e0cc357131ebe7a9c6ba5b1e89754df0262da478b245bd411da397f02d064868fceb99adeb449d3926d3e4f68b6cee58e80a941dd0e022f8242c49c7af7dd04110ab9423178f79bb7574faed3c16de90138cdf5391ae2c5ecfc553012678b183fc2aa67073df259ea5676dcb532e4d79f6f0d028f35c4ae302216eca16dc30a6db83e5e960e8ab848ca3da63896e5a115659c1b597213f75dabf9ac2cca1c7486b35d7e5bec0888f34b2994cfe76ab3c1dfafd4d3653a45a6d176815bebc6ab89f115fcd16161ad82b8ac1b809951ea4ad7a60c5c0bb6dfc2935a8a533c321751c7fd01d9881d41ce104dc21b279602db7c1ff7afaabe5aeb8c71fb7936f865b01c13f8b3752ebeb270022e3dedb1a0188f2a1ccafe55131f2c4f40e4f341c7231ec45f474c543f18481efb7c5211ff9200519cdaaec782f8c5d1b7e1f0b28cd72b23153c865295294f9ec9041f28143d10512257beccf8303731569c8e858fd04f81b184c037f986e334da4ea015d3b670d744d8a1fb3facfdfa6cafea536e76c396f4626cc27d6c61bccf14b8cda111fb8cfa0f7ff23cf347e0082ef08c80e4a1fb8e8267da24cf67dfaa316e4c005151f7614ce1190fafea76b22455c8d6a7ac9dcf9f505d33ab42e087a75e050489d7859f294a76808bf4b61ee617a9bc09cd40934809a0674c0b1493b2d573103b21096ec8bb691dd344f5fc239560e0cb18f22fb9ea25815aff645345d505aabe10348d39451e3410835b07df9a018f8591ead3112042c5292256e4931c7bb58e2f0831bd75d9dac77adf0ee806b88d7da8a94127673056652a0c92a5d6c6da868a9000f88457eeeabb0a49f1527355708500f25b65682e1a41241d0000030c4077dab9787927dacc3ea15504584f4d6b456ceff844592e4557d2719b40a47c30e841abc58c0abd9791ed3524caeaa71769ae3d2e32221aaa1c7afe734f20b9ebbc66da58af223284f51018a4547c952b93b4353226e20c5098e5cb5a787d3d48c70c2a7015746b9a99c921e2594db6d12ad70415d4cbea901883f0603be916e63bc873cc14e2d35cbb9535ee409ffeec9235e60eac2ca1305dba10778c13703ed0d22a853953615e54609ecb66616b756d6135729e93f927875d669506452aebff574c20bd81b7dcacfe2a7fa217efae286dd5fcfdf0ad08217bb7fd49b547617c2d16455277a0c3a246b687568e4af98fb9d96b80ab591d575d3465e140a0f638cd3a6a48c0540c7095a0f132ad18acb708aca6aa21348f41562ad58f8341064dcc425d74b6a688a57f8a69976eb78433544cde0e2cfa24e2d090282d425780f1d6fb075a83702cb745d0a89ac7f890d03a84ce7c872e90d8549a0e66e47e40a73d2049522102d5855f1e3d8743a09b468cda377bd845c9fbb0630a37bed53838e5e0b42ca01a42559d0a42d414af37d226276b206e232ce5307fca2f8d0c12bc1ae5ef85dbeb6d40cd02f5e8322a3d981f522af3d39c84dde2a580e468a9abbd4607c4c8b918ce91399fb09fbdba6e8c8a9bb816b20930c8fe94a92e24ff36466d9811433f24f696b404a72c6309419489790c3bdfb1c45d933a0a951b1e69c71b43974a68fad89b867134615ae95ec83707a349e1f730cc0954501fca1942fd32747ea7dbe2d99c7dfeba23533ec6a8f1e8ca7e24a3123554aa103d569b50f69eef636c204122a9255a76face1c85d3248e9e2e1f714f6cf0438d08518c6320c52331bf1034e7552da89f333dc537fa4d445c1166cc1071625d3e9bd6d958ef9c56f31acf61e7c9fca63e4c53b2f15bd3ded20aefb8a4a645009b9d9ee7c7f61313c68fdc787146d32955e581e55e7cb07ed67b88b9d99db1c6930429ef2d34c45a929170c2604ece68fb48d8fb23f398363174c79492ad7d7be182af74828b23f504687f1734a746b0d7f47d7237cae13306ac8643282ca45b615da4ebea8cbd039507b1d84d889bb8ca558579fa357b13d2d39b36c69a5c82813c4fca68f42381f3e8cc10d6a003f620bdadde5f8b420f2646eb0065beb3f0dad0735dc59a8d5d6042f96170c2c0d1c6aa6cda6304924939abf07dba2d4e4741cbbadbc23f39fc286505c7dc5387e72b94d2b2efb2c8c69059cefbc1e69e33ef0b2e94264a1eadd5e815577bd5f72656f128d4f635a8bbd7376c1e428e234dd2f2ca41b49b7c7f0f797c78ab4d4abd50a42dc5af97a1e4ba59806f1df78894f2701120e468f213c7336c125b423a909b81e614359485bd472e6d8c59573fca0b4a8265019d513673eb0e3f4ca465baf50ac764d5e2bccbc1d20416b26e12196d3808a001873fcf3f7a87c21123ff58d699879c6bb4c71c2ccccc39822c201e33f50e362c3ad7b49a8b9acdc15267ea100dcb249c62cf0e24f5999d02375a2091f25c128aa7aebc433cf35d422cb456e4e87a634bcc38f317d8d8dec619b12a444fb820a4c0a142eaecef47b0ba8f53d1e2c63aaa1c1e4c1e5c00bec09f791396d1c946be44eecc57ed873c5421eabd2e2000373ab9ba216f6e2ff5fef5158bc25b2f83480f6fc09f3d9795811e86604dc4ab6091c253a6b4d50b346620fb42cac4fa5b300c3ae3bbf01932f5eae5131517890991c1e4b3d571bb2d3176cd2b78e7b439825371402b7cdb27ee4303159fa8392271aa46e8b59641485ed126a95a1ba068221fd6567823788b88e70d8ac5f691e5350e194d2471a444777a1f972862336ce65153d328530a221d8f6e5afc4479aae44229700d476d725f331058a59ab7a349950d8ed21d87a78a63d40873e3f26526be892c0bac11f418882c67f64e11be2ae5767e0ec471003ca6a86f2e69ff865123020993d99916e5c13904e527dcb191382a74c66c9cd5ba649c2f6a79a845353cd8882528b523d559ae0c992744a282491e2283c7306cace00a16177676cdf550e08b64f9829511d8133f7c17965605ff734b15200b012dfcdb69a77c5d03ce2afab2f986a09face460656b8e052b1b3edbbfe1755efcc580e9472c7bb942fb3ad7546b8402fe2a6668c3146828b0454627ca35ef2d1732ba81eb65b0417cbc9c50c33f414982e756e862575aac98a007d4f7b6d9d261b5c90447008ad51bccd305a00b537b7fbe60c32d690b9a7491b84d37fabc550199351c25a8832a9a3ebd5361a8988482967b410330927404e21b9fe7134d5092948a7ce9eb54446ee5f7283a5fec02c5267618e666132555fc8ba8a0e61848379dddb3799f7488167f409ba3d08933399ae83c9a843e5e9469eb535a8876e8d581519a8695f6b59a6fb18e5bf96c9d717b10900be7e9fcf2bc62b2f7df2b44da360d4d798e377c0266acda1dedb97d2be962e4ee4801aa850f43e07f2bc0f830369c1aa36c5b540bb3e70a59b4048102b7cdbbf1149f7d9a2bad2e1fdcc3558eb2a382fd975bb076ff5f4434a60e3b9788ca36172e8afb6857fbfa8d9d992f2dcd661bc3b8b13e3797da4736ccc6cd0436337583f7f2498886271584c0aea6b2f6d5eab1351f63abb56dc8191218ba5b4a2157fe51dd1821041efbb5eeba9a755c06d68ceff9bf16e41dda493f578d2ba3d462d2a5ccb51c7f86ea7c02a0012839d11eb8b7d46905c84a86327ba882ad7e8975549c23d9a327dd4cc1a99b883bbe2e126234c840148920c54414d287d3e4798b9f9a6ce82f762024b7b0afea72ccdb0c63000f5021927b013b8537ba85e7410fdbf92da9e5ec2eb8262e0a484ec4d6856effeaabc6c402b0bc2e4708a03b4e7d1efb1339f60a7eccc5d6db0d8b7e896543178c6dcd8b82ac6b36b5123514aa6e3eedbd6d02e8a592b3531582f515fd802d3c8a781803fc7e18e02b44b7169367733c0f122cc4968c2fac69d65b8bda99e27a0cb6d6f6e9ec22319ed41647b1f126776044d25b01f118bab0cbf9fcb91f4a144f549e4220e2d188d06977e7a8197ba839ff641b7d27fd6584c246d10f9bffd64108fb187c7410b7362d0e32b312c94c9306daea7828f00236208b9ecc93c1a938e9ba7ee8b14709310dd990b43a5b05ef934ae79fcf9d7aa27f03e1d8489e00b84b6a26867a844a9f19951cf73ea760176e08191774dac302c8a0d2b7bb406b8b5da26ee2aeec02cba3e21c43f27337cbb64c55ee2d84a32fabedf1927333fb5d06c3febd784467f0328acc6775d52ac30fe17a2ab3e32139b74a0c65b949e7ed39e67d0d81a383dce69e21bf75b0490484c8d888254bdd55f9121745b5665ba45e216d88ae60e0c7fda0d4d5e906a3784dbb7d93387f5f439e353fc13bd1b99fc918d160888abaa24f24e58dd3cc6e17e9d4b2401ab45af7bf7276a8881bdadecdc271fd7ef080016e766f1b4d7d38a103118ac0e9593cb35d08603a7bac08e16765575b616af29029de62a2cb98d4418df688643c629a4342eba40f38719af4d1985f092c05bc7f3c751a1401a3de61887324983cdb9bb0ef581cd85b61ddd5cdd2f4deb02b17e6a6258323f065543e366a142a4c2ba0e2a5448e4a96b2002d68be831522d5f43fbc1f4838f3b115c086ac824b8e1bf8c3a2c8ba2a69eeee816cfecf3f9590815cffef9872d61f1e4a6ef13d8dd4d81bb56613c82b559a5cf31885ceb882ee217de3cb4d14d1ec569fd197c4348b3ad25ad14cb94caf0565eeb285119e3550325fd58a4c1d3ea2d1e04d7ef46805b9b030fddb874cd3c946426e7631f8ee10b2170de82950dd080f51114c09bac70c68922e09aaa906ef44f81255370c4c649e0a85c330c56883e1be152cb08cc7c01f05da383f1accb1ca4be42b44b79924da94ef5b5ea12c7df2a1841fb3422525655da9aebb0c3dbd59ae1af79840b5f3f15a67738b8703732f2024bdc563b833d4f706150311f756b7a1936b43534232cc4555f1fdc281510d3fe053df740388823dc8734b28123b07564d552657dc6871447b84922b062284f143fd3acdd35ca6ecc097d07a2c07854ad60f9361b844ee389239ef15af898467dd0d21704ce97ec30ea1bb53bd3e2e2ea3e0b740c6c1b77e85c67287020c07f456f5fa8521c6b087cda597219c8d4894419a1510be0e3846ce406fb6727e854904d3b7dc1f442d619d158962530eeb4fb882f7c9d4c784195d58c0b699de41908eab00b5291436ce364cd41c36a055e27f711ac668452b8a23c5f2da0486c3e3eec9a6119b476aa6ae555ff1ce83b1d13e88fc73a96c731fa18c572edda6d108284dbfb0f49320501525a437947a1a599f9fb1e11e0198800d774ab874d7dc08cbc411de26d0acb9dd2516868089e25483e7bc5c4e4d345c0bcd5d987927ef879f782ea8dcd00e44d29432e03cdd006961dae23e81fee633062eda216ab43660f694e1593a7a1cfa81b1efd0dad0b53f1e111668dd5e51f37a9d285556dcd071912e8418a5c7aa0087b92a012d10d2f6c4348a8e13870222a25016d486fe0d98ecfbdd41c374b459f813ea65daaf74ceb9ae04dfb5f219637bf9610a58cf728badc28da22a3e9d55361464b3f0092feed90f38ed65cc8eca11c43df61086dae51901210028c3406bf5d8ada3b065e4eae470fe901d3134e4cb9a54b5364ab0a0ef7993cb53aeddb98100d534e2c5b849bd39ee3c16bb6ef8002ccd7bf4a262d000384adedff4182c60dae4cceb96df766551841d2ff7d0c66526c56d7f2a21245a38a85c5643aab2adc40e9c867a1a670d63479b0559ca9fe0665c4d21b1b2e5e7adeb45f685078d0d505897c2e0687bd3dd9b1c441678380b14dae9638ba0641529e07b42ab01c91c6d105e8c1063586cdceec54c824b9d15e0b72aa763daa00694fd3b34aec69f0346e03b267a01527aaa51450075302d27c9faae6e39d1cd3504640da00b5ec108b11b709e6209fd7c002e9d36a63bbdcd8641e0ed9809a4dd76b2f49d99c62e5a83bd2ea16a85e28cd51f8d5108a864b726e2d835f3848b573f5d35825a706a700c6487c541d3f986003eac6838de66fed091a0ba90369e136c888beb0205936ee446892960984d8da0c32d008065133e9509630bf6e2ff69d83e4206854a4c05f3bdeab9f75c6c3d78cdb20ba7262dcb1e1c088e1be299d2932181390429dea043e315830e9c0d54955d47adac77158156e807b978f4be0d3507a836c4fbf4a2048f5bb4e338f804516999ae9ce6f79d79aacef5edbae33c51439f58a816c34352195e11eb3a3c694b5d2ed6f4b0020a67203020160f8b27384914a309d153172836b78d2b63a7a92c84d0ef1fc28876cd84105d92e4502d9e960ec63d06cfa01599560f4db04cb44bddd4a5b127bb8f695e2da1c5dd0ba351561e2cc0a47ed60e123e226a9963ca2626d3c5ca4125d7647330d8ab4b1e6c73736cf75500184c8203e53a081464de5ec3868ed75b122773ca7d4162e4ab305329436c6ea0380a3ba3821979d858d651ca16fa72fdb218f4e85c59279bee12321899fc095ed8eb2323c08089c92ab6a9edf3c4303014a6a686df1049d386d61b8786a4d168c17b3f5cdc895bda5cbead3b2f72f82ac49382839e6424ba83d3cf274fa3d2b47be5b9d2f454130d8bd4497a83c348839fc7d969564760a23b72028198ecc48be9a5a0ff1dbd3f5c80ca3026e8a17bb7baaed9119915c7051f35fc3a5048cfa316fee843f82854fe18a1087ab7784098259be7515b080d98d1ad3518d19f789f31fd5f50703570af3c873075aa473a3363b056a7f003d317f3d0ea01e10601697ddbbfce979e449d765dfae3faeaaacc67bdcc8f8f5cff5b4b88ee3f1529942407621357b72fc44af7b6b41c2ba533371a2cb79212e0857642e4df6d2d278fe7b34f746d7444cb51d4614fa1c29e579b8706252ae769751aa09245694c2102424f9ee1c7166646405c6cbc58416799ae44db4152122caf9c14af78dfb226bbae048ebe458fd1c6ccb60985ea581635f4dfa3b8df2f57a05e5b3f371c075aad3986348ddc949cbb1a8d1e0fb38b33b6c619302599fada07fc3a39b7dc75a7c9c3d5cf56f8860f3c9673bd2098e863e81cfe223a2b147b4f888a02edc057fb0e06e7c44461d23adc6e43707c230cd98db1594ec029cdba5c650270ac312980c0afbd000db25e01a4b6396d5c0e3c0e77697369383e06ac594f7de038f0378115d5d2ed4c938e5308a6a73061eac8bbaa2de3521db12ca1837231dcfb6c50f1fb4a41a87634c64f6eb074b1d4a70ff1fe4729c1564c4df9a738813a4c2d6a616c30be84897003432ce577d2b2595507c98c2d963c6b4c71cce1e13923d48c43db721a097dcb0ebfc7fd90fca94df7e48c967b9506a53d8b9a30f5a45ac310403abb1160c3177f897ac068b15849618f4352c828edc8cd3c0380b92a5b007f96073ebdac5c899075042535ccaaebc5a747db4135c1002006904ff807c88f5f60ae683328ea401dae1f32260bb9fa96025d7487d1c7535dce5e08e0870e3df36cc49368adaafa165babe45296e3cf11cf2e5b67ebf86638dfb95cab5ead1aa5e6d96f0c001b9baf272147978d708d7af412d71e46098b4f2b70ab32a33e14dbe7cfb982686b66f3e7a07ea38aca420daf130439297ae4ec7c1038263daab1a8cb18a6e2706cd373d944de86db3e5e181c2553cb07da372b7afb6a3e4f22712976b7db06e576696489c4d67ba74df7ad0220c243a5e679c86ba56d741c154aaa94c5601ac58556835077f9403db6d87d7cb439e6ca9db0ac54e28d1ea4683b5053ed63883685830c6f48db29537f7bfa68001d21f8175e1717673dfb9392bf26d2d4b83ac4a180f078b3c82961855ffef1cefcce093bc403443b0342393646239ed8a3534831cc8715d9a61478650d7f30e13b970aa465d8c1b1ae653f786358a05dd78ba4629ef9d18b5bc2cbcf05a5a10d7590af26bf908cb2b76aa527b0d03200842217702cb93691c870416a8b087b5589a410db73da2175b00ba4a2964d73ba2c544a1aa025516d16c16f0547ab8696d482fb8e17ad51b9cea4e08765062b22bbc441c86ad4a49625b4f8e884dfda0c30a783b64ab3cc8f8bb47442f0793be5b2f088624929b3a5e9c266624acdf3cdc41d6c21fab25b00c5f9f3c37cd4e101fbd0c011a5d6f9fa830f8b3561fb1b95bcf5911215bd745e77396d47cc05d23c152a5f486a35d472da364310886bd4491499537a4a5d089053399e56aa18e6c6c836b8e5ec456066115b3e828434b4c3ab0c46b6d45016ecc9a726c0434b52575b3beae2ad4ea88058accd1875aa2d48d10574fa1c39d90c7b8f08c31c65cbcb5678c88486dd2ce98993b79053b288ef31c249cb434a0f5e0c9f236e97148adc398656a59e4a4df70532c144d7167baff1dba55cf525fd5a2e246d5e675c15af13e85a0ccd44c9c34249db24eaf5acc5f18aa81810daf7b3ef92f1f9510ffaa55f504145f022ab96d5c5e300cd29a0e92f1a4f4f2bf49137f26536fa6b54a016604fc12e89f60f323601678e37e808f50170146036c59c3e251986e43c100703c7e59f0fc36fecc6ff871147a9299a53755d687661ca9bdba030fc2b626adedbdf7967b4b2993940193059f05f5054f6bd824ca38865a4fbea9534d1d0778fffd0bef3fd3a88928fff7463af7690dac2f3ea36cea5c5389f8993ad554929fd6be2a45d5c4b411b029172db84d492297a93dc513ed66dc81e84a55ab402a2a1d28a4c12141a24264481108f440b28688238e44692197f5ca12208bfe7dba8d4ee14a3002352e80b981a9d977253bd3614b82a44c932753b058d5ecbb2d0451599ca6b658a9a99061890c377461c283528dd4613d3422521e5b69cedf8a9c49a16e4a7a15773bdc61cd422a1bbb1f82a130116ce4ed6f6952b6827fb9a805f4b3e8da29694d2c6907747b1494b5564bba5b2f42fd2c565052f0af72479722f8d7355b87571c7643a9f1bdbc40defacb50eac892327c4253dcd7658873d8fd104c2825dcd95978c563379c81c6eedf50cbbebfc3f91f17451f719815a6d9f75f25f598483dd09e0e1cd58125dd1684583b355482a6b81f224155b4b636c31d4d715f839b3e69bb521bb3a07c3d25bf771b335402774a10ea04c120fbbe78c79d92d628286b8d9260109ae2863787ddc729c3240b4a5aab91d1e07f3ffe295aedfb3a6fc1df3f41a733dc5159794fbd12cd780f0ebf62bc856e9071550595f7dcfc7df18bf7e0fc7db14ad44259d8e416442ee12ec40ad38454f6c49f3a876adf079d4028eff1bf0f4af1d9057f1fbce2330cfeee6cd069dfc7a0148f2ef032cc72d8dd31c39d8dcda2b48e496dcc02130c1284b2a813986756c2e598e70b07a67d9f8252acb2b1fb38a5f8e5a614a9707503718bc8a585533cda57d44253dc70e7b0fb1594219687693c76dfb583b67f6633fbfe19eef67dd0e633ead98cf7e8bf9f773eabe0efe72c9fbdfefe09226df26fcad6db94ae174bba33ee9a270562d7c7ed2bfe998fecfb94dcb8acbb8a1be8b4bf4a571983a6a8df2a8b64ccb0311a4120d6e923ee705c031135d04206a926ee50b3a5ce0b1c1cb4d043522d878c052c46d4ecbb898386404d9211b51c2b96825852b366934ed6a007139c6a5ed25a0eaf75041c744c08d094b1d5728460946a4d3a2ea8d5ae668e5aeb0e917e597f689a534ab3412536cd295d6d9a53aada39252ee7df56ab553645799ebbe7ee79ee799ee77989a91406f9c3b5873a06b5e29a3ffc7ae1fcf9058ff15902c05b421c9266d3270224470391f29c94aa6e50731ed8a24dc005b4092cec2e40022e5c5515747b13b43c7a5e160e40d227ad1be46cba7952b0cfec28282e2d558169ac7e06db7640a98afc94aa00a13eb6d9940999d1d514e1f7f7be0002ec1a748d9aed3dd9c169ee4f841a75cd16e102dece6fc36b246067f32b7d8b76ace5dd16786d1bafedfd8f5359dd308759d13ebd621b61b7000281161a7342aca83e9b68ab29a5e92340f760199276dbbf85acf6e80af3f756abe5a2ad1331e8a0d6767f1306ed49b2386dfa250b6e0f60d32f37606d215fb6bfeffab06a52d13427c46a9fb47d81ba4feb4383c164fe622d4bcfd96940dd6e0a99d1f54dfb7a69cd847e162250a97d01df356a9a9a7d7be5fdbabdb26e4aba48c0c6660dba668dbd51726ead1c1b0a563814d0382525a160a62562ea61af467d31831dda6efa19ecd09ec10e5d71b8e22a130ff66ead0fb332287dda2cbff7de7b7dc9deeb4b5976e67afbd7e63d5fd50fa0d48dba4ff7856be4aa60ed5f2ddb5eaaeb63d7f78ebc5a246bd36004daf5a7b5d5a8ef63adf50a48a4b25776676d34857d33bb1d80987198d5dded5d001efa7c5979405e7201d7245bdfaa2aea3f6e5bba49f30155e92bd9c192d2c986a5bd626d76078dd927d90bfb74296b6dafc2b6d6041fdbbe953aefeeeed2dc1d8af265df7ef199ccc6ecff6b5b6b66dbf385855bf2255ff2255f7ae1dbe839534411ee3b10effb3ceff33efa7e6ddbbbdeb5eeee6efd5aea5f6453ace7388cfe5415d56645cf5ef4e573ae40c193450ee8d0d41ead66d377db91cf26a0204aff59a12a138c0cd49e6aab30fb6a363df194d62412dcc7599dca99e07f9cd2439ccc00d2e08adc2066a7420f3788a2b5dee9eeeeeeee321a2c5fc7eeeee1d3ddc660db5eebeed62f7db7ee375662757b3f29daff53139b6efffefdabb33aaccbbae8fb340b194dbf329dfd607af5d2d7e26bf18733189e2fa315d9988dd90040e9fafe7d185f30f450ac1ff81ab6ab5eb74817d92f2aa2ba22cf6f861029adb552a76eabdf7bf1584b10ae7d0cdc3fb171ded8dbd79a9ecd7915db93524aa901a81840886bef4929a514574a29a537042346e266837055a0d1b4cb0d599b76b9e16a9ff9b5f33c3a43e0d34de4b65af83faeb345ca35f07379d4835603cdef91722d3445afcc0f9648b45afeb03cea916bf9916835f045b7dfb66228d292525a9e277efb3a43e0dea0287e1e15c9f1c6fe4a5a034bef73f9d5786dfca26ba4e589b77dd13556d2836f57c055e3d39b7aa44eb5913a54671ba3afc71b0f5f4bbd7eb9ca5a2bc65a2bc65a2b06dffbb6beadf762319f3f2c885adfd620a6d44f2868cabd163f785feff17118cd610608a3ef58c9179e59690c630bd21a96392c8cf7f9c35ed77efd3c9dce637e213739a9e23a8a42e6b4378367e584891027488c70a2027973727382a4cbd9c64b075a2bd8f49520e40a4cae283ec625a556131f62912a1249b8826e5c010954128ddc4ac84b55a1911e3f3e2254609a1f1e0b53190b09ab8064bf4ce60e71f27040f8b0329a6c056d88e652630157a503b5224ab8a75b6dc8958b265561d6af264e76053b1e2401060fab8991af489324ac2648559ed28c4d6871d3dc13125e0b1adc34f774e5e249977b4a21f774021951ebd70bdfffd7cbd2683219cceb097bd1af45690a7c46f42afd5a64340f2ba3c956785f96ada0f980b41306c4576d5676d39c9398ac3cea2cd3faf5d2d9ed0f3ed31eab6fc554c60a1215242c2eb5f3226d27a304191ec69449c20891da796ddb9f9e97c96755ca3dca477f9ba5c3762444bcfc9f07858c96648c0f8c189ed3c082556f358956a6a8ed75aa6aa9ba17a6aa55cdb2798f08c495d6781187f21ef2fd5d8afbe954446c0ffde9e93b7f8ba464fbe86ef3ee37ee6fa5ceb875777777777feaeea79db24cd2ec137f4f3c0e09742267da83778e140ecca0830e56365b2de76f48a09c7176c1e0e03c75b2717098206d1c26416c9cb72181705e0540d2a7c66548f800ce56ab400b19272a6821e344855afd9ba767cecdd333fbe6e6e675d3957df32f1988ec9bd724d0cd87dbe65d2490cd05f55ffd798998ad97f0d8fa5b2490d6ae274920573ec7ddcad9ad16cf6ea1d8ad160c43760b862476eb5fad184ad8ad18c8ecd60b5d76eb4712a825233f8b2410a935d8e7b8c71784ec9109cb1e3f248146bd0204b62d3e48028961f8370c5f339db0c3a7543bfc4c02852fac0dfe470281375bb0cf9c9d735612c3ce4f8fd8f975b5bfc724d007002f97c4caf644b0bdbf2490a7976c8cef45b2c2b636fb899a63830ebc32022bb16389f014828454563fba271e26e824355fb57d437849469d0b69225a2cd461a04b394ce68446cc3901912b0245a4874d6e9a733a53a67a193d06323fd8aa9c3922a276ca30a0048609169090208732b5fbb2186a0434dbdfdddd655ff40983d999d7b6ecfbf7ce386822c40f2a38d870c309b5534bb972c410344aa48025047f60cbd4876d369b8da99633c28e18a16571a18c029450541f0eb04f1e2342446d2f02956b218c0b4f7efcc777b689e87bd7bb4c1c389a74865cff005a7399464d44ae17f5bff0b25210c10a2b4cd96c352397f96ff39fa96dcc7a3f3e6d3d298bd23f32d71b351189ff856f249a4336663f4ccb2cb2b1a8ef03f1bf270a9f347134d50f4d1d7ff275d4aa4924e2c0a13364f33a6afa9b74868c9a886e3e7ca3d6d7fd010ea45afb7e845afbdee8c6acb617c5274d1cf401b4964faa13ffa43b5a23df4647b570156763464d44e17b6f04be51687a7f56dcf7a42955a56cec338d5c0fd29af73df82fbe07bd371a4d1d7ff075d4beef69ed85e7a68e03f283df847f0c42aaf400731e6822891f3fc8906182625bc24cd4982da2f56afde8cb375ea890c02e5150b29ca8b4b67c5fa2b0b47036cd4119e2314187a0d1dc53d0f9ac38417d188b28060d094c2504c9cd503b7514d387b14431a9208c92a41d3d6c403326aa88e7a506c1c31305e456c531513bf639661fa825463d0603e12174fdc0c488904956cb8b5841f3810ac21337cd417dc1022ff66cfe53c73f5f411303b5659f54eae78a0ffdc2d2397a86203c581a8ac9f7811ebeb6c54f90d04bbf34d40a5a080a20301c59414112b2f439c0c0850710486a00c2040a6452a585af30e1e24179c01b7346281e1f50e2a989253a2d5e8a485d31e18e2cc1e170383a2514146467317e582193c982280b1b0e9bdd6000dda0065561dfbe0bcaa2023485fda9a0234f96ec234cb8234b7e60c21dc10509118163120954956a111434d90a2b5a6c9015016fbe60510cca42dba04153d8d73ce89602d6689975e1e98c13400c996c45fe17d40b87022763c21da94ba4bc1c51e40b94d3bdb7d67b6f7d29f7566f3014d58489303bf3f181f950d918da51eda8ec6c805f6f3b98f7d84091b56237f4914044b7a47aa33a797c7636686e88a31d8ca1ef764b52ba9fcf4f4db26f7f05154d6a6f9564e9e6991f56013a13cd9a24eeb3263500fcf35d506067261b963e3e5443442fcda4eb8d874655dad9a8b79a548b38d9285dc5705d5a2b8d1d8d9d142e958026cc63f6ad140ca9aa1830a4aa627c1785cf62c0aa6055b0dde2bb413f52b0aa18647eb05215f4e3e10f7b30a7f1c77bdc8cd142275455458e2278edec8407fef8f69cb00f86c27bb05bbde380dad8ad8a41c3461acf5b58ac056227d2ecac4847a32cf42ed23be88feaaaac965cdbb63add8c22196674338a64e8bed123bd27f1df12870f3a09845f74f283f0c16b6baa9fbf6cea7cdf7fe1d39a58c77bbfa85e25e0ff78919d81b4221957a77bdaf3142151b5edcbb0b2631051dd5724e3ab3ee8ef2fc6f7e2bfffe60d419dc39ce507b0a111f8a12e0cc30bdefb5ddd8c2219666c1bb8f7d67aefbdf2a9d68746a3f9d02f3e200d04414fbccf534d25e2d3684f7b22183188beec6cfb965665e78440b23188a8eea2f718c20efe4b7a70df9fe8567b9f4827f3eb9eceb9665309b5b1af9e4ff369002663f86c4b362cf9d004a46a92583343d698222390d1d181214ed81951a5a9089b951d45884e2cf0a063e14c119f0edbd206a820c1c08304626a15c8972f57cef8b0420e3d40dd6aadf7d67ad55469d0dd092fda61ba54223ecdce44f3fd693c3e237aaaa77a2a2a37a88860d0b041775443346cd034791cca2410110d87d9b7016388eee86e86d4b6584fb67d1b3086f28e66659ea72cca16364df39e6b12f9d899a6ca94ee68788f37e3fce77969244d77b7960e63ce6b9981698f3f1e44c44f794eb056af57b5565c1a8d2f3e7ed1e28a4d11c617cd6a6bcaaff3620c41f0c1ace430d93ee1454fc9b07f521dd5d1a930326465510923832ecc92ac1af2875932356e3c659f630d523b57436e8a934de52548d52ed2c9f01e2cc54b07ae6a15a98dffd64d96341bb39f4925a2196463f6a7a64617f40c87d92f7298057587a6392a66902c8e427362ccf88ca2d1613a55a7d65c0d486c9bcdb3de20efa15b7cfba268ea5087d9b7ddec6c001f805a2287115ae88144cdfee0a00b420211d09002919a55c3830f6550d88d39b2a166bf22d9990c862686f050a247142c353747177f85f7c89051f20397f9b231eb4c6fdb9600dbbe477ae07fff86e31bb28d1d5f3c9afe19f60e2a7db5f9681abd8de1174d9deaf74d1778dfbf36572450989db4b1e9a40bfc9e39dea7a40b6c5e1097dd6546a4575aa450d5afbb9aa7d1a60e9b5559e30527f7e40bae87d0962372952322e5c566b0430e3e10c1d2c2d20974b754c684201cf022268b141712743baf4a9b4262f2438f38644d382a9033496c351c39b21235377ffc00f573503fc0e963bdd6a963eb30c0f37de6d85747cde15eab6af5ead56bad23d8ec43ffe8d522e9a75ad66dddddbddcb62cb7d790f3ebf58f03cb09db18caae4c80316283922049744092c3aa8b112b6670e051a456ff1582a36d4ad30a253d746e0aae009be6a41c91932284a6c201229072aab5de5b6bbdba0ac12d79f31be90e7e8833c620f62ad582fc1f3b234da22f215c5d7935e12675bb0ae12a842b108602835806abb72ba5937ea1714b9a018227db7e0837190cc4a07956a58b416d1110a331fb620e081b465358713b0ffaac37fb396b5d6fff911ddc688a9bb5d6822ffe55f867e962021bb4368c312531c6b701101185ee8e3f93442426c771247f7cfb3c23ec2a841ca56cc5963368e3c3862be4e3bf57f4db10d15fa80a4d4d4d09f9080dc9d04de52277bf1e86e6fffbfcdcdbc267cae7b573fe904e46901aac6d5f4847b1accfbdf7deebee733dd481170cefdd091272263f58518ac6aacb95a3085455c1a8d2b9f8339db95cad274d23f25ba4a93334be8ece8b274d9dfbda6824dfe65f8ce3db98464d44fac737b27992d674abbc6153de6c4a5ad343349e5ced1047862b5ceb5dad77b55ad536e5fa203b739932d994cc65e87453483a19b62320483a19336c47365d900ca12ba220a1fbdd2087e9509cb2a3223445b67d19d596648782f2c51549164459dc59dd516d5353d5f6bb62118fd8fe17ddd18a6635ddcb265f14c720ca82dcf66f496ed1c77bdef0b839a22946f33442dae37b179a823475f0d7d13c4553a7de1b53db64570d0af29e53265bd172fdab755ddf7ab55a2d17acf5ddd695e194a0cf38691d3ac22ca2388e9a0925bd311eb768d76b974bebcf394c55ceadaff835b62a79c77b2f8d1b0a50a32fce8d8dc61783f8627769974bbfcbe57269976bf49b1da2dff0f7e17af5ffaf454be8ee22769acf48b3b3d1fca73d4d6808674c24a4e5b5f35a8e481109517cf3c574637c855eb6dd5ef774c619638c31c6f8abfa182e06fc10fc1004c3f02b8192adbaf7de1bde7befbdd7ef9dbadfc5170cc1f0431004430e400e40379379909237928de5d65895330e5539c3280b7db757daa471d8c8445eeb9fdf74ceddef7577f14717ddfdfa55328ea0dfeb55344e582e0920db7e8c7a64ab6ec5d73b613fde73cd182d744255e10f6571dffea6b31a544a0aa6739cd2d060341d4d1c3ef8f7325dd7db5e0ff0dfffa91886c2ba7847f18a3ffe681a8d2f8a7fc5ebe3bdf7beff8b6f4d25d9c6eee87ed33b9ac3de5e6befdbfb20d86bffb5426695d80ab6356df5b3defb9ab16d8b2274b565082f3ce4cbdf97bd8b47b0dc741c455016861f3e958526183ef84e32e077086210e3fc71e0258bd156acf84cf5ae775f94c5f814261660d31815c1af5fc18f6b590eb5accca2288ae50e29b073b973adb73586758760bd0e9325e0870ce32b193f2901035b66cad87a12c3cdb54d70894441b2892508c1e0769ee7f53bae1f9eec187d049ffb807159f568bb5245aa371b8edcb990b21324b23be864860bec94d049170aae0df90aca150e0f5962ade68931c618634c3f839e7b2d08c44ce995e9a04514ee3e6e989fa1417ced7ceb835c739994c6eef5bc290c6b60dbc73804198077aeb5ca4a63f8c992d298cdc66e63698dd6d2f787f7d5c076af52b75747e8f749bcf77e062e32dabd0b68abbd35b17c1acbaf4cc3e629bb91ed10fe1b9f9d91b74d10faacb8ba4453f86b1ffa680987f7d025ca82e6ec206ba7ec94574702866c624580dbc48ae8e4841b2b060a16af49922cc36dd2c473ea31d22a6a9575b51b7f8a6cdfa639283588a1c01ba29bec153f36ca921e5192c05e395a0be54d73515828a20b01071a96806022468a9020487ae4c0448b0e2e6469c2e344932123c6a1097cc2417ca201073f85213fc0e95e58a28bd4084d3a7e6c69e2081d98d00041f544067c3a62023c055a9d78a5cadda14461284d4ffa6a9787656174a59a450064b1d286e6e333220e72d096ca9a57d3d8f7beccce86a89cca14bdd2fed0abee6e1200f8e7fe3442689d9a1887b42c56f2c13e9540b66458a0f8184df87096a7e1b5f3721a033a1901de40a3e185c10f67b9619fb4ea860e4928a9c1696784045652188286245c8c30e16906275b7e7009962ea8c4cc996a5ac74cd5080000000033160000180c0a06c301716828cb645dd50e14000d64903e6c4e30958743915094a32808a3288a318000430841c41864185345b7015586ccbdc0c1ef6f85786aaf1e69dba69904e1e83bbd7004bd3afca149f1e349a8323b1dd05d5028f56c74d5b606383407423197d4aedb49269e4a76bdb0a4e7b895da9554a28173c9bfe6ed1177087732222487d2d595be9de00ecbfa5c95fb9c40253baf5e9a1d8c3a16586d788f2c80d18fc45a890188601acc7f1bd9fdb68fcdea738ff2665d806303435ca346ca0178bdbc2d6e6c45c208448d09a81ea8cd6e9463d9b0718ccc8003a068d71f53b2feaaafdb288a2f83cfb9418abb9a9d606900a71fcad19d358783fea8eafd9254f2ce529318e2bbc169cff1f28953118d034d809fde1105ba29ea1085cfe8bba022c77360a83db6475f0e8c538f5a89ae874bf447fd1e2b99a6a0f4481e9f2e04c2839fcb07863abcfb84d2870025d211f7242d40742c89d3418673ca176432955ed8200977db29f9b49f4d5a102cf5eaacc40667cc24ce0208f6d3341968f0167e24758002659bc284a447402408f3b49051038a62832f5fc738cd983aa1118028d213d83ccd6e1e3d500773914ee8a41d2c7de82eafe15f828b87ab1a5b6e8fd28708178ed22e23af414ce6662fcce11edcec3a8f7834faf5362f6bf65eb9b1bcd26ab4e1bbda1d3fbf69f2865fc4e6c647d7ef3ef8ab0ee90d9da4b0cd0af7b676e90d6f4b4fdfe6be5ad7da5dad6dc11b04d1633f6c4f218a9a2b5f9932c7db5bdf8dd5a127909b30f4728bbe9074431404f37a25583d553ed91fa8cfa415b4a0d73868fd67faf3f298618c4d64517be57bc0d1b705bb7d944efce482f724689dc93608ea840408e6b97dbe0cdff0cc988136fd9be76369bfbf48482a5f833b1fe6f3c1267e3b68e812b71c627c32f9a1a090a511245bc5f9c8df31c1d0a084122155b56aa0ce026142885688cc060c40ba9a24760bedf29a92c64b34d87af3b173cbfc4f7bf31d1bfd830a499d2332a8b1591a6ac0f57f20d81f921c59decf4a02a2c0e35af0785b65217c49d7ea1c908fbca4c29628bb19413e7e4c89414b4abb64444c34e87b99e3c2c3d7c2b5aef1fd862829cfff84f8786f6f30b5b65fa67d13e180fe70122425ee4cec0df7f55d30161ab993de71b0ffb552ad83841057a1815515c261d226497cb4f70e81a1406be4feb13e6aa01db7b877622840d80538bca1779658c6b7425c999a8535fb0990fdbaeaf25096738ef363ffec655f81910fad163e6e64a2ca9f29e02c500af066f51290688d8e40b4f6787c420e5be491cf04d52b220f19ad7ed3f060793c876421fd0f25a35b2242b0debf9d5467980e7915a7b63ad8849583e0416b9b69ee9c608ebdb584286c108ef9f48878facfa94167fbdf1c6ddebc0cef8d946d442516290b842e489ea020ca68a6d359594734921f3521b1937d5c858f505c64862937bb606ec3d1371ce16ad01a9d1d2abf482bffdbc8371ba5e3291c63c42de405dd3a1b743cc3f22567a5cc535050078719220ef54da684c66ffa1e119fb98ff6aa4db39038ff48568dfc632e922bdeb00c9aab971c15f1b331b2df63fcd9aa9487414d2762b3cf3c0ef5e208b698c7fbc5ede7270346fa3398375bf9c8a1f4618035bd55d413fc4231bfdcf3898c508c7e6b380ca19d91a3a4aee0f70f81acaa03d38606469cd343701fdb1deba654161157a2e2d298ee76c2cb09b8cd99def1ef88e56a5189b016ce854e9e9833cfc718288361297b71c25e18a43489c206326c93fa7164c8317c0142199a09cd46ffe7d0bc0c5cacbe33db0c3cb69a43f4b939e0c15e214ea47a1fe0e73e9f68b40afe0067351c44d19ec6dbdb704873f8c0e76c0ec74e2144c57ae06318f4ec36bd9076837e42d4f83fa9948be8f37320314df6cb225a20b6f63c146e759bde565260ac334d5a90bd07afdace17d8440c920c6e9e4c05d3872aeb57b59770f2e3f8446c2ee821722c2da032a07528c4094820b2b6bc14763ba1f3bfb0381b91db71f683989e4d64af9ac6b9d8567ec00d015c8b9ba018ba28825124b4f111266064631736f61b287d467e866138672511db8372ea9a363890e21fc4b3dd2b39c190595441beccee35b3345e0be00e04100737d0ae9fd7e2224fbe1b670e285abb4fbc9cbb404fa3fe5b2732864b24a1bf68899c2a4bf3bf9cfb4affa2ca9292f8080a538113ce27b9586f71ee27d6ce3a41dab2837e34b5cc63d36f1a4e4a54c177b10296243764957c4a9f28205f450b98e4312fba71f4ddc32e11434c237bf86ace59c9223f67e14931f45cbf4002bdc05cb7cc1b239ab84647d9e4fd06fd4dbcc88b235bfa4bea49faa4fcb76bb424b2c807680c4f49386e339a97a66eb5153c1292a943296d0bd9ce869e1c1a2ea8e211f4f87f3a26043e70560f8fa4545d707d9c809077d3cfc0a086c82b34e26bdef08674935d5221efba53ee93a7a436e3df8eb7ee03e8b5c958dbdf9b3eb550886c4b5c80da00e7901de4fe006f29e42eb3ff35b82428e166ea729f0f99c250329a831c1ae1c1320abb706b16de680165c512e54c94a0070602c909c3020065830df776aa7627bbca3c354c0f74f25b4ba26d9390c7f2411d366f7fc43471612f8027335f91900719324d560fd93b71eee3249a08432fdc8e9b088182dcd8e074c93e202e88092f3058cc7d28a819e650b1dccb14bde46f436b917107096aa5387e455e5fb966e193434948817418912af486ff8243d3a1e312885c8edb09ca80b7462b90ab427889f7754823881b108bfe0769dba302972f225f9baabd612c303ed4e9e8159dc38427cf8ea19d1b7264f88fbcfd2e88e8ee20630879b854ccaa87e4733b28b35850901237bb3b6cd1b9fee31cae773217b78d13aceb2e0744f186d588c6457fbdcc9dd69582e4fedcacd2bbc0baae083ed498f28a647820554f19db783eaaae4dd6ffc6d478bba035172db8794281584541b88984064a47512d8a31e7eca862587063b83df7cb55b6e27d27417ba037ffe8f28946fa2faf960b9b36046053deb5d2227de6c38576ad5b6202086cfe65fb7eac962dbf059b09d0b99a2a445cf1c4e1aa2f1cc9af97da036c5a3f079c429c5c07de970db3b87a592a0dfdda913213e86f6607faa54fb453a0b8f7dc86cc276a6017052d1ee069c059a926d18ee1c386b70f9c7468d43454aa163c1c2edb9fd0e5b95e70ca37cc6b352da8fba9c4c9c32f7c48fc3d555c837f4cdf3f1a9dd190dec9ea532848efaa47743fc1f7cbb806336e4d04ee726ebb935a2752a79294aba98aaec1fdbee8e77d7d3b1ba83a1e3a2808c91baa09fc2fa0be51f82208fb54699a190992087f5dff61b142d9fa0c5f2020d555ff6e5a4f0487e4dc2f77e374af101810348faf88cff0c3f9477c45c92a2a3c699abae58006ad47936dc0db4f0c017e9293e887cc06702dd81a23f41ed0e41d57b0be89046b8f2f276d424de8a56eeb957fa562729986b25148d5a4d7e02c94a3c54e90b7c343e36c81b5075bece1de9d6189772b00326eb82d8bbe959c1ac9c5425f2a68b443c9d616b6bd3abd58cfa85ca5ee7fa804111726ba5a688ca7368088848e345a5dc34e50c86d05797578e06c5cc336ff12f84645c129da21e93f927cb210fa3882e991048e5d3f30eae50329b5311817e27204a757f1add7d333f2b8fe19dc0a4e369120245e98ef8d471104e68a074cf051a78b8a61a7df36050097370e07a0d23caa471dd59ea78205b48a000c90d54a325d8581e3cf05668bd4d8bf568e1f82393f7b59f90d8a0d79e8084312137b5ebf957fea1b13797e63a6ee4f4295ccc33641fae98ec1545e31b3ed5bbf2418b804e98a642654b373213a54d0a80aadfedaec416b345315bcb551fc145b551809c232d70dc294672475b2322cc30d087d59aed1614a069132941bbad24b95e2c2214f746352af41903d13ce5193dba59450997633efb14f420cb2e4e20132b3b25128236a1778806adf43f5582196cc79b06bd9504e04432e1556fe7e57bf920c56a0a008eb3ab52c2a64bb62fab337a5ab81da2714a09035ecfd6680debb66854dd4b707435ff2e57b3e042cd37a385b13fe8ef882b31b5ec07458279c6b6b524b8f8deb78aaa405e0f3acc7ebe46a7a14f6e2f04b5999c90b945ec49c2005e83115f7862f521378e089ca2c40b40628b5688ebfc4b26dae68cf81b591d40c939845f2f828bcc05b59e045e21d58833b6b87e02d2cf1737c16a3557f72cd8214f081c3fa7e2b1bdc5059fa141feef5f8d8110dc73a962f9454ea2f1ab093f857c7fea5a2fe71b86aa8ed00bb14432d615701086696d9b54b0c514f085527f6fb6a1b590e7d184a7b4ed6fccadf5926494f0eb7089aef87243ee4073faa7bb797ad1213495c7de4a8cad615438f4178513c6a6bc4d05a1606def9823526895b8c7a119acbea78c515e7d6a23e5ea05d7720089d9ed003f30cfd487f72ad62390ac98e46e8a35f890ff4e85f0417e89e33cbe1eb3a2bf8d673d65a7c408d16bd5330e270877d9cebd4f093d4f41a092ae15cb9f3cc217bc38e526ffb78a6368a77d317a7a78d766496dce5c184c3eb8a751213b67629152dfb0571d50ec936b824b57cde8d8eec6fc7f6d33fb4700f12ac5dc3b456cddf0569d7f637b33a1b9c04335db97b538087e582a1fddbb25673497be9d1514336c571b2702fcb50d46cf9d96a51ab8ad6ba9426d02b8db3cf066464fb342aba7cb72ba58149a9eaa4eed6f69f57defd1a4852984492075b74ced56ca5473b675d764ed5588e02d6ae5c1b23b81529f5594a76f158dc4a1bf2a7ef7e4ccffb806758ce7ce6f66fc0874ee0caec765452ea818a83b79e29f0be6eb698ad560a92493a26deb8593b4d46545c2481cab6bb9fa8dc88431f6c77a306e0a689c21bab8a6d365d2a6dac1960b213b0c4f85cbf43a8455017499d2f0e00262a904d06a64929391e9eb4af215995149bbe29f69dd106e12993ea814788f8f37bb04143aaadb4b9798707c51bbbc1764439528be29535d4f07ec9c71baca165581aef2a0a5b83301df3101487e1c60e201c48e15e1b46fd4b33b369526218799abc456431555524037174e3fbaa69cc24b61ff3abcb509b4bcc0f584d6f30f866b5d265085dcf42d6763e56b7c8b7755a346ec1679f12c5718d9eb0d977398db328917c4716011a2700d287747e20c8516f8fd31923b0de0aa136eed421460e2f0aca95cc0d6630b8fb7475be59c62b722f1dd31a2757c741f0cd333b2f0410f100e7e79456d01b598c64f84635c85509d40718c54633ec55fa83b279af7e3750e794ffb1cf10d382026ec22eba4daca7d4d805b476ac8b25b08bb09bb95b066377540bb29ef93d323a20bd6e55b0ee6b75a25db9cac0abc613182a275a9d3a7808cf0aefc1860f448d721f9d1140f53603fd8918f5a2684a5a628376bab4d2ca558197e97537deec9b345705850a416b3778c7ad2140a33eaccd8330314b2418e4aac015efcc0724a5c7c4abc514fa207e51d133621aed63b9dd2408f0727c438aa3ea60558b53865ae46642c7fc10d80244431cde2061f3d31203b313663bc26cdc0d82df014741e2843204cde331c25fd108750382ab265293725a956dbbbdaa10cce61e065608601d18e34bd1da9552c7ed884d7a8d5bc1fca3c5416bc38879ac3f8b1359d067750f916b7fb308ecce26ba0bc46040e914e1b33fb440bbed97dd79eff4d8b1d439974f5ae1206c55c61d18ea7fda3e35972e389de6757a429deafc0a990acdb7762b461eadc837c03cfaab1a73fba20771a2ea264a1f8a76e3ef6902d69725d7b2e1dd4db45bed7536f4cf8b10a62767bdc5cec4f163d61e42ff395391356de6186c2b685db0332edf2d718e48c371b9c0861dc03917c8511381954ce89b53a5763aa95c76d44911a9074e5ea15e985dd93a4b511d4f5d36117d11497228176f136f1763ee52f08f8b1086492487db2f7e5cc3243965235c8791f9947df413042d53e6deb58ddf18e71ceff4c2920dc284e330ae419a20e3f8d33d2e64409ffb2dd92677867bd20893ed4bda273cb61f9360a568de645b4534d9ae324f6413a67cb81bb99a848d359be675d6515e736616efa6bc1ec74be20f16a9cc4b1e0ac36956e9af4ced3e6bbe0a46152ca4e97d5b233ae996a80b8fa52ade01ade461e52c046a75792d82a4de986411d45aefed7b9b3710a1a6c2484d424a217ad996d2ea250c442f44abcbaf5c22083ca35c484e15846a85a396383a266b9b112b6e92eba62c092fd936df116cc9b8810154a141eeca8c2ef6a67dc17b033bfcf0b10676aff736c3e96e375ee57f78b107b80dd7981d935cba9af68be8a4b486e2aa33a7f41c489d86c389d9746b66e61641c1104f85d271ed866602f76e190e56a2554b907edf4d9493b2e9b8bee922ededffa4f9e0a4840096fdc78bf64f34541f187a4132f1ccf1fdaf2e610d2df06453d8545ef061802cf152f9be71531f6e8f44f232a76a7c5ccee9e94d668f2b67216b4a4ab2e946793a56c7be4847fa2c4a7078107913bfd4cb502a1d879a1bd9b2c5e06d9885501fb597d97062fb2135cd73dad087209bd9cf4652f3833ce8ccf4fd09c02ab0e6ae91a97a308f3bcc07755c6467570bb562fd0bebc74705db75328b89527b200cdd6aed9611599607e434b840595168ac306627008170b5be7a1cfe6703b4bd66a0281a2ddb0091b5f5c50334aa811fb845eddd2f38b41e691979467c76a6a3cc486a49426155a6472113901d65d0236710e034972207db8410a4e95d55515d9a07112d41d611ff082fa51846bd366b936c497a6227d82e9acb6072ec9bfcbc6f1c37b477d7872fb74f8237279eb3cca53aba5f51b50fbe6acb6f2d484cd2ac45811e8c46018c3137b49f1e090c4feef15a445e44abaa1be69e7119cd92f41f06bdce487ac77a592fe480c06138eaf7d42abca5675b6ab407b0b86b5ab59c817ce14155ca7cf24665273ed14109c981541ec700ba81fea8488b32f9fa77b4cd562d78c63b4d64c0060631fbd28fdbcd16150b28ed1b6bd318059282170015f717a77cc717ec12c06dfa4355052a01c3397d252be1c1bca7f847fb94539b08fd2a4e650844c1af54cb7817316e6de936e3814e5b4c2afe1d15ce194f0cd3ea45b068624146b6b34980c1375d681b1f384e79196aeb32cc5ee55941cdbf97dcd77bef71975ec9c2997ba12fa6bf07b07107350f13662eecee6290469bbec7da6e8c35bb34a10af2672b98b0c137d228c2748aa9285d610a3b18c6f1e649485525c4e825eca3094c7bcce61a2a7ff03b00416447cf35ba9f36115042dee6bd6f613d3a14394a616baaf0144fd81d760fde81eef81a9bec74eff86af4cd0a1e96d77641d8bb0fd6ae091de49e828519534d4ec7d8b041e9bc278c1ff42ad53e1e59819752d32639aaf9b1a2fcb25e64d4a87d9cf8da6973f07471b93e7e812acec58785cfa47f9a237c48505f5297a779dd4d9835d97bacc77e56128e966e710f3eab1c1e68272ee065a77da561b04c3b2d6f28c0d2b15a8e33eb9be8d1bd3ab2433b09bc10b2c6911668266babcc80d234cfc70432f1f84b517714b9b0a9231d5f5c2c0a54b7d3c922258079aeaec013f28073f65fba2fa682a04978ea84efb582efef8cbbdf7fbb51cf455fab38534d024a10ba944cd6c4424801ab2be87dd40511a8e67a4181f8185ce1e087c4456f265e36eb00277a81ecea29328e931323b6b7b24d8288527326a9d0f01b69af006d02cf4e26ba020869fc8ae19556e201afd5a36c1f7b12414f8c2cf2a54fd2c3f997a2567319454420cfb222c98513f3b85cf616e4090602c4f68d3dfaabd1b72c1743e0baa4e25a4c8a960950d0b6b8c44132075810cc149e64d34a47fc439002328945395962e27363e269d845c0c1352ecc1a08263f4012c4890e0f98ead9ea32ad8cb25e935771795764158b542a1a49f4b8a2ee36cf16a0471f9433ef4bc3032a81528d39c84a758995840fbb71c603933d44b99e973cfd85b1c48112e7805eced75dc448c6b375d50301060225832fe06432091159f42ea80606d8f7453fda9ec15f0653b92dc008cde0c6b2e5b3906097a03f197f7dd9ef41706482196e150272d3f302635806ba08685ad21f0276a0f31d7a0a506f065006fe062b9d65650120fe7250d5e7816ca83ecff36c5f11959b89c0fbb52d6bfb3f07e58fbbae408b302374f566127738f3242adb53e465940e4f4fa704d8560c35cfc101d386c4263239cdfac1dc1078c5b126d9d3e47ed1096a08c3aae84df404cb24464528277586ff228515238674a8ff2cf266141f973cf340d6a1ce789823b36d248a1c24c46191d51c837cf0a067d31801a26ce85173225e5e19ca2487d3f0e43c944671b00d3e100a60751b70df78b6e903ae0b203a0494cdf3e9ced1551de8381f78791c19ec1ca20da2d51bef9f8fb5b3e3f8110421940f52b17c17660fdf16c900cbaf4f73d95fdecb67e8f369562301d2e2de5e735b2a7e91c23afc8f714d5b70868f09eba9dbc16fec4cf5e62597288e7124503656183ac13efadfadf61276a82ef00ccb1f443841304a4cde1d64228fbf20ed5bcbb4d4c36618f4c6f40ec4fe9597c184968a6027a828676bb4e4080d08f135f7f54118011103e6cb31500d67411dc1f8d0436417db2ff308fe5f42bb2a1cd9267e96dfe7ed4a1b6c144fc5901228136b0330605e5dadfc1b58eac2ff25a55483793ff6a91d87bb9f86abc4e3da476245a2d0f85ffcceee26024d8de8d202858af2aa2133800b03d7eb2487a806e8563cc0e8bc1675fc8ce0a41ee54fb5825062d150fb3cac0d4da463757d2054486691088527ff81fe7f041026243211e61d6d8c3300a8ebc11808a6e0555386a255c11f5606f166d47fb986101a389b0ccc3fcd1a00e3e3917dc524e03f1d758caab4cb73137438478f5d59948ee8dd8738173c3e8cc4a71465aaba9669ca98c95b9a690fc058fc893335fa89448bc8709591f65ed233418d11632a9e144e54d2d482c6b4c828292e7967d152232c8120b035b5e84a2819142d21425a02b1b42420b21515237eba448b0c5ef4c2a49486869f7a6b7cceac968fa6b2076c147f5eab9c3936cfe45a7a3a4f794fd69d7ab48ef56eadc3e08ca656324d6ebb96d7bf7e7755d8693ad0703429d9b797808ec1237acb0f3bcea1f1d7c87874f41504866f2a49c70546f4d26a83358ca6fd7346b3eac6a5e47c0475dc86b8a2152c3e099491c1beefbf40ea823f90a87d44e706bf211e3bab535eada90c71ad2747bc3e5ccfe6d4080bdfc7cc2aa9bde5d97fd1118f9d1eaa0a1950b73df7c97be78bb5f9dab101723ab48cf55e3d08b93c2230c3c33f91eaf4890e35db7790fd359c9a76ae0a1990416813c8bf096f024bef4773b42d172ce93e7503cec217ba8436e14af1c125fc0e882f271ef5d2f67f18a099701f21a2c2dfe2a4057af0d2c2af1f3f88cc4e9f97be219920930d83d2a51c50e15ec438b507b1aeab766e5cd4158ecbe5f5f1ae691c6e85187907f99ea0e42e5ac2e17473609ebc735d5a1ee5e0a7653c55395d9b083b469ce724ae09786859b2459fc9d76499b35a6df241e423a6dbae3361fef5474087d743dc634e0f596c8d926058aa8fabd7fc95d40a28f959587de0f31444fdf12b1df6778ffda0e010fc1cb15ee6610196d2c064f20b826798d318b13d8c8c3cc31c3d3f03eb59d03ec8822f87872710e2647401a8ff4c604f0ca60c4345124198767b161f14ad3b125b4387b067721d9826024bacb1fdd5f11d2cffbcc3a4c2e12ea754a2c192058d99a22125f0e138b02560ef11f895548eda5d70cd7dce266689e5f2a190d483162f6c10f6d64d833a987357388b3b84999507a1011958b9ced301cb1c0330cd4eaee821530e5bac80e0af3b2d354cc505062320f5ccafdb2115d5039e23a63ecc543e66508093d5c1a90cf935a1f9149e49c2b4d389591cd7cecd2f40d110103572c5a43e9b211fa77fcf5fcdfc24cefa9ac055c7d421d5514a04d5e7ca60e607c54e9e51b76dfd7113d9365a5901a9b97069085982cce1d50d79497016c4f3b664ac51f9d582e86da236e02311af405b23451b8a56eadf6efc11f466dd2e34020b1930e976dd4a9d028286153913d3603f8cdbf78197717f897832656e5d8b7ec7c6dea98c6571768f51df77b62b0127294638148f123310cd57aacbac9efabb2193886e9a0355af30d92f2a7d3c6bdbbf866ca1fdb804bf805b45e9c30f75654f6d70a613538490fde26f9c99f664dfcff38d4815c462d600b2517b86fe6a5517bd84faa3cf0fa897161e07931746db9e0d09e8249a031f1493315c8e2d3848cd0bb1475cb05183538c8d4b109c1936baad158747e2f14c007c2cd2c6298682fc702b554886cf299e75279e2eb02edf3ea6af61bf32411a8d45dc0fea2a6063f26bc5d399cb8ea19a017e720ea824d685ee532b832fa26a803f20b4c0a6b7c868783b2d830e5af05fbbd42adf052dabd17db8b520016091fa6ab62f8739952b67f020df9b1d4727f3bcb05d98b43dd1c8c6b4d677d5a3528e9f74ccfac32c65ad95b0940965837fc5754a94fa6810952251723277e03cd14e5ea3e370f59f09a0988b3c43433d89958d5d647a73d4081dfe138ca813ec58d784c8dc4cfd8dbc4d9ba046a9fa4445a72764cc553c9cabc13a2a9fbdd23c679468e649d97de525fa8ea1408b23efebac00c7d2f4493962f4e46d36de64ee3c2addcf655e6b3ad41f22de3dc016554dc4f507fc7a18a888cf2fb566dc666aa34fd66a68283f05c126f3afb93638e94bac95ed9c954cde3ee0b7b1f127efb0c2ab6f05188173f2a0ecb468513f5ff8f3e1dad08e0b182138697b00eae4006a7f075377c5d782874243ccb977adbc4c6bbe528374da96a17331b3cecfb930c0a3a78fe3595af9e548ac6bf29450a98e8e2048d3b80112df060cd74ad0c9c23c5145cb80dd595ae69bd54bacd28a40134e8e8d9687f1b09448e60318e503a5eb459e311b1ac59611f0e3f09cc3cfe3ea529e3d5c26eb6484a626e626e4ea7e89d6ed8c8f5483b32afdaaea80dd741e19e06ce60fe710fde477167902b5c0429688220f636376f551b1b9c29ae700d6f5cb6a4d075543bfb5e6777cd008c04ef99f9619133089b4baef00d0131fa17c1d15a138b30582518a03d456b7e1918a88e309ce39d4f14aeba99d29b2d1923dc607f5153af20c75532f710f83f5e819b2d170b2574a22546d2d467ab0501989f2fa17eb38387170d291f5a9287953800568832f82cbee5a1f4936e5bc8f4126a68136484e0bbc31beb2bcb8c34f9400e264ab852d0285d451ba42f8d36f8a31ea5310a98cc152d776a69ca3c9052284f6465149e8506020c818470d17d80c259feac3cd689c97d4cdaaac033df66609a003bd04ba70a4c3c3930ff431658ddee4a5d989b5392655bfb42c8af1697b38e4255d892cfff43aa4b7a022e847347890333a88b7429966f42b6e002eafcc3659d9a602005fd53e7dee28c7b5d0b4ef9ff72c892f3878683799cf048d4796ac486b9679c29febedc5ae1f17a54e63d77f452105823f7d75438a9c524a8e2561aa374d03208d7a24db0e8c89a469058d0fbcd08dd8c51c0b79a7eab120fd26045219ff4f56dd8d9f8adaca19c8750ff6d17313d778a5bd1cf88faaf830aa5802a2b3e55f1dccede12d8bcfb0ba8dda8948f223cf76bfcec4f14d0f40deab4ed572a14429c9a74dd5345c3b8777da29d99c7f3cdc7f0d2fcb3992f03f2f7a646293e0d64ec0fcffe6f170ae9a4964e4ed1e66802b580215404850d54fc5986c0a4098df8b9eb018f570640f35d923518837e3d167d1e15e241b3aecd3b0bebeed7c0d8f6ff661f2c53090fa3e7861b2ec784001c8b5fff63543ab3e0b92ef7675669a6bff419bd629d6929f43de9592e8bec8871d0338536b5f1a08606cb14a9deb72e0ce2086ea6cb381ec2f0fa953873b7542a4919ed4e83f44b2dff0f1fae9dac4ff07f02b76bb1e649efaa2dfdac7d381b28007658c740d0b61e52a2f2d41d9e8a64c7aa7461f355c9435fff163413baeeff1f22a431f50705d733b847e605aa5e2e43820483034fcc8f7a6b517cf150b3d0840bcd94a071735bf8df3efcba3bc07b285ee47cb792d8dbd976d5ca5d4b0f0863b3edb834930212a08f707887af0d35c07076919a566f3322dc4fe7959c88570ff8b1cc781294d518d61c2e2a93d43d8defd69bb36628860261d0f6e431b98689751bb0c7851fff9ef6ffa914500ac2ada05aac6d54b49c96a04fd25e38546164818dfd72eac6c4c77d6eb0701e0242db1b670b82ea613600323985c379df292298519bbce9f47e9eebdbba487fbb8fe423c5204d7d821ee8aea693442a146e20880ca445beb0703f8c45b0498f9ec91acadc9c48fd966578c3643d6a465379194dfd11f70f1562a8ffaef8990bb34c4a03827a85e55aaed4b0124c966f9d72464764b176cc3ecd1abe874c7ddeaecb90638027288cceebe9ddaf05edb6018c244e5b87d6e4ec06326f712c2eaf3db196d032380d36c93554b48c08d49837a29be7ac53e8489ab40e125f7c240d6b4876a80707931e0840aac1a47c0b572a27887b5765431eb435aa4c54bcfc06950bc8f5d31525ad8ad0fc0b12b7f82b12135a3cc9e8905da61c43e23a6aa786dba22146cc63884ed8720de5b0c1e983df7bb03ea31023330022b28a81e9d4b5f6fd0ac40491062341e8de69423df9da6edb8c422cd6b5af0f157938b0b77f573c3f695287698db44288f08e43a7b508301c9041c1d07895bf047d3c4936a591714edce30bba755d9fd8e151637812eebe9e91ea9159260f245816fbb75ea5313d2c839258b3cd9c00b950d182cd43f3a83837f7f95dda8dd3d06434f9dbb95aa21e959619c652268883feb34118d17b355d65dc6105e751ba451d9dd6360c842ca29cceb157819906a4f31b82b377bdc6eda5261c1abd283bb5266c3ee5e1b49175c1d34a69ca961bbd73271c1ad481f8e8a99df58ddb4a9d1022bd3056fe1e6f6409b03dab62acabead90c2ae2b34141499acd61b8a96601fa8d5363b5a3c7da81ffb66801f7aaec5c49769eb1ad07a8a43bd8646d7cd74fa606d67ca11e8e5613c3a4278e84c9ad13659403f029a9274e04f49edc7569d543788e2b454fff3994e801f3c37dfc053cabba8317d083c4ac60a22904a0c31122e01363a02bd4c26b71e145d74a287107320e81949b39d0952a0a83590f3a45ac0f8ad1ece13520511581af0a818a0cd14d09c79ef128aa4651b1fbddff0a1f0b945801b811cc44323d60964f0223b0f26548aa081a76df31729d28925d3f6f989eb61ed4d9ee0a64ca18b83ce3e5e8f35de4f50b1e5311f9baa0595a7d426205d4308d640b1460f096031bbcfa25795ea00b46f022fd92a7afa4a0b4f6a1d6345345afa133f2783c339c00042b112be51a90ba26c7b0c4648349150235f4d1c949b0c53a1939e41c4e5eda983dd65568c45e8beba26b3dd8efaf9beb2e288f6493f5418f3b8be3e0aa72a8b573f4be9410e0b0359ff80a4ed23232a70bd9d7a691677ca627e547ca8017fa1e6511087c87ae513447d8c2bc35ce6d046f7ad717bf22e87e2507590f20e162aff8b10d25258225b524850a4606061a65e964380608bba6d5e3980f953b7d77d99203f4511fff386debf55dbdca113c607626ffeff678f19d71d31cb77902edef1f5cf0326d274cea6b9a35fb372f66b871d5f3fda20c6d17670fedc09828a9773751f6f9c92514ea0a2db0707b159126d4f7b7bf3449a1d8e53b39152e0591a9ccea84a0407bc060d1643332ddcec95b93627cad454c7996d91739da05819fa5095de7e3beebd982928791103b7acd83295a6952db30e54c814c4c66cf444bbf84c7731268d619e51b79bb4c1f811aea23782f1269235b58b1c4e6c85b5a945c856c23872bc7ffeb8d5d0b67a9885b5ab384c525c8687cc36b29a51f7b3cc3867039f9e9c87147115abfe7fb731cb4705c4de735675bb8ac3149e39ca4c56c223d8214b7a91430fc49bb6a77873ac72cd9d416bee15486d25c7f13212027026c2e5169b547220c54822ba5572f42c88445805e34fc9d18cb91adb3d8e46429533ba977b053f21a75416c424af4638f72b67aa20d27b87d3af122577c6f940e3ac3f1132d031cf2f1fcbad76c6125c444765c09d1d24d15561841b5b98911f616110cfdf71e699ac6cf4cadf483641937f5d0e569e480787a5168acbc5a752bb231337c5f46e79d3293a8802d5e74a638c1a0b9ed0a6721f9c062b5f155314caec5afb6ef358ff25fddd5b5702428596e845281058a1366e2db573d7ab8460cd1e2f928c8acb01bc65a7608c6275f1e1b4b6764c196665ed58400937461652a9e72d82a0a2b040821987a97aa46598550bc0a86020aed149325091e70ad081b02b4b54546fdf23c6082a9c852b83935466fc34de472a816e751f0858340a4e7e3d28ae11cc2e700891a6ff1f5971ca8d1231ee2054fc0a313ff5ed44d606e22c488d4be862fd6d29a483f7233f69edd40501d08db82f3d08145a2176b8146b297aa2cbfce29412364765eaa91cda91f9f4bca41001c739c0d2f316d0270b2facf0578f5ba21fc77a2b9c07ea784fa923f1e0554fe1ac40ee65fc044f1974471f9968ca4c80c32484097f98a2d237a8ae241e4459f13ccfb193c15fc0c857290f7ffdd41e7ecee079ce0e040854fdba9078ba352527883c34f3ae5a477515841291234fcf468aba74e4fcbdcc1c9919054b80bb07b371fd9ed7ed32068b2717574b70c47990a39bf5197643e07f03ff488b929b06923384967bcee4544bef32fc1960ef9c41c792234432f35fd72a49da66d61faf198eb0ebb9268f2594329356043914027360436fc189d160a8fde9c126a1977133f3a6d8606d09ac0b38381b6cf6c709041cf0f1926e31109ad9ad1b1d7a642464a6df3e730252a9f1fd3907f6bb5bca8db9236be2dcdafd2efd27b38d50a8ed040381ce510b13572e292fb702be19ea78739036d75bcef92f660f718b4b4760de8449c22db76ff0b9fb454b61f75c95dd226c096a8531059aab6edd95156f5bb6772967a9d6237f1756812fb0e256f7aefe8ef7a32f2742a89252aec81d0e67d5651636df5ca6bb0311376d00be9ca541fcb950db0736339627b2e1ad5110a30cef22a040e0e7d90abd368848190672b6396ba9ab1b7c256b250137d5985eb595d996999f692acde3219d72b0454c30974e34b6a0f1c433dfb42c0d286b7be6efe041f0b7c9fbff3e66b1fef4674993ba060104299088290428af438f07ff688ebc8f3169371441b0c979af68203f6212e23bdbb9a0aea3d9319d2b026602a6740950283fea0d2b174712580710811b09626354d30894dcd81237a4288adc42cb70429c8848587154961ff0cd1fcbc4464931664c69405bcedc3c342c5aaf7cff1d60f7a5cf1aea9ad38faecd08370a7a1913a617635a1cf6db6777509b894832ed1e25e0aa5b703665905ea81b057717ab349d384a73830450ca8d0d131e59f8c37d165c07fb94082cf6d9d36abed1d5ac5b2f87928b008c6fb4f5ad87948c1c0798bd836a3cd2adffd6a740bfd958d69f512c7f4d83a89ff1423ed42c99ef982199c352826338d72aa11c2cd0920cc388592767b7893f960f9a8be01889b4893ef31457a3a7b86cfe25987be0c1df8abc36c982362750273d4029d28a40b23a890ad545f5665b88eafc60b3391f7e3465d1b1b345a817342250a6062e4b0c7687105b6750335fd8caad42437449d4c40e966e92d1f0d4e12cfa6581a5a43878fc3280a178017a3ccc35eda2ab026aa64125967f9868880ed8ccdf2add06241ba2a0e27af29681a6d820f41de9d9747049c0ae2766c898ebe43fe388eb8240fa9142d0cef186bdea2e9d73b8fcc6e194bfb694cef93aa93a101488014043c55bfd94a8edf50b816c286e855aa18cf549a59b0876ae0bcea75476aa2e8ef712021fc251321fa05fa7fddd246a3aaee37e80f12f4303368cbcf3753026d85e9d520260d896ff63fa6676e6471deb7343f046bfdbf2d44035f3132b78c0a9649210c6ef7c5171c9990a9124706179a0cd9d7020c5ea9fac30d54c7af23be473f821af4e2f5e5ad8964a0225fee3916431d6bcb1b473f4c53b98da56c463d52307346795a5fa7c7b9285113ab71eb6e9f6120aa5fbbc1272662e3afb961a22e5ec3b8f2fdab76b336ca101945f86c0753a22cd9456984d071bded3a5c0b4688213a8269231d753df6835b8adfe0861b766f2e326b5be0345acb544e7011d692c4173e4f11e225bacf78ca31261a03f13b9f85756382d75fb9962917dd49af0e73403ad6155c9514ceb3b441f1ec3ba306d543a0050823e9a60ce7a9585eaec2fd8690bbed11f2a1fac39eb3ea852eb796695963c188f0afc15095110f2767ef1cc9f28f21fc6b73f00eb665917283300ba7c480c2dae5dcdb2a38dbf5c8c22d62fad21633fa38402a29942160ea965a4d5d2886fea46e27e3bc935bafbb8b17d99a8a06a4e8e6043ab07dbf37d7d4df30f74be79e2964e9955802eabc2bc404d9818cbcbdf0b94a6c3870ed9a22c0d95e1f5de9baf73c51e77ba45301efdfe2f554e2f49cc343bab02a3c954b6bcd4143ecd12b96ec413148558c261fdbed28956b7a6089898f7dc31f387fb5e6d21b81211a4cab8d3af94200e080ee796122bd6e9222fb369973102f61d2b25bda5a2d082f8c6557d4cdc4da2b6bac68f879ba994e2a90b8682deae2bf5e7451e4686da7208d100539b369e271f5dda65f94559423a8a2077e6a1f06f8d38877ba8d780bfb6c7c618fccd416e44bdee261bb0ef637103ace8e3857d7ae7c8d50b579bf90a97d68050852b9927a04056ee82615f382fcd319c2e01a3b69112fbb8d3f2fd73c13ae9c91d75af646a0e1d2fe2de92794649528f11c30e801ee92a8bcbaaa98153696827da235ec74ce6fabb89c33aca65a83df95c325e63a703fac104dbba6f14143e1b9fc4c77553ac37917e3512ed1fb63e95db1676636528906a29fe2c98aff98ad9e2148b568e664c1d676a4a19e1fc6cf49c804de3ab60606436cdbe66580b9a68648c402cd29629868a6fb50dc9ba955c543eb7f4de9ec57637dda5f439f348ba6d4cd5f8f3af063e70f553bd0081d59a7860ba8a2211b3c1a69fa9b80801d8ed662e1366788ccc0578acd3e52cde64fcb79990678ee0a5f1175a394f1448e4758efae71d436512ab5fc0eca30c1153b149a587348f03447e633ef0a90de0b138cadd68ff1e53898692ee88deb1e22628090338c5c4457ce1ba3bffc2cc6231f07374817dd6dfa6933f6ff195ad2d583d258d2060e0c691b48b053083c73ad2fec5157e9d79fbe00c09bf6a83a520270ecf361e91d056a0b56cd5dcc1d290f560ee75d6635deab9fa174b44659101fe66b34a4a4d155c0b482039a27aeedb142d02dca2fe8fc34294d87aac22b2f95bd671ab6339449e5d5ce73c99a3d53790f2475678893dca9d073017a30fe4690ad538898fae52edd9c1ebbb057f04567d3f45d2017faf1b9685ac1e248f0ac6800be8823dd9d1dbd1393ba46d695fd96bb4df7a92ada7b3c69ba1399d883191a2b420b6b3224673fddd5d01aba9d121d921e6170f8af7c07a1dec99d6624d3568af40a232f22b48b071f5cdd50675bd3b87f720bba11b32a7bd7df1072eb7ad54c2d7e68fb927dc96f13b841c81d544375682dae50b65415c0622cda543568c4847d7f6e9048490132fe25035823f2e282d996e128a7d639efd0ad0b475428e9759350d6210074dd286629608f6e0087799d7bac38f7efdf47eb4dc4fda075f70ece4cde8c9aa3b80010a57d75f9a59f5e97218011178706be3315da145881bfe63b0d057a1b0fa89909a7ec24651fd842e875b801750462cbc4b176c7727ac676b044ea731a84b0b9fc10ff996810db4839db0acc2cc9b11f75f7ef7e00d3d4352acb951ecde288a0da03967e7b092135fa2d5b0b8db8c375898289f2a267e2e88c1e34cf6576a75fb9dcde364d7ccf9be20679604df797b8f64078c791e298e28bae08282bfee8e798dd3b0400c9794e89757157c294fecacfd7551863c8610101fcf62c9cfa7b1c074c573e1315fb57e8187798fa7dc4b48f574b889aeb5278329edf999cc624f5b375b21b9ae34a4750802441494ef32c29ab62df67f763f4e2c350b3efd562c24ff1f8bbe847982d12bf520227df4c24f31cfdea4d92a11f98af50850b658bcbaad50ac013ea976477b8e24161bc4543337fc01d98641d7e5617af22b3469b58278aeb072eac5f7ec41f4dab75c1256883d3c260110c54e21b06ea5b3a998cf361544efaa6e37ef022c0f901a6ebe0b9cc88d99a5586b0f1eb6ab7dc6c71ddbb230006939527092ff537a66f23a57bfc70f0dc5520f045e3566128bc664fe9c318dc86501d22d6b60205acd7321e7042b99b6907a1b8875ffccb3346638a00242eed73c40713dfe4c8d0ef02c7227d8ec381c1f02e6d754de53445ae5dc84b2a30a58556e7090f2eec00679d3967838f17bc86e9a6ab0544bb5d03df18dd21767d6d1f23594a4ed88eaf0d3c5b4fb958edd1d4e4ec6160ab835e35b6dbeef929025e1c56ac621ec9cbd753c9b014c2c5b0c9a8c2afaeb4752fc8dc9c8a4283827ba7061a53f583ba6578e48f5f4143f5d17bf639bfd482022d1f1640c045e99cc188843d1feff0f5deb8fe9b7325c980e5f9078d37d89415e265d871426cbf298c0b3822666596819097c8d07f7802997b68234490129068afca0724822b2697dad134a4bdf8aed1f06be417c8f83105b277294613829309305a5c9403a702a2eb8d4f488b4e6f418b3f6ed0b666f5b6f0b994295050ea987f80de3d9f07a23683f405545080b4f854b102489aa2bbc7b157f94e5900d9d0ac524f8702d478de883b0d847212b3d2da1931e340501caa9b4235580581575098d4c402780485d57331d014168bf81d5d08ec18db16dc8f8d794caae6373fb5a128e81f21a3b8e0560466368ad7b267dcc7e7d21be6d9400232ff6f02afa64e77f590a1fff6eb2e5965246be945226191f02160241023bf48469f4c563316123f3148a1f8bd96c1a168399680ca6e112933a3b18f6311dea82c9b1de2253a8c89882fd0f90c5a40ece0fcbf961b1fc16e3b83165c0544d69cff3f603cf4d09ccd39b504d208cc4331f791ce38e24e252c464d7e5b0e51893a54aed3af584494c623287494cf6d81814e0cba80b0c93291c8483684cc8ebca4a09734f63ccc2575856ac4a68ad85d952b639f3e73bb2d6d97950e420e4bb260467200f7928721072f061200886d95a9bad157d425eb90bc82b9701d6978b494cd260b1efa979b62900236c2222a0279fab060f3e1b2f22461f439c80e20205511c31a28a1b5448220bf2889b12b41e3d96bcc07c84890cc9cf1436a2d791971037560d8888a2fd9148dcd6a96c54b8385167ad1561bcdda28e9be2d525aa8420a9fbbe8ff47d214d0a25499c10d97a289275134f67b57a2f67f636994cdfa22fcf7a1fff83091395cd8d8a496725e9fd75a3ea7a67f1743002dce8009cd4e59f0590d59180ba030f24dd6fffbd578b307a4f59fe023fbf5cf5cf5538ff8f3c1b0e2e4748be8d4617472949c9dbdd7b2fbed4046332554e693413fdf9d166a231300b8cbc91fe544a521aa523256d2b175aa331ab49a324a5edd8a249aa721525a992198d9923f2ff8ec021c01525299f36db0257d336c13cd1b1ee9832975722a94a8b542ada60aa274a53324449ae79e660b7efbdf85e9df10d8cb9e537f0cfce364a7ad7db18dfebfdc81b515ada54944687f22d74c2c4ab948501188f3f232e61c8a1daf8533e49558e877e0ca2e172fcc97fb156609eb00fb844e11235f3f5d65b6f1d714f8f46d887f95279129e254ae01297b8b4b9ddbc9bb6791197b844d19817f110ae95a95a4e992f5557bf7568be9a455298ffd6d16387149e45c67bef784703eebdd7e6fb8fc81ff7dedfbdf75edc7d7b4cf5593934fe3c502502e047d65ead18e80c11dd09a5c82e602de79cd7e6cd76535bedfd5bdb12c3d6bf998dd61a200a145c132088e86480410e0f0b7026ce565e01012b3f7039dfe6dfdebdcfdac769eae9abe5a06a359a1a95b53b686a324c30281c5baaf29cfe8ad148c01ff308268d9bd75e2ebdabf4ade7a12eac9fabd944ddf76a54c719813a2e488d7a8a5af3350892c4eec3d85acb0bd098e6a270462d70f7b7edc7f7defbc358060cdf16d5592d59a62a4afcbfb5ff9fb5cd238cbdd17f167df6beb7666688a52506b7e275592d9b73fe517e217054f9cc59730252bac9e35d6fdf7befbd2c9b57de12637baa8ae9f7a30b819b0105d5663ffbfebd9e3c11a7c351dce963383896195010911d6640b3ef34a6c2fab34633209e3e7bd8f7996d364955dc45129bd186e66c064404a74f191fb00eeb2e9f3e1fef6163f3afd495c0fa32e3023f650346cde61edf622df9e6302cff994b891f50c3ac0016681b20a1f68c74bfe3e46c1a1cda965aff4c6bbd77d8dc586d67b82732030aaa35952166f78af63fe760b11e18ec6690873018c843d0d3a0fdcf0135fb7ad7db18dffbd5a8f16d6f94f5fc90435c51c2723bae576ce672b95c347346a5a9a79d5c4ef5a22ff5459808d41f61cea89c86c668cc81802aa9d5ace51a6b65e3ec899e941fa09bcbfb816c07800276dcc648d5dac57ca97c8399f9ea7f100579212524555f84e19990fa17fddf3a46449e2dfd6b43002e01b9e694efd5acd1ae347f777cee1ccf43a210ac217d39b36870535dce39eb6eeffde5ec42e275b790be5207da5caf989db138a1e7d33945af9b93d4e19600267dfaddfb4f9928f2d92da860a993167cc5132f464b6a0a05f91082082925a41479708b5c5f7b0e1cc8299a481105872d38e802862328140df1f9a02885a215eed0d3232b97f26bd721888db284be4251b2d0451d24c1467451a2b851aab82d30261ea3a56ba1a4164aad502e4b8068f11272ebe2c7c6ca0584198c00e5d081ec6063650a92e106d11014248804279f623b3b571ce36e9452796aa9f620b5d65a6badb6d65a6bb548b0cbce864ce1b96c006285ca90570d4b5a58006939a929e2862b8efc78e284253f0035c16344e8092e4a0f49bec42c9ebcc42788b81897a0b506082247d67460b91dd72b36f34623cfe5da28fab293cbb95eb1ee7ab9723bdf73b987bdebe5cab96032d74b87075aaaf21d57cf4f6e845d18bb5e78a4c03cf1982f1595334fff9a312811cc934e9d2f95f798a739ab08f3a572d7c85ad076185b6b5fe7d1e579de36790fcbedb85eb13a0b8128e76c6dce1997b9e55ff3f823d67ae34b73f6f938aa9e3e716668a89ef0107da92c63799b9543e30fd058de66e5506dfc19cb1c73cbbf050431c6b9865743e71a98f35c025b6ca84ba2a228480951114d8c085971332224d3dcd459addeadfe3cefc397feeb7b6f544c98b019b9514d7db57eade74c0e1d4c98781d8b47e398323727031e16688e63ca5ccde7ed262e07c77bcf334d19f008a8c2499c729c7a12c046e539103850043e573d8d161f35a5451f905f507c167da93ce56eee79fd723ade2e049fbfb83dadb5f6fedeeffb48f782a40f247d3693ec851029ba11b11c111e5c4e67b5642157e93de42a61d87b0e0e876bb124b0b55a8da646b583a6e622c30483c242c90e9a9c1fe5799b66cadc130f5c0dc401f9db524dfe48a0384922addceeee056779c1b2a2f2ffafc31a95300c7b18862aff59f459e1550566452544c93eca12030f2ea7b35ab2deb5eebdc481a39e3810304cad66d94b9ece6af592477756c7e510e17018635ce7719161aaa24c89f55cdcb5d806dc0fd850978b63ca605e790e1c16716e54d485011658f2012fe63965e7c0bc959add9cffd6aea42af7b40906d63f6f9ba9b35a4d684f6f2dfa7c1fc8c2e3424296d27a5dadb57eadb5f6be7bb5be37f32f064dffdfdaffc737cc69e95f26eb3a2ca250f5743b3dcba6dffa0d35652e3ffda8c0a4f141684c996761ce90d51e19cdb26ef42eebf9193b2bcb7a64fd7fccd32ec97c653d54d66fb25b4488520694b10c6359cf679a99caf1cbfa9cc1818037f5f1fdb2aebb34ac4f9cf3458f6cea697f3752e92bdd3b5e0a43cfccd8dc3cde018b36a834ac9ec9109230800263180400c230144371180a8351326f14800e4e7c3a704e3a300c4943914824475114044118c42018630c30c010632442089d980332ea7ad87d158396cbf221604e3599f71aa8a2c0a0ca0d7b6b1ac084d57bdb86969eb4502c690ba6b4dc4d8d891cbb929b6d050a8172a2e3ded93998dc2c6d88b387c83a13402fd19073bc22d98a41409d46418e5ea8589f93a08f97892f7492f9278b49c09d982086398e55cd5c1f84be977bb1e3079f5937731a991d113378942306d6ba46035bee4f1455c94ef20bb29b43766ae38c332210c09a745bbd69263ba34e23a57aa37b3318b489758799fb0e0102886f23279f83c087eb9344dc3cb13a184460d0768f192259fe1e506713dc95ff67d99ea8320a40d9aa95d53e2d23095b8ebdafe6519075a9fcf5b6271fab0f895fe0439903688a9b40e8aeaf1177709229e34dca964fe263c1a6e884cb369741f00876e6dff9d1062edc2094849f81441df75f07214a86d237709c54d8226d57eb312f1b25c71148a1f030502afae886210b6ee9bb4f8b1223e8d323c7cd42e47c465662a2815548f1e1d573ec2c14d990b6be88cbce4a37472e36ccdf5a42adca9f910580821b2f533da4baa2f8ddf1df067c76c25cb97a0915892f80cfa046d2db7444874a61006fe9c0346392499ac68ba7e53afc5e7736f5781407a055b31e7a034d07c9e21ad7242b1d53e8f8b069a8c92eba68121a8d8e589a04b4744316ab3763b752aa5cce650ef68043de418b260848b7c3c61d86c168ba77d62280d8c231bf969ec2476c57d119f201cecd39521aeab0c7b60831c00201f98a3ee3f412ea264090147e5ac91b298a1a427fc4432cb3d5b9a2c25ccb3487b5ddc861e19610ca6a3f4178a8b60750622101d9c0b6d44527da21c071831939abd4c409280a1d1f0a833f22009109b7847675a77a8a42a0bb4292a8efab7ab4dfcaa4b75d61954df9eafc1337ab060d4a5782682351176d54106e785f17645b5333971ebab6a5dd81cbb8eeaa3e61597a2f853ba59fb16d5151013d528ed1a3b238fd67d2feed6a7354e654ab489d7e05b31ace1cd3baf80dcfc7ba08e30372bdac2578676de18f1f9073c080abe734e315d2d010759685f4c1ed252e4fea412009ab0cd96f1f518013ace2be938f2af508812d2ed9f6b3e630cbaed9456b967c8821a5961c1b7c6afa93c936e2388535828ed81c719bc077f055cc8f0ffc08c26ee6a788ebe7bb675873cf9cbb1205f9fc577dd72048bae8369dd465c8ac30a2c5ebbf3479fada90e52f894c9ff5a18819dacf5128746b07e702f89e37a8e00a0b45a2bcea004f794ef7c72f59b545bbe62795ea6500a7ba09a23bcd65103a8599c3544272c94b2265c631643d321912e488dc7a67760edac29c30c3d2e18dd0e9394c6213a55a978307d844b5dae2a3487c7a9d54c37bdddf3203c136c47434419d651506135be77d8158773b6742e638a7f30e286420c417a2d7320df2b6e89ff7b43eb21021f919d9de2d1d5b94f9c300e0fdf3a890ff7b2e54b915beab0a2d07e81a8033c92b1abb05bc0d9ab101f20ef772263cd156795125452ed8040c8a5233a43879ea2a8181c0b6a0559e34805a29a12fb65843a36a624c795c6b12d76b0774676222d7305d1ebcd206eab748429474e96a2ae862a4d158525d7bd814c8ed10473487c373551bd2ba0e485bda31c1466c0471ee8efdd50b42ebee20ce2dc0a578d002b9cbd37fcb6587dbd5265484355cf949b19c5f0a0191338c09ccc6ac9083b166b156d0e8b05b89cb902f98cd1ba09a2e372fa1765eccd353ff4689d45543c984fb8744f427779089c242084fb460b364c654a60aa61a84bb313e28bd7cef4b02acc7777f3ae918d59635089c76461c262e934a188143b0833bcf8fac4184e044c9e40a2502d33619c5fb4d4140e0e36ea92af21774957d12d75c902700a43e73c0534cfc49a4b201d6b2136317748451d6cef22aa34c5a7d72f03f7781927cbf4cc53828ee21a8f5884a13f23a577af7054ca0982cd14c5113c8d98bb0e1d03a830e7ed5412b6d0640273aeb00f4c8d7f162fd1d446c2f561eeb36aa52d87d053735bca33d9fc46ec294cf0bcd7e8c8903f4c53855f949693e32316935a9d06d68c89f91c6d7a3bfb107e6d7177d51bb6cd3381a79b7192393a47354fc5d8c0faf1d23dbb0512ca5680c013466a3f4ef603602338231e6a814018b12730cd35e865c774912ba60adc98406394b558c1068b391dc64532eaa06a2039fade2466a2c4628e5108266b399185e44e27a3b378915dfba8dd4dd36818d868345bc2ce23ffa5ff73ab578b630a542a90a4d3528bd5858e201683b01dcc6fd015b4e9c6302dcb7a6cd318d80c551c4f6707f57ca2b2438db17871b8158d5ab811382aa43b0c72834eecdbcf36af9dee3c156da1b64f4faf6d8ce355cbd1ec096cde5778f5a572a1197d5008e487cc3842d3f3567737b5a955295db760dbd7172685f05c3c8e909a0b105101474ea9624af627ca734af82cacfd70ec9f376f3037d4fa3fcffb599b08d6be8ece191d3da15e7b6d872ba330b8c6afa1c4f0b3054a079c6d54d09577626d4353f3c198d71243d3ba4a207f6f827253ff6e6820578007dd08276ac44482af403d11b583547dc463c3a72843404ee62f8b97adc2c82ec2bf48be80a928513e18f1f8e35b74340a93c450a7e0d7e4b011a414c4b539580fe767f95b6f9e7e6975b102865d72aa2c46a625658ebc00ed5f93e59e6cfffca74de58a59325370601e1bccf1c35b1578b47f7d7353140ddf05fabe2353643acfbd6b8cd39c7e85ca6db83a6c5d9e78cc28fad72964bcb31305b9b0623bdccf5f4ee3b51190df8695d27592005ce7ad7b5893b671299ff23a1bf747e75000426c7e14a5106e87cae5cfe01e51cfb5c790f72a2a86f4e1859e281416bae98004327235a6e2b3c87326a0a2aeb8067057d3965f158af6f7d218f77a46d22a893e317ec815c3140dde04c9160422733c09328dbc95af6e72865eff56324c5614a523e6e026ce280226070a0c049df3e6b001450dadc776b4add1dd0f68099d4f2d887ea0d7ba16d9d1a6721b7d527e667d578b214ed21eb1eb672fff0f74e8403286424584c097a7ca601db90e933115b50bffb22be126e81e95634036852b814bd3b37fddbd2fec426f2323403087a5ecb190a551896c7d10c4a19ca8058b37890ec4118489b751ef7a1763214548cfe566076da6f82a902e1f42695a4703b2d11c648969881035adad5002e42e32706045acb4512cbff0dd4a681cd6bbe880cf1c99c41caae95218ef234796580ba73f746216e340ea4515eba8c82ec776304b5307485d7b0d040290311f1d91a0819681882b5b4545ce5ff68887ec13dbfc97ddf23faf81b9415a323f49c03494d663f3d09af1ce00b04ba40b2e9f0903eea87d2b60783583f4dfe542b3afdbdd68cfb35c8d4490060ceca13fda748cbc32d86c8796c1eda0b0173e85433157fcc582351bee071ae08c67a4cce961b7b4767c5d422e7482d47f17bc313311819a940d77c70555de5cf8c5cc83d32827e10ab95d3419907d52d94d2b3e98aa1f70bf53428af557910a2b0cc0b7b34f8ae13d5a3496fe0eff95e5dc45bad5acb7b61af06df75270e227cf828bf58e440eec1484964a27638d4676845119ffd1b7f01a7ec6f34818d7db276a8f69022b33b5410562f6037525013a3a49e9828989c942dfb0e03e186060fe8a6bc48c90a10e2883cbf2625822e0586e19824a0ac574a65e0089e0b9a0e96eaf0c200710748dae138e5b8f902c381c903117e9b3fddfba688f6712d8b92d80cd07b01ab9ddff0fbc5fc66af6e15e1155a95414a2822d3a36a826f2b864b3e458b3b856c3ab24b5a4519e4cdd413829601ff173ceea17ce1e19f2e7253d1c9b60e2d6dda98afd3eaf64de2f8790cecb3ed635174961956a9bc3ffbbe0e4b6a686a1c2a6cd2547a7548be38a064b93a9100bebfc916bc0af9b6223a1d6540e71f03a234acc8a129b9e5261ef94b64129d38e26bad4222b0154b9cc95c8d31e906b8cbf5b6de19da4ee01c20254f2ee3e6fc6b3151d9ac922ab9dda6642f482b8efaf0429991f06848c9731fbbdf08266aec37b24e45b0a0b0d5153706831c00a091939822e776c404adea44e220cfdccdcd8cffb2fdbd97cc165e3c6703fcdb4b131204fab3f73739186cf0f6825db13c18999627970efcc20293ec474045a3a8610b91786aa69951ed659d49dc4348717a281722cffa813181efd1b4da3c377b9b84596d9e3d003113ed47e62045abe1b50112ccf598005df9fa795ec0a66026d574875c250e41b37204d57693490785c69920a669ee74c9a75c1a27f7574130bb69c27deaa6ef49d8c29180c74e3afba08e6818277989a824ed6d618ddf51be052e6c2ed87df840d9fe476f5a52ceea75f99afc1241c82440edc52cb1931da3454f754c76c49220e111fc0efd271038841777c47d7d84a4ed5b10be216ea11fac384a3d027969d4671fc920e906bf1cd3ca6cfdf18650de34ea2cd87215f653c5db84c67a26a0893aac0c07b1f2e92ad5fe90367c272e478e9c5a35b292da5207391c7e3d2edbca99245042c10a9e261fda88b7a769ee89e5a64e5b2cd88d1c6e11af74f3d11672afd3d635357eedb20bb992e3e9d17497a2a13cdadf6f318283b4ed6afcc423909a2695290a69bd9c3bb48627ac954db1c237e2524a71a40135ba519938fa859c48e8add698adf7b99e525840133916c136e2c471894c64a7671aba0f5026d9a021b15ab61f3c20321bc5895d8540c0c7022291674dc65120e25e3f605f0bec0836a865bca500c19665b5f70ad00728c587e892a7f58d019bea41a83353c4122f44d380b306c19c00cd121c47f505e80330be2f8b98af12c34931c22ea608c608b3312569e218013e14a680e11fb36aa133f51d74bc550cf29c2a192d01e329d661a88843794861441754ca25a4d670a79d127f984579bc5fa04e654862e1aa9b0de2376a0acfdbd5cad3f82fc0e5a854c52cb8a035100ed970d35a21c58a28b39d65dd7e1bfa7d6602d48e833b9c3bb2b2e151c8a1f5e820a8b241938b8c0131b16a5e375d7b691ff49dadfb52d22b6c29cd435faddb48ebb2a85ae470d043d253f7fecbc3a1ca2fa3e57e806fa36783a9c18659e0641718f3994828da676740bb28e7565d1da1694af36d5960059490fef5d2e2090bf181f371af802a9e6c80f942e55300e7df3664cccfbf1a079520d82d4fda4bd8cffe2eafa3dc985af7b636c74e26c6427896ad807cba114929e972c26fd59faa4c6e84956775b9ae5196b891584c363124ca44d9f8845811dd99656217812eb30b6e50d9d945c1be1d675c1fb3c1588dd68a359e15e3fb35228030bed570973582d08cf5ed8cbf3b7be71a9a2005736cfb8fb7f22a3e9b089c1c83b6192b6e08fc4148c96a3504b757ab5102c63b434185ee0682d923c2a9da124ed2042e965f83064314509829bb58395b21805805fca607de7b97eea93875cf44ae6813654dfb79e14c26509b2e53c5f69c4785a14c6b9a783f01eb62d45e4dcd7db5e412aa5f36f204e8242842179bb7b206f999870d80ae2d5d40976c7595d7f95df4535ba5df7ea7bd482ecb5ce2c7dd635a917034e5dc22a42a25033648d5449573e9a8d6cdc8a012420771f88e70fb8cf47624a882d4c10ae4643d242eaa3d032f50ccaaaa18687a4ccfac27f6a368367fd42f5e1b3862748a6d0712ed6807dd43851b48113bf78468961bacc3328b789c3c0f572dc2b3b2c098d3a9336758382107b01930291daeb8460a134f0d36df37cfea15c1a7fe57abbb7281c329520a4d597d0903e500a3cc9489430f6b0a624c6c122fa34c8c7ce1789a2ba42353844bcbe186d3ccf9951a6e9001f5d08a1a694ac9b00074197f9ad06bb0f8025abad288748db0341c91a9cae4bdc581354a4b95a6dbb840794ac323c7add0655167b4ae6fe328a6375c00c92ca2c8f460f241c14fc36f2d30c068d1806b75a7c7b74060708053104ca7aae2b0dac8d37c3929e2909f5bb5926063e9aa994e0bc43e17d287ceae677b88b8174a61ce2de2a08f72a22d79c0a083cc203a72ad8ba7ad1cfb31efa38b8b5dc9a4a532d5bcbac856b7e639c641be739d98e3c3c6ca67d174cfe68b828e0c2c3ac89e93bd58a11b632d49d3655ac933df79858e15418392ec2215317bdb1125664f5f08672b0a24a322e23bc698cc6a56e17484e41663a52702704798a381c8791b52aae62ea79a1df0050cc8a9e68a3f3719e01c999c01533ed644210d5549d530300a25723fd41b9e6a728397974fb152a152d0ef4b58c30d7a1fa4d85c04013fd4820194a0c94edb6359acce1606ff16a14f4b354022972273a8274d53cd0c4f3d0070df7860653f663adf4ef397b3403491102aeb99ef2cbb531ae16d688e7c9921dfdf220b81c4d2b883c26676369d6767a5d169259dde7c7ea3f780c5ec115f62e1793b21e6288594a606c31a751ac2e71775d395bf20359686c912e55108f3376496e68d275a3cfa65cb47e5e38785d35eb3314c28eaf1a5022b175116ded9653de3b8fc3c155f674ce447468ab6b4a36d1495f5042bdb457ed5e10313d3c188eb6d1586239551924380aec34dee2769104fefe4b9b2ec9c7331ee609726074fdeacfc5666b018924c0fcaad3013cdf44dc6f9330e2c9a50abaa61562ecd139d0d38a4587da33b9e280129e2276ae2fec8426e2d2d73bcc109542dcf468cb39b80d0442ca1cc0eb7f34a6bdf8feb3b0d1d1f863fd36c65dc7c4a7befa6c4662212a8970f05712952fb786cf59d83ceb856e864131e68f351ae631e3d8f735391dd1a78c83ac0ed0b7c28d23e66de4edeac53bd1fc8ce7ed2569dd41ceeaf6717f4e38b9cd97b39dd2d96c83fa9a51590880c89d4ac91e72dc57602a384e5dde04fadb27f7b124f4f4029b417577902f2cfe20912f14507b3ec40013122c2971c2be2511df90cb37396850fb65b470a89b9d457b79baf2a716a275047cba73e225f73c61312f36782495b7746e1efb25388737e3a417bb6e344df1fe5b40cf7b9a88fd793b30a5f6c86f2df6f29cf4895de7eba2f0b0dc4484697564d1c8552a5e48c681c8ad8355896ae2219bb7a5189c61b6c9db41a0f694dbe7de4e95847601493f624248af36b2f904fff9bcdc17467fcece8c301bd703a6917c7845938a0d8e40c0961f66ca70d1b258613932e94fd407b3f0105f4147b7d1d3fd08bedc7e85a60d6e8c542e9b742cfd5b7fbb2cb29a3016f94aefc3ebfdd2788c901bd4402fabb05446dc59c08a4d2351277853e888d64919876550ecaa036f3cb4d4e64671e58e8f4df797f0e0c298b60a8f1ea53459aca7f3a2940788c1d5dd9406dca209ccf3ad9a83151520ce4f6b4718b5bf55b73e548d99050bbf10358dc29e2e393ad9d93afe925a75a033d4d86e053780ad254f8928b570da80ff10941aadfbe6444ee67baa8810638ee8bdd45937812ebc281eae0c11fd5c901d0654cfaace3cb9e5db73f7b71b3908576fe492ecfd9987845f16da1ddaf059b180bb0f003093722982ec9763d2591b9f818dd966f14a4a1b1485261059ee4e808bac1bcc788b77b0c05fcfceea8b427219d17c7ac630452b9339578a6e7664bc0537676d19aab8b13e079d352fabdcfbc0c988d96f5b036c29440a02567232b3ccf4ef19404470fade1a3445da1c2a8ec9a26624805f0ea24489b9838eb80b99f48f45f674e7d7be03ba6951b9e163d0f4dcde59799586d2f3aeb2f7382024fde80d6d468355b62f43e8e229667c032f504f94c55670e90c413401db8253f32cc07156220b0a2dc2da4097684279612dad15e28b0ce18252185be01d337feecdfee40d7baa256b3c3de5c27096e2a7e9c4d060d8d427a47819a4f86070d15ac1f9a35763208d370403cb8bcf37e118589b58c6df35a6c40011884756c93411e950b544b03cb16fef98c7c8a328cdea4e25c0b81eedb001f48260461a8a74145ae2b3565a7d4df682bb613590935179534318d83c676c2dabc322c1d3c8dc71304aee7f50876d68cc99028a06f8d419aca0f4d4cf49bd06f398c410e6d27b3023b25613a09db22085fe843158517e73a277960e96fa915a690800f2d4e09fa6ad25b80c8a84eba7c7322b34a38304010ff9f7736b4e5d394e12df6145978c5bba022bd0501ae148d939ef3f61f9e0fc0628b24bbfd1e73d36fd06b111b09109a06f1a9fa62735caaa8b09641cddeab8267caf465f592f482d91a7ac9f30c8e67a9d2781c12cf14e8e1221228cbc2b45d3f622c42546e17c84011a03c05c1e595369654e278a2897e2851b87ca694a5e83aa6f314dad752965810acf5bdcbd468d0e48d7ecda6105a60bec5db37f7f96039b198bf65e840006e0f0f9f87450ab2302c763e8097010c0289b8342c853c3ce44e216747c8e92129c4a8ea2ffc79f02b9a604889d75c39c87ecb4921f5421283c2b6201ad2cd1d722235afcfa7b7dd8383bd863e08770e847603aa4ab6765a3090424a0749d6e825be83b9acf47091530314da5738d52f8d8baba09a1caf5eff515f32f10fcd983c71d892bc80b21800a150e6c485703ac846f1cbdbab177fa83eb1c2a647b26a1f467be1acfc964842f6de64cb2da54c49a66e07ac071507499e6cfe7d3739c133dd679288c46e77cb008b35c16ecbe9ddb108927e3043615ca273c33844a5b5c4660882063d842923a8790b195158f0858a34644610d40fb022060d146244a1023441cd666431060d46ae3803065182fa85c49698624aedfec55883f163ec96115f0d8864f0cf7c158063cc1f8c31f0e74704cfb3610354e16b314fc778263eff9420e6606b4805fe01139598a75b6083fd5be64382e64bcf05ff70e8fb871f0efd78c49732225dffd260548a8d8045ecc68f6d4ab6aec23f2cbf76984886fa873db404bfe214f0b92f64b13ed6ae70d5c26d05c77ac5f2731cb23e630737e425f6a202f38cd0c53618fef1cc6b97115d3ee4877d831b6b98189f4c1897b54de18ffc4737225d157cb42b3e897263194eb6b8786ae2f481f8fa20ee38d57a40f1f32382e7d9b0a1a2df0ef3f8cbaf9e3c8e81f5af1b0754d26ed983631f882f8e10600ff04fd5b2efa08895c4d670bd12618e013318d7b90852e79cf30ac50f43268c4c052fde8933273d8301211e8b5cf71a9f54fa4b8f01cd7529a51412f218e3d71c3bcc73b3f083eb3fbda8456e0ce6fad3af07f36c61474063b5f7a802f3b49867842ed6ddbd01da9f3e68e30e05f9f4a7e782fc703e9cece3d17f0506b1fb82dff91b8848777a1149f3407fe9384a8cad5fde8d3b6634367b970e36ec2124f86766fce31f3be880c592943f392b108edd266a3086da079d3ac38676639773df085f7ebabb9b02dac66245dee11eaaf50bf90a50683fb83b1e0072b061ebf69276b5780c1bda1b81982752807ff86bb5367ed8c1ed2f64324343feea3071273e19a2306e8c2d831b9b88b8b1c1304f7424315ebf487ac889b61b36fffea4189a5c102e27c16670b7c8b5c7c03faa2d31de808945c6869145f0ab878aa491bf4efce3f35957ec12cd2cb0aa2fac5d6ce84db01f2e1daca6fd94807f88c41882882f37414c72bb061144f8f9817993371531c43cfdae2e56fbe290ef7c3164a6183253a49908f38b620ffc3391408a26883506e14c4b3b7cb8fddb085dacd4c23fd1615eeb13975cf8b5436ee19f30a2cb65c0023256cced2b6ed3806970436fb28279aab0fea1c3be30f670fbbb04b7df8bb8fd8cc4ed97ccd3fe0df98b657ff0cf12fca382d85fa1b05bae97db4f82c47ec23cfd524abe71b40513326e28bb2533f713d7d13296e9275ea678982a9de57690e83232c5a5d82f01486e620626a3ece04d5d8820714349d48548911bca25d2483eb91d97881cd62eee1243112a6ec8b992b8c43ffe9d817846124ccbfd80c60c6cfcee7a84c0c5f287c0c5c6ef1aa0bdc38ae09d0e3a60b1ac75d815d612b791b8bd14c6a59091ba9134d8307f492f358c95646e3b4c3a10d2a889795a3ef11d7f39194847ac2ab60634dcfe251983fc6413f550fcb0878a482dccd35f3d59e43bfd2088b13e0473fed061f20c8e92adaa58de4fbccc5345f8e19dd6c23ff1ffbfb7c40e23ba625183fd2c321d267ab97149bf40a703feea2d71a7df0b2ccc909321eab88315378cad050431161c010b1b7ed02374b161346a2315f887b5f0156ef14f93c7a696b189190c8caf8b2313ad74436e3be305376c22264937ec256dd44f2447e6c204cb6d09e68c0f2e47f7ff769887dfe3c90929254bf9cce3dd4fd06c652d5bdfa9d53f6b6d1cf3cf3ffeaa9ac7ea9d5ead18cbf58f03a3a92e90510e6872766ce212658aa332ad5b6d5a4760f5a96e98946cf52b4dcbbacfc9aa87bf561f06ac38da4ee08d568f0f0ea5a32d5f5e00c29decba4ed6db75a954ca761da700d0a6466553400fb68eb43a846b9b4597225362ecfe8848c91222a26e4544b442ad7e552b4a2ab1d07d3d7af80ba8760940474766cca4806000f5021033603461e5fc8d568f0f8ea32d51bc00a423ea3a2225a8afebfe681bb2fa2728a5ee811a080af5f1811ca1524025a89e10596b552854f739a1f1fe3937effffe5a6da71e1f1c3e346e56361e4be5d979d4b53d422ac354d4248448c99229444444444b3b907c69894809519390a6a6261f2d48e622c5d13d5d0f0ab9568f0f8e23a418c392e4ffc307119192a21d3e5a00d2d464ebc9878f1d293ceb098b2885ea38056c0a38294053808f653dd8422a6a1242a46449b567d02c7193eb3ac9b55aad31635094a3b293f5b260a849142a190b9483711cac48c74549c3d8ec6b1861ade86d55caaeeb50d116a55229db75dce7c466fb9cd4bcabc01ba0efcc1aaffa0eab458d52536c2870d0cc39b8a473d2e9eed2dddd5dfa74ea4e9dce499d7febee76293b3a783b9457ce8f83f8d75f943bb43ea8b556adc6d7546ce3b67f41e2928ebfcce15ca72352fad56aed9c4936ef18424704f819675871295d4a24fec2befcfce1079723139feeb3baec1d2ebe3a7e1c7050d3f1c3d31d12342468be0c1beb7c13fc9a43b8fdfdad10f8677ef351fb503aa32fc17c6300f1f5c59df8fd81d461c48631c6e6a0e63482cdf26bc8113cc4e0cc1061aa98822488a310028a0cb014d10289893b4311222940c3a4091652b0e0c4121d62673c495383f4c80d6699325f4aa6692d68c127c26ac6ae583b5240b23b906c6e08b699eabdf51252b4e08d1d297c99f58c760326a3582c03c2c424c423eb2114830d9929922d6912850a519fca83056e3b4909138a99f45337f1e74dbcb9b9f978136fbe18638c4c4b38bdfb83fead94557d11a9418f58e251642256a1e2d978519e3498e4c558fca2d4e00170b0fdb62dd2175f8e628c3146d5506c08498c4343699e485363d4c4280ea970dec6c808e76d706c1ee7716c9880a83e2738389f508cc9a84911214671280d73c9a2caedae07855cce4fa9728414535a623ad394f4654c193368d208619554a954920a6bffd43dea875c0ec2f9d40b892ad5c717d260cd27c423daac6caaac7e65646363b352a9ece7c426f539c9c1417d4e38b0c1aa712a61f5fe3b76e4e0706083558386d7f20112f29d39f404895193289b6d150d3758ee72520d63e890200ad946114dc734cda49de09fcc8818f1919062b1cb4a4a97bff28fc3ee6d9612d708222e7f03c1af864533b81ab122681d2e1b11c3606bec2ad2fd0c1fd47d52a46cb9c9eda4790d23c288265222deb8648449045787863528865d2d0383fddd311f11bcc426d36178b9fd48b7bbc6d860cbc0dc85f5abbc9d02dc7e30575afe5799c788cb32b37761be0badc0f2e52ccbbe707a1f5d960d4595b6f93989ae6750a5dcb88a33581d91f222558313b77b189854c3910a4ba2e1ca49849bd980ca020c4121ad008688eaabbb78b2b2497ee71c41fc8b67e2990639c2ae134e300fbff4747003d140349366c23cdd41208c19377e18cdc811d3300fa7619ee83b3186bc65cbe5ef2beeda8d1f6a7c74c39dcb9d8e7efffe3a13a4accc2351b0b14e588dae339acd66ca1125f274e59f2c0a1576e557d8c3aefc875df939c11162d75efb1a4d146262b020ed4f4f630b246400439eb62f0dba0fef87eff819aa44634b4fbf23022295944ed5129658141b1aa2339b59466f888e94894a323a7dce39a5f7fea256f08e3f18900b0ac676e23822205e7e1aa3b17ead60b40c3d43d31c8942c750268a863665b0acc8f56ce8fad329b331d7b331fdaac9ca9cc9d2d4a1a68c29435361b548451256a2eb4aae7fcdb413f72cf7a31a496c7f5625abe2afcca8ca13a4ebd994ce8466bae154f27c2976e7972c16e9ba12f3f8cb662ed7870e0dd67e8bc6fc450107832a9171fd43ca14f31707292d5dcae483799cc696fc29933ff5a7fe5ba431e6f117cae2a5ba4868ecfacfe045cc0c47354e44678c7e69d75cc17529a534aad185900c41e4e7980fd419adde95de15b0341784a1b9f475b64d6aaa159a2051ad208419f9a9971fcb13ba90fbee1be2c23901f5dda33e9d1bedc239c186a8b7df902b71787450cd7750cd272404419dc7d7b994e742fdd445797c3bcf85d4d714cae3cb79f1a6521edfed3b0f677b8fe9ab3c9dd6c1777edf20a5f4cb59354827a574470aeda24d29a532abb505ba75c5416ed4ab5c4e647d6b470a35542b3429e2ffff1f869cdf5f3f615bfe5c552b0881a6562b3b0269a141370178a57b0b3f9c956248ef833f89bdb91cbbf8cfaf7e0ad2af23986175a47bb1b14ed779380e8821e83e3e07711e8e033a049c25a8fba46859d7d9534ffb7050a02e684f9f6fe6a1a03dfdceb2ff1bbecbab0d56d50a4d94c49bfde98300135af68021419c967dacdef1aa0342180b7edf604f172bdd098cb374df7d42343004f7c170fcd04393201c07c4e79efb8404f942095150941f8efc5697d5f2f7f17ff088f6c02cd915c6951696d5d3c5fa87d3cff1eb7ccadc4283fcd25b62ff0e61f2822d3c1c01e28a1b98098a5d90d0c04917494d68088a6fe3b3c26cac538704c5089c5e7bfa5af6e1d053f6f579645f9f7efd8448a1dfe9eb8743bf3e070911228587f6a7d337804fa73f7d2180e1f4dac7d987433f216d48d0101c66c8020be27e7b7f0880e13ef60d024b685eeb5525c9c54283b05417363e0be1ac2c2a79c9899a05942f35184119828aede10b192a4842850b26566e62b7a7c002ca1359a4f0b0e2a228e9dc886eeb2e41f68496b02305d683dce5a41976608d41c54c085e9f9b09f1f81a1cec981b9ff668302e09f1f8cd6b695e65676767778f2dd021b37d042932f6a4013152cb47d6f7260f39dde7ac92c592734ed98216b15dce16da55b5e76fe107907659b66c1ff53e2ffba9ee09c00b6c7cebede02797faf0d1902a9c07f28e4f9f1d3ab23bc1823daef70cfa3bb390bdb5d6faf84b3fe9e4f4f5f48ed799459419b24069421589713aa5f7f8e0b07139c98819777539c90818356cb55dce44707451458f0f8ef9e54a3355c210d344082b33084105352421c5152fe052441738bce81e1f1c2c6ec5a52e271909c37dc12e40e208aca88ba22488b4a06c91658a1530636cc0027b01d7f4cd2b323051d0a411234c12518f16681143040928497429e30aad8c3139d3cb0a63383962840c9a1cf170450c53725012028951156514d1328030c0b4a28c232440c1174fb8e01a74a952832196b018630728c66092c2063e883063f186218888c1428b27c620a2041718385102c6858628747041360600b3cb901330499285891670f132c50b37f0014a0d96b06287335234597192820c323ca842636d97938c7481822a62b5241991a2c81936dacb494692b8f4729291238aa4e49fbef5646b1a36465d000f5d4489dbfdd58ab9cd5ac00daca42237dc7e26f2ed18ebeff3e2c008a805a54e92e10637e462676ec863788999e874853a37c01cf433ee8277669e7ff4e4ff0d39ef461d22b0a18ffff42410eefa579d2f8a6183198636c60cba0a2f9a2b61470aac07e5e52419763891608b959931c8482c4a2b1f1d2e8deb97936408ac2a2cc6c11db25aed9755e30a96d6dda98149350e4c39db25db956594c179dac0f5fe008dcc33b5bb751cff465147b6fead3d14fc25733195a3025caa863558a0a323c550a3a9c289a2141c9159c5a171ab9ca22356a06543da72a4495f82eaeeee2451093b52603dd85d4e2a0ae286acd80976caa877edaedb19965e4e2a5ad2dad74a2a3aa2035759a7f460b3cb4945b032b65e4ee2a129051ece9cacf0a92b4032b3267a9059280a6a7024d81ce2869e8248fe706badbf3a536badf5c3d6eda99f8f144abdc34b95c99e6149d1f4b0dee12c43bdc3ed8304090e3ba6a8a2f396abad1e1f1cd5b250508fb82f4e6268711ac2de5ce6a204d2905d5de6a204956c0a5b73998b124168b1f632172592685e2c8dcb5c92481380cb5c948081d2c61e59b694a4269404008d0dff46fe71ddf820fff88dbfc33f1bf3c47f55153728a185097890a188111136a8419a1bb0c0224550fc07b7f8623188c01ea0149a70fcc5e7461ea8dc90b100e07a73fc1c1bb3b821f73e0fb2d10f92cbd03a0683c17408bae147ee1ce2b88e85bff098323e378c4896441cace0c1e106d79f6582ebff44615c7f3087a3ebdff24992c3f5074ac2c5f5df2154829b340231aebf8f26aeff0f0c6871fd3ba0c40c1812493ab4a0e887eb9fb48394ebfe0476e51c821523f373edf7226268582c797c706862e6ba95b02e319c6234c0f5b729b8fe7c0391eb4ed43948c8ac90d0e0769208a8a027d858e7e78920e9c51c6628e3491008455a58f142c599334b58090a62022a452841c922c491a0eed3c541fe660023ac7c1c965ffd85c31f8e0af3e93bc0bf3f183e18a4f0e8f70f873fc26060f9523e4bfe22969e252c3782b0ce3116856ba72d9ab0322422be985937ca4990b5b4b0418a3b2f27d97014c4d651065d198bba9c64c3093cb8cc858a995615dd3ed323d3dd96354550a2d56af94edbd66cb55aad56ab25db6d2a73758a2d4a9b0d4e6e777039c9061a6ebd9c64430c93868d75543638c69e9efe421bf6b050e307eb5fb3d7de9fab1fab77e747ed8c5be79f3cf99a0ebeb17e7d653faddefc8cf665eae9903f9f597a641eff1e17d8d095dc7685dd74db15769aebef9204261be7eca676c5bf118485410a8fece9c3507f3e0c194700250b8394f830ccaf0f03fdac3e8f8f07fdccc8fcfa46bcbe014063fdbdbbd9f5af60cb81887cb71b757b998de2c8ffa0ccc3911f0701e5607530ab020dd9569118bbfe9571620c9a5e13cce31f8d825c892fd9fe2e7e8c2dd9806e00b2c166ffc16c974797fc39c3c6cc0cfaf0cbc777e2f3abc26030d85110bf102c579db23de7d7ed2bea5fd3a6fdb6e99c3a577e2f4cb069405b4c76ce3957edca3e9c218e1b7f94108605c2ba92f54de9ad5e4f83b7f59c1552dd8883e37a737e4058577e37a4d28dd76a327e383d59ddfb9c66f5f471da27e79cec69e6aca0efd417ad99efb0159299ed0d71e47b97af5c4f8596937193a6554598bd67926f286b0d71e80c8223545f75e335a16ff60db60f3f65e5be6a5de0cfae8490ac502062c355952e783969cca4c7cdf940ad55faf50bb3979fcd7e7e56ab9fcbcc5b651f7299cc68166475a7ce9ddf0b1387e7522da58c5ca4d423b7e22c8f159d73caaf96654b29e70c5f9877fe0bf2ce0fc7f52177c8fd8c089ad1effa85f2a9cc80f8f329a79cf3935cad5c4d79e152fe6549e99717dcbbb8587a4f8352ca77b70df2bb4b7777777777b753a49435a2d8505e97f6c331219c960b3aed75fa734ebabab299482a1d09a01a45587e81be406f9464e6536ef5ccdf6aae269dd36b1672d7e909f3e9d3f9e1a86e01c88857da7c3b806241edcd654a595d92b9aa83c5fe4b973537deee02350f91cd9f7562dbdbf11dd62f1fea9d762975e6a434cb217b684e4a59594e8eac4321de10867a23d34ef1743a69dae964c2111b7e8be3ba0e85ca5e5e27d927240441dea9d3116f372b86d0bff5705cc775adaa99353534502106ba0e85e294b5e055a150a84e472a956a96b5b6d3412f4ba5aa61a6cccccc91a83b1d7d57363872d8743afcb256ab55b76af0a663314ff3ef5cfec20ddcd8f9d015cb29cd202cbf0f49979f0f3985d55019c24d9a659911a9d4775dcadbdebba809dced79ebf8b9ed936084c030f8cc9472d2e6bf799c2c3f8e45367f57697fea3e7eebe3db7c642c6e6c517163c74f40cee3e01ffbf16d6aa2a41da4fa4438c2f2c66d9b90b358a947fdc6fdc6d98f9907f5409dfac27851dfd6793db69390ce3f8f061b14bad120c740fe29a964996acab4317f503666044877af3104fead5b36953de7176377cb6e325b6d17c75adbe53de77bfcea6dffba3bc9c63aa16dc9d4e3386e7edbb6c928fd738f5438e56218a573d987fe54ca3be30f9535c471d93e04194822a559466956e9cfa795dafc4d6d239bbfe9b6b9799bb7d9fee6396876396aa434fb9cd8d8c41acb9849a1721e3c428a292d319d69da8225e9cb983266d0a4e9228d248b59466b462355bdfdcde6b58fcf31e0f4f1859c381ddc9fb8533cc54ddaa86169c62855a11289ce00d9a1c38ad96965e38e723445520f42d070628b0d5678f872134676eccb65a52e5f6e68bb3cb95b2a46eeca8d7e8ddfaeba92e5d7a0ca4d0b86c630dd7011c6cdd2cd1634d0f0e18605375eaae862e4850b6a14d5e0814610357a00e3080a90d0a1092d376254f004d20e5cbeb8d1e2872453a800c20a1a5720a141c48dd24d9924624a66808285111a5988d1840a13256894404aede54bad4e3f8ac532bdd30f3ecbccedd78e6c7419733b2e91c084951f55d25fde1c5e5c9a4c1dc1b8dacba57665cfc43facddfa9a273710b38f32b1b160564bc10d35782962098d11dc7ca1c1440d1f962832230222129ce0081a4f6ec8383102871c680c7183457cd6099fc60a6c68dfbac7d823920085cd1139d9a0133664dd9843ca771ce93efdc68df32b3273e393f0840d59d286172b3912a4b0a18c39e277fc7a6e06e295fd3a39d9ecc853045a520a86aef67fb754fd2dc26c84aa583f6a9f6551defee17593dac72e47d6a530447a17e9ffe09f46d2ae220bd4af51c98d4b8e6210321931d0f67c34583f7a2d34583f165c15ae6efdd0e7d631b7be4fadde3e3afe6a99f65bff0ffef15b1f489639e17ed5f5bf5dfeb57eebe3de895fb52fd4b9f5c68d4666804982058c922ccedcce3c0e129253851005182dc1822a930f21f535178212f32567f2982bd9b05acb62fd87a0ce2028fbea6d11012cf4ab4700d05821fe71ddfe1e52fc372a297b01eb6ebfbd844a7783618405d1296329f897f0431d3056e676fbf821d4c3af7c1d7ea54f1ba0dfbdd656438bada185bdd65f42bdd35fabb52cd6bf6d755fa127f6ef085944b1440a92132a9812d40ffa4b02464384210393a2055150bf65390848d847ff8f7ea1fe1e67b6a50abbf1b718962f7299a36a05274b1c29fe3c72257ffddb70b13ebec7f8a7c687ac5b437bab071fd6fb0383f143bf9a92efc4cf9a8a7e7b4f8afdcca872109fc6673f8419981bff66553ae03b1918d6cdaadae47c0d003a780f7ecbaa745fabb5dd57f1170755eb6156c5919827664b48f1b3a6f8d952c654e3819a1ef9ab997c273ece737044e30b6d7caae42f87d1267fb991effcc02e8f82c1a276f9d1cd17b26e6c946eacf94256cdabbe260f68938def8077f08515005f6873be90759bc9b7c7f9c2da1c7c363c7fcf97fc8b2b45c1aef80e73fff87e847ad60ac6bdcd17b26adc48e54648b584af04204f79a15fd4173a98cb79e1dfd091ae1c0ae593501e51a2d0ad085917164aa32bab9050032bb1ece897f539f34c510988890d1dc991922cbfb80b145c09a28b33362802f6803263a0188232030d4c303b9223f50b15f3d89876319a22459ec6bfdce866a237875c5cc2550fda16b50eee386fc3a259b971f9650aea11292326886ef8494cc4906425c98a5f4eb2c2b4f2ba8b2dfe9c9397fa87223c26b2ec468179fc99397a701499e0c85cec2a0bdb396244817fb6d8e5e86e8ceddf5a26f5f0a48618db3fe7e48ffd50a67bb28e57d7216f7b72487cfe7a26fffc6ef46ff363b0416700ce09f18b43ee77839b39766024a4e93a2c76920f0e2b27cc0db93bc1dc980fff1ffe423d98c114169665a5944e00a21ecc48a73a3a19fd7c7a5aad956d174b297d8748ba0f45b33341d3d873a23d77ed446b3518575e438ba537b44058a3062b5da9e27277428ddbb1898d3f3273cb6db766d317a52526d939ed0a6fd8cabd52ce8e960fd82ef9fe812e1cff21d75faa6a83ad063f27f4e7d7d3604eefe448faab7ed1d60b84293e2508b1c0444e995664a525bf39f13fa907a31b7364777bf1da7e45cf09fdeeda097d3e41c6707d7a7aa7a3a3a26614bb72943665adea6fb4cb513b5e5a65bf6496d3ae1cca55da3265db6573bce0fbf5dd2fb0775ade5b8e0f10ad94d2d63e5b9f7e8eec6b263b13a20f50c85d9ef214331cb6c83cdeeeded46bd6ddeefd85ee93455d4a29a59452c629a5c7d914f9e7c68fa5ac16749fd2a7949c6b0b388194ed6289924fac5edaf8f117ca0b8463357f40b8cdb9e8e19cc01f3f7e3827c40fc784789b935cf43696b3fbe37a8774ec285bca7f736f29bde5877393d2bdfdb673fc146797cad9e5e09f54b6e7b5cbd1d30be96d996267e61cb6b935367551b7fdfb931a8da72d2eafdd1cdbbddd679572669e799665994baf21815c842ed1fd4b419194be748d63f94ba775e6b7cdf7be9ec92ab51ab3bad5e72dcbb44d4eaf34db324a6fac6416dddd5d3e9f32cf6e803924093158c93ded2a1cd337548ac19adfb6e95f53b243c12f176b6a9e7b95eab9865371cfa99e5371a82e5e6953a88f99877ba0e63a2f5e194fa08e0d33744e71480e9ed9dcb29981e0c6f7483f9edadd38aa8aaa166c4172d49fbfc5d805c9d1bdd6d3aeca60ea39f5c2954e6b767a0ee26b25832954aa0316954249c9f7e4c5db719b74f9f1e9a43957cf89ea250a12d635d572054bde2eb52ceb82e4909f7de5f82715f29d13ab65b3fbacac192cb7a3e6179967d6764d39655635595f52aa519aa3f15c6934e3b266adac9c4e5fdb387b2b17a0aba8b44d786435756848000080001315000020100a0604029148241ccee2a8fa14800c76944478581a8c835112e3308a31c620640801c01800068888cc106e00301c327e6fc923fdfb2db72405b28af7b174bcdeb7182ed36371b3dcbeffc8904215dbb9969d8295dcb9022de9ce4dd0a458b3d62c9941c522d94653d57a8d29bfb57b2d9d5e17b1e5bb7297b2722dd2b110d0c8cc4f3c91c0afda3bc5690bb9f6445f6b795f55291b21b2e0c82029aa0db11a6f7d4c862fa151240d1cdb7dfaed4090040cca5d9256dc93e42caf4183d09bd9f7e48049a13ab051a5a1c1ef9e768ad5ab748d38e3d1e00b59702250f35a831cb3c7652508c1555104301f7483390d60d5041c25726109dc51c9cf0a5d8d388bd05aea68483b78c03ace8c9671c841f175f3657feaaacacbba8c0df92deed325d0eb1a63fa33c27d5252ad4b6cf951ba4ac9f48a742ce827b4bb282fab2ab67c97eeb2a4ac4bc7d49fea5a978ab51253f1031b329f05f567e5aae5e5aa8ea9dfd3ae45e9645d2a46f251bacad2b2aa63eaafeaaa4b25d64b4cf5292e65b95c997c2cace2829da704606f67b9f094c884e458b19f5ee38a357c40c792836495c6ab241f90ba40857ce954a4e88beb2e93bef9aff843412e9da57c1f5b61b894b15ac29b343aa8e880457c9919ad69e9642ab3c2ef63024e84c6504fbd7290c4fcf327de83c944731feecc889444f7d343c1346e6d4e7dc2d5341a3a5cf6502e43da39ea9beae662badbebcbea0d8aedd46b5c6efa03797bd7dc78b9a4d385df359d2543dbcd6e3a9be3e29fcc4bac0b562e5676d86d8dd10c4737e22eab4a370f39b12ee50616f8ce2132c2f740b1ef794a3bf105557209f4f0cc8a44e5341b90ba53a1a7e60dd77e5f56456b66a92c8ef3b511752f89218528169685b55010af33b99ed4ef46db6c65d987b2764e4dbd9d525765ecfa5bdd7589c47a2406d407c45d9694ab12abfed4ae5a5eaf8b58920f2957292d5765ecf231ed92be123bb9ca0a7f41776a03cf8f27f87da1663ba28824182276bab9da3cd558836370e6e1222219eef5f3e77764741750052a845fba2a43f0be24426b1c0e78e5252921e469d90a49724762048a1743887edb2a4d759def3e89b4a9685f7a43a892be83065f517f8fde12d2a961ed37fb962d652bc62db02c0901187c020dd3b0b981eb87c2228dd5f344da8c6075625a6757752f587b8bb9621efe23b1a356dbb7f7e9466efcbc9f68504be454950642cb76742df9af4f86e7843bcbb548d43640e9f9e67349fe06b43ee32c924f185d4e6c59333504f79816c63cf2bcb8c030946859b7d2635c91894cc037d0a6c22b5491f6488c9d1d33865f44f0cab2ed5509995f84e0ac75d477fbc1c295ef375f7a8e0c2e5d4daae590b7dac8557f8dfba438dd744388173498886b6a7f6992496d09896e2f88f4a0984bb4493c920a268f67a988b77e753767bb4067c88d770d0ae46c4785bd4c5cda438142d41e8eacb3dd7eebd603ced4fe195a951527f081ee902e44f623e1b0180e7793cc9c91ae4505895b266744296a91c36c1f10393c2d8308254eda95c9ab7cd653e56cada99a5c605b173d017e93f7f10a2dc0e3f2170424ad9e38870c09613d9034b6bd0c31d824c44d80ab46853b8dbdafeeb1e90db6d9486a645ae56e3ade67a4a62b5d57ceffd80d54f8d1c4fee520ab0d618da6a7211aeabe362836e5888af4f60dcb0d700cc9155ddade27ff986900a32b80f489f7d4bc1ef742b07fbae7dea4166b470226175553bd6bbf6e7f2746aa4dd27b916f4375c9b72dcc9bdf1a0d1323aa091876e751053362ce46faa48470442bbd9416b22c430a69640899ada547b950f07fbb86789a40711bbad2a72aeea782bf3d0f55a7a7b0fd62225487595bbc5c3de6271a89b54678f47fc50cd70860f30c4a29f8f7c6d4cf1fe7edd758bafa633a463c742269c72975cd39dccc6b2b9b85621c13ad48c90a20c4564ea14117b9b7fe4f2ca348497f5cafed0c8851ddaf0077c3a2f5a675965480a7f82e5ebe6924e2dc122a2997ba847df4cf5d4d3bbda922cea5eb3dee80751d9ac045c365bbb52afc7cf68e10cffd943831dd835588a07a4d8dafd75c8cbd264cdb6bd64ce7d67d3f6f725c83e52fcce9bc9757219a0100379cd519a6b905e2c24cf7ae0bcb625d16bebf23aab8eeb90f9973ef4b187876cfcfb77cc404e7433690b2aa003187a5e8cb2639e181fd4919806132a3e6b08574e4a4790b0d8146df3702b8637fae67c8a1d2e63c55161524fd0c4d751c29ccbf9be1d67970729bbe9c820f89242d0b549478100514c275a4fcc7128fa6461f6f8d0ae875fe70a47bd520fdbd1819ffb7b025c0872367b0e6e0215f61d0c48cca309aa4775984627eb6c4d3cca5b551c86e4a7a18de94d7847dbf320d8a58fafab8297ced95cdb0222e95156e1721381cbe69fb3b3d5a5f807988b52cb5234ac18b9e4342732d8e53da89c162d278cee1a704e4833b0d4536e115270b4711bfa026795141cc393a096421567273beacebc1f2a8719998a7e0f6880bf70dc8413195a41d546d4234732856380931fa3e5109d141f1296c24768ab3e6c9eff9cb2bdd41ee808a463a8d5aac17b1f794a453912c29789101552edbea4f14cca033185048e6a3e01364933166a72653cd1ef05b3807674b68d21b0578b037a94b3fbfaec0e909dd93484eb4d410eccc5f4f731f68d49c9e2d59a4e3fd361331aae84280389b8985fe379d565cb305ca672c903279ac4617b3f175c15148edc21cbd9d0cc2624ba0401c27cc9fe8b33f9d05bfc8eca888fe914201020cf6802e8d317fa971484967536ae85ff6eb025e7593060323434d4ceed59b245c23e0b9995674c629ef4a76e90ea69a6a80d381952fcccc2f2a93a7bb90fb69e3290d7f7b0372aded703e84b1f5db3b650ade41a2f4a320cb7b16c8fadbc410b6b5529028306e1f58fff3b2849254cf18976252504c0e8bf9b1cc9db245aae1dbd295bd15b1ef18408afbafecad2eb6edad67789e47aaaf82bb90533a4e25436c583395446cae79deabd1ee338f332b49d24c5cd100ac148bf2a998d849ba0326276a92da9f8dc6dae74a8ca8d6500180da4d03320b41634712486613116942bf4ff93e7645c61b668d9782bec6b00c78a4277362d80c667fb96e2a811041d1288b248a818efe58e99c18c18b557662cf2431185b2e230572ae39e735f313379c493e2f63fe766aafee71cee0983e10c80ced84bbf2c1ed85239187cb2587680611a3ad55f33c03dde73ad1c5b57a953c0ff1cc37f5369e99f070dd4ef29ce60036075373ff4fb725d2d7f5b42c89d8c7d5437e70027eff08418128e1218ee50b7891f05750d59b1ec137ed36dc39d3c0d964859a427df7da53d0ae56eb40cbdac16a12d9ed4e964e055e4f64db5d06ca3680e5b962d55d86fb9589093b27b4d5fa92ebfeb3fbf6cf23e3ae23db8b9d311f6579939368d61d0b764d52d7f8c8e29bda41d7d341c4cc770ab8270ae398a2eb9a63bf0c3ee2c58a265697c9e6b6be7c650a05aeafb3021c50c4251214563f68fc0914473a0fb7b7c93a66cb487519c84e179af9c31e6842b1d2b3a0952b5a217710d8f59c6f485a86691d6b48fbad3d85b74cf9978abe3714d4c83044a9a1fc47c080818418e965282fb820aac8335ae0102effd317661af23137440291116b15b1f72fd11171415b89b85dfb1cd25a401b6dfe50f9215c73dee82dff8437835a6e26d4c6400433eccde35e550dd5cf9506caddb392651541fde529c99c9c5f515324725ba8398a28faa79c20715211326ecc1b5ccff411734dff2d0243a6be5e79b205b6c32a40dcdaf0a35d7756ad117daa58683b26c3f422e7765ba3f4aea52063c97b217ee54fae149288360f23d981431892e445c1863a1244d565fb89f30cb1cdb721fac9f880e6fcd2f5ca9c576f7590e366b48d3ad8640303c3941e400c441673976d3a4f57eb1dbe6d14728f1e3605854f5b4239c86480d7d80607d812582b02ea97a6368e15191c9f55d4b981ae0255ff035fcbdc2da534fa0dfb30f1439b7a8833a6c1b87910b41a3c01a211d1cec7acc5d73a05dc8fc1fb7093aa157fffcf028a018c433c60e552126bfeeb1ab2a2226b7cc7f14dfb84e524cbad687ad7ba000deb0b1ae7f15ed457598fb587bf000a8dd634eeda0729c48fc5b44fb0844ec05ef2181fd8ab0864df4e0276b6331ee5a469db523ff668220a31d9ea59696bd4b8ca7b9462cb83652f3a1c23be5dc702a93894746d32788523279863e58725f500fc055abbcda3b0003388d44f0b21c1b300cb53e33580cfe82c60441c00b0a9841cb4131452120be00e9fadc1b91b9d39940fd977e0c45f8a81b980ad6ca013d45122a7be7b3040a006896b682d73a4757955cf321b485f62c19d585bd5fe0eb830dddbb4d055c845d510e95d31f1b6a3e05e17e7903a9b9efff05614e3e851ee7e762c2e533261d758e7e4c6a8e708f663e97e291bd90c1048c909922c19831e75dc8254683a1536eb8fd86d756d2dbf9fbb1ad598fc8887fe5b07625f723028af23b49f90d74ac4dfbe2fd64dd0ebd1bbf50625c44833d40fde5edde21b8d9abe5325d8f9676c8fe26a20e24a23ecb5afdd23c84c9abdae03bc4ccb819b6a3d9be07ff1511b83fb401df4f5673cc6ba746d7ac880f05c7bb3618068b06f62b682f141263b565db72579cfc289e5d29785b18c5e301e0ba8c9e788e8f9d2184f83b6dff6356d0abf6f356409ee7e5400abb42fdc2ad235c9408a5fdb7fd1f32a0ff497eca0da1a4a11841947600ba43a3d3947a53d8bbed0a01012653aa135f55f31e152a5b1882bdf393a9b21e71ab6afcf83a9d13aed082412e837bfb2ca3e0a8729f0737a282396c4b351bf1705fd74cb1721911698e6d271abdc053a831864203f7e06f7d3a03f878993daad1e04f828d023606f181de7686f186ef58e88dd1425f18f8e33b1993525fb1738e33812e65f7b421d5fcd924cfb73708e6b1d78ef7f01b99027923570561310372a1ba9c1135836a1da60e06485e4cbf847832d02394ceb8804d53cb9fbf94e1f12f7d8365d1dbaa96d11806adb8b9de3ed00828c68ec4dcdc67bca835dfd0ce23517aa5b0d93b004c4c91641b281672824366a471f80a5bf98d75dc3fb0f23119baec9295cf0ab7e025adf6ca1930411ec0495c6d74ee6e40894167ddfbd291dd2b9aa4146aa5133ca7c4021dbf0c00b1373c433a434cf68b0c9c03ab48325116672cd5c5b75597bb56e8d545fd9c84e7ab9129afa33be8003663baf5435becd8afd2a5eea4cac420fcaa26b1fbe0c596d9e55412ed37b1105c65319ebd5ce5810d61b11f45c0310483045f962af3a5b001d2a25ea50e010b6623a44eb6c8116a505b29bcec44880a077ec75499c2da010c9538d83438d3351c57ab8385b60ffcdc1d4158cf4019c2a69d5aa1a76608e2632853b9817fb46109d75388c28a88160cbac846432ddc14603e78190531653a60358b726abe0a77333082ef7525ae0221b980c99547d3860c8f1b1bcf1f5e684170b9a630c287b95847262ffeefb3e2e62900034f6142942f715628712c6eda816ca85a007642b702e4ae4514bc99f5ded2f95d168498bd04f0c0cb29b3d2212b373c42e31707f629ecc9d88bc053a46fe9191f8a5f01c80e9b640b2871420652e52f9d348d3145c1de2c3f307d932c25ec27225568f8045cc3f43c7d67632e5d6e7f9fb0080e7aa5601652882df0598093652d89edc313225d9f5a5911bafa06aee181750b3aa69c65d8f7be7ac2706e3e2367e3443ad6f727b49ddfeddfb567e1f72e082419b5c0ad3ebde9c229e91acb04ffc47972370e9305984238919862463da484b098de355fbd7425e222ee7fd66da18e0aae5962a5323c87c0ca2aa6c92e9de47d2444380247781f14ae8eb08cc0c74577589335167ea5112c3109ff1b13d33c5e6ce31f14116e815f27b3acc5e7e1d283676a9da26b2bb9e1105e19b289f738916dc5d283c4a32e5ecaeeeb1a701d3b426366d895cfcaccbce1c892ec73a103c5c39e6ddc09b05aaf7c78dfd6aef740167c16e165e318b9fe5d557f5981e6a3f33b653155374a6a536b0d694f2ac39926d1921dfabae9892161b55f2e43b05422341d0b78a148582ddf37015d2422c69427fd39b8c5f78b20fe40e37a541fb260885a5b596b2968daa6ec130de97d3f655c3152b91c4ad60dab17b57603f3cb7a232748f87f0469a10ab441f68fb7a1221fc9d1257900fb682a2cc2b4405f345fe7c89877da19707d4eff3c91ea6fe57acc9a38cd9c2eada13760a2205fb32400ee092999d24c79542585c326ae3d2c0380b0be11fa1ab01b7420c582aac8390890b9b643ac2f3cc701318cccc628765343cf9273d1db2dfe536844236ab87b1e71f1b155d435af88f857dadeabe53505df61da70ea7ef46112330ec9c4485c0e5c011a23d7d1303873df1981ea1cb34d23ef13b2170c8e9549acb9a836fd81cfb11931a19e128f78600e7622ef79fac3c1a8551f41aacac0f1ca6a030100671d79a32c9b1ad0900245234d944e3bdb80e949e5018676eb67541f9f8be673dcb3ee9f5b77addfbd07437efd3a0433a44617972cbfe99210563031de5d993e36db8139009c11a1bfcf47924a10725d4d8a2fbfe93bebbda376e2219eae391b7a5f55699af7b4ccc78381292f1898f623bbf4dd7f372cf5945f489dbaeeae9f77a8c4a4770fd0fa18e4b8c3218b421588aba2506119d1e1c8e3ab5602e4166d09a304e6105f6c2fde3c2409383f7e0a319ddc7fa4b6e12996c04d37391899aaa3e42534e6de53303a6693b744c52844dc223d9a4102619e59d77705d3eed7185589fb398401526eabfc303ee3446605671fd0c012bfbb248689a2e44b0e3d974af3af6745c6cd46987ce8ab8b982f9013892210ce5e3b109e318d8675c875c5f42d3f04431ca16a40a77f821ac2b421eba11641738cdf5537a2738a4d98b44bac3b86dc4d1f436a5120e01300b68a62e0ed8a5c561044b661eeed670f16822e5be5d2e47d1fe413a304db21b1bfd270cd3869c93544e34068d0710b2af14039f09759698e7bef3d59f4041295a8898ef0edb65aac6c0f5e903b8901ec97ce1e7d3d63939baba7a9c58aa64cb09ad530dec7c892099625762efdcd78c96b1f1d3aea974871f07e2f6b91eae0702e221b3237d9e1a51455f681891bdca04b004d126e761b39a84a3ca089e413fbc7e41bf0cef8590e61f171b57517f4806bcbb9bdf8aacc402a60216bf5f3dc06a3f548f947426b4b3fa32be8251801725c9f289781589a05161437df5fbeb80b4888bcc7de477fc79e4a15842f12be41e7e25d2365ada47492271928c02db5bf1a74850381d7e4ab90802b70ae21c7c6a0323590b01006ac420b482896d9b49c4a5269246ec3c4e11507075015e63cbfc7f620a36b236b6c960d983039b1895ff5d06f4238d8146ff21845f3927e734ecf6fc24377cf8c6575a28463ad75ab529baf0ac6c512271ae5badb669bc628318159158c1bee328bfcc5723f027cf10c3b2eb1e951415728fc42b404dc0d95ad75f412b76eae21bef6c31b485b3ee8ad32d06f4d150b77ad0c80cd637aa62e440abdd8245e418149c4bddfa03362e3b1f244ab3de4f16a1ee87d64d592567bfe1465a79fb834466407231bcd4313ac00ea367aca39fd176fd628bb7ee89ef35faa02f14e94b25b452089b4371f1d45bfccd939379f5d64537f293c2967f5f7c75aa220363dde89b9cd2501443a0daf34a4b50b5487b08de096f54a5e30421ae4150a0e1e4de46ce60c2d37b3c632a7a0cd6bf0f03c6bca23f974833223386d510070b2e815f31b931ed48074c169d6a10c96b661cc0cc55bcf6ca7848e399964f542a5e800bed707380fd90684d5237264b739512110a485a749756d0cde032af7a3d285540c519a8a4d708feb2628f1ae02ee982ca409a987f8b746897e8922547da32ddf650faf38e7f6f6bc50c8343e94efa76a53166f11b3860320f7dc184ffa692567844d56e3c5d1ecb9d4d5ba42f286d54aebfbb0e99a706efb7e856428f5ac2b3c43cc95d831beaf684e5ac1bc5116e8454b24a6d1edc5161ae0cfe5a6badc023dc003efc5f88e6efac8e4152e63b57e877133ac938b78b976d77b65cf5784a45df4202e2027f39f3ac4f9aaa47f23e6c1eea4a74cfb46059dcd9fa32576256e0c90137a53bf5578636bf4f4a5f4cdd54d52fec6d7d1f9de475ccb1ba7e356feb7b787298438eed4a04d8c31ab998821408914d2015ee854a8af99f077fb1b85ba88d3a0b500ccc17160152499f12189f7b63f04490904a13609747e2bd48a21977fe79a4d1db6cdb6d3c4c9270ef1b34884388967e0fc0eb15e5269269ca973a7d041340fc64665dd3cd348a6a0d9dec4cf3641691bae92b91ba13bd734f4297df7d7a444157582b5087f204b3c02cf06667f17791993b649ef548dfe2234a84fa6e12537d0d2e346a1c10eb61213ccb009c4213b7722a4ed215369152c79b36acdf651f16d943e815532ba95403d6e0db8f5e54a34efa22b83ab16b086a13e678bc2327924e5234c3d2b032012e14f64cb89709a0cfb6a825dd9db83b41e26eecd96930331643a051f00a396a0860691deceb453cde7751cb0439993f85a1139ad3c69abd4a65c7f83363529c36079e6b7390b9eb3c427b97cc966e71e136a5e9f91c690ed2143ef2dada92570083181713b877c97c6199f071e57de4d520af5ff361c6d16813245260a2320da217287bf97ab71ca6b82b016fa1bec95b7a5a18d0427eef10a612581287d7759a1386d6bc1fa64a4e3513c92ecafd5071e41439d74b7834157f1068831e867cd0ae561530106fcb278ad6c25fd97831aba73c7cb305f2f059577a7dbc7a34a38d4dca9b00fe405da7f73363bf7692858dbdaaef289a997ef65de37ddf24f013ba47009b5ba161da95d1612030c60b02a948b32b50a2a521fa07001bc5037237330885a1d6b8adec71049a3bf98225e029d0be4db93a356b7f2057da3beb161c0fc28703a79d343e062084c3c075a870e38df2a3262093f77893ffe927785fe547738b8a5673421158156d10ae31e5ee0114000e247cc6f60a75c8fd24c72bb2a041318a1f7dea781fe98a404d0da9b66f9f387ebb64b0dce632cbbb86c0124b698aebe5e497c54f3763969771a8817a4b04c6d85c459496935e6a95e43860da7cfc51d7b5da1b907ed34e9d18165d0df44e1e98093ec5c45ef0f4fa559896d07bf1b8bcd1a10d028ada9fde79a2a24a4083db9cba0a6c54841ba60f9eb5388fbb58e48db0667a7149657aa9021b2934ffd42d82da928eb8eeff8f6bcb8f86193e41afd71e435441c5466c8c14d26bf2d51295f3fde86effa3c92d2c01364b7229b75e9c923f9a65b1f648ef85782fdd5385c5cd64e82d0d19a4317ebc013f1b3ef428d8ee5398c17626c119925708635daa227cb38a7547b533908935a96fe9b0174c97d805c1ee6eee5cac62945a123e84fc68b3a90c41014a79fb92ab4eef2eab02226345d3b52ea3b7a969f4f635493b9fabacfdf940a5b079d3847751346f451cd19437b5764a620368c2b51c832d2996cb78d72d5dca1d9808ee6f62a1749fb2069aa955f59fe0c09b9f369d3c0b7334c389c040239eaa21d9d1c4a2e06c869f31c69620764061f0a09e0167b920cbbf6cba2e93ddde140aa77bdc802c7fd556638849abf6db6f11ab1211e3de3a7d39915bd797d3dabe9c5ad18733789ff8d34a358eadf3b49bca45ccb96fe0646aeb64c65ea5de70783271ea021ae54efc2081ed24108021c0ae04b6a82c7040133f3e656ee7c4c011eabbb01020f3e4207f16a68ed1c423fd4ce43670c2bd1ea24dc15e17887a0db7cf43fc0a40993ccc5defb899dd01d3fc815abe1dab1e97e3df01050cfda494040298dfe5cb2c04c74beef0f43fb6d15210bf0f0a1dcf15562169d1e04ba7b53fbace227d42cf50535ff70ca6b2656e20330e540548520266142428c749e113ee6175b11d869f6d87c5e324a81712ee7a490d1a00bb32bb2cd1507f569f2a4aacac888e0c9b2ff679ac812ec17859cdf3626cb588651c4ce5f2bbac7937c5fe9a2e2079112a20f80591cedda7530caed04b4908f24fa7920468cdcf26944586a8ad1ed4cb95ce03d32453e33d54cb5cd75fb09f382c55bbac0658adb37e277c185ea3df26a82cb80a454a2c4bcd519de95a68e68b78f88f785fb055d28926f198e87ec16c1c054a2b2a1c628d5be9b6c35c5ce7cbfc51097cbac7aff9ac51c2edb61db9bd34b5306a959c8924293fa06a13450215fd296db13ee662a8ca608db7818b5b136bb322ba4024442eb76d1ceba5d59d876f3965e2f03353884e4c015d316dd5e42652e53ba8c6d37609981bdfb60d2903f05e2d1d4f6cdfe1146064381879919f7d4b36ce788efbec62b37283ba0e0cf23900ae9575051143ef40ab0ebc84d89f514a5303787aab6a477b625920cac38e239e936a6dc4665c674c1e84ace7044f2f02f76f075aaa6d823d70303b67dbd3c09885da834b14e251bd0dd708ea49368f30cbbe6ed4c4bba1ba7743cc5cb71a748859b5a44909c3b74948b7da89f9a8afce55d2e989f1fe301b9b80182d6862140b2f32be495a5e9514e3fb322ebb885f50568c48d3c601bde35f36a3248d01e8f04b5f4f4d2fd7c1a944730f32c4409eabb2d896cc4d77938ce59c01a546015fbe27b19b4c82198c72e822b4952f29b7fcf3464252ec1e0d3643f90a325dd813dc44ca8806146b61bf794acb04066a9fc4f88c4185a98b778a8b4cdfc59ed309861e7e4774d27bcdd49cf323d49a5738bf230ea3954100791ada3dc8677539790c1e11bc46f564fe194ba40bb6a4aa221fcea5d5f4ee672163c65cb9449f10fd14777d1efc2bdffe69cb18243fb0160fc4e2af3b48e6008c92020ec957b0e4f9f515d454c19663ed8b04ed7ebe6191f0824dc591e842c03e6aa7b171210eb980d49442fb61ff138ce00df1cd6c7c4c0d5a4a97844a32d4435eaf9033a7ee76bb10ee10285a05df6ac1fc41916b09ba74fc55f1311c14acd231c27a0a02abaf029cc17cafe328142c81d625a94cec3993bb0b45cb02ad9594fb2b3ec348f72865c8afcd71b9c3c91d3a8c4553fb6dbac0fc8a9d29abd00cee2e0c8c6feb9ae8bdd43169610885a50d1983466d4fe4f144cd461a4de1b188a590667580b4008caf5e8490018cb9d8d048941517f7600f4be628ae95926588da20fe8b996975d4af69a5e82d70968b2d450a93ec250d5e392aa950774e141157f37d19e5167519296b4afb6f7379b80c6b174669791726a0cf79afea1283fdffa56e01a02e2e5ebbc9a5f2d4767f98d8db783eb61480f75b400ca90462ec48696308bd2cb7b6ebe471295351fe7efc723e968ba2561683bb4cd835e2608ca632bc0295594d7c16055ef8bd0bbb38f3dc434af95380216559cb6527b0f35e206ea472686d1ea3f5520250386abf8c880d1a9dc01f63bc4070b24cbd3af724b3e6330590527127816efb5c9ef1c699775e5a8ca134388d5229127c8728137909434cfcd7554577991f5cbe52990a76a998aee8b0a37454ffd2dc840a18415e56fe79fb2306d8a7306f5ffc9989b91642417aa992d51fbc659709211a8214b00e40d152533d95a10f8a7562d3b67f2cf6d2fee8daff954bf322f1d57e9ce535646e1782bc3dcace98cc9d060b06f79eaaef012652b2a6c0cb6ccdb2a17ee6659352deefde10d19040881398d2c36a5341805548283354f8dc78ecdc03951f9c4c140d8ec7dac513df2a06211039233066f541c85e79b9911996858229a45188dc7878f00b6c7d768538e7b0193c10cf24b195d2c46e76ce38852177b20aa438c98bea57cd55fea7fa6d9d7376d85bbe5505d45f65c5d40bb3732e4419b94df4cc5c23418e7e28e5fd414e5bc7fb35a20ac443c54efa901640e2f509532114ab54395201548f56a45122eb6b27d5cb1c75fe9ace209cc01179c528fc2899ab67eebc5c8da5eb4af1f5ce91bb977556c74d993802723d3d795024b60acebb23ac292c1360eb196612f8b8f0f95fb675f648f38e1b9f0b20dc51d49b26725da2fcae71e22e23fda8f1c4302a1719312d0b978ef31d3c3b2f5c3186bf4678510393f090e307e7c2a6e85f70910ce6f37d78c756a9a19c2e85afdc562159d9f0a1c5eb7c20458a05583ae547f3a0e98581d97bc6185248b68137707ffebf4835b447452b9d008ae610d660263870e614b1f8a649d104b463afa2c0e9d1e5e6fea84a8a8e3300d4e482c013a26b000702d45dfd39127650c1da6fb13044d8866c28d2355bc53cb7fd6957f8345163a6a016ce39270bce033c2749b9d99dd8f6b9361712cc9ca3055a651dff241cf4ba4bd9d58b0adfa9ce5fd94f5666a70d20d7c16cd0d97979421f2e9bbeceb72763e99626236f5cc21ef151bcdc4e136d9f9ab145c5855a1afe50d6fe21322f2419f5d8e5a85624a33b52f206a8a70270a1b14468aa0d0a7a6790f61f9678ef7ec722b4715c6092b2880cea109d333de031e1e4b7c74d0ab4ba847d6b05100818269bee3638f24624684cc8b1197ea8283bb44c8fa068ece4469623951758d5b67569733a583d111cb9d836d415ddb92e10f9c050600076106e8ba553a253534ed2e9b67f49db9bc595a4bdc41e9b46c487f0f9a2446d34da4138175a50734389edfb45e8b9d7581aa68b702ece5d62643831251809cd1a98c22f02ec140cdd205aab0c797e39b099a938e46d4569ac727182a55a891184456b594d8a4376b1bf1c3fa6e75c0e41f78b22c8f89e1dae6769dfada4cd12cf2a7778b84f72f69ce48b073201c038c7b0802b99628495053fc14710cbc5e0e8abfd12cce07cea9c083d8c7d46b2cc1d9dbc86135ed6844b794979a9c520d90413f40ea01e4619c0235e81ace7add26941322de08284aca4ccfadd059964d9859cbf329493a895078683c8616408576719c849824321fcf0c3423166fd0c2584628af259204719a118348dc86b69f0b00b6da0be8fce982409d86dd9db0ccc037ef214b881ab47ee5fe85b054c54cc72b4974bd2cca7f6b9f0050c2c999639c179e9fd4503d8364848351c3fb7c744fc35938fb87390e511405c1bbc1a182c9ca4fe876bc590c87fd214238555f800ba5738814065463c21eb8a7bf82bfb30bdd0d9fd6265367f25551e481d9e1f54c4961f1e888f840f036f05db9359b1c43450f67b3a4b31b2c84b759a68e108d7026b22c458e415bae02899481a1747f06505007278b2c3be7fd50b3c2ae9d64a23a265fcbe0a44bd79007e0fd1605a4e08a7df7df3b1ccb4faa038eebe4d77659e986f62856bb5ff2437bc2fd258187f5a05f958e6cd1f20fc3e9170fd2146ce3696198fc88961e850d2e10114a8ea2aec052345e8363f87bb985822b924c5b152378890e9bf3215f0467c3770748c3a2e5935050db2552290f6cdb21f361549dc992ac69fa0ea507137bb32e9b94a1a8ce77056b529ee3852bb489ab53b5450a8955aa8378f2326922bb3463a77f68681c690b692a515ab767526c6d2d15f391974e4b22f752101ef88334862ede3602b7376e1fc426da2f30807381a76ae787de97c33c09e0ecd82b87c30fe500b0a233ef7ef883961ea4292a0eb97ccaa47a82628f49e6f38335a040bea5c58e3e0b232351bd0d3a0c6ef8177bf57f169bfce6fbf2f580297a88efdcc9a53121b72dd1eada87f38d2b686b4523d76b3d68290f93ac72c0c0481a9ae849c2485381c0a80beee10aa1b8dd2076f9caa93474e4d3b90262317b77546c767dda5ec71648ede2ad8e83ffeebf80ffbd72f8ccc5b60e8b8796f0de2c9c329c8171537ac31de099ba44c58edb7ab9cc24eb291af9e322e3c42a29a865ced5b7b71c3939083dabca8f2137d75e58d7b08819df0b73142f3e2de7c25f016c96ff363a8011264e79ea28e81541776db0e7d65cfbac2b04f2e0707ff3aaf0955e181bd224b7030141071bfd570e735b994350b7d95cde3610b3e16df0e82a57bd8847c9088bfdb1385ef48f52ae024257a47302db1fbad5232d2cc733b4d2b112124ccaf5e4d29b1643f05b8c7aef02b90d5afa1007de4b82807ca3612d83e4fc8b2f272fe6b652bcde5659e3a739b39f54f96a0de2fca4062f7d54d6aca815b5c405cfb21dc1740f9d386657f4fc7b9bf87f923a917f0bca75e1a65b7bdb5b9dc96ac0737efb22038dfc33dd999165444391bcbddbe13250bfaefa1d9ae97dd7a0de188a294068f09518664f7862507a7002163ccb9ca47248dad022c4081d030f6fc75b93722f8624fcc6ffaffc05d2e53190ba8bc570fdcd480ccb8e35350e831db2371488eac6d21d8fd93ae779d913a931dda767069759e5eb96d1bef211c991b4381628cb9226d3a44e8c6f6a92f8b945df922adc5fff729f0f4937a8b3c47e90b1f65dd7e4a2b8a4a1cf13fb88118101a9d2fd60bc063c6740f0b1e560ebbeced176dc6fae3500f60031a6ff9fd6a61e3a0b44794ffbdfc2f0bb3e7595fe332d6997555dc3c93e19647b3b4005de1c43378bcaf37de93ba71d8f80ef46221518ea32c3da349052a7c9a8bbc93dde49375c874f0d14b6e9a9704e2ed511179cd465a92097c1390a383357c8c13f6a6b2e33735691f8dc6a6464e4a32589202577c6a0b95e2e98374f64ade65757450e592a31305286406e444c989f6c71c36a2a59aab84f5528bf0adabd34484886d773916cad68861f0353b443d00b30ed28d59d8add28b7123ec1b56d173a35b27d82053da08298d59e50cb27d13572cb9e28572aa5b070bfdbc66411653fcc9025b0394e214f2cdbc51bbbdd6a1f51fe76878d432420b27e209f1aa6749bebc6e7c51bc010d0ee63d0e87af02f7231066c52882b91daeeedc0a82bf33e17fbdc8568cb9a512dee9c98802a24ac5be1b7aa3b4ae9041e1f8cd11cd16f314aa746e5987776d4b4252bf88b840e93e96d43b836977d69d7dfbca2f8d2604f15c313dfc6879c2977dcb100af7c63b5d000cd4e57928a4426c48fd9e62a5eb4d3061268d21ee1c450376e113730855951c14b8e19d4a1e32e7ca9cca997d65b4752cd32088bc3af831091bd1d724f8cd1289e690c66abe3110ce2bb07db2228f4cf1f77a6434ba0e0593dcdb1f1a66588297c00c0e69b3b494f6b479a629a142013435e079eadb02a11a3fe0c2f1a58dd0c485c8cf4e952bd97bb83e1ca310940d5b5995e6c130849997c3655f2952aa435c0040ff708eff95f3031cefa7085cd0199c609ecfabdb305a42e7d671c198f6cd303d42c1b7102b39e674565e30fb0e132b80b4bd129bf084854369b071dfbf5e916c33c1202774d43ea1076589438d5640c04a4ac4e31190e463d471fbeea094b6a04c11b409302cd33ffe0a373b6f9f0bc7ce93df867f082550b627bdadbb2761ba4f00ae4e9c1ee6af8923e00838cac6fbb218c3baf985bada4f770155337d58d369d47f68b75480e0078e2847d5916f524b05247a452bcd835db02316ac82fd7ed1547b82bd81abb8a429ab943e6e65b92ff9c74fd026713e30d8eb8cadc2120e28a01e493f8c3242efc5b035bedb32271cb9f9a6f6fb731c71c976dbd8851ed2fb7ef8ee0ba34eb694898f4b1c6bd44cb65162fd717ffaf3ef8ff8fa2792f0b72fe449f5142c8a4a63d7e0653b204a552d3a3bee006da17bc4d29f8230a31850945435f61f4b5a74e1c3733f42c9116743a760a9c714095bd60b8388552b93d404ad4f74fd5458cc7bafed551eb203a09c94c302a2198f2314361da627221ec4869a5430ddff265f1ffb3356d29613fc72b293cad7b86348c01f42a30da64d7e2544671256164dc222d80d40b3b8301aa81f124c75b085b48f77de34149426ec540f091c8cefd38291cec4cad5494152d8269c42c1f87d5dff47538287561e718aa57bbd7eac045d48bfde19ffc9d75782eb0d43deab1a01df55fc11bcaf75bf4d2c34e267fdf3c4b8252c3a033b87f71a4b0ef74c7ab31ba9ad3160e285e9ceaab23359d9f6e34dcb3f5b6d6a3f19931b53fcf4ba63ef4daa15c20e6bfd50b6751d70f63811f5abd0b5778e7f39b9756fb3c97dd3c19fb3b7a02a91c40847a777745eecbfad3a09e17f0faae0fdc99c5b781b826c0996ad031039b682bed54f6f67b6778c06711956fa26bac33cfdc56434e60d58692d50b7e94c362776238261e4dbb67ac5e8d5da4f6f510e8061f7046090c63b0a75d0f56841855eea59b92fa80de449eaa4bb8a20dab36042e631bb5ae1dea6e89cafa67c04646d045101436755468dd580ce4833a02a8b1b9215f90d46137869104b25c57706d449ba4c098144e3441512b4efc9a449bdd59ef4d83ab238a2d7ea2f05563ac8e1e4fd3904c0200a7cdde6c0f372f01f1479865cea0c357c65478173c60b1316fe930d48d0d4b1cb9fde2141e387558d572342d9af20b801b50abce4a212b79f5b0cb44abb9ecccfa20a701f498bba01dbab1d9a55395e1734131218b260d867c0752cb1a4e38090f0cfb51a65686f6b0f5e24189111dcbd34706a91dfaf385c422aaca3d03ad642e558035d6d5f5b4f048942cd077682e5ebefe61fe1e3c8db33d7ae68ed3b3605f9ecd8425382127240c4eb96a397c3ae038b6a146c5298139d002794107fde035d7e81a72255a10411216f33ada1854b41c87bb70081988b64f283ce194f960f5b58d0f6bc69d829990569ea8f68d82e3c19b4b87d91a2b6b2f1b237147397941b66b02cc56ac082f694e431688e04bd19ee2fea26a93e5096a5f82c93a67444b5a1184ef42eb4c58d4a16a82ef5b2d636d93582dfde01a129c11f50b119e74e45808a3913e20c3983c30d5809b30187ebb8b5513273268ea0c104870b074228467e608fa4ded99cca9003a62b4eb99d211d934da1626d45419aa9488b8487bbb6e04619ea521dc44c404b9eaba31a2e1956bbab008bd0fba2a7fdae3f170bc000b2abf1f0938d903e785aa8909c922eb5f1164d8a8d4370d129a737e77e9c5a879c87814c26b71ca070d3800bc1a65e7e929bbb77bd26da29bcbef7b849382084907060c04a0c425cd4f7d218afdfb3abfe6d15c31ecd34943bded1b2e2612f2361a80edca4b363164baebf9d90b893c08d5869c30ca21540ebc5b1a8c795e2f68d02c1135455bead8dbc6eab947e1d04259963277cf926599e43ed70b7d0e074c6df322694d5927478ca20ded75ad42ef537e12caf70a3db5e5b237d25224add879a55f4735c663c57d405d4829920b6202b3b4c321124d71c81c1ceddc0e9e75c298f20c65bf24f268a263e2a2e1621cfc5675ad67ecf3479d8a237cbf20a6d7940e1002bd03ff64273d2757ed4276e0c03b845778e71388dc127238d698c08f85087674f70e7d749e386804c9698809349e695f386e10fdc3eff0b369245260b1c183718c011480a82810200d93d25c3676b195904b0630d01a0425e71face394da1da86ccb8bf9458822420323c880304a141f3b576737c1c573e57ef093369ee84ddc2dedb36ce62694d4ab59b8417b8b28222345cf4f02ac90c5872c23e2912e1001cdfc9c1078eaf43c274a5f46c324be9f797c10b0bf3165d974d3d1ce5d35db6c9f2df5d2bccbe4ffdfd04e062e62fff7bba3ef01cdb6a4f9245304a080b5ed68662c1c8b54f8d40c6be25fd7eea66b1e8abb00a33af714bfe3286b41fe6b92e7eb8c2e5340ce102385c506d49762ca42f17406cf3dc7956c76f768191ec82edf625b37d4650b356be28e496e9b566265919eb9cafdd39d5c200d94801f2c14549d4955d9550c322c1f44b33942ab0da139a343a4dffe85dc9f4520cb826380ba58c9b6f2037565ff3edae465ea9adb22263f8d6783e9cdf4b4e91b23744a5d52dbfae044260ed96942ed9e7c108cc801b69f0cf415bc3abc0e9ad96cf4dd6bde72640a8637321384d6c47d8b21bf7b6b15f8def3b8f9def425331eda18d8a58b94ab52e7496d675d6863c3b95efca64d347bc3594ed4d510ed618fe94fe59bf9d7e186668a8ae8a21b79582e5fafa3e5e605d7c6accbffabeb7f5ed6a9819a3802951e5e9460691398744b055705d503b555a7bdef82f674e6190a02f6764464d9de24ad2feccc48f6480986ab86bdeace2dcc4e756b3089cf23033bb17b5b8894ba6f05b3dcc21a6784851a39ee8b029ef1956a4926b774d9b3a6bb5346a5045c44bb716e36407936d87788beb8ef75402b47e77c784d478c5bb97e4394d163a9c2fd41b50fdef42f7ee952e81705e21b8b962191c91df5e04a399d507ba3e1b1cc80eb27fb1947ea3907ff51022ad4e61b62fa75dcd53ae11b1db3b151be88d5aab08a2da46c2b898f01236d3f51108e47a7cc8e66a8162af442afa979da902acbcb79763fcc71e1da568c4e7f14c7e689546a4e9cba71759e281b34fa593c8711c522cbd520080300e5223d2851e92b019c820eb4cd72bc8cd654195ba92754992f7e168171cb9f0f601b44b1ba28bf316864f9f4c0086057860369b9ad8b98b37248bb3dd0d464bc43beaba8bcbf3e9acf636de110e45e16c792754f0172f0b7d65760aefd2f2c42a41087f6c201d47ede259450345113462e560e01b873d9b8042ec7e276fe5ad8ad7c464a6680aa758d5a6d4aae98ffd0abe07b76a2c5ee394b898fa62d40da744cc6380525edad1546a7d3c185a45abad5645b99eecb3fcb0bdd25c4cb7c6af105c1cc5ce1a94e6e5692f010318508c22e85a17cdde74659849e55962a4aecd09b2c1275584006cc4f25411f03fa866e11a7b9badd9e6e5ea93be83b5a48f9eca04cae28aa4ee1e9b73cdb9133257a4c7ea84a3c6743a8fe18bee5ac868a3b07b144259202803561607879d5917a710785dc00897c7346d47dccf08c104d8cf8cfd699718213c69786fc719d3b4a17658fd94d88896656d44eb2d6809268fb15322f2e2ef0c3ceee0083406a8d49061006664c382660acbf69ddffd1d2abafb47f67098945f1688864ff5852881ac71b2babcbe9c2c4953659ba564727f44f646d850b967d12ac61e2a284dc27f45b05ed25229bf6679d77f11146b472c0cf1efb0f2de94376032d0829c2d44fcae0e0a6616e1ea61eca525616f4d460180e4501c6d6b4ba9289a9de8f4a66f64e5e8a899077796566052b2bc80b406d4c34f2e26323ee105c386898bad5c2d48a0b0127c8cbec549a6ae74a8e9a02968db2d694f8a68608a819a710c7795932f274edd016664d3428e222f3424525a85018a44518d95a9a3faff4505294aff58ded2c3a41d67f154596d3fb6a09bb2d71b31b7788a58cafd1b2b75e988934dce03560e5c596d311b93bbe9ec878340e1219c5fb8601b9882b92bcc339aec82465c323751328f1c6a35329c26c3eacc368457c9270a5697cac5803c649b047809a87abd49f578adeedcb1192ab30a2790197ac80ae409e868dae1cba59bd163fc1d83807632309340a4211a0e093e9ea3d6f2d906c6097d402d631863120d25320ca04903f4bf9f030cbe600724063be494f25ef2777b1802469528496ba62007057b2525142b92ed5a9ce3aa1cfac875a2cb24ec1ea29f5d27482ec4d502b466b04d5f33e4746f6aae43cbf2898f86bafc12e8c401d54268d693b9cdfa734176a18bd00456890384e0941251e6beb23db2255fe4f1002c7ec343bb23d870c9273642504d84e997958751457000c3a753a3a9a30401a4bdb3fc38c4606b2219c4f300c7a31a74fa23b1cac1e83f0c29ce42c97b6e25919cce381c91eee66e44db09c9b3086c088e2c45b7f564edef16bd85df3d903a888543316cb86ddc37296d7eedc1d7d48d5ee0582c23604a2fed22956d973331fb0b43efb7e21a82a7f87d485064153ed13222d28282c5eedfc77187ea96bb28e9c94dce891c61cba4a55e6d673fd533b116455838b9186b6c4e2979d290f3a433295a4b9443d35545cf256e6dd029840b7f17be831984ba48b857d4070da6f595a047dfd0a9918513158adcf32db591324f4bbc3d4900c899f1bd901c9f1e5195c39dd74c42f2fee224042f67f43ee7b0ac688a612ee651a96af157e36084b2547e3224ac122d7b8e23618494270879041566960ea9edf69c08a983b4853abfda6524b5617dc315249b3548bf5bbb43fdbe626ea59dfb20d7e486ad237749fe296965b3e7ab57ca29b32d4ddfa774643ec991de75579c4fe9044ba70031b8a20f117669935801553184e55ba90a30a691892b6a2547a828ff4954a7a6ea7e4e27ae4cd1cf07c29c92b47c5c863595057d4e6df0713e5797d59272094556c29ca71ea32b918761a68a6a638d247f0bdcd3aa7b8890a1cba0423ae3549d9b421d179c3e000bd8b45751960cc768221f4fd4e1a308f707e02aaf7db6089d15fdc360ff72b4efe54c5fc8c09824604d94e86c9aa444a07d78474eda9fd08c6c1a7c222014236aa49072492e48eaf6477778edb2a42abe5165aaec262dce8272454f6961290e019c1fce1e7b8e4348a1607b68293e42495560336017259420cbd8612e3e81f3c932c96b89b9cad6874427008b78f82a6527a6a27675d291e6ce06057fb4915a8896a0f598996eb1ae3b19ebd263459dfa8a82c8b1ee0e1eb30b47c898b4504528414fa8b24c6cdd39757e4fb48f14128f79d75258343196d8c2fa4cd3f72c7802abe9dda08fa4b5bad474c8fdbfeb938ee17513a1bde96fb34cae3ea617c892b780088dc0d21afda2c08bda6cee3c538055b290f599d71bf83481e6172d521f2a38b4a4e864482e82901969c054076d8af44a5e6442db0b5f8fb8f4c2481df5df038682a128478f07c264d42d39e3d899807f326f1f9ee882da2a3d29d391e4f5f12e2b333eddc18e26c73f93b7fe7a2f367340cbf0b72b6fdf15403d4d71e7856dd4535ac1b6c4881d31b6ab32ad047a667913a13674f8fc72332e75cdcc760bdd9fc0f6ee12a2e31de18bc3f27378b06d55842ce8eccb0611c26645c7bee294bb7ba05f8462f563cdde3147974fec10b2cbc4dd36d9e0b6a09b9ee17fa6c7141dc18953bd309414651b6f71eed17f842ee541d3c7f6248d5924e81970a33ef794ba97f511acc168bc3d031840cbabf5560eaa7f5cff8b1f2ef935f494f4547945e73c56aec01cd984cc3b90dc89d80fa31a5d285b549a9207e1d89993bc057f00aa52fff88e7405c11fa8bea7e62dee3b792e356fae14e435263f543af67c472a2b5877da8caee828ca53dd396fef6c0df803d2d02a53945c0dc83105638c53ceca64226db30553450b24c7dd5a29f34b19385622833229efbb0baec2e5e08cc5608add4416c3cf2c737f674c1c0a83cb46750f5274b1f55aeb8b589367604f9bea6d5282d343051c2aa6400196600216bb765365d8eabc519baaaf53c443393a8ce590ed943f0855cb15e271610020c17a3d0e582c5a592e38430616257ad3d35521369ec7f2c4cf573bce82cf7628fd17b650041de2bcbe72b5df591695065851dc27e21a00a0f6bf93df7c597e9e44c47e6f10f95d89fbc58c4c6bcb91aa3f1f870e2c98ec04b52e8b0bada9138805b5c4e09580fde727357d3c591f9869fa5bb9e20ca38b899b92bdec5166a0de883229adf4d0bb088246e15d5b364fe198c3b6222958075309a84092279454c2d9652d7b7ea526faa7e419cae28c9c3668d957a98291d707005ee9591f94532c0ac578f084acf3489cd1f8096080678ca1267a0dbd00e5478062e504f020b95e3891059febfa551670a7abd507a25ac38f34e92acd248ba3d6a0ca82de0bcd2c24b44719be15a30f9dd7ddfe9491dd7240bb730b0f6a2d78b3cf49e99fc475d43ae9ed60a94c49cb39031c2a9e9065aa5520f5a20490a44a738d15881f4a6b89d9f09aa56749a7394bc3e081169b0051ca2917a257171f70968f8ece38c5d529fb80c505d66319bc1e93c41e90775fb30e2f3dc3414bc2b8c306fa48686ae46e042fe37860fefdc573215723b70a1c64ec1caecbbf687c95c8b3aa69fc8f8fcb8e70272e9a14bd6b708ad4ab35452c807dbf3a886c92d5e78755de040a798cb5918fcec58f7a914c6b014125f1e5b766b64ee380c7e0a158de404727073d68d1eebf10d423b164bc78ff19780900ef7e57a70516b75f2f7101ad7f9b34a7ffa02259c27cf8b5f1a8d14ba19ea9fca7eb119a0e34941ea8e21407e1147d3deb2f579ac0ec0a6e0074ea91b218950e4278ff152a5acd1bc7603343c2e5487d5f6a401fde16bb047af60c9ef6fa0de0750dbcf2dbec3919b4cbb42801f5a948f71e86758bdef60dd65fd3330588a11a0e2d162eb7b061eaa05f699924b52f2d72f0fb18d2ca1895bd2ac2b0704928d00547ca28fa1e14f9035e5640a1189ab0d099a4cb182b39d1c481958dd35d93f7fe4f453718f66b9cce32298e3ff210e550110e71e13b381e2417a78c8771f0cbff2b2b29354128fa77eac7c6c44df8470feadf15640d69e91096a955ac201477bf85eb8c3924009656833822a1241ace5b8df6e862c32166e2e2c642b77a831382edf25dc3756a743f1d83167718c43edf6d4faaa4a98dc4cdbed03d9567474d9b2d9094f5315ba76ee01ab49429f0bed539e5a37096d31c8790149a9fed0fc5eb85447ede78439da77af11f901246a4f049c0d4a0a1d58f1f6146378a3cf2d169af3d01f3d3fe1821eb4db82122e2dbf17bdcd147ffa5b611108b5122cd74acd15f7b32d37e03ac6d1d9b5d1225b8686b6088d00bc20f6d86d086fea0cbc3a6a361c0985c0df8cc86a016db00521fa3d8fc1d943292f66d63cfe4b4534d86851ca54a5993602255905bd4fad32970fe95206238121567b94d24aaabf71c475b1e25c0ac699dd32cf73f0c3ffba857c43c632de14d76362c2071aabe12f1549f7e601a9bc40c6878695aa23e355466b694409274a333085ee5d8244da90655e9f2aaaae170ea550a82ca43e7c8c2aa5b23a20ced1ca845e23cb6ae088399a7d376a9cc8d34e9dc07eb0f349e661c2d412f137d22f9f5f0ca538ccab70eaf04508bd75e320ffcbc43f2c0ed252d10c100c24ce3cd007015c0565a880d516f4c49dca1a0dd2ebaa16d190f0707dcb1e79993a9b23b018231e07f790aa4cfc67f7ffe770fbbfe2865dd44a516c7776a00ff255121b0edb0f3d4d1038773e83b8269509a0c6d65e61eaf2f8245d9883873ca4f0308201367b486bfba21a9ff73dcc8662758a2ef3d549e9f8d247db8d5e7b987a7c432f58f62d8ae53a6e4921b333b5c60fd458f20a28b96e90acee4bb30a3d0998121267028b27f9b1b55f2e684b8c0a90965121720d31187555c4d259fc94bafc0dd81eb1cbd01b4f759eb2845434e99c9af611b80f0b0a826c6d345b5264a22c0453d102de9e573897d734e3b75890d85bf7d3adbe99ef0a7be2da75134c6eba5e4163236a2c92a7891385379f80ff015d7bb99d00f2aee976638373ef8a94c11ca4d672c71db98391398bdf9ed99f9549bffe032d2ea8d88969858cb548cd59c13de4110f9c4100106c66ffb4b6fd93aa64abf2c8ea6f465fd7d2c8030b77f55e8f3f1ea4746f8491d3b894c7a4c1788a423b78242f8a048d57feea4650c42e87a5e870f093be737bb29e113487cd42a0ac88d677256dfa67b1554f8b906abf99a40d0263b70b6b018a4d89d404db80fad2326dea26987fc725d3ec36331736e4a7928e6a70d610f469d33dca207db3d9ee246559d2d3c8b4caf4e01abb8264262224c4854717ae3ea693297863c1b62b0ce62104f4e330ad9239f4e373dabe56b8184b202912960c1b9b6eb254dc97304f18b121ff30db0fb0d169c74d31c71e480ec95e76d5d7c42a53371c7e226e3d91577cd123734facc8c4c9b2830fe83ae4b9fc1af3946171bbe8c49685e6c54703a9f3b0e37c70b75856681153e85dc2ee182143ceb42bd316c61b430633af807b535652943d91b9dead6b47755f8d039c022886dd48d462cda6fd0604953e05417c9b3ae6c85a21da063cfddd04565aa01d31965dc5e14f47eee2c29587068d8f4a591d92b1dce16015f2a4a1107a0e46b76e16b7010d8c6ed24fe1edbc853f0688f3b7a95b61a979728a50ad7828241deb5bf72840287311cd02536e7a696dfab92b1b47fca0f0f8ec1147f4f0afd935cb2dcac30480f4e54079aa874a72c62b7128f890a63d5104dd4b19eafa7a99db530940ee9ec8c93e882e89f198bc1d2af5d42340ebc34998d329e081978c71ae0642fa937f95e0191f1a4a344e53c99f504c6bebf826f8f99b4c45900d445078af7c3fd10ad2a7d5dd6b9b5624854605fb81208111e78bd1a0f241f5931520fa48766233eda9fa0292a8ec2a1ac873016e142d865240f360c5e61e5e8be1b316e46b84ca63c118c05e0977932a999903b608f285a16c75332451b183f0bab2d0df53b24429740787ad315a1489976665b15013584df90f013f8f6a56b36c88b80e68e800669279dfa3d15fe3d17caedae2f0fd01ae5871ae632c465387d9ae0cf14a003e218481e6e295b5a99a36ff3a17ab7764e07350b4edf3799b64caac855ce54564f4ab718888f52456737f2b0de9683036d755efce2f47a56e921a24c8c266de600855099367f2f2361582ae7919e184b6e8163351fb69b8460b40a1ce458727a19cf4b83e5b631f35f8a65c78653cd050e73d7ed608209c1389fcfc73f703842d8d6dc499d1a8bb5570c09410faba4050248b5931e178ca87cc451cb0c9dcb1c3f7c0993ca445ebfe8e5f3eb2258fed21cd6ba069dc0f1886b3255997898f603d9d03fbf09afff8c476dc0c384ef419643a1fb55ed0ff680e39df598c6d8b16f6c1728a14b32da5125b3250b788a22739ce82598746f675145b18e0d4c9833642263395d8214ce027f6b0c6d83fa6e8ace23aeb68197b429bf5c10b680a03945a7b907a2c2a0c409de4703af0c0601686ef17ef004a9b500244654b00548405f2033cbee918fc020eeab49010b8c1f4198a2328e59cdd161aeff64d7afd102639c81c41207eb78a3bd78769e8577aeb4f41773b25ab52f569b2d1933a627003a59235a0362c749b23f617ddc5914639e06c0b431c2819c01f6c2fe918e1a60a1574f98055576c25843a31284949dccfb46c7ca3e58dd46c9080c2f63b3b4574f53f2a715e53d4fb86023d79dc8c082c261a771b247faa2831e2600d33c84e0804270e77427194eb996c7f3cc7e7781691c28835b9bcdadf1dbd44aed61a99bf207938d8b173bd9208172ab61fb07dc0c51b93ad4338564bac7dd10aff25603261ed74ae5e53c68c901f5e44818a41a43a2325276b1e90a2ea2c9d8a2cc4ce98bcf00f888bd4092c5e2c0b70abf44eb18a79f1830a869563f3bebc94ffc2344480351c8457554c9141e5f1e4327939e090900c74813b1ad03215d8eb25939dfa67a899e17cd7013a425964f22c239d79a2bee564675243c96b0a0902aec4e29bf30f550b083a975a9119cc4c6664e0a41b8b51a51cff941c44a7889c00100204e3d35396cf9f7aca4cf7464c54ab09624bfef657fb9481d078e5aba53826a738780956a8cf6457611532db49b389d3e4270d679579f5bba2ff2d2acbca1506736714af720cd2f7c6a27f0059670daa04feb60f283231a57b9385e89643cc2fe7426220ba1260c23ea96b9ea2c81c04b8a59249abb93099a04b2e07f7873ea95c225ce678af3dd6a7819a4ce4167614ef28b8f676e643895b39a1397b87acfc9a22b8fdf64dde7d1b555da6406b74d8a076a01c64256ec307a1166e448ec65015a4903d78e69c9abb35c5a86d90a9daa6da3387e19e18d25ddc45fdac787e7d6e2b03c2f5196d9be4dccd9aa5340d463c281a909c77399c02211fe94a790509671deb12438ce075125b36b618d1c5f4292553c0fe0cfcaf4318564e9f077ccdd1e31c7520b42e4babc6dedfbaa4e28e1422532934fa2f5c4473281c64c2bc1535882959cb97d7c49d647abeec27fa03f5f2f4a3d92cde843b5187f6f4563e3694a9d00e939e2a9a632d304bf6cb5ce9b7e29bfa0772ae61daa7c321342c5c8fbe1b06ec1359e1efe8e4b5bffb26e7fbde38b84eb90c5e5ccf282f783d69b95ccdf4ccbe63ef41f782b3936a5f0667765cb6a82c38d05da47e0792f577838eef0e403a1fb276a65faa4151220eb1f548f32abfdb1187a8fd2c8b9ebeecfc8f6ba831bb44e27e60f5429dd166daf091a53627e2affbbc10949979ccd539b3e2ea1da1c1df366c69443c4b160dc078d51dae87a38ae4404808c0be1ef3ad1586e8acfed39e86193fc56164842e5ee70c5ab7b6dd06d0b99f1203f37b8102dc454d5cfd1679af0d6ce16f41a76c0017157bf4504ada77f3e3596f325742cf84beceeebfcee8777bd3410f03590ff29bfb464587de0ec780341a29deb2ac761c15858ffe11c85e5ef32c88edbaa8bbe094a3e0bcc3618236cbd482facb7997d5fb3c4e25c42ea4332dcbf2c01c480c5ac1635ba59df9ab7d091332542198099b8d9156712a60f127414b134f5587d5ab3ef895351894ef313266fab9afead951200e4122e3822c264cd4e6d1dbd4e90c048982d40ccb364a6234c01ddb605c6b9fc7fee213f5e14212ac4f0bcc69e4d755b45cdcd8f212880457e57381978eee238a54573796def13d2f4daf87ee10c3339a9c445e1ef6941af7164660bedac556eb77cc12ea8266f74138e81309b8028028d230b4388394edcf0ff0a0273e06b6d8f4deeb2c59a5b933167ffdfbdf88f9a5048a2b0a47fd5ef47de18859290bb4073ca473cbbe0b19d52834d5f1043b212cce9d47681fb310014032d50009ac1156d562113d869a0b9e89b51696802077225d330ccc03441ee33f2c832d3a7247c57d948428fbd7f95330133f611704bbc943fab7347e007c086ebf8fc3bcee70e88e06d0e3c0d1037942aa0b69a4cbe845e663ce6474a1d468f789eebab88cd9f7a4c1bf724f3bfe37481cb3433769b79f913414c4f10f2f8782ed0fa60d8624449b752004653ed8381cf91a3d946838d4258e074c6ec80f60b9a4320365a44f11767bd4c0c38c0f877030fa3185153f8ca25f44d90804f59c2938757ef3095db54bcb8b1cfc2c497d6d67cf15f7b401d06138b0c715c9fae3f777932457c4a71aa58d33a1a4f6f609ecd879a9b705fc1535aaff2ac6118de31e4c6f76e43bfa4cacc52f511eeac8be72fdf630e3b95dfcd778e7aafc4b532e735d66407835fb00472031e64e703bcc3e1c8094e54a62999059cc886a38a863933baee8ef4f5955f0af65d1fe42aab058f41e10799f9f37bd0cbaf3d0a888e6e8298bb23e8a301527647e9366ab8473d4df3e969b013c7aeb190a3202845ce2c4c8b908fa019eff0a9802425c1d49ca128971b43bcf88a95ef3ab0845796cd198aabdb1530ec7f4b299757cbb49349309be1d7e45e2f217cb917d5871c4dfc2206e4d0ce155eecbf867e6ce275d9a940a39e814f02152f4ced30b3df312f154f681f080e8d0add3db2433ab8431ca1e72d26cc49c4df72904e872678de2f13850428bcad8054815c5bbc9ae94fb5aa8966b05279ca4687476f0a06e0a27ecbea418ae11a28ffc16dcc535954e72d782ca246d3a5e301c55a261c8cf00b1297bc55ed8b193604881e69e8e12b18cbd384a65c1f8a3808e38109eb9fa0b08a7c1ba397fddb2e178b99a082cc8fcaa7ea477b859160016090b806abbd8d2f3749f8df5d6f69a58bf995317e6eeb31157e0306b326323817afbedeb6f472489e0889ec9d8ddaf0fd59a2a73be9d8bfe898e8fa6903184cc34a7802fa0d56a42cba5168dda1bab3d3f45b9cb157790182407a7952896a3dc42bea409f80e06723d38b08275cec54f550a217c4116acd51ac9b0c5b23eb9029f95589019460a0463e46c651273f6abf6e7e1c25bf08e2ebb1581050161be1af35577883200ba0a880d66cd264a6ac5f9c6727d1a309ce1c9acb4de48abf2b5f34f3aaf0a5b7b1b435a1d134d45dd9de9199f8c03c5415e4cb5c1f8e1124a03850aa52e86332a3ed1a744d05b569a8e2316c7caecd8e378dfcc2b335b012c82ab5b58473be7b6885f764bbdaf1858a1e747daa33e74b8595a4cd9e2ae9e05d42ee6bbdd006997f91ad35da59670935cdce26839e607dc10148831b9d23580ca4738066e85405536dc8ca485fdb1d82f80c5438fd9f8fd3cfdeea8cbe20cbe9750659e786472c7b6ff9734d6721cc777c4c35f39b17b73707b011a87ee1856e4ca99d0462640bdad6f7df7c181a723d1b9a0c5770b332b39cd9c9d6475433c777e96fb12581befea092bcdc134c469e3f79b2b46690cda110c351d47a54304cea560eb58146434f7f9b6f972b33855eff6d41838a8c40ca2c1900c6e18954576419f40b64d322d0cb6eca158c7fb2605b3f2bf858d8f2ef1b3f561a09da75cd5a66e37738673a70d24c64fd841fdb6a2e5ecec1938b9f3561de7b660b245b0c3c1f7bace71f54beb463f1acaf31e5a69a0b6dbf14073bbd932f7a786e8cf30c4aeac6e03872e84e08e87d1bc74589d9d92dd36d0757963f0c41691f066b17a37339c0266f33f5f835a1576240b38cb62a1da85f67d1935b1714184899360d6cc09e4f44af3ac1216c19e09860ef2488c84442687174b08e9298ccad0fbb66e9969f1e421426f3e9729a8f087a4c66a62f9799823022ac536f3c4dbc861c18688b98ac6986e63b7d812ee4b7c7fce141403c1edc90b369228ddcbd472da6cc132ffef7bff3f72650f0df787b1e2fa080949830134750706b4f4e3eb35719a9844bd331c2fbd53998f00f33bf54e558271d7ffca78092dd16f18bb54aacea2790eb781d6631a3b2342a379119056139acd68c929036fce70c3c7f2e80f74db3c4e1038ce5773374e62f0170975c6db31d935f648ae2ad494eff245833d5681325108fe94dc6404750464a1a36eb6a90f8f042b66be27d5c091b4962c60cec61127ea57cc5c09fc7e6e5b9f259a5a127a1d34a005f6e2adba585fe698f5833de53344d30fcad79fdc7951d5cd75c038f0ff7b7fb0458be60cd46cd9c54c0acf32694829dbfe823e31b28510b4e7f37c14adbb3acc3e7a6a02934136e4cb718bc5e738bea40bdfd6fc09a435f643f63e4c660da4c19825f37c06de36569024ad5b265a1555eec02e796792fdb329a158c1a4d24d7d8252897cc6c1498a88e86a813dd3dd197c59b3da52da92f46df1b469a7aaeb1f9595ae25070c88cb7fff71a0af7ce2098dca13aaceff18e70a41a70aa93a5c16075511daa02fc3302ca879d4e5d40d499490745175f300d82eb03b138101d22c9220e5fadafb5dc92da5f6fc99727e0db4132525627ba82dec7c1865ad1d51e87ee09db7ba93971fdac10ab1bd36e3023765cd4eeb8095152c154c3727f234412b2f7de5bee2d934c52060805a4049b04eebfa35d2bef1f3b6251bb457b5511acfd7ed5a3b05ae1d82a16ffee7f652bf8a8ec5f58ddd8a07b34337b63f76eacbebff1eaa54793fddb8f991dd6ec37ac59b5ba396a0b4d03aa628040b7ec3b866d706e78bc5071f82e1f2a4291fd398b64a30c6ad05df0619d24905657545c7412c8ffe352e8dc63408f4c8106fdedcaa3a108e0b121cb520c07e0c18635b33418a168dc00ba185f50a10b685dde1fcefc1248aae0d267d7906514b68932fcb5bba3c19b6e71592303510517f09d9c361065c820d9df0511d8ad79b09bd95fdd1027af5ebba1cddaa541bd7de9e140bd7d1c2aafc27166f53133af5a07a9c2f67d433994b7d76eb8236fb141d48d3db361960625c671a8ec51d9af3e437d55ddd0b30ab561af6dd8abb0d820cabbaaf7bebb618fdc3d2757abd5d3c4bcc22f54be66f5daab6018a0b02f6eac5efb95ca6fdf23e364fba81b7a46bdeaaadc989a31adba3db2bd3733a7b0cc41aae03dea86d149f63e667a17fbee7258a39f5dda20cb906d1932584aa28715ca19295e982ef9d33ff5c7e8a5829d1c5f39be8a600a69f63721ba74c416f71931da85d53f5bdc8174fc74e1340bd38581d8e2ef3ef9bf26ef156c6e7c8128c37f851bd85016c9616cf2974399dfccecdcfb8d67edb9f79748ddea6cbabcc95778233326952e105f6cf6f7ae0d98190dcea395391f9b184a13d39783dcff7577afb814dd1d811bec9c53877c9d2b5d8e8a50ca2f727c1551948d3c61d86330dd924f8c38499f547deedae9c2106c7c32c5528e4f929c7091ebae669d24d987e06592640dc830fa2aa2c86b68e8c69f0c69df37b45c8ede8df98d5f68387e8d7c4dc334356339c35c3a0b7a82f40821117a914e4338290da1d4031142d289a021413d487a7e4859811404528dee11d2f3229788587a91484190aa93122727234e3f828082524f489e86ecd4e81f203f3b40ecb47c4890a527229e5e475e3e483922454948c9c709c8e945e4d5f2214f459e78082b1096842c311d61aad14788629050900f1211482d0408207c202242d4428286087a914c4c464a8c7a701272f2e125c40b0825a5214a3f7e8efc5801a444e4e7079097d2103b3f9224412a8264021bb33b218588146964c488080811901192a513b8a28cca2bc9cbe788ce53104f7389d0ce8f57d02b49129fa0a01f5ea40449f9f1f3c4439091200f62f23162a407254a3e414a825ac8d3131020355a8814292d240911119da520967c50b22385fc2cc99e223d2fd2d2244cd4c24419c7a12b20cad0173001610222652e31b25344c86988530f403b3e4a4246b60a11b2750810413f82e8f911e227c9cf4f7c91ad983b4c5911e40908271f828208f920410a229a4b88e809424808120a6a38109c89a99b314d8734754add9d0aa1f3b1aab790224b3e0c31eab111dca247a101f3ac1833cbd9cd39a7cf3967aacf3969d01cc228f7af7c6efaa0cc13830dd2a7b28715bdbed448e94be73ce9929ea1fcc5273f98e49e11d64c6dbe4c7f4683300dca87c00f4b4399a9a4f12504519681478ec010ac471fec1608c6137ab0a0527ca9599665599685b5eb96cdb2ccfb2d1236fc72860f5002fb31fdd58a0fb083ad61cd1a9e9f659fb174f4c85a162b76563689c0c2fa867896f293211f79b26a141fcb3723a083fdb29ca183ba4b0779748fefb166dd4a6757b26e25ecc21ed9ca4719d4bd4590d31863ac09c85e93529c3de0e68c4079a5c19a61d4673361e38b092987dd8bdcc92b0d3689cd71a93823b1ec962d2595ef4670313a90ff48c1c28912d1d0e4993b4e4d4c90beaa169fba3348ec51b7023c3ba6abc696f958583f9b29807d0cdd9a8fcda41e820102eeb9c8c92e46ee431bb9afd106e746747db3857bee63fc9a009f64ce658acc7dacdc53ccb2acc82747a71c5f2d10ca9cf42af6063dbbe1a45d3663caa6f53dd78e7bee6355adbc5ae0934398cc7d1899c0702dee6db0c0c56fba3cb6c8e7ba9ae170c5c6c992e5f765eefb6b90fb5e6eaf65ee73702cddcafecb9ee33eb2385c2373b0292cf0910190e36b054ef931ecf2b3265061bd41d97511182891d4042bdc78e62bc1b8684e0e8d18f663e9d9b9ac4eb7bcbba395239623568c5cfd29529d487b727c776a9727cd963e9a2ead496b3a3a3a3ad29c361d4d8a92f694fba7d3d70fb5285d7592e557a55c2b8e0d569b94e449cd021fad69d2540dac4ca25ad36ce9d7a234694d34476b9a2e4fea967efaffdfe749aeb9923b3913135f52ca9c6407f8d8a31cda8f099a9442b2a16b4d3bddf2249a23917c742bc9ce882fcd03084936ed0c2935163f4793c9870bc597de36ef464ba63a5ce732fb08d333a84e83376499fa686a4354c1c51236b43954a75bfabb4a7372680e2d42851aecd7284d4775bae94fc7c621ddc9fd99d694dbf3a84475547a95b6414973680ecda1393487521ad21c1df3334cc3cc459aba8c4d511b8f8b22a2e4fe9f25f9d393c35a973212e693ce0e9b47de2d248fa666ef77c1840d2553ee67aa61a59d6b9491f3c3cf71cecea28cd25f562f0af6c3834c29a5f49928a59446af4c57e2172c44fca2fb1af9defd0c71c22e4beea3877dc5eecdcc1c963b902ad4df6eccd46844263ab06f17cae444e711384d53a95cb8b82e39747179b1a57ea4b88b32aa0b256c188f3a974bad4fefd4e122cb3bdf366fab5dc36064a737e375fd6edb384a29a515534a9fd2a79452ef467d6fd6ad4e5a67adb5d6776fa662fffe94aeb4b4a718a75dcefbed863879f32ecd7ccfc3eec5b47765ee34ec2b867d64514d6638f0648f4eeb9f9084a5815429a62fc3af4f5f0eb58fd641d69099f270ed7aecebc70859565ade57cfbba8cf3aeadd4d29f539dd5137de4c8d0828879f6b7db07e7d16ba45a9c895c827d76755ef468fbc7df4747838d9514f6f5833cd86638be989a33f85e38c690fb70ef4867288c32ee4a07dfdbe2ee4a0e1d0b38c4956b84071b283b5f6b543f70e4f841d76a0c1503f27e56a07537c7ccede952c630d972acc195fecab568ffaec637bb7ca5bb5390dcd34f6a596b5b7b746191a0e6fdca73df24d05a5cab495bd356b33beea274b1065961c9fd8a0088a0e56dd4aabb46581315ce2cbf6766557a9d56a53b92abf5a75aa7ba562fda537837acc9bb10dce2eca981fa78743f51aeaeba20cfbaaebad43fbb6bf7a6b5fbbf633bbea5ec517958fab8f2855a6d915b2acb242a9320d5b89838f2720f0f10114b5d5cb4c4493bf8dff0e77f225aaf7b771ae842e5c69acbcba605e59851e5756f5f13395cf5ed35450170623bb7ad46bdecc0aaf8075d2c33167548fddd0e13936488bddc3e139316d7168c392573aecaffab59740f8627f0aac565ebb445670ec97ed63b05856b42e87d61fb79b1d0de688118f5834b2bbace49a351cc625faa567ed47054bb90039be542094b9134ec8516dbac5dfdfc6051cc2169d45b22d549f737440b061740af8c50dd99886996b6283514a174ebe0f127905ec41eeaf4740c9fd5ddfca8494f2092e1679b9004a8339d92b57d4a01b35e8ff8a32dc05ca27bdf06a684f5205ff588becd1276945327b0bd90d7b00e50cca1665bcab2d758b7f773525ed49d6d09a68126a56e4a46e2d09755399f6f4ceb061c97341176e76de8d32dd9532d18bda953ee4ce8d323255589a98357fefbbf7a4a2ecaf3d75abb1d0a4742bebce322d496b22ba5c53b9d635468e335a778951867f0d2860f68f69aff3a781c596eea61c7f1d71b47952bb58ac5b032b62c1ba49b6c769906e5f5fca6d93db4bed9dbc10039207bd42f7711f1c1e54c7bb4571b64e72afbdacbee334f2ab94d2779ca703d165250e29b9d9e972a06ea14f9b7e0abb8b2616fbe972c9d8927aaae9a87652383cf07720d2c7892f3ffdd5068b43a62d2850100eeb0c376ede30d860eaeff6f2d60daf20bf7ec59a96531a6635987a6e769dec6ea2e48d3707874783f45d3c61b9c73e6c27d24be148555d83dccf6f19e4941ca9ca36b893299ec19808ebef95d9739cd46aad13271dc376f27dfd3e5935147030cc9bf9e7a4fcdc67b6d0972f7dbcc8fc361c82d6a77e75012e1ff869b57eeda6b011c6bb37f3ff82acb13d7d09c417ede94f20b6f053d687d595c287f665155beaaf1edf19c1fadbf55b3f851b630bebc6d812a6727ded7e76edb9dfb454560390420026c65fb16b9aa6611a64761cd6af5fb3ddaf2dd4432bf76e01b8cda441fa29dce6d17a76767c5af85daca7ef435ee4471ee4446e2494e9e3fa7ee57665761fff71200ddb74f269f05c5f8654aed8844fbdfd987ea9b3d338d3e539b385fefdb072deb5d02d89c3ed534f9fd36aeedfc88c7fc30ed8b1a1e7c4f4bdf8ba4efc6970a3eed32df44dd881cd9ee54ff8f9fd3c27b878fabd7c07ecd83032a9917f2373ea6bdc478354274a9ae9f3c8b1d120c5b78d6e1f750b2d925b7cd84e78e40e7dcfc1fee21c146e28330a1b7e180f807ff1383c288ca72f755025782594f03196f0d77f1ca841ea1ece74bd305be857adc2c0eed3207d960f2316f143f7b1a13e4eb75c481ddfd7c73c1c1f4eb75c441cdfd70fb9577dcc44e1c67c02cb8b0b801b1b7471bfeb44585fc20d2d76c350f6849dca0d3ffaab3b4396c3e8c4de1b9953384783f45f98d4c3a1ed5898d26a352a2905bbe5305a00538632f6dcbcdeed982e131eeb3813ae8c2df34bb8f35b5ce9237f8cb88852d95779cfbef38e9b0631efb32bdfbb34d9cb15b2972fb14bdfd1ad897aece514d1f5fde08990b12c32f6b2d6ecb9ec66ecbf4fe55f470c65ef27e78e4956ed5658986c717b49698c15151515154c83cc2b38cc5ed6b8bb13a519cab6f4c2bfb10817e1a222ae089c45475c37bdcb92a7412c633874c9a10d2bbfa0c1b37c195259e2b7d3d3e1658fe2c1fe029987e96043107b97e99247dd82fd7f982c9a450d62efa2897579f9d84bc15e3a75eb493679d8c32fc862d88733349fd982613422385f690809e8953b2f478fec7d8c78469695008a11464ddd0a6551514ec65e1a614610cd8c66ec259386fdcc700c51529f1db129555e42892f3add9aa92e959212c7d02016ca793bd5c75751911ccaa28cbd2c5a328a7284843d267b32f6d80e0cfb568ffdeac61cf163b7c2ec3df3ecbdc6bbdddda7b7634c230646592e2e2eaf26ce844e31416c860ba65b28eda73136e4c3c86b03a65b72c6282557af0d989806274cc601237f0763a35b11d360612e9e23943927a5945218982572b2e3d0c244893f279dd44e171a0f3e20cae8f4cb98d43f7071aab2afdcec54ef75debfbc58e3d9bd77c39a3b2ed4b81b9db7ac86f97dc316b8c79ec32f6e6c8f75efddd3ee5560f756f5f4daef1b5e2087d9db7c79aaaebfbdf4e5ddee8b1b9ac49ee338eee9ad365a4b1cd6a0d23e0b7ba06e9d2d19a621006020b2365faee9c73efbf06b4087361fd7e2072b33f6d87479f879fd9529674148ae714d987af9dc954e7178333da670cca85b133fbe7fc4355e1d7be918f61aec63ae2163dfbd5fcefbd8ad2e3b0e6b76adbb5b23430db96b62de3cebee8b1bdd536f85ee35c735f1fdbdc76e75efb9e89c2633f56e74ee3ed2df30efe90dfbb5f7a7de8d0d62fe953ed718f712d7dccced6af766e626cabe5ed9800e317c3373e39b99e3abf20bc737fae3f797c3d8395e57272eeab0d89c38ece4d7d49a55f88b777b7facfe86ba44fabd1bded04cc4c7cbf4fb4fec59e816eca38cdb68102bc093a53806d36810c37e060dec8c6e551da9b71fd3d493b1b9696f4cd9063f9667611f4a5933265f62b55a5bb3ce6fc53a0ccc21983d99e5c05957947911fb27f600f6401208440fc42813edcba721ffe583f26777114a1e2426e53c79423e517a990425a080e20ae952e2f8274dbc73be15052081c3f6e81973133b9f62186e60a77f7b37e6e3a8f9af733225c6f9f1b1f98ec5f971864ec7150b2eb25831ce239e399390f29c73c6df3638aba5a065b274ce9fae15ef5bc07058557ebaec67bf7255eeeac6e9fad962e392b30cbb2c2b522c46f3611e49b2e7a1fad4671802a85f611ef651ffd3de6f25acd9fbd75caf8d4bbf7f57eaaa3215ab58c53714078c2953a6e42ca489b9c6e633ac815b33bdcf7576440c0b368e18b1213993d4d4be1c968916409a0d1246ed14cc15541b2ce4f8fe7b81cf97548d705b12b65f6e5dd536cc31df640e567e9ca8fa32da0756be8c38a2b0d1065510e5b80412449ecf79516881ed971f27758c4e94c43ec090e0e2ca0a6c0027acbf8c2f33ce183d46234ca939e178c2b637230388f51c5f4b9ab28c4660cd6af47df863c4a1cd5b1ca8e6c4ea065744200852182104274648d1032a8e40128210001df18323a460473e4080ac4911b67964060d982533d09630b1c428775816479f69c8aff23f1726b9e6e8492656cc00851451a4d4008a2110c89c28a50850601103156491948405823ef0044812529278b2414210a61c1129694282cc09577282ac891b42414e80c44f134842e831e4a88aa51f113411028a7f204be2c9a28a21243e44c043133d7e6eb8c2082aa2140d210826303049c10a94d020c8117816e083044e3c190194a723644cfc200b242190a0040e9ae4b0840a9017200d21c40b8ad2096c6080278edc400454032444e10411512081c1153b086a01982b12318a896422d1aa984284233f20c11241b8618612274545a2a460474706cb5e55cb66f0812962c0832336a04226b43d9099122f257ce044153c88e0064320e5e008dd4af75a32943fc797123350c2a843410db2e4010c7e08620a2490646412394ccc600a164198082123ffab0db64b2709f6dc6bdc77da7337e64e862a6bf633c348ac97e36b0950fee8e9883cc81477f80a2b9f939d042e4650c6691afb0a9ccc4c94f16e35aeb999f9c5c4ee1ce06abae666e60e935fa8b48e7465390ad514491080200063140000200c0e8543439138281a074693f403148009909e40624c954623310ac2180a81188aa210040000010600001020c8186db016a248c313788d86471435803c6f1a08211c4cc225803949730c0320c7a6101fd81d8e670c5070b9650d77b2b4f33c4efb41d5e10ecc484f4812e3300946a9b94a7b5ceb48436088b20e4c789e630e4c614029887e4490744a9e7fdfdd0ccb90032b55fa24835888b6f8a5f8cb300a9532c309cb005eee2a0f0c07345395dc4c8ef07034c4846d6ee9ca3226fa0ee701295fe9b5cc7645e30d0a6dc9e59b2a0bbe054d800d5129aa2c86d05cc1365c945ba0e423ca429c9378b000c248217d663cb9a49af4bb0181822e17178a8f59893fd02bef4327259ea263d76de4e2b09bc30c344fdfa0c54be773ec0e239bffde5ba0cff9d2910bfc2682364c54517d18025e928b4600280e9e09e00404cf41f144112de0ffe225c3904a6f6549f2b2c9f6f0cc6c24a3bd24fd3430be4a88f12d6cdec727209d9dfcd2c53cce5797028d79a3d8e511669be93662c9fd11db1f06d6f6daf031cd2820df1045b6b217391dba6dc5c205e32e2bfb3b3fd96db0bca74f1ab5954796907db2d569a9bb18a6c93b3be44c53bcbfa160eef2234777f991df5d7ee44acbcf7e4f86b694c099fa1e65c476a844315b71490bc72aa815496767295b5831b3d8046de660cae2bc3e06d68003b118e948bffc19bd6e694408002b3b025683d13b630ba717864a3a6a87359b7eef691e67d6e896796d89e8b8d852724e555d02ef48e8c958496d7008af28a1b9e7d1ef64cb96a9e5d30a8e6930dcbcf992ab09f515140c16b49da69a81bbdd5a1636e9cf9ff2b37725db26493c4e588e483526f1619a99b624edb50438e567b76814a14fec4e58fe8c8f68f1ea40f69a5be7f916c4900d121bdcb1294535ac60995b4742c0d64e958a2dc21fcdcd8c915d7b4b468485fc9d0a60893be9c2bf2626dd731a41c5265af687e1218ebab51b6ea36117efd806149e01c612e8ad3837736f358caa0093c54cc4af20721709bcf4372ea97fd2a04b945071300a3feaa2ba7a74719c3df8bdb2ae61215d621ae3485863fe4b2e267747355cfd50e8e53ad32abf3db55a04edf15d8873ea8ba75ff17db103ca02433a62e6122bfb7a281eaa86dd80ab336c864d14d95ed8ae2b0ea1acdea44dba28beeab53827455cdea2b4cf12197e339f6fa16d5808079b198150d69db10d4c0647253ce6596590f6d8cfe8b264c348df2d83a240b2db0580188a3742095dc095fd7066f9f4b6a7013ea4227694e9087c15df761c0a286b19ef53674ab2b5d13f706a50834470e8d51d1dd9c3325ba4b6ce52bf16aab8ad8b50ddfb824e884632463ca9ad4aa1427911d15b6b4b1f5dc9d2e7692ba8a507ff5ee09a80dae6c16034bb8498148750415259ea61d69b920ce21bb425d8332024005a4a12c73f7beead50aecd3627b692a50f3d3758c187322bce2d2630d10041fb67755ae4ed9fa799ecd0358c70db75cdbbd9077aae68744d48a4114c34ec9fc17ffefd89baeda5f460162a4f991acf1796e427115f604bd7023dfbe3e5ed3b48ab41ca4e9130dc9731e6e22e3f9be4de055d562b191c1c3342869832c248d3b811ff04c6c95d3f204a2f08bab874caeaa504bb5e423ebc24a249a13887937f033dd5c5dc5c4e8ee5f72808eb862fdce2944216910d96e438318713b6425064a8b45f0ef630b5548464426922a6c9dd4cb8a02e153f0827284a30f96c7b170e671b0806e3855d207dd32c4ed4dd9a125c6f31eb32e872a3282d9a95d69e3aa35955041f6c61014258506cf08ac2f72b9ecff82fc260951271c7a14db48f8ed53279d9e8932a0298cb88f792c6a0e73e6119c9e1268caa2574d89925d7dce25981700f543ed7781f0e3e02061d644ebc0ca1b12fac94c2c1f6690fd8324141498c4281835a99095809a3eac8bb9b82adee80debaa86e1bb90608fbd8337231e74ba0755b1dd09c49950d3572001e4d83986cd79b5e1f53be552c009729a797bdde01d2ab6a6eeb633e927925e791a1884a4a728395b2b47627044cbe4a0cb72b516049a573ade66145a90afb4152e099686dad463528dc0f4e8b7ef7e9bd23473d2c5251052c7c31357fe4d74d7fe3c9d1987d23bd8b85f6310be9de78d082f76ea3c3a1dc2a45749a76e422081c2b392c86745466dd416ab981b90a04a12638d2f1f0794a9ef6babbefa9d1bbefa81d78df51cb3fdff9a12e2a43ffb6792bf14d3b0469172e1e45bf91b0c6df27060d9f2ff937a2262619ce2667993e40243ef09a1fc04eee735149584bd9ed88618f5925ae403da6d8452130ba7a24d09dd4d35f205c8f7c061ae2435a26d4e7d4590f9fc4816c1eb67d11690228620ce18c33a02a4846f5ce38f535acf56a8f73699a50e0d19423ef1c8e95fbf6dd4cd009f8f2ae7a61fcc003dc2762a170ce1079c58310009472fd94ded890704054b6e8675544d8ab408da0f2a2b9199c3da8982d84828b6cf3a727dc6916a614ce74f4017bdfd3b62d6cb28c85a33fa1bef847505d6cba840a237da8180b846a02bb7c22e213e8ee0a0a981f298929ec4b9b6d50f40c478e7c42661f259da3a08fa076feda0c86be1db4268573e3e26b30ee561bdfce983344db32c6a4082d85ef270942231b936640b2e7b12651b19f5e357f4aa745b20c088385a7f4a71da9be25a08dc5bacf8879656fffd32d718304a70a6b077cd27e6fc884aa3458a3c41fa0f6b253bbb353bc668748139bdd5206b315c1635c99a62bb08d2f9cdd351b5304e57109c976caa8006c1802eb2fad473da87dbef2499a7665711fb61d86462290be9b8155a3db9792325a7785052aeb58efa9626f21a10ff082e93087f831d4e59e94ff303d6404a5c44a10c65453719c4b728033c437fcf0e7236e62446d17ec42092e66acb3900200bef6ba3972e6f91640cc27af5bba2ca050ac59e68f75ddfb30b43b6d5894bbe08f6d3477332e39f8bd4b4fe0b6a6a5a6acf2f8deb7fdcc6234c715ec9468481cc83dc55a7c0319648cdf1ec00de43ceb9d90f72d8fcd4a17dac3575e83465387a225c371e1a04942e66b126a93c38c94234855cb4d308e2c78484c89897add412b8e23150035b16f0a79f6a5f1932a3c8875aa148a70c507faf8e0079c959a269185641e0f5a6850003a6d07779939616b8abbd4560844c6a92580b1222cd263a3ced0b16956fde46ae36b968e5d821c0bb83a44d6f61157ab1f32c746bad10a682f04d0732cb30061f2c543d009b340a88b4e7bb5d1304b5171d2c5d8eb3a7ccfe8d22844560fb727825eab5953d0027f4c4a3098dd41482244f0ce9ee2659605882bb29e2e54c77a4f939d7f7902ac82a1cbe2dc03fad038dbd267aa58b72c42751dc2728a49962914890b0e9a32c3121b30f931291b1a4127390146c5a4082db0e6fc47a8dc3fdbef5951201fa2554caba6b9f42c6aa20afff7483706b924cdc9f1c64b4221570cd44511fd7bbbd563f52df80612d2d8cfe5d8b13108dc8bafa7a0aed25ac584f0adf9911dd0f92970865cdb83e35ab860913abf967c06f18312be39213007681b8ff1a5b02aee67c85419b720cd618ba63f1bbe93e282289bbd070831ec9d781bbe59bc811f860be286f6079a0810f53b9c0c916389b6d08c695792a9b8c5d39dc40f9af0edbc9ce44ff2921d24b8a50f619610d4754d14bea70cf306142a25d91e8898300e8c64e1e051daa65bdd5031025238eb13faf978988353ae62b66c5132124717b50d9f987ff540861a9ad1e9873ff4282c955b01be9feb8b4d5aadb7d35c8947de0069f70322f443fb77248c9809163b654906f5ef323a6a1abd0800025c5a653abd27146e0d08e381246a327c778a7d6a0fe677cda308065cd41cf69a4707200e3a2b4c1610d1a8e2b44cccc3014f58f0402f7a35c69d57d714d369de80eacc96a47b031bd27be4ee3cf986741d011dd2cf06058a7839e4828041038c538bc3fd8acae8a3d7fb0c447cb6b58e9cae9b31f0e4f49486912abbe0a0ad06b7039b2fad938e7b0ddf1e60c5a4e33bb599e59cfa19e9c2532743775d522e60aa88f8e3540a68f9d57ebbd49622cd2acf44d0c6bbe4afd12f7c7a52c1261335f1db93c592a6688827b3ef8e24a7befa3a310a0b5b9d565c96d97a9d138157d8eff79e88a658515c1095d3e78430e8866735bbc2c2b31426f6b2be391b2bef0e54ac7a4da7dfe98c4b7aa612452f204ca2be5ca75e6bc2a9eecd01a16349c110d8ab91f938f8502b39f5e728f9cc97eb54321f6cdc18f1cf51927f3357f7728c1484b85d09599b8d45b623dcae64d021032b3ee42b8312b1eb52f5635501ef83ef381e203d9d91b37c5e4d2d2c11bfb846f6450ba622965113f334618d7cea8baf466dfbc4978abedca3a16582d019ebe5e6ad97d13bb9eb36da5bc48664465036d16cc4dabe325f6cf99549d89c35ee6584efb08ed14d0596e5e7355bd9f49a0df3224ebeeb52695dcbd3ddec9ca58d99577e264124a6011a3cdd13c1d4b272cccaf9c4b45919912bf1bad2569863cb6d915c6de2cc40d0a9f2644de357ec31de7336dc8089bbe99630add5899faceb2d64bb656adce9736175eea58b2509d62bcee6187103cbae43440c0785d022f726bc538e2129025039420ac61635ccabeb3630d68fb85b8363307cfca487fba4c954649d2aa587c12c4f3ee5f303322807878f97ed141943c701f87af556520175d026e471a3c9df30104013487a6fa9b0a648b13299ff12a1b4c9780a91f7382af05530e93f937be6f51574c6f6c27d99e0ffcd1936f05ebf388464da49915ca8fbc500234cf2aa08b530848ecb0d954f8476d898c8d60ec941ab1b5a60732fea72005350407d4805adcbc2fb19fd673e7d2d504b30da43501047538a14c7f7289d4aebb0aec42e17245433aa41c43eaec88f577de4861f09fc4e39fbb011a2ba759c9e13bba2a3fafe1f7d457dfaf3ee1b4085b1b670a24003a21f6500477826a69c377a25cd13588e8075a2cccd0cef7b5f9748ea9b00a128f1beef2d47cd052bcdb425c7e3cd9080df017ac5dc2378c8f0a524ad320257d57d5ca81e05276f33ad3ad0a0c98c2212a3591805b03f67feecd8430682bd1326f4a6e131088b0fe01a219724e276ce609be8b38fee18aa69476ff366d8223c935e7d22d57df40738c119a37722d5a673d00973514c2dbb515b5b4dda88bf19ee610bd65f0d3452ff4a61bcacb485da60dae12f12b9f9112b67701ee2fa5d795f602fc4425cfee9f8eebb176d78eda0ddf931927d03d60af6fe214b76182bc8c392965a9b04066ccfc8cb551f812b7afd874045588ed61dae8027badfe8407b473c0644c87bcb4b4a2b28611f057c94b5b874fb3df31e93b14e0bc6ebea0da854208f7656bc484cb0caf50457c404887da67ecf986191a8b83edc5fe40bfd51d7e72778cb165a23fc1369badf3134d6ea5b047291e3829a97666633a867d879c6a6dc1a5e98a7775ee479b8f04755eaa18fa921224563d3f50203be0310c180974f6483edf47d49e5f777b48d68187b790c4d66b618406984ce6ea0f784c8d0f687bdaf16c51080970f05f1f9470952ccb4c00e175200deecf33f4a4f6cc37896158be0d759ebfe917bf7d973f05bcf005e20961afadd84b6c05633c0a32104d0ce3c52c7163dd9618a4fd937d4e1dae1161f2c079296ea9f7542c010dc423de84cd176acbc01403eb7385c4e974e773d0a011dcf9c19a76600abea0feec60aeae7d69396860801b8fa690f0dc72e536fa6825b54755685dc03259f83e92e255c7cfddaf7da9faafbd48304f7c860f5c79590196a255c5168786884c012614a8ae8634b23b3955153e4b2ce48c1426c8f19c43c99a3f451434a5f80c9e6822c51147f8bd9666d9e360ef8737ebe3d386bf4fa8371c07f9eaf720a951d07a5acb60030dfe341540a6309e79668bcfd1ddfb8b0fdd472dd1c91dfe617ce100e99e48ed8aa1d7fe65bf8d060d307672af082453a953b1c3b64dc5f3b90f73ea4f7d279136b971e7d0af1db69b2efd28dbad0a8ca2d49c214c011449c2a1e89016f3eac2fceaef671424c10a239f8a8ca6690209b78042dda166a61745d1fd6dc008a600800d74023250dd22ba1cd4a0592d467a0b592600ed98d2fd8bd84c3f72e2d2cef75016d2c0f29827520204fbe4212b2eed432ab3f5b26586b9fc5841d83e58409bc43844eb4eb3ca4ab516d905ebcd9bc467ac96a759912f3b39735042baf60d6b4af70b767ba156b8d20040b74b6a5fde5b9304ef6f6b09776ab4b31065ca350a366d478c608cd2a66deff7a8e9f54ddf3d1efee72fb26b39f369766f21294cbcb34d2fc6fa90aab0fb369e0bfdd1424acea08265505482f3a3e58152e17cdde0acc3632f6b47b81012c6711a8a86dbcef8de29d84b47319da128e077a7446fad55eb6c0b4c1202bc45d5480f786364fb3b6549cf8b7f4c035dd96e99a4a1c05105c9fb384bce07b04d88e0a7a64e4e4900ec8a2cfda1aed6919fe75ed8890cf401313fcd6a21e48487d63a4142b94d91296a52c7716afe893975589a22589d7f7c45e1d6f8b22277b7c6c08b7d2fbea5dc7d4cee1c2464d8170958b3c5601907802f2ac270ccc4901d36589e2aa030617dff0fb850fe54dd8eb6581ae2e00f5a102be51388db7ef07ae80bffc3cf189b675a9bf83c68c9de6b34757767b36a2ae5a9a97bb2318586602015215d092ea0b9d5b4b0e2971dd6c9b880c87ba279b9c4cc8a33bf52d3e0e0de8e63f62abb6698c4c12e041c15f822503e4e186586a0e97f344471e31cbe1c13d9081aca47cc83a59c9898bc7014a581c9fd028ecf74a5778cea0b644b1331423738f3c4b2af0d7ff5d9cd3a2e69753d794554f5be541c04e39a34b4fea80b665cc36c552823fec3849c13221c842406de0cf2a0bc43f472dfd9c5b94aed95461a63da4f4bdfd7a5e5005983f46311c28d00d7df1ad4937382867bbdf086818ace7a323d5557d029c2175a0bfb59d5867190f5dc5e51a5db39239dcbe95d751e9c1ac5f2c4e882b384dc7b96f79b99b85be812d98cdc1f13eb39088683b2ea9b51da7a423e041d5ffae52feb95cabc2b21cbd4a3be060380d6dbf1add2592e97e9d80dd9df74a7dabe3655f4ca467334e82ca6779742018ed459466b6e813f20c915585848d80beb1d6c6057dec1c7807c7bdae113d9bfd2a16ea1e4d1b185db99441d459c4f6e0a05e41f4d81fa899ace98dbd829a850c31f68ec1da28f2b916e3cc57f689e377cb6e66480392073603f0dddc44c9dd80b4a4025f98b66d9612db2c8ac1f5fc870d6895d97bd74964d1eeec08aba88252d29dbdae1024ce63d304cb7cd867e6386414b759c21423165068910180beb442e7fc5b5d3e88da387272a403bad8aec719f76298ed860efdae665fd0d8461a253a0ccb9b6f53b4d4172670da886776d711859d7a8fac1867246a6a8f029d3dda30731e70034738708fca1f59872207e5a8d5233f6ad52f1e19d62eb97a5c8510ebdf03875e25987f31e256dba899a323a44c4730be0d1382315ba304eca342438b324114b03136567ddb9248dd3432943af0f8e44938cc20c6baba2fdfb1cdeb1e518485c69eaff49eb1a30b3041c85d2d7a98b5b02bb4f1809f11f95b0c10b2ce0faefb6c42b14d50ac7cdeb7e005c0d131260ab08c24cf31eb4adead01057e0c04923c8bb0c1be66d6bbaa1841849a0b5ab54d52c6775f74cb2db16c9ee411b6aa2a4728d0a8f210ca5cbb8a9325af32bcd27fcfc9c0688eb1602c2c6bea5f7a3947ca40f7ec0903caa418628a5e5319a76e9a867bb66cbb0f9124b4c7933db048326bb0f8786daba79079a6064ad5ad72f249ff39c64fd56d3351e3cd29a489e71a29a2cb6f5c03f644ffc45575362c3684199f9cb569a1f461101fdecf9453f8e42d028c7ae1709c13fdb3acd69f5c70bb261f7263ac138d5f6c3bea6cd7fa536f7d7fb918cbfa2a7c63ac32f3c13614755ca1a5a99c59617eb707076fbe6bafcfdd5381dba2502286f1f31f0d0f236950b30b2760f12a5ec1f15c2771db96f8ccb70b7a43ca187fa3276776b5b9a9d4978aa7a154af84fdd8878b3a3217bebc0825364202206d9e320051f761da58a05a9dd3aca57be5a64b7d5598111b34aeb0bcb43a9c60b42aaa343f3297e5ba0e39ee07b52bc5a52e5ea4a681b411e55472cf8f92bc8067f4a92564d308065d265d663589aa6ea2eeecaea63e21e985077572e1e04c9085fbb943a11891d1ab15fbf9c834f1fe6ef5da6634ae59d431393d7e2991e67f064597217245c981e03d717646376aaaaeeda4c66ffb5c0817edbed511ca070ef8a635cabc43d718f716af6cc0d3d5c93e6633d0a890a2297e1b3e2012eaa83eafd37706b63f9b28fda5aa931b9cfeb587461751e70295596bf4ed5b1a85b334b3a6ac8a670f2d89df6d44cf46bea7c6ce90ecdc7cb113727b4f6248d73157f7cf01392cb9fb37ef7990684d7a4861d90a6c5f23b66dc38187d2e4300366c2f105be1143f6b5eeaf42e6400299b16c86111aba336bd9da422bc7774e98e250b3fb6bc2b699535981dde1c5caa3c8f0976ff7f1b5ce37625c097bafc5d5f5fe5aa25dc4e745bad3add2c09eebe740ce68d8e7388fed6d1fe99305d227d3db9c5e4e94601e569a09162ee28e1ffa782eca1399d99346861d10f61d7ba345b06f7eac794cce498bb6a15a0da653764f7391357f2f7fd3eba423cde2a99f4da76a84e4f25d7c31785dca562f2d8ddc1d154168e42eda906c14c22648994c3ba6041edec6e2c1ea404c70021edc0209eb13366f82a34b81de24c7ec97a3e1a5071e3e27b7b5a36a6027ed8060073d1af51515bf75d6a0fef4efe6ab8451e9231d328fed2f01ec5ab1e83b643d0e0430dbea4556f7643fb4cd6d76eebe91ba0e7a32c58325d1a1f0a637873dd952062a17e1ee830fcbe75e3398059fd2055bbfcd894fb7401222487ae91741b7cd75a7959b7f1c401ccf4e065b3932a7ea0b4ea58f575b6bd6b1407d4030ba7ed7a466b09804c322b5485748d1a434107d2f1ee85f3bffd2e6a440453c032bce93bb003ca630f4b2e09540cbf123bc10f7b968b74e1b3315c354f6c6cdf76e98c3f813976604ec61e6e4aa1cb15a3da34d69b4e7d6b051468b6b0a1d2396eb2217c16a5933f99ed25f673c00753062409f18b08e88f7aa095d60be8c010de47d3fa77b6de88a3b00e5a264aee5896858a19e3b5f416ab3aac7899e480306a3a4007a358e4471d942572476270127ace6072643308a3a5ad135914c53c2bac98039ac25829c8c7b346a300b4a6318e598776448495bd8bf28b44edbc503da095ece690422de478c5809164d8e933f5e58729bc3345d17810d537512bda326a8f8f1060180a77251ad57b385d91ded0ac6fc2960685186c85ca13c565923e8a9c81727cc0184b709792d59a3ff8847002bb7369225315f219a46fbd1aa6397b95eaa8d20a9cfc26c28a44c89357a40721e52873a80c06804c4512bd2a3f3a5815b593ef28d539b69810dfc366a4435eed1d820a6fd11501eff4db9e91dd9c693d279084dc6c4c74da0779e4bfe2ad27ec93d564a77360a0f3d0d1d40203f3f94978ec061ced8644fbd4af9a8b5bfcfeb00f35b5143e2752fe16076ee78e68d971162d327c81993e587fac45a2d9a39a3341bfc28b3900f72e346bdda2df77004bff393f9a5f9c21c2e20e79e580c36534923a83e33da381f4f0b9bf2bc0bc24e9863a907070ad80510067f23f3fcc0d2235eac2a7372655ca266ac3605e9833b864acfc09c09fa1be0a12d777f3f828f7f91d833a482e125231bc5a99314cf37e4c402990d37b3c5892a334b2c657a2273d17c712b7f4ccbfefd6b93bbee893ab225fc2b0bbd6951fc4f406a9381ab722c5c50f0737034d7fc2604834b6b374645452ae4fd4448b8cabe2b4d1a1f137ad5196a1ab2b6cebe728daf684fc7a54c2416dda134e33ab1a88864c2350f387205306309b06d9100eef93d6ed0d5d89a5049a44cd91f5735e8c39c370ef626b5419da1db9cca3fc9233c430da77ef0ab96c46a6e651ffd3dfc0750391e0f4541af77ed52ed12b25f270381b9a3e4b55f25ee124c1a148d94ed57e9cd06614f853b423d35f16f88004f5ab57974d0faa2af564ba3889bb21a35fa988d498ff17e220373b1811cb316068eb41859864c3d127c773411e84d21b7acac2780c786d88347e77e427ac78daafd001f1894c33b8143a3a1ddf5d35c9713f9bd8ea439f93a3a206069528eff6006349344f9b743a275e9a1c9ffb477fd7e41e427c0a6e01e8fa13a21dcf4c8c49645df65ab2a0f3d69809b271a42e6f9d9a3d912e0024fb8e791c2e551114a018f93b6cde55007c6ef5797a65c7ab9fa6667c5feb204bde580df5014febdbf8b0a52bfae7034225989b85c8df813a30901beb8f03c2e5cf1668181abe48c45be705857467cd4b562fe92bff34467bfc8a83d583b5f1c9c0b16bfd8b0c0c7a1b01d85960c3e069a00287bfda3240753a5e3fce24228f17b0ca6719bad148e5b78e05bbb705a33899be8f53ad0a9c5119a1b5aac9e355302d079d355ae69b8ef55b8d4e8047826c8d8fd29215dbfa350af3aafee198860c1d7c5fd4a122e7490cc2bda31009e6969503d6d75e88a1fd65ff9e5317139f7317ff0e586c6870c4728c26c077696470edb5024df53b5fe419fef1146dfbb0a528feb0adfd4e42d62ecbd0dc72d1ef209cbda57978a7caf11ba74b40c8d8ff9be1fe1e20dd02b644c0df662bb7b505c25f2bd9e729619df1b2134c3039616a23fc1a1fa7cae77f55e56085d7a643eb015878af23e4ccd25cbaa90ffe4ead5a83374f10839aef5d6d07d076b10ead3f47abb3a2ea421f0b20e5244f3cb17db46f2a9133deabf675c7563d83c474e0d264d12250fde8243ddb9f0098027cdfc6583cf9e3fbf016a1d79e0411ce532e9075f3294e1373409c08191fbd51b287840248416c1cd3ff1f8f610c443653de77b9514f1ea3fd021d92413be63dad38f1c7b95b1dc6a53802055bd13f1d2907c5b8ca021f24c659d98dcef6ec1b91b79e650fd82bba0c846b5e19721be70b1d2986b002726ef8b4321fd998589170b79979516efd5ec41922ad4ccc3e57587d1aa5930cbaa9cc679821a6a3394b69fddba74f66d66b147a3b66d1f3f219f0dff65a1074fc47fb93e54976c555845c6bdf80cb1cb732ed6a2e174412a35ec81de75cdea6bc0f364ae174380bab43e644a6e226665e89766be36a37b931e58c0300b617fb64cb0cfdd60ec829d33bb0e2af411faaa22cfd9dcb82ee0cac9d3576db1b3bdc85f94e1fc4b7e961705b562eb6ba91eaa7a6b7503ce2e375a5914447eb6e7e099de9e31eac2e714cf1cbb6ac6b5b1233e8350e465356cca85d5642bb1124278b739c3702bf7bf8c358d857424c9b974b34a74f70712758105f2f5129b2441df0de07a4cea490831abf4a82ed4991954c6bad424ef4e07cb8b099d8637c723164c133a319857591c807a5cda0adb1048c1c41dce477c06d430418cb206162eb9532d847ba86f45078c7c5aa48beb90eed035c7988c4ec17efa07bb996f84d7001b6365c5ebf320cf99dbbe70e761a33f13e73b0e8e293c2f5cd677dfc8b041bf3cb12a443e7b0b7e87b30a089ea4b90b64432997b58add0a94557257ba1a826a31212544cd5bfc491c4e8377e9e0d85ee95c356c7c7e835fa2836399142390f6026abb7bf18afba94bc31300bfc2418125baa0216a5165098cd4bd65f06a003a0faf0e36dc1a85edd2b40de03070cb83ca386e4e63703121b1bced37d834da8165a83cd6a677992fb398e738b26df96405a1283884b2ef538b9cafdcd351e5129faff2e4c71821b27aa93e0939688a5a93458671427324102bedb7cf1c00de7c482c477651c109c6266faa3425e4f22913ca0c176d8d71b8db644e2f8275458ad2bac3f0411d5620ce1cc7f8d6b5bdb4def75ca4933bb2054c484eeafa5d920d0f71d5cc40507b88429f7f54af240c740066e48059607678548301b096d2de72bd257cfdba6ec6d996497149c472e1b3b89214652138dc53125111b8386bf8dcc0bab5b4817877e414b39cfb134476e70d73986d95fb0343f6f415ca84eb56ee0adf76bf9b5729dbbed1027f08711ee5d3012f699239cf22caf43c4a331bfa6713236dfb26ccbfe4db6f626f272f352400695fcf856d6443954d7adb2b047736de754b59005ea128990ca85ead257101b76a48146788b18dafe87b607d5f7c01e266a570b4aa9138e441b2a9432e414112a11269b6ccf50da5f137a1e50ecd2742266e34e56e2552465823581c0e1b426a30c38f93437a412b9d39c00b185ca62567c10d17e95b57b14090d75420498089afccc4b2d9997d2824f71c9e54786df64275825057cf691262e91d8b4218a96073ede460781cc219218ce8aafb2d74a5c57acbdc27746b7143c2bcbe6017ae2576c428035106f2eade65fd04abe14ca931a713bb2494583738809fcde4ca05423588145d050466845cc8cb9684c15e0a17714c017245a9cd53912143ae88e9568190505410eec2a8dc888fb15ac35f0412ed4f0291e01a802fd96c7e7fed50855458872c0587a0d39b07b0ad8a90c151d633ba285c2ab9036cabcfd9126e741bf16cc50212548f38580e58a8ff0a098ddffd854c40322e938f7fad8a3468bfcccf904e76c3c2c4f6a818067aa728d12e4466370aa3544fd72bfe06d61ad34fcacef62490eb19e873e94013c671ae6667aae6098985c9754a8135c00f816829376b4308f3b7596787aeb917365df41d6610ae3efa7fc94edff8a4bc0609a48b1133a295645c3c8ce57b05b6765553606838cf84f777ca5cc9d34cfa1002ee5fb0ee4f06df6984ff67795815863149130847c288bda86030fb7450c126886a936270f9c185548921cb88bf7e04320bdae03f63ad0bbed511ff5bebd4aa8028e77fa20aa2dc73a8a3ce0bd5a58c6f67900ac47845595645b56d68a80c08a662276b83fe5b0d7b6ab764a43e783032c8ffc2509293303d51cdc17931c1fe4048cbc2b6727a8c70b465c4d227066c4d7b9bbb8b22d1c6c2e23c879d50b15981d29b5651b8df040569269650579727098c4f9c3b73fd88c5c30b1ed125add2177724a8f894fb9364f2b466dfa626ae329f33173cb4ce50e0f0a497ce3a484b844e8d5ea606ca362dead5b63423f9ff395504f72e577c3cc64f57edf6f9ed98c475eb29da21bb5df432aa33667209caef10f19373c85b5182c6a7058d1d60395b7ed30fe63ec257347bcef0d850ecea95e5213ea492ed422d93e24fc51baf9ebaa196c07ecccbef397538e5d85fbbccc99d66342c38084faf94d36b0acb334c46a208f58ab3a4f7d0f705039aaec096fdd6992502d594bf597a115687c00f0c0bfa70c06f5cb8ebc040cd5fddb0c0d70da66a0100ca7b8e405b452af03cc1587089e78648c5d6c346b1a18102fb33a75419e8ca818ec1297e20497597d999ce50da5068e0807b9277ead96ee075a5c0cdeede3df17fc32f089665d129e091ce5f7d90ea6aaf73a94eb7717ac17c62118c30ac9cc2582eb7c53962840a1a393ab3338ad80a63e6d3154fb25a161a7f17046de8c63dc4ac8c92162760166b42824abade51dda4006d960d42a459f0efafd65967e6d213d11173c1925e35c6ce4f383ac067f2a800080fbe81725d329e762b1360042b3d5ebc65e9b4c722ddc5ca702ff0f9d7d5518adcd70fd6334d0f0eb5a65ec0e7b8ceae56c1f78da9914f80fba4b45489b45b6d48ed52d937acb7817bee94e77932d7e32e7a9fa38338631de76e8c05d989ac3c8da3cf3cec92644e65ba5cae71488fbd6b6e72d3c62f795c0c42f08dcdcb730cb50ada173ef76f0fc3921be95930f4db10e786bb08c463acf3416f1c55d0eaf67567aec58fa3280a9bda95db8b658df161e52d2f432541dade8fb17219c01a515126e95685a173afcea19118c5b402197374cc45119770363199ce8b21832cf444810ba7e0cbd6a375a41dcef2d9fd3f64f56054aadbd46a83d07ffb67256f57cb8f8421f8d66178fef69d476a31a0c345846889c03033c4802966a76588867fc069d79c9a4222d0e9cb8478b3ee774162c74667106a9018469a9de2ec2a0fc7988937a3b18cf34b13ee71dbb518dd39fc204dd1cc950d6744d7fa0abc3e87121a2660b38dcb9551b7ed304a8751dd87700d8c5e9e0c266b6417b4ca2cff3c3755a1cf9a47e2b5e2574875d744ee5758b6cde0d343c7d4d8e17080a27b70a78a76d59a6c5265c7dbb87fa07b39bca0ac907f059bea5615329622e3209b753b40cfdceda510ed35ad4ae0146dbf0f7928ed8931aae46116694a6fdafe2a2b23282a29476c74670db86ba99e3bcfd74ec31f42a13dad378b48074558f28dddc1f32ed9e669496995ce4949288125f3879344a15b7dc282858ed442d9bb1951a89c230aaccf75723f49c19612226a3eb46d746a9c828f37051eb0f0f9766a515db7c5cdf2a9080b0d1cc0e4ff0f0015f1d1d031a53dd13bb46de1da8b14bd4d88eb6cdb76668c27a0137e1814e1b672b86aed44bbb41ca2c9c94530746e43849b2b6fee13cf96ded02adf7d8a2ec13ad6c40806d3a130bd596c7d4739c19bc89cc5bb93909ea9e85fc83e83f71b81248b244540be6a815b55e874746029a3b2fa1a58c04429273fe24a2228fe424c6f854bc6068213b1513f8024059cd8399eb59e65dd076b3523d80528a4a821c79f66425f193e12a2c88a62a917f2c010f71a86a04ba35ad49a062cbd77a49033eb3e78ebe8d7da0ca50a2c0577b41c6e693e8092ffb3e1c4a0c6afa08400c47b2dcfbd254b24565be6011c538080b1ae9e53d2db87139fcf04f2c37ee64ab3b715d673655e48c422cd7d918a20b5a6d513104bd31266663d251f5ee9aed9e026fc2baef95e1a1fb0d95a51ff5f58cd0d0caee49c14ed9ad10ca3ba284aec806d936dcf8beb95c172e6a0bfa53fc101ae691587efd2a8e057073cdf3a00aa6f9d05e7f4c3c79634b4f7f23c01ec34c60bfdf49d8e5b14f328a6993feb007e6fad591ae99f9755eaa1ab904537f55b4dcc102f6bf3f636e2b34658454dd9f7a8811f9b415fbb8f2a95788b386e5183a993601ef59f78be52b7c4e13e6bb0210df4d5bed98d43d98a841d8fc9c1c2ff4100de51dc2cd3ffe25f73294c17c5245f8f58e3d36e382d4e2068cec2d7b5f2bffb6b90b637239c5bfce57cecbc3d83c3b72a3e663a9a8fb44638257d5a13d89a3acd6b071415ec07ee5f38df5c3e8dfb420350f5743c7cdb8d7f004074962c15ffe025d8141dbef47964fe5e09532cd3e1e7c32c09a8a28689650fe8573b471aac47d87a4003c2cbe1e3eab3a3048b295dfccf505a9363b47fc42f1d99c8cc2cf02744a80f2801e865dd4c9daaa2fd4f7ff84770ab553eeba4e7985f637c7c45f6368f4537febf8c528706c83ff1a888747f1059fe705be114c915c406cb4cd9c799ae663c5b29bfff89fed2b3e9dea770573bcf9c2e8ed5eb27e6d3700eed5a914302d41e4fa5015d67743f15b1281f5efe464a7898c5542c794fceef4529102b5b482c1ea5627edbf53a0ce50db0d3865ebaf0a206bdfb032f61b38817a4f753f3e9be27aadcf47286fbf71210202f4e6a9c31f8dea521cea2e404cd73cf5fafd69505e2132781ce223f9a12f6ad49d43b70035e1d61f01dea7b0bde9274c276f1efa2b4195c50748d1fc8581b34acdfcc7739014fffb3193587591e4db6a39f2880e1f1be9949fb44a502f649867f54eac012d76b9ba3a7a2cc2c85649dcf55d2bd2cc9277f9cbbfd7dfd32aa248f2e3a9e5f3d3855af14ae3c3d313e8df3524be0f09c4137d3f2e9112363b29e59e936a8329d40d1f858d14d40c554e043bf8332dd58dcceed8f96aa3571a84f52768ef8b54bfbc8699a514c801160bf7d453501b92ca0395efcfea4b633d46fa4f4492477a0ba4902b3fc3c813a89efa74be17ac8aa078b488a7e348fbe9b48579db1e0164cdd2adc18dcc90da015480d2ab0b4c4d1241ec58096fd861be5bd479ef1246f90bf7da04f61759af11d00189ae5885cfc834a5563fb4bbe8971d2f7e74da956c4b38bb839e5fcf307d31d1758b205f6f42ff480f76694abec71b5cee65aee618a683bf0acea8fce030b651f13f91fff0a829ecae99cf82deab103afd4fcd3cc7154f1f40703a00233374367313ca4c1581dae5deb7403f91cdf5f2aa3bdacbfa93b6bea630760f55965f995febdec524065f971027512cf4f971ad9ac7117dee838ebf3f10da0210b10b862fbe804f08fe68fc730afc176632359a28a262c3edb428a4b9ea07f7c41a5da4042cf201f5eb66e861178fe9db81f75001c67751277b2c26f967ae2aad09f55b82d3a92cef7e115c99b4c9c5f6315b9cf327fa3d2380488ea8d081950e78ab39db3ff91d279304eeb1b954f63bd6801d4fabf41e91ce12fcdd895f21147c89ba0677f1f8200fe9473a3e5ecd74370c6d1734eb49e7d7e4025dcae9028a02e576d6ada379b63d29cf5126380810646d6ab34ef3aa3a42c0b39ed55258fde70c0c8db26b14690a3d8b385461a99866984a715919bdc5e46bd2cfe35a7b8e63d1f73decba9c4a479fa940734da5816916872abfa799b5dc6596aee2e350e5836e8d8892be1d6df5ae1bc959ecabe86f8e2dcc162e2933c317afafd829558e3e2492723cfba3e7c63a926914fbc7171434914bff431cf60aa38b9fd1be4dec30cf19a4a66d2c20a0ef47d2a0efbcb6f8bae81bd38eb3a02339b262c28014e4b112519cf25c2cf3a81d269dc1c465fb36ab7d4cfccc1bbdec4152c2911f6360b8be211e3ebd263eb27f96bf01db1bda2cbc8c19616102a9bccda90598382a8cc91d419e2f9c3e2c03769568c1843ba96c7e1544a9037c52849a1b65991576ba5f6825c7df25315b7e84c94f41d50cf83114157b3322fc6445e3103a5e8939404d1f5f59badcdaae0ea6742f47ff40fa268cc26075616c259b030de7d4337a57b91aa1408b44ab6880022fb8012d8ce171cce14edb703e3ee64ec479088939d59af47ebc82a2002462dc764593345b9ff5fe24b987ebb878bb9846d6aed8c3cfa0fb944b1346acce84f1f087dd3f76bfbff4912619beba646242bc803de3fc99b7cf3a260aa320fd3b914820a6ee179cf7c791809227b9f6bbcb0a4fad121cd949964068486231c14132740ecf6e73bdf76c8757cb7f891ffe67cd481724f1e58ce138cccb03720f9395e4e7f93bf912cfd80ae0213de325500fa0393d4137510efdef1d820b821480f16013b1f11d0123e4a464abcde7490f4010d7cb8c4f85deb114bab28f5c1280bc70e6d208b2504175ee36c9dd8813a2a9d7ff33c7084f143fd6d3b7e9bce1b3c6abf732927c82fe86c617186741afffd54183f151ae5671f2ac0d835c1d044aad954e472336fc2f0ac86036eff8ee31e1d669be804b7e2c0db765c998a193fcf95e0a98a3e4e20a80ebbd0530a3271a3188b0d586a5f851ded326efc74cd9b85db32bf04ab6354cb725346d2d6082828f158352be57f677e4797820ae1210119c0ee9af368e365be1d54631de4f4d385858893b110157b55999ea1450a6fc90ae9332d754d1466406ccc026b44588ec45a8059e552ab17358addefe95a138e2b2729204e2f9fa0a6ad9b2866930a3d290f625b18a4b67dbe1cfc3a07e9deac8a9eca66333f7f7ccf3077a1d116fc69cd960c6426067cca66b6c933abe1cce89ec797d1693cec426234d6447253755badad8f57e8dbfcdbf4a7c6af72c34f36b87896159414333db8ac60514c1b605872415aba978d7fb338b3dbc891e2784d75b0d22857218132c6db7e572fab91fd307479b77b4afcef10d3cb8d18384ba98d336338a014a57b339b7506ce72d7f6488033a36633d19ee8b81c28c85d0e9a9970feb3fb6bc7c0c4d058ef8337702865613e86a25ddb7bbcb777f29ef1fe4fa3a88441d701e7a05ff656fb273af3063fbc7641edfabea2e66d2bfb75e542199aafab74667b1736012379aa498db2d5babd119ffa24e8355875d6022141508269ce8466e6696282162668678276e668618206e634609a36266860863633b466cad3c89964fa0507cb2b57b57699af900e83e830b02e83eb36800e03e81e8cce03e930880e037519b06e03e83280ee01aaae64001a388a3630c605f73598f13533180052689f072b07695e4e100a014c410a1de7d155ff0191422b33e6ee3d28084302844b98b025bcfe344c08121c4222ca537201acb5038aca5a8c59305a554d3aa949d641ed4014089c69c68c5c23b027d7066f034ffdb611bb2748c708cb6803ffe328601c19101e3def015c03500c0fa261cdc6289cad5a897045d5ab4364036aeb6646895adc92afbfdf12a2d60821646f2977d5089b08c8083918169badd1e48ed288a98c182e3dc9c37ba2bc206873708b3e46028a1bedaea182072f2fe99ee97bad64697adad27ca729dd86d6b7c5ee82b6c63cb345b214fcac41b106fb88373811c757cac13c3670a9440335328272ed6de1afd78b73bc1b9ead61431adda861a38886b15c2fee8eaf17e7300fe9e2e2b38e7441797c44fdf1cd88504b27bdfbe8c9e0944ef241360b26a65954d5076f432b89aadee1d1a22a46e9244b433a0ded695b231db434ece39f389b34e61fc9424d86d4e816bde709318e74095247cea174877499ab1e1519b0e052904f70e953255ba89d1d5913c645f40ed74a8573e8d6241434ad26a8b3588bb266d10be00a758c5d3a8bc96c0e7afb3266340c35bfb2d19d5e8674715d7a1ad245c5a5078276b4e3544916aa8c098bd198890956abd54ab2d0afe04255dd7175691b7d2c8ea7711b143fef3ab65bb2ad05d6c153691645358bfe74fb1336a389189d5206092ab711b9e00c9356e152229969ba403f417e8c807e8274692bdd902e2c5d38ca38c069186ae290b0d8dcd1a8228c70e98188aaf96f7e9e64697aa6a5014f3acd67bad396c48d26d3dd7c2789208b3724cb4872c7d8fd2129d91a770db5f4d2e5f568a9c381a4a7f49cc83e92859ec51bcc83d3b109c3217714618433c4522f684251e3e4f00ddf14d1d28479b4eebe34ebf4141b3a47d23ada890da2a49544794f2f52bd1451c517556c55314e9efa4cca557ef2d453883d6d553ed8223a57475f8f7ea7e722364211715057f19388a37a8adb20e29c8e72907da044d455620fe92944224eb3e1282211a7a97e12734eb361a779083151176922e1c1a2e699309c1e921371dae9f46c346136c54da76f1e2d245deae9fb08b2857df867b686882cc6f62104f4f333a4737430f48f7c44c2dc443539174d2b984cd349fe3158452e41b949ec816249c41e2dbe12734e73f11422ca67564749f19a155fd992f7983e93e2abaf6c0d8a0babea9f2e6939a7b5b0ab9f3eb3faa9c56b4ebefa4c8b94b7b82421b13d5a5c14556ded577c463c8aad41b9f815b6a6a78672f1352b6e2f692c4455ff864bdac5dfc56758fc065b93721677c1e23527ff256db5fa69f59cd35af09b872985285a51ecee4a7c0bb17974d047689fd9a23943ac2869a2286917258d85286925dd251992826d0b9942cb3f40cb47144dce997c93728ab2e2e429aa5e21aadae6a89d8e82723a5dd2524eb6c7bba49d78fd1e7e8d093bfde4f4541e75d77b8ac8454f74ef88cd436c9e063a41e923fa24ca99a209a042e4c08d9b9b9b1b1acab6ced01152444963f19eee89675be816159d6c48bac40c3c371ee2a0a03b87b6ed05bd7c550f8e729ff50dfee124260c355bf3b5a250bf348232228da04e64901992659ec54e6dc9326770f6c66ccd9f70903b3f9390ace9138bb95c2cd68f9a393051a91db206fa1a03440d4ba359e2690f1515155ef3f411dd4252f27254ea3056f40152e8a7429434942869df8bd42dfc8b54ee8e7248862684aaba2d6e3f25143da0c2125a488308c4608446dfd2a38e0c54ed690b4ba76872d4acfee920b681348b2640077564a0be99309c9ed389388de5f42c74c3e9f928c551dec23abcc330173839a7b19c88d358d487d73b3e6cd4c226902cfa190f4e309010e972fbe26df09da883bb2700dc85b8f21662eb560cc051c4ee2df24d018a3dac55f55bdc8676127be0f01b44fb16afd9b758dd5a1c224eeb49f11ef00617bfe13634abeadbdbd0724ec3c1b26e5f639da6c5596f5bc3e1f6d6d2d8e3701bdad7a793ed81c35db8b80d6d0580af5e03c057efaf56eec2d2b8f8ca695607c06d685654f573b80dad85a86aab8ad1ba7dad75fbbeb5343d6d6b01780e96c63e00a769f1d66d682cd65958cf390d8773143788bc120011005e4b94b3852276978583d86c82d6d9d94921ca8b2276f724cacb3ef406d1bb3918514f2c176119a7be577771fa1b13665b7c44b9103df18724aaa495682d6e3f7ad785a8eace5a89aacee6a8adeee20f9034179606355bf42b6b43bba4d98fac95e5001fa1f57497b4161f51b6c54bde4254b915c59b3eeb4e4a966ac55f6421aa882b441b44069a2d7acf081f352b8abe113b2572d16cd1ab4439e94b620f95a78839a7a9384ac421e2341544973ee73415cb3064ffb8f41409c9a2a7dd95378512254d852869b27de46044e5ec2cc6402c8835cae6a44d72b86bb368cc647a91af0feac84080f04fb7cc53d58b1ee14daebd5289db1b8d090bb902927726ecfbc320cf80804b3fb24e8c64a10fc58dc662a7f6dd6831d2c5e4f974967d065082da99fe89f531d2c574e93f09a65e466af7ee0ce4a47b9681348bfb64ca726ea61e21c94d870089f5a1ea6ebaa4418079668bb356d559558cd24d9f29dd649af9b8d0d2982dca3e660dc9b223670ba583800f5c4a3fba2ecd8189bad9934da5a03610b7055ec15638ee2b2f9332d479eee30af7ea166ece395f2b34eefc8aebd5dcf6e21642ed958e59e9d90d833bed582912434b10810a0d55a19b7958820494aea8fcb7534a65873d50d699690bfdbfc4077e67934105ddd0c995434b78a1282889a2954b368bcd62cccccc4c29534a69534a245b99bdacd021254c4106778c1575284882177aee182b12628468280d4542288dc5624af041ac0b45ee182b0a1a2a0211452b572c368bc966b159aca5bb25f38bf5158ecd5e88f82b442b2f44cc432c16230d1509195ae2c71111cc1199ae1c4ac21ab84d0946b629d05a4429a5cc4c29a5945246c009aad7ac7ebde8eb4ecfab3320a0144500156d60d002cc28b5400131ac21c81d655015869280062a54a2423724e40815ee288198f012f312d3ddddddccdccdcd4c8db62e0851c3127794411f98c1cc609899999952ca4c29a54d816ad800ea6ea059d14b114c4c119d01010d0d150174e40c779440dd0e983023169bc5641c9bf12c268bcd3a36a3c1b13b8d64b31769d4dd4d149b311ad588c562434a78c2a5760a51c318ee186b0275c95e5e6260625e62829839e6052608e62586ce9798d96b4e6934ca267ed0a01ba32d314a29a52f4141434ac84150509195d88c6730fc97664deecf5a84e9f37b7a30b3170904d3cc331896b1b61733b3805eaf570b7f265bf34053020d2d11844b8138252c01856ee8b301b73dd3c79d3e3f0870276d178b262a6936853aff756077d3377dc3edd4eb430e01c1be912e7dbbc887cf0fd02df248eccc9963ff7414f347b338d02b7de64c3b7f90ba892742908de8b4231bb9ad37aa44aa3839379e473bcb7d6018fe2085ea63c2484e29a97b37d13012db3fb345ef512ba1b8f43381ddc496731f94e3b80a1e09956fd10b3a7dec58bdfeb13f6ca70fc942cf83650db579e85f32a8a69913eaa0ec5c6a0a7ba09265fe233195246ae2b3e59b3e820ea94e700c0808e83cb6773a014078740349968d81a48ba9777a47bac0ee36efe663e67dec1da2efe067cd41bd038acdc34240bd730474e401f54e13cc40e46e6f1e473cf8888fe64927cdce36cfcea6da54d3ce800f435b53da685bdff051b3b6bfaa50e9473ee292d8da9e83ef2881989a9a7aa29ce53054392bb32f09f4da743c23943564c890497f363a29fdc174b63cc3a5434877884bbad09707eafc4887301d424f87748b4a6e2c4954ce32d190d7102af7a321d205c6d57b3777dbe8f7eff594aabccb004fba8cf0a52aaae8277eb310547949fedd470687e49f2a06e9f533a4574b6255277d9ead81af3d3c6d4684ba63c7582872ce6c6d27b26d2c402a25a2ec6380a33af290217209321c71b733916e2192674882c7177abc00086230427bc9abc2453c8489e6587339eb922cdb57562b5a449ba4856d136ac27291666d456e916d7ea3734e21c9b2b1907499dfce479030a6821017612116922ea6e622b40e54ef5d91ab9ab94c7755ed343d638f1ca6759f59a1040f6d032b94e0a175b6a63bc97ab3b5ad5082875662a26459b3b519000788b6bdb3cc335b9e2869349b83afa42618c9b2bdb0118e065c79f0e0c1d3b24fb3eebcf87375f4e56f30e813786c77641e3ce419ae4ab7a8a4156eeec856b8b994877431cdeb0324e4f3339b28a27a3ac31c3c87b86c519b3d8128702b02ad1111c99071c44548171da44bc9a5670d4817eeb4cb6994ca47e78d102dd21c0941336de850b930b553ec8720f59b610fdde43acef670a7016ba5ef25cb3744327e90b00c705608c9424feb40ade9a9211d7c4d8908b5a6a7063ce99ff9ae8a413af8999e1af8ef33252cdc800b3350c1cd0d0db43f30219b006395b48f07087e263c68c1d7901ef66740bea135ed238992b6c3e6723b62b5af038988e865745d7badc4568c6c5dba828f4fb72865a10400a923070d096daa17f36e974fb8f20cf76b9012e0d21046d73e4dd4964fb83b48d36539296521957712ff4c98cab3b5efa57b9e2d59954753fa67559ef5e8733042ed2c0f590eaa420dfa5e3a043e7b23670b024258c9734eb99936eb922cf44395edcaca75c46a73e2eb165c59f8a2ef8b64a19e0b0995c5928590dad117a60b2359e8590881d1e19a5ca6c1ae1054f660dc021a6dc1156700d12cfa17082a0892febda67470e623fdb37c4371587207d24b224e4e8c46b22dd9a227c2a3e110e0d213e1a249b9c30823c08b74e94b553e70efce59dec1f645b2d007d5cdae545836e0d2606408bc156dcc2ce94a6c64deeceb75a927f33ccf93bd288dc9b64db6518e523aa39452ba514a79ee665f1b1160c8cb7574d6aceddeb7b395358b8e32f628f53c4f9451ba5d46a9d7511a6b96ab5994524a69dde810a8d09cac395f332b6bd68b6c7ef672f996bd34aba5fc94534e39bb9729ce64f3b397d953f632632b2b57bf8550db0544bbba6777cf4683dcc491bb744db652cacb9a35cf5bf7ec29bbbbbbaebba57cf7f0296333c9d9d3989497524af9eed90b11918c586c361664326e33e204176d5352972c368bcd3ccff36631592c269bd1199b6ddccadd1e9bbd10c562b1cde8725b11278429ac2e83ddc2f29f37caae5b5dee1cc771dcaa4e98cbe5e2ece6a21b58c2073836c2cc1cc771dcc6fd356b16c7c95e3819f720482fb5d6fa229bc9b8cb662fccb217e66cccd52c598d6e01629b2133d2c412787089e348b04f648f4997cf778544ba675f245136beee4692750bc923914827fdf3441969e3bf623252bf646c5daf16596cb67dab4dd8eb75b76f6147a6e008123b29688902235060043da3502814ca1d5135264c553a0ea595ac0a071fa769df7b948e924635a48bebd2dfc091438710dd3269b3268bacb3a50307ea76a6dedb63bb79df1ec4761bcda21bed1a2cde2843a57da35bd852cf43591bcda23748a2bc5d83fe06f5accc8b4c84699614224284c8a54290cd00820ad5902dba196d561a15793d8ea46013e2a7593d045ddacd39190ae962bae3bce99c282e7d973a67c24ca7ff58b3c534aaaeeb6c6836b4300c69ea43b09aa4e9a1173eb4aa4ed559103c68696c682db29164a19dd3d7c45df78f39f4404be39a2d0a92bc5d33065fab072b0950ad3eac257d1982d5d2986c188a34644844558c302479f8ce961c7cd783b51efc28871491945efa27ace4fd19aa62984ce14d242fb134a64e1cab2a06f8f035f0613d68c187b6ce5627caea85375d55faaba82ad91cb57a90a656d6f85a1aeb6dc9c29285e94111355bfc10a85b7a10f3d9c1478b47dc29e9944e92b0ceb9f4a4cbf7d2bf205a0219a092de279d34eae06edffb87a253f9924e4356053d06ab680a65f899fad0d6f4d4c29b5e037a5dad243755d6e5cf985e5f6d0d89651d06191443ef424199870420a176ce84550f558f629d1b5d97422159e85fa432a5e18b7919308f5cc9c2b2c5ae1eb47c441f293c946969faf0bd3b8c4f07774b76ec63a02b89a4770f24db968db6db390cd4dde8ecd07cda8864a1a76916edeba4a061d2746bbb146a56c77136013a08ffd14896ed1f0f46b5df4574cbe8e1744b4eeb8c1e8ce99b0eee8e17b0b9a49b74b6592b0af5b358ae8e7568a48b097c91dad7072e085a225d960ea35fb23ab84bb22347ba673a49349d9b356b9bf50dc9b26d13e6ddeddee66de723c9b23dfcd7a4731bf7cf72a4730f827ba7764adfb66d2bf10eeb346bdb389eacd3300e4792651cdb45346b6b9c4e4661c4d646dc6d7b1bc13cf4b7b710eab663e3be711bc7711cc73ab2b57ddbb86de3ec585987273443739109976032b345b9b9e69a6baebb6d0f9041b073e1bcaf1442ff8aba48a88b848426ac8f8e848ee6cf0c32814c9fe97374346f7ae614d145338a7963fba8593ca3e099b5929b9c4645ba6c134ba322d91e2a2e692617fb68de348baa106164c41251357f724943114d8ef299929fd89a93971cc5d6f4d44e5ef21a9a9e1aca4f6e4eec10297e72148bb2343d27b686355b969683116af3a47a2a1fbcc94b4c5ef211c5848995b3c4c658499c589de6d1437a28da705d072504955926a2a4f1d1a4d1e68e6e99a5cf23bae5fbfc215db6279aa1e816b9235d60c8cbdb07449f6a504d5ef292059989b6cedb69c2a8a885843c8edbde79deb97796a6a766f292a7f808c24a4e8e72937b9ed789bd8383baeda86850ef8e3af6918e8a0e4aa833070c793b48b2f41720857a6a1e9d386f60f4eda366f56de8a9a5c900ee77ee74cb267b9cee7d3cddc963f27e8f9297dace1fb7df39ddc259b0590c44e8a788b66c41d2455e9889eda393bd399ab0a9d3adfed4399ab0dee956bfd6225448d4d6c9e1a3a6b47ef3f4a6e329519b67005ca81355d446dd3e90ac4aa6e4dee5a53bb3798eeaec6c3f8583ba710ad1441462b6ba03353d3064076a7a363bf6287949c94b7c5cd26acc568b37439c5ec32547f9c94769c404ca89e51f1f499834b5de4d3eca23264e2cefccd60f499458ca3b453420925651c1c7713797e3b81650d49c69225dfa729c0f2347448c8c9e9893a3b81ca5f443405528c0e54ec5ea83eafa4a33e04bb6f4cfca49daba0d7ced3b686bdf67e56cd1128906048eedab0eea76be4bbae448970f48580b912dee56b0c216b61086308cf228077b620bae5c0207742e7311277e88c82568200aa22570c0c7e538ae930213914e481736922c5c034916ce883ab20fe380f392a8422ec747a045b33d2c7c32c8c506ea76157d48bdd7bed3f4505beb1e5a1aef9dad219d3b4df78f7b4de9db6d68345e13de7b277aaf31bd3b028eaac9aaf8dfbb87f6de69e99e487ac7e8d87ae876ef24ab9a5615837b772232389dcc9da72275dd29553d5ad2355bf2ed9a4d4950a2c26ce679a3377b6997ac5b31256a3fd63974a0f3d2eed001f4e6e6e6e6b665c9da3607d03bff358e79240a06f0918b631e3972dbe698d7e15d962cf4ae6ec140df395dd4bac4eda8d9da469710320cb3984c0675aed786029e4c304f66e6e6a67d35d7dc27b7719cecd5cd71739bb2f97ac5baf69afd02c2276cfbe8badeb729699f2800973bb76d7335ed134be2b4c0a54cfbb6d92ce9662ae1c4d1e4965c7adb56c9326bddee490a76531c107541e09cd87e902e1dfb81b5426d2895096eb2514cd8640124cc355b1bb5520125975ddba78d1064e6e44b962901ee27b0a2361f44a11b4249179474d936a1d113b243015a3bb4b614094b91aded128522862a59f5e2a0b9fdf94d0e69344061f2cab5f25a79795e95af15d7ca8aeb357be51503899222f7e209f6c095426e885c063a12e46e373f77e3af391f486e1ff9910212ecbcc008c92bb19719cc0bcc4c4a0fa65f66301b9dc1c85c5b770d1b73ce8a5e8a6062e69c737677cf1e3202970ce625a6bbbbbbebba615e6266bfc4ac34eba5099806a25bba633ac63c0491481074440e548004033e12ed3c9bdb954adc5bcc01a7922ebdd7487a77b3eeee39ca962529654976b7945dea26b1d77577737373777ba8eea6242621a1f2eec83c2ffa6e977d4eb674efde6e5b1bfda641783afaf6b0e58053392b6950f9de6af60f3ae7ecd938cdd2c1a1de177ea644fa2ccb86f49d742fbcf799efa473254b135aee25ee7b2d3c4d0f67694aa38c1b82228d1bb747d795d1ac39fb98adaaff3ec7c33e6e5e743747b2cc791a399fa7cd3937abc3029d2b5b74445600741493552aa0e0b4821a4cc004489c4f26a87d963b2a9046f8fc997491524a299999999999594ac92ca59452ca34240088942c470c4941778e65cf187694e75fdca1004284dcb100e215c0954db8a9125c01a423a87c593382048d82424f07486e51d6b159ec323a76973c2f002762b2192dd9e846c5de50fc959e81ef29e0956189743959b33a2ba56466666639e79cb2a483921da47491dd2577134beec7607f6c5dee9748170963cbdfe16ee20e57863d802aa87cd9415e505285ca2a7a2a98e251f932061293a2fa8492b3965e7d81c751a0a492ec31bd3a8b91519b4144c68cda0c22335028146a464d06911974d2da0c2a238321523b9a01858c231a5040a183484d4886d00c1a42a809ab1141a188a08810e994989303b1179998da904c2da636549bb3d6866298368da95198d7134f3c61c3c80d2180e83863a49c74cea1a11b2e88113a7c40ae5c323a8b3829b074a19d034ee5d3a6134686524a29a594524abbb9b9594629a552e80b2c6328018ef364996741c34aec857906d3ddddddccdc3c99290331d07c8501908e547197574a797ecd62606464c3c83437cbc0740c8c0c8ccc4bcc258391a9492118995ad31addb37bb6140201f540fe6b16032323142303232324536bad3230314231303230322f2e9818999a91904c8cac2613aa734aa11d3578b4e90c7803df8b3e45793a78a0aa9c523d4e18d061033cda63a2821486dbf36a45a17ed922bd47a1c64c837ad4939ee772b95c1e959ef480902133637aa09110ea3c68e472d14e0cdde285943576a7af663bb91f9e30d209254554b73624481e0aaa86e7d9134a10975eb6e649e2b4714305d43bd25cda3a98fd842b2fe726fe10a46e93e3d8c666b15973cd79b3982c1693cde88ccd5e73f69c734e4ee7932b2aa32b12b61d8008957e3cf9502ffd476f6e2eb539bae7d0e1dd2b7598d7811ac29d0f0a728f81e629a909c7bc9d9d4996f9510ab9f4e3ecfee2a071e99d58ad9a8e282297822ad26575cacd3927a5f497d38e75066d33153d2a7776c18ee9c2e82b43b250fa43bab8fa88f6d1405474c03bbb55f0a07611bdc30ab5b3a8222e3dcd81f98f427596b4d1c92afe3e43f2cfd6f4d4944e6255fcdd64556c49482c4d0fb3add18037855db33e0ebf14bce076ef7ce16b3ea15913bef49185545c53b18d510a3ff34923a309f33c2323232323169a05289a3b10cd7b95443489f6606859b3457fba1347955112254dd25eddf2c281f9416e41461295b32f322119c8369d300a9f5c8d5488bee99b39ef337d342ba9542a15843cdf8f419f1f1f203fe310b7718282524182820005a5c40bf04dbd7f7ede3ecdfa61203fcde20bcc9bb238b8713a284876108b3b48e30409f2e99f1735a863efb8fc711ee15ce6e1d13e8ee81fdd82d32d47f466c26c68fcafc5ed6f58a5dc350d7046a5ac6eb038e0605b5c4e3bd6bbb236c58676645d9601565c5a2eb242e6a6f44db7a02c23e0a3379b30037c64ddd43f610778ea579c21206557fc43897dd32cfe0a918fa2a8288ea2597cd4677d0051ce9601441bae9bba4c598f8fba65c5f91c45c39ab62284d1969b78e1843ab2d1e58f5ce4f2d948b7301d6db86ecae539254439ea2931c58e2b37759438c66a577697e29692923a4a14f9ca9428af441147d45978cd2a7121aecea10dff569cfa971247be284789e32fea29e2c837e55f4a84216feadf045762ca65d800150f53a9940a3bcab378f8427ec5514415291bcf5521da5ca983bb2bebcd807560711b58b0b0a08aca9b68c228cf6cb11c5129618b69814c47b1a3e7a5d8b15ed3812eea9acef394b53c47d91175512a576147cf4bd9b15e153ba2ae8aca4d2c96cba5f231a622aa2e8affe92bae228e3657e536a4a4a8b0235f15529ec57211a9b8ea9f0af122ea6486aae2b36e22d439ac370c51a8975047b1232afc6ca6882a4f89361c259fe23274c0e92bec8af137c551dda24a9d7f153da8e49bbba9774ac4005fc5aa44be271576b4b92a9e12c7bbae4ca552a951c776514f71893a8a0a14ea294fa56e7c1cf118d9b9a9a7642a954aa5521f59a9d4c7d84da5521f513775f9d94c892897628aa370d0dc130ac7bca71412a5449e4e9ff5c97a9368c240d92af9891dbd5a62471b2bb79e3bc967738e28138a876ea989bcdae5ac8d95db53a85be43531c2036991ac790443f8a464967982288a209dfb49bacdb9cd59c1c997dd22a48e60c33c5609a99c286daef7710803071f299d8a23cdb52189de0f52a81ee9dcc35872a74a77e4c891355cb6fcd994610f3dd893cafc7842a9d43f51e51d3df6bc273ec946a8724889a1fb4916aa7248892726886215cf8e9268ac17acb5929c6dad84a64486a0c9aa629cbce433272fb135355268a6c4c44a0924a9cde557922da4e7f005e9a5bf9044a384821eb9d47627a9785d5f14d5cd8e3624d1a5f3d3ca348b3f7ad487093ac0854074622b41194894f881124074f0f56cf1051fb9dccca717432a78799949bbb3ce16f3cdf4c08b2254ba62dd13b0592b972f74bdfbbd6451a891355129de2e7a8ae294421441f026d9c9f0e472c250509ac48eac149606e51b756c273fb16fd60f1b9e50c78f7cc4f5bc1bb3085629ea68a2a8e822a0ad08cc035f4aaf424c812244e2d16464909caee2f32b0d431d25c5b9a344d66ccdab103f5b29acec56f7794952c5d1e6d67f131ce94f629fc3fa8f4f4e4e0e43de137b729b7b228ef424252636976eb7c46e45601d483e9b95c4d2667d9aba101447b02483fa92fa9488fa7e243d652e57fa48f3c891fb71253bcadcd277e6816d8ba16e1f5f3159d803677b9098eccc3c728446626fc8f0019286d3eac78ca086074ff292f7d4ea4da6cdd64c2fa9d6f4b1ce234768924632e37d063c897d1f39726713263d9227ce97c21e6232af6dd81523f0c0102efd6cae8be338eeb3e9b948f7bc9b3c99d24d9f1d6d78aef7d0aa4aa592ad8137591a700823d77b781bda6c92fa5249e3248d43078838a6c7a5fe6ce0895e09fcc4b1de8f74e6d249a20e7ac1667120f5018a3aeff26ec375bdb3f7ce8e541c19e87e67d1f513f3f9f7ef1f3f14bb735c47af0cb94a856e110cb72f02b787207967510793c4f136acf72206751e39d2b28d6d2fe936ece5ce9c73496771f49808ae894b52e292789ec50d07cda538e6e55ae2340cef1bd7dddd6deae69a3625913cd0640ac36651d2f9f254fae4994c281aa8269355b15183c65c2e56c76d45cd9a458a7c3c0d7ca7d309d5836c09b271c5ed14b74db7cf491ebcf75bb6743ab613120ec03acc77e2cc01b2091c7c0d2059e63f654b90f10472109ca73e7842e100586f6edb534a4ab2a8a024cbbc65421d69ff9c7aeb934a0fae3f6ea9a8308c7bcfee7a7b72a21daa23786a18a54db04a1717dd8095b34fa580eeca77575a29593acac397a36fae7ce99f14e5a5d1dd86246dcd7b6769e63dab9234d28626df95786aa1c6e64b4c9bafe9ee1db42af9edf3d2aa6270f31cd13741d5577a8d09eb3e3f43ba676b6c4d4fedabf924ed1351cd2a7d964ab3d2614a77951e2b7d86329d4a5e075f55f85a77d24de7eb892af99a9eef35a477afe931d91abdf79a4e25ad2ab435d2e56c81d6d6bcd3d750ab92d6d5acd263b355a205a9aa4ff559550cd2bbcf90de79afa1277dc69bf746d72d752fd92024183eb9e26848a489ba9274187c49f7c42048df8b27d8095736c1073f2edf796f4599b8f360137c1074b9542a1d06df5210a46fef441ddd2b2f24eafcb87ab7d0397b005c6001544daea441a51694d6db245d59adb81d48a64a90c0ebf826c828059de78ac950570e011901080839d83c4fca4dd233338c38f6e747eed4bec47031cc1c73cc31ccfd179818e6b6177e0cb79dcccccc7c3e8acfcd32a8b404f744b3b67b5f897b13697a6a20789aefa6836d559a65aaf534f335e0e9dbaafa24f61eda1ad3e7bdfaf0db7f60a2da2448accab3aa1824243592870f5f5fc3300c1fda21c29358d7e59cb992009ac234599a1e10fc10a0adb9115a1a611113a195734b42d5266b327d35d3c1cb0982e0413b440df3ccf0a6ed1b4b870993651fe691c1e90078fa0e980e9e7e06b42aefe18cc9aa3c9577d0f37a67bb496423b3b5e570539b47ef68d6b6fd8544ed1d1b906c892cd420900d3db5fbd83b8cd8c88847b2f4e4f54defe896fea7854fae3c242aaa593c002ef499f20b893ad6cbcc559c730153a82ba096029573ce39e59c734e39e5374a634e2f398dc9e5ec6ddb58b527bad54c64694a7eb22c74642273c3331473acd3e473c78e365cac3e4311c513978d3014cdeaded9691f35a8253779898f72b8f3843aa1f7a8046d7844412a15a2114000008000c314002028100c06c342d1582ca029829e3e14800f89aa46684c17cac320c8714e1964883144000400000000224d900e182e553f85e58589a4d4a92ca8fea7d3145959a8a15636115673e65b9ce198f7884d49b83388af8e6048f2db548277a03590c2b898e8fc5d838330bea9a7a82aeef2cd72c04f281f8c50030e9fd354c1a52f04540e01a811db5aa010e9010fe3e08c79af6beac2e5c66af93e98059f3d0057944d22e2805c220bf6536f4f6e9d0ff0f1e1c3f0c26e334f9101e8fcbfbff831f8dc897f045f7bf863019385f8cf2b7e18785a0698bd273bd795f973fccd24d5ba753e0167a76f7fa48a8d1ab63a5e3d3f2984899926e3dd14c6961007fae3adb4b0534e744e3c066238eb406bba09c6efa8596ef5384d71956961ae2d46c9db487580907100b3ec65e5767f3a16aa44c6db5436d130fe48e7b584c7253753b9de562e15c53501bbdadc8433a3a0ade4401779bf594e091398c72dc82117817e4c6598d1e3ae2929dc0578f4225305e977aeb6f627fc056a8dac4a5c2618d1ac279ea552a5941714f8048620d405f970613197ff5e6de025638bfdcceb5ceba7fa6e29226897060a04cae1dbb0b7e4b2516de291f00e31ce14583882ac8b1953a5a824683092d5886583deb2d95e83b0d8a033793a20c7b761919f6f8374209379feeaa13e44c6262f565079f401603a2f928ce09606197f06438b1c90c67009335d77f5c6a1223deded015731069563c803493d914a89fef970be454649525868a300b94d84bf47dc8c9c0a254c36e5bee04dcacd5233031a8d77097966b02a543ae3e7d66ae96d92436ac5648723ab3219d94cc1c9e6694632efcfcfcbbf43dd335600463cd54a6cbf377b253a24bf824f2b18f6e7d18921e436ecbf0025cf31c53bbe60771356022eb18b88e3af0c7804430f0d2adb0e2b43e4207184038d98388c1906e633b13955c487f653e0528ffcb19490218e616572db7cc8b599007248a53fdd49f66761a9ea453d4677938d94001407ec0c0524dca168b375c8faf9231200054673b6ae7dc19394809c4c3b49e68d78940f4ea1efabb60deb553eaf9194807545825b41a1ccd1e459197750b76183ebf61b9fa87f112b33bf904750c8617ef69dc63779f96906a06e71cbcf1684f1cd8d9df86d66d56978622db7abc72529d4649187ebf03d531d670c40ceaa2d953d8e13c9ee3e104f53ae4dc610dc2721c233d09f5a1b1810f14a7d07635b6fda4b10ec5e8cbe8af242fff2640872aaba0d04f73d635b9b957abde1f29db30d99998adbf86028f210862519fe5926793525a3919aa7c310865d0258cf3f4db2da751c170ab531b8f32d2c82eab4d9953c2ce63512d0194445981d75ad5e2c070ca833f97e72d87b662660d7ee0cc54ada90326482e086f233dad05c0b5b345a25836c2d154684ba3fe0be51963f4bdfcc7ed2117a4ced6bafebeb8c5e4107e04bd87093e590ed6381fa1a28e6711e037082dfa00516275890e70d6a02060a7251ff57f0e8feb6b16b8ec64fe2994ab870f21f965a91cf3e550af3f4bfa192a2ed61e00e4354959b6f0f41e3fdf3b1d454d1ec4feb503a7df3ea2fe04f6a3402847e09ee500c99ead6eb395b881f079fb08ac139907641c49a5825d376ba9e43245279d4187831fc19940c74640e5a5988271b8a51c5d1907c69f3fba5309e1385486d6989ddef6e9bc96473d4440780c9c0a161e014c5aebb7e1858bd2e7c4b042c35b0fef97d2964c3035db9c7fce3e0484804d77fd3e4c9c9ea580d0f014a565fe6667755df874c0024164e804b330771588d708e8be72ddd1af254f358ca897c85d46ffb8a9fe043249f62425792cf689d915c694ef12140f2beedee97a0664e3c701b038f2a57fffa8939d0b1893807b902e9310f0bb460a57fbdaade9169b8102a589ac53456096d2d732dc3e16bca86e90f9dcac9474db72e4269c1aa7809b9ece49897ff94d8dae2e6934b56a1501639d347a355107ea1bd5a8973761f685311a87f72a08a36782841fbf8777b2aef03ea65e1ac9addbc9e63dfc58120d53184664d4c93be4364f51fbef817bd1ae8cc4c4d24b382d1beca8320a1d0cfac1d5e8f7ce55bf45b9694fd9241971ab17f8ba3d6578dbc9090a45c3e49785aad41c1e5db2a88a29af586df02b9b511abd789aa834e15314870f4ae950d1cbb3048f4aaca24a743e7b7a6341d828620b2dc09d247877328b9d80971646a13f8dcb1c0e60b51129a228a51a779140ec4058d388d17f3e984f53224aa484482e46cc926388c407bb0ac1846c9668044143e4bf4332e966854595882e0cf2b17938bc8f20aa7f7b0a6e3ec7d19db9778178f4d3e648725ff245ad8ed80e9b7de27ada147f57d8f1ef6ad4b694aa84ba634d7225f00b3bbe44b7e7260529a6383558a053c70f13928e4cd56466b15ac5900f097829f6a716e847e7cdbc478d1e8aba2f3c209607d4373e5819965f8e37d4d75f2922350f008b471a5b37da5111851aec5b50b2eab89157e54eba4a59f5532fd12c2fb493ff84791f293525a729916f53e4522800a00c6c194b460d96bedf78e2ee066050af95c77e0a249ef0b435d62546a2e923c94f74fa35430412bb0280906985842b0903a807d8d04437dbd4aa055afe31ddb4a51b19142e2906183c758df76bf1d0a68b8264d78918df6bf42009c3c2120d683b1ac7aa0d1620c96ac7aa0013be8a34f027908f22f8dc3a8f626d38d554c700484baa34e415861de8fb03278c6310f0650ea27e9c3ed917aefb4820a0fc7f27860f8cab7359db682c126f68eefd3282253e312e0bfb1f80e3496eeda73c3e6281ef9f59a3779626e2e3ba4f0fb13d23e57c79562f78b0e4a01f7e43e51ed17257f940bcd8b0835c44b5c35354533d834bd02fc539fc38c67363b136d796cf42d918d910b2e3038a9a650f05722dde3eb26414bb18f1990a431410f9db810cd297a5f47395951e26554b099c0a9a93bfff5c47708065fa2cbe37af2f0f90e3c36eae2cedcef28bd61799cd32e219f377cc03e749a04d34a055c6542fd154e8ca2de8e570a0e40ed3082c7a7b333e9dcb5713b77f11c26135e1687196724d76414dcfd3187df7f85add5eec053e90eb94e8494a4090bcb5cabfb363561a14f49c66081cc607aeed977c02b88a3e901da7b384f922cacbde0ee11255ce2f16b4ad3468a8b5f397c07d0f743f461cd494c341dbc467dc6921f6b0af5eda64f4c1b33cf24cae6a3213e51575a9683e6a6c6bfea0c78264fc7edeb6d646dbd1213475232fa41dfa17f8509c14f855fe6d5bfacb3d6b1163fd5ef7ebd17b73f33862d1d6312fb27df1c122c63e3985a8194aff8e39d58e1797aa658395cc4168e9b9ebc3877fcd4d8a6926ca30732a53f642659956026e6020d98674fdd4f9e2c952fc184c08501b113c4eb02c4e93149f9f29808387d997f30d6ef2b8ed9a1b1e5594f2183ffc72b68260bf96235f885c276c96d09f16c2ea24d737c4a9f9e44e1a98e9cf173257c7a15931577d94eb3bb4fadf9c0af6cd9018beeff4ddab86cc0860fbd8ef702466fbb5348e9c442bbb858bd97251931e9940471091cde119b542fb52f2e009c92afbad61a42fb44e1eaba75331bb84c5cea8fb10028350cefa8ddc929c6b79288c4ccfe96f37c5ac7a6d12f7f7cba4fc4e68da056b4814a3274eac3035a8e73c1df7865eb2622c48552e414efb9fffe19e0df03baabc9172718ada79b6f130f44f755eabd56cb3513de43bc32112133bf3b8835805c002b460cee6c9b1a9b18f31c5c00ea4a80f42ea56a00f3e6cabac83c8902cd2fcdceff849bb428e45c86583905529cc0027db7b6d7fee7dab04f5478c5560d15aca9a34fe42323472f0e20db5bed39cb36175ce6a14c84e7ba01d6d3671e60bb592fe4ae2933219fc7451b04decc37152848706034a3797e1c2dfc2c2a828b48a5fabddf43419cd0004394f2aea70f39b22ecc414c0b3c0923248527fe229e5d97840aa10780abeef3b3053fb476780ead94a09c8816e36a88256e492fb5829115e4f2af40e6fb41b8359cf86a6c1cd4c481a310995ee241ffb99958a2d9ab84a61a7a962b112561398c440b1226744103cf2f3e327b6f6dacf3bc0b408d8ea4f709e91f7f8079fdc8b588cdc38a57efc812b99dcee57e2ee86a8aa7cf7e17444ec19720e5fa6fa7528f82089ac427867011cb22c99c546857247db888558452bbd9a223c341597712a710ee8ddee471aa9abe1254cf03ac10c06de6e6adaeaec1561d507c3836bf0cf2590df6ce0b78c6769156e6ddbb280042363f58b1497b994a6ce200d100227585960ef06e6067c1691b7a20b31f6e627b9b8154a71f5e92b0ac36cba36d344b137c7f8b5647c2aa79807550a905fd1f722b403d887fc47edd7b32a1065d458fd493798f04a32724a8b0b245e14814e0415dab40632dd44bac5221246b10ec2602afd52073d013a93cd469d68dd22356d350e2b60017ff6b0c10b18b0b75613d1f6c3171094b94be51138234d32342f3c0293f4e3fb6cc0c42320b75eeedcb331c80c0505381f044b59533da750535d829be40325943f128fe2d4c961964c2e31c2cd153f480fbb11fe37b087cb3ee1fed396f02f87e4c519198d95ecc2f4d0dcc70afc72a4598975df11167c8430719ab9994889ea1e07bac69d82ea219dd4d4de8d67a63b499cb95da99cb11cefb815747fcf05e173951eba05683449fa2dec5ebe4cfac6b41ed5f933d89c3a7bda3a1b700ab5c1a07dc00d2d4a734935f8156fe1c3578f620f58c20ca7343876bbf34b6fdeb928309fa831b89564dd410b482855610825d506ac04f1de2333b099910e42449c8f8af664d300f4131878e451d2dd8233e9ef84aa916cd8d7f7712a5a3f233c2ac4331bf0fc11440f06869b33e00b355424fd00fbff90d3f08e43081934e2632b737bb74070984903eecd4621dcd19f2e94d319f030b4a1b5703ab88e74cc52744100630418110da978e3ef2d2339a6d664e9f25171e7551c2b1a4484eedc9a186ba656800a44a39d26f5a0fad78f4e699117eb4db6348f861e302f751f30040d2c9fced5c8fb6519dc31ab991060ca78242220d465a2d8217cb1f7a5a2ae4759c3220cabcb80ca870c594be3819098d16c000fb7de95d3cdfbd1595939df3c3fd459ea8495c7f9d9ca9ecd894c884cedb9cc238cd01c19ad7d09c837e8bc1a025ad839d052235a3b9cd4cb0228b1123aea94b18c1299fd9cf60e66ad5e34aaa7d10fb1701e995296be5511cf6ad0849d7667d8c99769cfdde40544744d586988a2c45cc4332d02540453c7c64965a0e1c683005ad53a005f40baf809a16c82ba93f5f0837f823bb2776ca35381c296c44a0f70425be48c61c529a8d6827bc119156901f8cbfefb6b1a303848eaab90977c53fc3a379ff6aa33c54f0c5c1e0b0a72deacaa74a821b5a8be4b492adf94ea82bdabb0ed0a1903dc4fb5eca36a9213d60d1f23d61e7727ca9550e2a7d0a5cfbd2d98d034525b43a840fb8d32de8702e3c80f4e545f4f58dba177f1e0b0cdda42ebfe70167ba68d30a10a58bbf4288490f2c242591ed4fa36f4364682391e11f304c94a239e85861068514472a3640d3d351484fe0719a84f0e0d67a156b5be682c658eb440d7daa43d99abe4a93103ab99783679797ed62484702611fdd9a81d6648100f44144939f3a6f7e29035e6324afe0a2eeb2a7b5047ef326d50bc635db150a099b787de2e76cab0019554164ceb747d7f90fcd2485bb7f9e0646b902815a214a5a0319d9d88469518d6121e87ef3a98290fac4a81a5b5c004ba716509147c5c6e96f58a5290aea51d13a0332aa9574185be4fa07fd7979c759c7c1743f044e2e470007afbf4e10e81bc010cb3fff06af3ee771c47b581fee0b5a05edbfd762fb214a015219a358468b14e9f940d02b633ea36b12515909c785356aa6648e31020b7735615ece73b02bd75fca6ae942d9629c59c43de9436e67662b7bed21ff17ffdc65a8a776b4e9e39fa29ceaa8a8846918718c2999e0a3dc5bc7dbd898b140e667fb604d02335b4e3081de03517d620e3f404daec7efc58892408bfaf3127a02d3492d43deff4f5e9720f87d4d6ff0b2b3288cf1d8ec44b7dbf7be7412372b1f162dac71ed7b60b76061515011fd0a6a0af41ec1c79118577c698a6aa966e8a15067df8aab7d6d73719931a79e5192a07b9c7ab00875e28929288ea26d7d50f5140a8a2314317bef16f30c262ce0b96ece38e37fa5d1a174cc4de252392e746af63feae6424c3bc34f91638d46cbdbe960e7ab0d80b00e6231049531934c8fc26603afa6df8deaafa9c330e73d532117d14e2acc6ccab7348a0cd79f56f7d5192b758cf95c7c17fa6434661ba0d124471f5319a6788ce5ad5fcc8af8fb0743f65ee3c896d431062e4ca6f478f28ad8847e1bf11fa0a6d192a65840de7b4da4b3d0ac3289688b5e1b8d0178f71b2ef19a7773ba8f9fd77ba670b3897b31841a325a6e55d536c1d623be00465a6e005f032243003ca16debdd72b79b10e93c9f8db78db13a0873592e01fd3d4cb3f1e4b5b876928b5e21af51b9808f4b05596048b51ab7d270ae31df5c6420523534c950a6c8da2f7a654ab12e4a46c4d47a531b21ce75a90b7eaa26023d5254874b21c875a785414cfde32cae2df0d64b6f6951615fd456a7a70634b806a4bf4e156a8b5819fcb94c22c949d106a222b94332c99cc918143f6d083e2d85c553c6e66afd0285d65bea3f5ca31f0945719a190dac6011a3d6c8822632b380163b7a33c21dfbde73873a6267549f0b7be35857ac052ab16a24378791aab04a823c5c09f08c54924169ec7300c23433a201421772a1290fe00a49a43d0ea6c3e1411307b11ecc21194b9df1c7bbb9b7e1a7f6a826af6d76ae35ffde2f2f6255bb1c71576d1530c744ba01e3bf5edd13a705f5270392a37ec6567e18cb03e4d1a81cf1318e1c40792710b59df4315d01073c1c3901ea6ff1f50e6ce67eaff148408e02c1cedd1cbd3eccca5e3d2d828cb66cdb18a85658fda0740b77500e3e698212351c1be6f268f526c602608a0b704dee0a17ab6c8b633d88a31a667db276f289b602c7eb01e56cb4d3e65f5f293e69e52b2284c759dd129ff73a28a046a607d6ca110430f0e54d9c69b7d5630b0264e8f9a973348c8e18eb4c6779d886a912ed04d30ebfd62ee09006b39bd0b03b58076311c8ae4280f660e30f7d08206a818fb9b121fc9e78f5318456b7b5a82bb98f4551080938df007abdea52a80e42245ce4112cc66d239fcfc8cdf8a7cd97e69a37cd360044e05bc7a6766cd8109507f5bf22c7955516205344943be7ab60507488cf5a3eef09b76127a0848fe0e9bf867264889f690b6a6c4222585d0c10d0c6284af135c727ce36ca09c35a433276c222ee923081c29938619350d927269e337c4c4920e4b2cb364af6194acdd5ba82f3b8150ec5be781e00405e1f44182d26306aaef06725a1bf0d16bb43932bfcf8e10db02ebb309e351f105ec0859a0df87d2f17489a8c0e4382ce19593cffad00881577130d836b0a3cf14957f92a22780bed73a46152e67f9610417c8ef60a223ca386921ac127545ac2553a21a02b1e0f876808c4298d86264b37a1c3c189a96f87e25dd4f5eb0c349bd51149e29dd5334042053eadede323844f62823ab14253fe7bdcc5b09ee09bd0b6222499ae3997325fc81dcc4a46cc1c91dc8697eacb8e4292f4781c2eb7e3196cabaf3ead29410cdf1d61bd2b5da654bf45ee9917ae47f864fb55a30db29a65c179483c2765683876a30c65ee96221a627b77750969314de2f2ce8f5eab32cc793d5df880771e31dd8b81c09370cbd23c1e2e859a8d0750355e77f2201d1b41d99d3e6b16b579861a93ed66fbe496e7d06472d2fe736f557f8d10319d1bfa933f69fdd385a0c967f58628f24721dffd75af13b4f57f2f5e01eafb7bd62701fa557bfdbe9253f632d7808f8e489e77486995bd9da23affb1f9ce121c8c3d6c9bc096111bf5f499328b11aa070a30dfcb14ae8d831a72f75c9ff6ac7ddbe5007780047387e1d2230307f5ebceeea5d85af17d2228b02786c8c5ff3d3c6eaa40a60f746b7f886f84dda05d10fd640fe0ff573bedbea0d09a5ec36908f02b397a949cdd5ab00429a8cd7cf990b012d3f326850b3a81658f7d85652ac023e49e6b37d90cc407f2a86705d2eb44afb5f5cbd524845f5f939975efcb410a6ed45fb23fa80b475bba83dd5ac48c59fba6b00f3f9710cd557f70f662bf94547ceacb4fac6385e4651345cb44d7f4e872439b1875ed929804940bcc50cefefa7ed1d8f9ce19fbeef96784aa7087438c27badc2e9ce8970c77d614668048e5a5607f1fd3546fd1f7e58a3051b95c38405cfdee28f536072a3d62009503b242b2119ca0d70441d6da104b0adac65f1b12b38b11a5e676ca6e52394c34c31838dbc927e8646c1f04ec6b834412a160e3263f0f5c42cd30fa601440fcba744ca2059cd828a7916540f5c52102025bdfb0dcefb1e84d61835644c556df2e4a880336fd644a934d69ea07fb11db0c9d104fcd02f96ef9ab02feec167e1be8132cd32f76cbe4150d581d92ae04baea88b147d2b3399b2b6b5d650bd80f13361d23d27a54d50d22cdba956dc856b52503d8be0b6147b393fe4644f4c40ec743a2779e709ecb7d98147048d01f557c58ed114b8ec1a4ad64a36b99277c153ff37d6a01c233b3a3f53ac7ea898d510a90bc9e93b2a582f70aee9eedc10a1f321780f55e2436032d1484f76e198a408c47ac9597cfbecb24d5d24db9e14bb4cd104b113386f9b6fee01add5cda1579d002c7b11b566327d3d3826ced64db0c8adc9e229d7b332664c252126e77bb973109cd52f41174b7f67e1ed782622ff81a840e7214890c3707d02ee000672ea1cf9c9d01b41733dbe1d4cc10fc2e6ede5149a1bfe17c64e024364932b0b0a36a1df1856331962e24527386c5027f5a3dd48462418e1bbdf14cb8841e26395ed179b607b625d6e755ffaf7d8f99b8a36e0b7af46e6bea4ca0f2983f49eab688b7cc55c59b0f59fe9f7b7d491198720b5759b4cd2e86d647393da3b08147d14f5fbb36fdfe5a666c8423c265aa09aa59134b5654983d1b15a56de2698b5f7c527d16c8650f525735644e5089e73df7e03bc178d68202491cac29c880e3c554e74cb6a327f316fa7726f18993436d4cfb0776884ac56fa78eb56cc633e24c550c2fdf60cb389eae14651dda77f58c04f40ce9aceb8fbe0f09b699a3f10254f6e86a7cd3aa30160f0a188ac4ef27e935e8944f3eacdb73e83cc2de3834b951fd4c4aa852c61381cb3f536440646135fc73a04384aea4c0c6ffdc27e358402933ccac26f4417197495aea9676f8f8a48e455a3adb9aa7471f5b68f4f50cc899e0d1a8e0a338c3253761236fe9bda9bda4df3879439c1802ec403d89dbf05e27a4d411643cb1893f97b54567d90828660bc3179bfa90e537013659b968b87cee07211b330e138d0a057154970dcb3ad453efc5d3bed0420835401a444632c7d50ba74ea928b579e7483d3e2086d2d44a12b27aa9683eb9c632903f3c6c41e4484136b359b577492c6b269afcc506a5f9410fd708e92a708198ecd2a2fc97a2f234e496671ca1014239523bbfa6fb0006fa1c801ae68df4d952870f172879da16e5be91eca275116fb7b936267584e56a9ab8999ecef10c12bef3e4f24d2aee47757a392ab6682a119f50dc59a6d911b106d421803c9afd8e346aef54f068bebfb21ad4f4c41c91c1f5e33d1f22be3f429d57d666b7843033c7068f2197fcf939d5e683c496ffa7ad0566a0008cb2c62dd3badd050291f7c885da06713d77691ba147831e3570411c7fcc66c152910d36b6147097306c0ce42a4897c4048b37adc2a36297ff9c52c51a9c9066fa247979da761264cd2050680ab924073d571632c8bb7dc08a0be337d0a2ce22f5a8b632bd8b5d1bc0ccbc0b4016920f4db0e529ccf4192fc6433aea758ae2c99ab9682041321731c19856be635e569c305fce05316b6a4a47e776c461604800766a0e19f91cc0fef949af04f69c8a56a0ffbdc8ea6b299a28e10902d686a19f739e4db7c0fb529609dc16be0855598a12fe1b41a7ed1d8539d6936a635035cb09b013a680d0c6f2b5410c475017bfda5bad529743461aed414f81bf97f8b13c160fbc6f612628448e5604a306ea0388520eb640cbcd63375ffdd2b09269eb73636fce8b681cb57024b01fd61918b9fc4c06f3f10876c6c8e1414c1acdf78dfc98ea109b0e1fe34e863da6460bbd8c53472cc3d4837fb7300eaf9cede3569281b2e8cf032e3a2ed3951995862143ef93f7a1d04eb187bb3e6fecd35b03a9a4044f92e29f163142ed0d53f288643a564429a3fbd8a0a5f090fa93e32339146a7fc31a64f12fae24e4c6fc58d17d67dbdd5fb8c0109514f877481f0e8d10e98a18e0e1f90acb7bf98de413c97b461c19dafcc7519f50d173e15b94a1bc22f04239d7ad48c748715ab83c2c664732b3ea880afdbaa93642607a868a0eb3633fc41c07b86efb4f5660cc7a8c8fc19c792b7d5e52453c32e052afc57e8d2cde952c267f43c12b4d3c79186235ba2a7a0d9d26e88d1eb024f608740ac86cee0207423cfaf41398ce4a71f6b5acc758462508d37c20799d1ed3a010865ab27eaea59f51142774eb9b04ba095034a68ec9d48030225de2ecedad229be756af29d6740cc31841c00484f39c9c0e398f6c190a4d0bdde336b77e3fae1a0bd7ba220322a5eafa34ca975b9d66ddb3d86a84ccdcffcb2a84d1d2aadeec34bcd632bb5fbc1443428dd0506e2ed885513244f262751a8374dc26fcf8d9b253b14e304f86c48e14a9c4003122d22fb5216e77bf44aa0c62dc2d8ebabe4eb7ec43e4edb356833e8dcf5aabce1e9d6203ddd8e3a2d9f9dbb4eebe1c9b275fe75895987db92c54c28ccb8f588b65f2afb827c8abe6f8e55debbfb280c1b68d5de113c52b3768381f94b77514d4d794a39dfae81bc1a28bf286586645be53108b74b6fa295b597b738ab06a0fc0bfc505b7580d7dc5e847e2c0cdcdae1c7b141883e8bed520e200c29189db54bcc0271dd5b0ae40cdc7a9c2b7325cf4353b318c3b1bc8fba0b42f86d80ce2ba8603255f64694156184be9261faf04450d3d6a967696f8cd9710cf754b4c74b825f6a42a9ac73ea6d7ec457921de3d1aebb0757a9be750db92b00f5e1891e88f6b6a4c7d29e3af57cd6c0790bccb3469bb009d0374ea31258d4f581be71df76c0c382d3ba98288ad5aff5591d7feb6e55722208f70af0a02a8e1c0b7e63fe59bcdb50521234df93b7ec04de003ef87b4a2567a9d0c04358905a32d02755169ce2ee1785115c1af92cad152913c0b05c192e7e4b3d78c53a14ebd5f6ce0a09220ece28abf2273ef2d0dc5eb7d83acdf2da069c33157f9578302d86b642208e254c81d988af1426482a8191bbc8d6ae4e7a699e440ad967659bc553a352f8c4251e8797ed5c0ef4856f8880d84c7c769b81b082e682ce2c8115840940784f5a1050c2c7beb57cde951feee6c66ac367cc84cd7ac2ccec8480c6e6df9e73352261311133fc8ebb23c09e7fb2c6270ab77dac4782d96108a67ec59ffd32e8939f62d006d24ca8a371475299f377d3652f8ae2bb7397cb5cb78f29893386d8480a086ddeb176be8b67b1532b03085d148a5d5f20bf42aa84d2e24ec455fc33cce8f1f28c86d40a236591b32a7e71b846533a650a28707743f8fa64c5e7fd1356e342fb2993b0afca8a22ee34aca15f5e4f84fb54cd81e57593ad34470aafd5ddef9bc883d21e9a679fe6d2bb03917883b3c3d6d5adfd27087d77c3c803c119c746837da3f233bc8034c71a3ea95345855c3aca315f4deb1be807afa9983340dbead683ff9f7d3dd7f3cc815c74c0a210d2e07804ce9c4c6c46b2e1265ee30b68d6b7df6773f7de3f11f42d7b372621c68265705c741f1142d2b6bedbd58bf8b4ac4b8b4333685653c3758089a6e2a342de63ba7db9fe72315ff754a7ff721c49b6b3f158bcaf1805988dd4bb1116fc6182d823b7366c58b0b843f7f03cf68e931bd491e3b1f38c903b88b6056ad2ff524fb947f9bb2d2f48f5dc0773699e7004757df1b25c25f0692370c94238ce7b9804c66c3a01adcc48852180f1454c3cb846a65b3a1e60dc46bc9641f2ab3bd7ddbfe2902b38eb3cc4329e8832103a427c3173155378bfc7bde9b8eb0bcf2441def5807b91ca8b76257aadadc0b1c58e80ccf5b80a2445f3ac147039a24baef8cded35100e387813a52354fe58831e4224f89363b249e41e35374d59c88280b0e7538c077cf1636dba4234fdcc1eb4722da167ed86e99583cb9ca81cac9ef707823dda5ee9c6552a04420a7203fb68d673f53fe581ddee5bb6bbb3556bfd19fa5a59a0fed65ac6eac54914adf58ddccc0adb8790ba2defc7901f30f9d103d4886a125bc7252976af94d38464b7e5a4f581bdc8e00dde0e6a9112a23ea5158f748c3d4062041265890dfa708c10dc74ca00883a7722a936285bef48713c1636d79284e6d659b3cb5e2be3c85db62f8e5a55e7f158ae345fa1c35471ea1f1549d5c7b3406620a8a6f57b81ead2ff712d0ba1a222fc127e03c924c08075a381ec9569b35173b20696dbc352928b4cb161133cd76415998d0036ac18d729a3849d6b0a2aadadaa0c6327dc7a52f4de3109164147bfe058b17a739c804224c9863ec5cac3c43159f44c1ec4a6c2041fd9e04106ed66307b59b0677af5e310fcc2a4e422d10c5d2a2f23f68d886f043897947eb763576e62c7eb19cdd7a13f3f4d89dc38b91ee775428dd59e75122355822ae1911cc0432f1b9d6b7d2701a2cd4d021bf434007fe0cf0ca1aae1a0c860acc270d9af1c0d57b255697a1683d9418b2938255f3b025eb16bb25f51600396ecf8f8deb4aa4f642adfd0e62451fed213947e1d7a952dd0d7bf21896a758fb4738d311f5fa326bb158a1598b046d33b6336bd9ee16bfa4da5194ada978c2019d1869be930255555df21b6cf05d2b141e4b8691f7d20c5954c5a25f21410c822dd3c6a079cd1b6172934c0707e4ea234d8a46ae9724cd05993b5d453392b14eac94d90d49add399b107b4aedc7b5fb0995097a7a8f5a0384c70ccf5f8f256e832606a39fc13312097dcdd5d1ad5b71f65579ef8d93abc3bc0c7c49dba964ec4626858668a807483a009beac43684ba2edbe2b92b30ee45a2db31af1f1a9328d7d635a4e421ca717acb5c67cde5313cb929368d7104aede24764f4f494edc506a2d654a0529e02fd49d8f2f2addbbcb5967c1294a17ca8d6d08541c34d87322795fa45e9f34d71496d807e1e7ba6e28bb28391c8d924ea8585626d094d8e8ba7a6b5e42d0869f5b63b0811feb9d9a3ee530ef903c8d9669412d7cd83d378c3fb40921c563f03c05b0b6ec93947ba5b0dc0ab6e1a6cab682880005ef3016895275dea3e031f96983ac83e0ef053ff7613f0443ace576be6958f13fe4bd435d09e3927c9ac0f1fee7c1bce2aa2c6fdd7c4d95099a286d4ee91aba45d5f920edc3e990647f9a4558c3aa94bdd970545d63be9e84e0a9d177f2735697f4d2a5c7753e8421f7630f6a26ea18bb2044c6d2ff19cae54e927ec9066c814e9a89a43cb843b961d46987c35e4fc0ec1d46c9093341dd4fd8dcf7766aff52582a1beae30cea7ac32c3db9e1b9d2a75627706dc059dea859caa4221da6749256fc7f060e6846f17a0a10454918a2b1c8dba0f001bc75f760c5f3998911ff092950b8a64181c0c082f205715a24c6e50aa0c7bcf636ffba0321c6360a19894171421f8f1456167ea6375b58454d66d5ffde963dde99827c846df8179eca366268c5b9d482dce779e1040a889a7d96320cb1fd34cbf6d635f0bb699105367365408cba7c529535600add81aa13933f3a8f8d19613cafe869549aaedce6676056742a04ac15daf665d47d24a675682be10f9106ca2fc27678671ac20fcff616b3a73aa9c6f20700da0ce3eabb74687e46d8e7a77c40e2e574a8f1b2ac978c85b67ef0773e82193d26773fc3abbe9efe4f20452ea9a0849d791b7eb4abab1883d576655e2ac26c065cd4d64494d32783dca43e89cfffb7509bce2a2fc382b833de5c895a502fabfc1d976c18b1a3ef61adbcf7fd9ba61475b5dfc864fea5009d6fc554447caa83c9c89a90523430a30fbca64b6723aab45e58eeef2bfae51af39117dec40596ade92a1dc01c5a40d8b99d82d9287c3993c46c64418921245e75ec8f5f1792e39237bcf2f11dc9da7b659d85e35563851537dceb323bd4d59bf5a1b305bf4f1ce38eea0e724a265efa9b5b31f3ecdb37f47aea80301864b25502b6c708c2170f89ef790a79c3a9e97df843f0426d4080539ef5d5ee5de187bc824796a48628d0d9992e7fb9a25634d66ba1f1ba2597b0c6a1a8c3a225d9473988e1f8ea182189f2e82e49c983c086e5b3f8bd1122b06986c616fea7f194d29c37e2ce6f75f4de168418af083491a08498fa2448435432656023218764359d82df2e3ce570ab61d86c0eaf3b7fa68f848e337b79d3b7019878e29cdc7fb22b66f45de9edb48539427f24adeb7dbc8057a5854dfb1fcb79d086fa7b939e4c8ffce09a4148d6a6dfb017d345f82de1f8d40192964b3d42e687e63926276a0b1d53a143d1ae1317c0d8ca4e69712e3c34c319ce45c2efd34c46b3c4f4316c21f66e5fd94ba000cd3594b501fe0471f1d74797a6c37fd6e0c6e9a2f0fef63fc76f0fc4355c269c9347e5b112977eb19ea5a2e976cc9431458ba4040e341f87f2de42e3143798e7a05e878f564a026271117e00c741decae67c140b48c4ec8841a69a1d54d3c07059018cdee036700f01fba4299a367948f953a4bb6407ef53be9a2224913b4b4a4d54923300c25c59fcb18cd6b488f032ef06f7ed627c3d9bb185f8006281d2f3e504ba261a45a2cb5afbe28e48afda0a2bc6e5b4d7c3638ea875fe01afc292ee172d0c0e386b89184bab21e5c4e27affd68a81424b9140440c012ec38516793c523105ca27c0d9d588856352940109ebe2b13392bf388965c2b516f57dec035a898520ed7414db1d3fc425c5eddf574f4d389844b87a9c104012e1ee08a8e114d017edc13de9255736ddb69f023de24087550da540120ed5b3651e777728ade0f814f25a2dd325be2a21ff5e0cd30a3d93d74ca32b697347cb8d945e945a28626395b31f69bc7c0dab07e6b7d38f85ae1c703adcbf494292051d38f80ddc93a8cb968802a6d3f5fbf317f48cfc4e9ab7388fa01649cbc1464bd11527e4115eb2d72a3cda5798ce16686e58f0b2095c6cf4fdb4ebfc566592e426ba65c50058659333f27bc6ae88a7a005cc935e8ff6d204c1be8bc3ee34010e35620b2661e42889cb611f71e629ff747d446c06d36f9f9dd9e0c74ec78e2fbc2a73b43dc1ec1cfe79204ba334041c1788270e72db20bdd94af73f9c3d462527af03e47f77a0a7d6e76207a679e3bf0f68bb29e4c3cdfd3f00b35958795c474a96623e5959c0abe5d2b5e8dc6ec462138eb3e7ae573b0f370f24fa93032ee1ef8a74f0ea16136e7bcbb6ca309b5c01092fda8344a441b7e95a40c19084e33a5d9c57d607df72258a4323672ec9214ba1306812bf71860ca088c823ff667d34a0521f874d42e127bdbc308313896f03baa58934daec9dd402a0f2d8d9e8f599d7e8e70bea3e2b5bdbc5205c543efc1642ce0d9eed950674c4c7da956af342338b43155384734fcf32444939b72b244f82429b987b153a46f85a7d6074216630c5faa37c43eb72c77d8bba1b68c4816f4ab1e93d52567783aa8dea657a48aa8a432f62754ae3713ee978e67a56ab39ad60f66f690059d5d5012e39b4a1d89ca90640274c02cd442a7c1e255d5f4f9085116e3880970a4c332d072f9a1fceb20e8c95c38c4e464054bd54aeb3140b20be498e5f17828770ee877b7c8ac79bb66ff207b4930d594ea395fabcf66b0a732528792df0993415007d62a76aae583616a597d1d5dc5f76d321d5fe1c9214113064928a2f8e5f8b561e5bdd7e5f1600a7af1740b72ac017cafd4e229c67530a0c2dfa8812daec0c6cd9385bfceaf139a978b2ba8279c542d76f649320949d5e207823ca46e5c74d3b4716d4ba24bcd2e453fbdd1ede7b4a975186ac588de6fc2269915c5800c9ba311d1eec2892297934c9417c29f679ec99788451d016980a847c2522e6e20d4bb809fb842f6a090cdd0b3df014d0eccd7faad9bd635852687cde0283587a6ee3fae2964957413ee7a590cbf1da4e01e0ac66f98667e75a1bce60bbd1d6c49769ce6085af284d245c9ee5f6f162c6e7fb8ec3ad71ce20a04d97fab95898e5fed0c97674e518202cc3f8be02e3178bfc7ebe5a2d3d60aacde8de6cc348ee4d0b1aec406a417938597702182c5660598b07b9e56ca3c61d76a2c482ca9878aefb510326ae9ca1411ff25687cf86c56e3d4943c3cc4b7e09ea688dd7bea039cc6cf5d0ef77b135d0a861cc2b5e3f1a9bc7b57325d64ab7f6de0e7008f3fb6bd7daf8e80e7cb8795947b99d049a5c2beee63d8b13ce29c7c4ab9d1278cfc08c31293ba85c0a67658341ae12bf4066f54f367c0906e4fe1bc1193016d74e72177eb0680e8b2d5e5cf1dd96db6642169f96d3351a5c8daa6bd666d5ff705844e1afc63260b2be45d28307a68ef24ef58aedac893361d1a2aa36287d18b2059730d54e867440365e6e1ff6c420bc77b885cc8b7d2a2541ea4fd48688ca7fa18f27dfb03cb7d91546d3cce0a3bb756a5064aeef50cc64952ef0245a3a2101c6332c95f65d805bef3b6645c7d4707be888e6dbd554a5c40c3d97df53bb420d6aab2a1387eb242faceaeacc9f060ef4b319e84dda4eaa8da547d6f985a878301f40e8ee1f64344f5d3230c002e8b45e8ca1f467c4ac49a783da8277d03c27a7f34c5728b1c9adb4800d2bb123f9b38f1bee21ccfb943a39f8fb9ca7b4faf149d7685f7d14a93b412870c6233c2a08f4ce33eb45d94144a8caf8cab28c8d9514eb9ef0a36c4eadc58ca387df13a37860a559cbf6562da6ae132ae63cbe0a70154f2b32be9888369bd8eabf6ef7eded0e3f0e61f5a76e99cd8871c10c113a6f810c5083513d9e65d57ca775b9abb44640b5d09a477235a86e1299f10efb8176549a8d8a4acf15c715fe1e5a4f52f758493dabf743e1d49c9082784101aec0eb44439a0820d1d6dfda45f3f424062e39a881d68c8570fc05bc64b9178722f15fd041bcf23489d41e323ead5686c6e712cd748ef5cdff878f700cc020cda431a1f7b89ae0fc2c6bd71abfca9390ac2b3e82105ddf246118881c2f7998bf063fa6a1ddb4db5e727523924766ca2946a5691e73a57c8f34c8cabda14f1d17fd8c13ee602e5eab54c3c6db532e8062061d861a6a135c357e0cb10c2483d452fc3f8e0d2b04701b80691914c48fd019ec3b2e47960d5264819cc7fe6f101868e9f278280a3cb147ade148b619b615c3538f064e00589257ccc581083aa0218174f15b0f8989dba658cd5a8892f3a890520d2c278ebc2c1130b4ce9145281ecc5238837adcf8f9c9e1000126e5dd6c69e16ce3ab8f13dbf78bbc84fc4aeed3a5d192fedb05ef9f258711374a3c3d3ca1c2b65bf2750bcffa33d61c81d5406fec0a6cc3dce28df6db60c558196015a3b8eb84e3dbde0f0d1c0de780c5cbe0a5bdbe3f614c63fff6e0ff76c353c61d0fd392a4e9b3684644f221a4ae22e79bf36bab23b53e15f572daa69f63cc3517ccca2398398dbd1dc858f31b48ec2dc710f7d5fe431934ae4b1180c16aa05d6915c7c22e905762c2264ec123d14022a1b7d19cb16b368543f274674199252ebb709193fc2978e74f2d2a8f44e5c20fb996976ea442c349bb7ff76b0353071c0a8c4874fca1e5e34b73298f9189ecb0a12794f89b5edd0441f2f5878ba608f97ffa5b55e2eb7644861bb032a6dc77ac3868fe94eb5cacb1affd2a8dfdf3de835c4649752adbf8af261e73e9645c1aba71aacefa801996eba7193d308f5df30740d9d3a0f2465f430133d8cb1d9318e021c83265bcb03da17808b914909cc60397436929c55009461829054a8c336e93931d60da51745d82e44a3fec5e55408d050e4223430f163c610b3e53bb12520366e4cc172befa646cdb14573cebd5c00b4e337f375fc8427c3b3c00f7b7688c2fb8f3e8060f216751b882a39b7a5f7af610324fc62f280b0cc57c1f8a3b887ad0c4439b4c00e467bd904c493055c652d25570a4d702046789ff98f534b3630965bb63cd02cd6373a85a3c3b87ce7596539609ea3f0e90aa55cb990e099d60ef078ce36f7ac05f44c48dea9a6117713426303c0b39c04c7978967101eb0134114e24b5425a7d48aacfc999e8e06fc042ea5e30024a1c369d7b0c64219c50f36fa29b756044227da990abb515e6cb21291e9bd7616b66746bef7df7a2066b254228b9d961761d77b20501eae073b080fa9eb6346fbbbb7bded91b5c583b6d73e0909cb4903892908633721f2426c9295ebf556f62e46a10f6808287be70f88db8941812c9740a87b8543b15446c78a67c9344dc011a59d7c6a7f908ba5732722bc1095d6ffa2a3525f706b027ea6ac6404f8653bb403ab83e17591871e4562702030c45df7f1af860041d04225e7b13122bd40895e652145be8f7b80f45520e48c860424e22f8d6f6de3194a2147b863c5d6c038046b1c753c0a71fd5962d5eade20f337933d4c1a6a9d0473648850b09b7b580a043639a3273bcd480625272c872a0cfbebc66c281a5bdd3b97c1e701c48d7a592f800848114bad237895577489ead069b1ad1d0ac76231bb74e2d579ae5aea3318fdc0ab2d60400eac1cfadbfebc5665782759a99afab1c746cde38b0873675e0c9ed6a242c898bb1083d886e5ffb24521ff1b97ea034ece21f967e8af4726a59a446554e4bbd04327f2e5a3663baae698ddecc9aaf9455972469324cdead00c069c20c179b677bfdc3a09639d9c1e59fdb744e229882c5c86fe70f0e66660c441d14cad12222b0948080329c20142c3a49445a1f851c40b0b858f2bfff262c7ef7d9e9321630526816776bee59fec05f3d34998302e18899c3ae15a1014665e833e0ee317b46323591d7175fc7f361ba34641c105db674c4fa3121f053c1362213c699d01ee84f44de63d8e99355076356f094e0e69f6c631845f1779b1d3ad2131560d8cb5535e3195b9476d0c7d86fc8f6f25a8ef0ec85c4c8cd0417d54f8389c8f99f6faf069875f91dc42a76d13e48c0a55482498ee5b269ee722887a1d93eac114e9cc2e77d5bbfab941d15d2b857e154eda0fb379efd148c13fd5785d89822160639206309c160c811465021ca0897d49166c4571a5ee84bb13ee3ff331de57307c1623bdf8c58edad856e05d26cd72dfc51742af5869d8d7e55a9b8553a6962d1b40ecb3bf3852816e8645570380a1baa95cec25950f0376b92107883263511dea06e81b77d9f11b73839700915c573192eb51f55330e037ed55c86cc2147f9170d3c65420a6511d6dca76b31f8a4631ccbcbc24650a1800dccb188df4ba5fd61d6d0bed48a1f46e3ed2656b46d330bfd2c5d788a9269890bdcc6f1d64cd66974acbe92fb57ca1d61f7b042bfd509b56cd92f45a7d5d63c88fda7a051c4d2bb0fbd2efb587c14efd38572fbf4ef61af576ae0502765b99eb610b6cd3c3e6d4c1d9ab97706ed4889939d5b0c440f7f8dd2f91dafa41a59343310e37397885cc46a266f85f09d0dc92065cd6651916898614d5628178d214141ffb6384e523454d2e76b41c62612a69dbd10599d0b748ff00b11efb891a1c7f783109eb7c097169d111774883c9de1c4627577668499cd0c50c5cd22eb4ce5992c698f40dd2a92317151ee85993328561a80c4a6cfcd4f0ce5f663e9cb2b14cc369f6a8bc6004276f78d1193996581ed04238d44e7b2a6a6b9292d2aa25875058a1a603a812c18e8cbd969548f7f606b800e0313fa467c2fec48d1686dd83ece44b369916da006ddb6d7cb1df4342dfbae500595b3c8526cd0c3a071c02f0f7c3938e2dd4f8a360283a2950d0c4cfab174a7b1f8c12c62593001f467f74b7d5481f6ae6fb485ebfba79046ddfbb37f6c417233191c8f07094cd23b20570c828ee12208f260e92743707e7091a35d73918563e771b2a00307d9b2b81780a1b8e03ec7b8dbbc43c68610985c82c542e04ed0bdcf41b6d50d49f0edf3c55662b7ad8d40a0653d7448c3701a74f0c98337c0bcce70de2854543595e8419774989ec3056abf819588db9aa5a98bf164a50aaf068b51381a857ce25751c7d35045a798cd970b0b2a7f12cca593b550cc311491326242fb13c9fcc7d95bd31fb7ab5c97256fb9416b9a86c69786b264630aa1b29fb52dadc30ef4a4b190f1614e234d36affb4d83b663009656e9e4d07ad4b5b9844d4c290b0f0131d9fc102089152da28db33f379f76884b52e68cf7a5d80a664ac0618912e950decf948fc9c19b48fdc1f5cb49423fe719becc0745de74f0d3f6c0d313e4a5218625cefbfbc6fbc91d3ab9afe5571bc3dc4fce3154a4fc91274d442f9040bec5a790501b4ffa336394cb0c255932f19a7f9cd15f63821be22c9790ace9102beff48d6bd1bcdfbafd381d737d027d0650fa960c61bfb54c82bf50451eeaf36378ef3027dc121e64f2b0a49f79d9ba965c57231f9bed5e0c1486c7d8b3324a0513a6002336338e5a4c5fdee733f6dabb9784db62275454afb15602ab1c57313ff9f00424b9fc5bdb64c4e465ec57016622a74dbac8b981bbfbadddaf8716422ce3b7946a7d7d171daf6d5fb537b8ef5ac05badd0bda9f7734bf3baf98449cb92c9023d1f9e847fb33e2f1c46e9caddfe9c9ef9156c80ef373066b188ea659e8ccd2e52b7c7c7f1c45ad71c0248e00f240d65549678bb050dbcdd22013e86a4c2ae722a244baae86264c826f70d55683c53d75f332c8ebeafae01c5d43467142f9d3e708cd71f2525fa31debc3ba0b2b4d7f659a9d22b80dfbb2502b346a61a4b9356fe713cbff8a25e57109f08cffe821ec2a765e345a8d0ae83a40ab2107dae509be0c50e86668efd2b298d1279e1e8647fc2708f177a6d958113c2c33256e78583cb68cc845dcd2e5787356b4c690e28aa71dd611bd59f77dba7916fdb652b6125c6c99d463cabc08f64388940f5ec169785fc1a7a559f03b904e850bc1003620b38330b1863a1a395fa1b2f9d6e5ea37ee84047cfe7868ab8bb77a3428fa4492f04d44faea4d8eb0ee85938677ed0bf594010b0fb4e7dde6a6cf2168f1f4984568315df93fc4eace758339c8e632d0f46bbad7c7ed1d0946d46f28c8b32f46319d1b4edcf42238b3cb778fc1dc7c9b02e929b12f1a152f6b8d49d4a6b08f53462a79380610a3f3ab07d92d021c598273a6bc6d3e8834682325a4e76cc44b7c12b3a4ee2ef499694e7b0007d72be466cb051df9583dbd29777470b5f2badddb24a4b958a0648d7cf8049781fd564f41ab847458a65d3ffbf49cf4b9a6745a8bba7549a61c9d24d2b920c5d6769f2cd3314197a4ddd45b71e5390aed7d38798b7c4f64a643ec90d0a416fa55ee6d7d0db205d02abf7c240e9e1fee85d70133d96d243f6e86d4accec1a7a18243dd81932e334a294230db10e7a9130278d0641982594867ea8f3305ab59249587a93a15e649fc68e700b3d41fc9ca8ecdda26d5635306ce4b293674e1f3d73e655f8f30ffc197c85c7958160366205f03e2033de51e8b10e562fa2733b8f8295e7910c307f126d0162a44e7f5d941fc0837ab0f59278c60f657410624ab41806b8b8df2d05cf8461017c88e8c5479bdc726e81676d89a1e0876e765afabea5e6de5bb78ff9e0462c6b33ce6a781e968810a6619780a19da7bf6dd500dbd904a5363dba7b046ae184e4d70018f209db5946fa0ab53cc39911683d4619164e4bdea5b2b7e5ce705a93f05f8afaab3e2cc47ac84107ceece91dd5470d11e07a412264112825821e76e57f2ec58286222c77ec6371b7ac808ab98cf5048a65f11249ec0bfb7903095929027db548d68e519f36bb977b46ef18fe9749905645218078eacf52c030be7a87bf908955d56de5f9f7ac7c60ccc29547d66746f7b315269acb0fb53490924b27cb4242e63d723abbd12b656f8fb71749e95edf0e5b21f21f8f083c348a19a30339ffd897ac270dc2aa6d7f338759be85da442fff634d326410b7b28222b4bf7b909eac54539e32bd7f3a46d97536cda9146f907e257cf29624e27420ab5dc4c7b820a3b450a51cee08732ece223898a454d3a4ecebf5cdbae5decad2408c2d7281a5b3bce25455860661568c4f85362821d5740dd9c224bc9bea83dfed8bb774daa57c2ea7bd447178923af2a3c9ff5060d2944f4b9932a7c7d4ca2cc09201f7192fbf960abe540afc0b11f930ecebc50f906433422329e04f37d56f5a85c54237d256aed72e3e408f4cbeaa9ee4ee7a02a6ab630e1fb315de3b313625d9a7c858e71bd4140bd054e3736f1dbba55fff0ac6b8d63ae807f39df6fc5c47321532d2b36355d4c09b41d288b57241a402c776093afd3e40b014ba1f5e42bb9b65035a548cf3e770ecd40d2a22fbcbd9355be8e77968c3f2e6431045d4c9582a7571c9a5dcf3a3bc074b034f07c7864ef44362e4f51cbaba309d888d361de6ab08bd35ed9a872ccbe573e45e6ad24652b9d6d34d3e1cc1fe9dd201fa4b26807f5c46a82f6dc1af15e61e2bc2dad6fa92a9233c482ff412841a8aa4ab46fb6941ad8d487435f74fea944036757b12f37f12d5797c0aa60b38af158fa91d270325b08ea6642226b0db238c3940ae6633936f9f831047951482e0c1b5cef642a1417064e5da858bf3818853d3615adb9b000123681c0a5cf94c5329a64b82aff37317e915e04eb85ea9407c5cbbe17d355eec72d7660e3f6125984efa4efc813571f94ce2834c2eb0a61fa3c3a54cc8c7d37c8888d8c0613e834ea1aa4fd6a884912485a5ff9c4a2aadc33128e391f30cc744ba3adf09cca51dcb484b760f123ae01835f881eee5a8496c0a608ba5bb3d89bd9ca636177d0b5d81c779bf132c254b7b4ef7b1e07d884a3f13b32b01953b5dbc0b47d0219ecebcf6d7a6dcea8a78e29f200422a9884317988033920d08685b3d737309c6bca6cbcd7e48f0a365cb1a68282a34e497289a1a55547f0f01114062c047b854c5c148a9fce746fc9fbabe1426479249825375a2e0fd9351d8c469fd8f45235f22dcc40ec95fe83b1fccfbcfa933451248d4bfa13ae0bdb0ea7ffe19c17f9c535f0e85d608610132818739fd14d44c04ee939f6a411ed7a00f8b3950f4bf0f1e54fa47226b7b7a8e2ef4aad18f53ccc3e8daac338dbb862aac1e921041ef312231789dc0982bb39b304c683d3211aa728b3d06c3c7c131ee647737ab0ff7e68b6ab24362ad3f0ade795eb0a9e1baaec7074fe5828beaece40e845906b1bceb5e9acc6faa8063db5d0caebb9f7223916530b13d991103c67e3082f890e9022565251049365e5d94eb24e64d1824057dc2d5c265b17347f38a94df12c52ac8c225e0b16c4c59a293347400372954c4a1201826e5ec4e3632e801df4da00120f485b47e8f8fa449bed8fb053d4afe39971fe00dfa95a0bcbef587a124f75bfd6220580f9fa0236cf4f0ee1fec40f3424df3e1e7981f1bd065ff7db15fcf7ef8c814702df230f7b300001856ccfc9c65cc8466f3967d44d136a839ac15f36c8be843b8b8c0277e8632085cbcf52b3f27537677ad190c3954364ffce0eb863b1554e906345a1b0065e3fbddd1f531e0a436e587fd68cb8a75ab848bf1ec0c805bb16dcf2a20e303ce633e1e4a96b71a5a5749a02951dbadddc972d9c1a1a1e9dee286529d0e17e5aaf9fd981ef86e5ac90e294404baec4df4b0d1b2197c61feaf312ac676a043203155d8e808f45b84b855a590a2e03924c7eceab168811ec43a18551943c26c66c6ea250119a6e6701b408c711c4bb1d17876ba8f41c812f3965b4fe6316f3d476e3ba6a7b3df9e86e75a3454454b817ab3891eaa2ddead3efc87b09569289d4f745c38a5f3c25a84b9cf7f580ad6647c2d3dbf271243ec445b42f784f89ac2c448cf7d401388290c769e98379afc5205045a9e7e0a52b79dc5e48ed4d2f47954a306d48bd58c15ab0294df1ed02a5798e3a0eb2d097fa282d8406af3ca0a67b8e8dda7554a67aec0bacb57717d779e9c8782bc1d172bbdc17f3d5d1510a91e5e2d42ba8ed09a40acb35979bc255a7ff065c4295b1884a9fcc2a3024070404eade9d60048c5f34908a5570a4d65718033b03a7ffb0c3484a52b7b0543edaf80615767845328b26004d0ccc33b9c22b893750a260a210c7c66956966d0dd8fad4c33612a96f7471ec4473e9bdafc2233d2d6fa0ed30a0390ae01a3138b296ef0cc172f891e3f495dc30bfb47133670a1af16c87808723b2f65a2787a61459c2282ba860e66e20f3c4c6ed5e0bb7542f63876f114be8098ff295eaa8b55b018dacd91cbf681711d38d3a4d0d7b39f5693c13b60fc90a22c9d4cc77b4565f81384ab350e0eeb0d44d931f30b6e6020acc3ab6b12bdf5cd21f3827d7486d15056ac8ac37e6eb797f78ec052743d1f702adbcf6c5135e215e3fd6ff465cdcdcc57f4db63df95eb7fd9e7405957581a73347099f4a1748ca59176207358401c37f3730ecefeb7ac0b8f3fcb73e894730998a48d9120a0f413432446321b2b0fe8c70516cad3e84ff27b0b0b9a323808c0445adea09610d0c5860183397e6e3003328a901059b8e4eea619b92fba9651adb06ddab69105fedefda2295664224aaf2f286f3ef5825be22088f26b262af29a87394c1c9e0208e9c3a2fcf9beaea8903c5ec6455e168a38f7cfc933c2aff4f1af83f349fa2b9dfbaf8572c282367eda8659930cdf79143c072d77062c3015d9ec237680a893757519ec1ca4bcf4dcc2d402b40563a9bd76de5da22d48b2291cae476342b314be57c22e6726692546352964a39db2813eef5f884c86d0da826cd978021deb615c1af6d100287645870137a57d642ae6606bbb96cd6eee85d07136d8267c654935c2bf4a790c810d689f27360e93439fc674fac5817271cc349c589f42e184771cc4370010caf72a45d39549136eae3ca1601903c905af28c3fcd385521a0b68721b43065521f5a88bbc719d63e1e15af6a4302d610d668a3cdfa34d48b25ecbed223b96d07ca2cafd374ea9d85b13dfdbb1683536455202bbbbe472293e3d8c2e154932f1f8b637b8754470d014949dc90a902fcada897df428126790548c7bedd9bf20b80a7cefd62f50854e816fce8ae115dc31c76c084bcdcd95b53a4b5de530759a2efccfd04d020292d3097a1e4e0d5b74d4b3058784f30731c598e0fd4e9f9a800209485977fe734e14d11315a2179780e964402bcba3ee9845299f9d2f8ca54fc05e4f5d51e3ad98c1c2532325fbc4e822e581f70246629162df99932f2f025afb5970e12e7cb4e40f055237fb7e2211f45e640154351c46c60f9d6d30713fb8cad268a29b51a394d4951d661a214989c38a8871ae43ce432f6e3257b841e596d7de40033378fe21fa82049b003d37b47b14a25001eeeac85fbf1541984c4b72e91750710337a34fe8c30104483642ad228e90c1c7b4368607f3ca1215b89e6972683c428654bb93991387d080daac32841b0451eeb453e3413e20b093ddacae786568e0370ba1ca666e00f3bd7c3abeebf33d476b646d3a19c44fcae2190ae7c57d6e91f839139ce4b7b6044f16ac78cf63c7c6b06c8224c18948792992ffdcc40049e151214535602ee550a9b6d42f1978f7e98a9db2d696c6408d475a31dbb9c96e6285079f8b326eeda334558bd39cded5d70804e3a3f03eb30be0bed625d8dac10b4fa1764e8a965e459f84628c9b86d23e29d7d0202be0ea7f9666d6ea8be9213ce807ac9b4af84da1d053e3808b8d854f5f102e6b3ae120deaf5e698a1a83f370ad90be26d832433f2ada7081ffc153ea48847380480a36b823e10cd81ed98b23ba1c71f7401328545ff93883246a39ec4c9ed1b948a99442ae691d2f0b5910efef0efddace9eeebf194de7797c590a157e38658b51b943eb680fe5bb2e045bb89b8a24282bb8fa625c5cfd259cd0cbd419cff4cdeda4cae32270942f7fe44cbb9dd3dd89b0d536149187f3f6b48f51f6622b24e60a71523d71d50f539fbf96222b6f52a9e45b34c12048a1f702a56a00505521a917986137d8eb600a3c4b727ef634461d86e2018ca03b4dbc34b2b5987fb5ca086ba0e0bd47726b07bfb7fe2ecd2c3379f35f0445b1df8eb4a85726d96632a38158591f5d8fa862b76bc6b57c6d332e2da28e297963830dd4719b98552bc3c3590070ab54ce06c29e1fec1052021bb886bfd9ca6bf5c52a273704090762373f86c39c530df466096527997cada040c3071403fb4411bdb6c65ccd5cfa6894d31672f02b5f98d414650c8c3663ed500b9cf55cf47e118e9ee7d3360aa079fd367cbc7fd99574725b39696e7512b20c2d4501a2168504dd100c66249173cb8d4794840359426182a824d1b51e2051df2bf7cb2d323a9fba92d7b5e026868c4e63d7f56f3c8e338ac017c19461c727ad849264f3e3ab91241ab022f17adfc592f87470c40f1cc8bddb43e021f0ecba556544540d143ccc0134312dd96a405dc64201c3ddb17708bc553fbab98212a2cf6109a199fdbe5d65373cbff1bddf2ddb5b5a3d5044ff8391cdfa580a5f88cc763b20fca1dcd07e8cf6b68fe86b7d9e8cfdb03944518535eadc897d7744c2789efe886bb632c2bea695c5ee0a33980658a5eeb0aca2431108d893f1217ba4127a25b1e51a7c45453af0dcc7c291a88ac9c34bd754e6af72972b6aaae918e89bf819bd50481bfa6f6728cf51eef3b876c117067ac50a4079c02340ef613af94e1913b8e4d539a66745bdd6eb7f4ffe658dd8f2e9eb75454d78f2ca6190c23b53e868e995dc0080febd8b12e503020e98be3e25e693f07b9a5bca0dfcd11c3705b907a844c4ab8ceec2a323a03972eba8bfa1f6e110a3266186482393a3ff824deffcc5b5c83dbb55dbbf14d2faf2f9a91aed1cfcfc0b3abd00622d97deec9ad4b9eeff50452a62ff558203cf8c3df03aa09e3423bc6338e66e1b95dd50b24bededaa39040e8abeb055a70c3df28036f5cc43e4fc4306e4f713f1b55a13abf6d94c314ae1bb69d30196c250aba16299c592a7236c01f355539828a6920bee50ab18280dd5596858b1f642ff2efe0f950bf6d70908b40a5ca6e37a70e25285bef46b742f0fb917318aea863ee34ce7839bdd64c3480f9e7960785ae623f7b8a1fd810a6ed3343ae4c3dcdb6706ea07c6951770f25e94a5747d2dfd72eda2b580c3ce62c776f6b6b841ce91f59996758bfe012c513628f70decfdebb8c8e334702191236fe59040a5a16964ff176d864fbf9d47904368c1ea1843745c6e9aea9b073ab920051c0e2daacb43abe36c926741e12b50f2958576773a8f9a204f6e79e3af52c4a93ab015789f70341bc24d4bfce7ddb91704209b1095e0a0734e18ffd62419a1f925b2df16117f337bd6a3bbcb3e447c0235fffaa7d4e503c1bd40698e3c976efb051c4e25b8b72b2535bc8eb2eefd3812a39828b87e2adb7b3230e91b281a69fe3e4485a8cb3a4e6766ae94e1c48cb65711a5defd4bf65c758813272efd741156d62cfa03a8d01e91cc2203ecf2902930fb0cb214ef8cc427be957449f8327452727c2d73f854c3db111dd4cb3e3d3dd97523435ddac6ec95260019e076ca5e1e42a60ba53a58a6c8c8ef4d57a8c68f7a38bbbf835dc25d13d90ba4b74ea2355737dc10dc3ac5ffeab62177b2739a67f254235e94fd2e71b832111922267a7349c790108a9d8db8807a00e59d1011e5fbc3979fb361605b32f79bf04b427a990e0be0576d5759e6b936cbfbd4f3c297a73bf90c6b30e5fc3c76229ccc3f2af002de372717aa4be8a7230084242cecedd181ba4072d0d22f26bc8a334687153c86be4520a5ef06a6e2017fed48b279040b41bdf395b23cfc435816093b1879961de314cba65650e4a88221f57233c13e8e0dde2f02a7e85dc0772c6df71418c19d048a554248964177eb8b13ba83f11a190ea29540ef65920ccfe8196456791d4c7cc9af0eed8b17638b49bab1fb36e2eb65a5fa31c5de195fae051a4ca7c26291d37a7f40284461dc9bd5da48825308b0798718759291c006885a81485790ef4fbad17a134948c465fe8b3deb8e557a20c0d4c0192ca7e9d17f1ba4455d95994a824935284ad3b549b18a63be543dfe1228f87c5a65b3b757715488d64e8505bd2f9081e6e9d47a1073418b44da8fb5be3a07b1cac4ecb6b8d85a23da8b21b9b55b1f75500064eb5f1b74730cdac588823dbd13651158194cf9ab55d32b98fe1f7ec27e2a512120dbca15de26f9b2374d32d12a95ce65010796afd86cc4b83331115e5d46eb7e7778602389fd02d55eb74a60158ecd831c719f9c690716b6c9c7d1ab4a178ff114fecba87a99887d4224b0a473a2786fd26b99085a96dbaca5d38ce2d7ea56cce3ea80e48bf7f6a672c54479d3274f570e4ef0c71e27efddffcb02d6fc4206f3aa46f7d9ba09d0ae84a5515d86536627dc775d526d873852abfa1a90a8713f62d6562929886a3aa9c072db3e11c076a7b52046cc1d278c114303d66e8aa24eed49844aeb7246b170ea5c99782ed6adcb5d50cab51897871b6929ff02a1fdb73f5a85be7eab496218c8e05502ee967db95eeb4828d93df28a996c35d9cbf0b1d1817615fb4e3e19cdd4e918a2cb7007e2babc3a298801bf51b57b818cf7269f16b8df10eb4b921bb0f776fb726c78e6e7c549cefd87f6ad312505a184c7815c9a5565840834d4117d7000904f4ad5365851385494d1bf589e5acd12b76603c9667e1ef092e0fc37c8035cfd01d05f14a31efe39df9228814af7d2b591a34de06dd3d390003cc55adc4126f026cb2e9af2977352d40cf79a996637c732af1c28c2184fb754974973f71e84d6d902883b05b7f4b3e0379c8df8c4d4dcea501a7131945035d3cf571886a497ac41de69ea21ba4ea71ea0508615194bc19add054edf44128c1694868eaea14209aaa2b62b9bce743ad42998bfbeda150ad25524787005f4f9ba12896210d77ec8c0441db24c728ad3257e24f3b76e42f34cf95440989619a10f6fb405babe29211c35304b6797434f195023752b9d5cca46541f7319876a495a5ef3dd562e5e34c7a0942a8ee7f411362c9153cb67fe2f1f5cb4227cbb06f5b054a2039636b3d75ed9268a8294e5382405f6ce2c331c0fe3309801905584cdb91782745be505b940d15744de992a8ee35586c7faa41df9f1326c1c67b636cd06d92bdc014f47a72a374db742b99d35405cf55a390ab03d06275c9f341481404d226985a7610f1b91fb5b730d8343545687000ddeaeb25652153cda362220c5189558fa30e0f78fc840a9605fafc11d33c8572c53d1441b0e54ab67b36be4c4ebc67df56364520da5357b45aa6e871a125994ccac8eb8c2726fd41156c8d10cd68dabd21437fa25626bf46d0ca804e4022776a8d13c944cc63d85add88594377b468b20718caeb93f5666b57a08dcdac270a6d6336bac5ecae20f198792a0003477857c97bec7447533f53bdce847faa4a7ee41aecdb4a4d8a88330a9fff9241145ff70c40955ee214c3e535155c442bf55417f92d2fe0250c407f7a75bfb4b06dc04984aedc7a919679e31f513082fb66af25d8d77ca0ef74404c524080911e081f80a788bf498e5fe620d7bc30afdd115d7bd407f80b24a70e608e2fe12f8f048bde50b5fcea640cd5eed1796d6bccf4b2bf29d3ea23ef01dbfd5e08778127bb77d1404e14c3300b14e5810e7e0272020f07b5d05352c6906da1188af254466f40089b49bfa9b23d572e10ff726a98423ea07d835ab5bd6e3497fd4fd760bc124d783a3ec20b93cdf3ed66a33db0e2c7af7b528c3ce5fd5b14c371eacf114e440ff5f595f9b6fd1e55ed556b6a49af6ab141070c2fdf24e4f662edf7fa89dec93781d0375ac5f03aafd8e9c55208cbb69c6fbb9f240482d0115a71a5c9640ac3f53edfd1bd0596542865a048075c2d95b331a31f77ffa9937179c7ab7bbba343b743973436cade95ff6eb28d197926fbf6d7fd2ba511312b2b2b737e926444a29033209d50ad609dba6bed2093f5e55625bf5d60864b09176abe5d34db99ebb95b3ed453859ac592a3386a2ba79894e157597d86b4ba82997d8d6b4ba1d7510c263d7f2f679154077a87dd3dd55727ad2d68eba4a4c27c925f424a68928fdb67deea45daf99b6a46d4b7a6ffb763fa03b3ce911c860abeb92f09b360a8f69239166a4ba358d547768d22552b537048e48d4587de9e85f3deb4b75acbe545549d525dd2925a9af52b924c15e557a89ec5e9dd33a9b57a75749a9ddf4cdda4daf92b25ebbc9ee942e51d8abdf6b5749ddab5b254ff6a6cb7b24bbb997d84ab37ecfbacdaccdde5c8f64ab45c2b6bd25cf6032047a930e4ff54dba44ed6d3b88e20e1e04733d5532a1eeca1d5ccaa2cc06bf9d0a369b9bdcd69972a99550b676fa6a557ec03e75f1533b1666efaa6c42eadaa91152dd297d02ddf56578ee1255eee04d97a81ed435634b4e265b73e52e92d3b56c22d29e1d3bfd7bcd757397c86eacbeb4f0d3a4b1fa0a6fb469f028bcbf9ccba48dbae90eddce84531f7df4a1c746a29b7b5025526d4e5332f595651fda026bf00a027406c68068ddb64eab7cb1d95b996ea1574833b81ca9972b57700fb884aa4b6da80a4ca51c15d95a7d2141b12564cf3e237049c7ec6c23e2f4cc4ba55f344ddb3452dd95d6089451d5d6111c7d58032e6d9a2d4497740b39c74daed65ae924f24892bcd76ab55a40ffc77b59acf1540e8d73b2209ff596ebf3ce19547b387af57bb2cb52acebc92ed70daa52c09142cee6b64ebb43fa37fbe8a173a8ee669fcf3b2aa16e920be4a8bb699ffbdcfbd6816c63eb266d7c36d621fa2d7d1f5d6a4363a9b9d345e2f37975cf96e714d233a7109d4b708f768eaf5a37eb909edfab832a2b043e342b9f9eb305d975069bfd538799fdf31f2f56769097748f67ce48d9411ee4f7147ae2153b4e44fd60f073ba7f7e7e8efaccf7cea05a53778866ad7bb4eed9e8cc5cbd431cbd433d3d3defe9e9d1582c5d62fbfe74918cf709aa948a4975876876918c0ff29b590fb2acac814f087407390df2212fc083aa2b971f8b60a02e2f4da39f44b02ead8b842621f2225eb619297bfb4433068d95bd7d5e24db4ff7c9272e77ef7c689252071d70b5830e3ae82049c9a7bb00b20948e80ec03be86eea7c3ef7e9dc381e797775397e4e0edeca1ebd0238969f4924e385fc9f5bdf25c5c88f3ca872740800fb4a37800174d1916f9de4c18f3c29e8468e64d20017fa143292490368520423df77c0910b69143cf8916f8d0298220f7ee42804ddc8a7d0bc00b0e048bef7b2aefed45a7db97a5e76db35de740164138602f00e349222f7794f2ec19dcfca25b8b55b904da0dbc772a0319f6ff7f9cccf3eb759fb58006413e82e802e03f0227fa67bac4430219f3c37b7751b0905deae120a8552ca20830c3000faf9c1608379e7e71d224090201a3ca872403eb7edde7b8170f59a4077fecc0faa1a74d9589c7b916ceff9987b94f892665f99a2cde6b26efaf8f8f864a66be282b2917b908fbc481e1f804c77ce746365b02ee388b14bebeb1b79d09b18d1416f72e4c966dd8373f35e2633b3decaac7bc1671ec06b1b9f1d72fcf6f1948aae5a7d01999a2422f2f173f7e812dc5367cfdc3381dce63c77505612f2202b0911c9a5d2dea698b3e79edb4c0a9b0bbbd46d1d83bcc1061b3c755b1b689f7b592c164b9f9b63abf579c78fb9c727933e073a01eecaa4cf0970a0711c47f10e8d638f267daec131d0a4cf83fca7479749bb07534d3d965076cfc73cbed4b67eebd3e5ba8bc5fabc2e17eb2cd69c1f73d9a391eabed7b757bb43accfcfac75267d740841fe730cae81268982fce741fe73eeeb80641aa78252ecb98486cda677d3544e7dd1232983cb6a85c6214308f2211fa28db607f9dc64083f9f9fda68fbcfa70640aec12906a7e5e918dc82276dd6cd5c45d2d263abd5f3d6b5abf512dcb3d5d3eaf9ec41d2bacf67dd07c859f964412ee9fef9964db0419e7399b435b84f2e9336063f3f079291ea0ef27913681fad6b197c6ef00d7ef1cee0ad0cee0d5e823b830d7eba4bfad8e05a1d92c1b50c3e2f920d746d730d0810049541c620d73740b9c2a96794c1e4cbda06c839dc757508eae4c973734ef24195247f39dcb55a6fe1db6ae13b8442dd5eadbe50f7c8930faa28542ab39ee5d2a6a976b669d3c4a6b22cb39eb23a3dd9e7d2cdf3fc52f3d164d6ee10dde3b9f9da064b93b1325ee0b2b6d963176c676767871ebf758fddcfc901abd56a1960b7aec12412f4d65b3bf720effc48deb991bc73569e534806b403ba5b43ad2efbe6daa6bee8eb1ba0f165e7e049c4ce993f736ab06b9b3a0475fa9d86a7af717a7ac611e31f9f9308a5627fe87f00c974a3b0eecbac87b9b4581766d6bf3c37a58242bd27974abba767688eb9c4f6a8438e19751285aa6d74747474ce01c973b45d581f4fe6526993e76c07846cb53e40f7bcf7de3dcfd36a691054cf6de425b05bf7de2799fb5e69b77299277073ebaa73b56365d78ff276e90ce805e35bb9dc608f0fb263469dcc3dda2ed517b569ea8b3eeb52f3d125de3c9fd3fbe4b99d03ae448ee3b883dc579c909b2e0a117972494b6ce7472ec10b3e807c1404c3baa41b7f455efbb2b14da95881d3581f8ebbe6d2508ae9b332334bb367b666cfac8d9197da9197d8839763d0cbef972fa19740077859e40099bb509e73e73983f29c1e1c31a275f9817640f7fcb27b1e54ed1c4bc4daa53aa4e7f4748d05aff225deec0f953aa4c269627574f91a7579962ec7169d9aced1a38b305b007b2e6991c25eda4196d2bcd90078eb1847bb9e1feff94e2e95f6ce39b0eb6e927cd7dfd4171c8eeb58f41a4b6b5fea6b1e75875a7abb43537777a87a3185286d9107065c562fbc981cccddb373d6691a32bbac70dad4217329cd984de9bb9b647e54a954a77788e79c4e4b97d86e7d3cbd4b6aeb3aadfce34bf545e9c6783492a95b1f75724d8354f70f5dd70440003f7fbd5aad1bf429347e1ab90777c091076914827ee41e6814c01405fdc851f0e0463e8500f0356bb0346bd22cada92f20ffe1c18ddc011e68003820481fd167b24b26fb086803f901e4c78fcfab047b9007d556aed8eb95037021417e02f0798704906b99faa20f407efd00f90f5d62fbc7f899cb207b9eebeec47834f72357129a2d4d8a60e4475e64e447741298d6936691911ff9119d64e7d81f7a235a49a8d5d225137a87743e5b93e7269d9692d60130e6d7363e75b7f4acaf1f575d3fc8fec8af631900b902c9af9ffcca354c9a3a64c9748766359ab75b89622a15862088f1f779debd5dc77128d4b6b1ce52a974a9ad5e9e38689dfc9c1ca85e661b8fa42e4ddb9b53888e2e4d1b7f95371e75896dfc957755f63ee710d53d4f97a983c757e5395f5897ddc5075931cf83d9f4d4f7ee613e81eeefd825aa21d0ef9a2eb97fffb2472f084af3f38e33788b0feaf21b3fc87eb96e9ccbee27ef5faefb7e7bda887ba791b2cd69ed136b2f4918ca30381b09dbf4aaad434533dcac43b0ddaa824b25fa4331cea85e493d928d01d39d657508966574ce2607375b9867cc91d993d03c976dec25529645a46c742087313b687183183453c6367e38c28a1bae60420b0c0cc002060b5db0e4604316ed851f54a4d400839c2958ae6091c34c12429001060922d6e851831e6fa8e186161b3417ac182d23588105192e7350e046cc03d4d0e20e177420a28a0d1a1521b4e4c1c7186fb6d461470b6628614394385bb26c218616a51890b0e2cb9739c0f061c61a54948962c40f6f207183c6824f9a15c2b07144112db4a04dc1020e2d7ab85181092951b036591b6c60e932860a52cca049e9018e2d627648210d9827b428bde043176b7831250e0c53685fa8b40104176c1c81455b61043cb471650a137850c94253215c618a3055bc88390386d29627c4dc4066882fb8c0a024c3194e1851051a5b8268438bb2c3136b10f1451a396a76d052d0001b1df690018931e83033d1f041431b3937c480071e4271aa3c11c5183b5840c1a90f286fb04081831c38a60073e20302419029e3839921fa909285cd1c39a420650a20b84c51460f56c098600834fa90b38712181cc0bc70060b2eccd0e3a487111d6584b9c3072e589cb1c58719879629d8ac20e6862e6220420e3839c820c707386caaa4b0020e071f76e8228c14cc3491c70e768481260b9a22b2d8a201727a9072022e54aaa4616a828b34a2a051638f24f01801cd0a6fa420cb0ae2303307083ede9420052d88a1c313593634a298c942052bae9842003af04893470f5178907252811859e4d052a7507a820b1ca83803c51461c890030d6b5c98a18c1c3be0b863022d14c1660a14f47146093b948a2063ca1c708c10a28c1d5b2eb05485092e5b442163ce132c659459d2b2820a6bd4114e61830b17a05823054bd001079b28aeccb0c69531d46429b344c499384e90831c6d686e94c1039626a860b3c51c6c68e9801a4d1881031d38bc51610c140c41c5092c2d60e1410e2e6f9628230c3db0f8e2c5490e6b0f35d0b81113c317626a13130e1632e86843a5071fc064014408c4b8b0c618589c000619e218018f3368a02305375610e70407d66288a5219640e38b2c59ac0011c31848c0d1820e5a8819420935679c6125cd1b5b3e2ab278a20915b804c1c61755a22cb10973a5862b6e18991953a60d1a5cf0228836a4f040c31362ecd0030b347868c307195184704309382ec046172be0028c0c61527062e3023069b0e882c594285658430c183124e1e50b3267f050c51572ba5001c7152f0c514410710ca18611344c21738a5301334a54b185943c84e0e2a48608944843073869ecb074450b07f200c3a58b2b567063821384d8818e1eea28420b1069ccf0420ab038820821f4b8038dc9c60d971eba88b3c70f514c0088384c80858b209e38a384821bc01cf1c514546048e20c3bc496994ed849d3aa1b4c8814b8ace922859936cc50aa018a120001a60b12675871809914f090c7155ee8d0021d72bca4d1868a1136305106c643b7023cc2d020c60446b031d4a68a2a6f98a082cb166498c92245194b2861c79c14c09963ccf046981abed8a3cb162d4a425c49c20926dc60496206333d0041068c153470b8328645b3c567093738f0b0268e1fa0f8801467ac6ca185971f5e10838a4983893774ec7045853bc2f860cb0b4b5aa021f3c60e59ce64e9a28d2a74a8618a9b0b446146156ea861c40b6fde30c08b1c3690a14594388800e30d27ca00a3a50e1fd2e8a205a34d84bc99a558b5006d6b2d5652aa4686016d7ba56dad1d31986199e958ae61505a336bed91286699b6af20f05176362bb167d95157cf64992eadb5d38723303a6a18ad5926d6302cc66635dd62a65a29d67578cbde6559667dc0304a699c8c525a6b7d236f8c52faaed24a8feb4b3cca35c3b00c336392110206ce6a86611966eb186b7595029b5836b36c6aa7ec42c0c0b27934cdbc669165733ecb320db5993291cd071b23af28528488176d23657564190d5d1898c994659305cc846126131e2d667ad999e6f398d8f4c00613128695b0330cc37eca22864dcc075c76593e1a47cd8d6962d8d462939ddd9485bcc165374f26932ec59de9a39712d99c59966559a6b5fa3261221a189e1a1b0a02975869c2768985603776ac3b993424ba6f309930133645ac69b8341dbbc54cc7b013763299a8c944821b031552d8580656904e48a738b20ccb321366321dd34e278b6118663a65a4cc9489f6872c33994ca66c4e712365364a93959cd7eb8d6c6736b399611866adcdaa1af90227a6b5368e1cd9e9348132ef4c63d849cfbce7bf8de6717d59b1be7246336c1fe58d69ccda164e9906f5354f265b5f1ac3943212d46a79f052bd74e13022a8cf7a650cced36a9f7b3b3da866273278842e3019c2b7ed356d648fb7d52411dea7e3126f147684096cbda861b45aa3b0563bfd3d48d912a6898df0f866ce79253ddbc822657bce69b11de697ccffa8d48ccf7a9489b3186c364f227803c2d9816ca669182adb9b4e132b43c7d031096052548fd119ac28619fd24c41806cea26ad9e82ec0c4a7d65154a7d6511d84936c89a90ea3edd6af9e8c7a6435b92176cdfb46185fec75e5553956ef59a4fd7924cb043277d9a48c2d4c35c1e05d937a5e9982ce89827472558a952a584a32678a4ccd903d873698b349bfb38ce76a63c4f9bc574d236597b97d0a48dd95c26ed721ea9d625f4f5873ab02c5bb13ed7602a55a833d68aa652199bf3892130b8a4716c2c0c55e751a99e44a652e7b94a17b99254aa548a6257b344784e4fcff1642521322b097db943aa22da6bdc29a2692e9d4ae992844dafa7fde9d14055cae66ac743a74a97387b88b1bdb27a26e6d5b333a878234d1563b08be4f4f1601e9f3a47731852ba7a18de9581c84ceaf0b474342902f99e3b80e7d728b8cef31e8d029822d7798ec2cec9d7a62f8140dd9383ec4fea3c19c8fea4eeca40f6273c99532b5d16d9a178aa3acd4cea2b5485c73b05a6b6d2b677756e95b33b149e9b57a50a33997a787a31936790a9f35c9fcc64eae4ff9d4ca6bef37c5726531a094d800cf8bbeb3de4319e8ba1cefaba04ead1e52c8377b0d44eeaaed47972ea644e5d954fa85bfc0caaf7aa8759753197495b3ccda90755552eb11d9eaeb4565fa9306f1773779a511fad775154a99e4a5dab43ac6c8e76e1c9f03c571222cf5a69265276ee3a196a5204f23c2f22cfa393c0ac9eb4a3c9f04a42d3fee0b3f44af3e824972643cd44ca15fae54a42a40e75024a80ff9eeb43b13fd89f04a688e73b4f0253449ee749608af2c9bb74129822d7b54e6af21d9d04a668e72e9d5482e6d149d3923ae903fd72a611cb19e753c8a5c597b30d8f06b23fe2a710a96f7f4429efd134cc4a7ba698d49778553e9a6dac98b32abc0c855adba97f87a454a8ecdcc59377b292902b2b09f1642ab4a3a7fd71e9697fa650ea41767b98b99734cc6b97346b652e9336a7512491e994deb2ea0a0d996ffee0b24abd542248d987a2c0e55c6a52879049801245634ca6d7ba51323633dd96b34d102093bdb66d9b4e6d729354026741d566a4207bd34966706980a309671b60064dab70e4194c3777d4e6b6639bb31d9116115847c41ddce2ca0eb2e792166eec2dbe68b1c461ddbc21501a339b5990d5e6cc34b7d92cd33328fb61cd9a50cb0fccda89d51ffb390f14949d8ed2b48e52cae496c8149a6960aa755236761a8595ed79e395849ca8be7a11eb238b8a572909518ddd8b869d6a6aada4ea1dc2e728099b625ec6a91c7e4f65a51d6a5b03bde03bf861f5b5796d4670834ba52f9b62b4bbb8e350f3444f1f54b10ee8952d58b52f560d6d2303950daa51e2363188b1679b18e6ecf928f6ddb34d0c5e2cb0e4a6ca864d2170325583e712186bf6fce4606e2bc8d417c23ddb30d1036acf2528ae6459964d0c2b8fb0899da61246d8ad494fcc56224c8b15c8092cb670ae14d0f8a10a307c702308abf980850b77b06183841a18729062c30a536028d8218e0c730cd1021951685ee4e86ca525c478c30c3971e6a0f1f2238332f08f572582615fac78e39a11420d14377c91840adcd0327b50d306d00a53ecf1e58e20cee021620c5448637e5970f1218a27d4ac6186cdc20318786c4182851a522013471aaf1ff505d4864503a3820b930abbd6333d68c65cb1224c1a7850d17650b3b41141c79a37c24cc126090df3420d139a25f29afdf5c33585d46740062e1fa40a55d7e4605aa0376ac46867c43945b021c312549c814617353c60252d4b2cc96085183bb850a39e5193428786a670c51ba93214a5a60d32494ca1839632260043015390b8c2041b15d0908706241db8c4bbd62007c33a18038b2a68ccb0070e7c685caee822d3630c38691461c40b5570c040ca06e45cf1e1b154870b3b648922840e293803ce2517c89023ca156a74714308fb4bcd1a7744a1c4921946d8a16db9c28913142eba88c209375eb410450d22c23340d308196c5833050b229888636ab9224bb83110450d7358385347115d84300cc3b01a04a88c206e5022410871822cbe6041230709bc2044144518d1041a2e64d1b0581127c38c1873440c2a5832b3c2e93833e70a2abe30d186032a8592142ad2d0828923d23c81c495aac515346c43ee98e34b173918f1c60b42d85f68e06459963911030c14ace1c5882a45645996655996c3ce8e804c698c163d5c5133079a21cc10cab22ccb8eba7d3a9665599665d8b513062ce052ec5880832505ca444d1740e0e0654e1c3ccab4a0051573ac0963c5ccc4e186394cd0c5127994600c31d0d08152c30d1936b868f3854bad500e700494c9c169d75a6b196b9b985ec4c0058725e28041061f342b63a450677c084347993be064710643b345470121cea890879b30dc0853cfcc20850c51dabca0a6ca14704c1b96d05c34fa20f305063de0f011050d5ce2c901b6ebad4d03850f2b38a106172bdc80d16a58e24ae00a36d07842872182a8a2d6336b3cd8828b2a777869428915588d8613e00cb4d147113b80c1c4116ed8252c0628c2ac408b9b2d6ea83643174f8a931fb080f105cb175db43004434d39436b9d706ed818b73122d3d21a65d76a860b27b450011477c4e162036dc840c19c22c810038656021996aa6c1b2323c713667a3033c613530849408c0c57c891e18d20bcc0615287cc296fc05162018b25cc30411e706cd821063e3c252456f0228a2aa250b9e30c18754f3877d44ac2e460ce71636aae7471040d66ac7c112a8136f6a24a64d60f300d43b3b117a943b42a1b5bb2228f8d61981a5e9ec8010c183ae26c11c238700c3c2f93d1fe9081cb715461db1d54c9e0263e1a371c38d3da9422dba6ca719b8034a843ee4dab9bb87314f5c13e71188771188771dcb99b82b6f6ee362bfa1e666b57a956aa4f09579997fa94504fa519b6765097a7a38636930619af3077551eaf92595f40e7b88c2f7ecaf7507c11bea88bbe877a5e2ebcf8a2d555a1a8a7ac541adb1f8cd3242982f8d445d3945069977f6d932e3f78fda8080934a5ae9e6ae0723a1da5734df5f0a3f8d657ac9397bb19bca76967699d88b54e043f71f79be46ad6f33c0fc823f1a72fa76927937c1a4803d5d7d4ce69ba6847bbf4edcfbd96691fe388b1fd99daf5941dedba593b98cbeff5e2f1cd9a76ef81efaee5f283ad7dfe6a57bbdabd2f5f5bd334f9bdd3259984fc3412dac7dc1f70379344dfefc924b7fbdc4a9bee79ff4fd9b9ebf47e3f7ed1cdb48fd4949d264d767777ee9ab2a33fd8f32efdc1ee3e4d7c97cb7b508f40065f7d4cd346e2b136625d3bcae5d54745b6a83d5d1e15d9acd7932b8d35aa9e5dd3656bb552a9542aedded3ee3d95763d4f4747e75ad6d1509ab6699ea671b9a7fb7eea5314eaa77b3afdf4a05aa2bad3e9282f9745b6f799cb0fb6f6f1d3125989c7e4354be40f7509b4e7b1d6d1a5c6d2255e893aa5cb7b0775f9c2ba04dade3f6d53efcf41d6cbdce7e9a677f79ede9f7489faedea55e29df3b48febfa453bf7e9c959ff53787a348fcb27ef5c67d7d5257565fd9decf3e77c9edc53e486e07dde21ef5ed6777d8acf77f45d2ff2f9ce79fe1759f01f3cf3d7f3532cd0d3fe789a2445f8f38b78def33feb69a7f0bc474f3b7df2b43f3a4fcbd54b6477f71b02507d9d9bd9f5fc293bef39bda408aee717b99e75d1ce7bf4ed0ff79ee717f95c673dc54763fbc35deb697f94485284fcbfa8e73c5fc014923225eb69cf7d4acf797411fbc35d69bbf2b4dc3b6d84ba3d2ab251faf48a3f28825222abce109de91a87b4310dbbe974d6570eb298e9d8bb8cba86ba7694a68fba128eba1a856b0ba6dbd66efb76cea68e627d75950e3e789cbda3f2c4f8e3477a17fdb1a9f77942cfe69680c7ddf151b9ec3e4d761a04a5cd75faa8eef520dc7f197f5e0560f0281069e39bae12d4bbeef3fb3cf801a5fd6910f4ec4e93dc8dbe77e7be771a69cf236d30c8e25c76f81ecc25784f8f400683fa1e6ba3fb4f1b8dc747a03eeaf645e9f2a8dbe3eb7572896d151e59e2b3635dae54aa3975283e14c3797c0e8b6178eed4a172081e773f8547cd83c762f8eca7f0a879b0d3657624bbc372a252a14ed54b5477eaa89cd225dd288c5118e36b288c426d014f37f8a98da82689ec9c1bf87997d8cc81f6dbd6e95269cf5c22edf0b312693dd49fb631fec1b7eb40d07e03bf81200882baa45f0e3fcb6ee3dbef46f3ddbff9ef21141024c11be1cf83f8f3feb347dde6f4f68a2bd2aeb747dd3e816e6ba94ef5965c76d04d5358caee128efb367e7592f5ee3a29a3ed1fb7e5f05ec6dfde82a3d9779ca99b974875ac4b13be4f68edf0f8a6cdf33c4fd42028ed107fbbb75d954bf01beba2a9dbb67bc79484ffbe65d355e21d831bb88124084a1b3c168fff7d40698b1a043d1bd4246cfc9284fd05d92d97e04dcfb2fb01ddac7fb9fc1eea11c8e04fb3be6923d6456dd4faf6a00a66a4acfc3452b6597ad61799edd6a70efdd622c767df74d9e9e8e067781cbffa88ef9df3c62cebb6ef5eb6e17ff7c6ecd986ff81bacca877ec71dcb30755a2ba65ce3ba64b2ecbde3defa8cddb36971ddfe9fe8ef57dd524113d3e3dd6256a7346dcb58f5e25f4da35eecb1ebda69dbb98cb6ff1602e49d8a0e7e9b2677bc757615df6f0f0ececb85c24d96ae9e88c238bb55aa954622a70b9808080980035516badb5d65aebb8299d73ad8f037378dca9c097088207418cef812f2f76200b775c97d2e1b8711cc7d1f3eebdb78ed7169b783fb6f7c3e55a9dc5d2aaaf4a71e35197187b2f8cff83a63d79f2448e3944b23bfec67debbaeb7c98e43411e86db7db8e3dd9f8d3b4eec993275d2ebb739d46c248b2c336d975a2e87da9542a3587a6699aa6699a8684618cebebeffab0dd29cf7327ce6a49fbf44d2345e8cedd49b79d33ddc94699d417c6a4c691d38917c7a7760a3ceae0bf7360c6ffb2f710ce1a8cba4b5007c10d6a278f3bc660e6501c3eea2078d455f2ddbb247727ae93a8ab494edf22d73da94fd7bb89d34cea0bdcb615f656ab636d147ab9043552ddab2ffc448522caf354aa772aaf53a9542aefe0bf4ea552792acff33ccf93e39d6eefdfe781dfc1cf0a22be0c82f8b31fa879efce793f992e9177a9132727d3edc00c033593fac276dd9cd7bace8b5adf75f4b4de8bbe7f9a497d4d4f33a92f8c25615f55d08df2c73eddb54f3f75fbd4e99f4ea7d3e926ec9d3d951a8735ecf47aa1aaa503080e4ddb585771abb73eea78c79c9753ff7227be4bbd7b79dff77ddfe67ddbc55c7adeeae0b67a50c5db879b74dee66ddee661fcce6bd26477deea38a557dfb4d1ea60f7da2b3deb8b23478ed51a4715eb2a968aa552a9542c954a7555fade0bc7f77daeeffbbeaeebbaeef57abdeaebb5a6c9eb9372cae613ac5235dcc0929234cd8dd3992cbb463b403d3b8a76d03d3b57afe512696b59f6ea1dc3325176ee5e4e9269d3b912b64997da27dd2a12eda7139d507b9eba8ca21760d76ed2e805d84d99684bb2698cc894c4f4d3eeba8e625ad850ddf12c72fbf7655c7178fc8deef0dbe701efe1768d5e801f7ee3c24cd43dbc9793743ad4587de1138549c2776137eb6b4b6d9bb87dc7acb5d65a6bade50eeeeda66bb2c3469d263d903a78a2492f289336fe0e0f7e6efced1ca841301375f7ba7b1e0e454e14df85198b5d6bc4f8aeeeea0bc17f2b30c49b4aa5527ddff77d1f1b209247c495d2a5e665edbb2bcffaf3dde350fb3e22dbfdcbf6921e481d9f48fc8e2fe6f01cce44e2f1533909d644f8dd5339097ed77d9f77d003e0bf1369f482fb501385ff0ee624a1c62ed1777c3027f98ea4ee6f63ddd5d7fd97bb2375f88938714c259c36ac84b184a3d14b1adb25371dee5f6a3b5e121e3ceeba94260a35476e5b099a86c9f0db5642092590df72b96dfa6824c9ed68dcdbd1b8c9a371dbeeddb6ed76dd15d3d0344dd3344dd3c612f697fac43b19efcea569e3693c8df535029530fe3601643a67d2b40ce371fc5fafcc843554e7e1f12f274c809800551aced852202b043f4d1bc76d478b074550d330fe5fafcfc9ce5d453bde5d4c4270d34662288ee48a35aa5aab954aa552a5543a3a3a3a67b85c40aeefb8f20e90eb3b40f667c2d1a9df13274dd34e502c141b461977f595ce5517c7ae6381da3ec1b5394f83a0f41d979cce411d1004a5edfdb39c87d2017574583adde747d64a756feaa6eebd3775efbd65b458b5f3024c76162eb404ab1b408192059c30d5bae30539dc3ad8ba20c771addbbaa78d5a5c2b951253622a954a89a9542a4ce9300c4f2738dff74e03bf839a565f18ef6e8921b81eed4c1351d7ea769ad9c5266295438cade3c26f195f2c8a7bdbeaf78920f710e4c0f0081f896279b4f1cba3eddd13412e3c1237787c4c1b710fb5d115f391b8bd6371739b2e8fc47d53de4da5baaeebba6d63b1582c31c4a30daa8eb12eb1caf38ec9af56bafc391235511337c69a288a47e26f15073a9d4e279389c9e9644f278ac2ff7eca259009bcb5dd3d263b7be681c77782b593ec405d80ba8a09f1a645721f1c7b6d621d10fe4782df3f8e186b5aa849b0a847f368ef03bff0c398c9ebf58fe3a749f0589724f9dd89eb3b77d2731e7c8ffcb408aeefbcc8a5a7dd29ead14fb6779e271b7f6e26db03315078040404c491ad56abf50688c9ee3ad2b6f028863b40d48913d74ee6b92bf7009122ec9ce7453be72972bd871481e73b2fe2d9b92f3a02a2293001d2a9f88cd7c676b45a939dd997a7a14c9ad3dbc9cbd336397a2985397a71d5d601e4667551f57bd6f885efb2379ed0b3c37bf8d575dd35097ac71bde5407555d93bd799a86f18fef81f78e5e206eb2bd974db04af54d1ba9b6a357f9e9a3d75675ba3c7aedf1f32d96ceeab258ab8bab8b2b71258aa2b81245d1f33851731ce7e6d5a4d3b96689901f5762f750d32cc6761c3defe8f57d5ff7ae7b1dbdb0d73e818ef55301c330284b6dc2eee3532d95f8e925f7dcb95fcd694fd5752af09efbdc49a026ba9ad3a8af53759dd8899f6fa5c430955a855f85ab70b55aadc2d56ab56ab384e8aad1b695a29d850b9d6ed24eed4d1adb00fb2983c9a610fbc4b6d1c5c671e2511ceb2b9db7bad43b9dd4bf107bfa9df794177ad7eb5250ba7f9f6478942ec925e03dd43f5d92a12602f59c42e686b23fd04bd9edfdf3b4d17da88d748eb2765fdbd261ad56dfa752a93a15d7799dca4389222a8bdfbbaeebbaae0b7cbaf1bffa9dfefb30e5f0b679ba54da5f2ea1ec2f7c2aa5c187794e21a02eb1dd7dddc11c64bb7cffe512c97a18538c8fb3b7047b1a11f80fcc26d03ef6577787a7904f6f2294391ba98eb47b03c3b45336af604304aa135bf843a1de5afdd3a509d83e6167abfedd7497a08e35a84150daaa73f77ecf65eeab5cdecf835c787c0ea38e7399b4f10782d2e6fe7d477d40695f0d829e17ea72250aa5bf639c360a0f6aa3d65148b5c49e2645542b3b4a14bf675fd7a5ba4feb50b9bbc75debf0bd54f71d731dfd3acd7a86caaceffbbeef63e369238e6edee93d6fdbb6eddedb7df4eab2ee7bf15ec658055e05de874f79b8c362f8fa6b5422d56cdbee058fb3f5f0e9de12a94eac25dd3a4e59f6e4743abd4ea6fdd170f664634e48c0e81e5a6cdc778ffb32f82d779ef7d15a6badb5d6daf01de8fdfb365017912ddd6de1e7077e1edeca27fbbbe92ad94a6d7f24bea74bd209f9968775510bcaf63ef793ddfd2b43efa0a791b08ddf81da68bc87846def1d367e7a5ed7719cc87522c77198eb448eeb30d76d294ea752a94e8bae3b7dd76958974a5d2e9fec2e7c2b6be0bbcf3ac43b98677d2161985e275d2b93f616b5de75452d8dbd9ec8d9487653caaa1706ce344fc2ce6636b39d31a8d40b99c7f328a91856230100080316002020100a8603a2d1601808921adb031480117d9840644216c863b120487120c3400c641022c6184288318618a30c4d9d00ccd7dd74961c2dde733c0ee8c7e38fb7dd1cd61f6770840f60371d17ff7d9dc08410d419d27c1d4a0f397a79437d4812a66942784d5d6d836c7c00239d552da97ee03fddfe3e90924b0d40f424e9f81b4e9b68cc7263df7642e96a5988a5dc937e159843e17b5a80b82c76fca931871b035af038cfed03377035fa5216bc480f90c64c2a3fc7f9d40c4866dc8392b635efaca49ff123e3ee147d5ba4ca0bdbe543a14354287e7dc27d16a6c60ca2fba155302254a1529070978ef32ff68e40d63760571db99c15f9a724c30fa5f17d909d785e59701f824ed1b2277b49adb0c792b7a154c5f725a4891ea8a50ce1ef0d485e82640f1fcc95b043ce5aa1fa9c07310677d0d53dcc249eecd0b0388fd27ce3aa6b2fdf8fd426e03d5b0b780f8b5263bbbb1e2952bfadac23a7f29269810c74df7389ed230427e0c6b3eea837212a70e5fd47d9f7605522110095155ceda81b06275e3203d62375f696fc259b95ec77db0604f587e747a2e1d663742e49e07ac4a1276a040a8a5e1bdf987ffb83d73e0f53709980e09d1d274a69864619395fb841305038ce2c154ecfcf805745c783f821dca7f593133960fe319177d4d8b764d483744b76fd707af16047a3592dc5ab7083110cae053ee4ba4f89d0aa6123983df7997c4e736223e4c87a3ca76195fce3ae932e6ac435cab86bb4cfd73aa355a0dc9451d260575542b5b4072ec19026f7c64895894a73eb9fecc66975fdb2c31010684c8153ceabdbac7a6608a93c69bbd5f03164c54b3c2ce6aa5f2f6a8a968a0deff5bb9cce0a345587d3eeaabbc609ef07f02f16b00f317a107ce51c613e69a5ad0a77fc74f45020d15f8d26f9ccc65013d251c64bfb5ce13acbf23363a1513e19176d4ea36649f6958119170d050a5daa22ee0da1ec20ada8a4c11759bb9ab8959c95c873e7b3544ea89012bcc4319dc1e3a85c4d49759134fbbc986c309795ee901f15ca1dadb1c7f7f36d802e4f251d148555bc51541a526ac81f1d9773346d8f959343baa73906f4429db4716961e3ab840ed6399f471bb72a6eb7f2bd060ace73730d79b15b8c3911b12121b6a21b8f681cd64ba4d6a683abe4251a1788c1418d58d0165b686c21b2e99df147e3562eb61ef6bbfb7a11c334e9fe55d25e0e529dcdce1426df80c697f9287aaf9ce989473d86f919886bdf0e9a1d9c45e967312d821599076d223fb1caa390fa749adb8c6fbf7c3c75973deb705cd973acda8d139fa241da39421210311647536ce93e3ed66fd6846bf59ff72aa747a2d250619e1ef62a39856a026a404469c22af5239eea7bac12794168a73bf246c99075371a28f9cb9b9a66c6512a664c81d2108b86d044a6362703c96324f6149ca9fb77285d36873eb2f99c0ee0d706f93a1ed062330e4342a04df99021aca59c3c46ad7e2cbd5e1c5f7f485e0f13469e93e219f7c2ca88176116c2f1df988588f39d10887411e4691307eef129cd7b6c1acb14b706ebc6b730bb218127de9a8bb779148a0862d6044bfd29b28f20dc9c9373ca4dcdf76ea6b63a7e5885418cd911d4452763be6ea12f0b53cc728653819f06e3c7fd783dd8648bddd010f9070ab6ed9244acbe12568f1e0d29ed55d9cb871b5d94d4b99de48d4d31841a41a2c7e72395212f922f7a986c2efabe101ffa85ac6dba0c871ffd2822a48f97eaa3b938fb652790104af1a3e801ee9610910fbb42e542e465272a938e77bd40a3fbfa0964719b346085b3515d1aec7bbf7bb47808651d1b195587565432fc78a220daef24d36708d1f0104499a33e222127a2b9f39a37b02320fa3d653ab2580c3d405104f6ec78abb7ac13c0d05eea50abf8d3145c99457e8989672c6defe30d81865a296a28ea641669d490f5bbde3ce6adcbf0422d03aec8632844375a0ef54f811b45a7b3ec1ce4f5b0e8a174755bcffcac3a74258e5da55029e85331f7e9ff1e237d941d57a075304258784aad73f88bce342f7a6e517a05400f851641db5ad162e697515b1426ce6a5b1c3a2681ce39cff838cc5af5f0477c9895a447b2b1fb9f6090add2dc88fddaeb79bb7c5c071a0bdad3426f1e67420236a5bfec61715fdb0d8b09f902bc38cf488f1e37a6b0d6bc3bad78a8219f36e1acb711765e6b47a85d696fd5e261bcec48618b1db3bf992f9f7640da505cdd11b17aa3894b84d4ab508cddd816bcd22b88b105607ab668b1cad7f4bf3a98c4c6b0414b62e9078ca43f5e656c4f30d890c159ef0fcb4f02257fc03473ea9020f88cadf057af4b5a43775fe95f3c83caa4b7a09f70d0269335c2e12f0920faeb1af227a63b3b933c504768699f36c859c56c1c0fa6123f2baa21d3216f5e37decbad1733d2d0be44ae23cc74824a17f0a25da521da630a65c26e16f8a194b65a69c47b9dc1121782ca3d09e6f4cada0ab248c3c560320a2abf7f41092a0367ae7e6515f8b50f7e67cb1c4d72bc4007160ba3e16eb21f34a5a10e3741652c164578d6eefa5327f7e3cb1ef2c59744e06902c440a7861105bebbab5fb96e14b664a6511ad27754b85470f8885f9acb2eb223c3d0c7341cf95489631baaa0af7f9b5bdd671cad0985ef32f8b16bd198ed83ab013b427835a12f7e326702919b5b9bd009838f650a5199c1efa149b70c55d9c947ffe7a7f5300e44fbfd980d12237f8aea3ab9565661ae8ffc1f37ce3f8abcf1ff4fcba21300eee6278a6195e9e94b1ce28c0c87f267d4311ebaabaa179601d1bbfb54658c6519921960f01896d986c6901b94c2ea69c83194319e2c998137054f746630e522217be6e8d8b54d512c21f5e02aef223bb4f3d1f976774f6000044484c5b7833527b8126392949a9056c48f3ae8c827dd03aa72974ecb419025c2d8ebf0cda6674bd16607e14f37c890bb10b144a7de8df1019ebdbc2a6ab38569c0e4d2c21ff8579db0c563e884a9fa3b64748de38e6422896e707fcfb7ab68e8bb08d4c1b865ed6ed3846e98b818d5d32fcb50408796bac3c3e4e8b2490d18a9921f23353c4fce8666ce4720a069b1e93dcb0cf4b8f9bd5dadba2cc383bb8e5bd1eaae80465444fe34901aebaefe6ac0b88d58e537ca0ec3e5f9e068e0f4d298ff078cade354bd0b6890b6fa98aa5c8745eb111ba813e3aa118e080f30962b64adc6177c93b454f0e703ae52b1147ca4ac58dc3192f7009ede00af80be1ba65a70643a4423b73c2a9a41e6291dd0bfae7560cb9b844fdf5bece90483f0057681daef01a465b313f3bacf7361681cfc4e389c506aed25b0d6216f00ba362ba00030a88043578d2165bba21a4db523699e0c0c11eb469177984f7300017624fd6c1a0af6d1dc2a287a90db53b7d33af134fb7eccc9c15891af3bba1cc524839a230e1484b8536cf41e09628d9810a3f2345cbed5080e54ce2db23942636cf428541c7e675df66fa3d9fc3af21035b36760c14cce7e50a6f9e57f1881c1cb99812b9665ee3c81c8c9497382ae2c26f3c8b3cc08203980f45ba9e81aca1da35449187501178a605edafc334876a490dccc5b27661e224e87c891962749b83f63725f71b2200df00c466252dd98f9f8751ba49575aa4c62c0dc42bf03ee32ba9acc54f0231cf025b723cca0b33c937efd5857ee978ab1513aa336741471bf39d557155c974f5035656cb030b974758031b2229ad5684df293b080e7b018aec61fe48bcc42277265ca9d414933c30ef1a988a3a0f1e5a710477189063e42b1f0d4380984110bdcaa026d6bcf67b8d158f8a40db66d3638e5864925b78e3f0f95aab1aa1a2aaea0059af1ece3f4cf2a25f780b25fb9e480ade5659f901048a96393b934d6d02c3d05c2aff22cad66e02c93155c0410a0d56bc5b392677582153c2540a2956fd298e143a5c592476f07e42d6dbe70c012acb49ad816427e2f535b36022e046f93a0e08219dadb521d5ebace50b98b404707664fd538d15d3465be2e52347398d2731c7d2589b13f336512d1dbd842a20c72fd638af29f8ca1083908d675d0cd2475fa80ccd4d5543f7b625bb1e0738831530ea4bff6e0bb6cdfb141054dcb949df37c1751f52957e3d7520e260ea80175e069c66d2c8f004b6227bb8b5be4c9b95924cf30d5bf1d52f6671c7e8c315dbbcb015b4e9e4127e17f02206678a9ef8a4dfc7238db82127bdf6155f005254335e34f897539ae997208e5e51e77d40ca74726730d41759f1cb0427d484935bc405f60340dd60bf021a941390ae2d30e65c902dd9f624836cbf9c9682c47b1bc4856a539790e16a4e8c5f4d6f8eb856e5bf17614afab971e48052bfa41a58e759c05eb40fdd9667eaa77e97e73f3de8749252a3d28335233992f6005c6e58e1224b71446c89ecffe436f7e0884dbdd7e2d0b27b62843d67383149624edcd8bf0dba969d19d825d59b2d0177bbee248039530021e09374a9d3295b4f24afee5d5e72e5cf022ba9461090449939ef317bc4c4fa1911a5bc624d47e7db74e57c6bb14a8b7e26baa31ad1c00fca5aab411cda4460ed648484996298fd0d4420ae229d678ded83661b809e6ac3984537a0766e5aa4936558042853e42bff420f77205a2bb74af9e687d81961e9e3da4488409b10a37058edc1505742675686e37dbeda35d6c68c807316ae3fd1ba1df085dc311ba0ec1662606267d3991b81ebaabb1b9ef1ecb885ca444aaaa6c5426ade579749de0883c2594207e40342584423bc0ab43726f61492e7d04ecac1809f6b48d073b777d654585dd8f1a001835ecf26de4119a938873d1c7c9e0f3a02ed436c901c113c52deb61334fe247e8f31c75b23e248dd3e05d7faa05f5ab4d104b972ea3bec002b8e9dfe39a4143f7aef6aa6694d505e4d071cf43a3e207c0a299ac5e3731d4764fc266073eaad23b05feb4335d51348b212efbc8bc1a1cc0e3a17bf5e0eb84785c7e4ac2a8a7f23f0ebf27823250d28fee4f3ccdb5cb2342b6648bbde83fd2b5b909ac9ed85d0d054ebd9d7dc7b719fb86b59d54acc43084b313ec44f4194a6fee9d4ca37a03d01cce60a157e828830421aea0280221c2075f1c09d0720942cdf124804babd22e41582a069c04dc7f90a7069a9a6f743ec64aa6f33998229f5aec2cc39f9d7b802940e814f2dc9190681ee4a88d224090b87e3859743e341e859c870fed795fbe19469ed06d5fb1d2b81ba4512a3f8836e4eecbddf9cb292855e8d367eae40d8c7f8a36cb0fa413436ccb06f65a647115574832c0d2f26c1faf6f8f1227197a77afeb8337a7100e622eb5b62770671ef2ec91eae994a64ddc672ea8eb85434bef26318a5f8414ff5e58d0f010fe4ede9856f7a274a1204fc2c80f98c81a32b59073f9f5cd3be0e2b5fa0898bc83d286114bfc46c99123ac58c510f2f0dec9959e8c40d08e3c8ec6e29fabedc3e9ac028e7ccd6e3f53dd8003013cac7e8d7bb7a6c8a4f83369261a8869c85249f6293e3aecc3084eb39ac2dfee38b8bae7a3790ac3019f627f1fef8da3b78a6f616e3e8fb6a4fc165ee6e135ed19afb8b7856fd170ba0049c8f0cf7c08863a376600a2257ac1cf16f655e4f315ae44b081d9c2bf03eee6e6c3433e66ea617185aee37e93d45c74493e62f1eb4ef31d5c629dba94eb701b86d56039cc141c89147bde2d9180388d0d28f349817a6a4d449446981282d3ae929def77a147409989a31568a3a58fccd338c87668a0070e27d001fcbd01da7eafe3aca953ecbd4d2ddb737eca739ee09dd592c84859eb8ab49f098c68d4fb559904ba3c5c6560bcb988e84525e24243e7e8ac1e69dd3ea6b75abfcbbf97921b2499ecc4c7f18a546c5097951e15af610e242daf173d7dbc9ea8e55222182117070ff63aa0d55998fb5afd1d1591f30fb77551d892705a578bec615cf31afcee87d7023fd1aeab265efba9bc3baddb0bc633cea20f98938d514ac845daba1c3e1c725d50e563d25affca78dada4deb1b1c096700c376ff911e947cd6fae62f903cca3eeac77c639b9b4cdaa1badf85005edfad49907cd47e1a697c435216a2b0d629760cf0b08f6a41bc6f51708fa1fd5a88e820e21f73863e3ea37da3ffa7660f7747bec689aed1f2f71036fc31ecd221344fae062e31369e2d3610ff1e53eed19ce9db2bb490784a2d1b1af451c6d0cb9f0854e18236548b6984f4708e62b63f0a74291de9ce07c17143132be76d493c949451e395d83f5e7ab9abcf93bc94901b7f24718bd60712a8592afb9d4e181fe88fa03dd28cea0e49cd50608ab9c832a05e31409e958d7837bc57cc9a04a6e007a550844ddf02ced5ff3645d3185690ab4bcfe4d2dca77e355561d0c4e4f0a9bb9ac239790f92b3e72584d594d7a759ac03ffcf6a3123e1b3409934258de81018b42234b6de4237aceb7941e1d1662c2417a3b3e57108c52f547e323e9b26884fbeb3a6f0f172f3cff3480ca54f92cbfb902f68557872f1c07f8d622c68736c94c634a2d43f156da224c352085953b26f50d8c5577a2feaf1f4823585e37049cbf3856ab819088a1b45d8e015dcdbee454f11953e6a558790673e520fc83276e82984c01f4294a75ddfd8a4dc3430b0048696c8b0c07f83e7c84b732b09ee9f53a820f0fb70971e4eef4fe2c38ed1b07ab795771b87c026b0e2ead6dfafbabea75ea76a2360f56360c6c11f9703d94386bcfe4b458c6b056c69f4740d2a9a0356274160211211acca6e22eac27a00ce4bc90df9c106888d836f040273b12e38b7973f5e8fa2277721479c1487824834123322e4d4684c732fa98ece1c4ed89913fb82d6cc19e1e70482d064b68e15896017e69c49f8822689174561019605b4ae7df2947c66269017e651326aab171ad107943ed1108f2e950aae1b46c583ce93123e3ec8cbe0bbd1aeec904efe36187a41d2f0f76b66fca64886646a555bc28f40a40ce1759de854f58afcdb5f978eb0f8837229d89b3bddb82a6b3e28dbb7ef5c6124e2a01c7e1dac97cd1dbc4b0c92bc12c2a5a0fbb503c7146b9cc4e96ff6cf644b5c06f141ff4f3b2873949bcf1d409b879827975490d76ce442a9f0179e35bb4ea887571e83bca7d272d6989cade1e1ed77ebd8ae937c8b42b3928fe88158c771f82e444d021fd1cfbe31ef5ee3ba0b98d3f55c440b478ec70411025bcccb85afb227a028e4c25c16e0793b0d14faadb5b2018a2776bbd3c04120327645a1d1c2c313b8e401b6b147bcd6c3d7e100eb517243b169d2319aa50a58313da9e414ab80ced4ad437b216a851f1a11f212c04e3ef2980da9b9c0ece0558e3819a266d0aae10ba76d86672bca48a8550b313c80aaac523967ac0215eaf5bacd880dd1c9bb220b9a5b76f88f66bd1a17b934a603c5f0fccb6e9303ff9f2d151779eb8a323aac0c1bfbc899249b7add7983e01efa54d8bafe55ceb841f966b953062b288ef05e559f87061cb0c08883fbdb8afeb989baee8950d6cbe3847163c03d2b9cd45066ecd4f890f46448d50570486abad41db581f46e8594e2e08c2b131157ab4cd06747992baa94eb5af6d4e6ae3338cffee40eb4dac262ad43506e35ed6b0e391c016c306b11619ae97eb28e2055b12daa8860fb1f6cd5a117d43c8433b902b8f2b0a13560233001aa89880705b8a0d0a89a528a7720427efb22dd8863b399fc059560bc0d47faf5b34561e0cdfd9b7c5a07c0fb67ac2c87784606afdd001650510afe5d4457ac87569f46e8002ba778b69ba02cff1a5ce5bbcd07a1013a61412d7e87737d85d003a86ea6bb6c732fca2d6dd874882b6cd0ad4b0a33d68686ced151eb942d457c170521c55edefd35a4c27893a0b1200e0b90ea9c0ce97f2c80bca582dde794a81bdcc8fd6ad4741bebb5cef935283355c0698d1ad406c7d5212aa56945751d0ab9d93c0eaf7b0e862a1677870a7dda4d8d4d6ac0b9a0a3283b999e62bfe8c42dff209ccc3667ee68056e101272566aca8c11b0cf5126087b4463b8d0d5253565aee19fe795f17870947799fd086fabe37b0bc50292b2c523eaf7e296883e783ec76c21033f95ee16aa1daa846b7d2044d1b692445f09301620de7b4edbf49201434da889087b7cd526968d16f55875e9ce421eae3fea1712b38a3a08a23bec7083f4c62759c835aa6890a26e71dae3b1fa6d3834dd71ba2de454c0826a8b03d271f16ca455f330cf5b605938c388616a2902de4a7f924c6d6f2515757a5cd362a665c9675979b4d1c39c2988190458cee77e964ddf41ea61e598929cb8ddfbaea8c35055b7ce80ec7c35ad357b0c30b340a775f2dbac0bd3a7c28c703059701172be1c8e17cbd5e5ec8968f724548a8d76fddedc7c7f88c666152ce957e684dd2e9d4f6f2a02363950fd9c86633b96a8e4eeedfb041a43cb40804c2a77e8df958c193e38c193982edec9c987e46f879728eb1630cd84e174292a8f13d0e5600b7fc420f06b28b585e48a651d04d5551669fca5b44ba4fbc980af8dcb911a1fdf4e8cdc4050b6777c69171f8e06536f84470de4770a5bae90e7018a6937fd17d5f1cc6b350406d53558731d3e30613ebd2b03f72a62a8b0455e9aa0e827da8cfaaebc728416c7860678067e3f97346f9539a8ad4408945393d4af016d68336973c5e1b9249d3e8a5f8da19939eb92c75ad82e4ea64fc5a643a797644eb76dcb26f349142f27500af70c3d1a52b3c06bb3f6bd4c5aa380294da4704e80e927efbbf6ef22fa66f06a34e78f7f28ac926f5b399b42b4e2e038ccb9f6e0f7e98a963485c84defc4d9441aa467b337edf4c3b7134c299a24f504815326142306937d8252872633a11e6b4545079a1e3897cdb15a28bbd41bb5af161691016c8dec512b1a7d2621682545191edf29512128eb0af059516496ce7283119f85d5b6ca22e34c0deaea66ed82f1be651434897163412b854ec1896ac89e783d97b678ee8e9471194e2886e5d5cf71b9bc44d72fcb7380ba66fe8889822b011caf89444da08db109fb11e24fee4b00d12149df4e1cddd2e8eca3c54913f5e6d17eaef93ecbd72761ce707ad28f4772b875816efee3d7356c90569312af8f0549e0aa3f8f37b6ea80a3eec61886b960c2d1538e7f6ad4209baa2f7d1e4a933b8c3279021365a6f49e65d75f7477d7681d659069882816b8fb47d52c7b69c57e6f202a1a80556f1f5ea7cf7fdbb8ab216db114496df76731ee1082aca20647641fbc093f3714098038e2c1a8da477244ed85e6b5e6eaafca7bce75a9121398fe9ab9b877d81f4605b8ca56a2614e70c211699ecd7b3ef077a68974e6745d57994b52c24b2ec5784448822009f7ba7792e0986b29fa1e26fdf0e339dcb9e50cb82f1a73edde061884e62ab81a601cb13029d2fcdd3f74fc261b62d7cce99a177dec6e16ec052cc043beebc90ab3927e5b96cc5c2a0026c398c381c9700fe290411bf0d644474bfff3004505163ec49a1d22d0a5ae410166e4576dcbaa14ee08470978beead9816edc75f51cd0c40201287533ec9c5b48370ac29c80556c42c5a352c5dac1b1de1038a9b23b3faee6fb5ee1018037c2b693da72a67552595c4a755a8aa0708e1f22f0c59b5b2acf40a2a7aa1d82c0f95e5429e11ce429f72899d7d0f25e80c4ca50c235ef22f80ef1a04767ab90ca468d55720230bb668b35d89baf8660653eda2a21ccad4d74757ef11ba5f27f6986629671aa00bfafec09d438089af8a05ecd98cb7aefdf6bab5dd5d1747fc9246b3e4a49675323e5195ab1618155d427e9115ceb87ffe0d37b1218ef7a57db2bef60faa9a6afa82dbcf4bc347ef414e8229ff44d55b64a9658b8b70c045bc1954a8249daf0dd8674f2c400d60d5e4ad24757d32524eb47920842b577c23ffc308b72051d8ed9858de10b5de260785034007c3ae8e1f19852d3a1ea1b518332621401c410142129378f84ba0dd91245fbd60d5741f5eb1c77d5ddc591fe4673d72d2c9a1ada4ae81040e94330fe9a5494a2c8810aacd9fcf5fa73487e2f34a2efcd8897e9f46087a0b15b33a294b388405344a461b29a78a4acdbc7c34cb6e6ea78cf2617e4d218f420980bd7670a7455d72ed5b8657c4adda078cb8230f9043f2f6a8df82fe5b61fe1b2d66a4b8b0417a8e56619bbecc53e61aa0fbb94b9ac46f26ab0006e6400f0602e8a0fab15eb5ac63ae6a4d7d0158edbf95650571d1ab82dcc9d41d2eaa00cd024d053f5afcf16541be4255bda11536320694e5873a42571f0723732208f6a436a7c8daf67f534c1316c24ece55717813ad4e711deaa8a516fb65a50c2b8c49df32c2513a0d006035ab6f21090b4ea39767476580d0b91c1e870a44c9daaf06ec26393006a1b13e30b1f0722016fce40f95f38665a8b96f57360e23f14b5752ce5fc1ff905dc49a4b8370a54e9b99fe2c7860353af6f173df050346730edff2c35d99c03feb3fcbc01cdf556c00426add00e1ce14c6dba6a695f335d53c24e48cae4324227639f9526ffd59f2a28040e9de0b6663685ff75495e56909334a82545b81a49e9e2c238d71842223c0515e97c1854f76a7254d64e068b0a3d62b3238c12c479526142d6e6ff24065f3355b493465a6891528185cbe23a38d39a54e48cb5507eaa96624b4573a4ffa4a1fac89104ff80b244db877272b419670090f1bd02d86efb422ffa128b84e155562bbf3ddf2f784f50e1aa7db83e3d395f2b57a9861a1b0fd8a9bb91cc93d0f857068d5090f9664e406f5f1ce2ee68d4c53caf1b03dd052a3ddd2ae6c826f06b4bc34a79ae61bb0fb7cbd3e6126faaaae19f18b55567634868b55b4ede3aa9efc0c9092ddc003cd9e1981d86e9b42527dd61c1262829863d3bb736862c66bf64619521f1299e7dde43a2aeb49cf9c3607de0bf89642a27e9aec9086b156e80e137f8a683dfe3b28816f9e9784e2c739edf5f058216d42112fdc215601c716dfa5ee0ecc18008d5fc6fc0190565525c671a60bb67e99a0865683832a42983ec93a8521614233d0d58ca54688c591baaa4c98e5c2b977c430143190aab522c62f46750ff5af06eb92bfad407bc39f0dc1df743ac82b5c13f98ab4929a8f260987b7b21996f8d6948cfe144af2f1bb6b0f9ba6441a2a7288451a47241194af3e3974d93595c73dab1c5108107f396042b7936cfff662bf0a630cacc566c9b4dd2766e289ed084c0d3cc51196d0b0e0473c4ed274871d5a308e852ea940583e1bcceae094c63b74804117efb2b5adb4350ff7a079d6544107b0046d173ee48d8bd928a9688f09758376da31d8d08b4aa615a85985628965fa804aa99b9ac603ca5e741f3aae062f4cd04f911b7971ae5f4e635db025e693719014797987704ae8e1804c1ef85c9eea05eb8e1209f705888e44631607260106bb88da7016ad7d9813f399c906309523833d70afc81cebfee6dd3a880e6deebb94e341d24d2a9d36be9aac6e35c147d7cf9b28ab8629d53c0cf00696e31e801d045cf4cb54e4356ab2b139aae03995c6f5982feb37ef436781d4a883e2bfc16b2cae77713bb0673d6b4d052a80251719770722b8fbe716cb571fcec8526a201012cb4d56036292af53c321403a3d0eba8bedb6220a0414b7c8c45c0c6cb83f5889b71e8520a007691beae3ac0039d23e20af5c55c8b5b710645daac3427cfbc35d7d6cc70b965a8d1bd77eab484feb6c6a90878f450a8d3a4d7aa02f7e1dcd71a1d7cbf367e5754981504cf671fda9173a42c16ba561b8f6010d8c590768dc1ee7c9edd6eb69de7e6885334c726f0faab0e512b44ac0d72936d76654af4dbe2cfc8e1efe56576714d79e66136d79c57f15599470d007f63b2208ac4ae28d896355bee7eae4a3ec111f6d8e4e15baad7e168176615acfb2741aba23e0825f1b25d807887160284f75f515b6e9b92da03b8368fa9cb51031e05543fc71001079f80fad7bdaef35f66a170a92749d2e9fa60a451e488484f0bfe5a54a95ce235983348387104644bd91d7723b6245d71b5c280395cda85f7270348bbfba93d0e9e14912e703cca5077df64213f013a0be8d9cc1e34b0533d77ddb759f7e1afd5b3edef8a9d5f499d96b774540f808158315b623112f52cdd827ac9c03d455725b9bd034e73a5d483f32ff9ed9e213142547bfb877dcc0877f45c15c72062235985c8179ba18ac702507a69d9f5cfe656495b5cadbd256681a9cdcf0cb565f469f16db63bf7af20ceb6153e2148ac76665204d8741ccea5aa55b9994143454daeed56af099afc7099d3210ae40d8afcd6e54e9830538e7358dd06c4d5fea6eab825c09e8a9fde215dae1311d1502744fe3dd22060a0f33efab2600de56991c8ee6075327f4750c0210e447cd339f6ac80c8e949fad6e768e5382a40518a42d481507495c81027906f5aee4670b8ec901afb1fe778021b4d4c6a611a0b98805c3b09241c41db336e7beb8967a03cc85b1e0a2e442cb7f4a46c70633bfe86c23d9eb8613a33e45f2f82ec09b0e176c8304c89f8bc10539e40f0e2fdc72acf6d9b8673cfe1c8d877e5f52b12b5b79b1663030cebd5d0ac49f0274a1926944d9d1e940a0f12d2f5f36551b19996d05f1db4f29c38741a75fea59a9533d4580a5fed235ce84a5d61344d232642f9455c20b777b9d75775cb1ae2686674565ee5bd10186ad163b8ef1f359ea0d32454d636d63d5d8f7c3132d8f2487976d341e500fab8aafcf4a5db848ba40b3b5cd9ddb4ac3c66f7932167e080e07b8577eab415e77cc36f0105be6a1f214bb53d99cd442af8282558c47ea9f222a83c248c2a7d923e94557919bc2940961d9d8931818b9abfe54cab51e40ccb318ba77922ebf18c2ca229b044d9df881b8913ae4f6dc53c7a4b2e2780c0c726a043dd723e9a362ee701c1c420a0abd6622e9456f7ce80c08917a643c5625ebada52b2a2d1324500d31e831fbb89f7b27afeb9060eca2981d0455588762ed5f10b9a031d19ca5c4ed645e8e2c6c2b486bf97ab5fc64a52cb31c38077d89124d5e25c6d0a34eaa44744c03cf6b8ce78eeeb74f94e3c4dc1629817822af8a90188593d4eef728dbc97210ee08f1b0f92e870e61d5190e046f8b8986f95d3a44b9c379d0c5e0033b81221e2b6081e2f0edf146a071b05bbacab745c629271966537c4e98c407856eb004747469eaaa885af416b5cb03b2d75f3e949464fc0c0a2ce7f9fa8a61b736517c159bdb64cd894f5b09d7afc0718372e98c64dc07682aefb39b1ab05ace440791c1e7e4674da465badbcab9f48983da6e604e2683d6ff90d57a0b70830c5062f4c24cbdb7208ee7dae51b7e360fdea7c83a4f2e55a82cc7e619c989692724ff8f599ddada19d2afe5cc5a3d46632e2dd57a9baca44f0a085c0c968e09931de2ce805fcd622ba4bb39d8a2b4af0b8d99fe327c11c97cddb2a281af789695be4ae58bc1a26613793fdb4bcabe161ce3ec21d7b4bb69df26b5abadeecc706f844a853eec7775bba5234ceb768de58bdad6e3ffc945d1455bb7a9bd3762de7e68c4c4be01d2bd8e285f969e723baa7187f5f10deb1a715ef5082e9185ad4a27a63e7d6b4c30aa65db472e179c7b6b7484fecba1f7e37cd7c122787c8931ec38b9fab62d276dadb5bf450e669f4167ebe1ed60297bd892361def337b8f6129dc33c3dce8ac9b788fad97472cc51cd7b530e6db981696713953687e041d7ce6b76118ddd77ea1976fd16385031769eb0c0accda7ffd225d6d7cff7f9d1b76bde9562b1d958e340b9f411b62c4c1e8da91332036ec4cffb21dd2c04eb7dea59c1ba9a6dc6be6d989073329d2ad0b5a1720e60dc51c33b2007e44dc7ce4fd8bd1f727f5ac481c29f1dcceb297a6a6f86775307addfc339ecdbc5910334c7b7a9903c3dce3fb2b74eb9b99f6e756a1a705a6f49d035803b4febffeaa462d5cb0ccdfb82bda54b544422e7edb20e634f8577bbdb7f927bdf5cdc6ec4fdfb4eeadaa77f02a7f1f084ae29dc85eaef8298782b9e5f6b2f42a1e8c039f44a2f7c5aa468f07af2c2331c1f7613cd641fce0ec14b979dd7fc40036f7eda718bc7139bf22f9eda94074abefb16199868c6139c9605e1694fec69053bdd4fbb1117ff74706ff6d0636f26e0c06871da76e23c1dbe90aa659ffb041614e875d8c313feb0f51add30d81035ad67f7468b7cf7c9727a32bde69193787cb3e7b6153f47681e4fb89d6bfaa803ebc974d1270172c8659a21a4293c3fff492c3ef014c53c50bfcc9d8afc90037be1eba08bf6954f10b8f06ddca184c64bdec2d901e7684f4da52dd3179c69ea726e7ca3fb132af0030ed31a9e4f9a073d8131075a3bfa69113a503ee20d59fc76342fba76549b6f8ebb9e9521497cbcb34e0b81a77cebe164ffb7fcf1dfa9be6e3396a8d46a7e164de477faca660c4817957fd90804509e9b9fdadebd9c3987a840b85b18801827ecb22d05e341b1abf327a739e64f9caea7de54c92d6ec12fe3ae873c24e0df1cbc9cafd7cbefce995bba55934eacce03f2a7b03424a60e81d4fc3df18c2cfe3f3f4e12912abfc06287ae3a75fb181d650de2d562d5a5afae34c888114b7ab752ed4cce1e98891e9dc599aeac8891b09a2580f76c0f1cf2d310a09c7a7c2f4474bfad4afe72205f1d1477a36ee943f45c671704293ed07cd7f68748d03e8468d5948f74aa21195d357ae8f39c0afa17a57c276d77de12b07565e8e294d4269a1284d2aa0763a4236128084141c1f1cd944f74548ce04f9184347bdeafc635a700bc6d6258320feab155e4e1bc4b51292d7576b52aa81fea50703cdbc8ae94a0a65880ff8a0a851704d153a1e658fac0960260a89c5a15184cabb832991b7a7876e3e5b2a3ff40a2e575285fad0251983ed324a5cb01759c22d1b42e66a23cf6fafc2cb252b3f5a84b85c90b086b6c1c44b7ad91448155e505c18181decdcb89f9deb795a2b3468927784aa830f19269a7b388b978ddf7b9abbc661bcc2b40ee7b798697d1b9fef3db5d6d3d9da3071b44f1fe421f3adb013bef9ea818b8aec0567b51f2380d2ec1bcade7273bd5130941caa4131892941f001c9d8964b664a15123b981ac0fcafc40aa1d2d21cb1eeb8758ad0d1d0721dc99d44cf11e34e4fe0169f62094fa7f3876f1df652f69e0817fa68f904f0700f6dcbcb268dbee905e45a5dc27715db4aa51bd39239214d71b95df96c378685d725e78c66662d63f23d6adade0d52440d41c1432c1c3b4e89227be50f75f8ea2816da8d4aff23b41b3c91a6d55e65608e369e39cd52bb63e1e67b74da71a8c30be7391b325cf143cc4824228a4312ed3a8f936e051d973fb7ed066e25105468e7f81e4e1a279213fd16deda047d2f35c7f336b4c818b53f4da1824516a8c47d8de197843211d8a0ac2ec444c5dcdf5692d4792b26433c3db7b9b3315de62fde48886cebd05fae864cbf83f47b7349714a039da9d0ef498c26998348b5e00d29cd1059b058d1fecb4fbd5f5367ac8b3f0a2687ec61ccdc4d25200955e4e23277ed8bdbc4e740d3275e3785da5ab89cb59fd6d59419f5ff27a6c8e713a069f1592e4b86a6be7bd2fe86ce5d5214e5cb65da1bc2f9f36dd4ec3ef8e940e729493c9634fc6b1f601593f2d0fdb20fb4eedc5f287a20356c95662c3decc917f9fcc190e1022f7b56bdc2b4d5dd770d8c10a935f2b0c740503e8b6492a358ecc07d398781cc031a91fb6dcd0f1f2288a35ff49f5c0f7b894f53cc89ebdb7b47293d452eab6690389751f8f48ae4b662817a5f1ccc24f32f43907524f897c0ea50a27475f8fbe8c005fa00e84cc1c716d7568b039a9686887420192ac1a6d8106dc77b9446de6ddbd8ebccec6b97a733aaa9b520e0a345e7e4750d81fda6014e6d5918c9da8925973f9a5ad9234d54eccae91e048b74f8ddc7d4db6e1723b4e1a49310970df14955f31b7c8d6da75d25adbd1fba7497003a0f6316f8d325c18b23194767220dd2a6be46c52aba8c70d492917e329cdc2c8cea8fa59913a2cb86cc0d5b96642d20e375909a65471d3f75a16845e83a4a7a6ac1bc781115d30732f5b340b312fb2d2dcda6c2007fa25aea1e09281c69739dde03a2f814807e3bac577d4a3c83900b9667ae25cd83fd43522162d68f0b92e79677023531176987d0f58c2ceb9eac0e206d2ea8cae14a9b873aab02b450513026c1143ae8de43f4e79a135133e99b9650a37bf3a235854fa52ca44c9e0695ac749b286a075d8b2e07cc5b13058bddd91512d4bfaab850c97710e6d33252a714c99888a358ab91d2326d3689f4a44a68352da9341d27a30d085c30d25efd51b5e51b85999b0a7c20122885eed8234142f7740e4c0deca61ccf6c81db65a4b3dd8d603ab7072f1f83b0736f987e54957c9fd0ee0ffa7313c47084cc9b0f575f4fe607aecc08f6987c02d3bcd3346b380da419a54f6eb08fa6c1800970a440219c00bd7db34a9c41cb693f65a8353c607d45944a05473aaea46b24fc58259588568e8eb6b99b89230957c21ad2fe6f6884f60b37ccb221771e856bcd125da342f28b35f7efa0ef3e6c874cdc5d839f63e8ee5c1b41f07ad2ee3b1634bcb6090147d12f85b5f8a6987eba200c29b85c9bac25777c5cb8978dcae30fe237ecd2258d0d8a0ca62ff082fe6416f2ddc42e09fca945a9068459ff18f3e7529351cd6d5c2e5ca27a2e4d4b39a52c5ac24996e65652fcffb271071525bb4b1d7346578c561cc8ecf707f409d3f22a376875fbb85328f8ca4b6705312708f7c519f254a45f554d69c922c870160c3e181030f5be1951b35968bf5d1708a914a9fb8c5522c82d119c20faad8bc3c13d7934265a1482962578bdfc8408dfa3a53789082e19b420a6a5234ed6d34852e674a5365578eaec72f8252d84c100c086ef0c6c2291e6602ab840c81ae7b6d7bbfd9feebc741eeb4887d9f6dfea2f3be9b35e15b2cf0cae5166a366eaa4ad7053087b9629032e2679114aad403bf51d89fb106e76b88754c6c423f3ef5630b04d6b9cadab93d500d8c74ab9eb17afd9199def0affecf8a72296d8d19bded4d4441080a61c27faf6987a4d5cd1833e5d9acf6778990cd299fa24550176e446ba80d71ee9fabc1b569a1f8cb3b69206ba96374c400b50ca15c03bfabbdd895e5ab31b2d97baa48e18670828012cd3edca049b15e16a6436e20093487c1dc34789f2816f5d3ac8b68318339a8b02745bf707df177ad041bdf7495811531d0d49763b2721c991b58a38cd12c265c82e8c3ee91931e52fa3af16418a233f2c388ea3cffaa69eb9647a7672aea87133445c70796c2a5656c725d21959a746452d3b6019e2f22b0c03e0a92b61c6d9c351c98b638d12ee8234a1b52acf545870d3124b9c3dea6f2b3589930ceb6bd6cb9006326fdb032bd457a52fa3d4c3529a08c2668d14d1496efbf0d4631ac2bae1698c370cb68d42093ddbf8cca03325140c346fd98f4b01cc352287aa1bcf8fe15502740f470712df6578488edf163483e7bda6339a8b6094ea3dea193201341d1aba1f786bb53668d834664d8d48fba49da1c44d34f260b9942ea20c6051738001855e4f3f4f7eabe8566da431252d3c2a3f585928aba3c842e6f57fbfe88d6c1176f2ddb8e14b39a2e52ad5c156bfd58b8fd08d98c2dc28fd91d3afa6dd3b9cdd0a5ecb7055e61c03b2fa26ec4d79d111dba41888e8d3ecc6eebc25c11a6a7e831df4deb615119a232e824142051842d4b60c210e5b5924d93c79a8ee5a13b64189328473a71615845f5a87e346516f4783d3b293e0d3d3d4fb3d70bc230afd74384cd1ae5d97cd2c2a464e63f9488aed918d1f1e1f66590e69553b14ef5a2d1cbf41e4314b625bfb40d1734575289332bf54a1a2fbfe69301ca4c20dcd39e8cd0b31e806eb534237a5f6b85b6f29520de6e55a200a8ff0842db5d3994f82a16c42312fd47d857c758e4d87d9e5f2665009843a9f4aaec85909cf262341d4a9a02599ae95a011d362714639fb6afa649739a477a746589a1e6af90ba2f4d4e888a76adfb4452501d23b89949d7a419955b2a9ace9da5e9f760634a940aea627f5bc4a054ed7a38ea91f449598ca1caef7bce4310df3dd1ce92ab8f4d6ca1953e064eb9f843acc876369013df10a5e2695cc597ddb403b09b818ae582d536f73cdf188e76a415acd0b56af575648a3b2478cd2c142da2bf8ec8ee118ca8e76bf762c4607c759c4dab6a41aecc21080f1eb1df8f75979cbaed903430c8bc21d1b4e04cdae978846d2faf4f2412813233124dd02843807f0bd312f483105974484aa33dcf78efa6a01a1ccd146cfa5a8ee86c572f5bf03080e92dc860c0c9163e1592168c2f2449a954ed40e02993495b866a74f3c42dea7f18bff5488ec8bff9d62dfa1fff6ebf84d3ead3f7d25d8f97b7d23cd3fba751848770aefd9f1e3ccc0340e3d78ddcd60081cc889d2c87868a95e486f41c5eeac8fe869d8e8020ba9e418c343f1044335d7f00f54c16043d0924c3654e4bab440bdacd3f03da19dcfb5871e6a3302ea8e652c5cd1aa290704f05be76d9f80516a61d6cf526590d1c0c6bc63692ff5b3953c1f98667174229734c324a9a5a11a540688736ca9f82f623f5b80c18d5040e8ec81e0177ec838ea2b2c9e94711f59f282bea8994a71a3d488965802b3225120642881b823fbaf8dffff2f3f31ca0837577177b2293199df9fc9f0627ecb5679a378779b525d2929693efc3a2cd5364a19b95402ce216188e6716c40676b108e4bedcc3d85f22237c488d1658e094929830f718ddc674c3a1953483981c90f3fe04172327e163ce39c037ed01d17a377e7919bbf56e9c77d65855916691332f5fb99860eac7115bf394aafc2e8fcd308a0bfe5a69ddfa9a35a363713b155f257d32b585913cca2a5de76a01be6d7020afe8c2985a17963a13f47aeb25e5e4e6b049cd3720c66ba1a76474130bd7170f8830c86836fd26fc422dec04df3841e287fdab87b84598ab223e2bfc24a44ea6a9696ae39e2034421e6002fef3e9fa652c5c7ab221da74703ed9e805048370ad1399342e7f92c95c274e8adabaedc995755352930266cdc079846837f29cf2cc044f8ec8d5cf1650f7083344b04a6288398d2e079903cbe7d013dc77da7e17db4f6c8c558577662048edb5f7451d33737191b6f0bf153a8f854c70264d2e5ea449945ed878a042e5f50b13c145b9ae7c48991d492295ab4d71b1b4a24a142522d30d0c5d41250945dd5a3627554950aaf9f5cd53aabc753e6ec4d354b3ff45f2cabd4fb8d5a6b4c39752c9f853e68d1395afabb065b6230808c369cada1cb4a766a2bc4760c2a40072f356ebe4e51c6c12b4b2088f9680a2addc66483c8bf0a18c91276edaabc89f8bab983a5947c2c3132dd63015160c3eacabc0455cefdd50589a1983f86a1e9267be6e67b17410cadb5889d9912420ab402159ccf2ab95d981fc343b8a7865a24255746e628631349f60cbcf56678b7da37333f4f4f9206efc841bc70ae38f8d0309e13f9ab71d9fe11dbf97427bca22c1c6d1ad4e1b58759b07265d5df96e470afe3b1278a0c049eeb5682f610b52cb1d301d4a126df34f157fca8a90c36940ac7ebe4d2cc06ad30c9a829a14a7bc33e41fde3328e5b6c539ac0e62f650008c967088714bc5eff93863e2540947061c3a1e8ca2cf2bfbeb9996fd8a2aa5c8453b6b7e216760510fcce0de6bc42408484a9e7fc4088609a774029ef3fa3e2670e640e8d46f0457c07a12118a7cfc54299b0ba8f45bae611e59563cc84ce9e5aa0f5ae48e941414b77022f1b5c2f35c332081aa432760d2f5c11820badf2a29fe2ba7a11426380f12c725340edd3397c037a6d7c34c2e14bb13f8ee9237aaf84b2ce7152e87fd53cabeb8900eecb4984e3c53d3b78701f6a12e491d52d011b88150a724a09d1b054b650c3aac0c3c27125d974891a6314fb74d5d95963925d2ef190c518ed5b81c5a4ca80cf9ce3806eb3e0865f4468ef20375d57155b45ca620de157bfe3ad5a6c8d8fcdb4a07cb9dee02cc55aab5d7815189934cca43226d4c42ba847f642897ae628db2828fa64ec02d0cafc76a1a317091112495c403b4ab3212300cd60ebd6ce00e68ea949c98d6af3958cb014aabc0c54a754295171940b2eb2348788257715c234398bb23aab2af109bffc23897293097e46c6fa4917d462ab5689af168558bc7009595c964f1c6e650ad452f812b0d6447ace530715c548fa47a92db4d9ac8211e684c46c27ae7cf1d0b7278d5fafd589ac443be54390c699ecf3b065d79f1897363bc787cd7b237d2311e48e16cf37448ff356052e2657bb98e3175d06959ab50d9a7b2c9fbe497d24caddc3319690aee03ddb15428d8f0285825f20a41a78fcf26f041ebcdfd0bca39bb484c812e4e7b527e607fefadfd8d6355dca81ec761450d4530ff201399d1b4149b35cfcc23b4fb37d43924479856311850ce48ab0a17f50f18a53084e1967baa860f0f77a7d07933e8c89e24a55900554586cddede1077e4182637bd904abf99bbcd7ad4ae09d1dcb3d78a2772e93149b0c85b464e2e1194c1f059bcc98e3dac5ab705c9ea7aa6d06a58ce6877038e4431e5703a5b784db5d2b4ce97d84867fd4be3c3967de19c3bf5117cdda8a7b1ecd0ebe94ae2778d57c545ce9bee9e48c896c4c815a5678186a016e8d16ca4ba990b3549a9a404472dc98ea13f07381ecc2bfcba90b4152152a5e8e487397bc352cba7825ae28a684d66039bd53a289dbeec4685a5458223263695896ad377972113a3505ca33e4f7c20862572627ed8dcc9a456f48b6e520b04eeb5bae2b15cd8f1662c7f97d5189def343ba281af007bb13fe8ccb5c8ed63e40609198388709014bdc902051d995fe99056b7c19ca4bcacff920ee977998ffef4c1835654bc832169d0b33ab8d0f8201fdd5ef42e8f60cf16ae1978565fa1bf0bf85bf18c45a8c99dc23ae140662799f242f73da05594c2ebedeffe524a3f67f33a3297d86fea2ef8f461618e2f410e2f27eebf3e44c8a23b23a6945c90fe17b4098492ae8f4816a45025821abab08a91b11be6621315e8f511e662290fabc8eb66b39244f676e55d568be2bfdbb3bf647b8d7dda6525be5a5c108c1f4d3ddb3fda255c28c368f0c4aed479010641ccb8300ff8897414e7139e026534b27637d6e75ce6fa6e5c51b353d779e6fc41e5b8864687c28773dbe6348f0a465dc9bad950c76b64cff1f267c748aa4d0d6b281a9174b41f2a41b52264ae2336d3ed6c5e77c4a3a6984752f31280135011ce5dc9a6d4fb1d0486acddd8ee565d9fff27b405278c14de81f95da454715857a4b97b94083ebecbca3586fbe08f258ae905c2193309b3e81dd6c574211cc78a70a68304b49ef300e571b2a3c085bd2034653bc76fd3a6768e4eb50a2a64600501e8ba568212b6c0b2eb423d5d07a5b5ecaa6570881b731c4c3d4a4ee3a9cf20a313276a8eed4c7ac9a84a898184ddec6b2081a75c277bb15480668c0a6847bcf043fd0c24ac02d11e6f207bfd9482a40f65e7a397a800f64eb166abecda30ad4fc6fa0c75069aa537e868b1c09823a9b8cef7f5ab7e0dd87779003f8dd2e85eb32f1e4e8e771daa7c4b0d6ff0eef4ac58074b4d18d653d301ba7906a7bf1a4af0bf113cc119ecd948d702de985cbba0c4c701c83a4d2808b202f5eb6e529c16c14c877e645a62bd43cbfae989ade73e7a35a91123d12ecffcafff8a0c8632aa19d99a10185d6d076d6e15e298eb58d8a8e04b67e34a1e8379c3b95e9b248a368e011a05ec8cf89cc7bf7e10a89b28b4f4b64e29d080d8a58d4779f0b48ad2049d91555277f1ad53d5eedee020f37e6480e1ebd5751ff2ce004ed8ae64c82c5562f5a731ab72ffa0c30b7b56b96a4bf997406a94a4d03167882be1a9a2da2a8091c5859c96fba3b641a4f770c39f1835544e04e2af16667d3d5d64aed4bd5be0c7e2a8b04727efcfb92b755d27d2a30c3f8ecdbdcf75636ca28505b582581e39c953b35cfada2c568c41893f580077c8c784f6eb4f19dee35fd317a7cbfaa57df879d20a9f43d3a15af78823205ca6853a5e5315d593e1159e10f0b2aa1b5529a0e7c1aa1624054291545458cc2abcafbbc9f0d7e138129acc201516a4ed5efe042a8ab6344abd3f7077f3c971f8da19c7b7970508052b0199c8efda65401bc419e8fb252fc78b632dd6e84571a13ed5e30406f2a13f0eae74f589c91b084ad31e6c6e59503f22c5a833346f9e0364bd97f6507fbc15e5a4ff3e5e7f725238fea5cb5e8cf50cee3599aacbca78f5c5660c79ec48abd2bce284b4c221e991827f6363a921acd9120a233fb9720899653337b0b725f12597f3f3831c7012016f67e01565bdf1bb31a93e93d85b4bdf1287bb8422ae31295a12973ade8b5aeccfcc8eb9d0e342e0c638b7d9ffe4adfb3ef5ae89b9590dbe786e6464e50818795d411710d0c4bcf7e649e51e35af3a7d6fe093191e776d75eff14c1745ad09e267ea1c919760edb52891db78abeb97a87164f703dedbf25d9bb2bb138767cb7d4c416cb1c284dce9e54022ac6460137d72ad6deb6581e936fe24aeeba7b160f342a3fcd9d65fa729e1beaa2832adabb7151dd554081054d990950915b56bcddbc07bbd75da50e08d20990c38a2cae5c68e94beb774599bf6efb5cdd24e85017f633904e41ce204cb13b386d70bf568cc650041c5c7c5b1a68135661bbe706505d04df00fbc51ff5b2e6770b9a221bc2058b39bb5e7e9d857f0ab7f5a1e9c9bf04ec00ca484b0761a61552372115832d4f06c3addfda2af737a0a71f725ba73f0b70f5e6765386cc88c9ea1c823ac9cd8fdbb4c4088136e3b06e2793a6a6f35a297934b82e682f05589fb64cc99ee21db4ee90cdce3af2bb241fc14bede9165ad9324aa545d51ec6b66e1c45924a54b746e676a463ed16d338093c91fa754fd694b1ae3511eb776457adb2e28b1499ddbe170b34fb5c6e6ce180daad90ab100df15dcdb3c15b679f46e69086b39860700a0a199500968bfdf95861b8b2b2936664b84404ba51294ba1e2ec9c83ea4344678bc976d50d6fd4d6de9c3c8e09e047e2e5e515dda50e01c00f3f5acec3fa939e3dd2c991a495e094b003f478b78722b01bb74fda9b5cde745e34ba37d9e14e2e6c68f5728ec1711372912a3c926ea6e695dff990d3a1c63d391a80ad0caf9b0d1f3237801b67e22b92c3325f0f55868fcc206cd7f0fea8ea0599a2c5bf5653659c537270957e47fc75922dfb61d02e70780d24aa49fce41f2b6382002a2df2c849e40ea40472005ea03cdf70afdd3af2e82949ed2071e4491d3948b8ab9adf5914e23772ad57d0a783949c43dcf59d408b875b823dda8124cd94b625fe62fb8a37316d8a71ef1e8cd4338c69dd1316e921785226d9546cd529ae38fcaaddbc1e4b9ba4ec87a2a19eab2df00b71d1db4b8743b86d1bb540be10de12197ab2e197bc6e076af99d8500f4c8748d6b27c473f91dee208ff3536808edc49941cfb2b080b58da03aa9342a25f1a5ea4cf67af09f768e3f7cf0ab08306dc1efcc781e82d77dfc161055c51601610770fcdf2e921c249a79b9695e8ec30221bc5030f5aaf097062c47dc3324557dd8cab1ebd60d112182844c4dbc59c4a8ea60a814cf9e4a483e867022b993cc813e51a4a6a4dfd99ff63a5a969593480b7f8702c39b876bf0a65d5b5c162b91fce994dafe187cbf6539697fa770c79110491dba03dcd2fda84f2864268dee3a098e13415e1cfba71cc3f5135a3c62301123393686bee45c5fd582fd780dfe60052870e62a6d942ff1eee33d4cf79e1288df8f3c3d374b7c7bf52e124335a83971757d182bce671914111886394eca3c7471a1c8fcfef7f624b35be8ddcd2d6a7492ee772b705358a5a6d128177ca484bbb97add08c7e98cae1a01e48fb995a0cdc26e98e6e12a44260f4b8f6821c217028aee7c82d0769f8e5030de5e13826c648a2d10c71718de1790cf1de843478637568766b49dfed514e6ecc50a4a11a9fcd6eca1445ecf5f76a7f4b4313ed052b17ce8e368bce434d095d5262a670826160cf322a344094bbb247a843d229e724728510d1cef92be6211b191c1ec85b57c5c634af531a187cf7a28078014f0045a04e94b6a23415d10487be6844b038c3516cb5bc81d7c0ebf94d037973b7990d25d8b11e081db70e9bebf240c82381d6e7d21dd72169fa925de13126994417dec31ea333874f4f6016f57903e69e7565a8c29626247cd24c61586c5d6a3b89b01dea61d35c44e1f22a3b036e1ccc0aae7eb029a4dc76aa2b474feb7e901db58a9c3481095ef6f16c1c20704ace0f34f4f8500843228245c559cb0ce0c3aca3e0ce32ba70c136cac1532a87b3e0b4b3daa8f293a88a007c386b03e4ee96867b7bf418e8fc06c21a6df810aa4390f32893e04cee17dd1e8cd8b359b1702ec8e04caa5c4d920bda35fe8891cf36a01a87a9479d575be247b9491b4f2b510ce37f133f3c15e848abd08b151d25c34e5962d4d391a84d9adf384723c9f2b90ac5ec53adc7d0d599f7a33a62ed942ccbb369ae172942a99932afa24df819486c36ba883b5eac9f3753d9bae25f27fff138d918c59d6a7084d94d6525bac1a6369639207c2e01f0abd09cdbc435bcab512039b096ba104455bde50a70289d03297ee470e1c3c426b0d79ce66da2535dd231d098a3e2ccb21b71bc8ab7a37b0be721b913b9eb3879db8e9989df69670b2ca16984ed845b1f429e14ebbd9ebb7e8a9f912eaa749c86ee125fddb5c6830ba4f48f3304925c52a2adc2f25245ef806810dc86e48498d1d0b20e86bdd8e85b680e9284d441059e31448a0c57405c15251d9b0b6584ddcb9b9f40dc2c5270be1dc0b582a4e24beee834f6cd45e15dcfe741b8bac00e033a9d5c9c073d52bb62797e1bd6281bb725adae948d83c3a0b837f88ffe2ffaedff8d10b2c926646f42f6967207820cdf0c3a0cf0ef97f531d9d1b4a3791cf8779c5105ff1e040c62fa75238a503c4570a6bff7ec8ff76797c0fe3e5924de0ccfddacefbc1b959813ce64798a6c399896c03e1d52bf26ebfa00d3d2b7f4c1412c1ba90f418489c8481e4e7f38f0ed6e1e1ba15ab26152b13f99eeb03ed2b151af76c039e7bc5bcf68872d51af2a08218410ce396789a2aadbadb2d0babe4e0656a10b4daecc754ab018c39d1918c0703729df7b520937e268275c8cf779450ab487857d5668d2bb01b4d0f8c9b3b4274fee73e2bebbf760305c78c9a4e28683761e8f06eb1e35862082b6f2118f958f34edcdbcd77363372d7b7fce9652d336518addfa9f635aa6f165aafda365d946bad70e75ed26f20005d1307b7294799aa6699a628c71b4e33d3eda52fcdb44a2e92ed3344d524a598a7f8e7267f7a90cae09163f261a3c11c164674327e7b7cfd1f9edebdddbd9d0c989b9cc7374622ef317367472600e80e7e8c01c0087719d9c97939ea3f372d20370f7c9d9d0c971b9009ea3e372017ce6ee94b3a19333ba0ecfd1195d870fe0eed1d9d0c96939019ea3d372023c864e0ecb699ea3c3729acbb87be56ce8e4883ee3393aa2cf7801ee6e391b3a392bdfe1393a2bdfe106b0a193a3721acfd151398d1fe0ee97b3a193137a8de7e8845ee33536747240b7f11c1dd06d1c0177c79c0d9d9c9427e0393a294fc06fd8d0c941f9029ea383f2055c013a399fdb3c47e7739bf370f78fb3a193a3fde6393ada6f7eef8ee26ce8e4646fc07374b237e00cb87b8ab3a19383bd87e7e860efe138ee0e72367472e87d788e0ebd0fcf71f790b3a19373dd01cfd1b9ee80ebb8bb8ab3a19333ff80e7e8cc3fe03beebee26ce8e45887c07374ac43e03fe8e454e7f11c9dea3c0ec4dd599c0d9d1c79093c47475e028fc0dd5b9c0d9d9c789ce7e8c4e37c02771f391b3a39d483788e0ef5204e019d9ce9423c4767ba10afc0dd5f9c0d9d1c78229ea3034fc487b83b8cb3a193f35ec47374de8bb805ee1ee36ce8e4f431f01c9d3e067e81bb1c239e81e7dcc5e0eb1891016b83812f5cfe0578b8fc22bc70f91658c0e5133184022e5f082c2ebf024170e1f22970e3f271aa73312660e3f225509d8b1181ea5c0c1ed5b9184054e76240a0fe5073f90fc0c2e5efa071f90ed07180cbf7a1f27354e762f4507118e0f21b4085cb67c08ccbbf99c2e55f1b1e162085cb57808ccb4f40142eff06012edf06142e1f0135945c7e4de5d378c2e51f600097bf83010470f9339c70f905a04972f93208d084cb8f1180cbd7c18acb1f00002e5f00d5b91833302e9f549d8b1180ea5c0c00543e8c174bb8fc17f672adcec5784c6d17830f539f8bc17fa9d0c5e0bbd4a9522e06bfa5461783cf22aa958bc15fa9968bc157a9d3c5e087ea55a98bc14fa9988bc147a9998bc1ff68f5e362a0a4d00aba6a685615abae5455242b4bac2d541d4dd505d69757615c0c7ed71817836fe4f26522d75dc70524b76fdfa63bfa760f06f81aa2640b503860663742bbd3f9ce3516307b195f47b3f0dee69618f19e65f1a8de4322e9370dc36ab5aaaaaa41e25d7f4f7333ef9b0ef7598babe639e7ecb956ddae5d691d52efb9b236163752366f82f6620e32550129abbd4841dbb4bb3926463c1ef490da6d870bbf44bb5b3bb994d27faa56b3da4cbac6e6cdc0d3c320874ff00d8a830eb911c417420835b7438d04e8702133ad1e55550e7097b2d7ad3ad2ade74a1f515cec4ceb46dd9a3df79af1565c72a3bd9a449db24166c712b81ae866a64b09eff442449b1e74179e456e86274ac10d521cf1d72545c147841f5399734025ab3a511c1643b6183ecbb29ec35deb3db7aadbaf1155bca35cf55c864fb00c88c58597e83e2170a1053838d83458b000b73efc0e09b8b4a631af8326723390929ae4ac8a45a026318d9e26b9252ca8aaea49596181a228263f7efc20810228036cf0f61694525ef2e3c70f14dcbc69a25890523e76337cad95400869402674b7836f8210ba466143df08e9ee1bbd0466e625cc39df162f7f8b130bef319c3e31333384ccd3bbaf86e6c78f1f22b0e181be900fe16b29504ab2c0c5754ab0c0c5ddb2fb3e80eb946001c9bd6e82f05e3787e74e87bc4d96ef74df1d7c772e01407e13bfc10544cb843c5f770057802de265937a380b6ad2912619a982b6818e78f25511f52446816ff0758f499a865b72b9421bee7de7e43a1b9589e09c1ce973f70da0060d3af7d784e1a5356486fcb89fd838242da0dee4ba707072933bbfc1b91438e79c9b40aeb198267745189d83939b9c9b1c1a20cd856f7aefd07dbbde5dde7b50c67f40c628ad7bf08580cac08d7775ab0f3a474dd334f5a893538183d3e426e7603ff15e2741fb46e3d232cc7cf5f6fe450a82a32808a769821042072737591d7865a301baa9b2ac673deb3de8a083ce49e8de7bee35e1efbdf73e2e46bf7a35e9d51cce5597215700b2c375b7c1f7d264fa06d3aaafde2b5b72af3e39e363f0d3a9779bf7a4ab3ec9ecd7d67fe75759756f46627583fdaaf66995f5aa942db96f3d8eb8aeeab7e448361d6f21c99d0eb770e44e7f525cfe34f5eb77d76f0262faebe94cb9535b0f6d1d15de39ea7dc2716f06deb925ba07f68f3b7dbac8c151a1f290122b38b9f32a5ddc0981500142abf3afc6bffca8fef283ab07de95fc694b7cf996ea95dd42f7c0bba595c7ea53d39ca4b487927677276b2c557bac7cc52574cc672c949eaf51fa66ac1b12b744ef6e123d3763518265565aca28d367771765d4c32d597777db7997efc52cfaccea16e3afa7f427c56e71d341e2c7c5727a62123d77ba6367c1463ae6a3f6684bd9a9129a769b37afd5275bdb70f8c7b53eeb66c47596bb562f4bb31bffb06ed3978c58ca67dd2e7a5aeb30112d8fa7b779292828b7e999d9e9f15d146aa73b8a92833e2ba1580fc01b3f47d847299f8f47b95547d8adc7a9a3c3eaa0cf3cf06eb43a342037da12df7dc59e8f52f9c7bdda8febea59e54d77a83c44044bed4b4547486553e26e3b8f863e1fbae2ca634aac30e4f2e32710a1cbb654ddac1bdf39aa382d6779ac9aa57356cd6a382c9add7ad8b13cbab35801c8e52b54676812d172f7662287aabbb356af2aac29112d76e66192bac441e3780bc79644cfc5ce9ff4292db5e7bc3624eeccdef28973ba5937256e4c89f351c7bcf1da33fa99d588d5f8ac629bf62d3bfdac232d1b6516a725746d941d7bca631da1fcf3f819aa204a67053d5427684ead6ebc65948ea8c569015dfbe7f433a55e07d51450bd522e1dbe281667f491f696b37cd32c4ecb594695e5594b65798c1fd5963b8a63b71e969d7769ddf86205d8e11b3f6b8f77a3f5405f1738687cf712028d9f137f5999fb07a8595e30a77b13d6e9ae42bb49ed3acdc7e5f7b6a21cfc76877593443cdb3d6f896e7682a4a6699244444b4dd12a71dfcc43e271145e158e009151bf1032ebc898e31f0522badbaf690f73ba20d5d1b04f59aaeae0f7447be84d3a8a23f9cec1450eda7b03f1babb690fefd37d9bb644673df0f9f015561cf95edd341c67e59b71b7e9066246850248052c6ee61c33641dbefd77ea3bf482f5391dfc69b239d17a60035bcfe524a6ef4c77b2494cf7c0e74e3609fe0ebd0c7362f719648a902942e688cc1b6464648a909129a2081919199937c814714d4646464646a60819262654a2d4e79bb2e5c45bea333f899edb9fa199f2d8f259314dc3306c4e55555595defadc41cb7a9665536555d6b34a8fe970298e96c7f99489a255daad4016aad8ed17866cf551a5448ceef2e9d22e1fedd61c91526ccc8ed5ed5d230c04023d87bba0f7dc941aeb66c48d6cc597c58f268f556a61dd706e555977e168fa439f4f733de106cde5e57fcc61bec10b336756fb2b3594edb83e3f27477784be729b4e49494949e94fbb8d88985fb1dba8ddc5b93837e5d3662b2fc3b0cc883b7de0dbcfead5fdca6489bc566ae87332d591f21596af6444e870431dea508742a4901db1d8ec2b0f7d5aacaa3ed5a7aa6ef350e68b887d3ea7f405bd3ed747b3d84a65dd8dcd8bf401b51fa90ffdd0b37a3dcebab1fcb24350a1b1d895b6a5d15b6ca9be3716db43873bb2ae497fa8deb5854dba7d0c0c4cf7cbcb417f61f9647969398ba8e52c2f2d2296378b8b8b8b0b0b0b0b0b0b8b1bb4f8eec9d7a33d408af32e10afacd8952cbb40375b32e4b2bc552eaa9b0e17e7b6a09c8574594e9291f9657171b92c292ca0db2b2c2cef5eb1a1a784588ec272d735f6a1bbae61b19bf696bbb754ea5add7ae8a0524d9089b07ff1f9827a313afdb4d3ca8a5dc9b295ad870e239bf78974078efd8bdbf47cd12f8e52b7ebd24f5bff669802d1a14f9defb29fdbf47ccf65a9db2fcbbbaab45414515db9a3cd524317d59edb2ba1ab846ef3b47f6af61494bad5b8f487ce74c0d1c1128126a3a2f7477a52d2b8cc8adeff4824dad0066d70f0a2f97cb22c849265343499dd785ced9a4d7c05df6840154e730d98ba7fbc9afe215d0cf9ac8a9a245f5550d5ead524d933f2f00de01b950e57ca59c554a94f9926413e4d565dad55de48f956a6478d0b738cee4089c2094e5c984ff91a03f3179769523706637568127c65e9702f7a6082b6f58f66a269fce8261a48d308222bd9241e2faa7b79b9cd7ba99fbbd42d665437514bdd3496aac3a2aac32b7583f02a55876f4addaca354ad49f09f7ab9c02a4668c1bb69f6d94d4eadaff6acaaaaaaaa9899b96299173000f0ed01880f40054085515f54995af1b83d68aef58dc765773396cc56ba8841dbfac7ed1e5c7848baf0ce773d8a8367e5fbeb73af3b57f3e25b75afb3ab81f1ebced9b07e1dc68b1a2f53630f21f50cae7431228e8bc4515a7869ae2523232323737e21f3c2aaacb4b63ad94660ba003098dda02db48692493077e0b6635d2677e0ddb13f3c5b9a4a3f949e183476e289eb16973004c9020e77f2c8850bae6664790a9730f0a0c925d3f582046dabf180ae31e2c93f99cda58611af86ab601f584a0cf75d76a1044f8f1ea41bef22aff8caa55d9a04ca427357da57a56aa23f843edf450f9b86d456ae889508d204cbb84a04694264bbe02073bafce532c8cbb36f6c248817179797b355573eadcb0aaf109ee2d5b8b85828685097563e5ec60b3982b6711026e2e52ef631e71b86a249ef3232ce5197ced160b9e48265bc4b79171929c352f98abf3317a0ab5876824e3117f73d17e33db3427379761ed234a47c37122312816a806ac857f2b138777d3e1f27ff612371076573e06374974b215cce5344da91dd8eb8526a9f4c23006f69a483722e9507e62391ddc14f82872bcfd37313731f3196df377ce303e63e6efa06e6361d8197c35895694b2ce45aa2abdca6276559ca2b458e8a4497f70a71a8e25adf7aae9c2e519517527959b56b491a8197cb1aef6427ab3ae25357a9d665dda49ce7af94445ff9342fc7b8893ecf627be05be5958fea5021e2e5b18aec26e3eb262f956abda9e853aafc454a7e5ee63c6a3abb2ba2ac438a634abbf3ae35af95b931a5c44b0dd5d06d5e751db4812e4adde4a76e4fcbea06ba1ec8a5654a29a7dcf85a2ed2aa0ce1cb0fadb401f85f8784872b1f5d5c5c5c5c2e6d0e40e063f4256e1ce5e11277a0a412e09b963b9a832f744b2caf749d421b8152b20b24103438f9015282246e08013f794d0461204d3240193477b3319046f918c0d5a0d81dee33efe626175844cb394682464e48bc1a0bb899f6618b30dcfaee0e57c36a8083ab820f4f5c127715fc3dd23719974bab77c59be97f0bede5e821afc6355ff1b40c6379cafc848d3c811042faea2406e26cbc2dc6927d9f752e065fd37ad4a9fd4946a8f7fe57c3407ac602993edfe49057f3e16e620a2a6e9f9d111c4ad0367e42a3d5d0c5d691d5c04fbaf8fcd53013f8095c85db408cc4dc8d9fd827468c3c79d23f1a481aded022e813340b2064a63e9fac539af065fa2bb72f59075d13efbe5d35d1f6a052bac6d5f03b0779351c704eb421bc1cd138e066fafdeeb347b818fdcc0acddd6ca008291fde4cf7abe11df44c7f8a67194712b4cd39e1691a0d91d891a269c47b04121af557c323856c62e53692dbfd265056a2c10d2cc5abe1769775e06a2e20188109b7efdc13dc11386493667541768de580ba4df30ca21df124e6eefd04571363398a9e79bfed2adcf7bad2a0862dea24133349f21e6426a2b7920464a1adde76cb78688236eaa1efb40257fe6e73c4ebc21259274abc99770b0a96f17e7dae549777854a6c5a3314f7bd690f46de4516da95b775a92f4cb87881029349492fe924310f4284490b1191cb75e9243fa4d81cf8f863de1722e63c45fa8f79c395d15346319f1e739b16391bfdf782bc99c7415e0db758cb4144b6e99dbbd13b6019efd927aca1a77017afa681bc9a4eb203bed15c7cd3804cdfc14df29ac99be1826f7415469210e1e2becf5055b151e20887643a51a91c85233d1c9fbfdb387784745d3861226d803268bf119b37c337946019ef9a91fbcee4deadaba87cb71bb8fe53826fb093d17f2f44e4f5eb4747ea1f4036073e5eb4103f4f91172fac7b33d79ac45b8abd9ad436073eec8f63ed2d4f3d098ae4f07051bec48d4dc75bcfee9a26fbd41d91f72cca93e0a1561ebe89f9ffdbbcc9b4871c7ce06f9b0310f888b98f1b4779dcf2f44dcc632acc3f759bae66375026aa1be8aa3a5cab4eacefd42f1269dab4c58337af9f8cba850a2eb2c0e2beeb946471c57dd71dba9a94bb5bc0d5a4d81d14bb1dc8e72ab8dd9beb82a195325a36049e5d8d10a02d7808f5be109a66339bdd78cc6ed96d245c8c3e0f51681b0d8d9452ca438b5dccadaaaa5ffdd11efa4224289c77cf6e3d48773ac65bcc26b2aa0edfda4fa6be46b49646b2d0848af8a369b82c80c1c97da7ba681a2e0b61a8223271df67f6e6af07f1b9ea55aff771aef7a9e5e1e951428823301f5c1227ee0a9c0c9e477b76687140a183de73b3b92e46f018c4dea776047d8c6090fbb4d77833ef079d873ecdf2884036b33c24ccf2f0c837f31eb292da11dc48d7457d183ae83eb4670f02747a6a7d840ebabbd96a10819d86ea085a504d795651988fac0011591e9662c8112980a8a4a000d978c8cadd8de82defb961d9f8085f3b287b0f599e22ec440b591ebee2cd3c90e571c2c349aed09268578438e3da7544fd73fe5547941d4560be1fc447de7acf8d4d8f987061076a6003911f3f6eaea3bc08cee7b3a59847b13c0da4a51872dfe7b70632440a953f209f4f8a131415cba3f2eb9f8f8aed2e3e0f488a2501dfa0d82e5a5844d5bd19edce89a67deb2e427737a1cf53de7383f2ed0111bdcf5304673e749e22382b9fe701c2c38d8ac8f2887e3d642fcb23b29de4cd3c9e3e6249c0372a16f4ad8f80ec887acf4d928cb23c98e8b98940fa8aeca117c101151945e07a769cebd990fb7e1dc1b91eb23c6fc8651f488a944aa1d4f8a95aa5bab8bebd21d725858fcc8e70b063a73c2ecb03a46fb22f717aec7d082e68eee68a2b92dc97591f4bd02745b050042304f9313fed085a1d100804f266de47eee268d97390d9e764522820427531cf37f3ef70c89bc1ec081e0e1905c137d7f9e675f16686d0821de15ca7bf4ea92e7e6caf8bfb4e802ca82e1c139c0882154abe80052c4c71f34e3979353d4f44010c2b38430ace00832eae6fd447d0422454920ba58052bc99f74abe3f4005508a08ea812de281364dd3e47ac67d7bd7dc3051140d081f7b613209c2550057be2ec6fb93c1754f1881920bb31a6f1a130aee7b021349ee7b5063c3e5a16473d0e7205e16a47c4e76ada6494ea7a275e66aaa9cf5180d5202ee86a7e7e69ad3f2f4dccc6f72f2b8b4bf8fa8c7abfa98e7a1bffeeab33ea80f8a43ab26223b16795c96a7e7e6e2312d0fdfc83713795c32c63989d03ee54ec4c98e9dfa91fd7dde650ada06e5a18febd8a7087989ecf473da0d3a24352e258adf6828ea5a95843cd0fa23b345fa98f5412340ed086714c4fcfb94f57aac38f397e58953dd79b12f2193292a46ea32a598dc78c9aa4a1b2b55e3c590d25c2e45511475bdca799cf32edb1c6ebbd3b75dbea06d52c69e18dda4ea883abfaaa5f86dbabbe4f6a9d2d4311f29c577b0937ce1c8ed5352c68a71c8c38b443f9e7ae1c9ed2bf982141700d729f9c28fcb1488ebd16ef397854da2d427aa2dae1de8bfb7cb16da06a7ecd612bd755555655a7bf4e7e7a4eaf6cb4582b6eb52f294cce1d97a72de77de0e378739cc610e1de85bb6247b9076a463b423fe3dd6c01b987bbf107540ea4cb93b5519789560ba3b994dab231dcf662e0667979d0d1d4da6b82cd729c162c99dd97427339f1d673e63ebf238da3f1f45003b7d10980d427b332c01778372591f45a67f3e5f55ecaf5eb7aa76699d56f9597d501c6a797caa0ff76678a0582634eba3880f1fd3dabc19388416b46bd6e5e6966416893703af5923de0c462debf2579dc7ea759bf7aa9eea9cacfd83699f3c98b0b24beb83623eacd36bd547111ccb3a1fd587d082358416e43fdfb4117c2c4dff6dbf3e291a0177c3445bebcf4aedcd6438bafaa8deb7b24b4b3eb35ef55164eaecef38d5fb596579a4f56ee40f20afff81678de229207d438f552648b0801b7a207d833d561ef4549580bba19f6a10ef067b557d6496870912f070731d08dfcc6b7634f18ca6eaa3084e6647d3331fa3c98e22a0dd3a4ef6ea9ae529c2739ddedd58ee667290370387d042cb7172b849f458d53f60ddddf0cdc6412e262cebde6f660f6c2b0553e711b913f7497722391bd89d4ef3b44994e4ba258e89cc1919d1aed37fdad1fbb4a3f7cee38c78339374b5ef9c75e4ea9291e371ce59b3f220bd9909004c34cdc5d011b918fcbe91ae3a67757284d3b7ea08c74abbd5b8ee94945246fb88744f49984ec6c13e8075faee998ef3a6e9d0f2c04fe7e9111fdedd4cf5bd1fc474687dc04f6febc347ff2551fd077e95a708ce7bf66779c0f79e9b26e293e529322d0efcb33c3fde9798ee83e6cdd8d1fcdb8ea6d5a1de9647ebb9e9b9c96c912587cfbed1dcdd64d6a634d2c1f2237803378d0845f84a3bda313faf8f2238d3b3fb18cd51f58777769212ca6992139493a466a5d2ce1e1e79280fe547cee9b3821f5baa268764754ccaf9a96ed31204254b8949394d729ae434c9692a517928a13c9c26bd8c8f739a3e4dd39ce4049a224b2927bb55673b92524e734e19cda1428fa9401528270855e44b9385d26e495cd75555554525fdd4fe59f9aba24b4a5152ea885198a9856c63f5f9584d9e93ed9652619376607c971fecf46331515dc9286669a7409e5e6f209d82e956d4b52ccb92202115bf2a9e900bb5664231eeb6bc72aed83d214da382957575e52e94f2a92a4a2b4a2bda4ce8235265d5ddabaa583dbed07ecfced945fc62b79da6f45b557acf5e31551129ad705551a7f40da9e2caca797b54fcf65edd6e4f4815ed4e5fb6faf6ecce9baa37556faab8c99bde54e958799f3799f243f66a949d9eba4dcbc8e5876efaea2f48b5c13c21977e25562bc72a8a025281b12fb47aa195ddf872b123db625f152f7bef652bf639b1f2c852af8ba8f99515eaa1948fdd449a165bbb7393f69c60ba75893e9eabaaba6855b9d2a62b9fbd3a15333b0415b4c9a56c9020794e3c279ac973e209794eb4304b1328955764f3e25f43ae0872abaa672adb3f89444353a38648d46d9bd21c5a4b2252fca2381ace94aa55cfc6d3ba699736bd24f2cea5942f711f0d51faf7fa913e3687ba5fe82f64b7573729c5edf7de99dfb767bb7a5dbdae5e57afabd7d5ebeab12d614ff99bd3a38fa24f4e7137eab5a47d89dbaf7aefbcc91ddc8da29506a2d46e528a4b5187e2501c4a0b3dedaaabaebaeaaaabae1e0a45a128d421a194524a297d9f5fddf8baaa4ae9533b0a9d75bc37104464147ca34f634b71f95a0a7ddb525f7ba75cbd7a8979137933d53f5b8d8d66236ddf4455d5a7e83718a691d21cf4a56837fa26721b6389d83ecc8bdd4415edb38bdd6a8cec46d36237128bdd2eb215a562ab790536513754ddc5ba2f56bbb5f74873684f3955fba07afd55ea362fc55d940a49e5ae4d6759b4aa2cda92753e7d86834871f7ebb6541f7b5fb6543d9e625ca346acaa4b4a4da3343497d6a871293d67a775dba1ae7c3cc5e44e0da4460d1a1a12e9178934ade209c98d76082ab46d87baf4d4af53d446e726279a262497ba116f62fbab460d1a1a12e97793a33bd4e5ee35ad89bab2ba6b59d62d4b4617860164baa601b109774ce708e7e49a4cec829556524a09bfd3a5a6a4ac2a694bd34ecfe01bd5a1fcfc367f5d166577fa96789b963a33ac4ec337e4ab0d4e874d83dd7437637e4eaa87670947d33b4dd59295757f9a68f8c6746a43b9eccc96a8e9fd2dfbd8ad77b8d93714dbd42d3b8365c853d28eac5787d3349de56964f70e77fb1c7edb61e31cf33cabcf683be74b1fbb714581b8eef4197c63b25b12ae096559d55d8aa2accab7a98e793bd21c93afd5ea59bd3e5538836fd051fc64d9f8433c1d51af0e67f08de9f02dd6af3aedc63c63baf5ea6e06df70b78a1315637c8c56c24b4d7606cb8019675410031c98dcebb2dc4272a114f700d729d9e2c9dd62c99d971fe44257dd494a3736a2596837c62810f35a94e6081dba0b2de67790497140eb4277299fd3b28fad4bc897d6a5cd8325ec4b5c4b454a08ffa48a7d6ca93cbbf5c5aed2412ccb4ec97dec5603b16ef3ac2d7ea79642d6bb65c5cb77137cc3badc227c5bdfd02d09a1dd3ac88d9fe2c1370cdd5ab96571b31d61978fd90fd6d96e3aacf3adb37c3c0415dad64182643407cbd996f8a1632c12c48f9716949f8fdd24a539ac97a0dd7e5120ae6bd92d89cc4e8a8322b93d5117abee36f3a7cb5888656cddc4b51e698ed09fa8d2af54ed2af573abc6eba11a02024a4161b62828ccd296e6adbe3a057ce3596f66c7e82953792cb31b1b796da19cab44b1a3eafc374369d6105468f1f42d7cec1b1bd12c164fd11cfc92b4d8270ac475f9a776600af8065bc74ea9bb945eab4eb7aa8ebad507ee04c19df0ea9857460ac4a12dcce0a4a7b719ae3083113310b933ae5352062ebafb581f9b8ef5b1c6a6c3c6ecc63df45014e68e511885390a73c7faaf96e0a5e6a4a847fde5bceb1b76778761183685b6ed4cd36577fac696e9d43b3b55a2ecf68bbaa452a82951e453aae852d441559399c5acf5948a523f559bee65b71eab92a04bd2e049922b80eb943c81e24e08e146fd7d0948c1fe849ffdeec697dae0c5a6ef38517dceeb71ce3867dcaa5f95eb162b73f52bfe7a50dcadfa4edfcbe6bc3bbfc42d5dffe9b7ec5c7dbacd9c7266bbf53c487b337c94ba33b5ec74938d35bb59df32bbd3d4eef4bdecac9e132ca3e268b79b757c4119b028c3147766707b43eed6dfe9eb630b2497749d922d86dc32447103709d122ee0c00517d700d729e1e2c8ddb86edaede1999ac90bc237361feedd574b393cb76e2f8adb87fcee645bb637c46d7063bbd3db1b12a98b0f3ddaed7acfcb789488f2f894f72ce8f121eccfed4c376eddc4d2677d1a820a6d6ed494e3d99265a9a9df2537b9f0fde704df88b6c4a7f894bd16d4a425a69eaca91cccf74f571d4ce22214b7ca972654775facd04af0938eeb6e7cb7e704cb88f2fda6e77017924187db645072fb20a6d13a96b1bd20d79d72a73be085f639c1321ccdc3c1748d0626d050856b120d1a1a1a1a1a101ce0b46ec9c326758e4b9e008aaee9236f0636510277a385b00cf8e3322fbec75bd2ad601f7139226bdffef1faca69492492cb37edc357b42461199004f9dbaf0c899b30c26249f9246120373852555505798a0ce44df1637f52d3600b650582624a297d7880bceb6b9174d864b8c64b9e4978340db6305a2e81731f16d0741e3e809a46bd3dfc7479cba981236ed31c638c50039535422412893e670f40b4cd5941034dc3ea6159afaa8a65ee44b5b4aecfadc951202273a907cd9dffdcaa25ee61c7644b5c82b1231df2d37eaa6c212e067c136c277631adec1c0285101244d2475c0cb6028c0e2e3d619c5fb91b1d44d25896ddacf392244db2022b5982b6711256c25678a91bb3909e79f241fa47ca616c0a037131841ce1c10a6deb2342aeabfea2f13c9ac645a26f129eadfb80a206cdfae6923cc0d9e0f39552d336510a0e3768510346542b02c232a0768448cf40c14732ce6e59b80517039e5f75089aa000546e461ef40054005429a3dd62bab2d2c59076eb41c34be61167633ad0695448ba8aa621abc72853e635b929ba1cb52cedc6dcaaa31d30e7b32dad5020605e3133977ad0dced8f3197b5c497d28e7654b6c49f87f90673b6a5b8f2ae58b9a214c7741a7bd0dc128c65710b7136e247df62ee47b4c9cf61e8b0e476342b981616cbf2124e622bdac3cb612adb019a5b7a39cccbe15949d35832612a7f5a1da0e90106e6f25ce5ad5a5dea10adac2f9f558826c1bfb0ed4153e3be7cbe549c26411703de8877f8222e1231792a2ff0e5e54024f0627160636c8b68121c229be020314a2ab48d815881c60684854859b9b8dce6b9d4eba32bae704c801cd161141dd6b28b569b043c8087ac98e90e97236808430364022efc947253e2cacab22ccbb22cbbcd0a892bf9ca695d0d83b63190fe028e24da06ba3046192608b0418f1a3d6af4a8d1a3468f1a2842b8a80deeca3d1adda6b98534ac2e1a2404ee061b6119f0108a91913010e90baf1174d291f8b45e8ec49f2037c37c83216ffc830b2d3b65d3c0ac7c9305891851a8051bc232e019f2a16ca91da47613a2da4090801932c13c99d359ecd68df110055f51555505334db2301fc658d2b2feacfb9169123b0b76a8d558ad696b217d65f5297299ef12519f33b870ab6e24314f108a60fa750218830bdf24d75dd577dd0f5a7cca5f3eab8bce18b5dbb40f6f0616c132e0352ca0114d8279df5975131d245e30efd1347a60ac915e8dccf9348e068ca311e3685447e33bb84634a9c70b12adb23d627ded204d82afb59b6820cd4493aafaaea342bcb88c9539df845442c72c0fc9a0cab51df0d004bee2070f4dd0388b2459407127755595a7e023b432153e1cbe08be8104cb802017e30a67436e315724ab8baaaa7a6637d1d63fa4753d6a1cd134aa6a895b1d4ee72b9c0debf07e442ca23b57c36ec6d26adfaabefbda5a59b1be89ee8a75677de54c9d8b61dda238ac4fd5a23d50b75ed57727a4112049f998f3c0f888cfd37323731f32e7f8bee1ba233e091e2ecbc8c8c8f880711f377d03e32f0ee3469c0d6d8b197d13b5b0b81a96c38895e688910e98c7c3580d3409321298dd7a5c46fc96ad478d1bed11d688e98fe2a86e44d3a887d740d38039fc113de463be45bbd1dcf81a9799e532e9f20700dfaa007c0b40b50e80eadc0c8c8af58f1899aa59ab72e5eaf35d7073d95e4dffd0ceccd7e4f90a96014924d0169a95c3b26f12e4db2370350708fd4e6df5aa47eace6f3bd42b59b69a90c03f9efe643c353dcb4c607aa22149572fc91089f2495946a2572db69b58d6ba6accba7955ad9babe620d50b82556df50ba272c6aeb65e55974d57fcaaaa2a8b59cf30ac5bb6fc4e97347875cb63986c4d7b12bbcce4e93bd344dd6f0dd3baad11f6fe0bd2d7ca2576ed6aadb14a55babbeda79f13ed4412cbb22ced05b9d515aa14d616aa8e0e92f228d6ddbda6a92f4969527e62d5941343b123eb7c59498d7e545baa08fb74932bb38a993c27ae39e79cd3aaa4d62029a27889a2d5d014e34fd554895a0d51fc10551d45ad45dfc98feea2d54063abc1890d516b51c5f8f2d25a74f5175a3989a2b5b0ae59ef6f4e5a0b67e35127ad851327ad05d56a682d5898c5049f6ab4e4caa8b53869e18263f5e1b73819c16044a469c457c56a9b98f8bcaa7a781e577f5dd11627a3212a0feb110c30901d11b9fc7a3c5ba2db8b918aa31d94fa4b5caeaeaa6a71321ac237aabf511454bc60b58d88bccf376c44e452a7d5654bfc2a259e7b6be1a26215bbd32d5cbcaa3a9ff92d4e86c4ee6d6544e4be7f3ed8e78d60f0aa6b5b5179f6f3ab6295ea335a4229a56d47306019d468c8ad3e8fa7b25717a57e5a9c7412666b45787904038afb08767a61d845f91ac1c0d2a860e24e558f3e72f9f12d5cdc2b567de46e3dfac8ad4eb57071a98f60c037780483162723188c888c6010531804048a6f3033cb259f25afa494b3a14ccf796acad234e70e5f86bf71ed304541ea4b208450874986e21bd9b71d66664ac27fe6a76e5c9de21b3cf53f9bec8bba2c452d99968214df606ea624c52c77585214750ae32c0ccc6f093b1a94140b3a28dc56c0251de0f36d871933306a06c7e6a654a58f158b4da1a438c994dd62eef439ab1863554b6fa55b656565c63bb51252b1af298aa2dea91e1e8a4f43ede06ef43b5dc2bae769f8466f33f8c63cad1e11de2acbd1963a4491d460e6534c89583ed4d951d48c1e7587cb76b4f2792ab36b49537c1a8e717ba7df1e913b8f45c69ecd2bd16259acc852a76f799685df452c7683971e7bf673cae3d5b09bf1b9fa595317d96d874b2f97542b5555613458dfe6a9d4cf43553ba8ce6318e9d5f0d0482916cae73c5e8d12336244f2d20c859999a9b56654f556b6c49752d366b4b2493bfc337ad46b1dc58ea412af4624d2a619b35efaad47bd3b384973d097327b3d925e0d4f75077ad9193388c419bcc22f44264a8cd5b7794a6365b18dd24291202959de895db17eaa39e3e72c6974ce6ab2d3b49851be9a0cf4ed2af176d9f9e6d424cfa92257442c979335c99389164e9ac6ac2613ed73d2aa6a52d15acadc94729ecad3599530f9ea5382403cfbc1aa3a6852ecd9b7caeec08d7764d38eb2578f52ca7335297552e500699fa0eaadc5163ac886a8a856a190dd2a0bb2680ea94525298e0bc3308c6f6b6fa2a5a8fcd595c32afa54592eb5ea6e33f94cdc28fcec1b7d66e1ddf89f6fd47e2e3fb7b5c0d8085bccb288b2c7afd4cceec0662db460a2854ddb7495520318d5d44586727daae27517dd4da49f7dfd4e698e98e7ac9892501cafe21f3566cccba80513a98062555525cdbdaa62755bcaaef13bbbd63060d829c97befefdfaad76ff1d53e18d9d64d4d5628c5c409c954c5a4e471ccbf4d49ec3625b9d4771ef6b087d1ed3abf89dfc46fe28c8f31c618734cccdb3d8ddff6d5ad623bd25ec91cc6e54345a0f7fede27245315ef558f8930fe6ce93d064645b54be96db5320fc6b7becc10546830ecd6158c5fd56db8ab77182e7c1998bbf7c26e226bab9dba98de7bf066f53d2dc64e56bca98adb31efafd73ba6ba4bf947ccb3139226513076932f76932e76d48291ee8484a6c6dd1c921a170505fb1633146666cc7a6651262ba8cbd26f1893d2f5f8ea1b6677a68b6157465576b2225a941ada371ad219c99b995e8384d9ed1592c90a1aedce6477a62b7b89ab6805dfc8ec9644cf64854834d189a3dd99262493155312ab9aac60191457ae51984e66e5f0081b691a53641ab3a5ae4f9a23852767e48845714c5d5d0f55ec53ca41b53f3f575314455dafa5144d52d4f5ee8bb2692de52c04797da7ef24af4fbe2045a57c7a739d9f8b51263b5d4e97534c55dc6da74bf34bdcc981a49cea06efc45444598a9f211602df90a77a5af9149a5fe123b06bb469c6cfc3695908f3fd8b864e534cd3b45d2957697acae70acd55a65fef6a59520898d5f63a9db3ba1ba7699a66cac532269a2385b194149bfed84913024f5c6919c6428851ab54a93a7fda6d073afa4375ce2e9a27ed34410ac47578b110a66521b01116c2a338ac23949452b21058c68424450b909cf32ad9d986a200c4a4396874ece292497150cfa23822768abed3d0a08c49a292888543893149bcb44a322546816f58a750a2fc1541292019975ceacc6c2dbe6e3d8ac2a8478c7a8c58dc0da35fe252d6e1c5fe1e95442bdc0d8b25aab7b82446c18ad16e71c9c57e8badc8d713e2a5b391f24859d84ab47674fd1da3a8244d4309dfa01ea921a8d0e292b884e6009db225eaf419e851c7fe30104673308d2a3d3010f6b08be298d74551147561545472a9533407bd75acb2ca536af6951aa23426e14cbbce6cab6b578c02df78f2bda76dd413ecd4f41805ac0e4185d663ebe196504feebc8cd5c5beb116eef4ac4a1703bb4aede196842af5e4528f514812a340511cb38a310a2c8322125a8390f784446eb2620911634a833ad4d9fb3dcb289f6b6ffbde13e241eb84c07a78a2104c22753231f2b1778c65307ef1aed32783c934b9dcaec915b7e6eeeeeeebdcc3f39a9fb440ac5b88d88f4ef8bde026f7bd3fcc96f82d7ffdde7b93dd7abcf71ec71e7d8b2edfa8fbf2cdd98089793b1bb7516fdff455b623991f46b7100fc39a60dce4c617619c851f00e2ebeeeeeea65efa7bb10100c30a31a7904b46a6ba7b5d576596e12cf8459db715e5b57efeaa3da6aa1ca6667fa9a1bb54d04735e56dbda5458826519a68851d161c6da962cea231d7e4623dae3bbff5b8ae63b674c6ba03d02be7bab2f5b81c16976dfc16aa20eaf2531c377431286c9ad86171a9d84234e9ee96996c8bb8f024869ff043f28e50c137b08fc62251b3b4f58e3c245818b3ac2c772b21180c6becb9160cebcb3f2aaac05aac16c86cfbd8b6f34af00fb3ac682929b1c8238f0aec55112dc9c2f290608fd23ab4be5996b4de628dac28a5c5f2c658564229d46b3b7a36d90bcc3bd234b05b7f5458522279482e7616c98281ee9e8aa863300cb3311686c1d8176b9fc00721647954b05c3ed28faaf696fa39d7789d85e51d6952a450e4c4505090c037367e117bd1b22c0bbbbcc5966559146394995d24b2a689c9c4d8298cc2a88784878477e421e12191f621816544aaa50845bd21175e4e2ebc58bc288a2a6593a2ae8b6a6e2d2645d9ad9ddcc951545f4cba09dfa0decc190562623447f6eba29c508aa3df908be2a078d6ec6e45655e5793fea586594b21a75d573799cdc5a5d9127de854b7a89d5cd86d456d43f4a11d21ca8e3ebf3e1d2505d44da839af6794e6a032eaba48e5a24293e6a05e0a5db7a80b64532c8a7d9f4f7777f727eb2639b24f6daa9e5dd3bcaeebe253dbf4abc22665d55d9e7e4128da9899cf7f35d05ef6b22e698eeb25b61b470ac475afdbbc8bfabcf566f2d6826f38ab2b39dd48554a4a29ad843752937530c4a1372489814988c0206f8893093ed1f28641e01370c8db4893d6963b0c8442dfeb07a3a02eefc12042e873b1a5485d620c8d8970c86d3e642252093d5b8a8f8251b4b010bec17f108aae5ace43e0137ce39d82433aa5b290096dd9da89dd7660cb6b11a984e01331d2fc2bf5180aac0e8550da42635a628c78a36a3fc1d84dc23c86260636136c8525c6185b2c7c020a693975a9d7b952f32dd5dd516d81414476939a8addb469a321410899c02724841032814fd0bc1a7b6b6fbf896468606c9791f285b5163e01613399a6ac1d7c023ed14c2e759128087c020e79e9172ab2c73bf954ed734e9547cb53b01533ebd11ad2d18ad9e78cb187a739be4bd797b8d1a2161b6126a03395bcd3284048bbf5bd8e626d3ac648af6d07b62dd15f8f6fcba22c56434946cb7a8c547c331794253bfb76ddb22cfd2d1bb3d2b7cbeeb465e990e7531beb06b23c459f8ad10833b1a4dc404e688eec8c6575e3db7cea1d1b9485eace14f1a5b61b5f31f2b321f47297527a31931cd9ad53959f5227ac2a47a9d863a5dc65ed6341b8694cf9b294b3783b70074aeb7d8bedf6a9b0493b2dab47ed5c299f8a10ce6b5ea586eace1497ba388bf8cb72162c83facc624e7662b91b635555b15655e42c86481529e58dffbc328d03b15ba8d4ecf6b4450c199a11000000000073140000300c0c8844a3b1704c22c8b15c1e1400109eb050705017a6518e21630c314400000000000000609240bbc51862c5e77e8b556ba6e8119a0a5b8dc00f3a4082546c0d5a51a66abf389d2dacf67b9c2740708f3a28f3e660736f3d7ff86e7f800bc82b84f9bcf276823efb4b4121568765ba5f7d0cebf1ace4b0ef279d354c8e92d05f4ca3e5f3d8e8c7341fd64440a68e04d4515ccd05998d7d813e2b1be332e39d45eff098d574c26383608839a2d3a956630db776467ff7826a7f16dbb159cdccba74c65b8cef948c95a0eb7c590a76e810a8b14f9745ac8590b83f39e876c58eb27cc4015d6d783caa2ccf49b37ffa2e979dfb3615dd08ebc96fa6bb16f4f376aeaab602ed10288142460173da3fff6cfbcd03fc2cd75adbc69877be6392816a4b786d63c6f7ce8f7383aee9aa9c82e7576d9c4044f9c12d3a2722d24991674b8ada55fc77945deb7c47170179ccf5f5bb1fe62fe218a3d637e2948eeb8b3afb60c09feededf02f62c99c376279ddda42d783040208d271b96c5d2cda8e08668738e65d8de0a1debe2e81d773a8281ed3e6db830a86d8a735daeb965364d79495d4fd602d7da90e3644d7c41c0f01505ac0e7163a7dbd29c12e9cf515f81d8647430b0a18bdf1bd6694f98ec06459cdc8d8f9cd7b09653908670e5b354198b4c307bbaa9d1ead488db80c67e61cd8fdc7c922331a6d7cc2e904ef70bec2d4e69b0f9d74e24a93a058431155fae61e323a1eddba0ee900f2768b5cc0abb5cbe493b256c07d045c07af11da1140b42a2e9f77b131d46de53e928ebe16bbfc91665f7f296f0b3a681b69b84ea4ef96f08e3889886776f4fcc5f5ca92acf8e94b31921f247f54d4ee6542c127b5da16d9379e063f5e5e55253f0d74e8affb82cf6f6d15ad1424b9797a369a9f560eb63243b3599678b7424e6a012cfb19c340d6b4870ad39a8d75f2969663a209172faf484c0819dc660a3af7f5c1d909ab34ab49e2dd1c1075691d415f176490b3833d07a2e6def9ecc00d6b6edab0aa452b16c0e988bf3dd4ca255c553477a7229d30c1295a4803b04aa830b797190fcb0aaf5d30437eb3fcfba5d0279163bcf3f83b28fc201b8e2e9bbf9c813f493fb1a9890068e3ee223f2f6c4aa05dc4358eac4b3bc802b4ef6e8538a0b9dc58794a6773de407476225bfc71c116dabc9ae37da345610b03be325d9d793276b68342447285e2f5754182f47b593f756b8140da2293df1fb097ea478e4af9c0ab3ad287e00051d09d0ee0b9a6eea3af02ac0c570cdf27254728e5aa123766bf8a6a3d6e18ed1d2ed9d5fa457903ac295368ca4d6329e955d1e8d9d3565a1848845613a9aaaa2a38be600c1eab454583f7debbe805d1f40830a7da40f25677d4425c48e203186000d541589f77636364495dfbbde91e09c1bd0b48a48bce58123f97af537916cf2284352618684e7d1f2276b1d05641755eb9bfafa8b6dfe3d5af4d27a030abaf97431a0d184bda0fa8ea4472f8ce7e8a9c52eea8c4b7a3e82314454b27834af0e3503ba31eefe307d46a47b06d42885a176e2bbbcf02916b80b14b4810c68e9240253ec11c38a889917b942701b0b462eba901b54ba90cd8acd84eb855e5c47f494c471527d0d82e027981fac603fda26a7639d665004566c195f2391d4794790a92ea68d07da4c3868410137fa10896530951a2b90e967d0dc88c4055ed756eea75949aa5a5eb7f6c28f64966dd4e439e3b8b167b82be28c7fce187219d02843a8fd28d36131a3f5ec81702c79d19018051ae40c40fcb52c7b0a02b362fd1b6c66659dbcb40f10b62affd1b9d013c540acec15726af48f0c39a1121a4333783f5b0ea4e97771944a8b6e4494c30bc082f0d7c4b131a667c9bccae910902fefe0d7f3246eb36bcb14a1b2dc7a660d404c1d811bdcd57028cef6b8570bebaa72ee96fea5be6baea8e424c10eb280be2231517042ea995140e5145df9f91cb1a3e7a4fe7c7bff435c33397c08aa26917a0cac76daaa044103075b13959da5c7fb2134cd2c8ff6faf530c032ad0a9ed271b93fabbf11412b36fc8eb5c95cb613fee8bafa821345236b192585a291e944d61cdd44d69c5f4b34c3df3b0337b97981ccb422cecc6fe03e0d2deaafd47f4124f580422f8da8e8b9eee33abe275881d19295ef82d408be80485e7fa2ea4a8d8a6457862282d0094f44af6a178649ed8db84f5a813414e9c3a410f4e4f8988b31f4629b621758a0b7f2d173d507447b3f2035d9a83d6c7d5558dddab958b0a4c2c4db8d989dfb26e8a0c215344a41e72beb894b0d5c0c137268e17f6c04b202556186a052cabc8b9e7bbed40a3a281df8f52f7e89cdf365d313d6f27250e64818947f95c9513c08f1159dce86e857803ab7ff017ae07b78048585c7a29bfa34002b6a4f31593e5b63859edf5e38a0f24d860721dbbfa3ae8c47c3d3379ae1a3980a16dafe6eb96069f917f94e58c0a535854393de6b6d997256dabfb3a2a0afebd5c4ff37ff172c5dc111d91483550ca0d2f58b97478d77cc582495079907b95f54b050c7da05a7dbee7921f00018ff0b1637b321c61a894dc985015f9782d53b93b9061bdcdbaafeccc73f3a5fca451e3d5e2fd9b47fe762dfc2f897a1e61520d6545cd015f737b3284bb5b8cbaceab519dedc7cd13159b0fec3bf88a112b3a31b30230466ba2b4a3230ef26815cb8d5093fe6c5510a32ea884b20447e7922e2a9dc602271494de0b7fdcd83fb7ee6963075cb20237c570352aa7b147997f9282b79e1964061942ca05da73c1ebc70f9df8915437a2c03e4f0329336a923fc37c94bba4a2a81b218c6e68be62b77c1c231482a60ef6a402f9450f8bd411311d255456fc25c621e4bdef2e6121b621dc7bc4d1b0e2631ffc824b6e9fe3bf1d04fbc91f68d4ab2530d7022ca556da23751fad63bb42f44f4fc73e5ce06f2d968d175d2fbe74c65054ccb1d90b554c282b9b1c0eea8d1094a7bda5697b2c1dedf64426118e00ced0d1e963803fc5b58d5257d07ab90692de0b74ac9d701875809421637afb16e7e1fb2988912acb186c6810368f119a24c1e0d8281875c27ef6634c3b3698bcd045ffd0eb08c3e3c92661c06b5a224b34b11b2722f12461f80206548114ac6b77ed618d1cd17a3883fb6cc72469779efe15ba9e8b49756e2704b659d1c93f4476b60eca807e4c96e58773d4f07bbba1f57f25d3ce91fdbaeb26e1fe0c3d9fb608315752248d4dada2dce8d4c58c60878d0d8669e811116f74d48b3a327b38012cbad04101dcee82689b79efe3fb3517dac00ccce4020096663a537b06fc84485aa609c8e5c6dfc3e119df525c78d33bcbe508703cc143922def14a27da742a0b8bd8b727d1923cc0d70089673b7751d7022510fcb96beaa38e38ec30303e8dd17865bdfdf3faf0d1b892630ad5bb0273b0a87f342c20194f350cc6088d29e281c97fb62bd5948b1007e05916aa7c8672e35cc4a08bbaa4d80a7a7d9eefe6e14a07e31fa4cf5ee73a05be6819dc5f5d5c1a56b4ab789491a72fe8e79939c8543d99126f22de1460f65d41083c7e160089104c808768aeb6eff62e0f3fcee0ed2086e3f6222309c3b62bf38ed0b0a231c73122039623a4c6dd08493ff1c50b81dcfb07ba5361177952f62bf0bec9326149e596025075c3b699c849d90219a1ee5a9cd8f05ba42c0722066d4d61543928bd6ffadddf3b4aeb6731e0c800533d113e0efd4b609dc998596ec92c258fee644f192ceeb783b5159ccc7e3a2fc17e1cedafdc044359ee77b354aaca17c77cf86ccf50da50c964dd3d15312a5b10c041b6009111524745955ec3cb1144da0c0423b839973ec76835c869ddea3d685ece3df2dbc6b37cd4bc91c37a4691c10f53a116e71f5aa090b37b0cc226e744cc839aa3b4c1098d7dca23845bca70eda9e710e5c85a8c153da5bfa7692f7d1300e50ff7754c68e8d9e996532b8cc8eea277a40c8ed541cb4be5c9a542260619e06155103fc57e1e54c20d41c8a2051f1823c7c7b560895d3a2a53c515b11894770b3e45c6f036c3251b92e87bfdc4defe3c9e9e7811d672f1c366bf0a10950ba9b5b1cc1f2da178ff5f8801a6299b8f50fa9e79e888b7e9d4b170015d88e43b4af1fbff49e43124974935008d60a58b3f827adcf3249e0fe1b03e92b427d5c4c687584b1dd2504cfd2c9dfa3f95715d637e70bdb8aa8fa19fafaf46fea39d3e14315b91e9a9e1e22c3bed04813b356dea06d7ae767ab8f040ac01420eb1cc22725dc8e4fa795fbc49e0d3fd87c9353a03861e4b9c932b9ef30a48b6cb207e2d852c6df09c89299e45c1ef5509c02a2ba2519754da57241830197ce7918b4c97f4632f809b451c7b1ca36dc22d935e32d5c0e04c865771fbc5d6dfc868f113284174d12071f948494d72b203e29f7325580785c77a09feaeb04e2f42d6c6dcc1de82d769e50cf258ae7185d7ab86e5c21cad58ffbed8cd23e92ff02e6447e84e164709781088258e6f5acca0ed0d8fd3641822c95eaff2e8805fffacc288b1cbc34f73938aa8171466864d9a27377071ff74af96c72e7b7ecd2187bbecf86a7a609810373792225de6ab1f797356ea5562bfc35ca0a2fbead5af66580a408b9fc03dfeeceb5e3070c9638727b1892e32a0b4de6ae78af64b59037b14c29b4003d17010db29bbab7435c506cd4cdf6290fb59f83449e0ca4b599b07ac9e3ed5123fb015e5e3824940ef221bfd5b7581931af4fb782cbab7020bf74c0c84d46638e6e675c774572582bc3edf55f98cd380535603d6a296cb99a3e68c45f04688943860a4493cc429239c25ad6c1a6a0fbefa2abe95185c3a4f4235f504ec7a1995ec7c3742c359b49e84ea5f5234cdc78d94704ecce208433a7d3e1116e4ad74116e1221a74ea859e88c2e3f1e0a63809c3e334084b047a2b487a51463a5975540ffb13a0e8db7823dd07a229167820fcf2f930f8687102139bfca84da64fad77dbdc9c6a4cf53e4ef7ce2e6e5911863e8071970895d3a7a045ad802a2f6b520606f0b77536d163e40d4fa57ff7ed05107fce3dee2b56502c9d880bac1fbe7231be45d64ec4c391fc4f9b47932e65b55108da82acd4c968716d95a81e3f99480635368d80112f7f95f8c3830459e26096a3fadfde6c502717093e17b3bdc0dd0e4c2fb7138dc2286679238bb9645a6939b3c9399730eb7efb794c5ac73f4425fd5726121af756acfb5f1ebfd03a63321699882737056222431271e6155a65c1284fdc80baa6310ae4bbe6b28fc8652a2e67c1633c0bc2ebe8a2753b8b62f9c5f157a49978120536a6e3cd14cd0f1c4f2b9ceed16eae1ead91f05dbe9aa4edc8d970ebc5c688e36bd534b4b1c74300e59249bf52aff6b9e3828db6044073c65fb3aa9d732bad102aebba42bbfc25f4471ca7e2257130146d2515f32bfad227205c0c99587e28868b6a982a646467d887a926706a1877d1518e6e36608dbb86900ac0c9546648ec38e7d2ec625a8b65c3ca8d6394037e9a18cfdde8c03f184dba095820817146edbe4427f1ccc21483296ff03dbb6a348752745ecd07fa3e3ca72c2781547f9df60a29ba3500a12fd38512b22248f7d81ec8feb2b45ae5dd2ef20901f2919fc94244e4a51aafe6e043c132688d47d95eaed671594e0ba19945501d4817529a7fa19c2738c9254c578ef90822a70315481af494033d07eb024b05c306b499f9467d7fab2cd3c9523c01e9747365526c9b82943bb08e27363922ac4af011a3c940d3f4a264ed959a58eb43f1d61687eff9ba9990f3f5706c8baebc43e7e3ac55a1c94e3ff679a4c291d6a7a8bd6f71520b145c8427c758455ff6e9cfd1dc754f886dfd0ba0b289ba8d07e70f93d3a5527d8bd691802a9527182ee05bbe96c9ba226dfe77b537291b9aea36ed31b4569e9d58d4fe819624d467966e9862b954fbba9344498bdd1440b2c4ca293d08e23e68a392d17147608c178d0a30937f2ceb1cc70ae1ea350b302ef6b98048d4f8086c12d4752e77ae0022dbbf80341e86c9540d09a099952e44f0b7b3a0b9536d870de86898f2f0722fb141097e6ba2fa523fdabb07d23827bbc719e9f8ae99a415c7c232768bdc5208c8704b74b466a9f1934136554741fbb4267578e203d77d307412cb3ecffe3ab9a9b4071079cc89c9bb35e2bf0571a66250ef4b0de004a2820e8a64308ce370504e9f0769c235cc2a0aa3d4b1d3261820816fac0b931edf31be0aff744b7ad1036d72128243833ebe60209b93c08441399acd91f1cacaee0dac0225515b2f444b72bf26804fe9032e84c60767cf82461c098f6ee54bb7bd63a884642d7980554bd72f7340c084e405e83ef56db21448b9919d170abf1edf0db4826a3ef8abc85cd6924177e3f02e9bd193f57b54ed413af4a65f05778e7c77bdfdaa0922224f3369048246eb4020391ed1136c7895d932fb8456a5525dd4c16ff3d8b40d63ed8df3ce3949b6c99f4c12c9fbc01833f66f834905e47aaa111c0acb44a7b77dbb64ff5b0923fce56876464a7a2cf0410f1c02de4f1586508be2a4934ea8eae5a001988cc93d0c6670ab5fbc1c2c1dfd4478ad225128704f88e8c6e9d6995ac674ae232391110e8357e3a30681b98b0ee7f0feac96ab612a9e769084c4eb01588e055d7525d8ba958b52ae6828824e987f2dccd036833ae337c73d23ea90a2fa7b50e6eecf66cf0ee55a8b0f44048431424e006bba70d6393e94818264bbf1e5102662ab22bef7e3a06540e67ce22595814063fb256a94dd1ac01a6f4beb420a62e2f1695edbeaf1bb24559d4fcd4bd231cb6db32ac9c7334da097bc961210973c1b466e56cca7b00707628a7ce00b1924317159b5e26dc4395a2c3dac02dcecdfd9d6d1546809d5dde1855a41e6cac70c6271ad2535496826035ab7719135b09d571fb331b91c077b1a0ecb0d982fc7617aa1a98fb8f8268c3cde815a94d433cbc292fbf5212c08894c76fccc470663847ebbdd66b849838da5c3e66081219425c7f804c1fab4c2bfdae82b7e4685b89441da26571bc73a027b51ff1e21cf8b87034950ef8b1fc50c0316c97a3550e7c855197dc1d7c132e20180e52b750a19ba6eeca1d9eddc1675d41a7408b0b12305762a76ca27f7fa12e67f04390f05372b3240215373b87d7a81b151876db45dd971a5584f48d9aa8a52c148761332248d4408ae84041b31042fabb270f55e475259653111fcc8e13224d4ae782eee6721cf84799b6fd687df457e382b21be638cd5d3e23cd76b85f48fe3bcf1d3c252f709f1a6f6c523530439cea26ffd1f53a821c162265d81274a267ee690675202cfd45a94166f29bbb6494ff743fddc4de60dbbe3cb753c5e97ceaadc5f6a1249ed0331a8e11f100bf705a1c007f0fb938fa7a978a1ea5d884bcccc389c34820bd9234c929fb84990e2d17a5285ce62a7d0a4f130117bfcd60e453d7b975076957f21b8f351cc2a41c8fbb97a3755563e3a8037c9d62714e3835cce82feb5251abf261256b4d8d20d9a2a2d47edad9f0b423458eb6c6702c64ccd3269ab0875b6077f89d9a1119b19e8655c3606ea04a26a674dfcb2a493e605c7a909913709148a2a5fadcc6f75459f66408a2625674b64b54286061a8a6a61aa5ab549b38237e9f82d61c42f8344857a40ed781331e016e3a74c9cf569dc1d18201925357f07e2fdd894ab9a493396ae9e075d624fea46eef7c438c930128302da5c49e79e63809bd29483f0dfe62fef9ea9cbaad4885aaf3957cd29e39842791db62974e9a6df7d0130762686e88a525a40648768a43e78b3648c41d7ab638e5e02f90a1b7460287a914e8c827f8d2ab83d1d320efa6e46e63617177dc45a70d9e2e027845d73629f739afce8ade63b4f20789fea223174e31dbf004223c88a0f7c7bde42c1eea06f51bc7804bff3d984d7d4d8d302dfabaedde65935c6641768ce0f23cb2c81c214cec6611353f2e3a4a2ccf9f9fabce691e7324d8dc273349da39222850bec586005df99021ae7f78c4933c7b664bb98626c18222cf4292cd66bd5eb60a470ec6a8082686eb04cccd058b7b2959f5f4729354eafd6fd2d3364d5f4342bdf2596eaf8caee506e9ac86dd9d36e54b80508bf4829e0606d3b7efae3c007186cc1e0985f82f944027ac0296b1330440dbcf2200ae12a5fb8c076d1a33d0ba3891e09c042df9f3cb0fd9468654799661042db9419e2dbbb60cf3e0d31b938e7663bc9515aaec0e1829c0ccbcdf06d4b53d21b7ad70098f3c8dcdb3426f3e0f58c0f0df3580c5dd997f9780e63b5c9ba02f4f0008bffa38d3edb992eafe06b1af3eceec520cee03452182e684892442c6b948836da1cc0605fb767260084f92e17c1db6086d09c53e2848b07de13ff25d92416e0c04a7bc74b388adb942999de48684c9765eb4d7e0814020e940f02288d88e287617893dcd47cbe979b40868e7bac74b7dd32c60c26519fe4e84eb10b2fe87c2bfb4055e0b75548caf6e28abb8fa265204f658df1c674cc09f6fdbed093f55d3ea0c6f4f905205d7bde44ea2fa176d53f3f2b3bebe0f03e4fb0aba26e1144017c7619db2351f38f246f990b11a4c218cf1722309715871c3b918eab9d68d43fbc46a77a3859828468c022a4ce4a0acc1f4cb3787f32c9a8201505d5371eeaf254bc088691531ee7d622b87c8dd3fff4efc3035c2289632f5c5d1dda6bf69a65aff78a3beda9bf0efa99e3138e960660886327476aff48db4899faea7552a6bb56ec5415529bd800fc5db95f03e8ec8b3e09677313e039358a8e2459fa243160b4124d9fa45101f5140d08eeec17f6510fa5b86d90cabe7b97bcf25572e1cfb4d92ac76987b2e85fd74854aa8554ad8e35dcd24e83053875f99647c59c505df1d721c9c0f0dbe3758bb1af10f535cf136b9a75c4e54ee886e6cf9083ac233bd1a40315aecae7debc0400c81fbd3192bd7c7942d6d0d5118e20e2849ba8ac02a1bc73e022b01d2e3a25b14eb71409be98e6742c76d00de9e30845f6c00001096d084ccb7c09aea6bd05dc241fff5bf5fb3e8e9f6eace803de465cbabb197402f0048997a36190e05d5fa4e190e574827c7a41ec319bfd5d642bd2d30ba464e0d0aa375a16a60f869eadb9c74904a9ca7f515a8d7116f981ac3d782493d3a88bf061502b89fab666d0b988e8254d27cfae01f439f3e347e8c18d596746980593ebd36485d3e68ec02c73348cd8c4153fe7d2e2498fff13cc8b68746c7a0cf79d08cc04896f05e1597d4e3bf28000d707c2d9f6b4586ec9d5e6e2d0b19a6054003369e293628eaeb8e2a7697728a89c21e5802676a038a2fdf04ef47e8d3169b35cb9814b4e5941e16b1f7169261321b00da0b4108f0b714f50c95f371f03829fff220671e40a9e8751db0c58ad71884fe712f6d529d4c6b429681c8b790a25d882d86c47e2b3c25232ba11021d321bf48d44b68808389ee6af95e8072421961c7221832590260813b02e3fcd151a44ad9ed57204edff905738879a6001d99251ced63ebe55abafdd6aba6fc7399b49f11824fbd7a5ae01113d1343c986d2d501fefb491d96995dd14b8f18a8f737bb1a73ed9bea7772032194d83b1354c1999f8a339325c701c050ebf041b41c97b54dc9fe3d18717f2c4393250b8708372e0dfbc510548d94bc3f2a88fbc4048af93c445fd0ce36e002ca816550307ddcfc27e0eafb020fb2c00cb4f22f72bb87b8677465db40e2e31af278e25d27e1513f442b56115919b275285c76e1cc214c991f2fdcd641528ce02fafeb344556f6701373659154ef17416a08fa90b0477ba490dbaea02e934769ae0cf44390576bd49cf720a75adebca3b024ac63fa2911e285bee54ffb691ea07b61edc046912cdb7b2d7770202a4612a7334adeee51782a980e40ad04382bc1a8a0a99383dc816a6f4f477047ba5b3165dbf39865e5073fa238939ab0437b9f9abbc02dbce136c19906942b8dad4402d0fea9fd503adb6f7cffa6932ad8910373de37a19996c2e3c1431bf42cb8046b216d041be1023e9e5d16596472c19fcfce43f7851379a6cc6ba0115dd7ca0185028d6a8203111c9e746f365130d6d13d6ed5205ce9c62b15bc4e32e8936ed18ae2591184dc93cce94dc90ed67f8a1c8ed99cc05c6474823a08f5fee3e1dca7f827e4c99e2440026c975ae5bd4daa9d733e233c151af1f25e78f13810f2f7faf458570da11ac6661556493ff3508e903228020dac3c136fdb8dbc8922fcee6e0dfa52391698a5136dfce42c9cf55a828bd1b3a05b91a72b3f6f262646ca55133ac4a72865c5f58051ed3ad48f72c442684a4cdcb598a21a6b651ecb033c7f6351510a3519abedd4b0680b6021022fc2dc53d87f456bb6b54fef0e362d69222ec28285881d71abad5060b261849a92ab9a86732ec877895f0b205d6824d40d8631d0b38142fc10c1ec565aa12b00654e2e151ca80ac10313da8fe962ff91840ebb01f8403e24593917224b650dbe3975f818eab66e147133a5e52449b73ac06265d80c2bb0d32e8844825e5ded1ec01a774362fa2cb78f68104fceeb0171dce65cbbf2807706e61ea5a9da8c4dc383771d634eb2e7f7b1805ebfbdc1835b5713fffe024bf16f21bccb14478f2231630e4bca41ee87f981b709b1c7e208e17d24332b870b757a1f722965147a30ef1dfe3432cdd1aadc36666011fc73b8dea1966525211f817eeb5a466a98a101f8c376b36709c8c1114be4f7f88921c7685295a9544b30a0c4797ff6d3226b3e09fb2d0a02ce581015b65d83cbb64bee0d1f87151a6df1ef3aaf90c776ee95953ed0895b66e1ee7bed30233976e15d95d998b51b56bff71df5a63336533b33430ed2a7467ff60137cb26eb0ddc20b09e33c4ec25b1a16f216cf3d3873573e035267beec308cfe5f5d24268b10a7d470ef6f6b6396c76615d4db988bbfd3f7d8d5b82cbe715e5474c481987f19a70b4b8ec20bbaeb36bdaa2b3ac3e64cc861fa04d876e9c6af4fc4ebb877258b1360906c5b5bd9a938a8738a54796999bcce8ba154ed12e5f1d81dfdf0742408f8f8e1a20c535a7f2be0e244387cd1490742c6549c8cb6f9a76a3a29aa8dca9d3b4b00ed46e79a9caca9d09ad413a77ad7ba2d4966899bf6222c0f565b21e8f720506ca05aa8b622a625f9d26ad11a451c4e71ceabde2d1ff1fd7eb101a172181e104c52349171ea97117c2778b65bf12c0f12c0188298d0aba97938ed32266e120ff35bf3d0837e9d72d06fdf85427f246a9671017858f2369c5047f3108a169cd8ea696822a0e10098c30c3a85f4e8b4cfa839fde0d50e0c0282fa7a68e311b75b1243c179621b80c319e65043bfde3c51a6c9313e6624ec89eb2b1c02e3d3ff14b293db54761e89753224b3ce2f12f098ea978cc30ce35b80c467fc62775a82e021b0e39fe122a4b691428b6c433d0935e0988eebd1740a626b89ce4d742fa3050e59ae1204d0408a2da82c7bf3df4b3f1671b749e4fb2238aefd96520a83bbb3e6b417bc8521933b9a2e00a3d70c76480b82e17a7db734efd33fb7e7b4ef86cef756e50dd0400efc5c31bc428bed43b860952117eb114e69a780a7a01dae6c25b63a199bdd8f0a6d4916ca7cec6bfd48fe1b8ba4ed36b242ce7674be3ee28ec90c331e0f554d80d627c4c26c3871c5f572d2d33352f09fc4e2a3436fa1358f95658152a8f07f06ac9f6f810495ee723029c413c7c6f9e9b55deb65038e42b1561f78ac1599ae05d0aca3ed35704f52b08721bb96d08d40c3466e23680411a5c75a32da4af17e41f895781d729fb6431114d2d1bd2ba8ddd2dc10b2d1bcf5dfc1b4fc91bb97e7a82f316207d6ae4b807fc31b22ee6a60e3df9741ea9a2a83764ebb5e1fd634367712ebfd339d3aca51eac092298a60e40d1791121e0b4578a1366b0db12c9420b7d842df7de327e731690c410c29fd803ce8d68a7492406c3290a1b2717bd110a5489c3dc09fb41f98b060618fd976cad6508cb6e6b91127caf8480414f90000e19f28b73fe8f39e451e4e9b6f223470fdc0b28acbe0624dd23b1f6c3555178ff5b22a3a15785635d14e0a21bf52e1bda4f82a6c5b9548124e24ea68f80d6d567c0edaad3839af7548fb9a14af420303c891558739dc83d596f8177ce11e8890d306ed078a7d987f49b517f0b4be395296865222520a594033416bda513baa7fa4fdf4a494a732ad99545217b9805c2b0362d10da41c5b37fc7047a0d78bd15a64171b5bb7d264546c5452e13fa8336628202fc478703cd56d28b21a0e5887402f0a8077c3d0e1bcc1c55d2f4799ed773edc357ae9d09fc3e022dd081cd5a61e5090508655e60633e1cca7d393a32ae9f57322265faed1214201840f1fbcc1526a78fa59ccd26d241fb4ed209e21381776ac98df31a4cee8a1a732e185334fb0f71890df065111a690e4ec85213cebed94c5f494d11ad3aab85ef45b7a48c656e03efc33e592d4c61ccde629f1c6a5e451e8a4e147eb58a237f8138db74ddb437e3968cb312511e27ea0445c327e68bb1aa872cf5a29089314dea7b175f2695bdf35a4603e34e68f98a413d8faa05487338191960b5e05932f5b3da4802012723b45521fc1ffad7574714b1d85ef5eb60aa1f8f48b46dd26ba8796e04a8fce3f665505f85bba1753504ea05bb3648319fdcfb764578aa354991811885df4219da17e4a409aa4d2d9d4a0d97961bbc5e5622cc12894c3f24e9ccb6a9b1545add8a788df433712811f2f85129611767204c9fe27b38cd71ee149e32cc77b72b8321d54c9464fc23b93c017966f3f04cb1c344a793274e5cdd0d1747ef5cee327c8e08cd0e2bea3069026ee56006d63f8a7dffe7344b3a12bc547b193018a16285ec6578f6d2a712bbc619fc550c523d718d78daa9e0bee2f87da13299a4d0f7ad664ca651e0e5710849b2f8278ff6c09ba0c62ad0d8e46859f2a0e3ee97984a1a411488ebbaf719769e5a30bcc88890461fb547db523e1ad21b4b8a9bedac0e79875529a51483c04201aef49e371329aa3c5995e95d8196402031ec4bc9a676db9428bc0911af56e1b749731f0281e208ab102a523f3adf8344478a0076924f70cf0b7da1f14de07f0fe13f2fb1cd3bd2bb9086138af73e4b148e0f9356c50aae224378d44ef8a8248933b16973eaf173e243def491369ecc88c922e2abed5768f56c543b16c2cae2c622b8aa2ee732ed282ae30202c227cb621a4e283eec435685fa0b9fad2e6764da29e9ccd125d0a1d6787250092a8c18b8c91680e97f078fc71ca2041abb4c53c731194be4ba73fac1919dd805810ee70c5845b8741688c94ee3646053058fa2ed26488a01df29d3e8546d690d117ee608f91a560b4af10427f245e77c0f7485a53f692628456251c34dd4b21ac871ed9577474a6dd5716ba82d76ce5205e6323b7df0ec6087e74498d1bc86c8d71438bc18f2e4565c2120fa12620a445472fbd5aa736a6d561fb10c315311b8eaa28a4382c5cdd0c15f44cad8d27e2a29049b9eb46c0173b074ff215d2e76dd63a76a358cc54d351b18e5ad934b09ccc8b6b0608523812424666a74d6230eed86e33d5e2d12e49032559c888802941ed516cf3295d632926f2e219513a42523cc773bd1e71da8a0edb513f5b20167b0f66f39410928a767a5426d9ae0c48692fc5176ed18aa4ef19d9796f1032d38b2935a6251008aaddd9bd0da76eb6c1988a2a87b88dc411b36e1feb293353ed104397b4600a381ec8bff850b9c80163e2a36002ccadb351bd8e65fc64938bd47be8bde92186cc3e5e60021440a877614ff128529716e5299fe4368065928ae506fd0e6082cb260cd0d3c59d648b8914fc73b86198e8a5f66b8867990f7ea2ff6f1dc0a2d989d804d7d5db55209fd0b23e25c9fe66e48eb729ac14a587b3972de2e77c40e745f7a8f889eabb6865992f917ac98872090e04a37540edf870a22a1a93384419eaabdc479e3602c955c4162edb5b5dc1cbd6f23955e3d6a45db78b1cc71d5f7cc345fa1284b24af1e816ec67353ebb3164771900b02fb508c0bffba75f7272970c574bd825cde84a98156295188e80c7d234dc2850dfaaf29a1c1c593d3687f8150d235953c2f00c33309578d994fc68a2fb011665667eb84e88f761f62d5e0162b2393258906acc94de0ce6a94e227ec271d616b56b53dbb9b6dca5ae2688735909b6c48d31d6a7c6de2173c3b9c109e7809fad5231357eb9c13dd8b61fbbd5d530e547dcec7f0b064512503b69269510fa2629c3c13e10871d8c952f69a471a97247291aa643044fa27b8c626dae3af9db0d90e7c66916f95529d724bfb799b7a9159a40a8a4a130658d2f5428770ddbc58e3214a081d876bc9268b101b763b9085d08a4025732119f578d4d8a2f08f237ec1c573c453061179858f871324046dd6cea284c0edc2194052201ac4a91a28ddc6b46791a11201f571bb00c20c9974dc279d352cae59964be24a1bcfd865ca2666daa221e938c6094ea260a404a60053c1d2c063689390a6e43df96d5e1323f5b90277b930cc63385dd823165c3845bb16ad025734e422da37798800da76b98291d1102903893c2ab0f2c3a61ae9cce3b9ceded62cb2fc710e113ca4713310d4d798b78583c27a209f9f34f7c3e151763a7028cadd8d05d8f869f0d04ae9920bed63966a0ae56f25678ce856c60c0c04986c68c09a5c0b71d57ecfe5a95f9e0107083ab3091a675361200a5d2ccfc58d2ad8fd83d22a75849ae51395d67a0b260bc378af2e37e54a1d4787e8dd2f072ff83b33725b0747547535be1dd4dcb1a33c2b4f48f131cc447c05f075332ffef8a22b0a9985fd627896507a39a6473dd4b365c9c7800dca8507c7dfb5f82624f79e5a99edcf76b3a67b77bac2d0fbd30a73a235f222a0b223b845baa3a58196974d68ba2306e55b5184d12be4f4b41407dbcc9cfc5dc2e4a92bd3c13dfaa71233d30670f4ff27c887e975f5246d53486c4466c0fd5322a1e4a2b43e01d27660a93e1bbf7bd0ba9537fddc55b40ef0498221b7e0e82667c0e9929150821f8e1dcf58b431640e2e19836c43f388f01805666f6c52f650acbd44a93e0822ea0942160821bf18805c3e4bc88b56a133288e15c79beeb94078d01b3e4da513c7c4946181868e4bfb72d896a93565de8775fae3d4daf1197702014460f76afc68dc63a4eddbb47ee94dbbf3c510a51e65b2bae82a71025fb2840e7feaa97bc7468972004f1412c269aaf310861764260e5ef142a21cefb7e25835e0dd31c29f6587a3393d703ff6b644600e003fb0bfc6bed9e8bee56b22ba27e8dd0a4cb8dda33ab9747f4f9532e209949abbd55fced9a1c06eab1cbb546c6c531f0cedb466b292bfd4f5419f8f4eed3b35a77740b8bd4261d3d116fc27550695f81cf7f262d1b6cb08f796e9ca98a38dd121fb3d44fc0f7f31f38ed8f10f057e19ec1e54f891b5597d2605b9665e6687c51c211dc5e63971e3cedb78d16d6b235665daa9b577fd3986dae52d09a05e18b9670064c73fe0be16a3562efe975b396815d0a771c4540b68e5178bdba7b85b996659fa0d9f1eeee1b9eeb492562ff17c03dbdcd0989034f79cee8d73a82d4eaf13f7f906e60e5837553f9a8e9b9f4417050d8d16250f58401b602ecad63972b50f9aaee29762a10739a48c610d6be1a217b8a54722c3a7546118aaba7135fc03db5143c5b09ebe3f4869c8aad23c801c6031d2bf1aadec33080687058fd398150a8d862b0c6b2665d3ac0259573a80d991a9609e1934b8842eade04b1270665ee9d26a1481f7b929f889ae1a4c2ebb72c6753bb21ac22e3be4bd0417d152e9f350d42eec6e1b88a526fcf83d2846dcf5591cbedc48a22e808d5cb20aac96bfbbbcf8d940262c0ffad2e600785d9f137598e7879426194ba7e7aabfd4b98202909e83e884354289a8418b05a8644fee456b5146849086ba99648ab72f369639d940fdbe83decb05ad506690ef480304a287466e0256ef22789cc885953cd4a8c38ffffbe6c85055f81295ed331e701216e09ecc7159855d0081d910529014ff10439bdec971642c3f968c704cf614d8f6db4735e234321069d3d5abd3427b880b3548f0a01a30220d19e1fed01205ca9310c36f2d518149becf5b45d6c64f17d2279a6af38a774e0b74894291d37f571847443dfbfaaa3a1aff2fa8693a665220e93fb070f89dc479ed3ad2ea41e678d44e96be25598b0a68f091c834db0cc0b65024f9201fb20bcffd13cc97030d5fa9c1069ada2bb1de7a53a9e9a321cd6249a9a326d1400876ad166f6705e1b3c6c01103d4aeabb9d1fe913009e453867b26805bb9f9519883662314bb41794dee0264c3c559383c9e40e5ab5f4bbb3cdc2ba3ab5cd7373256b1d6b1b8eba618f315f7b8ec3599268f02b63cf3a970e310e597c4dd226e55ccc580c34d9e519fc98eea35b257e06cbd40946f7a12f964c6e4de800b39107432bc55e381ab3f1ed3e4b03cb8a60f14e3b0f6050e88e88228f11daad22d49d027a364c4e9438b6e0a8eeda81223778575c3219d56fb9a1175c6671a5a74ece960378b2dc8536317a27507c4f204ba15d33a5fc9972f6f4a7262a1ff5b00473a3c3a12d0838dba2c5143a908118b97723b0031a32a0c530cfd38f31301c2ca52e32dd3cab01909cf4f69d59f2853a94c9f6f5b3c0285bfa0d5782f927ddd7e062dbca840f8709baf3720cb216e813ae2a0262f9bf3dae900aaac3e11a0073ad86b51a7019eaabb5f3fbe3059e5bd3efae4171e0063f1024087a6646cdedb039ee1f4c74c6d02070185bcc3c3ed000e2edcb1b545d8bbebb77967533c6a3bbeb98078a1b3c6f1129212c7aaf2fc4be795ff47cea018e8e6e583c9037cd2d455e1bc12d0023987a36636602d816d409b4c2882ddc3276d2c9f895b720704e0ada756291117d51a89e9dca63d89022a089ecec771f1bc3e5710bbca6755044f63b3f1feb21a9844f9e108256dd15fd59c9255c5ddd5c115734eaad4b0949572a5fbe7125bc3e8db6c8a5458f08625e6941ecd4c4a9c6663a0143381d30dfac3e642dd86e852badfec1cc3cf04c682b1d2a33c34100b42e8a6d7f56611e906c553a8caebc5348eec50dcfecb3473c8ae9ba498793e10d3bbacb473353e503e7dd06e3e2a0ce55fcb39d24d45c82a6b78d1ccf3bda398c78c2bad255edf7d99ab3432e6693cd0291c73967088a8a90f7ec0d16cbfac1fc322d16a3c5374f99ff314992a898a146f01ee745144eb106db4731515c9a48041ba97887e5cb46132c708b898dfc9de5e5b1b98003a2f8257750b8bd4618f090da7b71ed4d150cc6fe5e8a8897d6ea862cc063224e1b606efb87b4407741773c256bc36a1577e1ed2b9883948d8d52f6f862a826cb5427dc31b105fabab9f5549bb8f6d453882eaa5f5d5b40c7e88b4292869f079b862918fd7cf7b9c80b046322b9dcc9e8fb706e3c5f80369209929cd3f794202b415e848fcfbd7d4e09ed2d244fd3740b940024be85e9b15d877ff10f9feba9ab30c0d11ab6c210099d112b8835c501076083d7edcc18e480014338f63ecc267b164817dc24d599876a3f830c39dbcf8e64b2629b599387cdf849d981e94e829c262d7340daf87549e34221479c12aa8e19156370ff9035436c98df2cd85e17fd4743fe415829d811b3637d19b5d9ca3de40dfce50ad05b88c7452ac4b77438ed319f0c818751afd2405d6cf6e43c13c895e2210fa8898572315de613d1c79da73dc03fcf141af251a2dfb7f2c711cb56ae23abb9f00b5630a11ce8b493700335de8c8597aecede951db1cd5bd2a070ef2f4935ecd786cab008c924ecbda88382e3461e50f9af811f3c903f300d2be64ebaff2e9acae50dab97a328ba0f11b135c639d14ab589ecb63135d7f0c4eae06cfcf0bef177493484b469169869c966dadc48e10c2570236335291b21ee02e153ce2ea83e355e20c4024026ccab570dcd60b42eea59e5789043445909aa921be52fe7f8c2a2d07a47347e0197babf87332a2dfe3e64147b7a11490495446f288fa1858c89516cb001732fb4af81f9f574cb0591189f5f986ea388c25b136c4701e0335097b71b684803855d68b0a52c48914e3c2eff5973c0439c9e8da3ba93dc595013403bc9b5512023d5fb12ba0063b6a0674de8409ddc771392fa1bd814bd33b8e751869070031c34d3d2473cd92c0558cf13834af002b7762aa628bf13ba43fdd2dfde0b812b49615285e6bf46b65dd0205b107c826cc4108a922c6286a5a52ec8d1a05fd9618040d945d9a577e51b9cbe1a6d8d826fa80a099996af6487b5a3fd122765de58f99848adf35134873576e8cdae0d636ff763ea2c57051474f3700c87b77080c1c3f4ec85d3a0086c8f6580e9f1c42142000d92ec183f28cd99ccdafe72cf487bc6de56ef6a0181622caa62f2691902970f6f7a1271ee1f2c1a4348110490bf104db09015bf7fbb51551b0f1eaaa4beb0d7840f7e773ef41518300710f67b3b097c5628e958c5043f2ac1de5ccaea574a949349735048fed4401c93d21cc85e25f92154ced883189aaac3c35bca246fc1d73fa54496377b76baae78908921c75e0c96a3f4b76432e31f56bb063b16bc3986706c6a12e54d30306d96718f80068adb6889c814d0342b3c59c8d74c08f821682c5e6f758e94fab84d2846eecdb5d5c87f2a569f19bc0969a168fd9b16fbb8b4421f19b084075e749b1f59cbb0516d4eb14f2dfe3630dc6cdf02dad7808bb1c5b743903a0f52f0c6059d79882ee0128574d1b4411e8282c2d8ed7a4a6e4cd5e91903515a68a31ac72b8fc0f90f7b80722b518c60fa3092fe02be0a13dca05cc8c9da408b1fd0ec2c234ecde3a015773ca3ec7281041a52c8464adc661af8168e0c25cd13d6d11f34888a6d1c5b1687fc9abcccc523f0761451589f7e88eaf8e890ae98dbb4240d8568c95a0dc74e7d9b37c6643acc4f1b07e7b414f040e263336b82d19a400cc283227ffef2d0a78b0798e2b4fac04ddaf2f65ae45fdd8eaae9fd625d148ee2cb8a962f37fb90dbe9803b5bdda309dc17526dc6d00dd0a9adb3f82b8da312cb041110e43ee78bbef9da126ffeb5ea7ab90d093048cd22374a037724bf1155bdee006d0cf5fe2cf1cb99850c7dacfeb76a3f20b8b4dc6264f77505dbc6c1065239a8e4052f9051614476db56e496be0593aa3065b26313a399be4fd7b9dc9d0e3464159fb25c43ea66ea4de67217018da8e1feed7bf499425446e320939a933a0e737b9b0baa76b51dd28197c888408d762ac60530fb1d739b0132c2f340825ad7cbc3278b333931bb1dc8a7d9cce2cb041a5e1e989daf07a5869774e865b6bbcc73f544a4cbcec8c999e29be6f1acc9d360ab8cde5609209812a071ae80ed3522c31429e1c39b04262f426b68c73e750a20e11367547a0d59c0dee9c16f77903ef469660494f8caa125924aca31186711d611559644746166bf89a220094be72f8630e31e5aa760128b94faf99f157c23972897567b202a12422394680198eccf7452046fc2ba821fbd78a86017e0b62102e1a227a8c6ea72239c3d996d78bf48465da23e4f4b9d568efe6d22ebdb0f16b04a39735e3b0a5fdff2af0ccb6a91fdc6db42a59ad047d603348b5214afb2bdcc2f19006c1861dac97c24d61ccffdde449a6c20ccc106e9ed50b96f386e0d32846e922ae8106563740a1c8070a613768995a178eaa926671150094b937945588a726c2275b8076c9c9bb139a90f77512ffac2b277b25d0209305d58a75387480f5f13f7f13dea66823822aff33de86a0fca5c38543f553fe96bccdfd0021acf0b2bb0e37db9d168b1e49eb533ef76dddeddaf06e8f93cbb846a35db5524e68c88ab403b3df0422ed8e9aa8794173d8c16af7b0fc291712d3d641a57d6ec87152639d6d5311023b19c125e29777feb358a89fbec86c262ab804965a124d0f2a76de25c9f06d6b4d759402323d739456b7ec58345aba8d6b5d49887e93ef25cd1c3425b34db297e41fdfcab77686c37484737a51a2a0f97d4a6b4707392371140367d1a4724762352e054d12ebe8794e7f86ac70bc90d8e720612de7f048b61b57fcc4399b6947022b1aaeaf5f36aed95b56ecea6598c21b545f0ebf992e763fc3392c31313b10afe2fdbe4c63c38646dc5eba64becf0bbe70daff6c65d316acbaa53ad54604668480ef9ae218b7a4c5f336b254b784fb791c60928553828cb39e4041d3d30b202deefea2a8d8b37aa06a746915f4bcda653520d963aa50ecc7eb89273ea36a9af19ef1a4d94cd8009141390105db30417df260a213fe185ee8b6cea18ac9350f4ed2448b0c3e900a01f33e4ea7b8cafcefc7f45f7cf58fa07f0b7789c5cbff10eefff6f224e2b5c6f430335b88c5f57215acbd7cc9f6acd08962e80b9830c612fa7a1bed5a3fce3358869ecd6b7d2c692eb405bcf4f8450e8810f3341242d93706eca851a206ad5385735e8156a20270af44e10e6ff4c6ca4acecd767bafafd0a7e08ed46a2ff8f7dc83b8835af4ecf30075bd984101373c220995b6009fdb909ee0ac92aeb762bc9d250ec458f82916c62d854ec087eb48e47b5ae0613500eaa2a32d4928f8d4411001042086950f0f9664434f086da76b928b4e51d0a9706e287dff8871f458381a78cdebc0bc41675132f0a8fb4b9ee58f014233024f21422833e2447437926bf7c3ba0017de90bb03439f3ba4a5ae0c544f1e4d316b1352ecfa8744cfa12971602f93880c1c09f96768d9fd4c26f6eb8683f55094af7af1c71884f8704bfcecffd3f32dec8e0d6644d92f42b47c0519782add9cab157598e408e72bd8dfcb6f54e22be273ae42677ce06aaf200bd80b5988e7feec4a09019539f3c77a2be3b77904b9d65a939316e7432ea7a5007016be3e2b95a045f34922aad445d1d0dba2bb3dc0edf060d3121857b89f5c3e6c8fa484a892ba1eb30af740baccb28a8396261d5e4805b005def94a346bc3b6bd1ac4969a61d0279ed2e98743e8cf6e6ee786da7b3599ad5bb55872fcd566c1826d59a387d61161a08ea39a78d4eb268df188471e4bc97508597c5ee9010151639405f6092a6a2a36bbd70c254400216fa6b10167c6c4a46967e2b84dd05f543232e281a5af55cce511f0d9e0476b9efc6c9dd7e971cacef2af6389d58a61aeda27891d694cab497a744efa6b18c46bfd0f67ab1987923d26051d45264a1ba70bfecc1d5e9a1ca2fc1e9e38d88d6806f2fa14b34a523f6aae1ef6dbd22726001f33ca3217989be8954fb0590a5c71a1940cb991e15540a1a067ef4cf30fdbdb2885ced6ee70b8c2884b82694924c9da6e79ca2cd48cd6193c8d0a40c0c2fe98e7c6dda1511d28e9e4da7447afe149e63324ea2db3cca0dea012d75ad9d4e41afdecb0546064d3695910536dab53c8158aa941fad252b02b4500ded8f69a8a4579fd426208fb3a2e2872990475848b1e61fabd22415d0c9621fc22fe0d8e5d47df44822169e32562058aca47d6d955571c9533df0a478aa8407846930da7ebe147793181e3ccda8c105d386a7c43b78b375912daa9cf095278bfd1d44b7990434908ca3137d3f29f2312d2cdc798098fa039776c8e8b8af89ce481452c1b3587fd2cf1f70f0c0b532747cdd0dd473445dfde342ab91b471f0ae15e2b2651a853bf1e64c64ed7fe8609f99302287e7298be172dd76128259dbce4a885ba58ac5729f2706bafd38cc16c8394801a5e0cdb654298689039ddcb986621d0cc93eb1565d8db203395e38856377d8b6bebc40d9f6bf32535a4825d37379b7508e1c82a351c97b74d6bcfb54c89e4b24e684737b2745cb237f15677826e34c83e4955e293dc52bbd6ebd52d5b719d2ffebf4b9eedac31bd1d513eabc1d6777598288d04901e9b95daf682b6d12bca76676ef351801e1752b0a90858181869fd939a08a4a2f3bc8e4c02dc92765763e5596d831093cd82f1666655fd43571d98a47d0250b36c994e87d28962ac9690158aa3df3985095eb4f87f37738de93a3db5961065c2b310814ee1608cfee989646fa0222b615f92b259c155eb29233eadf819cf485464b56f871ec99b4ac21065f89638b25eaeda6a4a36a8c552cafa96c63e771a02ecfed8bd0ca06e783cfa9c007cebdad0862202b4252ab23f4a5c85b7bf803f1e1fc19773d777a3903abcebe2fe2dc7b958fa4eddeedc947b0b2c54d2dfad26278a73894899aae3e969a79743788eac13aacfb85b5d1c0628e921623b5f3fb0b8c0c686d4f982c27312e6ce63c5ba1793a36d2e40ac06eba5d2245e5ee8f2b65c80625a205be10b8be0a057cf185507eae9ae679e1c9f4f6b9416c1ae363996f4fea316dc306e65734c708d58141d4aca5a06855b59bafb7d3ddb73cb1d60a42dfd182d6a8a672b47c66d424ef0d899edaa5d6adc3e696bb3630c9c40eb618ea6cca4cd89e882f4b948d9aa2c58527e790561bdf897505584564efd36b65370f89ad05f776ee698ca276f7999f6684144ace066480e9483c3573d920a7580b8d430698fcb3a839fb6bd2a76b5a9c9be5ee334389d9cd95fd9b32092d43f8b4801a6e6fa267429c425586f599f4b8547a2c7424463ccd38d2d93939cad7988999c311d0b5184ee98c6044b525ba55860017793571cea41c3e38cd32217991913567425c24e748093290b8b4ad1c57f53a46cf06bad2b2758d2494fcbc5ec69099da2f2740a0b087c591a1b426294173313bc727e06c7b8c9cada076a301abb94bc91b205c93dc267ae76815871a057437cd0d4d1c99cbc7dc462df15c940654ef101ef77e3f4e58ce72e53a2228a7c9d9eadf77c5914d74b27a3624e11b0031089028b1b549750fdfadd84a41fddfb3cd48da731f52ba240a35985cac05823a4522a8184902a37afcec1524b9d37b04a9883db57fb3693251fc3c3f56c184684530980d6bafe62e7ca1a9a6c3f281beb330c4b1b56a4af069b89d026804be080c6ae51eb09231aeeaa4b5de80655efc68f39c087a09079e7a6ccd2d2ce861d067418bbde71420a363e6bef36de7f6b543825107289d04801cf8e7bf15cef9ed348c1aefebca861fbe42e2728785473e811a81b9f361e27a7b71e5cbfd9bc7b0120cd99bf79043bc62c1ea488849b14a3f0ac904e768f548996931a23faf8a663a49d8f2285103b150d43e9db21866bd02aef1297af1f86bcb1b13a4d3da4ab957ef2f6f3e4ea096571606a9d3fa10a0b882f11ca309d75faf141df9dca7b8573f631cb29bb3613788c3c2c6f8858f9d7f5345b9ddc83f90311e3950280279bc8f9d8f9454776ec3bfa580f46cb3501c63ade84fe795a01fde57b1f750ceb8f260b2f552a1ba9dd14a3d65d48fff1bd70dcff8ffa7bb52eb293d26e6bba19e151bae7d0d6674ae2e7ec1dd3635df325238f56051e7caac8f6b0837e6cb1de0263169cf3d78dd90bd0d2a81686f68a140304107c85600c1a0f6afd216d83d8090c88a4f3748464a2f130061d44262c790094b971812677e03c6b123c06a677be7df81e0903b1189f5b986f9afd26ed75a5de7c7406e14c8ec3728a9ff18846ae535761f3fcae0496d91eb028f0115a7caba80f0dd498c7d6a0ec1e6f68e8d5cc1a1df90736617d1334cb08e338449404260dbc3205220a4cce9dbfa01e26e783cdc50614b7ae32d6c76d6d60afb554de1f571b1c9e394b36df722bcc956dc40f56949f8e1145b2bebf7013d521a6228066596b0b1b7a9a3a6f31d2d68d045b2f0db5f6e317201ecba77c6f2bdbb227898212fce70b07c27bf8797b9919979057d1bb269e2982c218b4fa38db41790fda8531e2a926c69e430e9649e0df1fbc050ed2393b6c0a97094b9855748f1a95178c7f3cccadd073471185799c19537bda24820a2bb8a7c5527c78e8589714a936147a95248f22cb0c827ca5d872ef9c4e2540404b0e519b3298c06140f5d244b525b02b9b3f40d7f539c6d95306c8bfd7643430902173616691b546a98c9a3a6b3d59dacc1bd5dcc79e758cb123ca969d12ccfe736743706bf50a503b84fb6ae3d1c3e137465c34673b2b131564c2a3ad92779b9c26c2bab110a8acbbc41621d6755ca159a83f61d8984693c2017dbeff985dff57d0ac02048e765e22ae13db40310c2fc4782e3e9311a9e834cd8da08c27346a8dbf28ebefbe0a6b8ea320e58b7e8f8499294faa7ceb5f727acf0073a5880fd20e55eda7e4d49a1dac6e49892b48de4421f6d0cf441350f6f6ac3ced7240e1f5add7c6f35e09115246891bfe01ca637924e4382eab0cb15cf1951dc272d855cf1525d0feb908bde4770ccabad348b25e9e93b1efc70b5849d9f63367a9219381640b34d07b0e8d8c9fb0a63a426964a984098c2900993ac61fdc9f8c294722f99c27ab19bcf0b09125e7b54ea5615c83abbc57633a0a5cd519196696ae2553c5df7b68690734b36a57b32ddb82e4567e53bee45cca60771c35708be21c1d687270c9ca21c6ec2211b61db0ca50515602b67173f6e8b76b7bd17be80003f92bc8394fc71ff8a8fbab003610efa9251d25e4db45163df61ed063b3c21a926e998220039e49b31520a55c024824f79ad22aebe8d704a35710177de7d27e49cf76e08dbb75ec0c29f0cbe0fa7dc6a2d0a99bb33d0a6e4831563adf8c353076ad0c43c9108bcd980927e4993d07d3fa8ce1909e2326718f48e5bb033002783c18d4e094445c436e8ac0e42419d0a38201f12238f7a83761952a7859d2d173ede5f2eb870f58cc958b0f9b2eafe329f336a2f9f973697f4976e0cf845aae90dc91f31af96d746b920eb2c4c445475a28a2a7e4e3280e7d62a911c7866d13c24e4020c496c49791c15d1dbdf0d573dbea8dbddb52da9ab4df0629d88accb8ef1c523852ae27e8250c6289d676de7a07139b7508e711efa602398e42c8d8222081578887d0b0c0e3183f290ffa2ecb1e74f6140352a6ff51bd643699b07d3782b16ded4df4cb2dada6e5957a2d3803dd756e5552f56fa1b1415c8d64c5b5f203ba6495bc6aaa2c108fd8ecb8592a5f4b02e0b1b7ddc9ec656d18f6753ad8d526a350561ea71f9894b999079ddd6eacce31ce25188c76df09c63f208e2e67668099b9175b347c22a3142cba39a9aebad31d2802c805ed512aa7849b6840b29cca9c0b09bc4ee67aefe2f68b8835fa1aa814e1236006b30061ce90346497358bdf4bbe481dcd0ab1e0e1237d64571ca03a6c07640c6986f0088010d02c7ff5483c74871d8530ee87e92da447dc103fd9a159db04b8a4813d82fd05c06b1562b6f926bc826623683644e3d1904a4079b104727692a3f173e0d01f72970211e572126ba3a7402d7286fcc83ea7a9cfb574ddb0cfcca97001c809f07bff9460acb24c6ecbfe984ecf4d9176c770900be13dd18cb2cfa04df77015c078ef9fc5b38d52312e1da3fd6e661884a904e09271f8912c005820b78d23fa6604c00a78ee2c3aa5e09450918e9e8ca54aac0f86a9a8c9cc66ce0cb93170506a286552e026c1ed214e4bc09b85543a870209b8f7c08b8b0ea1605f88790d20a48ee4474fa306cc7edb8093ab359956de1e30c2c9ccab2c09cb55c8d5d390b110c948f9d2521cc4de0312b0cc931f94fc676b7b7d74d2aa30b3d0904972c5a54957860fb5c24203205ec2ccc945480162f112ec313d4515399a191b38e4532cd7408a8964334a6091958c92c39cc52f56033bbfa910655be33b62b1018a3252010a210a1df2f90385e1b396072c1f65c7921272c5bacbc6e97b0579f1dc570ea2471d2f04d7df1ae87bb3ab9094e70e6cc4bd04d43321895824869690555dca0af24b795578c0272b0d89f3580b709b0e970138c808bec3a89993275ffae602963df2dbdd3bf922bd2714c0411be2458bbda19b14ad2f9534222163d6871dfac045f1819f657b29b6118a7d0a2e4c8f990bccd8cfb917166eafdaa29250b6fbd793ffa84a8ea04da760930892ce9bc1890263122dc0ce54f4f479e44538530a78764d4e860ced618ffaeb376703065739df50c13dcdeafe9385e6cc6318be12eebe9289b6171a5e766bdf7ed52072f7a051f4c5b9a72a0dd3f41dffc1bc468b20913b02c6ca01d6740a9b332d0fd818715d864cb7fe7611b1eed421c1233f8dcae2698da5330623e67e058cce10db5af80909d60ecc373109b04eb0076de91fffe70c62d4c6a1a7487532dfa7229e3df70e348e7dd67ce3ef88d0f2b60293ffd08d98c7b9e947b62fa52986d12a36b115c607505e98646174fdcc704372a56ebef8867e9935b8ee0ba085a6ab63c2810c6a2301f0e8d22ead862adaa996b454e0391b9905e80a2f1bb50c626e4bde24f08fa57d4aeda7c92b0120b760fccc564ede44d445ef423f9321da252d9e7df75335388ab9dbc1f94c4e4910221c30b176290969cf29991c551db94bb29e482d5582cd1d9435a400e803c11e7cdcbf75f1dd954d2b8dde32ade676804e8ce4bd96b48a04ee93abc12afb01046467d0ef4c9bffed332c51ad66820c1ce0a31066a123e0d37998ca95173dc5ac866baf0242eb2e11a3197928dd0b9d93d14b99a9e78ce507677088e44b6ffa1717cb2487ec683ce61820367248f015736872230d2de90cb9ad5a7e78ceee7b321321753bfeb643b405164f1563bb3cf4eaf6c05801db518c0977f54b6530acafbf86f9a37cf213af9327aff7b074f0e6cc986cb00a00647e20268224f9fb74e3ee84e1f3aba9aa551aee9fda88f904fee917b5f6e0e46857da7ea08ed1504c8d6b87234d2b8e085b4aaa07b88660349ae1ce844c4a5e722c311184beb387a09f5007a048e11cf0f9a9a791663e9c2b91bcc35fbb79ac456bd7d5cb0ff22fc584c71bbb72e07ac0024b8c18319ccd7d33d71f2c482f6df2221fe2185ba847eaeb0c23105ae3315e3136d9ed1cbbb578773086d54183243bd43f40a0b3a9049b457f1463565def93fc9c7cceebe28432f18e033906b50d3fd878cc51a137192fa604a08908a4dce6312ce31aa398a93139ff6b65fb1a36e3316456ac22ed44ae0141af0e2f17952aa51619319b3d3c5e4b50da0e86bc870a4b8eda4709ea7d89a8a06aef183bd4e511f90804c94803d5306de063f5190565aec3d952a1a307a3a77a18ac1211a8dcf0820b76feb6ed48e8b41259987feeed8218dd42abc819001d2840d15c5f5c71be18161c62edbdf48cb75e27ba0d15cdc7a26eaf50028ef27432cda4661f60b29bddc500b446f6f2b94b4ea5b5957fd75eb43bdd73e2e49025b3e1a7e24305b744d3149c6ad2db02585e8286af5de863fda9ec07feea88e06ca6b2929fe80a7a02d454bdfeb947ec0d6e3548c23452a0cd22ed483638e920b985834ef19a4a289e03f89534e0a39fdd4e6966a551cba498e5a5e879cbc6622db00bdcdd21cfd7d63bf4b52e8e56b4d94aa83e3874db5caa90f8ef683508d47ff6eb5c9e65dda20fa9bcdb8225619bf1165cf4e5956e94602cdf6127ce281657527ac4276febfe7de1202adef335f03fdd88c5186f957a71f06c57c0c8ddfd2ac7047655cb4a296229d43a4ca67a00fe9f6c3e67357d4e5e00c9a6f67fc4515fcc9facfbeb32d664a6e1c44b5dd41e8eac01019e77cd0c7726d4a7f22bc643521edd6d2ae286539c9febab5529500dce01ac489496ae775ad9bcadc51f576a795998f1289c58508bc8182881c1312058f03168806894a832a49089aab3ab76a9ed495da09a66906d2ddcdb884ab1a9d5e5aa9569011ab27806d0981f64111d42899e8663dfa0aed973cf374f13f6f83a55966d00a9034fd621126e3c7b528de7e46c6487f5da393e491de70cd2967dce2b4283783f0560d1e200ff924dca31389ac29e60c68a3670377dff09eb0a83979e73845e657072f83175bdfdcaf130b6fe75b95a83d2477d78c6db9869fd376a145625d88c1e5ce369f38e054e182e750d22c3798680428091f2d7326f71cefee5300882a0e6833ad3c7179779b5bceaa0cb071ed63c7fc55da0e9f09d3ba3ad0ecdb2c68446ee88b239860171517297a06fe3c6fbe1078c0e4fb3c9acf95518895740fcd1b9060d360b09e70be74568919df1c0b497ee02d213b5ead413c39feb2e577097f76234a171dab8a8db494ae71908743c70e58666ff08cb67ac8d2f4cdd93375b2c5dbd426a89180c2d016aac520cc05fa5c4f584df9e75f2cfb9a87094496748ef3149229cfc7772083bb8c4c392d86302db10c2d596d11d4d4143e3f37f5d13f12f9c9ac697543378b7289b2ba4e2477dbe323d1330e0ca852c86bcf0b7aac2ea61fc5a215f4893d7583283d0ff4d4a6e4e2833249b9602f4fa2f8c897a2486d2adb714b424010772d48b6f9062b44002629b9babbbea9aaf0bae4eeb6e0a6dc1d6c36aa6b7015181f08e7743c74baffb5acfa6a8042c221ea0e05aec992ceaf0caaa02c0f3dd7f1614a49cba60c78d8944471b2741482b086325d327d61a34f0fc24567e62a97920f1462502ea00d55246a8216f953085348ca2ebd29660b8562ade02b7082a67b7b455f3682362f489bd38380e919f24b535a9ba245b056d082ced5059ed0f5f72845d4e51b0cf920dd901561d43e4d646a7cc6055308789a6707e15f4893af3a178d1516fdcbd464734777f726e452607e17e9cfdcfe48d1d4e40c0acdf063cc64d2e1ba0f3a12dd15b8120e2b9c65aadd0e2b703558ec0201100bda759392bd8ab5c2141d75f54550d5c58d0995192c8b851e6c5850b3084460f9c9b5ef9bca3da1ed9451d88aa9c8078bcab305394301ee14ebd65385f8277298faaf6b0cc036508482694a615b5c83b994bb87ab22c351ad60f943d5d958462304b6669eb4441312dbf392113f5e7dd2646c15fdba174ad7cd2050b423ffe4f7f4190330565bf6dad739428564c99b3c4570c224661e97b0eaff0597c4234af4cf1100ef4c470ddbd5f8cdf277b1fcee0155a8b53434c90941bb9c754a94b35db90bd2517a1da3d417bfbd68abc5c0696b7b0dee45aee8f2d595d3c104e8bd5f0c390e4c0db1c05140fd2d6b11ec456bc83a800cf54a02e803c40510dea0c67ab6ee889185e0b9b5b087e8e23406ff1511efca8834bea10fbe70156d5982cd7a3e201d6fe513eac81bcffc39c2d34924d52c08cc7d8fd0625c79535c664439ccc8397b03f72f617e9b0b9bc76dc24b957d2790d44cd25b0727fcdb00b13974df5090752f75e776b2799c9682e60771bc4f86ab7555544752f113b9ed828a04f48fb4093e10f8718cd77cd8bfc425d7b66169c9e29ca0c455ec42ac87ef137ebeeafd10604e98199e818ab2fa6cff40ff4ed4716b2e3864f085fb0bb2a01b1ff521aab7b5c28743320858ffdd02cbe8be45c39295ad4553a829f322c98a0e555a9860908474d8aa0803137a75b1d11ec715fe8c954539a2ac77464a01fc9b0b79d715d137e5a48461d889065d506ff90429ac59310c15e7d129eb461f298a91bfbce3296089ad0d643630eaf6e1d4e34bb1f75cb6eeaa202458d0a09de13a9613556ca3ba93f0eca8fc0c29e91ab3993f86783ca02e6529611ce9bf1ab0f295de2ec59341925b595bbb20fae9df717125743d73f6db3497018b5f744bb562ab40d4d555557cce7d5131d1ecafb41bd1ab2e6645490407f496cf89b6a5de488a7d0d34c48d85fb6a93df8f5e23fe6ac8c0b2f92cf3456495f9104876af444878d7f240792579d74966fbe438fbe38fc96a53fdcb6be44237e447cf860a02d90b5afe310631158130d1384978767cc0b39bb2513de02af7b33a9322a3b7edb11fed14e28de4d623a407d7190289283f8817264895d0dcdccf22a45a66d87a4a7423874eb008dbb9261940ee4e149ba44ba82c308afacaa2a302e7024a5b411928534fb05e0b9ca9845e039a6d33fb1c8c56850a980bb48f4594ad57aee4ba881aae5caddaa5eb65b3c221baae07d7cbcdd3f77b032b32b415c5899d8114021a03c142fd01c464f15b68488ee2133fcaddb7b32c747b7a8be181f363bb7b375209840a15e7087de9743caf6e5bfdda31740d50a441b469d212099ccdff6282eba78c65691f84621e2f6097f4f2e443eaeda2a6a06b1dee4dc140c105f07b6469bbf3686e1ee8a917ba34bf40a811726d17a3174fd4d61783626d84121b18f63125aa6a2d515c6dbf6a97d13c694e0c9af3ccc171067097d91d5c9a1d8bde3f007468e1cddda1eae5d35859f15a93718f0e386a4a1c45b93f79df2ee7482633fff874c70a7071026d2732e88fa72faf8e11f69c892cd1ce5446a788b7787164f37d84510292ce028cc08738182bc333e760c001ce8d57814ce8961cc1029940fbf299ef41dcc4d8cd9755711793d43e0948bf3c0e679c2d67ceec11143076604d3f33c8caf6a8bafca0605d89c2e180261a00bf4f7c7246ac93368c9394ee03c353836bcb6178c6b52845108897922fdc5f4f3e5f616c1c073f95f378c46d15774002e48ea700d25ffbe86337370e3a96efc59cd53ca1d6795c29eb03461786de31ba4ae8c19608966c5912303e9e22cc851d3ecee4dfc37b3a00391f7104a77860a01052856debf24ac6978b016ad62276ecc12be35a2ad71a27424c1d7051e37355b09c5c51254744f87eafd9a9d0c2ecfb010399564c6e57a1809502f1d999c257f94fc89331c9bbf8f535f593744432ef86c5b29e25735b6ae638016d7dc85b8b0e8dacbf3bfd99e3bbf79cd27fcc9bdb3ebd5308a2163bf5abddf435630ccfe664d6a6400263588e39f403f2455865c4b9d184854185484ef08c99863a913e08f96b5ee8ac850c4f3d54ad4730cc9d4d4c61f64973fc27a61251522993eb07e51449ce92009a7c38937ab8b4177af37f9a7bb01cbbc0b8582ac09913f0b34a09a6a724ff89a0ff4e455c6d14e9005652dc4abbd1f32822e1feaa8b1041686982d4d38ab4982214e89c7a731eb82c4071667382d1bc0e333e587b534e4ce6bdb26751d47cbfa7a8f08454cc49e26ad5abe5c74babf951aedd859bc42e95e1711de40b36e8abb97753cd0bba51644eb961059c5eb2246dfed23e5a09f9f6ef130590f6259b17e935e075fa34e061c9295c96a8585b089b68fc78191de33d21c77123cd97279b575fe5ce5d4a38273095004054ec092658f0a1e895273f346e9463b635976b1c4d636820090b6f9a513cc2806d54567056fdcbe262b9ea582846fdfbe874be5a8de6c4652abae14378b11ffc85dd6f333f79306e9d34b56ea56768b57e5d70c374a97143f56236d051a58daafa74798a9854c47a9e4031fbed5cf63e290b49f2b2c317961d895d63458e03d42abb24f61f5475ac710c1a5dd0d2525c4fa7f17f14d5639325be01266140a4cb59402d3c7e62f23309d4a948786cf7c305a99aedf8f94ed65ee93c1e90824db082637a6ee4ff256886ff72a8760c991b0d14cd9e338e075865224af78a0984199e2d4205a1cc9773283712f0098315c117025732e4887d206e424a63a0144e753b4577765210dca0afa6b636cff7f997a31e6516c728c2f434039abbd188f1e0992e36dbc5e01047bf01a0ce3ae8b5c60c321a2684e1fd824930e4b75ed9a353d1bf624e674404a82b45157f42eef4131fda4905a69f25d3f5ee907df792d3fe1df36bba606d42d160924aa621f3856822730f6cbe7e4224fae39dab4fdd77916353cc0aa738a31b484d28e0ebc11ea73050065c1dce44c6e484a8ea4e3624a4c61b205fd6846a5cf71030a8bc07e904162634165bdc2bad6b66a5081fa8e945c34072b6d1fa4c73a13fbe9ce2558e33a1648c9a55ccb80bbbe090a489f59e49d0ab7c393766f1a9dc169700a0ea9ac4e6093684ac010975646c184105491738e1602032555329449c7d4aee70151ecc198eba3a05adbf64e94d4a38114526fc9051107fbf2422e861b801e129a87d1739c40787097443c815b684d814395dc740988e022e7b13b8e2e4beac053fad6e123414ddfbca83b425b9b5a26e19ac1c597b0eb8761392a3df9af1c7f786bf83970e82d3f09e438af4d4de891890599565b815a8f281af598d7732b55d0d68622751cf136549c9fa701c60c49abeaee5daf50c99a94fcc8c1ead32d599fd3a94f1968fa9e8bd992477e4089a2745b0811a1dab5844efabbb61c6440ce278dc71a544dc70c4f69687f716adc1d796c1251f51b35fc604e3b18f16a27a2ebe83880645c81a1979b2552244528ffb3da289c41a5b606a91fd72a793a0719290b56630dcd9b4fd65f8dcdb1e3805d067c51712191e51dc4066eba534c3b9e4a253aaef47d26e420e5282735fc8fd0a549ddcb85c56dddb8dcd82c49ff474dcb518f833e3d49c0143f3ee6f4c5468a3f59377b23304cbd9eacdacce522103b0cbb614e0b86799db52917fe129ff3e5a0390e5994bbb3a7ee4212862ac597f51d9f997bd6a55dc4669400833e93b70abc0269fc4d78d2811b86c7cc4551afa1971d4d606937cd27086b57561f9cb26325e141e7824fe6964b86a16613394976b6e405c272243c8cb01c544f5fd47c84429798e5b0a27821b2e777146800398dea9fc6a5fef2d27cdc94f4b99d7042123c1b066a1b0129a9c5bd76ae3ac745d16ee85da9bdc1e98067357cf6a7b256da9ed2e85b28ccb44b675dc9924876657db31d8c773a56ce9279458f7a41c2dcf3107fd375c1d65ced1c44b6fea4cac18061b9b157a0225203c9a99a5ecaa3bcf34dd00f4f2227fb6c942f74b7b10f6eabdb0266378faa4570468943c655ffc36ce3722ecea36e053e7c28f02a5010d7638404362540778ecd5ccc7e09813bc83dd48e9bdc6e4ac88ca58e538a650c0744245519651a51bf0220bab2740c221f637138b9f458b1bf3dc1234b02bb9aa4595b31b4938d881b4fbdfa3727fb7b18420de7302c498293749251f7f18a317d56f4b73345b299a1341135140836097b433f18afe13fac2db0ca6c5952ce53c4f7cdb1e25c0e95474dae379303b4a638c432e4804c4e73edf8515af6997a09236e7d50296e24e4b7b306e6dd2be3733fb37aea8e9377a28761413428cd234e7e7d62297c1020ae2f12b11fdde013b2910d75b129faf9170863f6ad30a8f37713d78ea6fce5d46af32b372b112910312872751e1843ba241b5fa4c15214e6e675e145881ab762ae4d76bb6ece585e16db4028b0495a4c7a16d2b49ff64ebae6cb21db35a0ba9bc9d58044778408c432c04bd8127b6fbf7167e25e80a518dcfc94ce3d6cda671a67fde99cc8ca192f235489fa7a7cf43b5e1e37d18da41dbcd83e6b40f1b6a26fab4e2f566ae6d45ea331797b234cb0919fa81e256d4335811cccf78f85c12c8bffeefc6d113ed73371c597e375699d449d4531180dc7bd97bfdd2eca83aff74d791f6f98862da506d083984fa6ad16763b0e58ef9f7e50cfae2a46e2600bd52f2e3b9f9cda729be0f8b77c271da9957257c55f8b5d6602ad916a3c39ad92e69181a5c984ff8563175e99a5ff65b4e4e7176e9a8d37d391ead520a2ac1afe6f86f3d155effbfae29a6124ebfd3e8d289978a39198806c4f5e220488f79829c954a23a5d8116cb6c1f3a7f968c946474d7ae89c03dc98fad031c001bad3463e1904da13d7c96540ab7f91dbc3fa55d5a51fcb26185899a6e4f1820a4a029deaee63cab9350144041b4bc0ff1f798f3005cdff1666b20ea20a662443164e271cd7f4b8e0878e8be80371dcb61affcbeeee9ac70b75dde28ef8fa0f9334670f78b210c606e2c031cae0690fc1fb35668368bd90df31805a7bf962d08166bd475ddb3d0b8e3982f40fe059bbb92b5c2a13ce214ca7f9e081b61f97ab9f76290a9e5f6952ff28fc74708cec47dc17d238e4ece5fa39ec30d3702a095d62c5697bbf1b16a2896d900cb8cd4da03845e67c169b1be0943632a70a8ba10a59c72274121577f06381c1a942e2d5d3037a598cd77ce452ec9005bfd85004fbde4ef92e3b83d0a3c137b620dd5f1ed42627a6c72182389615145be3005bd6f05712035d26b420e23b30ebf96f7c2b8ff593b915150835b9fb41fb76314e224b714ee391325e7d13e0454bd2101b25d62df3959890ec951416924c7cab4a526f309159ff695cabfafb6c307ba804859548190c9dc3569ad5afd4ee0dabae745122f7cab0d68d9891bf1e56ad88e9d812375882572b483bcfa43c0209531d016401585041a5bd4bf6e7493ede00140e093c0078bec78fbda77dad5409a558299dbc82a4864a95fc8cbd79ba7220d236cf9326d31aeea287a0c14fd37abf00ea929990c84b97b0a3561a51d42585670f56245b54cd39544b415ac7f22b0d54469974f5f0bef8e22a788f7c0daabee88ed228c6370e00eba8d52f39e2e81eef05fccbfa4927d82f9605d5b59fea9a37276e1f5657285d35227893189259253eb155657ccd11098282088515351b81ea5bf58466859c1e548677e7b5950ad63da593a0319f1d3007976ca1f31775f9533d362666f422ce334285e7baf33c887fe777f67900f571d4bc30f47810de6edf23fc6cb95d08d3689f6472684cf8d9142d510999d62e743e50d053dc228e0a71f995285086e221900f3af0574978a969a1c816fb77960400af781a8189bab0c7b3a1d3dd94f7b72f03ace29a8f7a1d5d5e8021ce4c9a0bda80d474af5febb981db571e0bdde13aa3ff5921a63ff1d6d565be3cf6883b6a88dc6880831c6141f12e654c0fc53408b1ec459bbd1b3a3079d937bac3b4acacdf7c96939e979862892d4264bf287659593f9f3285a2c585dfd92a5480934efcb8f0b32171e059e1e316fda13c4248efb6e8df384f572cf0e01dbcaaeb0aa3be46af58fe06cb4f67f9a30b38cfcf1e10e7fa29a705b7feadbcd2fe921a2088c637aad3c1f211dca78afcc86ffc2b2ad08d040fa75a82b3721a454f6c95eb6fa2f34b7663b1c1a73e5c05de62a23e74e9e0adb91a5c920144a81e0d31b28c93083f3cec7360016a7c15eb50d53873e6f3b5e8983d50af3ee5fbcbb24fc1c351fa8193111559fb3525d75f9650de951b13784ee0d06bd8485842ff9b79b2625343c451e700597422f2122f1c90a94fe04eb758598fe6a885b4f695e57ba909ae73cec804d984f3a9e3902cb81e5d1feed178ce03cbe7fe3e8a314d7fd6148fef5f5e33c88dd4ca3d7b9b8929f0f7f72f3de0ebdf1ebfffa98fc7fbc5c6b04c98fab81bf15305e205d9db51745979915e6b5f05b4bdf613a7a63b7a700fd53663a35370bfa030cfa7a68078834001bc667159ea9ca07ef09e960c3ff9db80e38102381814c9144ca20c0bf7bc23ea5cebf0a28a3adc65a4a431ca518b2ece70a09dcc8e458b161f9a6c7793d6fa6ec7809219917891228ebb9b0de49b44ddbd66604b666422053fbf9bae3f2c51e4ccf8a28352d5013cc1ebf0e94d54ab6416a1e4e360adced29f73197a924cae1202c421461c3b3220bcb194240fdc42d3987447086399ba784e732ec9143e09b8113cdb777ec2b9cd8328aaa3ce09326ef21393d08661bd7ab0a869a4177cb3dc9c2c7aaec24a01306aff2e8a394cec601008abc55c0ca617f721288802d8bd8cbb7179a6cfc1789310dc50e3fb42c12e8ae37269037e0974e72df4c0569f7f51a54716e9264dc8ebeca679ca336afc38e717c8aee094c8c18bc3191818b4a606f4fc0c887a2d7c198b9f182508365d00fa569a123f97a35f51bac81d8b040b1082adbcf56044cffad857513c465eaefecf42eaa715ec60ad40a8285b21e843978132451bd1dfe70b042dc82a47c614b465fd60656944f5bcc692eddcc150703c585e5cc030512a96949afebf99d54fa93b0f127df19030340bd5f7c98e79d86d74f7939734023110b4557dc122d4355ddf787f1e9603d8a6b39ea2aec8be07b36eb3cfb17e8bb68e8fc4d5f8d0151c724de61dd56619c11ee632740cc6e91d00a132c38881fb7d5eeccd7c491f500432b267ff8104ca0d87c08f3b3c5337eacd71568a04f423118e81b2e4770a8c206772867207de65cc294cd0c92ed7f3a23b6a468f93ed03862cf1ce7382ad4bf56a105622f1e5a45076fc96407871ee5b5d4c25e1529d03a322fafd5b70a312d9bf8d9edf2d589b6de2c10eff25acd788f9df2bbeb864ef978a75409e2f14d80dad739b67ec0a4b9102aa319e70d9513d2717b12d539980e04cc2889173a5257e62795979ec43d53d832b122974744895235bbe3b7b6718c9f74c61274a4895b06e74685b8193bee67fd7bd2b6250f13b3f2ee8d9e2b8bc4b3833a1870dc007608200bbcc21e3101e362414177ef0b7e5a0f213e096680b7d5303d051e94d599d9d1d550b192f5b74aec258306a9346b565e310cd0b46514773958e737e00cd340e30dbc42e5de6b6173711ddb2c3bd69d17faaca8a6ca59d13362ad2ccfe2b43406ceab1a80b0ea8beb194ab4bd4da1a91ad3fbc50b0589ddd2507a4b42c4b49b580b584eea4a6d6dca82d28882678051af5a7f7f7867bba470c22cac98183565120390928e3933440b1307df5ae4661a534da425485fb979b8e70a683130f50c727b007ed10ffb2f7293db88622a0f37420fcc11b820a8d874bace9c0decabe0973044c1a5c52a31ef61f2d883379c67a0df5158c42193bb7d1af5626b8ecac59fd1b03137587cc9b830f9f5bf5a9401299e7ca2df9ffdb8115d5077a60b67c243a771b3af3dc099c087a412aeb1fffde3bc61b396eccefb9131811f4dd70862d867577e9a778992243252229207036f6249e27f7e2b91318d1765e860dd6c97669f099233ffa035dc9a5925cd865b1524add23b65fcc915779912df22ba564bc99699fbd4929e185af7d55f18a2e8299b3fdf313da58e13c17999069d62214b74e82e3a1f46f0223ba2f96828b78bc74c1edf9f95b8189eca00d21f5d33cccedfcbc9b8113e17eab9b8abd9d5b3dbc06e9489c84b929bf7f53b067c46019cac3e1a8e7dd9f28d6b466294e52ad1c5be2ca7daa8066820a031091c8fdf8b84e0ff9777ed7b8e304c70f0a45b7a46510ce51579d2ef57c7aa71d9cf1a3bbccf8b1c2246e2868721dbaa82a2d9ed13b6fa9acb49ac1cfe676a3f49a884f4310a09300f2656eb4abe587bb77ce0307ceb201b949eaaed6d74ffedb01e32bde0d6804fe97e99c558fe028cb9e7d8fe7766ac0c40117b7c1ee157eff5376304ddb166baf86ca748ad8b7b7280a1670b8d880c0363a75a07e9e554198fab0db2cdc24fa09f5460cfb2424a083bf763858dcaeb0edfc771671b8cce66092257ded659fe4092dfc7fc81a251cf727ac34e50936b61908d512c25bfca14a530443ae6388a44fcc1b88c5fc7b5814223ae5524ff89a3b2bbd55f8822b1a168077672200d7ccd79a50b7752e607797ae4f54d2ed3556342e528b5452418f4b0203eb8048dc9a6f971e1f6578e36973f0611b555a944efef8a5cc2d83e74c326ace2d6a0d3dd24bac276600137d75eceef31a5628e996033d9b9b9c1095c86da64bfefb97031ca1c6cff302081d001e857071c978b6468d6a5f8971a12c08ffa6e4b7751bdcc2cee434e71f715fc9f7f0707a0dfbce004a0907c46a8cc6f676dc59c2d8b37f15b88836647cbacccaa52aff90dc7fa53baa4ac514dd76bbd9ede68656361f9f7b66e88159642df2fc4212554cb8da427cd90d0a3ea4ec1bf5000c87307370a8f60cc85dfe7146144bfe781e4aac0f0e248826b886e99e1ecc739ac7e39386afa0edbebd5c32bc9945ff19ff1fb4b448c048b8ade033d7e1bff228b4b27cdb0e3ac6c7aa44fb81e0b1277021f832d5e03c0b22e247db075c16b7769da72df12c5b337cb6b6806c905bee07412328f3b71e4b0aeb6ccd56b053118053f299e3b732efc7481b4d04c9ba4361f3444efd04eccf39ea33dbafa695be886985978213eed56dc34cbf372dc89527a666d3462908ed296811f34faa29dcb1b8117d6ea6aeef92c21ee95c4d01153565e0f44fda0ec5678d293cf86c7007ca9f24fec90c1a2114dbce0632e90ae01a79fbeed0e7e60d594f8f513be68f35fe84300ecc45b407158a865abb34c55ab7a54d9b1856e29a0f97d6f7e21c2cb55b893970084c4abb350faedaaa2a7808ae10ba3c18e27910276d7c106ed330b7f7a307fe18a7d390c5036794a8bbeef7083211812f52c0d6c83d4e85d4bed893d8e02f96e4f819f5f372171b0036c44f8008becac881064361314f9518e0d7baa93102c8c169d03ad21e128712aa6a890ba97537ce16ecac2d670520af2fb11d39c80564b7f4af945772932c875845f413c1296d14e016054ff646bcbeda17cd84c2456724748d6286332e51e7361a8e9a048f5fc899d94e137ec46b4cbd7e31178f31c08314452e93892d196c7125bfd25af50949021ebc0e577882894453e5f7a4a0c9e83c70b61a82e63bceb9f77a9c8457f9956bb9a3361a920b2c3e250f08d5753d26e7592bcf58d6c2264b63aa4611463c52f19b17bd3c34ee2f6e35cf0c2479bad2c36ef360bae57c235130474e8bb1a980e62a1951d73971178d1881132055fc10636f0513cd018f9f4fdc531d0444485c4565dc4687bad04564e0e6f78f80af7fde48680e6cd8242f6ba23a2e8cd88c2317848ca002c5babb74121df0cbe9738f1954c0c48e0131156790ce0acfccb0601f32928fb403662b9b1044a2866b95ff5608072523e10ed8ceb6f51b443ed776187307afe1725fcf4582a98c839b22777f92b12c6c09e8dc943fc7878927d33e82567827c778258f4d6ad8bcf696de742dd7a8e85fe071696b6f4002d3d0cd1219bd02e1d15c4850e9bd6e5bde92c91f78aa1ee4b4123904ae7b71316edd45df7d30b55003b98117f4a877f48a80cb2b7da63d5063fa632883fbd73175def2f62912a43b149d61e2c6a722f56662fb4ed2ea4428cc78b46ed74c4e3b9da101562231b39c3b095c69c3044cc969d916a9642adc988feb1c39b54a27dc39839412b513ab46e95860bd86756020164684a74cbdfdc9495e4208b48ea2f5ed6b7f5bc55f86e6bc507508e671a389aad41b880a0fadb443b58144be949251fe36c62c8a4226b542e776a16e387d8aaa67e6c2fd8b88701b4e2eb6465b52cbe2d95c3832a3a40d82ea2df668605a282bf57241000afd41f750f154a75f13675e308ef5ec17cb8b5394e1d719fc2820d9bcf061b5baa7b38256c5f43a4e3da72b47cbb4bda7e684ad2ed3d24ac06fd93fee712054463f8665c15f34b8c7a4113bdb231db30990df6a5da0d400dae9b640705ce502c5429d2aa5bbed65891285a66af405c3ba1a95a5d6b0e090d24e53a185948479030171d947f4edbf5597c332a1bb9f6593d8efb49f9e4a4d060384625359aa5cc1fe32a07cab5403476918ff6423262f8b416cd51cafb3121f091b36af63c16574c872376ab2d3dfe5e889dccb547649b9b44dc114c2d349d837e296ab87e8bbd41409712c228a40506002e1b85c931ae04aa32db040b57d49470ff1ba1eb4d9e7286d2412503c7b6f7931ed8e5703a868355db0c2ea8901000aa9b463a4492ae05574defbd4d6885876056fae23626c791934f7b0ac632901272863fda0ba381e010a12607f4d02c0c656563bc656cafd498209ad0552cf173d6c8849a5f2d86210b9f3fc4d166b2c429cb74ddab3947053e5edcb5b968e240f1f5266dd641167085435dfae240b7a9aec335e0445613b6292cb649a34626340d050aa73a55b10e120d462dae361b3e17027c3bb7c26264250f8713c5c053a7c658cdca784c6eff80ee58da9a8b1b26e84359c2bc32dce55122288d184854a5761c67f1861204a815ad22ce43285d701c36488600b3c4aba410801c3cf840be2f9e7cbba733e6a8c0ba9c8100c92cb1157bfee25fc276cfc87fcd49ae7fdce1264f55c88bb719c56684a5f03b4225891a156d45a67a6087c2c08959223e9e08c1f023164e5ca24d10134b466dc9e8f03b0b4741e473498e8c8a641b144927e838f1102312ef8a0d9018ded4a55b80b8cbe3e425d4ddaf800e8e603d23e76f14a00ed1a5286111fe4082b144d3728e9c353356b50d114374a7109f4d5f87442acdd40815a268844b1f3ec2a1f833e816a3ef43d522f830c4f6163dae3126a37f1dcce772347f75cf63e435afb4c0593410cb70feaa552932c621b588bf07232710908f1429508d4a6a8d901b18df7080e971989fc42ade60b273e4679d2a84ea38ff842920309d07ce2392127ccab8227a2fbe289471c913ddc4d9e42b2528b4eb60a06617c0112266386acd69de1a399502024a9b13c4a273fa0a93e4a1cb280d17b8812f0d838a7f8b8ff934ff003efc30994aa820a756ccf71d89a3dc300b583efe222043542f369dd1051b4a668a1eae1d656e17d81be585f299e775b4f00ec7bc66b5bb721e839213c38b9bb8b9a587df9e88f3683116bcd7e1204566cc82c884227331803f0196a7606c7089a3c589e68268e74954eddcac14e81d4cde74e9e7e12628fdd00cde2711dbbfa50db3bbb5576cd37f024916735be1cc25f163f666f8631fef7a5dbcf695b53e0a224f91a9186648ee798e548b170e2d7389c4f94d523899e6f00f5ad253f7d0b13da213eebb44ee2460fb4ba8fd4a415c3e919fed56f76c82bfd669094e1757785e4f944a2108e781765ed3c44e9feefe1977e48bdc5fb47a665acb3fd8cab992b81b403112f42784582a4810744b40f202d4495c991bc2b880047eeefcbf6d0a43541a91200344de32569669c10c715b7d1c815257a435e03202e4b6290cf581614b8e0beb49e3e87f4d749c693bc0d958afaa080833810dcee5ccf8da4edca2920b04b996de1e4b23a8566a72c989d46e90524014548a5dc484e63bc161225a72d2a1a706aa9bc5022fb50dab72289a1164f5b2c867b6c61d1713d6fd76108d860aafda1ed3c37741bf4658fbfa8350e6e68a425155c394729a5a5743e90d39121113d34e831768852115dabbb37d18704a664f82ee935bae41004ea6f6154a4f87bdffc4732d10a8cae083f653e9e65e7676115d320912f64f8503873f10b7f06c3d4e00ae67d11ed0fc2215a43ae6224eeb969e760e31d1bc1c327f8a1b7ab45c1ed215d25a0171b261b418d81a7bd707a3737447ef4bf858e081f0664c429a0d2ee908df44a066f4710b74860d57a94974c20b8dc4c3652b79e5eb741585f2bbbf0cfc0f5213450792e85e4204f42c61c64a27f2279949822cff2d43e362e0a67abd48bdb655bde665ec79c0b8f710fcd08140a907c7baac0a836c4c2e2dfa48388073bda9edfa20c264ab195acb83908e584be209f2616e1f76a7fa217ebff89f25e5750c555694d0a281f18e994c2fc051835f823ee5cc599519677052b714737be752e0c4872e0ac05b62d3005011c1019359ec508d0fa38f26f23d83f5bf0cf7a6f7906934e1f566b5dc40dc756253b6770f1a10f536e202df760610bb964915184ca40330ec84af604767a67fe1117900d79138f1dc23dc5995620ef35f4b18260ba35c8b620f52c886641593c67b10ee1e5920d5b65e3c0204069ca294751d4d9fb9f273c9ad2f130526d4c704f01d05de64dccfc06f182640e84743a8af691854430671cd2b4459084b13f87c00ca75eab55b166647a6b5f4df38acd4f608c5c0f4b33b63a831459de0573871e207b6296c908622eb1b344786293e10bd67c0e6c7f381bd344863c9ca37f69c7e34445428000cfabb43a36672e4d63defdf5cf4d70968a7ebd350b0d475feb790e6686d55cfc129a4d4e61324e17ac15d3095d95dd6ec31e2b8be5b563df42d93221cb12e6b47dc71d8cf6bf0fd7669707b20f72f57c86c80bcc98c1ae43f559536813fa4ea381e10db06e449d048ec11361d3a3dedd5b642896eceb4286a8dd37704777e440aff714a847cc80527c41203160a0cb0c1667030e948cdda3025b0a3b8b703293a1ce425e2776c0bf280fd83db0ab519ed4e36053b540d7fa0e37eadb68c7081b7070127d8bac749e21076ab58957e9dcb25ba9d2391667652c3ac92099b00cc483f06e355fd615e3137b84a96c07878c51b80ab87604bdcf1be76db358727513bc0351c7480234549b5ea2bf32676679ebf6ab9951e219b0719dacdd18c1ed3724ba843a42ca924d78574dde7f6d76a228e80fe5da3dd39047ce4ce3cf719427b27237514288627354e285ed029d2f4de7161d11200206f77711d0d4202f8a4a110713f43f62bd95d40162f33f89cba437927780f4889c58c9a8f2279f9772daf8db21e8c981e61f82f8c5efe3ae8301d97fe8c68980edc107958108d476bdea2f9e4574a98ff302454af407e600034141e6dc6cb05c11fbbcb8e1b5df2ba3ff8dc39f8388fa506435fbb1a9e63f8b541bae16098e39d10aa6d36b7160250dd48b506b30ffb4649b681364bc5d2fb88010a4627d503822b5fd4cfd31a011e2fb45b1e5008908484c1a00a1065daa802b81c9aef93fdba09d3c74073e2da5d34675002542cae837f5bf315b9d7ed52fcab473805ea09f6b969d5e4f5b06b8608ca9372b65d6294c4858d106895727e8a34953deb596d47284fd747241892c933ff55ed2fbd3307ca6ec7e2f2588ce9c0afeeb6423fd58f4aa37e83ab25abe277dbe529a4e392ea74e3d06afac36473ca2d5bf2fe27f5527bf3f791adf9973979fd8433e8c4e03fed67e605a5cca037aa6ca85572096324a073e8155592b67bf749b718501f2159383dff418acf907d5223f31c50ff4d52f90fb2e323cd801ce62729b9bbc70c163e6b9c7964a0801257f92d591190fa43d793a0a48862dbf259290bde5de524a29534a32cd0730083c082e3b82d98c55395038e138327f4bcdd068a7ee61d56847e65b2ff3451afb1a6df4345a9dd14aef321b5a25f34082102955ed473d3c3d3c3d3c3d3c3d3c4f3b33823a9b95845d3c2d9ea5b1dce757ee7bcff49b03996c7c5b7dea3a5a31daed7a14e2e78896ddf1269be34d8f42bdf53a3493f53bace97568282d87e6e0c97a95ffdd6a6f306baa7993ac7978e5abb137fcf03e3872e87ea6bfb8bd6766c68a80ee9c3ee4f4a2ff7815b7e255fcc7818adc73a022fff12afe73d26a88b4902da59a4f04870bab0c6b2e6c544f1aabfe4e938eadf5f43a3ec4399116226d741dd7711d23349c9e757cfaf4e9d34fd6790f222f5877777620ffa1691a2250ba438c7a131f722603bc31ca5f61fe2dc456465a52da27e550bfcc888c9108da27f4e493f1b99373c1f48e59cbd616629a733ead5306b28cf3bf1e1b7d67268daf0cb4ce4dcbedc8ab7cce9136baf551da93f351e79cb59e4effa9148e85ef573042f84858502f0a5304b1bc2b7e63dfc8373af6d16e418ef08574dbdebf4bed8db314b3f2fa0df614b3b4ad92bedb7d9605fee1361669771131899059e004c0f82ec8cb8cb0dd56f05980415ac8732cc019a817e9a8cd48bf883fb54e5e3ab523f2277d4ca3d1889b58a7a466ea14e35816f887af6e4ce2f7d9e72ea65fd4f65261855f63adeda562b5b6975ab3c9cccccc9cf5500ff5900ab0c6de7b2c422637d7bbcb525a4c308c8e3e9b32226d22208dacef26dda49b7413ac63134a134a0996e097649ca5d284529a543299929df3fa6c7e76652599cc94cd4b62b33e13963d767d2946c7332cc325aeccf1ea9996e952d726f5a889cc2833ca8ce2ac1cd0f7ba335859a862d2fa5a2d5a223db5227d3aa3c9d08ca9d052e52cb31bc6d67317eef2221b995bc920849fc958b3ecca2a9665d7d7f935ab5fa4b19a5d9f237b5e31cc6e4a7c6ba1083fcb6af6ae49a3ce30fff11fffb9128cc62084fedacd26ff491f45b7aebf4a18863daa07bb4ada0d7d37af2fcd2f5d58e98b74467fca609ffd561fbbe07b977ec3307b612e53cab04b433de11f9735ed764b2c81f01d87f2fc88d224c548aa17e97a1289547f93798e9f633e134d0d8e113f8e1a9a527b612f332312a95449cee33ccee33ccef356b52598af6ea5c2ea571cc881fcc77f666af52a6ea54a3aa294d29fe1caf5eb56239c21bd8924546bad5c6bad95fdc77ffcc77ffc87493acda48f20b50ee99b09e9c1cb923bbdd34dbac9884422914695448a3f1a91485fa46b8e293ec47b543ba52443922975936ed24dba4937c95a664142f5a09a2041120aca86f241f9a09e9848a41c44a447f590504d9828a5f44d922b0de9eb6f334f929f036e394013e94924bbe5d0555ec9924896c62ae96bb29b0856db8c75553eea09ea09ea09ea09ea49cbb0dc42698c31c617df663d74d675bd283f3e7859b2ced58d33d78c7693bd235d33339147fc99cc8fde68f4667e53f246a33a7a26aba42f6b37d208a376b3a6357117f82cd6ab524b2198269449c5044d53ca9432a3cc282693e92714d3a44263324d9f09653691c469704c29a488e337d2934c31d6309f524088441cb1862695020284489c5166941965469951f807bc7c60729988ebb29821e652d2e69852486fb6ebe3f370255fcc504e3091be95493a33436766e8cc0c9d99b919bda3a49999a7b45699c449f547334afad6dfd8fa0d32cfd84d04ab4da6922ccdb4d7989dde43fcc3d429c62a4b2efff1a58c32ca28a37c54debd7f97eff25dbebbff22feda36a9bc7ce7fe7ffafcbfd984734efebb94f2ba0095ba2989d7bf95c2c77f7f6a7a339246cac82a473293d26e25138d4ccdac1a992aa5ac916f92915faaf2a58ca9e69443c73f8f1fc0bf00fe03f06ff30f807fab7d8fb75b0af19f87dd6137223a2c0a764b9d70d8ed6b68ec8c8c2c5592356129744646cf09e79c73f6ec23e6d46926ed73ce9e734e48336b53e255a6146d69f42ad6c3bbc943827b4b2965cb9652a29ae86e1414b949d952ca19a774f99db953aad9adb37739c0641a66adcb9a3012cb366813514a6987a1943aed3094b6970643296d224ae95547f449f42b1d3977d96dd543264c7ed15906b32ccbb22894719818dbb32dcbb22c7b8f66d8cba6dd9c4afcaa6464336b6594a9ccc85d4c58d6320c8ff2f993fc499144223d52fc27497392482452961b284956ca27fff923914891442245fa16e9e36f2eed36c4f4a4529d31619544fa1a52cd931e07497e8d666732196ab79509ab3dd9783d6fe7397950e4f57aa494d38eb01166b73ae7b4f34da6199912f6de7bcf8867c433226b2985af7bce398ed13f7e7b8977c677d769eeca48644929e94bd2958de693461946ad1eeaa11e825ce444f9bc397310cd47f5cc37514d4c948fbbe69c9bd5bf3d3157ca691be8ca774f6aa9b55bcf2faba42d7fd413d413d413d49311c33131cacde394d2abb895e93042077a0e747de6b7ec2d6ff93358b5344f9a26cdf4f369e6d768ce4993e61c56b2b41672e9eefee33ffe139fd03badd34cfa08f99cf74efd0dfb492a5d5573dd436e4adc493a5212add6de6dcbbdbb4937e92658c32ff435b39392c340e94c44c246b5da4dc923698ea96458b44ade8d54fc3deec25db80b77f115a9a19737a550f7e8fcddf471d36f74efee94f0fdbaa9a4efb3d2dd816468e85ba69a772099652019bb4d1abbd537758d2dd9ed47760392d98d48e39829d9875b9c18a8056299adfdcc3be78600e071a080da21006df6b0d1e603c06ada6b4ae2a76079d88dc80ebb010182b2ff3356a6546d54067b9ad33274841e159dc19e86e3a8f8d253a4e2c15dc9820418d57bd7707444a1e2c1b484ea59d72d98b0a77112965004918ad2604f63255c81c18e8ad6604fe32a72c0041f15c5813dcd350704514fd8d35c1a573021525114723837de780216956b3aa250399b76265067f3fc591cf621891f00a1e2813651cd6ea11f3e1c94972bea366ff51e4c2adb375135bc870ff99fc5e129b644d151f160ad40f57ea5720d5583e3e0f0c0c14a950384118854d49b9dbfd1b6bacef9e8a108368454aea1bca89c4d73f70fdd4a1a4c94f229dbd595cf4f1bae2ed494f47df6861564b6824ecca166bd37f39cd38acf5de77c4c291d83daf50efb29bc6e9cf371e5f5d1ff883ffda75d5fc47d75a9c63da8229f9f651f5acbdf9590358e187459c4bc07fcc38d40b79a1c6300042f7e2226827f5d8fa970179e0284c81524d50377e9618a7bf7ee6dbc4713355146b179c599b5971efaff07a28788868886888688868886888098588d6770a37c503e4411a29ee420423dd9c2e5faf3c8413d413dc98190a10dbca9252784dd8f759430c6f7b4bf52c0d3c3d3c3d3c3d3c3d3c3d39302f81c0d8ac3ebf7774ac141cb9471beaf91ef4ff1d91c715ed8a83ed308b3db3b8b45de41c5098573965cc7e1bb877f0ebb393127bbb9a21a6bb7f9bfc33b3c96cc28a61965499d58b58a409dcde68ada66c8c981a0840f42d27bf64e0a61d77c2f7ea95ed7233e181f6a8f7ff4432dda8dddca7dcf94d916b942830f39f5acd3ca20fc2708aca515d4d940ec62cb04de1357ded3294e22afe4e1368c7f9deef5ec3c426d8bf850e77bcec307e07f8fe174cb6e1fea7b286113a8b3696a3a61efc5b8f170df77f79cdc4f35d73a1648a78840cdff6997c6e387d3109c205ed54df8003896230fdbaa533c7e70336a53360ca2177c41541245230932bb268646dd1cd04442bda10fb3a71756fa8c7975bdcb32ac0ab5fe53bd4aad66d49a845a7fae9881d58a04acc2ea3ffc03b398ff60b67a95ea3f59f41f2b8ce7a613e22ef7bec8116542dd1cd094628c8a38200608c8117d978d24953d246d10222f0421f282fb02658351428dcf415ed82146e51830ac87f84766b3188a38c065e9a1cc420c4ab851582774195b49e020a5d5717d4a3b31227941c96ad48d75ee0e2ef5663ebca085fdc50c254339a338d3e9d3a967717278094e0b79394bdc93444fce269650e33b61c90e2e9559877d5a089d51f88765a52559070c3b9951209d3e3a7446811716d6c25ba2d0b5a08e93ce39275927daa973a3f08fcb0dea6c74604f670c33065f328609a3decceba7b446578c97155b67663083eec531626c27b18c0a67b4b26c471895adec65365a7166add34d56f1316aafb74ddb4de0234d365400f2a9cc7b765451d9be8941cc6171f7497946c58250b99a1e3e2adfab49c7055b484208b58a9da0f3b417abe397212f27c7449d62ce8c48f7bc30b576a451b79f60d41bf9f06e7fe9b710ebfa8cbe532db3de7a9751669e62311d261dcecb2342468dcf3ac0a87cb7bf1202094284bb6c2fd8a8c05d5888a73477d99ef6b88ba56d61419d4d0361cefde9623bb11e624bb2ad3b8aead65db8cb9abb3b84eacdf5d09234b320c347f96c2b86392e5bc4a1853bd009ecd969214e604f0b89eec11d43ee3e082d94bb034c8dcf7007f6ec10aabca5b978792d047b473de11f765b359716b2c92cb70b1772d96593f8983117fef66cc3b8d3ef45b0923fed9603cc7d566ab1c0e8329f11a6aae3cdd363cf08bfc2cccc8f86e6df430821cdd644af34136988cf88b7b3f38c783ddbea19c1efed3c235e0fef74ea391dbc87e3f8195bb2241b430b81af82da06e44aab83753dcd9e8b48a5190971684ea543b42e8a4363552a75e7974838e0471d663d7d94a9948f8f8f0fc4f1ece373d6d39c3e38ec8440d462c0f27a9e11a6ae612c668b2d8bb3677e4f47d888342232ca7e8a808aa6b4943126311166661e59cc6c315b96658367d43a66491609fe834d9303b97a7afea38d7e6a72f4414e369d923fd2be533231d3fa9aa085c09c2d5bae3fcfeec9dcdcdc6cc1e00e84bbbb475f4828e541719f3e827b769c60147352f3d61c99a6c7afd564e79cd3649a26d334fd34994c76e369fa53cd464ff6ad9a1a7b63fa9ac6bcbcc963aaa9b1ce53ad7427ce038bb413274e9c3819bd671e5d7172058b4eae3871728587733a6573677777f76d9b1bbf755aa775babb89bce084c7098f131e273c4e786a9a46a80b4f217a3c85a887a710f114a21e9ee26070176c9a98c8d5d3e32e4e8569d9571834cbce68260d9b29e2a71913a9f4264de667b4926495d4b6d3b5acdb39ad2fd2a71136f22fe2f36d522a74ca8988888888685335609857e4609a88bd600087893d3ba1f73eb3b44dcb7ec3ded96795f465d91b67b1cf7e9b9fd139e1c8deccc726666f9837f00f2774c30d1810bac109f14eb43760e0061c6ec0c00d38f0ce0d37cc2c7bca1a3fc60f2d6604fb6c6a996747e4c4aae974c30d4237609c6979edc471a97246be0ddc85bdd8c05dd8cbb381bd70171bdecf7c46d2a2296a0f8a7961bca8c1d8b0b197ce6cb41ea7e5bcdc68fd4c2c454a5fbb80953a6d0e18e6b277f03e2b9396bb90248cd7335df9d77b4f87fbdc983163ded874dc6bcbe1461b02d37df6e6fa0bb37ea4312123639289f58b34cc2850fa999f9d925f8a2f33994c8b7f4da024432f4d3e67d196eea5597ffdd5a9abc7f5a597d196dc6034df6549461a13f5a566c4bdeed1a9938eb7a9b6760ff6c25dde2aebd28ff7700f16534de63cbee33cde83c579bc078bf3bca74178ce53b193f73c938ee93cf461329a5359da9c9dc18059f7256d760ff9553b750f39eaccf4256de6475acd578d2635a399341a0d883ecca49d7e46cbf1351a8ea7d150788859a72f69397ea4e1f8aaa1f001ce3722d781dc834850e75cc830eadce59c35ef66bbbb5b46e7e0ebf7daddefbadb39c76e34b294a0d975ef5cc05ca00f9248f3ba1d8d2e95a3919cd6659b39175cbc1e1d615ed961188665d80873ce05e7487434a2f4f1404f0d51a17bf4e8aac0238bcabfa970555045adcef9191327efd1cf0297cabf9d1cf74805e7a3552aa8d02ce88652c064fe438594362c1af8f03ccb7b962704618a31c670d18424545bbd414bceb80d822b2c18a20824b6a062cb755dd0922f1785eb829664d941d74086d03908df39e8aa7307c695ef58929793d382ab243e5fcf90e0b8f2bd53e8357eb94f199f5bd6655960b4737fa807fd3df770cad810be079f6befdde10ccf2d1fd0748dcb08bde7b4e63ce29e70dff36833da4a709f956d1871fd5cf76a726f11995fcfeecd65f49ed39a93e4ee6c212476f7fc9dbf7687fc9efbf3475b73f7e7de738e85d15602b6186e4179328411151f8cf17ad4654df95e7cecbe3d0641b83aee77497fd9314a0d7559939f8c91efa7e010fa30d53d6c908851dd6f36146a51fbf9c8bb40aaa8eeba185f1a9213d039d75f9e31e5f59fd9b33caa54bf2ec80730f4faf3b0a2ba477284dacf0fc4b9705d7f2aa18cd868bba1e79b3ee1646db4ad96b8f27d844e748adf08de9d4aea75b7ccc46ffa7c1ea9696e2696f33d95186b3c9e78cf6ace873f8f28ea66baeeef875495432d688efbfafa19d5b09b79caf8dcdb9ffb05ff0a094208a1fb3be773caf8183a67ff37833f3fec7fd66376eccdabc9ae84f8ce861f33f3004275575ba7497be4bd7fc3b0c2ed7ed7d6af7f6ffeafa3fb83ceb52438b73b498cd9fb87f923b13c6633f88319128fc0742b9bc11fc86dfbf0398be315cac34a7d73fe78f4ecc80ad1756a0599a9b404e20750d0efebb20b3815665140f942049cbc005e794c51618838ef79b8541452807efc91f4256747dc1757c59115aef5f3d98d866b6533681b0d773ebdb0f711f56e74ebce702756b3a8b910b57e301e56aabb4ed5cfff24cc8cc867d49371ebe70b65c9474df9a8969c04273ebe2f4302ff3dcd30aaa1fa572edf57b8647c19610022e35f6a501e3ff53dcf08233c018d61a32811c4f03efe039c084c90939393734790c28df686fe7b128f2b153e0dfe30689bf5395c973eb5869c78411608b821275e80c5a5d7cb66b8ae75651e63fcda422eebd250345e4c3768fda5a11e0aa2667c948c17ce9597941f3d43325f7a26c375a98d56be74cdae537c25cb25a8b371773a0250fd4f30be347a66e46df2a37cdcefe343cdc79293b8bb312279d90656452fc0ac12d9d7d17d8f2101d366903df65c80cd7de144ce55e2373615bb359519acc4c8a206106460f17100f69d3d6075dfcf4c03ce0158f3e08a20da11a40085bfb38138bd92fdca702d04c31ec3b02d62d8e85deca1b6656f65d8a328eac21e6561239804e7c6517c2cfee42145bdc1fedd4c976d18ce0f3c467503f83c5caa0c49468117d880429621275e9065c8891e95f3f8e1f1838abd7fff114cbbc1fe8d465f5f6664c48fa1d882239c3bdae86f173ff6504351eb51172a5a8f620b8e34be309301fbf918f6d71dd9243ce642bbd170b1f8969dab8ba31befdddda1bb3b4cc24097ff3d60a5c2e6ce8f55d636f8dedcfecdccdcdeeeeffd75eaf990de3b5ecd77a8d90c71eedbac4d435928898aaf992f379266082164763344fbec9ce1b29c0f1e51d466e6e6e77cb455e042fb5a08d3d9f3dbba307fd2a9f59ddf7f33edec54ef50e49220eeb0cab94918703907c62b2697ef784051f9a7fb7277f8cc3dc75e66c459432254dd7bc8fe45fc6533c07fffcfdd243ce66e34dc393f4e6957b8343f54f93c331856a8c27db1b30abd9e622d84fef517fd820856aeb430ea775b258917d5b6ec292af3887333ea7e7bbf8d508d72a8871a799c717e12cf6478943ecc9090fe88733eb2a79ab66df4df468d6cf4089d1685e47dd436b619c321ea4cceb4c16fd750f01a7938176ef337f95b4459f6c875dda3264ada23d745457be4ba7efbf275b788432d09ce8533bc0b3f094a06f8efa15d4d6e2aba1710853471c59230686b4ba8dbbceea8b89e85143ad71f6b213da7f8e927a0fce8ede7ee66f782633c78505dd092236ae81c55447284eabac012e66e29544700f45b007e1c5eb9f796a7e1e2063b4d0822cc133d869809f44ff8f80c010921e854b1c201500f971dd0a0074510d1865bc3013d10316b4c29562ca082054308c20b25c47821c1972728c10d286a44d1c4b5088205506011e3c74b0da09cd105162222c2c841107eb8c2c3b802267185db525bf0bbc97fc2e230301204cf10b614755144943e8206b420e3063d4c7a4044959fcb67d8800b283d14d1e5064ea8588a175fc4a0e20a1e19a4a1e23f6179513c2d3618a2072b2d708305338955132a2822688b1421ae588153a38a2b35b852050c6c90c6fc4109c640e20d276bbc4184456fe1de7da0b798d7650cc48a7a9aee9d07827cc8b92ec8072e178beb827cd8b9a616e27f722ecc975bdce0dd4cb7ff59b9feeeb9c8b92338ddcd0439393957c98964fd36f271b77addf55b7677d841c9bc3bc0bf34763efc2dadfd4a18e385dbec0b6f9d7ef96ed3835ea9843933b35542e1f6972cb67092c5109a6020ea2b5157250b2d455a7a2e67a14598cbfc8300a42bb752b94d5c313ab7856c3a6e982e6eff6ce7cdcfc1114a8677dd9aae6b2e8b989eab03caccccccccec9c0f1b4e2e075597858d25f7ba2c6b88c9b286976bea14f350e5304354b6a8286ff1848fca351d3f382d7e68324505849e368a54aea17ea0a20f7b9af30248082c2a0ad16043474523175de8a838089f221d159d46e8a0688a853d8d5df045133a2ad7763041452f35c068b2a3a2748d253b2a8a690973c61615cdae204215151d614f6331b830a248454948fc00a4a2958a245c2046454b56ac88510550661025c6074f3a5c25334e1b02ec4a7bf39ec2a7bd4c8e2629feec54bb4fccca8c58d63527c94e9bec08a5f3e35bf1e79cd3fd298d914697324a4927b526b55294d239a765cd1f4c5c9d6d99620c950714b4a305f3094a01d0182aa615cf1527a0c1032126c60ce5608994213496dc4009675051049096290270c2658b0f4649ce31490b038cba3d2e47d08111ea96c9f0ee743e8a704da9dbdb52b7f9450ebc2042dd5e175c6c31041c68d1a26e330b2da86e2f4bdd1e1642a8dbbca26e4fc3624510ea36abb852b709841dd4ed51a183bacd29ae74ca7d010ac040757b9a14efc6cf0fea66004cb312850645dd66907e27ac723ff7bb91202d1ca085165a60c100407eace0438502b440801ea901082000362d00c06a2d7c0a3c76e840e540a185138e1a1a530b2d78f302503230e026e1316d37145cb6f3a78b2edfd9a779c3f6d4a9eedaa6d36366eb2aa80100c3434b6d7e1f32a8bde4fa3f3ba48b545de445688198a22fb4387618a6cd224daabbff10023dc4a9a04b71b9b00b213109448451c68dff5cec2bd459b9fc4eca45d50055fd7c99681e985dc88648455a82749470a306439904b238a10932aab8808d32463e643923094c5cf093f3301c54f1de7befdf7b87f1bdf7de7befbdf79efb7bef592fc6e71fa3bff8de29c6f7e2b3014aa9f03620d09f3b3faff739bfdbc4e70f0b8ac231c6874f32332761a9e47208b0cbf6063e43abe321f6b238faca6ca56466c4999dadc81f7914ed898ff85ff17f4a4a2dfa5e7c58a72ebb9d6ea539acdfe49c73c68e335a156c8000010a42e405185f5bb7ecc30a2d575f601e108f6ece39af6b74716acee99e35634cc519e37435c668c24e17c8db78dc74dcf8cc8f999999996d66a718d3010d200f95dbe3ba201e9df72efd22cd04967d917673ce39e7758d2ee6ccea38c1e787d3b6c53c2d2c336259d3bd629d7af0f9a1a35766c421d4d129934d0a7e84f6758ff7f16566249e74dc37271b895bbd0f7e34f26c98991d74d03921af87b02a6b2288083157bb2e6827cc731861bdfddc32a1f32a695ff7e07f8fddafb04fd01235d4a892c5f413441b61f40c3909a30726748abcf88cb102d3bb9273c1a425206807402af652832a5354339a0c1815f5190d2713826ae64d1a0e4d501b674c51d1e004015533cfc3a381caf4341a0e0fed032b62543770de649e7f754bbfbaf55797f4ab3bfa15f6ab4b7ff5ab3b7f75e5af6efcd585bfbaef579707d216455099dedda8fe1ad62df0977e847121b2261386725d9bd19e83a36d7551354015cdf7ddf83241c3a619cda960103b405f30f1a2a8076989f3e1dec812d5f5078ada6191927bf2a43146e8dcf570dffd8a2877c396d73b13b41098d342e66fd99c1620b3ba1a436aba1b6fcca153fd814e75078ca8fc495c0a3e1356709f461dd0d856435c1a0eae077c4b83453bd7657840409b13f2e1ff6e0754e4faf33b9d5c91e414ac49ef76d2f136a7d7c1852e91c41b038b144f0d3450f031aa161df4606609537420a970f28654c30babb750638c48851a65bccb39f26e36b7dd95db5b9c1647e48a8608f2e2f61701e3f6e34074bb3be7f4277a5dd010545c795dd010519cb48cb00ce1c32d9f1f438e4c1a5d77b789c2650d31a5a17c976669acf5e6d7317eb672730d9a589133fa8344b07265173a57ce1ff2457fedd22cad9d0ff9537b7746f8fc4dbbf9cf977edd7ddbacf2fdc6ffdd1bf789391fd96dd2edda2905f8503729df13166c11b365a767a8723e8a749904eff2a364609fcbd67d718130846de5dd9c0fff66feeb0b744910b35774492043a29d912062429704d8c8b9b003e7dc240cb85d736ec37ed75dd921892bcac9b94a64aef5ee4ab06be9707b87240cb8ed7cf02b8937f60ef195c40cdc4e21090320b05281bf5f489c72eb57c2f7bd0d8c4054f86084a765274bd1982f3e18e16ac0144d90c184284fb0418430acc8c2c613c6142154c5ce1453bce184cc192394869629de70c242810a95a12f3e30f1854f0f5778d084225630c58b25a08e78ffd69c80514e10e7c3a99c0ddec3fdbaef51715ac8c617e73dbbe580a570bcd4f79b0b63029c8d7bb8fe0cf0a9a9cd69e1a24e35aa8688e3c6bca18a164543fc958a81fc71f0212b95d3e084eb5fc3077cc853f9ebe0431c90ca1d05210d3d845d0074e5050814b40233329f20264feee688aeafa08b1c4fc8e6b2a484cc2b40b81b769d161c3e40830dcccc73ba8947126ac77799059e2a5a1c1e54ec63b3710e9440eecbb9ee5ee43ae0ba2bbaf23d1a6a6022202ea122dea3896c01c25a2ed780598fa5f881b8ac6519c87bf0c580f3f1a5eae04364ca2043054288c1921e2caa7e13f8900724a5e7270949b49103553f0e1fe8e76e547e4fc11a6f108d2103c8883482d64042070a255009638479b9a85e938f276a009a6004215c30c51369b440d55bf08ce959e30a2831e881f643e5bb0312bf6e79b8ee1675245e7fb7a7eb034cfd1234c18a1d00094144194550f513f1211b172f80011451988125052ae78511d2e891e28c160ca10c557fca8770008a2ba4b0e209296250a4ea77362d5b62c901543426065ac47091b3c4f4405011400461065ac44009152ba186194f7c004483237680b8e6148d09420b1b53a618d3c614c20d30cc58e2091a742182288c7b029112823004298ec8619223457201a70409a1854a162690c1c5e5cb5f90f8f587c1aff3e004b87b6ba00102ec821608f143143c187a4244118a90c1143ca0d2041fec4c417988caef4a10892984258b1390b880b284e192c5093a3d20218354b0250732415d77a9dc43de336f7ff98360519d8adfe788eb827c985cd7c5754149f0e0d2ce827c38c847cb656626de732683fb7299d079d5b3afb3948dfd4ef10a51ea5ffe14bc9f3cc0a81c3fc29843ea1ae9797dfebc29af3ec4891992620c2f53a01c41089c33c468230a2cba3882122a1574011a62893078aa204185012b4b4c71840f8000420b546650d74242c062dc1be7ded970159622a68848a887777438c7bdebb1b9c0ccec83d3d262dc4e42595bc2dc52b7bf8b70fbab94e6e9435047fa3a1f38c10c312aa80225847454da90ca7de50414803637f3d5964f77ff1eb77d3142f9a65b7d31a5a37fdd5306ce87dbd8e9a0efd52adcddb7e7efbdc7ce9d3b771ea672a8e44d7745b563666800200000000316000030100a86c321c1589c2792e0d3031400117d964e6c509588044a94a328831032c6186000100030004343db2401d0b2dfdaf659dbedaf5b312437231ac34becd7053d9263f89f5dba30c9f726ebb09425b5d0e324ec11c41984c6e491c6c701b5a0561b7260ad6aaf75efec6918ab1c1080b124e77df65bd2d10331cc86fe1f510a5e75384e2046bc5c9867eed1c9b4319dcc2a7047951da8fdc58017d9437efaf09098a4d5f7701253b72f3025a8ca492a2499b07dea387880fd1626cc480762d18990f3f7ac239d2554f0adb75591aab19d9ca5b1f28de03feb9448c7e009dfe547d87ccb49ef0d70e48e332199f2b79e7975fce5eb2a671dc3d2ced3152819927b2a57949cf9f732e1fdc5ad957092104201bcab8ca20e2edaba5f5052470f748c223d7092cba2fa69120dc66b3de6c29416c61797c9bf652c9af985b4f7bb9b3f8d58b6b74ee6c568ff3d137025870d588ce4747cadb9f62ec2198d79e2ceca55aa12a23e0b8b8aea23941a68f624a7a1d92a2a21d4511fd71bf15ea2a0d4bd4994d25387ee71ab27cb5b4d9b1fbd0cdf63d1641ba10a2fc8721602bf296dfcb5aae5fa0414d5fef00deab90437e47adfee6aa9d57855c1381682a612729652aec36b42e7f26e8972be4b283edf5743b24b089bc49faacc527cf12399a54cfe12447075a9b5800214d3a7ff809e31113ab25ab5a974d070d6a82f33a9d4dbf6dba05ed9ebd16b0b8ef4566c2017624be1642b2d30acf90448e4c2e8ff7254e7261cc7d144ce969ae76c5929a9392b2346bf037babce4cf2a66b8013414cb75b3336ae713941a4d2d3e94b5b5a5713d5edb63d315ab43644b147872b11e323c483e7614fefb3117704e190f7b8f9704d6383c778ee556f1aee81e69c27b8105fad40848ae191fba294db75ba68cf0f73af2f82bcf7cc4ed055558d5c0413b521e459b216dce68a0b05ea272331f6e912bfcacdc5a6ffaf5f9b1a88eb630530fb73c99c1b7b8d7b46bbdd72408eb54a82a1f8984c8118d8da3a6040091a9c3343bdb1a53f1b01c855a31e0e666e35310033af1ec957275ae92e28be5740ab079573073dae2f6e2020085118652bb0bf8495197a5338847a1414a198ae5ec54177154b8fb57bef1082d6578928db166bbed1f26c5c8ec4ba779d02e2dfe77679117f55d44f465c7a7cd30dc3b2611978d6f967dc9934ba0681e32ac1bf1965a8b70f9a8c497e1ad25ed6a67f90249917be2cf938f7793b15c268a294c562ce4ad2a443246c43f793218e2414ee7ae6eb6152f1d6b002aa7db68916afaeff60d6c5e8ab18f27396743c2793b00a2367d2c4e81d077c0a17f93ea6af457dbdfcaadfadf8a223faeaf5c312bf5fcb765f16221f5265d3a1a3e567a2ff85288208d579b262b467f7817c5608800ff67d33aeacc61533c87e59428a9bf4a928c1860f19c9d45806aefb16a0e535cbbf25bccc8df2f782c7fb73c61b025c73f98dee1e33fb5d1d07fac86ee4c39af04fd289715695555cdd705752749fc0eb5eac8fa0dbc31641acdfbb01878e1ae89e8614367237fe6aaeaad6af6bbd921eb93a1e3439008789c0c6a462d589814b8d3e3b77c92760dc588f4ee906a912991b22f0e396281f9f8deafa89b7897fe6514b6eb5dc5b9b59a55635a4eafcd53eb823554bd03fcac8d773b9dddaa1ecb3ae68b7385c143caa1dd629c6cb4646c517874c1dae5cc9d198fe13f2b1b2f444b67dc09021dca30b9548511ab56cc42167651f8e86d53008e5871ed6410904c84499cb132ccd975c10570703080ff8897040afdd9cb86f75001c26505464be43452eddd32e902aaba3a9ead8f65b67fe7664772fd365d47bd80cd6db71c0d00bed663e8d143e63889cb2f671c7e743b8899e12c6140e134e7f340dfed43d7b4f7764ef0343ea3ae9e9cfb697723d145f6bfe81d5b48a0c9bbfcd0e42371198788b1d75b09d11c172b0a7b708278607582e8fbbe5afb10375b52c71c6532dcfe4e8efdf9553f596c9eef1bab0f2c61f2e22b1ebd95729e35a76fefab7ea349d445c0ec5b1738d0a908cbb87045673ee3b4abecc191185eddca092fbf2a0d7a8034f3ae8c10f1efbebe5b8b7085af078beed3e689ece7d53b6457a8878eec857e8126f9f2170cbaa9fa998e7e6c40076c76203086959b109f8fba0f4563b50fa69f27dab7b807ed8324ad5ea7f2e57ae207c1353e1d5188e9611e8b99aeccf8b15e895c13dc0b997c79f236e9e4cc9826bbaa1d9e8a88608a29cb4d1e12352af49d5c1ea83720d3b8d4a8d899dad02e82414c3c4f273a0bd938c9664d5b95332f921ef61e61a3afcb436150b1e4a09481ba285752fa89b9e4cfbbe5349ee507238bac54f527915e75b2fce39e9d70e7a03f28fde90072bd601cf6a4fd998bdacaeb191eccf409073d28786591a4ecb5748d00051f50d34a76acc13255815ad6d34044cc0f8c75ae7a9fab8a1adac8c0ffea5c504f474d1bf011d835547293c60b02f771eeb10b3d37b6e51f224df80247a8a2258e2c583e2c602813f71d1b956bc5b48b1360bb650ce87ad1f7efacad88dceafc97557540e1dbc8efa3db885d692d18d38c3dab1affc60da925b9e43bd4e7e540199c1410fcd9137111405f0e4cfe014e2b581b36ec6f0d7e51655186a69cf2b56ddfae4a9d5ca4ff4a0410cef6b2b83ee94522335ac6923228932958e9fbf0cea3c9af390d9afaa89f643363ba3dbbbf65ee708d6a8600bd09df16a4e5eb2355eb4cdea3b071c00c2d9871a3b0b0a21e4a9f29687f7315833213d864c33e91c77c2337c2dcdfc14eefb74f889f408e854fc7c977f3787242a7287a0a4fc8f099fdd266c8dc6254feb47b8ba29c6cf8efb852343101c1a19046f6b8e6ae25af5339bf98c35120f9d4b9d853b61620a12a3b1a502fcc2b725ab204ae20628bde608c181cced2817d58297b96f7acb5cbfa9f49a1ffbff359d7c2e0bfb70fec3670c4d84141286b6d964d3867e87c5ecef90cf93e589088be9d88532ae317101877d353a513bc2d4aec029caf1271ba3a0df82cd30e06706b27d456d32cf310e035cf64add2cf604e969beeec00e20f1123aea8ec01a263bf12454a58ede0517eba7886bed95ad1e261f372b7473303f7fde0c18b0bf3547c1d54fdd1d08192ded3ff0c72bf4bbbcf20980b7c4eb9eb7d53bae9ae8db13881d8de207b9bd00973c10b87b9f1e31cafa077168582a281df4c53a30678bcc9c353992b6a6f0f2ac4b2fd1f34b1764a7eadaa1b1b311839a9abaf0e22aa768b91a8deb84aebaf85cc4a5e440b994b80bd0ee818dce79bc6927b9b15ed0c724606c537d50929c68fc26863b5ded397c351065e235a5ca4b799293486d748d2b84e7064d83873adf38e3612616152ed2e679d0f926d53f9522b23d5ad6e1875d7d3de104e85ad42e79d8759ead4ddc48e476aa48beb140fdb358e513a66f30e41c1b588e8da2447d760809a776bb97e0fbc6f2d9a43b9f2d82f90086877139ad6dd0eb98ac88cc9d0c71fae03d19f9dac38d1f19c42612c2fd493d71e488057f5eebcbb8e8c639eb533aeb0bc2d129088694f1c8b44774183d5f595784dcef5dab5d5d29c894ab511cd46b1e07718466fcf078149cf29af272506a4fa9dee857144f25ab45cf3ba85aa72968497c090d26241fd1688501c24feedcf74d70c5b3f65638ce507bbeb875a217fb5069623de1af627a47b84326b1fc3cc69193493a0048309e324923d732fbb3ab7b4d8e1c0025b62242f132fd221a0702133df244326ca73a08ff0e5c75797f4d97e803df0d512b1c2df6321c1752d9329aa425a80e9914c55651e08e73b49c1789358034746c187388a744b3ca9278411f8201625f4215597d8a2de997f994f1ccab747f13d085679c6dbdea3f0d0e9eb0915aa193853e7b810bb8303fcf2acde643a007957384e636979821a865ee3277889aa8bd16a24a0e4f24f1a026968bdcdae5ea716f9407f71cc81a8db5f952e0d68e4d7fcfb98512b06fa8246eed227c814fbaaf033bac68e2d24d94f3e1694fabe76c7e5fb018a7425efa8657465345099a0e910f844a3e8f25ef753879414e3d3789b9fd56a741029dbeec80d0fa371cc0ff260a6261328e4a656b959ee9cb946ea54c4e822eeca0224ec0c12e4ae344de79f43ba8c0bb515793e8a96b7b424af9af558113cdb7a1d5b9fa38630aaf4d1980dc533c158b8e1180bd6980172abe67d396bc78bfede9817ab69227662f8e2ae275291061c25a77d029fa0b1d551845093a01a3d26baa58b74a786fb0c716487fd4795c0b1cab11ea1ba1f3313b8397d9c68fdb66d916c870f290333a901d48a50447bcad814b551da9cf4d77f4274434365899796bcf9bd1b2fa4cd1ce3ac95b389d7d10a67c6c05878748132f04cb0682dd5edb4326910f558f04aa9f54bb8235e7d37156124b8a080b08f4a759fc8e9b67ec1aba925917995277369dc9635d26baa7e769805e724ea9d2f21764fec740f46a95937e2bdecbaf51d90a2d55513d5d1537128ae0022bfafbbed9fdbe15f43b0c07a906529a90876e33949789cafd555388be0eb041dcd8337d1efab4058cb6b27f1fe58c08a44e1e09a82e0eaff09d15f922d26f36a9b7f2a711df597a856a4aaeac671141f785f4f95e60802b1798c9829ec4f30ae7443e76a677f34edd9ab1bd7c85d9fecfebd5b9d543898a865e0eba1d6919b94ecc5f6a997abd0837fdf6f978f326dd8c1886a70a4a2a0030b35f87a3017ebf3e8c8fa6ecf65963a2d942d5b3225433fee00b262b26de4830ae7020e4f86b000e2b676ee068cc7a93515e2221166363dfaa79a877d2d98f4a24b44da7ce1a12bb5e56ae4e1424c625a6516dbd4acc0b2c43ee3725ea58addc12b54c53170b748b1c84b2b1b35c725c0d8bf1d9c44576dc212fea9037c8cbe187d02b2d188724a919afac49e91986ac8533b8bdd3718ad8f70cc8d399e435091a0143432ff262172ff7098bb33f659f92cb4bcca4e9a2d9882878862a42bef9368f86c20c1c67b48ea47fa0a688bffed32bad0211754c358e0484e5a194e6a0aaa686678eb9bbbdfc9ac7b14d6945cd1d8773b3cad8ed6af8e51093f33bd53115e76daabbf837744c2c5b2f5f0bce206010bbef5f382107c69e7e188b517b736cad5aaa2e9cd4795009dfeb08dfc103ebacfd7b65a736928e7cb134dd81f89eb623d61dc809bb03497277a0c4ecb38dbc2a525adc4d7d5e156d976b6a801211b25db8420f6cfed6a794548c3101409a75b462d3779b3cdfaf849a30f469af7a60da9488ac0ca91fa9d7f6b8aff0f1b2951b4e003b591a5a1eac0099bd3c3b00eeb87dadf24383103f23ea3b430f2d781f18a77b6deadf9ac7270042f77e76e2de31bcc105375a925ff7584428ca0706ddf13606569800c51c061bcd6857cecf75b5d769ce41d7ba19ce26a8270fdfa0e41f7161dc24c6f286dc85f0a5fb5cfdb3b0f5bc327a6d62d07c525396d1b7a624ec231c8030092beadc0049f765ac63da1d444d3a41d7956a5a69462171920bcf223a925fb4e0d3e3cd307318c8bb1c7384e7abcaf442596fb7672a23a62fb87db8524976293c03a3c86a7628ff54de31591b848c33fd5445bc469d0744a6a6fef251878ab1bdbdb87ea895b974d2c290dc2ae1fe1ecc49349aa384450c7b022a493d22b65f161a0cf483987e9a896f4dff86bd88d56f55991c3bb0faf65b87fb5bdbb6f470c7c4784812d65882a5603d107af00ac610c5a373218b75f17ef965ffef11248eca0457d1266232bbae3ab0a8ce59d88da49e1d659bc52a32692b76483c8393ec5b0331825fa2b95991a6224808dd76e6055f065f712acb3d4376e3ffc647b0e7e3133b0ea71176efbedc5074d3f0b0913fb4459766d5491cb7d7ff1fbd965daa6faddce6f8a294f2432e5617c7792ccaeb20a79256d4476611b6c105b8ec90f528dfe4d033a935aa572da1c97eca277e7c0b5d6e12a0d93c44638fc34b5f3ab154ed14dd60ce2bf9ac6d72ebe64482952a8adfbd8fed65626b76c1eeee1c9b031eaaddf95c6b0dfbc126fbb3707bcaaf1672b42ac38d1041822e1ca9dd8be428d98d4428e98143352524889d1e9c5ea52d339f8c05e88035e8e2385810a1ed291226dc86e530e844f3995b7aafb68943cdda3734a412a97abebefe1ac48d658662cab0a61729be67b60e72881003afaafe8fdf5dd4d053dc2d0ffac7b4525fb0854c501000e838231dce54319c623b4e1301b97e0f2d576f1cbbf492dbe64564060d017ccb4bef868c64c5299d8b88c4303b123575cce23f4276cbc2f39a85d055372fd65bb35f92be2a163c9fc874830c485a6e5824f2e6c4f8b630268f816981b05deaa16d79c2389c71e28ab8a2282bbc37b17915b03d133d22a47074783fde3e7adfd08d0e848c3d3de83685a1b682313a7e42da6293df0fa7e970f85140eb18a2100510e5cb1174fc869c3206b0d7841ad484fae91fcee28a0e98bf6141ff9c9338f2a88e99562861a0b6e5b60fbf1482f57ffff1d6900a7f08909e580dcbdf28712330873fc0063245ebc4262ecfaba79aabff13c70bc2de9168cdfaebfb792485a584edcef47bc2e1a36aaf9689bc6ffe8677a11dac5168dd36e8de63f9c65934b0becbfb144fb9405b6945e6a9003690625630cd0e49fa943adaac278f88cb475c17efd172c916b2526a0e9d83ed760ffdc438ba01f764dfdb2210e7f3c0ef13a9aa4b28872da8343a4b6ab373594179d46c5c556b6d381cdcca5a5cc82e9bd5d6bbb38b8b078f206aed6f4a2100a72c22ff029f7236e87b17159795c4a94969c956b6d08c65ed86a65f75cedec0b0f64b3ad40a276f7b0b91742b9cd27e5a57eb7817b42d7b13f6350ec4afd41dc06f6a1dd3dfbc60b11524115c036466ae1e006148832482d7c078da34f8e42fdf5110062c121d1eb2419b033c48b8c6847f8f66375e9c2308948a794abd0532d30cc61ab0e3a82841933fdfbb60e62d94e63d6186ba4d33d14324c99ace1631f7f9bcb4f73e66f6394ca781405b7f63d92b7d8c6682f56819bdfc40e6d1c4bff247445c73c796d35c6bdf76a672fcff24ccafa703962b0f0ddaf2fff215b934c82e4f2a1c7cd7a7e1b0e0710ec2bb7f6d59a90c97ffce9317b04d2e74066b55c3457b4ded935b09e71fac4e6bf10a2767b11d73a616cce98d15e1fedaa70570eb0a67bebcfec6b67c3ce45a12e06120437f3ed34aefb3e68975915bf85f546b2e492d977ef5dba1e5b76e21a51f153af966e1729c4cdf40a0b02fdd292658b3a0785cdffe64684bf7bfa084287c7e84bdfe9ce33814ec2f5be1fcce8dd9ae7a81bdc34bc5147e38f125915a5c5d2309c50baa4ffe7baad5949862f9b3e54e4038425b948dc3e3e685f5e718cc72a7c24c7f93b6366591aa01176c9e5709986c8bcba64d4f65b39f86dc06045ad81ba5a0e4b3505268ace77e84626ea331e62fa992b972d5aa26563ab300f77ed4326815418e4d3b00b5bd0596bfa9806e05a01ea1103fe5d915bd8ddda0eff2902e930d56d69e76269f9769b9a6d80133780ea7fc9d600afa8a19bb9eb45dcdf89c30163529114af566c811e3708c905520f66f9b488ab7ed5a2f042a8643446b145656287dddc4b4e2348e64ee8509c198744449dfe7bba7e8abc01599310b81df1bff76ae55fe25a6a574a1e89000aecbf03f9e5ea3d69322ee3c8f9f2a0455e4f46330fe43ad2f0d57be672d876fe8220d724e2a7a5f16c86a3b6c3f38e1c4567838ce40b4ac24d509753e31ae6e2eb9b514fb1c902c72404161b5157a580e8d2ecae7cde1b6476ae46693861d0e57bece4b239b4092f8b54a9f44fbe04efecd834c6f5bd546ca8a4e9977e249f0c4db440d6f0a5bcefdc08c2bbc4958733feb546103b1f779b14658e86797b05255e098aa6e83524e56325c0f84420f16171419c9edbdf473869ae06b9b32ecf05a5b874209fa7c0f95b19b011c20867bc80a7799858915e4db0225aa863970da6f526c75294910cce04159a30ad2ca8a731e2fb58eeb9ca6165effb15bf6d4630ee5993249b6b35b508a4ff22d623cb76502ff31d47646fa1d68b850dbfe6ca3afdbb6fdad534d7687ea79e0731af428ddf81a33ac63a885c1a08ef5bb2c62666451e7fba46b2f27318224a9a8d52b72886e88331081001f6e4fe147915ac417f4070345a494199e544193fb713033aa2792599242dcf8318c00a044924253cb43e24b61c1cf63834890f8bde10078d94d1d61fb73cd65e75ff89a3d0015fffac34b150b1760f2957ff5695d59ab1634dfb113877c4ab7eba3a3033634c10226e288686097c1da7d650be1f3cda1c84b1cdc9c79a5492d52f64e3e53452720249107f7044ea6a9511c4d809dbf495d5e1c5ef0092957e42128d72556a0dbf844c5b3edd9009dd7a5497a0af445509a3a8d68daa0a47c01e802b48a9640023c2bcf8740e02666343f4ba687c59404f141eb43531156e983005d0d27978abbbb75b7c8519abe245c8cafe1e2906b892f3f17e564dd039779c99a37487d795495c6131765c85e369b7225b59c114532af32ad4d0880055d1d60fd9f8f09f57c7107c424a9425a29df42123287fee69dd54a8ef7ed25eea8f12d7eaa11c6ac58b135d5615af1dcaf0591090b1d5a9060aea8a520464b48d6c296e8806b070b6971325dc018b3ad769e167f3ca5f160087941dc0be761b269ce9ac12a51f406d3503b3594ac3d18b1e9432d9eee59350f9b41c7cf92baca2b2320262e8d6d990d9e8c1fbbc1f1ef73ca8dc32ab77f185fdd9264c8df34c9e6b2d0a446b83ef5b445bc0f9cbbd0a197b7c98cee2dea9ef1a6479a2ce52078fb452beb102b2a83e0aa90f8993fcf7ebcb6d7833c2f4b23333d1a9629b5c3354b4e2d2e912deca486802f5cd409543a86998c5f6eff947da508b7aa74ee5fda867519ab385061ad2624d1a0de549438bdce6ab24988e3cbabacd11499273d680d02709cf097c75050e71b98486a049ac2453519ee559aaa29a6f69d0a8f0d108f8d14f9dc2799e5b1eda4a53712417bbed873e30fd717574543ca5efadfe8bbeab3c5d1a4324aad8320a06262737001d9affd567939aea1896e14dc9e9f4a9587725ddde690b548114856201ed707169ce113bfff78f9486af9cbf9bf545d4463c07f9af7936fe123dd3b2f79a160febcdd87234cc65d63f92c87e5f49e98c42c83cdc7b7df63276a63e0ad5c53e0d8e014007c91ed607367364d825a39520854c95d3cdb7aa4d048de71550956d0cf0ad698e57a353ae0836ab5760f4eabca21ad7383385a735343685dd514b943713a2859c068a1b614c0da93489c8547e6c8ab66a864ffc1c7a1290b0134eb44d14f9c87449b025b00fcbc7af2b0a1f7e9f39e910c0d1777b0a755ac3b54efa699b29deefa92574928159d3838d084a8004c9fcdf5f8bec078d68bce924b365b4e45bde884e33beea74383f1398a8c062948a66f9365b3d7a1085330e09ddc443060c27c1dae2d61d96842da0b670532b0acb1cee20677d25230808618a0b924da905822656037eb74d84b4c4894d8071f25d8eb2f35937740308fc5273a1b40af8ee989eaf294364b2b46761a9464a424d1db9b6f41bbea927e3d1fc6fe9f322862b6f04244e492c277d10ad35e5d7b7768e613556e3d0ea8675778c929e97731bc89d2d46d66dda1611f2943ffe49d9299d7c3f14c9d26c49c260c854ed4e662813c4ef52fb41e4ca979bc080adc678d0834baaacf640016fe05cb18986c2bf0134080bf9994476ffbd1cdcf8867e6f3176e58f9fd071227146cc6abf5e2801fae89ce80486dc05141f4841b48fc1d7b001db303f2fb790efde316f2d436a4aefba65ee9226a48fa65d54c9b0bfe1e974b55eadf8c61fc7700e15b752f4a73dafe33f267d7556716957054341d23312703a703522293f285f6989c219e43938c1ea160c47fee380dd404bd88309e9811f62ff93659efce8c0997dbf2a86d055df2dc2e27ace3a624596ba784c614aeb14a1d8b3942aa64f86d922509bfdf15f82be831034ef86e67d5fc952322671d9ac2e7995cf9e73b31225ad403eb3ef8b96658a03d5156e7da85f9c42302f04377c0bc604a2247e3a37f5684f499da4804d9e5312de00d91d9c70a812502ddf7f03cda1b7fcdbcb1a20bc0206b18c3e8d1eda736a8c143e763bcd4662bf67cfeb2be1f998c974ab808c344b6eb49ddfdc391ec513feeb15bbf986f2c57513496061ee57e0eaf6270001a0db15b361d936f6fe9a372b8b2d6989edd6a78a549cbe4d933c84446e83f24abfac5cc4c5c394e5cbf15bde511127f5f3841c88a9ab13e11a63e2baefb80884664253d9f5b0558385d5be02860658280277e37904b6f7111decdee9da0262d53230802b1f2ee445cd2c2ef4311fa244d76aae2453224263221c529d212388c91ce8a9f9f180eaf0fe652245f1c06eb5a278ce9a6eac52e908757a54885a9ee256f224d2f942b10f1fb5083f7a7b916b376046e916987d12729926f8651d0490c818ee543afec0a027adbe2a18f1569737313df00c0920d74036109a5b241ef56645aa075d4c5088e9d67b24e868d8b741f458411fda9141ed7a6909a81597d0d18c1d253c8d21d2d2d9ec844d66b14cc19d5545a25ce1f84dcc299c87c90f36e7b7ff3a086160aacd9b426f5eb1f459a64284dd019722ae62fdf4b8bcab19a951b114af4f79aa757b100b610c54c257016f936a7396a267331c554bd989c6d79ae3bbe0ed40b283e848120b51c99f59c41ae6a1eba79c2c726dc4cfd1e740083b012384420e472833ac4a0f07603f06ccae9f083d0cce09b625776623c9d24babe82c1a74fe19e385bc220c742a3dc5935c788d7771b10f987ca2e19d8f921260814c034dfa7056a01f1c193a5d4b974a88ffc2d98899b15de7e3490a647e8df1716291f003e0eb4861a28dd9fe1d656cc69537d4b16151945b22978f19588064b246db992f480f975cbff029f041e332a580f1a4b29a6006d0c2563642ebc3ceda580da4bb79f7aa43587e1019c208552aa0bac4baeaeb3656047a470f3348081f12bea5b02a22694329488e345d1d4dc137740be43a3acd38857a296ab0c5fddedf9bf471058ed4ef477c0719a0524672111a725edb0e11b9bdaca9898d56b2f1640353bbe032ab32094941f74627d41d7cf25896c98a4b2a626ac62c94517e1157f57679481f8aabea41b963c65f55572a3fdff763bb4f4a78ddd1583c9fe98e5e84625fe5033d70da2fcf7b14f3727e953c52ad6a92bd48b8e5a8679d6254256cba30e1f0344dbc9b894fd65d73729170785bdd2f7f0a139b181e48ad28dec864e99454f5abe86a4d7b238ac814d1da9197d47f302f8a38318bc532c7a24189aee2c2f6b94e509f0d68ca1ca568f152baa7522f527e42f150413bc21f03ece9a7242d7f6af58a137ac3213403dcaec1fbeffe5876e1aee9165bb0f2be77189a52dbb418acd2a78c21c27dc14a3cfe7fb61092c804c17e82d6de6714aab5028f0b834465c0371ee78c8daf9cc64150a321da1330936818fa63ed5eee2be01c06c43ad6969cc8f06e55614508851d075a91e1d875b47da99cd82c26a2b80107548842af111c111805afd00d4257867d95fa64c8a3ee30a88601ca8264c1f173a30a1bcdff158724e65a976cc51b56b4f7ae8f62d6ad0a55bc0801960b2c6bf6772a1d5429d8509dbd7926a0bc82ed52d2b139cac5d09ecd96cfed02e2ef5daccce65e26dd722f71a336f20ac125342961646b68656e9d42729cd18495f67009be8bd4b22946ae8ac2f059dc307d29bf49874c00827f092f761e1b61fcfd78a3853247ba60257fc3ce2228edea1eebd4e6b93f4129454449cd2ad083af0d04097a90f79f69ef7d24b98806199aebba88af48e7cd57bdd26c3fa09e1608a15e4414307dc4af422ace2c0a4e5ec359b58c0f83cca8185a6b71b05fc0ef33400b5c372d60f32947bfb6a303cac8b8fee488214310ae5c05d8ab00c00e3a45ceb72884a891189a80f634b51ca392e020770801042679012801d5195c95fc817e81320ee548caa72b30757c5e07e4d1fd4ab7f34a425acb3a11c16c43a2dd19d83116c10e6b1b06ae46ddf7a2867dbdbb733097d5c12f97117cfb5b33ae42995ec8da4154b08c34554f2f8801df92258a78e3e90c9d23eb667a97db526a9bb5d6e40240cfb157576772008a8f189874ecddfc924fb697a44adb189eed870414ca519c2219b4dd41bc788bf8b79213c2e22c38956e8f51426560d3bedf1b34213e0980e603ed3d1875ca5178453ee1d6631ed480ef9e46d1eb2be46e5b3edc97c79c658bc41171007b6d3c0ea68e76b3b498d7359d8a3b97fe26786ec3e1b233bd0ed0859a7c3f438bfea85a8a3d43cfdea9887cc339fbc548fdcc5415525b4b125ee84c44ce5f296226f30af9f14bd61680863e5cb5d81f0f1c83869a05832dca6b47611a017657ddabb7dabc88dffabe63fb07119efbbbdcfc2108a2938f718230ddaa692972b68385dbb0755594191f1e1b0a10d09d65258b383da0bc9939f7e44d891c24ebb9eb6eab7cdc57342c997344687e4abbd4b3d84d75be207718f923631d06ca4e4286580f177df4139fdf02982d9ef53f8dd489a90f487727febff3eef4b896e3584768b5f43b24aa588107171f68a329a8830fdb006be6ad30ddaeadf6fdd5201f8725ff126d75e71af7cbadc28cd18eed669dd1fef9a8caf42cfa1ce8f3f26ad6470dfa2107af54d84936ac606738e8d18fd706c648d61ef37103d760ddf10aa5096cb55e1c2638bc3d146c894626d4286b57045cde57f89a8850bd84630cbf1fb25e9aac786a309ed757299bd7f2fda73972b52e18e26d9995faeb98eaa0ab9fc4f53751edfcc96b31e71aad90ad33b1ed2b1b01a397748ca88f0553a97469fd1909b9576aaa8add28ffc7dcb34078bba836ec1ffb20e061603756650b2f5bd092a526a4cb93733377259812b73c1666e5ee6bdca674423d658e4f66c76f29096b3ef74c2cbc7b3ab7286a269a4a8691dabb27a75ce1eac81f0489d06729a997788930361cf7286eeed80a22fb6faa2304a23d2345d46447b9692f2c68e12c4c1fcd99e0dc81ea5fbadce7a4822e2f1c228f2d6237ea68ea88fc75f322776352547c55315899d0e5170ff98c9518a0bc72571e6f80610e12784c979e2c0c6934e040b9641c5e00f631ba5772d5386665d96f104c380d2db9fc14a555ad808674489c4aec69f12ca93b7f75e8f7163ec3432cb710bcd5e20a42fe247c4fe9199776c2930961c39afc42d59dded9f2d2920f89e28dcb138715464276b0446a5725b73b0cacaf3faf25d4a66fc4233bb317bb9091652989cdcf4c40fa1213300c3df54280f7071823f239cac69e4052603981961e748071d431d55a3e5229cc29d64dd029b3437bb928dc26899f644ea163a1579e6ba6f6d6bd292c4caf01d80717f6501c179a20ccd9c3c924b1a5757fbe046de2b8e3047497b41f54d152899f36c1a828545adf00ea8199360ca30fc28544411b18c9483cf7c87ab944b8481e86c0b73255e1125b582608140d4bdafbdab8faa75cfcf3d617350c53c3fe7689b0c2f1fcadbb2f443559ae087f40999f6fd9ff7e884f2dbaa13b4920914629d88fcc30743df59b293adaed4f4b7eab49e70150465cd5c277dee2b6e5a252ab37251bde0ebe4f6c5d5570bbfba6de2c8fdecd116b8994b25b24fdcbb961a7bcdef920fa2e2f73235cdc1f92e9a7f53159f0755c29398e5e4dfde12ec779a3fb2fae1130430c99850e77e69c4d84ba49baa6bfeb456dfb3de4461ee1655d90ee772a22947903f7ed696cc2046781026ab122494022ccabb38176fab080064e808988d5b11e5bf4011a5165fdf92c12e94bdd25982eb62db37fcae005c369e3cf1aee8ce4f1e70c9c34a89cd984c746c3397ebaa5cb72b3b52fa3ed2d07135b1a04ba351e395273e7b1f048bcbc8b07c731af04050795aa6b8f4b30b7b18f94dd04f5b03f1b2577e648336a85c795521efd2f670767fe7c55111a633db43846bb40c716188651bab3d919cf7629e61832b088eac77510e984bc5692e953b36426b64f2fadeca1dcdc075de89e265bd540f3887ed07099e469152960f39d5e8d4f90cd432438d1eeb056f80ac6d26fe9c5246546bf3fff34a8184ed4d1d956dff15c81462e51a1ce14567f120673c01f9237e1f646a9331853bbbb61bf90d77d37bc5ed544feb13c39091ca1d99d52be5c8ce5510576320137948250046a48c08fd8830a9f64fdd89dbd590a77fa8d03efb3c6b41d35e3e6a1b0203c5cc5b0281d5348b27c77852108b947bf2cc4f2965bf944cf65316affec360674d0fb6028a788f2e9663ecf462efdb81410bb39d57a884c56d8b4ab6b34ee1f77baa588d0ad4abb587ae3c5d0a4632bf7fe0beb79b99089a0a76b4471681c5b8ef2d2f5492a1b7869aadf385739f939a9fdb499cce33a04e520fdbe0c99c3a7d5f8b1d09cbd5f7cdb26b6912c037767f55be2b7543fd969af7927ae1103fa542592ee3506ea0bc1a7a6e283b5aec7d42ddfd5ce62b70dc035255d6b2443158bf2f14487f49d0e07819028fcf852e391602729a11b3afa36b25cb80ddd50488680c62a8f8481a5a5316e4aff49382d923288f8c58590fef7a65ab4ea268f3a1e31b89eae4265c8eab57a2bd91fefb98bafb15cbaff8c2f6c790cb453953c8f136b78095d665df9661715ce287dec21babcf6f059c29eff786325246b9d410d6a380fba941c032a2c224126dfa2176e52a5c076ed8054566b30403329cd2ac3a2e08b961ae8eaf355fdff6ec7e0a336d64b63fedd55c859299dde6f72b9a35e83a00bd00abbf1d5adcb123318d68e5c22ba5c538e9742145dc7df79a5b2e093e8829af78c61dffea9ca4c36563d868ee7aa5c358b3a47da8446e73ff9f1cc1e240f11204185b53a7e80f0ee75ca0c55d22dd62f0ab5da09440c433e44eef6b02809518481108718dcc65c70c24c3f85ef9c496ac6babce7db0edfb1d3a0ad09f4e140829b93f991f39161d163942911acdeff570812725fc0086d0797a3786e7162f9e09ee7a093e87cb5efba667bb0da9cb5cbe89b44ad4d8b0f3f5af43bf051bbd0f15989e215f034968fd17a4702121b779bf82e8331fe5bcf128c2b2f521082dfb3b672097956e302b21cb996f38199828cafe20240c0a9acad9adeaa9fad8a331cf65f0aa12981bbc0889c1c8e60a8e6609c58b1df0490c410a28e3a95598e86e3d9d2c45114747248702f5cceacdfab66d3cd4979acdd89d9d3177ec54a82ba6ad7a06a9ba633f17a712119d8f7552c80d124f722f087cb1f8d3397011ac0e1c8ca95b014c029619a088ff660433e84716e3919821cfe7fe00514eec058b0f5c32b8fec9598e3dfca54905a226317850bca014d4c8bbb4ddf516c08b6f14b17e3b3198c83a7421c77f3f69513d6ee68795452f89c22e1f54d2192f3ec8e3845248160c057788f66e0743624965d4ca4d5f6c59bb76ec3cc4ec1cf0af04105e00d95e53b50d652c1ff207d1346f526385958f805a8761368d29ff912217e836f7b1a8741288c18fe2829bed20fb39cb226103a58aa9f741e9ee42c036fe4505ec6f163cac09a2df7465ce7c1a266c2860c3235e43ce7fa00e5c84cd3d1859bb1c131037e0f28cf0802b5dffc1dd33940eb7b996b9ccab738da875aa3a98ca9eec14dea3c9763278aa0885dc9e83729714e38f992555ad490dd062f895a21f9a3bf904147be8bf671ee54c6873f0e3e3446741eadcc1da069908d12e66f2f1e7c957c3540f1d87f5db6dae3e395c40b151447fbfa509c8f1b94646a2bc8c652273e7ed29dec33df3493052252b6bd7e4db95d07924853a6719c24614d1c9f6d58f7076865b6388d8e3bcedb86d33b4cc5eeb3c96c8d11a67555436cf700b202f8b115d294ec98e912de376436e82f6d939b661448dc3940f6b8090b10d6ebba889b935792d351ca80c37c1bbe8a1e454d1677637befcc8905ada70b29a6c80fd5b33d13073b30df53fc2abf90be118b768f85aa44399e9c42179c68410db49938e53d5b9b78c35b5608338bb5b4482c0d814393b1545e81e5cf9647128e21625a26d9dc5220e462e09a7d9adf9a1968b2b576bc7ca0ff50575919a5bccd5589ab996e6fbc6d808f5c1356b10f64750ae67ca4d03890c66522c33d71cc6462019dd2757ee1949a045af9cca65dd722f6920cb888fdfbdd85cc82077904d98a7ebd60868c4505f4d4c9b711b406ed7856476fc86bbe489c0ac26ac6e06a4a3a26a24d4cc2f93af7d414369219c8d246d0860d698bdb7d5d0073a89706662243140e476d37c86dbc8336a1b65c1efab9c18a272bef58fb850bfdc98c1722f2e136c39d0906da848aa4f456ac8e628e12bce6d8f38a41288390223819be8c53833b3a31bd0d23b4792011d6cead6e15ff7524dc30038a3e5c71feefff206a25754c0e62c4582e2631ad4d5e6294d7f56aa12f581cd3242a4237fa82940103c64701dc71012bbc1174e6c0603f7f36a920a060483de9204e72e529d0a06d659a9eb6a4c1bfc1b3314688579f9d05088a39a11abd3ad8b6b893454734b791c008e98c9858d1025b3845b2a60ec85da62a807a9a32884460ad518efb2af340b81e35e040a8266ee9c6ae75e3fca1f788e100c1484594df3d21649ba102688066582f00ac2e0fdd45a6bf85886e2e30f84fc971cdefb71c1965183458efc176c6502a02028547eac50e9615e278848c6034bc042b191c8bda1456690ad50472104e5b64f447891f3bdadbd6cfcb3c494f2f6a41db1f6121a4498a2ddd569d2f023a5f82e20a4231aa43eb88e06431461ae43c3a502d1110604e6a41a8eb0f85c0f8737a434697dc1110aa3898c7374daa73a2157808e047e121de1efea159257cf5c528514e4f7efe67e178d5592c2cbfd2198577d890dba1d34bcf4c21179a24de9e925c80eeddcb2e40d544383a3fba152ef49d5ea1a5862234913038bef678a7e88e7c45a213f7ac28117b487ccc7d7043d29fe553f17f2b953bfd5cd59bd125aeb99020345e9195bf1bae112e0e571c4f355cd5b917ca3340909002a54920238c2b88cb8d1ffe6705d4129e4b27711a3546847163c5a69813df49a09a5c56d6bc3b5898db891e931d2475c9488bbce764385f0800038dc81dd5993119645abf0188e81b09e10fef2e2da489692c090c5d967a631207d98982d4e54b85617766a854755c7ec26a8457f48214195ec2f23216fbccf2f5d7bf24e2cf101c7ec9f3e534ae57da5ee6e83f9e45f45096c58d7a8230d1acba9227cb5b48828d5e223fdafe12d3ad273058140266103dc1b1f0721e107dfa1be47eb45622b28743dbf1445f114a5cb7b6be308ce6d766cece27c9e3d1b1bde8f0817d851291a82a898b074af9be794ab5cfb4e159de3822cb28ad1d68be6a55d66fb9ccc5e10e9a30f652782d858c98b0fb0273f286cccf15175c2bc6c8661ac9f638204b94f11ba1b8521937bba22008555cfed2b29733f827570a69324913d63668a96e7fee044b7fdb28711ba266a27af030f58b971070024fa463906bfa4155166c02438ce629228f33af06688bfe7accc1577505ae9c0f55fa800fa932735ba36bc30423fe2725eb301c066b9899a0e0efad3fb6eec42b3007dcbfb75fbedba6eb5f1c74dbd89c0cd6d3f4ae4c2d14156e3a3c588e5c8db0d2e7d2ed47cc6d826b80e2b177534a52096567c13916023bcbcf84b76d1555062845910dfa47114839a3114fdc4ceabacf1cc2acfa0475918d35a4f061f4ed6c6b03eb5b257aa4c6bcb633a8f5b1b0d9b8674db3b6c55feae19d42ad7a45fdbfcb342f9d7ba12fd37369f86d6447ff06d2d06e3c029f83f29f20c300b8ef69c95d0cfdba994d6354eeb6106c66c99c0193c560f5b44127ee018f12e2c69458427b3073f68dba556702c31796c644d91ddd6c0a5e0d64ee82a663d259a55e60f16d5b6ea7e9c6232a762e901f61421cc5370b4a60061bc060dc1516acf28b3386e6aeaf09628ddcc947dce0b625edaeae86bad41d48e52ab536c04b8dd168928b38a412d9679d4730e79c24441f1d06367bf7039f191f23aed2d3c1e894f0ecaf948f80be8f366d4708562b9ff1102061f7796decf20858c24a395372a51e7358393ba86e56b0ae53235f5a204a5f43078e64fcac49cff04310a1b8e1668e310b40fa57e92a46f3e6bf99c66636ad66310bea5d37e4c466422cb7a0af11c602b8a55459f5b2d5a5c6dfab5a0b36616a5fde7a80f29556e0bb127271ca9f02c77a16839a7be6ca24eb7eb326c17e6c592f98506c74bf20178ab830f02fcc018ce1ec1c96e76d7028419213fff024d3fcd6994458b8f1f59b7c6960719a0b988b599c498dd12e48cefedcd2e54a3f31b79d2d44f076a061d4564c2e9248a3800329837006aeb41584b8dfd2db524a6cda4292a4734868960d2841f322f4681f1fa793476a2ba51c52220da1b154eff9116f8dc831f985440a8fad5703dd85c0ffd71c61f3603838a101148738a6396419edfab1a73a3673d0ec449d16eec5fe84b93c3062b6d5e03027c2a20e517396198aaee311c72911c019c9a5baf3cfb1dab124f47933885e9fe26a9b9ba1312a89a106ae8ed32f2dec18204cd891bed1ddda2bd786cbfab1ec46ed14f42cc98cc5d1149fddb33bc64c0f5fcbf04742f2a733dcb6439b998d5719f2ff3327a4438af5ff5bf5c19855357345f6b2e58c256bd6959a65ffcd4ff638b8602d5bc7da3ca7b1edfedaa1f409afba3cae9f2852a832dce89cb964ab8396a1776a064328b1cc5a1632e67ba620867b57df951f795b0c131c80866c499b5d68dfcdaa1dadaf5bfd6d579b9f8d81e0de1366559a407218ca54f9f673e216893b50e1ad9bc4567063ea16e3011d623d378ea1712d13f24597eb42266821d28309b1237dda73b44adb83b017e507e4f4d5a276360507c816f4fa226a20f085a7181728a9bc4e0238759e467f8e718a3fcaca690ae9f1220fa3422e9531db21a7ff8278716c43599fb7a5c709fc8dbd3a5c61b14023a7917d33ca6be210db55f96a41cf8fd090452480f4e93ad6d8489fd5b0a4edb22e460423a25b26a15ffb424376c2c4dd5fff05167c3d201e7c8e681f4536fcd3c86527e30b30f591e900149be93104e3e081d18a0c9946d8378e7186b632f3cd9f29f04657fed0ae5bb9cb6fc32752dc3829354cd08270826619ca5d8ed26f751c68a5baadacc96316a60d635c837164b3a7d9430fb59d8005a08f226fb4852793393e3766926421a755bd8878025e4ca129f261b00dc27c53c63620ee2c9c01f0ef4af15895a2432a54e38b3a2218143ffeea571111f6ba523624613099d4daa97ceeb662f9a22e207458e7523480d427b5503c54f2ec3b337d4034985d0dab8a73a8a0acd40632fa886d972e4a3452f878c0af6a0c86c8ec9dd4034388bb09007e8d7bab7763de8e070024ea4af688c49e3108fb0a4ced5c357a38a2eba805136c7302b0b4a6aebbeabacb5fd7b097ef3c2f32d8e68d3e536a43a3d3ba5140970fc7205d8d04d75f75c740d53f582b1df9ad85fed4a9453427c62cde5ac0638b9f7b41dcfd867beac9b2d365d8f069f125c4a0323b54d78dd76b93063366963771dc3408c37b853e17c002cdea1dfd663af0372847e4c4bdb26fc38a39c08d6ffdab94e5f1bea08805618772f12d33b33915401dde011ce265427a1643ec85164c5dcc50dc0781f6946112ea976260039dc24eba36e6202afc59231ed289dbee3797fb21d056a1eb1f95ce6920adcb8cd624b5ccb477d0f3ddb1cc4c931b314041489aaf09a7ad3e989df04be1caea35030d107a9ac15a3f93c98ca809f72d2d48b9d89328f35e1c474dd6a012cdeac0041f4494ce92ac071648a31358024a12c47609b4a98da4fe6d4f486abd911aa19f44462880407d238280d0ac6a83a88181de81fce6bddb47b8259a623383f2a31feb9940a32af918fd27882ece8365a0507bc1e8ee1fc37ddcf57339280e8117c90389d87de8af270f6e8d9e9188ec275b1f31c487dcb4060e903568f134edab38393937002412f48bb43a171f2e29c0cba600d7d1c9c7525feea02a81bfd300271284b17202d32531234af81e33a84ba88f402a0aa7a7829e044c7ff7b66b783fbaf921d4e5e6625e050dfecda90a5ce34db2c293ee634a37c648f6c459e8299977a8553024e369aeb49b731e91951194a5f6acf42e0bfd3a94777383ac9991b1e707099e421765da5d458d1baaa687898f5f0d51dc25fb5105708f6ddc722e0b4cd1e0a382a033412b4f87cde0918069c44da9abd45125cf0568eea829349632a8a399bd015855a061c6d07fe0a075cdc8f8093d800884eb28b24656ae2d201bcdfe3c2486d6b61f21f7086191545c0e900c71605043ebf1d8fd34a511534718fb78153e708a4c666fc2ebb5704943085e33acd9185ece49acd92198cdafab5a5b5ce37176a94be2b4d2698ed42667319040d82ac319fa107d5cc0044b1ea174d126a989fc650319a1a1a2c08061fbd99a11e6ba51ce3c353a9a622a8c9efd27dad9ba0384d28b9fed20ca42021d19cea20067d40933f3c33d43240c9a12f500459202805340e49479b13eeb42b26cec4a2d9006dc161c50d35930875712604a019de0788847d8e18dfaac7cfdcceb840b741c9c685e7d59c1dce37bac52a5c0c5c5d04b893be4c82114ce8c6e3294af3552a22ce3f3ec09ab522196702e912fa7600f7a8d21c9ddc45adca35badbde6afaf7060832681c47ea65ae3726480b2c5fc83b2a8c6f89d9235d33a5c824c73dc4e0fd8b6deabd811e210dc94d00e17c1097b7a09ce4cec98defe04d0aa4f49462591abe00d689464087d821ec873b2c94b5de15053c8a3ed9cb67342c6459abc820f7f39eb4fa02d36644313e351e9cd3a10da334ebfc32c7d642da9c3df02d719dde4761e2168cd1a326563684168cc0c412c010bd98d8c8f54720e028f188a64815a37b059377ac2a73c83e949ce44755c2a8f6d09b7d683ac4b233e83ece902e1fb2f8f03fb3bdd6c48ee00ea5d5fbc7382fa1b91d7240579664ab21577c51ad17f216a0f41e26b8f2ffd634eeb2a5ed09147707119f755d2831af94ac5dffaa414f09fbd77c5c28a16db3459f9d52065cf28e80a1fd01a82aeba4a34109275c08020ae2c2533304bb5b322bf6ee5873c196549be48330c2631d14aab7ffd9d2a44062062fa563e31fad4ad199c9c55373be0787b9f8935c05dd86674498fa9992ac2b792efc50ae7c1a9c00e574c98f52a194fa876c5f6df731ead7f9a07dd62d3787d967a8cd36a05d72c7f83a817d68d57e687a083d165107ab808331657b379f5d0ee561cb1ba34fde0b0d0c1544d34f348321793facc4393d174188ad2c1edf09a7a5d459fc5e85552e1072499f85adc77eb8578105a4363643b3210baf22cc9442b644ce8c0fd620b202d5f7d70182d879fada7af696651248b68d9378f5a49309663fca799878ce196532b8f4099eb2c972979157ad1eb7098bcf51a4ee4208460528c0af10314ebf74f32d63f0e992d2456b566595e7e1c96ac231385f77cc18b68501a7e2872794a0d3e7ab8369a1d4c0433e0f0c505bf257e7e55ab39dbf7d003fce376a95fc734505e3e14045a07fe2b5d08fb00c6f137a0827ac81008e142598b303a3514b6f1e145905c875770d7a349d9f6bd9e4a586764c257506436ee984d964b503983c549164de5dbc5eff02e6314ffa5a5f08b1b953f30a744104a3e302fed9e4e4c9f89712fc0fd57ff5c46e1295c136d5b3ea7a83e9d6061d2abcb5f10d433610ef546819898aa4910c5231d7db9111149bbe3ee3f4c7efe40e25273160a920ac788c020aa5b5905c08093c8ff7ab8fbb1db60c601d47b3ffabbd5cd0d4abeed40ca8ec1cc737e0bd6690925c58c7705d026f7e1517db8dab1f3f615179fb359fa86a1c2102dc7334505a13552be0d9ed83b13d5d3f7e116c93f43ccd0ffa8402ceda3827a48ce205c6955eb0666268c89127bd1dacc7fd4ade0deee19f66b912a42cbd50056286a9fd644eb9d46ef0c6a6ba0172c3562fc3c0b765a25a411ed420022a92f2c7ccb876e7b01821a0122c75d8c03108853362db244e823880584028338eb2f731e8cbefda137225218f1039cc29a2b9d179bc8246bddf915440ba9e710481ca303749ce79c6c706f1a57a68d54d7cd7e6254846cbdb26452f87f5a7b365063babea17cd9bd4331ee0e30670a3824710c4360c879096c8e82430990552432830510aa850b4e96e2f8bd8c342c71e9bc26bd049a63c9aa4e82d57855e9779ab5e1d7bce57fd4ef3a45465bb3fc7efbf74084860b42a589c80cef0d827d02f54bb619aaab05357cc2e5daa75dc98513483830c4279a04e48138934727003d18342f749924a604b56c318f8b961b1423294ea0b06a6da44bdb79e22b1011da7c28a00a4704231b6ad61b60298dfa19ccd415add9feaa00bf9298bfcc74edb5fbf3f66d02d4512514ab2b787db4c907f8419babc4bdd6b13aa7e544bb222b30d65509a904fc9f908edf72ae0483df76e3c1516300937a313da4a97f08a7efa2c1632914354f801037a00978777b9d306ec63e6f637a21bd11a88d7e332eaeb8386c72a834658391a5187d66dd8fce66ebabab50e289e75290cd8d8ed523bfd0f34a853f584069731494735795c80fbd618dd7dd9b12ee293161b46eeaa47b2b723d3199165f35319fc2414be1872666c103ca92d2230db15839af085b3e3f40964e801918d1a772170286b4543c5530aa33bc3c49fbc85a65dfae0e21c065902104f418be6bf727d1b22d90b0a6543e07906e9103d0ddc1ac60655458c1b4287d190f48405b0c873e2cb58a7ff804f5b078eb49ddf7d0b75bddd9d1a9410a832fff491e855dbaf98ef5e4543acf1ee898c35da829cab504541aa4e8109400bd90cecb7cd1ef730628dbb7c0a6a364f12761ae7ba45c38ae2c85931d2b6d257873efc3876616e84f01544a93bc462e42938d4d6b4200feeab0ec6837a0164a2e73826f9829170f3e440074f63f7c10b98e17937848c30417297809c75a16d30694f4bc08cf5de6a02de9d1ef90474a5ff1b760d9fa202154749d4b610014931f3d831bae4d418818ac09e2c189faea36f24c2b7502aea3742ededce83a393a042540595622c95edf0f54dca0d3cda4bf030e33ac03a093581f65e14b367f5eaeef2a93f5314c15ea923a8eaa67783633d5154f62628dceb54065c3ba471bae8631cafb843de611d1019cd27851b5e7a28a692e010ed9683255a3891eb01214636c9960f613ac630d6b31d1c0e2d06f97b51804c4174accd96277ec25a464a69552fbc80229eed0bcfbe1381b2346dd91d84eec61a3c3478074c0388b504aa39b263f4c0093ec8cb5eb250a3ac5753600b0c233a30d5890eca3449b48fb29b73de771b3357e3cde68b0c33c82f685bb74da9d952fad333042ed3cf0792a04980ca1986a8442d2bde2f695a0731a0f7e7109fd0542b93733e081412a27d19a4733e4e5e45d1432e69c4a3155cc1b1f9cef8121f84fe947c13992cdea6ed9e81ac1304cb10212b834c938bb4ec4c04b0ac170db0316107fa2fa20ad5674e4a571a7091b7d278459a1c2e84aeab7760e028e7e0baca157c5c01548cce9d4a6eb50b529cbb244645e91c0f5126395760fe2e48ef35ea70760f449d47bb79655e7c0ad2b9b0e280421eb7b4e6fa1608aaf3e44b7c6f1e42c109010092b4b884692f305db3871040826d045694989ebcdd67c0b1bbb942788bb867f463ada918b0f519d7b663188b40283cdca386816879272b035dcfa1efcad31c1fcc3fed19d7a28684a78eb2cbd81de6cbf12bd7093ff372f98708486f11d6efcad5e59eb28960ca31a0a6ecd828e905509516d2adea3c3539a7269132f95d2967b7cef5f38954ceeffa9b1e35d3019c76ee0417c14a00b57734f82db7e45bb0e3440241dc2d9ec8ffb599d7861fec31f4d21c14f1dca47fd35b32afed8fbfc791bb6949ccf21f7b40866d8b64f01f797a96bf42b6dc87298c497d1c5aa472f0947a771cf074ba0056e25c7387e9c308cb810b110965aab212bc777b4a71316c2123b6b036b815dc781ca4aea1e2d096dffe253c3f8f7e6c2c146a3e6e790c58e2c0309e2427482483d5f9a5e046c0e2561a41631b21de88c82ab5256d462a5633220a9382d51193bfa72e2e760a1086b16c69d521b1634d0fb28fd380f0b716957b10238a0b0d2dab9c9e3344b32bbb1600039ad7df9d9dc54692a9659a471115b8743d7d434b25e65d5134b2b9741387d255cdf6a4d58be5de937048b61739f15c14a113a9fad66b8a992ea520a26c818ce0d4b919b283b8994c39d31531113fad0d0480869047b27f35c156c0cf942e78c29e54730e278fda211069d97db1d0c17243415ebaf04f98711bf9f3d60473886b2f909a8c7df41fd4440dbfb62b37e19f88deb27a0f73e77c22b67075be918499e96daf490141729881f7495e5526b0ea9f84d00f3ba8e4b87ef128622d0002c553ad27ad5ca6082093e346bad2728e65b96b54ba40f00f96d352a2a55ad770f7a980a428be2b8de590160666e3c338c8cfb2e01bb77292df82827b2b133b79ac7d45dcb27615b99c96caef59312c2992447a9dcc0c25861122d5e21183301269b64ef19bb8e120b1937270094306cb43a0d00870b772ac8922b4ac6b8198d5dc58a1a3c0d7a1962e7d2d75eb3ec782b71b6318cdf90c47d7c09e6287f706c4d7eb19312c4c39234b4ba993d791a7c305117298e321d4cddcdcba35a998155eafd5cb901d1e317c0abed5bcdea277ee38b980ad22e887595fa075dee3ca5eb616a93e1f0ebf8622b412e593149b637004baa4b4bf7fb12084492065b93186cfd1449f9b15a0d1f594bf3306987a00a766d672768e146684c9b28df0af65427b6ec7073b3b30dcbeb311b0e3f151f2f71d8f88c79c6493267500999e21c5cbda1ab340812c6b9b1cdf9468145d9099b8c9da395755e571f0c1407974997cf7c26b6d1a066cb6c9528acbfa164023e88e5c0e92a5c0dff4740ab7b683b97879308d179480c6cf00ff7669247511ca44d102df3b2341e12aa0db5943ad4e97fbba3dc7d2938db020c9e7fe63e2609f02cd5850eab93dc6a809d424c765e51c2c7b695eaab1ea66971a9164643921469081dd6202f771a079aab5f815a084f680e9e75283fede9bba36360bb20b2b346ba546274a0f93557277907de54e9ed28197c0e8e8c5847cbef38b94c91f814143b4be338d2651d32fbdcc63828f3ad8619edcc310969859ed15dd78be8a134f8067160e29b8d34129f412de98fc31c12e59cd522395ad611bad4d7c5c6a0519372211d70921f0a012c40f28090334177b0e7dabc101593e0510ce406a395260f1ff1054db35792a7613919aa9d62349e263a9e3a2a7dc2c5de61e08cbae0fa23c889f62815dad29b3405e5dad8ed90d3fa1103f89796c2f50e0d36a659885ffaf2c0a980b0c7e7a628f69e0accb0acebb90bec8fac5aac796d8ebb41ce630d5d4db4122eafe9fc02a44da5cc155aa652d23f313bc94fe61cb2b3dc0ecfb8015f04af112a56d95225ec0c7a986aebe2cf5f43ecf82b31bc663e705eb301ed2d1381e704aae355ee2bf786c005c5a47e3e384f52001e1db7df57a69e8c9d8332b4d217708c58b27013843d91b8de07764019de30abde43c983e3369d21ace46d629879fb8f71cc2584889ae99cd47abdf543b819a8511d50cf8aa9849971ed1d417a305c54df400dcecabe842d956b85a42bc126327331088ebd32ab75bce881a5f1f615cdbabe008385fb654967135bf9c7c95c502eb789d7ef0ee67bd633836097fd73bf0705b973155b97a3476a9102bc82226a8fc2ac451dd8548934653f229904d0f226bac70882b2dd01f57c5c2e477f326494a2d26a82653abfe5c1ff71c7dabb3a970f4089000fc76be38cb2eee372389b0d67b7c408bff2e83b929f274f5e893ddc941a31b5eadd70d10e3b141fce1eca30f9cb300fee8f59cac74e5fb9653d0e99af8af31934f1e6d98abaf69e9570ae84eae397f2046af98b172e6a9e84f77c67c01fde6d153c8a1a6adf54c4a39ea1b76cfac1f2e2670c659746c80e5c65205478b3f570d5d7df59248f4a3bf68b0afa8d873cb3558ab2a1081868bd194a1d9577f512c3b669b83f08e5e7dbda9f942ba0784632736906426a99ddc4c1a367f1751452bbf92ae97277369a6606b650ac181baf2de018d40638177f886bea2dd6c228bea6edc8a2cb8b5dcd263f175f57cf3dd3f041ae1f9aba7b9f89fdeb275c0f5a3cf913b1760fc805217dd679a64f58ae4c351ce6388b70169a111696ca0870ec91735c15486e698b07c61ddf4095059cf7984a233f44a982380c7885843f522ef9d439bdf2dd00163114033c9d3afd12b8d6cda811620bc7f4709c6cc0676de01e7f39406bdaaea0bf711c4545d30029500434fd7c945ed27f716308c94faa65b4a480c31d0dfffeda25078df1947952682ebb8e2e27a0d2c426055019b686eae274fb73ebec3f7ea06dd4c08f58ab087a41ef1547dc3687dd7b0197d1ca0cc4f2dc75d4190482202eaaf987c202467aaa8ae0f4bfff3e9ca6e4b6f8a45321b2807eed9ed4fcb2dfee0372ac8a3c2aac818b46e6c23662a129722fe3c7d47ea87a97cf8eb4a0790d03356e3b0acfd39b07de7076396d447b3fd9781433058045ef4b4dbdf549c1daf8be8684c45bcd10554561e95229e3de19d1cc71233e4e7d80885d51bc5a64b53cc8a0443acfa57221011c765c6367dc2e5d4cd468ed09dea621b93b4b399e22ba352ccea8b1b59a8472f3717d42b6d79156bd547729de6566fa4f1feb7e2a1e12d2191be044b280c5ae5939bf2431cb61671488845fb5f177ac02b6b9b588e6c8e0c01e7500ebceb0e243ebcc2c5228bc489c1fefe25dac54d6339275236616d0807394026d70c4ea0e31ac49605378e37ebb686bacc47ee981935e9a63700738d607f8280a2c39896462f974f2a877101b5d5061f0c748dd8fd06cbd092924a54f2ca7215ab7108105bdb578f3adc1fdae7474bb1c3a02cea0fcd1018d7c8179915db0fcd5a6c30ee5048f6e6eae305587e8a6eec459abf1eda678724384420d9f73a9ea934ebdfcdd62dd3b905d2581f782c7eaa5ee2ee4482e576893482683d8fa72600770766bd88f914758196b1e112c928a6cf23eeb97c85f6abedaaf80e79aa66a38a69e9cae3b8aebed64b58131856e40058b0ca016f507dc5e00bef5b13fe06e9919648af1b2c32d9d0e50d065deabb70d59f8cc90b3fdf41a9a27c978133717808b42894b703d03836debbe8199d0dc8d10a3bf202aaa42ad9d4db31e6fb9300f876be782bb73004d3bb029a360f76c6bbed36c8d87b04ccf9e5d4b3cc3bca2002165e8f40b40e9e5aa6a70d999fee6bfc7215b7d2391c3d91423d1a0492e4c5ac7f099e6a2719e85e81fc96c647550be6483ac34cc37c7f4d05dba5fd5b580917b31959f63a44ed6c48d0e1fd3826688f7f6282fb5ef1f2381f435b6e8247971b03890c37c41a5f2b127a90207f318d3692d313550f5d68943c0800825d2c639ec910c79b9bc20d1cb3c08f25622f6ee849204e1b6fa20c0203498eb82e0386df6c7cbba521891f67f4098ed12822d38aad367fb6f18aed1de6d8617be8fd23dbd0531bac00cf2a479ddf0d7cbe05d3ae292565df4124af2f2edbe268e0eefe0fe610b1f34cefd226012b86de856ef9d7f5ef70157061b28d92cd87cce0a6b284eeb0866df0a75cae2ce7cf8f9a9a5bfaa5cf563711b518d22aa7a2aea2c0b42989fef821394ee8fa07536aa94fe4f992d5b94ad797b1d6f3e4840e0cb602280131f42a4914748d504782e19ef5600e3ac23f39f5c4ffa750a6a38e39bbd7091c7d9ca7f06e2f38d057b58c74759acc572eedbea6c556a766851760d1baa12ee68f64ffdb0151b26b42232e4d5bf18c076f3b5261bafd71936ddbd18ad070be1e2782a6d2f2401fe39a9d42f3a38dea7436afc7697452bc2da826ebbbea71d28ad6027b8cfbf738296b81652bdb9928276751683a993e439c02e8a604a6d562449ab7ce5bbc572cd20a1d4ae3736c757e0499ba692909b25e60199686887e02f9f2581cb13ff23f8cce879c6f9f9b7e5bc8aaeb88dfa780aec24041f92ce75fab6078b9a3069b18fd9977abcfbcabab31574dc9cd62c03bdfe34ca78c9f1db30dc8b6b1b178fe69e9e4b0ffb67b58fb731f76a9b01d53b1e6338a3ec6ebe2c3fc87e45e77ed98d0431c978c293c1bbeee678eb69801c35687435ab22a1c9906477ea93957a4040e0dffe274b2cb0a7d59bb456a1e30909d8ef51457600e9d6660069a9a742ca77a9d851d613aca32da919cdd780241e095473227329a94d795d832ee2cc7fafc3a8dd8f03533330b451ce899cd46e0b81330c23e68794670e48f14c69c1f1288dfee6ba769625ddef77d4668608148244aad8e7208fac617af10e208dc9ff715b54481f9fce5b85ba53008741a50907de90eca94de6dca8c39d36fae2cf0df6bda64be2d01950594c75a45279551bfc5ffce3ff40804a4c8e9740a95213b2fb9397f83f1af2dc54d3a05733b084cde97bcf5826d59068f06451c36a318cdfc0ca28887054df7ed1d05b9a1f65793a0512e6a8fa359ada93e40be996b6f0785e75171f725ce417cb876536119698475fdc520e89b2f8eb59e04cc07588e6b4e0abcdab6dbca04954bdc7fe13ac6d33c3f8d2e2d8d3ac8d076cb185d42b6195285641af3ef6a4d83e8674aec106de7cacb070600e86172895406b3ebcabd0a40e2dc81ac0f21a94a08ba300e83cd93f0157aa0566660df53913564602f6fb1125a5f7cdea7a9fd6bb05615533f41d7ccb0e3eb54152761c755d565e432eb9bbb071851b04e170b2792f0a6cac247705b2a3fe30aa86c8f1e5bafb8be5d0cdfd27f211b549642ea610a42f97f0418d5eecabe6c8154e68f49735e04726342bbf2a0f8037d6c3cf99c77aadb35572598bb8590395d2cf6bc1b8b7479e17d2e90529198f7c4fe3c17b67d3fa4463bed24f4f7802a5ae0b259eabf81abe585f59a8f4ee5a5a05f30f89de7e9620888d45df03b5e2e37b3a06608a82a995f628f086cea058aefc7d7d5a77e9e0b5bd71e0bcac8fd0f920d7824c256e40fa207180e631f9cec123efa0c8d90bebf18427df7c529345807ef7b6f090fc002d30308ec8eaeca0684fb15e266a98f0079e7b690283504170f3d40f8b04f1d7a094b7c0e62f040a407a83b4677261969af3eda796a2bed57e53a586731669d67948d795858e0fa627d737d28e80170f2cf182028e0cb494086f4d4282276e8dbda95d7d00b02808b3cc01b8b95b906bba1986a1ec3dbe2f879e305eab5be0bc3f44b2e0d3a68ac930ceed773132082e8a05c233546d43141d10fbaadd590f620de4079058e4ecd8b863e2845ea561c3f2ea0e8cb00f381431c9a495d0ef8ee4b44a8f6312c7566b21678f30837919f2069388f863e549309c51622d0b7640f3f48873c91dcd34ed29596db836cd3760218b0b6c601e0246a43ff07f24f7a486a717c86dbf3300bf0440a0a2e1afa022d211771ec8a42df4c2c4a57e7fbee09e44a34022f2bfcfdcd7cc08d65e87e4d6a15828c4ec1dd27ba9f47f2ff6bae5286fe1fab5be92aad653ee49a2da3d8d45779fbf8c5466aa07c3ba1713eb642a894c9fe45d70690444be76ea574014803f6e1d9a50e36b41f954534a20c8126e639781c4dd823edb3208acb7241cff3babd4df0654a3ee474cf9a519515174a63a13f5f198f41970bd53f311ba849b26f5d685abc50883b5a307b9c07637c6c336c3fd90468cdb3fd006e32d18990006334a564e42f0ea63e865ca6d43cf6757d6d3c32771105a66b52c52e0d59c8c932fff8fa1b1f8ff58870c9836393eead25d5ca5d1c5aa952d0c779cdb6709ae7948783d41ebeb177d508d4e3424a588e85e98c65b5df7e4ac2457f21d5d68a375e7a1a17dd49352019dcfb40267e43735b84ca0f49ad007ecf88eea536daf53ae2393ceb094f6c9e75d184d443a4d0a6e878b950b5b2d6d28c88568461c4bbbcbe2d3b3277f4bc16bc9c190ccae856a850fc387eb90d9c4c457d8a6d33ea7a920196da7c0ad9abb0c7eedf6b9890ca51bc2e251e2a81a5cf5040e8caa6886e013c59842f479f92830e9741a07839416f44687242e6a03d0e0991270b2e6c399f8a7fb81f1d72c020b59772a4e5034d8a526616a0286783ae6a4deebdd19ae2c16f469005e3db60bc5217652c037c07eff42a6895173ed75f1db7ae10eb95af07daeaf9db568d29946933acdc7498130ee38f5f9c4a4df8f1adcb57b9c91f32e94ff91f0b152e24ba2ca4a55d03475a252e6d0477a9dbff83a08b2036e69322d08f6d04e636bb0cb8e753b03f9402193d274e06634e21c1c2bda61d770b7f455bcc031fe4097493edce3b55f96126c0073d64fcefde5d14c1f53a66d77b7b036babb6580c60a3ee85b516417786e6adceb99b0ff606bc687892e0a316b59ea2ddc5d3b31350c150c510f7f71f6d9cd4dac1203b7eb8a3044dd39f57464658ad90688244416a015ed02d2fe0ccde7ef3135ea10690f037de759d78f87e10f0f6203b9f813aaf486224b4329fd48d4f1bb65da0c2db2b3a0db669da838985875441825c46e706a923f1c451a4df3d457838ec21f7568f26670a947ad0df2a7cbde37be95a50efe820edb73fd4fd6f9180585e6f2924be604745fd9ad31c16fe735972316eb762e25ed9fef102b5eaeb388b28a9369d4e759ae1f728573945317852beec846e5373b71124b3dee597ef6ef773c0c6e40ae26a0f7419f74b2aa5f9332aa073a245ce2fa7f8cd463f5cb462741b7a279f71b2c58751fb84c114f5d3a185574e1bd8cc406930fa10aadf2cc96d4e41a2ac4fdd5537deefcbff302137f71f076f28d6b7e725f57deae0b08e38ac7908f889c89e0b58febf6a706877e4c02decc187c345d10927dce9d47400965f2bbc0cca80039c97ad70706f2ae1b4c221c76b7076b86200953390eb372d96ba3f489253f30b4e5be1178841a08d09dbc1ab4628ac815f39c2ff640154aee3a8816a70c08fe46779e52e9cf2b5e1e3b510035906327fec2abab4108f4f507f81311e90d44ad19b26c4b45cc72d347cedeb96f02a797eb3e8719cefb9b3193f3d2045c65f76979ab384b0ad31b9085124232996b6666df90bbbe65f28e16604499e366f6ed34b9c609d906f56337e03c00498e1cd11fc5d37c27f61fd013300a64016e192a4483f0e3e1834601ff346d6a21064197d721a89529d6a8b529ec6e96c4c7adb616f5e9c73a802fd91c6d7cc980db0147df8823b8fd2d846e8cd42760dd91c237bbb57d415e37801ad460497dc888b3dd6f37c467c9ee4921e1b4e3587c4859d7a8e4426d02085852049da8d4214d8c48b2371b32588b62cec87b74764ce36a4070808065b22fa1298853aa2343a8ecb22200fb423eac5dd1de0b7b8537b9fc1ca2c98039d519fd480aa7bee339a79d918e5475e7063770abed90174f5460034a5ec00a61679c051538b1cc04a87a97efb33cb17b731c22f31391e4b4884e166a19c3608b656dcb0032de58e055c8e038aef2e9b551050c96c3a96d5024ba305361c757a9aa576bf9a5d55a0c7234f9c11732742d6afe2c5ead19e3bebc079b04f7f5ecaf1325ebb660c79ca54185e6699748c1d61e2ded6bd1807f0f8d3402da46dd96dcb2da59449cab609b1096a09f7bf211705f0f7bf282e06e0ef7f445fd167f44df98e3e2a1fd297f42d7d563ea6efcad7f461f99cbea70fea8bfaa45cbcf9fbdf948b0df8fbab9b8b0cf8fbab9e95cfea6705e4a2ebefaf9cb86881bfbf0a72b186bfbf7a227776fcfdd511f20791bfbf4a428a43febe074569187b52faf6f2d96306daf73d264ad34354761f37ed1ea4b862f2d894d338260fc84511fc7dcf898b39fc7d2f88d26693bfef09b978e3ef7b505c94c0dff7865c8cc0dff7a2b80881bfef11b9f880bfef15b9e880bfef1951daece1ef7b4894367ffebee723775afebe0acac5d9df5745b95881bfaf9272d1c7df97525ced40c6ee8fdecfe8f5f8fce81d31f9d15bdaf7554694d60109511a6ba9c8c509fc7d15918b393f738a353dd36b49237540477b685f174ad34854e5e3e208febeeac74512fc7d15908b25f8fb2a272eeaf0f755412e9ae0efab9eb888e4fb99ea169b7decf5fa55d3859eff923be374013d0714fc4b9c27f810bc4dc6044846408221be5d1e0438bc10df3330201f781b8cc6050fbcfc3cf081b96f785b8d9a9a0d3536413a60f34238f02000360086458e843604a0011b4606408019562b02ac620a30fe108980979fed004fc3cbcf9680e77116eb69781e875940067e88dcf2b335e0e53764ee1b30f043e4be791e97c0057e88dc379ec75f6ee0f143e47e791eb7c0d7f05d575bd9d3adbf0149abe33ad5bb6a78d77b3cc0b93f87a938dc79de6310b6e3cb2dece18e5a55ebfb7ea2009c7b9e009cbbcb2f50ca785eceb0cf5b651a56aea1734d2bdbb4e477f15c197cc9218c17936dbc3c196f26dfc0f20b4d76d5c82d60f56c720ee0dc22f8890270a200943b871c9ec7e70940dbebc50f016893d1796f48879f9fcd048f0368e4880eded1e69e33e2a4154e0724489ec73192979f0dc9f3b83782979f8d04cfe31e0fff01d00603f29ee799e6fdb3b9f01e00e5be01b4d5e0791b405bcd7b352f3f5bed3b00da6c823c0740dbbffc6c42de03df3f1b007e03a0dc47405b58e43dce081bef9f4d00af01506e2f03e0dca0149d01d006f31e28457b9e17516c1eef9fad018f0150ee0b80b61b1078f9d91e70e3e56793c0f3b8d723af9c564e2ba795d3ca69e5e4a990270f60b774db01ec987c64ed83c2a3f04840d5138fdd3701a80af2d87d1d4095138fdd2f01a82201a8faf1d8fd11dcc73ed807fbe4c03e39de5b21cf26609703d86111416b49ecefb77a627f9f054569d265b297bd90fc812c7c0744692b272abb8fb1d6afd77f2cb672dab703daf7b113a5b580a8ec3ec65abf5ed869dfd74394769ba8cc87d23822d612a5691f2abb3f3484b126e27c346b074bb646a234ec43574c2eb67a64ecfe7d8e89d258502ebb3f9bc562ffaf97d63efb3ed2be2ca87d99f67daff35e5e7e360a3c8fdba6f4783fb0c68a37fd733dd12d7291027fff1ab9a8ffbed7651ea0ede53fb0c6cafc5e5e7523df3c8fab3e1b137309ccdfef925c5cc0dfef965c54c0dfefacb848c3dfef985c4cc0dfefaeb8c8fafb5d938b08f8fb1d16170ff0f73b27170df0f7bd5586791e6f19b918f3f75b535c2cc0df6f1db9a8c2df6f517191007fbf85e4e20c7fbf95e4e2928b46fe7ecb8a8b03f8fb2d26177bfcfdd5678bf911b4c5bca773152f9460622a69b16163622679cf9561e4073e8fbbbc578ea912b5e74cee9866b24b1935b05ce3791cf6d968deb3c93553ecf979c87f20086de42a446c1e4ccc9ebfc92100e7060138370ee0dc1f00e7f60038f70de0dc36807377009c9b03e0dc1b00e73e02cead0170ee119c3b03e0dc1800e7be408d95d7f3f88d0743fec01a2b5580b6e4f11fd902e0f735e0f86cae2538825451f2e2032b0064568129db86a166cfe35e0b9902e0f75af6d95e3e19c8847066bc3c8f7b4226f0de37c477ce04928061086bcb2a5ee8206748bec19325007e1f01b05b8200d8597900d8313900ecaedc002282039edc00f07b0680dd12ce67bb49014e0cab2dab7841e526865a9e4bc0596b0161acf5eb95a3052484909c250f800c03435e00f8bd026848000b010730004c08850caa2119720c2877905c00f07b15080076563c767f06b063f2d8fd15d85df1d87d2360d7e4b1fb03003b2c1ebbdf03ec9c3c16f3814e2872b75482728a29329580b3769b28bd4db7c9634ac4a082125b1600f87d0056f86c36b2ac20802360b12180217926f96122412614d14942241701bf9761e7b385a10a766668f189210300fc3e06209f0d04d10042802a5edc78dc23802743de0176369038f789805d1733e7fe10b04b22caf1f7f5a3ce41b4af0f397ed43be4610005a832e53b0050040e3877015ef86e981be78b6421e0f7b6fdd95e8ade07501afa00e420e0f730c0f0d96c866040804b193602c835f0fb6dfb6c35610b6c09e8986a069079c0ef5f18f2d96a80670ca1a18506355c00bf6f2186cf46f3440c0ac082e679dc33923f30ac420738b70264f86e985b07013210f0fb1f01f86cb02b02c08027600cc8333b333b5234c06e5945298c99066417d059f8ff86f876095900bba4290754a93224c4bd03e4d903cedaec01ec96a8ecfef4e998f6fdd5d721396101337c42e66662f63c02b20ef83dad009f4da609058000de5209092990791ef7129045f0fb15c0037cb657180e411fc08b00b7a5d2135d6c1eb6d7f3b81781dc0256ef037dbc8d6f48dd2d61c72471eefb00433434f75202f903c122e8ba6515a527360f706e1af20786525c0ae0dc12f83e077c37cc9dc2f3a859b5a89038f783bc58a222db07b6a67cb69691c4b95f61a0bba51f5b46fb7eed13e2bb43ea923c765f8632340ea4ed0969dda12843fbca2c42c2edbda702bfc7dde77ca7c28e6fedf8722ba7c777dfe3bbcf51a1879793a36a3dcd3f37cd5eeb5bad18320f91fbef7beeb37d53e8ced67b9cf71e007207aa54954a4abd906b8172cf40df39a0efb90494b5a90494b5990494b51da0eb00e54e01947bf680b296031cbba57d5f067aa0eeb143daf75bc0ba63e0d88db1efa3008e2aa17d1f0738e61ba0b4b141b96d40b96b368d9401e57e8172c7c8ed02fa6e01eb56fd7c6f35f74beeac56df7ba0efeff5a77a3c612aceebc01be8d6a1b61ed6d2ac950793217fd7792a0a8b41f5ddab58accff957482eb63e9bc47971eb51ec751377dd8fac1f573faadefb09c2346ba5e26617933fb086065a56b1c1d41e5b64ecfb4ed8aa1d6cd567709c3ee967ebbac761f7d3f3bc7014c156e11ab65a7640e233065ab86edb2b875da63ce6aa9f5a55402ce8d1656ab37c5cc45c6c7fd6cd45a9a4029fedcfea71716e67fd6c7f9729568fab7cb6c370d83ecc5e5cb90cfbb2672fae1877512ed6b769a22b11dadeea4b79cca73ce6e4a0ca47f5a3025239e9a2dc3f196236178e22d8dd93c7bc83f22eaa4aed917553f9b06e1ef3b7f9d1fefefeb4fd47d65307d545f9ab7ae4cebc7553aedb963676c8133b99d9520b1ed09035b8cdccc74bb0600734384d13a1b41795cdc734d8340c1a3cd9f483504a298f1158f0c5bed9eeab9b124b53579a5e6e3c49b30d0b74e571c2db4a53bd7d1f3ab3ef3afc1ff3c153c4be8e6d75b6a5b26d8739edb46d10b67d97e5388e9b2176d97cefe5e2f5fc93e1ce948e00c5e96789133cc8319a24e10a1bf4d0845b949de9d8ff9875800f4998a2081f84f0f444cdbe0ea5ed5094460c9838110106d053cdfedb8fd9bf5d542077a74d2e3acd863e45b2e2e213147a346523c1b447ca844414bda17a92a47eccdf74f37872bb01ba949c4f5c1ce79eb98c7e8c3ea141f489c7e84b894ddf75841e1d8a22515aec47ea3452a8570e304665f565b11085d70b4738a90f05a2415448ee40b928958e98c1a6ef512eba6cfa2e55f36eb56766859e47f3873ffd7abbf1f45d8ad2703cfddae3345a942493a81693e6499832fa2a554bcbcc4c18e6c8d1638fdec3e557efa043cd1cfa9268769590048b10a88b1e397d9b11f48833f6541cde378c9c361be7d19c4be364724da83d7f164d27defa713ed136de00e14b2cf2c96594111759ffa3ce9e4b54467fc2c2f1f794794d282ac3381e8577281b8e1a261c5fe1f8ae708cdd84e3ac65b61d88d2a370d43624d4a6a16a027d0f72e1a8b3147b1a0bf1db84a3ae913d4d38ea87853934968592c642ea501488d6af2f138ef8158ebad6982b1c6750504f76fd9610a80534a3ecfa1a68d34701c4c1a2475636d12a1c75ea542cea77c572e5e875ed0d704a51599db77a77083d060947001d11c5964a470879bbe5e6b5a516b7299ed0151a624926ad6e449c60c3ec5146ed39b567cf7e4df11902e20845188114c60c6412a64801840d7e88c005185c1c65df01776df5a103a4ba199d67b169d898ac70228b0fb6b002466d48962a5b9021861742b4a036c6a8608254122122966042ed861a2855895282032a4fb5231c5831c4136324c10849a841a53175c40fa24863a9f60120a486b87284221c15e1090bb8a9272f78d2c49329b63fce2e199cd0b12d9556d084ddb2a5d20a9cf2d195558260688d750d2b60ba32b4031e4660b17e9d73a72f958c40634b2523a2603414a2da76ebd4c088db0e6e3a0042aa9242114fc63882ca314a2983a0a79c4f29a5ee94de3c7953ab355ac394569d09fc1f132f5bf39aacd99a675739b3962377aaf0b4a4c9a331ccf87142194974104502c8b8728330b62003062dd8214a101850482146151f3009a2022ed260120422329e5ef0b4a48960e8e728085010e189131f0855a1451386a8384142cbf9364db4bd05196da9a482a39c2d955400b46958a5a63c26e5b13ae5b117e8d13ed9f3898b6395da522efacf5b6d22d1a53dbf4e99522eebb9edf9e3fcd9d3faecf9f36dd09e8f014a73a8514acd399b9cf6fc4aa472a240945e711aae5d218ef6e8958873aa8d6e74b4e743d59b0fd09eb5b106d1ea4241140ba552adc89d28d4c994fb12b5a293a61441a14f36fdd9f369cf9eb5a65a9d728979e68d566bf3f584a2b49e1feb64cfdaac8d13692ef9d39e51af2915d3b142d8081e52d296f77187bf8272db1a8e47903c2697ea947af4aa532a15c9e4b17985a808ca500daa4f6a9050fda940b75d7ba2a43e6acb29a7a72b4d4b56a820194d89422404c549900ffd99a2b72d9d695f9953d239e79c734e9fb388c7a4848ac2e2b1a41dba999b3c7933b69af6e59e036b6aa0e77fefcd979c93b552751cc65363ddd25887e334da77621e6f3503f9e3362173ee6d62d50249bb445476697789ca2e10da0ca2c6a60612da74222f911544443f9bd2b8a8d793c672051be9a3edf321f97c4b514ee388a8ccbba25d3b726b4569b307166dfad44069b3c7853693bc50da54f2a2cd253294367d80d1660a9ed2e60f34b4091452da14c2c59bc7ded4be3df9c7c9c6b239a6270e4a8aca2e1320985cb4017363a62587184ed5714a90fa1962de4017449d3fea8c7840ef06de27b7073a7e1e5ff5c0f2790f6c428fab1d35f4b8247951f25a22e3032c05ff030dd07b18043d24d3498c07f2fc07d6de05f0fbbb4469ad1e97dd6ff52ced8b9d5c76dfb1d36dfa0e8823d2482d2020228e48eb4b4469aca59691cbee4beb4b8471cbc8e85d784e09525c81b15ae2a4286db562920aa2a709fc4ae6104100f1dea41604410ca3ca417e88b74de9b1d5b3ef7b40de0302d6d8de07e43dcf2008048892d58864cf1b1090668356b47a5a3e4e9b43849e07dbf20bf23c1e2408d8254da1e365704654dd66b358ec9f22512c2291c392c76e80d26330605396e1be0ee90727a074d9f7daf24302824890805d52d8e4e68b69014511eda7a1b1436a09dd209cf093d3f4108e72ed113bd1ec113bad608686866c4804fed8a232b69290fcd8b2b25fb6fc62c22ec9633e487c6e7c906a136c80dd122b83aee9e4799c0545699d152c37174b6a06af4d2761170a09e1a23306c12e099cd22ddb93ad29e98a89290402bc3685083b24c74180130850fa0a637765df079700d46a6df9d1b43206696888f801942e0bdf6bd15b7eff2fc5c2a3a6f9f165530326b16a841a290c3ba77d9f261c5f1f861ede5a562d412970f9b6fc602e19833058143eb8f2969f8c2b6350468689252fde96dfeb2563f0f50a59a00446b5e5f782c19797a824dd969f8bcbcbcfd625391183b7fc6c207162a8983da07499f7e2b6fc6a781ef75e198335bcfc6c35805dd20c5c3bc06ea9257375d82115e97185b4efaf9c562e80b5199e706a86860630d9ed5d8ef20439b2d78801e492ce79474bbb25520449e7568b09d8d32df90a93c9cf1fb0c7e76b9349d85971d97d255f93be82be36275c0c1c71daf175e66396235081269df38e96d61ad401a2a373aba57d584d789939e82095e9f62e47eff5b0bd36e0c06ab5b266b158604c478cd5d29ad503e871190f4173d3e7c7a7f53c6e33f6ed5d8e6a979efa3d6cefbccd9e5ba77fee4eb7585abae8e2ca8657e00ba4f19ec552adc070edb1435a2db9d88d2163f476569af67dee1352778784c6cb0c7a1234e403c1a72a3e7bdefcddee3d9c6d057282bb9f1b772abcea285e7da702612b55cd2dcde256abd5ea7138ce8dc1d5ff0a636aa5b59dafbe30945a25c91db92f0fecc7cdd97537d0d69c9ab552dda0c386c57003c5364d6cc6d8660e7479a88d6484df6506f207272573562d9034ee480a8b7d710cf695b2efcc195756ecfb39c8c599bf9f9fb8b8f3f7b3908b9387bf9fa1b8386f7f3f0fb9b8c3dfcf515c7cfdfd4ce4a2f8f773918b2bfcfd6ce4a2ccdfcf535cd4f9fbf9c845dadfcf545c84fdfd8ce42290bf9f935cfcf1f7f3928b347f3f5b71d185bf9f995c6ce1efe72b2ed6f8fbb9c9459ebf9fb1b8f8c2dfcf4e2ed6fcfdfce462edef672817f7dfcf512edafcfd2ce56290bf9fa75c84e1ef7f3717ffef7f3d2e0af9fb9f8f8bb6bffffdb808fefd0fc84500fcfdcf898b31fcfd2fc8c5f0ef7f4f5c2cf2f73f211765f8fb1f14176d7c2e473a3a4e5088b5c4629f8dc264adcb01e1b1d93b53653a478e1c9fedc2526059fac2147a02e1b1d5d047cfb729ac74e8c0f9666470766499d70e584e95e3ecf5924b44c2d7ebf5fa982f67a69a753c78e01e3d54e054d0f158f5b182a581c16a76d1dcf800a2835e4bafa51c6c4684d1eae8da3459d2749e43b23332341d1d180b955eabe3b1ca026c47623dd3d189499a8e8ece4b4a2340693ab7a9e9f53a3a3a3a556707065be9e8c81db971acbcb6375f524a2d657687b7576db76578b96fcbd0e50a61bf3b1a956f19bae34029a595522f772f9dbf6c64bbbbeb504a299dbf75d0a794d2957565ccca3ab770f096eea5b30b7ee9b93d57f7d2f9c56badd937be1edaedc1dc188bb93a615420b3250c0dabb5d66f88e953eae10833d2da73536b2f87f3387e9e4bd5b9545ead95a3dd23eced96129452ca7993524ae160adb5d65a6badb5d65a9bbf154bb77cdf8aa55b2ee0f8b21dbcd2ca925297118923ffc55a6b75acb533f0ea90d65a6badbde18cc6d172b564171c2fd8ea966d7191e088836faada1df70213f392814970b4d9f4bd989795b133296cfa1e8d7f42ecf650d2982cc1974c96af992c758e1add2b4b4afdde9b55bbe3b6bcdb93c972c6fda56b74ba2538e2d8f4ed9ec9121c67605982230e9a2c6b64996da84f59c36e0f696ca868cd923293d299d3acbe3c66e759152d77952f7656d775a194524a29a5b405cbeaa2b4a394ce5aab9d55f9a97a973812473ecbcbab5ceb87a384ceab5a3d965469d949294a8929a59456cee5ba2c8e127accd3ee5c61329e94d21e659491cbf0179d3299d2191d607096b377c5b261d39f55d239a9a5957379714d7971b9844fd01bf64607ce8bca23602ec771dcc531e3e1aa5c9d73ce8b46c5616f543b73b3f5881b7b2be762af4b0fd7cedcb823f4fcb0b63eede5dafa346b75675c91fc5ece39b7b464cff33c2fcc2d9f43f9b5beac9360adbe9cc4bd4958eed2ba82c812692b4b73ebe56c12f72661b95b6758f07654f50790ae053aa510246a5c78e1d6d47881c7de1e536ad0f0eccad1582514c655ca51cac1aa4d22566766682eb8754e4fca9557ede570a7f2f2b762e98fd572bdc0c4bc646034356a6c1e0c6ddcdcc081424c9623a7905b52e6029bd23a29b33fb3e55bdddd1474c8cc28cdf5302f615e401caef0f5ba71a303e785936336a6ae1e30d80163ad9793337ba1dcc531e3e1b2d5561e99c767b33db2943b2e5bfe7d8a518882828ba3da7ac3eba1428b4bcba4916fe01b15f2abf0d9381ff96fa6eb65e55ce18c32b384a8e8b3d550260d1bf680819e1fcef4cf3e5bfe196b05edf2f27dde98b0e58340fe984333c7f5cbd70107b9c36ac0fc913f83fc317f967468308011b9a3faa759927764e6cc6a9129715a5a7e7a3f5d4229715a5a5a9e97f550f642d6eacb9e3fa83af2b4fd7f56646643ed0a224ba4ad44f1b3712f7e437c77af9375806663ce9e395036501d72a7bbb31966924d4e46386ce4693e217677a10db389740435d361215316bc9dacda3f807440b2943b2d588bbd165ce074148f0909a2c685176e4d8d1778eced4154838667e75ae49a4265fb7b96316b6960bb96a5dca1469a6846f158120aabd9ead760f0170a8202aa36701c378b2691c7dcc86d983f661332c71f49e8098903b3306429778264297766d1f61965469951a2481c213dfda99d09e232d3e23c94b0c9424f4ae98c4e26aad65a1f5181d4aa82088f46b9d02b74092bff21f2e80f3055ba6208152da2467b3ed64712494add8826940bf910130d9a011176ebab8b39f4b33e9b665981bf7e33e899a2e74da1c1f6a0b44af5dd675385b13b2b9660acb997552871750b548cb16dd54754f86cac5b7315038cb5c6dcec2209c8f6ef689620c23044317242e3c4135eb6ffd5690208dbfd2da689420650f8d8fe15d348713385141dc8a0c9f6a71a8618c0f698a5d0428c2982b6bf6b1ea4b67f75c73a464564c860cdc9408a8f0f8eca90da2155c64f9317c50f19423d107a28867af023c52222e2c1151e1ce9e0f1042dff9ea1bd2d959ec0e20342abb6547a428a5594feb6547a62e8892227a630e69c48a287ca749d70c284fa58277e48e243d419766289cf9ce9cc7ce81011446512373135841195495ca412631585be5b262da107f908bdda3269094b3d4b4852b2042adf19da6e99b4042c8aa850b0065f1ad34f33be7ed0cc1cffb1a3d9b86eeadb5a6c2f38bd9a413a9d46fb7ce9aa273cef5d8ad63aadf5d67abddee937acf4de7bad0d96d605d41dff0dc798adff95ca9ffffffff4258effbfdc914746dcb9c3f626e8dadef44ce96fe9be8537adc3f8dd964af73c86db1f1ceda641f0bcea4ea9f4af1247095ddd6d0f2ce65ed762989039a78c71dc572eac1eaba1a49662ee5a5c3bcc5d9b44ad13a7c09392da6ab35f6ddd99fac6c799edd75689c371f567d561d79fd55e6a69fdfb0df14ddfdbb3933f5e5d78e3aff9a386ccf1779ad046e2f8db4d431c213de5ceb4d8bbd6e2c91dd1c4130fa2f020c88e9dcbec39b7e7be030cad6f5acf2c3d6e5abeb7a552134c7bc47bfef0db0ec33f21948697a31c27df8654bed4d7691758ebce0a22ee1344b805b6d6041387674c822ad638eb9a134d7736c32ce85942634493094d1c6b9c75105254263126c28f104f42446925259a98482897c9204048b94cee11eba59f58bf949a18c25f13139db74c3a838c55134db365d2195b1c41bb6c99740651009a108a1246d214124a4f5ee0f4687ad2f42397f9b4f92a5f35a6d65a5d6aad3cb5ce2811e86aadb5da4a6b95485c9dd551eff95f5f36f1509a0bf92a8c00a539b6e138a321bdfd3ca2b4f03d0cb15b2ef49a707e8d70c4e1c3c27974f32f1b1a8733e06c12a2ef94524a299d4ddb29a52028a98cfeb3fce694524a29f5a3ed94da50498f6af80c9037ce3dbde9928b3d77d81dc0c1a4f3a414e5d3ea319f387cd0932ac193373a483aab0e7b5bb7527ab54fa5769d1f01bc66431c3de8f9fef6e65d7ab3555cb42298d252ebb4c5073d65c56286e7101434eaa358c04c3a4ea1cc75c171a38ecdc18087cd55d91c07032f361783156c2e0640d85c9428b819cde6a876b1c5421ec528bdc0086e5e2673e2232e37416383368a6953b19937a501638f375fec51878f4d81ecd8a34c5a82874dbfd2c74be460d3d7af2590b0e9bf0bb4d8f4634c0cb1e9cf9808c2a6af33c5a6cfa33474834d1f7f364abd8ad2944cb9cf56318f1c2841594263fb5f4d69608331387b13c6f6af5836d50009d5ae392d70c1f6f70990014515550c0144d0151048010f41101185123f42b2065586be3979f0e067f0d8fe73498826a4ac600296a6daa8374502c807473ea820ca8b9a0102f3f3cfd44685481983d177da42c6e4f6298ffd6c87f22897f2d8f4a71d4be8f7a7bd03144a5f7cf15303268a40a3369f064acb41054500c1881f624085506d3ecf7c22373e7a468fb888387595eadd65644948a453e16b2b3de2dafe94de544aa83c51c15289f67c977edd7a381538d6a91af154612f9cb7e933ce1b15222a438f998c9c6cf9d9c6d9f630ca1e6b1017501c0a8f2eb454da026a8f35686f0154a1384dd6a8ecb106edb1faece9e25881b61317eb1853f69c3e6ea408ed011cf4a64c3843e6cc1f31174d3e5c303938ba6ac6dc67bb97e3b8b9b94f013ad0dc638f71e1102963dc7b75c5bdeab937c202ad0a471ffdbbbfd9bcf79e46f9745ef8baf9c18607fafb9b269a6a2bdadfca762621ce0187da1af0bfefd16c02a08d599b465dd1e3bc45edf994d29c9bdf0cb4b60add88da0ef4a076752038784c42d120ca0e9a3e3717a5120da0ec59836e98aa2158888e8d855c6f06afb9119d9f10c7cf4377d83edaf0884349d9e0b1313fe9e1054411afbf499c59857c50a1c71db64f1d1e93bf032d2b51abe7d2f76f06afaddeab36373d97e48e95c9e44694b6fa197a931f5147a2be44a5d4b9b2890063cb9f5fc81fd3094c865a3d26e5e6716f923bdcfbf4a212511efc31d6faf5c24ee60f87e204640d5199bfe741dee450e60fbf3273fca16c7fefceeb2b26f4eb50072435566883a86c88d2ac1095f9236dcf3eb489b6dba13a651bd5a24a7465fea850c81c2912c79f0baf6cff19153d7fac446e4469b436bf225e93df90ba6f904fd83494977a0f1de89b1d236991f483273ff009b3b89267164f37a4c165d586d2653f767d29c52d72903b39bbda5d7ff6b8e8e3a2d3ea433182470a9d830e375a6f610e1eab520790b2fa45780161d7af3cd8f50d2071ea0a4be8514a8d184a0ef4ff5f2fad6b4503bf27a76b4aff6cf9b3711eb3d3eea87a9032fcf26e9f23ec314f1f978d7f4ea0e9f3831ef1c6dd8c891ef3c6f8e767534d500770f6780cfbb8424ffcd389d27c09b9134469b286e5c6ef3e0e45ee8c136ae329e5fde8b76df3f4a12b3c993296322fa4181361ec337d240efe5a12eff077e1f4f1187e1f57e879abce1101cb6cfc13ca908b4f84669011fae5f668b611a59598545c7424fc5348eebc36feb9f459bca880e20518e39f6005679aa067d013b9e3ff92423781710e474c292987392c03f419a93fbfdff8f1cf208983dfa7191207ebe0317cf3187e0f73f018c63f1384c6f831c6b8da303c79335a772f42ca2c1417b3c76c52ceb6d55e712bdb66d84d4f222ab36fe5b6b3164d716b9f470a0d1a27d1131747ec422e8e597a900d153d4ea2d183fc2791f320774e30451fc28cd9b7520cb96486c4b10fe431eb4eac7dafcae9c4fc41a79839f6edebd984dcf1b7f3890d9238560a8963bfc863d688086f6b812e0f3c79e3e510bc36536b4b3d8ba490b24a81e8ccbeef56a06813a575ff1ac241d8a5f4edbe3bcd229b2cb4bf235971713a3d796cca91e44ecebe755fea84feec3bd29e7d1f068486ddf438a19efc8ad3ec5f282abbef427247de1ffd49f5a347bd545c38beb49654c6230589470a0d95e4e29d13cab3903b5a4c289f33509adbe32cb2c942fba540c851e2c3073d4ea7a78944314642ca8e81569ee4b1eb484cf435d253bf9b8e741fe357cb86cd60bff6f8e8d4b087b1afe7605fff62df4740fd2eec7124c9e3be125cc3a1db406280d27c0c29bb524b90b0cdd8f7cbd8f7a733499cfb3b9c6084dc993bfef72730456ac48cddbf628c7a7b606eed4812e77a488b9038330a47097a4a79ecbe8713ca63f76782d06386dacebae1e0284b1845584d2963a5040db3a5d2d10d721a7a664ba523285445474a7c5347435471e4c36a896639c15302543642cb6ca984450e3218fa654b252cb4e0b880e20ee9d6964a5808a9868005101a58245901a1331a788ad6666024b4de52e98a31543d601021458c7b851213aed042ca15533c2a74b7a5d215523a20e8bca5d2154cd8205c21f404930b63d74ca7488c1e5a3530825c8a927cd0b5a4a39619ce82096ba633f3a1534404c48a08bae808213e565113a05cb382b42a5aa2c493fab2a8864094a528c187ae76031fcf0c1c64084caa2b4d38a64e8a184a823c0d250942849b94241f6050024a8a163ed49680a448d1a4a62425050a1073a633f3a1e385b52f96a404fdd4bc40fa1a517e48238d3dceb8267477860a892bdd09b46bcba4349084b4cc9649693c81add0315b26a511c415210d1f82d0390daf079a7504cc447f3ef0aad0ad2f3e1968c14281d65b266589a20859607099e8962d93b2047543d0ac2d93b2f4f061a15b5b264d49dd194415b1608a08b3261a53f17c302584ee095db74c9afa81159adb3269eaca9e3f34b5a4c262aa8b0ea479e12aa7ce15496c3f52ea5102d7c5acdbbe665ab68a5a4fb5473da3a96c22214d95cc3725ce4dcc53d1e88be330772bb52c17b5b672b5769752db597b39edc2d95aebabaa8ad67d5b2d2dad5bb58be36cb69cd52e6a2da5acd50ae68bc953366d22944684ca6454331d0cd37035b63a4df52ab0ba6c02993ae6dfdcd032055f2f1bb3d9ffeb157b2963723a7b877ec63315c812828e1b9ba9c6d20b916fdb7c44e2f813a1b40d4899bf10b62769ca7246cd0a9eb2c4999b03eb8cf78a8159694b3f6aa9c77259ce45298b5217aee06aea995d34fb39fbdc7babcfc6b55c9fad7eeb2bb2c3a67473f59decd7fc918f8311cca49b9ca072661290d88d3ce348963366922cf48814940d5247ce90596692d9048718887c310625925484480c44be30c3485d61d29b58ece6c60dce0a2de8a893ca5ae594ae9591242a1ac8967f7373a389b8ccffa64e7a445af9628c33cac86286913a29915952911991187088acf0450b636ce7a28cf975d29bd8cd8d9b9b9b1b981ce3a960dcd5dcbf7c363af315d96173e1ccacfb5a9a5b23ffe8e8b999a2c97552adbf9733b6fffc51661967925cbd9a2c5db4f1cff229269f9efc88cbbc4e7ac48686ce36b8383720a57c92ad3dca27f90423f38a99a13d49260c93d92ce01b8fc907f78dedd93943d8ef80bbcfa5f266fe56798212cbf658bad59227189348db73e509c6b6f702932778b3bd983c414945d5618ebb348b23fbbad650bf709d99526636869e4f69ec45650ca5b32a7ad65a6b85b12f97da7771d505b7742aedb1b25c7db5d2faad6aa595669644a2b5d25a2bad9efeb719f1aeaa96ec5a2476919cabde174a25b5303a728da994bea4cb502ae99c73cef029a5b45a5b258c05144ca730180c0683c16030180c066bc15a602e30180c0683c1666030180c06d31f9be9202df17094a3ae535383e6411998fc9ba3ae255d47ca5ce7890655600d7d61a18d1898fc1b17bbaa75bc1bd88d977a674e50630a4c73e3060c0755b9ead59179829e0f84c7764f406153e8f933385008a0d7a8d48bd96a8a142a53030000000000004316000028100e89844291208ed24c90e90114800f688e4a66603697c8c2244862144419638821c400038021c410858c689b00d27915e1e496079b8a7ce8c4a806e8402caf7e16653874989f60eb0f65e72cb911589a2dbf74431e97d7b8b6f2a3b10d8ecca1c0f96d7cc37163289ac7ae5eadf2168968274ee519d8281f5461b558a6d55fca34c29e3c7987023a0a8fd0d7b1d8dc593e2e25b3bcf4c9e397672463d923b93515d94f9745b567799e5b3a147d100505018eb6a51472ed858e31c56a0ef5de3fd04a3b4eb7922261782613e4a29b8003517613c3115786a45dc1d85bcab576e7d4c4d52f9041d875ce204db02860c18d82440ada3f1d6994ae4d78c751e0e90c6ff834001f104216770c182c135d76a879cc50fd32a11a0b1b688f9c3af23141e97c02d618cd1d75978e311e73235c472ca123d911f6e1b1f63ea65de1a8c6afcb6fffcd4ec0c36bbc9d2488e2256da3717c9c90550fcc28fb49a3db35492c26aa7e3927755b75f86fe069c4c10bae10f1770efc3bd0e5fc69176a01cff4c373986219f2b867442af0a97df9e0780bf94f03f0a2429f2b2d8f02f766835969e5dc5e79d7cb4d003a0c4959b6940361e158444d534329d20a54263071606d22e1d4f662851e8259d8f907baa95d6514255a4678e541faab8d1809a7f60d09432e25eec6157533b255fa33ed66f80af6e878af87dd04f026c62a7a2570236401c4b805947077a62e44418d7afcc0e18af0831ae3d982f139ed2fb24f7c8dbdc7fca38ba69d228f7426a6ee8287d71c5c19532f2c763feb6110e64442082ccc26fb8816c66be6f37be8be3a4736531eab4cdd82a30bf7d9861d8b7d66104430b93046d650216829f819f918c05c6cca751441e811a69234a08c9fd441b9738042394afdad22096f37047638240a7a3a804094a61ef3bb4270da3b81d8a9e32eb3516f7420c47b77097ae1d055ea31c0cc6d72694b91668576c7935f3e45b0748184d6f4b840c6edb60fd9eed2875d709ccfa2a9c050636a2734898cf9ac52c44c61dad2dac1f565b2a0c579522429b5c38f1ed4010c5fd276e777b2f0b0fa2bd4fdeefcd8be2c29c01cf0e71dc8914509253d42559963c76a481547f2edaa121ac9c7fa908b1d0ce5ed6f77006d98d03a12ff5bfb07c297201658a1bc0e1fad44054002913c570fee4b42cfa847cf827c3014aa9c404f96a9fb3336a111d39c086696a2fede3bcdfd78a10e930b0ae7ca7711df6962d50d893b42755b53eef1af4e12e00045f32923292a3639723148e3f7caa88fadbf4a4c0245419868c214bb179585058d3eca02965714b8a590c7eb9a5336dad7935738c3882c79e80f09935b5599fa4d9182ba5071f48ce4e4182bcc965cd155c712acc0fb1d75ce9996f8256478f9e43fa1b5ddd034072bc03e00fa9108a56eaf1343ac20c5699aa225583229e5409053ba82f0e41f214a194f32d16b90f54476dfe1182e3ba5a3113089cb375cc206f7b7d45e283dc8e7ea0256a690feb67f1328a14bf513f09c859c98d2ba884ee912f8f7a8b3fea93761feba2cb51e354103880c44e4fe5830d63decc4c2b3fb70c53fe39f7d5315e6fc6154656f73799b038efef92bd7cc6d978ec742585f4be4c4acfe25861e7499f9911783658873f307a7e0fff6243ad5f9f732d8419f19baf23d600408402b32b5ca53aa0143dc96ac1a822bd5aa55aa61522bcc138e15d33bd6391fe8820ba0be1563c80f32a7b5a393113ad673141f5c7af1bd6619848c62c9184b35498b26232c425d182fb3e139311f5aa48455f87e075f828dda560d748ceb287526c7cd790eb1b6fb162a02ce15b31cdc42822bcb104ac9c7b4ab63f3484a8e10a29a83c69e1f897108c4786e7ff105158779b9d4a5e3a0eafaa447a8c7661536f0027e3e59abb72c51ed11e0b96b953591cb2d86be57dd3130b5f1821c7af09835d756b8e1d427090cbaac56417fb1920063a1df1fa8d1b14a75d804a5db4973b3d28f56da618b6b2f07874d5abd02c51ad489aae3abd500d4620a042bd6b711a69e62d5a3b542aeeb5dc80b4a608eb0aa92e9dc06fd5ee6b5e610132a538d0368c22151606432b8596b3072f06e7688134c2e621b25a00273260db6550b9ef48918ce2f6b6a36ea3dec2122933498b651684c85efeb908d85b30c9c33498dbbd40ff87ac7ea2ee8b8c00ac1b25c904af51472558a2edf675e3bf659462bf0f96e3fc1f07ac8b53f62de0e16492c173e97de1d068e8ca0b4a25633c7c9c3955a8abe2d3b04b8ae96a1fee31d482125cefc4bc24acab6665888bd923ea01031ce403d072ad902566f3663a4d9da4f7bd117d87b953b0a94776d6899987bed917eb04d2671eedf8e4dc9c1131f47b321d314d1cf5f79b81c6d120f49b54b50aaa4474d294748c3e23e18bed3243ae6c0231a15e7266976bb53282a1c199ca83c3e43bbc1acca0e1509ada1b3162caf436b93f989393907ea5078af5aac2d1797de697e3920093c26a2c5d7e0369d77a13080666dbd7ab9ec9343e0b89f07fa9ecb63d4e1493a1effcf6c1eac189c92af4aedef7628828e470bfa12fdcd83902a4083d44b1694865fb467f0b4811569c9aa21c106415793c5a1865c6a0ef5276a514b255f501cc97c9ac53a86fd7b690cd28e381bacbf827fcdad566cd47bed3e59237100c3d1390cf18f57dcc27bcb5cc3efc05ef97f0799c5b6b7a375ccefdaf0df8c68e292ed633728a16869292818140ba83c29338282ae2b16b92e281ba73df7cf69b848dc9205ab2f0a5c9dfc6d7edaab2780c14b213282b90e6aae0df9f42fc16ff0f307260529ce4426996afb0b3d4a3690644c94935d56e72820a664dcd0eab106135311a6b17480c510100859e75af6d7e41e0fc23c86aa1ad91ba520abadfb0eeb2f6da7c2196006a1b6f7384b7247acd36e9e908f668859a2ac389947fd1145abc0f31166e60644e441862dae31ec073821cf017ae6add70cd81291458821584d4829dc98601b82e539d1c6b7e2e57904e27572ba7f576252688217baa2f2d1ef41192c4dd4aa473863919b9804054603db7dd64a0d41ccc90a5636fc374294b6c027933a4c2a76a6bd178b2d8a2c3997e69c28afd0f18570d5da7051ec0bb803a7cbdee45bfb91e863290ef16b4224c55de08200194db937020288a81dd921eb8bb019d33826dc7705b2a23d536b38cda74edff6ac49d270f5b9a502d926766218b61624e2d34aa2091ec7bca7a816cb3b8289d8aeb7946909cd7e2ff84e6f781ddc23eb47e9ccdf8906c58a2c75ba556172fa870759f9741c95a01a71ef4970317c2e308e48de81210246aad10a3366bc65a96fb2d032d58e96efaf177a771b7d193d8fef79c088bcd864215b71c28f79095995a651d8e4306836420f6ed2c13f3078bf92e91ce4670fa843e7375115e3761e9e62671ed3e67768fb326bd00bb33df3055b5c03811e59424e059a16d772c3b975ec0ffda9187a339f681f5283532a9a31667fb538f2d619259103cb5e57c266659c78b2431a3f1ee78ddcb56feffc519db92ebb3841987b4adb033bb8550e5d16d66955c2c88ec0e30a3001899466216ba92f6296eec77112b3800a81894e15efa6e7e16d9a2702d9fe80bc364cce5af4e0ba43959dddeaea068e84c4cc006ba9e1b3e894ff9bcd4af9762146d2ec614b6659ce7b634271423b76018ac54aaacbe4569146e0c05168bd81a3b82c377094f63d823964e6800744256bb14c731157ce3156520f1246662a691df7a9087e251b2390074ecb5bac993295a026cd550c40b2c79aa4e574580158cce99b535a0d8af387f357006539a15c6be78c03fe2626ef1d65ded694150c70efb4effd08c97e075f23a5359f274a73c1188984a1fb106da3296a0ec94c0fa3f682bd0dc18eda514cc9ed7ff2675187b7aca517394e7c1b4cf1bcdd478f1790dc44dd1dc471ee3a1473b252c00f09bbe05c1f546597c0556ace1190fdaeaf4a09fdd5639316de5ebf149433caba02d1765280eb7ba04fb49d58671ced32fa70b6881762dec9b85877886a06f9a1ea8b4158445190d0678cd7f27ef8ea34346a952b2fe3ae46e4bc0caf4729cd6280f51478db8655025f8f6a8ccdc96847a05dabaf0635309b5bc4e3546f03342bcaaa2a27c3d6dd02c1bcfd2f815d05e7657d1aaad958553937d62cc03cf66b60696cd6b255de02b50f2da27b624e46361e1023ee8b90107f68f8e31527a5380d578294e22fc4ca82891d9edfae53a06b1b592e306c726fc3182ef1126b023c087aabfbe360c0b118dba94a9220e234b8ac3cf3133d0537bb66e5f9773c82b5d678ef2930d25c94e99d273458736aefe2c098839888d90583290109f46f5544f1f24587e9cf3668ca44b6d5135c741424929600eb123c6e7d6b07113d9ad183914bcc9a326d9fe933672a3f11b576330e0eee9b5604d641bed30ea4d907ae20d30e7294af801a3a90c031a8154ddbc6ce310538245ede78aad76f308433a5e0af07127840714430a98c111a810156cb74809337c86e2d7178669307623f5be5ef65f1f14d8ef93e4a4a971d306ba88747f3f4cb50064160936f357fcb2e159f3f00988b84141db446464e308cd128e80546672d026809ab0612d20d7645b9e59aa22fd74f1a145f9b867f2e0fbfdf9b8ce58832ab1dc50f449075c13cd89eb9c3b7feef4e7af1ca4743941c5a56be13364b3863e6d5b44a8f527e8421062099c139b5004f880d13f634aece51698aa534bef1b22919c0b5f6ec62ab8df240653aa00723289dba883d61d36d14231cf50bb76c7f16a419cdc3959f35ef5f069fd935cd6027b6a58b173ce560e09708c24034c339bc77fd00fb688ac4153c511dadfc8b84e469795d625e52d319ba7fc5e345124c49560a2427351a1b8379d25eb861bbc91e9f69472b67edca9312b835f806eab25dc980f0e45762ce703e9b88ddde4b1e35c1dbfa825edb684c7d9967ca900941707cd9095091e66e3bb7c030fc6aa1be86f5597cecb76a91bf6106c71f1ac930ed98bf2d9147f18700c0fd47b471fd763d1f9ff6d70349b393bca30b8a7a120f2660a4a17d15ba778aa7f1d17cd6963d3b4ee7f95f1d26fbc0fda2691251034cc737eb6c149a8042a310ed091ede1f7645b10f4a3bd87d3262e33e932efd11f50cd1c2bdc844032c6ab4cfadde8cc0089687a569714c9674a5fd6ad65cfd32af4a900f513e59e8e452e0aa71cbec6d588ab59c553dd129b32bf9c46096369b26d8a4181a4d9b1f11ca0c6c02f0dc3fda0bb08e0e749e8b3e140ac86edee54d905064aeb8e4b3cab9c1d366eef0294f093384b40c8a0bb9ce514ebe3dbfca5e7250a4ed1d1430336251b5cb03920f3d4a4dc662d7e581e57367e159381faa65cf8976b004073e3b27c64f9a4b2058c810fc181fd6a299869bbd3d4cc49cdd13cbfc116529079b8e2fd221ff0a4f01f9f7351370c660478067aef2b93507f722755cbd1fd4520bba6bf9e7b0d3c4fe84ba31f4dbfa9f0b739be285b83ef557980923c49d46060fd20b940c3b9483c1da78afdbe2d9b45621e70a60cf0e681fc2c21da6925e6d26003c779c9909a64f614a344b74bbf0a204209c6e144fc0761f5fcf17d34b8db2b2b750d2fddfb2b416cffb1548befe9d7e48a2c65606619fd10939f8c280cc01d14247653fd920d3eb5f6019d2b0fdb6da8fabd926ee73d6c6bd5d6d9cb1a40a236658fbb4500d115e453402fc63d031639227948df30565d76e0ef5ec5e8fea59d5a0a24094ce89f2604200202536c4f16527271ff3b58c0f1dd50944d4f2319bd32affbb050d9b9e0c9854affe9d7389760faeb173f56585dbb80ad5706ff8e706d35a9a0113e4a3912925b326a9925b24d0d119db90e0fe4f2f8f588c4dd0a44ed64c268539604ffb08882edc09c458fa8295527b5b002aad395e05f1a1aaa990abe5f303f305855e33f5f48df81f500567ed25f4cbd6c2f345547518d26a04b6e4c0f3a160282fae593c95c47eb1d0f60d43521ac89a66439049f9f42fb9fcbe7c7b4025793bb93d43059d35d99ecb8dad1195b23075832b71b590a098e5debad28a826e9d5832cb8199e5279ae5834626f3f33bd4434171a4a44330cbea921391ee3ee6057d608276453ca8f3cdac5e1aaada665fa970267f86a85804ca19ab4dbfebcc8cf725c76db8620bdc14e0e9a9657bf87b7113c04589751f57ca83220b8eb6cec892f02dc0d9726a619a14cdd4f49d96d27b07b657fd910c1ef37a9ed138cc3f8a00d6ce1f149a3f702678ea3453b871492d628eec2e73746e90debf0299096dc22203c93717386803e18e74db77be1e0c9db34c51948594fefb60b59a5a8cec14a80c0a340cc3f08433a2103d3ae77f783a4b1cad05beb858dd59dc42e1f85559bf716685772aa1b3e88d8a039bdfe5b373bf959afa67d359ce4763d9ace100323af095819006ce5baf43a2b70bf70805811a79bce847c7dedd2c6c52fdc476e11b426b5846c5a8e0d7056c6e23e4208402a088eaf4c802d3d7b30f8c339eb47152f28df4b5d6361fee61685307d902d8969c01d7fdaec4f06f7491cd44866d41a8a5cace53510b0794a872c804bc135d554f7c0a9208878611b427e3cfcf3873c7e348a0275fa56f052a8f3e99a5d7c47c46b1aaaebd86497b6ebdaaf868196358a130b3977d6ce9cd2b564443dc6da7ba3c1c9070fd56ceefaac9feb28da98011fc227b321fb7907abca0056c5ceb224cfef6ad037338e16f667ada1c30600b625bb76db01a641f5dd9b96eea7d75e6576576e2d76563b23f41d2e45fb761093167761c6509d59f5041cdc35dadf8c192a874ce0a7607fc87d28bfb759eb9f7b854a2ac4ac3027b9c7642f3bfa0dfab92a5814119b94c0422498265426af888b8d01a8e9b19f95051376c47d08a0077f37a032a37c478e1a0be451ccdbf983f765044dbd58432f39783ed952cbf5b5175faf36351f1dc780da2ec358723d4288788797085b29a3afabbdd17e425a2491cb82f89c82cb24f6a0530757c6f677c6432206ecc5025d8594aa046daaca4774b6351afb525f43900b8c7c785db8a8f276585df9dd654ca06abf8b98b45fbe5c5345b49b02e8fc3014f0907de92e53a989ecdf8eab53a83a95f7d4f7d47d4cbece72e80e8816afed1cda8eb71160a10b1ce7eb7efdc6a120fc99cb549943f5a0ab5d33b2a16dd4336e462cce25216304711c6aaada9fb9b75fcea59ddff9ee578b5440ff601ac2de1879d92741d157bc3cd72458c41adabc7872c8651ca159ebaa1476f5c4dac71c523486ca80e5aa7a457378462dae9430865b097c3b1e8c081c0de9b457ad7134c620cbb78c34fb3f16a6bf54c57048698c2b84a9516ca4245065c10455b386100771efe681e6040aed359e919676668aff0422fa42d4702c3fbd2bf0c3cc6f66fe710a1aaec2335180c7172a6dff7bd031707212cc444245d342056441708911184fb2a071d5eeaacb21bcd0de51aea2267df12722bf9428ade4aae30af1fb98c249bd4043571dbfc434da4aa983196b83cbe2d6fb48616b2118a8cf0da95986c685d0e2784e62274f7d74d4d47851adee3dc4537b35111246d9a558e6cb291305c17c9f750b41fe181312da7db51e1b64429457bdc5e65976100d640f285df3425847d5e104d4595ffd52d0adcc66adf09bb6a7dcc29a80b18498b00cc30f018c6c552e0412d8b11786ae162808abbaa82f9d8059e7a6d9e9d6c9bcf187712044d8a78708a31f3f0120cf8ed97266f5bc6610b68e5270a8bca7227026baea63cab81c56d212ca954918417dded2d9242a63a899b3b3e8da41ac6fc5a7764ef686677a1932c3e1583759214a12ca7b95b49f264621e642fe64b7fbeb07d8885f629ed57e849c90b27397af1d4f8ada3d21601c387bb0d88bb560c563f9093391a5b2195104c8db6cd62c134230097cf2a74b0f366439f93996a44ef807f221ed0de165efe6816341fc0078f6fc793cd4386607952192dfd1ea3653e2c715a1e6a1d0b45f54ae7bf9733c80f296c431400da75bccc7ab77b9cc8a82c96243a34dba89a1102e1fa6f40029164dd8f8e2da2915cc4c5d93b7e22e611980e079fdca3bad81d1237c09326ebed7f67665899f7ae8d2c427c41865ddefa03a51334bdb3e447a83474f1da6908112deade58bb502376f6a87c1908a5ee056e3501dc9b60723e34c1517b6175c4ab4303ed48f142ba4fb884b1e6f30c39c0141db38293791f3a096d99b7f51cfa6508cca112366f7ef87d59e8720589501fce67ae2073dea5087238509202ac62524175b7a91209f24ecda849eeb4f6afd6b9a86de034d32f86a8b2668bdf92ac15389054903389d63553e27c738ca214a95cd9a3c445fde52f47bb2bdc9795c31c69568e8da99b3b874c1b9cf6be2cc20d3b4e1628840c83fb3f9e9916fd62424296d1f33a0bb33fa37a68fbafb15957782e19c3b774d24f171c304837d372565391cd56da172a29f08164345041fbdc62bb7e9a1882ecdfb8874edb6c00eb089f2688bd29e240bdccca8260be8852716359f4a56593efd761f5ef3e6084c9754f47a87220502769977a8e1ab0df0b5f16baf5f2738cfb4cda6407174aa8a3749fd3c2d0030137ef063ff2fb0a87a60f4bdaba24e1c09e5959a6f7ab1394e19dc2a16306e0f91470193cfe82f158c07300e138fd5883f6a23343bf7b161e84ee0d570e6fa62d17430b5bca7d2b523f72498198c8222c6b3ce64d13ad952832b65cbfcbee5a8694dfa2d35e40266eb373244cfd0943517646f1b8e80d44a64a88ab4af64174f606ef92c00052a3e1f245326895f8da601eaa8a219f233dd763f084605a19da5ca53ebf216b701498d5da97513f3e075d153f587555368f33c20216535b77f7bba4826a1a560774e21c8867b55b0de7827704a1c0c02b772f02abdba825d201f31e823c749a9f5c33b0210cd1a22e6686cd5857b20e867315f7a86e7b91b6e3d089a86b60ceff1664531675ffa2ff2757198dac15eebd58204782ccfaf404c2a61e1b41512250cbf5fa850697115ab1b242f3ee66b715134331941068ae4173079dc4eea0734108c2bf6147b7c3d885db8f7d966b4559c17f5d77c4753ca0f86ba8e2b7d9c46ccd751300b8ea94a5b384eeec8a8db218650390a6d0ab73dbb23c06557f98826104e38774091e27121c5df4ccc629fe1a935b8e17ad09943a0691c9268000aa7b8f96cf926ac800fa88c8d5ce9939650f3bf7bf2c14cd50b1b8a1bc7d35a4fd458217ce0016faa1f16ea24c6263d77c2385399527d2b8836f0400da2447e470076606d1dc4b611f3cb7997fc36d6f699574854b091d9508d61c394e7739bba50961c210d56ac6e252980ad6dc053ccb154f9bd62b5bf41fa24fece0616ebb5b02c2fe4e5c574d545d9b523c4d1f81b010dd78680a69fc28db4890cfc68e57d6f655197b3767c57355a6e24594dfa0e625da8f2f07bf3e28fb4db14eafa9baa1b9b17e082bdfa3620d54f31400fa21a554a295a0d4aa87546644cbfc5946d34913a4bceec6a5087fa135f4662ff77f19679348a4c6eb1f275ae3e87155ee668472dbdcbcc251e69fd94c77326a966034256f661f1da7d936a783c21c6846e77135aaabb168e140e4ae2142a42063a3e640aa94e904a4b0a055da1f849bb376de662aa573f364dda38adae61229b41353772edae72831be5b57cbb38c85be144a64f1eab47fc5a730272e2599d71686c830203c9a246b4fcd5fdcbd6839e86128447c78b04e25d49795019fb3b5c42b1707421d5c692e29d4e42fade5daf6e738e6afdf06d5e4baf5b276238976a7211c4014cf109b66537f6e61186f3fb82cd5d555425c41c422380cf6fac409eaadf773f6466169d88ab04821376bebb153615b297de5b765fe9d5a9b81f7f96d69e4ce0183d572fb63ae1af4db9b8b681eecd6ba9160945199dc27fe1aab602d0029eeb80fd5d6001d83bb5cfdf5a84de5a22afaf44165b89535768d7b9166c2016c163417577691be964672888a9fe847acb427460db4739d1026bf76ae572c718673e1126abea3bbd497a929dcb03462a41c4ef6584c3135537bb1772fbbfe3e1ad489106eb4663d7b49b624b3097a5883b540df787fad9113d638fbd6db9373b809df79bf7d4e0f2161c0e432e098b31a4235c883eea6145b8ac4ccea7e11174d15c87e77d351643c5e6d88672e8d9f4a7c399bd760771d0d689fb57fc601b08753c8fd682703b2930bc77dbc133620b24b47b508efbd4d0ee1a59e77485c28053a620e403f0feb397910fd572f1306cc80774e6d28ebe51b50ac9b6e1f26e45b1b7d93400b135a5bef31ac89287f1d083b2d87b9558e4d1c1e853eb1b96fe8c325324b01d732516cf60eeb88ff43836a0575feb31d473d58d78e598c0775ff84b6a6ac85a14b5df91b3e62b290b0587a043d8e74bf6ccd29a8d355dcf21b5e9c30e7cf8903cdfb21b6fb2aed66064976471ec50305fd38b8f7578f318170dea222293ec5979eda8f392a40ea41b2791808df26e16eeb5aa5ce234fb8100dd7fcefc7dffd254dca03105bdc32c33844f07fb1aec97fb742ff9691ffa8ec4453d2e227dae423fd3db2a14579d35fa9045c24c7ff84e8cf9c9a5a3e12aaa9ee3d0980bf3bdbd608ccc3f29a9b1d2fcd6218b29e615b8b6111bcc7d9e47dd99158575f28de44185663f897c82ceeb8badd6bea2c5e6a67dbaa5daac8d5d2f2368d26e026d174c5da563ec5c7960293e0ac468dfa0887b5d7a2c1435bd627b22064c64970cfab87b386dd81f6f29ed9721b045c40207a08b19860bcc7eeea890bc6835e58a55dc68c3a7c4d29ed6c256933c9f2287c86286053b473e3ff16116e39cb70ac7be4ecf811eb3e0e6d711de61ee0e1241dd16bc7ff32f912dafe13459296cf23463d68f58e58ac7a4e43817990b7408a2596602a149e5cdb28602acbd648c2a019b2a96e49f2fe02df8e3cd56c89daf95a106c36ccab9663adfa09423195fe7fe20268f29e3c2bc1e299d084683dfdd66dcbeced3059f9abb495bdde08fbab8ec24659b6fbbba6de0bdfffea7537c6c3060b84db013e27adfc3a32eb904cac9988ea553eb3fe1f1058f1e62a8bf8b052396e61a287827c6cbfa1261f7757975907a43f257e180d72a33a165166e4eeedbd2092127fd226ea7fd05e1b0b7760f9416277ec66e27576e06d21d70d7e45e0839c1e5b3253f8809db32c6fb4c784c98f0c4a9c169e5df27c8534875960b35040e0bf54433d8a5ef6130bf7d32f5a4d961a028fa5b787999480e5a217a3516e7a437188ad2cc48d1448e3b1c410b26e5017a91e9c1d2e168446a64e8fd32f62ab870eb03201206942338de790498bd413e3f1d8b293381dbdb8c2920c472cbe1817cbfa3fac77688cefe383f6b60700932630e6b48c5ac8d2dc1d103c5ddb5ff72805f2abf889831f172937c8165529a7359743720b4cc51871125126f297315006c5145b191d7078430b41a725e4bc7c279c61613eca36775950bcadf5c9a451e77c4f2ea41ad8cdb30fc9dbaaacb69acd0de57082dd54155ae2cbdc6d820be15abdecf70d3564c8cee5bcd0a9196c6d59c66c715e52bffec77b7168d2149d7cbafead3bcc78446cf642b1616d340e5794356eb8afab7607d40b1fdab42a26d18c43e069d410e4bc4273900574279a3542b29eb218ce37f4e9dd14dd23066cfcbea2c14d3583d8ffc9095d72e52afad6fcec88479bf0268e4f130e1f5f6f2075607eb268b997f3fdbd6e4b16551b5d22d30416a4780ee7f2a765dac69444049494617a8d54c929692472c48b7541bc5d178d4f6e99e20007c2efc8c608a3f201fb605cdfcd444521c1d6d9bf8b087778c940742ce1bc51b4b105ba0486723ff6190c06ca2ed6483b18a03d3b055c307189a4db85a64e6cc38631f019e031faa8b819c9fa5b299090e883a84dff52177f16c25c70771e57b27d75bb4ed6aa0f5ffcf6137fdad7d449a5106589555ef152356ebbe1e91c3998940b91a7c2daf8f6e0c6216962876b84f99ffe4523a1763d6664ab90f5ad352222f1114ea00da748fa469e221cb996e5403fb86d98ee45a4a14409dff2dca5cbc440215b1044facc70d67aeedba506b5535bfa28f6308b275c636de28bc05e8edd1098fde41928cc0b59714184bfeeb1fff1f6862e5a135a7ce3c3642659046eb1a629829b4d5ceed3d667a2b00cfc729f689bd671bdcba31d4b825da237e6fb8543bc97780934848098c64ccb9a72eace20a21a46034eb01421dc8b084cda08db3eb01e6472d3b9d3ea68a65c6246a3d763bd7383ddc8edc5fbce102da0f000ff128e06ed91dda750f2bf64fe315d1fa9ef9e8a112de41301ccba11e2999f15a554c7d7b649b19c512a5db520f6aabb377cf596411dbaae23743e0cd36af2ffa335afe607f6fc5688cc2e2e409564a1d876198e8c8a383be91374657668ecc3073b5e0768c144604631cedbf99908147c9e071057a2de1141715a72ac53728635315ccff45a8433530246b0d4bb3c4e2ac7f29f025894423755706cf57900d8ededb50224705684f9e1d1f8cbfcabead474607ca4ec160875e619d85c0d1fc396271d87d6410db3b778eb1b33b84ae8b7ad13b82a9fe4fb7db413b69f3fef4c5a64d6ca4228a60f0bfecd0800550f005fa96ae5aaa72869480c902f3b3bad423258549e3c7f452bb828b6013014ff2a9162eba0035a65d89bab1d4b9b448c1c6208e278a6db164e33859c8cca2a2582e29a0fcc8f463769b34dd08acbb85005f9bcfb3e556abf199ef849a6e45036a591cd119547ef601078a87c4f8601f3f81ca8f453df090a4e42dd0d7d10814342b03d59f889b06fa47a5ae520ea2041bc24d38f26d060d16ccac384480c5be696fb80d9b8b65786087b6f8b9f0d72a114cd29da06f8d8d420167d27d3c36d742003ab1b1c1d8305c48d714f867a9d0f99f3e88e5b4ce8a8dae99bba1454f5ade07321e98043a29f8f935d88931fd278ee9bb542d6e83a9a6fc5d9d1fdb852e8d70ffccfa19cc2c44b04a2c2af2b66912f3ecefe81d7feba1f7d385371d75dd9956a8a298c2b95db3e7fe1dc8c488e288719deae31f9d3f16113e6f057c57268ac7eb1458d494026b31257706d1899434e88a8a0971ca54b37eb1aa6de936e19103c0723ddcc070fde14634f32992953340ed00ec786dc1d442d4ec0409bb6aeaeb99c451bc1e2f441b0e0ec9aa350240e7e804f61e76553087517bd03ff2ed41e3a7c1ce2c3bf4bdfebbdf4b70c5649051282973b31e7091127b346e90a7b39545b0b4920a5699fcad68285a89ec38abb028601e91004fad4d70fb9c7b741e13ec6f5b884c81997c2f1e234f4011a87bf82102ca2299dc1d67abcd8d5881932f4f60ed3242e105c5428744ce9bc8a6034659e8674d7d1ea7650060425f6c8dc0b25aa0c7d37cf63ed74aeedc7dcf6d8ec762a1d463b88370496529313dc3f9b3191dd2307300330dbd61741707edd1fe8faf76a612ef443fbeb3b5392bc0740780bc7d81f883fd5a55fb07e0412c2d7f766d5973950531f1fcc4eaf1e42ab39720510ba172f1130a61fee3b28da4acfebb7341c290182383f49032a904e9d33f84d98e31bb28dce20153ed5136f4194d9b2ea2921e47efc42350c4960192b0003eee5595c624082b5bd7a911fcb49e35535d976e5848c92e3f878542dbc2e9285766cbc7ef4b62143d05b9f76117ba2b79c53273a2093bde7bae9b4076262af3bd79d0cb12fa4ed41b19c8b3b67075e884fa2772f9be52895d36a85cd127d5bed6e74531aa25e7a6c8a30ef30c94d7ea8649943170ebd3a25f134b1b60353421a2783dd28ffba98afe67cd64df15e998e62aa8cb21c7d0955ad04e632d4fe97e306c1f5e621ab5451ac6bf64ce15eb2a1272cb5e88aab9b8dbffb53801afd19fdc2649132dd712b99a5b435e1cceabab16a7ce87c37ddc8b3556e067124e9414555831c5d30f360641301233d7279830fd8465f967a7b13085033c3ba538b7b0d69889c5915e0bb0272d0e250aa600b39bcf68e6b76a22a12d3fd964204061aa2bdf363ae3aeb8449e3653ecc5c04f4d49570436ef316e738f37cb67379855af5c741e440dd99cc75f96ae42dd613b022ab0b7e4792fa34e011716f154151e4ef55935c6828f63ad29eb4a5cdf693039cb81a0e5ad437bb75e98e616e03b20f0c2e9488f327fc0207ab9f82e56411a62fdd1577c9e1021e80e0972617739c27e8864dc53c365bb049b4051684992f73d6ee156133a1c5157af058c79ec0f417af11f8921caad915ec58bb6a496d8e8061c8892ec44567e10ed631a24d55ec057f7ba931302bf4f57fea6d1d6809f36d3a4998a73076009868ba6dc81a98e5baa7011efd33d6258b82ecff838fb75d112ecd2985cc601687818cfda1f9d41ae27763805d3cb4b3df5bf21ba07e765319ca3b81a48e660a45122101d14569a64c7846ce3c23625e79e22069d85385b15854f7447e287bea02969e11e68d4dae6eff4d4e0258b6de1bd6c52b310510a5be12f556e63af70f8bde77278a3f4896b959a43b39dc3f07cd320305d358534fd9bd60a002113b673503f51cad556a860ccbf5802c1f061c5a18adf56765733b07b1bd64cbf6d2c4e9afba61193985a43e18f110ed4368f42b65ec4ea5e6ec44bd5409448edcd66200730966d0beed5f2093380a5633e82775d4df6f0213b4fbfb938e972126d023c6516ad0587a56886fcbc1d38da33e5642e544a79acd5e66a10c2334df4e7dbe6724a72a10106cea16c4848f67668d638152c34981b30d26cdb84cdefb05462eecddadea733679b450783812a896f3cff1974ba81e272188915fa36188f821dd72dacb799a2c2ab2d9182c5df52f6d200917411b4af5fa2d489395d7802920232727f0cc201197ca0702a990368734df9fe279393c1600e1f99b76697dfb26f6ea726fd668cf71703df885dddfcf0733415e89d7da095b968a0072096be0cd703380e668407fef336b912b702e45f42f7262e9775ae555d3ac95d308cfa4a824bc99996a847f8ecefc6668f45c94f320e0b1decff1839cb372820f9895dcfa8655d1ad65509ebbffe14c2a81cce3651c8d3c2b3d7666b76dc3c1e761a5b36b8df0b9190ad9217ab66a9f4e1c90aea1150bc66fe62c17c6b2af2180e80c5c26456dc57479ea6b5995f1134d76d70c38b4483422dfd5c9535fcb863291aa5a1883cd09cc0e460186d6279439209ef408b35309e626ce128c13ad29361b62333423164af5ffac5385bafbd5facc8a2f6d35ee6dadc66dde103344d7d30e2c80aae857dc170edddf99c1bc700b23fe61d1571036fa022fad72d1abb97fbf40f012e633ac82c1079c2b5ab85236e14d33d055a6e3b69aeb0be3abbe1401b310d67d51895a762aa3a4ea1b22a5620919b8cf95f774c7f8377293316d125b56623be92c99259c04b01bd20ca567d3fea7dfb2d329bf57768b1dd4ad48cfa14ed5811ac94f56603b075fc7eabf580b6688d81d6343b42f63fcc71494548ec0f7eb889eeb331661b92f63ab765605a83db4e4c909b50c8e1918c058f0214b328045796b8238fa26eb7a6bc2b903b49cfee83a6aa49397043b0cb5023cbd4ec51e0eb34ae1edd312df27788fe09327331531b7dbcae433b6cb46f4e198a164eced7e0687e47079e022948ca92996490ab8895cf6c3702dc8b22c7a483e6a7ea71355db944ca68ff2c937bf3c14dc0b5e9571e356cec3dc67fa66ee418c04cd3b8a595125178dab79508687ad86b9210b9b2e536a0865ae30e858c1fbc4c88a4586c3a911cd38dc36a6afa5fab918f2910a3081d4c706702bb0de2f906a9ab1f4eca442bb06245296bb6c23f55181ba2bcb999984507af9eca9260aaabc0c22d5cf37023d03be96d7f6255177c0de0302d0300cde738cb4534fade5c0316fc1890c4a4b256948db4ac17931e976a2c8eb5651856904d09a065a3a9d68c032e5f06f2849be73a82f292ca781de0c6be5f6fa74838c17d17cb112d7a8323243cc4084d1287726e24479785dc7329df1828e0f7aeb4ff40c351301549c58c29cd633f80a4d454d26614908b56e9f166538703ad0e4d9eec2266bf77ee33c101623097c07c6736469c3bb2cd7960eafa42cbd3df77a342b01b3719c919c0c8754f53b85f72b19d072a522aad9000bc83080c9ade90ae955b814798598d039079459dd80b91859f0a8536eda91181c9e45b4aec6b59c6eaf834061925684f8a50f7bc2ba6ce4cb43fe0a549245bf85c0815331bf07757a0279b12292a1f30a23ffd758919bc3a8c40f1726206372296225752b50894b690ce8e23d1f95847f50be64b1c1ac11b49a240afb13b39a59cda492cf2e26fe456a3328ea35e5523a9d5eedc6a0ef49504c47d1e5ef81dff4768f4430ec4141ea5ce0b2b5c9f40e8a9684a05b4d7094244f2783073e18e40e5074497eb9c3a35e82550a0b35c0a454850553fb7b905858dc362636c8e44432566451e721646afdaf14abc971967808977226269b1be48af2f259b81fef0b30cac4644bbb32f1a2aa8828451ff06a816cdca26f571a486535e46d2c5326cffb062c929448d4d6c9fd60281333d1d429a7f433da25b246b2c7ef42c3afac4c0d348976f86b1c9a7361de68801a85c22451f1df5907bd993d1a3d54b2b58cd7025f65423ed098bbc1d563dce42b5452260cf806ae8162d702b13c099e32442b2c2dc844451adb808c29958798ce3fca84a2923f00d63adc2893701dc39da7df670799f9983e0c53d7005e25cc4807a6e04cb601bcf5de31cf213314665761afcc012a90c1e998ab8ffac1598220e19b0d560ec1bf331fb6d25b1c8e8a211379836d7c553d74d083ff538afb0436ca1857d183ab128cc5857afdaa290690b6b125b347f5543a843189ced4c97416a9b956801bc2c741609e6266b53ac94e324c6abe955022c5a0350d337e28a2cfc4e3af4b333f7922f3a876334354bc32d1b60af767c62c6eb63451247c84e7b61072877b5aac545ba5c83473ba06a9acbb303d9b7e5e8589728cda331319054555ba1c5ae5bfc14b9944e49cb09d6c3b38ebfb689d30b6f67cacc28fd74a2b9b694f1739cb3d5e69b6220f043aab56d1e2fba5562af6468fee2d71d2a3c954ac08eec438c8951e6ba204e8a6233c264085799832cec481d96a4cb2e6c0cf47d445e9b85abef0da101cebec4762e11c4a60f250e1a1eec15af735cd80f3087962a74c338ab94ce0c830375a69943820b4eb338e272702c1593c5735a4781e2cac1289e6353611caf78ec8f91695008dd9e7b95e4a2906129ef08c0868b83e49b668ade3608c24b9734926ea8952e81c516cc046b4cc8f65141cc53bb59b7ad1d052a28819d904e28edc0730bdf6077c6caa70279576826c254d9c5fa665939aa58a2f3cc45fb1325a4b78fd3e5d333d9da30dfb9e64eed1d9ec1dba5ce3fa02ee5b33c559d7c2b635ed82efdf668be63e0261816dc7f45523e6fc7a6b244e845852e16de2544ee0d6207a68b15218fa9b8cff200b262a430cd9f6c2eb1b85d18914b8bc19d017c8dddf621fa12bf00fbe286a4f643b9df20eed4f1f5895179ad93b3262dde663ad587cc31fdf7082addbd2ec4abcbfac48b950c541635d5a522b15902d4bb2aa987004a6bbf7277573fc3d608d00b463d2eb8a4d8dabf08f7428c4f2e7c071fd7b072f0c7fe9988b4753a2d5847527ebc7672f3308b5ac070e99d5c0a8c14c885ee0be2e181d70c082591f8bc325ea1c407f6303b85a09badffbb3e8323007cbfa145bec750a28806ec56f6d8afc2b278657e40fef2804b2243264664c54c1fd49a1af71a8bb2743e5d2b6796075ac1cf9b56b86316ab9ea9011d02eaa7060f4fa72ae2f2e4933bdedc56108fc0d006b43446c76eba7737c11f494864734ecb829213b5b011b8457ff100a4c80f812209e98319a640b741b8141ec505c4bfd135cf4b50055994b1d187518fcbbd429e1c08ca5f4725824df75116c77747af30944484e881958be07022f30a4310b558e2b12f68c14740cdffe03a614c54c3a6d1e93b773b3833af096569517ff205194fffe2e9d27822bef553027185af384052f04a79286146256596863f80d337e73fc7ea4bbba83834dc3580cf5e09632942d1984d55fee1200e3e88802463b578194688f827d256b44a591792c54ed85dd21b4a274e2bd93d8c2cbf66e33ec5faeff19300875c5f4d423258ef0d0655a8a40375fa17889007b6ce70bc5b7445c5699e8e3a1495eebed2b5941b775a7b62a15c86e794ce9e0b23edd9b7443d76edcee68cfa72ca2a7b281b22a00efd298d355a9a100cc1188fd787a0f9b4ae7020861d2c6f34c95df82c88199dce04c83326f3ff5d8022f3180e0db2fda9eac3c53390e826b5287f445a55eba76a30238081e3268e401c7a39a4b248e4180cc019b0010916d266a3242e3c95afa4f9c37d57b53e8c04802d850a65db0fb33d85f48fdf6ca383579ac0731598502a330151cffa6474334c247304563d028154a5a46e95a65be2bc1f0793432361b27186920b857476ab2128a6d94714a0b6aa74abdbbbeee81ea90f84c9b525fa84f9a309aa13c3af8d151fb23f56fc22da5036d721977f525c1f2527f7d7c61ef3de16628c06dc6de3d8f272e13566984e9ca80cbc2746c13e6077e1f98d87588722173e3a235c62f2d90b2ac6ccb5ba2a606750d15dd9eb1c6fce3d06da01c8a87784ed4a3b0173f6534cbb24c419e5b189c80dd945d9c753c07050f5b0f03de70dfdf63bd1b6da00db418c0598c53ebb165d5b0b26b601975e920c9c3624d6c5df23ae072b1c89b2a5c37bc4ffd350dcbec790eab12e66d43821fbcd0b510d6ff6e554efc4222ef5d493e54b9f69be3642f9e0b569bc96e9b4687ea52388abd7f3878b8b14a3bf4a45f00bff17f053007dc03be68c767167236cbca7ecaf1bfcb1be1aeaa32d5c3f48e934fc10e82ef14cb501260f25ff6d23b24d1f59181f06ed968ce7933990f1a5d50b0bc4e252aec18d0f3a5e0edc12b16846b6f0999da8bdc1f9e8a743329280a8dc4c6ac41fc03e3049a9151bfec15273088281d0abe28558994460b2a237bdcf505c4401b0083ee92365beb28462f5497f1c2d57550d31e0192bbd055c6c61bbb7aded79d6752554600150bb14b65d96453f3ae82a813ce0c4abf70654cde1639531c01bd0efc989a5de10dd3656a0e3641aea204b980d3d4cd70dc3cbea6bad9ecc305b7a947e4d69d00fe36124e75302fe05b81631d0a01c8c37753e744e551da6e8789a83f99bb256862ffb991a57e6a02f264ab2ddea497de3633914bc8f53aa40815423e17a3d9772976f7b3920428730c5092704427c5fbc5448bee295de6bbe4da0a2927cf14a81de4a8479426d12e25bfcd9d0e4a720b8b051205cc434edf070e4b495f4f8bafbc722299af2b7bc516595e6243af86eafa059ef9a8241b17b13581162dc940a45e8a987b7dfb7142d4e5e39796137c35ae09163b56aa58d16ac56b033f25082f478e780e83a87e008efb815139137374c47b78f227cfb752b6c677b4ef1861d0a5cbb60ae73a4a0554cba50341640a22256eb4724da21de90e264212ac6b6e694c5d678341f62abcb7e94a7e6a24becc70a5ef60a5bc5b7b673fbde0e128cb0ddf169a70bec3a961d7e60d29e87f523ec08d3954aefca0e99a5201fa54a41ba0ca3a02e991e750aaa5468690e9b970b6f7ea9fbed0737bfa7f5903f97909ed399af414731a08926be414eb2e8a108cd99d54532f104bee06bfd519a64d208316e86d081adffd7ab5ce23fe9beeb6c5d66f456f81774afb6498eb769bda9b10ced7af2386644a6c7cefac4417fb5615361fdf015c5838c13bd9f93eb614867b5c46781d15a0e5d65cdf06d02b4b9fa832937a009d5fe3718bc1b6f49a690661eedc5cba9c345894a25ca7ceb6032fd6dabb2a960188d3056e95d374663d02611950fc7badbf9b39cafc8c721e016cba5004aa2280d87b30bdfbd0d91193032dee2d166ebc90de7345faae765b622e9631d4764a4e4e050a9517ae2998b1a2f77c900a62f0040a23630462d022356dfdfc4a95cec25145a812bafce7df40f5192b62f9c8e24018ec8b40e0550198dedfdacbd5268e8c2bc4dda4479caeb9c47ef51a59050f406e00a8bf8cc053979b096ca43c16b54cce728dd62cf81ef9b7dcf7921e931845b6341bc796ffc4bbb71bd5003438d546faaac77c628aad307ae442ae6aadbe168889de0fea0ace860631c3ddf73c03c2a3ee029865112a1a01ae1fda3908bd57f6d443d87b47019a7f10c6ec9caaca787e3fa1ccd5c409253d41c0390823873341d4b13811f97ec30b2cdfe5071a5b15f0e972950022b5c692de81469015487bf28504a5c8b87665fc304c5e250ef218e73ed4c5c3b48dabbeb4519e1de88c63797dd48c49f4782d431a56c7512fd6a5c05bec1b5ed011d52fc926c3f4440319d3f4e2e2928b13fb0ee21217df3bfedc24bfd5dc32d5776dbba5cb609a77bf281d9e0c0c0527498e798c0700bf8d8e61efb9ae4dc1cec9d4be69801f32694a0590033e3d4244f47f8d997ad71df374134d755dd11b2a535163b5aa13f47292449394e3f79c218d8151a583d0cb9b1f2627bd49df3e79f47c18ef0713d58fa8fef8a886ab11904077c01992f0541364843721c48abf116e19c4da80cbff9613e7e41397b2f0513355891a6c82efb9ac7a762d1ce5cf0cc7de95a2c0e0ef3ee4a933656e7ac25908987fc5110e30bc8e85d30faa2b69919e4f1dc0a367a03a22b08b993a35a494d99583602d913d10bc61cf12f4c84e3b0cb1aa6eb83fd9c1770f036bd706ad927f592396f59506a5c95d6643339b8ab39e0005a61ea31a1cd9427869940ff882765512d921ef18f3e87f82c461baa7044a11bf419e80ae2f5383560707c63c199fcb9e96b673ac12cd0ccab45249c5e3679d6bab0d11096469c5da63c10d8adbc28c25a70b430b53075e17861eae0ebe26dcd08b2857f2656d894ed4cb0add00f7528bdf333a03a24a6e595c15a361ccce2b7996b2a81efd0afdb50c351cdcb2a039b2bc3321039e5723214e76fa9f5be9cea908d1456b4aa0913534b231b6fce81b14f5fe19f53ed3eba95f1aa283397cdea90c403a06d2310684e13b956be29d084f960701d92796bec60019ebd9801504d04e7c1da44ea7a130ce50c1a55cb261d40b3202cf845bd74d6d543b71852127bd5803225a0096eedb2863ae47e7727d1726ff1958b04c246730876cf93302df689cb58825f21aed683f526a9cdcafe229db5a312558f8952b128995e15212e53849b9ff507505cb0260bcf6bf5eadc540431ca33520b21bcac828ec0dc00872949cdcb513e0cbaf3c649a252af75d775dd9de841329cdaa689d0a45afd6c689972f34212629448acae30a91136f0e7136f88868e1514564bb3946442b1047742eff11efd1351252289a04da84a884e8bc5be248a506a164a3a4cc71ec0b78424fecdb7032d48ba0e1b75c9cef4286ce7ade2b2b28c446e9b13a7a5a42e2789337fca78dc9b24690a4712367b08732645d8c1f07c32badf1c978751238e4865725c6badd8871b76d7060d79047b18b36de69daf89eae0de35fb409e344ed006923f8a5631138199262e1a2d872358069741d009f88ff7c205d2b99abc0c425cbff51330d3706bc8d67f888c8dbc87b60098cf66a768f0c53d1e4f1579ef46bb2e926f26e41f555a453d552c740a237deaaddda2fce1b34a1f6701f0e4f48b018072435372991942332b45de8007ad274c78d7e099865e2f16d1211f925bf004254a10ce701a05d4548fc4b0f5dc3f5ac14b689f630ff65eec42da10f1f0d32eaaf3ed6ef145ed1328398f8e8d1872af641c3efd03983e5caf6e7292eda8d15a3053fc136c7901d2409988ba78ec6197b3b6906d9759aa5f201f76bd9cbd5619a4f122dc92f774af532abc5b0aaab2f0507803c5809f126f8b23707a5cc26a08c1f8da8b26d149ac3fa4a79928807ff333368f9edbbaddce288319abe4616c611b01563802847e9abe3a346d0a993d6d03a6771e90a8cbbb8c6b0deecf1917a3c9307e12db9abaa20b4d5d4c6d9c284fa8720dc76a99e03f210eb7e7b2e100a7e2ccef3df59d7eceb5b2b3f39f91d88ce206612e5cb0165a359e070efdfd6372b996a10b109f3dbf39b43260057ec9dba8b6c8d9d1e394936ab2e21e96d6d5b442089d47b42550de52df71e8b73b82cb830b12210eb62372e56ede66c38dd56a76c244eff080a10291ae63f55f568fcd89e4a3b1d14a0ca38c0e4a4aa1d0e2c72958ab15afb84bf5ccfd8707f4969a7bc3753e7f3bfbe7cda39c25bd59e7f15d1e03362cf9648a27cbf3d4c190e219f25101673832260114c99c2906b7b7afbfac36b18251217c7a439d971f20f03e09bc4c2b83680ce484de08d239f9c64d23820c96de5f001e7f653d6ed5714e591cce005647774574b778f9b93a3965092266bc3351af632a11630a4dba519aff92e3d8e0e3786ddcb17e1ed5d7d227dc62e174e576bf3840e42e478af666222ef42d4a45349b4ddc4d68e825905e9089449ce255dc3205db619cb140d05817390ff533ae73752cea71eb554ac022327039858bdabcac92353922b6f7872e96286e55f7e769cfa111104b8205b3f27bc8720858b9a0000008f5ecb4e50ab660a49f52f008d6fe07d6923cbc7adef8d4b298fe9c737fa601bbf4e48895d2cba3095db4f1be587afa951f0e6d69948828de7aced2cbdf5a6543621d77716b4be7115b6b5e2efe1dd8aa463dd2c3a1db01b3e9409ebdee8e832de81c047d49cb035db35b4b02253f31a307c26a4f9993653682537cff1554de6b161ad278d39c9a156d8a491c8db5750692fc5560186b48106a8c257e6a7937e98a669632191cff8f647db764ddc20a3568e42f12bf7d83d20af9c6e15fbe5e65b056bf52216d5f61617da5eae90d6b32fefe0aaecd318f44a388f903333e19c432bd494e4e193f5852b8921b6ab249903e15ec31271ed62f3eb0852618ebd856d3229355ae5c3a2395756b3688663ca8ea0383d5c810c4c90b704983576eb382375392adcbab21799fec542e872aad8d97cc13953132cf77ab2a8e2ce5f3aed1219ad7201a577171a64dc2371d779d85b56a2e6f778bc11d208f67445fd33e5a008fbf54658c66191b7d7a9cf0c145fcce97928a2f36ceb5de11a39aa3330eaf93753e229563c88044cbbb3b01bb05ef5283d29f9624115b2345c04179d342d52f848bc214bc8dac651254681c9bbc98104f6bad713daba8505696d3bacb51a580fb41edd12075681986c070bff1f4f497eb014c15320090e025407921f8a4fdd924334cbb22d129f0597bdd53cfcd735182c135676f45982ddf8d8a1dd832111352ca489b30f4128de1481f09f21c2c044ddb55f42e6a74490d32c175dbe19cc3aaf0526434608ffa42eb5582414b4e15e8b38c56aad508a905788934fac28be296bc9353e1826cb939b01ec568f97e0dcac90124a26714f5ddb147d0f3d28af552a10801e19b377a6de121db63dd1b5da4765604e984c11b3beaf7e6e359a7bf520e88149d7cac9f3e656ba2a3ecbc168f8c888c31d722d3a6aa5bf31bb97426ab034f6339b824f2823b2a2244d08685b61110377d433752d097fcb50901a1c4c1ea99b844908e51693f6b0a6263dea32c8cdf3bf3433f0215105dfd6d9e52e3d41de3f1f55ee10fc7dd2ead694284ca5d9abdf2bc9e410832850740ce9e92eb1db5e6ed5a922381a5929d104c77d874d2197f030b58c271b592de14ad853185a3033d71089b5d82175cb042e6ca6b6b8ca010a005a249481bb0bc6a237f2a298abe74bd88aa0153a9254f5a938c1eee0b60832d730d9c9a0a0549f0a6c7ca658f19d64b7c9160af25173d6256a73f2ad72ee4d99a8cf11e8aa553ab66937b05798a91d9c06b149942a60d86bbdc5a53895f5e21166a892da4ba1a9a52bd46cd1018614d63398e06f63f5034b34f9f6b79e008615d092b02cf917256c3b9b8d6dba07238fe567bb70029bcfba7ba2fa2eb84d4a8858dee4e5a4c14172abdd9b6da020bfad74c5729653063a611b27ea4c8d900008c7565711ce5aae7b10189449136c6b9096797e3a97fa1e581df8fb68ba2f2170358bd688c485fd39778774218f11d4db634818b5e807385e73d7d6c50d19f6711f622891d4acc93ee38044e283f2b182ee09e1d0b44fc5108a59a4028e8971613918f4033d5dc9c66f67f98b670684a48e8e9118c20a50d1c63ccbf65937ea8d9d64deb6dc9f106d4b3e8f8167ffc214f985c8a265ab195ac2e8b438d628176749a21b15f9310f441aa9d3983d54737bf7e03ca4e78780c03f1ad481c782b31ff76fad990ae3b92f93eeefc9d35b27c617f578c2625281e244a1164011bdab32a8e5b400c1b365a585f4da943f80c8e045a72ea4accf4ac9219f8b8aab645fb4a8655b1e49c1473bd0c560c474c3c3ccdc57a38fb12238df2bc87019839eb59b2b6f97a6c8e249c6bd13ca0da487921675a3239157e672c357be7dfc6b68ba7e501d69d650f6a854a8a9820a4b58c3b78b852d5223e74680ed493a105f18e4e62966629481e95022f420140510258268e15491b761f8ddf496fc62f2402a2478011a2cf3180513ea59970398ce545fdb14ef2529ffb774623a560e9333ec73c04c472247c127d65ec0281b59d82747cc7504def59c45bf9c0ff6cf4bed95bc5599db363c20bba9d3bdf0c19506e613763ba01aed189a4fda0a6d4286a0656813b36eabc09734f4a52f3ba7466db27e5d69c97002966c2fb549db6d54dd002c617db6827955ac03cd78180739f0cc6d4e40e4cad021be80bc7e350ad525cd13494c8b642976f462704ea59122d4927d17308b580cb3dcab4bbd47484123f8561c9011510c04e307d1ff366bb6ebb54df33346c563656a9200a138e5ad040631f30d94b60c2ef61486a3e3376b52b92901e10146777b1d477cb5bda650abc0ea5e3e39082c3746d139417c460d29701594491a8246fa5813ac0299155f4ae1e9eae0f4ab51ece8e2131f32d9c5b1261df3e1753e58ef2a055e3291d8dca559f4ddca447f590a450ad747a229730dacc43b6d40debcb5641629c796ca62c2855912a4c18f6ae1bd84a420a94a5a8186f3464bcfce700d1ce97de895bbf335cc95a7bb71746564fd2c53e9148c5a41d90d0ae44ed0cca084d72388faf7efb543d7d6a620558e6e500a37917826ce37932996476563c2a5841574d02f1b7783464bd2b41b80224f26094d7f54e3aa40c9bed2510694482066c7c1377418da5192ee8e0d38710c1f28e9fbb848f9d98c7465a6d3ef52a2aace09e617431c81cdff368834d54d63e307e365594420addbaa978c827bb1c657b9568b5ea5078df3e73453af9cb24f7e18ba5d2908b91b0446f84d62a5f5300a9027435cf33b1abd549cd2eba0304388e2ff95d9f01a25e720332dfec20f82ac0b703bf90f77f8ffc340a0c582916df2ec2609a0ec875bdd67e9af0aeab87952027740cc262703b4d55d3cfc4052ac661065daafe29a7d430a2f83d23154664fced00e5a9c81eeeeba4e043e9ff077b95726f098c6def77bbfd78f207f059a5ec233280a132da5af17e590805cad5efdb628b1f319b016332840fa9556699941a5d076cc998ef2dbe57fa29e29027eb85426099958546d2b112bd6a931da8095ab25ec4139ffd59579f4121a5e4376bcddb6fcd7c916267e9e90469f3835f4a88e48b02a0a79a7d920c9ca8f7df63f470daf5a0d5e45130dda5107a181d4095e4df48e68b0d3a2dc6c1ab1e726ec789fe449193eab0c300ac5adfbce0970f916fda8542f9b4fbc6982b5c5417d1182262c4705d584587f63f1c7ad7228d70a139eff5de97867a6b8e78da9052923c5e4ae4967f027165f4cdc438381d9e86d11502cd2e9392bc25b9dccd5465dde24e900b38867b75e801f48fc59bb5fe5e3fd4a2258eb032f1c80976d1e0cce149415c83fc07e41c8328e9e2758012a380a02b7b01262937dce41848af679b9e1c0c8f75ec68bddbd6e421bc449e6c0f49af4450eeac5f3d425206d01ca0917b8177b2219ffc811bd77025fe28802bdfdfd922a0326cea902e57ab606370415a05560b818024069801543191188f634ef8ee0e662e65c2a047315a3b2bfa52816a693877efdb78a5f87721eb9286821c02ad87db746fc1e538fe2ed6830723fdeb165aa88e10c44db1a9f8abf33f8769433e6d5295796a908036238c9c37047e800a6d1b1e297d67ecb09b640f56bc4b526ea1e9bacf7d51eb2604a1ef269488ee0c940bd73ad5f94ee69a7af7a1b8ac2578ec5f349141875dba4cc1a45d2809fb16e391eacc36642b516e4fa6a919ee9098f77da937b19581c8dbc23b08bc37a9e4eb30d4875300577aaa83f2e8ddce707b80678e4293fcf4a5c38d8f48a10bbdfa9673bd283bde7c095d7828a885a74f272f6c725d639477f3fc1c225d137efec2d6ce6dce8e7dd5ff4112f7ca325851ab17aefdb8f193fd90b4f1eccf7d0b3f97553066a8b7dd96e762f57d6f88738e1a253abb20696748b0a3d6bb842f56a2abe87e2a2d74684f6a624dd5c341df2c3a84da8afc4d153024167fcfa0e9e5e190adf483a1b66feea67d8cbe16f5d996f58e7ba875fbd765e8cf7125cbcf96a5e16dc2b10b1c5457aa3ddab0e1d8ce3d2ada9c2cee280289033efb110b391819c3f648f6e2a18dd381b747929804fa426ee7308141177435788e13dde458a4c82fa2ae182252c35ce8c4e0531dd24a4fd6710d51f61c66522019c529efd0401dec1e381c6b61863e9d02c60735cc361b7b9526e727b56b2b05394aaf4fe2fa1442942eededae79d87e9f7664df8beddc871ceb91e7f35dcf0d7d8e8ae4a114706d5a73a79f8d67da370566b2903c536fb0ae1aaf0c3d4ae472401abb7d314af7bc4b0cfa10a2812350aeb71e3366f8df18394192d40ed6ab4000d6f2ce15203a003e865ae18d5dca707d0debf6a3f6b2d3cc30f026c6b03ea5f027a5a30d0324e072aeb105c73e08ba0650d7c03b953252ba7c27bb097f7d60438f803db72d829ce7b65b700727341787bef3b0800d1f089011082878b3b7493d7c1f9037a28c01e70edfdbf498ae5e9343e0a35b2f7de724b996492297a07b0079007b7dbbcd38abb6ce2a506eb9fe411093a581d42582161b5a194c9c03bdbd717225df247b2ead7982facf6939df867020951f9235d52d6acfab5da5a4f1bea93480dd63f7d52d660fd6d258f78b048527674da4edb277fecfc6f0c2cb7be573f6c6d9f94f14dfd9e26c3ca0fa5ecd6a73fb2566b99fecc1bfee557ed48b21cef06fbe0892c9490814486900830d07715ac3f75ff1dec8ea4f885ff777baa1d20dedad3f4b2a9003fe7d315c71ae812ddc7ed4278ad4e7fe5318ffc8ed6552a6be9577faf416fea369de3f67a61165ffad50050c03007b786e96040d132069631827680e9b225061629d912a4458962d18416a0190ca95077c0acf65d6da2c8533f9ff5142e8626b5af89e4d753f08dbf0cecb2e7514a5b7ab77ef3ac2d639da141def9893cf3f359ecd103efd4cfc5e01b174284cfa6cfa44b5b7225f7e24b0e66c22692f9c33b75c63bf13d0b9f3ed513711fda586b512a9f3f43589f4d24bdd420cc5b3998957b69d0bf57aed4a0fb4cb2d4e0bed0c6270f0cfacfea377ff8c69f4792192dc94af22456fb424ed290ea8fd710bc3ff2c79ffd6772f54118db3fd3d2a0cfa9adba5a6bad957e3e6bd0bfa76b74b0a1cf7cd62eef1c22f799bb7b521ddaa28b5f8006e30361e61300f9122fb147231196e3327313308fd954348a128b6c7777d74a780a51ecf64c7f0a977927c78d401fe016ba433891c191d28df7d9b048415ddcf85996929c48d8595c458848570ce2a5f61214c433a0f845a44af585dd0490c7202983827e7870e510ec427d6c20d4279796be8d3066fd312848d2a4b934c5d012edd0c84c90eecacb5f48c3eda7210649170a15bf88447db108091098fb0dc522be898f652908cc52e77416524a391489aabc1b7148bafa0331b6d00b7e00f14dfc0763ebe52953285d14ea33b2815e6d705b86c43b5db04be6e3d464beeafc158980c437b1bbf8420913a1bfdcd868dcd865dc089485dfb0611715b5518c60524baccb535490e4c61bc6a55be4ddb04578a73f3e06d8d555644b377eb161cb6e7cc9ff51d68207b7bf96f1cd920d1b08f5b1bba03e1c1c1b9b9a2ff2a7bd4e5fcb24ab0d1bf68e21a22473f6c4d10d1b8bd294147020728cf547173be5f2941478b9de4840535810bbf17663f1c276fd6c58daddd3e4c31ec4344089a258d439fc0d24a391f338934f775a2eaf64ae9b82f087938fa460e3f26ade683200bf7fdc410dc6066a302a61c4538896dc78c306329910c0dfdf9f031a8c6f9aa185befd41fcf66d17f826bebb472694a613487cca0f141e675434505433ccb276719216bf393c650727b1bddc5e923096bd6a00099a082ad23933a04d2be99cfaa4a8812ed8c9a2791bb04413bcd3dfcc0ffa35375dbe659295420aec4cbf097766c8e9514b845ea78f79c434408923329c1b16c87ad64932a4b8a4734cb8718a0e586ec846ac1e49aac773ce3927f3f4ef912bffea673b08c3f2a78c2cff8e99e52f4704b63da6014a20f1f1c94461f9439c5bfbf351a39f38c92f7eb51f094907a9c5a0ec1fc9fa912ec924b2fa6b8d3f3fb71db69245921591225244aad261b72b6c072b8b3c34487b22f8269445b7a99095db4f83224f4da244f04ee5c237df57dcb02ba24231c9e2a230ab28ec6860c6cfc00b59b7c6edce74c5ed9a14793838b80717dee1c280e141860d3930b79f8b4957d76aad4af5df4acdc56ebf3c013bc139fefd5205ecea8a248b49e4a94ab1476fa1924cfabb8885593156e11e319671635774db4a1a3b6056be229554584661b0bf2b922e698595228f2c9a6d71db0b99cca22ac925bee9a74950261f159245f3432ac4b24ff4956ab556a5fa07c1b0956070c3e8050557168ffa7502327dd1714d0d1444d818eff4a53e3384fef69bb69a19a259c98a7c8ae106fb9bf9c154aa985140d5e873cf2f6e53f7f70a06f9cd04e90f86392fc054aa50924657ae98ca0b62b75732b0d18c02bca74f3f1bb8ba9a5100d59ebad0bdf6cd0cd1b6d7e8e702c73dfd66ea67a43ef5be1e922c2e96ae5e5bbd387ed515bfb4170962c4e23752fc8e7551cf1c8eaebfebfcc38e16e649b202f14dfd40156ae3f610b73f6a4a92d5a75b93c47a927469495a12df546d49fbc23c1c1a71c529bdc12e4e0d66f5b75a238c0002083333396ec8859ad20f1e63d8988c23ea15826ebf06d2a46a8978e7749bb3ddcfedaf1f97e43f58ffb16175e2f68733c6255525e9aa56d8d5c964bc53857986d8c5115527b6c8ec0cbcb85d6463b73fa2dbb06ebed8d48207d970c66e7b2dab2cf2c8af63b18716bc13bf8601dff437086b10dd06399974b515ccea8f52addcee64b7bb2d0998ab8ef14dbfafba0aeed1cf638b951f6a489e348371b06d265dad1608fe871c8c8355bacde636bbfdf347b29ac90d55d7868ca421ddfe2e21b0aee4491fff84306ce849f632150fd4e0b6d591ae0abb1dabb23abfb05a1b3fd9edfaf54cb21a0c1b7ad2ed564abafdf283309e9035a26304d889d3edeeee2ee587737ead06a3fcbf42a48b032d90ace45085062708a34305521041c5921ea800e21261c3eed28577fac6efe9be9921de09f547668674a623aff8a8551771b121c7b846616d6a74b0612bb459cd74b73af2ea5a6948f7de67c434c4fbd367e4f4de7730d45d3aa795da75b95c2e4b0db2095a6c6841538d0a6c175c38b9f31fe907198801764e0455e12566bd5400e4572b8325b6d0e2190d2ed600a203961b42f55c8756b861ea48a9660b25b7bf5554f01577042b63f411ecf6d115b73fea40b192c4ed965590ca282ae367753be6f716665ae0db5fc832e250a5282929a988471659968d8d2aa7216455c064523861c5e880090b2294951fbc2844a718105d11135394147880cb22e62de1c386c54ff753af48e2a21cf1a3256d519200417d624054b3682388e903858996c51610b8cf1540348ba30f489f2748330b2b3ed03e45489e05143f449f2c96248b6b164900f96031932cae1d3889b2f484bb61090a254b4d684e96823ab86c144607293a2b1d50b5d82eaa236bf484a686fad0525d378b93f228c342bb5868567c23a3a3232c585e68d70bcd8a8f836363e379a9140d8a53881f96709915fffa17ce70e5a75d89b22a724861438fae200470f97d9cc086aea259e1f2e7c8c23b333fe28d7ce383672786875a93c2e55741884d8773fd84c0459773f97998f05030556b55aa7f106ce9e05cfe1f810debe984cbafc20fca047e9711312d253674991e97ff8f6c587390f0a4832b36f4d44d110f2e6ce87703fe12a0e0803f754507fc519bd7e5eda647b55378e446d693e10128b443850e11629014fe0da8b0343c2e3f8f1300a0e603102293bbc68eafe804247e75f95d29b0615dbd6cc71adf0e594d096ce820d8948ae66b3eb8fc3c4f0070795c7e1f2fb0a18730b3b4c48655041d46bf830d1df440a6021b56966af6847fc84f8c9a1569685229cfeb46d819c386d56603259e2e6e78cc48e051d46387096ce8377e0fa00436f41206b0c504d4093e927054ff20d86ae90c00054f470f286c0e4d151bba8b93b5603a3a77a543bfac78bbd8e6ee20b2a1f3783e64d050c1ab2d250f2856f0aa74b14abe046f4d1036ac37aea0820f9e9d14745c3928e09c00c2b712c076e517dad02dc29254c4a9261f9f3e9fd971620f109439def3b7bace6b75771d90d8830b6b2e78bbe7af958633f9d46dd559295736b147fc4ef3bcce99b21d6c58af4193cfe4366ee336fadb17ce1ff335f9d37f7e354c02ec0813268c573ed2c5ae055d19b7432501dd1afac789b9dc0ec559faf203ba4ebafc808aa533c43058aebbfbb89d4f39a5a4384e2975774f793fb9353789b6942f34283b562157b5aa54ddcd7ee517ce70fb8b31eab8268cb1a54faad58deb64b68d487555daaa7e1c2f5d5c3d3e849ad5afc2a9a1a81b854478a2ab7f55a3b427169b3944a8fc82ca87c5b9359d0a043bd3d5c81ef1b3c04f85e8742d0a4d219e452121132a855b022b0a45de180685f9ef0b097df4ebf45a6b8e5a63074ad07022e1f2e7ee2f594168a021dcf8d130d3354cefb0bbab64f18c6f974d431c061b1261b0d77c8f7990f892865e1a6a9852fe58afde37628cd1a93625fddc9d793ae2c41e2ca5045f4a29a1d8f89a4e2bf471b92390d8a37930018a6d9e8e36b147943cc855f857bafb6429a534b9d17535cc8ebb5797d549e92e5d47de30a16970bb5eaf76e7ed47492836fe4c90286f7f10bff28647aebcd2b225d52ad745198ae338a79db681a10b5bdd6a913b9fddc8a45e8d67fa97315da53e3dd3a62dd1f529d7fdedaeb6ddba7541a6a9721eb7d1a854d5522a437d6a1bd72d617de827f353eb47ae7ee55c039706991cfbb47d5c59a0a91e2e6db8328894c9e1b14bd9c33748accc99b05eed22c774697a02e8b6f65dcb9654ab5c67f24ef3511ed38ae3eeb5c8d598ddf3d9d574a67fee412091473eabb6168e8e8f1e165aa09c44fe725cb7551a954a43ed8059972e148d4de491f2d28a5a9d56427a24ab04323bd8e8ad2683dbf63e2383db6ba6207ebbedfd0b35a099824c8e7de2ea0a4883bd62a1c14ed92bb6877b5f3a7d748e77325e8e1c261ffa26edeb718f74c54203e959010ceb551f9d432f7fe7a726aaab6ccb4e59414765669231394518151a5c1e8772e7a422c41418a8ec8a6f586363c4458a0f574a8972e514218c94b4ec94f97c6f731648aa671fb4aa16121dfb7c36116005c37ca74dbf19207ce9b7c097f617cebf40bc3ddd1f37d8ad3f4dde025fd37b1d9f3efcfebb556f5bf17dded99ebec4d274258f9a55adf04dfd10041e59857bd4e7ef28655da641b7aed8453b56ba464308cdae685b568092c2bce556fac5ad748bdb84a912aa2b6c0bb846614f40d245bf82748719b63e2dea9c2b98876fa558d4da5f68ad34f9cca7da67a4497d838a21991a33d84bfbea02bab0fc1ac14a1b600cc1602f7ee120c3847935e9df3caf7e34f93c89af0d563343a811148a78d18f256b6612dd4a9fcec80f27933b878c441ed828020a356a18555e4db83ff2ea17bf98af30428b11bc8c6ca08bf26a82fa0d502cb05713ee438b4211af507559a973ac97ce8991b2339ab8f5a912467010329a742b1d9295c8c66eb5c2a1f4e25639835ba519b7fecc8f94995c32fde17e6884b0393e94b16af9156764e80fef80b73e4dc23bf3ebd3279d13f3f569ac03ec9a48925583b864dcfa215d224493689174b534d8ad74e956aa742b9d51242abb4f896e8df14dfd89245db38a29236342b97522c97c09e817fda69064ad4ed77fb0e144f21c6c38856ead3f857827defa130976b59855bf5626ec13b7b2e0d69e2bac0492ac5a7fe687ba03664d377c17b4a74092559f4d0aa04f7f3c894c763b926c475387d48480d3872ef3bcb385b199a185fa414e9fff0e2e36bed79731f0c67c354983f6f39f5517524af981ce03348e74ad2bfde5af645575773ceae9e9e99ce8e25a3ad55a958a5bbdd0ac466286a4b260d8f81a5dc2043088c4623322b3d90ce62d9790d3b5f6afb4654b9937bd347d27b3ea62d6daee6d0157501f738a399dbe47da95af422f2563f27ead76edfa55c0267e206a8a7f48a3b2f1cf6b3a27856a4aa5eb3a9e7576b27b96afc3bf9ac458832e5980b2b9a8ef52f11110bfae8b5efd233e32dfc5fe2357ca5ec5e4b039b655d8b36bbf477a3fbc477d71fe696553610c36b7fb2a6073b9f931d6ad916c5af5dbe686436e7f15b0b9f183a17efd5058d890461583cdad0d469acf6b3a67daa65e68a0040d26684091f221d3a50930b2986a39affab36a0b1916d7e975c19f88e71fba2765f4c00c27eeb551c73591b9ebee6ee69e3bf56b8df541abe2648c2a53f7d16000ed5968b07ebc950411dc7c61432b13860d63485dfacdf8f305d2609cf1f7eb5f0f0b24c41ef4b62dc68318f357888cdf0384675a11662c51411497a598d184ede0744619513029e374540650921b2188258da1e4471cb3a429412dc080925ef0c34f521340fc0853748615e1b2d11b56783f6f98e08d378030617923071514e05b2965abacb79e7ebfe867c486d7fc66bec4af778e7cee8f20d86af58dd73bb618224061e3f3d3a9cd3aa7a53a1dadeaab6429979819d2affe7ef567c486d70662d330624bcf05950ca9566b55aa7f5e2a225929b08d14978a2c2d2df1cfd7eb7bbe78687a116e2dbfe5c79225df243baaa0e3f1604bd55cfc4b1e6c7c2965757797746ab3ce095aaaea8e2a7667fab12a3a7bf58167fc5e56adaeac56eb8a41e7d10039e79c105835a573ceb9f2b9a58bf2ff06eb3e9932bf8ac107b96567adaf520579da31979fc857a756929628395162c233615772fff08e8f2b9db8f285b45a20f82fa59452461985e43793807eb1f41f6cd83f9109131e2536be1c927f4218dbb2d6f8fd4cd85052122525180852c848e20c2d6714c5608a4bca184ece5052839900b6106dd1e2b2942d45392ea7438bac06301a0859293348eaa2c40c558b01a6bbbba3e3cc208994527e94ddb1e52b5125044b97abe8e0e47670b98a0e24b86962fb7f34b12c250b1327a48780c5f6ff30819234223aea4e860a5bb905441f7c615b46a25a7313c5c66729599870395060594a962459926c35042f9494349a838ca3a3e96358ed59ca8c48f68a724fb767cad595576911fac9608448ec65fae717f8decaf4d1c4801db197e9ff7e33f4e3cbfb8cc497f7deca0ee19bb90309beb58606271fdd39a473b69f5f57321469703e4e143b539f5fde87dcc269d96074e568e8862c5dd2982fc3fc22f3ebca5bdd18e9cc97a10812d6010dce8fd785068734389f8425f6071396a5cc965cfaac74672b044dba0021b4c31470bce6111750390119606480431a485ef36528f25a8d2166a1cf40272d3aae095946537d748e9b20082437dcf82c3f7584175f668b0debad35729fee8f0d7ddc9806942437dc18e5ca2ff41b02cc86b509bfc7fe9925e1b2c425e98a3092e042c4e587830eb4e0862d4a026b9ba07cb0a7cb52c038a26a0103488d2fc268707ca1f445921148324b7e505d10c5d49615a024a76aab67ad951c7c3081c104555b6078f0aaad9e2d3ad5a0c392649a810f5c1844de151e362c439d16b21e2a18491c0c34d8565b5a0c8180565b3debd305901623f080174b5a0cc1c395580f7236ab84016a9f2f9878ab5649a303b1a5d3c2d10923a94a520f3e57603a94d0a8b841c484c30d1f9480a303677cf1250b85e28bac872f55783b58d365a32f50988ab0de65a32f4c8cf8e99877a6cb8e2ce6b9859c326e33b6a6b5a431b57dc66c76d3316b3e4ea6f3397cade5532ec6f9dcdf1d799ae328a5f2b79f5fe55e7627f9b54aee2bc7750b6784cbf2ac6aee6cafc3f2b1adfcca11e66fabbe3a4c3e717a334e9c6ab3ade28d3675be0eebc60747003d9b524d95ecab63a23c2be98a1b748d53aa79e3d76820ff0e36ac3768f2d1982b3d9928572d7e54b299d27531c6d81f5d767bb7b79c73b6a6fd0e9eb335aab59452aedc5d4a29fb677ff789f9664341175b7ad2dda79c94f66f31ff3d1e54962d61d5f3ffb19e582c46ef16f32e7e4d47eae158cf29055db4d5db5677cf3273f5e9c5150ddcad61ae706c6c75cd1b8ca9eef66ad5ea1119b72d556b3add25f539e77c8f3d289d734e977d8384f52879b841a272c5a19b9aec5a3d6e1c7ceeeed6ddebd712c5b6a2382ab95bfe06b7573836a895c7c1e7ee6eddbd7e1eafdf0edd3d15dd3dfceefcb6d8831ff5456c9f54ca23a856b5bad1d4b66ddcac5ce7521ed1bd4ba733cad7fa8506fd23e2d5ea799ea98f90479852b313ca33f9d04711f1f8e688d3b6810762f3d4b6d4a66d1c4d711cd7cd4d761cc7ab7410891288aeedb72fd5acc881ed431ddc8732d1d5f1acab95b3f6fb54caf366703ecdc0a51f2f7f471e4d7a8ff93ceba5df0b0d12e14c2653e4893cbd237d6ab5152b721169a73a139829793a997ce89f4c2d441eaed191ace620157bb49c1189a153912702dc63027cd3cf11d9a41c4a4dd16939f87126832a3111869423072d7ee0be88014a298c484b9b946dabb99bcddd70ae5871372ceeb679d1c3ddbce0e26e5890b81b1633eef6ad2fa8d0b10206575881d4e56aafeac289abfd7781c6d51ebc22c5d59e9198686d280e69eeac4dee7cab0afd9d4eab7ed37d4e37e25cc78e69532491c30d28206ccce52948949ca03f28012205e806243e18cd924c8179016214932cae35aa7a13f2d2c31a376cd51c7a48aab92c0548a684d21618a7cb49f3313539c01c746a74524a3353a909e6b091fbf82d30c7a7543473fb989a9a03cc4135934fa594564aa3a56a4a559f26a6a5026d8e0f265702e7f824492bb91d1be8f637926ed852d472fbe3ecc37844149934711b056bdc7e57f551f534e2b8a7cb3d49717c5142850a07da7889c00723b86082890c865e212f096539020b25652059c18be872d7049f4df54892dcaf58aea63dadaa19336c98ba38087155b8b5062bb882821814918396315eb37671fd2b18d73990c3951d745b9c165d835cd379cff4fd3a6159022900ad016d3a0788912643b8f7bccf4893b073cf033223847b057000c61338248509f3ea9e4d423cd05b01912cfadd4a8864d1e7564836350dca0f6b9c881c928875f50d52fa4e7da460c39a4bb948880b9d13a62e7d3ae50626973e5880cea9522e9535971a71d1a5461788f53b3ff4716911396889c14d710df5a620d0e286901b402dd9ecf1c69e1ad8d07dbe569b230dfe3f64c6ee9abe01c3474b48a004174b3088428d2522800349113994800b281de88210def1e0c61fd23d62d8fef8c3aeddda77ce91061f22c3e2499e91fb244488fcd76930ce06636bdb0fed690ce07539ebed1518a3eb3418715ebafc4a27810cfb3724129f02f185b820334999023b5a9aa150d986997d19fa023b414a1c4a4b4eda58ca1107ac8da33686627000b5016363078c50d4a8f4b986ec7a91ddf8cda081b91fbf500357e39bd6ea0adc16e36fab1a5f8b9aa6691fb518b5c8a30d2fc11b436a785123a88a296ec4d2f0928609f52493f2250a2828987d59c21bc2cecb52be8cc00921296a9d6b8ca1448aa435a40cd14214b335888268418a208d4bad6204d10d3e986056e6b214d89737ca7802f3e20698110d604e007059cacf08c6e874745aadfe5663462da22275a945aac91ba94569d4e413b54823952e439b8b9239adf8f44ad407557b29e79453a55969b554a531ddf8281a7dc6a8624fa86359b5f959b7282b59dceeeeee5d5df226822eb6f44935e915e4d6b3af687f9c2e9d4eae1bc7ccecfcd38cd8cc2ca594cc3c254b96acd38a2a29a58d74fa63604a19e52764fae6a5e39a6766a63fdd5d08f77c8734ecd5bdad3ff5c5fdb642a283ce8bfbeaffd457f769db73ab1f9dd7f6dd0a890ef5b5fd8fce8bfb6e7aef777ea779cccc751bb0eae4b9f53a87993b8799399ecf93ab698635d30c7f422a77bcc1f5ef6238553ee7b41d75975f5864fbaac9d50c284fae505e342140bb1640cda05df9c1403feba619d79e9a66fc5592d5d7b6ac0f2133334b8fd3dddda794b24d20a37583848d33ca5558dddd9d55df69a75093e2ca952b57fc08bf72e5ca952b577c7a187ec4bc72c58830ae685e624b9f54ab9ba604086849500cdab8287f3a67caf9c4e8088b93e8a40619948c1469b07fa9f3fc0522b3182860f286089139c0052493a985be53828fbafcaab62913f344a2d8a37f3ebfd79930e356f14983b1581489224f6c01f7e8af4c6ebf809b5f74c24201809c3ac7fbbf4f9c3801c2499dd53c4adbce88959564377efce2430737f4a1a52e957127164b3c5c59e77556bab28b1ac718a621da8032755cd0060942b8fe4eb3448c83c7ad4f6c4aa5c3445c9beb52d888c1b54cd8586df56c8eff1a6e543b59b006933488d27892e31ed3d4b8aa8d4ac60fece2b0114b83fdf18b474a1ccd4e107fe24f048a4a62109df9c246a0f8f3383bd8f9331cb061bdfff3854857ff52d285998186521a4ad050b2628a92111a4868c460e036004d4f87d70f437ffd208c8d5e0cade4575aebd56b2529a4a4ddde1605b69c9f6d50a6fa6377cb084a5b9e45c95a552a5abf185a373ed3185afe02efe83528a57b4e844af776c597f6b9eb6cf531b0513a37b07e2f59d191a01bfdbc383fd255eadb9f76b72ad539dbb66ddc17d6af5d3f8dfb3602a02e7d6dc5dd946d2a9c9f8a1a592fe5a5ac974a799ef5525eca6547a193dd79fbd6141bfa95d2e4bd7fe1f4f9ded4e6b7ad425e5a795e397643bf1cbb3310b9f463b1fb156c8197dfbd56aee991eb5f18af7f335ce5f216fdad723af99fa6c1204bd69b73cee9abbf4b68642d66b9fc520da74fa96bab70bafbfc62885992dafb0536ac5fb5357ed673b7b536f5e9ed5222d15c2607ebd1f37468ab147dff3cac9b6b6fa5e68a2fe7ded2d59fc2f277dd92dd237f514a39b5e8f5e94a01020813264c9857653056279d82ba1b6143ffd9b1da6aab9455def99e7cdbd57e3e85c6eff1f3f8dae73598f2d4aa8649e3eeee85ccf5d82da1245a2fe5d9cee170031caccc0dbdcbae1682c1602078c92266318f018664dc83af018662cce2cb2c1327a36143ef77fcf4e932966e456b8a4bad32333fb3d7402f3f73cfb8c0c6d7bea7dd5d05276cfcda20bba459dedb5b717d296c3ff777018e78385385d42fe1467777ef58ce6dab5cd35a84fc92a3ad3dfc30c8d0baa190185a579a707de4f32a2ce132ce4521b2873a3550938ffcd85fce08d1de84db5736a77075723c14aeaf42f9ee52075b1b64e91d6bfd8c6ce0a57dce92b905d2aab90ca0cca844ad5835b974884600000093150000200c0c87844281401228baa6b80714000f738e40725e3618c9b22c465114638c3180104280010000038010111179f032272ad7d30dc4a85d28d82d75835d2672700dc863e4e5045ed2acfc291e60828033a66085312e87818d658456579b419159ebddb5f8d3f52029b4d1d9e302ecd475df130615d8d35de77c0d1afe01cd03db353abed7473a75833734be5ebfc233701b075b453a2f56c3f89fb722a17b31027bba99b61887b457f2fea995d66b897d4efe5de5ae7ee10da8d5e936da254add019a468042c8342846f51cb6c037598735c83f7720e84bf5112fdc832d537a671b20d868c0ba59906e1b8d3eafe84bc35ed968dee7fdb83002b81aac6f82355c634951152a08d1ae648fb63cc873fbfbaf66a0050a3ff6fcee639129fba0763008fe2be7b7f2e5ebc55982324120b9a4170832173f7663c923850e1b35c16c9dff452bc9a29c9818b8bb542b80b4dd1df7448c8beece0ba7221a28d756e8f41f202ea88fd741315e00c9315a47a58aa6772ae6e0ce031bd56f47019c846fe80bb026f1076eb6a34de36095e1571d0f5787d3c5f1f3ec3e01ccc0df5baf736d57cb10911a9436263122fa727c238e78461cd4fc488d8da800d1e976952dad24aeeaf052a4dbd2500342b8c1ca46cba3846b51eece9186eb3e92d7989d7ef23159a939d5faa8b9bd23b3946272f21512c32f1c087c31ce2037a2dcfbbb6bfc1ab0655e39717e5e4a8f21df092f87cb31e56dad65d4e7414d8d0967c0505ea71d281c00edfaafcda419a5faa6ed771b59076519820aa1dde1870f56083632c8e9dfe45352208c1f44ac6cd50aba9dd97ae974aea05d4a7dd74b27f29f8464d4cfb133387c8162c25c6c5f83379b95c2151d8d3d9d765b745bac732c0653579ef8fd8b9a0249a48719aac05d078da10b666977509749abe116bf803c94bd42027986a365d12b504c8402ec5d83e65075fa56ae6ba864e8504ad211a853d9c2223b279e076f43d0dbbe659b5bb51b0ea1418a3da6bee51082636a4559cabf344671089542286bb4461cb3a14a242be095b671ee2d98e1196a78688892f8dc4feae133d6cf674e579e50e75ccda623c8c1ed9167a24b7c61ab2f23a78d3ed7568c7ed4ee7caecd09917577022aa247bb52446effd8a1bf6f28834c8f38d61fbde047c24285e69586f1f1c1393d55c2342088639f2ca801caf1493bf4a9afba689e173005f41b81cd169cb6134380737cb283fa4decc733d95848762cbbf3eadd449df4d474eb60a332bed263757b3eea90e6a48326e5450fd0fe2c70a030f69160ee25699d1186579eaf9d53749caf5f13a0e5f0f22854bbd7027e7fa03bdb2888270a9a0a877ea0c3fdbf4f4f2db69f5834297abe556112d7b54018dca65a3a424738a41e8cf76bdda15a07a70359c5f5fa97d5a22aba1e5cd34ca57c9d9a3cabb2186f79cc0ba180bd0a4eb9ca7defa986bf496ed12c43be6652e219518e5a90d8ff2f7ca12d142e1d8aa4f0c5225ae1b6810d234b249ebafe41cd97dda15e3da12c34b4b0eac886203d64bc5cd50864ae05842eb1dac13124976af5596967c6d9758ede4a1699dabfd43bdc879f1e06b98c3139875563a3b8ce7ae68b5e4ed17e95436befdbd1098384469beab6058cd480cba1a14a97d6854d4ec33df31ef4cf40371edae5b9570884b8222c3af30c04cdc26eb65dc1494aba425ba3d7c4dd049af2d830903b854d01d704773385e35a28bafb0c3f32d413d0b2d6bbeab5c949ac55449ff19b2ac32ee171497c5599b7e38de96688f777bb20f24738e58878e3f579a3efd560f446bf9ef1d9e5a12177a0248a76a23cf42acf515b84951f3a049740a95075bd6ab56b6a3444478759a25f9b5ecdee550162b16250f0de61eb27c79f999b7885d24c3290b4016dc768c78e0b6b0f38b495972778c3204a2553c6d92df70d9b2154011c42193744f8a79c050faef362929afecd58e85e7c758fa617e3a3d4be997bb7756ca9984bbe3d2bc46623316bc5e23993e9da5adfd1ed77c7cdf7611e3d06156dd2dc09f6d85b3ed02e1caefb7c44561ffd7e80cef8668c2b94dc79d0395057737fd49142e36bb17f68e838323db67f21baaeebe6445444b86ae22d1dd729edde0be5aaa51cc02a1d0d476c5acd3a66d9e3f59e47b6ab96d1a88757a9745a736f8bbca8939b30c79e2ffc0ca1d3b59edf24fff430d627f56651ce8b396940dc98dc046fcab92411d0dcc77ac4f9be4f8b3da19de3304ddebb408497de0e784ad20d19c44c657ce904d9d376237ca0dff81b051be51a4fb8b3d7c204ddcf91889cc9a9d801396153795511d85f5a9be6015c140bdfd2a939abe0518ad0a3177637b26e1e4ec7741d4b7d2ecb2261a86d181e92c1847a43826d04d0f1cf2d670dcde87368e5507e03ce8ccdfeac95dd8d677403545666b510c2940ce0234f2d0626acec3130395f428983fa4b7a1be401aa608169759fa00dc8219637374a0d28466c7bd48a1422ed6351a8727aab4722d388b2243224e991c5421598328cca283cb86585e6e40dedfed6f975332e53c734c197b7726c0a47b572d59c6f7e158cda95d9bd4642ecba945f9b9a59ad0d0a49c3cf3f8ee22edb08a2823bdfc68ef26860f550703d7b38f035baea020b60f9c8651cd6cf8cd8697b91e5f0a501f77ce474df30581efaf270c37280d02d71e5ceeb209c4344301eb2eedd21aaff6774349f045395c6fce8a6dfab18800e943c4374a082e741b99bb3e731b5bef0e524b0e01430837449e05f4d7a5943719ba3a7676894513ed80267df9094bc29f82308bde8b821e6c8aa70020b569878cbec93f0d0e570e1a0d25c7291a2549b71ab6ca5305e5ac3c364a95afcc68515d3e91297b827c0d0d89255780c2611f9ed46a08e1b4b7638f716cdea3653988655d6a05e8640680d830c66f3606a497526c930621534847a43fe7fb716a68f07bbef372eb3581490fb309ca65275233201fb70449f03f571076bd9b5224c21150c608607b82b59a02bb590b54c4d8154b09338019c0a81720cfc58d3005d8ea9b893f777bd92177710f0f2e9cf21a00ec91a81589d2a1d6bbb0a2f120823f2a924517dc13aa9b0d3165890fa6af66f5d6abb5b24bf5e6458ef8d01ef09577536c0962560df46123b958f40d3ea1f5d68d7a02866aeeb279dfe203e47e4da4213c459ca7347db57c94be4f005a6e8dd64b3b66d0d10796924a4c2102ed4dc7e42ea76cd33a2f79380aaa1247877c92e1aceddcbb63b3e9d4757975ab762578af15ee68d806b0c6d64c3b60725aac531b1f84b50bcab73886b1cece7181d346ef000ce460b570c6c9e6a961d2508a2a117c75bb99eb1f70c3091717a300bbba29477e85d16c663800e73f4bbaf52b463260837362999545c5cead13fd1403ac6b3400f89aac457b454f0a49d68fa8f14585ba537fb8dec0c96e9898f6e0ce6333f4db19c9a023d9fe3f3e293804f4e72c930264482431bc57c572e331fc5342d408d6037fb4090864bd1506f5380d2010db4757e11e976cb7719f35fbd67b8698778636fd1890b7615ca4350d5f7b01d0e3070401ae24ad344b2de1a22f28ba0ec2f33358aded15c520a1f96b72c3584a30c314349f7428c75212518c4cba38d84d3b647dcf7e2d8ff5f36fe7379acb82cdef90c4e5b721bbb05e68b38889373f3f0bc1364607a3499ec2ad598fae506d55486281113dc41c02454d4e104a05200629090c7861b1a5ab84c20aec7161b6279a211ea8922913c586fb57793938bdce50d19627caf3548d3b692c3449961c1fb6ecac37582b2409e2093217d87f2d090263cd07eb3fa71262b1f4281fd50c692a90ba7fa5d222437436f40a38e35cd42e299235c2f74496aae8875169f8845fe5db02657b897209a06d4feb63a441f75e436781236c375b51addbb351f92424cb881b24712353a389f03dde13a285bae7794a4cdf518a258d86356c6ec8fabc16888e49efacf732af7c9f42e8d3d34cfc5cfef452f8d2691f536808e271613b3a46dd994fbda396541064c5607aafcfa7bbfbfb0f60518e425d9a9d43e59e5ddd859b92f7af5be14dae11b37be72c74a47da6864d01bf695dc90756bcaa22dfa552fb38f5b061152079a171ca73222381cbb68dc25d84f1f4922ce9255e07b2782289441e4d438e942c5ade5cbec105b2ec81d0629ea0c39e62f6bfce92e551ec4ceae54fa5d98af7fd74f9df207fefa7fe0ebdfefee9fdbf7c72bb8fde851eb0facff5af98cb9cb3a566bdfef5c253a3c7a00993567adcf97fabaeb63e98b3401e1c998ea5abd9218e6a6a8b5de3e820ce518a6a2a975b37e055b6676d48e5013a068a895c259e5db44c9ef6d0bc563113ee9598cc6978cdd9340ea65b3532acd080bd41baa054a58fa90aee237d87dd16c9a1a2a2ef5ec56c7774d0e60608a7d3db9f20e643563ef54bcbc69cd33e9b5be16cf77d57cd452ad911ae267f4ac495cced7a683e84bcf20db60a3a99d8181c101ba57f0f847894e947efa39e91ca726ea8f1c2c1708d906bc4970a0e54d2a082aa3056216d4db98c790c14066643dfb4dcfc3d45e8f364120a94052f393b71e58753e452941f4eea6cedcea987921c5dab15ef15e3091d34d862153c8940acc047de4a48ef44b1a13524cc540f2e269e2a942e805440909c0a86b25946d37545f30a666f81ea6c9844c3ec1af5fde1bb9fc4a567a46dcc181e68a5fd7a5dc3944f82268a234b4a684826765c9cdeda65b1cf244f159d7c572de06e3588448c924a419521e0594deccf038310755ccb44a141fcb817d98810fbd8b48a04d7518d558cd2cbb5fb0f9ff6e3846592aa6fe5e1fd86f7727d96890bca35c7c7b4d35ea34a2e0cff3879f16939fc98147690c13a9521473b1c56b048bd5e25f46cb4c06f491c9ae0dfcefc6728a8b025057422d99c81fca20b2222556eef8dfe822fe5cc78f31aea6480e2f6c3121344227ebf4abe45b1a7509a5f0a3a0339e69db2eb5eb4a068b7a26f7540cd8d3cb9a3730956bbabf8e6cbe1ad55954bb73668876819f0d2806d6bd96384dbf9181c2933bf7cebd357846cecd38c2e3d03fe4d25f44167b9d475f7dad4de280a8f6c60cccbd4ff2d3b1c4f4897eb259313f768b33e12af5f2c6a8fa4ccdeb1f84667395fa6ecaf416bfe7044fe2d932f0d9c4c6087725007291ec0b267f9a4b85069501430af0a8ff50d82ee10c3c7fc3c2d7adaefeef7e9c3b43dfc071eff1728883f98b6d4ab75804b8417a703ec88e3dc56ce70a4a3a353d6fdb8560dca2a292f16f023e69f538b029ab49fb2dd68f0e9d28895ab82e0ac6273f31e819153fe000b30a7efb8173bd73ee0e5baedf7687c9f2620c8b8b1490d724ebced8f685caba49b5a34dd2707f4c225ec2af08bc1b3399db88a9cb7cea04568f4b053aee91274ab3094833b8a1d2cc65653878c3d761c19e18528e3b4f3d2c8c01444d46ef2cdb138220b14433017648db49be4c2f1ec6b98238d2f18c2f9397178952a66f5c05a8263113a17a685576158615945b17f5bf54e80912a7a5ec5777764e4326e43b1123dab5b8dd6c4309e7725461b326a8459870f06cdf0bbf3bea237702c9c53fbc8eae0fd96cb8eba4845d13a85b73340f7c815c94511cd69c872ac48860dfd93d996be66a6b0df14ad8cc17c6011aa0880275f70acc3e0ed12d0d2abefe0a171bad3a33180a3a5585686fa7dd7ce8db7cce8a8b2e3065b1094cb6892302a54e59e5270dae48419e3962a34290f6b8924e80a41c12dd3d8e249b25bfb74697103e41bba374974a96165a6f6c18441acee4fe56bb22e6c603736b0fab4788c644dbe6b127c74ee50fbd09bc344f81f6551a7b15e08e0220c9f61303e9520ded87cbd4cb0c6e1b2097cade96d8d8ab20eea93728b004f3944f58ee4260164a707db9da1386db4579bb22291a5c53910efd1ec930c528702308e9e262c2c0c42eb4664aa80f99ef100163bd0e908f6a1710a2061a077b258f2922c1d6678ae302bf37c315ac407650332d1fd63d4463986cc784244db6807bffc6f0d5eccc294b92cde15a75831415c4892273235b19b4850ec07d23f62df4f2dd664fa453e58afb6ec06028f06b769494e31d9e83970e02c2f809441d1988c807c628e0df00e3d260ac36c392c176494d462a97015312caf7f78f75cf7f30971b397ba18a7fde05351c52b099b1cacc0c8161b74196799d6c05c85827fab33740807d5dcdb388f018ff6933f3ea49f9be7c02f5164ee6ec5b8e435e3a64065b84f69167d7288b89fb21dcaec36caf8eef2d56b6f6fd503368c7159705f013f6e9645686a79d21c32eeabf78e007fdc429882367a75b2a9dda14b93dbf16310dd080b69c59e638e8900f6aa2c9a36a50ca2a04e20bd2b243c9b7aa85aa2c160fa68394926ac9aaea90fd3d5a2bdad5443a910fdd229463ea1a35a2d8899a12a0462a124b49f6cfa027d174a8ca2b4a0dc8861ea3d732c9282c4765eec4337c07f5217aa907ad725826c12353e988e6224317965694e8632fc69f59d274c6d630554eb2b5d8b71b07786e06ded8e4ba2774de8bdca682ee43908d67d8920d55c7e9b8159e704161b4e203acd6ec8f4b44b7fb01504bf4a46dcfdae6e576a642682ed6e87ed23b74f3f15ec59ea4b351e2700653e3ac1fb352eb4b0309cb231d26f1a8681ea3aad6521343a63f07a3cabc92168ed379a9bbb5a225e28932cc198a5af57c8f0defe873554792da8bcfd91f38c7e7bb73330b6d624032a991bdf09b9ec58f6f33171f0b94561d598848f866eda6601dc32676dbda21dd3e43feda81a6b6c894879cdf7d82fffbb7253facc6d2ae8999619e5151490ba18d4a41143b6a0ffe666a5236f97c420d855d90515622d373b40b82ded2061ff474c8b7bed10a94597807a080cd28967e70b96987908b18fa4675c8f10ddada9e77312a5d4121e0c9405abb9a3614bfeaad78060efe239f7625107af8d76b44ab0b37aad8cdc951baa6ef74bb0c83c0db8390c9df3413928ddd3adfc82904c67ebf09349194234ac101a52b5b90f553487ca121df46b891416ac58422e74861a4c4d27c98b960b8b83e002a22cd3b3f824fad94d21acbd8798d8d37007d58496a1669c3cd5f1e7c63e07a105b0ae994be103a6039c5bd13eb19cc88424b909d487660305851ca521381c00aff82fbc01fb3fc144b4d79e345137c294ae6d4eb30cb94400320644c2ba7726ea1755802e3a2d4863088404231345c8f90f88db783a790aee6c8feb3e709546acaaed7e10c7a1070fea01f7426351cd0268a0973dde676caf5a387c9237b67f128e4562ae62557cd8570224b865ec7394960711e6c5fa7a2d77c05417f1cfc8796ecba50757d6402e8ae0b4efbacf628732e8eee4835e1d9e5a6349add57f0ff48f7232614ba90e2d048f6de5cc070ce26e9b7710be330937184febe4393946a4f8999c00e7a0c795bce05a82e6441646bd42e07befff405c638844e1040688f1460553eca3b698fcc522fb49b506e20b38a27b9d8a60d98c3af36032c599eac60d3f315c74a726ea72d0ad6df0b3a2be1237e73152f60a6acdd7040ceda50572648533229ce61afa2c0b3b7d68888574232579442aa6acdc5ab95b88f4a097a2d43dfbafe9b7dc2136e887dbdc7f241feb62c45450f258be8d20c07805964f198e01310e0b8f7e860e5cb07a51f771ce425b4311069ac24b663cb92ea24e3fa56539a747088c038a739cfff153ae5664d076b438e58c56d94e3779581a256f7f87b9c3af39dec3ed4a78edd656b53a28957b6af638de1f10e5dfec3856dae1b50666aebded13c9d5e0fc0ae6bc839db710d07e6a9de1a85b59687d1bf7dd82be2fc802c876266e6c35d72b224dcaceb2c859aded7decd36d9b189bbc710ebb1ac73a1d0eaba9057c77194dbec3cf0e6fb3e050f71d5d0145434a6d33e65a782c24125e4bc8fe5ec6f37d5868c89a75ae1aca4cd3fd475e030c4239f80743cd777f382820f2770d3c0d43bc3e933db1017c254975f48f10255a10490c3bdd9cfabdf5f145a27ffc4cb31bab0406be9a02b5af563d3fa0a1892a907f7e45466509aea0dff737188e2bd75ca2f6d92dc39b0ffb15e0589d744acd07cad051d394c413e002bd4bcd43d1912f0765a0829c06929d8463682b8c285ede5e0f6a30f754f4ee107ef54f05a630863bbb26387bf97883a03990ce4c449e7c0cde20934aabf18284ba264af1dcaa003067e0de5425dc377f513afb6e8f32c0b62af406995805cc0b0dec2eb82ec694ae97fcb7d42f6cb85458adf05672322e01fc376f25e9a1cd4498c60880ea688e7043b1f102b4884cdbf9713454523ed4e33160382f700f600f1a434a0f88672b98b31f692c34401797444b1108a616c6e0bacb596f5d9533f356d21113a71abb09017e81ee5f52b5d812149759722fee59b332b12009b19d095088c8d9c3ffc0b626ca8f75b530aa8df833c0f765193d2fd7fd652788e9d8fe48005d42a4897184ad82621ca1d7786652fe4e47230180c00931f450b2419f91489e1edf2fd8e4661ce77e3d8bc014a49a499aa03ced54788290a6fa81da751510474367efead016b7f3317013a602818ea1b412e28d9545bf50b62a72a245e72dc1c0572382ce91b05353a03eb077e222a688123561854a32a15aadc34378d9662840141e6e4dc5c1a23e08470f50ab34dcd72ea082349aaabb34882f98c318842b8fc1afa5fbd102fca246dc2130ac42c7e49b8d76c91854db60a60bc720bbbf7672d4d05f7df924193f90862014c1bd3bd2b178e65cdcbb1ea2ebd97854dc3426c3ecf7439fa6c5d8ec617a6cf83033ae5c27ea79e7a30a472590dc1ece4151176e62a08287953215818c66dd684cd765ba5f66962168d1c1c49c8bf4e7f56ee844896e41fbe96b7aab30629d9a2b61a92123ff9dc6c8db89a327562e80b8b23e25d803ffa4e6fd4167d2fae5571f2b165dd5c73d3ca19833b7a1ae13ffd274d9fc3c9a682865e60baed6a917fa7f0d32e6613b29bb053a327d7998df2023734b106b1dd025a0335f02df803a7c0023144a16fc88f8f22cbb3162cd93b11eb686d822615930ad0daaf793041ac4111e59f1693d17c17d736bd704ebf6f25794506f9b05296381673f7e34f3f652c6182f60ce56f0a7cc079a2606553308124fa79a82595db0c9fc4407b76bbc34eebabd3d69dd06b7293cdabf2840d8f3ffde1682e82e3a30384dea7a3d37759efb2d7fb42ba0b773d3f20791f17d20c3a24afdf71188fde21655c3a5fa7b5b259ecf97046e994fbeeda42cd749b3a69b08dfe3060f0438dbee75858b4ae923d9f33613bbf520ec296de2ca1489f7ce7c29ed27c7dff4b276de9bfe08621333789532abb3f4f9af0cd48cdf9aa630bc1a27484066e2a8ae65c9ad6ea914b0b495e891ca71f46cf124b3854d35d62494001e64f5501184f055c15d8abf3127bac8b50e0f65de0d24a843fd3bde29485c4f79aff150f5a5a3b607d07b0b50b44670d97d8ad83970a431059b2de0c4c934a990f4d104fa5102531841c1395840de0f7e1bcedc390b8639f03fcf0aad08cca11a151fe32674c3b77f7be7203a1ee41787bb1494436aaa594639c6bbf615c5d0775b96016478a001a43fda77a15d2de1e3c9bd83c7f498c8e4831fa515787b65957dc3a01141c6b1c809818ad434cecf4af131abed4a5f871776a88ed438919d8dc930671d86f3df2dfe25a1f079c21abf5e7672dbddfaf1c48a8718086f76a7f6a98842c67af040a246f7f6512c56e1a01bd51d5caadd57f0f64f733c067db93f9cd1fb01ca0018be8b0aa3e1e3461dcfdb6d501c884ca072ec92c4009c54a6c7bb8f5a6903b2c2c8e4c00f2b60f24936e8dfdd07a7a54e50f0213f1becbeb0213f58823478655e6c1a57e17b78a79f4235b792ca3bc71cd536e74c016daaab77824d007cd49c72c006e5c22e4c50e71212bf4d7b6697e17b910bfd07d56b303e20e3ec40da0b53edb86c320955de50ac5391c7793b427848509e1508b8fbd33ce99a7cb4e11fe8f5070d639bfe629905ab3723c4133c18c326eb1c65324b2964cacd14f4a1d84eb08ea6d656e1b193959444ffdce476a7e3a71a79c8bf2022b6b3bf002ffc27347ff88a17efd23956f4bdb838e88140ee586edabee00297262bbf911c7920dbbee54065401452f8e745d5114913bccbed581315a245fd6b5b7c66b5870e59f282e244eb24fccb86746f085eeedd99b9f5f7be24debe356861d01efaa08915c3f5f01366cb1c0c91780c205d420568f9ed8e942bc033fe700a749b19992a9b49e05b87d2e3a233e7a917c04dab80c9a9de61af5da1abff79e102006681ad84b756160e0d6ac74a8e0d6b90aaf217786e735e7c4dce489935fe52d040517693365a208d2e8597eac5d7de098f8ba2a5737b99af68de326e3294a166e036f32390c388e7c93814bd35b11b0d022a4f449a6337a43cf87e5e120799ee4c31ecd4db79d025ac1db5eaef98b7bf4a4a20a6054a7da6dae3826f3d95aba9695e6dced7324974d7430680a3b90858828f8390ba35dc7c5970795986f4384b874d2f709b64a2ae4b47c6b9877d8bb51496c6490482a047836486ebcc2665acdd8b528544c0143de820d37bce4a06297bb8aeb41e9552c8bc5a614e06b24b73001ba3d5517e7d70533bb30b65d12800c1fe47dafdfb574d401436ec526ed1852ddcb7362999bad6e9c12d977de59f3d6c8887421558fe0865bea48dd15fae0eeb8bf9465c1aecd303dd765397f24cba1a789c803a8b8fd6a9e9d77d5b1f595b17add98407a59059049bcfa4885c08e5a7db0cce1508633712312c53a4520d40c4a32c9b9f30820e68c51d8ca1611211581d31ad51eda575476574f0a58184e0a5878c9f41b93544d4e68c5f645cd88b870472536c56c42045c8cbaf9011dd7cf0b01cc7a8b2d8a043f280302eb080424107c8ffbd6889bc8d48d9b4d74efcf55202961c0c82448c45cfc4f4343c652113b32f9e22af34c0b11a486d79c3acf14f8b7b3f6b990fd597cc1e8fd8cfe4dd326900f254cfcb8b2aaa78a6213eee423a5cbf9eeaeb1222fea5fb8b19139cbd954acd760df1f0bb422ece067e748b7a2468df210dad58eb5e9fb28ea68bfc0885cea4cdad90b0f85eabfa9b5f6eecd53f7ee719a98c68b8e441f57e5ebe186ad240e34849a9299e2277dfff4005655e7070efe634d6448d3af0a7b7d1a092b38b6314204b9821be6a6ddc7003b113e1e6d81fff3e8e6e11b5289c50d30273a6fbd539c17cff05606c8a811f3667548f94eedebe125231ed65cd2cc14f7bdc07b09861dac00a2bef2ab8cf60e885e2df4cf4b854e78073015785db6f7eb2e2d7d0267a071f162131171c1c667805fda930a38f71eb05e345983d9a9818e2feae463bb9dc00e77f55157121c6a192ae76253da3d71a8f0e67dd093b3f2eae3f67bf37df74dcb9230d689205bbc83e0889d90f0949c95183a6bfb1328a0d07552accafa0ed924e9b8ca84d80c8af9736b43c0d252a6dda28c080e311d0a596d103ad1b7bd8f8695ac58a33746cb985a0c2903d1b534b50476b5477db01ea181b39d6100377fe3c51994e37196886069ccc5955da02840495d9d2b7c4939c343d96f406830fb683cf7af55f7d3a2c52ef5cadfffaa23959bc5c7c2f506a48dadf34dbfbf904e5f8b92de9f2393be179be9038dd67257750fd40d1951efbb7bef0b381af8f958d80bb470dca62c7b2fc24f2906a0a89b20296d1184ee6ce16df2ec00a6a6885e0666125e59af4f1b8449acc619ca063a4a8d830984a2c50901c7cbc4458d08f253be4955970d239792bb99cfcc1f15760f7986e492023629d9dd60967425485fa7e22d0ef13405c1f1f21a0cb000c265226d4f71da941c88a475f60c86b0595c93e953190d8b242037051cfd631c65df9140a26ad124ee13495759cfe0d604827d24f4aec6fbf91f84ec78480d0499ea7d306cb38bfec16bc3568e56f82726cadb580cc9f370df4756300533ab8ca09fae75a33da5cd80b80b8ea65da8da118e3c9d1c647c734087556e18a0b79bd149a5623c6acd8e587f03e89e68d4c2d4b31a2fc185f002266fdbecbd448fdf9441f080521f13744a5758c419daa6e195710d8857d367743b644e9b12329d6a13e0048c7f02f9e490639bdbd40f47240a33e32ea696152fc9234be5dea4a6a5c74f54226fda3b6e7bb6213f118f082174979383879dda26129150bc00aa49ad52e1456b95bc60e3272a6990e450b545ceb0af28ae23f2482b32a438972a695a2ab49261914e6ea60395509ccb45c39d1d075c869a44142887a9956ed9d1aca2532104fc4d392161de9b4c3e75290129fc8dd02684665900c5904189d2a5ff2fa0b9c3716d858c816b238db5029b053e25e67881456a0d8390e64c5441757104de51f59a66cf2e2e15277248047e2a75663db15631761f71654fd671f304fab1fb1199145c51af93c16752a5665e8049f16f6f4d9a6a2b8126a7ac0ab2be408c9192402b27ea844ff803c2c408b23d1f8f163256d18aa4a62b419a66945a95a714976b02caa6917653207f969dd1d271758ab677e1c5890eeae8454c24c675517b9a9b6bc2a7d933b50ebcfa01665f6285d4da270bb7b36b40d29e6a8e6bcef093e7049658472163278cf7cf1354901b183c0fdf613199302ed4eaae7bda63d2cf51ed7b0e86fdf1f2ada5db782465cb16d855439a8ad1cc3acbbdddaf942ed300efa256b4efd37ddc1ab7f476bac7af738bf4968e3b9e1a1068618dd477d6c54fb45c25bad10a9f496d402ade372cdca1cf4132012ac592b67b48ee035ccc3bd51193edc7c18f97e75d4b2d4993c8ac85dcdbd4b545314bca14a53c4740a4450f74083019670e17d0fa7e5c4c70da5f8fd3cca52f242df94f0f0842441d2a42ad8fd9811b8c421868526d11fe4590610894f662295020cd9bd3400009b00588cb73477a30558d5d4ac41b1470bf32196c4bedf7cc8603109bd4e03de11358e943afc1d36263b371e037691927ee33642a13550b208cc1398e542c9380aafb950adbec5b3196176523ebf30789904b77772699f52d831c73128f64e1953a572c989bc5b261321b7bfcac5c98371727d05943ff6f29f9b12beaa5d8dcad4c8f11df119e1379a6c728a2df5c1491e48bb7382739b35b8e5458e8912aa7c2a6dcb978436ad008bbbffea29392d3f099761e6a8c2b1092fee3f502f370ee773f6771f4782a5bc106554414789e13b6704f180d88dd125dbf1e12caca4b3875fdbad9508a02c8be1fc1677340e1d2fa9fd71f473e7877dbcd0c3a3ca68b63a3e82abb490914be995813fff312583ca3d77cc367dd9c366c0fd0367094b5723312cb9f7117aad0c4da2c59b0562b510b6ede618268168bfbc661f07052601a2c5b8bc3df1d35e48387aa1d6e50c25ac2890d02325510fb20c5dec9db9f604ba0bf7edefde5dc43cb42368f01cabf03824a50db1038da9bda736a198ad05b87ce4687b1545c3cb49e2091c801b97f8a17091ff99021d79529c4257dcab971c0389103cb28d217a1f27b3989c278bb1f465a09e58c12a112e251a884ed6fb1b2535cf4bb6edc19e20f7facef3952ca98a2eeb2032622589c0cf5a4d993146d5db0ce623dc069956752b2babb13b8b419b82832e5313f9bf840351362a3173684dfc0b43804f8194c79bf08e62d65b967a62d2325ef54f68353c367afb7b9a7e52b0bf8a747d1362e5af2430454076de4c2f8e5800ae58081fd9cab671e06287e3a5072af37cf9ff2103f396b694c5ca5594d18d3feb04d98e64059657310548fd3e801b6344c0b43940e9ad7c89b837ccf5b00e71158234d1a287566d3cc1112b88cee1058ae3fea5053cf0a5a1b9de5ba3c5a5c06e2373ab1b310cec42108f87e6bb4c3f036a6d17cd0ffe79d8614ef4bd1e043bffeb07bd1b4652923baeb570cbbd7d38db72bc356f5f294e901a0097c69f235ce183c3975a40ddd298311bcec525fa081dacb9a1ee673beed35a36a2d97f77d79d98f6320a0d36779be6d63a3a20553c706343c77c88b6ecd7ba88c0b5ba6efecfe4b2701b2e683211681897d9cca0c46099f23f83c5db9dc00d55665506c7a4582a1227a024fee3128b799b92c061ee8b45d4fe2e3106e87b84fe44d50c501226c4c23179d10036ce9d0b497420267fe958bed02002abfc772306d4fa6616504090b69e1c9487f37d21f28ccc3d155bdb19f840faf2df461958f88263dc397499bb93b6520239326509366f0e7041c89384a93f43d16ba6b77222551793d165d3c7f677f2de87c6d2c9aa61d53ddc614b95e3eff2270ca443d2ea7b9c8651537e3f39306e75db798f88bd4efa7475eee2e4fa3bd89d6acdf0e15f40475910c754159590ce17748c80c9ada44c3683bee49195b7fdddbb9e3b6ba6312bc63766c67b943a69daf74f04e9207bce6ecb50e949fdd0eda6944fd1a6380542b99b3bc129c8f09cb9609906cedbb2b98aa6509027854f449c7dc06a805151f3525e1eef2e9065a11049da4d3e07a8a18e73ec95d1e9525d4f52e14d78ac49da7894afc2aebcad31196a1c490d1018a8f9270f7b23778fb9b2c184032a5e3839806ae55ce813ce389a000e8a1efb4edaf83f7f7c9fd1604ab10cde704ba15df01252b814dc0a6e703bca9cd1cef00a9094eb0494644e429def54dcc5f6db2599bc1010ad6902d6cf64b93c649e60085fa1dc885ececdb4065f64145419ca5f6382750a178e88bed9424bd89cc3091ded4e82921afe99b4457d14accfaf105b88d6356a87d755d6034b6f5e7e0329fe48e55ddb294e91d9bbcceaf3af25bcbb04c2473b309572531d0359588a2364d0ebdb8e39fa9538b86655694bd75d9bd43b2673747de8a00b15e399452f999543d659bb39f49e4072d170f7900311a0a50e12a046d2059790f0bd4d4ebfef8c8b981cb0ff066c5aa5e9d3be892edce5ee82252eb9205a695637dabf88497865436e85e3425da633eef51de7223f3c5bf3c6869903395d0b54b2c4babb27b85747f7f8e7cad1016f615c27d8057cb515a9dd032af0a678d4525d1950486664d638b156e9cb88c4047ccb3db1252709323c1e5f37ff5fc52b3472cd4dc2e9ba228df69e6342b4ade8e39e8eaaf144d22363ea2ebe71d67dd9b145166539c1f505e9aa3375bba53b03da89260599562e5bc4112aa48c46343a46a84e93df7fe89d85c9995ea79d9a0383aa318f460692c7552ee4c5f4a812f14c5b1ce81ab7d4c19471aa3a358575bc1a86abe34a4acfb959492693f1577d71367c1d8cfc43a8f255986921586867236d66979b536cf7b72728563c42919a1ea498b840958b5a90e53f79828b1c1cb1c3db296ed576e86d814e2712a45a60c7e876e496e01c1201006ea12da8dd474b843de058b957c35c902eb1eb5ca4e33a5f2a6f4cb0301529f0bdfdd65b0180b1f203d95734fc3862f2829f9f9c2ac34d6c855d8330b28c172b3850a468324fa060989078e9147c2da6f93a625f4c76775408c5dda38ef95f0c34baa61299c04c10e3fe45c0bbb3f254d97a5683ad69f0ef290ec53081ce327d8267619d811444556f8894559bdb50b33ea91754fdfed0c219cc1d5e9491fd6f878583d057cf3305ffab80f88749625d525585265b514ef8b4c6924269651c8119dcddcc726458a0cc1c7b6b29e44562f92e37de41e1d8fa4e293665c676a406bd8c2af0ec50fef9ae155d33ada8d73ac3049a2ca2b0cdf493f84e2bb1ab351a0f3e6e1c69bf6ec6fc638c40c9caf13101d36dc1b885695ab34fee814a5568be35d66833e3a3d5d0e01086bcd0d08764c796e508d89493712323784cfe49e95ab4b32ba48c5ddd025cbf239054590876b20658411cd7a66cb087c1df9ff10f5f27ee173eb465a9e541d9d5559cdf67e754ab333f2b48d3298b9f73a616bce206ec6763b495b75eee405c1867ee1a6188a0cc0f3181ec93a47396ea2e71a31156c644442434d7a87fff5fa39e61971c7da9ceae7eb21f9c892009aee80284168e8ea49979397990e0bcfe4af3028b94b745db9898d558e464fb2ec3cfe149c73e8036415572e397ff75ea921225d5ae0dd8d6ef92990c729dd4d2b97e39a25e4c61350276fa7cf3752e80cb222b8c75df657b68e747978ea5e159b44410af2754741a5e82d2c22b0ac764bbcce9676346e7c55f30b523b98738023ee417fa107bc51ba17219582188c8edb09f59d7d358732ad2bb64e884ddcff202dd07290781d249c07ed3a0eaa94c0a3a9b34f51cb7f8efee319042232e18a2e44faf1e245f117c17ffc4f1f7fa8e91d236d043b9c20d97a76ecf6c850fdd84d740e4103acca2beca867bb61a7422505e775b006aacabf980c36b2ddd71b0d8d0ab676449028bf47ad366028e51260bc05f860b59106bd0b82a8fec89247b8deefba1486c07b92ce12ef14431adcf0d508cba64bef7471d2f727ab6cefd7bea6973c4c98fbed91ce0706b67cb38bd21ca25238f9d7447feb1ad3b78a797a4137925462bf68504f47046c44ca89027a4e8537144f7a4998e51a1e941d1b9a799c984af62f366fa9e73abfa53ead797a7e9921cc1adcbed60207acbce61a341704caaf381ac6ae86d20e2819e3068457c377d84c2e6c81c184cdb49214b630589a42d8c2172cec4c9554a18583a569842d2803a060e1ee37ad90852d48d8b9e9b690852818d8994a60852910d8986c300a2a38b09852202bf0e1560465cc32b9600b5290b0997e640aab70b0c4a485190ab16af1cbad70ba6a66d00e8d57931d4c6a7cdd1b16ecc25bfbc866a5ad4482722de6d2097c6b89844abbf361cb2f2192c78b16ddab54da315cd9dc30222f008aef34b025306dd68662e15f9a11b7b7607f7d5a09ee6de2c4a25ed53f2240e44d835caba5c2861b51a6b77f99677f0ae104796d651d663299d161416cd6015156ea282292814b9f0528aeb8dd5657e67867e2c9675ebb885a6e82dcd0f86730646a541d89167bef47647e004abd095eb41c002b86c7547fde97d094ad707db7d5762340cb4ba59a14df6cf133b0b231bf24dfb9e5edda2c97738b566d06faaab56bd32a75ac5a1802104466404f42539b6d8148a8ad1ae4d954bd5778311490d1366ea5dc0ba7cab9f23cb84632949b34f474105519cfbeccee8de059bb90883b45da05eb5f2d3d6efca4c7d333dcc6b08b6d7c98e73b0451d5fa8a13d03f7ef86756e4afeee4e0cd901911e83895ed1676164ca544d86d0129e72e2cccb3d88cabe009f4d1982b4010c1463aae0648f2156e259d67fe71d585e8b0cc6e4a0cb291e014545cc6f454e7af4c778fbb1aac32e8cfc94e356902e3650fb914c6000b2d9b6a70f3819206d83163f1f6a8703b8029d43d2f7d51edcfc8c24fe45d04b1277621b603d85b80ddceb617ef056baff35458a6525d4a471331a8b7a794bd13f5ba22a808e68c071a88d9244e6980d35630157575a997b3ca01f123bb002b3f35a95a567d304f42dc393d91cb801689e6e7e28a45677d74c8e93fa5cfd42ba202e75876d3b36f905c43cb5d26798d261bac005b02efad0f85a57dcffab04c1eb4dbec2bfea4ff0bff9aa75091857dcf307a3d58c4f8929b2cc9142ba66be4e582378db084e8baceb175ba4b5619654d6dfc759fe1176d42d12ea6b4efb456a4eaf94c8dc1e9face8c3f82f62dded299972d119f8627ea5fb78671399e752848cb6da40152adadee0baafbb7dddd1adcaab9d232b56072eae4871e126c5497de0451ec163b0b554ec85e7d96f92c0b8299febd14d85905782e5ac5b0a3c045ed400593b17112b7d1b61d532767d623d5d4e9ca02cf1a01228514b549e07976d2fce0ad80229418dea917c452639ac41c1a2d2864008f13c7eb2eef49e49573b37d36382e5fcb2d8e85dd4f10ce365214707ce8ed2dbb38479a408bb19a4968d2b34f82b792fe06cfbc971050901f8367e3a70a912225756fd7540f8911c53e365f0b19796813924603c78dba769c9d26364f0e430f251867964ae9842ff0b0f6589b022600d89f0e14f7dbebdae29ce19b618f0685ec827117425fe76e4c092ffd9bd8793bbd95cc268d3bdc4ae910b79a1ab7aa0b389fa8915b9d292d6516acea5591dfff80382904d42954a6681df3027baf4f4916b46dd7442d060d5d1ea766f8b29558604caf2566f041fa360968327ee12c28d6365f4cdc8feb23c78e0496abfa43f50653ee0586b994b7942c010b9e4c5c1c629fe4c2d9d40ddc32d7dfcc17b0fd77b1e1c91dab7ea3250e856a9848684550d95d9369463d5d99b48b476c9e97fce9b1b11cf8d1d33535a831575f4c0ffdf25753653aea9e892840f64cd1db314717da3a06b03b35f4eac083ba1a88fe8fc4887ead0c26bcceaf600ebf550fcabe06446ca6655487edd9065c3fdaf77b6dc367d4798aca99815b42682b2201ebd5db7b9507bd8efcae95e9847ad48c72d9371fb8307067142234be5d297044ed31b0f8024c76be0718a2c1c22d8f2d8a925de104bc56cd8c0079fb1755488fecdd99670a963b97313203c0228e372029e9512d08e293ee0ed260bd376a183d48870d8e9ca284d5614e5a1fd018be4810768ef9260e3b4c38e627f39ed2ea2e02b4a7f373c8d81d61a5c47af1496ec6be463f043ca572e16e0bcd3a1407f3a1c81b915ac83376ac40dc20eadb75debafe435f0c19baaaa791855ea89e9d9888f82202e67b835014bc61f6ffd6c4b0a01ab0bae7b9c91def94deabf7f61a1730961001a5a6a199140d02af9328f219fa7f3f3304b6d39bf40c0ec10d61c2a3780e4512de4ce4f1f7c4356fad469b67cbdffcae99bfe9df5ce1639ab63acfe7d3f40640378fa888df2a29826f80cab170599224c960f5649cbe5f041695f8890e422e47238e85cdc6013f9cf3f3960ed6f559df388ab4121cfd948bdc9452f10f41cf281265850af1c15a5b0be16b8939eaa4657f0c312593852849e382b6edf3b223c4894f25313904f0df534836454ee5fd1a0ddc471215f1b9aacd01d718d8bf0d106bfbb605bdc1f3c48df0b285288e275fb61c1bc22d3de62003caa5067cabe3c9af33f2b53ab464cbb70dba7bf66b1a85dcd004e0d1bd88b156d893bc8fc907a37c6a96d3561cfa37c04816328e6fb1c95940d198332de6157851dfb452fb568285b81faead1aafaba069c372151c2306893876ce82a328c5bf115f1eb787fd5da762cc28083e619f65a21d1688c06394073208892a301209c66111e7763f967d5a1312ce7e5622fbbb77bc5cc84667685c54356cc1454f8e7a8d39b718c8a593c32e8747d30bf46426f8c4e92bcee0f2dcf3b3488a35f2c8062c38f667b4ce32c9c2ba102a04a3d13a94098c5ff807783de545564ab1a734f09a9746331a416ce68e08700f18d0a3eea97c50c33eea034226bc572e012de359e6e764c23ea25588ab17d6530b816b01b86736f67e97371006d95bf86eafd0e58237a6ae1e87400759ce34e0a084b0520615885c72dcf7ebbdc085433803eae3da2160ea2aab0effa1f6e70b05a13fb0d1825dea9365fa75012c4cabf22e5e23953f76148d8653e9c6cd3d50bcf49bc46b24875159087f3b0e9d5a8385a06b34e4908bfbb08be2f022f741b60b22885e228eba9789b46f91adee860d29ab5aa87bd16e1e4f2ea063e1212eda2fa434b3ea632f7d74e55b74e21a733b7a0a648586368e4d03805041fc94cc00f813fe2fc21729ce31b1a5014fef39d8f00864b78068f10e4936fa905460f8a3916f6b4646e122d1358456b40ad0afc18ec0e231d201abe36377a124848dc120c6897240016d038223f1089e76c2cf7f046827e8590f035cf22882e59a8cab84e37b8a0700cccb9b333968ac9006f3a2c841758b2af1a911f22d35047e58f0850a8974b63c58e7e565c2c9c25dbffdd3d430ad8da3661ce1bb645a636abeaf44d9a9a7d0e901f2b21178fbfc01df48e78d82e1aa1e46e483db00d90e7c89d38e3633f7c06628f704d33326f51e60e6e676b815281117b61045142922b015db3b2b1979af74dc3a9a44ab710e76672ae98c38531d7b7c089c24f42baa5034c5a6bb788a6df00607791f154ec1d11b90ced3460c64916cb0ce39941dc624d19b90a029c27f1d5017db44b7658f16fd38a949b980327a1921a1fbc3808ba862af2cb75881e7077719a3dd249a9dfcabc32d6918c824f390b5e79b74b4b08f9c9e421362832ee669ce6f0dea6d666eed879dca27b53b0298c9bfaf0975a045d45615440aecd97a6a11501068c36948871694190517611992a5ea34a043caeb8d1126cc15835060268ad24b2094ee47f3b1890c3fcb08ebfa94884544ffc4e7641f5be75e87c809399326a06dbdbf14bccbbbafe73b2b3b3bde123b9b8c3cf616515f20f6c7239e63962aaa898479b14a95eaeba6cf5b9fb1a20da9f1216b6a3eb40b194c5c3a6881f624785a923b0890b70261a60e6458bbbe312d5408443981bb0b76072feca3cef69d5afa656799b66932d5c3776e62db041f576c9bf6bcecb279ba09a9cf896a77bfa072baaa8d9b907a013fba6012ae4002cad858c39073b320681c6388b95a682049543d656c7b53cffd483835dc082e928905a4524970cc8d3c8930a653b390456f2be090ff26d3dcfc134807ee4f5de24de19c72bcd02a4d7e255db8d46655a506cc08db9f953f003e1958dd503274148b6f7762b904955013cab1c5dadb6ada6ed0ff6f4539f53429dbd208433ced19f4942df801dca0e6eb18a650581e056c14742f9c9407e1a48fca2069052ada77c1e528db5c3224cff602545d22fa3366e74345163a3039cad0501234a4957d1d8382aa5f04f133a44622623a76b40333ade1e247cdfc29f615bbfb1512773e86a183dafb9421f47c47604ea3c875eae60d29ba3cb9c814c246962ee13d673ea3c001c1559f8237d91201f351ec8f4152330115c70033b8f3b64660cd5a8ca411e311a62c23de261daa55d3939b00313de670ef003fc5ad942f271ecadf4ee1699a259c74865212e25b8287c7dde4b03c2eef5f5c36c44972beb257d6106334167fad56f7cc08a04fb1f9b69c8eeaf1251e79e7b1a59a5d619e522814ac4719702dfc68a4d13e856151d6abdd57508fa37bc5444cd0b9bbd147f014205eca3c87cd02982548d799a8449010340d5cd6675045ed583e1ce184b83dddb7bc24fd1a5267d6b735b8ab302754a7d64add1f0854818ffe0a4a5e510ce19a4676b8304170ba4909fc897ce09e5fb665415b9ac22015daafa396c9374b1cbb7945f0e5c722cb2852de831669b490b4d6f57acb6bd187220970e282df33d28d6320da5cf38287a648047a786048bd2353bcd78223c75dd04ee89920a6c84f81b0ae0a39c3b211c6a2eab03b2ec0e6beed3c1c41e2972ea8622c03f7fff9497802362990a5df4382cd25bc92523a910eee85d8e658f63beba3b6b5be98252669ece21dcfcbc7828b48df3815adcb6bc9f16bc9e5e10353575afb6c5d6e8c53305744082e0f2bcb42aaf6d8a71ac3f49041742ffb45d487de7f6efa2e321827e469fe394280b8ab8157c56490d5e46c755c83e1b5b2761406ae04ba76b5b8d9beaa36fb7572e6dea9e5e4ab534e8379e91f56d04881d95c57c4237189ee26055748134badbbeef54687aeb268b0d24be159d1c186051536333c746a7ea570fa8236a865352376a7506780a1cefa143939920ae9db0d3ccab546f9429816b13453e6ed26cadba655f46c9f11285c6d086573182f6a6053ae8350129c6d895091327a47379242ec7a7c7b1a4ae32f36ee045550da75b0eb71a209975849345831e9cd2b34dde5d4f9c99ff1e9105f33b3a0465234a09fdc3a55b4e95f4d01043a5e41b4b459da619eb8a0f642347ff4e53fb40122a9d279996aa0776bb31432e0b385fe363367d5e34082aec2b34b9c4a1119f96a90be351dff3d45ea904ce4df0aee6f3ec749aff91301f8e5f3df42a93f253510e0b901d87bde79aecc6c83f645f6d12dfeacf8edf7357aa4be772f93cf9190c546ebe714c4b1e43fa8552f2f1224e9107c62e7312d0b681025940b133bfa9ab23e0d88bf329e769c314eec70dd70261e3e3daadc7bc4e8302b2f8175b5b6493cab253a2f4093cc22f18910f4c89395f9459a1eec2378df27bfaa8475957d573a9cc98cebe1741709afc34a5f1a9571994a520340dad41da554b01727dae25433064497363ec50e0fba44ef7f8ea7d71b744b823d136aa9b06901cd5f1d0defb1b749d4c23076377035de6ef9c087f9239cec552c6f98e693cdf6812b80d081008fe4fc2a419f7d1995d404b1559b661b2a2cd2d359cfcdcb526f9b5926acb7864c769408c0dc791ce24871918f5b66bdad845959da23105ee87dd739d3b36b12007c29ce574a736b9893cc043741d40a274a4962f3d5167b5e65329fcd6f0bd7f15af8a282468267d1894f75db0084eb4012168c1a1a2812922ca745d42876f54ddad469a4d93ef16e4755e9f91e2cc7c192547ddd86b09aa0bd3a7d10f47075c109d59a41ec22ef7ad467698394ea77c47e30b629fdc751e6785c4a7ccc2a165f20f3ec591f0bb9622c711e375d44d69bfe080b238bc9a2348937badd7dd420d8e84ad96cad794f580348facf0a304980593174e81117a813f644de829a826d8a27f89d904b1c378f4cb0cba84957018d6dde501687f12b9957e69733ebe308802822485fe8d1e83edec790ad9411d43d9c3aef5146a8f250bf6a866595bdf8c9e43ab4ae3367983115215b31d0e84a4f04e3e19e0211293c28fec336cccf0d0643d408645bbd9ebf36e8911c094df74465b1de0a9a70454e9a1fe38c450f14d7f8211e0672ee590ab88239bc00ad261415fdad0733fbe3ceb2be65e9b5114a85c8dd7dde4d638b8474557432988140e8970f3a86c9132dd4772e2952ebd8d2b0d187c885a46d98749afdfcc985a37754d5a81126d3ec608820e962a5cc33a8ea39cb29063c1f831c512995f08e92dccd4ebf5e12fcc495c17c1d0d54bf4fa40c16369673c67bd7de4409db7c8bb15b1e38949c08d121aeb2683a6d75c790097a17c82aab0c058ffd0d592f8382b4cd5d13dcea5279b13830d7cb19c5b271da544d5480f0c649274330eb55a377df7049d452689097694472e8bc27a57ef13070f0d1bf3e7d553850d0d3eca1cb7db997461083a9c2300d92d2875df22602133a7df40ac709252a504c5978eb15c4da2653483303a1d860384ca82c003478470c45032e8cdababaf41f950063648687df36d493a95bf6f4b851be99dd2fc66ba8f31da1dc2da8c146422b189b98c88f2193eb16a4a5c096ebae1d94d660360119f72f5d63fc784536f7d4dd384d191a66b308af561ec86514a790862a97783ef86649b6215d22156e51f0b0d0c63f8e009ebd44614f448a6f36bdd6c06aeb5ca1cdbfc14c8d9002a947a9c87d57db5970ba0be538d2ed05a76accc706dbdc3ea19b6ab896342a45d07b3ca20d9c2f436e2bee7090d9c537112077ca12b512f6ae5095e51f3bb38469a52f54e0ccf617ec1a6bd66d1091987c5f7cea2d6590ef343ef5628ebd6c1e513d65855980eb176f56cd6d85a0eed2cb0261199129fb6b0f94967a44152d3768ab6740ed39e04ee912c69da846ff31bdbe749851235b993cc74b4e25c461f3dc0b4b0c9a3ce34f9633b13e76d5f90a0d3da7a776ef64bdfff747b47c2ea4f5308d8e43a7b2bd0b47832eebd0114974857b03604d1ef8d124bc11a690e07b9d6cd8a6c238f8ce4624096488580fd0718ad82a81f8eb9e48b22e4901c9ad50541d03b2ab300e79252faca38a80fed8a5eb4fe6290127e78aea1851e116a16379e614722bae0d1c2ee4990055d12128e5ea4d144dd41233e54906936a068844e68007e40234ff3e0a9364ed0132b0791b510eaa4336e22c98763dfd2bd247c8dbfd781985844f3c3b19b0296406cb1e88158c23edb50887e9885822a45e450c0f0555055c89b94028a73d01fcb9ce2bc723e6fdaa1bd9b2421bf2e6441000cb23fef30af1e659ba65abf100408ec2188ad46a8e69c209ba9a89dfc6787a687e0fe2485877741694830c9de2ad027449dd9446bb964baddf8b84ab89ce97ca4f00512a15b039cfb467402e7ee643e57139eea16e9cea951e96a3253780f3ba7c85ab3bb4af30684aecde233778deed0643262ede074370ec5e7a9e4777109db8e8b4e1bdc64e397492eceda487910de11f801ccb1518173eceaff5c765e2a7a51e8fcb0e53cb44889cc99dafd927e9e57d03f99eab562802500080e1e74b820e9f9e349d9ecbee77b352a0996ccfb88101eaa857c7ce0fb965dd06b6c8f77105f4692dadcdc1ce1e4ca232abb1e31d91ea41e8348a8412622ff30d0142fe46c545c521842b7d6cf66b2b7b4bbb8f6609b111115251d2a8e9f0cd09b392b11c3f386e5369b5104af985cdf5084053e354f655c910deff4328ad622d55233c9e3956b2d6e38355b033f14428b21a1b546e8b5de6c7f96409541f345feb509870d6745c13d113a83dfc05479e374c13d4e051bee4ce457fe7c3a0d06ef71aa75e839d235a7a47f8196bbf5bc2017156b3a1c74885f0298628baea5431db5a02d780f1671c89689b22efcaec75398f2c3ff0634fa67cfbb9e4b0fe40c3c9429828d468c34f5d2f258220610d6234586831188c97d89fa1565bd713e92533fc088351822012ce01d72428de3f57def66a9962f442da763755057d81e0529992edd8af98e00ded5bcc20962b00077fb74935759945967a6ecd256d1f37c04f3d048d6a5b54f8c3d3a9e81b61e093af8c090eb5b4b23dd30410789a67596bc737443e02c77ff9590bc8f54cac2ed9cd75ae0419e1c6810090e90cfbb916011b659d4798e28babc95301698448c91239da76fb5cdc9fcf642de5c1f7e1490b59da509da5709813be01a824e41b1244e39c226c3082c02d1011a77d742a56efab42e3c92be43700fdee58acc4a5b310a683a8358175aad5a9f6572096bc325a87556794b26e2243bf4cdde25f672a63315cb00aeac630a5ed95613192f0d8c2f191c2c8f45dda125a87698082be0e80a34e3b441b4b432a7ba2825a7c60c3f5fba70e06ec7f77393ca7741f05405981be034fabb45a91f1fca438cf90480e6a3e805d0e00fa0df3d5d9be5af1addeb5627618f54ef40cf1515db9b080a90a849b8bf17e61be4e658a9e638aa2539c411d17b7f359e24cb64a174db140fb7abbaf61133fa546d91a6ec7fefbe203b89c2b9a91794c72a9cf3e41d46854a20588a912e0759d70899622751a9077121bbb198582254d65b0b1269f9f8353fd0b875141119510c884a564694a7eece1c182743ac93cd805a71fcd12ba79fa29ce7913012737ac0748e303aed7a494e00b7deaa328bec5e569799aa1f31e78b2c01018d0ea7f9423c68c35d5448f07a38e2e238d3eaecd65e106efee9c9cc2c6ec4a50e10de329e72abb8029c8476bcd37eb77f75af671f0fdeca9e04fa9aeac2572b74dd8c260da2ff2df38177f92aa7f035bb7050205aa46848b6c375e49a47c4c7d3c01acbf3c6dc8da47d481ac4a1ba3da916344650b12d7f6fa345a4864a236bf2517e415df91945e686257d4cd0bab535826050c368255cba7a1e49591404905427719259219a194f042293d9d453ee1617a9067ea1511381aedb745b4648e4d6838da072cbb6b327ecf781eee3973f771a23823d5802d215319a69f94d679a198d769f4ed3cec544b395a887e9f0cbe764ea4ed90c9035d90cc3063c1bbc516e0a84ede17ec019d627b1299322e57aa03747503fdd421401217f84cb3b0fb8b57a5d8feb4db487fed349be9479bba78598039dc2c957371bd7c2dd57df2ca127b66378707ee5df674a3ee77a4d10e4e8e18f454cb3c08a5f8c5cc69744b905a8313f76bca20cdb699ab1ce5b3e1c2f04099768ebb31d6d7e5d8f681834d9d3e451a10fc490983bb5d65a672675824ba9d395119550048505fcc816e622c18e21fce3669f0254e476c40b3a51d19b17621e37e4bb453075f8b8ef65a84224e176736cb0e8e167ebfa41094a3dde6db3ab381446807d8172854a174b21df08fc9cebe4ce23f2c235468be65d34a2845d0272c9912415f5bb2510a7d6049541ac15d95469dd7d7e05d6ac54a3e3ae20a6e1c3fc21ab15da06f70ac5ef376dc9f83138b510ebeb48596114ac53f4de18010ebc5164dc955d04c4dffbf38245c03a36bb5cd2cd767a012d580295845afc33d23564a2e9b0b00258823f1c54eede951fac2439630ce55877bed20f49d7f24bc4f47e6dc686087896dfe25b4a7c6c7867cac0e980d280982a35c80130803a7a3a129be7be7c352e1e219f00beafd380e8d8c6522e229118144905c89921cc68b3bd449c490fdfd4a27ad9719d832cc2b43aa50c4341fbc8211e981eb672fcae49ba996fc854f550d4218dec37a871faa92a88b40d1098f3e945ad52262e6e41031a348fcfb70985b89dc7c21d8adbc9ddc2934048acee860891149a7293660907cb068a81446a3ce7524648d02dc7b2b284dd38969c0c8fd00da18612c80967fbed036ad0c293774288944fd4cc4c89ca4d803966bfc5d9968d7dbba9ac09bdfd0c9132cf10040f054d07afc01e8e2d302f7a9f72f83f07983ad475411356c8a78f4be33002d2db502d483d35535f498666eda7c2f2c3d1e07edef22c147ddbef40fe53be13231f4b5644046ca07cd7a8f9334e84b83a98054128b6d7d772004d36d95c02c3192a93351915ae1e1a46947dd3fb1747fecc692d6d029b45dd70c79fc408260a38bdf86c63f643fd8afb7e616356bdb33504e0bc2540a91bc2f7be896f81b08d303dcd9b8e5068f85650ce97aa55cb51080f88f52846a68bcb7da8d31d61a40ad776b403a8b84c7ff28ff231835224382a1b994522324e129e5847ae2a246402290f9f4814e7625a93c4743c33c723334b0e0d64e8a422cd37b093135b058b61028dc7f85b36d1ec6505ca98a666e08b6f44e6c55814f35a6aa70d11b305456e2e6dddd102a263e33da3391503f44851f32838080adc5987b133a6b9022c39ae82255443e4dde106a425c751682faf2689e184f41e60941b4322aaae82714ac459be8f2e01674c051d7be97246b42856b829f6b82ea9d9e30c760774de9324b4b1f62a9962ffba631766f37010220da45e8f1b752f068e96fca92695243f0a61fd60e7cb116e68c94eed561ee7e6e58286b82c0fb890acf1ab4104806e85122524d5812921ebe7d1919e78fa9bebf0965968c9f6a8a45303d3ecd4abc5bf42f803f11e99c44eabf0cd0906c7ad716c1fd3c1c8ee9b25662348f72aa90b7b40ca50546c343860c211e24d1ad168a6321b8ea51f0456e1cbd2df5ef96fd67250f42e90c8c113255223d3d98529850f6869eda224851aec4aa52b9dc7274d56c8129a23ad793e371d02baa8d17b9b20a0274b245ab1c543755138ca5d55e515a1179fa671095f3fd0fa01878728c19996ffbb1d42e2bcaed4c3fa900a70c191fb608e7c024b1d7e2add304be122f178735445ad6d365475def9565b830007ce222867a0a689fe6d60dceb1e1695405f53bfac5d8a66719f6edd16937da24a262ad11ebbc60eda99d25dccd4f00199503083744889fb97bc89e5697a6e69179a4fd1ea05f20337c80cbae323cc4a6147e42aef5333a94822bf05af8170167d0d6a0ad51e9a38e032db5fb99cbd2facdc0328c41c1cb7b09d1b681f700670c66042ef57500dad9b4445087d985eb5712a8337678562f4aa43014013cd92fd5edd970672424e9bbddda0c1727322b1e1219fd435f790c9557f64b18420a18f2a3c4e7a4e2776e04b9a4eeb722705180585037e103e787e411c80055cdfe803d1ad45ab82c7a0af058089e169c59860fd924cb6898d6d06e218d59dfed45d74182e4311f19e4960fe2b38aac4af8b098dd4f461cc7a81fc288d306ef45a34b3d0f1b51d24ff69125c16f0636c8685c7bccf69e9b639d64cc895fe35ef5e6c80b5b1f7ff5c04638827173d98c5cd490c91be81a62e6d63c96873e782af9e352652140a08b230d0d9c40a164e2246df35c60f2825185fb2d09739f22990f414309d7da873262adb8a612bd5325db2de491443c9548a7a8b6f7739f746bcedeb5dbc42fefb28c37518cbfaf4fa1802c0aef9cbb31e2061f46f978e9c1f7ac698a25aef32fc9a078c2602884786cc57042104eec522512fb76cb7175132388dd63582c41223c73d77e23f4545bbb2fab4998cd28d72cb257e26238317c1c6e9b973a270a3f0419fe7ba13ee818b0183d327d581871245ef46ab0f831bc6a025c4f030b1c5a6511311af5e2e8acbab08d5e95762bab48d745e89c029302fcde890cfa62d82dc44a1ac83d529ddbde98661933d1973a872dcdb932b69b76f71303d65e01dc87a0fbec01a1e2d5b8975db124557c2d3de0b0cbb8016b94c822a6ce4c83039a97b6845a201a56a503f1e77f1755a5233f855af91770e52e3e1523b378af4894fc913c32c5decfa0445f71cd07930aae78186760700ee0108539804c0535a5857a87d4ca7f52f9a2b6857bb1a7642346d9109164efbdf7965b4a29534a013e085f085408a18fdb6d4f73bdef5c71a6bf566b535115859531c6187aa1bca1fc093b10fb8d0803b7d73664c5c6cf5e73fd6caf8dc857fd36543db0db6b1bf29b1abf7df26ede9f3cef31eff4988b274396fa1aeb6fa93829f69ae779de0d377a9d165d7baa7d4edc5ebefb42eed61c4f55309efee5cbaaf8aabfc6d7c3c4bab8801da0b9281087d3b7fc297b8c461bec3dcf8b511e69f97410d9f8a73fe1382bccaa9cdefee9fb251267452caba2a414664e2c111bca9f50c8bc99146785999151bcd15c3ed36f74bb4f45b0d9ff744ecc94a43497e63334a138893729305b02664e6e3fcbb79dbe0dcab7196d479de9524a37aefb52d763ccde33d0fb18638c310b32e4d68f9f0c9dd52f5b9209654d7cd5efa93c2f7bf9e33737ce6a16173549ba9c0c924da413f99244b7dfcb42cd65c559558bdb31c6dfd1376aae78b30d75b8bd7c4ce0f6f2810d355795a4ed75fb3597e60364bbf2473b72b59faba364c36cc9edeea66454bad3a4d6c5eee273df6c89b3849cc58139602fa4664dfaab210721b6068aecd378e017fa6bf7704d3f6dcd0891dbda12fb37d45c3248fec8239ceb32b1b1cc0dea677523a7c80647682ee35c66a2e8ac100626c538bf6229995e962fbf1b777e5c4404cac5322ccbb8a7b1d971232b88828acc10ad084bb4b897f4a34fbe33f68ac9fc5e80affa758c008910103948b203252808c11241449cb022073368a2d5dfc38603d8c0863a742c0067e3c1062838af1a7286288eb324d8e3004d5e6645e32c7f9b9c244b3f070936fb52305a19f19f15a6b828063eb7df870e999a45f6cdcf3ea9812a1ef166bf23deec53ceb2801299f2d55683cb453e48d7570d2555c4e4c9ed97d1e1a36977f49319fd1d7e69035235388bf2c0a85c0ad61041660500a05b874839c395355c399f26d1c04544f0d5995fb11788b222b8e817802bbf00dcf9f14b498abb7d7125b8a2c2e2c006bfe125cf8c8d657480377ce5af830c1b46a21b9188714071968daf9c866b4ed7df06c631afff05fa06c6a19281defe7ebffe1ae000e3882fbfc68fe64359250ec48e919bc912a41b3dd79dabb095c87dc3592143d11189aeb354a90be32b9c1b3770a0870daa7f1b381a61481bcb84ddcfe519746710e3f0cb2dbcccf36f52cace61b4046806712cdb6790b3425f127256d8535c274aaacacd250c841b72379c4f2e7ff51313760a996193be24ec8ab31cc4a6388baf3f0bc9570ce50b820949aabc5a2d3c4fcb7e61dfede7112c29c7377db0a4e84ddac8c85973f60ca262b326dccf20efa91f6a58920b446c04dd07f41b5b587f9f72fac20974f9ed17ce9fcbcf7d39c86bfa7290974a0eb28fdae80050d846e233fcfe61b5a90e0c5da9916c6518411214f9590a283b08b5607c68c93c4f2be7c80db291399e6362f879e33038728e4053543d7c0cb151ec66bd240c5c977f8a91cbcf21d63ca3749fa2a4e42c950d17a8438ce453300e24ec0d71863f0152b02aff1ccfd35239a8aa008e8fe17de07c0e7087893fce3be803c7c7f031803b389ea795f3031bc3e7f89097b0a58851611c3172f5b9fc13d69f7be4729832f2151f5d769fd1dddd9d97a20e2b0ee440f146abd5da54ea81a2866463a321e16c46b886ff53f968616748f3c009466831f90fc0b7f03c2d994fe543e657bf027700f032cfd3fa8cb07df9bbf6ea65f5f1679ec60be05dfe66008ffa7843f3ac96e7af48fca6c6592ccf5f83e28d0bcf5f859c757afedac46f5e78fefaa4bee28dcdf357226741f11b189ebf1e55a4784380e7af49758adf14e0f9abd28de7af569c75c56f0cf0fc590febf9b39fcc88dfdc3c7f86c459f53f16c08f05163e185714aac1f62a6a20340962c9228aa16601fc180835785dd9c5f7812a1e7dbfdfd1f773fdf7fffd0786ffff6048c3e5799ee7b2b8727c188e0f8be1c3f9dc155700c31a038696a8aac0d0da20aa916aa21730b4b934bef9c4572efca86f1ef98abfe59b4953c957fca76f5aa13df48722a1dc479bd097aff8b58f42f1157ff651a48f4ef115ffcd47a5f80c3feba3467186df001f1df219fe1b1f751267f80bf0d1253ec34f808f02c5197e183e6ac467f86d3eea1367f85ff8e6159fe177e19b4b7186bfe69b537c869fe69b4871867f00df84e233fc02f8e62bcef0cf7cb389cff0afbe19146738beaa1a7156a8215d7ec692fca600425494fca667be9a5c7eac8ab3acf84d4f67d444d2e5afaedac3362e7f2de22c2e6a02c9e5af3fce3ae2598d1a92b3420772209f229a147e2d499be22c49c6e5d7a8384bc959d5a87da45c5af215ff019c589e1b3927ca8418d165a4cbdf585200be1d162a8450e4d51a42236887560b0f806fa79b416ba787d962a2ea1f229b68b5003251353883e6125f6140975f379c412d7c1b14965e2deea40b497a0ac611e42c55ffdc36f28d04a893f8732f71561397f9b8d5af1a28e23785be193497f88adf8521981f5b8a98958825f16354ba9fcb2c0c49f1c8f8008c100518447fb79e9204c5a2acf315602c5169d58f23426beb6e87e462c738935cde431125f738fbc71521ce0a717680607143ae4e9f9121e6a1604346fa2a2f86ed598006340d04b86103baa3a1000de88f4b48c18f4fab7e2a245af4c3a16db8c67fbe0ac3e8b7cb6ff88b2597cbb5839159c4034e93eb7de47a27b9de412d84d189e3ac909568ae53813354745d48628432a4a04284255cb9e2847703264562e0ba82074a7e384b95e2eb4afd1c71f9708edb308e397f827f65be46c9fefde923edf26f1f50c5a31f7ca10aebc9404a3b9df3556cf7e973322dc2ddddddddb338536f2536e9f42853736a72cae83e3b18946d1560504f6c1be7ee1387153dba4b32b68e2edc081351747ab6bbd1822ec0a05c98fc61777d6274caa96d33ab98b66d5a56312029e737e58c4e85c0af8c620f03030313314ab34e677e8675614b73db8903e52a36ba54f0b2e2c85adf62ae5bf96715bfb19957808e50246a74ab283db9feb489d39e2b549c059344a110e960e8ba8a065123d79ffe34418b5c7f8f4691c8a5ebba7c85d289b42297a6d00c9a5466d28472fde750388b241df94b24539644d75c9282a4c43cba369ccc24d77f020571a791eb3f7d9c959a2ea94445c9095e3e94528c9c4583e8babf14dac1a9c723d2d00bca75fb11e8fac722d73ffa2471fd4a1243e894f86143d2834bec8111246103a98007bd84a8a11c1d317981fac175d7c2dd1d09e66d743a30d25ed5d7e87454525e8eccb2f1a94ec786b4358eaeacf182256e8d1a2f90c1ad91c5adf12f9d4e8d4f3d8d4e27255f9838e2bebc4ba7f342e3519d0e0d1729d7e55b3a1d1714ea593a1d94056f4b12275858de763a2c568a7b7a3eaaf1daf73a1d6be2c28485c9d4c23599deb6c0886bfa540b96704dff2e80e29a9ec3b82b7eddd8fe3886f5a278de013c1d37bc71bd6725d78be17a5ed10a92aeb7840dae0724c4f580acb8dedbb06005d77baed3f17034ee198bcbbdd6e97075ab3057abb99af696e86a9f5201d0d5902871b58f91f5ab12546e55e2885b6dcca54a49ec40ba2e4cc380d13836296963b383146c787c61c1854bd7e9c4d6a484e122092257be4d82082484ae7c9c259a43e5b8218c0ccd0d1424418514f4a440084790b8fe3647c4b8fe1b0e1131526e084374431a23c008c2f5af44d78d20a1e8881ea06089eb361c17450b21a4e464e5e4175d705ef01607b8210fbd7e7470fd53442871fd9f882ad77f65e3e2a222bc28324268882938510e223051c40727583031458aed14521c599b2d6cf83f041200b094bb7fcaa344f9e2baff0c35b8bbbbb7445d59802be5db21622044195702c15c08e12344124f2940091bca97095141b0e03a16412cdd940672700431b8a84190107cd00a2d94288040c50c9880b2c3125abef2216960c4dd5d071936b49671f82d0aa20813c74db1c3949cac5cdf282a9a3b80eb406071fd5349aeff1715d9011049246783aa52e4b344861219421a8e18aedbafcadf7d27468bd6ce10ea6a997e080c2d26dcf78e6402d21346ad21a71f7a5aa68f490ca37b2f84de49dfbf21afeb3caeebcf59b9de7326ee6f802c2dcdbb4997326eb1d43e4964f4144caa3f108473fc00e2f255cc8d20901d1d7c35e39c520a217f62e453b2421b1b966c9ca57a191f5818fd0fff96f277f895dcc9d039f40a08e38081b9425e871d6771df427c65a57f64ffe0954448e8cad0edee7e45203a2809897243aebbbb63ec64e8746c7777ff308e13e34082713810e348a27dc76ee2cd02ce51035117b9e0f6ff601c1caff709e9f8caed165f26e2161701f1553f0280b061ff2cf98d7442df3412a0b689373d620d9de347bfd0df2986d2af1e6aa23ee22b23cd5dfc4ef2a3733411fc427fff93db8f8161aac9048de09aee96615e071b0ad7747ffbf403d1e1c5b0f2a7c6d2c637dc53eccbb46d8678c381118c6005999929c81cda09e6f04c7f10204088a49cc16fec528f0b70400827b1122ff595f8f287166d2c63c32e83cd0db273fd77ac6e101d263739bff17e5c2ed70e4f83135d2875e3eb8c27aed70d1d379ef1e4c6761ed85c62c5f1c0a2605e66157f624186b4135fc9168af5f9c1f87a79bbc7167e94a291c78e4a48314955b9787474c338a57677c757bc69577c5df99f112f57bc212232324242ea577f446cd7b813ecc135f2a351bc81003b18c6215c1991aebc911172b95c49ce925772d10d964829a59c614af6c82e641bb96dd448fd6a2229650f29a591115292a3a2a3a42dacf28ad279e504996b686f98f36a3e1d01c5c0e69a49758861a3e4308e46c606162685695e96da4c1e011cd07d2c9c0de799f9da67593ac0726373cd6c7d41d8d8cfa1acd52186e5b6c964a374be874e29a534c810e9dd43dabd08efaf71ede55fc165437ba75049228a3d37b4b755edaf6cacf51bd0282563a383caf5efb9fe30d757d76fe0bc66ec7156c8a958d621bbb2a99f31baf9e564fef8ddddddcd3857825be48e2c29ed2080b528b88a33be8a33fe71462855832233db54cd296d92bbfb0c86aebbbbbbfb94d15a9c5f3561639990e3b2aae5c05a1d33331bf588566efd809e7052b3ea1352a12be4ac9e5a8ddcfe3172e40616cce695ac97943de28db7e6bb5088ddf8f125e3e8627cd4e41cd8472bae7813932a15bb14ad00dd0ed948e836f631e9b6a4e09347f00b328904f215d7f47b5a8faf7c8af8ea07d34ec035fdda0efc42076aae2b4ff4dc1460df2f8fe01c18e3e8a8cb592afb7db33a91e20df58933f3c85934bea795a449e5f64cb29f45f9aa2d56ab4df5572a749bc5c9135fb5f71c8d9c17a43327d96bc857edc518b7edab4834d736543728d605f60486cdac80a0de8ea31c0d532ecd88f6f36d443436a338d3bff454526f63fcc186d9d0edcf96943e22fe9dd62d74911889d995272cf61bc6759f099341c9c6e72ba7fc1cb172253617d5a0ca8d496e7f9d65595479dd8ec8830de50fc8813860a02a7befb1a7a02a03793492cb75b3a226456e7cef93485a1a91477cf505615d3db1879f32acf7dc7b2008fa8634abd2d3bdf859d6d12ccbb22ceb1ef3ba2f1452c557d915ba59c9ae30107e6493183397b33adcacfc382bdcaedcee71566b2ecdc8edcfb22cbbe22c150f1ce2d3cd8ab3e2ab68f82881d4d700774a40e4039f568d1adf8e8bd10c9604b57654c8429e9ba59e497c158ff9d9cfcfe2973df679affa9864df7d34c88b65f1b38883e7bd0d12b0f1309d8fd4ab9ebb0ad87898dfa9f12aec73629c355400550ff3ed7455b47686c8265a2a90c9fc1e668b89fcd4978a63d83095bd7c955d7116d5d168f716e5d1c7bc20bd0d6d449acb57bd81db4b870a1be4ac707b4949e2ac304bc2348c3e76310da3b4f3ba0886345d06ae9cd8303e8679e00f9adb6d589681a1f7e10f9a4b1fdbbacfb22ceb3e217d3bc0483637f204ddac0334b703431f370371f0befb1886c435fe4e9e3439f2b354e5c70c3432ee225ac970bce22befb9fe6599a6454dd3346ff64cad7e4d0443dab12d647c15636a065bce10510ed73057798a0d4c84c3358c6174ca8ca377a6b5fab3eea883cd654bc9d40b79825a76778cad84ca490c7035cada303bfaa62aad337ad75ad976164d69a72ea554be4b4abb8bf44f944f67f4d902efd857b23a18fe90717777a712c3b08861de30128bcac9182b27696c565cc3cc546218d73065c2b55360e3644c5d69a53f8d2b20be72b62225a5bf514a299592c69650b883bd8028d8f650ca60db3cc69629ce7afff41839d59376196b1aa6b596c5c6bec1f00dfbe61efb55594aa9c3149b92a337c5fcc80a2ecbad7cc534753a779cc0d63a9225bb37096e8332bd64eb768f51ca392926847b609fd6c3e6068db66d1cd77d1e0d7b2693b5a7130b4b4b0bca85512d3468d06039599347a3a3c16d1a0d1a3468d0a0e1bd8217f25c6c88cddddbddddddbddd5dc99327bd83ede7a21e0c5d7ef636be2c137b28d9a51b04bb2060e938cfd471de2e87412a1523834f38810a0ca4b08326bc788288d203932b45486942119a0b1ebc954a092944456105a90807464f82ae73a8a8c44f195c7fbe7c3a626b68200c841bf2d8dc30105a31c638c154ab5cd0010f1146d840064f3c21f484245a0270a2821614210b25508868c5b7898f13bfbf9833830d4e44c246c311292bd7f8cfd9fd7a02e597209197e5e5d7112a9a073b2fbf8e0cdd5e6d3d98d87e8ef92646e60f0492067bf963e490cfb8518a7e60c4c5ee6006594a17592ed201941ba6b84f712e1685f22366e493ad79b07eb9e80914b79f3d90c68dfc7c644b7efc7cd8968cafa241bb110c62ba4a649c7179177f73021bb287edea1e604120af0439320c9f7371631de4382a2b9575522aa394d22ec9176c5734018a14188d4d0dce6af099f808a8c2fa87cf835f1f087278a15f48eaa27e5c9f2fa4de13d7f4b3841db8fe11043ee39d1eb8fe51ce1067e2a752e10360b8f367a895fbbb59b7f428683d70ba130ce97726e5e7724f1ce2707d9eaefc420f844036c95da357a95f1076e396964f1eb9941b7fc3381dd9c457119bd8e4b06eadbb7bca204de4abd790afa2d3e0f21544826e3b8bafe8c1c8955df050c4b7b85bd765339b997581ad95527ac311c0bc7204b4645f23f5f2aca4e5b1ef79ae7cc59b160b2859c2ca9470b397427126f6f0807a159e87978771f9159e87d4c77c0f0f34dec6f350e3559fe3312ccfd35a61856f791f2b7ccbcf6f8979167087e5637ea7e557789e96cac6b7bc0fd5b3bc8d6f79984f35ff9fa7a5c2a7c2c3cc870177984cd007cc3fb8a39a9f8a33f1795a30bfa39a600e3efe3ffb1fb8b3f3fdf73c2d159ea745812eb8c5f2618a05e4560b98136d7c3cfdc98f27e6e3960aaa8fa7c55d064a27be8a4238b014bc72e357d0abf82ac6f73a5ff255fc8f814d3a7296f64fc19086e3c758f273cbf4f386db0fde0cf43e279ebe9590796de4736ffac21f20587dd5bd04193c49b12177e9763bee7b6c75e42ba308448cd2c867e2d79b74e36fa72258f9a12fad2e4eadccd208c9593ee44f3ce38f6fe64f401f22f2553cf25544f255f4544fecd2a5f1353ef5f1e34fbc79799768e3735c7e7fa6eb52b01bc9b0215b39eab8a2f98173f9a7cb196a90fd71e64f7c35e4abf82c1d8e79312267b57c7c87e2372c1fdf9f506765a092968f6fe3cbe9a5d4d72f5f27c5997e1a9fcbd7545e3566b0d21262c045142a18030560e800350102a98820caf8c10d9b96af5ddfced73e3e135d5862df0a8e0e5fc5f8d1153ffac4f7a5f86ec5f2989c8524aafeee795aaa06abaa77540df6e8e19ea7c537ee34e2b239f14a7ac30724cec8f8e33d131f1db6813eb6f7c09d0dc401651756ce1067240f32acaa9f2ff63b4c7c6c339a7c5506f6e8e138538738e38c1607ee8040e24c0d43586ef19416b7787e30025112111640dcaa81423e10f93a60d2852180c8d741fe0df23910c9d000077ab0dd403f847de9a557c523ceab5deddac0e05cc31f2f0b7793d15df609b6ed003188eedd2eeb27a58c31a66e8ccc2a1d5416b886dfc643771abd4241299da8e64955734e965f8e8ca02ac618670ed7b89c324e49f9e671b22fc77e9c12ab5db77feeb72f27fb727272fa552d5162298ccefa548239180f792398d38c83b3ee5ca0ea111f86b06fc8ee2da58c37ee94ad8993a0254880da484ffbe870e5c7d20d537c20cd00855f36376456a98d79081e25ad523236e59471fbd91a036b4d9a001fbca0d8c733f2bd4fc270e5034e5c8d2f03377ecfc8d73e79f2c04962555a1d6360b50a65cec270582b318e9408bae215f483a2a0278470aeb206e1c867588acff09d2108537c866f68eb0c8a825ee083a023a92a991e71020208243c241f6b4617c5657a02109c1654bc29426c40dd1642685bbcb8170a322e5c5b1329a84740da0f490c81694194fd40c408bac54f15c3c84472827d81027964447d281aa28b233ed8008928484928310317463eb8928812e480a09fd4136814db72f90a238888c208204c4d58152e5f514418d80daceaf2154568c1832286682e5f0144181c6af36f5e6c93de2c2506c66fde206d52b1c03858e09a7e8e946eb1dfb9660eb912ac5cd3fef99591a937a7bcacb4d24a2badb4ca9777337593e6c7e8c9fee0a1db447c4004fa4bae10fdea9b3a9d29849ace38e30ca1202440493c1d279fa1162431728f743847faa7a77dba0877a305a9a808456ef7e870a55d9b8d8b13519c68970e3f96aa68342f2da812832a3f6e984225fbb1a272830f24295506c689138c20e5d28772b16934838e210a2343451149e68d3b7fa40410c5892836322b1af903550024a0202185d139a94dc019679c51314a29057f70519c88e244cff7ca679c71c619777e7cfde3c1fa94b4b18c4dfc554cc56a6badab7853fbebeeeeeed621a3153b9d1e6d85283e1191911112525252fc8804de893bb1b0d8cfde9eacb5d65eb9e10b36a65ee1082432c4144f66cd8dff2db04c0423cb0d6c8c0b0085109a2e0686fc032178b044a450ba210f41ca383f185f7da88d3998d5ea3f95923f6c2e865db118c617958a80b7b8e70e02dde2c08f334736e46e6a8b33228027a026af33994c26a634d57de8f2a6706853d8ea79a6af9ff77dd9a7e28d0d48bdd57e6202b5acb910c2e2d2298062976591abcef20c87fa5903ea67cfdd5393d775b7a7936d7d4d9f7d3af5bd6f077f34b57dfd62aa3061187632795df644da1053d66ea786825fa0cf7d8d035ed1ef233165ada99d5861fb3b2c0b28846effe9e35bc3b81af7a6af2f0efd5a37ed3b7d3b893736f00cfd5a2dd28671b4629f71f7800dec303086c86261bc2e9f5ca6164443b76a41a4830af6cb5732f86d27fdc47e7fd84e345ab95aebf61bcae47596cbdef32a8aab18cb6d73a9bd834bdfc6acebfc669f659935799dd5baae03996b34d07626af63e1b62a946ed8916b167c08b90f07735c03eec0b92ee3b0219242e79c734e1a63a435c6186394314e3a8798327ae6c419f68954c1a654c1a664f18394c54fd1c5ac40f229180e85320385fd10ef29417d8ef7e460fca68749cbf7f02d262c95dfa25a3e25a867f99478b77d7f3156d049b96dcb718a75d7526b1653c5b73d773998beebbaafb66cd8e953e2f2d5c5a236cc095233719ef7396ed2d16470d998a3ade35e3ea5db1773d49df62ddff62c1cf8821ee39afaf46d5f3f31a256c3d0bc6fcb40c9c3b6615f73936bb28f2fc7d77302a6c4e53fc737bfb1e39e3bc9814cb8f4d594a05efbea133ef6994de3bc260c5dbe99f76db5c7e338cf0a29375cc1731a53b0b134321c5706e7364f6c4e27938c9cc9f4398e7d31566cdd59f04d5a3d9db24ec7f461ef9de9abb08f61d8c9eb38fbf1c699be9823aeb3ddaad3b1e0fb8abee9937182edc73a13184364b1ef03a30949973b1dcbb96029188feb3afb58156650b9db630c30c308bce2cbbcc23670e52b2a835fef39ef543b1d6cabdc6f1e675b4e5ec765590b4b96711cd7751cc7b170a7ced6acd3c1b6ba612c9c8c971343eeda8f4d9ce94d2693f53acef4d99b6c4b8be94d26d3f7a74c29ce04a5c80d5fb0f1da46105290c1b8e78ef33c93e7b1f6dbc641b25a6b9d917d1564fb1d7cb12ccbb21cbaaf5fe5beac8abb9d2a1773c45bf65996615ba66926afe3b28f6f57511be792bd4c977d1f184b53b85bc7b9f72edad73a19a88028aced6490dd8e1a57fb0d65b32ccb32d7be2fd6f1a871356fdbb68cb5d6b46e190f45bf253bc2f68736190bd745298274b7c7be3b1d0a7861e3e528458e2eb681385c773bb4cfbe3a4b039bbb2867315f16b65bf780ec3517ee85d3b0e73eeceb677d51a76f397d0fdfb2bf35d7b13c0b68136728fdd3a7c367e85b1ebaf4412376455375aac65571e5868c455f231a6070350a18cb280465e62d7aa68ef33c93e739cdb26c7a5763aaa8314719f62d6d1f57bffa83c53e94973218436469f604d7e41afa9bacdf12cdb4ecb32fc68aad5e1106958b7da00f36445dfaa84b5fe3b84aa474c3159a316cfb42cfebb8e6eabe6915a3dd10a060e5cb2138660adb5328dd7005bbe960524e1d8c8bb1020145d8bea96ef96ddde1cc2a9d5162da469ff6a51e63ab66ec1da965aa1a63cf3927d6145cd28efac470f11dd817be1189978fc448ba31baf4a48017965e3e12a38a2b7f7610f02106d29c11f0218611cf30ede88523b8118499d3376f89cd85f531c1f6e523268c2e05bcb0d8e52326a6b8d89d208cb352bee241041b59a708ca391dc3689078390c9bf3a38c11e3b155aeeac86e8e3e064efa746afd7db58ec7cb6d300cc1b66dd2e39a71b0773a926bda0c2ec61a2386450cfbe86f9182a0f7d65d12b6c992f94a4e5e1a33cebd56cedfadafbad99979be8c326a5dc7a3c6ad601882fb80e9dd8e9e22ddc9e0f2c32e5f71822b7775f90a138c7137eddd43fefaeeec72e732977dfc541ccda673fde8d72fdeee7670193708d741bfdad7777b94b338e6206c940bd21bcb4e062ea3d62f62d659d62d13eb731594b57ecc359e6d9d83313db0fc1b97824969dac71715f6757fce572c51180e0ea2381e47b0533e81763a8e753a7eb2dd0ef9f3a9d3a691cefa1b570c9b5877b7e08521f0c762882ca394e04191d795d7cb9f4bbd90dcf8302996cf161f07e70ad20d39999249574a299feb2ff8e3e1850de57b648ec1f287f2f6adcf3a1b5f9631983d137f31318c524c62a818a34cc293255588179111d2f3ccca06270b97cfcf114e020a12fa2e36e6f921cc0de598e3631fd1fcfc6bf7185f3edb70ef303697d269689f52c8f4789d439e16d4eadd3db894d2a806aea1b15971b632e7853b1106eeee1d6394724e1486b2be42655c56b16da37393d1b7ded8f48454b77b9c1eb09ce564f3dc40b77777777777ecee6e54cad686d9d117e5ab1b0eb90d528952ba7b6cf724b6cdbd31be89c0c6cc298f314a0ea5432dc5b0aff6e7c357ccdbb6755ded3caf4da6cf9e4e2716aea50525dbc5c5856b1a9d8ebbbb6b40e9babcbcbca05e5a5e5e5e5e585e4ed6e475dccbcba6bd64157b7979a1f345c6176f00d42a16c57944a5ac508cab35cb7a685aa7c3715cc7793ad69a4ea793773a9d4ea729a39f9a6bd022bd8028d8f8dd2d04d5a88e1c8de0aa579f714e9f5d85d8304ba1158d8ccc8a46862d8aa3184631cc562d7a67436c9bc7185b2e8041eed9d30b792ed032ca29039b55e524573927a52bb82cd7aa5339c3688d2c60c932301ea7cf397b72e685256862b3ee517e1387d28e8776a20ca026a8444d1765410a159a110800000005f314002020100c87c462b1582c0e2451770f14800c7c9644764e9ec9a35912e4300a21620c2084184000016300466868e20008d1fa5ed27a2b8fc638d2ffbb97ae90893ed302ad3759b90b10ad5797f82aedc1c166356a6725cfe703151313d3f87ddc38e3d4e22fafb76fff40780e4bf73bb886f6d83cd046caf76aa29f109ef4e6d6eea6ec0d344015cd9b9802e6c227cc59ba26d86d846a06dbad13b728bf2975d1ed48956cc9a4d5e54ff747bff643b9014e9c1c44da6a2003dba449b7c070f7bfc90f63222cfa2f9573349119d69d116d38a037ffbfb9ad72aaef85ef11ebabbdd803b526ac2a41fd3ede6cbc1309301b18b349095252534adeba47c71b3d62d46240175e81997c78b8cd6ac09424493ab24e878b230702b30971b9e5b580a7fd1563278ce4afb349efadab9363c8cb5be8fd12146213da09ba66fb786b0da2249f9397ac485f0a0454bb6f367fe40a90b66ee7bb8cae4a99a931244e8a24b365640ae6cec325579d0f762bf38b554d36ee9a659648d7262c07d47a74f951d89e3701005090dbc8afe3274ff7c79f761218486d1eb3d9ce2cebee387edce15ea982eecee610113603bbe302ca830419d8b65a2cc81860dd73c0a59acb5130cdef26fc9701b4ea16233c6f44b995ca7929c08e700c3f371cbf76cb5685b636dccdcd3b050b4a11e7239b7cdb11d1140a86695c2db26fa478a91bb6813949350e145cf58373e6afff9a413801ac73d1df4d58f201107276d8eb9a893918865bb11a2ae8a6325ee25a1473bf86189c69d00861202c480b448f0fc728b9ec6a29ddcbb817347fb0b2d7c9b2dc0865708cb90ab16faf7029c91339960c12440500e56c3719b3ae180e9c9702b6156b317e532c4f64dea74e55e6a0f4dfe21a4de64fd7c5f0fcb89d30c67a23a14375579a44ab3335450aa61e9cb7aed2e456f403ad93e18749cef53f2c6681c4262a3d7fac04de1ac31e0c6268dd8e2cd8fdc8df42952b4b7bbdc276eaf33a65348f440b6eb7b66d5a5b68b1aab1212e9f44a88027a2cd516f6cf1835daf6711d89a23c9171f06b685d07217760597cba942ee5318f1ea650ae078b1c860acaa2081e2f75c555c3d2dd36d5f3a9ddb9bf787de7f751446abf441962954ec2d49ad013bb661a495f4dbe300759744ee56440891af60367abc31f591bde836089e4080b4d1a662884f9269062e73ae6090064a85be5e89687680a73330dafc891345f3c0ef85646de8581858acfb9205d13e5787e751d5556199914a4e3beb885a156d273b397eaa42467f8d66578742bf6ca0c71e307c04b2114bf92f3a24f06d2b90c56e3630f5e3dc5839e30c12f1520b895695a493a48549ba09ecb38ae85c7c2c2e9b619f23f4081d128f5b80030fbebe7168c060fb5469a0a94175f85149bc1e06540d3c21ab8840177c06c86d9da65252e2a3fbf90397ddc29d717f8f2402d35496dd2c9cc0954e970e26dd836789c8ae5d8e6858418166375bd35ff412dfc9901e56aeaf0c71d9869b088a55c41528a16c0651d70ffb63520ea98ebfff324a42d6757bf4933cafe964152c64243b23f7dfa4d7eca95c41478a5c8da292c76a56af6d0432bd7c9f9eda015fe299d46a1b3b41e4623ee8130f724c7b6f24ae4f3c2a6e6c84f0b7cb01d54d073ee57862754e0f75f533fefcafe822db010683453c41572882586a37a7d17887f12e0afa7af5e94bd96b54c83f0d19eef8e9e5e239c3889bff0cdd905b1925d081d7c044f8c0c307ba776929e2012850f8a50c91d0210a736ed3101956a699cbfd57817ab158d84250481095d66ccad29bf2845c6c6589586bdb6bb0c864760ea2668f4c02b27bb5147562d6f6ad981376204371536a85a28a9e005cb7c98e0d079d2239a9445c20f220e10f048a15bafd2cca044cd4a76c1844189951a36a35a9ffc287a889f6f1565fa5fc4246f77c1ea10a1b2fc950008e1eb68750235ac76b82030dfc2a8439c68d75cb3f240b22d137b28e9586cd03e01de90d1db5879df7ed58834832af761eadd5409eeff4fdfa5657522238726db637a127ffcce4d36778157955bf5212f3403d73c4423eefba428e142c5eceab3e1de35f4c8f6a3485615a04ce25924d5995f63ea4a3e564f0cf49a6e2a56d4de19976cec68ac451cd685bc50c2db66870747a5104dd190b1896ee22a486c2600f7f0b18d1c9b489dcdd5b987de2477444508b048cf4291f6526ad8e1def12e9861851b5b1ec5eb980f25dd5c74801df0cb54b86d1cf45dc82584c3f03d210c858e040a2cd7d17d47fc161d4f0b7bb6a913f6291d1bf8c1247d2225717108c1ea6f841f93820c94d5743de753c421fbb1e228a57e2a214e896132e2216e48ab881d6b4880963a6ce5a3f82a6b312ef8f7972aac32c411f48e601ad164b021df94a3df5a70b1d82d9b5c932f3db30791ea10729f51ad8fa6c0d834f1c758395183a7fa9ed5d4ffe0cda55647e8ad304e4cb1a7bd231661dd4da68c97b6e106947b9b80a101d13d7465e29997c8dcbdbe9e5d1b619ad7562b523d9facadc349b4cf50165a29326b768b635abfd280c421cb410ffca8b908029f7e92c56b529898058f8c210cfabb6f53b85ae7d8ec49ba6d244ad3c32d94cbd3ee7b4c1f13d198adb2e378b0c0ff4dddd8518e2867484bf05d1267c039b8916782a150843352cc2bd9ac50dd6ae8a2ee314038739049348669f27280140e51d8c0fde26eff54f2fb7c9ebcf0e368792473f94fc33052dc2690870fea17f526cd6ce6973a489efa88a0dcc4bad1bf7bf500c2d922e19c05ad8251d67485f713219d76887e55568d826254a2a3a5e7ec9d094896bce2638c1f9b7b6ed8b445e81ab51c8de447a2ab54ccc9b95bd9820ca8e57d3c89c0a13b56f3f1eaf6324218018fbea6eff082c580036cc99941abcfbd189baaaab5b51364be01b3cb3b28f97a69ddf003603126c81c6f60298eadf97a2ed6d4ebdead6a9b1f4ba521293acd1712e91b7420707efdf3ac5526ad05588607f3abaa457125970cbfc4649a3b2460e5c7a51dddaf85503ae96af7dbcf501a7da871d0736eb513b29d9cf873dd13542c26709255b50b3bd24848a2c217ec980c4201bd985bcd6cc640993f07b74b12c5788fc1e9598e680e16ac74e08ee500b11188574aee1255e171c4523ba39035892eb23b08b0d583c99d30e751354c64fb13ff0de5431d65ad68f68cc8a69bb4e8936e49ce2d5c517a8190f2e15a74e033da2a3eba77b6e8fa74334e44c4fe08fb80d311b0c1d2c965ded21eb1e0bef7c4ad4f714cf759ef7684baf6a44d20eb09d9a8dc6fae4642426479e26ad79abd3164500a668ad2e3cb575f47b30b31fb6bf5c9602f568e5cba3479cc852e0e4a91ee07394b326175a865080cafd30d554c63509f832cef5b80733ecb22c32d0e0c6fd5021f6a1f1a31d2d805d403bd04cf3a0a4a09ba8d786fb73816f8a02d83e7ef36b603a88f129d8ca9892f9926d1918d0bd09d3a714ae8e6576724a51dc82737c679d7d5b670dfa1e6d92eacedf23e4781460acfc28c953a24193399e54c8c8b47c687451f1af64521ef4aa040cce05c718b2aac7d4c0637f84e839dddc731cde7f65ebf5037d182ea4598d59d9caf90f2b5050644d16b8333c8aacf097457055040df425c263025c40a9eeb871dfac1e745eeca95d06bdebaf932b1969c72da32a28cdf8faec25814fe7b28935e3e64b4e21d1c75997c00e4ea6676c5a6e1c3b90a1b2c248273179dc49548af1e84c27353e34c4007894d2679261aa879ab7d2b44906f7dd63cca41280497a07eeb766bc4073b6854f4d5a76c7932e70b39a3c5d5f8ffe0b2a534b2b9bb135a5b57a1673c3d50be11a80710c8cfdc1c9f15f40d92cf6537e41a745583e1429269be0b4ef64fdc090a732de80943cfb7a585459ac0945208e0a87688306ff347a49cdd0266f4b63c0c4ac93b1502407febcfcb333e564869e2c23ea65dc2b02ba5768f02f9157e26f3323acac30c118a0c9aa8d56dfa32694c9b7f9a737848d804ba8cf7289e2302c7485447eb3aa6c98198f95a0f98ee8f76fd2a354be5563950c84d627077887aa03ee1836284b92f1f00c719631e80ef9a2d3b19708816144d673f4d18418e52950f51029e17b6384df088da6a228906a8c99e6f6bf3a5d0c8f8707d78efa73bd1e086d7ddb5a4525f4f9e44d97b67224c455d1a4f3af21797a4a251c628040abc42dfef085deb1ecb319e5bca96396c6f7f56cebb9e8861451b05c2eb9ea4c98c356da3ff924d6c9dc7cc73f8f86b6abf39abe4a506164b0836384987fab00c7f8a13aded2aa3b03feed8c90ab9fc73327d28927d2042b2b57a4d3960b1e06f5dab5ea11a172c556ed1aff91472f76fdef8573293b908119936ee0f4dc7506d7847fd160e3999d0d876215b1701327e7f5b64d7785327fcfc0687415fa7b2d0f9861b048920fc6374dee075c54c9320da0497c9e4d8fecfbae6b81ff63484048e3b5d14e56c241b51896990e69d3e18696c726d1378a8163ebba548ae96211f74fd9756c7ec654ea29969559cd3279392803f78bc5ca5f468e9793f29a4782ec5857154a9141a99c3a8a7295032943857f5261beef51ae5b2ae264d7b3c175b571fdd4b900722173144eb152ae25aafefd0764b786c12a7d883a2bc7338c878473ead28d0d2c014ad9ce84ec0df00b4051aad990a17495fa436d200b7540554a42c43ee0a3bf835583b0248e6005b9c578ea1a9d8a302980626b955f625aacfb0995ea62aca06246552cabbdd20a79f206bbe8986b1c15a00fefeaa66471bfbf3e4c238b063a0c3027bc284c787321cb3f4ff37ff5d4b85d9c977a5524a1c77067f09ed17613baa522c2dfdbc7c44692a96022372302f80ede1c1d9c932ef63c772925d9fada73b2f5121e440f7ff00bf4602a0f1c4bce60d15f30fdfbc13e26d7f5bd8310db4dbd04dfa01e20513c733875e15bedf25f2a1128b37b57c06e0a40ba535d06735dd233afc331e51ecdcd5e975d86eb6878877be8e6041236b9595cf92203e1410e0dfa395857a84cb9ba9815e93bd618e61cfd85519aa947ceecff86a512893be05f5d4027862ea14b155a902e56544a981c96870e531261c1ab6d3f82b3f2b1ab15412c1a1fada9d75ec884eea46b707ae99a31e0d81fd63ce80752b7ca101616a021421d093e0f6145844fb10c57f07ca78266bc734414d74d5b9d3d3a94c56259e2349984e2f60563826131b66562ebe383123739f5b5b7573ddc8e00c484b5a9e64817df2b5dd4bc6603ac0cdefa67d70de99961122895d4ebe38e314e54ea7954907c5643501a8615bc5a13734038c20fdd13b9f3d7b955299c36cd883ecd6fc3073d5bc55f31e180bbd14c327d2af602726890ad0aa41c7fcd2216f45d646c936cd98506b103b68d36cee3b5d325c0a648b2341f047614685f810c8de8aadf5108f793f195692d523bcf7908813450fe295036105ae3a6387804a07293f9fc5c096e1812580d12508813fcbf0395bc249661bc04407e98934bd5c34e65155519fcbc6eebc954aab0d3866291d7dac1f2ed174a76180201896d7cb625916791284115684a8e13b7c953d595bf47bbd584424459bf4da7f71508165c6292750f370d42303b3712c68024c4965958981cda38428c6db083f418ba7b873894b235717cda5693946a078b988d2ac935ea3d0d7e3193b57f9cb3a348b7e957a0f57e0f8fbb33e0f0ce353d8412e6cedcc92908a601183a61ecdc1dd638bd73431548bf7bdc0cec46c501e652119f66136425a0aa85417faf69d22b8ba77fc1516530fc9ca1f50fa4e21af0680c284c3d6c3a3806e77431d75dd8f507bad1f5df12d88062389c4f76e2323f78ce9e5596cbf121b20c0e9500086383c26579a212148489d5347332bdfc2d0ef1729024e6540824305cda365960863b5687fd31050ef8ad36457d88fe5eb3e86e22afa1b8d8e498e0876d783b092af02c71025fa41b11e085e9a2393f8770b560642fc5b7e3cba2641cc47162589057ec6ddf90edd51403983d4b7269f96c63c686e06d72a680b01262b7c32cbc020bbf6623d03424f4ff4ae6212c350b5b8e27a3dc11a86a38fb763b1e263d9d011962177364c8357cc87da9c8c9d9ed1ac3bab14c87909a0eb5a30ccc737e0ee60e2eb00d056ed82efcdf412dbd09c6ee97d05fe10623c414fe81de116c8982df8ee64139bf5567bf74936dfedd3d6cb9b2676baf85422a80c2fcc74918299eb8494e9caf378830199d9205470f9928026af22d158539053a5b1a2056585a6b6913d5cb7991214686bd345aca0e50ae58af58494d0e5c1a8ff472c5521ef733704630bab79c59dc1aad791508ef94261b3a269abdee5711b67bb4637f9812d91346521b300d406746919e39045d9e33aa19bc1042fcf902babc9aecb180be264f61e23c6d2be164310bd3017b740ce38b1e4aac8a1cc97936621541aff8d3769d94d17394997065263bbfa624c0f871fd0077d213d9718898d2697220553023db3432718b502b8ce7f16408ee83ac6c582809dd5f45e61f7848ac82d93e9d7dea0d59dec22a6ca086b751e16e10e095eb8a5383fd5ce639c5899d0e9c950d212f1423d228794b62e0e5d89e963ffacf71c49c0bc2d66281dadc3290ae5ba481a72d61120dae8a562c6f0648fd8906982269da174d0df5f5c14340ec399b29986fcd36a266304db3178815aa82b73d8d0fbe802862c808c33fcfa0c9c032c2b890ce1fbcab379d2e35661df2902e01227346354f56740d1acd1b59ae3fdbb8b92eefbab1ca1daa38c7e646d7b5bfbf6d97d2a7b6934637dbd58a036f3770c03b439fce635168c0facd0322b0270c066d379557d75ddb70e807eacd6d9e2bdd6bf1eeafd49b270025175ed773e0bbb7e4c7e0e23b921170ed646470573b732251bf5ee0b873453f2192352250a4cdcc3b4eff72ce2bff6c4f0289c0e2e928fc1c211a7b92960bf7e65ac975d0cf8c1927c162756e56e21429423984c30413176bf06d24638306450aaf797f0852542465423a23cd8e8f3dd4719de7d35ba408932e8735431462fc99f8dd898548f1f3940cd07fa51c04c72301e7905f51454a11b5a01b9239faa8d3f2e6771a228a5afe5fb6a1a785d8e047935031c8e6650d4b08127d441040443c7f5e8509a76664840a6bb8977a4cbd7401558cad225b9d94f41c2c429d098b4ed8bad1579fbd807d6e8249ac498611c50dfce42a58e053db622e5f0d330bf66f39fa53e233b6f26e603ddedeb5bd2c999ef038af16ae98ea59fdbbe8c7a2f693409f1d45b0932c66da014b31a3b61e86545294aebe0bbf5de740fda3bbba9cd99a1f377913e5846a511c01723214e2b72840b22c69f961ae3b62c0e07228511cd068328fe5ece8d3e933f6a35b2d24f8112808fccfaa34686ce1aa591044849bd2358f01e624f5c75cf6e7b6da3d718e18f5cbd167985442001b75aa2f3456db4b0f1f99d4a36f59be204d81e005186c4beddd84e5771a45bd8e78140c51dab28d429867338b03997562d841e8c319cd71a274609dbd3f30cc8ae9908978f378ed81b9094bf22b1cc5832f29a3d5df94413c40dbc6fbb7d96444aa313d0cfa88f7c24eea8dfe0bcc0c88b14f4836ceaa8cb4c496d85b161dd99a547bc8c35373d899acbdcda6a4230d5ffb937d291fc7ac8f84f199643fd6a980e39ea039309062430f9daaafc4133d0f9ec59bafb25c25e8f82124817ddea5d00258d400738f40fed175cdee02c79de6d1444177b671f7759808dc19989e19dba955ba7c9654143b53be414c4a00b8c8efbb8550b08b8356c4968c692617ba4761d3426c367021e7a25a24d618d9e674d47e83c7b62b8c510f075821a6f0e49825a430e05ff778218a0e28b65c2a900a63d4cfab49a5fe4e12f06e13b53aab8aeca2423c007e52034cfbeaf8d300e1058e814f5265e5884cb545337d110840f24274ca710e837e38dcdd701954d243b38a728a2509e6d63019d6438fea5ef56bae34181d706778cf8fad0ff6fbbf19f24fa8d4be3941275a025ea582b6f89e18a3b856c153113bc94ee955bfde81b097019a6ffd8a52dc28cf3b45f431106b6d7305e0fc69ac9c30194c48074536cb2e08030e5d4d407c9364d904d25716147505340d5e7ee9524ad8c3f4955ac65184fe71bbc8d1f9aa2d2e407273dd8561ccd7547bc000be131a2b8ac2801ea83481e0136d8a7db006951fcc462e7e691707f98eb7410138356d249772c8f482d6603ce0e2d68c6592d613333470a79c3823f9bb908af5ea7acdd99bd43446f6abdda97cc14f496ccadb81593108f868896c9ec6ec852cea45de2b73a06056e6e19012900d25a314844c79385d96530bb36cf1be55a6468accf5781101247b0d2f3d327c5624bbc84af6f625ce7384d8872ef900b90e74a276056c25f7e5dca563cf5c7e164b53a5185a51a8879ffe4d0eb86e1cd3a9a4777dce9c09b9eeeeb5bec712c996609537b6582e2101e73bd7259ada7ea9fc3c1487e91cb0c0af6851177c884b98d87853d3a36d2d0fbf30bd383aecd2010f04da00d7783173a156c22f685aac1f180781e6bc5b8653d66e8623655251f68013002b16c588d6a3d2d6e2ee2ec1eefd4493c1651cd5739f9c219bca45f79eb86f7827e41b392543ddd61b1880dae0ef6b0152c30d10624ad27efdd5b2e2b6ac71594c457554215e02f28368081bccb11e34f0f45004c22afdf71e4d6216a580f632e32165702436c2f0c4b7287bd0ab5466f779573078fbc0153da2c1f3ab0cb0c3bb13d1f726db1af6a35112cb9836858acde46f8847f4f88864f189fc595eb19b6747996901b937321115850168595230523dc782258aa0d0edb7b0cf013ea5884e2e14335d7dbbb8fb9e6be362c58005724144c205d1db8ba0f9ff0f422102ffc5d2f0e30d61e26f8d370b1ce296bd97732e61a04a87ce60639830da88336475145a84ebb7d44999d71a2e54798808a8a0f2dbcef5e77ebe5768a256739b226f5dcce89d3bbdc850645dfabc09bc94fc064f4daa659dfd033bea29cfb54ef6c605d2135c42ca7b91941ad5cd10445dd5ff9828e7bb376b9f67c49255b1215e9a2c74b5d4e241f13e9210d9fcd60733f9d8f5491274c87756d580cb28be86efb0ecb3db8d386196c371998339ca39bea9398f0eae8c5c14bc60624ba1110949949fd82c3a65681c5e44bf4ebe92ad2e01ebff8e9da3091e5cab0a777a1673ca69ccb8c0d63caa157b30a097fe0d7cdbcfa30befccaf2dbd4917cf431d0950ebe294e449624cb34bfdb55ff891cc450beca1b41cb544daf0b70605b1353c0196fe7d8a6c630cadc4f91c6c2bdbe2962d21e9895117b5bf90e3d6eee1d329fe0aa207cb04e354f86b32d806610e0e6d6b95aeaf314bd914503c356598634f4b604e408411c2eaeab087dac4085f6ce39374a7962726ca718680109ab302b52b6fb8eeb1cf90c5c7c6e3863909906ff8cbdf4b3218480f945f2e5261bc8d94509802fb1d8d3471ee3d8037d104f1a8d97050252e2e032c547185045087345b95e40d2683928d9f34940177258b0b26feb136589515233c9356501ae420ccdd01a25321822d0cc31d4bda76c3fc5692016e752f947037d18cd4eeba6dcf4f698eee3898e7d19faa2d740be133c3bceb3ef351b74270fb071988ce3b927702d433fae076f2083fc7c80bd90a5b8bbed18081dd1102bbd8654c3acccaef12d01d5e96d909e804edcdf4713765eb0329bb8a76c0316b84c310872588a141843d23f17c9a58e06c2886d0a3b001ae884a775931e89d801ee940006556d903ec4295c43faff55802a4f0024b296e9359a178f31600d13c9e7d99e83bf8cb2d90deca515b052500e2d1bdcba49b59ab8ee2154bf24e8e8325912b1e5b8b746672b451151005db9a3f0be8b2e2043f03886ad2f0acc2270339b381d09b1160e0e9cd2db81b3b5e89b196d2bbcbccd33f7a5ec6d6cacce67ac1542e063011a3a6c0392715050b855ff1325eb3d781d2f3fa0f0f24cb45d55779c225feca8523a6b983ce9263816efb6a38b6a5b1474c87aa63dc3cf68f7a2b3feb66a869d73f338fe1e15c64ea5c3ccea8d5fab2ec0475d74f6eb11c536d117db918cc83933b959147158ec1722e45a11003f4d1c102913778ba8fc6d2cab30efaef974f5aa6755bd8c5f15237721b199845f0d008d944adf77ffe6b6759c3179a02a10a8e0212a43707bb7125ae991fbf5a4f3ddb42d60920639194deb16835c2c628a0df6d18c070d30a1df8e0f27fa4d7a7380a205a7e59f19d02a23a2bd04a11594383899d43799d04e278fc9e106eff71766ab4564a24b0ddd5b83b061d1e64c448df719964623456ad5560dfb528dc91309a20e152c2162cd107120a718e8a1a2b8899a6b352d6bfaa7a2b6aecb6a1a710f3b2a883c96d5c9cb8f36337b94bca6f617d1911fd900d46dd16f347572b462be6c75f5765253c476963f7058a17e7ea40bc241b733a04b879cca48655b4cd4d2dd24d314f6777d568b8e29d01838d280003d9de501d7b8a5ec904058e37ed8b89b953ed0a8e17e5577d46eb81e544980ee06202dc786475515f1aebf199b2fc9b7b1a820b48de54684f56ddb82f9ea9f45dbdee24fb83d38662d1937e32d6e2803ed5274cc140737e78aa0c5b92ae73ae29c7502ae2ffc8dc17f819c08c0a21f115eca9db51d7c5445be91cf82b5fc8c78dd86f20db8a4164df6d1a62360760c4f10cc5f5d0a45f7b09a44cfc9e8a0596271cce24893e81dbfed63c81be9acde4ca8d443626ee6fffa7a5a8740fa3157c4c353fcec758acd57930af69f9050d334dd7b48015b1933d59fea19b0646cda66fc01bcf3993ea76d9680d60028b62799d1fccc9408af49f584e533ff13cb801e0aa3e000e776a36c040e703ab65e7a9ef64c9e2fab6908d17b948cc1539ea96594f3c3e0adc5ec270661d9d36887188f11c61a0fd9a146de86a65bca264875bed3483b3064e2b2336b398d04f2bfeb5f2cc9aa4217ae9b8a438caa1ca08aa0013a531d66d16641fbd036ae2a2696fa962cce1da06af1f3999c88db6ec8810a3f8ee96e1ac5fdcf82b8de664c62a01a1f494350615034907af16b1ca703aec18d68e9cb1e943ac35cbab5f15961907055a6af86e2d69dd8bdf041daaf8d6c27abc5b327c8f37205fb1ec1310bd3e64b4bafd4aa647ec13a8bce9843a7a7ab17b1f2cc678fc6167222180a6c865ac25c2c46cb39f2e1cfce19207578aa9b7202ab9065a93652967206bbac1d60b5c6cd77be11d07bb16a6252fc4047bf901a4eb0d8f634a788cc3bd14747398aba4d6795773d7360d57745e698fb5c464d973ffef0a8cc1f3a0893f10f32b9ee85fff88e5b1382efcafc8d740e50a3a198d6547c32ab09ceeb0cfce9494ee6aa8af9f8a2971522ad0c87db880f3e4823a525669b943301b94f4d974310ccf7085de738d1496cd56bf380d63936d01ce27b92538380dd282e0b30da30675314f2f53295ca9fd1b9e5246d6c9f0a44b1c0b390031d8e70a3c3cceff2734e877e44016203206f0c490c78b5562f947a72f8deec505612629fc3525058f4b596c64db3702d05ee311bcdcc04f81451124a60e9909eec077f9be96972be98036b0a67274a0b5e3fc79c47a69050e74a0f3f91909723b33876164e4fbc14e0acb4f2fc872be08a0894c23b40cd85e58cf5f9803be09c89d6e43bfb802aa7f7ba4a1fdf0620087989896e6af562d5197aee2079ac6bac76cb71bc0d260d71fae1d44e74288c0b94911f8ebb166f4ead58404f93507c7f93e1daea61197a11e7f8426d162d6cabc786b3b46a5d58d1e0e5f7feb89209fd5cb24fb9e20c87d1480bc3197ebf72c1438001716e8dd76bfbbe216db737d24862154e3fbcbf813fd152539d885e6bd2742e1d086d05dacb30b54e2ec93eac1dbf5888c1a690345f852ad099453db4f288552c4e5e050f2e5f025b83e538b29c1fb9056d49720a5e7ee97d9e96c392f66e194af817da3f3307708eff6afa8e4a0685fbdbf62cc465f9a677f81284764b6b2995b889a0ba13ecbb2613a187a32db30ba46fb33cf024fa9c92c22230753446815fbf928dc896db26819944341b076e82412e5017e66ea83e6309782519958b6fbba8198509c167b8652dbf4b69cf6064b0c030fc3c59e1997baacb5eb47f1bb0aad45fd74ead6d2f9bd91cafc4781d1c6ffaf31906e84a88b82a8876461f2c12c7c3ff92914fcd8cc67bd958cf834f5e26aec455073c26cd4248d8d72dce47e642db621d574ee98c6d87f220cf13bdf75c708643380200a293da243ac7628a641a09ab0dd96b5bba889716d1d69f5b2583005d78692d8cf272a26eb5626d1b52409077f2706b6386748c6fb5c6612d0101b2c5219c6a47b6f539928e7878b6712d45d3ee27f0865c44a0603d4f9c9e2f37a1e483b648b1ae85071d809b2de10bec4ff2c384cfe838b424be5fca3512f96f2f3287af53417c4819a986b42e420400b81ac7c7543f2022c833b9fa789e7231c807833931b62b4b2e88d281f6f59ce12de5967ecff57605a6cb0649b17a8713c15f813ce7e39b606c5c9e02272c0b106a3dfd4c2b3c04e65afdc2b59bd81d7caf2d738143dff38140c6795909d32d6968eeaa9ab0e4c747a54d27ed1f63eff5852554c790012da563928ce197a79dde2f9c8ff914d02f14a00fabf943a620bb472dcb23b55ae3c3d6b5f3215b93849c8e1baf6cbbcb55361e55eec4ac8cf8a760b95abdc285d07045fc7d58c3cdf20da43ff8fa8843d34cccf66a4322aa1b9692d2f0bf3239a19e14213f5d9623dd6f22f567af169a6cd3758d66bdbbf4199f654d754903af63eb556699f733b13948c013f117019b264c4c82935f65d89c7adc919b50fb1151fa1edc8e96a7d64acbafa60f890e9f6703f4161f3455819d09180ef920643e551222b853954f9e6d34ea61ecd10c33f7ba1f3edd6256c978b293027b203f838f3f85e27ee3f3d74971f6b186b149aa7be85297d967f79808456dfa4fdb1d646e8fdacd3f1289269cb0b3d0b84f17e0ec908ca9c16fbfa4a436895c51c5f42fdeb1e2b8487cfd56dbc20605b4fbceccbd76b2f8d34b184b1957e9be651ba2a2ac18b48a508955b5228a26886d40d4dddadabc7de8cd401db34e94a3fdab582defc265d47f12355a4996deaab024007c41deecf38dfd2afb96447fabc9860f43b0cdd3606bb4346c8f9ba77f7ee4ad7c83ba8c6457d6ef59aa5502680fbdf194c5d287bf2d68eea0c861657b5dcfe5e43d07d176402d83b22788b91fcd0342cdb772ee8376289eb88ee9e6b2228df668970ea6eace8ae02b8966bb69f35d1858b0a118d035a1d060a8866202288c6fcd3e5a70526eabc9973ad396485411433930ae546b86b903174beef2deb5193fe7386d77c786c2eeba2b8fcf951bfceb077fcd769da0c1958c5cc257b1a0adc9c6268c31819e67dd5213db1adac95842851ebce4e84e802800e600d0ecda9262d70fa5005c4c028ade25a90d9f1c78f62326b548ebfb4fa6e73d57cf72f6b9495ffefbb491d1c26e1060e0cb81316012080be9c80ea18dbcf19036bab795af6a3673f6c56dc3058f8e6833e0019cc53ead8b2d12b0ad2f8b8c02e7c21c1dace3c0e83b23d96014d9f358701c03de9ccbfd14ae0977e6ba437e1f4966470894cc1b886ddbd9649c683c816bf06915c8406c2e3ecd58e5f80741bdf2aa9cf136708894787f97b7470417551f3b481ece58eae894e0ba607c997d9e62d87f307d23551413a12dcb08147f2637626e2f997ffb182e0504ce19b0735372a376d05fb116b2df0d5a56963783358d6bdc7fab0f866d4778b7aeb04fcaa4ce32ba79eb55be9a98b72e46d1219b8fbffeab72a4735c917201f8a5a5557ac944471e7c6275d7a98ce06721207fb8baa8fa0d19841f20ba6bab73c8a9309c6daafcf21c5219f3eb0fb09fbf85383a1e04d6165a0efe180bb0082981fe0ed9c85609834294e3f5ec5542035441429fe5a3f05d74212c56ee52d8b59bc295ab9daedadcb219243457fe149b3a9d24a63a217cb3b49244ef6e860dc0e8ce51afc30e391ac318f0c44121372915890f9eb95a2b61b35f4f1e6d31b361c2b8379902fea6fc9781120ef00174514f9d346379a0fc0bec425cc11600a28b998ed2e78dd64749294846d7050a957432d8d2f7de763f073a2b92e3124cc63872fdebe9320c7befdfcb4a79363ece5e9c4af96bc38850436b0e5bb6d8b46becf77a2422292777028841404542883dca10a31aead536d05701f5d369b3d64464e3a682824a3d5344d9d55ce0198447725afbb01189edf29ef639fb97e35920dabb4b2d52f0d46bcb796bad4f9f6c209a6ff759a55dca9f7d147c7f14eb506b7011bae8a7fb1b706b2f81ad6268a42841544889e5bc37b5dee5770d5eb5a72471b8414b1f3bd7c57f9b2bd398b85d26eb393d469dadfe03e026d4e31ffffdc958020c7143a0b39c9ac2007a8743127167c15a3752d93e630e6f1655167b8a20177498138c8dd4e9e56fdb04f83eff802fc2f7954f88808f72331ed79f129db4a6dde6529073ccf913697dffcbd74815ccf346afbbac0f459779154969eed3af4ec5d301d97414db2bb1b7602f73fb906adba95ca2992121a899fec41b9e3d51d75a65713165c3cd8f1ad8184fd3df845b5818b33dd0470b04a5d7b7c815164a96bf021d857c89b6bcc9bf508cc49604be44a13981ea676974e2f62ebcf582479a286c480383704861bde43a014bc5d1ee3f1159262f604a3654e919ff22ef0f22328cda83f5e136550a293c3054982e079336174c7ecfc26cd4d7b148cf6a143583d69a43e6d245f40aa415c38e7133c77ff68c6890663aff5d9660f0cec14fd55f59e98aede691a1b55a71009ea1d7de6d1c411b9a0578d20a64cc3db6d41fce43d3eb70c179da877040fcad72f663305edc46cb5db9df6c8e297531b3d36b4719450b6dcc66ba3ec8666b5960757be34babc59dffedd38d2186cfa610854999d56801e38fecf17e60366677c1a77293da149650ab622e79674e7f9593f52ec4fe08bf0a6c4776ad9a70d873e80bf7e89674d9a3e05c6dd731023425e51b78085d36a28f84127e0838e3e4b03262e0f3d398f4cb0f7c2eaefabc2681705f57b17006bc58772a2c844d788eac6514c56391aa04eef6b4968a7ff9ba3db543e5907c331e1488422c6a2a526fb74fc3b8b8dffcb97a6a676b0c523b39bc0da5e3a4712ea2e56509c3b1e404e502c6f9ed6458ea0386f9ed6dd1574cbcdb3f5c911b4e59ac7bacb1514e7cd83f5d411342b3f8fd62b67d0558e79aebb1c4171de3c59171d41b1fc3cadbb1c15c45b00e8b041813ee293f4253aba29e5386c462bef731e437d5076e285076775f76d978a3f9499cc9c4a58863ac0befa3f30f34ead59ab7eed7421ea1aae5bdc968cb074acb24c9196999eaae5d7e1739fce752493705c2149e475787b2b80cda2ade80fcf7ab5593a2a4595b43afb667860bca9b36587f4dcb329180ed8b0b05c56b510384385e44f6bb26e3f890bba8f8ec9f8f5cf7851b2b8ab1ccc52572ec0db215beac6ceae3e187c9e5c0b6dd356d06ed7b5324a8188c50249e98029e34c30951703b311c1091f662e56af8f28853ae9a781024a8b4234eedca5bf090edce3d5e39fb677cb6b9ec331f76bc74bf897d494195ef1035cb8675c857ed92b7e4c541cc240bece6a55ac3fe82d05ce2b45a4a66ecedd0427144a256541a958bacb4c19274da5871ec8a37bc82c611b2a15bc008107a02d04300d22bfc2a167a56aef588af4ff9ebdb84fbfa9a89526604dc6282c5c6ba3d38a54fe75d7871a63acc926740cf7ab83110b1e587fa91ffce0592fccac2ec5e24fa016544249c63b81864ba511b62b090a63bc027ca030cbfe46e8e795534b2ff721bef65b22eae907c5359e132911a6868c5b32fa652b89e1c5c153a1618688abf2b18080fa3a70cf91fc76fa1f9183ac0e00f3924a35b84598e2c89205410b53d7401601a0c87969c954225bce0cca3d1cd097a3c377849448d67cd7af5ce58706c07338250055c21111ed18bdce8aa0565cc847042ef89d6e0d8006c52ffe7504284188e2e737a374d4a3cfcb01b430782d26585ffc926bb02a6074f5801c13e25682f0c735541e6fe2037925bada66ed6a9838be550ffbb7a52cb0f7f9fc0fb8e8b2f1641784a4fa9f949c68d09ea61b37c0d3d1bdd47343212a1caa9c64138fc99d1295a9d81d923ef80e13533d73dc8c8b61af20ed8f5088d61fd5163012c2fe4859e39f0315982a54c6e870d7166cd21cbc80ecc6369092f7dd64817b10a1bfe449d4230574e62aa7066670bfd64a7950d456085538be4095936e04e0fd263e7a4ba3946d497e02c5fd2c8e7ef786affc12ffeaee3e97d10d6e5c332dba444416df8322c6b0f36e2d9e5a3a47f9762610b35a4c9d1a205a96ab6ff9aa087dc79100a5a78ef0679ca120246651a5356311e5de0d6f244f3871181b5e596d57960beba80aa7c11097deace45ad21315afabaec8783480e998e2882b93931b9ea5123ffb9c9e69bb722d48aec7414158a0039946db309b05bf1d6ff78c52302f00b4bd5072884df1f28f07e88753b4ae26d5660e313e6a547b223b2b75ad601b7735a498570786a7387b9c9b6e78363e0d090644f392d0d94c07360d4cd1ad2ece9859f5abbf3fa37dee6736a41d3044f9b829d87abba3cbbf899f4ab72c6452dee5cdc59193f052b6c1849ebccb8a4e91f4086f41e81f18bed19845c41cfb1fccd0b951a02ef99983fc5443ac88393abfe0176678e71bc2e1e64795d63e626ca0182520f456e67036e28453c189e031a6f7feaab1954611e6847953bb3602f32c1746907003c426de8a3d0f77277287341445e4c0683484b99f821014664377b39891da65fd0849cb56b7c59a24a626eddccf56e7feb283fb33721dcf0aa87ac032f107a02a9d86cba041d1bd9717952244fdc864e8d2c79452fc7b5185c7647eb0f4ccd751a02562e0ff3da73ecc7a94dfcf94ac1111fa34dd37a6ec831c4235b7ade03de1420c9d85fc06477254beaf71064537454ac4f6a6b17a471ef74a5ded1413ea82d215391d765c83bec523ae4504284411ff8feb819d388dd3eb63f3a7e606cf343312a9ddab28a2127b1271f33a192a63fb1f267ca1e076353bfdfc33203151a06e90df346acdeb42a2b6144520e9bbb9a3f95b790b8d9d06bb8d57a848a053f2c51c44981c511f937de9caef8ad96c82d033344cec938e4f5bcca4609c68b0907ba028ca8c71bb049644e1a8ea1dfe6cb3b5b8564211d63ba58ee03466ea2b02e0550f5885b912937c88333092cba2be91588cc4e107341c64965ef40345f577aa9427baed4dd4b7490fac6e2a7b1f82a2050709263091a69141515e665015cba353a0bcb2aa903bf29d058db8f13ce473a7e938788fa9227fb302020949f4bfaf0e080a898cbc0f1c30fc40e4ee2d60cab4bc13fdf40b42810c08b3fcf2238c0c97d7622eaea82094ab6ad2439c0045f41e5c690f304e8b41648ea5f571b00b9a5d8287a79c614501d8548f281175695e1a254f6dd05eff9ea833cbaf3833d2b4c23da5256bf1508b90fdfe3b4a807de567c80f5a2fa1f9e64573591a9bfb72ced4d8df01fef759e431f1177e791b337a38124e7666666044442433d37249efe84d45b8b21f0e9444752b3873302b506c2683dc7309ab7b517da39663d64b22100c1c03f31695c7c0f8d59a9d28ea47617431490e5ff6257774c315d8ff995f4a2c1c382e7a7e5015561708220266b69269e15f915e03a6ea40c30d90ef68260578a517b12027d8851612e7b8ed7a69af4c1f6e0cde51a43e94c1dd13176f9dcbf7d0af44b4cd71dc5bb4d1fd0dbed2a6e4c968982a24320718d55a42ab134fe75daa75ee03bb65d6ddb08944a8f1425315dc11acb88b911e1b1df3701108a1dbea336a7702ccda03f01e3b185d5ca6df19f6ee46bd32123e23ecb95aa9cddddc314038df1839a166c5e3e36bbc8d096c9da3c5f975f78bc65d51f86fbeea8dcc83f0bde9c5f2c84f0fc71fe2a73bbf56f8aa83bc9d083af9827648772d9827be2eeb55937e3b09b9b4b6ae29ef74742a5f347dc239d31035c2df1e1887346e5ece3ecd12d85c9e8e9b826bb65adf7e5e063ff8af7c9fcc375f39c22ec36d18a0ca9bb0b4dcf9d84e9edfac3455d2f16bce372b4162a5423bdc4a24d5389173043d6bd3cc9ba625db90a577c7c31e07553a6b3f302decea789cbebfa5dcdb71e6cda13b4cf1b3b0d56036585fce400671a88c862a3d9072d25d2d6bac084014ab82c4c6291a98239f2496e606d7d0c8b68ea9ce37cc63d0f211f57999d0cc5d0d25b33f7bdcca14d936d2b05ddbeedd5a4333acebcc40fdbd6043c52ccc400291cdf46adfb788a849585639d4b16b2ed1bd40da35a0f139c654f845f7079cd4717d7878d8cd9b1dc4e0f022cd3e5500cb7217af823c7253a1dce0e793baa0331d303875c9b384b69ab6acfd3c6fc92efbc3ca543a38f10e736a7dc839ead06496a0d20a74209b6b6b1b8cccc7f4e2893a12c4542ccafbb0781de58d3dcd77a5d8e3339258bdb9f17ec40abe6f35944600984a61a389ce350f6c36e401032f7dd6852ea22f205675a63d79b98a9960b75f53ba6e20cd9c3e92c002ab131a5b02701ad419d982dd0e4024528b9a88f4b314b2b74ab09045b24e4738569e067076c996826a5e62e24a09fe2faf6b67720c66ac6faa597c714458750fa5c70d01c37f1bc3004a4e61859c47695eedb58668bdeaf06a87ed696ea0247cc0b793d81cff4bcb28be36987bbf13bfb89d53456ce68671de843807d76b84f63a4e5eebc565123c8f56bd1126e248ce69001564883107c868386c06c5c7566ad36b1be435301215bc14c3c46c2032f169a0217ad4c0146dd252cdb620dbe80ca271085d29b5359bc50b3748dbac0d8a70f0b2f8d386ffde6d44a1849f7a1f5320a2d48957c4f9f74ad6f8b8aff6d95d3d74d229a58970f63a10c666784d19c96310bbc44a85329b83128f83bc8c5088bfca29cac724bc987ba504268be4336ca2962cb39a0c7fdbf04d9470631b42cbf224164b5ab178518a41ff01157d3225f4126c91cf9b026d84fe1879e93869bc46b4d41ab27233209cd08185639060aafb2b9b1395374cd32b0060f70b5022c16ed79a7200a4534e15952f18f9fda49c14e32b2c9f9c324e376101da3266aa6e088f131bd61b330e304ecd6bde0f37066e8a9c543380b04ca68b26f60beb6daf12f47df503e4a7e2ba63bd356beb5a67398c7903d21692a87b14fa9a78597a47682cd41c70a907809314d6167982b0f830ac40cc93db2a6ad620a0ba84a26b2959ce067368d5eee97bf142c93e5911f9d122f19c259943fc2c3ec0fdfdea46153842664eaa98881fab7969db481cbaaf675879a96d0451b85a4a99eb2eae92ab2599b22a23942715665b2e5fb3d0bd2390e285596943f3f677555372950d446f3d865006677db170016a6db635897f97f4f0be8143e2871c7963bf9b9f90a701a3d2221e1ee825d43a1ddaeaf09d9831b6167d7deaac53046d6f17f585a970566a2b489d2b1ffc74bae9720d611733054d34ff2d5b79db66e94708b9dd7729fcc882682a3c2d02cb9e66c7d22dce356dfaa719ad10bb6bdb723377bf0491e6e41a5855b899d6ac001e6f6fb045d7b16567aa055fc30ce9f261aa9450256c72893f084e0ec5ef16177475599551e136d0329d8611400550f1a4e0f9c0e1bd648d475a0d17a881b9ebb605989ec02b569d87450d5b292525383992e0a96b1a8736329d9fe4b1b0a38f3d05bd39486caf8828648c1b6f2ccfdc8350084048faf20ce8996ebeda9ff2bc78aab9b4fc620d901427a53573c4cecf17a2aa0cf283c2ee412f95c1ce3d23404172cc60bba15dd5e6351d8c98aa1f1c31836fb10c0840251bdae1fbbecfcf5b0449e265a053e07e2a06dbde6294081e7340b81ff0672720b93813d0b1a97327a0fdc4a3927e6e79b5a70b24a590508e19050b0443ffbed23b5c8c330c1d2b813ccdc556f5e401c3b7b093f412db87e035a23cfdd2d6a449ebcb388674869ac631d47ea7e6f5d0e9eb83e4541cf01935a48b9061bcb4029d770c70112ab2729e9950c213da5a72d2c38d4418f6853b8abfeaeb37154b24646db583df93f78cec7d1cc39e7ed901807f32f0fb3faa8656abf40baf2558adc1ae4d9a22afe627d9bcd8d6f9daf0c1a2ad3e286c9a6684b0942ede9112b4deb5e7481e4e91a9746f7d5195ed735b17ef8866dfee3006f2cdbf1232d36d353d0879cf0387897e4e5f8960dc6bd4729829e260fbc3170ba0de85a7e219bb73b13bfd82673b46276893e4080a880e4611032d220232b0bf4eb208b547b4be594c442a5b7e107ded31b6a57524d92a2029d73aac45bca7dbc436d503a72bfb8a95d8ec153660ac439bb88c5c43d98000a7ca6a3d638179a14fec06c00b8f6d71ec58fbf2c54120c0946994d3c27f2fada744726ba86f76f884084c597dd9e385016ce645b073d452358c04444fd372f0ed5870ef6a2c57a2d891f4e07c916e2c3718069ff72912633befe07084b24e620424b305e6b498033422efa115a3b41d7623f694cda47d4940bbec2900c26be428587e5bb6d4ef22dd3a661f29041abdf316204d1f94b2791e7db86f4e636d0a8df9b6edfb95fbbfffce12aa479e77235d7e2b0b227fbac3bdca6c02995df92f604d648a61012c1b28763f2238cbd8c08fab05b6d67db60c57c76f017bca15169c7fb531527ab28d217b9f589b599ac4b6ff0215eff4449178a8de61eb785eb83036a64d33820b1492dfc846190dd26d35c18ca95e874db11abf47bdd8abba601de6cbf3e53e6a4af0fa35a73431721d4228744ee5dcceb1f1494727105ce1b8586f5c8fcad416547609870692ae6b1d2b4b51f8261380e0d60d779697894bbb4e98f025102304238c4b181bdf675f90dfa5f434c3b80a0f6333c534dc8ac229f5f38262994cc975c94c418a87b0edf62c03628b4352dd320a1eaac460c7e3806810af78b0ce3aca455eccded7fbac9721aa9201bb34b377991134fe81f988a40c23d4e328b59a990625c6ac42f775135a4d81908a25e75059d7ab50a0d86d0ea4baf759447e6c3595c5b628cd79d09312046245cf8bd449fef62634fa0c2ca35b9902c490cb9b2fefc672955081aa1a53d6b62ff0e47506feb120d5ecb0c1ab8e781a51721ff5f1d69ca163296024f0b38c8e681a8965113e87ca18633a11d9d0a087cfb9274333565d447b3be88e57c356d15d1678d24a29f0805ff8436f4b58ffa4bc3cb81224f2a47e9f2ad8f2c02d48f8127073e2019bd5eda414469d251ca8c081a749fb8e135241275d409845ff114ddd50667952c6e55a0f5c29cd70446adb51f3c8ff7444b92bb64f4fa9ac667a4281263a0f7471dd8959684a205fe7e84ee2c954bc0d1cd50ff0b527abb80fd5c6576cefc95366c31e37f0716992e13720a5714fa64a594541c35de5cc432e96ca68a0dc73623bda4ec223b1ad63b1efa7be2525a750d776ac01791c12046fe569e52f6d7f9c20bb281479a407791e585bbc50fd464dcb8423a29e02c371b089f06e5f7ba014469ee90d2f58cee4d3d9648bad94f9ee8599d0da3841464aadd857d3aa6a4b2c5d15b7c0dc29e6c9cfc209b2bf1204edd43299040dc9fc62bcc2e52ae958d5c6a788b44fa1652997af1d38e0bed7dd8a886740081e35502f68f30b347b6e4083b5c17b5df59ae7e0082b0ee47adb967f27ca8ceb2af73eca166c093929a5bcee4101f8e925b7fb49ae6f483fdac24a18daa3d68e48a8db41e7b750ea0f871e6071de19e088ea4d93470e53093149b00ce72a31254669aab31af5678be056a751a8c33ecfc0ceba7ca04cede82c1413db4dea2aeced26b100ff4a04e2322a30c7067e96f7b3f8c9d3edad536de9543e41b4fddf032f219df6dcc9f111c27f28efbd0831c895c2260693a8c360f2afef33a564169e9e00c53a1581b01ab42cc261f6f325da0b9175e1b206fed2d36c10c46388609315dc66c1188e1e4432a79637601e84390da4dcff0254635e2a9e30a0970338ae1f3010eb17e0795192d5d4086200898f96f2c784014346e0672af21f03cd6d48d2c5a06a79a768dd3035bd8dac1ddb56c81fd9851b530c5e824a6ec9f88c765de6cf3bc3d7d634ec077aa85058e4910c63b3d3875cd2401d08fc1e0463f972d5a511543d607e29b5561da7fb8ef84b4e9f8717a22017119c66ccfac371d81688f50e82ae37a7d28afbd1cc3416f9da7bf2637b4b81e47bfd0a25fc18f4c8a54fa4f0b33085eb6fff38a75674b4c200fb72d6cb347eebbb1f89833ae820f0e5c48f479cf0eaf981214e2cb5d44b48bc14d25363faa1c06eb47af649a71496409bf947183027d654be6faefb824898ac8ba4f757ac7ab3188880c259c324cc4b1b20c33e4e25958c2aa7c1e18057d8558909a30398088d43515f7842e1324ce5abe4329a56912e92d42002353dca10ab7f1dd181fc10db1d911d1cce88ffdb766db5512a9b9f93aa68b9a27a9728bb4b0f12f921a8ba64072e23d555fb3de396ac643db1383d64a896e5f60bacd4b182065c8d38a4bbc80adf79eaba74a23355c5caab1db3f77c7c844b39e8ffb645f648e9cb5b037c5bb021d7d5dfbefbacffff56ae2f733155a995700ffcd42da1377367949ed18611f9e32a0de44d07d8342f132d317891e17921705b9f24dd80f6b78366977a842b65c76d6d3cd5e822457d97ceaf7c3fd61a15e215b2ce381b3671826395a9584e50555a57d89a8f5f31c2e8a10d990fcc8162e6665a929df2a2dfb2a88216220559f25802a3d07ea5cf24ffd07bd048fbe25ad28639ae97a6aa7e2ec0352324b9f8e62c1885a46397280e882b96037103c5ae90de7ecb34aae3dd44e23bd55f6a2d6761871e4fbc8598ce33133256c29aa0680b0da97b8701659e6c7da1a080efb56e4134274a137994551449e53eef3d5764785ccf16c57553364f115657dbd01b7f3a0b7e38bac23fb4140928f62e7b9b0a3bd6f8d9254e25ddf0c2c5ef738e967b53be3f6a206e00da99f3cf5e6e629a151f137b3313076e8042be5a86efb4a76079e211b3e5d91974d71031ccc9484171d7df841223497239757828875310976bb3c50edd5d4983d11a866b76e70d7fbd4c4647e676c763626dd7bb7babb50d0d757a4754e2a9d83f5432104e624f09522c09bd4225be7bae373e6919391e3847a568c4786ebe8a45b459a24fb2c8fffe3871e22aec9fa7132c93ce0474a27be3c623bc6c5cda1b212861e336a618741fa7b5695c6392d8f3b31b055e2ba26150f6148fc277510ca9f5bdf6b06bc0797523d800596dadef9df853d884609a50576cf571834692c6b5cfeb75927e8f34051de247408b0cdf94a9bab84f06dde8d3a5214e9d0fe24443c53dfa6ce97b93de5cdeaf93a753716b5d01f7f538bce444685171732d7d3c2e0925d3b1ceffa6e7a5c58434d3bec230f7d27d54151dd94c8dbf9f459db5e8141acefddaec98e7b62fd8df994d4c5d18dfb4e307108353379261103e9cddce4406ea81947cfc08bf919e73eff26832b0b6bab7d1b01da36c9c18ba39504e0349f9f5b7c3483cbd63c9347e9d83323897ae615fec0fa479de8b12261ca9eebdc00fcb477f6e83492fed0d046cd8c39255a87f8f00dfba658444ef1c8334028c3677700de3dff9dc3d42bf9398de21f73b81093d14ed954535696442a5b211973b29b4bba16b3ab317128bd751a35cc700d6d5dd2719d64f0d77465939fdb57f4d39be72256aa0efc8261634e2a2d5f79a8be95875278efc300413fbdef61500cc11f945005a2e9071cab945e4dbfba8295788f95bb21c8bbe2f824a08263c1378b42fb90c6fe7b78a053cb0406b61d2e03629d65c368b893fc2af45aa3bb9a441265c81cb708abaebab86a71710fee4f0c047b9c47836f5723b92f19151badc4d9ebdada454fc03d302f709d9c651d2a27332d04f7d8c53d03054c5689f5e188a1f48f0a32492cc747f4639ff5b0c5b4050e53b25adec97a656a2dbc09d9c061cfbb13a15835225cde69721c8061d91fd1a69e57047a5a43af0406a1cf7fe266c4c7a19acfb539b08f1a2d763428175023b4b388e54c02907323015e121a738e41a0b6c0d13a8be80363542beff216f0044d18151b87d813ef042c02eca9b23909d0c376333da377283bd831a8889adae01604fb7a28298ed3ab85d0a48a1b54b54ff509c5b4fccc250129d78abade1433914df88729866ea324ff4ca206ce24f083c9e24272a78b4ccdbc19c7a5c1b14a6a6794c0195a94a6ad133da5323dbee47cfdd951eaa790943c3ee34caba4050bf5a8166ecad1abe55de3b41d9908d286d6ea13f9c52765ee87569dcdd54d31eb40276093f294e09aba61bc2580f76529dde917ac93e4d74af07a1885f9a8c101d17462d1912f419a96e51239f0892c2fdc3fd48474992fbfac008245f8baa04b55886b8bad5bde4e091747576eadca63434467984e6da970802993766644c15a120fd686e07cd6e56a69b4340f402444060d5020d2978073764c8ee1c4d422bdb69ed7760868f72831120941363bfb15cb50d830cb9d97f78264c8a1bd856b0ec6ddaecbcf0fbc6180f5ec3e1ef4d9134120f329046c0d7bb5c6c4606c5fca5131d279adec726d64a1b82b198b2acfa92c13e9c278bc969e976425f6e7f6a5d1e011794d5cb64eca95ac3041ce8a5adb862dc69ad577d9ae6f84133445c0b72d71141294dbc7a093d6f8e45c985c597c4387dc7c08b292ce07a33be816777e163872b2e5c004a8a7d34731334b809b32cc937eee016f1e4cb5645b173bec992cc7725900f14ec540deb794cb0b9933c6d3e6d3652843977838cd6d7019ed0ff96a2e640a3725eca5f0a25ebe8263dfcd96faa4d3d112da9619cd192d006b9d09b895d06823e9e851254d0194a7ce7d858feb549a4dd24123a4e106229a80cdd7a4e605e35c3531de46e9d0efa53d1d022dea9df7f4137bc337d2ef33ceb5ed1f00dd530432cd034526b6ef76d420e38010ff8ca20a916d6feacbd72d932c3f508f7f4ebe634e697f1c3476d9b67ef3d1146f68f8e66177d8fd32f2aa1949391cc99c15ec6fbc2fdeaf380cfd0f1ef07353530faaf002158467a5ac4fb02908cc64f826ebfda6e95eb643d74e6ec36f192696658790042594e482ab660541d33feb2e568e59a8a13e886c2905b5012264c2b13f397abd107c2da6fe072b3be65b617b75c323f87231a3a00523829f7381eb3f034e0a1708baa16fd1e1c825d122d664f61e8f52ad1b62cfd9cdd8d9c526eccc5b79c6d614e14f2d9380c706896b604203ebb696a885de62f9ae86a687a68148b21f308d76f429b26132c8b5e935619d1a52e8fc738a607d6408dea2f4f88e770fcb1afa2ac33321545302a4916e027101471e6aa12da4117b880a1844f3a7dd4d772d4b5a117b3774cb5281a61bad54b34cf9c0008ad393e4bdc0d9e5dd9c816ccaefeac7bc02af361cc5a46212139b4b993fccade1a067e70323d391933f2d3cf6eedcc07499c31bd4df385f4939bd815bb6f330695b902229181f95593af21023f87554c8c4d96f859bd98e1f9702b50a545b896d382a8fac4cdc7c51ec5541f364f490a202510d755f9f4130490232f4fabd35dcf2871e69913e65394c380904f551f8cc126ee7d061f419d4349fcf18ac1490fd4ac92ef5beed0ab3362e8433b60fbaa6c49d8e27b05b1912fc3e008163e87c65dc8c95df9e07863ba33f9f9580ec0cd60bda5221c68c50fd7c49df0e7a9e9d5ac7dc523f7c902385b3802ed69129875835ff3b8a439e0f7a6d88f83cee0162b3f2cebc3513ddede88788f61ade6ed3b5c40bf8ca20bfefc2d5bb7f44c4f71a8a5c85300bc8d0034050907ede276b1d63cb46297aa5bae99f5e7d4a1e2499cb1d15c9ceff9f67ad3fbe4e8c62ff26ece7bc36cb9f64df9332ec088afd0c9180b432e37769facb5f167df4a75927b8c7574602c0232c30f3ffb545d52091ebb4009590b911adc55b00bc93bd20ae759f27638e4a4e9e8e174687b5f03ab2cca7db1718764477af596126d23df09aa03607ed7aa6d490fa5f7506b448b275ed1ad3fcb7932503081a0441cf612612376377a2161c6ae6e89e6e38d9652ec536d10cc8d31efda8210ed22653597e68150eedd6765fe1e79de7dca4053357f7228ca6d613a05c3e56229802867e6355994a8c186febbbc46018b6cdab6581706536581f79669d56756fc586847b695f30a17f1d26a6105ef901c7812168f5602d3807ac7729bc2f0ed1e1b89d00cad47d92f25217f2bbda63c7ebf9552e94f717e672d95dc680507117227046024511ad29af64906a5a3147d4ed653dbd56ea15d032e68dcaae6155867592383467b4bb727f9be1f5d88b6825b3ea152ea0a6a22d67c1de216d1b50f027db57363bfb86864e8c35da4f497e0162bcb1a00e57319ff86cd7c644266bb01ebf7a8fd9787c4ff64323396f521967ef421b2c51858f16250d01938e51c7f6a1d0d944e56ee7eea509f81ecd92f874d44541e4641c45f6f62b6bc4f8f67f5d20b553f5c616b2244d6a2241af69bc4df05e131be584f3a265cda93921339aca3850799ef593611000c0010d13bc887c27e3f15bdb48af553519d6c30792e07421f84b4e0595dd083363cbb8c5b4a77a8f630b6b1962371244fef8d4b1c3095a9e6734e3b96c10c7c7c90fab3a5eea730bd7e11c4f0e4e93e3418630abff1fb77d0e2138521d48796ad828e629b8b4048f07f24b025dc03a19aa26f21010acd43f08b1377e14598e35fb0df805bcaa1b498a35fc34cc6d9e0b823b691a3c17c8c5ac22f3a4272ab1c74f889f5b13535a5317c260a17638d5128c4939c9dbeb914ce133c91282d838ae760deecd2a47acf8eb0c8536a76913d5f8b3f026fb2a988ebbbc604747bd64c6df0930f76be5886577ebdf1aeb838e792b6fee72fe79f72e9416bd69b4062affdaa2895c6af831492e7f161be749930ecd5d519d9527c8287a63172e0ff85745cef61322ed4de51250f510803425223b96f6dd9e0b83b9f08dbd3cc1d450170d946b2a1ea86f77e7295a23d069817b69913ae0c22c528bb38d226d3497b6937ba6bb046c3fe02be1adda8dc6e79473354b5a15b2cd2a40c8bb99bd7149b68fc6e4d343b22b6a30bce3b8dd59a9d0f5874fc35de331e8ac7aeda733e6bbc57884a0b6cd4460efaa77cd00070f1db9560f50d9038d3bf575b7608b4f3489993461764910644904e68eb2ddd728812eef74357a30ef9550d1412cd7813929ae4f50f630f07228f58192bfa1efe6a47d5d235cb0287d96156d56585157d3cdf9ae569ab60cb4c2c07fbd20584be7bd5a1783493fc7ac9c7e94b0d3759037760bea03859da93ff7af5160419de73e0d2d5f5a79f623f6dfd6406d746ad6275cad5bb6ee4d364d0f5899b729a31c6136b648c7431ea671730c60225ea6370fedf73f539e58d8b431c87f01e1c191a3c790dc3d85cfda379810d0e14f830ce1c1ee9c1a5b65606455675b509d6ae133f1d3c564fa7b77a408c164086e53de4ab826e43c96dce9dea6841ac73181ec3a1ab470748c4923fbb4324ea5f82faf169b7301eccfd710de6c5584ef73b11a5f43bc9b10789fa3db91331a5526a0b70aca620eba285693973c9310d8f709712bf28c7b5e49ef327b40884618332f9f50be126f68c5b5ca8f91ef0b949f90f8e44027c8f48e4b0d499736612dd22a78f9d0770aec37b07ac086207c3358a8cf9e5d62b7db49d685ea0440961dbecd057f3854ed27d5cecadf1b77f9314ca44d392b5c92ab2b7d16a0ea653e31817325d3dc4975d92758c404e2c645ec06c149b885ca2ba9fbe591a6142a580b9784f951a79934369922a335d73be8f46ea9e2a85955974c645358a560dcf82fbf0552e81dad5aabc8c5a994dd4afeb1c7d3cc0b7bb17ad66b8503acb342bffe46a488413d283f0d58de4432cd37708292b62edb349302011c9c9f482b694bf08cd6bafaf1e28066abb12d1dcd164efde675663814850b600878823fa82bf3ecd507d1939cff8ba9d1f2afb4adc12ef62cb908e5038e99afa56e9c82de5bbaa5873b8aa1da016a06556a520a6ecaa7ccef080e3f4ef991a4161f665edfc1fba36030be67742019406369fe4b858cdc727c69408b8815f76527e26dbad1fcb0a3e64ebc04dd6758c8ffdc69f29cfb25d1fb111dc690a472d63281d8f016de2f03a9169c06c22b63e5bb04c03cff4ab2bb1e3fa70785c8b507276c5a3db4dec71679e3d4e56e43707e60924bdbed1775228da65c0cc9a93691ad74707d9a895a54e155284c1605b8c14adac1fd0349c6ae4f3a992b4a7046c88e027f415b21691338b3917de62c919d921063cd22161653b4a73e525e25835f5aa0a9e985289643f82f73a2465aaf6de0aeaf04613d37d4b6c82ec86b2b363464f0990d994f706701bc9a96c3f9a7c8a43ae1319382181eeaa5961fe94b42294bd012a33113c5630dcd5a40d397010663396edcc4ce2e4fc108031371a4f068ec3d1316836e7734a192bb37296ce4b63ee9071506bb7a4480a3503cef27f3eaad4159d842b7dba53f5832863a38f9ede7ed2a84922919b48e4d29699648c03ce03a3036dad03bdf793d28075c34418d18a6126094651d3883e9d92fc0927dee2cf18c5381bc3d04992734ef718350dfd59d2c4851f0a42155166a0038a49e7a4bcce490c53a934a574565a981da2fb297f62f9d15d197d8c22e97bf8e55a24a79fd2cb8f518a130ff1f27d796da5439c20c3f040fd7ceae7cf49ca52c2388c8bb916fde55a745d8b9e072f6e344dd0f2f042513f9d9a59cc15d77dc4529568863990bba248769214e74f30333a39e724fdf44e8acee529e79ce6d3e9a6299389a8205c9ee1e0490aef14c50c33a27005880f64b80285dca0ba1076c36e08a3c7fecd88e04e597e6ddbd0c60861841042f830fa676d5e4359ebc5b2827aa7942fc9a7b3b65d8074f9e564f51c5de37f511d238ca42923384d749a6e77943276b641cac8bd35b80f892593e3a82edb63b3d65aa9b773b23fd1676da48ab21587610449962f757e768b29a160ed16d3098e07e7aa32ca08b1d1faa0aa84655cf3e0aea1f1e2aa0b770d86b53713dfa5edd7e04e279ea7ac031c6084076ec665eaa9d218a040e5d019e7faca1a61224b4f2f96e95e363b2918c171966559cf25b59520cb4cbbaa6fe9d059b1c85a1ba9a26ceddc976aad8d24717d99d6d55cbc856aaa37cd69c29546cbbfe01b24be86e5317c63447adec57adaf55d8b324928ee395b582ef957f6d283697c26be859ddf30b3ed069623f6b9756a122523aac398715d1a7667709bd0299f465104231ff07d4c156de10ffb548947c0881a2bc1c89b0d0d1da4ee9b89b2f93e47113e4803ec7841efbd9dfb4e56bfd4a528e838a4a4dff92999385b3ded7b295ba76992a629c3615ccf4e8b2da864fad2258e81c2f2135b4fab5a591b969f31502a67ab8eb5d28e1124b3606965211a0bbb318ec83d5c5a2db6e822cba7b5462db60023cba7933ba73613649add702dfaf04ce3911de9baf7f25054a74eea71ed32a57b07e3b8fcc5386d69f5b4ea4cbde55db0f3998ac6359c96af629524d9e5496942aec9e4f8321aac924991bc21409af1facb18b75e335b62881545927025fcd577b99825b7734c126ebe4bae9b315580727f12b0c24c087cdd59143f7a2a5ffb35e31581f0bdf7207c317879c50b426ec765996ad040c33a079259a2b80ec7b2eebdf7567bebbd7f6dadd95bd6adf7de7befbb9dd6e6defb15bb5c59caa22caadaefe1f5de7baf45d55aabad2f59b855aed43b65fddb852259fe6d8002bae0849b99b933cbdbb95352f7de7b6dd4b528cf4befb93c14455916455154bdf7de29a92cd6a6f35787a5aa3a76be84ad6fc15d4333215c016447852fa0e4d09bc9b410dc29876c6416c5ed5b5b9e765824f6e930a96225cb97a8ec9854d1821830c814b6bd4296fe31a902a5ddcd9046a3d179afcb5225c9da964aa734eb945a6e4d8b46c3a269a120dc976912c5fac70817c37af0047532d4b9fc4cfb711cb5868d774fbb7a9b2bac97b8f316cbaf4e0027b7fea683259a75de2babaaaa6c2a5bbdc4d55f2c2bcf52ca7b5f94ea0bee9a1a9f18bd3c9d30dc3536700c7656870e89837570e716cca3522b69a75fd73b97742cdc997ab6d3c9b13c3cac0e0f654d55b0aac455b2363a2a1e15f5ee1e2e5159793c5f54654031b53f284d917a8003c57fa912b7fc64bdf52e4b9ef7bccbb49a18c687e7ce77de654aa3ca328e90270e86f3f2d4a5b2c0d00d0a233110aefde040f16b50e2f6788cc7a5e3136934dabdd5bd36eac49e677c99f8d31dc3ae86056f2ea7e68a928d32a5a483f29f84b10f5679be73e5a9aea52c100e14ad0d10af7a6ad5ebf9aabf5dfba28adac037462a988f817924be86c6d7c037462ef61fec91f81a978cfee05a7c28bd89f23cb167dad7599d8c070cbaaa6068483386e4fb725f321d9e2fc670027c26de50659b6be2a0e4f83f0061c92ba474bc06299e841e0f1eac475027b3f912f9eda8f6b7972155fd26dddfa6df68de61b3a3b2ab5cac97df3ccf925d4b762e2fff1b0dfc1b4cf6db0700bfd590f92de6371b35fcf6104238c4f439b8007c247dc4f0a387b17300b0cbb48338907706b4124d89522417f38994332da149ea110b0545a462e2d6897b09d7de7710d7266e209e3a3109ae3a310858eac41b10c2a54e0cc48f973ab10e34eac43d60eac4a11a75622da64e9c558963aaa811763900b8730dd89198988822b01c9f88226e9e4f04fc22668e6c64679d0536acdff88d1962ca1063fb8a0c6e31d430a386ed32de030077950f183eb6a964b8b900939ded2d38d06b30c0c8ef316e2cd0e88286ed2851f2fbc7bdc5cb145e6c43796f03b7130c0bcc7693f731b8ab70a1c2c5f614ef6be06e420b135a6c2b79ffc19d041624b0d84602837b089791cb7691220d04cf0f3cb69f78c1bd03ab09cbf6902136e8d4a0639b062eb893e81838d06b212db891a8b2b3cd0207b27dd33729a0b2b328a0ec092e2c029b9d0d8103bd223cf803353beb816a3b404503343b9b01077a18e8600b385b01077a415c0c810738d0fba1c20c7076010ef47a68e243825e02dc140770d6000ef478f0c01165676f70a077e3c6009c0539d0a3a1c9ef21aec1d2f0ac8c4c8c67676b38d0fb38d0fb4f8b03bd7f6bc382b9f6b22c28a61ce83dcdeac4170075624ce5ba26644091375722bf7739da83535c7b508a033df89688b299e4cdd8a8c2ddde4d7ebf4520f9fdbb711c41844c2baf0ac4a1b1e3bbc8e9f770d86e890eed431e7ad11d0a9f797f5f8e06127a39847833ef312983523a7be288bb392805b0c2dd1c14201073708a1cbd92f9423c0c930922f77b04ddbb8f7c41dff994ddefb2339f13c3dc0be0c5f5df6a14efc1f71c86cd39a38826ea4784f79ebf0d7cdf4f3c0149764e9c909305909d13270cc99f2892f9a8fd5907fc0a6c58799ff9b413576658e6f88a7cb8e0c2bfceefcc1d724218c29085912b0d3072869472527ae7bd55555555ce9526785575554929499214a78d61f2aa8a6acada5818fbd44a145b41c141900c850932d43c33cdb597a9feca59e7add533af099f8d6423512ca54facd00a2a2e39a8d58792f92e10285de458216409eeee772283524aa935a9457b5a56f69d0eb528a594d2773ba9f4167619b32aacb5d6dba16cad9665599618921861586fbd1406289884814896b27c99ce5b5fab7d4ad1a94eb5d28eacd3e599b24a6bb5d65254b5d65a2f4952ad9645ab4ea762a2e4d30325b8ac5cfb2571aeb753067b199f894f9b8c8fdbe13c46f1d2aafaeab3700208f4c8bc90a87a5e8a9556b6fa9a1d1655ac746c2543869580152ecd2e0b1f4cc9b28af7ba35bb2c7c4046964f29e74e6d21a0acb76cf5b34ecbd3e978ac96ca62ab9f2d6e55939492a2b00e13af91c4bbb5ba86047f4d508749f71e7defbde7af52fa6468b4d28c514f939da6a7f8d5f7dea3f451fcea7bd04ed28c317ab5b6cb60cd0bf4610c0689b93f2c8c8091e5a3596634aeb90c0f5edce93b76e6bdbc2955df8b9e925414fdd6d17b929c334acfa515e37bd21427854f6da811f1e1bf175f8cf661ec24cd2763f4f4a38f64ac3166118c1e0f7d4a298d74488c117c7e84db022532b516a186943421c22b514513182560aefd7376073fc2afcc08741c47a0fd3c58e1de2608c9ce09138464ff1cd93951028505db27e438b6fbd99f87dbf12e66843a1fae832ff6d38ea2c718a38c31562179abb25b1f2f39c6986d23c83ec66b2b1f46cf6201d4d0ae5666d7811cfbed5e51dcd74fb578365256eeb22ab7ab8ba34e2746093b9d8b5dad52d62caa526fad34aa72da58a7ecd0db308ae41487e4cd0632a0a0e2baf5721cb0deabdec7b4b81bc4ea05e7184008e1783ccfe389a2f86cf51d793cd7cabf41135a01cd14a87033852daedca009d1581e4fe7a5ef589d7a51b7aaf0bd990ab4abb2224ade10b0c405064e5caec4bd17f3dc6ba9c5945afac4b8c9540c19644aefd5f2b4d22e8d76032107ba3e178b4172b138a4fbdbed08515422efc7a113df638c1146f1c1c72e538943bd84631cc87fa29e62ff644149cf1f1c6b657270b70b53c9f07d92dcedca7e61fdb26514bdf72484d154230c062e9abe8e6f3bea6f081dcb0db22b208d1fbd896e519a1d5f04b303e66d6d1a46fd6c7f846de09df3c2771b1fe2982beeebdc79023de3af85ecbfe9f8427609389003e14051903888205c732a40b8e69fe4fef801733bde4758688106fecf9f944d256fe8fc1a031554903416ed72b41c1c38a221647fcd9f2688c6217a7f0b507193a7f79cfbb71a2df537cafe166da6bd197fcf36cd256fb36d1a10e4ead038ccf7a71eb919e9adf4c9d26f08c80e925ee27636481fe1e76c6867c3f4df1c885ebe0e0be83c653f7aa072a38c88cf524e94c300f210ee0c66c833872da3d234a7aca3b9835be25966a1ce3172ffc1060b777339394a1059871ea4c809b94f2e93e052e42ac277d4351ad7ac73ee448a1cf71b5a7cea30e6fef973e7ceb1e9ee0effbdf71ecc28e0c494b6c1e51e2e06f5aff19e93fd89e552a6646f2bd9b1cfd1c3bb4894e9577e7c9c46ccbb8df766c9b6e9b1b2ed3ddfc936cdeaaab3cc6563afbd6c0bb95ef272fcf73f222fc76773469f0c3f4cb6cd7f1ad976ff25eb25d9633873443ec3dcb71427d2ee5db26d3af72cd986b9bfb2ed3dd9a659d916b292dd775acacdb6e988508e63aceb765f7b0be5a9dd4bddb26347b05f7f0de72c90fcf14aa42e911f84f08903c1fa98c8d04a1dc3e5784cbc24eeb920c377ee880c7d0c1184ce058459cde69437f3e69127e5b97872e4c894fcfe31f136ecc523f366069940e694fc7cf8f88444241ea136aa70b7f8844484878e4f44281c4791ba44744148a33c7a24c0ede8d9df35753e9df33bceefe1351d70edc51bae6d0003376ef478dd3774f07056a2245b03c90e049e43078d77df349884388e193be03822ea37f785d5b1392eb00b381c7a7821dc0e79b1b4b8bce7e5ddd3e8e8e8a17168246dc3d55121b1953adb564669f2d1c4ed24d04da7c18f70751afc268224fe3b9271e7bccbed955d846b2f58f4b0d317ee9aa8053f16d2b410017cf0f45b1dcafda3bbbbf2a981388e9b0e020277c61429ef85deccfb612fe6de83bb89dfd039ae35911fd38c624f118332a628e3e2aeb170bb99fe0e86f161ecdb35302b0263f77d5b9c7f33ef0bd0c5dd5c193f1cc8df62579305112aeee18c387273f44da47b44dddd112c82042778325d9e419dcc36ade4f7f48c3c3b4a4b79bee4e588725e8e9993f3e409175c489132c5a7e46d4620707b4be407c1f090f0a8344d5a4745e81009000010002316000018100c8582c1503820184bab2a1f14001174943a66449aca43a220457110444118638c210400028021001864083373ba01195553a057c6bb72809a62654f876000dbda6090171c9dc6590fe73fa1d80b08909861deafcd2b61b9d8582d317a680411b76db0c7b85876b4600a24943a51d99265b039eb84d453d9af8d776573b652a8cebd8aad8c46337a682a5f6ac03b1fd7a2995b59efe0826076b9955f112001b9d5b7e61f9d3269e1ccb797a7f528859e583dc8844af7e73fcfdf35cf53658b4694902712e8a817ecc9a1ec4c1c99165613e5f364439de56c7d82757357c7a4086628f1e19783d5603666a68a904d60a05fb20ef3030f21621029b5c88beb8439234e828cfd598209e4771040c3f66b1c2b32414f9e5b7c9b090eda473aba1b70a38273274b7dfd74238ae594f16af7202aa3e5e3518a03da28de82a810e762bfd6b735b315b6f34589cae0fa463a73363d7089f50dd6128f484cbd350d522f10d21da76dd83b5b2599102e462a97cfe64f503cc15f5b4abd945049b9c2d54d565b415e0e72d5b046d468cf6140551037afba52dd3e54bb319fa54cc3592365740cb1f7c5d4d89be2c2849b8e964d2d683649f6231516a14dc1d3ed3b8b350930ee0c2a94d2fa4a1dd9b77ba92454a923c00f25aa03535d04a19c0dae011ea0230246ac8fb883d53af4aabac0237cbb244f8d241653493ffa9d733087e378d7d1ef0e93d753b31c3ad9fda35728638be00d510aaf51365ca46eb1788b6cc674a05222c027b3f2db9c19ef1016990cce299fed8b76827cd2714cd32b4200a4cd8694871ef6499a72673266fbf2692c7640517546af04de322ab26a6a561ada7e8b367b2cdede4a8e5fed084c214512a7ce589d398053f09535c5f62069d61aa6720833a398af5ecca0e6330ef93c5e1d91faa05d6ed5c7434090195159e5b718571ad3f3850966972f2eee549f5a6eecc31471bb9bc259c870422da7a911fdc72c84fd05bf42a9aff0f5c15c7957b5436da5ded7d2ef2ac1319173c62e44d2a163cad66a1eb393999459b807fa056be28e7344cec2278906abc91e7a26627caf1b27da2a56aa011411d94fae256a84da0700cd38e8ca99649616993061e56bfc13f07bde6f862ec87bbd0c888d3acc955938685f27a31ed0cfa697faedc8a0b78a41e0e2dbd06de5106d7b7a42db1e4d9c77d05517a4e868591e81dd64722bf0675dd73f5dceceba98d106ea0b0e72e39a0c30cea34ff61300b8ea0c938bd3b271b1666ef2082f25eb7abf8774a4873a0cdfcd5ec5e444a6e7527b908f3b488f352478b0e87a32748f68b54c481c8624bbcaa5730c288ca5305d48fe7d19730550f66e1aeca769fc1d422698392574c7dc171c5786b5e468b3c1f43bc6668a72200bb62cc68bee19bdcbe42f4d6fd65c83530c0ad8a94328986ecc818cc3b9f90f8307871d2a453e111db5bb031620f981ed5184ea38b1a2b6b8be07069d6d28014364c11ae499d9eb60b9af63f2c08ccecc9efed8ebca78b2989c8239b0a6de20d7c27a161022c4058a326dfc9cd9a32f46ac49e22d745775d6dbf201dc70a2fcfea30e454c5edd396bd9cc99a3a745732029c5b30879c1a94fb04f3b993454fc321286f6de2bf3edf7d138542a29c50dd9598b22c7783390ea4015d73e2af59f4b5d8ce0d36309c11b09d1e3f482c983b02b7cec34d7fcffa35759407b7ae21f1ff5cdc1b04f46f5ddceafdf09b8f9a98104388e72ad12e92e8729ca9998eb3439f6b4ae817083bd1b241112609d75c2b96233d42f76adf547273347a9587d229b5bc038e8e5fb3a87005fed7a2acdd445ba9d97faa7d505170768afa90a3a871efafb5b98d665c2dbd2d5f063d32414e3c789b7fc305374e44431a8fc4c28e53106390f07a05bb203b93bf667ac29b1dae5532981288e509ec8d3c8393f5a5bb0684c45fe00daf5006dd4f2468cf830b64c030b9b4e9e6d36eabb59885c711e1ee18e3e591025726aa3f574055928b6473759e0b5d6230e489d468678754d1d65daa845b7302cb0aa403191516953689330bdb94b42319c4ebb6dc6d132f4860aea29dc61c1902cee75a28528de14b09261c417622836d89f4c4231c321be12c56a76d7981bc92271bc6b48d5e2192b66f7517f9c5f7a2754c069c5a479dea0fd08a7106a9dffc41a8ac5386f5d56734405d5b0400f338f68346824146b35a0612a3c90f426e5ed36987d36fc56938b82ff458e73ff4c902395c29867173ecfb6eb34b7c1c157b90a0e18c7b585f57e584f9819e42000c1d50a009182eb380f2ff25bc759c1b6256edfd9f2d0894823a1d83a9d3999770d1060750b96d5d2d81dbcbcdeba5980c8791d67a5dd260cf72035ee49a7697b3abae82ff4400dea38f9e1c58c3c3e08a9fac6492826d568d5c38da8b7849b47a3240bd7661e8feb6f723a556227c74df183629c5d25a138a4d93661c03c9e69520ce33690507c822e33ce5d8ed7c54694b98f3c149f6312b539ecb99b6039ef3e6d2d5ae10ddff480de2d055f95e7517168e68a99224ba024df659eb9e97c7a55c8cec7e0cb69bcb113a16f72dff4820379263fc4f5f3bdd2eb78cd5fd18a4de400742b625a0e4cebac5978618320e2e4aaa84fde55036f6d0995b67fdd5535528be19f387d94e4d162cdcdf9120346d90d6990b9ffa175e0332e81daa1af04a3630a8610c4059ed0a2d2b09239b54a063229d88896b69b9a3e1f72669028a3245fa58079b2609fa20380252d86756425f7652ea6e04b21e1395a0989f1926547dedca29eb1afa2e2d70f93b486a217c37d3f4411f6194e4cf84a0c243ad35244aa1bc5201523b06b9fcf6dd0b471ec6a5eee56846ee5a25805d4660261454fc550009a21fffa5c39f180bf53144fca0a802454f646d066bb51d88fa320be17ed73c2046c51cc4ac1b9b3a57ac1908f06110ef49b5ec6300c491e3fc0b61468f6eef4c3f06fd45a1884f5d75444413a0082b58d5cd9da8fd2c68b2cea5807156876369cf174e94882dce0d2df6851d42024ff60cd94907564bcea4cf4c0e422b2c9f8f48517d24adc7588d993f6f6425d825a1e94f1263ac891259cdb3c282e04e42c1f888484e8e72a4cb55f6e2e2897112b200d2f7b46dc69ea9be5fbc7fda826279fa34c234887b61645b17213d5aa08b322d8d4ae175f2d7401f37b8222e573336f674ec8935fbc2b8ed3b0601c1e62fd1717b92943e13f8d59552794342f75485029aa2acf8a82ea5ba845aedaafda0b85560353d295bbd8091ecddd8066275907554b7be3eca33471fc2630342b06412a08bc4be0baa72ad0c8961696d09aac8146c7f7a1c92c1728a19bc16daa5d44a535fc30f41b38b6391750645a780bfce9581299e952818d3b9f01cc40e814d3ce5f23ce0082f80efcce45fa09b4a06caaa66d1914645b6198517a9a07bd72855ea06d421a8041334ca41f297b384e53158784ae59e1959735231921428894d69399ccc8d0824a1c4e244888f6e8b5581049b5d6149e7b36b9c0161ba7188b24d9c527b3d1907d7cff58aefc410cc93b08d094239c9b47038d31bb0fb6a58d74c9b822fd9f3faa6842707fe687c3b237d68276033376900d6091e95c3aa2d2f6aacfbdd0b350dc9f6b9e1b1894a72c483ef593af6cdb8c8e30f564af9d1ce2dd3e602d7289c673483d98fbfd9a2bb037d04b902bf04ead9bc56bf1f9abc2656aeb2278b09043054681ccf1976ac21050a5ab4a46f063e0c52bb2c9ba0751fd40e810a57459fc7360416b1470acb006d8d5f84482f90b47c6a756c359a99f1a62237d21df2ecb0313c371769a20bb1379697e99f46aae79094e4769d6adea8a4ac5298735ab8826b45f0af912e18309deced4da0b4aa9edaa5659a6b0e3b5399c84b060bd4c201a9081c2bf45289fca904493cbe6574421b9db50e9889e0fcf7b17b7cb163c0db23e17bea4cc5cf8aec7889e89b4893285fff99911019763b5d3eed1c590f97ed58e6035010e8cdd766b620d6b0e1ba1ac35d0714a78628a9e8417b61915385620721d891e464bb599226770a25231e46f5bce596a6cae768189db7159704512dc3a0677462a59b11935ed02e9fd54bd2547fe22fa942800eaae1a75cd01eee26a320af4e1dd646b392b99b92eea273cee48770fd519550ab1ad734608f1271220c7722cb4cae1ef222a1e43e60df8ede69d5569d4fe3f8d976974f91f34e737d4e31b785114453db615bd3248c2536fd447caeb608f123a3356bd593bd0cd1af0062806cba2dbe9390afd6a2fc2ebea2fbc7c6f0f63dec34c61f12bd8b61038bceb7f173e8e6d815f80db5c7dccb059c1180f758c7bec931e569ab02d17a83e4599483466c80292a26535039cf1b929a1b0d8c4bd96a3dd68b1132335e1cb3402ae1d080b1d044da66ae86bec84f3e38587e58b9c2ac664a2084218ee6647253a41116fb2fe6cdeee1451a909f37ce82341e54498b38670176689a02492642dae3d37277b77e9f924013d228b0a93d063c7e7b958aa16582795a7c5a909ada79bc4203173f2b3b97c6d5811c6cde9033e33e8ad3d9e82772c18e683d6a37156ef042abd1f6ee7bca9da32684c282893819a2d98e29784437c3dd871daa2813cb6b9dd3605d722d090e976e75520dd3442341a9455610617bb0afac747486505fa505c51de53836bfc036438e53c229eee9f7db7da459caca504ab3aebecaac4f7d51cc6cabaf92f0aa96d28c3e672960204a771d330e0a7b240db28b18057a7f7b959b2acc11b19a6e0cb30678508b03da3cda2e2678a6a0b66c2d35050904e2fe423b3b684a2c605405d9491b132564951a25e2a01b1931f85cec792f586d4f412e9e398e76fc9fe9da87596cce0d4c5aa7cc61b4371030611123f1636cf2c3661f3c5c108ae2e2348814154c158bf41628b3d3e0039b60fae80115daca4398a780d1f6c5661cc85efb0a01b917f1e3c4dc07a13694a48d86b799e7077d91031996da32c9c942611e102784b098d8b58b28dea9e43d195d34af01feb6386e53aa0f01c0e797d4ccafd52df8ddf0758dd0b307e07a6b16f90fc338c03cd3e25eddfd920cc5db22555223f2437a4a334310800b0be32182823d55410edde3caf7ba7695be3eba8080843bfc3500e37f290da0e71a0e9c175467102a99adbf7d9af3b24cd276282fa8aa3fca401a00889a6b1d1c20ae446752d7dad991b5d2bb0fa919acbd1edeb9da35ac86b03b2724f39fdd1dc9cc082b048cf497110cee441036a84ca5c0396b468b40e8cf9d4b8a88760cf1eedaa09910d48b19b65fc2126b33cdeac9af50fb68198eef555722da9753cc91759e3a09027b8de5fc8772b3e1d8cb1fc805db0c329a44b6e637b02724eb58a27d412f86f0bf3ae67a83bf3b13f599ba77358013f117a7810227ea9282663761e6aa906560dc614be3be7fd179f70f5231964d1d3c7e8f6a15925737445eeef9a4b153c059e3c27577c4eb7e9ad7798db23f37ffe2d57bfde1becf7107add8787c3fdc547299be4bde6bac5599c790020bc3907b13764b71229d1ccb4dab5cc4bae9b1d2eb258f468953c4bcf02d61ddc23c8bee365c5114ba4a97dd4877d7218c9b473e6517c0e7195855353112e1deb8605c967e32f562351da065a606d52ebc15f3334e34f931f618a3173d1e8601b71a83856b6a20888668f516041c52ebb47d3c105e0700f8813b914731b2a17dddfa3a57764a32cd8414c4b641ea8b4c888693af3c1b436f4d6afa3cf5837eb248a6924588370ac199eee32c12387d8a978d381ba322872549b1ac105b7c513a0d679b45526d7719336034e84e11e870117494dfc9063e6f149784caef3924f86810d8393773b263da9e11f4ac93899246dc2e746d3efdb0777fc6dba408a15ee33f7c1a1748650e2918312249c2f7e73b92079ee2836ff28d4d83039f2c17246fbb0a166dc71e218d9ce4acc640b3e24794901b68c2b6c5282a93ccba7e4c74e574acff26137ccddc7a372758242a44a53ce60941122985c9be1cfd1e9d92682b67b3419995c7f2b2a4d3941453bed23469bc43b43ed95d7fd76d223eacb4b316f69ade291dcf4e96a285853a0b5e2a1a7f23d05ae2465cf7108a584d28510408c97e4cec739f74c06bbd952ebdab2462ae043ad8434c13681330068257ab487ae3e6cdadbd62a1383c6a8efed2be5a6b84ccee43b3aad35661b66754518d111f86b1da5ff9e87c347b4a243fac287a0d0ca26a947b7ba5f3a2ce5c960401077bcb2954646e998c7bf87e71f1d6cb08198b601a5ba3aef6a40f63067e05fba47457ca0a577e6ed41a7fc440f8dc4dc81145482c0a1977946a80b0b1922529d988e767db45c950b97dbd145099017c6e07b38f53ee59514c369ab2923190d90e1c267637c851fad8ee36e1433f8cac9d32dbbfa2874b1ec22a8185ec8e1715e8bde65f1b5c65907bb11a50237f087bb4361e97828761cc71cacc3e48ee082740a7b8c39924cf9edd5bc273be4fbafbac05e21e6a91927af806fbf8cc843a6ee45a6000a7ea0cb7b80e1c587fbe3d9f6341fe5ecdcabf6c7a93dfd2a49b869ab76ae9091436fb4be0c86ec6605a4fedfde60855488372408274f934a2c063870ce4d0ac3186e7cc57b4b30b8819bb31b51d5bceb6e486c523fcb7f14bdf29929629b1495cf008340e30a7a96e3640e9aa9c8d94d914d58c18879e0f9ef6b6c6c454dd24cb36c5e68c57041aff8550e96f72bd8799ef758bfaf9002dd62adc5ad5a0572c6e46fa79b9bbb9f4455bc75d82b580068b486a08e3742f5dfc3f92ea1b83df2316344d0c218fdddc6640a052021f6aad822312d7638e40b173f52ed1db58527f0560db5745de42da521fd4513052288c1bc050af075205ec14ec254df28cf38a9eeef4b6908fde0765f19ec6b125826be09e5531a2a3a1e74ebec714b6665a4fcd3a1346409c5decc0a7f61f1a7cee77a05fbe88470560517defba2128c5dc1d25364b1033d12a62ed48f916b32d73c10de529720e46e251ba212b24ea508e75d75f7adbfc7aed564c21bef3885fb6fed3526b72a089e80f08f3cc745015f22fab41398da4498735f810f6f0093754f419fa9ed501a7a8da10d448ad3e327b7b0a37a77bc4e47b079058bce8cb47e8581276ed73fb4c745dc5187e5ac4bb35ee0c0941dabd2102e04be73b2a2f6af60671cb33f20b38183bd824522dea4970cc5b81d73d3f19f7c1e0c3526787216ad05e45e79968a04ccd2ba0731b3cdd59e214b657669c71f22d5ad5b844dea1e6caae90530bf4c19edd55b295d172671f561b0531edd76f1b7942401fe83d943459935407c483edee18ebb57b0463e16aabdaef740bc82350d845b3b69add0ad405367df7955f365eeda6fde6daf34b46e4cf5b21ae5cb229051aa02d69d198b8492be45ae27aec517f77bbfdf62a387667b25f406833b0056ed637400bd1e4fc0e9e6ca686531a2046c4ca6e9232e9da7cc98dc27ccc63ae845a1e65ec0eb26885034f77c08ba8dacd381406d3cb79249fe075653e4491743f149202c90eb99a97513f6347d1a6177ce61725442222f9b82c29f540d14df557b74309231d3add8f3b85b1f9b87064ab5ee86acd30166b37d59d39c0384dec00647f7e1a4a0745b159d3993db1a98405b2e77f3d111365b98a774250c0fbc43f029ddfadb582dc39ca96ef1f1889833de38cebaaef92aa79e08f62dc32dd876aceed01adf9fc122ae31ab0ecf52008a1584140ce4efd468e9c2d4b8b20a8429ee537024b2edb2522fbd899cb41f0750af0607ac5e4109099855f9e456953dd8a6d9a98f60fb4aeeff622256ad7b36484b108f38f674440ec0832e7dca0b6a806cc19304227b84bb167eb736c0b398dc2b19d83d31a5cf0afcc54ea5fcc39a9848a42045ca5245ae011315d799b1728ed01b62d9f6e33d12ac2d89477231e80d8c282fa466e4a6b6b559e91bbb89d47959156e33dbe039dad6d1882a2b03680df108fe243b91bcac9c31ae49fec2a520a25460d6b39fec39e533581b1859b74708b4fd42b91d4b87e297233662b5d94b9af3ff4e7fcff853a312e1db0a03b5ad1d4fcfa969acd5043d50622695da188ad7a035e6b72b6136bbb33a74236c4a56d92899364801b48565c270a9f76d6ad29a46d89bbb6986dc08195a0357d59b38b8b12c6ae12e6d584456ff55428d10a46d5cdcc8f79b1bff4029ece2706527607520c46b8736474755632560e9eea6895298b62bbffd6de9734e6b7f2300338558de4f9dd38a8f5581d20666588100a0f6f38e7e027ba9c86579a700308bf2f35815dc3e7153ed52bbf46a8591d2ffe6c2f08c4ae0981d90d51310413f2b2788584de951cb4ba000ec3b8442dfcb1611b474d60753bfa924a725718237fb703edd5df8959613337c9d134994461dbfcbb295ae8854754702e26cd35b40103f3e4ec2396bf557b5917b5437e21bc6c792ddbe7ea5b525d7ccd43f655571f938f06548fe8c46792e6de8c71e445f220106894fb3f44cb36bf79d84ae314b53ef1c244b0b5a58f0af30eda52e73698663f76e9058e69ef90c7bbc752e7b70c607945f6aaad2d3d3208345f4a620c201dc42f7fc9ed95891c8f0156c0e8d50086f34929d4aaa0ff6f249b22f0d1aa1713421f163c8ff989891cb46fafd6234f67fd0c2de004d9a5ae4c043e333bf19cc8cf7b63237a54f58b682b52b0184f0324365b7b946bdb3e4b0c1cb21c619a46e88bcc724acd3b6cf0cbc0eaa015feb51317ce7d6c69c13a6ecdf75330d587dce6679cb69c79ab1481af14dcb9801813a726ccc0880c317913ef7dc36ba8794758505317f564f938933d527d66b3c8e1299b3886e5dfb85c854bb0909615b5545497fdbf4f062996ddd4fe192952ee8b5d893faccee6b0b5490c1cb80176547fe988d3ae32c1779b17221085c732039d58d247c8df001559ca5bdfd561e3220a3751b1e71b5e3d779f7d1c51edb7c3b8147862450bf7c35112fd8fd157f496be2acd57660b1f48ea996e52a1a4a989cc3edf94ccd1327af3bf9841bb497484f14993c807550ca87dbb1f835429bc0572c0f8bd3c2d37de49923579a489080c67a743b57f778fd33b050d8cbe1cff84dd421c3c8c0bb0f2b0415aeda747216f658f6f4f5ae6d1170f8cfe571cae17f08ee95286c007e7b2cff763c5cc9ceaf45bede9eaff6fc67ed5aff9234630ccdbd11b0f38e0d2f75ca1621098d00841bd59374cc6dec634469852295d79e54040c275f811633ffd4f1c580c4d3a53718d9e6f6c97da43f9ca65fac87f2cf17d6fd8fb7941eaa0f47fb1863efa193ddc54ca8ffde216b54939b994fab5627c318b36287d19c52cea9804b8475aca27cb01e67257d04d34526e58c5bede16b5fc43ab5fa5d57244b2c3ec5f46336631d803c0df79cd6970f3d3c9d4fe144a150e4a0b8d7e1e65ebf56b80d34aafe2055be503c58a454f0145522160e9d880e19fd1043844ac045c8d72a60de18297f12616099fece61013a9e7bd10e52c49c1a2fc0544c0352fde70205e4340f79c1fe7c414377edae696cddec7b2f76fd7e9acc1f5e793feb073d3c44297f5141d86fdc6092b23517dc05ac6453dc99e253edd42d394fa1c8218a8100a53e8125484b57645b070826f66f57f8c08e4d75723528451cca9f04c0de72045df123e21b824b7d075297239c0fc36089e813c33362eac38f8801ec6a6dfa6b72d7551aab678d9b06a96781fd3b6b992b3d5e660ab670cd39de80d3bb5a1212157f61f470bbd65ef88ecd4dda727701eed42577ca9c00bb1870fa6dbc67820164d1e5fa3b1a0805669582c136ac584672bc0d32c739c6e78d269463606f86c385dbf2cb7c0fd7a795fc0496d4ecda93f31c65a6067fea985eefcb7a350adbadd6d594b214b384492434dd9f878004310cd4760853cb330d9f8dfc4d3e244fec9b7c1180741dfb9f21c25c18c06d7eb184a7015b8974f99a4927fc2ab1bebd33675f278efd96767855e6a48306547d5b98c716604d6e9d5c5653a511c97d4957a4b944490742d5212662f14e332862705405a41396015831110a087f1abadc4b4ac16b0440d7d2a26a4d132ffe3665620e660a4804ef0914e840349f586990d0d7619d2b0ece56c346da7822d6edc50fb9c17fea547ededa6ff023d7f3082216b251d2bb55cf09cc00eb04aed813286bf98bb90681bb74fd8fe6ff86e967551bc1010291cd4e8f05ed59c0fe7edd997d0be18e4cf78af704e64a64f95391401b2c90e31cedf154a439d4b6f5e27aba8056b33fedc46b8a885e1180c39380f8e866610c70ba9d2735e41e8fe61dd7cc6eb9d56d9248b7f669bd16a7f81d745bb6cdf02b94442aeafa82a4812c81452132c56576bddee94e8c3b7c7c57a7976a25628a539d2a45bbff9449ed4121f1773f64d13b96270164dbfd4f2220c5ceb0ae531220185dd66f83b1f5c74fce1c9e54804ce007d30c20c63fe71d97c8b897bfcd50d789a70466cefe6a6fa8d8872e4f8287948e21f5e21e854e5101fd4d360d9ee30953a35e8ab43ac52c9c12d5a2e00a1f01549d17a2a82cf1ad88783a26e4afbb00abaee7fdf4f7ccba729c6355ae9b3430006e6d3581c3a981beacd4f069adf78770801cce00ea14914767c05d29df6bb5bce0c1c57b4e7fb2b701c90e3458b94cb97fba27169df13af8ede1899943ed92ecc097b4a26e6feb31fe1418f06d2d3527e45d25a31837b4dd9f901159470a1d8458e9fd09634345944b3862c0eb7bf265e747d20c6ac117118844aa149de40d93e83bf4116206959efb045fdcce3c5b5059f90fbf037a72e6dd826b71cfbd83aea37ed6f9eb07e3a462f86d92ca5cd49eb1d7d8ba8a459f4a5678daf6a78e24e6e5896631737ac1a36d06c3677d07878ddf3f2572f08a36908109f7c5e046e4b321d2f2cac297bf81c1b8d56e6e62e04cbb43d4e222bc72f401e4acf57732caab63820ac6348f714f132aeb85d7eb69d043dadd499896f7454b5cb8263e48908126dbe02bc6215c379247c1b192b5c52c012cd451bc22be8bdf2869c2c7d449a287249a96fa336426a36c39fdd2e7fc7de68791eef9ea81b1608f5ff3028ea020f4392bd27d1565c84d28a42afc07fc3b6ec127ce3d45269ab0a85dc7bc4de760141ebc2caaa974520d4952a7fa994aab4f8c860d1147932829ac563584df1c1e09c4260ca5075e3e606a25ea7856f2a8d19b692dc7de8ad521647e41880ef3f573b844356ffd5d9c027d3c255b085cd284f882b820135662d883367ea0cc1b9aa1029bdb8e8db83df216bd837c65760ba78d50debdf9f0d60fc48e4db71877db04938a1b9972f1d76f87988e4c8625f57b03d2192482ca412803ec7eced6dc5e6af35abc42bd99c0df0987c505dbda15e4e299d74dce1196d0926252863be49d7e04b7f2a41f09a23dd0066c442163883ae9d09b6789ad1fec35a5b27fb7ba6953ee60bfcb52e787065ee0b70b853db9ece8e3bbbd5150504c855c7220ac2cbc547a70b9c7f41d0e530ddae1d172801cf1778a803cf30406360a11304014cceb047d4b3c8722e2e3c9e462b3a156c4169349f9604011f5244cf09e8846682ebf2292e057810ab9ea915aa29cf80a1c4ee1cd3a2211808c85f0700ee5962941d81c46cb13d75f1ade924ea99715c505acbf4f0bf0304fc9dbce0c66c342f73f12cf00f7a718e45caf216038996cf8a41937d6434b0542f78cbeefb6580aa9d26d6e0b48fcc51a51c25ad36e96c3b8b98a3042b1fb57744861e0685c9d6b197e0dffb0e6186c6e944c2b5f48eb92276e4c947e5b0a5c6ac10c82ca19a4abbf00f05b9c48ccb39b2d2adfb0ea932a0f64ce6d946dfc5760455f40b0077e8991b831a9173cd047e9639d9dca90efa1b8b32434708a4232626dd37d26a012dac1d241902f8e827c33672b9865776259fe268fc9ae13d7dde975aa3548434a349e9e5702f5ab6ed4c00cc4035e79ccfbf07ee03dbb5b3c108859ba00fc104656ab41673fbcd2081b9af6f7ab6fcecf0800c613f08374bed35f618b0e87cd49b1a04b89efe358512ac50bdeb091cd1d68390968aa0452701d036d2cc22915035dd55380f30c69d098e7f8bd2f508ced72b33900b53d80836dc873846956d8e5e2cf2e1f3810297bb02120617a094ddcffac0ee6eac62a9dbe01f3c9c83faa11b0a27e382bb930e242ac12d6e5c6227de89a45c87c2c574d40c74b02db3ff716cf8bca3bed254d0ab1df503181e95d693d1efc0f6881f207ac39c48fcea096d04acee4a8996cc3c66e86fb4af3f94f60312daffb51563da28dbbf4d0a0ebb5745efe9c119ed7673f247e9a0d0e0979671cd0bc153e9eb6061927a28a82e804f0e9f23cd89999313df942b090cb538f06b5ea33199e787856775e7dc1db395494466afa0d99cf4fd797607cdc5a595e33aa58c53b78346e6abfafcaf7bde0802850573cff01ec4d8652a3a692d95dc09995e4bba1483122a82477ee01c25a65cc50eb071e29a663513ff5f97eeb4ee8d5c5ee812cd3fc6972241968daa04e8c2ecf807aee5c0f530424bc0135decee43162c17d4790a870cf27dde02ec38bc618336f373e95174a573c1dd034e8b452882844c2081b57d9d60d3be2b7cf4b9b7dd32b3aa33ac3cc2cd5abf45482e0d417da2a494a402a9e419988d6556cd2a1a4f05c13445d1b75ef9ee88d27e36308d6b225905df20d1096a5807c95d87d54a339c842ceb8575a3a9d0b9a255d73b40420e330aac7568ed6a20d2c92a2314a4e96e62570264b027b026401e119218267c9e908c4395997ac4e985e469d7a38c4d098099111db298e1524ae3fcd736a8d8594d4d0bd28d44bcc7ce7a4412d8437bdf7aabe0e5b65300cf1614a8ea86833f7fadf61aa5bb82b1fcd61daad2f0de3c092e3cb09d33f979cf5a08a842972da9a501e4af9aec021c8d4a5bb9d2e65fb0878ef406278edd770bf6f98aec1195a7069053235978aadf6bd9f3c82f62b928a22579eee09d44fbd3f8e73f40d16f79913225fa2989c26d5f7c0738e0936cf7a09750eb67a4d06de81a907a7cb3769602df2f587a7766ee460e3a604dbfb2617e91bc9fc3a47fe4cb43c2efce0b97e6c000a4a866f206adee3245f62fd80944e274cdbc137baabf88b88af29bcf8a044db1c22c049b623bf4db08165c06d0e7d42f1658e8a77d4f75e1ed10e1850ed544ebe38228526840f1a2f921e2885454e14f691671d0993f9d82eaa64be3253282e949335a06a4673241eb1a11f11e714841388885d310ed124fda4f159ee1ecf7ef684e30213847bcb7c85fd01a227f64f7a181c6159ea64e70f992d5ad21442be5927a2df38045208b0d4a41f00418c50632e75c3f84779ca0675e5585a0870aae52fa5f572c40453ef9615062ea4b69f3bf0c2e877bb0a02202fde2558b84c3a1cb8c90d94758070c773d5b8358104db2da83d587992430ace88dab1cf20927da49893d5bcc18fb4893ee999c46a89b8d5fb98cc7aa5e38239c3b25e150ed040ed8a763b10101c6d3bc0a46d276db1b0a055194b58a05040580de0908c2b66589052b809128238b9dc6784d4565521a94113dc04be48c97416582869f19802e1cc543c2db78e779386af46c7f3705dc0d44ee78ebdb21ec498566ad47713603e82c6e3167eb89e2d9eee5bb41c3de42813b89fca3ea6624f9ac75965da33eac52b05f9fd2f74329febc5cf5a237ce534c8c7a5722e2441ecb7f52bbb870f9612ef94d947d60065517545d511587ddc861ae79d1f37c73db31518524a2562d5488751e25f605031deac51ee343fa34e49c36cb4f967416ccc7f8cca082c97bb760d7fcd75fe4d5cc1784e562adb1f944069f2ea3d9b7c930f1f0ead184ac339e1c2c1015de2e80da57c8f71f0c3d176e624b95c8748bdaf71cb80606dde93880c3f76566618c09dcf137e9347e353a4a08c457852ec91a02d9ab1f8ea280b7bec56341db1db0df10f163c5bf2bdfe466e1913c1bd510fc326627e55cd6775ca8b03dc8c072f758d0a8d8e29899598f917d7cd7f102d41b36d99eaf1ba12a92da8ce5dd05b76ab8a6b4e769f5336c3d70751b875917b6fba13d1ff4ebce141bb36645a8bbdc3ce40693d60ed1239f4f8b44f56ae7a5da48ddba6c6fbbdd9d9eb266375b7853fa596811e5c95e732be71fc0c5beebffda6931701d31c7b1bdbc99637a0b3603f23200b15038eda0aa647fe68a19cfd96b2962338a3ffb4aa3b8024fb004a7111c52494f435c09c7871fc089f6c0043ea1452dc21a04e4e9c816e50f177b6f5fee0026085920e777af824f74418b555c0f0b86c53234e80cf5d1280499672740c482f105db9d56293fdadcc33b1161aadf3e6588f47e0df886aa60601a54e3f5f67ea1269f86e007dc13a1cf00dc401885a31028d08b2db8063fa5f25ad0056910523d2f52bc89dcbe769ea0f1cfe3dc559a3ee0a38a770f90784895b8eb5099b3b7da8bbfc1dd82c50448d6987f7b77c02a6d14d550cc3d4a736663dfcb99c2c162ac3792e3e3c801b947fa26e6d2fe541a1463d50bf047301a21513872ed4d537fab3686bd7db80ea410705630031391cdc61a44f835e5ade519dba13de141ec1bd7cc66ddacf0276a6a7d785da29e051142d12f8bb5421da297695531bb6659a71b02540fe1fe2c82101946202aabbb55e5b30cc59a539cc1e5a3cbe436a9ce6ad189c89fa41a8a483cc3b243dd91c10e86b829277545f3d7930967f64cdd35bc7b796a4bd8007983de22d02de28772a4792abfb3d28b10b3f096fb779e098e7ef665b935e5ada2449c89652ca90058f0593059b67a787dbeefa79616161617d2691ede37708cf0d7285d4a3fc3efc0e89cae5c7deac37ddd58be131f4113f2e6d48d061bd5ebd90a57f1ff638f53bba10c1f69e17af5e90eadfd7ebd50b36f4efc352d49e0bbbaceb8a64fa817e6bf7e9e377c8ce7d3a519c6138e41a5d7c3ea28b1c7d5ee3388ae2388e432239baf8b42712853dbc769e1d4fdce278fb6bc33a5c0a9530188d170d1e717f7b1cbf194f58c96e8df7c9258ea6b55b58b704e01dd2f387f7a98dd50d528fb65ae8f973949e67b05b1789ddba4f4376fe1934766e52cd3fe2a7454a4f6f0aae14cfc520861e2cedc86462c323894b3129a36b85e2aae859e4cbe0002b8d678b7c3b873d0ce59e275682fd3d6d93d33639cf6e9b58aa0b33f5977bb53267fe14b16fdeb18d7177b11675f746ff7d20d4a3eb02049d4ba1d2c56d1496ddffc0458cb101171d4ddb04cbee9b3eac132bbb7f82271cfa75da62a1ac137bde0fa1867effda33b55d6858fabd01b433e8d136016174dd7a6ad778316e12ee5ae11d3a617bd9f33ccf3b327a9ec7d96cbe90925149d6659a2cc7ed40e9b444917c5712f86991056212ecd35aa566e1f9b492897d5acdd4207a3eb52594f8d4deb03958f87c6a5b28628ff48a6550514b521c581a9675c2b24f5833b0eca6b5ea56ddcada5869b5aa48b7964fd566a34e23a3bdf7dea5d1fe25acd4d17296c6d2db3e45dd6ab5daed760b4b5e7b987fdb38f5cc76eb268db7dbed66b3cd6c335ccb0f55e368564e65da9fbfbb753e45260fb9ae57db2b0f25783755cffc3fbcaa67cfbcddce363b40115b7fdaf15c2d6a1f2395a9f6fc220f4f2882a3d106fa6d9475cffc308eb1ee993fc671098e8b3896e22494bdc4ff7012cafef32f4e42d963bfc34928fbce7f9c84b2c37e6986a9d4a4129f1f4b5526139f9f03ac746b355dc35a6ad2cfe7f2f3e3ab9ab4f3f9b1983a032b5da92ca3cf8fb12a53d14b65a9ad9bf574b39e30999a04fbfc360a675526f333ae6159fe72ef5994d6b886d5b3f746dceaaf63f81b487491e30d31177661163dd083897ccdb6cf81b8edb78695b81b6783aab2fcb79a4d4aeb9d391abe5559fe8e5665f939cce11957eeadf5cedf81f95c4562470ad1f764a87af5b9ed3e264a74b48ec62496ff431e12dcf69ef2e776bbdd7848121ff61071db798c766c369bad67137de833c46d178b62505050503eb0a10f4b216ebbcb8471348e56c646116c17faf047f4823a2db59be21dd53df3e35bde9f967b7faaf3adf6a76714c1f6a00fbd0e493dcab947cc50f5283f6eb33bab1e5b4705f4f6d3cee69d403d9ee822479eff9ea787e7f50212b517a44320d03572e5e6b8873f5ee5f287401d570a953e3f6fbbcfa8814fff31c3d838bab846ea91cf8743e2e53af4e9e9e1f5d6ee99ff76bbe5e789edec90b1d96cf945d8ab1437bfdd8e5ea0a0a0f2bbc08fc6d1b05207b569dd169b22ffc8a9fa918d5393b6c9a5d66bcfdf69a94750573d7feed0f4fca19996647aeec4f49c9f67ec6c4676dad58c0891e888a8a87adaade9b4f875a1a59be4fa69c56100b21f242cbb5daf758825a4f37c7c2f542d53cbd8149ed7d9f7b88bee023144bf5ced96b12cb83136c5fd2524a4f3fc2f2f540dea96b15e0d2be51b96ddf2ff3c91f22de54aa84a1d0dcb6e788c65d135d914f7cb205b85ce43a167332db95bbe754d3de5c6a417887e51d0d3bc4649bffff18ca6a6b8af794e536ff5c8c4baf1e052a8cc6aee795f879fd7ed18d879278a1304b933f5c88e2eb833a3b86bd7bd97df33b9ac7b5e1a56ca4258d9fd364ef988a7ee9950b369beb1e99a2c8b2c040addcc2b61abe7385afd663538329a7ce3b272d64d3a436e34563dd54c5e30dd8473193fe76cf36845052b342bf6caf77d25c6fade192664dd86d8ea49839473b6961bcd2a32677ae03c1263ec716dbbb5b37b8e1ce9fe9171347d80c0caee9b9042bf58b6c7fd403d9a418346b7e5a1c9eaa92552eb617280226e9b049a1f5214c79101dfeb5f586511b7a8ecdc309fa20fb768728b5a60e2b5f3637e1813612209fe3d11e7754a886091f8b99901c6b9454b706bc4473bfbc123c43fdc117db8ed620fd1f8c2761f5b423dcacf937fc7b03f13e2e786e6fa21febd10b734b3c902f1c52d68b382eef51637e87b6c0ffa31c717b6f77c08247e7cbfcfe88287dbbeb96d02321a5fd8cef31ea847f989783a0e2630e39e23d4a3fc18acb02d2d3f6c67f6af1c4386558f902806fdf7414241404045a2f6606c007a463fb717f18a9abca23e1ce715dde1a9d85fbc76d88b24bd1e4f8bbac32d1050a54ad7db5eba4890670ca12704f243a0ab976e06e1a74b5f4872cf04e19ef9b9a5bd5e28d837b5b096b662529ba66dba677e353d3f08215426db7f86469284386ed9d1534be40b6d045d262cd88eb6f7c14f6c5a22c61e16fbc68a8221271ed97918a73d0afb186fc2f128cca43dba639e58667e3dcaff227cbdf4078e2e4410c557e542fc7a859e087edcbef8e24ce9ddf899269cf66934feeb9718eed8d65a6bfdba6ad082de07eef013288cefc0f89f6f845d3ec05eabe4d0c0aecdd32824ff43d708c2426ebfeffb7a7a88402e8253543d3540d0131528906ea00043c4aa011020924553a92147327f2af625ae17403df3e8893b09e99ef972fdd6de10ccf8e0c64d71ae1fe97957086ad203ea99633ca02619b12df8c8b88723c79d67f4489204c1b1c3fafb5ca4d620f8fbc1073fd4dde862cca1e5e140f0234df013b5fe3efdf1a0978bfcbe4f83200886600fb73ec69073dd6b24edcbdaed09a026698074936260abb0877cf770e4de6b247148819a1482eac14d9af1410e43b0f3f967ec7c8e797ce4316dad1e65eb344763f2b70635c9dea8a79ddd184e569ce7ed0d337d76933cf8e0caf2df3ac722f911417389a675b2a6d6b63fee506ff132eba19beebd179ad67b9e9dd748eef09024f97a9124c9236aad7bb82eda167a7e98f891a4388ee33892a1abe2f153722479c4914a4a4f2d930bd050c9014551144511c418638c3d8c7187bbfc60288262500ddc7f5386e430638c31c6b90b7aa2dd64d9e1038b1c30529c94a8806548017860d911e6ca98f2c7151ac6f4cb6bf7f9e65c6bee6aced9c4782afc7617417f026a07f273cf1161d1f83fee3fee3de644537bb4f74d4f49b83035965d15f2fd9ea4e4f4d4005bd4fb265defdf889eb92f6776d9f7d358a9c4a1d796260d932f9e87adb250f5b456c5b6183b6371b2acaeb694949013b171af542950c28d09d8e0865b3d6be738174574fc1cbf1dec80bb0f7fdff775994c69f48c392fe7bc7f54a6b11edddfa9b3cb7bc68674b3e7ae0a7faf3ffcf4f7e98ad46b5d42fac7f8336dd979af4d9bc6aa4a2d30b6da763884a1d57225466750a5768923a30b8a4e1e1baf6572403d1ab1b2b9e4eae992032a53fd189685956353fcfd7d41f7f7cfbab93f12cd94c30acd5428abeba9ad63e55816775653dcafc3f5986bccb8d3e9b74e3dbaafc1959ddaa8a8a81a757fc6d21267a65fe62d1b350ecab2f3a0e3b7b8a6b984d65aeb01fb2488868482807e4a9f1e9ed80eecb55de42886e0a7bddc71f8d6a37b047f8b7b7df8f2c5c8979b44d5535717b187d778d8bac8d446097a7eeede1af7292c106d252a8ba39ae2fef5fece6c3fecbc635bc6b5755e18ca90510a9596c63dbb19b5d36a154386ada796885165ba4042eaf77d9daa5558f47a621705b9be3e006c002ad3ebebef54d8d7172d0bf2eb9316867d7c7c7cac8f4f398ee5f6f9108b4b58c93e453d3de1d287688a8ff7c9623d3de12d67bc3339760bced69fdaadbd7f5b6bc7711c7f83200c06fbd013456eb7ee12569af154d6adb21c4928bbcfdf2035c9e7f3eb6d9c6ab72ad37d1a817e839ee779fbc3dae26ad8165de4f88d1f09f44016abdaa82acbe5de58218fb889bed8717f1d5bdc10d62647af2d6ed8c333ba007acfabb1ff83c1fe1b15f0ea30f3d6ee1310bf43e004b58a160f27f4f2a11c68188a98dfda0960c0422faf68288a970f9100c59c864d01880f20680d520d5aef0accab992baa2df4f2222a342445cc69e021360079426b883a14a982e2bf9c4611155a63070bc5e6e77444122df4f28ac30e68b845ccc1a91b35352ff1f2124350cc69dca639488c406bdc2b55a8be2b30f796f4d0440bbddc8ac982863b22e69e0f5f7eb8a1616c07f6da2e7214397ced58633e1e14199a64a197d72b4bd01ad762ac3b43eb8756147979655cec9edce8a2bc27f7e2879dfe4ee75e7c93fb9d5b75077ef79ee7bd8d7e79fa1e741ce6af7bf066f58eb3dd4dc248258475ab8f80ed87a01b8969830e20ac561aeba95b7304dcad155610ddd60384d568f6d15ed8a9dfbb75768031c698bbd27b0b0c5fc45bacecbe97d90e345cc609df8088267e935a2ffd6e61a5adad110cad9cf33c4f3b03bb3bdb029fbb352890dfeead17d04cad976efffe0e3b9429238410562b34533bebf676dc3bf36aeccccdc50ff13572cf2c5d7f6a677806756b6ff6fef4d6f89758765fe23db97bda0e2a13eef65e9d57f5282cc591fc6a95ec16eea032b9ded6f0d63def567eadf1de443d7f4ad453bb75f5e2769789b5d4231e36064dfce682d9dfa7f84d0795e95e55a6ee2f7ed24cb51ecd746fd1fc423325eaf853a2fe5d81a02982ad6367e9d7ab979e5e315d73339714ab3059563a3cdde7613db21f84f12dcab2d65a6badb5d6e25bc36edfdadff6de7bdf72bd1ad920c2ad310aa5a22c152d36e040280b45b562c5616b24f4558462e5de980b576bad95b31c874da90caa6e4089422aaa14ac73d8dedf378cd8afb5d68e599ce5b2ac94cc10464a181f372b3052ea514deab85aaf3a0e53a98d8942391e2406d5e10c941b28e4e0a10bfe01cd1639dcd51c197ca860e0e098a11c27e23174433b4ea3da8a58b2025a03770902f3324846b7b734a1a19da9690489413973733b36a74288992894fbebc47a9aaf1082621a952a0b0a26a0353c1e51507d57d8d756d6d09004ad91af7c41bda921725c416b785523403db3de15365019dad45866f5eb0878ffe9a008e8af91c7cc50ef3f53ebad3b8769bb3385ee596ecc4d1a1587295a5cd01a7808d47b1be87957dcc7286cfbb9c3a6a87b8a82aa8daddf1763fddeee764284b5cb0a6c186ce58043ea4cb718f0a892426b586b4b085f2f9c41fff400ea99411004c1298b6dd71c7b96d31da735893ff0bdc75a835abf401ef4d21fe40a22f5078d1a04436ffc16371cbfef7b0d63834fb7502384124c8e20f81e07ffe35b707fb9c8117321377ada6ae923b10ff991d05549dcb9d095bfd7a3fc756c9103c62d1ae33062b450b33d0d43c3a66b8efb38d5f4a37be38b6aa6bf74a8c73bda914c6d74182d102085c113c5298ee34f180269dc61bca22ece1b47ec799e478e6138ee8ec9714c4feb0f59fc8c4b1c47974b74b98cead94f0b541617b029fe35f4f561dc24a1afbfc14d8291f8fa326e12d1d7e7e026ed0ffafa1edc0a54265789b740f615b4f66600cdd43dc23f7c10e883f8f843fc087f21fe32deb4843cf1e789c7f1e8056f016f5af2996fc27c1c8f163d91ec4bf0a625def946e7e378d48210ecaf63c77c0e64daa6af9b3ac807b9ee26c8131798f8e7df83dceb26f811d97f6611af7745682ac93eff08b2dceb0883d1e96432d3ceb0ece476c795e5b780d7bbc2f4617938241548b68a9e874ba15277f944717e1f297edd1b3d87dfdb31ecf0533bcb76c776089ea7895c23095a226b4118f8752471fbf7b5b8200882a0fe0b581620d414f973aee0fd7ee8eb089280919ee7799e07fb908888e4767461fb1d5d7c23496271dd8e53268b786e6ce068fb68ede8e22b2d167fb8edcf6d939d5df187d71e12cbf6216e7b588a43bc767088137d71e3d43d6e5f0c79d04ff9b5872f706c5bb7e391222e6ea27a1d8f98dfe2ce6e12ec3389cf6f692e60ff71a22f7584b929d2bd23dce7c30c12f1f4caa58d0a7a42f0fbbe270d361b0c185a23c1c89cd763a7d536030bdd116c2aaacd8ad3a705dbe0386cff0234dcceb43db9685dd6236cfe04d91368ad753d92d970262a2aea7f700823a0a86971a216e741054e7cb9595d0c19b9e3f27322d8187687d3530cabcc11206baa55290f45093a2a2a2a0ae9c44a48515869739d3e61cfca1c352baf08e59bcd667a169535bbcf611b35675b257636b3b3aeb18cf7f071c77126bfe8d561eff05e128081ea9ed5f2a4d47e5d2fc0d2e9d6bc5df64eaf54666a7a8b9bdab88004b6e370c761136c6c2f508331c61857bdcbb7b47ad2b0d2d6f59c615f5b952a9794386b8d9a4a4e2f2d2d2d6125eb6469b6c912ee6896e6c24e97962cd2d2d25216d7a5b6e3ac9794e7755cc7853eb02c3873888410a2e889f5e8048ef4fbd2fff97fe20756ba596b7e8004037f8095ba7f990c3bad37fbf45876bb6da9af37db04dc11729df7af398ec3fb7ae972d7711cc77de6b8dc19a00428ec618c45b03def2e7b9d19a535e6300b43c42162f6654bc98c478c23a654cde6c02112d5031c42de2a487020d991af95dc7158c55206df95128343cb54161482dc9a966c40f243cb8513449004886c45471aa05eab744cf5aed72a1d58e0287d06c8d2718a2ac34474b6771f7f3af6fab10654191e5f90fd9a31ea117ea31c74764d5daeca84b4ab12065586ffe70706ab4a690ab2e314f5083f006248a1a5fcb0c2431d2c5e982ca0cac90dab2a39351881e28fc14194895eab5620d24324523b5e972f778d625b2c53f45a25a4d661bd56e98082a5ac78933650760de8a82650356b9db819dd738f3b0a50a8c08063490f514eb0a1038b93376666516ea8a19ce94156ed5f909e9e4f3dad5224e869c502d2d3aaf5a3a796e66305fb344418179e56e094c606940d0eb319c044793323024d97c850c1c1c309b72b2550506c8e8132e50a13323f7c00835e33adb711ca7801030448972d3ea0a99d11808d0954769880c44c0ad0d43e1505f1839a1b25d8aac2064d6d936e7b68c0e30b0c38603941192250fb044c550a344cf17062250686283971a0c401e304b5519aa48044cd0b655c40399015a54a096c4aa80841ed14203a4cf1c0e6853150366a6daec8542591a1cb15d456404e9a2c543f8aa00384eeb1068a4b95312cbc41ad546f718f204ff07c4ce9e298b0022f425668da1261cb1497245da69ebcc1546c465a9736ae5a172d659600a1e1cd932a5c181b40a8b4b0786842810d737290d08665604093189a72a001320788e805ca0e5a5a38e3a3693cb24354559b1b9cfcb86956b0a142044e92202ed0b4442039ea48530d6eb4a85c58e265474d73a45603104878ec488281141dd25429020e55930d30f82033474bd3162c38dc746e727841cb4d181e9888800c7641cc902142662a2042c7849104368ac0319343ca089513f4c8d286b4553335079b98ac3537f800474916189e0441c3105ab4ac7993d95c14b8017d906638dab9a4072744007144123840c2d450035554103ce07c60650d981c5030c28b108eaa832d2130f0507344103a6c3e15be1b8a08810d8e1454f084ce143746b0580802cc16aa17dcd8e071030b5410136c190304cf99408e1a82a033658d0a66dae42d39a000872d45523027052cc5861123903c71523353418c9b70889107ae889a1c572a80d3c30ac8a0b161823070eaa401424d172565ca8019e334c31320b4a2542c45f8604414206ca2d0de70d9b8d72a1d2f9067f6edb54a47117c035a84181458d9b2b0668873a58b8f3831cc80e507c745870bfd362152650d99393de4d4d1a0890e215c1bbc8297f497908cf8241096fa9287b484a442bc59d2a4909f7c10635b1463423ebd56cd9975b0d7aa3a45c4dce34ab7f6b5fdb24af9e05d65b6c5d7e5a01f76ac14ca40c5520f3ff474eb1c627a86b373af555872e8e9de258ab38c6da1160880b1c1527a2255e968014dbf5558bcecf27badc2e2a47bbd566149d2d3d36a054e06a01e4edc34ed1025e4698519537aac0923048f1160a1a18de0ca89853a6b6cb0f04385aa1d4c6c905365ed97679fa2a51645cb0115258c8d245337ac7cb4f044ea88145b557880f1f283962c6ca83c395921cb981c5436ce870ba48083ce10408c647141d73a47e4e848410ed691262c0048818ea93838c4a0c6884f051b4f32140963e5063760cea0f52b06a2d8132ab820077c420de67490f1206e8b5a8e810054d4a3fb4b96053657d4142653bf7f518b92dde8c4909d2ef55b810fca25adf72eeb920eebcb4c58cf74ac6ecd112e0b314dc4ecb85f654c0c5a96c9087c58a17609962f365c65ce92a85a35a70b8d052d18b4b288f94d020565f344cc59707122a53f11f3bbb5e3072b50c43c9598a8842df80431ca10321a2800000400c315000028100c8643229148948589aaad0f14000c668c4074523e14886449100331848220c61863082004006388310611538416015856b787dbb7401626a5c68741d235bd1875daf2de68067da3d95718a5ede3ac3734ec0d3d5757f8a62a6a55e789a45e57519174557d48988b0a680d178b4ca6deb34347ad52a7fc37460a7566eda14fc29674565fcc7d04812e965bc5488777a0a7ddaf2cc80b61067846a92cdb2382d9d3a377d36c092b05be742de91c2dc2b314f9502097ecd15a19576aa528983f053c831d02f952a45d82ddc7c217f02a5adb34dc58dd99df255e272a6a4a5792cb269457fa58aaa4bbafd08474d8a3ae3667ce3061642e94925a481e6d44e088c04bc66dd0987cad73088c3b9370ce7cb583369b3c4236b160ac3d0268a38dc7b9600298f3a9eea0922f1e754a7355bac90c94900c1445f6d37947588406489917367d8d4b869fe3e7569d873fe0edd4e73820b0f02978f3d815b1e58f1e633fc2bb938340d423fbb205e66997aac75830514ab5f74bbe79bb8275a5aa3c7d0d50300157cd017cc020557811b331ae0c5e898f53dee5acc93154989002e7fb27dda791a0a4a9353a4e19da2c40bc86ead76d918ee96fb678612283429312ccccdb9c4da703157dcc2865459907aec6d3714011049910322395ea5353c04f2fb7659f1af4c13e7f34e08154a0fa47c10d4a2848e982e0432d0bd0d6a5ce05dea68e523a1331668506bef13343a0965e277dbb4bfc83976b6d570a57eb72d23dfc06ed56d82543e06a21c61f55a90f2e6e8cfd2ee505e72dd58d03694441e136852addfbbc066102c08cd50d8edf2de0a188f823a1b613b4f6ea5d4340bd6bbda1517d37556060208731e05c2a2bba7b6c410a385748dcd581056029d295e79742fa26801701d9344e66b92c7962d83828724a69aa9314ca9a6603325450723a85d4a8949170c25eafe43f5b518536515d5e60ac0f5f2a12941e43ec81a6de238453806ae3d6fa488e3f72d5750afd09cba674bcdd2244497e52d7d6bb26df8da1cfc81fcd818048e588399d0ef4e63b60a6d3bd2318f6440248030ac3ecfe77555e27b97aa000df4a8bc1e4c9c308a32ae3f3445e93a7f1bbd46905ac0cbeb4e854dc151eb0e91a17168a04a2ea737d97c238cb6a348aa22f3d7073830daf534ecee65dc95917ea3e55bad3b6cb12e998174a061a5579381adc48a8556d2bcb5cc5e079fddd7a8023bc96d02c77e35543f24595c45a6830be7cbad090731d0e83f9451e58ae2c856ab394280bbf34e0907f4e131b3eeb74f6c64707d678c8d6a26edf8e6fcd93d4a52785523e4848e1fd838e6de1c0046c197b1a0142198d05d05d3cd9d9adb1617165e42297c96f10ddfd005cfbec86e1a65fcbc9ac18dd65c74450ef2f7d35f260c0a9ce92e52ab0ddb94f2b017c91359fb0c8246d71b84bb3a5bbd330aa730a748c27fcb670f5672699595e924197a693249db6cfe8a9a70601b49ced6c6a1832cbd91253c31c8898666ce04a9976953052e9e5fd2e8d8d4f21dc7e0bd36931617d4097bfec3356ab8fa6f9e8043cd2640f0dd6433fa3338a4257444c5250f7b3ff4beb089cd1d64a3c5d5d787a52d6a8434c74f3ae876d2b25d18a3569007a521e750611ba47922ca727e11aadd56ac58bb6a51b720993699141c17a4dc6ba29a2d92a22514330f50718dd1437e02604dc18a771c01d8a5c27fd36e31d7a2d502e7aad15755fcf8a2d616eb6f78bd32b70a3cb784bd1f4b4784422d003a1baa7cb2bb6a8a5d2c77e080d8041c5cff3f7902ed6ff30ac3e95fa8875eb0004eb144277a325068f14d25eb5bbf0e2c20380dd8b68742430e92c47a2da2654ea9526b206643b59297dac8a6c5c40498192536c8d06cdb7ec48164d210523da2a5ae8951e643ebeaabba56e192e15c50f134db340d961577626dae1c06259924d9541d93924e4448bf5426113c89c309392807470ccd02b56e81c6c450985258f1316ce9cd2bb78ce10acb4425168ed288c3845047092149d78aad5fe0ce61dc0a169fca6f57072a590fe1052b06495ab18f0cde1668e46651138890464dcf4187f806a9167496021ba6bb2c82cacf9fe844fea4b0a4b3877831ccb8741f630c2c9c499a7054ee8306c66815e96e16e60668779b84be8c403899b563d418ddb7c2825b72220f0813ef322d20d4762534015cc7951460d4faf10f6a3e846584041a39087df3efa834cdd06b55f13ea263b30d604f8e996966acfcd97e6f88011e41517cd6f402163e9207969010d55e2141cc44a9c2ed4a1e32deb4e5bbc009c420f0c05e835ab99ed3120bd95a28c7553b71865045ac058965c588f5cfc5faa52f8536add56ef7956f42fc1928ad97fb1f70156a3faa17d05b35143a200233d53ebb2a457ce303351a3bf9d25314926eda06c0ae66a0f1c44ad5266a40c5b754236ae1e4bc5d502014d6286037af7c0fc32f967890460bb1eca22a3f5395341fb10395300ad34324b3a7c1215f293def9e760c04ca780acb98aee065646f43cc0b0c8f0c3378c52b2b8ae68713398fc769d0d0aef1c9aaaaf54d22fab48f6c381be4b015166bdbd112a9d60cc73876da529c77d62ac21c9e1d80b44d4b56a2c89c55a636996bee9d0b08e4c309ad0f14716a66790283e70552f758e82b24fe73f392998a9e56daf04768fba136f4832dfad2c81ce75134049e90e833c60164523964fdac0f3c96bd96b0238a33432daa0ffd8553bb418051b44f49d13452c4adbda1d07ec607c1150c4088f5f72bdca5fc429b98555a4185aee2fe91d86702e7de76b4d1bb94b6d2992cacc6e6424efa540d2a9a904ae2ba1473248a8fa33cbf7557b6d1f4ab05d77a310161ae85784c74bd2b99f2c53bea795c0c90414b15ae166054cb19b36f542fd9f5affdda432ffe47a99c65e1e71f8d338aadeb8b7e4bac57c9f4b4f2601529a39d3ed9e83522d56492aa4bf71e9bbf25f94cc5fa0094ee9a4ca77a2a55329616a682ede8364c3ba28c7137fa429798dcb7d2f26ea0f9ba747fbe17f6551af965c127e419d51aa4d9dfeed0989b7eef8ff724ab512493eeaf7a55c7659471efc75874f8966c577aa29daee62dbd91f522b99f41e54ddd8590cda0d3697683b267542b6443631891f32c6231d861dd309c605a610f73481036c53590e967e44255691bc9dd1e355745a57580d3db2f6cdc30fd14e9f98afe59f10f547e83f78ec57c2aea3fb1c17b89303d0661d75dbf7d995a6883af4c4d52972b4634baf3fb069122dd8dd76bcdad2d0794055ee14ffdae962213dc044d8d5ec8afe01edc79dfe3de47cbb3dda1115c360b55a65d4d02cf177f240f0a2eb3afde069e928627f7a427d671df33505142be10924b22c2848b5df9372539041799522c654fe1b290e146c761ddc71c8094acbb2d64dae060fc6d78d939ac314b89d3c6c06dfc8d9c30d85d26c9c18fbfd6381c624ac2ea294d4907fde202aec02c05bf36766fc9d6b8075c4130cebc812329c2d22d3e0386fdccb5a72f9e0431521ffbfe845b02b0c2d74a26099b203fa07f8f429f292a75a0178c9106321fe024f685b80037b13a59418788324eb4d422e34922fa74b7e3893a3716e87be0f6205c52fbff7714bf799efa3b2090af73476d249fbd267e6af3aad29645cc23358043d8ef537ee86a358425c5ef19c285090a16c2012a6049b9b0f999597f328b3f2b6e241db54dea265fa260fe73040b1185799f1f6b9c6ac56e4264fbf069d8c1e28a837f1e9d7a0de59dfdc5d0bb8b94948761b0bb3c6e7fb4c9aaed1ba52de178337d754dfd076ecdbd3b8e590a863a8adf2b86f2baed0c59fcf9d46c8de01352389b54855dc44123f174ab4a91c3b82d9af22309d0e233f2353fae1cff7c874ba00b9d2e9cc411f690579e1265135123a5cdc989157d015b1349a24dc68246d0fa5cc222c0d7869f77b5dbc928868d33da91f721839b7e6b286f2291566fde9312964261047202dc9039d1024673d75f34045e7336886805053b8cc76890ff7f244b65a90bbf57137aa13b5a4121074cd34a30d68b0ffa8a06e17502e844b0cbdaca96ea67c656668bf978f277b372a4730ea4895a5b61f16e67dae5106c689a3c6ad6b1da23ca6daa4ead7efa0616e1255407bc33fc64c69768703690562949b98d523213027e5c14bd20fdfd58d0dfc0047f09d8baac11e8362daeed8067e5c9b33101c2452c9840aa0139e0d51bbee23b4e0c0942d0f26841d655612c15b49c02d9ab088a6cef67fa65318ae8ac23c7ff5923ecdcae2c6919ca35fb962073e35b3312700d23af281a76e6d12ad693a883796c667fbaf9190bafd483fde669a9d2982e3a7c857cb39c235372d829174adf22c6431520fc3673532a4157df0327ec5e3dd670c4e94e93499ea4b73947921e79dbe2855668a662beff76f2f9f08440ed9610acec2affe01566d1e4b306273f48c9f5f77d1186c2b0fe6a76d94e32237c255481c9d9701a9d7989d70a792bfc62eb6dd97f8b3e193a6133414b5c241f5fe30e0004bd923b25ff61ec64c224b16dae085ae9f07e75f060bc6ff4856a569c8cf69fadd68385f2f56b2df02a22fe24dcf5a39d1fe75026875bfd7fbc1f006df3843c1bd405883b64e63b26fc9c9e690369c8e8a00f1d5c02d11ca8e2a9cc9e03b0013e18cd19c700962a4f44c8752cd4d25a4f1d63f06cbab488aef755770881bfac77107768c3ac448a917030d7401c6839e1a941791c0f0932f238559c2cfb90645780a86a757d5466e7541860ba2cbff63008972a01ee4067556a0084b5b57a99f9ae4f19266efc0685660d62dbe7a27d43ac0e841bb97aae96d2418d6c992ba0d51a4887cdae5f8a7ba82854afc810866f09dba8fc4496fefa2bcae0c7a07d8e80585b938b7110355549fb22ab31ccf9c367c2ec105ed6d3c39450233ca58f8a3882944dd393586601c416a9c4693ac52f3a2dbba9bb0fd0e94900507b4dfc831004ab91e48dc48ecc813410476e7996a69f6b57b7103bbb7c91557e0892f0405b7f0e02abb6fc68596ffefc7660a60e75003cd4cd614a5864faa43b47b922fede66f26b1808913457b70d561e3cc310801902eb2bd11d7be385c6fd0a596e38023c1fe97aa2f338190074065061a65f9bbda278d63d64814a50a6016113967926eeb8facf8b772ce676d2005ccef7e9ce8f3b3a3a224bef2754053c9501d75fa16ef0bde921186973e23cb586a03184ab4bcbeda4f10308cd71834b9524a74212283a693c1dcc19e0714e39ca7b446e841e72507502de3b2281fad746de3b2a04c62ab257a5af314dae2f0a0c4f0ba4c901e533f17cd7e4c4406b9951f5fead807b5c5947348bb17ee134b8fe66e3a19758770e6c02497a322127ce4f47f8b5a181cea955c3f29696c0d8647ac412c7d7a8adbc783307649816ec4ea71fd37f65f7fb488d90d4b65669c58f65a712407d5663eee2278f2aa1be0273974e0032722065c10187d832de6d750bca7a18a1deb01d8516013caccb9989b4f3ab089a64e1a4764d12a833a2d5b4e979e3d9cdf940f4cda95db18efed0ddaa59056e1269f4314ee1ecae1b771e6c878d53495879cac1e75d5d4331df945b391c68f827490ec6f6ad8f31d49c34775285327a00d740f13c490622ef588004693f02605f48fbe35d4ffff47c622569b36b255e261d4c77403ee749d1030cdbac881f4070026c9627b307a09d419ab7ae9b2cc592f8713f8a1b0e03381d31e403640b154ffc8d0c9b2b9976cbd1323b752c66a06a2414fcb4fd57cbac4471278207974a17675316417e314ea5111dfae6162eb7b9b0b9a8d6543974a9940ec24a9f2a3c38d9ad834ec7762941f98395f9224dbc11e45edadbd0c4a072c0f3824faf2e8b50b5f67f2d32cd5a195ed481bc1f1fa7698a6bd4964325881079c03b4c3c3517135955034195542756caa122a4a656e1f4de72f0e4137b4157f156f15054512313ffaf902bb6f73e7e426f719201ee5e84028e01f3dbd04ef6dbaaa29c0443cfae133e6ce87081fddfea210da7742f630a333f2d2f56658f9033f580385d867b1d41fa983580ac245ee27dbd289202551634480db781c72301152e73e1e7decb3cfd39d1e13f215b0b7c0c9d1bff48a4462a312546119e841ef3352cc69e903dd38c6cc363d94104a40aceb41856a0534e761308e5b1d63ffe8ca9d05f0107ac707249e7af2888ef8a5a2d26ec66c8ad1d230fa1d7b5bc88230e11a6cd593e916c59cff0117f8fcd2eb576737fecce367978c689e6af15719d502f377401b9813660edb9c2204f33604f3ed15c0a792b93714ccea45593e1a6539ab7b526c3e1c5c2f4a8ccea54758c6671a6951f97d82094584a496f236db5fcb0864755b79cd0088422ddb48dcdbbe5e80d3a30c4dc93257f3969ab30c8bee7814d52d438728ecb41758349585ba73478dfda0b99c4fa066d75a9f10bb786927e431bb6554fd02c81077a3b319dfdd5e1c0b35e7b12f78a01fbe119cd6e3c8756c6e95d8854034b09ab634af37aabc63bdaf73c5dace0b1a927d28bbf1caff48d13c997e6ef119e10fd75a10cecdda057767171300f18a8109ee73f3d03211ef18c52dc2319ad4e6f157801039cd1ddc723ab745046c76afd673b77422d7219f9632a4b8bc15f63bd086cad289a6eb656201dbacdcfa05168726632d5e9cff34efd767fddd914b1be706d2c3864bec178fd376faf8d40a393c920084ae4540a86920a8ed8dd94f1bc09a373726eabdabbfc1bab242b45575768431a7de3b36d6417683a39abc708b9e059dd44b3ac37c6553ef9b57d8e31bedb4c974b0421dca41dd3f009da87d7650e2cc62326c5192908637a718db763cb518c7ff7810066b53ab82b191eaf6bafb8b3a3978ba0ea15068a6ceadb850e3069a2e3fec8b32e31fd2934231563e56ace05c6ddaaa190b35e6455e2e323856d2a352c90daf1c09c3977b8ddea9f7cc3280c7e0676545ca93fbaf78b7f23dbac4f45d64f20dda565324970359b908e6ec7b84ce42b84a41656da5c67c2974eb12b3e6802c641cfbc1ab4c643c12c16c3421536601591cfdd2de94f459de3ed372c6779ff23f06cdfefb08bab7523b1d131849ffe9926cb1c77bf2d6565b4c55e0d795e5cc70a4f27c16dc76601e456618ae1250ee748f50916f49925d5be50164519fdcf9ffa5cdc0b0077accbcfcd2582acb7e1376934b098071abee3d8ebda32425dabc3d709302572761ca32d5fbf2ceea91ccc549cfb4fe6743194ceee28080616146cb0a6c762a01ab30784879afebc0273c8333d4c71fb603bc2416334fcf48928f761e76a63d5f2a282f03fd701f22b8649f1f6cfc3becfc53113650db2a318943decfb0648b2c3b822ba3adb01f9b335396fe05b571fa2c44ad4978297d83a37e2c609d0d550b43c8647f8f2dae677b429f3b5971b828423fb704c0f9a777ea1ec02c71c180952d0f5e7f09cd036fa458c1d6a2ff0db6e759abf9112a63e2c2c31da1524dc4229f1130c3d76577b0f1f375856ee13902e90f276f88dea6d2e628d4b50a24ded1299132e648080b49d761e4a2fe8a9bd2a8c389dbaa661d51c96db5b292969ea6eb65648b54560ee9fd372e198f63a3d6c23c88bab1109cfd035075b1465f7987be94822f8cd7b367b604bc821863987f6a8f5cab6cc8ea1c7065cc292b3a8853ef6d8eab16f00cbfd49297fa342c706574ce0a1e459766ee375c3ef275775cf04dbf3f42ed74070c0edbbcd2029ca2891fa4623735bf30809112093f269796440c1f9ba0d50c8aa2530e81f2a836d9737f3188e61a5028fca9ae1820fdb7a7f783d3dbceed45e66f1292c192223c07828ca2ec01b46a17acae23881d2e8d2609a43a3a86284a8d1a9f8235ae6ae3ba304ebcdbfa9b8439c7764099103665091bfa85f9bba63b1357b06b5fa057de5962f53b15d0bada466bf2d4d15955212f6ba86c21c928cf71d89e25793820e591e58c4ccaa8c95815c942d567f14abffd91d07d675d6658af28277e905a07f358e3d8c01ddbf6a05377e865beaf56653dabd5acb293c7c876a4a38ec814f56fff65650935c8ffe4c650ca83854763e7b07e7c2c9157d7d551ce1a074d54cfd903ca2cf9d3b25305b863feb6e2a0d4610cd9eaa766deabeedadfbe4da29e549b17a63f15e4204e684200dc01f6743d85882911426a44f037d41bc14f6feaf98e2c9e582c1c21092cf9d3140f587065d4a07c1620ae49eb02a28efc5bb6875161283d38c7e923e01bfa2d9a46261381c3fb0cc45b147e49fba0b1c321450b8fdf10f9124f4700d89ec8c257959b08a49b02c697a31c1ae5ba96950cf8fae36e3dd7f0a0441c81d83497673a61c04d6801d34691147c19d4702431b7711354dc742abbfccead83285b5c17aeb6615b83e499baca0b08fd36004ce836a332234706cef5761390695f6510bd11e02b0bbd5058441f808fac3084ad30620516a44fbc575939acc60111f3ce81b0bc76da318823e1c00b81e523dfa62ed1f8eb3385079c7f48eb5b8d4598544cace0dde2fccc9e7d3db3b61b2fb93f145a696bbe7ae15436b5e34c7639ceec6db5ff43187d690dd8dfb0a04ad316c807295b6d91c91bb6fa40c39ee65bf8c1e350345760b96f3775cc1e2c5ab4a0b7f262ec348ad317de1b042cfa45033a4a3c5b12d843c1b202e6832b6bc1872a15e522340823f527a91a21f6006b81584df8ae80cdbe2bc43d4eb3b2c8823e6a287908c8b3ef85304a5095b4cff446b5494bb3c94e2dd187a19bfcf1c08ac14153e07f3b7f158212ea0e9b216b567c12ccb0ec8979267507e92250cb026a53205cbc1a90324fa3b4c4f04e9ed9b4293e3649ad85eed59127bdf92d6302a80f1937185242419179eec321c769f79cf5bf4abbcc903cabe5315bdcb5054fea30126f420a477ab6ccc8da21c5a68d0eac28082c4cb81c89d536119a4ba8b967ea7e700418031f277ed3b7dd7c00b7c5d00ef5d5c4bdd226ecb671b94fa30a33f0229598a4f9590683e1ba35f6613e417b005028815dbf0b8a80a53619d6007158373533cc1622f0d2f99f75960e33b70bdc0691ebecc13870975285749b3e07c02b55249b83c26332841d7711427bc12b23e3797040cf35121138f0fa31abe2b07924deebe2696c8be73529fa24bd1b9dcefc1e8e561f15aac350d3077138fa846ef2900ca14697934cb43a02eee41177ac08981a44e9d73b27abf3f7b83956436c810b5c832c0c8ff271e78ebb300ee86f6088e9a24e5e5001ae33165c26e57d8e2fb0a88705fefc6da7fc333eb63d4a1896fe665740767248919df5a9b0e0f0e47b6c53a726c8be5208b5870c57b34b02811f8d58694a9781b86cafcded3dcb6c2183597f6b48985cb078c1b307da0f76ab899699723fff4eb8061ddb3aaa0700f893feaed7dd4f675e0ad36e745e70a7ffed36e96f7f8e0786a81cf587816c5015bbace7be376fc9201276f11a8ea1938242fe92f3e49ad56f572b417f721ebfe9474751bff581c80624bcb6fd294e420901baf153e1c62aeab7768e319a50d8535678d73225f5553b5ab05cb4ffbc28412bc44fe089291e60b261978df53909b5ee58e51586c1bdb0f4eb390ffb2af96e4d1bb25bb696da851a198991201f7ead5f924a99f514227c04f265db5711925be5238487d34467c6e071dbcc773561686e8e5af0929e9e26275ddf2cc939eec35d194b78fc1099258fbf730986ecaab537580876e981e5b78cffa4f20e88eeaf10c7df8c19b521afdc17c0be7bcd5f0cb16006ee422420b95b4ec0845e32758c82ed58b277fa4030078b0c3cf2ccad40266aa039a28b5e8362ce3b175181f2abee3aab77f5ef0c791a1af2da772bf19f1c8b7e7f9a993702fb413b0f0d73dac16bfcc42ab2d83c083acd609f4a612a7b15cdb35d6ac75dd2fba4c5946ce651d24603608b318844c4cf7af5f7c4d3c4e5085141a4a3fe72e7c92c7796e19088239f28c9d7f5493559e2f09cc2b066af6fac7ae16a837da4b6ca405262843c13eb372dbbab06e098eee488ea3e2868603856e2649794a59b1777689e6732d88e75ef885635159a3fe47528811b999286996f1df6a47f0bc7759c49c9b7b38537708d6b5efd4e5b3805a8d14eb4886307f7b0dcd61199069b568ee0c710bb69fa34edaf79bb876be5f11143746017e2301082c647a48c19c18a4906bad22819c71c7c33d3aff01c13346187920fcd9332c184fcf95add1b14be925937aa4c434bab8c3c699c23c18b2b728e6c94b0d0dc6639c77b31f54b7b9b96588f6e4870dfe53988f7f2cecb782fd04ab0732dc174fc1a9310aa276ccf71176ab8ee237072a07f5742659160520d69085f3f07e0c8d2aee1073d980ecf44207b1e851d45da63ebd38214944a5908786efccc76fd4e419c763a93f4fbeabc02de281ae57251559aa016259423a0e71d727c7bd699c028fbeca00c69363b6d2d923c102dea64978be45063bb1ba1150fb7cff4dbb2399318d1a30b56a79f7730942ac15c200bc9d0c7618107042b99bc2b551f4cc97eb559549038330a7c7419c80d0ac16f23d298bc8a3179554be2e11f1b1a3bb60adc3368d91e2ae964b11841bd1bf1257b1bc9375d8c656d6a79eaabb8196b14b32fb9ff5f481708c1b2171e760f0b863bacd858cd4c250e6436927f4ba6b87f520561ca7e479a5e5857e9a98d765c7bf711aa7b94ddea3b8cacf7747f170f67bad52d175bfaccd4a2ae05daf6afd386302544513a59936792834c938f3e0478618abeae49fb08310479ec4b3a0a34c5c2af9b6205644a6736118f7cae33e76543c153dcbf6c8694bae9f1c9495caa46a15e14142c2eb5c7c36b9096ae948da420e6bfc1efa1bdadc07a7c9b89d8a28f636f21dc8abfe594deba8f74cb6bf9560321a17ff840685fc017da3836492147b3c2e473b1214c72f47420416f8b3a50ddf3a49aa4a84248a5172ee9d78183b906362e8a41aa659ece570808424aa5b37b3ad1adf43edf647ad91024d1f09871f86fd28b3aa9b0a41515bae47f2a3d948086df505bd4af814bfa8ca6d213fba1c453bea229005c3bb631d7e9f5418b661222e72ecca3576cf2c852ea41d2de9e7912f552b21582de63f228c5c97a9eb9723de87a4fccebe052eb4553afac794ef45232a2dc1b9b112abd83be9e87617ab7f923a5d89b8e5e9596338e71bb345b982ca214953c49b23b7038a83dafdc12d7cc8dad6c559227b8e3c6994611636746bb1df152e7b9550192989acea9223d167bad8288901d0028b4cf3458a03397777139f1f9bdcf58e59c0dcf2c3a0d0f3dd75f0ca8f9008df8f6764bb3fb00f8ff797de8fc978d0805f9a62ea6548acd323cf7f4b2f07bcd1c9bdbad36964cfe25da165e94e656c8024b566dc61b42cfc2853311fb4ca9f8ecd2f6cdc6092582b354287c889037ac1e7041ec84a36635e8344ca1d3da961f67e73bb214e419155167c0c6d068abb784a2db3fe0913433825f1bc40af7bc39e36ee8f184ad2f18a050e9d11ef1c2f843f3d13e879431b3b566cf6aea882128ae26a1df6bb15fd2d6becda7bf6948cad74ed8cca6a688065f3bcc5942ee23071c45791e000d3cca9db6d057870942deb559bfb7958de1cd08f099cf8f6b35e5f206990ab96b5dfa2afae2447f0a9d84492fe348fc62b738bac72f508613f94523b60d08ecdff605a51a2523f8f5399102fbf50694c56c85f1efc76e9340a63104176d779a9ab4c02c2ee92537ea5f4ea6e6c71d72408ddccab6ab453fa40af85c871222f7cf90df3a14f1f84ac655c0e23e496421d8d4ed50e7dbbe6fd9dd55ffe71cbb87cd0bde8bca8f72e26895b707b93d9fa5871f7e1a94ed46786c0a50b0c68d3ee2cd512aef740bc18483324c6675ab3ba86209b1b8c5e578d07700771ca5664da7644ead97142b89fcb0c6bbb788fa7faf804df9e552315bb58ad5d66bf77add7b1b16084cb67d3224b149ddf66db2c5c1b3b2719685b35ef545435359def89f38d76da684bd52cbd1ba4237a32a9ccc3d9797ed0653e259c5b8dddc3bf80415b1ecc2ccb936963849bc4f8fe70e7430ec25ed2f9d7ea980b0c59e5f59a956d812312204d75458cebfb5c20bf6bca5a2c685713a84d6a67fd93b69bee47d31a21ef0df9c7ef4884771d00df32b5b11206ed4a347ff276ce7437b417ba5d9e5607cef0c00f8f37990d3ef60a9a5a302156ac2c85d870523aacb1be4636755fbaad647faa93a6f60c569ef914c9c14242d815fe12296ed239bb0c018436eac27361abee050c29f7f12163813c849b58bba65512c9f3959b470c03ce7deebbb820c45bac929a2314664efb6b48e86773a591d1939ece6b26d8558e2513b18fa206016b537865039966008bc69bbbaa64447b5bae2d089c3013d4892af17bf572159a2768af718acf6d5c26e3746e2f10256efda631cd5a5a0f8daadec811f1d08789ca35ea27cfd88381ce0f5ac5eaabb6e0d64eca42682114ea6e551d1e544266bcb8da1235a354c99af155c62765ccb9b43674298c16564076eb9091adc62bda295d1e7f03907303c6a2c7c197f892fee251562b14c6363a6928148d45804a64ff15e69c64e7e2bf6c9d413a8c3e02fe9f51af62b7f6d0b729403aa8723902118ca732b89b6f6f50b48ed85523cd3db7a3241f02f50a013930751201af0dd44b36fb3f29a5480a834783d3f5c73f4e4d124e29cbdcb27b1e6627ca05fb510fc14c88bc9cd58822eb52d8474231366687adb071aaa7d5100394d4a7fc26eb7df52f5e7d551017efedb24962de68e2858d0c07c0d7e10b2fc326b8c943ed745443c7592807ac9d02661ae963c4c66d3fcf7f805aa5c51cbfd673ab58bce71fb9d8d31e4efaa42ab5eecde59970ea2c38f42d9fdb1047d6de4ff36704cba43e4e5bb136cd5830e26d569fe6cbcbfb0b21fc9f65db541d17c7451d8d95c08f42ad3026066ce2d57e4387bcb602f3ea8a5b6b50b1cc5f421083a97822867694d053b575633022e6543ac08d789d557fad055147342d13d8fad751e2dcd5853f394359526b3a6fcdb432cb2acad298fa274adce03a2d11f8a5eb1b7c3efd4eec57facc3d6ab7514fd41b886a78f665716c5f385b633b2e816ca45d7379aa7e59837982608f9f715fba21fffe245e134a0530da077cceda33346b2b0c24c9cea66b0ee8863944acdad9ffa019cc24456f11187aaaefa84e06c5b787410150e7b737e2d42a9706ab88f7968b1e781b384e6360fb22ca84c2c5cf80188756e0b292bb522664766ca094e4371d97b150277d5b96d0bfbb47020a931eebaa5e6ecde025d89c62235447c876040565da979129b1bdef59a958623fa4e4f7bd8f84262cd2d246a31d7955470e4a5314c3c015fec2f9fd7467347492aff7fdaf81dec45bfa0a32ace7384adf6c2d4d54c3a0b475f0aca707fd758c05562287177a3047db721d998419c3fbe266d0504f6d5f0a66b988cbf5da646dfd1659571cad02d470c5eca4fc1985158c99d09f99efd563782a132729ab522059ca39525a220ef79934606d9ff528d4f00b27e46705acb563fb738bbde815f60faf0baecac6a1e9baf4598f66693bf6294738d46ad90b51cbff21e0717c15da0409e134e206f797992e7a4cf4a0875094a60dadec3cca1cbc93a1dc27758a97060ae26556b66f4a2b87c581c8e206110474629a19575552fb6e719c312924c7d93fb2eda424a4d2d95149436ccdcf738a14a58c1acc56041fb46b327f89bd93ab77db01baf656e74760913a0e70db3a3590d64da4c08ec583936ddfac299b75d51c6329114fd5708ff89bf4845da85352204dcdeeedfce3af92de154b0406094976137f2377b8317e0035a74b0c1fa2a6fc57861f2b698e4a0d2d87bd8e0b046aa02a102941564c1aac9590e0ff3656e51e42f6704ed88a88dd6bcfa31b956d20351c5e9b000e3d552ecbac6ec4806da6a8d33de7c06a57b3f0ed404fdd4fd139b0a44686fb5771aabf3ef4d3d624558577e62c0c9aee1f5db493383d8ba9dcf9556058c8803c9408bf5b2357f5afad0f3c1f7a04281bd4398ab0355517d901ef1699576afa67720ff3c2b4280ccf243a4bd46a2da6b52d6299dc9a7e28133b6750e8c3008c21002a856ed49430352a0c7e6a3c2b01673cf5d0571ef2ea1ed3a2250e8a01bda9c7453d42170772af2eeed1254afc442e871b788bd7ad0f211f893523fbf1bf73e35b62037890177aa86c4c44805476d9aac9e6a465bdd0a98689f400d995a20874381462acb47989c1cbf0c8a1eb7a9b7501b4424dcdd3f0b155c43631a30f2111b93cce2e9c5c3dbc645414ce025804befcb47bc4024fa04f6b5da9b62c0af813dac1aeea70ea476706f7befb677510c0cea5b2bb98641d10983a1753a68011e22112ba91b1c618a202e10801df9e3c3ab67d244fdc82304620bb3e95af8784713cc2a72685eac2091c4dabfd3dca57973b8382fa6aa21f21e4c8c541e1f7fe17a8842366a6bc7db77b3ceceab1e942d85cddd5a60194075f6d1484f12815775e90b88ae53988e4b6ad4c5201f5e476abae22e73e728c042f48d47e97c2f08589be08cef98c28c5e3753b725c2f1eb4e276d91785398d1fc1b7702f3ec1f1540826030eafee3bf5f1d69da0140054883a39b8e31633cf6f4011b334c464c2f848faa81cce05285ff2c9be3be107d735a1a4e99a1d13575065d30386ab8c4d420c093ff6295c177bac72aff0b0b82ffed1e21be4bd19d4f00a3b2ab2a477b075e1f7549c5265daaa33063fb10216b337fa89c9c2760c9ebcf4b9e15e4507c1a315152a6610a86c2377d3a247577d7d054c1d9c9e66a257c14165603b7fcf1dac01dc1646d64d3a417e0c5109b61aad022324741e5cb66e94930874aa086e37de7bc570892d3c54534976c96c8814a1e8d3149147df223058c1dbdee418d76cdc2c63e40f201ff18bb570b74f5ffc1dc19b830a8a4a9e1ba5eb68e7f6e1a0f46120e44f44572c419d5c1abb69bce52cef2ca8623e44476fdda0ce1568fc8a5fcd1c796059c6ee42dd250a569f5fd292fb254f6249979450ae5327352517bbd6c48bb40b76673d4e4468acf2cf8f3c37e8962becbc3e3f16ce382fd4a4a406be6a589e542486a4f114cf1a4bfaf13c9d91c9f4db96493686148f68889c2e52bd060543cc13f67fb166ad92fa6bc139bb8ea5c5bad777816bba796acc1595b21789159177303254f2e7e3015ccb35dd4a28100a43c99a441f8e14ed343c1e8937f6e798ba8e8132abc41950eb94a2b708a39569e9e9fa46cc787bf28c53d78118de0369123036707bfb3d3f45b000d03edda9ad21a631de9930b2d4522ac82a014419794ce05e4148333f9a6034e715268438271d437657abf4ebfc36a3b426e9b3c0a15c756bcdf480186be41795f2683577da2b435dcba4b544d44227e62b853efdcc3fff8777f52fa54a9cd62e0b9f280837e647ae76ebb24144c8c11e0bbf3489f8a65a4f8dadd1b5ea2b955122f6255c0dc7b33f4e7fa69b1a5bd934ffdc4c4a528de591f45a4d8b38f561e158d8d439853f42487b4e9bce85335a763890037837fca9557f962afb721b57fecdb22a203ce580a86ed67ca1c940b1467dedebaae4cfac3785b64838674fde96d1c0de491deb22405f8ed80f0290af45d230d077d78034af46647f2a86bf4e8318fba0e44032ac86023a05441bad912fe0484be291fc6f70b3a74c214b40ac62b3074b9d08746fe0ad58b0db29d2ab490cfaa292fdc435685ac660c93acab7d9d6901de4e476b90fbd9e7c4bf7e7342b160b06ad0d6046b5f92cec691fc5ba4a29ae4ce969c07581fc860d135cc855d6f02d6203ea26af7c0a7536e29009ef820405da2e46023cb41fea1a0298510586d7bebb28b871c8a374708a531d6e7387ac0d65010a24a922bd3627690d600f4b5bd89f737f6a62f17b0d3bba716ec4d86ea81140d8029f93b4ccad744f1a6724f9a259797baea83c367137ef686be88d5e4cb29935e7385652f5956948a061b0486abb3cecd1b48209243e8b92fe97be6b386ec28bce56331cc7483cdb1bb3913253da1b37293cfcc59557ee8d8829baa878a7549b0dd71064bab59d28f0f4b1818e054c66b5c187bfe67a6bc6285bfe99404893de5771f4b18160a24acfa658fd591a3584798b50e8760705d43b263d402522637fa1b5535049de6db683b00f77ea83bd98bdfc69767066de2da215cb3e7cd9de7bd4245201052a5421833c946365f96d6021e90844b23e4153c673503e6017a85d8c6020b9998c77321b033a6ee2597ac9d4b085c61b065a9958181ff1e64e4991718f89c77f079ae7cc2f13b7ab5554ff5045a55f0ea61cb12f8b4d0b944d87e42fb88ec0e5f600e5886b9642eca6516ae6c75307a4cc57e0a31a34e5ae0b80b89835fadf77d7887d74d26de4cbce33cd030192fd8b76102fda35ea39f29d41513d59ed41577941bb0e6e338b029220976ea1aed01ffcf568587a71cb996e0a750acd7dcf1a7f63e20a3f56638c371ae7d2a0e99dc2f1b3acad868a03db9783da9999488dd99a8dd132c7435138474f66cf679f131504f1006b93fe74907cb45057dc356834603932c7af790b6469b796ec6d2cd7049549ea982372628ff2c65ba3419af91a59e3337e0563e5badfce0a60b30d17cb98c1527bd3f8f8ce87c7d189c58b45c1b7a4cb449ca0c232bc8c23f96983d9063aef646fa2b8c480c27308746b16a6352c139a48c76ca68649ec2f18aa28227c2ab36e18673aede3b2ee07aabc6ee58c9698600393dbbd7b12245b6da93313857d64972682bc29bbcb47a51ad89876d9c35c8fb7bdf3ef9a9bdd919c3f8af2aaa18c411a680f0233ceaf6fc44d054cf909981e72f7029ea56eafc7386e2c50656fa5bb24a8b13fc081a81005bdc7e2e74d4ee6a752d3c826a6a4b017389cbd79a80758cc9214bd5f2df416ef14f1d81866a4adbd97a272898469ad4872b4edb255c8c89ce223772da38a6adee4488798450b2a390140817a5ec23b81e598cfe39d0146a140f897a50e6c14bac59f3ae0919cd331825cf2c431f645770507ba4683bb81d046adc033d4893d141ab967062b6bf7a24620d066b80c9568486f305f3ad81d23f40baa99b7015107ac277b89ba6c5c4f5913b4f713732c183a892b7150357d785b5c013b887c41bc2b39f941c4c56a88f90d28f57a0ad910b5dd7e9c6b202e07c3e6c489eb6e4aeedb3f3c5f9c4e2d1dd9b3a83147a91774d4115f8f1fde6f2e24bb9dbdfbc12cf432462e12e4fe1c9a298154fec3bd1e27af0ff25bdf28ea4ad3bed8140ef60bc76d1d81c10b1856580c712ce14871f0aecb5608cda78d4ceb9d589ec6dd22911d40478da22ae3c79ad4a992226caac84b62c4d4008cc9a79f20c201aa4cdbb85fd05a7f719f839a48e990fb3631f98d4a906289062a6827c06c6c02c155f68c666fe3ed7afb4fb628e99f5473e8cfb7fa626a239493b0820d0b102f7faebf95d7e572332caab0cbed88b6b82ed4b6746ec7bd3550b995f533eeaeb92c57a1fe2087cde8898d9b8019c9946a0a214fdba31424d32731dc279d3940f947cf51f487994be24dedacad949089ac412bd1367f10789ca535aec1cfa1d1d0797d3d89573ab7fc7bd379f6ea0dcdb0aef8b6fe8191381e1dffb90b78dc3925f5e8b22f9599acee65e920f4a5293349f6cdbe2da9a094bb03a55bed2edd3ceca8324499e67115bdc894268e656279d5d5219737fe7a44d1d6eeea48ee049379976cfe3c3830cb91ae24346c469d55fb6176f6115a384008869e0375e2a9ebe768830ab765197e85f2b232e2059107a1ee3b3ae8e14dcb66c3035308c5398aeed5029a7b3e2816281dcca3957e4d26f19ec8483747cb1cc759cdc0fb9eb94a55535978a5d63c4de46db5ff0c0172c77f5436eb4a389f0e6160f881d5cc8399180af5b37dabd124984bc82948e75bf814f0ea8aaa8d1a338b84507d6f1e0fc5fc715dff506ba43ed16ce9749034b787f182f6676512b1eb78c66ba87a12bf3e779d848ccabf36830cf6636749fe74752a0cf4f16479e0b4d6f5e72099df8f5192a4452d87e0c0e26659fc44bf269036cc4b7d0e1156427e444a9c43a7e5ced3aebc937819c94a7207c17b118471ee986bf73ae3675be9f3000fbfb2eb3c2e3c7203ed2376c74abb51387cb569cb1186083a080d14dac152fc27095e1c1b5e2bbfa4cbef08636ce20c286dd5b5dd0b02f9d6dab84564c05cd668b728d0748bf2059f52b03412236edfb742b466453540b362936a7e6e4cf81642ca141e7d2362fbe60489600540202a684ac4109256882af38523894f68c023f9d5aac168ad91fa77beef820dacd172c2aff8920a3a07a501bfc9e2fd828c430a508d6d6d969e0a16eac58b90f3a173a0d25e65ad9c4fcc595a8fd15c4136482d1d4e70e0813ff9dee532a0ed8987ab21b8e0d15d82176473268c576fabf7f53d65f42d8e88acb66acb6090afe449b2a0019cc87e785c8c7129e1bd50369e0672d9b334dd6fb7797d2962de2c26057f42697afb7336ace953ccfa670b95b0626f449b5f13b892b4aa9b106d03c6b58315d52030d371c74b3ac0b77ba7fddba60794d724327915e0257530d7e664672ad10474c105cdb29c0b9ec74ba26a63a43a55965e402e391cd07982b1fdf343b1ad12725baf85dfe82dc1f458937d1b837d908d365f2d82a1719f2211612db4594169ee3318318d403db33a2efc8902867e085f039fe77440b1115e3d0330f8e1d383c2f5eae2daace9ff1ce966eebc7eb21562833087010d5bb9ae42b88e4010d74980ba53aa3a1485f85cb22da399281882ef39756304e5f172783797b3e91350625ccb0943615d0a0d34a4d7d449da84f4991324d1f615efcf964b6815f579fb530099dfad9996fe9fbc6f726a7fa3c3e82c14727cf279f1a8abe0e44b926028782ba077440b81d455f3f2a0b9f87a3d3ec8328b3f7d344565ba04e0b34da017a0091365f40ccaada1c02b0842f759050924a982985cf6478140a968bec3d5108b1ac114fc79811de1b6f5af90ade9472b62c3c44f38ad99bea9fb01dfa5718a293aeddfb139502921a06ccaf5320d56cafac1fbbe82978787a8a1a66d6646f296592325803400341038fa3576e9020c3a6b44d15b0c9a907410332990ccb64b6b53b598d4ce74edbdd598f05ebb2ee36af3a20f5ce83e2078993fba53351ed4805d98c66596c6070effdb8b8e2cf3adb75dde5deaaeb708784ee553673d53dfb17910a39550763dc4316812a8e98b9b0cbd4bdca46d98b566132b294d9c069627d72bea10af8dd3f0c73d883fecdcab6dbfc0a54c86dd889eee1918faae384b086a1bd380c79b8dad19d1e893eeafe58d8ba234b102a1c74905437e89e91a86c50913048badf1a74cf2a1a60ba3892a3fb355284880a06b302d50c2a0ca864500d51c5a08241f582eaa512a20aa2724185d382ee590504e60bddaf8a05182f54234c0b60c680d902460c9824983060a6c0b060db686a7684e084c5da5855d46da3a9d9118213166b63cdf6cb6a4567ecd6da7ad5ae729effb6d1d4ec08c1098bb5b13a1842d7d487c2ec8ea7f2b4322bf7d92a159db1fb3e8f625ba6602d74a727dfbceb48e09cf38b7148637eff0041c714ceb911ba2af981579c10f103e7afac810a0f566dc0185f7b79d5613f144631d19d6fbc39e79cdbe784eea654e6f224901c3529e20361f000c29416801459a2240a26aa58873032d2d3e4089097135a8a2113e46840082f92540c78f416bbbebb6eaebb03b0dcac9f2489620a313902c3139b7bf50f9a8a5d6f3bac82a89c05cf6d98dbf016daeefbcffdf6f8afddf0ddf0d542dbffffbf5ce06b7547ca64a1fff1dfb7bf7d32f059477696f38a649d2fde2edebe2de88ca56dfc43efc3c5e11bebad3620d3a9116202e80c592b8da917652212cb6109c572e24b6436cb7447732e8184801448c4bfc9374de85e499246cec8965925377c377cb9d069c5da9513f85a19bc053fb2cb576ec3dc86bdb2873fb80dcfc837244992b15a62f289ee54b6654447344892cc2469eba87b25499ab2a99ae2323085f014cb26992ecdba944dc96a9024994992244992a44ee80f6531f0c65a161b1c8fc90e0f12f84747a2ad1111d12aeb57446ccb061ca050282250ddceb1c3a24023aa0db95f0fff23fec35ea6ff0f62cecbf40742fcff81ce005175b8c468d26c083f42d550558711f680e35c0ca0526ab81a16105d7db80f89ec3db1d527a6c471a00008b037b769cc5784eed5e75f3f84ce5c1aab89fdff5f8bc23f0e1aa0be82f8b10e3c10850c0a235847632e3d825bf940812ebfb515dd90502b6f23d88d13b878fec5b5d09dce64ea2ae93d2439d7578521af623df5f57abd5e2efde4be5eafd7eba5a3dff57abd5e212b3663c965e5d0eb929a51b763b763b7635d62a48394b4839303a413548f3000f5ea46e2470a109522a8c8848f42163473eda0b45ddd70bf1200bd4cbfa54c4990391322425bb5463d988df11fc41780d8edd8f5209e3a88bf056dd5927a759b60f0d416bc909f41fc14a53588bf6f8951d6dbbc86f173c7d553aa969fe225d8e1e9c99ae35ad0dd8e19c5d2f2c202ade7e2656147b0e411e1539c3e9e1d141f810ad23573c74df023ca5881b1832bd6dde6a0e641ccf8603f5666679646848306ff220bda4a51afeecf8b018821fecc75417c2762ddfdca20feb6e5fffbc46222a9e392f76d91f05edd4349397563bb1d45e851c36322665b389ea6c5dfda116c7196fb74ad92d08ca12f12dfc5e8a586a5667b7c76e88cbd78a33136381117785c60b04af21dc73f90edc8f39881b783061f16ef7aef8bde08e97d6ab55aabb55aad56bb71d6b2ee366f594de12cb7810a00e009c1c1a7245b1f71dc5ee86e473b13ba9be34e168451ab71b523badb99b5b05aed98e27811badb91db1de8704df1f7f7bb63693b37a3585a5e582fb55a8dab596bad695f9bb576dc41f75a1bcb00ac706038ce8e1608c755a0bb1d73add6aaac5663359f6ad6f8e7bcce2bf99def515d9edac217a5525975d89aa4f405a911d55629f3961a65e1a81fd45d7239d50ddf0d5f9e24eb190a684be8615ba51d2260c3b77473f7df54a791ddfc6faab9ad56613e6a357cc20ebad7b20ebd4ca7b4226dbdfa2e5ab975bbacfbbdba69b62ccb5259e2adc45bb61e67a27b2d4fb0de566e2557e692d64a97cda91a2de7b30e9121b1d75249dde19e46a9546195483532d6b154471ab312a28ea7fdd759bd2e9e654ba5734ae9cb00d2cc06d511a88e44bd8e75ace36ad43dddcf06e2412c1a74d02c9b50596fbea9297cafe7670644e3319af5358e2315facf2f35f70d596bad0d62e50f4869c377c3d7c929b3dbc4c5c96f5cb655daf0cda513be165febf980af459de7593acf8beb797195729ee7799e678f336b95d2f9e58fe759cf243de2bb729e67e93c4f1faeb394bab1de0dbad7f3ecf15eddaf713c7b7e8082c4256048fd8da812494901a1582d7d201db1a39ec7b67c6cebee7ab7ca03f0bb681a43b1d03dffecc9a34691ee53adf5548622d8cdc30621d1a2ac0c5befb7bcd88dba978ad705ef6d5750f8c515c46ff1711c59381a479b8f8da338723af3271a6377ff12fdc0521d14c8e2ee56b0a19bdf28bae60e66fab7a631b58912a93227b62bedba1b32e0218a204c923822856943b700dac18610240de9e288cd6f5709d4bac4f0abbb449d0e197922765a3302133b45aa327d979068dee9ddfd6f970754e83d3b893d68aac200ae01785f0b707bb300de77ff3e71b56e297a392c72e6f286cf1f18d03de70cd6f33c7ffcf8c1b182e84e4f2566dedc99b99a58ec3d2d2cc7b96ab89a1511fdd15d1efc2a3f35563d902900945ae4e94687d02ab83e26c78e2756cfa84137faa33b9df5aed3e0d025163084a686a893290094ef75efb6b92813db4a09dde94c854e4363f1c55b0d26582ed426fef3618496e7dbcaecc7e4f228f0d0b66a82c378a732cef97fffde9965c813b3d6b641ded5aff6df0cb3586b9399339366129935f3e5bd0ae5b45ae79e78db3a33831b4c72def26a0addab99cd9adfbf6dde17ba57d37499a669ce5cb655794cd3dc52d514a273364d73334d934b71ce6a6c6d6585691565d69d8010a2c56aa857370bd5b443792ca87c3b2bdb6632c95b9ee9fe4f6391b1446f9bc9645b65a17b3585aacc9c9933b6cd64b2792fddab29544dd3fa9844a6b96d2693cd8b41f76a26fdcd0f4b67336e736d5a03052c1836aede4b24d3bba1eda2762966c21bcd3a9ec1bfd70b5202d1150aadb51f0eec9a2c893a99c29af7ea96cd68497a460dca7d9c94b170d068202aa3b21c0e5b6c3911dcd817cdd4ab3b6f1c67afbd1c276b9ccedcdcf54963d118922439d2879dc2845e93888aaaed6806f9594248bdba635936db60f65c182232b55c221419819b244992ec488e2544f74a8e32254e9f72dd24c9cf9d5db87fd9168ff7ea2e3a8b8c907a258b00bd0ea9738304930db74b5ceabe07a597813ac6b390c8ba1aee36076dd7e25d61f432dbc63bbb84b8c391a3f5f2f2f2c411c691a3f5f2c28578e999d75248da6a8d2a3ea1fa4131dffbb15fcffd6c409a8db0614c22c12c23ba57329baa8e3bc27b7567246ea5055207f21f01c5d2f292316ef178d0bd92768f80c48d76511c877c555648c4429f902734c332dce9f9010a7a99108661188661b80244c6131d862187128a76c637d230996e4e5390eef57c25a44facc60f2f63cff34cf174250b2f6d7c405c4043876269796161603acfb334a5ea8984b6dbdc1d6f2128c7429f902734c3323499ce2926ef856dc35869849484a3417e0700596ec3dc86bd10c82eb761bbe1bbe13b06dff0cdbaecca5d3e14e368390a2ebe165fdb85ee4144c4c1f8ffffc7c9d1d93c2b387c2dbe966381afcd2b294f1b7a99920c6f5429975645988c38e5ae4516b338a5b3065fdbd2bdd058341c3428be850ace0a8d46cbb459a5d9d6f36cdd7eb3039a46a399f9cd376d0be4ae372de7d6e345e88c1d357fcdc8397f39e8fee69fbdca4cb41a2d041f67488e8e121aab229f1a39d7de4c810a9e098d96694ce892f96629531698cdd189be902063afec95940a32f60a364f5375bc58f7666d88544a5091f8325c56f60a36ad25a7124f756246119073ce2b2e17f8e00927a30d8ecf51f72ee59813af23a35acad5e60de2085f78dda7526d598293374ac63e9966a464a450225da20920510595eaf994eada9437553940a6a229ef1b265369d37c8b2b4570f13861e789d8a94c280562a742423d62a7329d1e994af95473ce3b0156cc3141e84d6d565ca84d1d6d8b867a7573344f43c41838889d462c5584f0506130180c0683c1603018ec05dd2b2c08c6f7d63ae7d8f1e47dec12d71b01e629d862b1580d0c0683f9d4d856256130186c8886c56c2a16a31be6882e20fac0f892ac6a78821b71291f9107c46bc28a6125c6476445056bc8171b2208ce05ef40131ec4d36175026fe803014b07045178189e90d95764c581ca5f781c2c4da7cc9bcbdc5d955fded5119b9704b722411112ec95bf304a1f15269ec3cd6f7f44bcb38fe695b49ecbd3981494e474d07610a78320d8c10e9eb811140882df15a0cf4f2d6d2b5b3363156f052bde113e2fd362e9f992cebc29dea3930cee827dd59d1e1004f5c7c38ccf0a1a436a702058aec8363e318a6a48ae3af2f812068220085ef083c117a5e349328092a4c16ac90d0f0c1004c17af4643deb513dead13cc0186d831ab10810043f0fe8984763acdb4700f87cacccd2997b39e0b8a315741dd701e95e8f7a062b08823c8a8c9092764c02317844842b185e02a06261c12c50e8ceffedb6d672ce8ad304502fa7bcb5701c2f4397409213ab609400a8944e7a45662400000063160000180006828563f1689e685a87ed0114800d445836705e3a4c260e866282204a412083400c820000c300800188020829a41c7c00014cfbbc45bf9b77404c233369a984fab6053beb12efafb12894c88608b80cb196274752d3800e02e216e48d46b87e7a08c4c03cbdcf6fc8aace4e9fc389fabac9ce8a43a93f610c35e794152051a2950aba14af5d34a9460730c751a6ec67a6e429b8c409728f6038c6f3f3614a3e8b94a794b24d4f578cf28c8116f7b654069495ddac86a3344f61da0b2ee66ba73f52ac042852999648b1dd3ea1cde3730b7df75cf5506da81cad9cc36a3387ae1071cb4f5839ca2f9d9acf03f00e5dd086c1211f8ef929a889c413b8d810db9c0c21fa1e3e2057c1138059d94d072068a7fc3a3358d319bce3fa5feeccda46cd800d7cd2ce33170962ba4603b6cc4a4562f838c2b82809b10a8e7b3869d4b4f861942553fec17060fca1081534ee6e5b3aba9297363ea1999f7b40f36d4b513e582dc787c919c6295512a3e8f99657c6076370200112d5551ce53cd2f4e5b59b7a9091706126751231e793d89526aae676caaf0abd3bd2599fe7bff962d64ba553b4ac3d83d0593868239e209b915ad329588ec7860b888165fc21f3e61add4a8fec1c33f5c038f038c295e958000f6603968fcc7651fc1018edb35f46aa7cdd4fa7a05f7a208f0d4ff6a4078ec665dc518926b3991e9a475aaeeb7a7403c3a54bcf23cb850a8a62c0993901d667600b9f61e2f289e2c66c797a508a5246ff4c7e81e2d7f0d6889239dabd520067ce789e8687a7f44361eeee7edbb19285d81080ca87c3d74761ae9aa9eb04d854058090670112f89edc053cdccd897d38906ff2c5bab5ec0483b71cb7d506b7cca38144ebd102c681c31667079d077a82466c81c654f5150208c82e4cd6f999fc534f16d9d7f6a734c496db12513cac542f85a3fc1c6530d6e99571a5b835dfd522c8193428867960140eef39bc3338e9611881e648b4cc156de800d5f7910d17f08169f343a5b16e72e64634532caaa5f5df912f1f23848046ec2f240fa468d1d074620d6276869eeb4a991a0244c3b905009384e4fac140309847fd010f70c5e822112e1e4e9ac31d9463c3cf1fa388f9cd5e29d1489bc083eb3cb54c3353d1f93ed2492904178cbe9bb6ac64b73bf82e93c285df2d71dbd65571b683e5df6ee9d3414fee1313385d3474c99b46a72701b4090962fb532344e081c2fb728eb76beabe39d9561be43b7db57348df94c56aa3ffa93a9149ae8eeb395f9c495de36e0207fb4871a055f24ac7f99b6ed37fd0abf62fe1e5a673cf2d2144acf32773af9c586d5f798094d54c9dabe032cd30541c921d9e8c31e6b78f626d4a0638483810152b99cadf882ba88c6110943725fd883a4a5c9d006c85ba19b0ee8449b3b43232acbef25774812b58eaab15ca461c1f1d97955ffdc4bc54f9248bcf9c9a63757b0960b18ed3d4ceb5bbe3c01beea5ce8526c7fe45376aa218447c5462d15bb15dfe15af3e58afb6846fa3e27c547fc57a39297bcb9e4d3e516db963f6ea26c7d2fd1f0395b8c640def80af9ff859c7b4e745ee5bd97bb883a27c45fb6c8bd496ef493ed1e5a0990096e6e243cc225f2995072551c291f36eb3ebd7c82c346b5af9c1a44c195fa3fb394528a23ffc11c8b809e646d7f9824838242b1be65eef43926ddb2ce531b3428d1148ac0d9b1bfb40b2608b0181838b60213bb31c9905d2592ab71003ee7cac0e99a0e8e4e2378dea086d073d0648fcea29439a2b0cd69fa67f7261441a939c89bc0df6d40edf9d7243cdbac4fc0f9599b84a839ed57e4fa214a1f1ec91f088da8d8f01b373e0576acb02f5b0635ae29dd34e60d4827288430f56cbae784f4fa64ac1782e2e7a9d8e1f2c08396a3a3d27f6524e297a3f814ba0f10586c40e4a66d257ddb57cae4941cf374191022102f2b122695caeb8aa50f44dddaec1cc94b62755321c331952a4ad19d528dda0b906773a5e5bd56ba3602040196f87d3bf075aa80299aff9caa4f75c84d40b07ca961352309b0c30164c973038c2c272c4a35c2aea622df7644ce1a4a7441cc44e3721281403a02c668a378fa14913dd8ca4d41c9a516baa38d6ef66e55aa3ac79bdc229c8ce4db120ef49a49ab3dfc2e97784fdc8b990f72463c48b670e24619d07b22ee27746b05f4fb4450b3a8bc1c4d8175737718febd1c192a53ecfb921342fc72e8d377d2ebda7038e3130fcba17fe8101a80110cc18e6372b07e5e2e6078731f6b4a1f8d9117bf06059f5b8ed7beb88082451249f596c19fa03e4fb11090d59fb350fc0efebea007bee40187ad5d1820a1fb1f7e169bf3da2ca296be3e728dce4e02b8fed600c9489e57a95b13805d9e931019e3f23c48dda1d82ddff6ca325d81a4f5159200401c8f3088c1c07a44cb6deb8e750a92cc047d7005aebccef5483f65e1805ddf58c0d87f9700683f4800baeb2cc200e01c07af3542c199e373626814f1534a5dc7a0f78e848ad98783763980cbf9ec4d73e8b303d3e0e8088dde05d0b023a8c333dcd6816077dad9410b118fd7446293554ebe39497f257dc9de07b55f1bf49ac37cba773b19fdbd620b45f9dee0062a7a37623fe2a61379a5e4f606ba1b314c7275127ae5200fbddced8576afd85f2e97d0b514bb1bee1b68b3c6984dc8ea3da3583a7376f9283a399d3735bee7166713b4f69f8a8e50e512be06888dc0edf96b334bd18f9801f80cc5e4f42bccd1ac27a1957f9ca75bb809813a4d5d6c344a5ba5cd6133cbb1a7158ae279383abf2c429df46dc40eaddac8f0f6c14aef6b257b76b736b74ee6b40e1147a1153ad23621c48ebfb736c17bdbcbd3e31ffb14a4dcd2a184312edbac2aa65b8ba85b6c8513bdc1c5f984e8a0030558176d97db5868e7aa436f26ee1c9fdffd217a310f292ceba49c3d3bccc8982d5279f6497e1bcd8ba63c5cb50f0660f339192ae2c3aef80664ffd290c6bfd9c9c2aced83a978a69c3a94ed31e3be3a142d05c2ea19f12202d8d58c84207300754ebbe64962979d3a50f4365fd5ba5edbeb952997f9c30e66382d49a272a510286bb6618157ec8738bebd6a28501eca8970dae24c9b9429e09b4c1ad0b04729590035474252fc796287c408165d41e7b4ea569c052f10c7e528f6be133707becdcda1cd42f094e25576b87dce8174f3722261c2725dbd45512aa6236fabc5af885cbc8aa7f8ea7f934178b4b2b09866bad6e7e87f295d0fbe2d8c933b7a3a87c50d221699dc9325ddd019e16602219ed48653f084adf839df3e6b149825bfd34166b32903b93c63df249687f21fde55c1e2654d29a9e33b6c45f1c05d0bdcb515f5b7c1cb9da1847faa7c44fc3e0b40db87f1ab360a6ff15278ec50e139e53aecd6e1dd201a51ab879fe3ee1dbfb4e2560bb30e2a34886d16d39e2f053885b564a711e87ba628ea0822d7e75de119a8f719cca28bcea7f7530c635ada374f1e0a5331607264b1fd852ffea3711fdcf9686f471a740c58f33ea46a431281a4505060559bb973267773c507abf60b614fe1519e75cd08501a430a55df1930d743fd7246741be3361bc5de37252e997c93c3561eceee1fd35420a2010db8abf129a0dcf214fb1704f60e2cd59bcddbbfe9136299c3587155d462a55964fff39cd5a375a36307c4cfca5abc1b6724230a2b4c5a594175063e7a612d2d9a406d4ec75528897716a5adf287cc31595f8be525e46fb67d4c228e5da5927c252200752de8957350da578cc247d8fb17011587aa8369b3f51d10d5c12f83d222f5309f1cde1aada9d1ec6228982c2ef9204bc3120e2aa362df2357a15fff49b54a1c11ce6fee781379c949a2216bdd021f82e716c60c2091c01e8cd13333162685ae5be323c3c76146658f7ca67eca90d5e4cb3328ee31d89cc621eb098f1cdcadb64d76ba78b2e7ebb2845c542ab9765f1573317bb7f091d20071a68393b1bba1bb2b0b38775847ee7e71921d764f6e57e2ad9c2e71dc246790be894c7a1add9eab95b54c6623820d4bc78ca992babbc3bc4b41f1291aee51d3c4c466f708b69b727e0436df3c076173c86612cc255cf0ff14a9782de6c24ac0b101b2c16471cefcfb127372fa09b6ddbe5f77e2bd3f47fcdc15b4e70cfc2458bd35839b846a73ec10ebefeefb321e75426d7d14e4f5cade5bcc1d9e71b8df569d6c4b5212172c7ebadd93d525f3ab5c80fc0053784048d2ec6ef0b30ddf37e730a39f7974ea386d9cf35ab674a6bab0cfba278b42c998551fa98262fa3a1bcbd93ef0b965cd253456dbedb3a77c6f2d61d811c58c7aeda71c2b1b8c7ac18edd32a99e7519cfef89e8a146373ae02efd966da667c52e799dbf29aae551fcd758d62d9653055e7fa08f7078c46843f8fda40400e581b9b031e243964f7bf95e647cc856f7232eb595cf9c3cf4e91e8ffda498e471d4eec5b6ee8d049af8d2990b4d0fc3a1a156590881165a56921a74e884234563c7426877dd3240db708927cb1fbd60d8f8b73cdbe50a824ca1b5ceb8842e2349de6b48db67c26a854de120d2e4d135901929f3e992ef23e4ea6f9b58dd2796b9e172f96f26dcf36aa9947953c4653c13b7cdfe90a10ba21c34986efcb0597289089632e1783091191d3fdc0dbef5fdb985a36afa199fa69f80ef6f9d6cda2c443d2098d4c8573b4a02dedc49c10122e28dbca39509b897d339edd7a4d8f4f150a08c40b66ff4bb9481ee96df0b026b822a9b3b0ef0f7d6a6c19b9859e066b90cbe322b1ad1514df66f6f7f37dac4322dc1c0400fa843ed5096493e31c425f6cd2e96a195ded9ec4fbe9528166fe9faccb33bbfdbf2609264de4dcc941f2f18b50e0ab5ec5cbef5aa577026d0dc26f44c77470318f329defced70e145935fc7267d67da9cab383292f68d14fb75ed3fe36d7850455b8d216e1b23abc6294b1840e61c5a7dd8d4607fd8033585345ef138d68ec6288391e7185ce0557640465cbef728c1cc19aee403c654aba6cb1a3ab5eda561365a84d629bbccc3ac030565c909e18c6fbd2eee14f36618d91490c20f24b50a55a17ecba9c9b428619847db6f052d8e60d76311a3dd442d9b7c2c87c56f5678ea03ed4cdb4bb5c3cbf9cc27f6c15541ba753dbe68d35c398388f1effcb3a8ad40defe07cffc493e54ecefec14bb4c0ac5de022fecffc43e5b01b6893d06a105a8973e6acc00f5e5911ea52cdebf73d4ff7c85a74a83515047b519e1c7dcfc6980741ff4e421e4eca82f7ca00e98695d4cabed1db8c51a93bb742822affb07459c39b1b93016a1e8960f66ce53b10821fd44817d1e1e1eb38872e2ae11eb31c43e194f3d73683c8bee1b89e00396f864e96925fb09b3ac4dfc81ddf159759972b8bcb1e36ab390bda3ed8b768208f38ca4bc27a848bd7d840a4942658eababca204e1100068736b11d6010a2eae8ada74b5420f1f9ac86bb81759d007dced8dd73b71b81065eade9c5303b3992d58962f48e6eafc2ad601aea14419d3e677ba01c6898355558811f6cb38807bbabbb1204d517741738b619fda41f340aa9c3e9eb324fede2864c74ef83b5707f7407a3714fa6f594f274bcb7b69bf0a155914df4e9b88244c4a7a8ea70024d427e9490de5d4c3fd875a34c2473bf4946b2dd5492190ea5926dc39564062f4ac860a2d466626e9a70aa586a3b0413e7dbab4c2d246dc8679f14e7f349af5259b6b4596cd0c36aa852d193bc2972df6ad4accb920ea85ec47c0aa8de9962a5fa3904cd56d93ba5c77b9247184e9b6542c18a61379bb0d296afb43ae528a84d94204be90ed601bfee2a9f5a0cc3912a7a7487ddf8ec2b4574943ec846370a55b738ea55350a164b48a16e0905aad089093d662272936cf6a18f5b866fdb88fa2e07e1261e09b17c0aa47a8d215e2a31316994c0568198afc0c22f083934740a003a4a4de90039f810acc6cd8b3c9e98b847a1ecb5496512b09e9173611c83b6f7c9a59d06348e85ce44891918590e7e4056938622542cef81b3d718da74a862a465b1a6da06b66535f6e4ed0fe321c6b668e5abd6f42ad24ef33bb8e74ba0015ecac8cc35c57c057920ba446e04f137890f89aceb5ba081090f011e615006048460dd9e22628148fe438e671fa267917b7922751ab62eccb4aa0d10299f0519cdc2e2c11dd22e5a150b16c5014f0a588cc1a115668133efdab9d32bb3ddfc13ca62dc697a82556ed9c0a36b63db3e3da42b276f6a2737828f69255b8732b65700e5fdbd36c4585707b2711d0838f2e0b14cf891d976ab4f16e051bef08d746ef939c9bdb944b104339dbe702cb672bb078d18778f953edb891bffea6cd9ca186d864e201029ea005d78a29cda729503c58aa41e4a681b13996aae4a19e29271a84d68d310b3b1a7f6a7644b837d97a76e3479ee9c455b2555ee3aa96c6d0728b626e8edf8a0c015e4223fd5f17b162ea00c56632c191b965af3544383c5f7d3e5f23bbdf1b567c4dfe2687a517ab1806d79c5877618405c5a812ece46b6c214eb1ab5ecd297aa2e084bb22d3c78159161674933f40c3a3049cf5c0d83afb5635ca5f5cd79ee5c04336ec45f6362bcfd1408c374c3c2dfd164d8aaaf5b15f4c3e5d50e6c2436fc5b59ca252f42a01a66928c1d339f40a6feb8c21cd58bb27beadbf3892b97dff3dd6c9b5ebd37ed953fe7901f17ef2df69ba8d363fc1143b49f1a9a62ce3fd4754b84035fa14a96e5ca2f24a18aabef97b79972830f538c8621d7fc79d536464702689748ebe6d750a5cfad6562d6178a1db88edaa1bc61a84a48197f5694ae18635822a0704ae50f7378e28fd20a2e4bc85e2a8f808768ee4d1013d7de5dc29b566fc5c660b875b45a2b751799ae6d0ccea57c8a599318a7b139c9bc0e4945286acd9ab48d28ecbb6662737d07451387d8518aa8922285c89a8ba229bd8be7597812ccd1c8c534c0897f43ad418868a3eb86618b7ec2910f279ece530d992be964e60496f3ccff4bc5f2479f2fc4fd9363d49c28aeda5e36cccdbff22f27cb48f0fa99d3dbf57914c2628336aa9350b69b142edc572dba6adf2a2e4f2a21a939011d9cb5124689161ca1c478a31e9887988d8ef4e444203e8740d36d06cf10f70010319b8c326f4746b1f7ca0d40b7bdbe298f40c611758257b12f93fcfcf31673fe8203bd53b52a89c26f3418244ddc4e0a2a501e203b5144199204a3f4cf0c01f6c5fc2160b535d80dc04638c7c4075bee23cf39407b4d2e81406f5272b48e7a008657f19889b42277c3ed16916671ec0ca239ab2ddab90294229d3a18078e9e78d9a9050ba25190379095ae0ef2b3c115488845a712da46e6c6e8bacf8a3a9d717e58aafbe1ca9b0abc6e25b64ecc6cf52d8fdc02337670c6a5d02d7e60675161c29dfbb2130a9916e3882b27b9ddf2e04c987510a793095ca28fb60cfd17714c3a72711fadc9d74db5ed5f356c6964e35ef9f0f7f607c119de3367f844923e7996f1609cfd410bc5f79f2114a5b7717d7f8e88b57877be65281322ed29ce9d27dce14478749aea7cc732edf33d878ec88802def08faadd3e594f0d62e06bccdff58e24e26d64e49d752622877ecddb56e9a1953822aa38ef077304fe854aa86c52de17a8c272372352b3a720998aafe7a5cbe20d691afb566e3604b430451f6e21062f9f6aa84144909411f63d1731ebee5cf8ad9c365164224397f09d413a6f73be0654887eb9b64c9e7dcd5994e5591b6c997af8192c909d7583ee3a60d80fd7b57aa41fbc81dc4a4c87abee85264704d935b0eec022bdcf1bf34ffa2f0f8c191cc18b50d9c4a79c879979ec244f209804fd8d3b1ee57886df480dd64202825965af6eec29c3458c26f89bf717eb5b9c49d48a7c0af236cc8e4a097b0b22cb501a0f4bd40c2e18796c0f9bc12c56390759dc2d7dd2ddebbbb00a5181483e38495d7e8739bb156ed7f82df057ff77bbc44523641015276ed72d08c90df549bea4930cd6eee3d942c71fddb932dc0df00c3f8f694adfa2b9c3c6203dc5e5d8605af112fe6e69976ca5147908017016e4b74c75e83fa93918482528bd2742ad386c0e4ea861cf7a4a53381294753acb91912feb5e30624e5e905b7149f4f0ba076d33d350e25072c39eb2488419c0113795809e8270ce59ae7aedf80eb6b9047aa678a5605005cfd117dc75f239fc9281783bb83a92defae47ca1c39e779795097ee3d4a284e7940b1d1ebf801d6b274f15b9c89700b4654959941674c315e4d7115fcd040091e29c7d2b1865f4dc6ea766a27cce5fe6d6e59e00675be12b5ec13eb9bbb90869df96834001507fe59488a9eb6e4a9c17540be294df2da5714782ce5628246b11603cb361b43c1035d9c0248bc5c346dfe6b489f3be3fa94f90666fa5ceddcfb6d91a13375ca88a0b926cadab6e3f6b2bb62dadcd2d0080fc2334a54eab9b898d564d6e099e1ff5d25dd5970cf0a9dc87c232c1e6f76d5c393edcecaca58a9282aa974191430bc79d1a5d9cd256ae906dcb5ef0b4d171a65c1bd92211f80ca9a86b1dc48f171cc4b33ddbb0c5214578581ca62f53d825576620f80ac2d76cc9f5f77f4189c9f43d0ef03db2f9f802e09249c564631d7b81066bf8187cb51af1933264a1628ce817cb12cd364657957472981e07d73e11340851c429c6ac8e24752f14673a2074f61e03a0d889fbf4eb1cc9124f9b6d2a7ffe09f5de6db09632894d9eeea8cfa68698e83eb592e4ba84c85ef47bfb6bfacadc0891fcfc9a498488e5c2a16668292be787e031c597eb72d030d398c5849eea88357b77d803dfa4363050d3f8cdf6394074427bec7f5b3519539a46152144c038ea2fa55dc66bc3177ab3e794a00603838221dceb97e4ff805bca29b8b4c6a4d3cd60c37e77c60358f3fab3e9ee061fdadd786179bf3b1cc7a1a81981fd0bf5ffc9efe78e72fdcdd15b288b8a706f53b2481407ad23f0231235cb92cd4f1024a616afb673d0bd88dae75fd0377159b2bc7df00bc0b366eb693063fb78442a1277ae814afc5462f1fa72c5b67537b891bcb512fb5830561f8481ec9f3de298dcd3f9100e90dba42d92771e8eb54a05be934d27691c97bc60a7c849f6ff453d4426f282ce71705656229de823d0d9c8dc73dc8ebdece3ef0dce10f558acc98cc0075dc4d74b7d7d8fca7fecbe541ddeef50dec60d7d624a17d75d2cdd5d9526f5b5f47e8fce69b7203b735d1f6b82043bdff72dd743508198547f62fbe2507ebd7da3cec39158af8bc0ea548de94a844f5e5c5b5990817d97dbca3578a994383070e033143cc684e72cd3494a9414c48f3f4ef26a212b3e974d390522a3e28933d5a6e66980d2b6e2ba785a23470a9290eac78588950ebe04b24ac592beb74d1d39cbe729106c94f9deacd22a09d1f99d29c813eb1f9eacef66b89bc10122527c967138042f119914070b0ad97aec9f888e5725396e091aa9271e3065d4664fcf8f984a683bc8a7854c8142fd754103ce06b63452c6cf76f325975f1b8b725f7f845589ab258a6bdfdcacd34e4b5f9ed9dc6f70d92da797c0ae99cc3c817d30446f4b2a62f7d7c49b1c82948cc8a11e4cc2c1d0face126b805a871ed3ae22ae194982a73e0b5bae7c7ad62e2ea11ab6538e0fa6ab54dbac228fbc5ad6a27964b9c2591d117f22ea3ff202cf08f145d6b346d2eb6613f7471bafa3bc8e160a536bcbd231c80566852c7439720d66f61034a9b8f9114e7598057a21c35e613deb51c3958ae19ed4da3f63a014866dc41a0d2b6eac378685a37dbd914035a2342bfa9063e7cf6862e4d13d7d9b4091a752bdcda4c89bf2a7160427810a6830224884276b48d3997b62dcc8b8b2463815d266ac3cb6032f7fe43c360efbb9622c6e29efa02cadd1c1918a481e1dc0229ab791233203d6185f8482b1722c8ac220ef3575d49b60054671ac6d91c078d2b70f272eb822a484c18d58bfb09ac4914ae57f2daf90889466c1954bab88e058da04a1746713a48fddc248e144dee67d680e687c5e171e8eee1da6db8d1c2967565a2c43ab4c4a14a87df4084f54fe548a2c710f437ae83a11acecfe6852d0064102d867146109f777a15239e4d42e0cef7a8662658ff0624fd2a0e6e80cbe935e964051f9dea4e1b31d410a62fa5ad3256d92023eb08ce2371643688ff1da9ae9e162457ef6fabc72b5a8e60eb8924dcd8c5ce939aab4906bc73bf40920007aef745a855d1560d19f076334c4eb1d53b2952359ec95f5ece3af0704ac4786c805e28ceff1d0ed7bda976c6efca80ab6ee5c083f20a2b603e1287da938d5440344af33236c5bbe471793303aa265216029c7fb98bba7ec413107ee29bc4aa31b9c6d6d749ef4773f1b2a48fa974cc1a7a0b930583d149f71fab4e4e17781315c67ab0b8f1034c44f306f543683574cd9682930b09c7d808a5d74d64640d4e2ac250dd1f3b5f4b5115a7d1e86926b79061ba1bfa310d4deced9237d9003d0e48014577e45e990d6fc9a1911c974f3a04f3112f509f2265c227f48f212285cdc338fe7b82bf5380ff5880d1aba22cb092018c03f5a7b952ce21f472e3bacbdddf0cf457a16c9612a1bfa932e642361070640e6b12c54244f3b8c3b6b1073ea2fb6e475cf65314e649750fab54e1780f4d6eb59c3f5dba8c8236926a4a09d072c9a72d1465d904e6ed90de9ac6a2e57272711c2344c9b27b840606f3f2cf926ee4f696f67d8b75e498261a4627e2f4249499ff03ad832334a81304514a9f28d2f34482c0396469ca594d724fe7fa85eb9f3ff9da03d8fb03eab7091d6fdf930bcdb31e2b37dd7634f3202980b5d632139e7763c9426790105cbc4c5f5c47040e95670186c37d1499ef794263d57f3c33ad21651c42db3ea96d71bd412c432df0b2e04b9c9264db4732d0f1ee74364f5256163dce9b9e8d51a32676aefc85299237a79960acc47ed77532ea35b35c13d2061b9718e5058e84794f11eef6e3807d395bb1818f6b7e32ac2d4d3ba878e6cc1b208a6bc50dcd5dce2ffea1a5b1fa9668dd6d737eca8f831b4578e00e23cbc697376fd9f4a4f8236e07d5e6f20acb8fd568fde85065ab8d09d649ba6aa8a2e4581d8b7bed7e25484e39e8fb2cb0ea8c57819715795096aa9aa9566a84422e16ad7230c195cc3b2064a1cd49e1cccde6bd44e5a3164e1e8899ddbc95f439aa395f58cb2f2daf5b01ab0d8f35c81037c1c2167557dc29d71f2a72c96899b05096e06eb88bc1f816f0025dce9bf9c3e4d6b26356df9e054ae8496e6404bd84417ef27f76eca9bb7c3666b77cf1b7d2103a467c276f79e4e08619bf50cdea784660e20d6396b7a9b67b6955cb9088204ac5fa1817e25144944862bf95079cd42ef714e5c9b0fc1100786e5063d0c17c1bfd2b6b62675b67904c75463a3ab0539081bdb0413d2a2ced21f0a4441752cdccd9001153e7a3edf9280bdd82d68fe76f62ab1bce451a41acc8c0031a81c53f0cadf486edf87bf85e9eb0ea698335e61b912a3e6c435ece9eb07dc472a625481286531511652c85782fde813c3f7dfab6d8d84f0f45c0aa25349564da062242cd3e74f553ba7570a27319a29752dde5782cd271191d9335a22c69c000a0a52860c20d6d5f3ec7b9021b32be214b69f815e3a88de4bc1a5e87fc6f893c01047297c4351f6b25f07ee571bbf0a43b5fc8ca990158d600723065d96ceac02c73f19a1f896b127f8f4ed47799f64f8decabd6b5f11f449d9a2f94e86a37ae03a6857747282ee45541fbc745a1a06931c1b138a14fa6a07d5bf2777b91dfc83ea019fbbc77befcd1ae2a72fb54c1e76bfd4c768f881a51b502c135429d84198cd3dd3afa5770a459b301f9846614aed11f25639df16556e943ed13656a45bd2cba5f14cc1aad0abd037499dd732be8008c6729aebf90605f210ae7c845d6c6f216651781af85bb483f1eac0dd5968e4c5397e04d028f33b0c4ef1936b398446afb4ef5f73bd6e7058b5c0030f7c21570bef9fa59487202c0042f5610a81431f9980d1ce17836d4443e1f751c0b033daa2931275964f202a6d957f7a93d43664c6a351d5a47bf055b3ae88d0b544afa9ecceacc08bdcc6cd82a91a46566387324bb3f1e72aedc17781019ae34c7abd2bf11b19dbe780f441df714c92bdbf506cda09fdf177cc47034c93731c353032e6033d466d39aac1d8b754067f474dcdcbd0a85d70caf233fbc7440327e4bc182e7a949e5dc850390911156a882ceba6684cb728a786bed9c01cf045dd40fbf0f0c994dbaf766fa0dd64fcd717af737c6467afa2415c7d86fd5b73b02633185b6f9fe24f8c0e94361e21203f16baca213e6dfc779242faae849f2efe4d9ec7e0730a53b5a21991824a6e1b40e52044e23fbe40924f44fbf23d9ee30cf42d7bcdd6a7ffc5d2f7284f8110ff52251281410f89ac2a2b415c36f3efec5d68adadc145e097c7acec156f6c0a7a238dbd2076907cd164f955634a39f23d7c0cc03e2e7e1254a10252be74af4a2c1bd8189e74a8b9f70fd0d66b81a31c0ae669a2ba0a5f8658a18fb78fcc55e02fef35e92a2f47fc7db39866317e5a4daf0401b0080ad0876a809e5d3cd76c44dedbd8bbe252d89660fc3bf3c259218b004d8ab9f4d5605a925cb963645d0f5ee87f25efe9f017fcf9e8321d24244db966e02f679dbdd182f17f601f9910daa69d29218ea5fbda2581c692b6f4d8579253577c6f7447c303c5d62e0e72cc500d539aedbbaeb99cbcf77bdd3deaf1c465a0ee2f2c7426ee19b2012117500faf25992f2aed5c1ef292ec7ec3939d6f58884f494163d663511872e628c1c1261be5d11bcea62533d9a2424ebc13be64b1c8c929e40377ecf83bc7c3ddf849391e40185e740705a9cac5f834729088f0efa68556aabe1dd5cf10daa0fa9bc1eb7b391678fd8d2a42cf3de69450fc436db3be089b53ebe363193e2e0ac5179a46c72d079146e1b00f4d236f0931ae256c50c82f804b66227ae25458a5e4b55fe1d660f1603e73deb879bc46bbbf3384844941cabb7413b93cbb328ec6e54dc7b8c94f91a4aabffa1659af909b78f1e1a5255df44593d630b2ceb2956190f4b0208393cf99b05d6411035e9739f7f8aa9306d18e928d37c4afefce3a410cdefe16bc46156220b549a3deba90926cff84a4cfef950f008d4bd1d6ada0831c2b8f59b203a7c8927673eff909b78bbd8f6a9abc9fdf8d3ac994f76435d4ec32f670fefac236b338e5e79cf03f67b12a7120db4c012c1e2233b6ebce5adba2af9149c3a5877a1a3426403ddf436d38cc5004dcaa4154d020c0d51c2c4aab65c0b669973f0b50b1aa84b8ab0540a8eac199b7799d54827e0af6987499df3cb8d3c9a91de5079b0ba836d0fa5ae652029ad0303347a99ad41cd503e10f9e8991a0228420dcea9a1a8e3c112c3df14808dc532ef34ddf15b236685e99291f8cc34bedbd5c8b3a44b1de0b949a6c4c6ea5a195d37b47967897bd609f0cb93d5f70de11d53559320737cd4592a8768279566686d2e698fb692205eb4f7b40a766b908754e8af50d96ed0f772ec9c35e10c2a32953211e213d84510eefafcb2ac0878d0589a0b01babb5f0024f322f5e554584ba935a4b3322613154dc04459d13ea8bd4941392f7ff1d60a046a9f3eaad447ee088a4a6e5db9d13a71f4a94078386ffa5bca14e8ba64d6dd96ae7596dd4adbb830e2c1ea530493709d9ae7290a5c207ab54e99a456d6325cfd99260602963813673b4c70b087a7eeb6755839e5f4ee24bace87969b4d3766d0adbec11bd102645629ceb32ecddc3571ee2b59198a26bf35bfd002d2d1960f466b17559263438b1994b9b33e2be6a707256993818eeffd898900becf40b7559eeee02ae08545ce8516f88de022b1c53919d725b41722aec50249789aa2860a016f26ddd15f1641495041e9d4d89a298d3217ea91274a0f3dd782d5d187538ce8142e17adb7f8b833b05dc3e017d6a96fcc8d65231a613e454eb58aef5e87712673545452928b2ff7792dd2926ded68aec7a8150c32bf8ef40f8abddc3ff09e760f2e1bb47b909112c792d4bf366de920ef847655264d9b7cc893b46677dcd37d3b79da14380e5a70e0bb88b7fa7fa2ec93962c8dcd216e9c3722377e1f50260ba20637ff0fff9f9aeb754aced500aad071a756cb9814ba53dc4b016735bfde1786c80a4591560cedcc424746b87399110f424c5bd08ec04ff75dada842cda12f45621b34d924cf9da5b21c334cd70d9340ff6dfe2fafee6ca4c1c632e6b07a5037f4a13076ac0fb1344fd59d5d07c9119ff530205214ee61345734266c1b7c969359af5a8e4d3e46efb4ef778460da333c8dc54ad5b78ecf721b249ff8c442617f9a3f1eb60e597b8fce7f50963d33240f0a9f206f7c0b3222cdc2cc0b46bddc70d440dcbdbd80a477a59b0c17266b00183e805cdc9aefe45ba3c04d4ba36c68e3ac86fa4ffc96f4415f2b59515fb011c8bc4a49ffe2ca506ca16135009fac16557fb4aaefa2a4a972472277b4e07df966cf7e4163901138a3fd835b8c8dead1e264b7a947d143219b1ff8dbdfad8d3c21f489d707e7dddb221bd1bf7869f2d77aa7ef27c525f697832e7f760c532f897ea7b26c089b0561207653891c93431641d394202fe124812f91b6b3fc39edafa59be1ff7c35b61a7f5f7be6c560a272cdcaa2b0cdbd3fb3569f609d7160c7ece89e3f4935f0671847555e69f70248f8d80fd2821ac3690bea8492e3ececdef0743580c5fdd4fea210240b7532df856dfa2fae9bcd6a5d62205c0560d967d3262202095c5ce637abf2238e72a7d983d2654dec7c9297f64aea390e3678190f971bb1c67e39326b03aac859c2ec767ac634217d8b581c9bca918975ab50d3d15c96df2767e6a922d1c99c39b3e3c0e0456850f4994d1ec9da2dbf3f4a5162a2465e0a96996ae95121e69ea5b28a884bc67fa950bc2ea6816d96b3a348c461ed8397bcac0a320e520fa7e5cfe780bcbfee471d1df3bf257db908b68e6e9db405bf29fb92bcbffd37abb104ba324ada8ad259dba1d8c29f33aff1d4e934f27e44012a9f4a1f5dbefff248c7b2a01946212acfd0efa7a2d4bd8e3020a41403feb603d8d4e1f46f3bb9fd54cb5ec0b599c4dc5ab3731874c11a3b42f2ec468f68015afcddc46b2058689022861604cb49ea5ca507309c76d8cbde21bc10e83a8db166a44dbb6854d8aaaf67871a9c0dce163198f7b8e40154025d305ba318b5f46dce6cb580030b7042f21b612563c907cb3f2144d152f502aa75ac7aac7353c2c75477dbf936be288f84444fdaca0aa48d52d5e6ddd63aa66014bf82099e479577672383577a9eadd98a8739a56f5cc3e653b4250f4712c7ec4b2ab546df1882bab15a80bb9dffe2a380d4e129dbb9366da2429a56aa6265e16c1d0d849f894186f43ed4143d7411c315f0b906b8cf4c19a6a88fd1920e3d20dc4cd516ade2d0d06e8377dae11704b01c64ecddf554ac30dee86cef0c35268e656b5fd70d1a97a89e861a0da5f571255c8fac26cd81d609c5080348298c981db34aa20f86ec719de5dd7ce6d5d3feb8667a709e20c67b00e06e7623ca67202975e074561ec8b0d966d5d1375ce4bbbdb860197e7f2068901765804e3ae4444c0f7261489d4b4a2ab3515e31b09db7005de4040c5360a6f9996cd6bc0eb73be298d31c2387164a5c4b6401d3ac3dce074fd281d26e31f854fadbcb87c315cab1a32532b59c80e587253492a857816716178a61cb01a06db86be96e205bc92a6d4c3db09fd173e08071e10c106d83d8fb75fb07c3925921dc41feb91e38a411aa8fbf51f8313dc2cabedb4a3d780a17c74d6ddef0c44c3db01c70c37288ca159507928376e78550a4f3df8409be531945d4b652743cea183a631f09bc7854c1cfa426a4b9dd03a7a2fa05089306820d47f7863eac8144f401414c816e07474a08d72e680a9b4f335ff29a23ff49f7fb8e6718b01cd93219bca50ef2bfee4ade8271dedd8f3e8e809fa097caad7d9ecaafbdf71343f111263c426bcd4d24246e05d4f9361fc2dc59fbabf053ec108c848828aff67d5e796d659db5ecde1618f0574430920ac913f1c4038c8c462dbd5b6e0f5ccdd84e5d2ad72cf306ab3ccf2c66df37e113d9fa568284594ba8b2a51378c778740dd1ce08da42769f14e139cee7ae01de21b0f3b5144ec3f45f3970bf647d9a5a565b454e8a69b7cd9345cf7c81185d7753bdfcf228502dce88d0b21cdc6568b50fb26738431833f15a067f12807df96316d51296865877ea6f8c8d979d91481fa47a6fb6c4c3c3dd6ba1424564b9c9f1112a85f87af054182abe753cfb2e1e2fd16ce4a71d5cec242ffa2941e6ffa44ed55b305176a9fb04a3e2d99c8960102543064a922eced19c59c12acec80b0f544cb36c3debefbe8cee3a940af1d319c5dbc48f6cc0da1e56a648715758164744820dc909a07ece602eaf70d675c40961571c63a21aa47b283321ce33858db83b73c827ca0531fed88c6a3240f41e15bdef31b42b3877f1aa001147031e974a62460dca0339896c71f691eed1fea00785cc6d22da22d3c8248aadffdee77f9d1d55e5ab2b27b4b29a50cf2064c06e905e3026a8a64a1880ec492d8818d2e1cf1010a27b0200821f2ec074b002106583cd1c40d5c6658b051821656e0440e8a4c0817a4808328f48022004546a0032cf83004082552a32da34822a6031f80408a16d41e40218915b15790298858552b3c4136031f58680215590040083f1421a7074d14b962659ff7f7bd5b4d0a15685a9723536badd11a5da748235057727997a0b1d6342cd0a8298c2d4b4344eb1b18a002cd45bba0d068321b9a8d868686868606f5636c591a7be3424343c3d17434de358a519bcb68349d43ce040535e93d8882a286ce943318a36a6a2f4880fef0344609d9861084080bcd8c0b8d46e350861072efbd3b8e50a2c3814eb9427b41e0d8d8b2b51a0f2cecae5c24dc28d20bc5ddf18a55817b48c2cdc2de2ca4f7d5de29a43435406438b0681441c6c282a291e1189691d1c233e9fdd8f9ae52723c73553c57c52434d9a58b42b1a0e0172e71696a351a6d66a3bd525ec0525774c705b098cc0b4cb3039f45bbc1a9bdb85a080d8746a3d1683a9a80d950c4088d8d0c088e5aade6d56ab55aadb6033d96474d50b4208bd5645c33359a5a4dcdf36a59f052b230b66c4d56691facc6be761ca1048f942b803caf9605ad5123d0a00eddc00015682e2e1506aac4d8b235584c6686a6c613e19a2fa6bb0d107282d07a1e6c882e8c29990d6ccb604ac59acd66aa22a1f7725f1091928562a7c4c66636b3b0f1a910fc30ca094ea44a1bb1336304ef09d19245a4486a8b3bfcbcec79b021bc141e63cbc260f6870c6c23ad806532f0870f8d69357526a603a3502d08b91bd76d5c873241109c9b2be4122982516480ca42085ac48546a3712d10a853049961061e41ae917b45eb8a9dab94fcfe1eb9575418f0553ca367cc17a50a37f8795d128d725bc6f93d14115bc6df8d591c1b998c08402c88c6f2c6757a861c594d8623bb91d18c20a244dc5a6bed1851f2e288114dc2831204931419a07052aa00a158918324c97ded08a16468ba044530213aa0c3d3e163b4322b63dd1c994c76042cb3c875059fa647dc96b92da37400735b26c96432d98d5d2032ac7265eec5375683b1656547649b2ccbb04c66714c1492582c168b7925cf9bc5a228c20764324f4683b155733cac9283d67e63318caf0dbe337c69d7ab265777297004bbbd72d7afd17d3b61b677d7278c8f16987af4bf79ad794f9306f7ed2ddcbbebf3657ba7ff726356370040185d3874a8585638b0dbc6eaae258203a374649a9d5d34c68e9165f78bbdf786f626df6e065a6f9b4c121a0663cbcac8589421cc2e6a04a70cf996ff6b2239e7bf8d610bc35b4a125a6f9b466df09f4811235d0c8404d410282b9ec005245040f0c24504ca04aa0a1414d021293359101b9619b1d8b7478c3a9a52d92de32d632cee96b1f53ca3db715bc76d283ab83877dc56b10d97e65c6ac6968d0591e98ea3d1689e8b0b1017ac623b6e8bd5c656a5c15c6c68b41b9a6b8bc5625e2c16ab1895e2c3d8b2319b188ec5b6588ed1622e7a3cedda23698aab952598814531725380f042eb171855cb9e97228087ae606ca52a6043a76c64b4adf44a1a8cadd40b8d673e2f244b2e5e709e972240e995468cad544be710d3a954ea05ce4dee405ba40481b241b149914931012a04e591f2044a86524418da1429a044606140516296d12c6c2f5e1c8792c5d8b2ae1e31144539d4a2d885c5489259739c0b97ed81246b30b6ac2b6f317288d484dca03875d12148e4d822ae6b3240a7a9c9c48b1220b9819fb3901acec1d66561164dc1e5b81d45702922185b764759ce80b7ed6cd5d91704aa4545511445511fc62b436dd0d935d2750780a1a26887ca8c57453f77ef324ab3a14150b6e8baee0858d7e9c8a24bd9a2446f542d458c1c418276a9111233b40aa5ffffa9705184d0e36c870cca132c33acab0d164e9555578c2d1b7302c7f008e4a23081a130661424b6142ab45e71e142bb00c2d852c176e0c462319b581021448a745acf2c9182582ca6c5d852e1a0c2365a6b9408a34aa562c136866318c7b075e28644041415366567b646a72c0d46a146d0e0e88b5a8153689051176c445002092bdb70342c4021c1d8b234ad739b0d980bcbd0ad02468e2049d2953b40c9c0ce90c964b21b3336168ce2c18590990b169b19c6287b7d517ea8d509194ea69391c96e79334a0c36942470a81274e81150a0982579edf050293e540f4014242f1fbe402693b9b04c8fa24c26636161b919736091c96e3a55d7298c2d2b2393419f4bb4ce38638d8e20888d10169b998bfb999046adb512c6969541ab8cadbcf1d40a60c48b10f0a0019fc1cf9623536b5d051b21b3a3a0ac0a8c22c165aff23d0504ad394d399333ca0e80e47c5f4e16fff72b8c2d9bf39aa3a98af64e952a73a84da752a95098a0fa0124bc99d4a82d64e0931795bd22f00f27d2d633cd5793e600c9f9506a25204e5c19b85457364d33da590f95aaa552a9542a153844980ac7b7302b6369422cc224fcc118d72e778370a5b35cf31ef4ba22b779b7d2c6b1618c4b275fa374f284f101737ae935cc834e18d3cd83a00df336699c0e7a0dd3c92bd210ee9383fbb7a2154d1aa783ee623af9bded2a6fd64bf4d0aba8cf9dec17e8a5cddc360e638c31c618e38dc318637c8c31c618731963fc123e087bf87c0e7d9add9feb4533c6f82718dfe2a830f0636031d68be6d0d727777d7d561dccee649dfc86ba3a39cdeea09f984e1ee6749add4f5e3afd74c298344e5e7acbc9699ebcae402fbdc574f3a6d3ecce1c3adc5057a6e7a0419f65bae99d26f91aa09f9c303e5a40af41fee427e70b0696204212245cae15f9ba226f9e7c5d65d6eb45bae8afd143e7368e77f85cbe68893b57751522edf1a35df2cffe5e6ecf45bbf3d0160fdae1c90d7e3359a109e9f994742e86075719ebc028dc29193df81fce1877d7240960beab978fef2f20c6157920f4ca07bbc5ca077ec1522bf2408cabf233462cac227a0dd245a210e9759573ce393f944fca39e79c3f640a206955425a871c8196966f8d654994620165f0181f969ecde77c9b4f1c17addd2d7f7b1559e459ae793f7a5d91b6794f7a476e1cbb5eb433699027bd067952e830a793af11fae8843979e8a00df1bea1ae5ee545ffaeabf2e116b148bfa1ae48278c0f96e85aac5e6256a27fdb1536efc5d755c9263d7c8dd1c513e6e4a3938f0e733ae9da8205f8c0f8223df46e3b8eabf2c28d8e9a6625f24db647a4b9dbee0d1bf938e47a3303abc4b83746fe77eab4a8fcd0aed6002d94349fb45f61e41be0c7787f8f4fd32b4567b960013e30deeb5061b82e8aca2fab2d40ab93566b8056cd22cddf89a3c2c88f81c598a38a3ad450d3edddb7894f3af9936de2936430319adec92a45ac97e9a5ebd3ecee429e7497d047c7dbec4e1aa4936f193d74f0b3ebaaae46e3411bbcb94d4eda251fedcecb2d5eb4c36f264b7c4d5bc28337249576b559f026e7409bdc157b3e96bc233e7c5de9e86c8c1a3df9267b9becbaf2d415b8635c19c68f9135e3a239cf4231ddf594c0458bdb35bda9123324123219cb6c7d3d5f88e20656c92d7dafca56c3a8ee6cbd70511a491da6f7ac18d58aa1cf17692b0668c6e68a92a8892e35c05b5107979bf41ec5678ecb46c3a8fb98199e2fdc776e358cba628d1aaf22ebf3768bbea7cfda125ec7acb67333989bb92a9f1f5786ac0e21810cd78303c205e16cd2cbcdd2cb11492fb615d71a3e3c754b78ef7cf15a5c2cbd2dce955efcadc67a8167ea2c31cad636209bcc863729cef7af9563a9b7cd16efdfbff325c330ea7af556a68655f0b8e594e3b75aad8655ea6acb71c1b61a278365dc8c8c03c2cd7034780a230e72d1cb838d9fb002905518d71e9f9c4911c0eac2c510630eab68cf960d034861cc3f76d868b04f851863293e27e4cad0c73c8618bb4a7302164510c216aea8196285eb4c8916e45ce1030c5c50835f19e602709ae2bbc03357c63d8f14e35d7fbd7387cd01a72db6d0127062bc01f831e21a6c836b30106e96d617623abb51810fde329556ccc5a4bb93de2d52fc029211bfa6b5ae541fa4f8f8c75aa45e9a77ad305cf926888e196c6c6c74c76d1db769141e66a82b55db8c3636363657a75047c69695b138416c66b030e0637447462961934942eb138c2d2b837e8724afcad5c829bc80bdd0f84591d0721c870aa271f7e2ce6c55102137dd10b4070f0b03a695b68891234892749d8c073da8e96a8c185b92dc203962440a63abce2c4e4d4d4d4dcd4c470d56716109315a18f06735b49acc42efbdb3dac3d8aab3960ce9c5352c3364a82b995676458c1c614951c458e4c646cfc61a5bc322a1e83a9c4e666cd999cbced81891a5428bcac175a9808b25725d35ec72b95cb3996be6aab9726833d7cc5573cdeea6b23098a970b22b8665f04c5661d56c369bcd465d8ed7655340a0d21dcf58ea45bb6ee6011058295c2e9790b1656738b39bd9ecc6480626b1b145d6d77cde91887bed3f0f788acf505bda0d550aa7bc2e4e148a1bd7558e5a9572e9b82d451b5be30d1c9c18385aebe040e542ed86be5161a4f8606ca56433a015b158ac8bc56eb06031c66236168bc5300a75031cb2fbc2078c6283f2890e45051bda046d6190e1c0b22bbb2826c65695e5d0752c5d11a3ee6429528cad2ad3b29857ba02ac2eea0590200226f080b363e60a49a6404207862c610b3380d552698128a2004205088004a106bde20813ae60c108a4500519a18b7e2f125d3c5f7e91e82f31aba3a1db7b6dcde6dc2043e7855d5c3ac6b748702d0749f15d253ef23ddbccff4d273ffd656b5796e273a19b80fd56cd016db8b78f1bce5d57a28b3b248a62e8e7b62bd08a3444a2d0e656ecf16fb02a54a4364e483168715cf6c61ab1358be4cab8b6666f845821f663a2c2c02ab03448f15dc09d96075757f4f16954158b858ac2b656abd5bed7504d1b2674f1df30e2433f6d98fff4930d7372d3f3363578f0645d1939cd91b76fb35e2ff3a3bf482fffeda32574f1a70d237ae727db478bf8d04d1ba673d1bd5d43f4cef5a6217ae779d7085dfc0b486e0cabd45a5d11538c537c5d5825f4ceaecaf0a5fdf17cb4c797bbc4e4e35f9e9788ce8a4367c52856a7035af17390c93d5fbd2e8a6d0e465dd7855d99cfa649eb2aac599875d55257ae8962bc0b0a22c7fd0e3a55f9ecde804ef3efdec098e6b35465154cdd537a62c907eae87b6f919b4b57747c10b4c3873678d1f6f139f9b9b7c997db8a1bbfa3bfef037ae8553c4f2b1316e00323f7fb9c52c6cd5dd77598db0758b10298e1a23277ceb37b44b202c0f776d9759fdf50579f57d1e44ed6f7791676d6eb55316afbcbd260147ef7ea3cfc4b5c0161ec70b8326cdcb83272b8323c2058a504fc768ac72d2b3b553176698e9cb64afddd7bc9fbc050ec94e897a52766bb1d1e44a291bd22916734227d261f900485ac0db9900bb990036d486ef1261fefe548f46f8f407074f0229044de44f41a1ddc388c31c618638c370edf7befe5b62c02475ab38846cf2c59347261b968d7992c916824dae73d79be3ea7c909ae3c316c98c47057fc01585de85c96a06a4c479fb2247d33e4b1e7d8ca581bbb037337e1391887f1472f47ff760982e5c18f405268547e5f075382e6478e131636d3a30608776f74bce07befbd36b08a0df7da5061e003cc58b128fc6f3f91e2832a55573e0b3184fd803e2d8c3bf7d1a8bc066252d0457f910ffd58c5c20e035feeefa72a462c9248a7c99df4ba72a918d5993440b0fc7798d159e3fbe8a313a63cf3ebaaaeb61d1eb44b4eeece4db677cf1e5f451a20f8a9ab8f8907feab2b1c36384353030476c3c645f1cdcd2786bb230a3af060a8310864429222715476483997949494e81274f222d0c14d822079107991791fbeae3a5b74f035420f43074387312fba975fe14139e79c35080a3bbd5d9fa6c61a0cbb9cdf9dddbbeda63e59a0df5057a0ebe089ee629ea2bb94ce90be3e6845d3cdf3c587f797d24dded962fac9f962de942f7a4b5ba779e4366ecb18638c31c618678c4131ddeda4207bf8743aa942f7a97cf29cc567d173ce9d5c6650ce39f7c8a00d4f4e0777a9f4f0a71371c3981fbdb3617cb4981f1dc67492d9bdc667a44fa5d7e9a577b7ebb6176e5e363b68dd7667d890efbd373fe79c73de72ce2fe59fb42e1de39cf34f4e48b3cb766fbb77d650d37b7db24ea7d2351093e2b3ccee2e9f93ee527acceab4cdedfcb61dfcc96356a0f77a041f82b85c1552cd9551d39ada5c5bd50811d256adb56a12970c4f6fa9fc18a6036cbabd069b6e268df0a7b7843f9d9c2fa6d3dcfe39e9e1f5d902be74be98a7b99d6677d2f89cf416f2a3931f3d44da9d8fb6f8728f17ed92837008f4d972ce39e79c73ceb986bb9e25f25ff7408cab303c10e3aa445ef326cdc5060ed0b149c5a939a1b72cac0217c5365c2e4aebc1d231446ddae26fe9e6cb5d57a583dba411b30a7f43cc2a3c5f62562f3e5acc872fbd858755586ebbbaa29b5e45b32b99dbaba85fe0c52fe0c888593666d8e05201adb5c6a512a6c12b3f8bc2174db4debe49e0c604409a135c68cfcf39ccee64955e53f31bebf50a5df417e8a601849b0016850fae9caa183b1aa59777313fb2228bf4ed8251f8a312c68fd14589562f5a62bd481fdddc30a3832f6d181fde61480f699417bda5bce87cf1a1ff427a797db6886e3a5f46179de596376dd15b48a777b68cce8a51fa04715aae3abbaec8b0dc9d8bb6f8d01e0f32d99ed70e67b2c2102463d810735cb0988c8b2a5543c674b7a408ece5138c4daf2b0cbaf91aa59b4e18d34b374ba5c39c0e3acd5b57a53d620bc3a103b42727a449fe4d20bc8faf03ab8001e4798f5cd445c280168cad70654b4118420e8c01a72002121072360565e03a5c8a5f52a6a04ab86d9102a030b64618c26d8740352fa830ae0bac0078dc28413b62b6c306bf6290c2d80a6308b74de22820884f1aee0484db3649f130b6c66d7b64364c8690db4d7c86450fdd7c4071a3a9572952fc59256918d39254ecd8dd0479568c223f22192afa90204bb8ed4e4a7ef06fa846b4490584db16431b03c1a87bd0c6351875dfd9b8076e41858193638711b3a066269542d1e394e38ac8d81a6908b71da6e0de80dec098721c0e8e26c98b8371c273db60caed26c887fbe27c9e3eef918bba486e920668616c853384dbfe527037419edb4dbc3e0742afc87fbb09985e91f77613b071455eef2660e58afc0d8255b9381805455de1ae163723153852685df3d9dc6a5bd95d2b0c2dd227c6958c57e406a55894624f8a476e004094ab7a0d70ad605529c60448efb1aab3b5ebd40ae3ae6460406a32a0f2009576676b03a9ae30f057527bb08237bceba298e5ba90610b634bb394606c5d1c7c3f56fcb2e2d7aa2bde6e3cd79a600ad08ef5da430115bc6cfa34556b4b8f154c6b117aa8416acfd6f8440f39692b95d6cf9881ebb5f80910acf5448bf1fe448b0dec30e0129172bf35a4383d30c18b35e474bca8e6b6bcc5f0a2b0115f5f74e7eca1008f203319d8a796057fc6bd3bd54a5debedb461c81542c8118115301cc890847e91e21757463df159667cd23a84045148634832b652a92132ec5336e7946506878454db55a8b74d6f39e0a08de029b2b791e4c77e3ee14892e0e80b794a4a722ef9c1ae4c5e42e3d9e1bf0dbea4e45332da76e5d99f7f9bfcdd39b89b7a745f9f875fc09131e79c73873732fc6ce4c78ab83b599fba024db65d61f082f6f7d0f6e06d531a1b88bba18fac4a3d1f5d21180d10222489672ed05717b421c8f3d0ae2bcff779fefdf385c80fc8fbacf75917786bc77ba7695f4c6c4c4cc605b3dee78ac9b860aaba7279a830700f1685afb2aeef5a170d17b43cb85cd5e5fa8eebe78935d83447fef68fe7f3c8f3151e74d919575d11c79a32dd72b0307cffbce5fbc7e4fb76b678f79c2fa3f71c603199199a1a2032972bbb4a62b6db59e2033fb084e3fefb5e3a5f48ffbebf98311f38a3994c4f89447e20d1e8a6765d377689e0300cc3d2c7f4214dff4010bc0924430775a6cfc671792b693b9bd5a0437e0cd7b4bd7ce82fd141074dfbf4d23eb949725d4adee65c1ae04f6f01b9bf7c0e9e3b5bbe9f9c2fe43ff0a5fdddae409fd0647bf5cc2517ffea3c0441939d83a571d7a406a269963ca4f1a3a924f29c98a39378124fe2493437e8a5bc7f3a9dee398d3fb9c933764afb55fae9fbbeced7e998a792d87967344ba2288a17596e3ef9ab7453d7895eea3fa93c6ff44a4fecfcd3e6f77574e79fee68d1dca6688a62699bfb747aa9543a9d66e7fb7f69ff343bff4b3f99a7d9394d1aa79baf71f32c5814c397b298b3b9ebaaa4d3ef9adf995285608cc163ac17ed2a77b23f376d939736e8e626453be4f18c27d5d5a8a43c5f9e8fa2d163f22141a192ba2a092f09c50c0c4f55783e86abf21b38c2100441f030a787a7f9ba9ad1c07076637166345c6299c7c12a2290ad5dd78dc910c2682f8f6b67276fd51bf0e407d2c3ff303a78b26255accccc133441006dc5a1c9644166446632dba3074e0f9c1e3d34f74385818110014d1133f6a53a4055b151583b9b9daa18b78a93c3b46bf917e8a29ac62a15cfea8a98665a5dd13a47cea1ae78c7cf4055b13eea0cac48f1abed5161dcb474d35dcc9fdc8aacd3c16d67b8627cd30efb7a8158a4e184f1d19927cce860f8ee6c790e96768353cb99e1b831c399759734e2bba311c92b2973a763924025a591c8f3f067f27a7c2cd367f268bed1fe9c94f70d7515fa8915ad6832995e62ea9c80af6226ed17e9269bad052d9873ce19ccdcf54626d2e775ae37227ddff7fdd3804db792920eebf51abdf417e926f8c9bc9449750ff546aff446ad1d72386aefd401a79d065bff46dbfc4e9386c9a4b3e71a6d1c538d44329d26f8d34f4e3a4ff927a709fee4a4d169fae8354e48379da3b3601dea165b6c912405bfefd44106afae48375f6315d2f399c7d2f6dcdce349fbf3d136b9882c29e9bcdcd5aec857d12474823a25a3c7e4436eb1ae30aef9ee67096075d1caf7ad32159dacd089cf1928be86e89d13c674d1459853d5a37e4ce8a2b7049c8ea8040e5974562a333300000000040013160020180c0c044462d188384df3bce50e14000e5b7842605e4a9f0963a130888118843106190000300600030031c6100df100ed0ac815f0aff1fda3b06290da8665d962c420aa753051822e2c82aa773728a1c9887d516cf2b2c1bfb07ded7f3be5c47b9ea71b896e0d7a1f158c66eff97bda4e63b202aadcdbd5a9af86f22dcae1b02a59df923d4d42500328a2e6828c05b79d35856e6b32667c7e92463e91542cb8751c1784bf8a60148edbd9e0ae3206fffc98a93de18c811de47c1b312df4708e9ef53a7f884c8dbe2a7b10814b4952ed54eabc9a21a1cabf25ec54b2dcbd57240322070398f4e600a4be8f807ec8633e38793a1a1cc48a0befb140a054ea1ce82d942fca68ea22f781b0734b641801f41d4a4c444878753d831d78d071e3c60e5273f88ceeed9f5107757fbd34aa4a6cd4b046cdb04bffa9a005af858ac112715b042d512f40aafd1696c5a2c3c80bf98f1a5073e25b92154d786febee89007133bfb7dc904ecc3db8fbdc3a390760619c6364043cca36c00ce646c248718cc05ea19294b1b9f8f548f1f157127e36794d6ff298af7feac59a57cc8ff0640d8095003b99aaba01a9e7d152e26de8646def121f5aad71690d25e24b80aa9bf52b4a08e0c07990622e9fd88066b8512ec8fd0712664f4744a3c80b3923b48cfbc93bdadc3c2baa9ce501f9c6f4c596a77413086720970ceaef0fd6b7cd0a11ac6b4673d9d284a3b8c51765fbb5d4bfd535708e7087a3d50e3262677573f6093ccedb38a671798eff440309612d7b0d1a0ac5874c8c68c4d739bd8f50bb88000df7b9be3148ac52ece846f039490e292884ccc447a393e43f52a4675154286d9f227caa8d50f20e13daee33fcd660a5734666232921ee981b40210d39f62d9b672b2e5b5f6f4553d9f91441db46cb1b066412fcf6f3165c58f4163c22f516743b76f81c11fc9e76199a4b40d198178e9fcf76f04a8bd5ad28736192a0047465676c4c64ff56e633ed14d800a8beb6f64868039c12e204e34fe647368091d6c8d31f269a0b0c7a8d13eb687cfebba644acbedc1d02341dda169843db79e4d0e6d83f29c5a7dcdf97a424435b56fbb8479ac2bebd9f385d6057ff1a8fc34e153972102cc72f9ab7643638642d9f9afa49c0f82d95444922721ac1b3c724a1034fb7b328a51561c5d4270d0240c390cda74439e9cd17bc3c9f8a936d60eedb8f1d896ce34c5ea09211d5cf98b801d59ed29d4858a8d8525afc240de92b4c9ba45029f9f26b132a559682098f844adbc5384854c46b4391bd09147b760a3775382f9758c34cc82dcd5f14c5be5b75df4239d6dd5f1caec614442eb1326d2e470086a97817f7edc830f1e91c3ea42c2ea285127ad824a49f94908829dadd1b65d12b8cb0136d5ac1a93c8185ea28861369321a1ef6ceeae29d6a0ba53ad5f39e24b2938118903036cc08b52eddcb2a1c421de3955f186f09ef8f7218126431b18265c95b83447a12d4b28ab0f5a1939f395a8f2e9f88c4e672860f71e0fcb46281763353aa555b1d598f1674c4353161c09fb06cb349e72711c8b69d96d1bc282f47f5386efd27bc2391f6aecaaa315b1722a3447071f10d6b03e9c7f476315b069009420bc0ccbfebe18aa12105048006d3fda26362a9a633c0b8993ca8d1fe81cafd107182be2ae82304422af608336fe2e8d7543f74d16968aced9a2861935ed757cb627b555130e3496979c3ada5c9be71092653698c7712afa4d026bca5811b5e8b02c84e876060078da2651f313479d482dad3a2e64d2867e83f6c4cbda86bc0b46bd0866f836168588b57b6336037c8fda5a500074dadbc6a8faf2b0c49abf001b1872897f75e6ec99eb3096bcf8ce03441df833aa0e9442f7a3c86115b86f1995c52601867216b55ebc17d7e052534a0b1bb035908b41c63fe08dc0f72207f44453e8df95c59dddd2883f23d437ad8b5ed0240a87d676b47ddb4f58e86e3080086b43879c902c5e3a3f2d30c71760674065b14ad2403c256355f8f870d2b5e15de4733193f4a22c1643cf54f3063f7220777b562f16c47c45ef37276b0d3462c14f86229bca5aa0aea4716d60336658338cc1c18787e9ecfb4ba32c171441bda4e76eeac572d26b4681e67d56f5c41c03e13ff259cedb8fae016f396f48806f7a152a2c2c433ca4a783fdca5293a16b5202bf51f3dd185a25c7ca05bfcf15c87fe839f264334297d5738a2a27cb776a49e442a93dd7cb7b569a05f9d230c2e7609ee43dee8528ad27a0735dd8ea8f72627a14d87497b55d82b27f4e7addea69bd9fd01b089aab6d0807378339d835e92383653ab9424a4f2f3e1a4ddd781375dacc922f18509a520e1c36fd3fbfc123e34da2bd0b320ce96ce943969477bdf58be7be0fbca6f7a99fc2ebcedf5293d856473478c495c252b328935030e57777df7a0a9ac3c2d23ca57b3b25e8a6252af41f62222956bafaf955680c8cb0d3c5ff9245cf80fb427f53d2091dc2e7aa3786a389c9f4f0c8a237e3b54e2db6b8d6a8f83cc49da0a8fc3e461597cb1755f1cce55e945cacb8029f9d40c3281bbec6562861ffb3f969847a098c34773cd8fc595d51a813ccd80d1751b223df1135d0e261d960fe21f4fd7e583b4e1a5537524587cac2af22ba9c2ca58ce4fa10064b8224d2ab5c1451e5e8d2289ccae0b35ba0ae86b06440c94d002f8642ad53e420bb0db13b92a990a3ce204fab3cded8a43392c8b927157e00869bec560ea0f144733b07a527cf84782cc5c269d4d7b951a382317f68123749c451011926ddb59484a63e1fbd4c524a64cd0bc32e2745b8da8cb841e0543d06a55c982b1e368fc76d7848ef064c9bd31bed289bd7a17e5b8261532459f6741e70ddd2eee73fddb3387be952e1091c3e57e569ab4eadc0f9a8dbf82acc6e18fff0027aadc0466aa97bb47cfeb999f7838c12aedf00092082d3cd09b4d5ae393e8a1eed0a70e5785a37eed54770af71ecd301b8496a08a28ac34117b6d96b261c1d0c1d1b1e0d3df9759158539f1e0f80d48900509d14f7f20318694443ddce347717ab889390f64fe72c52c551b24cb637150a80e0c3cff0c6936d7d2ae361a78f5897bebf7843693efe8250ac2811bdc01a3f7e0c401dc3eb0e40ada0d860f1e30025c10fe4e4a3e00161ca4817dffe1a587b6c5b8e927024bab688d1293345f98d573e9d1f07386f668ad780886e69ed31c6adddc6f662e895c1da6f5a643f276c796c19150ce8b0c91cc6e14955e87212bf47e1a3b1f773b165191b2e81c014fe173a5306c51494839d778759f50af547585709c52aba4466194a8dcbeff0c313c11df339767f404064538c528ec018d23a69c29e200edcd5f29a21ff6e17cd3b5af96f661f683a80fa87853a2ac85334495f6d8d04ac0a56f4384efca5f31242eb4548be6200ae1dd21369f108557e48b28a785b95bdb376ea3bd8c2a4a083127e849897d21df4b64405bdcf717d54eb089c9207148e94d5fe46b537b946c958c32e81992f145e53a0ee82c9604732bcf46e073e58b1e108c6f0e61ef6c62e2600ea64872ce2f1a04615c6bca8a97d7434a1b01310cd4d07e6cd3bfe8e4e6376f42d06da042c086265aff8403b8fa5118ea25595bd7d4de268a1522567232a96b2057514833ce0c7f7b55f228d200556f13957405a2d3cbde9ccc4d54e26d72120942d97e6324c1ab168a48e27f2cd6a06e895802bafae8b434c45a1de558413bef76fd24bc0e72f193f55744b1036b6d1c679a8292b37ea8db87b11a63f6ee9805482a5a3a4402655e684afb7b3c0222dd272a1d50bc6cec333ffa412d60d7a4d9a11c8af4e34d1f1cc52e69ea13679e2cbf2a20c1e8ea74e8676c9e33e44794b956a9ac255af74c1c7c277b45fac9fd20df76ba7e3a34de6bac48399afd2d3c9007fa1c1b989ef882a5c51ab225b0c1894a9f484c87ab3c4bc64ca0bf3cfe857072728bf4a813c5c3d9414cddb23c360b45982ddd95ad871382323c8bcf29a330c92eee9238a1628a0b4ee4029f59b6300b285d7dd1a2eae823f2edd5966aed78a2a12b2cb0dd2f0b51df8b20c4506d81e5219133a90b85bd82bfa3544317c0854ce3dd5a1e49b769025f33da70f5d9240e10557aea5c0d5ab0a6fb46ff4c0b92316db35391a202e0d8c52b3d256056b09ad58437ba68cfa74ce6ba14672716f45f913039a4e459a2602aa7a84ad7d4740741408fd6095b6ee775d09af8624c85540eedafa9ed6964ebca2370107b95bac46668aab1d32ea1c2999aaaac74596ef8844d36d53f2005dbb2c77d9efcd4c012c1918d7d7fffd4b7686198cb21426624608d368ba63e6f5db9522169c217f0dc8266554f12b2e254ff068885802a2a6a76ea962420527cea2689829d5ea62132277b67dd65507b682286ed88ea70de9c5540e96bbd3c5187f4f3bfcd9f7ce8128fcd532d2c6f7bd01ea525f90643250663bc2be2175f08c591417489aac787c745544caef68eb6831b9a6580a09435802e5878474bc55eb8194b16a364f2267c3b26c670b500c167d19c03fdb788c93229698d1b401b281e7b0f9dcbc45715cc8e07a81805ca930c2008c434be041ec82e42156d00340a6f1ea5ccb24f02261bdc83da0663d10f12cbd5e7fac0a0a471bafa90f5266231c63f43875b2a6ae66c749deefcbeccf16f6b6390deb4758e37d5fd94b6b79f11224d52098ead428d2ef51e8d0a7b450a31569663d93b835f2be82bccb725695c5677fe94417dd2f866429d9524a845b7bc6bb2f92411e67ec654a8fc147f61c6afe740941e3b409284dbd9b84c56948619b099241f648517684efe8984547b6c01daf4a7628dbb5d4fa5da71973aa543174a0ee7a9ae374a01d2483c7d3ca96017c7529854074f9ebfade96188fe73121daf4fd15d2dad09876762b8dcb498b8869fbe6e4bafab7a1cf75ca025beabd86b12ec7ee16185a52443b6f7dce0cee0f38f107798dbc8db7d27a42e250241040a72ee27f06894c8542743f8fe3bf43e282d6dbe30c32c134ef72b12ff415cdf64d289a4d8ba77c9163d9acf0bb513083cfad19a50acf8a4c3ef19e20e4f38c27d5a084fcc42ef4a4febe3f6fa221c2c7dbaba0288733b5ccfe68dfc41af00c6303b345b3462ac82da34d7380bb84a23e6a0b741d0ff0eb09c2bd7dfbad722b209cb5ecbeb18cd76cb3b1e296c0553fdd34d1352d15b7dfde4e2774304a74cc039ce513aabbee990d84f8ab56d72959e30967d2162e0caf400c33779851742874268ab0de2c400facf0ce1d960cfa067662de8d53b12103185f2be47b7846aaf17be25e8a10bf87d52f5e5b2073e2d791447bcc702ca237fb6744595410ca06a14d198362aab4f4ab3af7a016689b52f3ef6303f8c15587e1af0358db37fed8a053acbeb3936e388280598721538a99759fd4febaeb82f40b75ea098c1fa7435aa5b7ffcfd2fbeb4290afd1b658c25bed29e861c0c624bbd2928967e56da9d9cd2e2f1c49e8d41dc92c53b9916b0214cf72d210c0903e4f2a0e0747bb07fca13d5768fa0c0026a028cb34652aa2ef3475f766915aeed5025beb7c396ce08413f92331b5876a83bae89cbb3ec54c4dc8d34b3b0fd7fb8dbecf26f500fd6584e42f90af7fb0f2716f0f433225905cb7fe793ae30c7428c0cecb5f2f6c81ee16f8e78c64fe20263b2ff805bfd9535980958a4436202e0d0f33e17886c0c132a62a756284453c2d8faae256c7c702812924ac6707d9ac481da59197ed5d428bea5dac335b018ddc2a48a53263bc90605e1b0cf5c6c21251eb65c9d71df73cea1f90afa0fdbf919ba6a0cb9dc2a29b302525c8c412d7c76a873da60e2018b70d82f1863d05f0c47cc1cb49c0af768955b5af5fd51c628724d85f99cadcc96e826aa6da1acab186f679679e6545f07bcbd5621b80a2ccae5884668261448b6b013dfb10f249dbc057475fa56cc5f99e62c00d19a3d302a7af3c3970fc844d1aae091cc7c059936b5e7cfbb394da2260dc958c9789a55f30c40d9b948c3337204934a9401ed8369d576eff9db5424e34ced70b095a0ad667e6cc20b22462ed0b4c4674afbaeeead33af15350bca402379f9df3017362dba89cfdf64f4920bdf79117b65fbc46ae05bdda0da7541df7c7a5316c0329e733294117f856c0154f90247afe5ca5ab567f08d8b6c2d3b569b02853519faf86bb90fe85defc590574b62bd4c0d703066246b95ce90843b3080071d19d2b78ea14996e6a82967ccc063d17f3f8111552e7dc50ac2297bf0c89d37702116ce85097ce9963d2ec74381b9aec5a84befc930f0e3df6c9e9b15f54d9a194a44c6f1a455b9180202aaa53096193ac7d4bd446f3706db7b7497caea6a4ed06ccbdef314e9489e7301e7787582b3db9c2eecaa0cb9c583017eeeeba29caa8becc207eb491eb336ca412fccd77b494b483ce9e220820181b0d26eb55f5c1426eeaf27f38511741012bc73b10677a5a18d395f1290444f361dd7e58224282ddbd9ca614dfe3afede0fe706135608005bc06a87490c75cd5a6f6c8704dae5b630093aaf2a05c6fb78d03013bdc2feaa2ee02c64cc8c83ab0857c20cd039d3b0738f100a1d37feac4cbffff9dda048e45b8ed366ae14fcf4198817903d8a6d0dbd720d6e761ff4bdc7e96d94e16f29d3fb174b8ce6dc4d6099ae06c439f8ce71ce02d752df39c6908aebe6dfb830db655f21745f23deb6803590cd8fea12eaa25dd03cf90601812c352862792b5fb25f944f5eabf465959d48f081fc1eb3614ab4254a320370b5141283408e2be4c892fd2728e22fe20562618672b7ab3d0cc072b72c4732eea2ecb88e03cb4ee46e89272c1d6d49c6a55c9baeee6ee9461c708334f4c729cb5ebdafa5df2d548da4caeffabe9b31cdbff1bc7beff7225efa458c6f44512bd05bb20544145c96118edc88c7d6ca30882c677c098f7128950714eedffa06ac9c5b02a93450fb2e4f10a5086a85b53cbe1648e6bcf28b29b6b4e5d2d816c345723bb2996ffbd1c7484d1f7884658ecc9456021ddeda57b471378f5d9643011f5f4baafa2f2335bcd3a28994555fc3d86d2a363ac5325aadecf3b4a9e68b487ad2ecd8ca18442f2cccf276f10f7b8344781e9ea4505627934dc6a7063b56314d5a67eb41349fbd761cd1c80e346000412f9443fb0bdc175f9320f2f1c54d30fe820bdf4c2552b712282830ddddf17ee06ab7201f63f17fc398aef0ea2999d36a283053243eae57a4eb54c5aa085e7d5778ed9c167c6d22a1828d6cd70452006ec0ff78dcbafd0e183de49627be27d41aed7dbf7a7a7e2bdc6d575ff2bd0af59e12c7e43ab40876e697acca63f7922cbd6b4164a6bd28bba1cc110ed0d8a0c210afe3dea7e32c74f7a9a04ec29f0c47220baf9c4b7098a85afd414d032008d99b8d9c7801db4d84d318ab23514e758fff6d87226b96688a8117d21e78f53e18a89421b43b0523f01778f32c21cd5ab5721a95bf549228692ff051f1152237d5fbd9377c2f6ccb713a2982008bde37fa3b6dd3c040e730a2a8c267a7f72e71c15e5fb4e4d54bcedff39d0d5b1c25a5af6b6071dc0833d47807b60cfa0d2e0f6c77b16501aca66772b9f2deb3b3319f17a78bd58c661c8eb211f3e2b18d0e17cc35f12ea116364e22f942e417abb9d970152c1046d002ef0e1cc9bed13fc0c15677b3540482b9b5b29782db1c603e70f87d66541c21e0b572e77b0f6bd6b79d3d296d913217c913214743152e0f567ef718beb04b0be4b801036b78bae7107c0794d183e6af4fc711e1cf627713eb743b0bb43a1efda6b4045704bc2f050ff02c17bb0b327cafd7ddad492760f46e6149d193025bc1d6e08fcafabaf102a3d010286c6d802ef1ae02aee065d038e84dd085f94696542f60975cb83caa99f0bc69e6524e33471698419120d4ef3649e257960f9a2d19781a9f2389a646191cc812dd6636ee99d534adddc669cdd4b5bf2aa283aaa3f1353ef6d73ea5c510f363a515127a4dddc72e51a13e9794e2841187307378ba5b58e0308470ba052081e6a297abca1f51770dcfe0c639fe42bbbd612ab55d6d605acd20085b68e5f896eb5894c8136720fd8bd0e4f5c3d7305a9192f8d7cd7551ca98801301429a6104be5c1334d1cb64618022f3e65c8bc61fc7cc7cf21ee92f36b64f67038a915ef4d4c0bd0c7c1ca723257dcf3da2a40bc27f01e75a756d54378e973971df7acf5d3217f5a5a8e725fa4ffd5e058dee79fe07cbf94d9d4e3f0b805663650eed025faf72f3620aea6267a8d6fbb2888c2eab96a08019767506843a1db1532da7fa8932db41b534a9122af8926714feed9d72f812bda264c371a071fcfe0240a63849f25f185600ff4a28de4b6d6751e30c6f4a5b42d49e3806eb12445cfb37858c6e558b14f1a111679cdf9ca3e1dd74a20607f3eae8adfd88618cfb66f9725ac18776074c314b3b080cbec8950521b8596aa56deb295e2f7d19a8454a1cd4f55b415fa5a2e7465afce1ce2916b5b53654585f1e1e531f8aa4c57bb073a5fae6d78c9a5fda62ad868a88bc49f58b0bc205bd5b177996e3f060d05bf906943dfb1955c3055394be9eb33996c5490ddc9a269ed1015134d095094878051a2166a2a6fb74422d16c03e2ab21810fa66ee594053784ffc585029d31e0b8e00da1f8b260bcc48160a0591ae97bd8fb27ee08f759e053653fdb1a886609e92aaa07e21848f87c27dbd6b81bd3bf41840ef7a1bbf3e809ae5795c5f114a4a1d3e9df19d403a53777022f28bde8a8f233d85ba8570877c4c4302035384f5806411223ab67927f9c3c0e46b697b4c5754cf45624004170d02f30b88efe0ffef9df3141fb19904fc8356342cf20eac764dde09f184689a8688407801e8a201812c8880ec238ace09be3b0692ac909ef42c48390b1fb3881c01637eeccc400b9d747b89bc6c8fc2d7f65823a07547a610638e85b4285874825214e2f4ae8d8ac0df6ef602c714e80f842dc9d2cdbe8161e592f0f036d42e06de1acf2ff42fe6d9753a821f034e67405822dc883a0571b774cfb5d51cd376d860065bf40cfc76d00f9413938014f696738a6f737ef512731784f2b197ed6ed905acb319b717cd7efceff253d17f25d5a29c2e95eb4a14f6af3c1540cfdb7b01ee066e42abef1a06bd3a303b1a404c871a71c67f61ea200302797c4fc8311da59a53a5d130f55f95243298d639cb4685ec9018c2bd50f032b806e80fdb405db6d259f908b25d6409afee467c2d1918aa771b4f69f583bd8dc2ab49a06f0173b7183c657ed6e407a6ee86778bdc1bcb9c6626e954e12133ce90ac77ffdba01091a4441542ef6176ab804188125f7a019c77bd5aa42d404893058a69cc0a5679d46196360ace1b62213120ca32f6734a964784a70a5618dfa107f380caa6580cba0f38c633c24916bb06d53255c12db9f4882983b5aeccef7ff395be8e3584304b89276423c3b9d47a3fe0f52bb02720572d0f72e12da95a781ff4f7d7148d681c800536a800b423112b1e3c10bbc37dcb44ea8b69763e09e61f05058b2f79e4e4e410feeadb14abede0aff0c0a1e0455d764d6d7c2d97d6632a867a024cc8959df434a49a6cb94012ba984d1a736c73bbb8a176509d66c428139b21e11ee3c38cea80f10d9901a27724e872a61be5a2f2df6b54fa857f0b157e72eba49d40741d60eda0ee2830545ffff1272b80f6796683607763008efe99bd51ecf84ed6772d9e944bb51b09bf9af807fbe1b3de4525f5c2e3fb69fc0dc92738837a49342871343c2f12d40897aa38ee10711b151fe852bbf4829fd1405ceafc46714eda454f518468cd48cc5493b2a8b377c80526ec441e01c2b319ba32e458825e9ff7272ed024d78beb1305f193c387933e18d48a3d912bfe3756df8e33b4f82c6bcd3a4b50a9269c4a0fbbdca21e186a4cd990a31fe860b3023a98e313c77276c025d840a26631eb70d602850011f0e2d904f4218a2f0d1f3097056a9d80439af5b4ca11891dc9a7b3757462ca61ae62a9e1823920c57a614232be4b63af9e6e34767958f9db4c4eb4bcaced3a1667d9ad4b47e2914b1645b79ec0248af9f14b08dea6207d28dbf4b5a290cebaec78d91956d21d6fc210062bb0ae91a86bb34c5a5f7b270626e45c7e0075f96d95b718f09210133be6ff80a7af7866829eaee072142847073ca93603b1d238980c2147396e0e788faef60148e348e2e6ee285b1708e4beb164d396644b12e83432af886a2aa50f958da8a8ca6d881a31f7aa24386392479c2df20b54598d6c6c9c48e82b35b10577ce7610ef909ecd5ddfc852fb68a8e7b19ac570a8c20138764bd9134d21c0d394cfc2ee10df2d06999c74b21829efd5f1d89eb25d19c090f691fce64c638a37d8205d061137744c22b162ed736b9ee84ac30a447e2077a9893f510a04bc13bd8242c5f8edbc14c6f1ddf2673029825ea34677fb7bd9fd590308b47b93782bc0fa21d5285ec8329f7069dd303fc47e2618afb0d0fbb05e028f4dc497229556c68a3a550e3aa7c1b8c4f914bce645054cf654f68ea7dd26f2e26f506c453dc501063ff606d418fcbe8afa74659c04b2687b0dc95df9db078968bc73276afd14f5c8005f9ca69ae837fe8de66bcdc5a34898c380baa1dd9b00067e8a7961c8887ec2250fc7080006224fd8f13ebe2b8ced29cf1d7629ae110418a28d416034c21001c3e900dbbfe8ef1228dd7e1c50a4f745609d7ba4dc48318b5d61aa0c6435dc0e28502f4894cdf5140254158ce873174b9b799aec33f956fb00951927569e98d0ffbf75ee0545fe081122f1ac0afd5a2a13ee8a64938a2c829b8a32e60af972d2d2011a6c89463e9d9f13c165d39b4670c4b74195a94487e393a508fe1a4d17ec1f4dc4d8b225024a3b91c9c4b249873510b69a0087bbbffd83f3c1bf7ee3dc6c5d96465127ff0d6408926f072f86e7bf13d16b6dd9586a7f6c0de0c48596a5585f4b497421fc1f4175490980b5d9ff24a2c96e731de534353e4a40496384c6dfd02a33b7088a285feb539667641058254cf1d1afde1edfc0147d6e1719a20862d04535438f47fcb15066a815a6d54c04148bbb099dbf7e91c43e753a09841981503ae6f56c5413b38f5a3529e6fc101d0660cb8aa53dbeb1921c10f02d3f7409e165d7a2b445736a490e90696e28ba7246c025194c891bf2f7696a2e65a96504ba5fcca34d633836873c47272787be5c7b9e4f0c461dc78d1d7963ea138aa6b58dd47702262465bf09c93b4c7a0f8c2b56d5e7e92ab304045d2e0b08dfa643efebfeb1939831d4253285e79e5ead6133ef13eeb4ced5092c68fbfe1219314ebc644c9eccbb05e5066d956fb4611fbcd55161280243848b6a07492737a058e947025cd80b9e215bad3b233252b1e6303f53d4952c415b4884bde0c9be23bfad91d8f95c783ee0cab31745a1206dac418d1c0212a4244b2268bd5f31567818681805a627b90fa8a326b84adecd56e7dd7c58e2d38a9391d69c0797d66809ddc1d886ab9e380c8c6310c3f3031b4a79edd2fcf33f3133025ca00cdd738433bebb8e6797087fcbd636d0b33d8de52dc3da5e02fbe28e56539ee298ca8fd2fa61d1f9c4455da7a58c19a4fca421a56a767bff696b6e9ffd52dcebe61d569306428cb276efa8978cac0c68204aaa9651678405a3df1334bb0599d36e90c0c604190420443a0621828c4120d56472a90e466b430c424d1c06f16096c10489602d10e74b8f261107f78865b3f4b57e142570e50dd84f0cae4745d9bb6448a54ec902063a7d0f8341ded76afcc2eef148e302fd5dc3c973790eb124913b3990ed3c41508498f076cb4c429b3105d60cb70ab51428562830ce711e158077507444e2e97e24112132e12502ddc38eb2e63534cb80d9e79e6b4916e951caabacaefef34ab35afd9dc4fb31be44aff96691c1f4853bdcc070caf32a8fa276c4237b425d3698801645572e54aa1794d40f5fff51c4fadcad802d7fa98537bc7bd70ca5719877f0da2d0aae6c180a1e8c51cbcfb50fa1b4b6b4fbea496b4ba6f7c38818305e4a3a36cf3804d2bc03e72050d21e97c7eb1b63b696f6f10ecbfe5b8026756020a4c562f140ffe1435b121e05410220cf40382bc961780bc26e0f77f3b1c3550a98c227020bbd88cc3947b466b05878512dea4e72ca5a7741ec5e01b25f7295ee7bf7f75002695fe4ca51ba46568456ba9d2f049c1469e1702974544bfc9ae17e5dd99025fbe1ae41df42b3a4ef188f92b7ab0d9c40966e82f18c19eecac1db10658cef7c5dc0b91840ec09c365be304560b3c24cd824064c63d0282ec14919f235bb08f1d108d2eccee3c52866773d6cc826bcf4dc504b8add4c5589881ce7360ead8624f28d3861eaef75ff2fdccff4b22d90a6ec3f015dfa89295c9e3f1e73ace6e4e74ea2297307d21034803a91aff3c40c3381683b3aca38e9ed5f6a95b18ae251d2eb4ee83b68bedfeb48d11751a90bd4a3e135be1befe2482b1771817666f8c831816c053ce1e3bdf5753b6aa988f9dd38f03550d98f9c3cf4a2b6a98062a8980dbaace5852cbb3d9a179f8455828054fc70be800c2b399786dd6a884cd30dab3cc47303aa17b7ce2de035e50efb4a259337cb65e7b13554b17aa79c1a85e68b72c07f68948de7691aa0dd9860b77549f0be4d6993c0b79d32660546c6e0a8aa66f3178b019ab6a2b43ce6bf814c787208c8aece05327afd32d459559132d9905fe3422bd1b6b20b9ce3ef2609634e710b1ae17917efdfbda36d5796988ad9e1071403037bf99adc24a6f03e76dba4a9416c0c9b1522ec7c11730c385155618f8f8c35f58a5e1d92656aa78f04a728d7ab3a8189048bd5b0b3be446575a24f456aead8b61a4352a0102dc91c73d067610ce77fe29f027c694ba6916b50029834621b6572e33d016fc4795521d1bb3ab8c8f5c298331b347a657d0e31f7b87e95bf664742b071066d0b31d6e2a8830347c85fa9f33dfbc99130255405a482e8a4b7ae2d5050b1cc0e9c89f87357e4457076c9198b41ac23eacceee1339d958657650f3149155ea454ff8a8b7b3e141d1f47536e1c11d4c19fc6d243537c8390ca343656503e6f0e12d85800db0ba54eba7b924d676815de0034a4dd0e7d4bf0bd556de52f6002b158af03962b79d0c6acb6e743dcf0f44fad276d8aa1825ef2ff2ea447f0839a3b1e6aff3bd8353babf216b00a4ceb31df304ff70dce559b1e177a4741cab524a5c100fe2caa389f7c09ca40aebcbacca783b4f5c959b783e1afd6c61c8d12b00c2be075131c9d7a8e570e98fd310c84387f6cb63fc836c87c5518c88bc95c904c5664fd24e26912d04a2570336f63720420b714fe1e6b4441d62d92d052037185b663e162327c9a7eb2c724c70c7dc4a743277ed610f146bff21a35de9fcba326bca7feead40545282ebe8ddec0098968d42dc4966985d675fd6f97f6604a177c17c5c42914202525546f0889bcaddcc53624c96525186a05ab1fc024f523bc9a3ea7db2524f187e25be2d0c42f1df661a07953a920cf13b703775117e296795b1e2f0cf14b149af11029a11ad0322b53abc1fab9d136de334ae4c21c5c7f0337386e77cbb4515d32044ad3e6e019807e6037fe5bab66cb1a559e00740998c35946952bc2e6be298b16140c3f86442c497b543272392facc47e63dc854dfd2495178585f7946a2a145647adbde7471cec7b5552d3afccc3b4651de768c41a6bd63bad2013dd3862ff57f4748f53104bdcfaf575f5fdd29c6cf41075644b95c3e9c7194b185ad565a577f7617c69c666b5d742833987a0405d0b4cdc96f4578debc9b49d36b48383f68afef74c3b5552a157d0431d6938b2065e57285943a1c54acadd5fab1b621d73d8e2d237decaf9efa53a03448db2d74075bff7ab86f808e019a1d02c8ac3380e2637e3265851670118efc911acd27c4ce751e47ed54ab7061ac7547c17d361a036034d9dff1e417ce5a3b40a5b14cab1df08101d4c27b89f70e3e087473f8372390351d2eb7842e1b80cc496982ee5751e2de9b355d22a79142e424507fe0080890eba9810d8737b52078d66f97839078fc0f8fc8d4fa2dbeae85ecf55f6496faeb2f3e2b6d401640b9f16f907122f3011d54c4d6d9dbdee86461ec218516d3971f513b35c88d38cde5478011772255f00f8f9a0fafccbd8030b35a5d8841ae25ac1a77bc7c522ba5ce63eec2de62ea2cf277ace9c13c6eeb1297da9e205e1a5b527d4c6e6e1824040e007486041b7d5220109b6e6de7ec36b5f2b74544cf1125ea05a3e49477d75b29683c8cf7f4ed5cb129f9d3eab59afd7f3f5782a5220540fad1e7092682724e9aaae5f54934353527c1cce154d61f9f17f1981e8020955a0adc89ce81cb07797a784183c5bb9c7c796cf2c1febb64c01aaefa593a47ea4b4384e77d6c60f0977baebefc8725f0208f5fc18739a67488ba2d1809cb96e4ebf5a00980690d41dbac14ac3734d784348a636cf40b3b58a87e7708ac115268c2fd9e10a01eaace952cf92d870b55be5ce12d09a30f7cc95324a1426d321e4e2c4fb89440c5a3b12e4643fa852c63a3eba5eb5f8838a9a3cdbdaf39540b89aa4c6f658bff106d69ed0d3dc523fa63d8c976c526be525ef26f28d3810e689504a5bab584b31f9fbfdd183ed7b208dc9606739c715d6a205be7478f1c798818f3ae64e17455b3c2bd06bbeda25bfaeaf6233e85091cc571baf5d547828f34b9c5bf4963e0200a8b71c2cf09bee16edb124582e08300484c647a75c626ba4b84f65e654fd6b5e0eba68238445ccf0381f715b14d672c911bafbc57697a49a94f318b860e05c52e5c6ccfc5753a64f39538d9ae67bca80899645db2e1fb75a1889c1e90c75170c617ff50615b61d6384895a563811ccd944db59eced5d1b40858509eefff2fdd28644816c10a760e7be2663af8296904ef597e84caec967d8b29f02d01c10e64d0bd9b5b9c048792e1102ef3afa4a4644768d640f3306ea3eb4873b8cfe8528546eb2d213f287a50004c38ccff229515f8b30411b4892afd3c8e88fe3faaaaea393ca03ba89014e0450625279a3c4205f02727cd2d3926539a2da4f1dfd7a1b85be91fd4935db37889fded0cf45338162fab6ec7fcfc7d0576bb6487afa92e9d47290b505ff74a59c143d3d625b16a2c74c4efcb70bd04aafa760677bd30cc5610c6ecf403a4197a9d6feef614f123164006e41e3c2391b2c9f649e66e45fb6dc04326b1c09adf98d94e11ad0de02ce1738f15698be6d134495d0117c03c7e10ee81f5cd6e7af3d709fe2c3b0563a0a141ac7347887b69b0bfb788110e482cc8c1a5de69356d2bff7d2be65f2cb0c645ea7f1423dd719efc592964e8d08fde91620b835247fd97e1bbf550147ec4d113ced272d124784d637fe898b330648e0acdb891f31b671070d5e8970bc7f3f3960d55405570c256bfbc9e483e5cba8e268ee2419388e89a37a87544650fd6b128fb994e300f73d262349a44bebbdc62be4965a563b0a97f2e0a8214262aa97724fdc1928f12acb0c073f523d3de60cdf3013802196a8c377d8fe3ab043c790828a97da7c020b37108e3305aaa7633958598274fbb0d826adfd691b3b34c8d52b6a52e47dac2d4159800e07bef3f5ee0d9ff9d03be54b27c549edff2d2a1b70ef8cc343ff837c8a81e17abad21a62896797d6d2ab42abad0d8f9e5417a18144aa12917b03b7438a3834a255b94d4c0793118830469577b7fd9f06041d5f879e793698d69bf995ce868940715ad5ff9e2c397913cb307d83a0caa923396249b930263ddde1f38ba5bedf9dd1f0044f6e7560ac0bb91838e1bca1042b46c24e47017d5282919f73bb25205e1c36f1d4202120a3c16234eb934c15d706a9f81f3337ad0aae4f54055bf59ae95bbe63467c6c372adb7bc2819e6933cf918a18705b9bfafae4495470d0091557de2a0d4b32e164fd5d2349152cebfc68d5b92897e4649e178b5b70a48f0caf0b87beaf93a30003654f79d458fd91079d2901e1d85f1c38d8828133b990e08c8b1db8043f9d08906230b006ad02b9e276853416b641a7f1c137a96e7740e58e8909c7e01b4ead50289f7fe216cd50b08bb70d907d4ad9c24f795522142f71f8a65f64d667ab14c8c2b9f5396d61de39ef205ff6a4336787b20ad4f44de9c396e7558a67e3fa5c178b566e73d3902a78bacf71e449e1d75c033d7cd75ca8d0c9630bcd223169e8d791a22add4899d35ef7c296595649a47dc5cdb9ade75faff5d8d623b9bda7f0a2202d27d4acee50095abfad87391e22f1512667bbff60fe09fa5207c9ec18f69ba38e67ba622a824fdfa720fb33cc3d72bcffb432e210ef93337d05e338026114b750037f00e54ef335eb33b1923803774a1a72cd0a943d1386613aa1e6e1a76ea33d7fc29554e5cf47393cbc4f67078e131360a222847cb47d12191127a6ddc67466e328bf1f63817f2822997ae11e8ab452b4fd8be3bb8d3da286142b488555ea6f679c8e4db8b6c4c0b885fb866c29cfaf29f51ec5b8dee349cd1ecb62093c478d0018ee6609fa5899a2d9964b47f2f30029bf82febe00a8d82b386365c3efe051ecc3c0a6a0a4077a5b4d5bd3db6f6daee3e6872398735cf7f47a84f7b0ab6a0c61e9705c7147fb8af31f4fa713b848be842fee78ff09850fcc9c9c3e9383153ffe12ee5fe18dcaf2b8e2a88ce92a96cee2d62657a1e5c65e4ec8ccbe8ca94adf150550b19f6261ba4c64236f4c922230912c888ff32e4cab664af2cd1a896fadb882b89a989af46a23aa2235fccd3ae92a90bb4b6b1f2195192589c3579136173b87881f73214528f10a6e54f0db002a6d0860c9bce8a3174c3745f7b6a9cc3a0c56f81f85cd7c968d032ea1042b45b93978ff3a9b76dfae665f705b70103da4271f5e9dfd6a1adac4db31a503e9d7e274668c28731a7f51133356e83fb6b3036d953a2f292a60f97a32874e13ef69566d729404a242185ee0525367b77e3276b98d8fb7c362b5c679c501b9d47be48075dbd6ca10ebe451b1fb9a3917360418a4c390d1c57e5a4b63a286e47b1c4f247942a0a048cf8ba2194c7dd5502213e86e5c948351c1088d694842076dc3e89471cd74ed6ab6330dc70412048370ccf77047058e698d1a8c1c791c53b006c2162e53617e26bec2bde3d4f6f33a1d23f630f787c501fed0036135a1800f87e947a5879f882e406ec022db3d800fca961dda208a7e1bc270fde44de5be784d4cc37e3550e1cd1e44efcedb3a286bfd500b81ceecd9bc1f5812e24f7066b47a62e73e5f5a74e81a9c7851c64320b129f492bc2a9fcb5b151bbb8b09ab42e130753b6f1558359975580417d7594dc59b4b9fdf2b02319b5be494c27a4c4dbb514bd9f98a228242599939f739bca9f4810f67be6b2623c2ae90da8961a4ad57c05099ff1fa8394ed436d13034576ac8151b98f950b8162c3409b8290b2f1f902621ae0c9a84b541e8b9b20999541e6279bc1b72b5794419e4d7ed4652651c68fd52457fce60204e50d1765dd23f4bb4af0f6b8afe41aada4c1161bf29f1213e7463cd1313de82dc0be8726d487d48fc32d05351257d6e0d6348ef7e8c590566b99a40a45599434630b85cc7ce86e218945497d508f224bbc6be1632cb4812000defe0e48117f908de17ee1417fdcdc0b1e3e36a95b116de0f02cd51bfc89ed0476aafcc949d9db0024631be1a9e7bfa966130deb07bab8bc5376c48f04432aa251ea4238ab911265e6c047ec62560e390decf2592cdec48faae6e6e0f0529e5e6a4c7dbedc3f30a221924bb909d4877419899169e0c2df89fb65b1a61a4c42938e2bbaa3bbc62be442f0cfc1be1db1ac3cb0eb99a169b8236c64152761a466733d9051b7442d3d1e784992a747d047ece45619c66c7391ccddc9b561d22a77116b99048098680572a25929194a8dd1a8e52361ad999d178d9cc534f6bb840ba4f13d3ba944f55561ae0b108ac14814d957d159edbc25c4d0103eeffaafd22f4b283c9c40ee4585e65425c6b753e8c4a5442f08046c8f7ae3c5f24373c504faf03d2c7a368b5cc805c3886a32e644ef073564b1dfd52380ce472c2625d7dc687c8f2065d2ef4972d07b057a358fe51cf748be7cd58eae73789e47b2acbe3b0f2e455990b1bb9a4c4b8f4956ebde2900cbb92580b4d8bd4d3cda608b7cae58c7bc37dc61180175b5548c496cbde844c25dc49f71914e1a193e7d8e0000107951de0c7d6556d101133c8da3ab42fe24cbf682b33578b213acde23f380ea9ee061762cc1d99fc281fa07974038078a465855a1b496b64a67de54251df339ac524e656da1d1632021070fc4ce2326ee49fd4003c716ff4c022d3ecf47aa4293b195154205a589585cc2b9a66f37a84888edd83de23afb9833ecd8cb9e8a3bb020fbdb5d1d857e039c3f2c72c43ddcb91415d144d4a550c76a3f69db3bb8e98ffce43c11017d8cbced24757f0ec87669c25c22d78a74b202372f9ae416b99ae0ade8ecc390080d619584254ec45d06a84c9acbf81ed6005290f4584af9177cf6b1379449d289747ecac7d3ab023aa79665c1451d94adbe68236373fe2f02bfceb78d2a196714863d4971cb9a521462cddd28d15eb20a2a67b0dd1a6f2374e605f61b39dea3d3d62881cf4608a1c6406298593bf5355d762f297217220a8fbc0c8a4200a041344d5fad150341403a41d061d7986bcbcacb4111f04c4d474b50d025e43ee7853881dddfbaa02175f68de98ac73786476b30555314cf43cc1abd593d8829404802ea1b2fc23d588ee8cb794d02651d11f13cd01cc5c8c58db5ff0bbb2208d8563a3c376abf52485df1347985b5a7390ea84c506d584c0ee807141ce7f9c6592a69d98ac50873ebb96b5e1892da18e043604377bd1d11e2fdd2a0706fec676a9c4b381a51eab28670d4f7433248c8e906870f15f61f32c22a5ee1f0e18ce4e2582a90ea93bef95b90acb3c17e1275be1e2b419ca69c6e520d367d377dd321bfc97d54ff9e4de643b15833a16b45be4d052c0b83f4e4911c66ab9c2868c06a8d8952ed4ac5ab56ecf2eaf0c3e0be9b933a34ab48612bd90e241a80bee107132cc0e27dcb9c4e1dd941e3f6e312bb6658ceb7690dd020e6c73952eda913b0053c68e71c6448e95ce4a5b93983e918eacc8a93c36bedff3c02a961c9e912154bd6e5a6afdd0502358c070429756db2fe77308f45acd3b5693034b6f692586c2a7eebb56810d8fee5ee41b15d27dc37b15a40257d0ac79ce8175c3c0df3e20f5eb9b65c01c375534da41c409834d62bb50327074f93437c7cd5273fbf6630bcd1dde4d91b686ca9cc500b35180892824e87392652a18ad86de360661a2094e9ca46be9b7aac9cb48577bd69231ba01f88e93425d41119614e9ec4ad9a9ca533ec22542ec02267b8a10d9e19e16bd130b3eda96e87fb07a0a4ccd22224c11da71ead44483e956b02858f57801abe7d9d586b7d4768517c268baf34a840145b4158b870722f86ba8b0c9acd5f7ada7dde0128d9c8993f75e881fb452e107180805ed1585e9339db15ef2a5e931fb0e017918c538b046d89bd5fbf779889e79acf4576a01cb979adccc20f1e342bc1955f0fddd29f093effab8711fbb62611be8097b5d0af723afa79f5ee3f4a6915e18e63e2ab8bf637acc5faf8ad5abc6d37b2b42a864425bfd99abff8ceac2c5ea2395bf014f141a5b250212b9d837c23f5397019fd2f4b59f91d22194815cae9e8d16131b7f67d6a4666e969023e1a057f9b2a8d72e03a43d9f9a7d3441502db528b52581e7e46732c00b643b680675272b2280e00222f88ddc3a8c2be46f128e3ab35b1c806c4507ccee43810005b3d931bbbc84f9db81505e46e34baff61f545ea203148fec2274fdbc50be32a1236844239594f485ffdf7d8eeb5f3faa66334ce684fc2ed8b035b2045f2c3a82578e70e6acaf85674b653ef3cf630cc97f82c5b8187fc2615e4ef008fd4faf6807189add0e782278571644dd714beed88196577968cf7866b821e9dba802a153833511b13cd57f80bac275d200d3592c4cd0fce7ed666776e40365a47d059386e1ad621d31d96c56457ede43c37f70686ca96d6edf44eaf916fa085bfd24bd9e33fc37637d012d07366e68f2329e1dfadd245c37ebe225d0224b73c13fc66c7198aec3ef954ec9c233ade87a6b6ff496283cba1c6f5e168862ac20a46049dafe6ba796afb94262378b8e688da8542519c164ade28c506593ef2157262e37d03ca0227bfc3c0dd6404454cc36c65afd8838ed9014a74cb5d2a5232e9adbf7fabff9b629ebaf3a20fd104c15a45e780d1a852219f45d63bd319b3cfae502d77c35552a619782e08ef1665d9e677f6e3452118baca502a263267f8e4944d7969f550cf1c5d15211584999155187c632027a5c11575f9b57bd6fb2fcef704e8a7bd487f71301f36b776cd1bc0232fd69b8f279053e5d2597b9b1211bf4be56b1acc325411d50a036d2cc6f7042dfc0a4fd06a1fe067f7b572aa20fa8a4340bc4487903f9d25d51440d5b18880a93e7f7d061fd88e412d4dcdcb2440d725fe52870564d7550c7a32693930cf3600b326bef6c1246cc9fdfc5c8d2acd4aba97ae5b45e7dd92b31f56eccde49d5cb2fadb7a16aa5690bed6416e74d550ff34b666584cdf574a8d06489981af8dd93ec07f29cfc8151644054f4072c0e3ae3ec5e106b0ea31c1ae7228eb3e32a8bb7443d9439db6b4e2be55bad49841e880a0d56d111e0874689d5bdf01a67a74c9a9cc91b9a2d42e45cf98a820956a372dcc25134e1b43597dc831861cf5e8fe2abf9d45f52c5bb41121bf04cb6a5c9d94c9d7398cada9fbfa7ca4dacf7bbee85ed1aa01360f1a8a49b8fc6dc93f1fcfc0cd8b7355854f9ae7ec25aaa735ffe051dcf0f043c050b410a7399285ea2bc08bfa51b88ffc562fad0bdde6d404f382a9b11d45e96cc7c216370e1c88b6ea03bb4a773731ef6a5825724d7cd9bdfddffe6b0440026f641430b524450998b55a6489660c45efa62a4149cfffe8c15d995446f7e2bf3882d79996dca2f463dfe56266718846904da117576a4beef7eb2fd5d2b85260c05da9a7088d91c0674274c5c1cf8c25b5bf98974ea5bac58c3c44bf49de5e341fe84e3a26ca91814e18fa1c3323958e0449f9c74e84f144a5b99d39d3909cdbb49ef5e6902e031581d9abbb130c1bb644b922c80b6eee4d293cfe775d12e32464dd0ce5deafbbbbf1bc25733c0c4440937e97701a90b6433f6ce508246e413826e602df4442f1270be77028ba7eeddf8e45e550266c753bc67d3d1b481dbe327dd07f9420ee3910fc0baf5a64b7c3a36c6c6cda8fa3633a63f04ea05a2b988a8617f03fd8477c0e30dae34c4cc81907a782ea82ebcbf09fe8771026fd7e3a4c467075da830f445be16f9491b1d4348f99a9aef17a7bd48a07d48022443d018a011d1ec30be1c1dccda41b7bd3e812d6cec27580ef44fc610942760986006390fd46174fa78bd2fc4d9a173aa149283fed24773b080bac556f9f8ba58b081549b0a3aa3afbbff8f64e5bc276d9c1fc4b532e9e01730b8bb082539e52ae098a8095a3cd56b2bd20d5a104cb1c3a47054708dea49d01cb9e69050397948a4d4097f8d21c83b330da2380d0b847e201722fa25d8ad80054a68010a3b7ae218101f20e02633540d44e15cf0bcd2bc64d37577ab65008ab66c913eb139a3799c0ef291cc0363c3e13aec8bb6823e99a653874a433137902203e767f169ddc9652ed68873c4988c6d646e74c11fd97f0a01661441af8242e6617f9c82771f0f9d5d1006ea689c7c8048004368a8008f1d103527bc11c58f6fdbb07d623f4194a0229d4b8881b2b9b1f35026a5ff81cf38a9616704393dd03acc08b352e304a127a463784d3a9b1108b5234a2775f40dccd30321e2285cf3ec45af81c4c12d89128a29dc399e039361c83caeca8d59646c48b6e556ad360b161025472744c8c56f003fd108b7a076deecc704d3a87abb8e05bafd34218756c6aabd04859438fe39b2728086323879ee302b7bc2b5561cd0bb0ea1fb60a764c250e10e00eec360958d54a08156f15ef9ca826e3a7346141e367e85b6108e06fe04f9f6aed24756e8a21af150ccfba6fbf105c6563c3e0e8693d45363e86aa0b3c8e1a86e73b901e5e20cb9750df1f138085e052a496280205e505a8462b832d292d1586ad1b3aa5ebb63e96d6795cd0808e8ac0c77d3ba0b4fb8b3128b03f09fa85781a298273b4e123569ff037316b3d4dc52610266183b4bf6002813e037f3146e91f728eea025be6333767d514336962a9bd39acd9de2dd81f1e3d6a96084be3bf571cb74f08b347ea2519d6aa62e9dac6b48f4791e5ce2bad92ad31a62569c4c22b326da3efe32f9d99a3f3ea1d8cc02f9dd93bbba5cd69cd98113d0b9c0858e7ab14a2e57eeb7976812d88b94cda544eb5bce7a2d2f36c8c1384d48ff59fc911e958fc7450f0cc9175435e311b1c8605b89e665f2c4aeb58b29876a9d81a8ac17f05b8668a04308a1150d487435bb9ca30ebcf5263c52a5948beab0ffab33d1af7235c5d44229d7f152fc64104694744932aacf38f24baa5ca9931dbfcea9ee46081eaeb18911f12216cc1108bf39963feba1bf5a4642cdfb42960c0e930204c4dbfddde33a7094da81edeb3040a3452a95ddade47e5d9839bffedb4a618429912d0d87256554f5855501513708d01e4e439093913c00c3e4107fd30cd64168ee60a930000c4ac03422cbc42d9feef9f8ade7e8f3d719983e2fabf615a96980ea59b53a54aa005bb94bc08b052108c7a909a39a0891da469539712569161d25c0f4e2a697fd03674a38964e81b88ad87c5a6f02c510407e72b3bc51d17ca43f9d84982da1c958ad34702395df165c56129249dbd6dc9b13bdb6ee03742fcb67f7564ba8168d721b72395de7e08eb5fcff338b4656328bb58ea29145cc7936a3a29b12c9bbcd1e1eb7e4a4bf625cd3e60953ecef2565cc45a9fb57da2bdda949b4dc618dbca9c68b01ffa015f8a4b1dd9ff9c41d304aae511caadffcbb02981a9ca7eea6a1765968dba03b183ba013bb8cf8111e99e7b34a97c8170d1564b21c7da3357ce36b69a27b961892750b09e320a14921525082561208cb81acf0027fecffb4135178f4b34ed580a6a323963bdfa02097d48bd41c0b079468b77f642bee2e37478c5fa581942ad7d0441d30f987114cd935cc16bb6a102bc697ac084e475df8d3efe7ea1701bea1c8404fec5400a7b8d0774e359a6a96b04bb9600a9f1aa2496650e9900a8110fa40eb16bf0168e95901ed02efe60a2bce7204d400dd89ab962aa06325661793e1f93786f022665f1a61d98f72987c0c4e2253164c1d93889549c1d5f0176b5c1e2f2572e65f5fe2d650b4a66c0dfdb3568da7e6147e64418bcbca319fa449fd2a3cec3954c7e5d02de375587b28bab2adedc41c57693c5d3dd115ca68c11ae1dd75c6be7c3de033c450958cc3e5ff48a01d323b4677eaf9e7768885f939a02d09f72023672a2ac74ce85c3efee52ca0a3e3c7b789f00f4fb50a60edac24969df45578b478dab1a1ba3f6ca49c042cc0656873f996d8e6d3e270028f1a18f8e6cc02a8224ff9eeadeef4f15991827cce4a65d12742d241a90c6d9218f734e364861a43676cd695a55cbb43f3944093c34ab68082624457f6a798c4a578f7a88710f89374f58a5faa9f71f479089e39869a01c06d10618be0cb847b4130d889190d10943db467627720d12f240d7b6ca574ee62a4fb1449d31b01c1227e006c2b92b10f015e96b1fe6ecc1adbb518e9cfb4fb9cdc572f0932643272578e2eefa06c3244333c55bb2cfea90a3e05f8e74cff72ac7416eeafe566b025be6cdc509831cd8ac9e2b41e96dc53e26eeaef1079b84b70d6d7b2ca2a2f5bd2c433ffc76e58235aaea751c66215ba43d37cdd3a5e4a939c07ff7fec4a080c5ef2ef5ad11f1a97fdbd1fd9658d8907b18beb803a850de6b8621a09d1e7276fd02b807e9ac9003a12381e349b643996db216de6a002a04309169cf472a0e58184f90e885b5c70b0ca060f6b7c5be275dec9681c264ae44a955c78220ac80dda01bef77267d1977902d2b5f4a51df9a6e18451cacb729c58364af27a68e54a5319ab37a7515e2dabecbef05cfaff817da925033cf9027a3d5e7a5510302b491d9f29de4e3c91d24bcd10d669b4bb1d35451904ca90b251995bd26345ce52a787a52012dea6ce3ecc3df84bd8705adccd4daeda545cf2f19f01740c4d11516d0bb12f3cf88d1284ec265beebda54c520667076a07e40736db3155b280e1e2a404509868d65a6bed5b2bb6b5d65a6badcf4ac95ed74ae9560cf659b2d9270d351fd03168b098c1b245161bb260d1e46493a2504d5e40fd20460b94eddf5a29798f4d1d552dcaf74a18db7e8f0f273498d0c1639f3ab697c9554cb0fd61454059d162fb15273ff26143951a766c1f4f7c3041f91467bb7f2d22ef123e6cd931d0d612ae4fb1a6c897550915079c5c9f01745c29f94502956ea562dbbff6452f3d78c960fb87f8f542434406692f8bfd7a790c4f0f36223d3370a49e68352558287163c41058887441f3275bc24885cd12f29543a6345c793932dbdcf66d9a2258b47c95f95539c8e5b0f10ff92c8d32152a90cc20485acf640a3505cca6504c4cfb24c3ecfa439b424dc191bc5de9cfa8912acacafedeed0f13ca2f1c45874a6a04f2ec0f6a847554569f46592b9a27ac06c102c67da647792c0354f6755db1eff7702b2318915dbcbc50bbcfdf7894c7ea73c0cb1ff520cf1ae121a8acfe114f4af4763513b52bcf1a51dad3ee45611d25c2c13a7955536e54d990362fa24a98482b3c34e548dcaeaa2932b72bd9b42ba9dbf56f4e49134ee764a7036f87a7283d292e85af0818e6e745a74867d7af58882dc418c5098cd03e6b0e4dee4d9c2e769db2cf4a67d76a67e7fcf9c729950deba2767d918e178953e29438254e8953d8866f18274ee15cddd51c1866d663c6235f550b77204f879f3658c48b4e9009bc8138f076abb85d41a65dc1dcae3750274596925a5969aa7044a6b4f25568a3fa93fa50285f6506fd503df9a33483bc468bf228bccb5923bcb33a58c6baf779ce1a515a936e87755656eb8320c8039fa2b800c36f078ae4af01e799413108d18122d9d7400b34cebe3f9b6d5f33a8da8ac4d9ae699c6d73725372c3e19c9c5589170555268f49c13a1e7ec23abc237f08920a9d36b7c3cf9b5a6a149a42a4c77c42ed3b2bf32d66fe47fe1fb317d0c9e73f9414a75df5fd20f23531b596084985285dd5a7bbb6a4450e0d581839c112123457531e243e2f98f4bed0e867d82c08b0d6ff4a8be8d70aee1eee827f0cfe2bb0b082175133887acc57a048aaedcf0245b239b7a6e286906c1fa2640c0d5199bb8f1b74cda64dd0d388c7f58161a3e0762829554a934a97c6ced33ee9542d62e990179df98d8f51b6f3e0420cfe2bb0c0002fa29f83d224310768512412e87e014689eeb7de6aba718d56c2d7f4e9b8badb5ebf92b5147510109386e6094e034d6a7dcc42dea7423a00ad5dc1b72ce820d0fc81adcc9fc829b7604ec0637fd2383f1cdc6d7ebd1c26ded2aeec380896ee0198619f23d818d308c7918e40437693c67b2cbfc81246c363301ae05dd1c2bf18936359cbb2a4200bd71bf47bb86ba118092459ce74b0663a4020d6e9c26ac562f5f4c0dc75adbbaa6bc562b17a687ef5ac48e8d9b82787ae5badd2dd2fe8ee35a7edb56a6bba5c0f29d9d76b753df6f3b30272b5803210101009040404a402021a31109018028140d70239105005a239586707b66cbb797e8075047c1f00455ab1fee7e9a7b082359a919f7e0b2ec4608d5ef5cfbcc0819a07bf00034ca7d3d1ea35c9f5f4ef7d922449505332fb8c192328f4694bedd3fab6ff8c2723133bb6809a96d93e5790633ab0026a2a269b209fd9faaccca560fa74a92576ab867c6657096aaa04084ca0a63c28f9ccb90c35ab3e3e3a7a91ae5d0d61bd9c61d67f4dd03314a9c7eff8f214dbd7ec9d612b5df78c7255778e6d3f49cc9ded389e42dd0a75ee5991e03b34b5ef4a5650867a155486ba24c7950565a855a11e55e34adc853ae4814119ea3b83c53288a2330c7864c063f77ca741096a1ebb957b582e16a843d8b35992967c66105eafd74b0b50efa892a483791d1c432a520d4b6cb0daa554cce73f1683e9ea6450fb01920f36a5327a343bda3b9e80dae8a10075d18c263cd8af577e911694a0d6b14bd3469ddaa795b2ba7ac3bb38013d5959cfb2f15894f511b1fd61da7f5a6c51bbf0d85453ec61b032f9d228436d6d94a1760a70c46c94a0c6b15d678da8b5bb12d41d6c7f22bfdaf22f87bada5aa5a4ced96c23dd78bd5e2f1b69cc12d41cfc800135d17e8dda7eeb0b7ac32f2b04f510a801b0a36ccfca1c0683c1f6181994a0de20870fa096c1b251977c665919ea2cb07f69fbc665fe3edab27199f7d0786c8c83719993cb1c0683c162b16de3041b94a0d660933a4b4fa95f08ff85f161280145925393488ca560ffb1d3a5885cca1a1d591aeb31496759d64a7f00b67391234fbbf0e0a4527e87128180810746b6afb2f83c6639b1ed8fab34374cf3311d0f07dbbe937912c2b67f66b04f972adaf64f7b6467c0bae05009ea0c62dbea5caa6d5f56620c7648beb4d37cbc7ce923b8b52d51f924b477f0f25982fa8219b0a8a9de17a9b42398167bc1a4cc1d5a222851171af34265fe40da86a13226688e2fe810fb867f8f76294ae4efd25e6ae782c6fc0454e69f854a0e36581af2fc2d9fe38d12d49ae6f47b46443e33a86d08c00750d7f0a163819428273d254f45784852a0a6d1d2168d7dd29667659ee4269f7956823ae8c5f301fad0eca00cf52ad4658e32d4a48e32d4aad1c98d667c7d796f16c3a1163f28431d82d786da793effaaae2377198e156c7a54829a82ba8ab37166002c5e1ccbaf55e9f486398e57c499d6fa96d258f8d477a5f6e9355b2e97cbc7faf8f8d897df7a44238b775f53bcd7be564ae1bf7e54ae191866170d66a544e3d351fc1e7e6b5b1481cc724d2200bd61004a7466137e54a32aa84d68452e37850ad3a52492559b4285f9410c228f9b4285c989c9e4a650619eb07208730b630bc3d1e58cc1183b8d4922e274a3d3114942263cecc405bcc126e2991524d707135ba843126b030ebce1e63e6ee05d24b72a4447c711ee6665143b0da1c1069f95519c44941c5619f8c976649f33159bec13c6aa4ef6f1f52c651c8581808aca334684224d1e23c6c8a3a5c7491e374d93078493c14dd3e49122474aa5638630c6d86fb5b319f500844d66e8568bcbd229c618d7d1b13866870e210c883ca83616bb1850220f4010fa398df2569bf3eaa78d0570ea9f548b12bcb65e1aeb3dfde1323fe147af77c28f5eaff7830d901f27fce8f568cf68c887fc635b284bbe1ebb3da2a1a121a2a1a1a1a1a1d96c88686868684895aba1a6cc267ba8129beca16336d933856fc3e023b03635af0577add6039018c360a6dfa27bad081ec3180633ddbabd21a56a367df06e0b8361acdf8627d177a7d51b15c9a953777777777777a7ceea51a2babd607843d18a20c623ad2655a4a72a931abd11ede1d6b45de4fa8ff1afa835da54e6b1ed37b65bb3078fb5c1d0b39bff7cb12f2fb9ea17a85d55b5d65ab5a86845532b1837bbcea8aa22504950d995825adf770ee6f431fe5457af0bf64963af9eced91eecd50a092c7b85841deac608933a6b30355a2995997c917f49f2b36d93609e802281531edbec1d5f9a84e1059d00a340f04170476583bb2e3678c4182f3fa2214c20f1c349638c0de62507239ad83762fd40c64a19be552da5705e02b5c08a90aaf8e84ae904b5fdaf1791c37989b51a5024baed4d8112d977c11aa92045f36c0be7776465f6da70b4cb1246cf124f16a244f48de4b3de2a921baa0e3d582ce0df56fda40f68920d72a508bd4714897ea633aa8316890f0695510374a94309909376d2eee1fa6abaafbe387f2cc3402db010d1a9c13f0518883f52d97dfc42368664bb691882d582e119db4ae563a4faa45fbf7e9330084d214a54c727f5e92dc476a8b227d1be41f5ef515035f126fa22efd091234eee72eb79770be50643bc493ce2717c82a42c9cd6ffbc1f82549faf1660377c7fd2fae91e7a3def9761185ef3b4dbf569b77db28704eddde799574ab49ea0dbb20c574af404b7fd330c40ada77d2f5d934eec256b0882a15579089ae7bdf75ad0da6aef68c5227aefbd6168cd7b6f088220354f1644d822d7b72d3cb557c46e84adc55e74524aa9bdd65a4be631c2d0bab1d65a7befb57adc758577035eb08ae0662984356edc607cafb5360cade5b1c44d39879674cc8ea3a34bc1718758c7adf54df098c75c84217015137118c22e0bfde311e45143a601a3af9c4bdfd81ad1715f108c655937a5225012a891f8a209e44f0ab5d99cc9970da54894548d65099660b06a74ec8ec734b9b5295417385d32de14aa4b1b551479b5295417342c1364d5a6505d96d8505dbc24f171b3f5907b3685ead2c4e2e5bc295417a62e38515485524b1886556a948846a2463ce3dd30e5a4c477c5061f44723834f1b1846762f0e038e3320fd9b98cf2f0902797d17d66d8143be47c1869829a82c6069e8f224fae7da2a8d242a1fe5c622822783d5e4a2e19b6691a3c440839c9bf691a3c38ac86c0b3d4d3436efd441f325982508b5c6e9ae64e1b962e939ba6b993a68c93676c9ae68e973b196f9ae68e102a2e777ae8f121cd9d28062062e714bf36853af2c4be9b420dc1c53e613c2dd55652acaa71d3c7e3bdeebe52bae00d4da0e4453eefbed8da95928f5e7bac9795acb514d59067ddf537e9a36b87b93e69af0a361b06bff7debbe90a5bbf6d5e5322faf75a6b9d821a3aa594caa8760b83616cad5bf0ba537d56a794d21a50b7f6f844a92a2cd5ad87484123d45dcd2a8263cb67fb1560180caf288ef4ebd78adb95c96ddba8da28116ab402ec63b2a22649b6576b9a308bc57a1ce178934d08fd6ba4c9210514a9ee6b52fa26dc38de64b1da3e572ec53c97de53edb83fedd96c3623605ce5bbd3a5c0d96ebd87d1caad4a405f6285a21a3c56a968ea8860f659a72a17db7d10034a0d9c2b8c647102306827bd028a0e77ea3091278935352f612c51a285ce1643d8d0ceaadb494bb8a85204cb921dc4a0d55133e68730bae020470bedac4f7c99e3244509969d8f76d65f1573d0ccf1597103af4773209078a2b754041e2e51ecf385669f34686cbab455af52e980d82a1d195b35049958d206bbfc71a5543a8d365b2b913b843c56ab09e3c1c316532ea3db16bbcd70474c2ea35ce45c26840d7b7c23528c1f8f2606b1658b0fae9444ecf22985e00936886991f3282db78ff1a263dbaf433de41356614abdbdba5271adb4777d43a6422f23b044953a77a2b802aa862871a2922c1144ee3686f600c5193aad5918f9847141b2edd3c0201a3551b06890b9258b6dbf02dc7b03a360a574ed1628f06cfbb0ec59a451f38334a3ae0102886d1f68a5645528a28926335430f90206c5a24c0e5d6c602c1973056dcc95e9e2a2483f150a2d516cfb2fd80e7902da324940dbdc0746e4d332edfa11d0b60902daea6accc9a76ddaf557d076f7006d793fbd7cda9d031ae08006b07e44a89410777c44c248d1a40c0ce4de58e165c8ae0c155a7d0668fb1444dbde160bd0364a056d7d3cb8c8a78ddaf553d0564a01dafe9ee4d36a3b95007d6d397ec8a79ddaf581e87b4380beb81a70f2796f0738e10027804ba56d09642121e5496aca1b1c982e50c345165f6c49e82006adfe0f7d990ca06fee032ff9bc4cbb7e01f46d2280be3a1713f9bc4dbbbe09faee06a02fef832ff9bcbb5d5f00fa3e0540df9e11b9047da348d0d757e38a7cdea85d7f047da594f4fdf1f0229f576ad71741df291f1ab47dc9e79d02b7066d4cc927d843833c34e883249f60081a0441833a12e4136cdaf5c91d493b92aecee5011862284185491544e4286f0b1bba00a2b765a90c5a7d240dee3ed020cf45453ec1ddae7fa4c127230df68ac8451a8cf240831fecf209eac8a123c7b844e55b326a9b104bbcd46983c591a6252553743f3051823168f5491c1de0e860060f63d0260731412c65510549ad4b18464c4141c66ecc17b4fa330d4addd0e0af4615f904a5767d0e343845a4431b9d7c8253e10d003ac48d517f031d32c974981b92cf9069d78fe950031d26d9f21936edfa19e87087810e795ae433dcedfa423a7c0a898ac86768ea50ebd017453ec3a850ca860e7f4ff90ca5c2290bb4680b229fe1d4ae4f438b415ac459597da231f9146f9b022ddaa8219f2293d834438bba1c40e4536cdaf581b4b8fbd1220f484b3ec5ddcbe7e5e33a4283235c1570f1050e5b1091d2142617d99d89ba0dc1660a5a7d97169facc8634e3ec5a75d3f6b31ca8a3e5f3ec528514afc5959fd1a59e4539412a7accc56453ec5a97db3321c987ce29b884571ce689b2356008a942bbe80228918286875042586a81923e58a181c0d0c414d69f80d7e5393fcf11b2aab8fb17d63cd334fa937eae337f88d1bd9e8e1383f6c67bc791185c215d98db83798ce681b8b8c4a4627bbfeb5bef3222f3af1141d76f2a270d7c760f06e4a4da2fbbe0a6e72ceed8ae378ac3ef6bdf158c56205e7de348d39d4ae0739b2011823b632b20220c9eb67c6bd170065dcb751602cca9fde4d60635f58f6249bf018e70c83cd2ec62950378fdf493e6954112fb229605894af74196b0c72cb17d6162a6eae1f5b124cb81dc29bbb59c9813f3961a4ee6c09c55099828871a5bb62c7d7448a04abdc103c3cdd11235adeed3d214516514aee9cb11ff02ccf481e3257c7573ae1eae9cc94c1998173a70d996b3273e68b19323f33667477e2f410fd78bea62477c2c844c85a86f7c381cd3e63648f0c939e205b1628bd274e78c078aeb0ce5897267264162e78c064fbd359b9e1ac544143f6c894a12b83c32345d8e23569e1e361081e2ac69e1f9a3a5af0c8595d9d115fe009c3f5fa3189c267e4c9c8a806d784270b1357ab67b5389154ece458a40d2ac911db9320624eaf11a77bc241d93d5d9cf33951240c5e183b343ebed81acbfaf9681082074564178548852ad76b4385ce095f16214ba77b42821373c68b3be30933482c21c63e75ccc1474ea0dba70e25f290814b9b9c3478ce2c8125cfca14bd28708ee0f017650d2f8a163626224c87c589cf49124f46d7cf67270cde1869a68831db158c949b420d0f0a898d8bb8b2fdee20e94dd96c4e38170323da726780a8628bcdc64615e67e7772bd3b5e6c55e0ab73f2e4640b9b1c978d1c0f50e2d8a6b06bca14dc94216c370867b30286af89ad88ca07a5062196968c3378504cc214f1b20405fba6ec33b63445e43da1e58acf0cdcc5bd6943fea2f0ec46255c3f3e9bc5adf961e9b7864a156ba6dcd654608b92e34bd3c5cd48d4f3d9a18227861416a40e8a295e2c6d21f6e03c2705893227056a8ef5f17a65984095a3134507147b3dab86063bfb8cf5ec0ce99511a504176f44ca848d77c696c8a880957b0273515af4f0da34d94f90e9c19aac7e3b16ae89229234118507044b03dbcd41a152daa0a02871848b82a71f9b29b2e8b181a2824d54af091c5b23de9e2da6c38dca659b52842f872f71c6954fe7ba34b8333bc039b3c3ce8b3bda7c371f7850b7dd1c91bc7eafb5d1bb479cfc8c1d010354ab975e54ff55efad558b1cd72ddc21176e1989c024a0a2187ba674e24e9b3b71ee84514922b88789631e2eebcad8258321d1d0508a3a52b192331a713161e5c2205e4ef7494463d750310a151535cce27a71e7d43c64804bf508933b3e9972c5452ed889c2c054159b2a6c72aa6d8a5e5b4f917109c55040718acf9571e752e28a6beae8060b710b3b87829b2eb1448755614d584050d711153721ae51b919e35c2f1e9cb3cfdf4fff6b12dd3434e9856dffa7bcad0359dbb5a3d9cb5a5b62af334a696c1613b2b398d0f51accdd734986af128b35a494bedcbd1cc93275c414bb68c1f06d584bd4430e71c0c1f4fd5624bc69095a5b5a7f6b4f4a29a522766badad16098e24accdb7f3e768a6c1a1bfb3987da796e22d82f7de0bbbf7e612534a29a57484bb2b25a2efbbee7aefbdf75e954bce057128e2f08237d1c48125c438cc81179b79a82ccbd5b85aad58f88622ce8537bc222e5524a9551a34ef0d459cc37704437c2bbd113e0d65b06178712ea437c0af61b8cd5304e1b69512811fde2b44e386b9f08e335c690c8f80de30178276ace06d342b25aaf56e0a86360756304548babd6028e291aa5eb522c1f7f8a5caa808146f0c95304491c6cf432e1a72357164c9f57bb808ce4a988de30df39079d29c87cab25c8dabd58a85592cf14395bbd1ccca4e0d72bde1ffb40ca0b5d65a6b4110bc74bb534bfd7241522152e8887c9f4e5105cdee8029fbd7b3f661688230d891081836db4179f4090cb315b8bce241aa4415ddaf2ba52055a2825489a275157ef5a2d00c5225ca633448951edd41aaf48254e9ed20557c1ea33b48952055e2788cee20557c514e77902a6c76902a3dba835441030b52858dc7e8ee798c6e514e6f09df0dc35c7b43bcd9a4c3ca9a3df6ea2287147bac26b4cbd46357a9d25a6badb5d25a6b6dd59a4327f786e193188813a1283e0ec310fcf0fdc604c46d51af4ab86e9461f07d75d628e802fd4f183eb54645b8b0fec8d3b8881f726155204d5bdaa50ac7b71f850e2c5d52f209dbaff049673df52296e9b8bf5e34be1d4dea4a318c3d6682ae71cbf516a34834149fd216f8d48bc2efe979dab4c117b151698d60a2d02b8825b2bef5359af874c532834e00fad60301fa9629840beb85f83c10cb04d26a6d52d4305cd6b34c20f5562d8822c72c8de9f65dfd5d59bbdbf7dde745746f29115cef7afb3b7e42f879fb030849495a9652dbf5593b6b6e975f57de7a147e1ee85b3f0f64522b63b15824f4f0dabe30dcf27bd8d593b514f2a2d52ff15be913f6d2d447bfde4996f8476ee4f3eb5129d498dfb6d68e297164ceec93f6c800b14ffac6c63ea94fbc5064bc0800dbde3646a8c7c05f99d4633de62984aca42649d10c0a3ae15130c2c1143d24961021c54e1a9acb486dcaaf0a1e9e609943254713cd7386a82d7e6d5ffde5ea59b57d61b87b653a937a43f5a53e6b53dda2a22b15ae612f3a6bbbc442f629c6b6daa517ddd01433b5e92a00629e3c97fea5f475f7bd34046124ad4f99428d61daa4570c35e6b6696bc5f2193788b9961904a4d532835aa690560fab7c97a97abcc2d3e547c3eff3b5195fa351f0355a908dafd1f4d768177c8de672b9de650a71e5d58ba6f8afafc1be46aba046abf135da7f8d667e8d563b6a63ead71ad6f47a6643c7bcd4d03d2cd0473e1afa872ee14bae4053a05328935d60c1cafc3710f9b4bffad5068296fcd215e7a3eb6d8b0d259fe16f93a2cd1ad93954e66fc9b82de1b65f24dbff1499b6df70229388f31799fc455bf8036dbbb7fda9d65a75fbe7c95a86bf5738e5f3407e7c7cfe650a79bd4f65aab9eb7fbd15c40a98339b4245f1f68f599f7a3cec64ba7d532bb33ed1f624c4822468ae6f6921b68aa7272c349f272f187e0fa69cf3d1d6ffd8fff9f919a610c79956884979d4c940ff72195edf7a19b800799941f75bfff3ad9701c80cba66d009af077a20afd6fffc0b08d0fffcfc9832d4df0399d5f77a0bf43f7f565f1b20f3c774108af068b6655a41897c8658143421ad77bd8f1632436502072f5dd05c26978d25cf607bbb3a5a682d938bd51b877cda1f1d2f3aad15d62765ada048f482d7862e3308fc20fb3f2d33087c145aff4369f4821774172a1c1b79019d7cda9ffd51a40ab6bf9df222bcfddec4195f7bfb40a6102ed60402f4334c212d213e35dd4ea7fb20fbb0a7347ff1668d7e7ec6a300f4305306d703fd0c53062e405c56869705d2de7b4ac0912b79b0f8c20a097cf0971904fa9841f783ecbf8cb8cc20d0749fc7fc29cda5cca06bfef0f9206b06a1e0723d0aad7ffd8bd228ad8773c0c4cf668d6a4990b8697a124797c70ccdffdeac910f133f483901161ebe10a1f9db9fbf9df2908ec7dcfeaccca5a9530ea77e3fd1668d5aa20d26daa81dbf4ab6df22dbadf529db9a4ceb5172a1cc62dbd5deaccc8716b97ea92d93b6392bf3efc0885cffb44cb6697c3591edeec1c82491977cda39db7fdf944f2b95eb8b390b6aa09bb60e8ec8f4ff8a4cbf835dbe6fff5a0bbce420e7a008230c304913258c2aecbc09c3802fb868cae2ca162cb0a0d59f1dd97092cfd96ee20636fb9ced333e28d9b5891bd0d41ddb2c937f27c92f3399da2924153ac7dcae4b35194610021078a0031cd840063070010b5040021078400382a8a0800420e00403106000012041c9c7e60142d207461ee4e8e0061100641a607081b661411005337e7c5a3d2b727cd0141f2cf2355a3df2355abd7d8d566bf81aad2af91aad32f91aade2be46ab387c8d569d7c8d56a17c8d5699be46ab3b7c8d56a37c8d36a4da66102282183e00c30b2e68a08593850a4c20022b3880010b4801052007f85100130450c20822d07a84b003e9a848078e1907431bc4321032bf068d0a60402f5766951f12f91aad1af91aadd2f0355a45f2355a4df2355a5df2355ab5e16bb47ac3d768b5c9d768f5c9d7683587afd1aa0ef46b149d9388e413efa05f070d7395c9278c49cf72d0b1247285a27b3cd1474d7275a27fd426ba0429f24971d02bd41b740a47649c76c106cd82cb897c522926bada96e8187268c9279d52a22b2e89ae37a230f9acb71a74cd21d195c9483e2bd34d571d0dbae623f5eb115dab115d7746f25977f5094f1e5297ea90ba84b73ba943ce753d144a079db5d5a66b544d57df549e4157291974fd2d6521ba4e8d40bb4d4e1681f65b08b4e3928ae4d36fbb7e0cda9940a03d67a4fe07b4377940bbce498641fbae03da794879f2e9bb5dff05ed4f1cd0de2b23bba03d6a03da7d404ae4d3a33490010d646034f23232d66f41bb1406b4ff9ef2e9daa72ea0adcde7964f9f62c1022c58200c82b40511a22933840b921c706c8cb8f1859415329e92f4eed0ea57405b0a684b249b48a8a4acf76545eccc90000c000040006316002020100a078522c128c88230cbdb0714800f5e823c664e32190e438118067108054110c3200c43310001ca1882904310bb42015b62e036010840a95f6a204e061467284419ade3947a4f284fa46218609498027332540f54a390bf928b3ca217bb657531a3b60d08535b595b8d84a56f8d12a7d43c3010a9267545ded74867d35186cd3870c10ff848c6966f8758cfcf91bcf11ba9f0bf7a305c55bc301c62f71dedad4a5e3b39b409fcafd7845dccdeb75f8b06c8b202e6a41598326b1667b4bc5c852ab311798674d32b03e4a41db59c3c439a9467441898bc054649331f80206635c6b756cb33a15bc4510f1f928447b08a1be42f16213c129fed0534f2cf0794fdd817a4dd1b7644fea76d8170c7e2202e5ca09ce2c25c9ec9ed167c3c71819972d05472db590b39ca517996e83798186b7325587371f76eb914eb828bace167039f0be62fdddf9bac786aa310eb35cd7c8a7cf117b440328b885b93ae1a4a5fb88cc4e0458def869e137a3bff8227baed4ced9f7603311ae7b8415104b444db4461be7d7003915ba95e5d8ef28b6b85d53804360cad98e0d2ff65276f3ec138768323314992f0b2f77cd91b79db581b7ac2e87146b4999fe20e2c994ae993ed4603cb699afe0ce54010f175b74d8adc8c1dc7bd14ce47694874ec744011fcbe80936fcfdea719d0299781f6dc0b996d601d38431011c7048a1d0d56715c321047eb3f10a17419e288b7d9be789c5f31d0292704a0d46920e734078a4e0ca864f027c7b97726631339c57d3a2ccb61a43f82b8a0dbfa0221719609e6644717bb51d8eb786563534080d9125200c31dad7a678a7ddeea585aea61b5a1e38c1d33c3710686fb9c643c85355a129af5eb95f0637d9d96cc476d0c98fbd6480ed8ca2427c28ad9e9d33a159827f30c699fa09c9f10dd24b5667c02742b870542ae5842a8d0241659caf0899a8ac485c269d49ee4cce0756152bc8e48ec2d20bb1967d72a71e90cd87d0f768e23d4f58c60b864b08d9c39d201b28e3920089c58b830737f4f624cb8503b419990b1c693e0429b5ecb312f358b7499f7a193e803910a7466f19a68f81af33ae9cb22e522a75b937ad36060d763430a048c554ee703103cdd55848f17b329541be4ab80cd5f45c4aece8c25a0592824071c4eccc08a6947fd39ad3e0a57ae44fb3ccf91164acb5218a5e2042b5b652cb21bb23f686b4efdfd711fca556588cc5d9bf710ee94b0def866293b44a82a0f52732a429f0edc7e30a7c3a52ad24373f706c6213c7ddd4400ab59311cbfa6986ff61166555a06ee61898bd5660d81eccf74784ec899577143fafc45fa20faa2745f0bd2aad77b37c606b28208ac05f8822d4e690ad66bb520f712130b2d08b6988d5ab13ef24cc447d278b37e3d4af641d1f003e8ff035f4b9bb4744bdd8e97b87afbcb39f04fd3d55580716152b02334c03cb687a70b00aba18a855f00ce1f315c1c6601db17a2f04e5adbcc11aab39ca6f5d2ba3ed0990efe5fe0e67872b60aa03e20fb82622658361db207ab42680245ae55baf4e27deeee2ec5b2622a440d98d4c288960b3b02d6f6089d01ea0a5db0288241586cbb05197e26b4aa7908bf399c7e252504f149bf9142b2844c8a8e3126e5b72bd9977623d821a628ea62b7c803c414d1bb2ec6d127271247ae9893465b88631d2a4d0c7e1707a25facd819b3e0e24b09e80b411193e5c1e7c3af725c464b3e7b2141f5c3340c9e3961b923e0295ad5f46c7743d555a28a53a7ea20942d9fcdcef1c4af0631bb1f9a87eea49f072620a36354dca697e88be8cb14f613fe4d86853f67097887f021b5f71882589b7fb12d44fe89efa6faac460c6437d440595013653a15116f312c04690bf08f7ae5833a83a405c297cbbeb851aab3bd30247f45952200f42a2e870622f44921de7fc0f236358c6e3c0e2ebf11a32799f643f210c040eb8580c090fc8c1db507c179e28a221784571da3aaaf2ce4d9b66fde6cb9e9df5fb471426fa8238f84fa6244ade99cf0a688409b205c4de40d61d77d0ac2b62abc42df8d2ab6c75d75d195e7c6688f3756f20d82128038666efe02866a77563742fd5f7d7f9d793f041304e7c3f078ae375c55a128dce8f92076c849818c7c7c6a2861e614aef1cf7543d81f4e87b3a94ede91977e3ee2aabefd667b9a8410b728148b56e78f60c7389aff8dec07abddc8f3d0a6175803efe67e983a031ad3f9c56952ce1379404e5e3c1d16d91fcc83ea7273d43ebad164584984d66e80ad74e9809eeec7bfd12f0bf23620839bbbd4b5bb0b107d87a036c4a4ec261d12eec785654894876cf9b9a74b546cabd2118cf3e7445fd3f45bf352423aa59b9e98d2955386142f63489e8e8680546f021b92bbc4645c2caded39091b29955aef87cf6ccc5cac12fc05d18de675c572a51c0e8cb84c6ceb7bba0c0a4ace782ecd7b511b292a5cb700f1c739a81235b06ec18a38cb31c11c78001f13cb726477ed645bfdd53cc6d5d8dc7d375ff568c5485ec5fcbbb74d8bbd9bf2ede731bb414e758b88dcd44208be9cf6798010092c431c2441b60106bcc8b660fae0b2dd4b061010692aabf9698877e7b016028143188045a47194ad61ad423faa29a1889dca187b1783385d2651d0bd4cbb75d37a34c4ebd6367622aef62fc11fb901ef9ec12d4b4e193992e83bb3f3c7e730a15daf2b56a876195dcd32da7c522e54aa4fff21d94f8abab4cb96f992f3bb4ab02114c6605854aca0cb63aac50d369d1c93034c30d91a324c5cdc214cdbf4896151b277e200ca23cfe6fda46d599609057be7ed4a474f4d4eaaa859da469e1656d740457469860d8f8e33f07f34939dcb9a0f74721f6d9dfa5fc688ab1135efb31bc3c41c1cc10ccc667458ed152dd6be75c2f3510170d3548a52af3bfb2dc01f016a03f253c5d28460539ec6cd5bae0735c1f2750016c48894eb32bbd48ea7ef26069b28b408fcf83aad0e7d50d5674710c22f3c9a62672829f84c00230615f1332c30246db12d87a373130ed56bc5115228b6690c058c59fe18359f34e2d331e23c01aa5fae6d6f171851d27e890c8da9cf3ea843508f1b3080f6bfd8c5e542ad9055172cc967ca1c4c9f6e52bc049fae4f45eacc3be8b60f4975b330c57b7d4fcd379d98955abbc100926c4888c4d34808d968cfdcc008f7e720fee95fe7a5198f763b0150a01ffceb3809e42db89a9d2abdcb6485ecf8a6123c05a8c5199aa331e31df07b45088ef8a58f97b9b98502971d061b12d38100a1a495cca4dcb0e4b198901b9a4a3e378630ba397d2a4001053500281c688818bfa5231025f6abe5f72554c22d674414db13dd6cda0fd4e08b6a573fd5c0d3543a3806c914cf80a2b158dd8885d74ded1de101d5e1276d5d7681c0f14ebb13dabcf94d6bf243fc3cc81e96305dd7f1a417266250283637b322d183665368c3884417ee51ebca205ffb7597af97efce63b11a8f2ade570ee82e4558c8c94778423e00d60ecac26edb55da75de82890f1007faa055ce16bb05abc3b32ed4ba498090b63390576ba0aaa7aa8e2666fa0644368fc1b297fb1e26c9c3ad12b853cec25106fc12ff42cb505e1a8ddfb647ff1f9c4440cdfe66bde51f45b5777ac130f30a8aa9f023420c0f74303291a7679278581c1d98c720091e9ab9c4c360d0401e8c5ce0d1cc643e1b4e03e03024624fc324f1b0381a308741127dbcae80432a596a85776007b2ae65cedc002651c71515583f2bcb81c0677beadb31cae4d203fd8c6cecd74d481e03460fe06024045fc724f730303a108f4716783413899fc1a001383899c0af99907c168faba1df77e22e02d5de8c68f15c72fa411b6b9fca614625bdf40ca7c6760f14b2b479b6b7231c3370664fc5e665dbf29cc268606ee5409c1bf1c474111347ea998215806f871dde20c3e5a90ca9570aaee3ff2997da0132b9b9d5b9880003b93ce4993d34546db5f580dfe781bae1013b63082d00c4a471b3b115d0452f21fc016fb1786e625e10ac58ed0950b1c10e79fc80b5bd9514d78ca308988518d89f3f20a3ee11e8ae30f4a6990bcf432480746d2cb03c1b9dd8cf76750628cce4257804dbb9b69a0872659e8608c08243475c871ddaee83b5d200a4975bb9b2a582d42520ed049aa6e585819a5f2f28a208763dcfa9e2e06951093a4e405c8b280109eda27ca3174e15ebd5795732b3b6cd94cef8e501a889413406f9de7685f3018f5eefea027151640b2034b77c0c55536c93ca4f14629ce464d673cea1759cb5f5c556618bb18300347583355bca0588ccd06ed4899bc770dadeb61864ee069f602fcfb263d0c32269a014bb07e30a0ca0ba6e0d0e7f7f6c0bd7d60e15daaa7e6d9d0a6b746229ab61d7dcf26b534df4ec56fbb9a67a481b3a48fb7a3f9d573703ae2ca7a87602abe837cc513856696eb0aa5bcc1857d741081a742dfa0704474cfdbe8389bbe64217d413d722a62701aacbf354f225534af432776d735d352fc9781d138617c5a4c725d5eccb6659ae957d05ee6a432d0ce56bc9176ab75df811534c37c26e0e020601f42c0088358dd50e910752c51e0f0448c6e159e5cf4e11b909c2dae75ad57252aeeea4d06cf325e7431974ad6712815c7fb5325cd57dc5664fb2120d50fda10b7adf5e25063c4672df131a8ee816d1df13acd591b7652cfb2f2dca335a42739a7fe816e34b3fb335de87366bb0faa68b23df335c713c986862477b13dd62eb4d62bbe607a69c62f7093a382c14eb425bb85d0d0b2e60f9e76946848c5599c2cfcf087dc12ec91857f3ea57f2f52812f21853fcbf2021b4765bc5f9ac8b1a76657da22daafa246e77e0e79b0613ff03364e7cb3aeaa954f2f8bca9915f561ce28f9e3d9ac8c09145863052aa724215c58f0e785469715a3bf5392f5ef1ab610cf5ebef68aaa857f9e0a1814be4b8822b86b60d9503a360955b4710fda7e1a276850ef2f2f35e1c6a3dbe5f4040db7edcc355f6d873e22d8d8a71a33c08c60ca4b4d713b8c4af385f7b4c2b4cb172706023762180868d3c656b4b8770497ad22080c1f07d3c5bd7f68962956bf76b3566262152c44a6dc4f3bf713f4c0e0541a66024ec48573dada30cb858b135bf1ea5247bff4136ecc822df10cf0e950d90deb540eebc399f2bb12b13b4315eb4192bcb083728244e46bbd5c42a7343af0e3302a89bf6e39599343c22b2767f7745600d6250dab84ea86e22a178c30a9051b8265716e1f71927d6686a178d8c54b87a6951180e6f102e1c7b335cd9d8429004980bbcfed102e4e418a2e4dfe52853f7f6df7fdc2941c8b3f4902fc6e300d4d65e02c0892163a48f39c2d9c5300822db79b15127dcad0a8ab51a616dd061db3a59f966886777c4bb2bc3cb4690449d17bfc6c5ae08e5f144bdc23fed84dc97d5041d6b3b66f375392f7f1c92b792f9d99c7556d7e97b38d1189fda95eb0a5d60f8f8507d8a75455b483923922c0584a66b0bac287cfa48cfa4dd1a78d2b3ba6cadeb37d849168cc68662cbeefe9c1836356defb678b822e5f1d285dfc5635fca530048b456ff5d815ed9ef5523da78973d12266c859de450aaa3b78e85724ef6336297189a83f49078b14241fad9516ffa3aeccfd2ebde473076a0459f049959f44f02f3263f681df0b71c01660154d55749dba9b069644fdc672a40ce3bd0f21e1f547e9bf0e4af7ca03b4b4d36a99f2affdac210a02111123b411f4cfc586dda8391e82c8443f386050b478bcc4f90f5813f18964f499161980686c35eaed15ec7fd68d1c5794eee3120b2bc40936863ef47622025be40d02f0b755d038dc22029867523f93fc83340eaea350d8da8de9da27e847fe055f7121e4127d430ff05b1a3fe89b79f530ac4aa8fa5db3c996ae376783589001447cfc30b95fd7af24d3786a9139d8a6ed40df05b1d56fa3af58e413cff6eaef8f3d6863be1be2bcd6a08048a474444304050a43e752c926e6e8fc06b6ed9ed58b4cf2263018e7dcf71088c47a50adb483eba778db623e007f761df8d06c05f61f720bbcf701f31b744072a0d7edcd0be23eac1dc8ebc6d8c7a6f63a37755b1eda84745eba8fb6ff66379e04ab4b4c55951dd5804d4610719aaf81492ec9125577fd748ee71c29802d48822d2bc80c03826b0f000126a851325ffa4c876712303af76aa353451bc55027014b95fdd06fea3ff418d7419c8630c7af027780e7cc165006a343574fe89c97dc1309c0e2f4eb9063c1dabbba3995f3de9b32e75d6fc7823e78bc211c3f4d1a8387bdc66118184011a41f41d87552ee5d60f0cccdd04670bd628e5f97ceeea945b05b740f238b2dc52ad8f15256547759b01788a05b72d7afa301461da7d77374a8517de61e0f14902ae659da3f64dc2219e0374007766baf7ea32b3c6020c38034846441fa221478c6fe47fa110fdf62f27457b7f20c0024d85183038691c73b3f30c7c014ac5ce22a00ba525600aedf088485fc26e8c06ea9184f90dd9e78891d6770760f201687f091f6718998b3449eaa500951b7274ad40d98d210bf27c933c56f14107dba65122b397b1f446055faff5398c84eb34633b534063e7a0769e09898b3532affc350cfdc8b2600377000cc5b74d141d00a9d3e20cb3d3128c7801b3d589c68ec099c3fe74a0439f0271e7ac544bcc7c36e208d90abca0b1dd870a28fed3934c37dd0efd67f119045525f7fb46243819e1e98083ed7b414d413218b3b109505b08185c391308322e9805d832889c56163534647d16a07c5d26122974c901f6805f5f62c0ec418a1864113506004ac079c4344168209c1ae56ab59112e96183d588cfa7c2f3459a901f323370084413a08b4f64c5eb5fc29176900c8c1c8c1180e7509e9862e2b021914b3eb6ab96fc7ba0b1c415000eb7420917bf79dea14b3b7480dd88dc5136163af0776e023455d25ddb4ee2c78d826c33b92d515d4ab896fbad51042a0db06fc092524fe78c3c1a5ce56b06c852def1002252bce74a1faebd231dc5385be8e9530702025cd0ad4920d03c76b382fa0081cbea2ff27b3e8876f4743c4edc8e3b845747674fa533c9d3eea5cea1f83860aacd4b9a3ea7bb7e8f7689d0dcb04cbc306c94813c8a3e049a0bf1a29f53a3044996651a2088d3752a0de9f6a869c6a0ce8ca614e30afafa34f75703bc1d14566dd576897d83b7998cbe14c5907a35c9e8937551805a7f04435cc21a1db21f38e6e38e3e8a1b123744e80752a0c0b8e043252ee51917e03399047d69c9116996dc2612004cc0352a234dd2c95761f8a147a8fc5f159a5545c922e922d30e5218258a8131c032290c743f13c5329351722903b9e00a7bd6b926527121991cdb292241d86649847aa39b3512ca4848f01c922d84e38069116690bc131084a152e6bac40d3027d334b38069218616bbc956f95a274d956d92d50915496ea32b6654502b6bc4552592ab84edd634fef123b9fab6adeaab75ad62e49141984671849116c83290f11c28e8a703010813c1e8be789ea525c246288ca89808aacda8afa2a00469a74558d8f21f3bfc80b20d15184854a4c7d89b452eb2e44208f50391128d1c406a90cf86cfd116c5d227279c0ac93075fc80e9a85ad388e0b8f55f36a7a40c0686000e216c89a021a37bc3a282d6e8a3d67b95af9a0789f66f6bcb0a780deee382ea739b22521c15673fc0639a601cbb5bb4970237d0dff333d40c9c29bcb5a978da22af0d8084806d4312d8028dea5b62d5a738179117fdf7e232026fa7ac8446e5c8be5e5632bc3c0e797ae62173be0a55f5c4168e896c2c7519ae1a0bb386084c96a0b2f0df6cc9d91155464aa37117d4d4c5f919d16eff169074ad7d141dfd499089b18da19bfe29a661a9cd894cfbd248edc073a9473292a77b1f091a956a65fd326491b74e93c1a3b318f15252dfa79d15f9445330e803dd30a731facc0d48802e034d552bdd8fd42865eb6c0cb0c48ab00a5c1df244397c87fb1f4b4ccf62222b913f5b20385165ed11e8e684e2d305074f199255c939e40f33f0ff4b761aa26d4929a57126198242b9fa81d1665fea7737cbc5963a8db403afe1058988ebab557e85d4d86b4c3c35737800440f7a31ec1858728fa948673e43465f6a8739a9a12ce01a1e99213b5340865ec45ab7c4ddb9fa5ed75cb010ebb3f5524a025845e845c32ec6ff8024b3e04f16e306078f270ed5318251a26da9117a94b5e792ab2de3feb5d28ed10fda5c0bfaaad63988f58a9d0e9ad693e0400dc8a545fa4075d4a38f52fd0e125e17ed0e0c0a1d4c91c4ccea6ed519ccf186257549d590e906f782086d2e611ae6e68e3839f7697e2b035d32e41f61b8fbc0f65cc00895980109fe1c878ed3d596b89eadb89be47a23c9d5389993631d632820b231283244eacccd97622414b4bea1e97ae80d9f14ca7f36afa3bbfa61dc6dd8b1189c3b978bf24906c3a42395572c98978e56a6dcfafad3ff6b8cab3312dbf861ef53ad7245a72fc2dff9a594bddaf5e908b2a7dc4c4ce03b450373db177dd17f78950874aef1fcf514e430fa0b8be72dad001435eccbf05242c5e830fac0e3ab91ad9823439ea048be000a0f781216df6fbb4415e1d47a6e179352b72e2945080c499575b3223ab35d7c07157bf29c41e4dfb2a42ca335bea19761998b9bd9fa6e128529216bfcf668e39e40b64a5608563ef5b73e98e1b1a8e400726cb2a140e3fab65d74204721768eaa31fd9608b71643cefdd2e216cb0a56781064575882d7021ac09969e1de74587d29f8dec895589c2d155bbd6519ae4861f2cff6a086e675d71e2850e17c61884709d47bb2035cae0000301029975a5f7b3478d381c11cf3f22c636af15045d5237a9d469d88c90af483b11d52efd0d0cb36e6d204fc372cbec74a6a5456eaefa27a607d0b8a936416e2d6c26321f0be9003b0dc0737c2c05deeeefdccd5b6649246068ebe8820281fd5805070e0996c57117a9e0b5830b3313eb950d0c12b684f6759ecb39ce6aa6c04535c79ed68ccce93457190df8df7dd38b09727b43b76c6a9c2557b4888417d83282c16bdf9a119b313ce60269bcf34666e57d4ffe1dfeea6bf689bd7132ad1249fb633219d1eb245910cb26ec9c532a4a61cd2d7160a11747d96d3094e444b90ee7b7f28a8163e2c8f50cb8ac3d681a1ceaedf0fc5d174344a31966481608c82bc2901d3d3f2d20a8f6264dbb2ec762d86a00ca57539ca37a4f8f787f644bb3d3c2edb257f875938461ad49203fcbf05621ddc0192d270ead7a1d4627e6494c3d77250eaec4526857944c383f3ba15e3f63dd5d5b9b2ca828c96028a5bfc822346b2367420ad543d442befac6b0b611534f99d39a8de7e1988f8dd10a0ae3a07df85cb8b8441a67ee3b3cf8c04959633903a8c216dddb62e7f411e721b430b674ddcae850148b2d7b44a04a1285e402688790f162e4743304b2c3203a7822a0b797d3ab3f8f68087e2c6fdbe95b41f5e2689aa0bee9ed2462bb089e61f3776b9c5c6b03da1c157266745e3656c4c3aa024c1668252294204cecca7e597673496093132935517891a64e5b0e9c4ea06dc336fd7155ca993ed1c79a65dd8c39cc6afae92ebbd3623d4942a0e498cad8d208e045481f03da89cf22d2db87f86e91a3ba79817f000f22ef74c3dca748686a3c47dfeb2b4a251429869231c834ff269a27c7d82009c72f853058f4df0d11757b22043adf54f6ecbffa5859add2d078264f6f7680819f1d11b7da17d762a6e4c150d1b878dd9007838ca211a14981612bad98177459c0fd3de578ca78d44169e311e8c5209a6f3c8a0cc4208227b85a7ded82630f9aceba4ed2265e73f6c2bbfa5ae912f96ae65a6ebcda38c3d8e4d86e1abd76e85db9878a066f45b8074dd52a8df694d0fb4aaac292a793803156fa39b0045e086d71a7f97103852e625835a1c6fc9530b704801ed4e5fd150a841b2648b498bcd691bb91f1f3baf775c7d7c3e8bd2c13ab0e983a1ec26732b62a0a944925ee8a499a386776a3801f8ae96aa53d5d982aaf366a61bd70365253a65067fca96a9129a1770bc129f80847f647c0b447720157ed49f35b3a8a6d8529b5f7269a2a139b0341452eab0b4ef6a4266f660c7d6ee2c90e5320f74071506f6bef933211a5792e731da5484227d224b2c574a2c19141b5628a13e78fb278f79140535ece17cad967a966a1235dad584d6c14f2eb749d83d921234eb40b276c667ba51339dbd4fb574693c8eaa1d4b41f238411be818a0bea8037cfea631db04f5b62ef36b37dc074fa72ed1935293c0f846d02855d01037a2f93952a137bed4774ada8b996c74f224a35aaf743464c69b0b7c5a0847b5eac51f4f65bb81c3971521c153cb5f1ef8fe8048fa2d188af22de9f8e332da0149e8601850eba633500c84f284314ac3c8f5ac41808d41509b8a64d41f653dc14fd3faea739ac260253b8af7b502178c7fad6c486de69f040035d7b68731ffbf38c70ccc9e1f9ecdbebee0d3dc360b94d0067aa5da63def22dc71a4c5edcf3bfa5c806f3622d41cd770a2d388c8a7bb95c98349931958bdb81e1a4db06acd4730be2b1b75a37d4549390a5632b3ac0222563635863e2621c0890387604c7310d1881d5a77cc2b1ebe24c30674bbf41ba7cd7c9ed06c2176e3923d66b157fe332daa04e0f9ef25e9b82026dfef61c414616d5c54ec5884128c6d0728cacf439bf2458246e07306dc28003b5b9366ef81beb5f82d938491c5e5cbdb08156501dc32e6675e4a381b9f12417a399e08017288d1d10ff34057b0acadd01cc57a01a8d5837178a9d8971851abfd6a54921d7290748c161f70399992308e2a4d198b8572d623f6646cfd1812c43b432ec5b124e7d9c6f5cb328aa264152e223e022cb46ec683226210a31d6da5f3fa4aa3e542803f5baaa5327c278cff7c2f6a5b5c400fb650d636badcf649735259cb0799afb6fdfa3ec4107070d98efcf6ad2d407ff350eea0edff5a4caca6d160c85a9c27f084c5d8a84bd909bd17fed361a28b684cdf9511d0b3685a4b589d0bc00c843d172a17b1634e3164d882d5921b1b7dfa2169801272629b0c3153334b2bd58e6c92e365819647edfb279753e7491276fde7151e9802fa0a5b854af2db76df033be86ce9538c7f9fa7af5e9f1ebdfd5c2a525f1535b15de59e550b53ed7a9a978cd35f91040c23c89e95510c5038c9755bca50f9b42da239e57faf83a07d9270bd3e89f892a127e9d81d416b9e9cca4014b4a096ddadf1f856876b456ca9700ecca25a446742d529845d7b1cd823f898f81482c30de69aa50de0141c2143a6446faa4e80f866e53dcfc5bc20545d739da3efd5187e2db7225dec900c77606ede6d6a55b4651843289fae12e147256168ca5d3be3f95ac230af79a43b1f7f6a9d2663606b02b8e27cea9ba751601590dae9f1a267605894af65150327f792ec9d45347a2503f8784883cca0198a62b133b639e8001501f9b1cab1b0641941d51db3675d0a681387c70aad86ee6400450729216db5d487178edc69344b585f9dd0afbfaad989a3e93b77cb002dbae00e55a34fd7eddfbbb280cdb248fcf915409ee988c66c6318fda8182f55e761011e9a456c6644cdf98a88d9636c7bfa6c480f517e77b07a0ee36e1fc25cd114e6a926110eb143684d2a3093c0461492176f7d51050b31d1427e98b20717d0624e9768db30e60b84017582c8f047b408536f29e999fba3a073b3c000be6b7a707f3842b1cd27ff5e4b9abfdb5f0b3130521bb58d0e70592bec8d82a88076d1cd03a65087ba226591e956ddbea8c576108b3f5984bbdd88124b19568f4d9084776252ffc63a5fbc630d806caa3ddd2f604be83485c85745f4104c4b8e01daa445db2782a35bfed9906c077961acedf3fd3500f253c90f630db432860e0ccba159622e4237b6052e7bebcd71226e307b030cda28b83d21abd2493537b2e467977aab6d472e2f8816838ee59878fd661396047c33a1d6f9685bcf7011ddc14362f13a3656b8a1ade31b264e258aa10dc48d368fb5b17da0526bb0e3204a8f3661153009bd94cce391ea213ee9708e648410582e459948b886c5b8b048301d3e76e188e0d0603fcfa3e44070c3b086611b715bc210a80fa4446487fcf0387dbb56f28e41b87045d40dc3f8fbb6a10f87b4f1ac7fa4b3cb91aa0c80c1a9dce17c0ccbfc7785063f0210c4d5c4bd6f15d93bfc574ed71679abad93aa7ce42265a51f55f503ff67bf2cf1cf5f5db200c5e5b87a3c88c130b05345357047679356ca12a5884e21bfa42bf82d13e5a507cf84bc55efc69c68c09fe8b8db46f9bff2c3efc3860b18b4c0e615c0991516d162d9ec46f9feab41d5370b895b82462565d7deb939aa19f98912de37d232bc86ed369a901d91a7153602d936cfc449c439e6f2fd45f97ec87ed94c2c6d275f7e711a97474ce245c3e403fdbe859913801f1d6b880069ce844f27d0278ee691895be5a33212e22d9e3c8fb6a75dbefc38ebf7d4a91d4be7041dfb0614f89b4bcef8ffdc2cd2db62372330164f149eae57014b0e58b90c2c5ea4a362b3217debc8a91be731db8e6ff00ec6d2451ad5588784ef8287b5f52301b99e94520e398ef659f0eacec29ad83c3894dc41718c5832c6b360962b612ad42ef7fd91e0e9fbf88a53d7673024ee97e1ca17a47b83632b7fa8c4cbfc08c25f0a5b9f493f00ae3dbeb11dd94bbd22ee50a6d904b2063339a77f0e9b75ac1d93cabe400e0b5afbcbead0446b2fe6b526acb7b0c51a8e7291756b93dea28ebf5da9901da345cffc9aec2945a199574571aaaecc6ff93a78150646bd2ac6650b356611555d84e7f75e5518712fc301ca9954c868d1586e54b9a8b70f42bcc975d616e7a336a46282d0ae1c6dca5f424802a4dbdc2d5c7bd9462ce4fb4807feb217aa0288ceb1527fd808f15e2b5b01af246e6f00c996abc215a664c7e1a7ca209e60b0f4c88f495464a0cba22e79c701b9ef5fef8bff7a0eef470cd178b8cedb0832112f844ae39931866650f36802025e43e01447f830f9c249d0cbcc3686dc4961451bee857ec5f4c5c394e87eedd4d9fb4af8b8c876a731ccf7ee3419202d461e214770f6fcfb41059356736e9119df1a7936791c6d3a90458043046f93d9244950232aad0adca5550722e03263cd4c8558562d7e6b7798c1a532f7c3c5d447ee695865fcbe3602a3f3e6340fa0d1671d2e431a73ddbcb99fcc6c00d5979f2f6e841fab51b279bb7aa5b45710460e4836a34827240d250ae7f90a7d6b8465f0125316411eea11ccb9495efc0fa48b39e1a606362b242643be67bc4203bb2e0e7209a43ec1776f89e836507d94d94665f80d545e162a12f166146f9e9508e1923096341bb3f29d54ba01924a09af5db6965550a74af6199667578fc8963bf5d707d55c78993a2f2e73925a0d15e808e1508eb6da19fd185f4fce2d2f85736e782c7fe04c0519a12b28afbe1aa080f3101fb2cac6a26ce0f2b56cc7f6923524efcd21c131f53af4440fcb7da299ae8349e881687c8b101cf1312dc9302a3d7ea711d6bceb15ef8ac3a22406052796dd29af471d3646557e20542faa295aa6761315266f8ccf886ba9130600eb231de82252d2646aeaedbb93493b41363b03648e2636bb94d03a29b37a81efe2a8349803c77d45da2e7ef0d5fc8fe6f46df9a8244280cbc70e8c4b4fc7b5475285556a5ab1c9eed6d368f1dbb191ff1d78a7890263a0c668b9f53db93636b09159f3701acc922e94321e5bdf23a63fe98ceff37a99213bddc773811991188c998e35d6a3d5254d83bf597872d8923f23acee59d5d2a5becef6854c28722bd85e34f8b486f0a9b713da41f87907daa84190e456138495a9fa9632785de8983bfbb18b94865156c69d1f5a20af13109cf437e2882687994c78c25e5ae04e1d5284a2e8d2c1c9fba511dd8989d551ad462547666df90669bcdc222e34441c875c19026b3b91fdea69e377dabdcdfeccae0c983becd20d234191d89162b2aa8c5669d9c02e9c5a8323704891eb0e180a29bb984bec177ac9bf1f46984f5cb89916990a5208e4435fd3916a650d7f5bc4eec8efbb260b54acaf690f5dc2cdb70ab7cc6de583cf47c1b5c82ed9110ca65f415d74b1a6af15cced849a9c20af1ed7652ff78d411392056807ff443c2239e0adbdf31358002a99f8ce8e84cbee5034a9b4c389db155cd1b3366623f0c2504022ef0b84e77c1d2cd07dbc98d04cafaa4842a29529c6dde9183daca6dc6d625d7aecc551eb6dc687902b5c7033ca96e020f43938395d86d350f01bf1835e19b8e43e99bfa1b43129b7c89084362305f1a56f7178219363713417ab710bacffa8b08457abef4140d61460089493fab55791546410a627205f37731e3db71cde4df48958f5eb54f11b17011dc9615582ad1f0d5cc2ec418020068b92e2c7ff3e89973326979723f620e95ca447b965d689cd6f9634c9e4ea43e9881393f2d72baadab034c9f9264aee349f40e9eb7253072e234ecc1992a3f15f14072fb08c5a001e2090c7672e6bcc2c595e115b69bd4f9d89aafb3cca0152628a223e1535c9252ec23efcf0cc5ebccf457071c43c2d1ae1610568151c7b56f86d5c42ee3da388afcd17a74bae1d70cc4da1a7bc834d9a694dc1bbd0c1a7c15c3612aff160342a4ccdd05360df72264337040919dc4f845956c8f63e105a76d2d737528f0d4930745714fb3ff144dd25741c0212f67b4e067e72d1d9302640b95196f469acce7a939313749e054a855f3442594bf53c836a5c56e3cc00833c4c94557bde351c3d2a70559886ce9ed75aa1be5710465c9df23d5b8a13c6ac57cd9c42291a98e3a57a3c7e081bfc7287a7d18f8266b781b21c6fa03fb04029e985a1be1b0eb5a09d67275a886e37a7853f421567ca923f6258ccd4ac919d24a328d063c135c3e50a4315d5715da360466ffe9a69cc109bd291ef357cf81adc620fc2899f6f6f5841eb3ca05acde8b3635eacd6609f5c89d74b0415f09a80f41869ddab68cb02a404ce0a695b6e8d1f4322afa827a74795ba617aa426c8a9527ca909cd98e28464777c4b5f2b849bb155c11d50cde855fc751d52e147e63d346cad7542f7a194086d5c4e535082bf39a7a29b13b4830ca584add2c7019f68fa7aaa75a5e251e69a727b8042679bb7cdde27b563b4665c3a8b759fba395426765f60ceb4208372c21cdbda721b66e2495f9e20cdd5a30e6b8cc2a5b52edddc88660cdd3b85bf0d38c7806cab2df1cff63091f8028c72c600a998f566ce9eb1cf8b82c7251c6b357f53627706484cf14db79965f22b694d524474f56925af61e23e6bb09e44adc55567938267ef298e5d95c36b10f4c994330f6f35ee78ea2ab3f14317bc727354b07d507bb21c2d9eb2fc034936e899a4c5d55153988db7cda3dae2175d02c3bb2d62118e4f85d95ce84ed59ea7798b9da96c2d75b4a409475bcb589bf708171e1b2bed3b39121cba760ac86cb71b7e77e7d98f9cff50bedac08cb6515039433af31a5f82cbfad4760298d3542eb7e74e36a5515d4b6d6dd394acc50824330af40290da798794f2e788e7823e00a2c8989ba20511d535ad9ed8d04ef4bf9147443e844239c6a980bbb8dfeef951d86b1de53c479bb905d1b025ac6ecd36846152192b74b0e7eb9a177702c4db9f6204b9deebeddb0934ba69ea2b8ecb1d0e164f43739150e49a82dcc1679d0c2750b773e0df524d869207de0e8c2351498eba4a40f6cc188081bed89cc60d3a6a8ff833a8f17653e6ed8b1481532e573bf969a88d4308ec70b771bf141366775f8895a39a5775bada41e08191e7193842312688eee409b8fb74b482ade170fb9dc0f5fed190cc22c25ef323d4db747a4246082c2afed4a8dc0d40d990fd9d8032f5e602fa6f770acf303304f7eed0fbf97750994ff43b1b56134357ec383b184fa7ed58829d1832bb836231c4fd8845907c2e80c9d1404144a3774addd817ccc98fa0375068f4ee40259f606b7e688c4830ae6afb676d157045701a7d89c702098567131ce7e794fc15d0b236a0883e17e18b8d341d4ea63fe7c8e590f02d902c0b54725ce03b1853caf9d43e54c5ca3be51df793185d093444043811656786577a66478676ecb05c3de50543c53313541491fbaab67f65738588af9f66e53c53e086749de1b007e51f52bc496dc77648279a2e8bae1782007407ada075552db63f3d524f367ac3477901c0277ee0e0dd0b741af8c4efafc7654f0e9be624aecfd160982afce0f11c459416ffa6b159272778fc5ac7e37eb9c6ded9112404ec7598f972659acb5e5d0e9b62f5c9058aaa458730eaa922aa0ca35d6e04a853b18b226781f9498e7aaff7eea795d07bd5dceb309bd73d6a7fd0454f6a32f4a033f1495e7c17f428ed4d7914e2aa22c722c9d05a070b04a0f25ed2e5ce59f7050a39db8e95dc1e795faed98ee17e3b9276d2036bdd44bba9aa1f33f1d21936d7aa4c8b28b9f9afa42330d9b36ebb842ccb21423c949ada1d47b2589f7c73d6d8157387551c175e0d85cd02fc4348f7c32bd1966349db6532242b029dd31062c00184cd72cc36a385bd5bcb68f66f0e4b357542614f2b4b3f225ef9078365672e5eede044fa728c6569200e3dae2d25e09d48bc1c0b20d56b9065eb680dc82a578fa571ce5621a2e54029bdd75244b271c3c42e51b3fd4b559926c04953c11e4008b54e3ed77ef35209c68eca26227bd8522d8587f2f94ac3437039146308671d6e0ddf391baec95ed9f9204d941d98a403fce4e6e2515e76ed3c6ebe3dc85e76425f03ba54ce73c110fd5e4a0c410efa594764416dde52d63f0ab71d7f76afc74301db3540f3df9124dabc8bc71cc79d4936a9555e279d763364bea078a7b967f1a1cb16f22af0381fb8490398760a891104969d555cd1c804857c3c60fe0ec511c43c9043fc9c49e73ca74c8ef37d9a43253627c86940b2061b7757b0563e1dd9cc42de30c8246f072cc512158c845173813b6c33f4cf3250efd85750ca61ea461da68762e404255011cfeb08c374c1cfdb8db8fe0f985501fb5384843ba847d65b901be4910519e612d30024a19985ee5f9a34f559a37d4b281f0f6dbfcc8d449ca18d6cf44ec5b0bc541c1a92a52354d641d5bed9ac8c5ac67a6cb6bf458ee414ca181ce7b2585a6d3da7e1199073fb17aec93c4d7e475bf1ff39a3619d1fb9876b98704991ece598f4ecb528bfdbcc61457744654d453275b98a63b7402c4f6126dd8ab41cbafe7e44a47de782827634421a6127a3ae19d560cb8339a2f321a37c2cfb23d674cd6a6d71687b5fc22f277cc97aa21f6883a9b7c4ed708d59eef432bf39cd58ca696527a47f4301be4cc6f509ddf4be63b4bcf314813d16dbaac99b067d4dec88878149868cbf133deca028053372b2f26e047436bb019da4d256fac4d897b6a065fa96bbe2f0010b2f0f813f26b8cb50e9fc3b353e40ba09d04a9600654ad8e3d81df24d0027ec6f6c6c9c8a12b7b8d1791267359c2ec066c45e7c23e11e9cb31050f60b77f4cf87047b35747dd49249405bdd614000d2636ad6bcff5e54035dfdb799fe5b2932c466bd0c6954e21dec2efb01248720454c2b4ffd65c1b3d06a42968b0f5129e8229daf28c865c6a0b47a949440682d8149c10682baa6ff09a3578a9bfcac59b2e40cf56c7b8886a3fb8880b1cc2509b6785ff0dab5e65b5e280580728589ca4bec9d9588957190b6b6a2755ad9cd8f5a08bc4bb434048947c8761c0eb6ad2c8a92efedbd154a21fe7b5b3d13b378182bcf2e86027b785810f9ab23555b4dffd928fc441410d43b78f6860ebe48d19c8f2308fed0e1cb681d693cf5f7d0e46f8d23d344172d4a1b895d70b4ef68997d45c41b063da01ec9664b1291d0045ce18e605a9504b65ca02f0848ec3446ee334e2074128655ce90744020385afbe55a46345a0392133564376499a31f82e54b43c2d678d47f4d242c61a14a75d7d25592fbd2714e3a2a32a4d8d776741a9c06aee27c50055f18fae37c0b80f7b2d892b132ce7b42cdf54ba0f5cf67573df59aed07779d073b00b1c60d44862478dd4fbf3c6df4558f17b188bcb8e805331d697cc508b3b888694944a50212a3ed82ca22a3e57337d31a86ff29b5159869d58c025d0c72cae4c4524bb3f884cf20906ce9185d04436b471562aa2ed5570274dd2b4307c1942906fadacf5e28a4b7624654d2cebde218b590981e51cc706139114511621efe40c5c409818d54a5f0e1e265ec2a647e7854871118aa74b709cd39d8a1222f5f2d919f6570baa22623e32402c0148d76f45c4e22aac2d938dae303b873512ca742cf1712e5ce26c675b923cf8baa9c204b28e61e86e57fe54e27cb6068ff5e603fa68d052af53142295c40ba861ef838e82512cac52f404686cface6a938df37465a6b905cbca9d66400ac835ce6b05f323ea5916477f8c5c934cb92f46175d17d270deb44d78dc7b65d62b617eb848dec6be47804a13d9128c5970f9e7dab57bd47726823c55de95980a006554547e8453d1947d367626bbe0c6056c506aebbf547906c9c81d6da59a904914aef1acc932d3dd4a776ad33830a2c6f14c49d1040edb4602c651220981d7f221f04012f448011411f23bf5cb595ffff7f3d7731bb50237a6888be0fda84a7bd6369ad6b8c464f44674ed326a3559012a24a16dd9afa9f40dde3ae909485475d83dec6257edf866c7757c1d661882ab31b82f35e23c1bd78d936546e258c84e1e0a82ac3dca8451cb396d61bf90d147f6617856b7c714cc01a909ece26888c371d7cf00b53db3380050e4a3d5e7c18682de757076380d0183a9084432c0e17064cab2ca77471d22ff181cbe91396836f2e568a531ae1252cd09e3dadb8696d5f72468966f4a6ab088386674c4442d476ac77c68cc8046a5d72c404b2a54750a36ed1d19e6021492f96fcab5b649741746973ab8d9751a4eb32bfe578b1b850eaa13d503b04092e29b44a080b692e15fe631737a9cb2b219e97670c51d6c590b2a20bcfb877935cd6e88974f154288f5a73d05bd894faea4edf75184dd7cab742c18b465f456f35a42fa26633543721123c05259443f3c5cbcc103609ac5e0e263af98fd09614a01ff0de53ce1b4a11831001f76f92a1d845e8b9e793dfbb1a00f6e316e88ec3fad388b0c1ae448af79af351904871bee1cdc0ebcd21e202de223b2c66a53aca7bfa06beba00dc0f9c80fbbf5d7a45967317749c5a5940a997bf8b364625618d8b25d6bd8212b7249a717a47d6d30ffb468f6493b4dbe01591f62dfb434a8cf2f22bf02711e99799a6d616b11656a4577d55838b81b38227f29c3e852bebcac03256c8ac3ef768c523b966122ad275e9202141bd7982530b283c5259a5de10e8da84d480a184cf3b126833a444f3893cc9a027760f4a72f038b72a1cad7ce140af708f365000635a780addb451d8f725c6ce69235fe6c4a18db5967b6771afaa4db0c59f2a017734b97fbe2036dfe731218de8893874e5bd3f1538b41366e123c18e91a088c5873dc1d3782dc96f35ce4ddc340ea54258f93e070d090c93529a93962fbeb7adb314e5b9a4f581d3fe47270e10108d8c6dd5cc4539a439574d9c089ba220a409035a9123cf3940a692fb050b541198ecd3affcd741a49e3d7cda3a46d6b4a5eb5c1ed7b0e47352fcba91f7aa39fa481d43a2beff2c44a0312ababd13ad4129b21f544605ffddc98c1a290eb817933626ecc899c0615b7580f3196208f510ae56836085891ef817fbdd5f5a9e9bc8099b42a486360569f24724f91f2fe961c520e5bcdcf6fdff387154f1ce3fffab37bc164ea2cdec42c268c21dbbb429309039dfb82f7342b1707560f30e7a88de2615b4051f807b04201cbbe14f889a30a023ff61239e499f55394dcfa7730754f9113688e5e0b9741af94893c4936c6b2939636bbe7332576cbd1621895cf23cff302cba3df1ea0008ee8e0e5a016c871d63179e9fc1b99db5d1facb26554b647643b1b78b55278af19c2d6c6eab6b146cf64a22e2065289f41ace39f2d2e850cf289df049ad3ad0edbe07912be1e1a1a6ed870861136faf77f21fec2a8b8d8e77b8f02a85fa55acca0055c9386ac0febd538a6130e65e2587ce8986de08d6c15b7d01023076771ad0098c4f073d42b0696c3249dd30a6fc0e494f26673edd2b48bb0e528d673db4eb7e8332b42b9951ef3d4ee116630609ccdafe1eca374e364b8cdf49796be09fb58f57c2233c695d9493bf890885a51a6703c8f42fbcaeb8bcd530e1f80afa648ac794cdadaca5371e807ce88e971e78e7ad33aa59698417c56adf5423ae6903a743e2cb40d1eb4e2f13e3ba1589f9cb34dd329420c7b8cc92d5f718dd906af2ff66256614bc2a2a1ddfe80fa263151f58706715cbf1f5ca349531324929d7523817a9e14e03b50b77929287b4c7cebf9d1c50300a00390168a836e8be2acf6894547180e29d79dd69d573d85ab7dcf99f032413da32e3e590384831b2f1a5e1eccbe5ed14b85efac32b393f8c8e329a0a7cf4ae48f88de385cd8484567ab40c5a4e77f745a0e49ad8967b929a4d5977a841a4cdade0ef1ff50f56ddd2662065ad9b74cef19f89a8aeaf0d95371cd985ce6e13e0ceb397e79db5d5e6aae37a06082350e50eca89478195a3626aef339502d882c2f3c90dffabeea891c1cec074ac447c6ac37dbbb442376f84936d81e33243cc96ddef3be0385408b1958b5a600dd8ad7988a3c6ff88e0c2bec4bf8565f08b117da551a780ab94007dcf5604c339b67b5c7956320304282cfedfd2dc2ddc6ee4363b093bbeaab30110d2c415d0b931cc9003233181cd9f10986c11d35c16cf4a371f82b150b986140ad4a9622b46e0efe5530000b09aa22b97bb36ef575794d6f69120827711e252a7bf98b67cca4f49990d4cdde8f204906e029a2db256b02811426cb872a3e5ac4fdd5055ab007f8e6104adb3a56c7ab22cabb491f589284f9a6815d88670d6b5f758db6b077e05bc0ca1c22ac972185354281fb7cee49e7cc1826af0529bb8cc60b4fb52747253425e7bb987492a7d36138d846c42ce3d19d3056bb53a5e802ed36f190ca491d92e89a1733abcdfdc14b6881a33a267993302ed8d7940fc621e02e626ad988fb54034b718ec1e03563508a0c9ce042113e30f7300b9a2b2a839d24d1ba39a9de408297b5a9a2fa31eca9bd42e99298c168f087524e1685735e859014e5376022ca762f9cdf4b70169db15cd49e6ebf0c1ce746c43e92f4d6c57b0bf838713028e3bf9a41c24fc08a82be912ea54181c04930887dd5a5057554875827faf6dbd799674beb99112cec463d048bbd8c4ccc83cfb45654cb65ed46f6d42c82c8ac9e1d23a5a4991a186da0ec94732c6d5b9283f188f7cfdca20159f7a330996e8a0fc0c26cbe6b68e511a9f52258d41c1e70b664071e277754e349659732686cbb6ab5d0f987439391bea67316ab38a9bcd2b4dc59b7212ef468b1c62b662c732bd44d2f0f3a28a7ec6d4fc4f25963a6a031168e2375795372e3b60c94a701f255c6fa235793774d44f433eb0272deebcded6ce86e7a81ede602d05d66b5db0c1e3090f58663e4c3c634e24cb7511612af974db62d9d26811038c4f92b16646300d734ec0f2001bbf0869b1482013d658192ff2cc0018b36e3366ebd686eee8966424321219e4644043f98b6a97f1b91e29cd457f4519b5cd0a139fa25681d0275a7335bd831e6605d5a2821b55774313110b3e4af09096420e65e398ef0a70f85cf5644e74441dea38fd5e9ae6c0b6e591a150526e608e3687e40858e01be674d83d327bcc5ab9374d294cf76e2ca72c3d741387403960f7272b61111b90dcf55fc5fd7ef0684f8efcfb917a69578c1bcc40e99be04457ca5ec88e63fc2cdbd1319fa8b57d45c5165cca8d46bbb94486e16f0e5773bafae96c926817c053b4d23777da210dca3e4be863244fe03680e10a97cf78eb19c9f8a307de07a99ea1ab9e16de495446689b3bd22aaa807b5f0243726e0bd3252b7a7215484e90518001145a477188c946ff2374a780560cb2df733a634bcc0b0c4866fc743618248c878a96c70736312939faf1b7f9e6a306d201c5b241b075abefa26f8aeef64a19ba730cd58aca29e9581cb82887128cc33646d626a9437eb8af36ce266b3c731035ad323a43bde9ad549b32f29a5b907c802087a904fab2cfe73052530ec60f19987a20ef554785401815f420001c6e09f5d03cc9f28f9a5d406baab975367c4ce5c2097e7db261acdf390b653f6be8c4690ba4ccf006872a00100470b12aa494e0cd8c93c06d7aee094346672586a359a544885eebb1c90c3433b1b0b5abe8b1975512922898db8ef2679a3c4e608497adc5d2bfa4bef5efae92f05221b26acd2599e0209849533a468a4493b633266a0b706c0d3db25d7083f230faff0e7c45e1927415be219c2fa55c49ac9f2412e872880a4d29bea55aa6c68c9065611ed69cf5a8986588979a46a2063d267433959d4104e8e3f8d03719111558277316bc87494bc95e3153727abbf18bd9ead41453e733df7afeaa0e5742be611a6714c397a1bb1a8544230e2c0a317c56df987ce3894b9abc54e54b4ba55d446419079a03b9c5f849a99662ee17b0e6d882025ad84364ba9834ae7bbd975f3c5bdeef5209d57b44dca2ea2c34c70b813dd622197c9fd9f968ca31d0d01303d687261657e33faf31c2ea40f172f71e2ec93f99654a49a63122abce9f773f9474549171eeb070462bc1b81667d06531b9698749bb0b4623d3ef349b66e48eee3dfd1b3203ed1e8d1509cd194712eef4567819dbe47fd076ea4d06b17fbc41a0618c67e49d4d13d171110a5ae389473d900770e052d63d6f957bf48e78f5dc0a2596c4b45f06f46e40ee96ec844cfb990a1d9b4b2cba1c20254429fb4b60957323925ea438433ad928f622113f4d472477d22e6bdbf7167bb25d3c333a2ab4fd9d55406a351e4a51a6f339ea241e273003124b67aa52f19f50c24249a65bfef72837ec09c99707cd6681d1c0c08036b08b0824c18add76dc3fd663da72a039546b536721688c3cf96e421b5b502cebd86d1b76634d5721add45ba516ceaa8d725997b53611d821afb347be8589fe9f539a702d87220ed541e339b0762446b05955cb4901bab2fef3dc29bab67eb779c12fea1b66e7d62988a367880414f34a5c96e21024097886ec4b4de83204530069533c03e434024a5311465d404c4a4e07f6a28165b90722519488252e42c70055102db0e75ced7349394fb5205d47bb9175bf6f6e542f3090fd8bc7c6ff54bed3d98989fd016c99ba549b829e3c780ff4babed1e2257eeff6c51f99f8412144f6de5b6e295392520649044a044e04e28bfff2d65432346992060924643196183cb6c0610357313561c21cadc182455e3369d2e012e07135019a83691c4bc1e32acac15b972eb01b1020d65a6badcb5a6bade560b5ead5103cba26407f5cae76b5b535c8d52e171f4c031e34e0e1b55a8247d6c52f3468a26e44ddb88df03466ccedf66e6d77cfb6dd73cef9849cd85a8ee32c0b3716a948456be58823644b50a028c9946432a4d7d29219334a3225990ce975f192162d689248e268cdcd071fb870519229c96448afdb8e921d2550b13364c8e09105934d9922ab4141d166b4d98c4976710d08206833da6cc6a4e4c5cbc5b3a6a6a85bd4ed0655bbc5c0aeb5569faeb5d6ee6eeebf192ed126daa8d83c2e88356c369bcde6828aeeb5ba4b6c71958a9ab355107864312d312d2d29cdd8c5b31b4b0d1e5bdc6437faca9225ea1675bb41cd2779299a98152bb017ecf532012a76e6ae9cc0234bcbc5b633679e6a4fb51a6d32d9b66c0157af34b2269a408a21c562301925af0ccdede909ca0665b33d4d9abc37344bb7adb576568ee3b85a6badffcd02d440bb6ddb98425632710910068f7209fae22852d14a326e5bd435366ab5b6aeb1b1842fe1e0705742e0916543cbc569a85099cda06a40d5b08940bb665646e091f534e369464d06fd19571763d6cac6d11c3bc1e30abb8360edda7256c1da0970e1c245183cba60ade9ee1e92b3599428e0ea950664c2233e62234313ab5205f682bd5e38c85c1c5323f3aeebba6e76f7deeb5dd775b7466359a381587dbb2fc4cd134310a406025bdabeef765f630a7561ab35188331256a1c8529919f7a2fc6365b2a46d7dd5035bae585ee79dd85aad136ce41fcb56496add8c18489ecaebee091d548b1195bdd5617cb6ea00e78c423d09f119c2faf9909ce39e79cd3db31385d8325b09cb139df2829367378ad4649448c928cdc98365a93b5b269540419737c464948f9eb162562a47ea76a1dc0ab1a2521d11fa41f234649b565946464095c5f7e49229265ca03a3241915652379aabb76ed55af784480c7f95a31896293e9eb3b1c5d1841a2a2ccb1582c0811191123321812059aaf204162b1a3579058fec87c72e7bdee654ae6ae55dfb6b896bf0184e0afd20020c0f3ddd6cabde5aab596737777777777f7b75cf57777afb556ae56eea5b51c576b75b7e19863f45cefbdd6bd7acd3b1910b8793cb44a5e2f992ce5ed45176db25882951ca9813e5903794a4c0d446b2049e448ad43c2b0dfa57eb8fae023f50e39afe4f94e79fed83d8ef27853e0d7d371930cd46d224d24af5dea95f921ea074a1b067c9ba74529d6bc25654f0dfb73dc2ba594524a29a594d6a64f29a5ddddb5dbbdd6a6d4296ddaf4f270829d4c1134a38db296a5b47d0bd8823cb2823a9854b07482a296e5982c9d4cb044364a6a922f7812f3d34ab8b8e7fbdf961c734c374a6ad2a4b66aa535344a62d2fd46494ce84f33619a351925cd8c92684d4d289048792853333161b24445c94445998d92985051e6fb820f7822f980a7cfae6d3ea90229482f182aa460b09b2d47208c96ba02fb545802a3c0bc1eb1cf07153a1f489e0e3c6e110c2a098c2be2613b628b548072dd2945aa2bc8e51314bbae29427af8c517c4453f68aeeea6fc90444e4477d6dceec21b4a61f3819b94277c14f9a049498285a21eb49dc7e07d0b6090334b2f772f6797702a4ba71e21d8018342b829625d931eb01d7aa470660a0b02ec593af190c2da8efa047510f45582c8f4e58c45964e3f78e8f8bc1b7b10ad5c0bbb75e7dad8dc877e643bad3d2b7cffeaed5ee7e586307dd6d010adf6647d687251df27250c2b656dc9d7a9de744a29a594d29b9ef854b5d6da9c7f9e4c7cf56b2b7f13ac2d243da3c3a1e6711d3cfd9f8486fdf933c491244702f3e5d3982f6748633e17e298e187ae3c65fffc10e8f7532ae4933b635dca3a43b03f5d5a923038c8fd9449c2a02c58bfbac7ee1e6a837f6229d0fb0f227bfabd05e69659f53d63dd4d28b592db7f4c68a01cff9bcf41043e0dd583ef0f827fa3fa1c447608f6bc10c70b85135ccdd35ff8cdd3ef85490200047baffaeff177c109879aa76f1e7cf06bddbcd712e10b45c0a12a1c21f5d43c6df360c27486609be5772ac60c1d37efdd3c8d2fccf19b9086f737ef79ff852724394115e6f87b2f8942f85ef5aaf00430fcc2cf0bbd3f2104efbfffc213c070845084e6b9096ff3cc1c88c061c7124a9c5d923da192f9a2ffc1609a47bac4848aacf9a29f6b61305ff46f900453267a0013e05404521fd47046cdf69e1279210e1488bc1fa2357bea83a319346eeee101534a972813659a5d2410e541f2f48b62abd5740947024ee48533c806353cdd4786a790c9d3ef3f4a1bf7745bc8ecfff9fe86e306799cb1e7c25100799cb19f24601dc92d03280ae00b3708fbc71fba14057f1e692c779b2636356db62005014294638632b71b14590f295043d44f63fd146949d586855fa42226cf3c85d0926707559ad871ce38216c99e3b8c76c32c7c2155ca9cf12e249ae549ac8f53d15a3bebb737904738b1d2d3414e47ecca29242ee7f2a4e3424599cb4ec4a90c0dd9d95fd8b141f6498f24295214418701a73e4a542122332227f19133b92ec597ec4b2dfeceeee6288e674a2ad9029a5d707eccb8dcb132f47268ca0290619a4b0d2a444d41d711a32c3294a5c07ab93fea75ea4ad5cbdb55ece5e4a6777cb59adad377c7267747597b3b5bbdcc4d765dfe93b6add2da56b74b930c6348bcbe5f2711db99e5cae2097cb77f8e6c4fd79457928c61e8254bc2ebf76f9920f4b21a2b8418c962b6cc6b830f461295f2ae0c3120887871330e8589242096c4035a21802e6479724669ae45f295f2e40151424616060bfbefd0544b178fa8b82a41669e54a0c5858a2332ee845d6d38b25edde7bab7bcb9d6eda596c367015534367d35a6badfd6ffaf8f87cb918b38a64c4f0699f02f8e04393341ac560f284990291eb5b19b5268396c10c62822b3afb51a3d16833da6cc624bbb8767bf244ce3420183c6213a0e48d9da94d6bad254012da6ddb8600681d10046178fcffff0fd3db870c787e7bbb109d74be98b6da23dfd7a3d45426a5b7c8746f6b6d4741b9db556bbfd42f5e17ef7377bf20375005240f6d80e714ea077601a70eebde9daab5cb8ded9ef8e4cef42a4e219aab0535f801f7cb29c4b5c407f3412e30edb73685a6d044d3542bead1e4e5b607a6d0aa09e3546dda53a8ccb561914493695351d34d59ebd1e04e5976c8a3eb045972c852c35151919acc020216a49c5f9397e33c8b447705090b3606d9bd32e4a8c6f0e2aef408e2445ed60a9b1f3d0456addc8e88285929a3c210262b5d5688a1960a02ac82bf2c9d74dc904797191d337c6574c0741c5590a5530f1c549d634031779060f73ca5f848b36d4ae9fb943db552da99767bb7bbadaf43a59455cd8cdeaf65cff4aede2c16d77afcb4feffbfffa3e082ac01cf3666ed6b07f4f4f61fb7f53decc6b4e7376d598fbe6fca4661696c2a432da57c29e5f449c4bd40f66060011652f40b2e605b382c48c88d935b014f5de4942e1d2ec527b9eeeee9fdb7c5b5707be8ae03fc2ac6027adcebaeaea14bf674004fef1ce6f7de5a11d79d20e2859b8507ce24a248e6b0648e0835997b8c450a0ba816e67afe24f7d37b2b167fff22b83b1269a72d43d49272e3234f3b4334b118c22987dc6f5f0b92cf9fea190c7124060d415fb1f5b5c1c30d51d49e18a2e44c27059b342ba83132650a51774a5570e072bf8c074818f2e2025cd12153da5dc68964c632e78bef119f431f9ce17d0e0d7342e8fefb10ee835ff7a2d7125d5d3d1ac539b27c9a668ca33db3dfade304db49dffe97f18a1592a7bf5158caf541907bfa53c2b04fc3b18429ce5a66b1037b00429769087688654f3fd7c2913dfdb6a5823aa64edf521754ecdf1177764417b761d8c6ac655aebcc9ef38197e97b99baac7c72075cb5805954a43e30e01bf4fdbbcbd9ea4d690d379023dfa09fa38504836a7a28b20214475cf9237337887fbe381fcf675d1bfa76614ca10cc817fd2bb2fcf2066a05759ce099257743c2e8c9fd2648189d5ba2c003f2870b4216902ffa47d96a31848022b8c58d32e3e3f0ef112e9843c8ed360be2090d508410a928420a2457cad8d046090b4818dcf75fe0d6d0ab57ffeb5eabd70bea38c19ee54cb9d7d9bfad9166afefadebbd6d953073065a1a903dfd9f8e13cc65eebfd6943d550615878a7c14e5f8cf1c7f99b94b1b86e9cc5cab48c6063e22b00403146a969822c31aa216818e254c48e1a1640d1427b873ce07fe3eae1cbce201df3041c218923d09904214902ffafb5b1228ebe8bc9ce1fc04764cd88d7e13fa5bf40d3c22470d604ecdf80053a12871e19336ae098985fa02978fe6a0a5069982a3565e9f951f99de64e954c5899ccad2a94a127964d5bc243ed953f449f943dfa507ae7e49c58ec00c49f0f7320932bc304697fc717ee0e54fce7044a1e52f532048245e82f0820b106d461c79926043924121d797b296842997303317624092c9210936e410b1ec2106e410b18c23d7709c5e9643c4bc3e5a52a54b1e5d57aa6c8955a9824315285a54aa23022cfc70a45bd5cdcb3dc619f405e72afb6d51fbdcf5ebee77ca173e6650ef8ed779ad0e7aee753b194cf1b618afe7e66a2ac64c4d5cabe355ddc9003ff129e51268962bbe2f057e1ea594523a8addb1fe72b6629504b294368b524aeba4945600e4933b93b657cbdd54d779a0f781f23f0f04535d65b982a44bb7e1e7d5eb1b56d7fae6b9adbf51715ea7b218571c1c57a1628563f1e98f145f74f5a7c0d50d169f8af4267f05373729f0e646d5428eee0e2f15595ccbc235534adbdd6bad584a79c5e6a1d6769c924fee4cdaf65a972d6b6d6749736baab8390f765b5901e5da7237754355b4c69a3db00359b8b250e1e05cce022ba5b415803265ad6d6580c572dba5723c9c7143d93c99869ce5a89690d7bd392a6df5dad43930d35d1eed1d77dd71f8757770e7db6b11152be0f9b725c28cae29103adbd06f2a46875e777bf9c0cbcd70393160777b4975b7971bd5e566b89c185557c46cb75cd7ddca812ac5ca81ea8159eed01fafde7ac00c65743ff07cae25029219d33fa8b9c15a3494ba7124a278d33b4fb3d39f162c8923823bd2c6b52924b2bbdd55c3bad77d62302700471014664b07627a58418d10a3e6b33d711fc1752752b43132aa85dee89a7ee5f90deba3f9add4375c0834f112a5cc902d3938a99280aa558942834636bbc000454352ec09121344e384ca1c4062c10a11262668636ba43137641c293e615e19bf2a1503ab56591525ab548faf6495d311b0acfa9b540c158b8ca75eda82b84d62a4b8190421cb2ee6ca3de215062a739c9c589cc2786004c12c31220c6e1eb5ec24b8f75e10688d113664f7bf3c3ce731a203f4ae56272c49aad5c0c60898928ce2a9090d513e7e50220d6bbabb12d95b7077cf41e3e20b1405d0f98a42e5c31d7ce99169104df402957556ab296d52135c8178f5e33c5e7e00572e4f89ec2e573f84faddad6fb96a5dc7f5cae3fbe61c6bad1dc81e19761015db76e843c5aef675469cebcf5abfa5bbcb4fe24e8e7bea8107cd6b401a9e72c84f36f420da59e3f459f84929d34cff822bf089c86bca74a64cf14207c26851bac280332848c3a4061d90f0f2820d1609262ce844d05fba284890f13e2341a2ec0e900c102f0a99219d8feb5bb02eabcac08fcaa84ce53891c6099b312e4f745cd83cc132fd1a4e4f2e642afbb274e20295659a1a2b4a9214875204c8d761b921cb8624518cbcee0bb08e6271e2224695a513975abe593a71a1e59155eb88f8bca99494524a5f520d389a1593ae6815b35496535292873e8b292008e680d49f863b3afea3051eeeece09b152b0ca65680a0f4317705a89a2de6fe48c379b4029b98812b8ec3e0aa05c88613e2e44ba284c90e243733ec9041cb0e205e0dd72c9d76c0422064f36da0db5eefa5627360ed7739e914f2beff6bd052ffb1877a608bf9825eca6a512be78b9166fff6cf9ebdc5e7755c77b9cad9da37ee5dfbc6b6dae9146af9f383e21b678edc302ce537bff306676be6569ea1ccb1e4e3a04c99f1faa8349630a8148e3a7cca686400000043160000180c0a06c40171489ce6583e751f14800c5578366e583a1eca4391400ee32008c2208601188a6100620c32c419a51852cf008b1a98bf1022a9f4a06e621a63c612ca7535b7e9fcf48955789379908d7fe9bea68985215535aa0ea5367fcbec69d021a7126e7cfd88fd07215ed23595d30870be6167ab553a9009c6631fe8c36005d1ca495fa5db8c85349b71a1cac9eb4cfdbcb08e8949faeaaa6bdbd966b18c7893d10b96618af500944b001fb8b353828907bece9286209061e7582aac318a916c9567ef75ae322a9ad2cbc090b34888adb07beb3b14e2dd339f3387986968100826fe24e7e34a1436ea2b853005b2ca74ba71274e480fa93b1dd98f44d913eff34ed40dc2db73449e92253a4cc518ef0a3c23294bd564139486d4d7568b938bd0b8a7983da637823235d24208ce29f7900e745f21de28c24f82a103604bdc6a5cf2c2c4e4ddaa6b8b3c4b2db527a5410337739f00eba8403162a8fce8420cc7fd6091d9d3348dbe9c31c2b3333b6a5b82972050c0e67b87f0393cdbab32cc5f427f121c9e8bbe36f52d3213cd64a733823ea65cac56debe25dcb443202742290e30c7e2090c4ea566949e2675adc67251c3650ad6bb9a933bc243777f1df638b4de1e12496c7a1c9a777fcf8539f5916008d4e5305a3a56b74a2334e92bab4cee7f68fc0e44a47107bf1a750e7e86f16b8c1301ab745ce52ecda10ec5281766d88ea3209212a31d5dc38fecf0556338b99d5f750c8ba8c1868ce0a562a8778ef704e35b88439521e25bb83682b9970a7bbee387dbd371a43857081918293db9e281a4f1341509a8e4b2f8ca3fb4cc8174426a9beb120eae30dda0333246d48c355c8e2635c9a86db6868dde520e7979fb29832104cf0eabffb8a8a3e58126ac5ac66ece8a4cabc408961808f57eda4185906fd2ca8aff827a59d71bb29880cd6e03d5d236a90a83debd8001a553ffe18be6bd1d9152ee184cfc603ac0a1a1ec5b0050e41310d9300068c60d4444346f254ddc22881fa1b0006302ab1578ea46bfef5ffb1630e777324bbe36818dcb0b04270f6fdd86099fc154bca7a97e4c055bc699294fea2c2dc341203035adc9981f0f4a2ea58e8e0d6efa907a6da04c33d7f6a3a9792e94f18771e6ed5ec9e3e0dbedeb524792fcb4fbe0e01025a656e1e7481c8b535e66a6c265b964abfea09ca1cb632c63853f4d32cb9d001120324f0daf9eca5fd6ca17eb272c128ad4e9ae2dbc9c38d919953532daa573a120bec7ceb9f30ba8fce5ccaa0c4aa16f3cbb6de7c94e75a0606237d51b8e2d12ebd1c86bd8cebfac8ed51b8e23310c05de1714200a576ef22b10dac69f2c8960889be7ac4fabe2d1df6aeb66ea1e8bf5c1e2cb84938297adedc1a9c3d3d159901a6cc5ad175a7d5e1a9b6c221ae5fa56530dca85b03ded16903ab733ad92d3df8466f5440ccd58255baa8ca408d4682590aa93ecc2174f4095f53581d3708b2bed61887b3dd8ae3c0808beae39d257ade0eaa0535e7813a4232f1cb5a652d94a8ea117888e6a35e8ff80793154ce0aa0cd9632d38ad123664b3705419fe5150913fe6ac996798dbe57bcd3df012442e2f58320dcd0965a3d6228b078b7bc64e5c8ae447b56ba2a2173cea65c0cb0e2c86e6d9171b99914c13d1e455c46c8e3be6815a52ceade03ffcb89d08a7efe92071ea946841908ceb3b0d15340ff6dd71caef6bcaa803fa5dc715b868d46000bb3c03a8ea97c9f95e4bd5c7251091176f100644c03fde5d72768c201b37236638f8213e164ad19552f1708b30b5757c64a6cc52e768ebed2c2732dc676437b50460248a578fae889b5bceafb4b4aa24d2218a7a128f6dd9bfdf1255f9e04cc63de24374184347a878eb7cefc8dadb6b0788d170a64caaf4583c5ddcc5f9cc257257b0d026c1bdf99573b19038bf7ddb82dec2f3fc13c3bb7a45171484f3ed497822eeef64bb3865914ffb92fad998b061e43dacbfb678879a7bc8e69d2c07d45b247f0e6f1a3e80f88a8874beaa455a2269649537f3c417c9997c989d09bc74f0a8ea0c33e51219d2b5db7c51b33f19cbdcce14e0105bcaa2c2473f4bdf7b4fe1db8f52ed165fa7b9394f99637d50ea6c6c36d019c4e9a85bc15e46b230d37ec48f1eb4857b4f5d8d097912282d0818d62bf89f8c7f66a90db424e5c3931af233969b380e2fc991c9c17779b74077c047d45dfa7949efaaf73025ea9c195c060e1e17949ffe7690d7cc553cd05dd421411746fcedcfaadf724e1231b660b462c09d187673fcece684b18f98c7a1c9bf856dda90d9a2df2e51e222d7ea860a63ac191cce04373a3bdf568434705af1137706eacb37be67110da399392245218c01c2adc210ccb465529fb69c6a1ba8505f73032023a465170012abbd0026dddd5ae4acd853a144ce733ac4643b2173ac672aec26222f1044e06bc465ae53748e9b1cd90aea091d5adb75056ace5d4e740bbee4980f43ae7558e849bede8a9e86b92d2d5593be70795173b627feaf560782c3ec3426cbb9590d8477e8b9d577314369971565eab5d7a55a6476b9cde85e5f09b58d744fb10c24d617d59100811996043ca3cc4ee60fb4af2a7aac1c481d780b22e49ae0052b8522762b6510f361542f8c41a61a9ecc593fe06080ab86a1bd572cadeb5a982cc62eca63cca89787ab263b620efb849d7df18e2d06c31b95ae8650a5ac02621b509bb71363b2aacde3f56e1f00dc9fd41ff1a2d2398afcbf8588b301d89f8950ab1286492e1e07a90b6678fb60120c45316176331799d8286f4572e34dca9510ba66805d0d489e452fda2c3cf65ed78f3c07ff356caa0b7ed3b109c36312a04aa3e47aec836ae5cf16c0440188b3c46dd55954ace54c014914d5ebb7e6d249c85afab639bc33da42d46c3704b334a31d7710f59714149a44cb46eee4955ed937a58b57e0adce710b1a5a8b7fc88a938942a377969b970b41c65a20ace51c76ca278db422725c35676ccf880ba94214352445aead9610c5489cd5e3da7403b9c539c428c7686c67d9aae444b1a3b2e74c65212b3942176495227c02cdec3861396327025e7e59799711c5601feeb80fce07cf0af0de14d8dd23da1f534dd90451976be04f298aa65f0df906cbab656957596c0e1783ace613d410e53089654614c0e211e50e811786e7268bd89036c9e2f390c36c2b712aeed7345a7ff45b63d8d47824857de7c6d43fc4fe8b99461a9cef5081de0ef3ac4eee2e1184106115393c454b52d6a4c814d2943c9a321ca84cfeb1c7f8b9a51be8fbad3b6162da6019be04030f316ac818159c8fa1fc32d1fd524380a06dd291a3cf34845d8958099ad62391b8849bd07270e8c2ec9a14c483f8fa86255d5bde47b0d9ae80704d160f22f7b6b384f49dc1ccab422171893fcbf3e4efdb63ecab98c1503d39dae764d6e5b99a773082bb727bf04f5148815a33c07f161bf53d7fea67128d12af573f2a7eb1e636a69b8e523d65d655a4132ab904598ae8b592e63420e2a2672990697d152e379f29242c442962ec55c601cadd34bda454414d56b64750d7a424e3825836164d59536d4ce787baeae67215eaf1318a2191968677c160a897ed6a72052c687c51618d0ca320a519617cad8e890ba66e027f067fac3a2c8c5a080f4e4bc6c13bb95072b271f364aa9a088baa0f665d199feba70bacfad76c77f631fd28bc15a161d10128848130e34b8c8c8c08aadf18c5b3cf1a4801091d9723c5b4bc5fa4e28288be95c0712822dee11effe511e9941d8970887bff72be0c2c55b283db64d1dc85f7adceef73bcc875fb3d77d5fc42eeea26fc4df0472010698d61cc47afb395d1078790be4c9578fda9cce0484a52b5f96c322e02f4820aa0c00f8e0bf03d1896114c55c8db77b89d885f467da4fa17c1b0472b9c2c0d0c3fbb4d616a6807a02f4f48e3a41c41818afb8e040c4462c5798d80f03e2a2f6a3367396edbb1a1514a5a0b796c8ae9d9ba8a1039ba46457865654c985a8dec79b0894412b200a70c593541efa96bffaf2ad2904f25e0fdeec2fd66b914071430e86b65f0feccd9239439a311064f758c89210bb87eaaaab9df5addcbf8810dd38228d1ca0b576fd000d810630efd0fd3b9fedc20aa14a5d33e6c7821b5c112058dbc847e4e4d6076e1332fde4a93018462a19570914ad70c35af96c0e9035e14468ac37cfa6123e1c9cdf2f3b3d861f4601c0eb34e65cd8a0e172b9114c37a01a9cb4c212042a118643e2b8d5056b79fb75a9c4fb0f46e983e25429b196965618e1ece14b4ddf9c5fe4233094807ba759a3d5d085e6b02fba89ad6cb5ac9c85344e71e33a8b99210bcb0950a88a250dc6d61db6124a555e8228a65841b1662cec3916e8f798a500037efdba1ce45eb59f917a658a6cd7d4c6b9202bde1090da3204bb5e967bd03df575b120c58f97382e5d15777c5d23fe2380f622a0d7250b03ad466020e71cdc7b26d80376518fb8b24d290db9f2e52c265fea166f7f833a70c90682e50ecf13b4c4c123b463506316e11440397ba74bbf620836411cc4835e542977a9fc0c85a83779a0e0044ce03e36460c9545737624a69cc34eab8d7614c8d945c1df55b98691a777197842c15637ff76d4605481377276e4d37276315597f9439827616ed8bc71bcccc39a624433ddfa9f8a655d8d9e28a68199033ae6bb424f37fa0aa291d651ad25915c5121bc6243262e5fdd38a176905f4d867776e7daa17a04e2800980bfcc61960927b59241a3c792b63cbd4d7aa08e53e6ad6495f728494c64e4fee13491f8b320da82f1ff29968616d629b3774b3c6e5f0192527792993bb87fdc917ec5f76813eb73ae192538965402243ec6235940d5ba950dfb82a0bcf07102e08ac0b07240c01dd01bbc0768b1011cba42a3581f69d26f9d4c5d6e80fe9200a507adbcca1894e5200a264cb711bb0229634fed36047eace429614c4c378176260df566bda152ddb3336a11e3a9c7300decb370b42478d69806ddeb3628a971e4c0f746820f9d1c256d0b905ae3d951775ea3e3cd6ad8ae80b9012962340c0b1c2b5b4ba830ca3630b2df4e9693b2046068ecad063e7688d4fe573e0d3e4ef7e0dde36bccd83b242758763aa1657017467ba2d32a12a73e6d4b6ad0633dafc17d6e09330859d1a9965b43d7f37122b0ddbfe51a92d2ffbad2a7def51bbbeb45e6618da2514e0f9f8e69e206f34bc37fce5a11e1d4916030810b42437891a8281501511ec746dff71ff7b004badc428b6578a9581002e3aa5050bc6141689166aacf53edd6f67715381511fd491f4a98a4cf75a605473b247819c9027b49df63956298d00077884d8fc77ffeda0a4cf1be080efe58107df70d73644361ba6b4c6711315b40653d37acbb4815a9e7d5674ecfb2989e294f6402017a60219cc2a9803292616fc56daef48c3cd9c3bac688653ebfdcdaeb7ddbbe748d3acdd651ee2c26ae1a654cfdc270595eaa6942e24630bf408903178b9d72ab3aa9174aa7e5dc9be158afcbf94936c539a7fd5f1c3948e68be29fe602bed2075dc2b6332ef8c0e5bce8a1ddbb64d600898ff8e8daec0d215a97da5c519a7857a207d3fe09b31c2b031403cd93802f278c8a91708105ef1a9f33690b3956be806ff105a1315a27eb2fc7770949863549b52a87c1ba434be465bf3c38caa145c602570b9f39898286c9119cb35ec02fa0e570f54335403566755ec4790f0e6c1d5a5da4608ca2b3c96f548f203799885317181acd677c7ca6bc92429151384073fd378fadc4a92e81ead316dfbfe3be36444995d9bdc0caf85c58c2bf4d27de6be1e9215068fadb413df92b4aa9b4df0eba0559b908b82a3982dd156c3f531aa4327913a2e0b2043f1474bbf5feab5c99c80a34b038fbdf8ea19118001ff1616a99a5617bb9bf6b53e68d29a33c1dd71d42a2e36594b77e64c4038e50eba4f42ca880ae426e33b75032090886322df566cc81337d354101ec574ed87d302c54fbc2048430a47e9fa9a0525b33f411ed5fd76738db4804397befe0719ea7c4242d89a5b22ea706f1a3f05628b610f65ebe55d9668e7e8f34f1df4b5541d27885b229a91bd9eb1bee1000adf6c4011e0874855474644ad78dce88eadaa479ae29e9076cd10be1484660443ccea0998e2fd7a86cedac408cf159f4f9e5ea132014ae439b15127466e657e1caf0607a32d53fe3d03b955007a8b2c9261f6115467da4f2f68f6ef8a9baaa9cc080ec725a416a8922a2ddcc7041405a85ed66be575659085e2a65e7627b51e2ed820b96976afd7cd81296c766fed6cfed70475d3bfecded99a1fb5de384402973ff6dce8938587d1a412846c71e72036f43175f4dcdcc71f2e7d3c4caef926d3655bc6b753b9639ea6c7ddae82c3d80e4c90bc48573bd3f360bd7a9578b55469b823d8ba28eb68ccb7bcc228baf1e552998699bb288511a67e3f1014795b5daed3e8590b4f5bbb04155062309fbd994b81dd02c4d1dfce6eb2b906c1908a6b651062a1b7ccbcd5215f0ff3fc029f54c010e2e740f1ef52198137b732c7c15a87dcd4add0208ccf4ccad386929777835cff0f1725fa6f62a97ae24c3ede14c1eae475c9ced3aa7d238b0e63591dfe32202c57e89cdfb621f3e392332162e7252c8523e30427c44854284e98e838f4653bee214ea7129e331254d9d5f480ed29d7a3db98880b9957d21499e7ce9b08e0857b60bce0784d5b0ed041ea524f14e74b1880e5dcace14c24a1a656ce1e04df1cbf34b1a9afbc89d159cd2e7326392e636ac77d9d05c8c118cffc842975733d97482c62639fe9489e1baf0471f2ae4dbf2d6626998fabed64fa1a9610a9e956db66bd0b1fd9566e7280ef21a16ba8a4ef19fcfcea9448de99217f99d930d7a1190576b08abdb4a7f29f478047fed015de31944685e6fdf31ddeef8f6df0703de742b10a0d867e49cc38d6823182db4f55e8b333056d0a9eb85aea57fead06cc50cc24be77e6ff8cfd3417ff8a5f7df741c33c027c9db511704cb064d68f171c83c7dc24d7d2d9e1e2067d604e24c9ced6dc16dfefc52e7c6666cb2af0c6561ed1bdb961cf07ae12beaf8731a6e578a3328e676c558aeb15cd0ad7e96f3b42d7d3c2babb824e0b7bb40f69d42e1ca74fd3fa34d1e97e1592b8de6919417662e512e2a773afd1f12031fec6fcbd93c682628f8133501eb4c4c252063c92e814cb3a552195efd09d68b8782c058066b0e80205f4185d30cf95560a0733858ff5a6b8a6dfd4643fe9458b1baa61d9b525e6610ef6fbb4fe75453f029f0a714c496703bb01e835fea1d7952883188a4ce41c847341b0b04038d5e85f99be152125210b15838b94c6bf9aca972c393ca855c4d98e3c9705f40d3acf94a86e30fee4f40875b3b787365feef4929f450a628cd33416abb2966b19eb05b66d500e8e22ae78dcd522bc65e46d75eb6cb60f5c41199c442cffe14098956c915263c14830a04c7d55c8602db19e1bc37d45fd07568ee883f731aa907588fc514a4597a6d01c78026f111c81b09e72fd1bb5acf026ed9f8f975914bef21afc93960d7ecdc92563a9c6622ecd6525460af0b11fe89994ab6d57d0b3468b8c2ba79c5a41b237bb3299721c6651abb60f38d2ef1d0484ec98650f894cc8ec4934f8cc06482795d8b80556dc788b0d4ba0c416bb8500487ce26a01dc362c7f8bdcd70ed356fc3d4269f7fcce8dade5323fad511f3aa5be5711bc4cd28930519ce71e5f40e1bb63c90b3a15973ce27c6f679ca87a39bc2b0fd4b2ad12ed81e1c7b4cd9bcb0d647db2ea0ad6ed278beb5a3d6e28c5d7fe63c6c364e4478b2be25b76e2af379246759d07e797da8a545505338a7455cb3319e046dac70a5a2c819caf38c8162cf5002bf7efada0b1773f58b7588a67511f7a59efd38ecb11640c6ac423757ae05bc323e9cce1f5ea2201497c138015b00de10b0a950042cc5b10519126ecf8e6ac546691396630bc11214d64dce3b15771415dc6208342be1930c67e7050f35960c21f7bf0c163f36dd8a14642547a5c873142c11cb7087026054b784a6bd1a36d8e6cda42890ab61535083396b0152cebf4d5d3f8dd5c139860912757822f437e50d0aab4efac460c67a4e97af5541f3c42acbba34a95e2ba2b741fe87c13b9db8a3731490c2d4d92a6383892439a361ae3f31afa842c09acd5c731dd331c4b516d12cc0ccf5e4c71914c496b6433a95bc12bdb4cf985484b956678a7a70d2241288fb268f33b811a0b90947d622700c4c58706007362e0c5916152888946c3235bb38f789f0072ef110d2585129a0f0e4131ac819b966015330fb5a7ee796defb2d0fb19dfceb0394c2b660e8895228121808c66149b6f486c5ca5ea1913d11ca817527d77d9592d329f00b82baa3b824c4ae2889f9a097aa6280c6967a6be7140b4572fdd60fb1775cb0a69235580cce1210b4ca6565708acb0259c096b32a681399ebecda4ddc53114b422b206b714482472546d6324cf7042a0c15016e222e173e45ea1402874d21f7db84626e3fdfb9a64d05c4af3e238746fdde1f19236b2117e45e40dab4216f0ccad0094198ac450b646132317c9f212b02fa8c53bfa43c48bc1c4833df6b8d5e5abbd5b7f9444261d0a2272580e64fed2dab0f3275f46565361902d49f787092de8ecbaf42b249928f303b48d87ce98df308ac2233964305406bbd4f630ad0e3c5d37df2e425344b970733b4e8457f74d7a98119846e5e46cd2ecd10287131b214d6d390d48fd87ad627e9c75b1c3086e3b3122f3b8fd36df623422c0541da1675a11f1f61a5d5ef36437a5d098aec7e0c3ed3e4a620306edd592558965c02e48a7f0c4f4c33131d5f53b6651886af437e410945198a8a7db9676ac2f10006dc23b51966512671fe8884fa624fe212ebc45e895b84fa6c63dbb592a8986481ec584783cc44ee4782a1b32f8b26b87bc973b73e7fc6d1b85891be0cb64046af3c22a625f08c270534a5510cdc26e0494828806a886d928a20a8f2065982379533690e19a147ecaf20c27b88fab0f4249c415b2a302e49a66dff1a03305968e7258efc05bddbea00f4dac8ec8b2fbfbc21039951454d4113dc0289922549f18b55460a210d5ec598212e7d2ee15104f284ff11592130a9458f2b5947aebe1734d274c9539f1d3a2ee5f20a7dc008b34f5eabf26e1de7bee08bbe3642fca133edd5c5d011037b8bd28365067c5917b5b594ee2d0303a674a96fa6c9a0bfb93fc12ab1add7546f40bb3a610a6efa5aa3cffc7c7baba810e5cb8a2dc65e4d2ab89248624b661a14633711badbe639bbdbf8ecaebd301529d74ff2d8487fe99fb58fc08900c5964be027c3ff4ca1d2d6db92dba7ccce06048a49a32b01ae8cc7426b674e5757caee455c08323d9313f1dd075756074bc541adfc06305f685b279bbe6f810bf37efa7b7a07d88ab7da17bd9eb01715878db77fd966d263416caf5a4e01b11d7b8bb96751e29d34e773ac05c2a422e4e98440dbcfef2646edf5affd31744b4e6c5320c0888a1e17ef9c904d5d78ad4531c070787869ee403cb13ba3197b2b85f122f5784597e3fccfa2ff1b3408ddac7a774906bc7c048f9f31d5bc8b6ca886aa5ed63e9de06091d3555bb7fb93200c16145f893513ea9ec6095c0f03add25cd8cceac6787a88f7500026962a8029365f9a496afb23484cdaee6b9aafc8e154bf279c79355970a54878f0ae63c9d82c683aab2c726c6f7747cffcdb4259e44069547d2e89f13976161cd8600d45f62787da8020de8a45059027a664faa4458e3e856c5f31e170e7f930374968ce2f2fdbd938ae4dcd02b85a8ee011a74f35a076bb4c03dad401202f403984c21d8fc0764e41391736c49d9380905d9c09d62abcf1c2be2dbc54f0a528c5a3a7482a47ec45fd72863d5674d733a7109ddab97ad4b985ae201bb2bd6081965fb031297d9415a36be337988beaef1f6a6ee04091a3fb2921d4a179dc9e59c58049a565f98ceeed2341802f4b8e0c785b4b411c4f3dca8dbcdf62c1688216ba53a6c601aa442fc7613bb1228489231f2047d47bb20fa2ea4f027c632958fa19d0b0e1f513f414848a1c604905fc560789db740f673fa038edb334948132ed29acf4bd9ea17fefecf62f309c992652a1a0c5c0c8adc3d9f495950a7c8a73a50918792b1406f8932b967bcabe667c893de94aa26124a6116731cb72e5013c573fafe7ebce708fcdf0412e70dd941d57f77d60706552feb334851d6ee34c1f22d70bdb542e05490cf9708607e9eda5f5959592d0c37698f123f2b01fdb4ee512b4012f6a41c1676e2ede7f2bedcc901211efe4749769bdda72f097d29d91474bd0e76c3c169bc3aa53fe22770df295345aaa07e5825e4b24aa1614df17abbb9d757a8d834d38d7610a1de7720d1a64d3c58313859cf1566c8c576fe8cb8984fdfa74c60c59283325e547a32a633c6a01fc24da4c8eda7e25102240a9b53a4aa29a9cbc5ac034e6b4ee6f96cd0d245f362a64d80e58a60e0ba6c79680c829d0087f48e188f22b79ac33c2b17061d095680f3edf744b11222a2fee17e7f5eacb62857d4f567ede95e42dbdb7f53601405f7a4fcb7c0cb7dab8757e8f143499327533cda0b90dec8d41f0d48737303dbb067f93599c5b146d4a4ccb14c5e7818c426a4684f7f42f11720b52a440c0852f5380b5011a621c83cb757e03126a165d1952371e34dcd04a72faa6500137fcab17cad3ce636494e036d3b8023dcd9de2c25fa0278bcbbeee7d4ca49a74876a98f4491fcc6c5672a55fe34d06077e2c03c33a4f290e80106ef70c1821aaea202e0a43940e0e19fc14200f9b41645fad38c214141174fb37aa197d8b7b8a0c9c6c9a72107220efa07a79ebdc8f6c22060f66103754fc492e35523302654e88088048822bccfe6c3021c7ff49281fe94ab8ed53c2295389407bb14d5c29464821b884a709875bb39eefd2727a88053659e4cd7b941e41c210485153fe162052934c026e55f8232b388ed26a84f555d38c3afd575a78b017e373805fb48a8a632c87436993aeb5017db7fa89718c5580047814244d5433acfea563edaf6253110c5a40fd6260becdde2b33f9fbb1bf8797c86500facf722b444c4638f057bf36c4ab1c9dad666f3e10f754d1ce631e483f36dba4c62ab33662e3aaac32de3bfb4f2dce0e82f7349007cb13cc3d282e92c052005c441a7a6d9c0cb614f7207631f2eaef0a83bcaf3f7c4a8ff21c0adf11fc9afda6a8a4f8a4cc6c5eb5a51f44b87d67c6a115450f1f3ef61a65418e40d9b95afa2f25ee68f0286669189c0591064bdcecdf2c991ea0033405525efd72c8299a3ca17725b3446f2d54e90552861f72d0af65d83dcce92e1bb99a3faeccfc47864bd8d537102c990be459d59d1fd0756dcb73c1e49250322a46b35a284e24083eb98a11707043a1e39d5b7b443887559c45133031d449ccecd2ab549d2642820dc692c4921fc1fca6d5cb2d29ac2e6815ea58896ce04f5f2c0f63bb6993744770d9d10404e34c8f824f8213d22373ee2ece4d92305a8fbc49699e5ca5b9640844de63e63a170839c5400f2cdac5c740303bb63c1bdc8c613f4ac5c9403edc6a06b2a3d0970603facfc118c1a4d1d0f9b26eb80367aaaa7dfe7a71cad9a70209c34775caf951af3d2ea998c5ade4e1645172a476a259c7a91dba3e9418614c7bfd7988378b75be3400d8a420836ed7379e6ad1aef2fa5fc731d0ce2e582d0c69839991944dcda1ea2785ffd14388aca603c491a4455af1bb4bde6a277d7743564597ee9560974bb2a0813669767c3169e3a842575d9c05baf2d1f02c6c139ea8e6d1c3eb43a8fa920f8aeca3834c2c515b11ce07cdba5b07dd0d3b7215caab3676368c34d98169abc8b2b9c8534cde8062343bfb09bfdde03c7b64a7ebeca4fdad7e37c2a1c2857700be41e2f4fef2d3c5ced3a34060e64402de9172c7b27688b187c4416053bcaaf1b3dd5849bb2a51a6bf4495aed2cfc7796944d3cd64b90fdd1c639c91d23cc65305b38f359443ad0b4e367186f1533d996233607f380dcacbeaf01fd637f9589482bb05bbd516ee4890c77d5ebac608ca29688f0c64159503ba8d5e2abfb420455f8136f822ab5c44ab5574f5882d167c4b98a0d80a0575cf076ad4329a472e11c445f2fee635bc7df484bcbcc3569ae911a4b7c9b691f2234f3f187296a0e48e441ae0b46eaa954de893f4a27ed5ed1af1a9f7192a418bcc2c6033e4f57e1546ca52c2dc6f21749bc6ad50827167c2d67bacd96d285ab0ed204b00700039e5316cfd6391a2fc12f524d551ce50eca9cc9a5337e0286043eca9d5bb49eb48337877be6ac6dfcd320ab25e3631f2341b94d68e475582bdcc7543bebf0a476b6efaff9bbfa44e29d133ebb8f9b58a8a12ed1d3bfcda5680082d8550f4a90ca558f6e28866a56cdafdc8fc174e46e8e238f7b61707b6494c16b3e6cc090475a5ea2667c77e35dca3bcc9f9792f0ec0c643d9fd2e2539574ed2eb1f231015538edf3ebf05d278b5751641263a8438a224cfbd394603123e8163a63a5fce852951c8d5c000c55c40848e3b42c74ea062d42c744ad8ba7710261141f4764ef79259abe8891fe7b03653098d1828874e7d380f0e93173aaf19039fdb7e391b7741bdd8e6fa24256257121086002ad2460006eae28aef92599a05614d8bad732264121285d3c7bd1456361a513018cb9d3efca0cc888532e8b517a02c86ec2e9c2c575efdad3b9966b0558f16acbf08dfa54a1229ad9746615f9a3cf43a690f63fac1430254f5f201100e3098f4d9cec0271c2809c763b0fbc006957527372f4bf90d828a72b290d242446cb118ee14a8c794730f9bf16f6103ad92e3955e44a59ffea13140f13f20b60b6484e5e0b51c24c6fa60dcbfd705b6ecd2112c647f5b08af2d7800358ff167ee6b2abe54633e9674cd416ea40d1616fb78e17ee9412dc0b51679cf17a18d3962479a4e8968e72eff3c52aea8ec3d07fff7231d2d667acd70427f82d287e5efa700c84cbd3816dad26702b2d7289faabf18d99e9fec60d1636cc110a1177ce5a70d64e9b3e0567d4d3421ff8685b01fadfb142d2fde2311f87ee2105c09e31062b0da44874861d978163dd1846ce2cabce1445f140e14018ea18bc65215022911d5b2fe8862734357263f14a74641d0f94588e68c237842a13372c83398aa41f249c14fc4649d10ba23c9b88781bef9b236a31e23ee79b7c6980d8534a5b57d770c052a65abc339379e454f9b38318d92133366f610063914185bb4da80d1003f5e11acb96c8ab322fbd083fd0fb21f83f2b514d8c630b621c37c0890ac68029eef14bab3e5392028eba0778e4a95366caabbae0485c7dc792a7238c254ee57ba86906f3b03c8e67ced666e054a9f30677e9532807b80e2a138b150e6204322a0b0f20de12ba8f2e36ee1ab9f01cb18ac934d622b98fc794978a511a8f1d120f0a775b77bc12ab3f5b1b64b2efc51029f3495a3e0c1cf01a0253558f5d04e5cb5070e2083b46528d45f7ca488488d063e290abe14f7a9502645ae26104630800302316943e6eb998f02c2135b9e0f2f2a4346fc63670a08613453b9080eae99faa577d0aaab1cc2d277ca42253933d60ca62183792ca2cad0f936db20df35584006cbd7600aa748b05be9b5f40baa394254c080346941a0247f79b6558797b0e0a872c238564ee20dbbf0c33d404f810ede6aa023a1d42ae2a9d235a49112ffdb84b944e5e4205b81ae65dcdd636b7a1cac033761014aa5bc7bba4fc7fd79fc635efcd5620cef59969581e2c92d00e40f25497583daab4dd0b0230c23ac57deca97098faaf5da9debabf8bd432513d82c9fdf27aa1b494c3d2248a860653c78b84c2d844564a5b70543147110d4264539cc5bca1162bc073a97baae893931994c7a7e11cc84193c351013f4d3a6e329d5ca893741bf4e6fe06a2dc206ddd7992081edab37cae80a082565cbe2199dde4da75efe16f0fb0d282bd3904c4a5bd0bf86acbf06823ce34c8c33ac0fd6abaf25845b21f50443635ecbbf762d58ec70a2d28eee9a195a467917ae49add0b33bcb52720e8af2ca0ceb6096c2a537b7881b5016528bb9d567a6469a14cca394d3fd4799f3a940b1d07c51c20646a80905acb62088ad45fd2609295b76b848dc6ae6f722f4298d9b4b64e31ddde1a491d40b8edad5a4eba0b0cac26769d8e8a1e8f974d9577b9674536e5fc8bc3c28544720244e205ed0b26aab3ef2d438cc87e5f5ad6a31131331cdb274dc8f69b5bf5509db95cb152dbdcde70285201ced83cf4dfe580a8f0e9e7cd04b7730d0c84cd20eb65638ed94eb939604abc125c2edb5c816cd71b18a1063ecf515d2806b54898e4dcc683288e77685ae05703f853b6e3e6a0a3b84ad8d4d17373480ba5054a728b4a8f74a21ad63545985dd28a2a09b5020a655a2ee310daa06724688689d033b4ad69f94d05bf9c08ebb6c04be492d8807c32a1fdc37cec70f7106f0386f3d746bfc7820ad0f6cdcaa15a624b31e9c022eb0b2e1729ba27fd5de823dd536cc80ef560d9893de9cee80a359b9a09fab6f5c8f13b100d90138423aba75525edd633febfe06af48be80b66e391f3e330f5cca497b0f8e3812cc3fc112a1d65a81052d939ee9826e98352207c0a3fd3e0d14bfa8e0fef0b0c5d87cce03031de3baa67916cba363d6e6361f66cdbd24d4ceb3ffb1209b9ad9ba68699c0d40a6c2d84d4f00690103edcd2c431d13f2c5bf1c8547219df347062a6d1b0644cd6c7ce915e41e66363d820d96cba3d0951594295f41478df1d218efbc796c5076253a9a6d834d987e2922191d055c2e301c5abd16896000bd1b1900f6de4cac14beaf57ee466768355310817e24b9bd1e271f0644f93629bfb3d35f2ae40ea333e2268a82a90cec87d551acf07411d63a720dfe9a15119c4bad1c98e10eaf513deb05e6626730acdd77479135cf9e38cb067b122aaddf979983498dbe4cf47a146b75f8987cfa8795c28510f26e38316d2ff410966a3544c4e0759657375ddb29702f306f20a86b9420cd51e49bbf07ca40f28634d2d3e02d30c234259c4b60cc59cdba17c205050481f3e27ac16f284edb62b934d63f0cb8c97aefb776adab2e8b9412ecea82a25633e1898c124d49ab4f995a80b9b290d495193c9561423363efe15435db3fccb8c91a50f70ef38a6888750bd66426fac201876bba565718c4968303ab3eaf8278291c8cf29a44af66e1884c13c5c401175d4d69f08354baf18b2733b1d2f4b9215eb456a6142756226078e86586c1c3b3935e4d43c3d84a1606bed12111a542605859ee6f6587993281892cc255aa5ca7c0803660cca484b57a21a995193c2ad304d365967b048a4197d616ac97fe86b796ec404653f13ac58251babaed95dc0665cd64be892dfa51b730755ab181e4c08176a91e732eab3b9b2254d2c1390ea85409997c30278ad40eacf6b40b782ba84f88997ff61c72007f067f28894a1168f7fe88232ee03f904982355121eb64cc4e4a8cca9ee410b4770f3356827130e1ad67fc449ee98e80c876973882ea3acfa6cc2be31260f69ea513e9dc97b2374c7b2de435d9ca0612f194dbd222021af600bffba46701e38026a3e4b64ad92d7c518b23d6bede01b8754ec8a40522b7e3dce7c60dd2a3953b80f4ec55c60de2ace33613ddb1db07a7ff1a422da94bb4023e2bdcfa1fc51603bb84f6e9724c1125f9267918a515455fc9c1131913cca8240127b70e70ff26ff30eeebf55b69339360d2ed18cc2d1c18c6a50bc8e82dc7c3c73440798f715a487a3f39d8e417c67dbdfe2b4d26d224263e8271dea65817b05ee9055293f3a206a0329338ccc7d5f5af7699101399619eb743ff05da9436130bb664e9b057999bc858531b4c5907c20bdc9758236d7ca7484d33e3bb7d845d39c04bf1a4456a45d4bdb9caca7a49304283c63b02bcc3f7fe094495be7386d5ca5a566035b41b271e45f8928cc841a372282604559cb32f1f13094af3d7498275e0f38dbddde2921e5c5435c03feae5ef05d8b640b080854060156e3a871da74085254d48a89d3f2900ac3005776134d0ecfeabd5e5a872fa23746858bc828ad0e1abe04d397a0159354f726ab3c2a28f227cc580697d3693e38a8a6f61d298172046b7cec74f8207ecbeeadeba9953e20f6dad35561fac5bb870b7540526b2b01fcbadb0c2ea902ce92eb7620943e0278e104e31cb672174e48fb76fb2c752bb0ee2932b0778941536fad4237bb1774d7061487ae12f651ec0f9271c9426a09d4216262b5caf02c8134e8029a062356890b36ef3c7928d752f974ef57e0fd1adef36cc4c5b92c445a329d4640d6ee9a87cc3c61bc6eecf598b9daee63678ea1a82f906d7799f1b125aed74df0fa3b1f0ae9361ba1efa9cc31eedc593404eac4c1a170917db4f6310484d5df6f24437b865d403aa7727c9ed0068e0d3f5b8e4f08089b7734308e389aef39800cdbd9d97750c963f7835fceb710bd709705d3f906e1d8f9f1a0fe04dcfd1c573633a4918195d763922145f3e250fa36ca5522b497812b26430509f2c8352b1bed26631659ca7edfdbfe73e7c0728205d97a86644cf416120da01633d21db887901081f003338a0bc8445da0b76cb0b0d670fc3742bc3386b145e7add9d5c2085546b6aef1282ac821be4e0fe458803cace13ecfc7b4a038c518a979e782f9cc95b465e499c5aa685904a155005b2387cd5c82b7b07a328b4830058f15bbe06c01ccbf333aa39629576e526cb75d3d7ee2a0518f4b2bafca05d56f5ec733c7ba63f9a4ecf45240709e6f23bcd24065aa9119446136dcb6c0161c0699522767ed98118e9e834d940e048e6cbaeee2f52e0d207138a88f5e3518061df2ffe112439dc5de96205f64f530a8596ff947fb9d5e1acdaec9ff4054804f4c57b6754792b9e8cc0d6b73b8535610aebb6e4c7acf08ff76bddc7e3a7b06100f2759f6c052a1a68155b188be3db9ae7c054e223ab054d11966ab048f3909c13b49dc5fbb1a5baad9de4721a04ac1507745e20ce6e310f0d85e9b8b7008e2f64fb6e3bed000a393162c61bb7da751c88efdb65838522ea5abb5390bb005bf447dadbec7189a56b4c96fe5b3ad3f75180af213e74e068050c72a72911d7c798a5fbb857d5f7e09f1c6192dc886f0aa962d4dcd7024c3258e07dbf606830973ab8ad170fec05d5351fe8367f42ca3b638bde1675877260f40294a4fc9bdb58af4cd0902ba24356f87578902bd99ad20bcd2898700041b535d01014d0fe6a2f7e66ff739fe0f2795620e139e9b47bc0451585c36f01c31f9d6e7df5d4a06a6421e89d164c2bffabd15c5d1e5fba35bff6d9d0f8bcf07ed489f758ee8d4d4de43db48603ee49e52db2e86ca28a640b81a2d0541dc320c0c18630114827859cf349bbf931414889d1f3a78750717a87227df637ff39c308b800ef0a3295ffd48d67cdf81b1f59a83384b1a23cb43df727161c6e61a6c1ec0335cac8dc02b4aec2054b966d94d2fb0d89f9e314e9d415c4527ac245300f2455a862131cae6a0ceab91d3a20e8357635567642b7a003411c0077b299668f4de73db66808b22237be784e0bf36922dbaad3383459b0512647741e9d84383f21005a3b427504b4ed1af21bda9f3cb04570b56e45937acc2d481840c74edb53154a8dff41eeb474ee4266c4d7fa315f5058440363883cc9f406868b0a56d0650b436978cfaf254a9cd4f018e45d1c034643be4cb3d5915e5ac5a046e4f8b7d5eef42572b1b90b81e366c9dc17d007ab47b12a47e050690d6170e1c8a9b51440d6d89e29a64a81ae4ea7402f2bbe3cac0e5d5e23ec8564043279922fd5a9a5e3105f758e3dd3b04a935c00f5e132a945bda52f62b353133d00abe75130e6104db72870a43ac5e73fe3828469d704e5130edf32729e0756545e22b51ef8a0a3197b5ec2b4d6a6b9997c492b06bdebd4f78db44e8049e47f01e8ee2e1c9a5c3b38f260ea098caca7810e9a8296ee22003b4f17a59072e2f3d392e4ade50b00a585ea084d624320bdf2925889cdcd912612000a1a428d8a38e104b7f43504e93d9dee721166c6079d01391788c7dbc1d71496078b017b659ca08f74b573c72ec78b47c7a6dda1e02e0abf97d50a50e1055e8f73b90dfe76d46eced36129bd076cae36168b7304329bf394719b0b3a066391e323cafb3748f1564efbce2d216bfea746cc518dfd632236923cf35189a29a50378b34e2ccea9d43017b6540d19f615f97958b9709f0ad38b37be28daf3842bd677f55b957737ed334a1966a99cdd1c8d948ef139efd60ad1da5f469709e6ae9de17200ae759e0f5d7b91512499653ac0c057feb4867f305abb52645190a17ee0824bbd1aa00b1b50ccb937dd646ab2d162d28aecf4037a18fe048269e313cc4e7257e753124c6ba08dabfbf6c2e3655cce0729323eeac0ad014121af5ef37c04bb7f52628fa946ef8a34e44c101a1cca2bd3a8a427daddfdda524982de12ab6577ce58cdebc8daf162d91d003843bdd6ae2b78ae0ed2a60b9753fbed9cd6a250f299927b8ece0a88155637edc01c0e141840226f26f421ec6958b5f12bc358734328383e845f52734ce155f25370e410f1b6bdee0b4d9751dfed80b35afb19e7bb6f161aa4c2c9578e8a4755ec6158c41fddf6382f9a7a608d139766115471dbc8f5658332bb40950147019aa181924baae2cbaa55070135d370fdd94d4635c70ff46d743f152fd11979431f1039b9bbd7447255520c947e51f9d3a026c8061aa209d7a6fb3ff2ae5524cc953286ea2e2652b07c19ab2b3bf25af44f06fbd88d2e44351ccfd4bb7d63827e26b68c5488b5829cf5aa212d2cf625bdba2ac1ff1ee244c9576b820e5cb12351b5357b063289066057ba0c33467059f0e9c4c6ecb04d8933733e56959a283574b05e80e1cf9a822e7950f645af04cf22bdedeffba986d85943b7a1493e57ab6a3116e056cbed9eed90aab4c0d349cc3708cb20c53b98a59c16621c8c2323516293fe6961ff6f88d29709090e3ec5aa64e3b2c64d28bc4113fa41700a87b3073e128e480ecd4edc485e19fd8388ce9fad46ebc69d9228d5904d92de8026420045ae51295593090ba4a07aea33faf4efe9abeb13749462f6d5f4cfcdce281f4ce7b9b97b7567ba0a727d1ab37be9a8d107934926b00004148412982150f65ae7e6652560f52523367e398495bdd874b68b9f12c64237b6fb2e59652a62453380927096b095167447df165631c2536e42d420d60e63135ec0e01a106fb8598a0638d8ed4076ee196c73c1ae006f00622cf175b9e7743dea2634bcd164d00acf84522902e21de232474345223907ef7521148ff8f2916024241ccb0a1ed1fd3dd9b7f424aecfc90b734e03267c1dc05f39849a9043da312a776678c71b6dc99d2a592cbddb83f77136f487479acdf1b1a3be3ece46ee64bff429047fb70ce3afdab75b59a9f7db6035bbd9005f086b35ae5231f0be0951f9735570500b2b8bb97a09af26747a43b4e2f1eb9f27b7dadfe71d67877dc6e69657d143cc7f188c186dc0d95cf091b729705c602c4d9c80263b9b5c1548f60b64719b38f57338ac9e2e2c24ed6a2c975a1a6e54d671fcee93f5719fd1dae431638a2eb374c005c612500b4cc2927097de59433c6abcd8f4544ce6fc5028723efd61d91ee48c8a60439c793f07cd960cfafc126733e95d43b81a8755b778b44d7836bc3c60ab0d9c71b5d661fcadbb503005c0eee8ecbba1be8b85be5346f75378dd3bc1c17c7dd364ef36edc9bbb759ce6d9dc4dc5695ecddd6838cdb397e6aaee66c3695ec7dded86d3bc2d75371c9ce66977cbc1699ce66577d3c1691ebdf36e2c4ef3e4dd76701c70dad601003af8f937f74a16fd3050820d22ffd338b87f10850da5bbbb74f78ff286740a8edf920b65e5460863e7ec185d403e6777c2bca10bf31e71c1afe43e33b5f08da5bdf662a085ebd95b332bffb22c625b837398082309aeecf60ed94cd4a2bddb7d0577e92f34c83d926cfc8e7ca5bb4be83b828e15367ef0c4074bd8f81f6049e2e3add58332be90b5a54296f6de65276ec822a17edfefc61bb232faf16a3764c9c7717d2e6b7e64e2f2a73c120c710e7ff546e09c10743cd0db89648ec6c93ed73bcc298d73edb91b0ea5346f47c68f452494f263e1e6ba0cd1876bd03d686265482fbdde21089999bd9bde0913a0c6f4c279e577151b3fdf7eea1dfe14acd87e6a2ccd3363de9a2f312b30d64bc7b6f82b365fb2e81536543f3138c5dcf9ec44017ee5cf18fdd5cada583fdd8904365fcef3fff257385f7dc50acecd2812a7f961438100eac6d7f54f4ea722b6da3bcc96ae7af2279b898e150f823ce282bc4114b18a44d7fce89a9f11d7e267f9c7cb224273fd696e101e983d838c518dd428682e68071bcad74bc2e49144924932e649dee449ce2546799227799227c5a81815a3366fa78806fbc4cfb7e01cfaf3653345694fbfcbf08e5ca27deef4b57ea10f1fb4d6cdbfd0dad4473f4a23266264721e56110d49eab55f721e6e727a82da346f687b24316c9f7a760d69bf7db60bd2be292cfafe729817b911a594524a29a594f6fc0c0932a242d00e96524a29a511849ba2fbe43c442efa9a47e49246eee450f49952a994428335edd3344dd3346ddbb68d861b1db26d7342ad10ab7e9dfedaff9307d513a9851b414be150a860cd6d9b7bde57f052f1031216ca4eff479dedb767df58e8b9a98f6bf0060f365eae5fb8cae837bfd0ca2f7c6742e576471b6b6c8fb3a341b60d7a14f99b933bf9934379942c92465ee448ece32fdf8b9c4708de712e0c3639cffc3cc95bf2e5dbeac38b6aad99b574b5fa3ca081eda608427f9ed4857dfcf3233847fee74d3cb258ffa8a82e6aa37e35ac8fe2d2125393d313548445d851444a8a29f113d20a2dbca064145f3d3d3f43828276b09ee42272499712a8c33ef14a2297fc666a2497fc97afd8d9517409b08f7f6194e14610e217933090fe189ab842be12c215727dd41dced52ffcbb7d46bf50e736f7d9db51d2afda98c1c69f4fc92352832a384f4cc2adfefe285186d8fd514ad6334ac7666e1b2aac7cfff9dca1305d3caab0fd3833768cd973d309c45c1d979b4ec07437e73eec1b3f9d68c33efd7dc039f4df82f42b03a6ab7e41dea2ffd33653340f33ec2c21fb6c96b0f3e5fbf7576fd11ffa43e8ebd0efa1bfc5d49dae6f0bdb4a363033b3f4e85b544fa04802898e4bd40fd506472339cedeaca29ed850420c2f2e6a86170280784a51996144157da9011ab44a1316e8b89ca586273ec4285bf6c76e59cae6e8d3bd41156c5172b376ed208a9d9e8d52c6e9d329cf497d6963de61eea6347653faf2374a3f7e4f297dca31b2a39c6d3f8e4fc40eddf94d33bfc9dd1f1634b3a764f70a4c6ef9fb4b971d91799b1b48051407339c544598d1f4740411666cc129c12685bd71394b0d308441461a635697b3dc1003259772b50a612504f4a11380cb7fe3c303ed79d29b4c880f0f7a56fe9aa64d1d0dd4b41a57427c7870c31f4ef926c391797e33fa73ce49e7a47cd38d2352baf2c9372bbf33ca4c46e91de3aae34a4aff706c8c36669e8c52ea4e6d6c4a3f9e2cd6cc5b2b9eb2837e88abb75d6b3fe774848245c4a594d1ddddbd3f79c4b6317beee1901fb6949c94d2f3cb52fe9671b77fd9369ceec6e11cfe3259cd2a9df2a86674caa3a323776f0207e7bb6637ee43c8c5613aa34b2ae78e1d3b765c9e1d3b76e0b04f36af34fd102e698614dded212ed10e514c5c0195c519585ae0f292d87286981b6040c3999bc85dd1f4e386383edcf9ca1630643c36894ec22885993c5ec112b7387b24e3e386d14c92ebdf5cbca348b9de4450b96ee58a7701a65a2f60d77fe50518d7ffbf78e2fa833a5f405dff9ea729aeff8f09aeff90201a8071fd8da8004692ebbf820cae7f0b2f80b1455198238cc2a0f1121305ec484c17484962ca888d5952822d318581a5c9490c1fae7f7ce22c624c8182a1086a8ad1184a5e634c0123c3872332a290ca604a8a35598291816aba2244b171e9b21362305dd692584129d12800a689261e7058238a138e22c91041c800ca8c5713ae36d228b86d74bbbbbb9b6cf831bcd1d14509ba50d253058e1337bcb90d46cadf0673e5369497a2ebe3f2a846d71152d22a16c522f629c08d4711c93379e42dff9fc651537040e4f1286ff9d72d2c181ec564c8277e24aa418f729e78456cf97729dac21deac9f522cef12f6ae11c2cac3423c934180406649436fe5839b9004d8c555dce02e60914304bc4a498b0b64cd783b5f9a28ab1344d1c0eb673c11936bb9269b192c560a70aea0f45a4acb0d9e52c5c2095714493700153a34a9abaa5543068b22d755d9048197148da067b55a854171b9864495a17189a50a0304a954b982713080ca68c4b930e12e8a989ead4279eb84e8f8e901e31dde25b9f4c5b2e47bc806850c4058826405f4471a9210a90104f5cbc6ece5c59c205f7c512197461442db902090ad59525b14e086b2f67598294f262692e67590265064b9adc2a788bba5a709ed4dbd803732bd35e59166fc73bfd59961d4143a9e781f6f4adf3b0a2f645fcb5afc8f6da6faf7dd65bdafb0b69efaca87df609a57efb865831c64fc8877efc5da9a79eea32918b45fb85fcdbbfb0e713da36de787eebe09c550f207e8c2cdfd654e216ad33468fc1faf0119fe213e897a9afd858f169fc84e6cba7337a3791b3345f6cb8c38600fad7388fd3dd475bf68cb3659e07b73a0f9229f591f4db788e6ff3fcdbcb2772a9fe6331c05fbe90bffc86a6643f24df3ff696eacb3ea19bf7ee895c5d4df6ac9a1a1fcdc32e8012f243cf14514a29a55fa3ca76502e9ce58c974b69166465b0f437ef16b069daa7bc90e8a67ea35ce66d97bb9477dda7f27e3c76442a179fec7335351fcb84f9355fc2fc9a27ba2a2f9457f599170eddec3b2fb4b78bdca0ea699ebbcc7a4437f3e216110847e572df79610b97fb1fe73ced372ff5e134c8dfb118d06fe385fa6d7cf5138a6ff3655e77198abe60e38fe5cfe2e7dbff03cc8a3d4fea442875f5d6bebbf7cf57c04f8f7577dc12e677f3030c33a9e0bf827f901122f45926d40a645fbf5590911e2c2c07979f0431632e673903bbd188d2cf0866a2ae7f507331c610843418df04fa1c5ca1de91cf3241fefc12a4e40e88a1321902db970fda150f3236b4575af611e14a6971ae7c16111fbd03eec0c26e70fd7df8cf2fc17f7e2ca20bc6be946fe5affc05468a7e3fd7f72fa27d7f48fab5f70fc914a17eed91f8d7e70de41cf947e495527ef77844ae94564da8c1f6cbd7711ec9d5ade4befbcd63577d8ddb40e9c20b9cb44f6c44128279b897d1882be5836c003045299d4f6917d5a9444f7dd6ea87a47e45c2b1cb5bf07fc15f05ff155891f334241d47e6de20297a8f73c71ee712638c48bae73ef5da3b60fb3a4568fbfa9c8724e5b16b8bbda59881b4c0b60a9ce37f444a8f521a7422629216e31c17430cf6e1cbb37229c675f961805db28b52461be3b0e2675f3ff545342d22d9be7eacf805a5bebab221de2f1c714e7f962cecc3136708d8607ffc9e97fa250fc718638c92892dfb0d870efadd9110ef0b0dc6ed9570dad7c8d8c4991b39276adde5f9dd3ba0e655bfd578aca0f92c14d8c52af259cddb3ccdc7f28febc792f38bd47c2c9f1f4b16a1f99aa7a1f99aafc6bd158df736ab55f6355e4ff6395dd830bed815e4adeca7c792df1057967d3cca3e22651f5fd94758f6dc0105d18ffef64ae67336091bc624377375a064e38b73b23f22a91001953b80cb54d4e0e46ecea9bcf88ab00e0576651f8f3c2297caa62633a1069b7d84c5a32cbe1ce63c363e6357e65d50121b7ff39dc7aea024356ff33fcd2efadb1b99cfb1cb25538359e6c58b4e0d667fe345256f65fdc439d9db2736f4d8f55815e6b1f1993b71b39accb5dcccc6c7dcea21ebb254562359a9140747514abcd9472bd973ef6431cacd22d2cdb2d8cd966ef629f757efb016249c64bfcdae73270d6636d9d764ff63c93aacc1ec539fbf1acc825061fd437fddec57701efbb1e4772a380f4df745e6738f84fe369f7b76651f93344f7c792bfbec6351eff867df429665bfd9dc60e5a7b28f32c27ae71b94aff26c4da18b1637662922d916062c7f0b2366f00136858c1a38b1f9828c3167a290682a23adbdb93b1aecf7175ea7bfa7ff41321be3a8fe7a7c49f9f5a57cff86fce537246bf538cff2d21217529a5c8004931f5c74872ab864b1444509052efa35f43bd65564c75a64340be552f6a9dd65fae1244175eb072a61fd0bf374cc2f8d652e8d63d0e0d2681497304fd56c0d730f91ceaf63f18bb203aa35935559b5d64f887b9a6fa87bee8754bf3d11ab3e914be5b1ea7744a87bd51114d8057a8b3e065060d7f628b04bbeea1b1a7a6fd1efe813b9b8f03b50b2318973e81f913726d1efb8a4f2885c9d47e43281066b69de841a6c18938c62fe542a3ddd2aa5094ae2c9efbc1454833455449fa68d388776ac0af3a89eb613977eecd298e43caaefebb8e4ade02da898d420fd1f2696359f6f5fc914e43c5b8aaea21395b6525f68355a6bcdbed62ea244b3ad185b8d8f4ac91e9137b4b7b1b02a5650ca95429515e86743495668a209a5d80437ddec23c23cec6a69b90c25a2d870c6184b701deff84b59737fba8b1a8c58d81b979fd7f0275fadfe75bce56f93d870f5e3bfa377fc431cf07a7b0ef3f90e6bb067f8cfddd4ee77d8c6e2efdb1e0de7c4e78ebf7e818decc3429379b5aa8d83c3e3eb2bb1d6ff3971eee4712b30fb68ba87f115f95f38dc0ab89928a61b4c6fa94936966531c60aab32d628b32863f42a1be38414aaa337d406de94bd13ab33f64e3e7166b5ab97af1b5388818dafcb379c4e148a2ed96263606e7c8260c10c442c3184d197150a6230628a1498000c1042d0c4a26e3424aac4188b95259820c3b44617333590a108337e90414c18559a7452548162b52370461872c2c684892724524ba836766a29622ed0747ec7aade7e334866a2dc6c065bffd64e38fe8e17c6d2cb59d2609f9942176be372963494c882461a691071a3ec52e892060f37ce0e052e43091ec69821c39727c6b8985b5d0a5dd298e1c6dfb2997596659c49cf22a70a5fb8fd91065b8c11033d6cb035c6d8277b3d6cb0f503bd1546331dd5496eb4dde4c6767223371846273a7d34956cf11967e35900a5f7d1337f84dee12c68bcee9c21ce9d5c121ab059e6cbb433ce389f36dff48e6644aae6014080a90d4e041861e7fc95f3b8fc9ff371789b7aa02052f42bfdc29ede66e7a4f5b51884d1bb52bfea56cc6ee00810e7e6379ddf6450e340cf39bf23dabb50efe41c7f1a7ae0ceaf1be8ab49cef1ffc09ddfd589a64c94282512f1a116bb9ecbff1d3dca16695c5d6c7cc9b2f63b3f5183207694418c7245a81b76518702bb6294cbd564637324722828b6a74999262565b4acd88e30e404bbb2655a7043904989520e3290c10d46408cf962c6134844797203146658c10513e7c5464bd209430a23c84c2be894de4a3d2118c515518a3257ca24dd9acb59ca98c06bb8b0f423d75df7b14ce8efbe84a1bb35c86d5cdfd4e7394420d96b5ed8606e26a5dc4a94c52eb2b1e2ca18b026446851c2666255e41003580e4b1451849308a2c0c890022e579c81648309102560c26509a6460abe88d0f4a487199438a185051010530329638089014b962972069cd2d4c2a96a937226b7e8e9d1000c57bc48c1c41532d8a1871765be5c21c30c6e08814b043ea83422409c1bcbaddc293618b14c94588604654a70fbab530d4ea6ebbf49fa621f11ae3f85b10f0d8d729d52a4eb1f44c96ead3467f6292772cd2feca6eb4b0d7a758a790fda9c939bd3e98b538dd3ac5f2b798bd20667f6f59bbee81145a22f0aa31ed7424861eda402cef167513a979a2727693279994fbd43664e33d75dccf5283a7b2af54e38557063d30a0b6ec8f99c73aa807dfa7a7c79cbe9c4d2a04f26facda5275ec9362f77403109e7f87b079442978d9ba5ab4ee08c62134c834e5fd4a34e38e7a3af06bd9fda89beae7f102aacc6bdb63e7a4d094a52b5eff156ff0f4d11a2bffdd094a12942dccf1f1a5a79ebcbbe21f01b7a551af6cccfbe087ded43a221496df215bbdd1de57637958eb592c7584b2e9c4dc2768c917a48b4a73f3d24a9afd9cf7780168da608695f8479c39064dfea68f6c71ad2609fd060cb1f60fa1ba9bf5f0d73d2511bc8578c3991f2d5607c6f58bf622c7e41cc57073981bd1a7c49a794104ad7b78f491af42051d8902a0551b22195d49b31aae43c5c3da44ad77b3061439d98c77ac78a0cdcf267a283e561f5c3f5cf86b8e0f50935bf23f3ba951e4bd8889f742b0dfabb674a41a208a264fdbfc1f841966c7f2958b15dd4450d761785b0b18ae714e1ce8f46ecd377ce39e50f6970a6660cc1a4efcef2ccfd13da3abebc359f7dea786bfed3fcd014eda750f7f61bb2de9adf75df104d4afb865253fb94d5361a8fe54ff3ecea3c96d37c1f12bb7584415656add90644cc3052b973ce39936ae62a4c60fe261f0b9bbaa14442f3dc771e12fbaaeeb77700cd73538468b84fe521e9563dbf07109645247bffec63fd34384760f933f7f4e5ff00637f7e84cd8f45f3a35173de0a5eea93b2b91ab2f734dac879ea0b76e4ccbf01cce9659b840d7ddcfe6dd29045c9a26452b2a4cc4ab6348d32a62c4a462553caae6458b22d938669349b4ca34943774041333b8ac16652b2284f44b9fda137a1c239fd73c29a2727691e1131af34c1727bc266d2b43295e652f74fdfd1567043cedd9d0afbc4fb328d7b644e6f46e19c862d492a6cf75f7a80c8b37df3c85bfd3d3da98f81b6b2a27eb0286e6713d6837e3f6ee84dee8479ab630d9eb16da5a93418a409ebb449d91827ac4e970ac1c2aa629c5ab8457b3461c3c9d4bd64abb576324da6d964eb2afbbc5c4aa9d1a54f85fc35eddd3ff5596fd11e303b9b34a7f6f8ec1f72734bd3fdbed9e42daa79f425141b6f503799b04a2578d0e3049655e9d7ec0718a6e9447f3ed19f4cb36904af951aa49ff22292b7e8cf08ec93c9708fcccb03b7e8ffb01ae29160c1a5505cfa610f45e21e99379c4cb0b98573688f25786c8de486442c126436b744ef07133b9ba6101c6cd3e7589d525ec40f12031b848beda20661ec23c29d4551ca8df1a706ab4383a2245e94bcac283591317e52924129895192d4d74fb2bde6f1c85b11a9fa6b71f9753618e744f9f2e215039518cc74f4262f609e942214e7c4973159859b9c9053482d37fec6044314189ca27717af2231eeed2fc905e6e43253519394e2eeee1d90bf77419993cc254cbe226c93301963f14a348a31caf657efc48f4646ee31e771a19271817322755db12c126e05e65702df0ee52bfe945658fe95e59f8c2935181f080c361e7d428eb0a17cbd9c27fb962ff9921d3bc80c6c7f902c6c7f102cac671f6794714a8ed1a373eeedd4c116495a18ad5c1a97b0d8ba3df7d4e657f016fd5a797e742798bc3489606212a54d977ec64d24972c6b3035f1ee80baaf7a5c12fb8870e9c718fba42ead4f97e4a76a58594ca2f4e39525a62d4dbd6373e9472ff4a3537c6a9ee8a29f394b24ca8599d93e8d1712d198a0faec4b507df644d7bd508643973fe5857f53af7961bc9ac6ffd344973d17fad6780bd7fe8f6fd2f33cee0ea8fb6c83f469bed83036b9f4c3265138cf23ece5440a87ecc45e56701e1dfb14a4e32dfe1104eb5861eb3db2e15fca5f102f96ff41e7999fc4b5ea083058566198b921460858505230f08e128fd58ec7f91932c2992ca4a0c20ba428964c510032c4706192a1862ea66c516dd1a355f1b1e482131c41010ba2cc0c834608ce0c0115c50c61ecb04309ebb12d6052841105c5218b2c8a86a8228608ccd4300651121929f04207a333cc8ca1a572b94a5a2c0c1334cc95ee51a2aeced01b681266382b21c433d59f50a3069b156a9051032a09c7a487a8c6531a6c6da426e59849ed046a5c7143561262fb53e3ca0dd6368f4c593586b0330a6fd1d31346086de330477050504992f91338379663213a3d21146d6a8ce0888d3d566622193b068fde520ba1775434cfffc2d01a2b38cfea999598b9fefb03310f6f5c67e39c31dc302ef9cb465caab55110799ac97b09333dc1b402a623707cd821b8dd506e770fb75b088f71abdf86d6e60b57b11794f378156ef53b51a7702db73fc639fd1f1ca1e37bb5b25687c7dc42c213ae27b945b923f27c73290b35f4db3df613f398c77e94943c7f4a29ed8ec877fded17dbbfafca8b97c65345a949ee8b0c6eda02dc4b182730dcd41719a43fb578a9c7aaf5585ccae2521697b2b8e4c1034ca85f6470ce3ba5dfe81a271b8d938dd6a79cd2bf3b96097d80fce174ab1fc72661431c1e4d6ca8739bc76d213d3ceaf58fab29ef86274e0801c9adc9dd38e44525c8ae7ca1a49d403e91b4a5a6c5188184a6f51527ac7ea5c60d349420c392162ec8f490c3144b6c700236c619435ce122068a15230410cfc286ae055a743418b686198c8852832d6268f08222a0a09283136646c0c3981d3629c69c0088a6020eec8045152ab498d28498061869f184166b301162c91524988b51834609277ce8c1cc13142f687082c312666290c4e48b2dc4346562b4e8c0abaca1445b8387cb142b5708d1c58a2c4014bdaa28a2063e14a920cc6b861181269d10dd20a58aa727315346e0b4803356f040c6992c5a804418b38c1c5a122b2530a68061e1625421439830be24c1e589eb0b13402982063cf040050c19a4c0f8d2511961c80967d650236a818373268a86cc0bbb5dce7266cc0d3959e994be62926997b39c01a3544311b7a59eb39aaaaae75a5575dbbc9f214144ae0dd409ff674850eae5833ada7391e352cf79ecaa4595c8dba3b0e6d79abd10f7d9cfcfb6afdf90f6db0fa59e7b22577ceb4f947d7da1ecebd3afdfd014fa09d5f76fa8bffe907fa6792cf944ae94c7a2df1121ed534750908f0114d8e59ffa8686b42d7c17b73dbbfc650b2f18798bc8a555155a78c1795cbe1115b2af9f84fb2aa7a2b79ca1ae64c7a31370b0f27d8a5037a5aabe21feac6565dcd01421d5ebe850f9ee158140f54852aa6fcafceeb90f75b8741f473f852adbc7ca521f2be3b822a9efbefb90709fd5b4ef27b5d10f3ad7bdda5577777773d7eeeeeeeeeeeeef8bd82e27cd6ab26aab46a3d9a454fcc4501c65c408e7c46a6ae39c93466c38ce8dd8749b5313377193916ef0074fd9f86495116f39d1d84c4747e7dbc056173016b72280798cb011f985ff71519a74eca553724fa7ec38b6ca3f23917dd8d6646ce49b9de66aabb1a1ad5d041c61641ae126231af73ad52eddd8dcf0daa364e4860d8e95cecb8ac326474c7946dce658f5581d1d230d4a233a55e72bff66a332c24d46d8a703287a7b70b575b749b9e8458f1514bf30daeeae52de4d4300e778f37af079de8e9b903bc222213220ba401603a2eb678bcc711d17bd23f5ba30bd6c09ead1f171c3d51768984e20ba42c076f739690b76de1b8e6b2eb30ee845dbdd5506dd9abbdd709135c44aae0eccef00fd1bf3a663f1bca177bb7163e3866cebc4869967c671ef34556e6aa91338875f888fa879d912d4a373434a29a594de9d3ce9cb3927c7b930eff4c28ca6b8b96ddcdc6cb417e660f1173987573ab80db81d1e5c0e380074073577be94525a779ffe1e0f9ca5eb42df8f73f8ad5c173ece839ba4065fca9dfefd3408bb2ef4e5c119531c6ee585f4b217a6724c16071ce0b8118b5ee8c09bf346c79a37ddd782b778ce399f99f98699b9795b5c0f9071742cbed1b178fe16e79c76ce3a3fff06c0f9e072b838008ebb397372e4f3fc2a203947c7621c1d8b6d8d3ffe4c8f24cb1107c70dbef12a6d3ec0e23531c628339aaae9802aad4b7d5c58ae4300e7f0f3f838e7e3a227c089e043a75add58ce0739c218db3a71843196c1cd65aa8b1b0de7eeee2ea5942e4cfe4ac3e4a35afe9c1e9ad6b8bbf37477772941bf11e1071b471863f9c68a83f3849053ce8cd62ab366c381e386d6dd9981eb34cb341a418d031ff4306f4839658c5fe49cd9545299bd4d967d8c5926e9d19cb26a32fbb694529fd25dbebbbb17011d1d11ef4a6d02c91e0e98393a20f9386aa6d2bad49c91c13b79c62ede5417af46277529abd797ca1ab945ffc6a35f73812b6b6cfadb74983922e7500f90c0c3d2cc6895f3886619ad475366f4c829a355ce8cd6239a65b41e4d99d12327396b26279db266f4089c72ca5933ea3465cde851736bbe8d372d70ddfda325e2349f00345420a7b3a65435363672ecf833b1537c8a4bec372e718e941a1c3872dcb8520ec915a783e3fc664a29ab0edec041392425cb866969e9c10f92b8c1e2b179fe50bb353597d9c663b6de0e8e03770e3aa0fa1c00802656c3ed282395b2ce1c00e0987d54dc7d08601f9fbf02c106e1c13c11291aa57869696929b67fec1109090989524a297d7f1d7483fa4522a0fac9068d96eadfaac24a47e4e82a29678e0ea8e2907fc3dd9bd58e077f74866c2aafeff67544dc4b182730c41863b3bb4aa552a9b22ccbb22ccbb28cce39e774970cca21293f5774ddb8b1d12e296d0bd6d9f56d24c8014af7d19648a841aebceebd0e48f59ee6417d811f021bc780d487fc82cb1fc43e9a9191119db12816656f71ae0a4334343434aa2e0997fa56d4a8c8c828870a43ece48423a829882138dce3643db2162cbf90e64162a71683a04204d2d91bbd519224750b18fe139a272ec5a54991544042ba911925895e6e6abc9e20747af4084044aadbe5d7188468a4695a8c4b316623000c72554e09726007241f6cc95af33a9c5d468a461148ffafc215537f9c8281f483f1e202cee99b8e8479fd8b4b3e008e9dc7e6376b3dba06e08393926b6c10ec83cb5100580d6c7c1b4a3c13a00c1b9f9f15603720249820b91a45d77b5861c3d5e51e55d8b09ae0c59661f9ab0eceaeca39ed1f01bad8f02fbff513d408c586b140832bc11037cb5261b00347c89d2104605e31d9cb9d5072b8538a3bbf5a285ceefcd50e29b8f31fdca18a3b5f870720eefc9ede61261ed2b8f37fb6dc3999a2a471271309aab853cae8c1c6c872f86ae52ada1e0bde40536b14cc081c35cb8dce0d773c3183670444c060b8fd373aa07e6bbbbb61f0c4edeebee9805cf21327ae7c1b1d90ac2e788282dbdf6f53b75021821da21081d3edafc1c27d71fb653bb972fbad7d41ac82a603eaaac572373a2cb13a4059d5eb4f4c31c64627bb84e0cc956f738822043f5cf9dcca0a1d6e6c02607a9579a596c850693fae48030721aefc6aaf1c55679fc85dd96587997080ddc0c4954fed12966e72f9bafc0d85804da6b0c187dbffa00d576ebfce0d2568d2c3ed97d676b79632b67b8250b707e0ca6734a4b5542c61abad9c6d2f1d83e6a1c66da61aba3031615a8245471d29a8bf316bbfc5e99ed2adbff59c50b74e300dd6a7f9855b55935b26396fbaf5a73745101a864a61b73ab18f08b7fe7c527da9ee0b69d1addc1752a35b9fbf708ab9f58330d9ecc3e914c574da2085185866ba7c8330616951ef24b14ff3f56993d4e7b1aa555a63b2fe4fbba0b0f5c3e9e431263da4b0f3f3a406ad379f64379d1aacdf038ae53b9d38a77e8f1dac1711c53835257d24c33e4d44151d06fbc45bdf9390ea3b0ecc53bfd188623008918808e48cb8b37dfd2623eecc5f05e126087d0497865b3d86facd450b370c7827f5f5db8a08426cd25318ca8b2f4d986a1276891614000536fe566d10a1ff33030bb5557f9a2fd2cf0aa26115a9f66bbeca2efbd9a7f922b6e6693e162d62f3f66d3e96663f167dae9af7361e58f37feb4fa8fa33aafe74aa3f9fea53afc7fbf1567d1aef8714f67b6efd9c2e6c7c111141985ebaea85084ae973549b5bb7cde9657a9973d2169a4410e28bfbc2aed3ea73dc9af3ebdc3c875b53cf3fbf60b0bef426170cd60fc3ad5704613a4520f5eb8cbaf5c3b8c4ad65dcba05e7d40fa5e43e9e9ff26a83f3839c272679abfef685b5562dc979a693b7aa53ad355c55fae29caafd788175a55a6595b2ca2a6bea63ce91cf38f5ab4075d2f1dabca6a7c116cee54ce37ccc0e48ab9f7aed53f17990b12108eab08f75ed43323465b282b447815ddacfaf4809aa3b3f9073fc5d50587685f52aa99a36e7d73bdd919c0897020406ab0336e8f51aa03ac8814bd65630296b22d6300f47f78e579a898b2ed75ed99abd8ab8daa2ed954aa55c3f239cc06d469084609eed65d8465c196b52ae24bc82b72494511735d364c28bb29a559d1e1fe22df93f294da7e7a763add4494149b44f75a06475640734d4a06c507eeaa9a99b9a8beca631aebc1a654a424f59e567f27f2cd98e05a1c28ba8141bcf1aae412f5b2e3f53165b2edbb8fc851fb83743b4d7df0e322c01a60ba8d48dd63539e9d49440000000e314002028140c0744229150282414f4c4f914800d78a0427e5a994aa42089519032081963083000180032323232449b01b655d0cca8acfe0c6d19886e316863f4ead31d4439498c04f9dac08515a228d8ac5444984e701bac254f6a8ba6a04944191df59b8e5a007da5d788583768bd07e7e7f0ded9a5a80caed74ce766de4f2df3d68ec370584eaaf09544d2bcec267b07b4971297dabb5b135db9007c9d7d0bf97e30eb81ad68dd8f0454cf4940ffffab2000ba87ecd015dada4304a92a0d9a7d754c4515c692dad6a07573ad236af51e91aa75e9277259d5c846841add69aa988f4170c9adaa7ac6810378f9793be08a6455a48875bd52177b0eb56e908491ffa0adb02868af8912e5b4d6a7485c4da194817a5a9f288d7cb540c1c530ebc88a77b7e89c6ec63354485caa7913ccd88268d8dfa6ccc96912706402c7e22a291978a510b2955b5cf7a810103709ab3c6c47d0ac9609d15fdb35878084132a6d3d6e704eb3c6c10987c2c2e2a8e4d911f29faa9122dcf504833bbdfd919671440bcdb6bff547b9e13cee86b90db84ae29a3133901c4e30dc6ea7a54de00d98d68beea6a18f798956f2ea69f043df823b10984a8a9ccbd1b53da5185b015e705fd316f11dbbaf89a5d92c5d45876ededf3d6b36f2db916151dc323b7f12b4da3e05ada94047d404321065bd14740c8cbef53c8db900f543fcb7bfb13d8c8eba551da380964c43e6be3ba903408be1bc40604dd6340e6f62ea0577ad3d4266f395584da92b0983125d19e7ca2be4359bf923b804467d0af8e392fdabfe2d32489a6e7c6626b72c1bc630b6f36789e9548ef09bcc00fa87db10477a5ec095d12b365d8286c283080099a0d72306d8e312deb80dc90e48ad755f5718a9f88196a902a20ff5643e39a4f68d39b35cebd4c4961b012047b5db198300ee5a81babd28d53f52a65e4b7285c0004b6102ce90b741f7cb8fc4749380a8e1dd40f61320ff199aae4af120dd835ad1aa74a9c747373635ab8adf5cc69540a43956b73681bb621096b02a23d59b99524f3fe9233328294fd8e811fface1e4615e813eb37ab83563069cfe2dde00529fd2073b776ec35e4d3f84532ab7453a437b58ea06e8ba846632624e9834e5b54cbb1d72d6641dac7e5dde4e8ef38fb1601012de257bc901a466fc40171630b1b4ddcdcb011854696bb079d374511e5ac195daaef218aca292bfb17e9398735c2739f2dfee54ed18cdc17d75bc3b109d096f958301784fa2752a9fc4a5d94bcf8037a036632a80e8f143026841fe943a391836c89e8c5649b77a3fcbe536c617d54f359c1ce9f24a342ac4ecda8607d8d9074f7a107bab8227127e274391893347cddc01e068b4c879420009bdc0bcf79f40effaf801a1f97a546a40ff3a82eb0a9279e030ea0bb8ee95817262c9f7540bed5dff2628ac358e425fe3ce5155f9c9d732895387c7a6c672cd6164da2d2cce0288157635bc87a097a828f245860aa805704d8e305fa880c93200e3a504a4c540af066b2e1be8779f3b254d32a62434672329e346f21a1f657e8b898eae53780b7f7a8ce100d38ab615c0f1d74f7aeb7e3d49a1e8fe4d4f132410f08688cecff890315f1a80fe040260037ae93f932ada5c7e0edc4f425d8234fc9a3510f91840a8c6a3b1fb7e0d847dd720978c2a70b1eade07e7bb50c95d2f40cd21b533494e656517a0091663ab57c46f004321828a450550de3a782e7813c7267b5614bb95157485c8676114c91f825f44ef2590491fdd8d7d3a19f7564788167d6db50fa238e919fe66c84240094c400d15c8e9541465254d6356d0f9818319212c42a8beec7c763e811e8ccbeaea56ffff1e4ef83d81b5a7a8a6fc5e3fb81801d99657e74cfdec4debfdd1f9ea0cedbcd099ba9bdadbc176d56c3f6958688296836e3256f7ff9715b8a76121d58fa23c320184e334c2307b5a8c757cf66faead3953c02cd21217a549acce1974906461ac56839bdf4a48aad89d2d5c84ebb0c1060b53499617b2ac3b3c420d150942a206b5fab9ae8c0a135326e804b0e8beb5cc97438592e0d1762db63ce69aa23520109d6b5a02e54b5b4dfd7a8dd7c2405e1c641be69dc2d0f0bba946b6d7f7f16360380941975f1998697cf3284399eaf9f4ad5ed14ecb68d8ff626338dedadca1bde3898827985322c9c1f38067f80e05f90dc629e8fbe7d00a4e6045ec18a6cfbf74536b5cefa76a997482cf148bc04b5e144e34c14a1e5ee5bc9c5589b669059272ab7e6727b01aafbca00217d3fd0d6aa8ac1754a0bf3725c616f0cf788d4cb05a736920cd453123e2f4c20af302f3f892fbfbbbafe3e7d09f2c8102e9815716c376d948e95684649fe334e26cdffc9a18986a18b786698816961e466aff96e9c7efc6d2f1a71ee69e8cb9e7d86cfe8507866804eebb194f91c3589fa151e24dac651c9486c8733e457b927438403c6a2c2f91635adab7132505a791546e19fc11f80e53e1fe6c974de0be2049d35c96f4183ece105675aee63a368576020029fef2c81b30f7dbbe1992e8a8cf7fd923080d9cecb32a6962d0a6e4bb4d039abf826843e5d716942c57f70bcd1957ec1fe833682278cfba280a7890eef30d880396409a54c869cfe4492993c547c4fe0d81f161acd56d779b0031e0be8a10dd8f92c190b44d480dbc6240a33436f227fc1d2804af1421476a104efb48d9570a0efaf0db2a590d3233a2c46b37b05936819e4694f836edb1e9dd40f85fd743da37357dbcc665823d5a9be1a46585af9e221de97bfc3858a84ac55ce73af8df6baae1c45c404b36c10df8cda53de6cca732c472496a450e090819c68890501366e5f6edebfe57ffa1ff3a7707436dfee71f38ef5376fa1ff6d790e896cfc67bc3964da1d233d6011aecf0ec55b5267937edc5f66aaca6cee23b3d64a6cd435a10268e742d0e009c5bec46890b0525fae8a3267c0f3852dd4900fc661cb06c15cbda87c7d04cb97f7d152ebfd815c885be1171cc8471caa37800bb73ec1ac20f29731ebfd2382643731b879f97fc1526cee14ad0e9849085a0ba43ab293aea12a7485bc48bcc99c1b45bee0c179741b237b8d168d9495ea85356ea61d8e2daf14b567838370e3cada4317a849ac9a05d870568de23290f88d28078778e4252efe7737691c9281f12d044c9c0a97f886a7805a3d7dc618a7eec034623fb2cfb4850f0420acab38f1ff6d6ad4e0222f6faf16b36136127cb3514fb34f2ac28b21e90908f956ab158a768c7eaf33b83d1b47e402e22acdd1e784b187105e218738754ed941e943aa7f5bf2a96c9b6c1600f7331478a0944a36a82cf7df13408dc525c835986b33b70efe298cabc023f6a6d5c6262aa7cf591408cfd914839cd25c6bbeb9d7d3f9af5f20d0926af6beaa567a1af7fe831346907c7118e3416c5fa3d129823b6885812f095e495c37ea68d5500f07d808ad6c9f482c34002e8add497030787fac989b14055b498ded17233b5e360245c1018ea9459831234425099517415c8f2235f81ed0a398c77a3d2cebc0d899385e26f1b80a85399368dca0bd843c97caa7195411eaf1c660716c9438cc498a8a0fd12325dfe3328b5d49ead7b604348b92c4b6342439e1bf63990667bb84c3162f6f2eb14011349256f7abd4b45185268d9f9d4eb8dbbe4cb7e77d3a02cb29dd6ab7471c11a40b45281ff9806b0b22382f86eaf14bcc03359e04ccd7691f5d1498a054535532c503279831819e50f3f84a8b77ba9c89a88c0d1c41b8efbc455e8e001b4b8f85c6e7eed12f13ffbd2b5ac95256082c9c515427873ec7ba6fc493fc1c4d8da872ea3d7c4e4d04d96cdab164f0b34f9210ab945d465a115d52ba1faed41b91a42e15fac9ac19fe2d9d036d4339650be2019c693d69556d3aaa88557b4ddf1c87d15ba3178ab277dee6f23f588498e63a590a1d2bcd783a49d68b842a96d808f6e1e5957e9d2fd54808cf6032bf634e17bf71d754117ee7d0e01f2281ff92dedd7c737293848e39a497cd7be5a36d01f3735d5ee7b87b4ceee6a29c9fabd6f3077a6b3fb5298a6ace2502abd7d83cb801d7a306159d488f000706ca6c6fbbb111107084ae18cf5d170cc9e42678cfc8107e9169b2d3744f441bad18a5ae07848f02c9d18c696495b5a28c82fd5b7cb63a4aab58ad46a8320a77e23b123b6dfac5385f7a154d12b5733c84ea3bfe616066f6062b40a8f0a5ff588a88924419e755d8f9e7fac9c0410fc28926869644882ac6246e0f5f8ccd8b24a9881f3b7dbce5c24b0258b8907a3d2d6b630e569317f29b6d1d97689257caba310a9e058bf71436689aa47441a0bf52d44ee3fd1f06fedcf01c9f53819f51189db52a5a5bf9bf45bbfbdb332b1c84e05713d171bd77e39e4bc74601570d6379a48943c59ad65066354cc581282c18100e435738e6056fa201290225e2f9e0a79c66c37098464435cc46d5dee378a59819e96f7ccd32759a0afbe934c7b069697eb62fca74110680926254f2c91d0a20c2df90bc90061a2c11f574df8f62311eb3d1f050becc8b6542c4f943371c24db3b87c3ffda7dc9e3b6bbfec1de3ca6964cc88f19ef96c504816c00cf096448ca005dcde0785f19402937c875c23e989a2e92a793f5a6934778469a046c4e0ed3c3d6331115cde51c27dbe99141fbedd194275e2471a369c41b84624717ff5c8a1ba3213d4660cc1c141f6b79043341b332c4921a7b2d6f3399e9898c85c81a90b22bd81fa32bc6b3a458e28784f8551095350689f5e9fe10ffb11af4220fa7fbdcbbe17c20f2f06241f433730f3bb922af9c7dd472d8b62810fcf38494482af3041e9c5e70bc1ada36d87e3501c99925c8ec22b6893705a386bdcfab272f3639f070a7ef3d8bbb8feeeb2cd2d0cde18e03a04e49cf64994970146f48834ccbde90c71d7ac88fac54938fe0e8fecde764f344ec68fda4c822104f0f4f9f60984a5fb80d03b1a2cb592ec8af386d6b86594273c4e75bf43e7400be68c9385b4be35a426fb3766df371edb4d9e2f6b323dfee7a525746e8ce37849438cbae69da2b4007ba369d2735a7a4cb33c165fe912ac3381ccdd2d795716184f90e78f38c1ea1a595cd5b7cab1f052109d150db1885f8a5d702c7e80bf4eb7f52263d023a6aaf82bafa05f17025b4754e55dcc01c4f2601610b61e4114325e9242136035c604255c96bf185f46781420d1c1b543f2020898d9201cca492af4069b5719240ee0561d40592d0aff7f0a0f5474bd7f4160115ac18b6c7cbf6087efd182a6113fd4b0caf488b3b6b00fffd29aa012f8a16b09a8eb66df19d845ba350173c21c51972ee44250bfc61351226c4da44d70ad61defdedf749954e8d82a33f2450e479aa3619acd188727bcacc7bb8f2ce74b29a181e52dc9533133211bbf08d478c899a7de7d77883445c72c44442227a134e3a9d14dd8238e9d797c0dcdbe7179c30a9e26a4c69bdd0b82828ae2cb20279da3e7d0a9ef4803d7965b89ac7bf69d2c9af16c36e29b0c3c655aef3bf06284fe86105fa804eb6a44b196032f36218e610e451d0f024899f6c23859d928954d7c7bc06f457f7500a7855076d263db1a11cb5d178a331f6a8ecf995df70fce3b9b3b5ce1384a3fd417072722434264795b5e4e4c6675dda1eb591d5fdf854ef52e080b6596b200b4bd6f8dffb9bb8eb5fa14a7bd4e46ed688e43b6c88808847d0c834f870072dbd18af6922f83477bb1706ebfdbb349d1510e0a2f92e1a38b5007ee844e8847b5d376b98706b8f1a870d672bb387641df12d61b24a403b58f6ef2180a21a57342b2b38d9d08c70ab326ebf26ecb1e43badd7898ddfde6a105250e77d9edd143a2f1bb91d4c28b1cd5274c58cd849da4b65c5b2335dada0bca21fc92339d0590d23710b63d8d851e5e1eb714bd0275e1f2cc3172a3c7e24c0f219a4a923d5f06faeb4a4fa4a3cccce6c019bc361dd15dcdaaff7b2bcda2a8c7e6530895335546737e718259f0a18597c1c3ba76e574f15ac504d1759c90155227e2088bdcdf1c4a1c6a230cc43b1857a1c19e246101c0c1ba123f6f6b0c6be7ce06c57d58dde676fde506b94177803252b749bfe044390942afc1a5b5529a4f8089363a2363d2f77e588fdabbaf721233fdb468cc6997984d54e8796eb4d4d8b18baa703c4c43e236b426bffba35ea4cdce4e2d7bde3e077b49cefb64b5b74fd2ad50d321e1dc44c4996bac7aa8870887374fcc16707b5e963d5eb0816ea15f1f496c25f7426289973b0bbb56e105bf0079e1a59bf80b0b229815568c1e20085f6f9bffe370d6fbef35160a23206aaa1d77b7c4669245a58499596f24ca2e1cfa3377946672f4911eaafc48a1d66815eb7f2fbde82cfb6e08270df0f061a8b8f562b91578d46042c08bcfd2cb6529f39aba8a74391c81086fb0c0fe122a80ee0d301821023d458d0ffd704fa153e8f7b3a5c81b8f329b62834e0c55e6f5473d8cb10e3e9b06c5d23d892d93a1a3594b5e552993fcaceb5bce41272ede1cbfd52d55dcfc8a57f7bfcf8d076279791ca59b27168cf1354fe7a858246f4f73d1036e59ce7fba114a61076e4a2f7cc6dd54fa928017cb8ed5d324e4aca1b1c60faf971184f1c89f9bad76f1aa3b5aaa0a24187dae22426f69b0c60ff654f9d4d9fb87a5f392eb0aa2f6607a525142e3bc4ec8a019c1eb5116ce84f2ded0d18c522f31c1f034ae96efea7ba745e78d92c39e2a78cb7b789c363ec6e7826f70ab580432ec942cbf01d0d4e81640115d770ee3272882e7eda9d0bdfedd37b0532fd098389cc8b1e50f8f4d845fe4a4672224804a2eb76b2d0d1472a5c64750aa4611bc7e0655d2f5d1324c5293c96c1ef42d666adcb4c5af68a77a0181cff8b33bb3c33ac17baf8d20cb501cd86a765e15b4e209db700bdfcff53f3b9bca7c7027aff72045baa153616897f9130e85ea6836fcd22920990203a46e92b527d1429d1f19dda8d51552419ce6651a4484bf877d10d3722a5d0d15d1d8dbfca6bd41cc2932b8c4f6f8db8905e424b137dbe2541e2596f25d4e1ebd0818f441c9108711afa429d42bc386a201ef11bb1f1ace7c375f8828b544e3a293b3e6cd412457aaf40cf967f0a040efba214e63697bbc909e9d51a900063852778177680440825ba168385739e1865f360135aa9bba2370fd0e830d96b81b1b4d4af08ecf71743612ae663cbf2f6f9c9e63c2aa0729cbfe5128f47d3ea826871248ac449c03ff4867b1c1bcc57a0c38960cafe2b1d5062ea6f0b357eea7c405bca321d1ced3e502a55195e71ee6f8c5e67bb1042495cf16b95edda60413eaa7be59ffba7e2fd392596a9bf4a0ff40549ac718ad1b6d4529c092b027552ebfb481d0f45ecc6eb7f3bb8474a8b7b1bf767aebdc0375d300d20462de5eae564e4d0349715241987fef4129b9f64d9a51b0938e42052ef4f39934eeb6da4e3a1bbbefd04881249ae45440b93ee38ccf71aaa38e0e0f81524073c295f9bd38b4869fc501941e3e3716c64e18436c17035cbe52102f79fe693dff4c96dc2409968d9381fb3f8beb2fabfc31625c867ea0634f23a1ef4dba23815c701941122cb4590e1c734b0bbf31dd25a08694c3bc58667d19eb05479c7d08d58d0da2361842c652e3f978234c67704e91e6631ee36c682f4edccb033b6b19b398e9c9f3df35de859d387841ad2f4e4558a0e36cbb59b4544317c94b037491912b03641cc7bc1b8a6ecb3a1fe214a8f7e9052f2b6299d27232a0d6a0cc9fe67c74716c2a183e0865ffc2cdf14f75952e4f8f75b6c0470abf560c333843447c409f5bbf994d59a807e05c40cb6e00520bf5555d49cba94c2434b5bca69c1e80312c2db6a19c4fa163cbb5f1bf3715daef86b9c85af0cd27817b5f08e45fc08c63506a071d44c02949e3ea1caad2975da85c5a1bcfdc280708f69024e1341057ad6997066055f333632dfd1596c67da72d915eac025a6937d65c3fa70803f3a3ec22469a6dc4e11ad5cb77084e3e6a6697e56a71f57916de5f77475a5061bb0d8a995e09836006902155366fdfb980ec9cf07b95f07886dee88dbbf841e300f11dbcaf822061161858fd9b27da1ef4f36dc68c688ebd513916ae715243dd979ce348f2afd4dd54bdb6291a5da1bd73f951c8b7c485447215f122b7aaf886aa7f5018d0a58312809fe1fe59cafcd010acdd05f35f9394978327dfee1c6b3d49d201cd0074184692e8586e34898b8f8b7b89926052dd78d6eb7d91dcc6595359bc26c8237cdf5d65d9b1c2a1b2fbc8d2ad4aa43ea63455595a7c5a0fb6352de98ab8d1699d26b54d169b1d5a0c04daf1f91fbfb813df0bf57416f0d394330da4ef53c26512ed34ce5dc87858685827e53ca4461746b29edc27e303f1835f1e4c8079c27e2846000120ffe870e049eeaa774093114c0b50bffa664051c22140fbc68eef01e269145feaf811acc64d67ac9a8266b5d59eb93c5017aca4b18b755bf58adbe121d3f7eb019bfe08ea42a482794a4138aa24229630765d27ee3a42682b75c5890a263130af8efd2dc1b22fd781c0e980a64468fdb224d7f7c1bbfd033e23d3f435e9840a93cf5da67ded0051071aace9ea550fee05cf514c36410615440eb2e05d39350dabd3eba6424ef7a2ac4dc5968138679bf702122d5c0ae014a9a738fa4a9c98d8970a932232992a7f13e5ef3689d0a396e9860d72db509e148f8dec4f7927c6f3ddf1891046b1221da0ed1dcf4242ce710c51b4699262b82b96c968e89843bb9876734885b2393124e6a465abb644a47fd26d1482393818a91f111e1192f2f6401165fe5a3fe0ddb956dec9b066ec92e9a434dd86ba1b9c535d80d494e45373b868f8ec7890293a4a5336d6e6064d3419b730dd8f63c61e6b265627bdbd945622f6d78a8c277eb81fbe5544c0f90120bfacf8cd45b29f94e1b381926627024d2c63434b310f1f83a52b29ff48640e74f317981934e267ee8e165f43449cf4e1829aed328696e902953cf1c520cd0ca5b26c5799bcb58c50fc8c8c5e36759e7f4acf1057c3adb6ed474924ae226bc38c2aa147c9c4e67eee48c8f7d49fbeccadd638d881a912d779c6caef81d56ad0a35b5687f124cc8057f33a83b62617b5102f5d776396bbb80a02eaa5d7d706005c7ea73ca22c8be995803c9e87b4347a60c4df9c6d0418201c7b7846e0e6c86f8c5f22cd82221ab9b24794ae52ca62d88a4ba883661e9609490830dd83066c1fbfbf8fe887fb55ba53b316b4b7789ad5661193dc1d005bb9691c66a0aae68e123f4d16c91e2fb7f4eb32f38519ffbaeecf3a54f61f73f3ed19cb93d2b5a774ed38824f800f9005b09b7ea9ce4e8a3650136b63351ff3fa6214d668864643100507f8639d43a276eba76fc3c263a17ea2a73bd693ffe01adab0af7b295f487d3ec4db42be15eb4074b8b295e4f6712b009f057532a607dbe92ba637cb8d00f4bc2288189d599654e767f4e7b49398c71c39c095253e0f0f30cc5feee1f11ea51335233217c22fefc6516ab0d30b66722f98d5f8370c1682ba21579679ddc4212b45d55f483717d61aad00d7870068bafb079c58cbc3106997a3a744c18cfb048830f1f46e9bb50e808deecd42b282dc280a1176118b98ccd19b5ce2ecd246b99f49c5654225968cc38777ad3631e33c2f8d0316e545b9628379a2f355628af8b3270d079199ee8f81598847528392c67ade334197c7f69ff42a845f345b050db4db0f4162d9e50e70f64f18ce30d0560514f00d72df9705d350112e71434a7ad063b6ee6b2506e375a609ec7fc590c2d8ca46c2186e78662ae0f11d5afbc4115ddcb46b64cd580777ba0b2f7633c8c19d98f379563b78829e44a32ccb46c0d751831550ee77406c48d789f6a77aaa542265eefb85acd5c7f8fe738563e7eeaef948c921731c0d079f3624786a91b4a9b2a1e31fe3c386132c27e63c6ca54acd39b60ac94671b226ed1d82023a28fdffbd41455b7466bc3effe7b452fd8871e89d6c231a7a591ea3cefe6a248613901035f35412f9c964b02af9dce2a6eefe8d28165b73aa5e29950c08e1c0ac98add84180fe0443b43750360148c0ed0aa880b5c42cbe69877c761f0d4cb2d5a52aafffafaf05892ed4ea810e2db10f907ebf8e8ad15b3fe1fa42ae59d46dd21b19cc6cb485b07ddeee9a1279d6e8666c2c1745817be153d3d4bcd9240853147b1772cc209bafbc0d1b01eec088ef7fd404557f570a3a70aada3454ff928281205a520a192676dbb1a7abc88ac4a0b47748409525420c4d753a3d86fe1ad07edec3e489896ed8e1cb8671d28c54389390b1e831840d2c64235c4e4fe155ceb3d53644344e25d45c0074bc62a241d1f9c690f2bd4955d0b3e37ca8271390c5a3c4d123a0cd298e87228868b39dd462ea2bf446403a76b344911c4bc43b1848fed0b2b15f55053da5b0cd10d2a987655f8df91210fe028c2e20c2146d84a0c14ea7f76c6a1f09e74e32be4406a5961f3f40f999d7ded8a488db65d3c1ae54579ff4ad26a45798d503f0f60d34bb2a18e89cbb11fdbd02d501001128cedd047cd877472847a248e6c3e394ec72e1cbf986a1845646b0841f035e0bcc7bf65c09a821ab877d604db52edd4efe7881b52036e0923cf1dbb0df06626cf08ff3fe9e534a2051dcb5e8cbc60bd3131cfe70b041cf2220b2ca61ed168dd0069db2883157b64ede63bbb6d1805f979e70fd8368a02a4e5628ecd4bca805a2cac3f735d1db9744000439096348107bb5349c1ffec9cc5030168a4378189374b776dd5dee3223d0abbc6b47cff168c135f229416f21391cb898934f3d08995f8ee7facb3e990b0b661ec211bc6a09ff7e9f36650722f41375fdc9eb08d1827d5088bf94e326160ca554a5f4670faf1095bdf6be4bcac79aa02dc954f0728acc85b33ed5e2180ab236da15ac9c52b3844e5a2347bc1e96e514975b7883bb76262641e2424e633df1ed810a70ce22822765ebfc75292daca3556273d1523e01073178e276f6b74e7e83c378257a114d274f766ed5231c7d522de70bd81da5ec3ab6ffa20d6615e0fe2314088d8631642d65b8dc641148f0192a86d613450847c7556d02b8a46d6be842c297063fb637d24736cbda9234457d72508d403dc46752f5efea475293ad0d5588de26c8d81d7f56c572b8027f1dbe0d41d21d594375601d861ec7940410f45122b2de8310b3ddae39eef24cebb6f0bc7ea3bb208441f36f76e0a038ca0599b41d4d195fa46d6e5a63e3d7ec0c9cd4c678b56e3569ba734ed1d1b63a5eeb214ed25a1c56a948ed06ab88ff4c464ea9fd16a298f61b5fdb19c8688b3a6d3a525b1c7335a4de56bba6ae1c833c36b33bf5c0175092015b58843f1a58ee9c05645d3c061631859b819970288c4dd983e46796896949d5b5324aa6c4cba7bd19eea5780d1d9aa442a52e8e95427d51044fab95239c6ffc618c00db714981a159cc850d7b95559a79f5c597d5cb0ad9b7a6e585626d0ee02f8166c821b4c2c4db62dc62c49fce39fca4b7cc271d9baa814898d41c245a46d7015ee09185616830efba3d2ef9c96a6e19ab46a7c52f6b0b2ce413f890fcdb178d0bd58d860dca1269ab9e1a06e5f65261efb4b64406fb291e6d5bafa61f7ba8761ed3db7e79ab49b284a30bde963d9277dede543eea2052294baae8e8c96e8ec6a3d7c1084039610dde7771198d8139279bb153d88ffc0c9a7bef1155ab1b853f9f1e46c3173f53819e6b1eb4164d8320908bccf99a126486154019f6823106b8b9617eb484091ac1a7591aaa35fed25dda7f5d5b1b41c21c957636d558a4dc0e1b578071b50c85f098914b969a564d3864c8c59e6794405cbc3026d1f62d1052f0d6c618beb73afac49732a06aa54e2540e85b36a34ed317ebb1d41df5ebf15e6d941443a12927c3930249295b4ccc3b36614cdca1e5cc45061be6ee2df90b11d5058832f87359f2d312669f9d9ae1f2849bfc39c34b5b1fcbba84314743b7ea4a750aa28d92f2fd6fce85390c17cf175f93dea7f96575acccd568b5586567a675200f13ffe8da573f3e53c7aa1071582864f0228660b75aa7eca0069f2fdba79c2ced70ef31154192caf98f21a4e0b48bb4cf6d8d29c36ac69eb6fbe70f4bdd516af248ba538fdfe4d2bb8ed07455f48e642d3eadc9e3954d6e9fa7460aeebea38547630542d011b4da93808b3819ce1ac0476ba995a70a1c7b0c3549d52dd0aa86d2b91f20e0b321422a97c3a9ddd8323238d2393795c6b54d50e55402936f9ca497e0ad23f94cda7fe39dcfd8b150b20b1d7877975e66a274177b9752e233f3282a8d4638bf57c37cadd45b771c02aedc926bf4799decda4e7b0f2d6f22b4016fbb0c5d760bfbe0ec9ce27c1bc9587000f571ffd7b8256b14c3ed0f87d5d22e6d94b69720b9b8d326003029ba94af8ff9ee77c01bfb88d2be21349b8e4ddf114f39302a61358bca27df39b81db1e737ddb1694304f6664b9f4813916f4092d9ce7e5c2322dda06540139c4599a19d92af5104244f9cb3dd043e0f93de125d506bc0ca212b2f896586cf8a89dcd4e8d14e20c2c81c3ce0a1dc09cdb324380f16028b0350513c8cf2e1f7bfacf6786376730c5d9b1c5f942c5508e177f5c3ce353f54d62a0063b285cff5d5db8418301a3781544606953cb5b155ba66c9efba388086336985a2be790cd299842153663310e4f38f152c6df3a8fa5e54191b5d735e4e230ed31c432ed575ef6f6e5dedf966b64dd58090c8265d98a73def9c2b236bebd3854af93d52b45983bea3e086efd96237b5f4ab574c1d2d1b1309d5c4814e9365f461794b6a2cc55a33993c753bf2762ef0f78b6b0fa178ead74cb2fcef2539005c1505910fa0392f0a40dad2176e1735a6cc682f3787e136c16114b391cbc03404218dc7398444a251702cd520fc328d3801f0b77929db1d35e525ee81db4bc373cf2fe08824fe712b67e68235250a0f4d5f02f893238e3d538e6a4019ed73cbf64af43754984bfb63ddd000d6a724c9c588c6ae00f1c50f4d5776b4f91d38271c939d0c052a57626991ba71bfe116da2fd4e1267c24d94daf09333c0a0f3d0331625c2523df07268cb7563e4bf3e7701790726016a1a7d4a9b18b4d58e906fad51d4c768267755d2b163dde41da9f8748e554213258754f9855b6a9d700533cfda6df54a3ecd8775df1fbad1a307fdb63f3fa65d937ca947419799aa996ef294b621b6513839180b8e789c2ea3055c665686ea5e2146c973fe07259ce4a96a926ee8fad709409ee8e42ea498b7c482221d103367efb9e03891a2a73dbc526fe56f63cee706b97283bbf852dec4e2b24ffc51004113ce2af1b13b52d260ae0189c2aabe45e604d93a5a13b461aa56157517317ef5d2022c48f02d64fca10bd2365243f310e3124745476c11d3186e26c0d451b6a1bc1798a9f38c8d6dbd68caa4ad736f827583ac994888f2c04e26291949887d1e598b7a95c239e7951ef3423db14de8d72ea4e3881b85a1965b859c934f1650c158c178270cbec70035159ec0bd53c605d9efeb5d2835963a661d9597e8150ed3b841c79d56907f7ccac19d5c766cbf476a348041040e14281999183b540f836bec715d407132b6eba663667e08d0cd17c8a9159436c02f8cf5fe1a313267606e819fff693936c140c78d250b4066f6aa1c5c014a0efebc297cbe95d47963478d36d8f2ab46fe313bd142acd06ddc42da296782c365ca345d7c4488ceccabdb0e1e9d3af65bc011200e747de443801fd3692ec42b7462ce731ad2c4693aa29586179bea381b20c1efb51cfa41d08f2a7755aa74faa6c160691bfb37cdff0b898a42026c3d66c5e9b03ebdf8251f2885d38c126de3dda09384f74c0f63a0ce061e88d9414afda4995283309f1a22afed7cf5d22c971c94298bda67bf5ca808dacb1f46fc324cc17c0d7b56e6fda3072ebe6ae986429ce221cb881b104aa19b6b5c466aa13ee87f58215493758bf4056c4b241740c2639065e2ddf3b8f0b98759fb640209e1e085962e3641c9f7b38db329ceb3dc2c75b26a648b8e50f37ede97e6f433e2a915c8676d2a87203c2e9f94fcbd46e5e8c45170b59233ca97c0b412104177fa815cde1c269a42a96cd8b5e12b1d9e6bd8f1937487e8d3cc18a6ec87443564b8d6a88299bd544c09df86e87081dc0233c5879fb58edb3437394e7b3f71ba55d9b94622ff48e28e32c989bb680744a316b43cffa7f24d9d037ddfd2a9d6d5130f9c5c3003642bb0c650bad322b814547c9d45226d1c082dbf526f480a66aad85f2ec73ec46d9a5c06610edf446e18c62593d260d5db8b0588d4049046a9051cd5d18765fe07c5bd413ef013f9796f47a95a5e24d6a0f2f95e03f7a039296a3e8fe762e56b19657c74bbe0ee24bdd8e3f7dcb7b39d72639c489718bf2cbd3c47f697a799d812d3cb1ea74d9db78669e3a5019d846a5dfe0561e8c25e0c205b585cc99a527b2fdd03d191db53889c16e4f2a90a4177e1aea590f1de4db961877d4f17342e9fd1a75a5fc17077d0151e0ed696f229f70670ca3053f0164a40218aee1c48a0a5f1330a08eb28836f1a9b7b7d5cc8f58257acf98131a2b62a3b88114f2b8ff640efdf35a7d0ea5986dcf2b1b47d340e745953d7cfe8c75b867b0ddefe7a704b0f9b8abef67f8d91c5bd7f9d007d632b34e9d154ff02945078dee649f31de67100a1833cf4640d5e78ddc64598c80cf2a4c16b2dbbc786e80d18b841294754c7785f449da6b10b0c388e3d204af72cfa4e0e4372e54485ad3f5fc27f40ccbb5b3fe473041aad8ff36742b67476c61125b323a2004fadb6eb9f3f19baade26aea1185b1a930eee73a1d776e973f4a4bd7530ba3713f1ea410db8d2d469e3f4c8377d9b248a78a90a4a05e3a60db8b61770e31693e2d6e0ec35af3870b17cf355c9f6e87fcf076cb00f15fbb2c2037513c7bfce459a65169d819628bfd55377a01508969476ed121e9de891f5f8c439a3cc134e622ad0c1a617a1310564156d654a537cdb958790d794085195075f607674423114012d3d3cbd59c5f1180340a64be1badedc5659c3a509abd8aa7e33719df0c825f594497d868c22ac5f69f8d129d4ce3606aec70a2196401c81f5b9d10928a3c0c1bc28f06a0f6aecce43fc4e3001e50bd59e01b5d83ea2d445254aba16201a54f409800fb5f135686a0e62d008bd5c5a9854e4b90e9163e48aac92c44885acd4fca246bfffad756adb1fbebf6cd067e6079335a55fb5566b3b603b7abf61b2a3f11e35ecbfe77e6543a8d3de1174e910974aa1e9c9bc94b20d2a9f0ff38a7f375fcd6b8cf51a2ba7b2f464af455f370fb202545d43a0cec266f1fa950263cf8996e8fad8b1f2e306aa1688d011162c05c09e06576bc978f3fff4be2f781b521b68feac93412252fe9f4fd269df27be05c0eacafa04131ab0e6d8b56278bab9dd5f0f3c29c4c94e42ec52a9b942ed7a703f3ebd9e5849649cd6bbbe4a4cfdb5f1ae5a9bcda2d8eed0c259c16b32caf1c350994495ac008f44f587b951f634c4410eac991457acd6b70de425f44eebf0b9712bdc10dac635c2c09a5ce51bc3eff0e7bfc7ea35a350276efee49527f17a5453b3e0ddc0892c576001f418fabdf701308436a67230b32813135b91488644e0f9caf46b3b176bb6e20cd68800c81a72495bfeee2fb0beeba3f6f47bcf83135d6efae5370b68100a21f2d8855f2d78d0fdc5203852763faf0b7f1091c462e091bce3f2c47a289375fe1559dd433d3a07751c3f78212d66af151df0efbef6a6dd4aa77630beb846b2e3b67f866fd04a2d5480aad9c16a340578ab7f5cf1add6cab64d8b6bcc3871c63f8e985e367d4f46b081eb2277af850a57fc56a1afc24a9e1be42170b358134cf048ea4d9ade90d6086172c3d14f1ae7aba8c4892bf4f60415b1af3db7ed78c874db4a1254392794a5ed40d246c773044927d142e134f21409c8b1f494abbbb215c9e1ee83677aa7006dbb17b20e7cf5e6c2e53731c90e33ab0ac8ee25c67280a8467e7b818be7fcb4ed9810b7141d6d30902072ed797719f253e37c88d6e831e76b24fe0480fe055ffbd33876e0dd1e64be881f0b3cf9f62b2382001065cd23d8fedb789a93cf413527e749a564d601df9bfe37829a75c5c5260ad27ef740a2e1316fc0da030b035e696cf98da2ee309d3d8eb5192e660c1f8426102361421382b9b3d1df4b3084b75a479148e90c976c31f2cb9526e848f5273d42d90eb76c3417a7da448e44c4979ccaa881ed6d394d24511405f370547cecefe1b90ac61d052fda3b39982e6106a79826c495ab739e4af7527d69dbe3068132621397746c47423f5f26f8539a8fae4fdbcaab42018d4de0d9f30c81ac2eaa74746929a08a16d34e2aef00c1a742e5504eac44008445cbab6125c9258818edef24a7e414704639d16d8c21d9ba70874f7e2e907c542a1878923cbeb80b8835c097f984c3aea3239a5a39aabeca77ca868befca0183e6a2bb9e14170f9f2f6c69f41f5e69b84cc0f0fb9a713e8ad59c7a8d5cb05657a7303d223c710e3c21a9624684137eac016173b2a1df157462a62cd28d3dc50431eea94ecc8396e9c3d0163fa2bb1b395b133f8c24e0c4beca458ea6a0033c8c2aff2b0398ff46bd1f6e5b67cf09c63588d12108290c8c06cb19201373d78686859878f18b0356259ae68f553dc0145d0f9880e9e943250960f01196db422af839cc99b361bfc10b2fa8bb4a8087b8b558cc08cdc58ae8bb7eac401a138f3fdbfda3a43214859950b6110a5b8e75e5c2bc93b39d65a71a7a33c2aa26e1a6c85a3ad753e2ed0c6c342d00d9893982a46c23604912f375734a7acf5ee9430d0a470971db36575ac0cf77e41fa5dfaab392c82a8d0a3feae6b0c2eb0bcea398d6992b4a784a9e59108e38c8e56d84cd91dbeae6dbed7c864f8ff28d2d7d1b1f6142f969c1a09cb5ac0d74aa955b8104fc354fe464bb20bdd9a4b033a3a10b73da6ce8007e3ecdd6661d7a4c14e1b2f75f814ccbc97e59933269d848ffe3ed1b8a04db729ecc43d34ec2ab791a5f3b41b399baed8f6883e902f844458b825a4338826bd06caf4746337a460ce423d4e1af713252da0e0cdf9b88ddccad169c5cac9324c2fb962c71cb3d5490250ea555b5014ac0785efc54cbdcc4bae0fa41eba9996939e9c9862221bf8955920eac6f90c3730a761bef779d9e6131b78b6225fa22dda4aab53a7a85b93651027cb91714d783beec4bd6aef23fddc7b22f27bd68dca696bfaa4e238d976f654a52e0e0177418507d42b5ce1c5951841af61609fff0a7fba53543ed3d48969a75baf9872f56e841d4af1d4abeb32b8ecae89a85e3551eb70400e8c6d403962bf150214cc558917cd7c331445ab6a9c5299865a48ecd8a5b69a7249357071c11f0e83f15e4f49d79e61895f660eec744e9233801412132765e22660c313095e6cce93ccc1fc28dd9eea03e68333f20728f4d0b11f73180607d27affceb1684f81deb121b2b5986b90f2df083f3e6601e6d9e53708d0894dcb648ff2eb58edb062ee281820551969559614bd223642370ca0e03bdf430a463ca788f84aa15e71eccfcb7694f03085f6be626172660dc45def7a48321f81b0588550b95d9d0b84a5313a8a400b68e7314c8f7e5dde72d762d4a9e43ebdf5602328879a41f60618a7b357b76671a0756f35ac02bdcb1a4312d04f6abe0d7a6f21e78443f7620a281e2b8a4f60fccc3a2b99274f0d2d0c9264ab27a051350dfd4f6b98dc37a2145d646481484d729225aa60a235faa293264313524364eb79df828c98b3d42677e67dfa06658e93a285cdf23aa1423f5d2ed901f33ead3fca037532046d476cbfe924acca224b5fc5de2e6ff730b815524f94f23a5d5ed7ce5ed7c26a570078715b749c6dab3cfc7728e170ad433685816bd38c6db4b72b960965d1a654ad536959c435de2ecbdb230edf594820596d05c4b1553104473f4852a8f817378bc9b3bb1344692b524f70c14098b6e99105a704a592b48ceef8b2162f1d6059233ef3d956ba401f3d81b5281125d4ac95d48cf041b248e623c646251d4e630c9265631c8cc607fcc8e8d03f713ce211789e50d342113d3e2d104205755a354f9ed108f736d5c8464e2c1115595ba5d5e55927075d0467d474d0e47b88f29e4fe89c601b890475b517a81a04e97a7d24f894cc37544fd4bb459cd4a9d47753e2c63628042ca2877229e8c0dd625ebc7d97772251bdf1c179b73d43d76849cf2d7a00493a541e2a95745f64afeeb1e7adfc7c8119d167b90a50e708a98289a94371529fb80883535c2c6497dcde8bfd981053d8e7cecbed626e8b0821d30bc0ec487da1088e561ac1c94f9f43bc559602b7063dddafc0195024b5375db97e6b01a85f7caa585cd3e81b33d1d19fae1e6d7c8018ecf12c8b77194cb283fae311676d2befa88ebbcd1872f5aa578b01581d6048d9a7288085a59b7dcf3a56d8072e2ab4e630807e8b158d54b2f2630f883f4aa3c62538f73b91d2064f43405b2c5c79284c96f047569ce412f7070637ba88bf2e486280786ff27127f0e5ae95759adc99ae13321c17df7d3619a8f3a45b4f6c57d343e1bcefdefe617046c5cbe96c64de65f350b79c8c23c64ecd9124155f721a17a7ca842fc5a398d9c0bb92e6c76be971909cf164a837ee8992e82b1d7bbba42bd3de025946e0887e2648fc6272542dc0ce83f885e41895349512e87a3ea053c62b9e370e8be7fdd4b178dee2249a17859554f823fd7c7cea056633167aec74e66a5b7f7b768db2a3b0cfb96691d00959750a30dea6f036a585e51fc36a7c02b75cd25ec05b8719169f17d5581a5c436088da3a946abeb677048f0621a237d5e2f0be2c06abe50db79ffc3494cb0b6b4ece20000cd5ed834196e0fac0dfbec9c8e3aaea060b7d27aba4576dd90d639be7a2026340eca252a0f40b1717d03c358e47cb33252eef01b23e0088fa274e992e714e40a257512278bda8b0d5532cacb22b4de5dd8c9d85019a57cf102245f9c50572aadecd436dc2d17879d22617b18a4a05db250b8ca2b903bbf9632bd68a36c302dbc9ea0cd7309f40998a00c1562f74f12ae8a99fcadd639552cd3b6b30f5e20e806ebcc25edfa0162a0bb0cacae98ffbfb6d062e5e9e9d14593df0eb59a48d6a5b3a9b2a714410395825e13ed9a42f3319658a042a58301340a0b47c3d6d0a80c1e0037e04b3c8af0f89797b9944c03e737dcaf8c18ff3656824208021bae25b512c3da6d7e025d1378acbe73e8af84a6ad6dfeb475263fd6406df44903fd669693780c287e1bf5ea5fa229bf8a781e29d1014c09445b999512e0e083a278150533d9047416e05522ab47543d0b78ad9355276b53ad318cadfc58f818459b526254c0e8d6f9b12875fc19b02e1acec997c73a4c0280de9ba509c641787cc5c5521c324b6ae0ba0957132225188522e54bac9c5d5ca10c61475333f5acfb6835d4acdc4976a7c2dfb9be39e1d7d5dc15f18855138e42a6ea9627c921153992a3d85d9db11d91bb0d347058864c8c1f3a74083cbfa4eabbf6509b85685cc2f7f2546c9f57ff8c49e898865e60860aa175f789dcd2bb7546e2df202e1097cfda391d1ecdcb9cdf2e387b7adf49a5332508bc6c141e3403fa3bd2d0bb9cb7928e78ae8908a35c7f54b851cd976410865a6228f2ce81cec7b1b0538319f43b05ff8e1f50c0f8b652055110986b73c6002fff07146856bba646877475a8bd74a0a6006939d572d72275b5b8b33d95aa24cbbb737afa93123b3ee8f879c24619d4f7472ac811e09ca9c6ce319d6271af8669c498a32248e79213d7de615cc3b4720812a6553b2995b0c7b9d64dbff9caf6847f03f045bc8822cd35967ede46cbd2fc42a97b20d7c04e421d8e31d88b0d9846e6e041bafafded72a1b37b3a77caeeb28e709e10b37cd43d891e20cb6ef91415f0ddb2f31425359103105b323835c8298cbb451cf5c9f3a1e89f4af81363da12648debda88cf9620a2384344fb22673c914c97090db24438de6a34ee1df1247665dbf2d5df86fd802d80027be4378a723bdab34209e161c807e441e5297d678311f48935b7fa3200b9e5f063f58274a1be0a46235fa07a027ca13a86d7fd19d5e74e0e2fe73f460150dbfaf9dfc33e86b5236c049cc98e7d5f183384b5fae31bf0ea3980dadbfd6ce6bda285aadb2a60d11c205c3aee914840da6045e09ec6f72761e0973b889e48eb492a71b76ad126bed5077abc023855191276d3f5c276da0a1bf96a3b9c7bd1d49a8c06d6a670f3cf71f8e08bba42422665a796b4d4ff0cdeb673f9bfbcdb53bf4c5649202b9a475f747da515ca4750d72e99dd4188a0d5c15e16111cc76aac06b7792d95051a0d59a32584cc33db7103878ae1130b03eb1eb9effeab05a34e47e7ab268c115b5d93252ad40221bb23a0e63778caa4b9c2939c674558725480f01629a45873b2cc5f2fa2e40536d71de5b9ca161dbbf1f4775a402bc3ac77ecba7c79b095553211e6fefb392fa8e979bdbcea5422cdff8ee0fcb09a2693c4427900b24857b16af2b7def45398239c0ccaea76ffff02456b04a73abe742b85c045bf0cd6930ed796b9c1692855c04c15e520853a956a0c1d54708097c761bb100b9496489d22ebb05128350fb6645e4a3723ce21652b333b78e0535521731237ee8e977e9994b73efd43caf403d48b5b224e5d4b85aa25e6a8b27945354963ec2975e77cdcc561116be02cfb5106c3c328bba4bcf9088562a37e9e854227684b28ce56ee8a4f320e9af6b2c18e3dd38c9c351a9635634d91e5052301a6a3a2b84732449ae7f7c4120bf5a028832260b586b75cb9ce17c255bf936082e42da6e4e3703e754433f40dfdb02a6f6eff993ac99f3b1cbc256c8cbab472ef060ac06a277237e443ffd00d8913542b7fd4263d1784e63b175652427acc1d3eae9d8a5ce87831c00bca68088bf8d71c404b5f71eb10b1846b6b49e8c4566012cf5adfea379259e456f018b248f34c1a76f5bbf3d3273f9754d62c75ca01cd22a4c859e81270e6e9b15896bc83d479674c4f5d217c80177e37fd7b0b8d81f8621b998492b92dcc55e661cca46d7b6bd447007fc8ad837e31518c1c71f2a805730f8564abef0bd8decbdfee530172fcbe16af97ef3bec7297229116b233c7efb38c4550c6dff1437a2e72e6452b0ad7a996385c3a7f2add265cf43f456ba34a7a21751f277ea77750b8596ff426ae438f4e688820fa4a2361d51bcb546ba374ea0f7a9b80f1eb4f0da85fca23cb7d1822b260e0c8043e31cd8a023e5f2cdcebaff0a75a4355d67f7448ce3f9bfea5b481b8a047c3e0605b06987ffbda8043712be32a3950cb41eeacbbfd74f3bbe1e231025636fa38472bc611957784fe0dc799da4c632d59d9b76356c8828221f63d4d29d76285d6706ad82a94a52f09054ec66101c53c7efced2095f55b2a1b9ff51af8a8ed16f20b7d44e6862fbfd9da0afb61d58e4dd8ec9d3cf8a242ff5125761ca06840029088a0e41c6366564eff5db3c1589363b5d366daaa19c087a8eb8351b7abf6e1a30733a10ce4a3bd22e7e0fe8d74707f622b09598038bf6c9a63e5869da25adddd938d9e4aa60599984ced983f73ec91eda50afc0fb3994ec3b5d8b87f00ac427ef9bb29b81f6be21fe45c8250ff92d8e01d450956be0a21759b5305dfcca972fe9875050342e4f90524905b9c52bebe3b0d99a81ffb4dc721f15e8202933c1a8a9ecbedc86ad760df475140997d65b92014add158bf9f566ea99558294cc0a564ad9981e2160c03ddccc9a403e6193352c84967d44a666b51a19bdbf488587829f44698264e92563db760dd1e82ad8ad82d5a03dffac136e915b67f75b34cd3ad02c34dd576dfb8a0e08967eb1662ea0e482fff474f4f923eba4f09922c23ad78e18dc6dc5e1117d0f96cbf4d22a441f3ef52d137c21b3d5ce01ca1cb654930c36ef42fbe111d66da8e6bbd8dcf6e381ab2efbb78c8679497a0026722b93a17fefcc98a1e99011b83a16609b363631c34e702ed8dcb20463357dde44143e8742d443c77c2ff7a62e9c49c217abfc935fc9b505bd29e0aa84066be0ad2a734cb81ed6a10558b6aa48740eb0bc9aefe5da1230f0a133dbbf5028d40f0ca7128075d846e052aa92a2622df7e4fd0358c0a5ec09e8f9e0b09430441d3d91b9591017ea2d8ff1c3b809588fb3459fde93dcc6935903836c1143ac61d84ab14465b88555ffed6c82fa74ec97dfcb92d6add40e7b002f3f6d9d68102084b482e6d3ed0fbdc4016858046142340df7f41fa8452d031a7522ff1840931f48d69d732edaebff6e7694fc478158457fdca8ba01c38b0001e5a05c7b84fdc7febc3aa7620a624202ed296622184befafbbe00f044406239e980be8557a228378588470edf4094e251cb0c62bdc2ce4595d6f437c625900dd096d45fc88cfe7ebf328506ec62120d1eb694e49aa983bf92786c03a7292bd9b61431e79f14628d0e3980a6ede583f470f829cf48a20f67234bf9c4e278863ec3a5ff1571d91a04deaa6f8749df5abb83a4b93cb2eec3fcc1bbb51f43b1b101decc261c23bf6de2ea25d4d82e68b53546668c797d8f446afbe506c5a36e3175bb2b21e7f291e2b6b1afcbf14c26731b9b691aef889ecb81ed42cbeaae674ef6cc43f9766bb191c097a47e9204e5a80bf2d7fb1178488abbe54a0addbc5d15394d402af3ceb3beba5a7d3b41ffc4dbf56c572ebacf8bed43bba07b256e132962d7295026276b1ae20798a35bb9979d1340fa0196abd69558128858589972b20f5e15d3accfa99fd89696a5aae61baf0184bf2b6494ed6a1e3d5ff22250403c90742e0a0d4405576b005f45f2a24991346e36c19d73a268688eae63f8955b48611df27a152c9cedc89a93b6e8c903b126a50800db00a4c9605193a3d1cd5114a8c09dce761632bd90ba5467148c964889a8d8c0bf0c0854d7905c09f96702fc7fb8dbd8d0fef411221e3baf15a716cd45ed58ff1c629cfe1e9b1cfd98f5ebca97a52ead5367719e667e7ffc79793acc73ee76e158d3f675fdc35c152e169f5f983426b572dcd9d32356969a95fbcfa5de3956afda64f799fd1337a91c8e2e3b068a38adf2272a05909b1ec40770814b15b9fe5241b0e71dbb7a48630d2d061952d7f50bb414ed9724dbcc1147d741fda553f6adb55a1fe6103ff82f8530f1dd629f806559a22a898e0b31a3f8fdbd93501ff49d8428f5d21b19a3a561d5583b7b03fcef76687dcf341c0817fc1aca0774736eeffd414e4ce0c978ef3e5cdd01a62752f652f4ffd434de30f17cb7ec35eed966c9d67bcb90facc9fbe6cde978c79fa4de8ceb5fbc11989a07fdf134b0e2b0f186755e16653108a87be87b67253a077868827e502162bd6d80e7fb747c01b5cc21396de26df047e5b8288243c6443e5be5cb81c1df882eff9eecd09db87fb874ee1462cdecdf3ff50d1fb4a75e909bd0e8be102144f9447241981803183daeeccfc3c39166a7f3139b7236dad20ae01e2ba618c42b5575797d701ec1f8579ffb9f8f81552d34640cce57a3e5ef1d457a09ab38105b9d2ceee862a56a7f20fd2b794b15f0b49872124e14d1257e11a9be8527c6b824fd9916a219bba0d2443388baeab10abc54e3e9110d98e586dd47ba02294a9a67c2c4b4e36a71e9dbd12ae4725ebe4bdfa2d08c252c26396435dd3a7a851200106bb79b0bcd7a0f7d76391193cedb7180f3fa3b64e936b8b292b1e28444d230710e0b3b79d33864c686d5e309c5568dfe4336703e5f58b7ec19a85a8029ac5be6aab23b520ee252987105aa0d86046261846f9c0e4d8cb4742f81f665c2f0dca85bbd109a20d4aba2369317db5b01aedccac1e8aff4bfaf57d33e6583bad4aab0d8cb45a72a5ef3c00fcf7106c805411fb0e4babfe2969d859bb1578ca79f0a5c4a48ba3abe1dec8db097ae868888d9cf047823f0933560eca0a738d1fb669e82e7dc3d5013fa44aaf588fcd418fa07d7d3151ad51d928de9e7c4cec997efbb3014216001d0f1c53aca3f847028d4f37d93ab6e966cb0afc87c2cd2d127c09fbe0b320e9c54c6fbe813172a4460792188f0a899555a20b0419140be450a2cc15cbe4163122dffb5964aa01c6bb3604f4cb9cab99b5a46baf8670fcd650d843861703cbcb328dee9ec69889815a09202020cae928af2a6cd75572d4e8e12afc698d440565aeb3f5812da2fcfd28a63038d7e495bd76c203ad07637b67087dbab616c2082145f7ee48c3c7ff092a9d733360e64591aa923f6d1f3235cc275697a1e18eee49236223b739e1ffd688de03bc9824b6c4bb4fd2fa1211c852b4d7c995d51c6c49788c009fd8cfc4981c054add2a4dae2af1081262c6c08dd843b88d84f7587ba8a0684c6dc29bd68d88c451943e2518070befcf0024ac5a11a554e4ed83bb8cb033c592c15667bd3d74339c65b70c6ae64de1ef2a04fcfff992ea5b6bc78368e5665e8eb387057f981ebd84bc90c85d0ce5c43c785f2b1cf2727e754353a0a723a94537c3ab5fae89953b688623661ef27b0cc8d4f2f1559dcef68e5ba1910cbdc3e5abde77c9cd4f10273f41d2193cb9360ce48e51a883456699a40d6894e8d482bf737dc097ae04dc2073de3a6eeec2a63b27d939c8ee7f6600ca00f267231ee980f10d8e5f6c4eae5fcedbb65ae11bb89606078a3081f172a211bc3d5ce6e55f20a5d6e1b5aaff320dd30828e599f507c32e366534be6ca5dac74642eeb3487a7c58691f6f0bce3a27583701edb40d7c6c4226806ecff26d1bcfbd499b735c2349c80e9c39a0898d64de1bd71648356f436f8bceb59f71a3fedeb350fd6118c67a8571aff432e10c4a0e6444c60db82e674eab6cdf13273ad6b379e67d3e29c2bc4b09b151d02fb68fc1188cc56417525956ec0978da3243d783c08b70d6bcce330287f9845286b15e062ffb84703e5eb8ffd6ee9e22fda08acedc7de4da7431c528766e0f1ee942d619e9cd5ddbcd407bf00e5be3b003753032857acd4f21a4388d266734a5e529491f9e22e5351c3bda0c9dfc31ed77e630e29854d1870a54e3e799b55524c736e230df74257ac22ebf33abdbde834b384f3392df55c8b9502ab193463b740ffcbdf6ab2e88f10cb09166dd084422e489540a5e84d28c4bb3bc4eb844229459cf9332802d6dde5e72d8abfb6b8e74346200600c708cc73d275ca70007c5b2d19e5800dddf9698d42dee1afccc2526677784affe767088e0e9af633111d66d248c70ac8f0e8704d9b5cebb1b6e865b0f7c4f966d2be989342d21ea595ba64f7a97cdfd88cc06d6042cad232e8638f34f74ac95fe11655c1b083164582400e37377f105b1a3e904a2eccadc20dfafb916d086246f97b52b7693736f9a5af215d4801dacf6fe7f66428dd038c2d285b32387fe62a0571fd2ccacc15f47e37d328e7b32d453825eb99461ec5cf85cbf20e97a22d56b21bd560a98725440061f8e7bfd39d7b3661e907c41e951314285bd8322d848be0ed80dc611eed7619c4e0f20004397f87ebb560449b710c096d78a4268a2d1dd64709849107e5d85511b8824a1ed6a53fba26cea8aebb9f24e26f7ed8fa3cf591418c6f9e6474f3aa5a7d0a3c5d62941ded7bab8d77d6b45fafa2147d97f3ec9a3e135712afdbeb6b80acf30e64e1f60affb4befd1a02e8723f7a72b3c4581059dd02abad76eaee269082852ea3721b9c12dcebd20b533123aa98e07e45e4b130c90a19f8ae1bb27f37e799d392d7301896a1b062f1e92d4f89d2f197b239b688040ed5893cdb851beaddf86c3c43dd92557eb1451c9c82b4801a9f16af81fb9b0ea1a39c4f59176c79da7b7e31fef253a6bf71360348604002577b01f188371218862a6fadb94b651560ab21557edc4aca92900d32e79a9d5eec2149dd61a6f54d6a5e319a16d436213b86b79af74921aa8868f4425d65036edc0e229d18d0a49664acae99554ada13be47818be45d770200b0d586ee9bcfc62af4debcd9b873e0cd7137c4b491c690d48dc69223508f1547560c7ba8fff6b83d1dde42cb614c15eb706c95a58d39b66573d685a7284aca5e58c210b9145083ef70206878b7398dc2bcca52d372317a881bbef2145a683aa260339e7cff032af8bfa1c004e0de128e390c8c539fe18a27faac4d5e62f949c708af2610d7e1b8cbca8359633580fd25c0651997b1420f45ddece6e86bf9f48a54ceff6ded9097db41630de4ce9cc6bac4cb61a66a47369913b5c40b3dfdcefbe7bed04395a200d0a9db05e5af5047118693f2891c2ccb62a61c00dc3799e584defec1c8e526458d8515cc5718d239ebc6b8297a78d8c36f6255e02e0f114bc08b2ca5cab7bea82a877baf2f03ad0c08aa67d2adf014c2a65a9e51b88d167c54710add4c3be23551a6b0598662d4d75b374bcd39a23d1b9999bbd62674a788417347b996e65d9981e636121b9430f0c9393a1fa83e02c8d3686796078e9a193800fd8c0948771b51739655d873e7679135a896c31adced466ca56f2207dbe9d062d08fbe0eded200e963b273057b99bad4b1d14804dc8db426e9409ad9e656358cbe38c2544113477d7c8367ab105a95f3a62f82ae9a24b2e7c2122e7f252905f6ac276309043fdcb46ed2c39729dfed7d0d25a146402ecec9b2efd3da5bcde58e007d8bb5807d1743e97428d248d1fa9ab5320d5c912cfb2669d491a4e27a9666b2d7026116bb32c352944b4f8a4c359fd4ca2b7a52f4f2f64cf80ff5e7e9a56b1255b790abd37863d1cb50f6548f48407a44f065252858b174ba8970a0b49f549651876e061cd51fb252e4971c95660769a1da0de59d0155a6598a616942237350503f55d0452cbd4831b76fe6cb6111efc42d8046f0de1bead925736da1f63015473facd0fa772078a82bfe38b7d13182585f6d5a0b4eae457b5af534b9f1a2e54825829664d4f5029092f330235db72572911a3189266f3faa8a623b17ecfea2efdd549444833905349dcc63e244380a377b030d0b4f81d333feaf26fd6810d362dd0fd0bd972239b420934b9a9c586599a6e633e0d68b040137de0cb3d295325171feb5b90fd73ba26b4d0fdb61b115e482606623dad72ca55db486470686d4403e6e3d3f6d1adb011f5d6d3da6cc434e2e525e96a8da4b87ef0fa9d86e74a806fcaf3492c5d82d3505b7b7f51af0edbaaf668ad9509aff7f110a095b2f84d58d1e6bb71af067751facae9debf89bb2afc09ab653bd77259d77ca020f97af9379f04513bfd3fbfbce64efa43dfd12aa8ef644b7cf840efedfcbb432a4b8bba71b58910aed6b11d96293530942fb5320eb991546950e7ebe9beafa78ee8a8cdfc82fb688785ff5363df4926482082ec7d50645a970a956f881ab1a1e174c8fdd6a933f31f68939bf826b3b9edb86f4f233cba48078b8c2af19d2d2902612b2f31d9d75ec85e50fccff1efe8dca7c82d30c8970a88f00b90849f288ce897b7e876d48beb5d0f6bfd0c450a9797e8ef8a0c928a15137bbe0dafb1d6c66915badb635fcccb24ca167997820019a3ce445da897f6debac8b92a95520a272abde53329fc1a7fa290e3819d4df16a8507766f884910cc111c234e7d5a8e23697f1e5e4c6715a4fe54ddddf413c54f833fea8b5c02e46d09018460ce9e622280197df7bc7f2760af1a5267a1a8d0566a331da7d286a870e9c32a25962b8c1320b81b5dba98829b155c0f1fa7e271651298f873c800a228d0b178e8fff456984eced3b8dfa72e04b26621a4ee81dac7f2a29e9e5a4b4d0b75a85c8251e52a54a9cdf324017b7af309d1f1fc8dcf72ed13b849d327f4681489e08f3d997e6998a60a9c170c8dc275a8310e79fe28d4286ab00d0dc612f40aa5f5a0684c669a87e116e162d31040c3eb095a48c002681577590ec5ef6f7bdd0e5d6dd6cadd1e8d19f1f106c7850a6a8b24e6e4c57f0beff23413e4e6e9806ba0e9a51e4084214b45ffba53b6b632486c281f81025378e47ea69b63760a16ecb93844908ce3a749c404decab522dd04edbd8570760b1c8f1f2e038bc0903a1905df8230b2df7d0f9413bfa9c1ca9f9469f6ad306d14568695f7ec5eb2b06d1b921a53aaf141be9ccf89d5fd00fbc6674ae911a8f4c3d34f2fb5131bffc57d8c1aed201bcb2253f38415bef8987531c3f27d117893dd75cd089c4380ee0a6eb24fe5abd792e26964121f6d1ac46b26fac7cdac90e0afac21c77f9ae6691d6f662bdc5621109ce27c3520c4277eda2a0d13d7ad71da31560dd3c3365513889b530895f4aff9415f53acc8c5cdc5e8318a3cf552cc4a15de8a1dffb6d7cf70c399869d6e41c397999496d4af23c36212f8b5082f85679c98105b1d4ed5f4b87125f8581f76c39f137707378c3050ce93a7aa7265b66a2e83b36a767f680622b446eb468475ac71c8d43fb3a30d1513faeaffa98ccdd7f0245231dccf2fbf06b047fb174782b1436e03842d2e831f8eb806f940c5f4914a5bfa55b8b5a367a679f0d4da29c6ca331a7c8d7f2856c897c712871d6af2cca44b7c95132ec812aa267498566ab037d183313070f10b6a099ccb95e1df25d7a78f37852c6a084c4fb07caefc70e796c5fae631b62e2c81852694969680286986cd9a30a1215df8240daf7afaa6d1fd29d82de85323a9126e89c958214bf864fe096d7dc6025e5b40375f651650211d78b87562fa32bbd302a7aa5a076142774c7cb627692483fad765a30ae0eaaba7db1198bd4be96591b4010f8f99e988d726792f1d1aabd983e9945fc547be03b454d9ffe1700e7e81e340d48c281a2b377c1c261fe07d385d8bb4ee7e84df400313f4743f123d103c7d4baec2098584b2f81357b1e651344c13646b024360534f71ff803bb115e3233e606ead1ad83803a1b7aed517230015387416be73c66c4c40bce62620fe9f796e837f887e6039c53a6eea64b98c7cc18674a575b095546422b0163708cca840995d8facd80e1064b6ca3c9a931635e6f94b899e79e9833ff325382bc6572866cac5e9f24eac0e8de9f3ed139b6a738d838890a06e1f4f14836fa751e899b67bd903be65f284980819c9279cdd6827c09f05a0df8e5919b0f22a0da7b4cea783317ad6f10e30a555804e586fd1a58a2dd8f867af302a690d0ed070218d9a4cf2e996b809baaa2a0cb56874424e488e4f4cb518c5a89dc4b80bfa780e3b13bfc6a95350db12cb3c2cc80ce03759a2c0be69228cf9a89f2bf5134eb3feb21d82b1552ac221270b20412d5344fb9d14ef90948f801c61fb30324e2c8ea4f1cea26e42b67ffe1fe5910358fa851395e03fb8c09a7756ebf9edc6bcf1be60bf20478b5975015af49d5790f36074c3d38e826e8ddff3d554333b3230c2eb123ad1195f4a89f29b53fd817a646166304e79d5d8ab9114d2e9fc06707174c3708d5c5832576d375c73479a3e14dea199e003c09c02740161b6ceeaab7be1dce0d5304a45f9f290146e5d4b9515324258fac723dc48b50695dbab33b3cc5e264691c0a136dbe25df2f37671401658d7563a1c19a5f128c92a5aa228d1d4bd12b033db3424086e8273330b9ae44a356927be6b41ecf24d76492eb3325b078f7d27cd3d514513a5dfa22de4c2d0d7bc52499c82a4c4f0e73fe2de29e0316303b4f821aad02193bbba35bfc5d251aaede7bdb3db0661aa4d3eaac02c61541fe8d6e410d26753885e9396dbf667ad08137d0565ab724600d38e0f086482ab472e5df60a1fdd2e4702b1e681b7f1300d5de307c44a651a6a6eded408be0833c04e535c1b24adeeedfaad26138256f736b99361d054b0f6d4a4d5a759887799c3f197252eb035e56227012ca9328afdb3555b93de560284e19471227b7aa0ca846e9c82ac0cb032d8d5cc365e2be80afdd3a97c3b8b49d873f61f884c76946d88c22b09a5133aa89dc60528d0d90b8a40ba85af90eff98efd9f54459c13411392db2b052bc4a8efc146c0ef087bc09184463dfc14fc7bc4d1b3021661d538e2b85c7ea18e7a63c369ea9030ad9934a8ed022961a249485bcfd1596177597f54b8536ec78ef55c20da76baa8fc4b5fe79e0e2af73ea0a24426470884482b13ad0a5c76a093ed6c0978d7fb5e94c5673b43bac3029b8345bd7178fe92c3838c0b99dd6440ce6b265c71cfa2f54aa8e8e5174bddaa083c5d430fc8d76ae6b25988cf283124c557b30d350ad8628a56a1977ae203f6245ac4cef328edd07241608afa0714fd6a4dc68820308647180dd3cfffb4b7ee0b5ec7bb89c204030761c1b9273a9b43b35111246f2a3494418bac41c5d003bdf1f6ed2f45d52669e58eb3b0705ac59de50c3071d867e6e77fbebd40ff3b2e63c002b590b23aee545fcaf8ad21b0fb8a3bf34f92fd3191305aa6b8fb7f45a371b347245d146e6bb0a0779a71f88a258d97e1f1a0fde23e537fe6f96ea91eaaef2a30e7e8d252c8d2090b013299884f5c9752d81ba5dd9eb4b7b9299cd6bf0cfe3769314ffa291fb90ea07e53630a9dea2f5f38b53c9819bd659dddbeceec7e2a9e029e6bf22b6b16897c56fa138a042d1dd3e2a723e5461b653d77e3da39a58e4fbd46e0626050ab2565978a294e5d217d9e1bd18675a7802628d6814b070062e5a24774f01bbfc0323c24d6ae59b56728f06fb3d093947218697d9515321e88683e834f6b539c04bca72a264922ae00207915c59dee8ce1168e82699c6bf41b6219083cc06b0076c93c56a4518b880eb873a261af5908f6504541345c45a9f00d9d1280ec95f37836ea2c73264b540a80f60d01dc06faa8fa27962acd00023b9072bd4721f155a5631f1a146e2ba94fd30939a172889eb140eff1276e19872e7f25b1274855827d5fb574887c1bea6f522f33033766b53922c7817d74ee51bb12a41fbb44f6065abf04d2375103484ce2c8ed6507c2e57a2641baf061a92e523fa81d882cf21c6338c3f66207906acb6d5ca57409f9547c7cee03150298c82967670f5eb5c46f6f071fe967f99131f657de49db4beb248399a0449372f29b5e167a824274acde82ca46d550018d6355e50611eb1c52b06c031c267993fa1c71dde4e1920888af34052ec239756fe535f54b548852c3fbeddd34f7754bde4f746046041baf031f13f5b981b44adfd5adc592c1db0dc780953acd58eb329c6da6435a9da201260509edda12698dc86fd4492c99dd1c15340d49e0282cc6883a419b5f98b8f16298d369c02720fdf6b9895432d1c8c47d3b0ff33000bceafdb10c81cc8de415cf2ad971132643949975fbf4a6cdfeb9e3ded090a49e4124ecd6b9e28e5695517d3ad80f7f8f151035cb59b337406c9597b9549b9926887add70aace7f2318d5eb35d0a5f345ae5214a9d3c75ea446163c23c02ebe7fb8437f57303fcde7193b8f7758919190342b267444c5465c205707f6946de1bf99b1fb37e6a6fd2eb54329369c8ddd425ec1144fb9a6e20833d8fc1b3bb7c78114bd57a2bfca86c452ede793c4b90079c2b7c53cf3bb79ce9723a621d12e60c93efbe01fb6a2649574ec08799807c573d0665c2cf708476010e8a16940f05789aace1c660f545e4dd44ded8745783894a521c04182fde5215d1b98f00611499b7c803a4824afecdbc7374fb7c569e710a7ba209ccb6692b803174e899aec83ff864bdc4db8821f513a17580341afcc3801d5a662d58ef218061597fdf086e7ff88f22a061f9777a155b582754d76ebb4e3eb51010b7b3359645703650548f08e08ca018d2889f9e66fda219cf61789ca26b7b7697e0b1f3600edd34b25f98980bd237538197b7d5dddf2ec09b81d5dd059a2bd4dc66e26454c2ed84c7f31e8f4f7db2a0dcd2a39254d7a369a8e52d0ea5dba1ea982522cd1a893216c46241d1b205ad4a6c61fcc0a2b098f331833a6ff41250ebec90a232a7ab928dba8e27fda88dd3bbbfdefe6a2457064d1dcaff9fd6445196739aef30c12ffd552c765affa6b7151d0d3d83b0422befa8c0f90e014c227c1856e4dcbff81d1f0d1a1d9bd2d344bfe214fb7c275700ccb07ae176c838e21960928a679b9b6aabc53cebf1b34ef3d940057b7227850600f2092d394895aa14a950099089f41557db050a84cb86d92fb5c5834b019237338317139a53b55497f5822c1043e4eb04970264bbfd267c18d0c00f6ac32ae1c00d83308d61a840929607f5a1950cd3a195c073cf0d68fbf90010ff6321be067f87febefe036356810d43dff2fab0bc64d8841896ab81f62fadf21ea1e5a2101ffa9e2ddef3fe811abe0595a4e695261719fe17dafe25aa71f5b3cdc478762f787b9afa3cd20933abed0fce71ed63ecb0a7ac758d438f3c806357b7ec9523429e6eabcfa70928a14e70beca5284060eff01c3281cf4a0843ac78ebb524dbf478aff9acd971498e06af2f44b897b6e79eea378187ae4c7b1484de074a04882a6e44d43b06a75bd7f3af071983414bf49008bc424ffc4faa618d094bbeae8abe157ba5c7226ebedefd1560b8bd5ac4f4f6121930effe058340816a8bd4598b05d25897e9913c546a2dd0ab549e65e8dcc22add090656c08376582ec02302908e980b21599adb2e89ae14200e12c5ce57cadd2cf957ee1d99fff50723b48a0fce6fc722ebd7c13624aaa974fd159a9bad85d2673b20f7acb8d5b852661adc4b466b1ff1151d1aebdcf5f165222c6b7336e0915500f4f09ffed623be311f2aa6b4185b166714b72ac659b12c514e8b4a523d7048162b4bd16deca8d065dc1141dc8c0e5399aca04a946f817de2b9802434374a081bc7c9b40b91953bce613c216e4e73608033ef93e176c99c43e1c876b95b7e9d98fefad3235de3f24e475389ba4cf44575b06a31a959e11e7003b4a09e8d2b134da54113baee834fde8a25169ab784b6016af83eb62fe3f57e230e7d9c55bf5c2b3c6e830662daf511122eab6eca641a1256df9d864649e3d5df6fddb0036e8ddd98ab16c0c23c5b1a1ba628839d93cb1167cd82d2de8ec8e0d5d978cfc33fda2300a4f0ef797c3c8bab8a61a3af6a20574336143a7e1a5d89ce0c413307b0269235fd113742bea3696700e6765a0e0c20fc30e4e6c24eef9c6b8e4b7b6cacdec06a57cc1d7ddbb9d974a84859e25a8a103a610329fcecab882fccfa3f0c61cbc26a6a0562c3065814abd2cb1eaad503cf3be046983bf012bd7cc2c8ea7a2ebf0edf6c17fbac8cab7419f178bf5e8380290e9194c3ff9318fb368dffad86c58f2b1e63a78bb6df06f7884ff975d079325e0b72cdf502ed87c2193c05e801090ea0f18a10590bf8143858cc2de5541d3430cce18e26deb1f5fe1ffee7d424375ba7addba197f4f703458c5b1bfae7d8278fee1a077ebd6667f1da6ec22f14da1ff37b658b7ce4865609ce6094419ce2e1596adbaac5b4fd5d7011d7b7cefe6015e71522bc26fabcb76c0ca1264d0fe3df2d477f192c3a5c25eebe24ab17816ffb78e8af0a505d6a7bf5919e95331b383c5da3ef168d48b21459dd73742c3be98745ca15df1e7fd8be3705970f6f2266b90a9a9e065fe4254f6e463cfbeeeae227400e55abfe64e55b6ca0d2108d48664fef02a28098cba08fc20a99bc793a187adf47d449a5b8da3a220bc3dc8f88acfdc18374c15e82a03638fbb9848af21ace8bf5486fd8d70861ec2d91330363faf411ab6b50d159497af6540a1a36795a1299b04e3c2818cbcf77213442b5f9ab95bf6ea881041fe76766c44ccac9c3c6b052e6d20a24afe979d1f188dafd362087e7ac21945a3091485c35af34e6825b7f1b934da62eed45daafae4e960b917e645b74bd1f3f0c7decd9b6a7758e66e1d882b63d3864ceb7038b680395b3194cc3b138971c21463e076f891871ca15f7ee4527c0908bb6195281f87c36178b062bf72e58beba8343a041596624ab76b41023cc014816988c841f2b634edbfe5ca545b5c0a8d0b2243e65ef855f8e02e73ee7e9e137832f6cc07f3ae72dedb969bff0a57c865e2950780af6ebc4296f1bcf3b7b80b452686d1dfce5748199767faa9e1cd22f16a269d42212a987317545142c3472532a8d754aca985c280f6a5788106776991c81ddde7f9846588a57e024da9c76d17d72acc30f59e912720d5428ea864c89a7653a6a33e0d88ce7cbbcfd483fcf2e6aa7366ea256a63ed13e82e0ae8152141942b9e2360d1dbbb37dc8903ea63c27e5c304ebaa20e063f373c8bee419b70ebdae4effa8823c73c38bc35e9ad41af0bd2533079c644177898fde4add14a9740b1ced0c101888228a8cc74a2cf5ccf0ab91501cbe79da63fe1eb8b5fc9fa2a39fbea2768bb4b88dc7b4b99520a0c08c707b7074f5ec4e87863458c8b90270f9d1ef37112c103142d70b139865b903084086eb139722cf4b9050e4d3117c229433c288b2de6020e1e9a2c89d19fe39096c55c6014c4684b0a4dbf7744cb50cc859c31616099433a886928e6024c861d144f4289165ddc622128d27148bf30025dcc855924c66ea314c1af511cb20b94aed8c5e6183211f3b1af0b4ea4dda53ca55d62964566c00070014c7f950e5a8304960c614521df4869e101f3fbeb651b81118270dd00169d741dcf2ffed0db51d4fbc3afe7f53a5d50fc768ba7cbab60f18bbf0057dcddf90b70c5b6bb3b0f6100b2f09c32be04932c9261b445068009db93bed724497a3446ce39dd65487ef99324d36c12f24dabb83573c571e67ed78058e2c0b623cd1e7c021145268a76229f4008892574e9d2ee347bf029e6c914611fb92b2799db9dc479390b921e7876572cd05bc32f56a94ce82adab85c7f15fb887e390b9227f6ce2e21df1c95bc74d963cfc3b9fc5eabf42af567fa5d73a0e5a6c82afbcc6005ac882bb81451e3d6d6501d562c0e52e6563145891388944b20c2d62e229c4164f919ac41a506951a546a50a941a506951a5474603a37a438b5083dd8596fce78b0b33edb8742fe64884eae662e6719e3091e32f09865796ae27994292d11a4026d37d00b54189492122ef0ac308102d28b029d75dcc549182b71c94dbc8bb203988b627445d2f54f4156e372ee87312e7839f703184f84f683f57876e6f3dec65b500023967f1686b1332ee77ec0e2a675390b089cc82813d773fdd58673cbc4b9a50e8e195b83bb3881704b06436fc96282849a49110bee5c81945c0f37a19c0f58889c7250c2202141cec88a915b4e0448b4dc085a90fb81caedd95e1111540525463409420645298623a8406a02871c6e6802450c65440aacc85091d62bfa8e386f4e2cc91029754b455d773737c063fed51ed335bfbe2eace337d20ca9f551ad2175c847244684355d93b664f06b7a317ecd0608d9669a4678b46331d55f478d3ba6abeca75beb37ce2f75a4f99e486ccaa6ab7e6aa4f95a3d825cf589c46602a84d51eaafcf43c94f577d29ee9faaef5f5b343e50ef8fa2f95a3027ebf74cd70742d8af3f65b3fe9cd5f75d7d7ff266d3557d17f36aed7408849de5a797b38411d34ed42c6660518b86785fad161083224d3c0102dd0c359d305c4e00430abe1459129b73ce3951484c2cb9f373cc39278da62e6202f384689d29f75a6ba5f3f331f55f6a7e3c53616a2cfba6649807f533a38c2a858b6a95f4837837f55feaafdf2c36f5f4c3d43845275b14ff7bf1a346acf8f341ef7f661dc5ff46be2208ce4ffc298262abc73d2af6f77defdf47a97fdee3f58b3027515642bed1e969c19ca441a82ff231544b8a7f7feec9d2e5dc13a45b9270fbede5dc1311dcd0555fae28e8b2fa89187faed5fbd902ff67fe781dfdd9bff98deff5e8c0b07c3fd96f5937847cc33ebf29fda982044e8a40718361894810424061cb3d012505344c3aa74fa73c10b1a39452fad3137f784b0527bdff4ba3c996f57a2084c0c816445fc81084939817c653172f2890dd10460962debff7a4f775f2a8e02eaf0b3b73b33cd0f3bc67afb91d72d7f372bdaf717707e2a4f73f5ec208ac7f7b5e77bd021ed9e1764b180c9683cbb91d9ca492ec2003a8646fb258b23649883758d61499176c069773b51c5245d8d5e55cad488864c330324b7051bf5895153336587105a918581413a818585412a8c456a4f0488823ec7739e764cacc072c7839e7c4a88793da5754adb563ada25d2d29b151fa234404e0c890cd91284900a00bc0911d90d49810060d00479080804656337baaa1031894686650e8c041905107b32a38b09838983dd161831d3228b166488634d821c36d6004cc0d193069e0469880b212d3343350e9a84c1675396724e996b02936ccb8ad8ce460838c1d4772342accc8111a6cb555b44a33c2cc3003868c0a7bc14ca6da2a5a31365bc4c988ca8418d0668ab0c00671662403ab4bec888156e48824eeee636a758c912d819009639e6a85ed706b7dd157f559b5de5a6bad6198dcc54d7567c33cb98bc5c8dcc54ee68ad068d861243786861d300cd52e66f05e48daf1c21258613a1c68b555b44f5d4c7872faac126dee98792658e23b8acc682d5ab2e303b23a24544d188366c55aab65551c2ca73281b5b99c6586da8c0e332449e1ac8d81e7c576704548a4e50449ac504902840e7675394b9210cc14254922f660bdcb5992ccbe2a561403fe60c32eea08ac88c5934571e1c1d6cb5984b61c215425254b85111a816a0cabc1e52c424cbe98610b2118c0279bba9c05c9130d09189bcb59966cf960308353b0d6c1bec9349b76a856f38b644ab59d4c730968ba50cfba614320c04dd568b1cfd7404b4c5b6e73d91d00a582930dab71fb09d013c2edfe6959214f8dbbfa7baed20cf9e3b1981d674699519cd1200319e28a4673b30cab414fcf4cad94e906e2cc5589a16aca904e7607a9ee0ff5214ba503d51b34aa53a29dfd7dfde07fadb24be8afff3351750c39f83efa1c781600403a9d4e57979270e890cfb23855889627aad0f244155eb66cd1f244155e7ad09e30988e0e0cf6621b236011c5cab5360fd84d4d8551dad30b165d00718e9970420a2f5874c1838a50656281e1e8e0c04070c1d887fb4b11aaf4978c85a41cf4aca25851550607e3b802c995f61451008a0010eb38d08dbafa22f59da79b9a95787992404e7b02a00ba0ca05850a1481dbef0fe4a58b1980158d0c3690a11ca7d64fd3ac92a669c08a4a85628faca463e38632628f37379c919191f11286322c9d7177777777bf917177775789738696e529779feeb0276cab6b77b73be89f7b247577f7272d6bce38f40e2d82a6817177823f3ed89271a5c5019b336b85940003f6ac65a91d6f986412e8f633c928dc763185db5fc5daf5036190946ec17a0b5bc29cd8923559ef0f83e92881445d2c588551269987c074c418613d4a08b5fd6005d6569d2a6c8983e3b49d8c63b06cf1bc6e8f83dba58cdbcd3c75ba5a06153d955b1d0cc13a0706dbb5ee80c8963843f387dcae348bd0f33cdc75c755dccee2922a16a3eb2fae2aad3a5cdd7517dc0ed75d38e87b1bfe7564d91bf8b31d3fa474590f4de3ea7fefa37e8f6a0d61553b5d3e5bde9087437db0e5cda6cba395f336639f996536cd9b1391659fd9dc6aa16f0bcdcc93c87ae5bc95deec361312a77f50c62a5aa5dbf55fd5d4da75a434d49de1cf97c13ca87164592f2c97963fa73a28058d2123092494edeb349e2fe3a6c61a036b02dff9f5414a53425b7e59e0f63421049bc90e7897d2b099ecc0ede7960205607a5a669222619d0a1207a68323a6345d0ebb9182355db60052d812a6f337ce5464e73be5a7c4db814141d00ca589b0c4d6a062cb29a35ba88ee63c60b29fec057e397d6ff7c3808fa6c46cd2dc86bfed62cb7a3da8c2fad36c567a63266d06cd84269319735c126d220c92c2955f3f3b60604b7b43c9fa8f07beed52dad5cf15a2eb9f63a9fe7097bf0555d0619deb3cfc2c96b553a7873d283d80c2d8b2de58b2b687d20abc0bd223c9e9fafbe0425b491c35d9723bdb5113921318efa01d4e0a11d3b433812d2dd5c1965eabdfb666e22e6ff2af11f15395d99e35a5e0e5946c399bce665120dabea5d6dd92849092388717b6ff6736a5e043c7e40186b0650d81adf476f3a1a17ac552977d31e4b0c2a4d413470e1decaa04255be210594ce596acabb7c4c1b95aedff1059168bc562f27220c7c0482b46d71f47a76536986c596bad55b613594880b9fe353730d6af76f0400a5b8a462815b7d98ea21c4d4a6454bbcd8a445cd20f4790b00209a12f5daa14ed7a6c5101080fd67f86163b167801e6b2189759d0c5138eeb5c388743baae44a1b0623f6b035c29c6b10fbed8bf250e1a42b6c4413a09a3b1c4963898660cbce5e6a888ee0305224b9b581870ca2ac2ba5c7f1d1c34fd342ed7d103e6050e8e6857ddbaa143e4dc90e21146d7dfb218d74d69103073fbfbcb156e33d9255912747a6a6ed7ff491cfd7e6eeac115cbec6272b564739049a8238c905dff1b1c97d1cc9e2d285fb7fddc832ab5dad6edd984045a9196c04a594f697555b758940a400c5b526ac5962c76bd0e4eabbc216fb3171406d97ebe292bedfa73f7b36a3e8fbda2c23ef94efff7e44541d789dce55f8262ae0f7920644b17eaef5974e63ba5cf8476388724e60b82f20d5dff92e58971977b4f50d8d285e8ac63fdd199e7952e54f9c5fdee62bb1272fbab50a57d50424e400d8e9a228eaeffb76c3e0d148fbe96ecdfb2c646892d6b704e6e4ea0f43ddf78b447baaa591c9af9f5031fecdf92dad0604b0af31fa82042e7d1de270234e641c15dcd8fba7e7f7c031a2cce77927c87be93d5a1e03ba8237244145d7fdfe23bcde53afd5a2555a2382793dae97aad16a8e7b4d8d293a847a3c2c877ca8fca37f41119dd9ca21c51f0c379ccdfc3af69e4a42d0c5b5a9b2a6cf90d4d9ef902bbfc8fd468301abafed648c62f576a2959d9153fdcb7745382b4eb8d7d731bb81d6c794373b0d43679dc56fb8684837473b35d7f12d635264e3613f23be8967dbbe1f18c6ed7339a3c1f918b334a4fdb8ce23847bafe211125fcf29f91c296d446917ca704955cffb2a3dca31ba8a48fdad6362747d1c98ad4c1bc3912b55dcfc8e6197944cef3117d455e9167e445f18c3e22db513e22cfe823f2ef286dab799056890883a4d0f71d03d886ff5fb1b305c4ad99294870588f471d318498eb5f7333852d61ab29ec0266a4b025ebe61790a332ee27875d31d5d0417688a4ebbfaa9142bfc8c7eaf3cd2a04411004c16eeba45321b7e13f43881b25d6460acbba4962695e8441453e067e7dbe293f99cc6df883e314c0186bc3c59653e6dd3c1cb74ab753e681d185e07b385752f25cce75a5bddc2a9de996b63565166c7960a607c677caea3d55f1937925c899a0a8c8c7bca72fba0ddaa4a43b994c3643fd1c6435b76e2b366c095b8a4c583256029cb0fdf4f611564e08d9b4321bfe3c9698d892958015581a6cd932779712762c8890714e6666e66e9eef7d2bc8109b286cc960e67b3fed6257b923a2eb2fa4db1bc84aa583b6ca968d428604f1da4d55f421ec98bf0d14b65c5d7f5a1d713d882e4c3a2673b284182c930fd8a6f9cee842e54ac8e996f496934665eef21769257cc09693a6a23224963ac92e9b31842d67d00c92c962234dffd31dcd22178451ae0433f4f90686b3127338e936fc4908812debbd5f76eee2fbe5a9e79e00258aef84324e28da720214a319b6e846bec3ba9b5014df61dd10604e8062e43b34274031ba47a8daef79b5882762e4b044857af4045b18551004b5000388a22e4378069801064cb1daaadfa38eefc31e476f2c7f78ff337fbc81b0aa0c3421624350ef82131571129332512365950eb0c71276fb2b6a44b538d6237dd4ec910a59af05847567bd75aaa85026a1c917b9d81cc32fb1b04350620532c45c580d81e14f5c608416a373a4f131e7952342b8d81c6b8ec47ef28d4727ab9d20c110361c2462de0f4d34994590bc20d11e4a52454c8c8e3848c4424fc948099e88855f0f554c8985a09844d20bbcc4c22a4e11638c5858456fe42c4b618c60c88d15312fc529c6b244f4e9f426c02730e914609703f1ee0a6b8193c0961993219a934d9bde399de354d8927540dede240ebf603a3aa09a0b9a8a9e9e9e9e1e92fceffb3d5ff6943ddeadf23defbd8d68d7f5a546e2977f0e13966d7036acdd4028268b6404fb70bd6299b84e5ca7e9bf3e683a365b3e429a0e4522b1c68963cff833a2c6f175643b09a9c7f3afbb4110049b5f38b09e9e10041f172914e557aa45e96e97c3631eb7adeacccc2d80e779dfe739d77f3eb18feafa4f313c53895d41ce42b2474c9950a21f4ecea73fb698415b6db96d16e07ee3dc39b9b3a96251b7a4d5a68a9d4a619867ee80c13bde2cea9c69c38e67453ba52a2e960284a1e4c513fce53a0b7d9d693679a65151df98494633a35952d1349a497d633a758ebf6a3a81315fc0e40cc3aeb9eb1c3aa3317851ab628b3aa9e4d43798739cb83e73496cf1b495835ffe365576f305dc37bc601fef03321ac35398ebd46decf302fbc0d03b148926fde7ae745bce6d3b5a65e6a692931d2cb13f88e6ce4b729453c4facd26839dad929d56c84049c946e3a6b9adce59ebfce6fc1a0cbfbce89cf905bbfca90c19cc72eebad605bf7c7ab1a4775a4deed8e77bffd90565c960290cd7ab18d783db93e6fd6c1c5845bfaf9b49d6dccddd871322a429a52608e1a7180cb664dd20e100dcd33782748effec010aa2d33118221d60d2636057df10424372fd7d38d06dd4477db381cf62b1584f4252230829155ce31a77e47356661c6ea5c43edef56f2c3ce2d867bc3ed3729df6c4f50f8f6e3459faa8c1b7f1832d99e9e78aed315d3ba6cb6b4964e856a01f0837ddfa1e377d40b8a9070f279d8a45dd7275c7d8bf5676c0e1aa28b1c41549310820d144b6040c11d85025c62840c2822567e404172462ce421317f450450e4cbb2331ffee6e77c7e168ca36a7c85cf286d8393ea46128525425e6c2082db0028a18f8fc2cc6519f4b1b03cc6aac8e302363b53584bd40117361052606d60003639fd5f51781796cbdeecf5a74dc46cfeed9a2afd33740e09c1064ae7fdb60624b6badd7b23ee784e9e079b99ce7843c37457eb18f5f679fc9e35a3c27baf87d37d8398a2851f41cfb10e0fa77fd9d8bcfdae53eb4ebe7977f07385bfacc91b812dea98179dc68cefa86e384f059139f390bb809263d0acf7993107e85cd5530654a4b499e6464641401288c5ab500bf1ec42f47ba2df46d81261162629de63a5a6cc94939fe7dcee939cf79221839cf52f31a651fff4cf01b845f3d18043feab5e954c7c9967d236a011760ea974dc5457dd957dc3e9a424812d7b35c7fdad256fa4633e91c7fffee1bd24ef8658f61c24a6a46583a3314536218a68efa8623813d345b4847b5c9d3337d748e37ad285445f22457725cfdbce99ecbd01a4ea56a3d31a152049356d8e57dcbb994254ec02f6f22aa0ddd1ce7b59ae38066646464ac8c8c95f91f9f9191919119e264b7cc5d7d03039cd33f6381a1130468f4c1affe9ec983828fbec100cee977ea726fb7dcea0a2a25c8dcf9ce837aa15aefdda1075096998aed5bfee774fd6da858ef96ff7dc367d777406081264dc791e59c154e974d90b9b335845ffeb1236cdfda3302189673570cddf22f6371a47301183818e1c52e063479ea3bf8a8f7013e8ac90708b680a60b0134ac366a5a0fedee0f271d68ea6acc5398dc3517d80e1a328698169ac62f0f626fd74003e738110aaf2e6c0a40fd64cb9efe3ceff33ccffbbe172e04138e9973ceef9b35364ed8b29bfe70bd697d8347e778e770bbc96d27de7780772bf40d1e17d0809fc03c210478a76fa4bee45cd85a61a65a55856a31bfc2152ab8db81b5d6d8595333bfb16f60b20626bd09bbfc6949c5f1cb07508fa65197015f83296cad738439a9d3c3078d162ac9e261b8b2deca572bf671dacf0c82445aa493a8ab33862d7b56ae48cab3a35dfe4c4544edf29527da54b1e12d57b456cf6eb6642504f0cee700e6f911f4c5cebd95702361b26b609773ed8b2632f0cbdfbb935ae9fba16a953db305fe8fcfca9eaa35f5e3a8b16b7765958e3ae2f04ba78793fdb319aac32dba6fa02e0b6cd94aae3f8332380a1f842e47e1c3d1e5da7ad0c5b0b57b5876b6a618619094a69305eb19c3da2071e2d63ab012c662d514e14490cd0c1e84be5dad449205b6147bee6cd94ee5e804e6fb0de05f8a5b98744defdce5f44e979f75c3d366d369828b478213db039b5cd892c562cff3ee960ebda27f3451bbfe2ab093ad69006145a6eaa4d8b242db754ed4f3280f2a60b10249853fe79c73a27ece1a2a8e640c6cb9e2bb721e8ed1b0d972555f443ccd969f72ba04e7b43ce7fabda2245dc4a4422ecaf5efa01612e1892d5ba6238aa2ebb34b20e25d5567b2237c21525dc809b0fc7d998bebdf83634796ddf5e7b1e527b7684a48d127b664a5a9746bd5e18552517d7016a4eb4f45ca54757834c717d69ff2601d87ebf8624b9dabd3c359a0b2cc688da241832d6b703ee054cea580e8fac37a7074c4d8b8ee57aeff8b5bac5685c3af0f96d8bf3492c0e04a10362861854f89c3c5a4569b62542baa1545b1ed604b5a73da9091acc6eac1765399b85d7f71b5bac1d9d9b2be5260cbea3278384bb9eb6f3daf39b743bfdfbbacd2c18207ee1cc3fe2dc557175b8a305dcd2ed1c41259d5aeb6844152b806e4c73bf9e3c7e4f96ffaf1b3a2f956601f2e7b88572c56139025a2d89be7a60f3f8f497ed152b045f9e57580142d102bd6847af6b3a367fc334b410416078d7d689a03b407a594a61cd544771fa150a8b6cdd60a4e8209c0173b5ed487ed93c5aabee426d4875f521452b84098ebffa36ff4a8005b8077c007827958ecd34454c1328e6d2bb909845bb68d9b44c0a918e0b1d6f9f2a9a09a5d86e0208a6097b74dc94a09f8e5ce0484820fdb0f15b80bea3bd59d721c7ec19cd4e9e103c8665389a9b6825fadd5a6892060828021d2eeaed3c3472a88940cdb4290eab5eb370a854ab5207383d43b9fcad83103f57e44689014bde15bb186e2f3c8c2903be79d330ce78b791adf31fb33bec4b16356a631ce18658c76c4e13b2ad4bfcf317cd56c957ec39ff9d438c7b2a6de8eec2eb1c53335aa7e666421f5576664a16f8a85899aad9a1385528df4863c6d28a65262984a85a9948e93389cfc51dab19371918b5c161b335b92e5ea7e5e12fbcc3f9a45312af25a931b70681bae13895e920ec60b30d04549ba972cf334780b01725cfd3332ec8c4fc2c19348c71ce220a288aa334c8932aa193b4383296c49b2d32071f805d3f10114845fa9718893dd445d731229c949252749325cf27d73ce23d7b1cb9fa66b1a8e55e079df47713825f659f29d0602c6a7934f31e09734a8a44277cea47efa31e671544b84db20b874ad6bddc8fd7ffd5570e738714ab810105d370192ebb4c9e4a87340b8a5ebdcdd754f382b3824a66e098afa71e2f805b6280dfcf2076f4847b8fae53cc2512a0508ca606bab6427efdb3c3a9a493069652ec1ae89eb1cdd952690983b2e4cfda5eb8e6ed304ad1cfcd2e9743adde4e9db4d77d3dd743da7e7797336f94ca2f3ca84e2865362025705896905aeca6c9a504c152881c3dd7044dcb460a9327113f7e136086de114db510dfbb8db6c6159f37d5f8f6aa5517c46f8e55f8293f5e7eb5a5cce55d1e5f6676484e63be557632afa6642fecdaecf39e767847d6a7463084a96733927abaddad88784eb5f6f7dc35f40ba4cd79be644d5dcf5236cdde23bb694ebb85cff6c1536d65bad36273d070f76b01ddc3e9baeda98c2565b0d0098e7fb6abecf16859d51d67c40b07fb57d36cb2f7f0f86b2f0cbebfbe781338acd568faa6ddaa69193b535eb510d818a2d6b5a0fc0f95725ff6aab375837ac610dfb2a08d63ac10ada6ca14d0618435e6e33639a5f385eecf23941c06259091288b93d7c8795200198ebef03c81f0506a0beb6686acc7ef0458945b5641bdc62ed6348c825561ff585294745d2f5eff14577fd7d84b5f5d3f55ab2bf802c745354316242c5099122c6b8a1c6c410495409fa649ce0039314268f064ae0031044b5274f8a883916b6a1dd1429a8886124e65d68010222c434b9c1c82e96e3486e4a0d065eb0d022e6efdfa7fafefbbeefc3c9f590a1a6d81910cc518175be2a1dde7f4f2ba51504ebfca2e6e4887dfa75c8344f09edf29f31431445715a61bffb7ddfc4b125094885fa0840311f2ca1bf8223cd1014c216500a1f7c615bd612e2640837cba9d4a73ed52a1d552b0a552b8af9d538309d2a3b2e06f0acc9c33a7394b9acc963835dfeaccb1a21c94ba574747faa1b4b567cd54b6900c764be647db4a2522954e8a93a950a3f35fa0d53ad5f6203a0e36f28b1256c6471f0b38347dda5bc1251a7e7d5f8e86cc939ef6130ef6bd8c72b0a045120bfba67f70461ccf48da1b2390688b68e79fa0594e7d54a856caad82973bd67ec336ff7b4cbbf27ca0ab222b6641daba70315d81ee22bf84eb7c06f484bcc10316d843b06242c1bea1aae3f0cddb60e226405272bcb531fa250616a4e146aaa50287ec19cd4e9e1a3652d93a55a8585d9576ca74f0a6cc94b3cd8a76f4c1fe6192124278f104b6660425f14087e737e41bc87023ac75fc8e4610067c14f4f24805fa10212c03e2067c153f8f3d8c00b611f9086232f74f7d7fd753fe9246c89474a2686898989f2649a3c9569c8d26ba38aed2fbfc6c929fac6d4a1735a0af6e9666aa6198259348d745260cb9adaf5afd1600a5b36d3656a26cb62391393c7e439a9b5d65a6badd55a16eb3f05995ad68bab2d5ccd0bfb849747480f8dd76bec3372bb5855d827b4381036b4b023cd0c4e631faff1cbd927047cc3a5700e0dcce33bb0cbbf563acdf33c06e70453f8c49fc9c3b15699306fb73c0a3f85cf596ecd8d540cf058d8f2da74fda073c5963dd44dd8493f619e765ae7f895b6e1fa075a0f4179c2a4ffc02ef75a5ff1201ae73cd09ab8d1fa4613f2f44429add5bc9aed82a6e448c806073b8a9eb7c3c454c8eaa53bfc27c03eeda5c05cd9f29c2038271555dd6037485515c4817509998a50480cc31aa46f1d2b503f254e3b45c806b09cc362e87a14552b8afe2c612cc792880c20acbb650564befe8cf167cc61471e33ad12083f9569b193f35344ee1457b81d44b4c159f096e29d0fbeaa15c4af47d33ffae8568f540b68094bb6dec910bc582a53bf4754aba4b7fd4e50b4c1592f04206cf9d79decf977199dd212f24d69c32327d9794e9ed3a5d4a065cc85023eab24d0924999ef424c4a7f534a1323c2ceefa7f99ec86d0ee2dd6902a594524a6b05c21b53038c2da70c8c2b631f769a4dbce34d4ef677b9cd85cb962d772edd7e4f621e4ff21af3788d5dfd464636dbec59f65366eae44ef60a2954b660c2d2440e3127a2e40343e0866c08423725e63361106d6185115898004aec031dc27082a8698b179088f9bb0656d8724e1cd994c964b2cf889c97b9a18b93797273c02effb13aab85cf6f88024154d5512beb4bcd894e07043479a86ece49a90845942c1a1baec12c26c016568f8f1ea0a0eda8848d77453d0ad1cc080020001315000018100a854342b1704c2047a21c7b14800c6c8e407c623a1889a21c476218830c31c62003800100000098a121220200d063c33b5657c0109904cbd1fefa98995985ff6fc0dcb08ff3586555df3c9ecac65fb0b23a9c33e89fa41203239c03640f431f0acb28b65d986cfe8a03c198226b8d0760258d75f44517ac4907f8d34ee8838cd9039a5f242a464fdbe1ded61e1860f1a3908cc4e7a4f7701606792b47652ad504b10dd86f1204e2a8d9bd04332ae25f3f8d24953ca71f35801fd8253e50211a5e9a520064707e359a5da7039510b0f2f45c8683c01b867821011373ad63cd0a97329e5652634e0104813a5ab0a4fa3f3ec454e65067b001d192fac460c18b0a1c07296c0be56e49bc664d7aa04b80a714d6a3b6ba9d420bf145b9036f4579b5872f0b70a1a35d6352e8a8a7f8c047199157ff5b7631f0f984e8a10c14467f0987a5174bab838df81d5d7311375d2bc18aec14079e5c52215bae9dfa97c8f537da0548b34e53f05796a33b6d4b97487fac776afa635d967540471309dfa13025c47434b650e917563c50b9c9e8d4b4c474ebd93a1c76db5f8c7f55a574fcc73d3a2ff5522d24c8ca8cf702bee5e7ff25aaeacef9a35141df12df63bacfcbdb7531d75dee9ef96f51e79f694685f081462d6913c25dfe5c75dae22b2b576e09cbb9eba82329db080e5cbe55a4563305c6100acbab8ae08184951ec23aa8c9cc01b4cd0544569c5597985c0410d58a628d2852d285094a1e3ca24b42dae1ff5cba0b62bf0d3d1e5fa14bf161c3697410155ad2897255de4902eec53964037a90f852eee36e1c44d419720bffc0e03fad1ba907d65bd00b90d404124890e04e538f2fe61f63c911b2730816058422dc0c8f76eaf4f581927d49b02b058157611f2acc782ac69ba81f298e656d03799012bb48c0aa81353c887338c2fdaa2b6f5a8691a73cec0186b31e971720c2df6de9a1c0f1daffd6a91711267dd86867441ca813d145d9719bf21b784fdb580ea5d89aee36672d5ca68ef2394acbdd2e69b2a308b2cce8fa8a47990afb73e053c34b2e9c3964c652d1885ea0072aa0aa509a47096646c746673564bbbc9b5e74aab2c8b5172cc5afbfb472bf25c3788a06080d3860251058a4b8f2bd84f6eeadf751dedaa67fcfa65c686db795341656b95f2d2d47e217d73c3b3a0a8f9850f2089ddbbb63e6a06a37ee5da047d85a4ef0faa6f5a53a3d2a0184dac31f0c6efdd22668324735e52c2ed3dba78444a0265d9111e6a34b2bec7ca542bc2e847ab09f137da025c9b3e27807ae0a6230b6602453e6e08c6ca1f7f449fc6f1badd522f5f7cd094b7172f4dbb9eb4a61fa30fa6d0e05f4c77b0dcffafe1ef544d2a7f7a1a0e247e72d1c928253b77e74021a466316db37aeed966a35cc0f7db2fb229de6f712acfeb5d219a856b5f9d954793548d81257862c4a54f6b3dcb96356cbe19ed09c206ddc2601f85f0856a409d3b5d9cb816d663186a2a43ba5c1c3fd4079b811c285a072c2496623a04d3613156611b0541f2299c90eff099c261a46a67518fc809175e063ad7222fffc00910f0518c91c25964d4a250d8b30ecd299ca5cad7737c61700c76b8c00483bddbff45d1c771ad1a16d7b026ae4feb38f0e7921e3d0cfe0a042fd337cd702cc0bb241381c1bb00440cd421015b2986d48f94d4d19cc374e06e67294c896c4e419c0def9e42398029ee85a6b27254223b4f0b7cfedc9c0a0a00e9ebf19660f5ab7d51e527f2c6f9ebf19da8a25fa10e4233ab899c696f24513709b525e68e6a97f0ee9d839ae158316accf7c2617f91bacaedc5fc9caedf6064a1e74c1d6d89922ee17b4f7216e513637442be531f1c4047203cebffa566c076727d28c5781b319368a82206022dd124a9a744594a4f7d3629983449f5b310524159107b906971d997a8e58901445159bfc2a02fa522b869b2bc4cd5f61adb96796846ee18427462c61e6ce14ce9363192d45ae6fbd8ab006307f12c61371db905531a0401de3591f4b8c2c9add739423675c650cf1560ff414c60a4ae2cea1cf1ca317cbc4b13db3ec489721b4d8cc371484871361d4e6547f8cce31913e85897cc3ff649fc71b013c978dad3a8617379a4d613c3f8031b7865c6448f26f6a5cc60bb68f5b7f154319ef7a8b08a8f505566493f112f88d6b50db51a27314a8dace420e09974d85b3b92606d935940adca360730bb797cd703cf413f81db59797e138c1daf98976d7b1b460ab28d2e92861fa42be37e5a0970ae1ba9cfefc6ea1167b136c6ac006947121b6f8c62ee07bde5f63d73d7fda4593e4226df32d46d3e333b212aa28ed017afc733bf795a1d63952bb48124954df3fb9d0d6317e5fb413fec001d52adaa9f16a4149234104f62dd013eb7e98367d0e4f59ed9c1c9e80d38d1f607e762211ef5df0deab9e011cfad0597d72e95d2d9c8c8ff68d823f3c721a9c929699a025a59f427138a098744f7fb62bb3703261b4cda21002d4e8cf5cc9c43343676edde9b1e340e6e1f192cbfeabf9a9f4c58aaddc045ea60e40109cbf2ad1db560d06712806ba9edcbd35eef7b4063035674f6df0fb2440c844dc8494c03add5fca1bb502288c36892833f281a4266aa38990e4de57ff6f493ca799f3f039ddedfc4d2515957f69a5cd7ff4ea46727e4c20a3d334c5372f211a1c55c0297bd16160bc1d049f35c58be82829b8ba4a5bb3beeb60a37f88fc5fa3e092bf56b6cbdb6fd953ecf9d5629503d4d3887daf330c950784e3634b31bde2d69c056ae37a90a5b0245adee36d866a4e1fd7528138d950f078bf2739d35bd3527a7a7ed9d85791180488541c579719d6a8ebf77614169b19b12526bdb07a0ff9ac78db46ba8b823b9aedd7b86d8b256cc18ee1193a3e5b3c77ed59715f65886c07702b5e7c941c1b173c9d0edc1dd98d7aa279afb64c9730ca7fc52a9f8f9613699febabd82127cbd36067efa4f373fa46306ca82ce6809435947aa584718dcc82143132729ae05a005f9e92768529503261fe66255466257c347170691ee9518c822231124394b7ada35b54d78ce452b18f42cfc3630df2bf64154374f2b7bd1f0f46314993593f18a8c4963dd3815d2633e6b0f2809790d0390b1e20718450e8616ed6de1a21a04bd5849cb11d47919e0bca7dfd2c3d88f96d5301fc1928e18ebfc5430632a8b1e8abe42fb465f4f4292a1585511b2db262b3169e23f656a7e761a91ddae77b058f6bab6e3d55562f76a34545f60c0a03b01c759b0cb9ab7ff5cd6e0d5b1cee8afc294f491da43e00f8752a1b566358f05bfd5bc455b78f988f11d71ca1cfa648b0f0a921d05b76dfb65cc45fd94e2fceddf25ef625778f77e09588284e308de0928aae5e88a8bdb5fd08aeed1d3bb6c0ca4bf43e530dcb81e53c03575684f1360043ee869cb236d29c7582be9417523c744a977bf2163ee54b6032af876e9079d37fa7e6b819d16f4e6ea8c7dc11f85d8f35aa6e45e8efa436ee1dca15bad11a33ebf31baaf48986098ffb49412b15c8e0577fdc66d6a4cb1708b05d78e15033dd8e36ad15838cdb2a30b6d42ba45a48b76ad6017a2f315b8a8160bd36bf11b2f6913d36243315dd4efc31b141621c363c3508d5fa05a604358826c9187d8b53b2cbe7c22027234aad2de107194f8f19efccbfed8cc594424c0ccb5e8e753d5221ca834c80c63a93061a08673c691be365d98f438cd071263f0767c5e475f6a55461ba8fbce642b3cedf2c0209c0db400f64a356e6674d9d0ae2822015b146158be73dc86491c6944d1b473c78c46e99f309c5df35a7508dd17495de790b6c7205382604f559a76c6011129deec8997daeb56c7aa9e906455390c599f4aa3d8b2f7f59175aafa2aab23b101817628069c467bf755fe4b85371f080c3a79ac54f33a8f1771c0b5d8eb75b849093918fc3dc9ced91d6689819e1a019ebd790639f9fbe2a27ec480ba5f878e97b76a0609ab868c6e3b0bed96dcdc01fa3fbc8c038bb24de32fadff1810ead09303ee71cdc53b48f7011005cf0fa4e2efc1c668aff82f453633ffefc6c61e2fcffad9b3d3464eb4c7b400ec379394cbf19475810d628625aba1d94df9a5bc2a2c9dfe50ee0433577fad5312e4682368e8df20d78e533cd0c2b5e35ca4dccc1de275b511e71000b2a37a6d27c08df4435d810afb6e0c26700e77e1653c30e326224c6dbbc5089a8f2492a196479e486a94b7669c019e444f6f3b147297bcd7e53c4aba83d95a7cc3046443ef02b067b4e345fc4d8e4097b0f2fba9c620eb8d601c4a97fee7f3adba4438911b1ada331614c12a2389562f9b39d6169418d9e1c0120b9b4e468b110c5a43d1063a9010dcbaed78e9b24f192e761e86f00fa1fa6cc9dc3b9882ca96e888a67395604e9ce0b396ad1c987a4dbd86217c653b8cc76ead3b3537040b4d3768f690700653b03411c49c482ba3f22b50a2a1b942a04ae6e02158187291457f87a7a760c7c6d4a90a2b5970dcb10ca30a2ccdcab8ad13dda8a0be93610d099838fb1aed8709b9abae2b0e730ef4d87decf911e540c386a42c38d25516f94709db399a3b5c5117fd24607da9cc3ab513a7825eeb694981bce9ca05ebdb74ce1521773c41fb84f52aed926dab3df6908c9037a0c261bd82a1dd685a680db12c02cec10f94f34e5503c5d920d5b454943bc171d85a46e5070aa07cd707efb9c5ce2f1c66f2279399c71b7d20c53921935fd857ed95c832ad56f9880ca1af67f73c30623c215a36ce242cfab0b1ea7e0be3d9e4575d74cb9dfbaeeb34459cef63c21e5f638fa42109b0c91e01f7cf785ec4104dca4a544bb1fe87c50e998a8c8c6f0b71148e60311e47daf7b4d18235acbaafb9c7b816865293202713cada7946a780c9766833660b2440c6469ecdef3b364d5c95719f7097500e5adc9a6fbcaa74c5df0db802555f0046e1f56137a905077243472094c4e80358a470d5109ec25084de39fb64100de4a345e81efe7e0085792289c4943d6d5f8e5127c0ebf171c2a7c8d926ba48e942037562c226c8db32bcd772a4b234dec147d01de59807e2c6b7bfc06db009ed84be82a1561686448fccf144d4e0d6fdf51624f514687e25690cf5586b2e8650d5f15fa19a1be8d25dbdc59750197a51a937c5b1bcd8f0e42839ab9f1828ab47ea4ee98eca126c0b60ad40136004b12074d247d90f2aff60593ab91863e90f25cb0285087b06233bfc3e7b473d740eaaa5bbd42c3d18251292b4baa9827b26d21bc554a460ecb7b77deabf05e6277d2d19056aacfff851142ef2aa9f1359f584e6f63701692f04ed1bcb250656c88be071dfad50a1f013ea9ad187c3b6d917c99e20aab4cafa583d2ec2dfac1a5488efc925c351eb03c32d0050fa779f4e71b9db9e037d0eeeef2c594bfd063f993aeb4342d96798735fa85406d5ee21b76ec724f4f33a95d71c22497342d7c70f96d25456275c7af2fc103d42b5dcd61ee8acd76055ba789c52888d342f437646bc584930f31062e788824b2b5a9365d028ff67dd1a3bdc5ecbd585eb4238f18059025b74f0c9371cfb753a5be9b6eb2b2b405dc31c405fe54e68f64f491c4decba5fbc442eecd31abea991151a36528497ee26fc10ce51bdb2100d51a844567445b5c8beae26b8c98264b09b4b7002597115ad1173d1de877336f63175da694c4c67db29f89aeea60062b829f97139195587c99955344b9d4b63206c44adb1f0206303a4c9fdd99d66c0971d48846012defe672bf47fb747cd3abbdbcbd7ac58444210de8d9e559a0fd9bd12a7bb3146de4a8e633f39bd37adaa8191c4d57502a70d850808802ba10140388ab336034ef112e0bec8f5afc1cc5e4b325a6222426074f6442e3b0c44a970e39a10f0916db230cd6c58e5e5995f42c09721d908bf208c6535636d30606d2ab83a1c00f5cd0c72100de32ac4e3e8bf4d2eb95365ee0a0ca8da6bcad5d2568bc2db593f1a17851ed8e5d0d0c1b490641dde3f885a9de65b4c6801a673a34003d1cfcd6ddf180889f2c59982c68efab2fefaec723429a5cc3c14cef8488c45a098628df95f4467d3244bb0c8451e94b4db1a76db990f9ec85668a9215cf2c0d2969270c636e3bded480239934033d543b0fdb3fb78bd9d08aadab07a85c61392b590beeaeb3708bb0704920b4b7ba65373e47661c9d3d13cb9749dadd3ee27208ba8a2dbbd9807efdd59b73c6133700eb30b3b6a042b1e35b55c30a590385eebffa9aa4b65773ecc5b87a02ef561503b4a29ea354c603193907f651a699faa31131c65340e36b5e232dcd75cbc93dafe365af7f3bbfe052b83ac9434498566b94c07c65b58fa5bea4dde3b302654f47c62ef73c8e5e73ace6b37ea464fd6703105d89f4062ee8b0cf98c1498eba44c1f0fe3ff07d501ad1f4edd6be1e974af8acb6b5adf21017299688b0bcf9f19013f8b3884b8a749a5522c6f2725c194030b612d93628e15e3ad5e9a97df0d40d1480238760f0c406dab4cbda68a4ff2c70858d8ff6ec09f5b87c8a707997b2badbc9e967a5b04608ede3dda450c220dda05517eef0a256c871d2096d39e5abfe6eda2e1189fc58eb8fcee99ae4c2638bf0234a8c92b0a4ed65c230c52ed379b2a40bc2b8897c43d8ca55ea9afd62df9cd601d256d407a6a664308ca8466085d966607ce492468cf094496b9cdc2e03a214304e75f96c976b7699098e4ddacda6f181ae880a38c6f2be7eafc4a2629d13012efcfa7efd5eb3ed99f9325a3c527ace28eea2690fdfe5c6ed5bfabc3fc265ea97b6205caae34345b24c35d45ccf1b11943cfe41b9c5962956a1e860a4fb0ef205b25a2edff1ecd8f50da55bf5cc851a54147d486a465016d9278330094a4a2cecea303e7cc75a308b164fc177767ade23f2caf003aa63868eadb0a58ee3b521ab0a848f38edd2a45326ac9a58fda461904e489646b89dc64112bab0da841bbe1945d8107587746edcab56b8b5d570c142d285275ef7066d5990996a6cf46160ad192369085c756ef4ea4ed3f0ec500c9a9a433ee90cee56399ee13b05f3513abef8c831e33d009f4b7fe7a78f31ee014e9aefc51b52e69db66a5257e8ea5cd48849c168649c0c0dc01dfddef50c56f23e56e10b1262c669eb4d59ca0b85086523cdd22c123c71ab0b9f7d5a0527fa05058b480d4be26407f948c2beecabcebe074ea598047d4b57194b812105a7ebe327fdaa81a5d7ab50a01663fe1155018d2a1884dba5f96eaedfa8e756113284d7041c7bc009eee8bdc09b84ff28451ebd2262f4c38d1e2085305de0b11aedc487d94c5b98768bff2df96c1104c80e1170581c8ce120bb2dc20c1b2e627f470407a77943bef1fdf9039dc51eb302d95c0689a6d1f085213a02c046b00f1ba549f8505113dbff90a4ee1d58b45c8b14bc3ae0d65bf787434291693e8608510dd11a5a08c833589541ec61f61d66e0b6995799ba7e8c5664dd522b51d0fc91032b4be9998a5a630024d42b6ab0950be23c65bfc03f535d80f00c11cedbeca7e796fdc6b18ca30374333f25724c86abc40bc0905aaf401cd0b0c7ec35968b4ca6428c7503ed59654feaefb4e9cc19762dffe6512db0148008e16bcd695aabd222383c7268484e3cba4ed2f211dac5dcd30f7995026badb908260b4a552a6b8678d663c592924f8d0c6a74e600827dd85834d35a3ca35a9049306399be9b46d07d8ba2ce8892b0daca679c870d71bd451cd940b3acc66faaf56297065c704af070fa6f28b3ab13bc563c820b5737a18fc45e06b18c77b0eeea688f47258018557c9ef1723dc2e047746af47ec7c171ad8c585fc7789b99cef21714199e3156d9e139a367532c192bdb42cd44764a69b32c1ece2b452c5b736d3236ed2f60c35da207314a7b4afedf289140f99d25973793874d5d109874f6f4942ef7d372928c6709368d61b46d48d2255e3925e20c066c97bcc1da72ce2f6c1e84a8cf6e9d6be3e2c70e1dd9c397ef14806124414591abe596d46d4efeb9c447a8898927b27e59132bac9295b57111d04c81d235ee4471dbc1225bac788a1c35ac1d73810f13747a45c8216f50c848e8887fe4702c33a722a3b7cbbd706f06d6a555df49538869b0023468cbe381477b9c89a626788437f0b6575f254056592b8751ec0b91ad204a7676878408b764866511fbbbf84a503e173af1522041ee03d6faf7275caaf5756c45db71b6b70a15270f7dd0042cd25df773582eb6fc5ce3dc652f4518be00018126521b8a64017892d6a00b6075e10db988a932512565104d6c136a052c64d97bddd68659c822a10a2a22bf2caa8541506aa060912be891e94b70ed147ab0dd0016060a474ecf76cb1446d42df716aa8732530f55aa8d9c1e8b5e5b1a213283c231d3d800e96c03fdae060a82953f46069ba9ffe4226a55842a35ce9efcceb1e5f4dc437c2a9e8082719c04d412f21073dd4a4ea04d6391b51aa4670750e55827d725dd328fd7e884afc173c76280fc3679e1b8fe88c314309a009083be26ecb14c0e54d4487a9b7a96ef22da0778aab0120496d361eb64fa48a97d551aa12054f23df293463ccf4c1bd3efa82e536ed92ff8b30a3da4b1707fcad78eb857b785a956fda678bb50ca803ee726b0aa97564ac9bdf066b6413bbc4cc127ba3bd1b7425db7c985937e91f9d210f87c8c8b647f051db608f1ea470560f5261b0f84f1de929cdf8381e59fa826d05a2d156df549b100c4872f817df7b608b5b343497b7a68d820ca11009a2929c2b70eeb2c4f9890d39c873b68fd13a6796cd2cca1f0c6874b8079d18871b9963074646b4d76a2fe9848d3f3e7e7668dd2b5395b7faae279959fb4adf477526bfa56034566f2f510741509e415349b41bd070e4770e679fac85a29b2c787e06b7e45f7f6174bed80f07ae8fe41257c6230fa495b90901c4031b0d989c07c322eef8d43a771b1846d75cd573788be4b4d491794bfa7262a5b4a8cedd5499aa65868bdcfba7ea2f4c6b34d2e77481637f0baafe44efc5d31a272d29cf90efff6eec23cc7d189afe45026f7a0fe047bafd8622bb557c590ac76c0e8aa4bd863da00ba42005a74cfe754d8543c44ae46277b51baafa29100c483cd44c594a7f00bef94398e67aa65dbdd5520fc0eb83815586b5dbff5230c9dfe35ffca109bb8f335867f2d9f9d491853467adc153d811a5f431dca841160c76e17ca2c88ad8f9ca9f02a06acd6c88e9a5fb40b2d8e33a7529507fe2dd0e8c30d909b6d1a2b22aa82d0a323a168198d545dc6c422c82b7276f3c2521ea281469840db1ee3a1334f33a982f0473ecb0018c870fa01a28fb76b8b4f38dd6eb9e9213418b7720d605e3649281701cfcbb646a4ceff6b277b78c23b20e7d7553eb488a37aaee0526c3d0380e61db5619cfd8d615ae2517af06a2796c1debf090b2a593e59f5d18fa398d5181f8005d8b822bb8ea2df28132c36adf85923cfe207b47c7b63f069854472026f31c6aa1e0de64c35530de4f331287fe5760ea5942e235029f7f57b77c1383cdce85e8dbeb63cbc4a394b3370c37bcd2d4c4e9d64c3b4598615a0d32370ab3932d2b7dea2c5c6bb88a82479c6b4432cb0eb18a63f53fae6fbe817a37c2c103aee76d5d72f253db7352f8e3a50d6b94113b85835549a09b565e4e14172bf2abdd5c0eed0d2a1f75313deecf75c9d0668aab92a97cd31b9791612eaf0b5b3e52488ba9c1ed70fa42cb597a531380d9aa1a62673fabce1743f264f00e8fbcbf8cb41536d35b6ecbee2591f42602db46dc87afff6096bff6ad0448ac4141bb73621b186cf9f61ab9d31642965c4abfa0b24ac1d74c3e71b6a75bc6747da6a8e36d574a261560b71dec7f151a868af41a9eb6b13fd0909f90a57c3d7999b1bf288a1e400fc28208ac7ae9b06c779b2e367a54665ea9594a79bcae83858b46da1584629a67e19f582a0749ad652fbe3212e400003c09416120223519c6d7f133acb59c2d0082fae284e65a26a0e213606e2c8bf700a49f5257fa12f51f82a907111869958b3aa4b294c759ddc24c8cf8d2b4aa8feeb3f548350a1a6ede0857842fc8b153f3cbafb2bc12f2e3c7492353ae34595b6edc240f184008eef341dcf409586a6ab7b03232c5360108e5ce295f54c3a2e29dcec1d4a7012b6dce13792f2d4f4ee76fca4ccfe245a4f30d1d44b97a4a02f4d8c0a95eb1293d6ca26f62af71098c67cc5bf5f2da6169d469746620f23184f80490e06f73428cbd2a34c186b002b49689ce4712210d7e7b2f1c74124c3f06fda20194bdaa7fc91a51b297e3431d847240e7d505b5775af863450c0f4d8a299b9c642262ae1311aba69aec25c0f7e26bcdac67a93ff35d96a823be10a6e4c5bd12d12073610afef0da2fc1b1e2bc92088a7d8c002b46ebcca27b914d078b7c362088f431e22445b1457a32968ba98e7d21ecfbf444645d937ad35d1cc4c21abcc9f769ab66b90d9e6182d023b9ed4fc8676a292c719429d39d5718395a89f8ee2d5f04bfe66d23d2c7d1638e3d577cb61dbd0188dc35ff00c2926e14a5af48509c3b91006bcbcae41755094b0775f92920de94b6576e0e7e1641cdb5e6a03002f2ab3164826a2efc0c1e5d4a436595ca1cea84a0b6150c4889cc52401e818b282c7885accb3a17dab324a851bd5720dc7a380fb20e4759d3ead6144026ac7493b3b6335f91af86bd4d7d6a7b8bd6a5c7bd92308a5f4316c8fbb8a8eecc1f0701126a5a789f5a8b33f912c659e006120be70e7408262331d9d4e2203ba64d5e29e7021778c2f56723a17f648f0bd28067b79c17c7f85806a8f165b4fc738f80d6f8127aa9bc77062451df6b1c2268c5788a908e6029b211d2c92d185812a5eb7bda7f8dda7c33ac905ae0d752fb0e7b86aef886c10bb87cb14fdfbe72863bb1e13aadd3af191469dde7a4bf98eafb6c0779b5eeafb07ae9bacd03f7765c4e114cf97216245db9c62bfaf176d2811cc55f967a16406f9b78e5fc849b79f454001dfc7a44da93b6585d2af2ddcd2660a71e8bc5cdefecc9217fe330dca2ae0765f33e57942611aafd0cd8b4b11f554a1523ab30e9bbccb17a8a7247324fe9972e0e729dc441167a041598f89ac1824079116c13d01cbcb0f0a9fc5e7b3c73fd04d4eba345f7d04ac34af9829ea97c9e2b06afc8ccf5378d8c2a41a67a6725708b74509f381af0c7ba709b1b42ef044c1831bee35c18166b5c87136bbae04c80fa822a364dd4ebfa5663623d511805a71382cd9788385073d660e0a6e4a44b97df1c584c8ec990e57120e9764562f68e22b86cc9f1c4d0e4b364ef6ad0263403e526cbc9e1fcd74e0958cf2a4c81c4ad40aaea4dbb0c31920f130e4a38b30b7e8c0b6dc5602089dfc701257ab3340d776a879f25e25220e4c9270ed0787c51ab25ed747e064d3e79f6d6a03cf3f4b22cc93da3371488b9ae0928c7d21a9acab2a807c8562f65b60dacc40b127bd7ce1812638a112a0369f6c40ae318d07fe1cb56e13a30337df238815e6917bae0b5faeb0e9824855e52100c7cc6fbe4736e9e4ee63877433a2980b5c3416bca3479aa1ad9fa174b950ba5edc747e46d5cd12019c31e44d3e79f40d6d223fb79d62c3d85036d0d79bda7225adb2d0b87a725c9bca078521f212563cbb80b11442a7736445275e6e19e11bf13d0cca3bd4fe3d42b95e26d85fdcda0a6dd0361332401a18bd40fbf7470e29ce13506aa7bd468228d283ea580014a21332573575b27004ce8f23543f871bd076d7128a57414712c233f195a0d3e52d7f8d06b272fa9280c3a82d7b2acb5a019efc8215a47bcfb3acb687fd551b38eed9383a4204dc65459f5c18692abd9a37e4104ba1ad7aa7fff4a3ae1faca4f5257e071d80628955cc3184552ce5520fea8f7ab807ece5837a0024d0979b4e4c89c2e326bd0ae8de01074a7f2f6ed6e8df8623a5a317842f7dc6423bb7bc93f522709d13a9ae6614a6f903672219c79cad0ee9a28f3ebe925fd62021d01cd4590fb148e102588acf2dc74e7043a237802e24f9620250cb63ea3f236d3698287058ac8873309e794f6ef9e2c3cd5bcc0faadafafdbb61469fbf6c7ca15e7d0beb252c5b6f4be7c4356aee17c7acad4652eea248bb0d32462aa38c0a416ddd66de6547148ebeff587c0f32ad0d9acfca26a753ed65620c19fb88a45c3748b87218250f6ac69119128ce1f7868ab2b2bc7a520f64625324e7773675c75c5f580944599688fc67a7113c13b19fd3036dfe243934b5648d6533e9ac9d581f0c73a178d04408c4e66aacbbcaa5acb198dddf98af04294959db1c425d0044a0090eae0aabe03c24a229260bb9b69493e014f6eb87b2e29b6b67b98ae26e741efa31d5d69160446abfd04233b3efffe065f81b9a5a6e6690564a16f1054d068deca781013b9bc5d0ebd92366ac28d941ddc596933023c29fd07cb7dcd18c78d502b3d2886fd20a5273c58d847a5c40fe0c3cc8e180e14019207a65d23fc9b15d0ebb13b84bcad24f8dc6af3a71983ff8817a670dfed10ea0b806d1e57312720826057652bf1bf607c4caab9e6fbef81a57a06301edd40f8eb40d73147725b369c476c52baec0cb14897122168bfdf23decd2550814377510aa5028b53ebc2fa6c9fff44f27ba15e39698f2da024d8a2bbfb39a497445c5aad6f1dafec0135f0171c324da65d98ac73ce298acd14ad7071cd0b64809128f818b0a735b2df3655c98d3991bda53a5b1cf285713a4040fee44fe9b2ccf38afbb84ec06807099b71429e45bd3b690d0bbbb50d2deceff2568e91b7c17a05ed96f19150544faf8dc8e1e6d9ce223fea94bcad43d59111732f97c2701308c53a7f744b5d03906b06cf99d652727c69dc68ee870fb9ff3b9fb9773922d7484ec1e972a17458c7e5a15eb78ec31ab0be5d8571c886d2fd21f6508706084b864a478ba10f351c44143bd8eeee4bcb3ebd2fd963868e8e194120b06aa01e1b7a0b98585c0226851089ffb671eeef4ad983cdb5adcf4b7bdd0e5b734e725f0344cc832a42e98a3f83ba972845c33a6a328631e366c27cb890200de2d3234c99b33bbdfd172a4cf84fd2f4346e33c912d74b5884e6255cc7edebfcb46d72d0342e605ee99e8341c0a73273886621da08202a8814cae265eb6a05a80a95360595029843a33e6555620e9482d3fcd33d54963264bc77f94cac9ed1acb63e3820d0e60711cfba9b42181b6165f429faed689e4b6e761efcbf6e0706f9ce3dfab3e31c258eb8cfc5c833794abb3409217f049a76a2cb787b32e36e0a309acd47481909ca5dd04ee1021d7353191505831943b91f35744246414fae974917640bfc6ae4d27db7133efaa3b702266a8205b167308c3c8e8c918d7df6333e157c0abaf41a97e22797dc35efd2344ccdfadc9fca3a1f1256ebd62cc634fcc174656de613264f2e17f14a3bffbac9f2827f242320d30ca4640f34ccc5d63034a1f0694706da791aac2b48ef35b5ed70420a3d99b0bc042d0f837bcbf223efada1492a18901ff957e2bb2f7698a0a6fdda2298ff98df2b9a60e78ccc179269a74e1619d4e3ab094f5423cef7500bd03c407e54b7e544835f691aa2af7770ffe9b9255a2aa1fb3acbaa18aa1966bc119cd6000b402be5575b7ac9cadcebc549b38fb41ceca76682dd77f4978401b14dd2d8003a59946383482a41066177ab81c82198c10791ab88123b8afed1f627728c193d3d28648bd50db9236513ed5923fb7a6fbc03538d1595465c8e29157c4003c4112b12956d8be9733b608a52dbea8bc72a8563be618b71a1153afb19315c39b381302f2d466c52bb0a81665d4c1355302c5730a8eddc365465d4492ec4d134c821613d657e80701b0179c6d3fc055f84bcadb4797c6c45cef04db9b8306a06b68226a859493c29d4c346a6e81527a12ab5b0d71af10d400e6240daa7e66d7e153dce1d87bd03bd9d06ef94b29be3cf5fae79a07e01e284ed95f4954b40eb022de297cb658ba4e5bbb5b95fcc5df451ee01c28a9cd92ad83101ea390c414953dc14f3d323344e3a3bade9c53aca62aa4d46c6e9a8fcf2aca825c90868d4421a492deb2fc95beac8163c18489a26ea134cbf04c0fdad8d13edbc9558a3c59c2ff25093008a8d5956ed0dfa447913d78ed657f6553b5be07b55bd419aadff75e4a899f28fea15b4490c265944d177c8dd7567197100eb6679045ed6dd7b2f1ea4f6112a9a890c56f3733f9ac1dee531b516afe63ba0407de80b67cea4f79e8b82ce6345d7005b45c67abf169e5120128edfdc95f47d9aafe30e2276cbab95dfb02ec574a23e6528c18e2238919749c946aec2337b3368334b634495cd89a0e62781f638afe3912942e4fea621bd5b37384c7cbabb72b8867368d32431faacd19f804469f5baf2fb2e1f0b77c398c52335d4c9bde751eacd8303beb17efb1be6da669709e3dd57b422186beeb24592c8491ad8e21cb7c9294a9939047c678d993f2a79906f69b3518eb58a838e4397ac200c926750ef130241f3ee3b318f03e1878a355a794b295d4d416c47aa64880d643ab7401321613af2b2fe441c99882a900766415813e5478b4c53aac2cda9f07fdabcda6f0d4d5c2315fcbb03ceead79899d6ec300656f1d957465eb7b1d157a5146b9d7227bab394fc72f8da03f9ff4e01b2f26309ff2034bdef47a9198e39e6696f2a2dbd34abcfd739a7a4c2fe798e1c90209eb9e8d4e621623d4f450b8db1336ba891e69b9a312962b664d425c8dcbd93f2bb65617f5054f8e53480927e41d10270f52392a0d9e0f8526196ef99879d3d933a8e3d1a05c26ab26866c5815800ebd5d2903fbaf5d71b01b7060fca9facc2c676d24a9a5b27c3e7d19e54ff7f2f934ceef1f8458d2539a1698cf18feda9bf32c701e1d1485005a158d5dfa2d2f501edbba5cb0c1622d38c97b62d5012829c5fb892e2da84b42a7a2165016992ecd5ca1454dd96cc0bc40adbae0dcd6b6f4d622122efdc3410860ce3997d61ea1ad4b316202d7a22451e21215f1995b30d7bb96e62d131d0f2f9178696dcba8e3c282db36bedbb1b61223b0a43a4a9bffb432f9b7211f75433a825c7b95a0b194b37b5bd448b920ca2e6d02aea2f1cadb52c76f451a5271fd884330fe3bdadefe02ca942e83e3a3bb77454b475e636e0a85f9705dd6c4e96406a3f9e18ba9525fb3392aa624434528f2f4499a173e232ff4abb44b9d7eb3ad074bdba427aef023f9e95a77b1a13f05e8e406186d0a90e24f0702d7110654b832ad3ba0403eccc31eb2db14cfac0c2bfd2e1c199eb3133ac8f16ace73008880b86a43c4d80612ab0034634c96783dfe270900d086117dfc00b3034e3cba1f537ef2af4c8d8fb89aa3f379eb2098b0bd17409a38e513893295c074067b823a42d20c36d9a5373a14125c18ccd81e04877b20d0581af8a597419e2f307dbd77bb4fb4d68b6899a6736b9c0066f2c54f7916cbd42629c6f0c0adce1da115a6595fbaed429bf6d14901fd046aaa56b292bcaddc71e3b14af53fe64b4892554ba5d5d272b62d1826f405ad710bc44cf2e06c28ba1d280a683916c068b4a00c25a7bd2e92ca3e768b2a65718701bde735ffba15376cccce02e32302bba3db3e8d07e87bb5b3c39d4a7d345be96a657c88abe5e19d1bcc45446e34cf63dec3542e4e071a1720efe68c22f992d9a89358c3552498f9788d04ec4d52ec53142fcdcaf2da036fe526d75193f93f20e972e1767322dc2dca386ebb83cb4b6d21c102bc4d791c7470e3d01788fdc389a4278cc48a19b9be81b8916c8971f08887921766c93330a668450a548094fe794cd6e4baa0df42c87e91005ef91804026ca9eb78bd2089cf8fc0c2ec123cbea23c473d52eaded52a1fe325092638e01a7a7fc9b170fb444d84d502c5aced1fffc39b496c499e61a8b72d8b8907d9d30074867fa68cba8055122f6dd379ad80e39b758dab863be05204932866c4e59756525ce3cf63c8010f22f693ae58b0c10fab072be77ad1391c3976d2b3570ae55dd1ca00e7816caea2ca2ffca1366a5d17389bd76719ee770250c461a5d3dc41c379260f97cef61d24a8fc1a3c869449947b57c944a9a35986b42beadf69ad44903bc6076ae3d6ff430452b94baf749ed4e112783acaa157149ea4c5213ed40e9abbe290bf4e517e6987dcffb1cb5b882299a2b1b5ba6cdfd33446ec71343c4372c63399cd82fa3abe61a9174768b830b94304e6acbda2e19352e276bbc033c7c82b672ced0664c4c067bde2469acf7c3762c78afcea8b7db7b7291dd650702f996596436de1a05c447844a09d6017a8c7308a001f977f93bdd41b527ad5e212e48517aa8f9ae738f4364b73b69575eef1b35bede8671c144519c796022683112e5018f4b710f1d4aea018a00fa48b54266fdc0cdd148ecd33928bc7141449505d3163e0856a5c90fc11a653e0d864dc85b222a5645fd30388c28d316bcc4d46e1dae20959cc9fe06ac889a008143799bef62afe0d40f1a9b63deb192aab93027c962c5417b5470704d9234a1f4359ba7be61c7f839e98b718c8a80d08349c9c5bc65cfb228b1fbf434586ef8c082743126ae300f080aed77f9caa3c624374a175b37037e5b2ff08b76247341bade58542f2ea9071e0510e90bbd407e696ad6b8be62023ebf324566ce2ef3b6764c8bc401b0c0e3ba7935738edd63a44793944fdc42816c978be627cfb3033785e72153a29404719042630849dff077eda11e8645e7ae50a4db99d95cd0dcf71a28c68e70a3620732f08bb6db4a2b0a8218ebea9f52b0c17461f17c1408aa4c68069142035497131f65f49c4362ef74fe9467f8a1c94eeb7e64476427da7af14f6f8483fefc87cf7b563a5d3a7145fe64d49d713fac17f8dc2141fa658e8762d4075e505ea4842d5c567fd17e745e91891a7cf03f058a86605017106272b892d15fa3cd3b825b52388e0cb33ce67fbcc5f4d88bc685d92d8c112c543794427bc76d895b6e8b8804882b00c34ba7c94fb0763b8aaf80c8f2f86d375b9d995b3ebc93c56ea985b0f43c3049555de1b29b0de7fe07618a86f278086fabc7f85dcf2040014ff65e66a4cfd19f780c075f2937b655ae9d88af9993e9ab09e27d1196992a1bdcf99f2647785b14e7fadc22015506d5669bd69a19814204049489f5d06f4085a23cd01542115b8cc379b088088c66d28c94803024083d53bab239e4c9d0a2e285239c29691a1205441ab010f13db33314f4d4e9692734894e4dd9fa1779dfd0a947d4c2217d38204d67984ab0a67c79cef959f33c6a7fffbd52b5bd1bd2676f8aeeb96588a08a638559e750d797d42d43147eba47cdb701f1c543cf4e789007260ad0579c2945b943a8a919d3f2504372c94eeced14cebeecbe96a4e9eb6b7dd8bb516a443a83e356df7019e175bf374182c2549612b2b9c18feb1d9c3fc1936f0b9da370536422f520e13577219c40368b7861f2aa8309b389468ae3e1480195a8feb233ff9eb70fe02f1f3eb6ce57463a6eb1d931e98ea3df574be0f21f6a8bf239b38285c2f0468de05bd93e043957d2a3bd8153d41f649f6b2a956301094cf2abe4955a45c6d2a05173c222c7d1598f31f80865e0b3dfb63fc6ab4346af4a347420a2a040a827a8483f7bce8f62a9ede045e0632be4644786316a6de7c975757b0856ac6e56022c20bae20c08845803f5340f1646782ef4d866ee3fea917cf0a5566b565d746ba4072f6934084af0c4bf10512bb2ef46f61b6f8c6bd6c0308bf8e072b0063453d601e45e6005907c264b03d7666794cacb048ff4b8d4af76b952dbe222add73260c107f58c1e663be9eaa9e3498ceaae1d458b525f72b73b40717cf654ee0161905e0609eac354c9a0b331668887aa474ecfe24011fb57b8079c1ce568b6efb093f0d1a9ed18c681f213d0094ae3ca57315f73ef24b145b7156b4350b7d6149924eb2102e25a832048cd9b92083b5882f89bdb3537a568b48d2cf94268ccb2ebbcc5a38855d236675e99164f5cf1e06b5dc38a0a0c41579f6e187f722e39c93e25529e873744d1bb1282414bc8503b529b398cd2775b183fd69235f23d6c24665e17c46738a4fa34b2987ffbbcf34447bec131337bfe9a66fe99899e31de14f42f2ef03ea878628c26a32f19adf329ae69303414315acf2e136c4f2e9d0ab2a10029123b53c818b193ba836f5d75f2f1c6e1bc5b12ef88488c47b1b17ece56a6c3bc08637d24c565a9777495c69e9adac13d56dfa4674658fb7609779b8628672296fdae25a95384842eb764a7019c3e688dec99d477a60c7ec4a831c36780e16e3490f7ac861618caa36f40c0f6341fd98f7866fc1ff970c2590a21ae1a2ac8826e65826fde93f9b662427f8b1ddcff4a13d9ad493f0a9a07d544130632594663ef2766d9a7c8c724b0ea79e64808c26ee7c73d11fe2138208763cb80809226bfea262128dcc5dd1f95327c9309d175c075aa8652375b27730a8a388bfe13a7cad181cbcbd249ad1ffffb7e1cb886b6da2f4c73c62943974577bcbef54f6192663afb30e25c10c7ab8af1024ba13fae5e52cb1cafdad3209335756d6c1b03c5f7a83f00080ca10f8416469759a92afeb9315e723f5268ca9672256a41de2cfdb13ee229fe8f063996b0db790e7729014584f255ac2ca5134d5bd3ddba8c42cb3252e803c863fecf4d04eb5edff2a31936186522fbeadd5385d5ea303d04baa82a425431e8d7841762cf0250bb66dda1dad9ae5577cef20375ac31b09da1cdd0d25d4378183600855a766dadddf2e49cfc21b9229c04479cd65aa2e33852c9a5a7fbd914a892c2f8a87ea6a991ae71f2a5911bb747e8cf74a4d9fc7d9e9b1150f283b0ce9be749bb50111906f41510384284d50bcd3d6d6bbedd1e8bc92d14e785cd215a59e884e14f8892a5bf496fadfd6fd8f14d5989aeb027c071f442ee3cb8b3698db577f22f42ad5caf0b8f3e654f27b05e8cc1f0ec6ebf874a84abf9c0762f40f9e60a8da8e036ea48f9d49a7beafc6e4907dc9cd7313bd7cfc0e0902f851b43c820fd04b79c3846ee01463cce664b65e1bfcd475635e8b3307b6ce3d4ae13a1a4f86a906de90c5f35ceb4be49ac934d9206a579f6a2c5dee2a4f7ef2780598c1c2a9360bc8f0bc0bfc52d8a50fe5b966a3f8202951aa5ba995739e619a1945bdb25162f2c8fc0cb77f8d4b68f93f3497401f4ce6e7722258e6ec7a8865e97d4fb4990f21e7a13590014fbe9e16e15d3c3f836ae60c48a193ce564a3d3e14ddad814ff2b4265ab1128eee3231b5f92fb4296220ad732279e648bd90c88bc48e14782827937997f2f59a032cde4dfd501f14866ec45da3a89b842f03a66a231a13c9b0069a40e659e3c4d7e9486610a1b6f0d87abd3559ab5ad38c95393ac65c5e2ccbc20cca91511715f786fb04dc7733f48d42623ee4189c5d881e5b04d3c8c899dc04eba122ed28c94d43e9e81e2a36f2681192d502ecc65c2b899031c73fb3c9b5938091692a988245106024f3aa77a9bf480b38535673465e0b29fbbd07558fc245e0af2ce78a2b7b046993b9a5cfa8290c84457806a4de2022603646552615e002b0527589e76d094301004a982036aa1a2fe9b6e704f2f11c84c9b5c50a2015111264fdc911fbf661507364c0d031102a9232f21adf5c2c064aaf20df8659393e5a1c94c82a632f6dfeacb84fb495d094423de58940555c82632c5f0fdf68eb11fb78878611dcd0977ccdb579eb7a5b282d304cc6cbd2c34ce85fa29e9aba0c4da2b85ebbbfc26ce80104cc77da15c5a59a8444778f191518997bb063d164ea6da4ad734ce51c79200ad9c541d540f6dc98a558ba91f5a9c4886ae120f4dfe3a940bdb040e4c0c2a1b89802588aaf15f04b072894006b6f2964e0e6cb85a1ca4a28b047c1f0c5e2f5c09679563051d47f50ff628069357d3c475785cd85a6d46424e2243dc9f2b60dce5916b1c892f172fc50467085742f35e62edca45cea189f390a5968ce9748cd85d77ec1c552d93786b364b84bd12ef0bc68aa3c60c4f25c75a906086ff876a5abda8d4d9376abf820f6d313727c102d5d7b8a3d5e8116377ce11f0562642b0884850ffdd791c9c2da39ef95d10bb3741fef5cb32a8029d5714962a8c1a4158a9d75341871583a3c46106c5f9576a64bb7352bd6cfa19869a1839645f515bdc7b890f30e7ad4df472b1f9b4531775c1ad4fd8bc7f5d3c3e12096259981f42d3293cf90b9824cbd6034d12135d285fa01403ca1cf80d9d1fd99fe16587efd5a5924e757588ab2f27e16a45a6c4b30f459f40cb60621953c94766d618c03af9f5cec3475f13e03d9515069eac8c071cefafec06fea1b24019ebc91b77a669f7a30bca91cb462619477093b26cf8d24ab7a477a2f2910d4e23e519c85e72ee57e776697164288e24583aaa3a5b500fea04ead37880a851f00f26b0bd475171c2d2ca0b6eaaf875d0d8f6f788f47bca15b018cfbabb8b46584c9f2a7912598363728c0d2d85b8eb3baa15d41c6a6f7a40760620d8047c3a3770a7b706e44b2e55a2e9f444d9d7c089ad80767beef4c605e348c38eb6ef9172d5f6c1bb44b085d2660b955ce7e8911e314497067b7db6bb0f9004d9a4245301a991f6f975f7ddbe56ca6e8d21a1102917d9c9dd7062ee297bbbda69f5e4def7cbe9ce6c30179fb39f9306f32f160626dbefc9e2731b4989bb7fb09286e61b1367a35ae9333cd392e14a7547b73e7b2bab490b465e5de0b3b8a65eebad9bfd7a4a38880b4acee80037d9f2e8fbdae6695e37e7421db5ee81e50691f3675be2cb11fd3109765eef00ec1259d5ef761dfcf39407f19b19fde63a6bf6f926603106796286625b91774c4cc5329cb42032e6cf1183e71fe6296500988c4f48cdb917b09e4c199d5f52168909555871db8ee373bf231383b0f4bdfcdb46aa3bfc92764bd8359f88bf2d9ac20c237f708a6f744c3dbff7b9c6ebdfa4ef8d9c46d5ebdfcf8d9b51337c5b4d53d324c105c12b3760df5cff02503f17d169e725e9bdfc8457b3dc87c902d802c073977d7c3e142ec947772e094edd4a460292be268736c2b08bc6347a7dc9d05875f1c7751da4720e26e5e67b3a3d612705eb7050c6bc5137d998892e7564ad654b41f8516d8136344bcc920d92490ae3ab7fdecff475ec7420e49b8aa0e424107042ffeb715d555ad855c5d376922f658974142f03055f841147fd306e5b78e61ab90984d796bca18b64381f9aac0c346f8b3cd656aac011ec6a842e8728efd81b4a580ef762318370aa6e47339d0088f3374be0839d70dcd3f05c83aa67449ae125a25df100286f0542d6956ef2c3a8481a9506d9408349b39ee0ca8843f9402c49f2907b72044530ef0d747fb8802d32c06c91b64c0e1893b9ea5b822c8578a0362e990b70a731fcf82646d28901085cc6d957ab24bb72ed34a8f50458283b27e3dcd06d8135d5feaef84e882fa0b09ce92a8c9899381a13cf16b6d5b8cd3c85c4c68028196d9a7bd7317460a3ebf0f852685a215cc9b21a7e95b44ab79bcc83f266297be366825de73044397786f6661595ed4a533f49d601f4ee95de045eb1ed406b3d15aa5b2676099b58f289033f8949a15510f94c0d630703fbaae26eda633dfd5fdff60d6bc581f849bdd1155b7865999c8667c832080a9ce96d1c19a43f06e7013cd091a1d25d54e6c08846f1944a2c7c569e16e8780fb0e65b245f6f7319aa8e6555a83ce31b2c76d90ed0ad7aa6c99076b76e05255890f5128c987d6d39dec60e509f65f446d56f3ac540ce57388587dd2293f34b9f32a93b00c481c010115dfdd81a979c985d94636defa66da4e3c0b52d24011a384c4e6ad2709e9c38e13cf024231bace4fd10434b54cc29b23092346402c4267b965ec189829e587b82b290a660feb2b57c80a7bbb4f88db33540ba6cd824f6bbea25b9ec9097c5a206e05168437e87ed8c11e463f7fdbfe83d63c8cd8063180568a71130d32c4bfc6cd97275f62c3ad7bc6b6c2aae843ead5647c3ae63092e94a39ef911268ba92c5f469ac732f7b29b5ef14d2c821bbc62f6d3abea7044aca3c95390548fb648b36b106463d6004e347012715853ab1c651a18ef35121f5b242d15ff87ef3ee77fdd9d83e61da9d980f502ce3e806aeeb1fba3b28a94e7bb2377c91aa2bbd5fc64fa5eb19f600067e0b12c83104d82fcbd52628e4253ab36f70a13714bb3b10e3d20a32f13d93cd7497fd5ef281496cef057c21177d0d3621e32838715107597d19814b9062c0de4061d80bea6d779e79d5cb852dc51dedea2c9b1a9cf8579757d839d9e7ffffaa9b96cadd9a9ca9aa0d7a46d811fc6f0d59de666eba548eb8c9776d29f5fd6217856c98c3b7158acd798b1969a29ee68a3ecdac8f5b7610b60a213b24d5caefb48c92c883cce05d83001109edce44725c6ba7274944ce915c2b6bfe1bb8a567b3041d7f312869e17c03b0b0f524f8bfd25346be60ebc52fde436bd4ab52e42514e2882aa1d13af965e0881708e4125dce4748a2f8f9b48f85c36d86827226b9dd86f0964b323432851281857523e8b73bdcf5a7bb14f8435f5058e16b318839641cc857106d664d68e2c28914568f59abfd62115ed6dcb708f8886b2c5617141abc7374190f564b79905e81f532355910e76d84c535c510e1e5d808305e0732c43457bed86ac91bbe797e1f1fff46933b148ba8ab0dd6df0fadee7118697254bdfaaa44634a1414282efcd025cf349b56fa340635db718622fedabc080f012f9a961958cc54385e8a147031dcd945f8c3936d8a84990dbb17e13db20465997885d2414f9685f5c2564daad1b3347c38d9770cf0407a5e050ae482437e9ac9e88d36639fe2db46cc4d7ebe16e9d5f759a510d7b199432e7d003c8cfb322734de8f4dcdfa5a2c2463c8076497cadaa499135081fb190450e837bcf192ceb917c62c55284eec8824bd60227865e05f86a17e90171ea9cd690678638e6fb06aa802c23bf598a3dab3866687b719e9bbc26326cdb04acd04262e4281969e068ffde38a8961a4936d3d5508b62e22c5ff9d6f1fa677fc8430c6b8852e9b298a09d61af47a2d065858f7d20b49519d30d6275da1de510d51ca25a721e2952ab9a1f3917c4892c136a6fef22865650f92788c38c22c60abce1de030210ca91bd917904a5e8fdaaca3b095934b7dc40bdcc9e522d098842e77856293a78614ac79bfba414a2b6110214e7b49704af2fe6d36835e9f27efa079cd5ba048c4514233dacfea2854ef179727a05f12b44aa5abefb5a816820bd2a7d1be0798cd3a059c36ff04584a0a42cadb19a060395fb626c86800beab860fe3bf6a26415555eeda93d090d51a51caaa80e0a9ff27f93f1b9980d8b77eff13c0a14f30a6f2ad61ddd0e25ff716c5b141195243a26e853434cc195cd18d27d9f140e1eb8beda3ded0906600cd7f3df35008d26fde4a66b9a4a1421a4fdf66696437b15e3dfbf4aab4bfc4bbdd5fbd1df015144e253f0e8e07741e88f90f9905c3f3f7ceb99b6eb6c80e7af0fc21da08857c195de0c8fcfa2bcfa2f9b3e31599fc0792dc87f2e1594d69962f1c8027f67d447093cfc5221e8c7b8d1db19f3fc343f534f538c9f80c5b2af3f98f80beceb576f66702a4b5d2ffccf4724c1fc6a07a8e56914d90fefc10135a2ad8601f63c5c87edea09b4fb2b4050af90dfde543a4092b0114ef098de3393824a65e836110e6f79ff440b62aadea69b0bbad6a35d788193f02c5d6c8ad97a433d4cd3746ee5c87b39674d71a435820c64fa259199ae9ae4369e87beb15f587421c33311bd2bc534b141f04750671ef2a91108651336d39c35df6ff55909ac66003496b1c4963b12ea191f66b59a480002b1510604570f90d5ea59bf8a4157d0377e2837b5d86b5aa09e02b12129cce74c00e125c25239fb35dff5d89e8e83e3bd701bbc1efa57a80242007e5d4d5275d66442021909f1d8a1daf1fca358ead9c3e7d45d5c64684b63936fcadc692f326e77ba363c4e6426dbeb7581f25d8be97336f0cb0d1cde130d0100fe979faee49fa2043dd4c72d9ad7a48da446a00e50aeffc331b2249e1eb7b496821f3097340509e2639529938b991dba27bbd17ae4a97a3574ebd0d60b0c32e6fb9888c45b12023f5c7e286cd3ad93521973881285c2b9614b2fdb7a7e212c0551f1c5918f50206dd3e0426bd912ca7cbd08d407e7fd531a9dd83e02160f58a8eb0f45a991f21517d79a72a057093f6357eefcb0d6193a0d9e70ed5f7cfd36fc8dee9de9d2f9e76d8617f123b916d72f629133176a57304eafd5c3feb09007a0df1fc5ee62a2991838a2367e1bb4751f46cc5d7373e254933dd802be8a875ff7d7ece68b32873e11e87eae981eaf4788c369a2c52673d9008e0d4fe49374a4765faaf2e287f0d2d7a4f3eecfb2502f0ffd5d1e76547d6d9b85a763e9e659f7b32a194bbf962bfb117e9c5b35b87329265a551b43c3b6e4c3d8d742706a01acb8a3271a2625bdb4460db44aca5a88963e6fc38d6e0e6351ec52e6abe945ce261e749e8adb313ec6468d5a263048b0ac4f1985777acd083eb91ff486af3d98e41e14a64de8a5978385a4f63d121e24dbd6cde4256e1563f8124050c22d0454ce16fdd5010f1afea0309246966c3efa5ef973e16530dd7ba234cb8784d456561668005becf4642d2e6ebc852ddaf441f13cbb1e0d98b32eb88f572c36b50ed78e5dc9c70f70f162d2499a33c7feaff8070d506a836ec2cb0dc885711742cb5acd46c6460dd8442cdce1daf46cfba2403f09c0e08631982004fed6512dbf14bdf6cfbf71ed74a95a755d56175502824cf6473ac6f6ae42c8321f3383baf330452008c091d869dfdfad83973420b0296fee53e4753611b442d7da02d981fd29082c3ab0541b50fbd2fb68e600b23e44e91ff20d4f613e20317483ad582b0ac51c2394e756019a8f03ceaa93adf99c13d68f26c52555b1e67bcbf695efbadccb83a8f48cc66f82b6bc9daba37371322fdaf2c0a46dbe9076a90aadad05574d14c3d1f8b976e5ac7d74a4f2468dd52a9eaedd568703aef6b0d3c6bb8d7dc98c09c6301ab9e53f21785e47744526cac79b2e9ee35dbb1e87a57f7c7faa5bbd22c6223d1bf139bfd7b99b23fdecb3ca6550471c75632ffb1b3db4d7b64c496312b20dbfdcdd331e859c99248462e6571c6ecfeb19939c9b83ff12080948c31dbbb952585cf372aa4ed50f576afd80b98043eb53a11d02752a007b791995dde0d2e584d91b3beea7de58b02ccd68556b744580174e8cb58cc0cf022f31998f94a6a5c3b3f9c72e616763c9f4b79799d96a217d630e1198514d0356d982ab6e083f63ca7a307dd986e1644c8254a8ad0147109484d958d42d3bb4aeffeac6ae7660b16943a3b9c6165aa912f7dec86e4651fd5cbcdadbc0d33ac47c5d3aaaf7638f13878173a170791402ec65deb8cae704f4467c1b0362e9d6cf490b8a3899e88ee279b11a4a24fc82649ddb897c7ae50ad8fbea2a641c8c2b265d1912dbbce16647cfc07a0ae9bdd1e7b88d085756cdfa06d00ec1b75d1ad39c7a6612292eebfe8965dc78803a85fd4cf6edbe722ac7d31106b1183930ba293c750f7140a2871f2281a92aed9fcf1ee45be4556709818cefe3902cbaac82c0e322f842e4e5a2290c101d91e84c7d7b9d309cc5ac85658200057823cab5b5228741b626cff72e616b3182d08474355a5d932cb3567bffbe6d6872420ba3bfd108ea2789ad81ca4c9da11a45747aa1bc577a2f340a18910c2e7cdf8c92b0ba6c9e85fbfbc98c0a9b7e0e9b105364055e216edfc03d911df1bc78af46f39868e307aa4f847b0a0ea336f660399793298421065e6a8f922b4fc1b2028021476d6297113411741ebc04498d4b14bb4f0051f8ada5df289f5a6eaae0ae3ab3cb2351571ea6bdc5a5c761be7c5ea8acb20f09c3cd8190ff911e4cfcf458daa45d6020f88f988b3c98211d4758345d370c47a6c6a2f2828de23a70c4b6baa5fa068dcf27d4a39c097f1f0579b2481f59beb7bf31ed8503027a51ec505ed3436ae4072f4f5217d55bf5052bc53f77fac62231292a3be00b8b0d06250eaf73f39a41c6a5f0ae7cc66049ce28222bd0f22fe0654dd16e864dbacced60783ec2638a68b45fc9c3cf9ca162e587c1b35423d5e130ce0669729c9972c9b4bd39a0b386898446b43e00c27e9f0e5972cc2c00fef7c4308d31c49f43cfcbc324e12ae89b4547b84872160d006ac7c457ca740f66fda6bf666003a1b473d4859a2e5ae89bf0cae69e9c87f1f035526392955a1e1284454475075be76415017bfb4511a41190dc70b4013f114a09c1132eadacd92c28b273bf4617c7c19d129e941d6d37e14d1f0ceae5040287b9b78c1085b301891c951db39aac9c5833ba8e793b82b2ddca07d4e513758b354cb152f691175bcc582de57d2d3cee8d831c55b46e572962881e8e45a6dfd9fc11051da1b64d0d88c3b52301c1b8c16f7688c5ab2da693fdd408d2640ca77eb1c7a5da00579924496c22a49e4ba73282a5a37a227aeeac70cedd7437e10c7ab8333cafd2b8876fe41b9f42408fa3bdf877e4cf05d807a521eaf8ebe8b29a871f4878baa63ed49f5ded6979b8812ded606de615d9832b0ef0b2f0fd03bede551fa60cfe324d6158d80106a9af52cf9731120c40d1e0d144fef52181c1f0e45bd8324f57a6ba0f7b221f8d642971a81276f2bedbd671e5e59e8abf7b6d807250f18c8b46742e0ebbaeadb6c337b839243e505a44fc7dcecddb469ec6d1660b9346a38b7f4995ccddacd36de4723e4509900f309454ef04c969a1130dfcd73b3b7d926f6163039a84c40dad796b9347b1da2fdfe571946df338abd11694470e79e51e16ce6aa52acc0b7dbf1c127d93b235bcb0294afc4aacd6cadfdba6a7c7bcfef59b6c598ef9a3b3fbfaf8ea3a506e3cea8fbddefb07cdbb82b9bbddcae9874df0da3d99b61937b4be8724a1e976cae2f5daeaf601196c27cb50c7c89736a3027cbd8d1ff9aebc4633aa6c3930720e1258aabf5df2f4e8f3ef8d90b19369521a887618fcac878a86afc51b6d3dfd10299948320a2e1ca475a803d8b9e3e3f46e744594d6592046fd212f9c886e73cdd21628af2ee25f9e17161c8ff85e5b35925c0ea4cfdf6bd45e2c3750499f0547386f3254ba7fd07a4faeaf5223789be11d7cdb99020d546daa8802fd7722de5ff0411faec535162a6d1b365c097fa06fb4dc5c57a41982e2191a2fc6c4a9406ac5e10d9c6f9d90c2e68fe7d5ca21d2fd0ffb0b61c2592975f4997f307dd1d381431b2b702b461f060a7372d8e17fddac64fbc8530227a07ce38be7bdd4ca9fb6f97f46d2fa046cd3f8cfdc234358681f9711ced1dbcb4d28fd50cb180b5e8f439d0954af572c68baeb9c23748514a5174c79b3b5c751720afbd5dbea4686fff7ea2da2d6cf2ff2e9b46d4b3ddfe0ae33d8c9d958ac067b4e52cb2c790973c40480ccc949a05e621029ab18c4f5f055152975e249b15295f60376b611c779e5ece3977f2be369af8ee365cf27bb37460adb6503e0445907c9963d2fbb44ccf5f739d975705b921c641df98903b13bd3a2210e3b00948621e0d72954737af68e0fc0de884333ca1c40831c8b124397514de1e8b950893d074212952d968abbddae954572be8fb7c4d435d5f9d6568763126fdb0be439895b114869ec8fc9e35bcbfc9af889c78c87b3ee1bf9aa7029be9e2bf21e11bf93d1865370d6caec5a6e2b288022a2d480a88208be5b3f53a0c16f1b09db86641fa722c2b0e82c261209eea350ccee377a86e4e4dfe6fe8547bf2b2f1f20a5e64de7eb509fa14c1e088870c17f64a46077cb209d6767b043b22a2fe9159a71225959de22c35c8495aa2431c7f7987c6295fa11f511e32c3e3249fbe00004493797596158659827c217840c18ad5b723d46ff08fbd24c82ad3566481bedcbece99d3057eed5d857981756d3b7569f501d36a5038ddf968a5496db3c191b8332349876233f21b700a6d648e0a5274dd40b7a51dffb402077360104f6c214558b527e467c1f13b648e4eee51cb90192998f5d771a89e3ac4a355e173fa838a67ac78bf8878688bf6a0bb880dbfad9a201e371553828a7640516785536224d5c091030c4d01b4c2daa084cdd39a403e4040b7b72aaed79ebf1d390b5aa4850a79c925c1035bdae91d2c666f6fc06a7e6a1522813e4e924a752542a457d89912a3ebd75b53c4a7f2c8888eb1c258f5985a2daa77d7487490193e231699968dad85579271d04bae5368ee136e39657257ee2f547130703c0fcbbf3e1a3b1238fb7a248398c5d7c91f305194457551194ecaec47f75a8247d62935b60c8dfc080380905e439950820a5458e284d758a05f4720a9444a3a09664089ea3e6b061840adc0eed061c1f11e0504e182319f0332184fc856e68e7ca2b0168578201b94eca436634f5d5668292b6d8f1b565c50498b1d321bd820fd3b5a047fa366da6f506cea379a27205b32f41c81e22758e27e0f69230a2d38f44ab8664f45e6183cd5c8d16babd609150d953f6c2b6a137592b356c2012f66e08e1558e74aa78d5f7f5cae9abbf5aa2a448b3fff709d4c0116325a2fe630e98abbeab369a6b302314ba1d6cc594023ea9f68e128a822c96b7ce6d820a55ad15da6b183628ea09f10f1627f7e1415028238652cae49722073f58e18975e7b6bc600f4e5683e8f43226fe1c9dc17ba33e6b8e362680d4db4ae985554a33567bf666cf35d92da463857bbffc6aba61f4d0c85335a1d9c0db3587ef3acb2f96d605bfac2d5ce9699b5b6ff3bb490d530b107f5fc3805b3c7994a0be4a9734a0a4eba065a41793746c1613b3b4dccc0d0e4acb4cdeb938165f232e78c23096b546a9acae789f94cf7525a5a523b68e98a70629822f3dcc1f126859357582ad277323d27f9e3b013baf7f3afd7c58372d76aea9fb460ccada14df5f4518e39d7e9b4ddc23aae53849fdecf93e97453f0f84506863b1fd6764fe3b49339077c2bc8a359bc4459a2357969d34982c442e157230ca942ef58215112989224081b2f8ae602d37b21286be66cb8d603b224544ece5286a4e1583cb9f3d14287ee2f24b7afaed7017a72d4583e9fb647d04356fcbb0406be81a7e1dc90770debccd32c53b0381f79150099fa9cf20ad40069f021147111eda348a66dc0c8dcdd1977921114554e6d32f14cdc1088900b3e3c1d38dc368158dd0d8a630e83baca036a76c655849dd547d46dba517df6c58726d87dfcfab6501ef2cc1ff271cb793cb1bec9bccdf37d2521991d8e656048f7a630042ad789db25d71db150eea3bc16ab389e16ee6e5a3d9ddc607ccb1fa478000fe4e47e616e3ba41c4dd5c1d2e0502fbc17039f8cd008b6442b4c286dfb7a29481001c490039a4b327b59208e42520745a71715254888a73ec979b2fde52fa6901276eec1396e8ae3295b3ef9a4246921e4f57ef79423edbcbe8f2c69cf99e781c064531a2cc42b6a4e63a12f167e74bd9ce82e4da04c5e03f220b6c9967b6f295392018b07da078507b8a55b923daa2e074363aa06aa2eafd59a545d270afb1ea7f2e1e6b04eb5ab4dd93f0606ee19c1330f70e5ccde2fc96637b18a569e73728db38cd86cb6829ccca7966a293706b57b6fadd3003d29cc4db43645f6f7bca75e8b51c114d6ca421ff55d8fe7794e55e58a385fb240e2214ee9ef4dd5b563cc0f6b54d145132329ca0daca9d50006932d9c805252296250e28c520ab064319303759dc66efa983c262670f4a515302dcd6eea261b29dc40fe55875570c1240951e3a296bb3a9cab7fd254ee39cfe1b0b22bc32976241f1f9f9dcfce7d6e3e5888ddcdb9dd1e6595951abda7d59533f6842f7ecebb3f929e30f5424e9f0aff34f6846310d4df71341a7352754811244450d815b99183d2c026bdf504115259bdaab987d430780d754abd71ee9bb5d6598d5baa45ae8b71bc8cec2f56daba21a561bd340429a52105e98794d29567f0a2b0ed6b2f0d65ffe475ed93bdaec2b105087c4f731fa84fa7d3a95f3d3c889630fcbe0f09f5e13edc87b3d6a2ea87fb701f1385a5be2bec9b5fcef35b9124fee1729feec37d4ce26d5bc62eb95dd2209b768901f5fbdd1471d2bf9d88558e2c73a1b64bdfd287b34b5f9a0ff799f9943edca794bbbb6badadef0b4f66b0c0662b83dc62ad35c7aae5eead56cb36018e99e1ce647ff149833d03c1bc20cf5aa4ae07a990f5a8508df56820ff00b8c14a188101a0ca40a030ff4c633dec6f515db84b9b334c11bb2b50d035daf410868630362f5f9425c85531650a9b92952b965c393344103b3668662a28fdbf635d344b65f37bccbc9e79b5aee853d8f72050211908ee1750d2dfebe884b2fca3d09e82925050d2adc0e99a0a174f14f9e903880c77fb3cc77b1166b035331cceab16874b05b1ab65b4eb741581755d8180fe1851418d5aebe974c3fb1501010aec3ab293946442c976624198029be42ebc44391284ab109c80b2bcc8ac9b18c9d58610416117be49d710e5c44fa1ac45a1ac45893e2d278308297242a352a95456707dd3a9caf10dc103bf0ffcbecf476583ed8b482435c44937005007d485426c0df9019a0225fd81545708869ca65196a39aae066469e9de5badb5b69b4edbb03133632b95f49728a0d0a1dcb1312601b32895f49051ee380ffb22d8b510561ee85a4ea1ff7bb157b56b6d11beeff1e636271da929558b6a6aace7d7c744d4d3dd3809c70d85899f531b87d3d4fa3a8f31ca86578dd359355350187c5d25a0ac7e26d7098e92bbff749f528a84fef47b7f5a991be47034bdcc7b2691aee53af2a090b079c4cbd7496bedee5e8c55aadfedc42f72e110f8f590b5f796a032b933244460b36d4cafdc22d07cc4878e3031b9f15a6b0301e183c3e63d834dbbc5096cde267cccf830b1059b76096cde323a2c29814d9b041925247cb4f88cf111e373f339c2c7089f227c88f019c2278c8f103e493e410081cdfb830ab069917c8e7c7cf0e9c1078c4f161f9bcf171f1e7cbcf87409b38f260aae11150aa524595b22d26e4772c11e17ec3dc905d3f1e579efe3ae23bea2311084e057d44529a8fafaacbcd329c5152d53abd48b3939948a4c7fc222b53a569164abba3c058e2ada2324f5ed8c80a15452c768546a4bea659e33be522b997873a7bb224790749d61ef65be8117f82323fbd722f4e70b6cfaebf3d6e4d0adb541af5d115a4ecd6dfe05250ed11fd43854877c4d1006576093363512f35657ce3884aa9f389ad44c12277d09dcada13a2239aa69c10d82e06d9f16923ba367727275d7716f75ad58b8a5a3475913b83e0fd8fcecb9e2ea19878669b47b31fea72a953dd1685516070bd1b0d9389c0882a0102fef8b1e0d38270423fae3ef5528cbff820b76761a476b9c09b6bca3d32a0b175493a159fed53dffdc3ae8f741fbb957f79387ee417c07199ce7fc5de7ef4cfeafd7cbfbbe8f460343dc02d32c2a60812fca78732add8bb14af58f742fc6ffd4bfa948a05d2d43ebd036a829b9b45e2f7f7549d38c318344a9c436a121c9f843c9c257a2462fe29b2a2a3d458aa3a31bbeacf6d4ef235e16c71edbaaa78e7dd45d9cf41d36e03f8a9101c30e6fb46c11274ce94d676c64dc208515326a4a8fe1cd520e67989818a334a187306848a1858d0e4f94fe4540776f05a160f8729f16b556a4aeb95cae695d92ef3f150cbe994198458bca89e1424e751df3ec6f4f3ba3b04a73a1cf32a11fec7cce9b7685376d0bd99f071c7cfa5636e362684c47e8f390c89eab9e545da934ec177e94bb81a98a2a8a3b6192c9e09cd779b37745a63fd95158386e49bd7f37c139d3a0b1d3fbb719f4839d7176cbd4fb1a09408d33f28c1e789cbdcad49bfd26fbdb294e68ec34f6b557ec0b95d27a5394a64ce852a4823faf7e35670bea6b0a025ea25ea462bd94525abf9c70043bf608f14a7cc72d784ca2045c89d9ac39bb5459494e5adc51755922dc82a1404a47d60720726a658f56b656593afac386b28c7294cef592e8060ceea65d9582a9933992c066cde572b95c2e97cbe5320d80127049e829dced0824d565adf5ec57ed47c1fddf87242582cdd1c6b39efdac9733819b23a4245b93ed034110a43f4d486e6d2a6a65e4c8ad8d5aa5eae8f37d357f5e4d91e50bf45379048a860a1a3e6a452babae442af4dda02eb2fae8c90da02450d29facae0750960369201e79014a48e88f7f51cf4eba44561fa9174895eab5012cbc4a71ecd9310b82017f0d86b26cb6a1d702ff0801da80bfb18784fefa754ca17edb1850c79efab44dad892fb5245ed8428c19c80853840e616ca96ebb2dd9926c0a049d77248159b0dbe1490d4d7081c50a25016240438a9a35582c61542615f1429a3662d0480101706cc29899d16931a2f4ef82e0ad3e2ddb0e0b177423fa7347377296bf1b5d376a266c52a637ddc89589c696932f193a56816820a7523d07b928ac5d4343d5559392983c6badb5d67a15fae3563a498a1e703be090fd732b1ec6ab5098e73df80e8e831bb9911192284e9874dbbed8477723374281a961c9fe22520917ec5a75ddb10467f9df7b42dd5a29ada9143da14aa81d51580e180ad66a4d277af212de6b868931a4a89141072f687461e60ad396233452a830b9b24486156630a20b18d65cb19403163494c6287dc922841a9a1ae70d64685840293d0b27665841131210649a924ec0744607242dc060b95181a2060c63bc8872c6891a32a4a14517169c91050423ba685263da01b7d4001e54d832450a376f9270418b2bc8b090061ba5282ab0a5694b0e43c420c54b115378496309da121060d8925030424b183eb459a14a14a53f9931bc2041e5cd1636201c51c999898109382b5ca1c244166378d18316a5dad1c5180a2660802a95192674df3fa8834792d8896db5a050a1cabd18d7ffe17fef136de0e436bbe6c34999933f42d4c0f0224e52153158815446b9648a99a3a2315378e1c20db5a3dc0d35fa5373a20723354fa4f0814ab9e4099ca52a5dd09086132f9c334a696e140a55abd9dad885470eee06dbaf22da3276bbdd1377ffbe5d7571c0c18e03fac30185b9d7bcdb511806d9a5cc40856880d33b141ac87bb7da612118b049757d545da8ef40d736717561610852f8c0908e9d46141ac87f6c281e086f30389e21020717b0f8a2e5484de9efb3ea5a02c60c2d66be88c243133894feddbd54734bb9a5dcb7b4f4e5fe0906bf7e43c91550b2d7c875ac773e8bc29be0dae46aad13c349ff351f6d9a9333720004ae6f450e4ff23fc1369b1c6408a05e448db8b2b0d87577f75777bb5d2a0ba73914ac83a23f23ca513a2375944dd10c70d05c9f301ca69515be0fd4d52717fa850a7d9da587c814b5126bad2894066084f4a73128031f113514d425ab2cc775ec090a13a915d9bdcfa2faac6d2665268b7764e607dbf9663a557b98a9ae3eeb2dd7e77994caa93527c75a142aa7e634799a553fd15134188d6b2c52ab4683ea27ba0deafd1bcda9c168355d45e34494783aa150a714eab4229d1c1212e4404e4bf94e8e8a3ab62f47649af4a5ce9b00e8316b953a6f6ea0d279fae2cecac6e3559776b565e77556b35beebcb79cb496665bcd59d192e4826bf78857363ea7a888852f739e8556a9f3f8f1aaa3501e4e3b309b0aa507307b86ec5faf80d4d5359d9c959736563d42725644b54708fe9cc7235165798f9021fd780cd2d3a3095eeabcce8864ecb39e6775a9684d9da7ad7e136c77ec2320f79bdda2b1d3f7dbf0cd1d03c88d23f76b405d40725021f0fb31a042dff7dfa0b1131a88c6eef7db800289868209caa2194cfde8d303f1d1409e1a4d8c1ac7b1eb595d486aed72fe4089a72c568fec22e823e91891adda725d3c6390017592838e018002bd32b880fef8ab6c361bca718079bd5ed5659dc2b8c0d4c92f3630c4a4b0efae600d5575f56ca69aa966aaf082e0bddf77c14bd403d6400978a26746643c0061441e5018f8c412635e2f27b31baa44217d5a2f9b94e621c5f3dc1dc96fb7effb40508332b067330317e3b75b06b71b851520d3a65196ff454385902351587bad15a459fe4528cb5f4553558abbd8c6630d6cdf6fe50a581c93784992230b304dd8dcd6751eb67f0b369bd683054d536a5fbaa9c126ddd99d096829da65a04119b8bb64fb79dfb46ac4054e092428e94c30d500858f71dff9ad6944348d8856ab653dcfbbddbc1baed5b030310d0d31310d31315925f023d34a23e4d67ad38095c644d3d53a0674e97cdf9edc1a75abdebddebdbdea2bf4c759dd23a54066d790fd1d0bc905f7d8c3c9efe3825fcef2ff7e28903f10aafbebfeba7d7a30c1669d9263d25bbde2ea23af42635328ec7b57db1c1cbb060a44850a75150a8e661bd5fc8d1da3828d8850584d6511ba08857d6f9489a48874c0031d0b8bb0278651039981c906ba914ee98ff844b95bc5b9cb13224363b206f22b86c2c0311d0b29ecbbe57c770af5ea71db3de5f4d6b812b989d19f4781fa01e0f596720cb6c09d61621a1a72cbe451d7ebd5302bbc0517fabc1768b74061fd31179a06d50b471f1ddda397780ac3d3e9de5378eaf30409341005689ba350027d7a04282c6c03869aa1155440292c14230498f0ded3fdd3edbb6a05bd86706293914f124e2035ca1d85da15e9982afbc7528087509c164ab9db03c00ab22174776b05bfbef909c0e03709fde01339e93914a8e7799e67bd342a4502e52283ddff29125629f4571168aa0708cdde8b40b3371ef17e040dfeb7da7247998344436467e0b367ae26535c1082065b1561ca1f4c63e2f0d0021433984aff0010800ad9efd8090dd4c1152f3ba1d2db15df870251284f7642134b8dc210a21dcd15f176457656aa164adc5e482f7f4f2737044465ea52a9dcb41012fede5481e10dd2c205a9fdea57c5596b6bb5e1bdab0d6480922950a2a6156080467321f53ce7f439a25c4ef4b4104fe2a8aa46eceb02eaf232147cafaadc920cf86653a5ba9ea7aa2ecfe248de25fbab282c2797a3b09783d1b1568b471c6cba18bb8eb5a130da4c365babce145cb4109405a63835703cafae4c329856d6ceb76c5bc8cae2e10536db66ab76657e08f86bfd3e7d5de5fcceca3ce2e19579c43bea417d67d4a7563da8980b38fc53cf1d3b4bc7ac6099dbda3f643e6e752c0148db88aa8b963c5fc5f5951e2ff778020d7726a043172f9b7da57efe7e18f9aa0ff69d14e4b0b53e241847474747617874046b02bf7ad81b9e44f184124f27510c43f12486a853783a8911024c9fc2500c5f0ce90f19f4ea819a42e914d8e4a194f2f0f0f0743749e256a8b5bb918282b0535048eac51792f3a817aba5322ab0bff831f15481532b191a6caa6451609348fd7e337c1210108623913aa64084aec93d7a80943d814df28673643328c543076c0f407f5a4cf88534196303113b6c11a28992b279020d2c5f14a17173532e7122c50a59ecc26481a3c502d058a306315cdcb001a2f4a74b41404ee09bf70e34702b2ddd8ac0b65deebb37d999bc89a18398d0ea244a155114cfaa02655579534fdfb9e01f7618560d6a687a487263f321ac8de44266cd922d15dddda9fe9ac585288e0b2c6b7010d8ec1bcdbd858ada12d9c553dfdc75e33ccf9309cdb44c1aa32e4c6598c8c866339581224b367b4deb7a770a6b1717a2659eb0d1324cb8ec5deb0fa92d649a934fbcc8c9d39bc450967f78772ec8418cb71be21db32e2d85a7d3e9a6638beef0cdd64d8dd4c97b653ed4348f22c5510a4a250910233746894aa5526392b6c2841a7b380f1faa4dbbb7ae7a38e91e5020ff18fdf1afaf520c4a7f287da571afb50ed5c435901cf533a0503d6ec0344573b88aab4381728eec4fa4c808d4a5a26832a5826e616d7710438f2c5b01b93ab234401f406449b793e7d5ea79d56bdd90fe5c235bcf46fa16265b6c1d80ba184059ee819946b9e7d96ce5163672ffc8cda0974125846188c9fe5c05e7354ed227ea7fa90ea0022c731c17b36cde06080962e4880914c84b70726606046f7777ea823ead13d574da38e77922352ae743af2254c37ed6abca26ca939c3c4f0ae3c93ab9dd7895573b1377e251a8ef4c400b9c1d31e06fec22b0d96edcb85057af9eb305f59d824097a8318992d29fd070d36653b0f918c482c0efad1708822f053b13cfdd0b7f29f8948dd8ea4536e2d9f4b3e90d6e386e9c0c9201876fb69bef87cc6f50f9beef7b29f87aa91f37a660d34f307543066cfa596b8e68250617bcc867a7d1cf225aaf27bdb635e7fdc4a18568932af4e74c280cb4d9bee93a64b7e231f82905a73cf7b37ad1cc497fe22c7fca4471595457a6d4d1cf15e0f04d3f67a0b5f6d67a53d75efa13d29f5301729fa777f28821426aa2eab23667736dad7b9ee779f42f407336e7830caa9ae5ff39b2674433609a236ac2a0fdaecada1e3dd7cb9efa6155760cc1bbab0f851edff892f51022cf06c1795eed762f58e644b95c2e970bca116da9bf1a3be66a0faed22b0c4c1bc87eadd547754649c32490a5a5251e1e1e1ed007c80f1557cfe0704182e07038080e57df445113280ef7010d1724280c9c85580892cae6e3821861f36334e0557defeb2acc1f68ff1beb7b407aece8a30427f38e33708c16b382bf5aeb791eee7403bdc9f22da343467ffc83ccb8d55a6f32ec4f481e175f0ab6d9e4c93c9ee7595b5f0af6282ca74f01ec6e4bb6249acfa411ea796946e70c894714f83c45b73b13d05214441ae99c5a628497177ed059f1858c1444000c1423904002892e9a28971cb94903a78718c0aca04dd9b3e484142ea039428d1037a860b3cf20d5e824c9dc69871a1677777724aa126b90aa52e1d3450053136e66a5127f41052aa5f8497a90b4944a74be94e2e8e5bea9ca2c605c0c067c1fccc00a361b4b9093abef89cc04e4fe5a24883686d1f53cef35fa9039098e3d76d8403424c810b5965afbb910b02b920429f7a8342db289ca7eda85d1944daa0bc34cbe71b6276486ae7994b5d63280aec9b8204be8881665bf2f0194e57f7bb8b6e01ee05077f7bdf7aa545f96ffca88b1efe9f0017f362b1601b480cd8a25fb7feaff1b4d56766f340f90dd8ea607d99f52caf2ee55ddefc130bc7dbbafc74578de38fd41f966df795617d6e101075fe1d636b9105d23067563cb50afae9db74cd92d1a3192d6d894ece9f7afd1393b4f0a9b754c749d3755b409f65e8c7551e1e47235a7dbe98c6eb24973dcca99aef0353af79c91777196bf57a16694b2139184e47d7bdfe94655b27f3d6a7280973b23156cc2ce770a02b6dc199328297776c6eff49a3c389e9beff4dce4effcceeffcceeffcceeffccef0d4f1d4180ebca7fffd908e7d234f03790623fb9b01880d094f4fff4fa757791aef063e58c0409cb4160c52024fc77e50207f1172f038a3f46afbafa269d0578faa6aa48260e500fdf1ffbe4a4d1a075a0535da0c51fa412916340ada846e88d8c2cc5a6b47d9ab9ca4f48768554e52ead4d54e662166029badcbbad6b54ee6e410aa73d2c5e8990747605207129639d9dfe7d96e6b4d9ed9ec0446b45f6a255bf55e8c55aabfd97ad96a3131911e94fd1b299fb8b3f87ddf23f1be8eed4c204b96fc7d9036b81f14cd2db35b26e938a5cc79f4a7e08348f80d387d8bdf1747e69f08e05f93085dca9fcc4fff51728bf8e205c5950a5efa8b8a8a66af52fc19598a5f345395e2cf6e297e51110bb76ca2d3749eaab20908e73c4bf18b5820cb26b50567297e6dcb369bad6d17acaaea3ac104286c361e1b743a9d4ea7d3e9743a9d4ea7fb4b5e1c5975c94fa7d3e974ba7b2f8bba3a0aca722c6e9a56086970d07d9e0b5d307cab44eb06b24aeb3e53ca248d548905dfd1939c08fad34342b6e391cedfe836476a33a2bc2a3349231c5b57595cc8ec1e67f3d9b4ee1de7375fea1be80782a04ea7a325030f947091cedbff8c8a6e093929940e51757580b2facf60413f0c8ffabe530614e6ad9c566abc517b519847d5ca697009db9737bb2143aa0b0765f9e3c02123832fb8145b43024161694d185e30f450e0edae857f12ad154f635f3455eccab8dd6eb7dbed766bf9ed76bb5dd55d22bba8be493a19f4c7dfb6b555007eabd5d6f62532d664264aee69babb9b0c0aab96e2d634712158f67f42e3a146565147437d6c5357da8104f6a55b17f85629cc56d9620b366ccc30e346a7e8db6d7423314165a81215d9df6badd66b9d314e21088267ad94e55f7120ea14079b9689a9babe1204411014751c575375019d2c45c155b08a087e7d101cdde6471da881ed683ae579f71e3c29ec051e81367ce3799ebafca39d5e068be36cbccc6bf6076b9e03835ececb8c703ec2383e47abba3ae72c7fddce6f153cc1139c75ec890bd9cf19f1088e660bb445e1dff75616d740fe3956f65ccdb2a5993a4e4b32c9a3ec353baeb952a7541afd795267f5e459b9aeb2fc0a67793d473f02cfea0a0206c1a1f123263fb231facd8db209de6458b261c3868d11fcc4e0ef03a7f8401004c1133ccfec20789e4eec369a049161b3d9acb5599bb591ad02f6b269c1d86c960014f60385f5a3510210ed2a4246c579914590ca92c26c1b4ea29dc8fe423960b36dd816ebf2448d96da59dabcdf390057409c1c91d66093ee38c0827de070d65aebee5f4753853a83f4c44110042b8d8de0e60f360295f5ddea080c007095875058b515ccf78708dd804d9aeb40d8ff4119a8bfa9888c140e75f37ddf0647e00db290d37724095165e9f2a9081099931db40013a1e02cff1e1deb00353fc823111f406434a7eaeefebe0ffc7c52b37bbbb77bbbb77bbb372299f7f77d2b331604fea8b5161ce132c96be07bbfeffbbeaf7ed5e7263bb5c8699104fef26bf0c3165a705aa6e8c287d2b550214c181ac0ac61a54ca3a8056cb870534599334a326f6c4038a981862f4d4affa639b2c0e67b5970676200efbd97f4f95a9e19d59ff0f0f0601e1cd4a58190c75aeb79ee3c14e6d6831bee7714d0e01e41ea33bff910d97de0e25ff20e5ecba1b9102121c5b1c9d694081b6493076719fdb10f044978c7169abc4059eea71bb91457a1c96d576a467e1a2169aa2d0465f98bb965d0a83a298715d8f4d3cff374f05c720e31c31632d2ec40059512852c496b9cecc46852a6741c5892988ecc9c5181ae04365c86d021072861be94ada033c5c53fbd44b2210d3c2128d8ec9dd946650d37e5c826cdfd28b1e0d6b518465ddb35d19fdd0e776a1287528a31aeaaffa521408054172d31a618ab9610e0af16262f75b5d092dc2f1a9030d5006fec19a1dfa3e525b9f6f92456753d6946e7ccf33c4f7442ac3efeaa1d17e5d3d9bb281f1c3b563aa7aea7b74d7f1a2443bc50aad3eec59866927567c7fe92d2f4daf5a36a94d35dff7ea750ff8e66f8df8bd4c71bfcd927c3d40fef711aec81c66553892da7d01fe232f8a6125b0e5170e393f408d9791bbf33aeb0a4e4791bcfe33b6fa35096bff8e6abe9a23a25428f66e36eac92a0c00a1aca9437dea37953288c4661628f101b3c6fe39794385ee63bab1e213bafe3758c4974883cab9a5b555d65ad7a84e4789ecf31d65ccf7d9ecff13a563d4254afe35563d531f6dccf31da19adb2ee688297381ec7589b464bf39ce57f2fc62a55686d280b059b366773d5656d3797b2398f05d8b436efe2d1bc1ecd96337a345bcada524ea3629c668af9714759ddb9b1124119598c4a1b2b5aa256467ad52402cd46eedbf888342edb9f029b64145cb2fdd305dff468d70b575e14fa732f48ea701d6916e5a447f3683a8ecfd8bed86c365babda5cf55eda9e883cbc6093ee28a5b4d401d34c349ba98870172dcdf4dbd48f1e2a6bd8a44ca9120bb685756c2efdfabecf6613733b44419778c86285943656d6e04176861261b8b88196c3130b854643a2f4fb3e9ac5b5e8f4a6b5345ac7ae513e8b320bd86cda8bdeaad0a51be8193847a1b234d8a44c27ed8eb4972c0c9c8115ec1fbe7def668fd2d154a556af6635eb5545008f7819b4e17bea47f8a72da2380e398b299f56de434d63aa1dd1578c0a79d61b4ad2450e4e9ff7dedbeede0ab2b41d1bc4554ece3860cfeeeeb40b05d872e8a254024a7145797f8ceb54d2bfaf1e3c825c41f4c73fcf60628cf1f781df0782df077ee0a53f21fd09c238f731f10453813b9b3c3cdf4705e669229454a20d0c857d1fab6a3a56dfd559dc75852b79edeb2a415c90343559fb1e15ea393dcde11bf1ee83dfd7b7560cc2822feaae4e50028ae443da0104eea4b6750da1a7fed736fa531f0bec5f5de106dae1058f4f05b6426cadd6d66a2d18fae3968a1e690309e9a181fcbb8727be8779bd448fe9306d6b9b2d8a1326dd43c7c2ec8f7d10916cdcd0812347ab4592189f4455f537d31c3878de7cd5a8e3de1c18e350a978fe6f8c36c6962873a22154015560ef531fbe793fc8a9324c05a14ca834cef704b574666604004000b3140000200c0a0643e18060442a1d0e327d14000c66824080663c1848834116e340c620628c71c6000000404466486a1c0419831144d24793ca8404357a5459bfe046e69a9c7c852d31b21b3eedc8c43ce80eaa0ffaf365464fc16e821be7f22e763531d40e94f54ffeac0a612078e2505d045804018ab840de94f1d12dae2955499fbaf1f2e4a14298c2ea0b1871ee4a1bb794ab823fe2177c4195d4444c3102c10a24f1d8bcaa7eb4e2ccd1850fc82fbf713d0d54393ed01474e3589b3b90ae7d909d67cf073db5e483b48d45890b8c253985c39939add8fbcc7de77e6b8554c89077e0b8f305b9bc37fb1bb4eef84b1ae9f4446090fd7b691b3bb589afbd763e50e607a254baa29e018f482bf25ece1d99931891acc1a2ad4859d5273cc7b13c96779f7c15942ed755f64d07f0aa7355ceb95ac1ec882e331277e176353f9d9cd9247409d0211312a2fadae1a343fe7745daaa97d74274a90481bfd2169ef2474200c14a020571d14f633b88524940946611a4ac987cb05a831d963a3723b25d6ef8735a906766440b8fdbb2bb0fad00444d3dd776203e5b2d833350cb5017799e585833ef2cf1617905562b951738ca1dea8a24ade3dc255bcf9705c4401fccc55448bca03d9aa1d3d1812767500a4603e0dce7190b1bc2af38a09d15f8aa91fa6f7dc622eaf38c0402baaeb9c8e3c9c977780c8b782907fcd1730cf59411b4a63fdcd7fda880eaeba3be3b8375be4d50e20d4d6bd6d5b84979aa6c05804847975ad3c917b2c9056bac91be86729ca964149e052b0fcef895ac095646ea8f796396c75b09cadcd06755f5aff9a129d26b0779bd52241623c25e296485c5604dbddc292a3a8e40d9f5e5645e72ab64fc462f966248e2ebd4bf9189a2496364f1e1eafa57f5b7c338165c59ffb2ab508716e6ec26889482e3f43ee62036147751610cfb28727a1f0498051033d202c9129716ef7300e78424bca85882dce1587ba014ddfbc6c2b052efff0ce00eb6fc21d5cf043d950d7f1ca7f3bffbc03525aef273c0e6101fd881ee320d373053e93b5bdc207a66fabc92a9c53e6dc79ebbcf77560579ab3a0d22651b0984050d38a3dcc2a775e4a5042d6c4a21dca73016096f506f125a3c7d077d1c30dabb0001d5fc7d679e80893356744e8d30307c9c219dfd9f292926194828f4a08d4eaa40901142042c004f3de133cbf047dd1b78bf9ec2438651cd5d10d8005e72c8eae75e2d89eeb9c33aa7dfeba8afb3cd624f000caa800db42787d0178f96f39a957411c35bc94e94a649a6c8ee5623a668a4708d032c98b65700257866b4772cc0acca9b6495e3923342dc492e64e8619945a4fc8724830cc60039b1da715887190d889f0b93a4a2242a60409dc8fb2d7eb20913aba445da8366e3968cf3d066f2d7a9ce35c5e1280a2c21ae69b1c639a8f7834b64375c18cb454fa3ae9734a046b9aa02a1a8cfc3084ad34def01a877d000012587d13ee7fa3d664f589b0cf2eb186be129a36cd7d0365ad043542bd9e3f6004caa55e5c3e71e26882baf687d34cdc48d91bb2170db7034c924a7303442ee4acc4c905ab511eb19b8bcb3c323d9128060101292263c4c536711bac10f5213cc024274e65378e21757650034456e7905ac54e6b5979acff01ef3124ce27bd8924ec6a0142cde468525814940ffa0e513da4461ddd79445679dac9505a9279a17cb4f5d5690baf84b4e006dac65e23e90d116e83cbb518759bc1144498e4e5b7eeeba16498f6ab45c72de2a400755b8ef51082807396c363a21716601120681a806b68b08d1b392e3245f1ee034db6941f22bfe791fe599eb9bbba9f9e568cc46732480f1405f1efd5811b382920a7dd1d2178988404cfb4a95bedd7f5227b221ccd2cb632e0eb4a132523f3bd343efa6deab2e44e1936d610b8deb54f5c1a01a3d5fe0b2024643cc6563b6199bbc015fc0729325c03c87cafcef3658847a58e1d8648b9901a127aa8b4ed8dfd882fa211d799dd993743ce6ab1d3e38eeda2651456c8f88b40084b41072befa8542dcfdb08de677c214a86c78151ed725475e61f8426701573c024ecff945d959d98a018e303b9c751c24a66a83edbd3624fe1b8074b2037997ea0dcbfc9c67f5732a436b3887fc9e02582a75b20a7f855bfde897ed3c30dd9f2af17af3ba20aadb1bb31374a8827acfcbf15bcfa9feaf380a376c08ba118034602fdab30673657da55341278c85ab793885d784a0911d00079971892d883596a2cc3218191d8f8a4402f8964d6633f69459a8d817e18f5b36d1f0518f95d09120997b50bc79e441f2eeab1e67d47d9ad319d83041c7c1b62f386ea5de28d1f8685c098474c0d959ebd30c86cd04d0915b51a51af2b721ff0695e2c05b36118670dce50bfcccfc0f3242832ad02b07b39484c77040a9c88923fe96432ce8ee30abcdd5e28fef0bdce4d425b3b8262e181870bc0ee0ffa25998a292f945f006cf049b1065dc2dc8f4b2dce04c9378989551284e1ee4935e163993537a6b486e13defb8f4f5df3a09f6531b542b253a5b04dd6435432d1077e0da01ae18f0c863a19dc0c996b439d5cf1af9ba18926fac220dd88cd9efd5a474b4ffa3b220c2c6d48de5294ecda5a604f4014c116f61e8a4bfb305dbc9180e6413cf9171592a32a59905380b720c2b3a20fca36de2af4fe81c2b6be740fe1706e95964e95ae49a0be833715b20b18f5f3e75367d59c112fb40d7453b18cf78b01a374957b9f83697499fe219dd9463189c01965e05827c6126a45c5d2e2d96518b66afcd53b8fdb3c03864e3dbe7d42fe92d281d87b37cafde3137538d420298728b4b24737485864b94abaec77d70c24816eb00898591535cfd79a73fccfbc99a1b62f6a83c32aea8df5cfdb588210f98963468bf36a600c7fd9b24816fb9b5df2b5ca0f8151c1519969f170cfbafb47fcaddd8344bf20533a770021df6aac70a26499270e119e078626e0c0ca7c5e5f9bbe125bce5b51e07a801c80b99eaef9f81b70e637c2e2fe53941280139700ad053b8180d04a95eaf3935ffa08aa8d44783cd6026394aff5b25ad55b7134c81ae76b0af19bda35b232259ce3e21a3fdd7cb1acfa36c4a692b9fdb46babe2c4d67759c8592167a23d64801938953f2429cc0613e70dcd8b77b9fd1c85a4d2356bdc628635c7b02ec7ceac46e35f541816de412dc198d5d23b4c0286a445969d37c161a3098866adfc4e76f5a1ecb42203ba1932644f68edd9faa92ca498fd4626828dd1fe9767c8b6b178e00a3f0c8ea941dc716e3f82baf94dd1b2c05a42c9b9498600fa9adf1de5c02e6502ca5bf30e55319676e5bba7decdfec9585d8da5dadddcf8c0a943f94f6efc4bda7d8464708e12d2b1617dea20f6d0127136281250f66090f0e7a51a5f223e697d1d4f2bd606dbb047e610ad18c117794577f47153b28c9545ebf3f22f0c435ed59af972d8ab820afa1dee333f07f91aa80ad790bf5d81cf41af0c1971b9a022fb8b125a7349b2296000cd841c5569ce3f4feb60ad1cdac850490463868cfac9a8264225e9bd15d77d85a406d1e964790a2ca6a3c5858b0ebd76af007a1833e08db26d2d679a9283991fb22dace02b80d6adb73b63636eed33fb574bdd75616e8fcedfeddbe1982f3389e2f82bdfd29eb14f01032018c5001154b6dbd30e79594b03a170f98ca76c5365dbf92d801b2e207a26fbea60439d1709cab442e2e212c2e5a9d2bfb5c7861d06309362664c4bdbfb9b052334519ed87e3b50db6d8ee9938f34b4f08adc8a9d162da7f28b1371e85d6975d6b305fd520f95b71fa96238f3726ff0bc0ef53245f54896b89b8f18ba7644e7f5402539e06f28b2044995881eaff107328a40a06dbb1524f83a59a4ba34b82ee47321b0ad4f1cbfb809b6b29a841f2b3be1ce2084244ccd6458d03b4fbefc9594a83fac89b07106d81879f88a0d66e6380a5153f5f52392e2c47d5b364a3cb76f0068678db4bfb6ad8eba0c15b50dcfeea6c4a3093440fc22bb8b8876c245aedb963dab841278418e87e06e5f1b6ec139303d1699db3de8beb6d501deda4155822688f118c181c4d47ca3c2feb1693cb60fc2809d1a3df0a8273ab9744b353798da797b5d9d2971aae90c659243256aea0756ca2142dc271d6842765284acb5d75384d7fbdfd2e8abb535dd79ebcefd5fdf52b9b155e088830f71169dcc233a9135551f05f5d46954af602dccc77c31ac4958b1bc6352c0dbf828cc6a5e67d10229d05a78e49efe3e52a0f7a835c6816cbb44a33e12e4402c602c0585c594049477bee4dc076a45acf68b08960f100e6289bb00ca827d0a74ee588cda29ee0af4740c7792d5fede098e65403e692bba153ec8b82be95fb11c230c5e85fd699ad88f1a6b87a0da3ec22c82b337d831fb4bf78122d775e27959f2a9c91b684cfd689dc7e47332d4f4f9cb14939746701c6cc30c815843741a0421f71b121d9876cd15701ebdb5dccea45901b4d8a7b7c8cb6634e4e1bb71e5fb4941aeddb9fad264d09a7fb060abde9f9b41742bb559f8ffe0c268d446322af50ffa8d2ac3ef4a0281a9a92b8401225c2f62f45881c2e23ea97f0dee1697b26d87cdd35c198bfaae8d67a4e44c4a862906bdcf9e1e89d593bc9af3c115d1e5ecaa38b20c3d11fcc5eaf73a86d9585ee285518848232b3319b021e69022f905da55d679480da81942137941087bb3f51a3b62028586ec15f8e333ca3cd9d80124c3f06994dc448d52dc35ca4f6c945d764c1c28ddacf1ae4275a00238d908a80e680edf68f05e2ea04bb17b8c92273c5c4111d1a642420c7ce5b6a8c6b00f54d3f028b167f5b57f3f09bdcabb1505fe1b7441c659ed6721db939ef2037625999b05443675aa7a67a7efee81ae89591d5ff51bd9f44bd468348a3f1fac62cb50c3666cc6b12b81407400d72c5722efbc120106a34e1fb1869fda6ff0f14f62decf0b500b63cbf708a1189431574595124564deee81c3d956c16c68cd86b7840169cc86a3306be8359c85af8d837d0c3f39a584425dabf7befad366e4f91281c6bbde027395744f5918211e4bd5a05994a1aef5d9b6762493db9f970b7cc23c370412ee256310a889baf645ca1dc9773245e4820c91c861dff253704294f6a56fac30b1d8be8a2898d84376f6422d2aab2e1364462d3c28e309227202dfa23e186f24a387fee5625ecbb52f9cdd2fb79f41d145cfaf3fd99ced52f90aa29347a33df5ea4c00e4213e6104502dd6fe0749ab4069dc407d3e3bf4d65682e4920d1431be48cc421c4cbf7237e3ec8e0e6e682cb8c8f2a824ca1a2d635757ce96b2d1c544f65b6df5f8ba092eb0086b94dc10fee90dbfa879b2eb80f72adaa791bc7c5d10225b35acc0e56bdf7f65df0edd03facf9eb91761aacff51636c269baf659ad81ae525ea2bc9537078b0d310a4710a877c7e7708d30a878e637e039cf4c481209af290a87959e3c6e1690ff3b43c0d1bb767accbb3557c0305869844316a4ebc4b59f46cfa6ccb389ca39d1a71015864a9e7d95bfeca0e10f223932c7a851f0b7a4cd1dbeca8c23ae677318e2fd85d5471b09760208af41f954e2a4b61ab92eaa53667cb97003adef9a77ad061590ebcdf0da99c620fa28eb810b25d636980b4b4356258feb3a5884137298438c838a995685277babbcb7081fa157e40e7a3399a44e97e3eab56a459a4adafb9e3e25db73992320fc993b48d1e1ea0dc8dff24b60fd5395256c3934a45451811730ee1cb193e3b3684493de18425709feb00c3c6a0fef86a008be018bb5f3d4dc29cfecdd0fdbbd2cce15130f90d8968b4690517c6e75426cce81f7b1887f826d24121fd1da49b588e27e5e98ab21c7067c5380680e88c6fe0027084259b37cea8e22660074e442f3947321708c4501e8794a58c7fe4e661502914fc3f56c6ccf8bb18b07c60b60625d91345b17ce1e02981277d449aba0630f9a91d0ec1a03be282c1b0f0b7c7198a94b0fa4f8fc39624adde0c05f430a8012c25e1000d090aa2470b1b39e83cfbd352359789cca62bd41044efa05feb307e308ba19d49b5a8be8c22883ce86c5c8c60d6387e3295764c3403c0ec39f6d4c109562b856827c202b245685c5594f134b0b29595e632842100c7dd80345cd274e386c93b6eb43a56c7c31663ab08d1417a3cffc705be86bbad6d1186b042d2162d72e7cf0903631f6daa3eb33db5f43e5a92a63e74c9e802fafdea091a2e7f895ee159abced89e0420b114608a08a755003060ee4fa82a872d42a217d949281026ca5a0557a8efd6dd21ea902fd2d401d8534b4fb406f8e4a2f21d403e44e37dd894c5c88134481b606724489de333fd0d626566f94b31dfa944ec0fb822a871d128c05a1d8a375dcc64b6ee223b91219a31d5ff642684c2e0a129f9e552f9fcd2fc45fd7a9d0d820902d2813c41a082347900a8617d4c754d0e4c82598c9830c9556ee010b2acc5973edabc94554c1e1f65cde725df162ae23de6e5dda0100a5085f24071cf424463acc6dabee0d1114d0f5b3cefb79a6376fd6d5b22ed91d8dbe9c86a740896f9163588fa240cc93af772e56d30ce570e65c5274c57260dd503c24a816e6d1e5363687bccae1291ad13a09c529a28cc5b71ee17a8bbe67206efca4c955f76b4f07736376998cafd0960b87005bca886908fac5c13d4f93119bf133242287dc7225effcc0fd1bb9686aa5d408462742abaad4c0764392a8273ff19603e35d0e7b9811d9dbe5f8e7a9d08d4866026e95ca02bfc73da94402e1858aba889e20897a7808a219c74778f34dca5645021759a4fc63718afb3447fef55dd512540ddf461a49b328689e15b1084a43aeeb9e34b05485649d1021ba9321ce951e3927811a55d863520d9b2a5b79a6d6135a71f561176efd9e5344bee8d4ffae0970b18fc8dc8738e3aa517bb27b531d3c6d15288e90adbe300dc38c7c70ace7ec825c4f8c462e956ed2fc2a1c2345a91b842fec5f0a181e933ac612090b9cf43e265c85853400173a4a4d06424bb5fdf8661fb02ed26298736c90e5ab51dfa77ce1206b502831e83e6d58cdfbb883e81431b75ad1cbb90c08b42b35dcc6be147bce7064b7cffa56aa8711b169affd9096116f242f2e9f13e38cb2d51552d4663296879c417b07356ab22561266651f54a659cc79730dc7c669bf392383fb7633f204a83ff496acd68013bed7f3529e2aba7f9e4909db77d3110c5764ac12ea1cb65099fef3ee4600ecf9d21222c1cfc7c2fc1ccd2481bcd6024742d60c50ec1f876230f0366cd949a5f859b32556f7c991facdad9c500b7f3ef09c03bc580203c7615304649d1e1d1146e921a0fd75a47ae191164211716229fe75e977b2210d6eef2964fc55583b06bab792d36418e4e666c28b9d70f30f7e7f4545a68e235f6a12b2f076408310568b660f2e63ea846f0a67c414de9149aab808a3810fe5577827eb6941852b48dc14b203e83b1f4e48a5b682e8b49139517746cd3d843eb25a845c2c198104ae6ec19d9cecf3a0bef76c5861210e90206d43331404984788a610c496043ced8addbb090f2ef53d9850e1ceba4f24cd0cec3003d8433895e2d340568d91c09818685ec53f653b5467d87d8b6baa57a240600fe8bc000d56c5bee6f86f729431ac124f0c7489cc25e5fbf44ce4627133e624ca10a75625bac846f10638961700cfd37c7897505cb9fc7365a929a534fd5323ac82b054d58e21e01043a1c0f2a40488da79706d3ec994c9495864b5ffb4014ca723224216ec0055ed06da29096b6ccdee24713ddc233f531a590ee929989a55e38fcfba000f93221549717709fbdf43618f1afbdea16a889040df4786800a3dcb84ed06978c72294c69e19d97e877ef09a81b5ebb8aa3ca20507ebaa12f4cce06af36259c91e5fd53d35547154737232b3a6d132cbd4304a065b9bd9a9587cb5b7661c45afe264dcd3a4f784e89a0a8cb5b8c47cc70660cba150ca0c8509a4be2cc500d460c98fd2fb2fb99ddd667684ed3eea19022fea6f76eaed49915436a8352bc8fef3f0cf1ad5e567a6fc8e003b66dd33e96772d28be6ad23cb59c97f8959148255cdf437e4d1dee05983875efecd035137f2b7c11bfabea3aca60098e16f001870eb54baf3621f4aef1cd40f67941febadd88245a8b0e597b9cb1c146a47be01a4ec8f8e4a263c14da58fa10be63cb344ba4bab69fb2f3873cdf568ffe4d4c926ea0aab891c83245cf44006c5b281694ce653ebfb4df13c9e2f43454bcb9c2229981a12a0055d3cb9446b133f23f75f1c87be7b51b429e11eaf57b85bc27346e1916370a6255cd3a83da9e2e4a643fa003085606ae2a00b9b37fdb20b13efe0c07b472b7483b729d115c1b244408e1258d62ddde38a371cad291f1987101b270959f9fa4352890d6c296a4730594c5cd1d90948cc3e48f833e29d732e65ea3477d494f880636721bb29881f2850a9b88ed5fb57328c2749188c112303692c583c33f417496569219ce84e3cf9860d50a697db161645ca5d151a92c7260e51f22f9c4d7a111e254091092258857aa6c3d0451883a4192586534a7e6dff636ce4bd9e93a3b9b3e04bbb9a5811f17db6dc5996e3104dfd53b6a761255f71c1702f4245dc285b7ebfcad7758fb4e2924a24c554353490fc22929fb9f5a53a2d458611fd7406c835007b273861dabfc11a5bdd51dc816e5dbf405d72b93aa768fec8377d4d9b4356d7926b04f08df6a402f17626399118c799a61b7cbb439e2722c0a031c06794d591ce9e35d6120b73c2c243b85096e90cb521b1ea7438b954967c9916bdd96e25181886e1b14f5576178fa15728460cfb05f158dcefc40fbd782ee9c3ecb7dd4868373d3c79312c2ca0f5a05c03bbe427c412648ee9c7c376a2f4518f569187a2f81bd57fec610ca61b55092fc800f17dc4e39aaaa728bc43b2a431d441f7b1a5e06dd6144036be7440bd3d768c192d4c0d1e8ecc184087d713473b25f92efc598d742737751bdacd42fb2ac0ed01e31417bc6c51d533e6bba95fbe6454511043b0c171b3a34adead0e41bf90eea2165510a79ff34484c626f65e8c077702db89e7a9d18dee251687a098fe68fa8fd3889b679eb077f73783b6a2dec787429941d3b5316e055195b0ef13169048265443283d458fb8e890005b9ac18b269a165502190e64d1b3b795fb6d206382404043a46083cbdae7a1b6eac824252dedb0abc2984665681866270537c9c3d9f22f21e288a94f3ea23420498706e7cb2e85408cf50f0a5b1c94c1b0206f4e88c86812e23a65fff7ca37241ce532460347443f1f50a84cdf76d8c039fe80ee6ad6844170d17c62f0d854e07fa7e86386b59afe0170241574d12f3137501034536662223f5f1829b86607d63f63e5c4504223d5d3e37a6697480b10a3a023dd798c27c5d993e0da7517ae5526763d0d8d6375827a24ba50a2dd0117dc1f2da67bd8346d443aa9897722a5274b0ee150ecff2518bf0d740237772b32323381363f3034cbf3bf70275ec3a6e91c6c6e6d9797db65dc0e2f326ce8be0edd559237c6071474bb80757507a12aa46023e9bdf41f9e9f7e390c979d0e61d75922862fb1ce1cf0071b6e9d0c71b52fdac670d014281c5ad9b41934c4b021043a777f636e69dbc30281e8a89629d0d29fe5ce0d9e4a9531db0c638f3f55c69e2161b44974c3ba8a35be2ead4bc31b0d9a4580589f32b4a4addc8eccb1f5a76b3141298410200c873f01b0a12cc90163e09edaf369fa8d5201d927c88528423810c98d45aaaea647f5732d118c9ebfc9b82b2b3db9e49ac8cf6813be0af6105e5fb6db96d579989dab2b28cbf73d911127b6ce491fad741507998d2dcf01c6f9267769b58edc03390588facefc16aa51c83979c77cfef0bfae2082c4aad31b27ea03ca8b3e1fe94a5fee0b894d36d6a1de489394905e23c43d3a86c7a30c39a7733b4f3abe15e4f52309d218407380c20eead6e5f122a2edff72b54498bbd641bec591f353d6e1c40f30640486b38a738b58ca815922a68c56f376ad60d1c43d4e66397f6c1fd61bdc5869dca8837ababa57d87fc00715a2d935e8f5286057973ba7159d86c6f729cbd7a61a5a3842d705f3dd85b4bf74710492503e2e434971a56b7598470c54493a970123978c5158d9f773ddea2e46053efb82b6d17b1b3a6b85d8da27cec1a9bff62ffab2d7f621282d06e01f6cb00ed7c9133d594e62d8d151da0e7ddf779186292403c2c973434290c67188966d384f4c22934af96c23206b4587f904dd3b5eeac373926ca542c58195528bfe42487e32b401012a6ec6ec9c5074e48ff4f0e5b2f99c64e76b827d0a001657c4994bab39112278c50318fcf95c73d0260de4cd5e20008d0535a878828d0b1da93f504ae88a7bef1ea779942cb4862cec7be69d9e03500cbdd3d190b27414abfdf6ec8ffed1d85b438a81f1020b0343b39234452182eb9a8efb8f117f93145901f4ef655e5c5d396534bbbb320683226e45e25be0bcb32572c9fe3080f91322818af202c4bc1fcf47ac84fe424096bfd2c4d734164f344430ebec47435754d603eb79d8260bf106d3fdd0d06b6ac0ad9eaf2039090d8e2455d0b870519b1a326e8f37069e2b955b18c18e990b2f904e31a37f92ab9313adb97818858f9890de21001876ac980183cb8fd8c3bb05588c9dca9dc6c7a8aec90938c35ce314282b4511e62ef41fcbe38a83617f6373410d4d210ed5024b0dfa551ae3772ff75c36b7d02d8dcc5f0619bb25d6f00d3f236f69571f56dd59d5d5ac746d5b5457e0975227ece7d4c07ff385d9545f4e14f00f8ffaee07a9916808083dafa743d02f9844f0baecec3872d26b09f5ccd44516352ddf399b068b9d28c726ad3dc0f844418d570311ce8c3d7b6d6434c2c90ba4e369d831e314c54fa1770c9bb2f0f852286ed911a8b4552d6eff6e0f3f2b2170f9104ad0a8cbe5f8339a7725fb34ddf9935577781d21f5497121a3b1ba2281663c5474004528aeabd5a07e3ad9f904139298ac11a32a80e966678b0ce876c04785912b5557fa3163d4268473b899af4cbdf8daa056044389e9839ed385ad0c73cb4d74c4a3a6bbbbc84fb0595e669f101ee84d60338e81a2892fd0a304689b28784ee49ca2917f5f5353c51ad638803fd9b6399186c5bca085b08479af5f52d56959fac500170fe5ff29511476811c331a8f84b77a72d713d87d5f427e8ac57ec6af03b7a94db6a855f0f1e4133ca8a662548f39fd3ac9d7292f5bc3b610f44a176ef234e39fdd8999a972f4ec150dfc295bef9ea8590ccd190b88af54cb8da39d1cf810b0597eddecf48d65cde8050016ca3182dd69d887522eece16b516449aec3302f96d14e77964a2ffc2d8ff44346ffa0b00eea0a44e7af5a90025464255b0e1a88a7ef6005fd07db47ae42a44a6ae7aa27dd886a650d7e4921a56a5fd85e75078b80cf2c2b5825993827e7da463ad2bfcfcdb072deaf1c17e921bfb9e56ef55f85fa7d11d52a0b296c92857937d5d5ac2e91a644d954016fcdc5694f54956479d8419c9d097fb80e0fa27b5b4e17965005a082eb33f04685f8125b308a834555983e7c651104f85303b0c5d57fc41de3416546db77a91b29ec525ec44724d315b68996965f3aaef1c999da8a5654a18b87639e1d98320e6dd998282e13f930a71df4c2123b80cc3e6ba0d57dbb9d273ce784e43f39b8eed8906c528fce0ba0c0517fa31a8dd37a1587a766f4a4be41309c432b542e04c975cec5f30572ca3cb7d54895b2368595d528c5ec51301451a04dc332ce908342c86ce03949e1a6d728a19c421f2c5b60239e22b3ffd19b10bc61c3140a8c79a78d6c5e8b5e6d2faf18b6807853fe8a11aad0afd81b330194a5b10249a8aee4293ac0afd4cbcb5103a639003130f48e7c1698c2bb0d23ed5329940cd3eab1751a61a0a3c6fb5ba3c2975a22105f7c5827700d80d9c42e445658d10e3b83dc77651680ae8a161695977adc83064eaec07d2429e01ea29c971ff980e42ffa47d6671636599fe57c618b71a540ff286b91a7591f16b43633703c0652e7ad466a7a8b426190732893790199ab59514c5d35ac3e70457d86963b6d596525fe5e7660138a659eb1fda2fe4a62457ee5a2d78bb419f19527d7ce6596f1e7fb9d6dc5c2b326ccdc705c3bb7f38f64437f5aa6303b861dcf2396bdab5cbccac2596637cdc547fd555311a87f2c1cc5b925f8ee2351883185f73d4f9b49d80e48691a2b315a9504f8102dab1a009a7f0be44a60a83028d8ced0ad695c25ec4dba14a357a351ad5cc01aaf17e7af57196da57a8014c993a8520182e547731f030dec8a06e2e2afd0786abd2caa473550c51c570cddcdbf003438dc27e5c3e259551aa5cb686dc668f30e9b19e1a42b82f341aa722dd8a6f9644b28b0a25c5ebaf1ca3c0d7b31c9f9a728ae327cd3bd3e76057f8f77cd16d57edf8bb413d64c0f44ec79ab871e3d86c2d423d148317c57b5a5bf042468186150b1824611dd925bcd2e920fe56b7e48f4dbd5b38008feeeaac2086f2dea734f6d707a73cd0e627811962040df55f030f4c33ca90d5748786ef0cf55ab4b196335a36946cc5d0c8004da5b86b55d0e7ee0ce2311c8cb6a471cc545c7c3567977ec0fb6ffd055aa803fe6798b418f225b052e94789bbf17c4277372d493f8241be34a1766333c0799fb6517a509b9b713b31a5510d6cd70865b0d591e01def53f5b94166a9c64a9d53905495a186dd035a6d75fd0617558274c1e1e8b68129cca22f7f2d9fcf0c56c8d2a697c54308ce8535327b4c944361f15b8869b32a0ba9ce6fafbc2f592a3a2f06b428f6e3dedbe931a641c90deb952c14c6cfe6ebaa31ca86c12820b4891c270810541138c65204f63d5b3821206a12296617d7a689436f5017827afa2c62a54cd05726c1d3349f1c99d2bbfa9a6a2967059a6af7aa81c7b488d15d5897d53023c24a1ec16a7cf116581588be703f680e2ec078171c64bcf9c1068f1bb2043d1ce831baa1f38cdd784f6fb798a20d3c724674843feae4e936da8b723cc103154f886c291740c266b4573a94e5fdf384e27f1bb270e0fcd27338dc8b7c381642dadf3d9212ae37faa3919d412d8cc37c6509a542ac52ed5b935e3a79f8977354e02196d8526d3fbf33637df27ad8b729d5daa1927bc7d3c951ea453daa425ad6d0b534f5add1a39e6c417f08cba9a37a4e304634c4797fad20f438ce002435395e90157483bd80dfcb4b493f95671cf3e2228ad826c4643ba734acc2d435c78ba9b4dc01dac3d5f634649ccb7124fb2832770d24b364034d9b1125909cb56cc3657a6c97083e6ed98d154765eb124d856af4ce9efca96489385ab74773974a89549d5ee073201edc53e48487bd5d22cb33cbee94af5c9e95b5327b5f6a14babd88839547c64375ca9087f79b5a117d300065d23b8d4a82bd60ff33fc532fb733620b0c22594dbcd99b2210bf92196d2b4abbfaed403f0acb26ff63a8bd50af994a25fa61a233d005ec102c21cc14733655b3a46c337cd2eeffba280e310d306a54a4b29a2afd22dae8a4ad455b3f615cb49aa0f52a5cd026ba8e02f4110e64d31d797e34be10b8e6f3cbec71ae5df44866ee8c94bdb026f87523bdbbbf25f9792ce12affad237a8c5fde7357f1b49d94940948d3173dd5e7bcb30e74d1a53845f11e61c859f94d022d001a6316df130d3dd9786ba78247e534ac469c345695a49bb3871d8d856bf25b08c2d8bb1376701ebb413641693eb66e9102c99931b6497822777e1d10eaba97c5b59cddcb9df21e5c8110267807bcc487a9e8aabb32878902a04184cd7868aec0f5a0c90080332ff1fcf76e7076e26d194fd7065829dadb07aed54aeccb99f2301db7b3a6acb310e95aa18dd8d2311b558e0a45c86aef1660777aea6d506050e89fe9444257fd19c46d68dde7be041220870f4573508f51d958c705424a82e7f4860d7b0cd101538341014446405524e538a0138dc8c8d3bd8e970e3958cee7ddeaa738300061bd0f69a0f7125bb074bbb2d6d5482cc511933ba18f39c2a41fb3002531a2d7275c9ec80b13494b92ec2b0650099261244cf1d3735d52779b881a433290af286c32f5f7f10f2e33e89dc04bc872ffc3c6259907eca1e5735528a26f46ec3f014366a7c296cf8374b7155f894b17ac314faa5b1cba1f1dcee1542a50ab9c645e8f1da7a8c79d3a9b4c64b6233951546699fb372f9cf461eca834a49fd7264fa1df9a14c2a10ff16c0809896e8066e955e6dab62aa34a87f63c6a7a29c7caf8a2306ecb0c8e2f8300aa3b8b36cf16922b1743358a541774c9f6e72adc975a5b596dcdaf0067628c3a9ddfb404ba788b65a0d0ca2aadccf41f6eeb2652577d483e2852d5596c59790e91f0a719f9a024984af3723b3ec51bd529be168416db6e5e90c16eed8e332edb863dedc67c83e3dc52bc939b8e2095bde854a297a8b29c7d4d3c5dc80a18e4541a5f69870fca63b194b245aca623747d806e6d198d634c321497179a3954a954756cf3dd068d8a69736b293e9d56222bb1b1d54e7e3c1c4b862bff919e0caa3c06d3a648fa44ac85b095ad3195a621ac4cd1b7424a8359114e3091cba556f7c42e2574cb0c4dac2192a37957eaad6bc6ce6c3d5b002bcae36fc3bbdeb531460169586be043b1fc1b046e5f995e76171c41f066785de7cd94ccafc7fac2d4b37168756a7424d5ba0bd0d395a830d8c167aa337bb1ce6c517596647cb491c7815d1629a0678176b777cdb656a70e3dcb6bd0daa8416717a5739a3ce88bce31078e28e004a3d016e4cb5be08d0721877addf076442fc5f8d5522941c68772205d4887796060b9a655248e04890790591e310fa329aca5c5aeb96d92abbb4202a38f3135d7e0fc383fe44a29bdcf30f39578e29768b9e81993e6067493008e46a019499d4b03350c48de699d4bb9fa0220cd82e2dba95ee043e77b6a97f559303b0bdbca078a888f3579c2a61d2a43247a5f0e69aa8a3cb9f7361d5febe6f56ecf6c4db43f9055780a8cfb5847ba5384a01789853f7c2d4aea0b7c74cfda4aca4ce931eca8211a89954941614f51c2f60753bcca8d5f92d89281aec293d0863c4833cea05820a59f9fcc027bd1bd029de16421a1d5f89573252103e32e544519ee39059dd20d25cc5b40ba6dcaa7a9136759508976af189758f0a0f34fa80efef0225f80ec93a2bd93051fb4dda136ad853a0ab58a29839aa40d50ea48d4a3fa8a2ea3e1f722ca983dba5e2f1c015e656f7fac3b6c870d3546776b2e90bf647a04e2c20625572c4c0d7ea55b8f7b43ed055777569f94d3ed0142c3792fd8fea36522370ce865819324bbb7435a9531711344c54a128e0cd40832c52a027a32ef35cfbcb0ee3e72fa3e7cbdc4a97e0df469c9fc351e1940946490e136ecc863a5e4bfa7112496212a22e23506e38cc400c8912c320fab1ff8056bee62dc86d01b8e63ebc5cf43ecb88b4e0a3cacd9d813069bc544a2513a53863d60c83cb78b9cec9420d5eadf848d47dedbecbc9dfe59d64e5d3cc6b8fc1733a7db37847987300245e99b98028b0f8bac593357ff294f5990ad02e0d32b0be80363aa991bcfa3eb71b778f8b28c906974e5fa94905dac5ed0ce465be814c4bab82416abed6e835d381454e1c1b378a2e8358350076d49d9096956763eabb513563df535384da0b934c7263bf46ae0d87bedb83e8194ea93711a5807aa4eccd90fdc41f15d520735d08b2641d56c89b0a8b98be9160a0c91a5f83c48fe322e7d6cd95befc620455df1773585aba4f502806d38f685e6ac75001f44caff0cc1871e36963c0941ba58565c1bfe6cbda458a0c834aed55e16f39e2c482dc416c9d3d86c3056a30df67695a4703d1223dc5249a7c5c37a018b0c900079e182491e0d16aab7edc59c287dba5c64ecc0272f04c4b9fcc84ba22f579cf4af898041c183f81487558f78689ea33bff73207f4bb681ffe2bacb1b74917ea3cb4a6e204831f2424f44359c350d5e47aa534f45fbe210ae63854dc31a0824e4bc7034c4cd55b8aeb6170acfc0117c94ef901dca8a58a5d404b8428d6ae88d4c86ed27d1556a14ce5214624fd6c795d9939cfa1fdd22067c47c2049bd1f709f159898d99a209222d1e510a4291b0dd5e508301e28ba4446409434ff1ab76b719d5ca6fa23d1fe2ab332538486186565e480dc9f89ce5c9ef6a32da2826d286b5402a0f5a5ff9f4556cd046f59dd3123623ba3179117af145f72595c58b3ee3016a6a72e8379761f1836939dd25fbad819e49a29b120bb6cf08f6ad872649b2dc2bbe77bd6175e810ff7f82e7495b520d5f8692c282d349b770815e282d06fb2d453d6b302fe9a1c7d59bec36935315c57938377d8c49f08511b10870f0cbd4036188068d810e3b9b116e711d2bef747d40d935716af14fd6b29d11711e5577c8831e5b5471ed8be9484bb0a4e5f6631eaebf2c763412c9ebf5f311e275faf8cf137e8afe86f34dcb7152e724ba3eea8020bb11626f043a1c1371f77c6604f0031a96d35332360b44a1b58544e9e0a96c46427227c08573967834b4afde8e38b3034868b84d6cccf5d5bcb04dcff3d155a92696720f255711c8af1c3a24c6926ffb2708abb242365020312cb921ddd65d8e20159641e1ae7a119d1d0dffc4f09846342ce24fafaa872ca0caef33b3f199091798462299e64a180a9df71cf7aa3eb695d17ff875b1e662f9917de52d617aa7d44710d57d813955bd568e60d6d32bcdf94e221ed33f62e8e12fec068daef4f7427f554a7f6d7abf20868aefb134d62820225436c86f4dff9d08cac17bb57db14d0e40169ee95d16132efece25655a65927d9c8bae353d7beafd71dee32cbd5d77d9a5de8f63ffc33114756b5cf69f1e0ead227ee3aa26b2c7524475e9097b6a6e277a44fbbc984dfea8c81ac0c6a463e19c322ceb814d37211d9fd4affeef4df6a3d505bd8fe9638614f799287690982521c9914c7526df676495d09350e481095d469642612ae7974f6314e071dde90d6cf73f7acc0a44aa7894ea4b78e9737fb803482b30c39b00dd6390e83f0e716c9dd1b9b7c1d59d65e92735b2d3c5a22696aedcd66035c8b8971ad5b635617e246fb2a5a4c4823b6792781bbc52ead826c469bbe785dba67e68dc4189085741995774bd24f004fcc206545d93ef39f8d15c1157a8a828d9ff11726f00764085ba16902b1111b6df628855174a773c93fd67c06f32306b9d6fdef6c305a0edbf39a41177b9550b49aeaab2d27c47a9ec63765c1282a772fd7f7b044d365d03e2852efba582a6954a14502bc38b333f2be3151cf5a8a7fa5930ddfc07685115dbd94613cb5d07ef7ebb4754bff6dfc5aefdb41fb595d86f4ee0feed635519b9b924e480bd251298f6b4990fd2057189deb6b8d3be7727711d733b2a35354d4dfba3d6834f49f4e6809784a4dff1864152b0ba3460af9d8c2095cc5101b86224cca15beeb833b82f04bef3a95dbb02aa21daa043d3ff90ba807320bc88331b3b610952416b6d1e9f4600a5127304b6a7c33c34f17d01a16b785ab63f4a4844242b410812854870b04f48156685bd0df8ad1804806c4f6702c6a2d40b2a6562a04786c85d2d769b15edab7ba9bb03ae4d5487ed2d7778a8f93a09ff357924ab9814c47262a598a6763fb4f0a53e6f4863ce7e791dcc89c5320e554db6a54a5618a4d8099656729ccc9c6a6184eabd6f393c8c40b7f88c03606a91ce5de290ea3983a6ea568fad55439d5af5089d64e5a18eb53ad41358292af3412e0861df1fa220704d7cbcb483347b4820f85606bd158be65d2c84130e8a3a6d3df87b60aefd208a9eb258066a4153b3014cbb6cb4a0ab7b281b379eaeee78973b79b3b88e8d9f063093322127a1fcf9110eb3842d1f4a289503c736623a1fc8d5d93808e85d9852a9709a060f6ff88bc0937b970934b8282e9cafce44a9e35c5499dc8ad888413ed4cb7f252abdcc68b1b2eeab1bd32e0b65a3fadacaf62bf41e77380536d4e3fe207dd14f2074e1723721c48be644c5c87bc40027813c12625e2fcf3ec009477ed79159f7503fb91df1a09dce125520306e17bd77e6de461ba964a7424cf4853fe511312d9205a32c7d715c8d1d71727ad9bd21c07435f0a71a017c29b61009bc9419831089ce3b0cb68afe7ef1965bae3b145ded5056984601cc3182bd16a54a035368381822346bb71482e5893342648690124219328804765f41127f8acca81650cd33477f28f1ea990e7156f853d75ab85419c4832526898f7b631d3904b2f4c7603790100246513e26bb71215ed8675985ce4a1c62342da192bedb133b4f6937aeb27a9e202a4373e8c96199eec9b50fe0ba7c18c1242c0ec8a569711a22701fad8ece18b58f06c890fcb29529e9cb249937ce729864fe1ceb5d6e54793e5a16128babd35fda3036f5d21bd0d74645e729d3d38fc22bc8ff158db4fcb73658f3deae0466e3f7e557e7d04fa354856d22e808812d1fbc38240947322ae4a5126c8138299cc520036e11d0f4de8db3df1093d8823354bc68e40ab6b9fcee3197717e8a9650518950fd62fca7d275d6c747fac16e1f858344e8af50c084549d8cedc5e00ef6875c7b34a17ca30f32d32b6cbd4a9a5828983fc61fa2d9bfcfe9696ddda70c4c2cf3fc387cef02397e6a78f192aa57b4369d7c2ae24e4aac37d76abc1c4caeac53ce390acdccffb9ae61b3198dc9ee5c628fc22a051701cd9eb4130f339171f1c05e7a94cc6d68b45d4ca9ac2ddd7fafbad206849ca2cb9cd802f72acb426b524953a6338fca2f928b0d6e3e7a26b48186df92681d648d7447c47bb5e0031fb841e537f963832481122af564a4f76c0038a903cbc08b2ab169627cda2545353d3348cfc7d15cdb050ea9cbdff76cd557a1c710ca54741a78f9b07ee0f873c2eed171193f625385853f36574bc5b4a2ad513d6775ac25c1c251d10ba0393430aa2b68091d24e227005d04e88eb7d4183016bdeb26605c9c9e0514bdafd7d69c950ee23d0a490709d45f6c7f61132058133c4aa024cf554083a38eb185bf9973e43aca41c5691755fa5cf11fde912fd9b251e6c7c5a43a1b5d1bf98e3485428849f441b5924410fdee859d297a0b36bd0d8519e479b7f31494d155901890b4b4549517c19b56a2704fc0fba5fbd13af0c855952a31c4beaad465cc7a00bdaa74ee2fa9fd042a687adb6ea92861ff4e59b1b4acfa78bac4164e61c8d1d19bea06f9302e84423e7292832702413e4388bac32feff821627ac2692509e8ee65e45faa797d155b09f8971b1b13edc5d6dec1705c1a425b44d3e2fa54fccbebfb5b7dc643503469e2adc96534e73959186141490a61f1f3bd13ece32419ce16331f2ded1c1ec7511f8f21100049661c93177c08167d48b65404d748504ba8e4e1c543133e6ba733e1b1bc1face2e12e0a47b094976a25af43e3f349301056d9e1fbbb0437a5dea2f28e8b07b47f3e6e064f61e04dcac6ab49035c40dfc1ec1dfcc3734dbaef1e82ff0fba95be75a8516cc22f1e7a89369ab32acda7168d31fb0e4a90d5e4af7a969e2d8fd5b712dcc3589486ae2e9852eb3b237adaa02ba583c38c7a865486b57325e182735a7c0a65a17b4814c42f2d0a79058fb7fa2f7e09526212b9b7459e625577c0e4d9c5cb4f64a60e5d056401e9e14cd330982cdad5f351a2d29899a73b1f8b4cc6e39d30dccb58a41d2d0672bb9ef0cc6b3bc38b198d3ec4fe671cba84796e0cff30c8562002714361c472b6b581c7d9c7acdc3426754a2a43762368f91c5e769b8e38558012d8a224171dd40a3b40cf0d963b06d1a8177021a8584543ba8029a14a39f648c95ddc59b13a95d27769043d78d2d5947a1cb0f46763ec0668f521726b7d2adb5b6644e14695a7f11bd0e1382d77c4498b169b28fae4fa14ea3a990ca397c65f5e959a0433d0f6a22522f603f96839d11b58a0405b90e1ae0532ca0e63db0e61b9af2e15900f0f6c4845358ad8dcf56534d12e2a0bd2258dcb83e4bc8e441a349aaa901ad9fc9282ba18fd289670cfa4bb326361a61f4d078cdf5ccf8d170c01e52832953a8a0c2a224db56d2a2428af55a25762b0490a6be5847b7be49f88e11512a62100b14b70f8644e014d6a4fab46615a88aaecee7ab29c61b118c5864b28ca9d844d85857bb25d595b06035ad5ccafd8641f583fbe6bdd91dbb7b4837044331b3f27f0a3b50b53bb74dfb7b18a38f1f65ed0bcafe7ed25dec7950927aecc1c268560a3f70863b4443b041820cfb236af40952f0fd7eca41641e6ad859f2badf2d13870654702270ec9b291cf615e3687880f73ef2abf1c46d193a970b0a15bad81d0a05831cc1b1495b533b3029d4521fc399a16b9a35ae92578473242ee0df9054f17070b45414c0e1bd2fcd77ac700f10a82aa9b7eaef9b0100f3137f43ef60e52d342f31cb3c0e9b51a5015a295cca355f158dbad766ee62938cde63f73230d888dff6d19bc48c780eeac17ad5082987cd74e24290b1b4c1d400f6a0f1bfd39be590d80b719a2c637785789f2f7321d8e87635e63fe46d773ad961554276932bc2bfd1c24a2a0ae52da0660801ed24df8af187be53799173d3872af583d37a6cd577a6e3c3b97872efd05080a162b9836fd32461f8bb9a38f0c4428a3bfffb3362247f98cf35919f73932900f074126f1935282b0d53ffc54f56ae7f9eff68d8b80fbeca9d9fcaa6f88c1f8c6ce3a26b94a8101944361667346b8917cf96ca412e35a2b1a2a4c756e60813098291a97b2aeec25ef3bff377d747a97fb28ed68950a65b312bd3fdd2eda2d09c12a04d7a01ce70edc5c08eaa8ef6136651d63f83a923a8a05b92e21773aa765f07a9d43a1bc4acd1ce5b3d759feeb6175716678f69ef1edd2a7de8128bce715601d798e77400957e01e97dba187572fbf1a8e784175057b39c1fef9b02c6817c847e015ef4d468327e5c2614460f91a112f4d1a0f218bfe240c693616d7b0732529ac17f0682ebb8eb12bd105db8766462f805c22e992c050091de41c92c5aefc90fa0809699c81ec992b3b6a1e7270c4ae6a0f6277c8076db203b998f7b3b5587d910c7c853ef7061b6ca8b8197386053602e9c0e4a4ac00b261fb0ddb5fe0b9cc800d005e4d76858003556d98f81d90cf464f5f0584f43e839ead7644b65a81675e322868d4da5baa9cd64876886de1c874901e09c23f2608c33a4c4181f6493a57f26de92a201c4603b25a70a4de0b0149368fb6b770c599ccf5edf0f5ef04b3e011967b61bc8f51ea4f6fb8fb68b4af0770644486527d7790c572fabd11320607fb35202dd09187ee7fa8129d3051b56c696ead4ff5d64e848105a0b7bc425e90b787a6f40b0a6f215a3ae95bc3f0e7383df42142b3b15299cd20029c3bf1cc769dfdfd1dcbb732c40109eca68cb7700172cec111319f0f66241855db0764af6c9af856dc1a1fbed22b756fb55f017d0bd79dba4997bce9264fa3ee5212b4b77450bc94c53f8fe0abb70a010bedf293ed7381a333a3687dd26b4736748a9c5b6fe69b8fb9e645f8d5a5919493b7a34fdcc081e0ffbb35377f3b6e74e0ad68528492d305d3f0f24522e44334eafb32cce9ceb988c8a3d9db4eb2ee511184f926b3b9428a51a370f7104f7ac58ec38ffb46bde83d50195e13135b7194a8b29a1b3da1f74e48419a0b8a4810e230baebbc965c5948c3e1127ba997f974d5ae20c1945fe282f4a0a10538d11005f06067d2d8644044b2a61e9818e28600ce361675f6b1097f9b0159a92d3f9ce12ae0e8989e2ab57ac86065e4be511d9ed41f23c2c06c8008578ae6f3fc6a958d36733bdf74dda28916b6adb30ffe8dd15d578da42b0e251062155f05bc8fecfa81d46c6c56e929ff44dcd298a15c2f74e508588e38a4371c00da618009def46c946438822ef8aef3cd36351b8d5f90e9bc1117469367478a67dd1217f6e86dc52a3eb01f7e2875c21ccd6d9f90f834e3bcbb39e6c109d535a85b0c537ebd114bc5e15bdaca371e0fe206279118158288d2f5caecd807cb31fc5dab7722120aae6fca0e75ad3af03a0cbdc1824a2e6927e8271a53ef35c2d97beee49d8055e7e59e5ca3b2f49d4eda9f63fc4bc1cae850fb16543db74551eaf0b78e9972cb013b1da013fb842afe9b710939658c20090157b452036fc8bebd4c3d5803f91ee6602d1ad3d2a124f6bc9fd5b750e9e1b7cf7247548355ce419f43cbba0e4cf8a0b3e33af20c5a0f96f0436025c0b968e3f97a07b73b165231461e34f3d256a1ec814c31d75b821b1c785eb428ab62cda309da2001ddd26129cad5c2fc3ea6fb022a6789302af472c9e065ea9b7f95d8ebd25e9d5afa31328b19daeb198cf35b021053bde0eebbd866ee9558e8e13443c8eca57145d2b37d61ccb773982c072d082d91b6601f1d6595625b6ed2c43c7fcadc138dfbcc3bd1c6a6ab9353755b8994f17cf9f790c42f624e1631234bc542f55cbedb4f3163ada4c1510a25a52be48512bd4a761448869470e3c35032345532a8ab6667332865f501cc7e1f98516038a36b8b74d24f3cf0f8a3d0843cdf602d16d8598abcc6d65ea767db03c06136d540664b512a093be1650bac8079cf50ede7dfc7dc8a62bfe6d79d359a2b30d7cc67e810943b0199f556faf15f09475c42395e7d59baf4eb34d9fb01850ba2443ab7502349c48db7b9547e0c922e4785911e2a26d018910d1c2a82f8dbfe3e39ec66f6cc2df9a564aa38d7dad6ff407d475930512e320be5cd256150930a55a992b6d931d8aa33320a62106b914144c429020c7821e9cdf608deabc053719aa1dc4e9b681c1b29ca1e99e3710625aabe1d3e4f6253bee1cd5fd120e7dc81bb88eca2aee212e8538d54468a30f94f9c323d5d7caf584a6834294609d51994fd4573524127014bc034a606c6d4df382fa298537f2f679a8b492a5c1c0ccece8ec1fc4a056da97b1fec36f038f7680417c65b442358ee1b86c11bd37711abfd015250326e193b30699e526b00418f849a41ab4a4bc7a98bb19da3af7ff3e85c428d71baa050942ebfdc99ad00c9386b84095857cc58ca1eebc51426e1a6dc4d26b9b09903cfecb9b8c8e2385f6a3e3e5e4d827d213012bf5d05eae75a09bd09625ffc8ee3728cc8a33806d41a4b872fb7a2c79784113a01ec1ca70b64ceeec0a3370134ad8392a645454834ef82e2fe435a74c2d3127bd17be1403a6488c0c6ff41f44e728a0d485c93446b039ef89b079724346be7b321b19f1975d30c7bd4252906d5d7bf52166b926a784c8c48da91263fc51c0f59ba88523d299e7b37af6118035e5193600eeb6e5e3a8d02cadbc86c5df4f5b784515b3b5fc0d38b2c492257bac09aa949d9de22e368326f3139b969895b1cf020610084c0343be00b25c4ef6ed769819a89bf08f6836dd11aeda02d06921c98ecb5236506395568444e4a53f54ed428d30432c731ca14395ae4d49f10019ab38a0996a4500c92c4ea0b421f0b0e4b60b05f3c59f2997352d4440a1c2501840e67c709bbcb535fe5b326075cfe3ecabffe1520262e1747052377ac9a418473d9246ffc8a48cb16779ee65b77fe11b7bea9efbdb994c8e97a459446e9eb46b0f37022069cc598edc08808055d88c8de29396758b0ebeba85805e8498a6de822e89a22d2f6454cad5d8336d700ae9fa49c29e105e1808e6e64710a7d104d9912f01b0b0762970691c14b61210c3d714344030bb5190a83892452b090b509d691dfea5a42aa60d53bfbceeb8551328108de94a9da582874a66ae957928a6c2716a62a7ea3bcd473ce3360bafca9e320b1be811960beb6627ad425f05392be834a40c5b045fef314fbef86da60adf3194dced0b85bf8be7d11af6c8afb52e29ea3cacf49285078db386a7ca553bcfacb50d5e20bf2ae4afbd922a3aa6051db9a3c8176f9003ad0670e9715e660325c1b0351b099fcae12ec6849ab3607bfac6261693cf238bf074a26972f01e6a02412fcebc06112c39d6a440c05ae5f8142625780a21885ca1752ca0bb574add0c5d504a0ad5bf33710ff31ee3a780e2128328345d886aaffd4421bcc1e220eb2ecb1464643961638582367beb4b49308c0886584d7c1205cce2cdf50292e0213588a805288b8a365fdb90d1d025556233baf1c125f2989608acb248980f94217b2fd2f210a9c88c65b206bcc1699302a82098e06b344a956d1070e821b4bf1dcc51e606075f4d94bb12c5549647373ef76f42ca9b98a0d7189f6b222ecb6e2e457978e6ae8e4653e98e2a7067e22124a2c466a0675ab458ee8da86809ee82d9e0fb9757ac4bfd04240baf3dc90950dbbf2e7ef57c17d57ff5068002d07f339a43d898b8e1706250defc3f9d29959a1396fbbed24da74b6980d70e0e06beb6c52291339378c967eb8a7c5e8081c1ef2d0c721041df4115045594fa470b88fe40c9460c28f4eec38b7c8de1641eadd95892d82e933317d07c2d588229003398f5e24869f965706420c6fac87cb116497e5b02b68d0072a247b112cfc8f076432b7c7de2165c0c3a13c6a5bbd35ef0501c817f1d8662e551e0b67ee56f4f4754cec58a1fb17e6912701c646c7af9076f3f4208e4b0ac2a9b7c1a0caa2f85845272a32974b89d0076893c81d61108a880b4e1a0296aaf0dd4c11d4d40ad1936c4190664c2254139e1857bfe98fdaaf5a7746f91ea6f99ea77a827a3349bb0438c70ab4b6e350127acf3a388c85051f404a556500cc05d4faf404c9cda53108c50b69ff734413b9a9d05944898d3b78c6f80b7a074faf518cb1d17332e28d6191955219627a822db18894c7f8866ed45c7e337ccc88c54d601ba85b45a3bc27de75966a6bfaa9f266aca24c2d60562934af5de5f874adf04ba047097fb9e4a309c68587339bbc184019f9e916ee18938770a9b32ba54675a9c6388a07fa123f9727ad6a719d290065885782bd30f255c64443a536d98841d3e605c4cc3d5a4668a0b295011a115ed95ed9cb78a6d4c7078199d2750fb576b214a0811916400e99751e6f9bf47d4aaea6313a1539840d2e5ffbcb5e633199dec669d1dbbfde0469912c3849046e471b2a7f3bba495b6875b261107114c837d5df850acf1c8f550fa20fb3f0a640d217dbc4604052fd866cfb22c4cdef594645af882a03c59be0280cbf7f5c9a0bef67ff512c96aa5843d7186cb2747461c3f47a92e9da144535a7f52992410ec20a299078f13d0acb73ebb38887d7349762c5c45a214b78d53ed64bff31fd5eb182a84c40072a62e699e5cedc55742391360ef452fa27c864f52546cef6e5e1d12c24226de034a5aac8d5ffdcc350fd139bf41eae88158931975c399410ac5884ae08cbce89ce1f6d63d5814aa3eeb229e813ac241ff8468947f8a5b51efa244779582c33a55f7cc8a62f64bcc5d166a912714a4f98c414a4b15935808260aaae8618a6342bb4579d65d2f57fcb222bdd1f4c3b6d57011ec6a1fd16dec35824cdac3c1e5b0022505558b1ecd46a20759896931b561665f18794e77d96edd2b54b85ac9dcb46a472d684454223748372a16ca3392432c8eaa3095e3c2b9fc34c97ccb1411306b3405cd27403bd2cb185f7bdf534e1cdefb00a9ac5b68955bae9d2a916dc1ab229362b72fccd5c728a5040b1b12b96c9e2bb2e15a141f15d2cf204fefac18b811b773eee87276a9724ae4f7b49a54ba163d3150b4ba0129fe33971df9df2b0d3a41af8a421c3593dffc5bb752856851ab73f34ff94d5b36ed0920da20a6a6db86cbffa35cb86b412f1e566ba9d3ade170dd63435fc57faa686b75804b726148bef061a76279fecd92df40c66326762e29ea5434d7e293073791f4ec156123abc0da1f94c869ab52c82bc18763b1a45635a37ac894ca1d21d32c3d84ede85a54d259b3be7f5f2356968bb45e98e1af3e836c67aec54602e28c543fe9189c0061441e374e9f40a6bdcbf745807cb05aff83810e1d3aa09c56b99a655993cc3a4dda27dc240ede393af6b02f7e5f73020401f7af468fd1b356a62dfe03a2e49f07800f37a0bbe584a1687c22d5ab8f1b3c7f88a0332653654a7216f3d109d7eea685940cfca91248c4bd26f00f73f1bf9fa8c6c564d91be6e7ec4ed31734dbbd33ec34391e6e43706f303712c1f404ebfa5a6d52fddf87f68fa748e06546878406aa1f3f1602fab3cfc44e23e37c4b6a289ff88aa3b30e5aea25edf071c79e14e02aed57092b24a727fe19eb688bb3bc86182c44c8278a8060a943802bb3ef97051654ecf300028c2079a8d897dce43631051a08fb22b75df1905ab2e8e41f074582ebcac4f199b977aa55f68881452b7275835ab3c473dbcd3948d68581e5322a6e3bba5a15fe28c3ccc23c2fdbdcffeac12aa0b0b3fd41f081bb25ba248877eb09f6e32c02175411d2d91ad1aafeb51b7c6307c4182dba94cbb2f95f01c51deab7f95463e9fb32fc455daebd448328e135b2665136b1337622b79fca195fa5c5c4bc46263c7cf3247fe641cd745c2f7f148a95abbef284d84e276a4d904f1fccb262d9aad06fdf3b9ca41a10812693098200c10caf183b83047be8581ca6d276118bafcbdfb6e4282d609c59ed62e4f3bdb789dd2affb01691dc95068cc1223fe79f4129d70e49827c31cd9c7b336a995a1f37cc6d09b190d4551bc1aa84548010f0823f5fe22cca31740434590d249847299cd6f68c3aa43dede39532aaa4b8cdad597d77e8e3333882dd409f68443dbfd587773ec034ce7128b0a198246c3e0d8245cd29bf62907321f2223eeebec95bb7f48b80257ad6caa9f3386e2355161a4cd9199565a5cc0ab525ce206efbd73cb28fe7bf3b0f701b97e4e3cf349a35b315c32468e0eec90397c539d4ba001244f1886d03f411f226ac3a68d08096a22f67117040e637d09711021a8372ca74c2310aa27f8325d0bf8129f1fe8df37b876487808a8d6e56c1866ef5b73ef46511b5f2580ec85976efd74f9aa1398e2fa0f880e261c85ce6a504859b85ab6aee3edb7e3d812aa0595124e175b29f8dceaaf44ed92e537f8accd1b8103cbcf9b3c3f872b2e91ea1b23015be11850617b644f2af4f883c0768cbb8f073fe1024bb5cceed87367d468b0bfbc320014923b486b7b3a0fbf1a2938c9927abcee4288c568ec429b676d83a0bbe6fdbd7eaa23703a3b84be34b7142d2bbeaa447221775b73089ea7905428430ab9894830fce8a0ef69b357764e7586be0f1287827ead8a3b09c1db67435658cf7b71f174fa28783f366f49d02371cd6c5ffba0449a307a6cac97ad7bcf1e805846da6df37a3166f2cdabb1f3e204a8a9a95d6ca44f45a4033a5bd429dab381c3d5b386192ee0104939aa9aa1e9853f85951f1ffe63f474d69ff6f1e8039622a9c3433e0b7ebbad89b0718df2c885efd02b156d8651d6a02abe586d2896e18710eeb3a5aac4c6a87f5bdfafaf520c0eb600e3e51d013d2c3a166263945f3843826f067ab095d27560aca7601bef3003eea1185bbaa0e628e2d36f4f5afb08cf1af634154097a5aef3206c107e18ec5c0e5c94604b243b21fb09615d52ff054fe07ed8fa91421af02cb815a8dc9572331090618a5963bdcbb912d785e9d2d9d544ceeb84b5d9c29c71502bcd92f701d285f8950b0a3f1b3cfde1e6f5872b3d44372f9b037a2ec7080b17267ac5e4694aca9a909a9aac29f90ae8689e5c96dd0ea9bba0f51ffc83cbf72cab9ab7331e86e06eef07f1d066e89013eade3da3d72392a7aeaa8aa84289752ee8353e17d6b0faa3b479f883f1c977f7bd24fe330f75bb67a672450724b8591acd5672cb4b6c04f5cb24226dc673b2288d0d4df77d93ae4a3c930b857e6f751dcfbfd80badac0caa4cda0d5da68c906a1412157f3efe08f8e3b82e9284681b3bbd6a9ccac737e831b95da8572c20005e50725bc520493ecf40d4415479a3dfbd98b9d892241677a9ccdba1e0a11583e1e96468016e681486c16f8832a87ae30e43ba13fb4c92fe54b24955a3155e23bba63ba23275b6ec3ae46f232632ccbd56cec7c54ad3ff882742e4494f3d29b7db296de4d087f8b51aff48b5b345a65be5d81e70729b60bf830b01bc59ed22f2971614c8632441c077e8908a596833c0f62ecd5e1777269890625b69d3304002befb5f8d822a520c453e2af0ad0546843883887b39ab1a904914d347d5b917e141a4cc566cebced5b212094e886f18674174a7e1ef7b2ca8bf2c3ff6782f342e204e383e3219a6e776f0f33bc3d086c40a06b1d0d411b39828606f6b2fbc9831bac6d8cd9c850847a3bf133c4caf42f46474f58f26f9cfc49139259fcc9130e5144bdefc1b3f754dd14153d79851c3bf5e39e99468bd766233785736dec7f3e66ff002e59ad24091afe4ea26b91d91330048eb7fda5136a9f62f684ee5ea76c836d23111964b7455420a51563009d939121d5511fd4da588c3b6384f2f694d134e6449c24a56827947346f5f8733454d9c1821cedf144e43655df91d1366a7f30ad129ffc04edab3a8a5c40a14088e3be70b83e070b20b7d9f5f9d97d642e5b1446ea19bedb30fd54d7b949d2acf1d432dc92faac1f165dfd097a130e00765cdb453b87fcac047d6f6baa4ee74097cae1ace665e5286744c0bde3daee2f13658177a6ed81c7a1be6f19f3ee1d1c8518911c8f37d80dd7f78cfc4d3837a4f091c35cb8a27a7f889a882b11e6983064dc2652d464a806aa3b9fa9163b322d9e79b073f710f0a24960f28044144b9665143c9273a2f5fe5cb7d60123a804635d5d89712179b5ee9c1f45a8d7f168ad7c5c2b88d3fe4c0220c97f4a29c258d6fc930d0dac3997324949a0d286396baf35a88067c16986c06963ed656e6d4fb73f612da39dc2bf6701cbdbab8d5a65725419aa2b0fd28d875845375d8225c012f95722aa97bbf16a6820decb2731ab035d4a8e438e737ad42b7f7f70c34325021211b3c5916064f9c88fc345adc65e2ab2bfbe5a41416d76371348b258b414ee177100c3aad2276046f395f6526a5659a849da4b75b5388e8438b16ee0f778ed3f22c6e452b23bb4e8f4812ca8013e311fcbdad63e904262241160090a465eea660a11090fc46d3da545ba3dc5f289c22a0c6d7e823eda2223e5c4eced88b2c228bb74a063c27850827cbd713d8b9526916f94a9b50ed50c5e4a5c1220ab3a465b2370956c65055cd8df44da833737751059eea96843e9c9de78f1c13246bdb79c8da9257fe8a1d0a8080a203d8d706c30aa99e8657b9e6de70417d0a25e14f21dc481dcc088603d0e1ecde16dd3e500f9551a69c2fc8591ba66e816b942fb47562affae7e3358cba306a190d4e4caaae081f5410f4f3f96d0a095b9748090210875324211319199655519329485d82ef110aa4dca90d71ca2062446a0589eb4056f92aa2c25cf87c8c0af8aaa74744ddaf812567884812fd066d417d8821cdb2f3f6c5c508259b0dfb50a82f31ead8e425d9a23c787dadd9c70590aa396029291c10d79949a24255a8c132e4a7c2a8b86eb2bf9ebf1d89cbef4c79c39d2652051d895f451c6b2a3b3c9883019590f21f252816188756cfe95ee39c5b691b53926f91559c1c588f49b482a5613727a09f0751abbcd01ea1e152b839c559cc2f5ef537c8083ae8df6946eee299487a151796c9b7b9e7ff7466ed4ed299a1384487d9caf15113d898d426d48cbd4377216019cd6c3d1433758dc3b53992e2b4ad951004b08b5241b1fa78793df9bc899f96056b1937a0083990f2eb2509d701dc1e4e6e9083556706043416a8a4a5cfbdd468230b8a73c8f7aafd4f83089ac2d149594b7427e931273d368a99f284375db62868de654f33bbadde6af7ecb4491e04cb0b1d3d53130f588fd6729d2f57b354bcebdc0e318fa21e9549611958458432b69c8660ecfe110ee0c8e4f3ba68175514d8ed9a2a7ecfc7fab67f730bc66a1e064e2e541c8d151e22261c8c245e5495b1dcaeb9e31a3035ab3db3e7ac16b525fa408df93780e8d8b4349d24fc95dec93bd2160c848c03da156e6f5b2050b2e21c596c4f9e7737defff5f71e152299939e2944a9b7f6f5af4fbc7b4dac5d6b73e2458713e7354c8e84dfa61603e72024846382d5d55f8c48889f8ba2135dcd2d7468982e62714cda167063571555b08934dbdd5bca9464e606e506e406a57b22555df3b4e6e9a7b5141f017e81c948a3e6c6d3772ede3f58ebda8a24037f61ada7d653eba9a72e2a2bc5ce6c1437931cc9cd2337bd04a2706a53eba9f5b6b45a9376ad73d76a8e7bafa79e76e90d8f9142c3c3e6efbd156cbedea75ac1deebb5706fd78b216badbddd7cb878f0b8ddea2b85abafdaefd5b101398cf6cd851ca75d4e1c2f7150892591fa6f58dc4cea288d742b653ab491c0be61e9ce8bc283c707b5d55ff0b8dd3e77c37daa4ebaddd03af371f35cce034442b225d9b6c8314d64e0a20c1a94a22946605810451145174bc8f0423773ebc1511942460841c12106e708463838629b2105375871c3d9809bc788baf28f01e84415a4bee1d2db4dc8756fb2ae2008822038546a10c49824ff4dd34716b8ba0982dff7a5d296a497ac2d95ba4b25d00897390f48d6765da73251cdb75333b27f6d5bd3e04af72d211fed4a1ea2994a44e00ecd0ed168a994d775de4ead57d494c488884aa854ecd49a2b3c47472e13c18a1d09bf0dd867eacbf611186ca8be52f54554246385f5f1b12a1f9e28b07d127adcf46a61305823a93513a8ad4e5257b518d80c1938c84dbf91a2e5464667be1fb6c328150b2a94c85655420c604fca1b5273301792d22c16cb3b25753b0e08900ba4c71378092ab4f0e19de72dc05aab42c7001516505fde933378c2078e03de111dd434bcaefbbecea4f14154320a6ba80f023993fafa6fb2eaab53aa7ada18159216ba8dd308f52e8067cc3b0e553d4314997a1caa3e6d916ac7e350f949d6d38aa24da9647a52558a1067aa9441214584ec89f1d6a8020a0bcea098520685182238828ab8f4e034f23ea8c829c96954fa225f92284e234f4cc1bbf158118186423d213f4625049ee48b6237628c1fbb60ec823f26e65d609da92731a942d51e1e1393fd532a7f113da1543f37d2ac060b54357bf7d780656ec4a84c1caa6a572bd8f1077e144675a346f0ac05552a81d12e3aca28ce387ec7ff876fc2297dee4cbebfcb6ceb8696fa1a5fc7cb80ff398e37f335009ffa1c8f42cccf9444663ee67394448c7a663ee689e4f8d4d7136d5a93ecffaa79c7fbef08800a009d46c58f3a0c2f3033aa8601d995100fa2e6b493b6c141cdf100ea5117028d8e54dd509176e5a47354d5c61f951305aeb9e6d4c73c8ed22802f5bcf145f834bef84518973a72832814ea511885c2a8f1070a852a31aeaf53fe2e2273d49a3ea944d83181a7c727851f1580044915158d465e1cc6890a6dc2bde2097e76a612f8796157962b1730dab119aca502cce50876baf7594095aadb71b3493beb588cc8fa77e4f2f5554960817dc32b969e6a85b66dbfcf7ef77e0de22e8c46aae483a0d7ba47471e71a20873d8a303ecdfdc3f3dd43b2688e0e6f5ac2908190f32996c48f681eefe7df78ae20e1cb0f8a2eae6f01377e0806f46674a32597d19a0be5e72e9bdd6bdf2b7387ceb4bc311c269a9f4e28b256a24974a2f7253c7096c672b5bf258995d0d8151cf653ff25a1037ada838a62c2a4e78a5b63c57eb1c4b6493d4726010d572b6c5b226b072392a442553580a4d39229bc4c2886c6c8955627ad42a2941a9381f121507069d6395d06a4d1cd56c8bc702197dc63ea94daa29445d29e91c2bb349ce8585627db04a6ccdb75898e73c77df8f70c0f6080465a4278aa2288a2ff6506bac0fbdf24f02e702cb021f44261aa7ca7a2093b02cc868f9849579cda920e30bd702751755a8ec4474ceed627c7f37aa2f512613cbcb8568c5e63537b30419e2a6cac7c43281c5a2c2536b589ec903046765324f2636a9c55111dded7996a70624013fa1762f9247466bcd6dadf180e00df6913d67cb0b1e350ed0d25856d7e170f138dd7fb69d108b659aff2489deefcf19a82d13008581ab5d390a822098419d4f092bb33c0c89f5efbd7508dbf737651e5def29051de0995413fc2f2b63073e94827921dfe504645ba91206045f30469527f8b9830c0cda55cd99000888f7aec2bd201886e11886a3188661e872d3879b3a2200896e92a1d6a698919e456a0f5e88e282992b6791540bceaf9cf11efe2800dc6de31b606ae673541b7f9917f0871bc1b3d6eb3cafb3647a535f9e3dbdf1973c76efb523d5c60a26a1da78de08817e9d2bb05591b955ae25014e60b4d21cd07d2a0716dcba5de16188140071b329b106113f5c01620c2b5aa0602a5100228d40616206453ce8228d2ec440411b66305922871c3c1922cdf5d7436df9949496d2525a4aebb4745aa76dcbb7da751d6ba4c1d66aab4fc9a07ff5d7f15b83d8f722b5df3b8e30d439293d7a875ae6a4be4e9d7363d93f33299265571fb97c6e2ed739d9f71d68cbd2a757fee087d7bbdebd4f42cdb7ac000df07b57f57d7d6232954066ce73cb808e7233da51d2e974818a81aa81ead339bda46ddc8c2540b66f967c20f82de99bcc7a1d50cb723224a054d3615057de496429fcf8f4912dd7b23128a8368eebde9604204046bb763faf4b3b546bfc7930c13d546b1c0a1230a82d97758ed38c5cd64dd03c0dc31b23fbdfb6ddf67e59da868a8343c5b1df7299d3dca849f692088d6a9a514d57a3ae1cd73616c6032fc36dcc4ad79a88a2d4a935fe34db5dd7f7de94e31c3783c1a14d5f357db5b5fe5579b6a1c964baa0c95ad6141d45e0fb6875d1dc5d1635bfbc3edcbc71ddfb82aefbfc77766898c9400cd35a23969eca4c21f0bd9edad6c880301d93445c5a5f27cb243b93fae2a1b6cc5ef9832526a865623d3585c0f777b081db9a3dd41a1fb28c74018a05b4204280c00003b14c98f4936e22445d79cb92a030a9b916cf792af3d432b14c401004471b2a58c1b2877002ebba6ec6be0dd87a75e6eb7983dbb09bde2ecb4d7135e08ec5c858785566e7e8ee57c666b88e7bdd3f526baeb5626db6069303461de63087592d2a76241e50d402db47c5eca7da0aadef7ed3dbefbae28400ecb62a1ef72989b0f3a39260829408b40d4fcdf6783e3cdfddcd532b95e1855b7bea1d962bf4ce08cc852b2b9081614392188f293a3489c2081f8a68f0bcdb22c0e2092588b03892048b7a8694283bd840b4060b28f8be1d1004df2b16470cd598d8d280e10c15bef8a1072990c8b20588d39fe53aa940bb2a95ace96d188662188a6148c3baf1a113fa2987ae2469ade7917e6fd4286fda2684dc7d60650a1c286e489224ad0d21a79a0da82b77d53e9022bf5e37405c2e97cbe572b95c57c052f57b1d00d97f487dd57c244f61dad6aaae5cd92d089708a737c9ecaa4ef98505a7b936c47cc5b760c9f308a78f046016cbdec2f3becf45d5b7bc05e3476b960673c03d6055b52b1308aa086a096a9030b2d836421e6dc3237be0d050cd0a1537a988aace1f04244081da6a5b53c152bde8bc5e41b70b1912c446a56d544cd3f45114c5174fa2781a4551148700811fc8838808e692a406b8ba7944d8c6d0e77d1e0d8c260068609b519a2437698aac507d5d990dad33d4c268b6c8da236b852c0c8ce1ef917ce5512e42bbcadf167208ba8ca4d63c2c0bee4adfa2c53ed152ab59580906e0676db0e82a087e1ff8e9803ea452a9542af5682a26879e988a49a5523fe45b99ee4d4fc0b24c096d7a0296fb8df0f88d0b1835bb7c73c0f651b3cc590146cd9c937c55a1d668f13c1b821ff6fb3330fea800cbb4082e33534b25944c96f1516b7292c068bdfd7848aca5b9cfea9c5bdeeeca5a6b58758929401c711629b530c5f9bd27f6f06c77bd6ae31f82338cb212505b15e7b640fb6d53697f55ad045433a7b2dac69fe68f80ffa935260d0f1e0fbef73a7e242709f7db00ac038882ab8de23397412c168bdd58cc85ac505b9d46ed18593b46d68e91313246969dd69a181367e23cf8132fc291c8fe7ebdaef33a2f168b72bbdd6eb7bef5cd1402777dc5be79a55194e911c5320886891533cea022a318a791fd229507379ce21b3947954c28f3b1d385ee144b23d31b39c3cff3c4efd16a6b2cf5d57518b5d5331e629506f08c98986603a8d6f070829f210c18adb60ad4ae69e06e6e628101f77dd88d3fbe4bfe036cd93753b65330da2eafff7b1df77e646c0ab73477034110fc40cf033fcff36ef8852153288e27d3fc2749b091c0920d639b0ddb5e05d8b2ba6ec74d2ab40284d129f15ccb38c0fbeebbf2dab2eb881250034cca5439f221e96c2a4c4871747a5ee070a2660f353a22dbdab13ddac068e7399b64a3388ef71f921fd51a3130fad9320ac272e7c01ca7da6ceb03418cc9cff61d65b7e5efa8233a52e2385e4e18b8ba39b34923785fddec94b8e91d51176303d725c4c0e55c57d41175b11fbbea01462b2ddcb1ad8ec877783aa2037c91003370add68e9fe77d9fe77d9e677d5c9a0843c85e3f5429bf80fd2bf8795dffb558741d124d77bb92c66fe99e6df6762bd45d79bbe518dac9c8d30387fb3df51408313495c0533982a0883149fe830e964413ae5fd4d6e915a08052a791bdc9a8abc664dbaa6c0b37eb835d79efd501b7f3a30376fb75ddd775d77a2ec6e09f24ed0cacd95a201c06ed4c0794d205d2ddc1c3edbaee7e909d244db0c5064b98c1c40d66b8e174233074b842062838882156858674075b3069720513a72f31458b2d5cc4d0c4ace72370cbcf81bdf74bc20f4aa1041959e8e0871b5c61bac1931b94e8428629639cfe15ecb6a5922d95ba5e35886658c00df7fbee053fd62743977668a4699aa6699ada564dffbbebba6efc4cddf863fc130966f4d320fbc517651c7116b93fe8701af51bc95d59a61346276a85723a042084654ef0d353bbcad51aff0faa601b2970fa01952430ea52bcd5b2ea2e5f1d05f3d5634e7f4b5146007c8e377df85dd770fc0d00945d9b2965ca6a573aca5a9ad6d74bce12b98ec751a25676a3446d514e07d932dbb2527ce51f53a2964af64f952868ad64ff9712c5a812b55bc85c4ad4629189650ed508066d5b1fecb0a50a1143207183a22baa5882ca4c4b142156701a394289115a0ce5a086a131ce1e2c5e8003285a2843072d4e5beff51d6ce092e7c132cfa9733c1f7ce866a1c9245c1043d78044c8758eef02789ade05d619bef8e3a3a4cbf649d531ef71a4ae7a843d43ad09b04a6c84b057fef8b8a94308dc5d1f216de3550aef84a456f808b1d952d282a5ef2b81dff7c1602722308b659af585805c6b0b5e5061382c60b465329bd18a737265b5e6b9c06e9d14c964b2db755df8050862fccf6299a6089ae8037350f2011a44b6639f1098a8eb6cdbaea910b7d6ba888890e43ce739cf85a95caebe6c6072bf17f9ca9fe8c7cd86e57c8b0cf8b69ac9e93aee36cfbb1702b8fb98ef1c76251a94bba323378bdc3cca52348423b9f982a260fee56bcd63298f63898adfdf1fd62572ade82a37082855f55195eb981addd631a54caa4440ae55e41795e760645e1ec7d79752e6041d2ff32890248e274b99979779232711f27594322fa58c0574bcccf7e4f8997ff99932c8e8a5ecd1f13265d08dd7517a8eb29ef50c6f3c8e279fc88dc7910b32eac1f1379efc7a12c1f137645ebe661470fc8dafa3cc4bc9437e04ea499628dc781ca5b545b5c673289c9447b7b99dd269e9725d8a3a12daa53554a14e845a190a82fd1b2a99efcf3bfeb07ebfa6e0a6df7eef3c7f2a778203a273ae0adac67fc8e56acdbda1d6747b255a6f4070387bef354dd3344d962b974b39cc184745b0bc491263d709ba465057b821445808245d4757ba438ccd16d201c58f0ee817dd743731a9b2f66b1a56ddf1bcf44216351a52ada74cb3ad4a43526b409c125cdb747481b3a58906c3a25bae1974152d45a575ce575f9e185d74ada4b67c600d43f681dfdf07886de1b2c14601581980df96685d237b89f692ec65b54a9a4ac39e2cd18aba6c5ad3787097ba4b0f84e7243eeab949b067d49c54cdca14556a694a7d45d139dffb3795faf27e74295718e147e9619e9e8a3a77d9eea337ac737c689efab4edd2eb38aa4271576d3ef8c22e79dbdc5a038a34dac963c8b8dd6eb7dbcf0f08fedf9266f5e53296cc94e1c080d1ceb9cb0b75ee6402efc86339be4b79faf17bb0cb6b698116464f0831a5969eaa3309bbe838818918f5887f7a22e18f4f44fcd3a36deb3a2fa33dfb2162d44fe4f4e257eb325df69c5e1c3ffc24a7174f2a213db8c0b720a3a04a832d8e2863861bec0c4ba3eebb1205db0d7e97d648ae37ac0c963e5c2e10726814c14310471ccdc020aa418634d6a8d1aa104167879643bd688b8f17d9868891c11445282122891d949c350c308e20e38a188c7164ca49c44996140d2ad440da3283501839c0218a273b1471fa7bd7b22ef0cd0fc06db3d65a7bef75bd48114551bcf7dada9d4eff9fb4edf7e3085eeef187774be07b3d3be00170d0a9ecf76ead2d896180fc927b7ae54256c00ee386f8cce61c678b65a3be7ad039e0fb87a067e60cecbaeff3baf1070f524659b91e8c760b2a37123efbd81872818ad3b580ec902c6358011a9204e656200169b1f7de7107b5ba80fdab113eb06083346c604871d61d2c51411618d6a812440ca77f05ab4da236050d7f9ef77d9ef7d174f70311d2ddb52cd2863f572d44b440091938f08005248c3469e209168e68f18205191ab084890aa8489979e1e4ec07625b0da8420c2e7041208df1c3f97eafca7393c0026ddb2efdf66353603d53c9fb12087edff77ddff77dafe3f7262c9542971093e9de52a9542a595bba1f7e58d65209b42d957d1c6f6b65f71ef52c9fabd616ad9a4ca2ca87affaed8d8b13afb4a6fbb517d2d497bb773456e0990da375e6e96481fddb094b535fb6d5547cd56a294b541b7f7513f67bf43ebc1747ae6309a86c7aab7a22f4a7a96c29be9a11a089a7417864fb5d777fe67dd64c420d70b6dfe51d33ec3d4a038e3f4034088fec7d77ab7b5dbed6767b5e09deebd870ab70640ff4bebd366121249ed5bccf63b566466546a54aad7e45f65a9d8bea799ee7799fe9a67d9122dce2664b8a8244946a0952dba1e9ea6eeb16db368b363c9807f3905cb67e242b0c6c592cd3fc27491216ae86c026f23b4996262938838a94b418711a855f844504164c4ea3d2a3f80a1e90429eccc27c113ef292b2bf3ccca3b5f6d3799e90079301f7578251c9f49fdec8f9a27a7998ef797998ef8729838cbaec81f95319747a980f72f99732c8a8e7e561ca20fc306fe40c6d5bd0248edf2ab4cebaaf675090510f0ccc1904f332d7c793e9ca13faac7655cf6a75ac5da1480edf64cf7085ce61580a0195742d7b548f76c83efbc14231046aa9787b645be00f75e56f94948d880245f6f72639049d51cf52e1c1ac935a4303ee4a1fb0a7c48b95ea59f3e92b3d35b02dbd2b18ad359eeaeea2a3c8c0e17043381c2e8b0ab5c6dd1d87c18f05fcf190c9849a26f37a408165686fc9a9169d2bd83fa60aee1a0e6a8e0d7d8404aa35feb296b54c2693c96432938b55845e541cab313386048218ffef5c8f99313316b3269305c40b43389c41451670431451ce972fc22a02ca91d348fc1622076791d40ee74b6944f3a22b53c57d69240e3384e304eea1f1afea03554aee80fdf171b65c6b389a4dae355c2c7bccda988dd9f16dd943b7f4b5964357e8de9a4b59024bf09500d13e2afda8eaca3e8a67474747a5253aa9d01d2fc88ec47be8bd9f6c7ab475dcccb5d6fad9d429a1078f19f5e0877922a87f7922f8617ed471e2e5514f04e6f1cb5814601e7f8f32b63ce1e5518f3f4aeeff669ef4b1ae7d39e0cfb60a8451bda8825429f9d644a9c10b555809553ec491ca637625d6d3a46a6c2abde8e64aadafa9637b8995b9e95f6f3fd6deeccdde7b63b19b0e186e5ebca0ee4b79bdf4d5bd3ae1bd65607fcd4ea86b859ad6b496ae087e3f7e180451ad55884c2aab5240e9ab2b971e47b68fe2c828d9b11cb21fd904d1c31d022484055cdd74416dee6f13be175f1a968f1d13fc765fbf71e988703351092105446791dac4113a4091c1f99524f852f1bbe900a00177bccccc30ebc6f5e1b29d999925e11222d97b597d240b6b6da5b16042f55593fd43563758faa0efc30780a2854aaa3f7fdc74a802553548d8c572f3ab7608b64449270546ebcd5eef4617f8c636cc94466d8aeeeeee06418c59f5e57fd3f4d34f3ffd34fd47404da8a6834324d3b64fdf230619b99441635983c42edbf35cbf6305d8bd9429c12bbbc8ffcbe8a34dcb3d044edd70fe28548ea3da9179c23dbde669c9b9991ed12b7f4cbe697a94652a519cd2f8e051d76690fb09af445b89b1968ab534b442298fd78e664ef3234faac20ad93adce635b2da7ceebdeeb597263ecfda5c811d04bb9b06a682a4a44e0abdeebbf77e5fd209033e8191da02d20f5906a418d268c9da493280410ce9079996ce75fa5da0e2785d9ada80d224b825b258522c75b95cedeee48df949492e312089431e159ed775dd1533ead5c44c7312bc1a0fe09429f6defbd56aa520643cd86c3e3eef799e8f8d4543779da856da76db9905ac08298911d988dcbd443b5bc0b5d6dc9ff9bcce9482e3801f7a9e288a372e1f3a22ecf8d8df13291a699ad2a434290d0d4d4a93d2d847692c4d9ae6eaeb943d1d783b0059c85f0c35dc9cd4977d3206d8888bbbb81f70b6e579a997da56ad35ad29089fe5628b1bf9c771eaebc3dd2c884b2fced3e2a5593c2ca98725fbebcc66336b2d0d0b84baeaef342da561cd716abc4d2547691bffbc57a289aed5b57ade7749aa31100631c58f3a3dea47c8162ebb862ac10b43f6b26f34943d46767bb3b5da5a53ded7fd0dd8e6d0bb737b7a72ea4614fc3c9548f0bb009ea7ef71851e79c838964145cef1514a327aa324b9891445094b46ede1dfa9ee91cae22a0869ad21b22b7b46f61f2d1ae88d5d59d1ac0a8d71e4a6839a0dc5c0b39d6a658b35bef7de7be28d039190906d7d1f68c9c0d123077cd3b2865003358084ea80dafa013ac386b36266435d9d8173d8961fa0db2df7fd3f8f90100c053319e4724040b91c502e07823d6420812ecc77b080c18cdecf7375bb3beb86a7a7d6cc9ce82e0c8674bbfbf46d829acb39b62693c9640203db3fe2301808d9ed3dbd8347ed3848b04f058b6c364ffa1ecb573a12989b37601809d908d7b3cf9a653299ec2aa089250e4b826d403298ece443305fe24a4493f86084d586f2023b50c961335887e9e071985de584d0009751510e2cc98c8a4a2d036a992c67b2a03886e11876ade90ebbc3d218869dd93158866ee18e1a6054379e4ee3e94483f8fe3f29f03fef61449d1c94de84b241cc8c8ac0483ebdcbbb7cab44375dde73890631eff8633c7dab7c72a7a0634fa57044e5d309675ccabc7c07bc0ad000cb94e03d7eef71e9f2e0a34ad0cd54ea63ca7a02ccc7f4c07c4c49da95cb7f1d47181f97303e2ebfd6b8946810339fc2eff047d50add06aaca61990298eb582a9be0212b2e18b96007596ef041a68ba32a3b30a1e48a1b9ceefe04a82b7f1bb015826318156957b5465557fd3dc59457c0ea07e5e20b344cc3344cc3344cc340767ebc8c569cb5358a2c4cb07016f12a48a751b7b5ffb71eb9d96a088cb4f303fe097d9e1e5481ed43ba1c7e18fea81255e1873574f1f3efbd2721ecdef3924ab6be9ca82d2f495df91b1919616f68cbec4d666f8ea4d63889dd6cd8bd773c0269481445fbff04f7bda24c5b1ed67c28d8b3e186db964b6506f535a3398e67bfb928208511354011e5891853a46ab6255bd85002052ea46cd016e97adef5367046c5d20d795eab00054b5bf2664908eeaaafcea3abbe6ace79872ec0c70d49de2cf9d911e1d539a5f7f7515fde0bd9bc8686603275b7dd47efb000d996cbe55201cbc5c97e638bda14432f2b70add55a6b3fd0ff561cfbed1ea1cda8e46e977c56a29111000000800093140000180c080683c16058402619ef6b7a14000b5c7a407870409988834994e43808829031c619040820008c91a1991a0b927611d5b519b12db6d136948f1e63b2cd2622139e3930147518ebc767e2035b2b1b847f6bd4084a25b1b1c12240d2725fd8d8d3760ef39c5aecf4dd930608db1466715eb24c79342de6f795671e2c1eca094a11bc90ff57bb121191da2c8a1e504dc6308ec358a7acd48fef0b82c1ac7d5ebca90555827f11108a25b716211629ab11a623ef7e0156d82ccb8404384d7da26e84034ff6bc6d2d85dab394f6610ee07245e5bf9ba761b1e5374fd1b07ecd9f38f55a43a5e8d918c38e3a1b51a9678bbe9df7fbd1a703058a775059369a718cde5aab4af9b8d082535507100c8858dbe589ed3a9b2111e576c163cebcf6430d68e5f066435ea88a0e016c5bdafc2d6f8ac7fedad82ac65af326773640751c7db72727cf517c31ceb8d2303045866bad7ae5a15610b00339e60cd418e9988d26af8e4facccfd70595eb8c56735e3613b29d342aa723b808634578a2ca45d702ac51b614e76842a8b55e04eb34f33dd21435e953d979dc5bd152c9010a167d9832211505169d52386bf1f15db4f96b275475c816862b30ee6d06f612b0400addaea564a285509178574e09e9e0315d20455f5cf063b7752dd230d16b239f9c8aded8d8e0ec743380bc745c9da0605b097d84aa8f3c237245625189d24421e6f51f468232462e3642ac839e5b95458f55db9b999d5a581cca0d05766a0aabf92463438809bce890fc8d9a533743cd869eb9a49d3cf8ff875718ae3bb659836adb3c784e6b67280b3ae1531a8e955ad529d07c83002168b3e1917738defb69f6090c137d9a0508dcb4ce1575cc882dd8dce7b7888aed44412e7cf32aeb265a49730460d3f8a8dc7bc9868dd4f1931a63b2974ed442824c8432127bca588908bd39abc9f3864115ca09b75c4d9f1c5bf3f0a1def0057ee318409bd3a2330e1e2ef1fabe46bd29f655293ac58d4b937dda4418f01ddbb763ead7487d9496a45562657dfb836786c61efd6a0f534bd578bca4cbed208a6491e88fafaaf5e8d6a7dd42614a57b88f79259bcc929ddc0a1455b4b4a1ca9909f32a907ee264a57b5116f4b673725b2239d91be65adf15591f20254db70f855c2438bbc6be777249be7b55e1add246c3361c83f34d3d30199bc3a5693f4706ccba55e74e092c8cc865eb31943785c4292a410159d9ff091b081ab701eeb74b2b3f67171f65c7057129701a93346e704393a083a2b46805f178a7eb169154e690bee104692342b229da3f7359ad1e2e36cf49cab9413d56f614db02241b8b40ab02383901b3035333903a9b1be474b240e5836ae3c0a9a7a8395e7e166a579c50d4cd86f788c39b11c086cf2f59f8c4f82aa27f104dab6044a558f08689505a7f3f282fef3e5a5aa645574a90204b85f73516117786776a68278fb9592d7d28383f52366243143a1e6246d04378fd7706a3ec694bfc7b72971e9635be66e274708b852172c06d6c5a0509a20cfa597f08bee503be1456c9d6640ea1dedf278c937376f53306e1e96598623a33e3ccca01905c3bf8717eee55bdb0ff60d2132eef0d1790c128065cafe25cc10b827951cb326a9f5612f2bbfa7352b2c05724acb0daaf39b389c63b7149986a7399a3c8ae8aab034ba4fd018efacbd67d6b6e84fd5ceb4eefefdc4b8744c6049f661d7ca57085db1baeb1e8f9378fbb0836a412fce6104647e1dc354146434421bb6da0a5a95e61bac4dd8f8dda89438b5eed065f3f12dd5cca5edf2aceff2220a99b005560f68b37f5463e16f9a550357d018eb001a2f77baaf8cdee325f6f7ebcda9aa454ddb37a38d84eac316fbfc2af237337ef6cb745232d19851f96320f5c37225bb62d5e856957bb9b80490d4fb6feb8cf4b3873ac404309337dcf90aaed450a9e931fd20a4082bd368caf05880ec3de6718acc386a191697caf0496b65883f88d56245f1a726c83d437440ea60bab71b1f35c49a5ea3faf2bb030254faa9689abf33738fbbc5ff6bdc2bdcfb11a96c5d6a4b4867cad151236b4f8c11d78524619e0634aae46b0609d61121225d84870eccc9976d6686415dbc5519ecd1fd50d6375a215437f5b0a1aecbb624a74dbdbe3279aa362208215173c435f50386e6e1d5074b6420ccd390994d442f4006da8230f6200d4dd20a9528030638191b9f009c7dfa461bcefee1ed4020e95204451e5056bfedc271473e016609309adcc6d36c6c0acc5d6e03171310e85b5eca88db2d89ee84b8c122d9cbae46ba0318850c3f20fa6b0bc2d44082118b23a0816c7c312fc86aaff52a57a93843fe62ddd71c2d5024cbd9568bcae95e97df4d2f61dd0171900b981437561be12cf4122ade5ce864913b5eef6a6ad280bd1d22b7b2ab21581bf8cf0812ddb8f7780c4723d3a362269900837f6bbebb79a5daf9c72c30516a484c23c5e0ac77e97acf7c22df568ee342a04c12f39a0bc2b9fa0ac31e532f15a54f18c86f6ec7810fbd8e59d4db6f370510d1a4b2e20f48912a97330158f0ef925106e11b66784b795f227d2bef0460ddf72b8378fb796519429fd0016ac045ce00d88fc6db09ff048998cafd38888939d0a09284a200f3e27f00c7f5d6ba986640dc66a96a70904962a5aafe1768644533dbc5ce35785471c381500ea8bffd0a1b6729e0aba174f31a306902c6626dd8e673c783eb391ebec219d0e12b444a28c337d3605cb932c1052e032c0ec3571463761abe427042d45e7c5276af20fb654c638a374ab6f10cdaed4ceffbde85d6067d8c91975aa0b1c006f7ae27ed0e36f80b246ff4f8111e9143848569668e8a9bef79dd6841f4ca2dabb9ecbbd01159d6f5a8fe80e167e8551d67c2d220577553a81a5acfabaedd9cf8c76218184bec4274ec59c56dda5a9f8b2e80157897016f497e923793b52e1a38a2ec85bbfca96d34f9bbb5f04412b038a3d2e93d0698cda9e2ce1ea258e1eb7eaab1130a1ad8674818b9734a8a58909f6a57ac514aa8c787bcc76a62637dea54f02893b02f0f7557badbcca661d2ac83fa2c133807bc7c52aae3efb134a5342e38628a69313ff1825798de5bbcb6653af5955feefe94a6d437cb95e74536faf3888e034b2838b671878163f3e2bf729e429272841dabb2861f802252f2b73f2809b452eef4f91cbfbe2796f5f8033beb5fc01c7c05651bb1b757a7741c667936ad734ef95c28ba1ab9653883db0d366e625f97110c585e015fbc00cfc31d9e6237c30de9d90b24852bf49d01ef8171696d37e6cafcd0fd76e90e871248f79db6dd5893cd7b9ddb0d22d85adbd550875e6f7aa780e5d2139273acce07d4882f1bb88831acfe680dafd0e82bc8e65854fbfa41eebef576d920884095b9a2844b05201147373897228f89fb4c82ab965d92da9ec1f294e94ca6637fdb9ac32c297a8dc94c14dccff86ef8b521b89bf52eeb047775832aaf297d1ae5ccb22e54d5167a70b29cec7e18316ba45d52ec71db154171892646f96ebdac38272e5bd571860f643a4ffd62b6f8a01c508088295f9ad3fb331bef9bb88ab3b9abc8e069d4196aeace59debadfeccfe273967415e03091c67d10a8f7c459867bf0fc2b38b0acfa8e42ebfaa4e8be1e0899fdf927679d8044970543e67eaeb58ca5c8a707a9226d60533634a4408403f90fb00682c22ea106d5fc94e6cd82af4b3870bb8a1b5ef0f9ac868dffaade7e67585a2349e0d9a945762ecdd9bebf940d6a3bfbca249f411b098cc9c7ee8e8165bf43aef5eb929d52aa83aa660f5f1367ea7a8da5ea00138166b551977b2e2f7e2c6ace7378d5c8e928e6d159f6d8f16e693bd38b1fd1bda0bf4ba372803e35e0e441a78c225ff9fb5806793d1a0dfaf2adb16004b234c7b99d1431e646bfb64e0b3e3106409913650e7c69e203cf051a5d16e0fd2f82f25a86581bafc65acb2fd2866a28530e4e21fb680ba70f01caee8d0213b9dea800861a885c80a01243ffa8bd5488b1bdf22c84e1d2500fb1bed5f77c02b201b4d7279d2bd56e648e6cba2b795c6c825752e48edaa73dfd129561838ea20d87a1971aa3c65e2e557263e5c74e246d2b773a80db9806cd6e44524a0db0227e4e7acd05173edd59695b635fd828b7556f09c3981df32f89b1729c49e11d2246626c37aefa2392e7498c55a304c09667c2db7ec8d3549487809ea74090fecc7a82b462ece4cff19d0193477852f8a2524830af7237eba2aab3427012706a051cc901e7472a4a742b262af4eae78b4234cf13b390571b0bd86f11ac99f70ec5600d8361ede56d634983221c4223936845c8062391c0dc8bb55d5566ac919afc7790108b624ac6bfa6b222b975543adb7fac5531b567923c3f0e55174d1773e5259f86c97cfe9bb3dc944d81b8f83e94d1b05117da902c28591363c079f9de720c085e0d5326d353d30fb09ab5ce577c58e51a671cd2a25a8b07b2ca5a9c952776520823b8997e970dbc6d4303e41586ac643d1889765228bfd60178da18395037f4c58515a67e6a443e1fe1b8bcc1eac6643d44bcc410dc14f36b196950d6303a91c9832fa2e346c2441eaa70fd589dbbd461e134da9bdeb2ce1b336b4f65cf78df47512b8d9935bd9458531a3fe886124c464e8a4dc3beb32e5ae7bdd1cee1a4d52efe47e263c649c9da10485ec065ad2ad13184635d69598b2a2d30de24dee51463d57f710dd6650df3a678733f0164df25b8d7c9fd074c04b155e30b823ac643a9033d60fe69cadda03de8ebeee41be44d08ae1ce3a42f76089ade484195a484309986e23ac42e0d29957e5455286993055e11faaad9d0f9ec865b6653a2f14b25db9bbf1ef178918a0213db38f698f4ba4d3cd0957270796f1a036218ebc003a848a59f5b257e66dc0a1c45e4c51832c5b15a09d8c55e0459164451bf0b19c006bc6df8c8c86c568796e6553403df38d3847b8fa6f603180cb63d4b01ab03424c513f9b1e3f01cffc6042a1aa28453807bde10b990afaf113cc2297fcb53a7c7168441ffb88ad38e81e8504050a5ca718e27122dfb4e8461e132847329087e22330503849790338cecd125f580768806fd48c7c2b2d6f0627eab517524246d7542e5817d51d57a8fd08dd06ba835c4eeba7f70518e124d711693032d52a8b7e577e8675a5927a631c77c788b0088f9e4bd7a3042bfcee79262c5f08fe370ddca4c600263b6fc018b611bd8671099e6a2028bc4dc4462db054f1e282dc69bb52b56e69d3bbbcc26675cd4c41b776e559e456e8bda5b4e3d955bb4d56f768c358c75e910ee018eb81286d30f44198e68156bc0130ef68f7d8e8b91a45b3370ddc68de3c6298b19e747025020d6d80fd818342750cc737f372cec20f7a3d47281d80b72c264919baef1125334d3d86a0de5828dd5de0e75967adb02d98981aef0f6e3983cc7080008078f2972b62cb696d173f9de2f52dba8680addb2e53636219d23938a87aff6e16ee42c7a796749979bac4d09e907514d073471f57226887f860cde28e14cf3c989baa9473a464a2815b52eb721c5db1e7c77c460a549f589c4bf590328a202c4e3ca7efe7ce5f3b38bb3cc8cf17051ea0a7f82d76cdb1cdb58038e7dd77f160a408ce56ca614625cfcf12899b2c65e024b929d3b83b1e80ecde627a6205c383eaec8ff40283dcb0d48c8f2b313cc9b066683eb7789dcf71383c29d7394083f9400d629a05af486de605e21149317006425115a72d9e6854091176375d8704747c572d174b410347106d9c5e33a006895d003985b7a0d06f19e8a8ca45ec3a6edc6fc46c4303823a426d3d29a4c20efec701056bdf8a3a934fbedc1ee4a146042a32e82fdf80839db2c218052c110f5de4bafb7fc08ede3d604f693862404c2298670213d3747f02dfe86760f42220ca0a7b610f2cff95ba97c8d2aaa321c58fa1584ee6740be5e519154004973b6b35f099028808dcdb239adc794b74f7230a2183d6122e2181e8832c7c34b07c58a7534f1d05c52c3321f15c1e853cd00fb275968e14795e67d9fc0bc3b35fcaf62366c00005bc8fcf78ef036fd921b50ab390112d2b89b4e255ea0371552d4033144ce62df04961f4f21103dbf2079438f08544805d49d83159fa95fd53ba2e132e93d942bf03a4053d28dcace06e3237c2fd0515863094f26eca0b0282da5e7a86c428063e8c47de3e2685a1b9167da827832dc1c9dd89d74573c86779d214697251b421f0d6383ec02570ce7ca256e2ca85d68c23f0ff5d4333441f9031ec4447f364833bdced29616764194ac14f70c7f663a5a43c47c15163bff1e029f531051a6b336a40dff1796b25ea4234d66bc21ffcd0cd4d273faf2cc65bfa72acfd1220faecb4db3bd83b74896a8f80b00f8044d56cb79b34008ff2f8dc82ffc229056a1e3682eb99aebbd1a9f9a9427285c015f73e0e7a142342eb674e4f129a2cc1b87fec7d715b6ece85446f630f3ed228cbe9804f0903e174be731ab3385bf99f6d23f3dc9bde2f87ab629baf1ba47490dcde9d197bc3e5eb59915ba0b7ecdba2900f92db5c08f62db1cf249e619ead358333c282af53d9b95b326f8f5596ed6de2c30f4d775a9f9794f27b3b3e6bd4c0e7ed116990c84d3ae3da5a5f88a6edcd58c2cde5b812eb63781bf0bb895228b919b54bf3b2ab6b1199a1f5f4e02789f714fc5190f50c172104607ccf52e35730905eab70a03e5b409612ee771ff789101f4f239bbd2c9d320a2048d109c1123f86d3cd29177e59e9bd06a45a7873f96488c756e274e152891c100b465728630eb1b02d8a3fcbb520708aee920490c13af8711c4f25ba253c296cb6c759576205f25f387bfc87cec08fb89e80fe3c70da41529ebe27680c6194e94c1e166aea64c68120aa7e819e9e95160e706a40e336b7e9597022c7bf87871ed2e520ac59c8c48287f46744f3be0a713628b9c024380ef3bacc31de351ce1ab0c0d241e06280f2704e823f103fb1d6d07dd17cb5e11871a785d21d36a325051004cb5ad46b28d8419cc7ae77384d8ea6352d4c2744194613f67c984057edb260074ff31c18551ab89e0945415d7e4a25c4f84e93d51c5f86a0f4fb69a70a03322274f7594ae0ec6d755fae868f8ba34521a1655aaf932739cc1a8697531c86a33e807979b8fecd9b61dc42343d4d3484c83951f34b41ad5353b3fcd129e061665c7b1414cd9b8915791925b479bbe3d0226560b6877a6806f78beb8b591a10c5bd280641ed6b2d74a59444662065d4b56d94195fd74cf8a1cab220cd1b837209aa1b322446f459b555cb122242bee3d68d6b362876045bebc33f7fa31b28badace88f3873c5f6143bcf0e06eaef20572cdf60d8aa2d7abde48a1c4221e58ad40b87ebda41d76c4c0687aa5004de000dcabbc867fe476e5b42cf8ba96ad7e78af31055fa2ddb4888ba3fb253d5e6ce9e6a47840d048008725bf8f473ecf85899e808739a889e770486071fd5ec3d1525783fcb1b346ca2c0c9eb96ec6824ca8870fff8b1c4e3240d6c0015f894722e50d7c4a99ebdec169da853b5d336e46c44b5f52b2608e64cdf278fb0a7aa49c963dccfcdd0eccc16281fc70c6957ef5fa5def7e3a6e146b316baee4509b0d024ec6f9afefe7d1c49a0e676bd54b86efc0ae38b04ec575a17d58eeec0e42dc97d36920824ec6a627d86395c60bcb63f9b91323b597bdd1be6f4afa229cbe77615d5c39246400f62f185be23d6804087a0d02dd65833e9e6a123ed00d64b76be321d757c9aabd459b46beec25a3db6f5d64575a8fc0131b1fc40f97b98431b82f06bd35527e6c5b48d25de1417f1c22639caa182b71bf7c289539d2a72eaf636da9c1364b2c429bf15de1af4b4b9d0e505eae3f09c12d0f9023250cccc7eebe2f295f029460d035dcd63cb567220db3070a660bc08eb1345e6bde0f858aaaa55a4491c1a31268c17abca9fc98647ad0ef8c3dbc8b3508cd6b2480d894868ef2d646d5b4db3405cd4e4c65a401114594a415723d2f2ca05f4bfa7943ff049e6849f8e4a31f476bcd3b38a9ba86c0669485d212957b5db6541142367b65e48fec751a4f5c215fe4f9e8d1e5652f756bd770696efdcdb26c38ebd985c5476989528b861a79b6b79fe193464ab182552cd98663d1108c38942f37403396969deb62179b03264c8dbf7d3056f3d4c4fd0336ca60905b7e2998c7449eabc7d4da346959b305d3be2f46367b07daa74cdabf7b7c0efc4041472c60ca1089a13437cc5fe3c1a16398f86c775f1417ff444de3e035a4b76376ca48dab56dc1d2ded5e89e866fb34192f3c04d986cf75abf9f5022544d783d361fc73d74b24912b0d89bb0b274f5adf90eb8aa116686d33a6a746ed37022ceb4c3b9e9544e75ed26e91f40897c2d663f4f88444123971018ce1b7988ff5a8cdcccc4937b122a0942d436cb53f334e0c3731d0a4beee9a19cf444ba9b0f9278544e3435cb643ee4a30514c2f51ab158cebb9b2264662f8b0788104b89c4b3012bdf46c7663a65076eb81e304d81880627b70e01233361c1f05c21221e85e48c53d708d14ff120a26a0ec0c7554bcf61ac883f31603b222827248cab9a2353db7b4579153dcadcbed6709730b6e55a13e5888b886297e5ab09d95a6353cd0a7447290c0e68d4b0cf8a3e093c029ce1cc4f32abc0cc48c5c81b9cfbed63403c67621329038382d075b98c9ad356657e0e2496cb2d5e6691227e661c8a1861e6695aa1191acc8f1383b3e98b690eba924cd91a48e15d4138f47988cfb1e2f00d7fbec0ac4209b51ed9d85402c6e318daf8dd0e07c0c8dbae04bfe16c9d4bc25625b3dd327b7b7f670e7f5ed3ebff78051c4f5dc4e09e4be861aeb71b0f08e0adb4db01f7944b87870c7a45b885084eff9746c2f8ae8bc97b56b6f8d2cf56697cdaa67dac43260ed068066e76564e5dc8757c878cae75035d450518beee5a1d0bbba506a2a416b72f64f58ce624046dc0679ba85c40fb3f063d9caa13b9618d36c82a7c12621f3922fa198fb8275a1604b02be0571d646c81181c62ef9cf1dbb4c8c8e667fa6b6e1077360cf9b81a7bc7b5e9f43d8b235d2cebdeefcd50d0426e406e08d68d4724d95b7424cf2948c346d2861139d74e730113454cdd0a8b963fab14818cbf37c1e69088d799fb31515aea4caf5797c122df087d023507477c93cad98dbac50267e8338c19b41c1e6c417d7fc05c902ed0be67fcb9629f47514ed8075c9c8ae8f3666a76bea8f942961c88c53d7a7865436bcbd3325d3f3af0913e94e237340b08aaf72af7599e106d437ad6ee2cd008e997f813210b5e4abf89974c75af8a5fd4352e4e2710a246285162e623a805a7be55b6c077fa3541ef219b2b83fea60044919342bf98284572830b327047d07a1f19b95c91dc2e0d2b0a9d6679401e956dd91a770b58756d57204094b58d552aaa8b14840b33d7eb3441299f0f649036f38392d583c98a6d5d65b7337464f1df2d300734802d98b46d6049a4b435ea8ba645a55cfda7f3f0818ad2efd7f974172e7d7d2e0f7bd037ce33c48ae08e2f0b5f9da12d7343e794f605357ef641d2c96945cd82ac01e7fb2b500694b6658bef7758bd2ac58b2ca3f8f15a67f4bfcd148c2747ed475d82cd37c52ccf49903f64e5a8756643e03dae80aa78b3f05937e3b8357cfcd320f015c8264f8f8b7a31664e2f4eb95ec6ac7a5a9f48cbdb24e2502bca01016d4c68c75e382a2f6e92e318df967812c063788a52c9b24aef794479162584c4f97fb1d091ceb764fb76e3d8493f134f81de23a8b76fa0cb420ed01f069cfd63bf4694fde646b08054f0c505794a5c93c879600a1958a836786955cdaa474299d3c244b7fb1687777cb1bb1d2c3c961ded618f476210387f927237c8e8ffad0edc67da2146e41990de6e94bb176f45473d37b72a0176f57b2b08e3360b208259f8ef35ec53ebea43bd34edff315bd532f637e947965ef3165cf9cd54f47e1d1ee8665615132ea4893851d66b79461ad53310c287bfa6abfcd0eaa92e35a255d413f97e7db7645fdea31ec800cf73b0514d80871a7f5d94bded2f8f1cf4132b604533f5e367040065c529acf4f82760573a33caafbf2a3157cd1e5b22d19cc19ae830918a5e3908a00a47d732067d5ab1032099cd9410f64d7919f0dc322279eda86b382782eecbf30974676add131af4e04a6774b1f46b30d8b286dee6279dc0e19ae213d912b07ea4bae5fe1ac6bf0a678fd60bb1bac8e2ccf8afd9abdbc35c90710f79cd6fb0dd87c9862552f3bc1903082b4de06a49cd20338b9d4080b2dc5f9a36f71720b54c9205ee3a77e9d40174a135ff14bf195be73b5ec4b7918ded011861de4bee706da5a41453951df5cc26987ee2407b00cc5071eb91a89b68b05bbeb0b12f8179d8662b174546f32adf2f85cb0ac08dd6e0069210db5594f9baa376838256844cee99f626fb4e77022415241d50a28ee9c91e72977d4245a9f7ed5cc202c555a976068e1719cc4b939fdfa7b8bd7146eb4e822c7291feea9c4b880adfe79a3f8bbd19820bd958cbdf03d4238de1091add8cf72649af3ed36ce97df106f401c740e006dd182b797eb710c05c7ed7b0f2515b599320c1e8ae961bea5c6ce06ff59c4bbb4feea1c10eef0ea73280c6be49cbe291915fb80cf4749636aa5a5090b8ea3c6d69b7a7d057e1116b79b5a233c840aeafa97d68a140c6deb3be067058f3e277f1a17eda8af4e4fbd802f65eb1bed3138c3323460cede507e26502d3562d7dd973cec3334a405bd45402a69124982f5eaa44cf5499f2869150bb31fa71a8c48953fb8321a72f0c6510398d0f2636441d09058bda176802a386b0b686d84938e085034673e4d97e6d698ffa5a52be02c3a0810b5112d6da9c23e6ce8c694da406f6c735a6d904b9bb3aa1c0050e6f7c1ee8a4ce13c0abd6cbd4bce5bdf28e113f209228ff82488c3034388cba43c42e7ef81f9ed88bb72c81baccd521195a76b5917eddea645bb9268f705d3158b454d8803ed0e5a7f96fbad415b7abf75b3d1328e318f5b30eb8d86ba399daf612a400c979186f60fb18147a43cb150f87ad34635ac1aee51633bb8bea79ea60ae4a177cf0db076d25a1404ffcac75c692c62fd2aa40a53518cb79704b829773253669ef61d438e67a3cde71b4157283d2e5c408ab18c47280aeeae2c7c119ad833a34b7d8f38b588c9681fd39b7960ce0e8ca147ea7357d6f96a1f97f087debf566b0d6c4b270852c20b56affee74a6a0d81f76e73a13943c244fa0aa370ae80d46a3f20aef9028ff5f60d5e63698a7850f74a8b928ed6800866d44918d2c3344bba347343ab3fc3326a7ac2ca50cf15fa66c363589ec247cc766b1bee183254823b2ab4ae8042934b324d96af3e6e3f2d22897302b7128f975acc973a3a9189cffa8b3af292d0be7c06cb72608b61b1446f6388ba75e9e23208f255feb58d6e4b66aea69c1b79f179825aebf49829064e92ca86ab1def055cf260d4b900019c3daf7471f727daf5acb1b9807f289c490cb90d5d8f81a3265a23b896af823988189a15166b93246ed294c18af8623169ab15db44532678fefd1d2ebbc29be7e1c0fc9219b4f53a4e87d414a4dc9dac09e6b5d0b3e6509b95a15d4b9d26450382c367a8fbd08463ec153c2662b9a5fa4fc06691b9a1e9aeeedeeb755cc0bb7573c3ce54f36087d2e6e7eac53d112d17948a393147366504453760c34290540788a28adc1e226cc2a91969343ec2a2e8c97a05ebd2173b5a1754f4e0a8bd8149788eaba523a8be8ea8be1ef09c49b137fa53a667c8719535ee5c6859dd0a9fa6c7d81a02f6dd0d1dd6104d2065d0ecaa02770c757a46e1e017e68f0bcb99adefb51c53fd7b1848d1cbdad768ddc78a2c20fe007cc44408d22e4988d6ca55ebbae8fffcaa0f086c190510c30073e9e4b9e6d6b455ee5d5753cbe47f07cbc533c161765213d62b153b419ae25866f0327c3d16dc985d1220b67b83914a5c2ed5b64097c5746cd2c5885d152c8cd3c342c7246174edf71bb76668a08780ec6784ab3427b80898522389f987498025322a8054b434786f59f7d55b85ce2b979c63c493362f5d5bdc635f0af8d04f19230159e2bf10002f57f894da70666ea3d82cc66f562702e44e8c155ef7c1e8097d548976ad5fd560899e08ae295d55c2903a716b10c0c4ff56376fe3104e55ead9bfdf17529a69bca270200696f3729cbcfaa15f276ca2d202c3b7a9744f45637998c0fd5f6e4f87cab4af1d4e7adcaac896ee6eb38f434e9c3f1175fda037ea970c7ffb911a19fc3684ab79599c384f0a1509df33be355950973cd6b6b96fdd7fa4adf3fe9da32ffb254edbc8ef3bfcb2a6d74e10355541cf4f5951ddf9d63fa29833d994ca83f7599e3d46f9c4c1755da36dbb63880dc95b63acf3214a99ce2e70636d47b399f7c15029bfda7572ad54556c8dc1b4469c92ffc2d2581711746c5435c7f64b47a5143d4a0ab6ab66356287499927c6dabc8e40cca1ec32876c0d0f67e690208cc92bf01bb28d53e8044f4303d342ed4bafb7ef7900445686fe73f6dba8fd847a3eaee87996c43ccda1d0426973283c609439efa266445bfad42b96776bf3fbb7e144ee864d71db99df3b728cd30dae492bfa2444a26112ee3533ccf7a022a3e2142bfedf9efad7d562fd6b60ee0639ec0d56a6fd7eb9d1eb1359c027ec7371da086457d04e2a50ee410c2d0345e0f658c1afac51e7f36b8db570c68f72f594d3364cc93f393253c0d265217942a1642055cc85cc7e473ad1e9a143b417531cd1f74a4eebaea27395ceb1ecb29893ac7f80e508e2b86a3ca05e2cb9852cbd48c3d817b9e4d43a1babe66060456b199c891af393395c9503b588e38a6edc9037cf993a33358714833806f7bc0595b6f4cd58ffaae22aed4be0d2a3383a0ef0855fbda6ce046b599aafabcf13f2d3e81311ad06fe4cb646135c0fe52e52786272f894d1e570265cef5c3d4398da80f7159a63b5dc0c35e7fcb538d6915306dc6438c7caa2105f2573b0ce02436449312c0047d30994c35ee9feb71e33e82a4fa93090de84b37585a2333f51e47dad8304ee96a1846fb8bfd310cef62059933d284e0e856bf2040a993844f3f586507d1dcaf28ec71ff80247627d7db1e2f9f3bab9098ea0c5980fea688b41790f5420f055a8daf67b8460ab1217d93fff9e2347e4754d3364c1afa06a4040c40051261be03ad27d06e4d3f4625bd2163f6dcd84a8bff028288963590412590e7f09be7fc02573d9ce79310945156d4e002c242ef3b5719441bbc2429f631e33f8f6905220318ff09da690e0357dec3edf39ca094142ae8134daac86e14aac1fb55a7f958c6c13b96f53355872b132b654518abe2acd763e779e9ec8a91f29206816938ece85d398cf7b4d61d9e8c0f98b76f762226d38e819f113a1d08ab6bb72b6e599984b445043af2cf70b8f782191597cf15a304b37a04543c7b404d170406895f1aec94d1ffaea12808283ca7530d3c0a43ced0dd42dbc21f292e0cd1d56a7ec12e9df83dc0883c88e2b9e28fd2a04a4c40a393d5371297ca3b38e11e0be65b89cdf2452a933416d27123fd4e916cdba013839e329db60a906dc788e0b4d1b62c2986ad0e643f7b82abcab1d63f83f7430acfece831ccf9384ebee7a42ea0e7c25677ba51ce39d086115fa67035e09a0ae05a741e6f9f1054532a573ffc294790683926eaa62c67108789de1cc525215341d8df748b78305b82db2b4bc37fd980d3bcd602c0e6373f19cb74bffa85db3c40fb807686d66ec57463737e0dcd762545108c1e405697a9f31fd4c74cff7a2c3249867315a1fb85f9a4db29907d0287353cbfdb600d2838300fb529374d071ded5de0d1abede55ea0342340f3661e99141faa2688ec460222d6320cd9cbc51e7de1e16cb3c81aae1f3259d14b0f0adaa5a624393796b562abda4841786da56cead6b43225d2eae13bb6f041b91b580c517e2831821cb5ffeb4c447f5f206176ca77805f41a1cb98d97e8e02f20b59bf7a4537d8f393d0febe1a3866e762b2b4a29f8f36953b915c02b03dc5c7eee2565212f6d132ad6cc932ae3a79bd28080305e8fd2aebcff18b4522805481296ca9cdd40740adfaa6272df1e096ec39ce9ac423ace44ffb68fd35da115bf7e6d28ad50d2d0ddc15aaac656bd196c466dc6e8ad246d77d316f820d186ffcb91eee475f5ed2a97765a6e0512dc6fb761053e5c7ce5487946a2755f0c03374572591ec18e9e3a0dc7437f428898e81663e0a14cdb16c57801303e881dc73e9e22df12b9475c2c1c15d8d86bf688380fafc2ed889178639068f9f3c5e07c4a4be8d5dc95a26a32896477e42444f2cea5e07544dcac08fc0e611b3a99cae482feffb7f764f4b74fe29a7004beb740119ea5378676b8fbf2b474f0e00116f6546a64713a451e6789e697581b0bd87a5b0d8c82e002ab6108f9509710214294a9c8c17112a091d2a8b8db887786d1a299fc357cb9dce1ef62cb15c59f1793c01b93dbfff63df26473cc986b10d9e8bc18380c28389d0ee70db41aaf1ecbef9ca5c3b106afb815b7bf1b8adc657b7704759d98b56f1e3fb3f0c64edecc796dd64c82d8a45171bf1a85caa1b95f7d83064bf644afa6f798e017da00b9c777a000f7d943cd6aef3a8bd828cc753dfdf8fca80baf95ac40dd596a669c08f36226fd118b791cc0b5774a3ca605c71846f9a9ef9da043ccc065f835f0f96b8d13e3061f8c3cca6dc76a09156ddee2078cb04f6c3f3d50eb76b4fff4c0c17749c8aa71c19cfee31f2bc8122ac019203d363151ac1b6f73cff543633654bda5d8c9e72e8bc8edc7b44f506b3c481a3f526bd08ef1760c1084e2de234a91184a9f1b19a6da786651de795252397c31bcfda57348c512698b52c8130cda8ee0bc0345f8c9f7526ee0b1cb7837e9c967307654e039702704e5128744691e18cd0222dc19438bf1c56f9ddcf96b277dd104a721699bda7d0ae3ff67198021c7c07b34f983bfbea818253992933c8746926676486bfdbd6e4bda754071e4b7dbd9d116309407743485af32af00d91c5eff5065c8dc1f8d166f4932f80e41b15f082905f84150ec624b09ac96a09ffdcb40a8f5bafdbd8e6cdd596b273bf8e2c6bd6bc7c64f3fe60cb40a20f1e3e56e9e955d0907decee9901da7460a29e2c7cb079f15be875420a60f9f4f2f902a2e869f484703951e44ff53fa4034e3d14ada9fb566b4a02d158d02c887023096d777b696a699c4653fcd4fefe3b3394bfb0df42598eefa9d0dfe56c8d71e767b559954d9da4627950a9761cd95defa04df8364bdc7ba8329d68e09c814a212ff09003696df7799d73f6f3552d0a005cfcd9443add81231ca4fe0678fae05261032625ad5abc6a601c5c807aa838fbc6f4808ced4ffccb5824b3ffa94b595e605f954fbfc8239167ebf0e94571395fac575e9a3dc8bb316cadf4d4a12f3b2b6a18cdd8aee508e5a78b31f2d9117c310afd8999aa7b931ae5ba068fee90f8741a3a87da6223047877af02244c5f6aa18fe055553620cda8d519aa14e7b830ca75ecd03b46ded1b1f0c74924ff5467ca993e8dd12f1bb7f465baf875818ca1b635226dab9d6c05d7464104be3c75c8fb7709ffff8c6e14c4389d15f0fd50feee7254fb925fcbcd3f822a88d4aa78a2143ea7fb69b7b308eb20496ad6cf739ff3fc034b2f8080cbad06272a400f3e81b2fd9bcf939fcc6ab0c3e016e5b855c38064ef11341e4b24ccc8f38ccd2015751a81a675621c598ff5d65e9707d2c4bfc5fa6e6c5214debe44cc292a24892cfb2862567002b55e49f3d684325eb32d109fb3267f12df9c7698a55fa26db2d62a4a18aa665d54f7b37f4ed90e7ac9a038c5e4d2dd3440e3f111886e7564cd80c32146c72786abe2362227f3e80b52b668afb4fa76c6644354d96b114d7f75424c467158b1de2ad9bad9158d97ad5b0577d5c0f7d233ad90e114cc6360b273da6c9cd3fc4eeab45765fb3afb662eb217c0ca62c705ff560a820a05255263f0f81831e239ee46b68d078cd95c2201e453d644b83000c1e5cf2bdaef0fa82e0dae568df1698e4a729a4c140bc15df941609f4cfd8b5c459b3cad7144f59d6e8e5d01f9150928e2888479589f25815e8eb33020022fadb8e83e66590c1e441dc5b311a37e3a3b1d8d8a63eef9a7d8fa1dfcf1c119a0e10948359163eb3630e01137dcb9677194e93d2fbaa3a162c9e4dfd43033b51caed432e225f023fa8521186ed1399b9b8d62189d6a5deb6f586305e7c3a847787b72b67f1811e59b1fca26409ab5871d7373eb00005c40263e96764593f66740bac5bd5ec6771290c562b90fb379ffd5844fcfc1268c2ee3ab55a752fdb192b45deb77f291bd20cc9c75da96b9d2071925300bf5c5cda570e1a809bfcdf6cbe0aecc256137b44b65f2406f4b8d895c2aa3889702528ee534eddcc4e31616aafca2e56fb556068566537fc7433390b98fdc64f15397951ffe7f70a717de5b56ac130d7e1e584b61cf89e1759e93de2dac5a36954f824d62e87f3bb2425b1452fbe423297fff6548f40a913da71fe9cc59c46f4c10ed73813aba477d1c3f0cf6aea8f2ba4f9f0439681852a1cd2520240b02e1e6900964e06689097a0273724a7f9a33d86b41404a8a09dee42eb9c65ddf3b28ff5d4cbcb5db3b290f70ff6f55efda0986303be5975e42753e6246f515598e6b3b5a293bca2a1b3d4fc20e463be83ecfbfb689d98b96912cdb65e2b667abe884ef3393f44cbc7e0399235c2f86fb8b949909770d51b4f14995505d701568b3d75c45db651f0d1e212c4ba6090155aaa058a9d50229d47c180f6901d929d8f35db96b6d17790cea6a350233e96fcc1b1b3bcd2d198ea054f801f1e45039b46104e2bf9387925d58f471b14d8c05a650282c09cca2fb02a8751d153a41f00c013872d5e03f491292bbe9d0f394ba1b01ea8b2122eeac26ce102d1912209d90ef7022b60fd92290ef5ba2ca4c22a050f626947d96d3c409d5f40735d1883218032e5c5de68627d107aeb0add9298009986273a800596aaf9c4525074baaefe8917a8765d1180e7fb3c78ff2ac3e2968d18ac3a8c34d11d94e73ea7457217c5a29315b0dc7514b63e0c053afd78caa92a43d1d0f194921e7d497ac4cb1b7cf094c59fc07c0f9eb282dda4cc3ee67ad589f126c96de0dd6c07a658ae3c86f1c89381c3b0b3a5b1f99c790ddd19ce72f31a464691b22a1419f04fa1d69563cd6dc2d4fe7764103588ca9a4a99568c31cd0f0682392a708d44dfa00cf5e1a01aa053ec870433ec88013913ae1b7f47d55d95d7b5c96e9809173c9dbae3e9aaa9bee49db213e0ed6f4d5a8301d7a8fe7b10b351efd27ec604dfbb0dd7e83fec830a47a9bcb8f52af80dd8d24324ec1e51aca0ec2f7cd6f5b0a637cbae9b4db09b63d2945817408f1d01d7b1972e9a159a7a11e04ddc84d0c83c93b64b44531f1b09ebd53c52ded58b7edfb21db7866de7d39a0ed9d2bffd5240d0758c5cb5a1725dc5ac81d643d1ec872eeea9c299c687054a5648b33f39b0abd1426e9e3bcd117c5af7eb9c057284028af6ed761a32b7c5c3d71819f04f460fb8cf657dd76514b7cbd64803d6af4896c37d39785ca7e1471ddee6be5a4824ec119e2eb52d5db4ceab52230abc4182d15209a3cd3ca350ce9130a3f290545aa0a3a87cdb7bc73891ee038513f68db8694bd526bde261416870e36ccdb170bef91eee2de17e624c0c6de9643888a42eb52b5492aeac7419e8301073bb3248dffcca216977965393ae89631a259d8be087940610a2db3b169438645ea38236188a4a3a5939170234c209dbc629be40990e3b2e2e544f57a2fa4ca646a8c2ebbfd00e771094c9c2683b93c0f8248d9d4f480f126bbf778ec2365c09ac5fbf5b8c8401c3315b77c83b6e59855106e7b3dadf536fc64ed4efe22de2b901ac605e6ef8da6a6c6ec7a56dece737f8a6b4c9157b0f25b04a02ee6aec636df13af8810ea9297e234ae7f9c7c6f9690e28596f667185f360e506dba10e18efa7e6f7fa4f3a37e6974b6153991bed5486dafd6b278b8a6438baabd4aaa4fff8e13ebb99548e8e1469461b78473803db5a031de45347cdedc43a95716684b7b0ced1382c1e5023669debb221f8e9ff39b740e2b42c71309cc25f51df50cc34b10fb69c135faa78e3326408b1cadd3e4652fb700bafee56cb475333580cc4a332a65c02640c19fe3f7740ac66f335d3764423f00ea323ee2167faab339b7d66b94e3bb3d1d556f02084d8cc751859a416695eabe208aeaab4e8e456e952bfd46818f2809a2937a1d47154f6f800071c615afa9494209c115e28098a6593c91a4bdbe8fbe6c41ee0ee2779ca1478d9d5b0f479c37b3baeb9fb01bbc16641ba65951298cfc069fbfbba53216a709fe69616a491253112266ba5f45f97c6b6b60bed29e17ca25efae0ff80f550a6d24b88c69a9eb67bbea4a5cc32cdda0af92da9dad35bc32dc3004f34d396a94d8ee99e112fb9c3c77e611e88f5f613d2a5c56619df1ee0ae1428343ba2a009ede7c8f5c295db3de4ef2a35e41b88fc7c95aec00f0896d3ca9fedb5f2b76f7ea85efd81dddf70998b673442109b126ea211f4dfed13c52087f2ad0ca0e6c80078f93e5cd74d107ff4e51bc899354a618c0db3ac0031de118284de6d17050522d0329e72450a2c47631d41b1dc902ac691842575c72973a786ee834870604780c48c3b99ee2d39ca394f3fcc33bfd1f0c2554c44a68e27550d179b885fdb0ae3e96d9d5e2293cb9ba78307d3f36bc29f17a0784cd621afebb27fcde6ebc829b497a7d1b6c0a5e8b4322a1084fa830d89670279a69562f2211e66e0a082a8136b3ec51342c1c35b93027383b758a27312e8b3775900de6aca6e31da24290053212c215221dcc4e629a18d00866b6d47378dc430a714ee2b60d9ab32b092012ea5e67d534760dfe4baad78f2758fcf5ab403fe8987be593d42e5132a55c0e101dd75e8d5bcf3655c88db017bdb33d63f36234d9bfb4624e900b7a61658a03eba961795783e1086c89cb1e25e1bd15840b009bf6a30729de753202045ef6fb25420f028f163b9d0ae5532664abc771bbe6c7512d5529e9e4d4b3a0cdf856f127b56df864769b9c113cd7b358ade8a1e9d73dab8ecbde52b83a11815fdc1bdccba142117628e0e0100a506ac1715110c718ca4ffc4110d1bbd897badbed87c6cdc9352cd5b7738a1148212f51d909e68fd235ae1b2b0ab04cc96e8c5c8e8ea2ac03be7dc53e381fcbaab47b0158d73c6632d12799150118af108d2f2d5d2113cb47eb6e4100adc76f0a2e5b9a01c8c02cd6ed7dc82298433d6c44a25db02f04b2292d2ec9075c74671a27c4827a7748a09bb1e3092981b484a0526a6990bcce0928aa23c60d64b55078b807312aae8d2d13737f22ae528b3b36468de09d82bd3f4dd6658d0762e0ecc153547aa75f46ac20156390bac745048ffd8bc2a6f331c54e327333043e873f26f1929b743fa018df9248584ab40690f03ddbe8cb5769d6b25b034577895f40df89bde708330ab2e1e968c8aff77a44aabb5685cecd1f13b3c37bec160b2635ecf2ca915e8a53c7249da612c14ba7accbdf3700f69c940bd2a568384451dce2a009842b8acd03faf1ca7f40a6b086bfbbe0807bae6bf46ce4082765edf73c6a8c5401955a9f381fed84dc440b7b372f2b7e4182d354ce3e9c1888196e846b318598d8f111bfe7158d6db6ff03462a0378797b19af2e64dc0fc38448466d985a435c5795bf21a599a0a7a7c170fb996c81a834867af93798d9808c135425485411caa6aa4b7061ef76437d11286d9b1da5bfcf24de22106cd3f7aa39f80f49f67b25c70b154c0835a32e039c03aa167373a5e93093c1a625ca4d625dd646a6423cca68b21d5ec55f43243cad7ac669c1c7b0b44609932244cfcb089c98f308b55a147ca41c0691b5690f61da69b313074ebcae021b15c523ca583cceb98231653016b505b3860f28b124afffb61232c4c173484bd07fbd285f96037e1ac74411dec403869ceee64a639351405ce7cd549ba221f9afdea816fcdd1926c44763470240541878ce3658c17b0f8974dba2dd41f7cd57a624e3931ba5870e6d355611b12a04c0727db70a321134dfbbd8d14e31d8617f4c85499eef0617308b2a377513b8294b52e4c4e37d6544de8d9574d3d90ae1749edc3ea3d4e95f0953a7d20b50db7f718d2973284283ca75901ea3e93d5045e14c986f33c4a6b8843a3db30780ce8f768593d7c509353a95860c5ad132446ccc8b302e6d2f4cd9adfd0f41c421c41f3414e2d1a25baca6d26bf56fccd40102ebbb1e94c6a6e3532635874a82cbd8a785e9445fa3167f919a934dcc56c48ac638eb6ad1f9cd12b69905af6a31f9ea3b2488646d6e5bf86e33421ae5ce05a7be1ffc8c8259be68a32a4243f656f7a8fa7ca2d3bd4dbe47cbf57247e7dd0571f6fb097eb4c0283199fa2b9729e815feb6d8f48b889c453fef026883a72eec5a0b38d17a17e1c901ff591a21f5a097dc85bc8dec92aa0a879ca484f21735aba3d9f85790d61646e56d012215d69770171a5964567b830f569cf01e34b8f56c94811dd02cf790a3d726d2d450113d42c14da5f18db87a2470db374ccc0100f8c136812f4cbe20477ba43e9ddc9bc4969afe892210b241e88e5699a8b7a07de7fb829c5f6f05dab8b9e34cce667be6ffaa09a3489f91dd61d4cc844a1ff16b5a3be37175650dc35773d4336552cb780d03604d512852f9b7432a29cf0fb7ef8e1a29ec8eecd3a4429ccac84b0bf0f3f7b669aed49041ba58f5f8aabe4eba13f0494884d88c9a1a7aefb44f34a42d99794881922cf04e60b754958236365a854ac8b4f8007970a2fffc3c91fc2431a04ca79a50b1a1a1a6b52cd44621e3c96deb67333524950c98ed0b284cc2040234ede7e8015b3ee14c815f3d3355c8cdf963e0958b5d5f157d0bbb48597c16486262aba711609f34885e1a510ff8296ac1fd62999cacf8b7070c04360f65d10f37d82c49e78c4574640c6f652d36de7c9d03de4f7f086e29f981110d0eb639148697f572778093a2826514f3ac36638ec3d821f92eaba85310e7a70943b1e243e7197684fd02c4b54b0fc04503674493ed27993beda08ef3d8ecd1e00d3d0462850310bf0db46d8d396bdf2fbd75a240c795791742ee922fe7f539928712d82a24f69919c712c0919e0135627286a908b58938fff79f16637abf44f6939e6f7c1e188be4aa6445666a86ff2b3cc66f1be1144e7619833e6abc875169ef2c8b2bd89c4e688af4ea162f01429fb84d99ccfe94f5f4382fe86b68d32ff77c555a38412cdbcaed63f22009006086124ab48f9bbe2045478e6017021d360946075a8e4b278feeb137681a7d09e16b9187d1ca4714d4bce71deaca3e695c1e463ed6eda167e7c8b829d91c3f43b178c911645961aabf9a3d751b056ad68397d0b28ee59c8047955990985063bcae2d61692c98dd14187c7a0801684dec1922830573e45012ff38236964fd643a67802c22b07ac656438ab71191693589acf3bfebb3b3992828eedf2223a23c2f21be63c1740488aa857d783f5197b8b243b0a95ae65bf86c90c348d4a61697a8c9ea125a62dc3349fa43b1a818b3a9dd8f922c9c68a4c0eaa7a4d7ad2ce0e85eca75eec4f4a81985f3d91e67c3425e69994e6a650db398449176293ea96eb1d16e1120e4ed7383605f91b62c644c24c00337034f504dad8a14e442f88370c408302c4633b068da3a0f6364f26fd8d16f866e89def2bccb73e0ba8e7adbaaec147f5ae75c650dc8b0c345f986f0c5f2169ae52f80ac5e85a84afc04057187c85d53928c62be20d0ab409f8b64e3563a2cdfa31e23c26774afeac499718d416b44eabc42d61d2a2979456fc847d094556f10f95c7e0ba9e7fd6d8e2a3f412790b7ae5ebc5c65c1d510c712a75e2ea18bbe7cf601c983cad1a4006afc3cfd0615a555a04b87bd3f856e39aa92aa78924b6eb67e4b29070dab2f4306aa9b0a051cceab1f12133bd0bc70e7bdd55fc1646548d8060ff41b1273ff2a56dadb9cec2a607378b89ba37b123e4a2dd88e1471d4ae588a96d45aaaa414abafeea47d1f5730dd4914f7d06e1af9bd1f80eb1b4f26f67f109c86910ccfdf2eabfa31a71c50abd0f52b200fedc0f505075c3906a1e235dbf848e8b110517628ce5b24bb1508c5c1f95328b02e710b9699e46f2b6e8af302b23a093f63e83b51a9972f350d59030eb6151bdab3007046c034d97c4c913a9b7a1a652f2e855e4bed7d5adef723a83fa1d8a5ce344466167d7eb75e321d5d80fc5fd7c5764543fffc0240d260bf31c6b8a94e8d1bd87eb72e1733750ae11006f0dc4cf01668573fd6d55707b5332d4439c4a7720c251fb0db8896fc005271693df1e836db93e83fbefa743b45edf5ec1ff5d0c31e3b8046a7e540b8e9e95d10281ac497e326a4d6e46891677a05319fda1711d18b30b7056f1eb5c7a518487408a50457bd081591e38e605f41aee4d8eca9d65bd33740d16f7a261cf994956e362881b426f13cb7df5f18e6cf1db53b3de17976f7c5a181f74e499f1a086910f34f776e50de4e981ff785d632d95323ec841d0197ae34c08ee5d3a2bd14379f27cd2760babe930ba3d1c17ab05d171ee55bd475c98df6d0a4edaa60830a569e9a35d35ad12cacaa5afc009f5c3db9627aad883ed88bebd26907a586ca686ab96f727ff21dcbe09eadcbe5ab42e553acf2aeca5f6b6cc33fde9fe60da1f56aed577ed7980cb42a551c31e19ee7b9ac5267ebd9a3b9d5c233b0386030ed35f664f5b2d7e98a623f82e49920b15bce56e0e109c91ab5ae588c553b0844c337dcd39bffed1655aa450fbaab26bf00b3fa8f1667c36f8ab30296e8a07370221efa00ea0ba237f67d7991d81322e649b5bc6243142aff2a5b0bc90ce76f4b00e4cc28e4d10f19d7b9a179b24fb0fcf50669d217a9498b05d000f213c0e6c648b0bba95435fba89b50bd8741ce2314dcd5f800c4ca1743fcab2026c851b49c3270d68c400a8894833e4d8af69ea72891e280c820138e32c8c57ebe844d2e84a694b1d6d327f16c3a857e050dc93a56820e36afa3b777a46d9105eff0057569870c220cec64f15c841757d995fb88d1b8da7c6eb47080cadd3d5b18199faf8a5732e91af1013c5147422f70bce2a1a5eabf4f2225402acc51772f3cebc4e7437672b18e3b2ba4fffe038f80e55ded79ba810d0318ac2518c458e1a9cf656b3b65f8cc8572f966f016902e3651e5ac64eb0f374b82996df07345d80d6f94edccff686752158b670b4f46416645cc0e92c5f7f06d6eb226b8e01e02d16af737074a855026396fa4e769fb9944dba0bf0b8692a41da01de63b5897cac7836ad650f6bcfe8e72cb8612c3147b6cf2787167487ae2280c5240e69e480d4ac32f86c6d474cf2764e480f420ef0ec2ea42e012f0a45d7b0ec83ad428b8c581ee657e370af58e6568a03968ca57aa702769460cdd7596833a38b27c8c0e2001a654730beab827679442093a00f4decd886cad52f66d8dd898ae35259e4a2a6796d681de69d3f3fa28679f8b30e022cc63b546d4df619bb9dcaef79646b8b0c95053e9b138c29bd600d3b9605064a4cce4b2398145470dd6797010f97d42f4e8135c0a48a744a430834de72b11e7d78b0f92487eb8e0a13f80843e8da27cf7e84ccbcc88f162421e87839f377b38997935990e8a56241448d516cb8dbd834c5b75646e72358e5d498fbaab4ccf94324bcdbaf0c3976363eb4fae6a578afcb80041ddecd48f735a01bb006b0d7a9bd2e49c22b538a2149716950086f3d1c7014fbfe7c56fdf560d0881e1e0e048f5e5c30b5f0e9041f5985174cc7935964b3280d067879f5b2b7de925595f92f358d397c9b90f7166926751981121be6a1ca3b0f2a78a7bad4d222173a8f7e9914546edc488a61f5c597da9a0e5516b55bfad53f89e567309868b13263eadd1d2228696084d776343b454396a95ba2c819a069bee49c032c76a66803f9c8fe5ef860fdf97dcd3e0e39bb7f31404d08020a80c78026514134645f7c54c8ea43061f83a99272c027051bd80a57e3352ed4d732a0c3e630be1549bac4cc4083e1cf283079eb31e935e1b645d78885aefd225f3dafa49daecf8c9a6a7c8debaa9f4d66e8e08ceb73f53237d0ac4f3acb68780e63120b4a272f9ef173bce3bbb73e7c174d6cffdbfa1813d393dd125644ac75640603146f3c2c2ffb0655c02781b397cd5fe9983bebf041ec9760abcdd8458ebc6c8d40435250e9250f148fe422cf6283c86a3a134c1ac0cba486de1ea8c8c0e8bfd6a8a50c46bc6210319fe62d14066809155b1b2d51aa6ea4a536c4f2019530324f4c2043a95a1b8d5274546df9d9655b59b059df4f067759b43e56d167990e0348f555d574b556a56c87da174b890019941bd139b518ae0ed2c3f13258e3b61f5f4b1caee9bc1b1a00530bd5eeddfa615105fc235f0e6c32626896b5c05def798751965931f31894f028d69895bda92b9c4dcd27abc1bf385436efae9fe374a35e4c5eb33edf59fc19b7730ee004f53333fd491fd53b3e6fcaa72ac2e223c2b09b27cbefcfa57252c24029f999c31c8081bf38eb0464eb93c699778c0001a393ff0ba80de5f291e4e19f760440e469bb39c01f8b52b0917867727e8e34e98073b8702314a7cb01ac174532bf016a2a2b30c7590aed3a1a12950a65deb8dda4951c63adc3cc2b81f2e95a106daa1d160321e43f0e980b0d83dfba4f9acb848bfcc89090a6d0721a712a4c670180703fb70a18f1281d6feca139bdf5e08c18d9badac864875d2f9c6737ae8a57befcc52a5f2a186ce0859f719d0b31870ac6bbbd44aeac4b646a181f83793720c8cc55bf8ae3e0c824d33a3aa08b658c7bd4a30ee9b85f418b49c85305973627b0ff4ec52ff49d468dcdf320813067e236aa42c1ad1215b18f225d9c93d2c5b356d39257d441c9f81cfc98d815d67ad691d82233b13bcf2dd177622afd1fe037bb93c340b4ea7b9f95d20a72689a6e2906cafee527ab219197b9dad120d52b4bcc92da61d1aaa441ccbb6635dfe9f73c5c5c42be7b4ea9dae76f59c7fde0d53d1a4c2fc51d08830ba412a57a60f1c54f7bfa411c12dd35596d90c51f1a510346f4d6038d22e3510302922101cebe7d89db4029d31744989d33bde8ef7afd0f4634c9a835ffbacae41c0407f64599c75f510b16844f21a8b543ab90d771f34176dff4c5335d9659057b22fd483f5f02e427698b0331f60409b40ed8f64220f8b439b43a35b7c089335118988a449124afac61fc168de930a2c7698eb59aaa4b625eddc6652d2dc03bae356fd6f7845c1f08c1504ce3e12a051f283469a2820c5155a58740075c70ddb50d4748e8df0940d103f0a083cbe7c7c1f5db12fe10991649203863801accae68322df30104162125cc64620eff520035f4ed533bb40d9cd2747eb213f4845970cbc60676f932601013cb3806156a1905cb745adf75d9799978011e730d13338cc97c9f49b95c5117a10d1e6c1a923288c5ae5d25f0c2c075372e93086d11a9840ad4968561434d951bcdc3759a22e263898ddb469480ea22715c5d94f25f0194cb72d45788267f9250d1caa8c835f175ab78848c5021d083be5c9215deb58ab2448f8b246d718d944217edbd1fe5c36fd04524509353a4a274c9f1d476894750b038dc9c79f6beae1b75a2c084ea3f2f6f8007053d138445dd8582264d1374482793fc00e3f0a872ed415d0b9af8a36a824a4a9ab662fa4b469b344985f9688f0000fd2ea9aec153b34ad102e0e3c1760107e415ada494642503bfdd102d40d3c6348ad67c036e2f023f3059f3e17b5b7fe24a2483bf0f68aacdafbe83ce1b938e9b77b13d14ce5146ca5758bf9dd95fdd4f69cd852b2af3966d613ce84111a193db4459c3c41402f24d48a01ffc6d44e7497071b503a144131966ceb15138d293f36a610d2e083dc466ac653914acc3baede8939656a2f804c079b809b7ceed5f92b681b2c7ac9590c125dcf85f6a075fdafa1243531d4b58e1bed47879696c197d15f21ea49215e6054902f86c22a9986c1c04bd59e34f352e16abf5d80fdb7b1cee222d80dcdb56c241f58d96c2e8249ed63b68a6e42da5373d34620824c57720bf6a46677a270bf94a1c1b6b5f64bb4b70dfb3ca898e4c860e4cef84a6dd6fdd390fe4f7915eba5d90b01a876ac4bc31a4eef24d353987cc7692c17572d87288611dd08606457b933c9e140d837a7fb8ab45d1dad4e2d50b3c775a142d9b67ab8569d13f79572dd82f97480c118e4446b600a011a96ab2ac35951b6d863e6b67ac366059450e7acd559c0cc4378e6a984c43140a2af9cc76bfd4564dcaaf2d44e449bd80ff61d090cf7cc7d836071ddc9c9b3290aaa9322b6cba409e1066de9c49e7e4d904b4c5ceb62596e7b4c367085bc5807e15e1470d2cc9a4096f9e033e05256306569be6b85d6b002d7370366de76ddc5dc91644ade90f7cde4bf15e3cb10146ba3e75e18d815617f6f1bf77759a52a0e6878a8d4e80dc17798fbe0cd2ec87036848a18586c6ebdc9a8b9cf12ca320e4fa5708851a043558f1cead17ce92c7dda3c6e727519216b19aabb56cb31644da87c8535e5b39553d28823a52d4c46db4cfeb45fd2b6610e91c07bfb9537aa615448b8c207f17653174f5800e0eaccf3957b061201052f9d3e9d53a8b9458030bc48d5da0c7b930c969b493bb554dafea307c59c482cdd13d9569dafc2e62e9199f5ee42ae52b78fcc9a96593f1fd2630cf6827f8d4fda9115380fed526e35c5a2267562ce748daca75a0ba8fd7f7f039d69501e8756db07d6daa8299216490712af10c188bdd66f5fe1384bae6249ecba89ce96df8ad86e0dc22b3c1b73a5b1b530b3a0311e7461917e5f528768e91a0866c49c93c9bb61c5e046bfa9982fd7dd5805405754d1a66bba1e7744f922720c4e4684c5dee325db77931ec69c32ff8da5c54d7d3ea204cf6fbeb2860748b6f9564fe8c51193e1747a64d75b366f816a6f21bd7df5f84a9c6198b807c90ebd2fcb9d41a0c37f55d0e75a94787a3f987b9e33cc511e0c7b9683048462c2b0a4db75a73054c99294798eb2e9c1c0d6311a66451a4ac74a71808573b6236ecf29a19dbcbf098d440443ea8510602a7751ae28ecd9df52a31da809d54bb3964d2903d66d0bd432d422161928b176cb7e3d826cb2b5f364a0ac332723533e7d2e35b081b0392ae954d58efb187c03aee092bd0e7421b28a0082dbff27539d54e2a091bb5df0ff2fc180ec29104677dc6b42497a3541edb6d558e8081350236b9531a368db68c209ab0b87c00dc423d9cbe6a8e7634be38dd8e8ed0a0b573aad1b4702293301d9236a185ba9d27d15878dee2008a86d0be6ac246e70f5927df29b57d14fd1f6c2b91d4562bc9593c1291eb02e64e433e2cbffc8272bec5fb420fcc2cd128f7bc80be0fb0cb8345a0e9602042c4c4e3ccdb11b1cfbe80449307641d441cacfbaed490bef2e0c9fcbbc96165bcc967686c3ef9c05f5bcb112b5b087283912302439e3a9e2a9448d36e96d211d87440f7bf76595b8d92140066e84e57cb84569758610aa7f1335020f84ac1da90b09f78c7b0cebc6e830c3183f7d54aea89865b158c69b715aa82a4ee4217c160db80a1b80122d3b37bd2d050a0ec2d389839ef2b4de1d231f070419ba3b4f47159d2e57052c2aa498c74e9bba86038810d638f67066724d0672b939958fb4055c2f7a079356a0ab96237e01356907f7bf260c53df0ce5adb8c604c013235e6a39415c00ecaba6564de8f5638f323f2d4b8fba7acb9d8243a52800084390def776e84afe194e93df98ea200ff1a4bdb3789aa5617f87bd4ab38f1228798f1e2aadaf0622a9a6f22c2e9f72f77b425c616d0574aa4bd94a716db60129869e5e945efc79a48bec3811763490d2df016241bfa1d67ddf69d16d8afebf5253db27be2546924af392672d7674aba0f1060af6783c4f42a8cb789198ec64e9fddcf0ded111f91c1802336e0c6fa78b0a9a851610d7eba5aa76f68aa561dc2a06468a2abc59ba791219febf882323eeeaad26f090a5ad72de4b4a675fe69adf5786d291a51872723c77f5475b524dad52d44dc750db8431ae9f269789710448d94073cc6647db5ac9dde954d5d9d2ac3695a4f96874840b8bb61fbef6e5c6275990055aba20c57b17ac20a895130100052daf9e3d6e0e3449a49cc13fce2bff828fa738738721c4dfbe52a491d8438b543a266ae5fa3a95e01092c1a5bba2d1f48f367c81f39765df21c5914209510232672e3784c328baef601af0f4e7f9363beaae9746747c42928ac210f5c757c2f5879bded13d89964bd7aafbe65b808a4904df0a424972532c14a44a1a3b62775ed32c1e2cd339297c153d8b5d8d0eb2c60fcf10b86bbd68161f0e487677acf390a15bd486f091229b3b6c79b59255c8a05aa34e05b30038bf69d9915926e8c86e12526a96178bf6c0126babb0b40d0e2201a096ceca041c94640a8bf8361082fb3595732c2c82ab951e2409481d7612d79c08ba3853cc721806f625d70116120531f32d3161eb559cbe8bddafbf21a179dfde73386b597cb1c9ca80cbb80254d6b5c8c9ecc807e82d5944747dc8a7fcc5958911456653ba41bfecd78e8b01fdfd2161c1e404cb090d20dee2bfa43b24690e0ec26dd8adf2d60b422a0d1caf0e6913cf0a45d35343b92eb230c0e486ee3f190e670d3696947f896f9978cc200bbc49bb9a9433c9ae81de821694800af06f1bb4498e722ef60a056049a63697b1168002d2115e73801ecad7071da9e8a62a208db5bd78378962ecc6c150b3e049fde9f4dc4a729e277e8c1dfee354221b735a1180573676cb0904c283b5d13a5612e31b71284eb4d270262baad3ee255dbc92ea92686804c5d8ed541a2fe0468eebd3e008ef273c08cf50392d7a18bca445237cbc9f54df0f072f336ec1e394ed9a4d4ea4ba41289ae4a1a2d290db226cdacae751836cf2559503a0418785d4402e9305c54da41e091064610bbe7abc4d19d6d8ab901462f3f0b480eaddaf88612db4b2020309885254fbb66ca167d1f44c63d3369655fa844afc6e5b6eafa33ffab225b6367ee5bd5aad86f39283211d6014abe3fab4a44e8a923d6a209e22ec171dedd00fa145a001225cd783f3dd663d6e7336b79ba4605222f0daa1a2fe4628b09e28d517fcb6696b5eb23dde59266fd3023b390a0f8281eddc8e2d5b08ee1342f339a433bcadcb72422fc37e4ff7ece0c91542d3b797b32c5ebfc1dba97e0965b9e6b2e734b9622f4a223ae26d23c969ec730580e3270f09c354d910da54dd8092c0068562b28996b81da8478eacc288fb875fa443525886630f589be4f1ee89caf78b43bca67f9e8f0a669314a60d50c0440aba325e17daa76cd8bb3ed1c26ee8fb2d0bf5263491d4684c445e78513a53ace30caa23fba022b035ccfd6e245139ceb9ba2bc3bbfb9e3d68f83948cc2cb439a4a900d89abf233ffe901741a93717ce3fa49a4a52018f33a3960921c0cae7fca3316764404fa2709d4d66b17684e4d2c4cb407a6528ab112bac0a73558dfacbdce9776c5110f5d054eb864c9006cc3488ac84886dbf9f26785888c76737a439547e2f66b069173be4ad4a42cc525c18628319676b8ca5c26a6b247fca253cc201def645237a435e01a2f08bdf68cad45a80ba998972e764fc4302f6d3acf36dcb0e87a187c369fc599210ea28c666587711bc597a410c58ada505d1fa005a2024dae16c8cbbfb1cd8c85bfc179c354d1535ec28be685bdc673ddaf4eed97b7628c52003712521a5158ed90e4200731fb736f30a809fd9191ddb0048b223fc87f1b0c61942ba5f8cf6f73795aaea1c15b0b74544ad6a7718ad966eede7fcc01a6d62d0f5d85334f79bc83273e8615306bcc7a1d9d46f66c540ba0d324fd4c64488e977895df5f4a06d0c81639f05de9e433c0f426bb6c67dc1d97d4bcd8f007bae04f4fc111bc06356d08f81395336740199f2ad73a723ee0a9730b522937595847ec0d9b10c6c2c6c60dd0750d8742ee967d15411f89ce3dab5c56f756ada1c6adf0e11f9829d0efe53326ffc2437d895090630ed8e7bffca43b1cddbba4b8487a0461d2882154ccdfa16710e009c14a3540e05cae4b3dd7140d218571ba6dd5639d9f3be1ab5e8df9500813e43125bb0f2a49b9e2f4b17e7cfce4abd38b0a8170fa091ff689c68ff29fd0b455a5336a53b2397e4e4d2aab68d167b8d6abaf7139dc69393f4036e5312503debf8bf18cfa72505706ea65869d6975cb0c88c456164fd9eea2cbff7734140d2543824765696e968af1a158f907800c8cd89d1ef8ce22caa71ebccf9517fce43e8389da02c2985aaacc5c0f006bc649b4e92d6c3315e0d2155f6e6e886a4ad5dd320f62f4189a7f169ae58c541e4093660c29a926ed6813ac714ac002231385b9974534ea5bc1a1ca0bcccba8a290504948e98dcf4cf0de328c969ba1213c2386cb3afa743666a27cda5529420d39c5ab4914c8dc64540af7e166cd7f42966d6f65b1e8d4c3ac9a39b6188ee2dd70b3fac8deb5c9a8f57746b54fa864087786eef92e43e4cd3b98008a40da72ea3022b54120890598a464e90b580975dcf124284a4a07a0d3221d9900a68b61c3ef3bf818fb3fe2b4333088d1ed7423ec595e28d1d6af277a86315d1531bfbe139b23f7553173dcf44eec07447b5e5bd63f3e28e337222128b4ca47f09d4a95e2b73ba220b82c4f89e03e695f3bdbcdc08ac026eba70497f7fb9eb3ee8deeca2ecc2fcb0c19bb97c10938d49c6e40b31759746103cafc75695b30d02a6e0e2419585fdb9680f25be68953bdd0fc9ed6bf765b3fe65b6c9fbcb167e9d2567766ec025c36d44b054aa40634d2070030755f5886f61f1b7cbbacc0618f66c4238341bcdea59b558627ba5108a58d9636096d22654a32720691067206a510b823fde527263da3351c85c9f53bd725db17b47160a531238346f679c6388e13b10c854a947800fa48039bb456a4aa28a5f45900010e4c2b8a23773ad05e6eb101dc07e9728b28f0340ba8480fc5a916a039dd84daa83a90806cd29af9abd50823a050e3e7dae7cfb5161a42a4859a964a532b52036948d554aaa3dd8b3d9292f093489f6752254ae983e4c58c52489b518392f43d2cd267c64a29c35692c87b6f6a5549232d5d34e145b2484595c8211555a46a2147790f39cafb08da4988e0d337a842484ae983043cc34a497a1f241f4051b690fbf047e22c1c4af14ba30f0842a50f121e48c652249b840fd342088d8682e72641da912158a447c890effb3e8ee3402745e1b65aeb10aeacaa0ae2fd63103030984d3a0b3d08c521b15814a782396a9d55a37a54f31aabad22973951f61e9a343b06062e65aaa514ebccde900557d5caeac174afb2688d0db0e9a74c1cc50fc7f0794aa4f8a4f0395605da74dc69d428c730f8fef5e571657540843dc37c8e3f4fdbb642f822b942cccbb4f83c2f2f92fe05971ee310631bf3e1af1013be0be50a3a3e7c1e980fc3871175fc3b78826ddbfeea3509ade907038331b3f6865e54553039789e07f6a017faacaa5eaaec5be157107a3030c9041226c78db11e0043beb4c80a54515e595db0e9af9d1fd2977e2b91291299eaec151dd6c1139866fadc93d65e2fc97f5f925a59b54cb3b3d34f1d94009b5de3ecb8c3d30557a0caf2538f25b0d935d683816bbf9a8d23ef39fbdf83206843c682dfd8f6eb784297fcd907c75c4f68141850bfb1bf45134eb8df68df1b4fa099fb1ade3b9ed0fd7603952329a535dc386e134571cbe7c2e71fa0613299acc99aac355993b5f685439099468a1ac1d444bc72c494f04baa34ea783cd2f2657cf9d2eb18f1e718bb7c11ddd536fe322f63c62e5f465abef028c3830b6054625246059ce3f1d3d285b234caf0f858366ea052a5f42991322a94fee55fc8232f5f22495136e91e4929a814c722cdea9c4e426d1c06207280d5d5eeaa6290bb56394ef1ddf5d977c8fea607e52610a0e5cbc37c8ef0c1ef292d0bcd218d41553acaa0aa9835bcbf1d8e791b54852baa4b35c8fe554b972ba6bb3cb0c8eaa7252b3ae98cd2603e07edd7cc36732b6aeb60e460ec7124dbc65fc7e81f23e2d767f3efad2fe34fe95ffea7f4f8e4287f1947eac31f8f32a4044082194226e1ebe8bd381a51fa9711e896a51066ac317b84ae22bd1bd87497abba5c2e5224ffdf5d2178dae109c28290163c1744877163c78a101cd785248a86cd8ed15ab3825a3b1d110ba8485579efef8d29cc6a774dc8a290c9747464321d19c5e92067e1386eab57fcc8ce35953070bf8e141c06c63ad96edb26d3b9332864518837f4bceb91bdc44f3784b94e1a31e454299009a049c1e5da26402350017a823120406b58ad2025a7927347e67119b2202cc14d642340f61f42cb4b5a1842e4c6063c84765de73d78bd053ff90b9101770e1f7cf3bba0e1d4dcbe9337d05f4158229a40c518c0a715d57f89a4b2fd6fbcb58520324df2d8d4d0cd30f5537f7f87202cc18e8237f11b93df701c97026361a660118a23e694873b6290f079f087df1f1e293de9e57d8e34e1293dc985f205b3808af4801cc779de756f0b3da8019bb456fa23e18b7f84f4a597e9e7113f7c17659a7c80f8e1ab20929854a144f67861279e208e46fc54a4b4e27544203be1d3cc23922179bb9d4aa46d5627095bbebb3b446030f31a95ed1039b7d0a47aecd43e17633c26d5c226add55aad71411c409a748bdc7f3b8f52b9228245d11c4a6d2cf8856f9ecc53ad95e36ee7c59820924824d248436b788218f16070d1f868238b6d73f721b7d6dad1b65a1447048aa3e383fdf0d3cd0cd8f456cbba075dec9a9fc0ff9e0724cd366a1a29761c9d53b3681b7f38284ef5d6e8ad2a404a7e5a3f4c26134daad56a5d1be06c597e6a2a753a61278dccc400819f0421ecdf2e27eb9fdc94697d5fc5a4187225d69eec0fd6de60c166cad48ea274046a80289c135355dd7821016a33d22b94308256924619354a1a62d263d263fc47c40fc3a731a2178c86442f5807c17f8b709750e0f0f1fbcc6451923e1c7da81433204256fa20b96b942412494e15266437424efdc4fdd643d4f4d533358d74db2883c2f6df6fef42a6de4b059828214f1f3836133f39d94570f11325df7b22a1a901b383bc51000cdc41de483a8b92457611850ef225ef2872c92e92f8c5273d0f267dea142c56a80cb15865f8a5777107f7484f34b4bc2a0a268eab8a6a56cf2b6de3f0d81236046db31ce55c77b3288ebb9348e802c358dd2416cb7f1ce5d67eb7d9eee9563b4a77c8308be27493cef2d38f122ec04a64ef38bfe9945075962c6490c13a6a56cfecd82c168be534d81facdd36bb6d5b8fed148415489c342ca954ca9432a54ca9aa329952a694c933997c50814d1a9ad50f2999005af0af6a2ac58d717e5a70a02306e6858333069f39ba13e64c751771bc91bb3b2bca29edceaaf2f2615ef0d825f832ba0d38604154821dbe8caec40913b11274da15598e6af83276961c8e7095302387c58712acbe6d4dedb66152f7323616b3368e4a985154c1599ee7acbbd2d16af5b6aaaa0b9f23bbb39eabae7563b56b5d58ed5a5d6beb468f0c5af3e3056cda2319d2d30c7635f40d103ff9d34ca97424b092fd372b688effb4cdb951f19bee65c022fb6f455bacaa1ca8a23656975f59543722d11e6df6c81e9548e30dfd74765de72feb0655bd90eebd5e2239024dd9a3aac2640705a532031cd9232abab383d29d22d941f94a97557a3fd2c457ec80dac61fb43de0d771207ed3d5d0a78e0443d9dcac9cdbe927df8a7e3a67b3826e1b163fdbd6cabe013526edd1d9c3c6c21863b2eb649d940ecad941e9ceeefc4e92c7e8e0c509c45a20544af7a03149c8feab1f3dfcd423370ebdb70848a3c089948d89deeedeaebb394bed939710ee7d1721c4051625920f7696d7237d4843a50c5b79c926fdf40f404b5af6986dc030740f1ab0bff921d09a6b4d3ec0bd64edbada754df332b2b6bbbb398e9375dbe56032f732abb458c79ae873ecb1c04c43c8fc871c6ee77d2cbfd97e86fc97de477c9812e953fa17da25ca9336ca41e2f7217d8e87217d708e87799e1c6493f08fe47898cf41c290474a0f23f300f15f9e47fc175286fb97a76548f2941e8694e1c89d52c7b96e75ac89825a49ec8d233f71f15ad3ce59a681b6138a45766bc7625d80624a6ea04a280ecd9e92ff6ddb686231d04bb09ea39e1b22ecea31c52aec75ef6a7523c3e68ae3b8186052366d17ee88012ed97e05a1c0cb91bb560d65eb69d92002283019149b7d6ab37a4cb5d6eab5d616abd4eadd54557964d73a756b2e6cfb8abda5cfe89caa44dbf8e374adc9daa40e55a21aeb1a4dbb3b4753ab7171801bd74351fe20393baa150471b260b35da7db342d6d032e5bf2973306c5f17ee382c492983951102222b79bed19d0d3185d06a5f551afd162d01a1f560f6da583121d7ddff781e0f7b5165a2346dbc4e00644456d46f6ef2cb4e6035b8c17689d85e27cefdd400d1ad09a467b42b485155140f0d483467b2902acb57a80059bddfac20f77135964ff22b6146e4ef766f3d03eac6a0a6791aaa29e9b28054ebc5c4b7ce0a195830e414d2a2c1c3bef5455912ded1e7a0b4a91aaea5685a2a4d5505aad86829ddcee5aafd5c7136cbacc96e028f79bbae5952b8dc73a0b3aa786f18242f692c1e04746ad5c80e2d4ead1513daa2a97a2514eeb018c16175758961462443102838b2b64b2d710af274e8eb0abd593214a2910d86e9bff0f534e907d0224c11b394342176cfe535a37cbb930a601eeeca3858f78e4999f2e1ad88b3ceb39aaa909501c9bb302c5e9ee187415f35cb0f75a5b6bb5b75f3e22689b23ad43ec882804f68aa04360d2a15f70626356648fd24f4ccf5e873b7819278753610d3cd964a22891e4c852de386a70628612493f59419519ca4b726fe254ea746a1a9b750ef75158ac1b2bb0d9ac161b50df44a1fef65db7f641033671eef7771185fe0ed42e5d440734f9b46d2cae5086a8370b067ac3ddd84055b8be3e60e16de38660fac114349810931893ef76acc6623199959999999930707d738607bf29d2e257c25cc68069f95c67b7d1a4b28e1b8d705966239b057403fc2c057081cdd4977bfce6662b380cec45c91d0626657386458f7e8e7a840cd90962b76de3ce9def05b2287a06564fa521844051fe211c8570cb28b8eb4a29b04c0e1fe4e2040caac8c08d1bd4a895fe7dd3049b74b6c2323660efcdd56c66adedbe214e2d4c45fd354ab4309962c394253b604088165469838d25a01895fe7f1219d019e526b78ee33aaee3b88eabff41dbe6ee4361acaac254bef95e10d0c0cef21bca04a895bf76a4d3287fc9664228aa9f4613bf4fbea4c5311c6b2a1673227f72a3602be816b4182b461b920d11c56820a0816d36c34c67465e48518320569252c7c34e015ce0da71cd72a12e8446778236414fbe028a728fb54dd10d536426846834a1cb625d17aab5566badc73cb6c54a5a9ae68122188220add9a82109d6799ee7d9679fe75313c8c1994a9de769ea20280a955a726e5c672b0e2d1a92d0d989c9a0374bc702f6ffefb802aa1a52518ed39ff304c5f11a8b298a8a865455cf664633a399512ba13535b4cd0d44cc808c78a0d1d05fd7d038df37110d04d0ec8b591a6464a1cd281090d3a0850315675a3fd02f5f1fc29d501cafd5b7074b35b07d57555557f746b6da956a9ced53ed3978ab0d4bda0e6ab55c9b75d25b9cabe53f0ef396bb825c36954ab9cb97a4ecd76c496f41a10324b5ca46e01a2443c3ee6a0de11d5dba74e952fa53f796b7bc257671efb66d43748b5515489bd22e752dd3b955a0aada9c5094ff935694ec0e6eb14b769456ee27731cebcbfed45b19688b6d318a43d439a4ecbf41f11bd99bdb99b7998f38b0b9c562f55e92ac5bac61b4a65fcca08b9b919faa938cf09e8a2af416eb5a5b156855576f6473269b1528fbacbe6e05aaa82d66ad8de2c5ccdd7bf73c8fdc6215e5bfc13621265b6cb5994cd65a9a542c76631805f556da2018579436a473729888629eba40b8754f36609d8f48a7a23148c10bce40410e50a8512b2bd7759cb55d67855c3140ae03aff781a7d33fc6b5fb38eff32ec61d773aed2801ee5c5d2c205bebb6d58a83ea5ebfb9f79eacb53cfe0b4cfdf4940d196e9a1e3f64d65a6b65e82a7107c129b8e260e06b55061ae5947629eda7e02dff14ecf9a7e00e2ba5351429bd1e5561805e12b098a17486ced099ae86089b291838a186093667c06e26b59540002d30c601fb30029b339976d083d608790c01fda3296d0ad119689c41713a9f71063de35a5aa447c8900f04419a10529116453ab55ed995f91bdb2dc99aebe6ba494c60eaa78fca6a15337109cda980ffe3ff4755350b480a26e8e4b2733c6ed6ede2b64547c6926dd1d9f23f6a4e321d0ec6e04e4e0b87bdc3607f61b5d67f8167d3612817a6388dd3effe7d30a6c33821ae09ade1849cc016760455796f9d70166661fd4e4b8e0550e00cb6184476877dd79885c18638213f7142f956ecb556eefc9490c4195a4322676666284edda2c5519ed35976509c1e83d6b8ed3a6b7718e1fba4130e4c1689fcc70407111bd48c1d9779ecb6b0ebd52b98823616548687b3678711be292f53f104237e0273c3fca6fb0e48a1525229146aa4344a73170f72c64f1ef880cd269ac944dbef9001ded25afcd4b419e07edab5dc1be1664067da36deeb782a95f25aabc552877a03fbdb388e820edae791fa1e0cbb867e7e230dcb8dfb55553d80a26a1553b049b3630536ff0343f0d690d298f0813404bf0f0c9b3459007bf4781004c1a70161b46090ec410128f87b4e3421fcb62ffcc68e5e0ffcfefd74fa4ee071f2537daffead0f7ee10e31f097b3046fef8d26cea68907f734aeb2253d2d20b573be1421018bc13a44524924d59798b1cb26e1739d43b7e812684d3f915a18ba8737fc4bc6f4c78c28eac351b4a686eb1c03d09c978f19bdc46397a491969dc3b58dbf090ba5bc5418b4f0302b49a48c0aa4203dce2845524605f1494f228fd08aa2549ab4c2e3096c36ec042be988e9b86d8d76833a0c399ae2d0fc793a3ee6c6a327ffd067a0aa1910688d0ccd0487a435ee23c644881393d3898adc46885ffa01744b91ab63771f38f61234097aea26284ce66305292498cc60dd9a1963c65b51f6738c30e10fea07c828f274a2356e60b361b01a3acc610eabe4e974d22981d6004961089122467a4822e8305b64510c799efd029f540ab82b8a058ea9f610bb5b6b8d19f1eaacce3c2eb6b7ecfdf77d1f4f90b6027370639c5ce18212c955d2a4f4dc874e0907f89180ecc2263d79764c2693098bda2aef5611688d3f95e978aacfbd045909b4865231e5cc29e38ab0da441833ad29c153d8d129dba696501b88cebdf75e9a5ba361a1d19c3664adbd1f057bd7d9e0745b4af013e7df9dabd7ff60947c512314193315edcbb78cb5dce834cf1ee8804b309d06c7ec8a5b794ba335ac9a85a2fc8f300d4133220d27c309adf1df394f8ee3ea122d0e8756abb666666a6ba6b666846899d9366ba308d1d2ad7a512cd40ad471ae560daaad1a54c7fae327252cc044fcf4e33df832558601a60b79233d763f7c15be17c923e091263c20e91fe9473cf23a51939b26abcb6f2a48a9074a60227e7a55215ae34f00294160227e7291055741e75825dac6534071eab75cb5659b38149711f98948e5325691131111715bad9bb5db469403ada93a34ca91a811610404cdea5099a0383954242a1140b46acb555b3fb886b0d65a6e4ba552a9542a956ab55a39807801a0b23f9014a8a9aa3245b9007ca400d7375395c200571d994c26d3e9e2fe8eec0fdefc657a8a0147767f8ae35d67ad0ddca97f9c0bcb6b65e0cfe70c485151735dc76d5bd76d3290451182a7aa0a491b8bc56cccda6de3429b2ab0c9c52c37e43744b1283476ef142aee0998c44e43b1588c28e627ce6bada713278bb96f5bca5537b6c3c24f36c3f30c21683387f1ed799cdec8feddf6b96de3366edbb82d95aadce93928fcf0c33034014e515bc4018561188661e84318d22a9cccc9a13533e33ef37d331487547ad29bf4acfdc168f959570d1af82353defd5e701e4bdac64680de7877070ea3168296a0088a723872270104ade9a2767945826a1d94aab5861ef2b06ddb17185bdb7527ac563e7030f9b040b150c185a2e1021a069d41d7eeda994ca698f712e2f5ea57fd00172e31dbb6c5bc86f07c8413caa4dadf68d39b8d6c18f78a11bd6046a0d0177dd1fa30c0f8656d93311bc771d6721fd0f10024c15c5e2f2ae018b5fae0025b8ee32cc759ee69fc0c53ad2653359da6544c4b7137ca5c0d45b2cddbddbb992a69fabc60c1df834e858a4bf113955b44a5aff8e99a5c80ef69c5179ff461e8a77884f4e2872a905e7c2aca5c5205f149e03f809637c8d5ad9383659f99ce323d66c4b3ad323b30e0527c5a6e61b622b9599a9f343f47689a9f2e458adf746ffa13f866eaec21244d04901e6c95fe6be1f75aad040a4c8069255a9f3404e41d1764c1ddb66dab13f4172d47a4f168b5dab61d920c51ea0f522366970341b03d4f34c103de1bb9997b0dd0ce65140c804c4de09752602e7f0f7e132fa8e2431155aea841e90fa648804d6aa548ab5a70213760f3c70e05a0e0fb9d078ce06c7f7bf08e1c116f4ca101d4e6874e57a306092ac095f4beefa3090959e05ea2deb5de53db31619c3b5e0a48a2b5dd752fe025230801cde9a1a44684631956fb6bd795ec4a95a22b2ebbd255bae84a5f91c9fa4abbfb518f5843cbdb1105aed90ca388028bd90cefbdf746d1e16854673a34b8d1019b94560681cd6e5199ab36d1cb36222d0ed09c0e82daf8770ea5bcc44acbc711241cc9c26c862e22de68441892426e495fb08ef3997571f31b4268b48ebb5c27c40c23d6ff735dd7f5d8e169b55a2f2d7809d1d75a5be2803b9bb65a6ea382e4e96aedac7065c856b002548366ad1e3bdf093a70a86bf821796bada74ee9965223f5f0c33777644a222fa5d7cf8deb8c203dcf5692481f24a5f846903e1c816e497ab034760c5c600e031162bc4a12e83f586028aa3164b105c8c220c6116d8b818a1f66dc14326451d44971bd717940a346bb28c112ac6fc9141a1896c6d6218c188a4ad2388018946038460d8ec4b034f60b5068889524120993faa7a8a204b492347ed04609fae8824d5b1b82e67cdbdcc03aefbffb7edad11a91416b40d2ac42f5456bea10d4c6ff23cd5a047949f39e155593e99ed6aa2af41b1b50d5539c8dabf539e42a1fa74285c751fe3c78d0d0d89ab9326d4dc7a6aeeaaaa2fcb454d6e1771886a49f1565b9d8236b6b96bb24c7751dc771f53c3fc73fb125c02322341b65bfa9141eb1a9a2aac03d7ab4a6bdcb030a36afd93b64b383b2374ee7ae5fadf5dee07a3be0d8a15d672db8030e9cc11bdeceb144647f97a2553d8d7230b8e82b4c4f60268e90b835f4cc75e899cc0c582663d93ce3c266d3da0a6db53275b5b35dd7d9af3361c71bd85cb5ec7b9174578d4255ee79501bd1927016add9821ce5ef4968bb6666fc4423c108d3642d1b8e4c5de8aceb59efd2b8ad5d2d136bb40c998cdbdc067a829716239ab3685dadabbaaaab8f032cbe7c02ec4f6d8d016730fdbeef1463b2649c5af46d1d1fdc98d225639ec034b7076e29344fd09e3788d48468e1995159aa07a558747cc04346715eb265e532284ef7352ed96f8f761be98f23fc2ca0223d2959ea53a9549f5505634619345c11c48fab8849d01b696cc966cb8aec17f44c43ca998695bc86944ccf3586c8c8f4ac2529e228bfdc007ac0dc8377003d544ae9d32ebcf752362a94ec4fb96c323564d032f155a3413ed5a092cdd672ca66cb6ecc5476ef8b5376ce644537752fc626d3ff69dc017b1b29c2047faef917190373b524d99fc6bfbd7bbdebddebdd5b6532991012a21843e53acc5182eb7faf65a4d98095b0b6bb95b80853d01bae0a7ab3a984bcdeec99789fd658268ae996c7887a0a2cbb4824d2a76ddc81da0d925254488e5122855414c9c51a6d78d15d641f6a4617d1681c26136976ab9bd84edbe69d0345792ddc2d6aa9effc74cd317955c5ba62bdb1625121d381250352f2d3fa61ad5806a0287fbc45ab752fc626d38e9f7af058d14b60f860c516b3d96ce6a148554328ca3d3432ea51579e370b0d200536a9d1d7f7de6c276eb6a06ca894ae986c1632120000020504c3140000180c088442c16058382619eeb37614000c5c7e4282643c9807a44918c34006820c42861903000004106366086a8a0358cbec775b8f0d626f3480865b10b1be4ad2505a10d71934ca689067afd2d3a611b99b8ed140ed30abcf1a9340e3220eb917cc5ecc9a2ba0064c4be75ed1b23a40d821f6b7e9f50f68302da42fc88b018374cf72910b0a2f0fa61fee615be109172286b8788f7b149c42c65a59614d38e6c5e4d2b46ed53eb13d06044229ccedce6f12002b522e3299c4c53cbde2361a6dff4426a66f69b52dc0969cd416e0e1e1e089cbae5500539514460b04257dd8ef59bdea71b145125bf05ef3ec566eda956f20c2ba3671424ebd10a40adbdf8ba21b0a874c1b17c27880a75530d5a1790561c13438e91578db3a04a6027f0c5d8b7fa9602540d23685b59c7f635ab047fcd2f2d738f78b9fe563992459f50b2e08728991a75f695bdc61cbb8855485be4be2b0958eb7d80947187968f64027466e4bca730b671ea8e7656f1e5563ec07bef012f7062d000fdd5548a08ca6a9e89a4cf34a6386b034b1a4b4c1769d1f44c36bc6e97928b69ab7a4baa48224dc4f982ca3531bee6213b1e76fa5efed4eb926b2d01ed373a692a7274d2f46dda1876508d05f3f0de7770fc3079c216031e6d3d90f49813ba0424bdd2cd678cd64e8fc2456bc06e57e58c55fa8e18fb12f73b5462b5bb79273c532cfe4d70238307c6972b539db0384b675dc33b947b7d943c068047d52aa10a648d7b6c698ebf93935fd16196828220fb3c835dae76ac74a10ae25792d23b3555ad11f6e3ee667b64e49b03c1a19f880e15c003aee1667cb74d9e67a78917a6540e8b78d6c94256e4af9b2c148398bd2ea3f85651a86acfe0f794fca1d63918e1a07303c11631b87cd9657e236d7020cab84550dbaba2645131a2717992db68602135a9b158fddcbef84280cbabceab751ef874a25a246af5e91c434a2043b20d2eff6bf3531eeb0a18f74d4c55e7612975c62cc70ee9145a20dbaac5c714669df8135a5f374a072ba1848d03935d4464b5aa717cfdb3b6cbb1267108b7bbca68b62415e80dce6a9459f4da11ffb895fabe3e024c2af21814ec47a9facbd28eadbdf99411f087307302de10ffc39330c2a6f2b2b7d722efa9705c9cf507ad0dc5420375554059adf9ab510786b733b0b92745a0d41459f274d068ba93b28a4a753f26684661644edb286a21294c560f91263677164f896e27f65ae6654626ea67fde3a6a0026cd43f5294154332a6c26b1b09ffc683cc4808de0c8ba666e4afa61c345a91d376a3719b0de722988b10a659f3e8452f61237150340318964d25cd81818bcbc856c39e1c0a71e5dd8ee8d856e1bda05ee368fa4a893d08597d8321241acb59a72ce50e8c267f44e8b6af8dd93ee4f81d9d270ade3b26b8542f218e1a6d139a8594831145d7b45da337132e44ac3e39a19fdfb8016c0a6df4dd7bbbde53dcc2766846f74aec19e42b3da53cd88583ee28d4722b382884f8dd22ab73ba85fc46dffef1ff338d847ad56827b981aadc0685e3ca4165573981f74aaf9749ca8ba8e5b0444391554a99be3a75704b4343ef561a90f3271aeaddd8241c5560d69ed7c9c155870d85d7258541fe258dad6cbf74be79b61105ab6a26554a0523430edce963dc72409e8423918b397e379838d52239c4de18448670a2260214a133b6c1358d0c47fd0b19f9fe4a4bbe9fc1116fd1b37f56c3aca376927f95ecfe1b533dfb4b416da4729655033fe18a046236570f7c7f44e834ffbf03448ec028b7b0c2c1247475a424ae6520f36fb7268e9d263ccc3152733c0254d1be739fbedd39cbda55d757cd4e1db0932baf90d420609a3206d0685305e1410bdfb085ff79e5753c851fe411e7b0c12dcf116af5cc4731db1d1fe067451a40c497cfb44ec8146f25fa1166e5e345f815a7bedc543543d23d588a745d61b52c81722a728f048e28c6b1932d3482ea952c98172d9bb3d6132b0990f24735871f10849a51a939116e94e17939d69cc9f0a4c22de51fb652cf138fbe52b017ea6ef45686021ac87c8b484513214de059722e05b27d160372f480a4c2f09657bb65a87a3b248829c363fe1f9224e14f3749d4eee3b8a0f5e964018cef58569c8e6be133f24d032f467ed9524435922650a18c33603233271f9733b9b2238ac24773b9f0f7fb9c436058dd919841a7962c1c5b628aad549850230bf6ecb13ffe045c794a6ac8b1473101670189fc36e2543bef753acb81613b4f7f33e9bba42d43bbd95cdacb97c54c0871e66b8416dbd699e916b7b215e018695e758c23b87ccdc3c200f9722f6e6c35c4baf48341f7082e8f89eabbecabf7825fb1f7b3d11719846bbb84bb19c6e90c764d1b1c30234c3df1e8c91fb21d3b6802997dd94b06b1ea6bb5e0d0f6abe3ce08159d6ad6729639d51ecb350258f0d38dd5b52d0814cd64148240200254ad6992cbc8990f6349cbb079f72317e78711491b623bae32c6d22316b4dced9112ebf59912ff5ae318fe1bfc6bccbb88f8240f824d7789e92f8f24302c63c4a87f5ee3c3743ae92ac0bcb9c205a83776b07c09366c90ee8f22fed8f8fa9758add7279794d79b49c003abe18a11dc729a31841a9c56423fa3c6975e58429706ba39bf6724ee292e439266e3ed8b4ad0c9ad8b35799f69bc88a31bab105c45be7f1aad970872e6df4e98bb630f74e5bfd7878c7dfaaa45251a1782ededd9f64fa0dd4aae5a12694d5ac653d9afa9d9c312e38654216225198367abba5175225252d5fce7e514663a86c658eea81eb1844e27f70e6b40ecda3a561dab267c13fe8a62811eb374ceec6f26a3e0a8b27484fae4258ce1f3d95187286d054ac4c3799f0e1c9dcc960518eee0a4bebff25f7697f2863481037fcce4dddc3761f83bdcd4719639b7ae2c30a2a93342b16867b6b33ba218b596e03942947d7b948a68e7d42ca5a89dd75b92537b16002f58e8842f5114e5708cb55a98a0d384fb3b26776f48ca135b3288908085e80db9d6f2862ae83c21486ff3ad6b75cc86abb34974c6e82bb63b106ed2b1879f113cfe0c4809b9efbb279b61b086e9ef0aaf1e61e5b534953ba811573b52771aca68bcf15f454dcb35703c4fd8fef3bfe8dd0d96768529d20e13d5f7599442a111834513ba9f81a2a872d4b829646715c6ca3b712eccb693c767cc59a736f47d19e0ff23d7fe1a63bf0a9b904be2b13e445059599d6036ffc20cd2a7343f54f96b4f9212afe4fea7ad2087508d6867793cb22f34e1a8152edc74dae9652aea5233e4e6ca8baf91746803e2bbeb0f5ab99d10597720cf562783392ead54f24c4baa06c820367ef499658ad7789093a4d5a51671c35bc38a2b635757cf4ddcbe05803d2053795c5b03696825f90182045bdff85f7258eeafaa7fcf4328d71d66b4c8e00ddbad5883f380f443531143ccc6806ca9fb8afb984b2994b46f1c0c9a0e0e43eb5ac79d26f6da811987ce7c22722ec78b13b560fa4023fb0ec684c66e532bef6f4d3458d33c608b59324256211d73b7767cfdf5499475ccbcb895c720f26106203989b4e01ca3f1791b736801d80ad14d56ca2942d657d1351064c851c18c0cd42531ffae5b8300fd9f9216034e775f1afe55af78ba9161b74150b74bb5fe4c45fdf16de4820e294af3c8723e2ffe3ba2cfd97e58e2c2ab15e248700dfe7e679229d854468d1f234ef694c1acbdab9d332dcef2aef9f076b1d35fdbf057feafb1eccb23ed99dd0915c95320c644678d46ff2feea13990daec15d8f8b177fbe818075a9eb10171e8720f57f3c6d34e02a2b31990ece006465a4dcc1763cbdcdb71b72ed44668c2c16e6e5bff74a6ad23d356e8b1ce70e375d0d866cc7841b0469fd916cee05f05cdf8cee7e3ba8b1b10e217c750b51d674ac2fc9449494d65864b9f0dd1a47666446512dc9f7a1a8df99438f41f8029ed48dd494650e2409f2300d30d0b805cffb55b39447325b8db74929a3ef550ce6ba01b76ac91da17add2ffd8b3e47a026ad4dca337609674adc816acfa514cc68b13552cdef987c470d0bfffdba59f8df88013d467a525d62b361994f34d6a09855432aaabe761d6f737c87d12ab15ac501a86ca6e59def1d47bd02c84a1e683df198839098bb7ad62a158de6361e9aefe7329b1fd0a524396c7f56459f1d54075fdc88bf58f35d2d14ff3ce82a623defe13ff94fec8f2fc7d623af6d76dd2fc6bf8e8389e061a16ac0bb179240af122410edbf92b1038f98430c1d79390c692938bf5dba602bb9513b003fb3da01b00734348566d569c2e0d1f4706a6fa718e280de514b2531d6de84286922cbc8f58744651507b2a13c916b9316a94ea5b1ce8564e1b48bb6a4f4021900bdeaa1c2910265ad21ef9a6568255ede454cc24c3ea5887e74d65ba3d4c2938afed12ec7225cbd478f9191018c44e57d8554a209a8e2930b59a130efe9beb1adefe5a21a47a8da2c87d471e30a558898c57f8cf3b930d7b0deb4b3e12ff15f2f143ff5be640b90aa64645a40c72859b293645d0895f57db6afb1ada1857e432dad070b4593e4a56c35830a01180c7154d08ee9b60b50b481b1e6074c0a379c67b45d894db5d04c91e1eeae16d271c6eb6623760991b40f141224e6daf4c5dacd8024762a4483c8ee35707a438cd4ee2bc7dbfd9b29037a74116b8558593a590d05656ba2c670badefe463967fa54589b261132685af51efd6cf6f3d50ffbbf0652faf146714c829d797e125714fb1a4fe6785322bafee52315b1e473ecfbbdad83a15dd4bf12d09e1b3304bf2d1c74d290bbe769a03ee1b09d217ed6adbece49d1b7cafede5a913f6cf44962a99aa1fd4627456befae9f370b32052b370859e09d2486143458082b64b0b077a6503e48904b98396fd80b835bd60c62fbfd9e22194c97d6e472c9d68788fba2c298c01c9f7605a43930ed68ebab620a9895dae330e74f5849283bb3cf7736fd053043c4fc4e54094dd9c6031da601bb0b66bdf691ba9352fb32923bfd897ae7928170beab8803067a58cca3848799a88991e02f9b29f110179acc9e7e2b9fdb029521ccb932f530d7c648b0a3ce8f057815ead4300196c2dfb585e204d5838f6039262dc24bb646e78b465527484c826410133bc558a1254fe6f8715b3ba93f858e3049bd34b7d3a88bca24091868997b13c1cc8980173092ca0e85a8cca06189ce48d5067e30253a61b6a26725e4f5b98083b69230333d84369a1dd40ace7b5154d018348f912a5992f941f14fabe7c983aca8779e398b368cebab0876596f1e0da3489d30cf0e83f94c76d6255ff6159f90168c9fe0af3b78c872484446de221df94a83faa85a676897b488fd402bfad0fa8e0dea7745cba0f730c230dc7a2b5076904231860561b13b119d857e578f6b0d21b02ff7f48cc3440c8f929f019c7f2b611f3cc9243dbc06331f511cbc21618091440e610b9c3873d77271a6dc7131b44c93483c459b9010b28fc8082bd6159520e51ba477d948560e58490875b646b589a3f4ca93cdcabecbb84aa778cba7526901baa8c571b05ff3542f73748312c6297d6cb8bbd34aa16575a3d458068936ac40583cc6d61cea2cde052f093b527a719ea97f58a4d8c08f91992b37f546ec5cc5aa6461256870e7c8d4e2e53e0b0ea52260d95cfc20cfe31a2a1694d60c54ca87a84304a6f9e48d09ca300a52f3671b818c8a4a8df2e95984bf2eeee04bbf732dd7969ff106ec288d21c1af703bdade72807753995feb7fb3a9579a06d4e5c7dddcca926662dd00642929b0c0490f356ce5d2c6e5287e8d27e1a7807f9101008c94b0d9c0e1ab648823bacbcb8c73aaf0fe0f2d3faf2a4cd0ccc74d267340b806e099de67101f9a7ce41235b6c934fc747fdf7b4db93180a0fb43a9fbf5f6bf762a0c025df854a3c44601e1ec5c07b1af33f5ac26194e4d63efa51c6b6ee90954f4dc3236a46980262099a2b8460495538ccab8eaf291a06a17544ab9222ef162c790846441607fd136e4668a954516fe85d7939848e8fb37a33fc08f333a66b095db8c098e9bd928718a3862308cfd0beecd25f0b887afd7e6b5fab7d6579e360745bce2dc4a15d257723a62e5fbd11e065a521a21f6b0dc48fa67af65551f1f337afd57816db04a44e8dff9c229cdcd58e9fbfe8186f321e1385b3d0f839a954ff5b0a118c97b096eb7934a92d1251dd3794fc55f06aa20469de2867705cf54ebd5f9fb614043bf7a31e626da5dc177e04d59026152dbedc8e28bf4150dfdda1bc9f081fc56ae92543e172fc78268fd77dbe48468410af12e17098154ba21a7c5bd6c7e6c235168433d3f62ad838b5a133646e5bbae91c8f3d97612580be6958b2965ef0f58777e0ab89b0f185e3b8781fb77c7c5bff9c62ff4c269741d99760fee18d638e2a164115cc3347506988b9996426b9e8ce7726a46e0651af5c2bd01d12a4199839f834220aa15eb040371f9f25820fd9864a07bdbe736a41434e53a14e6991113a49411357dd4d8c8bac4705c3652190291f565eba2fcf7a78ee5355d4dfee659ab493c58459398d6180daf99e468a13982cb06d8cb3acfab09f71a8da1357844113b321f86d5e17714a3a46ab10c208fba384e8c5ae6d4f508fb514dfc3d207d231ea6232c0c6649f7275e78a46380c4e97a1b483c2c96cf8477c37777c3236cdb405eb58a192d6954896b9ff8f9de9147bc0b05e49eb4801543e522a5b4b9492028175ef6f5a7b53fda1298bb8a16d7b665de590a3f2abf21ead78b31805a158dd1652fc7e7ad45030ad993b188a8ca85bfd465ca4db29cf81497b21b9ef0609858fab22aa6fbd9830a9cfb20ecc5067b37339e0fb8b3763c469ac4b66d2fc20e147cb33662bd579fb5e481d5b725f94c4ec5c61d53f49b0313cfe830878cdaa525d4c2c1af539239a04f0561dc2b047291485fdd0d069f6709bfd08ee44a66fcfd0e9be5989ece9d9e9aef820937faa7ecad14831d924766282549e6fc061d0c6d870178e3e44e865aa03b009b0300e2ed18aa0512edccce2536995fe359147741569bd7f497d2296c5ac0fe06391ed382b25b91fb30d784fb58800d87456d6e48f7d706a1eac6482b7e0b72771a55c6ab0b73d960a9823cc23307297818ffb1d2dd056301e61811a072a81ca5aca69655349a3341b75004a3ad0733a15dc2bd926f8ce124b9494269533a4f00ac48143234a65fee487744212d9c652ae011556ecd8d90d30c2c12e4b876d5a9678d96dd04b7c28ea94926790eda4eb02c0c71fd20d1556bf8cc294ec13071101d23bd2134aae6a8ad93d1e36211fd505945ac60da8b7bfe456326df56763c46f06f1dace70945fa1d0de0939ba698504caf2b31e9f6e6037e2273a302339f14529926bd59aa47a2c198256c7bb4cd55ca5edf8a1447e4647e55a97bc0f9c49e18241344f2ed7405f227626d02ae27b83406483583991b90b0de3b6d17cb42e075fdc47308b32141d3b5098bb4d7d5526a3fa79737be19cdee32cf818994d35438b5e496a8456c795a3e0b0aa4a24caf3c64d64f0a659afcdfbd2159051fccd1c0f6ed016eae649e36995a16b1000d81264e6d64b881861b8a67692622086b8f783b8fde09f46f9426f0249fbb261b69f4bf546014ef77bc7dfe67dfcec41fd97c298bb1c9785e2187e2e62350059d44cc9cecba92c3384bce86f6fb59bb9c0c9686bf143a8d10f9181c2b730ffffb475e85123a74ac5828111928a7e14fb052fe4a7b697d2f795e95eaae986fd2072f293184eafcfd7b0dbf96c2b274eb945e0fe168a4b20d2988e925b5ff1d66542761a065910ce8e51f2894b2db48d989354d2b7a9fd8c6ca0a302adbcff2b71dd11e3017ffb2684aa3c3182717b70942f73a189d2bd65a4e6573c7d08691cd78f54095d002edf689343cd42466c4727590f5c194deea5ae2d94d8ee10cc3718d8ef73bb634651e84e6d5415c92e24dbc21355d3dfc97125e446fcb926735c78a11d0f97d3cc6c0594192ebf1969c25a14169e62c16823f9452578539e44d23d0311f303cc4de5c81bacfe52ff2eb3a0adcc1a23f58ba36ac861a165c303daaffca876b1d9db9b9a978b47cdd5aa1d78a8dd8df3049c7de27f6cb5ff9474c77bb373056bc98b65da18c4160bb0c65484089fb57748da0159a7c434a994ff772f12444935b825a17158c79b898c62988e8d7e736e56cfad7dd9d1e624d27a659135d40654d455aa554d39468df4c6b10f6552764617cc3133268c5b74b22a480b2098c8ab5d87517a857b617ad0db0e14eed72a428fefee7de474cc6d61e03f783d37167932a3adc85d20c0e6ec2d84fa123d600befb16c1d40430199a70a8ac17c0e4a06af1973893fee2d3d0760ade256a6b4ba5f76ef884b20886202164deca28a2d4a42a0571efc4ae8c78495da0cc4bf569956291949eb215d2d42a4a2d582c11d44de33e96ba6d188caa9a54299a40f2c42009db741d16f5fb538d0b4ba6ae85aa9829012ec37dd1258a70994761df56b7fc648d3347de5fe85100bb8568b10e1f35669410d723e0ee4516dba2359ea369aa6b59c44bb0cadc8198bea9f2c531cebff356d3182e5ada72927e8ba2d88752ec5ab7aeb83891747d743bcd571ff6c1970f6b3aacb015edce83ebe6d1490a2620c9152dad0c73b6a422038b3bd37e8ca0b18861a83927cd411a99924f98a13f52d4ed25db86474fa44bf64dfb4e52b4dc6405bc5747748871f14260c0260d3882d0ddd639db941be05ef139f1452e5d703b6a3b372f2e3582c333ee7b505d5eedc0f0097c66c023203b07f29b2d51358abcc4f5e23bce4a5b6727e646931ca12e7e8609681517d1a7d60e308e00958943629ee9a252ddcd43e24c1412768870567164b2963abf2f0552620ed3b6bde3d340b9556e474cfd1c390712f6cbd39cc587725e201e696ec58f7704d54e12207b1159719176554c4c6ce4535ba9225581e7d085a4bc28a1fe7c47b57c4cb5f295f7219fed578ee1dc4946ee6344cd7aa18f6300eb4e476a29c004ab374d03e54ebf7c958e1a8900f48d178216dff0fd2391450e0801d5b356087285556385af74e8857b4dac41fde36dc1ffd78d6e48e4f88a45fd416d5bcaa711699ed60587ebe7c0c7904f715313b6d44e6aeb2e204b927f2f8168b8243977461139b00b6ce3c5f444311622b0f0364bed386d89e9573044c45c4468993fdc526937e712805d3d7eeb116077388e3ec7fcf8d9af799b0d281acc26d823c416836beb853b15069d8c353cb57e8ad46854638022610a497223c1589ada752b0c4eabc8b245802b3119f2a6eb517af69127a43dcdb2ee5f41736da6d3c1d0dcb6b14b12bb99446e2078cac62a240656ad733c3407a480f817d8fab3f95a5df8bcf6474147db78647eeea3da602b9c6505dce49b547a436e5fafe30ebf64bbea6f638abdfe289a55f0494ffb04b6f09aaf35e65e91bafac90a582600db4533370ae0f1e2ae024e70b664988c5161267ba16d828f79cf609e5757a67e5cbbb8c6ea4f05b04fcb9dfabf1305b23defff1b90e4b350d601210842090f8610e9ac03c858f1a55199931332c09efd71d40cf3a418387067852b40773fef7598910b91e4683bb0d202346883cf46bb91771c2658cf27fcd16621cb6434962fa4deeb0b8ea657391b2a11074c93010116a711af1140e083bd814c23406d8c3acf555e40a6a4cacfff8d42f4d09f7f45cd77267017a069ee48a4fcdc7bdcfe5031b1f87f855b54e75dc0050d6757d300676c3e9a6694958350648af709543467a4a66af830b8a7d45f3c3846cf38f86ab11e0111130e514101952586954dbdfb56d588a0e1a47a0a24c51a0210a57d4ada2e65227416645a6f1f2edd4286e1bbbeb7f01c7011d18814cbfc82730081b5f38ca8ba24386c93cdc74836ed5c24a76f916e0c05b1f096fce08e322002bcc14d1ae2b4345822b190f2d431aac0b13e58721003b3fb13318a6b25bf9c90b21e50efe9a8bfb798c995014906842761649b11b726be10a305f8efbe3fbaed1a34a962ac6bacc04830e24fa1d7958d60b71f8a06f52ed9b7f1cb17d36a167be50a71ea4b14494043e39542fc31fa15b10fa722036c63283c2e896cedc716247e9509e8e155e9c4e12ab6ac781bb10c45b63e52e8a994bf365419dc0d9cecfa541ebaec8b3eaaed727144e4048ef3faeee128fd67ee3fcfaa2c83bc81bb20212dca82b07917de6845819ef0923443c2cd6eb863902d39eddf426445bb1253927627fede69e83187d9d73e0ffedc13fd23203101e2edde240dbd2f09182cfaed68671fd297bcc76004a2be8cd26398e2ac7bf314325bef0aa421c38661262a260a649ac44575c511ba0f32e7f9f3d72e95aa1eae3df460afd035557ff9eb1a1e8dd370c3e06c750acf11d54157b2fa769889738d251741572897a15b1ad30ff79ebcb0c5ffe21d74e10f03a4588abe5a8a8153ceed423d94bf81f0f96c55662a695cdf8b60ee9a30a3c7186315f919e1758680b203fc8894a0f87cbd812d1edb7ecf3fabb86092739604b802c95bb1d391285123e23cd352834f968be8a1b44341062432056c439df1e87898b91345c558813c1eef13e750a43d905aa1b4ace4d9669d692ac0c039bdb14259ff69808ede2601d735f706e87f20de45d1110112168aa67ec0a854c5256f5a2c850ebaaf340bdc4495aa0587d3a0d7beac031c122d5efa1c3d2d872fd88f99df273e4bae311790fdbca23762860370b0316f77236e6ad19cfa8496b0178c52c031a424ddccf3f126b8706c0828682c3e704580b808f520bb83177b50559cf4189dcfd32ccaf8165dcbc6984ee1da8aba0c284614fef061e0e22126e0406688c337d7882b85cc3e2da87087c9c170f875a4c7bf228019815d8faf0753a4e1227156110969c2f00069c9e24e8dbec9ce4d4a2c9ac075ec0b8e4331cdc6dc93a1cb0ec91576811b75567d948c14df58a9fbdeb8b0c7298c012f62bfb0ccd19e15a5b67fea7df029273c8f46e26d5d814acf72b497cbea26ed7c12243d12266590f9925650dd2207b3558503e3db7b8e6cfc71ca8cc0ee3e6db17dbcbc50f042903cc13a1b3a3c1bd05ed86daec1b1bddac23090ae502899238d80f8643723c39fd8c965b6ff89613fedd3a9f0f2eb6917d1273d86ed1b6cd0e33499db3b124a6d7166e484f8e7d16195de95c20ec20e374e414b27eac72c33c3c9a0aaad1f5fe50b57da00ce8d2faa108345c77c5be50663dd3c94e0c9fa597d2f350eb2bc3f7836e7aa88aed50ce0cb021c7f0d1c77c1b1f4407e36e53c2dc396ea7e52e082522aa9cd92879f459fad9b96aa07ca500caf6da4b7254c0f0f3adeb328deaaec715fa231db70a6e71a59593f1ddb4c469fb5ac3396ddb73f0ada47388f3d6580b17708a946faf476fd8e3d5bed280fcecc1dd52043390339eb81f5ac8549aac93cfb74a113466476b362d229794d7265ea59a12d15c55f98834aa1fb4c8d1c22a8b219c5c7888408ecb460f69efbe5ede75601b2cb230b55f7dbff177149325b1037e9bc9aad5d5c354f300104a4d68d1418a901b2cf1b86dec0608b4b07f4c876096c984c7ce2170b527a34068db00995cf8a454cef86cfe21642c3e6748d3258a62d22dbd2382dff432cf2659554c21e532f9e2ac302f05aba491fcfb8da5538f4539b2f7eee68450bc856d7eb210829d4e762a7beb03ba12467afdbe457df5da24b23234876aac5a682cfc5caad5a50343d9199e0fd4364f7d2ee9cff9f3da4153b98e6b0143ee283e073302d60b4302fb2ecdc6daeeaf98ac9d56a35f5058f444474542aade0bcce012ea43a9bbf040b3941cb4f5f41bcc15219024f2db0f71b48719cb9b09fae4d80a499c094d14aafc94668afcaf1a0ec4536c9694d6fa1546c8944e1ad0aee9451358e5484002f8ae0d2f0638a92e024d40c10d7563d427405b0682ad2b4e765fa856da365cbc460ede115071b56f6efb7b9a4fe4f201e5d6ad1fe98aa8c71647d003aefe629edd3c55e14f5f8755d729be4e9730c5f430e9dbaa369352941013d1849a183c2bf7b84f7fdf1df18feb24555c3f244568ceae278cd4e34377b698b09c9b8fc2734385b5c712964498602b41f25294383d5f192fbaac25cc6c17d3f71e01c79499bfb31e318c0cbfc21b28b4c57cbbaf54938e41b214fbe7b46d72b42edfbf8f0307b1d4bb281371caf4816b0086b77f7ae2832d7552a188ba95cb5944388c51495fd4133375b26422a848a2488a51bbbb4aff8ea375c03ad9de20a6a89a61dc98f7977eff615608dcd80a1bf9765d014f57925cbf9392e45099b214884efb4db39dd1ab0fa1bab9369aa6245065caf176be4562a3b8f25bad25a2a4501d125544819b982ac02ab750fc4cdf78d812a4ba36cef1a8dea4a5624a0fc81602403db767bbfc7c716604fb1fce750eaa516205b3f76ac8f4099218d72c29a53a2eeb2b62b790576419890c7bd8f34e0ed4e451754f721dd3e5e1b4283c836f5ec4149e59d3c8a159541bbc86277c71dd68adbb87edcdd7b8a1394cc7e6268eb4965200a04419e2014416ea4fdcacc0ff45c06ef99b01224ab3c0d178732580921a5b4b3fa990fd80dd64680e06817f7218e14fa8445c33debe33ed2480d31fb04d04dd3e6a7c0a7d52c4b7d24ec6b6d903fc9f679e67f7c1c31b1fd6608dde99c2e0c6cbe8574bd500778056832e47be72c2087aa0233203e694c76b44ace83abcde141b976eb57bfea431de65bbfd81b5b51ee5c2355be4209af33a3927415844be40b56747e52a59ff8c687b9fc003f930bc99e26e844130e933e7391cbb8e36cb04421080f0ab1dbc7748526992345b209ae151c8ad3446dd407b1e1dfdd34f3ed2851c6f8e6cacc672ea3961f4130ac5ae7d58a168edd9c93fffd223a655eb4eaf4d0cc28d4cd47825e68e0500e9331511f4555aa18ac130e9ef6e8b040833d26d0eb64b5cb2fc8279b1ab30d9e1317bfa6a7c652b0a596e07e72f8015e2f26ad663083db3c036cd69f5551cbec24934924b231a65dc77f8721faadd61fd82707346f98cc0e1688e53efb9045329f3a305bb02d6696ab5214b4bd1c0fcd3dd727cb19d6f66d786e2575e67526d51bcb0500fea0b4f40794224cf68d8ed6bfaf8bfec4a418d1b378109d1957f3f2cd725c61f0670ba27681ba0754aba598a3c60120a1a2319864effb615f66dc280c788d44735cda160897eec811b86ef8f14cbfb2e9b0d5f08a6020d1e4f076b492729c5f6acb37b545540f7bf8105680e0508f0eaca9a3affe392891b9c9168d6042f643fc104897ff1a6629861f8f874c6bcbfc46c80aedba73930b4ae3f4af4a47dd4078b660dd56252e70f48605426d9474474f3a3ea236222103051efb50265b64ccee63d34d20c3d22c321ceac3ae903a654761cc329f8916ce01e81fa9fa70a84b859c58deaeab568263d7fa1265973854940a43aba5074ad6aaaa7d99fdfc551d7f7f7a13768c4542c0928b338146f8f6bb180806434bad4326832b425725c9b29e8e36e4a76c2a20936f65a83f6872a4e0d4ec4080977c8a0ec746badf2e41ecc6dc23c8be7194a5c3f23c3e346707401203fcc25e4a5f5055d7e1cd78e89e7fe0d7f2a30c3d285d708c50e1c4731f14afdd3793dc6732cfa144e6ff6838a70f0b9b50580a36629b59fcf67190a76849c369c8f99822017ce167424298189e94791b4064d41d738e19c3a675999db513fe36115b0e610c4857266e245211552aa1593efd6a05c3f5036cbba02ba53b3582fcb407920b61f443c0e8683470ecd43f74caa8324353e1108c1be4861ca859fe749aa684899dbcbb4c720df8a457c5c259d1c813168fc4e4d7a2bbe7a4820d010f97e90476c8663fd3b4f578ab6cce9d0c322e68902d5a21b03f0e57455c4dd3887643e72b64f7f9033eb44b4a65302c781db4e88e953e204f41727c6d6e1746104d020d3b6756e2ba3cd608a4a908b406ad65d2762c480b037eefddb7c38d92123d7cdf0c1fd48638cbae9b3e8661a661e67d7240f3160ca47437648643769e62ce65cc834ef17ce075022ebbbab09f337755337b218797bcaa8cbb6a97f13079fac1a92b702d035d27a5c88b9631ebeef3c4962eb8d51cc07daad58a0e5f356a12acb26411be3e93e48bbd0299dab043999c1476138498ff369972a6d8f0982d3bd4c2f1539e603deb403027f61981be36ac87e100e23a7d8fde8c43bc64bf9139bf673a645eb3b95217e71fb54bfd981c707338e564d6fb2a6a14e432b7637476223874f54bde7f9f8916965e0ed0e18759f2640828cf67289e782a025f5bd5d6a37cdff9ece1e9c00d1e84c33bc85e0b6cdd9b079f66d033c74dc9dd7802ef0e253f8ffa1d78e6891f41c25fd6aae471339c9895e8ae75cb4fd2e1d6365c1ed4e369e52794e2adeab7a8d2550fc359179574fb0749dc1a252affed02c706bef62bb3365babdaaa5630b89ecc5801fe4f78b8db5a9d368e276ed6f842c523a8adf74e7a3ef202c1d18f6af4745324163f5d0efadcbaaef720bbab5d0a15497ecdf991e9fce33e1af47e70464b3af072becada6109a232177c5058c878464b5bc93effb74465b2c532a10aca7737ed5797c93fe2421a572a948ad2d27a1351a0960744bce5133a05eb08679d626ba4d21679d5f4d81cd2b84b48690687349c9b68ea927673612227303556baed1a33cbffa0282e089d772286cad92662ac7753aef9336e4425fac3bb2374f5c276bebccc2b713eb71030dec28f071bebc6db0362e30976fecaedb2d3e600dcb037861a4e83d50b89e90f46e7c63f1e41a147529cb77d8f5623b4fc72aace80131d034190bb21044336284cdbcd42064ce3f05d1c6f8c8f7289a81bff1ee8494881b017751361a5a7cb71a77af62bdce7797e40c5a654a36a5de6a81d8d2ee210a36f73b8925100387078c9572a92c01eb7f9089fc17a4cdb6ccbffb8c342ae8b0d525d777cab5003c3549180cbd21794c30b36da5b413ea5d89891d03034a4d5238c7088e5caf15cd6e75931427050f482fd9d6d150688bb16e51bed327e4c8c5fc70ba47ceb26f1b046a1a26ca596e8fdb4788da7e8b23f4328d72272ddd1c4c4641d36ae9d4fc43c57d793e003c2f369a092e7cc60ff0f025b229b5a42a520e6d0206cca35cc41119658690ac805314339f91c1101e7d8d509075fc150e1884c212976272bb03b132588a622caf09a1d800407e042b80933df9111be6b0bb0d89c39b1dce6ad83cecb1b261459900cbe926fb2ce4b10c8d5a5d29c4f094789b5de79d9b5c56a5b30a1cd9c0dc276602f2554fb6651074b5984937d9a5723b1bdbcb2d52a88aee0d33f0b65cdca3f8b1cd792074111cf0be5633e4b3a4655f22b8fde88a004a38a5b3d69763f3d2836167514d3535ae8e366c07e5933c15560854b4889d6e0c31d9917479b45300b91ac39fe8d9ffd42d45c9365b9f3d26f5174f1b7e9821b61058b0ec8227c72d1705a0182a943d504177901500b055c86a64818f9b68ee5d92f8740964e39fc412d2810c83292094310a6d456586d5ca951e14401d68fd37052f5b4bae5a0b24680ec7bbc748a26b2259e7c85d95f53ca810e98509312f1a875222d6844a340e82e1dcfbeec4108c02a6f66f693bcf6bd1c6c1eb74b499c607ae35f75a531c33eb35b91e5066bbb12112bf9776036f9f3527001e2746835aa44b47296f16b08aef9f6026a961ef065b270f081419785512cb95d6354f54023b850753f2c61cb69005d40f5aeba4c56da46715413f41b5c5352cdaa495a75211462c2d91ea8e2b516040111a15beceb8cc00dbc9e5286db840408e08c1ecb70937f831886d4980619ae32630b30c479a88d7b2ae7c44ecb00583afea12c54be3c0211d7e475fa4ed394e071949d6697a8907460a9dfa061c98a824e952417f272f41f11910f8c135b824d02e77493cae21e5ff9e5d50d323cbab53bc2e927976e623b97bff59dd92e9b8555fabdb17b4ce97bfe09ab58f31a1a824f18bbc4c612978abdf1c005ad08350ffd70f388d17598bef7210607dfe2bae222b90112f5b133eff8a6416c0df8d208e029dace3acb4beba139b8475ea4e66e770f2ea585ecdcaee22584b82d569ffa130e98be03a297406fbe753e205114b113f91cf18fa30aadc3115dca104c7b9439b871291df11e182842cc9e323fa91a5174c8cadf121a86444c507692a5241a3dd929e86149574addbd44ddb9a268294b81f2aa3f57e37317e3007b2cf0bc0016f49de6e6e98f7c8f385a642527a8ccdd0c54bc4b4390fa4eecee4834251e10afae8ce2dc48f906f9c47aa82fa41288a5a6771cf07163e809015512f6c09c0db795b79b86bf848dca9ebe4d8331a4ae3793f482468df449b8ce45296b1fbf4807c930d9ec5d6727b9cd8b14523d57b20f348a9c050229a5c09368811d57c35fa2fdace1b7951db0afd5ffa9a4321154c6628a0a3619d25643e3df040b6a00aabba486d9f62324307c4bd84132062c90930d8d2732629052332934473cdb749496f7b7901c8f7b399e8177a359439397827f89778d945d1e32ba5cecbdb7f28ee027cb3b841656044132f613d2604aef92bc579a0a550839a58a8cb4cdba500920e0a7d546a58786c930b0b21a893a1c30517d2bec1da30303628289fd725f53dd54b27b9e94ad42d931c8a53c47fab25d7011ae93244e063de177a28b06126bd88d9b1410fdfd68e0b65ee9a766ee3df83e20d463081975a01f730449423f87e9e29e5aad709c0664858a1314c6f508acb4a2ab4469df7040bb9e1c673f3c2ee5ca663e408404dbccafa52a10061e66c22f703b94f868285c7bb98dd531099f0723a7b76ddd2ab6cbab314230e87598f01edc4ddc3cdfcf53afbbb9fb01e7224f3456abe108c677e23812ddc284cc3fff1b8c8750ca031c4a9b3fcad560e79d104bb665ccf81e304064dde861f0643d1100b3ddbfef4b81f29fd8859601b695d10182c2b99d7b5c553b1dd5a2b5525971526d561d678dfba2f30c2e55d5a07809d99eecb977efa4ddc46dcc8edcd661dc71dee1db6ab54e0a65c5ecc447eaf95d606881e1f72fe826c36941f504369b1576d7990018e8efb95faa1e7c29b15f388ad35bd927f9abd00ce7698422a570ba941ab37a58058c3080bb58c91ca7cb2a7aadacf3be0ba6e6225aba09900c496569ab9f44bcf04d26720677c8acfb8a4f6f3c1b474c5d7ec3b96b0330cd04c6dc752e2852023bd0bbfb29e005fdd85ded4ca3e000e9953e8a4e9e15f93a0005569d02f785f41cec0886dceff5d68ba57c3a4d30f19340bb571124255e56e5fc056f4cbb145a1a8220f8c1f42306eea1fa0616900c524aba1e5a27452e6d6efb6d103742d10ace573389756dfc1289b6daf987d620f40aad12abbf0bbc13a6597f57e0776eb3f0c6d45a104bf050cea1d066ccd97fbf725f2db127b7785c15b16e7d3c5d91f4058e5d170bc4badeba0fb33a7a39113afcb6ccf379dd2c993fb0703f9945303691c43bfe911da45e43249be2a1be0d1dd64874f1bec8d92afd0a53dab047bd573cc32ebc42cda2a340dd7682aa6a4e4019f7fd50f91a85fdb3a47db161d8572147384b23db9289559ae0b40639a236880386f3634bafe546a6978e51e191cd4c2e00e18793eba0151e231c8390dff57472749a1bf87538d0a716f564ba9de5ad1575e3658520b795610ec90b35d14aeebc988fe7f45e9677d7fe298e9b4f25e18cf6f01cd62acc295761cc861b66d9d35dc6e65da2ced062bbe35148d6b18652a839dbaf98430becce9651dbdab3a4b85a18b62e213d96f85982ba01ef105c41fc0c0a29fc6065dad9a21ff2657c2b6d562647df0985594139a5162ac2fb0f2c95bf91d972bf8462c1215e5913225fce25b3b5380ef52e63aa28b27ab5a03277f74f72bb2cff64b4c28edc59c664604c2ec028645e5119f05efa8aa73ee89d2a27ce1b3a24697046572811b3a492ed1c1a38a1f8aba4730ae88c1012fc82d54ec1e1d2d82d3ed5acd0e9b300aa022e0f3450c152868ff883c2b833b57070c252c6e657a367963c80ed49b049db7aa398e090458b572d452f09302fcc3870b721a93433207e0e8723dff2adb2729c73cfa3766240cd0048c1f57e45cd9c2b483c28a1770d0e7ada555f58cb7f773786e3120f9205ec7b81bafe4ec6927b4d4ef21816f31592a78977b16521d1851612d5d4342d6ce8317c782a09f70412310f0400371af3ebf0393d0fe4865263b7e868370db1661406baa9af8ccbd108d3490307cae02777032823331ecefc7b375ed855161bb06320605c2b006a119811edc25464bf1925581b8d90c9d3ba063b1aae129c834a060efc15347d2e151b49b2bdc244a65d4d53702d160e697d709f1b645dd0f20e130085c159dec5bd92279777c46aed8f817e68d74c1bf12aed8269ee817130d0f0dc909f919efc97779884f8f921b28adf424b189930a4951a8d031cd58804d05ec2b807cb43cfeccea532d5f8727b4a0b35351518937cf12bb563687d257657a270e4d1cd78ca97045eb04c4c519427194c8f7d010015af4ed6f129667a32b8cd464b46703166b233acfab8d7d22d801e27a0cccee4df847674abe89c625242199f41d20c2a6e0e5df842b44e2f758607b312247d1c64c85fc249e1bdf586bb635f7eacd33fb10e82a186147c01af059f2592b4488792e7085ee57cd04149bf2db08727e2c72144e1d74580d2a5d1bbbadf9595368ba97d152059a5724aeba0c00b9bd99a22b11ca2049711a27f4d991c8796f4fd740b73177e49a9ea3653983860a5d752080de67576d8cb80a48e1e939e488d3cb50897ee027641915c4e7885bb8a28c6919c93a6530eac68a10e5a144922036db894c51a4c027deca54855b3d42f971b4e798d2563593b4a971e10c47b41c5d93cfd117e89e38425e141729c10349380a3098e7a12c519c674a488bc94fdaf725bc564bd424088e412f97dfc023d50f066e0a9da5489c178569fb9bfedbf96b07f3fb4888b06bfb3e8f24a411b304e2aa753414380ab81d3cac9577474cd716b0a238ed2ae28634220e2319be83de3726a0efde67a743692de5712a2868d9a64b2ade8d6c8d5a854f2ef9e60039e6fd24872f35a29c33d223146e7f459df25b3d15e29e02526d325d44274c02ace250d9f3f6315af92007cf85831461ae220e7038508b82853a228056475d829d9efdcd60d7ebea7265903ea1d19f5c2df07c30b203543af459ad95bb51b8b777a1aae5ff3ca4119214753858a29b31451bd1b62bd32ab421bbf68b20f065881940f6d8f25d9b1e46bd106b3ba509d0b3d8a094ea159785a00332a00313a85f71222044100d47af0207a202f5c2dc101486c0da93c16705e6cad60bbcbc3642bf7cf822d9623e8697977d56ab7834b00081d08e33af0ba2e730730bb55827fd82d3c66c62c4d71e7d05c42cf4df1735cac7f3355f47983aa072e2aad75a1828718c6ccb1fc95ad902795f00b8e756bc8c6ebbcdb73866692183f7919b5c777c2dc53d195771e81cc5735d562aa383c90aafb71347d55ae284125ac8046ba44aa464d6203dc7e96e979fbc1a3d0a88ac38f3abc70c404166b35853458e8e59a8694ffaf419c8b5dd30c9db4691c2ed73c2528ecd9915343274948cf0d5cd7ac2338e48fd5d1d5cc85ab1967f15bd9d415733f3120ed41bed56b5e83f6ac68dac409ed498bb3890ced49e4bff6832019f26cb28c36908e0cca519ee9700d1b058cc2aa48672bdc3ed007676efb7843b4957a86221afbebaf65fd977bb2e8a26c0c18e11126ac4b6d33681aefe47799cccf6538058d7e3d601dd948ee246646f8b32953d718304480d23c34052ba53f2daefd3d2905d4324560fa230c11be291438ab5255dd42fce99363b0104f5e3c26c2bf7f8d5d823de67b973130714aa33ab0fa7fb1de03e1239fd2c401054d6f5969583c7973f5bfbae0069c3439179cf9e1ffcace3d2e84faaf0769a9db1d36f4edcf5fb089d1c710e5f51ce668f81c548fd6d9ffc5714f7adfb13e2fe54154cf167d4d4e3efe993dd3bb60c8f73a0a89894a3ab4be3c41c1e4398423c4f16c8faf10241d089b186ead9044ffeb5123aa2e813af3bf70438c2cdbe7f53a20c5b528e6cc30eec8d635cfff6882ab9c652058d1afc1431f212b3b7ffbaa2de0f56e6c2c40400b81c48c51d91ba05bd5d09a4f3749f14a04ac29300c6be9d6839c8a99e0e7d4d2ca6126532b9a8beff61a8bc81a308eff390e868931098090eb22ded1f16908154bf4b07c63be36c714f975a2fe73cc0094a880c0a1f7fc6794bff27891ac58bfce74fd4712c19dbe4c982ea02bdb2f0512aed0cf3d763b43268929589508ad0715d844d7c483d8731511e947845da5f09f47b5d93cf865cf0ccc8bee617d0c12baa70f150715d1bb81b3d9bcb5f31238668ae03fd71637cfe6cab5411eebceb31c65bae3fe797a9a0f2790612ec49d2b775ecd686efa1d28ade92373675bd8e7942d082624118bde894d545846341c5a54f8609b481421903615e0ac42088d5cc29f2b7017988ff91a961731acf8b28c32cb3c971ecd6d1216826a098f89b61cad2e29e1716f8a691c025683d6916da1b15330d397ec8c6fb38fa5d9791e9ea68c6c9196e2c6614c0617842e6375009e9580b69672623d4258f94f6f778a4741b0f1ea06bc10a37e87358d7260a88165f0f726e31715d2e67be49255a2fdf10dd1819f5a08060180e3c0e3caac1a92a3d997f67dc71ab383e20072b3edb4661e2eace90ac53b78bef6641ec07e5d754f57e2d35c5f2e598f686a4dd277e31d0e63c11e354e10004b71b300214d835f4ce2d67ce1d6d3b7391b858ddd5ae0a24ba7914708e6ede22fda0ffa3c760311a8f430d72318b03b40ebcabc58256c92bedfa1c967cf124da9f372fc1f0ddf37c0a3cfc56a24a8d0a9b1d79e60628ef1bae8999904cfe0c2cb6c7f500b330f25f677530a977a1d4194914bb1da953adf75deb35bd13616dcb66ab995b1b24774ef67a712103e9a42aa608c2775870ee56f143c52954a0089c8ac938584fe996a5e3cb7315d259bf95d45ced9bef79820f0b00e9a01b18159ec37fbb0892fd08691b8ffee335c50e6c1a47227afff224a0e994b0f0fb497832ac9992e53fbbe235121f227c4c52f438cf0ac5efc28be0a9e373c3feef4e84f42ca702c7621e7a0545e881d16a6d07770f6186656f0d8e594057b8bad95f556313ea50ced1da2da7de18ba0b3e2fc810572ebec9f80e48f56d75ba1be55d38e0ccc5d64bf3c170378cc2df0965bd4b0f4098c333c54518ae46878d8418a4ac2b89b65e90b7c59d77567ddc01d5b4d2c1dc032cca531c7be1ef7e18b9fd8a45cb665a428c2923a196dba485676e8828c570c856b3f7988681c5637a990d39f186ef9e16ed0250d2a9f0edae5fb058c8511f4cb08c95156809a39eabcd65b57d66d995008b390a3f97ef9ee00960b3ede6a11010d06072634df2dd5deb642e49b5d636c2abdee1e91ccc055ce958262c67fd0c84754f57e9458fdc96695933be7c2d3c2fee5409a8d7d13e621cd0147687dcb1e33cf1a4ecc425af350985872bccd3252dd86616d3090cdc2553800b68740bd8763fb87564a95bc8ec59b419b915d6181b53716db970f88cd33311729b920480ddbe3cfe3df41ddbe4f11c2cf2a44984f21578e2a9774297bc5fc0ad07b6f5455a5a12d3a81d50c560a17a3b81aff44cab18b2a360e5540364f83f48ec4c905559e25869ea0748f17eb00589246b5edd575a99135e62ee8892d9566680d8d8a0fb155ad7d100e10e9a72b0399a0c8f8a10ea1a0b448101ddecdd76dcf197b8bc00378b60c59838e2c4297c7420ee2c1a8d4124af486ce3574d40c1c66d2bc86521ab370be8445161890aaf944bb976d41e891f6744f12ab0a4a595316a6b80a8a1194e4660318c1a4633cf1d67e71d8099a08df7be510c7ff435735f36f720e40f3e903eae2971c0ea042d3b0766443a82ca2ea8448b5639cfa5a2f2da54de0fe38222aaea28c8ffb470c023a20c3bf347e0b5da0a45d7b2ee97a7482eb309596c6043d0eeb0cf2c2a16d1b317d2af0ff237adc377c7f50af66b9af5416cef7ffcf79f6ac0ed014c207901a1825092cc1077d4630085b95ea0890e4264da4ebdbbf5223ac098a52c6d0bb1e4f17008a28115da485fe8ed2d642facf67177bee9299cc6b9ce9e54a9e540a57a1a4cf5879d21e31ffb41d272b3c7fc3e2abe728001b46c5f56678a8c28a54dbe8353e4d58c9031aa48ecb456713cb24dbf2dbb177c93c78781ef3881a26155f8e9471c4a3eb698ae9f1040a212977df8a0acf020d0632dcfceb86c7bba31f3f67fafebe3b417962b046dab8a58eaa0b88e333402d0a31adfeb187d4e815c04cf0bff589a03b356a50f9291af358c7ffdbde6fcf0fc60fda31f8559040a8d346baa25694bb14663858ea7391d0b6c2eb6e9e7b71333e21505d54130f47512bcf5d0ea18f1d5aea02f15026de8f38369e1eca3c2f2006c66e477f1c70f1dadacf13f6c51c886fbe870c23645c0724d0cb997ff39bd985b911c4048e392f2d94d34b7987ceb0ebb05a3fa37ff680caa02cfacb3d570dd2710012faf63af9d73c99ff341734be5c9070d6bad1a568fb0c394d5a06c491b5fddf0c5e8e0b3546ba40e04e68c746ca7015bc5c2c589c4b1238e4448ea31cd2ebccd2a6dae3b22d33f4788e9b38447471a5f0835c1a47a6ea8117bd54523b3b890d280337d2c1eb527f056e9e51b1fe5c393a16f726c6c1895429e3a263f56e90fd540d24e4628800b338efa7a8494fd131f19c45424811c8bde758c5a37ba09f3069336e24e81d3276688516cdd1410050a6e376de27354f5b2649c3140bb2446abbd2b468a0054c9d00ff5276d043c0b53d9cc317235c100232e31b2b2f6d81fe4cad5282bcbd64bd9c01af7d25c0d027a7d95ca4e991800154dbf0052302a4ef4149308c61d1162869a6e5bc47348289922aa78e937c3dc5eede5ea1127e64b1e2bbe396c7a0f8a0c1ae0eadca6003c3d06585a77232629b4f50c117acdbfd996402dfc854d20620b3823f686c8c415c49d197de3e6e06d3fa5502d8f2a1322bddc45c1b55e56b87d20f81295807da055d46e5ce54d0aaea47160d099b9012367b1b835286aaf222cd090534794f52f5005a988d58e595d0bbbf44689ad9619a015b4273b2e772130e84ff100b68265944df96bcf67f393944c56bbd124753750a622ea8e7d61cc08dba44ec568a107382582954ce444696045eb6b1bcefecf53fa4a26cb43d8b2d07f78c33bae6ae46ef62839cf4766adc19cf45445bf0c442d78c2a31a33d173d0d3cd846222348ba0643ac4a512e5b778b42622e43620bc79650b1eb85c26750d6ad1c1674e49b2f5011d7e185e6aa02889d9773d7752444ff806e3d80c48f8265d32246037ff3b6e7c10aebaf39d11c8a9614dbf2c34028f6d65f28db533fdbb35f72f28d32aafe8ba82fdb7c91da62005004307cd44589dd348e30aaf95ef21c2c5d51a0bc749de3f1ad6dbe66b16d6e4926087e65cd996dfff09e9f21c6093a8f5f89957de6ac11c1238515ea6c07d600785833796e0aef0ceb4f9c37c74b6ec35f267e4c556b1a2069bc67e27aeb7c1bec0b1ef0149cf513c3a5568d65d9fd3980fc9d711992a635326143b781a3992da82f00647dbbe39302b37acfb8d37c7093ce6074a9fbfd23c63e5dabadc7c954922a39f936dc69feee52c70c2fdb4131954b4f5b93a392e4801cd602a982ac85f9895028297f8c536cacf522364ce29be7142e5afb0559b49272afb98415f1bb8035b1fb3acf4729511ba6a1b6384d099654aca23a97431afba36b1f46742f8f72b0f1561592a31f5908d4d26de5b3b8206f713b3c05cee1d337b49bcbd8fe3998df4bcc02bc1b4784aa9a3dd4f54be00b9371e0beb012fe4568444baf1d3ed9e088fb105549622436702b72a1570aacb6380b7b2d86d885202263beba105d186dba5067bd853c88f90e58a7110c7e34f3d69d8ef154e2964fcb585c82739832419ef33592e78e8546087051e3b97774b34a1fbbcef28b03f5ffafe3562662dd6ad8a381db3623ad85a7d856b88fe8d7f8fe31b304b2d25144ff68ac357f0017cb8815d883e1d771900cf18613fea667135b45cd271e14a0b3645d822d4660ac0eec1cd179dd9fe724f3e26e6c006c3a91ec36c14e0e1cd65a42e0d4e0c31d4622768581ea7042cbebe65c73eecdf834e3807461cf2c51df7455cb15724031e522f7d3f8c67747e36eefa2d9b48cbdbc0fdd975960011100da999236e4d21fe474662da4a18ac76b00463df7ca31ca974eaa6986b666a84ac229dc2f926c2fdeca9c88e200dea9c00157b2796205c3bcd4cb890a6f057f4fc5f732c221d1b5ec80af740935269b0c0c4aa8bf30c7f9218026cef1bfb63ad3c34f2a744b10460910f5270c7cb30afa6ac5cdf8faf801cd9a219af5131a0752aa8765a367f081dfe39e7153c56be942a400d902d2f08f7684816a7b4d028f16d927d566b946964bc0e5d79f5b546551e43f09b0143eb874582a324a70ad3747e416ee6d1c151ea7cd930430de5842596036a49f84f76858568de2e21b998a19027a7c23bf1b83fc9836ecebb0ebb24055aa67909f4408504289ef0001e5ff9992599607827157e7bc8fe40544a774373a054da156ab81b26af00b3cf0fde077c186ff1552c9d81e3f2ab3efeca312800d322d944b074c2f1a4cdf7bcd28a9dc92f610ef3f4fa1473cba6eb635989727424bde0a8b858cbfcdd41107e36ae22923b1997762be26be37027cd182bc168e0980156fa13fc0df19b7356ff25551ed9aeeddcf9262832c158cc6a65221722257f398e19ba3da1aa36df8c25009955bc191920a80731a68d3e57510d2c4e21018e20e6a4489c48a76cca3e3a5df1f3968dc57db0a1f6f6eda4306e63f61897ddee030cf6ea6fad410be106fb216d9903134cca47cdc400b4d474d6263f6f2fb0890c65495ff93dcd1841474608a1dc58eeb06f20896f1f1889044a022198e937fb5915609339965fe0fc5b9f393109060a6e6814e623512e6d2895bf0f5743e26412e07c0dfc4a9f028a552e6f56097159709807e311544c6f500d0da81c65159889b9d188624575296b27624592364ae5a03963fa38c13ee1dc8b63dff680fc2159ff690cddf4e6f7f5b2fd6bfc945e849e189db2c1caec10b752b680663031254e5303fa8813b18877ab16b1682a8ab752745f579b987292438e724ee307971f41396bf5dcdadcd097cea3f5b343569ef201a6178c4a88901803009123829b23667f51b53b567eaf2e9a548b8c12bc8a4cc33f4f54498a9f00f0ccf284e64e5d0e42a483900e6004931d095fe2d655db2c2debfc336bd04c5af6012e55214f4380aa06c431685c90eed8726a9cb50a98bd24121ae93d005a6921bfa46e8afbea85b31e8b257b04df79610ddd8c5ec7657c13a4553487b0999192a06dbe6aad836e20e0f1159759d15ab53f7dfe1a2b620f0a49f447e610c3e8974d2122703060171577b998c45ffc5ed286a0ce7a95e2317c61a1fde0b010e28552ab51f39fff86bfa0bed7723b6a3b5753dda837474b85451b9db0a18e542579ae7bf89e1cdb6e2f03d63e8db2e810f3e8cd75ae849c47382f09097e2aeaf45d667e6971ad54bf2b1d53da478054f4c5f60af2511fc4054ed8554e6af62fc0ff3b11f9e697109a3d275446aa67e692f06ad7a7d4d06ea3e1838c64a574fa5611e4b48d95c8b748cd3c3fe82cdc1d2a1d9c2667638874aff85941a3b34fdf53bfd83c6d3a82c1d1d2f605e273137a82bb94d8cffad8c16a823d610efd2f40dffdf5bb805d1a7c0f1a33e0430a92e677352d15fee12be518f14b35c0bd154133c8b697c734111600bb4adf68202c8513beb92808fadb018b604cf59629ff8e5988ba69da7fd42bd1ca11ba81bec5912286c5f720d4538accee518fadd83e2c373aa350596579c47105f5c4862d3edc8d26612799ccf1ae882158df1a657092c135c2dc10aa976926f24ecd8013f1761eceb0f4210b3b875028aa22f7035acc37176e25d197dc6eef125f6dfb614ec8369769d5e94b3093adb5dacf591187bdb2730cbc26c35e1129d1285bd86c2188f196a1961788bdfd18c13486d11593a8078c9ecd612f305cc4b1e501de5d5a06bccfb5644f82ed993439ff362362beae3544234bdf24cd2946c7d7f4be38269e5fe521bfa1ddef4d438e02b89cd351290fd46408e7891c0733e8321bdea3d19f70ea58af6aa4297e9a44a5485251ac70c546d36d257faec94d5915b8e3acb0f7fba1d82e039bed53d08e0f1a9a6b72ebb507311c5f2112199494fc1b9c9a485b1f6c2d0a8c11f5470a26de24f7f40f755de28dfef9c4150cd79c262236851e7bb36c47df7ae4b45b81456e361d7c8a24131486e7a9ec292459fc5d44dd6c4df2ae1fa04a5bc7d9d13dc1f786894573eee27c59eb0e7bfdb659c070ec5784a38bc41b1857ec8753b722c7fcb313a09e0a3cc0d51742cd77b5fb510e572cfce0cdf1f1d0d91b2ddb76850a2a9f5a92cd3f37abd6a1ece8a322e32f62235852373a900329a533eff588ece69e2d6e5fda37b2129b3e1780e11cec191e1b6fe1c1cda6d40308d0ebe35ede8dd23ce6f41def9f8b96bb6fe763d458db3b0dca7583a783e8dade22780eee5287ac50461e310390d05c4ea46a9cca3c4f1190b75b37bdac2faf90e517f531ad23fd7142739acb341838d92d376b5090dd7fb283a317b4c4b36560b8c136e43b6707f1cb12ec44f7bd42ce97eec831bf8a115919b69e1e600edc6aff811462137fc89ca95f3ed19b5d52a27d4e8945560796179db3384bca7a8a1e9cede775a3c20ba2f803dbc5825880de77e29f610a7a86cc931ce134b24d10cc2adfe81cc7390b37d18e75e246ed18f70a1fe21bdcda36ce508fb030f478bb815e8640de5aec78ab4c91b619eb1534ce4d94f2521118affcb928e92ebe831753feeccc315fec9c92b22f8bd5ce7a909f91a27561d807392ac0db480097999dcff472e4b374378885135c64f2691ad361b8816408f027c8f1f68048b44fb4f3097f84f5a63ee3a2754f8166bd13c9116d5b1bc2144569b7d6ba3e7a8da1dbbb5e0a8efa35d6e8ac97a62de4440a44d359fddfa436e8a7a63140ac2c65e6f9d817721c0ef8b56f8cac3fde8fb1b1a9d5ea362648cbf409ae4d02007a57e43d2dae7129571e31e14198faa999fd346ec4086ef60e50d4d673df706b23e7a17f73103ff9d4b347aea1a547a19972425c17b98b54430d8dc2fc284ea1387fcbdf4244b4a1255a75e0725b1eb66c3f35da3b18154c37008fa0c15ae9cd7c17b295e333bcb41ec94d6e881829e67f64eaed4c67f36ebe5ad1f7389189bd9007cf3db736775aca3bb24fe0ab95d075cc47dddc757ae4c7c333b4e48f52ee4e6fbd807adb662d6209a7986c9b6708c8faa25d782e59a3556ce08376d9bbb873c84e3c96485c06c40d86144575abf2079135a3025e8b869a3bb01fb04b1d4bf9cb6e2f8973208cb60d03b7cb3f6469aa0276efd625bac770e668288a85de3ea37090c08056d14c596ce8ef91bb05f4b99e2ad6dd59d8b3ee844f54074eddf23c0bac28aebb333b600b4448ccd15d6a238fd36cf24d4491068530f4e9b3afb14b36dcb4e2cf85bce5d17eaa85a8e5bf905ac283432a69cd185ec881d286652d6ec1280053be6008fac09f437b422eee667109bda6441f7cfc1587a20431912e1fce82856f7979dbf0eaeceb8780007d0a8fa49e00c6b7cc49ef40d92fdabb83535cc579d12e5b7454dc18f6aae537ecaf1fa79a5ca4abead9e16540d7ff5ae544258cbc094cbda772d214452b84f52dde77643400fed1a67c71b1f014af296d47a06ac852121afe2baa2c1d4750c044824f1cd4669054acf67af862af737001c59390dc92b5efe935df85383ecaffd1525f056b0fac1de818e9ddea16b779a81aaf72eadfc10c2659822195fa0af0303231e63bf65730ea953243854e5cead9347cda6bf3c1c89d6e3c8f431adc8ec07c155ffbb6b22cbd568369ace48bdd0a00c0f8df82b85b12fc2741659b1981869522a7f9215949b435d153a14f919dd5aa41a927e7467dcd2ff27ad943d5c43baa2e1d5bfdab01be6f1fb814fda892b3a83bb2f54a757923d619eb336c78a961b969d50b921caf531d6e13c76e28651a73baf6038299e1a8b0b83592cdcff3d3c668dfa66a226e8cc82582bb96fffad87133e16bb85306e092028ee24187fdf0723b949ba4092a9ce5718d9de2742545e1fa2164b40ec08e50291d9143dd812db3d944d1132c1751155f5ae10d6f0b5b2dc864b7ac4a8e145aae3f6bf0a770c860878578fa46b3cebac318cc4550f0a2c6bdcf7b165fd58e311513b56c063cf3946d3815b3cf09fd77b24f4620cdcb839e46bee8fee97ca245059b176ce7cb047bee8070e8f7654c492cec1f2389509a37c27c5b039458ad6c440992ff2281fadc48c358e5c68b26e01e2833cd21c7d5e17640dbd6150fd1b63d15711d2fe1b375402c4d89f10cf4e20b279423c094bff8a16c4e5922bbde54758f9e4b0a51c3c280548d7c723b9a898133fc24dff08e410c59a89d1acf17823bc68c0f3b82835050425ba88e106a634a26cc67f6836b30d3ce6da12fbedfd1d77bea8e3eae922e971db0c6e5246df2e539244ca95ad39f85f61879f6d6fe02169db324d30fb985d9b0d02511d7536feb09533ad2216b93dc80f88f69da700203c1a5576a85f4d678a8a3fe9c4d7e702dda389da761e4a0620bf897ff02eaedb9f3cc4f5d59c2796651fd5c5469658361a3a171be24e46e0f7c02f7c0abae93c2bd2bac19221a8d4194efda2cd0addb8170101a1e7b698945d1a3fc6507cd8f575ccf0daac16d442cbce6d2163a44c63bb01006c1d53df7ce12048d1df75bbfcd516d59de57523fb0aadb2e16dce503469c54f9ab488a9e71432acd6adad858495f2bf22b0dae13405782151e24989579c65018872cc6c4da1846e49f4f449ffc22158c99a875ba8fb0891f04057e46d854ab73566eac4b24c2cf644fe79be8b2d076f0f1279d0d529463f7ddf92d11a0dcc1d87e9a4c36b5e407c43d14ed751ab91fcc6f03830fba9a55ba4a836c49310862f8c4ae867bf700b1e92b0f250ab5416a5dd6ed94cef95894c1eba5f028ef799223ee2a93baaada9a12945c96d34b2597d48cdb9cf3911eabcde036ae2260c0777242ad82501a20681de26410bd490f871b6490c0e259da67bcb8d972dc35176be02ca99c4af4afd57c637c70542ba51fbbf5ead7e9aa86a541851b7dce4b9608239f28f182bb084ddf8ce302d18809b79d34d3af52c0b9e4e86bceeae6785a0aa43bd91441debf7ea568f3e9bffd2f2b5a2d2f7188caadcdf1839ced0f12a9ce2bed9a01c97ad11f33210319eb017986758539ca2fc3d38bdaef2a4dd9935d76f54263797526199e0c501ece302dab5695b5d301232e21ca93dcf89ba7e1c41a7cda00444f73c1bed050b625bff2b654fb034a34c3b6d5d256525fb454946af3a57c638c0027018e6315025820038edba7717425554d5ff81e0043b46183e7b038dd1eb313b21eda7a5252bb79429c994059f059d05ee5e394b81f4cc10135bcc2a20d4aa71271a20a2ec6608bb97d486ee7a9ec7043669502947021c90b6f941a9a862680b2a5874edaeddf56e2783c014d60e4f2ba8e5ee39a094b67156adf7deeac37ce1fe055ea0555eb8642dbb7bbb7beb774c2a125c455114a94cd7d18a5db5d714b483cca69523cf0aacc5dfb48bca62a8e0af3315efeb2e092448ad5d9ced56ad2d91286a51c1f70bc1fadf0a750897bbffc617f03b832f1a4d99546e0b780992408278b5ffffae73898e6bd0753b58201acdceaccc0b2baba1019b56666532dbdae1a9a87b6f50d7dda08abaf7de7befbdd7ca605405a48427b7765a16c8caecec0b192d4836a38561655666adec666545a85dcb99afb5de5b513ea8c9bf070d9bd42624c80b43485e641b80406d340c0bcc66f76d776f773e6156e1f1dea3b68e729eb1f3b4f606c824a740d060e7fd075af718306e10d9f9bcae71e05a1c5964c8791a6515a65081cd537737c75dee9ea7fdb6f0561744d8e2e91482ff5fad484618974aa99b4762044dac60e0c143841c56de17c1e1c40a061956ea8b14b5bed9a7f7e2432877a4675337d865094c44c84c0f342f6ca5c0d6860aec5d3d35f8c4bdb5d69807ab28cb713d7a54c62b0ce655987f8d79f53eecb17aad9abcc2621eae308fd523c4605d9f1c51aa4a64b7b54ec971026c654062b10a83da825a04357985d51912958858ad8adbbc06a456f3d8d75a61b00b1b65e1f2c1c3353ccf74b3bf8e5a6b3c146cfaff9700bbac81e8d7cb5adb75321910557916405e92496ffa0ed9df741cb23b0d253030174110f5132d4549c305365bf64205a92f2c4f3328654a57b1e2573e1650460b92cdac8b448e5a22d2469a98344b3132e05a7ab78c346b7da17cf15e006ad92c0b4f56a50717b55b1450a0b47414246cd0b220276870f381bd5af62acbb23cd1e0c86432dc2c5ce4217610815b07761791f84c51c1114e80a812c4598424313c3102e80836228810c2153934010377ccad7f14f409b69f2a551e37a99bb2d6e2ee7a9e77452b62214607d8a44396085575ef10466aa81bfad1337428f5e376dd5dd7eeeab5f751bace5a8bc4b62a0abb632ae3b42ca6e40f43813155b9e7799885a2aa1615d71bb62dab43dbecb87525a66d926fcb0fee5c5b16fcbcafc901db90ac372a83001998b6655b15245be4477ed9c42f3ebaef6fd23487f839c44be7440cf8720da308d9ec406e32b43cd9dfe5013ac06e2553db2a4013b721dbb2d60ea1aa3ea98c116ad337500ed09a3e424bff30cc26bdd22fe80ed39ec1f94ada1695b13aec58d2a453429bc4fe7898f60c8e0e3de36f2d5525b13f3608cbc4f6605bf6b4474e1e92dc6075b0d6dad2cb6eb104e1f2c1f36c16c2ebacf5bace6be5e4e47847c0b854f294a7c25577ef2aa71f405119a05df40ed434c5ce0e166021b75b776f776fd791426a0a2645f59e759dcd7a56517446bfcf058aa7f5fdb6511185133be0aa60eec4239228a77e4f2ad941e27516bca97ed52937a0366827a8c967b5c6218a255e4ef48c06bd6ad7fa23674405921fd65a4bd37222e6e19696166bedbdb7f680389b2d5fcb6d6192513ddae45f5aa2310dda8b410fb366128410b04967b4d5450c1858c400ef5bdac6592430c46e89010387d96cb1221fdc77a4d93df7d9af087c5f1012a45576131f58cff8d7387bce2c17848b9b4e90d3663bcbb2ddfd44d3626912528ac297a857020b9808c3587fbb805c40b556cea640556e53007201a54055a37c4206bb6935a8499001d36af27650812b479a9e875d2970b6a660b3376963026cd220ce1269d170b62c47840626341e253b5eee10690d0db55c2e97cb1506155155429cd7dddb751cd7dd8ef32e776f2749c1401bcef33ccfd3f3302e95cad24f3a7bc9a7939f18f320667fef82a27a54d153d5e8d523b3fa749602ad11bfbf8eb46fe8d35bcfb2b7784e96952f4f5652485ebabf12b35ddf866254e5372ad3360e069d71946b718b79f7d2af198a9ce7aa06e9b27106213372ec804d2f831485134ce061838014aa66074d090730c00985110af9cb21691ac994ca80ffe52a52a1c191a66db8f7afa12a7b42d77cefbf6a94906a7211025680f94ce906db456e616d93d333352704c35b9a5c6ed1964e24fceb05038e418643000910b44420ce447126ce70a688271a171e60d3676215d96b1d64c7165eb61ab44d0542cf781254557f36a33fe8166bc64275b5d95836968da50495715fc2d640e5ac434b5ca1c48d0a0f72309bf98cebd9ec05483ab6020e36d575b5731950e0130d8d1e78dde5ea7bb1047ed18fb8db799f0882a208822228e2920d2ad33d5ac0f931125d23bc2647e73d7d8f74ef1f2cb458c1d05df95985e1c8c377b8d77597eb6a46c1e5b8db7dbb76d752a9543ad104e534500cf3e0c1e3c6e3e63c4ca0a80c501e94c7bd97c709f95b75efbd49693d03a9548028b8928d4b304408a5fd4be9a5f7588346a6a22134448478c9719c901bd88328187cf1459d8b87df1786df17863798caf468a1af9318758e4b71dc97372857ffffffff7b908027b0f947b86b84b5ddddddb456abd5969a1503a0aaaa4577418f24f191b4c29a868ac364e1355ccd96eeaee38be2fb76e8e0cb7d9f6d1b259b63ed1585201882210886208c0a5e48842dd992b57609a6f964ad2ddd24b0216262101bc795a003363fbf15f946079a225cd4ca912ce36e9898ddc864d55a1bcac059778fe950957bebb48eb78eebb0bc465482b96cb68ee77960365b47a70059a7f27caea755b6458d1198fa0992459c78458a38f9de88e85db84324c062c992d979ae8c846469f420e9bde927e8cdaa492ccbd213d1f7468c88c81e292844f2014fc8192ec03362d8ec9a9f2dd30c93daea0f075428217041134d5439cfd537a46617beff485fb590cd2df423fbf959c966b4203f79f0c750841445e48089dbed49112b0d0411032268053540810dab181c2c1185099260e2830e371fac4822821038c18328ab2e7f932f448ab4784e96ffc028c1379badd380b39aa040c12dfb6161ea65d7752c2ab048acb53c6e64ebb676ad5dbf01345a47c3c929556f089fac141e418bf391644e35f9e3e0dc00572dbcf4e3dedbf578640a0d94ba490148109c1ceae52e75e7791e8e58853ab9511fa2619468db2aea64baad9e6aa9528a04b5c91176d0cdaafa2526b887fed1a1548fb816fe0302fff96979905013d86c2952e88debb4aaacae20a49abaf356fd2109f62ebcd534dbb716d9ba551b25b0e9b61b28aaada0282ffd4079a05e12efaf6d1b35f9b78dbaad34c306d8a642bb15d4e4ef5a64f7ebf4c84d410777135411f805e77bda3aa88a661ad92c794b696aaa6fa34476cc4b1b35f5dfbc3337f952398e540097abb5914db76580fcde857ef0fbcb8aaaab7e2afae1ab3004451d251d54d5f96b792b742bdc56e22af743fcef2b19b68833eaf0f7a477017c4c1a113df824d288931fa207df88f8dfd3d58be83fd2881323df8b4f5754f4d200f1bf7741f4e04b7d52ad0f820f7e11f1bf8f0157d3e87b710cdb43fde0171cf069ee79f9e12bf13d2ccf7eb0fbaca67eff6981e450ee17057075a749063a3790b5b67e3216936cfa151d20f1440748b4ba6d15cafe3f11e8f1f9a9286fb5bc490eb0e9411e54835c6eb3ef364779b54c3327a30d7185db4e1aec4836eb491b22289b15496d551ece36cd7fbe2860904df1e34136bd49eed74bedfe56f2a52315c07df7f276b5ea0ee9362b7037f1f2891400d12952cc327d220550725f89d1d65131884143eeaf38df87422a8aae562e0f80826df5ab5238192c389a1938a0571f29a49aaaed4d6c8495cd97fa666d0d654b5652011c8b2df7b3d872ddc9fd54258aa143659aa454a65dacdc272f86ce0360442535268962786f697bc6852e069ef0826656e169f272d95c3704c52f043d1f31402f40cb0dec38b580d3c34b3a7389652d4597f8a2d1683412ddecb620e2154f29c70d8164f414a0fd6d857034f748c14b27d8af0c4890545fb46b470f96c0046a5c0902fd41ad8a152f6f30f41739d490fda9103e0415c28570215c88a6b06aad157b582c9608763f3c185b31f4c48e85ddee9801e3376dae0155554155b6793a1f7c6ffa125de3bde94d0c45a14fb21be14eaea8e00a26a997221c960cb9eb50158b0df6d3bdd8028b4c6d285a2b96acfd3ccb0297c16f9efee28ba1da36d5c7a7bff03e9f1afb815558eac7141f91bbb7ba8fbae7442b70b9fb0eaa57daa6fa0405f9882e17025a77a82d5645e5545685d9278249e48ccaaa319e656c1289843189a4436564e8191abc87caaa3c38e4182ce0bf71199c095691be66d4830e2038fdacac4ca23c509b49a3111e3d1e3d1561d288d52252c4cbfe3c2a93334406a385d739c21eee2d5763261da56a2a71adf1bcf4b00bc74be26a5ae5c8019ba7930d445bbb5abb5aa5984049fde488da3019fc68c9a2dc752ee0a33084453f227dabc6f39e52cf1b895c72c0b4862f3efe112647346fac3f1d8e61c32a09949b60fb3d04361b06b3e10fa491476548a4e7794360f34daf05aff9ec8b0f34ab39d1dcf032ec181e6c459158be9737baef5c3def44d37556e4a384dc7df7df77d77dd8891e55798bba0f3f31860783d947090f8082452ad84a9dea4879c9c3cb1b2f9f7ab428b2141253f60fe271f7a3a41d4df4f95d8e2400cd2fad557fd4e8149caed68ee6b5d61a902126b8fe094a251729dc6fd7755dd79d52208aa21873c4bd57acd1024e13f11a9bbf4839a879a8aa7e959a0fe6c81aca7f7eb87bafb5770a2ae3544e1db811683e84995f21732a3258961bc187e05778cd6bffff6fff6bb59193ee7a9e57034e95b8ee0e6977f7d2085b1d060ef31712f15551f445c209b04923fa91d60ddda232495c425ef5096ad352aa26efb339c13a736fdd9bc140077fe9db09cbbb7c7f59513a4e484fe3fb5315a5e3a4e571bc8e13195fe3fb712a4ac7498c9ff1ad0abfdfdb46f4a3ef97cff1fd371565e3fbc3b0ab189646baeaac4863a42b4e04c31862a5b4c610516c6d3f3dc2f42faeb8151772290ee4325e40653036503bdc11850cc46305773c41c614d8b42e235d9546ba32217bee1cde9147c663cf8c1b23ae26f05fc63a62df01b29077b451b1dc8000295e9a50029278c714ea550bc00e668877acb10162878b78471a181b25f18e25bcaaacce700499c0bae3010cf0825a824d7bdac1a6bd21de71e6a760d38b110b008343a8060f6462606a0891b08317efa823b3b8f818208643bc230192c0a62d07905d3e0cc3b1cb378b3c83e58c91826118865d078e9dc3d2f455942f55110298c5306112ef1880224820610532e21d73e43b0220fbd0adda6a509d5559e562862ce1076c7a630c0c8a086c7a0610eff839868b02c4c4c8a1026cda3bc26416ece34036403a4496b1ca882ca387352c38f28d9156173183e00d9290973c66804d7bc7172525b86496b1677c3cf6fc93c69e986f197b605ec6f8314235acbc0d29f18e364a2716d4c8a39165ecf918181b2375f0658ce0c718a9837f63a46e7a19a9e718c1af31d6f02b29197c17ea24f834c0c701d250016146ae2c1b285a6a32328c0d1266d8f4b24abc630c96570cca942aee56bcf47120978243c84d7e23de11cb68cc12f0031ee21d492688771cc5c0f0b061d3cb278877146596b127062606260135ac10f3a4b1e7bf65ec195fc6d8437e8cb10700314fe371903fa39e00187dc84dfee4e837f71f9d36facc4dfe30a3c3dcf41a1d082a1344cff878e93f2ef320b7b9c97f268633cb0c164ea70a22cbd803f378ecb1f1a4b1a7c6b78c3d33606c8c3560d3f321b28c3d00783cf6904f1a7bc66f197bfe658c3d311f63ec81199de6350090a4cb688ca4cf703ce941356248b7c1907eab261f5a39e1e57005b11b8dfef2d2630ec57d1cc8a5b8c93fe6079bb634d2158d91ae70d0d58c9b59c69e9717d2ab26f0439478472eb3e01a336268814defa50016971709b1058877ac9965ecb1f178eca9f1a4b167c6df181de63f2e36480f6f9eb2f7a512a945413d54a2d92ca17dab03bd1bf87dde144bbda006bf0ffcbe0ff4321586e1fa7c70b95c2e57795dee1c17f33c8cff735238299c20ce5551a9942be54ab952ae942be5ba9dcfd7247563831848c1c3aa080c5e1634ac9c803e64b172e2a5522f21326eb3bed1fa16e4725195cbcddc531486f07bd7e742b931d2e8566af272b9aee77da128b2222b821f1882e0ab5bb55ded028aaa349a0c6a495421e5d6adcb43ab282f0926829ea80955e1bab980ae929d7b77b2ff8ddd9feb22f5e89217e6ba6d807a807ea0d27ac697b066a071b6de1e5aa2e0ae809abc6daeebfedc16e4cbe4d2faca50bd79596fd5755dd7755dd7755d34d7755d2e1a6088a62826a00898d6dc22156c0eab83a997306c3eb773cb8246a3c55a68349abb68937eb3a5a5041260b3cd920683c16e8c46a39568b4ee2c702d75d0a6d0acd460d5721c5769341007608427188608282bbb77b6fdb09a7c3025ad35f960937ee11da126bfa19504134c5630882f206225f26200de493a4faa6251957703a549681e0f3f64ff1d5d60d3dbc9fea7245cb4e63bc29706883f7a17441fb2e09d2223e1e8c5cf095f04247cd23b4dae66f2c14d9a9e128ec76bdc234d9959e6da75a4f9b9d65a6b252f409b524abbfb02fdb7eb064110bc00f74dbbbb3fd20c7b34c7cea15fa77744b3d7f2922757d7284845893e7c1159c485091dbc38c275aec45fd121d7171c1095f1f7744a3349b0c73a5d6716e2063de84276aee8ca3b7d87bfcd0bb0e99dde792393c9ce333c598cd0b1e3c6b382266043c02cccc2603012dc8041e99fb6711b44554217074fec80c765d3423d73b3f2051695b5127d4575ad8622c8fe3c2c25fc3ca2f6e4c6821a10cee3435134e64d5efe83f3e028f025ee431547350d0a219a15a12848c0bd381e8ec5e970ae8ae290387784dba17133f4803b87ec687fec13114ce12c2872c5c19012377b44cdc294b88bc7f258988559988559988575b0cf454b944ea7b2c4d8bb8c4b258c697f36d5f3f186d2a43fef337db95f9ffbcc3ebd8eda5a74ebd84c7ac6b9116c8ee3a27c14fce552459d4e2718601db3dc83051dee7e7ad540c2f3e8d39bba03099ce3b9bbece652f12190745d57f18b15e29ef79eac1d97cf193b799abc60972544abc9a973eeb810fe83574e49a1ddf33cc24312cf57a7b2bc3c63804b5ea9068d19b863f918cfc9e823f5bf50f42459921b4aa4d953d420cdb6a2b5e821544fa18d2da5674032af67ff406b22d26c20a8ad5960d2225cb2d6b39e95bbf7767b8dc63b48aea51fa51fa5f7da182a58465d79f78e5853aa79a16568012fc1f0a3b41c097c60fd1efc5e700004f7f7385ee67cfd9139dec5a92820359c1c20281042444845c55093bf006e62294aa9542a0919eda0b23f5099465926d665adcb5abb049780ca384f0a4a5d13570a72132ae37a5d97ab5a6beb698a30e62530b04965415015cdaa0c025ce98a08076c354ab3451867c07614656badb5a993d310716a41e1ae6eeda0367df68c73d6519d15b975d078a9c3468798fb86db799e475aca1643535cfd0354fbfca4c8a6d8dd7d8a278400777ef1210056e6de51d4c74725dbffa8f85863c8768c21e330cb58c1ef7ab9484b74ddf77ddf2773b9ce663200025aacbd09f1623461705509557927d8cb87259708558527245e7471b2893e4609a8949b6c64e8cce8f193587600e479ee2211934e3148164c1a89c410fcbcee72b69ec21cfaadb5313c74cd1578884584e33e161bb4d6aae3f4ed606b77c7aced3a6b5962a63925db99f90e1bb0bd5c07c3f67242b87b83ea2d6c6268880891a121224343448662a68043e87b6304b871cf39b1768b00656ba42501c64cb676a8aa661c17c80f3da88c8fa0b29a46d9b670d9d211842378740ed92c692c070489eb3879e9251024b756bb48ca56d96ab55aad964fc7bcc76cd683aa46dee36b80ebe32a704ca6b420c0b2153580ae744c07c8012eabe90936db25014a8584b05089cb42cf9d72b3ceda3a45029c04a814ee58d5a854230200000000431500001808080583c17040281c95cdcb7b14800d58723c78603e9ac8c3912c098210043110649c418000000821c620658aaa13bf705a6c5dad22db88c098a5623377a1a3a6f6a3318c2f22a34175d1153c104768a2d3825afce7e2bffc936ebbfe2542095e915443ee03a3e19d6ff77c28b5b458cc2c90df1032a9f68484591eaeb934a9d67411126868a67eff58e5c1bc883fa172ac5851266c26673bcd475529b02399d362d1dc4fdb3cbf87c9992a460a0171076704932df0ed1ae786483d0b517a2e4e3bd41bbd0f7f330d96898005c35a31d3400890b29d8b126f6360eca2bd3278b52c9c7022140f04714bd4f030f5383175e7a6732887f6bf1c6439e645d41489ffaa7b626db219711508568c18fed634e738aaac8de18d7d1d25731501cbb4b1ce088c47eed9532dc163153db9fe6d0de7dc62fab52645deedbe8be5ec4f4c28fa8924f2c60970ce5205f55879789bfe20034a9a81137acb5646050c4b2359dadb8fc9bfc0d75cc038ac27b3384316d4e4c4c126de80e3731db011ac5110fdd0108285ea009c5d60d2cca7ca3e9ea6d55cf788e609300c929b02c63c9c23ce75aec290c358df631d8b3ef3800f46b3802e41226889950005fd45611729a679c32ed6dc8ced67be32142f6570e8f62bf50a96793c85ed8cfcb700b9532dd45c2566f23618818d639362a722abaf7a3a6ccfa4e5741ea0bf4007346ac4bac2326e4bdf40a0539ca97386171dd0f726902884ae0e2cd121973b440e481223fc8166612bb5b34f18b6aaad806c8632758e0ce41b43479385b50b301f6949ff7c4e0cb6389f58ae3d00771e19c3f1d0670e2cddcc46e2c8d7b633a6ffa06e25bda8983a1d11cdb02c66ac82b0ff4465eebb5248c62d009f064e6039d6232b9719f3b42c5208f403a94a77324a8517453500a052d3cc9ead6515ea9f8e6ec770514a66680f08fa4074826c91e96b29067a86c1cddc68b29e637289606898c5af77eab559664ab4a07c39225013269279c79982f20a16eb3307174a74befcf272baf421f08dc5e702932f27e4cab67b4f31a8a005ac74407386da7fff141d420385ec08426440bfb95475fef253dc7538d0400e5adda5f1d5af0a590c5936a77e0bc65bb052905935b659e62420565909a511aa7295597fdb66ee7b576be92c912ef78fb9e64c8fb938c28f302223d1b4ea138cfe428c0a130a006d13fb0575c0766a8e78af23629711360a2fd6f31850f9e06ee03809b1b628133106f834ac779709caf71d86679bc79d6a50eeb7b13506e547a9d626a0380e5e2740b2ee3ae3d393ce341244b090288a378a4ac38c28360eae13975260c2146a01dcc3202649f1681b8c9825ea25b1779a8956b8ff66d97b0659ee1ff19b6cb36e48f400687ffbe2498e22507baa8c35e05c7f2ad6f01b790f1f41ddbd585bc908e13fa9d4886f1c0c7199dcdd09e0604cbbacf7368bbbce14036be99b1b8523b9e83d2f97c80b1331827b4f5f0eb765a43bbeac868fd8b6c0113e54cb80db6f2ac2e94a146cae46ab397d6a9790545be7f2e1dd76ade559804bedd5c66c471582d699768469407c9e698b3ba330e4177c521091ac1fce7e6afe27e16e319c7a7a874abf1aff65efa85b816fb8bc07eb5973fd07bc24af51dd0bac7f2062803cbdc1d23d2686a6ef5442f245f1c56be68f54cd36a52f1329af128d3c4f22caad3c8b0ffdb82057cbf7e73912d99e264de762214eb483363911b909da78a1f49844910fead4afcc9a4beae0c95a8661f4839d639f5990028528a2de2d8e9ef520321474a91a7cec327d4f834a3522d5294931c5dfa19d3841bfe64a8ea1d9156dc99ae825a09f7c2ededfc0ed47d5e430d4995fcc0b50c8a75cb26050a3af881c2dbdf17a0ece1612aa321c344c3e109abf873474bf1a43401bec9ba2059fb67d4460448b10322e4179ea3ffbb00cff3da5ec07bd2d0467e1955143eb00aeac08594582880f84f8346fdde62ad70f4a6721b7498fc030928109bf1f30cac3db6f079c2cc10cc97ee14d153a43f2f5ca582d9f5f4b40807cf0ceb7c749e17325ce9d27d12ba09074a57dfb1b57e18c58d170272502b06d207103a19f02bd987567a7090982945fa8dbe95b371b660404b658b04f586fb237056a2dfbef436733702d960f30cf980723be0bdc5533cc30a4c1ac59a4c3e903e38d57e6843940c3a02351af5041e2fe2e4773b02e8dc3a507322cb62d0a9d921d3a092dbbca4e5a1563efb6f7c49ad58c883577fe0bf7bf09cfad2ea427901550e8a5e5e46eb0143a456bbe3326e9db3f3cbd46f43b86067f0004f589303aef00c864ec88815f789dd0ce8b3149f4e377e3d67818b0086bc4c8035522bd922f23a7d3381ef77429b8a253f67e6524af18786879ad97e95170a35a6bca043302b2f384e0bd4266d56b2592811fa3737b2c7e2329349a226f0785ac3a547de921b3df34d555d259a4f9c40b6b9870dd3f42a029e8b18c81bf6ac6afbba87fdf98c85118431cf034eb3222bc4999b821210ee2bc25290a775b63e0af57f3f28f3989592a03bf3f6f8db9385ca8c849db5a8fc19581872d6a1fa963a62a0a9b7c492091179e376a61fe2cead2e7062f09e5feaaa0802c14069ffe3a2d9654f8ea05f61e1d6cb3eada57603fa250d176ec85999a4b334205a8e03a160aec912ad97ad6c37aae8953de6199bc8b7d13cb60df1f187bc5c45be698f1d1879f85d6be3c1e9e986f0ccbdd9e66fd10b94ccdb1ea1502515fbc1948a5e99b26a48b8d268341222675a69881e8c59d9c065036dea22c0c40d278e29a98cac65a2ca26533cca92f8575b025d52be5dfc7980c5c495306c6e7303a27483cd1ef924226c5e10d6217c035ca510eaa7a62599e0c630caa2f897880fda3147acd938b70590422039671f0572ed8d122eea3a45ee46ad735e3fa40ea11522adad96ed89981bda036d239fd80a927ed5177def3c2e2913e03057265966739d347fc2517341ebc898969d304e6dd8ccbb4bb72677edc81f0c7f4059156f85c9d1b25a00b367dab894a5a92bad70b8ad9ba2829fd772b8703fc5d8d0b07b14da09a0140815322fd4ad7b315bb5a18c25a142423eebd4e9155e1109185649c7b7cf11139e7d6bc478f0db38a6a2d237d9294d5307616fb04dd251af48e8a2c940e9907bd032b35ba0414d87785ef4d09bf85a92bfd3969cb23e6a62614a73ac2dfe0db260fe63637f90fc2bef5d18a4e3e0023b5689dca9150ea81d19538127de33f5756a913a9e74046f49b2265eb7dc74ac6738bdb525e8c6eabc806a96b8504bf71d6b674c84330837652ef3f52616ba75e114c1065342aac8fcb8952fa5f779e9aad969bce933ab13c60bc321eb51fcc97066d2d6411bf1b65135724055f7a1611d356562f0ee1bf0fd093d2a943cd031d1d1123dad560324fde4a4a1305ef45de4436ed2997f1b0169c033fc3e9302df86e8b1ee1287ad25091d284a5bebe60f73014230fc19714dcc43ac215e447f883731411cf6b249c6328e1520516c91007b40b4cd7ddea03152ebdc55b29e6c22523ab53118ba736f00009637a78a502147ce1ac669069a97a74718adbdc6819c0404087217ec4bd4ca723a779724d6ae8f08aad16f83ac9572bc817ad5056ed105ef4d02fff413ecfe50c93d900b981a697f1a4ec78347bcf4e4e7a35efbfc422e8b3637952e919150cb4449ee1eee36952c5dc079bb148ff648a3a28f98ce137d5347a36c6a864a256c47bbc871adefb7055a497ce7aa4dc5ce685a093248a5ea1cadd9f7cb48dfcd40e687385081594793df39ef8538ca7978cb95848bc565bcc8003b5b5d3255a5da8c23a09f39f24d458358d1719c5c90fa30e17023688bc686112fa786564ce2ea86987917a377640883a6650821666d59407b3e2d8517a84023b82312801e40a55b14c317e2031ac5946a56de70849cc232401c76399c8b61d1465f091e518847163dd028bb091a1edf0c65b4f2f6bf54b58843fd22507c4b748b4268bd977fbd7eb3d7777eaf2c89a5fdf6574450178c740220f217fe8b4130214342a21ccfb63df3800254680115fa62a3e7c2b5a987723cd6917e7aaef8e9a5ae5a84bdf59fa5da285ca583c9dfc97603d1d240eeb9c6ff62acc51d7848b5dbdf2d215dfa7aaa32d24479557165b5e3983052dd66d10d14f05d7aa4040ac1aed8ea4b3893d0455872e9b8559cf5fcfa0425a22d651668bf7bfadc5744540b53b920edbeeb8f715856ddc7648ec3c8c8d5bbe97242b54fbcdc7b433dea3024088a0c9ab3589dfe14104f49c31adc2453e3fea170451b1685ae8ec4d6b930616f79e760884d1a1d45ea0254f2cd5dd97938349200210342eb4ec6f1e2bf3b1db83014d7546d15546d84bdb441ac39ca7fb30b7e8ecd6e4a3297d8a9ec14dfaaa71e4f36d3bb16337598d493e7b06d9c97f884d4c89fac91b98bbbec873a2a188353627538d889022036ee63ed84e2637f93b60c587b8cf1c0c84f466e23e537e67b943889fa4656db3cbb1820ceca6c564321403d106fdbc9d3c36bbd8c7105726b18d4ccff379f0e33800718fb88f86d6208742ab4711eb424f57f420b293dbb8577b44f3312e1fe18f003875f19458632907e611e892f62d47593f3607646412ef6695311b370717d9f927a5f538588b4158d441b11b89b97d7b60e972a88fa50562d1c6344836b2c39a2c7ab13af38d8e099f324e4dd35f2e3c7e88cda082d826e2522f50542560a84d95de0b0979939d3da47233b60fc268fabb564543e8b7e24c35fa5930bc3a9750fe650e5c3da6999f2f3bbc42a56983c5d7b1c9565c37c41f430644facc9c13f0c669b2d0f67324a1479ae2e995c2dafe3054add67084283a7e6733c5a876907ee666f62b3b32dc08a06875d793c0b0804f4279d3b7709a3a4c3d583e62001195c95968b076ab0f8e4fd7a1745c7077fab38a0a6751ca2eef2c38d3c19fc8296ae8f4342ccb8e5b0b8e5d3c633814e3aef0bac145414f0dc168432201aa1609de54c0b59392e2f6e78aa00bb669d27df3f6a75cba787152b33a4236cf9861076d8ad855587f9a0c5fe432f93fe8247d64b87d3bcb580cae65acdd632810685ac2de28be8a8aadd674b13106f4ef17b7db03729a2a5c856986b5486827d4080c20f4c6e75d32a0a4ac95236a76ea281c8b779595a6658139c96516184ae02bd609fb20353a30300222fa4a21032013f4ab221ca5f0619330d0554a5937828f8e1777f1504187f69630c836c4c52bf62ef4d909d05fed669ca32266b7ee9ef30a2427005514b151d47c24aef4ed72b7234580cff4390f6a5770e8ab67b3a431ea53672b1eb5fa66fcf0b4d4d364a19e21d85035297fbd6a348c550715b53a78764476826e281614d53b30cbe80fc89578f6c94abd4fc5dcfdacdc0d70da1d06f70828467b3f38397f0bec71ed8f5abd0ddcd8bfe59ab895911f925a4852cbea2bbaaa2fe5ae5667dc0a03595e99918f51419fea338b99788a9472f0664724eb0709c1f425ed4b7b8acd77b02194f7afb41cc8440962dc2121851546e92292eeaa9605f8ec839c41aa3c8499a6cfc9ff103e7b48bbce50fe9f83214e6b3282a8d5dd213aee007e0008e33ceac2f9a461fdb4e46605e483b88464c8bed6b4e737f58966df42d5f29defc3764d0bdbc169ee8070c6b9b64f42d324589388e82e662d2cd0b302f20d1a4e5e8a11b7f1cd6267eb224a4d155ace38315a196516aa7f9550a5e5faa944ea81f44daa696c131006b7be4cf5e9b020c3f55e10b0ebfa12c70243f525c0d92c7aed956e8f33f1b314d2ad78eaf87e7d6499eb3839869abcb6739a6139aa0cb13abec3ee3f8d37752f673f581217c935e1979753f794045cbc4185267ecd642469b50d716239e83603f844624c77814514612df59e0f5938fb788bae19a122876a376cbe0555a2c9ceb3a236a32b6a1700e7aec2dce9399880db3a50d4484576283265393a518246513e0bea953a22c6de275be50ea1fc6159fe69184b7ed4136b840b6ed202cd3d8b6a62b246f1ae7d646f9aa5a16882965749e56368fc9edd839c4fe829cae16c3ab8754d9f13a413bb132d5178a34f745a3908d6ad243455327b78b13e56d86c34118cfa83fcc7b0894e341802b0e20a2562e9ff323ea46b0aa10ce41f7bc71b074bd3a36385440820c373192663fde549ec3d0e150be1b984bfbcc514d3826e7c526ddd60b1c4908e892d14d4885d7422b4794e92186f3b34beeadb47afbb28282a69d82440620ee1ad76389a9f762c960b34e74133fe6bfe8c6ef57545e202f3ff8bc13bea1dbd2e848780ea603537bebbbcfe1569169c6c15ca364104371b309c3ae166d71c28ac616014429a302118e2f75680e5ea28225a93c61205e0aa25ba4ec6eda0c304e259bbfb272fcb9f10be6563462ad47c97addf0795eb4099db049e5273577e3a5618a1424eff6447bc0d736638d3e2563413572312271b1fcb412ec090efc0c6a8cfe809fcd0c0220cc9e3687b1f895af5900431e7d6514129f26b31e2e14b1f278aeb315f216a57f74ddef4ef7db17b128f6706b7545765d8b71a3ff25474eb29a10d20478d8300cd0835186c96a73b63480a527163bc39d3df33e3aca1b5946712b007000bedb4663dc7e2df183ccb80e5ee1f687af76c55a5d01290c26b29a7002eec1f615fd73f76079d8eb4fe61adfd09a6be9d54b4e930a4839e5b051348aaedde5ac14493e59f5cf30f0d32b3f5aad0df3ae07cc747786be58ccd7bb95e258f39001c3a8a7e6dc5ac5fc82af9c7c3d2ada7a44479bc364225d6b0077343481552973a5edf57c286c13f945e5850e60e8e0ecbce4d039be5af8f630f7d367a6073f7f3d97a824d17cd67731ed80cdef60721f2cfe4d246a3fd34817e73d07536a7d111f326c37339692fe5e520e05cc0c6edc40b0659dcf8341347c4d9dbd54019c63283a29cb8af3ec30e63203546503e90ce9dde7157537b816192990c5c00d33ef7c6a7bd517c77f6ad02560e399654e4cf55a7c188778e2cc5697fc2b5c575f322d5211aee0135ada63647a6b5c7b8af870da080db40cba4212d194a18a6aed3170d3c2a21f0b9db2e14f5cd6aabc1726efb60a3c6327c5a77dac640d9e895cf1940c499313e662f2a43e6a4ff152fd7a32de4775b963d4160e0da99cffd34d1b27028cf367c94706f0a91be8327ddf26c635367dcccc5f51d60cdf22a1fc9f43d602a011730145a809c2b22f7d01589c5d1dd670aa10e4526d5fa38ec5114511a6de7145401c8282a00dfb8c2041743e16da31985d26004dd19eaa3991018b0c2af7f4cf686ad3860062837dc766de27498eab805ee854faefeaa5b63d1a93efc8c952c36f9a6eb7f1e4d123394e660a442155e0bfbbfb010e99701650ec1c1e0633b3dad68497e81379e6dc09e94ff47442db238e123f1072faf82cb7c9cf70a50c9ae7e000723f96bcb39a472b86a0efd7523086c0d42492ceec02e09055b3fc44e3d8a24ec5e2144eb84a3db2a3ad4faee7436d25f04c90c322ffff01e98bfedf3e45e8c4241a442a8f88bc46367ccba8681c9d5c5deace38c2db106849b850ed09f4e84dcd46f53152718f39d59aa92b59d8f5c495520229e2fd7c887987516917b597d05410a9c1bf3196d4754290dc10ef8bf85a177164b68e35e6bd0d2056999a635aa290116d8a527e43be74b1304c677e48381e00637acc18e8b85ab8646407a6dc19e0b6bf6164ba5ebf82750c692a499d2e96bdb87684dbd282e19da62dd78c90b9ce42c5f163031ab29e0741b360caf538141083b5c05df37bef170ce5a2de75e4223048983c2bd052ccdd4c8f9679036768acd31d29fdd605f5b206b76b693d29ae1cfaac06d6dd2f0d44d701eaf172c337c2354e9e6b0360ea6d37467c9994bac92ea98a389edb00331c1580e80e62e7726836a9e1f83551b17f41c557d90317b03c41d8f03c413e9007195d90162208059faba2f7b977285250ed0aa5c27375a19e1da187f418c19a2751a75a7e0604f134247c1c4661aef6794fa2996e4a6fb94d8c53fc82be467462525af326784ef90faa2ce1615de27c7e3f03e4e0557749333ba788bef65272ae887a7e5c6e8846a2b5901128d09432ba2c3caa533e573e4243ec579f46ce4f5ad31e26f317883110651596c62ed61510be3513edba732bed07e868e15c0e67903762c1fb166996fd85c81c0ceca59aa6456e236ed25d497fed121ecb041d19f8d3b4283b4142a14be3435b18884b190cd09828de3eff88a833eca34cc1cf6c09ac1dae1b5a0106c7f48b0659e682678d7ebf55c58971b0b3332401932fe3f2b407ca67b6f574b29f65f6bd1f8ca41e7bc7fc697ee3756784c79d5fca94a095b8b8c5e54b3a3564ec11db58946f47685c70f000b063bd4269db2b1169ca547a3a7d69283fba83c9538172b73212c4cc421ffdfb09026b402ed5145cd0eda4d3085df0901ab67391672fb2da8b48c32a4ea815fd36952c0ebada2fa5ef6e3496f44cf4949f6da162ec22d944f6dc0013aeaaebe4c383b29c7bbbdab5558e69fb57e44f115e1b944fc109bf3813f391dffd02b3f4e5becde14d5406a0dcbab16f90602924161af444ccaccdae966f28b6668a6336ea85f816d1cdab1d0b5503ea8d48e5a62b3d9fe4fdee87bf773f8e52e5b54fe16c14faf0520719c4a963ac198575077ede27068216e67a1ac8051dd105b11f2dd90778f7acd29b2a2835713dbbe560cb41fe1d58f08af4bcca961310510ce5cd4da59bc88c3f857bb2dd1118df44f548b74aa840674b39194637673ffcf695a25ee0c55121e527127fbf9ad7f6e2419045e8fde1c9a1482903ddb1a305d6110073334f1b1a8af7a5dbf7078e84c02091eb2e9d5901c9ce623cc4de9b6b89ad9376bc3e7ac47ba00dbc7221b30c26af594859dfa588461e190f564f798199b460bdcf2cdc4bc18b5a4b3d165dcef88b4962c64a213895c2888c493b1e0115bec5e6ae03c84e4dfc344ecdd73ad7495eb6a2b8cce05145ecb1042e73c10fcb69bfa0a215c87e0a3086de234164f2410452ceae6db4e51c7aa97b65280139bb2e6a87a9d19e9003a49b20374188ef4e512c5b9b5ddc82c15c9949c25a0531a658163bf1abb3b7f402df716cc8e516b9db0513c85d8838f89fdd627850d349831f1a2c52899dc40e4af192ea69a32dcc4604e33864ae8159afc838327c43c5d4e2c1e2c52ebe2d421301756e3403b838c1545a1992a775b7c69741199522e579116f1dec501a9219bbff8b339543e4d0de4cca1ce4c954c821a7a59c3d0bc79f4673850b9629888436b9f9d0501217f0ddbd4ad2a777919e4ccece7bce59f5e29fae61a162b8fd79e609a68f50cdc598a3bd8c3fceecf706ea3f8f5b930d1c11ada999fa0701f98e26f93621c4230d3858b9b640a462858bd06c05e22c5cdcb9f935ae59893abcb8a54f80a022e877d866c5bb39575d67ff5a8592282c530a9258b50f82c16e1b91034038d386cb3f0b0d2bcc8f458d4a236892860f53f16c566da3b936bc2ae3aa7b74066338f8083e34b2842688b7288ec66de90f3003fff081826e5bc2b7853be7efc7a31ce94cdaf94d3c45a40ca88e1a516e4524fef5224052b3226e494c2c31e2999e601fb37f480527628733f52eaef05ea717ce18e988937693c5be5390cf7e0e2263ffe14c28d7dfa5c4df206366a72c8893e615d451a7a9dbb03cca3c1e1d636dbb163d5b12aa0e3a6050a0aa513a59dd753f9a3cd641f50b2c546c5fa2fd3ad7a596cf6e86f20e00678c8ed5e38ed30e370c5a5b3424e6402dbc6bf27ee28ba69a90d101a5a2a83c8e3ffa043bdf6caf5040df82b1c8adcc58b7693e6330e858cfeb67a580825bdd71a39d1fb3f8a48b1a6702b31ca5febae7dd43632394ae00c3735fc6ee4ba161b164ad6126172c46742f9bbb773801e566440af01226a498ad047d85cd07923b0fbf21615f69ce4b4ca1a2300c26e711140097ec1782bf40ce4d5c04743f5f746c01b43d6792dc06200fca5d641a81dfca96f41085f80102b6b5986bfb9b3919171c52b53351601e6429f371be69497fee19df083f4095654d899de0273ccdcb88de1fc63b4b7815c08a552b41219fb5bb2db161348429ffe5cc80b138f6fe46118a7e8a9f978e75d347e4f2717791e4e8836b7bc0e2be1af36f9e398834d0b00fa594be5d5076d568ab04d67224e5ed0fed372d8a6e651ec4250744a39ba7213e5f6153ab7daf6e207bbcb0b0ee199f0f50900a9805022595685642f5ab339998838ac7f81cee51efa74a64485d813221addecd3eba7a3df7846a3c1837748f16109d91715bf45ca38eff5bec26f4f6c5a3d0091257cb85b2e7fe0a19933d6a02b68677782f76063908d803720373b9c61f639a7b36012a8c788b6ed1483b0a0458e0043556eae03aaa6bd2124b8eb0319c26e04d857aab0bb86a20e8703cc44be071eea5c2b77e0a02a2b45843c4a48f34e402846153accb657d56608b723837cdc831fb3b63265b8eabc75d52b1e448679215fbfff7e26e566b410ca25b6a5b15b4f28815d38d72365deeae5a9b0e1d0680e1cc2a32b2b5fcaca0d60310c570b157538c00a54f38718654dd655b52f32afdc6322e644b88720364d4c51447bf63a5653c66027cb6810f9994c14485bdf04ed6918789db8360d2672c28fb01f2d8242cf19aeefeebef191a8bdd091fd984df01604590b98118ef1013518a4e761ae379898ba454fe17267012201feef9e0b0a251207ed7c3f1478a39ac4a0c84a719ef6e275630701458d32de7aa001117bfdcb7bdc14e8248ef7a8a6d933e8d6f5941b0d2e8a14743bf153750097cdf9b90f411e3138c27f15ccf6f83d31a528e838afb256be247b6603463b81007dd85866172e48886dac0e484173021b498073238acb0b542795dc65f74671012bafc01ac26b6d7a3e9a2d8b40f7ec36b3dd78e8d51afa6ba38b405afc4efd6d2c9618bf33d4ddd85b84fe3d7368bdc7dd73853a20b3be01af3f32cef9b804bfd1a4315e4831cb44c39e9d4aff32ce659167bbc2d20630ff2c70d2990508b84911f94c61df69f6ac0c11b5ed02d149c20fe9227a79ade4b44d57199c5c4c5b539dfd7d3518ba5bf4854e55f30b639e1b6a9adc5475984eaf7e7d53e038ec82c689f04aff91085c55938c50c8ba0ad1893df7d07a1a3e7f08d1f214a6d221fd4955d53fb849087373493882536fc3851c14c0e101136d5c8cce421f6e60df6074c7c11074c3913645337f65a1d7d1c917cf815520f0475b23add58dc31186bd5824ea98e5ac81da492a1391b40e4d04f8e03f159c969fd314c5fc29ada2f37281368dc3ddc6f4ffe8dd57c0540c5962e4058a9f0abaacc07e70e9150abff587682d35450c0de4ee590647e849c600164dc3be3a0591a4ead703c431ec1cd9f9e08ea5c60aa9109f6d08288b6376580ee0d83aacdd98b63c7bcfdcf431ef77cec3c96f8461ccc31abb697645cc3ef0fa7d43a464828a2d46cfd251695be17ea2c41ed63f350b446e4aa34fa11efad0e893690919d5d2bca8034aa0d4826e0b5204d4853ca4062af576c386d4d5981557a95dd6516d8ab718bfa9e96415810531dd8c58b03658032848d172712274e25477e2ab31d0f0e5011b26b082e7e94d002c61dddc214a26a89e3a700c8e25b2a04b5d990ca7a0864df46f536a2d9c94b0b62e2af3eebb776147456eb1b5ff0b623bb0c4d120d823a2847e5810a474d43ac9aa4ded13f8e4e40012eb9c0dab2843ab8ab0060bd66f7c2b3d0fbcd18f5f5c6863b5bc923fc1b8c198278d335c395713848efa23af37edcf6e0743cacbd17f95fb1f9b58a4f524392f64d2ca44d6ee9a2e2806ff3d3f8f14933f853c82aeadb3c7aed4fadb5ea7ccc0b44daee0b262c4ad1153495d8e847152f48818e04c73b06d60feb604d7e3f106e313904594714570ccdf0b682a9aa030a5215d70c1a6779e0854aefa6fd6e7e099f42ee2d27ab04fa8af92c9e480c5950a48060decc2a548b66b03fcbdbfe1e389eca34cafc063a7af0f621fee86db2cdbae0c752553fba6fa716b2b737f92a0360308d29f31d26cf78f19963069fd8cd354aca84e0c3b90df89968b0fe475001c211fa194bd52f3ade60a656276fcfafbab910ce5968c951854c78da1549d24ed265d3fb413c46ee397b2bcf345fb192b82d77a1b9fde4513fe6971cc0d926d6e7093eaa03f789dbefafa6fecff746158fa3455beeb033d7cb3cdb394afe7a5a9e97892c3038dc7cd1ee322868e0efa8253c1eb393ec78b2d2fa3ff26501053972aa1867015413a2b8227a16a4890c90cc8d0232dc8f8089b228c8a9210ce52608d6f471e9a8c0cce73219a014e4d85a592e8d2a090beda6bf692733deaa5fa6ff07ad4bd5cf1675388cd4131b2242d9b410db5d1f48dc3572bcb09fa9bff5267fd851128a82bacdeeeeabf398587bf719f1984b46d8c3d499526ce4e2c7bc39ed6736681bd02981c5c1c301c8ccad3f6994925c147850c7a8c8cb3cd42faf32616441af70132f3e563a4d110f6e3b65e6bbdccd18eaed3e722a06a7cabfbe9c82e955d7b7a24f0a49221357df85b910fea2f0a7decfd6666025c0b946bca39afb950a94be5b298e6a3a8f384c641393fd0ea097d441ce48e2c06e9d01b69d6c21eb2febf2da391c097c187f5da19f70fbe89d30788f6458c7c50ff7278b892a88af383eec6d5d153a49b480acbc88040c9888ec9d71a7d523b8f206ba309caef62e6c5e3bc22765c33de380eea6844c8e7dd4b20592c68160bd5c4c32e8bc0c39136624d252b162dcc0c5ac414acfcefdb3f8774d1a224f687a57bf447f441f05244af12178d44fd425a908b76160ff818968e134f68ecccb8704a03aba54d3ff4855ebf0572fc857adbdc6c61be30d56e2540876d6d64400cc7be75190dd2bc4988c2cd36a666a2669c10b46bc4f5af360ab3f41ce42fe146ecc758252729b0c1b1ceb831f69db59eaba8648e2080c5511610542dbbd77994772c92958ad6a5fa800a882d6f20ee949c5825120a72ea4f23761478e797c96538668fa4dce7afd42fc08cb6509364a9e2fe5e4f5713deee5de37aeba9068f2bf09aa12a0c760a401c3f6076c43b3f5ab0b8a3ed0f1d340cd311ea98b88544949097969e170310b3212d69eaf382f56ce9e63b50821acfadcdfc8326bfc0d9b1118a6b7c3381526ec92306075c4bb438d5a61e9914e84816c12548ff65e373d66f5c300f185b9703442847fcf6983e54431c0c765eff5477592e18fbb08824d057167a9b9c23774e6cf6c4957af3e10ee0eb4ceedb54e304f02e9422652b626b7917802fe1f90724777c435b222429b6a87ec37b6d02b031c31702a058b100e8a3c0f2c95c6ea662185d086795e794b860a11f4819e9b30410369263e3d580ac981b6d1fd7f6a4283214020241cef76cd504ba9d05cfd0d4d2a20eada968cf6ca0cb6254dd4666c0fec0300cf0288ad8c9d24a35ba0791957fee94543cc4e410b2f6cb0917f11821e40648c86e5fff76bd07c41d6d5864aa2b0888eb378864c67223c30f7152f39635cf5ea0e564ff94d954c67adf18fe0c4f36fa45c84e61726e59612f6dac8b2b28a74d0b4956d263355f0df8c3b29902bd703dd91060b77510816bd64503577ae2036d5657d9c25a568a5e64aef83bad8200cd426de6e4e9c29252f18b02de8333d1acc522d06b3ae3462afb9163664c8523542f098531ec0d761438c141e00ba5abebcfdbb72175cbb513885099c524469afc67d83a638141d254c997f800f50dac10774ad816a84b53f0dbc8b5480a06b02148f0efc09d43dfb445bef7a3a8de6199609429820be5704896916c78811411d13feb11865b1e31d0437f3ea78b957c4a23e05ed055c532a501bd470d862bf6bd6141a2357405d31a454e16c91471102ded32197297cfc596ae564183d50cc5a2c24f5008ac33cb79909d055287c6c0641fb959d127cc03a6547624cbd9e913faf9b9e377145077014b151d492a3628509285d434c92e9489313264c74822dd25a83ab9a1b26d89641f8abb7def2d3d82c564cae0ed9f6be59cb7916c3ad68b7055f9aa3087c9922b47d9e4f042c31a2af0ae02d80e65fc975637ce44aee2754377364cd4a635ae4582c8521b8cd9c10a15aa029417c601a6c93cbe2eec6e2fd4e25cb6a635aca3bc81b33bd2021130e75e98aa2c67ee2c4d7bac72df93a3081d9384273b4076e18ca79b57ab6b17687d8755090de434e802b70d34d500bece1b3f62bdd9f5949b3d3254393d6aff7e0bbe9591845c84e7992401c8efa4ba0d9678de73f5147ea045824f83a63c042638b3b1110d436ceeee59e27e18118badaeecef96ffeb54deef939436407013861922db8701c1efeba06011a26e4d91df2ea4697b60c356b05d48d6907c2abc2a300cf810a21e3a23ed908c98a27322934826142179411e1d1181f0daa852be0153c5c8d9da7c31adcbe17841c58602278ff04ad44725e2f4969adca9fdb987ead7dcbae7eb88e1674b8fc742a4d480c9ecd321654c493d6d502ea097a831cb1b99599cff572968302363174741d7a4be302664d7232808a32befa828959a620a949a997d89a92a4dc999214c823a24ebb29e31d1a98548a4fc6d97f7b93219dff2e2530db4961da26348165bd69068f1501a6d499755fa09f09ed9b3a2daa585a230aa9b5eb265a65facd0e54866120507189120a9b825614627944e9e4aded1dc52e239706c4d35b0def6e07a5bc65916a3e8357d93eca13b3d74b4086ee2e4c9fe7eb071cee5f102d891521a052e863fdf3edd3f7163fc6a311827e782b0fc74f8b3df6240662d14eed39d75c01e01a3ae2231ad5683888197088a24db85be9bbd2edb758b886503c0a4406bf7d121c0cf463d84683f15b73e42f076de7bc727ddd709a22e81deec5e0df17b0b18c6a8834183eed5f66a21e73ed28c449751da97cee4e3b7508d3d5e7d2a3dc381ed8108021fba1ffcc3f80e846148bad2088fef82b5112eeccd5e25f6e6625024354ae0eed99d0994c6fe2f9c7fc345996ec3b27ec8a02e226a7d9c5067456e191907fa2768a4620071f2e853e0d05741c32e44ef8e62ddcc7b9e0aa0f3da920e28b551d600fccabac681179ef138c57648173bfe4bf897d120f957df91ca8c996be51f3ee3f05fee256168af5784a9b3c5af3b92a398243d5559aeb118a835aa81d8bce8b6a712d6a3e45b0d82ef3ee5ab9c7e7b6190fd9e3081a8254a0f5642cba578fbdc9e4502cd0c4fde74a8836af0dd72e45f920a1b4733ef6d4f6a5d4c265d4f4f2a6c95e29b46a4bd8cb213d23e9f149b248c229a68a8652c7514b9d7e7590ec22d4bcecf0463981b8460f7015fbe21a8adb461dac7c9f24ac163c1a89912436b8f7feac75156b74d8548eba97c07ef5c6bffda59059a29f5ef11569eab05ec7c9f836f0b24250973c936328d5aee0342c2e214f9ef61379ec3bd79c434b8fc58f20596e994a2c261a4f1a35822ea07847fe1f3210cf508b29124319a715b3161821b4b6ecf1f990620ad8f4294ac39de00b6dc75358dc2aed25e700b6d867b13421620f1a84b682e47f1617b3bbd4203047258bfc66c0384fd9027a576beca8b3d1c20e43bcb9ded4f72cfcc1d4f83d14874c092a01b50064804d199a9e6dd6a80b8d8dfea085f2a47c4541a0c60e801dccfa4815876b57da459c29906931f49e506b415f71e9d445ebb4ed902196bd17c37bb39efe60678937c7be7e506805210edeff7bbad3485cc33dc47d987d8754a75455c71d49965eaba9bf6ecd64d802be649953b2c18da6f984a7689c6a64d34443575b06cbd50376eaf5cbe4337ffe000d5468f05a43481f0ef0ee2de08f08e22d0efac5ecdba667f2104173f391bc24d2bf7b180b088502c2976b6be88bdd6641771ab52655563f81f203f893d7e8b96db64f7b55af26716c28f0e71cf0cb8ce6c14cf4c663770bf2c17523d0769ad42844f93afae80c0f82759be337709dbca8eebf1fc7b5f2b142ddd92d51c01f34d4a837ab63b84d23f00a78a26d9f018c4a712ac995d13aae35e559fbfbc70519fcf184f037404a41422866d62b6371956421a8942d6731aebfd85155c9e9726ef9ba508a66c51b3ff4e04b4833200cef0b01a0320b0fa3b806536c447ca3256d7a9e13316590b8e1703f34dd42163205048e45c114714906df18fb41e50d5f8505eeccab1671b37389fc470946729c2ffaf7d3df0d522ad6d848d203efc460560017207afd7c063412b99db0c8411d0664e04f9a8e0009d0f11c75c15d3d1340cca654c37a67e85cf2dcb4c0fad857880a2f95845e4dcb9e07c80970b4ac0b31198ab440cbe434d6def2396f54c8c3bab1409f8b2e8c813d5ace080cbf6f3d8f6dddce7b27b3cb618d12dc0546a610851bbbe54cc8dab9f68c81d451e2d0977f53393f801d34c60c8cc902aee88edd6b6db5782d7f79d0e4a07ed3dafb12f7e6b940247f4c8118e92aa75a5f24db01967816224ef18beaa719df91945b023185f6998f280bee65a249e67e0f3fe0a3705a814f5dcb4d58ec5241bdd4863f94be225c029bc77db28f81117cc800b6dd2e453bb947d4498b99ddae886f3f0551ec1da33daea909f178a88463a98b5c0463fe4a06781832d300a03e7245eeb1ec58a8d559d0d575019397d8e06001c2c809c3f7229bc1cbf090a0cb91209f3ea63b601250b3df6928af8873b9b3634977cc89fdbf3b709b4a3522c4234a900cad40e8b16a5e3f0986453934c3552cf982519ebde911a7347a5c0e0e2febf5d701371b648cb1f050fd76929f9f78cc32115729e17ac490678585b0bf56c2d11594d7e079d24d673a1bd468cccf4566beb002e68765f1866680566479f292ab316f58cda68f46845d76f2f28696c37c43717c6cd72ce4237283d9c3046f1a303b6d3529019cea1539af49dd1b7a66f00619f20766e350acc6cda40890b3c76932df171ec221941823a0325fff950b4639f61baed4d888bcbb7aa1a96d740c260e0f2a12a56d6d40efe78f9d05d30d631594fb4eba439cdaee3edfac8c462f8557ee4fc5583b9831a58237472990ec667d5945f8e8d1292a073d3cbd79f9c5c667717764ca8250a53350214a182402de4ebe849c7efb9093370021b19434d7f48cd7e597c1ce713f3fc2b6fff0bc8fc635dbb2a41826ba83823c61b0f5a8bd1ee2f38b009d09947799ed81ad5bf1bf72863d5e4afbfa05ba6c9fa16676c7669946db4baa581e4ec6ad75e25676561e5d5fa09c943a332bd902815181524eb31afb1fb41c8be2b0bbd83e0db45092d13e757a4f9e9b9ab4e28a9ecae633acbcdc8a0cb54e621b0c859d515e8547dca2643ae52d6c0e52e7d1b50c4a373c65839342eceb475feb485c48a0736af7edcb3a3421f6c3356f0a24eb5ee12272746ced06cc6991c162fbfdbae22c2bbbe953a0628601e213b98752502415c56e4adf4195cf317220e4002e534a96751bf1c11d615654d25ed91731668027ae5ae329b557db508f39ca76adf07216d3e9eae9a840c8a03dbb0ea3bc3526f976fe18618e7e1757da2453d04481a0d74829ae7514782558d481093ece7c28610343ddbf2db6e7c28c6f956084bead09bf1fe808973f212d89135af9b51b85ac2591074d419d59ca0ea6e7b71dd6cbec9f4bf2fb86153f60a21a9ae95b2bac27ed31d99aa7cb35adec7c04452359742882b3d27bfbd7187029dd8e22f87300ec64bac9397966173087df6d5d4e40df25db02a4d18ccb9fc804f126d30922a75cc32584bdc50780fad0467690e650832b41f32f744f97dcf177d20db9cc679d3e4eb995dd276197991e63dc18470da7f0cb5dc792fafd6886c123b2cca887fde0be0363f8bb6380f95d97401ca6780aaa7ed64fddbaf743c1d859a0d8d8ff77cbb3599054b1e03cc36f491ee5b436f3ff2da03b4d8aa752a97a6ab782937e3b8950183b6369d41a16a1fb8ea1c556127cf4586697541913eec6ea171f4d868df039853d2f24de3a12fe916eb4557519f43a2c1d42512125b191914f777ad3b04144fbf37115575b9150a99648cb5fc4a24e158d824b5d834c31609d4d75286621390dce830cdcc52b4449a3bf85ebe3e49674dd8939608b67c048d83961cc0965a09534bfce70bffc1ee61532fa3b4ac66b592d96507ebaea84943c9db7252c1a0268aa90b4149feda79958584f46cef0eefcbb2dece7b43e6a46e3a81e0e1faee055e9a5338e29d52fe07f26b1061d320279ee2dbb4c64b61112b2ea41045a5874070d9e8c84e96a44226a74ced95125ecd52a240bd8fb3769259ef44774d67cb6d3687907760d61116589f2f380fb7bd30c30fd2d04a8a18a3397837d40310b124d65152ff2efd32b8333267c27386ae34e0b25cf3e05a4b191654fab2b6c4c7547b3861345f9705dc193d14d44e4cb0a258506f69d961ba066ba59092c88408dd51513a51a5b7e597f2c5823c54ad329afc12a1913fd4260f4f57ea182988f94485fc5dec8805c1dfe3ad7a2d4f44e08308444a6b274167de0a633846de458ae62b0845acaefbc0ab63b111f77828c929a69750dc373bd38bed10dcbbd2ebe3ec815631a08b7035b9cf9375c9ac01f03be132a981c54d83510a3095ca510fdad44521ac6b5537b32fb0e807701ccf50c23b03c3d2007b9b4f4a8bcb3cc35b53d6f11b6ee990f5565cd447012c2c82adaa2056240ac01f8f7c9740dbbc8aad378efa8791739673ad57fe81018baea36ebdca2b480605ee282a77756e854e2421d2038ee388f670a7e59071bf21682e6280b164ac8a018b8b4f579ca17642bd358ba48945f5c4550b8bc5449781e9c3e3188c36c1b4db92de83af4f609c5cd3da394681018e6094aa8538cf4c5ee09a6c2cd6343dfe45e01c08d188c589abe72044888e7dd8843690e58cfb0370ff1fe3e1ba0a65c442935e7cf107d97ed8ddfba438d3c2e26e7980117d37824961a8220f20d90e3ec3854c497dc7270d0d404d99758ba3443d0dddca5f6089e5bd44d4ef1ea11270f24b2d44f61558915f678bcc18fe17632313926870af867c288dcab29ac9c82a41eec7dff35d105138a332889a2a86e9dcf8cd6dc13b59b3207e9a2db4d53dd91a2f31df2b6ad0002c010b91a1d788fc01b98d164698ef31ade63814747af618a5338b463044407817e67baff326d57500e317366f8407cdd288f91e3630fb4e8909d24068c798efdf73057b8fe6ef4ceb4eaaf2d5b2fb8ec240e4730230624d41041a3a3d23a12d1beb0d2ae67ba430ac496fa19f1bc1bdf5c301f6d61033c5ff65c4ae0b3903c61c2933564bf33decc903388f3ba210a4e9b018ac5b2e14ac9a99a54370c01d7cdab026a99d2691042c4586a5fbb7fd944a408d0acdb49630f02429092ed219dd45eb1fb3602c1a2b42e667eb7d14dbfaf75609553fd38fb321cfe079a6d8a82bcdc9a87dae3e1682f37da6d4328a24a0d18ce7a547687669a6fd25c87f2cb20262bc10448120c65e4b8158616b270e97b40142f7d3ecbd699be4100ec0c2527e7f3b7b41a3a43bacd347159ad1bf2e7db56a332a8f9c11ff5ff3492ca83dc5a3b75ab2db3ce890d2c3a10a90c7604f7b54e120026110b4154bef2a9f27ee76a51c74ffea3afdff6df904e7e620db6a0f1b5ed86f96e2110fed113b3350425224aab16d2ad72d5e2478804c2644daf054a6af17a12d23117d0e7a01694df6ae309d4395f81b4e48a4dd85b7a67e8b2f8ff80555d6d98b046f45794490016d360de811cf0fccd2233f30a15a9632413b6ef80e4486d7fdc0117e25ecca97e770bececfed6f469c62f589f0c5e3da24d2223b4367c6e7c95ac95ed75dcb489a87932c02d9029ec01937b6549c358fcff0ca7547db2e77b04ad746008f33c5641e550cf11556e4b251b037208165bd18961f76dbdb79617931b3e70b3fd7046da3ce3f7b60ada3df53cc9ff649c7c2986c92feb42f608d24aa1b923bf689dd43e677a5e118115a2e48a4945f0f57e9e400601342903e3dfc589b0e507a088e4a0ef708f91f10d57267c575e1482cbce24ed74e7a4a9688024cbd2a2782dabafd81c2b57a533e530b8906eaf4a500294bcbaaacec8339475c7324d45f9a04b6b216d60e6dbb607abf6d02f778e8e97f5df47215383b572ded5d79f1863d4e143e471633cdc74c85bb06e5642b1135ea05aa6820ceca10d9983917871b47eb09420f0d29d42074cf93fcaa3b61e2220fa9cec50f4552852ec4d6a941f84cd221380b8b473e999d907db9752aa791a1f6a3121b5604417e38eec1cf34075e16f5be7c0c0928712954684230fbe444650c1965e95e95eb682f9dda269a9286488f36a86c33c97b98fa114bf8523372f26a192fdfbabda8ed6990ecf9aabeffca48e066ef3e2b5d23da5e28af995fbd98a887783ecaeea0fcd69958a2c9e30f1595e5db683d0af59a64741e429fe7de857faed78930d75223d3d023e4c5bf8c598e28266870f28678cda4924f7f351f95ff0a3628255a26e31f555ce797be484fdf5fc32a086ef18b26e598d7813e2f06abae6eee640abe612f5b678854309a5c8c92ade107af0de9de551d40e47081c9f3664f65b75f975afb97b9f60fa30071d92e1cf3863be4da5ff0474724525c17c44a0e896654d5799656e8c7a713ee405a02c71cd2bbce66920ca4f33d21bdfb43193d3f2e6831040d7c0c5dd43f31dc90cf82d97b404f111725860525a05f8c52682d7ffdff531daa3786994e3597535c605bd1a12c1529f94b74d93f219b07867d2e3af52f87db124acbff4acaefb2a0352088cf40334ec91c3eca4d7d4a95780e3d65d235d7c0fb65a3368e9252268789922c2910ae0d427061c0702148168d308d8717feaed787327478cf912eaec65ee4b4fdd853414ed22d205015c4f184dcd28b8098462e9a95830ac9a19ac717371f3f84a18afa35ee86bf82071796daa23e4c1cd33be57154cc3118ba669457cc5d9852f68349775818b80cfbc134a4281f18d27850ecdd23c4764d6ada2f1ba2d7b9020e1660e094fd64b5a84fd62c0a8516f4192952669bf48d42c3b2a6932cc4fbf1026ada7645c59c82f5c8176712c54cc2103a1f1cb80a53a3004b32fa93a959895258e2f380ef8646790040898b022917b62b752c0582d9069ab36b6540d84ff5e561b3aa7544572e92f0bf0baf07126f2aa86ef65dc7778bf8700bf85b438c40f35973d9770b7ddc3569406cbad258260cf00a8c864705a2422e209bad3110f5a1a81d6b63b1169794f82db04b5f8ab7235b8aeb2e7099384767a84f1454c4a3bfa13f837e359676e1f84ef118fb1d6ae395d0929e58d3dbe18177c4ea8a411510e33e2c9702c9cf6bda67a9dcaabbe34671152ea75bd55d8326aef89ef2babceac802f53d31fcfacb4b0ed96c8bd282aeb4b4a985ab2b103e5684d21f1e432ba144e3a4de7ce3f52bf9b86a85d8af1a3ac8106d8fd0c4426828821b6389bf9a5ed4713fb9192a986ff9e8fd07d7c49996e58d04b1f3b9ad1a9edf905ae584defcd317500fd2a97caeb7514e41ed350d0e2593a607f9cde7bf81eb6b7bef5df71bf04687785f992d47a803ac596269f609c150c976110282a752172bdd480a2540b34eb07284a09a1cd75370f023f3d51d48db58cb341479c72f9d6c5c767e84f46fbad609585abc07a1a35af8da353107f5d3939a5313e8e1ac300513da402f4ea7830d49837282d46064f8c1d3088a164aea38fedada8e2bd4f353fcc2149fa003bf64e9c6b25e249b15f80fc8364ce7f207b038383f23f21d05e7aca06b0bec2f4d7c05a7519366ffde2ff12ee8a9c8fb6140f02d5d50f8e7715e56d173aef6d9552847046aa8be699c0fa66601d7ab80b1e110019f859257834fc925f0a31f504c9e54cd1a4ebe14aaf7279511a3bfa5b2f1fc1fa150203b3652c11062aae2289c961b03cec37b70f9f501f4077929f6dc505ece0a6e4220b79c2e1edb053887a5cf0d624b73d526a79119d6842e606707d193cdf9f1304ae8906e600739e3477df7252641d2e50be0c6c74fc8391fad6234edd6322c594dd0b6dfb2094b756632f8acf469ca80658d1d54057986bc21ec92ae3579481a3fb74af34e4d0214f4b66015c1db8a3e921345f10694b12e619efc937b654dbcdac10fe1300782270a20f2d7761133269daee3c605147d32960d0e3db8d13c2ebc77c976211f7300f7f30ba0699080381ca940814af0859695521cbc3c800f74f90b79113d153a5471e9d0cf0416a1aa18234131834b4c54d1e9b44f3841d5dd2d83bc2d94987aec2e79fe6edfbdea85147066a5c8a4af17a0fc6762d70e94ffc9a3c85c39a26208e056818632a1ef6c5ad97bc3dd0e2d710b01d16db85c0be006cb87c9ff5e65b00d0b5e3d39157c5efa45b5294e6f5c15cb9bedfff54f9be3aab8ac938b72ee7ad96d6f24f3d51d0670bc61ebab47bb2014f281af6478e8da5c4ba37e384540d659d63271b43ba47ea4260d4d3d7c5a821522cad5c9711fbf278e1ce806aa1ed55c0bccc30898446053edc0fe02149a37ca78b8aa1b769d873ba36355c7a507d48ab028fc7538076832e3337bc45bd642e2e061e91f9b394a2a2cee49d266537e40f5291d50dcdb5bafeb29410e329b5a8cee08afe9e8835b0ea5d7770553e83d7b022142d89e3019e30de841bd48e2c41baeab8dbe40081e701be113f668637a2b2c0bc71588deff4107a7e5b4612f395598f8729e9b190118bd729bdcd09d2cb6be7c586f6bcb210a28d7d76dfc08480d2558d5ae2c152b2ceb986b85b9aab745a255e23998cb58ee2b58d4d4f238bffea94fbee47c1828cd76036f0332c1b6fad0c19c63258c9aef3b68a543d8028c8f590dcd96b2e985486bd06b15782280351b2a2f3dcec21d2586709a8a5a0e04add376b20d8ff3885d1e7072c03f4afff00740ad649ed54f6bde2d2d74d4682cbf23a47b10cb79591e0fd9135c91217f598ffdd42930c3b469d8b02d73d3047414abcce78f24568d911e9ac74bd4973d0fdbb33078d417df4d9a0e72d3228b0f7a8708908cc95a7b3a625a7747a994c55855185590c898f05240b82eeeeab19597de710308f9bb9b81b6eea798e002ae5ca5dda80799d2cd8d82ba63689de3f5552f30d147b4986096bf3f3e1c2e5247911bf3e5a49ec9f6b187d0ebbad33922b96e8fd7d8ca43b50a2d42022488b0f325d10c7352d55c1ec9c7624c725419260e996676fc1141fd6c943b4c972e0f824115f70a586c0896b7cb159156430ae7cce505644ceb2dead762d336f891096f5cb3386b3f4574a4c538f1a624153376cbd3532c9d36c191a2320472baa7569f96849bb8b3b507387109b50db8e9d44edc08b5a5e919b1d7153932a165021134e77f8acaba3afaaa07a2ec850a835ae549165949b3e1d3d79e246caa29f0d9b53ae08f29bd95d1eacd12d85a278ab89e67dfb631a7cdd5639ce86b01242f8ae5c9f37b6da6a0daf33c9ef8fb0a29ff7b3cdcc4ef41b9dc4c78392110a716def8edc627ba2052ddff0936afcfe0275de7d3525b7c59fd74775298f1e222d80e1a9faa64d0b6c275e8351fb5783bd618547fd54c9405c1f6c2d7d5b580ad2141c36169575609e6dfa7f57d6e2d78944abae509c8e01a9f6eb7c835809a1c07f1af1f5b2735fc98b6be9cec3d327a272b61c3f1b5d1d747bb7dab2b033d59769cd8e4f5ab8162638968575b42c46670d457791292bb0ea54a7d35eea6fbf56109277a78328494aa05de1fec101e2386b4ab58adf30e8cba3a624232d59807e7699b1305ece87ff69aac58aa35fab11d7ba66a7ed5c1b9b396b30aaa5e055946bb485723199c0edff2050d8c77168cf575812c928e620d759d1c425cc7a507a3a94720da6dff6ac7d370d3b950e37432414e90b819afa85d856f5c567a58a52886808cd618daed7aca103e46d5301249eb2c919870d1a7611b4d9a2a0437f88d1cd9408d09013c52ede1655ccca87cf1887aef90e48e3d161d5a96a63333f48b25506188f53f494d23f9c7766bb5f2dbe271764e5d848dc26001aeece1ee8b4cca7970e28ac27627b3326a0e62a047892b2e46be4919caa4e70a17f1c146a97af754658831504c5fb1146501fa4b800ed72cce3a9d640e024d8ee66a15341f2a7a95676564ce8703a73806680456a0013b56350272a360ca5c78d3c592f7c1d281bb11ef60a11a038b14d149fc5c6859fb5c83be979ba58cda33565d76bb0c5eba1284b163fbe98af84dea55dd664ba0bdb81eba6c9138aa741ddc531b261cdf6a1153d7d923343015b3c246c846a2091a780d662520883075b27c8b6f37e28127065c0eb5249151e33cca7b934588419d7bc2613b5743dc7c94361f449cd79091368e1aa87b3ddd5497022ccb6d8b09492a723d76913b79f617bb4be95268314827d536f0aada8a45e3d0e242c81da715406f4988e543e5dc1dda2d6cd281d4e6cb5071a71c3af6c1368253653c9229b6eb7688c8bfd88155bcec8655f492ead43b3da46aa86740be9661274696d3142d4fdb653783703aeb8eaba95376a0c1db76f8d02d3ebc41493f79944b7624e00e21d54f9d1bada1f05dea5111ee89a5d30f1a38e39c97ee18eeca49fb32bbd800279be0c4089d6bef33ab73e4d21805f17fb90537f404917bb27c6ed93a26781d20571c64c478fb118ae59434988969947c878bfea3320449a0b4549132fc52ecf3650ed99e00194f1617da5db2dbe2b2f9f2f2a8511b7eac225ec1b1dc970d7eb1206d52078e4b6f130aef8f8cbff893ddff8550946d52ff03e8ba05448ae20a39a16974198c841e35311282cf1ce2ac37269223504f352ab048bab46e288603647e4d644c3270e81cdc04525574e24ec8c0e560ce043444bd0f5f0e23285c806b56eb82fa93d5bc3e585ac95831d7c5d7a8b08848005b4d6b7128c81c9476ac0e1927235608f3f71bda54d48229d126f76c4ce33897958957e92af14710b0b3981b619370c1b728d1955adda1301f25ba8a0ba1ce62fa8818feb21cfe3e0499ac95b3e19905f22f8b82eeb6960f17cdb6b6b5ac2b4abbb5166dad6f08b68aac6772be3e72a56fb3cace03aea7a424981620820e6159ac80b17dd51b03ccf702fae715655e301232e21c555352049ed66e5f49c61e4521f92b4a12fe0c6d44af15f716598fd4e6630455baee30860411c4afc313c5ac028601f0aee3705065c100284322d5fb7b596b0dfc79417586aa8e719b0cfef1b3beeda59b8810912bb79452ca22065806210611f87eefffbcb7b29c3f1c719ee4d126fcd088e37df838df587100e58a0e3658f2e456c6fd57ed1414064514063f04472bfb6fc43e5aa42d4bb32b9aadc93879cb7e4b156caa8e3db65a39b329293db65a595d356a5378887acbeb02fa62bfc756b32996b5c17c6a404099629c33c6dcbde1857e5370ab231622053c9431b97c618309a49870eec018d3d24a6cef9cb30eafb3cb5281fecc7eeadfff5420d9c0eb936ae0f9da6e159263e13815a84c28cff22c47a93cac4b08285a405937d9089a93a0a74c836e9f00427032dbd79af3539e7d3768a85dd9bdcd4a781c4fd2db2716f9d19dda7a4399002db0dd28ec0a5525db1567da15ed2cdaa22798cba6b418a1818493798643f5253c79a3dc78f2d6ee0dec5643349548232e0a85e0f7b8e3ed628b90330c502cc26ba73695bfc31cc7bd006fd0c0bb11bb6caa9e280e91443aca866bbdbced64ed4e5e469c165af796816e3c91d6a7126f88aa1155ffe589b470e85591d9ecf66f8c375ef536375ef5f555aa7f19715463c6b931d2ab22e1469e5d2bf4e5fad854226d8d7072f2de663c9cde2e8b6be5d955d94f3d596b243c596d359eac3ea2a9d61befe2ebe3171c07e3ebcb387dfd140e0b635731be6a117eefafdfc3ae505f1f851abbf2bebe8d5dc9f8fa3e286057dfd7ff615733bebe0a406c10bb1ae1eb0bb1abf0eb0fb1ab90c6d7c771fd4b04b3ab3109dfb12b9772f4d5860fa4af008852fafa37eefdd448e628248c64a6ddaf3192b9765f1cc96c338d00105d8434a249a4dd54a324128111567ac9541aab1412c4ca63c3f4247ce93f9358e34b214da9468d2fd51887e44e126dd9b2a5934aa4b1ce44117712c42a73a9f1a5ff48a2f8a490a6248a4f12476f1a9146636d621269af21d69d91f4e28ffe2389a61f85342393e947a631484ce7a4265490743ee2638d9544dc45b1c2def4a3ffb8587a1ed28c4aa5e7a531888e2e2af92c41451771d15875ba49ac3934f8975ef41f17492f0a694424d28b486310981e72c143133cf49028345617ee25f16604d28bfe0b89a30f8534a2d1e843a331088e1ec2b821e8871e86c271884d5dda49629019a11f7df85f48e41f863421e71f72f04d60088e40443f6ceabe0c310529fc0345914864127d6ffafe1b296053b473d10605bee8bfff4031f45f48f38542ff89b89b42a69a50c45d24f61021f4df7f9e18be17d27c61f85e380691d1f79bc2135ca82069d2374500388018de879e08fe06b788bb09d46fd25b8f311fcce9d3e2f7e96f0c62eaf84de1092628e9d141c78f471c2e2948e1fab588bf0b69bec7e310dcbb37852718a0fbae279e6ceafe8b9006ef6d0a0276ae091e9ae0a1e346934d5dda3d3105299cfbfddd73214da77137e5378527d08cf7ade3104b10e91591f04c7eef3a497f6c629e8612b8a1c58ce786a8127b28e1b9fb4ebfdebfbdf7beffc007c30f431f12bd883f1ffd88f4a4d29746b28ea80554d2f49548fe0b047effbea9f43c24de0f459bfa446aef6ff1a6b094aec5a6b0abdfdb1703148b70514f00aaa6db04613b6dea761f2f5878aee5598e7273bbbdc81c9773adb9d6dc7539ef19006c0942ccf0fc5b95fdc78ff1d36668cfc6dfc7f5c04ef67b22e7a30a781e076053f6757767ba206650fe4f279ae52e9318a975e89b7befbd33fb868fba905c64adbd39e7ccef8f39856962139ba2ee722ed35ab9560065397fd0b199038e878bc2cd6600ead4c4409547089faed7aa064e62139bd8c4e60c316c5e15ac8a352d90bd99d8c4189b32cc6081b0e90304c751e02ad8940157c126364d194fad235841ca39d7d16fcad2acfd9544c4877306348412262280a1b59aa208ec0a932db2c05a2fc50d683a6cb104969d96dd92f3840993189c5872a455a3ffe3c01afd34a4a9d9b9e3b88eeb38aee34eb9be967b79b82814829fc7ff3fef3b10f6be1018b6421818f0beeebd722344888b08787e1ddebdefdedaee137ce6144e6a2cd475348c0cbbaa975faef2cba2a12afb4a544140bd23ea7bda816a1052e6955891db0d110bd03b5373d8ed937d6acc472c458bf9c8f95e2e73379643695e16b5d6b4a6796bcc1c7cc81901901a1fb61a51125e6877a1cedbbadb332841c50b5a2dd4da0e0d8956180a85469c0c85acd5428642d60af7d6dd361140067ea23e3e3eba3bd97b77ccae623dcfabb1f1517394e00bf6f2533568b5f0c28ad60e175db50bc64044157ed8540a3487fd09d017fbd507129c7471815901efe761804ea3932e353ae9d29f94f19e8c7992d5eb48036fe4e178e2bad71eee1d8639873b442146078cc591b25173d8f7715903b02ad39412ba48c2de3664ba02ac02e092820f6a05b502e3e2e2d20108822015fc03bdeffb40f0fb3c30fc40f0034216574c338a19441426a8bcc0c78827cba0621c83636c3581095eb9ef3aadbf87e28516ddd217fb30889942abd1308d96b375e1743ae59c636272ce119e7b31f6f1f1f1f1a1621bc94b722cc3a808067ab99565199663226c61b352a7bcac7c242b916526b3bc43940c83d917a6fc66da4c8c8b9e87b2f2694a396fce513a2ce39f89a554a3273d69cbb256daca28fa85c162950728e4e2912b92613a35c735edeb9ee62d080b50cd4ab12abb039d52be38d865f5806598acc70eb5da2b8a7d85465bc24a5928140a8d19965f5927e7c0720e0c0683655886c1601b369281b6b078df05185a2bda56cca766740bfefc122008822008eee49c4d7635c49e3801e8f66ffefe5d4223e9149c9a7b0a85ec38c249fa0344051001f5b10f7d87df91951be830841c4a31c77138608aa022e4d4014130739ced281072595f6bad1dfe4edf90017b731c973bb0810fac609e42cef33c4f2b2a9db2c3932767162562a0427b7e18c2862c3f4e6081658b19e7333eebc1a970ce44ca2735e37cc6675a3869673217288f54cecb4552daacfcc6974db950e4c6ccc5492c9bc930101094959ac92a4dc6aa393d2c0a509a8cd264942693f560a56666a8cd7c98c96c0a7777569b4599cd6480f1609d23bceb7c5cd529735cae35db540915a0f7ce3e80d87239cfe33ccff33ccef33ccfe33c8c3d8c6de7fdbdf75e6fefadb5e7799ea739ad35c7799ee7799ea7b54de92e6fedd9efb3dfe781a11ae8f4a032f5450b02409004bbae0b29eb6f5dd500808492df1afb3eeccfd8ef61c313bc7e9d304dd3344dd334cd144c354dd334cb8fd61709384c0c90abb2fa6561ddb6ddc35c966db560a8f0991c701c9827adeeb788537578a083abdb5fcd7b4fa7d48e3b62bbe3ae2a0fca822105c7367543478298b5be265af67bbc151d5260a2e0e049cd5c7cb029184cf090a660039edf860a78f5a032d4daee64ff8cad2fad39bfe6eb55b94e521bada92fda8a323365fc4d139c3062e7496d0821662d5b8132071b50e17a22058c56b375bf5f02fabdd741715f81aeca72634d7de1e115565f26d08c1872485272305678eda103b8f1049afadae1dfcf115095fd2340af970ed33481a05c7243a82ccbb2c4a1b6e680950715c2b8252664837a484ac3d159f56555f60794479759156655b61b59a02b0fd8207ab341413c66b8e1cdf61f14a84cedf9390a5486f606541e1b8ba53f40781e373507b5dd942538435be54079e0a839ac96e97e5399fc16fc3cae5a1bda9e5a962894654f6ac6e946b7314e9d7bb38389d38fccc570d9ce8604d97befce885f1b7db1a3f1da6c565fdbbd174728f450700e631c5e9b0935fe1d14cafa61a40454e6fb2d9de46ca7233a22cc8e05afcec9ab5bd2d5d0ede72b2a2b2b4179907ba88cf7a7ee053e84ac45ce41962237b10257c5005446f72764f4931d10b409ace6f1a1db262719380c5417d154f02bbdcba25bdb4ee76c41b8656783cebd5edc8b7b715fb65d5695c96c329bcc569e68ba4fa4bdd7d7eb158a44da6baf3299ec41da695070efc96bf3aec53784fff3c4da7f884435514df43d59ad108da456a2e745ff44efd6207097e35ed7c5fd502f0e9407a539429587be81ca743ad4150f75c50d514d2b088de4eef549aeefed79d766335d65adbc658de46c35dfda2e017dd950a8cafe36c2024d846d1f61db3270725a5283e681eea12ffa8aaab25a09aab2bf5f380d410b570e4e5268ba4567ebaa74b69e3b851bef94fd2151a8d6900d69bc5028ae405f364055f5215055f56138d52236d0545cc1f100fa5231976b0e0dda149f7941c8d280d5b36251fbffda8bff48705b9b58957d1e1ff4de54663f95dad7425ffb01b2abfc56386a3f91bec795acd686e0b4d3abba63cda44af8a0498fcdb47121380b4f6aa7b7311c43a368d457456f04b8f1db0cb6a852ff453e5434d62676ac534a2a3f3cf747825f0670fdeebb4f4670347e78d5ba8ab7e78fa935a6c6d4982d92e2e2e2e2e2e232e406048b8b4b29c5e630f5fcfaa77415728c93959f652b8edb19e242e1df7b41b7bb4c6e896ff93330e0fa59f05e3f59651df580eff70794bedc1968118d8979c24998d3e974e272e630c6b8561eb06c65e1ad9353d402ee68671cc781b5e2128b5dff6a59962238a4ccb5b64265d51b3c522d45f85aba84dcc0a0251b781005a090bab526629579339b03cd612b0d268a936e71a02f7f0740c338e41cbe4b8b529d941bd000fdbcd7c91952bbf7416efffe8239ef057038b8464c5f74aa2379b7a1c03479860c09328386dcd83368ef6ded8f6bc8ea04fc24b2b737e278afc77aeadf95ac3e33d3a68a743da2eaef11559f8bde6644d5b186a4471c9cf09fa06af44380b6f4f6fe45048d46a35d22a8ccb5e6cbb4d55a2091f82f3cf6bff79ee44fc00431033356169ed880af9f057a55cf0238d65c95a5fdb8aa518fd7659a5a6331b53c6c8707346471411667ab7f66eb765d2dd3d2b2a8933408086aab2c460c5366ca4c992933cdab92f23a6fa7b5be26299c6b34e28c9e341269911cacc3c07031ee15b2a028f47df51ac1d9f3be1f8928fe25ef4d4fa4f5d54e65465816ea1ecaa8ca7ed87536a32f8d38a51fbd27da90de34e2944ca5d2bb18afcf55e92fbd8b77a14d6f2a69503f7d21e51fadc08124eea1dbfff64864495b6844541a8d46a3a578606052a9ff7a2dcdd22c8d867ec6cef4d83494cdb6d10fc2e0494b3f91d6877f30097260b59616290c9eb46c98001295e92e2bfcf246abd1c2910bc121405b3296f05c7da8271e200b073f1cedf353f5f9039c9c2b3bea24c3094e9e3228a2f27b0ffe77f98b5e02a49f79c2073555b0768a4d8196464d9148441261780ccc0e1d3869633b64a31195517944d588449f47565b4d68ccf1465406df7b9bb093ffddc662b158edaabc7cad58b182d2624ed062f48516b34a98dc6ced5a5aee66f0c06d8fcdd6f21d2dcda66a11bc96265ce1ae9cab13abbd32a93b00118642211aad858f48b62f72402302fcbedb0be706067eff7bf087745d90b6771c52fbe9743add6e683a98f2b229ec02c7114159fab9540ffc86ba85d1e8e5ace5f0a5f9c07bdee97fdef77d387e5feb0b7ddef7a1af2dcfab32e5d5c26941f7a0e58d4ff2090b203bc5236d53b5891e9d785f6faccafea8c38e4dd17acb380c7d287c1cd684be8642f0f3aeb6200e48f8b084909b1f408a8082eb727e2247d1ed5b22a88c7e3d5e8c6df5b73c7db16f8970d169ddd97b2f0e311c53968019c19273adb5de7b71c0e880c940bbba2d5a737e3afda7381d8c3198635918765596d3e965929306b17d578e6b6f7d21605ba2e70f3e17af0ff7e13ffa50e849a111378239d76551ad393f9d38d74d71ffedd7a32bc74565be0f6503865ef4e1f5b92af3fa742211351aaf684475cf47ec7a8535a86ebce7886536bbea1efbf8c87c643e32198de78d64f579e970d2be04606bb7a206f35791f650a42d1c8a2bd41e8264907c7a970baeed72a173699073712eedf22c89c7058e2fa59752cb55ba22b947e5a7fd769c8b2432d460090ca27072040dea81a9431357a880320317534ca1821aca2a5e2f093001a5c707052410820c623e557770e91987a2b5e601cbcb0275b984d7bdafad65a9655466072a3392b5cb4a9377ef80fc5df75937d97b0c69b6ab575197366582c9b576755297a1027ed3ca1f8f26904393fb74b5bf90e6ea31bf0829d4806b57494306e4efeeecb260002161a264072c35e8d09a4152831468d9810c451869d9d7a596ddb2db5297bad4a52e4b5dea92bb8027d503cfffd9540f1c77bf4eea3fb82f70525b6b73f7f56a7db5ae1507cc2924ffc0ee88e1de3b737b9841015f20f8ca5cb7b50dedbdb7ebea08e88bb54185e3ff7918ea08a80f7ae564bafac2c005bc91a44cf4fa5b7b3f281cc07ea7f6bf0f6922d1df7baf3853e3647d711eb316e310fcbc21f4e506e7f59a49b1025e9fcb39e79cef49890fc63c9f8ebe576b8f49595e4e8bd0b182b26a28eb2fff4116cd047f82d625bc3ecdbe8e114e4b1dbd75f9ded87fa0f15e84f79929b8fd0f5f90d6187476d509fdffd7d86c361b70db49cd71e17df10043f0cbaa53aaf4749cb6810f1142565327e90982b4918bd76e690fc89956d2587067638561021d28a86df7eb07df3e4d478fe8dd77fb41516bdb3bd1f62a663d7617db54cd6205c5fb9d684306e8118f582471c7cfddbf23a6a97aef4da3d1be1aa3cacdb7f2e034877d91e8c919bddefb044f0962d083560b0590d293a415128d38d58617024f7805bff2c827e01c009ee338eefea5e787c5799ee7799e27c8e9539ffa46653e2de7798aed7288c5b5984de92cfa2c398ddfb2d7fadc8842d5ee75a9cfeddaaff356775c57653bf116746230891e2c4954f9f901eab1d995edf9c9494080b674b6d994cd557a8ae064eec1e0c541dd7e8cd36750107dd1678dd3a73ef5a94fcc71fa1491e854fa7eb966a06ffad4e7778a5ec815a6a38a30ac5a6a144662311c3dc496600097d16bff4414df7b3dcfdb58c73cc13c9da98293d4348366b6e0b77619986abaf2be3e48596027e3e607100ffcb0b7691061fba5a1909b1f40bc5db3bd5abd7a6b2dc5bc5d7d50e00708840590c9d3655d81a0711ca7f53d754c56afd7347dea0c8afb649dfd787587b27e8c600f007ccb02c73abbaa028075acaf24e04eed9d46a256b3cecc997e0981d1a07b0999016661f5a5ff1f630ca38337512eb902b831317092faf8a03e5664c91ccdaf2431980f2cc62626a68ac501a3c3c7870744ad5587579a339d82e7ff2938d849136652eaf0d67a7f0a5ea94c4807ddb1a96e84d39e263bb228668f535e2d5a046daa26e0074e525b8dab004feaa84b9d4aa5521dc7711c9771780276b95cde3d8203565b105bc28a133e626a623e8e4a07ae62c0497a765d7777b092001cf80a4e3490d3ccad22a9839c7ace2228529b4fcc88ea3e4ca1baef6dc01f719e74a3cdf7e188f338e0cc153550b76cd9a2a55ffd1fad750ddc0c00e9414ebdc654f08675dcf1c3cb300157d3ccb16885d993cb34d44960313531954929e4668f30c7713a6acab22cad600605c60b17a6126904e3850bd3ac34238df22ccf4a6337229148255289549a552a4369558a5d71efb53e8f7976c759068aa299d01794e869073f27a93c68a83cb8cfe15c76a5c5aebabf4110faad666d79269685645ae6c94491a8419b9ad16ab32837dc036591466fbc85ea6d14fad1984f2093e51cf24e9e85c6bc13b3fa8b6d1a6a8e9ca4e618fd8ce5723817d672a32ff80734070e4214278ea95836c3b359d96427731c379b896c09047b6ffb27fbd4bebe5bff8cc51ec6dedeb56e4d61b455d9e7110427e91519a032aca77105a541afa071c5bd7746d7918610bcce70308030d0080f901e3f947012731b564b3ddd77c354a0847f5c059cc43fdd7e8fcbb2add2d7278e6895c052ed365ac0c90dbb36854f20bb3a4016bcf6ae9e243efbade35c577f2456d387af7a7810ec834dd9c7518270701615b4c088560b37b6a545ed0efc26c480931b5669dc9bd0c3f7bde97b6f5b24bf262787f439f46de0c0c94a2b899576376cc376cc1cc9bd5356957d72d36ade48725bf7e9dca8c76e2453b8860838994fd2487ad3e8e2496f03e34d0fe34d6f63c3b88d1d0e8e6f72617a1bd29bbebe69c47952471c176f7a1c119ef4445a2f4414ffd31369954414ff174fa4f5dd1b0c8cfad24740868c2fc97816623cea298da7a51fe12330e3698c2cb8f8193fc2c8c2131b173fe35910e14b4f5ba2ff5c881bb6635b561269b990817afb34ac1b06e363844233be14ea9a1cd4cb781144da2afd0c11623c8cc72ff1de44da2aa1c42a38f85f4d8e0b31756dc8788c87f1dc166bce38fabbd1d3b012e9551c62fb68bc486a8efdd3f77322f9a3ef9fb99e8877401cb3298b7a40e95fbc4de95fc418ff8e362ffe34e2c018e9cf5c914862583e45f2fbe9b2abceae82f22d6be972ecead5e97423fed11968ef4d2b6b1fa12a259bc39dfc2b837d2477fb0859591b4955ed1b6cc8a23b010cec369a70547e4afba12fa34e6e98152f14cb836e2f1637ecbab77bbb3f601996e118e021f00a72b63ac809d7377d2ec1ef93faecf2b937ee76d76d9865bd34d9b32d259f7b8acdbcb261342b21e8e4966d9e1d65d3babd9d39c8aef013e7bdf762d9eb7327d9308d009bdab05d5ed68da02118810324335481a1657fcb2e0b034e64b1528513570f575af6376cc760bce52fea483e498bca8231eed825e5339f2fbe042ec60d338d1b56da30d2a69d5b08b55c39a12b0ecb6a0e2174dbc55d03dd32d0d4360155d90dab39641b0724b24dcb41f996cf0dcbe7799e17cb5c9dd6ba66c3360c0c11e1b684277870e8074ed2db4d8ed5b149720c95d12fa0d2777c60c18da7d3e986562487ed240e1c95477d1182a081921ab44072c4882c7e3061a80205490411d482c18414576640c2081a946871c0d6c38bc90c4200d3a2653b4502fcc00ffc7a8ea082529082940b69c013ea96ee51c1759b98a8b4ad3805b96433220000000413150000180c0a0583a150402c1e936bf3dc0114800d627c42785e3c1649635194c33808a218838c330600000030861042604335015dc03c5f4f5c68d33a9f7a6b9bd3f0841cf22d846256b5a5fd6d4a7a1e8ef6ba8d8136c86566341f72dc36f0dfc7eef7dbdf75f290cd07970b8cef4f96957c457de74102b2b066625e8617825b85a9c6b04f343bf7c05af2a38704227ead8175cb909085ad089694205f059dcb9adb7add8b5cdaf3762e0d3e90846c60637cefa6a55ae8aeb1239ad0f6235f053d868203c9959084503c6f106b4e898a3533d3aa72541cf3d096969d8e66c4d37530617d0480dd1c94cf128ca30eccb9be637ae04cbbe893438e74e294ff3a2cf3b93396e1231ccbc2838a719479537a5d874f84290cd8388e57249d699c30769078b8755ab974862faa1c19d2f0b531cade60145242597839889c633a1a3fbb1a94ff0658ff87a00d18958181113d5934d29fd05bc7845e4d506d5aa830d5bc80110a87574d2cadf082b31bdf80968c61f109553c2ab168fc8d3d8f463c1b45d49d6c08b9b8b7326adca0b0c0317183f7006f2868b48e5f87f56bbabd5922e1306c315652e4089b932ed28dc4bb31343f872f1dc0c1279a7fab033e77fa957c14f7507abefaf3b527d4dff67c7aadac76bf20c77fed58eae7a29a6ed44d229efbab4e52ce9bc9d03851d3ff4d2bb870aaaaa910d8dc5373ca6686745d8a9b84b5350a4baaa77e5fde3a9be1e884522233128e87607bf3f9433b61a2db66806a161aba4b84d91e1aee5f9915dc05ff2ca7b51e27aee8cb2787a3d3f61950a1dfb4c41e486d5b043608a39e432f0bd8334f633e6660f7f0ea6431689d08864db4cd235fa8e126bc5dc9a766464b514862f02d5509f81b14fb28344fd48b22fb7e7d9a062ddd718aab14c2f5d2b27ad3b8e833df5ddb0348ba7ea471df4f15cd067d09f58f39ff418f9210b76adfd48f588e99141b6c1e968351fa1c08b60ce634e9a3921124a8dfa6993620f2ecf2684a2fca8b96ab0015e461b1a017d20018e086422f641134bf3ad45de71b0438d77d04a662cd85442c61bc769ecfed565d8380cb3802aa7c800b5d3339de5865b6c76f97df9152a87a43422eecfaf28597e3fdc2d0388e616878bf989041cc94522c9f3492b2d5103ce5d8a1c8e70a6cf14c2b1ca2f0969b74754c3e581cdeff55b69be54d8d63c11f4fd1f0052a1ad7b00958b43b249a534bd9ff3b174431186ff779c239792456d3b4f601bcedf770f0fd7d68477c47890aa7bcbf8637f38c08acaf6d56c793a9129f37f86972e93938a4f40f697c49455b863c9fdfd54f6e400d9e6846277e0910148e44483babe34f51b1ff17426bc5054d1d8d54f9cdd0d91ca825f457289ccff1a673bcc18bff7521f8cc7c9b3360cff3afe13bdb3174e61050b4284710cb81b8ca4f4260c16618a50e2232fe04ae9072a62d2fa3a36c23473bc530ac78a11081013d90e4e5cbd4daac7f51510d334809fec6b370e2f22767d4bb13bba0c219bc84cbbb643bf4b0cb94669128f3cc926aea253dadb00318627092b57db30738a817fd4e7443eb868844927ba726361f1f8f4499a4e93bd4a185239325f9c4431e7ddbe2187eb520b694feae3b732138755a102b09d81532c2b23535a375b4896f748463545674e0744234626c69b1a171f4dc1689d677edbf3ffaf755b654bb86e3743e18835d223a3e94640f3b61403a12e2e14b27585b54d0c1c39329434e2c93d7e34015527b28a716154013f797658802d088ce41aa720a542ef5ed766b0bf94c564d1b887791c22454fb2c3b82f23be7cc6743eb0097804115ba6d206d805f9e1ad0bb6949b792e68aada9c8b52409912b8947e6857c43eacd08653bf1b747a0712cd16115ac047b10267f38242de0d0f25c2cee525145d874a04501a4ab400d0c254d572853f90c4ceddf135c915fe83eeb9fb5a28f4bdaef0816e69dd52f1294124a9c45f0cc6dee69724f3e841954de4f65031a8cd31ab0888f94bb40cb0d07fc2e496e11d9983184f383a2ae6b25de9ee1b6379b907be42038417bc23b9bfd89960b1362364d03dcf8c5d9cce33ed142c17ff9d68a78314474be4e83b60df0e80c348c850f247bd8c629a9179ac6913b7b28bb1f622693742fd684633204bb90021edbe53aabd54d7fc22824381265bc84911ca2873c317cb320c8b8c4fc57f8767588a17454a0d8e7522916b9fc97e7c008f6d83963f77254fc1d48379b16fa0839cf9a1a006df7002853d360d13697b6d80ca2b4fbd8a99a70af416fd808678af0d26a91e286f696aa54830e8cadf051305b367c882c12f2aee76884823ced0a544815968a6e52ff30bd67d40b316a092ae4bbbdaaee328a75d6419e1955e1c2b74c5db02a77de0bd44c43119076699973ba9f85990070c028f1aadc198095d8fd4c98b9e9e480556af30d8ad58bddd08f3f2ee540195a87a8beffd8d2fd273216b29ca54ef6d21b1f5acf1ab358f22aa6ebb55e93db64deec757c5097191e84d35a51bbf32c0a802fd117fa064bad60940a05ecae4661778aed42306b51b0dc4b584323602903c45fcb09c557619f52ddcc6cc08acdfa583b9c6a3aa6ebdda88eec8939fafb0b63682314b494e05e5880e5aec5a2c0840115d58b0a7e66d6a2a8ec568ea563af88e563c074e000d2fb600a6c20b14cc2d49158723716f9c6e548bd1438d21480a2276d62e5682a4e2ce4754c10fc7a259dab01c910f693a3ba3ec7a767b8b9f52089dc9d1c6da8cba280cd0fd45c1c0c13ec00e58c69face579a9d9d25611ced17d1b0912b22b109fea6eb8256fcd6e326539553aa37b66046658cf7cdf499533d2381091bdeb7b8b936acb9e2ac17f144f282f2cbed11842b741ec978b4a076c10f50974467f59a27903181ba0a7e5b57cf5bcf933f035008d05c12f374e12acbd7169f1aae4a30fb883f4691687bd22daeda26e38c60abc5b86e2d6fb6785d6c509fc11663132617e34d5b2c0d4e6d297276fd74baea37f0221b9447f6c9188b60a1b8623f88c4907229b5d19b0995f8fca2605a2078832bae72f085b98d4e6e5bdcb3f4c0fa211b97e0190a00e76780f34aa4a002eae50fb8266460e29fe05db5a93719bc8ccfe4182dae98b9316852cc5129438bcac482a3e247196f5417435d7de591a37f0f410384f3f3bb8ef37861f888e08b3d8a372eb1858967f608b9237a9372b9c53a379f414fac5174cb12e802b630d6d5f5a1725be52608de0cffc939616a706360fe3413384c41fe15d6f8cdee550bf68caff813a87253948888b98bf3198605e840615d75a4a2bf2ffd2322271735d9096c16366e9afb3f192fdea76e00908d8cf5d5e8fb575f6a9d8276dfa8cdf83f1be8abd0032287701f37352cc6ebb66f67cbc1f9b6f185fb410e2aa57850beee4e0d33c212fa8ebd07e882777e45f907d2094649393df934c967f82bc50b33b48636f67408ee0cc820aec257866ad3e5b3daccd430671afbf72432814b02193335b69c38699ed32753c360cbeaea3099323d980301be71c87c30067c6fd203afa4d022f91c4f6915f4a3f0bfdbd5e44754734bc374487e8e883dc6e8819bf2f311d24d64b97cfad14d8a2b0b1bdb7dcbc9dee78712213bbef4a5cc8ebc4b408398568b0a4555f2c38cbc1c546dde6ed7ce7c5ccbd186913ff0bf2f14cb187b828813fa7296d91b17fe430ba09e1e60baf01fba34612d73eab422a92dea362bc5abb86ef553a22069fd89d7fc3e4a58b10a9052d7180716c0701661028cfcec61fa39c4a9279de3ee8ad2394ee63d6bc06e55566a98c248abc9c7c5463f875edaa122deaf551bf1e5ff1523d97f17bc25e8e7ccb4948eed7d9a1d4ad2fb326640453cdf7ed38a886e61cc0e30b0a390d946acc3447bf2686cf1a3b13398da5da4107af11f4168106cdcbc3cbc2a8a0d0a70e9c562010d227745474947858dbc5901e36b964528947527153c8683556f8575957910dc519e89a81bb86500e48246c04c45b1eccb050899020b6a509ec34c8a9ba68ac48e24e682864180b24201642ce84ad478183b1cf8030434cc80830f72f9e25882497157239723199843ba62804a3bd9b088a6457db6d8e358e305c2880991dc18f7153e5b2c0969a3e7465183cd8e3430312d0e6ceaa159f19261bc54e0c09920fe52c3986661826706a96b2bb41118a1a5db009b1c4e0a781b364e5e645a62ce47537bb337886116172625844ec2e7bc40c7a12bf6fd67d97cb48a08e20745821952edd618badc3013d0f483c126cea739e5625b630d73c0883013dd57348e9d3483372ce3cb9d8d4d5ed5b9520fe041792865849fa8a91c9f6eca62d327a213a7990f6ff2e909400b6fd55fcd70d768faef6b40de1a7342b6ada313a7d6eff9c1cea0e5bf98325e2d1c647f04e12ed2c83fd17afad18f1082b60f08a3727d79da737f6fb45403f0ddab02b438b9f57ead5003eb2247fec4bfb30a042c3b531da7c4d10afb73c43a84a97a09346d4787e39b448eb33c9f5c040128206a1b222229f574d6962eece9c6046c0003f041937cad71750377a1c5f0cdfe557b36c66b4464a6eaf3fc5561a626b40f5435738fe88285a1757073e4947cb01b541c39bbabd3ff46d37481da856a6fe3feab50aa59386f453c181c142b1bd205866e6c25d4060c843dc037bdf01f003a2d4b4183c37319f92dfeda1b7ce27353c90ebbd3fa234cd782a0d5b71f1b88065d877c1a1e210b2779aefd195c0fc35ee8bfcc0bc3af272a2cc5bbb9a4f2db50ee33a2a28850f85d0def8b8904f2c49b0aa3f6d8a093f54b34f08c7331323a5ec87fd3240e36b1b26166412bc13e7c26c8d9114785f9b4b2ecbcabef59375fbfe0eb6b1fb4d5f7cde9058877d0f4043298df08d9d1f796fdfe55a5441c02e9d8de1c460d2081bc6ece852a50f3f749e53a5174ee0bed1d15624114a368234c25a57aef19c2cd53cfa882318a633bf188ce1cd5120fe5ab07afdd2973f20c0d02383c924ebd84f03f9bbab5cca98a1587b81a9159fa062691af055de4e73e9bed21188431678203c4b2e597c4808e2273367338b98e9199a8f78800df24f79d6663919c49f073800e0e54c88f053cc8047de2800136a33978d8f51728cf497a60f6d6058d33a3df448e58faff6688f8420967df0086351503be0481108550840e1a44e36f723354687576a1a57168f824c6b9df7ba09b3c54ff32d8d1b7b11b548b8f2ca9fd8006430f3822a0979829806b69019b3cb11e4fd4328a9ddb09a403f5b20ccd9bea383a4ec07c0c220aee52f87f56cc85ea4bfe672e6ad77b1955b4548727700e40ea75144040dd07c6c72842114f6846b000d61102627fe6a372a646326d0e18800d33c485e9b8281b2eed53017fe2fbffb31aa289e50928f354341024062e75c4e045e20c71f94612defc422f2059f294cedf446fbe29b9748bcb928a3ac4374f993d631fd8641ff49b9a8e5fd197114e5f0fa982e0e9941db26d6bfc788e05bf02a579c39a918fa28d329135173f5a3e28def58d9c87edb25729372b1d6fe3f73d93b2bc3be68e33ad971f164d188edcf94bcc9e130404e0a9cef436935841b96bb8c4847d682b9a34fdff03faf1389ceef278947951c2f6ac30655cea7481783f5b44ca0a8e4978401722ff5da315ae38b89382b3b5d0a0e186620f07bc8aec5fdcc9c713ca906f5cc0b6c41cba450044aa3c508b17aee2a3c3cd675ee1cc75cf772b16e3e020abf06ad4455c345157671d382447b450e3020702566328ce624820c5e3961a6a61d5a787858df12ad8221eb4d89a99ee7ab5955d73973756edea13fd535c63803a4b6f5e27704656c9f2e0727f1a0e8c19aa16524fe056b8874f343d6e409ffb34c34421bdf3ce00d1a148426bb294b8626fb12294d6de8a72acbbf7a82387103b9fc4c7e570733c7c66ef2e822510517fe951ff81aa7c95a17e9337f1ab71166592958925f3688a68751849e8c643dcbf24dbdb804f2f9e9d10d0923b6bffd9169cd674f38347c0ee5d4b5733d9a64d3375f5359478dd7be1c80b232ed5a0ed507d8914a9b7e98d6359de34631abbfd2fa5144c3d256bd3ecf3b211cd96342e0698ea0869a2312d7ffafd329f419ede21af818ba36426bcb67c40d1e5198d31e52f63a827f9bfe685312c00f4aebc0035c062a41eb02cbf096807a0358a1635a5fe780131252fee382df190e42593607d8ff6c4ff6cf50c214a1fccdd048436a6bd4c49212455d2c517b3f77b9bd6c42da2379b63b917e472f412aca957e5a268361b382caf985e7189af2ba554143e1bebd04b8df122dc29bac0f49b56990ee07e28c28dd3a09d378e0f5e3f2b0acb064fa5a1bdbf99a258eb7c256cf594ea8d36e80e1545048dcc5a44e2c05e4521092f06d67cdb202a9a2bef6c25bd912ea1dfe65c43288af2f3ae7442d867a6a6a200c1f366607a8a62babc486723bf07074a3c702998b36107ee1cf7374c7f21350838f90ecf2b04c6d37a5d21243123396281b073a2fb646cd8fe597a749a52cab82e8e6adc90691cf1a8bd96ef5562ca4e74b5208f39b45691df827866f431f9654e29af312e69184f2d0d65f0efa115c92beadded8baaa2afea935df8e826e97da7db274f66685cd3044e27220e3e1b5b006a164fa6a7031d9a0a605eb866e8ccb146d0ce3aba8411aabed243692150254f8aca84932b389d11b53c28f315e07dc7e837a9596063689df7cb65a8680f9bab2781a0374886c1b902a4b44b44ad9d6e6d4fed151ee6d10c5101cf07dc69fdb3b307ae144aeefe0819621cd55a4ea96c546f45cf6c47f66d5902a350b14c2cf14448db6ae54108682562cb9522b668d683c35bbb889768a63857320c5cba14680f7547eb61f6c522a8014ebc6cfa89c8cd1d277bde852c98c2f6cdcd5ffb578638c764b76db5ad5e93a19b0c2c0283d6c5a0e72e60710f94ff30f3467bfbd028fcb35717e2162c5dd3836ab28828d5d23abfc506313888db8d0273129826fff415016e218e6d6002a9a14480de21b61904a9d863dc7563d9c2a2aee3d62cc53b3b1d7a5e7f0d8fb6241ff98954c0ee3d00363b101a738b35028b955cb9fcb84ad5341cac78f9c32c93a9415b46f5b7ac782e7fd38c0c38de15039fe20d2f6433570d503d1004ba656290033b41aed261582e68d03a278d2bb9e0331d26bf8fb3844ba756c749de3c6b1d0cefeb1cfd096cb7fd14778dce317c4044ea3454a1011bbf306d9bb03028ff9b9c621e984eb22e8c045499da93861156ecbdcc17e932322770ca2a44ea658e0d73824132481e083d6294bba241ee31ffad8b8a92460fa9395b41b81aaf6e1b46f01e6e2e666395d0d9f6403d484f4f767e01606d4fa571202bed76c1724816dd42e202dccc60d95841c97ef88b3f82e02f2c9270b454d6eef5361d2dfadaab04692c6d0e417848f3bbbf381a90908ecf4db9728dab6109006777c8eb972eb3c5c4f688722d2a3fa92e5f0dd5a8ef15db3a2dc955ed22074c48b3632089d7acf0d33b41945a2e0ce0f8c7a9951c73a0f550d317906ef0c6670c4bcd6e323ac439ccf7aa556120c3fd183641febb3c6df033ff5e87d387d316778a10efc44910e4c5aebbfd256c1094f3a6676ec4c023b8a6c68817227ecf88cc39c258b907b7ed5cec8864af9a7ed771921975fab558462e42bd86c9226ca9be13a3eeab6bed602ba053da02b92ac102848967b084feb3bcb63b2ea02840dfb70b2ce139e002a6b68f8229f9c4e59ffe931f22d0fb2549004c0142e1a05da141af6f3dacaadfcb232e8ace969315060bc0f5694033755518d9b3e268f303550a44f07f70857372d2eadcd13a6521872d0b2fe97482c609e613d53317d7249bab0462abda4cc9d59e01e3bb4a2e797ce4e37e377f515412f5b0452fff2b932e2ec8f821207aebe910674601d036ae1ac674247886fb43408024c1215062309b3eb1a2097ba77519c234c35968a58ff4c03dcb3bcd20c0228235da336fd7f1eb42016a053718b06f6b0c006dff4d28104044ae4c064a15f2450b3eed3a86b1f4f2b0c1ac9c20565811dadfc43e2b24485905331a30ac934e73940584624451dfb202b7924821e05516c222537bb81ec7f3b2910cfa0f6f47c6b9ecdf8db45e442a5821235089559faac43ef3bc9c4ca42eed4007c0256e0db6dba39dd3fe4ed800fe83198043bebf3702f05a39b8adb16420a522a6131fb8406621f77fab86a4f863bbfa8287450d56dc080d501837d2b4314619c6e8ca0587ed8a39f83e6cf63bcec007e6b310d84740226b0d8fb706ff2603f92f77a3b77d58214bc79b05dabc497aaf4272967c194a36321d6309e15681b4af20e4a310f23905bf6e17292e50e895552c16e3a68f64f6117efd755e0854709730048b3bd495f33248292a00cca6db74bd3fb09c10d4ec3ec170838d68f427d027202c9e30c13e90274ce04c03054b4a9e2d1f0bbf42b9da8b1d2e57604f4bd0c5dba44cdd5c38f0fad8a9b35060a04cfce2b003c652bd4a72f4106056709cdade018518f6867452a36a921a80cf117d26a1a9135c687ae9fde6a18f9c8dee08314c735f1b7ab13044d12047ddbe41e965488363dffd50c88f1f0e2328631c6943ffdab85244b2025910979c9f493dca5607c98bd9dd489055b1bcb59f513bc9e3abd0e37fad8c0ea3dcf16671305ae4c686a6dc6d765194ad4665aff906097c41b6bd6841551344e2e1af4e7496d779363a16faf860859bc52d96e73482a26c858002720497d28559c0f2ebd721ad6b0faa76343cf8f61aa072d8d769c3254018fa291195b7a23ec19a0bd4252da26822a853b3df52cc6514f2062b1839c2ec022c512c97a02a38b186236e4298742dfe13c652382d02d48404cf27845661c004968b0ecf2bd56498e8c235374df3476128421d64c85a4c8e80c25bc55a90345518802130c1e8523fb3ce93ed7a03d327943098fcc67e06b5cb933dcf5d234d0b3fbcebcf40ef5bf093f39f0861280cc40bfad88091bc4c57e7ead083a58f6e41fd70b7e6f1e7187d013a5dd874ee0c2d0c88057b59ba0829c634fe2b587296785382c468f0dd0377907e3e7099d47ed86bfee8b673183aae52684e6404dfb45697b6114c9d3d506bb63752672b9204a2ba94954e75335f5cbed7e19e5d73174435d7a58eaf5da41126eab1d76674cfbd757f1ca9148e86d371f210af3430fa61d5fbcd035102eaefef69938d14a2ce591e9f4b81bc451f0a78dce72298ae386a44e3b7d60235bba3202d78c7430755fa5fcc6770eacbe3543c0145a918bb896550c9b5789e27260f5b7cf3adab5fa0379d16a93f824c1ae09deb7ceb13db333fcb8dbfc6fac0055fc320962106a96121c7f9dfc2505cf17f188c13b7f4f730e0d233d5ae9218a0850c1451b460194a8b0f81d7216e2ab5d9a19f007d7b34b01f252ca3ec2b968c261c2a65c69a275ca672eca32c163f7bf6b138fe1f4e082d71a1219c086fc9be1089987c71c9b43a54e160a3d21785195d4714663d5fe45c4012cb98fd98f1643d7111a439c44316da13efd9399eedc4b2093acbc5b99920e4a0f74edc34530a5937b0f52ed1836d1b736af3d2fe4834cb7eb5b84217c4a697da92caefe0ba53c54dc7d4ee2092d98bb2f968648f850664f6ecf8dfee27b56135ee42d9bd711e2daac876605d714d2c19478bccf61ec0c3571df7c9cbb69b7f711113956148913279889b2d69f62e20077ec27067b79a2d814973cfb8bf73e339a9dab56401d426b7f06b564f16ed7b398cdccdbee650ca85e2c87656bdee21b44c9fd2c104d4b272d864d6dbd8f7adb58cbbb759f955ba44504a85cfbba7d8f0f3272bc85031f46b1d38eb2d6126c1986f26396996e2141b3f3c9366dc9ece4dd555fa06cf2446cdcafeab1123bd64641ae94c0a12bc890c904914d9d2f42416b3c6f5beb3b45d2f69a2d1bea4bcd95e126eec544267f503dd40e1c4b94b15f7229669b67a3509e95d794f6678787540534e208aa4fa33eab85e9471412821a1b94b8dbaa1c4e2641a0775c7b402ff8f604f857a2906b43c5e0f036f2255a0ac704555f4d0d10f4d72811fc03ee9bea447589816b9a7bef45c707ff26822c648af49166114144dc262a9cabd89af914d5a565d3019cf2649fe9f4e44beda31fb7df871ac9b4de237d9f726d165723bff96218a3e6d7719c7096e0501bd7e0dd19b54bda7722becb668f5456cdf12304a1d97a53dfb2fa69e1b6310f0f4c5be9ee5680297f878aa7cc3ba59b1629d56710e4799bd7d6a234b51039e4edfda343c95ca8bf1bfae5c4d061cc96d1933da4c35b83a8db30fc80021e24aa0842959c17e4f852f1bc872c0a72caadc6dcd9c2eb583f7fa7dc9fa2c7c004d4da0f58aa3086113d81c981979b8df1fc1c0dd091460ca562ee0859a324b2ae4a6af6a6531ce1f2fc0505ac1b99d467530ccb65543d2984822b1dfad0446e562d21f6259c010919f8e1d5a4843608a332a6e62c8141ec5c56e691268179e3b02f1d13a20f307d66cff09ff141f734bdf958468a9785a49852d5037478e08669831018b62263b1b4db69d11e092f9f7feaf79f95ca635e4fc7a950056d597cc5e153d3d236851fea71200a44c4697bdb4ea0c7a33104eecf392fb29a701e8f21460ce579b722413513450f68c6dffd29e77d9608915ad3d59a4c06ecf120d274b80d58e2fcfc869d4baa14faf159b2956049d52497d443c7f09b19d727ab839b22e76d098ec8eea8b6de9f421a760ec2780dea470c3cb49a5916d8f892d55c2e80dcd81f36c695af6330732ec7be6606b2c25ae39ff8fda519e36336b653cc782123bc28711e9bcc64696d1b0a91db3d8c34a1418c0ee92dd5f6cb38551762afc2c423d2d004040876494d080327fb15780b1e50a0ab5f03bf150724e33769d39a270219bf86e671e568f6e918fee86721fb570d4bf23a94d3e16d9e2fbe2fe579026b277a9297a09e1382948dbea2b913dd2fe2e7c537120465be777cdc90845b60cdc3454456db3333f16495fce3573815632da6e85a7f93d2b8652a1eea47d6eb5984fb54f45bf16f0132fe7cf007baef3f5dcb7ded5f66cf54a2f4c7a45018b92a142ba24f68a69e9d50cbc3bcf2b2cbe7c58f43b62918e5d1e9248cdb510adab4919356f6653b52d8d429ed5cc4e896db00d90743af2b74d3846abf0a9f7ea3c14e7f66d34d38fba093344b4e637a46325e8d78ac1f037533c7bc1f93110c447d9acf591aa62aeb7e82b6a3c22122545e6214127d44faefe93a9e8f0013f00cb161dc5d416cbbaa686890f55a839f16694497449759133cb9d719b2e8ed9503645602ca7117c0118e4034d546a5e41122d28be07205781e16d7612c11c8a8263f4c0998fd93f968fd53622c3c03389cf252c2ec51215459357400c2ce1abc1dc4745764c18e679d380112357f651cb4d6feaea98dad6829c083b10873ed5b774863b09c4144ff56b37e8b51ac5b2b99fa652e298ab7c95f92c033b2af3f205f4e733493c27f36975c87cd264b482ae550df8f95982699fd3746dfad6b2dfbb1865022fb9a62dd5b9abfb9cb0d0f34cea0c001172eba857fda7cb010e9ba2e78454504267528e18728f5dd7e90a5b67a18c4202ad1601ac78061b39d2b51115ebf792d7d093614e0f9e90c5f71b34d377f5a09ee723c5ed7e4ff0849308d95caf3dc44d9623c57f02dc931b9f1c1bdfac0fd871e38c8081cd1c874c6c8d60c5d150371aca07ca4debd098d1aa70180a06ab7d70b0c6cab5b2301339ec994eecb5b58893ac2c006bb6e1e3d26e848925475d68e11b4a5ff94165b34fdc5077c280b444d4862ae15336c6b6d8343654581511e6904ba4c5134d4b423eba9296c60100a39c262d7c6f169b8f2330a2ba08da724b05e2b9d9762cfabb0d2d3f74651ac6818883b86a23b3cf8b894c2663d76bc009382f4accf0c80597f2ae867a5296ef0e488b1e09b1d30f5da6f90169db862e15b4b6e58feeb7a5c4d7a65cefe8f8299eb6cd4c4cb7565a02a3197fdadacf32f12d01f77fdf8ac334931c3eb54f74d484c398fe6b33b780256b74fc456b98b05b98d3f8b0e238b159cf1bb391e5a8596a43667f6da035e76fd55103d97a92f2de7562ddd53875b9f1d35f6c81431eb617c611e8b4b76fe969f77af21564b190ed37ba8913772798e14f5a53ea35423f11c92bb04decc6816326825661179e9b934f75923e2baadfd20c49f065c8933d49b91db8b280df452ab8281d6098f14f848e7fc3226df9337f688e4ebd25c2e535c1d6a9f4df25a2d9ec24f7b6269237bfc654a7499840e87dc7bb4344fc0c9caf1e0140dab830c96ad798150c138665eb911badf99a11676bfd81cbae6d470898c2cc3bdb517c44d55e8e745e4b475c43e82060108fe8e0aa104b7bc4130bd2d0b6a30204e97d4d51b2fd12ca1243d0f3917505e11ed4f53e064a2510726455079d7e12e6cf1b6fa49dc6537a121ddeb36468b6255146899c652fb24966679e3bb10a02228ef31174798a5965d9d25ba47eb38290c38a7948add35bd6ed49bf9a1e4551ee1dce3bc32206f3de3f0085f9c2bc436158f0951ce7e8ffe2df557a1733bb56350dcee7cbe68c1869f81a224534d3618d8992bd825f1f0323a649431ab294b0749252195ac0816141e7c9c94aebbab60c54f59e754621ac8d8b601c4f80d53b36676539af3a5af23adcfa43df0903240c901614590af7ac93bde5132e6b358210288be522cbed73d6abce4943250ac27a92e2c5de68bcb13475258832ca2c9ba6f0ede6b53d8d31ff4ff0b2cbd61d9136529b3ba4598841a76ac1ed025117360aacfcc2cba03561882d8979662ab9d18ac7d2c523dc7283a3f86e48ee725d7d716071d29724cd44c0e33be441f2e5fd017a207bf5218b341ce8aa195f28aa23a8b592a08a996630a7eec687a5289980d92ff03a2177024c18ffc42087baaa1480b3446242722241802a9bc0abacf07086d0bfcd7fd575de02a47249029fc1374a61e7229caf12206dcd2b9be0fff32e4462848e2a57d438eb4b40be41f14dfc2c4aaef783913346c9317252948c6e0e290ef7be734cbf60d9e5cd5186905606b33a86535339db716d2d4ad324f4341808d6bb24ff80f79ad257895b964cc65e511f1834f1c08deca12d363ab53037d198d91a5e84351de72bbafa5e6a43881ba60d9c9390c9346e4b3e35168ba36ced973f09215743279593949f00ac0ac7a4cb8e8041bc9c58633d40ec0fb4234c22f1d1d9322f2068edf76a34de6e7efbea9c3e4bee85ad2484c7ff115ec99bd169acd9e5c0b9ae5e52749b9dda73fe00d732d25b7bba1d8daa9371f84e0969b5ff073fdd0b5b82c2d0832b00c2612c5471d0f8286bc9050adae09576434d560bf38aba4a4dfd6c5bbd78690f267dae994af6b8e67cb60b751fa04b35a2f1d9968b5fbbbda40c5c8713d7bfe3145453118a2ca831f7f827dad29ef2ed1661695ccec4864b0446e12816d02b4a73823a0464b9792106c3c3809bd9b1dc5308cfcf16b1a1dff0b6ac47fbdc73d5de85fa43a4ce892b980d77f22de710d957525d934b837825ca8fe66f2baa3cfe45fa1dd53b6c6f3713e6f682a52a38fffaa45925bed648a429eba91fcc632d0cc8b5d3e702264b7d191f7c2c7b6ceda5cdb748bfb3778e68a1b1d72064db20f4df205c1181a9ab2ae1ebfcd94710f409ea2ec48ae6a79d83ad725b01878b87f3469e0be538a5db9c176aee5135bc2bf2e8dfa4e195771c754361a52c5b47f29116220897f7d41ed703970302775652594f33e46825dfd331a2743214b038ce531e420ad4a0c16c390b0c84585666fa2736f2eb420152a5232915ce19df0762b20bc686302e2269d813ae80c994a24dba9868aedb9948d7c9bb17726c870c2bae6e27f02cf043d7be0d7071d47924eaa047ad768801ea9a1b7f8c29a60fbfc18b36d73400865b7d7eb04c842aea1b407506beb32403e400df8ab6646d098c3e92d2dfc4290a3a56efb5b82101b91b46ff8805fd5da5fbb341c64aac9a708ef3c476eba0eeea7648f8ab34d5523f05bfb4ec51f8703e2e9f36c5b4d2ebb623ce7ca39ce517a5244b1377f303e99f3a160988868208c182db0f276bbd711ba5fffd0ae1b8443260f31eb8e4ded1863416e9b7b79f515851a1f4de9165cd3a76cadac1d9b5394cbb22614a5d1c1a9a9830fede5772f39e15a2a843220a0533d94d7c0f3bf00703d2930b623fb90705c34ce2af40c6c0610820069915776f24642587115de4821ed44556ab086bbdc6788c51ccc4ebadfff9a9228605c9f4690bd753df61868f39abf5aa4783180a1ce22e6942317b671992a60dfd3ba7186dbaef1b4bdf81ff0ff857ecbac39ee93fc04c118d58edd8eefb3d86da05ae8664d4726d0689d2c855024d1374e27eda0b17804ceec28fead81514c3a7438638fe0120fd5bbf698bc22d244472493220146ba02cc9d422c91257a41f13697f44f873eab99772bb0059caebe396b3e34fcbbc7860f7ddf8088d1c6e763e13e17f1188b7bfbb13445186d16e77f6906f4c25626025f7f0c88f82db4f326cdaa3940b6e7d12cc56cdea9700d8331495dc52c575161235f3a930c3397e54408ced2ab02cc5b00a02d9880b431f52bf23fc574f8a96adc76e7c46a3f1e6eaf104f19adb7051db6603003394fabd176dcc7f7f3cde86bb3d5a3566ab422d7ec14cf41df4bd192f63ae0ba13355d57255c928c9af343ddc675c721db2653df0d2e6700ba99b59be0ee156e4010e8facb38303d5b7a8b41053745170df10f90d48b77fea458ec7ee1cdc243d5c59068b60bf41a5a1a4aeb16c111470a4a4870b7a416bb3848db4fc840f519169d3e26d336faeae92c9e5523149dd43fe25563260e9e25e0cbf87479fbf1085be2021dacd3f8a12faadf27f6432a297f6178de8b618d5a3354d4a8e3cdebc8fe6aa13e766e45f6c56d05794dd010bb501d1af6b800ed835f44bec1a46935d03d878c5b2d4c4fe7339e6e5c825d5a9bdc51fb3b10cb1e69d782b6517256f88234e4b48b8b98ca80b4e0a11dac990b01b095ef664211ae51f9a25d6b96a2bc374d12aff06b29a7968597982270e99d1bb5081f1e8c4b134e3b442f96b7032eaa52cbb87e9f7da6f147e13a54eac8c7abd7f8ccb6f9b2dd1a5bced81f7495127c297e701041851edcf9ad0cdc87387073a6615d56b1d50a9ecae7a72f241016ae2428c4f4c47b1a59394c678c0983cf13999ed8724133e89529a30400edf4fea234565071cb4a425dbbb6dc5c0b221402270bad9f6e2352ee79d8e13154114833f3f5426138b9196263432f903d89bc642647e85262193ee1b75e38b2d0bebbd2c025ba24e379d71cacf28de1cf3e0933268730b8c59cf9ef02ea72ad8d969250df7f8d7f233e90dd6830df0eb170b9402e831090c2c8a05e8804ba4952325b1a06ce793ed6b1020ebd867181bb165551e16045d8c58f1d888d0ee8984dbe16c0139acdcdba772818f50e1d8a8cf3ed708b47bc44859b9a065335d2e7825569018b9d383c00cfeaf3220ba2d5bc6166e1174ebb41ef2fb5407aa54c0760200bdb22e82f3e6503bfe7ce8f107ff4ee8b199ce2a4ca31c323f8c466714adb22484769f6e1877627089f4eee885e72b70275ec7edcdb264b33265873f8c7423f9f284c99e524f65dec1ed3a5e539b1b53c20ea42efb151c4c030b0545f0b3b6cbd240dade7e8c2c3f3c5874dab981d132c8887c827c63f0b8741ba9b1e248fc6b93f141b33410a3ed005a802b735df73330a581216cf6bc496c53eb63b8daa481eb5eb567e842853f2b56c2640f0538cdea68e0642b460339be5534109a68e08df961e4dc2771860632e772c9e5a4d6f96ef8dd1dd087e805f88ba01668c3d6a854214103050502e297860c3231350d34306a306ce9db94f5004aaa2957684b60ac9b179782e7b933a3b88605954edf51c1852b1c1da68e7a06aef94c374485b0979e458edd180b2beb00decf97a27db6691b973c4759cfec6c6cf23f52f6a1b16124c8b5f67304efd6a72edbee16ee760d6ad6c3169b7e3e699aec2f88a239b5f4fdfdc2fb99c9c11e344377412cf6cd27f3098ee482080a5fee3fa1746080c78aec7a0d842de9d2ff8cfcbc28c1aad415be8108601c0372226b8a2364367b89c900685224d3f045a00c3287bfcb261c3e97e62ffe977f27ae626fef12052c8d81a8faf0aba921d5d46578fd4bc1f9535243aa596badbae223f219a1dc0e1a36ce17d0c510889aaccbb46a4b678cf5b95ee0dfd6aa7dd36bad1a25f00fd8acb4fa56bbf9b3c9c02de039a7e7980cbd972a87a74a090926f63ae8f5e2fa5348baea882811be4d80728d724526e2320218d6f7c9f5375ed64ebddac4303ae2fd09049c5401998b7a744598b26c272fbd1f96f8ea69142ea06f3ee8c32fe87aa042b0fe64f069991a879ccd45b3bbd921b0457860d6ea116bd1eaa6a5ad41891aa88e4ce927f89c1757a82ab9ff53a0f7876e39efbd01c7a8eb9d7a4a61df5ed59874e12b9b6aa3a11174bc7dca274541d19004eb4ad1f3b1b4a0b92a5029e1183fdbb97d479cd9c7e78062eb6ed500d9edaefa04388f88bf742e1c7f2924914c4c3b1f95ec45a64bc7e4289dfeb62911bcb95006453c4ec56cdcefd0495077d999e64855a30c3d74a007868468f6c579f23b6763f756b4b005659823c29f0925dd52490269896e7aa8575d68d5ca5635010c4537c36c0d9970290d9f207b8dce77512e722410b7b97e6bc1631b78c62526b57fc64ccf015d0865844022c0ee1f77e51c16b6d3ae9d060f070cad2c84141af9e47801e8c4c294d3a71193397e1dc792794dc84ded4b91dd98906384acbd4634606b5f4eb98f8fbba5a9f12a92de817f10ff92ded17425a1ffa528e6eacaeb310b3d4262f98f108095d5d3bf77cfa03e6c23c8e6c9dd94615b73c9bde166757d7cc7c22a0c0a51700834f8f3aedf90b8d7182a18085d33e8c420e5944a4c515132e8bf085d629c1a9efe65a2ef29ffa8eca599d683a046d000cce616a094b94217358b4465f21493fb8a4c8c5166db9991eeb6a61c96110e4723286e331c7cc916630e7c3546569acab7f02444fa6f3e0317d00ebd5947e981d05491543660f2ca7604d23b4dcd4ffaa18f4c0ec07c9ed5cc5a50b3ebe321c3aef5c97548de440241573eb23dd8d18b9bb38b95b93d0854d29aefa79d48ea8f6dcb906ea299642257043960132230bc6d30d9ecf6f17abdce0b68e30c9aaa38c72046c8e14dfc6f5f613882a454e0b00e30513c0fb261420ce1b4fec51f468dae53df8d6613070f144e63fdc2373949834d461584672e7da29ab8de3fc60be064c6e661ddf77e9a3453befa9f9bd6dce5a0e5f1d7ca5e1b750610a5654e394b43fc31ac3368ff50c1393d540282c76b7a68eb078ec8f490c9072ec9d2438502dfe1d2d3303e334ad604c86bcda886b4494a146db00b7eac331806792917fc15ece6334897b4165b2e965e01f5d3e779e05c6ca8d9c4eeb8ce984c3814bd7fe783c650e3af843676b3d9a9a527224aaa8d9afc92aa837151af28b05ff5134252e3f3fc3a8d9f1c3e7da642801fab2da9f1b7aa940715755777299dfc7ce7bb7e0425a14c501d3e0afe9b608d775db3c652858a640ada48a7bfad97b9353e2515c5fbab5712e8adf1db1cb5f91883e5587c68c29199597cc94a7774613643dc3880b705ff1e8dc465186d9e3d1c1b9ef8eb505063a03c128f959b95f434db491b44ff7c9af0963e8654e101dda3ada4693c9d1833374545228419ac38d8100d7a8c48b317a82687816117037e74b375d23979642f4b49a64d0cc24a8e1c8a061813c7caea5e73f7c38e264cbf8c4c363e4642ce7783c64e31acbc70f36734a008ac6ef063a03c05521c53b33225581b9fa47666617dfa37252e8399ad296b5bd8572eaeae3d908e987b89efcf7e064752a9e688d189f903b7ba449b2b80064c5e69095e554ca9e7272d0f13e093c06ca5f025c62133597abfaed541c3c4302302de81cfd0e0f1438de4addfffbaf8cbdb984bcf255e647815e6a06b444330ce03706b2443516bc883aeb6318086118318f1ed1d1a663042c8e169dfb9d2dc1b0f3f904e4d0092c652931cb3751ee093b073ea65fc86aa4377c1ac0f2b67859579dca947c39ee2260d6066e9ea46a295986970fa11ec2e70eecef87115215c849e5cac6a2ce2f210004656b50fac995cde4ef6a17d6afe4fcfe5282717d80def363cbc0c06c119570a544e5cb840ba1eea5d29cf81f92eceb1d1a5236a2f34bffa89820e67cb8292ce4b4607688c864efbdfdf185817f2d62caf051a2e96a4f20202279a5bc2df8bcfd96a5493a4ba5503bf4badb4a46b18e9b492344b2bc16f8a24189f00a8244a2b84834ff9865064f012d4c3330273a61956345edb23b1b024108510d88669aebcdc53f3aed9acce81d10acb486bd1039e90e1e2000616aa0bd7c4f818e6d164c1afe7a4f3aa4e36fc8ec74622a1abbb08a7a36a83863fc613e99cd03274252cff2cd369cefe9954ba0800ca906083719bc17fd9ca1b1b433d6b1567d0139947ed649009007392679679cadd3d75551aab91ae5290e548509187caca0126c17c03f0b4460cd22b05094226cb53a573cf2bee776739c7586f75b03a46e112aea3f94e17be951b48c9e75e332b30f55127a7fc9ee24282780007cb6673ddf50f29ca1516b1679ad66013cb6d372c3d777673c6235d1cbde46982877b031b8c7c9d9aff921a52b64eae0d841d068d3cffd823e5355d8223ad21ff5d650048b4b881890b132c0c7e196efaf33f68e031243e1d6dcbe619ea71a52d3fd013c976386b6b0c59eb92aa21e74b2b856373ea2a9c41045c4ec77b9d4166266afae08b86edf7e7d9fb0835315d0d4e9ada95471a0b0d59d9d22a1e41eacc550b8371468d931f0b83c9e0d6fa2bc339489e16989eef4b042f9e2b7b93e427c60f11883de2b201df74937031068af885b5b41e56da96db59260ecaf74225eda7ed606182aa30c20522576e526591b6aff2ca2e365558ed1cff0fa589cc3f972382053feddd48a7df43f85291822e0fb8ea550a30b6302a9a3a1b1185e92edc56736ed865b511f0754231eaeed33c8471d71523d01d084596ab776de230004eb133f162922ae261c2c01f805a249d45a43493a652813d5bb23a098799558e6b08c10f61f3f2159cb856d878548c7bbdb5bb73602359d5dd73ee86c69e483d14e550460046d6487097e4e716ce6c1be0127b24cb98d3bdfaec6b2627924cfec0f1fbefe54af4b0c8068eb7cdc3088fc24abc70da698e3fc388557811ffca1541d4938b694892b0249cf6b1744651bf07379b6550e9028e505b9eaa1b9a55f2d687840d74a527e9629e0f3c3857a851d659293e335fd0b90ccb228df2d5f093888d918df4dbd7311939c593768eede5193b33741c1c15ed1c55b968bba4b97cdf0f0665664477ab70858010bf4488721a79d51f73800213a5eab727b1a629d44fc39f286edabe3ee8659cc978a985d1883d1e1b5877346a7e8b01baeb562b37717820b4576fa7c56b87ee5b35ea4378cab72f7bc6cd30c1da082d7e0655969eca73d8f73a438c2a0062a0ec5a3df78e5638cbb2d8c3f0f5a8917bcdef05b348c47f019b669d10f2f66260584f84b56bad4c2a23f9eef412a0fdff1de56970b48a9c5063c345ca023c61798038ab592dc3d52bbf8f943205016c00ce9e83c1993b49d8ca924ffbde038dbe8748761fe1695a5113015fbd9faf3939f75039189475deab113ed224ab62f9c71caca56cc306a28e9ef3b6aace1f459392b34db0485317612070bdeaab30775e1f856e9de949be4e1e34a52bd28d40429d58a8915fccd2b71ba4864c457f00c3b36ee83b2fedea0198ae9f3b8840e2a3c46b1771f7cb0c27222dd4b9a259327ef6da331cb87ef17728b9a6eb3d61d437d117578eea2b4922f3d3c162d08cc10ffd8d3ccfb0f338b89cea0fcc4154d0bead3d9d7fdc66dd401632aac8716eae910c7145c3daab59be8ded10737d23a3e42e4e73b43be61f0b06a75d013e38294ec6c204dfd53e5c9e3fbd57382750bd81604cf1bbfa3d5f382a1c9fa6229d3da5e3878067de611a44ea650177b3d05068829148fb92335ce62759d3a477f552db69122746c0d2dbc405ac25bff71e160bc766dbfba1f48c39997befd143d7ceefaf3ab1224dd91cf905bca3bad36c7bf956edda6a1c3a904e754f29d9c046ec5595b06185c6cbe01eef8af5ee058d2e9117eace85fccc8cd02017f2ec48a6a4091c4accb087343152a1320388ba3a72d932d12df94e4a1fce64ea709176ca1c0ef84c37a026198ff176eaceecd1485b9d43826083e5e8e6ca5e27b2c8f7e3513c1e48cf57ac53a9755762daaf2f20e276255677d15497e4858967178d583cdc7a4cbec1a189d9290c0cc3b21498b0d1e31be70c6931f38f1f049c48ede75fc245b533ce54fb6e40b9dd35dfb4a9b3b3e2ed89706d01e3b6fab5b4765801f9f0254666819866ed776192e808d34108c0ca4b7ab30cdcda02e7ae48bbacb6ab21e7b024bce21c3ba943de726fe1f32b6f2463e474116757c0d4122c779eefc00b0a76449d3bc1d87c918825c52fdfec4a941ae9dad6189505fa6d9217ce0a2ccf4e5ae1de44c18778c129868b40ca430a304c531593a6107c0182125b59614f90276184afc8896702266bdef7a2b3e00274591d0dab364607f4034a0a51ae4297a39662bd87be147aca538b752bfb3f873cfc60b021b25740f62ba3343ad0f561b8b1c9c0331f2a292f516b4b1fe29ae68a51a3e2ba3a9964c932c9108f0d5c9ad0872207157805c6ae7a441f9ac09fc0ec3df61e12a73147abb782e8bb07976bbd5784b8917dcb4a611d66ee57424d21e7e4d06c8753c83bbe5b7f1dde6a8b50d19dc6a530def01b01ac2bdcc67d8c54a2744fc55644e42efb0579e4ba44c9e4245a446c0e64e736a7cdb4a5f4cfa2e1263fa4fbdbf4a1c5b8f42c5fb14bce848c0dc7dce04fc5eb2c0566f9c61e398dd007cac3af52840c652235a22180166e150a779ee6f64b2fb7914d8a7d1af8557b7e45ca2102d50bc329bc43c9fdbad4dc48a0b9caa0e7f89acc54e2f227b59b9814e91f12744f0de09ed58f2c75989d2116089c42f661eb23d44eaed725dd7e3cb0a1a5718f35b40128c0a7bb83662ecfd4415024018988fce95e0a75337d7cbea5e6851ab390e6ebdea268ab6f694d5730054690f191fbe58f024331d52388c87d57a2047c5a1505ea052f1c52bc72224c09fb3c5aaf5b0b1eeac00c0e97a5bf7bd4be4f75e1af55df622ba284ab087fe3489914d5c8292f42f785e534b969fb38b093b8a4ec67144213e37b1031ce2e26d41eff833e0e6029194e8153110706ad6dab103240cbf07ef4c94881605b9d1f0c63d354cfb1cc2013bc5a66b484cd134cf721e89d8ce58a1ce0b2ede04cc6f7ca0d0113413cead62fcc05f9025884dd70e434e9f69ab4cda7ab07155d79db1a734cc2133661204f08bb1487ce80eb18c0ffa1398726d20ce505dfa75078fede3bf363087e36beb2458e1c8edff00f4000032937ad4d819672f9d9f4d89284483134120da6732490b0f5f15a83e8fac27aa3821844f30657bce3ced7b63873132d44d0d1b06b01c82104bb8f3bead1c1314528383c22f48851485fff1e3838779c8c77d0d8fd2eb7504445d5266ca456960b3cef41505db77c848b3275b79f6bf4053f21450b1f6743cbd12cd87fef1ff5ca0d6950c7237f7a3b28f36ee69f81632e7234eb415f37e4117f7a1892f439f0d9e708f3c0a31e733aa9b7fbe4bb1d069f3f83d25e0eb99a54803090a28f4ef8907800ae41ec76d6fbabb12ad4b7f139b34bfcdab0c6f546de34442683642a3ad7b4a3cce8b7b8ec6fe33dbb7fc1f15addc49a02c2b1bd77de17ff0cf14a92f93dcad6d57b38f61e2e33fa59eaaa55451c460cc7127af299955fd24fa5aef3e6e12c01c48601b4573867db0f54b04a35045c9a6c1b6d00955598cf2cf9b6feeae84a518e4fc2eb84f3071fe92d167899c7e4484557c3795b6d7044fd08874eba72645d872a6d4d192481fad55e322f569148d4b29094e018156a1f0a338a02a565a86711c06b2dc8589ac39c469546666c6789621a0d728a9fd84f65b028eebf55572a34aaef323ebb2e2bf4a3c974f3f05547a9fdaa32b5e6d4d2e1329b2ebe712432e7f481673357e3f4590cbbcc672a481b837fd787704df47fed247d13547c1b6c362ed53a8b10aafcd58bd3b87fdf89647185e570222dec82f4d8fb41c833f4a4b5850c6e42973f1bbacd5a56a1212fed5bf7baa1981235079aa37ef218828c5e76ea0551366d67a593a99a3e46425bb35db80dc66ae3ec661ab2f1004a43b540d25d39e741678ef256600a68ca256720f8a0a2e4cd34edac883d304d440d4b971ccfb9a78e0f8a8b24312d62ca6cca9d19746dea7a45a0b9a56fde5a826488193ab2bf5eafdbdf23afecb0a560a13138a6d9f28591f76af40c78ccd4162f168742c105d025eb97e70428cb35f2f1f535c586f63e6bea7cf1516482c7339b3e8a5d755c2aab182665814179618215088461cceb704ba84f1609d5e1932c8476b43bfd21ec04f0f214f7164bd0a36afb7372b002bacb7ad54701897b81ba5b81eeaaebcdc6a994f987382abfe2820e6bec68557e55c395570ce9c7484ce884fab7632dad820c959c96a745d5d44bdb0ed3ac5829821f33988e116d2dd7236410d95af9170c8b6d188a142ac7e0285b0a595d853586fdd67f3c8081f4591f3f75d35f06f1146c32c14f3fbb5bfed1169615dc28b284de4cd75df383edfb6b21997ff953e044d574f6c1bf32cee2155136da51e689920e7dbe27b47a31bc87ee7d31a53fcd29eaa436224be091b16c2e8efca9e4e98452ee5288e26713c8535ad6dca01b67ed0f70ff24476f24cf30de3ad746ec4f65ed3fdff5a3c7e4f9586064a43ba3dedfa47a54c48480c7435a4c59e04dcc5d1ca2f73c0eeb412a1088ced1d5f16c82544f262dd3c0d4c33976bb537c3094897a2b4b16f1c00b741d90e190eb584dae58d61ac7e1b591cfe029847df9fe7c391467feb604bc0657a90ef415fb4ab8d236a40e8ca5481366741e1f09af363265103458e98ca5155d968862a5a91e0faf9b04c95d7a2344ecbc17807aedf7ee3d87ce8e555acd4ca14ad07d96257fcbef712c74a88197eacd2af97062650c91c256af3b383645540ba62f02bce83ad4a8b6944f1b73e284cd41ae49a3d80f82eb94c1442385413308440407eca5aef80449ed6707957ea644099423472a2e246b19dc828c64a2eed764e257dd4829b0c5f61b24dbc008678a2e568c23c03afcbee81ade523f5e5f924261e37b7624659d9564254be7dc743b31e4479995bee305cc0cbacbcfe03fcae9f834bc39dce11c72820421ad82a8bcf83285d27255d57ceb775ca220ac48817ecbff2293315932d91d5a8427ece222479946d918313e30b34ffb92eb35ad1aa018c53266dc0e6c6742428a944bd3afa3c085ca06f5c6121be095e1a1c3d0e1e98f4d65a3450f90198729c40fedd014b6a51d9421d6fe1a2ca82854c1cbab8b614185c5233dc13b0b889bd7697a013428e0bbba2e483f0c6f72650a99e033f7fd7d62b0083972d8a19945f5c12f5a0f388023690da03473cff887957a1a3bb407c0ab3ae55f569bba5dbca904d1f98b36d462a0971b04f373b21300549d9624ca7ed83425eef377b0df63130d2928163b34d77669a8201c95a35a33446c6448fcad41e2ca78fc71228eac96a802abc5e3043723b2ad375e9ce41390bac25f518dd9381049cea5b3d9a00193b7ed479509ab342ab2c35e79f2fe17f6f4e2ebf5ffe330b03d0566c706df8e076f5779adf49ffa4009011398bfcd185d4a54f059f45254fd5344c030daf1287fde60908296b24d127e7120ccf90f8c49874a1db369f22db23a33b49f2e8d4f6af26e1e8414d2a1c362393537ca565a3ab389524196fb628492aa161121c5dd2adfec5747f6ea668af91a56afdf727bbd89dfccfa5051a99a2adfa86d8aba82f4914abc3c6678e4b084445b15523109046d193361b47da8d0f5810a25650902d41e6783d51d627316fa4c4040381d2348bca0e7669f23d7f86c261cb42cd0938c8281cb87721dd5af89ce1470f905143fefa79ead92e4acef4727feba6b413cf0df4fd08af973cddbc9e16573e4aacbc88b52358b9c4ba6b90a27bb87d275bf18b692c50479abb2b27375e36f1cbc64df966e611a2fa5ff62f04499feb459cb5e534fc71899a176c66ad45a32f3d47eb86c6bc7edbf38efd09a4e775635708f4145f47362557b7b189b2c8966247a42d7fc7d938d3e56a5f5ae0981e194de97d4e33903835e8929d362ea6c24aa1215ac84c1f0b4dac51a15489afda410a3f8e3e713f59346cb68d5fb791dd6345a41fda4b1df757671d37ab5cdcd4efd77f56b9d8a29bd43564ac79f878a587160e1659913c21d0027f08e69716ded09531100500977396c980e1d48096da4f69ed905576b0ea6cddac9587541bd6af9ede686f7009f4653732af20e5c6b2c5f293bbb46f973841fc6ca901a60cc64059ed31b74fdb24774f3cf10af660d79bc3b413f68b1b186c0a747760acad669227696a9fdcd6e0723f4677dfc6405eebaff1d869704f9f7e02eb5cb814c86d81630bd05accf8b61f002767d2dac8f67f7e8db176d0e856fd8e8812380dc4d86ba74d57a1d7285a31473fbd78d5c4c718774d18924af9bb12d24e4439be95e7f41c0301612336397b03cd21c2a72c2755888660a50f5991d97449e4c0f390c6a206e349d264b450fa01a3f8591f5ba58626585f781de31ed105adb130ac809c498e1ed31b9921cd4b3646175240e50ba88f48f76652710cfb194da8c11d5a4bac89a7e14f2d74174d25a18eac354c698e532dce52dcb48e3c021adb7dbdef8d43758fd7c963a09cebeead004b029020b4aa9ebd223cce76738925f3844819f56408c461955a0f497a082d82a5ed8fa65e0afabc370c7bc831b864fbcceffb1edda4da0016258228bb07b2d058daff665dd4b443066228ec270594e60f906464eb3ea03261acad145c31364702a1c460104c2021a92a1525b3092aa9a0e2d5e869c604bc6be1119673ead7c816061e046f9040e44cfb435ee873e6f490c1bc6dd1736b203f0dfd902dcd218886331cc4b0d416ba6b3d24ecafe8006d361f2d0fdf3fa9b74e2a61361166b6defbda59452269964080524051a0532d6f2e0defadaa6fd6b9be52ca987f67db29123c98548c5041e6053fe6ea492e324372757c3a385a384244d4ec89bd23bec5731b2a4df47b120d7d1abe58412dc942b30e2492c0645aec0903e4ca11f7ea03f74457da6f40dbd418ce904ed9944b3f5f298f9c48c621e4d98c7cc5834f2e18915312aad28703812a2c05c3fd15010114d209c1f10499a27a20d145186fead1c88367e4343072211500dd4ad7141585001dd7030bba6ba36d99bb8c0e20638adcc881574109dddabddd72e6aa6c68cda849412c412c70078c09f6ce1a0a0d5ab1882f7e303c9fe66bf655d83dae364817b70962b1e404dae4ca0d62e68b0877a090fd1c6738c315e793f47010a0840005a5a4ea798180420203f0055adb53a7c80595467dcfa36cb6edfee6b75dc2bdb90bbe3c08103c74479e6a2400cc653bfe2a05e3b0aec90903f1c9dce1029a5095aad96a7382939f796b736cebb47c825b064ef3a4a94f122ca48691fc4b0c598b5a3fc004d9fa62e70249849cf3b11691a26bd2062aa638d46f498dc156023724653efa4138c367e2fc626d3bfe7812ded3577d74ede72d7b35ce0488270af51cb5b33bf11949892170c4c46f621cb1fc207247c08228e88ad0413dbb6514a722451c655c084fb80e405dec4c984329b4c412203fc792bba1511cae6dba6bdbbbb4f27eeeeeebe693d9dcc70164d27dddd0d4e348afa49f4da8ddcdd24d49222ba153942c9344deb568b841e17104f8000a2a9ab628b08b72d6ad2b2ddfb34e188b3bfe725aacac09f2957aad3deedd6566aedcdb239e7edc1284f61196d243e82e511dc73eb1c8f4a2196906354a18a9803ef7478303990c09f71e4ff88400c94e410c4134c7e94183992833494f0e24995263b50c99e71125880234a260cec5e5dc7a532846f7ac41dd2c64794999b8f1d2323520b9702dcc6b3d3c46807c90ab08d1712d2dd9700f2215e89091912c21293690e63110205fe1aa83b49a4b304f1e6044914f183ccdbb65a6ddbcf6afbd9b69f9f86c18036a00de8c379e62d2e43caeeee46f9bd18ffa350118542997050ab5e80638e912c1b33c596b0980c790440fe9ef4c2d7b94156107681a186ce39ace80a5263fed7b556e78ab61cfa46603cbecefcf8feb19f7644e27707e344dc88caf4d384c2f981aa913d189a52ced948f026adb51dd4f50034cfffcd0046b83eada48c43dde5380cc201c76ced47d59c6f1fc87cdb153942a73efd22b448fd62ab07cc03eccf076281d48e87760dc4442be2786afef55ec26a263d643299febd9a660919c2138447ca8d89989e73d248c1ddddee5e4d265694dea49400934963eeee76f2ed9df3de396fb70e14b80dddd7e5361e4f71dd95dde1e81b2f297bff18731944a3537a43788244303e13787276707ebca4946a2740f9bd189b4ca81e9e21a6ccf37abd5e37501cfa66fefdc94866571105085bd048819bf20c39c55cffd33dd13c5faf5773ff4284e773ffdaa5cfcd93d63be42b000adcdd4719f971d3684f467b3ed31673cddfc300e3c27cfaf4f10b05690f5d1d49af07edbeaf617906bf7285e3714096e73492de0c7e85ae6030daf3a89af724edc181f6f8385dd19e68d3b028235b0871074d5781f5941c635186fad015ed915e37a94d695b3ba725cd690308b3a4da09235762b266272408eb28f4977c64fa7b3b98ec118024d53ff29ebad9ac39e757c34ffdaf7f6cacb5d25bff4f304296b7ac59fff3ef9437bbf766d77edb0692298da6f68f4cb5aaee18416441fa38f12417638c479186eeb4ae5918efe0fc781720f0d72cd6cb0e1feed974cfd1d931daa942bf493ee6cf094cb0acb4524b6b6d29e5d0c5d7d67bafcd174db06612168bc562b1e8ac73ce592b8bd537720a131758dca06b1a8607dcdd05969f89cebac635a170c4a273488d0e610f0e8e0c01f258cc81dcdd6f666d76adb53a50332c16c9080441100441d0bbef81e0052f78c10bb2686c80e7ab8868dd97fc79bd0292de8fac59566230980d22b640b067058be56bc59386526d05c114785ef398d3da9f8fc7509fb4326aa88146926622098bc2095a6bad066ed94f89871705d640500335d0ab610d3d951d6547989aeedbaf51dc02790d85748ced6c0f01f2092cc0d9942e7a8cfc138ac09bacaf6a242798599e0e0dd49068e0cb6bf737d5580d3d66071c55d914e9d5b0c50bfc6553b413800059263cc13a413b41e93388094e10c7a816f1e0a142c883070f1e13f45454110905b15a393584825b68cab4a0253d6e53412b9b2269282b77b7630a6cc45de14b4f760debab86d5c85b32489e90829e600bae12bc0450a50115597eb6caf2e512602d3ae109fc45589ea0bbab77c89f44c04057dd22d62ca2277f829eaa5dc41859c32322c2c022ca48dbd3025d1304dd95134a2973c210c70f6a0d431f42a13cefdd9ba1a76ed8f57ef8622daaf8c04065038b104d54a4e7ba3b3bda8551248d51b4711cffda856117b686c814e46fb5d6186dfa7ef62731463e14e9dec67296d52a973f2f5b951bfd80c3fbf54e8eeb605ee07ebe0fae8bd2dbaaf6533b0991de8b2569a667aceba3434c512084f115c697f4f0e5a115973b69e22cc04ff3e7959ef43aa52e7b52a793bdcc600822835b9e1ffcf2949120b210d2e20455d6284212558f229e080334638ca198cac808a66891640c28d0e002062a10b07000228908a40c2154c9c769b564ebda30b421840a3d2cb9f75e7b6bbdb6d6aa03f57abdf00d27b4f0e7e55829adb56937ed628cd7ced0b649a9651b951fbba78746a3c94202a0c0dbc74dd977f453f7ccd0007f35d9d65803ab793112021b42c44a6bd976dfe4a99a1a9295994caba9a18a96907b8fd1e6be719244922412d7e544199d9d979e1eae5982a0b2d2ddd78639358c1a0e306dbcbd04b2e0a04103c510f8eba0c630581bc1726c7c64f9926c29724411ee59bec8f6252637fce581b8fc0d977f71e1be057359b44277c03173bf4589126dbc060f7ca06fb46c461b1de28d8cd23ba400711f551dcc035c7e7b202fcf7545f0bffcd6bd7c919677f9a8721f3653919919126625cb2951fa0608597e1a525a1eff27997c116d74b867799ded4b6f493144958dc72718db72e21e3f90ed6f6c8fb72fc2f2409e7ae960ecbfb8e07779202dffd215297dcbbb94bea593402c8fbba8f2ee01dcb33c9023745abef4d1816c5f2a7d0c5155ea70a933b97c4b773d86e53136ba52cbb7d8f81617cc42727996222edd8fff6a6c743b2eccd2790f9397644275626091419e62e974581e3fee88909e65633945951c0a723924bd5c2a010926e52f5a99400e57aea8881851b1b090bef411268652d7afee7accfce831f3b3c09f048a568e608268e015adc060309869fb0ef2d4f6460108404b0b025e4724288180324dd3509924e18718739cbe550e49d34e6a21e6ea0cd8410f0668811be8477a9f915cb3ed151778befd1caf63c6947dd124ba7b4c85a08a264cc490820a21aaa8fa4d31654404433c31452c0553b470a2ffc66e77fdc8824aa452777bd4b4707e5060d6484f074ad3b6edd6dcbab805333014398663801773922693124331644b4afe389b34b07f7b17060f1e0d88bf18f2408ddc230dfce1d8fc645fe2b4f62db4f6bebd9feed3d35703f524cd7df96d1ffe33d25b3bdaf704a363933ca1838a88ed826c2450599d3b45753b23aa8d72b6470e4f10f88b31b7827a3274101e9c56abd54466937acceb31d6b265cb96ed0d91da1a30d890c33609934efad4808d749f0b27b54a949136db9c7036e6247139d2ad60ae01710a5743d25497a7b08ba7b89fe13761fd7ab9409a98e0a1bbe448962deff21cc96131db78fcddc1bc49729809aa77404a4fea5abef440589ef4a4ae88cbb3bc9ce2b57e4b55c7756e3c8c93be888de71e08e947f811ba22f849374e18dff9f2e2f21929c7a7a5f31849a7a57b9de831f82d29c7c7c6e3af248701491c23f5c8f199ab1e1e30fe96f795a76e48313a55041753105afac05fe8017f1ee26f213df772171befd2c9b77192411eeb60fc08d88f03f9ca09aecf52fa92f7967482a14f3b8f2a9c1260d209e531351145dfaf066bd8b639ac0acc93c01cec56d9fbd57ae5e702e34c0586c2d0d7185328a594524a279d5dffc41831ad95b6b4b4bc5e15a64901f80084154f7c603fb0dae9842309d5f5d303209ba09d5ad5271f31e7a054b6fb2cbd87a303cc13d610318203155684aaec8958e0894a7e0370742e8e245437ebe21a4c9a1052655d54c9ceb456ea51f5f54afb38a972446543d760882dc250dd2ccbee7f02c8b16f240db27c55a74c37a82cc814a4f723c71df21940820cf0b7c20a7d6332b97bcb3a716d96654ef0178d6a2683d4a1b9b687083d40a3bddbbb4dda165bccd19d6443a1b456eb6b57001f9c122263fae50f757a0a223de9f5b32034254a94afc1af410a822ead0d288dc562b158cc63b176a7b1582c36a934652d85d10b562a2259276dc87a50652520a122a2754051a6603f93401f04060a0a0aa2bed303c46bae0e320dd208217ea417eb3c16656411d9fb0df89340abd4f7fc649d5c22a71a3d78f6784c7a289c81fd85c0932e99424157f0e7318f553a3ffa8cc74cb158c805a18772e49039729472b4c1aca1bf02f12988c7e4c861f31715a8240001efd4dc5674bd66e6b13bbcb22f7e70f4baaffb22a24764aa5d442d2a4444946a9853a08f8ac08c9a49148b88828858442051ec75f43aea9bad267ff53582c9c67fdf82ebcbe735857a87c3602f5d6c853bd04a8964462c0b724529723971b58bfacb53f7f5baf1ce4eb2eaeb871b376edce8eaab1ad52845af2d8a5eafd7ebf57ad5577d652f17598a22bc0285f23cfc23f4dc501a0c325c4991cfe93e8b3cfc21f3178fc25974afbb87e10cb52fe28cf4e48f14c6c0dfcc4cfb9052d6d09f9ef36adbb66d9d7692a0c7c8df066005df283f76966559a366a8193c8c5a5174f79095ad567c516a2d0b24f8db97cd89a98d8adc3f24a0756f626a080a311569e8f7a362e9dbb27c70b76eeb5a0fdba8e5b22ce42f366971bf753039dcf630407e04294ae4400691233e20254cc152e1a0824f4b6583ef10aab6dfc04b2e62eb8afcb7ef10aa48cffd87a1903ace89394468132202d6444c86ba85ba857cce3993835f31be876a14eaff9a7e4a37d3368e643261fc52155f7a7cbc07c68508cbee2712aec0440e2084991d60faeeee35359da5f1f3ff7f7384e338aec7f49fa0ff38c79d72c05e698cb1da58a3b5d1de5a63be2577fbb4df6990beb93d363d441b2110f8faae9f5b6cf9e39a544b3992ecfbc959c8fe33c05cb06444193386f020c1535a6232994c586093c964aad7da7bad459950f405240067a450412889a3a3201c77c41d7133c88c18f88b4799cb5fb3522f8fbc238e23b5d06faf069c98b901fe1ec72b7d149e56f7ead62d6a26e728c876062b8991d1ce8e911196f36659b66353033cff33cd6ba3670132f171a43c6580ce5f21cf9f9d9452ce12be842cbf8405d052964f032e65f92513e40926fe67c30df904133b178ce4cf88fcade3fbc793cf53e71756c8f26988ad1c3b181756c8f257c8b29b57f2e6b2e3745ab24f6c94beff562f977153d2e4a8e309eecf5c33c1870926682de03c43c35af83c43bff2fdbe697983fc489596e8a40ea0afbd4f8d34ff9e169023e9051f0bc8b79b6101f9b6267d963a20f307eadbf9f4bd762fd06e76528c9a04e5fa2cdb7725d75f5fc9f74aceba6f18ea374baeddf4c1926737034bee19784a3c259e124f491bd1dd52c62851339d7570f8ce798a4f6ba24c25cd39e7fcbc2cb13c5d4e9eeedd2e17b304c79e3d784a3c2505f82103db7cfa40fa635724163942a7482cc3a34b122cbf5920506ed9ef9dec01eec762f8152f65ccb9f463726e6be59cd39970b95c3f2e4e7237eb148080bf761d491fa9c60a659871c3a377b4b554300ba947c3721fb5cbc5ea0e5d3d74a5968a930e5dd2b340bc40a4a1a9ee913f68fcbc68fdc94202fdc89f564b7b1e28af24c6b5d7ed8f682373f63927b5c2e5ba55e0a0955cb974499794b25d3228282868896b763e9e922b39420e343e7dc2b4e0394619ef605ca06166e7b2771a30659f3d67cfd938a4d0102008deac04b829b5f6befc0a586047c2ca9047c03b0414d241498f10475c45462118de4ac390d69d90ca2bdc098d428ddb368edb362e5efb2a9d418229b0b5d6dad83aa8845784e1d0cf9c73ce299d7414980565162037186498500002b7db2e729793262cd6640016b8bb270c5c6cbc441997eee50566e305c66d9aa575becc79cadf0b6e27bd5243a6300e346e58e81d927bb92207d9b5434141b4deb48f8b8d5597bf17d20b5ec5196134118325aca45114ab08a1080a1654906028062587490fffd72da5524b4b77975a30cba99144cff35848a3c98f36c32543ce8cebc84b29182afad1292afae6fe07573be7733a59ee34220d119c846db46ad87f7dc6abf4f8949da210f0d7797eb75aaeedaa116d62dff4111dfa280caefbfa072cbac8628b2dc3f102c7528e26f0d760172df899f98b452d8f1f484bf738327b232a99754654d7638070e76ff9224c5de089b3d73a1817ee8c949e7c6fd6c1a066505c8cf18e3bfc85f5750c74a28dd4a9b6ef506bc885780a3f0eaea9699d6a260e4274779fb1d7fa7d9162abdf39632b4e4a35ead756aaf558964d8242799e8947e36296e0ed775a70765ed6da2c3b5ae5db4462884318452a1b4c54ca50919eb544d234d831f23f4f16784dacc90289c27649afbef65b3d753859d2931f435f1c9cbf9f41b126dab4a965ef43fbab9dea77bb88629226557faa7003debaaf8b3c8a173155ab98ac269aac269aac269a2ca2c9ea265be0afc1997dff24c1d02de9dd26129a4433086727cb31d46b915421d45282049c45c4d982a924c6c8c99a4455cc255a930548661865b2b844130911914f24b56a9aa6b3c362b16e8c6102161887fe11d2d666d91ad8e6ef45ce007be9b2e7350e5e0a3dc0f265e07e0821e225014a61a525d7f871ca5e3b655d9d2e68d9fb9dcafb38d26be8f6da6b0f2604b605fd8025dab6f75a6bb3cc5a6bb34c6b7bedb5d6da5b6fbdd65a7bebadd7da39e73475a5d7ee40ed68b9b66e18c6418da966b55aad1a3bfe97aa551638b07286ca86bb8aa23a62450024aaaf590de49e6528ecf9670c5469058932f2513ee0f9a68c3d155514c6671763fe89d28b471ac8bac9aa819ac0ab6b7d5c3e8eef4c0e298d23f863a5b5d69ac5de41a30ccaa36a4889f2a19ae8a8644eb96cead0880000000043150000180c080542a160402c1c146bebf80114800b57743c7c663e17c9e39128ca811404310c649c318000428031c020648caa06004dd2a06a464ac8f09b600647f1e9e9cf64055dc0d0005d015b46ae3c67371f197713bfdfb05b2ae8649dbdee9ccd09355bd45384ce990d40c14f2679beddccf3ed39fa1bb737c67281451317d3abbea901d061bf32ffadfafe3347f1d7bf6b1d1a1bdf05678c7c1e17ee736d754aa5a0c15a3a0497f9b0a2b2d72ddda82fd93929405d8d25353d1180db27c74105ef11e97e799336f38e2badf413d28d66855ee92cf8a00d2e2be65863c0c3b95e1b9908e9304def6febdf7d0268ff86ceddca7bc0cb0112ceada910b5f2797d35a2c51f129a87d83b9fa422f51e53a732f314a7ffc2db517feb7459b8da100b46486a4a0f3df000ed9efa7f6c2e8ed278f8e5df97d249eb5df9b0ef8b80af8b500d07efda5bcde292b770f5ae6cec9733567c274371df7bd82654bdbb7c739bf334dc09bf1f510cafaa66d7593c681ceed6e9b78d2829e340def324bdd3022593f0c038759d8532726532a153afd8b1ace34db2492e261623740911a6bf8ef00820db976356254a9becf54ddee116ba29c4ea3ecae9113a78fb249279b9d5c11905bc82b4f10160ed164ea04e48e183ea6e78c9a83f040bd8526ba894b92e2da274b92becf0088e7cff7802a8cc4db884181da2e48c863957ae3a52eeceec8ac33376733c68ba646adf64753c97bfc49690f22904876a6bcad3e01dd26c5b709b538df215eb30902e827d47e9cbdddf109bab7b25ff7bbd5cb5af2652bd9359fee57abd9a62bb65accf31be6a7ab3c06c6478cd078e81e3df635f7c72cfc0bb264defbfb403c41594d4205752b84f5297155f0b400e79403b017d8ffb0d5c228c2a7edee8e180508c9d875148f449b61f08815171554b1668cf80596f6b01398a4ee8d2f3d7993981ee27266494aed7801e07bfc4110a2a5cebf896c5185b82a0016919e01e650205e6980edbb1e04e0b6357125ee147831d4f2948025838fe399430ee86dfa4d345d0eac3c51eeb291d8f7baf47515f80b7324e16e9667c420804a3734b1c7859e505858addc6748cf239124b9771d464f56835d630239cfd6688cb9321266d31206041b986a3eab11dca8cdd8963f5d23a60738cfd50b0573dc8a9d0358f35880f35b50a87cc1c27f1e7f9a9fd84c406555e86d029569d5935c865baa0e1fb9690f431248c7449dc2bd5c7bf6ec921b45e7f4c9b2caf1b9917a53318db3469535018233cc54d51a66c07c9c7f1e75159c5e39ebea7bfe67539c8c6ffb6435f0c73f5eafc7ba5e3703fdaa8383670cf9f2daced5da8b39d2915e4f7a233b8e7217f2523063bb659d9348c408372b815e7b3ffe48b405166fb9fd6f636aec7feab6249a73527e2e230b3614b2c693ae22623cc8a4f4a109e21d9712e4488b3c36db2f7e70bb1fb1f90c2c5f87645097029352ec94867fb3244c7805a2c36ea410816e299ddf6922594964ca6810ee2aff7176279c50360422f91b0a5563c7933c7d9e6a12e8398c6a7efda93962ad7d305053aa413c354769b668762fc532f89e95413d65ab9aa7f5d5b14a75786677e32894bf169f98645f531df36c534a9c259990ad0cfaa2f29041414d2fc90f26e44455c4201ab8c3f7057120b1e216add59e1f33306448298fbeb39d1fbde3876d5b2a60fa447c1b0a65da9f2aa38ad5066a015759013236c2f162a7a6835851d8ad0f47c670327056ec36ec8e1ff095fb9ab11c0265dff2765ca5a6a2f858a37a660d7f55c5fb42a3a0ef8463ea5e6ecf66b68e2d1e3e60615180b89805f7589cb15d04026f8d1b7e727ae579c690022ba6e0525017e3ebf07c4afcef3ee0c9576b91e6ed0a93a0e3f8e423971c29d66fbae4a09bdd28fe6d1b6494381dbc414056c32add70a552694337a7b48536311f24dc35bf6226f2f03a148e5f325e218f166847a913f7a2f9626bae819a6b3077c914e26f6eeba0b4c5d1e3ae25cb91ec1a431cfb1683304d1c5049aaac9ad047f359d2f52268a3e5c41e3e206790bbbf70ccc01af1dd4f58452ad6c2ee73191090d0d6de3c59da18a11e84bcbcd27c6249a07360b18acffc0b58cb4f14bc343a82da3426b3fc9ef0aee02067aa2e07be3d47767c588882fae8b1047c2520258bb3df6c48a51c6de904a3e335afbec94b96e7b174848d01236a07505111b1c0fb5dc9e161e9c9220ede0852bd773968905abf80265f368f3b9ebe813cd3bb5a721308035993e3ee246ca5c7d76197feb5f771bc0e74dcac982ca1dfcd8e5c05cf9325a2308edca7a37d7150a6b359b0f84935b05f9a43646c9130db850e8b1ba19f23283b8f6ea3e408560a3a252c935f1ccc578f692b468bef7df18d3575432603b07a6ff962f03e1a8339b8c8cbb0e24eb6761bb2d23302bef047e1774cb33aac4ea3d29b69ac59c739c75768302ff62e69a4447b4699adf6934b873f80ec9d035e8f723125ab7b47c793d97ef4850cfa82f6cee595a2b39e58b61660c429ac75babeb776ad129469b06e824e119a686c08626c4c4f1cc1f4a9410127bd55f9913c26e2ca2a596e82c39f71c102dbc55b96bfdea1c2026bbda5af917afe8d2aceab72b1e4a209ba130b5ec65090745e3d5e66dcb9038ebec4162607b859f6d4f287259beab3f1c770b928e0fe9bf75e871502083db3555af6377ba243786fb5bb47facec39bccc74044ff29e6aba91e31572ca5d72ea4fcd148712eb7a74b793464e40a25971ee6029f569528646d83ff0e7ea1806f0000c8f3483ce2890c772d68885d8f10be6644eb2c0f3e2333d444438789f51cb444ca441f15d5872aa2122bffd65bda15ed204adc0ff8141dbb65648a9f59269fa11b7893cbb4fd40f400473c033550d138c13790781a5b17867941dd7258dfc31b550f514a742cc36235c6386715426f6f13dd82e68232bc6dbe8815683326baa3dc18d01deb0987b7d4920b366f53ad6661a6eb001632bd525455678c5046d03eecd3a85197cda8a9fbb1888718e191bc130a7c110a64b48920bba234842486ec5a592ed9e7788c25f877c9a95f336148a180aa0108ff36c2faaadf00b83f83b9625c096a9c12f6c098b0653991f5edb76fdbf2f5c4dddf9db6f170e7dcd3beb674c195f9ff7f993cc24d286b4eafabe90b5c80b2c66ca371640d969f544de58bcc0a499c5a6e60a908131fe08f3485408db87b90281787190a5faaaa234d5c5d90453515f5d5787a21ea00f5aada7a4b828aaa9a08f335f110ff80046489e26aa7564365d6853119dc7cac47386fa73d2a82c2e92806ae20697fd527d85229c17d458154f0f2d5a4ec292b5a546bc8dce030832069df8fd0ba412691fd9de1f5bbd4a896952409ee8048250747a1f0f13fbb3bb534d4c6c31c6a4f11a484535f75aa999c52983f8ca3cb9210c2edf27323793d4964ea3c69e0790e5aeb36360111f37f7c59df5ef35eb0dc350232f9b56486c8f5698b989eefa13897f35f8af273e5e3ba76e97017cad68c8588eb615c3de6cb878626a9d623f5ddfb3cab2029fc49d0cab7cf1f92aff1ea4951f92295ea31dec8b159d15bdf23b0a2dff98aaa749a319c9fe8c75e28152ac5bbbcc008aaae2e9a49a7f88e3748de35981402bf17b2e9566ecdfe90daef8d859a1557c0038205e1ddb509ad644fdce43a8c16bdb6cf07ad115a2ff7df061b32f44ec18ae171150bc797f97b637464bcc1c0f5cd6a0ad89f17eaff800ce6d62f6db30613593412765074804e20ba0f3693b755b0ee2a34b4f0ec3f15188530bd6caed46be020340003b8b09f254ad3cf149c31171ef685971db3dd13219dcb1142e3b2885285194cb1fa8e8f1ea1c28fcd90388029afbf7daff210c4d977b1a93aa31b05ddb3663c1c57eabb247d734c6e8c36e542ab26f53bbb07e180416f7081809509bf119313c49bc8d1ec5b2127f709e524d32d9802b862832bac21e69705b74c62e1675ca2493064e9807f7d11bc8d354ebe8e872a69ef59839b88a78bbf9713de070c73394c2be95577ae90643565d5d4cb8cd7d62b460739b56d079fbf74fb88b1e5ba5d816095a7f8c9c835f7a9996ece9f007af1d8e987c3cffe987dc4bb6ce996f10178a53fb411bb3b84110ed9f218c9a710ebc500518953d2ee39f4ad5e55a8a8b3b03ab65ec708894939a71e938b5dede6cbc285bd8f3ed545f55a32d5a0c777beac0adc2005360e4a64539682fea539b434becbf22523d5f93e96280952f0061af012401d306375f2487f9e5d5ff0d08d95b1510ed7a54fb857f45cf1b7088e903e6da0800cf22c91aebad16ea57a72e0d5801fd8ea9ab97eee9dbc29589d719042981497179835fdbedda8d48f3555736eda9e9835ca459e76045231a40a12987f178f2604742739a9612eef280cd88001437fcf38386240a3653e6aafa36690195e64a8b1769d19030d5490ec2064d0d568221398b2318ae8e0ba7e08676ca7767840c4b997ea038a5c3db2c8226a0fa74f1c143bbd4dc7c985c9eb105acb599d53d8e5714fd7d8663e4f7d293dd77489526a0c51c92aa2d48d5c95994f06704a7494865bdd30137219d6f3e142128c614bb5250a1a6e978c9a17f0a791cc2146c98e2faae696a3368da673ace54b5c14c3a64b71b8b37b25b1f095f5f873fbd8b4f5baafead88a6ef90e121bd0f385ab5c3afd1f1c17989951ba516865334ae31d48fa0bc0fd46522386f32b095a331ce9bf0d86195cf01e198e0cf3048a8e5ad105d982aa35dd5653c17e3d765181fb9e2cb3a48023a7ff4494d16272190ab8d70f9f3a817f5bb5fa3de8402ae6fbfaeb169096a176abaa247fadcce0b0b9156525f1ed9f3be7f6965ec41eecbd725fef8517b578c0f3dd85d51fe9c630013a1403eaada46add7cb00231a3a5c14bab5ef56fa0b1615d0a40af6f8b2571f7d6d3992d98dfbe23a9fa1688e65b0ee567360376ec7af76e3638f78050f5e5c339b807677fff8b11e5781040f929c28a8bd7a0c7868eb91810686503f12b20d4eae34ddc146ec590d9587858d61a0d918355cbab462ba1b6542bd3733e488113e11b1ff7b78d9b2c6ec2e79c70c86c945e6b147cca3f02ca27e107f6fe07840c5dfa0d9c077a8b0eb2df7b464efd00fddfa9e8e6f3927c7323beb1b59693297b13e96744679ac3a5f643ebd0917e03f2760f800f410b1f62b3bd0fa93342694d9cd2024d9c58bf88b44b695270246b550ff1633b88714d116e299f72488e0c2e820cd760b16e813849a2dee3c91ed8e63000968880f92190ad3cd21629d69d6b7281ac531cd0773d6f8fe305a863d686460c614cdfa869a6dbaae3fb213d0890c734c12918f1f191e35d18cc47f7181233695f77243ea5f58d849f85351d8601c02c151470fe4c24d36ae0879c261b1cd69f24160076a3fd27ae22c85c4666adf4eb92064ac21438a322c9187babe0b104194459991b32f31399726c70ad4ff843347725d4820e9e4c3e44233c125758d197b42f6ad570b031ed1edd5ee5f0066a858331d860d11d6adaf418fbca53cd006f764db1efa64df86d9d7df518e87dfb9aee4ef26df801b51de6f5496bd3e38f97e33a8526118e43412921d8057dd88e6bc605bfa8fe57f9cc7867c87cfb769379af05b3a6d647a90b79f226b295fdcc81748b58fcc3365afe84653c3e3ffc2e9c2bb83e9cd087ad2d176e902a182a7c272affe8427ba5a3f65ceee1fffffd99c5816f08aa09daeec8e04fe38bcec1b767f9e76705b4f2be162eac1d9eadb3bf79f4747d894a4835a60200f7e0c2089f82e4ad143e1b1b35bf8869489155922e0105ef09874500457c8cf9aac27362726f50303a973d6ca5ce130e5a736f687c0c8eff5762805d74d684f1fed297676c40fe4eea725d6557febfad6132dcd2f5131a30ae836778013a945b204111a591403ef441104b21658efef2783b63a97f9ee956a83a2b4e05d121b6cb2a51df89c9c30175b5c381a80701b3cd4c132eff21896186b3febc11408e175097e868d7ce77de2e6de1d65e9015da6147a720a6f81ffa1fbf46940005439e151a07c69d91524a8ff811d80da68781d519e84a938aa5dd00aad1e705f0767b7a519cdbbca23f5f1a998b5f52dd10b09e682d37e63c9525b90d694902535d1183f36b769e076488e35f71d1707c2976b136a73857546ebbd134e498028d52a4c550ad0a716c42afb2056181dba661b8970146e7e9279f5011e3f902817209825f4565ebd96efebd7e9f7881172623bf3c8b3e2fb67055c59fd90083f5fd83e9af4af3b9e87e6466d0e791cd85de941bfb0d3772b29fbe1fc53da8854bb519eb723523d46f9502252afc0b7808f949e0865daa16414d9bfd16ef7a950dad30a900c6a11d0a3a6de023d8f9516ee95450e64f697675dd63e77573b87c34d3e3ee32555414ee2fb1bf2876d72492bc33b50fdd353efe9259faddddac930f0f31c8c40f485eaf26b796b5775cb699cd82937cc38853bb28873e7b6ee9212b056aafa409d3d1b2d20049eee5eb2e5912f155e0de8bbecd2cacb3a5c8d54546edaced48803735b43318771a2e0fee4a6e5417d58e5abd7009080f3a3a71cf4114ff81da1dd43382f105ed70c94140912e6148c10b62a7bdff0eb7d75a4ca2b1827ee23178ee0532b5b253d72e5547c1b91bcfca995d43f84a4b6411ebebcbfe3ad64ab52da6bd1d469521eddfb2453f599aad88e446fe26ca575c705aa5560a5a68cadee9aaeadefe1e27b49a9b4c91d54aeeebd899b9d36a6b064ebc70f3a39dc5b8d432c883013a7d242d0970bf026509f98e6e4b61e154b35ab4d9bd4afbc780801da8aa61bcb56e4272d5dd6955c468b244e553b3c8db807be55b6b795f33168f11bbbf0a6c26dab56a7ba82edb7a3d10371d05c45b6162b28ecc0bab78e732865c683399d451d2eaaf402587ed92d2b0b184e4dcf02e6d9f5ec53da8129d6ee8ede12ee17ec71254293e65ab31771f3ecc0cdc037ec41ca24bae3f4a071c2847f8b827705aabdca581ccb608778ad1a0771059763af6e9e133d21040c27059c7af7f025a5362cc390eaecb3ca5dd649e2ade2eec6eb0ab207f86d880543cb179baf3c7a15bd3d33fbfa6bf2e278ee87ab9c9af06bd54e218e081ed46a0941a19b700a9aeceb4f304bf7fa16e3cd26f71abf8295e2aea2fe3801e749625e5ec94e6986b9342881edf289e3d23bce2939e6d9b8ce55bcaedca0ad487023ac05d836f956091f8e2406039fc69fc23a19f1d9d12ade15fc0af48e88f4f85dccf79f4568f62d379de52140ca69f5467d98badb363288b1bebfd42013a35c392ddfced735c9cfb4ce93c9071c934741797b73faa6bbd48d98c44bf5ef09f026a8c9a2090ca9cc1ec2847f5f40b9bcfc35ec9386cd9cf997d742593736f3b0810a74825b205be90eb6a399563fb608ff8b6653ffd5ea8cd7bd4c72d027d7685c3c108d4a3e1c7895955bfc98ab1744f106ec7d1626ec75b2fabf0e5febca3fad46003aa4394e98d1a88836b6141b321dd59143078a662bc6a37e38f080570cc5f340002e32448640070e8c74268831a8bbc8877b23000ee3afb3e142833f5fa4d16624f4de1e20111d782ede2c7fca8d08699cefff001e439e5b9dd7e57c596e2d3771f8d3d08a205b95e415662f86885d38f648339c920cf5b5f452ecd3424aebed66bdb856edbff4f398aaa39deb4c92976a826f8bcc4ffa6dd4384fe1bcc28a07f8cb3fe5725fe283a853944a52db6cdab26e07e0a6e33064cd4c2a0096e776a92009c91335161c7c1cf1a1856e91a4b1b5b26775adb4ae1b829f1966aeff7113b693e3a8f21448f4b2776ad9a1ae92c2a3ff75f704747b9a14ac0bf6ea3f998edff902215cd816d2a3e921ac9a465747645a3655dc0df91788f3189514d344c7a6c6c889653ac8bb9bc8412634d5537d2de3048844e326126c1bef4666fb683e50902075257c86213b36a8714e66023ce93249012d0bee5560a2f9f54a5dd8a275209ff06d042f1f208b7019fb004ead3381605040e19837917c633abf5cf31f661aaefa2500b06d62e68db36400a755c95b5a38f9795683478049632eb6afb1b52084c4cf61088b8c5513025be5601b11042afae5a4bdfb3c9a11d046868b107917c54a1f0859ff17829ce15d72a16563d1bc4b04b9875508730987dfb286d012d85c2b9962baa776b2819739d3f583e73b35cfa93f09a5bb2425b393259b109fe9e171c9c828f7b85e276733738b6db9c850e4fe20eb8c5294ea13298a9bc0b535b571487812c23a9fbcb2d224c6bc4fa790446ec6a33b8a25e18df9dbcef69f4c6c6f7151997b23fd5e8cb7696f9ff06e0fa2b476e98d929ad5b1d358a26f407a57a8aca3fb08273b7cfdca688c0f789c38175d18956dee9837d7d4ea3a06d427dd6129ef198ceeb0e51ec96c69c1a1e91349878d264f8217f2b11616620112b83983f915bbf6fa2640bf86c9971c6f485f33f5f9a7b39c9adedd2cb083e68eaa1ad3c83bf3ba70e268f5cd48b329c48d2be9b7be96533c5dc47a948c17b0cc318e4370182032580474de18ea4d21162bb20cc1ef62c41660f3040bd5c9253ac5c8e1a82d64d93522de0ff1acdc9ca41f03b3b41fd2f660779a9b8a9e86909dc9d5857e718227765ab0d205100ff3ace0ffcf7cfbabaa7cef6dede322f06deceb08aee6d38eddcf9fd1ad0ef293e6a666fc1fcffa555d4bd7933039671026363286f0ea20177a2a851c52bc13e3eec3fa7b05472dde8c5a664edca0c24facac9d9db29a495ed6885a8d05843a601d2b8f63068c2520ff320033abb0f340563580ae4ba29127e91691ba22eee76dd3c5517650dcc7ee7daa33aa397c55b076f4510d20c6c3d2b4e8003bfd862f00c5c96ed5887f23fd734b1b1e8d69d3fdf3fe5cd7a9a53ed95db2defa8120351cb688aeb33abbac7bcbbfa5c7aca98a71f629377c0038a8455b1f89759ea50bbb997311e4b130c1cf04fb3de6900e106da97927221a01b7c94c90dd14407463d71f0a2203f6f99f2a5eafd6d50cd8e14200b02ef6e06f4dba3b233a6d3030208b2cf737eec5f8850d5182f50de479e505656c8b74b8034e9825d7748416305d8c8cf64561685bc16d9e52433d516234605d2700bc0db195e32650e9e577d1470a0c7a0452378f6ad5ba38aec20c905b92a6ac1cd889483fe41db91d942b644962db78373b5f9a86bfd031029989290cae2e64f6783f03da25d443f33c7c485012c7d2100824cf1a9d28b0f8bf7eb4288585410105d4f7cdb0794579f8df857b2814b42af899df02ac810106dd8b8f082f6461dc248450430fc63568aece2ba3cbb97d81421eb70954832a906914190a9d6443f3894219002cadf916349bfe82322fbaa8fb9ff3b7978c33ce83922ca6e0b13102822dd143c9c2ba39767070a84cd296fb1cac419f9a66868037a923282f3edba1b09ea537ca6c0bf279629f3b09fc3170b60b22f815037e3d92f0f3b60b42bedb77be6a62ce86a30ad0032f18b753cc435e3192cc58013d32018d916f9be95e217e4e5eaee3b2317ad0f57c21a55c3dc61dc504d8e9d4479012fd13fcc4a065edc4f4686cdac304919554cc7859abb829a3c76536786fa7711b2bba80b5a00217d8aa3443bfd9dc20a75df4119661629865c60ae2bb51b460ede131b090b46e6362de4bdc0b70f34298b0f1e202508029c168c38016d6001f584c052eb836e399df6aa2ddc6d5989834fd705937ebe7806103d7003c85d23295a80feb7c7c03b5d9b286d316ed401af8cd04df45caade506f9771380a2c78f8244692a31dca92107a78a5a0a1980bfc17cd1e3131acfe52baa41191a4cb69ee196f1e680e56d34b6526adff5d4ac13f73804791a3da1e36bdffc4435ff6d434e410cb304832495ca95d4bfe1e229f4f36388a9f27a250fe3603353dd753c38172c03cef3c7e8af045b6513722f30f6073e21c2293200c80b3ad4346e8ac3901100709a322f2bb079ab2bbfb04590eb6d0ee0a555f6641b1dacd1c5828492f1b5219c631746e75cd8bdf533a61c1c319b97f5a616516c5bc186b671f368eb75fd2353b49ac7ff4234d69b7829c1f9cf626e2064378c4bfb671f224345113339170547eafde6a4d91433b77e1ac23cbb16712a2ef9373a8ab60d98fa4c265cf0cea223e1bea108bc3660f7c2af40bf572b1604d274f3865f0976f8f96c9b8cc569ffcf9b4e7642c52fbb56fa1b763efdc1cd9f9227a07400c084c7ec150d1c04cb7b1cb3dafd680ad3e418451fb0f722a04568b4399ff97211d9fa5016f6c41ff01f5adcb8c5d72053acf88bf02952ee444403682a64eec16ce67430aee053fbdbf501cb28a2a189df4a94b7845c1d5ebab45bd440355a5c907cde115c18fd7a64cf0c50a9ce144f4dc5a08b89594793d6ae8a2bef6dcde0362105aa9bad105153b72d4292b33d820e81d565e6da5dbe975ae1a6b31c6c142c86cafaa3c3cd1d366491354159b6538caa0f2a7b1c317db711635058efb7716d846ddb9705d79d01204ec8a1cb6e5122461bd2ef429022df2b7273df2338ff80819f9776ea6ab6eab50e897ffd7f3dee56507fca2c693ad66a1eddbfb47a56c22c3b629a6bffb4c88fcd31d7e2e9633f23ff4a53d13ed6a6a63625f191a583c8d2162f2b45353913c9f748c605f7ca7e5c854432b16593835f80aec9017c013d529b444af2e23d582301996a3fcc42e9472452ee77e2617181dca840fb884cb61340510e43b77325904df848a69840096529944ae7a06288fbf206a14facc26775855b5ab4d682101cff7a9db1aa0972bf779d91559d30f8fc29dfd709ad0551b6fdfa912609ed894efe7018db24b26d00e824dd9d6b92ebfb38665569775ea3f8b3d6654ef519d895549ca365acaeb39bb778c98303fcbb2fc44f3106c350d14f9eefe9678c5c52f0776592b4746007731a62c75470dfa699cbbaee0ab16ce37fb107035ce48d81b0929c813bf24ff0afdc17be465cf4b5370400d26cc3e7c0617d5a83a1e12259ce7bf4550370be0528a6a6866d81dbfa1280862c0d74641b0fcd9a5690dda6596c68b0fabd5e99213b109425f058a87a15940c92cf7095e09a62fa7916e59506e9078b5c62549e3cba72f5e2a03c6289707654add41eb2e03f5a9a6d786c00c951ccf4b2506632fec15590f627dc605f27105c54e302a1023a011db2b4c7de63da00327d36067385f111733d0ea9975164ae0b0fe196183e1ea30e8a9daea57ef66fd3cc77c6e633c4b6dc139f40302339fe4ff07312deeb63dd1adc93256e8c728933ca12b9a77111965399945f7751d8827f10be763f17818d74843b813256da187793a9a68889f2e3e6efb237078cfee086faa4c396b7ad1f69aefb79b1f7f7ef6c75b9a8965978e568ae67c66e5ef66c62385e1a3455da981cf0483555fb83278205f55afa1a6f625647baddd564b381cd140d0a1cc436582364737103024b580624ad1c66d093c145a0001e5f47f1ef22aac9bf6b4be3540353b074ee16672111829c5b8daea813de19d7efa3a2a81976c02480b9621f4315d20853d3f64041c1322344ab6f008de80c11568130ddd251d6831455625c13d05052c1dfc0551cd5560940c0c61bc4bf88c73a8cc4141168421d893a8e3ba6a49b867df1800506f6685d15f4a22a3055e7497c7e18ac8e05bc7f70774b7411d88f09ab3714fdb2eabac238acf529c15cddc6b1ef3b39ddcf8fbf9683a65656b921e2f8e20cdf863eaf12a096f354607495dff4d8069bb418cd4150028e9398635f3d4ae66ff9af8428149dce220d2ba3cf1f7f1f4e01270baa77f5673d52335664edff836b7532d0fde8be4a1066655f7cc96884a0c7f517fb44ffd67d510a0e922bac172a263ea0b48ec084dd27f7580297e57d7f596a7017182ac8650f90a74b72f89243bfdcd9112a2e11d15ba1d197cf49cfa0bbcf1e1dbc03156dcb4fb6067e576682eaec20012ccd111f76642c58f5255a4cced8ebf199d5e243855063f67b9b6a9bf7d4b6f355fa945ac540da0799272b0ececfde2b18b046d520547e5965e9e39205bda9ba145167ad50d364212d035041392f0686911d3ba2552191b723f703e65513c62b001bff21d64b2cf1e16de42d13b9c07460e4ca6f9b2aaaf05d81a7552af56a0e9eaa9314bed95292e7bab447a819f5b3439fedcb6d37a203e4e9c0d9ece9517bd0bf4040f79629069ed7b1dc7a993d99e2bb872a303e0f7afc0310958d5d089df8e959b97097042d570a3e092c3d6bf6100667ba8452d545cd6b3164fe8065650c58345c11e0a2de4757aff9842445470f5ed709a4a3b1d99ee4f47cd6583bbecd41fa80bde86c6e14039cca2d87915a2117a5de6a3e6e8179a13ad1179fe5fd88102d881d6f2a10f360d674645ea2c4ca954d1edaa41375e60c1c2863d0a05d6ef1b9244b518438fde75b40d3453e5da353882e4c667faa60d562285a3a72f30fc05d489aae5074d7f350284261c9cbcdaebf0b61c47bddf449650ce2e4544d0e55c96236ea6e26563643fdae0b6bfc3bac15b8eb37f2298768df9d23c1f4853a5a1712cd1beea656b7da5daef91226ce2aa52187ca5553ba6fb1dfcd2a5ef44a149eb874898cb39f8a56c5e13a5ee94a850aadcf8aa094bd4eee4d0b74d70f25c445c70284cc6375a3a0169eba27b46585030836d6170fe8b4d8fd8dd5284a75855a198327350088ef894ef5d90f0c3426298d4dc1b2b7f114505784c0631255f2cd1fb7b8fb32209abe8cc642274dfedf1262b20e129c716a234785757afb529a6f561eaf202af0f10bb7f88868375ca2fbda0252a8cf13dad4b0f0cafe0cb0cee9208f750b3dc8103275c1db7caa8bed8026f20f8de8c7e7c8bdb50b551281778ccc01d708a8bd9f5c72f62e815f121e4454bf30b184421d31e28e3c0ed10f146dd6a70cc4859754f83cd55ec34b286bba8e98f94a67549db8f0418b765753f7670a2775c2e7e41318fa1b20d676e0508cf8d2f0db563bad00f481a4ce43aa4e9ba6953addc720f3a0c2b98d7ba36c8bf7e1b42c468f3948f65b3e4cc1b644aa4ecf5804fda4cb6c7cc5e3b0f2ee02aa0db1c2735e09fe8d2551a9537319024f8f9d4a412e05e1618e1189b48a93f135124af51155a0333f420d27bea83b91cdb66de713925ee59e94e3833552645e98d8acfca69b667ae5705717539ba57b97092c5097eb93066f1cbc06b5576f93e1f77417d857f9ae4103934c50c62bbb47a4e0a7016e9d1c32cb827b017c3e8b1edcc3bac70f18b2e57dc59813603a5739b41e0f3b2f449f126d2326039f3bd3cd9970ed187fd840590a801d1639857add946812ef1eaa7520ca96c021420d86322c0aa644a348cd99f1d72cb55dccf0ba8862fc3cb9d091190174c325e125dac814f8454869d3775de5be67fe240827941b6ed940e5b06591f8454b12958847ff006a5b0cdb500cf8bec001501570678f36a200fdfbbacd3c00043f76b2373a8aa20bf88a6faa071b49021370826b27cc2e801f6df891d831ab1085ee62440cab8e0b934fedf845a7961e836a9b8f7dfdb0c20e17cf94d76c3acd04f45097239fdf5fea24128543d727746bc6407c498f4e6dc327770eaf237ec295a0efb3ad1d91b4db19f2a1673128b21b5fae0e48149ccea05bc33ce60694f9684569d0d9ceda8439f031386e88392905878bfd86b34b6410b4d88728ec4a7b4dba91d043affd12da9687b2f1e71061cbf85c9f6c211806bd39a5dd14a298cca97d8e89623c4a41d826ea7aa7dd08082711c2b41c549fe7af7f47127a428a279b9ade201794a580fd194786f1f06cad0977098707bf61025ce50d0d5de470e49c6a98f44ab4405e6bcfd7570dbec63f6907163bd77bb8aa4623969f9661c85bc1f114b2df4c7bc5d5844560f0da14325da1eed40957a797fd0e6b0442d2aaa7ec191976c11f932ff372579f998f9164ee5d2ff76a7c30e79188694f1f53e25919d142a8449c750167a3e646c9d631766b1b336648de2ece8a712e6a00051db64920a8904a352b73c11464f22442877503185991efcee7564b15e8ecf68298cbf02d5c2f4c6b1c0d958bb8216f1e6633485a904e66ec6830c5049c9919348fc33336a59e87f1d4d51319c9290d66c385e0bd606865b1201737733f592e73d03fd71ebca766f867a5b33ca189012a08f8af3f6d803b8b23153bb90a14990d357c4a5f8b0c961b0d2dc223c9b0e16f71a82ab0de00851ac8e51be971635637c32b721157aed4575c49c4dc839245ff643025990612133a53acf955d61f7ab359e0e5c839b3510926f16bcfae67a534ae28375ddbe13620e873651c17d26df24247422a48a73e494b9846e403650d8a13f00a40cf20d98caac14c48d0bfe1ff95e40f12056a71e6e2581c30bf25cbf10cca90b9bf6cc4c754fd1a22675d722eca376646e8bf3b55e18f31ee4c49b3209827a6eca5e3caf8924ce01d27c9498f8a0d570c4eeeab33ee4538f92dba24cbae8987cfb64e14e01972dc00bd29b36671db32a7736c6f84aa468d0f920a754abf0b1b99582aa191e6f68a85f2bb0af552608be99d2087edb5124b69909db2ba4b50f6a6cc0e001a8f1754b04e6ab05e9824ceb865f1ca1179b54088c2a9c6dfc886afe1b8b984305ef608e2709f3a37821907f418e997ce09102c2dea35cca4e219b1ffe592d4ebedff81ed527a4c1e0be06358802c89c7d4d4d9984584ab245e66d8a528f13abe5b7989b7a579fa071b4fffe60f535ff8145c75f06a2b199aa0070188e6d015660d6237403a5949b5138f5a40471e7285b6e740fcf3e2c1c0c8aba77582738cfb24ef7bbaa1a9e191a936bb1c39454e35bdd86c33121ed25ff9f2c3eb38251a126cc3aaf51af0f5c603469d43ac8b91a70d72d550748f48bea76f73801c93338e105906f443337248a853f7be97ba0acaf06af8aea3c53afc4d5387ffdda2d4fcdb038930d4d67efd15e88052fd2abd6317b87e404ac0e23902b90001cec3a6c026e9619fd75433662283584f65ab7b567dc86872e8254cef30b30053c72bdd1302c6529088c558f33ff706c421168b830aec1d18d3fbc47391a556f271d0896f3a960319ea211c64c3b6836190b70667f866251fcbf18898754cac14c65787c92440303b0fd1179c3afc9a8361927c88092d23af0c71e95b805bcc9405016b28de38e77e61f049e98202fc651051a730e36cd9573f4443019e89fe01e6dc8ef8430b610d7e51fbeec6f7d3ed1f9c16eac93438454a5732585714af4ca3fdf117db3767671278bb8143d0f62da3e95a69ce10354d9e47c97f35c9d284bf12e0d833e20fc6702452cf8dfc8843f32d435ea2ec3fc0c4bcccfb262c46fa5022f1642a225b50b6e1b6c626d5ac0bad3bd7592d34cdec6980d38b65e2d32e12b28a3b81e249b2f9282d7a6b2cd90c8617e7adfd4f002f8c798f10065084fa5c9a9eec889acfda8159d0aa640e96269efc53a2878c258acda089208dc001c2e443a55a7ac3958469e719bd94cdc960c6ecfb6f6234c10406070aeb240e0960ed835d43a3e15b3d7bffa3051302ecfcb89e441284a33a4a27ee33769ad1b5cb33180546985a20631aa30a372bb5f7936bcb2c4fa609aa1d91db8e7b4f0dcf06bdd7aa337139392834cd5f23d0f2ac5d6aedf588434fdd32538f87de0f107667b6388c8fbe6440320061c6a6851dd90c84bffc97270a1a06eb6e07fa6515fc03efb185e281ef57d1f25c488bbc1550a075f1ff627464bbac235588713b2922708b7c662bb5788d060223299722932e8b066e8757870f6a16896b8c05a7425702c342c55c8c30d072888fe7be6778b73305a33601bdcc855782f2ccb1c650e15b30f71c84ec5e21680cc119dba0b11508d0728c45909e895c65b16056d317ab6bf6415a72773274805d7fa4e6b0bdbd7ee9a92acaa7b0ca14d8a10f94d12df822032d42d67422fac335d6c7fab3e8222c85be84e9d00284689278cdb69c1fec294c7d1635d8ec130645fb6e4a8a37892cc5c7a7e8148b20c5863a68f8a33899aaac16a3cf34e8258570efb9c5c4ee8a4893c7964d9a098f987c91755070cf8918b87453c7e003058412d951e37808dbbb2e3cfa21ee690a75a8b8783d5bee187dba7df21c334c7dddf4d67fad78d300bffb86acdf419339a4d0be203c09649c4caa2cb47b55e64533b70bb8f3c386aaaabd9496d60149d1ffeaa018e373ab5889b572bb21d9c3d02f8008a405713d986bd9c88a4813cf1f7bdeb4797883668f45a2b967f882ada3cf63d11e243de0fae0cb705173150a557b2a4bd8f64f87a8efa5fb576cf8da4c4513567227897478fa5b2ea2918fa1eb74c37d75dec6c8412f3d743d7a17829098d3b7fa144f22d78dd3f73f262bed3ed4662ea9f22adf92bad261da6b68534840f9737828260efb4524b0df8f72adfa2112f0dff69ae7fb8cf98e99d2be0b3a18e72c44bea09715ce8c56f860321db4e7c82bf31d42123c06f882342f7da76354f44b45ce0c30c8e1efad22c45b74a5c60395d437ffc393ad44dcc037073a3a9179b400ea8d6c32b7bde6c37ba8c47b9f33e370103713b9da86e74d08e393120486ebd7e7b1d7b0eb97fbbe89f617111d7b0dc1fd946a4471ee796f54c502bf275443b090bf02e5cedf377d8888e5b85111d1ffa0225eeaad6487df9801f5d3fe23b09c012c72d58e1c5610f7a38af239eff3e1dfa1311b2a660c0dc070b02706ecd164081f93eedd938ceb07d080530f758eb64504e0e772c98c41562a8474a37e40436d62b7ecd7b381bc64543325d3d24da60a589c5a6c1e06773d983fd2f161093aa39e6cae0772e2cbe4722f37cad2c05628b05c164b9c693e99aaafdbe926d3a0f88ea2d7c5c8b01463a6da8672ddfc780056811a36b64509a0bcc8533c6adba2a000255448613f43bf51d3097de6a345c366415fe344e2d16758c99c3f4774bcd63f35b090cb03dd6eeb0002819bbb179c9ef7a2cbe69aaf8285001b65db48556619f137c8eaa4ccd997d667b5cfd5730de0eba33448ffe827e853c55c58a3cca15b9c53ae4e450ec488adc0128aa0b5810cc58022d7c9cfe160e19817234a5894f02026709283d46aae1af320fc567451b1b9c79f82016c8ece28dce24777901ccbb41a18d377565e5e96ad20feaf32f75a03e8933500e775b3284245c6409e3e5f5c74498e864e862b231a20c013e253f70e7e27f8d35ebf78109f42d27a608162b9e960ade4155d4ac9cabfe3408a259cd515c2fddbb4b021b1dc17c5cdf4b68a3f6547dcf9548e3e3f825aa1c7d481ada9bc963dff51f1a588ec99c5dc20a4914e3a916c0d38bfa89091f9d0b2d5d077e60a3d5a54aaec8c2d3adb39aa2437ac1a994ad2304a6eb4f4bd5dc7c44443ef3494b36d73f17f459470ac137c9c09f3ad44f0252d4cf197dd92f9d93292e55a27d1bf76636568b4d86daabcca91fcb642681421809edb9b110ed68d19f5c884b090102209b65e9855c2cdf41ccd4258dff97aded92e06b981572c5b65dcd8cb9124c8959584438ac410f263edfe476f3e48acc9b76f7ed58cbdd97f656957a0a11c676ced3430001eafa0b40061181a190ebc885b684be765824a3b3f59e08bea1c981fa5ba7840d403cd1103b50c5de351f00bc22243a6559ad5e7cb865bd442babb3a502de025cb52cdd7993a85a99e03a196430504bd809386d86f67ae0640530b1c3945cbbff3a54b1623e420ed81647f1ac1633e2fb5a0ad2dc05994df303ab088cb23ad78b3866c647435b3fc9f96ce4533e459d4e0b3a4a928703c827ff49f75714266e4c0ff3a055a6bae0e44b027bd84d1c0de3868d976436bad242e53365b8bd40a2da6392d6de104e7f2455787ac51da9e3611838b638896d2a0498a415a00016b61f75770e79f41ccb710740ffe2216d25de6fca690335c9800bda325732cc95abb4775c8da6dd216a7256de90f7d482d0f5c701eb2b8bb3bfd7c6537e8965546a358b7d494de07d405c66861d99b03db635fb4ba276719ad501db21271c2e300e7f6f884606934cbf7d4d54bd59b7e7d19b47549ce2ee5017ef1126bf2a230bd7ca66a3fa3c4083f92937b587276aaa96654a86ae6b05ab1f4d066985a6fed95def7b6335f212401c7252f3b1eed4a6f9cf8e7f3c8b94e8307daf1719dafbd49ea46e1b91ea6cf00307cde3fe2a3beb4a85e1bde585364130b07a83e4abfa1856f3a710586c2384bd9e3bf3284ed6e293b5f35f9c014a935ba790e04f99cbecb2fef6bde470bf007a366fa0bf9c6bfc28a45c452c8889bcf55507a01abcd30a1bd6acf935b63828edfff8a3f8d20607fafce0623cf7b547cb1047dfecaad6de1f0a8524279f02a6a5e06d23ba80436fd83f733732602fa0a0580c04dd3207017d559665ef8274b1b1e3a44cfdf0161c4cd23b7fefb6a64f0dc54e5e1809c09827e9d56b63d0a4eff9291ebd378dc171ebde8be5e6dda2ff5312185c82dc504ee51fc96010c3a388a80ba74594777752c100ecc28fbf702e9c04cbede03f3f78a29f872dc9e71d4f85335c7bdc059064af9da61d82b0c3c862183c59885bdded2af491a8fa6988f3ebfc5de7d12766046657b4dc3bb8ef7a48488458d31c5089fdd026f1f7b3548201a477f7a65071f6f150a0c092d951480c9d704ea95c598bb92b4d4b698a0b559445d20a4c4b63320986dedce8be1c4c3391b2650672e263843ddf45df89f89f89e43c9ea5790a65227224cac0fa9a958c02e0f7a7e45f64a8dc2cd67488cc9f4caf20201ab9ff7f648455739de0c830fcd50596fdad4e1781e5c2695ceb81e1cc9e0aa35f41940114298546258b6ad64e6232879d3b2d22a18b023c4e13761a206e7b992081a3174a82e6a71223f847958cc41bc1c59b2baf9195a49134a70a02c458605af7614500b03d8f49e021f2f51957e4f41844f2f4265209dbc18881278e80a1a0509f108f4ba355fb492bc125107498ad8f161590614dd0945d2d2af90fa067724117e4e0f1a8fe0d5baa159b73e53cd1cbd35b813bc0e5f1d75df226fc5928b60f0981e300cd85bbb1c9588485c82175232e24a9ca168c3b4cb425e45b482d7dc222f7717928552ec9b5dba2b3383ba5c9e6c64ceba8c6054461a0eb0b1f3b90d092d5ea852daf3f8cf7b04695e56c9bc052f94d4cd4edef6a24e77314a0eb1fb9eb37cf73ae1c44e3f29ca05ec4cf8f3b155c028d8d07370f5423cffc78f2306051bf753ca12532b99980234941196c6faf3084b37df659a7501b43285cc54561f8b3b8295f8b8d49aab879670a1b432cb6b517a2877eb507d1b78be05f066ff1024b9179ba599c13f2b9a79030cb123c1eb630f65c9d41c3468353cc46c75e6d10eb9f46d14c25186967195112c1f797e63a2d7b73f4eb23d4670ff8f2db9822496579712583f12c9204a90b15160371310a78c99661dbabce4225de4157e5e971473304efb8220f4830dc9eaf0544b16baf904e52bad4416ca8db79193f54f19c647da05724de926dd3d0bd7b428b5893c29cb5250cc433a10c77282363a6af7541b27df1b47029cf33a9da73865e2d2aa282db3cfdfdab1b776191381540cb19cf1cb34a957dc3bae0c89ddf329f2e805f6055272055c18e43dd1c6286212f0b1eee49a986d489185d1be79e093fe6016bff57d12f49838c80a5dc8040e82a309973a830c188664053a9710ae89187cfc8029e1c274c12c8c670a7c70205c28e6b83db3a3070a7ca7001f643e43896314f8805ea21644cce4eaf8d14eb41f8b4087546d8c566b3ee6c21707d99ec5b587ba25f091262d6da157f0c27f794682cd1344f30d6b6e20a50b2fb66170a90b90ca8dfb8b1115dac0bf029ce2cb82e71504f78c6379a6da98218fd779185482ce9e75e06394a40effc3bb5506a9161b2957e7ee55de90500bd6b41fa8b58cd5cb0610f798c984410e781a9558446151e60c073566bb8702642bbee81ee6642b12ec33e7d4eaf30c634accaf0c2f16a73f1729d83ded2b29cfe5dab6695f49215c2eed98f69580e7b2d2c7695f7d0914fa1486cf84edce1fc1380bbe0009580eb28a4d04be88a4f18b1a9facc7a88624c0dc0c07a82dd838cec862b2b9ee52038e0a5e8a92441f53a0b4eb7ee9ad06df437d5dcfe6d9eff5485c0589cc066e76ddc887523778b8c7f9e14bef3b1a14d52b5e10c4ec812646d28e6d7298efc6f4a25351c9b756b20d5180a2d6be52434b4ae643620e0af5b2cdb988cc86cddee311021a754b253524a3d0798f25a917a4db0b389cb80b0021234cd7a6aa7c62b171f2102226ce2c8b0c9112b9166495f9276c390560c829292a5001321cc6481abf6f24977c22b86e405f0d8d8f73029e23ad8860dafc0a6fe15dd8bc1489887fdb4576b5293e2cb93766d14958c17ef76a76cef07f0f742603f91c7f911375b3b85547a584b095d6b7ad698e57cde584b5cb2d4375c280f102407916d70a21d200b6a22c275036ea918bbd52d78adfac41f35e04c6bfd71260ebe67491391532702d9fa0840d5d6953bf2ee439ad5a54c820d061e32bffa17af340849cca133b4c30257696381ddccb07a461c500201258fc3359e9efe9cb3194c637ef5d2e2dc16f16bc30a863aa44901e4c9717323f062048fdc8fd3a618c6692b5b22f546fed93f71fd598a559139ec5f89eaafb2ec2382465ec5a06ce4273e2606e755289050d9e909f6255fe5cffcbc3e0872d7b09f7aa9d930ad6cce511e45d6af8672dea40caf4a24b82c6d68161f0ceb787c8fee77941f4d41f7eb155512b83941a8e7b2f14b372154c03a610482ec417dceaea630c7e817a360a7810d0f7ec665d3beda17934172a56962017da8e058bf99c968f04fdc4b99f5e32e3c301cbecb42c87cd0ab207d50a929a82f79ca3002d3e757d84c3ddcf8f1051f51fc00ece2d69d85cd6eae969bf11fed9d01c3930a262eb1a52d9d29a09eb76e21128a617130d2f7bc5fa82dd4e0961eb49b07feb22371d189333bb6c193146e3d0cfb1a917246d7ed33bc37aaa179c49a28e2d50ba9fb1fcef7aea82164d3214972d5bc6a5c68cdf4714ab9821e528ba02e24deb076fbae3a6114e4fc9ace12b2eeb6bf06585ef309e8c61b69089626dc0945445a7934e9350b33efd80d8983f6563f399ba05d835692492eb0646979c5d7dd8cc1b8f985c4eb254edbf11f97a67977be9760cc99d12640bea554296f8db0dc9e245eceaeae7faa3a1d98070963759adddc0afa21cec8850c3c88cd2f69521eb0ef14e8a03bbf2f70ca2375c1e44df1d1cb3d4b45aff18581a7a76cde0cb8cc7e32c221918de7acf20b8ec6e3023c33e72200bcb04f3698ee14da536e50df99b35ffd2f3668545cd140beb4c9557eac40c1cd0480d6a9987bcee8fb77b5c7c8aa2cf73a69dd879909b3f5d639ad218e43123757135e105fed3d075424282d64d2a0d1a325d4e1da1425d1383ba95f9416c244d4770157d830a66339fb86ca8588ce2aa970ffdb0768c7f957321d73091025d552864c84a12ae98f446a02b09bb357b8d905e02391e8d2041d56d1f1aabd39745612a172771e3ab1d704b4fdfd3e82659caacfff3e21c912534e660e700e3669b3ad814846925e2be9f894904861905e9e53c34f0ec769ca02794e9c76247105198132338eeb2b3345ada92def180c07512004b089465f3612aa20ba0af3a44e99b2218cd243785df214eae4a241a4396deb9eee947fe22c5b6cb7347105e150470bc3c9872ad4dc6f93e8c24982ad4f1562a29b3aace693466d0dcd9a5113d43532f311145d2bc47ff97e65e42e9ac364cb674908e17118137e7a62b6560113f4e1034b34d789155c304c50d892c879860cb2d3a12dc460fa4aa3cb915a1e6630481a957c9766894776fa7dcb542182ccf7b3ef40d051e64acd554949499e031eb099ba08de23c204c8262154ac18780d1c643c2de55c03545284ee1282aa0aad3d057d879f944397d1694aab3b93455b43f5f1745b466fbd80d12a85664b775207c6f9f9232e6f094a33105104f6cf0c3bc69183ef5f1c3b35cdf896b9266210862f08ec7add11f00f19479a4fe3e2dcccc0a68e426b476915389d06cdf4905f3895d73483d59c692b73df32545d8ce04efe006cb5e79fb94cf19a717a9b737c8ec39c79cb6f9a5a038f3de5343a6d202e53c877e80b0808527d9afd932220ce221c4f0958ec349838595735f19bd533d99f1c61cfb13e7d44bced9a239a7a9f84e51c80f74577c38e11f77959c808b8690ff3c7b8c6fc4ceeebec58455aa411cb3fd35432c43f84676944367716299ad96e1c3eefc8db960eb454800035fb2df83dd1d2d86547068243732ffba48a455868219440ccbca0b943f6fc31af9adb53ea0eca12f64dcf6eafe9387c5387e0bce6c9ffce8153fbe31653128db54a6dd213191ff4fc004be58ca2cd2a02331ca5184c9b8cce881e8d0422b269ddd764efbe6c62b831e07c5fd57346a96a334a9ec8cd687992d7aa7ae014dd4c20bfb62831e786808917b6aeb9e344588bd20d4e11f4af1bad67e0dcfd8e23be57b984362060efa6a6421a19a65a61fe5222603111a922e6e10ac3786930b849cb6f2d54f435c211e9ca9be27222f60361a8e30c0b1af53422d29e6da05bfaeafab42b33db76c8d77b3b546105eb7ca7d7b0caabc799faa3b3c24000e2344a2f781325c46aa70d336bdd51a60a5626b7081a69fea370fee6f8920fc5b32c2230676007872dc54cca8e303a290e3b7a488127338a8b67cd4970fa9d7d1dd282ad50f0374ab0cd969aac8eb3cd1bac2d62f0f97e6468e200a1b961b7998c1f82129ddfed6bf5eda1dd3aedf5d91ef60b063907088d26b48396fc239381931c0495c99de4627a155a8f5472334b80b252040d2af44fb65adbe47372a6358b45add78393256a26c8920fb66fd90f86391206c36dee69db86412b6f0506e37b4aaf14ab6fa0d7188d1c5caa2a03ce0e73ae30a7748d2cb6ff973ee095900a3792a4fb6cc56010b2025fd99035abbbd2cbe520ad62b48ffd01a0edf86f697ba425e45f39aee15df2ebcdb50e47001326d1831a869e55cb98f7f378a7d015c91b30f68dc42f46db406b36120298fca0a7d0b6ee5fc925520837819835ce1bd494b0f68a10b7b11194dadcd6324cb24a77c50f75e357547a292ff545ac3a79c25e70985febb627de24a92e71b755a97582532a5b7271b083920893ed97a03f46507cc95edc9dc0abe22039c2895a946d373c2437a11f5e50108db1cc4ca988eac93c51eb89406f02926fce101be8d7453aea52c03428e11d578d3d731369972062eda26c445723eeb1bf52270353aa2b533a3b5f1b6715256c854d1ebc224eb26bbd7e2cc9f5e337368ef4fbf907ffa6afaa703f69f5eab3932a680887e53fdbee0a475617e2f0ce56d29d856c4a2f02e11437ecd31ae2eb8136f738cafbb07e6f84efd27bd12585f54271b25096a67f02cedf4f49084056fd2e0e885247bbd84e0d71631cdd3436b78865ba39762460619e202db1c92f1e2bc464dfb337493238bc26c31cfeaefd696a079c30e1bd4a4121eed90a1c89684c955da5604a5b9f54d0e7af2321504dc2da5de8f82623dbc2a213aa7af191d0d114f8fb24118891fce8285cc9b990ddf0fb1c8cfc295776a37f4f85b596f0db42228a98c6aa3b88780a92eeae7b54be24e1da9bc910ef7e36521798ac0e88f722b43a997e1695595fd660f4f5c4c80eb2b975f6449c22abed461e415f2ec57a8ba55c03a90f0f23de194b6f80a60763bbad5f52de6146ce6cbd8ca3df018800918690eb91d65d9c0adfff16cd01af2696499b8a3d3c5c90ccdb3d33a1a0e640ea9acabe115e270e74c2d4bd531975ef6d93b4aa57e5350b091651f110c65d658da89f74f9e180ad8383ec187b005989b6518d70749da1c3a9d59638d19cb3095c0435f3c0aa798ff0b7262900524308108c7527fe84adb68d5835b055628e6692593a4af25761eedfa596a8c619cb94c4ea16099621267455f864b052566af3a9d4c90c27b0d60aadb51e925310ac9f7efabd775759100d0faa5d5bceecf2c3dcf7699f4dec56ff771e3c9bc0f47c288b41cdb469400c07a8392fbecac9a52cf185fa973102610c9a074851871cd5294f23aca2253cc712cb16682def632db5c51da776ae384e77394d250b8e0d6fa1dd2850b6a711f2c597249c095c3b665ab069c3d79284b2eeb02403482f0b4b3791c70ff4b249dca4d94c984500ad46579d052de4743bc20c3d0f987eb589f97b5c5488f62d4abccf92254194ac5c84e552e8b912ad9edf0fc7ea15c8a71758dec124b2f3a59af28df8554362612089e04a1c411885ef8e4e30a62bf6d0c71b571efca18c7765d8d26aededf87d5ca015c3ac9ba05e4e2027a42ba7a55208e61351dc057aff100974b26a31c20a6f48ae019c5253c8674f3c9f0a5eb686e43e1a6a38a226e9da9b2baf75d0e64e7427103c0d0c4a21f512874b8e2e9dc64be9b365bf6fa997ea7e8de25b4a4ed2da54c49a667086b0759074b2740999c10a819e4e7862a3caa2018d83165d00b44b080ccb101a473c1e59e9398ebe172cf490bf3ec9f908d5a8946d4209ba800e79ea0ead387fade3ebfb370d1b75ea23c183ec0291f54bbabacee76817e48297d3fa294d22808d486802b947e8b17dc459f02b46721ba52c048943e535f114bdba5f403c0f46df4e8d2d276e904f336211bf50d698958df3a8d5157dea4b009d6e271751022a20be8746fee05c011a7bbbbd3c04e726762ad881244b47fdf9c20846933e702da88955a5bab53aa66d24b2483a8dd47d4278ddadfc8013cc405b8a193f25d801b71be3fc3f83bdd79158a77656d44eee976f776b9ebd0901bd66873dffad4eb766d04f2861f4e1b6ed86037f43823f77461b7b4b73e73923b6de1f9bafcb4b289f099b42bea2d8176027a691f8e59b7041f2eed434bfbba214f2622f77459de3ea3b3d9acdad96c0666e0a16c6272c3e7917b3a37773636dd92332865df1ef84bf0c05fcaded6caef6b1e9ea95330cd09d4c8925ff6321421d9e3ddf06bad7584d09fbfacb5947d0932164d335c6612a5ecfb692d02b277d93bf82159f2cf46be4cced4b3b15f56ba099a9aea93b764fa2100d1a6705a1bc01adc890943be44f93ad3678a0bb42f18a07a58e982f2452a544391444005204880dc79e33487d90cf90a53a6cd92242de400c572d834ce9375b1d0311342a548a8e325488e8e427fbe6c00ca499917c6b07400a255f59b0e98c903856a87951f5a5ea0aaf6f8f9b1cbaae3445001aaa4d9d2214f9fdd942b2c52909ca19ac24186968336c1800c72ca8829b1fae1244e141c52bd1c5843b472583b3964568ce696363a3fa8b4f152652a8a470e5994f731e282010e122657c4f819c0d418296c785598c82015dea086080b0d47e27061f215c30570e8c400c5ab0e8e1648d562a0503f88aa0c9c23527d98d8de84d1b165858b6a4aeda3e46a10171c2b1f7f5018a4e5853b529aecb0b3044b47101be61ce293a3cc20233ed8ac98b285ce1c2a3b5447742dbc973f58429a28a9936766c4ca9f1d0c7139d3458a66c6ba6112a8e969ca1b313345ee58c9e101156e8091faa2a50c140dacc9f41125769658e964d891004e96144368c23859410a8c7ba19345030d607200549525055b5e08bb51e78b470f19540e398ccd0982031e272c17b27c69c5b93af2ddd2c6719696a4ecac17292c7c5d66091f0f62e8cb22f3c9fa8c33589f29d9ebd6dc95f44c585dbb7ce687940dd403c6f13c27fca0f2920256974250b00cf1105465a7aa4e10999a06734b1bf3b450b9a093287b527310fd72cfe9ea7a6041ac977b4e4bae079dd8977b4e4a984248c1828673da21eb3909116da2ed724ff7e7d22ef774766a975a551342e185254aa1385cd2a0f930c31e345f6e8862648d545803ddb9b8cae2656a4d112d3d42a27240f3c2161132586854f46a022e180a031507cb8908873113a5cb530bb60cf1c821f3ea19f4e43086a3cc10373ddce400edf1da3283a54e9f1c568e773131a4d09329532d30611301267cd8e40002c6c820a9a9e6c3438812dd9b1a9ec6c84801a363458cd50d4031e8087b08f9dac2b503cb202c303abed800c667b747509e40211eaaa403ab27284f507a98597205c81a3351ae8c9112fb91a6298a0a847a5184e8f66c99c3eb5324cb0e6258aa745825aec20db4a3b30548080d3bdae0e80ad4478c93950f54548da11e60be94c123c3202ecceb01d5440c49172b563abe1d1cceebf075e5278dd3561e2b2573ee3871112a42050482c50607205f47921852c1cdcd088e1f5f5e72a6c8911571405b04853944c315317cd2c8ca5c1133667775054ec83bc280a815c68481b1536690913538e0485909c94187b6a32db8e07344ec0c1f3432d8d0b463cc912b215276486121878e042091ecdf8823f0ef24193f8b80960cd65a6ec93caf262941459aa4b08393d8921c13baf104caca48a0313d724d06a2927a43a40bd098273909e090840a57979d0d8472603d1b87300c0ba9c6f3e437f8a2830d2f48e9d85287d54c29f30503973045aa72f3438ec0e51a17a007ab88f472d721203d9ec479c5ae433cc0ae433874b41e500a061ccaecdef0047d99cfe07cdbbcc1c80888943d94a33a2029a33f7ba49c2945837272dcb6bded36f97d5bf3e3ebce3ff3438dd11fca428c52e4f653b06d6feb9df931e4ca2e9ff9312690981b5e5c58a255a7e763abc9098f2d50b24c51d3260b188a8562b9f3798636554f63ba1d7a68d7131f4e595210c4c38b1f99cf2098ae3343898e2c374a7c3c514d2ffea5292a074253dcf060c2e60500102ae3c3c9922d63b67c99cff3c12f6ff8cd9dcfe07c1b9899838e0b470e85b06060830205203d2fb1344258b8ddf9afd3e96e50273a245d3b2e5df27c72806cf9b082b2ab12168491e8f95248cac78ea814ba0c892f2340903c9173a7498e9f4140a12e7f8b15540cb6d2d4e974baa8dc9c1b084157aa8186345d7ec394311876c8f578620f584e0145a2f0724d26ac8a58aec7222bb9b076ddb0e7cab6d90396eb916b6400e5834cce060869e05401a04dce49b08a71e186a99c0ddc95162b599c3c5380e89240391f6b503a40d0b0c9d9701d7ab672dc0c08c338553b9a7d02e3a550ce06ce891138355a8f9cf3b186028460c5c9d9e0af1c390f364cd9f940f3b183363a2e5ca12eb91004cdc79985c64b2c04cd47366306cd0544083d99caf588b3930b893c8c1b407472366a79c4721041f3d1730cfab3c380e6638daa460c9e1b391b38ac235f72fe3dd6c0d9c9a1d039276933607e08009a8f22f0acd19323d723ef202417da683e7a18962f5d880118000de60e32e0b1d1b33ab9618f1bb6a0a73b137443eae7869546e7825073c38f46c799981b82343a7ad07243198d8e9f951bce6874f47075c390464710446e48a3d1d1c395badc15c8e9861e6874a4e930e6754bca5d7fbaee1445163d14b9f890ab3fab648d14e4ba767de4ae313bd7bbf184dd3483d33f81e9d66fba5c43313920288add46d7a5e8907c535bba13f303be274e4cdb095b939336a58ed445c52646a8064e03a6877a8ba29cfbddf9237874b185c0748241dd55c84661756badf396d8b94e8210d5e5a04d3171724b065b22e896acc7679f28e79ceb3401d811fb7b4bc6acb53fc2bc9699d2f8466daef47c449ff98832313f3f0bfa3d9626884003afad716b25adbe1fd13777ae9a53958a0e2a3ab07a3bb07a3b98dcf9443d1d7a2ef750c8724b3e74e717e0724f479714e5126d7ed73c48412cc58b9bf52f0083c839d9b7a09145e0bc189091508a564c1a6d269bd55a1105641ffe8bd9d39ed25a8bda8cda28dafc682251116980a40962bfd1bd81b7bf7ddf95d80d96311d6b7cb04095959b7f73a526255bfe7851d96395c38ddc1cc15396183835a42973436e72d9aa7a03e584cf9caa9cae3e09298ddb9fc14da11601ff24e4a4f47b9ce129fa1642df265302f89c608687c5cbd89e392bf0989015845c09d2c506ae5a8367f43802f6ba253459365ddd7e1e8b58108b56d8f0ba4e9e982dfc887fb2f01eedcb8041b55cb9534f519e68f245271589e2f75c13817992d047b33f104602c4884da660ea5b0777c4f2c4894e2a71a7c41224c498253ae93a11e7e3b857a5ebceda04f87952a6ee181de8619ab7059296f8574c0b67bebe58f50471e170b31526064914382ce4e6c3981fa3c85d6926c9babab9236b3edd4975e77b274d127716fd350a619a4003468c49a293f86b5d5dd74f1c9a553b2617ebba6b31c9a274b967c5e4f61cbd5b2032f5cd8b569046e55290236239abae37e08ffb7700479cdfbc9e9a5c7de4df35c7bcc0a28cfae64b17c5d295b8f404c5feec27d5cd8f66230a9f8362cbbfddddfdfd1c4b19dc75c1efb16cde6d9d4e6ccc0ed8d5ec25109c3626efb1fe1c3f4bedd71a8a6f5a5c28124da6a1e812cba5147ca2419851effcd93883f491fb738025ce2bc290277c0e611db2e2e5fc671c274b00b1c043072b39ffe93ffd433017740ed2c0b1bbf4cddf2792292acfd249dccbca727da98b33b925adab2765cb81e86e39a9b8d39eee2e0bbb3ea76cbbab49e51f7677e9bf4a44a34eeaae0bfc846c14f20632887eb7eedc724b0f97e7d69c69cdac79b59b514dc9e84f9d6c8cc56050ee62a2ff375ced6e9e5b97a9a7ada1004196f482b021de8aa2cd66c7106308fb4444f45dc43bd1bb880ff15c1b81e8458c1f9e48c4e8e189448cb4271231864f2462149f48c4587b2211442323798871f6761cafec735a88b1869416626c5a1b81bea5e0dbf16fad8d40df8a407fd644b8808480f5031546e752722bcfa10be2796b6a0cc418e38a63f9e1fa7f18cb29a59c3e4ac6e1ba999283dde807ce993d32b29c3a313ff0c001c992c1fc6871738779d6fea924a14efa3bbf75eeee8ce45fce5e4779891e6239ff5cf73ffedc499f801ee2f4ea9b3ff52f3d5cff0ee888f34b36f20be6056cac949654562f4acf2d69d6e45e54d89d4fa94ccb437a41e4cbaf45fc67de1228862f3a43b81c01932dc1a13546d00b6f84d49ea95f4bfc4b79ae6480ad222dd08064100c51b9e954c662c0a18e1d2c7c7293863b75b0747692e828939b4dbb2a7da41882d221ec506efe4f8996246292a6019658d219f5d22c4aa593b468283e3be1aca05fbc4cf930e40982cc1ff991fe5c1b819ff64c0e8efe1cd21a0a19f3d758345d266738cd427221ebe70d27ad36522a632f47d4e59ed4d87c0e2ef7a4b82ea572254a8566b97376b9f3792cbf6ca7fb7ddff732dae982cf6339ab8df3826449ef58824ff7d36119b353c4be5f02b602cf09d70b1cc355f22d300c4b1f7f633f8f331939a35e47e17b2ef77250dd599b9134ab6ff3915c10e7e5cb64d94e973fcc20a9899855029058f6541623cd47ca12d94c50eca9f920288a34a75bd22c1ad368ec457b663b97c5c4b14ff7f7f3b27589cca0962d4bbce297f18c9f66791872b864c38935e6c9cce3338fc1a66eeecac9039b6f693419ed74d9f242f4a6ed9f7f9b3cc76c71fa2380c9c1fc2ea294452b7d602e3ae9ce1e8eb0dbd4711806733e65c00a2ba914c09d3fffffdc7ae79c3b6998bb005488d745df5ab0980f4e55de07ff4942dfe6c3a01d041239279bbd55e8c68ff8b79cbbaa3b1f83361804128d5a29fc993496e823b7a3cb946664095c89a510c0c452c6789b0418319899fee76f4919e3ed2f2ac382f6e0002486ab05499ce4e6982439e6280993ea01c14d9c2b718e0ea02a284273c474f890e1c953143d586168961495c175090e9b355a02874446fc4b43c342971e254f3b6cd00085386d5408c343e8466e3e8cf9316698f3dfbc36ff461b451a083944eea170e4ce8985ce146ab0b2cbf1edb19f98e130292a5ce56c24e9caa61dd2ec18cbf5d85892e49aa68d6e1a67b064391303d701429e5f227de7335398dc12bcb44eeaafcf46d503d92d81df7f3233333397e04f3f64a416443ee3657793f88c17aadb4f3bd3a5ebf613e97255c94e5af6e57216d1afffbd1d8b2829c2bc64d452e3fc463f57bf285bae7e48eb08f67a9498abef3511beebe409fc5aa5a0be1da3c05cfdaecd5a25dfbba279f3c62807d6acd88fe6cc2da086bf3c00126c2071e2858c9a393ac668002509941b0215f142a58e13b19a2761036e717203289383a3ddf9b81201eeeed3a70b525e84525a9bb2bb57ea94d239fdabe539e7f45a29b5b40164f90e717e6843ef199425c2950912254a6b484e4ad68e2a07c52b8a2a17450403455bbddc5b410be4c9765baea85c1097b758f158103f5ceed2a10d1c71c4e52e1db4c8b888175ceed2c1090556c8e2d1eb1ac4e7d2cb3d25dd4a349b8dbb8e19f893efeeee5ffd9dcabf9770b7b7f57b24ea1b957fbbae7528faf80463c0815dee9d386a606730e832330afcc6dc92e87e23ee6774bf5b92b8df7390fb95b9df835f9238f7db45b9df6eec7e4abc5cdc06bc1c58cf54ca801e121f2087e5b0755d7affdc7a891a0f183f341a026e49a4428edb2a8455a1b9fdd5a644e896418fd19811c14ab7e431546b8a38b9fea2ad4897ebff46845cff9b113bd71f77e4caf55fc271fd99b8575585c2bb7a611fa88e7cd0a29fe162e1eeeeee4e410d8818bafd338e972883c2380ddae54af1ba138e28b02d56a8f4b9e3052b2cbad3231287a943ae22ab8f8bfc6d238a26d298f9b71e97c888ff37d1d673467cdff77ddff7b148d1377f109cac087b3207f567d82ead2ba82bfc7edff7f4ebd2c6a5ef27e8fb95c0ef471ab95127559288b402df5f742576b63bc0cfadb5364741a8fa543d5503066fcac506bc5c117dbe634f3555dfea7710489cd5fa483080a24dac5634ab999b2aa6e7d6c7a08d38f560104864b189d573e74a353a177efd7935eb183048e85b9d3b6ead4c7a8a91ea5327429e9c6efd529f288918648a4d5081cfe4d6ee39e7ecb73fc9b2fb65cfe428c039aed8a0056232dcef69cfd426d0e8243bb3f4519d5a75f2a682345557bd205bd4195963e642b2a87bfc9b1fd5471af31a44897f7b57bfafeaf754fda9d5c295665fff458c4e82513f85bb530688d9714a29a529e658a482c36ebf085044fa5e7f36e27a5cea5b7ddb4a25b29a2aab938650b9f5b9d6d91bd2a5a76ead543cd4da5cb7be9d258e57bffe14ab323bb76acd392737b9d4224011fb1b2c04940ff8ce0f682b09608cce77436ed9585942b26ed95a42a26ed95d9aabdbebfad39e734efee0043736d10aa8d2e5b85ef9911fb158c78c616299f4913fed12d2b18e0913e997b5cb75ae3aa6b4ddb2ee6aeffa1321114bcb64d74965ddb93feef6e20c49afa4a539ffcaf3af5cb58b4d4c23d7bf32e92410d79b729edb91225810999a3656fba3e0d394ba7bd7ea01384edd9c3e7dfaf4e9e0fbf7eec13712694d9f3efd51f4f109b4cd0a5fd05df0861ffad9a8b43b112c88bb5d63f17c147cc412e426c1baa3bb5a270c1ee846ada52cdcd5aeee5ca9d2dfbaa5077447b4b484c3dd6eff28fa88ba7b7768683a435621e683b552afb5d65a6ba5d5e7ad9452faf5563aa9d00f3ee2f67f947e5f0dc547bfb735145f0d994d74b77d02b406b7c76bc7f1daa731d29c97d64bdbbbc9ce1ae552dc8839e2036b28beaf7c3b1a4da2fad6edd31a0aabc19458d29268257982a85faf8ff532a5583c6ce5f9fab6f27c05a102b9f7e3cc9434b704afbf3fed44095ebc4e8ea0554246e2f263f7fc4c4da3939a2c8bfc9936592103c80b4c8c1cad3d574d006df5d9218a90d4dca262a689570b43ae049a42a78615ac44c103454512204a9cbd14c65cd6e1720f489a9bc29898095f339ede7084fab5159f9dab81232834405094d966f397b84bfbf071372469cccc6459f330fb1e1bc000240218dd704b01b8202e87f872dedaf3487bb771430fb49eb5fedad84ca1449bed7e1f4942d0d70d12754b1eebdbadf49e82d89d97067a0a69cf2643987fb32296330be7470e25b289c9d682d792241e48975bce398164b9f367963bc5fff02e44f20359c42e707e34bf88c91620c4716af9d12469f48d7bb2c902868310d78dae34e29dbd1f60774e9a9befcd34e6540df08aacce9d3f83741248e8ceacc9e3917e08f371f4e72fc9a021ee430556e043e887ae47952d5c28ccabcd953a48bc76c010c59f1f669c2653aa4491a27565e5060c6b0d99305bc40f233b04d848f598d2834b951d4c10a8c90c5c3140b963870446e2d7126ffc93d734e409ab909c2d2455a8e4669316ad3643b8109242c48906fac65997377f72f5f8a2a746bc21e301efd0ae4b101899a6167ac09982a148a03c5a778a5cf962b34309a01bb6d09df3a2b2a0986c15dad15600074fa03737bcdc61939b6b046929a15ad2e59087b39b9d677777777777374fefee9ecfedee5e492bfbe0b71bd28d605354584476b93a8e20920b27cd714e073035675feef9984626afd7a3caecf5889a73ce773aa311c9e8dc6eb26845778f14bc72751c91950b39450d6239679383f922e811e7f3ed152ef77c04b913b475126dc3c30ec5711766fa23f8a5585f123f729ebe062131629467cb99204678847d31a4e6cd9d14c4e63c71c139d9c108941f14b078c9cd9ecd0f9a44d222fec589224ec4c92e6f717a02e7071fee7c9e3a70cdb43bb142bb2b3a1bc02f496aaaa85499c2414a4d53934052513218c9124383ce0aa452d3891592ea1ad35101e783535b4ced57be93ced9b3a9ad14aa41b193bee79c6cac7c4465d752b204c18e21e40888469716f1108b401ac882316ed26439c1d1d3e7035788d84992b51588506e3e6e4974314cc21295441fbf6f13492b056e29598cc3eda6b4c5052b97c4e4c09fadb5d65a6b59a46822daeffa42108928c16250daef0b7181086420428c80886ff569e3130a6206b7be8d3ba84fa2e8d6771277267ea40d67e26c763f3e5f12f82c8a36dbffed86c3cd481182647cab5f33c1a5eff52341190a2e7db7c0063919a8a385114434a6948b548ba2df70beb4d4c28ffcead653a14d003e9325812326074d03bf04f0c1b72ac07fbeb36fba5f09e6d7d529f55b6723e51bd3f85647d4cad61680e7ad94fc9ed8671fbb001ff983e40b46f24f801171e92be83299dde193886c2049e3231aa39c61819a189435316099623ea220a8fbbeeffbbeef330282b60ab449f307dffcf55c929c538cf4002f31d804c81363adb5d65adb4a29525ca013a7a8ee494cac93cad68dfd11d3d9f9c1a43339f09f5ae65c2db19c766e7646e8f9a61636d13118dd98367edff7cdeffbbeaeadf87041902c4db8604896e29d91460e92b7beb1e85b0b94b6d368ff2599935229fc7ddff77ddf079224488448412c495cefe04a7491c23f26dac24f01cf7de4fbd105663cb7020efd3db76ec95c53c747f4a3a2a6e8d58cf2184e960cc6bc29508c4c6187becd767595a5c5bb2ac65bda00bb75eac098772d8cfec6a6744f6226e868f89821a6fb7f3e3a72d176f9c89fa9088c58b29d18329e4d74c5ea499184fedd3eddd979babb83f4f609d332ccaca8aeff3458837552d9651fba610dd6627d6bc015b16caff6ea2fd71559ea2466ab547b664f511b714dc292b06d3df8e044080d7880cc52eb810911661f526bc9250f46b83485517d4f71e9db6ca2c805b2ec6f31ae0d1ca94803fcc27009a4616a84b5d65a6bad48641bc13622912d398291e8885b6d44d75ab204e20836d17568d3a674d2d994523af956e957bf1e23886897dfa8939e6f5ce3b93c8e795d4b4c22543802dff956f4adfc899a92ec249300146d3f458c4d58b0b0ff5b092616b38bd3fc92b317180e37cdec02b3ba274c4b3e23f96789e5e4e29a63be8fc59c80b61b68bbf104e1a134e196c0845b5f8c63dbda69675b6bedf78db37ee3aca990ddfad48325d9eafbe8e581a5085bb86825100f82604c220cfef020c659d547a14f4daa1d965697ac2c3cae2e1831742480edb0d6daae81e4a46a4104a940f0fb3e1004bf0f04431004c913c2ef036760187edf8c2c9bee389ffac8dd4a14c939d547fe369befd8224e19486bcc599b00d5e926dfc07f61dfad7d3f4106fe0bf0fd3560df3f2b035f902f3ef28387510337dabfd70b0d4c2a7fc14203b4f74fe14a4bb425ae169dc47769098ca663b209dab4840f1c891394525a5301d27182f4c609db8d4ba24b712596be71894bf08d7eafa0276e5d2a21e3d6b20605c113532cc847f4bf157d2d293292786b096880df27b209a7515e388d71ccbc16fc9ca25c621959e2baaefd16b7be091f86605b393c261e73428609634aced331c11a9b55bbaba9011260f017eb39d123f3988b4e024917fee128fa91ff8bbe816fc492d380b2d16a016062c96968b892ff8b7711c20b259c0c77824d348ed715e6f3d29113a0f703c71354509d2eb4a30a7a29a5de93ed130740ed28e06ead9dce5b9a3bbcc43cca92604a72628984b5d6e228f0f6cbdbe423fbcc4ace6cb329809596fcc85780b8dff30b3ff2074151f4a6196eddbaf45f80e0df8f7c462a39704711fe65320ab089ded9fea4beeffbbeeffb3efb81b046fc464ca735e80aee37d66bc3ab1c97c96432994c2603c1671a9b983dcf4819239d6076657d656389822bbbf4bf9186e12022dff77ddff77d460f4eaeadf8706f7debfaa982d615d4ebee574b44dbd64e3bdb3ef84db31f8e2cfac81d7043b4b3b662662d790208e2022219b6846b4711d782e308ae1d435c5a43f181202982f85c74994cb44b421bd2b1dea6dd5f7fb4f956b9b66205b754817dbf61fbe44a3d3023d5ef6b0582f67609d98892d0499cd537f7b7b71bee440a175fbc31ee6f6792cf192e93b99b590040412c2795577dfff194d8467452188eb3915a1094c99ad209279408a2e9eaeb4e1627166e001932224e1043850ac920240cd309645843c3133f67a8b879294750c082a2baa183cf34c98186c8902d3f066d00a686a92239fee828c3cf0e0845e667e6079952eb4f9fbe25a91123313333ed1b4edd5a6bc9b29b7ebd81b825db53ea2477932ad450e3cca4f4c85cc9162f2d0065e5edcb872b382485b7b4c5595a6263d9844b56fa2b23f3b38736182e5261a8ec8c0db4b9d1edf62a6f5d3b644b966081d9de56b5646a4f918af9452a4a7a9976999441bb932c52d1739233549cd0e7363983faec2661d8cf037881c8aabba7842177924c2693595b7ff3d671825fe9f7a57dfe1ec3ef1bbb3e8f80762959ceb820298376fbef9ff60368876bfb1bec1bbbbbd7c7a1fb5ccb7eae9d6193e5dffae5572959d22fe9f73dfdfcd6d12f9383633983defa14fcd2beec7b0cc1b14805d5e93e1553a7bbb207477a65a45f5a3695eed4d650d4b763d9762cab1d4b7bbbbdc7b25eeee91e9ac009228bd6a0cceeee3e7dba20e5eeeed327b3fb9ce4bb0798bba8e4ec56453d2a95b2682000002873150020280c0a8743029158341ee7715c7d14800d7e923e684c9809648130465110c4300cc3401001c0004088310619641043e800a9ff087fc73ea4573c88bfb8d14860c8282e38c60a5e10a712d2e79ef390ba79f26b3f18da56941976f2c15af2949b3db4c51eec95bd345e3c1078f22a14f36d6c9eb9f0d70e81cb1d63a8f490559e447acf10b27db147344f6049f52e47be67c62e89447ea711213f8746351fd10e2744b70818204f4d0bbceb4efd0d06bd8802691dd25167c4237b7c00451f9ae17b746349c7b1e5c90c08d438d634e3cd02a891e29c87b825380cb444ed27559bc144265f052468f9c50d3cbeda13ba331ff57318fbd49513e15e811ae087b885c3123ff46792a280b04f40972793f0ee665f2b29db7ce8b3f07462618dcaa43c20dd488540713aac59215d3d732ba347582f9b00b07bd9f487aed82471603daf3513a0bae709587100d1d10e44be80237150dca53a3bf08a16e3adee6cc60541a85b9aa2f2fbe761d267d9c9c402a8ebcf81b6e8c083c91e5070408c462e9f9fadb766a5f25cb9119dd9ec1faa797b78408540c98584327e1af8d59f041460386291274f35450fde1b1a3eeb8028a069f442faf663d389d472a5668e8db87613002ffa171e6344dc1930b386fe58f66c3731a17f8eba8d4ad32d1ea2711ff80a600708f8a6294eb6b1c8128c5bb61b5c6d95ab8da9fe50e8d228bb2a980239e1acef3d4358c05c35ac2dfd533822f196db9ac98abc91da834ca36da19129f720f7932052fe293c426e1d990925d08c8e126a68cbe71033ab068951ad43a9bc9a900cfb31348a95388608f6fa2fe924fa5eef60289198627088cec2cb9e0b9dfdb4d594a5038670971d6894e8e1c1b92d6aad697ac45108f1c2cd98ae94f21c2caa2046439a14570f89a5b44d4af1cf61ded8826a5c0d459ba078c390a6db4c04ee818fe258d4c3146dfa519bfd6485ea9e04d98f0be73fbb4bb8c91f08d1db7e74bc125ddd9d6c51f035b70cf031a3957974ba938a8b20d8d8c3df0afc4dec3714f999c49cd4918fd95941f7d91530c55eb2a1c9ffa6257a5407e60c9ec81881d48142d2e0d9e24d477c988c5c15834fe347813c2fabe84fc6dd3f893337f09c9971487c12bb154c340427b5028a56c81ca7fdd7f3eb2da1ca19dd7adc2089a5931c7ad785e83aeaf19dc421481b1ac52e3661a0747405852004c83a9ff0b25ea20c1aedd702cb764f2edccd23467ce5c33fce67a70a62953a09f9b0212b9befcbe13e677ccc90616b509786d7d66cdbdccc058ef5f25d50988e915893f05a458481a4b8363f46cd8646e1c3e35dcf245fdcb17bf37943ae841a07bdb7892b594cd15db273a826b074ec9b08aec44b3a69ab9d8c9691b41b1aad0aab0dcecb90c5e4b0771859ba65145cd046e48015cdb47eb1628a7214d467ff4b863c671a9165bf869f55860892e605f706de31e6678620393ce3d319985913c478b5e2c8d8bc4565ece78896ff0f260701f17fc19048b3171f44f563c10a311228ec4ec449c354da3b74af0206aebf975340e3f892d016358ea38b770a617e572254667f17334206debe02eef69eb8d81d46888cea07d833816bbbe6cf93f714aad1f874c1622dec376f18fc11b45ae9386328d3dcd76bef9970435f65f69e76863a819f6fe6afe3664a959670318cd173a60c94943029e7a10bf8278d2f17da38354c4ea1b49923cc14a9a2d7ca72fa16ee8585a24b20e514314c1f1dd5d24746f8e451311232345de71a46165a35dc295b2e3faac9572b4b429c2be38e250012e24e90c0eb07face99c35d9c4f13ed6562c38e662b02f36d871a46a7d0dbee95c6f63f3ffaddfa274e136e00be61be11f26a2534dc83687b8bc150a34f76ce6000d00442731b49d2967a2f1f727964f1a9f61bff57a5f58dfec1913c37e46eb656313735d04338dfdc0ff60ee7573f66d3884c5ff97a4de8b56d30e07bbb9938f75dab73fc5af814dc23d8daabeefc448525864d6937ffd641422670db334623511338a7d3c684eb95741917e3e291d041525abf4f43ef705ca08476651032ea20383e8c4ddaeb209e57d5dd50d0c05366dd2515672ae4338a19da536481a2363ae0f171adf1100eb5a71d5a039e4a59551ba6ca32077adf8d79cdd1aae6513273333b5bbc6bcbfd5f268ee4ef04caf790b51c884d3c9e6dbda2c6982834e070757d8690f24139387ae378a9209f41c29fc4350c24fa2f752e5386e04ae632c161ebe7e49efa09cfac1c89a8908bdeb593d399f9398da19f20335feda82dfbacbbbe2adf1e923e5d66fd86d2bac502099bfd1048ffa8531aa98bb68ffc5a44a28aa64909c1651fedc3bea7b8268a310039c2f5e4f24a63c0e660667a734f19c3b85ec31a3d44ff63683fa14df593683911edee980857d7a085c9908c02b131c386935d38516107af6e2208120c572251d8bfcda63064b8b388359aa0f576a7a6dc3de5ea6a9f8af3a161976b5598e1e1b91a0b4b9fd7bd64eb9b7ad97c2976369a9ceb1c8842a33d86289f6b6ceaf798b5e58af6c1e2057c2b57cc7df8002affb50ff2c347c9c7fff8c0791393c097664e1a653cf4817bddd3fbb0f20fa72fc7f0b3567560c7418d8f7628d46266c2ba8647167a479d45f2d32aac0abe1351ed4b6909dad7d5e184bcab360f2edce48347ba834727649a4eb068b6dbab1682ac617b8b082a071bf1b1748969c354b6a20b138cf4e3775381ce606a830f64880604346d4169aa375f970af219400dc9d2c1c8bfe100f92627214446a9167a7d0e58ce9b26c41e690f95b88d448ddf35ddf6b9aa574419ea48dd6e2fac4203e8762910b777eeb6609cb4356bf68e1ac401342e7be9831bf51dbbc9a0809d81f0d7e939fc13e5e8ada390b44e355db953afd82bfa779e54815425a73e4ccf2a4d51234ca26a53bd703db513c573231692aeda305084002af201fa7f96c814a03e2e1e70cfc2cf609e97cb33a64b5d6a2aef898eb61ebe0d720281211f6b1513891c269b6d912c9238a86d24b8fd07120aed15719b62443957ee88e5dc188cb3cef7e5ba8ba055bac560bc0be356df250668f3f9d7b83f0d8dbc327240fb201240df5e2887f93028ec7bd5bd20af5f27e97e5cdb110105696dbfc01aec8a7356c53fcfd013b6fe2637ae688b480cfdbec162e72161c262dbef363ab8cd28103033868b817545669785d229bcba1a7c5ae374a920332819085fa20b06c59543f1d28cbe159dbab979e02d6688dfc8205897ef17fc433aba17da5345ddb0465977c348801b3bb8fd5610d136bd80cb4579e1fb889c03fc109ef4b00331f07b64a935c837eaa1daa822571724046b2bb1cc2a33894e81f5271508e8bdd6499236a991676defb92f0efbada3f12b11d4f499c53ffb6c47e7af83cf2f788304d391072f5dfcf178658052184f28fe88b843dd6c2ebd05e8de2b9f85e3b6e922f55a3f73a736445eef316bd7fa1972ca06a7f82f26cf6e67e52a1ac099496e904ad7816698f19820c1677a0c6e125345cb9174329aebb837a9ed37292bd133da58d4d14f92a4e5b1b5e22dabf5598de5f486baddadcf3e636791bab2a1da773b9927c8c0087e48f1f23b34f1e875ef614848bb786f7536d40feae57790b8bb7f1907f7813716091b8cc56cb7a7b4e6ce0a8c865ea5ada18bc5aa69c7b01ecdea3a0c395d3532afccde97968e4560eb6f89a3026443601afb77b4a636bd76dfbbe12f44c918326ba4d8a8d826f5e935ece5b084541d49b023278b95ec421546528f942975065dbaddf766b0d7a6be04f65db8801765e463eec6930ef5da024c18076afb3d40ad5ec098d0e6e800ff75125a25299a0c08d9cf1fea17dc54eecab96d079138d696321404ce675cab67d98f81c41529ccde3d66f257d6b5537be364d68cd4e7cbaa41e6713b6a72947ad8f99f223cff7661ffb7f2e6f9514060891e1257cff66f05e577acc74d4aa2edc62b6cd7d67c88e471702dd2cf50e526c5499179ad77bd1aa19da69091c1642cc797af516423bd9a88d3acbe4f47137b4cb5eefdaefa1f78b9629b1e20ad91585eeab01f00ed8dca33f31585ae7c34cb6d6800b56ab821413bdc5ceb84198435f10aa8a1b689e99097aea79b887de2f41adfa31b48315e4606e0bbb431db60ae9bdbb5e2c9fb943c06c7fb4d66f969e289c936d1b1473bc4a794997cccbdb41e990589fe2d21aff396e125e6cd98042ae127a2e1d5e0c6dda88a2ec25dcc60664ba0c3f23d35164445b85e09044839610970dd8831ce182d53d188a490c0a43f2fb157851de61ae91f56d46227f2d758fda25ee7d2a1f587cf8039472fd4a5f0b9ef2e1cb322c9a95fed0f225ff9cc7c6dd4261cdd1ab5ad8b1cc7d3df50e6c999d238663dd716795edcd08af2b2dbfd4331f62e225493976164786e583892d4a83ab7385699cb43b829b268115ae92a79e7e248c828ace825bc1b322aef69334239af0cbd12b9e9a897e5bec9cc55acdb18808438f31393c0ebf00cf179835f157f5fb86be1c24730f227a6efc86914af9f4d3abd37acb605a62f220a472a9c83c0efcfd0eb16e00f2fb14a43a9db73fa2c4ca677f3dff20fcf293ab1c6b558ab0c1cbb93c33317d7192ffd5b9aaff79c12371dc9a1f0ce68dd4f311c82a3c64915e6ebaee5e6d0b282de2198a19c3a0ff41ad781cdf637fd7a2209114bc883533ed0a8c7cdfa34c180e1b4977f05b097d9448212325d9bb474da50a54e1d990e26f8f2a31990ef6a2cf6492dc4542397c2ba51812006c5a33e92f1539c6aea20f01a39807e9a0851f6ec3a3be7ba8cbc7f391befaa57b38c76a5c516421bbc960aaa2ac0a0ba414b43d02efc50de3c3f5ad6f6f2a8b9fb28366378b2b27938849f787cd5334133c2f61bb95ec34bcec8cc72fda9f59a4e766fd3418d8669f6194413ea2d7de5d84f9c0305c60452dfb4e43dbf3fa687854fda2dc31c0b258743d648dd0dd43ae76e58835e225adf161752947194152986d38f524ae33dff9243e2c22f4c3061a7be2d58aa208f3f93a4162ba82e082533520c9eaf816d1175cfcf6c34b71d9d5e7f127e834f6cc62393e798284924174f297af92dcea693a42f485284a24e568601159838f3a3e280140ffbdbb68f3c2b11084bdfb61fb91240b3d145f425416d995fec1b317a4f02f64429f04a1d1792bc6562a090910467e6a3b955184fffc160b18abc267fbfe2ac4bef084861a7aaaf2eea97303800a22e3998425ae0fed37fa74fb98ee81fcaa059fec209704187216af60bc6a164f58bb8d06e8a6aeda5ee4283b63bf5d8e28759abc7e0ce92828238a3f947715a7b35effe704cb1afd82c2b84f47b595e98d33e3e6d6c8fa3543dea74c30b2c37a9fda1e9c1f0a0eb0dce6c1467edc8393ce27a1cba77bad462c128ec82c970af50876ea6e18625274148d7eb5d63d23d80e81739a55f93339dee641ce4e188a0b8a962bdb08c692187c2911541293510915eaf71f9c12602b19403c4afbd6d6af60742b78d4d96e8916dea873790a107f8a17d27129d440f6efe8b6b723d35262882ad8b1b410f93cbdee35e5b0c51f8dc719383bc72811e9cbd9f4716f9c33cf0b4ee01080c8a54a0c5b5f09c604221652e446aed79e8f8e9dae8bf5f3b5f23e2fdfc9ada00067dc8839bb042687ae85be3e241bfbd4445ae10d7224a4b843233e451159090faa1af46ffa603ad29e433dd1a2cb4b9f7250bd7082addbabe0f2e349437407e63ecae4174006e5c787e11c967b57fa1c183ad1bcec4b4428aa2df2122326a15c335336abd6a44a48485cda0937d5fd019f92217f22a7c7cfe28cdee756cf6b5d4e1d61b603212a31f41eb9118956fc6c40e301b80f6de03f0bdc9688b84a7a168f884174325e420cc6c5d1a8d04ba00068f10f4eea9b17024d44b343504261aa92cc7ca6a38e9ba4a6ba648cda882eae92a520ea73d608719bc43d14880d89df810245a6a9cdf485945204e46d1b13eef6403f7016f8e93bf40c35c76029ba878145a180a116abd36201645c7eed9e56a75bd912ebd0a22f038c31874b07fa8c05ac6e58fc463abb2fb8cd35ada56455ef3b945a387126de09732c5d887b120d8edba7052670ad5a276454852599d8030d918ff4c10826489fc651738004ff57b45fe25a1e128109bf6ff3359c4bbe6fc9a350ab23bfa5187e8404dfb1b60e7cc6a5c5f4ff25cdbb7a9c58d03fa28e76601849faf9d237af4e093d7101c04bc6eaa1000e4289b9e08427a9bc340017952e136044773335310308f512f4028679385495b3fbe81c982a1c8e5bdb5c56b200b2a1a4cc6928523e77213d00b7c0e2028f931feda08813a4415888692c78480292d144128ea35aa4885d9e143100cad6308ebf01365effefcedc9451bc3873ee13c954531abba09597f540ffa3347d0ac34b0b5b827e0166ec2911381e0cda1d9b0a34460eb98e91a448839fa3c193f7f10772993e05818c2a51301784ae362da9003b267fdb073b57d3d58512c74dc0bd6fe983d6316c927b1535f4e9d864507d124fdd21142431f030cf6221d9a2d449185a71077532614104b97441a0ea26348da25f7eaf4f290748d1b16ec07965a8b43cc62a2520e2e4a7aedd81ddee83ffaa7f4b2b1a4c24118ac40728adc1e229ad8189d83d4b4ccbafda23e8f30f32db0b99e3e7b199fee789626557dfacb84e2aec8db59264f51eaeccfc0939e86f0134b302a9dc1ee3d7e103b686b730e92fe35fa0c76c206390d83162f9f947821b7f9e41b58b87c6e9c806e8b04abe88951a57d06db485fae9211e705493bfab080230a4b6988c6af2a6d895f7f7a865c4e742c4bb8ddb51a9ba21d0939641a2358f66dc08c75f7f9e1c4dc69f30ff7402101af97fef915c4391b6cec721dd0bea215764d93ea197f1aed1429a5e6757f37f652b30b4bcfade8b1e7578485583bc1f8274d63ebaa6bf5d55f171d3987004307ca4f64e9e63777d3427b2cf76eb48eea6da7f7b71a4c710276e3fd19b976f0a0b421654479b04f2d85e82d3d5a234bb340fc3ca2facdaa2b6c9fc044161508e4887ee513ef739eef009df9126092c9cbce3d1429113c6f98e0187aa29f267bb218c0af0ffd95241166194a673038454971d1a8ab26139856aee178e87fe511162d8e9da82914fca267ee2f951bd10ca548f51ff072be239f9816ea50172f8987e8ca0d4e728e2f04162aead3b14cff09cac713fdad6a813f7b890a459853bff88961e626090267aaaefd6cd0d28ed1b55ac3588879ba69d7a28493c6ef64e0b2adb3366d5c595473d38f6e5aca44c9e9069d8979a2c44076bb7f5a3f27b296973267564f21fa86549ec382ba4586f22221df9c08f60499a3adcfb805fa38e4f990cb2241372adcf7a2d74e2ff4300d42ba949475c96d67c097a657832c20f2420cb3323cbc66b863c6fcd23107f3d29c99683f319fd29cb168df98dbc1eb0f4fc27da44427a2817620a892efe64033528dab2a3f146f891ad18265c0b2e67ba6ec79c394fb83f6e4b7c6ce122a5e2ac70aae60c23ecddc2226ba0de4ec40c4ab34b84bc3e5328026d5b3f921a0142165da76345a321421dea19a4ec0f8cc324c55f7d232b9994fe3b142f0213e6229597aa24e8017e9c7875c993a66ddaee811c5c04ffa4366cd1ecdf2c0acafce7893986510b0f00d11af576b584c26e780c57d34b238386ab1e461fcd95028bda7fcb29754d22f9415f9a67a6f100f345a390fc6d950fb6231cd5ccb2ff3b0a4d0afc2f8bea3b3786c6998ab4e3829a542215e023b9815302e51ab4f11c99ea398a5dd28ca6d33737218f27908110729689ca86e845925541d732a31b515c472586a0462c374ec9ac1732d0a83bc2a825e15b5ad10c157d361b6e13704d481d9d8d3b761dcfaddc087d607900fd1e0939213f53de8bb8cbfaf7c6b9809f847fe8c013228d050d4ab08e229298fb807608648280a8a87f1fb0641e3bff0984d4fcfb1396eababed00521161fa141191eabade739f31dafefa52130419e7f16c753fbe8ac87cc3b483c6f02f5ae8d49e64e70ec3a61e38cb79023d870de025b4a6d7686cb420e04321e0bdb9d967abd179d55248902a9c0a2998f0f6e843c1db7aed3734249aa3182d6507d643635fa5a75256587b5f2bbaa15b98d120866639718cb40f45e4007d1ca1b8b6300a1b705ae2057b6df815cbe0cb5dd9330783517f233f59ea45104a47cdbc7e18411acbabe162967b12d98e4c1cd164dd750489780a60844ec3d436adadfe0b6044a6c690b0c00c04850feef34393db3290ffe52bd43f0414b13c1d3fd162c89f6a136854679cbe2cce58490cb80a55ae3b297c6f5386fd1f040e482bf7529e786e5587ba5b0270202563ba7b6b43d8723d42a5bc08ef34300ac191705b944c1abcfb4ba7a77a031b9c8d11a066fe61cc16b6b9ecdb40dd3bad235ab4d5aecac495c96ddf988324534984240f57f0be90c0a999cc1c6f82715fdb93d9ef12199cf299b84915f5e459caeb87bb2cface4253241a21c370333116568468b73540bf3a8ab35de8bf9e3b021b294bd2e78ea8c7008e9a4a495990554e344ee4798f9131f30a600d803955f7588fb35f490339bd2ee6b1130d975282866cdd58118bf52230fa8f8696a400468c1aa8b52067910522cf1afdb9be47fca78644cc5d31cdb3b379e2c64e346004486d1e7486949761b68e2d557132519e295b27300e3cd5c2652bf0b72f2cb520f44f660a3750210465bcf1e939eabd629ad06f43e48c1144dc88c80561af48bb27d930c96b8c4c00ffd92fd9d84b6869697efa8cf67425952bd865196d22fe547629356eab6980752202b17c5338243cff8b24288e1ef61c0e8002431a15452001b608d91e01d133740e172ef68fc006d291ef8c3543fc787422186150939fe155f9a3fcdf3158a3fd951eed0b2bc9975778916a0d434f9ee45c49d1036de5e05888af2714c493c0ee73a248a7fa792235979e6acfc777d92a3e0a9f54221bd17d1e2e9f20356a0fb75c12e6bcfd9f46b9ca5c18cde30448409c00cbd07601ad898522cb5b2e316a3c2a8bc8a72ac843e5652e76f984548d4be4834f8f0ec7935ed02f30590e478a938ec6f07eba7029b858912546381e743ee7b3f0cbc1eeaeadb4618ff3837960fe256043092365d7464f1586029f0c1215c0443a8588019645599437c24e1f10f64d73e552e8d9f38827cc7013740a59c4058583e45919a33d098291e1869ef07796608468624c3711e0995b852ea5b7259c9c5dc916762c1d8345f2ccb53f2e0094133dcc48f1ef33e8dc83259047dc2772e0cdf45040095eaa2737e633a348a796aaa257db04f1aa7d8a22bc4156dd77a56d8c97f394fed28e9c10c458864d90e566f84a74e57ecf81f1b961fedcd26b50476a32f9daaf41fd1e3a69bb4d8ca8eee1f5265e69b1740f6c3b5681f36b53557dd43d0ee3a97499b76e6088d6fd5ed66d06bf465094d353c6e357506ae28e1b1057dd375760c9271eff4f3df35ce0a3e214794e30a8a0bd0c1dcf421f6fdb4d086ea8e15dd5b81e2c00447e563824fc672ed7eabf2cd4818b26d2ac16f9d71249b62e861b4132327ba18a39d2d283f18da07703f1e5f5ec886b14bcaefe653d4349d65be6022761c5b4b40b229a95e729589caf61ac34db0e31f7822719d7d473d86ff0df34a80a7211c289a0c0768a2f7c4486ea10cf4678840f96cfc2afcca6574128c6895b79134ed09242e8085271602ec0fc74a32afb8ab47b0fd14f423b9c1c7bae6576dba4e6ea50383f525ecac121084df6d71da0f8b2ebbda65b84acf919af5b288df297eed91ce5e0e64900b363776e30a977de1456c0d1f544617156daae885caddaf920a36613dfa127a9d06c0dc781d2a8cad6c8056838d22017447b4d9ce6266adfff98ed589161e7cb222dd010d9de9cbdc32a4feb7d0d26934c426e076912bd2a0be83ff94ea57387bedfa51ffe0321690e3a88882aec199bcb2a203a10fa79baef3816a668cd039d86d0287245190c6c4a7aece1f3356cfab0f544a99b2eb0abe21fb017233711519f7be8def50193decf76dc48a54e8254aff4b6d547855c4ec706e139381f6f121874f084e195033af4a236bdffa28f712430749a5b6de1be55004f97d3e46eb13f6052b6a95f86268b41d328598a3a5983d0650f880d230df16b89a613ad83fcdfc853e88aa221d633ebb8d8717031a729d0de408a3dbce230dba12bc8fec94b03f2b15f691494de7f9221ec47989488e424bbb332a036c90c0eda215a18ff028e59a51f0138d02c6da286d5e1cccf245c0f3e53ca2690bd5dc198c5eca08e798a4cea118cbd7f6a5dd0eef4444ea434f48e86454d953897573755af938c161dfbe5b85ad354456237e5862648e981f3dad6cf9833b6e6b89041a243b23180b94eff4fc84ff2c6cb6f55c1eda2091b44242403591566a6f6c4d579944a132bd232da7e959e772da3bed97363843310737f406e52247fdd0a5293545a13bcb2b7cfcd0e14957dbb712c5241ed22c27bb4d4c2e86ea9cd291fbf532c2cb0a5c7fa414bfab925ed14488d2f2d81073d5d09abe746b7d7e288bbabb323d7d3e240292cdc69b5382c41e4124b50b8de05b5b6eef063d523449f190e1a409c0928d7cdd5b6e6c3c7e9c004ac0f3cbfc0cb5726c824588da698a500fb3915efb59a82c7d34f2400c96f1d6d96bdedf55434b8e0fdce37066395e057db754388e6545061b9ea244f826c59b9e5ad4485dca71d7247d0a1c1471402807a7e5ca19b49c79311dad45ab783d1250b56a5a48d59b7e53efa393fcbe0acc72b1974c6587acb589fc3e25fe2fc6ee8be1d6bd8dffef7f4b0ac655fe0ad04d2685f9a878f619af48dda9918233949c8256f8877e0f54b44c29845b01f4d3ca9a11c5e64706e985dae248ca9db70197f43d480b5b04a0f38c2d0458d330e1221ec2a93c3a90c11d462383eb5641747b65bf50ed46f96daa9c12ea372da4f67fd0611c0897873ac4489196ea8ac22dc0e4360577b50205c5a072fd6088c59e246e1dca86ceb33c88244111e35f5a503342e2ace64bf934d7cbc52728109123e8b98ca8a290e8be56a270d32a3283db45c0f5640bf8edf7ef0c4ed2011fec32ab5641f9b81d64f88cee88965cb6f9cc83730e26caa924faa52bfef44a51db2f7384f924947e35ddb37b6ea33e15eed5598cf54c2f5ecec69916ba344f4b302d1bc8472a6d6ea9550e7159170d2348b6273894bb384ef6d523f5c5cf0780d3eaee0c1052b4a707f9393f56777063d52f4cfb1636eecba087b56484ae7900617b1f544456869db99cd53ace5ab1219f71a3c5afa631b854cc887e75ab14c28897f7b88aa146bb0e1a272651b6ca0aacb35fbe09259bcf3060bcec6914e27499b81f19becd4ec3d7926b0d04c3ab59afb58987a06e1b7fd5621e8db165c229f2b1a5b842789d31e2d37aa2206e086257beebeaa72457e000a90ae415b3ef4d98510e6272956048d5cd7c9ca07fe236c62dbc102206dfa824e729bdc37030b6b3d4a402e8cf9ae3d4a9ffcb9a044e35a616e79164abf757021a7bbd443a12dbe993bfc4151bd45ec8297f479037c66d8fbdf49df353444f26471eb85d69785d7e8eb0a97298faa98ad4f422947f4c8af4edcb1624fb375357fd475cab97ad8a7537da246596b2d6d15df43062a9b676e16405f3d7e44413d311a9e80431e2fe89800672f7d75e7187489f2aaad00497ebd0b8a330842acdf40bb42b96eadf832546b5714bfd2a3e7c6b5424801e4224a07537faa85283893aac21ed4ae0255931d45ed90337bf4662e42641cc5bc8e196fd21fc91ce005092cc080f6901d4f2d450aa6fc582887906fbc4c2e0c0886a5a362b07c309029a8b601258942bce2b010b654341a40acc00d57b93a003a8c38e684e8a6878dcf9937049fc28ae78c1ac75e2bf75305dc6e2f9d1f6caefd971d0320bf8ba8475447f58ae39ad603c8639b262a83f376b79f62c6d05a59f01c2117690569ecfd91d869f76cc08d3b3f5a077c0905cd2a127ce6b38e51dedbdd58f02f8ba8b07862f9c99dfdba72ebeff51c25b1fc7a18dfbd834d117cf3163e96c8ad1091f46e85aaafb44d38d4db9543a5e4036e53060f4ee902d10aa8877736393605abbfcedcff37eec32f716a01a8e64540d7247a535d3a8eb1e58dc6687833f876db37626ef10ef45974359a1b4a09f7baf1caacab8cd3f46090d89135b3178f9674269dc056724a8546b06fcf3524f5922018fb21a38d446378687bd2459c30f5fe0f9191304f65f4b66ada8eb79f18aa3b929a6bc5bf43a0feb63b3b54bfcbafadbbe8422e1c1fd2028c3feba154ccf50f92327815999e42244ec05b791240d21bcba5a607613d9afad4634511911eb61b2b53dfc8af3062b08a8d497643170457037a454883273a246b24044783e780494d93d534842f6803464b57eb6c716b3ad890598a273e3b299e7a2ed097c07b4c1e842ef40ffe7355b9ec228428c48688dd4b33173b397ad79db41f3e11ed8722176767454594960b66a7fb0e0c0f6c096275b00fd338842b6db4c84347cb633e66ca8d197ffd44d3d2496b324efb82d05c34278b92d7317ee41b431a9c57069380b98ea7d637ba3684e3dd881a5292aca4880b41e6c74285f1a63382434d1e4bb1ea02c59521f6f8531984a02624b7f2aeb64d36c7c0eddf39b19d7f3cf07b6ed33a83f4bf4b9ae9989d88857537a7c61b65d7c746eb371252c6a5b6af08fc7296acd169d453fcb0737c094dc2c76e6ace5369c3cfb356973dc08703c22799aabdaaabb02cfd6ed15f890fe23d77f9d521668e84bd5c952fcea3efdefc31f2c4d3bbc102f3e2c1daf5b6279184bd18a77cdd39c5c4076311b3fdc19ba0963da1d1aebf5f752dd87b85be9734f0e53eca1f9143e5b6ac05857daa1466c78a0d03f4942c9cfd572013ec754e154229d69cb4fa46c8e14f513f3cf541f5113614243eb40372a73a6dc45039a97e964ef61947b70cca593117e8a8196446e12637f0cee80d7c0397c354218b2493574e28583c05c420788f5b978681ea9648e775bfc0b8af336da6d17bb09878a0ba32829a8096c0595c9589f116d6c2967d838687bdd86c6ae7a1457c8a760c14ea024a7e12836c9418b6a521c99646ef97dd53153a55ab25e5a33ff59643f09d2f2a443256d524f314f13c5626944a0e415f1f6f61da86600ace922a2fa8dfd7caa94c107c695e5757e6f5a0bacd69d53bdeb090c66d45fe87f01aa3c5d43a9fa59f2843837b1fc9bc8e6e87c02dba347cc51c1ba9f33e90110e7f813a2e367f78624ec394042121e9f8b8e44fee8dbb116f8a49f41625ba1a8d9ad1d4afe1a98eef0bc3fb1ce345ac9879895e47151d91e2e4eda84059b61e1c904812e6717e830953d58bbaad652227c1509767f387b40f6afb6434ca608e6fcc5d5eb6c43874b8262d4f56773fb429f20d3db499e6876ca9d0d83977ce1602db595b55626480e535158ad335a9f86f6ff215112a31ab488746f2542c89787543062cc553c29a69e417ae3c710ae87385e595a1f8605c7fdc1aa5468535d787b149b9c38ba8d81b066423d87f254c7c251444306d77d402f254f8e6313936d817e7f69fbfc1841b423716c194d770c32cfb261cf94c4266e660091d58388a6218c92480f4c606836f634384b1b378cabfca08ea60509f8c8558a350fc6e857aa3227f90181cc9fccff8bc6958f4e5a202353a2353251cda90e6a641f10fc41bc62f95f2b0c3bb9b72514724d16906d902103b1caf974832c5d8f4d7fdea9d5c81c3f8e1ee2f5095a3b8879bd5d111fffc23b61db436563bf596a8930056313967bbf409fd4ee69147f5b25c2eb32c7c396fc5e265b01c211af42b49e69d0ebb9d462a76223a24eb178fccde99cd76af91c1eb02ecad47ce8e8950c0d75f3779e9ba792fcbf26b8f63fe76913a42205e3d8eb6bbc551daa6d18262a334d303785667e4523d8cdef84a5cec0e83179f1f971b0df75a07e9887d95b6ae7bfb79d223eb2df95ba383625217a98b473a66b3fe6371d52b86592f52df0f63962355c5a9e93ade295445fbc1d2d6c49d4b335ed7c8995c662c9f1d8415049eeb24b559ac9d6500de7b828c799c001aaee043026f8870fd1160316f9ae03030c1b7469ef0af1bd83478e844704bde942c3335dece198b854ce0e96f545cd0b95885a8e97c1624f5da483de288d8ac74d1285d2c1fd74ecfc8cb57e00667876c0888e528a27559b12ca4ddc487cda36fa6bd2ff4f2c736a5daed90761d64d980a92b357ef0bc7210dec05699f81a10b29a8b784986f37edef1a4f3ad68558f4b38e543a981d51f44ef7ea8d7a058102c428c3593857c740a6bbb40acdad7aeda4c06c41a4e3976835b1bed5ee16644d554f63ca80f3f968896d2ec521ce91579e04a35bd1de50fe71cbda7986267013143aa1f7ca22e0d99c61e0e8a72fa604f69312000049a16440c35ecc882efa6930b5a0c187e1d1cba96c2fc04532c376d201ed31928f8930800a19092b1e7a3bc32b8f62856f8356d7d601bcbf56625404a3e60b3c7bfd95115abc50077f5820282701237c8703d26bd18c9f06a00f89ca39e416dbb65cbde86c3a4480cf4151707cfc2659c1dda31860a26afb022210daefad2369324c2f9fa48104b931d3b8a6a2eeca453831bd70b6c7bd565a747a415c22d9d521266d583ba0fa1756960c462a2fffc74d1ab4a1737d12bb7a7374a391544af69e6f36dc18687d603d2643d1e5748005356932ad3918d4949d744e102fd69244ef2f0c50302cf0cbea7e0a7a23fafd662616b92e15564db9a5bbd0ce1cb044e00603cdbe6fb4cf3eaaac2cf53740a31249389d751b9ab747c4debcdfa955926ad3dffb9c13a8f72453a329fd51ca5c632b63f9e61f33fbfccc4d68fe40390f5f14422c0634497ae05973c481e773b462a1e529739188983043a5fb9757c51a571f26b481a63be01e5b4ed273d34dffb93034ae0746ee952d7185293e8c393aced94b839060faab387187bcd507facd92d8f78f176b48276e298c1236d3edb8ad44a6694dc5a91838cbccb68502bb4318a46c9281e545f2549a5493c026fb762ec6284ffe57729dd3922556630100966fb982f88b940faa5049dd9c850f0e8ed9832104e48b9d8aae8e8634125a9992207fa9202808a5b91c30e2dfa8f1cb30c12b2f6c108433c46ac9f0eac6c9d6c203d9d96879e4226afad1046ab89355876eee27d394d09f570ae79e063856d7fbe65d004b70c8dfe47f83dac4b6c94c61dd926b43cb7a24306e90febcc2ce12498866ce3f36c1d32ba3a50d27930ae8a7c913e5c6f3a9e076be4bc27990c8698e6a9354e9a70df1f2db9e6d6a7b6f783a6c535bea065b8aece8f4d052591752fdbd486453c9c611b4474a1490d3fb862627e8825725114864bbbdab015f1779a0658848871f371f3576add4d3b61fd281f9e953466e043713a290202bdbbd7f0cf016c9956084d96c56ba0d2a1002f8bd6279ecb4a65d5f6b5f812430043e3f7527430310f2c6681568ebae64ddc48ee4d172d21d76b5b35f374246d1a0f111d57c8aa6001b0095a952b9c415e3eb0abb20391f26bf20c599f4fa205b1269d97c045068df468628d3860b7501e6e4deaa493864122bf31949366b4d846d9ccd29c73322fcc6851fa95cd14e1b576e169763a959072fef05954b37ffccdf234571789743757a7c3b1b76a456d5f9d9b35d1c4d27453875abb4b0f2e3e554608083443a0e0aa98878d4b1c487ef06da1cceac1b5c0a9fc9a988141ddb04770cf0d3a0f2a37a979254708ceab78a23d751165b09d16d400a0f32c7ca269836528768ba5eafba13d1005bb8723a910b3593e044909de2ab2761bf97b1ec5c714ba0d43699e347e80ceeb4d05dab9028efa0e107437d0d2b7c7d310b6ad07e0d240d0b212836bdab9320dc0454f0382e8b1c8f0a587a8a8720edfc8dc3b26fb60303df3c7b444a4499be2a4c5785cdc3435306386cfd4d45650688397d292a042a0037e75d8a716e5a47081ee905c70499d116f3279a4ed867d944fa472088e39744571d549b5a5eaa474481d0bb119e3ddb40a57c7ce47ced0833c2bc090f2f3dd2f5733a2a2b12d8c0dc0a098ad25185de7d0618b70108d287b13f1b6f26d45ec80b722b34b3b8a9ee0a3a2da158bbd064de77ee1b0f4e715fab284287d652b3e8b4afb1a83116d859a0701957f27b8e12e31a5794b8f8466bff8b9bf9db13cdff2f0480d82cb85c7afd805d8a16d85e0c5412ef2482e977ee4413b6c377711405d6b5d293babb05f7740e39c50e95f51b242e73e3b458a428340e1a4083ff0d8961aabbe1916a298ea69e17ab94b025d6445e20eb3d2103b8231c3da0bc950647f891c5be9ed78b06c6bed9b96df81a971f005168b4abba983cbdab470193aa2f0856b6924863ab9aadee876d1547f6719584f525cef3d51b96c3e840d50ca997905ed20c61291983b6993d6b8d0cf128166df37091fad9ace6cee727878f025558fb6fd72673d54f10ffc74cedecd1e1cf929ecf81195b6b69c671b2fe93113e1bbd1cfebfe627f18091b6434c52badf00d5f1bbdd69a8e5eaf6d8314aa107efa01ec55da0d6b1b49bcfec08239cda2e54c35ef14ba936fa077511c28790716b0bcfd1ed0b81e2396158ed409de0bafa564844902ff477220aad92ffeec987501717a725555d3e2b2d709303bb644ff144e37d481591a41a27d4a3592faafeb8fc8d8c91ec1fcbc69f7d2c9b30e1e56180b247d669ec60f2a421783e3252f4236280b418f2efe30cc55c87bb9655ac1484ea6bf77a23af45f8280d3c7831eed64dc1abffa967130559f1b2a11627ef23836d76f45821d99fadac20db1795debd6679c530816cfc20177c0e3e2a75d1fa159fea01c42db7777bc8380243c6621f4d2cb95ab64aba6d19c0bf9db12ae7c223a43c6fbd254804338ef370d0c6354974669bf1a49740e047cd732536f75b86b3189671aec46e80af1ddabf3bc692170a5fa61dd9db5dacb4c805371572e69724f9df5b4cc423173851ef20191f9dd3ce0d4545a5cbb6efe33409aa476dd3530ddf246c838b5c3a97cfc5fc03bd9c645290386d8d62470e1ffdb41dfd20d1a17ce881c871038ab0182ece0d40328d70bc3273c19bf75972f7dd40fe4bf38f902b3fb638fd31a534d934b1206c22fa87180196a0e115588d0115b787ea3a8102e3eab81d49cbe8caa130f8833dc3101fdcc5b9c996ecb19371c70a212edaf8b9fb0868c8d16c8942fcb81bb7a6085a81f1ad507fbf50ebc7bf9c6065b76b4def9db0e0df8a0cef58b62c8affb3604a65ae24f4fac7b6294743eda36ee40a1ab6d739b56011dc682ace1e2f905d677856105b1b50343450466ae7a6adf05af7e608ce12fa52b041155b31a26455b7dd2f871caf9bbc938f58f29b099b47473253c373ca0494df4b456581399d494694b310315ea275f306d8f5f1e40ca1b8f038f7693f5dd304e154f9a67bd201ca0e4889a575a1e1cf7dec0ac18399da364bfa7aee77b483b06fe9d975ab24d3a4f1d1455466086134c5f100e9586691be6679b23302e0f8df1d4ffbd256f2c6f697fdd546f668f9c3169c9793991d20b22ef3e86053fef1eba001b98d851382cc0a5f1daf00f7c4913f1661e98b65cdf3c459a9b4862b46461e9ceadbd1cce991b22b2bf91a91d8473cb2588a8034fe44b1a8f4254e7d8e83bad9966051e000b7608fb440d020e53d4e695a46d145a69bcc1b49e488df8c66c961a6b1c5a8f9a1809262c60c00d469ae4840210f224c0d5062b02d2e298c049824fcc8ad3de5c82f9091b6e2778a6a4f3df21a093c926e6e324bcdeba3d402b007110bb6c61d1dfb51134ff27d7e9511466ec9c14a5a66354e5c80b7397f6d3f9fb46322b9ea8cfa08b5dfa8ec6afd44b11af1a7d61f80e057418320f56e15585a99cef0461dbf1327bc2102bef09b3e8a118956629c141c0cb2a2a26be85e7e136874ae216ad16451e330fb0497cc9ed5bccd3c560d2d2c05cfa10df63511fba98d46f74101bcb1051e7f4d61000a4b95600c977dca618cbfdf2270560ad9dbaa4251f2c02652ae1d5d41521b3256142a607b3ed1f698fb0803d4a599b4475c305b6cef50cf91828949c9257d8ac1a8b2a2cd0b2949a1054a501f17f20c643201f498d38d3f69fe1652c93469fb1e0b6516fd048924a632a7fd2a53a29ab9b38d79379212534d9cc85f99dcaa8aa0e76327f05a8508b70057567d120b2424365dbc37e23b6e6eaa4423e637b856728791568cc9b91ed533110075765a283d2601f8374bcea84e12bca06dfd7598b1ad8c2818039239506cdb4b861dd6c7be86875bc64545ed9af097df9baf2ab7a9ff1834d32e3bd1c3b3ee1942e415d1406fed18b393980a4bdb4fc414a1d081b92bd64c13c5fb2fb4e89ba3c8b6dd95b957f61f38e1a8b0b69f5aeb0624ad27f5703d05b813c64ad0db9e8b5d944ce40a5f301cfcf3c649e407443b92b905762ff89f930155c66b1c76e99cccd165b8da867a08143ffd523846656f145ebfd91b4c63d0d983a5a57221b7cecf21a370918da336b411f833ed1b1805a3cb7a8fda3db1d2d034248234b27dad3dc4a02abacfdaf3ec423773fb357a75bdbf3766ccbb82f8d5e8ed16b5da8198938e394569cc23d79a4072b354e4cdd16415db8cb3ae5ed57dc92dc397ac73afd525fe02c7dbb4444adef0dbd7045844dbf54eccb6ce006d333ab7dc4942b3aaf61a96adf47131aa643a08beabc88166bc2a04a7164c23bf36d33246a4b493b69374861885b9075452fbba5f9a4dbe6173506a2ba33918e3dd04aa591159bba28bea84c94abc8cd09aad7c2e92b06e278fd2da20ab82e9cd1c348f0058afd7d7734b07c74f3a644648dcc1abde18bb7f4a0ebd5f0dcf18f4f2faf37fc7eaf174b84c7524600823a520bc32d498a68e281f0670a6b514f5aee8c248a068505dd29b029ca2adec44960352594910ecd3b8d033d9e80be3b3bda954adb842d8bb2e1260af852abaa6a802a35869f5d3421fe44e5c71b53a497f76a4267d73a4d5e9f13f976dafa3a834ac4c227a9e657d1cd10f81ca5e56573fc27e14649659a88664717130be2ddbfd4a82ae379433be8c8380282cdc5bdb43c70b4c1d6489d0c6927064e7b45c46f665df2cac9f0702a1cb46095b188381cbba0793e020b4dc482c576e743730e7539a98d5d508e2bef894778ef4a8c76b2a20934d646e9e19fb0bee57339a47e1f2e188183a9f22e66c964133d7421610063efeec360f9e506657cd22c5e18f05570b7b6f88f89cdd80496e01b12f24bc9133c421bfd8b654644916340c8070329b3008b86700fc390a10849d74f99abd8cc333ee688eadd32e98baff5cff6f45c7b349ecb49acefa9420d07300fb54100eada486eb75b24973f4c032e10f6882660903904f87e6f9c3706a69986ab9593a5fa4aa0eec3dbd7960cfc7cfca3ab32b435f53ba7d3e152522150dcbe62e3a8726ec7dfc10189c0fd5daa15b5b4ba2526de7831f8ef0dbc0889f85c48e1aad74c69dfc3363da0edd7098d992640836ecf0dd10eff2ac702213d14abc58277c47fb21d9ea676d6bd070ac8aca07f2e58f37c0f8629d8f26bff39ea549db90678ed5eb6380d005630451b97a7863f1a11df5efc84b24343e9cae58e6d35eb2fc76885007afbe447a2275c1cadd4dd4f60f6b58a1250ac376cb4edfd872e67249f24fc934cb3716a2545e5c0f31afd0fc2fe02925ae67c708303489ced85c3f13bc08722fed895bf2719e5c738f6e04a899dfec5d852cb12a0a9784907b83347c76b373ac4f75bbcb503ef2fd33f4a877a3e8ab7c4af54734e4bb440355a388a6a5019f288143bf1c00bfecd7debd4ba26f78da602482b175326ba7aea5e877a19d85224095008bf04fc4c056aff7c88b3e640873e4a42024d88e77680de2a25b8d1ba0847e78c125fac0e3017a1efa0fa9fcf6d14dcf7499c65409706a367efb56881f2b675f81321ee9372a051598b65b7eda23eb9da3b48aca503ecb3238f95d0efbf182b04f10046f5433c7d88c797b8750778f0400fb7e80a212fd5971dc7696d6aef60bc0521fa8c74bd543aca64238dba22e4733c444787f8bec45907f8e3ac7fd50b7d9478e5b6a5a2f5fbc9ace4e8fb670cdce9ba8dd0224c1895f8738ac43928516b5466a64790ffc0e35f1de0230a49284447990c3caaacd82c8268715c2f0dd55503fa1db4c0e1e3a7a117090428063a50a664e56cf8e076e67a26e2a493faa8009fbd5dbe51aff50461353afef4463962d89ef509ac00d65298e971cf2879f04ed4817ccbd84bfae5ba50ae69f265e5da0f233b51e32ab394b8684c4cf3142e7a820f8d21c1a3479e07745d50c856c85a85427d81c2570713feabc44b3ab833efb56c1a6ac0a35088fd1a70cfb219b5c49ba6b00b24827d930bd8a44a419cd9b8c359e3df95eaf1ff4ab57336eedb873d47a3ca2bced1f821bdab1865a85ee1733612887904891b00f94c3ae7a446390bc1b1f5f869875578abfd2ad341f790d06bf225d5d9387f8cffa5a005d88c6a916b647ea430c5a71da8fb6ab468e5e94e7fc2c4a61dbcdda14d7e09aea2f41d747d37c22f7dea11287ee2c159d7e908573a3af4fb26ceda01f66e23f1981e0d7dfdc7ac3a589da47e49a4e5ef12338d20d7aa115cb63a45e81c4cb59509dc287d045a99fc9823e13fff622c3fe04a7af00126f38beaefe074409d32faa41718f15f1efccad8e28c6ab9e83bc2f3a028912f9aee1d3c32578c08c5d277342945b811fadc63c2eae011a889f974f033c15e49b8203dc24be039abc3e42fbfc5a412a7c8fc7e6e8a1bc3aca619f1c41c503fd125382d0836b697615203b0e6b2c7880c888a79051e08e2ca82b6fccff71d2a69f09898203ca2bca3ff3644dc53a2b096e042a641ca4595eb50a51e3435df9e85fcefb8040cecde7109b7ff969478a2e4a4b0715a0e3824b6fab95cfaaadfc8274bdc03a4267be3dbfdc18d811ddc2f218722de25bae1c91065137edd1495ff8779591561f8114b7cbf311213469d04683955e23d8477692dfbeaf0ced6574ba9366ee0a91c9b9ddfe50930d50df45f1b4280156d793008038682dabdf7b60440bebef207ca1738e076771e469d79cff30d916d375fb3c5a9fe6edba5040225df066e6d7baa26bd710cfd38749a8381ef7d43e4a52423b0a1e340f15611a38459644291d5018cf53ab1659c9ca343fd8a3eb3a483f901bd4b4fbc90672677cbd7f771470a3365ca94c51accf8452d6144cecbefbe1ada74b56c5d8293b57e5aecea33adb38b8bc1dc9490e70532f4aa804edbae3373bd0a0a030755761171f7fba377baf63a167a1d562c980903116d400b34320c8687711f8a75d3ca5d70639125a70e711c43f4e5c4dd2409352e4f721bee08b0631eece14f2138487205736c3cdd46c38787ae5370bcdfbabe6ed7a5421b95bda188abd799ce6ec4be0759cbe83688450f7e1a33916c60d01029fe06e17ab37cd3c4487e800e3378a5294c571f6ab2020af18a837fbde99a0eb6cf44734b6f507ac2ab0fb07cfd67eaaa3c593d37b95422ee565aa47b496507291d89cc893159a446e8e8a713c9f06f0199db6edc62da25dae4e6334ec44312f118c744195c62f325b8b9193333294b4547d2b28d02ee694c3a9ab1ddda66f9f81c6946ad9c5f8e9ce1deb9b8251ba6d14d0ef223259179bbe6fe33ec79920c6d9433ae4166dab1656bda102074375e0c35fda7baa53bf8dea30eac0d45af6dbdd91a4a278e981e8c49d0e150ecb867c3be3948ee169899d61e466f5f80a7861484437c5ba1823a8e0d26dfae85e9d676ed2683a0ef5a8aaa7dd4bd6a72e41917e9c89bd9a0b830115c37bbfd80c2de0e0ae6510c102afcc962135b2dec901dc860546e9dc80e79342dc5118066f002908472461f3c5d66ff2fd4fae37f2683ded5a417f4b4ccdce114646210395e09dc06f985b526fecbeaa6ff5187da2e8651653ef8261d4ad95787b1173787f26c5ef46d8e93118163417b7f4976ebecfd7273c8a6ddd2ac242078c2965a873a6607626f0808ae2814da74e9486e67a6d280063566e360134ebe82a3ab5db5d2617e337ad942f985ee8fb705d91f42eea9a63a51a12920fe0daeeb0cad1b07c7ce9b66676e1e01f97d9265e7de357ce3531ecb8de3b6075c092b0db5ba706cf51fc46002ea89a5505c3012c24a076649d6a3e059d64c4f9e1e197bbaaa3ec587b77ea692677717512e5fdfb2b9f4b4ee953cc0b45c1d5765dc98000c00597408846113b005a29e9444b4210051f00ed5b798b0bd46c48778af908dec4df696524a99929401ee04e104f204940b2b90bb3ce773774e8eeb4c89a85dabacb25dddabaa96ea6404b9e7deb78ee3361e0d6e1fb8a3c11630ccccd030b3d65a6badb56ab56ad45e231503b97a5a76d73c1772f56a9e9335df4170db26c581020a068827c82571c7eb2795441d039880669924a7942d7be29873cefac508367982f16af50f82add60dd60661c56ad06d4a931a9096ab0b18ab1f35c6045e84b7d600991b5713244fcc011da05c1f1c70bc72b4bf5aa4f12e09b8277e00224f8f1e4e4e9e04bc7b572b4f9625c92a5e0cb6ab15c127c01c6bad922b0479ec5002adb5166c2d8001f1d2003b116b12115ce1ba6d0fa4b4daaeadb5d69bdaae8d02a3c028f0da1f519ef6bdf5422f0b71dcbd5164ed5a65955d6bad40b1a7bee2ccdd278cf348e8c9f3815c47cb610de3bc1871eca73c6f2153094b51aaa2d9b4146832c5f752583da25a39a56cd973ce39effbf406be5db1aa529bca3b62844b508fa01e413d82ecfdd5b6b55ab328abc7af2146326d3169e5e0e8096adad20a682bf6d45a6badb5de6bc1562b53211f85a6699aa6691a8bfb98eae9525df7d1449d1bb6c022df5779339eec52a0c91a4dd6baf33a6bcfd108ce9733cc804ad5f4cb961bb3d65a6bad0553b2d381b306e3bc1a5561f8c2d2d0859aa7c3b8948d3af31b3627115d225a6badb5d65e6c73c8b5b76dab75ab73dbea56b96f47e3f89599b560bc37f0237c73e335f3010a120ac21a3373fa1225269261b52bbc117a1020eb46adb58a69977c1967aea4793aa9a1be7c797a9a619cf55276f7fec296e5f9a1c766441d15c11995871cc1c2caa106a04224623225aa6910473faa37a4ea96fa94601cc1084e8e0b3363994c44ca19751040040ea5945909ca510b870fa11af5430813274b50a2644c36212a92b21d4141f0587ada82fc48ca0194032807508e1cf6db3ca0a41c37805adefaa3ea4509d32ce9e86886a48495a31991391b1c21081c76b7101d3d4619a5b70b017febae401dad1c1af1526badb5d67aa73079d86d160b04a7a4be2d3246d3a226880b203a2c5a98b6074a23630a484989d227d55e6dc71356aa9bc958489e5d04692890672af5456eeea28e8a489e958b3af43bae489e330450f886a9b9f42c4989c969c6a47483a419933d610c0e1b09098bb5503ec4e0eef50352ce9892d804c61e4da389a14387f62ced63815f8d19b6cde996974fbb7e85c3fb7aa93c1c150a101ac9f4722106b49cba2debd2b5d65a6badf284fa312a451639264002c99d1face5c2d463967474344352c2cad1acd65aab4c1271fcbd7881028a29a6f8b00c87d2c8884a8fd8d354068cbdece5f8319e002d173dc042bcd054e4b5d789a6e119c573cf6edb76ce3927f5e8aa79efd401052526987336e9232bb23ecad2525a7604da0f749c13a8c061775b585b6badb5d656a96f3f05d4a0d71490c0d188279c7234420750f95e9cd8d3f5c3a834800048171109fa0f893af90a4eec69223a82dbe2056b63ccc1122dc1063881b528d8c183282ee1b014f4eab67b5fe5755efd5651e76ada37e448ae600d9d154c58ad2801724d79b40b8164fab76d5b19747d2df2849627ecb4735c4dcdcd4d8e37801a841183d50db07972448065a854caf568b07cd478c0bdde1701fb9e04382fe509b1404db34b30d45ac10ab672c05a6b4da53e20a52d2fb7ffcdb7676975dbac7f974ed6fcdb48aa1d7a569456abd5daaab9265390d9fa74ca7af5ca3be7cb30033a422499de2f72b3dfa16db34a42b0c4e404253b32ca2245260333beb0738b17e10b3bbbf8d8352dde058d8f2a459dfefe5f010ee31325f344eea722d890f1e12aaf647c88f3ea657c78f34ac6afeec766c4f8b0b388f0b2fb89459d7e9ffee8f7d1127480c32e1a9301f0fd5d64f336ef7de1b5f9ff426cf333be7035635ce4df8bf16af50f82366427c217defc06002fe69b69e385538617b2728c198b853364b9f088c81a2fe4720b8f88cc21550a670ea952c8e5902a85ac1c52a5192ff42c116ac665c9fd292fe472536ffb6283443932e5ea838576c524282ad24aec915c54003561d1075e0ee3535c228be293110f483994474d3c40bd5e2f7fe11c97665872b8f21a5d6303d3a7cf39e79c73ce39e7acb5d63a5d065e2aadd48239b4d64a6fdebf568a6dcda1947a92526b6bb4b67a34dac0260c0deeb5f6beb5f6de7bafb5d65a6bf1bdd75a2b238ebdd7edc735f8442d6df9749df2efddaea5d6526aaf03b0dcafddcfa5ad96bb757777a7dd8f7bd95ab7b57aadd57d561ad0f941b81c3faea67b4e8eee9452fa855cf6201eeeed6830fe0c73353a353a6524817aa1fbb65d5d76b4ab6a3169bbc1a2353c38bcdffdc41002962f14ad64dfde67b5c2d8737250f6972f8d5422cac32c490d36c90854f7c9eb4ad34c0c4a15842e29c906381e703d53dd275696d0a108063d68c10f38b0410dae402145882641c062ff9dedd0c5053388589480468be204560575a625c592b86e83d795ab45d1841328982042cc0b5f9a9a76e081e6051fd0f0258928a00801ebd5afba1c9b7610c10e33ac6c13b3d60b6cf92afec0bef287721e50423f8ac49ab8bbdf2cb3d65a19e030fb09394e53100fe7f199c162e7136747483addbd1edd28a7942d7bcea79eb5564a2ba573cef91199b5523be7acf776d17fd89281e28e7fdcd1385a47b03eabd64c358f0811fb4476ea175965fae9a099b6871ad0a9158965790dae419334f50bb5d4dc34cf8c385c111fd42aba06494bd9dd14fb0f21eda23351a7ff9bc9fee0a4e15076276483ac179392b29d1a70288960924812399122155913094b83eed43c3e830243c65bdeddee2edb299416929456ef1079b6d72212d9e3f71c42bcde81ec4e9d2891fdc6b1ffb4620987144af6a7506e725a4aece97c2f95cdae4cbcce73ce39e79c0a88335aebc3ad9ea4b7731123ccba9656faaf59626d1344f866d65a6badd45e23e0648173b24016b86d330552d448a13b88aab5d61cdba35df5f399f2366d46b1d4d8da83e602c6eac70472f562e43057ef459e78ab695784c1ad32cf39a7cf39e7f576b4eb7e78644e6929ad37ac760e69445162cf9115599212931351bbee6f324aec897d2f639248c8e79d67e5f45904d206f98108cee73c199351a23cb1831049984c27512a25a3c41eeb05c78d1cee06a85dac5953c50e4cb02ee8c2eea7e3b6927fc77141e6c8c88adc12a3d2c4367b4e3965d3d8ad9af74e1b46004246e4a4634b4c4e50311cb277ac8994007f5c090e25193256b4ccc6f0708080949468f2540a29503f7c2dc6597ed82266d679743465528888644541382192c52726ac0a1c4a264c9a1cd5d4b5f57e33ea6c1fc16d4e497d3de04ea5c4d819605bfb6e1a0dcbc7bdf409140907a862cb8ccb0bc7ebb56d1f08beb00e58d230030ea352d0d320af11caaab5d2afa10bcf7ad6b3b60d4a9212939394524a2995fc372882143147875caec9379995e299f17c228eeaf3214684de5a6d68764dc2b471dfd95b6b174d98cf79313c8c269ae022874572b326639dc96ae5e459a62cf56d5f88b54fca9040cdd88ccd582c06552b5485aa50329fad563ebb71e693e9bbcb5ce6b249270fb15f6a913c9cc46995e491518ed31f5f64f9d4fd249fa2cdd6643c76a19c7a16d5515146b99d28b7162445a4724072832448ca442f38183194e573fd6e1bbbe0c4130739ce99a50d4d40c890fd0a01873738c836b20ba0091f209501a2074bd8a05de8010c141d644da8e800eba0eeee2622775393dc2c72777783373f958891e7c53f50c9fe2b2164a7b225fb0f4db2ffed7e1ce4b8161441c514263478e1cb9721a22380b862056178008417683b88c194f9ca21e7c392dc3ffbaf0f5c727f7d822904dde4e6e5244e0eb9fbd48307b237ddc0299122185d7f20f92b5f224cf68fbbc137593e78f3d2a869c6e45457cc2802cf124080a5a7c49c3308779f4d2f350bdf936e7800873b594cef586950ce321631443896a8f3399699191b7fb99361e43933133f1bff76a28edcc93d931d8b13111d0b1619d098f512234ee4d13e09a671fcef18ffacf0226e540145d471191575fc758e701781a9cc36f5e9c7238bc44346f9eb58c16ec5a9c8281b7b1c88a85325fbbb535915417325bbcd4e25eab88ca292fd25145146c51e79352ca366484556fdb0355bcd5302d32bc7ccfe3e50c0e4e397c8053669fdd64e13ae362bcc5c5f85996bfff7ce1238e6f83b4d3865b382fcfaf50342532e5dc6fa0d60069c5d39360951747586c0f32b010cbee955cbc71fa8f5721dccd0948f4fbb260f7edd4b57d8fbd138d40a095d28a5943ee745fa568cb8158994fae84b1670e0f01d3be8cf380629668d1491a152a8748ff62164dd474a29a5945efd1db6c3d12e0f47831e7311296304652cd6d2c891190e5f9952fa2cfc10eaf1f2016a9e08638a4f72b6fd20e304b3d4c58a9c9a3514928114991fe38e06e9c783d2203959bec799d3aad57f7a43907843a44f8394d62f941f06c98929ff5a6b7d9fae3d04853265aec8dc572f6ce59c1c0e1935f7b5909381c8af41b97e4172b2c6e55a670d65909cac7159fb6913c4e60b78ae9ff272f490e10026b02c9379c0d0bdea6bfd800c9162721199a7b8d0a9baeeebbe7af3ebbce88543b1da759eb7a341da43fe94ceeb4965d7f40fa0054fd92492d0e5fec826b2497dfa92a8d65a6bad9f67f739c9b6fb69d2202512124a09111283091c4a2e993e0d2513a72893dab5d42eed6d6c2c7885693ce2c958834a3cfb42da3524a4414a3f7bbb869e841aa44cda85a341fa3faf2170189fa0d06e973fa5af233e9a8520f1690a510e23191eacc8a18cf14c187da01d5442b50813777ac0f153ddeed1b3fcc223d2dd5531eac82955c66bc5742fc6abd53f08f6f6f3d11a29e5a4b266ca0f084d81befc42fbdbab7073f3f601e0853203e0250b9a8f82f1a576496a458d1fe17bd6bf27c2cfa87917dfe253956341029c0232054964820111cadce26bde8607838d079f47c63192e507e4029ea7b860e341efc810cc060f1b9f8d97defc6cc4b24f1b356fc38361283693113151f24292186cc9106c7a359e446af1492ca99f2bb0f62c94e01b06d9a8cf2853e68a5cf3d263ca211228aff95a884c391c3acaf30372f3b306fb280789737ac9f1e6b8d3836cf7973de7b4d141b3e7f98547322543c7449dfed782c32a65c62a95764d59bb1aa9c17e21600f083354a8c274d2e3d7f8efff45d841e63e093b0c9969bc7b2f3ed2f86a91cb56d1781aefd3744ceca1f1fe7484afc617ae58dff78538d778df17de5c13f6de5fc5fb31debff1de6f29351b1df7e9dfa79f4dfddbcfa307e7b8552318610a6c83dadd67a4e2c89b9098cc224ca74fa8f9c5079569c5b37c153ccb18b021124cb1058b1327b8324510c6304182301ce0014c0c49c88c467044822069690c12ec081202e4e08913ecc52339c01132e40006e3fbc80c1d628021b1e101ec088c4fa84de87ff1b1d0262800df9b5391b3dd4fa7e3bebfd5b84e01f57d34d842422c5ad4e47454922c5a7c21ae71fc3863fc31f2fcf8ee7eb0ac8594b1f8421a9a54d7753f34cf22f6a87273df3e854cb248caed7946d519b52b8c5145b34beea614cc3a085dd7e1a7c1342c884dd3bdcd8cea25976ee64ba1f34cf792a95db2e6895188316a576ca424dc74c54a96b0fe1955d7c4a57d911d21c98cbacf668599bb5761e68ef3663e86671314e35f7c8c7ff12cb4cba67b99596850f5dd8538772ede795e7cf760bb587cd7759dea83549e0fd587914b0f1d33afcd78aaef7e28a7ba54eabbd4174a1b1ddc77df7da1cd0a2894295326e3b7d1d18560eebe22d4c55754f3798b0f7fd2090d148c652f3e1b1ed871da014360186fc3038684bd789b0648d88b97b017dfea657c888760367f238393dd0f0623c6934c2e6592cc2c9a45325ec2b8b1f9e13c32bed507e3537d2fbaee87860cd8ba573b05dc18de108cf3629645d72b22637843b0d855bb94c48a6cdf01b229f678b63e6d841544794e16da1585da156de647d88ba7f39bb2fa0883f1d4a75fd17164ada3a125343c310412474a2ff0f1b37eeb984f1fe8e61a4c704ddf689940e0f0f5ba17e3d5eabfc396bfdfc8fe73c98bcebc0cc2caf4b7a65fd8d26b8f939d54c91939a3ea384e76522567a4fc1955c76d3faf68ef3e95f21b82429932da26372935edbf7bbbe7ab00afd813734ee215c55828a9c82ac23bb9bbb74da5cabd331375fafb55b97f015d62334945d68c196e1ef924e2f84b1c2e4ec4f127c0757739257beca9806c250d3a13196bd0bf841f60ff0fc00c3894312a4f3e2010af16232791f20519b2bf27e5d4929adfa38b943e847a74f1510196df1fe77b2bcf14e68cffeeffb47fda46072c7f4b2ab2c00e74bf0ff84683fdaf56834dbd9c0fcc03d002ca2f93b291cfe90c81e33b2b5a0008eaee0412344e292762f31c4c90d25254037f5db93795635395192cf970d2a0a813e7e7d3a39cdf93be1c27ba7dff42ff76a7ee4faf75f76feff6399d0775a278c6c6afb1fb7aff8d4ee7a4f369c7e8eefebdcf9e483958a34d93228ac9aac15ce472c8caad4991c35714295b9ea47c000c114274913d0993449826a26061cbca589517e4fecbd57046e42a66ac6c26bdb13a0d1b96f8aa0a0a7448514c69a4b4ae2aa5ef350dbafabd3d243d44bb8f646354b39ff82164b2a61bb63061419559d193097ab862c3079c9aa077368595b117704162c10a6a789ab243a988871ca06240c306727861e610838d0646e604953db15dd64acbb1a90a95a88b5bd01aa59d4d55a6e800cb7288339eabbf7885abcc906d8e4d5594e4104c928ad1e5d3bf2b6f7f9203581299af42cca9a813032c739822622fe61a3452e2c09455232d31e0c06484820ee4b8818cd10d4f72c8988c40d024070e454088b9f1c2d11b1343c05b8e4c3f48ca360abe3932fd000b93154d389137377d25b9e4dd0f954b344fcde5b7114a43cc8440922f5f0432af620a3250b88c4c2d7ff96422c63849f012de242ab08c32d6904ac50f5d2291650b64523c22b717c3a1ecc29ca9ee2679a4130b1832d99445e934533187f21513569aad8eb01194ec069704a8048d1a495a09cd0c00000000f3150000180c088482c17050302410a4cdf514800e698e3e6a5a3a1348025112043108621808429001c610408c31c0286488c61ca09c917301d80f7496547fc5e65996c1e8f014ec5f8e82d33961170e62825cbe57fafaf4abb07463e4810c39eb04b9497e6f277956a278b1c120fdc05aac2d1becbdf99243e6aa8743b00416fbea99cc2193e56f2904f0cc719a51ae96521768974fa6cef1e68bf7b3bf60ee2a5363ac93b826112c96e2d99db716a5ff556f19d1903af5b6e49a999975e5b8834b7364b86846ab7fc5045eb46a83a09c8a89e7e530d90bf33896c12bfc093c3a630b7fbb542336411ad8fecc6b4ef9675a296e665693566f1fc24b8a520addb75bc81f47aa314057ca3d65fe3393ec62e648763ff5f77ef7ee3d5d89e91e97dbc1911ff7ff0b098fc6c1053ac9a4d3fa120fbb47b567d80d096afef912a82f8f26d812c9d90c5b775b47b1d5157477756ff4571757fc682aefe749075c5326659cadf38310cc528c83fbc14349327995199de2145776cc498b84ea7f5171a42d7b5720530c3631912c0dd7804d7556dcf9c18a8c9a21f1b7ea78f07872ac57b69822f48c22d4ad6b4a8e9f7e8b8e94a1d7de44ea6f3ccb9bafe3a7d3eae94ebe0d826ddbd03c04de2e331d436dee7766dc9ba66711eeff1508272b7c13b403aba1d8acd1d04288231061a42e48f39750cd072f3db3d86cb5208c98375a09512905529074d2ce58b4d157a5dfdce10a09ab231c79091d5e8f2487487ac3d9ab1a588036379af2097a29632ff4513e89e92d471b04587b26cd3e724fb71bd3ce415edad7e4586e4c47c42989ad2cd1d54ccf45c5008cca5d81199fb77092ce9d99b98bd7c96dd771114765e3a6a04b1815575ae9d7baf30984ea28421da5e7b3f45a910ea906c9461d7b65ff972dc7e71a5ba7c10616b97857e0924cf64319d59205a89492e12b4d2615f8dfbf0be09f22db33447171380c3d8ae6de0d51455dc26aa64b0734886b96aa8f1306ae9a9b31aefb5974a74a80dfbe00cfc2f7fc81d5d8607b1cc28a70f0d437500e3f8589fd5e3218675f31a17348316e1543d04484b245efc97c1fe43004d8707b7a1f7c001775311adf57074929ef4d307ed34ce24965b50b2684141e5977b1264c560eaa3e16c284a8739b85ce6c1d0590eebee731fd1c3add9a3717b15970f38f65c65bd7822499f5900a872338bc1edf2242d0bec08cfd1e5b10d2ae868fdba9e3d5766ad074e2b5e42ad788cf2eb6b893eca2fc594ebd25a11cd1f84db830dc4ce1eda6d08ec94613e71e25a218975758f84c8692f0ec81e9e8b114cf7008d3ed27f1b3c9d7c5642cb0327600d0fb2a9e69ce1cbf2dae5432857284ec180b550a29f21224aff7a4b9bebf040e759b638f01a61778bf5f375ba10efcafd5c63d073a55d6618ffb96f0b9bb183708b0a21cb700699c98ced40acf48c91979668be11c123e9a54dc8c874e813ca66c6e71e0572427fe0bac61e4673613b25b50fa85dc354de1966030aebd93c96fc03243ccaaed71bbbaf0a57d4652712455071d0fddf0a111183aa7d0975d769583c1d521f7245b8e1f11da9a81ff6d022bdb552d438d3cbacf221be4d62bd9e68c61b93a19ed0793d51976280e828bd8b2c295c8b2446215b468460355cdf1da5ce52bd726cc340f4d4a564652a5c747338b2012a13e7e57ee939e0930a73c7e846d71df1f5ade663da30a7e5d5aea89f2736dd25e32a882bf6da3d1a88fed9abaf5cb0329094499c1c515daad81b2c91fa9b85839ec80efd8efa96bc7ed59e26b5734680033770bb666ffc3214885abd17a3d801f4c04a26fb0b34104d2cc4df87b5fabe38cf52068715c543d0439f47f089cf231783770388588e3028b358618c7c33455e0c6cd79cf49cca361798564bd0f7ffec75d650a80a07027293238d60e701693735a19b8e8bd8780d38e0e98d4742f7b3b572ca7f09c7ecfb62147f57833637a007d9883595dc62c265489577740c9b7875dcd79498e403483941693423b7cc3fb2e003a4cfbc3041537bae1d7eb21e3b341ad399fc8f83ad647bc21805e2c94ebb40b32934eafd61aaf4b534791b446519718d0ee5ea8b063787c3126535f12161fc112b6cc754909ef0c53e4b6ba132ea6c0e5e4aae5abbd8bb3456d7a45d6ab5a56a40f887e987b89101d06d3ba0b91c2b200cc0f4adc53555260d2e8f8636d8444b15e832a1c6a4c2b85ef3ba4888675251d578d72bb141dfe93216917cae092540db889381169033d9411425785b6ffad2e195a042594b7fc7c23f748627524037ab20b19669937a9fc784dbb68848b3e4271249c31da51ad15f733a4cef7701335235f6275c7fcb495f75516efe88fb93e825e33e742323b0568ecdb52b7e1b866c4d3da0caf2dfa2008e103060c93003730b24a379e756c84930e0fc39ca022d3102a275f44b6192b322d44cd8ab19cd2fb9cd2d4ebef4ee03f8f7a8f8c4342354074ba6119accdf1e66ff43fb80fce34f2ad88990d23825d6745a7872da341eaefcb375f5e82e89dc3813dde255381d2815877f267309671267c8b7d1819646bad4ce50feecd86fa1de176f843c3f09cddd2131df4de77dc20da8cf4476d3d5543993b03bc1ebe159f9b0f1bf47156e7408459c0408b3b815bf36141cbda19e33efd25ec843daa5545cdbbd5be21057720b94f2859ba4125e8a2faad083cfb6a3be488b7f6408c873debf64b5cd9c0a8fadb0054df46984212a5d6b20d2f0b049bfdfb266e9a331f2dc815a76283d0f9c5980504e5ded424aeed3ecd5ba7e693a0b203f286a49e768033350d789049042064f88adc4de650ea909e26412667a08d677ec516e8ad513ac45c528413dd123e2e13798dfac4c03f4162c1ad4cb121dc5c3fa29988682801f0acc7f5399248865374eb1c8140b9c88e0fec8c41df1cbf8b655fd61e790ccd2f7d04f00da61a990ace1e154f78586c32d06dfe5aa6f6447ee37dd32f7a8dd16dfaf82d1383ba6ea82d6d93bb768850da3afe3eb711096a55a60cd95ee5f3e13c185ba979693ac4e3ab496f96fa1a17d8170fd73fc7a4210df74bfe677714512c98a3329560821d0dd32c4c314910991fd13bee6b56c442f8d7fc13fc9a1860f0dc10d694a1c23118c4d372aa987eaf01e2b96a787a5b75e6f46927cff331e25afd70e95792bfaa2075667121ba652559da47ab4ac0f78438f4b00017b6b7da7e8489359337b3a09681d94868b1141988973d5f6f3e03dfdd259e22a6752fbbe72b70088d689ed6283c7b208b6db6ec074b6dc408b19ccd8592ad7c9fb162c3ab1f17cff355add75c1eb577e5cf817ca996cf25f8fd0906eab4673de6f23cb30267ebece4beabbe2452cc916b8461972ef6f863321d6087ca2fa4709bf219f3223e13172ec4a410fc84245b882cc70cd1f969387e4c78ed19b2f1f588b318f7e794a0321c2a4127982c988564060c872832a7c9c3baf5488647cf431c84e1ef8b992667cea04108f95d70786542831805858e6a9c12e4069dc629ad52a068015386bdbba812abcdf85f999064fea7743aba0288720835ddbb2e10917fce7535a03ac18d6fb90fb21c76f8be100f03a285e552e969a9e5781aa95c362c57fc2dc54c3cef0712294ddab49010d0a6be9c6b1e383f8adb0b901f06503261ac6c7fad1b4ccfe75660d166bbc1beb63e56b5c95cacc8a2997101d3acc4434a029c697390e605fbfa2ce88834487a9eeeafce794334d7edf04273ffe922ed56e570b43d8b8dee6743d927e69bab3438016e1ef69e179dcd71b8162d410b094947ff02a729759f07bd519b095ca975aa51663695d12896483ce44a836f1a0e89a4643c514d5f60f4e3a75f21280bc77af18e52fbe0b96bcbe1f82ae7ea9d764a4562f9887373a03efa5386ee07b00a28262446b36ff8e075074852715ca138aea023b0fc4a6da827fee203d1ed03894a63702567f8562fa33308f5293eff23651ce229c3e7a6dbb6a330b4e69a38dc5f104adda60a59abfa10da002f9700c97a8975a6eb5d7f5542484080a01b9591134376fbffc2093741e78e444d6633778232d520d8178b3b37f5e1c3d7211a4609497bc05bcfdd2754a110d76377a1ae279a11096747d1aced5801392029fd3652a35e13c9fb1341325caac97c548994bfe92709b0ae6d676bdb01efcb223c8b767bcd515c2f3d60ffcd79d0664d0f8682f03c3e51b765d679e4798165f7f40fea52ceb9aa62ef5b732cf6ddf25f2b772c4893e7bf1aba7286e750e100037e00a0446e61cbad914387ee7c107a3b5089eead3baee95a428170fa004214356402721cb9f034fb6c56eaef47aef486e5ca283673c8d4a05517e06d2d310119dbd963163982c846a7c0cc2e466bfbc8bf9270c5e2afc4dc766ae8aa22722364296e139081c320e3e83c101ba83a8e7a9e93d39afc1f7323899472473545108d93a45cf3d3c028e9aed5e2b3a740b97c8a4f6f6fa74c0ab9fb5e10f44b5b7cbb09b731ce442870256e90d9f128484fb1df5edd067947330fbe48cae595c8e55e243bc032bf55e4a02bd1264a25a1a69c043ed606c4cb1603de2014aa70e06a53df928d521daa8f2b21a7cd8966d80456fd6be1df80117fe8151a70c69e22848b5185d54e00c61001adc5261a5c731f5f00039c3810d0e1eccfcaa890e34d6bcae99501b5b0baed6913ed1bdb9e470790ee92976c2101c460b340f8caa2f7ed3fefe06b30a2355b3942cab7d9beb6739d1b38b5c9b008b53dd8bca1c6b37538013346a0695a09bf10a4c47c25b152a9ddac9f56c9947e4b70585d9b6bee54ab113845f9c5f5d61ca87791cb51dd42543524c9d5201b8ce1602af6de90ae74f3fd7e72b6f1272e65aca737c37884b46da67fb1d07bc8daa3bd1143ce0721edb2327ad35f6fc7aaffc2b19e24d65a625163207f0ede4cc38dc8860466dfdc873fb38370f6b85b418fccc7fcc96e54e665429a861608bd924d4baca9e9997021ccf135ee9419a37a970473ec8f6e4a855a635acfc7486c5f4c83c49bc7f2c02ff187c7572339dcf0d2eddde450361a95414865fbc44568a2e256540ede6ba8051d5e69fe9e2a641e1e6b371e84c9098e611acd3ab96fb379e84716715c7afbe1f10c6585b60d2f69e7e3e13eddd23c7a0ce54909135377188a4092522325c8eb473f7ac1d4877ef09d2900832c7c95ed5355d20492411240aa4826d47f23c8a20edd1b53bdb532c085216ec5d7009abdd2282351785a282523d17aaa7803c48100303e40291b24f9bdec93f1561c4fb9d131a7bf46c6c1770e01a4b750fff4c800d699e0c42ffbf4331bd18d4b2ef7800368fdbc03a01e7cec27af3bb42fc1174bbe26a542e6464651a093b69155f937797f820812de01a16da955a4f825b1cfadb0497e518d1937d4a05873028ef9bd4031ea1d64a4a1afcef19d7bb71fea19de2907bcb866a04de77d05d218d16556b626c74f4de6ab91869eaad0cf290db2ae1118a844dd7836a76caa804aed35757fbae07b872448ba8154489a9109be5b5bc00bd711be978f795dbd9d0f6666bfb0f315984d7a577c28872ba2e88585e639cb9e4cd0e13be790922607383bba5de6aafed4fe1ba7751522732386bf6c15843f0e1d0e81597dfc2368b2f538cd7918597d9ac2be6c8c0fa2a8f4fb8f0788a7ae3bb6fe255fb5158a85fa6f4b0ff00a94ed2d10241023dcffd23475bec86ec8453ee27d8c3068c227e68af055acbe11d1fa166a2a7a57d448f7dda4efa4429af5c6c39df0225d3c0349cec0fa10c554925af59967cb13526af3633c8f38feda1072f5d2a7fc36fcc6e597f4c9eab9070326705e7f24499916092b1fd5b9ae061e2a27b209d8612d923e12aa99e331765307bfa03701b421b8aac2ec4abc340d7e84ddb2b854ed79b548ae56bf0c67e8de628674cc4e46fbe5c38c76dc1cedb44ae5a007cc2165a912540b85d64b2fd23511fc596ca66fa6a067d7837036d4ae6eea5ef84fd8f16bd714bba84cc719b7600105d782929176a0c18011ef54729ba7e3d5fdcc262707021cc3fce4bd661bc0d4a84fe4b9ae97417c27f1ed8f61836080ecb3f3170f551ab948f4d92bb27fb91b080c15adc76fb415c2ec478394a2e083aa8803eacf5e7a4668c2f0f202657d1308c16453b5186e6e73d84d790844a13c4705a6bfe23db667c272570548409193d7b40e2b29e0ec0d87f23b960fbe02e8f2e12088f505c9ceebe2001cbef17fea54b77285dcadddf1d336d817e30880dddfa407e40c9f78d17a870dd28c0afb8cee3f6b4284dfbe84e21af30b5dd8b71908cb027325611d0aababee3592e8b76b28b689d5c1679880594c92f2a5d789e4d9519b89b06ca7e414793828a9ab52fdee8e22d3c3fa6501e54a88f3b3593dc1c153e7e9bf829e0cfb39842576272b942aed8c6fc846c06a4aaa7e40b7129c2fee92fd099aa0f8ff7edeb81d0b8d58ed9df6615373b482722fea658262ca0e24888106b0d3b6aac036d52e4f425385c3b3eddc0e7a7f464bfc67e39b6c07612be7ded270d28d3d3701f5f9d38a6e0663f98386b2dd05f48a82c775b130613c090304d078966622ae547812dbb88105bc50e69f57b5a781f04a3b023ec9c7dbbb0856a0d654525fd754e40004efa779d1cab56b23a2142852456c81d7310ee4e7a834687f2402cdb647e282204c5c670c38d527cb44b2e11feac5e4c9880c11b1d04c9c31261bf37a9b4daec38fb32179db7d38a9a87f37918950f59b863ce8741f756a441951193822b44d904a27118b8de2fb16a37be194fb08f7823fbc17adb596340e77f250d5bd59d4043d40410cc33499ee1714944e6f91b21f4beacd1201af961cdf44c297954c47f13b470ff6b889b499c7ebe172e5b570ed03fe5c0c2a9eb3d66f3448b74301e5f6edff2000104d9752304edb5758f30e79a7828702548a3884e5684d80719ca2bc766edf3c1301b4a7a69dc6792a37b113d4c24315bb6fe5ecd8d5392ded88903864f855d4168ba7554bc8be4a3cfa1c2695f2d21c1d0c3517fce04b99263ab3a124e9cbba3cc7b80a7dd025a0cc3beb413f1a403bed8a5119a384dcc0d2ff6ecddad59812edc8bbb23c61b471ef591cb11a9d3d21f15f30850236b8c70937ae556e2257a18c8e0dc4ed37b723c42aa626a2f1a32c3b5453c8c7ca5ae6ec6e51476ebfc974c98fa52db54a5ccb51c7c0994e02b37db35ba1b0271b3fad9f22d462bd0641a9b5263abe41a175214e30dc79405d68ab125328ae8a765b3516c7c270cd2fe02695b6a73bf5802c88786c20854596dd7bf9095e14c28bdd941b7e1eb392767a7274ddb9f073513ee4191ec59a14747eaa5bf8becb8f57694ae304c4ec588e3f6d421c3d530ad45111feb5a0fbabc54e4eb701481ff2a4f6928516620caaa5427ee2a981188f8a2275c181d54f99f138922c4106a1dcb6a211b710be73a546caeb9f30335232f978b4eb623e2419c64f1288dfc7686ddd641d3c11db8707e27e08050bdd878b092eff67adaf3381ed2723aacb549979e5523b207e28a1bf3293bb6a627dce25a245214978c3295f13891e32bce79096568f0b330ff3eb53ae6c24b7f0fc0168eca5784325729a6a88855b890ae2075f455101285ac207aa40ead9ca4a7c249cd3c7f6caa6a41e3796fc7a23641251349ac90ed2fc603c1fd67d04ef952166f471d805e45104fd4ae9476d79dc29ab6c92226e1ea8e65dedab8d80cee63913f8a560453de7f841b82873ba4f3328f0ab91d5c16080f52989e224aa3c2b4279528da34809d927149ff50ce3f3df3f1c3fa563dcab1441b0285afc629b50a06205be91331e5d45adec572c39c180a8fcfbe6758430460057ac005425469312228c54f0b21d4e76aaa2e7446ce6b538d02b9b60c7db5026ee1901384851630b761195e35016d1ae07806495ebfc6b1acfaa17d63b6f127c43f3cc0c6802491edfd11584aa7e6c8510277ecc3980a918025c24b822fe5aadafea996497e8bf08984a1ac91501e92605e7ddd5f7936cb7c9d98276162bb792096ec4dc58d0018de0f9d979f9ee29c6e159ddabc8d9034518724e970ee9ac88ebac1007d1897e5e6a341bf14b36074c1619d31e9ce89b429aa1ca862fe70450da442d3aa132c9dbdce2da5d858f34c4f9784219b7600286605101dfb1b3dff8288539470ac5ffcb838710c3bc8d2da4d523ca12c39b12f884ceae12af475a943ce75aac2e5a8dd31c390e21cf1222494333795b460a1ff660a2426cfcbf3903973bed7aa0961e5c997587312751a0c25460ee13239efa7aa9b12b051812c166e659dae990bb40b00eaae0586c95479deb8779129019c1ebca31114a3244d761493caf040ea0d5fd066f3fbe38e60813bd57663ccf9562a203b44364e005116af00b1085915544644ef98c61e6458357263d7683258d83f4bbefc2afa080cbc5862e89a87ed5ca846ce9cb7595a88b2c887c6059b606e63859778c0777c92bc82cf470ec7cc5458834f462c2e77ca940c81c35e5bb8ed9000adf11193aeb1942cfec4983078d38f0d2d7468425acc05eefd28220ab9c3c1ba2a551c3fe19157e8d8bc1b0513fa1d8a793970ff701d1c8834d1f6c4c674027c60c96c626f26295923ca46292e7397e93b02a8532753f48c2955727c68dfdc14b81839f5d534874576d43aea83f0ad010e6a1b0444f382aa59c11869e1759a66310fdc16c335612c1f8343fd37e7e6dac90a75061bcc5794367cee3ecc1babf91b99580110127554cc3a78ab01dd0d2102c1cbf1607fbd690412d04fbae196463a9a57179c5ea4c0472bf9cdc74750dd8067b6ce7fe796baf8c050bd8180b1b66c5d6fdd8f448d98ab8d97c8716bbb36daf0ec3bc273b0dd183e1ee94b019ba1124a5e99d72fd4553c7077516413d8926d0112946232f34aad057bb76e54ff748d6cb7d8d37f6d1461d3ad3d94744ff1b5a7da7283a89d83c08d86ffbed21a5cec1ae661234afe8e258f9b699830d99cbc3f04026957d834257290463ca9ced2fc4e51792d6e01b1af7b5da8e5c752581f10f045944573ad4a382a6109a1b0cbde6e166a7cb96469470c254a40357e6744a71f14891820cdd00f92fcf1974b2a36fbd64c1549c08a3eb01ad306cd83c7275ce5e7921d796f64f75ca0d2187744284e1f7f7581485cf7ece163b79fadc0ddb064de7b0b59fb0975ff36689ffba9a83f63fc1fb4501726fad79512d68d90606ecd50d7b8a22c358dbefd93874000b6546e0142cdd0b5cc7fbc17fb2f562f13c62b707f17e9b55b7b70578999ee4b1beb09762fe43c8a1ccba1ed73f84570d5d30206107520865e2ff11081f16cf66eafe07886373b297041bb3d2068ecbe1753c11f4668554780257dfc7a60852faf9b0cf4d3dd0641c5d79d25581f76b80d9f618a546e1b2cdc47b5b2fd212c7ec80bb3142917de7edc8e7342010a19f1d810c116c06088907b70a88918ae660680fe558df1f4c6cdc46c6de131c9a7ab176f508b4ee73c2160417f9f68cb72f2e6924410f6bcff8f465a07d8d3348338942d3bebec74cd56e5fc65e08fe59b3e515d1d8f7631ba6bcc367ab81fcfb86984c5134e070c4f925988e030004249fe77d3b06a3f52f2e0427c4a4cde47c99ad1f70d128c2fb78b97601889c0471996c16f3f1d798a38c9f2db4100d3f9f668a3c9c722cca03ddeff2c9f0196b8796bfcaa9c6ab45b419e99f82814e14ca528bbda90f8e7e900679d68dec197a90a652140c1a5648c3b00160466a50a77c7a7f13f6fa64a925399a382ae5c793ff4f94df8640513dfeb767b442dbf8b8a32e77a20fa2d9349a3484d1ddabf49c873d5d90951a17061880be83ffed6e4d5c2a7d356a1b80698dc99e4aa90b3870ffc2fecebf2ba37300d0b2517762b177f917980cd9a909f2dfcf4215170ca186e60de5fed2003fb09af974f3c41dfad752a2edefc28dfe452734e42e11cd7cfad826622e183eac8538b54cf1d0b3df074d2781a35dd8649aa5ceff37ac857f3479893439ec98d802d181c174aa946fb9c86c6c70d131f9531ff76fb920affc8d3104a33c7aa7762fafb539d08235e75e989bbe1ef91d59c645f34215b02e631f91ee1989af9f053fdd8155560a82e9510250f9d9d579e6ae68bc072026f7aef04385d17843a19b86a415c45982d7939fd57626bc8f361a98a83c8251c3a8037b9abd42aa670bc4f30b1bcaed9d06934118f5b85fdaa44a630785c644c95fabc3384b7b021d2f0cfa1e4439620624ee1b036dc535adb75ab857d056bb80749119846e0344f4eacb325a097f6831cb7dae2e9a2a041d6d657ae0cf013a481f0eaeb3539b07d881687b62f7c6b6b8f0ddc892ad7af14160b04a639f7ac7dbb8f480533af425e5b18c7e2ded0a131c818840e1c7593c3cf3e3e836103fe8faa9efae51b4c542b9ca81bad4809f2ce6bfd25f5f43b4f627e7125651c6272d040d5bf5afb62797396f0401ed31710d36d8b11b4b251bd7b20d2b118d4dd3e36d5745cbf7afd4d9aab0e73c31438ee9d8ad5def4da33bae2ab577bfa1f911d7a14bfb0dea9d562be7ad06f1f3423a21b341b1fb40295c07bad2bd42662ce4eb4c2182648dac36adea744c1662165b8753ea20195eb799a9176e140dc71f35fae1ce3d4035630c70864fd7daaab81dc87e79728401fb8b5c01cfcbd617d472d67b1abb0db41d6a6835a2048e6e8436d1b80b435c614cec873b21d9fa66fece3fac468801a82f0fd2487494cee976f0030f21b0848b2df3cbb29e1b0d1a25e679903c097d18c1120085aac262092b1d8409f427e0172884c3ca1033ee1ca8a03981745cc0b34622b24e2fa997700bc90be701b16930512545915618a29184b17e296419df6dce16938ec43798f0c0969b9c3e4ccb61be5788706d7cfe642328d35876307d2d21b2d17672e9152417e1beaa7ffb50c4e3b554e507d9412987015e289677f6612d6f1823aa72e3fbdf5d1d60d5f7181aee4da9c6cfac008e57f40005e8895378b74f09c8a4a1b3e59db6bb96ab63747e08346714b75a045a1301d2c5fa8be85f5feff1634c823181257d49055a564430e7cd3450f059910602b03705195605c54b4aa6ac1a1278e6083fdef02b616abe64f182e58067b87b8ec169e8cf565a73d3528b8599a6234e86484d65fbd7f3c33d51354a245753058e8fa3a8c548dd56f080361e52667e9a543402dbf2edaa0f93202982118f08fb80b926320b079f193fe8271740f0b3762d3fa47c67aa246bbdcdb1c2adffc1adeac89008ecf7d55600c1828809284dbb646ba2d16726795280679a537cfbdb62fed6d43d298a62d43e1b24850527be680a0e924fe454e63375a9feb31cc30e7353a9e1d53c16097a27e7dec936683f72e9c7dcd8490d98cfbda6662204423727278dbb330b8856cb1e120db75fc3b7b1515c7ff393cc7888b9349b7996f50c86d3c683c950640f95508af8ef919c893adce339cac4132530e20e9c0a5482d6ec02f1c89fcc38041096a1c26bc349e04da4181280c1c7e3caeba86b0fb7f6e206b4fe99d609af04ea228feeea906d86a7a2c5fbbac8981618fe59ab35313f16b3db296f619e749e89fd2339488a0b4f0cb07dc00612a5b65e596a6b41d6450e67a3370aae671ed12bad11acdc56ba38860e661c09c732967dcb9ea9f32341aca45cee0e89f4e71eae8f7425af5e6b92f89c578cf10721fa3dca59f04590f79d5b09d5fd88e5329588e50bf03a6ad1183c6ebc9a847d1ff9f5b44c98e6a80a0e8a5c5c103cc633cc3220459569d31ad835cde37a286687945173b688ac003fa4e666f23c299525b44b0a82c6853e51f68800a0d4a12a6b3b6436022866afe37a9e225ee9df9539c946b86528997ae910b1a8fc99a3c8e331de9d6a0ef088869583f26be07106bd074b3f5abfbe1746ae8d4660b492f6d82179fc9b47ae833f09902a182dd64a15dde64d00fc7ed07efbd03f57840200203eca03454bdc35e8196aa3fc2be778743142b0d0d9833c0a6831862f4af79efcfd93b7393a070886f21affae1b2c7ce28d3b8bce26f5b4699c8250dee076392962ebe80fe06a761838c76e7370ab23d0b97d15ff6c70a29b44683dacf82ee3de3677041022041db1b1cd5b4480d48cb615f87b3b6b8f835b9904e2416a9f71d6bb061b675b15d50539a44adb1e1a6b1fe29b942c3695cfdff11562b4ac4738d81ee3a9a448d435016594c4b1c7ac64c66d1d5e76f32fdab51765c1f0fb3627a93a5dcb02eeda86b65c619e41077475ca4f01db1320ae5fc9b12def2366bafbcdad733c12dd8976a90020218e64ff5a06078e07462d543f9bb18e788c1c726c17e78ac21eb4942d0be4346350edca7ea8a1454b7a4cc9ca85ed68ae9a49409fd8f6c72be4919b099caa4858398e50825404882fa1b2c6b66cf91cdcb5becea1fe08b368a8afb4e5dc8a299718e70a32b96160a507b7876195e3ccf6b41f560f148e112a57374a4f6d0583d16e419bae4634e7e4b5e09570794c11db5491f73fe4ba537f4984f4294f066e765e9e3e9bc9b3482eec8737d9aaa13bfee9097b1c97d0c850d20ea256f3f54803416800e14e9180f5def17fc09cc160dd2cfde2d3a348b1e01a984de7925270ccba6ab4f8834a1c01b8bea2071ee8e8b9becdbd872cd765aa5ec95058b41e05f416a4a421ccc43f5cf8f6f0f99bac5edf33e18f68a2d0e0c936c024ed50007a4c380e40861353cfa304010f926ddaa528dcfb821b27b892bd6ebe09f98bd2101d4ecac344dfc69bc5214b519c339f96882d8876478b29c2f6ac03e208477bd78e04ba9260d51be6460a2a75471b92a149ea3cd174989bfdc55b4c7db1bd4462d645c2762085bec0eee5e2e3eb9c9d4933b97993bba0af7846f7bbea179e0bb24726e3ef2cba6a4196d671b2c08ebddbd4efb4a2b63d52ced242ae06e05a5947681c5da0ea9b00de19c25cc8516c2736922114d2b7ee8bd7e7be61d9015dc72f38b2c6131cbc66615e22cc16367ef111004d149a2f1d14283101c214962551fcc322f777e927cc4a57a46ecc6547b184a4510b8b5aa4c886964c654ab4a1608fe32948cf863d71803f106405aa0d00af89b09d6b2be5f49814de3bb6e3353cf79340177ab3d19c0e386326bb41507297c5d3b825d28ccdc96d38b2ee8ef2111a40a6d8c44a91dfeb4f5dc064f58b2a78377cd8dd3b131763cd3e002e25148eed8b83724818b07eeb7a61cd667978239813d8ed3e8396125b8f12c539852f6d79adf29966055f14951e22c59a0f61347bbca4ff472ebdb680079abb14b6b9d4f774cf2c8e4b791d5b4c9900a2e0ad1000191c8dca90f98d86968d18d040286d445a2cc5d9eab413421a7d3c4324fa50b37375f45b5130102442e39f461ce2f80825cfb14133cdec4e4a5adc0cbb83bfcd888414fe60a818fa86aeb7221fe334e99ab4612099f774bd8f3e4caead15f431089d62a466b030326f2383baf0257d49b72a41a1510769369aa56bf49eec61e1e2cce8290571c71327bcdff54def1e6ca63efb98660d4dc67ad64277c5112e59e395a423081cbaa538de056ce7db60c4b758b88b7a17c6422d3fdf1c831900e49fae32614e4889ea0d498488d527233fd8f27f39ae3e5e57cd968cfeb67d2c99b1a1b18096c91f53b13bd3051bc4b8c348f50169dc5d1be800154cd2cd6765e9205da78af10a3cf0263fbe518d788fc8707e8d77081591c714fa78e1867ab1fea83a30177fa9f8efb8ee219ca4b047da0a38947ad2004adae87347839b393a84d60a97978e12e9e58a4724b75582e539049ff4d8765c8d70a423aee30c4de1c780ac41d3a6bc3eae97da10b6e4857989a90f8083b592b59b452163877493aa532795b10a6080d11668691084e2619764ecfacebf383371e430b5e5ac3ee008171d34d9f72b37ad9f9571c66893dafbcc8c0d929fec9a57bc4a9951e1d0574b85ac14f7958f0a4d40a735a21b90317ce2cdb6c056e4dcb5299449ee1b2746aea915f15ab27a784ddffab756f7f4493d949eeab1444cc6d25bc1d5687ab5eafe15a957be0417c6aa57c8ae18b1cf0d5899acafd61302d13ec7adb1870c99d4ae00c61cb348f3d57b2a00ca1931cf2e75b41d6c6e49d6d933356157a07854d76e557ac0582f632ebd5bb5d2dffd0db9b58e229d9439e7b63dba426abc70e9df1f33e9b871cb0c8ff32860265b74ea89348de2982c0e4c871dbf92c1dcc226a3c081900f03eace60a8adb4727c93d033caf57ef9a50c93b17657814c16dc994510f8b890252101f6a4292854829fc4d2f0505073e7c154da792f555b09312b994d4894b322bbd8bd3b26923e78df768776b753819672378d12a297646aedc58c3a7d205073d2e3651e473d6ca5cfd3e3c6075f14223d7b3bd0b5e9095357d2bad1f8c02e6109e1a28fc3874eece1b3338db7f836eae16df7ae2ffe387e8844d6f926cae76098eb80adbbb0edb763003a0defd710a2270ea5f1417950cdbb81683167aba57216650ebb2cc7c8ea7f233d36fbb233d38bb36926f2a21c99278f56fd9378914f78302cca80f71af2eac431eb5737802f5498087092029f78c90a77e8bf4995a0d99dfdd8f4ac7ac16ba34b2d7156882296165cee0ba40adf1cba069d442d12f12a3dbe48bcdbe88d131cac538982b141820f71e620a12399e771af284b6bc8718d56c9a52bdb0d6c28c5815e1dc81a5dccb1490218dcd10fa3b5d2daf25f596804ce33c72bf9b718bede8b415fd4500dd9977c95af685c0487ded39723099d3fc772f6180d47b387cf3f7dacc2c7abe72d48b9bded90ce5141b96262b1c96996eb525362597eea501c9508b1c25e965bf1124813e578a2e6c0f385bb03e07922df28c5c03a964d74637f18ba137cebc13364405e436f3b2c401dd8466555abf32e0d6c5ce90d317ee10adc35cc9008853f98ce1c28633db6b414e2e418664e731175ce801faf33962a2d370981d22c3721320d02d60f54fc5a2a890e06e8cef8f6a775a8013f3f44d0a9e16856ff37e149eead85e8502287df627e7a2f16b95442664c4dfd50608b9a6aeaa440a0cb3c8118c3c88a38494dd27599b3a1eb059f49b59bb998c371de82207c4bda53f139581d68749d00123283bc4520f8ac530732bc66675e622a604ed5828547ef0e2111599074bc189e4706df6a98c50025059cefbc507986880857eb5ce4c48ae5894748295ceebe396cfee0856231803230f882c2cfae3c3779541f6eff38f00debde01b8900aae4a95a234654e24bf0a884ddf5eaba44b0faedf27dea9684d13b0e61c83507cb9b60629967e3d791f8889fd479fa18201015c85405c7582a4e37359696af941887ce5a462fb13157f126a6900547e890170d7c3193a0cd935493e04a45194578bcc9bb62a719091d95431e950d407859d924e00f5cfeb98a450095398e3aca922c09a147f8abd9d220c54e6960271d57883d18b15c8626e867bd45ed46e8bc36623b7d6fa7f82bedc2d7e7280b95d3209d33d19ed93f1f29cc71cd29f026c6e3fe0538688a2081410890b5a8ec4cde7272369a4688e53af946f2e76aca4b4422f0bcd8008f5750cb8e0fbbb2292a7581b5f94664e5061e83e3a8b928e01ea095f1505b042f8a6205e1c3ee95ae7bba813804ef08877e6a548b032e5b81731207eef558fa0e1f70c66597df861e12a53e52c2340c169ea59c5d371811fb24a390c25d14f531f2d82c55efb4973532e68c25bee1aded3835eaceb4cf42e08994f99c865fcb3ad5e68e456d776a19b33a2c7c7e2069a469eb76c5c8e43d1065d50526de282fc3d655e31c517ea6159dbaa5e831a75deeb914fca7ab9383a4ced678e574e5500b8be6874733e8a9110738c537255722619cf3070e239a5b3cad30be6e30916f9cd084506faddb188330810c45b043c014682588b9373ed5d84260646d5644aaa2fbed7765259e25e51e58044bf774251b5ea79bf1a203218b1a5830b4f02a0a3fd0bb49a65966c95732743785d3a124cdd43ce545510f8fb0093fc059e14094941ca2d3b1e50a7d9cd3620a5624e4843b4b0947ae66b680806c2edbc26327653edf4cb410e0e5722173afd2769a76c811559698ac4396ee7e3c6a702d4f190170fe9737c52a1fc29764f6e04a738b7bee733bb8de34d5241471a70df8ab5ef158ece745324fddcb171003eafa520b38081d2953e86865f4bd28986e900a199abe9eca66285b03c5d238f8c232656c8b0e1dfc3e07f28da6b85551422512729838c3b0265a556027d1be44b01407f265a61105daed6101ec4df189124fce4ebecb2203670c1813090d7abfdfb543e2af39f20e35e3e0a7e5d8bd4ef71faa3f7e78b8571bbe78f9ca9e42c788392d8197dbf467a71a8d51938a0c07f972949a2232d104d878a3420ac9414cc4c7e9bfdd71779cb1c5e80d966b458f4f58c0dd0ab4ee1c6d07701c86302bf60920df7717db2cae1d41bd5dea32e5e09b0147c42ed08675a3ec17911895bbb80c63006ec875d89e6601d9bb301cd65a2e1bf7185c1f1f525dbe07966378182b6b009062b48110085e140ada2cf7ba14e8a3e66f9eb7b4f5d54b24a083e3a556bfb62923c5419098361332b73a15a01958639f9b8ba4090ddf852027898c83644dd08657b106ae231fc89d24b4238280ab3222c7aa240223bb6465e0375bc5010cd56326d7136f27e4da977a9ba28306176b28ce8a84a721833e0367194574e9cb4ce8a0c8b5e6c3814bf87e10c0fe4ee901884d27525f19c0466bf11792cf0cccd75a462e492921cc3e03d3744b6ee1db7a7ae26041c7c5d08517ccfe6feca335b42b43ec24a18e1f2b2920052437237d42529ad8a0f7c95eab1511ed294f3579f2447ebe6c6fcc9498da6b5e2a858314e93e74d77c3d09bf5195b6b04475194001afd78341478b245d7feea9634e04fbc337c87f307d1551275b495b5afb6f789e7c9772e279ecab4ddc7d1377499bcb1e63f76e55f9d7306a4b9d267233e156057410accb5941881b727be66732eab42cc53650a35ae2a5381ed2a5334e59fbce10a6a03722f8af4aec1345075661c87870f9f5bc27e0caf0307749f3af8b041a84fa117380137fa6bfc183da3acada5d308813a20a017ccf5cbb7071bfe2c8f19c723c563a3475af6fbc55b3fe44b04010d63091e954dabf51d193b45e45a2b57f3c246eb02add24868a3b4e08252ca4dece66e6406079215614eb627113027782aa8daca3098ec2e729b44b41516cfb24763f6af553b01d27f1b4ab1ff936968ec284814f362261bbe73d9209a7e2c39a9280b211b0e147b98afcd89c97a581ab5f1eacc699ea264aa14c165d67801781cba80ebd002d211ae55415e6981801a0cd14abb4d1c64ae55c2219456788d2dffe957c354e32fc6d65a5d3137d9a1e45f47945128c97e1d47d57a948f6f22c7add3cd2967e6ab5c00f5dcd0c4c3028745baf43095bc540e34db17f7f5aca4ee6b149fb072456a91e1dd5a3a23db2433d52d491c3e0c68d3e4b3e82d29e5600b8fbfb0b92c6ff3aee044f7ce235c32c60acb15a6775c357354711fe7e5e8620084afa95578738561446794cabcea11c313d3479ee319745d257860316a46f1602401acc717e9ef84e1dceb418517448fccfc8394196dcbc6f7b34edc975966fe42c5d23adde78bb778376cb3f8b523cf172df9d5984eda0d188e4d685020f08960c6d08e59a65c4729aeb180bf6f43a117feac08cc428e931c2237562f6e4de7e1d3bd205ed95dcb0b1679c81e9cebe6b58cda38cc470b3f311e8433aa40dcc50ee5b5ed2c9898e4aa7d33552fac7ee4990980b809f35a4593c89dd0ee13bedfc7def36346d3f86d7e0fcbdb28034ae286f36f12866b056608d5e25596b3b0b92a2bc290a4e289028c589916666c716c44961d3a41272bc20692092ad40b733fb4861c1b29d3c6c25c2b81d15fb473a14c4b913051d4cda0fa6800a61e470a1a63fc9a0cd4351aa867c0254490efaa38c15ffe6c5f522582a5c18e70eae9fe0c28923ef75d8b573d664420fc7aaee06f3c5c9a8f1409f49022b3f0af92d0eca5389ad328ac5e2799ba78221e337317d9596e8e5e49f6c31ca023c574d781fe06aab5c56722277eeb8abc66659189cf7195d154eae6b6c968c9cfb8edaa7371147d853f38cced024a0407ba0347e511e50002f67928fcead46a9c04632fdd91d00a0beca6c50607a6edaf99ee9ee75738d3abfb61f61ba08f37068335c385add57af5c487c8b81919b495fd8f77ac00dbec2664644104072461fdd6608a6459420efae260f42dc91ef956965661d25f696c56f1c491536fca5d99701bc24436dd734e6e45eebcfebcc6858a2903881d4ce0e9439de9ace0206be1b45acfc34026a1b26b8c0bc6e40582a1d33b0359a87343662595289345df1830218f1b2d5bc7e4804ca63c633b98e6b442a9fe621b8287cc6c01d4190e1d87cd7e00cdeab3c659f0849f774f9e4885cdb42ff56b08450008cc574409d9c0ec6847dc93ce161b7cb10121568e81066baf6ba5b93d084977559117ca4069bd67ab1860d3cf584e83fd1707485b15b62eea875b6757db56b2aa97ce473ffb9c6da7f4bd27a4ac6922b42950e91c18d0a5ce6e5e953240bc8b8081a7f5a6cd3e95c68227768d6970c43756037bd7d91d77af63b49584ce64c564adb516a7d787c8ac0452f22e603446e9ef3aaf75a9c21dbd4f8354d9d8456ec2656bb8936e771cc1e7e17878669064d37fdca57c5383f6792535c0b820af0f341886fea7e17749e413090e136bf8189790c6380b2ffa7238ba671bcedecb9142ad66be26197d50785b64b8742e43d430b3e512596df815c5390d69c4e93fc5fe0259a5d2e1390816b3386e114365f24af95e00f41cd937c7dc3a03e9c19332199ee1e1d876cffda1f51ce088eaa807f94288ef4f211a51e9f67a000dc4591e8e5ba097ebd8712703695f02c8305e81bad7bac957158ad748cf4cf80548608cdaa90f56a118b92fad2e08e7353f85b5eddea3483c00300e5d320e1e7199b07e62090d1be9ed4d24a830065735b629b1ab077aa3fc9242db7ea9a094f6360784ab171412b7b28da47fdf2bb7753d41a6dbdc98f69b307942b130d9209e800e8280be91b00d0bea586cb25a41b984aef2664a4652c3f7d9eadaf7292caf2c3b1a6951e83c7a75cc588e11ca45b7253635f48af475c9fc90076938889b19a7b028135330ecad92206a8ca0fd7a8ca970685af5d0d1ed6d076b1e2e88eb7970be7c9f4ab8340fc1356c224d4b8a4564c923f06981b2d6360b9bb613302c275fb75609404ca938b269f9361d0b9cc97c9dc2510c53cb0001fde7d3e88edbb3a621e048eadf8263d24ba90a6baa73111c8f36ac478d40dad98369fdd9e4089a39dab3848d05364ae0e4a36dccb61cd3c000424a102536a434c43306dc499793918407310b828cd94a6604535cbed41a56ad919c37b770a0f7ee066beed02bd144fc857e0bb3bf443b6daf9d335c5ab300f87910481a2e20d9047587d04184841084f21846a3217a425866187fa473021df0434edd459fa99e3912c41b480b10b2f0582e65ad83f4a1617e2bdf300c265d778a15e197fefefba73f37a76b3975fba383cfd056f8915fec446d96d3c99a6e3154a0ff7edfc4fe74b3dae01c5e9b3df644182363eb0c23bbe35e1114230f7f512185d1472d5c9be484c708d771ce751f91840dad826a5752f3d8d08c502ddca70890c930a0478fe125d0a3b7fa8713938da28f92b20f8388e90409e510447bb607283017a178ecd9de3bc09498c6ac0943463552d42c3f865cb42e1364a7f3839b1ac6e25d0c59e7e99c39cdb5669c107c490c40aa3598cd1508afe552f3233e0d7408952bd80c109eb2f156aa726ffc8040f41f100bbe31715e1f6ca8d11032b6827cb30ab9814c403032abf0f2684840b2c1eb13a6212f4f275ca131bfaa4ccc8721613f95a55649eb6f825bee72b4f6b4ae7fa311060d931f69402db25c2476d11a3fd3fdc28ab367a432e974f8b593aa287f92f0e1f1ed4936d85d1a6f37343d80cf47a5184076632db4bec42ed0ca27d4be6bbfa973b8599c71d44f6baf3d7bab243336c6ece6690d4007f7b4a1b019c7c03aa5b9bdbdd9682645f94006ba6762ac7a6c525aac457ab4bbc92f5672c2c8800c33bac1f6bfcd0262f9da706ca2034aa8ba895b304cb34a070d2b551a0cfa41efc570aefed2f24e0ce2a863d4272c41261893c8d650d25b42c41fb9cc950bbeab01303008664f9620bc1607d30eaa50d0c0311cbb84f982e544a25c321889b0fe92112409d97bef2df796492629032e08ed089e08a91bdc433d007ff0518ff3e50e6901b1271925e16394d47f30cb28011543b02327e0a1d4a7f00947e695071f85678ce6f8d7a7de691023f5db3ceac719d382fad4d744a9a9c14348f54f802175fd2b5f9ee4474de4df51afdffd03f2fef6703fb0a35f638967b8dc0f8f5588ecf5e88ba32ca9457f2fcc68c23b263bbe1704ff55f869063f75383b6ad1ffe27073b8f447fa5d105cfaa27712cdf1b7f6de4e52e2de20eed8493449ef14c99e7bffce6ab82b62a473f61a96332cd2cfcdcc16c9de036ba4737f98752f9b4c8b4e936427923efd3429fb5317248f7f91e444fe448ddd49ea3811e59930ffd7ebc89d64f7a2ec477dd43fbd7405d3a2ffc4b54b8b5e8fba64af445649eaf8d7a3fa433daa4464af49641fab13d9bf12519b11d11c222fcafd1aa645ef945f40e5d631b83ef907c172c71622fb0d599da4287b4694fd9f64070aaa4f34c771d020cafefdf5a93e8d36833b62d7cb8d4706f4572c84fc844069d11fa88dea53f6cf86fc3322fffae45fc7f8b710f689eb1e6db494f9e5f2e578bcd9c4b79de089c76e39c9b4982651c4c0e89fe104a3f329c87cf2319f5cadd4122dcaa646e42cd77f3ed127efc91de5d393e04f7f4e21e97ff10519649c71c6182a75e84fdc4a52c78728718904b508846619c680cca17f0392f074c693f4914f4f4f4fd60c2050c88c95654e29a594524a29a55e29a5b4d65aebd34a29a5d5412f404c702b58298e75777777777757eaddedee5eb3c6fd5185b5943645419e53faa86e9e9f237de6cfef163ba9339ff2483092c4203f0b90d293e76c92ad79e7f6d4f322a5ce258925b25c4a428829592e49f1d23596e9cc9c7a287750b872490930592ac125cb2529493e592e256145ee58ef58d4534ac59009ae54278a2915cd27234be4402db045d4d21355620aa5f389d665229135eb50e64deb6e8df5aeaf40dc573c8690ab5f302e4e94dbf459093042fa606066ff6c86a20fa943ff470bb795625168fd354f69665238a570afe17914c5e65136de37b3fa3dbd620b1499dfdf78ecdefb6e2249cadad784ac4a13b26aad7848cddb6021f06b5ec8e6691e09ecde709fc0b06dc279b4323aa2e25628781ed1f9f43e8aaf1edbb4e2110467f0f87ff128e6a6afdc28dc837f7eba43ef693a1b7a38d2785f134ad85c32891acf22a339b3fcdadde79c39b39936b3a9cd9959aebb1b08182cee94560a22c5dd79e2f6c76255fc18b92bcd776baf88750efd0c8fd6563c9370aae04c7169e311491099fb2c3287a7931d14ee389b7cc6ac7e993d0cf29a4d84c8d44c676679901b73d063b56e7fbb797777d7b6592b75acc5296608cda199a4c36e12b613202d6c7287728a32aee4ee3ae7777777d79fed576246b25cdf9f3aa0399487d5f80776019518094678b0703dd0bce428440fa3e9a7c1b27362dd5168be86518c340fcd53dad57137712a464e4949529e88806044525393cea1df454aeed8313f638847c278e613234ab94cbfabb11a6b1ea924732f61446977692ffd549d1502055aec62adc4fa4a3775ac95bac8521df4c314eed845b9c654bdb346c7c4845296cf740223b2c4461a48f77a89e2bf17a924a483eba0df2ebc5e5c9439fe9b9d0927ac436900365cd3b44c2749cb2a980e6304267b9d4afeeeee8e947d6759d6f6189a4f938c7f13f97713a527d9dddd6ab51bcc549a56c87172a9b5d632d2a7be0365df607a472e19a144f61f57893b4e2f53c99f86ddf70bd1f77e14b1507ff72e44fffbb1a79df4a3de1f159a4045e8f142b18fa8fb8f19f3f4e4c58b935353d3952b4a4e690d1d481dff0d09687ae9f944731cb6c4a5df3fbfb3de953e55ab3d69450540eaf8df0064ff49c6f482373c6e7646d2a19494a219aa72a701063940b65cf94cb8f7fb98d68a1a38c8936a594bad62355c93c695ffd340b4b8b2054671e58f202dca9287746ae59039740b135d6d55a794524a29a594d2ea4d9f52daaf80995bfaf4d39a34ee7c205adcd9ae5614d70477fe4fcb166b88b1e5a43dc91430f3dc773b4bdcb187e60fadd43b359fcd2b369f7db63dcbbd6f23b6f0b6b87d0f35cf3c6249f6dda49d64df46bde339fb86927d1ff5cecdd9b710bd23978a5892b39ab36f29cd5361d9bbb78d69ea9d2c1b5d934cce3e1be70f59dcba70e99dcd8c2e60c2642cebe924d1ddbdbd023c6f349eb78ddb6fafd9fc16024dcd86419acd4b9bb7c1b2c59ad08416b3a7c95e442b2cd462d64b7ca872f64d247da8b5cd3abaf4b36fa225bd2366ae76d23baacfbe9f489ffa997b21a47e0b713c0dc71164def068a4f386b9efb19be4ec7184466a66a15421cbfe0c6609a11fa4c5ec53210bf533a3f02b04af2e13b7e73cf0f7f06842f67e0b4713b671c34668666d2f730f6b7bcfdb77216bc32f9983fca0e15593428c0834ba1803c3972d5998f83282325d50e1f231c0bf7b960763079cf2f632cbcffbf086ab16b3d749227b2e7b2060eef6f8a7c5ecb3978e94970dc116b3cfb2efa2ecdb49f63d947d13d521d4978e15441f09ccdf462089cb922c89a3d49f305690fb8451fa134631f8933e4c933f94642e0967110934674e2bf38a6dba4e794e2fe22b88c84f074f491d4b886445e1f00953294f5c0489872c2159f697b9886396075e84651fe79a3bd9b3a5a32e50f27a151957bac4b7f4e595f982ad7fcdef99ffa22fb1c9231023cbb71eccecb698b5fa5d2dd6a0e6916c38d12b62d5acd2cbe58365bd1044082262adb51907d965054c48819d807ae2c21b309510eb081546b24f0404b742b8f7be86339ef635607bfb9d6b66eb5554bdd57eab4597fdb1f53f1d4479c43ba412091232f3d45942ec38f3f691645aa64c993265ca64edad1003646de6999025a4be4879823aa7ffe2d15a141e3d3c82a20d5d566ef6d5c8ccdb671fd096bd677fb33272f62de9237316b6351fb6d0e008638bbb90cfa4fe76b062fa21fc04d3c5960250d9e285153fc6dcd9a2945231ee947abd01b3bb7b08bf861a6128ad957a91061a673cb9538a25a5740ba5748b08cca0744e4a84535a2bf582d25aa91765743932b85a5db0846a29c27249b17eb73812c9e1bb726d22caf3bd4dee3eb3dba7fe2745bb7a03a418b9c353eaf409b97f72d64e29560f548bb3b073e65f3d90fb673bed867529990a67fd3b936b4b4a6537ac9bde9433d92f907b26b75771ffcca0d4d0e05065b95ad9b0a23d6710d2e76629c5aa59eb457e6e4915e0872c533a279196d9d387cef6a8c4f94e6d47b11938dd49e507983b5b997a3f5270274ef6de99b37aa066f526730fc19c659af7e3cb9d2f7f9071e7fff0c2ad8804fd18c3f37ea0e0ce47793fc448793fba5ceff3f209dd023a587952fa703536cb16c6f00232a72f2075a0dcf9369e943e5a96df81de8f30ee8d57b3ed69b129e640eadca43b7fecf1f15a59546ca79627a50fd53270cae1fd0043878e1c2d164e0e1467a5b3f40937505724718571ef9940c144145b4247964b2d90612232e24ad3bb515f792309cfc7ab793a363434d4e48d2f50658e52655443e0481a1a1a52c283eafbb1a78cada424c70c2549995efe56f96be5cf953f1f41f2c78113dff7bd7c227fefdf5b15f2f7378afc7d4c2b60c91f0b31e48f85a5fcb52043fe985ac0227f4434e4efca67efa8e8bcce47ee82e4ae93dd77aeee650cb97bef1d1fb97b7b516022770fa6d042eefec51972c794c216b9fb9e1e72f73f1d930a25c81d531225b97bee03ea9a7a2873bf7d409c6f5b2b6fdb56464cde988694c85b1924f2f6f328dbd73e20ebdacb37ccb03bd5287beb8d28b2ec3e4fb86ca40605c08076d980d228e84cb293e57c2246854ce9db2bc6874c1f14e394e9ff181e327d714c1899fe8b0d2332fd9e1f36aac8f43b4892e907b5f144a64f248436d2c8f4454022d327c10437d018228304510a4552e4d20a5690e9b71116b9e737675ca0ac114ccfab54c8e899be3f36d2b993402570daebf63a68bdf37c0d3965f79f4eb267f0afbd1774d0e6580ab868138012c50a3a8060045c52404202252ec2984146098b30ce844a17289f99850a2cd408638d24d48021f76bf00135789364b1210d269e525802890f49482041310231496b509f454343432e885b1ab999a2e4eeeeeeeef980dab916131772ca13972d671c71460c0d1cd058230da53022500385eccff301b992952768769ccbd3901952e4fe017c400df698a08c29b2bffb5b339c64ff205704575861c10927c034b10209c60a2ae050430a612c1dc17c4abba1814505273fb6b8e395403e203a97caf02103db3242055760f00179eb87561e3d305fa8a088ecffba54f3a20a477f7c40ee19fc90538019025344ee97294022f75ff001f51391021630c8fe3ab68a0a70f8f880e8ddc07ea9e20b0bb9df826b05171c734700ae411e570520a30a1930e4fe1c1002438c81822c4655da580236de5c858d36a808028c124444e1336019637dc44993fb651bb93f001f50db21bc31ccf04282ec0f801e1c5080c6183e64ff1e97670d2531aa400110d9df25458c1cb2fff3f8809c8913496ee4b0e5c9964b7924e0c30d5b1cdda0254b0b307fb14ab75ed44c5861851ba88a3f20776e854c3ffc80686f41491f3c5d48200693dcff62bf2493fbff03ea03207119c000f2e8030c165e601c11860c6150c9fe3b5e24b0228b00a810208f728a16799458749164b84002001758b23fd88510d9ffc52e5e5e5c91fd7bbc1893fd7f9ac8fe1d043991c9fe4442f8024bf61781041374cca1561373c96a8b054d728a15120bc9458b1417680993fdc12d57b2ff6f8194fdc516b2ffabe7874b11d9bf8320225cb8c8fe399c5a3120797465e7400b157468b143762dd86812a2894cf66f7d406eb4e2208fad2c70c8220b33b23f98854af6677d40fe6dec50b4c46444041428b0f13ec0061894b4c08395299860db1957986c38592cd8c1e2062cccc01246eebfd981933ee05cb59ae94b6e2c503061c9fd361f0512354c2de47e9a0fa8af74d2d0d0d00c306f6c6577b9f2e823bb73f12ddc251777dfc22f705fa22229fbbb57c124bb57d143f62acec86ec512d9ad70ca5e2589ec57d090fd8aa7ec1f44c44a52f60fe10a51f617218cec4fc29537b22f2d69c9fe936816ad3e207722c50754eeee38669029a648cafdaa0fa89994bc98f9801cec41c9070dee07e4a00d5ce471e593c796142758a20243f6252a60b27fea03f2f73cf72c927ca80f88aea40841145d72ff074ea142e54d89828a10704db93d0f8b15ef2298bb7b6e3d7b95a614e57ead27ca1ddda17892dd1d0a2ea0fb90de7117ab58c1dd5da43c978a1cdcf9d5b138a194e58910e4fefbc419b9dfc12a5168e895d8189f2207947b6ebd5e8a2de56ef716f0839cf3e948eabd22fa738cf4b1479086a4defb23f73b2ae57ef71f7433618f2730552834935698d205ec8446830c0ca9a7d08228cb29b28ca992e5145980c8b34bef58ea3ffa55e252e9e3930d3994e9193287fe5855aa9f5161a47e59e5f68f9715f4bdcc43500f44ef1d42e4419016dd22fb352043c10260765cc4be8bb777b8776771f755ff414a858f1c51fde5f0cc9ce30666ee3b6b5321cb7fe625ec86a9ffa09bc147ee7b4752dfbd8439be3735430b660e8f22e40d8f00e68983b4224a33ea25d32610bc1715fe844344738c17be680ebdf68a40bf02f7de5bc29cb7861983b437c81d32b57db9d0220aeaee3de79c73ce39e79cd2bb534a29a57c570b049d748df629bb4d8d8a0695b2c14e746912117523e9238fba6f0ff73b61961182225c80dd179a6738c14ec87102d8c548da8fe0cf0d37f535df512ff34aa673fce557ffccdd23e31e267f507ee59edcab9e43fd90140a0b217178484dcd0ba132dfb24cce3b55288bc352cee628a8a02128fc34c7efd33cea55efa8ffe03e0a7f40f32a9ce43e4df79ab5e3ad6c8c190ed99f3e75ffca4686c3e4a128642e643164bfd90dd95fceac88ec1910d9331e9c88e6b83b913afeb01f562eea859086a45e2584b4fa2324d01c177ad11c9cc7818f04cdd427e9a3cafed5fb29ce9c64ff0e5b881657ab5fb1fee6c7971616f6bfc17388e62471338483917ac470efd33c8e5f3df8363fca980d0e81e624f1340f90c6bd011f8542a1f010cae8e6413c6d3ee1eff80748d80fcda1effad67fe0fa16fe233bb050889b3ec01f7e888fb43011cc03b32c2e6148eb79fc3feb3f78d6ebf8233cb090f8818e6f7d0b1f61611190c046a9c4e3c79ed64b186bd514be84edf8517c090b3112cb8322aaf79779945ebaf670a89e47b8e3c330c7bbc27f1ceaf8d9e3c1971fab7ec541374fa40746f20701f048603636363d1e0058c8e67b60a455078636368f5d7fc4069b801ffc1e1f012d3db0a439208f6fbdebf18f93c8f53c5e02f85b9815c483c74f5818fe8485acfa3d1e09ec266455cc0abab9697d0f2c74f32d8ca47a9c4702f390e51d4e28843404e76fb010d203242cc911a42137afe38ffc1fb9c13a1ee75b1f012d77c7b3702290c4ddf1acffd7f1ff3b5e023a9e8559413b76fc84e5c8f1139643c26ec26933979852fa49ef34a69c932bb12b4a5762d3a9c52e2dd29f4edbe6e2b1c281c31da1a439aa702674b5585f479823bc2388965a40cc45b8ef1a8f620d4724b922094731774f13b2b4bfd1b4b7a1f91b2cc4d2fee6258ce685c0b7f90f70fe061f693dcedbe02348435a8ff347580f228175efea9d54f797f2dc7cc77af089b4f0c479f99530a4f52c2c34bdd01cfa2d4cff0112369f581f4cd8cd4fd8cd4b18ebc739868591581e787fffe222da7b2fb384d9fc38bd747f404e51a8ffd0d5e2056d1772df8e3d942d7e19ab29479324c5e888b3bf7de761ad35fb9a7dd98674ee68fa8464af619be1562151353883f69d6c1efadad4dee61d4db751550399a36959825ab2a6690f73e2f6644dfb1ee9c3236bffd301e569ed25d5348d7ef768da6ceda9f63e5ecdc341e768402f2677fcacbdf6a0c63d17765dd7596bb3d0e6db3bf6b6a8556bed5bca43dffea53c2388d97e67b55fb171ade6012bdbb7da6b58d32c4cfbdb3bdfa2a6fdf4b4a83d9023bc1d4d55c3456892460508a48e6c97edb388d27e32b36c0e39ce30ce9a524af1ff8e3e6a4d9525131311b4b1a9c0e1807a8288a3eae5c8f3318cf8a6f8417bc28cba313d0185968c06a28d69264b26264d7e40e30b1bc8d4f0e4e88924438a3086f8e2430a4d92c8e04935b068103d28265e964c4b56a0ad8088a4269ab0b14df16264cb681943312d3183264ba6255b989658a9b265cb166b6f0bcce074c1b9304ba8745b5c56964c4b84b861890c291fee4c964c4b5010630a252ac8b889064e5ab7612451316ec6b4c5ddb2645232856542891315cccdb264526282573329417aa1a2c0a99d2e4e964c4a66404171bf2c9994b0e07d2903c3b559327d400c0f1f787ac007bcd42c993e30a58abd16cc1163a2098e16a556ac0825374b45ac180f45a015229c978dc1e6d5f30ad273a5cb153037d7be624331d4d86bbdcb25898b14f03e15d1c46cc670619565a846cb0b38b078a259225231495999a086992c8e70f840c3d532a46a220725292b334d3079014574ddf896a4a4bec0c1c3e284b222439725f641c135792f7b0493edd5f30ad2b3055107c412bbc509f7b227c0a1487bf5bc82f43419d1397289ceb14d533a6703edeb042ec490d96bbd8b458aa53caf9775e385faea7905e9b17245b3f665c612b7d77a778b239a23c140c0154a5930414016a32a4408d0e285891813042c3909e088ad4b199996eb65b994048c4e875b93e552122bb62c5795e55212258eb838592e2531f29ab85d964b4968a86e244921cb72fd0dcd04970bc36971b3326c1a17e5f4657169aa4091b92b24b22f4008a1c20d4f5458e2b970bf32dc1097e68bb6c305993a362e8e263c145c1411a819ee76c455b9b5072d4a0e3d5c9be5520a33fc7067b25c4a2185266e96e5120a645e455c2ecb2514d020c1f52c97502823c6a5ab5fc30e68ce7cd0e76660b1677bc3bea99498fa07412f959aa1cc99bf592d95f2148ef95dea5eca49a17965c5978ca1e8dc7a665eb529da3d2d76a1ed3c1c15973bb7b73d9a63a6d297d25b2b1eaf7358363820cdaa06c6aa69d1e4a03a76fccef65b685fc70744bdf66096a16e3ff4ee7d5b5fda0ddc709d36f49fa153ff54751e28570f0f009d88c3dfa1030bc002cf1b280577f4ecc3d3f1bc77bc45bfe087e7e281c3775514a76a633600728fdc3c72bbb04bc6729769d69ba1f8c220cba58ee336ab7959add5a382524a29bd53a6286d8a1aa5945252b1e7f7bf63b499525a27ed324ecaff1de1dc2c683750e3dc1df44c4a29a547fdf328ca7f56b053524a293b70779c27bd2970fa5b795333a8cb22339bde3ca50f0e677257a7f4a9a92c43699a9dd81bc26edeb5d975f94ed20be7c99917cff69a79e56040e45fd24abd52f73efba134afd42b45a5b2eb957aa5a9eb3333aa55ace54d0fc011777e57ea3e339b954df7f502df2bc5b1f2ac00469f2cef8bf2109139fdf68278e64b40cd447cb8f7fe6d5ad178201712a139770bad13a1994111914d3844742fce197eeeeaaa842975fa7bbacc5aeb32d219892b779e918a42a152de4ca5ae37c3d1f308ae3c5534ab707833f4dcad56ab158d47f3b1240e725ac34a0075fa1cf0a64d1b0739b5a9a159e150d9749c8dcd66359bcca65b2342b6e664b5ad5eae3854de504a69adb5565a416fce596d32cdeb910368b7558f27b11ef15b945f63351a5b3318c3e2e0aa8ad2aee22254d6998f4e5b6b4d81178f52ce595f7e0cd8918b542a1f854a7dde4ca7e270789bbd51b41a50eaece0caf26d2af8f68b3c29a594e234cbb3b3e5dd2877663006a594d21c3c6c68d284490a2f79b460eb79e4901e82757f559e59ae08fdccddbdd455e190ee61c7795de77137214e0eabb6727852b63875ecf01518a76ca4b1c8467af62865233dffff7bd46070e662239da5df2c67ae1e3d5a5e8e0f487a38eaf09c467a00c499e309c0024ff68e0f9d258cc8463a4fa923ff82f9f2e497e111049a2c47faa3fc5ae977346465b9d2ec5d5134eb5e1f90c45996490c2c00a2b343c7c7721c64b1cc5a7681273f2965880130cbef82782f2a7111aa23c7b519064080d4f70c17a99ee36379eb63f9006ed2e8628b10f5fe10bea37428cd52afd9c67d5e6adba414bb7ff6fce96dfbb656eb9ad55a6badb5563ab30b39c50d4ba1e8c775e1ed6e2c03f3c79b3cbe05c5195bffcaf780e09372c081061203a9410f082dde4ef3c4bf28973eac9d30b0e33ca033ee68ed0c372802657dd277791ff64cdf74b803a963a289c4d1751bb5dd8e29a87556ad7777b7a59dd59bd1d9fddddddd343674b3a9d7ad66f6334ed3c07b2fe8f4876696b35bfdffd84f2c16db38cec5ffff89fdfc7fec27e6b11868bd3aed38af6ff823633f4f797ee8ffd3ea1ef77d9cd2150ef513933ed2c926876e3675960326cc7fe699eeee9e9edd188416e597bd5cb95cb7dc652bcff69cdf3e34cfdde675e85e67cd0e7a2da7e40e5942ba896872e3123c8f209572922cb16db1c395d77d3d25aa56a7ed81a093d916b4715a56dfb590c8c2b6cfc2242cf4c036ac3d9185713893443db0ecb930090b16963d510f6cab9d4dad3bef43a5bacef3c69aecdfcdba72afb5fa7fa8d49d515994dc3e20fa63b291ce99d62eeb913af24190f25e9a99d58ac6fa40a9aeaa7e148f2664af8512b669ff4369880130d3950c31a0658a8b54acd9e780f6374b1f1afa5893d32c96608babe9fe321cbbc51632e6caff11e4940f48be94d26e70c49d4fe56a4a29250b676a9d829a86853800cb4020505f778fb8881432e68e3e3ae73277770d67e00bca9dbff1586b35ab795a4629a594d60cc668776a0019ee67f0c59ddfdeed0d4a70e74f9d1d640a3522c9d662210ea0a0d4acf3cb715ccd386b8db8aa65465cd5b8ec021cb8aa6546465dd775ddb6bd9cc9db05541df77d401af6ac1ab9164ab16b31d2d2795ee7a4c583d9de99b5f3bcce494b125a2c4cd6a881eabace888c4d0a955a0161e7121284dea91c029a270427116c83831f0de40626f4481fa75e8d280f0d8c83c9af1cc77538847420d3759d0ad60aa16a26dc263eb2d70f5e6f9186358ff2ccc0e40b91f9325885398cc21ad6cd70dd2541f509b9d9e2506928ffef03b249e6d011f9a3df0b923114834024e559eaf3294ca6280f0a26dfc7023ab833df4b147f663c98aa83c9e7c29b8117ae16bfe98a06262454802c3a1a0b0b7369ea03a2461ed01a98773535300d96047c514888f2d4c0e47729231a18ae3b78af13f94eca783730650eb8cc3c4942818088cf4a3926f7ce8e3c7a4f4e90bbee2d0864b82b874205d6ab64d7987038226b39c090352e324885e90625730456ba60233604f33b002754e05491c10d278cae93dccded8817c137224bdb07582280ee960d2ae47eefb73664c9fd17743294fbe9f3bc41a5e5aae1850b6a5822f783dfe20a5e1330723731d1a044ee9f3706bef2b89ae14bee6f62afabc009c989f0b6359abca17d68440163082942ac200858145f8af0f2841a2a8480098e8a013631d4e9dbd6c8a36cea716292218b262280618c2f4e1fc8828c219c38220612c49ca0e83a297db2ea544a29a5943d7d074ba5fc1df2fa6acb9c73fa742c99cc96b9bad7e946ecb670b52c99624821c8924b83d081040f4b5a50e2850b5c20b1418619460004d20b5f6e282a73c19bca92a9e8293b25e94a706f964c4527c8e36b4bc14565c95494d4e46a6268f0356299174ea81a46358b0badc6933b41c31ce3648c51e7c83cdacb04890facf1f480a2234e8c0c8d9b23cb2b62c2c8e3cb062cc05c9a2caf8869e2b3222689488c0f3888e1218d26ea547c3de8ddd566bdbb02b756d7d595e7d52b827613ffd571ee57a967b4c09513e449a7a720dc4fa7f96fabf636488f2b8703cfd49feb348e0be716a4c79593e777bf2c0080a87dae9a7d6bb1f5af55ab5eab66df5a2c7af36b715e33af59f64a3f73b75e5d66afee694e37b0f34757d18a9c684591e3369f54a422276f9ee8a43775cfdc33bf29abf9eff8a4d491d469764f7fb1a79b5a50f2fcebfffffffb5fc69ababa92527ad6bab2c45d7737a59f29edd923cf4792a59415359e50b9e83a77ea2ddadadddd3a3b501e28adb343eeee965256183a5f7976364d101fa2bbbbbbbb72d77453dae1d8d4523cd66457f364d82d3bec70c453ab9ed16979d0414eda830e3a389d4f9dd2eb3ae83083c826f59a519fb1db36cfe418f07a40f37aa74a71db80bfb679611e4c96b217d0d2e583c772603f8c91f9a3bf7b7ac811e599b7c3a3053fc8041e1e6c2562a49bbe6a9ef50ce9b1b867fb80b2dfb8fe97f6e7fb8c55b9c13cf2efca1c3badd5dcce0d38207ff43759e281ca75736812153931c18431a921bff2098631f29cc9730c0e1e874d39bd451f06a44ced7dca3ee90efe9e77271e89f040114770e2126a1e41b43b4c70be8642b0f2648c0c2880c012061136e820b57821c11165b62c412104cc5d8deca87ee18b179e0057ab55131cc820810217b62841164fc450228a2a52f0448b07c3605981487bcd7047579e4c2f2cf156354b7737edeeeeeeeeeeeeeeeeeeee6eda2df18e626fa1cc94520c7677d3a658cca074d2d55540e6f84b0df898d792fb2dd2115a1441c91541eaf88ff263002b0329c1f57ef77183ec9ea4c07cbf519a7d0159448a199014709ff3680a31a1f477eea4ac19cd1a95e1aeefd93b14e92c9b2f208b48310332c745983f7c1c4076c3ddbf7d011760b941b883161d4abffb8fd387ecfda19db3e6f9010525e930a6346f623aca75777247d39ddd39dc632027782da562a654943e3c32fd97f491d96bca9476ef89f4e51794a4a3df85adde691e1f9eef0ab4fef6b9b00423b7db42eeeb076439c76eb316aea40efd2ca4913fe8d7f0255ea3ac874eba76a6dcd141d617b7b5ba33f4ce915b866fd8ecaad9aebb7b7d96575cc2909b77bdcd7f801f071fc179fc36183c0262a11b2c6136d606e4f192f2e0af6f298febeb5fca137e7d1cdf75d84f5aa4bf85dd848d9bd130c492e67440736e9e157473835975c26c9ef5c1b49100ce83f808d2109c07df06b3eab39e858fe060a4156679b07afbabb798e581eafd55ef0fdafccd7f003ece832eccaa18b3bef54358dfc24248de0bb1ba6769df6261967d567d968787f078d7bbb010abc3250c09a279a8444d99143929119124040000f315002020100a880442915012068220b81e14000e6f943c745c3417c9b22c886114838c31c6100280010010430019a31a0bb068798f26b6eb7b7b2214da68c9210398e08d5018fc9557a4d31382e2d0dc2ed6a715f8c1a1fb7b6ff6e9ec4df0a4ba83fd7c0e6c5e2306c71d3eb0851dd72860f2ef5f530d3def372bbe8deaca1d9780b0f42748c0492460002dc926c2c01efac43749996aa794f441d7fc0a33e30a4431a24520ebe9bf5e4ba10450c9333f1960c3c89e13450c8c7a00b63ea3e03a8b4723cfaf8eaee7e9b6bd8dae00312997cdcc7d52206df47fe0bafac5103ffb9ef014bf821f81da829e815fe5baacc6c0d36b480bb1051dfb0115924d05dd1f4f64d4086dcacf8a1535d94cab63814034a348d7a57f89854eef08a6c276d74a61a265e16c8ad0b9c57934537f2c7a7bf55b5fd4913020a306048f3e2e5df9297968048ddd501ca4e02389348d1d8002bcc887640e3a1d9e36b66ecfe1430c799bb991cc339c1ec405221ae8f30ffc0a7eee8a8e1f4830f71be8cf38092accbf412ffc20d6444ca81cf97cdb7b4eb65e6e72729dfe813fd5d5e60137b01932c72bd92f0a06cdc86b92c82f5e9f91e8f0e32bf447a5710bd963b28d5e33ef0e421f2ab5b720a715b5d6ee71daa0f42afea3970ccaba1f3a1f40065cfa58784761867b4ec9565f4c7f1f5c53c7d937c3edbf12b2ce0777168ef12d98ce61125019af474290462d59bdc6556b6ce364b0810f8e1f6fda56aab6c1d5e8d8b7400c984af8e739186f5904f5d19d76b7dd7a5848a3bd6af4e732df46eacf0816ee917d16095c836a7d556f13f537b592ff4d800021856f33869c7b832e82f843c8a939a227568e55db5d26ffc83d0bf751065fc2d2649abb4c9344a6a6e7e49fa8a71aa2f28effa83fbd0a146b5220f5a88b1e271cfef190170341fd5716625143792521a06bfed477af0ef6425eed3c2709363de68d738cf7f71983a777ad10b9dae0d7be04b7a68538ba0309599a546422080e4cb28cf21c5d6f3a230298b5a896e65a5f347a585254651b391c36225373858e71999b349f3cc948c8b01a360369d4fd3a91ff5eddbb71193eabf51bd59f60a4c0e2bcf8e8ec0239b855ce53abf2bebc19c29cccdb3df333ae7590aa367910e5677f7a6cb9fb45ce35455465c5d4a7b6d4ba6f44670b7cecadfc3aa3c7eda122ce216c5ea5fb23b110883e8fc75f42246ee4607ecb7b68bc966c9fcac67a0e89cbbbba75b40ec4938cf902fad3b05d4051208628d18b088eb9e474512794193a6565503d974d120714ae5604ec12f843971a5377166871f5ac4661149cc4e9c1e5c89c9e2267c5c3c03db2fada49dc8661461926a33fba7c7b99999a8908a9971d1221d0a62ff4440ca91c4c7e8ceebe4f5a46f0206def27a65340329a5e4da2808763b0c1757fe6b0c6e4625c8c7b8c73453778a7320bd92e3234ea54fe05d97b738a06feb082f5dafd087213e9714a445b7e61d529720d58c4f7b35d551b872e25fcd1781af17691a1c1fcc0da37da42dc95714e1546a6de3118aff7d5eed565babd60c656b7b5ad3dbbe8ecac3ffb1ca2b00c458f32d57f46504b0350a1b4480a90d87009aadf6cab76196607bae32757f6499c2cb435a1d3cc16709764f3c449d556431b5aa06ec5d005ed9146f8d2c4fcd2e880694321987cbc989289fb25af74053363a3de5c1b065bf02d66a0c16a845ffedfa707200bcf32c4c355404a8a4e45a6328b0aadb6925a42e2a176415f530aaca2d25adf002b03d1d94518839e8be5a3332d396e440d035494ab851425405db6b83416f102823f4b81b896b9cb96b51684249e93dcd865b2d9b4c3ce04a67d326e0a6c20dd3f8a036e204f242605f974c7f0b93d4d447d60a8e1e2076ca6c396422fe0794107d6ea0dd855f2d82491eca3b3f45d61f6f21c9dcca691d741102d54c9549ebdc072a60801fb7de16e4b05956028fac6da64346bf3a06ea5e77fcb9be372e3cff820067dfd5a922e2c09c953c91ddd08c5b7da2c8c648498d92d6cb884f0dd3be8c1e05f301fcf0c44423d2e10900e4962a9a24a983b01d8efead336ea44a52e4101287d10f76fb0d99bd0bff4811a23c163c2dfcf62d7ebd1f39dbbee2ce6a4149c21397c38ea17e58da973aff284a766a3a1464699dfdce72faceb54016c9cadacf729948266f0d620994bc210c795ca22d08d061954f4450eb646a1c5206d4176ebfcd17199902e16255a521f7d83c29b295e799b0c2ad308376ea7893723a05e45f139620977dcf1625a4f17add07c626ea3148dd8469d36785e8300c46943115aa6db1711704d54c2d64680e784eaa5d629d90b28b5a4c428fe76a3c33fe978f3812f34b36eac641de8137ac856863fd46588671b1c025c47ccc900a7fe5cfac3a4b5c1ef1b39c45f0b314cb2e27163146dea9e462b9a0918652b3bee489ad4184a1ba57d91a2218c80f03bbd79e6ae72349a895963cb3f52edca69a54dce2ad3d682e9ac448d7399d88702795811661ef370e03f8e7357c3eb4bbfef159efb5825c22e339215b7773bd12cb57b1323391f85785bb6eba54cba9b0fb524bf2f71e160c7f0ea20357b187d597b910d25aabe5e4266d31e1777eb71c3b4dd34367a6786fd04b65911027bda56754067b936ceba16bc89221e7dfa8dde48fe767aad4af3d82616091460cb507dd43188dac603a37055974e1c1649bec338d3522f8d81c266e53e43d3b4c5bfdf01613dfc64c7eb4b9036080eaf62819e96411597a7c897a10d6e43bdf2d8dc8aac3031f2e18904e77f4ea34f6ec60987db4fe2ac0c2ec69df63b9b26a74c0d48b27e26df9c6e8454fb70ac92f225264f6cc1e47a5da6433fed44ca74f33eeaf144c744c012995e30ad22a32a682e481119f1c0059eef98fe35d8a6d89e5b1bf07e46aa2ce30721e19d56f12f55f915d2f4d8ae5f052a9fba6cd54bf161351ac8fb76986fcc0432de32b7870baa45c484dd330d409d9367cce04249f5f4b44890b2da0f92f855472839f121316637701bde0ca5290c0c5cdd0a1320dd5d81ffce55f2ac0c832e48ee09db39f8f96d6e8b43ffa1b14d65f32ad9ac3656e88cf9091e40d644f5c68511e266e9931784604b8080e05f27eb1688f68f220cb6c9b2880c82af62f98e72146aa68043034fc8ccfb75fcdbb04431d835ccd0fe453fb89d25df4f3ed8abde79ab885c29600a2a37414208fd9ab8951d44933687cd574ee32034b153991f166c9f0e52f01413ffe661c0c423c0a45e9890cd7ea63e015aa61d8d1e60ba1b783499538a26801372a805196def042dee6d2773d6384e8a518e8528309df76640f1a14ce26951c0c84a3cd85eeaea71ea8e7d0f2253c8dfb83873ab5340e509e034087d4030571421cc2753fcf2bf693f6c59c42aa61046e440256a413fe8da9a25c37f880e4327f450711d8582e4fb6bb934ed24f7e70f0191067cfe7d6e578a5402c933c2810b3c7cc91da1be0caea91bac13920f7b24f4bb72cd0ffd91748386fe8b273ce8df1e53a067b900823d8935dccc3084db03213e1dea68c58914cc0cab307915762a180feed7164f7308adc27d911b07c1bfcd80978e434cef226b31c98a4ed21e60b1e4160fe9c02196988e32a13f44f9db2b2ae474c3f04fea6830f8a7ed1dd2b30d4c38d9fbb2ee12fed751493fde323fdaa8b4956dd2d774f4b5fb0073f74a1bde189073fbdbeadc4f9b5e20a14c8ae683a695a031cf44afc7674c5c9ec436360053fe71865a6986e9a45db651dd81279715c780a43ea33f1524a80b705c9214b3709abdb18d0aecf2f8b3a799906d54ae5cf83d5b32f085954fc9edda6754312674ba5683d22dd8c7ff344d5e4d0a2f1f8376e3700a757c019c12f3c7dfec70d6a9f3bab3433871a280b8ef77db1d3841711e31c97b609571bb01aba808656addf8859d815227095d705bc1aa4ec69e97c55c6f7b6c4802cd5dad03099ea4150fc73fe7d1dc33aae6769a75f8d93afc9447f4f8902829f2717a171511f325088509bf919ef2313a6caa9b730621b57d20a045e8f205a8d83d9793fea401b446003962683f4347615029213c742ab8e891a5e78975ed5827f919cfcddea1af76533f1d904cf1bba004f5e76944c36bed6aa9355c6ef25a5312b98be891d56086651d1a9790b4a63fc8d27f462eea81db7f62d4de037da3ea8148d0d8fe2a7902b7a1b1b9267500b1cdf35824c28e04e9fb5ae237bd38b4dc8b709fb40d6d8f16bb4c68fda23aafc8725cbb3f8cc602b4540c7b4c3ad1cb18ffb80a3bbedc01cef75ed632974b2522925596be99ae6d3556d919194708e2609c3ac51f3ee5db8d9e3d43cb6727b918ce892b524cfa4b78f245bb1d1d78ee63e6e1b5748629b49dad144acde8e1a735ea4b99e02b00139c4004b5ec79f2c6d78318e536c145eacc6762ea90296fe9e8183c58a00e7b6f0b59dad8a74dc16a410e0e231ab2d46734476e7489962df8724d79ac5582e74e02cf3c6fe73cd06296d80ffa5efc1c507f1ea2d4e77e4634e7e6a213a18268030f5cc7a72509a406e3b7bc7eea06006accb28b0ea058bb2d8d2c39063e2cf752805e3cb8693fc6c544f033fbd6a32ec6f535c8f219f93018417c045b23e1edb615a1683c61c8e1c84832e76520e33a3d96152b81a59112c4ecbaba5bf868bb05dcae48474d4a750724d5f7b3eb6ad7d6a47b561b046bcb811b952e482b7f3b057acce67eedc11d04e0795dfd049aa80197f7385eac27a518a827bb4e314b9b7811feb3dced3f92b7f0ee5546b7b1891dace42fa0ee374f84f25eff322311334429af3eb813129b2a5777fe715958b363ca5595e7d1124d1e2a60a9bb6765d0c8bd2f305ad04c1cd41f01d59f67f50a87ac47a0ba8b68958e58447b0a9496464d33317594de5e29aab517366afe3865c0a46698a8efe1f366f8878c6b1630f7fe60bb104d7a0d3ce3645b71f6e79c1b2e795b95954e24657fd6bbe0ac6b11244ae06157f2f56a0fa4dee9d5b1300eb8072805668237b5741facaa866c80933ead7d32e5b080ea9112ac0d985e9f0c8753aa693884598b3ad395ff3be95888c86cb5d514320ae1852c08d2e0ed473aade52d3ce476681838b8396db01f87e17cc4414f3ac05dfcc251b9781260fec220e08dc15fba501ad5343a5d0850aab278ca22b044e8674ce1c83dc45328735f107bc1d78f483819475a421e0142146e44e0f18deebbaf12bd24488871f84d387dc7e36db0aaa1c388089c49122c37e8fe0023ee3df0378ad58a59d8b18bd1f09d4b78a0033406e10b63c1bce0fd46274ba4bed3c380b8daaafa889f17e930b9107778c35b45c1d704ae6602bfc5498e858214a34a74514842e8def320b00abec6fdc1e967d5fb7ee738111e2afb1718dbb656fee3df8f1df0f53e318e18bfdfe35f6736c6163f430af26c6219113cb27798badfbd11f294a059e49f3ab153a9ade3e3ec8dac4586ea9a6b3ec427a1821df792aa311bec35545d571965a97391e76000206a0a6d7caef36116603f04f2585885768394af4a2f8c8e4edb2d375a06aa94f75cf1392551e2b61ea90cc80ee9bb6bf1f273dfe90502517d1956c75ad87d7d9b86e9cfe2ab21324157eda30db8f82d6ff6e3055ca96f643182144716a50fc9e26cba66f4808ef7fbb1f74da4943b5844b4ab36b7f043d68cdc56910a02bbafd34acc2292a20fb2703cd4c5929993c841207f4121ab4da4755b2648e02bf826f4745509694457f7ac8228e419ef8f16e89c846abcdba6f36f137a3c88aae6bef6dd7cbd9e7d0d04d8e50d180c0b515881e17bdf2854beb00dc01b08dbd493c3df48c558fc02146b1002674af6a65b6ce53fd90f5a22dc2a8d6d13c2ebf521d95494209c3377ce25ac6dab939ab21d63e38e00ea1ee79fefb9845200dfce625e364ee0fa662bcbcbabfb3b149ce52859f45e7f3e2608773b9bed15346fb4e5c2dd73de000dc0249f20554674a733b31fcb11557aa5de7799e917da9350615a144497975625711e8ef28147d18e1ea58b6344c979ffb9ca9c84c557d872e271670ee2003b904afbe664c23b20d727145bb09f351ecc11635a3a30743cbf24c092d689cfe294efdbf07adde46fffbfc76bcba7bfe1f0ce282046d6086a9ed9afda08bb411ae57882074b8b37980a75acd2a449f36b4c0a67e9ed81dd93258602a4ff30e81b1e887d7f212b5a7575ac8b121daa56b8f19673a68475e77684618d88487cae09958f42916b07ae99cf06c6bccd9d6079b8e83d00fa94c064bd8659267c11de9ac5ec5327ca416fa12c661c4964747c7d0779b91577c6805807626e907fc5a32806bbfb37410bd3a7da038dce9dcd9de5a06e898c0fee310e195cb37086fc92d12a21ae59895dfcdf45ac1234a86218a3ae82dd395d675c269873cd3b2c98a120f42bc51a4320588c0412c6e3a075407f13049c91e7d8e1007df0a33e1e23cfb9a87ec1938f460f0e2d5801445f60d598eceb0815d12715e41bcc70d8ab1ef9f8508832d6eaf9b5349228a80952c39ebe8ae9a3a292514e2b3011f12b6ea9f4dc27a3564398a8ba697ee685c6d6b8547d9c29a98cd7d248f559bf3b8a7f7ee52f78a06fcf24f16b755ce12f464f9d077f7317e1a1f052d57286c5c38bf240bd1321dfa0257481b189c226242fdce35a198180e25f971130cad2e16295bc872698f9c1725e91dd732cb7540f748d1f95fbdc7d1144aa89dda555ad082742a00024f631c4ee3fdc85f11f3de4779756b7429c68ba55cffff1b25c89ce81d13cf8a3246b040056de0c9e936fe5721649fa5f4b7182234be1d9046f08e24907f2334cb3d595a9b9bcb1d19f5171b0d74a17cdc1d40d7ce6cbe7dd9e20376502694e4c2078988ed0a2f9dd57030d9b33988ecf95c090822043d749c9152f7330b46e22b4711a5ec034a2847dd7531611ac856e65c5b1ad8f154cff84bf3d5b082f61390ec2cac209ab202237217c3e8bb5b450f28097801452b2e1c1b953b836d5c129d4be88edb18bc2ea997cd98cc191d37d0fd2eff1ec2ef526620c3a0400d1129adb96047e58993e9251dc0c47e00c94b8427b05c024d4b486d671a731e6c86fbfca49129b0afc90a3ac8d42f8f4cd281f8479fe062067f80978b2891561eaa5f6c14d655eb9f86273efdbdad15fa65113212b9bec498927d7e118a25ddbeea6e200079315832ffc0ecee75a04dd2d061dacfbaee589069b0db296722119acc664a8ab42ef68962b86d8577b722fde121979099fd9b10bd2555fadd80d6212291093edb60f07a4516d9c6f3ae1c23c8cbc620dedf8454e83318e7a4ef29fa34518eea7766d268e83a343f61d77162708e1ae656075ed57315a0dbbaed93cf43fc9693ce7c9310891846cbfd6530302e92ebbf347945e45f1543a354ae7fc4ad5884e0738499f9a742c183bc35c41c8faa3265edf3bc2b34836acec425c010d5241eb2223b5be80aac2869c0be6ed7c7d1d48c6938402f83f06850b311ad6e090a42211135c0fba6dbebe83854c1929568c8a865b94b822c0ec36d470fb1136a71250ad730928a29e85da5992536ec9b99b1ce2930ed6bc9fcbe00ea1b7556ff30de9afea1b8d9843a7869d2737f791958e8154021579c38c7aa150abed60d08ca7dbb0afd42052dd0c0fa77a1d9ea831d50dc92abf554083c30068c97bee8aa16642e965e68a9804f5055062d6629c43148334be6e0712eb5c77fef2c8b508d869bf7cd696d1780b064af7e68a6105172c5694f8e4265aa8b76da3115b102e13020df1f38ab51f7e5294aa9bfc2d2e41df33c480c3f54267ee85325fd1360c20df0dc31dc02e8c1b58c9154d4cd3640fb86bfa4b34327c4711acd63c5bbd0211551d42f7bbfd14f822d03e1f4c80c50bddac451a163172c42df1e0a26be4fc608034b5b43740b1e202ce00c079abc9825bfa1328c799b772084e12366d261fabf0a62350aa2bfe1a8d9b0ae13f44f8567539806bc5348337ca8add34585dba9164c82080e6420a3cd804afa9dbb2509c396ab237ba1a74aa443f008248146bebdfa14256d50c3ee5ca0ba0533a64014e1119a805f0c6ba0345dc1d8827cb8eb2a315a91dbcbca16e2c22a97e994120e784a1f3703100d5a656bb0804967d4461ab37a6d9a24840075bdeeaacc86ae780d4cedbd9e5bd3ce7b1ab32ed9847ea387999650529e2ac6c694e6aa30370f9c41b79a659a520b1ae7b046486a2480429580022322982913b5b9eeb190e6567b509abc4ec5998e58159835f967d840803cec045884476898bdcf7fd49aa546b49c6f4b07ae76e85219420b9f740da060e4aa4479e894421863d71d9fe0991b66eb55805a26dc5723dcaba72d780e1796ce7d88678b1d142bfeb9feaab04a3dfc52a206b3571c088aa7b142593fc24cc71948066e9741a5356746b2b0489e782892125d72f2dcc116d591bfe20ab1de509c7bf6693c00800580681fe9ac7695d1cb2f44a08e7cb3303454bffad00c943b9745803333498e3fa0be6472e1c8f0e37956ea62a41345dda47f9a9ca14f08abc3c6f2b9ba79fa88131186c74673423025d3be43c42a0dc6f47f1c40bccd4f51dc8fd906ace6f87b530e7591b80601c88a509bc10cf1154da097fe4d68bc49f09ebf38e4cb9f2b8a012ba8d318e6bdb23c39809083f118b1424987999197d515c30805ab978ed09ce9feb90b3528cc5e53b2b5eec23a3156ac8674f27abde912023ede407123cf1d7735c468a599f0b8004dcc6a58d2ad03027ab7d4ae653de553f80a9f45585261f731afb21418699ac79137dd3758891260b75952035b8916604cb6aa2fd0332b1551021aa714543b5a0a21c8e8e0fd07e0c9b0f1c72c14b573ddd4c9b3e4243f7b336a27cd94f4ed567ed2e8829afa01e1be1eb44a07b3882e0d93840cc36d574e901dee4ecb0c3fc11b3f74546cca384845ef121f1f74ac0b257b029db3e8d8129f1719125f147919063d44025de2039e5fd26d6b39250e1889976287373fe38d667e259c5b61058a725011694d6fe0e2832b12e2f227f74d08dccc8f6abdf29c5b00e370755c5de86c4e34e9d8579eba569c17f4d2a1076a9f31bee0842294761077dc5163aa7c209bcd85b2d2d944d3ff857a80af2972c671dbcafbd301dd0ba0aafc5cf585f0637158435adbf0e61d60ab29418ddb1389609dab1e2120df2f91468838bd804bd2b13cd613fcd28e8f33f6b89c6b02286d938ed222491dea1df3203442a0699a1e27bfbf4865a8add602b1047901281d7ffa9390e2b66a07d5584f32060bee4ad19f2df8fe16e0ea5f9be1a96cafeadb72a9dcb0b7c96aa9195645923042618469ec3647e8f296bb68c56b944fd84ef738caa2261f444a22e704d994eaa82ad689a2bd540b474ac43e75e2e8dba1a88f8f007759a867f96d31ed11f3e415cb5b7f33d4a04de58b0d9f36618878d59d418dca9623623d7dd7a9d4547268d01d63b4b66e5dce2c823a21d22ed67f7ec1525d3e6e5d7f9d8dd5e96d710a9d405a31315a30c4cda8ff1a21e43b0dece3ec26785abb3e83d42cd846f4a03c71f23b4f027461997df1a96c828e2b81295900e77d14196c9eb3f89753195d61342ce6123509f40fa24c0fc18fefbd445a6cc9359fdcd3b7992913a8bbf95f0aa4c2074e78e280dc8c8239fd01b85c66e42e9e659f6cf7df3c1b4d250b860818a5b23f84580899c3cbf6ae7993d5c68d74332dd9ad899a1641ad7de5e804779b698c281f4f65ae9713a90af7d68a480503e43576a1a4fdd09c5e7f352008d1cb676368b560aabad7fdd1a76d7d09f72c6836dd1133d0783490d8b704aed2be4b9a69467c178d0e96e1143f0f17fedd53951b5427c1c42f46a84aac987882f26ebdd0500be0fdb06e4ec71182e4c6cbe508b41c851b9d1bd31b0ea02828ee9cef5b2ee157b6d360f0432a586e0d4bc5c8916d79223b2c698a809a889b9906f68543b603a808771962102b3d12d2c123a7ba259934952659fc79ea19e4ed5e60df0a3ffeae5196ef81cf740cb412b9559c872b436a9f3c0af9cd71411f16100490cfa3b80c8eb97324fee245b42f61197756bb11a14b2784e1975f3e382f1080b6d3a0932a3d08ad19a32b8f8229a52effa75e539026575944fde603fc7e57cfaa9694d7cfc37fca832d01b0569b59f78f5a911457ea7e5bbe2a14455f2e15ec03c06413ab9416b19ca92b232685c485c0bb7991e12473a1363cd70529be70f89835daba03741634a754b852be0b3af2dc32d0e2b56eb8adbbc042672bfff4456a4303a9eab8dd2913b177a0859a48fd1da32b31589c3982d44e6c8ac76a81c41b9e52ed39b465ac9b311298f3e9e6124435da7c9a0fa14d217532e8add241d846ee1bf9d7c69e963cbc502a841c0b49f1e5ce6d0622af380a7ed081d2427e44fc435e5341fac8825d18d963cf3de81a048b4fb92f83b13c41fd97a69e20f7ba988e76275624f8e3a60b7f6eac5739d78cbfac819a941a97b376a534d0f50fe7e6bfdc14fef08937a8c4d1a2b706ad79b9582a9d3b8c1ee22c95c2d0919961776703a40c015581babae011c8c6106f77ffa8c4da1a197e2d58e17ccd1bb13e1527f9f28bc350fc7bb47eebf1a807bc5f4c54f11ce04f13fefc7d74bd130b84fdecc512061fb9f2472756fcf73c0a33962d8040723d37f9af4c32a039edb8549feba7e5c5b8aa446c996184fda22cd2c26e5bbe8297cc63c0480f7715538526ab17b28e856d3d155ce56e5ce9f62a395028bcd27ed8d90baaf29edb4d7b1ba97ddd4caa50882ede22ec272df46aba69182e4940cede60c66717a4aea261157444bb8b926cd609b3232b1c2985401bd178bfe26b8fd42adb61b7bd02ee824fa1dadab34eeb655289fc56da997a63c328f3257dc1a836c55e3909d8122b316f813e413e562897c00f77bd7206fde198ec6fc418b5e00f9523c7bc302324a9c2a1bc31baae67e8e9e704216ca41f30a4ce8b0d951964abb182d30c0b401bb886f2557519872676aee195b8703492c39a7cb9e1eb559ea5c6eb32faaa201e39cd59e1be1937c69960e3b3851a362dd27a9fbc6c4b7508dc6bc12f3867f007ca9a1fc49ca0c637a68d077f6dbe991e721c838fa3b49c90d22ffe5b7858cd220d7ab7a62814d449571bf0343cf59cab79e5892ae7245a7ce9285a0ebda87a4e524671080722f18699bed10a450ec4c203efe3bf6df3240ab183f5a2da1111b811f8ea8427a9c6098009bec08c3fdb25cd04e21dc868a0fe3906f9a455380a487a9270cb87adb4bb21460c5a89da3f48aa4892ef5bbd4c6a1d0d118e803c09c1d8272943b68c521686ecb3612a7b0b79b61a317bac3786294dfdb6bd13f8fb73bbedab5042b1e4bd36c26337a1f370b149a6482d3fab6fa6396678ae40ab015eb3513d5864047898ea33b863ec78ceefda6e8eafb0b536be1e5327682d6c908cc2da6f0042db40b610131e515b438ed3f6be66ad1829fdcc35a109989f05b3728b959249b917fa7bde22ebab1836d82c878d27c4a9c9d5e0bf906108b79ada9faf8750c5219b83e0ebd835106d78f4d37064b0c201ce56944b31042983dffa1af6892e025fb3342a36a58a59f582f2fbd7873746c9808fad185f8dc349532cbfeac692d96998c4fccd2badce67d62be96e57df613268a56e6b39f685294b2f6ece7cd55d3986570f1d8ce41cc1a7bd03f9837b9300e1983bdcd95e3c91aecadb8673f0fbe0534473d55627b5850198d9ba7e8737a3c26fd31585ea0cf6b26d5eb652967f90df570e59e4ab882c573832932cee06651546e39b21379dcf6fc2178b64dd3d73424b9fbe6244d4be81e0b52a27af28abbaefd266940dcb61d96445cd478093c58860e2bf2472b08ec7509208a2be82ce532200a2bfe3a3cf6408c0e7d8004bb20b1ff8c3c25ebebe1c66d296326803ca7b46351a35e87e5f8ad2fa738f6721b7da1677b8de8828b4415804c28f5449a7b69f41283747c6128df1e2868b90c6ad7eee521b726e9f6068305ae3c219c6e613d31185c8a45575897ffcf5a97dcab47059b6e7c766fcc5123225bd96e65dc73e3ccf9ba1ac4a2b39649fdb52413f9c06cf49639c0a3236a71d61055a5a1b60495bc743d6137b77236ca2dd9893284964ebdff3ce759b7da275c413203ed7378891563adba5e8db88caf839ebf3d78a10794fc554f304e044ccf7f3a19eeb28c8a3be953e32e95f67cb239e93594fe77405201b52bd1d349c1cc4ffa11b53ad560f5f9989e8c96c50a8298f385851a93fbfb6083199237ea789167c5825e40c2346cd610aac719b69cafca291ac9cdcfa353d0705f76d56251b08cea3f17ea8102009a73c6490b9e70ade64ce4a92ab9a24434a85a7bc2c2a2901cbbaf524441664433b6cc089264a824ba438fb3f3e410f14ec31aec11c82ec0676a30895dc6a2f9cc62d4fb59d68ca53511169fb1b96b7c845731a4f4c2ba6f4f7758bd554ccb41a4da3bf14993752f703835e0e92215cf6594775c449288e9615e2419d68697448e79a8f8bb6249f48b6ef708a0eb054a0a256b5d8eb9516424fb23ccef93d77d38e063d0ca46c053146294c32becd0540a042238d7bbeb8b78938b008b3b78eacce0314a4204471bad29898d538f2ef0580ff4751bd10f584a077f9c4a853823877f650ab18ace0f226530c0666035247ba137e6e2246785ddab39c8799b3a10a3ea1f50c62696595e01ba752001297d9168c22931f1b2d2c986388c95131585602864c9b4f7dbe92b1ae1af7af94c45e576d79b5e642e907c8e3819b805b5f86b2158d4861153bf5522668307645b20d70abe0e3de8ed475f155ca35bf25affaddf4d281f0c49a4e3b87852587b4a7141841cf72b0a99054863a001998b9eb13599b778be050cc28ae5c2db047175e97682dc7e2ea25880d1acc99ec6ae743e34013a8d4031334f69720e7fd293fb26308398e1c56c33982bb1decdb12b194e3b8e78e02e907412bd34ac1374dad3c0cdb54cad1e4ed61d9795e36e39532e6c4566c8f6c991cbb0f30d770ab7eb3674eeef8c4e57f071a8b65bcd88e0038a5cc78dde770974681736df1b5ea494d36095a5b08d18229b049107605f0f31d6483ad6949a97d422a3457e8c3853c5c583a0a41ef7e02a4625e36e2150a138402c4f5b01710a5bfd6109d0fd55f4c53adce16d00fec66b58b1c2e220c4f597ef6360c68d5c165b7ca780e39e6af3164db61d9439fa22a90c6df86246f4a3d01180d739cbcf7d680a1385420ef84563f358af7b2a24d0fd9ac133fb386e6d4dbf495abc5b609576948fdda760a1dc46b60e85b270902ab762602021eaea2e64402385697dd9d9d26d362881566a49dcdcc0ab547fb7c1e5ade15d5ef538581d5b52f8bdeb5791f68e19e9fc3eea77403bff8b3b117d95537b7da0141243c8665dface445d42175e100442eebd0fd45fe069be449b2c7f03db7d6e43c5d7fadcd96397984beffa31c02dadfbac0a7b4dda03dcc1ba727f7f06647236e75e4fd98a0cf1ae84d712a04fd0b2ba227bc0ff59c20a0bee4081fc98dc1f5a11820fa01d85a68cd9a23141a22b8f951074886aa29a49a85830235ae4ec3932aa8652bfd3260154b7e78332cd4a231e6e09f200540a58c5fbd4fff3a7f3ebec6fadc25b18c017d3c0bc125c5d53ec0298e1993116a85a256767a9df6c7784f2b699211dbd990ce299c3e73b5ae2c0d6d90a526b0a5573e8823ec8b66a9bce469b199f0253acb36aa47e42b11287af8f269de8176aa10d230c841ca3638c87d0df1a33f60b868747025eaa21fdcaf120eeb52a542e3a2954fc185bc135fdbea0877c5601d582577904e4ffc430c18a79ac8ebb1aedfbd0661ba84e36c51782f1a48dcb839cd7c0327244227feba557c4abe8f208dad71f07df771b0d887981631250a984b4245ee568404a5bb96c5471542cd9f475bbc25204aaec0508872d1ca32238aa72a553691b9f7b6246025f94c0ae11f8455c3b60372c2524edc41bbf48f48dfaaffab213cbbd0fbd4c5aaa7520619f07db51b89c6c12ad97ef0b883dd58c2a028768752bc4e76a3708716d2cf88b5a312c9e22a571ed5ed6b07ac670b23a7343a3b9171aee8ae9737c1a3c5324da0bc12fd260d61d8a0ac08960a9b9578d08438c1d5e7869e005fa7100b22383a54fc0920e71157bc1fba92c9e534d4020bf942687f9c2cb06e26eafe3c777d778597647c386acf43698dc84ba1dd3ab33f42e021c00b53f66f6fc733f627269d6c00894557ca7750c6eaf588e015647a4d4ef424008ec9965beb8db3b4a730af2a3065ca62506b9915f5eb0dbf9766f391ba890aeda9d8051c776bbc059fc598b9684b29ab4cd352310e3e0b4c616eadbcc2c8604a6f0aefedd18a2f7859656cde4e055014e7401dd5a703ff340734a291e46959350ce629606ae48b9a6e3a4a12f47215093fd1a5069a4f87348baed94ac3ea76dc5f9c67d00fd4add3d61daebcbedda2da0fb14c5930492490897c4bad9b5e3556bc73583bb4bb33b7991cdf23734497bd23c18ad3e25b40dcc9ddcfa6354a3dcd6a7e58b0752f30f0f062079e6ca986e7e2a9a52f510d8c7c807bb4136594621e676d61ea52f446e942f9a7d0a02d3256f2d9bae517d66fab642585a4b391f0b6d8a2f4ec374024303f7c1672d145a572bcd23bb4580218839295c9ac9a9946d180b2bca6a14433252f838f97e3985cf1cdef8136f93a0847cb980b2e11398189fee9876aaa6ea3c9333e37ffcc20d56bde47f973d1eadd4391b9ebd2e9bc210f957d09e5ed25fb4a607d6de023f8c80eacf1949d9d008396a7a6163f0b8d6ef37e800e508d41dc04d99d9eea5794c7e61db95c64189c4e4bb90557b0068046de52a38f6bf094a0cc07ca953ff29fb8f4c6c6b2abf74256a23552fcafb0a089fefa2547d5c3c0a85e2c31523429d66882757d9908ecc7cca8773e94d327f19c6665cb2d878d8e0b6ea7d2611418cb41b6fa80bfd1f13319b312d4a6a02b2722d9aa0212780cc03ff69d044478669f41db0ef5e5b1f807c439823e3efca6cd25fc6bae13c1710bb3494564c5c3f540b66fd8834e21cd5cf78a488e9368729084d0c8d4651508487e86ce96d27e69c2c111b8612c82d6edf1ffd56d57e374d9cef13ed58e44c98fc8c5f08dbe75c8e1f567ec35880229d40b746cf81da54aeeac3b79f2694435234b316b95d64bdeaf020391ed2ec705e2decbe16d8731d60d239e0c122f413c7495fd132251d606de285995f64ffd3708e85b31f5dd82a4f2b13a2d76ad3c18814ec98d42af63008917461d44730f7554488050fbcd3557750f704183ccd6ae51497104cd02538872ceafd2c87680d1913da2deaa992ca244fdea0349a9f04276df889d57941e259dc0f57194e0853f4da8dd057dd80fd4fd2e2e2ca17d4a9efe34b6e7afadfd7bf0e49bc1207d22a9e9feeac211d0d5df323e76a53603900e88eccfb81f74ff868b34c7028681adf48c2ae087c0249029278cae2cdd0fcb240b129545463fead16ab7c36160d9d4feb4d35cc143eb189fa9500c01ecafc5898a0d9711f135e7139f636ac08d4df377c344f61bf6fea92971d93f8019bcd004ceaad08b234f8639856505e11bc78fd6277d0a46531fcd9a5918189dca36654032f44a3ed0d8deeb1f85c7f49ee9352ee6648e3b0ff47bc3cc8dac021903579597a689ea37a40d6ae7230c5c3bcc629ebc300b016c8b7fc7ffdb66e4ea7185c8c3255a0732a1c5cc00f41f724a5a8e4fafd9e796b6a4773737a54b2687a4f224b70b3c0ef2b6272a0fb09d3276da096511f81d25dc5387fe8bbd07de56306f67c97f2030e68f666dfdc38b980637fe5d4f877f5f29b02f0e2fd5956694e4b727899f7030eeb465e516110b41057879edd80ca22fdfcce8516c82bed2f942a13af33d1b78ed3b7455dfeb3b1e40552af1ae28161182ce618e8d90f913cec790b1f0af29ee6d3abce7ad147777b21749eb70b531fbdb718a750f9292f31d1070d0f7e8b168d0ff2b7527f047c9d171e14b19bc151f3f2818a2f1b04aaa829a2c55e2ffe6a7119a88285ced8badcfbc8d14992912700bb45709d3aaf76c074d0d84ab1c967dd644775c066cd8f7bd065afaf3c8f46f0b254b4c442de9dc3b328d660382e78790bb18a23642b75aa6acec373eda87febe5ed623cb60aa0e7e2484137687b7b843766bfbf0a9c8e6e2b2b72af407c4f26615157b86b0867cf853805d3d49827f5317efe0482a0a59b61f8cb21098288b67346602d37e7ff6e736b0ab770c8e7574a972031c34fa84201cb3ec68c7b8ed1e0892de4fcde3dd5433b1edb6ab6acb3858873465cfc75a844af5c72e47e463d85597c1a4487b363019f84c8e4214a16b8e27d2b883466e9fa0192f2cd06ab55188c81601250458a4c7172582407ab6dc717674ab4771b1b4055102941f8511ec7c1a710e7b3fb40094a110ef6883eb7a2a229b2320255c58f62d16e353cd53362c3fb9d2ef8d30f6f092a740891c550b67e1fb66e0b9231960521bddf09fdca19397511bade335686281a824807ebc6eb73b0eee87a9b3b57a4035ac3b3add7f90f6a1a19397cc91cb7c51f50b4ad756156c08c18ab2e0cb316b0b703f90db682571642358c2d27acc9fcadc0d9b672bd1bdf89f78c74239f1b5506d799780bc5628f8a443780d22bd2f033dcbf4af2b4b868063e728b2299248843c86e971f92f95cf87bc1de177e797870c47e9cc666a482c18b6977d33ccbba148f07148a1dc1df5fe2b4a6d537b87ff9e540c8983ecf9021f221458284c12e3dcf83280fb1fff38b847a715bb0489757e8fc82963fd3adf8dfb8931c5f0b18a20114594a86fa8f29b077553d5e745fb05d10d2906df7d9d4b6ef5c37d9e2984905c4675ce7330715f839fc9fba5dcff6b4d3f9860ee270b992d5921a804668d1163eaeae24b79861ea912ef8c932ffd8c3eee16ca2b913d055a4bc1d31de75adbc0396c04e0457e499e6e060f8f3c114970dcf3c3d360383cce389b649037183c4265a5c1c47e0941996b492b2671de618c41d6812bfe4adcc586363fdd2a2698c2aa111b39100b2e12836102e915437b9bdfce72d8ecd9a8506e61647357b6612ea6f9b7dc720f0dbc577a1c7b1187f784d8746dcb8eb76610e3cd9d8d3825259e4afae83d96beb9b6169c43b2fa87755bb0dee879390925ccdf5ed4c545d9442b0d6ed0d21c7109fbe8abf2245676a4a6327f3f110565d8d113725d51facb5d5e2fbae55ecaf4eaa94524f5e012f07803e1cc81dc18ee26f7a6f9cb2a8e7bd4ce650c101b400eb6680f4abb2271e8b8a1de40b99e1a81d33b315091a12cf74bf9835b81f3f47be6bb16d1cb79725f0d412b10c8fce49cbb121a3ab603b8c8a96e481546305255fbcd3f2fbc63b2d197f4c641d9246a8cffa75718b27f01eb25a077b4332f88e2612947f469a19f1bd9e501101e8e48808e20f46368e7d1bbca0146af4e805d6dffc30199a6bd879d3334535d249cddde8ef98915e03592ea6870f2a065d106a2f74c6263c6cea58e06b35d4bb00e36c258fff38f8d7e2b9d7541ead2b4f52f8475e3328fda11b8a015d3918f5f51149306fa3172ff26692904843df2e5e898bfc330b2c69c32a2f86c327adb760c0e8c2efaddb7a85e233b50f29aca086138a8f9b34324f3b5f29e2995d454927d16f9cee6fceb3b496897af17c11295c61a2ab1f07e4063ea0dbd72f5b8e0479f49a6720e70cd8912d9a1c525a38bdc30b41a994c38b1083230a1620b08a4a62ef66fa085902564196d9c072d8caffe117ed77686ea7abb6ffe71d02622ee1dab2ab1f18fe2a09930eeb72cb84760bdabece292bbefc441a285108d764bb0592a03e4c7efa2ab222cc2a92a0ea27c7148a4bae1a5dc5138d8bb01dc0ca3a01b4db420b84ebf34f61ac5cc8757a623906ef4d7e052b94fa38ea9ed564ce9dc16b80066dd5847a8e59711e09c4be695ea7467273600df73a74b4164b3e0a3f116a62fda9336dce35e5065987a2ed7de6f0bbe772ab76ac98bab0e967e9d5645119a1bcf3359954dc377594769b55f035180ce4399008e471b5e1c0f512ff762230d17183776ab29ae01c0675c9cf2b4b48e8157fb58412deee2406e41ac33f2e8c7dc585272c31f0133e3a2d977432bddb8cf5b5abc7bf0251d9ad84dc241f1f1fb6e952aca45aaffb2283fb967f01e3cf8197db0418ff6cd785b69b6dd2f91b90352efa10f18f989d7beedcd7eabc4ed1027955c0e295b5655871091a2ac8c227dd9d76df353763f7fcb880ddd9a2f5f40ed90a74f07e0f7bfab0562001d6b8c479ce66c85937dca5a13bce99737b1d8d9295bd2a9b7faed750f1171ce1e8ece8005caf71f67b859bdcd2396637336ebd7e61c2bb869bd7738d7d51414462e6c3c0b9ea934f4ba6c5fd08cdc8ec25b01c5d5795474ba6ce5840cc479d91c206ca09770522dd4e81458a0a5836b3ef99ac3028532e1422d6feec7defa1e353323f4e908e17e60d9c7929ceab4514e86564e78c97572925bc15fa51ffb86f7c0b0bd5260f3009dd78a43f4d5aa02b3e01817a85776cd86186867d3449b88d8f076dc5a64eb006f11c88015a60dc41e3b413209f78ea2161b770b083ad4b0a0217ebb91a2aa396b9eb31d310e7f7a3f4c919e2a08dbf14f56c1f41c0c25027d29fbe4cb7184ac10d570d603faf908b78cde93ba9a33eb483988ec2364058929f530d5b89ade262cf762fee05b0afa79ee3a8d7238754e743ea280bae2fe9eaac6649d32baaece75a7f0efb4ba41c0e51c58f5f5c3f7f4c2ad71ef9dafaa4acf26617c40ebe86857aba475cf9195d4106224101929835b1b39ebab6e0e6698803d4ed0604dca4e67abfb466d0d05871c218def3b28a8c2243177ad937448310c20e8c6ede8727df1971523397b9fd51900958a511c5579f9d550410b7dbb45425a2b937aed40143f4dfe368af93820a34ae43f4e27b7aa7cc746a364880aa0111d08d4f4aad979448c674397f2dc080fb629856a8d4edc2ca1e4b320627b3b805ffed97dcdc79fb547b43a650eab3e13880cce07b0633404d5d1c9b035f7a61ac4c950d666cb6666da9052098177334420046480a75685eaa1a4f8024b8a47d9853eb6c933b124353712a9d73e2988ed6004cf00bd77c618467ec3d9783397ff6b093dcd36c5dfc247431273b9187a320dcfb7901747376252e08e9559ad9950e9f5205401467ab12c6faa72b66ece6de02578904637882069f9ec262ddaa87754f4b3fadea89ceb5cbbdeed06595c8c2f4c3400148f9109e6bec60a9ecc52eeedce6cf22685d2c38d058c1ae67c737be7f3e47fb814e770edaa72a9c147114b85d2d55ad82d6c8be3ea70ac216683faf524176d511bb4dc36429a5c7df1424a4ad357942596b0af95deb6c85127c8e2acfed525b8c1247c706c11e9557096a9d91baef164960546860d9bd8699391f35a0705a44a2d94dcab827d07c790672711900fa0c344aac8cb6c2aa566e4c30305e8e9e70faabf42e25008278995f613ee8b19b64a2d4044fa2c95d1b419d64c4ba47c86d3637bdc839cd767a1416f28036ea2a2259dad20e85c9d4aac05931273f80ff09e7a4208f3cc126e9f435af39997e031494fdd7e375420df15dd2194dee085e90161eeee0dc5382c9f40765bb5a517f4edb4c1bdcf774eb8b5e7c10982446524e9a9fa043f8adbcbdacd1e24b049ceb27974bb1bd5892c7b79fe6ff360939497a53bf97c78169f59c3011030c648a0eaec919fea5127726ff557d70cd9d09ed719c96b43c4d37883aa6b384d2f802a5ff83a3b5fb7b1174bf19ad7af2c2033eca640abae67424264728ef7d41dd526d00908e8005f48125994af20af04312f80d5ca9f5d7bd145d889f870d99b51c818d0f887f76405167d89085569e6517ccc7f5ad247d53005c1c67f4ea399e8996071f172007175a963381d8cb5f8e820032c75344d6e4723e7336ed45d1d3255bf6c28eeaf7f73eb8a58e7cc75d487b71811ba5318e8785dc090dd03552b6e7ec8741cc18c8ca50c1227c11d0a2ed79f864e41b5f1c517cc1a7b55dd87598e397239cb0a679e76991ac511527965d17068548ddb6c181b1c179b9f3c8e1a48923b23ce89101b3b08081a085ee99e4bd9d29db4d7058c96cb0300e48d077aec68bd97ea0b9c5516522227bd65262b4ea35439cebfd52614f15dc8e875b73ef50ac8a33970fd7190c4e17541450c7200ed70d142f917f0afcb35d94a6266197eee23ee40547aa90304d3459eba8d0593ab52803fd7bc15c798f67ce95471c3897f424ceb661400b8755f9c38c117ac9188a51c042e53c854d15a9b9906b8b759f4a206c1aabb14cdfff3993bee06609f138f0c7fda4d141961dad0d4b3684514c5482e63857b0733fab52e9ec1df74f15169217080de27a1c8c2a1178df2461ae6019369223391f934a11798660708686c381670881e35da28bafb4d935977dfebd13d226a56758621a9c23ca557617b6433eb16af36f21914e44d0c1e9a2edf7b55ed1f2ed23d1a25e27fa85280a010438c8906a8d333479c5dc43262fcac80b66e41a9f235311aed29f0b12a1aee119015d02d36f245ba021fc5a67b6c645543855b924b813bd856189a2db1cd0a3184e6162eb44c95182241f56926eee5b48b7c37e0cac909570bbc9ff40b26e366dd9488eb92e1a02a15339f2e788af938172772e303f4aba9c2d521a1e975371c4fadb7566d1fc56a505218e8bdd2b599680810b4af234e7cc26e5c74da6682e0b4a0f09f4f3c7955c8549b9f8737139f8b339d6c9e6422524f28cfccf0325d35b5ca3f438e6bd9acaf332414e7d4865f20ea415f405a3ae6073d219b05b10669d736022177cb0c5e57e575d963e256959f714d902c57cd8b91a00d6eea564dcb5ca45e916173b0418a8ff3f0d9b995ac173b2b6d2f4aa9fed9b244f888a04367d6a6f0a9556b75b90ab897ee4b65947dfe62424f64d8d3adf13107ae09e8e4778571046eb121f9b091b674f3611a552a50f0353c0c928f60e586968b08810b296439d3ab4f751909823fd72d6f152b94bb4b4f871529d34e43eedd494c1faaf058931e934b1103f47faba5bcd2b86c9dd0546090bf49d8d6bbb34ea0df94b9d3706f3fe7800d0d60ddcebc249bc348924d5a1bdbac35799d1ed23e7f7e68d0822d7bfd8e813abe6a32fb2ecc10004e6763e43fa6cd6912a2ae8f66cd27fb18d55cd8e0227099978023b936130f2d6bfa6998d7acc49a8f95226fbaa614a734d5818273f8151ccc68e6c8456d0f2b2b1cc16465e56e6a8e36a9fd4427ddad06ce8d74fb564ef4b10e4f9bc2043c96d85fdc2c0841ff9a01b87f2a8cfa12e9fc6e49ab931d49d59fd9b047467537aa2b2a9ecb94b89f0a961219e207b8bc8448f5a5463a94100bad93784cae757836ca157b5b0a4554af813a911ca9548d61d5b15e374fb32c70f700fbb5c50de1c8be393999e1c5175dcc9213aa2c925d93b068f870271c677604e2c5b7bcc99515b0e123d209aaa183d39492117a2f2a36c16b5c6d60e45d23d7fd5a809b0e03719e02b88777cb7715fc5dac750e768dc76c990c3fa469f839ea95b366c87345b85e8e0a5220d164396974c449c8cd843c91500120f51564d273d922ba809f62d837ee0aeb985d8d7c597a608525c8096be9a439361498d6f45dd1b24d803460ff94a01b282ab2b33f4e0583ac13f3fac7580b5a96f7cd2f758b93c939f102aa28f96119d5050687241b34306150e36a8701c540c516cf5cb0b8566ede314fc94f48250b388e6247eed571b3b59c66c5b0cabe4637636ee9784731d08d7487dd2f9dfc445c595b8e6b7e23cae39fd4b4c1f7d1679d4e5ed3e0447f28b9310febdb12de1f0e3201785e80b83fd128e8cdb17e70c58afd5ec02da4546b4b2a46d43535710763766e0fa2742a0566e5b8932139963262c5dfff110aaacbdec6006b4c76381537697208026678b51a4d5bbc327b2e371817a11de42e19b6d9e145aa55084814fa43a970dbb29333cb273d6e9a8d04ef82bd13259615253603c7301f2f4216e34563c4239938d480b0f500dca8468e65f7d0304f68dc94a81caeeb6e4f99a3735f13fd94d0e527bb61e06f2292a3b6c79598530a5c2c07902212622fbb2017126fecb8d07e606c935c6e92a5eb10be282d3489988e365842caeadd663110e98c574251719004b1cd6bf63d013638d5aad005651396ffdb3414e2e746d43d42799fcab4d2e2d50ae25250274a44d28c4a38e4f03f44dc17edeb7baf90afd8d117870b9f4b5977336764fabead5fe50e4253abe6e008264a69979ae35c633443c7511ac2fac8559ed2c3e1db0b8f444c469ced8e76f3693551cf860bcef840220a052ef7a16aa378ec823f0aa95268e356e385c1b3e05650953cb02a9c9e1e7654f87db322383d0c105104521994b13a5e018a0065ccae933f7426a6e0ed933cb1e10b7761d11267f0901d76b32a2b81919ad15cb21bafb46f87560a0253b54212b55b1c81459d6eb1f15132a6da4d11b322b8417c58ea3196d879ba8b650911c256ed8bbb113bcb9b986c15a95aa75cb2f1ce13b29b80aa71ae81dadcef3ca464c34d0a6910a5a96e177d869a9b1b0e10b03d4fe4c5755ab7869d41d3583635bfeaa852b88ca17a3519afee5e7dce3a55606cb82dc17953a358c066f598d93ee6de52e27d8dbba8e1a316b783c64c509c521384f50d6a1372ec8ca407c4e423f81c7dee5106d57f739044202cf70298f9b1f2a4cbe10d82f5805a74c288abb0ddd56f4a9c5929194a2dd4847f59a5bc8e278b860b094f936dcd3c6f6c39b8c3acb6571e3c9c1c69a6163db23a3472b2da091d2cd422fac6326edd75bf5b344a1bc9c9530531ec7131abd3fc271458c8af0f6e7b056d8f589f5f6ed398160446c2746ad7c2f445c65fa0c6c901b39328ead2778c1f54ec3dbd5a6cdf37d8c63e9e4641fd3a6b47cb2483a6340b895f51c727663d86a4a1e8356965208a265c3bbab986050657947dea6c928e582b820daa5a17bea45ff04a00bd70135d554d47e2753cd6a9b3e06523d1b30b34cbe3f9d2ed9f478418e66eba52b718a594006ef4586c54b4e1c3732aa7b48d3b3dbb160a5f233c9d0628aeaa9603356ba133a864f3d93dd0091830fb966bc488dd34b741fe1436bf23218d28ac6ddc00ede14734523ed970f67648d4cd6f8c4a129353e9b1d9c4de0942210f79372c9a2dc79c3587b1c3aadddb88d78859f676ed9ac3e6c3dad72b6f4d1c6028465282325211ab94280f21cd0f1ac42811d30e2b2e1aed42cb67be79ac7526159da0fa3c25a35a5b3d89810fcd7f1706774f8a3f9e9274e8b5439681e11b2f8267722fd510d5700306eb600bf7a51e7e2223b12fd21fc18d5dd30c0df7b152cd4a6015e7feec1635d02d31e579700b338ecddc815026531452900ed777c47e3b1323f46b7d787f3497c2ef2a35abb9ecdfab594368d1096ebda8a4e083e60ddefd8a343559e9819c66ec1830ffe63c26153d97e6c6afdbb4b8c0299af151d2f8b8bfce10d038ad54f1cf5c81ca23d798f5f4c2b3425263f7df02dfc5ce1e34bd56d99f80d3aec136930b1e5b6682b811fdbc9aabc5371bc1cf626d05538dea6660f7e32d1509deb0dd363f628f99b5e0a333363f53b970f614198b3b09a8ccb2ba5401cfcfd781aa26c5714bb3bae0f12f730dfe4e9f469c218fa5d3fbf1ee669b815ec8764b538406a3e00f96fdb5f4704d693c3aefaf3d1ff610946e6911329a465aca16624b34c8cde2a38fa67036de22600523223627315bbc9aeb2012d2ad0e55197f72056378804239622c9db4eb62564ea5eafaccb23f8ef87905f11d677637010a14035a15996945a2bbf07033cec92da14815dfd58be9f83cea6b5c782309a152b419e6ff34c5cbb84b9741ffc9adbcc3763a88cbf34d919de5d0585db0ac28e0828cb5c6045642d67866b8cbff8328c618a0c7ac59892b589d1445d251169b52e2ac5fb7a38ddf43bc3d0ec60e858706c03a9f14392c91e62727226ab3e89d416434874c11ec4f5bd8f0c08169fb62c707a4275bdc8578b887ec8d2b8ff247eefcca7a886b1238f7803c10c2016d93f1e01b3d7d4601c6e514e77913465b4fea530a818c35e6157e5dc5bc90352e4af899e47445e9cf108ddba86a87b236bb623967fde721faa71d93a5a861bc68c82f70ee7d9f94ea3cfd40fb595b5787672e1150a41b674f0c26ab4a5a113609a8018e9d13bd7c0f5c8baaa8ee44ef2f00b2170b2551ecfa6df0a76b89f1be6da1ac3fb86da00a5b63a58b93c65aa3945b8836269a6aaad033c5486f33ad732b168c3f36c7869bfb2a4b1b1b7b93aca5ccb71f08659faf8badceb8af4c2f7fdf718329c56832d82dca75120c9d40e78905edeb2f7e24cb5a3bf4dcaf2ad88e7ebb9b28ccb4658058cfc58061a10f419fdb0c8b865ba27629486e191c3369e577504c2b08720096afc14e248c36f85a2f58088b7a9acf2c6fb2c53ea548c9b65caf7a36f9b787ca9a24db39419efe98888838d4e78d4c2129d6484425ee5a5fb54b5a6f602556b0fc2e8dd5c036b874984c0d192dc779e1bd6f734a8d54b5301b97e386ef66660efa3a9e7fac34b2a104e3b0fbad3b84728400b97027450548006b91613a2048b5c729902e52cd967571299c00af581f08d564b6e125c6f595c9c26700977ba98d0ea23bdb0903870a2c3bf3443a87f2d629a52fda02c7567093f9992e3959c82a8eb4b00dd9620da468955c27e070493fd40e304f8cf96b15f3f24dae8cd2430cb1ff7c5b5792a590d8cb6ee724e9e65d1d27683b69b5905300b01c83aed384a1f83439c7fe2c1453bd5bb3a6bb6be24b8c311662d3b020f087eb6ec83516ba672d3c0ef1075583fdc22de8a44512820d6d2e18434146a34b2ca8f7cd858bf86545bcd84c3e224418927320c645793bc25ca0c4503f1e74559dd3a6994c2d0f78d4d01332b72337910033cc7f513ed62024c91a566ac35c20f47e7fc49c754b8550f7a98f5c429466fa8a50a98e4a4a576abff3c80a2b41ea320454c25cc95e0381ca57bae87fad86cc1ac43cf55282ee8242af80ce2ceff5c0a14598d92dc14eb8830ec6c58071f49fd476530eaed59d04dd0e213f41d549c6f2cee9079c744c131fe436246f0f09aefb43c5bb74241ebd45db5848ba507444774113224f39e5893d70363443472baba6f0abd2363e3884aef5502ae6e587bcb75f75890634cd5c9d4a571600ab5b6ae95481542ed1627fa45ee2ca6419eee101ca5e3b81e40ad51f945e21aa49e28e715658c8b459958dabcab6e2cf07d4e4ac28d8516e776e483d28de9316fb76b30a2b5658fa411ea95e9c6f15cc3989c4854c0586c70aea65e44f10ca46f095e29985436c83ac2d443eff3a9a3d5133aac936142e872976e2775946281849814deb88ce7c0cd6b008c95b8dfa0e1c237374343c05f848c5b671fb48b671c55d00a75a08c72a4ac6ad3c703f2d330713a6f44740e3eaa76ac7394f5edeb06a335ea4e15d3543d79111d77b94c69530ccbf0e6bb1cca1e882d2751621fc88479cba553642b49721adbbd9897d8d09a1bf1df2630922c45317f5fb435b214f85fb5adb8434433e79f43acb1e2e13b55faa398874282189b6c2104719b3b0a4671518e945a47846eb1f59666a9b70e9fc6f647e3802567628b99d26b5d63a41b9351c8d672d14909bfeecdf779a89d6b2275b66aee0b050b585e93856144d3b01b8d73222c3e9412a041b0622c0514c03f61ef938ed3cfc4e22a501ce9f880e453154abea45598ef94cb1eb6e349decc0a5abdaf3ffef367feed04b85e5710e3624c9b14d1d7bd4bab7f91ef4d2ce0c7ecc13f16ba6bd1328fd460fe2ee40734061bd8a11660cd7727a0aef06fd9f844d0d88ee7ac3624eb8e13291f8e9f440a1cc662c92c8bdbf0caf769f0a86c40872a0d05f1951608d603f948317ccd4597f18c72b1e81efbdfe4836a329c22ad49b6734d0aec37cd0e1507d18406e998e914000e4859a0261747c08da77cd48bbe45154e9b2b18a6efe91be4669476b7051d9d64b3f9e1d4f8324fd28ea5f80639780c014ee3af88c3145571ca8690aea5a266045412ee02507b4c13f1d8f7089d89b5ca5ee21d84637cc97c63c64c5df78a7a05050bdc4068ca5b758255cd6f4a8049d6a8bb1983c26f6bceca34abd5d1fe890dc573f92cc5ac4c0b4d6d2258e0ccd8c03badf120193a1289141cc4c8e56c384697460a68fa1f4cabe296863bba61328209d600fd2739c0c57dea9b11ed2d1e9c271f1cd2034278591f54776a3775be1e08f523001af6e1b462453a160a6e5d6d7b133c3be63aac219831f19fc39a947bfa4894e83e607e2f9ecb014413776100048e5bd10f929be9845070fe9ddc02a13713e49d66e33cd35578045f01b66a44d3b9014d4d14f28df0353d73afa63d03a1554aa160702edbb514a6da4eb7c1f622cead5baf2c1b130227acbe958dc8a66dcbc01a0067203e3e40f226f66c0e8fd63bc68d1e69b681f9438454787ea15a80749b58d0c90089a1ffe41e7a06a26de1bbb412e68f406a009ecc3a4a68c7113441f2e4aaec6fcb14edefb69e0962ffb084cb923bcf63e03241b6e11fc2fc495bbac15071e57ffbd57d2376c6709a44c29bce4abda8b4840e9826a1f40f30532d7e65572c336f45983aaf373c6e062df8cc366a77e324b5341e58d37a340d1ac4ffaac4f0ce080c1a4055131551fe2f49d7042d175cde9ab99654b1645e1c1e14f7a5e1005b222c70ede57b648413a94bc26ca20aae379e7fdb80491ea8438ac54a8861734f97eed413d65170a726c67c193dc3027776e2432c44183d1aeb611a44144c5e05665b81bb7245eea43029078f75d473817b328345ec14829f21344154c5de4049d09cff46abe2696f9edba0647a62f9b7609d2c319856b57e8d2eace22c321d12bd70fe6b41d7b4437ae962f0800c7cf9795afc4fcf2a25235ee3713e0af3224d4a6f530bc08f259836654456b29116c21606204d8966e37eeb0848738ea5540e3429782974734faa0999440c915826f5b52120ff65f8f82f96b4123791ba89e4904b20cd3f61f9e3ee2e99c58168a67518421ccd7f790d330a317516346600a062aca85520dda25fbf15024a37448af11d28ab715827674f58acf31bcd35d7e66d70e7013a7bbd0068ec43841a1a0a4febdb630ad65904fb1adb8b06d3a6456d4e861efd7e32eb7e28ee49ae620efc3bb6b804a9e671e47a668b86cba6b1bdf97e826a90f72e7c7cb244c06f3b54778aaa41997725ac81899d4b3f05fe4f3bc649c2b822c624f98663b885e6540373b475d31a41b981af5d7ac412f687efd13b024838674c672fd71407260757f02eeb9f7c56f9c5dc7e07977347bfc60d7824b4bfa8699334193ab33f2d5e1061af9a5834e11a3d9104d346e4a94cf056f1a06e7d3b569a51acdb1000c1c725d007c8dfc31ae6c7d802c4aa2dfd50f0b5dc4f90f7a35c82de969edc3ba6e95c5fce57020cbfe08463154af261d86f9de25ce2c5cdbdbf0d5e0883dd32c06d1b4451aadf658db68c5eacbed8c68c0aad66d11624e9439de63532b3a04a56f1507a48d0a0217ef0bb5abb735ab6acd62c1078378f65faa894d112acbb36cea2599580a9b62de030db87c32c327e87b9df8d171a324b8cb7c8c9f5f25577c437eba53e5423f933ef9a11ffc2a4e94e4175188a53fb4518f01e870e7292c798f9f3c72c30f6d66fa63bf2657a84d1dcb60940fe387dd760ae1cc6076d9caac0d5a71561560c385e3f6e9eee80959766e2512133c38176571ef7501956292ebf0738b5593657c8e2feae65ec9a9fd53005defc3058897eb766b18838b520ea4d7548b379235e837b469b817c8f76fa1c9c9e2a6d6ea9e4fdd8c5359e35d649c626e52b38bebc3dd19b2c56f4ed0bfbacb45c33cb3c25ab3cff8e308a9ccc84b7882ed512eba3170d29f7e7c4e35b2bb678139411f6f3dbdd5b625af48d4726311476bde7afc17b20519d2b17ea6fd786921960a9cdb7239595b564476be9bffaee775efa0e8ffd64993a52c32591b1b922400f7a0bbf5b2a121cd583cb38228ef8d0a1eb4cee553fc85665b73029fbac23205da4f13906e38e9c74f1398e577ddc66005d3a8d455f65cf13c06d19e8864252057e0c47745402b297d4197599109430e2099e55882396ce3964c2e941e1115a83d0c209d6fcb49c34b17149d321a9c8e979d3b3336547609d4e208dad9689d7dc312d660f823e8c8ca9309f9768cfdc94976ec499d9ed086be767841c6dacddc418c62aafc7354889e28bccb1a9b4ccbee680da9a690e04b47689d25c05f1e9e85ff7f0622a84f3c43a5125d0436fc03b8ec3a1683f95bb9a3ca32c7ff04531d85d0630e1eb224d47b5815e5c494e8ef9a3d5f3906b5003fcb4d7197fd2085992d3354ccc4b7c871d4a4f75b3eb137bbf72917aa737624877792218043e7e1c5f8aa276832e937f0ab7d8a5770e21d0e4146aa040f62add2190902c08614a77e6c15420fe757c4969645252fc9513001692b28f21861222d454f8a582bbdaf2d2b17d757168e7f7194c2d98e23aae2865968157ad535033a7cfc88ab3449b719d4967c98a695f2e539a710fc94a28948dca158113f3505978722ad2f4e5a49e0f50c37d6b96a8a1a7e9ca1e0c6c0f7381f377b85bfb6e33c3144d4545938cd2a942abab4336e54d7a4ebb9faf3ead7f772b5e14f5d579749a2a9520949a2add8e6d4564668ab16fd9d86093f5449df4f7a3fa93e858da4ac9af3356d33b35d8b09713599fc235b857b16891b9298ed4d348ef5ed7c338dcade5431024582ce0771a260fcefc31b1e3c7d61d2aab84a0cfc23bf431c8343991d08209b0b7248a956bf0c6531002e7e48083c9996daa75b1fd9dac9e28d924acf7496fc1de27fc6c777e7cf31d507866a0075c1396e0dae9f9cd85346873ec3d01e319f610a1fa85298557c4750468b2f1ec4664a6a04268e961f5fe76a79ac6a72b23896eac36224e137fb7cb347e4e5bac73da347abbfd0276fb5c4be1d08a1bbaa7f652d919a47aa390cdd71954c77995e82471f7aab4fbfc6fa274f75b39a906e53e6eba8e388da65252fb3cf37cfbb861771af511a735ab8639c7ca3946e82786dd607cd2364669e3a7b4d1897659d1394e044bde97618c7602c8465b8e5f626f31847fe8f36ee3fc175ae8eacd41a49d4d70f39ed8fa2c5b06b86957f9c1159c82ae9ef775bd97bed7cfba18031ce0d2c15ed793a63baceaea90fc703e1a30015cacea023656d82e768e095a0d6ad71e24c6ccee6bbb51d369bfc1311545e2bd15391b3242ef10bf785da4ceaf335bc742c8178280deb756e4f4b5560ea19674792c48b54535abbe50d6845d564af8c93ceb01a805f726014e7c9d8f1701b4a115a1c202cb3e47b0b887dfcf95fd8c9c295c1ff9fb6084f674ce05de9d32fb766f771f2915ec75a9ab5d22336e80a7503c9d1d0a9ad3f2e82b714ddd73a3db688241628e13ce05b440d42c448903da8bb6815930d03a4a07d1f733213d401a51053c3ce60aaeb3a20756501e3ecd6393b7ce808e23cff1312b29546b14680b00d9f77d2f3da054393f1800969127150cd5b50fccc64f71048be52d6d4624b1a4d9ca6f646f42a49452a624530e0824083308ecf37e0c6b0cff9baba3b20f122b261aa411ba0ada3d123b0af8fe274ceda0e62f7fc11ef6790f8da6555f8093da694760b7c00c0d50a6762c03e385f246dfdc474791d1596d7ede83e6427b56fba9a276103524be026e4d9412dfb3d5c623a45240db0edf93dd1176cf399f7cefbdf78634375b52e12114517f15b5e6569a5df1736fefd8dd7d24caf8f2e7ea28ec7385db685121d49afab7e5b96e8bf0dc312a0faea3e66e228c51e8c7a77c10ccd70179a07cdfac1d32adb4ef3ddb7daf43465b8a0a21a4cd4aa3fe7ca91d7c4236cd3bdae8ff6ebcaf21f4716edf6f4ea867f0dcbdc88d3a66eaafea4bdd57f4543e207c720cf89a06f41e7e3ff81ebe2f825d7ca9adb4ae5245c2d17dde6448f870877dd8bafc1a659492e5596472b2ff8d4e4af9453242f8cc6c331affc7fc2bb7558c317e8d939db8d116d12e7428dafd1b5d8c1f4b805f14a17dbaf9bf47a9cba53d4a298d0ddb9ba8b5be9d569beb1bb721cd3da0083b6e8a60326766666edfda7251df379d0d21c32577677e2f7a31a7d69c0f8afa0e16a17efe5077a80d75e3f6832f7cca3c9e84167ecd55dda1d678bc63882b2d84222afc5503c9a71c445fda2ec69dcb1fed4f94da69d7570e1f469631da5790f80a22ffc5ecd375942b95a25561755d3e267bfd54b0230f0a4690bcd8437a4d5e1233970f9e5f7eed59151e0a3583c467f3544bfc542e15056a5eb34a5e441e4cfb07d32c9206ab7924085ba23d130a7bac03f5aaedc15a4504613596490b3652b3cc3a503fd42f437d134b3c55106ee2056126800809fdfc70dcbfcbe51d3371e9cb15f8ac49592b230f4faae91766eede2d8c6f8b60d71b641ee9168bde77f1514f1f155ffe9413d052a97d05913fdf3f8b301280050000e6ba00dcd3ef41d08dcfb3085a515f423c2882ff972fdf0edad75ff93006a02685679ffef85e14a3fdc1175a68adc860651fa613d2f9927876561a7cb71dfdf934a393524a29e5e6247ce88ec317b1571b67244a7f60407100438622d638638b1db4c034b0040d69fca0830d5462b0ee6700585a10038319622e7881f5731e74e482124c44e1f2450b4244817503c12a5ebee84408db69872e4f080628508b8126a5a6452dc2ee28b4e133e57662e3a39f79dec61b4fe4deff79fe79b8e1bf1ff2a1de71bdb9e93edee2436d0283a37670020e1c59d46a33e184b3d6cb83694c13178c3102333228230416607411451531e00256536716b3d6f97456192185c1d53a58e033bb70627c9da794524a5fc9d579ead2f98bf3ae4dc7d2e65a3bbc04f2d5e6ed8e96946c4c49c460383ec381a3d3790f1cdda863a3e540ead2961410ba2a8d34cad085194588f10206c6152c9a74418416345cc06c9ee18e140cb5306c740b8c46bbef128e1f6a4a29a594aa341d4a359dd75ee755d0f55acb653b7a5d8f03a95657946aefdaf8e2e8e8fc50bb36be2d9d8f4b1e6854a3544747d3f9a1f6a003aba483efe0b30e3ab0b12a347eb445fcea9ca08383aa542a1c2a4ad5a04f59534ea965bf7a4dc3d1583ad1155b91a2a8aba543a9abd6f796ed8e6eebe9d6fda53adf511d9def5cf4551f6d47df451fe787bcb5d5a72e1c174ece67aa1b57a59146aa5d1b0cf1e505371051822e31f0028927548c40238c1319301baabd6a6a68ea860d574b27526abb22ab87d4c6d7344dd3b456bc3aadeca16a84d567432b4a29fd57ea860d17fd167d1d6a571f591bdfd5363f07a7fe4db5a95169f3b3ad2b32638aa250daed2a5583026957db79fa9481e053aa4d19777260b0d13a5ab866185839f30ad6e67c15b721cdf1dbb041edb455037594ba5c5c1b48e563be7c7924be82c08fb72bf273e11f41088552a807414a4ad4c7ad2f87b21fef472fe0cd6c863a9b5bdfa51d96ed8e2eebe7368bdc6984c15ced3300a0a969988707d7ffa5e15d002ff55dd667cf7a0d7647fab65ea7f5373fb7ee21d5eaca957d6be37bb3a580e4b25857674b615ed6c3ed85e3973af86c6693c5faa1ee608be1b04a703c8ecf706cd95311e1b0b12a733eb445fcb22cc0dae17bdd7d67ebd13dcd3952acbe5893cbbd34748417d4ee48bc3ccdad68ea733edb5eafb677a9ce4e733cf3294f1a0f7a5eb8c79fb66c47ab8eb36ce7ba5cbc88d11c96fad07cd15cebdde6816cde756c7774757eb258acf9da43dbcd6ffd538d30ffe6875c67b3f9a9f2d1baf91b1f389fa96acbe6d3c01d23a8ddf39289f08533939125ccd20f2a78a18918bc34c2b89245931b50a0c4175ec06a6e7c478354ffb220f120b7f15d757de76a7df73adf713f69e6c369bb22390f553e58599665593675e05f960eb445399f7aa81a2167daa1e626e7412274cf7c9f7fc34e1bf65db625a4633b6e3ecb4e9bf3d0764277c8571bdf9c4d3eced680a37b63f375b3e9264f4b6aeb8a0809a5d11c92eef1a7410fe64840d0a276ccff06940ac6891a08f5f839e1465f9b0bb5bf83aed67962a58ba48a0306d5825a9dc8b01851440d6584a8abcb4e507ae852712e3b41490a020a0b2833aacd65271dc688a166979d74381373a039606ea84828e160d1c1e688273756906ab2542098a89a6c66d08ed85263c31312645a905436c420432a09256d8d26a82c495918744aea87969961fe08fdec103ae2c97bd889061f58c4e0020399257c6851ba02838f2c4f54907c20b1254acca9861a6af091c496170c98ce98219271c612d50c6aea8c1a1ad4398666a5aaba984cea4d153562d4541431064a6850ea3422bb624acd13f5e672931926d058506b2e3799f1020d66ac50e343d52e37a5216336a53903011dc8b42e37a9f1c2163032661e284ab9f8139211d6da1cf7f353ab92f7680bfd68e7506e41022e027c2e7f74f6a047dd39a8b774d62f6b72049fbdad4341efe7afe3d57bb8e66636a8abe41d75bf25d7650dbabbbb43267242c8cccccc3af287baffe67acdf5577cf9f4e7f68a760498b44842fde31c7c98a41722b96012daa7227aacaa310c8a9aa82c6816d563948f85d7ce536a584c2c50cc41477d40b67c5036fc2cdcbbb89e8286f2e4f811eaa247e425920a13b7b3b8dddb72032a5cc03484104ca828c18e8cb0e206193891041034d002d6bd58d0bb31e7ce9d3c2900a349054bdc3955f074271513dcc9ed7806e8a2763beeb41405e9d6ec3d28db71f7dd6ca63e15533f37bfac4acd212e4fa376aebb80dbadae7c4ee3ca8712082aae4cc1d295ae17bb71c5535bb87029cc8553982ebc72210763b129d70c7daf490a6d474be572fc5083f501572b29c464fc0a20658bdbfdb058eae28b3284f08206089c8080c1861a2cf9e28647068d0ba9403273218410421c2af7de93c274006d258590f2a9504fe31fc1f8d9835e43e0436bf460f08f605dbd2989e4d56bc2b6634c7d4f6a8025c635107dcac97f3da950a8584a03831b44c111b0d792da8f443ea54222b89254790fadab7ad08b88d1110cdaea3df219267f85a5d2ef842e1239e5c164eae53f2d26b8ae54d25688cfaa21f0871af51d3f69cdc91ea90d66ff54fea9ed9559154a18d29c7cfa3ffa530f6fbc29fbdc89e03eb7cc2f04b8026ba97f5bd1fbece9f60a423bfa47d755419e65e6509fd94e04f7bdb30fea7d6af379e50bf5601e46ec235f7e023828c9ce0e8b25913427a50721f11ef9925697ac574ac95d29a59452bec63c32c5d4efc9f7210f9a307f20244014ca0ac15fe150dd5f44b457d1d75e445449b457590a833e24d49c9077519603dd51eca29e57287a0929829fb22b9475dd1eece3af6d401a01fed23f015c00178a379ed4fe27eabbfdd0d6ecc7dddddd6975a2e67c478e1d63723071d3f78370a6922082f6fd5c7fed77f57bea26d4698d5e48a828105f5a23ee62060f5b9aac64ccd341251e3f9edf9cac7f286c469a8359d32b907c842fa4d265a71e9cdc171f85223e70518a12e17b435f5412543fe2a59186312ce820031cb048b1012c1e557972010c616ad082140c111f88a9b21e4888cab2ef4900b203b5a792cfaa1e0dc477fecdd62352c001f3a781e60feb86c5a2218975d303989f1ded43a8815e42583f7f5aa1e6228b95dd6cfcaccc884561b2e24f20de131ff5885e37ff62fdd165d9eedd9bcf9cf52cfb0ae297f57e5956c97dcf7df35e38ac241c3b425f9c1771509a42c5a987d88dffaefccb12638c4364b9410d8b8fc37acfc97bd240ec1485e9c67f39c4f7dec3f9951115e7339ced5d2e49959c6f59ee45a4f5ae7759a32358cb323fe835acaf79ed5311070785cc7150b0516536d97bd25c7c1cfb9258db934d601a68b2b6ad6fb4e18aaf964dd28aecc48dffa6d48f28704f7c94ea993bd745d9b841040eb9618d1eacf5ac1a62c31a3d984bca129cd56681e670a8dd672c1d1dfb949ef52b1b6ac75c581b0a9b91e672b65573d1d6e6e2af8aa81d7369bd5b97a5de036df5c0098d2cb016dfbaed3447d41c100f42a17be2dbd88eaa6c5735dbd5c8050510a488379e3011d72382efb24610054728a93004fe107f56290006317081b97e763417b38f4f69ad2e578c313e2dcd4510ce542376c798daed9c71bd0d22446c5823eed2046b594ad47a97357a6528adb105d66aa00795706041d27e286569d4c6f1acaaa669ab9d9dcb538c00290dfa1aa539b878f881e7c2ef5add0556e4101fad95ae78a8c1a964ef852f6e3febb213d215f73d4a0c14f4880b84f7b3d30b3d40a7175688aa179c4c400c1214d721c0658e2001152b5000050cba8065363d0131485f4cea5446da4c29a50fdad47420b8fddec3961cce6ea741a00b342f804963458b31374178f1e4a44b931918306567d41e5bdee38104da4a0bc06527251a288d81c290bd07fa2aa93e2ff27d728cff6ea492caf729df943baee67a05529e4ad552a375d1380a2b27a842893296ba58c119679870a046143bac8184154fd890c544994182939216cd4909ca4d5d76527252461a7f2d619ba81dbccd49195500ba47e485b11261630cbf817d6ff06735cab1cffb0f9ac0f9540de809fdaa115fd3b4ea311ee9245e5d9e7d96323640170ea1bb8435860a21a448d40e6a903297e836caef628cf159ea453496289496e34a66f928abadaa269fdada69526b9274fa0292e04348abdb265e4a09a5fc28a1fc0ba59412d2e65a07b472db244bb96ddb7661034929a59451bee01fe032153f0f609f2568e30690c6bfa1ca2a4ddd13acae74aeaee23f5f7cfce00d1daac0dd2333f38331ba7ba550f43565f46fdd10361d8cd8877d7a34d75e125084d0a5cdc939e79bef56befc1f7ce77cd89c86baa82b5197551185bab081a6ec57b4b93557639ff75672ac785533fe9ead64fc05a4fa1e05b0338e6ee65bbc11beaee992f42513021921e0a03ef61e1d2a9454659f2d727ed8b991d55a5e51b0b84ccb8523f0c220dd172754d1d4efd167fb3d94d5e0df401b0fd6be4a740046ecbee7292e57711b8a1714280d4ae9b64b89f8eb3d2dacae77f6a92cd426202d425d5645188306e01b27a3006e0ff609e35508815cd5197637f7357c373f6e2e6d8e550d7473731f7caaf838d700d7c940cfa9c26ddc23f1fa3393e3d4bd849a7bf183eebcd9ebd7354bf27d03baac22f29e191fdcc67161c78a1ce46220a1e6806e0070c81e1714fe9c71ddb8a97e5a641042f89c187045092d58c41863941709f721a5c6685580b7c8cfa5f6485fb74bf1354dabefbd7eb1bb1b4523dc611fd8831995c11cf1eb96cc96ba02157a5ca94ee090f802b8adab73bba3bbf4226a98fc86496ba404165f4216021004b7da618443aa2306ebbafd21b6fb946af4756f5bfd751e60fdae4aa1c30f59f61a420831708fc4dbfdaced52f97f402d193c026f11edf6fb0d1d54547fa8821042f6d7393064668ef43b7e5601c66e0a462bac71fb4b78d6037ee517f1fbeb744412f350e1e7d2efe477b484d47d2f511d3b1161e61e793785472d07d8cc3593e361c76ebf7f6f1d7be6c831723f37f77333c76c3e4f397fda111e6c41c60ea8ab0b6f66f3606f759999f9ca951fb78c36901ab77377f7f80e2184d0dd5b45a3477777cf713b77f7a32bb7087bb9eee5c2a6a77a56c714f4dfeda494f2860f14294fa0a6885d81621ff6e91fea79790a295b9ed5d1545197a79082e5be101a0dda4059502c2e4e19ef994a0172dba43e95db0eb21cc1c4605cf9b1980df7c814d2bad3761ff019f2129e0c32cafc0e1f3bb3f773a2942133a51442c9324efed78c71d3d827298b11ca09e55c39b3ed26cbbf114286ac710ff47796929da00e7f70c2892b577827e3ce1807059527d35c5a3d8aef75c9b8b3cc5b903fbbe594527e6ff087bcb7f8fc5ec68db91bfef3ee7e1fb71494dcbe293c17c27b74909624c2100ba0e065b5f39a524c52b818e3fdfc23eceefbb07abda362aeff80b7a90b79b1fbbc7869bafe90308feeee984f691058509d8a4769ceff005cd4eec5a25cff1786832600bf4c192fbcb0810ddcd99a7043ed15fcf10b4c02c6e14212646f04b52f3b119174df734df69e79ba9fb702b73dcf1397263ec685ecfde3e794458c1aeeaa3978b9698d19eeaa46c91e30028d75d9a94a0babcb4e4a5cee6ac70a28bc88bd07a5be95abca509fd5eaf773fdd52543c63c52fe7b22f8f65c73dcf517612ed2026976c206105aa8ec60030b332c993082d8155f9ebce0065c9c8888719fe6bee7c9719f37fce67640a92f21ed6f5f75f5faf1ff792ff4fe392db2a1335e438caa10f5fb1fc11cbe7fdba1211ed4ff1eba7d3d1f2ff5798b90f73c98d1118cf39e67c2101032af9f1af25f6e8700a15b6af79c78b94239b4d010dd8c8cc85c798ac1e4cfcd28043950023663d05b420ca108bd7948735b68ba13892b34019bcf2a22df218a293118e76a989c0ce3ae410ef367ae2d3ef119d4ce63b43e0df5e6eb6b9f7a55cd67611e368f7373f3381096818ff3cc2c66d623739f3f7ffefcc9279f94f3792c8d4b8cf7f1c9d554b9ac561e839f535fa7fbd5d6f11626137b4a5b70723ae7e6fbc63697de62b33516f6e9f7b1a562b9fde6bfd7d24090c70fbeefe7f67acfb79fc840499346a3f111a2f2edfa3e9f216a4d3f35508d6da6e63ef5fdb485ca7e16fa9ee4afccd55e99fbfc95b9f25310fad6cd25d793484384182a38137d20d3c4962e5c9cae8b792af35e5cb7c175a1fb9e34ba9ae657b32fd473596a7ba1fe5dd405c1044f1fb05017804675bd8def7f9da6b9f69807b5fec6f7bfadd1f40e2aaa8cd97886b598070ebf97dbd7036cfceb89b87ec72669b93ec98db7e172b95cefb24a92d878d7bf6c85753ea5d56ab5be6595b83ec98bfdcbbe7f7dab65877e8caa10bddec6b3f774441e18457489c158683d075277a9659360e06587784f01ae6822067bbd0d1bad7fbff3afef3ecccbbea4d81116471037fef5cc0418675ecf04c25486b9c87882064c6230576b7b4faf07c213af2986f4dade19046871e645c4d5bac1f49c9070024de674c4171c349da6df4bd27ad76b88d111cc658d922899676036def537ec4b33cfc01866c3c6e61998cbbe7cbce4cc50b726e33dfde43dddbbfda4b91c9a438a35d707f8a276ef2eb5bef3586f69d92dfdb4e5ed20861527dd5bc8f4f7f716a528cdb5122c87fa6c337951e306820b8e96761073c509a4a8c183930ce060050d9930a820810f99bfc73a88bf24c562b1159c3410df7ea7b2f4453ff9954766ca92db7993db4b686ee7516e4f8175eefdd4402833af9ed254fafd49ac6550df332cc66a01bc90b10731d70735a711f67b1bf441838c1f7373d5358d1fa5fed86bdcce399fc0db3ddbc122da7d1a9f9065ae2eb67ce8f1bb2d8b1142b745b4acd99f47777766d67c43dd271fdc21db6902363f7777f72605640913c661c7f8de0be3689eb43cdd639b5db502d73956b53a6c7e1a0f0f0fff946008249a34b7aa2b204b9ca135300c41c445b9a0cacb4e4354b99da6ad785655d3b4d54ea44c2cc020020b69ac846143929531363059918206a41fda440cf347e8678790124f28fa334492a4956a1509264aadfcd00488124c4dc85831811517928024412688343400d18214040d6400824493f730a5d5b5a2e208a4284e3ba092904e602f4f9134e53aac05f5f55ecfbe1e303f3e91f9d12649427f5a2232497c695fcf3245326409b531244616a0467d6c847d4650e5eb01f1e55781fff28f60f3a1258a46d1bedaaa40c4d13f82bdef388c0ec8ce35b72521b9457f23ee8fc46315b0ce80f34412dacb3e18a283200cbe051a886f1a553861831b9eb60b40a2763cf0a2a017262a6da5d5958685106308519d64a012071ab73fbed8142998f0e9307171fb88da693c1cd3960f2e844d740063c5982dceb0a1041b20438d19603983831c8849638993a6c385666ab2a3e64a143575d9898a19a91ba8c8e009151880a1f2051a51331d6cf801c4142935c4309d740fe710c575c613ca53e97754a3b64a79ea1e2643cf4811c3d57fa686b8843463c0042a790f3bfdf8210b142ffcf0e189054c7e4c698a9225062d3fa238d13d7c3b5a5fc86a68ca4109ce54d4e5a61c345963fec85a5d2eae07fb6436b50a755b2311c07a0c9ae387cb6cba772184b0c2afd9509755446f9b17ba0a021e2f84d6480430b72d86fd27073b6cad07fbf0ffd0ea7afa3cb8a1be67a1e6f82985352f2287a19e51d6480429335e3b8c725214d75c2a73c19c6b0e72283a334de3d88f7c7ea11ecce3bd581d23b75f728da91272cf711ce7faa9f6c55ecc831254873706ffc5e28bf98bc11a8e4be590bd9f550d36d090266a0e662af8f48a56af057911e7531f3f0524f7d5b779d6dfe86cb4399c3fd24038ef6f44e759c7b2659c0dbaaa8437a5b9688b34a7fa814273fe481a285309c1b1b43955909b8f9fb315dd7cfc4c5b7d7cf8d92a0e3555055915c5cf79aa0a123fe76bf86639b6cb799c8738399fe56c443a549ccf2901e78b721e3a20c7d2fa38b6bbb12f2145ef6bfe7db41a540579b6c6428d93efaa12844e68ce9f05d29cfca5d663a07bde67361a6c200910519f0cece3cf58921e95cb4e5890ae5f7fd2ed5095d00349cd1b69a09a8da8b9ba9960811c0d6e431ae875947dfca7d48ed3e0e4bb9a932f1ff5f0bbdabd262f7bb5b9f7a4b921576dafc996c36ad61d78e476abe6e017d16edcf155dbec90d1679e54a73ec888b3432219aacd96a37b76b455733ccdcdf946502f4604982a87718117be461a88936eaa553efc7d8b5b575fa9e7a5761b05d87c076fa44e1f030d447f4a4b3532a95817199ebac8a03406b54697265792e0a7a5b25316a59b7ad553939818950b80cb626248170c18540ec4cce045cc0c4ede15234394f79892c68c61427a549e30d04093c99cd040118b3b1f8506d29e0a97be53894ba6054f5a9014c6892c619640ba338c134c77de69a3d1ede53f8f3437d3b8f3254044a57fa3ed345057e40f359ba7da31983b2d5173f3771aa8a8ffa982f8438e37abe652dfbdd8a780e47647576b20beb33be257f535ff96dca96db4b9d49b405455241c5dedd9da947d4a25a49ebe051a88f296d436e50790e6e65ba06653a984d04fbda60a927dea555bd14e7fea535f9b9b9a2a48dba2d4d3d75441524fe1a7b69de6e6bb8ef83de2977e25d2a1f6d312fa8be8af9a9b0ea0d6d5dc7c21dfdc4c7ddb2eb32f21b6c89fa65441dc52225509f4dd8ad0dcfcf974cc0fb7dcdc928d85dde33fbb6aa4b9f90648ea588cec5a0954a9d97790fd4b38bafef3fb07dc692023b5db32260fabf21a6263f966ed369b0dbc9e3a022fecd1405ddd116aa06cc9e6771a88533f9fa783206c7ef5201b6ba47be6f3cfed680470a80ca36fa483a81335a97ce9679b90145d7510ec9ed46bda6ad5d53b53f46173ffcee345ffc170e172735c06f3c496fb0dc40eb09dd1fde652f04b5d77d2a7f6ff25b5b65083b5cb53f430c6ede8bb8064ce9ed6dd056e91addb5e10fdefdfe63d9cb92f0418935296803dc69823c61823478e31c618618c31c6087f7e628cd1638c114e1f787c014b41d2ebfe4a76766ff7eef6f7de7b46da9dbb13ae7c6e7728a133bbbbfbec7125b394ef8ba67cf3e17c38df0efbcc7fefbdf720fb40a8c241084a6a708c8fad74d9ee5252f6e1f9cb9021171182d279e23b94524a2993be5cf8110dc98c06a506ac4b4e1710c2c7c4f58f30c618238c31c6087b85ebee36e818a3c718638c58308f2a692ea38132c276791ca3dbc873bd5b4a296516348d075a72b67c59a2c9e52f4a34b94197bf68017359f246556f85ca5fb468b91dbc90e372c02bb6f07221849007ec3262af22703cb1e17b398a169a5c7ef831ac902afcca3e19abd87e70820a9f21e4aea2c3a9fac31b3f15a3bb7cdefca574e9996b730b216600c69dd3dddd394a89c58e5e3142c6d431aaffcd65a717e033ad173e7ffc2cbab46ec5904b296560034de5974fa57caa28df8a1baddc4868cec1cc1e6a9ca0b66a3f3841e5efe2def0819225f15097a1a862880ba1a8220517def081525397a1a842e9c28f27b08fc718638c8c64c6853246a98a568753ede718638c913719635c512899555a82e81125470cd8f1d3326a919c5346c8dfc90899a59531dee4fbb7bf9696031ce5c6a93ba5bb6f0cbf4477e71a54d565a72a4bcccccc5576b891a39452ca2a4f5094320f9652ca38a58c31560980171c32a494524669dddd3df2bb7656f2bb1574e7c8ce9193ccfcae9dd50a62e13da58c114e2c32e92b299d9d3d33d3b1dba5f943edcedc29b91ee1f4d52a42e8ee68446686f1a98e3315c5eeeecc91bd88bb84cc247394cc910168a4845c64f13ac618238c31c608b7ae88ebf66711638cf1c518638c1c638c314228c76000941e593040cad8dddd3c374777777777f7ebeeeeb7b64bbddedddd30875057a4df7bef6d0f8855c13e0f884dc1b481e27d2f8b249054411566d05c78dfcb7fefbdc73cecf3e69c737ac31a27506301512be0c3995700be704a19234cf220880adf75bca0fac30068a1230c7d7777671923845b304e195d045f00b7285a149652ff733bf6e28f9418d1a7298bb24b98f8c0508f9403a33726604585dbea763977a2643763fc0eda256634f8e34604f61ec2b89444097f4982b18df1972498cd7dcf2a0af09724d8b346fcae4b460e5876c0c244867e0caa60061f58e84109d812263eb0f74839305ec2a461f49114007b8fda901400a3465588de1b99e05550d6a80a11fd678d38e7f2c465b800c5520dc4a4a08c138c617c54022f4a4081c2c4d31063c018c6441f8bc11e1d9375f4f1bf9745fea44c3db79d92cbdf51ffa427a4005730b186d1e5678e6e39c05f3aa30b6dc7a9fb525742082384ee8e464c298b314620f73d672ea574e9f23b132e7f46ddbddda584ec5202b94584ee7bde32c92c7584a9fc28f8fd999452ba949bd63a9eea37d7312ca494f2a9646e4e4a29259c52c658ada8f1902184b091c8c912b309001731c618218c31ca18218422e3cb3cddcfcbe23d9e0fdda7bfbb7b0e77f964362d07d84c4a086f71a3656666e61d02a0f2a8a4cd776439e914d108000000055315000020100c060422c150340d645d4e1f14800e7a96446a4e960c845192c3300c420618430c21c418000821c418aa9a32005db5b6e153fa874f6c0fd58cb3a24012b178105999e335931a1af1266b43392c68d3eefca7ffeda473b2341c5d2cb0fbac776d17d32e09136429ce8d9338142af5b4f7de44ae361ac4574120bf3a9664e98a8518e63c8bfeaa68577c055b847afab84f00bec1580329b06d85e7155dddbff686dec120df6e1b50e7bbc087f608fb166cdca0e3cc67ab338acd8bbe0c1c1ea7954aaef3859b2babf3550b574e91658f200a31542fde0487600fd530fc6d3c8fee4d79cffca8cd9f5d82d5157f0e68ea6a9e3a41660091d3849279f8f359c0f51b42d44989133b2c69fc7bd3b538f79cd8ebecc1a5143ad343e69c893b21df9629eda6fa685409e8e0a3a7cfcebca1a96c4bceba22e960bcca3a8d2bf67dbbeefed1be424d7d0359ad03fea8f04a516c3ba79ef3e2c3377b407d8eba19de79440317589f05d1b4a60f356fa91d02bdbdebaa1facadbab2d610efd0d6ceaf5f4ad499c439b98874f0bbecbecab3da7aa0ba64568845441d4dd95a7a539be11e2874294faf1c337589a5f94b7ee151ceacdfb43d7983a996a642d3364e7497ef42bc4511b3102ff55a6fc895888a7800e1e1756694199df7e6a23382042b8302b31a8f039041aed2b3b15f0d6d7b40d951796748ea24067a9f6eaaa97c8fa3ca7e60426c90b7b53ff9a638a6e0e54ca41cbd1f5b3d4110945c3b03fadc187ab79258f11ad9105969e7ca103d2107db441d95353969b92cf13eab69546a6956a523ccbf0c7bae38648069c54aacf17c0f70fdf1f24ae2b351472d17444e394d439b1f9e730b68ee8c3f7353aa76cb7e597703a987d4a136c619aad00f1fbbecbf45c408668e2ac12de02757b00f79e9288df93ea2f4d8c27c0b01e173fbfd78c8c613343325e08e5befbd1f5739acbcada3a725061c1b9aec8ce879a77a60f8e11bd6b4856031b4ef3f2d3fe35fca47217ecfda14f8af6b9c78d541d0d0ebaa9da9e6ff358666d372cf359ce425073826e6e33e86e719323eeb1a201c820b006c50aac07e0afe8a4a6ca7200be6c84b9b7751faa1627e499bfb067a92d3e796c1cd47883dc4a36043ccacae86519f0830a7eb999997b5a9b7f7171ab4afa3cab224cc53672762b937559bd78290fe86c39ac013218b233209681c5a5994070ed4cac5d8ca5390721de5f9fd1882d0ed20c0335ff92b7d4188193c03b28087e5616d9c7be915cb57f3f55987e146bc543c84a1f0368e333bcd0f0d930fb786aac1858f806a44230eb40910786b2e3154ad63b67bd1b3de7cab63aad335edc7970ae60b10c192c89ae564d49295ad2e952f93adf2d823546874ab97f7df96367c4fdcace98e077b6071c13a0b90f96203ee4c04115ab737e4b3f4bc195b88049516803b90905ecfc9ec5ce80f80c8b8da4fcdcbf4fef6baf5490b94559e6dda0a23377edfdd1b82ed32acd35de57c53c6e3d55b6312591fe12fda09952d11ca2ef71008904d0d8263c4c766a0f0802781f146f9f3d5f1ff3e0547905b511ed9dda0d4c52aa52259a8a52c52ef8a592bdc2b1ef85bca33e8d0da3c277cc6af8e4a24d0c9aa48315ae0355ddb99967dabda37708e71e888363ec09c366fa8302ce0a8d7af19f620a085c01bebce107bcd3e5d717a058734af81d5f224c1005e96a46233259fa2ddda3c4b40ee5e834ef91cf97c9b7fcd3c94f18de5b531001a56fda02b02683ae64ed5353acfd4dbf96cbad78d10e90c47398b22ea4d4948c3fcf1b490b3041e205c9b0af55b469fd83ac176921431b099bab13ac3df0949d855bcf0d6d8934fff8e58ce738a2c91b032b7c733c60b433d2829dfee630396dbcab6573fe506af44dcc16532027f6b663163d0a55ba5860ee6b23513a1674260196f2ce598a540fb9a28a3b87491a5e0b9c2d9a02669884148da3727fad1c24642e63840729b7b64f56b84f137cb4f229af963e92e288367f247c845c71cdab9079a5e1c9f46bf22843ce236fc91129d6ec87de684143a27faa49373c4b5d1eca62b83ceaee434c883d947a2543e8c1f17eb09275368a04305095a489e70836c268021383c32c9f883667825b17275b95c9c97ab5b018deffa56d3e30b609c136768f1fb47ae8eec1955fce90f2ee74bfc572f4872d882af15f8b18c103ca7d9fc707ca1e1089939f7e25566c7bfdec2c71d4a490fbbe902724d8aa32bc93bc8a28c859c899aa103499671d0c743470389d6b322e98fcd2e3a3eb54bdbd9f645e8d72715aa357fbce4913349b4b37328fd52c044a967601dfef021606e599a98cb69ae80305eb40c5efd19fe754eb9358dd08463a7f161090158396e8b0e6f7140d55a7e1e6adbc2e1cd9181f51d86df362aeef850b3a8bb79fd4c61e374ba39403e24f7d779388b04c1716d298b9bb2b3e78fe3420aedb65dea2a3b6cdba71187f0f6ceb41dc8cfb7e9c0c099111ed3412640704d788087267f7d30d040b22e242e89450f04d480f45ba324162b2680da0452b7f4aaa4fdce0f00f19f7c3818383c649a94a2bc7625871b8f425b165bb6097194950b1b78326e5ff09af1be74e08de40ab97064c15c6bfefef66283fc91defa6cca900438f916a2b62c0341dc6fa07f974c41af7804e4a6efcc18b564d001f394c7784207078d670ab28507092e5278bc78f68d8230a36928a11025dd15c593176751f294642482bb64f9ab263bbbcf1f6c6b8c235fdb7b83f6a1954449a2f0c1f003d4ba57beb4738f08bb02687f479170288a3bfc933d60595d149db20d7120a8e2b037b72da47ef9d3ea09af9c39d36f37cc60a2de5a941eabb1b9126bc6deefb357a25024a315646645aab3226175aeec54d5c98e3cd9b3f64306609565153f1f3900704a1a5ad5b0c8c3a2f896cfc9c739ef2ec0c4bd2060965b413946eb37c3822c81e214313f51f6bfc88078f335db4ff2d06c11798cbcc17ba077a8ea1d5bdfa2b93c0bdf4892f29c1b2ebaff9dd5c172ad3371d95f877e849f8dc8af6484c609acaed6428ad045e46ef8c031c0df355adc34f099389d07bdb58721f6a03387a478433c73a057234422a59ab3f1e436f04bfc5cb8f9a4d8759c3b3d642726bc56812294404c9488457e83300405717f71abc1c0578855e6a46001cfc3eb823d3d60827edec2c05cea8bed3df4ddc619dc429b3c3bcbfc8ec066deb5dff38aad16c5f89acdfddd219847a82303a70540a98ccc6215c2eba47455acb05a9e5dccc185a302e3af9496b58053c2f7b40996f55fd9dfd3d7000f8fcd4020e32241447b800253c1afceac8cd9c49e76fdfbe137ec0697c1dd5ae3448ac7d22e3e186f93f9d8c7215a4ec9bf86121c8c3ab56f31fcbe0eb6b9205a1dbb2c25dc7212317e91afdac359597ba85d7dc19c7a60d9ee047563c5b189a8ae802f83c474dc840afdedbc66e45a5997cf1114ac86bb6eeb22be35cba06d3835f614e5097094f53e9a7002d22a67e6c1856aa4129ac3670c1d5ce8fb898cf253d949717e193630fdbc10411ab5d21fea1d1e18f04811bfa2d5809861e64554f1c586d81e3f57cd37c6f50e037da474c7ae69053dee608267d7eda26f420ab374b452a3b4b3089cdde99dd3c550aa326b03760ce978337100ac30fe942b1e0cb70b99313a25eb507631b6f93f911218c710c72e8a49d1506e32fa0ccc3c343f204a2e5a30bb5d787662b2073690ce90ad7bcdd6affb0ddd558f2dd9a2c93bd3910df525a75595815ac4c0b81e54d082b102dd1e66a43f411608214416db64d109aa26460856b5010d6d05baeb49922774bafb2ecf188013aeab6d02dee5bcc0294c501fe1789510459f7242ff919531cb8451accaa4c660ae0489c991dbc31167ab75d2eb878da7cb78577dc0d9c628d89764e31eb8b5582dd5a4c06289387c738fa79cc961c530d7d8930f806fced08f7cd3296baf78dcdf0f892ef2f56bb675716e9b0680f5dd5c288e87087b3e76fafce1fcf67c426fdfddbe85475121a0e802dfd72ee25646cb5f7ff64d67740d55ed843184d89bf0d2cdac33cf8d29a2eba8e11df96f088dd46b438e8e654e802bc4b34f3fd8bd2d5af1d93d94bfed164eeba0c2e97744301d58f8b40a4c10296cb3d7e6e46c452b70d882890240b5a0607c38a4ab5582074e06191f46a575eebf0e40ded311054074b01b9f52a8e071c2c6b2c6df888d4f23021bbb1bad1d32027c8131cbc96b0ba7aca99e1240955fc21f3dd66aef9e7ee9f533ba55a3214a0962d2aa9b41496025bbc7c95a6a60c8a33f9f7f5272bfa914d04c1adcc58ac3cc94055b6a3ffb76e915486326ba0f16954d85430ffc6f7ea619f7efde232a4630fd7d9693653c92464c3466c276c50cf9cc2a2f13b7718fe32a8c4d6fa692d4ebee100ece83b37479417e54dedc1d96ff3199815ba73aa56d1bd9bafa0499a358622fa8d544da8b8cad968b5b3fdad0acc91b4a0ad09856a8bec94f351b9325d98e8116e69bc3be63fc5d49f247a7ca83b00ef31734e3fc43756686c744b19407d39294b46d8790ceac6442c2740e9230df011e2fd283987a5ac1a02c611d14c2d31801b6ac54a8df17665966df48236baa1a6baa95eded8d330025e0573baa33bcb50991ccc6d1f0a680df812e24c3712b3c897e571955acdbf480ea39f4aaae5589e6af06965d2f6adb4b75011656fb661b1ec754e0a988d538deeeb49459e9ee448174a0ed9f3374c7b45c676d7210d39244eb466b762a106171d76e3f141ddcd4af49657dce17989a40015defce5a61c9061330154e319909d96dbe4aa65d74b98377931d4699d9d4afeee4bfd54df663ce338e348dc2d5204e4d26e10732102763143bc558517b6f5f7abf215ff66b34228e81b40fbd498daac1d9be0008dc64473b559cb6009b9e77060ff070e3f3926f9e31933e82d15a5b49abcbd64c0ea9cd3e4129f29d2a548846d3ca51bb5f915e41d730962febeb463a7abb372a96aabc1af4d0dd9a4cd87915d9f416fed2fe0a6c5a32e906310fea2ec1de921208e536442e78aa04ab7faac6e1bea5ecc2c5624956630cf4674ed34b3e6670bbd8fe0a0e3dda01603187c0777fbea1a1908621da9395952571a56a478383e408cd3ac039a4ed983c143db772a793be6a33176733ebf871633d51cdde740e596423ce173016d2cd6024dcb0f9a3149e72b22fca10eaf6c9b7ddb604d9b4bce54165f8e635e9e66e782dd4292db9fb3d0db3c74e5391bf490bc2cd35403647cfd6a686cb0abb6c6f316b9c9ff018cae0804d822c1fdbc8f13c94cd9476d08c8deace3c1f2332bf324d868ad31ce30378d55ba9738cbe270547492bf7836918aaf35c2de6c1fc0de01b3b3f1b6c004b9b044f77445d185f4cc126fa6c37406c3997821495f05436caa9c0b5e0bdb4d7bc84024865c0df923b6d7e136628f79a500160a4003ef4aa0ea1a2ff72eef5abcef63c7a4847573428ca8b77c58a74c1419451b70fffe4c5a08b1a0c248131d75a30a9a302a7ca228d1b4b2daf33182257c9c1677aaea673bca8b4fc31fafb55dd4fd9873c693f2bb67be77632662b0ece6143aa7578184e592383f209a12ffbb7364aa9ed7be1f1408b5bf83e58397cb871cd24e2a780f9ab9287bf7becf7c0d796cab4da0fc04e616a5a850ef580f44b58fa1e8d818da030c459aa111a66903363b74267b403eea61032e7805d53901fce3a599e9a5e31451066f0286853a17d13bbfa79dc27c7d806b318ef35c2172115915b597b5339210eff3f4d006f3f05b1a0ff43d677bf2239a94ae130263fbed4255dfc39afc922b3fee512ec859b2dd2c909a1a97f246eb1594ffa640b023830bdf0e3fe051cabbfe72517eff7e389f2748122aa75230932ce1d27822f40bd52b80a8995178ff2520b065d91a2dc541163727a4102f8bbdb9770e5e7ace6cb770bd69d2ac9157aca24ab27f701af9156857d0f953b3177917271bd12ae1500cfa1cc9986a0003742909696d506fc4354dd08069d642d3ee669922779b032658811348241340a807f9c30ccc26924810820a37901f6a3260206695891c5a98828689bb85875f950534b0ada027dfcee8b384f9535191ae0f949aaa176e01737be18021a32818983d9d0cfb18a49c26ae65d2d22f431a063d561a2aceebd1f010aa7538c416b430771a695d19c6d1917fd14c34df610bb1a59e070ab24b638fc7ce1501e014fdd778199bc226600eb6014463bb5477c37e26f14d9a4c2e86cb02bbdfb04f900e23cd78084d04fd80ea69681c539a03df69f84237301ab5263d520b33583654b0ac91bd1abff86c2357034a47ed7451f180d6c198212567b17e876462abdb680f0d32fcdbc3a581b613ada3e3c5c7881910800cba3605c33875aa111452062e8ea62682b7aa141fca5e08f3c4c552f0b0ec6a6e8908e3f144581e6c134b818d2e5418bec9245ff031c3e4b1b792da12c7b015666cedaabfdfa9db15e9afe946347d2dd6890f53f20ab828223ec5535eb2efb5dadaff4cade57471e602797d9a3832761b57d8665366161ed937fb9c46be8fa7f1df59039484c8dd761538968c10fe0c62feceaf5f3b2d8c40a12cfb04059f88809c20e5650209005d5bc72390bff0755d849593a05f1a902776d4124923b8f3fe3cbfae051a5ed6d2dc2adfbe358971ffb40c1e74ca0f8d9472f9b82262c92ece7478509a48b4d0113c1eb5c1919656ee92079febc72d8c081f540cb69b88131340ca569f4fed0f856478de9293af3e2c4cc33ac94a6b307162b4a52c78c153515523e0d3649e9115ac887e2044ee48a5ec8062cde12fe8fa8f271dd0e4668118e5aa820753fd6842a048b4e096d0044b31df7cba2d88802ca834640a1438d07903face7e8b343d3a988ae59789b0d9d0c1154164261483cee107e19950514447cd2bb6ab1934524d02fcb851b3b78cb6a76635163e331ff33b5e635678ec947f156fa79597d09c90697380f2a6a97de3ac74038e04454e3e43f7ea6d93befda232d481057b5efd1a868f8c3efadb122b2f49ac1a6c95a7085dc8c08abf6268141ba154731a457527e67a0f92dc2c06cf782a1419091318632a6beb0c6e08704f4d153e9dc80b34966a1f91c9d69ba8178ccc1b209280b99f89d7fc4251ef6527396b54396a46408fa66103b9a1cafbb8514cd51af15f67ddffd120afaccf022e0be15217a3f79729b88bb6d40a611055f59d4620e08b4e6818014653d9663dfa0d266498265b48737bbaf78c77836433232036700edd374d5f7a37a49b50f255a1972f408ebebf39c201bfb0aa89c33d9b3ad843d4632e82033f20228faf072c629381615fe7b3b00790d235de5c82a9bd05c348c3504640a4563c42e9ce070ea6f8761a78557cfc2fcb0441465bccd43a984f0d3feac6aad599ee5bbfee8c4de2bf432c12b674f81afa312ba99327ef30218a60adc3d49422fef76aee346332ad648a0b17aa905c3343dc623d79129b0f277732ca285d84119d5b568814677943b7ccd8c8d9b86d509b18313478853de55622b4abdce88dd0f3a99d17c85de8d9b67197f029b5c1574781863717083933f7fbf75a9a89e0a5e3c32eb3e2c94378fad1f96ba941a38ef3cdba5f8004f69962be63464144b27d6fd8f09c5fd96563de77f430cdb01857bb24a8b0f4f71db0a4ab263eb0755928a11789d9595afc9f2da4d7a7291b0af7ecd55ce921308b2f763a457cd50cd7da2f4ec060380cfe7aaff2a44c5155cc4050f7945cf6e50c102d806c6d862fb7303b2c17cebb39ab8fdafbc9dcb37f0d2510bf97dfb8d3918a6f70f4adff7ac2a0f5786c48b5645cf9ca3266f680780d3035cd369bf0979a2720d7dfff0247141a0ef1fe2647ae37112e87b68aa58537f81f33b19b7bed1be3300aa2b85124bb5f8f87e7bf801271b8b0a82fa065ad191cda49990c7eae4ce17ec8a98c88cefc7c5d6e559de7bbddb8b1d755e03b2f11912960f4907a890aecd8003662cae0ae931ba2f789cfcda1265f8af901eb67c601d4e6d4c36423aaa02def1d06e100aece649f4fc9e62a94dc65eb8354296a7f30af2a2feecbb317b3a6f45f320ab75183140c25220d49933c73466c0a3e84b621495a0711295d63ace60fa84af825947de6556dd61bad5d2d9c30ea2e15390741b77655871c20fbc9c1122fc2373c7e9be0ed2c20b7d8621b0953558ae372b2d59c0c6bdac9dd8f41237d24ae13c09d8b4da401c77afcf5e55e53febee7d5ea1a65000ca5a11340f6fc42dcf4d98d9bede8629970864e59c95918a8ca620c116763fa2f4efef93f0d6ce538d9c59976c3f23bf156e18ea8bdc27a0b238073fac3bec2430349575565a1fac82e33daa307093a9a2d623b8d4261945d801dea6700cd89bf4ccba4d1c84aa2a45876835b2c7043aeda5928e20bd6ee885fa31f6ede66529c1fcde747c68c83a7c1b48e3a05b83e4ab645ede1581c9e7923484e9af97b9480c43325880fdfe1ce99052f63931a3746e3fbc55ef0d9e048c5ae6d6a15e2d202d88d0ff8a0e8a303a9e93450ed5f360e3a882ffd4c8ca6f1e160c0ec950999ff75b5b77b5f289700cea5a6ba3f2e0ff35382e75e887cc61baa01267c5507a1b97de680e8072f3b935517e96e8f1b1565fd790960cd5b5561a585a210c003ad5175e30eb2c165573de68480b300503456c762df2b3b02596b42548a5245cefaf16a33d946a548bf810d0843370b1b800dbe5ff7a4ec3d3311639944edcac077d5c7b08a9cb44b48cff26b0e3e41a15d8880c21e1fe256ed2f3258e70d0b0e0fbb0139ad6b15cc06c90b221d5c79c7d44bbe3f9e272100d1e48e20b7065acf6a4f04b8824b3f22560303537350e3c376983cbc2152bc0293025862184c24eb17bc1bb5b1d012c3b25b61cfb56bc7296c70db18cae58300303513f6b43966bbbea555a9113509494a5d06b0e28a67f1aa2254e741c489fe0cf15e11461771df2aa6fb45c25a90410ae9f972f542c6a4d0932afeefa7a212fc6ae982fc9e783e9b3f8f17a7c0b52872e59ba1eba64c3a09434331b5d9c2cc161e7cc2d544020b99cd4f7ef79243a25bd5279d080130e25bdafba91b176685846797c34316a3deb3e6f69d6780701010305e88896b850bee1413577e28cf0994b3958ac82aa56750b0f34e045e405cbd1ccdcf9515456081e1b0e3901e29a5d6034dd0efd096e7592673d6c590a3f605bfb1a4241cdba6b3f1d229adff5d7f517fa7e51f7b147b20e1bbd6b85a9b9b8a48d0dea17570f48eb3669e14688b64fc62adaa804f32b00a6664450055458a0d16f422d8a96782cab0bd600e6a3661e69d6b0f9a2c5a4dfde33e67e9888d238d6d09fb26e3f4c7fd672078db9f71842cbbfb327c128560bfadebf4fd625eaab25f528381d82bf0cae0bc140fa2f48a746aecfb886935f12b65eccad902801cba9195a4e002866ebb48012bb3dc3a0fe73610bcc7acbe162aabee30e3107328e072467690f9f02f022ec28dcfe9c69066dab843925cd03a9ad1b9d5f0d41bcdbeaf562bfd37b2f32b3887c0cec0c8bad6158abc21fb16208e1a11bd02f72f2b17d210789cbc5d46e4a2ae7eb94ea04477e650a6cf63be662a914c70efdfc9e3889fb7e594e5d9aa7e16ddbc6c3684218705659fa1c4a94059a5406618ce75b85805e6d3547e2b578a7cd5c7bc9a958073219ef17f6a9beb433693924b7159fe43d42b44621e95b28447692d0c81cf5f6d6a9e157c2f6f6c4e8fd57d3d1ef52a606e653b8bc434874b97ca22d96aea640ab83fa707cc4163fa392c10ee8207c049bfbda820321c2d2357ae2702dc89d4838a0db4cce62105103c18f1f972afd4dd436a09ca1fe7a46ac69ef51a725e2a908e4bcdab609b17ae49c28d8d9133cff227c80195892e5677517a23f8c27d569ea8506964d8012d75456fa81bc110f865a1b363bdd02f5b32503b9bc7b7aa178f706e5f1ee61c50bc61700e286fb87df19da82a9ad16045309877876ba6d81d3c842ce0f67c15412d02f0613fe3704d85bc6903c39f4e1a93655eb810423d69872a8470946203432ef539db70f9748c9bd2cd1ac9be10e9390a687749737fb6428fa9ffb4838b9dc29836a50c641079b2e7b6c59af4ac5bb340dd8cd3b31a99a1762ed34a40b5a726841251e6310ea9bf12f4fd74efb97b09119ffd6a9e426b8b2d0babe2a5b976e06338326b6619b763001884f03df1f3ed9b93fa80c39d3c2a0f6181a8130691d0b5fe249a4e1e100180542dd3ed3b3a340d9f241a36b59ee037254cfe8c96c5f58e247bedf00b18cabd632e17741d29af737b58628b794896817cd5d7739fc4ce3896c8880518eb4c022fb29745f0ccd7d051fcb34614d0c83f96c8132740b3727ceae8e9f9c17c598b628b72c82cbd0d4ba20ee5f35c910cda2ea3b0186407e7a178aa700c83f87becfc6fb87987070ef5235234ca5ef934bbc5057d1fa41604b1565ec4bae6c153635ea2ae5a200ce75c297a29426b8d4b0d32947fcad47a680d57dbda41fd95dcc7774689f85c03707616be010be7b2aff958103a7a56d56b248062e27c666fa1f0ff534f8bf04e3db5e6dd0355b8ec3967092430ff5ba255d2179cb0bd74b4ed3b0618631c811a0e088551167cd5ff863359194ef3b03a046e1e40e02b3e8e369cb3714c0a584a034d51d7f68f8c5735323f4db32d5d5067d57cf6d9dd50f68167a0420c22e4f0aabe006fb84ba21a23e8bc9c0d69142d4aeeb84e4390653e0e0c4b474b1fa9e8567211088dbd8e5376265418c812a40bb025cbe2f5f4e7f94f4ea50b2b54cf39890610e23dc68758004057d0057844600725745cd64a5151213f16739ce89c39ff8df157a56110e610ec29218d24fe58685009eeec5fb32e9de1dbc34e4cf759555020643b4c08d29d9b577f71ef6c2817115738f77595d423be8e2e18140082ecf868efd36b8e17dc0b233ffc5c9a9567be1d233b27f401a4c9fe1ed6fd36efb23d89ed61a5d5268d4510496351a2690514be2483296e078811be21060406b91a4a37ab9e6d8d57161a9de61e0453769dafbfe68aacf8af2138f211eaa1635f80cc1d94213de5ed8cf2d13d4dc902c42bc53fb7ba566a03cb8797d36be2fb18a892f5fbc97deca64b0ae52bb3a36ba6dd13f64f2e115a3b6c91e96406fdbf1df92984904b66f13fe1f8ee049cee577c08d3e9debc1f6245406b32390432a91500f56d48737c71d4a1c44bb50c602089783485908354bf156c989b0f30383b7896f2df420560db4875f55ff9d56053e938228922bdbe3236e72ea2d1d6b87e4c220256392f5d83fd4a94ea89da2d4d28f6a4d8c65ba3d1574d1418a7abeecf5b8f7e759a74249c9a57dd1ac0ec544119f144ad68e75047097070329b44209ef21e0e9cd3ae2da357357a72e65180ed0a9c9f699880db5349c82319a793b43283ec81787466fcd680d6b88379e94791700b483c97caf93b5b219fd6bb230678f2828ba107fa002b502d302d889edc95ee8b90434400cc2b5a5e89a7c34e5d072cfba29f1dd1ccc6ca90a02293696a40bf3b82092f0f80efd27b56bb4039b419beb821cf9e6a3c79a19f9420c5a8c4ca626e3119217e6e18e8f7150c6f9ec8c7c2220aca6146a0467e1ba4b67e6a5c62abf7747ab094a18e2252c14e7a3c4889e781a7f0c94f1424aa4488a4f13ddf5e43d9d25aad0b5765964b32551f730dcbd08105ad85f6e250a4c6d6520df9d57529b6147a260896f2e6ac799c144bd8d8e7de1a26786ae57907a5e7de94e601aa7420961e3d21137f578f9c1826e215dca856ee4bfb47ee2ba7c7ecf1dfbfd4d34b8dcacf007c5fff136a9c6c0c52bc4acf2bd48ab81be57d458436085f7874dff72662ffd7a12275b5edb14cee8be79496116a09db521346eb201fd15735f54c8fb03a545af870ca8366571737016cd69879385a95a700811b9662e560b71eb556075f6c851ad4e5ef09efe76188a6690bc4e906cf385325a195d362d42312247d54c7862b51eb51223f6704efe89f0778447d9bcb79272dad18fe77de3009f2eee3e0247ca944487e9975189b07895cee854537cece69963a7394a4e9d7964b1c7812eb8d885d72d066f5a57482c466a88064b80e239d317bb8d323318eb776a8aa64c432c0a8154b9ed518c7da60e8e2facb96ff83c652fc5603a408284a104a5f9a584a85189077a0bc807103c36c7fbd2abaa970444ad41969a55848352286e42b4ab979cf59b5a2f00cd7391c07c5deaa728d6e62f7b3b4a0febec155f8c7da6628d6dabc0d7bc68177f921a945414a753c7b88f73671da9bb95bd9a5ebfbdc6ea1f4feda15331b1cdd467f0cf7aa6a0828dcb20802343bfa93313380de74339dd100cdf5cc7a1046d457a63f65256f31fd7be49af2a2f1c94a28cb49fbb34f0a8cdf2f9e343ab20d6fc0773fde35b7a7f1ffa7a44414c401254b5da62adda12c08bdd48c924a8bf0e5d6ffb981dd1f82f10ce36208aeea7dbe494ed540576f49357ccc07912ca8cb67a2344e3c8f45eaa0d153f52958eaff8c502ba81c533d8f54f89b2c8bab96ed0397bbdea6ac3a03ad6e3379d095d704efafb2b507f84ee0cf89587bda0536c073d0b71abba57881b40cc7d05154efa2f42bac7544e554c41dbc25a13ee2c61d1172e90d900302e0412ac8af5bfb89913ee763842ccfce4e75d10115f280eda3167a1f1c377d6d21e291587a3f4fbaf99d985fa2884f74013cf2b52fe25d2f34e111f10cfeb17ee97bee7ec337ef00590826ed1ab067fc264e2b2cb5b847064e25e0b917b9dd5ed3884522ce6f548a0ad9b0000305647e3573c597c1feb1c1be6dbe09234753df588dae8dc152fef226901825aa5989447b43185d216f97528745d9542977042bb97e7c3c1e3600f5b7a2d67fdbfd851b604866e0363768b2b8a3eccd32811b3ba19a5de8ff6d469ce01d431c82f6b1ce252ec64c5c8829dd2fa353cc37452ccaf71f45b558c119dba5a22e84ec8d2fdf5c23480ba9218b799e2218d5e1b5763ee4786bbb5cc6b8adca3d40abdbd3bd7a950331600f79cd71c8dbe8eb1805ca9008c61bd771154788c4e0e407759db825dcc93a2f691a8621acef40033568d5eb12745fc30c8394fe1063848802dd4c7ae585c58b678980a12809697a55fe3e58d75b213fdcd43644002fceb9669c11444f74ef8a55369d0299cc2d5da14416519b0be36a15863dcaebe1a233d8b81c18c74efb652c84344feaf964617e3a95e2a87278867a55356872312ebf73ef4dbafae206e433f107127977f6f311f600c47c4eb70808d822250c7a89492b912a0b8cf8154cdd9f1eea0c080f04282b37a12b32ba0f685d84e3f4597c30fb0a18f79f34234ed3955ea1599bd8776e35de1a814fc68b8b10a898b48d0851f66754d0e61b8d1e220dd50ca0882dea0eed2449871c2147f36ee4380c1912c3c40f5a1c2d8c951f54377a01751e1ee2dc8e847ea1ada4fef10c6c5fd7d0879b1f19ad1c83674b488dd350c4eb626db66e40343bd2eaccd2def12a2c16793c2172ae89ca30555d34ea73683f89e6b8e11cb0738b77081aaaefb9b9b2080e7700de29a11edc66f18740cf482db816485b14769c4bc73e7b9a6bcc568084c55d794ee113bdb0f613b0613ba961492daa0b47ad202049184c230a2ff8439418e5dd25887c1577a5024b09ac13a3c88fe7ff47c4ad537ac8df87185ff630df4f56161c7fd4c50bee6437a3bec0a9065dab22693b28f45d4ce76baf98daf9031eb79e7bbb0ec563875d4cc2f886ac388ee5887f6e0a85e6570e94178754548b924e076be52d83091a945476870d436f23a687b80d270908ae14afe7e6211149be07c4cf21809ec96996ecfe473726ad2a2646be4e371ddedbec2cb743a43a3230964fb8d34209c2b75294c7ef279cc5e1cdfd0e189f59f49618634f8ce798d72905bfffbb1ffdd0ae93d2f1affe34ec6da8a4d691eff1bdd0636960f46eb38d5710ff773e098cf0a5c31be100527088881f00c4a51c87847075c97c74815c97bbd41a6dd4039891e8a2f66532957d7eb88eda41c622b74b42703e1652ae120a28ab64c5ec104fe136a322fada09bce61048c4625ecb61b140c70415c6f2d56ef5cbe506a0aae9a5d3e62964b3d15bc522f5924d43f3451ab1c72c804aee00b1e70bfa089d939def7d3d95aff5edead90535bebfe88a9294779882c60841e216e6223abf4250e086e3f1b34a720959e94f6745261b89403042090560aab2c325791c110c1c3abfe45fa0e8822161847041c01dd9908607d918364d36ad7dc8711909f9342ac66089d9009e8275d0e8e89ffcef710447321504b0f54901d86f0151c177b9a747346c9940820a89783caac8cbb0e4bd14620bf3d5173b5f9780b0801cb2332c2428cabac027c8f4b287901b33e288045d47e20c2be90cd72563b096386248a497a5c865c66467830c596a07df10a93bf14860038a61832341d72d98764c7a3fbebfc340f57c128256e6b55399ce8272c1b718fc6380479b4cb15bf1190c142d9922a1b077a9adc59b75867e95ed048bd900c54bc1affd4e9633c9d429cef1da0f0bdb707be21d4c8443973e1467f810a1eb6fe0066be652d8211e0af53cddff5fb61dab65ba948407b5080bc8241ba0785919358c915b172090b93e91bcba377d72370adb89781e1b291faaf6e4064cb5263d3a833ff1dbca61dcafe231fb42d4c88434e5a589e4fcb9779cbe642cff2c3d263affc9e4888beed23bd700a4aa04ce7a39e739e8a2d5e86a02144d585f5f71c5d8aecf9fd46f53cd72e338eaade0eb219fcf9c0154d161297d5409961d5db746429e3bf8b8e0b63a329e0f929712d4a64038de7f275b3e268e4b524353a5314228f40686334b84207e52041629e27b22fe84b25da0f14c7244c2d8b48088da8c800119541291997789f266732884a821cb2a9c8edf1e21ec4ee5769ece9a6f1c2b7ce757d06396985fcad37fe37c2414f9acdcce4593143e5c1b8cff8eeb31ed41335cc8e0b0ac653274b3617e8843da69c6078978e702c773ac8e19647e4e6fa7875745d3465a35615e19af792f965d87d01589d5ce823745443ecf1e55ca00b8b6bbf0acf70e3559a57b150255d86393bda933f08b34033db2b844acf67d54a38187ce3c634883b638db2528a7e3cf46c4f3fadc1638a182b2dad2b55802d33a952b06488cba2cc49b2531f016d8ec60014e346d36a0c50b059106dc81ae724d199e602ba0da95b44d304173e30ea24e02757cfa094ba25a441c2520832ba7697774b593ef17e57cdf3b11fb803de2eec315204ef46d39a6f5880a45a16779afe37e4faf284cb88238ac1172dd69c681983e7a6fa6c107dc6f4a1cc8cd88c66743a5324416fd6accd33fc2cafabfaecb88d3d58c89b76915fadc8199487768cbb4859595d9658b9a05c67743f6c54a175915f65a849870b076d1db0586a94fcaa0d5eed3701b56ba766562415964a36b96920272b7efeae04d6504e5c107cc1cfe5b2f54503e7bb181ca29cdfe68325c7a16ce4a9f3201fd5f3677ac576fbf61c85fbde3dab389b4f1286bade2754ba246f8cf5eb9c21dfc1542dc105608ddc5f5593fb6823cb13132e4639b548e95047a22ed0c2c5ffb0fa735df453453f85cf3dd0060b9c37ec814d00e9bd9e0a69c667b2b6101c3ff7719d0be3e5e63f2380f666a6b1604be23948782c82f787f04a795886ca1ceb620f63ac92774203ae77262574ea85a0f047e803412b7441a852399a6376b4af9c759a87d4490816d92876f3472966ed2f63d8aa850cf9c0f49d245ef410a12ecddd44d6160e99302d3b46bfd8136e82ed6bb2f35d2937c588b4b1ea8c58bd69246a1543a8e59547d2f01b8959498b740dc882d09471c3603eb3b863c85f66b07c73b39dbc20e1c2c3f3ea4db5d60eba99e7ac1bf4c3ee648dc5854427f4f40aab3a42dd19ffc2355bc62e204d08dfe607f767653f61fe7d7ec55fb0f9c4155ddb716f3b8866718ee44101207ba7c7bcf7a7fb34309f209488e6c0d84a32bb04d03a7f90686adcca6adfb8139a7d845cb1a3cad332c21dc3200535b437422d8d20951267f011f3f744f575c4bd6edd2b3e987025c11e427d780a119ec1270148226ae7de749c41a0e84769cb6b81773117c6c7fb98ba4deeaa001d04a05a1041ae795650a0120abb3a27060d41b6c51c3f3e699ca5e9461b22bd4cd9d404781819e4774a4202e7c83572df486b4304e9b9ca6f8ae9125e70b213fe79a3ef6fbf151461571b79add16ed0484f4a2a860643716288dfca4f9b7f31a5ad41e573a271e124df3eaf0471cddde07c5a13e874417502c278ccc63d22e60a0b1d8c4d03c6ae59ca225278567808c8ba324b964e77a5bd01b0b4b329f8a104b18c902e3494c52d186f0b6dcbf26ddbc35083338c895c9c7e38745536e524403269079e7d768f4ce2da59119a98c5a8065d3847ecfcb769c65eef17d6ffbd2c9e4d48f152532cca742b33450b5f46651f2e05037873eb08125e29e4d12cb299f849e8095a352323e3fae036b3d16983232ee85d85c314497ffb4a625a00b2e26b6e22b221c3e5a4d1d45d5225a634d34a15a960031bcecb7e035bab1533fbf755d00b0e298839222641b3e0acd26f52d5c3b70f377542d578faef4f0d36036f56d3c12a8cb398c091bcf81c5ddb9740bf34add0f936ae4cbfb5a87f288034755c56fc63aeed91a7c748c24a95b9b2f74c09f5d37975fa030e19c6985d67f7b91e8f96d861bda38a546597518d3e9912302cd2e8c365a6ef8cc3e226acd057c5855e30ae0829766d590dc6504d19d41ec5c957c873f8de54a3068fdad7063b94d1f0ace17ade48130b0edc438bb9d7a9da0b493193618bd2cb17549d83d4424d8a7f90542588bfca023173543e584048d058f076e091da26df3e166af9145df3fb7a1b2f5389cd09e7e2c750400d23f74dd51b4e3598794881e60def79f6f9cb08ff2f35be2ad48fd609ceb7b2d343db15e9eef0b23b3c63ee29f9a264fb3103573df1a95354b9051993acc08c80e62f835075cc958e8fc1eb8a68afb5508bb07cb6bdc7e0b7736accb51e8b3fed81d84f0383359e38f5dd879d42096ba146b20e35c247c78d59eaa305db89662b55645deeb96b0e9368b3edb85761f667cdec5e413e130de1759acdd3ed695d1cbe02f045968ba37b91e59431f6661a2de217937a2cea617f1c11e2419b572ce40167fb387480457cdc8015556d636f885920223f891c4ced227561885e1b7291ba2ebcd608e7b22a40c942640da3ab41fac9c096d3d624d970d227a4807403a6427dd9a15bee91660be4fb0a29558b0921bfe940c6ba3af383d1567e826a20e4fde099572cf8c79a55a566fda13fdaaddb3b4623384f3dc9a6bccc225d6529c0e2b12eff805613c2b837e11ae1e4a1946811cd70b2bff2e116439ff8bea85ba390dea3352f8ad6fd531aa226d4f903306572f5f0f496bb62c9bde2cb1b4f3e6cab64295be4e44b01394fc552b5d3ff385317a7b8738782e7773f0c4cd3a0993610c2f577b63ce2a992dbed4f14ebb9ac0575641daa60073036b6c7eb4637c4887e2cb3dddf1536898077b107eea79e1cf0dbee5730beca6e1ef97598914411cd0c45eac0f8f595d9e7b8644567e875a4277405c5ecd79b06622bb106aec43d8fc8ac267867598db479a715157816fa00e9b1c636ca42da9339eb42bab4478760e82c514ee40f092194c54c7729ea01840388e4fc384db1c2b1a96592ab9c2a9df76adcd58997dc6b6a2b5bce2d6e2e2f2f6deb4c41081f7aea47702f1759cab870b5f4da39d3cf59c9e76551845b9713a85b070dbf742a6e680ed9184b74d6542d8ae1e3fb3013ebb5c491996de90a063877f8ef34beae835717762122947bafba2dcd69888638404d89d819943e48d45a1101bd08bd833475642d0ccefe2a9dbc5f0be419bf953ed527b4d9cff8820b2bc6f336a614166a28f5efbfb0a00d20d8f1053a2ec2b24a2b85c9a0bd1526731c96033cc968aa32848c0742f603424fc95da4a509ba8b565f56d1383fb5e44569191c0bdc9749c948fd09a8aecc4b155254d3e1180a439124f0bb2a76ec113a2702750b987a66fb290ce387b6dd0bc468e6a263e46a2f6fdc971fa33e50201f035876a59111c0feca9d1f848a2d6e10624fea4e403ea131410e0d8bf3aba6cc8cc603e53fa30dac4b31ab9efbec40b1a234cce7477cfaad188b491885279c541b771615f0d4307fd8a67546ab86d4c8ecc60356414c0b0f19ed624f7dd7bd2785d008349c25186ebded50d45944cca2d666dc5c432ed95db2b3ae2f099e67f679c1f8323ec4d90bbbc1ae7593e4fecfe10db7e9d57445a2f60756a35bbd27b444635b4f00ded169043ef06baf728dc67a1492b0ef58136a137aadd4c6203fbcb584cc6f391ef1ba9bea7388614c331054ca0444899f84ac8e423324c589eaba26bfb6ed63a0d73f279e1cc36003aa8b0686e9c689037d895276f10dfada010209e4be363d4ee7e659dfcc13719d2d95a2ed8ec9f6d7485821217c1a518a9d689393732ce2755459949dc981f6443179f45135b58593b4b71e30dfce7928dda22df267b7367be67ddfccb48a98f51e618dcd9eac7a3d14cd8c2cb81d6eaad8cc42b2c2c75ce35d6a986230ed369719659f92d4531573ced0f495fbf80aed44f6ac6bfcc2b74869fe8b236b52cf05d1810650f4e875ff2b08cb58afe6ab3f586276be1a8e1c68f72277f1374d153c8eb7e7e1e97ef044f334f70129c6ab1d9bf64bf515599a4af2598b814ba48cf97b37154fb519c13b45037dfc5509e46cf78663ffbc9884ab688567191db8d4925daa9b39ef201d2e7714407cea2a0a6fe063c93e8e5a84a487771cc13a25de1f513e8b4334544b5e3aa8ce441aa82c2b75c7b6da52bba4056b65e3de6038afbcbe43519211efefebd2b53aafbca949b43b43030a3dd92250bdddff27b40168b0825341bec009b24bb9a5e7f5fb3b98bbf7c60e52869781c9a90b268477a90c1f682f245d8cff09aa8aa7209129b517572ed29d5d61d0bc474fc418430d098f86838c8401415e516322cc17702ce43f47cb74255db8ccd62f7e3538dbfe0e981cb529aa480b84bf71e2708a7054ff7d9c7afabb12b3e76a5ad067f1b0de31d1c6f5e8705ed25064243401352df977b19cb3784de9110d37dfb9156ece8ec892d4400711045e284811aa536db782d462501bc65539091284f0dd69de26538a846d6e82aeb8f567347de9942ca262ddf5f460dd4f8992f43fee8752e336ff95216f2e9232a6ec295d103876c9fbe8fd15ba16f574aaffa87e72d56afa02d5e32260c8b750335c68da30c8d4ca6f9633aadb617dff0286a2e51e581e3e2e226494c89ef4a7b5115594a3d31714e8906d5d0dd281daebab8157df39c7b30cd9380fc764eb3579a889d230ec8ae6473752ac7fe0e19cbbfee0f7841894db7adfa1369a1c8cdaacdb45a4810e677d781ae647f409cf49b11c8c7f178ed0c7d168a8434b6096d5cccf5050691010e093dee02af6ca962013167f56d415937579eadc25fc920558d890a51cb1e7fae5623e5d889efee7859069677fb9a1f0a5e640b62841d397bd06ed46ce54578f8b079042191a4dd77044947dc279fceb9bbc403917bdb596e9f80e77a832ea3a83638e098e241fc05aaf9a64c74c900d3eac83e09117d9c7baed7ad4f1af2aa004bb3976941b775f7c2d03c0464b3b68a0c75a4f04163f7776a125323c3ae6a81ec37284b91afe711b9af41988e5819282a434ee7a7e2e4947b7298b269397c344aac8565656c236fe62d7637eb34cef5a10f405fcd50ace068f671c039c1f5384156eb8b17fe8f2da899ba3fb39b8e8615dffc30a75ff8a7f748f4202af28a38a301bccea5f6c4d57b374999fe261d462f3713378ec1ca468ec6ee0592424ae489a280fa51f83d264f4b9e511de71b1002b06249dc461418a62bfd99921578378a37256cc2848ffad4920b5b8fbe93a9c4b90d50eb6aebecb4abaf4829a6a35093e8d95539fcbbe3c8b48979477c70d0f879995686d18c81acc1a3634c01768d02f82741c2e1ac32b23c5a59469586a1f4ad072a794d7454a37c3c4322e6966954b7b3612c7e8fbad50196d4928e0f787940fcb47ee92234b4e5a6022197810a1749c245b63673d1230de8b5cd4a253de5469fd1ce8422cfa982c9ca7684d37abc498801488f9561208b6c1ca4b234abc54124d0d4a1b7f9a9ab8fc0d031d036dc7160e5a62abe6b6f091e0433a5983fea47fd5814f2ed8b45dfd325a942c18425e3716be38a7272d2823737d3f9bd88ab2fb73f59510c8916297e2aa3da25435dd24cf24270c3f29007d81739908e232204948133821dbbd9fc52ebe925a12cabad732a90fe173837fab0df159f6c0c5eb2c46db6ff34c56f843aec9a5ca9f3d68577c4cebf4ef85735b5270bbea0fcefe97ec5c9a3623bc278f52f41c255d2b97f93168077b6523c38ae99bfe94b3d2edc9168b4e741ee8bce62bffc6eb667c23888ae9f076d0846ee35418eb58ce3841a328ec725bf4340df4d3c735eab1415477570206fc7ac982b75e83f1719863926ca4b77921e77f4a54d01718d550654545f83e3c5803e6a30f67e28652fc07b566897ac4ff789af19a703755c63f60de953ab5d34ecc5cab9657ce897ca8482d11be5072d605a04cfa73fadce0066152d62c338e7cd04f6d62a1ab859c5b3b610a42a7fa27f0de92b10cc94dbbdaa1960e23a7aefa9d290cd4074df9b1e1b10b990a8e8b4be5435f7801c60df2c54261437d390ac5015fb1dc88a45a393d211c3a265938ab114b50c12b44ac6738fa53055bc8fda920dae15e455b8363c42a0b7eabec3b1abbefbc475eb57c375aa07850214d6e154fea826d51685b4fbdd688875a0d071640c8a963facee6bec8866a089f6c625384e65f48d9294240f21ddcc365237bcba1299a40124694ead7c2f7de68c0ebcc8aa392df66f330ac2658c6e41091c789915f935ab2e1987605ec64af1e38887a1e0bb25943bd57f099233a4b963c7f15389ed8e6fe93a0c340e35420e2bdc0181ee7228780749d25eb96952e8081eedd08b472cd95dd99dd94ce3da35402f7fdff75a8d596c275a0f6f8185877c2733a60e3b2f96db72564624bae4c90e7b0ce08250d544bd58b7cae04af17d1cb7e59f5c8ffdcc457281ceadfe98c63074cdeba5c436e55c51680bf7e450edde41a1a3ba7b655c046da85c1727dd362d9881b24134de9aab1102e86acdd36f8e5086feb8f8ca0f222bcb231a010b2679a16050cce6702fbf5c096df14b6491ca007151b5f5235241753192b36bd9fd5bab5c8ba48e02f2b68b9b23cf28d584390159ea6334aa08acdaf503311bdfd3da309245a6387597c1480590923f70ae6b8db420c0a062e0e31eed37476becc87a64b7acd5d70b2fc0b42f2a3d012446ed1f586c5a654c0fdbaaaa2c5be129c6ce6f7fddf7f904243232a87ac948abd00f2df1afa28b76e1dd755572d2982bbb9cd9cf6593c0afb9e94986a93f067fe301dbbda8574dace5e8f5d1080f32d295a4945d12f8c89394e2f8d717e560fc54fccdd306086f01f8d96dd144cff175f6131a8ec8c76e08212dc9d0264264c401317105fb3e81a50c6817941f6c0191ac62c4c07162959a01cfe89c0edcf2e2b7f2669adb990e1b5e6d43b7af959319d12dd4a9bb45f200e35295e7bb410e28eada54e8a5aa229c143fb83cd6f5336156378312e6db6aa1dd8e21b0bcc6220bd73054ac1b45b59137ef259f0614160ebf5993db2be5814cc716710d49813204a7d78c6370dfc2816f8d50f1e6e8b7d01b27635cf2f0e5996957e2f1038a29618f6ab1f784220694b1dcc017c2f03cdaa5fecca9ccde22f2f7068bd373d3f812ecedb6370b3ed06322f2f09c560f2d455801c00135c8f8259afe365548cd4bf0e5a8d655dabaf90deda8ba460df111dedbe6e32f8cd1cbfb08246aaaea3cf09f9f18a82adf9295c7f47c601624382fff9b371412047f06ccb532c0884b7bfcbfad752bb27016850bdcc66091c8a4d681b84e796a5a9a339e37109311685d2f73f321383e2fe7fd3aa5434b4afb882c9095578f9a7a61a3f76a8be54b6567181634fc1aed9fdbda8d42f762ea2362851cef7eb28202ea0a54484228a877109b6a8da62cae4521a9f3d1a058b7b276ec36059cbc0ab4bb3ff12baad82830354b97d4b082cb3ba71df39281943109f3b95757121ebbd78f841746d71e1e681c8ae3bb0180dadd3f9f909a216c0e159ad600670d08ef7d3289370030635fc723c1710f0dbbff40528c4961f1b07c385bf00c058ba584b2d43d235834ad1a2abfd72db77d2344b33f01c465f5c1f155f29edeb0af85db000e02bb1d9479e34cfe1d8e380d6211a11a8eaee9e7bd77ae7902514e56e58ba852505b0ecd45447023d6a1415dab52d57eba4349e3fcca19d1686d6a483487692733184b96354945df4b73383cd140241e6d2c170de21ac89500feeb80cf556bfa0f7971cb13f9935892206ff31ad18435daa5f3e64df8aaaaed30c4572fa281b99b6ca2c3bdfaa0dffb36e18403c1316215d54b243426287cfe268d6fa22e7cdcec6aadd94449657e1d18f245fd2042c1d10fd1f16d27a9b00250521b569e66c2ac6dcaf5d0988632bd5e203e3f047c2eeacb25423a5aae8fa4ddad06134b126f1eafa2111564e220ce1433c96b75ed99955b6bfa20cb8e4a4b491a48bf72d7ba0fc380dd9c839cbd82bb4d4c4eb9aece98d979eb765f03a13bee3b3b90868e9e64cdbadfe46757719a21b0a8b8123a45825b0c5ea0e09ce7aab2d0ee46d140ab50169701997806934efc494e65d33c0c3a8413dcb4d2dab4f21d5282f38896d2692f66a4c273a14c37131f7235f72b0eab04e25e7223880e980917b89b5cdbbed060c927da241112f95a1255804f62397263594d51869064cca13cab795569fe7d12c96c860ff7e24d02dd0b5278340193d5d9e69e67db8d1acf4d717a5399ddfbb110645d9e01417dc21a903c3eab56d15f75384d7c6d2578e5cc9fe263c5a00bb72d9929eef7e1ba9f494d852b58b740db72450ab79eba58795ec113b0b3a1b7778ea4c1becfd1b37782f8fcb620484d3fd244fdd24a4302dca13164b2aa95692912ab054a29d4c79a1343403498f03e19a0de6972e389a6cde8183296ca45b2f36392678b2a0f276413405e1fe199bc8396adcce57ac87bf154577822f7969f8fa36bf0b9a6b5f8c490b164e0d79243fc2d814a2d31133d727c39d1f49703b8d0afb6c44af50f2ab5d68c04f9c2c0c1a797d2badd558c8af5b51106cd03bd1b41f3a6cc15f4bc80c4761b72bc089e567fe667d9f174a2a0cc98463ca0475263e25948156eae70521f05792603021d62c0398be5ee63b62691a90630b77a3d05d7f6b4ee8d4aa280e76746b877edb493e65f6aa76271487edc366f74b415896c9a13d1b9b05523ebfbcc4c981610603ca0f7a9f0d48362f00482b0918ebda9ecd2e587968e3c2e804d182457ac2d07080ccaff1f4202c4c67551de00d761974e443c658c49a9a3d55014a0348bacc8c01bd52ffdadad37bbfd4288e6972e305cb4d37756cd9b6b9819b5272cc8e82b62668e070f139783c9f0da70737eb25ccec999f1490b6169b44532d5edb330457fd819a7f184830888bb1c7c979f8045bcd4d040c7b5a26e75c2eeca4f57f46a7b829449027eea3324fa9025ac95dced8146dd84550e08725ac58ff29130cd867374265e0cb90bdea8a49020a02f351496439c62e300d3060a253b2b3910504cc5e521aafd6965cc0b1b31a6a215bf334a88b55ca503395d3bc06eced56a43c0891d2e90536af031c1d0a9aa1349fa35c8efaa37b0165d36169acc99202b5b5dab0f658f167f98ab380f50a8097c95b11df42dd113797208cca4e78309197ed8cb2cb3e4c968757a244cdce34329e753581e38b9ad3e2af594b7dffd813ae8e638fc0a88da61938b9ffc704e05cb6609dbcf28f8391a144a9cc163034afcd216264bea2b3de8667515aee083710d16e7e3d1765b41ee4e24035bd38d7369793f1d64ef9a5213f89d1724484c3186375e0a8aa7927d638ac2c05829f6824610db764353fe7c907bd55bc4e474873b2f49a0c7d7f31eddb5a58fcc381cc2265eccfaa4978ae5b26bf9c116c4a822b116b91b71c62f3db478db932169aea2cd67a311ef885979c468e70ac90afd08a14ba80863b428d326aa1894bda86d60748ecc216b6f11d27df0f3f7665c4ecc0a2778f0534993da61b329783e4976f33ed82f51c958c7246a5a0acefb52458df822ab7bd65dacde9b69ceb97f018075b953b21d20722a85f10ded2a88ec59d9d987f57c4be7d5ab4dbada96ae63981262474bc1013b83c447d6942d217d01760a4668f329a17173a1308fc4b33b8c3fc69880d04cbfbcb5293f8bdf41723c3fabaa3ac80257c1e671b54305f3d770bcb842fd65ab33c35bed4b6099c644a9d402fad02103d3b5127d074f0147556970a3f830290628f2ce76d111590720a92da39088d5297545f5554b1e7e14661f999a3b4b5d4a93482f1c4cfb9f7992fb54a20697024d059e7224c494e835ec032c45d0e09817061585738bc666d2b80e5d350aa9c19f12e3746ac78ba84925cef0a7d7f9b8b100c6c99e2085e565419ebe0fa23cbe8f45ec7252c1406a82ed88fac7beda0f484cb817868b3f4bd7fd154f221a6f1da49275dd0e2fe0da88a9cd7c28ac4f79c800c85188d105de0048fdf42ecf65648de27329b4017b0d21f506dc1b3072079b7d58488115caa9dacc9c03346978ea8b130ff3e91191c175eeea5eed83c6573a52fe74bfb98574339ab80c4734179636f3d7cd6f18970bf41b8d891e777cc3d6a748be928ed386f270067701bf50fc4dabc65905ffcf49fda692527181a90bbc9630aa97d867ec04dbb7f6f45199563366d85c4af914f6d70077e6e3972e8c8636163f0b51797eccdf115a0a4b9d166798dd9cded2ddbbae53f5a0e7957ba35cae533540098a66041dd08254e919007a1a5d3cac004419944cfa94b0bc00dc9baf140ae73e5d8a9b2bd6ad70dd1616bdee7252168c62337f5c5f42193bdaf3bd9d397b98e2f49b3437990634f8344d551222d0b64694642ad8bccd754d292d0601c66220c9344ea6171711ce4349820be427b58521c8fdd1ae60843e2eeb97f55919902cafae3a332219e22b5115bcacfdf790eef0707b498fe83bdada328a6eea2dc6eb626a839974c02af2661555c553cea701465b41211ac55c57feb43a0aeb0c7e16363a3b21597d8ce7fa7909f3b13d3cf422959c80ff7e8d3613541087eb9a05ab668bc6cbcbdf6b99d283214b56a2f3c5c43117fd25b19737a4a673d7950893ae11f6a0aa4500a05333b9b68899b835a830f84b558a27940bb5f61efa2b4917b4f8d5e0174f994948d35ec23b0fbee5f3648cafec35160054ff812a94c0a659edcd497382b62422140c9f5e9459ce481649dd40bcc0a70a08d79b7420e9236af2a886a8f8be3230bd9e97529bb5b5f7da4c1c1a516a3b246bb6739b78adef3175b4d6bf02cd356d34a15159c834f023227045227b2fc2d40ef333ce0ff182d9ea7b227d3798ca658e8f42f9272977d7aefa9bc163c1c303341c0598e969d723e4693cf568e23d5d881beebcad49a53657745ca0bbfd8eabe0eb46acf198bd2572e103a4221b42774f6c0457c736998391ec9e52efe143b99c70c931881d62db3e9f4b2e06cce1fb32a8230812caba8654a321f29df60b35bff1786cfc0cec5fbef633702e8ff5b4014633ecd972d8438f43fa037288fe57e6e294cc625b20f946da6df7c6bfc707b633c35cb00e8dd34db71220caf55b35225588583a41237fb539d372977a095af4b92883589aa402b2528285f9d61b87e0c2a838b5ed630115130b38bea72504cd641c69310399d688993a6395b9d8221931139183b4509af1c50dab195f3ab56277efc34fdd8d93145e4a6e2ee7b6067134f5c6d4003f6c25a7da067e1469a090b6aca3d52a588dfdb19e879009cb807704729880d3f97d98ee06635c852dcb330b65eb4efe21e291723f727dbc3d88b0bd00831064741d822a6e9de9d67af25b433b75864cbe863090fa6709527d1446808834577f47190d6db58369b7d674f28d72a7f09816db0764085f5f4203b902363654526260b772c4464759a6223452a657c633210773f1bcaa6183e6ba1e6b772933ca8c55937932cd5035e0b99ac125b029e8bdfb9078712c47548b7e0c680890a48660b5521f2c73636888d32c00bc27b6220e6126577b20084160aba8cfde274ccee8b6734c69f9dce7411d1282676f6304addd4a463b1386740f398b703f670a0d7929efed77607006e585b02591d92ee779d09929a5e19aa7271804ba06d3b904859ccd63c46d8212ab1a5307c92cf22c90d3bee3fe72ef1153206fb3f6006f92488dc287e8085f69298d4cbccb4255b6a6ea259c5d047605a7d9ab20514035b2e85258e9cbae911ee1201462fcf955fdf69c8d6aaa3ffe40c751124d9bc574f3ab902638320a8df39ac80792c72968a63a8d8491314a1a8b26ad623202c71848c9c63fd3a814d585bd2104950cc60a819f203cab8112c606042c8dee288ec6b5b0ec612cf311b1bdb1c3c928859db6046372206e8b708fcc3ed1e711aecaca0b616a5d528bb3b379c725b0954ea5d5b688287547f967e5217a93d971b26cc0c0cd867c30766773b9d5d950efc33a3163ca26b35f13392d7ac78794c44cceff72176901381948ceb9d5644aebaa797dc0d1bc33915cc61d051a6b7d286db8a6c6a09b0e15fc6b0d335022993444535c02dfb0d833c98832c9e1ed421785abcc57a50278dbbe08f16176d7a06dead2ecba8f1a65d0c63cf5588fd791e97f55fdfa359e9f98a321ea087b32b186e48c305cd10588171b40357a5970492c907b4889462d74b88dbab98fb402f80960a08d071853f40f2656f54bf1f0678ca8e170e9223016467865d18ed2d9f3d4501a5810f9e02cd50197d2207957d4478fd117f64f7cd053eee52ffbe349af44cd8f4fd877dbe405f9d8802351cd03aa3b5c84c69e84cf6af49f55bcd617b67814671257dfb8c452f43dc68a12a3513bd6ecd335a9ff4daa9706b94c4b3d973cc198ab9aabf8cc5bd79a180599c2df30749a46aa5a8f3ee1b679f2a81c2bfbf0809e17101c34eb68c61ac3dd652f09f88748a32972b4451c416bdafb71b6d504c86f00bf007b062b165008e8c952d0f13226381d9880629374642465b27495ffddfbccc483845b3e9188fc392a2564650f91c49ad3b188cd5cf919e35a60d42a5010ae8aae635ace6ed8bee758ba800f47c693083a93ceae866a6213e25d525e448317dbd2dbdc68a13eee1ae8cb5b14e8cb04f1e0df0d0085c0036ceb1ebafeed606fa02598fd717541389c0c7076bc5611f1275fbe1e1e674ea1e9b66b246b691c9a2464fc1be7b17a1f6d0e6c6f1e3b525b47459f061336ee5e82c5b90ab1836ab550d5dcf708042249659d924c787cb0fdcc25b9510e2adffe737c3b835ff55d31feb3a3f849e953c55cc294196398ef62f7be63a7f358cd6e8ea194c7329d8c5449e6cd4cd5360dc8196de3dca70f0c4359384551c98a58b39f7d5cd922ea7113b0471842e7a84550ce6a7f12a0cf901f8ab1e311d71c30f1e7a2eff0ce29efd5bbcd447a89b5397dafaf133d1a8e0be1c719c2e874c35b2238f31b2e4d9d3fc5e4e71c7bb69060bfeec170a376111a0280bfd4c616e39f03aed46fb260d0b5e4eed3522069188ed2ff07cb97fe8e88cf59a85677332d9b3b3c651f46c72550ef4bb82e775ff4e2ad9273952adb1ac868c2de9014469b1624c9e29cb94e347a2439651ab635ee71780af7831efe155f17b95573717ee510590d56355a16ec0e705f88d8c4ea4d3174984ff24a9a78d3d094d2646524e8817d0e223f4dd3c6f919047ec728c3b4df5df610c3d2d765a6987b14ca83f5c424deacf91ef4e5d4b80dc9cc4daab9de8b225145eea6baa1fc4c85ab21ec2b698818f4cb03e2689bf98c82d4ee87f47c1c889904221422d678d6a8f2255225e3bd3f3ca04b2ae1d9afdc8dfb075606bb98ad117d866d797c5d00abe213be8892c36fbec6087289602e976d86111b3654ff3ff90d7c6f399b860919a88539eb4ccfe7d2a33f7637f79da259e04c525d11f4b7ff847d1cc2b5b0645685eabf0f891e9dd71823fb8316f190303f96fa8ca8f186466d07c12015149cd9e78c74410cf581c1da63505d5bb13ed6ba5e094b2226252e36510cf8e3ed59160bcc9045f77e1506fccf8166b15ee71c5466cdf14c2be70a5a6a10fad6821e767a57b21bd6dbc6646013c6a712f41572c8e0d5e2139a2d404b3b53d7c3805d2df8082203fbc8dc6689f656060d64d45bf35202fcf92d3a87e20eb2d87b7e80a29bf6ebdfe60de2e9735527a762a3426ba25882fb5f376dd52ea97bddfb2fb4ad4376f395409ba6f0bb62ffbdf45bd8cdedcdf5e79cb5b357ccd4bb58cfdbe2ec798f883c9de72bc45c01f688b203adb2e8ad3545f8ac32f88b1d22fcbc31f89e5d3a98beb329bbdecf79b4d704fbe1e2fb334e37949d063e9fa7c699227f6edb52a2bcd09203c6b7f8ed4a32710efe4414579876c89e24d6c8035b0b92c2b2f96286a144e3cee7f10c23de64d70ad4721e660785cf14b4644dca41d7e11beef3a12bd84046e942b1a34c4659d41a9da18eeea5eea04b821517d3036f8df33d8b60f9b4c5857557afa0c73264b7d25be5f422dd99d683ec8c6ca904368652d1b92588fe0ebe5d806d47efb25be8940bd7b8c16458e952018d9ce17ba71a908c5a3bc9a544b6e104899585f1405917f4b633b2a59d17f40a3384947a75d68907dec98d2494267db60ab9c0460939721381bc6fe968dff8156e48be505aeff7ef1e51a001704fb3fb2b90ce223c701efe5b56879103866042ab4cc7c56dd45c4e89d0c91fe93b80cf170ba9f394f380d717ace1dddc67abcd8f63734905da68f69e82336f6782af1b92098cce94c8509191a8ab99d61d29004090d21e1b9aafa46d5014d134bfe72c7567cb16f70c70974a9020ae2996456204a62950ed39ad3d17f97d649564acd46eb9b4c4e4789b5c7541ade90175db26ca152d9207d2ff4e656f1770d1c68284db7659c525cb7a2624a648ff5293ad41e1c66c122b33d793b6cd25bfb846c42f6de52269952ce052306ab066f1bdff64d8b1a473a6fb6d1026bfb0a460a2cdfd1f2b5b67429f7dd091aa74103cbbb0c3020a1741e801082085096773ad26cc9f9626206c601e9d68c79cbc1079e51c3819d6a8e347bb8fc33066eda3dffacc24dbae79f3470d37dfe99859d3c78fe09433f1df18cc2332278fed9843578fe69359b3078fe69643665f0fc33c974aaf1dc017ec23961879d725b21f3f79ed9b4c1f377d86ce2e0f91b10cf90e0f9bb8b9b583c7fc3e126089ebf87e0a6079ebfe9b09354d96cccb09354eccbdec24f365a697e6bb9fc6d85fb0b3b75f0fccd0337a978fed6819b563c7fdfc04d43cfdf4cb85be07ec24d52d889067f5f750a97bf8bb0138e1925ebb9fc23e4e0260bccdbe4a70037053d7f05b889f6fc2430153b45758917eacbf01a3d17fd53001e6ad2a236f8498b22a29134967d93de3f34b2173c69953e24b2e46f608d9e03cbf421d1332d6a83675a14d1eba611f90f58a697b2535fb3f44290e360165af25558a6efc04efd0abf46ef523664b10f7d96c2922f64999e869d7a715ea39f371c007ee453cbf45176ea6996a8465fa3ef6b547b1c3d3cb053bfb3e45fcbf411d8bebada514d034b7e0696e96bd8a997c0f6c5c0dedca9bf705f385c915d7a281be39f2cd307c04e79c9e0b0feaa223fa445f1d8d181eed2f7006f8c0f6953e07df12d9b1d0b7af1463401ece84017c6bf78a64525bd8cb1bda6d6e4d24fdea495e6e3c672ce0fa7ac6b61a41af8367fc9ba15eb32f06dc93a1586319fc9ba8bf72aac3447c7d2208963c5f09aed937aa55e25ad63d11848ef57b4c69f583dfee7588e15c33a3d936d7a6fd24fee8495a63fe1db7c77f2e496b34bd72d1d0ba4d1a077e9c325ebb52a8615af052fb9647fcad22e8eb4044e1c53ad562d19d52a0e7dd66465fc929dd7b11cf72579b3cf5e332ac1522c6bf7677cf9f79ff91f009fb33300909311d6e46df1b8b1246fb7c5338de5adc5c718cb6ff14b6359331ac3c8b1041b0c83b94bb6e7acb325cbd729f74ecf2ce34b10f7a558d698befc185fde96be24ef04465fe6ee049fb374074bbbb4d2fc264b79e0dbfc294bbf60b5106f0bac168ef51ee64eb4cb943196a0ed7163295af0e458d6c8671acb8f3196b7a35f1a8d3c6c7689ac356f360bc8b182e7230a3e14a25d18c67cf0c5e8580c637e632959f22fb0460fc3be48b27c5f58be5196772e6ce9566eb6046db6142db065ad025bde8e6c495260cbdc1d6de93adcf9d6966f4be7baf327b0a5db70e7b7b0253573e925b27c25b07c23b07cf942c057caf2ee766079c757c8f2a561791764f9d25e3773b391837094928d361cd04f7ca32cef7af413c74670fc466f9c31bc40aa0de6edeb07180461fceab2bffb17fd09cacc397d9c72e6d3ecd94aadd43cb4424fc8600bc1a194524aa9f70945b0b5d87b7fcff2e7a214cf09389b98ba573d2794b2bb4f2f6a2895d25b75c6df0aff560c0d5def87aec7338631e7e5d9e44966b32946cfb040fff36afff859773690e96318863cea84ec4ebb5a6b5dfae0fa5b46b23b2a6a42cfae132a79097e7f5806d82b4c4727e46c36eb1e679592403009dba698408a3995bc577762efbc5dbb10816580cd12f26c72272b22bff3be7a2cc35fe6e3ce6f5aa78ce9466020649ec1b43b4a961f4453944d10aa97de91eba5a25d81908f5aa9ca647564ee27ee38e117f3d9b5ce1e2f6dcf84ead169e7939a58bb938efc2f3ad2aeba7f9390afa8805ac71e99aa76cb0985dc49a84241f38a3fffeca7a0569adfb4d92576503f318d61cca7d1780609211fed7ae759aebc6b1442da7cf3a6f22a8b351f42221ad3fdf912d1e8eb5da208f2e46ee35f5b504277efd69a2e256b0ad17c3a3e55b751e8f4515188fc09ae841506b16368559044ec39e79c258811fbe79c73f6ec5622acba1da389389f7b7cb30484cccf3dbb67fb122102ddb9df5337b1286e9e24fa0f0981f51ec089481f0479f4d3087f36b361dfb6e508b7a98dbdccf6a03736d23b6935be918e363ea87fa394fa0b211f51ae1cb2aebdcc8503961b72c81c868257582c908aaff55780c5a2001ba1c39cc1fcf3ef2b0f83661cb789b0810e123d6e38306577013f3328d1e22325871aa8aea0ccb9c3268928c050d935d3fa0cc82c66d3a823379f654d40af52efb2c6f58397ac1fb8cc28122177b94b9adc1ec95ad11f1181003e5f1bb36a177bd108b82392db816f04dcc562e18356c623c462cf44c42365a2e7ec6e724a9dc7bc3de6b5027a8c06ceb0027ee9fff173ec751eb39e2d2d70a9f75f8e1e13fc159769e00b3b88acd5c4cdedaa771222e6e0aa79598bc9d7ed1a5d45fb40f4412f655b525da64f3425f3673897bc2507ba2533b75233b596f75574a4fe3a12d9a85feca976543bfef0c806b1046b31fb5e44f0a3e08d58de2e910def49cd16ad9df754bbf9a39fbe9b73a415c450e8caf5c8a1bec584c953403fa6538aaab6ca6375db6b9695c7cc2dbb491e0ddcb2b122e8b2b1dce6d2d46b40b0319b846e7f085c60586ee7c13253e196ccc49eaf34bc01f4938f307a10ff36202fad4fcc1515ad1d0b4bba64eda625b9ec98c8b97367372d8fa1b36b732583d6aeadfce431b21be2041c273b2d2941c076e1379bb6e8c8ceed8f3e620a9f2d3b1320b8b363906380ba9c38b39bb668879d09b35b8ba474144a422c41fe67db7788e9d31875e608fedc12323751eaf369328fbe3d9a9d99c6a31749f3f5c3390b3dcbf7d5f298a2f7ab24d459b53c426f2a76fd777516dab6b3d1f3a6525caf968800b49ffd0dda2c8cd1ffacc299b59abd7bcf3be6a5efc1d7f94cd6d7a3b682b131f4e88fce32410f046b6d433abb6dcbbbefe78df2d87de0bbb5d153bcb9252240ecc1bf111b6ff023408cb883c3f8cea5da51ede667adbe17adc0470012e20e0ebb3d76cf4bf3e93fc8bbb2466b30f56466a77deddffcff9ffd3c8349224eb27867e9f72e917aa053affe8e0ee4592b6f69bef7aedae974f4313d90bbe7341014b3c4b2784f2d0f3a5e1b3d3623c52a3015bbf36f18c9b2237773dc2ed52ef6e18ed22af644b2ecc8dd1ebee4fdb42555e5ddb4a509b4c68afbcd1a048e02f841e9376951348b8f79bfef9b94099870aad2f61e469d3ca6280f6f8a52ea795e04e0b5d29ca2cdc37d843df3cba36f094e5a54d7b2561bbcc7598efaf4f22dab8312d0fb3dc8774707721f938235e6fd3cffdeefc7a3eff4310510ce9ba39fdfab0fe6a8ff793cfa965e5fcfeb27be6d7dccbba3015d4a549f6ff59ee6f0be7a95d63fee35c6c9ed831ff57ed395fa7bd4ee58691f9450a3fe1c4b3afb678f34a8ee833e4b6f01507ded49baaec674a5b0873621a3a66be71627c6852e5e80f056142f4f7c466d3bd9c344055b16204042d42e3d5e59de0f4aacb00b3f38566d762138a396b5bac0c4d93110586b54900911030b5058b0041e259498cda8fd613b0149d89f1d7db73fba063e3b1386a2ece8c8534629cea8e5343ea08064e79683f8b3130ad381268ad8b91d0ab3732b215f28bcfc996680a09d4f20e423719694fbdaa5a48acfab54885a6b05adec78eb0cdd12450038e536282afa6fc2c9d825259150339e282d084ae7010818a4108554ac18ca200411748cb0e701085868c0614cb618976906a5d1a080820ade662db0fd0c6bf44fd6c58c1b1294d57d9075f1d4da6824140656f729ac8b17b2b6172716af171958dd0f5917afc2da7ec50d0904776aaf10fa6962f17aa181d53d0bebe21fb0b687e086e4a5a39f2616af1700b0b6cf5917bf81d53989138b97f8a2a8c9da5e8675f13babc3d977a7f64aeaa789c5eb5f24dd9ec9227d0cebe2afd5fd08b3a9b792c0bc386c66fbd90de967e378f423055bb36966cd5bd2d85bedd54f9ea495e68b118a0beb5848f63d0a47d94677e2a47d52af46d433aa9f37b359e69b11fd01d2a6e835b2cd6c37fb310cdbbbb0a11092ed4156b2b1f024b6186deaafcd92efc22ebd27e927bf72265749986439a141efedc39bf5abb3cc4846344bbc0f5ea3b7bd91cde88dfe02a38761f44946466f33b26539cda2591ffccdceeb4efcbf5613c5129ce0822fc97f76174e9094dee8951c4c032725db042cc07cb9b63702a3b3bc9bb39bede937cb77c93adf6cafb31f23d99eb43db3924d88916ca2db5ee9cbdc055f9230bebc257df92fbeacb9f852bc2d909ed9c9c11c697e8b17c16953ef60b69fb6571a1dccf61780d91e0698ed93c06cff02ccf62ec06c8f34da8cde48776d6ff41fb0d6b519dd2cbd466f64f4b697d1a28cc2701c99618ca32d0ef6644ecc067176990b4e1b19e09c997989b2cb5c707ca87844ef32179c2e70b21814e118b9658d16115b63c411af0a5c33c491eaf5ade13a427761573c12f4814f1617247daaae24f193b5064a123e70aa8e5e9c81a058ab97b9de78ddf22f6d0e0a666e49062521c67cf8d088ce831263b8641943830d639e30f866cbf38aa6ad81946b6f9230b8e2d2cb5c6f8cdcb2a6c5c767a5559cf68cfac7aa839f571dac0e82ded75abd5a1dfc2a25ef6dc550ad88c55ad117a53872ffefa345f57b5bf08b52dcfe49b6e8afe0477322a41ecae6b4b2768f81eeb1af36eb9c734e0eca52299db47a9ddf7f55c730e6738751a65ca97fa7a035e7b6ddbd6848644ab5802018e3e67010f43c0b82a047c137c6665f2c4504fd854215d03eeff3fe46d60fb200e83d68bfd924ba8f2213f137e61cc9d6ea43b5327f8a07541431f3d003b3b2d61ab485d66e1ac38e486bade0e7d5aac7b02376999bb4d2b15677ea5f6badb5babb17faf1dcddbf5ae9dcf1e8488933a5c4c9437986e731c07e95c94babb1130e479a3992c4512b1d4bd103415a54f820ad8379aba7152b4a21d26ced4bc7bcf5981160a5f956bc95c3081af556af26dd6eb29f0cb05ee3b0bf73bb8303878e11e66de2c8008df7b229db2282629c155d6454b8b9320b02082d08314341009acdabeed277e6951b049c4b0b9f83502213d5b8e13263a8db74c101eb545deac585073442a14a132cd141e702d286cef5894516d64c1b6b0ed185444dd1d884bfcf2d1cc03645eefc294ae044d614288a0863626627d2254a582993864a9e15eaec1a6b9a915db10a42f9d6483da2b3b9e56c680d9e2b04179b325b4b8864df75aa6ed975aa6eec99524a29dd11f5818fbe5d356ffc443c9a373a54349bc09fcda65226938db7a7bf411b11ece6f764cc3296ddaeecdf9de6cb3e9400015c441de4cd01fef7b20f1903f17bf0fb4f06be77426540319b03b43129beb3ef80ef6c0c636309be0f99fd1efc2c306f1c76b9a29957dc5beee2ceefef6b67b43ad49d20ce2bfbeff94bf61fd79a24973ef8fe579f2d01fcbe84d898a5ac11e38ec046e818baf42550ef0e2b2588b15136b48b8d46ec64de560cc33ff6fe3a32e2ecc32ff90c83e12022806c6447fa461bb15137be23f958ea203fa0efa38fbef42be841f4befabafa82e2f55563692afe3cbb439434853bff06085ac492bf3ac9fb733b993ef6d5066dc4b2af2c30afc02e94c104c21394c5a5262c8bebcc912b2e3168c004c243b9d618a9009c179c84913264072c031033c49e3f2e64408827aa6688020eddfa53e62ac43a228c0c6cf0043182094d9416ba204981035cde65301dc052c1b8d2dcd9e2228304d7973b5c64b6b0787d147263613183588252a028d66a6537b9dd4ff47d9e982b1042c0d1e34c6bd1b9b2ac384bdc92bfe26c85950cc8abb5d6ca4de85595d75cac89b5f2c63b4a5555eb9682c145f4119744e42f67595e58df38410475467c645241fcef1b7edf0ccc0a1b6b3e8de6fd4c367addf3f2fc0efa50369b4473329a2cbe56144d11158820b76430345b75fad1ad4db568369537a8d904fea93ac8acdc92ddb8bbcb6851440408fa146f43e8c579fd6ff08ca25b5f049e1113af80583d1639b9d59b5eb5de60a4fad5eb7c6f4e2fca53547114c191ea8d79ab7d835ee8fb67fda6816015f4420f7a916f09ad30d740c0a3cde0440e579a314002f1c04ed409134506fef049020f58650f5694347ef064002b0a2b01a78a192d2f90d1a3c54fa5b2c1961402e960070a297bb85475a100848c0e390c11f6c91074c64d0e5bb2903c3942c88ed7135da6603df1339be200262880e1f0a6c91e265884a933a7093a4698e8128a810521a0104245037dc8905cdc6cad90652606377d82b08292d0b2c7881df28069594aa3440c94212a40d9e30295e200ac214d5439c205853132c450c44f9f27ea2ce11383a1024644f18705353fd861c2c50961d82c5981c90d6efa7851261a2e2d3a2079c326870288498189227a9ecc691342a17a928416d80d44d89161871de26439b2c5ab4c153f7e644fc0a620a1812659ccb860c400605494a89375a70f9bb0f9828d24b82c31e20f1426498cc0e68a0b8e92392964e983431d3972c05a08631246e6c2651a1be0218a101b9841c915093869028636298cf9f2f5029d5df9363a312c818498346ff8ecfa493ec367c2be2562bddc050487262278b90b4816d6d2710056856bccd685e0721790166e78b90b4892302e038e27809ca00186405fae98d310a1012e5f451ca173552686aa3748803842cd12590b77e60c7142cb98336e5ac0c102e76983f5041461021d29d3cf60e906c806705842cb941bfc0904bc07c856a03a42060b893529b4d0e7cb97049e9d24b6c81ce955cfe31c8923495c8ecc25d1f72292e410244872cbe15871a950428724fd0879820b9218d240d1c5e27217923c342486a460854544181016beeb96af65450488982e3520997343579019822e770de1225231e8f67bece431123fd1139620291e2b279292a80cdc252409903d5108e922a2e4469239f2f3be8fc9f9b8dc57bd4ae66ad211497ae1b0789124091a21495ac35152122e09379bbcea798c4b229392489ccf24dcfcc26942a04949494945f49449eeba89e473eae6cddddbddbdeeee86fa238a47acee24724bd6aa0a72e49f7e83555555555a3b7e6ac97faf76775bf9d1b21222a7034f10b103260a2f7d41a75a5555557565c7b77e4affff0897eb6180e4b9e55f1c8a686922c4090e77c4071c4e2b09932a244c1020845801e140913a5f0f34b0305540debc31403f155112c51c1597bb92d8207363454997d50e6b5a8d9530dd60e4340f3d747be1eabf2195e4d14a755274de4a9c07385ccf36e24b77b7191ac8dc7a4c0da1160fd57814d174f77cbe543e9be987a6534a1784c8df3db9bbbbe77cefe97cefa5babb5baae7eba43c5aa9149ded3dbb3d983de79c73f697b0e76c8846635e91cec7deff68f6cc4f47ade43ffbf0b6f404a02a62734ef7a0ef20d98b70f9fbd2be654fb37c190cffc8dffdfb4866c5a1da057c446f9ccd1bed7056265d41ce707834fe9c8e0269fd4a9dd8abcf102a746173258ed78f2a1cbee6dc71a28892dd7c3267c5fb3f4222fa5834c4c425f2974375c9eb98f0d0e1614a9f3858f45c3a7ae8444125cd125e522b2e77196983a54e66b145f4e76f2f576badcff5abb556ae5cf963f6881ccc89a228fae43becec35176b5d2788019b4131a201152eec59b3220368daac5942cd952d4247d499218733377429a36606ef8bce9cfadd9f5a50dc41f42c75ff1bfe3a7f297fea551004df1b752008be078e0e3ae8e0f7a0bbeb3870f0f39c7a75eaee4e9d524aa93fc8ee742cc53745dee84123829f27734e10228b9d313fc0a0f5853ed5a537b146c5377385c89f231ebfe65f7bff9092fe39ffbf318d11cba19b4312ae1b0785f3a072b886f2bc3a94f7a473e272d3c69c3ee7f4d9c34ccae1a0705050b81c0e9783f28983226f5f449c9b1cbbe99edd465cb813771b47c7293be94876229f9dde91da4974a4660a13a526063e668650034507a5305400e9d16a020b09305ea78a3888ce41057944a951c7f44564b03e55bda193aa75d47d56ea939a4d9ff77ddff7a167a558eb93fa6ad54955d7ca4979c0ce5ed369695999b93e9f49a879e39f63aea976edda5597ebe6ef87ea3ae96c6e6fee6666ce81600e945dee42a22497bb75032cd2116b23149d7f9b2fd698bc88e5ecffddbf4b089cca24f480cad2391710c56a852c68a2bc6961373fe74e7cc4579e383994d10346a78fdcc7dbef308b684ae6fc3def73ba3297c3f346afe68dba1c54ce3f07a5f36a4e87a35fc4a43b198b7be7725c7a005d8f22ca2d735f5d9add9f9cb71ce93347e2feb20897ce769a075497ccf598346f47f336ff8b58f216081310a5949224d78618b93e962249fd84627f1f7e968e3cbce7a134bf47ed12318ce994463046c035fc7ab436ad83ee1b7a7c7dd2f914a82351bd51ccb799729809f154083d12266daab6b0c5425c513dee8f8a58b88890a3c545441c0ea43c108960138ab5092e731191450495bb35a6c73ca2c32f7d1db50a9229e508fd1edd53427e3e724a9de98d1bb389bfc913c492e530603af15cc01ccb98080ee019f3876ed7e8d197be0ebfb57ab57ab5820cc326b5d3ecca33fa2d68a7b191f8259040850a59e982328c7e3a6489e419f49bc17c0980eb3edd27dfe6d85e95315fb8a039d3a68f17223b187e88a850a70c0f35d0b0e367e63041980461dd9210d21282c94dd356b5204cca8809f2c2135949809882042684d7102d51862833c6d1b816856327dcf24a82c63958f3c7cb4a1d3c80bc3010d275e48d9d255d358079586081fdd0431ed0b398f842c3136402c9d08019601872e62b6bcf95d09cf4e79cb5cef7a741469cb53943887350e4239662918ffaf5c7e827beb82eb154baed7dcf3efcd63187cf0c847c74e7d21b3638fd87a6511fb11cba7e54549b77263ef19dfb8258329beb5fffa394becea7f74dc1bebeb4ee9c21ff46e6eea474da2f0668ca6f4975eb0ebfb50609810205daba5402e4a5638ea39834a854ce363439e990b911000000010053150000200c0c868322a150240e7461903d14000d6d8c426856329688435190c428088410630831c6100080318020a2981a321e01136e3f946740d236a4c3301551effc995d03d7c388c4f09e029d21a901e25b03e3ed8593a58ae20d7ad631f7d419298bfb103f74670d96df9296db0c5fbfd9ae2df8715a16d768ffd8f5736f493b9c6951f188b9b27eb899e804106a845b4a1b0595d2f635c494eeb6d80a129c10bf9f9c5967e5348c9e1e8169bc9dc8dab81a86b78059d6c247cf0cd39f232b993ea2401558afdcb829976c5c60a2a06b482558e305d2b12cf09fde9ccce9045355151202dfb1ecdecbe4e6876fe0ad3668fcd3c8d86bc7b4d7cbca27b6271bc58a9e07cc7b39e1efedeee4cbe8e85665ad54e9131c899b1fbe6d1632205829dd2f5bef2d8e769856102e76d3baa2035ac69c15dba95b2b31eb890290a16a4c1f6f53026c64364b0d22aa9e94545df368412f7717cc9d1a38eb38dac9aa241ee5cbbc19a6f411e666a46dee3070d1b99752024c43cd20d12f0df405b3358f41e6c8c33b951306e4ddeb9cf040c18d8b8937f800b3937a2b3270549b6858c2a2f713f2e8866e9049983671eada74fd80493fd3098188a90dd354d3de31b6899e493ac74275a09c2bbe6c1878e20531704362c0d7a3a43cdc9c36186f2e940c10452d67e7bab1bb271d46d8e88533c133e62fff440539a310a4026309a6049ce2eafeaeffe81c94484d133bb925bf7b8387c3d82cb5c093d3db546914be7a3038d56fefec8a576bb2b8321a798f11eb0344d3bf6210418709ebacaf73dbaab2af72848c1a4c1d3bfa55847476f1c99563fbfb21a0a3757f7d41424c6abebbbe942d0669f07726fba98983954fad0c91de0e8d342b9e7a5b2126bacc4822f0af5ca5387ccc34c32f93422019c7a31186dab2616817bb98526003396c2178662cfcb766cee5efca4012333580a4a8e8a1c804874043c1807dae320b8b7fe242cb7bb276a8965b206f13389bc194df2acd052e5078497034eb2e8257b249bb3f9ac11f24a28625b225e4d7a5fa0bc6ac3140c8fac8bfb1b4a8b8b08833b978b7c234112e275618b5bc9e1eb7f87239f0a2e75ce5071af59600fc94a5d56e0e9d2ac6957b061db96da0ae004a0aafe414923e82830b4d40758eb3afd00dbf77e312fd31d35fd305ccaebc6308d4c46ee7a4bd4614f142d1c1c1e2e4f78fabcc1af194fe736f1bc130cd621d955d1b9dc6ae09e3efce321ef34d527e2450166e6822b15654f7542f4fc860b046dc9ab2649ddc70a797cd6d5d1e49eebb5fd972a0193c63238a1c971c5f04496247d6e2e9da361a1a0d85e65f23e24260d9071748f0cad967cf7e5f43e5c1a44665ee45f65d9b621ceccc579460e961be2f10407ab70be952d0987bd4a3968fd04dbb313bd6393be39b9d289642b84a3682c63b04d03ad311deaba08c7604fab3ceb4044b947d035170f645c4f6c6e1846ac284692eda5357b936d2bd7931ab9b5e9067b4181bb1faf150052c631537a8cdeb06efb1da1c3c7d018df2e747d245859c203fb8b23f93967ee104beee58be8cb2f7c2775afc0316fb366e78dbc0a575029153e70f7e77ef8586202e9dc3082a4cf966eb7d73c0e9f7e64eb363dab1b9fb85d7c87e392bedb67e638ebb18e15f66b32397b9a077c8032962853693406926d52524e0277689b3507c7d7085ee0ccbd8f4fec3186fc5d17d10c36a6e464c9fa15e0187dac59526a61d5bb037028948e6d8ef4bccc8806d9e0197c380a6993346fece10e1792006f8ff03a5760ac017d6a93cc110c8004cca909a07a691b1cb149723a766552ff30f447d91dee7dfec1e3e470449d215e6491f77ebbad4e2901e7a20d24354693a43d4a48cb32486588c5494b1f5ff4af7683dc772ffaa30f0d74f2d6ad53deda0e84802b7522d92caafd0c4a5d3202ccd25d580a8a69bfbe36bbc557c94d4138e66e3e171780536dbf94fbb24d5e0f2c5a6c26eed976c2ab50842eaa733d7ec68350f84a343d34c725384be634790b1e93a1737ac001b17f92969733535d5ba0a7f385baa94b5df0dc263fab3f53bff7a164112014f79e86a0f45059fb39edf4cff1402f34e85a77a0832c86c2a726dd00484d2775e3520a0bcb4ac9aa590fe3ef71ad424c9504b739e838bd748bf0340f5526974436a87df59babfc714aaabcfec73d8b0174167bf6a8855b39dc88da86213d92c6b2c74ee8553dbc1a38fc86c58750aa20d129dad79149929311a01b8d95565d32e9449113ef66c25d8c1051bd4e8299c16f55ea0ac9d5d0c64e01ddbdf3969417b0624c11c3629cbe70ef6715bc42cc92f1adae8d9c2322cf9ef079951360884ebead65981c1d675e31e81ff4e85e97c84f21088066f94fe96a1038bfe584f417924f6f31c9a633e9455e750072bd72aabd31a1e6e96b97a30357c4dad45353451630dbbd561df4025adfbb581d432df33bc327e42eb2b05f47ebac25b654edf4917d7b5487698faf7a31ee8fca50e77815ca0792ebfe2db1b5412d87b0d05aa0af506016549e0b52ff1ca0eaf53b92b6bb1092379312b590bca4f464c6cca430a053b4e20cde4785a6a0bfd6eed1178178c03055e2729b491614f38e834ef91df0ebcae516c6c53d07dfb33de6da79eb93d27cfcc32c59428b2060bb01f4bf798d19a684261d8ca027c86f43212be78be06c02628a287d0088fc81e5ad2fb08bf44c81ca5f0505115aacd17c206b564154fe82dc9001abf07ca169b31298f71f14e749ffda172b13b8be806ba1c7667a8c3e22d1edda77ef8458308eac4cdf48d286ae33a6e0fa6e31091217d856dfb487042686a11c72b8a7fe4d27b4681120bd435f611cc1498bd94e89eef875e9e9f01aca86e5d49c62f2af10d8cc184c4c57286a8762eddc052a06ccde495b928875f9bbf2c16fb84815b333bcb902f53314b25b8d29206fd87ae10ed19b74d5c4d8b9c56a3f3ba1ae8382869ef1ab7860a4a4108025acd891ca43dd1a6c0423e3cce378246c284a96a9c6035a0ea0de5d4aa39eacba23088024dc37cda9870e6ddafa10c696a860c0bf214f3daa96fe6bc56796926f08a2c458707e43635f6e11473abc25622c54ef7198d0cd94d983e4b6f442f7234d1af9d6bbb3f31095f13e63d0d4220a3374652da0c320e81b40de717b55da9055d1e75eb4d09e983684cd00506fe65649852687eea258c722bf963aa02e800792d93347051294f89cbbc73c2235076d0f1f6ba268695131af89f4d5a4c9e7884353033890437e8149abc4f9a6523e93490b1176b3e383ebbd74cdcbd067785281bf8b236e8ac5078fe9e9ce9c4293b838e41b1131e22f929040017ea830f15c02249013801c746ade797f5758d59215e44938691ace887a06a6eeab08441ab9ff69366aabfdc722d79fcad94776ed3578035545383c67855bb5a03661db499e1878d6e14db59c719551a991543b6728c8ad1addb069df27d739179aa5c42af820169b63dd66d33df76320f016bcd15763e6069399a095f6294a25fc09dba378324545431c6f5d9f32227431c1c0a39dbd346e9cdd5e4f5cd5b48a955981c00dae0f3e5b0dfbce5b9fd3d331cc11615374aecf9a2685b506fc326be9c8fc7ed336142dd451052cf477ff28b1ed78fd2beb0cf293956613764ef9acdd2e03fc12d9586e92e612b37e273afda4c8388687ed804a2e19638aee3867224b15248f0eeb94e33dd57adb792a5f9d79c0d71a25ec568d42e70580468e7955d4818be50e79193551868b71fe0f32756ca66cdb1a8d18e4932e539f21685f2c1f085b5d6bad17a033789e709e3c934ffda5a1b29614dd9252c640f217818b0087bfeab6d4d2c85ddc471f30eed476d6177706541e6ac1042165d182aa85eb8a43acd1df16e45d711670a70de34ce2f6fa88ed6db2cf5e99853d8f9d3694d599a2a977cb583f30c2d0a250b0eadf57928e625b6186c8434bdd14415d14e4ae85a952c6dfc2fab7518dca310e10b702892cb02b0681a12d33884e589ccea438403ad033dcdf36c5b8b00fb73366d9ed9186e84aa55d23c779bca4c2183620f07818acc88f558428558adc30a448c6d54f2ca138cdfcd2ce273755a7fe49c28eaa44501672423edd691c4b9af9adc997ccebfd51eaa0b26e77c4762afbf59a81ff8344acbcab1814a0dc5041f7c44ef900ee4d4ef628e537c1a47f5bf5aa7395c7c80219356a1debeb9e8c3d2d8de6acc8c809e2017383a5c8809a6e944de4ff9fb0f3c4e22682b4361074da148137be0e8dd0e4db73387c9269cffc4104cec446163477a8d22116d453af080265a060326a28d48e1601e9f95859e43bde1b5ba00c160481b05042d1c13659c2f64c9463fa40c58fd43f520350149c22605d6a47bb870f853022e37b3c31b8f03a09a01d4b0b0faa99bf0d4cb07e2fc49e233ef8c6948af1d4d5023be4e4dcf1955618bf44eaf25581d7ce744ca5bcc16fb829948e316937bfe12babf2c2592369ed9d0af78e45256a6cd2e8239eba16b5314457cdb0452dcbe1de725ad206ad3de004e93ddef0bee85d3c1750b211419546d593358ffa34f2393b069e2b275aa367006426f3d9296a2c1b82c3262dffaa2409434e1fe104f18c70f44be20b86c3dd6751b18d69368551b7d53dd6f49eabee50053a580ea1559d781a8f1bc05e7d11082d5bfbe0cf22c5e654136b16d8924996cb874e6a0c14ead42ad3baffc48be913e0dd2d85c4c8b2d25a45c4a8e9f7cdf8b25f1283945f039173e0f8c68bf2a9115403210fe04c9a05bbdec62f8b2bb1385c778f48cc9980b1f0ad7c46f9782238a9de72fcbec49496f6a6630ee3bc120393c884b7c45485f37bde4e25f23314f1c903570f0945901d9ba194f2271a6f769808e46643441ab765c033a905b45d8ee6d42ab35c741a8dce6c00216d140ee781b5ae2a680892c4510663fbabfdffe3b1dd21e1766cebc19687914a286136ef25d94bef992e108d14f173cacf5f18f31bbfa63681bbb72fa4d26ea03eb8e8939b2cb39f64bbaa4ee6633f1eb369a7476571c8b4a6921d281b50640df9460f62643d4051a0eaffac9a788557e223184fa5867c3eb5a89c45bb670b1b0843120fb4ca46fd338719d883a7aa243903a351328cd1b55cede70c110991c763216634dc4c0da530a5264021fc7a39562f43811f49fa6aa034866868dfcf2d4bf0cd11a701b80d0c0307495d89cb34d03f76b37dc2a5d1f02d61377f1e4502bdcd9e470139971883b3129ec0781cfe1260201dc118d11b6f78eec9c3c5228879f030340a3af04ab2489398fe2f587cc8a509b8dc0824ba42e701269d263b94c138b86f7b8a56282e920dcff490007347aa765a1c038380b0121400c9dd40312fcd7ae1b69e84a2af1b0165f05d39e6d1ff4cb6d97039d7269af8576950c73dcc182f110266846719a84dc2b00129cad3c3f8930750aebc53308238301b76d1aed65701eaeda1af4a1b89521baf64713a637b90ca4b70de9c941b5faa8f99c17120962dc489443693bd77b86bf4a4104562262d2067367e523631d003f0cffd599d7c31e2fa210311ce68f62a3f2c56f766cd7f9a2b816592b98df58046dc7d90fdfbd49411a89ca49ef8f7d780cc1962649cd99c8cf1eca47c7c568e0b258c1f2a2b55df480c6b1502797bcf77095612c02de0bd0770fc23a040c968b3639a77dbe417aa3d127467a413f789897487c2c0eae07b01fba20f4d160c2f5111730a430576857815810899a904ea2b22d9e13e4d5914518cb5c50ca6049b157250fc0ed15d0f9e005bc12185acad37947e3e5377029b4a7436ef004224b58ca5f2b8f08c5f1703af892d20b05900420c9cde6520832cffff88c494b8dcda77dd9e09679fdbaac41faaa48eff7546e25423d15f2c9905cc87fcb3a28f52b768556e63bb9f523a02f7e2ac15acb80b7703ccb1cf02afd8a22715e58b8463ad11fdd6020709d5bcea7ecc970967b65739b23479200b100267d4959a298006b43ff61a0364624b0dc1e6238f563ca7a47286166532a25eab39c34866ce8ca38634d3ae4278fe1a7d1c2584499ca0efc673470a0848962dad2be370971f17b46c7a0ba0c6b0d63d73eecdc2e978849d50f06d305862eb9b093abce7722c0afb4e0a78e80de3d342fe9fe13ecaf3ab15ae3e3c38fcc22b36757b2eec924be3cdf423c71b3c999ca1d6b4c420c1d61681a2bd6e53441ca7ab8f5377fd48829b5c33e188b78297c66535a868401458b639476f1065971e6d06009bbe4b4eb8293be53cdb613b392e71521d37d7aac12cdde5d6dc6b900439576daa92fb965c5097f4c2c9d3043670e5843fc5ff487922ec8b2403bcff3f1105152ae389e2f8fb34ccbceb93ad38e66b7d3e999a86eb7c763e8c0fd78f040fb7fb38e2d27171afcb81d08efd2f3875319c0a85142ec38bf509d20999fbd3b98445bb27ece81cc96dac062c084bda53891f829f21912e6adeb87a18ee72de57a455737b0d152aff7c12998a94d6eef459797b27e1ccd95bb7a971e0691ce4811bf41b16e5710a6b14114068c3828a393858c185ca2e6b20b19443529c03473bc06a4bcaa092dfcff2dc7003d5ee26614c3c18e29ae47821a3b36d6cddc2688fa6a27237061c31002e827f33fafae6b2def8f328fcd4f58e5ffe8c092390a6d6d6b1b5d48376cc0bec792e88ed3a4f785c7ce56f85abd18bcab67de1ff80baf5cf984decc7119de0bcd2988a4d0d592260387d927aa38ca48596c3adddf10471c4acb0f6eeb2b7629987853f51b9d6efb9ec5019d694e3b400fd62f18248e506d0fea440dd38872d532688a8abf85cdae436760e0e0b8a7b042029893ed0ac6a5c539e08f6a85f19153e9bbfabd05a34f532521c3c2ed9197fbff105c688d86f802e5d9164a062b954e49292ee949bcf8d24de923e019d90d293723191bb71ee8a7760d6a2d34039bbd53cd9f5848a01b42142b7f162b2203a2cffa77a93fc92507f523d669ebea9ef257458478218b4bd5f996b39acc8cf30bb50211d179a147c290592d5c90a175c01c7726ec9f944df31d29d65ab4bea0d23708498080a165aa337b5ab90d87da33da0b15a211d7a916ddf80ce477f32e2b8fab9a2683e8a085befa0587b6c4037ee514b47cb97e99011dd82a44f9717d7992dcbc31e8f9a648bc06730f45777965efb50cc5baa5b4ed8580e6fee02a182b21524af8f04c811e85308014f9367f87eb1ac0661a7b12f965dbd16374b2087b1cb8247de0285bf8cf731dba6f46c42befbbb3d07157be79fc0a058b1689fd387023b44d5c720d6e695b12b92df4db62f66e311bc6e19271068098e2649119407c734c6f03e0b6ab82dcac85a8931f861963c0fda2a5b298a0e348a3d58f9ae0a90e22deb394fe2447f124fa99f75d68e9f4cb9a3766f29a27c671746e061b7484b52ccb38f86a0f51d4f2284556f75039a4bcc2176b8269cffd6b8e1fb954d718e9bb186fce8df13a1ca616a5dea8d4a7b7d3eb4e0ac1fe7d79866bb13108328aa480b15bcf26abb23af16746832e381e724658aeb788a7b0673961044ae66b14e8fa3af3f075016d4f661abbdfc586467a8f8e83160ccf119aa085f642fa6ec8c2f4b81454b75c3f5e39e62e0ddd9b21fb2157d4cc629f982d35500d4b564de43a72da2f1c60b620a9eef0756de246ab341501cb3bb6e1ee6eac2c1006ec968fea524530d2cf912098455865ea253d85d1df801ddb0a0b041354bc50c1af6e1f94945d7c150a6419ad421e70d8f20f351d658d0ab8f16eb2aafd49130ac6f20c5d8b6dd253cbf51117cd35a760be76e42c90df2f1eb941fb13c4e749ff5440a3c42ac1ecafcaed609375f006afd6ef80c0ccc4c2f4f1846dda808c7e865f3fbe20990c2c6ace1ed427fcfd3fd001d527f7ada19a46be6a4e8d9a193bb2ea62a42dc76921c2fdcd1aff25d39262aedc49e8e126118b1c35ac19d03ed70e850e784e2ce66d5d14727e9ac6b55bde3400be123145aec6e136ea47e10bde174cd3c8c09483aa5ad92c87543a990a56116a8e434d0213cc17ba53f3a1b3066496a5d453957f609280dea162342853dd9afa7a18e4433cb0b968149cd5b12da89cfadf1fdf7d42471251305301ee57cc1c175cfd167c2a58a5ba331c98163a3ac0cf2b06a013bdb55f3d699404c767491c48cd688a6b38ab690428bf0596328c683d7ee2f08eaae1cbc1f953230d40ee813265dd6685628e66527cc3ff8226bbe8ea02134d9644b054c851507041cd198a390e29eba5d974b0982591b9db7ec30333d9c8b509ddf8bd0579b1736d422c9a5cd5538d595096268c8732329f67ada3a93adc8867bd5916f2ffbf04015c9046ebd126d7660376892818c1f486165c7fde0766f0efb73ac5afb1d6996feb0e2d1fe8d580cef9cd0f54be2f191ee68370e1e8772783f736924d9b8613d529de8a056541b95342119e6ce3bca0fce55362a816d3d146889367790c02f36dd41b1ddc8c89e44059163ad104a927c29d03e9ce549c65611d27261076ef52b18a3ec6b0ba85f142e8a2259736e3c22b7d29ae831caf998239fe0df97dd5ccd0f654b7550775bb3610a4d29c6302a082a8736825a305d95988c8064f03041849a6bc83d0607feae52def9a269cdcc44e2da8aa9838ae0f0ec0b01964b6f47c602f247f08b9e6697528f47efef044bdad99e467f50fec1546ec8c75ccf9b60e1d2338c8a39a1fc6dc466ce6213ce66ef10fb6cd226190120208eaa8fc043c1afbaf74d752e6797317f756d79737075c5b4cd17ba126dc3256d6691f4d28c094c73048330c33720b024a008b8e56f51aa246ad2ef33b114bfa9d734b05e4f47d9756d9fd6c8037a8f620cf59e27497a2ddc101afa42bc8861a09d374c3d710e26566f965d6d69149782beb006b1f293c1540cecc99236cd70ec45c21dcad967aa4056b44a85350651ddc7038dec48acb7739e8f93e976e39689c60378db31c48845b2ee0c287c99a1d183a322b59d58a1306490185e8b2df41d60df4e91b6e72ca4d757aff4f385ab12c7b304ccedd6e7a112705ef9a1ca7ab8c9ee68844d3422c3a12c16ad43b341ef84d9e04b0070633e23b9b3d99e3747b15957fceb4d911a9e283cda9030f063023c68bdd555c5064d6d5485f33b61ba3d905d549b61d8b5100e64d6c572cf9d38891d022d8544008e8c4dcc7c321c862566d540709530ec17ee0f382a0695afbe5c3a3cdc1110c55d91db326e853318810bcc1986c83a270d08a70aaa1370c8a331530ada335a36f2f811fee72bb3fae041aad9135156c3fce683db300c53c2b8265461e67667cb5b319512f019b5e31f3415b5ca46b2c2ed5295148220ebd7d8139b7a12976c88bc372f302e8147048a7172bc61abaa662abe04e37904b42d22f1e4fa92d25f348a453cb315c7047b195316f3fc9d019bdc2152fc06b863ff4c6807d87cc1892df46d84fe812dd445d71bec8a24fc27aceb93600c20bbc668f7ef3c8095611d4718c0fab9900d60521f3752c80eee3f098015a4e0df6f22d5160dc81618dc1d931e281cd4ab10018cdf70c890d1dc13a9329e71e7f1c3067c94d1e6a34f3fe1f0723c7c5c571895dfa844c20cb837cd6d70fbc8d5a994d34757454366ad6a22f72755886676d0d2da30c68939c2a0853c788ad4ee3d428c7412f7394e51aa80b717330e17054f160817e3f4870e09b511e8dea0ce788d59dc3f97806217221f26085a9390a45d539a9e6180c65224743c6ff1c33d1a32dd03cc3ec8a54e808a8226439625ee8583320824a42f93bb8fa1349344d630d3d2a4caa5f62683150a546e5cb5fd0db85041e9899ef5ab44203aa36758e49e346f598651a47b63296a0f95e1f7747c24115163f2074e03f03e4da1212d02a8cb86d4202583cf8a4afb031d1383d27e600c77df44ff210850041edd7a58be45bc944f7e2d88479e2d72b35a9afa6671856e634ab8dbae6d1f4a44579c8220fddecee3369ef576995b76d6d39719053648df8a27f53af0bee7409bb4dd9397559dc7d2e69511d39c0cf34470dbf02f26719762c7111b9e57f3e3280b701bcb436017a7518e720aa598fd1ade7857413f32185bebe41470bc1bc3dc53536c0be2d96a55135ccd1e767b58a38c5d8465272cc0ec22d2557796c8408ada28da3622a822ddef6cc4618aaceb337b11fb659e4cf7c25c6561e881c405af11eca5fb5005f3aacad6fd6a108406380a73f957dfee34e71d859cf254372d8a8af41b0b1601b234a45fc64a65ffa1e9a47a1faf368618ea5adb8728737b2e50228c647abbbfcea3d340d295ad6335f10b60e21dd8d25c18b787d492eda744483bf5f4b7ff4c56dd661afbb9fe02cc0a42009bfb1f5c017b8b098adb9940fd89c3a33f9d27d343412985bd210d4e1fc665069f0e5a23c69f91361ce0bcab756be91b6fe194c1721ec9369ca87420632df11b4a94c20ec2d8067bda545dc2cc46f33c15f9d2b38db7ba09efd3c0440319e7a0153703a9a1ed275b98c5ec6c343c2a7b67ba436e1598cfbd525012d7231c184b0343c0ae112156b9c5c47f822eef847c66aaecf91dcfae37028412b8114a2e9a7ed645b9e8b89b1b0f37c6d6c906d89ecd1901ad218b9902f6b94cc53007d455d3b7b82a0b96a27400b78b79ff4e5588e18fdf2eb08b8515787ae83fa82b29dd655c81bb154bf66d3e32ba678ec98a4689965203776548da309c990417c05e65e0866b8028ef4f12de6c53addbaa90439da5e236bb00a5e337f2aabe9b972204df415028a1720330bbd9ef57395d28305767d2904db41cb3e4c0fdceab47f7924ce020a238308647f601f51ce8183d70ce5ce32efae790a277775914c9963863cbe8da1251fbbd66c80ee46f2c71885a4e308246229b9764816661a1f2c2b18f09bb7010c82a6260def4de2004ea6c405c0ba8c2c074c1d07490e276a5eb66d72dfbc526c2c019552cb4402c07a77a4c6a050441cd892cd82bd91a634b83a3ff7d4499a4c230c654e1c1f7a17b9dee1bfdbb283533a75b44970d0eeff5c13acac91167b85d86eebd35e54e7d253a99620825100fb38b3841aabda70336c654f87cbead6f66274041e9f2656ca7faf0e4264968143c58877b30dfc37de7fa27538e80172fea1b0ecfe2b915cd717e347aec2031738f621755feea81c80b0e8427e775228913baca1de8e484bb8a2d17acac37979ab329f0b8459dc388ad606b8317d3d310e69e3db15b42f53f492e54bf699f02d0caf916d769a30b111242c9e82dbcb9e2c0a579b3dcc02f45d60e1a11c893ba829020130ea1d3410b2d8de64f723b91970e24fdbd3f231b45da9c2b6e542876995e5711dbd1f49f94dbc3054d8f3eae708e354329277f8288fd13c57a86f47e8654dccc2a3f769ec860bb047dd41732b3e986af53fc6c60e6a70f185db2f6188c21c1a972465409507f65acf9f4812c4edc0098ea6b679670b6399b3e6aa3d5c99172650151dc78814d78eb23c713c06568b81416dcefed4a5bce37cc090a0e1acfa04b0ae8e224715c79dc3f453562e84b701920d437dd99d6c9b52fba79fae3a8675542911acbf523e241a42831294b03a587860d98013b627c1780c77c83be18bad284e3fcf3f9c9f19c18c37bf02e1fde6f66f20b653a547450ed03737284f39c6b3e834919af6569e3ed6c575aafafbcebd812c72f0241e35c83a6c5fc6ce5153301ff556a821de49bcefdf1c33b7a282bfe7f644e74f80cfa9335cc5f8b3c882ccff6b6ad324be01143b62ac4e749f2c00cd0b9423e5dd95133d8b955f031fe67050d1f70f563c9ff4c7124d7cbe8accefcafdc38f1f32970ed985e124ad3b9b67a68c9350add2fdbf68d92201aca379d12d3dd797273f9daaec45fea323416d3848375811dfac56b04a7e40fc4584c277e5f9774039876467b8b60943af7808da07fc21d88f44455a39db483020e7040d633ca94a33c81f54c8c0dfe4563a43b87e0d0a9dbf34c00fa42c76ad6fcd395dbf337911c691d5a3decc77af4006ec2f7897115ee7a17ad4729265b60414b75a9c966f8e0b2647e2d8ee916ce7dad603d3863ffbde976454af39a35a69d040075c4d4a5b946f352209730a9975a017c173be1a0b3a8f2c613e8d62292192d1f69938aece47729e2c8a628e706d6bcd41da44843877679d5e7ed49cd0f49144962805c360e720176883efbcf40a00d783d6dba52bc7511fc72202e08838985c5a42a94709b16b67718248fcebb92feccfebcc4d1fb4845f408da1818bd9357e991baf449e33516de72e1029b7ba3cbcbe9c54b4f30fa18ca998c64793f0ca317322a5a1c95b0c655988ae41a93d71b7713ba59989fbd306bd894c828b0c9035c4494a35a28e459f2c0ad15465ab71795a1544d3aa14ba5637e253e60cdc9f35e8c65a827b9635cee3821d3bd5ca5828e0197c47661716d344f0d81856897ad0aa104da512322de3f2b0c238a9324d3862c54e6b01b48a82498cc78735f19ca8c0702f35d4d6a8a9ed4d9f1608272bd78058431248dc59740fca1c1b1d66a483478eeb6c0ec05d5e11960e95070b62ca3ba10238fb4c446cfa26d09807c1fb017b16e7dd7dc31d06c933f19ddadb1db25b17b7ab6ab3f3149efc7dead18cfe152c6d0c838fea6701de619c3ad8a0e20de27e9ef2f3dd718ff2ad90ea3c9c65540341e6308ba9a6907fa796487b70cfa6c6066289b8133c7d6b0a54e78a65c873bef015abdc4da9d23b7993f523670ddfd559052ddf35f92de70382de5f0a0dbe0152a9f806fccffac2cac018a285fede90a4731150ea678fe8986c68b49454d883ffd50510b13b0100a49d43b5f476256466eb2e99213b46e2378ed99637119787c98c4d8e454fd5a2b1bb3f3cc5cbd281db0f98aa5436549b8b4d452c45e1018f06a7b7870ab86b9cde8c2019be51162b118850df95380fced6ff92c9d9d60893254416a84ab96e1dd7e053f655bf883a3ce41ba5f8d116902961729e8dae063afba1ece1a63c4493cd4745964234fb21609ed538fb61726e64cc0ca3706e7cb57c9929022a0843396996367e24f20d20954ebf304f1d76e7c37f7df7334de7573272f975e4e95a089bd7ea5a4882c4f1222cb7f28168da73982a28ab4ec4d068ba8880292a8a6a378340e1097b009f0aae46cab7d9329e4455d8023fbe2e18a73cf527242a09a1314d180c8616b2473958b991d486dcfbb9733d66c2d5f1da40722b7870ccdc10a16004f934d290569920b8d1e37142797cff330e03ae48147c822b67b0e05909a14567fdfe46979d25cdb7b3b8b3a13b013b21d96d988fe4edf1432d4c262d63b27dece90eb4fda0fafdf53db97c0b18d54b18384be41afd49a23efd1862aad9a913dd273ff7a92ca2302e85fa6e7ac2a1ed4cdffa7e2b04c26ac788d1fee72cae0b8a46ab3239ffad16d55f11440e30532f5ec39758fb86d17ae65aeacb32068f27c9a03b2978f57350881e2e5deec10f6a82eaf18aa961dd55aeba275014594936e359049973930d000b0f98ad44781102464c9c9706dc3692992d42b4720d4ef9471937fd5d0422531b342164299516d984b9351533f2cbaa22c186df85a6d025fd0b77bdfddcf9d7d52e38bbe360d3d116d22a1e2abf45f95a9ffc36e5b33d2e904c251b5e616360c42d97a39731f9034c40c8dbe9a04a164866dbacf6c7962ef91ae7eb0ad2e080f25d329cc2867076a2bcd5b47b7b5d751106931c9f53acc607a491de7a057b41ed307a28e793a6087ef4516cc3fcf427a275e044f1d82b794a1bca99b9ee005c9f7f000fc718521dbd131bd9310fb659cda6dfd5f50e0840f3c8b03be4a24969e537c9cd32e697de4de1b0de9e3ecbfdb207ec7f878a0b72f303cbc801d147ed81357108e1a27480ba3e2cee663ee46f1b77403a71203ab515d1798ee30095b2267bb332a708f5a231b55916f1d06a9af448ca1ac240cbdd467eb6a4fce5da007b37e9b00920a51505e986ceb45c3574fb6790429cfe0d8d294e7ccf02e557a0e6aae72afe3f781495f46261b85b16e8b075444807e2b8e26ac31185c61a0cf9d19cb3fbf8a936b875983332145af9bcabd5c1d0ea18c481654301f55a3092dff8217f55edb6b383748b0dc4aea6a245df51adaa59830036bcd7eee4b9f35b68dc0f9d2a1383d8495079d898007cd9782f5148177f6fd940a505ef50a3223ac5e920aa2b9ab20ff2249c69669c32eb6128856e577081204f740f725472d4e08d3671a243003683c07293b5efa59c94e6ef62cb2e261b444bfe31f9c7c4849d610ab1a8042c5220d6a5c53876c003d349f11eccdf9eabec1806164169ce519652e77e81b4024b952babd63676333e8cda6526bb98fb4862690a98249651341de2459523e9e480c3ff1a8780598bc4016679001b9069aecd12407ad033242cf85ba05a28058d0cc804e46bc0fc36f1b1ade00ce53183c808aaa98505aa766d98977a24c401ee452836b194c44f79c4ad9b9832e304c8f0ea6dc62e512ea3f96d9667262e4a8163c9a94a4be0dc806de5c1327d1bac8857dde2eb93f6e73b8a974877c01a0eb0e8a2116cc986f4df63c83386eb68c84e19cab55ac10f25f7122acbc8cf343ee191161cc563f5a780f67ba272ffa45f78e36a56a9ab030a1ed4369cc8e7f244b7c8a46500f861e194ddf3f5af30d8681994a40804596dc677d9dff50676ab8e712e9e3fe45ea1de627f130e60efca429229971bcf7b07211bf33c41fe86f1ff0a5574494b85bc08bcb8247e88db881ee83e09b8231494c3f5ff9017e506f88a0840fb2eb1d987a07eb0222ad75129823bbddcbaff7455739236cf00ad50adb7d0577876cdf3a21bf5cf47035f363c633947deabd3ce29f9b533cbb6202c567cef79fe1b4c16153ff01a3be51ea27663d166cb9d17e8d71c8655228b9eece14b291766bd2a472ea17e8d9afb5a1dd71649d1af87a95e7a668e4c646fb9bb3e73ac521dc81d58107543fe8134cb2e1de1d3d0d9c56192e29e8c7ad8a0d46cb0f3fdb662ec5d701c449edee4c95a84827349d704fc1c3efea0205d090122a7bb51dfe64854a69994f6a9ae2e4f8359fd0c2992676d585f314a9b84faa9a06acc2487862730022b4c4858d46ef6e61471be858a7dd64871a6ee5ef1d53b9784438a2724cf464fa7065cdac7990180755c83577e94e452b91e858322f9dcc893052a3f805cf6f403f0e46d8f8cbe2dc2927970711df54de6623c1a3329ca4a9c6053116cf00c7e2d0d865f2bea9e941eaf2caad551846b47e9abdde7099e623f51a5ab21bc014e19a8936b56dda4988c32e37cb10aec8ebca52d33eecbe55db2aaab9df6fd14fa35afc368db8f493927d9b5cdd4a6a84881e4469a53aebe5f976f94dcc9f70e1226e6e933e89d007638a82ea17be45d9832e24f6a3288e59513bddf5b2c76c86822b05a9c8336f7ffa51f1fa5fd11ea675a083af38139e506cb4ccb257d862b0ffa0c85bd08ab23a80ff0c31cf8ebbd6d251e95ff991ce3913c7a300d6a690c4a02505a4f81bcff03e69b72f1e78b300a19ce7da56ea1d112aca8df3607508833141854dd17b98427c7495e491c821204e3cef2bfac2f6eae6faa61561e115c385a43a017f6644ee0bd37efe1aa667b7526d03f20df6e875a4468036ab5eaaf196d06dcf994c627f5d573f2d5670eea2b3462295686b6c9b9301bc38aeeabb5f2148de8fce0964c90957ce16783b5ba3445046bdfc55b43f00d336ce807af211b0f08320d1b9a0bf1aec4f738f852956cebf53d8036c0fbed9847050d06e1fd360a7f2c5639f20935f26aa72412213907459e4a6bba0511b33f3f3686b92fb63cdc7193ae319ce77d2feae5220dd6fcbb47481328ff0d518dc66001a77fb26f2fae466f3b6784ff0b7b26c271a8184aae45e28fc031b90556d4ec72dc345229a2e972dec4f61e4f368dfc8bb8eee1b27092b488b271284b9416712b80ccc519fe6f599d81e0e4f1e4199ac880018a25f5dfaaf8c3a9060cdc1d30e469eda13f60e87367ede5adfdeb9dbbfb4aef14497e0a61b52e23ce06bddf12435b692017d60a578e24d0e423201549136a54f9efe4a999ffc848f3185aed76be8d2588439e47aaa84017ddaffd465a9a4ce34fe5c4910386b05844e4043c3d018d43577a0fc52c9410356da0df216c529d4e04e986265b317b625b059c21b999c6879840cc799aa1b038cd9044e3f51c30c2d98bfae8a890c2b039a695afd0b9e49e529947cd5cd5ab279958569c2116f261b02b0f8804477647b7d633b4a30e523689ae7d7a49130d6145f407e600373ee0ecbb9770c00ced268e746ab90487e4a4c54467eda9ae230531efc7ff4379ac1ff522a02c4c5dc0c8ab3fe23e27f9101e60944855d28bd3e0fa10da087de22414799c50d31108222034b276d8464408bec5682c70da995e6f595ed7f4cd412aab92339698b7c6c24a1f6d80bdc19363f643d106d5790990cbb1f487c61c59016113db15d5f7b02e5417896f743800982124644d8d18d6614cf44ab581c84628c3741c3819b6c6023fe15168f68685110c6beb59e8d243d66b12cac715a493ae300395e766b819fcb7ca27115ab82ad1e93a76c02a59124666200eb1a1672dc5b092c3f39b7a04f1d9cbd0a2ee2b466b0dd7510679f0e46721dfc11d268863cd50b7062c963564de92f460f5aa41ca3b32fdb8bb6af5027b7297b898ee315ba5634ba84630164a416be3250887e41faece44da8b8d19033fcf27e1eea20353d4aaa6540a32b227903f603a04666ec74b0efff437e1b37ceb7e98339151fbdf5d29d77f2569bae077f03c3b5087b88ab7b58de9d1760aa25f358451b70f67dea0c51071fcf07a45218fc1ef4ae064d68850e995fb987fe57b6372f6584a5e79137ff67e9d24e4d6d9b9b9ebffe8ffd3420e83024442ae2f7fa8d1f916c515d69b0060697e6bc5095513c51500e45320f6b5a38e87e0c358d4908c2c98a03118c9b2c0dc0516826424ad7d00d1e64c09a8f2bade4210d56accae91364a7e684619a1f54c749f77d59c2808d115552f0f923fdde3a04422c7acce81b4c3d6d2a3ff846b19430376c902e9474a0d2ac798dd589a6e4817f958f1a96bb32c2c8cd6a5eba256c5956730110c2ac93cec14a7a64e043560ee806eca870d7c7b6d89581a1e79e07ef7f93ac4cb2b49217ab9a2976451de3a7da8ed5cd7e05c1351719dbd11c23c741437b480f81a61eb73c96ddb861a6506f116518bd3b0b08c3696ee90a64a64e08d1f807af42e9570962e4d3087261c1ca3cf7624d83ea7439011eb5013902bd3d44e627bd8e50eaf29eb5f7f130d708b514fffb363e9f1a49c8c7990d47b528e199c9bc079d6bf980eede646ba9743f70966727f217589c0fe46673a482f49915d856ac8651df4e388ce537b144f98004fccc76eaaf7554e9b228916c99f41877491959eec2773b3917c58d90d64fa905afba1bb5f40222fb65180601030d98590ce8e9a30fe77d681624a65b92b88745bcba1f46dc0ed54868a9361e70064869fdabe6a69aae743bb0ef02ccac2b36c20039ec87cf2470fc42899fa4c8eaa1c44caee41b77e5cc1b105bed85d499ce742f719edc54bb712999eda4704a034f5c93912ba62d7fb9ce48474e6bfdaa90c4d3726f31901d3bb29b9511903f176a79ca87f393ffbb8f7b6b993941017f39316e63ca250120bd2dec072fbb0ddd66d1299255643299e67a44cbe5ee78895ff328233ceaa6b97f15323be89ee7ce9b1af8c1f510d3db08ec0d9003b19fa455246d4aa0a6248584e19e5eb3f36b193ea739def1d4b3df559c00fa2618c6978cff43771e8cf141becef7f8f12f2b745e1308ae1eed80d0b9abfe901bda31a22c90fc0f71402c22f8874e57fdc80326c3f4f487d819609fd48aa7d3be1fb6a6dbc61af799906ef61b2534573ec12a860d8efc381cd2c12fcc56d20e6300797ca4d9fd373634e1c8a0d4eba006250f23208f57e4eaa1dfc9e2891ba5e2909ab78b2dda2f4d4297a1c8cfe21e35848330bf4930682336fd07bb812fa1f942a28fb830d58c1fc6719d038417b8829bbff04dcc6413bb0973ec2a9ffce14f26be6259246846cb1c6b323aa56352231a387823522a498ed6f4ee02a1fc38c15a16edee70bf575688b8e173aa63ec5f526e20c7ab7c60fd53ceed2bf16829b886bf329a823188ca63d7c50d16ab697c7ead9ec0aaf39227561ba3581060e9b21dda8a109d10f13af8e27178757d146c905f117556128a278324031b1d2fcdfacd4f774f0b869aaf27095dac4ad0c235433c93efc4a6a04a679b21c8590cb3aef6993a5243072387dee1b2fcd6a335cec47c563d372e65b1e10a1c78f68f5d1c164009f466c2f630af5f3520b930d4ed43a18b6fefb1c25c8c7f842aa406204ba72056b8135f88a58ecec2708a03eeadf1545f98e14f6406eee8f145a35569cee5c019191d854925a2b4980b6cbb251ca878266ba14850f7bcb47274883de7690f2b6bf14a809aeadfa8874cc1088984fdc26c6f43b291705f8f1b533a6d984d623e2fdb33d11038e3a347a7e5764e0ceba32586f4cad634359216f96bc4d6161617b3c6487783b41ae028d92a365e16b1d14926478d939e76d810f93fb305e7a34eb309189bc88ab699def5def70406db6980865131cb79546ef9159f9986ca411e635d4c21129a18adf249d25364519d322f2357904aeb5303720a0591e0996898efc937a32c0138d323a478599f6ea274fc1077f108104f4776da5132cd2f8e8926bfc32ff0904ae18480b44e3e39af3760b5c94c36dda70502e2dbc95746b799deb772d04acdeb035f8b5de8205530dda81e38c683e577b313595538dcdf395cc1a54c6f3a635e9e4cf692b589f8ca88efb9e2bd0d6d9f4c8be300174ea0a24b6f12fc4280c6035cdf4032132637f8d722e0c80cab4514f53ad82af2bf544b76bfe9b699aa72bc85a1cc6bba762f0bf8aa35a5890c8ae454a10a9eb60ebdf7bb1d8a40339b13bae43974c649346c1830d5118a739b8b873da352cdf6f8f9f188ccbff257940e6cf551728ada3b9ece52d45cd2398e9e260682fa4a46f1973c6804ae164343523ff1965a75cc9e853f65f349a5918cdb5b6ecbdfa5e5e0f741db8ec662d07698b5e5e4181cb082d58abfd1030cf65d8409789d3f2c5e09c7459c08d49acac6233e5d504f6481f812d68629e3b18f954eb09ec14e6f14ca8219eddda9f42c8ac2b2bf82688e5dfd04364d1b3fd9edc330acd7adfd1c95a9dcf014761ca67f2a964a07cd22041a6c9b43a0232a947a0c18ec8923d06735138a59e458dad64188060b9f453f2efa92ef4536658659e48648666d5fdf897febd23df088b668224276ce1c79bdc180a56821f90e31b8ba552c0fc46dfc4eb8b1248b57dc7cc7647c8c43b727bf975a4ce4097f1850f74779d06b5fdd3460bedd66ea4f6bc23b455182daed3bc331b3d26b2f35b53722fe12bab8d1968d78961d4186f3ef839140a82d4beab99e1afbeb9c9811d26ef6b449da8e256edfc3a43d9758ad9131a8ac3d080d8e5cce57e8aaed4add435943f3267f947a9bbfcebd8b7fc2545e0a407e2bfc4091b9b60455f45c4d8e5ae80df8501e9351e97e6c5119563e8d7c759c1637b26a1557017d31bea118184244737d1ff259893c9a45e431ccf2a1a9fe3a9a745f260d09186f231b14de823733f9c7a5be9e6003c0d711adce9858c72e757e4a9e454b46bd6d70fa7f2b1080d7e6fe6ad6063f75d9be0e75dd86d60bb208eb2ce8d0748274e16463a21428f86aedcf4f3426a6e5605b91894cb154a963ea977bd5cde8c3ad07203d4acd77f0426962cfc05f03d3266441e464367df446586ff26f1871d040a426ab98a5e6a6195895617b74f59bb3f61b5e0aa7cab5ee3f7e73200e0611a41f6085eebb9392b05a0402bbaaae5021643390f965d05b6b7b3059cce0215569d95385ab3107be5192f0a1ae1723053213df655873b3cec7b24d23f8a7475b747e1f0424dda266ec94a45d9d6f58c62d04564d09b435412c041c999b52cca88fe04a7c90116cd0d5ac20c39e49210278d9443d12fae03e3ee43a8c8bdcaa975eaa894fed6957b2429e0f59dcb28861508f904f73dd4268b86556d6501ad75f24e17b4829bb6ae99f3a0c6f158cbde3eff64372d26c3c136f8676ea16673b24a2c4b75a9da1a48513617e19d8ee4a8d9609e5a413248b1226909c93b168dc205eab3715e772c5d3bcf9dfc58d743140816a1f87055415df7686bda0ca720d4462d9feda6a5dbd87289526d72d3d20a1b625019e74f0da22d45e3af384b04c22d92be07ffc56d246bf4c675ff66562a525e2db1587ded807d964a11b4e7fb7c02f2aaf1de11ab5a804681de2daca8a9de9834a370a340b261ad66ae5d90f056c4f2c69ec77729a664f52c5b642ea600a12dbd4f0088182493b598d3a29625773f6d1faa2e397d95830c5087d4cbc824443bf4991c1c88050f88ce96f9b4b42be73ba82d3549b9eaab5f921d390ab011da33accc624cdcbaed3ab1f48d76efd5d41ccb590b217db748f582554315431bd18dcef5cc5abe75f52125606291554b68bc17626912b5f122b95a84a2cd84616144b8ea309b7981f137a9b200f5ce7fac796b39c14330e2b421b021908827c5da6abb9dcb1c30b34102013faf06d650e345521f07103855e396490063c0d183a663f02b33461b4f308f74b46667022790b21656d2cca1ad786174cbd74367f10d9afbfa68a9460d8b05eddb5a2d72f09f078855b15c8808c675bae20a7c79c9ca84af58052a9ed61106165c7b53b0cc668c91e483400bdc190c497e421efcc407cdab3e009b5c43b39f0496bda435549d2274c87938950f24447266a7125525e1aed2c49b2cc91b82df7e27d17c42acb4a8a6983fc88f58d46b7d9469ea32b445894f8e521fdb27461c7852ea353f9df4210065dd35e2d9c75a85f2e5111fc3e0278711d6141fa1e21ac0ecd1c1675a8810d0e4d6247b9f188672863e6e790f18d23f0484f63989724366fd06fcec43873502181935e4cdab08b64609cea3a2b2331a070c7c1ab6d74caf676358beb4edb96744ee336ad1283d92d1877a9b86587bec80d582dd49040b8d97c388f1d2f88b973f44d3c2492ac786146d45d3277f48ce9b225240215dc04aa63dda3d6fa380be35dae9623ee3f04360b252dca1158084de417f80662f35d36aa17e4aeb14fcea1287c97de48621979abc751eaaae7c5c85c87b8b8e162de1b32c2bb1b8ceb3013b6cf582a0c78f138708ac02f82ba5b86254a804d62e15def2ad6ca1a7b4e27e1cbaeae4ff4c0ceccdf1525ebab522761d63f73065a2b53a352291b2712f53a085a6a69ff8160598abebd0d3dcbbee356fb9c72304a5fc403b1d0866df1ac25f10a781b3f5655784f5dcac48b098f314c6eb5560a7f91ba7d88626a262c3a92e9efb3c5350b97017cf251472eda927c9e2a208578d0da0fcd369b39f6222f643323f863003198dfbb48e7ea9f57c8c9105e3df1a00924f2464e48abbc92ef8dc6e193fe1f76401fa299d85ece1bc623de68cd575adb3d81ef4fc8c897aa277c9c8113dd49df3b89c71c04b5d052033cfb58c933b4a3b1db7a102b1e61003b1c9333a22981013cf36563c8a01740bbcc3337cb3d557f56a21522459034a6e867c5d3014565107f5993a3d7ddcf6e3218e3f4d2808accdfcd8523e45aa92b329bbf97eb808f7d7d8cfe55cac888033dc770106db6d6838144cfc33784185bfdee2b544a210ea5856d0a9ca261095cb90fa64a0a6ae0421bb84bbed2d534a32d2079d078907b41b7b161e27f62c3c3f0b2cbc8dcd9179163e07c7c77e08ad66ec5b1f699b1115c66661ec15c646e22eff19346237469dbb8a704dfb30657640cc977fd94e53e1b28097c7796b78c57214cb50421b2338e278992f411b632b7c3206e7c6c73e667358f6c64f9acc97e40d8be34b568acc8863fc7036b6c28fbd8d4f616c85b6b5e3c6cb3c8fd8dbf81b2ff3aab11543d812c0a98c00eb0661ddf04fb64533e4966890f4d46c2e312fea8d8f3d8e8ff9d263461b13edc6c7c6d6e97de0185b275b030e8e8f79034c5a8ccd1942fb498b7d3973382c0e7c04da92f027edc63b2ee7442e9b410377fd6323df18a7bb4e238d07c038e3e6c6dbf46c64264a8155a3921adf2705d49d9d9d1dda0dcb3877eda4549efd55e3cb8a53b1e209c78da71959d3c5af14d9084e17ffcc88c34e77a13e66c17bc3523bb60ffd03cbf893c698b16f7dd433c6fe7197ff6b6cdcd83646ff1aa33f2c77fd65c69dd71827ed354e5acc3869342eef9046f0ce1827edb35dabd10127fd634b2a7f39b970972128b40bceb9d908b056168bf581cdc3bcf355567da64e9fa8648ba8d6f26f9883f4b5d676f9c3909599197cb6ac5593b53a10c249806a63320d0d0d3903bfffa7cce4dddd3668ba344e1a6b4eff3cbf254d8f520eb43fe6cb69dcbd9da64d2d1bd14c63f9ea55a7b0e47dea513f7b86e5576a8b651967932bb6e423b7499555196793295b72ed565bf24e8a9d4da26cc9b6db606871208bfc7974bb64c58ab034f521247180fc8052bdff2c08e2c08a706c60e4b670a71435d8b9a18b383714e1f44c0dec8029e31f84751f305f2e03223a2d87aaf33aa4ff5ea7f4e0e7e0d7f99ef43ae097beff7bd2f300bff43d0f12cef7e0f3f86ce5675a0907640a5de6d551e52f61b118625cb64abeffe120c8c2fd6832a87a3606e6060e60bc4928a0548852214a29a544454b6813244c6168eab16dcf490a81ad4914ccfa2227e7a7f24ff5be9c5fe4d838514f8ffa7e8f06bee1b59933f1fdef94fd07dacc973f6af4e12ed75dd9f5098312e6240695eeacbcd637cb41fe2d48d41f73e74dcfe32576803c9e734ed1042e82f83667147402035610f81cd4320eda0df193a3db4c2b8124128934bf1f409a1c5940f587548444e28f3d8c1144a5f468c781ea7de94bdebde0beff709f8b102ae9bd2fbd34d9b15dfdfe7b1e2291ec64cad33dd46cd27168dc45fa5c824a5058f34ba537fda48125d3f308df14da79bba43fd96a69c4264d26d1863a263b69a02d19c975520eda6410d56fc94f7c67a39f490d3a413d4a29a594524a29a5f463044129a57169e9d2672e7a666868bee8f3a8baf3e450cc17fd6c2c5799ee947020667ee6259ef4c74553d01c9aec8a8a8a9aa350283a0a4507a56758d7326ec24dfc889baec85654a4d3cd59cca55c041de9703a5d8fae77743a1e9a2f286a1819dadd42ca3022256168abbb602c772f954aa5151d2aafe6f7f2f27283caa3ca0d59a422c34a2593c9f49594841606e3ea2c58106e04117d54708d222aec639b821acb75ba1f6e229542cef560800f197498889e73fe63befc439355b9e5d439e001a5f7ff3167a5f707d232531b71f1c365cca3ab256c51c7bb45ed1f0e983276c224f147ca8adadfcff56f595299c85d8ef8f78f3f8b556b8e65ab350fc2d9f077c2c9ad33e1889a9cee124d6fd34332385426c2b9d46ae93f9b9f5ab2976c6d72c81b576a9c151b17f2cee802c15afdc4a22dd4423df31500fcd20906d4b53dd4bee19b9ebff465e34a263b4f37d35d2590348e2e970d1b29340ee72effd816b5641ce37ae6b337ef2ef265f557ac6ad5064dfcc6f5c99327ce64f42028b5742007927193264be6cb59bb2741545a83274fe60cc5bb262ae9bf1c43e919b1c92753cc971ba9946140041108f4435408d7a43fac875a52212a447158541c03cd173f10e3707326733dbcfe5cd4363e32f213e3beec1ec67d3971a52f9ba7645cee968f9ac1652edcd0593487ca6ab2a50a35968bb95d56b1ac77759b6df97279c97cc950a07a34d6a4f2c3b8c81fd08e567001480885b0199b53853923139f41213edee0f468d26d58ee7277f7905b36dde53c32cc19ea48c89cc1ae3fef7ca96d8ce4c60ff533996cac05f52bd91204415b49b664b98ce00889cad73f5bc2163e6f6a50513dbb12593788bb1b4c3db081891206788082e290a0001138e839c31430e281d24411a0b8e17004d0f77d4e934bd2c30f92a46ca0c3103126484b90b881e87623e265f1658104053f12e67dc3fa4b583f6debcd72fe86790f8bd134654a433dffdc73184e0f06c0bca773a6dff34077eaee3c46347104a05bc2a0589243220b12113924a183d00e067078e2861d5040043926deb40406eb221663a2879f98981da2888949527988ecc09999ddd9dd9d999969683c0d908602a0446906ff4f29a51406839d0006cb75f1ffcfe38258cc168b318103096e446e44724cec60831ea6a84011bac8a1e8f3d979d4fb92524ae94729a5e14729f5cf632a38ac47a7a076ccdf320027c6b1580fb65811a0dc32b6a3513471230212518488a11da2a0906401030333e3303c146d202686879f9898243120724312277888a20230033d6cc054831e6a497c3840229764870bf4e7eecc4fc3a38d10d83a3b3bbbd3b8f3e74edd73ea6ef35dfaee43fb29fddca9f3c0c4a534378b1824660c762002c5f1081d818a471d71cbbf11d121872e8c409dc6e66b6eeeeeeeeefe74506aa383aae02450a0767377dfd0c5e522acc0bbc88188bf1199312062832439a8a03483588c482d166362061ab8de5db80dbec3751fc29945399f2865dc169f6d0b876afab25bef2508e3c79f2f6e59171084616de9b329ea8c8afa82508539f87e432799333a674ef4118d035f31654c88de4baef710d7cb06e2fa770fd7598b5bb20fae8fb764a3463dcdd1baf9f29f0d55bee1e700c15a57966d3d582a5bb2546c596f10088a4629ba5d0aca3600a7735106d3f4020781413abe27d4986141c67cb5ce6f37bd69b1b564d11b72ab4e39a1214db714d53332f57019cbfa0ba84b33e78b66ce405902686c2e9bb3bffe3ee68c74fd7fb8ccdd7987a7c60a7f08cd1f066b5201a60f4b259bc3b2436825fb81244b3609fb60f01d213803e8a1b62d8588ef3656ad9ac2d134f6608b45e509e57e5689e9592eebe16ec422270d0834109dc8f4015a29a5b3288a7528fc2d22a8de03632424ec49d6e350d8a53f43901c37a0c501fc9c2134b0f47cba29591c746e403b7bdc457ffe70179d010623c97f16ab4611d5a35588beebf67c6010ac3d1dceb448b7fb69e69cf16677c98334397a608222a827b8dea70fadce129cf0c5d7317df8a29d3dad18baedb4e58c62faf0bd6f3dde0382b5b643f15cf7b89115d78d9c3471fd430f9aaf13d4cf72ce0849fd8cc492e682f3821696b2a2bacf9c91da091193eb4d4c977fe94bbc67bec026a7ee368fc2db7c718ff7c0f0dbf5f9ea27d9d27ffa76e3246a6bd2e9116ac47b3ea736060676050c452216f96e356c5c68fbd6427d732ce6cc731dcc991e4cdac3a417981404938660ceacde9f4299b3d6fbd31c70cdcbfb534a82497b2810334774a34b5ca7435c37a23c0e84e94e78f0028441ade20afe712d7640e6ab87bac33951af1a4baf32827f1a492f8edfbb3b9117f58ccb116af8a5f35cff96911ae2685cc6ba26d23c3c466d04cbf8774fabc6469aecbe9dace842a3f7abd1f4479efae935fc3c960f5d5cad300856160b64befabdd1c4054f8aa7f2944070164d27294f3e9257ad8eb1a7ad98a7937705e9fb64ccd9556420f73eef46791666befa51a3f3cc97c7f80ed3c5c3352ec4323dcc19ef5b064234910f0ec494798f5f60ce7cefe510d75d89174c77c1243d06d3e58e6319f79c1234b8de02f7a3f972cf813cef7199385d420dc3fd89eb5acc390bdf95a49c08d7e0b08c3f8b712c3a3045e474db08ae0922c45d8e32e2fac9fb48e097148bf9f27f19690e58c6bf355228f3457124982e7fa21234bafe306c59734bd0dc4e7765a42098a4ff6aa42198a4bf6aa41798a4bfca487b98a43f0ed7d01eeee1320a4410aea13c2ce3ff81eb9ff2afb63c0d4179b8fe28efc1741d4c17e23207823b992ef737d9f274cb79e4856b71ff5e713d8593a180e39a7c2efc2b60cf63a0a0f621236aea67e9765e897141d5fbeaac5a71dfd0056adb12e6368e6bef311065222f6c405110992b5fb98bfdc16e5cab677d94395181c0ae67579f574ea315b8a254ace2672b8dbbffaa4190e5b6a4d445fedef34e39e88bd5db47d83cc1e04e982ee9c2f0274cd9b5eb79a0e9e7db742a4a93deceb2ae492ff645ad99b9de7ba6f71ee63d560ab326c632de7bafc36532defb1e2e43e1bd9fc165ae98f74ef8721291cf3c63e967684bd80d5f54fd34e9d9d0785057af52a5de7bde71598df782dce5fde9f5f5a73b0bcba5f52f3877798ffae97d8ace5d35c696cac37ed25e634bc5b676bc5ee679d478588d97a9f13af45f3f4d78999f3415136c6b07ec659e07ec65645ea71f66c1abf23c641ef630abc32fa3f293a6a2f25eea6dbac6cbdad196e04d8d8c43a5bc376d0c5b8225d812bc294f828d71e7b76c19e396ac73b1306cc96ab17ee7afd812f4bec610eaca325093deab2cfba4be649febbd4a2a65cbf0c1708e3570cab8134b73e4eb9a316386cbe59af193164383068d989898d7a14fe3ef2cbd8c134e384106bf0c7e19afd37fc24f1a0a636b7e8d9f34726c4ddbda41feeb79a0f035ac8e3f0affb23a4b70fc51781dfae44f1accf8c35d006346de7197f7ae710677798fc2d8c35ddecb1875b8cb9be13d7982cbb816f39ebc9ecdf36233c649738d93468e9386c23869278c9326e3c24c4b335f1ec97a1f5b721a12a3c55b28e4c89123ecb3fafefd03d7984834efdf473da37afffea267409bec0580f7d94c13c1beec5c0a5ff66e9cb4d93869b071d200304e5a8d71d254e3bcaf71d2f80403ca5fc98db7e907a2a6ee913943ddf0fd6929a8ad8b839f274325f042891640a179ecc64a57430e96930f35e94e641df7ab8f7d51cbae39106d815b9b3366f996af79ffd6f9306bba08cbf8db789957a1853f721cdfb9960fbdd6a4bbd778505d5ec505067aaacdd9e963ef369275c24f37e1615aff52c2cff9e3db1e77f98b3f5de6a9f0c3d8d882f12bfc10da8db10503060c8b13fb156c8eccc73e07070c976ded58e159f825aecf89b1257861bccb0ea1c1b02d1af8c2f8d27b8204d0a5ce3dbd4dc7c63662b945c17a8fbf07f93bcead0c5b826e4bf0a6de041b34ad2d63dcf0475bc6785bb26ef8316cc92ac192605f6ccb96608d215417eb46ac17c9409d4d9ebef422d71fc64803df932df93f4e8d650735ae75d73f650402bb2d7c63c61b6f635ce1718cb19719595081060d1a2abc8ccdb1f12a7c4eccd3f821b416647e086dc68cc7f138331ec7f3e368e1656c8eccb7f03938e68d19696f630cc0e318efcbcccb2d1f00167e088d76e363cf1f5be159b039367e85cf89f91b3f846663f3430226d37f365d7ad3587ace51b24141473b5dce888871df085e06621f9d0faa5d98e0b0a34401d25c1ced625fd49d3923d23290d6cf457a86e5fb5977e3aed5f7334e447d8e0664befa81a8a85f8da9f7d133d4b662a01f3eb52d01989eda21379c33d4bd115fe5fb7bac3ee57988aff2abd7099899635ed4d58b7ffafa25d7d3eac52f6b8bfe10da696cd1fa069834d2e69cec10daa48927d34fda8ac8129077e2f7777fdf0adb3063fa4b2313e121ad46aeb9cb961af93406dd6e206abde58c422defb81d800b5d2be110048d9ccd034370c2160595c28911774ae1c4080a774a818b72f90682b5defe767b1819d39d5cfff2759d89e64f7ff784c21bdc576fffb52d3d38652c5fb2e5edf3cfb2500bcb09088c6f4d967cab71ffb8f258275b5f68504bbe9d9e6ffe93e46c5b31d832e7da3408d6ca62fd93e43dfd3c9dbe84ddd369acdf1703298bfb3dd79aa4bb2da30eeb5b9e65d45982c3b22d56c7345363cedac68948bcbbf5560ac5efa7f3cd8665251453be9595adf774fa6aff9e1e65cbb725794f2eefefc3652cdff2e22db4306e13066b64b9b17ccb8335ef992395de1a76b03ceb71582ccbe280b692749734924e2f9074f7fb7aa34d191e8ce84dd5a927601ba069abba7a9a4a69adc6eaa6fe6875d90c56c5963434d5963052b4e53fcb8a947a49b82994bee98a8a62d82a65a396ed38ca51ae4877d4b58fc4ba263d6709cee9c3cf113f27fc936524a527f9f35193fc0591e669522772dfb07d0841e527b121ea674b98a2a218b6ca74474a42997d9875b026fb8be191e439ddc543caea4dd70a09f3d54f3f0fec58870fca7d3c0f36675336695e16ac9a22f2de7bf6a92dcf5b9ee9747a1dd19bb47a7baae99dc1db9c353165b719461b23992fff1b97d1b09b59ccddcc4da30134e9a42068e4fc08db8caaf7f5abcd51b8fe4c04f306e6ccf49ca3228a27405b828ce224ae97e0fadb380e02a68c8560db2c022ddb7474ac8d13fc8ea3529f77a87cea79a8d89c253829170f95b549d90a0671fd4b142ef832660d6360caf883a92fab0af83073667af055631da7bbc8fb00feef417ed8062adfcf3b1120c6fd9e6dfe2c56adb690a21e06f1c507ed9f40f061383d6861e62b65c82d8ddff3f72793686793a1355972be5aa753529f342a493dcc6529cbb66ae9fdf8d5831b506aa73ed5e00616151535f97c89fbb84f03f9fcf8e87c7efc88aaf3a2a229a68cb5d015e98a8a74eee33f3d535607729f9ef1dca7e6b2d6f7a59f34ffac8eb55c03df64d9c63ad04221d20a03ea134e188f529bf75e5a40d4f2e5d26fa63636ff35a8df152948493f95e402147e197a86f494d27749526777bee8d31f5570e9574123c5a55fdaa05fba2e9d2f0ac4cad0247d979fca4fdf4f2ff093accb0eaa7fdbc932cdb6053629decfb26a0feab7d3a4468584847a47a79833f621a6173167969833a614cc191ab81554700debfd69d19cb5bcbf0b316bc0f777db9c95de5ffea9cd1d0793fc41c2aa551e1db891af60720d1b9164ca98c80c885000029bd07c39b35075f910144be3caabc6d4ab8cf5c331e54d23eabff1f4a4517c705c3d0bb9cd6deeef46f40c1b1919f991e37eb87c03b17450505017b18c7f8b6d9c63b751fb60ba8cbab87e6483fff79d7a17825aba0d48bbfab900ab17691bd00e8611a054ad4660b0b0102a25e562ebb82be21a37022388a577416ca4c88b983e04cb68c008ca08d70c5cff301459483c710ab4bb365a89274ff253041ce386d8b2904dfc928576de45b8fe2b23cf17cbb0154f2d6ce432b0ae74fc7017d7301196f13f3af914f3e5cf1a29152ce3df32d2176721e9b9fe2b3fd77fe556380d26e98e83e922c2356ec432fe35967fddc1ed4e3a98c1f51753307d896903471762fa10b38849fa0aa6cbb9c68358c65de649a6cbdf054428b8ee20b8fe358c548fda86be5a0f61f5cb135c701124c87cd1bfe5e422c64ffdbef75aa48f549f07ea6bad8ffa492bc9fb7d9ffb7fffcd977f8a7e1d83cc194a082dd224a594a23e25c64fa56dd3e2d3ccd9e9e9a73065ac791a69e68b7e0a7d1415e95b932d652e2d91977e1ea51489570224cc840913005cbe5cd33c7ed43b2e763b2edcdbc17cb9c7c4fb929988cc64ce9898b2f6c18e99ec9830f1bcfbbf72869db2f01bf40070bdd18db8cb0f6ee47aefdce56fb23624a865efae50cf74ef1cf4909c6c4ef8a2e5d0b626ad649d0a003ee9bdf174e72987c73d7dd4bb988ff7eeb612f3e5f150b9735cb302bf9f6d2b1f1f2bf73932e7e3875a6add800fda1ca6813f84e663ce50976d3577f5afb8863730658ab8bdf297102ab515cc250122f98117d650a5d6443dd424fd90b62431c452a9d572ee2e9d01993eef3065acc574d1a7d49695f2f0cc17fdffa192a8330feaf4d3c5f7cb2f973eefe6ccbbb43d70291582f60e97b60d975215fdb24f70296d279772937eca5496e52efa6c41cb9644fab05627e56aae824ffab7b9acf5425ffe9c21b4fa93569ff2d36f243dc3b9262943992ffa75642377d1ef23660d633165e8d39e16b8a7a78759c73d2f2154d0b2117ca449fab124ea914b9f59375ff471e4503ba749fad241fdec4abc51043117fea45010c71243138c67666671d4d103308d373830461ad6ad0557c216d5c994b516d3e5385ceb4830770efa12be0277c1f5f71f7c306523607da076e07ae901b2395d258b7a9679764e2aa030f7cf6b21af89d7e4e320c4a07e9018d1fee319c0f430e8b7500ea5674a6fa1ec0b7d513fa9c021d7337de7153bfe1ec4a465447c2709a19ea95df1c4f5f7a223d7df7d4a6185ae654df347a5a823e99929450e0aada2a767a6145718b9148beb4f29a52d1baafff88a8ac5f37c8741d40fea276a045b5051288a84fe040afa11a29258a7a3485a31a8fcea57b61c72552c47b9f14375252ead7ff9d27f52d45342028fa691607326407379245fca4f47fdb4cb3ff525489f2271977f09861bb56e477c568b65b12b2bab52b11489cbdc7fa82d6b8aa3ace7284fe9ba5bfacfcda3b958278aa282f6484f56501ff5cf51eb884ae242e57210e88dc54411736be994257ca3a3496f018b5ab2ae4f9c0c2d8b791d37739672fd771860cebc180ccd9c7d76ce17abc99e7976ced74b9332b14befcf7219f830b7645d2f46c37297df528d1054ca1cb0400e8532d5b40d2827ffa4888da0d422366a7faffba71d1a731638bdcfb01ebc2ff3e583eaf6c611e352e0032666cfd9b37bce9e73ce6e1b179ab999b97904e014292d40b8f33cc4433cc4433f343444446d35235eabf54c7b05c896e7f3064131655ef34a6fe21f2cdc6d5394ec741768fd87249ab30e4215fec50ea6cbfda7f5281ea57679e7dda6818ff0b43667df13ede6cbbb89f972af68a849971faa13302f240f2f7487544510346a4104910379678b51c2d6240aea4747425cc89ca9e88aa4fa78e55541bac72ad730df71766e21425cb65a59b6f51cd58e6a47422430655c85d15115e2725455fff54f50cf4cdfa9b158beabf5d490d46c38a3d54acd68f7e44888cb5646b926572ff4e865f524a732325259d6a77a57a9beac2adf09b9664b61f2e4c9ef72d57ce747cfb4543fe4aaaca35ea5b26c345ffef138db5a06f5bed21168c2c96df01d36f21da3175057b592fad24fad1d2bbffafa382c0fbaab7e68fa4ad8a2be6ec946554c99d19c91bc16840ded2825abf7138fa6ad2cea74b3ca4169d25dc6f5f7227ea4f4b29aea5bc6366a5793290fda00d5d277a6ca966ecbd1c58e6ac72b10c23ba6934d07aaf37891399bd7891429f98e0a6a398f5a4c508fbaa84957f5cc6c52e5b3e1402d7dc789f44cd965175dafef0fd6279d76346dbaabfa872962095b54a6816f6abe5c7a507da76752ef1f56b1842d2a8cb7b3a342d5ab1e1c5b5e739bef388f4a6aac22db42a01f9f269d67be8498b71452b061c3e51ac79dda8ea6adacef18f98e110dfd7652eda2850dc816454e48c805a32745464517e49acd87cb6a65b19e795cf05a9394af0b463d7ccc99cba52f43ffe819b6d18791e4d32a3c77a709400827cc0b0e15254a420c46c54874840951f96f9c04f3a1420511944091830f1c410716e726e5514f535020ea9d887d42b9cee2f3f39c79cfb60cc2371c57620e35fc1a60084f31946e78bdf9e2ff38c7c98a76ce979d41f886d60f70821c0b86f0c31345788086001108c186274458d273019aff4d0f25a8075d86b237dd44b5460e6ae9c1c769929f447ad0de90483d48a41e3738373d43f29b1efec22f20039c32e539e90d114c87165c6a2751d8550b916d968b56224bbc81ad892d8a2068e45ac8619817148944cbb869b480a982eba20f19bc2660d6d8b08ca75ef52befcf4c804896f70f4516fb94e3f42ecc192ac7879b2f9fb71c724b9ff2a52f61b77efdf034ce1bce1e414df2a03613a00c00e9501f8a2ca6bee575549e95b2658b06be3497bce2a9e57556cf527d8b9d34d1b20b5c03d2bca8e534c28195c507a29e74b8560c6cfa95b1253eeb579e656c89b6b5a3e5599e07eb57bee559809c0a203e0d2a8f63cf98126c192190831f8679c113385f6c4b20b0907b36aad4b9a12500bff82962ca7798f2b61543f8a787a1da949427fda9f42963e9f94793a5d2cf57db64681f0c68926714e23fdce52b5265342299c0807e01a5715ef0a644ba84de505bd862c0d4908f607567e9e7b7789b64b2718d0100442db946327dbf2908e9f20b7e412f6eb9a260df10045b00422d63a092908382903cb40e922f2c1f54cfd6180e49efdc45ef3fd22934956e7c034d1c564ba90e014c197b00a7a3e4532b1de91d9e1b8b55eb8d75c43b9dada7a2668e7b1afc2a7a3831a5863e750453c6fac33d4d9a7a4c162c3d8b552d6dd207eb346f3bda086f2c00f7cc5ccfccf5cc5ccfccf5cc9c8e79741dd73d3d3da59d26bf68f2e874c3b70af372c54bef4a9d2245e8f3d3dd517661eb7cf80443b74f18daf073d8862dd0045a3227358416822e4b3d087ed8a91c1595e74fb18c34fd2aab4fe5a87ee59be5576c8eea4b1ad5b8ca613295b5b543a55a49bd8acd61f9d44a05fc9cd4aba87e6573545e659f65650459c8956791ac9e2aa4d58cc991384b07b62ec596ac684d3c52a19ed181f49d1186e94b53d63af04d0fce99587a81bff41f96be8652fb700dc85a812a959405439b7a9d50c5eaa82ce3eca485395aa657fda4a5522cafb23aaa67515996d729499e2f10b42518b6b05a5a58a0ca5cad4cafa3fad46a65649b4acba85a7993c559fd8a9dee52fdea4be6619b6a0cf967af5ee54d5f5da6b3726aed58bdcae3ac5ec5b2565e65abbb4c29abb3047c9dd4ab5efc77198bd5517996d68ed4ab1e27f52a1247e5596cb832f6f0d4ab7c0b7c21ab51f5ab37c0a4cd90a35295f3486571e023d0525f4e9d294c8d25d13bbd80baed335ffc65fbdc179ac795eba517c7d685a5eb70c32ffb28b46093e19bc60798c2d11483f8e0c3205ad80d9db8a8f40d564549eb108d0c0000000053140000280c0a86c321b170482a506269ef0114800c819c467e58194ac32c878190328c10400800600000000000800c06b60067e52378efeeef8af6ce3df661e3d0a0f6bc2d9c676f5aedd8c91866c5a8b36e1f9330f36dab32e20d9c683221aebf27eec3ccb6206a3ea81ad132ededf6d97e8735864bd45153fb930d12d4825951010a8fa3b2710ece8b44f8d8864f06bf5c0478811239162c6369d95a3a803fe7ed2f73833d4e5a64fa1d6757cf72785fed36878ea961f20b2d98dbd74785d91cfe0dfd1e7130d20566a5e599eea541922d9cd3c6126a21645d4371ed599ffa6760de6372935f202cf1454fe2cd2cf5f3c8d1a35d1149ef669d78810ed02892cd4329602180340d81b1ceb45dfdf5fb3584729f941d81c18e7eb1d1f53c15a112ab9471fd82f76a3953ed2fde2d2caeef31f4e4d5205219476a1ae5f687a6ad65b69516e41e02ea7405f53be2543414dd41667b9d4077405f8f81cc77acf262b6eded216b63983b03985f1988b9d79bc8fb2eb48785916d82c8f7e1258ccb94791eab0643b282491fb13bc47cab4d8b2734c77f291f86af4acad01e6f48eda0a19b5a43d3ac8e29df630389bc582543d07f34b072d282e831890c30712daf5a0de16f03e4a6afb25de6c6fef1ab0c2dbc7faf3861c5816a6ccf54f83ce53d998eb7aa4216eec29b3cfd8b592901a693d1b093c0c645239d1e9f882a6ea669dc84a8321360fab16a5f76f6f6646db277badc0b9ae5428f217f101cc0840790bab7e4aef40fde3d9d99d054344197387c6ea74af118ef8b5c885d555dabfbae5176561d768a695f2fc79a76ff36766cfbae2cec84f11dde73032ec007711e4960ddca039de2e9c5f84b5ab2d5b62a12d53a54b538f60b4a30adf2ac58676477f88608c816cefda72131e03715e670797ed957de115feb2a3ebe943f481d07bd0d12e884bdeb27046d1bf42fcf1b420d5cdbb9a3b00c12dd137aa5e6ca099058a6f21347ddbd607b2a7f508906a95d9627e228348e1e76c34fc094ddf8c3e14e4013b1476ecc64cc7343b78919cc43c91e2a8c768f75832afbe68fed0423cdb278f5de404189e14273e8ef87024735f04a6639a0abaf0f29eefd9fff8daf7c6f2e06fda1ee847d5150d15aca4d1e46bd240c372ea158e0c4ab630871d02a2eae78f583bcfeab966e1ea96ce3744358ddb5557d1a3fd3bceb8bae783e023211d96bd5f046f1d3bd295f4b7dc440ba8310ade9ed912ed4e882749f9b933c7360a32a979107ad8ca61a6f522b03f09fd6916c15d7b61245366683c8edc7adc35965cbd202ca4ef79867cb3a7c172c6db131d1d63f62130066a44a1e47f8ed86c46ce84e3cb6c54dfaf81177107a551db08fabbec332e7abeff4eba6a361851fa1cf4fa70f1d5d55f39cfc78b7c2795429d2a081f51d8b82e1796e67d5773a4d95971a83c268e71552bbf4aa42de5728846690177593c08337b8f6ec630eef845df237efb6b056b11d87416a1e1fd61680ccce4ac7cce508a1b9475a5a2879caa09ad4c87dc7a9abdd8838eb6d0e48110bb324b18221456c812af5a20b207ff9a91148f04ffcc1ce57681fda296c47860dfd76d9f0be05cab838f4da4977f97a8dceeff447048b12bd17c0e46d42656681328630682f42cc0237ccd0c32ac6110f4db38c48f8446f44e6fef0855e79bf71f9e6672b36b811a305d27e67466ae89104f785707ee0cd9cd517f8f1f3743b516b4d1a1b9344ba634faeca04bf953f819e4d2de32cd40de424d8c3850761e4b94ae02e2aeb8be30e6fc9b83401fcd5b911471f98fd9ac6caf0e2a6307afe2ae4e0ddd145b5c227a1db4601252c589a2a162f94020994ec15b80597f8f386dbdffc7f6e379440e344f749a7b069fd8f0356faeb976202e33e43ee8f835722e881def7c15b4f3e44a4dd235fcc367c7718d8ab4e65623ffa9728410a56def540212101f8c21e2ba766c32a7b5d9ad61e69bb75af1ac697796c12626b175c13c6f1d8f2b2d8a4dacf800a5b79db7ad58d97d810549750620b17e4763f83af65a6fbdf8b9a0ebb0da34b7ddc857fe715184bc4054a7ea7f1195ef633a05304cc3fbacd3906b4d63a6acd33587ec2db381208eadc3a4e77205b764504cdbdcbf0372b4c90553cdabea89ab8164204287820e28722ea5d4967a3841ab4fa042e7924aee3261697a89fab6ef86316d8d4785008ad5cdd506296c67982fad455d00d19fa2f180b93ee6277bfbe4ee644b3d966d00b5803cb6007ea1df0371776a6875c4d090494c0d700150367080373ec8ee0b2e7c03c207cdb8b968a3bbafa8b1f54629f8e4b0a4b81036c4233fc3b98a1613e56b4bc4968c98ef40c64a71310c60192daa8caffe129efdfba9112de9ee00454c583382974d2a9a1f27760e637a1b9ad0ff70191f183e73dea290dfdf53d7c00af2334a152215e7650fa00a3c4db4ac89c1ffe7a85e303717e442626f5bd45de840f8c37235d0e1148c2dadf6c82a8eaa4baa464438b3a7c095cf616ecd7776b3a608e12bb85545fae7b6ceadf800e3ed42ce02c66ed2d932e0f78220eff5afb2f941a86de118e2bc93fc7988779afe8298eb5a6c9f7452e454111cdea472339fc47680ab31d11df60312e3b7b7a32f9896461e5c380737a2ca0f14832879f46b4091d76d9578d17a5d126445a147e183eddb775c94117ff14cf9cdb317649cc8f13a8086ac1f1af9c33330170ee13314ef210ed60437bb7a50b8894f6804dc9641ee24b5ba164e9e284954a9e06e72bb41c9d4e6c7155226ea9949492be681a856f312d15a438ff75ed07c2b9b2a6dbe18fe4cd6f6957e918a854e3933c0f0b45122ed5ef46da133300b8e413c014742f5ee650a37b328b0c8736022beed9821c88895b847cc05e5718fcf398c78b88c0df2570987d16eff86cc0403206c9c108d907018dbfdd23cbcf9369357304af2575a942502232b4cefa43fad91d81329caf0f9f2521eda51128cdf43d23675d04a6ce5d64c8914831335c0e15817bee3842a2f25a2c5d3d9a00a39fddd45b3078221a1b0375d2293ebfb3dcf8c4a7bf17d86c82d44ca87379f00cc7603f619178cfc02715245a42088840122ff7c7ab46dba44be3305905f570970e3ded065d4a113efebf67b6457d0b7b928c3384b17ba00010a947a40239a759a8c2e07ca5925213b8f39af2f8877bde40586e50f30514a78885fd2676c80b5a8af5462b033e8b5e1865756d041fdcd8faf34f20030c6f43b85eabe5b58fb05a9e9f0d3e92e7c6200e8f68717e1ddc41fbf5ee9fc9c1acd236cdafdf17d5407590be2b3cdfa8c25257447cc04957cb1ebeeb813a43fbdec48094391ee3fda6b9446c941323c7c769cc02233ab2d3f21f017b89f7b9877900851e038d108829f69af3b27734f344dff24b0db9d5c1fe3a78d98d24b55ba4a1cf1a045d3e03a37fc031ee1b07b33c01b03f8eeb18ebc5c374ff0f20820dbc55c798a34d2b7677b436c07aeceb1fba096a84cc39635f7fce041db69fe6f618fb77b7a1cca16b0090680cb0b4a9fab3e50509838ad4e351ccdfc8abaeb1aea2f6c30ac89c81bc196e29a709d14127d11c411b0acc1c2bc90555abd79b08e5b474692d8e0f261de10563db9ea05af21527eb93ff8849872c1befac504e2d5a7c2e7b2213006dca588a2b2e4e3bf92162a10b6c980391478cbf43e1bd27445f45c8d73f6809bdaec0af410c28009f22b557f5e5b504eb62c24c572ce692456956c2c146a154b4c22b5cde73a486a95d0ff03ff92850b2ab66c8854efef002d2670592818d7028025f41f49a797789dad8d3b309e783f4259b1c3d7753c5aa10360ffc055a8b5c8193e9af879358a6c79f30a0eabb11f113c810594edb9c6b99b2975b27a31e0dc12dd7e18015f839ac0fef2d3732efa2a25673aa6bb023c228cd9ca6810b8e49ab8fb91cc400bbf5737831a2b2c1f2ef2b3742e735e7db9860c43c17a6027faf3c2f9d1bda2253f569113e4cd18af6f49a3fdc869f6b91e7b7b252274af223b81eaa904a00052433d759e0dca43c49c360793f1071271ab207cc525c773b12c8fb60ea81fa9a0e48e1b3e6f051815cc804b17931701221d2b4da0df958654c70e13dbcc1436834796bfe3fec59f3752656808b6e3d2e6655904b08218de8ffff318e5e7d02d9ffe49ab0a9ee1d97fcc03abe938428c266169f8dde85731ddcd39a00f6040d665580cff99665d16e3afdd3418f45393174336e246ef64a24ff9b1aa2d67c3f559a59126ee1f2ce24103577c17ec41813c8968421862d91c87fca88490cfc4ee3c0132b20d151c502cccdb620f483e8493d85a037125a19caac11ff08f089c278b6909ec46af983b65aaadc12ade3524c9550ce188a57ad752f305b170f5ac9ea826768053d09813c60d474417d85458acf9b7e9da9bf4d13050a227f8752365c7560cdfbb2b4d090d88471521657468884bb8b7468eca49a5d6ab1c03055752b2b07fa530fe587f5240e24c677a8155e118e4d7aaa91fbf9a8b0545952aeb182d9990f7411d8d5985af6a17029c0b4b990154984e36a5056923cc33e9c67dd7245e68a65dddbf66e8983f434dcd5adc75cfb96e06d849ce7ab54460a86bc390beb1a5b8523b87eedc8cf06295c1bd66f578c55f8d170f4f71577d7ed0cfca778f42c3879c83e3a5da4502ec80b1e6eb8160515800d7ab0fb52fd2274e7085f64f3f96e409a0c3b4dcf6ca4cd35df427430e498a43d324ec3820fc1fd82b0970194e4efca6b8fa13a7a814920c42d9de73299058a21423d75c007eab8b5517d7a3ef9d9ce3e7bfd565d1edae3c359e332dd9f5e4864166ef6c3fae19909bb19e5ecdc19e185eb9a0f4962ddb5e6c03fac1238590cf852bc2130ec080ec44e1fba0a8190b174b0a749e8e781f83dc9cfd68deac743a2f21027052cd93acb95ecfe45e04618374b87329bd6b5627c63f8293c16f467fd2f1b1c254ae4a29dc556bd1e829eab4c6439f1694701e80bc59e8c70a3888b3d2aa1c7588eba84847c07c38991c3eaa1046d890a14866cdb297e1ea66d924f666b5707da77d0e4afe79476528c45ea3ad5807347d09650730938ecdb79654235cb045e1411cd4a24afe9ed62732ea5a3c3bdf434f8671628de56dccaa0d873e907b8f1facb82567bf091975b19668f96289cb75d7256bc80c8155a4145d0616a67fd2bdec45ad325e084d5205f5871c6059ea8029169222d050ae10a9ae3a112ca428b2a16481cfdefebc0541714660dfb57d45d7957b457bca71efb5ad380adb8f478230fe3ce44c06234a43d8427f0909dab0f4d75c2fd19642a77253154ef3ef9d849a43dcc79c1fb69eb96c02805afa44cef945f6e281d1bf656285e1e00bc58108bf9a44d995ef3507f118e9060cd4269b44c06fb258204f6bda39ba59fe4e4fd966f249d71e9c5497f099ea46ab3c911a36c2c248e0da5a244b0016f338fe7f0b64f98159dab73177adff94c6da6a87dbb685e226688d63d184c94ac58184111f29bd4eb066fa13701d796ffbf97d1bc94dcfe94976299e7d3cec55a59c0427dfe025af371347afb9fbb25c11572ef28023cd5400cef3e01d4ba851fae1ac9ddda994136e3d34abf865246275037ef5b858842ab0b4da1805d7a7d24edb16f7949df58e52dc40d7a9bdc01307674e1f0dab8d22b6c245a18a330c31ff293e6536af85e625c672c8d4d69d6a8079bd644c3b7015da2c1be27aa8dd071219f81575a42a1f17a19f589e00a3a3a8a172bd2f7e3a4ea092c7bc77af3e6f095e36d90217cf8eaf28dbb93209862444c063b242955d271490db4c6ee2b0c59b17bf87193be75e95fe23c411a5f285e2537d5a18b6f63b492ece22b8bad1be4d53fce6d52951349d9cdc52c558b375185d5ab692b2f3bc742bcd3caabfca80657ebe5037d9ba32c065477fa893ca5c5cf1dc18070b67f295fe0ec0d8bcddf21786021454d3bfcb5a5fc31aa535b6fc43764d2db31234461416e0ee2c887e1dba873a8a4f943d6b04df983ef863b3f0a53624d2ed09f99aeaf8db381e0982ca7c76fd277b830195a5aa4fff040a2011851ccf4d96b8cf8614ae0d974a7455f8c9afcd35e54e41944894c9633dab9cd027db7084690ebc49066840ce4fa0d8862c883fe119c0e6adf3e669c1482c97f12cf1669e04cc47e3a0fa10f597abf2e62be06fd50423da27c915dca21d7cb1e528a89c0b5c780fe62cd3b173fbb0c3f6d045ad66fac122c6e83c988e5cb6e9b3ae453c99fb89967d14ebe87963440c69a39b5e7be89ab6e0bf1d77ce7585097e575304489ded53a39e6152cd2c44b0f05e5953e15993e6627932679be6dd8f49efc0089db8f2330892114d862a5cd3e07cc4fe1257731ed4f3a10d8f1293ba435fd3279861aca5b4ade68ecb3e9c143c31e916bbfa4a4698a49722d4282241e07909d04c9b3a9ada31b6f4d3a38e9c5a1bd4c6b57c45b88ad898a9f96b4055a00a5354c1ba5889cf4ca8d7673496a36fc42c72c921e6ad3580cdda203876891fa882cbf7d2b9d12b9d02782e23d535a67921d3b9241285961902bc203f510579115260d81b34f8444a1ac09b329a91a4f53f499e4d3c0df8a927d594b1a259326155ba9fe4eab4bf9e03c6d175e36a6cc399ffc09784ac99117916c9c9bb053e52c957f492d797a97c2ff6f0ccc5a539473ef27a206d2e2d726bf28d2a41ff0302989c4a5894a024c0d9a5ad9d8de452ac5d4bd0518dfe2758ccfbf25e490628edd1b73234f7c4375b1bb162e6cac86bf3fd7615942cbae34adfd0d3b57c673b5e3174d7e89d700c91c0c8d05c2dd4118eab3628c38b1d62088ab948180f4d7e31ac279dc7d9457264643389fec0f4e1559f66017598a7a9a3ef562eceb2f276ccaf48fbaa928193ca3fe7acd2b2feddda03226e9494f443d7a72cf10f141ec0884eb5dcbc3ddf0eca2697a3fd0420370b12277eb8fd474d26350b17d260cccc18680cfdff3d4e81843089f700234cc62cf677e4e7293545a1828cddb1d8ba48e766bd0499503d13a2ce7096367a28db0257c8ebf4e084be2808c80ca48981af432fcf3ac75d9fc54a6c0721e2cc92dce03a589a5f44e11f07887544502bbc1c3b3ad7f8de00feb283be936ba2680b7a5874361de4609fce9f6077414bf92c7274257fc6f0e21352b68134af1b1ba7f56e0929b60209a3d6029d15e14f639ae2d4233b79e2fe4f240d49782ffd46b57dceafbcdbe7abd257570ab83b449570d1aa4cd635fe4a7b4a3ca862c29e3c88f834837255dc793ad868d110950c13b0f9f3fec0f7a1a9d8fb5709b512f28fcb3666e85fd3d9d8a20854a3ed73a7569fe06254a9d5b04d78a10d03bf558f07e34c3dae486eed1fe8183ef28353e4f47dc2779a4fd9e36744dce91249481be123118dc923475efd8fcb4cdcf508c7011dcbc3b32ebb1aced0be69c53525691438c332c83397ca0353ef0b2f18ac70fc4c97b630098bc2d0d438eeb8fe2f91aa15024dad31d396aca897ab06c1bf4de481bf62bbf6e3b03232c636c66d9c84258649c0182b015fb45e2cf4fcebc968c6253deed68c598d34e7fb26a7b1b3d2c4eb3c1a87912fc3039c9a8424a926b26745afa5bb5723aa775afdd00ad101fdb69fe2d8a031ccfb13da4d0725ea480173950c6f347d34c9744a969a630e8ae295924d7351f4c9462e12ad58e34ca6f3e0b72ca25f9d4df01cbb6ebe4ce30eedb3d5f6a61093343cb31a1acde763ac0d085661fa3267d79605ad09167472ead9a2384f72577466f71b1ab5685d809c8ffaa8c99c55ec2acaa693da121dd8618b5491503c1f6b8043b2352adaeae41de25e9a1faab7c649ba04d9d90675644cf9c0f747fbf3dd3314f3160f6487ba50761a419edac2d73dd45a3ebadb01a000675b2efc25dd3f36255c3b192026dbb73bc4c061e1d0ab76c30a5eb9d42136e278a4eddb42cb7998c39ce4317cf89cf8ea190b360f7ca5e669015b7bbadd316d01309d7b838bb81d3b4b3f4e76d2f4dea261ed6d6f4ca16687f41aa8147cd4dd7a86f24d1dd8416cfbdc6a3c50bd995c91de9505cf44037bf6e5ee995dedd808b1be50f2fb715bf6b40ef8abcbf0803e45a8fd9b6130d7b18d63de502e79da1bb64ca44a2306f08cdd6ba2b4d6642927419fa0d02887b7b47c8eb6e335aa6eb70afc128a80c2d8e7a53545cb69aab3118369b586e6fc9d4ec93c8b685cf44b99c166b6a4e2951b780bba42bd382998a03d4b871511a243a0d7b8d363efa2150bc7c179b96783df6256ad7b9218d2cdba7e8ae3c6320da173e3391bcca448793da34e59e75ca613f3d19b13da1262caea79b358a8ee3e675a7ff15ceda90398739bd7f9d4edea3fd994da7b1d245bbc1dca9fc3c8cb30f77748a2c5adf18eca3a8308801903151532e7a37e7cc9c075ed2018c73a7623bdfbce442ea4f24014f9f6fc60b43cf7a8e10a2f5ec551760c2b3b9a1aeadc0347f2df42d8144cd2ee0ac431caab05aa6343016586383740b6ae99caf59e505e9da9b22e72f30fb3c1624c6103fc3d0f67ff1d532801074a55a898dd86beece6332d5450be432840292b5fe6bb2bc6ad08cd7093dd9cb0963ed70aa6cb71f1c7f096f66177f316a0fdc37f4c83a2e0829ef94b521adeecc2ca701122d15c796899202e4cccf9a80036950424e527225bb72f10df2c12b0196655d660b0a90d9eb4fda2a02a5d79af36cbac46c66878090336acec46ee14aed34a4ca1d7f188bee727b9f41a7c625eb5946b50a7d1a6243ad33653488ca0778021276c03b74c60fa88b987d27bf707a7a01d1caed95e3538be2e307b028d45c5508f928616fd38cb3b1863aed731c68edc2a8786593c5914763c1505184c4937b79641888f2697f6d6cefa55b86d1d55706de29bd2d68819256cb7b12fc05ae6a9fb079d3328fc10fb909ec3070a34d3354545afc765fa084b3fa8d54be8fecf114cafdf20918c7c71422aa29698003b75e96f56b5e4f15ca38d2e127c85663f64330df1f6413f1437a8783dd01507510e5fe35a18c06327c25b701293fb1ec10c0a1f7fd3471d85a5df3bf0eaaa53d419876a2b49d9b02e433505ae31a1ffa63d27f4451f14243aa9fe22b51a5c22e38be9f853dcc0b94f4811a0aef042871cc30e234540784253efe4aef7359b5310b40e5c5b4591287e9252d9bc6425c86bb838bcf0be9bb59a457976e40aebdba5ecb22f76756411aae38fb5a485c732d13afad82d444972ccde77482954e2568e37cfa1dd292c51c0a2f9fd08537fca06446f9d599ce16ebfd31468910ff384dfca9c514118eaa870a2d73a59447b6cb96e7c7d327c5e77a76e0a89cf6a10a827dc59c865fa1ab2541800f095e8cb465c66c58d8d0e1a96840efa2ffa93ee2462e93bac23b0f58d0ae6ade498c70d60e635249c07650f0ead0703d5715a2d70464f1d6fde6fbfa18132e09aff1b0cf26121ccb03561bf09b2f7f0df8b0fe2c540aedd071fdef3ee77b68cf00f2d68b2f0d13362cb49eed516ab6a2665a302f212c5e51b36aabe8ecda78ea63e3b58108aa2f782ad76528269dd77b18c84bdfead83ffc3c0ae6bb1d575da491fc27e4ea2ed1887e81aa415ac4c1d75b8888af0ccc3ba1f8ef0dfade0b4218291ea90873dcbaf763fe73a1aa7c8ca05f6f3077f3aa96ab77626745b2d1ce0f676c6faff80ed30bd032f93e01784a7ee8bd36801f3aaf1bed9dae520933a2071a310073776e380ec79cd86485e3799c99699dbd717f971e224d4330ef953dfa78902be01e4b1918b5dc068315b477daa2a8e7f9980fd725c51025dbb02136056edfa02dd5d61560973dc385787037940a6ea6317456e26b1374e83b3bc92a47ea3ad5d143a76ab1bb7dad4b52b69ef77b4ad5557ae50c83cc9d34c372d5145584d0e62455aa148b015d8dba210bc8e3309d3f9f88b45c97ea31115e52b2f79bf23ef3246860b2d3be34b28038c0553e4f6a773731dd77e8ebf749458019fe8d2bb0edac7c6dff146c28098e9245660a921024f91cedb21a708f7d5c171c8e3fc4f847ec3f43c19ef9175f7189e2e141158db7e1134c0f18074ca4b7b31fe050f6b4bd264a4921e2bed60e34acea0d844030383d847ef7e61466f9744a366813da144e455cd623ec16ce50e8063887c13098462180e13089914ef93de635ec66a2fac382828d2d6c9f32a0c3cd14ef5e0a378f218678a896fec546475c0cca0ba7d9905c0da0be2424a622c60958459785913e546d94f302dba5f00bdbe4c6bf37bb1eb296c435379beed73562c3f9ab35e98ea1608561df7b399feb7b4437110eda32e29129abc4bc38fe33b68c08117b72e0c10d02dbf32f4e30b93f0635d2dce35c1791114af1daac37ccdca6ae1b0415f635c140d1c9634ad8b554ef1cc2807a3f1c989149ccc36cb8b0128a305c984e22c2c9906753a5eea1000945caad5ba676a5a52cb46a55de0a9869e23fa53d143b07e3b76b134a569e82aa618713592eb4b77d7a1c7670524fc9d9f10e9eb2c8edea4ba42ab509168a258a8d2a28432050cae78afbba6c667d2d6452c0a692703924ae8ddc629143d823f8747efc0187d5d7ac9de8d828005db78a6aa6ef69819916a287162618abce83dd79dcbad8baf8e689175e29048bc330a9f43c0fa5320f0205625bd6697c9f1133c58f0cb8c8bc16cf5d901479b3854d7526ee32783ffa21f2f0ac83e0cc3654a7cfa1d814ef39735f693392407bc304793d2e918ebd4cc2bdb43428cf932132adc9fb845cd1d3f5b8bd951dd1b4e766eee775951598c4675569a0f6d94e8f42798f4dd2f146085b86099086ad72d8c98785b97daa99e95ff2aeae0967cbe61448b30dd34e0269d65f32e0a906084fbfff862c084815d9b67081e719781b1e81f873968730d576046d8408f40a5aabcc508084a6bd1de8aa5bf534914fccbada5e9fd93acd04928d5b447cc504d19b7c50a86db24c4f9d98a2a6f8558a16cdc0de9d5095c07fcbe147ee3449197563ba00bf0f3d09f6b64ecdb3ed0c407da82869ffb5a4ead4bf474a798a55fa1c5fbffe9349ec40771b6ce1cdf134da3ff8ce1c4e933ac14782d8744bb7281150b80e118833f6d9b016524d2d0aea4dcf01f7ad09aede1b0113f31e2e9deeac58bb438dbe6e53a1ab80021e1c2c561b31f86d0d97f3cc955ec89a3f942dd0633a31c168be06d61a2ae6868d011103923d61d4bc66dc242205a0dabf02f827c0547963cde934515989eb74e3034003582a2973d960dce8a33839f0f75e9a798a4760a56a8c85ca4dc92c62621dd845c76df37ec6c7a812556c3c1fa2ff42e6505309838270d657d89420f42ed1312030fa14e02b206e186b8b401a25fa44366a96a48511c474848c940bbe38200b3fa11c23097843b585367fc3253e0cd2c8c3a33a61505a36742f5c1e68e59f9f01bc6da2f92c37afb37f1627ff23626a818c87d25092ab897a0190118af5541d75955a8c191f1f5022fd173ecf60f70e40db0f9e91175a72bfc841665fff2298e67151a3741213969ab3a94f4c8426e98026e3bced3755da255077e67983d77e937fc4e68ef78172314c5bfe766490d079711b9f7997072891fe36fb8581930e8069934735e6fa3cc51d105ddac33d99e04381d478b1e580e7561c0bb0dd4bae1e88f958f7b23471c56a1450d36fd24105ce139d897d7ca406a297d170423893f66686734543bc420c42af17b4124cf8d5049b95d805a770dc51b377c6378493d67e0aff39863e27273229d672e9b8cc25ff752596031cc0d138f31ac8330867b18c7f8380a33ed0bd1cf8137947752a73b60e6649a03d1e0dcfa13315696a73209e1fe61c32a815c84715d2442163609532d452e8dd8e72532e4fb30fb29f55c591c2f3bdcb20e08f008de25683eb291b69b2e41553db25f1d0efcf94ae20687577aacfa92c267309a28619f534619ed073fd491584aa38c200cb3fd969501597d793e46140379598728dbdbe77c6b0c87dcc2e5aa254955e064b7aaba9dd5cb42c8892365f43e555952c3577d27998500dbfed6f5b3d15b8514504d0331b4d01329f623f6dbe83451ff3dc3107aacf886b605d141c6c9caa73f8bdbdef9b635098178e9beb7fac5b4b9d878a2f2db85a3582d01fd294589fd7520195ad6ceee4cc8e2eb34eab7a47e1ab56af079c254608487a81b720d3f454033ba4e4dc02463ef8599458d26632333b0eef932c53f112a19562777a92bd126c69bdae75709d6a933c3b5c5783c4c4e00bce7120866a360df59e70899eb880d74010c93134c997ad5a5196386d803dc7eb3642b77494dd12a4ac3c6d96f6521cbe12539b96c778251a51ad3c4b9a5e68fe5c810858dd1968c5f22e62c737d16a6133c7907bc0a040362b533c5b5bb1897816884aa6d0e3cc34f2fe6d34ccdc30dddc2441740b1675fae3859dc03e711278d0669a823a80915c97f0a5be8ee62b6fe309e13a1f374f16618e1f77339f3589fa64833fb38537dde719b5fb3b2201f8dffb2ac9261466353f211a7bb05bfa839361bd91c04044ed49400170c2a3f55e891303431166bbae9ba6e1351d88499accfeb764c9d003af29907bcd8079ac0c0987bd369926e95b92125b9ee286e36aa46145c481d1eb2ca15baae34f2c72cfe33d5f36d406b10c90555fc1d6902c47f89471a9fbf33825e0e5f023f55fe4c1a833242cc67825a1a9f6e405aff1bef24259ab4b06c180809746a697638fcf2b54dcf27b521ef9f3a0c940f965f52d393d4de253e49ca583fa5fcef9cd8ea306ed042fc91708a7b1eab7d8bd2f0b35fb8a57a9b0637504d6422164a1b6cc6756b7d1ce0f14a9502dc5029b6777d14844bd2a75ee428153a390ba4b86a889bb700f0b4f47954e3bf145d98ddefe75ebd8331aed19e759d0e939a684912935f5e54b163121b8e9de88ccf2e1c4d7bff015dad7406147bdd82241355fbd44b56347889fea1429586c91d458ac283c58c7048f7ba0322ce181b7a60b3658914a7b6e67b63edb877635358dca4f7b5291c00202dd0feed4116dab5c545a58d63a4e889e89cbd85a408b50f57ccdde3dce35e1a4757a51f5e85c6a380c45c202dcd6550f962939c42098fcc05d538205d25eee891811f0932672f3701110631c9106c84111361e491db0dd9a6b9784f22a385865d6cff469582867859ba9d3cded802f18ef2f7b03b3fa965bc849d06ae5e9d1d2af7e4c1553b7583840c93ca8c95c4dd9be48a197db703db0aef4954a1a9ce75e8af074fc8a3c3b61dfd455a304063b7f7bb25a83ed14c6632a7fc4812178f83262d7f61142ce8317905f69bca34f84f7dcfe56b84c69d762866fb335c7fd32395692820647709fcccb48414a446cee5e1e096624b5824bc7207c52356416be042e2e58b9f59d03e0a3d0f3ca851ed5b07ee3524f8004bffe265dff902f0512f153b06434c87f52a2ab063b54e138867ad9f2c83920bfcaa9d078b82de1af553c48960634bb701e0bf86c0f9cc6525db7fd69a69739e6d89e679d4fdd5fedfe620079916b82ac66e38b8f7935f3a54dcec2a4f0fa751b07fde39c9473020819a0b573616c4481234963992a6028e274478ca949e6b5f0846ef02f2997b39454e6e0e3e6cab934d52c993f1114e1c761a6c7ee4ab92a36abe971be6365ca3f4941643e699d48bbeeef8c8b14d11a4b2374f99e0111216ce03a5c0e5361f512b29ebc146a53062c3b839f7099126b24745e1a38bf7df726de344c8b3d092bee26f64ebc9787a70263a51d0d7b981f5c6e44dafadd0f0ffbff5e856971808ff49755bb1311a6cf36f8c46e3a1c39d9f8524ecc43979072294ef8016f28aea7aee490c6431637ba1f5d42bfec420a0fed4c71c2ff9506ce23f20e079558982e18c07707a5261a03deffd40cb91026c8b7a5e0a55815d7d9730b5c9e6bb4e1466801146d77138f279f2ceb04bf67f79151561da0e71c51cd7551d1c60fc2af6080eb0838f43609c675e334ec3f98f2d9d471c6f6c9e52d84c5cd39bf069372c7ff83f05a842b4581e7411bd42afffb030e99870a53f9bd3ecae37e096769ed4f2a57dfd09bfcdc51c7b738334561da05ca5da6b9d7de49b8c7f3a4347e9859d8126592aadf90988c94f883e9f754700082595c30af2a90ea039d847c2786d324a7dc9d012eb4fc22c5024b87313fc93bf04dfe97051a7e2ff91b108298a6bb50384103776df8388e1c7255235f238c37adde2226e288d6f02f12f990a7e25c6756e2ffed6a5083f016129e902c2701c8e5c46f66bf796606c64592b0f34819c1b744f9d7d47ed9e175f4487bd6c1061e7caa9b915dddac496ed40934d4f8e8fc7f2cbbf01f9193e28fc8b20429690d6ffe69e1788103a114f4925441da8a1e86a148e6606b0d30c15b702506f56155223e4a3e2ae25bc14466b404d5365c631a4f84558b49064b517d5fdb525e1a158e738cf85ca7fb659e30a871abb7e31620c902396ec059235cca065aa828e458f7e119dfc169c583448b389a4fece68f227cd487865846cfc6b971d47ddd49469a4bb32bf49593588bdd95e1445153843b319e20ecaec52d0e1f3723d030c6a9731a8e95d033aa193ed1f53e3fc1537f5f193ef50b42bcd0678e61982e163683f73d5a687f43555531f3e80048b926b004a0c50f13177fc857b9a88b3234f779609b8dc7524c603b51b2460dcc78b792ce141bb8d459f7bac1ff03288d96fe13e0bb8c96d6089a3b528787e646826b5d6c64563fa069d662ff5744d20a4ae86e05103dbcaf7764adc707679f986ac80a7dd1d43d157dbaecf08a15e78029750a8458fa8cce5072a5c58142b829c79c3d71c29dc26219ba38046dc6020b630f8d0e6a5c7cf2092d20634651de4112f4095c149664bbb67f5c45c4e78ecca6aa43239cb1e445067198ed7677aef0c50d995412f77ea00f89110bf54e5b32c931d22fa982a476f46ac3bb7dcf76c5ffbd74ec57a9e79d391ef719e08032e8e864fc9c842df8cd4452294d0548e4290003dbee0b212314a56af1a4e45f464c2b64460cb70e9095942f69003bb37481fbd69272097a61e47d0eb54ede230cc7c6b74fc44b10b0bb79376fe9b70b19bee4c5f3f33a10690e7a4d90d1473d7b42fda4655a6e28dfac69a6db8710591a0cd1ec13ed5ae4fb33ccc1f1ea4796510a15ec8f269bbbdcb504430949d966e9794a2e3e1e7766d11fcca98871cd7197952f789e35f3100c22e2a0d192a31c975039702ccaf988d255b682cb90008a52a00e425f2c3be5541708b54484d15337fbb4e84f9ed3de03ef64342e3e1b98bb8d67fe43a11e689ec8e2892a8a77390a1d60b656279239f7c683849ddc7e0f1444d7ee2788ea7d5e74db8ee50e0ae1d1f9a6b5ec413985093c10663b9344274fd7f5deb0ca0eba0d680c9d0f0031c932f5ae9b04a062688f010aa66fc728fa78709464002cf5412206be7ae39945b433ad184ce613afb406a83e35143e028ec22a8cb20bac9662a9f3b1789ea1b4dcdf3b48218699ea0194a07082e61b890c7bf343fc8ee93768c3c8759f7380abb489d9d47be1a60b65a1356fdfa93d708b1c7af36d6178182aa212e9a94ecd6db721800c22ab38c8d21f5f80399960893a8ea2874a483acea2d4e0eb9d6ce9f2842a21f84aba14d5509938b602d16ff239d43ca217d92bb512c57ebc7461f73e0133c968e527cd5f6bd6bb83e9feecce7ead5ace1c26e1b07a9dd63a93dde06ff775d1c1d7d37584ec2817f4f4e92f91df925e89b0cfd66a249c5478423e93236dbfbf9e9d11e25a1d89796293cd2845011babc3c99b60151d567a57469a96597530f785f374dca81a08d4bf895dcf7afeffd6830991feff75f3d55934340b4f2ecfe15dbe5de28b3d8798969dcbfcef88c40a088857f1e81e40f7cb60d103ef22d9cea672a01611cc005a96c58e67546d783fa666780b6d12babbd33f3bda612f67dfe22775b578439f00cfd4301043fdc237b72592326440309ad13a7f4eed69ed9bc488b51b9b345720f02f987a08f4483b56defe187ef07f39e0e4880c996f844a3ac108af298416087095cbe19d18229daa290cccb98b0c96eb83de8e8dc54259b73f9744ecff0f0a05292b1075954dffd108a5ab241c13d1d5fb915ac470b5050cc06b659f485cdce74ab2eef40cb723c791142af5caf1c5654c2e1d11d4231b9d3e4d7e77de87106e8d33ed0a64ffb95ffc86a4af0a72408520a7ec9d5a39c6adc594c66a25fbeb3fc95bf1eb706d0d11dd3bf919af4a74601d0ea4d396a4fcc6c2063ec89aaed2b8f7da6bb6450072d88ed62a223df53cb42c59a591790bd3d9707675cbc7b2cfa1c88a35da8698b448d377af72e23ab273aea50bdbd2415d78d3638539de03b29f67a34fb505354b32a9d96bba7a017563a1ff56acc22a36645931160f3f2e6d2cc639c9b948ee8604eedd005424e0322e848cfebe1c7e551287e322e02943e48ed39e48ade42b1b3c70934f13743924aab27041a7b56e70224c23684ac4583101e02fdecd426a39095ec1d6b73f3c23e2ed5f8a3c2cbea3a51d9132e670d05724181bc80cd5a6b14a6500eeb6ce7e034e06b111e6ea53dd4047b2d5b094bec246d4694e6f392022ca041b4e34e0e41fd4a66d0b1c666b6511903f81900af3e2817200d86dfd66081e439e84ca4b2e136526f7604e38e4ab07e87d95b7f02b3e3fdf95b624103d0d1ce551fd8b9d2e960b088e4543d12669fbbee7b127fa88370456a586776b042911388402e7865d35a660ec6b0484620a2728625aacbb6cb8784a7b9c1a387930f46e8e268fae4885982011caced53d4d0b75ba5381893652ce1a7ae7b7426b0d497813a4146efff5a0c3907b257f9a0ba2cffced716da50362086f173a9b0245a61906786556a89c12ee9569c7566add799421df144038904cbba86db67566852a861a71dd5db80e3dbd65de9a674c65490cdc3444dba54f3d60192c73bb1ef48edb9bbad444abe6459b9e283c60714231f0899a67195cdb3381ee1c314a03a9594e4f615ac1fbc103527509b3cfc26ea03c5006ad5f043d0265567df877e114fa363fd02c984b64a2dc0ba9dae4615fbbe1067754947825bddc2f5fb7c85762c30768a932aa1cc73047bc156067c6093e4e0caa0be72fe29afe838801a975e5b148fa51dfea29bfcf1c9fe7416d00a6fe12ffc83d68881a82e7be08f2e1d3043c2f2df3f23498942e086c41b12b6030213d3b92aa6e7ec4fb7d26ae2ec2c09ab22164bcae8eb4f2be76ca973858c0a025c61a303f85bf3c736baedfc16a7c4373c04479f34bb544543b1215ced247916b8e8381572f3307a4e74b1049497bdecad8b8d1538a0dbf9f694dc80d5cbe5bc015021f51c71ce9922a532c50e0be43a3dd0ecca9a26cdc7c2e2f6aefcd0d2086a3a8d05b95176ec401623630448e68497c2814c9151bef55935454cae84a0c7d06eec7fff2879c77aa6a734660d883fd330321bf2412421c2cce789ff9ff5faab39d39bfaf157f780cb560abaeed002487c61ad6c8c3914c27eb4c33aa16eef4c6891d0864d4c08a2e72412b2b52ab8fe1164244ed6aa462adc510e97fb258e43efe71979b200bf0e4ceddefcacb08f4e3aa2d7957c6b7b7581fd05d27a56735be724953947dc0bf5c29c117cf4cb9bf74ca8a81798f928bf750f6f8ea309deca5add751d79f2e97694c2e464881c309d31d12ccfd53f42a1bf19b9b049126ea0e040a2bcd532e76c301606df779717708b75125c5c0644d8c381fd87d1cc28091e3b5ceb82675ac82b755058dd5210f78cbdaacd8312fe316ac4114e42eb7f20d0145402b99c7def6907d1c74fd968740ccef398718db3b2be687f53f721fd350f40e7d50a423d90ba51efdc544c82191590089c7d66d4ca10add18b41ab9615bf7b3a18ccacde3280e6490cb6062246b436227fee81cc82a031583135aa1e4102df5545281b1cf2a028275563abd5326a9a1cb47a34dd200cb1b814d127075c1815a3de280ca6a5502dc76fa9f7f935fa50f5afc567783db61ebaaedb162dc9af07065bc0f393fb1ef03a6233c5074d6b0716dda86c408b653c71623fbd59fcf63b730bf18e1e49c7b908aea300e5e111d7a7962aa3c123b46aa8033f69caaa41c2bea4ff09cdf5a3691a407a9fe36a1f230115cc79de3d4cce5d61168ca3a93fd2dfe5c2f139fc1c4856df6dfa2cc13c492ef7420e164306ade9673ca07b9d952be094d1800643cd3cc490f12124e8c93768da91c6689d9c6fddd9fd35f54212d16caa01a24258ae7e51acd0b96a3873aece050a402d897f4287640a6bcb5c7647b870e6c2dbd4150f1260d34dc24104952efc8b6f2bbfb2555362074e67942c718257d3bc088b44d628379274b92665832d3d6d4f077172cf8a3848ef35d4dc888ca7e790ed9c3c71fbb3f37474414e63fc96e628bc2fc928eab55c2f210e178c5017825614c3ae984cf645a06dbd2ff550ac1f95aa7290deeb1a340a1cdcd704abe9fd89f266a794831dc444391b3a6e4ed0ce54f6b3405e13509f52a72d03fb140f6fda24995caf0f6b327caa2c16bfc31383419deac321024c428ca26a7f381c956347b16a4f40bcb45bd5a98be1f394104ffe0e058486764df7a59c335cc05b86ae4330665ee289c4c32b829b6621d173c2552a304be0167b59010291daf849fd38634aa9531fa966e0eaea9031c2a5ee80bf26292e9a4a107885d1a39a3bf35224a9e69844df83a39a22ce1dcd9ade97e085c61e72d362bde6f84d2b222619ce314d193a0b5486734c136c0512209873f508f16aef11cab4509ef0aae657a86ee4377952b436425fae087cd7f2f2e1f3eeef00ce983bf85b72cd618af0f3eb413638179556f62f80c6e26a08948b7587ace8ea193edcfc8c21083eb6f772d3e2a2e1f167f7199c6367ec8252600e0ca088f9a7b7663c0dfdc0b11fea5e673e23cddba65ae523195ee728e54616d9c52d3e3fbbb8c4822c27ae30ff7c568d247ac58cd304a012f3e35c60784b6213e7a299b1b40d41f0f8b1996af714ad3911bcdf36eab49149275ba8d27400007302ef59ddeee795f7858482af5907e66c5523de26bb93b1ce08e30a453e5445dba8f5ae0b5135f3cb643013fc7ac27c5681674ed6d512bb1b890aceab35c14d298181c034dd69de59205e7b09ff009b4d81e5b61ed8a2fab54ec6c6285b90227d66b91f04bf9bba04d6a4f5252e7717b8c7010c49a2868587d6446913db0ef2bc8c17be2993d05e871d67104b4e16d425d2a749c6968958959c06222dc28dc6c1d8c92236bfc041aed2ada3986481a034995f4864ff14bf4d46c8e58190d0faf72ef2c42e615077f4d0562c042e4cea97ab5af84afd7815b42899d123b2bcf4ec476eee5c2cae71f8689f8c49c7b8edf616175fdef2d6c1d8623dc9541d993e6349e7f6cf8769d6aa6260b818b0bb48de99487c6ecab60986db520feadd4cd54d006ef17bb0a5266b7e5df5b902dde5cb130e8559ff7d0a6323ab59fcb5ace6d6cc0b611988613f7eb26b6888c015f3febd1f6b6265224af1de4499e8428fab6790d4d57468c5ecfce6a263414798aa6111a3ac1de5743fd8ddeedd4ed2cdf256ec300edfcc610c95e4e7db83ee980cc143d38b72eda3985d8177c343368b9ca395ad9cfa184eac6f751c7753e1f1aeecfdaef2bb9cc656376c6f0d430d943bbd830e48e5411b34e6b1ab6cad9dcb91b61e52007bae45630a935000d944b142d10c060bfdaea7aadfc730853de0fa1179a6f887d7b4c1de19886c075abf752dd22e9a5c49b9a37b087ec5141c845f1227d97f40b70554e700f355917662046d950b990454d435a2647b650fa2b7aa3f45807e1ec8e0ae1a3decbc98ddd5e01d4ad9175bf8f4c23ff986307b12b803c460a2f276541d5d98c548daf187efa11d675d89f4cf37fa87e9ddec228c1c19db425c46276b5fe6af80bac64f9624a0963365fba8098c7bbf2b23079d6986fd4bf35c90705af3fabb7b2081beb612624d94b6fd4246b093989b910f5b855b22ff65635de9a33d9c8cc449dc584ca1fa8b16036cd5389a259b966bc3bb19f193e56e4c4073cdbe7bdc386d68e4b572e4cf88a7d9759f1b38cde276c12b002bc6eee106c75fde0d34891ac844c80866d47f192af11759fcfb6c4fc901a1239cc8561ca25df6ae2c1d880cef1822584af380c98b3cb6567dcf8196295625d07fd59af862a45da73f20483a19da877d3b27768f1f527476e2594a041052df198e4d84493366846d5f2c1bd8e13732541532dc3bfe576c54582af41200cbbd82ba9cdda17e819f6300d2ce010685e7bba2d807116a73cb451cc2e4dc937721525f6a0bd5d1cea9e5e6d9091b48ba4051e861403275e94cae0c8760c0d69f3ea64efc73696176af1754195fbe5b87f1b32a814eb3d34c40657ec492a9bf2c48746b3fd045ebb4c464e0c20b5c11f740d082470dabc140f9143b6d0820d98fa1ad8ed39a4fddff7773e1cc575617e52c0b118c0c72fd874243ddd3842fdec0a52de86344e48a8bb6112eb4b500ec057817dda916d0d68ec83382ea941e558bb827de2c2af4a242c6ce73e4088657d844ab76760a0969244c6f7c7dd727ea9ac1284af9ffa00b6965c094fef0ff0695656e087b643c112cf6bfa08e86e9f71944da6fe37c4f6c3cf6ace9fb73cd9649abbddf644f8fc0edf489647c5d7bda3067b5724f618bd46df115cfbfa9fcac3f09b91bbc0a2609c565620bca657e16f2369970199ba0134480ddcea277a906dff96e0868a08d36dfb473b19887f1779f1412221074a5443cddc1fd026b65260cffcaec23c5a0704732c1f269b179bc3db5a13e05172764c786dce5815f063bbfced5fe6d93a803d687ac346c53f87c31520213f49ceda8d8ccdcaba3043ac826758bb410ffdbef03409c5ceb41a4556c65a23bcd258d61a7a18bdbc1055a8b097656be46969d64303c60403e446c4419ef04055fe6dfd487096532094661308e344c0ab776b88f56f9721fba1a2c95faccc6b706dcaff1dde50952208d797cd75207f7555243c835e98b1a84509a1eddde40aaafbcee7e4427041ec5fe0b94c4d6146eaca10d909fc0fa0b6e7d9e5d47610028506e2a3f38c4abedb4250c1c21a169a39871d7aa65daa2960aa052b630a9bcec17f3f0b3a97e971921d57d4d94fd02b834c64750ea2fa5e4501344de9ca20a7f133e466e90dbbae6ee01850a8399017412e49b5608c9f7eea97b6bff1952296ab417673cc601281d380398af427bb4faa18beb1fc4cbd3d6acb3a90828c95e2fe765ec4b67481ca2141d121b97dc0ec10dba69f80b3654381fcb78db2debe07ead2330af56289bb18625b04cb66a733ea75f46834a478e6f82f04fa4fb5aa608871ab4baa9d101ed115f895ac236d20d3673ec6390b5612335c4b4f00fa9d5a1d78c25d4b4f472e06f746f3c8ccde2e8ae2be9d4361b5d8d3b5c45f15b27f74273ba252bdf2306b47e6175bbadf580b7d817de25a170c0e5165035ecb1577a8f486a4e199ed1086069bac221abd0a40d459412e9e47e441b305a90281bfdb1c5c7db4841c8f07c22c429641176087c36422936a86dfd8c52033ad78b4e225bcc2154cdcb6f2b6482eb9423408f392f154123bceea525aa1683a8e602fdf7aae60c5b5024ca426378c811acbf77747cbc53b1458eb17141faf9a7ebcf2e2f2fff41f4ad9fdaceb8c0933933eed90b9b2cabb58a4be16e559a734a80600a136a81b961a82b4ff36d49d12d4aa2393f254dc3427588f8f870f06d38f20bda26d33ecb2463694b89cac4b003cadeae13fa79569201f37b4686be76e708e5d8c3488f2892a5d8606b9d5117f0978f3e4e31a01a9500640804eeb2a3513a76c28f00321d5e6d1a3fd3cec9dff2a29a7772bd9a75f6041f5ad0e91d8704c3eb14a29a124cae029ed7e81a644a71adf61419f8e5b2f26d11a3632f3aae938df70bce6c00d6429f5978a52687e0b05bdf6ce010338c1ae439c6e05a31c94d9343818b8d38db8fea5d026e03999aba91612f978aa0f1c952ade0a4540830308cb5235c586bc790b09a60153532d89ff957b387bc59ad51ac8520ec0f49b396c606a6973249b1d92ac3614c5a7e6024d41a24c217fd324c4a8ad39e65f3e69c657917a79632b4cf28338269e1a307d9ced4a23e5b22dc3cfbbbcbc426ab07a02a68067ad6578b0d82e26432ee05619ea4ab50fbf6ea6fb31aeb5526024c685eb9003103b85b0a10f9c60946d4452d72d402aec2db7102c8c61687e35a3d5e8d3116830e388c40acf9eb008fd5ab24d545365eba744969dc9f248e509bcfa2a1c26a74e1004590cd59dea47c052f2cf70387af770d26d0d451464d05aecd5e608928db180fe8d549f64aedb9a408bbafc48f003218908d06368195f73f1b467647c5bfe275c299691648f41e254f71381b317536b6a3796320c42f81d35dfe2527efc50bcb6b3782f256ef68c92805da54ef7c6311fcba028e4c49df01196a15c0a567a8772444582d4ca3d86128738d0258410dae6632cd33b7ea849ceed60890ec60ac1d286339a6889866fd59702588e3bd5ce89152a103901052f4c248c3f3750985d34e2f2421ca3fbbda523b5635b86b952a1a7666863795a1094bfa80102673cfc34f9a356452bba7ff2f9a2092831a2445d00aa84914b9fa080a5bf9e96fa72ab0382c259bc0214a62aee9e3ba955c82ac00da810b28d2083534bac5f14b57963e89322507964c6cc0f4c5afe5872dab68a83c76ce3b1f119c0c03be558fac44cb9c1d3a79b32a4673877907033c7588505cad9dba0b4b5851dc4c14d47320e956929e95ac433cb9520926c98f5ce9e0342efe60f538c154e4a2dc1557224c3b7040a4785aeeb37fb29b54178b8a778acf818dd9b82c9c2a3296f6fed785785abc13f08aec18724f33705870ea72586c9eff24262f898cfa74a14bcffde26eab87eccadaf5da356629dc30deb9b6efd131915ff4d9ee62818074e682f4a964ae8877cbaf8ffab12a8dc5ed10865e208aa33ec9f6b8ec239e2a06c79907145072b52efc5188a3f4dfbd3e122ee9668c4ad10264534dc52e905eb13e1ab89f2092e18b4d1cd2d8a7a48a5259a61cb9dba30512a675adaa486eb9dd173495089cc7d3ee544f36b0ff051ea74f08de11bc30c41a8783893f4c84d988f4fb13f65aa48e1b1377b8a7967c45c1e881ec782bf394f01b310deebdb829b9848648161444078f38cecf64b3e730cbe0fe0c92922969f738543e05728fbc8f7df47af0f06d6e4009a9383e6346685ac4ec8afa45bc0673deb9d5ceefab816c862910167ae2269eb8198b9a5d12d9c6c2533429fff1dc0197761c4b9db3c8e0f547d8cecae6b4257d670a45e949c1c388f83fcb6489a61882249976634596b824519bce0dfe5515e52eb08259aead997542bd184b3dbb296a111e3975992a6ace7216c01bcc2fbb32b4fcc9bfd062bd5117f2d166a5ed22c7bd254ecee5473be417bc1e1f34a442ec8e42a6ab951842e2f4e080204a267cb8818a43978aa99b34ab4fe0c76f640295a000db5dcfac7c25c67afb2e0a8f5d9206740baa26e7536bf9db587e4552cbfb5ce3d1bbe70b58f7bbcfe3dbb6cfed23e98d4ef04572bceb3619da5b9e437c60032aa7d003607541415113af0c38d9278906c4bc1280412aa9fc9a95531835ddee53ab438e31ac14cd59c82fa689c3d13e6cf6f181af2329eb5d933063bea4d3cd57da6607f89c061717083654cfa7337fcc8d782bda54fb852bf3608649e5147fa4a245de4ddb9ab44f8c6c069355594f22a86912a028d35091007441edb088e10591cc53ddfb80e092679d7da6ef723b9225dfcc29aad154e6a16a7a1625ed7c8b852ec183f9758408841af36765ccaa11310fbc73533fd70dd367bbb2ba8818ab50caa516b0353d7f0af7d8562707709c57bed7bdf2072cf92c6837674a753906ddb1de177a669c7b1bcdc7e58b202500b3097262a2e84d9927171a8820c0e7c7b031969b5ba4e0755c0579b604ef4bd26a7bd269464ea7126f19638679a53e3e355d88d84334b3763312a377d341570379b8594c9fd37d057f775bcbecede22a3a035e82ef3423a859d72439f7fed32a31ec734568bc3d6749591b4555135c910c5b6f8720f8908e9c0c4419c3ba50a549ab574bda45f1d9ad3b00c0553f6ab58d88e802e0aa0b3733802a8172422d1beac485ab8e48eb0d704c32a1ba20da255fa4fbd2886cc3a72bc76cb05f3cde62cb585c8fe83a42ce97dfa877b1def08fe7a3fc98f327f6f0e3a659f94433919940e869f7101511233e09cc55e6d775d531344f6491ae6dc353925c4e52428e5ac138b292f5b711892784d2c253db39cff1fe552f09191e0a63ba697cd120928cf5061646420f27909b49612b4605cf2cc29fa121822441176106d00c064511b9a7c19ecc678719144d0b2f757600f6495a9a5cd2a0eb213e15e395c65b89eae1de7039870f6ce612cdf5bbc5c9526b15bea055a1ff001b573c694d6245e66b798ecf962d69c54ce753b4acbc54ec687538fb2f23aa076565f7878f0e7784f8b0eeac85db77792e37a8e51752f8c9bb37ec85dbe187d05f1d423232e7a02b2cf3c65a582753a9f2edc284668a785974c458a0e18191a9445cb8f2c60eed9f1a084a59baa376250957fd3ea31bd460cedf70b8346fe733b174b74514fb8cdde059e4e29534df3767f51795301e1df2bb855af580074accd847665c4e278a38f52d40afc7d1b1237637bc58c354769f482a79508d952c9120d10f5ed57edf64abe7d5e5d062868014e8bb43a216c3f67d9727a53b0b66c657253ee64c57b6d2c078280a40c15f614f0b1867f1bc5d3708159d5c2115d3cfb28788da8b18a31d75951e98531218af0c96188ca66c9dd3c2a176cb2710eb936565f6d41ac445071dd310bc3da710706675590f0e9d65001b44d31df70c3f218c969c21a34146eca73492518e0f3e41a9e5261553ce8f27540ca0ddf1fd782f8010bf58772137e1a9c43ef55183adc183d6072db31e57f25b0b7c0224549b75c33efe01afb4aced72ae4363282181d395af626cced19e217f362e0b812db8ef2643c198ee335f93869ca7c194c9ae4c4335657368a3c993de24467eeab7f5e62f1c7d30f54a188cb0735445c3c0483341b23da57e6b0a842b0eb34273636aca41adc7ac9f5b278589e6f4133d58c2e2c23e3be43a6b62e8c93aaff6cc7c224f0f11b4fbc5e150e4e7247c5e45e159cdcee13513d9612d897514cb6c031cb38c313d1178dd638507dbb4d9fe7b5b4a59933e640279b0d709d05a615297344d967c7ffce35bf2b7137ab5369f5123a66ef58bb22bafd62620bec56aa57c743ab5f2e4664dbab031e3ae221f0ad11330d78d9c3b0e9b96d04dcbac8d5cf4be1891b6af41392b0f48356a05e9300f52b264a1c8b0b983fa56e3682520bd83b4eda5c04a4040a31e51965e12e8f02726b9709fa949f5965501dad43bc88ea3e01bdf3ba9062ad5bb5cd2f0762aed759086902b6663cca361e6ea6a1d9c97b1a3d48a8d0f71b347ee0376750df7e9b9b7144979dd2b2be94bd23ed389c82fffa439cdf37d5b383541f57bdadb532207a22f43f586b199d6d93b31ee3b97227e746f4cb064cfdb595705610883342710dafcde08e694ba32bfc0724fe2322cdf558313164819f54c7956a7ffd522363dbe86e910ff85d591da66e46e6cb11f15c12c46d9072db79935671317c87ad78c206b06287de639dd0b31d4dec1bcdd89d33dc2642b7dd29d8bc2c87732902dbac706a6f73658d9964dd7ad5dc65a8e7ecdd1e752b6486db44a6627e8a1093088074db20843929ddfecc1d0d9d9cda92d8e5e4b54df2b992c38d93bd46e46de870410ec065ccd649b0ecc00752b9c22f1931b3f4690fc46083dbf668df0dae261ba92136b1446d42eaea1e0849554a27e1b3356deaa4274188a63510faf2cbca5b8dd8e5b1989d84b08f9fb75d6b09ae06b05053ebabba7bb285cd0da881073225e125d1671b5b918e0d5f636d1beb7f6830cfd043e28eca17426ea1cc0c33d9bd9d51f9e5d241f2b2fe06ecc76849345552739bf3dc6f16743560e2a1cf85d86974b41bac75ed27b1256636d670834996dfee7c918d5a1db1aa9ae7cdc1328a71aa8fd0d3a7d38576d7543c9fbf91cded31cc71acf7a2738c64de69367498247c3021a90fb4e4deddad0859695989f815422fb6e7d4c5e7417b317bd4939595b881c4fc2305951dea124d73497563d3437e0278b897de3ecec1b0ca7313e72556b7cea888df4f47cc6edb07bd021ddbfd204a6fef637c758b79122b10ead02319e3d79c854836197432da46fd0eec9340980d8f567a805218df2b54aa7a562a9db2f7745f7c6fe805f8eb69c5d22b8666f2bf12d1be9ec696229e82564b8237f4caa1f7021b8d9e3c0cee658ccaefce6e50df8a52828c4567fb04aeb17a6066eefab3c26229d46e4ac68a5082e243b8ae5abb71eb92c2ea24e283257cffa4da63bb98f6c7dd1a5c751513c702a11ddf13ca3df7b41f07e28c5245b2f10d826f3a3d5f164eec9fa7bed77ffaa48539791a3ec46a9d7243ef5778066a628615c5fe18cc7511fb5ae73009a61045ff9bac3f2540a15c2ce6c86b606dc0ef8e8bf1715bd94ebb898b9ad8bc46aa3601c3be38dd9861838c2dd396fac481833948e9e11ccfe7ecb0ab9506c0f670069cc26a9a3c2a1711f72c890488b325dac6cd488df3f1ed73c124d7482c3d6b591bda0bc22e1f1881ce7e428ea9c01452e74ff949eadd11afeedf2f3b8cb6b51d71ebe3ab8fbcf4962cef8f3b55cd30f59d47a6ecc5033222bd3c2cf06780eaf53c4fe0405b7a7bf0c9f5ee79934c859bcadaae5b47709fee355c6a8945417d2d05f0472685304d9c8b3df98631b939965a86c7e1b5b26c4e3e066523a91ba1e1859be6f82797a8b4ff04fee13551c55524ef6777ba8db84d3c7b5c0bf75701dd5f6308404a8a07d28994b8d20a62958bf774b83cba460736d0443253f13eaf4edd547e0c47b20ae213797f06207899b1dbcab76bbec102073383c39e099615c444b3fbe3c7001b59ee504b33dbb2de4623c90b99d16f84c4f129828f8d2f2703e047ff3da1af2069c20ff9edbd6371f9baa0bef72c860a9a8f6bcd984fb13e134231898e8e6a6545245fee7dbb7cc7b34568a003bb1d43a00e2762acf1ba194ffada5a31a3386463012ba98849c05a6c2ff02637b50bbfde36f2c8c214e2b29a89a8922ea039cc60ff03b87d70a0badffd0061ffd1b71230b6f4e5538db6f97018dc371ec8238ebf4cb25ea9aa38f3a1da2cda8dd090e0f353d0773f8819150a49834c561a514832f0c4640e1a576006e3b9994ed123342a479fc22ac31b68ff270590212e30d06b528fa6aff610e283ac442bfb6d43073e98ad22dee32ba421860a09e8f0b8329d4a143b04eae8ae94572018564d07fa55238569078969d54cf5cb956ff35fc8b9c5b564e27f825af35de81fc0b07094e810efc5ab07d28cf2f5a1afbd80c17c7b2e6d475179f9de2591d9502cf82c962bef9411181a59acb5dd6dcbbdb74c29a5490911090d0993b2fc0cd3c84bd1ca5c9ee57fbcd0d54695a47e652f3f5fa7b50eca522b356b86ef5b7e0367303dea353002a647417901256864fef728d008939e4957da7f7fa22b8dae381a0116d37b6fa22b8df2d8e0c1ec25a524ccefc3fed1a4b4522f292915292d152941e9a55fb16a8d66b5d2942a4a4b4253a477ffec60223e02c13882da8492e7c3b5a98b696464a494f42449a594f4847ba86c94e4b0af5bdd9a524593208d552d8ea7bc55b5244646566470367a01cae4dcfb1ed3f774ff9d7c53a53e55135f171bf753fd63424242422e0483ee2acdf2188322927e2db5fc8f04c5190ca6ff6eef1cf71b8db318146741fde2a84bc90979ab7beebd0e8c41cd9a35eb489cc5593cb23cb86dd631688b3fcd72afd2ac1947a08db36df94b29b44cc359e38c082d7c31fdf748b3fca7591e756c3043aff2d3af3002557fef8fb366b9185eccd07ffcc7617126636cc16c2aab442a5a0d5da8af70a1388b41314914cac2199cb3bd6f9192ce11b4a8831beee7c3c2b2fc909d701395a65f11475b2529b9df9e7e0c27ee2568921c2b4d21c6274f80c4620de4c993053223ea9d955444985c84bc8537e7dc5e47bf76541d3f79c2465e1ee68da45ee663b38cc0fccb1b91f9d4cbc37c4fea657e5f1ee66778791815ccc7a45e4616034355e1077c6acbbbbccb7b3ebf9b2def691dd812c3a9c7e93bfacd7259c5c0f29d4bd77d0c5b3b3a0123b8b4d090270bea44570ed161e2e0533a500108581b1d3bdef2582c0a53a337506accee90e0f594224588908874a346234ed3963e17f24b98b1235b71c444cd8a21ff082d4e6c212da64685842ccef6f139b030664268a50831b130ae824868c68d32d1d6c487e18a19ae9426444d84c8cd51309071a36c05142cb4c50c9988ad581c260a9a5b7fe3f38f941ea8e32d9e98b404291f0df16d8098dc48b33f0ec923d206330aed87634b4b4b4b5bc34b8bd3df42cc96664b356ac84b4b528ca8cc668be3aa5e7b8684830a43b35511ec5284efbdd94a5bf3518f8ad14590524707ddb3214cee48d06c0593e3244f478be9fdf7212f2d2df9077690d4fa286c26aa7f0b6dcd13ffd9d1ec0806ab252647bf66152d1135ab6753aae6ab583f9b813acdbad17e502a38c2005118200a0ee2274f8000d91a8f271e4b63cd5a4101b238a886c97720fd1ad2467cb6c68b00591cd49a9efb0671d0a15bfe9ec97bf93398e49b3caa7213d73eccd65ea7794c3171d00104fb42c0b2fcc10edc898c63093138e2080328f16fbcf5e0befba9841939ba1ceb57a76371341ab7c65f4764ca71dc33c7711cc771cce9ec881e63748fee1e9d88230c10a454a423e59c2ad53f8ba507c53e6a2747db4e5ca7b5cf6b2350403424733591715af5ef21e6d6ee4ddfd1557ff74d79bc377daf9a32bf6828d5fb49f54602c35e82802a33eca33e6a4f478bd9e2a28c656ca48509866461ffd4991bc8a674d0d1d1e2b42aefd025256f3594b97dd8473cc5c4d2636cde50ae1ba4a32ce6ced6f8efd0b1475e142495514b8d5f437f8cdc4b6e084ea4907ea0a4aa3175b498f181bcef5e8240a697efc51b0ed4e181bf37e277601052d6bd099cc5641d0563ecb135f16752cf44aaad708401a8503aa285338c60c20b24a446ea21cd356f248f48dd410efb81c443fbba2e8132bb1a36927f4fb31ca92a2d212525a1a11c1a2a8a485b23f5775bbb6f284da36c458acc13413dcd6a169785c0ec13fb1e6d38a07e6b3179df694a66217d0275c4c01b22fc2def239bb4e57be6b7b8fca42c3fe9f3b77d38abc61b826df95751a2cbc2f23a5ab0b0fc747996f92c2e39ccaab3353c321670653e64ebf22b9be165be0b9dc1e55ffe851a99ef42dfc79cfcb29d9d214c8dded4883951a3dba27f544e9c38595282c24a75abe69aa6d1d048d59efb1483564376e25b8d4e9a81a834fd5a699466259be59fe42aacc44bac2255a31fb989d44fbc42697989a548696f5efa56ab4070575a1ab26285ad100d790fd526da568c8d5ac9c2c23a8a1e622b435678d88ab7aaa9720f7537f8a347c5c54f0d555cfcd4ed63f5099aba0dfc8afaa8879aa8fb8eae66f8154ff7ebad55cfb788810427ce00faf99175b4089350c98c65dd03000b2159478dbcb7fcbb1e0200164232ef4d1f4e303c6a726f2b50241dc2f1b7cb11151aa91be5d99a9a33a616919a189239883b4f9e00890199b1e030c340a849b37828a6b3e38387838275002af2b356662fce3910878d9bf87047bdef28ff3c01528185b110b327339e99fee3ef4d6fc4fbee5711f8ba377ddf77db394286a2b6125b23f3e4b70d7bb24f80c4138f06f2645b71dfd775ff51fef1567be0ca767cc47a9819ecd1686c891a5b9bb8f0c0096c4d911f220a186386aeea355441d2b0edaec13db00f8bb31c0dbf2a5562373e4c38ebbd8b860656031428cfaad1356860612180c244b6c6bd3722df7b55b38c98be7b23decb57756f2a22dfa34578093488e2c40aa6ce0e1f3cae184f60719a01a85ac3426147319dc0d66891099a29720aa1f8b359cf869634144b584bfac55070cf7a36c6d6f8f7ac972c599c1a8be335e917d146a559eefdf258bee9377025c3f6de7b5b57a6f7a9261d2da6ffcc7ac6ceceeeb3da4b5c9266c84b5b2fe996ffd2d2e2543139863206cd0c6b4613eab62125a5ad7125d373e553bfc7b589884eabed4fef23dbbec8e93f1ad48342519fb9bb134f5af1cb4ca07ff14ee4317531b6c65fd290a99c86f850b358dec4a57295c5611b2cce149cc3bd0fe11a3e12d8c69fc1df1ae7236c8d3f539949bd93d450b452b4f546f98bf83951cc90bf78b27decf7daab2117797c014a51d1e2a0166085d9af6a500828b0a28546568cdabf15bd00e5c88c553ef73f24fdb1de6aa9ce5035a104e42d4dc8452626e296a3aa7b0fd68be52b22c771dd640ad7ceec44324e10d560c316ee14efc4bd9f780cd99e33ad4ca62e0a2477f730a8547777f73675ccccfcb58666b91055b3b478e49b4223451e0b1340cd02e1e60ba6a1a1061d4d262751d5fb68f8d1ac06816c527f566aafa77ddb27995d4f3c4cdf5dbd1c24f3fb0f0c53deb2afa3beade9dfeff9f4dfcff6de49caa424076c34987e00e9a84eac595cec95502de19346ec7ded46d2e583f71d3b5eb862723bdadd6656d70dd0ef8ded39106816936d14dc161050102ed9ee8dd02647d8aafe3a16a7b759ad511d5be36f34232f9122427c2d06fe3670c7d6cce21f49a499446977e2c1ae130f66b96dcf9d786cdb8907db1079c7e2b4941dcb5bd186590c6c61c7d6c4aed69431b748fba8452d6a45bb928692a352aa543cdb56fca805ddaf728931b5f86134751169b57fde166c0c31f97763de92287d1122448af08f91d37b46beefa51de799c358a75f92b12217d1906b9774b458f17ce1efeeeeeeae0d2b634939a74af5bf446866669424099cb8b6057de556fc1f5322d4443dea13ba56db9b561b95ef99c0d5f6dff6db468b98be4868436510079a6675200f7bdaacda8a1f69c5bf490d549afdd674d0bf644d8a71d0d674a4374c3622ef6dce6f9af50ec66e629cb7129389ca1b24a67ffc7d0e0cc25cf731f87734d4c12be7abc464a237373753e686c38c1b3feb75bfd6bdbd473b1f68c314163d62d12c9d39da0f67aa7f642f52d55deef939d5fb3303b13929b6f157c9b04c97df599c99da55d3661fb2ea56a9301ff28f0bef12caea12ceeaa2727917c01930b65e68285d5cded2be411d5ba37d0b28e39aab744c3077e8786286aba3eeb8ba6ea8bad3c2d3786f69df02b8c918887f645840ac8dbf3309faa3d424694d1993a333786979647a2e7edc623c746851e3fa61fcaecaaec6fac5a604cc5ee625c07b36d155b71addb1fd72ccbbbbbbccccec03cd81fc581b9ad529246618abdaaff88178ac63ec0907a9e8540094c9fbcdfab56240d7fdd027523e622726589ca50c84ad218273980bb661227e1b48a653a57803cf7dd09db8d32fed9b3382faef8d30e941f507808a2fcee27415f5fdeb33a77349e6c4dcba32145df19cfefbfd69a29ce7799e4783b04b902b03bc37bd04b972bfda7ba14fe5368e934de639b548bf18461c323517448c1e658c3146f931ca788af251ffbd07aea47bf74254adb4e23c507e1feac4f2a8ff6c60097956dccf80a29f0f91cb1cd63b08780d7d6a0e5e25ed80aa863654d093d473f09b153d468ff1fbe53488fcce412985d810720ccb36a65f55107feeb977291d0c55cb36fe72d9669bd537dd8a1fe3c78f8f030a5e87e4486a9c2f98e126f120491224c6e43a3defa3214dfd7ecef024294fb3ac70c14993aeebba8652f953fdea14cc2b356c65fc5e04e7700c7f0c98029154d4ebb40efd42bd783132df2998972f1303bec36068b74481486a880ab28f7acfbf17d09f4f2cefb1cb7b2e2e2e2eef53437ed4cf6ff1a90b1a11aaac835627f522d806f53ace82fa667dfffd995e7b0f1c126b381769a180daf4e6b9d9624a2a562451dae4eee006c2b407fca16486fb45f5d7ac2f6ee6e68fdba9d1a62b3dcff49e27e97bdff4a5aa41fae5cbef972f3fbe17411824c2f7aeca20bdbcfb3168bfaadad1b07f07aeabd3f257c957a7c35c27579d3f7538fa451c674ccd33ad121784c7cd4d554b6716b34851738cb9608637d52b3355e2bd4757fcf57fb35c7ebfa4a11055e53ebec781af82c2e47e0602fd9c0e2f549d1860fa659b7d1398835fb952a51015a7e4f42a879de80ddbb46c686e1a0e28cc6d6e59352d3c1f5dc3c54a1931c33df278c7b4dfc1543b683548f7df2fb8835655ddb7801df79d0a0ce2fdd7f21e8d0f650bdfefae5aa001aeb760f6531f0306d94fbd27f31d231313f3316c8da1f3431db42a43c3fd1db8c63c4b0a44c580a86f01c3af2d3f659d3354d5f9ac96ef96140d676df917ba2ddeb780de4f904fbf27d469dffb408feef8e0017b7e00d9251b227e9822d3ddcc63d8babd1f3971a3973e95034065f27073730f590e048f8eaac816dcfa2c57ac888b7e84a44d295aee7fa8bc25c4f25e6f5a64fa43cef95155474dadb434a58a49d54b7e6c520efeae686b8d8a241c50d6b5c5f2bb16e36fee1b75393b7f6467e7d57899b58d34aeb81f5da056f9635cad4ebb2a9229518b7477777777cde0f6398dbaefba8edd1b1debbab9315215e166d67c848754184770d7e2a4dc592e4735d77cdddd571b82b34bc7eeeeeeeeeeee6a404042c25c1a6ec6706ddb6dae168744a761aa2e15a2aa38ce6816444d8ba9d4862b0d6c6d4da4b2c492ac9dedc291f94525263f043cbee1647e11c73bc093d0edd6742d404249696347ae5d17ebb812904bd0ac61695b27263303978ea5bbbbbb3a7476b8bbfbe60314ae9ba4a78991a67a8cf1638cc1d3c8d0e0a607252abcf8a93a626e00063ab81951305a23be99a1492dccf5f1a5c346d19166f4216e6c61b12df221ce2913c98a67fb01d4980561b86f19478bf0006af54688cdf02dde6cb7941d28a9a10a6614e10a71ee608afd82676b78fb1e2da78c9c2a2968c25b1a568011532ae1015309031cac3afd38c6703253d9a5850b82704105ffd6dc0c8183b66d0ab8c18cbe3726a0e2abb9c643c9905885a8aaffa41207195168d68d2be68a69ac6dcc75e372ddc45c31772188b9cfcf4dc3e9428000ac4000025ed024a5d269275430bf206d0487700d573cdbe7a85a5dc5aa5673d41b244bd1e7ee461007737f079ec7c2271e2c30986086128623338c63c030c40c250c258041081866b131661849304309431031284000cd30fee0430f30fcc49610bb123b23968598951816625788592156256646ac8c58156254a83043398526cc304a21c684d89458146250882921f6849894181951624e98a1bc39f188ccdf64e77ebfc98123478e1c07b8e1b2b15153c300390ad06211600002a0c911000ae6f81772a8646260523972787302beab4d43239535963ad81c4f981cb5d5e2af0ba1edd220cc6528cc80363b989c52f1e0d97eb9a836aa4e83528bb940f038a582f9c5a5b919d826a8b85c37cb6d7477773752a10d8185629527e62d33263f8d8e984e4cc73da6e3ecaad1356a2c165b72edb535ac4b49877574474bda298e757deaf0bb4b676773de7c73cd9db96352ca2ddaa21063e48f1c9963e418636466ce821243380942be7c2edde10a5d747d759e309d7ed17546e4333a2abdc5edf4f0fcf0cdfd7ff0f420f1f4fce0f9e1030724a4f83c8fb448fc53461939f0bd79c2e46f245e386bcb0f63b095b9e4335339a56f344cf949f94d3919082808498c31c6e8302957ca8d0a25ddaf4cfadae041ebd8d9e1c3c7fa30dab1e363870f9d98d18e7ef980b2b3c34865a4325aa3227cc082e5b0dd90f56f2305373d147113589297a50d1bc81d3c3e7ad649cfff7f8f0f76e283a7c747cf8e0e0efd6a293a48f1e1e4df8976c4fd87c9ef3412c186121c5c6c8cdbead76ab491c5f4671e19bff8b1582cd627a36fac71fcb8c7474c92deee1f234b13232a6d4adcb88026da2862c6779a57ecc10a2ba0c2c60473ff071c552633c0004744a1b4d42db9b7a4f4abbf593e4855350d4ad84242dcff38fdb7d250e04a5b6dab2db1f6018bcaa34ccbcf6479af4fb55fc775246b37c76aa140b3988ce58390b20ff59302c50f42ca58bebf4d3494df35fac6bdd7696e6dab73843760b571781efd28138bc93c1c9cd1691cf4c7bade82c02923cc8f4a0c1145255e49d33f7c21a1259cc352e3f3139ce3aef7a9517e441cc672677b8deec075d563dbe88afbaddbd7f83efab59acd8aa966451ecef19faa9966c517520d11092d89ff9ca37d7cba38b2002c6c01db8aaf52bdbcd4f0abe7e9b04d7c1b38101af2f84ce4424b8482f00212932bcbd788afb99ed53199bafc3d68630a734a2bfeaefe58ffb3fcc767eda9e21c2ff6c7bf45e6dd969999b5cd81aba6451a75ff5953e55ebc80c48cbfcee29c53f5afa1d33a382b0a5373075fea6a77e01a9bb5aa3555b862cf72997a57ecfd59bcb3699d248910e74417308c7fb8d5a4a578a2c6671faca8911a45258492fca49e309224b29824c94eb84f960935fe326ce3167fb848903df4d6834eb37af46baf759224499224998bb3712fc40492193d9872c552154a5124c50069f6d3ace82da9107be80d3f2d16718e56e333160cd3e1567c980b1f67102afb60f5213f6961e6439652e3cbf8a30b9448cf502d52a73c537d7c3ec239343e3e13b1381f8879993f81f6a80fe5f62c1f320ab89f1f9ae4b77cc829e8dee5c3cfa402ef531fa23ef03dcc877c84731165a270abc4e78161bb453887068d4fa45f2abacd42559515452aca44a81eea9aaa9b7aa84430028a2afa4f1f9f6fb03839a070b03d8b15dccf1cc86ff9f8ac83c5c9c16507a67f29f23e75c5f730397cc0a7cad06d6bf863e83e0cd8c9adf17f013970d34016d0b7c61f05f6d6f89fc00fe45012111111c56ee1e3cb6e61b265d25081311e891ea744c1094b62288191e4458c417416d35f0e3c7e9e718eaf64a041e2f7f3125715f974f150ec8807cd9aa5c36d0ebe8a67fc9d9438bb3454e0b79675a37a04e24f90bbbbbb031569160e2b568cd8c5e11805db8abf48ccae2e1293a5ee7b1e3bfcaa86c3e93da4a8bd8c204db4ab818666c5af3e4ccff5d9a069b4039c13bf39686be2bfc298fda737d5f56fbae27e340bf938c15c19939ed3a3e429744d000c23a713c7bd7c8e0259c9c00591b32efd11638cf1ab21dbc4df6807d826be80c4f4aa4685b04d74c5162716bb71a3d5025d350685ae1ae4faa88d247c92383185164ea0a045932059dc2a5cb4808c2557e0e0891bc8e2e340445b23974bb68906dc473671dd9bbaeebfe7388ee3b837fd07e6c043e538990357ee5f4062bad47d9d18e798aa8e1466e8aa526adcc7869d9ee35e4e2893fb0fe8f441bcec449970d444439f6a7a0e0c5395ebbe5fcef13e1a76affd09f4c0651b8e6f02b7ef5275d3844487a53c153d653344ebf4eff4bb625e6f58cc0050994a04098acf4938273559a294482c0e72e962a59ecc9de810e0a8ce3f6fab254c0eda4e3c8666c84040fc31a859364073a3374accc836fc0ed0bee93692242e8bb12588c66c5929d761a8d10cf99ee42212bb665c31a58a1ae3af8d294c3e121f8795189104c5e725f139283e270932fd00ebeff39f296b3c55ffb83832d6d4c1e92da0b975eb0f53e176e3930924c46165f2f48b65dceff4cb9f7b95c3b4e77e9d7b710e3ff71bc37c641caa72abc44ff091f100adb75e035ddee27e6abf71b408d57e651a35a2f137ad21430761552948f9230054e6141f99cb6f0f38e7abfe6c04cef99e708ef7dc6f7f7aef4c9407a8e5e5c39ed140e404ea0032122bbd802aa992a1e4aa20c2921fd9ca989c7e654c563dd80aba92a1fbd39f681026da5a7d987cc4391f0d95bcbcbcfc0be58189f72fef1e5df5a02b193eef3f9a835fb972a2abef7deae99de3baf7e18273b6ead02c229ce3bd3f5bc1433cb08dff067e1fb86cc37f029b6d3807bf8e13e6ac5f414eff3d17640b7903431dbc6e1f64fb0f3cf10686928714336424cff70c0eead609dcfa4559908d2fb60c334a0086951d9401c6139900a0d08415bac0011144f081d680209e89eb4e2ca7ed4fdc7bdf7b1e0dbfe728f79bb76d9e89eb4ea8cdfb8e3bfd0686aa6f7aa733ea29d4a1723dd10e7c75a341ba97f2a5a77d7b8aa1fb0f5c79bffdc979e01c8eae7abc5fb9523f1af209fcde033f707aef17042fec7cbfd1f0f4df7be0ced6d3fe706ff268e813a6eaf6de096cc981af54d4e9db3e34ddb05b13deb05b13b2d4ed4f7be2e15125b397bd6ce5a07e6db0171abbe5bd7ba8ff3a10f51364241be524ef6ddf076ed010f36bc848b032927005153680419426ab841fc0200a298096b0c18f3f0f9cb3d589f48b8586a6d7a15fa6979657796bff05dcd5f63e32565a6d9407c847e6e3042e1ff3963f939e1726ac17a41770fb9531f1be884c862ad3eb0f7ee58a8c4990cd01ddcb16cf034355dd13cf7a8bc63ad49fbe0141b647a158defb664199e84db316c9f7811dd39f7e673f4004042fd4130db73751d37bbffb5a9d7e2beabde7130fef8b66d950627294930435eb6668723dbacfc1af5cd940eeca952b57f88b9ded4fd48523939342d37bcf7dc8485f540f94265007dbecef09021dc5619b7d4913c036ae66ed03e9619f2a1be623db361f474b4849a85ea9404a541037378722db6adbb439c5ddddddddeba64530c6186560a9fd8b1486fbec96f60ba5c666d69a9bcaade918bbbb3b0641f62fe3222366669927a1a1d9dd5d9ac5e16ad55e2bc275d3215c3882530f8ee39adb9ae3389f1aab772c32d25ee02d4de8e9f42bc66e5fe73bd0ebd8fe1287ea34723d664d400c66fc306adcee1fb5e81fb5f6f66fadbda51612f9bed4d788a9685c373a8a8c3ac618635ca422efd4e3e5abfb77463a7b0034981a8b8bc050412aad6aaf83a86a33553321b1aa76c54f510d6faac657acd03c7677779f64e0aaf64e8427251226901e2a1ce02a3502130863f211a021cca01d9a631827b839f2021c55b8d1220cee066fdad52ce6e5756f6fd7da63edee4cf33d3f802c7333737312cd7d7384c9df492d18a2956cb05f9cc9e06dbe1c4310edb7ee6a52b4e83e9130b9d7847c4c982be5dc7e30b9d7e4aeb6bbbbdfaf6dbd8171298aa58d4bdbb631d7bc849716a755bb3d93ec31491f99f60ab0c264216f45284a50fad54afeadfeee5efef61e7f14f068c84b28d05116d2e9d8d6d49a336613733fac51e517a754b1126899f731e6d26e5cdbb6aba4ebe86cd06582d9bde97dbab66d93db6a15810e0888ee3d0a8469db9e9578ef710734c8224551b471753f72ceccd2d4b8792036ed3ff6cbbd9bffffff976099ea564f17cca4d9734e9e9cb3dd02eedf55f4ce5ad8ba5cf34dd1c5361d5d2e971833b022263f0c05931f1634f9612798fc3022263fcc04dc073b32f961434cfe602598fc3021263f6c36f9174682c90f0b62f22f0c88c90f039afcb01f26ffc27c98fcb01e5e3a548a739673e4c7360dd3301fec67f2bfaebcce98fcaf2cbcacb4f0bdb0b0fa5e579833dfcb0a937f3967a6ee7b2a99981994b735fd91086f8bd395ba01d342f5ba8fc154f54c1f83aeea79dff79d3e0665f5501f83b17a2ca9ea427da17a2d73b2a04ed308fbc22e1d3ba7b9d9a6c54377779688da628c3146e73e4df3a2c9ddfdebbcd0dddd552a29e9ef0b13eeb4a13eaae57c739471466f59efe5db538cfc4e4dfbbc1e5d5ebe1728dcdd53934610cede9c6bb1456bd96e70f20031759bd560b8aadbac064398da6078a33618a2be06c396da60f852678b97faf6b434141233c6e46f21a9130ff697afc1d0851aae22dbec73f5eac1a450a14ff524a478e897eacc436f6cd9526391d899a677727350dbc0b83671fbdd6a14818c5b6494f79d4c1dea047e9e89673d9d4c26936b3c3c2693c9b5e839f0155e56d462d7997630ed6e4cd59ebf4f8bde2f4df540909d655c9bba6d9a465d9a877e71291787c99579a8fcde6dd73386d7bdc658247631633482bb775d67f23c53f7448a6b0040f13ae5467c7ba9ed9193cbe242b01fdd88c796aa75a669f2d88b0cc6ed889abf21cb355940d449fb5a4cdfe914bbd3a29626b53c370e50b507c88e3acdd34993c984faf673a95e35f18a015cf9bb324c4cd8413a96f94d17afeb561ae8e26cf962ea7e4431e774bfcf60cbb2344dc6eefb4e3dfa3bf5687191a18b5cd8e9b7c6077a9aa4ddda68f1970b41bb70b53987b57e6999a9af39a7656db4df97900360d7a879a0fa738ca6695e8cf7279b989ad468dcc621000dd9c21380daab97da2724baed7a91c1e4a79142ed94150f6294acb4483c03d221a5094a8a122aaf748245ed3ef6ebe573271e12949202a9f1d86a542da9ca1afdc948a24a1eac543bdeb2e004e6b879124855f8f852df4cdd8812a5f6d330820a520d9c50c2063750410d8a28c1132bcc6e009485144270319ba08a720219d9105184a8e044141c4491610a25328e18c20a2abc904501c4171ec74898231ed4fe5494217c504609a2a0a207339085aecac3145688baf8d142c90c9969080846d3fee5c44363172327fc50fb5bd893000a9233ab29fc5c82a208b59fc527882f9e98811432a848b1d4021d0c018a2a4b5ca10a0940c21251a43ce1028a1958200c29bc60ca93283d8862a28147c9817482523ac90b48c18ca01d486185143e18c1c4193f48c1628b2dac38143318820ccee584a4967d3aa8ddefc91563698a1c28618615491061937eaef003458913b2c0820d23218ac045942d66401416f10324883822849312c8927e30a92628841044120bab5c66cc50a55a1cd38987731398a8fd9d4f0ea45005165c607414831588400a2394a8d00413aea002930c8c964879e2e15b8451fb3999a31368f1042f8a4812e4838915513061450c846a607aa28b24b64d014c50a2ca052031c34f353306162a58635c1f2831250b244800842b84400329cc608c2e8c9658420f64f1872906677c4e0f20c614d22f7e1b54333e860b360c283041e5092ca87cb1c411164064d185135c44c18127692185d37ea96fa6b80050aad4ee2ff54288ee91dbfa9d8b313a07b66cbf5713a67f8c9b16abc084a5616ee666e69cae3ad7b2cd8adfaad60cb8b0d386e1c491ba812ddb530ca81ae9f78232fb8b1f9f0a9ef671abdbd3b7a12122ceb901e76c1f61301f1f06fc91629bd8d33c78b626fee9b5f7ffb6dfbe0fb77722edb7d798a85f1b8d52ce498486f237a2cde326871ac6518bac44b3a2c643bca4beb4d7bef75589388c87b65525ea1001998f61634c5cc0c25831be8ec35e728a1abe34d8e20c7991a971888baae20c9134701667c8f7e1cc599c21a7958ec519829a41c0e20c617121018b3364be02166748cb2fce90d4c76c8df72fa0e95db697a0ff07ee2077983ba8769075fb16708709f3310f84ea65feabd203398aad896f02598aad89df815c83ad69c24530473f449a757384c9517e09b0b6928183cc6645cd85231a11180f45ed599a4663b8151f00350ec5d46898eae3d768d8cae2125181459888879a45c33929b689da72b34ab3e2cb807ce4adf831e03ab71c050ce522908788b04d64a943558a8e8688865a966848d55195c563eabea77dda89477bb12d7fced17e1f89738cc039dafbf79386a1be2ad587196e12f395c5ece79eaee27fcff2de48db9a1251dff33d4bcfe9bfeffbfea33ccc3732bde5275ae4fb165ae4f45c6d212c8c81bae5db61547f16d0f50263ea843199447f3ffdf74ac1e4817392d0482107853ca58be09ce61c8d2609c23dff56e75165860c249bac0c639efe439a09b12f329605c44bfde2a06691b12f4ec1b224d2d67c91d44a9d82270dc6da109a5c85f29466f5731487668980f2c036ae15611b5f9c4eeae11f8bddb8d16a8160232175232531fd9bab68403648e214b6710da9ebd30b62e46afc9e1f0e53752b3ef34c75ff3c0261caad7bd3378006d9efba27f2f3f3c39d26a316ddbfc5e5fd033b2fbffdced6a5e10dfbe10ddb0b5dc9dffae2fe02fa68566ca13b7434eb66686a130440046bfc8fc6377502a8f1b701c477c5624e3f1792aafb315715e6a62425c3765137f5b0d4c75f196531860070b292611dd401ea742bbe0dd0e4d96956fc1b23cc90558373663e3e8d854967d9567c961e2e4bed3c99fe7b5464d2028659da616a7f0118b607a8dddfddee3745d1e9aa07f7da733e35721fdfc6125303c2e4ef231f8d4bf58f3d83511dc57a88671202a1f63f5ea7e316b76621b1bbbbbbf72be4a1eda2072b358251651635fc6a0d4aabc4838621e6d69887f93036f3a5199525a0548d716b9a0d69667d61316f796f202f154dfee8f25e0bdc9bbef35ab6a7f12da9a711f330cf8111887998f7560a1893a72c358b86a01919191a345ef546522fb3270778cfa55ee67fd0785511261ded81f91668111a0ff345521f2303e73d470354adbaa7f13eb2554787f4a49e062d2253bf32554a465b190d8eb250b37852a997bfdf8469f09a28938986b0985ba4dc73ae3dbf8e4bf006eec31be48737746ffaf006efc31bbe0f6f387d7803eac31be6dfc0f25ec3c4f478a1a10b85015746a55f3d8573660b65a9d968283fcfd4492ee6b0d4fb63806129ca4343af52cd145d6f29451e72184b69b672c4c6124a4945b3a55f96f055f52f00e7d4d05c6ba1468780bbfb07a6e6a8b42d175539eb14cd08000000a3140000180c0885c321c178382012f65cf914800d7f9a447c58970bd42488619442ca10630c01000000110091c1b409163b9551ed98c769e7d5baad3df3dbbfbbf24def67e21a0b9e115e1a782e8416f7b6b57d48f145cc2a12fd097deff5743a54a891d8d2e57f635e897d73790a349a29d7eca5e5858a982dea74c94af7d8f43e45b63de070b5ac899aaa188d342abce80567f699c4e22a94d56771f786873262048753cc7ce88c530b67e8a06a8a370723acc2d4c68fe41ec6d5bcc6602e66e3cd81f05836a8c723dd79f70386df2351b416da86917fb50ddbc47a723b7371b7db83e5bfda7a361ef5ca80918648670528357df0488bb85b968c590bd10274fc8176447871c68f9963a7a412cacb3f072a44feb810ea520ad38bfbe13032688262f4ee380fb0264e23f82bcd28e6f58be5f860f18329053035bdb5d201c943af1c0b323d771451bcfc5ec473ed518bd5efe2dd2d2f6bca2cf0b03c657e4fd7d5ec6d39bfa44fc728206c55aad5af535b5f75feece4fe8d51a19734c30588d9a9ec7b3fc6e3c82bafc972a343cab48ce4f2c6774752b59bc77f7e41ca57f3fa9b2ad290e5f5fdeb10ba8324948aa27c2c9278b296b0a530d4ec2cc6d36f1f53b36c120979761998841ccd1bbdbc21d4c168114e64c1aca2a501f502f6dab1c0cab6b05e512b029eea7a1773954f4b8beab37ed17b74734b5491c21470291b137b0b3b7e5df7dfb7850669465654f33b62b83149decdd561c402249d0731dfc333832c37df63af9ed0a4030d09b98ff129e208efe8699a220239c68c5ed9a8c78f0a707a9cb7ea5670681156e05ea31fbe471efd77ea2d9999ec66a7c09afb2fda4bfaf4c3d49035950f1cc2ceac7bd2cf4f0a932575448fc057d5e56c1871532941a9661dad7f238191c1c3b85d6ab499f48d82c70b47840337c09341969d2cd9638d9cb96bf4adeb1843f466bb8698340fb582b1210eae7bca260f989788b3848883ba8b7019ffdad50e043969bf4bc8c8e2b3933c466ce1f738e6a5f550f269f004088841a684d0237cd6d3348b18631aea710e34b3527c90998b24fbe5762d83f01ea34612c09b6bdb39667d1330919324ac0fb47692e9355ae6f7f0b961901aadd5c33f8b4e9b877ef73397c376ab40d52178829fcb6e62222fcba5523e204631cf4016d311ddb54a0e90b4f2c8c7ba2199d90713986a09e2294d88a2e9e0fad835ebeecea744eebfd98b4e978939362c71ab1240e5f8ad3e380079c3fbfa9b1845c025d83c73030b9457a46b60c012454a5544efc258fb561ef68e8e63efca41cd53cd8eb8029885b21c23b177ec8abdfbe820ff3e960c1791232f17e20fe5127d1c64c985b41b0a64d386a060fc66518cdc65e174d66711d5cef7bb2e64cf414674d997244f5c1ec7ba9193eef8f455eca919fc520abb06086b47ad21c0bd77f470b709707f58e7a26f0534e95155a9f63224a7eac807e5568c13d56e3a2175ce8a17743282cb4a0d4320b336c8ac71827ff36380abe25603eb102023d5c865e1d56b76f6fbd638142ff74e1e32ab9d790c57b57f30c5930320ed6c136c69500413fe9d89c5ad94a9139d00a18bb5b5037fe9ba9ef0cc4aa1cde81eacf75c466148890019c503cbdbd1b107e44d1837b7a33dbc4e76d45b8f10378fb80ff2d16578b7dba6cc9ff02afc8789d0e6337d09116d8a9185a301b91f2402da6c553e707dd651b5db2d2b2103d6fe048e7f972048fecc6c186a0871864d6ee00dfae7eed60661143c8d669aad017ead43a54d7af299d102d8f68a5b606e43a8ae1dda702a4aac7e87501831d8121228b8b63022b1569d82a24da8b9505e7fc8cca9cfa6c2e2a02e3bd5b3e393b3ba1b503153dece15934015085c788d9d8e5d9cd0f05182449c81fdaf52fbe20cb1ab40ee1aa0a76ed786f58b4c85593905ef3eb13bf3a17f20aa6686e91aebeadb8c0b3db9c52c8dfe34506a546ad45cbd628332fff195c7326ce6a82899939f9317625fb0c273ee4bcfcddd40215fe0282115fc02fdbc24db7b02763e382278b9de87f3315d8fbf050fa8291fe7a4e1d258f9e48e57621c62d7b0326a905769dd31bc16b510749639a2860babfd5ba5e95a710547368655e5161954135b1d29388c8b2260757c384f118756859ee612ed16061474525821c85632bbda6011de4066dafe4f8ead9a07a6cd144e20c5e2e6d5a0df53ebb8ea3bdcdd509dcaf872eb9fd875f90efbb389a8b37844ef3a5cbf72555406130f18384341ccf2cb99d484d91e11d64cbcc358a82426b19f95cf5d0b71c21dc4f79498db48230e51e1374b51b083f6b1a08788fcc666ed2e3fe60f5d0fdd1fbb370d0a0bd380d594713391457d0122acbf809a27f931f430da415c8721cfd225b2c84449c8263ef762bfb69de2fa7aa3c9ef844a5df40b907e47057f796c458c48c4c9d08effdd0963736edeec26d50c5190c3dd66d0ec378ccd22f46e1006b124d4ba3245080331e265acb929d6ff82ff005e980ac4f2729ae3349760e86dfad094cc3efc86337d53551b80900fd2f285bde2f103fdcacc612d7f9bd0cfd97d2d5330b27288ed8c58bfc9df0066ffcc0845db121a18eacd47c20de9d270634eab27d41ab26366f6c785843909ad8b39e1d26ab5ed4d04aa17c390a41487cf9627f63838f38a20f3910405b35e6d62dd4e3c29965a633d60138b04fa059d99f968e509865f67be994d7e3d0d5f2e45252c49300a5eee88d03996c633af0fae56ada28db32eabc4a87f5240385b6b4564c9f5eb8a9794238a9186c813ba6dfdd1ba4bf0df12d4b7f29507241db2d42501f1dc2569024c32b03e522564412ebcdbd1c7566620f6374b46b8a64a34bc8b56b3fc3614af4454e29a48b01324724a4832aad425226e2526bd8da4d96280c24a84cc811c756748b046a610f46d9803ccd88b393ee53ed6015b5dcc81b7d031f803a82b756868417d9a0072b69e2d92dd4598280e15d244d3d045e82c22426ca42b20a4718e21de249202be4bdfaf9d6d6808ed431f094e011774f3aa8bc87ca7e1902f2f0e798629bde55cbe1076eba40a33ef51ee718f1c6ad4d8d18fd0410c8001b837aa38f86043abea8615c5eca52951a19485e248f8d31a1a7cd12e23041f1e30412fab9826002ff7748ecf526fc335598f7b888e3ba0f995eec93363597e01c35029f1b98554e5609cca5812a4fc48914e4629ec6641401b98cea0a5d5b58f3371ae4e4f492ea4def4a7bcdc31ccdf13e90f7f0bd2eca2cf6c1dab1bd0696311b3451d8cefca57b9731a8e89707d4e3deb314ace13805e56b037dcd3d203e21d8ca8f17038d68ab9e857d2f0dc3dcc4e607edd51cf7e78f8e0d136fbd7935c94317d26a45d09572c90f5d98f800fbe57ff10bb91f3b63fb845d6e734fd56a7e04ef851a0460d2786bdb3d6a9857931d8c4149bda60bd4f973b11c6e5107e1320b81888411a276024a068aa37a469bd1953a4c2fd7130233497d2efd40492713ea7967fb6e2120fb83f2614082e77aaa20127e9f40f270bb2530f060142402fcdd1e8459a2a214024bb20f8f7f9df1af41d34cdd37733486783800443e05886dbf40ff24854789aa6883a0ad6666006a3d4abd229e7819c65e04bbc003db109ec6573c975631223716fa01aa86dd115a3d0724b3e1617c044127611424881c8bcc3c3a708f0f93358cf596e499f8974805d03065120c1d16bca7f95a2b679cebba8f0848e72a50453fab75b27eba407ad0b5b71f459072a715fca0d5b22ee8e8062b405d0033178b19f0e2e782c8dd56cb61273e2fcf54ce9225ccb54dfc60c78445c2276a75774d4a2fe774a907218d89e40703fc1395482a458ed11bcaafca04240ea2d69857e01992dc11a510f7fc4cfeefc7176187aa83a1ecef960e174b694663251dd7d98ae0daa99361fec17e9d8712b9068a7bbdf4d987befad6efbc428fe846ccc1cb49bb8cfd05ace50aad173ec8048c72a15e24d5d20e6113e307ff31145cfcd058a06e3bfab76b865ba066af9a9ca9229205fa52a3b37c0854f804438072e84a053f10f8e455585c8b371fab5aa3fd4c4d2d3d4401ad29b857bf88d8c3eb01e729fd767ac660466a2e3843faeda9e98a4ea5a035bd669ccb6ffbaccefe5520f1479312ede3607864bd4ed902066d86f06875e2894dd78b830d56ae5f03744439c87a4608669d137194f7c5f9feae11e74f1b184500c608618a4472f170a246346a792336327c665c13b3f82abcf9b79341ee9e71a8070834f41e58d5e98043b4322d4c28839495804c26c6ed220908ba8d9d790c7ddbe566ef69adf0041030b0a088e458812519044d2a499be8070702293eab277dbf536102d27e7d91702a92fdeb146e46101127f13d45330a028ead79ed09e8e13cf49e70b42d45b7cede0e1364806112bae4ab2597f404d1adf96b5d5958cdcfa4127fa968edfada84f5e5fd6fd3ed5e677de045d5ca94b0ac229307b56461305791539317a91f1847d119a159eab42d6c02705bff4b80a02f36bd52be6cd794021740a385a8c35553af243470947569f2e8b046d751d5baca7af572bd42b1518a18cb0a46cc646c7123fb76d7cc39a86d23da74c0ea36960e57672cd48672207513c48bc97d3ea631244d3f97664710c038ff16bee3889d4ef98b097af3e48a7d22abde3a7d6348e5741eb00e2480aafb7ca43a7729eee7acdf5d8cd37a1db3ea591870204fbe23e1e796528b6d3e8150ac1707e78bcf1ffcfd6f81af4bd35d6d32b4c8f581d95fa209a861d46e5e6c66d2485d982142429837e02eb7898230715e3651ad3c6aba53042c6c19e44bce40cc214383fc4daf4510da9e765cf8e947da8d909c0c2bab24b39f4112df47b24332f60c20e53ddec8c4abe1eccdba244039b8d02d4a28f18cf3eb8a3e30e7b1cb3bcf5d736581691c7410b9f419b3e6b4fb00264405786e01d1361b4980d9c5daa50d127a4b5b9d02b939f92e96d2ff3189338a6e5e152f3150d9b483faa5a364d883cdb3acf930ad848a149b1c0a12f1192dcc7f14144f9864e66cc328f8a8e98163633b08c213ec4788a1cc5601303e969da4d626fc5edc68aafa9f40c24e34bc20aa0a760e28b3ea745bd860372871113455dbc2a7b167d5ce4acb6621fdd085e885defc6c6a183b478dc6a0debeaee59bab7a5baf5565faa2250220291757a293bbecd87ddc1dd52df0fffa7b53764f15d29a81bb572533ea41ae45a6ad355454f5ce13b8a78af78d4831906ffe6ad22223813cc89999d901ca1a41cd4cb9004375228b8cf559cdf98f9c97b951a4504badd94e2aca27368133d68e609ffa7aa409c58ef8a244a119f3626e4e5842b54f9e9958caacee0af2356561293cb42c4ba169ac4b0bdf661e5c887ea2f1a6d1762eb09cccc7849741bc853838806b329d8f2b13952b49645fc6cbe71e73bb12d9746557af5fd9fb5489fa54b870d16ca9ba7f18a6a3c2bc744e35c9cf1ec74c232867340ea55cbc8d8fc08cca8c5d97fb8be303e237a590a0405b47c0234fe688c667402367d66ada7380ebcd4f665512dd7ca7e8f9a133f2e07714aa8883f173e85df2b2b4abe266bd6ce70d2fb02ee337b87c6d0cc4de5398d5050b0ef159cdb3f1476ac6a981dec4f2ca533f472aed91c3b9afc37b93b86a570eaa76af9adb17113c4372ad3caa45f78a72cd99681777f39d391f7a12b584bcc953d52185e03eb64816310a7fa42083549bc2c1162e15c48c66f5c5e52e98879cff3d327f51ee4d99717941609caee4921d463aa760733aa05531d5bda5f3e1b391673111ab11d8bad50eb32734dee8411e03ffa78942ab85c60e484eaafdbd64bd8674a3e1a5f63897266595e45a96023a0912ae192c092566c7688b9c8d6428d33f1dee391d819f5231bb0f2d5fc192bbfbae2b5f20b8bb222bdb673ca0d1ca010783323c8715b680c0ce4d76504c9f5e612143ebbb16a15a3cc35a7c7149a9f3f6c2185eee67899c59bb32522467a47f31077fa42f76c28670f8553c5d1d8fbc520b4de29e3545c5f950e66c854c02fb27a3c3156b4aa9f334bfc38358d56cd55a1082111af5e2030d4f92e253821861ec469ae1f8915875e3233eb1c997836948273d3ec822d283d76fa84bc9dfc30a426147420485ab30b18fc0a3e04397015844df6b11a73cab8648c63e59342b96a2ceb570229c5933dec115f6f5040088e1d1f233002f21ff43d658e45e1a045f72d882620d997911be4a9aadfbcc0ff29780663c210877eabd8b9a76ce52780acfa0841341f156f022d784fb9b42a308b3795a470467edd54706656637887eb9f722a99a9a3a3fcfdb112ec2fc272e46510b930098e4c4b47260ad9d1d66a76951de51170910cff8f10e697fa59d9b88eef5cd5046077c029a218779205c0f5908f73bb4de227b4b95ce4729a3cc291c991c26e97f111b06e97df7d4cd3706a06a02045fe26fc54151c01394cfb37cd49a5a8ea4c8b6f1534cbf7facb3891036656334c6145090201ace78238094dfbf803107ac6258e44f73086ed68a0edf8db2ffe75db1c0ad0cd5655530d035d95f32a792f1bd7a26ca2e8de477dd1c7200b2cce99d6c704d48ee515086f871cd3e7eaa8fe48fe559f24446ed6a44d1a4c898bb8e89945ff0e2a1970d4810ebb87ddc33ee9f87384bda9a8c80bb057e0e4d7b2cc77b4dfb471a84e334b7c47d14b9081d485b62e8ba429d0f726c6277f86ed76c2b6f5eabcfcc9213c21928081cc0d981b81cdbf429a967ea41c89f4079aff0e1ea54742304294a3a2ab46c8b37b3bc9ca8f3364494ee7cc177831de0f26d065656415a06413b4f27893f20eccb9234034d1cb13543225b194e9e0d0e573a6e2c5e076525248ef77beb6189e239def236cdee368191467789e8260a71a018e478d44d8e2e521a91d9e1f50d717a743b183cef1122b5f5bd1c255a0b1bed3d8367a22d6ad54b637300e5cd808e52c464734a2ad874fe37d0c6e1490a7e76ef1be8e34560be0862d144c319847e8c9ab7ba89b7c48f30eef64fba88d84bebb1a3a8843930a8c2dc965ddb32c51c3bddfb481a0d98b116def393af00912bd830589e5f057699fed9658e66cd153cb3d9c370e17f7fc377ee9611cd8a5e818d9efcb105de8fa763820f763342c2b2335679a2c1fd47de39737505cec5abec0e9b04d0f2dd476c994f3b9948ced2db7192ab604a616682bc5d76aa01bec6673a3feac9062da82afa3bc64921a9f70c571c1b33ebc24a8d57d1f5cbba8e774f6f81f6f5e487406efe4768206e07a8626bccfbaf945f0766550562a9d1011be8e51902e88d9403b5aac7e3933aa41d43db805253c472cad605faa4c6f74880d58fd576fb59ebf879d62529aaaf9ce68672a2af567984f56a006831835a7918cb1f5c76974206b1218276799dd6c1472e54c5ed382c1f1c94b05960ed783f7b037253ee3c780275b5f15a94be48d90398d16cae9d5c59f3ef582d0d1cf797d37fb31b3cb50e6e495f2b25ab0d40c251aa7cdae5af525924e7d24e7e2c3b1d21c309986bb1bed6ecb8a55970d207a4c6c7a6b06b16da7b6074ede10bab972442a1cbc5239e51d893fd01aa36401cb988a8a102955879dfa383557f5558ab7fdba5be959502a8b00370a01a900ddaa14e0db4f08445b52cff22b47cf40b58d563135fabb052b4add1737076d639017d0a7fcbd100a88482f4f9ff18d67fd49eb889ba42411532c47a04cecfb1f09a6d434d3f7d0a365c8f20783624f9c05bfc4d10ee0dd6cf75abf7a37bf5170a81518b5a55adfaeaaf042eae912fab3850df92235a3e36c214a72dce45367361e41a4c2749ef272010c27427a9140a153e203937bed03cc0e5eea8aec73eb552eb3c561e511b87bf80ccb5bda9fd03dd08ab95468bf14eff7bfbdad8de303838e63d10624cb99af91d2bd36e16632e68dd9be51273e8bf6a831a9ac44e43a2fe6983e1467b551bbec1856937324ae22c4fb2f76c18d15b3140d32e2d5539711081bd1a8b4bdd63ac98ae596083bd3f3a6b5fa6d53fc611d2a08450e33a5d52c513d81e10e4bf352d02851d7b00cff3e122786cbb40a13df6b36d2a0944162ef2a7c00b3024f488f8a6ced1dbeaa8388b8589ea5b4895dca6e7e701db44ead5bad532c6b491a8067debeb808371079da713777c61bad7c26c9370151f3cc73f0e755030b7a70d58987773ed9fe26b69f50005f24cf9992d12a1e0a24d4f9a8ec37d88fc11ce6d55ecc41436932a6a335ff29344d634a701978b9b561cb2d0644ce15c394a025c31bfad0018cb7aa66cf721f44f6b22622c384493c1dd112c473c514d08225a390a5e65a3009cf977448e99f9f9ddbe182b967200fbd1dce112a0d5e98b80d1a45e2236dbeb7f3cc6e726bc53a912089e15008a3b14f47da5fd9614ed7717f6eac49f8224038bd4e0050b4273071562094c1389884f9f5dbe2beaed5cbaed27f675318021de2edb3efbf9205be8ccbdbc1a25524439b0756abed5e5f2c1a64a9407a654e0d5e7ba33049f07f18058b4d5bdccbb62a63cba52c752fd289a2e83e3d0bac97a3437917e62598f39840b5580dd7f4dd93d3cf6f485afc31290d42bc781c433f5df9cbf9d81b8cddebe27d87469df606c01b83389e52ba51ce0cb2fd81516072ce7898f92808950d63f3f73f5930a7cfad1e21637fb4827929401e66e639697bc06f0060c9bd9fe385fd1c9147c8067bb0dc58e9e3c2d70ea67fc54efed440354b1c9aa19ec86e861abf5cf4545f04c917052eddf46e71bdc737ada115fd68906a8e3056dbeca11f3ac01e0bf980cdcb49db3f4115c2aa447e26856d0580066c99417dd6bf51f03f16aeb8a7e4736fd1e7fe5ca67b6e1dfbd0820f05066cf7daaa00bb7392e0d5db1f581744be14ca11ffe0465b03e711fd5a278f90372d2351ef2c2f1784bae1be838bb46a94d4f2b1bcc5b84fa328beb5629f0fb6aedb24c468b4fe73865638b3b4a271d63aa2bb04a7594ca82266c6fce6d3a0bca416957c0368c18be540ec4b50b8a18773229d76fffd4c5f679cf64cc321814910d1dafbe8e7699b708624293b6d54f074782848a9d7c1d15d52807413f2a8f37f244d751fb16b5fbe41f23007efeba9ea7de4f62ede5fd70abf78ab057e142cd9dae07e2c73ad0775c0c5ca410f6678644c003e5240df0c2ae16549ea6566cb978dde2511bc06d96378f5b525ee7aeb5786d7f80e4576e748c9e0a5e2715fa10caea48cd9282962522c76bc3476d9f87d328f23833c85f278400d3f42feb404b7bc06d3a875dca3070948668b7748282482a25384034e7bea66f3635bfb6b92c276672aeef00cb478016d6e7087a536a349696202981ee8ffeff0efc5d986e34051f1f60634344de04cfb21c8467294dd6784b819c6dfb5184a981cde8a8e536035ad93533ce2abb33210690c978e6520cf63d6e5dc72920713ab84025a5e0ba9b2636b9eee072381183abb7d222af69b8b5c3a6add6e82d7fd7bee0397b139a6de5674564cdf3c0d14c69916e74a1c3249a760f8c02eda8fb8390a40ba751190e3b290c38237322e5b326670b7dcfa6218e3481b7911ebacfd0716218d5ce32e45ddc4439d02aa135fb440e0d7c3d1b7a09e09f485578860dc06ab94172674110a879a0893c7106fe7e1a1cfe430e644387b1a24e10e2dc1097ae9d0ec772cb9f1ed3be167a9ec7c181eebb28cd1fbf87d7aba6eaac7f3f3f9d7fa510ec7d6e535c1dd6064399129d9ce805f88420489df336fd17282cdda256a43254e5bec8d532e9b69cd9f6d6270c7405021c7ab1812adc751a0befb952bc2e7eb8fc6fa51a5d64d3ca8c1dfaa0495c8de1df47f382caecc874422de9cd258de68b87bf7df14983994e14a85d0bb1cc437669a90f3f7421a38e9747a4f4a098f8fa59c437387b8fd811c1bb2d8daf1bc015c5d02da80a7e16e1854005c5ec25c8c17e659011a7c9fef8a45798cba3a0f5a99598c500d78e640864117d765a0fc485b1b47b958acb9be54463b0e37b134a5014e11526e54f02b50ac34321dcb69077f5fa1a2c28b82305358250a5c0ab26b83409ea6cab4d768609fa5a4d639dd57313fd20ac3c0652aa65681527857199ce7481845d89cb4fb3f4105556702dc56b2727d1f8931d04c2394e74c5c576dac1987e9d8eb8734f8949b29fc0daae39775b13467b770de0cf08b19b3d516a52eb051f3072b395ce9b1f2322d6549ce28aa941525444c26b6fc66b1047bd7d6b092b39c41fb0b47c1ca9130b088b2afd06710bb2f434df132d1baf7808fed4b16c2338faf1bdafa0b46da98dec25423599b0bd57d79f0fc1d3222ec595e9cbe4565fcb2a42a02ca6288e8578de5e255cc42f0a1359e06efcb98647a4194ed4d3ad9e9931c50f1db01fb896a90cabf9c85d10b4fa7fa20ba6093993fa3f2232246e95a36e888f4fb3532ceb03708b44d56f244db525b8e89414dfa6f43bcb0a3050a63f90706b862b77b4df8d4ff558737d9795bd74e36423f8bbecfa61b3e531de9ff08070194ca7823162b390235a6cede75a01e5a3f9b991549cdf8659b5b7452a8f1d765a5677e14eb615445c72952d1364bbd07dd44b5186567a89bf2e5fe82a80ad1fcc69471d4dbf3185b7e5652720a4c9bc683bcf3f790dae8aa8b49a91420000fbe254256bbc79c5a1ec43c4bff7e1c3a44acd1626284c076f40fb7d7477eb42d9f4cf40b756ef4980c694c0b21324ebe61a230b6408bbbf232196022940f736de7f5d8231e2060f901cdb3c6c318d59896f40a3a48ef3f33e2d38dca409e9128adf7d9443151b750250b9e49d9b263733d619f91b97e108c647f576ab3b5915618e51917bcba094f45fd1f506effa0f983ad6797576be0abc27c9ffc8a4abc21b0afbff13ce097c2ba9184fadb26893d8fccf34e56f44a09892f6e0f3089a08ed9c9b6e48754a0d36982764a03a1fab743f1b24722255420572e753e2b49afb5e4ac3748f0d9942c46c59d993ee99e96a5870b3300686c9f01e8bd2297b98fd2e9b47e90433d041d4c8f23c43440acee854753386447544f0accf6ca1f72499846b750379f2d9323266096bdc8cce4171222e8f7d0c01f75fdc7248d405a7cb41b7ff93f80d8235c9c472ed41eaa8e3d259e4cb0c99303e7972c9385ac989a530911c94ae62164338072cbfd07faae834b90650703ec10ed9d063454969182c0e604a4f579116a263902ff095aa8e74248d6f57137ce0cfebd02d53a28ef380b901d0ba181ef6fc0c878c13ab7ff6ffb0cbe35780f694b76b208864f773404060b7241139f006d99916b3868fa9d15c620d720d112000a42ca5aa0000e581aff6ee567536d23ff8b7281ae4fe00c9528ea7c1899f8b1f3eda4e8a853416fe3e82b8ea4694101a030479dc370aa5fcfd1327e9d3dc78113f6a98519a38e41a3d36f07ed1324e44337cbc5abdf329afe51340587014410114441806bc5ff3da5417fab1921f7c020cfa943ae1606b97ff20147dfa2626c19d93d88ec1f0980ec7e0cd8543bfc2c27e6620af915749143f021814cc594de1cc7cf606be1805cfce8d99aae54392ca3d144550e4d25a845c4e9db3be45ced948d422e667bd27b679eff42b7081edfafbf963a385f019ed093224c34527616a16678d5e4ad727cb0b1a71b305e8d451c6e5ed85316565740e06689d514da85fc1491b9785214da6792e9aab636c4d60920b67108146bb781ecc2a38c3fd207b4ee2898e0fbf192680837b5e544a353491d6fb3c200948aafae854d2e98acd92aeba71d45e44126e7d35326dda2cf98add39ed8c9272e02bce44dcc9924129e72b157217963b160ed9d9b406c270105620689ea34c800b2e17249c2137034cfdb528f5bef811757a8c0be048f3a980278b8a860285258ced11c1404db8fa00263bf700d0d3a6a9008b289fdc11e9c04b1c1ee03e10503e155949e795b29d82fe4fe0214ab5a935da5f90c9e358b501c23c3c52b90623a0673861405a6ac9361753c1e00200a80023458294bf3c000eddc713a65b9032e4082f00900cdfd24754dca8073f8649715efcc89908c3e69ef1a83005be23830c43f2776efa7427f716a468185a8034b691e45c71827b0015f14f98f5f6179e9e4aca13487a34db7141d696734d56d6dd92e066180b96a009b48a5a2e41278e0d0702be034c8dfda80f6ce841dc7d1b7b656c197eb9517465314e2160ec583d5689cce9217646e176b5a18f03174c1814945ffd3a9bea481ede27f4fe43153d00d571c5a11d3c4fdf74583072fcec06869edcb3fee486c0698063f824bf4f80d93d4c0d239518cc5905d0e12ee18d2f9c8100e9bcd21b32005d96a94cbac2aadc41880b4a03444c920af1d90d315be7039de945d8474474f0685ea09562018ceaaf306350c8c335e0126d9f6e36d5ae98d4d2a58a028e1e8d2bd9472fd6d6480cdb7c330b5f00429d290933d3d3f2ef925b5ef948f6a1a9c952609a956d39e1e3667805b496e7aeeb21e2762e543c4ac52ba4b5a23b1e8a2ce11faebb7d82b2d3da7ec60ce2006cc1f74fd22c32a947840056f729d018c4e2e0ebfa4f5cfcb82d9d7110decc17e8526dd21c44c64ad397270da39adf4468b9874601f608a000cc7471a0dfcf07dc0bbc3491f06a4320c7796859dd035fd6d0a3c95c3dd8dad98848da817dfb72d2df6072e6e301e768ce2fe6942f31bfd974c1cb3fe251cd04a8a0b06ea7cebd6da2ab0d1a821056b4f1b9462ecc6d30788d12ea0d52fa8c1cccc75c10072f84ef9417db944f3ca210f5b8a266cef1efe90ac025b9e6e6cd45f3b93350cc2a9cdb1d8493f052985b7812c5281ddd4566cad610f71d89d78f6735f737c10984b239ec74bb1e8c978482f30d99572f9144fa05e9f9dde892755fa5be02d70f6cda86a46e646a06f7e8a42725dc62d87f9d49073a0326986f295fb6728a5411b44e8299c90f201767aa2940160bd100c6b2cd3c3546395d85ce55a4f138b4b51b79c845b1f87db5ae753213af0419ceaa1365ffa8a687850ecfa14491b28c40569785a82cc1faf7aaa8e261fa2a9a8ec237e353e457c005ad962f4c89c677c09fb97e7971ce6bec131c7b01c86179cd0e728567118c779283262ff496352170ea6ae6fae346f6a696e96d8e4222b0e4e819e2706e238083d2e5b702bf3d411ec26313e583d601ea3125e854ff40b0460cc38e2eadaf46b19e8be7f24484aff31aab00bfff82b16c766d50f1c013207a7a3c01102fd2774d34d293f83fd1d5fcaf6584aa0edf42e9cfbc83cc44cf1453403ca3da1b1409341c2ca610521be67863525dab21bad16a0b5bdeacd84fc0ddfae77dbd70b4ada313bdc42000d62d611ec1f86d3a67f76937576c0ed11e3b33fb3cc36d23da22d5078288c1ac600b01a6a57e6daa940790c9e1f9b00e29c838da70e9f4f764d34734c37dacfd4042ef09e115f40ed6b6913af4dfa7d201b4f495f598de24a264c2e053d133b1bec45e2acacd7dd8d8c108aa7587b121741a5583852cef66861eae0505cbd3067062a7f8d3095d560d3b22cbd5c34057458380a7d03c1fa42dae75a2740e96de29952923c02960631f7f328bb32911a2d42f755241dac633f797266042deb468aaae04335bb769a40909bb7a271d95b0cad0c9b4797221f591f000b5ce20e98a81caceab42ff9f5be8a9c713e3a0b47fa1555fb71f7dc00dbcdf243cea9c3452e101ad5349505745ee218ef9d114253d50d08c2bad6510035f4553d1b7cd7d4db59674519b93f4ecc3aa4ee5b1b25582b74088c5ae4824ddd7ce8737e38f45103e7aa5d9c944895817d238406a50156fc0b483a9c3a5fb5f72aba96ea6002f90b536faa1982821d33b74126228e5ae2c9ab9378ca2c82e7b552802f4dd2e4ae317fcddb691c5b17fc89efd9bcf37be5ed221749ea45abf994c5be20da0b02ccbf6f083f707ba7b2ae4193ac8106c060a29111ef67efb9c02a334f56c7dab37533f75eabcc62b3c9d8145474a857932b77984745798c743e15286e5f5175e849c70bd3420a0282e140d8f98982dfefd0e8044fb7258c89af439eeec93db7feab8101c908067d1384908dd0708b310664cb2df432431a0fcef585478a2b06636fc4c69226f45ceffe9ebce98e4c9815ad858ec0d057ff35b9928f3a56407fcb712be32898ea45b9bf07cfb45ffdd76bb3a6b1f7625c3349c48cc49f322c75df108ebb02bcf0d8431f38724f07c52ea63d39183e25561a113fe470113328e5c21dab7611e0574985cbace51f28368f5f16906da62dbbf4a2b59b820536e1cc51c3186f4b124860d2f8fab7b425e3d69993757e13e1e858e3e8fedd41704b21446a6e3ba40ad79f0009ab3e47ac07b7d5eb8c1196bc8d5f7ba336ee922f1901ff22e27c0541e8bb1332ba3097967b2cf5a25423c083ef49641ea40827d6ab54453b6f391b1ef671c788afabc53784004e0ac3055b7404c593e51ef303786acfb66eb3b6fd18c605a0c24a321d296ae1b1cf4c828462dba46620726a7300cd7c0ac296964519230bfac14caa3b5e55e1ef81feea6f5e44d5ce82e5240968ad1d73013bff8ac051dd08de376d7490509a5c70fd73343cb4a7f9afe3a410c3d29b5233f0b9ec5dc5ef05108668a980d121235196b25cef934f97db918ae2b11805a21c60df916ca627d250a8003638e56590ac28f393f809fc7fb243cb4db18b73c10acd69b6cc62f23bb51432b1167d33137d9710c9941a32ce27c8514908406e2e1e4a4b0070790098a812ff4c03651ae3baddbfc0a34dc3840fdc39700fcfd985978537a1760f182da49c74a3a4b0798a2be03ca633211ebd17c41d63bc183eec26df59683f385a2a80f90ef1d93add32b09b6fa930a59c5bcc2ea2a9e7dd2da603bd88a6ceaa9c0ad45efa70592a3c2c514be4a7cc03e2942d13fe37eb0c9110f1ce94abbba3e3d2143c4e9a04b45113bcac509018ba5543b1e657830e9287b6a18e51eee27d6498000187c126553eafd6b1329ebae9f514c6553c28acc94a64a1b44b14aac16d870038b232eee457742e3bca1a3031689acddb851f0b5a85111b7311c0514a6814c01f9c594999072d3096b7d505cea4b4994e001705a6cfb8ee6bd14fc6cb496df24466d7bc0fc60c6e0db1df59d92989ffde46abea4ccd212551895f91d01d1b33c49f64da1637988ce13b82421d6443b922bd59726716e0defa2b9db4992495c229a196c424375fff4befcc510d691b2870cae58dbe8e8abe1d966689f0bd9191dc599a860127934e847b249837770eea1e0a4dc41ba7fab232eec5c15a0c4f035f8c627de68d5ca13d7135c0eb5d3715c276ce8bb99eae28a8f0bc69722ed8fd78418dd3ae99b7390832fc76507939f17a3744742f381526e1c160bb8df8f3a07773ab575cc5c09baf2b9f5e07c4c6321a8f1b879c62ab607de1d2c8bdb2905645b512406e5a905719ee8e0b3d71313ba60c8cd4c39b4d0d470ecaa44a6f44ffffc1080d255d824d76979e7d9800df8c6a123d03572999b78ac3dacd188a09c7527218128a2989de2d55a6c1f4578fc10a91b797bb8e36ef3ab00d6cb123861a8acba84dff41456ee16c4658dbd5d272a37ec3cf784e2e1e3686a4911b8eaeaf4350f1af36c56a5702767a0ae4be41fb8d1b90728668ff6bd59e42f1210ca5b149fb88e5dc2a9aabb032165b717465a5873b2a0650a23ee3789c70119e1264153638e84dd4f0f57ea4ea4c69da63c8c49ec712f86501ca387d1b50d7bd0edb138234791cfbd7717d7a3e8a914a8d9b8a1408a901d74366306e30805681bce131d43f19cca17bbd6a45f2345188b822f522d71b51b9b789b1c7c8156ddf1bc82ca702671918fbaad97b50246b5008befb786107970fbb5afb2f9a8eb7af54408fc07578b9c5d9e05c9874e16562cc22ec8504094b987337774ccd2e0fe0ab231e53daf8b17371e0ac24b98eac34e75bafc728ca210667268cd0ea9931fe2203f4b82f8c867c6c267b8dabba27f830bd3093115bb07f299067101438b11bb9b6a28e3276e2ef55fa41c965c3d0125a152079d545edf295a738eaf960178e481e202be07876257109cdb685d8ef807dfe3ab5949ff68a7af248e5b1a7ed2a46896ce3280ec961f41a14de69b1443463dfe33f67efb3dc653fa1e32d931ca564c76281b1c8b8b89c98b5e431169c223f1a55c662b2de6d512b27961bc45fa60fe0b10a1d8164cc3f54f7c7fffaf38df12afe756c98f8308afe695378b03e45d6c7bebb77cb03ecd371c3eb4b26fd15034597e6fbc3b1134f97b0b092d3ddb1a1ff6f5be9e947e03c33276a144771419e15a38be02e510c75e9ef28ae856135fe5fb51d72bd3bc761b257fdaeb5ae3029f486cf26213f33f0bb474679c46f47e8d2e617fcbc012d054ef4d45f0d27c6653e0a3e5c3de49f0c84be2ba54ff56e2cd8a1055eb3cbcdf0b1434d5c7f7d2597e561d6ba1b7709886a9b75db967fcea762c0882fdf4c447ee95e9b70bf5500d94ec7e5056290c500674f2eb519d2b782608205b261af2a0c59e20fad4388b89a394b502b254de69dbad983e56d36af0c12ea014949d4752b080a43021af12b4a5d071065719c8dc59f70208e08e9ee8184c820d2900129e804c7da1707c2d3d341d77f6ae2a17cc54ed8de049c45938a6bad99b411e6705f024168dcfac0b0413b28b50f7b47b9eb8a62954b3058c08bde5e381e232be760313a8d62073f0bbccbae0f91f3a063b6a461c7c8a7e390a01f3c58bdf453280f395f4d1e48bb29d8d9b75d35aa14a547f4ae86590ea78d97638ef4c3328124845468fff97a298f591d75fcfa144db31d613b3ce28b64604750713ada3168bb1a1ee6c07804cef098574d451465976e0b152587fe2f08b3b7402542c6a88120107d69c787e526ad9267c03c889b57c4808f8790ad481a68c34128e6bde84880286d552a2a9315c019307acc35f2589d12ed7923f4662cdb69863da80f4e71cf6e279a9e451d3d04f2894473f480767c59e069197d8e109c86e5df088c86dc07135af9d7d181daf55552aee19d1ea2ba3702d2c6fed065167260ee4c8ba5e7e2ea553aea2740745c990e7e36c0c31ccc9ced3c51fdafa552f4f077f043dcb7fc1d4087b4f56eaea317a599ee9470c9213cf5c10410d906b8dd64c86125a434042197ec269211e0c60ecddac6ff2dcae4ab80b115807f98488e8a7cc88c18052966bff92fb15c080680d9ccf4c4f65c584f5b8b23b4e024a8c55d52ce92df8e1b20eba0f2531b411428cd26f1d0f00919d86bc5fbbca9b94c2948043111d5229548966cb67579fa792b19dbc4bcc14c9cb084221c294405200cb69380f14564e58d17e7a527e855087af61a499e619782a53ec75ec0370cb2501b71b1c0f839565545b0870bf7ecd70ae34b0259ed206766776c8fc989bac2f58c495b4022cf1d1130560d329ea0be40d464642c229e80a04150c04f5897e6a3195ea6051555d19a3f49f3c456858acf5c5b18523d7261acf1a489108e73f78efb02387f49d90ed59c184c541770d3f773d695c632a676b3be7f3855da0d48504a38ea3ea643367d46c595506906255b889c4806f0281992f6dd642e3fa1f206e911c91030bf0314cf798e64bad41c7f1f9a175c7ccfaf2d197d254139d8de32d77d291e6d005e6397426c9416eb1986c252db5121f1aa261665a796d1595b18535f824f9c8002230ac194fdcab2542cb49a9463c60491e043a9de7431d6d209a6d45ae5302927936076e3394bb6ccd525abc8e2d44800fba1d600cb7e62fee7edeb9792de45601380e7b933839791e3f7fd0b2d477cd21ceb338c7dab1ed661c64989ada48f7a39db9dc3886e02a73caf02cb8c35542c6d3b950fd3f6849f52193db10322b0e03031effc7b841aace407be6cf6349013891ea3f9ccc08afd339d27c4a3d5149ddecae5ab365420c67658e42caa6c391ee0db61090a52630e7b05aa2ed9e1817fd4ec777ab97bd7c5f2743962097a16b9ca8adb77cf51c22b237758b31ff92652f0010960f809a998bba1c99d20ef73283fab9fbdee0fc3e40ee4a7b115ba0d7e331b20a59d75a86d7085ed4f6bcac9120c045ba43e53adb3d650b60de56bfbfd0809e34fbfbe13a949e2676ce226ee745a3776fad32975f01d4ae7adf0753a6b080990d8e0cec34841e7fdd01aeaecddf87d2b151d70365b4bb3831b4f635184615a15ca2c0c8fd2ba4dd1a1a4f4fd5cc9140e9e8b45f44a2ee8e1b390cfff95ab798b1926c994b82bcc98b17ff08d7fac0764da8a976eb0428c078c4222a3774952306e821fa323e844a8043945fba2cc732dd3b5d9cafa5bcaecb60502be1eddcdc969b8cf00eaf40dcf65a16283bbd94bb76a72498938a41ea504929d18a28cfa2a7eaa87061c810d6e238c4a196302a2cdc4c69be2e858a00ce4479f748a114f163f7c728ea168f25341587c225c112660324ea95e262184ecc46ce0860d21c40fbc5bbf3f7e4bb0ff2706c914f16a27f8dc047b536dfda6807c7a8e71ea723f05e2ba920091598d7e85e46760ca9d577b98c81d2f9fd0b732d616dc5a9ff79ff2342b83ffd1ff7dff7adf9678c9b9ceacfd51924df3a3be1a2d45cb406439b9d5cd05777367dbb68dd8d68b6f8c1fc45557e4863b5d538d98ebd0753172bc67c07c7aff46fc4344b81e552b93e419af640359860074308b2cea0b9c5ce242d2e7867af5b66515da7be135a58544eb4ebc2ae788d1f8dd64f29433f4fae04cf50d53762c7a1afb3d50870fe1c5c3656c96e8498a8e11407ce8e1464c39e0134243a9ac6b95f1c380136107b32de4270f791e5aaed26d25feef42df909faa691fcac41e66eea3fdd93ec4e9236a89df1ae62491253832669de318c699f8fe6d70e1408c2e06ca9a7350b65b8c0087a746999bc299d17b259be67190914b044d4fb52ffad0f399ae38a0bfd05fdcea8508fc9120f1f8bc5627c1634f2a221a92bd14ecd60011973e64bc2c7cc52011b4923fb4bf12a53811e0fd58cec288f51e21603a54efd881c1736a83d1980509643bc7034e507b012e34dcdfc51711f22e490833f4b7ffaa140d518840a706081db6ba52e61063ba206c9cf42261786b570b97b18a55817b1829eead8a8c07b50a7092034388030881536edabcd08ad464b3ab7a8381a2046e18d49d272c7124c4accb6aa6c6194ac0eed39f4d93aa68c2c7d8c1c6f654bd1022b24ba3c5ea4da4ff31e420a48a4477e8de2d9f2f203c7e8675859b1ecde1c12e759cb86d30b097c34af934454a620ea2a8ba8d0c9d3b791695ead3efe0c16ed3a7860b9e506725edf1484ce90fdf64722143fd3827b7c8c9cf49d7393060351ef028b25e1d30bca587ce79fd82dcdad4e7f9d1ffb7e5822442855e5640586c85dd3bd9c14ece4418256c496b819d5bd5ca176fc5ec036398699955b536c0b04ded53fa68a53792daa4e2bfea05d9cddf970cdf6e7e3f32e70872aa55b9d2df581a9c1bbe9df9fc80b049cdffa87855a68516552a204a03d31e24f40be34d6515a2b056986fe6095d9fb634b76da28d79ea224c64cebf4f0b6f7b2feee4c603e7c454180a206ae5e80a6d087a8da8541b425fd6506a11717edec2c790c84cf48a5d850511488a705a7aca9ebcd64b79eaa29440808d9861ded22b243f8e7be5d34dd73e5dac40069612813b97b9bbf7e04711f5b7e279fc4e0f5433fc55f8f33ff91b8524fb5fb7f6b35782b80442cf059e325c7bfbd61e716dab507c7767afa3c6b5e06be16a3c97c235b6b8aa866d751d6e382ce470660541b804452511cc7856d8caf63d84cf1442705beaf0b68461dd9be8ddf197e3b904d49937f263d7cbf63143b316f1a00cc8270edfc093334b1fe8b35ba8ab08c52e1383ca2f0320c1d6c777087cef03fdf5ba558c8e58ae14da1adfd756341a6c1cc60e3ab502c0f158cf8c47a7f1f5c8e797f1eb4371eac51bc47447a96ecb0652cc5877fd66c36f58efa849f6c49fe1ab3e68c49abc994b596c5a6079a4841b49877d4262e62316f45b86c2609a59073a0c58ab7ad58e7f0b0d871a28a5b3adc9f65aeca598b9e44a34a14813d481a657b58c33fb1315a64ccc98f19c47497bcc68fc6610dfe805a5a9073ddc4d58e316334553b1dbac645f7496d132df0777f6f6bc1c2740af80f43838bbe232047f7f647cf54f5f6bb6a3fe6e6e4208bde5c8ac3aba8016432d3c81e5092818a1397046ca305ad44db8d0d3b0f4ceb3ccfbcd6c922030d3a99eebc98bd863deca919885fcee6a09e35cafd2b856ea4d4379db71b92bc19cd6a343bedff6cba68a8efc21ace3d4df198de7c130d1e7d09ecb3a078ee35440c36c952ef8ad8a61f32bde5649889ab96a52716ed9e1dd6e32f691613f3f9dd817283310249072674b21e4365d3c8147bff9e260d0e03377486b995a856ff4ffd1698f4994cab3125d8836e6f528022514149ddca6ae53ab81f488f8d603f1bd368b48867137a83a104425fd8b670e9943d34ac4f87a01a7c5beff4b0eb93b732905d86255ca4485be323085f535409fb405f7489d4d5a1bc58727b7ee96cfd184282b5854c9d9665e9f8eead54acb8f75192ff1d64822bf9d3c92b5d46d552d44f708187186d17c11aa7ee971030da81d4795da9d6789b567cc9a17245b030fa7c450c7e5063495560c53c272fba270fc15bc5a2f9c4ba8bb52860a6e6775f03076b9a8a75b4b644f1727d08315df5e6c5850058e7ae0f47f8e51d6859a8542bd0cc9d100bed01d0747753d9fc21a7771625e30d9c885609edf66945a7de9895aaf599aa6e7f56ce6831e021a26fd000722c3c0cac91b258869850f47f504c3d1885ed8c4536e8f792dc42cea381685e2d767fc7e88d5169de239c33857270f6882a907e0b079fa457df3ce93c7fa1fb13010f43d51afbc7e4d2d5aeb14c2a6e8f73e0510e6052aaf0d0fd7bc7dc0eb679db823a3802315e9e2f080d7631f456467e3dcca31982348c5e16101bdbcdcbdf402c80b8797b7d7dad958e9e989b2370687be99a9fc5101d2234869cf5d481f3f490e94d151d6a353e9b85106ee5f7643fa529262dac77a0b951dca94880ba2c6bd57ce7305c7b87b2e5f20326d7751ce7f6863dc1d0ee2d2862517d4fc14a1e4e28c14e93e59caa815e9deac57d0990836cd379f3f7ce759beb2c31df6f9504085c9ebd3fbd63a160b8752efb18b4c53ed060490ea7955c654e345cdab386ba6381516c8087082ecea45021e856c2dd1b8a53d11a90dec4ce50409271a05f0166f2c3c060da4c9f02386bc5b21df3f63e2f40204464b2235b25ae4257f3e476a34c951a2aeeb3e62a36f0ee48f754ef4d92325ef710bb2116290c8d99b3e9671dd47f12de8ee1c546ea803e02b67748b96862ce36b0595933a4cca66fa47d8335f729e3b5e5627afad152bf1bcfd46880be45d8c3a59592b3a2374a2dda11cfc85e5e45f6d7a5a13d0ead624aad6d52f56312603cfa472fb0c17c9e07d6b9c35ed7be8b626461c6725928727295d02467ed6d652d64856a0c7e58edc60819bfebd165dc6fd6315e0afda1704d2fbd16f7eca9d7944494bec799a47246dd3110a3e3a925be26ab87218151abbd693018f73d5fc510598abc258d8a028e938221f7abaa051ac89799af54bdb5eaed3fbbdf3ae9250d1044116fe1bbbb116d2b9dd6befb3df86efb1c2f6857fa835fb927fbaeaa0b4ca08f2058c771b1122c7cd183b24f9bebaa1853ef5a82c275ea3ad972845805ef73aea0d31f7c469d18fa99f348f5b3ec40ee0256a305683d844b9427316f4a4378c4528314a051c62e6af2fc23bd030d9269012598f9e97015c19eeaefda59fed31b99970a10775788ac10af9afc96e028fbdbc0436b1a6d7aa4fcacd39cddc7d99069db99a592b934f83cd6605035abc844b88ee5e1448ef478ffef598149b724f5cf5a36a19474792212fabf5bbd8cd73b0d2869d9341599a2bafedb98366f02d410635c65332ea6d723726a9ec498ba4f00aa68efad5bd8317191f842dc27a161ea9ccf8f14cc31c65b1b90195ffd698cbbe9463dea8ca01c1664945476b87a8d089edecd365032e2f28adf6b72f2db9aac8b0bd941240a16469ea3b673052b92eca94a44bb3c3b6ec9a6b9bdbd58d0c6606c7862ebdbc539b5d224942c84cd5ad9649d9371e2145cfbbb87c96a864d7efbcdd8d6d6b87ad67b08db55b340a4401f588559dd160dd798df67478e6400ba8d270a9e9bdfdcb0db6eca513380cb644ad9ad81e66d3c3dc36e989e8e6d39fc6c7297a339f105df1f34f103a9c898c7842ba7e508200439e87c83042d2a0c33d826e9aed4088090519e8180bcc1b2f8df581f3ee61aa530d50e85e4fe0ca463530bb25ff11aa5c0d8cf1aa6e6a1ccbe507649d9506438fe72eb823cd8bd2293f18944e068d2bd0f928df0a8d8f51e5ca18dd8064ec1dae8a22731d10d8e7fa86b1dbaa0774987187ebec97379ec1ea0eff5546f2e40bb5883f51d1dc258b8e512a63159e2a4f6c07b03e5cb98f9bc0020cabb4d4901acdc7e7db10f26cdf085ce6a490c5b222ea2de39d56f980df007c4f49b26b9681e8ca0e6bb9c9acfa27544c7bb44e81f70d1b036b9c5e4815832aafa1614affd80fa93c650214f7936be6f006497bac955a7b0117d70af7427a7c5ceb3c3d553e7c1279375cc40f2e62a108491229425e704080a98eaf57a4001826b0e6f36a0e8983849e5b265b8bb5e8e5292586d5c5b5efd5021d4afef17da779ecb95244e58eabecdecdec127801b5f7a8f89e236f3d444e626f822e59832e73511072111c38aa422f2b27aea325de9be50a6430307a5381c58fa8aaf9ac29471b51e84f754b2bb8696d53d85f122bd84657206579656c56a46a81ce031bcbd2f53adf5b0d64f888177b3314fa6abaa107edc574ccb5a2588f2a325efed1bdb4ce465831ee934cbdba7bf47bbe6f9e4d5174379b579d301d93c9a565c544c865d42ece164d60fffd02d54571da523d6e742634db2eb046d24467bb17b1c519cb0a6fd6687712a68a7a0962cb134d3c84a4b37e66ef91f1c6741646ec108d8b79ba321bb4d688500c3dc9aa342d9e30f13d01e3346646617849e96e777553b2f8382bb971b822cfcdb6d39e02f8c3baba02dec424814cd6b1aa4599878f812f6ef0d87cef2660504938d1cf76388d0fd1536b5cac520f2801bd753ade9d2773ea771fdd8660b5bf4b021d05045116632156767afe0cb62aebc8cf6cf3ef9eb319b549f78d6295e016c52fb3135e5784c436735064d2cb7b9660da0e6313b3899e713fab12904fb90fffda3dba6bf36f3e705d4a3a43698d5ef8b08140dfd877df3658e005101fdb7da97016dfe0e0aefeb450c19d0124293f20e5c1acb84eafb4417fbf395ff3f7a084c8a06301f82e9d17af935b0d25d3a60aa4e1e8f772f49b4dc0499aabddc6ea78c2507bdb944881386e6cdc9223e0cd4c2c28c09a53d472339227b8279c8acae45d5c0fa72aa052e37d2da71a8cea72d3c1760779bc8c5c6ecc3356a55952806df8ddb05ce2c70b4dfc8c9e01dfbf1526455c99c9790b8e94cf807b80cb87135ab10f036140bb59d0405f0293104bf69fd8ddb2b897079cd7d4eced62bbee6f27940c0904c396975ef4ccca8cbd90e74b9e26af701e7a9ed360c382c4c03612cf76c3b21591000207d24861cdef6572289346913f9c7b1ecac1c834672d99e64335cb8e96e8ca2d7c3deb740e16a7fb8536f53f2a0f69ce0ce5e1e0342bed2ef63b31e4be6b0f0173b1f39c2a1e8bf0f3fd2f6ba40568bd66e1ab7d8b7a1df566e36e5bed31fca141a0425d5431c8b1a339b2f842c878c36827633f997d0445352cc7e0b7725ca3aa2d0df3f5bcdae04de6d6a770051ca6bce957fc0ef6fb055811d740870cade3684286605982ecefdde4b265b3f006a1fc1e0e770dc82fc584dc5a56a7f4ceb57081cdae127db995fae2f8089c873a0bb91f3abf4afb0b85ea8a000ebd84f31b3d710e71b670aed013c63683a10da7dd6be7b72fdd42a33c0fa684e2df8ae68fbee14568326e189616953428114de16095e75f3931703782cc2e9f8962cabea39d6d623405892f655efb2c9a6b12edc150bba45d9809375d357a6c230cd37c458f717af0c4c47914115a69da752cb8eef4ab33a9b7a00ba9dcb92d36e996c32ec35961c830f5ba76a1dfeb8e56b491fc1a39d25f71e3ad7c3887193704f82abd2738a57e5e32daf94578f454dcad93bd6be16935331321e842e03d4e6711fbf0f296873bce4c21748bc58d18091f4d9554c6f9a401fa04d61cfba1b963f4bc890ff57862744717735717e67d01d8b928344d88006e752b5c83a41974a2932b4e7c3b9248f2cc4026dfe26b8f20804bea892ba696eb7ee24550fa6787169d3d04ab5d00963d2235148d69cc32d5c032faa0ad7511514293846a482f669df176d6d91f71f75008a9823cb5569b5aec62f7733d644af3ecc6672ace3b04db8d18e8427b48bca328ffdc11e99bb36a850b06bd91ba0d0fc915da8fa08671433bc11141113f12eb7cc4a1924b99460302be1fcff8069fec783cdff3aef40d193d75ff1795dd23126e08e519827bd545481c7d42f76715c8b484f0e7a64fffc9b7c256be7889fff0e0c93016191081e8b3a2979361c5d6ca5564388c6d25ad0febe0f0e2fdcf6cec819cc6a63ae701a4301159b333e298ba236bca1f0004a5ea1c951ffe69c9a95c5441e1adcf8d86e55801f69f2b586e0ecd84ce7bb8db4154037bf869c28206cb9534d587b8d221ba14b94000e24f8808c75a8b7ab7d8a1ddc51295add39e7a7025e49850e4849278bf91da299ba8c09c9d3eea217981b1d16f5a4f815d4dcbc0410f387837fdb4d31dad7b278c1544455aa516c2cc7d10cfca2f445c346a3b157c9552d41677019e945bb4a974e4eb7a3b9eb697902fec912f06f220de50df716ecc18b29917928f982f7eb81eeaf5d4b4a613d577eb3da10226cb17f98c67c6180eb7bdabed1df1acd8b8222d42824c1720d14142652b5a17698a1013b7b3bda3de0a67840905b54c000bb80b44431483305f2d8b43217f6c2d4fd78e9f8390ae21c09e991fddbd9e20077609343714b353f937a7b76956c770142b670c127f2a7e43772a0901e462cbf699471999cb17199f3af013c3c583ee0d7c6b8a5867c3f8dff99983213d086ca3484a5117ba91e867bfa2b334670fc73394395b488fe60eeeb7fec8b94971bf92c19bbc2a825099984c744083e765950a87d233999c8595d3f3c173534624678f5a5809475a6e3f4e572be43f2bc5134e0bc6800cac1f271c3aec750bdeda9283c30c452d289daa596b53ea39a1046258661212c17002bce1cb36605c2bfd1118a112fac641a2e0453542f1f89b2e19e301c37e9e7f7132433af941ad7b2f5b4f6fdc34119d2b112b15924e6d2ab09090b15548d99e22952716892150e863b4ab6654204355a36420633ced3b66653e56e9e6ed03cd566d38cfcac766ea28cba05d5464f97115d7992dd55c29fbf27410209498e1941b625438178da867b94502a9474d21bf6102f75ff5019de8aa65212524e8a360eca96a521bb3eb74e1ad592b996e7c908579d5712957adb6c4ae7b5ba7b9b95776c154a5ef2943e6a79c8240a4c36f8c6c8e8393ad0a4c46fbb3801915a78917fbbd8d85a58587d802b8bc6bf8195e2930aaca1ea07ae7d0474b280d0478bb7d5d0a6ff6c63914559e6e7a2afbf95fff70a95ec03e116dfdd47112fbcd3bdd72c1947b9fce911d02c0394e17b1d9c06dcd0fafdf8c72ed72e05ce6f216e75f34c5942af47557d6f48decedcef2c2674b9d03a8eb645a95106cbea64e8964d73951fa1a9a555963d370481a91781371439d5e3ad04b7109e6497fb64a383c1c9459f07dc3636538d3141fdb6ecd50f952504b495e0c0b08732e7feb68b342c6a457c48ce1484799a5745bef5a664ffad022e72b5740db1595296a2198f5928db4fb252a468fe939b9b37bcd04feba0e1095aefb1cda2d47a979d0d5029b513b83c1973c5023c5df17eb2dcb53194565f658e851071c261b7bd92d4fe6392be815b18ad3f4491ab1eb4c614933bd98eeececa7be290e474a02cce21f91895da490d3678674c12255c827dee2be59bb5f01d731715d1aa276c69c4230182de5039004a74a424b3e23297e1533da4863c8c7d4e476869064d3f6a405adddd63bcb8dbbc357586b42102b1a7daf2a5a914e26d4861a22e7c6499d88606a74658fcf0971f7a691b9b44ca216e3c061069611e6408d3ef194df156d548661c5149b06d2d0d03e22bf6058fa361a801ea7640edbcd6e1828473ca55d8f4d69d08b66d61fb3ef47660765d5c1a1f5d1fb980c119464c87d269c359d63cb99b08537e77f6f66a8c549d28134029fe54d943636539dc7512f5f0bea1e4d8502ffdc0edeeabe450c2a14ec9761fe399a77aa06b6b91da88545cc8e02812c6705b84b202c32c9862df5c4a495e68ba0ae04aac527735789c0d20160b6ef5b31b767c4ea5b8985f71c54ddd8cefdd4e0d83b869df222acefb51b63aa68492c58f910b61eac1de8537fe0c9bb15014ed4e1a2f483353017f84b2f06d58f929cfaf0654e39294054b1f0458b984b6df7af640e81b933c41cccd36f30eda0498606542904f5e83b48620396835d2cfa3f8825c9f73fbfaccfbdbfd0da4c0028094a47cb7ebc9ab13da4de9361fb363511be1eb951f6ed8b3b461492cf53e31fe4ae852a29e8a95d19392e63853605f05da998c0c86613cc46d15aee670f14399812beafe3184f3e302958467b55256c3b09dd44779f67dffa953ddad6df534bd883154ad873c134c37a73d1c1ef76f6eb25046aa8f47e7b97c6b859a2223ba0fe630cd6d604b0269d052b7e1b083830cb6373224f44f10c9c918ed5c14a239a478778b49d75c6585d3099a12f4e1c379f97b5ee1b4b4d6ba14f35a312132b480132a00b3700ee388e6b034c81e2d450969c0102746a88231f79dfe9db701eab943efd013be57458f5143c08394422bc0ca81dd21d5cc80e1e242698979814c18bb36c37c5709cbf2a47465a5b0c3d655bc51f27e3ed9f7388c0ef5effc845e037c9a2320f94339eef2092158e6f9312917df96bee7aca62c6f302df9406073fe8c347788143a1e55edbbf62e2fa006310c092bfdf86a3c7839125a449c25c7a9280c04310fa9556f0b288d99ca823f218636470b4c988a8424263ad01c84d0a0a1b80fcba1b773528ec93a2456496b67050ec143f09df7aa90934ffbc73d5d8fb951760b4dcb8669b3435653a5d5df99f0b3bb836302806e79d0555286937b85d0e8bf19828fbf617c519358e439302c996b2827aec7ade1ac00ab15fac850a0dacce2e4c3daab540f602e8eb6169f26395b843fccbc3634b093f8e0c5026a664e10590a17f914e869c6c65a74aca3bc8445de340fa2162fbd6c6c6a6581fbc104d2684daa6cb88700b975f1de9b15bc39aceec1cb2bc1a65eecc9dafff428d367c6a3897141ddefb7bd70b465af48cca8c16cfb5b811d45cec33f42dd680751c3ce6d230f5c99c9b8bb36b05402f268486cb2858eef58449c8805949bb118f658835af11f610b75e8a0198762153680946fc163bdfe27e70edcfb9bce728670fb8526435fa8acb37acfc8ee3f9257ea3611f0b4a96995f42ce402421820b4a50afdb164b0864de3d4dcf992c589fb84077902b8877e6c0c058562da84f38b03920d2a5b341d856bea58f010f64b697d597e9c0eb1a3b604bf79844e841359d6fbcd42fc9887ec941dfc3d075cd46e6e9000691bd6faa24d03fe19bd031ac682fd5e4bdcfa8757439ef7a5daa6194e852a08d2705e20e8dfb1c2fd598b8b6c790a4a10a6f8778a8ae0710994deadcc3aa47be07807d3c7864fdd032b6e4910aa1631d97428ef531ab8b8fbe7bd26c610b483066ea58ecb3cf92f5e8cb38472f8246b6d026257747defd7a0bb28318ace949a2d528dbfad53ddd6ecd16bc674b567b60aec0bb774f2fcfd94a5fa43df3a9c022537f3ab8081ecdba67c8daa4b37abb4aefc9c272cb2bc9732312e95f3e3a787f9773721c515cd9bf74b9f3e0eeed7a6c563c7b80738344a2ee7717adbce6cc34a2a265916ef29e9160570538e8ce09268cf1fde6031c5230f03447dab3c4ffd3c69a2fdb63cdadc71a36ca7f38f46f15a31a34238c320d8517911ffa1bb2f3d2fa9c10ac6827d23af1e7ed304256d17b938dd01a4c5affb5eca32997091170d953dadd612a71f0d1fb0aee51e627b73e54e48e950eb26cac3965d1b7f4e430de11becb25ae3307b0a846cb8622b18931f55b7d8ed268ed6998d192771135834f6991801fa6cf737b9f4ca95210c0803ab1494fb4d68586fe859635e271489ce3201a6ee0ccbafcb51ec10ad563945db51611ef70bdba34c4f15d3f71326f7de7a99871fc52956527136857967c70a9ae32f0675d3fe44c6421284f88f9920c97268c8a54e610c976f8aa09456516d6782a3f533bd200600cec671b63c817c087416094789132000900809b9287d984c661f84d3032d380fa1f1b5003b1bf81ffda2e874b8a7f6b23c0d7f926dda479f8c44da7b9374552379185011082ad1dac54e710ada0ab8710f166ef0d5b5b521ed51895819b7389b52401046e9ac55e30005a70c3c09b9aaab66334e95e530f0ee03ce87b7082f7a6dbb1afabd564758a04d109c2773636aa2470443d267e3921db73a2102e5a3d60fb539d4b2878627e4a3ae05a6645ded88391fa845d52eb7b603108badfb55533349f7dc58963128fb30d180c7650ba5bc4aeebd58d678f283c1162b740674546797b937334603305d6a2e6f8ea6c31782f72317a1f5854928dfa15901897e243d80b080b1803fddc7510b96eb88dccb9f4fc9cdb78611dda5b0c612fccc73002ff43be7bed04fcb880ca8ce8ab840a59eeb14306d619f51f1c2f6034ddd04ffcc9b5d35f6106b92a57d10fdcb82036059bc1b4d6329c378d19bb7cd699babdb40f02531743d19c555fd65cad8808bec7920224449baa4e471b14024d147accb8f2e0940c33aae1615f3681a42f9ca4e87090b5cdba3d42defb00f3ba247093ac29ecc76189ce71d6ad8a8087cd0e44cc9c60cfa4229c0cb4564cbc9f20a5e5d7ef4133f45809fe9381a5fc961ff3b4fbc0cf0eb26b18fbba66f73c09662407e907b330dfdf1d40152aa81fb82c513edaec32e7b964213861840ae9aa4af3308afeeb1e2acd449abaf466a55cb0d1cc0b73fe7f44a864b6887ecddad534fc0380c7c1e2314c42cb345af8d54d3aaa4d4cd6d4d184633d3cd1f8f2e40b65e9bffef01441d3e9763692b1e291d009735b3c5a80c7ada927933357e8914c49d6ab5629894caf13ee0dbd71f3878d39828c6ab722e3fb6730152cc08780ad327a900cc336add73b14d48829794f6484a16f045664f97bc12aa563d76b7630f190d28aa9cad2654ccad584c6320c7e0686e29bca1b77913e32418d583b63c9a5d874b673df7b67c3fccc5b6ba79373d688c929b1e6b8a1546a3cf9e113e8dd6bea0b79659386a78299f0679eabb3c02e5194ffb7b6f201e6b91e2855282eff037e1106d92d850362b1052f2300c77c0aa02832ddff4e544b0afec0580ce75fcca3222ea657d197d38fc31a2ea76b9bbba34d12566a0cd7b5d13e683d0ce49a944c7bad1dab1b24b3e05362bd330c3e36a676183b42045cad7fe3da8b6a11a75205e1d54304926a3cbbfb334da00a0bc466391d9968d541492dc1a9998169748ac6400abc2a76ee0714274a07bbacfcb254e5d30cb57230f4a0b31804d6c58e44722b18e46060a77fbc0abcd74c7fef56a69ba22932820139b79d792753c667fc32e40294582feed1f6eb312563d013d03b7f73486f4ad0db758e34c60eed54c65006bdcab0ce7b06e74c529f608113809cddd34d3be54bca3e02016d13a5b285fd18896208c47588b287a0cc5faeeda3e4a531d06b07dfa4444be4c956c84b35e3152a51475316004ed821c25e7508d34b4907c13210aacb41309916ed495479355bdd4709a8a0ff9f4a9dd9899e33601483c1577b4b397500245fd12992da3602c122192596b6129a2958e73807043d3fb7257b4f603bf7a51da513b0a9782a0b578619454a83f51aa4cb862014b0684223e01592ab3e5acf7dc1b434ed68a5dca88683524347bd9c35effef0d0bfd7f570159679a6bb6d274f099fdcd74cb2df260152934596c7450b08f9045238570161c48c36992aee35853634356cd8aa353af157b1f70797aa202866d7de6275f4033fcc8500cdbd17cfe83fcd309654c0f55d8f540b9e2a0d341de6ef3e667cc31ef8cc387bde28159e42531cc026aa7fa51d84e108f7bf19c5881c3bb3e39049f658f824f770442c84b3fdce8fa22c90b51212c7cc69f08d6adcf35d8dd52d266e0c3f4909817afd723bb69f461bc3244a8895448dd71d21491b9b78e3a2a0d89ece67af43aeac0e19077e956b18fc15155634cdd51d3d4f9c3d75c2d6af4f749c7becf89b8110046877df480c04f726f6ef71d00b24da23d20c47c529a60059517c2eed1177a6da51e3eabbe73639088a8d73197829c4dcac56f5155f616fd73d4b4b908361e3cccec1dda58b9b33fa7ac987b0f7aa6625cfc2c7307a2952bde2b117a8d4e7411f6fafe682de5c40e675d95f07c1561df8b0e2cffac3059ae535abc4967357e30c59036fb690354dc3de047bc0346b537583a00a9ac940237a2b453aa9340c853da8c51c39d82bd1edb8e4e80d1e1b8b106f41852e641e347bebf1fb4b6cff977a81378efd1e94daac0855dc012278709b9f1232cb4dec1289e7565794e6c4655fb5995196502d33bc21518d5aec7aa9a5bd227e25977dea08e1cd39a7c279ded7c681ad0cf228606744b64b3e998fdc8352ee41850dffbb2a7febce10a94c7bba355f1f538dbbee222aafed256153271148e7ba456a9d25e75c56d3ca740a4eda7416d001861039b2ab10bd9d8b2798ec426f463bd8f488bf2dbe1f6ba7ad1ca69aced3aa1044b3070c87a26bde94401bcc8aa0a476df387effb433b0495ade2a39c11a4cf96071f7b65393ac39c11cc5defbdcf7d90512b4eba9ec24c2008961ac37f65f41b889e18c703ac4e5e066d27171d7d137cccf378f1f7e20f23c9e2249c9ab299c2c138d5ea84e059cce437404a635d03acfd267be1ad40fd8a8258a979bb07b445a43da0a1df03f20153ae3ec2a0c91a9994289fb8df6864c1f29b4b06efbe8312ed0a8a78349b549c257bce034c71b28de080a8a64e4a5a0c4de302d410c8a23b6bdeee800440e28e281307405fe5cf5eb7ea1007d5fcde1b57f895da36499834134d265198a14f907217c3d985f54a4399843aeec79a0e819e06163229e1c78c2f1f8aa325a28eab40d532720155dce911170767f561aac640e8315818f164a0933016f1bfa8b25985f8b82525877e1458ddd2b10f6dc779b8e9a73b750565511021659f309ab131c2043e1bb9c53f2e2aa5593687a1f7ecd7f7bceed0192b83afebe96009a431d896630c86b7c564e540fdb70159a9c76bce8f61ee781fef82d70729b2762a60d848bbf4a31c463d1d90e3f50f3c2c98e86a597d44cff511bbf4c790cd7ce5ec7283a8f54246326caf61c043b2862808f645ca119a4c2b61d14681be1d4d46c616fb260757ea2207050dac43bb5905c35721f4363d452a3cdbf693b462c3906845eb4ee046fe15e6854673d7830d15f8aa23d1ce75fd7b722c690bf074e05cfd6e926e03d920c37dc4897160bcd3490e30cbd3e903c22149edd61b28009eedbfca4c102c09a64170a3f55279cd4b6981d13dfc5d6698fa37ffa02c896195dae5ff2648a88e2ac5be16ee3798436272a33c174914f1c99d68473177161a80a7ef2b5a643046d7384481217db7bd11b2ac32a533e2a182f82726f083437eb5bc1372a115f80db5a21d6c4d68d03babe8b81a57920516774e65ac730635ae94212c6bcf69c2f33ebed65cde426b8f2e8ad16c8db9ce8fb2327fe4870d78f885f33cc609386bf94dc95063fed5565332936722dd1d17435b1912a439d33f3a56cf6b09bbc6e06aaf689e92b84dfaa299bd793404bfb927f41a3d6bf63bfee9bc068ee1ed8041c0a177597ccb134151add99d253676470261ccd280674b8fbb68c9e0bd2953947ca80296244689d4d8589a630309c02e453918ba95abd65ca7264c5e874ef99374ee999ee816a3363cd58201e6fa587b111a88a44a24e418b4a86e7d4340d960007db0452571b55d755bcf61e5a9e94f4d0b26a2db86cd5c4072121f4a3266ee032252c0957adb20ccd8bd0ec85a9e1cd50ef0c24d735c87a12f97be65e256e7f6df351109ef87777a12fba916378b4a25751ccf0c7b8944155bf7b94207fc31b869cb01321a498f96b5e7ecb6422cec5a83bff548c776fe8fe8ba30d7a8f4b9efd9df33f11ee85ccbc97191cabde4e04d926171c5f530bbd864ccfe513f4018b8d6d4d649c859c85866f9b7f24730e376239ea595536011306a7763a5f55b3b7721f28e038d39ad4d2652f82b073f9a5c9e5f3b4a6bd0cd228570d5d7e9f54856135c084231a3d151316dd4e2a230992d7df2003a769ef1faab4738464ee427ce1de5c31bd4a6a2b414cf5f2098f6e26d1708277135e6903c2f59cf8f952d826688defcd48e4088abd5045f147ca7e3cd61b0e2ef6556096fbaa3631e821cad12cb71c6fb807c0083c433261acb79977ad7624362e3da9951422acfdd04d73cb92a9440f22b55f266fcc9524adcaa8bf68d2b47a308df07d9235a5e451cb12742bad508053030a804aaed1cff5926a3ed530fad8464a5274efbb6ad4aa69475dcd0bf944a9dbe32c93b0f353a391bcfc3e3824f91e1482b9037e4526f0f81030094aeb500a41dc4e249a0556c371899c26e5e143fa0535b77735159fcf672c352ce416b08fac2cc9af559a071d77caaf3220ef50294e4c222a6e91d322b468f4a4e09c80bc97ab2c3db207820e9d32e50894cca3dde0d98fe59b51cd128428345d4ab83ddeeed864de06d3f0d66c9c4a340254978693c284c60f99523616426b69f20b7bc03ab08db3a2c436108a70b2ee0eefae601839d97a8c6563f44eaa8dbfd35b7b5ac3dc59fc120a0eab2e9668b1cd683e6931b84fc658916b2145063dfedd319296b9de68c4c1d59eafe9be4bfe5bcccdc5c4d63901829ad4aa776b64de8c1cfec80ff6c2232505d39f72d28f4c14af0487ca8e1e220033af17fd3d2e0881051122eab0d9e1e87214ce583a7b68e6ef991686b67b791cb1828581b039aed0ef6a27ccfa902522451b58fe46a3803a795aa9ff9e93076e50818f1c9fea40003b3be863793ae63159a3a296340a8a8e22a44b4dc5c628c5c2590eea30d2486f4239198596d87017e36fac5736bdf325baba35ba2d2e3d5b9f3494e2fca38fd0d173ef9de94d145b5aac3357fb258e8f54284910d6482827bc069ca3838a3c6fa4abe2d0aed62f3ca747c41cb5efa5b4eb7594d0df8ae8a434382f81205d38cb869c81295adff4d518db66f18c1d74a9e2f07c97dbea7c99904a8e599103c5b65b83faa611552be5b4e01f15eb2e38d7196bdd3dc0ccfa799269eee1454dabb882109ced7905a37d4badc3cf791f73d99c7bf89b4bc1507d4662b704eaa044075d003fc042aaa7992d42f253151666e990c3b7d5222705cc27719f5d4d2810320d4329a7362f8c38ed4a9983ac410c09cf15fe4c665dbd9c369032f307167f113e4a8eaca226d5fded90737eda9fb9be9f60e4bd98285178d525bc009fa360cd146e90e11e3b2e1cb4f1d539cfd5ba95e86654751d3d1c4753f41af830fba50b322ec1df0db640179824b12a4e9564478ca00e0cc017dc889d14d7fda24d2902eebe396db4134681ba9cbe2d624ceaba47f4700209ca1630138bb48a23291b943894881f175d2948ad7b27c4feda63b9e9e73e8c93458dd878fa3b8bd780f74928f5a914c6ba775a93817b01008a6d6e789c39e59c5b0b85e5e6cc99f7325beba56dd94d5fd6e2f9675f0209a5df82ca72e8eb211d7f3de0253e13e91cf2e2cdc68b130a04d1dd854fa0f750215cdf4489fc3517e92cc3b8b94f138378e51527b983732127b39519dc27e95f677cd73b498e8a132678bfb22f0de41b1ad63209aa85738ceb1cdfeff997446f49c94d57040210b7717759c3fa504a822bc16e14840e6087921c3f2764e4a17f27d3ba4fdb074c8edc24792ba325578cb47846898a8e1f307a8a7b283f11646dd0900a5e5c986c75df600c87421ffc70230910b1834a27c87646b43a2ab2acdc2859b7925ef9de782d1fa0a6a834b7354139ed87a0abe261b5f2170addb51e131dc5a95c99b7c6258540d4a236fed506dd0b1d9a08ff1b8e52c24b5db1f782712a3303f615a6cb079e8753613a2662015feadc348671a2da674786c9b957ee21db8254ee20cec1fe64384ecd69c637ba75d9780274f4b5df56bbe29cb58f3bf5045ba3989caf00e2a0232f106a0db4f2eeaebdb7ca35adb28d874e4df9d6208fef5be54709e5b72447039fb3bea29ff789d5008bec724a6cc2226b428332c3858a2d5cd54eb49ecefe67e24291da5476c641495c7feaf4b50ec41709287fcd91f995275b0e3a2d3636e8345b6e6e20e5758f4f3dbd5c61457a924d5c1f6f4ddf143e18e5e78b9eb5595afd2e32ad92e396d06c2c0575b2912472d98d0eb903e2ccbd5c3a919f692bf14036185dfaee6447d1a9d144e776f43245b6e230d5d69f4e68468792c3f735426d80a1d4a0a2a3ffc1a01371799d3f5e7afc358f9e2c75a3ddd074fff56cd8c91ef46589d3c3230a03b78197d8292eca3726e502888d76bc37f314ed64922fa4e80af347b43e13e84f276102f63a00daabe099a8e6194e80ce208a024e46939c67ffb036879606f7cf2b982c76e895feafc98d7ffcc9270880d74acdfd96e47776af607b1a16906c7da9dd78a3371af51816a95f366bc1e72b7f1285fc2a775a63a5ad5f27c97465c7d7a4b36026627f51b4396e8208bb43c1b61d5d477dec13e8ad0ed1e6f6bbcbd967a02d0dde8f3cbc7094eae563e52ca2c7ef9408a92d2dac139fccddbec420bdb4e2143d12782aa4580bc6680ce3428c9f3b21c1ef3381e85f0c8e9d49c7ff495f8953267057269380a1254b4d849d75c6907ec4bafbd237fec07af879597f408e94fad5931ca335abf0f5e0b151bf16ca27d244898deb0fd843156443a09690fbcebef522b7e3d25d8afdbd7732a2d271966ab88810dc5e437490bda7dbfcaf203be2bb2e53a6d782762100498a7ffa55685c67ee5b924bccc082e8eb9644471cf8f7b7459c27b7f9aa98c5fcc8c28453044224688b18ccba1b01f6ef96ebd9d41e32172977f6252a987ee3d0a3ce9d994a91f406de62e1792d07031d82f83cbaf37d7ca6346cc2d47585aecc880709368137b2b4e00514a4027addb9665530ce349b0ed01c7e6a1890a5688e53991082529571bfa2cb61cab1c68492697ec65a29bf5458117031fc23a6d36b1d843e8ed3fa8ec5ca02a3669ed0104a1b839345bc8bab08c8a7815a48db7bcb2da594524a290323061b069505d46ba259c2134d49f1833a7aa5eeb08fbef17fb0b8898185c566414a8c95dc2f7db4dc3fdf6b56c0df44f10ee3afb0e429841eac11716690a8a366099b404dd8132f2246f0a9c24fc3e0fbb3eca054c5f2d351db723ed5d9b2ea7cbd7a6c9a8eca19a1ab43878282825a1a5fa9feadf75a5b9e2b6bab920622f8f48b288a22c65c8734c59fe28757ec028299f43d955f561e825f3fc025f8a11e9970fdbaa375d7d350290a481075f775c64bb97fbf7e4bfaeae391097f80cb0d64247b4e0253ac43d13c54f3da4a6905a658118deea3464afafbf5e3aa854dfaeadbbfafbbfd1bd6659bf3a5fdee8495b467832c5f0ef47ea0f5afe49cf3a89b4b77f737f2e062726749dc051fdd963ea45afa9e96177c74fa2199e88582a6aab2fb9b2a7dd34e68c7aaf451a83a66a58f52d94a6aa3a4d7566bc57a2bf37546abbcff25bd35a91ef110708702682ff0a1ac5ddf9fb5f734dcfb6591703fcdf975bf6fb78f7fcf0b15ef4eeefa745f506b8df29a4bb35af8b9cb16d73e8ff6579be9d2937dc1add4ca8f8b0626c43dae4869bffe026ad139933585c285b5a89c5f6553e59fd287f3da3af4cc3133e2033547ced79c362494f019cdcc1133e2f383a2d5427d5a751c70d22dadba4a3bd8db5abbe3f5fee25e00f4da1714b44d9feea89c3e06e0707defba8ff7e12aedb00f6133c59e49c0b22e54ceaf395a4a1fcf68c99cac237394f4103282e9b4727ecdb1018e997362fcea4179c2177d74c397f4da182c564434729a9c9023e4841c1c5a859c1723999c1463913f638a7e7343d3d26b636a357ab732e6e8404bf29a9e93e4a9be8784643adf1156e9610c167150f0883342f402870f149c12f69d737730267e5976df7df70f80d89bdc561900caa8a0f04447116f8b69513181d7e325f5b058e49eb8c05529a3c0db62575344bc1e2fa937e537610b3931b415042716a34a088a179430445d2ceac50d2b6c88b7efa808e2f57849bd292ca6c810ea642980a298ddbcbcb069b108dabc2e147df72d762e1d40bc2dc5448dd7e325f5b2b86c7bf3464841db7d8b5d8a59df434e8c5d5c3535214c89558e6ca8a2a41ecd92d6d5d42821430d0b141bb8b8d4489dd830852ccd5989b034652b36445192464d8a0d54ccd28899dae0840c4b8a0d527e697e29363c214b7345b5c18a8c34444c6cf81d49936343978e2eee0394d95d7cf674a0365dcabcc0da026ee9b6727e61fd6a34b04608adf45a39bfb07e7cc19a01eee8b79c5f58303808582b42c092ca671df493617047ecd2719938a56f329a991e96a189e86017b08f950dd67539bf7e5afaead764dfa90137656c2bd45abfd6b8397f403dabc59cd6f9c452e707759b66a069a8c34fc512e71cbed6ed2996d88b102f42ee28fe4fa0d52c887537641345a15b90ede7db74db1efd5bda1bc79aadf79048ac8dff162aedbb5cd87b913879ce66eb000005206a31eb487100e2ed1989dba82325d9a24a4eae4a1bc51d86b61cfe7e5b0eb9ce62bbc37042687fc2a5e9aaa8141240ace5bf1d04b5b67dc8c390f4e9cf6fe31bbf0ec99129ef7183a7529314f08849da75b50288f67f0a60acb82a3708c85676ababd1cadd6e144bab0bcb9bd5f1122ce94d0c43d1eac05d222115f944abd365aed10cacee9656674ba0276bf9831ba4cf759bdacf9603213bdaa7f6dec737a806178d6e62bf4daf5c02ca8905b493ca70ecb45dbbe178b34b19deeefc09512829c9c16d48a4baa955864140369df1b5307293088758cea7b64eb0167789f0b4435748dfb6edddcb47a5dafb5d206e0bbb581b296dac19eeb5706dafbbdd166ddd8640360e06ddad85ac98872ebeb1e8f7e2e69cd3f6aedd96c2849169be786d864a69064a5c45e5cd511899e65b0bb766b834d76bf7debb2bef2ca2f5aa72341a8d66400185a29bd88dde6eb71bcdd035c1ce7ced0f4734545af1ee7be78a5924646f5119529a41a519ecec56b71bd4eb93f947957e4abf5f982d13567a0454cebff4c2fefab85937c9a1d2f70195be5aee5a56b2c7a1ee7c740e1c38e038d831dbb4477393e835faf8beafef29da28eebd39e8a2fef925a519549a01cf0a6e3c67150b79696ff7766fb75bb53071d03aa4a91d0a19888a9dce4e7befbd779a419db75ae0817fb7b4bcfa70b8159dbe0f57621c0e87c3e170385c0f5bce59a7bd5f79af7bffad73a51b5f5eb510faaa531b75a75f2751f54dfa6855a92798ac1779bafed49f4b77e23e80a0af6bcd3fc26954fb701ce95258d3355975a8fd4836f5af7d13a5d16aed50f4e2579246a3353d3d0505017d177dbbd1f6a3ed6bb6772a7af1e7124d3797424bfb59f4b5f740f434d2c9f6445f13bfa8e8c5f74044fba7095f7b4ac90eb8a7914d448ffba6225faf1c75b9fa63add54a12bded9b8a5efca725de58ab8db5a29ff0fc3b0cfdf84af56f3f9782bebf07a0bf919d74b272126939f03bdc9ef61d8438e0a7644e02f7e9cdfff49fca71ac51f81a85afbdd3d08f3f977261d1d0508e74aa3d85272229bcd3f8439cc4c0d08fdf812132c7c7ef000532c76b148628100d9113c82132c78168e8e7128e1cd2e5f8cfa51ca79f8974736928473fff2c431aad0b7d17fafe4eb7a7715d8e93390cdc5e7c0f42fd855eec2ff44eb4bf8124066e4ffb0edc3a20443ef5db2b8937b289f70b22772299e3607bf1ed5128ea288b1c086575ffc8428d65565f98346101855fb45d9243dde5286082fc5487027bf4c15e51b1321296292992db92390adc69646d4f60ed51e1340201221477d033605ef8dec46031fe6d2fdc1e931f6e7c3afe2c82ba9b5b0cede5fa8d1ea85205017e18ce2d18636c31c6a42f7cfe6f778df4ed910c451d2d95ec96f0f587ed40d4dd7ca1137d3fbec0264d30ff43dd8501e9e8523834443414f440a11d62ea10f4408f491cd013bd07dbe348a7dbdb6e4336d2c9f6b707babd13d007ddde36a49b4b4d410f24f44a35a41d887ec8369d887ee86da493157e27db0375c06487493a0d3dd1d013bd1310e98188dce4b64739fc43987cfc36db0f914dbb098803d02bd59b4e48679581b964fb205d68bbe982741794007d5d02229b5eb0d45fa9761237c55a73f225065a47b795930b940f1a9e5e2b2717a818bb4aa795930b9489eca7d3f6643970ce9c7973f6256e9dfd380f11a69cf5c05cbb8f665c52701da259942ad02b9cda5cdc4c84149a09881914d8cd829cf899d9a082c1cf4c850aa6206579feb060125266830a4f589e1286e8c8f3c5060cc8bab86b90d6ef05953be29336584f17cbe03e54b67c65b5a092e409951e4d628477a898202ae75795273ffc23fcc7e12a49e9ad412948e9cd2313a696eeaa2dc5d9668a29be9fc39189524c290e004e9c20cfda7dc38145e13832d91b5e7b6fba7bc31581bb0feba6bbe3426e7577cfb12a7461a2b47c8276eb9927ae75beb5e4adb5d6ba2dbef8565b6badb5d65ac95a2b07435acd0eadf6e2acf9d4e0dee00635e7390cb178cbfebb8903c790663b6ecfae75bf74640a431a1f4a69ad75ce79efc51867ccabd55a2bee5ab5d6f4455c67b3a9ae19df39e79c165b5e851db7faae02d05c3bc510dc3e4271666bbb734e0bcee9bb9fe79c734e5168de6a734e6bed9c939673cea39d73f678425457c39cb3b562cef7e6fbb9acd9c46c0337aedb2320df53892badcb0b304a2918a5144c0718a5148c520a16a6038c520af622ccd2fd276b900310647a8be043d8d61ed80028e6dea9f4e8c5f1061a84f7014aa208bef8250fdfaa6ec7ffab64d4143383fa942aafa02620804b4b522a4aa5a1572dd45da75410b8d1e9eb3618d640da9c15ee8351b8db6d252dbf5bb3f97bb2907842706580fcc8c0dd2122feacb1553295051414540baf3317b54b252be9d7b26a81f6f4ab9ddafb6a1fa892be35d19fbe25627b9fbdb24a4afaf61754faac960d5352a0a76fc582de67e194f4a7cf9695f437a5d30c6a06d90e1e2ca0c890b3e4a3475c2043c5151b5777cec2967c540925ab80133153c66a7841a2650d99971533376e742cf96a901aa6fa2c8b925a1996cb7a95f483828282828280de363201d96cbd7f6d64eabda8acfdc153d69e3632d568b41f47265afff3427c6afbf2736483257f3a2f70dbad04c1af3e23f8892ac1391f00293a727ca4e0b240dd2f7bba60d83355daafbb9b9541b4bba19747673b25e1e1e5a30f191341f48471b2c36c2aca9b38f78d972e3d6a34e7863e52960c9516f666490b367fbac070d84231d666cf0a162a7043a84200ed8c7856bacfc8484f910594a0270b8c4f16570c967cbcf2820baa649070e5cb08ae104b3cc9948d2dd5c3a2ac5f6f567a84d4825918170b6705fa4433e7c47054e2a7611e7f58714d12ebfba9d6151cf23024f57afa1c7f06243d462f866486db2aba75715f05a0a95e734e250dbd241ed2cee88b70b72e5ec8eaf4ad907bb1bef7627cafc618b703cb6bb2d6fa5eadafa8c59cb31815fade9bf3bd99b62f4d6b0d160324ce6fe69cdfcb79be57e9f7fbfd7ebc5f591818dec2f9cd9cf37b39cff7222589091be3fc66cef9bd9ce77b7fd70bbb9abfa2c7897fe3fc66cef9bd9ce77b77bbbeebb89d984cc6f9cd9cf37b39cff76ad092722fd6f75e8cefd518f3923480956daa1bc84371c4341a8d46a38de3388ee3288aa2288a62188661188699732e66a4e212ce6fe69cdfcb79beb7df8ac4e4369cdfcc39bf97f37c6f6f4f9525f590947ebfdfefb7e3fd74997bb1bef7627cafc6185764a45bfc909234e0ea5c9dab7375aede7b5c52536bc7e3f57a3f7a54b536dd53eba9966f6af1b47a1aa2f411e08f90ea4b51f66c84d4872fc55bb2d2a2a8b50643a1efbd39df9bafd65adfacb3d6fa66ad6fd6fa5eadefbdfa5eadf5d55a5fadafd6f76a7defd5f76aadafd67aefbbb516c3300cefbe5a87e1bdfbeaf0eeabb9d6376bcdb5be59677eb3d639e79c75ce396b0de6acc1c8eec5fade8bf1bd1ae33742621286c4fbdbae8867742fd6f75e8cefd5b8d7ebbddeebbddff59084d3c8c72bdabde38a8a8a6e4560bc3c762fd6f75e8cefd5183f4fa3f0da89377a547f6ffa3c71abf042dabde370ff3bce6fe69cdfcb79be1709090909f7a50fe98d90c4783dc9e2fb78f93e91f63e5a99c1be7beeb9e7de6bb55aad56abd168341a8d461bc7711cc7318ba298b3b8f5bef98ae2e7bcb7de3767310c2b40cfc230fcfbd6d63073ce6bb4f6a64cc3ee38dcff6ec7e3f538bf99737e2fe7f95e0d1a3468d0f01a76bcd2a78197a461af084bc2fdef76bc7bb1bef7627cafc63829290997f4bbd297b4432a73d6be247eb1c6fc62ad39bf5883f76aacc17bafc618bc142c4c8d071dd80f7a99a9d6fa6a4ef7d6fcde0f33ff9cf7d6fbe69cb9eec0967a829482e2b8bf507a815ed8f6889e9574d76a61cc61de4f3f4f3d6db57be691e9d2a3fa9b1a9595ee7cb8d2671481a212d7327f36da7bf37df3dd7befcdf7cd79efe7a48fde5aa1ca4b7660cfce4a0fc0af50a9072005c2b3b3d2d7a4f5cfdb54821f625aa7d5e5d5e9aa70ce0b5bdf7bffe268b7d75acbc14b36e79c73ce39a7fdaa70ce0cb5d659ebac348359cb7befbdf77e50ebbdb7fed8b49782d06003663ccca33b565e1ab89981b9eb5f848cbaa5aefb5544a7000c7a4a7982525a8dc904cc0af76fc7b8e38efb05f69fc06675926f83127f68348ff4f3acfbb9c34fb5a63aeb8c31096493b78ea557716f7c6fae3a0e852a77d983709e54df8ec53a0f0b63f42ca65f0a057ecd30a55795b2be1297105f501dd77d3baf5d2dccd96b75777befbd18aa07e5fc0f74198159d25961faa863e134f2f55a75de5beb66aff66faed7927d4d589f6adb3cba936350812ef3cf5be7d1fd3a31e424a04bfbbab43f7107f3accc249d156e7d81ad4fb856349a4225f534689e85dfe24d0cc12487cd0e740e7f875bc2975eb203c8ada83f7c0ff945d209fcfc21f8f927e9941f04df49ebf7007ebeb9ab75b94b76f89c3f249bc0cfdfb45f73fa1ae4f977be5c67abc5a4ce872b2907b302fd5a3109b95ab8bc6f5077f95df409e5cdef1bf3fb6e129847b90782e0e34010247d1c7ca83b107547ffc6a7df4b363d2d3585f43548d2d36d1d35a8bb5cf3dc960cdf03077b4443fe4d561dc2175fc95ee06413051766486484412df1cfc0e4fc39f902279c3dcacf7bf628ffa52ba4b6a096c0c49d3dcacf81259cfc5d9935a80bc85f5bd37d338cfefdf94110041f04f5deafb7d6d1721a65d204536785fa437a010475efa2e36698f175b9a93af8e3e7a807f04732c78193390a7a183283248aecec6c097c0f9c73b0a9043bb2f401010a8a74b2ea809fbf537e0fdc093f2773147c0f34da7b183999e3007e2e0334e7e1c91c05490fe0d7be46cea5a9754af6488bfa413d974650377bf6283c8d0bb8e4886126058d28267af0bca8b886c0b96ae164cdd94483e206cf0263e30b892e335684d0d3af66852df56a62a825f6eac3c18f911088d8a072d586ccc69d104496ecc07141e061286460263e6170aef8b8281185460a9d165bc0ea7829416b161d22dce653d0c4c7d4941c297a8ed83370342082551656141e5f63ee3d51a646a77c4dcf153b533b688410d247068c2324b8a9c2b36f703327ba8057c795293474426061a3038e06115729d470d1190335a7b5b5d21140c4d070b30576e2480734579a3c21db03c34f6d73e207b7704b1b56e0c4e08e99b113bccc891d988483034e1834584ebe54ba2b951332403e3948ce3d813fb7b933e9eb7705afa4c3a74f913c5d582a2c99a93d1df0c8a155428ccc902046df47cd0c1205e55545366606cf982938b40dc07820e1d2c749151638b10ae748084676143931e7a70288181b095d497cf41993c5450970ca40e0ec919e23374e60e70a19167b82ecc0c1c1d81051d3830a90255e4660a035ebb70e3a429c18a16a9327cc9419d00263b8cce64c8153e28a8e580bb4a8b8f25244c9949a09660a8a9b155c59586682cca812457c636a09ae5b533f68d34f082fc66821319324c597291cbbca559d1d6366e46049ea73f3e2c25921bcf944c2cb1629194aaea40133bd4cada87df0c3855995b1116cfaa4e9be5e2b6f1a8dedd8c346c50e32661cb242f885d84286a607ef323522acd265cc1b144660904566f4444e1d2e7ec8c81192ddf44142e5ac0b0c332db898f093818b1aae255a7490cc104507bce83e719762af423420c1c6911872b030b1f265a26c1c4dfcae6c718132c50d1b1e9e3008fcd1a2b145c5620d19be45835e429879ddf8814546f443a94fae3a04ac534c58c926b43406cacb01829716322dbc507999784202860841c8a0802153a7da9966f4c2081943b6b0e4a003c56e6931d1836785980adb5223471409fad4e289932c116a90c06162ed94408343d03507cd1d2a35c8e8e94934686298203c3d620387122c78b6e84c99594a748929282296a70e8a1a7ec47271e63c9814655bf4e8300347c9c652424b4d082845c280a8b032bbdd14f0a297b7bce1ae5d6144480a086040162682942f48c2f02b256adcb6d8d8c305889728656c645d5a42c568e1e21927451d177bcc8ce16832ad942001d600fbed0961850b9a2eb75e7778306f0d9d5276349542023934fcb41053652b8a7749b129a16b4a0a860a1d39a642c841adbea80911064d922126661529242fb2fca863a4440d319d47ef687afdd2a57004ddddb1953a5360e0f9e5f86d308e54d538c308923e574d4e600182598c76d288c1318386ac8b4b4a45b670f8cca94a23c28d3eb382d0026262a89505d56cc057952e5f9618f192e25448fc19514648d5189337584a3c6e56e0ede93e1c6e62b8253cc9e0a233a74ccf902f1a7c8bc4d895254fbaee4871d1a2c5fca9289275d504ca0514fa85ad9038a377602ef45421093b237237afda2a4aa5b29132d2aa0565002222e2700df901828fc9a790b8a29523e01af27b72842beb0ed90aee7c606d1d33768b44915cb548aca861a0952ea0059912949c3023424c8b441416c0588e2258a6aaf0ccc8951555ad2579cc48e888e1234f6da38747c04f96ac335fb4bce0b180383c3e13c32c331800a4d66471d2c525c2889935c20cd3991d7bcc708c5539c1df012f614c767b9400157aa95a18592310c1f233060a9a1952f2069a009931429e3875a8ee2eeaa298ee13c52c628eb07a5336b740593191f3a607151126c71aa143b7e047086f7e70411146cb87ba1341dd55ded7077c82ee6801f6a409913d5454b6325a606250c68091b3f9ef8ae8d3011920564bdc08d94a43022c6d808cc1f86285c918c5139042a6c80871b6b2c8d85146c8d81f1053d2438b89951e6146464c41bacfa8ac6fb4ab14572feca58ac3c29f1237a0bafe5009016584147ffa01c6879aae3a28e868fd68aeca07d5998f1b5cc8267f92957744628080670c8b8e2e77d7a4926884eeebf6025dda3d0ebb18da7166ac44095b58679c44d5790a92250b4c9a165b64d4993c32dd27224d0cb9d2991e88190242941b47beeca112c54664c10db039259449a3e44bbe958c85ab4515d0d5444a981622b0ceec26515bb669e7c79c1f79a2f0a1430297232b729324a8d2f2f77b13c2961667bc44d1c144c40f004491d29af1430a888c0b49494c40ba2fe9424ddad84ac9c01aaf355777b66881b1246ac8eec3f58746d61454182495f2a619d7901950be623c9932b992281f398a840c1c547facc4fcc9c9a9954ffd9a316ae16acd32c3a2a85e830db2a45230e14203454c480fab256ac49ed3858bac8519235b515b45b09489327566872a450de1e6e9aa45d41cb03c4068dc5d319c12c8b080e2844c8f924ba336d1136a00cb903b25d8d07073a64e21d305260b11212498f1a016499bce01ac245578aae8788933e5c9182e2c3c5eb0ea90a0267f1d2631209b42020c123c85427905657da8d205c2092d118ce0a1b2e4e3c54004978ab02049c2044161c5a4aee9385fcf5a2b2c5d5a5c94988115c4c50852f21483126b23078b1e1779f0748056952e527af2906959f2f1caef502bbfe222c28a6b40116248193b64988c2dcd7db7a5554bac416ed7094f848624ab6357e52459aa5d71f46c8c17d345089a72a8e4ec1bd92c43332a000423170020100c08860462c120c9d2400cba031400114f8040665838960763915020075214c64008833010c4000cc318649c831022b201402eaeaeabe8cfc4c7118253ff80fb509bfe77cbcbe70caf2aea7dbf65886a20cc5fc52629be1c846eaca637b94a878826eb05e64c85b14fcf74a2cc9a1538d617c93bcdebec14ce2124d6430c468a6e4411c92e0ca78add500af2b63a2847d718ab9b2d3b0e7a48e80221ab14ddde0bd207758a83d3cb8a61ae939803415eb4e5996f49832798ea5bb860d0a8d13cc879561d4200a24e13f772d13a4bf749d61440d9fde96b3bc27d33149266877fd19afa0bf74bad62b72c52f468ff0345e5209eab2e7cbf773ad04021aba9ccf8e4d969cb7f50da9eecff78556e1425cd02ffbf938626866e31f5e69400f27439f2a984b8a83a4bc60a6378083b3490c76f4e4da6100d2f78a524f887b82af210d458762cdaffade2329ab81ace6778df010c0e7df570d20f68da9f5f60b0071d192ed2b77324b48097e1c934c71e2e06034e1e5db92c60d634914390d4dfa5b99cf1f8dd430fecf105dad9cdb772576bc411f97f76b2881695080644405d045f7dab7cd633914c9e9b551d938c3a40e05d908016bdee2ffa9edad0d0664cc046770774ba4d96170d731abf06685a7938229081e0f3e83f3a11f663dadd608407564e848337d29ab28a3023c72d118f237cd4d476fc574a6e93c0b3bd0fbe6b95ea1e3edd9b4d245597d0b3a8283cae7e2975e29d228fd9c92cea368f7e9857895c4621ce82ba91c8cb2a8a4f6bbae71963a98f82e9908ea5903a543d315106bb288de0e0cd7b38b9f866e612236bdca296220aac48b033926a7e3edb58daeaca2e3446e35db2e82fd51ca23b9ffdce3da477c155db2232e40b8e8fd43eba296fb367ad455225dd8b140bfbfe0060ae913cc5b1139106682da4af713b91b19e1fa955e18e154b35c7a4cecba870b1186fb3a706f6dd38b0150df6a238c1e67e5ee9bafcddcda1dd478882ba54ed3796cff518d203bb73a878bf1d0cb318df3159ff97a17e955c281198375ddec3633a3a6949f4d49a3d0e22aeb97475036771ecc89cfbe16864203d1460cafd25bd93783ab66882ec5c8a77789afb089056c716cba0ecb718e007dad77577f355bc43fcbf373f9bf176351460c2340a991c31aecb8a59dee94ae10ab18e1e5a9f17098f8fbed150ae950cf649fdbf38a3af29cbdc501e990cd9fff98ab5d1c1da6ab9f024d5ded1f7612c25a34be9bd8d83f559e9624a49efab646ff1d39621a545e311584beaa42b870fa590a23c9300708075de5547014c20e73b020ad54876de32f49a345ccc5de0fd2d23d43463da3cd034c65b17bf7050369a7e8b43045bdadd2f741dd419b18191d9126f820f60db20d4f20ab85545030e8883e45de59627e798970eae4c6f0fa45711f67b6f6c346c803d671b7d6918325b7a4f3f5403a14786863643ad1a4c187ff131408e4972bcfb775403d95c738c6a726cd1b03bda5272dde7b74424a7e48335b48e1f0e7047ef157d60c946c75c6f095fa0aaac10e723b05a0f40b87271a06e930d139f8197920240728cdc4f656af12133bd8bca2f465a35d4a37bd5c077eec893864856062a08c108c22aebfb14bd496130483f92aadadbac5082eb2d4b0be561250779baabe0bc00244761f099fb52fb94a7ebc67a43f782cc2ffd305283818c3475edcd17c431057777a7909648143550591f94bec08a166303a186db6d287cfa9771eb5b261be5e9072ae8a61c5a402555d100111af3c724d8a02d583b0e2cb44491f83216b2107f912ce3eda189d696f0c9da21d1c497d03dc1bf0da0a05db64280b5408b1413b2d37fd9591049b78428a709abc116ee34416838ce84a8b114f15d1b78b69f5d237f2bc533d6f32e5ff291d12c64a9db647c8396b8a18784d48b31a1989dbc849d544d848c5c4ec9656d24a3b1c8eb72f27a7d0b80c612f7c7f5f994630834854d4b59ce5a8ae617d734011b7c8a15d3bc8673ca271e1992317a7892e29b1996a309645960aae2f5efe180209aa8d074e2d5c3734bae379a512bb65ff878d8808e2b719ce5df330287c7d823b648208048f5178d1e86438e2647cc98030fdcd91cf61503d92a382cc15548784c7fe0de97837330229a90cf89737a709213efbd7ac688595a61caf582464e8d12a49a3287b7f355e4b24c6f8b2f4bbe9ce396705e8705edbb264081136b0467d5b8b3c494392e63786389699ede25f49401374cb7f0cc6df8bb01cc382eb14d756e072fdc0e203d5d5ceb11b5595cf369753c6d3b879e9ebe7cb757514a379cdb49a2c09902338b1d8a39383f86e2563f26304e2ec2ebdcc4b1446163e95fbf988557beed95fb8bf38002e2b01b4b1ff913d0b396076802119940d066d5d10490eaba34a6285d8684c7cdb334c29eac4e32ca33d5833fab1e02ba4026687b0c7ce23e9b9d957420e915df37ce511f54e6f53fb7c033a648121a764f2b268faae1ec77ab73716c7f117c36ffc710fe61041277dc4eeb236a12c39e99a6163f3a8d0033b906b26b5271af8ba3e705c21d44475d8923ade714d3e99ab489a48b8c88923f7d63a45b568e2e1a8488abd71348200d2e5c22ce7c2e1109e78e1f72370c3561f7e13782ce724d3a3f7fbe41734988e54e7daa5f61b5a94459378412d619fa289e4f557fa7043272ec740baff64cb96b17b35c3a044353a16f6a3c44a6880ef80e93e0c1eeeb24b04039691cde73ec272cc2017de904174e33cead3e843b5cf298070938f33e83515760949ead9b6470af67d68a8b5c6046cba491e6355062e2bcd5b4063553698c52a8cc052ed661973be4d2689970f73a4705e4df5c3a52355f1eac7a06bb63bce11ce86446d4ef4faf4e01f2ed59bed150402ac7f7b8298fd9b8ec5017adf56e45dd2690e3528023ffd49bdf3aa20c4da6773cbe96dea0ee5ab4b854bfc19f048b5f7622cf43c1a1b26a29716af7d6cc45f4af45d03a46d8267fa6c0d77412cf80368d07970966636d421e14a0e31b89d0e700aea491bdd0b9fc515206c24920d558d690729657e62de018a4321e574b1a3c71d31eb4dcd336b8ba56ac35342ae2cebdab57b8f94e6d99b57c1e084739b6811c80e177310f71cfccb43a3011859393e01ebf96122d5fcac14bc761978cd6c5c915ac93c4b7d0b3c253197681cd09c1f91748381743e49b921162b06d5dd18c3a849a546caf8db88532dd7f6cde502cf4a8b1e79ae8b43eb7ef2d41bf0331947e3294fb9108c3a5b7cdb438bd06d4217df2c31a032b7e3918c09953cd9a84e5d92ab13a4134ac4d74fcc87bb00fd009922954b666bc33c4911109d9cd11fe13328f69a22d0e63fe7de627f7b940fe7bc06c44e538250e78a8d05ef573a2058ec0f463907aee1544d9715be3f4baf468a49a62a88859c59654658b9cb4f2ee1ffdb47461c054d180a8cc77d58f8aeee5ddf6e00d9c5f461009bcd245073a4849755aaf0ad3aad2c0e8b3d49f5488a35e6f9e8ed729648f0f8bac6733c38b4fb9809f2e9aa34eac64ea51e6d92913458045539f546c2b309e3a3f2f968016bd28c9677437c7e864d2595db9d6735ae826da883d498b15abe18b28d11ecc3787b6c54c9e4e283eaa912c891f6fe0a78b90f9af23c9c5c797ee382c4eec2c1016a1ad103f6ccb5a0b3c51925e2205eebfb8e3ba39541ccac854b68d5aeaf62cc5519e92c99b969d5eda23abafcccbfaafac2d34c5093b968ff6c552c07ac59558e214a7d94ef56ce2c17877f8aeac578e16b0d6ee85b065d48e565792875886f8d60d5a39c9552154c4e46c80569389e724b110751d96a644050cba5479cf72282fc1647536ce9b4d6fdef93974e18b2ca4e9a5383005d353b1a50197b50eaf7eac1de76440cb32958308023bc638398e09df844522e35bf8b9e125dc199f31e546f6e948020e6a2a6c86809675b11c1776d23254972711cd6b5f1e943442377f0687a0432a3f44926089cc8130283e94b0040a247ac16c11d985f609858d59547266552483e37d8005a9de669888030c5816f344e79141e0503b2b7e7a6cf745a1b2b63ac04a1a9d16c609e27f23979885a75f5c0cbb7e0a514d30bcbb22271dc2c67c3ad065a28c52f1f9bc9e1e171dcfd236e9f3201164c8dab180d762fc45a001057d03d6a59f4fbb3bd73993502f2e8dda64bb90ced3ff4432e73d8a9760055596238b753bada91113416b9aef4d064a6ef806144b67f7cb4c37a05e4e55237ce9b36f12b094898b5986c2b489d2bac09c546948fb7a22a7506d747a55cfabe81348c37849bb18701dec74be5532620f8865290496052b6bf20e76dd2b578ff806dcbdbceb8e1cef2eee58f025f0e0b21fd312d310c5086b7fadb31c29d8db9785b1a204a02fb0d94f142201b8a006df71d0c9d5d6a0a690c3ba33cdd56e52ef314464d3f4d44682032e7a797d47f0ea120c0585b64b68b8e703c042839f461e120e82902b8116dc2ae5f08ed06b5cd07f965719c261ef661e98bfc748fdb07ab81a22239bc00ea2c3272639b86b234af3f034dd3ccb053aac794d20285e76f44ae7a444ccf8349daaa50402536a39fd56d5a1218a99e2fbb31bbd8193c00e00cc5363309f74c57b10d7b2a18573d715647a8ca8784a4a578f480aa257948ae9616f5b145dd6d071699e6ebbf596ceed571c341ba1fa011997cd49003f024ce835f5a93282a698be54790fb34d9806d7ffd0d3ce8bd733b7b7dde8c912776c9b804d47998fce0418f4e1fe370c0874e923ea08470f23e75f8ea653344d17eeec40f4042817571e12a669d597ea65e09883ffa66e0937d79a65fed0dff170c05d3aa7528c88eb9895fb47aebbeeb234e03ad52a80599375292dec8cb0eb275b7fd3db98b2eeeff390c158473b9b28b3356744f042ed532ead4b0a9149380f6e8524feb1d3586b8033dee12a5fd1a3c7c50a7b6e4b74eb2049c5348272b53cf8ed07e00e296d0fb28a5d3dade6748a73d5f708ab14af377cfcb32d747e14a9973b2c62c750e1703cd8a40381f67caa035db3a3e10c3d5d50c3e91390f06ad3512706fca963bc84d6e5cc04d4383b283a5e80a49e0c4f3123f7f01031102030f961c5edbce59c13e83cc893bdbea9557bbbb0fbec310012a71303bd2961e8894e464ee3b210fb0808045a05938e08f595d651450a7e3910024e9fcc1257913015f0d5b9b13bb1722854171006177f33768d4681a6bb21d968ac8f3341b5a75aac9f5267c92d3484ebb624d9b7272461dce529543764bf41b4d7b8222469e552ab66b30d941ea33279c5854bfce8d75968b94397192ffb24afa403a5f994f8b839a2a81b9b4b60de88850a8a4e360cac5ffbfb07d12d788629280804b81ec60e998002b7e3323663bc5042d86ffe6563dd872702632cfbd00883865560616700520e1b7d50de9a481b3046a1e24ba3f886774d8090fc20fb0fe6cabd2c022cb361447bd87453f1eac5da203c05152395c1dbf701edb542aa77ddde9b4f5ca888ef5c16c8ea5698a9643953a84c6e2a0a9c8de69771c019578a8fe7e32f1b349eaa96806689dbe8e3364b9c19d787ba2188b3d564dae83b87081628e2201b2a49c8a32d18f4843d5970c3e96890f0e8c3d0d47df842cb4157f3c7f7c5f5ed1b577579d71810bbdfa644e71b03b6a086ef78f0e92bc300ca39a32167459683c60c958637832e687cbf3e46c53f6ca204e297b4bed76561976beeb65067f85339f0d1bdca78cf6d788b8f93302c68a32293f2ee30124914c60eb2cad44f332bce596f66c7908822636434b0d48454eab12b0b68d0e749f17827c8f8b0ad6bb8ece4dad1de5ef302a7cf00fe5bd2013f5f2f81030883d321a49533266c76eba47bc3a2c8211ab5358ee1abb4c408a84cf806c05ee7280164f5b15582a1253c6935e424701f82e6c43836a44118b3337d0b46d8a60e8b66572adbc3406e19f33b877e23bd44a98c3be7277a0a2a93cbc51d7b0a7509a5a70f20c11e379c65505311d407cb09bb008faf5e41c09e6dbec50860721dba6ded18dba916086b4f8649b5b107c2ec137119edec80d87d53a199ecf646310a0d647010c54beaa2a889184ddf843697b4619cdee898599d881646b384d5c26cc22764b2ef8555e0694d0b3bbb526ff88a29abd98f43ca0f12ad460040b25f955820469b11270cad46d1b8e849a5c10e02793030a5afb1218cc2ef843b015cb19c7f0df1c61d9a3c94ae622b619f21d70384fbc03af1ad08ac926365be23217fd049f5434e02b900384dcc81210c3f349d0fa14dfa6d6607b71a95709365f8b424c596d0f6cfa4587393c964d857db71229b88ee8102d307856d0c51c4c2e2e47be6f5b035a22212fcd36c5762c1cd0f5f55ecd13daad73735b0b17d47b7cb396f2277e9acc2bf352e97a649c4501227ac2d743724f9159dfd4097e08350373511df79824dfd619fb9e5bf162f137bb3c9b6e0aa7600dea756975293c1c8e1b1363198cc4ebede62a07439c6a2f745f147436b1f521b8f8af89c2fcca2c061962c8ac25f1343348ed456e65595e120c71a18be8435f69f19cfd01f8af6a6710cf2958692b8ae7fc0b04d1983faa67ed4ddc5742643a10bea3123e547caeb0059ebeda349ce3048085f741c775959f1ddde0b8bfa52b77a15b0707031009a048e91e2eee91096ad95687f970871a6ae5f2bbcc4759d35e41ce36e4e64fd5de66d2dc99006273ba96ffb63a9af7b0584e4057d01df331dcc4f1171d41112e61f211b2f420854cfd4445a55ef1bf3deff265eaba1af3382f3c32d1eecdd19c08c67a2a0c4e2850c597e255038820ec43aab689320ef5a55dee45245c035ad2ab46926dd193dca0442614c86dd3cc0e2575195e3047dbbeef1e932a2a4cc23c47537c1907312c6c14ea4459d824c04f5ca59b9b1fa1e1242661a3465c75aec5aec5c77047650f0dfb3f1f82b3363689a7f94e9428d88385f218e300d04531d8fe0b945c3374f4408f5b9ae8643b05af9e48e6bfb7fdd9025f3a635dc2d403a0f69cbba75b8e76c4e3e09d4bc088ceb292252e769a296b90f236326faad10f58834eedd7cd60abb92abc8eb215b2c57b3888b51d082274d54f9375fde9f8462532edd9dd65b7ecf685ce1c8b40d6e7f47a85b9b9e5ecc01c451db39c32dc670834afa5d2060773e43c743fac8220e4a1ea31143b085be0782959d34ea536134f7f94667e20d49368ce3c7328c3121aca0cf9a24db276b7097a518056109f1bc8aa2ecc95f8a649f5cf39989c9ffea2a840bba9876927f9c11e9239753793c0c32eaaf5e243a54a67c2d92925916213a8201cf32a89bda80364ef657a876f61966ba89d0154f092e8c22da9780297c0cee8e28028a519580340c08141acd0b53b65ccaf10615df89e25ca780642b9f2015a7976ac121342297fa0f3cc1ae6bfaa31c3a51330324c8cfbd7c93c760b0d2a5ed06cd0a0b7a23afd57ff677e6e07104b53bb2b026345197aa969aa0d84c4be6c8d280b90dc182b344f7bd9c650d99e0100faa8c4520fcf892e42eb3097815123b9724df930a56b9438bb9004b097600831dcff6f2fd2bc9f43d2e52a2130bc47fd5afbfe009c8fb5634cdea59539cc74ea3054ca8664a2a49f07c9993eb99f92b95a298060f7e52aaa88b166e4be6b4dc986178de8c65f3fdb3684ab97454c057c172da7a5108a0aa78042bc9585ce4da446188c5aecb8184cc887e856189f5eefa3d0506d6f26cc67f0279de33c491ba0abfff1c30efe9436583098c3adce1f4a2e9b60eddc1e0f8f98b209ae8a09212d2e76aac32f53067311e23b931c3bb596ec346c2269196175ed3204d8cd13279a5e53ddd18e63301279ab8c9dc4a37cbbf6e2478204e78e33c3b6113c20761e44d52f724aa4a70d628c47de53bf10896232a0b265b8e30f03e88406bd4e33aa20fc316e6c9d584030a586b92ef825f0cda7a821af1ca30dbcf0a9bc04baa2476158d6f5ec177a7aeb1ef78f883eef9a4a7fd5fb9c51b8b19e1a3555365e8c95ee0e657d89cbebeb47a2ad21d8e5574a44901619b3a4e5e57f3058b36d3317e122c863bb4c154dfa87d061e3e1f4e74069cc120eba75c616743dc1ebb0e1192bcefc0d4b3999b0bd39110a0e4afb25974abbec30c85f8403f3a74368c6971d3f096ac1d0c305aafbd1381051f3739ef07ec74b8ab977f05b0bc1a1af1b346d61d1e712a660413075a191b997f347fc1aa9115a7f2f8476e925086df11c311c7665aeb72eb3307ea734bd19ea3035a091ad27403253816f172995ef7d54bcf2abee44ef6e9beac1805c18e77863bfc4cfa828f2396d96f14eb583b5e335b0a8fe2d724e5510c6666a4971643e92fca4841b2d33e8713e573c33d531c643c9f1b3ee5d740851ddc48ae1c6c3a2da76f2ff3bff6bb3afc5a2c3df901963e606c2066c04bd092222520d077da0b8d1c83723c842d2156f94306085c606ded8e17cf885346c7b87db1268ebf5057c01f7bdbf275d5b777a1954e0d46ae4c819ec69243bfe270e22f8eeddecc11edb65dab1d1adec839dac2354e5fde6775828763a37f4b5579ce6d30b453ced773a65adc297b3e9590dc2facb2f1aaf6750ce1f92462faf6831bfb18ba74ba6c16aa595736b7fde01bf066401f5b996d3ea1521d9becf31319143d4f6fbbffb10d711a62b70c0b938702170945d86d117b6d37218b44afcba88c95e548f5063c56dc8a2aa08f146d8c3a7941db6e12b4513a3754dd487d120d0c4aff3b580063b8d69993c4fe1fc040569ec01d32a9834119670e3c8c12549ef3dc2fa1e40d9f4caff68a1967d528900c55fd3f752b8617f03203f282199004a6bdbed182cbf73d17672d3cea61ba9886f311ddc255860809f2704aede2dfb87a7b296c0916ba9086b3a5b279718065182a29a49e9adcd7931d46ba05b6395c99912d73c1161501a25b3093d845b0512b9e19271d1ef018cde0151a36d6dae73f5fc2d60571002c2682e5807d84ef6b03b698019d233e7512d085d7d5f99656be3a92129f04a2582c6931b4d6805e47cf260c54f8ab933ccb84e8e019c23c6400e5801dfda3741c14627fb0ddf3b429c63b16c7986552f71c1087ef80c1131d840000177872f2aadbde83774b8f6f698058380f61ac396ecd6c283cc8f5b551bfc8978e6d8ee8d6741d37124e5f60f890c4389fd1b9a6fa2430dc24b1de40500bf7b323cbbe8332c73f2387dd6f5197a1e5345e926bcc880813579a1f50a91df8813ca8eda5cb99de51b02357fc332d8e750b9f979ca30a6cb9e0897b1abb54200e4988264a83707b7b6b7286c3df54e8be8fe8ffb31daf5dea6090ddcf5f27f42e161604fd7f19edda800b0e4c261b58794a2e1a79d687aa8b8051cbc79f633b33511b2dbb09c22c13ab71fed1cbfcb32fc7f51c7265447be5ced7b45dfcff91e4e80b98e6622cb6c978c631eb0eecc799351c2912dfd09f266e9178da94c97733076bf9ee138c96bd21c954b61b1c29772111fb0a722bb079a6959a5b9965a98bdfbb9f1b8fcc7e6d4e1cdc230d76ef1c31ba3f1d5cb3244374fd981a23e649ece107597361a3ccf30a0f2c980d7ec68f839fcce71fcb0132b840183732353efc76710a5d0939faae790ba4b5a7fed84aefdc0b738fa811648de4a0787c0f01e18a8c98db7343c6c42c876660626d35b9f2353f488a039dcdcb17f1f3199b440d0cc52ce5193670c60be645a1b7989d116510cd19af3b7339e3e3b971d3745cf97b58a50b31cec86d4961b6426a99a76652c2448ba857ddc1c07d37dbb7a241a8957440a79a06eaf1c45f962ccb4e39e3e285a9e82efa58db5c9895fe4cd8cba839e70b07fe1766ea64766f82573386eab674a5132bfe415da59d2ab3cec3dcc6a1f957abffbbcd273fcc79f5e291bd8d19109b02761e03149e467e4adb5797042f144c056279ab1f92519dce440eb9d98d3abf552c1ad27388cee27212e4021ea207283396737696f6c0b51b76ed2605c15fb283f41ff23474a30bcae82afe7a3099c2e13581ee6c4eec5dca6adfa7a1dbedf19bd77a356cc104626dd1872f4de66dd2ab03cf0de6aa627c3efeb2899efcf6eb362524263e0a6cb6dc2872f6fdfe7831638cacf7050a8087fdc9f77b3d31c602d62c2ce4fac27898108b1e9e8008ec97c9a342c51a81a827a01dc7cf0683d52b4da4c2168e3c3fb277e5b44473cd4b3367b4d3ad698a52495a487ff322c4c41a4437c0d814ae97294260d1b4ab5f8e4eecd00f759aa1e40467d134dec35dbb1407ec5864d4830bbb9236dbe447e6b3f2d168bb1d4a562c12ed1d048658f85af589e70321f4a97b68b5dc0954c4a8d3ae70e5c6bfcf2717f784c4be8e4e5484a62cb527902cf2d7ec56dd68efbe09c0b7065f533a92f498b963e4d5601fa44a310bfe302e70e55e44243c38b93ae72c10b5ade2c4d25a5dd24b441bdb6af6e98d40918ed2dd69824465cf29d3c89be559c5ef9f5c504baa0f0cc419ccd7fe597c0781597f4a110e3f1f427ffa9be06f4ab885b555cd05d71647134eb5fe02a04dcd14678e1471ba29b76408be083603482d5d8ccd4c098cc9e882fa505c051eccfdea7a07134a204bf716e2890dfa85c243f4876138a9fdb4325b19ed88e9aec66fbbcbc27a075155e7d1ee4b7fc074f9faffb2fb09fd55724ab6036e385832c2af61c6d8e8045fa3b0621fbe57a2b3649f0f97901119c98f519b488da12c861117cd79368a8c8233d8552c6e359ee6261174e2199474a03ac0a9e7a810a652b91849f52cbdcfd4bb932c414b7834d1ae7256788bcecfbe411719d380c85444e31ae9557f3b94904a2dc7d53a99c875f49c73ee6d8ece37d0f804542230aef226b502e4b0dd7dfbe4945b2ff0e61e6e87bfac08bd842d22296db8dcab51b9d50529c1da4a8fb3088e331d2de3fe5488976b7730bad865ca2e5c3dbe78863e2cf0d00bebfb9154c4774a676535d9e6c464a3ea57b11f75a9ba94e1710b88a9d697ada8274c0dca117930654b33a313eabf4fadc3ac9e079134a011c67bae1c3daee0d8c7ce92f0de160e37725b4e6280fd78488966bb5532f43459c49f95a43d495aac55e81d83e9d92102c874af7398a6710db73cc0455d0b6381ecec6dbf736e338ea3eae5a5339bcaf8fa1cd9cd92039c560ce785393e6dbc79f2b2f4e322c98018e86cfd4560268928d52d19d172ab95085fdd921136e73edc09bb19dc9cdbcef7b6ff8171827e29c0321c47885b0ad2e6184f48ecd7424dcf2d84545ebfa5a70d133e2166681f7c8a198ae21b6233959c19f3ae0671ce82a139142e512e69bfc878cab36f6f5c0aa5a9a1b88f80102a112182fc888e55530d71ff845316c251cc6cf218b64f5a518c9286d4624d875152291866142872c662ecc90fe73f19da621c42fb142e2be9ea78dc12c0fe245c3361592fa1421a7f6b7610f353ef2ab39cf1f3a30563cd122c7151bfc1fe41af0af9d245f94eaf3cfaf7e79279fc6b79711d25175f606c4abe1a7e83c8945dcc43de5047be3831ec63918a5e66a82b0cfd76b781ca8e4d371b3f425b1c7b9f5d7eeed0d62a990dda2a7fe1fe2516875599c00df541a0e203c1327011e08e189f808fbff2daee41151a1217b575d73299d6d9bde22c5cf48afe07894c42537789bc947570cee465e13cdf65e16ce4e9aa24d57d0f5f5c9d02e4b4e250712ae17fba3b06da94a65c740e7d3c29fd9be112a56836c9e0208fd7293f7ee302b17403b7bd182e81c11f9b9cdd4422a68be1fc715243383dbe0ef444879857ae1c080f21c36db75377412a15bd899d4d1f0019aa8c6a59d740e70057b73c8633bfc92e52334ea5a50c61b0032072cce68a732fbd1858622db3319c6f1bdeb7798d809b183ec3098e8dfd453337f3e52ce0fdf830cc0f9feb5ce125442888b1bbba5e2779b6b8dc826e4603d888d7c722c56871a231d3cbc061affdb2268bb1b208887c276611f3b52feccac1cd0d2bdbeee9eaa8687b9ad37e253ccac302efc6d1eef3b1c2ec5eff3a57961d6c44b43b4380843e996f5532650433e481c16389e693e2b5d5b91cc60d04f3374885902f0e32b1e049b85aa9a553085637bf55a3622081c6ce439069e54b8f654f391a3d5c16986142a183b6f011baaf9eaab4259b7b7488e60d88d4c344f574dceeea24ab0c2a6eb650953daeb5eadc788f488b9638b796dd53652b2c9a087d4668176f105025ae9a12049da199c027b9a9706f5061dcd934b39f15d00bae8bfafa0d3af7dc05798cc6c9aca22c68e9aea703d8fd4b0908457df2e4385caa35605ed109e4e7f0fd8181e6bc70a9397a663a3adbb9c348f6021c812e1114610a6d8c6f097819ede8074e7727b558bc81d3a3cbe50acb4415e98ce26ec9d78199629bd9d090ee10e686a0c91b5aee24b592224815af0dba67fc9164eb9652b8c7d0fc1025c67f9bf8f78e3e8637e9e9d56592940949b2ac9c845831204e5bf8c48a0c5aa5d43cda3ec68870274de6851fb768457363e5ceff8b94760b3883e693be7e8847ced8ae87c94fc2e69044e163cbe1ae8dd1a099908965c0b2648934411d381bd55c9568751d388f7d558d0cc087c152044dbd7e8c4b3de660def06cb164c346c38914cd688592218a7a64cf65f5e7c71d7fc1a2c5f30abf193a8c381e7fc2c70771c145ef55e2661a2d10cd48f3b4467a2dff030a958d2701cce704004d41d80de4e41d60e6b311f7fb8a88abe51b70128974a9c34f66124dc300bdc46978a182e27f86a9757d80ab28ca7371cffa459948c4b93858005ce478ca69614abf90bf62d95c3099ef6e3739b966be59776ea1069639af9659c1528c270011cade968b2619ff5e81ad9015cbff8566d1ab0f75ff9b0ee98019c42ee9eacea82266e954bcf662ec650a09c488aa667aa9ca898da73f033eb4ebac4a2bcaf19ab529af4efd4024baefc28d952a8277bb3756e31f94c133d54481a2fa85da605e562a0e8963171a91553142ecda4652e1a27821438b051c85b94962dfa4cfe2c961c438b6867e8d451fd29c1aaeee6b7b9d0d563798c9bbd8690cbc1e79b7bae8e507cbaae846c9bb1db4043a6241959da48ea53de5e9eff7ff6e2ca8721b1ffd2229af4d490db9eac6804cf9bf68376889f4d6dfdb6155b33d7a1ec800ef56ab9bc8e40d20486a61bd0841cf2f2eef2ec6095e073b399ce2f9c43a86af27835d7824bc00e3258c4cabb9953ede96b04ef00b62185c99430ae420b1dbb1e187e97d779d69e7199823898e1b270637818a7226b9619b0c025190690d1fa6c3528a1039c625b4be077579ea790e9fc1121681261001082bed042d39cb4a30cb9667492000d5f12a48dbb11e1cd4a99412981e014850de0868defdacf1c22f068a3bfa7c8ca27aa78595cb3c48260dbb4b2d56df59b95e9ec13b91f0a1512d05fd79d179085c445337b1400c0f989d22402d5405531192ac9c3e3480005d827e03de2b05faa156705c11a9d891ee58d87f56a3d1810495766db20e76ee4808c5983eb81079da1ffbcf0ddc2e288053b99bc4eb97b714ffa28fe07cced4a1db15726eafe097230c3642c740fa57c18d875d6cd1064619f527ea76ee46fe8cb36ef776a1f39e6c19dc06b721bc0ec8f3449c92460cb6ccc3aa7b18325f23329ea8ea861f834eb69dfc7db0cb814553724089ab316421be448454cc460b5a2e369988efeafeefb8f2c72288aa41df4926f15ec97db005037903c35eafd5c58003c49d72a3aff42bf72710b8fe74f9b0e231c63ab8550d4026163bc989afc796a0a1b60c3e89c3a898497581372e4af5930a1b82776b8437a0e6ca48661be07715ab492879ecf267fef6aa47cc181d5c78f983f6f836ec34e9b9653a8e3af41e1e89942cdfc191063197ed90b190d158f19aa124f8058b24a1593804c71df839cc07151c023581d370684f06290488e2af10bdbbc8fd1b19b11e9aeda79e25b9c2226c6ee8d69bc6c826ff56ad804da1ff70162e294ef03471f1af4ae6e96f1f88f633ed6dbfba35c7320a8b3efde124561047e954e1876375234a3a8b8afe70d7dc7919ce6c42a3e432cbfe9f99c3ff56b24aba148243848a76e3584815b4caa2a6a89f466e82232cb72c07dc0158f3e1253819adf03887d025389f05657a46260dd1f4786601e896e9c2713f10f46586baf3b33af6b81fb87e9f1007c2d97e247adc8f059f77cd803a1a0acf2bd9d82203427f6800e9130326b41a86a483306046befc9798c0b97659f7056c27442d1b5ce7d0191a12f864b9054c6bbf4a9c75bff639025e636ff6db572295b08823643870aa62108f84947b73a35ee621eeeb4b5342e6e711fbcc00218c341ee777c38c8ad978dfa9501c2c63a268e9c9317120c58d0caad49c8fd2057d8290066e314e30d64fb5b2bf0d999e2bd6a952e145341e737f5a450765e6e778341bce4534c018b96637af1066d87d40ef2e6bf89efc4a34664a7d87d13ce12423dc7fcf9360e30404c36a7207fdcfd4f4cd0c16eac55f43ecb0858ce9ee6284c1888ab838135531cc7b656b368c6710fa0b0780ff18673bf37c9abde372cfcd2942663af8a13344569308489d9b183d43aacc1e85d5bb70df9e338a62e2803b3828af6520d610363132cd74415cb397d2cb7e1be46e2069ca05f8cd3cb8b0588922e8b2a998dd1cb8b33ac93d29aeb729b665fb658b1731ee6f86d2b30e91a61350c2adea749b669fdce8af12f0d4f06c1135e777d4a1a7a4b8805948811f6ae7032a583048fc07a0aa60a81669995baa6e968e37de369b192052301959f8798e2bdabbc8018e9fd36dd43117edd191fba5d8ce40a02053ebb37bae198f6c1f708805405d620c4d28727427a29334343a6065436c506b64e1a2bdbf446ee1bafc9212b33a8d8b756f97b778380d341ce84973fce3bc143434048c84d3a84939ae7fe6e176ef730c69442e431191ab662d93846fa4c2059b848b24eb6a519245a94000a61d14ede7f653390ef9e2af5a8343ff2c4ba1630d7c23ca1473959b1da9c73a89f9eff8420d3a89b89670d022cf9b4601c8c4a83527eb5e85437277efe39c76b1b81b133b2c501fcd83b35dc909746bd71d8aef7c8ec0279a401a940990d8f651c32d87913774e3bd7050164f9183484b526de9fddf183390bcedca1231df76c63eb541c494fd4db68ebfa5ed32b45079ab5c46f1c31a5f9e44c3a616982e9f8ac71f2eb7be05bad8ccbbf7e158646075708ee4114ac4a57005ce80cc374243f067cb485ba1aae2e7333c98b35c9f4b211187a26aaaaa84d52952404fa2ccd23ddf67dd1a8e24ac2e683cd75bb801d376f9e8bf2bb5e52d0d3ec700a1114c9a55086ea11036dfe2bf1a86c7293b69600765bdd08f430ea94ad6825e8acf623f9aeb67fbca71f7ab14a142dd69e0da62a66a3b4f03166ef9012827c90228701d624fdfb2dbe498e989436770cf46fec6a3c8d7021d95606c8e7014e90b31f2eeba7768587348bde1280f8a9633a74501a89086a7d65ac572391c9d4318b9483974df8f1239ecdc1737b5182cce3bc6953ddf6a83fbc3192f4463ff3748435c790f4e5909066994da53946a1bd88f0d10e5ae9b1d9f00aa6c1cf48c7f2852d025acfbf7e54407a772708af7c41981af5d02da2662a71f37c52ab55c7e64f154df123726ba7b555f45694e8f3f2593ee2fef104df79b00031fa82ea132f37672e2a6d5d2e4e074d3b2f25bf98226d9f086ed2bfe963e8ecd664215626ed4c391818a20843516ce51f2b2038c9899cdf40f3249adffd8968c72424f7a40070fb9e4760a2ff760fb355b388611e7df7c52e63d71f2a3d40402e9fb14a2ec0d3a30648828c1fc7e83bddb6887564c83ed609db60a131b21cec45f8a9c0f6bc9ed6bd248867b4159a3d1e2393231e4995d22c75fc6a87558508cb0a96e4612c0632701a6409c7d4554870b949f29717fdab4f089641b90f4dcee86b05379bcf80b88b12ec1c347430e05e265e0e8a44c5bed589519c6aa719d638fa7882b9301578a18cc6ba0d8c1a862c06de041c87f80b53a50d21884f131aea2e69af4d7ee2a5abff02618b6e5d733b04d6749833d61835d4c5981ade832d4b5ba5ce5174c355176df342289dcbe323a8780d86e49bc9bd3adbab40440d60fa538211e65e10c83ff3931085af9db339ea68e601fbdf7097458d912908e394b06b1ef2a7a38103910c82ed516e40aa145dd5d14c898c6a1ca56aea6ea7dd18bcb621364720ee858b326367518d6bd694e0acb126252a85bf19a4211d4f9b94a4bf7fef1017e3b466bfa5e4e3baac4f7387c6778d116bd7c118b3ee4eec56090d185c5284aade38e18a8fdb43554b3cb0d5613488eed290c012c20d1ad77ea399fe6c572a6d6d58f487c25ec8183ff65f8cc4d5d7534f825cdec552c9778167a65d69dc7088502e11f089f96fef043951adaa37c8558adf2278ac39c83ef133b29889ccfb29d0be008f74fd3d2f583a7699aa95c15881b642d926d02cec45603512a118f26de10912cef08aad0eb908a485115598c7d15f3dc54228f3cf839004498e1e571a6c0c446940f46dd42fc1c2dbd4e1d992c288f9140bcba2b63a5839d627e585e02fdf14b850826586ec12c89d29b088cf41b71d9ec5b90c893ea404c58f3ff4ce8866d3339bf333ba74aed4088908abb214a7bb1be10f56fd7270d8cd70b05e1bf0f14247a6fc88ccbedba7df444956e7f352209a4a7c588b54e275e3d4d75aaeea447b507ba9646996f360123651aa8e2e776d25e5e3d66c25ac0de777cd5274cdc82665c5248285e9165c8d8d4c583d3ca8ca9c0cfaa07cd4de88ad6aa9594e61d6a1d19648386b7c64324445396a958583f5c28202f5880dbc6512e440afb848e8ec7114344ed8b55950d9360f0b63cdc874b2d9b4e51027c6e5f44946f796d108a84b0352b47e3380f9fb1b13840901607d9089205c29039ae9d941d211371468e424f0b4de6a66f2bf06a309d5ef1a4bec519dd61b1730247ae5dc9d637ac870759b093c70ad946c8978d441b43611589572549313161d27a357a5ace143014eabb64159be888539aa7a2b2b0e270c0d740ba4d4a7edcbc5daa3c64285615b7f229f9155e060e1ff56144b9ba49ed6056f9d5b255cc49b2e78f03affef1d28a0307d13a13c2b87661e39f3c1b7e0978fd5d47532d2e1cffe244c624a9ad247666287c5da8a5109752f0272f89f30aebea1940ece6c0f5f3bd759a6d0cd28a13f0272b52ce1ff86354f8d6da32eec04e82e4dc1025b354c8ef092b533d1895f0d0e2b97e7ae1452346739d2188dd14b0ba9f93af9782e35f9cc49cb29a23bdab3f56e54cd9da52d309d9a2799348eb10ae50a616112389e8f79b0d4bf5f30e1158acaf42a3a70d137f428cd03e7ca6a650ecf796db5085a38f3326a78d1e3ea246e88f1f7cfbe5de3a3173c4b571c78f89113ac287b4152a87afad6effcd288d531af9ff3fe7a8552ce8a89b398a9a5812f5b0d31a7efcb74af3b15fd8ed73263b4e3dd11ce5eb45660c638e42aaa8c54c36b322a488996c2fd392b364592b1cca3d7d72c985b66c88f030199b126f7b1b39842e7ba264364a0e45401592cd5e0eb6f8645ab28aaf0c2f1c14e54a4af6b1ccd348446494790a52ed0ec5fe83bfcb5f4d60dea55283fb9351ec7c053381dd0676af15451216ab48c530a3243965080cdd48624706e840bcb18480587504f26e570e4f46127168557e41ec514c890127b1c928d641be7615c6d09a937704919f822d5427986fdf130cbaa09a2ffc8cad9e4113f62934ac4f4a2e3a0bc42dfdf868ec5d1c3698b2f4ca1063b1ed35c0178d381c76ceefaf93e4971715e126ecb8a3de6745b864ddc9cdba84cd3692a40434942ec105132b886b85cac663ea1205c9131e45393d8b17c8728f233f4c3b34ffd406ec3ad75aa22f684291561a111bc78b9c2ae02260fd0e674224e63ba03793509ea5e76cff0036003f387a79f09309f54220be22c4468b1233a5dae575debde4b10898c8813d83ee317cf9908a0e915ba2aa9e2f7a8e61b23353c8091a3aef0f57ddd78b3c87edfb3d8a1918f9b783db03580f5506b833be41291a85083e8abbe620436a9d359c943bba747bc4d34d8f1c20320f8efaccb27fb6e887c7246b51728067497c13d417588fde6252c6e9dae78152aaf3d85359aa128d769b248773394685c2f1540a99dced487be0c16f2a76dabf6043d0c59974f6ace0ec4d268364a51888efa102d2e8fea603a26efa82fd322fea359b6f671033b00d0ebbaec1fb1ac3e82b92213641d581f2f3d20ffc17a11c33d264d29cf0de92332a97d8a13023a749550e7fb0598b87929cec5295d188c3ec4489ca1154d86e8ce7b1d2bbc4dd907bc6e880a9320b12286025156bea997662765781386db424b71590a6f0067f6933d1360e2896e0c9789af01dfab63f4c60047f3387720c865876a72c5ca32c6a2da740c567cb266b7fe139f5b3beccbc1fda2fc721a5e10604616e80cd9cb4b4609a91cfa2f7d9a2e42d55d8f5765cc42fc9d8102bc87d9d323cd7e7d3ffa61e22c16c7c5acb4e08bafd4692fd77d82d48eded9d4a26eed1a786d8fae806597922ced03844853f8871a77338e38259379449b670305628a53e5b0b9a2f6ed36014530237a28c047f5bcb6dfb8734b95757191cc7e094828bb76e0472cf1dbb46ab8feaf4087313561be3e2db80b6778731de3e4407d3acbc5c63e6171de72bac6d9f382989dd24eef994888ab86c01da63276618c14314799091a2934e3a675b41e56f81868307b702ae826c8b22c6e3f7677d2e89aa2103dc29cae5dd2524a237564d5489ec575c64ecd4e15a084787f1fc4d72924b7ff7e924ab4655cfde41712f437e5d7be900e52d71bb4794103e1d73a4725beb145879a7062d9542b8dd8ec0f741882b46bc882edb79738f61933f4ed70d8811fba361c5b38cdca09b1971e44120898599004e43f245744a4c4e6f85a9208a89ed13407d258e0b757a0a411f6d443f61974624a247a58027fb05c5be9245c350c16fee78d447103a1f34313469d682fa7a4e6911f97bfaac723e07ed4e978bb4a29ef1a042cbbfe212f6277d0e19383311159958a717ed1442289ab1a0a724f3f5dd785bcbc6d5a640ff067ee32b5f70784bfc10f841a30f12aa8c45348bf969d5223d1b7a846d81c8b2b78bc7a6f55c4d69adf1ab2edfa0e9b445b269d4dd36d801f871a8488590e1c864b87b2c4a3460f9ca727e1bd23c8acaf0f566a4d13ff2bcab3c4aaf99c046841c5a3fe1da5496c8a616ed8b4010839022398a591ae131915f48876c40cc28c60e62180a57678521028037208959cb767783150c9689a06148c9c9dd8bb14463308c538ab6f033b3920f7d36dd376c45a1d4db5ceadaf1df6df824ba391c7b610dbc7ebd0edf20af4596dab34fea6fd56acb826db6b8fe21cb8ad1cff79d2f1c32c86dcb0fabd9b04e86df55c98f31d62fb18895239ce640c929c76933ab2dcca8b4c8d8960f4fe1dbec711277d226a99f2176405b191d00df744afd972c258724c2695f0e596557801005a722bf27822e62a6c97bf780c01459a0d268a04a1daa42fa3d9021af49629ec819febb0cfc78d976362dce3bb061ddd24c43be6c8788261cff13643a80cdc1d1829d9cefea93549b8671ca5375080af1d6e3b41686a33ae92729f9fdd08061bc425999843da024ac6f37e638feb73d38c93693aa2db935fdb3c62e08d36a836c25e86c85225493f50771fb81c1f352d320c86d22450e772b7449c91d60e04c02e6a6852cb566345c69ef831f9304c159ef48fc3a304c1a00212c7f695ac8dc8558ea310005f1ab65ef80adc4787fd118cc25260e601557b113ff1b1ffe478539a64d568cb548d03cab6016232158a4818499189c1b7f2399b8f2bc77b5ee834c71e893bac609935e45699d03ba073fa0e125e1fca699b0450446a9a47863d25a47b8570cf3886aeeae5de867b72b93df3f6133025ffd669613012a56fd03150913139cd31e8253a7c7b8046c4262d11a1cad5e692ed71bcf39ee9d26d2dbac29944682ed5016af0ee8d827afeb67801be87bb851ad98b9687a184c9640ea5c5461fd6d1eddc5419d6ad07e6f0c90225a2233a0fd38ef5c6cd50ae10760c1f6403fdcf71a3e83a9701892041bb810f0da22d7e9f4ab6db090be4e4ed558f88a116082594677c1fa85f775d57635d694e43eb4e21ec8800ea683b3c0de1278e7fc44bafa436033e3871e0b38f8930cf5fb1e30c1953db719aa58cea218acf3a8b095e5060bd40f3c402d34687d745f9eee7a6c9288b2705d7ffe962ea8d059473079735a6ecd9c1bd1f4a36a9e20210ce1bde8f5b74a0388c61a8aa56edf2b0aef737e3df0c3cc3438705b8aa8777d31a39ae650098bd8dfc13be1dc6ac368cd17500e11a3331d352ebe4484051c842d7073b12b38ac549136380ed0218310c84bf3e72767cf4b1dec7b63d5a3911593a2a8cf1c5454bc9696fd8705d97a54002610954023a4368003bff7ecb8b68e49dc19b638ab6a970809fa069e680c7a6620898a533fc3fbed3f14026f79bf29e53e128bfc7e90a98411164e3cc30e6c6a4e8d9f3b01d145f42460d060879ba0861ab9992a50b850efe80af5f4cdcd384e57e98e12ca87f0cced6da40b0244547953705e3536b6c88a5e24a3a68e4c3bec45f4935380d08898efa176ac6a8d6a7eb8e599f7e17a9fe48490dbd23a21dd34954cd457441fbaf57866dec09170d5586f977f7cb43a93b1b8f29eab8171ca31437ecc12943366dd863d3cfd2f79373cf9b4ca0bab4d5f1e30903874052e0d6afc2b489314268b17eb3365fc89869aaa8dbfa3fce4b258d99d288739cfc03b1aea60f335a482078737cd3e0c7c59fe310cf3c4a4b931ca14fc3885546f597cf6d547500e96b3421df8d94ded91418aea45bd7cae5cd66978d083149e032b7ed04006a20f01bfb94992f4ec240cb2b8a2313381d5b91a20e37f7084854d9ce443ed0c663292819ed2a8927bdc4e06b20d89e5074966179b59a8b0d4b1279bc5a5975e92b8b35f14c875c628fbfdacce8167947fc3c41840010c81c62fccd54b813211fac10f448cf432aa7f909aaccbf877675b94c201c44a97387198d54f09682e2bc04db4ce4bf55414f3f6251307dab1d4d4dd67e2374e317fb76ead5cb78f89e1888792e55ceac5aa5eb15aaefb72b3eeef8c013c7b03fa80868457204cda4a072d6644822c9c7ec79279210f48ba2216b84860323261eb3da988ee61ba5ea711c3c8a6839e7473be71015cbc7691d537596c6396e339ed1ef1b86c9804bd1edab00f1d6872fd7c4b4bc8de7bcbbda59449a65d089108020845ba70911ed6a8434e2a1ad65c911e1a01417e1e9e394e3e28b2d2648146ae70911ece8e203f184843a721072b4e480f8ddc90b3aa089715e9213e42f6982c240d876c2800228b8b7ca2a44f00ccfff098285ca2480fbf28c8efa7873262b4da072678f0901ed6b2c88f4506330c11457ad8e4934fbac5c87e0775c58a8a8a92423aad8f5ba9567c4528c02cd3efa0b3ad327bffbbb6fbaeb541b8ce76dcdf6bb7bf96e3c46b37fb36dbefa0a2eee27383fb5d02e1cc2c26ffe4269f50b4f97f991bec5f6bf5f2992203e0d499e34e1b33644012b8ac5fb4da88d95ac2954b30bb0dff92fd41af3c77fcecc03b623b603bc0ef2ff21d3bbcef37f21dddf78fbee37e3f0ddfc17d3fcd776cdf7fc377d8ef5f8a85b0f0c3316ce2418fe6a447f5a908fa08cb9406731c7670d8c16107871d1c76704ce151cff33cef19f321e77b21789a5e4f30f29152998f4d7d76f5c066ff9acb99bd1cc1c4f281567b9c26107cec3779031dbdd4481d7e1db7d9da35f5d979e4fc6e8a439ec849c134d83e52ea75d6da5b1548a9577f4b299d7466a5b4ed04fa4ef779e79ddc76edbdf5de4b7dde7b1bcf3473dbe6b66ddbf6be6ddb94f271ce24426ab64fab6f4ead95c1dddddddd7dab1cc7518e738ee326c7711c575487f87a4e77a7b4565aeeb191bab78de36adff0359db469ac7c7ac0679fd65a6ba5223ce5497d76e0cb7d76a562d3bccdcac59dda0da4c0ee5d423d0edfe720add5fa7cebb4525aed06eb3c8fdbbce9d13438ec24a5301b4b8b88fd017d94f938b58a8850735123c11a89865cd9cb9d264c10790a813b4d982fb9bfcb9d260c965cde0c83e54e13464a0eaa138aef7a52b7fbe6d5bd525c65f4e82badb5563ce6ae94525a8d989f3b1eb3fbf6fd3fceaf2524817f6a802dc1b12717e44ec345a76b5073168005e8d30de5f90e8238480606611fb7503041094f5875605051d6c3aa70cdbd85c29239281ca1c9c89d86cd9c260dfa913b1886e40cac56907a09e4504a29a51998309dbc68065c824678345265f33a195d34098f4b5b4786a094524a29a51cccc94e23255fb2bf2de2733f437d88e359511b8278029ed9527202bd94523f41a648644a29a5d4e8ce8b335e1ba57406791215d14459c73e40a0e22ebc3ea26f371f0c5812f0a40fccebe08479f0bd08f48a2b72ec67e1ccc76c46e979428b9c3d144914ce7c107dd11789438c8020891e8afc8862efef307fd85782b9defa9c58d2ef7e0befb45169d7d53bf44d5e5b3c154b70aab9afefcd1cdd57a92477e628b9bfd386d00bddaf3e0a6ddfe43e0a8973ea4e1bf4bbd09b36e83b8c039ab716f58764e1fc4a32a7c21ad2af4574706963c8fe538f27513d330710709c7ae8971e0dd027a3b21e1f7d4c54a6e26cc2090d9e4f34e149a28c78d28c439ba02f92500fb4321527d7d4e2800a2e27950fd9df4b204119e883de7dde7fde3195144f62f11ee443d76a6d66750d88ae71ef3fcd74ed8c500d4dd786de7f0ed135d9bb0bb184ca2e6a18a4de20f6836c4f9f0b83704fff8641ee07e99ebe5018442896e9b70883b478fa436190a1ef4692854164ef22c44f439fafe18683c219fd9ae9b3086714a86ed6a38c6c29e09891d0a5845ee55345978a7a8263ef3d2c1432b3f7b3704863d9a04216399b421259696145df3ac1ee54514e9e50ea43b4cfe33951ca8c7ef8d91a4f701567d5a49a8543b617ec70fd400e79b27a7a4c1692e893b8f026fe98367e4c1802dc732a7af402fe3ce5ef4ea2a43cd100f4ad1567485c30101f874caf24564491b3270a87884c48a2ff1a08d91c2afaabea02460c296d709d45ef5f4eab2fba0abfc9172ffebf01451f8a2480f145ff22096ef001e38b9e0431fec537f9d1281cfec3b0e8bf67b9871f7a153da28af1309ecaadb8f52fae253b0c304638ab1fe3a1c8591583f880f131c42130c4a6fe4bf4c8bfc9a22f97608837d46ff245d8248c4d6c72eb30a2a2a8bc6a283b5580933060844e154595bccaad4f5119792136bdca6e5dfcc0cc5ee523ac8753d1233ab874a250070ee42c1ce252504a58423ed1482aaf9a39baecef35fc20c0b4c163daf01a34648530734ca5dbc4c44d45f62db987d42c9c594720c14512855f86fc26ac03f7a86923844945959c0810f72fe716265426740d2f1ee5369a585d517995cc6580e9ed3ed7fd0c6b087902e9baefc40dc8f2fc69e7974064b9fbadfe0d4b5abe7fefbde5e7b247d7e20664b90ca1fb12c4cee5ee2705ec1fa3def7f752d689976e62874064775aa91cdfcc032ef773b945ae690b052e54d0e1091922b85069b976a4aef86c90c70d0b414c8152050e402de0b2b1b4e04c21116a920492395298a820e6aaeb94a0888f0a97198a70324396312f6410e56686b81244e97542c10bc99715154a9ce8ca0649155ed79b1968b892268c0c4374fd201fbd16e14672d2ab5b3765de088930e5083a5dbe88a8109502233f7099202a89152b98c1010bd6e1082580e012d41c13335d55b8002706297a091350f06448494d61c226cacd185cf45544691d336c5e4811c1224b4b089f226c2c103f54b1689347892d2545c4aca1d21e9d13c87456c43c41a60e192f17a23053d34c21d4ee17ca8529146cb150a607203c2fa916be0044a1b0a58936327079522f9deed50722403e1c845b31c8fd4d2637124aec89038589269210a3dca0c3151368a8c8304b012e8328ad779240613126cf1102073d727a08a288372789091a6bcb962876c29c004ed59ef14e114e2881e28b1e29cacce0c9f9ea8ab0b480664d0a54c8c963c98c600a365b6e10024b6b89122734b1ed9923c50b66b89ca002875a7f082f4b589922a2ab0420fa0e0953605ae487234b5a5801061436329346d6992954649c5499e2ea84352d7ccc09562c922a991f6ed8a871a14a8b1216dabd385c05f0bce99263268a3759ca4c2f514ea0a45025052b27c0a9d225a1250618b644d163478a7b191aedc104363610e1460a263cdb57580144a0dbd848f5b7f082698306271a813d9763aea1376dd4af7103a68d505019513b156456549a743501a34277d55f4ce410468d1226dce12104689690c107384478b5a922668f1798d5d6143d5e5ef22c12850c971a52d8c1090decf9b262052553e6309912e3339b6aa2cb04512418e9b680582778010924174a052e2e479cb9da9ac325430a0d26c4d9c14b1e3c5566563725654b4ad6d60a57595b56b47c40c7062f546658d205072a350a686aab062ab78232b50505cb1614a9d693a71112a2f20c41979b266caccab8f0869c4f86f0b2031e3a4448d14095a8d3a93b45a848a7e2dcd3441138a487b3305d4cb8a122270aa65898223d9c65b9fada49169395a70862272f5592f958bbfbe047604a9956720ade077f04a1fb96f1138129756a778fb3a8d22ff5bbc10313e3a7632fbd0eb8ecac0f9c07c632b17c4a7b24e0aba4db174b21dbe5dc37c8ce71224c262c78f3de3d71c813e97d880483e0a30f1f4324d815c0919ef855e012e320fa3154f0ba8b9f084cc14e952a2e00fd928e4d7d9c774e09622b8d2a9e2c5f9a3b5579981061c2c31cad229880e3644f913d5d8800c1584f8aad2a82c818e1b3a9105bb2cd5027834e4e407fa092658e0e7680008289deca6ad3c5049823a2b042a64912d507355fa0170527de70da956d5b6dbe6ced9933947b6bcf0fb9cbbdb5e7885ccab4709407450f285f52d081412b892ffa8208a4f2a4a1028938509cf01f7ed021678d1d3955c4a942e33d0175c50725ca60e192640911a35abb067effd7a111a5ff2935d2fdee0535a05aa214fc94cad7713d2988f742ee4f2cf6a550ec4b988e58d26634d2e03e302cc70cdefbf1e091c1a70f3e98056665f0bfd01f0cb9efab4fdd8fbe9fe1e5fcfb3ea5aed59a9f2ad5fe82e7074f2f7ddb36e86f30a746a2ff7120e7654f5ce2e00c2e3b6b6949497fe9fb7efbf21385d0aec425068f409122883d0946107b24938c894326f96dff85dcdfb0b3d7fd154273fdd4fc5fb106e15ac10c995123f8e8b3c5d27a7777571bded935eab58a3f7c746bed971d6146750df12f103492cfd99c33892b6940e557eef34bf659694b41a3e1a33b8d31d70a82ae519a47a04a3fba2e55e2be2033fb3355e1ce5cfff0910d2e5bab6b478de4efef53e98279e4ffa38f3e36927b7ee105cf2f472deb1ffd267d59ad756a40154277759c3a753a06994669c8a8d29049cae811a647f3a132065d9b11a862c547fa820b2e75647ab33057575425e26b234a61ffd5d18894d4bd629d54b97e9fc8820654f37a4ea29e38992cc060b00ff6b150bfefa0e66f46b97f16f4c269a491c40eb83ca35e84319a55b5fbf51fd0b50c203095349847f5ff89888080bc5cd2726d2e2f9c518d54dffb72567155ae0400ad9e59f5a79afa26d7ca956b7dee7ab4aaa4566bf374526be40ae3c0e9deef60e63b59e89a53a51bb429d23cbfe882e73badc146b97a5fb9af9ef7756a7df9fe8a6572fd4efc625feb0fd08b259031dfef40d87bde7f61d958f9fb6e258f297b1964ef287bdef77d9fe779dff77ddf44bf707b2fec60db5fcf134510c015575c914bf7bc6feefb8af43bb4140f100f6ab6e8519325882421ec49b3736fddf0c651f8b6a758d7895c8213fb2522d3073d69c847cffeb6735a009b5d6c7200e71c57b9ea20b0f9812501af899adb727efb39eb4d8dd4b59b038056cdba3e55053c63244e2e679411ae5cce2499ce399b4bc24a32addf41cdb509044fea2d2a5eb9068c03afd5015db336375125da16de68243a459a185c36570642e8dabc79a6c8f4270999fec5b80343128ce07b2493fcfee3662bf9706f67d95801c08124231b8d34779fd96321aef62be75e75989375ebbe6d6190d30fb86caf1c02900e08f1a45208cdf55da96c3d408c72fd929bd6ea7ad094faf3e395ba4fffe476e1a21b69ba12600b50b8980207680a11788a98fcd5293ce4cf82325c199a4265ca54c6334f719b6242be028b0babc9d3f0081eda904f3f7670a8017d9c6aa88e60c983877c7ac103391b607fab13a5c817f934e486b44784a1220cf95444a5a91358486b83162c279035b4400b49c39ef9b0571cc2c28a3c31904f3039a47d28728613b28a18c7b4a291e398b6ceded8ac51320459c356a30349c3999f5e7dfd849a306a68369c5dad1790b8229b082c3d5491dfa48287ae2984950c57e447378083fdbf2aa70623a4661920ee746da00ddb4c145da6c81abe90c29360c9c18aac216c8b160c5c348264df5e6ce6c1cdb34b9819aec88ac3d746dc97fc4d2c59e849ae4ef29dca9f8d72247f1b58c38f8adc224efe3279052b9f4cc3dea2d221b791bbf03598ab3c9f8727798a42bc2fb002872bb8663e86cc189c905566c55903ea5b3a328861433e715590f5ad3864e2b942e504f2896a9155bc8e834a0d0f48c827ee8b080c6ab2142983440be453cbe9218d73b1b026ca89cc61d345d6f04613d2bb4ca1e68aace1e4b285fc38d08693891aa6b822bf0bdab0ebcce024ab036d38bbd63091226b389544919f3726890b541f68c316c315658833e4078236bcb1440a2fb2864d7e3050006ef0cc030a95a718036bd85d66481b0e99607240b3841cf2c435f102d98ee3a9b35a12361d29a40d87b8093a9499229f3625e46ddc3f2758624417b2862da7095975f8da2b0ba1b91b69fcda8b579eafe64b559ea2109a012dc281a450bde7cb16ab49a1c62eef323674a9819af9a0436edc21a908458b4c51468aa461fb50822216c81a0ef12498acb1229f6a9a1dc8761c5b125e4fb131643b8e279f265ddc1336d09e7cac20db710491e73f7147cc90ed38a0489f3877c81ace7cd0a745e2a8c0455291b665822d265f9eb57e440c113c240d5f94b155ddc40f5a8c203d7cb10299c60621ae203da43186d4ea62e585f490861452061b928643260954e894403ec1d290ed384a30cf941cb133851bf2298806dbdb1432a4b99263258710396091dfc422831912899a2b3660d128a8de4455af1daa6809417eb60838287ca571210929d2c3a212c821be43172827904fe00e597086d0b450b13a0e1a3a985f81749d9e938edd111a083a08ce35df57ddfd27bdee5389d77df78573ef53aea491413a7deabb1bf5f964eded2c042ed989dd477d7f5e4bb93eeee9e6a58f0cd63964d346d7a8520cfcfe0f3c09f698c4a14ff87d3f3990bb9f3fb98b7d1d2cf41ebddfb22702fb1f05c5d9489ef7d4fde7ed91d38e2f968a40b759de93ac1b376e643dcfb89198afba6c86f51f1708812a81df78ccd2e2820955d1f5d83dcc0399fbedde46ea361064eeb706c42041b1fba8fb3b42e67ea31d95a961d0486e94c70a86e90e931da63a4c29605a82890e9317d31c26394c4ae0f9225f4fa23060b0080632c56182c3940413124c5d4c28603a024f90c9083cbf99de309d80c90d531b262e26364c4530ad615283e7336de1f94c69f07c2622f07c262d3c9f69083c9f098d11c824840c9029881920d319fc59003299c1235881187e0c18165821aa01401fe9886543265829562e85b8fd3cef3be8ec3d54eec2f273f71e963fb2ff7caf7f43a8eca1109b3991829936fc8d0d7bf8dfe948607cb7a97cbbfaed136ef56c52d9cbcd08971a7e8c68d096b87ce9e852443fc135a9f202665a51d3f5856bc6f9c02f3d49e9534e9864ffd29ff8957f897de9655c8b871e5c8d7be527f097ae874a4991ddf31f2b408e6543f698fbd32e1ae74b5a27fb37fdba939dea99ca424f5a7c59a5545969e17259b5d4acec5fb53c69e8fdab1ad997f54df552a2d689729184e84bdbc40995550ecaa59592dd5e657f8be549b3f7b7658abeb44164b75ad9df7279d937d9bfdcdd3dcaea2afbf7c44355e55cde35e51e25758555f1d4afecdfa5adca6ead32b8a14811445878a10424c8d27665cfa2820f48bc98d1938709b2b45ed9b1ca64a3fce26730a717f35ff47c219637cc572eca454f04732a9abd0b98d38cc84b267a19cc89e87e794565173f04737221db0a6342967d0b9893cccb432f04731a6ac125b7f82098530ba1670173120ada0243420e7a209853d00dca2cfe07e6c40288072132d0639813d0cffbc09c7eea98310f3064fc319813be58d9e76130279fd8b79c1c7b10e61483fd077382555a2ec10c825faa32e8254d06df833981f8fb0ee6f4adc91e9decfd8539795df71ccca9dbcab74b91dc16e6c4e100e48d8b97cdfeedba44aef56e5379be982ea2f0c559b9fb6f51159becfef8005555412c59b3030a469038a441862853286162cd10a4b70c88ec2e042ec7d1e72a8c2cd38f5d2a5754b07bd76c85c9eecfe303107eb8bb8330a7aa23574fba71767092e97f30278a8bc058e1154d59a21bc01534b7280a17a1eccf2d6dd9120351f6df8aa8ecdd32ea40e68614d9bf166131d2d2831b1df0006c98a929624b4b0dd9df3109594c9825a0b195431e174a77c62ca7f495bd4efd764295aee8529413abfd4101ae4f7812cdc72f4fbae1e313575aaa75562ae585590b98480ffe41016e714a71f55d8f2fd1257a54a9915b69935cbb50b694a9156edab284c7a388e8e0f206ecd223985315a22770d406c25802f72832c9260f8f32a894d6255addcbeb7852798336f1a4d28dcc239da3045dc353299d4eead75a2b8d7603bbedf290f8eedffb5da3e52b94effcfb8ee565b4b852bb935075bfe4eb5612b8f76377680b2e65190430fce1e3fd1b4470908f4d3960eeaf57e53b6f90042e10c2e7c39366e043f910faa02f9b0b8414f2bdde42bed7a3e47b7f0a8951f97e90f89f07897dbd31b14ad0836137d2b492953748fc6f84d17c2655d36e62d580ddc8fdfbf3cb93e8dffaf73dcaa564548902f3e8fe95e12fffe7cb1148962f8b2f973205e6fda06721963b841e482c935afc4f733d16cb19b96cae98587614f98262d977e40c796239ce6821d26a088949e58efb458feefbfd26af51c47dbff76fdc7b450d543c3dc072996c6f2cf9e84934a4ced1b5a6ae396d9a0137d19ae3862719d1255c1e271c9eaeb5c8dc539fe73e055a42e62c67b98d7b9f90871f715fc3ca3987c7cb476e684b0da714f73788e00d7cfc9a7ac04d8fdc8b03614d3d6016fff3e5d4e266d5e781be01183f90d8831e718fc5490216a28f38bf32f70eabef493c898fdc77e6569847dce3d8974bd957983e1f13cb1df83fb14cfa794f2c6be4d2a7be13cb19572cfd8a8c0a762840e38c1f5a0dafa4a9e42356edf0a2475d3e72ef717ce4de457fe3e30d2470d965de644e96fbbbe6a346e2c646e29e88093ca5b82f52c9257ac4c5f247419fa24a589c5357c8bdaad0e811f74453dcfbd4d4cadc7fe023f7dc7f1684b104f6e951a4924d8fc2a329c5c4e45e8d35bde811f75a53cb93b81ad012f388cbdd48d6e93412f7b32606ffa41389cc051182f3f75e8fffd1b5fadcb5402bd112fa887bce8b4e0b99fbb2f344c91c47ab32c7fd177a0a1a897b2f743a6d83fb2e74af46e2fe865ec747cef1d023eeb96fcabd8b25a66279392ad5485770e95399e3a63ca9893b712adb85a550a631b8ec0a7c031e1f78d039dacf645a41d7bae9e4fada68d28af2fca207c572fefc713e96d1f0b5d198279d755a3b77706973e5073352477c214bfb53b497cb1ab07fc1bf5fef571febbd5cbe5fd7f4d8b9a4490bb8214d8f9d3bb1bcdffd7743d0c73ab9dcb99c7fdfab8f539524de4f04a8c4f1b167ed07b80933e8fa95567f2240a58e8f5de2f6d97509c241acceaa28028dbd1178daf09fa1376df8d7b8014381424765d5722e9b39683e5a7b6f77853971f665968e33fbed485c9c09bc7d394e5807dbcb1e0361ce84995be6623cfb520dca419e44bfd65a6bad33e0f941321f67f4bba8ca98c04d4519145394eae88dc09ddbf799637b7a548f1aa9fe4741ba3d8773c533c72696505c383aad52a51e6b5f8c6bd6461b7de4709480b79f3173044a4d8f3aada66efb7ff7a8573b30b028edbbf82fb7fdf4c2a74778d62c44584d6f877fe89c7f4536a435a3b6b8b104decfeb3eafbb5540d0dd9d4e9ae7d585ea30a76e13a295c68d251d3ee3cbb047956830f08389e5053fd1bb8acfd37c6e016a5789bd065c31dab6d92ad268b4aed168768a7abdc062c68c1940b4da2a041640125ca1c460f3be8e8c8368805b6822ad0787b1560f2d2dad1e3e564feaa1d557333e590e006090df123550f6babeec0d56636dd04a4d03e8daf6dd5d6e7697f36d76ade9e95f6ea397dbaa9d7e2fc6b2effad148febed5f5a36b3fbaeb07a78477ed147d7c7c66d68ab1469a5debdbf7d67a04b7595a695091d10d1dbff9d329410dde2cd639e9cc98311bc603d68c195836b6d2ffb5bfd9fa1fc58cab1db6e8a0254b0e58acbca23a236bb005cf1908d670b87283151b6aa0a1aa8ad04f0b2a433eb2da949a94da0c35196a515e74306a54b5186a506a30d49ed45ea835176a2d7c33626023f904bbd679fb419c75bed9e327cf998e1cd2298af927dff2270be520350359ca1be7ee0ef67091bbcefb3e1016037d6045411877f70da0d0661979f6c3472816e00c671e88e5acc947281d41e00cbdfc09b5e864181c9ad17c94b93b0665e00c73973f1741dde025a2feeebee4ee4d7f7e73ce393fcf990d026f1138c39abf17305a14e231bafbc119defc85b393753706457fb7595d386518ac009c61e90e76f9e6be9f918c20330e3c67eceeb74ea8ea4558be227166d08fd164723f0cad1646f0fc0bc82823032b35ea0aaa0665686868e2c64368cf9253ffd370c3f7b9095e90e6458b010ae981d1f58b4c43538bbe9e814d046b17b10e0293aa0c0f61f0a76f0865201f3cbafa6962eef7b1d65aede089552935f291c5fbac55214c4333655937e6e25618d59af568a47e1a34be6af3ad49e0bdf4c87bd11d8cbe31c06e219ee96ba069e5ea16b615c1eeeea6d1a3fe4a695e9366d44d438a826b123502315865cc19a0901e1a1a3c7ba34735448a620107537c5f7b92063ab0944b1eb9bf45204b65d9a3e91137d3d1489c73f4fecc03cf734c6e3179c6818cdc3de4bf6149bfbcd45a2b247b13f5b00c02527e99d66afb02200773e2c01b7e17bc6119cb9472e205bcb22b9b03cfdd484079e6192db7c81f08c2604ebdb968f1d3dd3220c7ce02838de46517cb590f1abedea4e5acb208023d2c855a801e96b10cfb82bca1ee2eeaee202c7341342b82e1a26ff86889fc878f62238533b7b97a697359ce9a7c2c023d2cbfdc61d9c18011e382978558bcc008ec62cc683ed65a6badf5c7db34d63ec242b10223191678f855e06f64549f31fa377905300e6c76b147adb52e39cda98b341aa9cb59106841aef49bfc36d296ab580191d10c194133400b661c5d9bdd0826c3c3b2e436ffef488601e89e3f1aa0875f8d2ebbd8dddddd17801e667917d0e8d18471810c5f007618f8db6ddb401bb6973b0fb92d7f3490400fcb9bd5e327cfec36fb9733366b1f67b6b5d68a6badb7d6a0350655e69c73ced9f997d21830d3fdde7befbd2dc613b79f1b092d4cd072b5c9c780e93193d66ddbb66dcbdab2b2a0c270627fc38664c0f49bbcc99f789f87d57f665801dc48d573ed80db3102e9cba8f8d348dd036d00d63dd879e7f7760eebb1fe0f07b283b05c3d90fd4121b6162100246db04c16c2b57556f1c08f867773766ddf050632fd691f04dbac5342547cc1b84254db2871bb6a696cdeed3cb176978b519d6a19ea3c4bab3b9d67bc6f6bd3e6a3b4b37613b7eff2566d6da4cde68dd2c738cc9632e93ccb716d7698694329a5f727f793b322b53d76d972b591ec5baeccfcae916abd8d54bb11ecd402fad9b86a37ee5e8ac7e36ee78917d6a3b5a0f540edac1592e94f1262b77a5fe77dddadd65241d1cfeba8a8cd73ac5435b4f9e601b5ac156b1f55305721f5521f81d7b1702ffd2b34ca514d126a8fb58e402b908dab76e3c46c5cb51b77efbd62e5b61e7fda276ddac8dac8e8f4e10bd8791f488577efcfed6777efcfede7c74daacaa5d6a466821a935a0ab5a9da921a0a3525b524b513e6a4b386a26a6b26d44aa849d54a5043523b5233522b52235223a1167585157bf45441c5145f524401c5134e3491074f95e56a0110a56ddb46273f45a75414ed00dd36a5ec5f237c7d7d7d7d7d7d8df0f5f5f5f5f5f5b5893dc2901945fdad8c52fe89b72082b1a2504a29ed166ffebccec8fd17e06427e8fe01b452f5ffb81f0366cc74077950a5a5251aadb338dfc264eb418bc9f6da3a4485e9d3aee782e864dceafdd0d9b4ce4c7d528e724ea918615aab206fb77bb0fe389d3f1c7028a7faeeb452df9cda3a25e67a77507925957948ab57f7e1b9fb3464bc68a1dc0f43ea237f1c38003d4c1a34bcfbe1c00fc9d9b925c6a5474255d43d30664493ba9005d5a07a7f4ae15919fd7eb695d1cf7a31a89921adda6269bcd1b4ba535be37c5e9daa0f102ec0e3831ee0770e006090fbbd8256c235ce470f100c7dd41eb5d268349ae779dee7cdbc55db5deaf7f6d8c25c29149e6bf57537dd91e881bcec0e86376c5bf17b0ddc609a92925680c6ca54a49446691f8d2a759ddba7f569cf396bcca3e1cc379cd5e61ab3b66a592358d4bc563ae7b6bdfb7b9ed99d7a7533403f176fde77679db62b0196fb346dd094528aefcc5d57ee5aceb376845cedb5268871d4ab85298df4e83af6beb491fb919c46d7ea1bcdc143a7bb4dee4f40f7f878ec9947bae6b559ecea49b7fa78c5e6b1c1387add065d6d9eb7f2a0e3b4e14fb38474c0c71146292d0e5c903d9feea894ad975435ea14aa110000000063150000200c0c87c482a148164569c4a60f14800d6b923e745436150a43490ea330086218c8186308010400648c514851d10a00badb33f6415b41bcdb8dd500d7ef236ee238dabea1f9e056ad9de9ab4dcdd34704717d0060f8659b906c85f42f22f1824c9cd8f6e72b4e09ce47b2c721a784a458911b83db15fbd1f8fc445ea283bd730d21a820516ba0fe7ba0eddff515144cbf138d8d09d5c61c30df43adde7d3cb4eee73509e4b0cedb74efdc86ac4a2c8540b306824e06050eca84870f4a5a074cee2e6c4195279d7f6b7964134ecd424e30b6c6139e6ebe2d302769cca02946c89f67426a8718628f5a81138a2177acfe1966679f8338d7b7991a7101c249890ece5d7eddfbd795d92c234d9d83458e580be41a622e0df12f79fae22980fc779a173f5131d69e5b2f116b2f6868dd46924465290b88e92b9a98eeb8845dd64808188c57a6835d4b8203925da83c8cc77a7e911ba26824d20b355f0974992c2b30c5d4f331a7f2ab38363702ce576c0eebe1869bf57fe94c7e6dd628fd087b94935a1620bd878cea5533e4274d76de4ff6be28e09084dbc828dc4530735f390db814227d5937b0083d3bcad5b71908fe83d3ad26e2e4a81c1eeb12582aa71b64450057f842dbb017296db401595810e5af55b91d76c36c82bfe6cf3c95db38792f31a01ce82ffefd19d8a0d028afdd07b3376bd2540ea08d3eec5eb6a4e3fa0d2beac05c597518f85d047f57cb7a30f483af88446ab7f7f024e51264a209cc12dccf2e6670f1595fdb5ffaeb0bb0a3de1d6d042c42dc5f30cc46a5d326b6d4620158ebc7540b9bd058d1ad17782f3344af928af48087f2ba60fc2369e3b313fd8ca46817bcabba5210b38bf1d640a11fd2c448b903130338c414d101b3bf3098f3bfd2eab4c96bd87661ee8f644fdced6a238fb9b81681ff55fdfe38c21842e7d27e655afea803b03f5fded418ef820a413010b187666859b2a85914fbe24f5d9815dadf5f4dc1d12501fc01df43049026f8d69bd9d55b06e1231278d0f90cc1006937dc114ef7790ef8293444f28a157cefe31b33f0af4f5ea9bd53245c0d890519d6908057a4bb5901434a97b687d30526c5bc4888efd488b577e0cad8531e1ca150b27f07a9c9c4af202974fec6223d9768eeca5334cda603394b81770fb1d6529b9a762fdf7e622343f46f52a7b8c077f8800b68f9ca4c653b69d3aec6a4a44933d4c41219382d7ea4e831ac66fcbc658d213ea98ad008d0cea66171cd0fcda0cace04a923d61cead1b5728a64c8c737432686fa3c7da8e8f9ab6ecfb5eb30d9167887519bfc2e7ae3b1b5f9cbbeaf60da9c085a19417422a45b6aa454c774614a92b29341d16a26b2c0f409cd6f384db5ee7009b6be8c85f38eb644a0d6c6b0fb15f3f45e2548541529a90bee945d134728362a512c9e18154f77343e34cda253e32982c8497426b007fb0e696ec2c1d9a53b5499a9c4fdce4306408815c29d35d49a9794be547c888c54b8f66ef963fb4035057893beaa6b48219c9dbd4f42b7debd8bcffcfdc679374108c076d78035193531cc7a3d74aa95d3dae615d92ed4f3dfef15afc74da4099779331a976658d1c6f874582c94282e86c9e1ca0695f3b6bca6844cc4d511d5e576f32bf0a9d49376d40300c79298a1dac07a4e352f2af09e0d6f8fe7400736109b88f03b44e07f15c2f22a8ebb0a03e08c8c1e351e0cb5b4e976ac208bcb1beaaf46188dc5dd5901ca3030288384dbd9592056ba92685c003f7a232908b35783b467b9d604a1c599df4d025d9ea261465fb8057cf14831c2a09f50c015e825b5587ffdaf50727b2d02198660eebcf60b8fcab34d18e9b4da7bc4998bac545716da3b9035bc36ce4cc919cfb046343e8dfe7ad5f019fc9962ef6e5e04a1fc009a278197fa04d53e3fa98acd09a7c577ea9900f1fd1b8432f1f7e7195851c9a9d12e26a8c31be11c6ca593cf968f68b89dd80506e319f9f5a8180690f9358aeb951fc255beea9a4a6a8a6f9555047c914919f9d787701595ca8f67f8289c7168d22947e15410cd483cf4de11ffd9e59af573780e8126849b45093bb15991fdd4fc1ec1ff5e2ce731a054f7bd7ba6dd97d5940a8af04ce3cc76b42ae328cebf69fe17a02747e6fc96fae1e2e5c0f0daa81db3dee9c02ed9b1405776257da8dad0e854957934cb10083df5e8150c03459cf7a0c901a6cf9e4f530302158e35c20d6be922fcdc138e0748b0ba0d0fa118bc41598c21477008084dc87a4cf3aa751bdee89a2b29e10f167d407a4b204b2990d348213f42bde747c878e4e70acc72ceb176b4e4f4180a2b0280b60cc890824031c71d1244e947645933079658be24d43d4f4b151070244a33b0141a80b3e3935584da5dbb840e9a2be85a2716ab5439be436c87d3baec5291a56903a7eeb3e16411d27ee86b33c959ef0e017f874b104c870c4e33818ea033b81cab5f753eb32cc1c51508fafa475c98bd8f270a966504529e3a7e2970023e628aafb9924574c62d8cf162fc29e70afd40cc11fa0ebd002e36b6ce083845b14449c050143da785940a98a169e424b5d4767d1c5eae52449362b410dc7d90e3edd3874056fff61c7b6290eb869025f02b63c30ce9b8116efc0524faebb0b617ff233d0277337fa5d96de1b33187cf5c73fc26765bb6c6194045d0576236a34a56c520702a35482e1d3fdb04468eff77832ae19db8a098528f099f051c68320c070c8c6ac28bc2bdef196f8f0d19768e57db496e69426dd28d01d61bcc5cdeef4b998fc7eed94a311c68aa19a386eebedfac2f8a2ccdcce524eecc170e65adee08e09eda9377c19f6d8fc423d0a8a2df70fcc34663fd0cda659a97180653b084a2f930f1b175aba79e61531a16bd46a53a45e64dedfe0f55dbeeec571752713e3c9789074d1fa85453009867a7492678eba7b0673d7e238743681dd6fc07bcb32eefc3b259f2b75c81fe5d8702ada077ae2fbc6432149a070b41dd28a96f705df97bf91c90553616bf52bf1593f520fd20d06844a148e1c3fd1caff4dd8346225af88e7b29156fbd9b8404824c89687fe1254abe6721ae03e232f2fcd4eb745b32c2ad3fa075eea3c506359de0f4b3cac706a0e046a5815c9b232b14c43fdbd2c4369409a24a0dd84d7578c056a366231da931fbf900ab704ede6da8791824394d1f73ff3edb8a3a7bc4cfe982f7461cbcd415ea4ed524f188d632217f8d37474f4b39f849cbdae5a6842b31c93ea9ee1afdbfd31a41b53a29ae389ba7dbbe861a0034dd28877a8e2b125f6310ce58c99873ea0188d4753222cfa59838394c66a73f7e335fd6f60791998f27c57356e6b409dfd5a53432a58958ecfc8978d16f57c692982ae64d3568e05229ae84e68e5a3d792f03feedb8e463ded8f2c20e57c8deab9c0f8802d617e71467521a5f36b67ca2e548e17342220d2afe3a6c54854a7aa5210e1c648215a1e8ebc0822d0231a1d34384e3b364a11c205aecbfcca0ef4259ad6c295c9abd9821c3b8d8a9467f487a2498f0edaacf834c65b6b480b5307916ce9a25a19cc4043eec7254d2f01963ff873b3890ab49fce61ed0c5869eb7c558db1052f9960640b3dc463e8dd2244728c324126495bae0ebaf73e708828de81f1e65a9a04126b4fde0ef098b1b0f8859610cc099a7cd479e843b24e0b12b55c70b7273a2a5a50867817580569209a670a9a31160291976c399f1da92d22a97efa488b4fd0e7c6519e1c84514d8387657b088e6a12a96481c599cb686b633b82bccae367a85794da2d0e48bd1c00a36f58a89c21b81087e39745dc09d2db50d063c5b877c782588cc969feea5d22af4c087cea693d0af8640442624153279ba661ded192d853b2d4f1fd913795a721343a086318c0179405a98a0251f3efbcd0f2f3ced4e040f64020881a7fda55567ec6b219a2cc3be4fd264ff561d7f1b3a9cb8b80af9b4d446c517aa65e727714ac7ada94260d262e3b982beedd707aaf1fd4a87803ea9deb8a109cc2b00ec0ff282589300bed360a8f76fc0c3c934f2f11efb14311d8528616cdca55e9d15194bcdc2b11462f52857eae45156b70c83c69dc1941cdffb5cfcdc8776be970621533d6989ff8375dda0e63d35b0e9172c0e5345f9bece7f4c88b940854d84ca30081f263f600cdf9b0d7f3a6600d00ace13f5a33748584287810490e16e97aee8427b9b6b6595875d8cfdb5815079c79603020e51d76b5003b63c22ae005eb2697cab613dc70f6a7c79b2795755325e087ea0d399f019a2e03112471fa3d085b8ccd3d404d6e50d6d1287383ce63632b29c6d38dae3d4549461473844b030513dcdd328410438ce0d03bf58ab19cbc6d49af0540e85923dc409c75163c81214638a4b41b12c197a47300cbc05a183533a54bb6d3f4f33d3eaf8c960748ceb2e6fb44228da826c0336f407357e11fc5fe21f0b600053bc5ebc988d70091fb78b850a617775e0f65bf23a803e44a8d20aa405012122512acea55f52a30c5d9828254b0e76ec51fe8b93c4ac96a5ec83435afd31f51f36762b3a481924e14bea352b6c7c1e611d4ca602af05bc4212ca27fe8cca1a1f07581c4029b66a4cb89880ac3755cef44484d3829e0a7739c9628e3cf4b90e9058efafa4497d18130a0fce72328a7ebf78969da13163b192397a611d43311319be578380b25601793b8a79a00b585606025dc73c62cb284963dfed198352967626d2045a37ed0f572ad969681d8fa9e63e2088eff6a69de8a8b9f99c758c6ce432eca959f8885f66b00072143b33456723cc147a0d885ba8c622468b84e1729c050f40d4f4d206e7a29fa3ca43d325ae583b0b857d90f2a71eb9135985dd43c47c0d02a29a67a2edc961e8579ff08a88d3237558df206d5d2cad79f86085caa08f211d79e352157a28665d731fe9778b2521fdf13acc08616e0dad1c22f2dfdbc50937b896b9521707c6ac31ab6a334bfd9e6877f140ab2b678b95b5ccfb500c700306509075d4534020126fd331ba88666d90739bc87ac35eb133bc9e19a4e5f57e5fc42dae3f0ba062973411f5560fd1849a2e33591d09e64c7c9d7f38f5a210c798615fa3005657cd66dec44982bdceb64b253e8fea73071d60e041b9d23842ea43549172e1bd90a736b8422ec4e5ebf544dc1d89b67258ab35f652583153d540da33567f393fbde163167eaa69d9c32d97c755d8c1e41da67f59805f13b72b6fb764f295f2ecf2391813180d1820e72e0f2f4eb5cc13a1bb1deb0efc7185bdc18af4a47d186c18e95c2ed4bb64fc0dcf94f0b418c2936a94322d6d503e30fc169799f3dcdec4699853ba9971813fb0fadc37a8ce39ab636027f5babc8cdd934ba9ffef58b04dfaebe6b5086dc883b2c4af4feae432db85085ed9c8dc4dc74a16bd4a2ccc265b43243376ee95ce906934d72ed079210de6a7b1528028055d408d2cb91ef2ae13a83cd336b2170ad08569bee58d213e2e31399d64d7bb8c99c2de590f5188d1f920c3d09bd8a7dbed3337c4376af957e6309bb784fd178a134f48c83671abb4d2c0aeb35a90860994d7bf6e9d3d8b5a30c9e7d4f0a3636f8c85750e9f63a7bd1a8ddc58fe4d7e10e952a2324286a68feb4ccee064a4b6a9bcb4ebd5783974616d5d3793bcf1ba2b6348915b7e4d7803e2bd94d74b4239bda918d2741aa9085d71559953448e19deb4c410d4f40a941695a1b3eb9a17d1471133072200844912505245a8d102180a09df1c5e4fd4cb17515929ef0dd23ae8600c91ded40bab8555949964c0558fe4b328e4beef046fa5edcbea878360fbceb316447121fcf2d06d953a82ca7c0ca2cb83cff1e5bab65e998975b4a46db6091d1e45ab4c1eb6e09941c13a827a286dd80ce918ebda2905b2a9f78e400add531bb65e7558676f0b419c25b4f012b642471e58ab6cb307621f3bb44c707a85e99a4bbff61aab74d63d7e4b94a98e6c3321df898702e306f20d78a649656eea4f5126b0a94d719714e32a7b14d4684ccab7e32c547e727407b6a2201360d960eb9714be444012a506cf6e3c29ac09dfadca44b3da4f585982e4ba5cafa1678a3ac5f32693fd84068cd7bef572342a62f78684d48f4f37719aef875cb2a7525b3f1db24b933f8bbceb9c2c61c376c2fbdb402e06bff41f6294b92a604260c72e3643b05e536ea48b9ae64cd8d2aa05d05e528142ce3fac20091a349092924b909db56560b932eb613b46472311a2339f3587e34df6b4cf95ed9600b185808ac897dd396029b1eca26b074133e79cfd29ff4ab47b186928722019b7f5287e31bd127c8cbd5bebbdac3a47015799057dc3c4f6abf1e3665f4bb26ce98d836c67dff12aba8442619e28d37bcbcac552c5a4bd170ae33e7159c1d27abdd4db271f36f323f77453b2bbc4d9c8099377c0fade6551ead222aacdb0b246db7473af40e3f2331b91ae3df6a675c578854e5da186bd0ff89df59720da881a4c8e808945746bc3979415e5420a7a7f648b0923ac9c462c401dca2b7ab49413e015c1d9e703f3d5e5db21f2044383817ba1d1b1815a51b9d002fecf1824b0f3960f78e9fdf4a043a4ee8b0488077781dac045236c419b202e92042d6df54552eba60b140df8bacdafc5092aa7cf01668359ad24c318dfc80ae6cdb536f49bb4e03996b927c8b82633815181e40dfe41eaad4806e1b918fadf04dac29d66cb60582b40bd4798e04990e25c43fd9cfeeeefab3782aa7b8a5b5e849172612fc01ac581a5ef5a72013bf6074349c5b562fde1e214b31e6a0eef9971d9d24bad5d5be3c9555da4c814a81623eb69bcb58326f1c57953d7af48061a2552120c8f2f9281c4d085428fc55b96043a8a2a02a8e95309688f9c0e0bf7cdcbac5513a28cc13e25675c3803324c9fc24ce55ef637eeba46e793c7d1c23d00f29b1ac35f1c07527756cc7ca88429af009ba97fa772085c02da4bacae1d8b25aff21537ebea25581ff067d27bbaad232e2ca778b53b08f7dd9ddcdc26c99fc7822748395ba2fc1b06c1b7b0f83a4709421d1bdb94d83c655fbb2fb23455e3e76b762728cb50fa084f8bd472e3fdeb8902e1f3c2105f2d7fb2342c2bc2a6ad2345ef1f3250d21a34f2fb21e33c3534bcd200b756124ccca3042f9ace34fb9831541a60bacffda7806795fe1dec01e0490b6c6c12befde29a691f9ba0a614466926dc859460d10c77df205857191909992ba91130fc1503caac1c101a621128900eac6332b44929f26d56a5243be1b096d21a545e31cc38135033f1a756f84d37a456989596d316983e5b375498bf1ad89b405d831f3c9081aed5de443a1e3c88011a20297d39c37aafce8740d8369745dfdb0ffe652ddb0943de30e826b6bd690126b40b229afc8aba0f9323e12a83b8fdec1b96141643860daff88dfed8d614a7130344e4ac97de1e07243e2889da5e7913471a6013a3e020d3caf4e03565b238c4f7a1235f798700f2a092e334558a8280f905cfa1d7865642e0a881a3ddbc9100e5422f45d96741b43d59e4489c5eab4556b2f333bd9ce3cb4aa440aa78aad6f23a64244c0272f94be6095e3bee10e7bbaa928ac485d7fbcfdd89bcd10c723d9d28912a14f8e4c4844e83ab47405c9d1d6cbe47c2ba8c9bfb2b5e0ace3736da5658c2855f22c5328702e9dae7eace2eb11c039a3bdb0388c693444c09d2854a3f76061a47f4c1003cd5fe6b01f3ce0d6188a72443a28978b77e5223bc54bed8bcc91a9549d9ff9bd88bd01428fab213bb1fa585c05190dfa40f7f7d66e783bf574f757a6195992e21999fa92ef8768721b498a10f350f94a64b03acbfe78083b05cc1115b970bab638c7d8f343c7b92c590fd5966f2ce0c542be7723136ee94a0e36578d6dc86336dd15c19bbe2b35cce196f196251a0e4e7ec6d734c40b631708d06e564a1e7a4440a257fb5644c9f5883cb5114ba256b320731e3d489991bb4407d2709fed2d640dbe41de06cb1db1cd90e6a951fa779c71b485265aa5410146d38f831db1527b5b557138a03236545cfc76b590aa35c2a379e28a5af83c31bb9c81e734a1dd3dba9c3d94f4549dc7e0eefbb5b50824e2586c64ba6b116924861ebc95860f24be76e8b5aed4afeaa819251352ed8a96d2902f77e4fe0933fa2f669d1ca54bd684cfd1798c3fe1838167efb44f5f887ed7b6ce184af514da19ed69c7d798332365b05c3d88a4129c1418fc3ed32007bf4da04e9eb7460009c7a10b6fc001c8646bfa874821002528d26d880f97bc0df8b7e66ffd5aa11245d9e442eedfb2e1e48ef8f4b7d48a35d2da77c170a9861c44b27684af4ea82f4584a98a31ff415c775dde831594f1c7f385d238d3e8429f3ab7e74ed17efb4c0da7ecb0e7597924ba9b9cfccc8fa6dca2dd478b8e91ee06b9a2752b08b874d90de91a5b141f451d166d331e8c30d0a9e78d778709e90c8dd8d8f857cc5b29a4a63c302b3352aa6475c8b101b8ddd321f57c3cbf6e6273f82488cb4bd0a47af5cd3a57eab831862aa54b12e2891709fb2acc5b09f567bc8cc4aa4a16aed1aaa71002972cf0018c765a8295b5a7d36dd30067ec4ed15c61f7b9282c76065b39de7e1649b35a19a2a9f5a9d0754f5ed23ca6c2740e8efdecfcfa0be1a8436819ca8153b6e8bd38d39407263f7dddbb02b885447b6eb7783ae5a42ac5b0e08c4b6c843f27dcf93802a41efa7df69899b5bee48ba0330a2b1bc095d04c82cc4a209b7dfd19205ea325be56f19e93f5dba4845d18aff5084774a183bd665e3beb978c937c253c2b6a3893280c653bbd0c6ba7859696cf7ce1d7113a472711eedae25ec246adb182581f488b9c1405224b94e1200256d9f29825b26824cc8eb4981daf9f12557bce398bf5501f5dd458df46bf6e4c98458a5e2c630c10765312610ba5c6581c9416e4f458969908a744f66c7a0cb7cfb10761b298b41b26c0c05dc1c4630ada888615baf509512bb3046885f5a96862b2eafd7f081d840596045d3a3831bf12a7279c4ae913a3c70510a698c0d295aa34156fae56b85b4f182aca0b10f15ca119aa5bb58dac9a0c0b8469041ff195e02bc671c40e3192bbfed106fc17afd3e00cbfd15c4cdae33945a6f96fc3f0a8ec0617123f55767b586b2fc9f9c232e32c95c97879d29093fab748d08a70520ede62ca285158229c87f30963ef9d88f869f32ab96d6890f44c376df7e4723fd92313fbb7351767dac8f74fb4097f6d67e72bb58c92add9bb531b503d7349fd69f1711543389f6b4675bb41ad8a38f45afa637dbaab5da0d49961550e8a9165087dea51be981b72cf25813499f7e267b718f794d20a912e46b2c28f1c7011d10561e8d6569d326b4327f90448814c2a3aef73af077ed3f69b405b54107b0ab4620ffc06b5e271c1f018c6bbfd0531acd29d4983302221dd6250cf9598ba7aba18dc4ae43058344eee8b3b02ec1cf9018f8343c4ffc7b58c128efad8c072fb8fe7a19840f4b860b1bcb580e122dbe5ca0e3e4951eb7f68c6d3c387801d45ff1ba050ebc1b0d779e9810707c4c818e5865759343b05ff00b84dfa6ec7d02bf44f1bbb128f1df71c18fbe9c97df474ba88d4e37fc029aea110c2e8013e60020fd1682bd1e7e1258c36dd85eca20edf434d66d8ed497ebf3068175880c6dca31bea15aa407d5a478a6029f00a8dbcbb4f53c6f04c6bee51148456298f6c1d7c2cbbe664dc0a7bf9f098403c2780b0b472322a9167ce497f78dcb67361ebeff3010ca817dc32e4f5ee8d2b7323539c260c6bbe84a173046a34e7bf037d66b11246283d0ebb3275278b3a54509dbf07ba3600a34a36aa141146f47f906a54f9fa9cebc8952649318278486604cea1d8a3466e4d306e0f7f344c6325215a368f6d8ad9d8a38dac6d633e23f4dd76d4976394eeef214833da79e68b0aee3442d9244bcb616f916954e59ef60e25e22f728a1332992b6895b8316d811d3f777d5a9f4c9362259ecf85c819fd1de269135e1344b81489bdb237c9ae722d2698cd724c0dbe138f103a16d96cfaee2516f47f9f8df86048ff425be1cd28f0f69265839eb1cddad6b94fbd1c41f2a5eb2aa4c6aab4c7aec3cce33c819ea5a96535d2fefd7c97a8312bd763d98d6f66193b3026730509c1f0d47112ac7a04e50ff03f9ee075b38a3ccc656a28feadcb79b745674cd50e587584c8f206b03e9d3f0c073e4e1bc1a12f01a944a6ba427526356359042a1515c3f8a151227bfeae0b7d63a50acb351d2a6cbe61ec0f7a93635d0f801bfa5f01308b90e64695de982085170a812a0b69c4466f97b92deae2212a7aed72e42ee4e5a27aac4c45a4cc64850fc7b8994101ba80977cd0e4c25b6454ad01f8be8b843f15c65859f4c23a6ef580f4b11a97d03c5247f0b8b216625727d3d5419df8997ea75245c69a66a751c5ecc8cb59c6f5fc99ecfc64c5b4d170dab90049a776dc838f3dec2f823fe9d5cc42ddf9354399390024b200d2c8138fdefc3581d9351b4aa872b8c01b49e3aa3e5cf1e353543ff3e5706d948986ab1d34025c0069b367d7cf4d7e874b735b1ee74a6bf9f51a5597460f2444b99547fa24d683e3cee4f81b616e23032f9f6e4460caa1d226ec7fd5c655ca774118aa47750cf173558281c5cc214921ef2b66a20fb69789617cc1d1411787a8093927302b1ae578a983b326c5c51612f38eadf7f114e9e9ac9ec45d3d53349daa66a908bccc34478c6c3985c6a464a1594f7cce51c5793f514711fbe9d90185ecbedc0d0438d43edd30bb53cc0bf60e3102e517f1923170af4b02728ac32d98f1d40616538042356102c8a36ec656388ad5d57f5c98d5ac6a7a6aca1d36f46d492630ad5c51c3e1c83586aaa6fa653c0dc67aca3cfb691d2bad0a3c74d96f8c048bafa40e932d6290b0be66c12f4aa622be87afd9ce9208623fc4a0d80a3c724e86ceeaa3c2225a5544ffaa26b672a83baa189f2cef065a808a05cb51539edc1c8892f213915a09253293f3955a0ca11b8eb855d5d3fa38d313187d4c66e9d0322f1a4bffcd472b921ed6837094e9586ed5618c98f867809408ee97ecbc3b0adec73810897084353a87e6837caf08afb3c48b03e5fad4d3b51aef146cc59e7dc585ab737b5b712d3003034d4816a4bfd6020530ddc2c4430ee3e1136b31d89a971a19f2776fb1feee8a47f58a6e66c86ee6bfa72037e9822569e37af9094546b5d0998d0c93a6837ef0daca1142000463d711d28b7593019f14912a2b1b22957469c933511ca44995706a0ffa2d1cc9221e56badf88ae39460b6aaf13267cd43db8e40c22755a87b5b034a88ce69226e6d512ef6e86e6aa370ca80bfc6343d4e1d87c0c1ce8772832475c1497e839982809ff19022fc4aaca2ca86f573a4e9517d44fb94deb3b3d7336377add288ad15a813836f29da496f109ef2b2995f10b288259fdda6f921b45b6f021d5047ea922f534567922d6205a74a96140b67a92ab25e2840e26554278f160612dfa00e9381e165849b09b33faedf53c646e81e111c3d0c64f009914530b97552f7c645aa5ee1659fc8673ab0912fc128aff79660b5ea1ca3bf7a4339e3f5bf937fde436ce5535797fef4ce5cd10007ad435d16f543a348d48aa2579b0871acce9ccb24c854f18ecfc1b4b559d978e63a14d25f45013cf302ca6a35a769d0c317881a6b40db7dd5a244c6254edce3a1ad9d84a5a188405566a2ef2873e37fbd7331769c59e345ddf3f18a3579566b093ec5c076f19271a418b483bf18f7f14ae6e02284e2621449fc158951df63a322609a2c951d84749c979f663e0af342c1c98dda1dc2ffbdc42bffcd7036329d4abbc42f6753bef6687f8145315295bb424fcf5b65fc89f305012d03804e481b4a30b2642c55b4b2e845050180a4902b113ccc408f43a25b7b99a47cd8b4a95741d8a173327cfa968ba0a19ebc333335039b5b38f369a1d08dca6d3eec72781442924829437b0a6018b8895cf6fa100e1546e945b326b0280373dee741123893073f635c75b1781715e16f206f25e86455aeacd4dd3be99f85aed426ad90d881fc40235e09b0863ed3d0f90a55aa2390fbf99b043189bdac4cb819382905f13829529565c69989088d6c999852485c8937bc42c87450339810097f26eed25125a9684bcaf06a50233d72d5fc1dbbb0fa35f5dd010b6a52e3c5704e9465552ace99d1654941a23234f681366533674afa3bd5f1eec7dfd2932ee84db9a19f0629170c9426d66a5540428b03ddba4681556652e74cd6d514e36922569512f8b8babf20642a3d380c1c97961df3a997fefbade5b147aa3e31f7740b46ab8984b91f5b545adb829f5cd6dac28d4fc2c900dcd51fcd44705e0904166e2fd18bc71e4859a1490b44f3d517de6eaea6fda737c36b17292b900682758f2e17fa1c027eaddbaebda10411be5a24457a6a823c210683f260ebcf113ce584ceec21b0493b4fe43e718352b4db75be02397f82f75bbb5540d640ab1371eac84985c38def65a4420e856b1fb859c67a0b0bec597ace6dc5c57a2936c34558b6e2cfa3e3739e8d4dfff09070315faf800031f63c4c38d0f594988437c52d7ba45ae001d60443af6b2048a6a3933a5d1f6cd57f41942196b6680d62d3fcea3e3e37beb1f354584a87898c26959641c00f2549256004a8d961a423cf5e78ba556f2b5ee857b611d4244a3e2eee524519d954a746d352c0f355e1776c91c112ec614ae03821dcf3c7d2f23e8455180e982b165cc274f709f31fc7cd02d5431a25b87ddc76abd990f986dc6e35c3ae21b133204f1fb5375089c15d1ac2a5c1d2894b4b885b973ea5cb379f8c6faf0cbe3d72a715ea293098e2763200cc2369c3ad74569dd0deecf55973f74e63764ba02b5513945146fa6d58a071346aff31e842488ff53bc34ce51fa8b3b683a47d9759242b8ce32cb81a573939167b66640712adc099132fcae260abae4ca0a2475ae72fd2c1c243a1c3019eed2549833992240370e1cfdb37b389f83d86e8574599aa7aa3aca62adb7b4e4425bb5a3a00212abcbfa9bc27c257c50c6718a12c79007953e526a9b2cba6c13930ef896bdb38798781493f56fc0f9534fcd411bd75c0491a241f023359609ccc124d733bcaaab523565b726df92be23a3f9151377c71d1f2089cf6af01fb4768e45baf84028c19d0e84a99404ab307fe71ae7f346661b72679bee7765f06d749c5bb8e78fe88f453195e9d33aa970f1592448348a45008e3025dba0988db265734f1d0947b12ec8073542ae3aae0d74fea0e2d64f463667d10e49b9946b46489ca3297a5b4cc2a0fa48b2e65773aa5a92c8f9f3ad35d697ef89ab1f1571a738a5882bcd3b5de19a42ddfab2fc25d28e32063996c51e468bf08c98717e7556afb9296f5f6ecd3eb139f914bc8f770b0d9d03fc92dff97f08893fb2ebb9c38a31d2a5113e55cfb136e89d3a6102088704b206b03082a481d52d242c2acf40b6707aab1ac7c3c2977e110675619fb48006c0a6e2bd281ecbcc2a7d84d48d66e23b681849ada2a4dda9c7b0ec69c0eb3d70dfbdbd5afb0baa472faaf16dfb6cb4ff14c7d81202d0f4bfc3244d30800b20b9b93a2985d8ed0d6ba0c7a00426e6d54b7c5ab0a14745470aec89db6b58887e6b37e6262feaf55001d668bd215bf33b937e9d68d64e49b5623df3716138ba33a0dbfdd03b404c17c45893c03879ff2974715416cd3f613d1e11070f7600f64b8898c9916f8abcd82653309ea6ff70aff124398319a7546668be4b9af994006b8ed2e02b3b28fe980a57b000fef55dddef26d1a184ff7b1090169f1feb6b7a53224898e341406be08607fd3bcf901291c0c0ca0340c026cff383397325b69db04ce9bd30665f726d3f265557120cf2c89123b443a2af27d892b387003e3e59b6488c7376d5d240f8243acb43f0af9482e08666bdc000b3d31b9ebb0e35e6d1689b365e9ad59630e851c652ae29500fe44da8ac6bc83588a3b06f3f36472bed7797ba21e171e6b39ee09945fe2c2b7809741f8d3364ae33c990ff79641687378418d2d2bb9a61c3edc44b9a1a7c9a1dbd91878b9679a430480c6e9654ebeeabed6cfd1c9d309c77b425d826f6d77e156e5aea7528bb7b4268d51000b40c351d2c4f3f1723abf6ed4e3acf995f9b5d336c9a1a869491240b11a02352cd168597c01c7cb5a74936d8c6337dc7c95fa783dddde2824c1f401acd04c1ee80bfb23caa4758ee63f1ede0290ead013105cf4a4f85468ef91a8dfcc92afa161581ed9c9d4479f4c3c3863b2e4fece1aaf09f8e0b0b3765b0dbdfd34a5cd444e75347d39921d60775c0a6089f8dd31a96438b45f2e5c9a2f443ad315b15fbbcc5028af75f1519e30dac1121fb9ac8f44711973e980a8d4eed7741645b3468213c0c4e3e26247006c4dcaea5dd87994d96aaafe911fe8528f20137db09d9f7c5348b5807ae262009e6b397bab5fe5995ce475492213d716a94372ad31ef67d5e32e25c1ae838644c0c708066165b5c8fc9040cae991c63e7a337618eee3565fc517116918430ea51ef715d98bb0e4f3276111f321f6ef8d31e5bb95a43652f3711725148fbfc4258ab671aa46c765c741fd80f3a06f952a81fd1b5b899f932bfc9afbf23cc046937f819e31cf0ff143aeb1a9325046092adad6c1f027a8758aa9ee13c7e287b037091dc74f9e7e06664ec6440988b10900ed26ac4ef7e036c45ac85e13c8dba7e16110527d8340db7547d4f80b06018fa98a2c99767f15f266b5b1c9a4085680117edb3666f18b9cec75a7e731ddf9a0c996c062bbae0b39e52efae80ac4ab7b1f9e33575821408074137f9e44b6b30e0e6f6e797467bb3fa3c52970e8ecc588259e9b1c185347280cfa3638d0e73bae92a079dd7f224ee595442ad1467fc21e3cb9f99832e76393ef630d4391e14fdc31fc93779e0304de0457815422a300d9030e100f4cc4a18205cc7e1f7290a0a86685171630a193f8bc96a751289f143e408ed08ed516141a7b7bc1d944de2de6ab5dfa7fe297056123066d63484a80363557427dc9b7d340f0522c8e9d5722b344085e7fc91f5d7a36be8370e4bcc56d366c5e1b56f8770de03ab8f3785cbc7c538c6c7c71a8a011061cae412a84914055707f4f2a5a4060a7b264d3a6f7f602b34439e4d033580d356f8b3a2b68c8d770e4698de2eb2b4c1e24d998b130a107be22c1cbf9a30707b052f667634e214ebcc5ff1a1862382bee937f1d1cd98e5c452e29f5d4a8e9e9820fb92cd886b6d663af42f42d64e7aab99e72ccaaf0635dca0ea434f441fb597c34013c6960da9fc97dc0982c9434d9c2c7076d8d9d37ef9c46f2510d3409cb0cd9790ce172f8e106728d66a1265ddc3c4be28fca22ca2d433166b2cd00bc250db2490fb4939c76aa501509ee27739931fa3c3abe1a55261d50d8c618ce0414f2d0704ba4b402b6f6e56e140a49da9c90c7d51a644ad9fe875f5039696635c55a76c741f0bdd7f5a6ba571dcd34076f0ce573e2b8e15f25426b348b990bf6a7509b8e6ae2fcab756498cc14e77f7654ab97235d9d899ac582e724ef80bb29686aa951a8a13232dfea5a87d89034936433ed3c93bdb1ded3f87356fb7f5a1c2d58d0092c85d7ad59e8f4e49185e72456206f018302e89143846d5dee7cf6e8619bc368a99218034ede8d07d587e22427d30720b188a17ba2bf5d46662e15a718d6a5afc1d332a70be410b9459e7e393c9b9804e99beb40c7329bcef63602862cd20d599d7e16bbb76958307d7ce117b3257d52a9da223002d1535b4e7b70ede9b1e74dbb20d719b245537b4a4db90f4b26d3cf363bc81d26c8c6d525ee291d19cc632f943c3a65c6143f13d21bb950228fefc223c392ef418ffda1e502c612c721469ced1ab730a280b75e43cc7155f9e9711f2a25d14f534f136108ad7338316eb12aa3233de53cb16b617af41dd938b8484737f6e909a4a4016ee82536dae9ef5c5b74d6f83847875f54f54ff61bf38a4eba9334d7bbea01b8cdca7e6fdc19b18e2212906759acc5ceabb269132e0c91c8d0f8df336df6f77c8c4a5c2f3336c364fec236cebe09a524b3ca332fd1919c7ad2ca658d04b9510e968f22541806aafe76c631a223012382cbd908b0ba94cd6523071ce2fa42282ce0e02afb3c71cfb77003df999709b8188a4a92e9d3e40340ae187028ffdf15f41c0ec1edd4f96c503e445dfa123980e52f26f8ef9a40fcc2e396d2a7ac00af6ec2ce006efe6a60af85ac7c7b6aab4e90c4c062b6f7a4c3b9ea38c04126b9be065600de2eadf31b9327a01def00d54d31d1c4ebc6a6d48889802db9ddfb5ab925652114a051009df1986b83d6cc11feb348176159489411bed29b9f3a52c8e16364b521f4acc3cba2aad724f1b2be58b571655a0149a70b307560c99a84dda385d1152661a44ba18fdd2a705e3f2b2cdbb82013153859029c9f6f417077c708d2b5033a8b12806d374e86791bf13466fb6e61512716b529d41f9a123e574a9e1806ba59fccabc43ec768e4b9a0c8f2be2960bdd1e0078a2233f088081791f9bd2ce6b11e8d3e40d2d8c7853fc6975b2e1e3070c5888148726483150a7f1a0f8c577a22f269d54153e64e2bd196f27007ac060d2b3fc0e81046cc19baf02b42557ceeecd02bd2ffc276a600afa97fb7f7934c4be8a5f295295aac34412a5c7cb9152e8f92655d6954010a63b2ac76d761fae97a95544a0f312666031d2c61d1596a0425b7832874ade37c470e16b47896978cb0e10e4fa0ceb5c5c7c5f50bc65339ce5e01f9956c4a68e994cf986a044ddb651bc5a572cf2310d4b43c5d2661be5574309b33f3cd22198ca7d8959b83369f0d72985156ca3c9f91bc11acd402a2d960479ddcb68a55229d294bd4f76dbd6cdc91200e76903c1154a7a1ee92245ec71064e9c724f169d7607a77487eec401a3c38e61062c7af15ed343aa3b4617dc718d9a98d01b0072120a773dc8ee49bc177e766802f3158295ac9d8bfc8c254f202a0b57bf7631fdf4b35e001ce0985534639b85834d7323aee44f7de0696043efb21e983c161a9aff578138432b8ff5d016d4f587d91a6f5bf29e8f8d165280cafbebc10a70d85d7adf0e61dee964f7cdb9b068bc243f1d9f513b26437eb5db1e4a86fa3c0abedc6359f413b7fd8d692c56e380078b383fead9c52a70f4c139aa3fbbb932c20e86f216cb98628ec8d892076561ed6c899ec63432dc46c917d098f94a63a7471f0430eb8a80a941d02b20997e6069ef48953cbd2ee814cb7cdaf3d380d70382f5e9833a63a8f5e6856aa65df1e98cc3ab2a603553cc64da13926f1ff45e8fdbb3ef75e55c86addc23b97bb1ed00c91439d4da8edb50f375e5d0f11a0455f43b3ad017065304a1090ea0d36aa34cb4fe8ec24263c6f36dfb6172dd96e43bfe729baf5fbe2724e7ceab4b504a32e1de60ebca2ea8c8d6fb4d24f355a5bcdbe2595b1e1e66401134cc1eb103cd5ce1508567cc3c5c5a5c4adcc00ca0a49cb4ba88b95536f477812cbf2c5dc0ec9c068a9f8d01d6617336be4a21b358b6f5ad32cbc33c0ca5918e8200b52d7c051ab00df3d83d99ef3e597be9eccb7a11b9c725a0e03c2d46bab682f6bd8bc87913567049451c29eb2e313930647882a0e7470efdefd14ebbf490e7cb9e31b5bc847ec6ddc08a67c28dff32a840db6ceb08ba12b66dcbfb47dd87c0703cbc170eaffbcb97331af757a39c15098c521756f6030c2994e598d8c3430067915700653998952d6f55872be2d17c3cbac08ea060705754c9b2ab5bc29fa134b9bd7931a2e4a47dc78853f08647a3307fbc48ba8174fdff0f0d8602af63ac48caf76b289cedcef2ebeb912d3b2089f5961904cf2c30b0332c59848d934cd9b3cc45041b464cc6fd8004f1869106ace06b0b63259052d386b2de1a53b0d1b5ad82085f98cb06a1b2c0f61e6c7580f6c90119f9d8c15080543ac45ffc8365e1b602a71c3ba96e6ccc2da7349d2b435cb18d2c76206bb828140fcaccd80f0eaf7bc0344e12b730deacf4b53a060ed3f2ca853ed4e5f9ed7a786b96473aeee04137006771bd9c33ffb1246d83b666673e1847f4ed45a7ead0744607eb280df3e868b58f301700d8a11fd68082d9368ca46bcf2c25ebaec74600903043b0fe654a6bdf5537abc4b94fd2b7e6ffa5e0140d52a8efb09a1a1f2d25b96782c04d9712f53c95147eb00cd91ac2144543764a525928497d026f28316e02c028b62cb5cfb8160d28e42f1d7cd176fb90279e027393fd551f59c98ef34cd88d4f35b43c4163cf211eb1524380b7255a3d1fae9460be142d81f69b2ee2cc45795128381c64b2d5fa0ed57dae19dc853e01d7303332472756525e7af5d67cdf318c7531b82aeac59c5f4efcf776798c00440ef318efd93cb297b7218d6ff833d0c6e4863066c8b5681834d11c904eb455b4a0e9c7becf22b85520976d45537a00a704366f08bbdeb6ade34b45c5606e6c295405798c181270293851881a386daa5ab98ff92fa9568faecea51d2d569b1a5bec5d1d46238f5433681814ca99bc5c2ba3f0a8e88d5e5929e26c38031b3fe07ae7ec48404424181984c9458c7e153a6866b62da184a6ec5cd2aa1d4f960b949e88929f447344f2883280f60f03ab18115cd007a03a601be18c75405017300f1c4c62c19c51577e9480fd7a3ed014f17785475bb0b2ecb02155d63f8997bc8bb31a1845939c56c7283981565ecb7ea5003fa891e95a75024879856d1b37374a938fcfe7c532abca991878b87c0d430943d42917f65a47c8dc28ddf6dd4c8c5a1020935e796768fc8e0cb3b5c0d10a5d1bbb03b8530cf2c9cf3b4e0ad7bd56e0a9d7800aa132325ffd3028c4ae5f3aef500ad1b1b27a8f6a82a9e560466195d3a4a9cbb2e50cfc7fc01dc45074e52294cb1dee48b6c12f9f483093f0048844ddf76ac38f57627b137e8ffa12e044fd8868693c8c888d5b67820a9c40662c837e26c64528b6151f7ff436d59e27da786eec6aa3fdb7274ef7c0d6d1b8b28e170ea7a4524475b425d565743b4cda3b8e49c7c3def98fbf4667a256541cb08d60b41833d1ef149341bfafd3ceff148f57562ed8b6b8fc06ea61a808c10dd00919fb9aeda928b88b86fd1c9b087bcf73aeba8b9c9a2a07e60c4021485fa69aa272f045d0d93be4d37f577ef5bff3629576f93b4bbbb2346a725a2e391582885ea0dd3dc0bb9511b500fc26fe2e917ae8125a13a0cc1db4137da57724ffa6be85c09292beccf2023a61a1b4c12e11d49c0b24d172060c397d6f1c0fd97e10d6262eac189bcb726b2fda5cddfe097472cf1182ab896fbf322599f6b308bcb5f89e482a96c2adeabdba2ed6867f519697ce1cf76720591e619c8cc6ee68aa9c0d3236e3840bf21df89da12c6e15a9550550aeaa3f5def36b24076b3191088c426369032a5d5a7db66a2a47755a4972eb423f07f403fc535ec9a167052dfa3b6bc1167077ebc00b0972948f7c48a98c4c37f0242a679749fc5884edf137a12202059f1bbc52188699a45eb42111688a8416afc2c22f4ed2b3a9671adbb89a14fa752d59a659f9f6fb53511dd0f3792ed00047a0e9d5839edb651404eb720a267bba603d5bbaa7c0fc1cfa735785a69dd53d104846e2449f3aae9b0b32d58eaa37a1ef907f434495e50967aeb5970524281fdb596b4cfda99049a05d873141b1da75a1fa95b3f3e7a1b95a4192e9dba02538eee603f4bc57d80efebf00247a378b00d3fadfec96b684c3857afa47ad9783ef1d51bf02b0c2c1e552b808c886e197acaffe32a24c8bab158e5d34090f3702530780e8089321b5f0944916de4ddd76fed48f33591f676523246c709b8aa0df52120a5cdfc827c4ce9ad38f62f5534e9f0e6318217b0de0658960873dc2caa31d0974763a7fba776d1466a9445810844237f5247b22f4e1045f3fcd195cde093fc3166424db3cdc6535b7ad39d1393111e8f5c1c09f67f501c2f5f92a597f9f1f54cbcb90338417cfc17be9b11357119c4b87ea2431747feea825963754d4e71e396188f2809783a21475e9370199490aebcfffaccb90452489e0c6502d513421faa93866bc0d3b5cb29fa48bc40e88ce80aeadc1ecf2728415be32d23a8c9d80c404a260cd5435185d6a46bd5d6788f888f26d77c0e2b58ee61bf502138cb92538409df8de0e68cee22018bf97a293fa855c830ff611cfd7fe9d169b1de1a8520bee360aa7bd966e0885e76126e406271456effb91086a7a9098ce3eca83e7e2f020dac6466988fd6544ec48bb6c0e7db7a1af51511487097cf5178907941eb84886ef8a85e8243f25ac1a23d561738b8c6293ef05aed96fcafee3b67e13bf817c8b4e7f8500b0d1e8275ec277eaedeb1eaf43515e7953acd028f31d452aa4ce3a1d14b2334cbf5f23c45b1a42e40b2d0439dc9bf32a9feef0530ed10d2cbb275fb4f9e5aaa4f98570df988b1578a4637921b92d2945482073ebd19d06071a5f7bc5e3764594ffe9a203d995ab57e95d608447e18c46a56a85f43864ef55142ccab0aaa07a140b6bb1ed78e3140087d42bf40cbb59e347d9375ae6b2892278717ca80ba4a479111018c5b33bff75f372993e967952cd60980e007d4bce9279bfdface09fc2708341c25fc5c603d009b75730ee3a19784050d5dbe872af33081139e13c7d14ae54414a07168d3a14be4338376d5818e9c2436490738a393849ec6ed05dc7d269adc2acfa0b193d238f7298fabb85d1c6ccbd07a4ea1e95abdeac116621167108e75e6fc4a8603077c0cb89732e912a28e20df79252223fbd8e77f247106dd20a505cf09592c23e3f0e74eca87a51a103be9b5e3d5d145db05e04ca60a6e0ad18274341a30282cf09926b95fe506de3375d7060251163114ff922b3a59775f512f470318b485da93daadda6b3fe158aa76db2b0524a8c25f6f834b58dea983e8313654b2000264582b575c68f2d0d93dd0f1c13532911ea615559d9c614a85574b309592da44964950fdb5d937a033c876b5fca86ff6003a0c6a03532531009b05019547ffe48403552eb9c2816cebad23c3f705483544ecd068e2ca837045d66386e58df8c48201f1368375272ffecc5753b7d64360350622393e51636031bd2100878b976975a2a38566f52bb5f66df73ea2b820e108df1bba00fc32594e49186d212c4b945020c29e1ed1e0c02b79d50f50835143a683d42ab26ebd7f775d6970a1713a8bbbaac6c27cf45aff02272d77f7fd98b682371bce7246d8f5ba04667c8ad44bea7c764998587386ac688e89e9c1508f7a3b33a8ef46526c61588ed45d80febd2224f757403e76eb126b73599b78be2bbeb143edeeb732b6a5656ecb867fb6649a83afd6ac41869f5de68ae89f6ad3b282c1f308996b11770b7af65585413bdd5931a95ac2eb45db0e239a056206c50effdd72f84a85c708600833c25c402abb9b4941a5e46a54691f03b8f7459406dccb5cc1616c5b4dccbe138215eb850d47cdd153e1c3080ec5a653f89865365adefd37220741c7c47dce48a3e3533fff8c344a78f1fb794f97a501512fd299f6d874caadf86645f847681592c7024f7cc15e2d645037bde537d4e36581124c2096eb3dd840dfb8d00dc6a502685bca96dd0a48a0e79384ea1bfb7b410265f44f8a00614e9b112e0844908427680159240d33752e69de9dc2dd17722240ea0dcd127cdfc490a15023d9be7b52b97ffe2cf35c3c18e6941d5ef7eecf6ad9bd8a93a2f8937fc2d18f5d6b71fe2a4551b66878012e2a82f411185a641f0be11f8680ce09ed4947b497e44f1cd7a4c9894995cb705e3274955397fa65d842e769697b5650e6c3eb2fb1e75c835de1f2bb4013cbdf6ca0e010665a3790b4456fe284da350812f2568018711bb1a93ff93e31bb4a950c8c4def8b16155b6b836125ee1c8664ea47602d028065d9777ef4a9232a7681c67b27b520c0660593284630d132d69145c9a2195149503d5b29d765e4620b006f3b4da155d16bd1d283fbb7a71ba0a47870fa262a6283ae72611584a35fe3028e301c2a81e2ac6d0d0d5cba6a2eeae7c1ac231cf34f376661e342a20523a1f6c9960c8c8c3204b2cbf6d2ad1542c73b68dac1ee2722742e06e87467a9e911e5dac93bcb11fb4a9a3eef89c302dd27ad87541a5a09f5dd8418292da26069c52edc9a2ee095deba8189591d2cabc5596f142629d434f2fb32c2e0317c69906c37fc733b9a3707defcd5c7696f9ea1b87f76bf3e89902b2fd9fd8f58885e02c58fc4beebeaa7953ba3544c63ddc29bd136d7fe2b178591bb1ffd0796c523200b21bbcdb58114fd70b40503232c3adac184cfeb295836f2220a0f32a3bd8c070116fef0386114c8e7718d2823813ed4239c41b8be0d964778475faeacaa8669921f37fe882ef428151a7fefc07e14a7ec518f705f2db44af451f5005ee05c824cca1f3386408a1b8a0acdac650c8dcd53e12732f29cae659575031475845d2f220ab4f7465b80024114b6454ebe4edb6579c5e54bc6c90edad66bed01ce07d6eb85a41427abca64195f262354d09d1f0a2fe5c96c59cca50b36c9d92938d371d4480d5be3c77d55bbdba173780b25d99f22c88f30033e57a02be384112874776c04de2399eced7bf90541d507b85669290d5449fbff547d365e77cd72280b9cb81ffa43abc4eb644ad4d40a1af902bf312be7e3bc764a01095b1a84263de11517b9a4fe48f7e8cacc6a1e155611f7f8797208f5683b8e3a3916ee8934b193042dd5e4c5b9707f5f555c21679400263d9ec7053be6af37aa5a4b661fac7b93317108dfb7d2e1671a5720b77b6e60de607c4e675369df2efeeb266ad29778c349c43f9f4f84aef1a13f7d1b97b71623a5da04baf80caf181cd524964b3e632b2a8d44eb5fbdb61faa407530d108e2b00040814128417f5e0d632f37797a5c37f47a74865967de7e9792ed6d661908e66ec50f5a367c48b526935c0d9c3997606637db51020555ce6c4baf428f4b4bf1e9425d080958c310b5925e501bb0e14a0931c4ad047e548af3217487c0cdc8c4d1061975982d3d8035853bcb071f5cb27a0a9892927835ced2cb393d9600fb106363d52ca4bcd8464f1dc2f6e29d8c6c00b3c8100d7717ea16bad8c30d91f9348d0b985bdeebf85089a65433e7de73f52cd10b2c6314f007bb03b51889b8bf54a0cb306d86531683e69a28a5104972b2975df67e0d328c8d9315f1c09aee3983765171c8a382d0eb3125bbde8a82a5d78f34ed6618d16667478a113217e4a25c0743dbdb3199f1f93d6de178d2369f329e473410d2ec7cba083d340ce0dfcf1babd292d3e458abf2a5ae6c7e17503b5795087967ba311b4886914d6ecd93abf2956b2e974b797b35a847aa467cb0c03523fbd4e15aee8834f1cd327338eb5f8e05ed918bb313b0693c0e593beceb6a616ed46074fc58baab840be430f89ef0265d34f7a1d6d51327cb39c2a7291d8100dd5d70dec1137dd8cd4b2e7fb66a9349647b09515826558ec2695db2952e850cb1e728e9167d47859bef837f9ec08397ab61638c1bd75999ac3291b6c0273068433ee6f0c80f8c4665f706294569181d2187511b23629ef9acb12036a4fb5c94d49874d744b3fbacd2df364bb91a00f8749e8e1d097276e527c7a39632b28bbc8fcb07a09fa033d2df40ed0646c5cba6f01cacb00f613241dc0414e3ca3670ddac4cc15f470bf44df508a4128fc055afd96b685b73c9c68245b4dd72fe9fc11c419086706cf9ac0863672c7fbcb03a3f7e03095673b51123746a4f5f3e5cd0fb795df56fa8ca30fcb5ce06e491e544da6f686bd511cd8521de4390d5a25498bb31133b21640940af679501748dbdba231f23e599b0fff275d08cd6da76069241ca0652d81f410e8cf7062ed24754114aa9ac89738986b53e4072c61960028b7d1640c2f189788c4a1819ff29737e3966466231d73050f6e6e96e2884398d9ec410bc3808ec934927dc490e90ebe4a5a344cc28a2a21f647014294c12d7ae18706b573e33c1940738a69c3a67a0b0b3ab54da36a2ed87592c27cfeccb1f9825d6cc3f6f0fae1403440cc1acc507a46ce6ea09d4be529587fc08b191c475edd07f49179f34631e3d2869096cf615ca862d0a342fcf7398d6ee07738a494a938ec8a7f3ff709ad2c676d16f9273ffb39b728ee919bb8587b57754eb5b10f016b9bec33d8456aab9e2d00c586f344658899c211302f5383f98fca34cdb734c9a8b6faaa0ad086ce87338ea025f059ea721f03eff9bb4d2c242f898679723b6b89521f0ef97e3ee5ff2cce00c9cd52c19a7f919572ad23006c121f0a58132cb6b11216866193328bbf730f898e697c265bb1e72833607cd423bdfa634f2f8cd0abfc26585ced3ac8a19840e794a62cfdd2ce56afbd9e6661c7ca5e634e972c8f30b1ebeb83d8f2624644cfafc3227ef4a642e5f7433f9c27334c389ddbc20c9c242c929f2ca58ba731959d3ed5a1ad4385f7c41ecfc433f14523c93b8f32b10a6d3a34decd8a8caa2b37cf4a630544abc18ada3d2dd67c579597aa21eeb4dc73be047e2dc7857468a0b3c6cfdb4804bb13d516f4a518554448bf1a5ffd1bf0dd52f69f317b30a065a064163549f86ff841d62579bcee64478f8850b2cec589ef0e078d7314e15c895eb82620cc4d10bf7859004da910a4e02192c88bb61821417245979928b26f7cfac45921abdedea060b08860aeb269e85b49e10c6e13b87cd55216d6824068077f138e40459b1285321edf2c70dd30b18ded0bac9ec47ab6db6b8bc0a69210cd0ada77ac1d00cb952c653db3aae5c8ab2d9b5ede6b45e276ff6bddd13590013eed1603bd2000528d52e355aecc1917aab6e382d0269a8c16e3cf455031dfde70e6b6b7934848f190999d875a84c40e8531f30f94702072c201ad01dc745a2d7be62e35632c5e2e23b55978c0fd8b01157b099265ba0d8ae58c4e87336f7f6e0a349843e2cddb3f0b4d1c77b28ed1bed6b1a5c9ea1af3825ec77ee894d561c4c523f088eb82a41d472407390b3fb87958d890de4ba414013ff5fc150eca7981522dcd6659f31b730cb11216e27eea6cb0ea897fc9e192d7ad7dcd40564bcfa1479dada527cac05af369296fb021e9cfa4383ba7661f9c0be5a386afef4978e26daee8b9df5d8b8716aa8e9645eff1aa5dad156a6179dac2214b76652285347b6a30d980324e646a6c97020f0cfc524c5c86dc8fc9880b5b60c0260276f1d46dcf0460ccef67bee4306c11da5575c4bab151a4742dd23d03aa617faedee28b3e02a1a8744a26a79d05351d31d2dbd3b1dc6182d9443350dfc7a70ba419c924e3ab441b1e2f26219c40f19136f353f71dc12272c7a3e860fd184b6afc956770825355f9e243874181509cb0999dfb9b85e4198dfaa0ef427d739a45d79e8aea5e81d3194510962c1a2504d067848b9f2cc926e5311ca754d0a9c95231a7388e9fac77c6c01d2eb0c0227eed170e3f07d84ac3f9a70cd0fc544ecfbdfe6cd0980def515c566f365381e725f0ac195706cdc35bced7d120d2ca013a60c1413937e56bc6e8d3a4d0f66aad1c6a1d16e73dac5767dec9ce19f341d256e95d5846aa89177f270eef9772cda8603b030cdb0b50d113df0112af871948d497db825205ba6d4078789183b323c2099b09bc6dc02f8f8957517f2afd965c2a49cc67e187a00fe915239dce84283b171e18e8a89a8e9cb2bd664e95d308c03321c63a8f23b86db44395783b15cc4e21339feb443ddf11896eb93b27ed0127c99ea40754a29ce0e9ae148785da1912349135b43b83319e030a6fb83779f4cd4632bdef3385dcb227cf337751da95718025cc8d9337325c12845c1f9f8131a02c887403a6ae059889e21643ff1fc8d3a334f41fe918b1c3a5210e5c321f640b0d1fc0ebd7c94c3087dcfa8ec021980607ab1951ab4165215da2b17792d7b6c12c0d70f284033bd690fe97b19610953ae12182c4a5bb8f674086fdb71abc298d94467477e975fc030cab077b0970311907fd55465056da42d2c4b966e9aa38137928d0dc391b7f0f53ffd164af315c4e3439b1e5526cca5083ec08634126d03f2db315caa359cfa7bbc07e22c0e71e904bc0c03adc5e568d6e0857f6ef805dae69d5483a004b025e962efec9987127d3ad1eae44dbc20cc4ed55975fa8069fa14a71bf0555924515aee5248ae532cf79b32445f7530226684d53856cdebbce88af827912bdc7629e9afacfcb24e00f63f29002b733e3406f8044db2229bc426f60d05d92053f08eac503a06c1f57834c480d793e5c1917e14bda1b44be10fd255612a667235502b3268287316a2a5114431b65b11a6f473c2391aaedc8b924783447752793d4ee0ebd86759c02ed27c967240b0342d6f5680bd286cb5c691ac07c9a74f614a4730776ed0c01b7464983efadf87c34437e3803a93ab8e0899bbf5eefaf74044e617ac2f4221c3872695ec7fd9a25828b712b2ae3eccc24df2a3c149f61449c8b25f7f6dae9656ba5521bd9c1339871a856fbb1030cb2a2b161ea6ceda6341e95426a56fe9dfb1a0ecc41d6ba303d2c864805269f99c00d12b2907814bc17edf2dbf46f3b8e2d3a6a901f80bc72749c9959bc7a0a2e44a942c8e53a4f17b94ef31361cfd86f59ae40fb230c4a0e4fe9e86e7aba6482ce74aedb3f41a1c30d22cc0538d02b570f4f5d5f7ba0a75de05e38ab0873cccb1b2c54b6011b9e4ef33295e1ee935775337e9b8ad4a5989ae5cdc44b3db118888ef4c5732ac141dac928c8c2657859d188f63916558235b8a05667c9622963093cd7aea482cc6483fd73efb9187a3bf8a5ae1281f328efbade0fddb95c83cf21fb226bc16be91f12bb2d2709fe1cf4ffe0a866b1a72d12834d52b54c6a7f1eddbbb4981268baa040a90ffe372b62c6fb9f74f274aea5815e13d7da4ddc06258339d4be886e1bc37693602f1a296360304f0f1cf7b5a7aaaad291dbc9a42f9b8e2e73d2de4081c166df9666a9a8b17a8c95e9dffc58c7894638a22c7029c8cc7316282c5bad57b3ed4a55a09199b0477388ab4a120dfa379b2f474f1e335837fd7518643a5667c4778cc23909c2d4ec45b59bde1d2991e527091521c1a4ff55d7fb4481da07fb44609dd0246e7f58fd3d54d080062de44ce33dc91a468ed372b1641febf4b2a3b8e7db8671780bd1086f604d365e66f0c9f8fb2f965aed0b9837223f9fd5e69321a03399a86c98d1cbd85fe490462a354c6dffcdec14bd177a38c6e6f7c49f3e8b855117b4abb21dcf52ed36c35e8124ad8994d1677348eabd07b836084a45779afb7a4c18e2d90d39a3764bc5162c239a480bdf171b8949797ccef665160211d530280aa24890d4bc5e56f05524133d8c618addc6e1b2107338d791c9492451a0931f357cd37798d755c8205bdb808a250defb51eed749ff7d2c8d5b93fd40eb71dba905e88866af1d41b1abde438b85a34b830c494991031d5763c2730f75617134676e79b9f92c2f44e534f25322e11a49913203c74bf719ffab9699458ace6202bd3dc2f16c8ead99f8f5566f7eaeb02b151793bdc6c9fba65246b627fd24ac8ac7a6d00a3be6c44d01beab1321e70373bb380855ec89f4a679a293d8319be64017ae340c1edae89624b574c4d5697f874453574878097120df200a6ac87401eebc96463c9166a13e488913f9152c1d1886724089d069fa6a4ca53deb6616891dd166265134a80c5216f1c1a6f26da1148f80a1b6e8b2c1bb684a1ea9e7128e098a55a85c6b147d2d0fb5c580b88f29496db2443219ab1c049fe05c988020ec3b8998e1220744b2de4ea069ad0862304e2bba2541aa76cfd01a475b5de560b3b3a38d80706a724bc1ce5503fb13fe00a02c57e1985e88f44d87bd1ce03a60b4dcd3eacefaf42e9329ccb2062b05c46f2938a80348a95bd02615127220114bcd376fab8c8438a92f91dedfe2a2c9f9534a1293b273c270d47ae69c4fa0791b72a1e9970f57200a507b2b936ff255a39b9f21ac72c7427f5a49645cf13f46828470511ebe06da372f201c7bb874c9271eed3b682abd688e7c1419c433411934a428fc755b3bf13733b191ea74d4012bcea36b8990f73b77a75279fe1f93dcbf029b24aec864edd68c08894a0553b71774da43aa6a07264a9219d0700058615271083867335f0302222f0766faace8e671c0b6347d0358c66ac281d6832781014dcf4a24ab4a40578e6472b1b909224b0b7f2264f403aac1d28f5a200eb39a0ef52ad6b7edef94d644e80a77656da101a6e208b8e2d96b1d117acb84c5c3187e637c4d0d50ae670a3bf75c8003350785abd111f90fa62f4a411bac6e45f95dc6621b7be98884eb310db590b677b72db7943225290355098108e708e175492a7d62985a56b3b2cc1b2670958e35ad2feebaa38cf1e68a7445988be4b0ea535aac1fd4403a50df6bfd9b2878a4b97ead2fe99c7d452ff971a1cb3474e1e7e7dfad7694817f64f913fc6125cff0d26943fd4e2607bcf513382a71cf76873844a47470fcd14873be3d0595640b1ea9990b5b8c0964fb20bf607369b1b6528bf56fc2c0e3acb1bcc0165caad205b906f54d183cb672addfead8a42db8d0b9059a39b953ffca9daa546ba58ecdd932e38ef991c7d1c9d768a50fc91f9eccbd13c91f9acccde7b8f7247f82c43997cc516fef217396fb0f9c600c067c02122d2673db73aae75c1e824b82bcc431e99815ea312d66c9efc59843c2a1b0c261922268a87afc49be6ee6e56c05b25833f86570c801fcac70d675c520128771bfe26631e00fffea471f7277f7eaf58f84590c18fff71c58bdeaeffb074581bfc797a38f02feef5158e1d0d000f8fb04ac5e55c42c2a7227997b77222fd74548590a0ee3fe729845a5ef2729e20b4517b799aa080c78f63d48396e42398c7b0cf692b9440f2e0cca59cf26948e4d28610b9500fb10f7dc09cebd739f82cb261013c6bd749a404c991379e118c20acf70fc317d0805993322737388cc893f7836f0894d992a0ce12b428f5ae49468917b1a3695167bbec0dd4c8d32b3e630ee555f5585f3c961dc731f576754e6385596efd46b903bdc53d06d903b9c7b60c2b8e71c88cc7d87e384ca9cca391fca2e749612e430eee537448a8fc3b8e7de6716756c6c2a997b0e8516b9e7bea35e7f22f741ed1f1952e64f248c7b8e4603010410b4b161cd5ae65e0e39aca70cee53e818f519268c7be944ee70dcff58e17ef4a1ccfd091debe7be48c7fcb947a163f4b9972f2ea48015aa09a344962679e4f1827340dd2bc220028b53e705cb1476090b96d50e38952513962adc0f58a8dc31588c68c012836d82753c7552708e2bb836f00d924a0bd6912553143f746a609c2c99a210ea8e308602411298541a495eaa24613941d212642401c11d25396901146b581b304d964c507061a76056964c507059a3ca19501cf1048a117862a0d0210d2896dc1d70eb8caf0996f9629fc0c25e9122892b494c5c71228c2b26a8625c9972c5485e1c954717b703907b3ddcba1809306ed06182da0089251c34a062ca0e12573c908197211d2448d0030c8b291a2051f444d46228032466f00006594c811d11070d3fbe208947ac61838f2f350c2e0f98d7c5d7c343fee3882f4e7a6c99e2e388293c106a71f43ae2891b40265a8f235030f4583c854718edc0c38a29e011506ad8c105ea8f68e2011d5740f1387223678b1d4765dc80e3a4a4e3a8cb4d97a89ca3299cd83015e11c41e1e242bb3942e249cd17219ba32088723419b98e78a081468ba59acb7354030dad8baf87ff7e8e379ecc484113e606992e4aad2d88584d4a334945d8cb910c1238acba10b14c50e483caa9089b8009946fcbd2ca05de15482aa819ba29689f1833a4b60c795e6ce0969c3a2a68b84d51a926a06c593c71247862675e9c2e08ea8c8bd17679749861b644c46444931baa1072c386d91451f73e3d993c3e3c3d3e5d38b36289a9882d6a9855a10475b1ab66c96445298f3f4217463f285df98189aef68309b210e2b600775932fdd083089e746bfce0a4b3e107a15593301c104c1e0e3ea8e093826db264f261884ec8871bba23b02a4b261f963cf5d086bd827964c9d443976f053da800861e8e544f78264ba61e3e60b9e02f4ba61e882e0db7c65c1e704e964c45b57b4391159d0830ce92a9c8cab604d764c95454821508708e2c998aa07c5a14d56069c0322ed890f0ca0c2e0edcca82db8265a2d8963057c5e3025f253ea623550a7818e2033c04d139e12d4b261e7e50d580bd2c9978b8010c1e9c20c00aed52f9a289a1b5917b264b26219498685042509ae7ac9e0ecfe76e96ca0409497a790eaa758ba62087f574ddc8a45e865c949ab61841ee44a0c5f9228fcfccf24eb9336beb6bcdc473b656aacf5bbd5a1daba5f0d43c3cff37210ef83a3aef3d25a5a02933eb9b72e725b6c8938373237bb5cd6b0155ee751e7e9dc78aad1919562b95f2419fd294ed5edf10fa2fb1b5bdbe210e56905ad84c0632d57ee7e31b627bd8cad2c13fbe21d5475d6da002f29dd0b2131a369f8354071edc0f62dd7720ed9e1e9dd7abd502c1fbf1fe5d2e8c83b85c184b1fb5171addbc73fb34683eda726f6b813c0e93f972d8e779f5507beff4e69d3c2c224e5151ae201e68d0a37b69efdbef56df108b51b82a6c89800030c2513a8bf4c8f33570f22007c94342b9335fc62342e2d27d8464eeabea1b52e7ec5940956d73d67782923cabf80a6a71ba4ccb2fa417f9b3bd04fa204b1e2ed08625ea1449e3c9895caab9735166f1e1d1d1913b60118f274e968010041eef953b15a435af9c6da625434f98a1d96030a70ed30619a68884438aa99dadbddc2ce2ae4532a70e790e39038f124c77d35bb630e529bf7c1941c266d7b9b3ec3cdf53dde4f938cc3303a30ef29c8f45f629a2c8fe40d2f53a3ccf4abdcfc880ac222e5b855f1822a11f85d01459c8f6f739cee6271d720616797a22e023a7c78e1bd26f8133a0cc06dea75dcd37a4baebf0c9f7757c029011420b0ef9e68e87e772f91db823cc79e150c7e971f3c366c3ad9c6f489d3e669d18f088ef51707aabc5b2016158acc1b9b171e1d450d59441a60432a3d3edb0745e1888284e178f8a034f7c17967f3b3addf3382e0a8ceac0eb3ce87a3eb81e5e4095ed33d87ab61e6a639bccf3f1745e2d8ffe77809ec97c343a3e1a1d3e30fe6874f8f0ba1f4f06692a85d8bca4cd8cd2a9e647f9945d36a0e8b0f92eb026070dd89a324439421e9d8ee4e62417c90664cdf25b42e3e4098f063f30c08d001484234e2b67622ec3c4c8128bdcb974ba38361984dc5d7a715e2dca07b38fdc791f8f2a5c6196d79299992d9a1c35de04714e6851bed492e51423ccd0e6062747c70e6f825229773cbc098ab97bd09be02b77614f4b030d1a392d9a335eaf6e39514c7bb84743efd24aa953faf633a53c36b983c78b3b8ff8e272521247f250416d3e77e92e95d39ad52b87d7170dcb5b32333357a6255912e790ab1a77e92a970ea54e3f1e2a30a5943aa5d4e3f182278f9719810e2795c3e9b83be4c683da77975e411d4a432f7b0fd9eeee4e7db88b94de4c7fa80c60867cda72e55ccfb6bbd56ac91fd935ffbfbfbdfdf9b41ee387ed51535852baef9a46aeeb87cd6ef65623d4c8ffd78cd46a35233523466a132ac4a0d33a5d52ce6bc199b729a5cf507ba7a017535cadf56ed6063d18d4b4a0205aa32968a73cb0e80aeee4dea7a008e6802e3870d418f9d3efd291c78ec236e4eb31e42b0447be2de477bb77fbb18b868845b0c3eefd1b317816dd0661f7d27acae8301dfbcede7b83bac3b478efbdff2ea37fef7dd165f52b1427a452a98acc80b47638fae4769ecc7dea5bbfe16fbb45ee777e0291996fbdccb37017b67a6442d92a0cf21e45222abda664d84afbc9c6db5a8bbb267f7864fb0da69f58503d679d285bdb516ddbe9c74ef2c27672f7097a0dde8bb3740b5582cad257bdd357b593cba693c3ecdf8b9d6e700c509f7e02ead390c990cfeceb30b2ed31b2ed2fb2fd04d057854cda497260bfc99d7d617b9130db644839d4025f02e546b6568d6c7ff693dcb1473678032361e1091e3d276bdb7edbb7d6fef5b82a3af922a18b69a463f81b0031d6cb3c412c3b31b984faa9f0e702dd4bb933e2bf41938a105a08d12cd099a7795be00c38c5e4587f0464be1f002da3c9f1333fdedcfaed73802e103bac9fa761dc7728db13a37aef3f705492bf11bff79d7b32a0eae7f77da702470e1465fc2c16eb4b909915b27ec413c4e038337e1638cef7561fe43d469ea0cc2b95f741fe7921f77227c5813209cc0ae0d6c58e327098651d42bf1394f4653560082679e619e6b464be49028f18af60c32902c39cd587c1ceea8fa93a54a4d466eaf239ab4fdf1d46a5189c93a9ab330b8b634ba4cd06fdee832578a4fdf2fd837a82207d7c5cf431e7aaa1357256876a60d201dcef93288aee7e27a73875baa73bf7ba5a3b5b2df5b6d3ca1caa9185d474b20d0ddde4fb13ca6c41bec01c923f3c5dbe3f677883c4740fe94c79c006be384ef036dddde7f542faa9af41014e8149c0c9e4fe1c429a535c56ffde7b6feafe2c86fe52cfa586aed0b562adb5d65a6badb5d6da0f76c096f674ccdaf76999b4d6dad0c9977b2b6f3412b6bddc84b4287f78f2f63cf2c7f3f63d3eb293b86cbfc9b02577b60fea0f8cf028066ddb13699d16226b77bb9b1b8940529e9a9bc761f47d94a0cd2a4939522240ca6c78a46b281b4699aca0ce28f4e94789be2140e4ce10549e04a1c06594c3e3b216287523531684e8f8ae29edfd7d81c89f22f5e9bfcb6a889d052a97a2c490644003d3a888eb677323b0aa30b48fb3d7515ab4ff819dd37953c363171d8df2c9a8632306482d93b285a0bd64a9e4b0a082cbbeb7a36b1e3169d904d3b025f9e39f2444484f8f8ececb75ad3d32b242da97341040e08003180cb4a150b2fd86d2d16f4811187a861d66a5dc88c12acc175d668109b36f2f16b3b5c094b591c3ecdb4fb5e29e66936c5fe016ff586da02a8ad91f43b0450eb3ef16a9c5a26cad7d0ce4cf04313069b6913bf6e737a405fb454a634e51ce770d08e758b38501c81d6f61c6b1a323f3058f5ecb741ae62937b2bf989df6cc14d44902ebb80d71e0f165be9b5e51d194f3670a265668f2675e0eb368a98f754fbfdd905192256d90746ce6e977b5bbbb5be218a46cf6e05e4d0d424c32d879df9094844232994c2633066e86c98c7a42a265fc4ceec558b2def325de53d5e77dcb7bfa9d23794e5e78e1e4b2e98617cea8efc719f581decf4fa5f2fefb26d265c9ae978ca9f91c354ff32d2485d4f837c45bf5549a5548d8501548a61b336a46d5d4d0f0b66d5b8dcafb66728063c790e9d38063cb90e9b7c0b161c8348f738cf7d3adc36ff1d52211b94347a9f495a0721a4dfef03417d98c72187da12d869ac849a9870ca54c67d4925353c74609354ea52427fc9faabd64fadd30e1fa4ab5e6e9cf288a9d883f8b62ba0abb8686345a9417d2a268519412c99cdcb9332aaa63fead16692f39d19430681a05cadd5c0690922d26a57a4ba6df5a64901b8a35df495d033697865128e40e6d2b9dd422a5ed288396e2b814084b853c3eeeddae3ad336dd772c2fba97b2e3c91d98bbef306252df71dfbd177914976ddf755df713aa6604788a9961a8381313529daa351817eab6efa26ed77df70dd57d4775dfb5eefba9fb6eca9e2fb07ff741ed4f2d76df61d75accc9f6bb9fb2fbd176b349ee7efcdcd51cd6bd3bb5d86dd162f71e76538b5df73751702b779d0e1af5b424a7baee5d1d7b7521056acd1a5167d7d0b10b6c4b4ef227ccf436987e12f221da51deed26a71b2a4b173882336da72d5850a453cd2515765227e148daddddf439b0b3903bf42fd85848204d7287be05fbc903dbc961b4975aa4134c48ff860a5daa27a0357d2e4b4a8d643e35556aea1876ea58cba5b404c599b4700bbb5ad87a384aa84c5dbd45cb66bd605c62dca5346b32caa5d4c24a63ab95664d69d694664d69d67ad6945c4dc1048900d356ad36c1cca719c61c63a91b49c746ac04663e515c695c1a2c2ff0389532b7b4c4f5c89c9273b9cfbd37d129f2873ea7e2b89f208e72271711964b42b796391ea8ebba2ee75ab8933aa9a3909df4a384fbfd8ef7862192077653ca2847426242ee70dfab7e74cdce1940fda02fb89bdc5fc0a39e7b09db7f1f837dd56d91cb313dd0ab2cc91dee1b74a716b9afa06fd122f72ad0690ee33ad0532081709f025d05728773a41639a50daec0cda593a874d23c72259cca8833c78d96eb2273480ee33e498bdc146a917b0f913852e638ee5bf87a1df323ef4a676f9ac0a38797acb50d26db0e93ad7dfb94ad2b5b30b21d93ad75a4166d95d09568d1dabf8982476bed7bd8695fd0ef96dc49febc3215ea9817e9fa2253aa068f1b997eb7988e71324df0d861c6707094c07d8ff9a1e1b185684499fecc388bee95b4edd2fe6e5b10176ebeaca7df35740c3f75e5fbdecf256a91426991dea3259638bae0fdf9b1581813b98cbe5c11b5c2f1666b9dc81086ee8ce6e9ea29cdab68fefb1e924268debf21d7c861f45d8a84d1af60134919ddc8573fa4d07c50d3cc801e7897969cde3be2d1d57dca699153dab07e166e8dae5538b60d63df909b860bcc6a94998c4e3b4cc7da7e73f57bd63abf9b5303991c702f91304f2607dc427287fe4f121e7be95ecaeac20c7c81b961b9e34d2bd42265e28d3d26d39c9a3ff9923bd91d65e00c4ce8720d482848d584b61875352945bca00a2e238e1a8cc841871d6448411155e10217a8a14614222b32439b103da2d2846a890a1743322658b2c1280b1d88a8c2440e4fae6083054f40392308a22b3256acc8ccbf5246a09a7fa7d08d89a6464482255020e88269439a7f392eb8e0e6dfc9a24d21a3f6810ebc00864e015b4e8043962a52c4a8020ea96484105f7258c387378c9805b591a589158480480435c4f00697a63cbab8e4f9392f0ea4c092890b943cbab264e252c34ba6088f547a1e48c1e1fd2c1a47084aca0e4b3a4079c107ee965a530898645793d198dcdf6a24fc5584eaf7d270f4af3fab57f7d99fd722102276d164d8b2c5855c080cbcfa449842c8653a77be2a8f2e2402173c4a9acc851a36ff5edc09d1e29cddfc6e12e9c21e1a70f72a1e60e0d48f3a5a9c6ab264d27294b2f37f5a80fd7bfecc730a4082c9f639ee6bedba5a6bed38d082476a4ace4f4a6ba5209262488b9196223ab395c2294fc924c5529e33334961942593162557964c4a5cb20b39131ffa8648e9011296b9f51d28c1f14723999352ca0eec4f81fe12a4cf81476a762aa9f46fafc525b0cce3cd5347fea8b20853e0ee53e02acfef0075e67d0a54651192c0f7bb09439de138183af3421ca7c99df9de33e99917165182cc1e45eecca6b9900accf454e8422dceef0902773f3a98fa8e03c7cfa96d08275fd62879fe76a4ebcf4a277140b9233fccf24aee56579cf2912641956548e58ecc4ae6ac40e75282b97b4715b8bbeb134ae9fcc91d6400b26c82fcb91b5a5b69a554feb8fc80541148ee20b9d3bf830a1c04aa72d0936ef421dcdded4d7cbb1ee7d3ef57923b4ae774b5e843985236a894f3e53b21e8eb9aee04cf97124bd7bd66bbdb5ca95773e0b992bf33c5b5722d783e75a7549ad695fbed55ad4bb7f547eeb72c5c6edbb6cb717733e252dbf59427652ab3c0a4bb4e4068e0f19e81478a250c1eaf194065009181058ff4098f778c28c408038f14cc0ac0f8022809a806e4055017405c006d01f405480b202f404e4059007501c2a2098f9749098ff40aa02c4056002d015501040510154053007101da0224458a7b758c764eb7eab66ddfb62139d262926e4102e9c7000b12ea86774928162406a4ec7e3f1197ddf0d5b09e39e4fe71d290270cf28dd4bd1cc6617fbfbacdfb4103fb5fa72e7fe8d3ea4bb0a55caa691c169d3f1c7452da348e4c3b5882e57b964c4a4fe4f1c6fc86587865811279e4692e2cc10cf2d23b53432849c9c866816b964c4a3f6c5bca4659c1a4444483378372f25a08501a72b5d7caa163fe9a8153593265a9794b5e544db25c31254b0a6a5998982e2080a0b974fdc80ee487e0c5ab55eb7eb27eabdc54e6fec0ae53365549173397accca0008f74ca741021cb174204f610b29cf207878409e41292e57736c80f14cbc97d8190e503f1c0f9a464433fb2e862597e1012781f7c3e3d59fe0781c7abf220cb071a5a75703d0eb27cd907583c50f048658064f9df84c73bb341528d1678a4ad1d251f59e091661a9d2c9f0325726890e5b7a2a8f1640659feeca6875dd5abdd54a3923ce5ce7c17ecc7b0118d7e9cb8c16016f1980287c6099ce383081daf1d3de694dc068f50c98310bc0c093c5ef0dbc0e30d792cbd7a5c0fb75c39419270373d771f3d59880af0487fe04445c1e0864bee9741b481b96a4764009b1afc8881c7ab430315c4cb8e8fda063e94f07833101e25e0618d30041e29072384d1c1ca03214f3db4113ef06e80288163d7cbd9b1028f54965ae211f2019b80e0c99b19d38f47afe7cae18114440876c9a801e45d771f4a84e05d777731bf7408014848901f107c64b10f7a3c10c10411b8ece1c8818c4114ba94efdf3aed6faf56f6ebb4459f955eefcff9bb23f7a7dea9d37fa7ff4f9d52ea15a4e0fbad3da6ac74d1a53cfe8c81698b7389564aa1ba2ef8debee20a215cce2c45d46b2eaa1d6660f91d0b324a684801aa101a62a11fc915c5eb740b20777260c1d373987e9dfa3b7575c1bda4349b94585ef8cb2a9882c39cd226342e2da9abb448a911db869325f7dbe6e56d53c291b66ddbb66ddbb66ddb6af3693e6d357cbf6b5bd77c4b29c9dd9c737aa9b7a092eca13fe1ddd6ca1bb7fd05714cb0b8c5edb76ddbb66dfbae7b6edbb66ddb4f17ba4279db9e2608e300045a37e5cd6edbf6dbb66ddbb66da96aa1d42fd7ef30502da665efb0fa543ccaed315576ad5f1f8cab0beea7da0c33c3b0cac0f4ed4f099bcf3d351497e510ff5a104009b5d6ca39adebdcbb999ba9ed3b5049f6d4f65c6501acb5d65a6b7d574ec7bca6ca2cc9932fbd3699fe66ed04f1ac1e2761d486d78d8a7ba4b849d45a6badb5dad62261b556a73aa6d65a69adb5d65a6badb5d65a29adb5d65a6be5d24b4a2028615a6fc8e8b65aa3906cb5d65a6badb55697abd65abfd65a6badb5d65a6badf5e5ab76a79adaebbc10e3276a20682bcb9f422dd2a6955abad14b39ba03d19c460c01844afcb101bd5dd1a5d489fed842ccdc990441188c030e6e7692f4e917e9d891bdc2d5b4df0336f0787b5e97a173aff3c259d485441f5cc1e3159dd5d3693a4da79e4e3e61fe8e7f14471e024c59f7a9700c21f6fd0dc70db650e9c57075e15d54e28f8f67032f8c6559174a8751a2e9e430ef292d3a15215a74a7d9fdbb79930626a27d14d5c9174bc6c232566824349a1fa40057e949bf573e879830fadb4dd9bafaf97388299b50ab700c41158eb169348d76e4711ab5d08c9a46f4d08e3c4a27a24cdfa98b8ca4139e52643e4d252e610b9d8bc81dfaf273b96c1a3d951d6918fd7e2a9d8408e9e9d1d179e5116728b9431f025236d5a08100020730d009d34e5ad129ef13ed5e4a111d794d4542923f3c7926cfd769918a2dcea62121a12a150e392023f3ac1089c3e87380f5aa28304bb57afc32ac9f3548199a33187ae672d8a454a8e8645a73190f4fcd796a2e4b81ba3efa940b479c0a698a76d4a31f6dda4767dea31d4d518e5e8a87a0117fb478369809636308799cb522ddb4a988f4efe591c759e3e1502db2c06642c2e86350ca0f56609628326d2d4f717c41ade85a49ee500f6f4680fdbb0409ca1d4aff260dfa355aa5ce51aa3d2fa0f2fd6e47beef4c86eee3f480a90fdd8eb2b46dd843f4debeb7f6108397489974217c4a940bc91f1df9be1f8520dfeb4f0203c09f67ee56ac5a5d1b157d7e03478abd577474c02bd7e71141903bb8c22bfbabe8576bad5baad69d10d45a6bbda9adb3b5e680c2b3d6fadd5a579efc2895524a4955df10f72a6badd57aadb556ee8623ce750b4757aeaf2c6badb55677526badf5cabc3167bbd3d101afecf447e9bec2abede6f95cdd6d678ac8e3f316779ee7b1be211d7e74a32d5296cc0c6e5d1ad9a2c951e3baa1a9719777385de30273649a992c5d32b94129efe8df2ecfe61b62e33938d61bcfc1d1b2bcc72bcc52cac60f8e748727c1b1e29ccf0449732d587e833c58325fb8eb85bb526adbbd736af172ef9c5abcdc3b2f974a71771add3b2f974a71771add3b2f974a71771a6d5e5a56888f8fb5dc4ca566085278494958fdfab325acba90fda7575bbd542fb5da1faa2581973abd7a0165aa97213cbf7a095d4373b6d36ab9542779de01294c1a5291b9330452048cd4b6ce5ba150e48610073ea1c5fe4ff5a9bc152bc592329c0c4f4f4f2a48d8447219174e28920d2850a0f88402054a9ed90010d4b2427c7c686abe2e4bf98be00a5285a4ec610f0f0f2761f6ed3b074e09b37e9dcbd4da2ec7bf8e28d6b8dca5c20c7526c7e5f26c24544a46b90aeed367547097ab5fe633e16d6ec7bc0eb490f986782823039e4f41d627d353a6b6b54d07a8bb67c9d4054ceccb3e6b5d0f39600166eac24512f752ea459eb368468b6e061a2a567342750141ee9e760c081706ddb020226f1bae6cc49129c5c2d4d4032dcaddbc5ce07bf1d21d0107a6313ac8fef6480aaab421e60b33a060418f29baa421861710403d316907aa08d39a3862c8e66cfe7b4c30306d817d88ae10fa72c597ec4fb18f932ed9dfdf7da61401f31cf0e859b124a693dd26092d556c0903065412b311672531acb1858d2e61bc68a1032dc8916882862dcf87870b1c5b9ad263694bee1b65bf93a9eb1a3f4c42c3249389863126982579c14b7a62e69fe4859c2166f45fe8a121662d1c146892d08449fe04de0a8bc04f67401950c8163c62d6d795b2306ed6e7d525f73cbecc5ffe284a4f42ca3cf426ea5b38119b211828b27d99970993789864d6a8acc06896e4050f8b11cc663ec90b355a68f96226f34a66491cc961f66998e4b5cc92bc20ce6642a7f507f693bc20afcc64c222f0fb2b9909d982c7595b3dfe699f5541d9aafa79d5a83fb07ee43de66a38ba58e188f3178eae826c435f12c284e9bbd74926153284a16196e405ef8c2d33997fa1a34049c2e30799b0080f8bc09f573faff6e755a91a57dfc98ff52c70015a78dfe068a4b76fd08f5ce65648987d2f485f388d0ca56c2930aefef325b9639de64a47484926cd4a0b9c66495e48c5f165e6ff425b01664679c8304bf2c26be66111f35f905666342c02ffe8474576f658c1a31f2d6121ddb9c8d6c33823dbf7a3ebcad66bee4bf20728dbf726f963b35dbd552d61285754b6dfd52d17c07b9c9b7798b8f671048029a07afc3207f5f7ab6f0cfa91d7fcc997dc6905ba538bf655a083f1302ddaf740876a910aa6ef4f2d5a6f923bf653d6fef52cb27dc74202b1bea404100fe02df4a316adfd1e3fca76c9d581ae86e30a2da594324bd09f5a098e1e7debdfe00a1edd429d0d9050120413587a10238511516c388203175d6c18aac28833fce93f0932eca73fc779a4661c0f65d6d9a00dfc996a415fbef0f4bc75b27febafaface3347c992ed805f373dadbbd8e49976c9ef92d94207309327bb0842711c043b73bb35771b32f9dfaa25178f27494aea398b67449576e21ddae76f59ca103e4ce9c3d34e0f96060ef97f31d5c65f90d11810b9eaf1ac3b72033e0faf65d2dfacfdcad167d8336f0951e2061d96346189d7c1da0679d4bc2642acbf166ca0cf223fbcf12cc4fd1701465c29b3cce29934a18d383353e48038ff3f651e7b294cba9037be6d3a30f386735f778bc813b8f7403a73fb5473b36f1a4d23012482044c81d7ffa91302506cc85a94f8549aec3fc7dce6fd9ad92e27d507b619217665d3897fc48c9b585feeeeedf0305bbb2fbe8e2f1460b092d9938f44797edd40b7ed0c0f33bb99333236b64ecfe6c2d2aebbe86fb91c6bb41ead310bc6f72679d9021d7ac1367102ef49940ba8600087fc0d4ac03e54cecd60cd23373f47421118771a1d8f5bad146ee4fc1ca17e4094858ff6c92fbab149d829164b78f84333c70c835f3be03877ee68529388cc8343281f483913f12648b25703d29c77192e33cb5028f37f0cc7467032d9129e178808cd57085389454903b61727f901d3a30a76152ba97ddb70a4e54f0213c9f5b81cfa1ed0d206bbf816d2c889e7503b95e0f3138005326256c06a143482d7283d103e58416bbfe093324d2a20b60661bce212672a76f1410354432bed8c2200084425aec8182e7df045902d7b64974f3775280ffde39e50d1d96418288c1045184e14410209849a143932b56a891e58b338218d0e4430f514d448c40861d4d4d9821e68b0f4dba902f43e8b024c23e91343c30847d22698c476a877b9b5bb76d175f0fd76eb6fbd673f6776ff7532f73aad656c5f1b004ee73da4edbf2eab5d6dad559fd2380dc7ec8465338fd1287becc5e6bb551f63b5711700cefbb4e7e371c8de4fbb112e00d7cbf17e323356f97b6c8eda0813f8f9256c4653ad0f8a286952c5ec43034b334174469c287254f7011c7cc7e907d22f66f487dab63a9b7efcaf13cee7297bb5cff4df96f9eda52dbe6b2d984669f887d232b18652b26db6e32da9247cf22596b9fbb9bbcad8e516cb76ddb5e768d0e5bda8fadb5b66daaeb5236c80c78befc9cee9c14cedd226db972debb30453d07dfbf8238a9b084fbfe204e87256ca0f71109bf0eb1df90770e1c8fd4d1e2f8e7fcd0e1c8ef2c5fdd4a8672257f240a9d7c8db89b4d4d4465d9d4c453d620cba6256ac8d7e3923fcb2627a8e4ce61f7714cf8ed6fa5d7a3dbcf2f004a72b50490f423a11f961b675a1c133af7bb20815189ccb400f63b0cea10c77e7d1ae2d8500062ae2fe61a8af2e5583af972224a6665d9e4c450eeda931df57ebcf5a9a435880cfe38742301875e2ae50eb8fd9c24f44f9c2bcaed29ce7d31d32c0520e62d145b946fc31a8e344b244242424b320d83c8804b00071b3b50b42934c0c1860b597010fa6249972652cc261459bed0218a2e02a573a8142db84539e9d09000000000004315000028100c07444291582ccd4345181f14000d7b9e427e589a8ba324c8511032c6104308000020000001022456340e0ea3b75018128b4515e620379ab624902391998b432ba3d170598d4d8e501be4e488c29f0cadc2adbefc2c5a8aa32af140d2fb6c7a2aa96605bb27b36bf8f9901edc0c0186c534b914b572bf0c81ff607048f51ed1b034f2af5a019c9b09f8e0d0d52fc621c5326473fd84452112e72221fa4de9871d5311c564ac84343dd3a739b08286b5381ed6b812545c10bbcc1445213122962ec6d4f72aa1cc9b7b8eb4a45dbcc2888917b3c1e62685f17134e8bf7ce86983e3c2546211ae5653932e75dd03c9774d697399bbe3f8310570c969ad0d3e7b5bba25f12f6ecc48a6c2b45517a1e609c744e74661ce722de05147948f6a82c60ef9352a62139a48c0dd8c391cc19e0251d57394d013df77b75067dc386068ff8afef4c2d7f2501bee55c23d85626bbe006ba5537afad72e5968a17f4fba8c2796cbe070192e42b72892a78529e42039ae1b2f613e3b836a2450642ac767316197985ab8733b1ba9e6a908bf5860e84e324f5446feebdf9f87c672db7d072891abcadcf99671fd3e83d46855206ab4c48c170f34d64e0203622a7668f88836a3f476e6c2bc254ff7b1ef8310848842880b9f057b5ce08a4e498840bc7ce8822527f167d9f08a665d4128d50f5d2e51f00e0b32ea878f8dcbe016e4e9fd7e486ed7a3400d6a9028df2d925c4c1331e4ca3dcf645c082f5110b6173c7e966a543177a1a9a2e33dd532240e15f80e5ce95a6cc91906a053072cd5d73e2017e000900f6be2d33ecc87dab10e0db4c33b18ac5cbdb3d6d419d857e06684f426f835fc813c5dcc98fed4aeea363be3be12defacc52a3944c49aea92781fa779636bc8879466758d550200c100dae08495aa8342e87644aa78b5565693d9b58a5e514934b2cb1b4b27cc1b051babb0a5d38b410a9e4e50a1cf6ae17af947259d3197736b1e9d1c395f10fae487956ae838475afc4114e191066d61357642edec2d89642b174d782dd8d47fe94c3ac07baed965e394fb1c07ef60d4ebd10f32728568ba6394eccf795dfd134146068af2032ad31f17c8014db954a925f6578ca0588f1888c5387c8f0bc9e3256da3c635341ad3beb72bda9d197ab95e52b0f52da2593d54f07eaf71d83d92128edfdb09a9ea11cee80885d41bf8c379091d0884c87d412233c33944b62ffa0303378f1ecfb054d1d4be46bb3e79e30711335b13a1037e24fb3e70e0937511399e075143aaa2ff8411fa32632c126a46ec2f152f8898be1603be5631ba7c6c18d131fe00d5446a89340424feed48e0e87b0b03220a497a4660540d35f1f58370a9b5ee9d69ab6c6fe86156feba27a524ff5d1b629e6732c88b2942a1c9476fd9d7268e96db986a82b89bc90f44982a4d00fa960ba4c43418b2c67d9209594bba10b7c47ade8d0349a099b390dd39958741c430b4e8e34d3924becdf1cace3d590043c0f770a661a9651797a2ae34084434e57b4d2d296b5dd6245a01ec0a60eba82df2676cff5b80d98b539b70c976ba9dc03544839aa0a47e64b022da9cc7b84053161751adfae439c37e0dd621a71b97885d5760ff42a74dcd9035c2a07a4fd79e7b97ea67c971cd3141fd86afb611575684f1be1387899e14aa59e41c1b1617faab172916bccce3ad7a083ed8dbfe3159bb1a0b014503554f230b79607a3d47bfdbbd5ce78b3e53dd6c09fa2415497e2b9e2458b3709cc48fae204602da146706bbd4dd1e2a966b50fa369ba961a94d702604fc541248df64bf57b8961d218a3685f7cefa5b31277174d46798af7b263524f035a4a06d9270a4e46854a3e026576692c9ed2e0d24a9d5466d8056ee79f059a6e0fc4a1a5f43c06a08baf899b6ad1ae808f7ac2d509334d1604959e6578329345333154ea6ffa684af6a30731a68c848755a0b3d56d39dcfad69f44270d0724fe77cf10da0b9a9355275f1e2aaa1afa28b710a44506a2db845a0cf951a0006ed229480da33b3f57f542becca06c7c84e9cf11c93f4651450106ab26c555923d582a80b3a07154aad19251c5b5ad633d60413c9d4803d496ceba0d2888b9a4aeb787550e83ff49087de8a9500fd5f5be67b6b13b8fc341e54c1e7d94aba023245a49ff4013d3712dc789a8e3b16c4c83116f159ed2bc17c61a48457d49f0dc944368645b0b82601a01108f761b24a7f2afa6373ebd11ddda4c457d8cc79b9768a06f4236200ee21a125623ba3d7da004da6b6b88e7e2420035f97e08876ac601a09f9ece72588cba59effc8d992095a38f892c9679581010097bde0e211eff753c172f1069189de085f45f9d761ccf5979685f725121e4f58430c2910c608415e903b5d8093f3d936fc148e6756a108a23561b2f8d74257c661c76a71cc9197ed03351bbb630cea4c755244203c46425e9d5a1345a44c106b9d607959f05b1e288ad43c835295175e10d756ada34aef6c3682ef8024b876beed9f3f3e5d8099767d0e36311b3a83eda1974c4ac2691291147cb60e888c1081e994da585d20e252fc26779c4efe403723cefa36ee97851b4dd61a0f307bf8b243213749c126ffc86e68fa47abaef4fc9edf3c9eac359b38c5e37a452e3b7df47e92524568ac031a75ce170771e4ea49bc1a705ae1e80f13b131fdc33404f3b4efe647760328b50b5d9966981953ce1814a3b85d57f834fb69fbce62010054c554fbe0c003ae32bac51e4caad6259a02d26f138cecad8867b7f11eaf1d54edf0cb3225bdc5bbc22a2e16bd078889c542661477f986e4eaa5dc238a58fdf0af21510c5f481edd8a61735da7038a02bcd1bd4f7fb5202cdda574c765ef7da7d1aa1f9268d338d1895750bf922fd80d39f82eb452dfdf567f8d711055dc3bd797d5b9428fbbd1461369bcaa21179612470ccad83ec72e1f7c65a992d4e727f239a33da7ae1c783fa12255640a3e11afc7031057022a4c8b707a5710c1c11cf7b064d0c138daed8d999e2b8a3b2a9f719501800a9c0b60e980e00d1873645852edab173384dde771b1a7ae144030474dda9e336162f58f7545269a54ad75287ec2d9f738c5a1be509b8b82328b08029fd6348fc2e7a2791e52c700d12c7f4500e70112e69bb239585b19a000d0d4fdd233c26f9fcfd903a3af3156c482079a368f2414f12c2f7641b0b53ecacdfd2c8e6feb626ab242ab878fa54542074196bc2135a5e14fa0cc4f2f16a75851a8a99af35194f1f4a8708998d33282288980e61759259413c439c67a066a533e8f5f5de55e743ae28458cc8fa378ce59cc877cc1e786908be5458ddad3e537ecb7dcfb27a5fc8a677c872578880f8ad69c2168aad24ad3a21ce66046f1bd6bc57548807d8e072c3e28642cc06bb364af12225c2bf412b81950cccbd402b5dfd035ed34cfb27dab6e5cac5028601a573f3e8a13e01cf81b87acb91cfb18c3f2481031b49504124e2ca9ebf44c52c5e10c654fc4011ca24e1d42ba8c27ffee08d1ffd549d8b3226a849a248b340ebd5019e2cdf5d3ced0e4621f50c463d4b3094bd038b9980b9a901a375c17814bd4b76290219a58820dea4e3992278539472c40125e4f2289100b60bc66155ec9d77c96bf8938493d879efbc1d8014936a74fbbf262d1dddc4c96434e334d2fb2f344c0a543c78c0c84f00a802abd4f0843b83e23e2750589a3a61d7e6745775a16473f58da25e77e0d7c4dcda9590f3b657b9f5232f082285a7c4efe975c4f806b84553da01773afe89c2a75fef94167bf8942acf96423c2314cb977bf50702302f24f6d5ed04f4d7faf0611426632281e3b6789f6173c20cb2427f2096b8e92a8f5ea6a5655f9e8363a50e924a959126c7efd4ec119504b01579ec634d66577087cbf39caa2db9d187b5eee4bc086daf81a83f9318430b967fbf8e92e184f140fede03446e3e059ca08229c3077822903b8d58172a293629ef1783b7ef8974f42c3e37e398e21cf6020b096eeafe7d0f66cdaf7a100a7db98f380e4ce6bde2c1164079b6802a7112e95dfa743d7ace35b48750be34b8434fe16d04bbf05ac748d3c7c8044a7844fc8deb8d1ae184f0a6b11dd2f38355ae5a78f348a5391a148c341df9da895839ba31134e701edc91f853abec366b7825ef6e294cbc96231b41327abaa9929a6f4d15227e2ce3f874f59e30d5fba9365da21bb989061af97c91191b128ea0ebba8847aad0c1fedc6489544590ab1750aa4a8bde76784ecf92390f0af465fac899b093781ac7e6716b4bbdcb4b53311354b9e02569bdc934ecf847795701505d7c7d646dfeea4d6427a732b1aa194bf892af3e1afcc614014b1c04c6e5841ab581588fa9f8cdec9be584beab7e0e433580320d7ab8acf94c74b7295a04ccf2a0266adcb672e1b000b8b630a39ca4b1f60150902f29e4cd5ec64d30b37425d5fc99f1d9c5d9049a14d19d57c8c71338f7e40ae17d6680a2db01b6a22a34b7d379333bb0d0c824b3b37f45d880bea63cdcc6f5754359b80f81a18e9bc0217d50f9de46f6c5884779809ec1847959c11b1781d1433002863d4680399e701a865a2862a380ee0ca973735f2d188faa046b82fa59451c98a53d8ff48625013cdf59970082c030d583624aad5660b8ef5ed4b7104c30a54d116a1f6beeedfc474190d8e0c4a8c443a33751f7d3a23dfc5f9d208a6fa08d8238f12cf4f006f349946fd4527812c4f3ff0f3c6d92509a99b019e8d795a0ec66e1d6eaca898fd4a540eb03cb2e7cfeef05103d21d479cecedc00fc4a26459b5693bb02e18820104a4f9e53e3de6f70a82554bdcd01fa3b292ee36f4d46881251e681509595f0b005d34ac493704fb5a3ccb3dabc6c1de1ecd2ffc399600bc314dc5762ea4c0b7466478876226e1ab8b9e2b3c44a29dfc6fc8e1f8c1c88569ff5868e8b934538512e1994bd599ddd0602ca45658b66281e895440375451d8e2e7b469ef70c0fc4eb3f8843300a2711e4b5ac420aa503d50e72a6283dafd77482b195bcdf8e62dc52596868fc53cf6b2f5f119a4389233039a1694a9e4cce87576c3644e34a93c2634c9c228c12f04a65784175c8bbb815a1430147a80dd14e19a44cc3ed7a1824dbe0b2f3a080c8d1d60484b158bc65676b5ec90e7f254764ed41fcb9978a65eee98a70d30cc0d6d1aa3e7ddee0d4522f58528086954e2389d74d548d0b0aba30f90459847691d4e1e363bdb331da62a9d81c1bf383286c36d8c621ac01de359d699bd3b4dc6483833144defcf22454ef9fab4096b395b88c29ab494d0c58a46e65869473f9ef7dba0a5efd95ca61ffab175bfbf5ccdad0d619f123bb0d7baa417d2baf6ac3d94bc107463e9b99bd3b4ba2cb88e9600551e2e88e5abe65368800f50868d7616d095a7297da53820ecddd86c96722e2c9a4350f8ec53da2cee08556ad9ae6db884aafa6b80d0ce7ac1d625690ddef953e518cbcfde37edc7ed47647f8e15d3e1534f84adcca27e16512f3a57831e4703dfd792652419016aecf73d41524e092f6fdc49de4be39d701ffe0b5e1952c4e82b02c9827bfb00da83545129f02254e3744920e5cc4db2c353ce45b45d9072e54c6794f3631d5c61944869801f9e008ac28ff652bdcb64e822b4fc52b486d35da6aa47e6c18e6860798af602db4060eaac1e3990bc98585dd66ac12f749d633f0329b63ab826c24f130028dcf549a4fed12b733991c390cb9df0fc5f97ac4f3489c06f6e374d6bed08be3c1e35d093d86a1ebd3127e0f24fa1671e5f5964576bb161a8e4394ca33ba5d53af6b836c61e2400654b32461aebb56e4b4009cf343507d86c03c1c2742f7a34f9bdd5c8f2d12c4a12a93e5db4cffc266b39782be799e90fedcda6bd50e74cdc326feaa5722a827121f193c41512d95122b6f3092b8caa0a60331c4fa8d05cc5f8b59d483637dc882e6f1747970bda282b742e3a01efda79cd3934473b4beeb44217b4768a16b4502891a886da089895c10fa94cca704d28f78b4e424522af43e1a827a06e2ad97b686d2d79db4b4c16b186d15fdad83cc88652004965ce80142a6111e9037ea51ba26b599e6cc5720adf3c06bd4ca2ff5ac33c4c919091ab6a108a6c69bcfa25286eb1f9a8daaafd526849730de535d89ae6443015e949bad3b41c2fce05c78284b92cfa6ea00a77b6e3e5e1d17c8e27a4dbfa8b78f542094bd5e30cd92ba8f9b09b7d0cb8dfd1a741893a4ac740045e840276c59c662cfd04e6942565fe2aed972cb97ac3af773943608a15203e55841c50a15f59c1534c42d7e3de87c8217323ce1ce33b24a3672f74e235dc49c4f41fa5448706af9cd521f5b9857525234e87d40f5e5ee9c892088c3fab30e2abc8f58a0fbc715b61accf99d98ffc6f60cfb98dae742e4b6fafc0f8b282115bc14d7fc6e809a5ad30e2de6208fb129674475ea797ed05c446a0a6f15cccd2c1cdff7075fe78c3d10fe1601035c12096cd8159e406dd04c79eeaee23752e41f88b1e8e0b12a92d1a1d608bc17609c19e1d2083ae8b179464aa7fea8c1a51876405c893970140bf8a4580497c2688695b1a69231a5ed28637aad9c9d43c0e540b15d66b34725a1cce643ee11b2b5c23261120def97f3a15ef96fd7d4499c3d5fd57053861ca970f7fe30d7b87473f8e26c2215dc96ca31abec841202b7050038153cea7cf6f900f33cfbaa1ab38d4ad3703a7cae4b7532af6450947f7ad82cdbdb19e0a1e2b3806b4130c9f1ebd3fd45bf7288199e2358bb8870a53ab891834f297f55e40e65003115bc89eab09324f09da0c12ed16d9d98358638c30e387832332f57a69e8ee4681c29f7292af13314cd28ed25109e61c0882e51f0e86d36d1bcd470bf69859bbf30bb9f6c35d3675048d42489e92046f0b162189342d71b8ba1ad12a21bba6e3116d5f9178cc044c93c2632bf2317c08069bc92597dee98338259971672f4adcee46b2690ed1c7e12a991504c2836a8223e7a8fa818d7ffe063e226800d82d60e06dbf83b7bbd115ab66471c522e4a768ebeb592269ba03bf18efb2d88913f2a5772e39ee9044ff11f5a70925aefd979cb3eff2b2ef54e18f862a7ee3b6d3a410e2c277e50b4f2cb45e4b7a71c7c809b0e223b9196de8b6f237fe92442e219d218797fffa4f255f6154f6ca073a477a36a5d8802b5c4520125db245508d932f64be97e976263880caf48de99508234148a9d22804d33e63010fb369d7572d6dc5adf0ea2cc9dd8054da07d84a2a0e83e7f59224cc18117180da459f7821a17b18bde5fbc2ed6cb22ef2ef142f71124fa95c9885016111f4db4d2dab842ecec92c2b08feb5b906969ce4128b458511c0df56b6f09efbd7dbe9fd48f7bd6672bfb60f6651d1f163c3ca8c56ade0a3fd52d0552afa8457c9a2965862c4eef39418a6eb9633ddfe1f0f33796c95e4c7f41be968dc0b6711b63c27ceedd0a04465aff09b5e9fe16e1a62a3040b8cd76e253a2de7143b74e283feb47e384c9fe1380f424631d9e49a745a3bec7ee3ac9bdd8252e0c660a88d8a3f844e3177788f697dd5899362e2792a03e742d70bb52e5a760707fe931bcc278cf0a32b4a72ecfab78c7a0fcb6a94c112c1d6f85ac189c2227db8cc97376c042a25c9da6534b756ee4c3326bc331d29f3bd7a6c9fbe2ffd2abf573cf2de87ff9b805dcef2d367ab8d46d68fd70650ac9c6a09d5a05de777aaf7b8892ec5415a1bede6f8428848c4e1102ebdce3dbd75c036c818e6ee8e1fc7749d468c2b7764e8e2b9d5a30288a54176af32eab8a5e5db6e4591ffe0aba9ac1d3422d116a8280be5e09ff7e5811d926ba2d791a0850cf430172193013a2b4dc9918040a6bf16fc1dc111f7f4a761800f7c80f00b1089a27dcd0581a3bfdcf8381802a821e67ec981d3d982a482166f138b879d0587cb2600eba3d2e2c7835c027e5d7f2f1484c45c209f84e48ada3faadc10a85537361aeadaa039040567a10c7da68bbe856eaad99c8598ad68bff9f5a7c602bf414f0805c194ece4b2c314fde9efd6d4144233eed298f331cd7fad5103ea8ccb49fbb5e812b56e7b7ab7d49e73b0b1f11dd0aef8afa5ae29888057c5b2c17b430ecbf82129796498cd25ac49bf6041f016c3fe737f9bd791185639474e9d90a0e61ffd6b04940c0356c4274406f1977dc2299914e7abc950b1e6586ff01b0e608cde41fc0eb25dcb45947d887d206c8081306475a32fe4bc6f4310a76514bb940179f29ce60f32f9b74d5cdd3d52d4f73fc18a2c24649add0863c7b9eaf60ac63d911b9594f42e19fe541826be6d0f975e39827206c934b40c7d65d1b4ece675ac1e167b15dac7eca857e72082b253ea19295c68eea7d87406a46b08d3c070a208f3ec830fbb5747614f2d4dd79c54a4b0838b507e22c5a578e257dc266949c5a8552beeff8806cae1703148a5e4b00d553a6b601e70333c4dac9294a6911bece2c03c42508c4171095cfe548e08d95e5a4ba0913789f1faf9d7433539ea8a8e6a13246defa08983a79461213af5799fcfde39331619f3a4158fcf77a1477e69f99bbaea1b932946b54d58d9bf2aef70a7eae0244c71176594e5a42579f7973a44d7004fc7ed92fcff2400057542b52eae12e56856637af6f9fec452a3a6a0ee7328c196b37e9d3799dfabcf687253910988c3244542461bffee6b301926b8f4006c212e288d645ea941e3511f208c46836e0ab6abc19caa81823e57d98c3f671d172a8b5705b6536593e33145b30181fc8b8c92267e02e1ad301889dbe7d771acf31a8721c1303a5336886e574ab6b7add60080ef7e817aab713edd9d4a971db7d355f54a47e18958b34ed6c66316c0df5ec5ecfd25dc7524b61b31bb580c1bda29704c34587a6380c2af2b1a3b5e33af3d604c99a6c96325c33b2dc89fc6d8fd0f3ac07cff87dc48df97186d530208c5141f63a936a0183ad5769d45a70007329e172b3c5175f0e569f0e55b45498f0bfbc7c4bf99f4e84dcd1d0e9f74c4cb81e05e73cf9eb5d5839862a968995836360a5908ae511ad0284d222f97053c7204720fa3b7c9b1ec2c5b7be01fadc5b06ee159d4d99670622186b2ab7f40146ec8f665f9ff14d0de81904198b313ff4b9ef6eff995ad408a982c3e40407b65fc0bd72303dac5a3e48da64ff3ea895783d70a13bfe783c5a40c480ba313db02303ba95f3b49edfe8426213d49b4c21bc1110d5cfeb9345352816b37ebee3082abb38873418104b274f71cc368725bd5271ecfc922a631ab047604700e2f9f5c6e2341071708f9e5beeb43c27ce33cbbee13f6c714b091cbfb603e4a2a9370be590855bfff20bb336aab14061d62f3f5178fe94df155dc843872d32b0e74a570a46bd8d3d5ea397bf163007e53edbeff5c08fdb58900db9ff42baa575dddd4b02597279e47449b3afdd589aa4f85fdcc712a582b6133d6101fb2b422cfe0c4548273056e40aa46907ad0a0a755d9a2083c357d561949d8eef9de99446b056a4ebe8dc697066ece796f4ce8c37956eb1c81ef51ec10f50a3dc18047c907a45ca8e33231f93ab622978886c10bf46a58ca8c6f9d320b84aff8900701455403b2362e3381f1605f5c6c1ed545d9724fa8a75bcafdbaf133e8809831044648192e5ee0b7ef908973814777ea7d711f6299f3d8b4cc4df4d50cef64b222807b6785e08e91a88793229f8eb47e75b10c21c912b31c2bd501e1749f575155f3694b5384d21c07222f0793881a025a090dfa6c294b2f85e816b07d419e7bed7b57b5a8df0d2d609be2b68e2bf2af1160c3305f6b07b3465567002d5b8635926bf0ff546636baa3101d076fd7f59e7b62d755bc11365048e63960229bdb8d201d639df4c744ceb9d1a448a15079294438f92901407827eff280707d01886c7ef09315945de51d27a9c0521a68923b53156f7258215d0da07673df27e23016a04ea9d25c32468b815d806e6d8df5d76c0f6663db1248415125e628b6ceb042ddf5020e00575d69c3e6d97419f59ee49e084c5ff0cb1dc3d73c47495e04494a631e33067f9959b9471ad0a642162c489ac8dfd87597ad64fcc736abb88f61380aa37552f5f6975db40191482e2341ea65a53388217126c2bf7fbda84a56a4f5019e00b96ef6fe5a7ea887a051ffefe14075801ce12f7beeb7cdc7bf231e2bd4058b71b34109030d5d4d4d42c384254afa8fffcc9b3483a1255c4d2a4c871eb1105c60032fbc879e9163d41f93ab4adc4d0b8a418b1992c11f456e3faca3a2ab5871e7b0cb5ee8c700a93a5f817e08c431ec8b27f8b9f6c991a51ebbf437c74087e540ce8ea71f4e67432b0fc08d46ace193a69efc391153b9cc48342333a2f222e327d24317444e73d8d75052f5e3421d0d42f92e352f33940e147d58635c474ebd27f6f910dfe258a051838e35bd90ac4bed0adc1b63790570c3e6fc340c515e264768be12a2bf24d13c4173c25ba765854d8d14869066c8a49103983113cb6eda4c52bfd44e5c321414b17211662357150aabeef0a14b8c154fc695cd3483dd4045d5d7150b4c9dac8781f0bae4353dc598b58eb50499ffd38ca80f17bf3a315b77674f9136af7c73a43262ba40d85afe7724ddf5c2e31fa1aea092a331c0fa4784d3566ed7574bac4609bf966e338d5f4a21cf65c412a73fc9fe119a0680516931b030e6e4d5012db339193d385ea3dcc0a48049cd4832c897b58283c2e0cd238e09ec0e70b8f87a709ef3fefc9be04d411ca228e0e2e4817f69ec7eb4d77477455d24ca0ed2c3368f786a14ce4b2da69aeab81456951e73164e9f6c9f06d985548b6a5ee1379b4d7e80d043219ed0af6705e7f5cef18f01d7f48f916f8708a11e6803543a9488882d83319855abc41e17611d72c6978f8645eaa0706052789a13a966d6f1e12bbb2b66e9e3903b8a35c5ce4bd97d8e114993be2664cc0460ed4d98854d9cce1bda25f878bebc7b3678ee28794563f27e1ab0136dc42132b3154c41d682b0455af61f3b010e4e144d168ab7e9680c852bdfb0f530e7bad3e79b146dcfc64f39855a55143e49cafbbf91aafb1d7814e5ffc391ec49149329657b34017f859b19cb48f1e196dd8b12bb93d888e61980204b43251dd671e67518043c0c7583d26202b449fe922443b0424087c6f4d0ee64cb6d99e282a4d93993b29fef4de798a8b4802315f464fa09f81cfd755e2f5eb603de1c06a722832b5c45514d0f2b7a01c9c19daac99d3a9105910068545581f28f416cb1095f564b640287bc6566f4c7bf50606ebed787b05d739933519f6e2f79ab9bf5a0e951e3585ca06f8f47ba401a5f0face1f589f76468daa63e0ff02f143a14974f594cabd3a6b0f01c6fcc38fa0efb95038d7a20f287e70563d6e3db82f64dbc64873cf5ab980379a88c701a477a044621cae8e0aac578e4bc56a8d6787e55c908a33c5f7f91678c02eebc412c7932b197225b8348c7e658a9f808509c4959f4295ca52769ba7c7e500d3cb3a50fd9c640cf3d459b9548800a704f5b670a5045a919428c4eecf005900c9aeb37811b76a95de6f0697063267b4d4befb7d3aa1405036756de41fc25e47ef97d5e52e9bca3d3b3d9832d01d0f36d0bdb5934206e5b6bd55d9c1159a2349ce0e676949f298493297c0f6f352f8a8dc917931294639e0e796f57ed399d719e327482cf9760e5ec8dccf7c5e05d5d52d0d0ceb8b5ebd93182ddc3a43d7d68bc7e76dd34a93f283032de65cee7bf49f491a7debe6f5004056b00778a1047c92785736e95ec1bf1d4507f5058b6915707a78cc38734c53c5584248224ed1fae2ef215bcd292abaf3874301ed93407e672c5c0e19e3321c5850912207610e8983bc14cb525e28342b575030b542cced396480234e1916d8500cde06f4ba3826d689698690b9939b2305ad9ab839101ba540aaad3272fc779cc118bd7ef83fb0e9fc9641089e47e39b4722ba7e4074e90ac70017f8dff3868097f811dbc51404d704566a8130d38a1716485d031e33a9e379fba4f5896641bc7874ed978b7f7b69b064f0f54bbdff960ba404d77a04b85bcf4783476a280e0dfbdc4cd441cacf841b3906108b9bf25b600faf3dc32886502676755e5362fe57b8f067f86677bd827459212dabd962b18084360d444c85669a198e8f9a66af73a3071a21c060d3f5f92f158c7f59b9b923e8dac59020e8140badf6df3c4b5924f224bdce719c78a0791b12b98ebfdb4a41644d60269ede0e03aca8fc8ca5621ca22892148f20d3475f960ee968112f36eb53aaf2a76a8509d41b13e88cefc4ecf41373071f09ebf41b48541629525afb74d568163c3cc0eba7398007c02195f1ad2333fa546dc5bc79f09c9cf9175241f8dab12868c32636d2f47b3f059ac344e803fded527339aaa851949039e20c9d95788db9eb358254465de4339823d67492a27a07c7ad936423e7ac82d9a6cf67afea1d1c96a2376a45c8e3b5424e1d5cc091e7a20747abc23dd969456f848ba095687de03a099eb25d54eea1964b2cf529074c7c36d81a7339bf6d941cf2a69bc5d3f674c0aecae5db031e4658f018f654f4ffab87006699fec9102ff47157c43bc0e0cacfad541df1a981ad42fa12db72a7a2e573f1c4f374ee0f96f086d263f8b4aa5ddefece8bb5df02aa8c20e23a89e73e4e686d728f99865407634dd88de08d77a37a33180af6c56a932ee28e4666663fa314b7522ed94125e1c78ee3ea2be3145768248773b45ff61f803c4ead90c31e83ea1994167a1d2ee3637720012ff26e4beebf0a7aff5e01022085d2057c85f6bc586ff52bc8c8dc799b1ec4502329236870648700f1fc8ba765e5adda77b4512f5d4fb8e0dfea6130e62aaba964b334ac61a0563410d5b70dc51bed53d4a05c56e3800b516170742f547f7bd0cc763da36a1ef60003ae49af014fab3a335891bbfad525d6cd6836f69446e36b77592c1ece33d82cab16107c52dd850d186e98fa8d1b466b182ad9bb6515b7da08d11eebae6441dc009dc9e42a0c7511999819cfe404297a09571d9824dff381095c678a5d110c99d51cdb24cf9c81a51496cf833af6b03a456879052b9bcaa86095e02b034336f78dd40d86b3ad31ab04a6abc361ba2db49145c369f9ee6be987cb592acf994721518698a0df3aaa20a65709d85bc4501fcad0e212343123c83b8ac1121236aaf75b15a88ec1922a17436a8b164893aa23d45ddef6f145d6138a1d5f35c827fd935e8d22a4e7aeae3d2151b78c14ac4828d741353ed7adec3b4dbb023c937d12960ce40e6d1f3031fdb459680f12580a8dde2ca7e7d3890454de6b176efda6012c04e61441e357e09452c6b7b2b7c689b7ce1fbd685c7db47a2ee3e1949ecdb6052ade64081a39b49166fd1703dcd0138825c545a26ac6de23d6c03c5e61ee9eb1e4968a493d86a08cf1f130c9f4ea605b559c38232c63a04cc47a1efced834bb595d203d8ec2d21a390d25588ce682823e752c380f9563708e334bb12a231e7aba465f790a9879d435d2bd2c8319c314d812a18f10497bee7a46c7eacfe2f9ed44992e71a8793471ca802960186d967a2cfde2a85adb3afa8328308b067fa63e782a98d578540ea7dcb1938a20c4732f15ebc342eb086be23d62a3a692dc5771aa69e8d1a00b0788614528f8d15127d1924f82156de7935bee5bdc031483fa968b28abd131a9c66200898bcb3bb35526fd24c857a1738ccadbda9604a598ddc234e99c0cbd51baf7490ab3a25bf025e1dc07e643913ff9e7ff7e34bd1e1bec6191fb8955967f37494f05d31228c1916e87797ef56e254faf0bb624158368ac9682fdab2b2c46be30c89fde966a50246c81643dbdaff42b1c02a6d15ff9b1e56c1ac1098644e11d064e86d6a3ad354bfbd0820e418d0b850a20d82e5ee7d56dbf6c3585a0a620a116c23b1aea6ec4c3733d77513204bca244d5ed8f4245cfa7d5f065441fbcb6d4979a2b3439777b6bcd7a03379367ac88ef4fe1aabdb2b6bf406c6af5461a25e15b2767d381ce8f21070454909d6a2e1f20d2d84924e5d9931aaab5f849257bee49c6157c56a5071089b23ba28152b4be4854d377a4256303a48d61b5c1d175e695a88800a1b0cdf4c7cf86eef5cd9022d6f83f9c3e318c78708da80d72a3e8012861afb22e09caa8c1428948965ac6b629a9a807ae4d9ccb0e19a5792dc6e19ecf0045489b250d65951c4dbaf64d0c813dc1c39820e69fe6867b0a64cad1359102925d0cf6720343551ab98d23546c63c8f63e7974e8cd7f63802d05d054006f78031e8134efb1f629b1330c0bdbba2ca9f2207a6d4cf27c04aca9722316f7676656561fd12be26fa3987624a3bba1c43ad6eae4621725f040c60f231d0e9ab1f023701c600f41e2c91440d54ce30a6409a85d9d7e400d6bfe7361091470f96e135bf92e4b3034d31dd9a1a3345e9deec2bdef99af6643dbb7a3a4293a51a9b443953243a06a1168ab3c907bcc1a1f7d07f3882d0e48196cf0eda75abe37601f7fa8e867e6552c947883c36140f10cb42130811a5d74fcd9b0f6ee236104e4680a641624532ed706020a2bd41004c34d7a83970b6e209978278b19927a429f127fffffdba243763a43b9cb8db59baa4f19f1eb19d580a8ecb8e87d70635002567864b4260a98865c2c40c8cc100713c50d2359d38257462ad3aaec9f4e19d462147a5f0732aea711b7c7c03f888bc70df0767864b1fb79d6819c342a1e39f9a9271980e0d57fb6d7d6947336c61f011efcc110a7f4428e4499da71b544fa220ba9d8bee14d15f55a4cf67c27a9222a17a079cb1c21122234de87f7c15b7ed27703e7ccc3f1c6fe13e661484deda398b3477de532071f2c8d3b1308b27a7deeb829ddb652d246f7535a5f4ecb50349b812e61b96daeab1d224e311b848c52a4e39f9fc5958b386b6d98a2983097167130d3b9b62037b9f275f10c8b07564f841fe3b2f272c520b38c99ab3be5ada72ebb2379fe58924a9858503977b360b873f0b966654c36970f9c5149b7f16639cf9222814157efab198a137eeaecfb5ec5a2733e1298e803e99ad97170a9b17ff320203025fdd8dbb242556201764836de8632e176f60f9720f0dafde309f9f42a78e9a378f756ae4c1c055b184afc1e76128f0b26ed2e731380e8e97f6cedd3fe1601edf8ae2cabf4da00294b3a035120b0dc36077b433b3910004e8ae2ff5d03bf6fa445cf9f432e5efb5995dc2f06523933da1ce4a8b18423c0b3db421dba1d7b1fd8e7f69df26f762fc2b6c47dc34d643716dfa6cea734b86a7a11f2ea0aa57242c861b9f04b3cb6100ce80c97e100cdf926547947b183450642794e0333176b7997c455ce0d835a1cd2efc0340e868d88cfe4ac4b85324baf9f3b984c7e70a71bf545a80c470a0d08eb58224ae26b2cc2bd192c7dcb244c08b4491b6826d8bc79903f85ef3b203d74f21e8c95a09d7102c78e9bd691e8c4db00d0385d2c3f23b22d800b0b688997a190199738b27e9c146531fad88e619bb524e9e6403a3b11b76a87631b76bbb312b0f00a4d12d582f40660ed75a062b7dc584c0210696e5ace97eceb8558ffe5938e183ada62b384eaef1dbfb74aa55e66d574a484103dc4101da001786b93de5eb53c9cc19705bc36591c76ef0a3f5f33e789c72d49657edf56d6921998a0b1d3b74b410c41d203825c1d4c0bf86021f05e89d752459058cbc6a441f32a0ebaf9c71e1ae8b79c15b7427de3811f9b7865837453877c4870cca40774a539e39101a12ff686cac4a3599fe942e3fa169b7c9cb45d735fb958f81c2aac1cebe40dc6d5fdac9ded4b6e0643e44cc0be78f9e3bf07001f3dc70f96a9ce4b1d5e87e9ee31a4b0bf8031d10cc1545739e50809667960c9aed7d3b05e81c113b64ca8f1c38950d1c143f984ae039db00c83a0f1aef3ee1e2a8b1149de70e9c1620f7d4c61b4bd4342a05b3171d8d0e28b4f6a034328482a7b861eb471f23458e091af3adfa7a4757dd2367b63eec7b21009838657c235d5c9abeaf627081184708665780d7dc5ffc02da4d9a8add4659a309ccb52788b7234f28c040cb3f98d8cda6f2f0cc87f6eeec978c208d4a2c9a0c064b566a7085e9255b60a04d19a4238cc0b340194b06e35936f7a35887fa119ae10ce5102c4c10de907f9930dc29ca22dc9dfd28faf8521e58b9536ef633da0ba03efbcdee0550988ad42058607dcd7e2cdaa99077e157c3618100e371f3f4d186fb8f4678340ed40f8bfb32f7ddef9786d5f71abd1f51dc65982c64bb18c9bb066ca67f864f11cdd85017f4118237b739ff5200a781e8e13902566f95e22424606eecaeca08de1c82f2a7e80ee05dfc6dbadd94f08bb5eb237f6eccc2c47d2a2546dfb4f78223e1836e3a24333b37dbdba7d323b233a50f4b1c570d0eae553c0aef8ff05bc5379c76631f0f24d7378752706f81c9cd79e6a984d650f43e4b59f44d43427378a726a360835c03122bc35bbcf7ae47cdc32da9c4082ff00e7101fc1d4fee33375ee7239e0f7ed561af1694ee8ceae30e9bff356bbf3013e8815a8666c8dba44215e7b7a0e86f69fce3a581c24e9842d1bfc2cefef615346db0739a2e67391e8c23142386ce675276777257dc6dfa050e216aa17a6c09d921027987f6dca1cf11c0ae7abe7429461f209839cc13ae9d3dc2f0766482f8f8af3024a1c9286affd481d27eaea7d00e3fb323b9d8aa930b3c980e1fe466d2f680f8e0534080d519f1c18b5afc63bc086e2186355eda77a15ee7d43864ba49c5815f7fc634666e2b31beb443c15e40b1bb4b0dbc5c10ea1f24d5f514f7f354122726b6621cc19aa07e3e2cedbfe9620e5762aa88c0f284d43aeaf283ce779ad0a06979be8a8b8f41970fb278b68dc0fd9c2d14e6a9a1489b83ec4bebcdd7f8a849e49b7701bbf6350ca7a1bd0c5cce7d34a5c23525fe4cc32dabd83705d8492ace08292e9d8626cbf87c11375ec5b158c20804cb621c292bf2b110665063a20309752515056c2f48033361db68d97fd5504f84836f0a56abf0bb920f12aba6abe2226cf7fc8a8fbbac09c8b31c6ccad2dc6fcd5849d870d924abb0c0d89f3de475b4c1fd7b113f913cfb2d4901bad24b3518970a049ed058979086deae7cd9551ead4adc6e31e0547237d84c20bfcfad412d51382ea60bd9cfeed343f1a38a38341965b944b649f1cfdba2a9cff2ee6baf0ae836ecd48024d9919f329920c4ac65b3a0fcc85a6df02826ed8ad02a9c00f7093a504ee3b1f2ba92923c9651b229e0d452ac98f7f4e1465004ba7c58f4318b3afb46b786dac61ee5f9de665b2224a953a01bf3e7bccb5945c14521f03a7b7e6c027b2b5a6055bc7c35bb4f8dff0347781eef7c48ff37260873047eb353a501f601182646c0b98f3263f92ec2f0eca189bfae6d08c6ab972448728431a1475bab095b0f0331abcc83831bf8ecac52889cc1fa8017d458326c2f4df7057c649776a6959a723dc2e04f72e8fe9e9b040440fee53b4cd972d1df96fde30eaa187ea267825fea8b61ec67d541c01037db7e8529c497fe9a14dd3669a312f89844e998ee4af5d25d5fe396ee0eb432beab53afa9fd384c412b53ac200bc4f1973a8d3006e62ff07c821c2845c8b04234f63483224ede35e2d533935ebda751da22ac6343e3e25568289769a84eae252c401705aebd31234781223a2555f8f9a8246712b17637f6d193172c345f6f520873952b9e098a5631855f0223a6d19db22281ef4ef6bc3d37c169da9f8892fe9b525e756637ed605e902c90f7f3b29e6d4913e8ca1d929e36edae28758d1dd73214f356764cf31fef48ea9dd1748d1c1162a5a42a2745b77f542f238f047d2b1b9eb885d7dc4bd402222a62ee6c03c05305d3e6184085b6a338e35a3d5108cf95b2f184fda3debc4c153200a9cde374ef10a1b2aa0ff5f0a792c8d42486b433ccb62f003f5272f00b4fbf6340c6cbba7c5c50c75d03046426d47fe29f4f7f06aa64d2ac540ff9a150ef01c487f857990dff510f7bd54a13e35ea16f7ccacd3861c22f3371d39668e5f00d6c7a82e4eb743380143631a10e48705d2e702d66c48b4108ac5fb9b2e5cfd5a01d707158ae416f5cb5eeea81451dc8b641b6604515b88f6b940ae254bf4587501d847bee9eca54f151400d039bdc9d375b6c7ef8174dd4f793300a3860a787540f82c09f014906c714d8852f393759c3ab55458b8293650cb8886a60301df4cb7c1076f71713c53e4db0d7fe6433b15f40cc269dfbc40186f0e364430e8b7d19fe86ec02b1983dbca702ebc2563c4756921d03ba913e897164e7216cbf90147832134387ffa104519ca76aaaf873630f1a4e39740decd24f85514228708ecd597413a096fa073a2dbdadc9ee0f078667154d10cb172df9158d6e32770896be2b783b289aa40f72f4d24e7b4be53dcfd21625bd15c0a74dc4370cf8683ab3218d8dadaee3d8d59908560ca68f50e860b6acef0d453f8e20de210a89856079b88315788425e1e52fb9bf072e684f6102081e06a02c80eb2df8e37c25502817f104acf2336bb4b64fe51c12e73a22469ebb157006597f90bb6584889a975cc65f03b86be0b80471dff850661f243b126c83db741ff70dddcb197be9717a59d51b9701c136f590973318fd2c8367639cca5342c3d3fc5d68feac316f9e777ecb25e14e4fec34d69c2fd95ed0e1a65ca9ba871418c0a90040f6d087bc430ab034886bc4b7a2355432b93baec160e89a763a7650e48bf4d5e8a11b4184c2bbccf584c809b319b194438baf37f49fcf3d26ce5aea22af60f963a93df3572c28d789c54da3144882c9fe63a8d8e5f06291492ee1f73f7c4f8e33117ace2be40d63e74366194702dd3d96f7650df65e9d2a9ce9ba2a00887cd11e5ca537fee370e2d7481a17ca3a84604fa1dd1a1cb0046a77a579e8d51d261d8f5ab70a6fb93b2c0c25ff295f99e9eb63e2060f1a6665eab0f0fe76742a535cc895046611d5b779887e322d24bd3b076f44cc90dc11602517fd042433100f00f4d64d45040a1d8779523fa7eac6e1e90eac72bcc8d257d05ba2f3f5cfe3ed65256bfaab55caba1547526ad1be6c1b99eaa878d0f374ad5cfcc060f00970d4b2436fd82cc46183c7d830a2dff8c8499393c957b19b7b0f64e4555a39a3526e9811e4c28c8757e1a1dd9187247541a3b63d5b4ed338bd9b0af9952dc2f8f614224f5311a2fa4ee7a10e73451773d2488f80f7a17562968b2208e813e07579ff1c023f317be4d1941b97504e4140d901e55e020f13e3749559b1769af89809f3e972ab74478b0ccebb23c584c8f2a016c2b41861e178025d52cc5eecb111ce0544af86617ba5649f79b575c3d19f42311cb0d14457561ca28a1de43c2ac110c2a7602dc4ff1b679dd641f567ed3b9918ee3a1eb906d23e1915e900b11b23d08b31547ce0ff23ebcb05a59a1bed9ee1c1f797210322b4e16323a0f595ed50ba4582d7475a0fdabe5dc81649835db099ab203f54475ea5b3341ac0d11d0fb513dfb3301eaadd16a1e68ac7db1b67af6c8e5dbed1ff18be9e653cf179fc53183654da6fabe627c41633fb82569db301ec3f6a0871e470659ac2d9127889734086ba6266a638ade10a47ac8edd791e55077e11a10f9820b7802c877d15b2b3131d64da76ffb9dc431988e0444bc5bce97be2e65dc560b40795768b3865da5ff9fe5b768c7d5970a13d1a9c5777686b2f56518279118102abfc39a41320c3e8acc1df3a574fb5aae71d28a2572542ce082981da933c9a975a8573307a41f2c76a0d225f71a84c17e1e228ac3f6a1f93d250fced7132b0c2d379d48574ead99b89d2d00592c456d59462f3391fca88d4395b9c55e76fa8f62050298995fe212dab437fea7751c7d925b6617484cd5eb43bda330c210d2babc9d4032992450daefeadb61ea031537f015f5de08b5ca7e00abddc538789ef837a674826e7a094c373ec8e893143ff46db0a6dc9bb08f59adf1da748562da0d0d230af6977e4196ad2670c1afff201e0e6f43f7788f0ad82621a3c00cf02879f98b4117ea1584ca9db0654caf9354827afab5b24f07b09bdfcc82ba121067139795d2f7cb25d0afcbb93c290f52624450643e6d537c08076c740f8dec75785ef797fe13bb0c3f03d6eb2d85c5794bb2ecb145c29fc67b62d7a3625beeed45d687fba608fb20b51617243d540c1070af775e71459f6f0f96695a9ccc9c8661696a4c6e23d1ac056e2fb439af2144ec828d0a12231821663de6c2d58b4f422b465c0054ad55208087f42d4ee18868a5500a20e025886b2fb921779d3d785ce3d0184a0221e2fbbe50f8779afe6dfc62306709ba4fe165b389c91822a51eb30dfd051d14ee694339bec0d30879d0bde74c3c3aed2e78bb6ef19e0fbe23b310d2f6e28dc1c92f26261c22b9fc61c69252201fc38aa2437e61670317d060d667e07f27916b488621b9c94c666085b4be68998115c248c01521000ed30e03be3bec336763f0c0d4d552a658eab3d470415f4f0c77bb29df80b5c3e99168319b6630db0d01979ac130becc781f3bf4c395b8bea74e2373c89b19b234f55ebe1ad8c5a0ef7f4ebc5c17cd0388ecb3374a0cdb0829c96bc8972d695014fdc1ddef1cf435975c1ef3ac7e93af8ad832fbc7f1dea5006c7bca66a0c9e78e59c17ea3c50587862132cbbaed01d3e86c73aac661e003d2674a8e41c8e7e39eb0c3dcb8899ebd166f74191926e550eec404da0bf5f019f158206b8f79efa08024044d9cc6c697c9c6d4a14287e6352ba93f9d5b991ee8f44fcdbf4a454e76237095c6e01e6a43c7e575c95e13a4b35fe377f79cdd614923c1ebcaa27b5684a236142e0dc4f1de146ebd96406a42003b2239c80fc48271d43b961e885d3d7595e149dc7387bdc758ebdaccdb743022df3e5454595e8eca04c2b6711f20743077c48733380e2e557ddabf21464673551b97e6882258ad4a5d86de9cdce94c5eba1063593d9ce01a379f7803978a16377d4fb40bbf4c084b572526327ced816ed5ca5931132839283cae0665e8cb85cf70bcd8d70784b3f6be4e012ebaf8ed44c7c89ed29828bcba0fd64bd213998c122b77f005265536b6db525c005e94b6b2de038d8aa66c3d299bc3e66295768984fda24aed3096c4a5896e2edc5bb1891ade3705e4f11412e4543c5f4b845805cffdfc980aa2acb799a7f4b1ae23480cd9ad70979cdcc0857ab218aa424d67256a7f5c5c2fee00e54cd85270332b3780d09c97b81db032d9fb418960fbcd7d5d63572c1e8500fd8bf2bd9f1d8b999a0a16b73ca0ae8b461e6c4dbd38d3c7a0279c7665fd7ba17d88ac113f3b79a4dfe73f994b4779235db08ddc59734c8242bce09e59207aaeb40ef9d6f66dc2df505012216b024d39a752e437776069004e0418d9a598a7c703c11b7fa964ad2110f615058a55b1a482b145293a2878d92f82682b09345a8a94d8d657df1915c6a778d46e2320e78beed80b7b478a0bd436822f5f987d2f8600c2494865ca84de67af03c319a19c06a706129137f95c49a5d191a46e507b8b44a5c9f8efb833fa207b0dee8d0be5d11ed1dbbb083450c7f6bd517b34566ffa4793beb0a8cc9d87c8160c4554295719e92c47e06d3c338911f33294aa147621e19a715cd86d4e279bd0f75be5dea179147b414d44a3ddb264ed559f85e73d006419b19a5f32afb8158d13ecc05e605012c7bbd26a9edce02a7b8adf15a5a775d3173caf7596338ad3072ebaa586f93a4a3c68c602d4fee6a770b9733ae4cca5d45ad7d94f331d3e7352049081bcb2e0f5569e7b97efe33ed73503c38595659afb2eea465d74145aa09baacd56b42a9472011761ba669aab829aaf7cd1590813ecbe44008d255c3aa0132cc79989e1ed592010d335ecc5e59bcebcb584a1ba5864e79fd929e09f00d63b11b72b92b80b77823b26b117e250fa6cd1bfc328905d67419ab31e9bc7cc57ea7fb276cacef0f5d03b1a557e68ecd270d63a5cdfe3ef0928f307b8242808207ba6691a9f8b04d8d682d379875f3b827c8954d123392badecccddc5b3b23d647cf431ba7cd4894ac33c12b5356dbd543f53ee5c4fe9512bd018604eec88524519d4a8ee47ad9489a143cf209e988641fad0a9b38c1335aabf4b739b5017fa20285d5ac50bc17bf87382d5e8de61f046672b9b12ba7147e9a9d337ef381ab3079276bdc8c0946c955f5d8ac36cc71327660779258da3eed2abe521fca31bbaeffc7809c3991612dd6cd630e72a330185812453b703145265210a9256b1b711e21381d11b41692319c31a4872f19c4f88f5e6d6e5e7e01c5bbb767ca3f076b737bb894962eb6b923b82aac900548147fcc0c6d7b1e65b1b6ba483845197d875d90e9d66041c3b3cd7de2d28d8a954fc0818c4b20630f6c73b9f9ed7374457609ae6d6e16dc875ab42afabb026c2d79c6657ddec293532da9e815a86051e7fa8b6d0cf954ec963cceb9e03fa39d2e372c3357e02c5dd1b91cae10d2addd609cced16671fa20495b29a77835bd380aa0cee5a85bc2408b4a3a01dd1e48c249405d700bbe1f365f087eef40d3a4f7d5b9bdf5a386f704663ebed4de70c245ea71f34443340d3b8cf8a1726017ab4085a6d307e843d41d5f2e49906d04a8ce7df613258bc0f71c8d0ab5752ebc691a7bca7718e83ffb7bbb5f57ccea0e4d4d4da5e740ad0c1ab06a54a5c0f5dd769a6d8f3a900d3ca83ca4804aa966b44e7eed5a55450fb288067efbb94dbb4788cf2826328bae0b1b25b38d51987281407c08214a21583cfa199cc54223c6ffc5187af70a90451048e756cf96521f6bd45b5e2c98f812d77a40a8aef89d0fa87b97293b8a6407f06d87c5656592bd623293c34f99d8a5b744a36679d112c92eddc4bc0994f7fac718fe2af55b388d711f03f3b06831f3e66922e3f862b733591d7951be19e043a77651049e44bd2b032cb8a3c86a45f2c50a27d8a3fe8bfb60c321d4bf1e143f05190ca1060898701d769e35c1fc889fec425e548a619b095438ebf1915d4529ea8b88ad8b75386e47099448671c92c6f06a102c4023f230e6d095038659df9ec3a8883ee57e6fa68b40dac98a120d3a00e4bd6d3369ed7eda7761f9101da04eff433ff9af4ffbf52fd80dd6f05f220d105eccbd70a107db3fef19ac56400ab333b448ce27bbd77f4b5500bbbf466c0b76993252c373244d016e16b13c8609e720304f9537894a0aa99e0abaf59463912c4047e2176c6d695ec4fa1c93d21c27dd527645d6d2a846f5ddb810358efb72539108c8894843bfef3066da6ab170535745c0b1041162e04ae81af330be21aa0ddfed7d59cffed2b8a1673af89eebaf3b307e9a429ea76bd5d51c59c711443a21377a518c3b304652805a17a407d7f49592ebb63b945b536099aeeb5f21f117a4a7e342aeeeb833ab239fa35f12c00c59e6440c93554e3515ea77d0dff69cd6b48a55acc60cee599c18caa2a73fab6ea405efad31919bd401f6e902836210192fdf4b2ac4a1f4e66e3c1ca17ecc8ab52c4c25ea7f2aaba9a8e3c9d3221b2d0ac68d9fb289f43a6c96fe1f711fb32ceb0305f7ff62025f1549b779f4862e07c12e1557f9d40f56227f7dc1cf3a08eea6537068e4f3458b61ac8bf47db94d996c092415367b4a6b7af06b598e693dd4580225fa83c7e5e9830eeae9f566e12e2dd281081db3f02ae0f5622fbb28e167aefd3bc52630a0102455e603c7113f37d051357a33254bad34856a0c6cd44cad8e5a7569c46a5d59c8587d51c7bda30a7cd9daaf49e1a36bfd675264c883a23306a070cc690db61a5506d2bf742008634a02dc940a4bf931609cb644e3cc59d969643cfa46111a352e4d12fe435df2e8499206645cd9054ead001dd707c0f51a3e52d1bfa38d93000b2f03b2e73435229ae2a87b5403fcc4c256285796763fc9196caa63886bc30638c0127eaa14ea2a5d60352a2e2c7ce5f1e34efd1c3617fe0ef24269f62b8bce8aabb8ba6a7c8cc2079d14500395794b7d9e46973d562a5c1f71859b71aa095dc3a6f80178c8c59b5ed78adaebd7968643707088b968b33b1821327eeefd38ba08a79f373ae93707f3c6226a23e9a9bf9556cc9354a2b0a84b084eb82bceee23057fc159d128759fab3fda75519dc049cebe0b871a21a5c77c22f0974654613ff7a0559a4c2c6732313b253b7223b345a0970979a9e236da1d410efc816c02bb6909c8f893a44afda88e4cab5151926a2408b754f8c1dd340f6ee739694bc70891d5ad47e547aface76a6b29cf1844855dbd254f7c7d0b10ce7feac0d9b6a6b04500dff1ccdca496e998ab9e8497b2b94dcd9a58b8eaa903a52da46760dd46730459d4ab89abb30fbf0e65bb4abbb6f84e9e918cc2e15810825f2e2876520fae1456516c98abc00d2e0f40638dbfa81b3f166648c38b91692b1b4d547190a0b981a4d7577dd94e69d3bf6e3fc79f23fd6a58a1d8a5c8674c383692d17ddf8ddf5b7eba1c8fd5d159032c3025c4d82a3469fdda9ab52464f9bdadc0a2ba8e6f4a0ec372b1c889b35e7ab099593b35436c6b65be13319357e1a2541bbc27d27853689171cb0ee89b786b4ca371059c52fc51de09ec0a9677d0a4e52ca4f1688827397d9ab359c7bc41f05fdd530a185682496b1080caa316143a96832180a0d1cee822c0268374b9ce14fc2a7b697edc8354dedf51fb8f6fa24ff31ac76b94bf71fdb763b05468ceab1ed7a73a95cf7400fd2d96e82c2787f0e25d70e02fc2c4924c212995aaf060f0cf2bfae0b3e0e4b31d8b2180ddbe9305d4c0c4847596f08a753fdd5e30398d5a9c1d4d84dbecb732220553caee4f950745dd5be3d032cc871b834ab7bf9ae194ae394fa99140a5a754a2d20c0d7b6a36ed7baf1f0a77c4ed4470bfc588c9e7bd9b6969dc8d36ec1f7e763f79057077dc995240d88ed8c45f91b129a8f764eaac4ae05205e296377832f1ca750c6712036cad6a8263157f53d801956aec48c2460277fa65f054052b14a05ddbbc690fddf3a489b5a3445adcfad14a91d8724f26a594c5ed84f38ec3be7740c1fa7a884f9b4f62505b4715bac7538197b5c02c3307c1b8c9fac9c0476d85decb2e605b15782e6cf6f0f08aa7f5291e3942a2634106575a9be2619055a95c8e84a7ff2ece17e863f5ab3fc5dd6cf5bc2e29e713fe6b18bda72ee02fbea902511dfbb8896198c8f83a04f51e5d3247cd227ee8f34e3a15cf0126aa1ab677ccc0ce4252390f770649d765ec4ee3af9ea9243eeccfe5bc68b24a56e2fa337da06c2fd6fc8b050915eb2427bf2561d67c78ced91f331201c5e3d8fd3ec668cb596cb9c3415a0224edf24a554044f2a4b09b6192f9efd2134104228a0e5276164e91e2ba281452445e542d6a42bb141b32013f58715c87866ba4dce603e416cf04dc7f0921127d66cdc4762a6bc1b89ab9a339f78da246b21f0197a0677e110c8bf8cfae19034fed838ef46e769b08a9cbc3f257064f1382d81e94843fb426bd79d84126f62bf44f0514dc232a8991d6a0b310a965d85bb4e61c93aa7ecf49cf695a7a9f0f4bbb637ff87a318594c76af4b4a76f3839bb3fab481a3071d5701f4f1a711937684034dad3312993233dcd01610e42bfbcbd763002a2aa3bed1fa33cb8d5376ce3f982d5692d8df4a9e271f7cfbec2e29314856c38cc1548897b33e23b51880b43627fae33727172fe103ae307666e986391aa82c22e5ce297a4a828744c222f5ab513b6488cc1e698b3ef969cb416543c25e91ea728e991b196ee675e7328e58d7ad7986cc62fd6101ce64e2f2cc5968997f0e7a11b8fd08376a3add3d9694b3df95f5247ee692a8cefa5ed02919a7efc8cd2e11843b179c483605f97047f9233f272b52f7774141df8642c9b58f9ce9862b9df609208065ef4cd8ba296a229ea587ad829d0e9548e467223f5afc094c3ac9ac527146d511fd4626a3e8cc153c0b65c61c83234fa2143ca9eaeccb2af601c0ea06f5aaa5110dd3200f154f792a70a97118b1a3f289cbe05084af962b325b1280bcfdf08a837d7044ba544df7a1a482710e019bba7541a15de378b5524a5e52c4b117a4b11e77213eeada3d4432ced2af16402f4abef62ab1cdbf647cc24cb1a909ea4a060b9a75c44181609472fe721e6352d8f08dc39c9ec56d2b7400143fb99f97932ad4b345c7a1283b14e2a34eb8f874d17b9f45024c8dc3537c97af4b107c624039d87aa3590ad9d0a6a7257063e692f8d2b723ed6c8cdd4e2594806d95fb83e7fbd2bf705954d5b2c959ff9e2b048a6b2be687dfe7a43ee052e4b9b58953f53c567914c65df0b8795bfcb636c76d6bed2e6ff165fd0c98bb4ffff7e9b0c052c63db59288359c5bb7059a470497dfeffae0c0a28d3b6b34c0ed38b7361594873f1fafefb4dd914d4a76d456fc47470e5bd40f6a25cab701002c82ac54bfae79f776558d09f6c14bd47ee852e4b1b589537b3c5b1980cb27d69fdfc799b9c5b88aff27f7d84de161e4a8503f4489865faf7bf373d70e01c17c9543797fefae75d7a28ecc63658a20753e75d200bdd5cbcbfffbca93705b5655bacea81c9b961a0322e34761bb2223b93e15d5016695f9affbfef92bdc098dbca52f94c0d7751594a4d17bdf5ffe71dc3a2a00f1e3fb2589e987a4c217f1769bd8ce7a1e0e683401e6e312f6369eee59e8a8ce7f1c759146bb65761d8ce74bc2306ad0e81ed430233bdfe36c126f092174963e8c91a03a141c42b472f03fd0a33db87a856b81fe2703a2da67253e150c6058d646a7fbff916c332be662d5e1c33f14eb811e72a72929009b7bdb8539422ae0c31b01969818628efccd5c2ec7d173c2853561a2b8a2ffdaad882fd0e577de86e6e869e803c26cc42dc9bd1a11a2dad4edafcb440d6db4163b4b09d61181d47c1bf9c8540cad30300b3d829a5dba43c1d553230c5cf4c44b8207107431b8b1df8baa871b358d3e13c4d61dfe372b29f325b194860e8e2592626abaf450990833ed60a627603bbafdbe9484216a1fa40d8d2740a2a397f52e7dd2c6ff9c22c8b73bfacf52b337ab9dca8074ebdf3c48cc3ba1105b9c42503a40f66b6fe724217409b1dfee2430863c864d9e97ef10b8f4f030b82d4cadf23a4ffe3cd4602134c60e6a3f907a83d3f6aeda5ac6e5741f0289c319b01c6263050b277d0f600eddc36226e94aa2e6860cc650925150ec59b53294899ed64741422aafe5b0e47c8118f13e7b2a77e732809dc17aec952179c00e862f8c036f85190b81fc8dd39065cf98aa667102ec571d0c225c778d45c90c87b627c2dc735d0cc0e2dbc6d6e6ef43d13b7515c2844898113ec8a0743028a8c2b40e166e6e0f04f0804507c75a00426287226c768ccf27830e6096732d9972e832813e67f5dc0d3be02aff1a12f17c4c6acc10b3a02f76575acf458ec98f313228a61a6d813ea48d7e8c2b03b3853b14250d49a8fa1a260fcfa518bc30bce508b45d71b52492633318a3b01993289eb0f4397f7ce08bdab4b00d4b0a1d23b240495c1f6a107d265ef44e7b8aee67571485ea230fe5888c75fdd91c34164e7bd896f6c7fbe6479251341f844149172b5f20ca6af0e77660947335530d05aa80fd7baec12f8468603269488bd70c5962c0e031714d61a68801216a3021b2d317341c083596594e2d05de0b4a72f26a9f0b18d03fa3692c0c2e00b2580bc646136bedc6ba07f7178e5ea6cb8491d1df3ea4af20a3acfe8cdc0e002dc39f5d7cf7f3d1834bf192b8bf87eb64eea2ccd247e34e08f32acdb30c5f0c9c3e142c09d7b728afc31d2231b3ec1031a607ce7283be54aec768816df45341cade5c78a324e23afdca9c705e558995a505ebb00ada0374a0aa41c78cd58ab05037798125ddafd13d151914a159832ffd54c82a1f29137af38bbe892243604a72212a4df02d44200d96c1bda6d288d45023212107c38556b5a0fc34dd37f3e33877b900c2eff3debdc159e98b881e856c32a985a9289d82fcb40c90ca3214d1a44166f9d3a209676ca8f8ffc74d050b179b20c437d27b03ed804fc4bc74d800c99ee189d2fd614603b5d35e7ec3293c08a935faa96c70462904bb39d590a3f8e7a37a721904430fd621288782114c8ae30a824a379a735cbbcdc1c8a860a1593e6c384dac1a7c5abc5dc541273ebfb0649a34508af12e9ae30624416560a6631feb0bfb51809b7d31482e2c9d1a730173aef164852586eda4b528e3314476406725a248e6045015907c2d21135d8f0d6d7dd9998d6510adf4653d4165a7f02457f569f0623f7c171daa1a9c0856f1030bae69714a153e03a680221114d6ba50c9edf5bd57c7f62073ad2a508c35b51100d61eb23f44c53122d6cc64eb3ae0cdddc6a292aa6c280db4b688bd418a8c16daa6cd340fbe94483d4422c9368b54fb140779e374bd64a2f4c0c088074b3408da4e38a9e14c41cf7b56014f71e741f1aa610cc188202b03667f2d3ebfd61838fa78eb206e2ccf002a10d54a028d86e1a9ad86d18e160307fb903eb026560fa524b0a8a09f457e21790e9402405aed90c790e19ace49da0adf4df020de22e7afde87835c5a7b771ac1b7113aa7a6d6886a2a1d3c4715af90e16955aa3236f201526ce21230f3100d5e27483ce0ce0dc6b0a4d7e2488d0b000ba61b7c3839eb0bf83ea678a6928804e7da93059503ddd91f1e46026a385264cf717a7c0cd2e61b37ea6f374eb3fd189e3262e91ff02ac673adfb8e4957d32c47de740e075f4365c50545929d38f2f19c4cbb1c3d049aeda9e5b494f09bf5f9dbd5f22bce66276d9191265d2d00013eb435c92f35306c089875e61290d965538df08a43c32b1218e2e5a244f6431adc163b8a2b475a51382cb600bf78294d44fc655c62b8a8a977e5f191afa1257e471c4125c00de8e401cee7ba2170f7ad134908eb7fdfa7a92656a0d4493e43c35f0e6914d42d0e30951f8b5b6d073c64119ef553485188daf4227aca8739c4506e85f38978e32aff740247e72208ca3f4ed4de7334d5bb29634d03bea3ab9aac44676594c41aa0104e1bf3fc0761b61be6cf27deab505522ff8507e39324a0846e1f0c04143b8750ca520e95bd5329157211d3ed15199594dbc55758a9ca9a9e858273d6e13ff62a944e8173377a87f4c78796d61dc09abba47ae8d84323ecd94cff6650bd3e4a472be133067ab785d72262bf9aaca18eeaa82820372d5f8d3be0deba37d20109d4dfc3f69e28a45449c16d9a55ef371fb07227eac8051d22a83ac5cf347af19102b218fe1211f15088612db1d7ab93c27597adbc553119d8d20a5014122d109173b1995691a2398c905427229694edb16a5b495b7204cb8027ef34c2d51b39193eacb105bdcc28a6f108b71c5fbe04bfad02abe2700ade8bba4add370b239a05edfb4578f155589327d6d46b505c6d5205624877df1eb06bff0a57ba8226a95099000bcdb2162d179433a3018917f706b525a339fda60f54a32f5054e7db52ff1817dd7c92594fdd276177f91410b221e0395f2bc1f8629462c00c2095d14ab8242997c96d5249212171d98ebd2b3d044561288c7f54c9ad9e45907d4b59e8296df318792f727a71fa6282218adeac14ce2e6c6618a56abba30dbfee3a6c80d7a5ecd2e1346731513c3dbc3ca44a612538b38413f7168cfc192cc65680637f81d599e3a5fdf24688d29032f6c7fb4f7344ccd4035fc0535775a5d370b35b5949a1e22d0a9ec675e9015234201101aff08f45e62d7fbae24bd06eb642b14840417391f25a7aeae4490527b260f55b4b0fb8bd6288741ba1a5dfe0834fa10c0e734a8b4409929987745961d85706c0fcd540a212b7e136a0354ac4d30ba5d94d466559bfca90bd625b5e36daee76f60446e06fed0d0c2d449e04ff6bfa962ea6bf0030b3e94afe27d150a5c6a03d96ef3e188ac803465201a263658599c97e423caecbb980439f6359027292a64414571d8c18fef3e62fc2e9455c86631450fc8371e1ea300fb54ca8f82fb5b791ba425560875655fe26d1b46692caecb37993abc6d58801d30b0e0cc88427d82bbf327674db57cff4cfd5394223eb3c1a9d884b2f699a500003812f334f53bc893a69d59f46a283e5afb86d14413cc0e7e06e5377c47c8c881493255b3e0215a0afc1a10523911560834f43b298bded7550ada710fad3d553d0ec09e6cbbb38ea12620349a8babde71ead7bbb448098359c5a47272e5378a71a03e37c06df4a2761b4c9ab0e2d62a2bdb6d42e5238e829d1fb961991da9e87031b464010d20677f0ff194787031f4583119f3d931e4633ca01620ef49bbce6313799d28d020dfe853e459f6a3848fd59d22c3e2a37a809913a7380a774d47152e40171ee4c8695b98e210d15995824b012e67457c6f9e07529e34f5de554877d2f4dcd86ef14e2b67621cc5b610f01653a91ca736ded44a19f99b27403834de60be46be7318203078344ea032b48e227db8476fa2d5e795297985750c05381c28c112e7a9ad81c7b968c2e71280b9935aced3ff8f9b26cae62cd8663a09b601606a69f8dd58184e1938e80ac7330fd3e5d80834b2251350112728f69c137b61ede395a0c80ab408f664a0ab40af51183b6425c2a8fc834f987513817e089fed1bd2c7006ce1ccb11924c79660f73fb6c1fa4a1e5f094b0ee3b0c3aec4779d8cdb7267b3483e66bac980936d7f93e68cec3bd4d917f4ced9cf134b11e6740028214d0b3cafca96eb56a55c94d58222add6b4ab93923745dbcdaf9817da815b942469dfd167c26c56fa8a25dd2e41fbccd1473283bd5b65a296a7965238aa83ef3143f70f5da604b92c821ff70f6d4c4bf9fc518428ca3496f8986a22c25c65acb2e2f4d1e420a11d0ecec67e0f654f9b38a09915d006f0c2b8c4ed8cf009fdd8e82604ee8526030853ca3386ce3964c885bb7bdc8e94f7aa5e0a46bc7321d6f6c738162253c8fe649135efbf51b5f1738e8000f9d02f50b9e1c4feb6754368a9daa9870946c4e3cbd1c2389d84d19a15d469961017176b3bf9389ea18b141f67f2fa1ec8c63c8b7f5415cde30443e1eaee92f6473e8021948f5a6f2b861f15f2f46fe79a427fd3b71fd576f2f2dcca1367503e1b1a8588eaaf6785fc06c0f14351f6d67212159e6b8fa3696e0cc435c0f90b25f10b74b7087e8a1efa7f92250c688d1784a2103464096770931487be767b8b996b7cca4491da6339dc5ca3acdbbd8270942ad2185f78fae4cb6091411d0bd47f2c236ea970d3466a043de1c0caaa1b94752af6ffe59358f135467d0e15c83a4c0bd7e573839b03d5e99429279e8e8e95a153e2e02bbb95b5a2ab2e557b33447a2b1fc633d37d5a0108fa2007608a293ca04c9284414adc730a2b313741fe44095ad30c0c5d6265de0a81dd56126a62b3dd732fa13008bd71265810d6f147df230c6946b663e06ac2f77b9d7c99f0cba72084cb5716b510f205482d45c17d9938df1a100a55f96eca4f500af0683f9483790b331d98d3a296ac257020f6c805724d24ffaa268355129fc1a71168ea1458317cb3c494d503121d9166407f5d087820088c90a44622c8a0df429d15eab8376547d0a2f41653bf8090af7b2da5b70e7713fb16f4b48128a58ddb504fc3ef2fb1011f64347abe88cad0107c7c5cef4e3089e7ee544aab165e2bc611d3f359843476be5173be39288863eabac59efad0171b1f0dd283c2e65cb70ac27df3133d96c094a08b88c3a39932c00cdbb5a590ee8a411e35168645b0f9e7627f6fa23aed8bd5be3097e38c11e13280a80b7a7c18cf10ebf83e514cefd08ffaa2663f0b98f3a57a18f41c7ad4020dc6f5e69757063e1072e80f4a0cff9fdf284d1f3e44d1507c74d1531df0c594af5674e6081ef7414eea7f6741a343afe66b0b253d0ebdd176093d2a2410aef969949b7f7dd0af8643d9f8222b049bb3456ce36608f169e33be1beaae5312615c0e335f779d1bce7ffc2d6514d65f32c407fb0f38a6ece071d078293c35e17f819e5e718e1b0db33f3b3afa19f34ba1ae355b7456c584e04c0ff10873c6a3ac45e9f490706902302946f204f07014789c13f0973c986714bd113bc4a1741bfd5360e112652a820ce8cec8b5e0541ed005be3b52f510427f80ef383a80b6526a5c12358d869a2202313130650dcd317324615da6040d5c88f82637578a5a5b464ef1b042fcccafae4f2c870228ed6d2c9b7c5dc338d33de31078627c9a1234ecb0256e98d09fa4b7667098b5b1203f082d42f8a798fa115f65e0ef511dee73fbcccbf470d3aab50173389a2caf56e5487c00c6ec74600067200920792639389f2ffc544f1d7613626ad08e377b8826158ed155e45aaba2c3d473a2f6f1b8ded1ea59d26849311a0ccd65ac6e6e0c8923d3f99b8da19c6cece181b21e6b629994a6dd2f32b06898da4eb55ac546fc54dd4feaf62a3859293d6f4ff8c21b1782c4d2c6a74c50fdb8e4ba9fe5b4424996dec328c687cfd631b0ecba7c27ce7254e0413f940c484f4c7c401f349a618177230ba248bf4b3360c786052e224a20e02021f4678f30f1993f13346cb27573e5aa91be95083d0c5d3bd50bc5148772186a9750782f4d3cf0911e739baf5ee538083885c223f3454f05675737ebeb020df96f5133106f7540c37bc85409aea1e040561bc6a0861ac536ca7c0234f09793ce72d16b703544d941e4c3d03ea98be8b5510302c391df01b829d4d5d026102aaa24d3545b3ec80f49dd90592a5fb30565470797b78386599a193a87c0e74e8076de98f161ce0f73026af9cbdc0c8c95c0753c4c4646008be01ff7193ddbdc9967b4b296592019b086308a708e19cd37f4eaa69b55c901b2351187d8c2975204ec0392202cfee00b142ddbff45a6b1b4cebeac5df1f821a829944ab905a73abd607ed9056d35a472ee153f1045a86afca3e7b213b11f3922239215d6b0d5ddf0d2ac9911c082d824c15691ca9caee634c223dd14ee8aba4d9f565d2bd5e8f54732daf0ba9c2a893d80a399f084813e4ac507688d0845ae22322c8fb3e4b12be83b9db0ccf5a61f6d26775469fa0ac50db14fa44bbd031774a93955a0f1ca0bfffc630a66592eadf6a95e0e5bd38a2666e8ed7d17e5de7bbcf3ba256b4bfbfcffc3d8a871fb5b2eb40fbd3a79944bb509997a13023fcfd291233c9a3983cfcfdba569a0652e57ac17fe65290e03b59dd751e655dd4855d7eeb000c92dec625a4c4d4f73979455fb4c8941212b4ba9973ba94181f51a4fff6a63933cad67babfd6aebb5362a8a1975877e3c84af1d56095479f80b59e46a14797e7e8a24b8eef9905a0fabf0d0635189e8b148826b20baa2582610a00934849e33295cb1c8e7f9f94cf468fcf94d7a7efafcfcf9f92ec66df468e8e7fb187a447434a3516e54e6388f6afd76dc121388ebbc89d9839eef57a8cc6b5bbae8f95e65027131629c509993d9fc15a61519920aa3ffa68815312a5b8383b67e780f5a716e8e8ece394443385d8d966b933f5ac8850b726daa815c3e2746c66d55e673268cfe9c39de1c277eb2d7f1c9beab89a1d159edf688a313b732e53c240b4913d1b5e94caaae3e8c74040929ace33bfaa25314e664501a9d953179b8cbe7642e455f8b3e4686f42fcabea330ea739e207d8e1c1f5b0c5192cea7776b8c4fea72108415ba2a689840230541c8408687272f6178204c0fac2da44a05b90b25054e05e342e9f0dd60ad131a7031441939b513fc60c437874e1753c00431732a636608951450628c54778cb00943d5fa179b2bd844a159558a8278c677f05d7f36dd6eca82dffea6e8b7e76efc763966d89871a3e79099e9b6a0e93731de6389f92e662611d1a80df4073d9fd266d20f933bed9ea084e66fafb53c8a57f1283ce809f448ee4499d233fa307132f49c53869ecf6426adfe8339820f4820959b1377c4a9b022497c1cb307fd3da5c031cbccd7ce0124c97bd0df38f4fc3c8188b307fd7d41788dde359f9c320fbbeed0a17cb51c9bce0c9ba9a8ddcd0d9aa16cb51b3443b96a47a369519ef47523bb4d67868df69f8a7237da876ee4a2bff116585054e492a3ddf550767de38d1451be3657dd041335c6687f1bd99dca8859620d94197f6a82c8460e0afaa2aff1e14a54aa11141474ab915d1365d74536319387e7a987b26ba7f953ff4d7fa04d1e7e81b2addaa508659e3ce9ab953d8a57d1fe504f53ce03502bf33ccf07bd90100fcf15edae81b2eba0ec4d9387eb55beb6ea4947d3b10e923b4cc8f0293a8f922b43fbca278f63a812957ac671ecc9ae57d9354f6622e66bab9e5ab08e509c152299c1271a9fc5025d8bd9f548a4e66b8354addaf1fa918443fbd332b11c499a5e5054525def5e5d8d260fffab3da775e5e1cfe52e4ddf127da292271a7962b3d721b7dfd1fe375c4708c210df7bbd39a7b59fe7bdf4e779d7da7aaf67ef755d4b9fc4784efa7a0b6aa5d6291dbd36a9d39ae8a5943a21b157ef5f302fa9b049a9b5ae6bc337a15de2648e44e6c4397aa348b1d6b7e8bc644098788f2cf375fff57a75c08d6789f30e85063b168a92f9ba4fa4ca964cd8772985a26f1aba3e7625993ceeec42df21c8bc3461f759794e58ce69cc4226ec5a285d3facf32644d727ef92aead56927715e60e3441ae5584e7055e1c3141d244aab061072b50e46c3884d9314185d30cb6344410450f47785518a9ec4c61cd607d5268a1539f89568d169923bc5c29b6cc3011233921b9d6b798d0bb855bc17121d2677a91f6f7568d203fe8cb91acb03142ef793b838d16bdc92f0a1b2b9aac3a48a164ab0ef943b291628dea902ba0915466c91d3f642563526348954053b2e546ea0abd5fb82f0d5516244b4f3552b732248f9e6aa49250d1400ae9a946aa360212484f3552330c818234c6b06d7106b4610b28c02eb610a3c242f6e8a9660b225422d8820a972da40ca1c59d3130498403428806a7211c941f8270ad2b465003529a45095dd186cacf54d00d3e2264d9015d3185959e19a07eaeb0e9c013e5c9a703a494a99e2b76e0814543140f8e9de0ca8849bc22a3e448346cb08837e05851ab1976239a26aa845068228e0d51536112af481b9a5668681c006f211a543026f18ab4e1061519060fdf0e3cb30515ef86cf50a1c35592a1e9c3313235585a94e7011b2a94dced920395e264d59cd90108afc10c1a3f28d19ec815c6408691cd963066b67809ad90437aaad96245750519b4823b061996209481f4c8c0222083b608eb902b2baa0001192d604235a48f9e6ab408b14aa3c58791a6450724b4d4f0051176be108102700622765c7cf8124ea3eade6aae7e42116b21cd24ebb8e291f495d20e1c31165bf77e5ea8fa1cf6884a9ea752b9eebde0db8abfe2ef5be15f91618f157dea7857e24a2445a5cbba2b718a6f3517d1f5420ce5caf563165e71ad1612126529edc86dad78bd4f65145a1eafd3dae9933a10b53104aabe1e9ed0eb5959d22b8fa814fa882e669c47900c436bad0555e0873e6405c22b952a0cc3107be0f7b5a702017d9febeb444e313d72fa3ca292e5f151c1af74486bd112aeb0f91be8ac77d112459a3ce6673da1d0e15783c4a0ab3c54a9ea5bcda5ba5e88a1a42e1a45e8ee8e57b5865555abadb532317a30a6c338a6b3d6daff3caf5677777c6b45b2b556d56a8a73cedce47ee89ee7595b55b4d65a6bad551c8b8e88e5f75673f97ab2705aed1d3d9189be764c4c4cf465bd6fc56489eebb914a926050b544840596f3a9cd6d48311f42d86c365588c3959d4c3fa758e494b23e8420fd774b63d235846aa62ba4d72a553d93dddddd4e14956e258f98564d9cd0177da62148921c599645abec6395a1afbe4ccb59774cde1454863832ed987cb2d8f6ada59456a7f6ae486cbd0f03e9e9029daa564dae76570b5637b93a0c43a355a5912e8af8134930872380a3e98f9104fd1dfc756774a040b7281a3365d0dc6c36f3c16228ce64bd77fc202a9a66e61a2cf49e6fb4986b681abaa26ec5af68fabe65486fef92b383c92ec868fa2d2f66d0f4df8b339afe0b084d3f86e4c4175968aae68b9da6bfa4464e1260cc34550386169a86d145d37722c66c9686d6c485a66abcbc512306189aeac4680ab55a512f69484981ee092d3917ca50a28b9c30bedc8c28296e299c498142a529a594c6c8208dcc5c14bae228e4b6b9260eec2a477a80f574a74787b2028a0a312210234514e387841e916212cfef790b41cf9ffb033d81e0bcc7b88324853f690b060c3e38cbd7fdfa3fbda223e0db07dfbef7403f6948334bc5126209b9480a1b7dccad0a1b5f951d28ffe48abb9948858d379c43b146150b6a8ab9e779b2f89e795ea57a9f798382522fe744d273d43eb9e757397c9ebc7a56e6894d1ee3af7ee8f1c5cc6307d1e3d3bc37e8c0033d3e4fde1fe8f143323bced750d8f8740da5d4e803e4765c4b8f4f6f6e469b197fc8620498fb565ce31feb8f2fc594cda969999924fe38d22cf448cfe8f1dde6fda81af74a8f4fca66397ace758e7329ba138908a7117ef1db3709d69ff778da37d69fdee8cb5d73cce4f1bd100aa40a92cea8bbbbfbc7f4bd93ef937cbf845a3446cbc27cf255aa30742a4367b222ff5962277a34be12123d9a73a797b46ee81d041495b8d06f42658ea3b0f1e71da79c93942e33da82e8ddfd1370d1116fc7f4a4474b5a30d8a213beaf5f5d30141db195ce70e19a30fc39f10c71f448057ef8a1a8148a283c292975857835240c29040bb91de75bc627a76c82a104144480b1b363c4ac647d6bca5090f3860c0d0929368c29593f27ebf1647d1595582f8ab0f1dd35055d61768dc452bdcd37cf9fec6578ff09f99feb052fa4ebc8f7dfbfd0f3f89fd87bedfde9c945e47f3f4b9f5c44ba5c307ceff3f87b9f87017f4fcfe33fc167fc57858dacf15579cf9c1e3f1cc707f39e385b059deaf8e3bb6dfc1aa3d1f8e38faf6fb9ab6554c38a1edf5d1b8f6f0402d28d16a8bac34d55333369f523f823f9e3cf8f413f7ed55599d08f4fa998180b36d3fbf1e9138502fa51f5e3d332f4a888f5538f7afc9efec8e3da64e8da3f8ef6c7fbe30b654c3b083f28674c5faa07caf5cc04e236ef31fef8013dfeae57e871cf9d0e7ba8f6c9b3fc2a1bc1711c2d7d8dff93a9aec2c6273395435fe38399e6e86bfc2f178138e3fff913be0772c1e0f3dfff7c0f43cfe39fa5db1c0885337b8c3fc6d1e36f3a8eef93e92e8f4fe99bc9637c20559045abdf568f3ff5f45c5e4c98de3bc624393e09fef823c8faf14356768de91457a46ba6c7d7b4697c5a1b9fcec6a7b4f1a7d1e852c1ce2c0532239c463bc469fc33fac260148dff7720bd9f9eebef8b7f82fdf1bd3ca4b954b0566118ac3279e0a62325c81d96d1f8b70a179ad995a1471b9c45d1a38d6f2a1c26c15d95912eec5461f859188f24e984efcc24efb10aa62cf43261f8311860ccd9d849e337e02e859f9e4b8523af0b6cd2f843fcad9e7eb8cadbea95063598b4fad54a95b758a4ea90d25fbd90ea59f553f45c2c540d8220f8f4c15781be4a0e7de1d94c171501df7bcfb5a90b74a974f485ff890ebb905090defbab701affa7abb21f5a89ffcb5519084bfc104589ff93aab29f2f25fe0f5765208411a54cd4adcac0236e28f17fb62a7b95f83fa82af359024c89ff7bfa9caa2c9c218912ff57fb9aaa2c864389ffa355d9dc95f8bf59951175918b52e2f7a6aa4c4789dfdb55d965934410257e4f5765f34c89dfcb5519101a26a0414a4ed4adca6e90e00c1b549581613c3955990d23a828f17b35afa9ca88d294f83d9a37abb2d81d27a6aa6ceeaa0cd329f15f5d95e112ffcd5559cb036fa47055464e89ba55190b8912fb98a0c47fa1aa0cc89930b712ff7daa3220244afcd7a9ca6a193980c04d89ffd66e5395e12d4afc9756652f1294f8efacca6896345c6628f1dba92afb3953e2b7bb2af32a7020b053e2b7ba2a03ca52e2b7b92a7332a2a85051e2b75255e62355e2b7b82a9b67d028c289a85b95dd196c505506c21959b23c3955d9774689a911257edb5465631a20ea94f82dcdceaa6caa99da55d918751381ce96f8ab5495d12c25fe8aab3210ead48828716b87127fbd5599371561c61325f6f2cb93d55262da81128700258a1194f82b0da329f157e23752baeba6c43e667055f6c197204210e5ba31564afcd45665aa124f1550d1a5c4b01d4afcd4a9caec9c33b92d257e5aab3594f829adca7894f87daa0d19257e4c569908a7ca98f2e74e39f670e74b09342bf1c7aa8ca80738257ea42af364a10f3994f889e050a7c42556419a12ff12a62a0bd2428b12bf9309060e5e683fe86a4e55f6534598a79fda16dbcf1565a2a654113594782c318f131725f64a8caf94f8bf5d95fd0cd7e811065c349ecd66b459b9bfa98d671acf66331966e5c6b41994d9acdcb829c4f14ca93534d5a5301d88bbed69bab6097d5526211dc8ca54bf899317a88b0bfede7e2e979a4ae891cf2f76f56d669a3c743e47ce54811c3dabb53e53adefa4eea88853dc70e08c3666441ddcece07920bd61954eca97abb0d9450d6bb2505333630316b332342ca29ac88186449a5b9b0e48c141514cb6f06867d5e64a1d9cc5152f5858aea491e24a146dae30b1c58ddb23fbf5439aafcbadad43d46bf544a57ae9ad6650ea95d6ea391d624e77ca43dd6752e5803ba554695eebda17bbe657eb73ce09f20c79b5773efeaecbba9d53d585b51893ad2b2acd17529d525a35fd59e9f43ce9abde7be6de5a9568636bb5ada1e9b5d67a6fad6dec3d41a8855c616a6bb5f4be9d4f6e770abcb3485d62357054ae00220b203cd085155da4d44c704bc3c59834681082ac53a992303722a0a0c0860ed854b73557b001f3a6ce0daa15e060068c8de16de818794b8495921a9078b5a3923b805a58034d2feb5b249e1493ad0f55e007e2eff36ebdb6de1aa313bf1295bcd72735d33d1f8a4a3d768befd3dfe39d1bfd3d694618fd7deb8c28fadbdda0bfa722658a99e6795054e2b1f75e7befbd6538a15f2329d2d9428bef894a225eadfe8a4a2b727ed63e26ada593031954d85748ca660d4d0617ad22d2aaa7a2920a43f918ed8fc7d0a3eb7d1854852b7164913c3d3e3f404142ad21a2a21a366e58f0d97581110e0c72bc603a32d8c143831eb10d7c70f0a383231992074940827c004208427429c2084a43482052040001302280011060a904130a70c40027a080e4000848400a0a5800039234008a031ea004021190c092096c1598ac40810a30b1d082059a5c00031970e2820636f0020c313cf1197e82927d969fc49061c82fe40d640db8909de40c640ce40be426d902b9057f163253ae40a640defea4fd57c84cb20a396f8fd2fe135892259023902190b7efb4bf92fc80fc0ec89bd2b47f03fc936406e405e44da1b4bf02f2a636ed9f424e40de344afb23206f8ad3fe07f0479237cd697f144ec89beeb4bf01f2a653daff482e80bf09b984bc6b4dfb2f6502e45d9fb4ff00b200f2ae36ed6f24ef7ad3fe01c8bb46697f00e422795729ed4f24ef9ad3fe24e45d75da7f4856cabb4e69ff11f2b633ed2f42de96a6fdcbbc6d93f6d779db9af6179243c8db3e697f10f2b650daff83bcad4dfb07c9dbdeb43f90bc6d94f64fcadbe2b4bf07795b29ed8f94b7cd697f99ff51de76a7fd3bc8dbeaf48fbcef4cfb7390f7a5697f1f79df26edbf41deb7a6fd63795f27eddf23effba4fd35c8fb42697f1e795f9bf6df9133c8fb46697f1d795f9cf687e57da5b4ff2bef9bd3fe39f2be3aed8f41de77a7fd71e47da7b4bf51dede4cfb5f90b747d3feaebcbd26ed9ff3f66adafff3f69cb4bf05797b4fdb83da9e4dfbd7c8dbbb69ff227fa2bc3d9cf61fcadb93da5e6e7bbaededb637b5bfd9fe68fb6bda5fed73d2feacbcbfa7fd41edcfb6bfdbfea23e9cfea4f697db9f4e7fbbfd4de92d4e576a569aa660a82a86565d18caa63786d2fe530c8e62a347f608cf1e436131aebd43ef27bf7df61b86df31fcdec0ef177ebbf05b03bf33f0dbc9ef0bfcc6c06f0bfc6ef29b85df2dfcaec06fa6df2bfca6c06f157e33f93d81dffbb7047e2ff90d81df11f8fd80df4a7e37e0b7037e33e07792df0af8bd80df09f89dc2ef03fc46c06f147e23f96d80df27fc2ec0ef23bf4bf86dc26f02fc5efa2d80df03f81d80df467e17f90d80df24fc26f25be9f790df22fc1ee1b7fe5dfe0ee1b790df1ffc06e13790df417e7bf03be9b7ec37d2ef0e7e1ffde6e0f78fdf1bfcf6f1bbc7efd86f1ebf35f89dc1ef1dbf61bf75fccef1fbf51bc76f0c7e5ff0dbe877feedfa6dc1efff6de3f78ddf45bf6bfc1efa4df45be877eb37d0efa0df3ebf7f7ef3fceef9cdfa4dfe167f8fbfc3dfabdfe06fd5efef37f69e3c79325561339fed7c965d3f810106183e5d0c31c4f0e562c8ae61d8c00636f049bdf0c20b1fee85ec7a032eb8e0c217a5010d68e0bb6920bb76210319c8c06773e2c4c907e524bbcec0052e7081ef090318c0c0e78481ecfa0216b08005be5a93264dbea626d9b505586081858fd6420b2d7cb316b26b162a50810a78534c4c4cde8e29bbaec00a2bace0e92840010a78390a64d72ba8a0820a9e1413264c3c1c93ec5a85094c60025ed4dedbbbedec7a02129080043cdb92254b3ca825d9b50420000108784f118840043ca70864d71078c0031ee0d5942851e23529c9ae1fd0800634c0a339c0010ef0660ec8ae1bc0000630e04e254992e4ee9264d70c5080021470750b58c0026e6e01d9b502129080045ca9145248e1e252c8ae137080031ce04621000108b8370464d70740010514ae0d091224170a49768d82010c6080fb74c209275ca713b26b0314a00005b8b523478edca623d975014a28a1844b33c10413eecc84ecba0402108000766a6969c9ee96b26b0208400002b0ba010c6000363780ec5a0001084000ac941123462cce48761d8022458ad82800000000f60680ecba08092490606d448810b15044b26b12949494ecd3902143acd390ec5a49041144b0b5114618c1368d905d8ba0b5b6b4b22cedacccae7508218450a7840811527742b2eb103ef8e083aa030104106a0e84ecfa0320408054a9204182545c90ec1a88071e7850a3929292ea2d29bbf6402693551b1212528542caae651d74d0417d3a3a3aaa4e47d975071c70c041adfdf8f1a336fdc8ae39d860830d2acd870f1f75e623bbdea0478f1e742a168bd15d2cbbeec183070faad340030d7215e69a4706196420b563c70edc8eec3a03180c16a543878e9b8eec1a9623470edbebf5827a65d73970e0c0f1840106183861905de3b8e0820b6a4646464d46d9f50539674a73b95c74e6caaeb305165830f5ffbbcfae2db061c386eec68d1beeda46515191548d1a357015e63a1c1a1a222222d243424242b656ab05d5caae858080809e8282829c82b26b201f1f9f5a85fdfc34fd64d73e3c3cb49e9e1e9f55180f8bc57242922413995db344515c328e63920a73d76218864856abd5920e411024a252a9845498ebf0fb3e8c6315f6ddfbaa30cffb0aabb5b65c8607f5148fd8d9cc6578eb32b8c80af36fcaffdbf97f3aff2f2785f3ffa2fcbf9bff67fba0fcbfa7cfc9ffabf97f4dfe1fcdff9bf97b53fede4e9793c245dd6c504f4efe5ecd6bf2f768deccff4ef9df9d2ee7ce8af2bf37ff6bf3bf50fef7e93af9df9aff6df2bf34ff3b73a09dbfd5f9db9c142eea6683f2b74ffed6c9dfd66c93bfa5d9d9d4ae569d7fcdf95729ff8af3af51fef56683f2af4ffed5c9bfd66a937fa5f9d7d9d4ce9feafc694e0ae74fa3fce9cd9fdafc29943f7df2a74efeb4e64f694efab7deffe51ff347f217e24f64c91f4912ff254cfe4e66b4a69a937bb65b144eca73feaef3f79dbf4ff9d3993f9ee12777af6977d2aed3f80685fa0c6690de82821205ac6caad852822eb732a03c09238517da4e0c19375496282d03a529a594d21fd28a1509eee8fa75ce1a5d1f1495ea6a85439c3366e83081458b11e526672ecc0f6634f18131333a6508650d1b4d7f044a29a514ebd0f53109d2e8fa330d5d491c6a8c00091f0149448d60a6f809338518a6ce171084f9d2fa8206ebcb0f2d306d585fce0429314584ca61a809a22f37c2680993a0fd88c142288c0fbb99f522078bb901484c1aab24aefc84791342ad60c8cb1d12cc0882a68011bf682501d552e287f0cb1741524cad00ca4c90189d5018314425b67861d48049d8612921077b318281e22a718478432d33a3b342c3f2a286878c22b012703ea8dd08060c3945125a8864ee8801959813be90d0214ced16c64a1a47044166d705bc2386de2ddc912e3e2548233dd5dc8942ef18983b5af01972d453cd9d1e9eb8434574227df45463e7ce78c68e1947d8f1228b14143b685432902b3dd5d821f3183fc6242649fc38e2949165080db738b821a4e200e114a72644539c28568670e0890b33781822a5c6851754866071c231acc594a21852ec0752d3ae69aacaac0aad4ad357a9bdaa38c5aa3c51d8b4c1c514443e34f950f3c1c98727fa5c3c61c310ad888b2c575a5366445cd07045874dd014c483190a9b6bf01b0a9b3cc869d18f612e380014438afd4012628a105684b822d43a53e5671604022a3e43aee08070ec4b530f26f18aac014761538ac2a61e52438ec2a6fe69c5309c2c39f0c490623f9086dc90f381938315f287a79e187e93062b8614fb81346416c583df88511b67709ae1897cd3268737565019e283d49b277498bd0983c39020de10d134c406fcc68729b8a653bdb961ca17a5294a0d4c41933704081b8e613178b831a4d80fa49a53ede973c346070ba5cc102866286cea8d49375258192243cdcd13b421536c6ebc340dc9a1c98d105486e000d53a4336c658cb32060b3204630409744594226d0d2c224b93195968a0810cf554e39482af062739b808f2f554e354068cd3123f9082b4f454b3e58c2b6ec18bbd9af19cfe1ba627cc1fb446d641b7bea3d27b5db462ab577fd795243d6b6fadf35f3171fcbe5aeb57e728a9f5955babaca2631923f64d4e64d91c92d1ae3162a3840889c249d5d7b15eb4d7472ab0702ab06033cb5081059b15195aaf2b7225ae56ab15f692764c1efeb55aecfa6f55657fff8d12fb81aee48e600e0946ba1d79f6ae91baa3cab3235cd5cd22d1d58e5cec65edcb49e14195f58a6315842483acc4b9029a36260effa80d1b26eef33f99371de2cf71b0a0abc06af19c737eb5d65a85a27873ce69a9c05868d8ccdfbdadcf7a3b8c5a2d8c3f15f8d605667bafb5b6b628b60ed66aadb5b556950d1484d3c869b5a00a54617b915aff8a2d911463174992385c7db1582c7655a2472ee19670385c8c2449156e0987c3854b3e93a66af46003588cac308a412ab0d0ae96a623cbaac87a6dbd96f522278cbecf94a99ebef32c1569ba9403484e598ccac8798bb2d7e6a5ea02495aafc5f55a9e1eef51f94c1c0eb7845b8a5519adbfe47347bfeffbbedc1c2ff6c2f85b15e6b446e5eebdd6dd2badb4d2baa2b9d6fa7ddf87546b2d42dfddbd9a1162299d73aef05dd14c279d742ee10aa3393787e69b14a594524a69f5eab5a8c89caef9d37b6ef55cb5f7292de10afbbeafd6ac82f7bd0bdef3d822fb2d792f770f027e9f277402eb17bbb5602c8c970f31700ec91a2351423e6be728410a637a36c88e6bedb5d5bbf8b3d65aebed983c2689df35bf394aa6adf8e2afa52dc5480eaeb05b6b53a0aff9a10f3148b7d6fa08e33da65281a40b4d388d2ebdf7decb63a5ccdceebdd65a7bedbdd75a165af662dcaaf14613d42adcbf45ae212576d19068acbeec9718bc1f8d2cf15b71c8a7ef477d8ad81573d9bf734ed6bcf7decbd393bb6becdd75d3baef75cf02ade6d4df54cfbbefbce1281c5255859fea3f55e8fabeefa3b5deeb53833c9ec295f7f61d671a2ec3077314294865e8c24fc3e5ca05be900a6615f861a6214591824bf0694865f821f52a595bab6a83f27812455506c3ac7a90c552a954af72b578288fcff509818484425bab108bc1a42fff11a4cc8efbd65afb736b255b3f9f28ac61ed9ca058345bb3de7befcbe6b7c0e5a2388c6e8e1c2bab03cc9f2a83ff650c5bd57087f7d57361f05dc04f56502caae04fb1a8ba96f0eb7d870a3f1843f97dec52fd031c385e8a8883050b162f45c4c1e2a5883843d8216aadb5567bedadb5d630cc8ef3d2a3e278d51b635dd5d6060b162f70e260c182c50b9c3858bcc08933844a174ea35de7b4d45eefc35715aec47025f2f4f8fc000509b584888a6ad8b86141be202c71ad332e74cacd546d12b9545a85511f6e48faa191d18b8cc291acd65b80bb61232aaa06d515895c688ee6721695f06300220919818891a52324ab88883a0dd11aadb528bd71a150503ac70ac79048d61b232310d133a9be6dc712124ba0e5e8729daeae6a90a8b45433a571a1b31c3944a5fb394412a8aeaf55a8ab981d3f82e8a9f2aaeda7ca54d92bf194ad7eda5519c260a2927d1d3be891f57b55363bcea354b88eb101899ed3a14354b219d83a65d566ab51b556ab5d711295aaab565b6db548b2b2b2375558adc8fb38cd69fe5461f47b442eee94dd76e3e250b0154c54c2bfa322051172f187bf3ba6de4425fa4b2c918825a3c82589132e4c19f05889ac51566b4c7830815431295059b5555bb58d59c44490fe1baf442eef062914b9c46e754ccd81540fcc1ef4d7e86a46d34faa4e5426865cfa3c9cc89047a8fa9e60fa64b09b32c27480046edeac600c08536e8ed072041a1f7251b0d290a1940b72e8c2881054f1849d207a7ca1b3c4113cecb0841941f87c010a69a04f9a0853c50c0f68ac90428ead0d145e7270e490808a37c5123d7861143c4217e4084ea4a79a3b7534d6530d19507c373ca39cc4afb72ffcd2e11bd454054192829c329e56621977c671cd194bd4a864284f942975c650f594314117d28775020f08fd80684c11a2625439158d353c41a49d26c270068b6b501909850cdb75bb46695a71339ad63db4514326ce0f62dcca6db380a24c1a3b54be4023556e7b03c3cc07b250628c2b53bc287398400b175de8e444304689cf600c86c618a7e08bc629b0a3f103894af84934b468f27f44251207bd8fa814547f74ada16b9d5555678d6112055674fd160abed0f55f8caeff8aa5d1f591a6de9c00a76b14d0f3884a406ec1c72790a241138cd1e093a21248befe7996a8f4c3aa5347b37e14955878a67d5e14957cac57437b46daf3bc1240d15e09b6d05e1d1ecec0427b019eaca8a44b5b2b7a549921110000000082000317000020100a070402390c647928f8f814000f5d90465e5830184a05418ca62886611896018000820000c618830c535575008cc290d61b918a4e087aa931bf74ef8baeb4206852228a6390269ea2fe0d441b68a34b082942e648d4c413d2bf23d2d38004fa5337374a26e4c723eabc805c6910e1a442084e459db821edcb22351db4147dce48a343696931bd07d19a564842b6a8e044c49a0e9b88faaf216aba4419f9908223912d2e08ff9a68a1878652f655cf443a0d883c89f62bf55118e231ab49a34b260e10f6adc99686521173a34f949180d4884336256dedf49cfef82c9524a10ff534099c9dc462461eb2a9fde3dc409e5de333bb37640b7a3bb056eaecaa86dbc050b573ddb4682ef36737ab803b5986cd5e324c3a9ca6e1b0a5ed70e6ac128af25db56988f6a321752778f9ea7bb47bb8964cc6707d4cdaaca900fb45daacb51244644bed3f97ef4e2ce43e5d54a34627299610ede6f6e567237451cc4a45f7a6bbcfad23a4243d33a64c53465c74f5c5d2b0cbf21c62305d38ef79fa3980e3a754b397cb37615b96aa58a19849338248bbd7e33737210355e254fc1c69f634e20a99226ac4fb248af08334dabe2aedd880d30777ac8f38f4f5c3a028508d1b6c49d5845ceed9e499e4f3a3047aa5e5c2590a6a95fc886db8e1c8ff393a8a52f21541dd5e557e8a17930bc0c45c2180f9c6b395ed1d394de14fa75c29f97317eb658414b9bdb2a5b17566a5066ed174f3fae13b300467a3fb2303f259e26da6204a04a72ed25e09a28af106ca8f887ee1955da2d8f110b00178cb79cfdadcc098d856f74613a267e8b6a9a3224dc43cc270279a617a2e5bc320d5d181e4cd801b53a098ce76f28ac0f40457b29deb5e7008635fe2dd4a0fc09afb9dc0e9ab042abb77d095b29c9a7c85a01fb0cfa2c6d9f013a4ddc7a0720b27a2d973e4aacc221878fa1ca13b4d53af0a2eb30be5a250117db0400bab79f9fa93a9b6cde1d97370d7cd9815acf1250ecbd5257035235b31d2319ffeee7551241428e98ae34f69b367918b6482c8d147edf4e989097e39c25e35a83b4d549d2741198482f5bb845824bd0c05a1e6c7319016e2d3fd759111083cc60bdb74c70682782f45d3a0ce544557576f3c035aa478f4a818dc3476452f574505a81bf91740973fa3eced2cdda5d176ad77ccf560bce5bc87f09b0ff830084f3dda0ab593debe6cec3d8f9bf14c225130439d791fb71a6ea98454e17a8eb0f0ab8318ad12c719a467e2ca7ac9343472d22832ea5a6768971529330be76c8c41b7bc178e7b1e8d1155d89d7a42a0ec9098294702378e8ad32469800dbe9468c1986178c833bf55c5fedc7443d5101853c53e6cf64b7de6458483a788b4d3d334ecb9a91a22ab01d86f25500dacf520864a4c9742ac4e92f66f2dab032cacdec6da3e2e367b453d8798772517a1da5e2a4610d929e0ae00e4ccb2be3110570c05fd100dc9d0946130a7b6acc39b1b1438ab7e37889fe9377b7f3db688bcd28ea23701a63e38083d3c1bb3b14512d483d3040c6796f0354ed272106d84dfc48e99174331e22725998610b3de20e4d82990dd1ffa3f809e7b4bff1bdcc783880459aaaa6e176e6a8eb807cb67654bb3bde86bcf3aaf4224aed42bfc15786f5af07442c0cf0cbd9b324ad7cec4f7eaf5027c9d5c8217f0f569f9c97ff6820371ec89c12f8d8e40adcaec0d58f6d4fab6ee48d7c28d5c928f15d1e9391dae726d7b662e49380032702d9c9abd93b74eb900a615ed374af77bfc015873785f76b7f35ceecdff4fdfc80bca0097f99affb3261c371e8c0295bebf508f56c88bea34d4fdbcd41ac4510be34cec9051eef01d914867f58674eb53a322b92d9299692d763e8172a23e963f1f73e0be3b9220634cc4ed68b4389e320823d0c6f428b4c583ae50ec35c11a7cac882e6df2b267b90ef111120ed08b05fb547b3192468dc0f8c06750889c4112b932822af87d54bbc9da9e6cc88d737f861f5ed3ee732a2a0cefeeb3cc32bb1954e55d6c831afefc8695477e85aafc9366bb5b4a6ed6a03c7f3e80bbfa4749013bbe57c0452ddd2e65c29e89405712fd17b36da215c7955e86fb151db5f7c364f9b912b1bca9f5082c7a5297ff0180b0e8dc87b9cd520c50078445b00727f6724bd4c00331c0d022bd54990e87d2f33ac7e72c170d83e6d0d13a0468300186f49b0d90c549825644791cc23427a381e70943e94723c78d505f5f1833ee8cbeecb514bc98097b4c8b0236e01256d30279c1ec2ac53a643d30fbba52efec9a8e2b2cdf05e9b21cb457a9f958edcbb6151d407c1a5084e9bd8ba716994eac520459e2b7a048fa01208c166e25ef2270856d737c3b27c5f7b6f1f76ca76493c1949137022b74b7fd3a2c24b614e2e4b7e2eb5da021679af56ce9a1d1aa2128c5bd4870ee8d5644fd58837b094a0991af013f3da923b474d6775ccee3fbcb0fd68c68c7af121abf7718f576f6cc363fde2274726df5ac6e17513f028524517179c728c4f6cb11fbdc255effeaea3ea471520008b39e46367cf3337a4c8f90a2e82e1ad322fcef96a9f0148e1394792b5f7fe5d7ad89501e696e6723ec997cd19c11d6bc442b5c09fd650bf1425e83206b04b362605f07a415e3fb07432a11a596c0b072340c06e8ab6a3a7a68fb0c237a048f4433e8a9d328ec1be67fb3b4850eab5ecb7d7329b38156f8313e964b7e84bd803c018cd2b69dc0dbf573e8cb2642732723484939a07ad9d63ebbb5877999dc4f638c3e3c00395f3ae3e0bef89e6aeca814381edbc1290a6d60368673310a839e02a806b91d6644f1e44c107d3416a8a1f47a98b2bbc54b4b66a824e4ded4a26e1a37da1f9153e4594da9a9260faf15ee0b7696b5c3bd04fc3a45d740e5991733b921ad51867580155b1c60f39e03fb49b1d0f475b8407c16301e1c0dadc9c5bb5d0d000586dc63e3016fe8d0072d24c12478c721aa891472dec8542a5a33692b3967967736168a51b6e5e5885e14c662bab3c3e6104efcfb4a64030a45a8c324bcf57e33f273f102233324f0de3e25e3aade968e0286b641206e9668499f5404d27120d9f691a3d131d4ea787ac9c8aac80104600a69df13afc906c182d9b181ca0a5436dff90ea4dc6c226cb95f0f6d33e13e0a58bd94740b8d82eab1e4a9c3024b65c8f4abc9086ed36a42035525503e8606ba28fddf31e6d97874b341ddaea5c3a0c92db09fcae87de65ba74f53d264c70eff8fe1bf1c8b45343e2cfe8ff54da1758ff7900bb738bc96b7d0c09626b6bd07490a3ce961ff100b26bd70ab885f817c4299c5a386f0455fadcc45e1021cf87fafad73f42bec7b4ef6049860248da26e7a86251e9d94f7c4952d5b65e5bde1970e987193b5b63ad45e2a71aa1ec364c72a9ca161427740034e3077b38c5604d0cee04cc8f0cdefd1216de08e5b93f505a7e41da5ccf8b3c6328ccd57aeeec14401a0e68fdf4d04422ee747fe1b2599aa6de69052af34001260b959bcf288ddcd0ddb772a9bb1c6a83dda556084559b880ddded3e6d01703786a219937593d985edfbafc19f0e27110fbba5d4861c5eab6e3b50a814b888ac3c17608b5017ee229571ba1e6278acaa15f74e250b37bbb3b286336e9ae660d13fdf20de10c15b024d51440df24a208dfc2c96a3d3b38fd9a0a97e534d522f151a254bb3d1a7c959bca3d3499c7d911db0825315c5f258eee1b2b3857dfdeaf2885029b59548e9d5705e561f9999dc6122789533a71012177a16854ab8fa123c476309465bad9bceffbaa189fa42ffe80b1df0b657de27c082d6750536cc68b9b7f34b12d725906ccebb6e550ba90ad32edcaad75d4f0df86efffb48f96191a7e86686bba66f29dfa6d6093c87d0671eab1c2e51c44a955e7c5dead497e8c0f7a76b71eda23ba11bda48047d22bbc0c81ed592f05beec8f8e7b3b55d4946fd55fd62500ea0cbf6d9cfc463411873baafa6b0e474c12549d49b3e7ea8da1049649ad2aac186e42dcab3a9f34513e37c2fc8f260a5aa4ec1febde68370bee6b83f76147693187d5e84986acda408986bc1358cdae09610960bcef430ddafa257390dee0342b2658714b060182b2d49f7e0ab45bba9d3deb35d3aef0b08a2901d79a1137c7055b8aa9e5e4bf585e5b0bace1e315a3afbd848e2815e9450ba65618bda391b7886f64a60f81ed4738b388e43f1c79c87267dc38fe0929ac378ba5f0dd96763f2aff8e64ec2e59416d441828cc549268ede896d48d07c696aa279cc60d9edd71702770d1c673a7a0e78d310fbaaead33662228566d77f60b861777b6e78b10e5ae3cc6849d3700850bf171c5b1075109d443d51cadb5021f770f5f91af1774d3b1f5aa2192df26f11fe9d9f4bcbe528b2a39e0ec6a34366f7646651735b73ef21ff65e4baa3ee69e620dee5eb4b37dd678efe763acee0c239efdcd9efdaf8e7b9440adc758b469eddcef37f5aecdeefbfc780e4d04809c453f9f5c31e9736f950054b79222422d4514a74458894498c88fc369a25b0021f60308e60f137055af9e67e29f3d17ea7f6e52279246543b454518dbfe92ae1f41f797839bda2cef50a19eca8ff0e48902dfcd06d52f2c9f8646e61d62471b04be73de396db20d74651a129243f0b9ebe9192785fcd0d2a04e8ed11f0ed90006f80a454324835be9cf1c19040c1ee2c02ade37eaf1e4f05198092e51b1f82884827223903cc51f2d4c3afee4e6c539c33f75ae34c1d75589ea5993a66367a00662a761a726928d1816acbbcb96792f6d2972186207bddad58a7d7e4eb8bacc4f61bd4e118c442fbc2d41609cc3af81418ab916d06cabba306aec1eab52191777497a84e200cf6bd7000196fb494e2e3829a8fe7b052b3c5040d0765e2b26dcd767f83c72149d45b2b47bb838ff7a448ba4205dabf9b878e4bb8ecbe9b883d52728d5d7511bb5aa3d36f42b5a267e055c789d56626d50562a043e4097a09cf9c4c0b40197014aeec6e8cdbc88479d2f7352e62f0367d2776749a9767cc749921f6f5ced268b0c285108bfdd2943f0a5d6ab4f512d3244c92f01841f24586cd9139f8c778501dda48ed77b523835b1f4b7893ef9cecb9630499585c46c0654bf47ae9dc87b89033bc8b0c55cd66302fc5b919b75a88028c70cea280ba2b0357f9f5b4fa920056810ff0b3ae795c2f731de0980843ec6db53257f270a039cba0472eddf1c335544581edc7db602b49353936a489b4bdda1c7a714835f970226a4a5c81e89d644e86f145d1673140d701f8c28feb93abacadbe5314a0405a3cad5fe8b7ca8a9f41af97f6dcc4e24dba5eec13fb948c770b77b4d09a0ff8ff88d53a013c0aa833363df6c2bf6001bb8719f7d4daeeb24f6ed05f02e49786bd6a4ae593874230314b358920b0ca6f4a31e25f5c8ed352f419e3123ecf2cb86e5d832337a3ee2f1a4ee7721b1f6e764147803db8bd675da75f89fa9a4b211137f798faaa41a8b0c5a529efe58e5654466ae8025fa55467a5769cd93d71465edf5520d84de44df1c297f8919b4bf281e4f13a4683b20f42279dfdb875bb3b4d74b320780fc7c66a26553805b50f89a64122e23ad91925952a0af0f98e41bbcfd7862daec76aad5a1e56e40e10f7d06df66ab76a38d24108c6787e9fa7ce47afbd74c146425eb9456caa0e0aba1f1b1b8dbaa98e88cd5d6dd82228943114ae35ba05ee20f95a5aaa57a891e70e205f1a49cef574cecbb865f47e180a1e0b1ebfad2072dc44a06d2a792e1de8d3dd9badb19d051bd668ac07c3352d0e4dd8b068c74decfdab930f6fa21ae5cdc7c245b7db7777e364b9b5a5664f43020a9efe5640eb81359d4b51e54b112df2eb5db810194bf1c440c9405790ec126414e76585145f532ebcbd83ad6d86c939f7c0f214d5f621dc0512db229392068c0f4e56751ffceaf6bd8fe5713518bde488c157657d0ecb5a7d76c9e13db381cbc854b64873a90eefcbf0cf115a6dd5871633ca56ca2d5d6bbeec3563f4d8b846813baf3b6890d2975e696dda7407c23696f9b214fa52d1a1b35be9e43eddfbe68d8a144ebd77331af8e8ddbba05c97b1b395b82d7e5fde8c923115e4b484b11d86f075b1258ce27a1b1daf4110edbbb22aef92a7c56ff815b02058795584dc7b04cebe35ac7378d5d4ac2f1c973fdecd1b17f37b5d4505202e86053fa11508feb0fceed3ba51ace0ff91172baa0d5c20176f8b6e979d6a7ae150478d5fd739c37b0c3a8dad2183b8120ddea6a90f54c0174f6214f418e854664b6f05c3e2e531ab6a67b4db5b0d8d5001855f4f89db12d1288b4af728386d88157b85146826710e3a0dac8a267fb9a9e0b69a999bf1da5817ae573d0054e3b18c8683aed7cc73b044aec5f87b026d0b1787a8fd39dae5060ee930cace7e9915db174310150f314ac0c9a098994bc37947e0e46bf3a29464a64918c9e25ffcd8fd8da74f422a02fd015a687b17455762f651d74c05889a5643f6ac35ea23ac7e3d98a36b2eeb6ab4e66428a624ab795f17f919e961b7d302f5286ac05f52a9a348a3a7f3f45574579a22da131301c679c8ac5b8766b8217ae2853694e3f016ecb209d6651c6742e42cf2f7e38614a6dd9e638401c9d69d91e322ae92473a402d221657b0a25d213228e48443a8b49f0770a0192aaf546c0767520983ba464297dfecf93c0f09cde0e2983e4490a3433f3387367b9861e73a2c7a58c39de181dc1591263f6af3d2f7d09607a12ba2e5948567e3a6d07b93974a0fc586b03a23b72ea16c240c8f7293f953f0b54f445f247cdcd271667ae4c974bc4fd741875c4fc935093955dbab786228add7672b5d5133f166583871e8d86bca5b9f0bded7df5aa298404c603fc09da7d224832f4813edb9c8835b8aaeb83cc25cc8db277b977143dce1debfafe4bd17e9b8554be27b93280948d3b5d9ab717e3f060a53647a103808c043212de546ef3c294b9c83277e30748ba46d627bb37f7b9e02b1a6324f44d1dccb83a10cb5c5d625937063ca0dd382a196b8e7979306f17f28b8a806030d62a5123407a1ea97f4eeb7f7ab81b1de46bfcc388c42744be21714f3d88687dbf389770d1c236e2eac8268d34aee8c772bd3752f999282b15c934cb5d477be14644dedc3778d945ea84400f8eb216f40a4a753f4061522ec092392d46d5ad5c740a8c054c6ce71b55978f34389fcc78add545a3a59a32b750a8c3654d75cf2712a7d5df0947159d75bd7cce1a0472d907ea3886bd6d85762c0bbcf052406b26e1a4e93f96fae2faf4edd1481418c64ad5825c6fd1b2e588b878c513767d3043aad336e00da660c1f2c92ae04fc2b3e8a50339d3468d74a1ba1946ba22bf06ec46629d68fa1581c2b9f7162549affe234a563239744c48f5b91667abe030bb1d094a23c2d5bc9f5c03c291b6ee9d48f152b822cafce0faadb04702151c3c4aeb8c89a1c9e4d438dc0d120f56d52ca2996d43f2748f3e851f8160d0d6feff95e9d8d6b65484dee938b331faf69deabcd6b01cbf95669bdd9c64f1135916e26660ed8e12d0ed80bfc2bd78f992e749c2c69106e4776956df95273bba0b4e2f9425da364dd86e436dba304d6cfa05f32e5cc0d90a3e839cd8b9eec9934c3c0c18f4476997ab586630fc4151935cd8a5e3fa1c28e8a3121eb5d57bbb07ee1c51e8944ecf8e130e00e03d426277339cfb2243e369b2b357394c29a3564fb591703d5ab928311527428bffbeab4e7dc822d010d0628d8e97624caa1ea1f533041a814f0d14bfbc1d5c4f24e9462cbc37428732b9b8ec4c2e86f4124891f4cc4ed346c6aa186a6bb70ea5a3ebe5be08efe643d58ea9564e1af4f33ea0c291dc76114c45f3fb016373d2051d1f3c1c6b6dc0f293e84a61c99b9965a2c6eea16c283108b964f8961391276475489e6ade7ae1ac725d0791a38897f5e3213abea8c03bc723f6d89ecee0308ec262034d17a8d04cc24465d09b100641b9a7257c91c0cce9fc60e28d73ec073951bac8301682fd325ef74e65f6ef60146a69428998d084ba9fa7d9b7feed9bcd318027a7d00b3f609dbc2a9ac76352366aeebb714f1702e8ff46007f13f8665724c7d00127608480ede2ddead0fc06079a349bb053f708d49093eea03183ebfc3f4771492ddfb0055444ba3dc0760557f4472726a283acedcaad203c8a8f061bf11b49e046ce25609c2757d08829add4f028ee84aebcbb07e7a050c88449d804a02daecff15c50bff177ed2bbb4a0164319bd786e94fdf92468ba26d4b603d2f0fd9c1c4556fb01f3445453c7ca16b28893bbbf02128e076814a850c91db7e420f247ff76e042fa75c4b370a1d6265e9120d16fae0d7fd35d333272387bbb2210c4ad8260ea7a5f2323fe6df4843b0596a26387ed28640faea8172e8e986d50beff47305722aab779c21d88d28c3d132f41502a5820bdc983b8611d2854d62121be0b4c1a65005a342bba05003a9212de6e8183a05a17f9be59cf30fcf211fe431d2d09412e4a34d19aa4ff48f98479f023ae019ba0479ce1ebc1d0572269009055c239b6ef4d90711264d4aa002459279624a77baf4009372a43b24e22fe6147243411824a4d0b9e8e128d72dd574dc49b67c6fe634a6db6d914b2f50820f1aa01af062403b260c60004623a5a6ec4eda511562b2687b488df24ac10ecface880effe4017ab71a0e48a0c6f7e77864ee83176a31834608b49c40270f584fa048052ca750888316d3508420abc9857c400a5b398126072c9e4290c32ce620c8a116d39024418b0964a4a0e50c219c9810b69e81200b594e421087ad4da1086156a69084d0961348a290a509f412906171cc1b623987220eb498429105594da149822d275009014b53d0c400622d68924d089d30dfbfe6f5d0955c0bbc066f0fd8cf07d42e8efb9851b90b711cf2ad64a1fa296de48f29bf3e1dbd0a5722204ac3f0c9afc725c439a6165ebce6cb53e514801f8ff59021eb62c1a050ed00a8e320a59bc24f9552150d487acce8d9464e719dcf87c74d80454258c3885282c49ad89da2fe1af207e14e292ddd52bb87e7f8932e0ddec1d5df34c065ff5fce36f4d29921a007684cfdea01cbcad7829a5ea73e09f50af1dfef3befe77a5f7e7d2aa11f78d24fa7f9666ebf9024eff9651468e38c0781bf77491ffe00b610c57b4ec0cf80b64678241b7e400b4611687fc64b6d83892a7ed037c5434e63d8e9a2941941cbf52cdba602722b7fc0c52222c6e1c2acfce514ee019f8b363e3cd116a834ad0d7572a95c958b721d4a62d029c3c9a441640f71d7d7be01f41d059fddc6a4855bbab57019b065eb39d45f4ad581fdf25216ee0a92cabdc2140c11a67a2ce1d373359700167269e665953e6bb0972d0b40ff16fe5c09378b5e3ba0ee9d2a6d1cbaa7fa7a13dbd0ad0ca278271f0322e54e72ba605b8a0919c5be2c55f45e8c6681629f145d7c279b6e89fa4e8cae602f9d9534f54e2055b025826b996a5b3c55b811c13481722f805eb8234b9c406927992ed82ecd844cb1278b2aba17a3b948b12f4515b793a55ba27e2f462fd849c74a4abd13982ed88ae04a46b5154f15de8a605aa0d8134017eec8265ea0dc49a2156c4b3321a7dc93a58aec89d12c52ec97a68aef64e82651df8bd117eea4b39250db09a40bb6457225536dc4a30ab722982e52ec0550857664891728ef25d1055bd2989029f764d345f662348928f6a5a9e2f732744bd4f6c4e8853be9594ba8770268055b915cc9a937e2a9822d114c8b14fb02a9c21d19e209947b49f4c22d6926244a7bb274917d719a448a3d6954f1bd0cdd656a7b315aa19d74d612ea7b0174c14624ae64ea8df874c1560453228abd40aaf0ae0cf102c59e24ba704b3a9312e59e0cadc85e9c2631e59e34556c4f866e99dabe38ad70278d3509f55e00d24a2ed8be4869db8b104f1d0f65f35eee3780eeae4a153cd4f79f22847e3ae442f05055d9511ca61a09cb361e1304e7c34c4546b265762f895eb825cd8444694fae4dc8dbe79c554d1be0b984ba403136159c360e8cccfb743ea92004ca6047c40c0d16ad68b88503282032840c5145dc6fc382e9d5b0b3f9d3b79d7cfd9f3c040aa2381fc18f57a381d47883e420642cd0c9b7ec80224194901f6945039fc609c84321041f41c7838473ee564816d90a948928f652aaf81e840f0cbe42727651a8d84f8b8a9178999b492fa74328d10fdf0e28301751c3b9a8eec9ffc704eb462ad641778196f72199ca5ec1812c54c2610cbe4553fac9e0cbfb901cbc54b5b3e49fb4066b10e73820fbe1870ad350d890ce5dd87d5cd630a5bb814a27ad9071384a4964bb6410a5f44375056b0b2c0650ee494b7b135422cc3475044d051441665d116eb22b4ae95d6331504a32bc595b13bbc17684a3949ce8a20c04acf02c7a3810a5bcd9a8b0c135425346292f4c14734495397e1062112ff336844e0b444626157a518ac9868206a5f4f9c70aa5140e216e794e49f462ab0dc8cd510849748f237a422909df8072ca7309e6a83cefd7d28571fca8da9ef43b7a99a20fd2ae0c82f441290f5fbfef4ce41019510aab2a1a4029833ed004a530f7513c0ea5f4a01a3929e8e45ad8c2ceb16952f20f2c87632c9fa78545f14a058b4caa1eda128c4ed7db8e1c99de4c908c7047a5c821a9904b0a9d4931950c7b12fa8344cc3d5de792fa2a28cf72032380b0fa76b21a26c618d7d1e7f76233874b69be048a7e205b9e8ae68ff98d00e8b976c18aca39715674ae451cd4dc278f255e7325325c5fa68572526627d35a75ec513640e0e915a32303a651eff7012cb08207721eec44736011acc809c7ebe575d2785bec69e72515404f7a2f2045da7928a94653faaf146f69003b21e7e9f958de9b7a1fa625f8c989e2cf5f4cbc90751c10b4384f26fc164628cfbe4125235fe8d7645067c264e323beb8064ba81b671b84f0a10eac4e82817a1bfc73526f40ed59ad6b1750447810d65bd0037e344421a3be49fa697484f1dbdf606642193f6ce0e07dc8a032810b2259c3bf4b441d47ff05bd907b108b286e1cde463accad82cde658222eed8b10f18d559b05dbf3e1450555c9056cf7c33a7528077311dda90a44b7d4a097f58087f77d2b2180ba82dee0020873a224ba21a746f9330554802588a3f841bcd9cdc5a9bfe13bf9ecea251a7d58fe3fdb7b48831ef2720f9b95b0075c94b8f41f1b39153ff8ca223984d3537be04c097e27a4c05c59bb16bc5a27222b45c6fa310687707827f2b36b87368c610726a905b67b9f2e88bcd9ca7496d78ff56e2b854d6398a568916dfdd70d2aae90f958f51590d9e8e0947f02df54cb5960da00bc3146ee70ee2e8a783640027c6d4396c4da2902a5982bfda171b600bbeb8e0670036279bc92f6c9c8282abe8af045a0e21b6081ed4e559899f311f94dc63f9fc09930ca2abf927f664938e50c94ff02193fa551420d41d40abc56c062ed9d0941c849e93d7c0c92df95d89f3adb5d96a4d87d1036b3c7f7c4689bab7b3e980e9557a0d5db44ec7c4be2f01922ecbaa4cd2ecbf0aaa52947ec81be27a2115e481ff9abf781bdf49026230886a604f6506b6c2c3332f709bb8bc1b16ffc430a4bf210d0abec009dd5aa2eee112383483e63b44f0b0940e0bb035f7b3e8f82325495c76f0ef477d308cf7e0c3fea72ad1f5684157fa0ec87dec0fdd44527b7a2e5bd3bdb1ad73fdd43c69fdc24413beee00429e77819b3678e7485e112e63c9e9c1e94ab7be2b5682bfca82397c01985c7a61fe49e6549527860ab7817b095e03d899b5a9670f8ee86cdb92e9c213038c460b4990a85eb2d3e1d273b29d550e536c2a82876b406ff8d816a9787807d1b16b8061de8c8d85d518b857d1b94f5cd17229660d3fffe572d4c384708c720339510228718a7255141ff0ccd45c05abf7d84b47d45c6737de26b567e0abbb56adc7827ec2a5e9016696aafce4d5744168e42c509fffcfb084f207923972d8b86022f2068195766c20222cf617d375af260f3edeb793729130e8ecbd3adfecd7d3f080270e87426eb80ec918d16a0c1de54f7a0b9fce8c9a7ab2f6ed2a035ccb6f382707e19fe4d397233ec086366e7c0f64e6bdb778071d085b29674720683429330fc5e7a81eb77fa0333881bb6bb2acd977f46e821931da30e9b642f435b0a155ec3d24f3c3247305c36db6ed5ae90a34333c82e21c7f1ad80eaf5f215ad9a96a236768eb0f154753a2497ebcb6078e14ce8feb90b9d4fb0da7543849e007bb197bb9a90bda4cb1cf11212caabd0382f0146af02a0589394e2e3a4b2485a45034607e98308f3906773151efad111dbb1437bfe247cfd659edb955fe0958c2e7b1bcea8f95613c92fe7223f8f608e4fa69fd768c6b3079e746fc5965958495e0b1f2202d256132d5640a49ba7f1d9a563514c15c8c02ffda354bf060dfbdf4a0d181a25e14c47664eee4568a56352007b6c0bafb7eb7941d957059101cf58cd20f23115dd1fa3e62d37fcb20b76b182dc448914798c54fd67f67509c5cdee6e6d09680d12bcfe1d746262e1265be9dc4552920b884723da4537dedc668ee445b5152f9b6cc7292072bbe6fdd8965b0ecaa03828fa9087dc69e2a79dff64e269896780bdb71f6b3d5bdd58e9e8c9803d8d63654f40d87c02deab5dabf432e17ac46a1c25f4c517daae8b81a81b4e590681180c8db9c7366e6d5c5946d0d01fa196e857e1203a86f2da0401b7c907a37ae17424dd3f05d8d356e9c5b75e07085b2599e3fe7f9dc00fcc2fb19d6d7c1ef2eeb96f50ea7f0c7703d8734921b60f3c4f89b953f814afa687f002ae5fa7227fd7552120df63330c66bf9ae852dbb307fa0bbeb3b266a4ba7d44739aa26d75eded566cdea454abad840e73cd8ef4783997c1cc2309863263fa04023018811bf0c1d134f7e0eb224db7fd17d100eb1db0fa8f33f0ac9c932d4b73c8793d9c53a5d7ce3a9064b1b7814b6306c3b89c40338016fbce91bcbf186f5feb70fe5fe46089e1e2116e24dd6c8a21448fad31ebb165586e8220347369b1ab3b74e9158a68108d0efa2735b93fc3de8dc031f359a5605d5c9d76a6e6ab1c8b26e53e4031053a4c8ab65c2098a7d26196cfba1466954580232a792d7579196e217c938536697293e5b26cfb057570849cb2f718ae025dc730ed978ef06ae44db476904f237ec5c620860ff3665518915132e710f52970516cffc1f1e6569afb7eaa274fc37c6f13f7624b8c469de6159273b61a1866869250fcf2e336ff277a4453c2aa309e969d17b88b51bc1d8f85e1e1cfdfc04238f3126457cc541935d8ff32e006a874ce2f437f2f1ad692b1b10b2147eec4b82a8391cb8c7acecd49d58fff246da6b1ba06d7acedd56f365ec3297f96b1a3c2b8021144ff2ba5a7b56f807295fe8ae37676f07a75dd6837a489e2d3be14d502607382060ce91b603ca7fd4bbaf1b18cb56f665c7792784b0767e08f30b4b663fdc610b02f7f505fdfd8ce7398eb49f8fbc0fd678b9909c66727081662dd51145acb763fde61fa710cb3e75d6284e342888c399e9c70d3b59e683582c3d1cbc67aabdfbd21a7c37ad9436d305ea38a6b70844b9567e0956fd65a864a166a0e01678fcecb74c9b75b4c8ac14567b166cd6ce94efe89b6dd18debaf73e570d46861f854fe161e7e2d7851b4a22de7738b0350d9fd3148ab518205b30be577815b5cb368df665b77d4a7816b5d0979f9d2894d3acb55e166361f6d7bc70319796cf8f776e6c9a95701ac8fb5ac892efb47947e4c6a2f27418bc9599337ae31a1622a7f08d1be1f9a77c96b55fb56b0dbc8336ae10638aee70831f120e4107324dfa0f6e3831dafaf32e1805ff8eab7118bdc4ae07a647e970b06f97f83f581c072988f24bdf57c3d5bf2accf742bdd7f40235fe0c9d2270f7b0ce51eab8a443515f0bb933d09ac26ac857a0043d7b7fc97a849b52c729c5e3dc450426305afcb6cff0b0520016b57e8fdc202bb14870d50b64f1803e4f106a384bb4b80fe630d22067f18db351840da16a7f8efbc7810cd62789f388b19fdb083f73b39037ebb7f45c49c3a592ba6beac017eb4b291323f3b22b5f77373c0a2e1b910a36d1cf504cdbd3e6bd704e37b93ce8a999078fcd3c90b499417ac01534340212d6a9433c3379dd934f0a363b4671549416d91aa88c953e840f763de42c269731fde6d33b025ac6cd20ac22d46b72329c815771605def684182609c8b02ace1bc17c462bc045b9610e80acd37c58e569edffb8f0aad1ad779c573e108f71f8dc8e5ce18f99da5ea60c1731ee3097346cbf5751002c12dc56dcce7211dc6757d0a02768ca66635d706a77644279c8adbf2edc869193d179ede4aa31a6e4666f1d1b06e0513bcadd3e4efb6f8b36739240ecaeb3ae132a8729e8f3fa39b6a7704d835883b1a92d7b95f0b72431e48056cc84b1d177d814331ec9e2ec24d109f2f149eabb46e8c437773971ae781ca34b21d1c0d651ff4d4a37a408f235e4360830aad5f84d2424108cef5c2f645e8345d00076244160ba84953010ac346df9c2a0576c240e672b0527d64bb79106d7b688aebbec7dd7653b20d8c158f6bde36fcce77720c5bbb72c0d3ed2b01d4ae8f589e82d8d63746add07afdbb161f7dee55a18e8bdebe64e02c3ff1feab3a82e507c17b5547c4d25ef771931416f71f23e2a78aa029197440b39769f216206ea861e3fdb5cb7e6be3bb896d66820e77da373835c02873a73d0f4cd50073af37ae0e496698107bbb9b4e84ef0ab155ac9e67540356853bcb61975b7dcf4773a7e19b2cf9434201b26b41ea0bf30485ed3c058bef82f1c1ab749aa82c546ce14b1ff74b74806de8f2618881f164ed3bbcb358fc2011568564cf726728b94f937c1978668f6c80a182b59e15796710a5063630fd37269fef609fdf72e78dfc9ec8919c92742fde366eb797b27c32205656931ac26a75a03389b35a4b6ced3ee1262bdb7a8689ef3eded0fa971d8caa421b673c913e4a607fbc08d6dfdf2615937869ff132273cb0beb622cd13360678b4c4ffe21fc4285c62f4628d64fa8a61f231008acf39cac53fee5096f980c98c3ec6474eeb1eb5ff85f475424a77c7392c2b74bd07119490e4a05d5b29d6712cc6a4a474c2de2f22dae90db4be802829ca13b7d10414f6d9e8bb8fd845a53cb821421aea32d073ade80ba11eae8ed7f54a3f5818e9680407fd0dd2f3b6a99d06fc657b00649d2c8cfb423c40a83bcc6f0249d1b8242ef5df632d5c70a994b790eb7a5c5de2be3cfc1e81acdf43b98138c025df4802b9167f3f821378816b82ec276d7a815f78f52b5c0603ca6bba9bb96cc94f731c3701204d07fdb1c7309f96d946d255816df4cbc5be67279163d5258881b746aee91e3546c40258d8da8ae3af88e60b8c1d9da24378482544621c3178015da828487be77ce5053480f01f057ce3fe4da3daeefb0776c2071a64c5cf9bbd035fed1dfa22c3702248f098605fa44d490b8d75f937d27cb67ec09179be0cbe8396b98b11ef7430df9d846b46f70fecbf7f7cf7dcdf154f85a0aca4b734379a17c2ea6b722b3fbef278464adaed697d59a1141e676fdcceac591b43bc32e57dc4b1366e2cedc599cc9ea3088a2eb6f197a94247cd29e3373d9ddfa3500e6ade6414fb4fcbf96081cc5aff4f7746bdb30a2028f3c27b66597fe47b30a90f805a86fb45755cf46518067e74647aac7922db740b3ebf555549ab64ec212896c78bbfc0e033ab12cc83f5b5d0d12abbec9591b4609d1fcc9c15ce91974f18b69edf3c39e81e12af656551acb82086062ce04d1cead4357f32e2e28d877f49096e225354a6846d210cf257b00d7b13f0a52d99af4d362e6c57d7958bbd06faace30870073ef54c127cda58d84fe283ab4907df49db4eed54d9ba59daf12e363b54e8baee6377515e17c316f3abc318e75d7fe5263673861f736f12efa90c571ebe20e9eadc0daa4b42a798241b880bb4caf765b5c2abb3224cbf05a906f358faff69b49a42d94f5d55afc746611e760a0d6dae13e486f54aeb6f55df6d30908e35b4027cca1cad853f12c1e3304c18da2e5a6cd964ed3ce7307e13b8c79963820096340675131ef2704c516e84e14b0b22be4222fe6acacde41ea536b344a50afe51a7cbdc976179ab84c7cfa80bb93b738a6812f0317d596073177e51e466ff0459c66a4bee900b764203d173c9a749d1eead74955b396428057cfd9cf1ba714628c4312b7eb786598b86dbd37c66799b051874e96c58f8479be09246cc5a6b69050378a18dad75950d174b9e8ab6966e2f453d24ccd2a2fe6e063408d5b1c7efd3228be18bc32d96ba5afa89b4bc7199ebbfe721c38885ea0601939bb2910b9ebd09494d203dd2c97a2e3943477d385a353b3460d10a88e777122e2383232adc77993584fa8253d7a5aeab4659d8665a18b8cbc1d3cdd0dacb24bf6e104c399ea11f0cead411f3a930bd240f95de6bba58cc402a71b098852a11c74d772abbdd2a39be03cd93fece377be55e011105de400f6c2b878b2d03d4e7e8363f0d278f59c48fa1411ddff5b7d1e6bf2b40e6d59991f174709790b27363f1f581e7d39d3c13b39c204e474abf0ab41f3aea72ca0db9df66ea714b425463ececa1c7d5025ce5738420434bd551996bbc4729cbe9d6827cc0bb68630edab465b63859b555b411e67f64059193ec14a2d5b3ad0097ee8ca72c878d57d82ef8d6655ae7ebe3f492ab9e9065d747314df9b69db5a9f7a7047a8fda52f025c860a1cc0c3766b6c2ced55083c5ffdba3e0b88d7c450b3d2631bc2a099e29fe7e856e82984084e86fcb70847ee69464a24659aba3f717584dbdf5db738c4312c090f3da2ef9dc7cd3eaf17a17913c9e916564a0160e6ae8c3d0e3aa17adc290cc569087da7d9f2bec45c36f3e0bc38b0716c7513483dc8dc0754b7ced0afde800f61cf0bffe03ed45d8a70ae57175cb38f4dca8c759b895c9d6cf9b8a0b844021c9198a42a379783347e13609c22f461b340412f916739735e04aeb6250df1896e267faf1d1efa6bdca4cc1a29ef04fdea56e1afad0d695215c8082aa69a731be4100b9af4b192dae4313781a66ce400c2b3951ee612b50e0557b996f984674f6e5bd62653da44e63b753bb8ba9609d16b02305b68adb41f7e6c2dce3134d4046806008c7c9bb05a03cd162c358baa7a1d178da680a09863d33856bc30b684ca8d2f15a01eca10a630ef9307fda7289332d5ae061521176c3a5dd727e9417654bc1605ccccc6e52b8ac2736662e0acbe4043f095c14d838bff683ae4c5751578e94457da431e4fd7c30e0e24acc06919fc3d93b50a84d3fed4c1407ae8029cffd605d55c1e7f9d96de84516e3d23adf3d79d1d36bd3694f28f374ebecf8a6b6d4d87a7f66e42bd2f60efcf4f775349d802e982b5bfd4c4564d181c537606b94a1a6f59183e56bcd6e1ece217174e1cfdb3d177659ea6082fe1415777ed54aecce113360fafaefc1ddd0005e5a1c50a399dc3d1a25535237a3834d998f9bdfca2aeff4af23f1cd3b27748d9e631a07f8aca6f530e8d9e3a977f6569651c46a2a75b78d9ae36398cb7d3d172ea23b0764978a8b07d1f483dd75070365de20821621704c0073f8021cd8dea08c1b985b008a0da1c2cf98fa9e198e3744428c4cf40e0e0243e03182128005a0c9f6eac8e7110e007b59ab81b83e4b26a8cb7e63ff8c695ed05ea3bc6a3d398534ef9cab986dbb878c0da7f2284083f2fa4a1662618996a856e2f0a056ff47323bca1fa5a316d9b4740e57420f651c8c2b9ffbc0431a7a13dfae2822550bdad1b717202fe06e202d5665f79dc6069c37614bd8d4a02e4f6dbe81088ad28a52fe7f9b22b3a58090f46bebe2409841803e9f3cad7fe16ef070509623521d055b20c33b506d30453c9bec9383fc411dafe9c1e8f3a9b58c88a6ee2e1a28ab0f8725a690c119296bd891b8f18d9166e2e655430acbd07a84d8c99e91bfe4c7ef54d35be11a07f959c92a01aab0a0c954ac311460ea41b72c1f74705c73954945c0b58e5259cbd8a6241bd79d47330e5ec4f92043700d0aa9290ad32959ee320c41e995c174774fc2a5b1dd44aec31502a6490f04d384adb32019b5c5835c9153f4515f529a2d6609b2485c9f0ca0d4caeaa8c6105923f82a32431ce7615f245daca24f54f734ed447d64f68ceb96a3864d4e5f98e0ac65734745e5782e620f896e1b0e488ca3fa7688aa21d8452d135cddc4d6e42d99b2e34f642f078c90c50afbd3982f1bb938fa778cc2e94b2d15718a91f4e92d28949ae0117ab9a0b7b4508a6aab9a18baf3c7041883ed208b15872a3ff2a0766df2a2a5535540b810589e7da3c316a861308b0bd5e17182cdce3bf1195905978ed3268fe94d2b02e78846b17439f5a1b1e35ef5a842b4699eeddfd8c5b7147b14d4f05d1f7d0662ab7c86366575e6721245d3281ac5df875284cbb50fa973b35238e21c00b129ea332bed49d1de8545be2b484e3c0b457e5800f86789c6c3b97235320cfc25d1f50d994a782fcf2368d3662b4a301f40bb5501565b943127dea31778a98618cf2ce4ebcaadd03cd05f8cc94d412d4aa7b915437b0a9c168a53a3220923ae3b107664e165baa9e4bcdde838a2df39674c1e769e4383d2df0fdc229d44116ac8cd20d54c1f21ec19869336570c3973e53cf5df5305af112081a682364a26491521063ea1ed0c7cc8cfea82afbb587aa5eb262d9afdff3c4591617e6eb3ccd70760a8bb3d3b8302b1c6fcc83b59e683f8e0b9b4d89d1d74628318a28c5c795819a8fcb5d918b39858f1e90524752a4e8df90503f6a4ab26def1e02042db4a498280c092e42c8be47802200fa193bc26c005ee0537720ac66f579aa509f8fb8e6d714c0bb13c2abf7ed7d1cd295fa1ec849e46c4c8c2f222e8a1038416bb428f1d4d113e577f9579288a53f16f56de07313f1c389a18d4670b91101f48f044159533fc1beeec4ba6b7a5a1a4f3a8313e8b678811486dcba62b3e5a7c825635d9cdb10320028b397708f083fb4503f5b044144b8913b66f5c979745c5e090ab943643860a22628bc9e780801cab7614e2260811eec1fa940571e9f2a43bafaff264507a9e837f1514a99fd07453cecfbe53e9e93a5f9ca57f53e19c3dd1ad5c27b2aaec5f32f1a5a02a3def897a25eaff0307e96fdcf94e27584a95c7bc3c276d26951d1e3d901550b173b46b62c68c8e6dc6d8237332cc6000cc5080c17c147873f9383edbc234816c10bf82b7c4fe09da4b5eaec1e7673b2268c634f80f45eb0129d055e81c321175b4875468d3f512dbdaa3745f4f89cafdadd16c403801638bbcca6ebfbef961e88a6c16e3ba2d8f3c0e4929b8742740e782003ff7148950e17057101ba42b23b5df430a955474dc636fb1a3934aad26b252306001ced50271cd7707f592136310eccad4c8de0db2d650099a56540f923e8c9585a397b67f3a556584eae9caea02fa46e124f31fe721c994bb5230f5b673607f53e67a2074a6f8b152d349520a27dd95f76a85b619dbead014953e4c04a07735d34f3a38674427e050ccd0e30fa82d950b601201d728afc72b4da76ae14d1ec25d759264e39da1461cd3d7f516a6530e2c9763f905d99fcc4a19d6ffb1dbe78ad5e72da15012fb3553348d6adfe992c9350a38592b96d942f994d9ae8b41a7a8ca083a830111104b147d9f867843b56feadf4164d1f03d5b24960179c4ce06efda17278e512bc5420d4850b863c4068c305b88cd7d5600de0c03ec437db37094e581dc1a1e70bf6a5d2dc50f5ddca451991efd183d2066923c0e7a5a45a8e173a0eec31ef9079d1d28eddc2ab87bf19a5f4fb671fd5b543580fbf786d3d8487275424783ddc86931f7854f350589770e840f6e39a575e9046d7216f202abc0daf64fbea7b524813468af1339bfe7891b4ce5fa13fe8a465b7c491474310610050dcfb6139d089912e31e188efc225b8a99243c77204ae947ff2218fa32a7bcd640eabac0f77f66bd4e061de38ed0a4eec46a0d187dff904bcbe8c16be2ede5979beb2f9a01bef7b191ab4a12eb60b39909fbdf3dbc32b800957bcdae58234bc264ee6a7b96834932dd67707cf5526e6feaa199d166ea306434f43306db5805d24d7fbcf240210051dbc78eaefa1fb71c11691d9a904dee71abd5ee06d117385f2b478cd05a1da4488364f95d6f92601aa9af512bca807b22110e4fb98bf16e96ac8047a72dc17a5992d92cfc4faefc700dffceb03f8e7a715305337e6c2745eb166fa13c56921888ff23385d93b6f4aecc7137913b1318b6ab6807cc8e88ed5a61c457df1615d043dc0eab236a18752776da0804b7385ae016e0797fab6739f69bf3c69a807f83b645bdd0b560b0bbcf3923bbe52e2160ae7fe37acfce286e6950a4ffa07ae3ea0c3886c741bca74009cd78152d14d04bef51b72a93af116e1f538810b984a20a0a9f76cabd06e232661ad04d7f801ab9423d69f50a439b4ed687cd05d6d01845ff10a74cf815d323573042f76cf713f60339983aad2e942f6262886855fc63ded31c91ea981c8028d805cd84a61ff14ca4120706fbdde3d076cfc4fce3b55a3bf49faf16874f66b9baca308286a1df0158d472633c8929add2a52c5c4afd41e5a1f73f49cbc70538d80cef957e8e775805489dff8059e0fe838a3a73ed60838794be4ff7b07c7bd515309932214e13b1958f55d26fbeea1d602ea7794e0c71a232248c88a3f1920afa86c90aeade22760309ed5aa330e96048e83c595b0eb482fd41f74bac698f1e809378580560090705f129989bb8fe81ed8c5634a9f78e6135533d066133d2ffffc3a623b223d723de9e8f8075ad85a9be81aaa30da8a60bac548efd66dd8980410476a1020c9444f7357034e65a2f65a21a13bd681dbae456a5e93fd60e1fd5d05033f20f70f6acaf448e3b07aa3c6f3401fa0ab6eb92837c958f1e79aff0182599f962df17d93a85a1a2b722b1ca6a157655f5a5cc7e40b7dc96c00637e3eaef6d932cb40c747505cc9b9b02b4e3098a7c68053366b0f7ab87423a1594a099fca9255cd95e456fcb03b06af4df06b7ab5cb8439eee111f7f9993cc90931d1039af9e3bfdcb943bbfc125ac4d24cdbcc03cbf3fb10c036733caab550fa13280136b7d3b688a3a972187c5ac80acf69b0edc600849e160d220eed917b99c42737c234975677be8bd5f4b8d4bbf8c4f4f0a8a6f7236c37b330bd8bd20ee93afdd0b98fed9425341b7beae423e3776d94c1ceae2908af60a6bf7a0c4eb47eb976aec3d98e7b6ca7d0d1b76b160ffa4fca42ce96742f06f6c5af04f856fecdd5ab7afee3d06f8e9756a54337a62ec02aa68b403dc10884e3b7c191a89951a4ba1fd01424993557062f7c70b7b51675828d644cdff79b822efc2185c2be6917d289368b04d9d300b6ba06e0e15fd715dc87a9d05736085e9a97ac8ca5e55b04cf74c35649a526617faee01c8dd27dbc497fc7196ddee25ab0b1fc8f3fbcccfe791d09ff4a9ebb89eb82144aaaf2b7d48a16ee44e31beb1b07537a8bbbc40556add6f5b4baa191ee62589f56699ab097f9a79b6c27c877f7b70414d312c423219933a6a42dc3ae7c0211f45e25ed955759754638f3f716364a5b27b2f51c519c40253569a69139aa731f96b729b15d7b509dbe6b0ee42badacb52bc7ae1571d1037359ded2839fa5628c514110b084b301dce26b4bb1733adb957773d6f1a7e544966988cd576127ab93660f1d87540568e8e64b5325e9073ea610aff19e1ae3c1eac6b0f3644aa14ce3a961e460ec48f517e2e7eb20bb9d8e043ba3dd00f7781ba4713c5a6cdb874ffabb05aa5b954fb1c5ca077007bd11486a7dd54a7a3bdf0e458b9f1fc015fc563099bbd40e050bc901d004d6cc02c8dcc5f6285a540e016e56b98fa23ff60eb51ec199b1d57a73b22e580f604b18190950b6ebdba170717a1e300de672d7f2da8dd542db4f627276695d6cd90bf303a0d584be93bb41620d095108b61c2ab4d49527b82d872bdaa5a038683850465e01ef05316f5c45f8498e03ea6bffd845e503ec952fd82515940bb0837861975a4c5f40a5f07bbb6e3bb92e6a3a0b0e27f40d268d0ca8d575245bcb12a29404ba60e86663fbd99b5c5accfacca02bb538080ee314b55c4cf2594a4b895983a6496caaada31ca2e37becd7c24351c2c403a704e1a68758a971f2111228c7f4f3ff1314584ccbbec3f1d0d8b4e7b402508ef30f3a3ad63b5f38efe80c23cc50db6fe09e596617309dedddc09aa7d0cf564a77ae18244fcf0a6ddf283beddb856291221108b057089c1c42cacf3a2bfd5078d81add5c3b4f47e5b44139e7081a15309f5f93c2b252f3ebd3eb9c23a0080d47d72db6cdc7292645b2786d64b2b86afeec30d31055cc4952754366d7730128d3232a0e8e3df29bb50e560835964a12fdfea65ccc4dfbbbb827a91e4a8cdca2bdc049af47592253d2982576f43e6059c5f6945a67db15ef923538d20ef106a1a363793e7e9658351b6abdb47a4d7bc149e1c2df2c8d3b3419eb6b06d1a027d09cc47f4c8887478d0440cf3cad46e083c24c087bf069c08f342d41906d58c16760522931db3ad6ca94ee9dab92ded1796bab1427219e455d3919c9d8f790f6f71c9e7b5f42ec4d1776d071fada167ea23fedcfaca0e3f772d3bd8af38b6d0d03c4903fbc9b1b8e29b5ad28694e3b2eec75cfe88f2c594261ecdab9ee9b5e47b080b9227c9ab572e46c241ad8ca310fd69101421204647784301cfc9ec13aafde221134625b0edbcecd986fed91fd0e1e163b400d21f06dc0faa055e0a1535a1e0efd98a982bc2dc8811b69613733e93aac8daa5109620c797ff794b5eb822e7ca2f01e6f2d6e86cbbea296b3dcf8e610844b5a80966f28bd87967725e66e9ea2e47c514bb9eafb5ea5f947d0595f98a78c7976abdc5025b7374803dca598420e7ab68bad74155f945849e96f0c9f866aec9365d20a079c9c2aab2c6f3236bab674e7e54a3a651fc27c7389a726306c523fd699fb1a59d67068b4f0a1d5b65b8bcd99ea4a976bbc2d06d501eb89c445614ee5fa84d66138115db0976a6a97d15f7c364c73b11abf0131cd09af62ea099cbaf50fda60b87c633f9f91c85a1816e285e2422513a5f9d5b22331bc82fb56eb22ebc9af1605c8206b28c260bc5a2c598051c7ead9bc5970ade41e716eef185228b273dd51df16b2b4c64ec823e66fe170e021bb79d0c6305a6ec418c6c31b9b8d299afe98784e6a0f15a933f34ba1e1124c61a615257cf52325dc695871bd1d71277e73e1d9b365c945c0d60ea1a20c450afc0ee8400b2e87abfa1c0f41a3510fb73769d9c1e1796a26cea174081a1698924c761da1e15949a6b27454be917e4867d2ce7f9c3733830617b484fb7d895a3e068c1196695c17e50cdd0c510ed9a6342a61282fb4b4280fb265005a48703a135037c5af89fc2d014b570b61f5b1a87a71f2f73cf75597546fa144bd566704b7542ee001a9386c9c013da8d67092ed61a5b06cb4a865b85fd9286202181a8dd2c643b7c5d758a615de8fec451583bb9058aff86d92920f5d59a998dfd34823383a0e9800cd92b3690573d4120885e5f588e7f743734b4e0d29f60ecbb5992198258b9d3772ef216067cf573d3178beed7a74aacb1f141bfe00186e1791d446082a0bfd8f940f1f0d4f33f2609477e2032e11bcec945244cc5ede4090a17768f7f8327bf45bdf016164f846ee05c17c3796bea5a2ff45d88fcd9592d4d4a8e645aeef70e4e22fcc21d90a2b1eb344aa613ced9f532fcda9bd4e0354834c6ddddfa56084b156248bad0ac2e012555c463742bc82ddbe2e08ec0b9984672b51eeb2e6ad20eea61824289086673422832b4b1cfc0d7722c2490f19d6d93aea01924aa141d1e148522e07aab975ec540049524be56a2ce241ad3446108e1b336becf4c169838ec30863d90e8e8ec76ed818c2212f01a0884ce5322679db35d85a7f75bfb423dded6d23ba2becc5b842e2fcaeff66bd8ac2506c36fa95c020e79d16d5b190d6a69c9545355b34b7fd8810728f3d24102922d9433a83c055df4e8a9aef1453b7112a96d2c3824bc594770c40383d76d28312e8bcc1131745913a31e5d476abeb6c28064c838313f859c34277aa9e093cf534725d6ed6b6db5b9020e51502b460b471f5b2122ce2c2bc980246036561a6a75900a8197ad0125d9a494e146a580b60f64f5e4818b023fb119a5d77dc5efdb7ff87117069c3fe11138ce7e2976dcaadeea8df0f3d370685dfbf2037c2ac323516502e61f72923c7a7d7f3be200eb62bbcd64a5e60eb8e7c187d8024d7e027c24730b3ef4a64eadb09c3f52e0d2fe17fef2f0d213a62055af037ebb2d2b4c2396990cc9f3e61ddf5a97bba6ccdc682c29ec17d481d49e39f9a1348f2b47e9b6cac885b3b2ed5b4b428962490612298f7001a60b3e8924bb8cc41fb3d7b3083c1e8cc670490d6ff955700cda360647c5175e1d2db9d979107a3388487fc37ff31a709f434792e3148bce6dc207c52809e590e061ba41ac6217f8f0ba9184ccbf7136b0b9cf04b6f2743ac4efad11306adf914c6575d1397b53f77c4e8c549ce492f3ae6530ba4e04bd20eb4326f6a01fd0c192db110a256db51d264ad9640f376dc69650c4b7811eef8f6b1b6b0b5712e4a51837cae771599d58a7bba0aac6a9aa9249f501faa1ecc7650586cd771f9756108a3bbec81d9e6ce2c1f03da360e735a300e3b4a0703750a22239ac4fa911476dab487af0e0b6691c73cd9e02458ec75e7055a30944d1fdd1457a9061a15cab000c86aa03b1a80399338a05928ebdaadf54f21f4daeb0d31ecd5dcb08869da4a42f6de7b4b29a59449a61907e1064707f177fce7875173da6fca27f35edbf46ff538788223c501cf9fee8a3d7acee9df4e91b86f6614f91377b99478958c8ca451cc5b3e04837174db382de3baa9695b76bb9384c160b0680483c16030180c0683c1603058348a303030180c068bc1603018110c0683c160b09899335ff8130f4253060683c16030180c56e4b5bce5239231137de4f7ed25df89464611c977a2d28a49a65e6e914a25f09c3153c21831b78587522ef79a1aafb22ea5359e656d1b47b78dd332ae9b9ab665b73bc92cd3ae3d59947d899d87fb8e475d700d8f007d43df86473f1ee984408009e4aca39f68e3d06f56cd345a2a0254dd6e17c4b30727b85f37cebd4ef84d529823cff283117c992413938d2f1e75a9e1ede89bed6bbc0d7f98daaef6f1887bfca13eee4fdf56816e70d3be70e6ed48be1f3fcbd77eb70b76079d4862c24c6a0b16348e3ffd3870126f3c727f99a47b50ceb6502e0024bcdc4023c3c2062e5b94b82229880a214c6784f9228631d0cc30460a1d4383b7316972a9124555507964a30a164e7839722599018829c0882186c885316480e56a09c036f4822c525046972698d0028a8ec10c76b86225091133a4913402ec82a0014821a6a851468585142cc8969e6001031130207d890196b0480a163154c0822fbe187344b6021b394589a62a7789314653cab0a43ee9b6173e29aa502970b0d24af693fa541aa4d48da62ac64b02c6249991a58a1746a0826bc3141c7e08b28204144e1cdba0b5a39d2a2ad23471ba01890c863445d82dd270c921ae45f8e61633c592ee0731697c48f10053365807bedeeab617eacc61cb90c3660a9247398c4a4425d412398c216e6549a24c50104ac2c860054a4ba8882282921841819430c6c00086284aac2f86a244e1c2a1290c56d8b1a1e83a428c2f4e20e9a0c58a195618b3dc0044165cb63c21040fac3086f12822c5589a24565a49c324fbff98f08aa59921fbc7571a2bd9ffb6700a9fc9219841e1a630556963808618331a172f361c062b9e550ee72b3133a0dbad74ca9c158f0fce864ba388bc857e871c9e9a165b67fea059ab54b07da985f3b50f28377650eed8f84dd73de487146573d38ffb2ab0fd40cc29cc0f6318330af4b58e3d3899c3995bd3be9b7df6a1905da0fcdddbd3856d3e2e07156cbff935e77f82f61dc9246fe4cf56cb558786865c43ae21d7906bc8d53d3c535c4e1cb95e4abc5c45595c4453fc4a963664e9724d4972a5ba43e54efde694cf956558895c6670286332d63d63441f6926f638e33aa15cca32d63283c3e9724d99e2a09c442e195c75cb7dd2f2767139b03d193c73d7d7deeb6b4f42b5afa986e08febdaf549d0beda6fe1defa5615ed93a0bdb5df8246826d21b3dfb3709ef55ec980267088b3c437bc4f06b72725614368a4d56a65165299a6a6077ec4c699ef4f3f6f9c39bfd9d19b0249af513629570012b3098d237fd20f9a70386180fd6555aa4aafaaf4aa4a4a54f07c4d25bef96a07630ec4df4c960e73505ea4a9345ff328caee699984caa7b40b12b333358e9c5ffa46fa5795aa52a522fa4ca34ac6752491cf1738fa781c7250aa8a5016fd96f368bef0cbdd46a95163e3818a64dfbdfd0ebf8defc81120568d1a201b3650df11d41fd91e6803aa9e09d9fb3b5b0422f6b07f84dfc46a1bc77e2873ffb559f7b05f4f9b8f11bef2c6febdd6dab8258b5b1ac7c88b5d80883e914bf7b06f85681cfb6eadb56f3f2ae1a01502873c72563ce250f7f460c2dbe7f18fad14138ec16cb5f67a219010cfb3b3bcf7de304699376bff6fb6af1272558d53047efbf6e32b1ec52df6a391448ac90f6de4fbfdb57bdce3b297d917ded0e1a0ac1fbbd838219883480f92659f5d903b71348efc156293cdfe5bf5d8b55659ebd44efea9c691ff44d873bc5e8d3d24f5b04de34c1f41e0d494456cbd23a41f34e19f453194dcc18fb79ce41c9a44b1bc85c3dc8c17dd8b712af560c833ed536f1ecd20279f2e706ce5904ec9924e9930b9335f7e23ff5e8c53a9396159fecb870af622bfe23a354b1f2e30fdda01b1612b594fd5398c197b2a7ffc2afbdc372bf354fed96719c6dce36f8155e3a9fc6b7cf7271b8ffa54b6e6374fe56fe3b3f1364fc2f6a8ed6db64fe52d6c6fe353f977ddfb16a322cf22956abc08f32293bc913fbde889e01eca6bf91d96379e82000993957d479064dffd823d8be748819b03aa9ebde0b6a79f416326f688612452421107a3b32470048eb1ec5470cc0f2061b2eef58771c1d28cdcc241ff9c2d64cc9b408ae12497401aca386e6b80eb441d7f32700f4591524a29bdf46b943fa7742b5bf73b5177bf1b75bf1f75f73bcc63dd43ddfd328b51b7925c92b07ec9d44344598cfae7ab7f1e7577ff8c757713157577f7d3a356eaa7b07eca344494c5a8bf1ec99dcbeafeaad4dddddd6f89b274f7dba3eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeefecec864b4da696f0a3cd9c6c1219c4c3959cee305f49b6893cae1f15123b798346058cab8d09083880d8428c3460e292d663097a6a636014263fca0f309a12912fb6f3125db172831c7d57dcd09e20721288c3ce79c738681431d3272d973689377f0c8ee4a82c8fe38287b52100992849424116385c3272579cd4b2400a433f2fc39ff4691e7e3241762797e171dff449e3f5d0727cf5b0254d4496ab990fd75ad58f950fc1c7dbadc8b533e94a3e4b13efdab1f10563c5f624ee455a20d7e339fe815638a19213a138bc5bc4af7d4eaa134a5a125174ac66a75291f9011739de12e27b231d648b1f8e4d2d793ece8e56054625322bb9e4a48967dd9561489b25c0f679ecd0b2329bd8e62b1582c4684098db70090044714ea6bf1f58abd62afd8eb7526a52315f3a018139a1af31653f4c9d0c47832986beac1574c75b34814331289885e44af48f48a44b1d5992cd6f2a118532c07148cfad3fbc734a6d8993462f5cccd2276021cc61893dc89482e25bb993723538c21208b180092e0b03e7ddb0da94fbfad035285d4e73e435d4dfbadeb6a473ff350a85986f163a19a7aa241fcef9fa069b57adb6b5ee74bbd1452998b592baa2f8f2faee8e5e08c4c5f8c3938115006d393cc3ef321fa286fc56a7ccde3b7f15ab4a03ed4dbf88ea04edfe779fab05f353e157dfc40ac9a4f455bde14391d3949faa984cc9cfdccf13b538f250346f2964bf127de923f639aef685d192d57b9fb5bb4f1de7bef8df2defbf77ebdf7defff1b8e5de97392bd7d9fe3e0fd7c9fe7eeca17be8df8f43291df2c555f2bd3732e1a9b7de7aebb5d75e7bedb6b9bdf7defb4d944dd9fd68aff3a6697fb5ab5d6dd3ac66ade6b9bcda4bedded7fd78743f6eb91f8dba186d61023bd2195bac7b3a40ffbecc5e7ef2c775e8cb2ce74b23b33efde982449d5affc789348eec1e31ba87fe86f2288b7aa8b824b51562538e5bf5807484a40f1a665ec36124c6a24f0e17a49459525bde086cebc3051cae16905543b2a79f3dfdee3cb3143978c50b0e6351f7f3e315dfc1c19a4f5f2584fe7daa1272738723ff786cf94e9be185e889313f3cd10516acf94696b2ec9f4a21c96fdd2124f9218fdfc88f3d2c9551a01c733cc11105fa9d0f0c30d294458d335ffb7ec76b52dbf2f562d57ecb38942759d43be5019cc14b33f3e90287b1a8355f95cdbf17e354aadf48e3cc88c493a7f58948d806092fc190947ea447b38e2af89ac9dc77aaa8d438f36dbeb97a2aa01c93d0605a91941cac1e50ce3c9973e80c81e90423cb2e1a43e2d74f25a48633d707ca99e779dbb81c4f70e801a0dcbd11073b07d021f4ebb77540a89011baaf5f6cd53cb78f9d03bad367decc9bece8fff8b6753784a240bfc69c65dfdaa71aa2fdfd205af68574e33ef3b80fe29ffdd6791a05f2237f9c7adb7761535353ae1e0b92fb62cb33e2e0a4722716796c153938a31252511977e3328fcbd7eb4cbbd98d10bf1ba10b58ceee773724fb544372f68532842e987e7ff16228ff789548d7e30185fa5a5a6e5565df2974193570d1caf4b509aa8464fadd8f1f9522124895aa67bffb41a423188d23df7a610736b472fd22192407a9fc89f465642c9ec9618cc598112a32c82d8cb020e7cb6dc86187d302e5693fa21970ccd489ec349a477cb38b83fe3952e0facd2ed9ff86f7841c762acb9f5e08345f25402aa19e61bf02fd659f99107d68f63a9b80810cb80e51f7684f3fda70c57538fcf48dc89dd3530d9ef2c42af4e9873cddc393698b526a85e3e1b898398de329f2ea31f2c6a5546f84fa2174c15af578a8a9f94e9037b40479435f8428d8c6d7780dfec66b2962f335aa07d4bc065fa4e635a8f98ad4fc8def48cd07ca1bfa36df45e1ff54b5c6035035df112db57e45f0d76c1815232c842e58fb54952503be9fbb628ff8f6d380ae673d64f43fd06f6816aff54103cfbf8ffa90c756554264068032cdb47a9dc1ee59459f99e97b107deed3cfa1ef837e03baa77bfa20b8cef6f445709dece913719dd3d32fe23bf47fb4cf8ed843524a1fe58571c9f3bc259db64d92d9923aa5bbb423962315438980d13ded8d607ffe66adf6dd0d89d97ea1f6dc6b43b6ef3a6bb010bae0ecb9df361e30fe5a5aac6a7b95fdce99a77913a708bcfa40048481ef17cdc41ef4ad67c2d20ebab965da5abeccfe7ec84376dd5f4bfd719baaaec37e36fef7bb9bc0fd5a5a6afd544372fdc2a7dffb195b7f088166b580e4befd90876b3f245ae26b41218514e217df9f7e1b909f09ee853004f60f3f84213065c980dd12c1add68fbc9937f3458882b7d7a2a5e5cd57c4fe36eb17ae72b3eccff9a968f600fbf78b58fa473efa15a93f3e3f147ac95d5ab1cd39e7bcf6da1d7baf753cfdab71ce39a79473529f75da285d449a447ee44d7f0761cc3f5d072affbc95b51ce577906302321199e36f118d7fa60212b319b93f66cf48e3f4cfef2965990806144b1129928966363aa57bf005ebcc69644e000c8163ec39e7cf9c521aa79f014ce0e801181cdf832f38541211c1c1222ea47bf86f416648e3b8fc4000e1e81edda30bc2d1d1516fd13a51440615bdc411497cc1a4082c4c88c40451022523965c6982e20c95d399117070c524038d7b46498d7e017765cb17a41ca800d343bbc088305c78085346931690e1c55d828c30b8b92445776c5dc33a36e4aae245caff7f4c28d32ac2b993aa4891b3dc4955c2a490b8a3546a721cb6497d816263b0582cc624535c52952e502a67c3619b318cc6788d7194a2e224a50a968d04b823ead0c03587dc11beb993aab8322d836d0eb91d3698e3381b1d4c1c1af7de21284a4c2e206596602e206030397a0114335b5cb004480c8ac2bc00c40cec6f874477c50e31e470753a03a3728bd9218995810e619cbc602db7181db868a2c3145ae82026cd11ea074c738bd121092c68e6191b9dff71eb6aabd0d6aef3390c418ef1025b778faddd54565aa994eeeeeeeeb1dd5bba26c5ca49279db7df7ad56bec52fe3ffd6f1cffcdfe77cf3be83777f7e31b27feeb76d9da75c22f68320b1e806db3f50540a7f4eeeeeeeebe64ae95d4bd1b4bffd892bacb69c4b55dbd0667762d077952a0333baf990ec8c0fd5cee24223468aa26559392a26b72eaa146181b61700e83189ba915b7c46dd391b7cc236f3979dba86091b79fdbdf1984c8dbe39450de687841de1edc7e45256fcfe33a9d44d445eb48245a59a3d9cf2c9b9246cea61891b3bfdd8f8cb27ae72259fb788a241988521aab66522a85884cb748d5583a8ac2c16babe1df887b751081c39bb92c0a9927925c3d648f6149767f8c997882bbf872f8664713305c116508062a17cf23b68e91739df8a984c8e8ef23074c595d460b29563086e8253dcf646cd2533adcfb534da0f666f67f10a7e4e72307acb12200c6044e80e082b3d4cbf707fdb17fcab582cdfe67f93922fd83363aa6e0ed6dfe11c2fe3636dd5383bae74ec861fda617daa72c2e88fd2cf35248a9ee7b2a5a77a454b7c70c187c2ff0af781e9c475b3f4f37189aeb77f7169770fd885042065ca7939c2079129414e49043820244eea5a4274cd993a05cc9fed9630c12a2dff246a8fe4f773c0ebef0e1bff5e1a0fd7e78724cc13c5b2895cd5ffee62b22124c96f4959678564beac70f7b64f93dbaa78ea012d23f9168e5fec0bafa0161c5137fe483207f259f27256fe453cf710e19e028e598cd578899872125b189a5a53fd56ab55add101fdf17b6901dcb08819c86117dd3b9fb66c280fb95baa85eec15ce878c064dca9684932372b8ea016fb9939c70b162308edc494e883431706de254029c156186154cd78b9328659cb8c04941c64d8251b9939a6ca191814fb9939a8ce1488037c89dd444055a13f846eea4263e6c5170963ba9890e1725868b43e2758231d9aee8ae60a21dc99bfe71ef936c69cbd6e48226d70a97d614e605204b4d4938b122d6e4050a902b8c80506aca1204e4054c4d454340aa689aa10910325b9a9e34016285910657761003e3c82d068b163d608962082c5f68195850a02dd9a104302c24c84e8035c82d068bcb0a2c4db27cd1496e6e54abbe333d87c706d8d6be6163539f4ae98837727ccfe1b181cda986bafda752a914c6a7d50a04ff31ee243737aad5ccde54ea1f0457abaad1cd951cc927f7d1cb474702786c4df7c3561f3e742821f9f070ffab95ec7cb50241147703d0967af4915fa9ed5a6dba1fb6daa8d5524bdb0310bf868c87a3e6d6601c5ebc8d636d56272771cdde75da7957d7f35ce7e79873da74aed6bbb166af94fa1881a983ab30386f5ee36de49c934a29e594737aa4148c4e8ecfb3da5aca39e79c724ae971ce1c1540010514504001858d44f9a4d5ab539f7eeab84d6a32bbd2d6a60c6082c7a7948e316a4eff54969183273ed23df6909d6389255a5383ab6163b361a3a16c6e6447474da6937e7cfccc89654abe04895c7973f4f3ea23950eff51f225551ad1e5a4d5de4cdbb8ee8442459f13adf3714d476b6a70b7868dcd868d66732343ddb8f7ca0deabd130787a3fb411f471724e6f93966c8b3a2bf41eebfd13ed386014f3898adfced57a3e21c58a5d2e1353a00802ff62bebcfe88303e0d1673ebef75ee7a0498de7f0dee823710d3eddbfddb3419aadcabca168bf679a69ccaa0924c6ecf9b78a31d2b06d1eb0405eebe31e638f4aa774777777af7572f004872c0c02788de3707f2a51940328f40630fbbc98b47a0004388fcc7ae791691d89df9a516d6e721e991cc79d84901c3051824f69b6de1125b5186c106cd08320707c692f1501bd36cfe813bb876c416655a3dbe4a4e6799e73e6ade3baee87f65d1724ce150fd7d17e3ad85a067e06dd87013e100cc110ec9d99e7073a8aebcf269216b32f3e66f898216366605bd8569a7269cef7187bbc808629df149ed38384b0983ff840a2664c97d4c44add9a5c77777711a400ca0b430441c60a90605f58d1831098325678c10a636c076b91b7df7eeb7e6cddc7f918c2f1b7f7000b8c63cc6858114d668560deb6edcb9628797b114c903bfddafe04b9f3dbabe03a336fbfe2b9adedb10b600cd1448bb56dac2d3369dfa14dd65e1093356dc887ac317121956702ee0b4c929674c11dd8d0caf669f7233794a4f1c58b0f3efca0c11133c04910f1c30f5bb62843e3d00f25fd18ba07fd7e9ff4145d714af774761dfb4a2961a47c449f6680d2cf9ec4a024e91989adefb6cf9e05fa978b560e2f17adcc15a980fd54f75b85fb81998e7e9a6793791853da501cb143932a4c80254b162c202e626071c28b184af0c40e2cfad1453f1245171238ccf16ec621079f04b500d39cbea17f2fa63999da49e4cac9f4a717a73021a2365a39846586faee48f88f2e1989e487d1f54060cd25b38b1382fb13eab9c7df3951c284c32826a72e6c58be91e9736558390201310d9a6840bf55b2fbfe4b4425bfc6d7bc4a7e0f70d6e9f1a39ecb3060f94d34e7778283f473bee0f6b0e7ea9ef9f4636830454d6f6d1cfa3cf4e98a3e0f9d4ef00929a8e03af1e977de09dc7c82e70fe08c06fe84ee5140a69f42f778a65706328d4cbf3095a3505e9a668050809316000144163edcc8612cea9e1b4cbcf8e0036c73975ce8639503f2f81d291dd84616f98dfc5ee5803c7e870e1e1b971a64f9f14af7cceef1971f99e81d1564c4d23ba9a628ae163c44471494d0381280356529a59c5170131fd2c70fdd223f1ac98f45f26316f9def9ffe41081c35824efc55266294a5d6192e50a75a75e02feee48b8657078ab379fe0f8612cbaff03d672884728924ce03062b1a142ed0b6f77dfd9b80ef79ded77a74e9f92d38956ee5b21fb703bfd7d7a3abd1010ebf409e1efbe6f85eceb7450856cbfe601f518f53139755dd7755dd775a7d3e9743a9d4e8fe4d4755dd7755d477f76a7d3e9743a9dbaaeeba8e6b54c8c915a0760778ff187749734ce68e395dd0ff9dc8f23d9c6415fc0110e71fef8f958f174ca07181c3d52ba43c7ec298123b07d95cc7e7a61cc31b3d98a8bf4558f69a5f4db2817638c600a3cf28de13837d002ef70d0a3bb0eefa6d8b0dc995fa842f68f9ef633ab94524a29a5da977ddb17aa80c272a7524a29a5945a6badb5d6d24fa8fb263472859ac9062c2124d45a6be79cbf8487355fe888fc94bce9afb5d65a6b9d9fd0fc5a6ba594fe121e16fd84687f107f1e6904740721500ee3bbffd7dd41644daf599e91b45296348492b670411a2dac235afcb1bce9078a48ae6b556cf325f5c2ec0791233964616614b4efad39e7fe08108bbb0ed20f051666d6be15ee87fd1f90998710706fb94f09508ba5e4089226155c11461968a4d1c4e25e0888c57d42dd6fdfb7c27d6abd50855c3feaf1c07de72189ad57916b2828890b2c25ddc41ac2c1e23e26dc0b211102626dcff1b0b847c26ddb965a817c2c778490e0a8808b1e9008238a1d9458db07010d0505050df1b0b81f0259dc070d5d16f7d488a34133b458dc8704880729929cf183151f5c68012be8269125cd155650d092cb5282626ab5522c25164dd01290a544a669b1b617da910315510c697912831896161b4fb258c192952f5d28c1925782c204ede0041a2d90589286148881218b22a660c292df5fad6843493980d9bcc0a7227ec8c18721b0963b298722ad8c1c88aec0457270dd6b6b6042a88c17115298946a28a2a18c560d444365c06a187231b9b431560a6c43664c980c891d90e882d8a14b97446bda81042498a2b4d1193fc838fe17e703ec6383faf1d8211f5cf1585b2b9d1dca4651279d33833b78ac7240ba83474e8eef397a31c7eea136fef74e0723ad150c59a4caf24d9461dba8f3c83c3c48c2a97f759ff4738fb2ab7626ba9cd5527be7cd244f8ed5f672e7e7a7239d59d53c478dd70f2aff1480cbd79f7a6db594ce39b52d6edc8f83fdf3d338fe4bdd171124403e4006ba9f8a3b65a0ccc4b649ea53823ce6949ea5bbbbbbbb7b944cdefdc5796f5db6cd031dec50c523bb35872a2e8302d753c76db8866edaa66ddbc6d53ae9a435d67a1307f5ec94435a91d7e09cedd64e10c421ab3538ffd401af3638b50fd0c699b54e3ae98d3abb14449793567b336de3ba130ad753c73daea137dbb2bb6d9c7624eb84cc9af9267c0dadc68c4e57feee403cefc832e7957176acb1c60b385e4a4190d1fbddcc763f68bd514f67c058be2d7180814d05fafd26bedfe024fb0d6d76dc4004e6862b32bd818b4c71282253d083b9c3776c6cf892a5fc783b1802251838c6f28ffff8472ab97962b0d16145872ca5b4724596360c917974a8214c9662ee18281c6518dbfc4d520b34c2fdc29851f8ed0b815a993e0b56f536a5a2df3d801858877f3947b83fb47121daecc8f245f84a5ffbfab375b2a7defda0d50321470b1cde2bbfb0abf0a14ae2913ba0dc344dfb1fd791210b36670f66de8a0b2c793c9a1c4ecfda679e9629a594ded7bcd8ca7e6406daec41aedfca41f954eef0f080e08ae700626022201c7915681c3b8327c26e6bb49f3be137f3eb9794e73b1997d18fe944f744474a721dce4717ecd173b4c0a167c99e05ca162a7e439eef418de33305c738449ebd6344deb84efcf845237227bae4cd7c997227a6eb031af0e4f2fc4fa53c72558acb792bd042f7d4071d74d077c025baf66980057ae7722183eb032b71b403020849688359068229821c9d26a8e4ecd84445cad0d4000000008315000020100a87c3018140209446d3aa3e14000d718c42785e361808a32047611003318618030c000400000021c8206445370038cedca38aadd0fdf7d1fb804c5438ea82341b231000d17d7441340a1d119fb98fca621435e2feb16fa3b11907643f921b57717d22c6127b9625f0f09e5eee0170fcfe7789766f53bea69cb1d399da04e621834296c15ab750ea1ab8ecd8341a2cded7b635d3a526d85fdcc330b258e51bfa7d5d0831e00a7ee1282ef90e1f41932ffbd2bceaeb60fb22181effae6cce677a0d2914ff90211bc06a07d83ab134ad1ef249908e461e3796460812d8297d62314a08f9149502e738ed28187b4a3b9b16bf45f4d965904dc87bfd2239ebfa7f8b4b46d1d013859db7ca12f13ab39542cc9e9745252a93e559196b5a162392ff149a03a35b91438d1329caf8332aa8453b73871ed8d6a4236f125b12d64444397be4636956e8e71e8777b68e1a85fbf341152f9e8c477ee6d3fb775c3526a6f66ced54ce2e6e957ef9283a0d5f8a880d689946c561c7f8293b103b2253ecaea3a3985c3930d655a84dfbfc9fe162b77b4f62b7d96f84b68189f74ad659b242dcc5ee4ac0ac01c2ab95cb958e67408c5e78110fee097bb4873318ac56f621c9508b49340ad1d5b9e1bd8e893d0922d2a64b388753cc5434724c9056996197115a17b9719955c530e6851882eb25597215fe529b45d77c1472c35f0c92e238e8b3be23e411f37ed9b16081dbcfba6131cb0966d619cea3198a41bd8f8853e0fa47e2a770fe94707d92d1378ea88396209ecff732348131a5a4267e18eccc41a06de78d646922ee4b93175d8aab7a3975cd87055ff88632d9fa7b0f854e7da68ba34914be2a6f0654f5c5d7718d3a032ff11915cdd2601b2a6696676dc06c6a20d85da2887edad17dabf4d35b7d6f7d9d2d6b39df943d2c09e4a57284dc7ef7c112c03d546daae98f1cce5165677ad8b9d034b1fbfea561cf463ed92ee3f290efc81f21c05838bf2a729e1954ccece93850728ea2976ed01310fc0ad17ba317d4ef848d694ffd1a4fd39d2b983a473ff536d143f4457e26b1b195eac0516450637e305a87218160f03837f024f7b24da1a61a4378bbef74c4442177517e2aa9078d0e9f6f1962a48f3bea5f42581bc904483f4e907c10f223b573fdbf221e07f5ec3cddcadebd447ff7df3c8f79c442e4d604a26badfa41525c17a05e71b8628e2295095ff06c1d455108a7b788b2b98c40d76dfe9c31849b15d5d52db2cf4446abeeb1f093e212cf61ca5b3fc88ab629a5081b868b619450eb02e20b1ff4ad29161121207978bcce86aabd5e9493b6b125ed14ee1712421d846ff11859f6eeed56b95d95b1f7511e7dd696238a6d3a64fe25eaa11aeaabaae98961a944c6c9fe914bd738b86c73b11cf3c8ae03e107b87bb3df1c7bb60fdffdc65ceb7d546b27b9ca2d76f4514af20c77ea003d7724aed69b06f46f3018e13418526266a8515268c05790cb201cc54d2920a8796ada92b9117d58129bfba0299066de27d56584e77ede28dd5286383bac30f101df6977b63d97d809699fa01060899d473bc45876027848c00738196679c3da20c863448140e14e9eaa100d8c85453c0bc8600d7b10f0b9a878c81ddeb7667187d0256eb8a1410db65cbc8454a0265ed109f70fa0e7e84bb2d1235fc90e141520c21632a19b84b2f270581821667df7e4d5d74e5c31f75c5fa8f6089d86732816dd906559faaed4edeb060ef01df23ad99b958b9055760e1bdfd983a5372c5677e98e16f63adf6831a812eb3d6f1aceeab7dfc024716a9cba4198e930a1664fa4de5f4b7a3cf7227dc20f64d6b67d147f914fb39a9f66c5b7e89b458b58e42b538f5b13b839df52e101e7d58323f06be245c34beba8d91af857617d1f41676a56f7ce8cd6657e27fc0f83a73931bce237fe8b61cbcff9537f888e8694522745e641d334bd400b88a9a9fa500c20a25094fa76f21b500b153ce5141b97e49cb8ab368e294c5e8a1eb4f58b661f8dfde62934d250b734b6dc0d5adac396f5373908909fc955b9620b418bc39c60119dd6c4d427c477ebce49027e83f1abf9414aa54c1f628473aa300d2d8d8accc124ee57774b40c622303a16bf85229dbba65989f909ce9041627e7db315ac8210c18a5ce444d74881d1f485841b7d01d537ef1f503f463ec4d7ed9e2ae50f011e1e07be9cad3240f86155dfef00546762c3ab1805e8a64b644aaaa44b1546012c8d6db892ea6d2cca89253c5f6b12ad04ebc740e9a804976ab2d973b874b5f744754950d5ef7865d478f7ef4b7413361a407b03a3c771221583874e025d769662a5582d67ebf44f5f2c1da0cabff898cecfb4f5fb299d8cf914a7bd27f80a160a862a6cc16267784221e955e263155a1a6ef82180f5e48e7311bf92760c041b1d63de2c0480c5a224676f4c2773623612d4bfb537b0f4678b2ed44322a3d16ae072e0e19a54d6b812ab40682c36350a89e2a7c16f1d946235a176f2cc12cc83cd3c6cef99b327cc2b7bd30ce328dafd154f827f46d438ddfdc0481e507d3c70dd8044d4a7430a0a839660d5268af3870d516fce2a84b233f3b24f84a92bebb104530fb5a1925100231dd12f3a43aa8904c8b4f4e7035642f6f6c70cad9b008159ff759d544a2e188525e5dd98084f41c5bb429adf765f4004ff9a515e5526bd04980cc74b8f8fa39eebcb9bacd7d30c9eb4e6857dbe958b55f4917b7027eae674c65c4ed87261ef370b10bb8b596bdba750b5c4216d0ab0304a5d5bc5de113c5c1d6e6fe2dc01e723bb124458f4e7915442070d0466097694c5dc18008799b104032fb94751bf148d6b1e6a206020dba7e4c91f24c749b8bafc221d974ea4520bfdfa4f536794ffb258d9ffdc8dfcffa01088f514b3b44e89b3a3178120ce49534f1104d7b3c6de28519669e08e3c0a82a8cfd428201b7873948271b77c7e3cab11cb6b2fbf5f49a6aeb31d86384abec3f03bf01552ee133b69cd747f7d3e59e22a3d3f477085bc9f2e72d50351a4830eb1f36f92b300c00dfaea747e0f66324993d5dcab203bdf2bfc320154776843187ff014b8b12e0161de2dd304fda83bfc4e0267a13b1ac87f8cf71c3890a69b7e977ba473531c21f304072f4eab677cd63b7fba72929624cc3144e5b512d9c9aaee3d5b35df80a4d392e252e9e09df7018ac3e5fc7a8fd7b449712e592ce50e922eae90a69019bb3ee2ad85176593ccda502af2e12cf3e34f11dede2484eab4aa29e4c30d38fa3ae90e97247fc25b474d30e81af54d9cd36b4aac7f21cac0bcccba0db256ba7b22aa92f86db6ba0231b244a8677223e89c4659e95fbd8b6018f5fc7f4cf9d7fa5e796e16471e49a47b8683d3b05e49095389520f992da4d77ce3e434734609bf2319c688765f0206d37a25370f72ec15ccec96462d603f5d31424420abe9bacb35bb87acd4137322d53620c3a1758395846c159d2c70c87542c2514c5df33681f219d121e2a30d4505f9aa0c4efc219be4f9494e88286da114ea2264b7a10ddadd12c9b6576506b55f79191557ef6a5658b3aebfa42cd0db1570f0448a65138fd0f1780b30666e402e8b1926137e1d3136815734529457cce4d6e2a3084d2be429c3ad1fa39227a3b03da59d5252b4badd12c9a797958fd5a81efce59f94aafd09a47f27fdb0bebe45b14f19e92359870d4fe80c071bc736a1f7adcbabe2ea112035ce199a25f8191a3b409f9596817eb0f5f5b0ebffb9dd06f9dbe5ce259e3e1cab1474e864bd6739f3f9a8dd65508ec557d3e7446bd3933ec6dbf848de12b21f87a367115f87cde3c17ec6bfef4ea71da299e9a1d2441698485f9c241add886b62648443a592b1f99537873489284b64144ddac2331ace2c2efcf103686e46dab0f23760c6e36073a26aae2f283436c25571f299fa9db7e495d6519dd79688beb01e4362d54fcf4e43e1616ed5d400e63aa0fa84a643d95c977fbe665eebc65ad362434cd3a86b6c8edbcac4e1502fea9184459c6df589173d8903167bfd8dac9734fd331d4b0140519a5b68249d3bcb224e50c0887313286ae804961e411f60aa0a71c4bd7b3b968c14a0e710304697c34d1078c6580b51e3c8aa3f9f94f731b947014360207b8f2f2e086f4a574c8fe5da11505523325b38c292e07ea20c87b4d1c792fa1cbbd14b2829a089f281f514bd1c0c915a1f26451735a6c088158dfd3746ba2cfe172eeae70f721bdd0524a11b8482f9f3160ddeacc65ba51268015e4cb47bd9547fa516585f33172263eb6a76884949e0441087dde1b89a033fe090829d583615bcc9d6532a9ae2d1e50c0bda9a38ac5612b48f59b61d956d3c629ed9eaf2c5eab00dd4a73e2c674af4848ca5d2b8e9ee2c84c7f4b710cb9808fed5389c10347feac332c4bd56f842dc204e25eb548b7983ad1159feb559b5aaae025eda544395c6479dd978a8a7eb72b1b3df7b10a01ed0e2a2bc0665d0472f8d4fea32ba52704eb3f0c167a1ae89b56a3ddcbcf693dd9b19017984943c171402b5b9c31efb1229fba646906d46907108987d4d26947a1a8cb50bb7ae13074c9673a5bf0244a317c612adb85cee81f115e471c508537071aac120524812051f641aa409d9fce3c341dfbd6ddc38dc642ffbe1934ea60d6a8faf1851a6c639371190c2e260235b052dab77f509276c0eeab05afb31181c7279e2498237127dc11860075bd760d1fbc96ec8781247bfc3fa665d580378560f92dd53abbb59843327a8ccd4813212381fa6a93ed55b213308795b76a4c8bf0d857635fd3a946742434c63bec395667805fb3ba6afa94b50e1a5222ac96d4830a059552ec597623da1c120b54e0cc1075ccd44cee46ce59f4d71dae96cd7385aae3ea8973876bbbeb7748942fb6d857b8d0d405f6b90221f8c7c3e2fd214d356946a203a7bfda0c58bb14eca7fbabf59d0ac72d7fd1187d0cef818ab17bc1461762d67ee9d46c15d2f600b62214ba52778ac70329b3de93569f39cda41ef7f110968a70813d8e4f0b6ae71a3c2c06d9c127bf90e13d5259db0ad67c17e3dd16012c00a2f594148e84107935a025b32837a74cb3b7208170f7b585068bb7f638097b57519002e134e2e19fca0e3a02336f2ecab8546152d874d10941acba8a6f3686638f0deeb1ea5411e9e07adabf9ed1daaaae322e99d8d873bef2ae749ffdd99fca290b8c849a2333a9f9ce2f8819bde4674e991412f620d665a962ac121fb55d18b3a45d79205fb5a4144c9cc48769d45cac04bfc5cd916e097d74c5d636fb9074915ae38f3dc97184bea653726910a470ea49ee6fa196aac42c8bd582f3b736c436b271bceca30918ef5fac324985f5f158f54d32da5da70e0c0c89f845a88205b02f5064c9b36103575469bf23782f7adf5f0e97bd258e873b92219a134e299f802e042274b2d1309f11b4c9adcc9ac3c9f8c7385e6fc18546dd6590d8112cbd8d2b3d9cf04ae05b1daefedbea51f5c81c158ab0530bb2def01e53666c0379ec8dd9a670d648dedfcbfdb4ba6b11ba558836d25630c53e2ea0790076b9e9ca8b1ef4311eebb06ec7a15e9a7358b3e9e2a1b2d3d21aed22a4956d2c2bfac2ef7c1083e5b86151ef828b8a69c4bc9d18e005b52bc75308ac7321869f88de5cf3cd6538c6afdb26464ec72510ec35465dc53f08f08cdeb88904085177f8483e923781e583ccba2e964e283f2c9c9a347e661311b55e3ac1f43789125d429e2439660ddf965c278ff0692282272214d4334c51a8b6842ac66e999c41b924aa01de3a52245e6fe2cd08b353ad10ecbae0be62778fd683e72f0a57a0a2c15abf15152af5a4d0f1928a0f19f56d97cb040cd12faecfcef77afb0131f659854d7e1d11d45aec35016cfe63676be1861fdada7b3e06cfc5e445465668db7e6ea04b9f3d416e2b32a67efeef43235c60cef7a1d637e75d69e272941b9e7fa9e8d5cd7913affda7559d730545a3affba12bee1b4fd41a183a9e3a436c7206f09ae054d1fa6fda377436b05a84cef070dbecdcd24ab29ee82839a0f5a6d828023e442c89d9d0f83e5262bc59635cfb1b69a4c5dfef1e4c01704b954059a7bf28f5177e5002adca928c8eb11378f84256f9d2e0c448ff8ef8b620486c519364699a6782854d1fde38601bd8238a7579a4ab48f76e130e21ae116b5b4ebc92a3c1820f7621f77debca28535b8b1ae4859a5e720880da0a5fecbce76c34d1f5c5d162d25c2869e9fdd4c7757fa575df49d094fed2129ed165945e09755707d7cc831c56d2db634c2c217a8372c30f26104a67060ff53dd6a67509b15acf7554f4c78a795ea32106954056be37d8d921d4da01951d1fb83c048f2b23418988f9c340a854b2f8a1a074544e28d3802ba49df810d3bf869c687ac8b2f3acad46ee9218cbacef65b7ef79ddd506ad4c58fd64f80a1ec53dffa2d26859007eb00e2bd97d68451a148211a5e034f0ca0962823540d460ab6d8672d3bd995c0a003b95810cb2969e5fb53cdf442ded68fefedb332c33671f103da0a9e0289513c6b14f23c8347418eb53c924a36e56849e8cca43a4a66b0c3817c770d3998d7f960cc9b7674826d48589b1e24d90b39d6b0411269227b9e260e0576a729bec63106570ee1e8dc091bbd55f4db503cc054b8afdbdeb5f5a67bb9b09cf5abe5a8bd99125280de92eed7c0c158ce5763ef55e91a5298de320cb118858a71f28e3a35fef8ea4a5fe59581fddd2fe8ca7fc9de4da62381b0223328e6312101aa0821a5c2da32c104a22d0e52e5b0d8827489816d11ccd9eeeb71db5feeb2c3efe8ccdae0a39fa714624c48ac81b893444b7890518e2cc6f2ba449000739d0149b1fee33d1ce58847493989e2866d619a408ffe4b6677ae4d5ac392d0a8edc684e49b1ce628f283105208dc0bacc94688238870450a711813ba57f1f75543569b20f7a14dfd22277340c12564e96f095df110ec851a9d3b61f2a03b78e3f7e33143713236569cbfbd992141361dbf2b61566303420667085059356e84430072f450a2005d940c6dd1dd6eb91afba5bd1f866198344f875fc3a5b246b23cac5246cc3f23e9b0aaf016d487d205bb37b39f94b255646df780aa4352b707b00a5b311be48afb19abb028215d01481325a48d8cdc05e5d74bd5f33dad3f2ca7a0292e74dadb2b6567f898da0fa584ccda7a2c376584831e7a86d5a32d4eb9820ae370497edb5ac7727f7d3f4de41abab70ea325b26ed867177d3448fedb5a97e57a7d3fc173f7f28022a4ac54359818c7f5a04243988d39662a8be8cedd8cdad07b1a2066994a6168924b1ba056c32aee82663220e244237f53fa30053693d9dfe83030ebf92a7f8d3fb3a38480ad0868ccced4038ed96e1efa70d466596ba71b0860b6def3b8f57e488cbf4d9ca8d3f63cc7ea6b318b4edcaa6036f0699f7a0fb7826a301c14e7730f4349d7bfb08d119a2c82b4a90c7fdceb97bba0a8fe6365382bf9aa66f8a2bdf28eab7d4035267899934bb0af330ba648a6a4e1aafaca90908f30912d37ad72be17b9f5ea96f9ec318e573268a9d1d7c2574cb7013794792152c979363009ef97e29e394a590d7c726ba6409ba2cb1d995d2537092107412d2784b388ebcbb4b671b6100922e34081740402a48fe9cf555dc3d7ad40fc354312f7c1665bce46e7ede23daba470e250f6a38fd61fdaed41bf18a4bcd0a3449bd9b87a729d5678b3d5aaade4242beb6dd113e801035458ec7b50361d709f3edbe9e9e854bb887eda939cf2d702984d4feabf4e167584eb37e8283b03ee5fa71d704272bc67811c596e6119b554e24b8955190a4f91f475bd8b1e93a6b264ef7a02e0c2ca08ca71b9a5d357acf6df24d56b8ae26b38009ea7def70759ae96bcd59a19abfcda881d4b70ae1e3efdf73f29b483c64c3e4b4685a143245df3687f996ed4fbc63bc83ac9e506f55594e375d5975371286dfa05d0ca0c6ca1c55f02c270f4460c9401c4dff12723d0897f3f7d0cc1d565a0ac3c7a03e29f29162bfb17ea9c99513b02e93cc7a2d440f7c35b8359a95c3cac55eec0b7a4557ffc0f2eff1a66a48ab705b4574fe996cf200dff7b4d19fb95f5596d9e892d3b4eef55b44a8bc2b4ca4a3281c22fa9cf34491938b4ff8887b2227cd8530d59619ac362e78f15b7ff8792eb5b98f1d6e70d4a7d4e44652f1489d5d88a7e39e1558cca6f6948d9fa8332e1c19ecc73c717f81ce417187d5edd09a16a2a94d523d7e0b26ba4650175c9642a70ef1a71c65e6d56ffd40914aaa85cf7b0a92d060ca04b877f60536f5acd6e2f1213cd60b3316f333358030888be6495082d66298ec3833f68c59ba9de182665afa53689988e39d67022f248176494044970a8b86bf1c593be03f9efc577cf138eacb4703087a3d08d7755b3fd830a1a233889ea2fe1c66afee017997a3c2af8827b2a570115e3ff9a82e1aab007010dc482d986efc4e2910c4da7e223539b922f06a06c802bc1b00c91abb2ab70d49f1cb0ec1db739aee3ea35a84d8b601c50319fa3a53c80a7302fe68c71228908b6bf61994c1a73287b725c46e706c99b8f481f85b154785c5818a3199a62fcc0f4397fca0b3ba0b5870d85410e0de1f3956ddf2f5099bae06bbf1b28f2fa0c1ff59ad94b83a653b1fa6e900158155778b14571a0e1d9688e6b1117ede26e93604557bd28c8c007e78176815162edc219878e9477629c1cc062bf0bd0595c3750f38a2f75d1cd101edfd22f78a008c0c2c34861b8547a770d6d3ee7e4fb689e856df9b8741d68892f40bfb4ce458e4dfe091d8c2bf4bf25362451c659e9cadeab1620e96bb733b0043205ae3aa856267d60a9bef2dcb9b575d8792efc1bc05597bdfbcb3fbc915a13a4a591302aa119531bc15b9f9200823b8d225cf34b8c04fd12cbc6589fd0b500fa19f930f5506da87c93c262b8eff2fed015c912bb4990b9f6eb70fdaa09fbf69fc3ddecc99e02c58916383abaa1921b4f61236b47da80547defa07ffbb630c36c7947f5d697d94efa437eebabc21b46b36d8c20254d19be11539935cb024e19af22b7e5a243e163bc22f7f6e6c49cf26938c7f31fe930201bfeb74c8be4b52e713c9d01f5b5d4663c00bb51e097fa89d95567e7657996d580745e70a059bb2356261999e08d499ed7ca54064897bdef2c01bc1c707e8c394f01af617a906adf35cf494fcc930333bbe4ef985d0f6c0b258b4397fca2662620054199e3e81686e7586b82f759e498aa86cea926dc68264df3fbdd424614056f24c9c01be5739ef9d582d6a3dc1b41f20420f4e4c6849291f72c5dbe93fe8e25c9487a6fc8551e450e48f9d631eacff02696075dfb3837bf23837184f76166942dcab9f33e8a4c37b53ced11088c20618746ec2f22015f657489ea2ed12ecd42a312698af850ea2ebf19dbb9e7ec01b2a64a1468e43730abacc2cdb136ac74a72d21f0f10472aaac1e4fc8c273ff9e8aa5f96f36f9e587bd410e3a7e2ac3aa44dda79974813391cd1e2b433485cde9340cbb77c5fa883334d469b89923c80593e7fab86660fbdcfce80cb2de6238e73bb726f91d15a23e34d1b9e9f1daa8064ac5c0391d2da4789dd66b2e50659fe987e7433b8b1321a0e0a5d55542071fe2400b405a06653921f0c32db69c11f501d38faabd738cfedcc35a1ccfd34fd9ee9ff7a22a564979ad784a790bab20788222b56c2f211532fc5341daf36bdd6f7887e1a2922799127d6ba750abafab9772a674bc3867d0b8199e7937803650fe597d6114c37d11be49f2c699c499115467a1b16f0b7ed17a8aa90c31e01381bda803d5ee22f62f9b68fb0af3a7ec5d60c956df5865616a995981e0306278102b4ad1fb047a504c640be40f88facb053f2d543c173c642f8c52474f4ee81e5b7a142567cead6ee306371da72f13af6079c00d18689345e6c1dbc52d765d161eef19f6f1e024c2cfb2fd19a78743b34e9d4135547667bb2fa11a6a31ddb74a7034f6c652bc50516d780372ff25ce601aa04acef46e096998ac3b33ca5a4946638f56d71098a84f5f1e465f9f33e6a6607904ea73e027d2f793c4dc24c767472e94f7f386dcf14074cca1e33708ef539d20e3443a470f5c9539e59dca5ce54fd97aab167a3528fb65d533582bb50af7ec3276e6d77059acab04f2205cf5a91390c9af0a359d804ebc99cf79f9c5db8c16e339841dc157d40021bc8f9e1411e852383c903d5a5841ed1f5a9f53ca38db70fe3ef878e9fd19c5a1eaf9e39ef9eb243681709be69447e8e80b40c82ca8a5c745423725013227d1c82b1791aaa7a1b508b8856cf4b671d0a21de9f2026ad6d0a58c4f382f004ba11e9eb55e4b58611b1bf70e821b0e50401b12a87484c98dfec6c5f2764a14f8b4ec70f8a6e1b8f3690a17b4c201f8653010cbcb0c925e12a1c81c56e56c5214930356a0548b2e56ee9518aa4a3eed11ae6c9fdf6c3c93acfc1a1e1e634151c2e69c72fb5a2fceca25dc1418d850cfcb1d771bd62e01b4390de8ce6416e1601443ecdfb0da9f56a6722448f63e92be39c587256dda6bc1ef20e9b3dd26cfc582c27050fcdad4752842c68fde370701524c242d43a36f51e2ef18e559e35eae3cce5cfd9d035b73a5c4341876f2699027ba2963bfc07ef4e57a0fd99ec4bb05f6a694ce730932397cee5f348a1705a007198fdb7b68d4122d69a795ffdfab08c886ddcf82adae36483af83d58f815643cb465947bc158d309c39fce63e366603cfb614ce7ac23192bdb2253b2c184368c8ca40cfcc2a6daec95d4f8b10e2d59fba2f6cc59ebb5208d7ab9c8dcaa8e830621b43559d6de5066f2648beb38a77ccb00b5b0b0cdd79e69af56441afb51614428075129fc4ffbbd9f7d080b0a26aa90d8524a7e3ff0a201118130fbdfd07d3389aa314c06921c9b920b856740f42a67837928003f7107a658c58ebf9c1825b2d30511e073f8d126b459f249c8643f243858fc422ed79940a96486188cadf73034fc34ed1d8741f59af6acc17b360c941021881077d59a9d5e5ce0c089e14f420c8f3ea6dc0436f4b32c63b128849564d8c91714b1f1bbb175fffacd1205fefd25b133e716fbb023befe75b08111745c2ba229ed252bb71620608e06b91166089e38df053f36f67af78fa812aa8a6848392ad69343085819cf58454623d9c6055a4744f402e916443250b9b61473cd5fc26bd552a3216f76215e864b09a9eef72da2aa7cf546843675f95393815ff8affe6171752a9968c3548280e0cc05fd55d8f47cd08e6e1be86088949f1651c7127e5d7b2c98351b5951fe88f189a24dd868404421e8bfbf93715b34c28a815cab22dbdae7c9ba1cbe58a22fb298ed54b4839a1127832352bd774f11b422ba56edde7d805bc095c01b5ffaeef6f5144b2dd5d59c3f4c8d8859487565f1ecf8b7c86feb135ad5e869a2c6eb42794b065e68760aa1b1aef911c87c09ff41fd43c11ae442dab881dd01b61210fba28cab1506ec23dc5bdeab147e98b90f22435cb4de53e25e6460eadb02afb1c5e7658ce2608092923b8941a2f323e9a951186002d07041a4580c883fced5cf5c269ce8c754fe4de9da54eeaddee0753a816134325423110ae8226502970d4949380ed1c0ff2c2f08902371c3ff5c700288a73fb4a8b18f1480971c202693eac73a09354edc3eef6003304a5c2fe04eef9ff321383219217a71b389847dc60bc07d1f5da9769f2692b86e36c73c5e02a570b48b55a16ba41da8514792c8099eba99b652138dd0ec66ccdacddfd1900cfa8033698e0d74f72577bdba4fdfadd229618193727838e0d305c3d1e46eae29e886908ac709c6814f8297786f24dcf8cb00ff8ed539940d56fc216809044222a4d14ee30e5547a33925aaf15befc680d834318f7074aba5a57d9827f5ab8007108664e02acbfa627e3fb4d606e8b21da6d80ab4abbec3973cae03589fbe88e0f0108065eeace7f18aa748fcd817c6c3ac8483b9c8e1a1dc04af38319f196726842901cf7a0b1bf02d0b229c0effb2a1371729f4495d2058862af597c10c8ccfd8d85d831a1613cd41324f958e7636b3ef0c2b019f396cc82f8b48333c5ca1f576085dad6309e450407c0a43f6ea6a3338611d5136f8e21f2ab4b9b01c642a1d0227400aa2b5ef990e642e0803dce65d8316c97ca82368e254e1706890caabb4b0c7702f26f9123f4987b68a55f46da135ad653cf3848f71a70134ec966d921450e572f2127729f5c9f3dc9536899fba778456c852ee1e483af7d353126dd1eac7d81104123a97b9a9307248fedcaadb78e3be14a092f66ad7abb7ff9ed54be8943f210f95214674f8672466dcb6f0c314c1c31c0b145d45b48e95ec31b7e027948caa10748a76c4eaaf2835ddba9d92793834274e687cc566aea512acc3b2d43fe81439f8ac37f63c97ce089224a4525505825536772b65b29348932fa8c0a408979ad6a4846d70ab90ed10ab335c43a255df562fd619ed6914f0fe39a202c2c65c2a18a80b00ca5d5ec51b66eddf60f0372fa6a3f4f5b67ab20fcc841f65f70455e190c27c53360a8a10beba9670b3bedf28a1002600efb01705ec46da167ff1fcf00a08477414c8a968fc64d1103ce1ff5bc9e63d1114edb1b0b35fa841e106f9c5a8139939b69b994236c4b9566d3f0ca2f2bc5d7ff764afcf29be517e2259d1f4ca22da64beda4edf40505c6c370703f3a18cd8da94b3c420603b0d19f471096e1fb752b7d87b7fd89f07f0172c0f9c222114523eb6ebf753f125a442ddd9e1d544e159d6ce7fa7bffa5b903975c8a288a6da0f3b14970db0d2100e64e57e1f71a9d796449a294eaf685a7a5f1d97ac7925ab167da367ec6f4ac6e2fa9c7c5d964aa6e4600095d607e916e3dba588a6b0f5f638e99114416ad8e31ae1b3ef37244012340527e1a87037c439384679350c56df8c91aa0a2b08d5b2fe482616f92067e122d1eba3ac70a0af65f0e0147af3c948b95b50a56392d439ebad8c27be7dc3b4ca5551ca5d4d06540d8b405cc9bcb167001d06884068692b21ef868418d8353502ad4ae78b4d1ab066c7d40a93cd53035b1943e1edc28aa2c3c6a6486b1a193f5f8c41506426b9667e32a7be16ad58754926ea6c11e87ace7b72713746e38bc8075bcef2a6fe590e0fa146a7de70d36e4e1dca59ae0b64184c753508a5b03d266ee3ad607d67a5e48a238a0f74557ddf9133a7a458669d12a2c9f98dd4304f3a31c26e88d7b75156d810fa9a8d9a03802f5e369939a606253c56d2832ee11e176bd5a452144be2e3bfd19e0022651507e10ccb42a4b3ad4f3cd18e02b384c9c7fdd18d19109c3b3fdeb6b1c7e73100636154b22ff4b1eb5396fc6084c2d1d33ab0993c0aa3a6b4224afd6de9365166afcf36c76483562cbf70a2e912943468ace78b0f3c79b918575f8867d443c1bb4f063dcc88178cdea23f959a755e7bc984426c330fc55674f9720a956fedf154e8f599927b06228bab55d9e5f1e68be5aa917fbc483ec366f912a67d1e0140e8f85439e7871409a4372726d0bf964cc282c0a111c3f801a8fa79b78f75b2ff94571abe7261f29f43d65ccd6d4bde63f61b56995b59cb74be34d0aec815890f2d23db6e022a4527f5e663ff7a4c01f67d4de193078f20fa301400de418ead52b3eab2ceb1f523be00161bba3ff82531cb9c15f36ae8d9aeccda381be6ba6c8b8a3f98fcd3f9cdb1d814ef6d25d480d75a3477451e96f5a2b3804c86db3ac562d4907badb944bc82a98f4ce2bd02d910b05dc762f3f53cfa0303ae7cd56b0dce7285ec9f2b7d3160bd516558b1912d906bee73ad18535b87d892838482a8077bd8a6d690942e364db451567c496bf0d4b0c9216bab94b0776ba6d000e5a11d558488f4b9db407fa4546c996596830ae0869c3de6bf3e915ec9209607666a7efdf154df2d0d49e3fdfc4005225a5f131789b639961b5198a00daca75fd773b778ff82220fd46009b8769b98b2b07cd5901dba19bfb3636d8b8848fc26a26b73a0db9e4a3188c53bddd6045217ac4aaeeb6bddb64740bb38ee3ab7a9ed21ede92375de57aad9cae8b6a5759cef5de91ec5fb2fb2f97af4cd2375dbcdd1b44df0875c51f5211884e904c8e53b6cc1b7c4c3bb84eb666c8cfbba640f92a7ed3def365a535cd69d34b889d4907ef242e58b16726b2a17eb612259041eb08668ac53fde5830711a5ee9b6372aaa436c00f8700256d932d17ab451598b22e662b535111268a9cd46b518a27f6992bc2e1f5510ebf4f14b11232a393866457f56dc959dbe1b2abb2e354d6e89e10c1ceae7956809754ad0ae1b148488e83baf285a18a43036392e43610235101b01a6d5a313e4a754b6e776115a863a75c4e0cde215a3ebd782391c03923934f7747e51765620ca76a683936e2133a60cd0b370dde8ef24f95b73cfdaae5cd50995e94294ccd8577c3698aea97b3b5552418a94ef50204e9850bd65b6fb4359b4596ff41b8702c6764dff66cb68a59e0cff9d245bc243155ef7c173c616b679db270efe26f8899e1282d2c394a231933b41778334a3fa006e376704999ed708e5c7f6428360879b30adb21572463bd6244bc82a2673895a3bd0e6b7c753b36fece55f16601d605da3700c0251076bd1a4e68f78c3f4be24036b9a77fef2315a2abff1651692e49ae1dd9abf6d973b333f752fa82adf3c7ec4e4755e26f1d448b078257679df6ab1df040de253911318cbc115087688fd73776de8b254bf869a881fdfdbad80813e7a83cdeca2d6dc9ec359d54176be5a1d115a4851fb819dc2e238c4dbbe88308f604a1aa8a0d22df93cbae5a5f2090af6964d74b4ed42a940f3208ca045b79b953d9654c5f9d896b9164a16df1d92505bbf27f0a567cf02d5fbc9090bedb3273e0a0eaaa53bda3eeba46e613176d5d8ff22770565d83f3236ea2aebf5039e99baeb49efd2c91c351ff1a890a83ba8c37692d97eb1a938dc5132488e8bb8a169ffb4e83af59c81c05b484c1d26c1e97e667622836691fffbac633cdf63a7a8dae4fd8a530453a463683e2c7567b487c456230494979a0f5f6a151c3a6eb43cf8fced8cce4b720bf753757830e49eb34761b47883856827498858753bab01712bf52c8171df78976a072fd71aea05b0d6bc2aac960d1e471cf15e8b8470cd628ae2e60df9412521d8900198dff6f2b80960fc6fd1979afb7068ba30dc00d7dc06ca88a8e71fb05d69b4b9a8082118d4e5adc14428a7e5b0d06f9dde3c07a10badde7ae630441d9de0ad45c129af6dc6d6b7f2b067be36846ccc6f8207f0ec597fa65913c1637c5952ba6c09934f4be1c50e980d4d5abf9fdf8fec97151554bc3daa4d8b263998ebbfd79b67695161923d20d627e0c7655bf81e6c2888dae75c0f44caf47af5ea38f80c6b9b5f5da0143d8a4d46115a3f40054e3a6621337879c3e008a492d7beab4ebc6aabc2a24661826300d06567de5bb4efc325a536880c6ebec7fcba8225bf78afa2b70a4615ad4aa12261a60e6716af9b3c6ce67fd1b3133ef50447b84a754924621b487f8413840b292bdef5c40c89da7a4242019cf13fbe6e1c4925280ec8db2035102c44016cc42bc12ff7158ba51a19a4331cf81c8d35abe671cd6dc1ed7524a2463f5385a7b8ad911cb1ff32d13d0e7d8205c65d1eba0d512ffa0496ccd236198712a075b9fc4690cff9dd72dd5ef208612fa3f7f7b88d1ed980f6534fb2e849e5fa154467f011e84d86918fe9542d76c3bde34684fda19b7ca9851d3833c0c30a01af7261df7c9ac3605e9cc3a8d22181f003ddf73910a5f69136e360e05cbf8b8994a1e9aefb4f2181f43a8e1bbb2e283737db8b12aa8acd3d2f59d1afad435c001c70cebe8b1209c1675591ad95d694dd27640eb65526a6954eae5a4c7aa382f6d590c0d6d4a87d50fc7b8e9d616741fdd9d53114e467447d18586a9f048028bada56b61569c37332721953fae595a570bae924c2a7965cdd57867b337c6ab03da5f7b4ab7e386a16002a178a080abd65f763b8c7bfa10d9136ccf0484e1f8ce16f2fdc9bba29e7f1c7758714ddb2f46ef95e696f555118bf666b769391e4ff066d4804b4a855c01cabe6c367245b18804aba5d045771fcf1d88d8df19eb7216dcb02244a2eaefde4cac5992fb25cd6923e59636c53f03865dc63d907870432e7ea76a3536724bc90530d74ed7be3e819931a21c51606e9d28cae905f617a83a9ca20b711773f573d00d03283acf264baca200534260cbc7ad0f4b8d211c43b3ab2f0a49dc9b238c10fa5e7631acc3fb3ce6bfc89f40d04eecf60c456469ee96b8cfb763919bea01505a204bfbe5598b1ca54b5952c1f0e11c473408bd6cf13944381732cfd94198669131dc954ee9dc69a3e14b0ef5c743a664dcb5f66c9a418e89f2b9531afa95113ee5f92680783aec0bbe81c826a18a09b610916f85fd7810f0c015920c031d8d8fa7c31b64378d93ae4db0910a1b93d61ce32b6f6245b829f3695d41d72b628e8896cb95ea886be023be35bb7d202b0a90661846ee9de550251ee06aa56bb9a94c29a117ec41ca1d345b1affbf22440d9e1dd0bf5a6e8ee62c72a68b234417e222f6e300125873557b878cee1278f963153123cc87d7d7fb02d6110aeee5060e1048171439e3d0e6905518c480c1b1769a3e94811bd892f528336c08ee368e57eee5ec7b2492a8ef3b384331b905daf60e87d0d3f2eae621fe9c9563ae76025caa82f3a8019dfe7e8f71be9fb2a0ad8968d20d892c9c9facdb140f73d012b0935b5d781f51d370d2c778f7231139e6f08ef85333a39eaacc9164fbeb7e85348440b6ed818e64908928ccea3e62c327b9c2c5bc585c3825c7155771dec4a7ad5d73cddaca2c3ab740a409c8b1f328f3ee5af4de3312340cc8a00b9f0f0dbabe98c3ec3ecdbea63c0327d6eb45b9b031ccb95a9cb2767e8b2f1e51631c9a43bc5748f88bdad63a86b94a14d9d7e1a06de5173de0d56aebf32b6d0f8bd0ce3b26ddec2158a0c7a6faa4808044de9e0d22f04f7f8106c6c6d6406d55c6db03f0620e33a6ab723e23b23e48e1088b7f61b925ccb01aa1e41ada27babfe2fd84edd9a57c5efaea5a3cba191359e0638c5b5f238eaadc6d3e7ba2147ea93b2d97557b0ec89b8b0983eba44a610684531beda3b165cd7c7783467a61095576f1bfb34227e3283ac8de9972fb90679926fa18ab224256c06679f7b8081aa4fee1311a3adb4c3a241f56ee9fad7b28fc5e0754cc6815325f4a34f57ec3fbe04538cdcdc94fad6e814b272d503721889b1858dfbf5dc717c7b02040c24f2679d2bc61dc75ffa92f7bd735eb1fb7cfb38fe5a5a45c2356617959c43145a4329e52f48411367442a9a7e6ae929eb3adc338fa6c3ad6a8fe5a8f039f2a23af7fc33d4f643128ee07b314e8c5c04b08a267cbb5555d71d2964955561f64fa84703d7d04e1006a0a1a8e977134d7e48175cfd4ab41941dcbf9beb3f2539130459b42d36e462753a72e91af4dcd025c6b39e3840b82a897b0d3672383e08f31002fefbf3980a003db96dfb97827dba69bdfe13a63fa39662cd37009c73100801b15a8ce798897eb0853b2ead930bf542ae2bb0ea0777d82208ff44e3126f5df53367bbbaa8a4c3b9f088f6bb219791e7b3ef7f4e20285293d56f26437eb8e1cff8f4798ce693faf907a803042c6244593e0561904d087d097f0c012920413063d87bab79870ee00f2294dba984858756635f435301c171095b15cdc8d27926d10e99fecd28316e2a4a55ad136a65019812bc96efd0cc741e7fd7053761c2c2d1439a0fb43305e76775a7cedab8b5c64d8c4610da0e7984dd5cd33943f8d28c51dd495e26e403083e83172650d664645c1436053c81260de47ec4ad6d28cc5e232f2bfb495060e0d3cefe997e3b2c2dde7f26b50ce22f94ecf0b96004976941ecc25396461c96601bfeb72a33366ca6cf65e9fbe69d97d7050dfd64623590ad2ca479d420cd5c483f600400bd81ccf51c6ece03bdefdff4e78a81c818a35b097327e44e840b57770f6d1794b2dc2214bc73b406f34715afac4047ee11dc5c0ece5c5c76d7cc9a9904de3fd0d6ee4371a56b141389a822c66e5747d9f2f5fe7c5224a0bff2ad808b214ab167b9c5f31f75ac60a78fe0acc33f12ee1b7d2ba7ea598cc7b6f12279627d3df053aa4259db989969190cacd1cf00eb7d252117582bc781bd9cfbe327817cbd093d6c753d2c123f38eb51d7a26c6d05fc03aca6dffbaf250cf670dbcbf956c44eaa01758120f9ddc9a50b765e683565735321e5a9ef4a45899e9457863d12b3ab5546c7cf346db92615728fdd08d17617e7dc3951d92d3f7ebc19fefc327b81a0137c5ca13375789fdd8eda03bc016595c7bf67708610ae78b939b8ed4314657630aaefa562601184ab1d50befddfbe3b5b9c83e3320b714d20800e88ff46204c87de887fd7ad12bf8b8e37cfeae91d73b6de6e766d7bbfd8b4e3866b61b9b00d3474572d9be074c7115d530824cb387073756500d03e666f796d2fcc8ea8d24bb3670162168320ce50e3ae5c76a346a7109afce5da1305d7757edacb0a5779f54c7720004bbe82a893018c1ce48cd1a2904361b6e62065a5beb8983f1a97b782478e644767a1f611b0ee2cb4199716ed04ec16e80b6bed883fbd0913228ce44c2faaca78451e723c69f1fc5c220dccf1db032c327ea06de00dd2740dcd5d6e55dfc1194ea6d4085aa00c115817e72edef85f0af9e320e107af4fdf671e1308c2ff71bd2cf616698de9e9501b9356baf5c443547ee19c13cc7cfdcbedb5bff1c950a5f554091a85af2a89bb59b1afe142f956403057ad18e59a86d65bb5516a5d0d33551af94826f6c9e0c4b159ac6154d9243ea01da91fb9540f19e42219e1acee909c64882f6c108c6d380673743b891f053ba14cf20757eeefd8713b1a139a512dd8d03a0cc033ea516bab3a109fd3e10ec9e68318a1d0e09ece3d8f4988aad4887e7d11e709ce7e82101f17d8d5caef497942b3c08122dc9450ac7f3260f25f0c2abc00a58b86908de57378474cf5796ca023ab3449914e2ace904b916d03de348b82a838a743c3104872e8dddaf7da944e205ecdf987d266a0f20af547910db7f38a35e015eb6bda71d9b4cc5f8ccbd1af6c27d6a151291afc0d872c7568aeb7d8b4082e67208d04ef2b53049d8b942d7890fd57ed5d97ee8cef63a27a47119da186d608e733723029473392c2c8b0820de2cbc14f46b8a6a7493c6e553553cf3371b62d75ba481f742fbde81e911efb7b96e0c445183d1f122059b902d135274c1a12848f90dff21318aaab97a2f1a9188af4d220540f49838f5211041f1dba8a548cb7f6979b38d54650ce92ed4dff9b3ad3fe01334b2f1074c5dac6f464b903ac5fbc42c296bb85b7a3215bbb50c773f997ebcfa1f284e6712f83fe68f40d29882a42eaf700b8283faf49e1be99fe216c4e047a13bde18dd8c5731cc6d9d982900b8bfead7115e2064c9ebbf86183c942c79c7e28bf434f2b46263c9a1a77833756e1465de1200a2b41f05289451bdebb46ff93a42a7387f08ddade52d30ba937fbba67b87e0ea4c61cf7b8ad54a6279265f53b18708275be704983a35e08510a32c79cd89ada77958ccdb56ccac70dad38fdb0c0d42e5b844eda92dd94f6af6ebaa6899a3cc6a01dcf3eaa0be482f140acf209bd5b91f6d61f4622a7fe68e243cdbf9f0e7b8b83858109fc1de75c8b2cf1372cf1763d73bb8e071e8fbb599398ac02e65a1f0c790390435e480bc4f8d12799a13e7b46cbb0cc49c092ade5e0d8ddbdc7f184e164255aeebc724b38d49dcdc3d452a8a05b1ecd5fe647863272167904a376adf5c1f0525fa26cf1808ce18b25a2f4fe26b52a7ac5cb45a4f4f626b62af2cf5e21b1ceb398a882733217aaec01ba0d5da27518800f15381334726afa0e186a660a58094f351ac98dc1b0fd2d91425e2c808a57d9901498154f7299309c0e6cd71c6683de28836b2c45103277d0b4b48b9a82fa8769284ad490f589f5e1dac007ffb1f8205db389f0041b1b4e27fb434f325da3e00befa06bd733a5d3636ce1c73986ba22ae310c70f7d90dd8bb908f8637be764f458c1f6764c2642b9ae9833ee29773fe82307c2e81c65b274ad8f8e5214accd0e2aafc45530771efed5ef8e3a360570b0bf257d3580019cec03e14b28e196733895ce214095de1eec0da0b62ab99e2bb6ce408b3650cfbb4be5dd9eb17e60211bdcfcda3d7679ca5e7250806b7d8fc34ce909c0773896d2d7e413100b3c51620c00abd44f7aafb13c03217452894f46758557a3af8c0ca14e7352025d7b88fedd88fad7c581113137ce935906c04d37e790f58bb1628d77200c258cd47b4543b8344765a6f6a97b9942dc34066bc3f6a97b9146dcb44eb47101c33d88634eb13db3d70b812603824d6d352aaf03d664695dc6c7b3f626e255e90f00657acc05c518275630e801cb80aad12c92ff965ecdba8019f0f3df4beacaa423c7759055398408a494843b586d4c475a02b31295bb957ffa020c988b529afad8a037571cfea3523a8ea05c331246a53302191c15bf037497d2dbbf94bbb2ea48021908ebfb95a0b9c0c5d782e20b4b908a98a26b73a548d0e88ad33a44c0f00ac8ea791699a8188d620984ca04ad411294780d4f528f47fa68a7f84692ed16ce3328422f388243d6907b94d076cb402347373f6e849a2f5ff6fc12a992c755d3067f8ae4c08e43b1366f93235266779d54d063c6c24517bf008a1f657343aa1552d3dc5ac0f22c3559824b4043ad09281e8543d90bbd88d8b7e05201940a0ca9f1e72e8916616035abc7333a5273e9618b41b0d81cef8e9e50c81f776fd8249f00646ab6598892296a395a51ba7dd843b8907bb34c3a2e25876482fe1f8b60198859db033d91fa583e418d8253655b9609eece4a933ac3214ee340700824e09f4c8aadcde30c3db88274a29a63f43271c30522809b73726ff45a1d45011868e0daca6b36bc982e1fa9e8687c71c7f2d22e9ff919c28d38234b44bc0d07e74a1da6d9a380e019504c53f1012a6059701d8c0f1fe2ed664346a92d39e9e2b3697ddb590ac7eb149c8d0b7c15ec6596d913b89ef0ccadc8b30d1e00a3ef7c2f2860f1a05bdb19a0e14d60d1fe1ee5af9e1082a557bf29f20b2a37ae0b274971e3279b8d3d611f3acd8b9fc7420d0a7197864c47e409c379be03c97aedc94cea9a0c2bafb9e4d0296a2cf12a3a295fd6547cd819c637f693aaf41d768cdf33f950490dbbb0c9bf8e6ad8d76397de47094c4b952a86b72f7dc034314ebebf9e639ef498a13b7dadc79ee00dc28568948daa0d8e1dfd7942897f74bc9bbd8ced31cea28438403ec4d6fec3a79c13e2ae17e7dfc308b26f8daee31524efda5f7dfeaacf462f2a90fb3ec43a64289129c1664f5c11c9db90eb419d93d11e23837297c1b547b1a29f4f6f5f189245ee4884e61849ea8996f08c8e0bd109aed93c95706b9c0542bb95cfec0ec143a202e57d517982a3d9357fd04d1aa5f2818fd14699202030c8ae72facf156213928c13d241fa762a5ec4f2c796739542f67777751201c1cb3099f93e5077d5f9df31d6615ce98d79537761585fbbe25bc65ed716fd0af00d0622cce848a2a64b2cb833afce97e5a259c469e689048782e65109907518936c173ec22ab4de23dc7165fb676ac27d6f4778ec17387c812bd73f8609cecf48e6eb831923fde8c9f6be1994ab7ec53c1764cf0f394597aeaefb1bd2b4f0cc67ae05ea8772137866c4a1ae397daf82e849ab76af00f5bff937902f37f8bac95d82367565d9f085b8149092192d34ac1fe197a9f4b99e1886c03195ae2e39ad3b3fd7fb3e3518eb1e8140b2e6bc4c239067b539fab50adcabf26cffa9452a9d0a47c63f8d94d377d8a4458e4d0d0f5cd366c7df1c3e9b89fe57525fae571b59add570733957a9da8c6d57c187ce5bada9f3efcc3c4e9b887b55dfd3a06b3920f3332748039a13efa3c8c25a613b5f7dc731575a4d0f040a41bca92dac218014222aab3af10cc078c83ac5f4a7e4c9e0d396d96b9ff22d68228a3885b92282069ba074e63ff21455a2725b7e78fb8b542ae865f31bb46e54785010b3d87db2cb0c44e2313af4ff780055b554ab438673b59d20e5ca835960231d0781029616991f811c0539530edca704787a710d8835502568562c95f86f47c9eb95776e2fb5a301067a4d70667134b448a8cc330f7df046e279779a7143ff010f5e61f07e5c579a23659dfc45bf3e96111708b8c1262966385b7ede95a15d5132af34a3a7178047eefd14feebe7a0311201c3e9271a1e5c00eb3ac7345dc8e0245a4360bdf1098916908114333336a7d396249992eff8ae96db9e56637190c0f9446e5a702f4034ddb9e54e9c50baaad08de0ca1648e45a773a41c954d8843416beaac5f1305ba6f377514b4d2617c925ddbb4353b65822ca124b7b4bd36ad7e2f239a9770d5d5d0a6c7708246c02f1f7b72e3b98d250cd22dc411072d1b527e2a1c7b4d7968e4b43292b688eb0a1d6a85af93caaa8b7ea23838e1774afff1e4ffb8af322d0ab827200e717eb7f23e3143102d1fd097368a918cd1db71b7a235c3186ef158740130da72c4a06bee3a2d7c059a9ea503a3c4d34750c516e35256bd3b0fa4de393c1a1302f2c3def297f9b8391873337b9d14f3f8d7338775d0da6586df917a284583567f1333a40d959d269e824c8b71a8227670c7758146fdc822819082f823e57384be7832b59565e34aab9955ae67af0b63cbae5984063fac305701e7734d079063440ac8c1f14522a37e2b48cca49d140b93c9779d3263de579b1e6dd70890fd402ebb091ad7dad99bf2b521170d8fa7650e58f631c1343adc2e50c5452ddbd7902247daab2fa1ae7d5f719cf05786c1a5c28935a0304df069dc0bdfee92d17604bce6204b089f6105c068928d97cdd136b47af87aa6276a5645dd29562d38c418365a58d39522e40952a580bc56af6a728ce0faeb557b36e2227f881466c121f3d387b381b73803e44b46c58ea67dfe32c381b12a320c0394e4b975d7d7fc6584ccfb72c1c52cae146b1206ada0a8d9ddb8645a869a2d9a7bb21f36ee1e394c7284b2514ae77c4782fd69da9ae3db747f52bb8a1459581beb786d6a3f5cf50bd01a20948e74ff42f7dd90d6184237d7ef8b8d9f5fdc2092160fea89eea42dc20efba09ce641ac815931075f161df1dc2da89dc578b6e06bf4b47f557f6e67dbd0f47b6b6018b8dcad4efa0cdd41477b0bbdc42be30d54374ef9c51f65c23d1105a8a7e158e7ab91f41ac632d2683976143aa1dae47edf8e87d48a2ae3a2dad9a93d4ac0dbf1146540c5f2a5e860ced1bcf62dd44f843da8ca5003a6649514a53cbb001d827d912921eb38dcb3080d9931ccfff847bc88d22a3f0d0301bf42a0f48718469a5eab4fd61e2406a47b10c991c5d3f3e901c05d422b1ff38fd677aaacc7d6275a76dd48d8c5f7e9da66147a6061eda109e87c6b054be36f2dd3b6bd89699adc29473271ac801bc4b4e562967c054e2be8d6f8b12108506a8cc5b50cee4025c4a60ad8195e78575a77320415c0561050792609b07b5b0456ef2e129d4ece235e131bb4da498a2de1a6ad05478f899e1cc60360cafef239648cd8b9d6c13efab21d4490df90e19a0c9c66e076d69d06fb2ac7c4a60135300fde6eb91cdc7162451a99a25eb9145497f4a4f7e98413b67cb1057dd7c239539a7e836ada95f9bb9194145c821124f5d68914a056b1d0527ef577dc4d2552852a09b4f76612b1e71f51806874564b9366f476e4baf9020799717b798af14ca3fab8fba9f9188b630805fe601d027c3a471ce6e454e36169f591145ea32d97d9b18e72607907d83291c995cafa238be2a8738f3969501d90cef7147d3a564916f0121b6e99aa5f948318535ecdfe4e9a834dfea29ea39eeccc9e9da1dd61534453b0eb12e0e4c5c853089afcb35ef710bb0215294a8531e909343e96c66f0b76ae8ae7146458245989d9a118a35d1257308f5fbc658a047f4224b0d5f1ecbfb8fad5c76d6d91edb39abe10d057af9d89d0af2c359ae8c574ad4053ad08fe7723d4ee6db2c2f5f2e986c2208abd909fd2cc8e4702cc5ec111d0f9c2067ef214ca2b6c7b66cb1591169f82982ae24f933eaafc08168a02a31933aa42f74112c47ca75811a2574a272c56a6d30e5ea1e1325cc01973d188931a830ebe86c374e90b7c1051f4de931c3c414e8e2375e5d737b2041242e043c0cfdafb4245f5d74e19049a47cb24748b8db88e9836242050a753ed5de29e64b8660dd0cd0192293c11e230c1960fd1544c1ed670a6cb8389dcd71a7b4accd9a3ffc01a47f51cd2534a1a0bf9936682164aa2dbf87543c6e25d176179cff4450b6c828ab5ec605017260b1dfebceeeb15c886fea4eb89ea057cc7bc6bac8ce2d82a44a2136338ffea019f5f1d118fe419bf19c62f376a6a399c16d1f1629808ebcbcc1969069d1da347b739bab76e17eb442d51d17f82cfd1947445b1808f8e50ab05863b39da71b2a24b50a45ed5b70b024b256d51790cf93e75d8faf112910e5d25f55994b13122cb298a0f851245aecd3e6ed384391c9c750b44bc9c3aa23c3047c042f9b30367a528ba71e12cee3f22befd69b2a723c94fd304c08c046019ca250073957c603f384c28d45e5ec6f71539248f4f37ba5f57f10e1b84abf5721ba186e4e673db5b909121e507f0e45f7ddc5476d046087628249d1266ef83553fa4ce4c679cbbd4fd387a96ef1629666b5bd13b0f18ae4fc5ad187078a4f6cd0a230062d3fb3c35ce6200e9129b8c5504f0ea779d8f1e157d248c27b22041c4d5e4a4ef92398af429a45d916b27d9a59e2a7573f97e1735d71495c589e476ac4aad31a6175746940af39c5efe23f094a640aa65b61698e4a99447e945491d8242559c312e727786f519abc49c64413fca51be6f13e10b683b81602acb41f174df8d47cb89cdf18e49a8c01ed2cd66b4be994788a97346c942b490cf1f2948f7a71f41474364f1e0696463ce1f99d2809dd696df0093b891ec753399d98213a2db59dd3391bb22e2987414e9e304e4fb4101d06a70bfc26db356f9ab99548dc64469093f5d9f4a0d8e4b06b1aa2910e0dc285d3507070697ad59fec43686ac66472a69698e5cb24ff318ad564fa7b60bbca64e3d3c9e216a19f98d674981e2e61721c04d390b549c67c89d9e8a555dea54fd52513a27402309347b825bf5c4b1391965261b30423a7586aa7928e5772297556f2285795623a15a25223909729a520a59092dc0713bb7d285d913f6933b52cec241f71d268b049d99d49ec149336da25bd812cc9f0a4d9119414a0e2b87524c95e48ca473e123bab30d4483760a48dac489f98489893ef4b2017bd67798926526402e30d94f37021f2a9c5f653633313ded671085cb68d79529ad525917c4cbd1a51808fce2e9dab3fd82166c537f5cad5ecd725354933f8256da3e9fd49dfa3f309f43859f0a108987b2106774b54b3831c2453846c4d739d595c97003ef03a3cf0d56d383e707581c26de03399c5706af057044b33230adf6e98387ca40ba9288e1705b1b94d387ca22ed4908937037a3d2501fc15038a35d6725a3090ba4a07b608a411862faaf59194cff3b18a9537d24ea9de745fc59116240fe5681dbd7ada68f40b95a97369ea6d44588e6c9d5528c0ad2ec227f01cc4b621b08fa8c5e3a0266b2ff4a10a6a5abf88dd7b932de596292529030407f4064307d24bd5d7f48c6bacbc5ff152e393910f35116a69ced695285c64dcf92c2c5fee7cef844c9d2c82bae56345892b39345969f21e34a53bb1c5eec00ab95511135708314588332eab6585c5e3865c1525b02822c1ad96882b6ac0b8c15eb844394137171ea0d84b94256c700b5cecc5dea620b03405212508262ca62bbc6a4f35efb5cfb5a9659a46b3e9cdcd5a78fcfe65bfdbf2ab27bb74ee73d862ec6129644ab90a9d8ceb36f739f8c5fd64617ede0ac6c5867e397642daade538b461211bfe21894bb7ab142e57df0a97ae7c661fdd6d4a6ab24a49bd24f34ad972f76c4eef2ceda9542af5a1a73ef575aabba3478fdede6c8332aebc93d22ff48f1f673f8e8bfa261eddf8b63fcbaf8ee257cdec0ca5d28dbf55fab0252efd5afcea55131bdff20eecc6f81f7998a86fe2bb997813dfcbb8ed65dc327ef6b7fcb8e77afbe637e75fee7ec2628f5256675dd9b55a1bbff0ef066cb19b77e8edd5e5573ff7cfdddd6f83a93fbb9b7da73fae3fabcb9a5d2e3667cf97ffb3a15f0b43b888dff9651ecfc065afb89e3293547ef6ec711fdb1517b9461ce99f67d28f66749f73ae7c224e7c9b24eccf67b13349c68a730037491619e95ff6f7976d73720d95a6346e8baf8e405cf65bd63014acc6ca56f0ac3533b9810041872c20e800820e6258114a33ad0f655428a1747c289d84628f8d9d96524a29a594524a29e54ba4d873e3e5cb24dec9f1f2e516deb17919255912876421d9817c761279a49393744a9254249408443635e170e577404a0b4823b2888cf11c9100884092c81c7e066244e6f0cbe6277cc35f757c61b51e7ca16d7dfcf19337c618a36ba9acd24d65399aae8683558d1c36379e7643b26b938389584802611a7044b1be0e3e16ba01631a7a70b211c28a83a4a6a2294d35380abf8688901ea9c6aa3a40f399e1380a0f311157ea54c6168587988869288a4d611bf8c9f4aaecf8def13021ec10dff09311cee027f1c37ae4015ba72dbef4e28d328abecca4f6526eb9a14b257ec5d78c296f6631a16128689ead2cea655e9c1950badc35b0f1c30e6a1cbabf90bbeb4be72fd6fad52f9bdddd5e13b3babb735679ba7b65cd49c20fbf5ca9099bddd804441af4091051549a80801a03082cae6468d8796313104ed40ca734aac7c9a4db41ca9017988470209a010e4e30181a020316424398103d71430c4549d090842403111036043595200a94214d9e9c0c8921a8088d864c4b1049644b4f2c8d7a411028c01204161c374e21840b34d866075593ef00c0d1f1cfa552a94208a1c795ab95cb153d9b9487c9ca5183c58a59d7382d9bdaa77de19c4fe767d369d024bb7adc4d7573b7e9cd736e60f39d55cbc565d333a7ee349bd3e59a9e3975a7d9f4d66a7048222430f788917b6efc8fc5aa9525f30ebfc7c8eddedd3acc3f6877333333a5b981c5165d94524a5fb058e479cfe8a4b1478b3511c7c5b951a5c313635575d55aa329a65b4f083d52353ef67edae57d7ed5e2629cde59fc79aed21a4eb09492a5ec2dc6f84d9f9ec5166d98e565adbe60b1a79b862356666e66e64a9d6ff34bda1591b5a613d2cfccdd199759b594466bd63d6975af547677b7cff62c7377ef9e5e7777773b875c08636477777348442dc57534aa8eb3a2e3b82a5d2ca6e2a2560315e5bec2921faf392704bc1a5c8bc562526b58675263a5cdba69b43da35b9df3bd5b6705bc85b06245bb3047bc23ebaa5bfc626de3624703f59471db0a3a30d8e6fdf8c462345365a17c851faf17ed3a212cd6fc7e9aa9af517542ec538db882c681ab33ff99545ba159ac9a7d67b552af02fc6209f08b57e0324a8f54434d407889c506c2881a2a6134018695312c53d023615e90420467aa6879810a6230b941162a3670c2073080a089514d805105132d351c25b144071bc218410c2b30a28ad309b5c2587063e45c0a2a9e60c2a5154d54a25c7eda850bf510c6fce01de94ccceae54ce71f7f40baccf549ff10c3ed5ac3375d11382e053158e2053d08f1c30e5a4425b898a245072f94ca6001b6ad5578a14273ce2bd77a32366c591e093699e0c8b954185f6e4871e5cb0d2976b801831b47493b6c1121eac68d2b57b6044161038c15286c8099a1e36c1c25cdf082131b4c36acb49395179a6c096fdc1076e3ca952d675eb061c5ca0b3eb67ef6edc3afa98345c2908abc3ee257d19d3fbf566b670a7247c27406107bbc59656c17776631c2fc285bc09af6b1d89a6519fd1acfaae8c73aa113d27df57ec53bbd5a518fd33ee48658eeab8fedaf2bdee99f95f585f56bbcec8414f7b55a9b643ebfe6771e6bdb366fdecd37202ff7b21342f3b2a3d9382fde154299f22afdaa7d5c6543fa5d7e391b7b74224ee41940bc99df6a759d8d1bda80cd2dd9d748b0cb1f3692d26606162c58b0e8b0e0ca952b5744888a93fee49aeb29a3ddd0bb23fed24c9742bf8c7af2f3bdd8c33fe76b806ff8578c8823a322cefc2510d0b0fda5bbf0abbbbc159ff1b6f835a558b90136b0076a6d017d3e823d1f3b23b10ff201d98490f3a91071fc833c104c892686c0201ffb1f963788c75254b104fa784602c87998176f100f4806d120490954a2dd00fa7c4639bfe5783d6e3ec70bc244e9c69ae701f1c63fc70cae3f085fc80ae3fae37cfe3fbeb086aceb3ebc1ede089ef38dff8dc7451c7f494502e9628e3fabaeffeb0b595e0fbe505e0fbe5dffc3feae2f4c422f8fdff1b253808ee7f1c5ae840fbeffa73d165c2fef4f07e07b00b8bc25f7032f4cd2b7fffb9867e3eff3b1eff16cfcd34001a08441031028f64a6c90c00834ea0ff23ddfa2c286f4bfa741bc136a673eef5f54d8f00727a157c7ef78fe1fbcb3e3f9753c2fdef76cfae3750f98ec70af757836fdf5d36d287ef1832086a5421f0de217bfce92cd3ea4412900f9202fbb1408f03e2f3b233d1fe403cab4c801ec79d91989bdcf0714bd24d1a004c6fea75b5ebc36de929bc30b77e0f0c22886e5850c832c2aa241fd144e3045e1ea86f3285cd17861d779e1d3e52c1a1873f9b550164d4a83625e8fb78101637782ffe468101d6a9e0928b1431a4362cadca006203f256a9e0fbee0e288a0274d9cb002e4a741fc5468030302f9587dc3dfd3e380205f70880209f0c5bc0876191bda54d00efbe0613bbaf1bf6c6040a52730108136fe95c0d7c53b3ebc13a3086aa2907b5dd6892979cbb073b8fc613f6922de8951b880c6e56f1e78c7add86668a2c6d239c49e27bc139bb220f14ecc822fcb21dc45d161088cd2ddfd3b50b04557363d46cbd280bf3c0191961b3eb8710a2c48b878c52fb731c2401d111851207f11887301d85fede089ed2d6e2ea374a7995f0accea1bb03d9b14fafb06fc69810d63d3f5232a380fd0921070698209e4f7088001fb48bcc116238630d21a02ec8f79bfbfff4f3b331b19200a2bdf005facfce8deb59ba3ab5616abe5337f5ffe4225971621b927f7b296e5a3a3638027acf38e9c99cf963146692d0cc6c576262ce2f0c3982a957a6de5d9ce1fc618b999999967185fa831738cb1ce99d1d4cc68addb0d2ffcacf65cb76619b59abda05d7aad53a49c22e51429a59453b6246ae6b365bb7bff64ed48751d6d7524427d7c523537b3a6cfc251c345d5911c1e7747079c8ed3a6e394d2894e3a3a3a1ec4094103668c2c55ccf0004516284a4ddb132254888ccad4c0c4851958bd4286098bc174624b7d138da0a0818809a6a46125861fa6187191814809a09cb8f04483926d628a2b3e541858afc11250c6d8eec629ae30e1bcb03434c8c49051d279f1bb4b0271c91cf91cb75ab94ddffe422565748b5e9f3e373abb7dab3ea7eb70f64df339dda54f9fd37d4bf99ccec1176bc9b031245a2d2498df2b9668c51063aa38b2ad238670c2459e600b1e35f6026784c609c25c6647c1d075f75a27bbb73bd484f20cca33280722c5c2aebbbb4f6f67a876777766efcc8b0c2a870a6c987511664abc13724cbc13665d7459f22f5917128827c91c7ff7292377fd61c9000ad66fba2be9546139f5f58f6847b437425fb399f4cb3e23dcfc50e89e4bfd0f779e2bf58d3fe7f966a9e78f8364e7c745fc72f7df5e7dd39ffa8052f49780b57eea8dd44ffdfc54eae907a47dea81e8d75f02b646393ad4ac9d1163b71bb7d850f515c8de3d9e2273b297dd0218b47d938596524a3f2eea9bec79895f59f69c65af534597aa8a3df39d87f8327db978fc604963973a40f6489e189340805c1ac7b8347e71e9474925b59445dfbd578e226c8cbe8af321426f9c6f24fbf9d9b891f936ce0f64e3cfbd3fcd47903f23aaefbefb806cfcbb8fa0eab3f10f05bb04fce18daa3a1c24fbc345ffc558ee46df9c535b11ed533f440b93788aebd56efcc84920fcf455b67966763439ab61abd50be58c31562963cbb031ff0b16e3d16c0d0bc7cdb3b78760a32b6e5e7a37eee6a45cd918630d5b9062dcb0e62671e946eedd8d5382d93186e084f5eeeeee7ee194e0c36e698023bf319eb16d31bbf1adb8af4a19da5499135f5e56bb7c66aeda35b7592e3bfbfad04dc2dd5e734fefc832a3219b95e38b520f64b35639b3997d4c458e39f31dc8252b993d67e633f3309ed129b341d0b787b022db8ec8b2b89485f3fc4c1572e8e7f49dce09844a9a65dffeed37e36eac3c9b8b7df9caec5371a31f9965337055a82dc4a8b0f34705253125ccdb5f55c21beb5fb0980194acccb82711786194e4c46a3736190da1c5aa6ae581853e7752b9dd5a39bb42426823c2035437c40c29256e8a0d1a17a68d48a876894a55998106aa94a4b560094aa6045185d5346898b0184c27e625c98b12dfc41b561b069415106561830f4f96600a228c10911ecc10f1816875835416b6e6c629acb8200c2b4ca92dac38b1155951828195241efec6299e98d2d667b79cb32b96d6da36f7e92bce39e7ec8aa5bdec365babcab9acadaa43d656ad3ab4a6dd33cb66d756d5b1b5d45ef35edcaa9e758b7a7bd6b555ab777bbb675d5bb4275b908886a2ca4012719837e6a0eeee6e668f13a2754364a4617aca48d1532666d9c7fd5996655936339ecd5f8db2a3d3844bae7c9692f906ef597b08005c58f931c6e8dcaae5edeecdc4265fba609fc53be18b2ff33cc84f0401af2aa63cb97cb71ba494f24a17632b9d894273a3d2192635d88aec50444a104ab8421a75fbb7286d1776b67ab0f2b72049369c474912acd6b258ff9a4f50b73f9c646e73ec6cb6d8b8d4afd73f8b556bd3d7a50fd3a19452fa9a54b289f3682acda5793493a2c2905f0384ad93ca0dec0e141b32d42cf249c34e2cfc3a616cfc1c508c747390b9611246c249377e138b06fc860c35a9f0eb0636e449e572e4b8bacc9fe557fc6edb62a713c64e2a04c862e5a472e5a4c23ba1bdd10659a5a72e4b5fa4138be11deef89795e4b364179b2de45bf92cf9711e51223a191464c3c8f4d328f08ee4970a488e48a002dd33721c287aa2d4451630788812b7988284123628ea12c507a6255888a6c8524498166c310348420e4ba4314317475a9001f95168fe23cddfaa4228c80536ac95f562d6894a506e1897b4d75af64af7314411444c7cd8e10722c07e56e45932a50b2f465fba404171447f8d9d7931a2e9c6a6229a746e6c2a62caadedc33bf46bb596c5fa072106cb5fbab04e184b73d48c0993b0e6b1dc3e1b13e8cf1f42812ecfd492cb5e12bea92f049953bf55036543bfb59b1f162b7726a4eea4998702e51c0d40b2486237dcc092cb9f7d96f11695932ed1f67c74e5d7802d569a611d9fdb4cc442bce5ceccdb8c0b354ff7fc4ed43caa67f6a1cb3ea3906614bf10a0eaa7e119c5725a8e956a6f9f931e45d1a31a58f9213dbafc5a6d7f2226aa511994a7d6bb7e8890f0c40395413123ba69092b4660061a4d8c3873801b4e20040dc698e11466490a2adcd213151bdbd05116da08788a4e4d45105d7efa71631312996bc5a44410638c71c5b93f1131963e896c3daedf5cff81735db217c290c4bc90b913d2efe1bcee92c5c0e2eb0792181104cca7dbb305192373dcd7affee057915d590b6b1d3629e3bb94524a195b5012c6a8ebed5337d8370fcd47f9c1224e1540a8809b7d44e1662f9fdb6c4ad3b48fc537231461fba12a654f41971548a15d92f882a64990a3294b910e63801183267cc874012385135cc684e1050718b211d46c36b856968b1cb7d520a58c143001834b0e59cce0a9e0288b2845445001c3c4458c2d39dcc064031644f12207141a64ae9811262a4b0d4de812930caa168301285cc0524314146954e1812f98a85c01c39723b688a95c0460a3e1870422084869484774585cfe9c3edfa7773791516c5b8c3d1d63cf39dfc3fe6c6e1d638ceecf5d658bb9c40cce984c74ad34455d8ac205f2c9f6e4b2d118274da6b022240618da26a42b4688e102991f7238434888edc626a4292ed8e44b767257ad1b9b909848296756460762babb334ac4179b1b9b88389a734e5a8998d244c41321372a3109dd15bf687cda55ad490b1a396e6cd232a60579a6057926a4009581d4428b9313ee1f224348204243460bd36d9e1f279ab0bcbce02ac39bb42c71f99df52cd78d4d5a4a70e78d4d5a78b8218b291574bfe7e36ffdfd6d6fe3854baecdcbae085f9bcf6c0290fd1317eefdf475efd8f9e76f28ded1b1e36527e4757ce192abe3bbbb7bc7c74e888effe1ee04c8eb7dec020080ffe16d939d0734c8df5d1e0b1e7c741e1edf9617cadbfa4d729ec7a4e751097d79d43c0f6fe2c0810387cbe5d9f8d8b5caf09bee73baefd1bd8fcda5fa2d935b864817902896070faf03d72791220e0fcfc66f2c9b9b86c9441cdb85089b223284bdfc25b708e6492cfc6279043b415ed8278ff8c5f1966183628febf25326b48862e11d1ecf4f8f628feb19c7fbf8707c8f2f64dd0dc7e77ca1bd61bd5bbddccd87aacbe1f88debd1c3c7e77b7a7c011efc9ef7f9d8fbf8203e3e0da400e47b3e05027c90ef8937c8c76c7a7c557e7e84f7792ecaf9c27af3852afe0df4eebbbcc91471f869508de71a1faa6e48836a7c587dbcfb3f9ecf83de7479343fdf3cf2f1e6f5a6920d3664266f62431a74a9107d4283628f8fe7a72ec41e119e9f864002e1797eca44290261313287bf02f91f02fc7c4005f8a850dfb09120eff33e1fd0085f90cfc665538214e1e5900b9240698397207009188b77f3e1f575ce470f4fe67812ea8663d7f1cd8db7f33dbc017c8ea7f32e4f5e566a1e1a34292b89e1f16416f2c9935c7812ca939706cd23fe48e7110db7d54dab3e6a369b463e451cfe1b2c220ebf085ebc3ebc786d5cae20dfe3fa0802b5b68041be27c64c220ebf8fcf67e3fa7e8a3d37cfcfc1c7dff8368dc0ccd5f13c7e63bef96850102f822e2fe6bc7742aaf8fce6f2e48de2ae3e9c47973b99f4210d72797c6577f3d1a0909f6ecef333173c42904fe8419f2f2727c8badec68734c8a35bf8e5d1a4b845a6a9122405090609723114db781bbf45e9b16f6e3c891471d8e5d269c2b25e4808ffc3cc24f6e4e4f870c765b158ac8f9175a3c7b30fd7f308cf37af0ff9daa02273f86dfc56b90078a1bc01f8adc7c74e888f9b2304f8201fbb1480bccfc7ce48cffb7c4001d1c51f0b32080a4f2a3e6dcc35c62a2bcb2a83fae90f09f4ab01c586abcbb2bf66d1e94a09ab1f5b90d52bc02f9600dff0536f851400c91ea094e12108045212c1141105a65e894a0c0b96c0edab27811586b0e13fe9b87884c803087d2ef3fcc0b844676234bfc983db67943d0f13a3fa4d1e4c7d46f459c886486217e7089c31f6ea6043186c9b419412c8c384824d1e34aacf1df1a9114140f694bd263f584e1356057e19e1172fd9303ef553f745ec915cb378ba78d3b1c50229792746c9856c2fecc0955cbddab3f492f4a59fdce2a7e733194ddb9da3977e985dfae1bcf43df6744ffbd2afbc137becd397b147f5f439f620e12e7da75e9f6638f3551e8dc71e71e6731e4eca9baf79b3caca2ff7ca65944ae79fdc751ae9429b6f3535db26e7a281e914f1627c31b3b7c58e014b763872810c113061448516207bda17729ee4819070d756a9f1b6c6f7e21b7f15cde77262397e798d2f4dab1e5fda6f3ea9363b05f84da576522ccc4f699a46b5aec8fcba2cfb5969f6f1d22ccbb2af05a3617a440d97dc55b844bacb2ceb84b45a3eb4ecb56aad58ad17efbc8fb8f381f641dca1f48b31631ae39bfed7e1573f0931b0f235ae3b054c5aa9d615995fa65db1a566aa59a652a9a8d1f895ded9acfc922b564b32d324e7ce32f739e79c53864856d2e3cfc52feffff103487c452ef274ef1fe34e8c5f4856d7dfc5af1f33b0fea1ebf5030624ee8810a9173df396772c96538faf56e996daea2a353bab553a3b4f8991bf08b1274b7dbf003e84d853bf9fdb5e7e0eee8bf3b5ef8af8c76d59573d8d33bfee59f6de794c8ce6bf9081201122cde817e7fba77c7eee915fed1a4df4ebd9eb4767fe36452eb0ba4a5b14191465431f5a9a435366d1f5f7a7e64952e29ba11964e6ba475d77a8ebdfcf9827be89f7678c33dd9f314cb19f314b44d75b483611e5928c3dfd2c564d8d6311f22811c7a5c41b7f2ad77b10e3fa902433c4dcddfc320c1bca2519d8b0854a20c34625216ee843d78788a65c0f5be828296ca5eb4c43bce4745b7296465437442e5df985f34a6ff6ffe9e85f65096480d57e4c6463d86eeaa274fd4b10a3cbd1751eb67ec915e009db802df665c78008ce4e48d74f43e3859bea554250b0df0bf6b7ac2ba13f6543f3dda370bbb7a1a1799aec0b971cddee0b9144a6cb420bf343ce7ebcda4b14ac7d189680f683a1c6abbeaf85f90dc58d6e339f7e26bcaebfab4acdd7a8f99cd88741a552a9542a954a65adb5d6da6f1203ed2bb12a954aa552a9be490c547dac312c3f33775c83b6d825e892b9f26b81a27193f0070ae053e6892250491c238b2b37b49c804a564dc0fe9a98b9620a48051a5e1001c534ce18830854428386f43863d8f24212175264124e76c00254129f90924315910c134374e90254129fa07245524e127f25c02f39c60f608a1acc1827208a523471010a640f4819709b1c7b91064d60012a915135b0c0e328d2e0218a6661460c946a151f8840f66ca400374d053a38815b4a89a832a254006e1bd75e1c63872527ce0446433081ecd93c815bf7431292120dd79e1ce2053a2481ecb5a4809b4aee6006ea085432c20ab488f2bae02c5308c2305313849427a06a30e9c1a88803ae3d8924831822903d1d5ec06dc5746688241b529e28dde8e2844650074e3e24b1b8f6a21249481481f287303118021988282b4c207b3949809b0dd79e1ca3459623706b71edc5289c8832046e1e1859d1c1b517c164f1610ac89e4d0bc06d07d71ed00e14ac000a5412b98c3182081b2c402539845e071b28795c7b2d02a22e86be1bc0487afa806b8f71f0c28722903daf0b10a8ad40aa8109324025236cf912a5db63285f6e180279f008cea8a204b2678305a8846536464c41031b03d92c801755a2c04d3a8941c9c5fec4b2b2f6581187bf064a13336006b48501662ee35442ca32059cde1606185ddccc489a9394923b05623abbb1498b13f2ae22a7b14517d338716bdacfaff5ca6e9a409fd2ec047ae6cc193345e8993367cca822f4923e8d13123673b3a79c0ba922f460ead9ab92fa94b019d0a8feec4aa845b25bdfc68459fd6357699c1ccb0916b6c98faead491e3112432da1228bb3455b2ebb2ebfb8e988a0cb0cfba25fbe4d7f26bc9648f923cb6a85c11a060b63e5c7ebd4f9e5c702f317d266fec9ff2c64fc82d5307b58965d16b2d789d1efd80d613acc23c1d565be215ac98a60b78afbaaae3fc7efef1c5c7963c7c1b562737ec5f826cc2b3f1a277ec5af222b6c661b11ded13ef2581eeee377dee6c9a07e1a237520c9440ab5fcba0ac7ec194bff2999b9f97540061bea705e05f8a62530021a96d3e122842b6ca8a3c42c3f671fea43f418dd63f4e8d1638cee2e70915f72d5b2627fdc79711e98cd360f14377e967d310a208c5f7c96b0f56de8ffecee36aa9f0d7dfab53f3333337f9318c80f03508a04252862045256f0c41410c83fdb37d2dddddd9ddd4eefeeeeee6f1203fb8321f2cd1256323995c316b9a74c4f999e323d6580ba03b75f973d299c1fa844cd586439e81091080000000063150000200c0a07c4016138241652656def0114800c6d8e46665e369849434110a428886108328418038001c0104390518aa84c0022bbf2118ed4465a27509d35a67b9de8ee7649978c1b15e92f2325e8b7e0a9629160286172406da3f53e01b25c592b01f602458f56546a21c20a9bd2cd419436d6a58f4aafb7a581c27197f703d7f3c807dff3702785d228af3caaf425a458fc3e431d3d51642d780d78f0e195c6a4e7420d43611127ec8808aca7415b61a41ff60cbd38d3ab89871ad61955e3c6650f22ededc8e9eb72b538356323d7255219755954f055c656fc9d747c4755ff022d7133d0b1611e8205b25c43bbda8912dc61be8aa46845f2107026c84fbe8dd50c3e2dc310ae392d96ee211845740bc4d46ee815eb6c2f816dda4f47d8fffb0ea6c27558750601fdb524050d94631f876b863cc6135ff4cb5f22ce7c1165a3a1e31b97434179fd376ee3108171f759ac0f01d33fd3dfc211bd0c7f156f1a244f14394d0dd53fe1882757e344819f28703f2ea37cc1a3e105fbb1df970b656c40e1430a78d418805b4a9e197d5019199158314908c06d2475a4401ec1028631425d6546e6516e765571c7724328593a541e43b19d1a899a5b2264feccfe20f44d6dfa26e7c378f8fcfe1fd2f30168bb4a12078ba43639276ea6a1be030b4f79ef985badcc7bf6dd2b371761b440f891049879929d4d3b53a659a23194d856ad3be2bf318883c529a5e838bda5a574eb21211063239ce3350536c6c6065d44c45558aeb5b7656fccc293b9ad81c11b9b84de943764db4871f748021ab5c459da42be1972d372f381129a0bd3265b16cdd4ab1b4f1cd89f10ff7f0189f1414977b43d97ba77e327e27c3ca057431658fc2c36475c7885694aea2fdd7ab82b0023d55dd9320b64cbc6ea32622bc63345482de4937104545b2407eda05284e3cbf6564db49032530d3490947457bf26a2f30ff90a6995b270c8cdc1f40bc15843a3785bc5fc6192108db6759cbd115adbbce76919fe4d58ebd9940a770de2742c1d05fc0b461980b3a2d1ee8cd23cd69c597b86769e45a5e1c8df97196f01ec6ae6fa03f2096b144fb2234737a77f6e11993c3ae1be76196afa77fe8e53e6ca3df0af994ed698e026c654fba971125ca1650221f16b804224b038422db9f876ac1682849b26df7b00155b57db196b28ca21ad4fe53f1c3aa1b71a8a75faf17d7c6ead41a5980259afc03c0228814b4bb3e18bc19b693c5a705d161634c9b8757c43b3a2b7d224962bf12a8f166df303402d1e60033a2e2ddf105010970165f009eb7fa8ca0e9675392552bec667e8666f56b355c44aba6cb44c1ce75f983aabdd1ca45f740222496dfc9d3a6890d07046332e640f4fe193380a166d31cd1d1b48e27290961691c4dce37860ce89a1f2197e753e6d46125b11ea2bd68eebc0d88adc80f1c946cae6acfc69c71818eb5f7e0af66eab9463f27df9650ffb6708625c32300d07f8f3d07d0236f00f8ebfca9c0734558ba5d92562c6b6b3a27e0b05b13d337c84dd74a8c78cad2b8822be32760ab45909d5669ed9d47a898d6a2f07be67349ac1a476a38cd54045aaf47ec30395430cb81fdcebb47822293a8f0ff122597fb91e6119ead869f6ab4a78cb8d21e621a1de43dee96dd71e56e99eb1fd0377ab8ba9518eb68da2eef1769a52f2c4505769b7a1138b109afda393c7aa5e3e90d0f14a4c9d9da81084ae585bbc48cac00a41b9c18e355f81fcb5ed73cedfadabdef61b50131a6e610751752f0f34ac69f6ee963cb1bf9099e06cfd57c1d4f1ca5073383d42e6b124fb9adcc6c108cd9d7dd585229c4328855c77e7f26374eeb4b2f09222db46b5b83be42839ceddc108eb5eaa1837083a96eac2be4fff0c6e6cf3c8a0a07e89fcb111ed1080896d22a11146679aba3c08e108d7e043cf0fc0b57970f70e274b408586050b29f0255f22f962a6f13a89970b5191d4399ebba6c5e6b9598e419ff8361a958f6c2e123f96e20a523c8f8da105f0be0df778c4b217974dae592cee9012b8de42b9d64f167268429147bc280f6e633703f60e4f268037813d96c9d3b5d8d37879d814c561981b536ec423b9b2214e19806f2af53b840321182ce4ef087250d61caa1376a8a369028ed8ab344960104b717ae84f283e5a579d65af64d50b6385f36938805ed854d250e7a734e348ea20384958ce872eb60b06098ac9c1e31ff50b1b08cf3c06c3d3325ce2342c992f3d441ffeb4f93aaf29f853c8a67aeaca76ac5d67e123b56b9f4ae03ab48cb190e15239c6af3694728f52017f4d15062740adb52c5aabf97feeb7fdb7ebb0f64bfd02a320a83ad5a29024ee5a361fbf194eae4f694665a3684e8874594548180ed03e482748fde598caf700b1854b02c203b30d11c87d5e1bbf12bb7dddd6933d66e6f8893fd76c0e69c2a01db8406830386058349dde226a0bb411ad0f616ac9762e444176e3e2acabb21b20993d2ce571fd0f820d3b3f8131ae0fdcd0930a79e2f759a24e70fd0845acdfce54b2726dd0cfea10a39b39f8ca37615b85917a72f0481843411fb325b214421c418556c7b4573c1d007cf50c321d516ed82742e065752284d2c4c123694962fc20b22ceeeb88959743d6cf4ea6993ed19ccd2c9531c366ec47d087095a0f5bbaf19c0f2868c3493553e9235924adb142213af378a5ad5784d77f58b2e4166dad872f769abae98922b02088b035f68e8e62f7b517a2c431eeba287f0ab7b02913124d23ffd1454734fad539770ab29d593fad65b78f66ca33a83ec628da80a1844ef4567a657b925ac9bb1dac8cca067e911737bdd1abad80b4e2de4b25ccd7e580d703ca4d8db6d9105e55409acc17bcdd37c075cb38d29bc0657343ae40e34db56b5fe4d30d93b0874055c9a2960340634761ae889ad135b5dcdf6907ffa685cd25ebd89e2bfd6a05a4bf7490052550ad80f1c7bb946ad9d8af1c3635277cbb57bdcea20da98aa30375c6f249a121f3ca941f2252b2ef9625873f2bfaa6f79efb174120be2644567f679819e501964e542fedb2f0a65c0dfeba047479a7c4156183b13f53bad4885bd5adf248fb592862a186f9643940b34025aef58c402c66d3f3bbef9c8260784643bc255352490a2a0f9d06bcb7e9b388eabb53a51ecca63bac84493c9bb13e05cd1c73e48a7342d8314c8a84a81f66bbd7b660ac61cde0a8b4c13b514e7b5650eb040fa8da06da9e4475a3efeb35c5721429f56a0e30bbe929c923b3b247a01fc00cde255649d27e61ea9cdc7e42133cf156bdfc2068f4dc085c590761487b223bf1ff99814085794af57373fa36d4fbb7d7adacbf3daf20cd31a5ebac13ba2ec265cacd5ff08a873a53f1079a0475cef685fafe4ca7c15d2c5a80c7cd37f5cfb3fb581f06be2782a05f7f32c55d1c5f8a9352fb1cac91d6862b1f1dde0e47e6efee6f3881909f109e3589d37c0e61735693e3b9d60ebf4f4e048f8126323eaa7cba552c5ca35a2e6396566f88620d559c5802a94f1626b2fae62ff150fb137ca8a14fee18f5b801fbbedbe997dd3fa5a071f38636dd598af12abd62311970e672eee9ba24bb7f7200fa86251188d67c3a9b386f95626d21e17f0bfecc6348ae297dcdf2f7572275051dc15c382044dbe0c958c8a9f9d3eeec197da486405fe3fc2313f2b17d8f6b66bc028f65894072d706b50a92e08b781e1ed68fedda5b0abd04149c0192c8c525f7201c692be21e9eb6fc0fa3f91df4ae7754796f6438721269c0c1f15a01c2ada8cbe21b0eeab860de60fa8e3c267970311f343f721fa948ec1d7906b3a420f86ee2f08e2cab670995402dd7fc8ecc3b96eca1aa9f7cd5471e69862a2db296cf047dc812e84221c382fa6ba1080bed3ea2738c68a17ed1c1e73a8450c39ba5a76d95bc1c0480310e91aba6ede028966a2912b54f32b6a26c11a381aefa35cd7776c574c532e9321d53cdcf9a676c2726bc2b2751530f8cf4831011fdf1918360b5203f607843a47d5751ea3c100e8bd282f5ab0066127a943947dd417ff1518102572aa19cc8ee1809f824c4286e4c801241cb50d00e16c7e64e9304c1824afca814f93d4b850efd865e757926adbc71994429f02e4e3740f7b3ae401701f3772a8c184ea4c1f56b857c962977d9d16f0b85d0eac65790bc205643ae6d7ab1eb81269e52b68c1e8293bb4a806f98049eafe0e2b05fd935a72488a6598c53db4ddbc19545c3ef99a40bd1b3ecc28b8d17a7f0ed4ef451f60728e00d40c7438cd74c69040fc082679a62b3141e258911e2f87ea16a76152dc61c201dc5046b7ad470e8dfb9f0ced081c9950ddbb2e6e0c3d580827ec41840449023fa125486673ca89092ad84e2512da95b4012ca1fdce9a24e8082da0484011580cf29731075bfe104bf47f80449c3b60916211d1969915b388e27074883e1726808e4724e903ca327c2d80d37743dcc2b449a49e8a413f208b07439c578a0a96a5427f7939693ae72173370d4953ef06ccd987600a055fcfb2bd16dafa020312fecdedd89d39ad0e0970d8d6ecc50818afff2575e1d063e2579249a8fd43f9c174d8e6cbc5663f05b23707d67ce37c48e9d84b4cfdf30b0d25cc8ebc408fb957c1df338766697df9f88d4f1107f9a0f020d0c0150ab62815950390446b2c64fcd68a0fd943709e396b6e99bfb512f8de00cbb12100ba00f09addb7f4e80a22cadfdf5de41f21dfda398ef9f494c3796c358d88b246eed4177ec46c34444486684fc8ec842afc9ad799cf6f3fbdff7610987964f43ead0851c70fcb5fb8a3288be904aba9d9fe14a442e7d565af7549cc80d993aa9f6cd6df644e6e93b96e0002fedbcd5846741ee031f92d8fe894d80091120647f4bb619e7c32365f18a0f1b40fee786231333c8e20a5bf1fbced0864aa01152a2c540a9fb3764acc9ef388d855cc0f359487754d9dc1d21129e5f532de3474acafc6d86bf85b1f297bd4a3b10880541da0e4e86d6b93810115f1b18c0cf8ccd8a9a9857db1fb41a402d0adb94d9069080291276a7b0f5ef841bc7d62b7b96ccd6f2d5185b563799f808af7c99ceb33103a203a65187075349269edf54bd9f76a0dc764588d0344c674719d4477b6cc1cad7f7c3bcca9b374a61420b8f334eb45cc9c1f6b6c9cbd2a4a962a8704f4b8c8a08d3ebaa7804cdf9b2caabcc9e44cbf4d3cf1e7b3e5343d240687b7107bf1f1825e574432946061089f6662dafdb66366b0ab6937b3ae8f0c941c15d06d64dd35140559b68f6695889a5bd987df32d24174495ac456c88453f09cae14b33d436c7c3e3e53183ffa64738ac757742341a927e4468890c3dce74e7cd27b74aef63200604ad78ebc758470bfd3a821d82b0eedb7aa4c93c1025925e047bac6d8b5131bec75e7d84bdfc196f51ae2270bcaac5822604cb0d44f3a65d61d6cd5d70d38ab5ec6272527030441ae8decdaf594c4ee69e334998fd9c3e6c84a6dc5e941144ce450ba636dbf18146cd3318f3777095cf4a432f93129ebb1384f088b21eecef0665cc621966992801b32949aa303b0c4e9743a2de30e4b638b98b5b1cc430ff5fd3b2293ef7e6d798e11d6a42b6ac9e81273471c4685aa2a20fd0b01bed53a7be34f16bdba4e92741f58aab4c0641a6a3842b193dc3522dcfe0b10bce7cc1643a09bb7495be25ac74c50970e1b79f3f1014102186c7c3b7a1346d7e10af3591d7f953581d0354ee48f93358585e7f87813b3042030f1b84e2804ff73a5c22f182ed551e5452527fefd7729eca8269b7585240149c11b4989f33c58df511fae285d89552b0cab6845413fb9f1e34e945461b59054d1f88f6c69a40694eecf211af999ff32196ab306a4d42db703a00a35f2f53222712ea389e1b87daf63e03fbb6affa17101ca21dfb56e16b8a680435ff1bf1bb519229fe33d11cff647cf63debd64bb4291ab5c74fbc3effb965204465250675184ac1543a19a47ddfce78e65909add83ebbad357fb0451bc42d156db031bdb044328aa7e5624006af128c229d42fdcae25c9e833acf89ab3a73c53ca8459671324f5afde61e6e23f6530207b1ac3dffd5570b3b5faacf64f0a9aff3fefa21147b8fc863e824d10c764fbc48748dce0a9b74cb25138945984874d36b2d1e3b749f26b05e962c84836825c55fbede0e9cbcb130a3bb9254a90c753f4d258a2b69a114cd456aac018965aaa9f478b6366e7661b553e0cae8669cc26834f8f5b0d2cfe6bfe8aeb7580a1338aa4114fc513813da4e9aa2e3fa35b8a24b7337d24499f28f3e518bef050ec499ba239c651fa99798496285065d3ff0c161466cccb33f452669cd53ca3ca6e5f5de49eea71dcc6d23f730d9919e1702ebfdae2018c200088b8730a5b3a5532a55d5b9540242a17b10f99ed621f85411df1311806e4b495b0412ea9897d94ba140b17d28f73b53686ce0b693f0c72fe47e6d8e73a1fb439c177ec7d962ecbd72e2c87da21dd5f36a9b025d2616f73d2c01f004bdfe6c1f9b249f5d5e5165f1c867a9163f4871d6bc526b1df6dd66897ecc7f8ed687d4f924b5d42f3935e00fc9644845895fdd098b61079e9a3fbaea4738eefeda5a4e9ff994bf74ab2cd5a8f3e0225945555b14640a4e04887289e15f91fabc868824f7f01c6df86b235b7ac69ee925493491641f6e6a3a49adebc7485a2d3af2c4ea4eac3727e2626fe98255c0c39389526c8a7275227957c7881816d9a73032965e0dc6a87d9b95b073478ff3eb94d95b526031cef6fcc72a1623dfc45116e81f959eecc943feed588f12abf1de89387e77a4d211a8941e38cf24c389960a03bb9cc256c3f9ad5c0d7c88555fc0bdca5118dafd15d76301286c6e178f441442093175d0f6a3933684032a7338fe9d8ae6c661b5a8eedd5bea56aea5ec4dd06e38c0c7fed69633b786d89ec3c78d77fa6b170664ea3e3eaf81186a5acaf63989cf59fce66af1d3cf695a8c4c3788efcd2d8d9e4da5a17b9eba6e7b46f2dbc44e8f74c6a7d494655c88bbf79e247239fec11ebb58453e79768a43d9aae22769b1ce4a375d621d0b940897d4d75a77821007b5c9b2b4726bc81fd96955d0d0d7a7d7ec94822b7c5cb4247200e47c866634d6aefce92722e02e6607843811aa8b3fe92187eee62aad0642a60930cfe33890c9c5838419e96dbeae63955472ef96d360da2fbebbe8ed21dc111b10fd05e5449d981d0db5f539268afd3e08fdb6e40e1819d79462902f9f14a9f6882a294c45a8cc8bc2c3620a2c9e70697f1c9c36d2ee976b6fd63ab6f2a99221f0cb2431aef9dcc821d8ac7cc085476a5fe6c9b96d2b8dd7287958161df25032654c355795a914bb7ec977a2c1601812bea5350d9cd8d211584d8481c717c27c7fd5b6f60d9163a7f1cf57fb83217909a02997cc1ac3544fc3578992f75eb1a09ec245dc47bc868887ad3353dac4ecec0e105fc4cb40907358fb167927197ad743965f88ab1156dce3853350fc4443b4ea42ea587aa988f8943ca48a32455ce51eb75c405d3af73553fc70e0969a82a7061c0689f86664aafdd05737458a6c4d5161ec202a95cb783afe0bb2072f0cd785f972d96349465a3191d13491162a19d13252eaac4361888ab289551939baa3fe6fb7435ca83469c50dfc487431159168d00ff80c0288891855e9ecc715ee2bc1c403ecc1bb37d2e7cb5a108a358fb156a4798877c30cb2442ca07f45dcc45682552b890ae827f40579f09275030956ac07a87c515e84558354e49791d03f6ca54c65fcfce6c2a58d7fb8cc25e0e413e3b72296cc8f76c4da23b1de8d67d1632bea0b8be518bed39902b8d2b15642ce1303189302da80214a34b5dd2adb6890963fbd6f903bb62e08dce0bc8006cb020afb8b756132aceb1569dc179bb71fbe1eaf89d1d8dc8848d3fc75fd958cac53a0f708d22bbdd581871e2a31bc3b69d869ec529c71603a7ab9816fdf8c1edad61798a447a41bb2b2ce24db6043e6aed729aef1e2875492bc4e89f520e2f31dad69805d4f753c7a920dced593313219aa16035e3aad1f6abbdb21bab680ce9080ccb5ff66ee36a804349e124876673f07c8ff793034aa5c8f511a627e5b29cd5b86348134309f6b38c2af09eaafe63c0017af9dc0283c4364aa14ed894e20996fb52bdb192524375ad19e209451c65d957ce257c791b33ef75ec0269f316a63e0b90e9cb84f639f35b4795944e9d8aec895f31a101171d4086ac37346de12b89ed9ec5fa689b4c5f03c9a59a8a2e29bfd15557a303d9cd70d8cf48de7417b64f9fbd207d616b586f23198252cb18ee71b79e63b95382e9186aa93432e4a9cba0e58ed7da3d84c070dbe09701dbb5ee87372e14473be46124a468f540d27747a887415cae160debc68ce35c6953d15ac2705b36b618b3527c70ac60c19c3eef75b74e276e58462b37f5f95895674f33c5cba5cf4c87434c017935222a98172dce157f47ca7fba3eb9b6a054529a6bddace09248fda91d0e603f8933eece81f5ba768e149748ee89dc41081beb2ad5a72292eb58e52a31e07609c8a6f0327bce92216dad5bf01a901a9ceea9117bd1fdafd7dc3a6210ecc79a8523872ed3944aa8f00f189e45b2897f8fb9941e6f629b206ddafd60067bdc3fc7b0072ccb9059f2b3fe61c709ae1b51163858176a2f9a6353e0530055efd4e81d0aa29176d82c5414cbbe0e2731c6f9a3433e26eca43c739e19a8738a45f9c1c5e0c4ab4b1248236da287195323521b2798e906f2ec21df4191c7652058da55554acc2b4e13c2cee52f7252dbc90ed9739f3000042a5d8efed741b3497e34886b482010718ff89757b74361d51eba1010bcf40daa2afc6cba5021b0d7d743f77ba967244a3f64eb4437177ff05e9a02b2ea519e2324b97460f1c3bf2b936345d81f56351c9693f349ecc0295ece06136f4de4b44481e7fab156526baf2440843c2a6aef8c31cc1e68994886b6027acf7a6d88c1e1056c5c023363486715458d5e7fd0437a004954d92423d88953842907f241d23e37b6dbb0a45d4412b154682aa3783b203d6e490b40631f155c965f69dfec5022d193df9b618a22359e1ec7549a1764ea43ab9190548b037de00a8c440a0dc3000e4187603d990e3ca805babbd1a0fb08bb5173e91e2aa3f4bb0d50314df1ccbc9aa51b381310b2b2cd004535306ab8be8bde9da6a7d3468c4157208fafbad34634b9da9a3552353a47f0808390961a011271819e5f4fc13821d85e83a6002027650ae5ca04d042d552db861f5b4f404db0cc91d52931b65d48d465967b6b6391c82770216c3a047165757fd8d6ae8dbd245e350b8c07ad32d3998749badd8883c4491537652b186306f5e139603402867ac3c05c959e00479cb49c6d0312a8dcd9aa9aa6b765d9e5dd8a2dd1134ebde98e7b9e53315026d42be448b2bd1ae1c5f690af16c22d2268bc64e375a8932781382502fd7c383d9032d5a8541b510ef66266128d2f4b369a65cd86352e97caa1969899adec41e9be292c42185e77f540883084a59fa3302741f1c7400dbf088f5928a7e121f6c6b20ddcc21a285cbf96ed4a5a06c9af10a90288ad38ad3fc638d9b5483f9b410f73716ba7244d84431ff37b57b0c564c2d4f1d33f69b48728ecdfe7441fc00c8a66561c6fbea11e109b9eca21051e8573b86309fb8f128969c516af94344e413fc9ce53c12ebe1c10e1fd1e951c679680057f6025caf3888be6bfe1b75121a40a1261e4a5a22172286c3f246b012460bc00cf4138d44bd1d656f0c455113b20ba8a540beeb7813ef98f434d73d8c2e796e786630b586115a16feaa5b2664fd7cc055beca73dee1ff84c2627963cd2ed1cfbc27f1b5a7497e20110a08d5de3de443e15473b3126d751bf5d05e6ad5068223b61fbb4d76a1e2039ae104a8eacda2a83e2ca44979cefd2ef925edc8945dc0405c1e87d6f88dcee41a4a1de4bcc102d1f7f0a178017008e8aca0a5f3f40af31050dda06de0681ca1e04d41c41c2e5aed4be6dd749053759735f3a0f6e93e34d7f7f3b15c041eb400606b20447c710aa5963b0a0d111d2e92f356f2b1301b3463102074bf6e1d0d75b9222641cf28100eff7c32d78121e173eaa1bf91681227049f5ada3698ff63b7d09aaf19339dabcbe03d72f00a3d0ba009c0ceadaf33bdf85af83bd4b7fdac3ce1de0f2864fc885f532b21fd571bce0488004cab728f10b7a1988882ca5da89decfc01fc0e6a3b1fed9dbe13f68531d0ffbbd477bc3ce9e0c84cde0e3c1e8a7f4b2c0a3e155de913b6468c4860d4e26048afe0f703ed2f55c54cf3a7e0edb7d39ea4be8176b53f19ba5d41363477e695d513b4110094d13ea66a28e66432cc5fe4398b50d43d2f6440b12204ea3c9bce7eb3fb8900bba88ece7248f18d9c79e185261277fc60e8e6b31f558d329102846ce07db97ceaa7089c13de6adee1122ce5acec09b51a78a453d572476443a2c1e720a7b7fad9b782e70d60f4b8e37d0003d2196bb2d06f72a1f9c3aa68f10f11916dc3c3e8d1bc60ab6f262ec498713149ddfcca9fdc041b9efe35488efbd4bf7a0ae65b719e95e9b3468022b9dcfbe297b3465cdb4b71f2a8cb85e23cd34bb7068322ff2731fbb217b1a26feda74894d88589645986f8b565cd63aa83f77dd0ef9a3c385053641b13a4d92710d9432f7bedc7d78dd23e0dbe0a07e141c4e62861a0fd3088fb4f0d259f4f09b012bb4c98bcf461500b8aa80e93d264c663bf78e45899bdb7b36ff32b5c47ecd5f94fae177a7a956fc5a408946e60ebb5fda1efa1d63e74951c1e05eb06a6c0ea9f497dab49d9ea25a5701397fe520d270a76a41bbde614523e7fe7bc710a766d5503e5955cc5453031277427b83e97353a18bc4ef4c282885e50d8eb2d1375245c4821f4bd72ee0da7baa6ab7bb23f92c1756362ae647b7e3b050de190d240d76fe0f879355e71a85424de25b4f86175942124507cc18a090cf4bac8cf795864de6f363134d205d17892499d32338daf0bcdc92b485e1778e67519d8e22b73b8c5876b5f3199de921aaa191295a090565c9e37ee58fca20e8b7f2e7af855187aa2b38eb5e217aeb506a0fcc1efa1922f511bc5f2c556b7809664f651083263bae2583f5fda3dcc986600687529da546766ad830fc16408d3ec7917aa22f098685ae373255a1109930f9b8534464644a1ae1228ff47724c44186b9fb8724b8fc59daf8bf6a2a4018d1d28fee47091d4d5629f4ccfe0885893c6acbed612a359f0068928b893731b9d1d856546dfc4766608e061ac859d730cc44362710467eb3fb77619f8fb1f740db970c1d7c25a59e3177ae7584f0108d5d5bb999ea79c6fc07df575a10bac79c092f897c65b94f0d5bc1b6ae3fa1bb7e70874137391acb9f75377126931325cbf1e999ea8407ed607c5b23f045b57c22088d175a22e31c91abd197056b887045cd662f0bd5755bfe3f808462a00e4d1cc4aed188b254229413ba68ef61d125f67494b670f89b5c0b673e655f13a0d321f78dcb80ab706a968f8fef3dc13a764b9e87b0a6826619a545cd133e4e23f9dd2f5e9c2e16da0601f2f68480d7a0539a7ea9bf16d6112b57b8ed8ee8b567f4002d7cb55bfbc2b598ffca4c1565b06c28e696fcb1843fd27c4f3cf7a344405c8f896a58c49950b9f897e75fb654029e7db5a74367a47b23ef7f1485cc6b28fdf34717c47265706dbd4cabd14d02e47fa105cd04a4dbf6f12cb9052303495ec84b3b51ca5cf66f4a948f466d5ad633a1bc5a46338632dd967cff67f1ebea432a0300adcbdbe6aaf84778aeb0acd3be2b9f1c51a74acb6bed9c4b4ea14416c55d2dab26af6e9935fa303983ae4740fcf75eeaff6cb9f21bfe7fddabf679b7271692f018b7e01944bf4c81e594ea4597a02b9fd4153f6207657cbfe6e54a4d0647d43a9941f7c017d1c225369b244f8c48f4386f29a28f9a7ef7bf34563e975d4a93ac7679d883d31c081ad5ab9d1f87d4fb511aec8f8adbec4d1cbdf2059f5315ae846e6220282f494b26fc7f20de9b2537c0ef5e37aefbba74197ef7bf64127b3129c393d187c9285f13f316e36b5869b0825b3c9c3479aea30f03527653ac9d7f7e469a8c4624020aac76b8d7f0f782818db61d0965ed15faa3d8c1de31498057160e615e32ca80edccd93ea890335a4c1b3e5915995e2fb9dfa54d319ee9181eef8cb94a358406007727900f0fdf7ddafe79b8f8047cc31ca889152363dbea34fb7038ea50fca0180f79e234f7522911b5589e0ed7729f90ba07b56964713ec312d7dac905e9fe207f06f3acb78726a2e16066ddc295716754a465297b6ef7a6fb8203fd5efdbe1ec9b56d3631dfa25637f3e8bbac3a8b10eb4bda599294f2b2b50ce5dd33ee28829a6b109c99c675c0b711d7ab02837aaacf3b228fa1ef444674b05e8c7ebe919ff77f3efaf4da5c2f02a74e82d9088d53f4eddbff86fc76b43d46137a3e586ae7c31c9550dbe452fb20121e47268956d743249323ad1f4914b97ae171a0eed2d0e7452c8ff78fe470be36ef09f8c3d0e61e1f990ed1e01f83590e450a74fbdb011512b0d56d631b8822d0a276d5e4262052b1c1ea109956311fe2bcef7c7b5253525930b464dfa4214d4d254d4d07d94537328ee0554b4b439942255fb7bc8f0e2e475c262f0378cd93fb8ea1e53b1b86dd6a48a100629af05961e7f296f5f12bea98007424d126ebd07f4b64e1cdee4b8b1810902cc4d28103a111708dc4f9e62b3da4b35ac0d14f6cbf470e5bbfa513495cccb0acc3c7b7cb93a25f854e2ca702575758b02b4642e4edb7bac99aec327ef52926c72ad28a8039b81215c257260b941001639306f6de673cb32916c9e2166e746e2c5a413f0dc38f0b85d856fba917ea40bd577aba8e4335a2f37f49b83605aceedc9d16a32869d62c00b16194d4889f80d10eec591f51c5886ee5eaa9e8438403704dd98f1ea7d8b4fda10f38985552c315bd67e428c4e85d89fe64412e4b70b6f06f6230cb97359b09f4214b366ae1b850de28f360492a2cb33f9599d1798fb46997bad99f868247c87cb80b5e3c3bc3128f2a1ff9b56bf651e730ccc994fb62f1d4ed60335498ed2a344166e17f985b91062736fabc389bbd20a9af4eb839d243bd9a94006b7b5bc625f1815b574432c519c8c0e6d325d0d107030321e70dcb6f63ef5b207e4d4c1545487a0c71eb540d8e1b29447d485dd0f66200731526f06e3fb9b8b96723b4fc8d877e5cd47eaa3c523c24eba4654d561d7ade42ef514a7d3307d0a8fe8e13bdd21481242b3452a498d6f9d0d67fac861ae8695df2a1bbaef22dd17863177b63c990507ca490ebb5e1129a4cbcb758e41e6561ae7e88a2be31719f61eb9986c545285f10bbd96e7ef76dcc3775ce60c80bf9b62442d6d993dfd89c460a8e726748897c47bdb947f33c1af4faa5f87309a6d0bb27597bf5b34bc12e4d3bed8bbcdee3e7f3745e9ee88cae4c19c46caf54e4a523ef914c66ddde554a844c694ca5b97bdb452a9bfd9a208596ba3b5126011f476493920c0774bf2e68b71abbeeeb0bb72a80fda166f640bc39d9507a362c5c8414a53aaa2e8a6dc294992a29b9553111afef8a3303ede244e6b7b5714083f34e126245b5ada38fbecc4ee5b875be0b3c30af7cdf3c5b2cec98a812eb09f1d279fde9af444769b42be0cb3ce6ebb2a46d7d4c72aa0e48aa5136f8899fa02d2db11da1fb0675bda0c7e7dcc760b782938503f64443377b69a35d2f05f469b1d38f93f046722dfe013a51f1513adf2617a4ef896abe444bd698e2fcb4d45a33e4aa1f3024ace8a071aa427e4a9591ae83d155828f9f51d112236f3b971034bf2d3b1fd797d469ad1a7114dc80734629322ad682c0c17031abcfbd41cd0ccdcb45cbc7c2d6cd3018a66c243f167760ed901921b0b14a2f5c985c855478441c2c59d146ba6782b77ed16b8b70a866d3e92545d36821fe24c65fc34f2a472fa878ba161aa74e7deda8f1451418ddcbf3dda510d3ac9df2046e1dd50d306fb283837db400005c129eefb64509f37d20b1bb9f40bb1c0c47d81b3334a04775bfa8a7c8a04c3d3651eb2e9ee66a97ccfd4866ebc8f9e6407381740d3f93e12168d09dcc606806350fcf0864e1e985c7b031cdab5dedf64296df04402daf680e20188df75e2371e4ebcd4cb6dcf044a8d2bc8756b04865addcc7e5250888572f5dc49603e323f346b50b49359f0775b9b440db3b4210775b97f5385488bdb4d40913c9b923b7b6f218f24d74a6ce19f6553a3e101997f141c708f4253b704267832db9568b4152509bb3ce0479429f1a9a3432f48a75b36e079086a17232c1577664155314be45ea3aa734f1049934d60eea058134c07907f149894c8b350e67c8346da2a46ef92afb984fb6c7c709bdd4e771a153cf50c6c59a884866b0b0ddd7996262841c7ad6da9278372319010fe8435df4e51cfbc3e32688bd1f12324408f18446d67d1245c8abd346549c2a0c488098568a4968cf4b0131558cb15e3f1768fcf1d1d44aac5e091e6b74dd67440b464f228abce75142cf8b8592f4f206feac2112eea15e6c718cdcece796bc71f3333b98fa79993d7ab0089ea4e89c65e0a8f6e1bc4807110b491e617962a8246a444dcf9e2b90df1bb53f02a21f87a25585baa444918cf2fdd251c37898684b53214e596dcac0990451afa4db62678c028490f201eadd1f3b9c70713267e8921a7064bce82d54661887e3ea4a71a71e24eff11fa164543ea458f462b2f4b1a086b67613d6b01bf34af9fcfd8968035797c041fb8b2306a3358174a743fcc0d1ebf1dcd253f34f4e46fe538478fd240e648ff32b06243217fe3e15c2596c85830a7f314c050eb7e7ddc42a9b5ad57d662602b1f8ea508963a0aee242f254129eb4c8e3fd36421cfd0de080aa2772140e59aa7312586d1ce2f60a7f2b6c5c8bbd9e5ae01a3b57e3e6d3ff753478e382fb01a9f7abd3dc648ae00c781cd30dc844bd6435b403c08a504f14f8aab092728a89b5b5029b0d27e25b667834ba906faf71de932be9975660a3a316e269ee1e60f0c5e6305523d4b78ad230c9859163ac611ba8223646e3230b7d2db7a6cc6c6eab84843fa27ad58f27af001e5c66675d997afb3569567ed32f04281b3b6a3a14880fcbb7f22300f246823feca2db846ebc38b5310a7b014af7fd004e8bd4d022d504a6d91a0efa107745e865e527d5b76a4253a8f44fe7083690c67a97bcd1f6d4c2cfa992d5fa8bed62672e7b1a149ad80e41e822315790187d63c91aaa027ecaea77789b7a2269db28062ea9e1581c00fb56eab0d59c87952a2f3ce13cf2e222dc3a5e42a5f9810fad8411af0339c6fea6830cfb6de12bf7e9e255619b273678f46b748f93c0cc7781719810c59fd520abf723e5971dde1ab490afdb0d5777011f7ebb31bc31a36a9155dba8fe0a589474ef4a4b94e807b76ddb9a91b27001340ea012df09f8c0d6dfa057b0525c705dca2c786040a5326e960393df6da1faa9211dcb18829da89228491eb0206002d5bfbe57f6112db6cc57a36480856706a460761de80a3d709723122f9e38e2934b46263b1d6b0188cb9af04cc5853d0dafe9f305e26bb59fccb70a2002a48fe82451367a38014c110c659507f8b2f9744a722f52cf5e5de606b33dd5d046cd8afda451d78344cb4fd017bfa2a364c308cee0ce534984e19622607899559303e953754effc444d3a24007cc026ed0687017faafffde13f4cc052f2a47b5156cd45ef017880a2204ec336854021f6e8863b26b62df7439f528b202741820be46943ec8df1385a3efa5c278272390e5006643e9f6c9388a06044a1188b25f4367e59f5ab41c47f52e4b2307aaaa241ff269b28d82091f036a13125314e74af603dd1b2c1320a55fcf823b0e496a0fcfec98c87172d4f507eff2840b634bceab89adf042532740b4579fb557032344579fc2ad1c994238cb8f7aaaf5ec9399cd089f6cb88123392a6f1547f199309c9a4536fe9a1fba3b5558042f1ec04612d99936e1ade2450c6f0fb12e8b7a544773b76b0a755c4cf348b88498bc193207dccb8f018873a87051d2277712b2f156620092554de7fa3a301cb21ffc5e722607bbdadd47ea6e50a06f65e46521833c49c80bcec09fa66f909822a2f79bd9fb23d1fe7060fb26bb33c8d512faceb4f1ccd403a1992dcff688cd71aaf425a338469ffb2547e4fac79966c118c17948bfd3e9be4d80fc288e76f26745448f5f4982df4de20232c749b8230cb6a0692c67ab656e5f2d6b2b2950c7163c5aad52fedc0211d81097b59cb4341014563a8689c2106db6157fc5b3488bc02ab1adb6312b493b64c48a1802694aa605c5941fd10d14535e954d46264405353c3c6a3516243f2c50f73849d24c556c5761b813507e8bd50ee7209df0529537d5b9a25496d96da82cc1f163cb68eda9890e9971c6d5b01c085cc585fb9896c4c1e3aed110ebf648f31a19c0ac6840a763483aa51a2215a00823aa58f5b14a94fae5a710524e239328d810803ff4d55a1693bb59b6a084854f9a89446066954402240537aab1a74947c07451e76e20d7ed08bd26243c84594caf142058484de938ed5a7269faec1373f5379b0d7ff4c1e50bbf1e6ac41188ccdaa269b36005fac7e8f79814e9cbdbf7f1dc39ca1ff7e9848ea608dd729b430a8cb0b8443301b777884935ea939bc48951226942c8eacbdc918dc155173af2590ba543644d77eb5904ce9ea770429942e0def0a6737a176b8260733993232a90b3422e28afcd830ff5a356bc2b268489783cb149b569b59f84cd40807780d67a7ec011ecafdfb7911ace189565538f867c76caf529f544b49be6075a112497a7590a11d6ec757015c0769385f08a4a93b526d1a73d585014a555f237fde5df88fb67c8cb00304613649d5b76746dc9d04ef0c2800a7f7d44e2692eb90a04aa19df09f6e89f843e7c5077484e33e8188012e5ae4f9f0c97a9eb331839c92f22bed91e2077852eb925df25f708a323283bc149a3c30c24db066f8b3fc1fdc7b26ef6b10cda4beb2b251d8b1fbe512453bacfafe30701fff72e706189768a8f21acfb84447e6ea04e30b0d39983c21456b96e13f62d0a5bba669fec1dd66970700b52ccf926dbd29a696d8e7d73159f8df214dea95ca22d8859e8e54c9a5d615e81c5906303292e8da4c2d57402587dadd2525235a09be60df89dc601592566a1f98dc60ac33248032380fda0dd1bb02fba8e9229291e1ad9d3509e65308a8ccbb583f638ca9da4b4b8769b7fc9b2e671a7c45d1f037b1270205ccee945aca4fee73e4bb1c7afd4119b4b97c84f61a8ac4e0f893cdc031642853765b9acc83364dc6b4eb60687633f835e6217be421b33639e637f743ffe1f2fe7b72c2cbc320a75ca2f46f5b1e90e89f53bf4ff3f20ebced71f4751b0824dce59057c8ec03cf8272484c2bf296c31cf1ca89c609f7f060ff3ff2d49a59fb96a4205f23abfd617928cd8ed789ddaf6ee4c0d9145d6e6eb0ce8e6b25c6b541e4f80ce7a25bc7d98270252a163ffee3b35b5bedacfc130f22f8f2834e1224701a4cc29d2e4f04bdf8e449af93a873ca6e6902fabec04a617be8220f22f86bea8f0ab2955dbd506cb262b63b0cee0c8e6c0c99d6ef63b9a31ca78a1ccc1e31dc26b51575a038f8aba8e5122b4693df8daffe2312dcded83abc9cd3d4c9eccf91a05d7472a3ae12af7498f17a554183dcef49be6e6cdbf335b132bd3f29e9ea48f7d937b407799c67bc896487ef77a108723349ac31f8b0d86b914374858590c2db1fb8f5bf769d7defe17d4058915061ec07019750f8e2c9096dfbbb4a1deab5e9140f7223f37ae980813a01dd6297d1d5b05a251212eca298dd853f56ef59b81a68fc768040d99dbfffa3545ee0607e21d42d95b32c6b1baf2e9b5aed56c57208e223e70ff6f0e4e5264dc883e5b09febcd36b8caf194b997b834373df5ad622407d3a13c370378eac0457730d3d5ef30c1802aef8f66f00aa751e148d53f29178c2944e391c657e1315536ffbbb83910089030696925d2ef3326523afdb065b024d28a62c0ed7262054a9f780a40300928066074a5d8e0f83030caa8d596370e63fdeea8f6d0215a02fc665f77ec5ce5d9d8159fa26623c46451472b905a366d6b1303d0c30e497831a1007916ea01e40dc8f7c67566c9fcb0fb11cf27a75200c8caed5910514c6e824e3f03078ad4ad5570f397d4e5e0831931adb8ff689d6afa5a7d4729a100ff6b2766b7b433c0747c6cedd34de9c7fdc3b3f47ef8340a88599b0b9e2c08ca41297c5ad2a106e98523d486bda9a0b3e02d970a4051aa835020055ad1e085cf37ba6c47c60a4f1147a07a7385cb0e717bf401c9a3e7500b393ac17ad5ef3439a992ff5f844878c81107857d343a9e9c2d6569b6c4b80f0852a92899ae5a9095db732b03b881153a4cc81112c9ea8c52ba245321e80859490b6612d3ff357cc44c6139d3f70f9a6e749b3e8a334d5a21771f644165719ed67be1c1d6df45dc617714932724c8ffa0e59a01442fce40f290ce05821a74d1d51b545fb42f23c30f807bb2a12870ac789a0491ed78b3d5594405175a1d1deca132e7e977d981a87c2c6a58a588b37b2c38dc273b984d5ead4f48a75bb02c46c4e70f50f31798faac6f9909e52d16473ed4495f8cc4fce51d2025b91f3abb7309597611970ee94d2d09d8fc99ccd422de364940127b26b35fc45b4afc44bc22120f59a30d447225f15d855acd78bc45352d0e2c7aede8d0681ceba3ded26df046f111b862fa226141d5ecbc9b33020efa88d91d60fe6e15ed38c36989689e94c2c86a2db8f9ea0f14ecbb29e147c2f9ac08141f8f922d0660d5439d65cda48cbc162fc07a84ca831f202b7bd32517e9aef51ea319e8905bf821b9574d3aa8bfde929ed2ac77b66369fa274fe8fbf58727b1f65ed4cb008314ea9e435c157269e041e3a909c9822038532e55ab152e97116ce97d0c8e600e573d509e367ada90bbe4d2e9550527702b281c2f5cb6397c64125e72a10570cb01c92da4cb881211bbee12843849d72b4982961c19873885f450f5c29f63439be48974f304a0b0558e055b5d3bfb0e4c25d44b2e17cf5523f4f381231af012bc2cd15a5008ac00269a9d5288162c98c7ed60817559e08b89718af9e8222bbad451c2b28edfc3ac768773fa5a268f4954a794a5162f76e02633096b218716b9856075a2c8cded9ed51b709b03e95a330491d705aa3e35b7f3585455083112a96291dd7659159a2182dce7e188b90a0add2ca91f2b68feab401f85220f6e446d5cefd128e0fb392fa18ec06fa07920544b95fd0a3cc2b3071766210729c3c23c0e6848a66362dfc2071ac0dd436b09024e9e168a8105221fa427b7b702ea9f8dc08d18d9148b7ce2c336ec7eb9804e7d3448c4cd6823007747306faf0a4cd141a70c59a51d142d177619d6da9c00a0d79022cb983a1484d4cdd3bdc62a782b1b26111d2af599afb3e011e87263a3a70c65b3deee151fe4811e84fa4a4a032e15b323b1a4c27c40c10d1da6bdad5aeadf143064efc1f3f74297640f1a850e4995207012c3a8f793a69480ca3f2f5a2edaa625dd9a649a73339c3729c2f072d14b94bd4d985cfe2168eadcd3b97f224c0c8d70f19ecb90f528625107849343a2c8d7812288ae59012bdf38d904da205bcde6bf2eb62c543b30887640edfc89e2f962205c402330208209b24eea35c4dca2369940d7f42fb7358907537c20e2d26d90e17e539c9fcc4de44630632ebbc5f39e2c011112f6cca0fea667ac63de1bdc16f04400e4f8851378fd1006c918686612b513044ff8c5fdb0b3b6c3720044472f33bcdc085371a70b7dc830a092854e04b59d613e8868732268d2a277cdb07a27fb5889c7771dd58d8eabf6fa3539cf3811dec747f7e719bc9a08daabdb1129a54c4d0e8032edf40173c15118fde0ce569abcb0ea7c4510c0897e232cb4df8f55f0763a744e9629d0556890dc21b07e6745d9e10c49f7ae8b9a3a0491e058fe78369347b18c8494f81e764777af299b6092a47ee0bdfc66ae11faa872578f843c4e7bb049784d3ee92a812ce269471939cc64444aa96aec686d2e2e231be1b65dcb3282f4615e973f7614369529a91955fab55a15cf2dab802186ce9ed2d754cdc50f444a276cb654ef7286f6c88d9ab89f930e29d0484de9e7423dc2d904d943f0c68420ec1f2c51da5678f4937662e73b3ed4d14683e1167a76e448b20dc0c8d23175d1b57a17a0e120b9f020fbd8e5381a9c8ba139df1f9c2e9c0e6650cac0e6cba5a6cec0bd362f114c3f3a4d6fdb518963b90557975b09a0a0fd23efd6af2bbfad048193d006b83be9f8b7faa05020393e831c7976ab4a280318167428dc943478e29d762790f97d00613f3264c10ae034edc1a946d54d8168ed8fbddb301e93c55f40a94d2178a89fa5136da8c9d212e9c749249428e8bf6c98980b4d51e475931070249ee9596ed414d0e0983404e52c195337637d89e015ed06439a2b714c74b322be48874c8aee7e639605db493921e3f5c21032b11734818a5c958511f31e9353d816fbb4fd0a0670a1dc96fb68fb2504a063e66efdb25342e327f77f391187c3f46537497f0901440e7df941d02f6100e0805f7e22a9973080c8e1971f38c03f30ce70f0fe28f81be8b02540f1f463c9c0ff8f7651b34b696d893d09c629aedf88eab6b347fa1fdf19ff98e90da56c9ee84fb95b8cf51bd21afc3f3147053c9eb8e386eaee83842077330d08ac50bf3d03db993ae1024f02e1e07799525732b069e2950d406097a7b172656160b64f05b1fde10e17ccb703c2cab1255ab2eec43028894840c33786e1d7c46958de9e49067025994b1077b4b1f13c158ed6c784361ee53b9cdea53dea0d7a63a471af5972d8830156af29fb32779ac6ccda05fe2a66ec629875335efaba054a90532fdc7a7611514d0c387e7fbbbe3b9fb5081f2002bdc2476be7472cb6748fd0036f53f3d94fdf9571f7c4e832e18490189456e7bae1f7e229e0631a9ad700a2a29eb30bc823e64c142bf1542b0b49e909cb81bec0444d4f921f661e8aa489999d4777cbf1771b5284a2060ab67803008a6073b0f125a979c58f93808ac65aa8119d5287ea1a797777c24cebac7fdf8ce529acd8e1f4ad92a8feb9cd988268833113144ff5cc6d991e95f62a7bd68095515ed90e1e56ae32e126de38035faddf2e15e6d031c57621f548c1f47508c44d1000a54b3fed71a44f5e875e0abb196b8637184cc194f6f16b6f1dbf2e17716250e5db2fda5132b23ad61f81ce8f0c2d3b35fad555ccad0c0984234c7b4e8bd272f7eb504ff1bf68f69dda3ec1ef1fad2dc1c1ff5cc4153ab0a5779c257aa9d7ee7293a31b034b13eb6e921aad550a08fd7af282fc17fb111281b087ea6e69a01d414a20281d57a13fb1943fb5fcda73f486762930da310e449d52dd48110baf91894ac6318ce17ad66de18bc45427ddd70886ed31611bd0b585c8ae9b1e62cc16c169f340c29ff3e6838700e831db59486af9d77b40384ffacf5ade05005f07f27d4aee0b421f92294fe6e14f65ad6ecf706f3cdf4b8a1c0797f85e9d9c9c3f66ab53c949d039dc25ea1723f45fb14a1a807f08f8b63bfa9e7e4ce234892ba52da0d46cdf0045421db36ad927dacdb931c329d9a231ef5d2150962df6adf8ce9da57aba00652e48d6a25b1cd5dc92e361a9e6db0087866b1c848a0968cc4d82d2a5b108a0d9b51dd51424fd1b939c8ca373034d5a4c9cd9d00aefda82046be32ecc3df3b0ed706506af40c0e666f7ca430e688c36bfe961c4cbdae6db508101d00415cf4ee4d909092e77394ca064e62aceaadd746a139fa5c5e76cff9535499d1e71e680745a611ab8361359d1391e0713ea4c69c5f0b2bc18da1c043bb99480b324492d0db7da58aa72c8801fcf3227cec6e0f9324d549e35da645ce863d0cf08299c28195d46b2639e985cca8ab39568bf2174d0fee689990b2da6aff5f1012c0323f83ab48ac1260127642e4e520e0bb5f75a031ad4b6cd8290f344ab1eb6c82dfb8816981321b425f80a891c8a3d2fd326a148a6807d673727511a5120534fa203cd1534e8a7d25b9a10783512ad40f66ee768607c20548be579daed9448bc7d82ca57328d329d214efab9e27de2d8b03ab4b22a05b26fe5630395fabe644868f35998b14ea43262d940247b58834036ece2b0027464d2f19b30f90eac84fc5fd0efa495e133c9902e01ecafb511dbb837018ec40d30c9a50048cc3869bf948e12208d6701e3034e4313209f633412df04a9e74d036d963862fbd9f15ab8fa7d168615bb4ddb2a5c6aef0fae57c893da9d20496fbb9f35365094688cb3b81ffe492c54ecc68adad8b489af766e86cc31605b0edc0ce563a57ecec2b907927f8afad50b78cbbd8396255f9181b482c6174a9457175e2684cd8a300393b8ae20372d1269c5e45c61e8c4cc0486293d1381dac765f7d7a2adfdbc162d5fdb8ad6ea53dfac9939a3151c39060e1d34997ffc8ac01c1b069000299a880cf3ffcf32c93b18c55de1780c86ee972df0022719e6eed0bf61c46ba594d0904799b37433f3b2c5ddb6cf423200ea59b0c6241d7c2347f78fbd706e00ebd16e0eeb462b07f645581f4b7719f9ff2a6b710620090fd5a169d2f5c9856015eb3281bcdd504c0c871988bb1152dce5af9e2642cca3f8477970db55850bd462ea31f000d543da8f48c6334e4f096edba137eaa161abb44d6833c3c57eb61e80c7ed25102f285be0e1313fe51b6afc8eb5675b758b65726c18df08bbcef42ffc6e8e994a8d1d7c73566d331659ae5ad4b954a8aac648c76d4a2ecfa82862ca324305474526c50f361640010d20c36925a653a88b6267ca8be1bbe32d6503d382d0a51f6aa89ba2c2d1b74a3083cf0dcb602ccd22b9a367adf54e468967484123b6d3aa9d5304e813482b22e8e6134569589dadf6b4f27fe7049b0e51dc9a09cd85951c9576ab5da0d34df19b321440da8f1b5a91954fe6cfe940cb0fa8db84a472fdebe1a50c1f778824abdb69b6ec6b8f3c0b805f208c22366a0de99afdfa2123e74c252ae2a53c22d52c8321acac5c6a44db98e957cb776dd560d36346394fbb611b223421ceb17901345a555560bdabe9ff2f1ce90efa1db64f7d1b2fb88a84a3a5c2b041db436af519db8647e7581ec29a66857d7d862248c1e8ae1eb70c745ce2ae117ee8b433116318986e63fa5f8f5066da6f2c587fe39551ce081d7fce4ca9a20a813813be898b6c072748861977c95c51f8f49b5ce6ec7a11479b5facec6ad030f6fda830850fbe46e235b5d39f2b0d9784361040ab1a1a92f0c99aeb3cec24c5eef0b48e15140e3ebcd1856b7f792c42390c5a6ce9f6e05e0cdfddc3e0919a31403d8523fb4f884f935c2b341a15dcdd4e8b01c1c926e1911e7cbe034c382d47fdbe5e1fe60030aa2a54791748284546c39f1343859b4d4748104a06cff1966a52a96cfa17ef272943566a5ae69bc45869662757e68f3c82a94330bae4f81ec11f69b50ca2d6d3f9eaa679a80e80f465679d690d51568b296d9467b506cec0251d5a8d0a83e4e11682f13bdbd4a3d8c317882f267019bd36e03928a9673101f8a7c157e954937c0139b986f748a4c5083bbf60d1e85f7511ac677890b04432a0fb30d322615f4e2b549c156817646a76bef66fa18d35396625f62c03f774d33bddb4b37a15332be4b220b6fd17071bf190428dc4b5774cd8c3b7c43ba66a6ee67eb42ab77497f0e1f12435e2f90f1d33fd2bf3cff000d6d9111466e67ff26b2d76233810f983ef589a20b134fe9bdf231e490402224507486855c6c8ede59141354fb10fa9e786deeae3d93a608717eb462205e30736b8909af472b8e5d0aa0bc9a55da593f1a4a0889f0caf869231c769652065a73f77c06fd74aebdd0aa58a0875ceac6edf1bc9248a08b30d06933d33a6aa883ac2b44d0db3fe46aae862feb5bfc197ef1f4395b8845ee1b3b8067199ed12e34b4961b68e21fc899ff028663169961cc496d419ee888c52e45c2c07f58a56e2dc44bf33bac7ca1cf7389614debf2b4259153052d83bd572d01742e06ec9ca23e2566716dc282581b5dd64a0b98a1bc4beb98b4266eda4c2257cf42f309f83f60a2be3bba9df29fde3ea9cfbeca88dc58aadd716088cbb7065a16b2c764a3e4e71b72ab3e01ea5152b3616330d11ca6a83e555ebd2662bce6a2cf061f468fe2b068b19c4a187562c2bbd0622307d6b2cf006fd98c4ff22fa36e0c298ed946cf9920a430df3f35b046d0544bde2b21fb9416e87316dd20ba157b8f63ee35f01065d19080fe0489365d838d9fabb692d017246a20b8bc0e0ee947b2f57a84026e650637599a78f22502837062ba10ad168ee1a99838fa4bd2b59e8ad6fb2298dcd104dc7d01be2737bbbb835bac9c221553a2c9256446f393469d9d0ae3eb48570d9933865c246fcd5ad73e8993d059cd379bd91fe358c051d1700df621ab0a183d976c3752526386035fe2cce2630d05b39af73aad46ab1f153617bfbf336afb77c9e8ed2b13787edc665a7917dd2b914e4a2b4c6a32c598c1b8b0eb477cce570427c789e874b86185daff150d8c60f6d9d5d995b0b84a4b989c0dba50f9ce39e64db11706e1cdf6a715d65099b94b42b7c1c4b421e1c542eec5a0ce306337641bd7ea26ecd796aafa3fdb3957fac69a54645b177c014cfe60a4f26aca750982d9167041707b162b127849cad20367b28e26ec35c905345443b29d63a097875d9571f00db1d10c7f1525ca8e319f8467350ad147936f5c48de7242058b98210e15ff50dc8f626c67a9cd824cc1b58ead4d4c8811a1e78b294cc7a7d795007835a552cf6133a3fb1c98dffd68cc0478ec07a244a5db73fc5ec5a30d08f4f706c7a0ce75c455b77d36987d608a9e4ff2c55425fb77bedd59c8eeb3eb3f9364d7111cec7782bc3db08a54ff40c6e9c66f4abcc7f80ed650ccce8f10423b86fbc21b13a4a64b28211c1e66f7b437a2b34ab68e4ecd32f2302a085e4dc5c480a7b64dcb017976a227d0f1272e5ae6ce5a27bfb325664236678c34fe486639e7b6250432aa39380bcf077f7ad708dfaea88a815f9b9d1aada247d8da4f77cf998910925496cdd3efd02f302de6a1802c4e4deca88333a7594be883ef57a97e7ffb9ed23a9255071a3ef586873cde54a310728d6f9aa9be33eaf809807ba5cd0030a9fa2845b3092b24a07ca0127e063ae6c8d369a35f26ca411df7492d962d008c0b9362efe3527dab45512e13c63ae808d3138ad9ee6fbbf872a02a1658dc9c927e63498df73f3494381914028c843300e2c428b2811d972ef2da59449262903db07ea07c908bf62e5a59d67e2d5b6ec174aa0a0c5040777af1796e9dc58d2c98c30a3cba852a329de0d1184d062c40d5fe26e67b4547b6d70515eedcc0d4c54f8c175875be4f81d842d1b34545bc516b7c8f46a5b689020a9b672645282f97302a156faf06d5629a534c8a554ca39e95c452999bb942fa59c52ce39a764b5404eaae9e8f76aa9d0951ec9801e6d78eeee8eba59a5c2a856051e549b7222542f2cb33c7098c1e3e8e8e8e8881edda38bc2119384032e7008f55097b20bb3574a29edb61369e2ced5da69b55abecac212409629fa3397522ac6a575ce39a507f294adf990704a5f11c1927266524a89fdccb6cef4c527cff72bcbb22c3970fd6343f27cef8139ca6760e4d55a61eff39aba81def7efe67ecef5f4af97539f3ef6722617afa7ad883dfddd6c9490053081ec52eb71b30d20a73cb3376dd394e5d76d08cd5886bb10b2ecb27f0f9ae7d33c7dcc3cb1cfeb92312c5f0dac1022404e97f46a19c4bf94e7b521ec2dba27ec974daf4b4ab7d3351d943aac9a8efe884ac94828faa1bf8cb2ff757bc323d5522925adb5594128518dba93dcadb528540376e25b4acaeea82fae7bec52b7282665563071829a641491aaadf2275cdd7009a7acf55e5aaf2bcf6879f2c9274d40bd9af835405c58edd5f244284bfd9bcbddbd6fcce6f589ef7d395eadd794ecd8050e6bf556db49a18b6a776cf62b164e165e6d0aa7212842780ad96790f9ac745e98e4e2b3629792baad94686bb664cbb7953f015f4eef6951d6fe08a7ecfe3e93dd61b45c3769d60413e23f9af8f23448bc79c118c04010de95947f34490c853a884357a150aa8335d88b9a917152461733d136dd32bd4ad93fa594524a085f42c7edd65ed41717faa4103e28e68479be0d1ba853d891dae9d047ec4229cc127b07a1a1a480e386cccb0c4e3d2a8307a210ffc6bf2fd5c688459ff11d33b39e50e0c74ba2495eed51ee9f4c2851f1bc7a9442ba4bf9644cbfe88f7fccb3cb8c3104557b294d5b11ccf459966d93939c73916b0e72da7c9a8f17122270c555f9780122ff4aaca22f67b0fab82fe7dd464004021f7e77e57488535ea509dc7d957db2d013f304643fc1b77773dfdd3ac599a6ae5a134cb8f0cfab893f629c49393accd22d9c4bb4942d1d768be146b4ae5067547bb7b828e910ee905db463bddcd3e9bef4b0ea55ddafcb8429591ec455270b47df6842a686a5ead451610906cedab93e64ce28e6d778738151a7d7eab5b51d0bc8efd5d4af9e678e49a75f26ac399b3a9e73c64c42adc7cb775a9dd2f953fa0095823f259cdf5206a2503232d55e59e274522add7ffa805db2a35232318bd54c2ff7946116ca96d37d316936c357adf77a4baf53429948c839e79452bed75417cfab7bd1a7663f8412b68cb4a9d84b948c0d21544a66897cdf62a0eff3232494fdaaf86573caef21b374d99ea34b972e9ebd57591a21b1ec654aceebd220989d6eefa99473d299cabe02a357695dbd6e29646a00538898926a02bbacc6e2f276855d17cb59ffc2d349a9ac1a60b53c8cea5e234c0ca5f459f1e63efd98ad562cb7d6f7aebdd9c5fc5d927ef66aab90f9d2a54b973a6462ed585c6b51d57ef7a99e0da586bda9542ab55560b31745a506b618bfa82814c513cba47d7f771d3c9b521f2a31067a15a1af7e64f93acfdf71f2d2a4417738acee61dab68e0a6da3f53b2a23c35db53027dcbd560b27775785b792bf635b98d77aefd4a9b276adf5df0bff8e4c3f3829e31d65c77ee1cca2d6ef6896334b99a58c59ca872fc7f4f2fbe5682f3ff572e895ce14bf20993eac996fdae0ab99af6dfd6ae6db2dc3aef9755219ea8c5f2d95124eaddd09da03bbdeb7895d4ad419f761d95bc97ff1c95e2586b12c4b0e642ccb2158f6297b508e5d87e72e1ffac05bab5b982ba821ae7f3f7f39a7bb2d4156694d597ab3abfea45442c98a4fbcbad7f8cef83ae5e63146d3c4ac66bd632cd3d789d4ab7514924a34b37267b1b2fc991b5c665637762cee2a66dab44d8901b40892831b64696675a3875535c022923454292d465f588da36db20903833be7b6b2b84b6954f270c04bc69e15a3093fcdae7e649bbf95c42eea137ba4543eac1ac07902adbfeb612f938295e1ab639c9b570b553e80ac2096a1c1ab4f29a59c737ee7b9da9b74515eed157abb796dcf979bcf4f963e51cba490ce7366b973da682fe15b51979a8eda5a867dccc77ce27ad5219dbd575786a1542f0ca7672506ce4de1fce70e27caf3ea2ef4fc4929e5acb68abdcfab10e943a416f0797d815b641b45ee16b9832f49d089d6e21aaf267ed472e1c7244fc5d8c53572d4e13680420908b7903fd47aabe4f85dcfdd52edad82d2c1859fca6fef83f282c3135b3c2810490ede7a3d3259ca205c295ff49abac141879299896204495c261ae12ffd6f4effee1efd5dbac026f5a57f5e3fb253207bb3a48f8dbebd5b207845e1ade8cdbd58af267e086350dc9d90e37bb5ab11a27ca1445d65a524aaad3555efbd3d378c6a2f0a95a272eff3a8648b2d64acb55726f56ae2a36cd4602f093a5256dcce2dcaebeb00e1c75496eaeeeec1ed8673abb8e5f189468245cf90e1773d3d43eeee72bb21164774d0b3a9a183a42ae1f33cfc1d0c611a173edcf5f873c224bf7f2d1f3e1f889279b14d1d506e1c0467713b8b3b54df542ebe8cbd2e24454aad51d321f36ae2c7540afadf94141795d2e1037309af267e0c9d3b19195cc5edeaed6a5f4e7f1fe17701fec3401868094f04822fb12abec7ed7bf539b63c9afefe2fba5d8efc027c55bc91a63702dce07eee72308088dbe5c81d6dea88e489a19096858a22eb3ee351b0e4cea3283d28837e0d898aa1ac7d265bf0a17e0cfe3eb0cbcfb40d663f422df946df5c4a5efe7af9685471b76571c767edfd7d608f4d686f88cf4baeffbe75d1281a4549bab214b90c194152841328ad2a58daa6737cd7d2365d6489f6373cb7c43f368173e6805a63d8f1f2f53b60f6ceade978af005de643f30194b38f4db48df6f135dcb58fe913e49a0fff0bd7eced06b38fe8a4571a8e4df44a6af78adbc526ef9b18027307eb06331547e08bb225377c0cfbc0d88413afe67984d20165ff178d6e48b95d6c92e3c7266de324362185aa92c7d3368dd4bda761e3ee01852208e0f51d5cb170e4a4af36847f2479c8688413d27b3314ec54dbbc4c9c120dff1d88a0102ca2650b962c55945a4829402972312c045fcb162c59aab452b71a690c0c8345fcf0589df231ec319e8c5df2eb0f32c9121c9ac9988cbdbd4326e3b6911782b40df657af7a7edac6b197b1f797310cb7932d5cb22c295d414a3a8a029b9cc4b8d785bb6e92553d88640c17e523bdeac14d9269b81836d2ab78c44f59a291f88314924532fcbf5082f4482985e4906bd9b2cad86727242ef670909e0a4397ca5ab864882567c959dc4eee90e17b15a5f74eafe2fc7a55e54a0b09ca9193268a60822409922223478cfce0433b3811975e5d18db320cc3b08745328c4b19462d36904e51034ac65e36049edcd72477f14af6737eff40addd56908fc9c75690f281c8c71e834cdc873445932c1ffb296a34c93060c9fe2fb4cd9b728652767f59b2bf096d2e0057ef050bbc1a7f0838713b96779f6baa5a6c933f371df3e30664fe7c0ceb81e10efbf932fec440b0971f9fe236d22b7fd946765efa87f9982b797920d8f7915eb9f0f2524db87bcde28e35f10bfe3faadc975f86197e1be91f1a49096b486114c5263da428a2e4f8f5ba4ea71146d83a967c3743ecaf267e4a07b77f473e864018b77e0320a0743104b480af94e4b39757d33cb2d759f6de7befbdf75e8bc78d18638431462e11462cb2d73618969334c93939fbcc6d46647baf46734d874fe7ba754159eb361094b387df5df6f16d8dc59df6b44b972e6b64f81a108887c0fc18866b97bd7ceda1c6424ecef07b351aeeb08f5dfd0a25fb639f656d61fd88ad50b10b670fcae03e241b2065fffa36b892fdada63dd6232763d9d7b7f55de598fd0c77adbd863b98b32eebeac70d484f4ec6b0067232f6187eaf267e8cf582ff904885728dac7328c2c2882636f2438262e461914496ea0416463829038b24c6382d81a9e0941f12142058f54a8c6775add83a1add3fa577470c21cc6ebc8111165df8acc8debb89fd10dffb123ba8a104b21df1facb95fb8e5b7b35f02d9cb9c772e1f6458bb2d7ad8dfd1e3d4a77e91dab401cbdaf8adf4b7c2daa573d29e932f7a49a0c0977e0783550da4c8fb1d2d883550ebbadcd4cd5d94939e786dad9c1d2faf3bb7afd97ebce0eb743f9a0e14eef3cdbc88e7b6cd334babb5b48ccfd56bc748b72eba89b8a53ca29bde3169225e9854020b63b486ef7d93f9b691bb7b0573633107773f6a0327454b5b787e53cb84dafc88059f6705761cedc6c86b006f51dea7a8695c27f327696f92094737e67279d7462219de7933f6fafa095120601d66cfd3481216497b2bdea24beb6a65cba37945964591624c7963fb3e7ddc19ffefd8e85788634cce47abdf7170632bfc7965b31c5efe14bdcf3a0f410b627cfce24fd2cd2bfbc620829a55ba53be843e1bd02484971cb2b039172eb4165597bd563b3c8fcdf9b1357ef183bd8b0e17baffaca5215b18c6aef948bf26a675a314226b28e107abfe3e8f168c95e297b09c91bb6b23bb1286b1b8bc7a148e324de64ef383ae9a51be250bc8943350ecd38d42650497592bda85eea2b2608a29796b47861a8e08557eb6aa050d3bda78e0aa84aad663255fab088abd92adfe5754a8a4ac9d025747503895c628616cbeb8c2c1c26edba4124f6d794d3a55f11b2f6fa8b327bb34e4ff76546b3d98d77938a34d1a662178d62638679c217a74c9acd287651eca202d061267914ad89961851b250ada1560783a6ca40abf3602dce09345b66af9733b1d49aba56ab02140033e00804f451b5b2f29fe8d55e2d2ecaabc5d18252364b88319e5725affea4b8b94114a2219c94460abba13c08db75d89fac164caf96a6e04d3a6308247477772aa4b35c3fdf219557a5754a19825a5f8d702e65ee98bbfb4ebc527eac3a5156ca2a72bdba5bebbe0295d85970e1eb44aff6ad71e77bb556ec7d5e9da5049542d158fda19cd3abf4c8030ae5feee2edda9f44b52e93f7148c37e71baa623252387c416017a20400f5ead1f65e1fe2c16f63eaf3db82fb5d62afdc724e19332c3a451149e8219adfa729ba9b8c261616171a6ed8447233f013b345b4f60a15620fbc3cd696df9a4aeb28c58fc79cd3aeb9474522ae5944217754aa594524a4a29b537bbd8adb506b9fc290a8cbc5a2af23dc93c672f317a8c110bf1e12f5f7a3483e5b5dd5ef16a676b373bf06a3bcbab2deb856556db11327970e77bb548f63eaf3168498f3f98cf5fad172e52a47e0d3a4242373c475ff54a370b0f10bfdb5a6b75e059462827ee01dfe14b88c3d072e77bb557d8fbbce218c9410e9cc85e082184288bf2c248a6b18990209a9e271642b37c48b3bb1053cac7c5f34ab31ff106f5d825592f38302cb8d89ca86fa5b44b665eaf0d72a72d5b91e511d91fca1a6c8f3b6ddba539214b16fc2b3027962b8b12242a16ad6b13cf3d35c68d349166a6ea1274a7eeee90884ad3abd0abcc6a41224d0b8d1782c49b2b976e2af5012db4f550d733783948e2cd4bea4229a59c73fe3cc1e0f76828ae3038ee8008690743485a2821593942d222a9c8c599cd7020f3853bc804167df73c2231b596e42a23089e1617172cf181346820220d248e2869811431aca8c0bed42782bda8140b07479106858806f882cc08421c3829c0294896e00d7eb094fbebcd6f0a12a54cf39b82848a960cc9154b208db184075d70e0bacf700727de38074496d285162e5c2cd1828883568048e20524f00287308ce0a0166354e182055480d08208195c9bdf142a50e4eee629548c64975bf39b42c5099dd291b03441b272940190df142a3d4ca1c2039523b29523467e70c319527e5061931bd280d29a820748504cd172840bed99174588182c71418ea5062d0c2e885573941e488084eb0d66065cd6363003290a212e08e6600c17603103022ea8041ac097c9817bb8a110a3881097d383144546425ce6b13d9a70f8c00c4eb8de485882cb241823b0010a1744a51089400617c4eaed47003f7041afb5c560043330c105d927a070fd31ce400639b8c20565671cc1f547fc036780849224b820cd8631b8c6f44d1f5a5088b8de04f0031714616791bd78f3d368a08194c4fdfc04bd1d1c514488f30fcace5832e27efce5fffc0451252b4538ffa0192c4170f283ec096e50829bfff394a4e07e8262c4e07e265e025fe225fd412817708e97c47f1f14e105cc28f201fd7a31aa6d24edad6375f5259b15bbf022b63dacaa015606d2117b902472b56f91bd782382185b08915046d252d294a51da690617403a52e493fd7121a94b8a0f7c4123a90817201143ca4a088cb22d192235ce64eb0605202182419e27a6335e11e165ee0a005d9cbddcdaf84d74a4111475c066160c41097b525c2e8499524489e5c395204450453b4b86c4ec144042daa240726399080cb10975d573c192a9a6288cbb22ba088b185cb6c15344831830b42b5b8d708e864948888b8cc74c5134070e1b2972753cc50c465b70a132841c4652725b61ce1329827474c29e2b2182078201aa208212eb361c3133e180a81861f9cb124828d5bdb00a54889eb8d65c4652929671071d9083d50a1c46524583144e43c30c1a18823ae3788a4c80c4a8509204831e27a8340c8e0092e2be10a2b454f4c2005132e33e16f60c28922ae37191d70410ddd04edad179471847b4f6090434b460ab47153412a4c88e008f7b230038911a7f27f5548b10225eeb598584112d79b0abe8a069cea0a97c523425c6f389470198c0da369a657f07dd8018b1117bb304388238a430f465c506fd862c4ca9554448716604048e27a7b2728e121091e70bd9d8c10610026ac504308aeb71314455ca6d9b8bd333eb054f4248b505103b1058c25ae37150db8135860c411d7db3ba1088c21aeb78703101c6971bde13882ab811768b4b8de64a470bec10c7740050a25ae379c2a5c16c229841838050862b0c4f50643a00347040675c72ed915f76df6fb673e3b62de71e30497e742145a28475c82940e8747bc49354efc2bf428d037379a06720151b8927d43f5ea6fb03aa3584e8e1871031f5e20450b17fffb458bdba172d4fc5b5be1467e18460513ef9859e2f76a8088724f2f3da071902c45f05e0a4227f0e183eedfa564fec6028fa64510e1ca2d30f06e66525cae9699226cba39c711ff0df7655a61608ce26d3b5e0d937b91266e2fb3921c4adcaeab746beb24108decfd9bc9722871fbdfd682e4aad420b924ce45ac7aaf26c6aed2495e0d7c0da58ff07b213825ab4498e48aebbfec52b840c60bf35dcf6b65d9fdacc63c6377c6defe7b3970bee963c45d7dadeb21c2a46e4498e4a7adf072aeec7d1c0f19215fb07ecc3c8bf19f9fd5ffac629f0b8542a15028144a013eb8f04f30db6993fff2cd5eb22ccbb29898ec8a898989c9ae8c849ed78a89898941a15028140a8542c5c4c4c4c4c4c4c47c500c0a8542a1502894027c705bdadf784384899298ef181cf45adc1298864122b340e4c7ad8b5d64cc5e5e5ececb8bc9f4724c264d7b399af672aab52fa7e6641986bd1c0c7b3533e7ba5ecdfcfa726a7d35f3e9cba93994cef972e694f2e548f96aa647f872b0f8f1e5c4571363bf9c36cdaf97e97a1f37d5c7361fff0d00c12effae5e15fb7cc51efb0b4b018a1b6dc4b55756fef57603f22294258e7f0591f2af9756fe55e34f91d7a5063b20e30769a8b14617eef435406e88723610e14ef8e12efef53a314eacdbf1b20f8db66a3a3cc3b6b8ad60374024c7aff57dae68fa2ed6384f5f4f78d61ce369621f135692c3e9de7befbdf79e4ea7d3e974fa1b70b8d3079df08d34f0de7b5fa75380e2ce7ff7743a9d4ea7d3bdf7ced71e4208ff693c5e7eef4687bd7d6deb82646b3720fdaa1e578edf43f39098e35f11b8e25e0fbbe4ae3e864d16e64fdc5db8ab425c55b36727742892e157241f3892e1bbe6e3453c24031d91ac019ae713c9adf5304121212121950f070c819962558f9afd7ba863872f1d0210b2da140311e216087d7f1ff99d0cb9e221236cd7755dd7857d260939a2b8efd18afd46573185f2b7adab4f6b86efd17414fb4cac04c718c017438992f852ca88ab6c8f31e277376f54f647a5a67c331ed748814da37e8c9f7df62095fba2c0602893905f941764995348f6b557f5e343391383140273632f193e1b2d85a7ef26156966fd3c3f859f26ac6d291c88bb1873c4c95f9f840834516b6d9b09f3f3faf7528028e0bc02cc9f9dbb14f2fc54bc81c13a3875f1c5d534b5894d8b31d02ba9b1f019e29ec75db8ab54842eee84b9b75a6b9d6dbb7e39e70cd2363a92d639e79c736633cb66ad55e7e5c4fce4556b9015945cf837727075200a30cf57218890b6a93f7157e7552b8544579b96f8b793dc8fc9e0287f9e12851884605f7be5032863df5bf68dbb2d86fad7d34d08cc34bbf1650412a1648d852dcfdf893295e5cb77268890e3cbc767333fdebf1f9fbe7cc4dd755dd7a75e8dfc930aba07c5be10193ab0d39990e1842ab48d0ae64d3f5fc2601fab0cf330f846afb43fbdfc067cafb4d786d45c3b06986fcab4759e356c7764d8aff46eff06d26f1d060db9d336f2539bbfbeb76dd470310cdf5ec9a7313fd933c078b3235718e2c2bf9183dbbd14440166297f87e765779e87c0d70151a74fdadd7a5259fb974d65bf667bf5ea7a6d53598c815e5dff72cfedd5bb92af9a1fd657cb210a3d0455b5bae07fc2404b8080eec77f2be458e3ced3fbbb70615555df6afdf1d7587b11af17702a72c373f1879e3bddc834cdf702fce590842a2a70256dbc6cd9b2e595529e7e0876712f871d4d4a4278a8b9d05c08781569e4fba6c3e2b1c90070b90d8ff4ff8837301ff3f2619041661343dc41a28c7f96c0ffb91ff14ffc7be92665a6ffb8e85f7d035a02fff410f3c4bfd757a0f821bc6f4036b20cda9e9f1b10f874ee14799186666ecfc6b6842762d5f5f16d7c0858357f03525d58059f874735fd437817e2db78ff101e7e0836207c6c7e96bdcff5f67bf40a19ce7e3e84d835ebd69392b3ab72550013dc177ef44af64a6e2fc4937c91daf6b898ed7130dbe34c44847ed434916fab980e51a0f9fd9cfe31c71ad7fff440f1eff43f3d8f63957c7f55fdd3fb9f1ec33c11abe4ab5a38bd3f4ffcfbd967a7edc5bbc1909fb62306ece9ab7a74a6ef63fa97efd119fb17bc42ca6e8fbbdbe334d3e60366ecb5ad2795b1aff99af30f00c6ed8f56646fa612b93ec33f3f447ef52af9980cefc2059461957c8e935bddee6cbd301f86f93bf37f4c099fa77e56c907eaefbf206e217e7d9ef8f5e5032d9198a79f3e5074cc43b1ce03553c9fcb41c6952f045b5ab1810837bfdf06229c54b9fcfa3c723ec53ff0a75f4a16ceafaeac38bf7a5c6b91238ddbbfa97c3e4fff7c57490cbfbacafb715387070bc7274b87070ba71f7e1c41461f6a3b14ab76e484f45f98ef2d0440cbfdf172b40c43d27dd8b5e28d1569fc67dc78441a7f999aa1e1d61feeb115d7a0ffeabb009f62a0ebe1570cb48407e8a5fe85fa44b8f830f4c3e781f02bfeb91e62d5fb81dffd44b8da04b841fc1f3a3c54ef85f0549855ef8196f803f5d7075a32310f7df840f5fbaf4df5b04ae216faebf3f457cc039f3e10c5ac1c40602dc920b2fe2caee48d082d2121a11938c883a788faaa7c5165658dbee892bb67f44594dcbd289e39ef47461619feed6a86331946a2eed6444872fb9d28b390a3d2e5440422a79225ade1e4024a9265890c2bcc68c285833c0c7981c609a45092822394b8173b641492174532cc2f278d7b03cfbc24713bcbca7f637f346596bf27330c219944a22a464b52889861889828fd99d632436d87bbbb9472851d33be688a3bdc754cf86a1e7eafe69d20c57d48579ac81deae52619feccea46c3d6fddc3d0b3ece4d0d463eb0840f4cb2604247d2932e46e0c04319495c8e1a37bebf4c0ff73d8abbf75ec68fefbd175f743168986204263a00a35585151aa6a8f385d42c3fe9c70bf1c6be0b59661f287bdcfdc73dbbd548801bc88746f2e1917c4cee60f146f51efbc7496a32bd3c8681b07fc1ee1017002dd7e8e5dc2c1f1eb54d4b83ab192e8c0287b27c09956409a1c81f32f46bff38a96aac6ae174d2f08d799807baf27150c9cbd9d243b26a3a5e2ad2c89735e2eee224550bf74fff23e6615ea7b51d2a2697e66dccffc8bfff308f06b73c11ae1ff2907e372caaf7a725d5c3aa16ee6bcfa3e19f250ff3687fc249506adbe38c228d84bfe3e51852afa6ffb4d2b6b765d06a9b8ac7f4da9bb086efa6e2d1febe76312b3f8e0e0e0cbd7aff6897358456685cc211d73fbebc94a6aff5627946f2ef3777f14f1087bd49db783c9a87b3690f700ec39d8d3022b24dde0b88ffe67777a669e6b37a01fd1366d90d21eee3b06aa7be8a2753d22f94fd4c692d3c2e005aae0c2f47cbf3a1d0cb199a708b3f184d4aec3fcd85e62cc689343b9b4efc116188383342b77b5b324e856f42ed00309f046e890be77c135e8efcf90078391e9760cb231944a1857adac66f9e120fb75f5353e29c6d91d3b6bbcd9fdf35de6091dbcd0f865ecdcf41c67d59b553e4fafaa70cbb88697ed45646ee4fdb74af0a19daa6630999f62d9e0f434f4fe8244fc824cf22fce6d45431a85a30bd7d1e937d1e15c52a09646f7a1e8c3ef6a637e11f229cf63ba67fdccf67b1f072609e2f5f6a3ae48c3473bedd6a9adc1fbd9a2ff14eafe6e3d8e1367d9a8e0cab2416f916ff40244438c78ea81cab5ac8b2c7de2dfe09f2e2fc0c13e188703a7660883453e99e70c5351a755f2ae81c24ada4032b8caac8416809bd32144514ada229559e706184c5c50e193e8e14bad882c3ea6229c3c7914286aa9d17697cdb3ed2ccef82283f31f243e22209cc8eb6c39453af06be0066b8ff020b4e126c86b8efdf4bede83f000bfe5337ef08891a40586305581061c1c1e7019f051f27feeb58f67b5859fadc3a6834ebcfcf121efb633f688908121a9d48379f9fc7c9ed659fd8c3ca8deb5b9a53261860cc0ff8c088152c21e20a1296071419a24b193618010a76180109152b4ca85072a28b150c891d7c0002113a18a14405078568d23aa2061a6cd1032125f0ca8204a12221a4a42f949070a00452522b8b0b49a9480b129724468084193e2081153f6021b2c20a2b7610c9f44f10abbc35ffb7c1fce4ce8d34f2a12ca2932499aa16e2d777a1ff52b5d01f9fa73f7613d58a7ba88fbc1af96f93b91569248aca4df54a92e0c3854778b0ffe9c73024d221a97835f23312018c5c988461ab5712070e6e67e5bf1919db6d9816d2bc1af8a88eddab5723d34929e59572ceee5019c68f714ed8c4abb1717f3edf5708a3bf86f3755a6e7006af264624453146a218e5c46fce984ac59731c6fa85951faa0421672f6f269a1010c4ed9a684b07b564086de00ecff1c58519e64f3fbffff43a0db770f991e3c3d3c3e0d306b5b44d5ce554510849adc591fc90b41842b232467e3e2dd476585ca5114d939fc38bdbc1233edcec7900b1c8b492da263ea44a57a011e7c300ad3dcc14a5f930409e0df38c568eac18c5efd819b66fb242240db27f3469b8897a05bf89da080db24e6f01a438a8f4ed573439e8d0cc000000004000f314000018100a05c341b1784c26289ade3b14000d7c98486c52194b44599003314a21639031840000008008c0084d6d144000d297fcdd9f685d7ad3f019449d5ce087b404118f2ee5bea739dbbb9384518401c443e7590b026979b9e80c1819a6a4186f05715789eaf8032accf12570201605e068b89a29be0354469f4291daf82d1798b50acfc3207ad4c1099f1a07c649ebc74bf70d1ec07f66439b0e24cdcba1e550be9fc0b4ad8d8852b13fb3eee083106be3fad5e10efcdb087618fd8e89cf234f4d4440c524722e8bc064c623787894cc0a44c780ec2480ad0d1a3614a4f6d76e2d1e27ab0faa5800c1be9750f0d9c43d698c7f2d36f85914c364bf15333eca09173fc910e0979a93d4ccdd9ab6553e691234e5d0a760690c667a89462570aa03d7e989691ec3b168c7cd20617c884e6bbf6fd9e395369114c395997716ec8b42c29e4a352cb33a48216b75333fe2440e77698947ca9b15aa7199c5a156339fd5eae6588b152c1bba776274c5d8e081bbebc519417e87515066547a5df6bb9a570d37f62180fbb838e14807166e44aaf9709e83562374033901f9e2da695c6d9422742de1592b0f5e8612548d40d95f772b0a5c0a2fd882b56ec333b889813062f8ae10074c909effd8dd19548261c50d1cb7593c1e181f15ac73ff08e5b45a42345c1036489618c2f94f784bb35225fdda00bf7e0414d62b7429f82fa4852cb40849c6a5db3038515aae14b6a21f2e76435793185205faa05033926f66915aef3489b98ca9e5e813f43a2f0addbca9fe2c05573434a0340b95de74aadb6f0aac5bc44c661bf9049d25df6e69f1a7c1f736fe55b8b2fe91582da0b8592bd9444f0dd1e88193ef63b5ca185c824f4132a349dbd0460ef9057003b0430d6e2fd2496e0f8d8feff2bb36002d13313023af234500fea7565d05205668f304f4c37c3881d15b9a25fb4ee260f2bb253ba844486880731ba1e088d2bcf60305d561a03917678e08749149b909aad47c3e20216f8e00a183aa44e653057a11b83ec36fb7766a769e11fe3d7f7b98c17eb66c660d9a0e687ef5c0971d96e29f5122d90c8072c523265284b2485b007e0591463da1ec710cf620e3ee834e5d6d47710c43a258e2978ae0e1beeb77ff9e941a3e902c1b18885c658410e9f35b6a838e392f5760b05a2d5a6d94d6ab2034f6c17215b60fee55d473728206750f7b011eabd44bb53e1494cb5c80f24bb53af45d07a782eb07f4b36dc043964e000ad70009217d50f43ae39407b708f4b9e47ecf1420dcf9e4cb4e04bb6061fb06ca04955e0f117a85e38eaadef2d36b630451875f37dcc35ebf2e285fa704a392e031ff6615fe3c817df1c0f6814ec57e860cd750819617fac370bef6e4f608522e3d62489e1c03ce85b25ca447fbfb416807f8e44c7b174ad51b7366b8e022573cac97572c04e373ac3e1f1d5b2b3882b7a3bdbfbc2ecd8e786ecb8b3d66a7625fb7299ff260396956c1f1198acb2519dd653b6420b5ff4aef8e7e195e7ea0349544adda9b83a343080aa6589e75130558e0c4c85d978afa26ccda601325af88aee9ffe458cd4ff4115e510f29f5e0b11f5cf82d23509891bb1d237cfb3966d3564e5cf1dd2e8128837ea60af471945c17654460292c89cc9d81f90de1b832312e9c6b3d87f855530b7dca88fbacefdda855bbc23eb95da85cbcaaeab3fd5d3a1a438be64ac933889e4289c6a5f1cfb5eee7ce76a0e915fb6f908bff77ae3a14d7dcee829d02614c41a5240991fe24d63a0e788cd2985d59cd82c052cc781e254b717f80327eeea247a24aabb1924e6f48608a3e4cae6ab69a9852704d6ddc1b6cb1260b1bd7f2b9ac2ae2459ec6d68888712cb75a475eb3155562c610a8cff66e8d051e427969a9657b3a2c90d11e0ee287a40c97830848f85d026509ca09408b2b4ec33315eba36672234c963eb104a4f13a91961fbe6346fd3e578e67d6ec7d4f080eea91d18e7f7d1ec557d4106b44634b6530e93d86a9e7d290abd22cd85fe6c02c71f0f2cb00ea0a3b802f107210c2803235af5994c831c97440974a295d4b480748313fdfc59eb825645726d4a452e09e97cc1c3c270823a9e8bd17340bee20e3bcc7d06df209dd4f3c8e8eeb7bd8a859365070693f095f3d925a355b40deaa113a52aaa2eb732698d37cbdc0b580b8463d69d5544880050655bac9e13b5a42a286e79ca99550cca58b925416013c0a084c61c690ffd837ad36f3e0332151e1bf7ec533e4ce97d7968101ffc129f818bccce918138c5b1746fea04d03d6c8cf4fd7b535b43ac164c3fc0f1c5aa21cc158bf03b1917b4ec8785abd0614cf9343fcf2be3ad2e37ab1a5548d75969f13f05849b7bb6760d311c0fa13593bb44c17c3cecdb101660304169da4161fc1fe71d1216eed8cb405602c3cab5d3683c69c00222de9f2b1deba46225372a9d34ed713849039642d7b1d12771d9e09d6edddf55d217190b4f9016b20e3e8ccbbb8969707ea16fbd4869922743a71e264d011789ddb5b309151c166e40ca07096682ebc716d1f15538bf0c796307f33181647854838e811b0bfe0dc742786e7c331bca52d347bea282b3243c5d114970aaf4391dce67489c95da90575bda2e8be422a7b68169725247683fe4d6be2d2713d71052d0d5c6d87117c6fc8a3884121ba2b15fd74dbdab381065047d080f9baed169a9b4e7fb16987071cc8706bcb7787a3b626a8ec1d222dd0108c8c2deefe259d607c5729f05dd97d2abc2ed7601b62b9f964e2fd4dac38d4604b121cc2d640910f31e8e38e4d64fc9842513e6e385ff769ae328d4e0229e11dbc9180a5c72706f9ec71c32534674e433bcaa5946d71190ac8e670d0919a0a51c2bb5b6d4654797d384bb38d63cbb733995ae58ce5ce40134114d2c43050dbcff009afb4ebefab830eb297f5952fd080f5b2e3ec4950bc7b094ff5b845968475d65864895e91a95745ea1924b8f52dd4d7983b9900a1219d2a0d7992fa4bf56d0aba7ac1c01b852e64bfaae8747f4d2c8276bb9ec9fcc2b72cd0b4d443cbe8c50ecaf31f99e9600830374f25c6113d4268c8028840f78281cbca2a3fbfd3ec689b0f80611df44e2476f76720590f1e0d5865d9618cb792adc19de768e693a449f62065d8e9b3896259bf6610825ddac2d4c2e4e6e06eef342c2e7318875b3909e9f237f17ea29135682329ad20b493381e8c03147d84ccd626cae2b74d49e208a11b0052e0312e39bae78da55c4a9039b28def56a0ebf791a474b293d6e358ef2cc1e4d8c0f1de1980f19f4691d47ed441780dfce823eb0d40065827e947452f0e8f18b5b26b071fc43842cfae238ee5aa0ee019eff551195761f1ae16f07df0cd41c69e778d0ccc93771fc3bb0548e6f0c0b86daf3cf74d5f4a12eb02a3611896a83480c56b21ca1509af25cdc464686e0d993624a27b206a07a50f6ab8876e135f51ed14256c014838c296dd9b93369e457cd29440e6b78450945d7d14aba3c1510aeb59d4ca2b967fcd90aa252219f9dbeedc63d024968abd601dd3f600491bd26f4447b718c0d690f909398e9cd39d3a03bd609962e596368864a76c0a83d8740fd0973e64a1526cd4d16dd106979012a1ee99eaa877dc0139ccd5a0a55f5dba610c80c2a029b3df435a909911c989e84a9a83ffb2f51277c133916d1cc7ad97f8d3a5bc3de3d5c2f4e1fe046e9ed2ffc8e2e0cf3f6e4ede21384f99e96cf65443e24d88c14574582751fe612da82af8b84996c2710791493949b625bc08171326650ece837ac9a6e5e84441fc54091759ff56b0a3fee5ceb3a5ad1abf058091c976c233ac80155ad009d75d03bc4eed91903f6864597b9a4e4736b6802cde9d6c2d0ba501f5a4d1572582803cd008dd3c76c26b3b66f90777b495c0f9cd5a0bf64af2e59c60c5507114ab53b1b108c0c66319020f9aa013624d49d6c279c99f98ec397d2c14b1e63b03d0088e6da4fc8d7757224f6a19fa841d1c461a52057e4aa344eb76ae10cc8a297967df54fb1b712aec3c3318f9517c6606f2908f25e25506625df043ecf05abfcb05997b59c4cf7ca5d0fb758fe1d4ae2acfe28e2056f7103c8e4b822b7e43be017871511554a0541670ceef9c07a15278714401b5a1221fb4675aa5ab041a8071fa4ed375163e619163f6e2c1f9854d12f4c070b5b2395217d7154400c23389dd2d1da612d2931f16f04de62663b11498f3b70866bae6e5740773729c9fdeab5ea94ef6f5683284843d2c0d9dc7b81d073d1761c3962a085eb0b76a85df0decf6ce274c8d19407c0032289c5327569fd0d6a664ded26f89544086c4f79dccfffde4edd96b26b68bcf0ea95fe7c456d05892accb837475444deccd61e40f6216593f705049c2e29f72b04f378c93c10adf45084045d01b71f72af7df743858d87a633cd254d35b66c4a2b4ca863564e93c48262d1c013f27b409ab00f7bfeb24ba7e85bc042b31542d3aa85ba1a5efb1d248c6e146a6a7d967c6882205784994930c048c4ab6135a6ac0d6daf1c914d9efa68ca09c0032a347663898f1e3e82e0f95dcb369787b06f8331224c6415ff5f5b8fdfea4287307e412b3f5d23b07ef9d2f462a8e5db5d153cfcc7234d46862e04f23a07d98ac68810c1771583f2eae208e3e421961639eeea7931ee477e388c7f105b8675ea6a8a7017e8e3f25d4f828dfc172f97e10e06498c7ffe6e06c89680d9c17a6d997ec4807f69d12e9210a247d5a68b51bb07c39e5cc758da3bc6088312e5eaa99189361a21fa9e9932f618fa9a399e102de108f3449b9d880261c7f8c31498552d4920f3a27f0b1b074911c8a649a5686ecd4c9c01f4092d2e5f68d85a3c7c60497a1830277ab0b7b1bede62c597fecc800ce932491d9ff40c518de77b9b283a55606ac4a2b104119cccdce41c916ceaf77dd9ad1802eca2a92cb0a0cdcc4f08c44aa24885880ad582cd0306b8451135560bc3dcff017ade001a6892ad4b80b13e5a0f60c6b7f981876bc1f6e1beeb3ea1ad91e3124faec8343f7f21979d713eb532a0d4329f69a228843770ad39015fc4f507211229f4a2d3c197262b98f3b22fa2735fc7a3d41f0f4caa565dd5575d8b6aad6f68022e4d4232abdc3625f7ec272f3d05efcec49d74bafeb45526e7e6c315e6127e676921c536bd44276a983f3d8c6abe95041ad01e19e10cc878f29b067eed6beaaa53847ca879fc44bdd8acd0054afa95b4907a5fb565a2044e1d77f463ff62d9286da05ea784819909bf8afaf2bd1df21c73a2156a3d0227b4d74b8397437c35027a92f1afa524946fac6a62f63837e763ce443d076913b169d36f31333d3904ab87a61dd47e4145e9af688be8b7dda74fce44a6c36dbf0c4c022e5ac0c088fc32b0a93fbc6521c197233e5088db795410c60db739ad4a78fa6b64edaa2f21e2b5d9ca470db47b2c129d5df6586c12b97fd90929352a7978052abfd23fb04da6206d3ec750d8c95b4d79c2c0e4825cbbddf2e05660c38686b688cfba9d4312501106d058c2cbd6a7d0a4916a0640b614a55481887e908fbf490251835157d15f4d14c8804419a31d46ee5da3529e2e3459cbdba0d359c220be2cba7073b6085fd9dc0dc1f18b3c93203ea55adcb15094119a8864e98f19815b31681bde2587b424bcbb21ca0a0c84e147f27243b288eb3063214ef178027f18402369cabf5596fa0c800d5d2b0cc99c93e493cc0acdf4dca1194ed3582f9f70f51da4657b31678134a7dcdf831aca9820ccea8419612755d51dfc77f9f8d96b91bbaad34c5e6e6b3ef454fae918a337112f1cd30a2e48722dd1a61aa03920c82c33f42e034f525383ed6c1fadf20e7a445303a7004056c2d01abde6313f87e1cdd7980b290b40faac75c7f40e8713220629c77ddeec3acfc09f5df757c4381cb6484beaabb43afc4046e93d3b0d2d2dbe8ef0910a5b8aa2148927fc6b9f51e6076da633755a2f97273294bdf3cbb849834ac9890cc9755c556976656c056888920fd36fcb80936104f7dc6217b4b4762da97205cf822521e1441c9b984dfd8f218641a22513b76fa9da5becb5f7cb04132503e04ef7b8c8fe2bbdf1407dc917d14088c55cd82980c28a2b1ef9151ce6029a4161419f145870992f81eeb8bc3d07d42f2d0e8d7c27826e11946701e3ac592e6b3a527b86f047c25a5510d9cab18cece06f51fd27b06641339639a17a580dd292d49e9d9894505bdd41391d2c757967f0db8c03617a6ecf99a6aacb752f18e339a1fc318616d59b2915653eeba4a116371ae5a0816e41316108d6a30881550c80aefda9e347314731259e049f33a716585ea0ab1f22a41975bef288dc721ac896d4fa0f72b886fe6a9407431bb3494170ff770ac30fcecd2625c0e8f91affc6dcabcc7b4b8ef22bed169abd2cec1f4dc113ddae97d61f21e5c887393c65da9db34545be79539eab42addcc068c46b042ce5f6c1f4ac38c2d0fb768d1ceee2f859a3af392e5faf0d8464ac1dfc3c1b100188d0e7f0faaa55b965da48ebd3e4fbb4b96e5f161a165d9073ea0afee3fd73ee006e8d16b0b8fc54e0907146dc8718be7852bb1374b1387132f5645fc7aca9af049834e43343749ced93d1f227a0552693ffbbc385a27c96064048442a672fb63089414a2ba39ca2122a153e162fcce3a02b444cee46a61e45ba49e50c3c4e009a33431bb929fc2eb6762bbc98a821bce5e81ab0f89c1c67f7a4dd87a5372e719e42441bc43a2bae14ab93f82a4f99e4310ac799e1bff0553378acd1601977a7434efcd24df500bfe6aae29bac55b35a02432e0ea826c78a3e15edd580574dbb0eb2d86284310d60d587506c16965e6f40fee4a93a85b3e8dd781ccb316b442dede26400187bdd4732fa1b7db3f84b43a8e4611a3f8a1b2e1f5f42b2a59b8fc7d90ad7986291c1e199dac8e3f64bc6c6a3683cb1a7e62a29325d4fb33ebf8493973f00c738d052486c71269ed540b2f68c52635ae7ce00d79d112485e83746e0d54bd00cbe1a1cbfa3ff9f949de46fe3a91cb4d38f78046e696951fbe8fa43f69177dbfeb61b7b02058dde4d80cda6f57b622a3606449efaece5d903bca2589b35a3e87edf4e1e2bcc6f14dc2cd8542da68a8849ecb491bca5064a323b85612b4de0d84670d49d7a72c14e418a03fde0da1e8e38bd0486efed5e92fff4d2413420ffa4eb39e921c4746e7c483851b4e02c8b9fb8553923e76a4d376f2b909a4e8b8519c80008ec389c5c732be6a19ddd83264109e138e4defb854e474f279ef91a83b4ecc2c575267238dc1464d2513a54aa659ae808127fd2ba6172d38615b05872926200f97b097302806b525375e61ed6b81d20d71bc4f4e973903ac781e362dd39d8f47ae5acedbe233330a9eb262087e0b77e7d3d72ec9ba707e59ac2c4fdeae4983c13c793bfee9e91b83bc06fdc066d8bc6debbb8fa56b73db18c28577812ea65b77ae7472d83f721df0454458c06f57265b6ad2b682640f2c70425912d1578a628e15fb921ab8efac16e560649e667de661d1de02e60bfe2c125c6a7f1cb8b56b3bc03370b7d8083d2d6e07063d1836e5be12d0650beddd7cc532f0917259d306937d35fc12df035691d9463bf88faf997cccd7797afdd926f0535ae07e4893a909fc1bb9742739059f21a846c78a59edf9bfb25aac07f890d5eef9ed64c96a81ffbcda43ec5e2d562cf0c016d17b1affbc5a923aae6d89c3d95a23ee83a4d332c97284362b95a211a6b0cd002c215edf5b890f194a3e383f189705abcb5ff65ee7d02a3bd7ea50b824a3512c781a0acae0ba87e767d00d313cc04e997439e4c8f05274193151afc2162ae077e33f45419dbe36ff7a79568ac24f8f09e859af70b62cea6df58f0bb85a26ea604ec5913ea2b9a0a17800904bbdabb0da8f98b53e2ae27d288371d970e4e53b88e41de38800cd3548fe9bcd02edb9236c210aa29ea03b8e88bf28d6cf087bb3ddacfbc23befcbaa4ef400942ecdd45101014e55f5865fcf0b900f68c3b9f4e3612d0de40c8e13c9645132a550477d62fba962c2069ae468eda656545ab81b09e37bf1a2cd29af52b42d74b92829e1555165e548fbfc29359553012d7795fd823e28dcf54e2b1681a8f99e380a377c984256e2ac6c30d469b3de2c7772059540a00d2f5d757b553355936a69f0cd6a64d7e1f36c873fe6ce18a108f6219478d4f2cafc8910314a041465b85605d50a196b872fee11df5d86db84f448798df9a6fa1b0d3e2b8b3c338202031540878b4c4912a1953e6ca5b35fab313617ba6f7d3495db7c6cad8f804f5f4d4aa52d231279c35202fae6f4c3726f18e9e159affcd355856cf24f7afc8e53708056fe7a663398527715e437d096b49b43cc0a12fd81a03d87b5c22207f4b52748a94012296b3c39208c9a6001b5b44f57c50426b982a2f91716563181db7720548c096ee34594a402cc6a4c90a6be02446a1d05709d4b05810625cf2134e77b65d513295d4ecd9cde2608df67ffc55933f9028c4ebca0625889007a89b5a2b8138ed98b14d41561befd0374db1d92753f171447d728ba3a6d3bcdad5828169a558604fd628bd2a5016cb156f2125a7d2d2b0c5dc551abb54c0448cf3d3703da94e54d120731603b792ccdba85f2ce47c71a983d04ce230f04c4b1f84097f987231678d2d2b26003c66e783118a1ccf5443aa7210cc1aa88f8da248b6b1b402bfe3b08e7a4924c00b132b1261107c2a470294a3d312e4ac9ede00faeff5197e4b893c9fcaaedd9fcd16116cad21bb0173371624deed36b38f5708e42454148d94ac422832eb5a9433db1cea90a2d289926efd678ddd0f81333507f9b1f83f9cd942155ed891537582a267e1305b09a6e417f4a67d769905eaca9981165ac2f2eacc33ca9f87c2b0ae9b294d6355200f2628a946288f2f9e20453ffae2a54319c89ab722ba6b024db8233a8f3673f6c4ff85a41eda38a8d2093686abfb6a963efbcf9c021105d25d7039fecb3248439a89722d06d87e0e0ab6774d5425d4ebf63b6e5d368fff1c0717430ce7e6fb9c0441a691b68998a7a6afb03274eb4cd21e7a9e872ecee0879da2f0756833b0e183f4d61c8c88fbf752734e78900a08b53e9dc810cd83e95f56c4b7e1177dc274e650cf056454207bb47089880760fef50269015dc4a8eb279f00deca3d2e72db6edc3fb81cd3ddd715d510c6f977f71a1b80ffb472f29a78755db8759e9543242135b07581c7de5947602a08e77fdde8706f36916b55a703adf5c44ee494325b27095fc6054a4421c297c4c0a140e8dc8ddc31f4d7d105aaf008d33dd636aa1666dc0a638595f03394d1ec7e4e32722d69248080a7f8b574c19648cc1e200041f4980b36b5d69f5cae51583d0960c3fbb3d3459dde41b29920fd9a2b5b73b3e3460da38084e51f4452fcae41f7de803a6a21d3cd2cf4e66746a8a1ff131400fe3f36094fc63a6bb7a6fc7ddd3d209c0124c8358cdb24c633bc3056e704af21420e34eab7d5d878ec34be71cb2f30938bde984f1633bdaccbb71be4e460c2875b34b467bd8c271810531f41fef9cfef32f9a48d34f032df59f7ed2332047457c29637e19b2b5893cdcdffeabd4f911c569a49e009e40c36de672837ab9af45ccf76ac31f48838bf3563aca89263619165a705d3da6cd396cab9bdd8ca789be4491a2089315080cfb2531637cedbe482c99ac95fac81389d6a37379cc509291123692a20285c77e8b70da1ecb699dc62926f7efe02823775152f163cd9137b162ce817a73292a0df95de97d4e5251123174a8cf590dde9da888644862d5c1f99b1ea66412cfe0f4aa63c74b949cb53a62ef7adfb5d13b20c8ef175067fb1f8b2a71faf7b4a31f6b6724b643a4eedc8f100b6ba0f701ee7579a773a71f4f428fe5d65f89beabf50e06fc6608164c82d65c2350507a0a4d43a86ab340b8365e11b5f39358c0d2490fd217f060e2ca2797a5f9aab874d97c2063ff5503b41581f59d1b4aee5a40fc92a42ceb2a2d1174c480513ba9cdecfa6caa5cb055f2c9d0ae8a224a93b5f9abb79cf56a882902e6931d1acf4f28198b01fe332c0600bf5f9b57e775f44cf223459d531901aa3c0c52fd505d9c70274799c114f2fd92713d79addc013ecabf2f96462f47f2e19053b1299d0fe05fe600f1f6e2ff26b34e8c99f771d7f6e5a31e742f35bf240598abdd8d382cd7fd5ca2399d32b442ebddf8ef97442007dc6f0a44346fd1caa8fdafcfc2c52a68904cb6b38d32630bd4b96e00ce7dae5b442f172538a5d49719bba0583c726bb3440a66750a5f0a340ee2a9b500c61a3786cc7525ac917e16261ae11059294181da6e6a873563891a64bd37132e4ca286d2e75ac19271333e6e115cbe6df05176b7b2522d208da0838ecf2a49ed11ec980cfe430718c826b9035f884b7824b5e48f2c1d834a75cbf46ea4c770efb104ed10d7fda25f5e2362fb63589a98162baa9e8c454a436908508a150cf42b03f74926b02c0f094f646206a472530dac15a076d00174e5bfff6859cf6c05f721f51f3372f076f0a3d7b50941d96f3caa5d6b38522a8067a05b81bf1e0549cdd4472187f46ec8e1de6494a71adbc500e05091d22ac5469ad679afa06015138e5cfee417c27faf6ebc9b281bc12fa179e8602bc27136bf13fead3d18039d82187a504a797cefe9e9e427681e420659016cd9d9238648b6636a12ff4df953437f0e9e63b273d6ded3d435ae52438ae5a7b5eb3d34274f1ce59f0603422f8ae4e5fbedeac8156f7bcc35a15fd5f43a20f985a73061dff36ef91260945564bc8f482e7bde4ba2bc9c93058607130e29159e642fdad71f3136108076bed2c33a654dee0c5aa0655a54c4016ac0ade832e25189dd0c0349cf28d8f60d2ee14b53c9681ca44ba6f36a72f0be7232b392c4a2d9bd058d304b5f4a2010b92935c804082da300905589f3d2237e0e9920a276e9fb24b8f35841a64ebba84af6c6543d155d4a8664472e5345d33605c4460a01a575b49dabb637277af61c93912d7bef132ca1c9b48b20a76684e5e6576a0d111c1d5932ee3b0278f022b001a423b76d4ac4078a94a8d66398411ed91b875d1b847ad6be154cd739cd6b01a0c58577bfdecf1a3591dfdc10758b95c2b4e0eb5f4e592872df78c9a101eaaf3a8577f856daff03cf0db6ea88a576e59a41baa3aa08a0601ae6fe780ff5fc80355bbd9c0852760221feaa05cc28ef2027f7201cb279884a03ab143577df4aa61b9da8ceecce8a90f5c05cb3a9f4cb015010722928b50f9cf763ba436357d1f079283e71fe6cea28cfd3826c116c10ea26ae59ab4b240b82618ed695bf87ee82692c098ba300d929cca420e9ef91862dc45ed550499e9d0a4117145762e73114ae9bb9bb81bdd6435c457ed6e668ca6a9ddcfb049019a122e4cf999e9a4c24d59f22601072085b6f839256d74ca01c1d1afbb4348a46543a9bfadf63e4fb9331b735dd4ea4547396e9b8206d43e21b288bbd4301e331f8e23ed1e0a302b9a153a89f5597d9379c56fd96f57afa424a9de045edeace0e2f7b9cca84ec3d044b5790ee7eba30b249f8b1368c64acdb9ef8c6cc721b0d2160eea23476fdde6398aa6339bead71abee27b562453e75b1c36f9f5077490568d1b29a01280c53b3375e4f8940389dc6d8c0c982bda8b51d567b0109b7d5165b10a1c8863cd1fcfb2ba0e8febf252c7acf71881814e693c74be38a2560f868b48320ce19f66d7fe3005b051966d00ad72d4fbd411ea0bdb89de2bfb8e67cab6607c8c4128efd11fcbaf9f88fea7f679569bc841edb02bd5a330b2a6faa4217e62acd3c2b51e5ef1bf4b78b55c4a9c66c11d2a41ad5aa53ffde97b134893db6f7ba185f360e53582ef9ed00d4e3d18d3e072204be56d61f5c33249b5d5fd601d1fb08053501eef0babc73b99980085c9beade1ea236a16151de9ba9c1a5fa2681dffaf77280679aa6af7973713e1053bedee38e9f45e1bfe54d5a4db26a6577e469e873d48c020eaee14d2cdcf86b4ea2488759dd141828f228e7d22a5a9405f4f3f804f5d2404d11af904e4a1ace3f7507f17487ad2f65f0a9af7eb34185109071c272e0e281e780fe00a3c62d7fc795b63ad504044e7a6086ac11093bea09127ca8da310de567337d31e0fba32239356d31d84dfaf5ba5246c84008727a6e15f80c7fce826fc48602396d3af8c230a7de700e5bb060a8480ac47670a4d21f9b6beee83f1dd56a9cc2471ed1ad970de11b1e6ec49e9a234728325fdfc01d3c59fd44a251061f1f82954b4b698aaa29b2597b5c4ea403818d57256ec975910bde54a086d4bc578ba9ec15a45f69302044f4371bd3fc3746ef4e201dcf5d20fefbef06296131cbd246cca7e75b34d1f9a7d872dc63e1ff18b4358bc324ba21f668503d89aaa777440c03eb7b553d7f86a5d1704044f9161835d6c1b3aa19719539458452ad1a654d97ed1a46f54caecda5a06d7375dba2919326fd9606527e88351d12b9485df10044013806b078041608b2aa5039b354857a60fcbb629201b80a54a7df5b001c1c3afd26d731a6f9c047fa715f6047686a138df46fadd795986ccc2f7cbfad3bb7d75ebda8692b9d735b6356eb8db61708a8073dbbd2c11f3dfa2ce2d786d24e7b3ae9a9dec5892bc51bc49f84dea31b36beef0bc91433da27a4efe4c858309f52d51add20cee1e48589483918742ef6da03af5b64fc0c28fb11714780c59b2e860925bb2f0602631e169f9fb1319cb4ba63381191a0e02868538295d995aad364130bf1b31d1c4ea5dfe4d9e802b05b80c7b8b7bc0fa461ff1da67958f5922bb192bbbd5cdcdc839b871d0f727bcc97546cdc8a292e68b429a62971318a6a84f430a0e58b9549fba5f7f85fce62955cc1f62f613c8a90ec3f1876195e9366a2f8cfa325ece83a1a8353c4ab66414028f7bfea98e0507354d19103b520203a6e2d8b6e5d59acde8d4e03070fc01c8ba73efdd39519b269ee9d5b2e4bd2f462c97edd243c3cd5ffada122681376b2504b48a163bb93aaf5d8164e0599809fb45f39804a51de0a5564dfb8339c096ec8975d9fa5db8062c6910a3ed644aa95da513a31e8acf2495fc68118911a0cf845c18fb1ca02500d350f5e0f3ab767c1ef8a92bdee44a2af05c2ed54a1e6e71942abc6ac22d33a86ca00e634a6735f13f185d8282ccaa69c9b4b5c0cc78d78bb5de9e2a8d1f823a2b8b865e3d952d525db84493088e902ef1aabf84e0cdf71694741c030f73274ee30f579c200969d7a68c0c5e134403fc54dc588657eeb006ea622a128ec772ca0c8341b183aec28069780fbb69f05ed7d408a4ada34ae54b78eb734bb8f516ef7f1e7e64089c20288b9550bc794b9a5ced7c36ea06ca4f5d134d238b4067ef551cba2cc0d6f94226532eb09eec397089d8eba2e0ffc91854612a26487e67e603e20183d6442a535c226eb459956214e84b348791298259c3d97621ac746d69a0997160e422a4860823f0cd416025d87a3d47a9e7e0ea112713b11865d05f576a7de806f1e7e013145be60d5d7bcb46fe6af43db393850a7dc83c8431097694cc61e962b1d9c1a692747ae6301f6e24496bd1c6a5af1b9c55633905d4a82cc3b49e0f3d0f070c16d632b7e1c1804dcb267c729abae27d56aba119616d1f7596d605e414e8d644cda1e02527b643d3369bffc75604a9e0f3d8ffb662d59483d4c19db5ef0ab622d76df142dc726e6130d4cda7a8224f9312cd6682d579e497a7f765cb6aa4ece260682aab68cc956d69f871fe783471a742dfa887fe48e7f2858282acf65c0da824042525e2e4be4d06b5b68ec3dd05ce6fbcb59de1a67cebda99e334e668407e54383061f6194f86bee556c325d6ef9d07965da0e4f1d92b0a46555b34f8a5ef542104e9329432d60a85c6716f373004d255d55631d5bfb3763d1628fa2dbce4cf98dc7580317e59eda722189d04c4cfb3c021682162551399747a6c1578217730ad8b2b2aeeccffc3a3bc5da181986bdcd70b7bd285b6ec4c5ff6b614bc2e34a49d27b2e591596a8a1644230b9d1da95642184e1e42cc4c28d1672b771b32a2d2070493563bdd0e577c4cfb67746adc702dc6d7122c70750ec8a0054762ff377a133815a368f4170ff4aa6111301d642ca1765d600b3d74c3d1d48d1c5194d6ba5c0008b20091c183a243c000e1497e5752ea6ff87aeb655eec0d4c93bda05600c9378d2ff19d6be180fabbb7546510b5032fd9c4f5b93afa2deb491733745b92e96d7fa7cedf6644bcf2cf486eae4901c0c210d5e85383e238a9f4e69fc5e06e172495a6f8d25c747b17ba3d5ea92ebdc3e32a99819c1d700ff29fb007542e397824ea887f23902e2b7862d6a8020908cf35b58b6b107ecde7e54140831380825d9734f8192abdb58527c5f87a81ed2a7bbba6523d6b8aaa9f1f6012ea4e97aaf1e739546ab0020fb00a1f8a7a655ef9cc253a234348ea2115a900daa37f5258ec70799dd9818d02b59db75e5784b4d35892aad01e0a7e588f47d7e5dc5ca3d266da035ef8e0e5fd27bce6b4be227a95bc2037d1fede8d40de692b8a41495971b525d6c80a48bc227f461cb163f79d56349038ff005978a32a9914a6331f2f9e31ee6eca2384fb7b312e68a0aa29531174e0159d744903705c3fd20761ba301632675785834ad4dd950c5f7829a16260e5e95e42c8207750b58c32bd0864949ef93fe6119790ed92e3258de2fd7877342b23beaeb2ace8b43812f687dc736262bd3b847e5d403302daa8022dc265eda6ec7fcd82fb14501adc1f74e0ce54aea7bc4dba51a06ffc9de62d0fad6ccf26f5cb9bb16c3f070a61680d80d874038e43fd0e2f83710ed67510305390416e0280b6603c4898a1a6854554b5558158c837d13f3f6a0808ed800963acdcfd7729122728ec8129cab2049792774524501b680b4fdddcae21f68aefa4f1a840c858356e3e60e296c519fe6fbbc2d83e877ae44c2b2ed05eab17dc93504fd9758603aebe1f3957c40ab0397663de01bf6fd9e19c3588da28b25dba93f040dea874facc09d8f8e225a356a82ba22b680cfeb830c7907521be98d3dbae8fc6908e0d2f63969357a3a5e5b7daa041d9e036a1cc8de70f900cc34a8df1c367bb0a070ce909c5561d7490f82847303d76a2ac8d142f1ea08cf24f13f867b3aa44ff4510a823b53e73808a167b86e1eb005733693a83dd293e6e1e0dfa2cffb4187505b34e835caba770280933d70ad81e17a5617343e6dbc0d2953ed462bb33ce59e9a55d5787c78abf757d32dae96e4ccf1be02247fd14bf6dd680aeace17c205e0ba3ae2bbb9e1a93a6c4573e6031f9012c108f46d3c4a03d54741fcdfb0917f7cda12ee7e10fa1c9c5abe55937dcd0e81ac7397fa1397a4be9507cae6ec549ba721404b91c653499beadbd65b717f125661baf50f10c1bbdf47bcc87e9baf08936ff39e0327d3a9f962c4b0a746e18f1e280151b29efbcfd6c577bfe7005debd84b1b710157b7b80778982be0d038e4005662de5c44f1a79de8c21deada909daa490b39b03ed9c0234841805e7e3f59cd6b471caa8f3ee3c608793fe81b90fd3cfe898c3d887a08e777dc7449e9db0569a5fcf3bad028440c01e519594a09178241db24c69db5a05f0bc6530d21e9c59df37a001461f88ddfc7884ef3adda46a571f5238b81adf05f07d9910edd0ee4c3b1ac87e0ec0b1fa12ce9457b861a259709d1a2f5c9141331fb20f4cbf414de29403153ad953812c05f23379b498cb8867494fade94a29d352e7a3efc7272ae97a4d67540927f0f8ed1c18366f852cb60267dbaef2c6e22a048a706714ff090f9b80d1f225f80bfc72fe2cf82d10fd4110cd832aec83930700477af3bb5bd949532abfb28a4199a5f0c720c92c0fdd221daa58a972b1210cb9e09fe56de8ff22e6acc125cd602086e82ab0becd226d5b82eaf56f2d8cccef9eb7caf968d412360664226baf43c05eda89d87382a1aa3ba08bd5dae92583354128d331697eb813b68f499193f948286aa8e39fbe5e18c16c42de1956638f1761d8eb971c00ee7d8a0f79781bd380782c7f411a99c4dde1846b206677c3d3692e916c008185389451d2460b0b1061d8b590fe5d770d07fd9059049c11ac59ea01168bd175d76c0e91e631b4f97f9fca40f2001805c418c82bdcd427364ff3f9af454afa8ce9eedba72088d30c7b96bf34bb9546642e2a200a692e091e5fb1a921410536d77fc03a0290c7086d5ac3552e8fe56be214f33dec5a936eebc43e2838013bfb011552f512ab1f0c7bd722f21cd7d22c0ef718ef98e4dda9822ff1666e2418e859de43f23b0d9c7b34aea83ba462e03c077c3842cc583419018154d4a2b3d63967d4dec9b6d70c189cf03a757a91e977392a4b049fab292a78318138d88c704f6d533d31a82b4f8e7cde8436db1a7c9d8999ce9dfcdeb3d3e93937a4fe478d4b5d86ca5b0881f6bd09b0df5013b0fd0e66eb8463b2d51543878797ef1839ef844665bb7164aa9f0e844a290f1f2365803dbfc4e44f7ed19260dc3c282eab19a382cf917dee1a564450afc00fa97305fdce3224130889848638bcdb2952833129568ae0d8404c2ccdb4df1394ae43f3fb637b255a4141c0412fc1ea4511ce8b843e1eea11cccabb5531ab10719c4fe46ca460485ca5dcdd879393f192e66f54ab5fcebf01ae40b6ee00700451fd96872110b7247569a278a850980b61b5d0d5a31c383316b3cad8d999398eb92d7ba9f9d99d92b2c7bc4ef231372d12206d4d593911507d363df14d2cecefd97c017237de799e9f71f03c1eda7975f49cdf67d772a8ba18cdcbc5afbbbe57b7f9b3bf0ac6c9511fbada5fe368cf75aa586cf0989602284b716f962651088835b7011118056eca5b326aa8f90e3724963c83cd2f995685990b5530684ab645361c9c163093c0d0239a0a9c7676790a9e9d2d4b94bb51643d2348eef255d6451fcf3010908b857f6b8a4031c70545fcec31ea6604fece13fad6ca8e262e794c16b3dc1181496e959eff1fadbc1f5b31aa12a1def3f725a7219ae64698b92316ba5ea8ca3b119f2abcb911178712eceed9b7408b001fae8919455c5236461ca7d59829751c35ea78a36e3ceaaef2be8611c963c8d2a2696abfaf02786bd5f7e1edc9b61089df1be0a677f9c71b88f7a8419dc767a3d904411b97f9854901627ca75379e8d1e2c16149a140ab76bf718ff7e87ad63f9652a47b45e67d0903445b393bc007e548c7478065359bf8d342deb6c4c7d4682b126585a51bef14474f1520731a064bce9ca87e10b103dc39a7bd62aafa7abe53aeedbe0b36cf7003aae99b7c0a7b24f30d42ee3b0d981ebe36ef3ace63102122c05338c6b66df9ba9d15465bdf50583fbcfc8ec0387c8189aab47a03952e025d4d01c48fa3c8e6224b2b8eb257f53a77477a6137b04447ccbe98682e99d1748fd5c7af7fc8e06d2417a901f8f926509b35a9610cda2f77344b2df0399d42b8fb7ad1b2b7f18814cdb0eedefa42538c70b521fd7c3941a41bd8f5cee4e0cdb14706afd03358bcdbe93517350c1a33ea10e80662596d27c5d1483b39633f8bf41404704dead99ed0592ded5b685de16c634ebbfac6a153357117cecf517b83a9c107aeb08e8ba61a74969da9ea6e5d3306afd18d763ac5279b9d657d788dd52fcacf76a6bfb82bbe3192fa460f693fd44e7545f5376853654ebe9df7d3736bad1ca9da5ad7b735ea8be4edbf85fe85c0af720321b344b01daa21f3c056fd5efa7b3efd158c0e7f93f8f3d9f912e6a3559c29e91df7995eba5934cb4380d379940c04b011c48a52a11cdceea10040494418bead2982a8db39672c362a486b8ddd7e56adc002633d9a304218fd4da10a5540d6e6000da35b277e6b3b7c1934e469942110ea55a2870db902a96c3872f6a39b5eee33f4ecad974da84a58aad5efc6a5a4d331a9c3db5ab002a4076ffccdf6def114e64158d29f99fd20067ee184950629a568af2ce18d160a66545bfb295a4bdf5cbe1b7359b0abea3f47868ac6ec89dd00e68a45b9544d245005b80e0e789cbc75c52351b4220d77d2e76da2a298e6a1e27e07e97b83a00feac8efd7dc486ae900c57eab8afa0c44553ed87917ba9e847d11fa4cc5027368ae22e139e3ef33377b3a01aa97e4514405c012efc4c5fea9b3747bceb2ecbb52e7faf150edca74e1604a15458bf41736d514883d45d4041d069a7b5781a852e9733acc5e281037a86edafdc15557f0bf90968c60854156a4df833716dfa345451f045e8399f305efe486f9c94c69544886d567f927ef5208bfa2af0c0178380d6060e376380f6ba01489a40eddfa08ea1be471f3e47ab2a14204ad2044ef4e380c304e75fe992379ca20a6b7c2d0cba0b26eaecce8103dd1ae2fbd3db313b10b2b9c65aeea125f99325df7ee7028066415c569e55bd20ea72ff79abc2e1465fd939d9be6f997a23909a85c11e29a35e723e796b5b60f7f4005814cd37a1314f5d77a93463e2f31945e8794f99e1c9c08161226240dd5d16b3026089dc89336ab3dfcc072f3e0ea0cd0221883dd27cbd3209b167b0633b1b7a85506f0d2796bec61c95bd1060dc17a94e72f2a4cdb6be96066b1e420d238d28bb5f8f7de2a8ffcb7d7a456a1ddcdf8e0028f54a29febd91be3c2377fabb674e347e7ef74b4876f4c4eab83ca8f328741d8a579e312fbef47166abf128c4ee1f664728dc769e715ccf12404efb2b220976897150aa6e59c53db96117b1eefd8a898b1ff03a045c20a326c3302dc4729a96e6d5408b6ae06845c06a28528d050f360e72ec1730433246a4c4a967052a9de5266d144c7158daa1795a5e703649b8b7fea96ac0d146715a248727aa956d841876b196ba91b70f34fa35ab230bd2fb441f93d87afc60835f8ee924988bdf5be74153a08f1152ee061fc20b70caa4ce9978014db908c3e619d1fafcd06f44d1444b3458f14f1d71627dee669d4268c8b9fefe5622d6f21fd7a924221ef6cc9bcc4a7b8ffb311a9be11a1963218d12a9b9de2d926c92535d63d91e9774fa124eff3c8fe2265b00fcfbeb410560690b13914198ab29b8ae4be12d60d98960623476139b3665b915d3ee345ff8bb7f6fe6ee9e89d4a2b8118d9a6ede164776551ee89a998b540bdca479817b7c7615b265f8fec17028ac3029575b06ca9fa29f116d778d3822a08b91837bead99a62cb98ece13868bd39a5d85734d0539a4f536094317954840bc9fc0a45d0efe3bc0b8f4b2ade0ecc7eb5cabfd537a33c85508d868c96828c2c896fc3ff403653e91fe107e186ff2f345bd2327f6bd372208d408851b65a291c9c86c4ec21a32b4a224822bedf7ff7dda041daa734a52c9b6a41226f4b791c8b0bcd4588edc9b0685f92ded290a924a546bc27cde61422a0830e41d2405dbffa1525fdd60688645ad36bb56a69639292c8ad606080f4a91610f769f93b7811e70178ad9fc0ba9e644817d7b77ce4d65d5fa6e55953607e8024fce418e35bb68935dfb32725aefd59aa9caea6129eb8e1ae8bcd8722063c1fe6056581239520b6b626a07ba08e78a29146d3d1fbc6d149608d71ac0916a3fc17a381c13d0a1770a734e8883861c9abae70a9c83053b16e9fb81513cf6e903ce25645e2b6f423fca91c97f908a231fc21007fd9cebb6736d2519a1831330144c78ac71c6739554b95c3429ae8258775ecd12b1ac5e895fafe5abd21e6e0059bfe7108cf5a149cbbad118e59f04571ee7031c429affad4ef411ae6015203394f8aebaaae2997a36d67edc1326a8a3353b659a4af27d4d24b0733149719d3b16cd1229cdc917dc87a8dbbb721d9d1c101ba534725cc5ebacfd6bcbdd25333cb63cc69f39c7989649c00220627478d436640955e6b792fbd96aab321088c829cf405793ce49f830275ac91c52f8dd993495f74752f9936508b2101705d49e246de57e406808f191cce9ac0b63a3482c4e0c25653658cd248ac8a85c1c4562e3162aeceaad169d583045734d598e46c04957c79b02cc8d0e633ee6b37ac28d1493ca01b1aa3d5c1145869322c7862fcfb8123e180b2d44712ed1c4cca1d78140003334c4cddee398c59b712b768eba17968989d84ab227ddc7c086aa7bdf6e450fb7ae2a597aa817682f7a91818630f6628f4a816a5beb38787051807a66a6b35664d2c3ee0e58025dffe9e29135516336ecb32c82f43420d4ed0c72243a9f6724623cdfc90b15194cbcf7fc59034fcc05708ed761503b9a822e0ef8f1825f893ee8114ff6b9f3c62b57ecbe5066b3bf5c2a4cd6e8f763d877f97c3ae8b633595f52acd1a8508e3d40f32e0100005110b0f854e07c5aa91fc789848f834f62dd981e1253e4b1abed2d36dd3cb5e6fc3a989aa343630326fb59454c6ab0cfc1c8edc76cf57fc84b695899a9fe6562b3ede2f913d8da35908209452a1fa3027c01e362e6dc5351d973ad465b59520c03d73398e6460703fa4290dff6dd9fa85326feb946d432fa4a4b6058b8c65ad8b641f3f244e76b393bfe585400f1a11eab9489363c371e9c61edd46bf5b2169bf5dd5141345631aaabceccd4a5264915bd2737a239a5c8439617ac64ba93c75f4f6252751e2435c8895cc2c5afe0cbea561d2d19bef9a3cb4b2d1efd01c122715793b7f98007bddd11a7c8a31d5887852ea60c009ea81136e058c7cd89880c0ea9604a3cbdfe44036f079eb4eb15ada8a5d11ca34b4a3f397ce043ef0ac3c18bbc70fb2d9e008a2f1465ed0f97e446325425cc16842f94d38d3d2d8c09e84ba8e24501ff29a22996a3f020a5b6023ce42e3f5a2d8c98036170ebc22516e6fc691364436613165e8209208f2cb0c9b1706a8078c187ce2dd0ade59a346244f89eb162e937d31cc5607cc4a7ac9f087ad90003d83e7c5c243b35d46524a111f5c08b4396ec344dee60cb5d10e139f634cc6f85122cd8b2275319a678b0337a6c8e373c750e70b21b6c10ccf437805e145e0db2e032607e4aafc61393433c3cc4af77a0523cddc847e379f52d2b49a2ee7da4c39105be552ad9b08b267e241426dcf677391ece65e5d44009ba704a600b34dec7d03f7ee851e70c1def90247724e1440c089fb49b906aceaa477f5f28f8c0c7fe7aa42c933020be0e01f420faf4e6f54600ce297860755d62844983087feb6f013fff6a0d67baf87b9b881fa5294873f3074c836bcaa7533fba2ad40d5c743107147fce83bdd679fbfc9279247774b4b784017d23d51143629667549451d1c3686f735f2a5174ce9b3759603add45bd033fb17112b978fb7d616c8411f05d0783caa26d71f48225ee7951d360e75837c525ccc3b17a65d8c0853edd36450c0afb00a5a745b40a0405ca4896eb8f9af68417208eba12c8f944459badf62583c56885772cbb474d896ecbada319498b082d7eca422ac9d4291138cef114087c0643ca8c9b8687fcb9f86f208190be8a44c8f362cfaa9bd692f300758493d09db79fd42f3653f0a0055616509fb0169dfab3bf9f696fc08764fe188c1c40c8d8340c43f0a28230f22f88de14de3c5f4754983713545cf24b4799b359dc9607066633032c7352f9ee221a662f6b0e006e6dacd78df49944cc3586afa6b1921a35a8930f407c548b65593ed1681991400171d2cbd72e9080c3f15d702a2afe1ea984d2479bf1cff1e041dcac36127d0eb8ec137f004511ae9c5eeb13a0a2a03186588cb7a5afde05fc8b3a33d2186e492f26b4a0eb060a3fd8127457375bcb74f94029dae8d0ecb004dd930b6ced8dbc8022e289fe6e3df2b8d1d360185045c5fda9f8f468c0c8f33a5cdeaf06f2ea9856481f42a34cef555bc380a70dabb20d9a977fdfd5e921794eae973eff84d22557496a561801c2a1d1d0d7a19c509941055572f1de724be8848b59ddfc72a382c5f998b35a3863d415f83ea2bcaeb1f59892b2b1111bc451a1a8808127639ab1dec57e941f3a6fb16572970187cde6860b70cffeb19b33f22faba862bd23f13d9a459e005927aac5a95280c5edfa556056d3845792f8e6959fbe99aa21700d99d487b579c8d6bb6de3329fa8287887660d6f55f95c413d8d46165fcc45f402aca9852bd26284a247234fb4e3119f37169b58d6d31e8794cfa495d17980543abb593184a047c1e023ddf5b8186c2b50e0dee5f9b1036e9360edbcd34a3bf8e94267ad570ee707694d380cff8545537f1a5ab2304c57fab01970933003a40ec999fc622162f66a1852338c59d6c1626e3ca4b0863c41743c6e473599de17e831210d20e0a5498155a27f24a1cbe93c5da6ca2f15610fb06673c5a05b132474514a55317b827c60137d2133d6c5ed1be0a94a0145d60ba81a415b1f38001fe6fa34188d89cb144ca64a3efd11be95957592b46037d37c79ec95caa0a4f1f29e91e768bc7f1736524c4f89a10b3bd998b682ec9f2cb54038b3f1d7d953ad72eec0d5bf95956df53ea8b37055ff650602d4191ae3da88807261403c2bea571c9ecdfb372f30f0418fa4dc6ca5b652f550ff1e08b29bdb9c6bd8c9f29faeb18e347e0bb998db9a908b1f9145d4a470eef540470279f554888c1df9d8ebeb45a4377cd2b78059073d6b3cd092ab907b057e0f537c65fbfd541d23f0fc3a1c16ec482223c3c2d5b5319566c223d13b3cf5c00a4fffbda5e4ce9cdc4990f177e550910097659f56285bd0e54de077b1b134885a672c27c30fe5c66fec7f76a59596be1a482b4dfd7ef7570321e5d1406a947a65e226b5616cc1d0587f09857efce0bb4009b153fc0fa1dbf69dbba51df5d885fff8ae306734a0c3521152586a44afe5be1200160adb0d644ca66a98d1299778b42f832237c52b2a8ab809c233d51b344963e96d80fea6584e683be862f4d66a252e42b9103e569f381eee766f23de8aff3458e7146306d72232ec00088d77a35868bf8f1b9e264a7969af73a802f297412a990c8ad5ef0f5b17d86701c773732adc8ea0202abfe4f9e4f3757fe36dbd9c06f9d09195153414d35a2acb6ced98b4cb161d6e5e08b3d4afc1e3511f0f39d019c53858163daadeee46ac19a97bbe69f3bb87f1352d6bfca9104f3a409cf7df94d68e018b7df786ef9681a32b77d69e3b7269d8bcfd014bd95f8784013cd5360c1088e01c616ec7fd62bb02799a72ac74a9fbf6cf93af54340d3588ac083ec050eefc72078a50ef76a14812c7cbb282cc8a5cc12a382fb1e6e23962f514405535200fe3de3f323f7b8721918be098c58bb776a7ff0e3b4022f6fcab2be2fb08c159b4f0e2c24f1527ea8246405bc1f6e6285dd23a5ec01ccbf9478d959b2881761208f2bcb84cfdea82c9bb499ce551317d3d704b3f75f74b695fa5124d88940d6beb569c54d315fc0a6f07a9fd1114e0dab4600b09e195ad949d04049238f9e437c4d6a33fb7fcda7387f948f149c5579cce47ee6770bde492aaa8276cdb688c2602f9b3e552d9888ad08f300c02b909f04480d9c8191a3e4d3132c4c699d815d655718d6959aa702b0440cb1909b7e92095c3b92a7c16da84382e691cb5023340e2089e2bececf24843f75eaac6d1ddf3e90e4fe4210724d0ffa67551d45cbea2ae82171b41e33b5d433f733d8708b809216de3de15f4529cb29545aa6dec5768722a22c1613efc4256263bbbb748a39869061ac2a203c14b1d2fc31de818998b4a5c0a40cb445f96d0cc3d410f25456a696799d7f7159d235b1d55b1b5e56938e1a4f42a7058b5473d0abc47c17490ec764f92a2c8f3044891a3316a532b42d28ff7e39b9a146802b24dd0d1f16f14f34b970b971d21750733583af9df02d31a599aab30780b13622f92006e03eb6720f6307158b1a7d3c9ca5bdbf21d9fd71f3ef69d9dd61e3408b0bf918e662d7291b79b8b3ab828310b8409f546dc96cba0af55e1bb7ec398e9e40054b5db1591e0c8443c4fa03eb49e73fa6f80872fc43e4e45ec0ccc9337ab04ded428e773b5eef17e11f362391fa8515ddc50c434af3c386ae2cad5b7252c492c032c4f5ed1505e8735cb090382bb3313308d5140198eaadc9a201206d3618a4d3abb0aa91304cad38526a8140cf84036ad5237b43033583547375e81e9210ae360f11e620ad03fffc68296d2b798e548fc65b43361b9655208c8306baae0c1f037c4c032c27ac6fec2438322cd91fb45d0b13023a24ab8b5918dcd73e8053417010c81a4bc19a46c7ae747f18a842d8e1421e41a9988b8f5aebee2742d736471462a8285e9090e33736f07798f94d1ffd92e228586c1eff2186c50c8f97b854e628a6d617401ff33fac1404f2003e4fbdf76714ef7e761e49b8feb2c8c827c6ef7faad19ca04d98470f8ad8dae372288e55580cfd2e50c09ddb78d28115818f60c50a1ebf2cb840fa16d075ef1ec8a1d54ad8c6b27caa2ef73da83186730416d6460bfc2ae2c71d6cb6fd709057982775961c787e1a21550415bb1f2397801fc45011edca693c0340d3b51de76dc11dcf8055a9ad21a9b2301b2c81c567080cbd332667bdeaca9fa189a1a446d676ce82c4867d24ed4314a2e387c97f231629044343fb94a118bdccb05097ba4ed6c60a8a2fd5f5c169877224b59fad41f711cd8d3cd16c3f85dbbbf253a60010b93d90509f6343edaade417fd876fe578ef9f0ab3c90681978f4e393a4c48025f56d3738bc4e122dea3b2ec94922ea0d2da980e4961360cffaf9b8a0d18b02be4ad282183b0b21b1cbd6b6ed23c5acacb9a2e122a9fbce30fdce4ed793f3ea9e35bc13ed39edb6243c4aff8d1b705755f42437acbc2aa80c4cb29ee8d54f4f86780550f28d323c750045335fc06ab2e96350fcba4b0e7c35874d276e40f4c9d974ccfe2c9177a07aea5a1198808ae83f7ffa7c2988ecb9b9d5c1a640eccae0965ddd4c80dca1b99bae3f336ed5805b83d74b71f425e020882d563d22e9263929bb3a3282cd62b80d6298c07a76665a6b328d5d91caf4e45b6e33f199cbb406d38c9be4616ed6bcf63b907c416fa5d80c83df9f31669c116ea46fd8c8c9ac4823165dd2189abe3f17d4d5c29cd2039458f73091bfbdba209b6b57619493346ab02a91bd9c6b6d219fefccf291f965a70843e58bee5dfdbaf670ce10b66d1ff4db8ae45ec698da85ffcca25eb20d403ee4b16e6a67e487c6ee834b56a7d560ae57c7b1a674efc9db4813e8c2130466444d290b2670135b318b24b436fa5069b83f4b1524d432a956a2eb2892adf8a675b525911229f0b616011783ade0a7e0cba664564b9a55b3ce3110f2d7e18d440946a7f43840d4c524e9c3f49cce0722ebb39f756c89e6039b6c1e5681c76b5937013919b67122cdcf0e83e8c158df5e6ae7417bfbbc08cec36d968a8eeaf2f912c4e151338c557b7a40ef6cf5a4f18022280d5621b3353543c893cf9a77c4fa4dc37dcd20963ebbec62f39562d901894035b2cb9aea5e4d46b28a7c5ae8b34fb94a0dbdb2349caad46aaff4bc9ed4d2d1950583c56f300619b18145d94e27c145a9f1b1e15fd151c242922bbba2d70e41cd4c47b207c6fc46d7695734d73474bcb201f5670488c180dfa57b02471af0eb45266a858488a4671c672c94350084c1b4d54c46624b22943a509643463d6ce31b9c43866d659d1cf046e942458815cc43d5063b9218346cf680cba086633c076fa00aef7531e8599c9ab44de90071cd852f2075fc3bc06503bc5db2949303096e998eb20a3983c059ec69f7a27d47ce8ee18401552d3b68e462c34f8bbed513c5af046a0668db14aabe85dac7dc86203eaddc46eb202c1d6fbce44ff49bcf696ef3a420038184986ed1f66b42eeb3bd4c0609eb61ccdc20436b901fe6c6f58e62b0d40f73ab3764f0c9b511b332b9d8c662f1865c92100308f899da659284c63173a99c21c992a1983b89696f1c33bcfe503533ec30737b3414d8b82fa3f95c1a156943b8c33ee60edccd1074d16562517ca67ca17c4ad4ad82ce23d7b35064b6eb37ee9bae6e5caa983ad18c7806a4d4da38dd9606355174db9d420e4f7d57e15896b5bd5b652eeb01b913f03921f428490ea3581fea8c65dc711618b7625c6770111229296f99e3eff098eb68cd36f748e0fbfe732d87f596ad06963e3aa766615d55d28b665d780f644692a08d2f25ed455ea61443d7462e6ef85a45800d03a5c8c8b8f6cb5e355380c3ec53ee8220b7c400ab2ccb311bef6b2e73826f376fdc89e39bf3f9919c6441599ed6e5c89f661ff62f1a57554cca3197c6e6b226f56458d096570af35410e314d55197bef7daae7ee1725175a6c5e53681b5cc1c05b8a2dfa404a5f50586942b37c4b46574b712bf8b95cdd6165a78f1bd210303f53c315da7574740f064d819243a1b61858dfc3f07b4793ed0a3692c32758224614f0a10f8c42c055f1d2380e9b83decd4d446837862be7e47036acca002ab5e5c8960f412bfc9259f2c657ed06901d9525ef7d0f77500cca53b241d203fdddd36c8a819bac872f44d8b89bbb498d76365e42ead113e3892b3c85fc63c081a397950fdb5a3c63f7d64d70f031fc4db642cb836ab7a5d76538ad5c3531df9101e9683406b2629891095c77ce307f76985edaa2dd01078ab70b57cef0435a5ce65b6e050afd3b1ba547a2f70fe4031e91c433ba3f8d6da801aeab8c34e76abe5d866696b9c486fe5342037e37c8ce21452d3c0bbd5491c2ce84e76ffd8bb7c1c333c3236ec1eb5c6302bcded2e63f68969588279b57a97b98ce3f8b481abda7e30d1e75e557375f6c688f2277c14128a07ed5253425c29bccfa18234ca2dd69791a94d0b10a5282c095ec6f289629eacc0f04b73840677a52bda14ad9c5430a62e4ca5e3667bd56694730e3e13f26cd875deccaa46dc4262b591d8afe4807ab201b54ca6e05e4c25e88714ae795020d2e0991e8daa17455cc759edcde901ed09ec9f2dafc8c90f6fb310c1b8231dea0d7baff95eedb03744ce8b51bd9bb37947793fc93ac5323397572df2a7b51d506ac121ae4f53d99f78ed226a9dc7df070ffd988e0d679309e7718e292981369b6dfdb464e9e9da866b6f55f43f6a29f9e1afe62591d9bd238690178f7cd2bba51efedcb5910d98058617ff3059364418ad3cabcd8afb1c40c1cc0b16eadc16f2c0cb10c44d74e1cb8806725a60ac492673db345b849c11a37f11c627732312dec92501643c15522208e9d73195a33ca625637c966786cc1634c9b924f05096aaf5dcc4a51113ffbc1a6fc5b03234784689fdc0dfa562c4bdb6976429d6b6d07e0b6a04688b85bb16fb81ce958c7752c500a80992072830495b947c5dd20f258a8eb8ab9d1f3d7a22d2864898b95e6b4076f07095d3950ea101d9b8f1558ed4b7d04f888b7d871c8ed13b1317c09c3bd0ba2a7cb3acec440121fee87fa80c67ccdfeb01b1bbca754d7e5fb5f1a85d53645579a961bed3d5f7f589cf809a1cfe1f6e0f43a095d22e684aa54cac400c6188141036c97dd8b730533b254983a0360d91c8485088e646251e7b011c6fc0296f68cddb137a93049638764edd123725b91f9c038eb96e9a88c8252377f8eff6b3650ef96c1283b6bc4b54fe8e40a34ecc6ccd9053a4dbd1d6650468b314418bc73a9c6bcf19949876936f31ed4bc945224a8cccb25e34d16e813321a13005d1ef2fcd919cfe4b13653c7b0fc9bbe4fecda89db713bcfd8add43792c34a9ee4ed73c42851668f8d868fdcd563848e1d63f003bb9bed97b162caf22d92c39f25564ab11062958d5f10882d2947e19ee2ac08bf4ba5f4d56dd4a858f90d7a068e85876ca0659c0285a4dfd4ac6fc86cae998c96881108c15da2d117dbb2c4dafab970f54d23d831ba64427366edcf6c8c448fcfbfc582daeaf393c4b2fbad86055b69d81e1c8cd9dbabec74566459113e62d78af2075e2ac3894684c5a8abcbcc074ebe410a3a390ed8c6315cc22ea0ee4bbc886e48ad3ad73da7da60726341d52234bb25e7915bcdc067afe0228cbd08a9ad5802dbcbfb91c28cf3cecfe0533023a971306bc148c8ec7ba05d08a993adec13b49f9e07aa42a0d27ba2e5b7eddbbf4fc1f80e568fbe8da5ff6ee39440b396bb948afd072c2612ba5e31f67062cbcc35dd216a1c070d50cd8aa002acdf41441b7525d025f20c06b802e451f6066dad5d2ca4f6ce59e9d5802bd5ff92a33370139b7e252018621abeb73bccf63002bb468bab922f22ebca6890155ddbabb2f18184d415c1ff42f6ed8bd5518b80d99a95473ba36842494936c7c333eb708bb5f46b12a936e34d0f3a3020b47a897e128fc7c069cece6b0dda58cc056c8f1885804d9422edb765beca251560a58810de6a68881388054d0445dfb14fe9de593916e66522c8787e2403b1850e433f1a925a69df5aac4d1b38b20d4aa0b6f98f4597572ebd39fe3dce6b288b7302c6c5eff96f0f52e6987a861e5dee7ddb4835960840ec0f193fa2ed09d780ee47af96a490f28724f57dc289ecb4869ab1add410157360b8f0e97d2e6ed6b164c9a5ccc1ea5c223e67e0863f51e96dcf41d6fef8c2c608960d34e507cabc4992402a2ca1c24b03096966db914fbf682da42111529f40a0901082029c65ff102beae2b082e6bbb9c03ef1c2a3e451f835b3a749811939f59e5f852fcebe516a6bc2133061e34ce24385bd71de6101024532de26300e8769e0116e53ce12652d65a442685c4efd1ba2c2702b155ab7f22f412a41db77e001fc01d6a33b8778c9b8048db5bec3f1d4be087f73e9bd1908ce58c98bd7fccab7512db3a75d8be389e936d4ccd1178ad15f1ec05b9bf9461472a057fa6672a60bdd4603cf82d168d60a41b93eeef88900818cc5f0793c113f9161d10eebad5e6c3d5f0d8593f913e10548305ee373c0ce2e81fff96c0a5641ee85d375357759192b6f2c4b7f9711668f4d5f436763e89e878dc130683f60390b5ba042f4a4d6d6e20d5b2bda4100442ba02ae8a905020e74a724f521d707e6a09d443cb4611a292f3366687a2c6691bfbd1a7aa15d9343ef3c06568493b7fc6881623ec1cf3d346f88ec8b6c7f6b1e0ee443309668c0bda21bac8984aa978e2b6af57c2fe9850c14179795ba0060365422a14f35b7ae4f833bce9d80aedae0e1656958536f9da212821711ec672eeb8b44cb9a5bfd1c5729ad193f4f7e137d885a4d9a46020444ec81544126b71d1f291ede296d979314a330ec79e3a626442a14c1ae477677aff364344c537014b4930353350d628553a9b2c4694e6f1e2e6e6b8ca5ad936a1fe864e5d9ba34796e50eb30b20a6f031979c898c608fa98274e865fad24aa2d7c3a42bb64e3c9d2447c35be5a746392b1d396b82eef90612726dcb3adba7011393741dbca499155bec6784c63b4749ae67223f16e14cdce3858e50f0d449169cc07a93976a28a2996ba8c4b188b6fbe43a8aaa40cb54e724fc0454c367d955bf75622d16459c9af6c718d7cd04faa8dc408a91834443e395d31b3aea04ea0d324802b91c46c28bb2ce1f27e90c3c9d5848d2864ecb4780db75ea0fadddf4ac30ccb98c84e0430fcd3c8347b95ac571d3dc96c270d0060698ccf07c13180c225cd1029bd168ecac9564e017881d46ae0e10228299ff43e0aed83e677bd673a0b1e97f2903a7b6d59b20d5b916c067aac8dc4af3287b5f7212ca6a6bc3511266ae3be89b14d21839411b1537b7549c8cb2f3491b46354e6d2b5f358ef91001664ab4936af8c13338ab4e830d3d559090a6fcd20470ab7a8061b3da188edf5662a65004cbc6f5384054ba3a3f6913fd6299027a4a0119b1818273ee237fad1b33e8dbc252fb3823389ff0d99db64ac45e07bbea76a20dad4718ebaad85d550ba1d8a28d76ec68ed99e7f2df393596392e835856579aa5207bc8828d11144a08099e3773ebfa7575a0c239697cd3cf08b64222c8a93c51904245a17296510918f694096f83f19d88af479c1142afdcb93862824454fe33f64df1100b5af1232bdea59416339fd45c779ee3667c0bad83504e8d128188f288ce4c8abb1b49f8db652e97511e191a1aeac868e1a4a48df26538d2d36ef9106ac54eee5da3d9724c793d81dd2e616ee66c3b8d0832140c960f13af1fedc199e1d278667ec2ed2370aeefecca7adb206301850ed90422a68529908e7ebff9ff6b0c2739818c7bace2972f1a37d1bab29d673ef240f55554d5def6597583a43a46e329deac53a4d8d76d9ba9aae4874c95df18f343d903f0bbb8ecbd9bbf5a049c46f351f8c66490478b21ba625eb19807c3d8b72d9a944eed8e4336f5403ef2100b9f15cf3b11c797414bca717e551f171efd4999b68dc8b3942bdbe74041b20ba013ebff632829359c6a1cb4a0c4a07540203e576c0bdc613a9f5d16364548b3b8c8dcc7074ce740da110a06c78a55a4ea2a84968b1bf30b358d95cdd6844d9b4ad827d5fdf5dd6a674485ab05e5c2dc0403e0c493275996c153b331e19e8d9e5883b24d4d33be686f959228051e4c5af83925ac668596fa269b1ad92bb51c05abac2bf35a3f56166322aa2471894a9fa3ae04db6a669aca5418c490769165427012bb43cc7e31d34b02ce48903edaa4e1e6873d0ac931dba0bfccdc5913ab28dc339ad53d1d4efd1491b279db814ba4a153a9d3a2e3f3c854198dcf5ead06cb79ab175560c56c47b8b8e65b356f1ad318c9f2166923f42ac6d29e5207048ebf5b239153b6537debcbfb81fbeb6a8c9fa1711b7a0e147e900df9c3a97d64b3f53d9bd7567a6017257ae336da108b7ff867db7b0ea86cc221419c2de3db26f59863145147cb8a10781fa8343444ad804f4e2dc7ed739b84047b435076518343bdb18170b4a9badd024f038cfe06eba44f33cb021722657ef84dec87d4801cae607616e293da4ab971f72faeba20d9724bf227340c8f4ec48412e6bb8ef1a68bb2e48fdf5b2fa7d8a6c591598b151bfa5fef249eaf6560de5657a7e975365b0425d1255c5d4786a5262a1d39607f73d249f5bb8f1725de8261f045b0adf654ab186ec941889f0cdbbd2a6aa66012b0f8ffef9e3c38768f85b8306a77ea072f08190ba16b00c9b12b55a7ac320718b30d5422a8ab54f60bc22da028a268acaa5920282e9837bb0371981a9170ef298c3dca2f0529e2e67367dd8fc2c4ddb2b8ebe2dd6b8b0e811f4407fd033cf6fd019ecb80a0a1e45a08389b750834ed6c38202c28059afc890ff186c25852800b3e54d306514b18abce840d329912420626fd6ac3cd27d3af1249558e3221cdce83375c16b78408ad2fd80772a97d521ae42feb9bd538d9a402e75b03a83f2cf9817233728dd110a8ded735c820861ba2382088abeaa3b1901e1372072bcfe3283fb7fe57a828729d4c8e34e3741fb7aecbb08a36cea27cfe68e585d277533df7925c541431288cf101f24ec5922738806f1fe22374a592120c5a52311fc2688f8c8786c9ed1287a4417b82130f2dc69e69b96f2d2f85f3e5203655a2e85b8143623bb4c05e1572bd278e0c8a3a783ed989309bfb9a63e696dc5371de8988a45a38f6c2b4267d8e353dcd35105f578a42186c5e77feb49f54ca2dac3e6a088882f6ba6e7d3278da10e464f153212bd8a3af95fa38d8f091af606afecc43cf98b6fb082ae0862bfc691b758dcd473772b9e74806e4c9706e95e0a2fae95175c2da96a6f6ef8a624f7be59bda42c05ec80b9abfaf41538ffd602e4c0d52f3f52a09c88a026d2e290257bf3deeac872f89702e25e8c32b21235b9377422665ee414154c366ec1f72b3263d19c41274feda4944efbc8af0b2b00f23e8aae80013546e33b2226c2a039890b3e91c26240cdfe6514cf941a53b551ad90c5cb76c165cccf7f5b65b67a5c49222abdddc2407b6ac7800977c0e715c6596b195e70a2941bfa71795af7a50b265be62d9eb513a099c29ea2ebca00b48684f2d211263f655179ae4d2d431a910610959197236feb14f1165f9fd34a2bc64a4a55870243ed9316d3454e0aa4869c815d6b2142e32146d2f9fcaf4e348a26c456d1c78178f7caf022e986bd6aa6332e77eee0080ec531a6e053ea52da9d5529d25b4a3f2ca52ce83b59283bd4925f16d5cb9033a8cae8658204cd2d21cd591465c6b22119dbbe32cc6b94323bdb8917b310900fe95b96aa9b3a0c04e9db4f571d037ed9ee6c4b9708feb747be667795900a087abd95fa448921e1fb8428c90c9255a39143c2ebf979696369152a69402bc07ad086d081f63247fa5973faca520790d15ace8497cb118bb116bd0ba5f5404de5a27e5c0af433d54cdb9a2aa56a5faaf2258ad15013ed82febbf5ed38850a758fda65a2d0013d517621c75234b26aa5f14c7d6ff2037eaee474150f3da3ca9d6da6ed7afdc77cfc47d57b927a2b19932852a68b922ac39ab60eccfe694324d22ded3777a6f047f8e3def2377fbcaa88fb5f2b755ba317d0f3281df43365d57f57adcaed36f7d482a4da1cdd668d356bc9163f4bb8f7915136df4e7834049574f727b103ad2d5db6f9bddb6faee5ead4849b920d5c4d4ddbe8d529140eb6f5ff9680316da7edb36ee653f1d558f7c8128718ea1bbfd12d38f79d4bd9c3b08e8c1ca984a69691e4d90fc9ae84fd2ea672b31d1f645605819ec6522d0d111e7f0bb44432527b62f8336a4accf2581decda19868db810413ef2602597911aa18e58aaa6c3f088c46c9cbed975898dac0c0bad40614eeed99b8faaefe8f74cdefde7b1ff53fb269fbfadef69554aadf9132a7fbc34ea12b2b5aa55dc544f499a051349931b4b1daa70fdf4645202afa1461e2f6416ed4f43704f86065a2b8791e483651da34df23e9f8225fd1c5c4d465984868b33fe01c5ddce8e24817f74cf4bd67f2b84adf7b10e87ba48b7b8e8130c99f421b13cbd797d419e4dc6ddb9a6ede315794651b6bfb2d4bd65450d15654dbfdc1d6b701c5fadc2f4c048689b6ee2cb2b1389f79b6ba6db46edcc817c85680bb6d5fd44ff3ce94337d6e5f8d1ead5b32d1f64571ac0ce8b7ff205efa1ec9b7e76d05ab7d5fee9de3babb3d6edc9d610fa7dbfda4611012ebdc23b9df1eb7fae0ffa034ecd1973e4886a081b3e7b160e703791985971c698d5c0e41003f6c7d53f84df45bdbfdbae741a8df43b6c810a610377a46ee2773ba237c5063e514dafeaa460bd63fdcac3ee0d84742d5a75630d1f6f77b102a08f47b0a67a4d93011b759cecbad688c9501dd8d7a67c4c7411dfb1a1caac1365161aaefdfa4fdfca6fa0540639ba8f437cdd7bec9bf6acf345f9baf7d11ffbad5a9ab4da127a7e1e320592f71b93ef8be7ba6ef3bd2d54cdebb9a0c7f7e934cfedd772411f0fd9d623d5f3bc6f51b102675df336a31adebaacd6f00c75a5bacc6384ceae9215ddaf7b83419df649b7a5ec6d7e3f3242471bfe4f3ae256bdfe563f3199fe30deae765b8344d93f1e313a3c76afcad47f25a7a56ff5033c64cfeae4a7237c2d817eccb2dc66112059daa7352f8a3dad0043520f348a97c710ebfdac3d80a0dd209d6b5ab75ff711fe78dd48d5cbfddb85d0f9392e8fcf0919cbbdfa3852fb08405019540577bba8dd6c8fd3690ba916724aaa36ec419b9fc1bd7da2e5292d65c2bf2b1bf8feefd7bffbec9bf7bfe260886cf914df3c3f921e9d29a9cd229ce91fb6ff47a8604657b3285a4ab9295c91fac3ec0a69e07df47d8d4faf0057bb55aadad6774e3a69e9f5f291526ffefb5075ddd8dae26bfef274904fcef89cc9e4d859cc30ba9ace8b7d43c7269dc33b59e7bed399208158d64e2de238970a44b039f48ab45d51ab1c0b1a7b47ff8fed5906cfadec91262332bf45b0bfd9ed1e7f0abdfe8d2de237b4ad733927e4b2da133ea3d553088fad88ea8576cbe4c469780f9b2f0b214ffc4fec063feff2d9192c2bd3686307623144fa1282ec6914b0d88023202e79847dc739694d875e44f21fab059224d21ea05a00456c6591788e5c47934a77b53e722412321a9fe12b70501d968578346582adf671174bae6f63ebedfbc6fda7869dbdee543e3a06fb7b7437d1af412f7dd50f3b96d74cdf7b17df73eb4e7c826eeb5efb46fea7eab96721cd3a808d40a964389688d6a639197dbd36f82dc3ca2bd641eb9b49f2fe54db289fef720fd8f7469316ddc90b657dafeb53d6c7b3ac25e2f2fb7d77c4fa3a34ba3cfe475ddfb00bfeb3cd2a5bd8bfbf0fb2697e67deb7d741f924de177df229ba83085df7d53ebbd079f639c13d80776dec873e358f79a42db6ba695a17d9d52303c22e177a48b7bd00b9f43fadd6f2493f72149646edee8e2344e7b4dd3de7cdd3d83b52f7da89b846482f5ed76cf44bf235d1ad37c97c6bdf73e3c6e74096900c738ad56cfb5bd9d4275236b0daa753e0e9adbc631f8f37d84936ca2c2e41f7adf6ddf914b3f8536d1cb8d6ca252bf693ef84e36f9871f922e2d247d74691fbe46ba3e007f3e53f8fee0cfb16f92eb83f9e033851b525473256cef8de214dabe2b890cf172db9e8336f7a966ce097633833c567b4a567242851ec9043e11fb604fc8a107be4732856f43afa715825e37bba8db66b471b5bab6ef36d27f7eef7dcfa560672dc2fdfc22ddfbd2245d94745192d26ddba891cbef61926b693e5f26ff49643275ef2411ff8e7eb73da7553b2e71b5b29c29da03b9d5b5815ffa42f835a0e4067ee70be93c97fe24818938e86bef36e7bbfab9db2006ae08405ab0f6006d6c73939b424e74c58a80018ef37d235ffb71d77e95b9eb19e499f3d340a413ac166e75cc008c96112413ac66e4320df13916924c339ec8043f83747dfff31ce3d0b544832442257c22f5677c4832d1f8094822f4693c92873f760a754b9c18ce4a5b8767e4d2d6b1b93ea8fff320d097517fc633d59fe1fa5ec6cfd76792f194a4fff3959cf1f599683cfd195f5ddf8c51fc1933c807c004dfe4e2def591ae0f687c8df731e30130e36bccf8a61a4fe339c631f139f60160b453a8fb1ae304dd8c91c6c81ceb7a5ae0f77d4ff8debb84f87c8cf063901a78df7ba3ecfb9efffc430a4f4dece8f0c48b07761832fbc59f47149072478a0d5c9ab040a5cb192a78c42ca1ca8245d50e3bf6d79420892c35587cf1c50ead2c5492f8f0c4841729317f2bfe8f38010f073883440c54a88a18c2ca046638a4a9e2898a144bb238c17295a44e93246d98cc6ce922cc08b078e12a26b2d17c6868e876919743238883950dddee7f55ca9143fc3aa980294fb0aa9a2cf14591189e2c31459c2b80c0e14bacf14085e1660d9d344a7401c68e952c29c8004395113c717e24f7b1f4727a4972564ca18aa9157098a289162a624d040e5e6210a208122cf49a7eb19f45187a2375c2c8caf366aa8539b166a24e94a821dc5ca19386033f88e9a207189240d1c4180eac18b343160f47aea809e2c995254aaca498c022c40622c898a952024587993d30664e921d5290810623bcb8a2c6ccec8a304f74ecf08bdd5c501015a8b30516477cd1448e101d7071a4cc14292d607142ac9ffbb986c25f7ea003669228628919138a9889759c2f44c8c0c2123b272861335992584541b3450a7130a006071a961002ce1739ac10c41552d490c5072c8a48c9627c030b761aa28d0f6fe24425a1429b18a70902cf124754e0328be2a598622a073b4dc08921c679a0a8d0408392333330f9007fc90c821b4dfa4510be39fbbf9c42cd59f1ff8694fdebc4450a2e4e302147ce162e311276b8a2031a1e92b0c148ccc6183150c000a686199ab09c19dc305901c91369c274f17190d3130a50c0305bc34211a920255eb0410c961aa63089f55b31c8c741ae7779df08f32f272579de44f1e2421d293dc4fabf5cf2b97a24da52c1152d5362ee203103556c088c2d4aa45a3803c417b105547dd1c31b2d50ecc4899d50a5c59a24508a781af271100e280cf0e104294eccd0b193c4112aa20083021e375fcac422d018d8c0444e0c8422c6ff1f2b4961f93f1eb5c6315bb85c468a933baf66cbe0f0c5752bac681d4cca9ab60e2675b060fdc6987ff9c3fcdfbf0cf26943b791a149e406e91fe29f83fd496ca5cf5e76b7bdab9797e57860042654a16526460b1129e4b0c5104b44a9c18b0f02b88282840f26b4b12185983fec09edca2ca4ef645abfaf568fc0605d04100addea7cec81a5e0f6fd7aacb50dc439a61115d968fba6c076b17e6556898737bea6907bebf028cb5150cecb06bbfa4252823975247f25ff176c921d30917f912fadbfe8c523a1699af6fdf6dd7bc041f8b9ff78946dda77a48cbd3ed7d736185b97a361861124a8e2c487216470c2664d163765bab431410918b621f5d607fbf3405236a4cefade587fcafe6edbecac2328a0277f7f201362f67b0b3c64ae9c4042852b40d029b26d1fd00bd687d43ba4ce305239602be653929b60173587ef0bbfdf4aa6e0c8d0d0839ca3d5fd1cbbaf630bfcf0c39f74ce6f8e32114472edb7ae73fef7db1804fcb981dbf63d7abe8784401aebdae0c3f7be45b2972148cae67fe0ab32f0ce1781f3b247d7bd0184bf92ff0b8cd9e4effd1c3d929bcf532804ce51ef04e291ae256edb9ebded03d6344df336e76600f0581907c5bdf650dd6ff44708538866bd9774fad48acc09a6d8bffe42cf3926a0d70017dce66f19d20d327f88762bf773b457f33009026938f2ce211a90fdb9e18501ee685165061db258998af59a254d906c61c78aca8958ff977336cff0e00f03a2071816ab39a186866afd1d2cc75951b4b6ab185e73a71365e1afe4fff28701f179d0af601f8e4ba13f8f28e9201b0b5e19c8395a93e45eb0f2bbcb9f2c3bdfffce9feeafe9af98c77ce248629d5c78c28a1916b600238c1992a474592305a7cd953b31ff178c091f7a15fde01c9ee51fa0e62db670c36a26043cae1b4518818c18f0b2c27eaa0c267b39e1c0890787ef25e555fde7e7e7473b82dd61194c09375eeacb2e90fd0019808f20c04295fcc14461ac0cdce14215e6657d28e0d35472c3f8a4ab0266c430fe17456b8f82bcff08f15d04f22902cd496522b8f4db5d14c9fa9bd6a1141695e65150510ddfcbf1c9fa776da76a6c78303c298238e646abc178ea052b5f5f2e4da1faf60a19e1d2a5796459a83eacd6b06734c1f6f49209a686cb6d341f8873ccfe306c6b6d28194ab555cd995651d4e9948a1ad9aaac5c65ac8c9999d9060a962915330529d87e9f4e2251a7f459c9a92b79e9ce4389f2642425de51411796ddbdddbdfd57f0c6c3d475865362d2c8a5e7e7e1461aa969da8f716964d2b8f2d20feec04b8ac732b5fa7eab6f92d21b7e309112188c07abd7ebb3aad2da604d9f3c6153e8c693ed9faf1d3024d81012c759cb7148b01d30d80e241852911df7e94b34b99394591816dd024a898d1428951615d4d9aa94d830d255e13df832f5e1bc94a2bd94faafcec18829c696937cc1ea3cadb556af934e6ff7c2b6fb3bfb7cc5a9f4b74ddbe8f695be921b6d24dde8a6342251ca836e55ab9456308732ad94a7b0a817456c447555701779d9f35fb0201853ea45b0176ca8823b67a078bdea689ef6de5f8386491ce713811ca03a188f8d44e246a5d7aa2595906ae5a1549194ea0e2febe7b175caf2d4993757ab5851847030ebc8c19cf3e92449a83f84bb17841ab45667a5b3bfb4332c73aa8451a40b2bf2c4ae701f3bd07703faf401270147ff10f1ea60a29e5f5c2749a04fd45ec90bb86ccdbd524ac298a87dfad7ebddb0de71fbfbcb7edb2ff67350bff074db35ff3ac692a8eb72f80e85b9d10a3bbcdb4b96d95b02bddc885d1bd8a04aba6a2535e8cbf96f4f57eb7c2290037d19070133d63edda78be47364610353dccc19020918234fdce83266872d3a78c104074e7b9eddd3d17bed59e64ff4092b4b0e9a3b565453535456530acd5c32a3e6d36c8a15345aaca8a6faa9a37a894bb594476165c94173c78a6a8aa7a43a8abe64b0cb31731cc7b92624833c79eedc8ef3f74621dbed4821362837929044c9212ff993daf96f7861f945e6d7e71c1904f860d9df49d707f5b5f74129e9f26fab29d49574b91226eaef6e8f812cc2b24cd2ff49fe142227e03245b125e0470de7a7390b21d064912505e69781340a7da77e7ea6679208954932f15392085792dfa9298359ea1fdc64533ffd4a9be833e99a01653fb595d64267a0b7dc7cec79468270cfe3f65f90217eb9e7aeebcba38c1a71b14d72dd3692d34696c3a489294768e1e48a33599c9254451d9162872c5d149956e018a1031760f2d860811ca214a1c2b24267c9d4d7455e368b65ecdf28462821042043f3c8e3e1475c5b17e2ef466f98971cd7ede414ac114a08014815cd354dfb5cd3348dfde946376d1b800e5616e49b085c756990fad4b7adc76be357a3eaca6422385de9edbb47d77dc7ddd8832365dafbd79092431c444467860d48a4c0822a88294ac4fac9cc123162a6f082c4484ca3d374d65ae7a4dd93e3dae96ff53957b5b456a1945964a379a43da5149473847959f4f2f25fb02fd98adc826cbe3f7d668ae4eb114a9847f45dfcf5394647ede9fbe0be924d75f2f3457262882fb7e50c4d6d69e2ca6077cc95294cd5d38d784c1053b77f0837d5e79e8e4ddd6f1fd0d71e84fadc5361aacfcd26fa1ae9e21815d59a1bd02c1104121bc41798b89282eacad40eb1fe2f2b9d4eb598b2e2d45527b283ba2858a4cb473ca7122c2efd40522221908694cd7eeee6c944632c2bd1e4e50f739f5e50a7378a9dcfaf438975d5e7cb7959bf6fbdd185485f5e66b73e433163ad7640f2f0b295a4d80e782855f1d6524ad77595fca68fecfefb8f6cf2c88ee4624cca4460800862d94c7252d5c4d7652ace96cc4288cc2b13c1e5641d70ba22882e58eeb5ef20dad70fa2695f491eae0dbc87cbef3d5ceee19ab1b0d965d8ec72c8c34b218e188195277ac0c2872f4bc4bacc183658d854a13ae225d6ffe5c894cb231503d94e7ea0d87eeaa8114ae81867ad283ec75489d0af24c7f8edf5ffd8dddd6137aab07fbd099624aaa83063e64acc5b68420d132d54d0e2853b317fe626b5439d7b325d77f71e9d2e1dbfebd3a74f9f3e7df2dc424a141723d2796254e857fb2ec42f8ad6725c59be5e53843a9f5677f7cd4b9db47bd39afe18e4e5d7b1759f8928585f1c5792378dab314c70db285801086c1d406d81988eadfb9a47dd3391972ee43f328e003091bf7765af912c6a3892581898e7738702fa7a041e73654edddd56b76ddb2e82090b58aa08218495392f10408b0c3554e184942a26318f9ac2440b175ea02ad325e67388c0c24489246fc03ce1944d7d246a7bf905c1c0cea773beacba4fe766abe90ca4ea68c11a978519ace370c2f60d291335d9fd0c9384741e6f9f2d99d3d5805e219de70612beaf0ee0c1c108aa21a8b8c98ab96f20f3d1596011f3143ef8322921f90492228889c0638c80f174b98d923df836e93da5dd7f9d12dbd7f30ef271c03d7f0f7e8efbee9daef7dce8bdf5f299bf7e03893f51fc61ee7e230b77124830c505cc9d386c6a88f99d27353c11c2c99729a862fe5f524e888f338062b5be9c0ad6df6a7e83b08c7ac0cf4f67a860fb4e0ec2affdc75b0fff5ac739e9288523e7e5ec5cf38122cc28c103174e5c49f3556040a1872252272089f57fe9f48a8f3e05462c5025937eb0b27f6bcb2538ca1cf84f265bb46a2c0328bb36a0181853a589138c80ea220f1563b6c83913c50b2194c41e7065030a61ac90c4912ab12b664c18220c385d6879220317ac8f16bc4cacec79e478c8bcfcb221d3e918c4bfdd9ff2e8eac1b2973c67b8c1f62570577b9edb36645e7fea0169b5215d49f0e7a7e27842e384a91fe64c7167052cd298e982850f79a6081345acff4b4ab52e957bac2a0192c9cbfee1657f0643580930fd70a3f1bb30d8ab2cbb9b4919ff6c61797bee32c9bd1ac6714c75f94390e7ca883c7d97e71113cbb88dc9cb8efad28a5a19910e992b7b7e4e083655d77dfa07861b4cdb420ffae90fd16eff5c62fbd2ff0ec291ae1e7c351202699a56291ff9e3424d7f5efe30fff72fbdef9436828f83ea1bb151e5eabf605ff2df88c1fe95fd3805d142141ca0c043840c6e62ad15f27cc123058b306e88f17ff9e69b4f01d40c52f9e3b82dc8907aabf70db23ddfcd4159dfad7f1b8368df97f392b2f75b71ce33333f07f1053ef6b1bd02554ddbb620aef3a837dd6baed192395dcd9fb6dfb81e6e7f92c40d44706521d8401f3dee031b0441ef033530629d948960f8411f1454a98f8f8f8fcfe7813e8254a08f61ab5bad16d716370e99f531ecc15d211db67a2c6c47a5d1928dd02302c9a0d37ffa87b7964c488fb53e61d22702f9843d7aac4f8c182c234c9201faf8e3eeeeee6ec59fb0875f2e4a9a11f6987706e8a34da211faf893344118c347b4a2d8d3124311143f5114454f143b4e14374dac229da28b628b7c8096ac0397bd5ca1eba4ec0365d9348eb0b2a2db93c99e5197bfceac8b9d6c1e2ee8be6e911b5110d65e24db71db49e6c260a1654d9e362470812887302740b903c50b3ab17ef6e2c5ffb7ffd9f291f6f4f9f905070b1fce0c21439d16e224cdae2041d3444909c088dcee65aaf473fec307fa0ff98bfeeccfb92b2143870bae1014ccaf301fcc18fdd6ed2e5bcc60820e2a7881831797053677aaa8a2c2093452f495e1c0c139c42ab4744142668e973a2a0cc0cacd9ba8aa2c1c8ad8c0e7ff2cdaa3d784ddbe1c562571029514a02c21930587165937e0a1426205c61b9f3e9d9178bc76dcb932e7d4c1a78cde210cb0e2421d2de08489424707a820b248020520e82011eb678f9a3e5f4dd8202f876e49ef0f9d2e2e2770644e16178eb48153e54a183c20c96ae189257066d49caf2b6c5019da575fd11d5117eaee1cbbebd3840a59a4d801ca08a07228819d2f5428f305cc149a46ca26b5fa2181314e49c8a04005082fe03ca921d65358614286239c949943c5ffb9257e340184541549cc04f124c917542eb081014f1348ca1f360a02f9489cfc6549a6d63b675041051628b3365151208ca9528526ca113048f052b84faa892e4404ee9c8b8a7ed186b1ef0400007cdae7385e104465d982ca1460686105a60a2b2b30c07042c30a2a689ac6815a7d24ff6677bfe6e6a6ad4ab2c59a3e1d8c7e71040abeb462065c24602468989af2226689355f1e70040c01a58cc95cb0c444fc3f208700a323d805396aad46ec46cc0cbb20878e1d18d45ae7053974803f3b400cc604d45a71e8a006781ba18bc9258e5caab55658adf53564c18e221b15200083a30a28802520070540b5561d19500c805cb5d60a72b5d60c9098f932738cd271c6baed3b1e3c6a6566d86b0af177adb5d65a7980f307ac9526f97863a3020a26033db3ab86264ed0d1f02c682335e3fb0199889fa332c21873ce3981986bb7408d6cce392768e7ecf169c50043f09bc1561e8d6e024edc5e5a8deaa240d30235d482366de3454403ffb7644ef69b985dcdae66575750cc44f3ca096b36bb9acdae665758b32b193de387db1123867d1f192433518c183ea4cce9daef9ff133f214c29acd66b32b0feaf340f0039dbcababab89e4eaeaaacc6c36bb9a5dcdae665758b3d915d6ec0a6b768535bbc29a5dd5ad6a1db76d75764565761595451c386fb0e8ee2b37596dae60d3dd575674f7d59a2ad474f755775f6151318514514091a6bbafbafbaabbafbafbea0acdcfa939f1362ab09382d9290071d3a652030041b6e48a767cf1a1c98338c1c651ad863d7c03ebd7d3d1b03effd3b37e72673b97df03aca3a54a20328473f4bc873085fc0b228dc3ff07d312e7f0a290c00e9fff7c7c7c7c62c4b0ef33fafdacb5d6c7c7bef5796b7dec8f8cbe61ecd9534b7d4f2b0c8108f86179b5a7b40cdef50d332fa7b40cada5adf40c3b3a868ec1c73d2bbe39eb8ff7f5775dd7b147769fd7b97727e11c836adb5052e9a5a7b135e8c75a4f33b5da559fa397bf7028350e7ffb3334c4a161391d74c0b4f443a97578f07a3180aa832a262f7f0cb50e0fb22c9665c05007552087c5863f20088220650bd2d82d3db5dad56fc95ff565387610b18e1f8d63e376540de9c777405ca8754c8071f86b6425652ca7024ce43f25509f3c2e3a2eb83a58db731dcc320fa00cb0366dc27ed3601c8f6d44aa55d3941cd63a30601cfe5e66c044ee7787ff3cc3cdce947adf96ebcaeec6a29797b0b2751091387a688e5389d53563fb6f19db7fc950f03e61fbaf139aab03a53be65ad9fe4b02db7f9bf8c0cb04388307d2ad6ac9d801bb4b5c3157899ea2d74b466ba8bc5437cc4de282b95f6c5f24ec3dc2a505fd03552051a480fe58ce91c60678bdd8fe3b654770fcb7d2ce7cf34b0ac2f6653250585df6d20067ac4c4433490b8e58ab0ea9b0fcda65325c88b94870d472d65ace8a334aced3d393112d8e582dd0dc1d72bcc8d862ca9c1768dce931e2632caebbbbbb1d8b0b23b7e75b61520fd7fa304c6a8573acdcf0c13029e4ac7765e0fdcadcefb9394beef7bc0517db3d93b95dcccac1a28515d626408b17383bef7c9b051171b2c42d2beaf674d8a48d366f8b5c1e29bca32ee238e1041ea8286ca008c3041131a718b290810e9d2c4cc0a14a4cf69a22891d2894d8191346ccad84c943c4122f4b74a813dbe1d36189269dd7be27cc1c57063a71e97c0e4e1277be8df3f446ce1481ac0871c1f56f581022993735d437dbb66ddbd35a2b27132beda931939af69ccfde58e3346d5362a24dab9556d752f85c1bcccb3fa78eafbb187957dc886a2182737cdff57cf7ecc91038cee29058c65422ccbe4affc8bbc56ee92eb722716763d912e6f60f5c562c4bdcd9916d8589ea0f24f0197bc653ac58b5a4665877f6939ca727a4d798e8a7164ca82da0509d8b93162f947c3933664b1830540022ca0d557401e2082eda3c418200df940e4cc14203104bd274a9d3e34d0c39ccae48b2c20fda133a9f94381bed2758752e7c87ad388be5707123e6fa87d04f6011547c424255889b47de0785cf5f0a718e9ecd44ddb31bb51b85a4e842ce8105b73af8165cd9518cd79308070cb1431b26cc90897a2a43a7091330593e44916707cdcaf7e5c0a63ba20476be89f5840b379f24095df8b61b362d8b0a2436284e2cfec268ac90b860892f8297c9b80142fcf182a77b7202124f8e38175a15f48a70f220861a88824486333a4c3163c50988999a19c2387103250497961b1cc417dd48796eb82d6e94706456182b7067b2b8b832ebe6889a52fcb1a4ac446345db73994c96125756be9161e587cd8a112d6deba71d532d59f9dafa298bcbcf653259b3cb5d269325a5d581c2c51826b3bb30913f4fa1eea6f2d2bbaabf547db11241b501c57e1b888027ac4369afb1b755961bc1e93b1ed5565ced353a5f5ced899bb7c3aef2b9967378af91d0b7ad984853c244da94f2529b314c275e6ab2e9e46aef79cf7136a058eff26f70805bb7aeceee9994d450134d7c36a058eef2db80623598a6b5aec669da0779a93d47027d676085f6ef475d444c1bed28a2a16c7aca3c92e2b695152d1d0544899cb5542fe9a73b1da3b1fabada43afa231565666e19eefa573920d7632bdfc9242691b37e23577cdfd1c9cae39fd8899e021012c3856b4152657067a6a62b832a65203759ddbeffc1e7ee708770825b907afb9fddc64c84465921c84bf92ffcb1f9684b746e7618a893bb1d0c1daf3fddd14840064e9c7b746cf5a72e629168eaf2bb117d19610dc7fe90791dba76f85dffa2408a4097ddec1f7de87ba530a4ed1a7ec75656c258019ac8cad469842fea1931e69255e01d060656ce54173cf91b28d243130f68c617feea9a9fd1c349d8797fc7f95bce47f5d61fbfd88a73ef0587d59035591480b3f8cd90a8e8f26f6d1c4969b9ac73ecfdab8f7c8267f6efef64ba4d87b1753d7e1071edb3a20239490259595f58229fdf0be39d681f29efb6fe4983672ecf3c611b238c6e6630facf77d41ea799ed669da73ef799ee7799ee6cfddceeba78672236f86499ae79ee64da73bbb7b6e7f57f91192b70e7c14f5c3922db75bcacb6daf6960a17e1d6e776fe9ffbe9f238184d0c562f1e81a9afdcee08eed79fba40f6fe48d75cfdc6978b6c49085141ab4af6192365a6e9e778a0d3f46cb7ab08e62901f87e40dd537f4142d1ed9b31b6eac467654177db17573ba728368dffd367263f7dac8b3d9cfb33d998350a5ac67dee8df51501ea1d1a864ae564435ca10dd08032000b3140020180c0a060482d1603820689a247e14800d80903a74541b0b855192a328ca2063082104106208218608cc8cd1c601485244e28b35ac1a40710843106203bdd8fdc8ccc04f0a9e3caf6e3ef05d32f64f27afe5b1122667bd452a94746e11160c66d5850c102f2d3616a817d6f1a998a948868ae5cb3a90eb0a884ac5471715a59598a723a6199e44805dcc997fd852744665209e36de8d939e09cca72a264e3b03fd627921d29c3eab2400e50ee4ed98089f4798280bbcbdab036e82596240bdfe76c61b6af9506f6f9c488b5a1ff4da8b13dac05a5d536f225a30a000398d229b363beab23368517b52c125b3bdeda2d860ca81adcfd29d1420f262131633a10988f9824f31cdadb0fe3903d09db37be63b03580a858d94c13bceaeca743b561cdc080b5bd1025e40577b560a954f3dd18e49568afb0ce5508f584939e6466b03da18cc5ca6713e12602d2190e07c3707ea02a94726130a2ca2b69ae1200410d2674291ae86d70d46579d86a212d1ea9808148bba821a14e364237e7cd23c002d234cee844b7fbb5f818e41d94bcbf3a80b138c9bd60e6e5daa0b5c64c252ee00ba1d75d5a6b1a2c411168a780ec05d3cc92a4a0293e79f5233407a439ce3cd36084c7b060250f818dd7cc605a26d253688601dde693398875807a1c77949b3049e934b1004fe6478bd51d350b3a21f82fa1a3346c4264a4d35db0fdc7ff9f241f85aa5cd8384ba7f7852a72bd10e5498adb4d906d2785196523b1c3ff03dfe5b0f52435cd3f343b8375c2aca17d3315759b14764296d1c97590510ec3f428f32052dda600b43b0e50d223b2e16f6ba7923b57b8c5f586f240727c64d481dd26cc62007a73fb3310673db0fb945f3aefada0421eee7072459fd1fd7360563696c715a2307a081ae0ad0773699480431758016348c4318c0b1d853268d960891518a77b04d1fc096f498346eed3fee94362c51b879f2624e6b551163778a091451f11a2b7b701c3c0e8e83a71d8c1d672c859db4988d170e4f323c345779270997dd07eed01e8043e340c661ea0aea247963fb78cda1559a6c906b505ee1c4d1b07e25a68111b6aed9b2837fe16de6e3e9ba3e48c7e5eb1a1f0bec96c93f0439233b42e74ef2b4754c87a5455da79e0767142f2b24e26bd46523a9a24f447bb622d0e3759b6ef09a8d1bf0b51755ac94a9e4c4aaf4ad6e028814a359e79d1a6f1e9a4381499c07adc1098b8dd954525bb65ed24af1cab05e516faa9b69f87043ae6db9c971330d924c5c4efad515167a5f3d85e67ea467bdafd3da2b9cb93f8b31697b7cb8ca11ba2a53bc66988cc1d142ce705b73e372ebe246fd5094cc648d5b4bb1bc3839d46bb9266195166f0613fc9120df148c3a88ca325ae60da3b2d6b863d953948f4c2287fb77d2821ef06bbf351023a6fbb6ede603ae4a45247c322d7c68dacbe066e426ac3ec5ee351b3772fd861bb91e8f1ed24a919565112696b3523484bbd1e9268dc2dc88b8018d6137bbdc40936d04d26289e903ad2e0e8a9ac432b622fca58e5d82395e6350bd8dca37a359b64638c425136c7de1053a42dc8e58f5251ae18eda27931ea99b6a6cc7090d0e77c70093950ac45a992289b045a11a8d51380411b622e640323242ff00525ba361fa5e59c5a7933f9930bf005355a3235949981f80a9ea29413d95e95359acd58093b0a36719993e82c98da7bbf88a5d985e4e84acbab2f9f312f061d1d25dd9cc4dc6269b616afab15ebbef7f747126514e56912a79ac5057314ae8ae899f3f91d4821f913370b5caae70f7550cb50d12bda09f181c5a86103b46bb81817a6ebf40b8f328c35e8d19c341dc2f2a64b2e262046cfb865c0bc1a0b96da6930895221a55b5851ecf9f520b0550c074105a24ee958c01d9561a5d4389413ba21ad3cb8ba507554c0c5bd04d16d507ad5000de701e05dcacb7cd27a1815b171dac5113f2da235a18edf5aaa612235c4cb5d66c1840115cbc329e4806bc8afa0631d850893bacc499ed4e3f20bf9fbe002a2a18bc42ea1b8ac188a1aba428e23f506f94c95957699bfab72e47ab9a5e46fa451c0f1358233df327c6d2c62f01e683a3ed54ff637f138b432952f2d999889af870a7b67469247315b8f1b80b1243e546ba793aac6da275aa7730f1d91fd382e44eed7db8da0d48dd39f2a96abb21b92a15f3177610d1b90895ccb617ae6d204ccdd98bd7d077cb150ed808d2a00a60d7960f11a367fb04a87a5494d82fa6c02f5451ff2dc45f0c24f8fb36b94744450684439109ee664e898c34fc3337e5647b79def320e6c26f1223abf08b0c64ebb80a92ed9e585c68d005f710bb597c1efc7da604b7e53e7e2bc0e0ef8af680131b440818d34b01413012160ac880b7a61c2834f81b3df9b3a275b4d519138db07fd6cc01ba981df4b5e84844ac6c276a03d74a90f701af4eaf9dbe9e29df111185e16650191c35a63c9b671ec9ac932a0f59cc8d8cb2a305f92ead9195dc9ccfb8fde428c945483d8a9283ecbd1efaa4af2b2f5b593a1b9244e1734857fe969310693bfdb5ed4cb13410cf630383ec8e7dbe4a87a91d5ea78bd76253e00b3c07ebac68182753b8dceb5b16c0eab2ed2869a03e4de001222bc3cb11389edb3f4a7bf66601270b97ebd9beca42de060eb8e66222420825a28a7a262d67d6049b1aad1ca50906ef881187e7d150be37e5b5674240f788c846d1e961020d8f0fb6294db254a4a82b933a2bcbf69c85ca45e108042d5a0ccb1ba4ef477683e112e15c02b49cc40fccd6e0a373f325b567e07b902695c0e40dd25f7c19bbdb1b671fb850a4dafe4da2c336bcea52f4db65254f8c0bef9387d7efea94d99f622f00e40833c4aa580cda8fa01d604688e04d2cc4ae9b2e2f0ed07639543921e51cc0b8f5f71abd4b7dcab18804049191fcc94dbf52c9a44deb9df94a102e24f9dff6374ace789ea6fe1a6304a9906ef65d583f9f8c868b0e7805ef30275aab876819b3f77b730f55306498ca2e054f0a82dc81aed069aed06352a953dd14e2becd286fdcede72287383c1106550c15cf0dbb0464315478dd60970216f3dcbb576934f532bc73a5b835eaec973303e3bb77acaf261684ea29c5ff132e6ccf53f0e06da905944f763ff706fb38dbe1001e2edb45a1819ba06b684d5dfb3636cef50981ce322acb937b371571878e5abc2102cd705d09ee9211140c6a1e0050834c46bb376a30508f46d5f36d9fde6af8c2c8d989bb5e31bc7680ffe254739dc05dc7dda2dcdfdd137b5b1eac490d0ebc5fbb94480fbd3edff9be3a96524728627d67386624d89a11208e96618b8c110324c99dce3867304df18328b910f6e1a3e3c01ba37524433101b0f5f2b91a3a3d5a434062c79ca2fcbeeddbf2e0ef13d31d34c523d362895eb0e377e9c0d7f8d577fa61c1929aea196ecd60675f2e18ccf35b5d6063e10812101e162d0721202759de06daa65edf8298bfcbe19a2b79204b421e4c63c1a0bf1597536de94057f689d460af94225b8601bab25689ff5b447add86962a5b0f3cfaaa3c9ef6bb39371f21ef14b46776ff968496d30720d0b99f25a8fda1546e8c475e8016d96e3cb9ee01b9caa586fd3fe1405d1a6a7f1ff71c2108699d67051f2d6ad759b1d279871b0d33158e2a90ef970cb7cdec6286e298750a8f0cb3171d10eff373e4d3f5425c3db5872bc044d8a283f5f25b93eff4bdea1c1b5abd9ad11ab4cccf91cd5fc2943159313ee92bfaec8a094273ef5fbd570a3366ec1f2443a3f1bcf17b6b65c3b208a3bd9237002c332a148589c967542c4cc4490c6336a5c97a0252c7bb714276f1c6936be174ace4d80dc437bd76f1a6dac0723f7496400c8394010b7bb81a96468824354382cd9063c5ce22948f2c4ae87c243d7f90eb2842bafc2d55fc43520516caf4202a208b0c391a3e9b2011a8fa9a01bba10f03a0f10563c26329665fa5daae4bc31e968a4103506f6dfe6e1d4b3d46ad1db675933a3641bd778ea2249a46c50e263de53a96bef2ced11b86aca7468128e75b1d072ac74a05fcc914453af634cbc0a4b9d269c194f167a070cb5f266f8924a4bf51bd29391c09d476336cfc8d89286ef2d46825134a66510529ad1b3ae5746ac60447c020c4959e37a4c9bb386856cab01d1c4d5a3f1de0fd60a61b06ee129221537b7e041dd670e735b5599b0453b131b62efebd9290491c1e22b5b01c365a89ecd508dac118c379ce3af5f6661c4ca7f9865f8d82d7bd95fb0af06e94b3b3964d0b083381e18b1cbb16692dccd29e3e520f791f1dee7f35f177a65730e1d6bba7fef4ddcb0d2dc3dc27349d550e159ea01484af2a1862bf14dce299f12273a0ceca14f0dac4e0f1f993eaba5fd55adb8e051b0ccb4355588e1fe849ce602f5fa09f9864e10e41122f722875716c8bdf4e0df886707971f1a26a39c99f4db1909e5f98364b53d84379a11c51e60a3bf636b30657aa41eb8f0be9a594c26d5429554981f5479be68d185677d643d7d5c856b46889e54e20e4911676c3453c7c829d8559ba83aab301d1d9ab3616bb7744d9926921971375ae11268159c7fe916a5ba6788cfd12d73b7de199b7658cfb12a117a6519b5d04198693eca870168e07a2b25d885d462cd32bf99e09948cbfff3277930a79b3a0f0f15192840abb6a4b006f386c44332b2ba90b4c57e0f96a52d4513cd00da99055818253e1efc1e3564157197557945b455f6ab61e8613587d3e33318d6ade7472ddea3074e2a29c90e16808ffefafeb41868a05f5a1f2819a800f6b493e8d43528836112222b700db3e0d861a30d9efdfda27e8fb44637089c0933c8015b85b079906a1e0aae0a3eac0e02a7e8d089083ebeb5f8d9ce72139d36c8253bb634da21e65785d2a03f46a9ed96a313fa91a528f5fef7d690f508808ccd95875a3734fe8954b0b4af31b176d546414d93fa90c2be74ea235c4dd3f3be1ddedaabf750a1cb45d18b1f582dfac660a9f9e64c8cb18823b4342f665ea7c39749db42c915f1144753524788c4ba063e868f8010de2b193f4fc0fc035371370008f5b4352c72b717be16933684f7ffed89ca3dd0ac2a7f71c04bbb39231b7ef5abf56c54819069c929348f6323fd10fe6c3354223d2c45b19901a3f2073ccf7eb4e56efde7164e4722510853294539f6ce4391495b3979a489b6699768c071bb2d7090ca64fdb9a573809088d689b0064922d01e20b00abc886abbd6fef1ad3ebea920f7dc900283830517fba8ad2ad3e24ed2d205c96a4a58b6bc67b1e79f8605efe58bf981d2ff34ab3e50481c61dbbd1df428d66750938791a0128e66b8b641d9b561cbfcdaac5557c97c20b6b16e73d20912e7588c2e58821d9f6ecd16045cdb48a16931783674ba167f1130d1469dc8656290eae00048a8906c1249210840b2d013eebe4c849dae08985a53ed4e619d103c3c0dafe161d6bd32826e5edb8107b500a23fe93154eb554e14ce5b1ece7671f95e3f72d226bd52ad7fe9482907691b725b4b41bf5061fac27645cb899524ae2818b529370e5342d7fb6f0e72621aeb5ed44a5b08e35854dfc34f7c17df870621e61d0435c4b7f983d7974393bd260ea70a42aca0b5d269fb28d3344e9d253e2c3d4bfef3221fc90a20b6e5f90b39f3bcad744691ac2da5a822f31688ce1313462691e254b97efe90aa245b5470c8941c4fee0152cfcb87146ef9cc781688b8b801b2c9b4ede1e8e2113c5d0a0bebaa32d960d8336367bd91146932c4b121e84d523fb7c146b3b805e88baf4168045aebeee51b4943df32894dc821131fe4d00f4cff0a0a14165556ceee211eb51fa55d6e473f8c3af481338428211464a7668dfc7cfdfd6690e593b8f2057c9b791d0937a674cff53e842e01a778f29b3b17ef1c1b8f0aa5f7705e4f8f5881096f6c8dd3633a1778cb0c5da981e9981b10117448f845aa662af6e30fb7e1282adb987bab7f8d49bc03979f3f3808579871edc7baf35c7ff20ae23c4dd7916c3db33cff9a3ba44be4fd03dc2c9476e0256d6979ee04616c62ebd200df96a693056ce8ecc4bcf830f9c66c8d713e34aa5b69e4589475ae5c0914ead3dbd60e18f02366d097adce64421df3f77977753edab047f6f6fd1f7152b0cfd1f225927ee2006a024889f1565bd07a47017b36074d805be22f428c76a3067c53f75879e5f4d4d65cdfee0cbc6ba5220b86aa80898fdef77ed97d0a8c9b4f1695886a679f3a078de7a0d6b2091aa898d7ba108db296ab30b326c96b7931527ad0a25aa6fe4ca7ec106dfb21af027a9809f7922dc3878c55edbe9d0ec0591b60126b0ae8c013a20c8270f13fe9f44d87d93e4d4737d0299da0acb17459fc266da3c05bc04916160ca9ec597f2b30be587f85e3153b7c630a5e3c2a72b33da8db443fa52a68a827420ecfa25ad69df9d39570db0d33bbd93e97a835aabf4e50c1c945782de33050d80845c1083e5cfa49957eccd86542dc01bc6bc52ce235dd5e99bd4f218d16f0b081138c6a7a737eae626e0b3959e33d8dbae1727954c7616ab8178dd83f158b582ca38fc14a8cf9ecbc516c9284a2d211f3c1dfb88c8592fa10f9e23f30496b1e52631e55fc1de331305c013627b4f484c99fd2f9aae8f8be38f55b513782b5616dc94140bfdfc2a16b594d13350eb779a7140208b8e68be9e4b1cf0a06da3f21ad2108437a2bcd13f3d85438ab72d319edddf0ab1409468e40dc6c5786fda9fed56c19dc3399846214fd4a41a188eee4707844c4cccc1ab9498d7db1ffca7500a712306fe494d651c26ffcd198bdcef8701fd31075be710061f95490eb7c588e6bdc270446afd54dadd744b526f0f8b4ec3133c0f2b14d8d988b880b1020f54f2ff768a60c50bd25a1977311846c12898819ee9717a7a256b01df081b262718008fbb048ca1a648b348078315f078d5d8c08ea4ab013e62397c4edc00cc41a83743c52e477ddf84b59bc565a09fc925850ab111146df58f8302c973a296c64747b345242a3632370e9e88ef385923e8a60fff37b348511fd93228f76af7b2c20dce5c6139dfdaec3a4b492737d282237c111adb0b8604b9daf22f7bcda693df990116d7e303d8e32c9be8cb5f8babf9a6272c6ed01a3a082cc3cc0072a55d79da7d9627506842184a666a826fa1f8ebfe44579af3e5382030fa00eb8bdcb3852e8f0904f530de64ecc16d8bc9672437d26493c4670679bb2a712ffacbee1807a50ca2744640585e194893d4c4a6089082e5173ffff4be765179d051506ab68c6f09611601152342af063a07331b84ab90c19b4b828e09c1b8a9caf3741ac9a4527683881a43c98628b32350848252e49509cffbac7bc94b043a7e0c489fddb448fcf9a2a59487f98cc20e4dfbb69d11374529334bfa9a61418206b0aae7c0ed42692f1a3c0c390c307289a54184f70ab8817bec81d1ab1c910f1636a290a54b12a4f3138181d224c53a347a78dbf3f7ebd62051100160ec29a3b2b98b5bc781218d65b812f2dd26b55d8f4a1469af6cbbd7c21f07e0d8c201ad74897439c9fb669647d11f659deead678ffae12edf07a66792645d3749c81d37274b19579d6bfcd7ef447228213148c04ac1792bcb9cb02827825db8e9ca3abab681e83745e3ca292e87a6077a6fb79b96994d0037b11c5a6ef32375f19d748da8fffe82f355f1524b4030f1b9687c53828de4ad18ababcdbc7bcfccafb47e74125a0601980549bd0b1a3a2a0c585c7e73f9042c996d4cf4edb26781e8ed011428ef359d0c5804229a18c518ae37ee2a0bb50ccacf01c406b7ff6af8babf0e8a7913f228a1fe83fa8158318ebb32274839d85ee08ce7920acd84746aa7ac867855fc08a5a9974d376a7586bc019e42334d21c858bfa8d3a28fc990dc4bb48c5ad190b0b283ead788e3a1b3602c418179fbca5948facc16d6139602da2c1e052bd8bcd112836b2a2818132d43110756653f465ca21ccc2104b8232889fca97f1717f78fbd1f478c16942a4f5c11fe9c9fe8225cd67e0e13a28092e79183e5cf1904316cccb7af46c99600abf6d34cc3cbc47e26960158fffa91598f20c25a9819c2686a0eaf8a10dfd362e5010805950d479ef060d17920c029fd0259f865cb99e7c7cf040b2f07957095382702dbcaee94a8d3b849146b2aa7152df48ada73e545b1929db68df10ce27c4ad362ea2763da652881ab260a2b6aa4060ced006bf022b4880daca5f270df904922ea8defdc57f0f87b2cad42f640a546d4582ea0732b1cfb973e87200a39bfed500ca9fc1e3599fd852036ec240a255f0bbd6de66a9367bcc1216f34441ecad012d5efac5b4a49cc0820d0e70a1f5094dc2d17a729e6fc722c2c645937a4de337f7aa27e40ab3f90c2573da5a7453affe88602abc56abeec33c05f6bc1eeff233e52ba8e8d5ca1b5a8941ea4b087656ad9f8c7dd773fb07d3ca0b977f6d9add6492fe7b5411257ec7e6e7a3f20b61cf10ab88cc389bc6f3ca11b87ac197f9e1c4090f22c86ce0525b2ecf3754f99e29e4b407205beed200e6528fb6dd135da161a0b6588b46e8a7bff1070a90ce20313d89cb7934e35562a1fe39c384a5ca784220abbc3e47fff101536ab0534600663fa0b9eca1cabc554391194b148f4950bf7e2b171d5b049f6e6d31ca9c01bc2ebd366decdd21a5b99b1a25fced80b250a0bc90ff03a695ede0b536b389c6a6b4db5f9046f11e4ed178438556428c170d1ca14996a3063d10c9d9ed382a472dbd24193afe2d1a13a12452b50a6b3db01614949ff4a097ce44e4216c668427d72e46d03b30fc13b420cdc72e9839a361d25c066e3faee7a9365041c77dbade52124f0c010476e714091432871e05169e10ae5dea6490b70ec0d05e9dc0ca091bec74c1e4b955469cadabc262a4f3125ddfbddc45780de720c50fa870331958177fc86750ad8f579d3ff3ee143007382f92835a0313e067207c880fddd87cdd93096024427773a21d86a29881b9b0abf1915fbda498bddee0a6a623a0eeba3331fc9c2de703a66e2c7700b87e1f857b1cd5df0f5a37d4eb3d8250b05566cacec86d808312afb1d6d551f7d3e48b91b9f99831f1f60358ba3fc47bfccacb9d9e5fa5c1bcaa5beb9d034acaf1b67d01d30f741d74dd5ad1df9fe733f64845fc0914ad3875443ff55243970716dd6f28d614a08a1f76c2c0987eedae57d6a666cecedb5516ce827061d5d88d54405dbf6689a3ac45a7f382e5885b88e2cc4a831015a436a571ab0c1a243c56980388607689c095628b8d6b5af561175d9e7e59f7d7b5c8bd9d73934e890a131ca6ff6e95b47e8b2aa8419b8ab73b0d26c60ce9c472dce57063b0b3825c69bd5f7c2e919f55b3befe12ba35106d455400da7cde5ac8df1e39182dc509010b5cf7bcc013f4a524c7dd87da2ce8b87188eddae093166398bfd044421044a5a145175a97b61684b6090c93eaa946cc5771efa9c445ca7a58b2a48fc8c2075427d0129f95a1d1123388b7e3ae457057942d38be4315e89bb70b406f8c39771cf5911c2d04adc82880d0455e042b0680deeb57d5025220aee41cdbef49bdf6b51e8efc9cd69efa57f2f5c4e6112395c6d9c7b6117f07aebca097527fa80800501cd777d6386ece1646e946f6249f71bd6437e53043516b4dcb807ee7058c88b435bfa3010eb860e1afa555c26ab81f4e6a0e61584537fd76922c4e8c17309129939f55e840c562846ecfdf902d0c649984b8610cc4a7de671ebe75a2f678d565687513de83fb0df11b4a76837b3d7566ae18325d9ce084e0a52ede90c152032dd0bd480db24adc68bbba6816e9ced3947c701e7a8c3d45836b41b89b48ba92911878f7f7104e35fef82b892f1c0c77affcdeaeb7122c1e9c3e8ff914c224c2e5945d0b2c64e7a61dec2a8a7ebf64ebc1ca7acfcae30e6d10f4bb536f24dd14801afeceae611792762460f2f35ccc794f5340a85f88e3cd2a45f7823e8472e70e34c944ccb405a807b57dd2d56dc7d1fca2ce175f3ea282f46e9521b8d9a8758726b62a821a87a4c92e95bb968b2f5f698c011cb9cbfbafe864f91d2c99b107e184e53e8146ccd0cd99a029ac7946753ec0981454909cfc97f40328408fe2f52ca40f3133f126cec0090c6260746377095fa3f1809daba69f0837f2bfd0d5db4fef1c188a0ec83bf61935c430df2686036b0e01e56aa2e0f533121d0d5bfcb53d3acfacbc8caa5040a6186b7f748e1acd0d91b365a822e65279544dd653735ddc4064714b4ccd38724f6829f058083b2c86dce23422637622d1b7043d87511844851b5fcc62f23a4cccf119302d54548cb69bc3d264004cb4c530065b891f8ce25c73cb848768a16571986630ff38712f96bf4de4bc7dc3af21aa9dde7548ec73340a0e549a64f13933b5abb8c28e4af97631d11414e7b9be40c1eb77b9ecf4be0c206269b38cd422c78603fad76bbf7760e8cee8ab77b5a78ba96713ca0e9b3ae8190c4b78a65539cd1a4c73636819cd0bbc1f9391a9582ec4668888e4c2c6b424bc4fe6f013a3d17606ee58d7111be021acccb19a4d2e0047a647eca360ddee012e85a5a19658f86ea06f37fe1b560239e489bb74b76d97c66ad640c4d5809eb9a2581f42c1e0dcb00c9d0db840b04b140b8dc9525c3bb73ee1be5d9ea49cd7d577576cefd0a220338cd7da482b1e5ccd934a52defa8c04a03a2cf2c677439e2059bdf0c04ca9792561f7708be81105b2c6de8cc0e4c9e7e5a92f5aafc70b0b1095abd63de7a23d64697d25cd79f781bd58496689890518912b9fe4708286643c4357804ea66fd3143da2127581bf961d650547e6e24e487e8a859bed18187098efb62e3ab9306b12f3382424d3ed7018b48fa5eb2cb08e9505370baac810c8c385ae14ec5fabaee0088c0b7fe0a77d711ce17e5e77f2fcd1d82a4a3d3bb19af63b3b010e8b3322c861764e8480abb8901ab5ed82cbd35c78a3b13541d9872603d375d891e724686be08462466636ccb0a0f5ebf044ccd8193eb222a3f645795566cac58aa8871c94ed46a711449384dbd29ce6433da465af9d913d68ba9a88d488d498595110b0847c4d841c0982d85b74d852307d4bdb8d61148e40b5565ccb8657a395c36cc1bda682ab3b1876f067dad9c0e102a9d292ea6e774113633584593534716f7da0662d15b7a8fcca8af71fc7f2edf75847d83a09a9a5eadeb7e788ec594f89523592a6349b320550d6e556e91421acbacb6c622b0b98e55bab68a61a0c782c4ec3806022d4d532ba12656d511880755dba6a34cf93154da6b757e024576a434b78e0ca0e980430aa2ecef100a4b5b8c071e1830ea72c348c15b95dd7b53d0ff66e801f98834d756abaab4128581130aacf0f257f5eaee62a92d7bf8543cc8e721b1b0c678e08307336d04e18c0863365c624276ff930ac0aa3a689a9971847b0448368842c5a97a504240b43bc79320160194259543e91abe267b70bda8a6d1dd6881d5837c3b3f42f89b4b4860b314919a05bf12d070ec0042e5e2728f635c32ff031bace5aa0bab6920860a867cfd0a9c41b96960c3aafc70cb8692ee83ae5ce68bb405de4979240e3c5896f031ecd594d0c02b8b9b5529d7a214cf209690ed7e180dffd842ff237a8d8a7b47d03a9e8a5dd104027cfcc31648084a8225d4d9b0d5b81f4921fe1abdc3efbe4f7670f9b5c7b44a896327765c55bdda7c04c0c67c24f6b15830b480399908a9f339288b6f12b04e679522b762fd6ae2fc0128bfb36613baf6d082029418378b016bc11c30a03af9b5e347202cae7fb61507e3acdb97614e9e598c16f444625e036694069a533aeec4c31ee434f0952d803147c3b68bff504b0cfa5bcdf77b0b8b184e74eab949236c38f61e6d5798abaa6122ddc5e3b058f0126fd1ba723b2105fb74d994557aa6101b1cfff42f5b3cae99bb6631e9da877a79bfb57240fddb481ba29e750b244087feecf2727ed128723e771712c6615a7489420463574830114f61df7b3cf7b824dcf5dc604ab32dba66109b6037a1b91b8e4ee276607efb653dabf8a58e1f20e12bafa559701b5a10678ea1c2ea8d18b5cd544194092a541c43843b01ad80a34fb6b553a0c011d91b143a9f2024202c7cb9549c06891ea804a521ea57c3f45e1f80f144a3190fe329728460f86cabcd04b3c0a303fe924557a1b6ab33fb7ab1e15de5b374cd7859507ce516681d2a08408eb45d9a20292d883d4fa6cdaffd53f99d7a0b47c32d93bacf181a10ea8b5500ba37d9eed4a7d4a3a2a89087498536f79e1f0aec7cd4d13542cc8baaf5d19853e94ef0b973fbb60f9d5f94b8d4a22993ccea22fd4ac7a4256ca19f60ffd149a9cb96d24b3e8ff5183a2c6b40a7abc14b568fda34a04a68ad5e906c40597394a263129943211df877446d6276a99294d45aece254e2fe9c98aff3c38a42faf2654ea47e4ab2e56823e8a6653eaa3c9f07e7c8ac65e77e442ace5acecd335eb470ccc9163e62a35e1e7c9b630be7db240a13218edb4ca7560e6cc6a4156499182052db31f4e6168117389c4925fada91d1e9a87518a7a9f21e1e2d27c934187b53614e477eabb8e1ebaeb204d2330c44a2c5652f4238a91054e931641376739467a0a4697aeee44070564de48695e5ba63a6d7fc328b4a7f6bdaffe1a75451ddab72967b854619227e2b7318a7885184bbf18b0e8007440b1a5751ac352341c428a373ce1bc19f59e8692b4775ab1589153b33dcee3a9f72eb951d59d806a729cfafab2fa3092ef0f1afd803890c7b71173b9a5ae2aded56443f7af1c920bf0282cffb619313e7018482ac8cb5d041d396c8fc5e0972ec8f16cf824e575eba3913a043c368c3589bab336b66a879f3119450065c4c7bf14547bf710ff901e0732cfdc35aa8d3895ee5512b70a3e47d67f7f70482c7929178f7d28b26d9bd2b81b78edbc8c9aeab4535a9cb8d7d80036915eacc2c30658e17e977f9552d4776b29919f9dae8390296a1906999647aba8bd05f0d16222cc69f960cc3a842741e39be5bce17b580eaccb8b6d36df95ded223f0813e7a27a085268f43ba903f42b100d79e8187b5bfca3654294e0cae2739d6278460834b58a21c863b42f8606ba66e1bc88fa102e56cc872650d0ce35a28150cf911cda99b3315328581366d30f4bc5f41621bda2d2d96cc4f8fe888a3daa35dfb24acb168353245ccadd7c02e80618fe1b710d788de60eda2d25e4856ad1cf73c898516df05fe50be81563d06e4521f3cb4bfd3aeb62ade0539f62fcbea21e00107f2571b4dc206539da3d3f59c5bdac6ff84bd4f697cedac0296bc14d27b24d51b6d1ec3a20436cd0daad13915dd84a9033b17155d055e398c27e79c3f1227fe4f8ac07aec976b2a86e778557b8db579f05e6d17a4cd9d7f20e295630520f40a750c823a67714aebfe05445274173a83d053be484bee06a9a62778ba9e420d640a3751f18cc2ef2b8644380d834a21dd3a38a1653fae9953bca4ad99602ef0bdcac021cee334297abb42517e31938ffda68a7183f8d6d60b89c2205b1d1eeef8084e2ac292241726b3fa24b9dfc2e856fd4ebb43b6fc4f6c515a2ed6deba619d10f09bfe5c9ccc0fc284bdff20df1d6aa31fee2d36178f3850ea916968a8158721dd706b2d72f579bdb27111b6e7bbe9cab9a312fa1d8586c82e9d806230904b2225ad97e7ecf62cc7de056f0b24662b3170db766b2770d6437ea81efd7519432ec3947f6c3712f3f6468a01ed50b725f147b658cbc9638a9388ab71120d5384a1a198219803ee2259520696d38a73efd6deb990a3cd5d9a6c455c3510ac303e15ef1702ac70744bc7b658ba2bf7f01e28a3087b6800c7899905b8e50ef2f86fa8eb89d15e4a38ff5b3a21aa1264e8fcb731cdacf8304482fd50570774d7c9c9c678252733d78a3d680d26ca3d927ac91dd5ba3ec72e79f62aa21ab0081dcb853f29dbb184322c9d2a50eaca96535288f7eab014636eef30d498806d7845e7b775daa3b5b7c861e71f3818fcdd568cf20009ba78a9e5cbe856e876da9a18cc0b0fdec57e82cd8af990dd3c361227b71db436e1c1be5f23b212fda6cb324e2675c36ea039ecd3804f8a51c8005d99ff74d66ba36acf35a22de7bf1b9ebaf1ce88668a5e67f996bd26856d2f9be5e28c8dcba3440924f82828b515343bce60f889ae7ee25c57b7ec6f117fec203a0971c86e641006fac84b6482c2438fc046ab39510bea2cf480793cf55d0edf74cebccff3b5eaa11b7be1891cce11410197e74e50f4d8f89b0a30899ef9dea779e1a2b635d083db5778569d10ff10a263a5eaa6f386619185ebd7e05170606cf9649be75cd1af00cd3408ce87ccecc81c59600a5b83830fd5eed4d66387280ea07e591d3c5d4192bb58f439a490018dceb38a1dc0149272418a7f49761cbc8705e6357931c7a7cce66c5dc83714090c1d416056bbc690b4b488468f54d3fe0674ee6b7755ae6d07673a643cecce41f180deeed54e7162fb6611c204747735bb89dc25c92798c8c902fc5583726d2e700a68cbd1f1a3a2dbaee35985c79eb5c4e43ce7bb3296f6e23cc4c9da6365dace6278ee608293a80767c0cef9aaab826b5cb06eaafdffcc43848a74a6daaac5656082a8250398670a2d440c44ce2e7968450d83b2b9436df4519556d608826076191f441657a42c6f775d067af8fece3f34b8834ad4f7f1038fce286ab706e5de946b43c08a300449104bb80a38f428c9eea2f31461406996ce8bdbe32adf5f61db4385bf5ed5f83f2f4cecd3a88200eb285f04fcad220dce231beb02351c16299cca3a0d7cadf45300b0fd7e1404854b17ed074b001c6f65a8b2fed9ed7bd020a76bf684f3a4e0d45b245e83c3d64b6309ddb6c5e223eaa328047cce7ae3bc29db063de57b2e6e01de967220b29bbad0b4b667efc8c2dfdbde204ed9119cdaee4f9d4efc8af2fec234089da4d750d6f5333c7f0fcd30b46a150b265f56039fc5855c18f98590ebc7aac4faa0ecf063a390ff7959c8bc246278c9d1caf1b6d25db924acd731fce52a320245d94e0e55e4de801335c23a598924f8f883cf8cb70f9f267659bd390bb4be3eba7b228aaadb504b76ef2cfa3832c1a87b4ed5b08fc433dea34688f4ac923692eedf6761ad908e168794ad8efe6688aa8ffd7ee9f17276664c0526015ba2d063d6a534a1b5b580b79be10884ac9eb7818d57f3f4fe54c070a1d44b697f9b933ca17ae51c8ccef76b825839424656795be577dde824684a71308f61b81d4dabb59f2d8590037a24e9f7fdd251207e041667ac086996b10e1fd351c1c07da74746b36429461de2df2bf17c49a93efbcd59bfd1785fa514dc2d318c4d6a1d4038f5397007cdec1e2802d4930f536b61cdd474cb3d295e91c6f51527a61a4736665b017f49a7a3774e34cadf8fa15ffdf148dbd53d1843db83914cb1bcc93c60b71b7e5a0ceea69dfb11a8e5f8b5f3ac1c4faba68db8b9ebaebeb51db669678f07ce3f123b626113ddf91c5d34dd57bba4fbc8baf12ed9c5b7c9b871c5cdded75666086cecc190f39447c86a1238dd300ddb71a6bce38cbed525d5ab3182d06492c06131befccb4d189077e2536103e68cf8e76ac3d7ab8636f93832af4f6518681ed0bb9264f39b8e05d926683d8b3c068e3ae0157684e8f3b2a95c09ef1cad8e2e32f296b78cf4fd07acb7e9dc5ad7a4f618a5ce0303013003ae6e3802be24bc6fd83a1643924294a96f5efec4bb7f7810e96ea627a52571a6e8804156d464cd21e066a6002719c0d0690bc56be4621d676682c61d1557effbe9e7ebe6a86ef22371a9a37cb5b03a8b0a3ea47deb8495b56eff85df32fdcf44d56da2cc00bb2d1bf9539fea0e82c58584740e3d5673b578968a9e09c2642721c3c9c24f50354173fc6cd7d731c1b8c8c0d49295133f93caa1b0c9e06f1382a2d185220a0bdcbc5cb6516d15ca56a504f17347525df9e884bef05e81c67cc6c86fa362cb321431313d2b9b4c2b924ab247e44f83231bafad5882feaa0f1fcec50f09599c84c9b582383ce87be488dc1f44499d9b037e61fb6c376003a19e9e6fe524d17f7eaf5c57c01e3ddfaab55bd539dbc0e6a7d4a821a975c0f5c75bee8b0e5dfecb7830a9d86f0daee9350c70286dad04b4b6842b127932ad55a58fd8b7be53068f6f7e7480fddba52f686f6d21997173dbb25654949fc5dd47779851fd36cda13eff1f3476d28f8c27b0199091eac0bdcf67fef67aa7aa8f21e0b670bd7eff8a80c2ca0f844b4870a171115be68d72aa97ffbe14ae051da6f6750e7cae2a3951143ffafd9072ec8ac4060c1652d2342bd628ce3eac64772c2618142a16315e4a71980bf8987f35f1424c4ccb8065da48a47d3457e4236f76b3a6404e591631ab1d6a21af4407587996a40cb4dd336dff867a71b8382af844c954c62555d890af1ea25a189f51760f653371f3d16cf29f76b8df40992069ae8e0a83de21636c6964f2291117867abae66dcfb9129896bb2d26d9e7af82da5cf3086b86571d50ad376278822f8bf44ad8986814e0673fd82dd78b2cfb50da1641500496768b439e81736943a750a5ab29543b2979358f745860cd9d01208b380ad800c55b9e2b4f3a72b4ecb7fc44fd299257cbd848a26a036a84ff3bcfcfa3800f920c22b7d00abbc3aa6fdbad09546e50166386464bf30e1ebe7e5a83cc67f8ee16e01777849f40b0b526047ecbeb6edb200ab14f277fb83f26d096216ded6dac2cc1ec39fb869c9f340d51eac8404f939f9458b1be2fc37a8c2635b46062ea1175b0a82feaaf6d96b14f14cd7a821bbf67697dabc4bca5316e0802b88f50034559cba3707f02f4b1dfdfc19df9059780bb54f20a802cdf9e05f3570692bb9ccd681f88fc155e31b75debc0bb76ce07508c1f98830b4ae730851d7b851ec0d420d55bffdf7e2b5e4f469af1e358364d82dd2db215f96c1045d6c8386b209168a62c441f4b21c3845fe9a91fb5283b813742690460a1ef8f6aea01fa52116b7fd004bed1366a95d697b5c90d24849e6a4e81ec9e2cd6a3f3eaa2dcf964df8ce809d0e217d29e5a989ad5da1a77cf0b02ab3c2252cd3ee6e5cedf6eb1e7dd8b9a635a0cd7433f28f89bb965929109448914ecc1a87ba6742fc088f833bd92f4a90e5344c4ffe31daabc91b42b013df96a559508c5916bdfb8444093413600299d89d072fd7d3e9ea0b4f61d03f3f02aec633fcec7fd4518d08a710d6931a409a168cdc54b88fc02365c75cdba96e83c256c8648121b99489871a440f3a53a8c1e839f3c6735eda9b08a9ec78f3de2bad9bff45b744888cc24b187370ea12e1261738583f2ebf8428cc44dc7f6832360ddd81da3fab24399bbf522242ee034c5a42215616e256342541b31640447de487b81d12261e65839a1aac25218b5c0a6fb5090ba7da5d144fc5807534b5ba0c9572f9ab0e5ec87bf1d79bbb2228d40edec3ce03e02ab3b286888fc3ec35c3a819d9b701c36a47c08015cf350adde108e903a276bcbe78135bfa62f209d0519f10c5778742eb689ed055e73adfcedd2b83ebc40c995d419d88fa667869d2956b4d3172e6fa5cf1aaf3fabb1040ab7406c9fcd084d1c9070de4bfe5adf10e8f7d86f70192dba761979d355f4950deecd794c6194d82a7e6121003f0301767635f32e942c4bcc2208a55dcc5689b61dd367fa6ad9d559c8150d281f13f9e243743bb1b20e466a1e67b165cecb2fdeb576dbb79a7e8c1bc443c47f66684f5631d89988c9c475dab6532c345d3054e0e8e74bc9896b989ed12f2da2ac472a412ea31b40303ee63eb58fc808e518c784ffba5b1280d44a94df9bd7937a1651ffaf3c0a3db9fa6c56630b9e6f02960d59eb372bc39c62d36c86ba4bd239fcdae182675b305a4fb5d832d252c6ef2d200347dac04b47d2c1aae1010a0bc10afa6efd0d26cef9a9f39cc088873b9418109393af43bafffc36e49d82a3929532da04ab1aceb53b1ff882560d88cf6daaddf961abbf49f1a6ab84347ddd459cce43a1e6a76532a9ac18811f70d40020e000f611e75bd8637aa48ec5e4afabe8026cb46a04ad204efdee2e4a98bc09c895c67d1bd376348447da2f4abb7971853fa9c631b5dbef922403d0c6ce053e2ae19cdd41fe8592397cfdaf5f24016ae71f28e8f1ccabe2dba76a84a554413c0eaa0103db832d626dc98c9cfd41d4a7ae6f004c4b80edaf720fb95222becc8da1acafa23ec2baad49acd23e704ecf2b9214c53ae15e61efd99a34c533261b706193f18349a46b868b3940fcf90acec5c3db5db29213000b9178ed9b8d5151955a4f7daeef49b45e90b2f1c9f99a2e17df2320fca2964295d3cad5010e8190b6b6579bb75cefd3ba4150b37576fe954eddf46855dc6f47f1e5149428913f3467fe18a37131922f456a07a369e90392b4e717c1a9085dcce9e5c15f1d5c82cc4ca96d122ab2016bb52b282ae8c7a5372bbcf2e928d7f3607af2c1f0ec7dc793033fc82e0fad1c60ce2d542ba9e10558d90051386df12cf8b9618d1303c334f07e3b05fff9c4ec11c84f861c2ab2eb393b9e8b66490ecb2406884ad3516ff5991ba195421784c9b09f8f514716774722e8c0dbad3d842045c2cabb2ac39d75a077bd20005e56d30b7598cac0653a1b4ecf9f7cbbeb8e4a8a81d6ca029332ea03801ac286580c1d4c15c7c55340c6709d34d92b3fd25cc924bdbbb4b3c88979ace216e11a779b63dd4bbbcec7e16554f7822b0a8b6f11069a60936222562914c395238b8a598af8785fd728ba9a1229d0f688f1ae0d8884336056ef8fde7ffbac14ba461c9adba99fc3e4523667a5006cc91908f2a3a925ce3ae7045532119b62146e5f6ce88959bc6361876377dfb55349844ddeeb3580db16028b34f7a672b5eab7ffe02eeea90dd1acf835abac8ae7221e01aa495c3600cc458ecd65937c52f0cf8a57d7ad8e3cc8669452af2eed9dd40c7007fda69d8d662fa4c92e93b417eec7365f29f8127100fdbb233c0f0235f4766cd79c1fb32ee355b3ba5e47aa69ef7635edd9cd61ef593e4af2a3c12f789be72aadbec560199064539c1ac204e50a81ed8e9103449675630ce75291577516b5bda6a86ef66c25d874741248b8d2c68abdd976758a694675ac6e9563438054c1dd12c52a046eff194d66a6812ee528fe49fe935f009480565d4fe1e7a51b882ef983900dabebf7d3b32dd09400c2d1d68aa4bd7999b0fd27ae5f1dae818e349161c545671dc056449f3842e8e58ebde5ddc740a0548a557433d0085465dcacf982d50f5c11265ffaf31c2f65c11ccda58a3806edcc7b4ffe368b665737235cd93f14072c2e9866eb296c1ab524a9f0704ac04eaa6be024c84f340443872a95e80001a9cb1b7bcf29edb9cd8f4a758ab7f60bdf67a992761bd15fb83b3e9a0082591d2c177c559ef75857c0ce69a611be83e10b29353da3ae75db4ca25b5e832b9486938da27d6ebb100f4673eab6e187d3add2f48926d7340d4cbeb5627b4fb54fe52bc8ff96cac845c56ac6cb222bda6654772fb9c7aff9817f43f9f7b138004b075d2212480ca4df28dd3b60d3f603efb861e014affdb8604bdea9ab1a66a77b260fb333fae5b3f527c924dc5e6bd6ebb974da5e4d0c6273adc5a304b621f7b6c0a2ef68c4de750b1da3e37cfd96c3ce5032cb1e1766c9256657066b139369aa0c6168172514ab40d896c3aea18efa229e104094c673fecc279a01bc8747615300d2927c0117722a4eb270eba5269d1a8144a188ceeba49f6bef0afabfd0d75978870ba2627a68c4e5b2730f0e6902fb919d4fd3c19cdeae1a71f81106ed19d045880d3e527a4a874843a195e83a6b2d784b4cd09303b445761fa996fa5c8c024ef00c9c76d928b017ec518c9b1cf61e4d511817091e828b6901c8379eea99f92d77fd9041f096fb168f4df37fb2b5f44b586cab2ee227af6bbd438c028330a385c7fa838534e0e1041ffe6f9de4da2ec7c08cf68f05612b2259b4cc0ba65c6ec6b13e1329d690d1d87d2805cadd3373d428addd1303dc5d2f5dc136c99e5325d6e0d8d436900aed62d7d89deb1ab0816876f20cef7adcae9665bacf494d3c27c534943c70541cdd560d62a168796fa0725c2981a0aa0190cd6ac737a91be75699b087e933b29fe8fc8654c29e9c3a6914b0a44ebbae74452fe3e42f9ae4bf9d1eaf56e223ec51f0f8ab255973c64810cbc79276ba949d5301242e65ccbbefe9be98963d6c44b55cec3a5db25a1fde84cb36e00f0f90aebe861a968677420fc35f409b9dd51e8b6b01fe894d0de56f53792fc374a95e7d3001a6af8851bcc3f6be7f4790112923b579ee24c191621ebf01a58e8ab8563339ef96c37056986e999a56589a68b46a04b27c46c61cafbc73a0d873c3f81c0fd15351a98d2e8e294deb49cde100cfafb5aa8c648acbe1644bd367490e1d677ddf85a47721e81ab31d9bb5be6dec37cb26a1a5fbb13a09d46f01879f7a24fce5d06206d74b3b9edfd584e2b34424799620dce64f47512125ea1e84b7885b7b38a88d3cd39d7a9e8925429590eb6b9a45c6850a38742f0f4edb5607041396a110e8c35d64f02963f7bb5fe9407c719ba03607cef42573390be073019853b15565f46da773224a20a1f3e86fb3a532be3a4f8bd3a43ae06dcc8e031d685701d523a77c9867193d2ff1693091feacccdee74ba447064b3844c910ba9b68d35bcc9ff945630d07057165e883998ff357fe287b2999b71901567f6baed1431406f011133a0d96b5827fb39bcbb35dafa77ae2a33eadf6d81d3550f655710aa24013b824007bdcad5fee88ef04f7b38e5196c9b451dde5d5b5825e5a284d1c2792f805a54a19aea081dabaf962eb8815feb1b9a940d3b15987bd48e93c6632ea521c554c7e52643b6ba43af5720099981d4738e0380eabe6e6f5edcad60275ec60c345ab319564ba59789c07938522acdcb7de8fe812b1d1bd3a3e5da153563e7bb4f69d938324498732dffdb8e2f7a7cdefeb0d60c6db25004bd61af37ae4b5dbd20f0421754e73113d9a31b61fcd73ddf10fafcd1bda0e8c7698f9ac6e650350b0e6b2e372aea89b48d212efd6264ea1ac2787f0d4b7cd32fd978816b32608fd5d7f1bee01183cac475cc56c0ba03aeea0815548dea16fbd914d198a0ffdd028140e20a1cbe056cee6fa7aabe996fe82e233adfbdd000caeab39ee1daa0175f91653ee3d0a7b341b82db368efe54f104ce8a4fe69e91187c8286bf88e3b3c5be2ddcd641f0033b50ef1c29e98fba0ca306e5000e50dd67163f8519f8c25c48992779d3986929182b178dded5f6d0d2254caf6dac6700d2c64488e0207e47c05d70f973fa074c17e589aaa80e362c280ad79bdce63a84b92c230e56a2dc654b54bcf839e66859056fad85c220875e40760ec71be179053e6487481cdae9c5e755bbcf114b6569011a225c5837693023155e7b6b38fdc74814f54be0a0dcdb4648c4b4f633aa70f27d6adebf2d6fbc5a7fd08cecccf05a3690f05740194d476fbf664b6145b440dc3b23dde54f2e0285e930ae3ec2c9684c22e7b77b6378d04d4762e577becc27f90dd3bbed53ff8898c4a1cbf028633e695c906fdb91afcacf8be882e2567058c553c328c340728b93a419b2cfb5e7e6b24c91b555401aa8db26d1556c24600632153a6b9c8ef245a799db4daf17c5c90aa984b84c1230dba05852968568307aa3c7324f935fbaa0732959de83a8a73f50ff97d851a0e23f134cdc9a82002eed30b944ff920eba994e980124e9ac854e9119c3454a90a2b9e8490bafc5725dfafd1ee8c29b821b53fd57ea65fa17cff67341f2553a30471e88c4c062c222ed0b74b2df6ea9a5f4600a50521f98ded7f0f33f3b76edcafa4a58c55ed1abbafe4c40d8c579c3751814d0e9a2a0a444e79fe45932802e1f0e06ce81f09a660c3fd45276c7cb8458499ffe7338ff12363e9764259791ccc4f8a854898c7c38a7339afebd753ff9399559f5f1bdbdd1c8f26d0f895ffb5f78a1ddf32f9de8bec1be2217f2ffdcecdb957851bcd13363a49bec8ebeea18c05ab306a7437d57f89038a37f32151aa18fe4d2a1d23f32649cb9118b118c2edc719d05cab36d053f073ab2946187d90e5ca1524d434aaad5451995c658f9fdb39870e5906044068545547211fbca9c3f646a1af39e8ec3542fbe730c2240d7fad10cb9d80bdcd2bb240014d00179e3b310646d06f001b120ec8c05646b16cce2a9e5d6913b84c61fc0d6ff6a114abe003bcb7f9a60aa9dfabb7f47ec30fa95ace0133f4b4bac11c7b391c054b63e6d0ebf0d302f2f8b08fe4d49b15207cf092293d03dfc622d28a53b424ceb4bcd188665ccd9246c290e1655f2a4fead6991854cf2862c5e76f0c1a887cc88e77cc33592c91f25b7a74ec5e9092d523e1ecccc4339403bbc794b58f3f6332d04ebddf38259da8731d1bdb8a8a49fe8423bab39879f49e1c02deaaca48397714f7f9aa69da1bab9b6400093c646998d8e6eda8da85c16c0ca2480c801ba82ccf5065395bf06e093f9cfec96358cbc084fa528a2ac15e549db469e97086bf69a0a27a171d5ef0c7ccdd024dd4eb42183c9b01043661dad61b57b9081c675a273156b6b8cfe219292899ad322f4dbd288bab925df733f35f09968ef1260d18e84844b62fb64d2adc097b8f01a81738b453e6b87195032b112beef13a017ed8be53891a48fba8538910acd64d56e6fe073d523885a5f992a17789ca61ade8bc95883993c679b5c9bd63cc13291ffe9ad1541fa934fdfa4f1351aa39613f289663f709deecdd797a329163dc7e102842acfc22877276060bca275261a99a196ee8dc568983823adf6eef1d60472df124b9e31867fed5a4abaed6a85cebb6d49a00f98ae44fbe20b53c7336c94c9d4f87de1d243c00266186acca139faf5b9deba541d9020132da0d804a791cd35e81e45f5e7e3dd00fcb515cc7381679a41c580894c0743affb31d3a4cb6f62081c664647ff356c99c9f26d6cf2e47f349821739a223af320c3201a2d9b2a24f5bc978e3d8453fa1316b2645f14f4a0f09d2770d59e412c82759301dea8cfa32ce44579e73ff49536dd6446746b2662133ad723ab2ae167012e04f072786952f2cf89bad0ffa06ab15e074f3e5e88084f338efe5eb8db15bb725a169f83547e386131c5242741f3881149b59cd0c487c9209fe87fd9497dbf5fa6a75bdd1631d72f24f0c6850171834035268fcf7a4209e17eb2cd823b7683300387a86f8783e4e15d3ef63a24689bad48f98226fa8de723ec6a908cc627b7dbea5b68fe299d5ef2fd2e7906821d49a9faa36587cdb793005227f67abd4936857437869bc6c3f493dcf4faa747a44a06061edda3b5f155debafefb16e6f7ef189a54198921e55656db6a152aa3c60a117ed3fdd5d6528a446fbcb5d399b426965fb0cb3738f6ea2405a1cf1ca52a26d7a7bae5515cc7375eaad68ea263a844f4560c9f6db0ae4ddcf3d95552b5543f1e4a9d4bb21c994596627fdc222c9779dee020f322216f664938c327a1c2702011de1e9260b9bd034156b7df2de087d9414b965a35133bfe667058fed01446d1df94fb434be40f8e5c884044248fbc2a8dfbff56a0a93e5ebcd242fd5b6fe178d55533c689e6e5442f3e4260dccaba68af192df61cc1c1b6a5216d48da698f729c804e688344179e50e38f16b474066887ab4cc027e3fd406dd4e0219478e78b6233c3b417fc458d070ab023c926a21322f815f9b546818a1b451585172a28ae34e382d3a4593dc1d59342640f127eda3e7bf25cc86d9d74639b1ee0f5c4dbfc7bff51b9edf7bbd91be43808fd16be8c3a811aeaa3608964f3512e794f6ba5c47c2a09317c8e12caf0c3f214cb410676391061b2f52407e07aa2ea362e444b7b2c8c665feb4bda330beabd8d8ca4a6110c6d93067737835c752ae4cf45bc6c2a41ca61cf9c43a0b344c432647ca63fd32ac7d9fc490c47e35abb8a84d3e8dd875c860d4a5c86b355f31f4b647c00a94d9ee0316948590c63d490b826148af26b35fbb3d6a56a6d87fdd4e7d30064d5b8da9fa8c75819b6c7211e786266864f86f88a8b9e72b8fb2400d1bc57508137ab4d6d6c922d2d8224999ca7d1c92cc550aedb54e182ccc9afd9dbb9ed572f032c9a6768b4ffb8f4b4c03f33bff89de90e5257a05317c0c1250849c2eec208fbf2f1180c3e1e6a7f0f407e7769ebca1bc585804e70161f5552d753150b2d621734ebb8952e85b5c230c3b601f6909807d268dd9c2a3346fbbf646b0576e090282b551c0e30dcdd7d0635278772da2abf2a522859a1fc9cd2f80a25340ab2023f4996720a78fd092a3512678e41aef9920abcfcc3fabb9ae4dc60437cc26792e7cbb78b3159594e0e4a1c26bbc7a48293aba1c46b3eada411f565a430c7a10c30e1ba5924a3a8b8bd8862af8664bdfdc571eab5dd4b21beb97162c437eb5bb0cb4b5cbb73d9bddb3ef971dc07173fb7235ce381c98d60584c40239932153e0f007367fba9ed3e1263d75ac3d59c11cc79f4aa14cbaaaf9cf3bf31abb313a89f8a0fb189785154b74c8b8fe9b08c19b861ce2aa1ed701f4af3f701d49c1070600c80e25d644cb9129246ea665816836f5d0a6479faad95b29567d398e8c7e8f4a9bf2f57bb93d1d5a53feeee7f6a4151f520e358624179e76c2ec00931198dcca9b4834b610dcfd50926e445324787d556332f7372a6a1a40ff34e417477f9a52c0b555c2a3183a22dfcba6c6a8d903c0866830f36fdbe6b135316cc43b1f219356f150341e23162e423c543ac1b36a975a8cbd58a1406f63372a33615ff05c191a20be8c20dfbf23f468f614ee1e8e3a7de604ceb0219ac8277c089c630d15472fd4f502523b8c3d6ec92ef50fe3c1ff4409c37b9032878c424a8352513b4ddf472d1768bb2832d039de456ef7a118bc841ff49a9cd5de7faab31b1f363a2f3454e016065146553d083aa6fb1955e015fad2e468839be4fc73c4ae7722d357fa409602a24eafa605aa9036a5eab25fc7de79d4636f4c3f67477590e7883436ff753a055e80fd6db4acca45b77b661991a3bd403b8022a2a247085474d8fe484b48a1586baf85d60029c6960c82574683e82af0903f7a16a0a27684180403e049ffb232747d03bc9742458c9699acfaf3ab15ac3629d097958195f847a7d15bc4af3233d5957e090a4808819865fda9929a2976253028cb96e6392a2c8d008916872229c618233a2028ef2d3b0efd4cf3601a10e26897b376708f438b8d1d00fada4feec098a90a90b2520b06564d05489231d06104cd8e906a1246d483d2f7ee79723b451dd32bb97eb100a0034d39880969c8ba9a4c1ab06b59f101081268815d573fcaf204b968ce8238888afc6db63146cd85fa1edbed3b3d46e711bbb72c9e50f42d67e6f863d948a07630821df176888f389414b6f1e231ec33d4a1e1a75f9c13fdc1e8399faea14208d85cc1ff1174b2be0f837f7030b11cd0f43ca11248480cfd9500298c9f3ed78ab51f5178475f3dd769a8a3b8c5ca314303e16680100a150c316a0907f454d232bf88d36b00ea0797aec498375a28dcb74867b5b6c0bfc519ed0d3750e5073a332424f93247c77ca43de779de73ce8980b87a80682453a6c86c163e63a019ac93618189b4f3594054de523cd1415f3c2a33aba2a0172c2acfe7e37f33f47dd44d642608326779088450cefd1a78f7e4021b94929e299f31615210fd35fbaadf0c51dd54c41b166d4de2dd37f90a95bf114b15c7be1b0e46ef5081d76b63ad953a22053150950e5b618ddfd941d73007a1d14307280191bc714104f61794c52d6520870420a619335f29203ffca329af4b9a1b6c8987591d2a376b0b77975be9c3db0691fc0fe52f9067dffe5094883ae5587286fb2e0edeb2fac62e14de749248066cc7c524f3c2e4163a39099002bd586c322d1a7c4ed19205d6d90285a925bf7ded076bf72dbee812ea6da01127630e31162f27f0c644501ad8a4b326bb45f9b42146f25f5bfa82f7c16bb000d5d86efe0ca523e26d4ca80e897058ec04987d628ae2f62b11d3ff0c59b3d36e82a150594a9534f651187fb804726c73898b68b24fd908f75a3c1f34f06d5d87f8737c24d604288625b9c132783ba3420949689e09b4fdd8adff17a925872910a1c2228ca1f7f7a58a91054c59e5a3ee66e8b8080395355397ed3300fd28e02ff439ed031528e276a271d882e75a2174fcca7784f799b41b09e2c67c04d5b28e28196efcb0783df0271b7637c8b96eec92e8f5764b6d59f0800359e59d3ffcdc6e6bbf529dcbc396944c94e6b89945011e3424d10eabcadabf2aa730c73ae6588641664ced272ff5eab52a411728dbd7e328165a5ebbfda518344e22905b67943b17a3e412cfda228cb341a0848417fa1a9f87bc8ec100679d80315c8ac2c4a97a12b910fad7c85d7525bbce4fda4c8616342615480704509fbe0bc622345e6a00c4f481d05ec34a4cbee7a7fd6b3ea0df455d8c06f174b0ee65f5bff32898e3f8a40849e93ea4d6f8695c2e59757a9c15ba995c23efe35a7a1ac01ea4ccf67775fcff3ec2a3d6b5588f19526476ba8ac425189f71390720e6b4234f179029c2e9761259d638d501894e60668a2f309917b6772f0345920a2d15ba363468c20b1cb8c04e9b058044832339ffffbe93f44358789008b6fe09ae3f2e92bf515c459420965e791b75cd0d5991c064292143c74d343be58e0dd2c59b8e10b6c9348d33958169bc4b20300bf69757cac65d70c57b592d91e8ce0c20884b0de134041c8e4da034ee7e3fab7af62b0b727a0e1f3059374dc8de1f973a267a9a8822408fa141aa3abf9d764e72e7da75096c236b2ee1b76734802c658edff577ed4f12a8cd0c57f6dd5821397a729260cf11f23e89fa51a4b0c247935086abdf3845930d1a7b0a3579fd3aeb518985d0ab5f0fb9a594587a225a3cc6518a571103fef4890f0fa108af52aea47621d7fd9cd4231563e2aae5e02483a437a3b23fa54ecdcdb2567fdd84a0f496589861d0a53246155eccfa52174b95b3ba0e433c907e8328f37bb2565103d7de35eaee9b6bba439c67c57886ed98a456d0adf4229c934742e20f0969d14e192de1791db826185f305e61df23ac3f3a0ac543c6a7164b3dc0a68f92e560b5cb2caf4e14c2d745c97a7eaef8960f0edf10c68ac1df0beedf8e7a54d3df8e2f1fa950d091ae8f99797e6d131f1aba10c2b773221443dba51d79898fad2df9c0db992225e3f6af8293af9cd8d7c579be5a2c824f723c53b386191432b7c46008985054a8fcf9b9453be4fa8030a954ca5595dcda38b85242f6470b24ca9697b3629149a227534e978d3feb7bb88c711e28203fb94fa28faa201f507df51b8ac70e06cd6bc26c85e56d29214348ade72ec9f1e1e9b04ab7c0ae5220e2f9d1a521317b81b1fd5364004a5627bd00196c138a9c85994e2f70ba50b1afa5e9dd41918dd90622321e40a6f05d1f59a8309e0d9509ccb165562a79049a2422dda8db56544fc86db051997c018b073df647d18c5472fee5b156856603da56cc41c5df149e82e15626705c0f269b73c74a643bf391e30b4f513cdca383dced5daf64f79bcf2598af3da2a8e5ebfd3cbd617ea77c141b9c9b166dd9f1921e15787a883ac02c9e324455ac86176f65be8e67454b6965e66238c5725106e818312da83999649c47ae10fcc45d934bbbb85bb48a3fe14a18fa0c3dc63c0f8546b66d38e5358dfca308f2c78aaff4958304b6602c96702197ea59f2e7286ba40833ef233b99b8a9617b61110a41f9f2258033d24bf57b88433ced429b9e95e8b3cf3f00fd919cd6cb835af2ad1e3f39e3174c49e4f56d69376b376b14560501133ecae0302b72169e4257877acb1173ab3cbe60e5a0323a5ac8c9878a127302fef4ac923d2cd0639fde3fdd5c7cb5b4456607009c3fed3691636cd8917eead9599df30a1dc619868708ce911509919ef68004c01806d81ae1c55d05d712944c0cc62ac1edcf4bb22614664dc6b7d22e50e7824f09dab24ad29a704c04ef4a91f621738517c7f4aec3e977c354853b9cbb18f7e65a01a3631df5eddef1c7b9b06afcb6065bb189c4075de8b94025c3a635b256a2ea258f6a760a7c44009a7dfc51aeb0fedcd545c79f240aa911bc9624ce1b85e3df942bb8564bd575db48afed5ff7ba34885b4ee8d3bf4e6096ab05480b2b0b607271ffeb5813d0a5ebe7cf0aca6588525ba4909889c477a9490f59502500628e00cac22dd0cf5c952f59acc201cfb0916c4124c216b8686f55f9a2a7888cca5ea2f17791ce204ac2e81247d38ecbc4458d81a80644193a491854710f7a4419131cca3ea66d92af4a6c3d075bcea1b76bca15ef30ca0f614ae52979381278195bbc8e1ae8106ec9ad82f7e0f82e2e09a48754860eb54707b41c20485b6cd3f74ea6f9b91382a6278ae9698ea90eb0c540970ee11f856a46b8cf760256701e6219c016538521c412122f3f3d72db44c922a0dc5fdaa08f96c5dd8a42316bfb2d65c35e13831a8e3b61e38c6ded23955534431491ebd31993e2dadf2064735cf47c852eb937b65729e81ac6ce5abbb498df1d6fc2adc741bb6d32a8cb02a13c3fd3e8cd9417667268375eebf3b8a02d695903da527baf56d450226aef714e60a448beef7e4dd7ec1ea6ced02c5bab316854306b8444d178e71d631611a524946cbc75c19213aab0f605c860977ec9a2417ece00c47b69b14ecf7add1689cc527fd0c67ef1e5a888d79390d8829c28df3abc27b6f1df85f3e8364ad02cf4e20c3b57405187d8fc4054557b6507079e9f075fd4198a9ab04b92e56214eaf5af706159cea3b0c5eae0bb9fdcaab40311494c13792cacb51f4f4cd53cdc1e426c3f3d6ef8671991778ef808de73b640a51fb199f6a60f92baa04e325f97262f3cc3900cdc8213b11a3b64e459ba5428cd8269a1416732e93477b3f3ad86dbdda94237dcc4528c2164f1814c227ffad6c61deb34f15452e9bf4ceb063e69812a670286c47087c11d5ff6993a0b940211316f27d2178e06fee9bce1e689540d1d28d0c33e5a3f72e0e303ca0b15254c8b3df52188d75632c5635aedb9b7c09ca88bb9b41cec675c9d2f45606a39c40a4edd141d25cb91b6d2b0ebcb21b98a06fabb204d1060f390326dc8cac0a18471e3f0a58d4dbf8c4fa930a7bdb0972ec36d18f091bbcbe09e75d0b5167e04d728ac133a06dcda6454dc00e44124bcc98b875c3329bcccc193559a6896c8c1b7c220604e897fc32be6fe92e1010a5e887e985ea9534b30884f90c3b80186d49b55b240b22d4eeaa5c80f989d00780acb776fccd54cabdba263c080813fdefdea10066a6e071568ace914648e5f818935f5fc72b25ef746e36227d0df57f37b27a38e1d7a4a3945886a65c6fcfa59aa8100586869bfbb0aff62a9dded2c6d19e251fde98fcff9ceba70a448070bb3ceb79a2f1a0922b1c2f22fc357c8cb1711cb36307c706c0a49533af29bf05cf5cb4360b94fc60595b9f400c7f26f7a605dbc343547f3e52b75dc9d19961dd8bbb58db7046490884102b6c8de26e47d3f1b3a6cdc1fcf7317bfd878368077c7dff08296b28f4bb99ce14d29b4c358a3f77f9e0c8ca17a64f5ae1c2c3c646c0038b89fcf47c7709cded496ced8816f30e015fa56f82511a4a97dbd3d2086ff49d0380604f7121ce870bef98dd134a67619209892e2eb6d4fa3d60aeeb50e1367ca9f810e2fb34380ff8cc28f507993c5a0d5dede589e81c9a0930c61911429c9dd99127c725e93dc9a693b1df387af181ab927a7600b7d172570b4c2047241549ebc23fb3f662a2b9d799e61f4fd6d1af82fdc79958b0a04812d2a310185461e0eb32b9e400c191f2589d01fc6fb597c8652692121fc8fc0d8ca896b04a26a7e60fba616e3448ae7289cb7032977cb79f806e6adaeb9000282c71af2c6119e6ffe9118eef56779bf9405087b67cf2f09315f821ada15d18d4ef84a2fc847605019b6501cf253bd04814a4fc7098925a8bee7e9f779886a76b36eec8ca66bdf7b099147c0322ee507a3832535687a1bf19094e3a689ca218d35ad69b9017fb438389d9eb37466602f36d8493a6ef629af9dc3047ac182064182011c7701129e52b83e3bc0baffe66f0c91438cebf74324878bcc044fc62d30b2ebffd3c3269c918d5d823cb8738413280ec02ebf11d3e89c32b463136adfb9085a25655ed21606d9e94fa579c855f1fcd9627f3049b6011f541fdf48036cd4040a2ca50ff9cd784dbd158819d7a1f8763f74932596835bf6c4b9306e8635703807f91b356c0d9f488e8c6956340390b66a2fbd49c18d02cd30dc19dc72689d89ab04294044369732478744f21550f3e7bb595f73e84e6386f03ad4f36ba7025c090565c69f47b1d0048d057a947b8d6a7821e9831e516c3d0f617a00e770dbe6dfcca8c1e5c2506c9c807936dae25e95d067ad1237a0c800ee6ce539c61ce41c3d77f592a367691ad74466a393cc7d720931d492570b148679c8c4643ea5000d60022ecb35dfe13dfacc82e7ed26073a69ed9f5c4504750522a0956d8871c679282f40d53c87ca231176e6cb3f16ca0f8e15703f69905ae71b6a86144333a8c2c0b3d81e460ffe03ffaeb7b389f556d57836999e562081434c3125f105e97612b2cde7813768be2763a76632aaaa9ef9885e72a9855e2fdc101a0ba18d00573283bd95fcf152dcd3ff2a157c57bb292f097c7f24547697ffd81fbc0207f07841953bf3c72c024d6d17b43f8d52b58433325d41e628c7a4222ab4e7a3e6c282a39692c3034cac274cf6025a013e6a5e30ccba9a0e851a92145a328fb222d12071c03e2b20318b1151dea729d1a3e1b25b81767871f0f441426607c7eb2388f0ceef57510c33bf0eb32ee67708171b0a3ab99f1f6cae2085d1c7bad785e75b8b6e2224a4edbdf7965b4a29a54c01c50677068006535c80addd2fad75f2997da74b55469fd0bc608b2e0f207d7022b9931389c60694f6f79f56a6150c52a034c80d970f4e249ad33d9df9d6bc6dcbdb73ac7625fa46a0b2caf097c9641a49ed72d6a6159a33add0e400a1e70391ab0e9eb6b99bb8dd706ea4506503597a9edcb258a49d43a83fb4a9a5b3032ecb34777a7e80967964815e1883cff27bc661e7b1406946d5aa032bca4fba6899f3d49fa5f82cbf8d2bb46d26cda4fcd9e6a239b69d217034c706bb4273728ec1894e2f4f95b44da81983f3d09d1fa8eadccf24d8366f2f55f1835bbbe4ac614a7941dbf4ce47546788fdeff3d190fb605975549ff38359e480c8f61e4f3bb4e9d8a53e7c1eaa17eb0b497d48e6afaa0fc9095565f9e990cff2275559fe184d8d31fae0df8e0709b4434b2fbf3852a72acb1f8e5e40780be8ddfda4746727ff474ea5bc71d016c81b043ab4bb0761eeee6f085efac5679982f159fe9979d032ff2481689973ce1609cce2c3e1b68d06468509417ea265b63385a1a188302b845dc220e994f40a4c6782d652e025b48a8b4785068dd0801641642edadbcea4050f4ba48023d022052b5a90806f1ad4a253c20a11098c144c50002673a1c32e1f5416f008ced30018203a26c0f4202ee96e3b1318241d60a8308119eaa8640d937972428bb643b3b1c301a757b6c20496ab8a314e56ad2aa098e827162d53a14445dba1d9d8999234454937b14114a72625385c132225a20da450e121ac820613bc27f096819c750eb50b382af3bc810b4e1ab6e4840d62b8315531c4c5911b18241b74a04805493698f20405135c17251bc08063428196251bc890149535ec6e67fab2b46dff38255a50a1c32aba1068d0890e49ab96f20f1a97a08988224d56b034b9e0dd9a8a86681af2a254104269971262124e6c41a77ec8421cd1025ec294c3129ab59d89290a13143c02a625494c48b6601ac225e8d40a3e2774cb09510a9d93c0f229c1848416308c4e6d674222043908bddace8404920785d6db99908832051219e8aa60422289f845e3ed4c4890a0e30b2e8b315974a1a45fdb6e67ca224a2923cdc8bc5c5ebc3c3d41b15694e24ef4b91efd2afa60ea51aa714a0c412f77f8c2ecd2929393979faaf35365953e8df63fcbf27f678746fbaf254b4afda05c0e48502e970b82120a021294cbe5a68ca05c0e48502e970b82120a021294cbe5680cad6deca5e942c7f9c1e172fce070b89f2b1efce4f8c1e170191694cb0109cae582a084828004e572396fe6cbe0899e468200d1ece4e5e91be7adc6840da1818df26f1c4c17f3485414982e8ecc26417eb674a93f573cf02d2800b23766a5d166370c6067756b7d3af872a552e2addd63dccd0aae449f4e83aa10283b3d5d1942e36e7e6eac3f312b0a8298ba80790205403f5bbad49f2b1efce4f8d9d2c59fb0b3de94657843e3c679fce6e646eb554b74852f2027efca101ae070389c0ea232fa3f76565ad0cc6f8031c09e948823397e70b81c3f381ceee78a073f397e70389ccc37e3c1721946478363b7c6d2202041b91c90a05c2e1704251404242897cbc9c8e572b02f330848502e07242897cb054109050109cae53c372d046c0069bc1c8cb841d595a26983aa1b1b5439111bd45d87f1bd5aeb69823a3373ac0c7d557759276b5b37b3b0b579f2589567539f8ba087a105456b6b58ed97724fe55977ab5a31eb65dc16aeccd6556dadaf0e77d85aaa8375b5b3d67b6fceb1b0d48d12d06a2feef20786624aa557ac96eb2533038331636560d0c854191a58ec6585aa4c47c55c3535362d1894eb00396cc9695aeb779c334c6b3d83af95b189c1baf85a7cad4c0c192b997f8932f4cb0865883e1d6c546158cdfc46cf67d4673b745e1d838820d444cfc7ae914c611729ce9811dedcd000690020141212028017800064a11256ca3a990030be9646001684308fc2d7d258806377bc74d892fd797af112993b1a1838b35a972cbe306617d0dbb90e50764b81966a15b2d1605c5043106829d4d4e26bf1ad01a359fd99a67784aa4cc8fe0b61a80b0505b342b4d09d079612f2192da245014ea794ba7b7d6dd7ae15b4e1b475db7b2feedcbdd6306777f728a595d26fde6aad416ab5402008864ed688a2980a271115139076f7d56ac562b15a2e777f596b31d04ead95666bb5b56e9919188c5a2ba5343434b158aca6a6c6c6c666c698f7e25b6b9541c672ccf92e770fdf4691b3a8c5f9a39e6ae55d77cffb9eea8dee795e8bbae64b26749af36d0b83d2cc18ad993634c694417f8e949c33ea4de8348706000250ca040080009432015810805226000b704aa739ee0e0327362343c37185196776c14e0d1a6d00f7ded90535680320c0bd37460dfbb0997cef1d67843e6346660e450561a256a01d1a8e2bccb40150026010daeeb6b4625a6ddcc8a94c043ca95d7b41db7e8af6c7580773079935d6c1b66490b92bf943cbd0675868dbf7f88c041b0c854ddfd2a9645325288ab6187a8188221338f126b218651165850722a26af47bf8f019102de7c77cd05f447fde28a58fd402483f841c5705435b086462685bd75f6a18069cb44cb1e2040e2e28d5a60a4eb66822c414286851529baf614db4ac7be9fe66c075bc665da5438c095eaa72748821f2d2f7a4ad9e676249fb64dbf9d6755c0a2b4e2908b302102b80f2993daa4e6c4e323687d49ae5b10514314ed4d005182935bb0108a42812c56986255ccdfe1cb23f89ece754b11af8cc1a9961a127917d0ca2b4db9a2fab4e8d82bfdc1bc579eabe4f5f701da82afb46e1b0ef78c77dbf8ee00d1ab46de2f67dafb2993441a214f801a5b7fc3907f9d3fef17df7b9fbbeeb82fc097cb9a0e7eede8736fed448b47187d451a9b2d1db1fadd53035d617c7ef728009f8f6f74d2fb4b2fcfbb7ede5718ae40efa41fee4455909b874e36eafbbbb7b757b4710e6f7a0c9927c275de3018df9fb86d11c4ac6fce77612c7052d4c2858045a34b211850212aa61733e25611c883a4299a24830a24b984b4f0dd3e076a6305ae89abfe9f9c1910516e355312e6121850f4f2b38e962870d909045091e4e187282d34338718ad120022526b845c289e3c7831b062a0c164aa9ed4c61a0d85a627861117305524dc808b4870f44d58eea8fa03aa24bed8a25a80941726b47f447b0556a973c9aef3fc29c3ce0fb975c07377942d1928fe8524569d7d9a54ad2aeefaad9f569d7292903fe3b529bab0e3e007ef75903ea9ed42bd502fa8f32d4f7a048e3afbfe3bec53127614f02fdb6d221232324508c8cb61841b1932ed1b609355b6f9f12559d0fdfb2de4641aaa9350a085629954aada11e551b6606f9eddb5c29a6810e3edf3436a0347d0c52d029194224b926fed17d24b9b67afaa1f84868b5d4ab54fa59df58a5542a63b561d6b0acedb5069fd91b36143ef299fd9a543f50ad6cfbad91264dd64857e314e332fbdabe8a846d3f9564db178f6c5be4befd283b37fbb67287e484c2616b32c55f8c8c2ca0f142ca1623a32d509e40ed2bd3040e459e4a20aaf98b625c762f258a721e9c7d9f0e512333df1b2341db66942da44855c76b3a738916d5a071b66d462db1b02f55da9726edfbf3e62e93330a0151e8a831ddccd1f20b2da36a47b4d72aec6a6fb4353bba97d5d6dc70c845d1672ad1f2feed2e659919541e668d8b6546f9ecd61d7c767fce198567142defd3aca0efb4509e9105273c81b6df18631f9fe1d75587833933e0b2f17b968d3fb531fe1e18638ceb483bfc37368031b6e110e17f001e83f10d73ee689d7ebb2932c6760823230b966c1c8cb6186dc939832ee7999fffe53a3e2ecb9fb1d8ecfc005ae6cfd9da8ab3f3f7709ebaf34fc047ce19b423adcaf2d7d1e27041f3a03936da037ad01c1bce04688ecd45e0836698139d4337ff063b3daac8e389ee1e7fa9e78f0738ca9d7389336df689cfb20a3ecb2e9876a72c75890b2323a31bc6602a8cb684e9aae0b0bb2e29cc98da54c05dbb6e4ced8c801874605586e47a42c366ad7bfc610d54870acda14cbaeec11ce6f4a09f961d909123f8c33f72bbd0fe398fa7c61efce1ebc01f923aee8324adca4aca8496ddf750cf7b1a077cc0fb4a969e97bba775396b6d83512a0fe691369638b4ecbcef1e874673bc5a764feb66f745dbe698dd7565594ed2a6c7d01cdb0d35f2a017cab8d11a2812a5f2bb7b1ba5b2bbff1b9a43dfc38283546bad16ecfa341bf35db41c757923086d83d9cafd37557bfd0127cbed33c12d0b887fced0da6d5f044bca90bfa44094d227a1ee2fc5b556dbc3634694b61ff464bd5ca65bb4f127b1f1c4d11b754aa2371ac579561b3f95522b26435a628c332df143d1f28996759cb94ae93871e3ac4b95c9799c87cbcc203ffeeebf874e5cd5994f13a752e15fc165f8e90b94ca7753bbfee73aaa181803c9d807a9175fc74ac8fd941d6b47f490d57b6d88ea6bab51c8d10ead7f015ed324fe1d2a92225559142ae013d920699bf456ff036951183e0df8b6f03f324afdf0c3ff28135a8638e727d2067e1865a4b71a3ef65d6f340acdf96264a16d9309261bff7caa3af4e632fc394f26a2a039f8bdb12ed192cbac811fec7ad821cc15bdf90cbfd7269fe19f3337a1e613c61fde2211875b5296dbed76bbdd62476e8429badd6e59aadc69698a468cb6d19a24da46976246b521eddbf635b47428d5761ed587cf6418e9d5f62b34cbccc09e802584b96db3882ef9cc3e6de233fb4f603b15dfb1663faa5b6bcae6eeee5d98350cf4becff31e5cb5d5566babb5d61a7636777757595ddd571dee94b4aaa4ee2d77c1aab8de07baac10eb61ebfa9cb6bbdfe359b58ad6d69a0ac5943886b3c7c32ae935bc135bdc6ab940eb02288637ff37bab5d65a212a3187bd2e58eb42bad659a7ad76ce5a6bb52e5c7cb118aa520f53a5a618dacebe93f8bae0423a86eba33082002daeee7de0bdfed65b9ecf7b4b8fb5c530a5b74ab5a7eb88ef9e3b38bef6b591c0ae2f7a5aacc0aed7bb8097175fdc6ab9c04fc6fb7a70a58ced6f5353862eeb6c35b609ec9b59620e1d06d9b7fb9598a313615f2de6b03b67d15a0b523279359d67c20861c0a0b9b5eaeb19dccc1af6316c656331d1e77eec6bc2d4fb4d8dda6516b4d9e64ee635a806ac4a96259d314297cc0d4a68ffbabd890913174dd66a9b6dce511cc87605548000b42264e2022ec1a272e1c3d255a83993e6d39e73ce39676d625265b7ded29c9bdd7a96e8d362fd4af4615911ec1513fa55a28f5699b04228c390ec899caa226968db1089a6252508e369d99e925b135111faaa60685b237697851662df0ed0ec9aa4c8ae4f7356a520dba9ad9e33773540d826245bb625c0b62f43f4b15774988289091bc44071000817365c11e68b156240026fb89201cf79624c2e367d1bdc0bad1acbe5480736fd98e7a07092240b0d60a0a480410a8a405a01a9051e926aa00d50324d97996d7319d961d3a623271471f2a1309d2d8a6cc000db3e4cf4b1f9c852b1adfd1912e43ae79199af128ed8f45f59d0b294004549133825311f00c20927505614f14592da048f9a46b0e4aa3baef93f34c75da28fb525dc5afa0a952feb1c6a96e8534980da1489129468dd4402924aa70b9fb26d12db360d75b1eda7b4d658b4803347b4477cc144f3ce90fd8203dbbe7d50f4b1564c61e24282a32b460851d32b60b901ea87288e1c55b086ce8b6fdaf469fe990f6bd202e5669d43eddaaf6d0b739b3ef542c360bbc9c2a68f2dd31653ba2bfad4d9c5924ddfcea12b42d459b52ffdb0e953599123253f7c0113c5113d96343541e56684c2096af50a239af8acb5d6daa933a6c8a6ef339a2656520aa25fe6571dac73055cc76b3695adb587ea4a6bfd8e147254491ddd6752887fd7bd904aa48647ea4588be08f47bf8180352ea6119ae3ade18be37aa3e8ff9bde6efb10facadd57a0e33853951c80f2b8116e2070dc0b0f1fb9c81c418ff1d6bf80c7ffe18502a7f0ff5c818d0e7657208f8f93f32d7215e7b88d07f1f9c77d2940ce25371c7ac89e4041f2955a4fa9984b128f210528d3f3daa0cbf378aa053ae34a30b6d9b44369f4c6ae04cc6baffbe3ece998c75ef6532d6e5df017ef63219ebbe1f12ebbc9cf30f1141dce159f4e1ec61a22ac33fb4c4383bcf7d3bf44571e348db60616d8af69dafad4a4abacb33ab8ae7c667f4fd314ccf0c2a49a3c5da74e6e535e8fbe06dd52c22045dce87e433ad74d8db794c806f9bfa1e3a913aeb39e0a7480ee8b69fdae216470cb0d0b0bcbf91ba5cce93523da53b1447cf09b3869e2f69fae03a228cdb36919c67dcf435a54510b9ed1ff583fc69e70acefaddae1dd9f345c54948b47c9a83b669a0bd7b3f7fd7c1bcb1c7de9f1e5adad841e3b73d175f24fa13879444d25463596537bc860e8f8d99845482dfa64840f479d0eff9b1482b2b41e81a6a3f67188c5e1b3b687aabb5df398fe7504b9b9a8cd99ffb8e769cf91044adb49efa3ff5693bb5d6d7f561570ce837e29e5152368ced4c514a7b6eb0d608b8ccfe047cf42042cfefc1af312a922139644878e97bd9f31c6c451f7ac7494b3cd65ad0e1c728f9f52925717c66ed4f293097511abef8f3e9d3d80d627931d48147b141985f78f981490ae0af489676049c27a6bf6c5bfdb25d554cf1459212292c61e58a9a7d72858a1121929862c90b4222f4f051ff73eed75a754fb52124420f1fe01d73fe5e1cc1eff9c004881ddcaf245195d9a21ee3cec36017300154752600820e58a1c30a8eacd054b3cfa3ea68225270240215c2c880829afd9e1f9a5a14ef518b41d79f48210ca08c20744d107ad6a4ecf0a0358c34fd92be86813950b46d473ffd1f0f8074ec80b98ae2ef587d480e097ff562f82b7daf8f21ab0f5f1c532fd62992e27fa48e15996d7ae720980db633908e51539d5599fcc144b32622a0263ed1ac85b07befad3dd5d6bde7451cab8fef534fa42604246d40fbfb2f450a095f487df189d47aaa387a0d0421fb7eedaea8000b42bdf6f3b6ef41cc923f4029f042ccf169d0b3a3f513d974c76734039fe93a057019b5edece0f059856110a5bf20407f1d1edb678c80894c9a4740cbe110f47a5ef798ccdda8a9d0be6d39a4e5ddb521748c83fc239309f0dde5b226864958d6b4bcf8decffae2dcd0f2dac841df3a439752892d4faf58b8ebbeaffb70f7fef75d30fbee2ee33e535de3eb65c69f21c69f3369833133ca8caf77915e6556e4a06e9084f9cc76e14b9512bfc5f256afbfdd85610e5bac9556a5c45bbfa6a47fe0cffffd1c61834ae1973b0cc30f5cd65a4bfef80580e30fff6c6d33e710bfbfab877ee0fade8efbdbdd5b5818eb7c74eb02a7f85f96dcd594f40feff1e711b67fe5f7b9f776013fecdbe6f77d3fbcb71f04b93fec63fbdeb4a3ed3ff02ab33bd72e3ba57f63ab2f16eb5be490d7bbbe450e39d2f17a5775d5d5aeaf7791435cff7a96eb5f3f84f5adfb3b58dffa1dae7fbd8bb14b925e652c72c78b2c49589555d7930fa2657d1b52e87ccd22d8066a7dadf58544a83aacf2f6d4536595c52277aaacbe46d738e30b1de483e6f8d7a75afd4b1aec833238c59d1a2468211fb4ac6f2307ed63bc3c89b26badb6c9827f978a3e6077bbee93297a32846db26097904cb15346245962dba61149986a51f7ddea24ca7eedda65d77b7360b069f77d4f9d47fff7adfebbfb7b1bdedfdbbafdbdd76fa5477a5fbc309f7d2d6f64e1f979a4d4ee4b29ad5e5462c07b6b4ada3eeb56cf3fcf9e7aef1c7c0fdffd61cea3df49d0b2465714bad5fa1a9a9380ba41985f6c4d5ae0ee1facb77fff3e8ce6b45ef5fe7bc6cbfb369d33c3835fe6ed8333abbfef5a91f7ebc6638c838d5f668ce9a72ff3af31a6c9d807f55fbf83beccd77f3d1539a875af46105c5c80eb675ece7a1f59afb2cf7ad76804c9d73e2f7fea8f42082188dee20781edee83e41d7e6b8cf9fb5ebd1e63f8f5fb668d31ffbc1db61ac331e664f6ad39186320d07d810a5a25450c67eeefe5ebf6aa286e213441c7eed3eddb3e1667d18c30da1694bb22d64565f69f1e80bebd19635a3bfb7d64f9933b8d6f8a689b3f05f978b2515c5a1f9c9da7ab4c979536c30b6d73a707d01ca749ed09a0df8027d074d3efa15dedbaae73281ac00610a9d99f0f8a29bf39a24b5a0f0c9c31b514a182c4a24915a95a99eeeeb7aa13deb6cfb4d0feb63006f47d2cb6c39df0429b5020daf36f4c384d452b4abdde688e2d5716684eee61cfa754fc1e5a2bfe9bbf3342446480d72c0be337763b172fd5ec486468d628d50613edaf54e93754bb5fdf6bee23d771523a49e8bc7a14a48fc3099d6d41371b87f4409498a626586c79ca573471228726487857b4ddded4448b2a89feb637352122a583566d6f6ac2836a05cddaded4444aaa88866d6f6ac244034d8c846074d745a843d4a785f6b63731b922f582bedb9b9854e1f1a0ebf6262654801b6862e22567724c121936388d56a0102387a767c226072419589cd4dce0148308a29895281b0f2ca1b1e156938312183410c5684802ab124533e5c8cc0d516070d102918c152718174f96bc70589a61e23a8292e1c20851ab869718160e432e1598b0b232d4a222899e81650215129515124b52549e340998883644a97a280aa928a58e9680558ac429493ea4a1100623de5114700b2719c83a50f9b61872d2d500e561e104d39094c59ce0e2c001aa13b30491c541831316a38549c55105e98a1981128a4307229b7d6832c3931824253866b80d20866ecc11e15308be1392d061862462f0220915c4152461e448eb2fe0924e4d919fd029a794175a4608718ace3f381d8563b8c060051716a670719297580a620917220c059722495e14a1eb76a6262e64b6332db145298a5438fff372c733fa6c7ead3773de3b6d73cef0d67f1aeddf61c098ab5437c2a46114f346eb7fca5ad91b8a3af4c0ef0335b081b36bb08ef7b899c369436366436376e3a7b5711ab31b3561a7baf6a626aca118be6cc4f0654323d43a145d7cbd6c68507761baca6265e3429021d81de46e956fd9a06a001b548d1bc4f8da5a55c87a56154dd5f0800deff6591db705f1d74d2fdbec8d39c360160443777f6b7dfc2b0c9633066f68c559533bb65655b5d3da344d5a6d4803a2a5adf7e2947b06aa327ded8ae67897c315c833bf00b2edad467d6dedbceffb400f0c73288e9ed2eada2aae52b8eb6eba3eb535a5ba2a6df5ea572ceab0afac5589d3b4d26840add5067a2027f7b29f58ab79694d11f9a6668396484929fd1adc85f3896c6ffcc239ea0de60c821d06af052b052788e44d1a74acd38e1bcf2edb786028a6ec57c7fd316cb6b5d696d6daaf09c554e82a9bcca60faea86eb974b63e822df75ea8ad69597455b5bb0d9c92a8148d5aa85ac8ccd00000200003160000200c0a88440291389003a9bef80e14000d698c34705a30974942a12087710c44310cc30006000800439021cc40e7c63a00c05c9fae68fe2eec09d90ca7bea418fd2d40ca7bab4504005c71cffad36fa51977e464eb22f419424c2d3d38f04e34298664d9abb1d4f8793146e0024afc82114fca0586ed4a70cdb96af104519545404a66004e7ca34eefc301c384b0045928828390d0894e0b4b036e2a43af8b15453edc4fc1ffb5161a64f2a9dcc7d94c8c0a01d8da2e27e719b74e5a559470158960b8c27fd9622fd38fcfd27b4f940f63a4c3790a16a53352d99bf6c42af6b4becefb7773ced66e134ae83ca5a9f67ca25c260011aee88e76b3025f9326d7a21cf7759ea5340ee32badefb1f59c6e2ba377425db1a9ecef9bd2330a55f291f6ee82401377e692ef69d1497a0ffdedd9f9d781caf6f0b63bfd243f04587bc275444ee650c3a908dace285f08fde0f78ac6bef98df1f14e206f2e68a0898bfac46e83e5f2cf187413f2dac0ee5cbee1b1f43f828afe3d03f32afa3053283191c2b6349afa65e85c5e3ac66981558bb7e9ffb51b9d21215e91f7a26838a221904a728ba1718904cf4d4bf2c17c5ded97678a7a3c218e2285738490b2309b44fa8ec610c01f27dd040fd9d7882c78ee6c1eb65aa0c47c7fc118d218034b3a29e85c8caff92b424dafa0e5f42a53917a1ec69ca6b05ef986f20c61f2d90cc4805e5c9da9d1522cf35200ac67e178b323ef33cdca54cab19fd6198e89e42605b94b32eee8d4863625092b1957a8bda4119bc5eb483a5db4c491b0e3785f245f2875cd0d54f0842f0ed32392388cb2148dd3be9d6c57541a9c01650403ffa689bdc27dc94622602408a00da19a0908e0076909e746c3913e72ac3d858361102ee9275ff41c8a593351d6d83c224eaf0b7e74233c955fe1276d2248c6e19557eca7a9aad99aaa431e872246048c3e22c88464594f1aa3c10dab1a6984c3189b5a4b6d333a133db28431f820a8d4f7356204d5adbcffb858db73676e34819012ecc515279c0be777417485b1af0f91f29c0322988d04cd46e43fd72832fc153fd0b2a7da1b84851b5a621f09b3d74df82b808814181d583d34fadd488456e5ab9f98f93037ff9aa3496bea5d2a90296b78f188d53c910455ed591f5a1b74e3ae3ae131485b1dd4097416c77e4f20c90267f9ce1973884c7a05aee79122694f3b9c546492965e95663a6d6b980681d31bb97f30e06b44251da99c4d32d7e520e374e910adc0c57faf158b79824aca3fc21729011f5f6c2dd41196539896b95f3417b022e481f59e734e13d1b082d478924910ae28f864f8bad74cdc15e3aeea0f000ee20e40482dbf8b3e98a527fbb5066e8260001394b262ce1624242f0c9b2c029631e89f1e65522e62f2ca1c11639b2340c87eba922d08a5a187301e9474dac2c0119446b8f6dc5e38f761f7ebf6050b818091d14953a8add1d8777a591ea067cb116a76d87ddcb53d6c3a3a3ca1b77af580cb2f18091b189b8dfdf28e77b41d8de71ea6e97d423f179b3cfe9b2c44df26e3fc24f133a2df5fdbc798647e716b34ceab3ed7c4825183e96884773c7085ccbaf4da04dd6a854137d61e64f7deb5a15466414322c261dff15b5bf86d7e838d8bdf7f1abf731c6c1027d44574c609d5a99fd5b406f995441dbfca3df6d23abf7872fca24aa56f3268a601f827e265dbb1ebeb13ddd7b1f0fbd9111ed2a97286ca5c4e02699d50c47c5525b4a510db215b5e157a40f24536a2b2fd7fd3c8635f5f31b81bc0ce7fe2b1e5b6f49ac36ebfc12bbef7d9537e7a4afc748afdaa82daf5f67a607cb290e490dcfa5171d224388877f64ad21c3ba123caac2c449d9ea31a57d7e0ad4e304859c275689296cc76ec240d2719913c40fd512af955e3c029ab57085e30e1b6de388cd0f46814891205ed84a83f34f8a1fffce1ab17e98f8431985aa536ee8fe9a82a04e89a53de058de6d1ef971af9ec530908b0bb7a4189e411f7c9eef192378d15369a577eedf46f7400e0bc6199fb1f7445e882bdf01a22b37e0cc41f12974804ff7695cf12e8608cf62d831dc168f511798ae79a5bdf401eda80445b9be2002370f2acf9d3f5761da380f46d8ec4f1f5a8d7d84e7d7fb5d6b2018e7a1977591d03d7b25c35242b3a348abf9d9c64f8982aa1df8d56e91949797fe91eed66c7c873289694293e7fe14fd6a9ceb936a22a4cfa42151cec35490a5369020b9012353a5061b224b06fde89d62879649c856e0ebb6db9a039aecd92a0538c861abfc0072e1ae78b41836a28b8e2e03cc37819d399419cd2f0cf22b255ea0d19d1b5a1bc0cda835040dd6109f4517c068ace45f5c88ea2e2b1d47c44eca4456985a0216a2481edc1da14fdc6bc463fe39099e3ded34ceb8f7e4a7d9e491fcb83fb1932439c84a43e1acc4827bc8cf589910acb9e3fc5280e25eb7f6db74f73c62aeb4b0e3b28d55932cff89808ca1f92793d630194e127417db59c3665702e7b346ffd44d37a17e491d2eac6fa7821df12c5e8fcdfa7eddae66ba5b6cdc2cf9860406c778117249b312ab40bc635c9722abba97492d2651cb93b925ddddef15d17101366d85cdd6b2326c93dd49b406c556baa0be9b6667551b9d27d3f7148a100ae111af8d3a1f80080ffd98b58c1e48f6d12c7ffe5adf69c4acfdf7ef09f4e9ab3424b851f2433d9cced9913c38173868e6fc11aed90ebd9b7160b314594fbf015ab938680cd9e828b00354f05ba2b61e83cec61dfa5c15a11bc06cd9464e40176026a05906a7186ac5899134e7386279cbd4db0abb3959cf66743e71b4377e9db9ff82bc6994e017a716171ffb27e84f90727e60a681f76d3905395b52889902a6be781f3bb17ad00e8be2b809c8966905365f5f607f5e2289bf9fb68e7e67b288ba4c7799beba3a32d7ec047edf7120d03c0f8eb60761c6f58c532ad6e9abed19e6aa308704fd0b67ccded4cb452078073b26e2b498f0172979c8a3bb19907c1673babc1e8c64e7a703f415316483ebc94ebd8c364674ce6d5f2710b32db866959703cb4fcb70a0cc4257cb65e22defcceaa24326f51d1df9685aaca9cb175a2c78fb93c4859bcd936ea30df2acf3a890e1c76a57fba1b72af4b31e5125ac28f33b36fab69e7c1fd62ddae3c0ef678d28a95f0fc6672d7bea727b6c5861268dc47c412b8809cd55c7112962f616fdc61401498ec81650bfa8a4e9c8bd1665811e44e5a0e4c46d0afe7c142c06dd33136dda860dfbc7179403754f58d0297d3ade8203417a95edda1e26cc002fa7d51da63c6be97cce2f3f82eb98043e46e3ef044daf07d6d925615f7f759b3aad695f6b34d662a695ed53c16b5a77cbfed325249e3aae6b0545b4afb6c9729f53456318fc5da57dad7da64a692a6555d0e8b5a56dea786de6a5bd5c4f7dacaacae53e1e2feb9dcae305fb7cf5c3549aa9ccfe2b630c89d9fd1e943c44a93b7a339bfed65544947aae662695b9af86c2f53f57450558397b474db57d4bf7abcecea9f5a797c566dd25635f3abb665565f2755f363b915cdded7b38e9ec14522a38af259d68e60fca86da6548f8caaca65517b83c8cfa410f388d4add6bb2067050e2dce1cb34aeb1c8d46df8f9276804e3b510fd118f2ad5b0cdabb816c3170eb118ff3e9b4f25bfb7106a7c4c6c1a1c5a040027876c555e0b632cba2ff78864d825a7ac1d8659c81af9534ee893c9a71e9611d2cc8884bc1b907871dfc3a0ade3c3a8257055780751f1f834e14338de51b6d70189b6bb00a9a9b89c841384112b88eb7095ec4ce0e862d68e3014092e1d96f545102147a9fc551159626b7455119c105b25de4629ae50299857084a7b845b2357c1a5dbef18022f6e3b00c091b7c8bd3432ac8690d28bad157ff4288f4110e3434bd50d91e17e2f75b0f66b4e50e59d78790f693c60846ee2813a8fa4a2019765fa609da98679a61adcd22bca844fae23561260be80e1bf502bc179fa98bf1f24cbb107e1db7581b84adf5465c12cfa306420251d58cb76c8a2e7d21a0e5fae71b10ae62db549a4314cbe13daa8ffca28a356e8331208b84e254dc98d1361050e81948628f0e2bc6b2a2619dddbc71058b9e0bc98555ec0ea11e739be82236cc0bedb9c6b447d13371005e7cced2201c467e590970e4c95e7d8f175e072d68a60f9bd70fbc4d80374f29cf963201b66680653ec46d485eec6a48ea94fb3899694a2295b63c7a2f63d549e6ca71f209ace3ca0000fc8d880338c1f6134f17548e838cbc0884b886a6c4b52ff6c3a6ab1da3645caaf07e8eeaee61b33c6ec9974570b5620644feda053bd155addee87bb0b36bcae9c817a0174479032559dddd2c3bc2aeb15a8391e1702168e1565cf4c00408e76c326a7468c26925910102cecdc07e91de58e55e415989878e10985bd4dc592ee4ca6a07e4b773ca19773341f675b0180d8c473505250b18917f10ad4d97dce1c0a322c49cd7ed0733efded126442598e3e29a4785462019e8c72dbfcea3d9c050163d04505011a630eb8fd7bb6fd9f186e247dee811be8a4d81035d51b1eb60f0d5bfe3750af257b9fb9dcd860c7e284f45b09848d764cb2fe4efede38caef95e89713991e3d85718c6310237af0b6787b2c86cf945b0b5c7d311e03e1a852e7940ae8a2aceb77a25565f079be7947e5946f2a687f904c7c7b2102d96cf9260f9a6efd4b2e4b3321bdecb52399722756418391deb8bc27ff68d74bd062aa4482ed530bc1044a0015d462d9fb30c05313e0bb2169a930fcf51038a5240ba0ce0aeab00b1d125d2800eaf4d9525020a9da0f99e138ee7e7bfd181c98166291e2c058be05be63865f4fc628951e4221ba6ac6e374ca017fc22e81fce555ad5467727e18e20af3d053eb7e9d75262b793b16a64e53f0837043c769680eb5b5f4bfd3630a16b9b1e9d639070d27b25432636e5dbadad7c2ca9596daf75d9dff269c469f4ece6e0f6f8466a143538d3ab3b0b4b0df284f9e3b71e83968e08fc9619f07c88148de67111aa1f9e6cc79605bd7cfffaad1c6bc49a492846d11603392cccf45ab4fcc86b4e611e0607832ea79e26e92133adf5ceb2c9830cc93673e47c13ae6acfe7daff95645483c4058d0eda57443230176280dae3fd404e04692a7877a1509bcae0780442b1a5d336bab18603766166569636743df4debe9d789f013e8b7e44e34bccd2c14955c948095ed4fd174127aebc85eb647333766511e3b2ff76141889966195416dbdf22579953886e6f205de687ad4d082056975c3fc70b41704e98b04a0dc87e2afd0b44b99c5d8deefb676f855b3202ea8d8fe96328bee15a199a044d2b4dc391d164973198bf9fde2c7b6fe58903d5772b8e39ed46e4219a6a39b4dd9f331c551d16ddbd4f1a67ad1e91b49fb88736f3d5b73add1c38644131198a0aa83e114ca4cc8d498d6d441facf05709602b1ecb53ae833d1a23258d30108df7fb2ac283cc323487d956616584d26c2a1faad67e76532b26b638ac3664d31012d5533e934ea31a597abdae1619035198e0b5a61532830e864bc3a40aa3102837271b847a751beab1834dcf7624d9f86edc8a2a26bcaa219ac72b605fc226e33b0a128f0df83b1be42424d1d7910d3c440b8cd89d9f9b84a64144762facccdb937b8331f521654ddf0800bc15cff67e2661ea83f4c63f7a7aa75e00dc413200484afbc10a2b3b93f2f89f2a61f82dcf48263d43743fffa3b75be007167cd9fce0034dd9d72bdeb6e0aaee509981236978f2a73737f1adebef0429a61382a8a98c528e678d4147ae0de22fee1a75f6ac5a6bedbff95228117d99f718ea0d97aa945f62319e4990ae547bc227e78f9b05653ac448ae6da8c3117b0003820783a8ed6461ad548934343a92b8c1aa2e9638ddd599f2b4b1c6b51fcb3d57604b8278698428f77505ff86857128b28f820f369aa354a0d7fac8e3635c1d99ff5e3ffeac024b757a5059e160bbb0f6a8df941ae8384c5af3af2b926f719d47881c9d1304702a550fba4b17a3b0a88fc0d44b02c3bf3505e96b8218e96a60a8d8007e374bbe1c0abdb36dba28bc0e3d7860ba3143b3cc20e61e115dea9f77b39ff4642654a66d97c9e2be6c51b7fcd75cd2640bc2a0a1ea239d79911420b76a8f9032f4b86f98d49fc974194d42d0db35b5fa0e873f07ab4c7dc6979fdfc44f3c46ec3bf265edb57607e453d8f47d1d47035f75c580c76f964b014c70e4a63b6a5d624d7e82c631e256fc7ddfeba480394ecf50422ea120c59e9dde518a08e6b43cc93555d93173a586e096be66994a913b18a7807bfe53e20eb3d937d08e2d3fcf883e52d19ad570978a5959931b59e6bc4b296de470370da85b24cce46fb12ae706c44da0da20b17e787949cfc3e068c970f2d29659038c1984f8c649e0f8546cc229b6adc8d04b4043073dd3f9e5deeb4d679332d000a70d18dc78c915fdcf98dc9631fce20a6ab3fa974bc2be84ffb65b22cafc8a50b704b05dec39d27f22c513306ac32bc5f0399ed1d44db340bf55465ecde7f3a954079abd4161811380c175aa6cc0af538f917c048469921e8714582f9378bc107cb30ef27dd7a9a72eaf3a804babf4cafeeeedbee6980a9da17c378329dd81cf43c3705b2f8de849eb5c43eece9ed13ff1516b70935c9b705afe42bf31ed703b3e21c4aecccdff06f9bb42f338fc62471b11f7f70de32dc19a5e9b533d79deb88e60d391930c0cc46edafcad0220ee80c4d487fe3542c6f73c0e2a6bd3e791223a7a7d6886b815f2a9c086d7eaaff35e4e3ece3d8b7b71d828b15a7f9a0498dda30312f9cf089272690001c059e7d237c7a9ab077ca214523366612ad9ac42eacaf7777e5e2848d6d53aeae9866effcf64670820b2b6aa7d9ee3ed5f5bd389da3753d6a1da51e579b3f270c67d9edc9c945bdd0c8969c27f5130fd100022b430a0321f7fbf6c37878f5fa687b93b62f4d13e1e83b13774db76128c70029c1bbe907168407e029dfa2f4596c11f3497491bc274692d4a41a72b79621ae1718d86cffda72b864bbd6d25b2b72f5bcd2cdff70dce0e65e69e1cd59caf4ec6ee7e9b70f3de5728952a48836fc1139ed57cab8f8063ba495396324e71f7d6f4bdf11eed4d577d286a91eca4c01a10e2d3a884cb25ee20a72bdc23eca56f9346d1278910754659cc25de978eb6555f18d8632897acc44ad47cacec94db57da064d86d0ad98f92b129f93149dbca98b5ab3be1fd75cbe2160482b0778496871fe0dadf7b742c15b3969c8535145c11319d085ee7ea9c464ddfc5c15a64733ce21faa066c4f2a5bb752e1bbbedcded995f23b80c7191d91361657a5d68a32ea3bd64289c3f403dad87ec948049c574e06446417af5c633d455285cf92bb393728ea8f7fc113645c7e26849c74ad4466dce3df5dcbd61941f129ea7b87b54908f05866b81c9b109192b1aac1e00a0e3d5cc7babf9024cba7bb53a6cf612318633fd6a638f3c8d64c674be54511675812676a5565809c8db11ccc6a45f927715ed6275cdbcccd8a77069504ea08b970c8c19ad7806f4516771fbc7a0219c72c152debe06d7ff64c4113e984c80dc31d298ce4535e845db36c9a9d6d642c0923b880cc6ca211ef0049b9c7bc35844bd39397af7c03e11ce868db71edd188a1d50253971e341ef9a14a431fcee359b384ea612d2564856cb6152e58ee9ea19b6a9b02fd9016de3b306e34404a827549493c3427c291007e7a0c71c82f2ca37717384bfd49c89781b5e70e1a09ba4d5a6ad0b76efa0434d9dc48831b6f90bc5a0316d280e2816f325870a9c2301b84ba2e1ff961843b8f9e7ff571a5a55f51837f555635f05b288296bf16e7d94d5e0e89743030d82606fa4accce391ce90797d129e188b090af6f786d374d9dd41645cdb84208902a7b0a403da09b218179527ec2d1d7b7011433e5cab1d7b493e43f53f14b54304d32ddbec48345e27b2a71bebd4e07206ceb6d0597329e646ad29026d3e3dacaa03ec34b6523bb9c7c4d7faff0b4c7e52d09782aff6c966c2c0d2368125245939a24c4c69155e922edbff10e69a9dec9333e25b0e0e6f52ea5416b0004dcc6fe7694b3694240a07488c81f117fd27bf3842f83db2b40693439d5a349f85f68a31e5b518ad27fd4f2b9521a00fea4ab71042ad6fdd40e6bbc8b9a2da0b4c5795b45c828ed4ef4a3ee4a0395fea7d39246279ed2866b2c09866b44d929bd883a8c0cb32a4dda36dcb0f875bb4c0a2751072883a3709a4b43a7e450690f231da571c0371738ecdbcc864e372a1a3054f441f5228a34ebc97bf4b4ae256f997365eadfa6401db437646661c768a783772101881dee1e4ecd49ef1857248f157f73103d46a3cde741f74c7a512525eef969be483dd14120b16a8b5e99adcb2b35f682f937d3765d1f495c822014b495482d7cb64947aa1b9439119c9d908f06cc500f82595d6b31ddae02a5e812c54f3cad946ca94de3d8ed498cef15232321480f460e7dce4e4387d1112a0989b039d2790a2d509aaabe5076044831d2b303ad3c7a21cef0c3d090d330add88f7d7e0807b6a7474efc6489bbd3a2215289256d893c9858c9898202195e20fba6291db5ca3463e21137b343d7ab2e120437306cababf4e1f80d89558f19ecac8e39d9c7ec60966d7956517091e48eb4894d092f2233540678ace202c5c896316f54e848838705da9a7570e85882f1b384393ecb1fe1d78f616a9fd399cd283c02ff5135da1c29676e2855fcee32966daf1bf2cbc1e68dd468ce65749d9cb740c8a3ed648263f0a98ac1d69afef1c66217ad2232f91df036ab1d811897af1c1714c66a22873b9c0cb47067572ade0ebbeb575014ec89eec063e42939fe0136452cf33caa6a0084671c5128d851b3fba9d135dfa9f12adfef89c28a2815ff506e0f156d13914ede5fcf6f3842acb4bc95a9e516588edf01af08d8cefb1117c843a9e69e3bfdd8d4fd36c7eb0242232fc4abafacb2312b7a1efe832b2ac5f16fe11564b8b16cf8bafb01847a93bca4eb9f53b1358ad94088c505ed2bd88d759f783162bb59b220f4fc61616f641f635bf4c09e687f6dd5506fc5d5e5532cda1bf4c8e7338c8b90cdb010e2bec7926d472bad713e7b7a13c9c6cb5dcfcbbe331c0a389c9feda7431c5f2f88b3b88b65d95458a6e4954a87a0998918414e8dd8430ea0282286fa017dcd343df1a1f3cf3fe3237b76e122ea163e5ed43f9f2b1358b7d4df8463ce4a8f77610593e35dcb599e589e801224ed1a584614523d14e66c3fceb906307b2f3e5d79af2e8a8c10c025b01020b46dfcc0ef31b2de4537ed822ff806e994cd8655f9fd56c586d5a0058f281a42dfc73e627302d5b54cd7a79d9b3c1105cab772b7b13738d44c1dc6b73587c0e1580b8e522ed68dfa65f0979ac86d5c27703247a03028e41e0b7a1325d2ac6e045909faec6c79bd6e6ec895b30eec94a7642c89b543e23efb6d6b32080b511c44bb7360ee23a0356e4d3193b5ad073555d5423b2c6410f5d7151cff55b833c46003dbc06f2a13a8f796c8bd4b2fd1b3520c03bff1b89f2118b13e59072c96e9f678926026a8468885b86669b86fd7ef28a6971c5306acc8564321092298f8258cb8c03c45d5c55e65da669a58e76920f3026e2d5dab0230276a5262412756f23f532300e8a1cbced2028be84fd76c96f607dd7138ee34cc0155540292ffad24c782768400a27d9e3425b98b5ef928e729a0ca671d1f3e81bd45cb288839245d6a65a2da652df68ce4e274b6b4c1a561af265310f0e6560d90015b44ea429f876774773b564aa06a832baf836a6864899b2940462ffffea8aeae65167941b0e3070fb9f84816ad976eef43a60d340999e3e396d3bef011436612987e605b52f20b930a4724f2016f8a8f01d108d752ceca680bfc5c5c087a3c280bf726b731fc94db76d6431dddb97d76bb04c2b7da222577e90a763752adc146e9096a03d962ea68972abb024c10daad602598cce873d3c9b231f300c332497968c3909a6b89292590feb8936fede9a2be06f832cd5ddbd14181bd04d2d5536d28f9d1666c0c506f83338003545f22a01012d554f2d56812a8505fd19f7e5e2b9d1e6302b188129dfc886e572719148ac520aa2996395f914c379fa145ba224a900cecf494e23b4b240a319e9191908205546672bd0d88dcd2a2174f60a6e5354a73e600f2cbe9259a84861e09f706f23c04dbc972e88ddeac7c830cf86ad66b38e307c5f1beb6913dc51bf82b8e5199bf572264f11ce48b3846ec17f1d438be9ef2261d43412250e9ef540a5defc3ef7198eda74b7a7461dd785cb98e90f492ce4b50744101e8b0709720925b8bcc256092fe68b22eed2f31f880a0a8fe715c38112788a045ec89bd6fcbe33d1f50cdf6a1cf7c3efc582bdd4281d781a74f8b47cec551f19185f6d70990705f1280a685ce20db4ede6d9e8fb838872f6914d0637158940c0420e0d16feefffd59835ed468fc39da6b76d1ce13db53e3f28f2bc8dfc603398cf8143478b2eaca89ac16c842e869af85a030a2d98f8de041025e5fbb26d80290c2fe04a6cecca55faddb75abc08c0fd4ac07ff4967f2236abc433b6712a0ece36518e075591cc37b7673b32b556737d01a5b907523529365cb39ec8d231dad2bac8241aa1d392a8b3ac461b4e28c180bc337925e863077809c9ac507e75778dd0e251d4b62ece61e62139c96245dfde907e72dd7c156df1c94d803a77b90169c919005228a42c6b6268ea53df791a5a9b2ed05777f4eb37318838336784834b617b608b43a3dbc720bf8e151bf6ed4b0580c08159005ed9dce9b0061f774c4d821d3eb955e46cb684f4fe387bd95ac6929bf277f9dccfed1be173de9592016b5171f15019da6923ce6e899dd0c3b9801cfbde7b9e8967e8e29f9b6eaa2b6fbc525a53abe87b9d138949acccc2017c9e9df65c0a6296672677f3b7923bc221cf316b70cdf87bb735dde3383342178ce64fa3ae64b3477c339420ad0168c55edd007e68d10e887a3a41274d4f64af1c87df8549523a9107363dffe410a00b87cd8ea044aa742578832447bd915ba4037ee24b4da4e65a4c027d53f24531d9764d36b6978237eda9e51bc28ba75b995c5d52e298bc30974184df39cf22208a8383d3e238f35d87e579f4148a6b5d1537d793d3a9b112ba9227ccddc8ab0827471bd880af59d20f127237a7e420c89e27813e8fa988dcf61145df12c94ed2c5e97840fd1a3923d1e286618471cf82e3b15325d8e7e7b6231efbd0e300a929b4fc93e0352e0d360df27c362ee1cea28b77505c257d777dda1d1f02b71f868f523d96b2452cdde21a5793141ba400b053a1afe0db98c576e8ca9ad65bdb5cd8fdc84beb8bd90c41fc0276304367b036f099a1be4a962134ca9b48fc1ebb028bad4c63878048ff482d3dc95baeae3441665a419c43cf9f2fa994a2b01fe0a90c529ead926a83ed074599875237cfb04363135a539e1261e0b2ec5930baee63e8d5ab730a04d4d2a82e410db89507260d227f7769e396fd204afb4dd7530ae8c54a4e7ed78b167bc051a40ecd85b01e4f0034878927f6131a79cd73c6f7d4ee92e060de3484de0a6fe4e4262af80712f567a58c4058c09c38031e5b0e132efe0c7e5a5b68f16443751dc134d0700276eade613407f21156ccd4670d5b83cd7a1b9009d33e05b2036fc7fa44cd5599f0971c45d72e65a424c2f6b2b84c62dbdc689593b3b680fc2044aa0ab4f03b0a3e09c28114c9638929daf248d89180d51cb59d28b1fae86d59648529989c13bdbfeb1d83e050b1967243597881e1a4e54b16bfb1918b4d6a0c0025ecae036c0f31a4e0b55b87c97e25a45db8e2a6debb54f987383583adeeba6167c0e3af1d01d662d3e349751f05a8fe351e28d4f37bf0a56f882c71018ccc01c8e6f059451937286d43871281e65196925ce39eb00e1cefbb80503928a44921883401bb08e91eceb9e7b80aad06926536b44cc14acdf67ce15a4f83273b3bff23380a26a699626e5252afc33b70ddf85180fb980972862aa4c02acf3c1d9a2536baeb3a6b3344047ffee982f895a9b93791dc6ac0b88f957e48ca880f9911b2f6d870a4f07a13e37d99b774ed59241e30eee656fb8e5aa21645d7d82c3cae04a66cdc73381e8d9fa52d7c6e68180ee89b3813c2965edb23227c7dd6336c5ad4ae811eedb0bf14ceb8bdbd41787ec00a824f3b7d86ce9b38a2bb8fd364eb175d12f6ac2a5640749cae40de910f27da199673d5e83ff140037f2d82591ed04ddfdf0db78174216ecdc8d3beea8cadeca650a31ffb7a8120fd20ef337aac9b00ae04656bd0632d71b33805ce2dfb5c3ae3a95d6f09bbc459263f7ff2b295aba3393d5e07c259966caaad6a4a734316cede8fc475963d232ea247e65b32a6aaf32e49b1e20ace67a986be6de43841017b8e90e15be551021fb032956914cec09a849350dfd1cdd4c2abe8d08921473cda3dcbf9db85dd33037aa468a58e44559721ab0cc5e20b271fd254e03166a161b14e0977695506c87b320aa16a2422f0d4203ccb437d1b5fdc97db79bd8b80be01bbb6ef8d7f92f0f109f2f61b6a83f473fa98afb7882b2a7a45b490f759f755bd260103ff6b8ac729f5e7ccfe8420e37f370b392a92ce132c0a255e389068be67396e4886f3c03e7695807783b77350cf6bf6168292ec3b75cb43384b96b716d5b1099cd767624dec7a0fb231ece6d04d8ea06304aebe1e7a10a30a215b8fdeac98dcf67662d883e2743e3a56d32b020092ea6a0244ea2b704f062bc34e259d1546d78b22b48c9e6e028ad1a5142ccbb829561de55466e5ba4b3b2a0ca025c346ac82af8f5379e4caefa928e8dc9ce7cffb5ceb0a0102dabbc2bd0c01d974a6c1f873e8163ff9a40d8e482c32a448102bbc4bbdef320921052a7f66e351f2132440219c877eb785ae8a50048b8de6611bc631694fac751578614fc8fb81393bfc3aab34f59d9876f430e879041ca2755f0b004e8e362d58a14e65b3ef4cae0c1615d5317aa99634a818eb50b82303c489b67f681133a790f3d1331babb2c706d2f0bec6dcad5c39c1e4387e93eed0eb915a852bb3d218bce32aa62cead41ecbc383c60744ba25684148384620d9e548f33cd99ad200cd93004c0dd988c6812732b73a470c66f44c39182404d5f761632a21512a8588642cd8318fbce108a898b0b530bc68f77c01e9ca09453caed7f3cd0bf61a93132e72f4f42a7f1872abfc921fb66ae37cd63c1ddee038316f106b012be5aa53bee645df8cd981d22abc141c8042c89c1ba959bc7fda8ae514d555ec58632913bee3baedcbae500ae352b47bc15ff03390e00e1e0e463a25c5eadcc0b2d05be2c73595dbcb39cd883c6b4ad0341cb184747ea81ac8b93519d41a055d43e03558900a378b217c096f3b4f724ac8668ede2142a4d8e2f75e86e8d4e1f5c29a3f38a065a1cd299d33c4a1be48e100fb380069b9875658a14d020d182bc9bbc5fa16b90ce1b6dc30cadcd1c68f11df688f2621818714634e0eb60fd1b552275630e627452305c39ec93f68f63d01b1ba80a0261ba2d0005b09846905b197383e0ca16d6468592ad3bffce823b4f0826842a88f33ec90adc3451ca7e5fa2030758abddf5d363e2182a892ab8f00e6fb5d6a83f96ff89a24552de7fe908289cdd16aa686472762ae2226a31b430ab855f355b6961772b21ad25b7d29763b3eb6f8f587ca28df4652b07e16ec165ffa94408fb454372033b84aabe62717da1d268808e7f179d9077051364a7c6a37489a6b9e5317342baee1cf3ae14ef4328b656b5f6c610d989bf72ceb97b439ea13a8d9197ec64024cbc0ad456c4c957b829c34ab7fa6ed2655b1848f7397f6ceea55d6173eabfc7abdd6ea0b64a6c2f745cb76ae037c62d0ff78822720e6e52f548c9d21d3312576952cd17cada685b90eb55c7afc0deec6a3536adcde91a1f3d90a150f8c2f82dd40b6b59901bcf1c4228541a45ca8c2f77a3bf186685ef6f565dc13e5341aab50590f5e5a5f783c5ca618dc77c6a3dd7379c2fd3a61bb89bfb19cb8c47f2422ea213475cebe964861166b1e7985f9e43c07480c65ebf7db81b3c2a163982d1037d96777ae17b8cabfeb69f4f7e68349e2d87d0e7a6ddbe87b9d9eceda07fd5aabe3a08f030291bbd7f7098eefa61859002344a178edf16ea475606f107280483208d2c51b3b1a20dec03e4c87b36eabd80fde487269381bc7c2c20a046481e267c5f472a353ee3cddea4b0c955129f7d11e8c54b43fdc84ecbc48b956f7715bd7c3614c5ea63af1f4a9f73904bb16e99659952326e05759b57d1601a2622f7d09d8bdadcbd33026ab8b043659a7ac7b7f690ad87341b5b08386825402153460f231de9c8d175f5d1967ff684f0bf3d6258e88aad351c03b09046ae75b43d60346299ba80f43d0abec94f1b7c7b1f1df5ff3ad02e173c404173cd77c2f0cc46d166a2eb8d4b05011dee2f1a558ce466066905f7c64d7a90560b2003a33927e4dd444dd6baea7372a87bb513ff962782024397774269c0e8f58d4bb3288df68377e6348d428ef53e6fd7a4fc9c3445bc39edf86d24bb2124bb18405ece731c0fa3166ba5557a627350ac062b419d328b900857f795cbb674205d36a813c6f928513dca044e1e708e2295db08c44fd59d40972a7c22ca7b24a097bad055b4ae0cae54516821af60a9fe1910998bd3a543f0f3ea49261813172923ecf2534df50ad41ec8d51864971efb8f9ac96084b470f5b6ff467429b8e96fc009f8778e481f5abdf28e1fd8441fe51be17dfe53af80a33b6ed1a71446f0332db884a2bdc3589695ee4a02b6a1cd37edeb59e49f5e36f513ea6517ffb30938bffb34de828d9401c968b9c3d45f88f14a92c67c40d4e2bd190752ab7295b16affc87e087b26007d92e1c2a1851f9183bf9dda53c626264b00916cd00ba2d9091097d9a66f1211a86e6c87e34747a5972cd79c66e2ac1bcea95894fab5190f131d2a03e8d5aa1c6e64dbfac84bb6c0099f976cc9abc72d98cf5a8a7c41be9570cc7e57e1c283137cfabf19b48cac70929cc130ec883429fff8cac82460dff10bb00b6293556237ce8e7625efad150b4ac50cde2fb33d9d8f8156be0e1c5fa45eec81d9916a15565959954dfa9a00fffc5195928a4c3e418a176f556d69d5e220afde0a1d3d458f131f393f5274bbd6645626dea51a932f0fa1de52b85f00e416454da9438e399f4ef6bec6c3dc7d26458167d2ac1cbf26ed52dbea56c8ccc4363a68b9f2448932f911bd67f9618de487f90a237557d15a25464cb26edc28ee0f99bab36d87f1c3fb539b033d4f969796eb5d50d037138366b2b723dfac2f08a506c5ca134adc0034b23bf446689159558752ea1849ad157ee626d59bd6c798647266d45f6f0b15999b80620d9a3b8692b2d15a2a986a5d6eb37443cba2f2eff19102ed3c32a9b3f2449b2a016570cad62f270d04861809d216d488bc660d83665f7f0bcac95a4f09287a31786af4caa746650fdae9524b65dc63394f54f364d43f509a4636213890c082623daaff17730dfd36bf12f7a99e3be02d7bd30ba1b7cf05ddb70d517bef9d9e3985b706911c571266d971d9bd31f478a2fd83feb1e14f2bf48084a133f4bc404b9c8bfff24fa405c857482e5f2e36f8b9e4b1150edc2f772392cfe3f386bbfedf803f1a31bf65765d89a1e15993b2cf56527f25f3a81fd6b474106a1fde938603fe592df79b835b67225c093b203fab507a5996a53fe1a015799d209e77a967b300aa534641c3c049b4e5c8ee483c5f6893065c9188c0235de14dbc1b89902f38f72808ca52e17c85370015c149745793a058863bacf14619df43dbcefa407831fdf21216ab3946853b559f83563324a4452657e8a7865b985442dd6c972bd2f99b226db820cd18373488a9a7f24e374c216c41f9295b0f707d1e65e255cdb0e9bd45ac2553e822f49fb50052b52f6e7ebba45adeb34ce38b546d56825930155b14d72ac5d3696e0adc7eb4b9bc2ab278231956ee6dacf2becc09a77859c3011c9b4a5719290abd1d7434ce37a3e4cf627d616f19ae5bb466ecdb02097b450ede4b38bd2bcd5deed6764a51753f36b3939cd2605a40d12b85ab289bd2643173459c01eae6f46bbfb4972045211d582227a23932484419179053b1056eb02706129d18907b1bfd6d5fd15ca7577aed77d7a019ea16344d2d50dd0f2b5e51e03b994898df1108344c9afb6c59065ff33bd761f2fecfefe0fb2c7ce37914a782299ec50aa91be0388896ab0ff08535fe1f9c7838aab2ea5215f50ae0b74cf004b2778b7932ab137c232e1eb4c30ce3a173b1fb90c6d0da71e614802e79f949b6f941f2addfc02cbefec932140c9e34e4c4a059a7fd008a911c5af3c4dc3eaf400172f0d9f022635b9fa5e184561a742f73727222284416592d65c905183cdf07cf0c9890e8dfa952a02cae307a25dc4944d5d6215ae43f4cd6d8ffcf2877829a58496eeb3de047aeb20bbe444686fdb47be2176313fcf7d47740d3dfe463faaedc01a783c232cfd11f11836bd1358c8af08ed3251eb4c070bd21469d0e5fa584ea69ed94f92789566d09d56817251699c9e7ac4ab5274585eda22a39a384ab285bb36ff8e64bd3d9abdecd8b353f69ffd20f3366353d33e3d28b9b7413a608b43394afae3c7b6eaae773906fb285df33132bb1a64cc991bd0705dc3e76c8fdcad78d7ddde0d96d0a27084c914b71aace7ef58869b8dd1ce47440ebdf4d15a6a9e0f64cb7c0c9fc6223fc9ca7c2f01dad07c75eae0e942aec78e7189f9c4390be54c123ec91ff0e81309014ccf0367bd0192e2a8563a324e2fac01c8057a676942144cddad4a54180623034fb771fadc3075ea8190a4a9e094e96a794e0e06c419cf326d66bfaed6698bb52c014e3752b4811a652907d1b8e416d2ed3d4c5a1e781f9dbc30ae31948567d826e400f8add09595994ebd13cee926b8dadaeda306178bad4fe4cb128377aeedd766d4151439fe16345f2c2ffce350dab48e59ea854916723081e4a7ec50e15a684591ccff91a2a7f5468271c20815abfa4ae21e74989ac57fe1a24d3d53222f40d384d90632888b008662903eb0e43b590a83082c24e81c6d6dba2cfb06d5322b0f2c5be8a9816cf4dd2c388176a04f52fcfa2597d1c4892ec75a66b66cb779adf6dcc63f95e37618079ed0b409c89ecfe27bf7b7cecafc58b81c3f52ae9f6ac65801be66b961f08c2ff9e06ae543163a3ede2089c1242fd77abce5a80f8f25ca53bbe32adbeb1fa7708d93d9cb546d64b9b17dba4d2369212aa672a25a03e6a58a7e25dfe1d24ae12e935d37dc1d0783556a5f577b3f2a96df2f7e4253d873eb67a63d7871a08173516165d4e2a1629c887a096d04a31a23ab7c2e64c88eb58e057f9f288bc01c7f5f27052a7bc8862fc61b4c400dbbbf9ce7ed173faebd05626bbf0fad1a0a7262a1fab65b66d6dcf8436eae896e821b1d250905b02bf081557b341395d158d128c7628d28650e6775831aa0b483d33453444143e71624977fd09093846739880bbc11c6edeb82a5520db762f7f3fea8f50c1824e2f62880a91d02237e894b8fac953138cf162511b3659f6b7a63ce7f3a0e32e336b0e00addcd1d7ac998a4535ecdf09123336455fa4b506aa970a7bcd76e3202e1c8d2abf9b404bf3a2dce36562a680674f54e3f1deea982c1bff9b985f993870cb3537dab515ba7d449e3d14845333d657dbe9e2ce1f0800ea61c365e7d14cac5926d20ab49e7f2603928080b028d8db50ac137800484805e349a14fd75fde8654af5b1e77ff61eddd758006335604b140805b2d1fa4b8aa3038dc3759e070f9909bd546732ad4257f64a96b1d11de08dd7ace4c7dae2558b3502d69f43ab75ba87c4cedaa71794ea805da0ac77eee6081d28f4dad1681f941d2fcbbaad4f85cf9acca0db3835729bac2e49b12a46a391f87eb12f8168f674edff1dd7bbb171ce100d31f897c43faf45ef42db12e485dfea49b0ca47158dc7a1fefd5adece36a28169e2b99096263ad302a7888c25e67bb695035c3304a31437c72d6687c71671f4937a3ac9b11b3b85b348298a3498c84491b0606bdacf1afc9339373006bb36e8efb4ea3bf53491f4df67e5092564bb6e42a044bd2470ee4695c05bbbc10a76e91cc89004263b25bed8ba2990562e63971f158d51fbf3434fe6cadf8e01cd38ccb2febe0322d4010223dd0817f1f6b12ecbceaa9804848b1795eed604d5c216c25fbffd4e97ecc1aae93892eefa33bd62deaed805c777904acb18351c41c1d60baafb541b454668a05bdf21b1eb5d41b9dd2f6f6fd5ef4d5266eeaf2867621fe91d7b0276c4db0784e7b3a1c1aced8bfc496412f0b7a78899332a84c95037ef643b63038c82d122e6e8458ff268ce03d9457da938124d3250b74e28a3318e19652668c6682dc5414cd0ab3114ef5554d3b7bbf6110a554f691d10bca0f502c2968eeae8b3d22a08b4fa0e984c3a2d41ff1f6fc15f8a8e2a25ec0e4c9a341d4aae5d6e0c6276876cb4fa1ee4ca02014fb97785804c5e815d7efc1acdb1e40471d734a1d07df6da55c9ce5d56b4ddaee573a16e6d62d47e3b2c1a51112f55f413713f31aa44468556c29b6c11812f63850575f387b883766446cdce55786c78197291aac637b19852633d0f2f7237b7d88c8fe5e318ebbf39f73fbf138f79f1ba5a70c740bfcc8b7d50ae2cd10c14211bdc6a4294829f214baeace35029b95b1c704648b2e1223fca730a81a3343c0c825e8f55b7b04b16e194bfaf1f1599affbc1de70216fe0f1101b723d0193f874cbea86dc2ab90246b540b2833372ddb7ae2cd0b950c701e067356e584fc918480f037c1a4828e85e6abf9566b012c006ee15069ff6f361e130a878da86e2aaed3fa5c1c4aba6684ee5d513ce9d4ea530aa0affa6424176b977037057144c79277647d34847e7d07eccfd4f61872e3c20016d08e46bc6e105c2d15d099a909b4b0eb257484e9b86127a21dbb5eab4bac8544f60ef62ec3883396cc4967e9749a045e1d75bb9a16259ba9cb3724b46477ddec1bbb430bc8cbb68afd7dbb7551c54bc77a726f3269fa8a4d6f9efa822eccdb47403d1ecd09c92a5b3922e86495cea03443285e8c852342807c86a75e819882ea2fd2fec85e1ae04351a7c495f1779d7dc2a4123da9a2e25a0ce600edccdcc280dbbd8d3169b7e2a24652023912b84da0545bcab4c1cd90235f0fd173e4e3649e4077653372c3de7557c3036712cf736136bf76cd53e962ae4d58fba71a38e404761c0f4526903adfbbdd9ed49f66902149f2ccea75d7004c9d7b0368fc626d0c618a18e3901481831fbdeed2b05a2fe324fe3a144acabf143411522f8f6e18b9bcf8e5bb40930b9d337479326a5fb4bcbf7f36f75b6f7c1c4676beb38d47a31992b4c33286b8e33cc43c7ae5ca6694894b6f3da2c26870928bd8bc06a18c7c9b8539157dfd75d3c825455e6ce91c6666e957f8214675b08521842b85a7a1c20cea6ad2272bd24a624565264f03be1e933ce411c1ed39a8c43b5be832eca7e4c4e60bf67bf70b354c3efb386c36b75f4fea31e604ca8bf7e06ed16ac9f62d851427848396e75d737372738b3c65786e9f4865d0e845b26996a8d3482c4ca68f3fea33fc628ed60f0f266cf5b1b8dbec690cc9b4821601fa3c7888db8219ebfba312043c2f29648d0af08da21bd36d8cc2d5821d5db288ea6e2cdae52f9c0fb9819b60b77d10b0017b26ce4e1953b10c66d53f550aa9ed190c8499e1497823b35b6d2aebc19081f8f27e0f7c6598818c9c150960e2c38b1befcdb7d6703bdf0d0ce1a808d55ea680f5f73d8e916023440431884802ccc7084a8ea66cca10075f759d3e5e381bdef9ff59d16a05d2429c4892d158cf9610d97dd15a088e597bb4bc45a582172837163dec0ea540f6df76c74356e1c39d47f850031471e25b1462bfa2692c0d646ef25d8a905129d314953afb16906191829e688f4a00e77961afaf0fe57c6f60501734ecb67bc185058ac831806098c12c34994127f4ac0222542943d4fc412aec104897198478664540c3a2be7b366cf6755221ce4bb068f16f0e01198f340f2cbbc28f7c576d2ea81314f6aaa732c9be9ff77a6391e2ca35b98c3dbf6046fc03aa323f4ece904131e22a1e551bf85e0a3388aeffdfb92d5b177d67742a534346e2b42c85daa45be3d23e4aa78a0455376ab0ab22783a5ada30c67e220edb2b7902714bf7e3dea0ef2b3fe3e2e8e4c906bec5698eefc3ec3c96ecf0c3774bc7177cd645a0c8c91bfa8683c9953e708647a82561d599bad6e79d5fdb673dad1af2ecfd8588a2d41216732a30af2181cdb3aee0c42b8d2239aeabfced25264adfe40e083ea70f18b748fa9bbdcedc03e1d0d9a6a29f640ca5b0f43c3af4837cee5bbabe31ff15c12fd77ea6f73d0e29675e199c43ec12fe8a281c9af84c06b96c526c04694f774031f102e60824669d104c43cc73627b32b90bab77a86c37c153887a4f02d412a82e704a6cf2a5ce5047425d720f8fe505b70c3e3827ef507eddce3f6260b26169af0c34a9bdcc2d08a789606d727b5ca792a29d9fd185e22eba5a6b4ad114980468f048d72764d5b0bc30753cad5bd3b65d19b9667282d3d5a54125f8b72d8733d759edac8e5b3878dff613829fb387f9a1cae9a7383ef33af04f9729c13bf59ff6962dbb4ef1d8885deecb08480a03f292a9667ec34b4b9359a8ef079b5dd937d948ce72780e0261c42b321d6e28b02bfe1a11b53fbe942cd2be607b7fca9b45f59f32cac236335fcb0691e633d745315edb50b0d60d2e1c57c2922ae2da21581a920e26d32594a96af466ff10e12e4c54411d94bb0a1a796a2144a1ac44ddecc926bc23a54aa12537041425bc42f5997c8ccb5e7e8f3ced68bf4d93a55e37d94c1f8e1519cb186a6bdf4f5a11515b8dfecbea5f5645d5f965d943280722bb4fb43b44d80388b20d24e8c30eca10cea030197a8a08f427e3930fd9e133a64f4f028b39498046d332a388da9dec4945902f451a3b62911330ee3e48631a977eaab62c19cb62c45e8db51f41fdc63c2ddc993eb4aab5eb000e3e14b4e0f62a3851d927b4d3c8fba0b4bb5eea9ac3e3774251d8a27e40929d4584436f629af3cc1ebd969e67c7a2ad97b47d209e22056d8b50696a5977b4577a3282a21103afb7a11e6a0570602aa88f8be685aae5743e900ff935fd8e1c124d40578a4f2919ff33af9184fe91c0b12d3352c4e961ef438308f8a3085793310a4a32e56d92e508eac8413644de29381915e5795edd24117103699b05d30010e8400f509c19d961760f7101822babff2b7165bf58f4f50ccde370f7002d8b729f7f4d04e0026bba6da3d99b3e2d457ba2fbb1e8b8be2919df10ae21bc3e0939876206ed43a433407fccefb1c24c175b3d242e879365c73e7473dcd0f73d3f33d168f22403bee234ffd3cb5a4a58a86df82d2104f568bb7ce48b62b0a8dc72c41e7e386ed3fd1e9c7bf17452920e4d9450be31c48b23ca39d3d1eebcef85f9665131f744160133fd95f7713e6adad5362931715c6628d0b3f5adab3c993219fc5e53f717eef55de01d499292ebd7ee3e232683a0fffd1f5cefd455b561fda31de7eb9516a74e2d205866183a7859fb017bc0a3f7075cd3a3d1ecf4e0692c3b08c42066bacb53b92360a503582d3962d137b0443eccf7baabaedccb5c1d297fa5228520b3f1735813854cc40582999c34835b51b4ac8591420bdc5bd5fd68c4fbc07fbe9bd6ebdf072cfdb74419ed7ee2e9b80ee5a8e7eb28ed7e4566de7753fed365e67d95c29d7499f15e8502ffc3873fff803bad9b7b57dd5e2f7734e912a54a928cfd29abb5885aa2cc72b78fe2afcbd9f75386b150fc98ce8f70de5166be2b052077d5b5a3db307f0a8e54dda003537bb101063b57a36a9cd23085c338a16f24162f79ca6d0a0354b684c5abf9fdc852d9273ea863c2ca902b0cdb0a3ecfd8d1d10dd3baa924cb49f1fe39f1794ec03c3905570711bb7c6c5e151b0ee2c12892d4280b78fcdbb41a02364902d8096100fcc32114e953085804fa03383fe96a2dbc64410c2aeb3e91eedc54fab9c9e892bd39fd0d8d9a3c78eb2a7a0d6ebb36b3ea697c56e2f6c2490e6171dc64851123343340b35ec120fde5cae1fae3a6a0c0fab55c3c57ffc26ba8bc1af5d0dc60a66af06a71cc238d9644a16d1f417074f9fb8371c265f29ceda1a56a801cf2902124a0861437ca90c61d09246993c8a0ff60e9009652bdcd090644b03a2639948ce40e42b4dd1115f11c4b850d0da2f7b21c1464ca4c55dbf6a450fe712cb292ab15796e83301f41e59dbc6c62352f07b381a52c03f1bfd4c28e14fbde78ee5250842627464cc1cb1eae6a4f69828b720cae2bc382f69e9ea05868bf94293b16421c7504ac2686e7142635abd4c0a187d209575a8b27e182b627e857243db3e016315972a896231231c6f3de011c96be9c307c39a0387bc899d111f06aec9970c42a4bf054938ca79e103913c616dcd51568f3940cfd406c0e0e9812b46946fd537a3307347da1e4024a2465f8936befe9fe853c986b6bfb492f6f4aa2fc6a2910b86f411296b842e3fa3422c367a715cee126690ed86d3653142f181d03affb808659a5e7331385c27513ca38b37d98dbd27d18a05c91365d8d06a83119422044d6a6fdbd8cc275d63f8cf873051e3ae81c0d468f2472293680d63b27f6e2b982507ef9f0b679aaad0da59f485c71219a9bb3dbbd616f3dd49a45cd6e855420505296570b7322bb3b7857a93e1cd4bd689fd6a2d34d3f2f6d0e763ad195c2eb9ce08081b14b9e3633972ddd2e76f85861bb8d240835ddfde4c6957bff7370bad72f11723bd39941cf253c14907712d71ddfb1a3fe897a517e17e774e963c1c99789094a4299c0189b77117310343d4369dfe7801a4f3397a436cc64029474186c57c822d217c547cbcb4f6837a128bb8a3f7139aa5d179d5520a9776cf1ab93ac89d4453cbaa76c74998883ba8c51b47e7db9b69190ef4219cfc7deaa46c51f8856be25d38435d31b90464e858b7e03351b1f02217dc5e06a18c23c3a4aae45ebd829de62b26fdc2125943fcea4d30ff927b959a31901c704039d03af87a3efeff821fc384c165d630c63511a29f2373918d23910f856b0c7f2e634a23ac3895fc6a12562244638df7c62d4a240b7e625e5647bd1d64fff9952bbfe12611c84a85ebe1705c6db0730a8e549c1a29e0e6a79e950dd10caacbfeff416356ce45a0a0b55c0fcef68c6b5ee059a9a422b172173404a1a4c4345d71759529c5c980458254bbd34a4c7520a6ebdb2c9a5517d57180535180982c7da97000a942f10d61e29eb932ec3937a5fa1fe7363aaffcef84da34e0078494020c3e4c12c78c832fcf0c506144751c1aa540ac1d9079f33c9c6fa37d887e476c354718d884065cccc22c8a2217c5e083bd9c647249473a8ce212b128b86841e0424c9fe8482c0c0fad8ac30614576fdb051ebf19e2ad34dc509487003bcbcee2ff76dd280317ea22eb7c40a65a4910164de1e480564b735d17e21fa5e205b0986fb401e0e037be5de8c69ba4fe4e1feb2444ad0a2dab532058b31afb81a07f5bd6b4297e14231488cf70f3de005654a684004af016c14b398419617078e6a0415ec4c05a341e0022422fc63340655fbcf3d7fd201e5dbf8f1eca3fd409d14dc14eeaf1a97d88f1b0a34c3d82e41942b9772857f99994cdaa9392c1fd1a0688761b245af16dc0b0acd01d7105f940a70b7218b8b1b67d8bfd1ec7d2f50852dbac97f4832d817a4817255f6308c98616db92b105091a3b9fc2d9a0161a8ec9d50a8970b10dd6b0eb92701888f050cf0777db483963bf118bdd4f8f00c911e0fb967ffcee4b175304a65e7f31f1f8cc82e624324ecd04851bddfc0181b7722a9a29e2ee90c0c596b88eb4d50cde915e0edb40fecd2d6adbec87de566456f5a98e2333eb8e9d7e0b10dee51ea3a6fd285138d716bb262eb736479bbb8b1b65b812a60ac3310ec8a9d88ba5181bef810cc7e91c018059828699da3d7f7874d3e5af478e8bf198676722afd81c8120faf17740af0902576097c2cd280110f28014e76e7450be899835d123a34a941055f32c81d3b4cda3e0bc14b3475331d21128799ffe9fe582747031b78d00cba657af26915dc8bfec97829f19a08fd224fcc59d5f670848be7073a6676896ee307c6135153f42e159b8e64a34c2f343264aeb46be102d632ce17e262c0a2b6f8f5b2264c5f685fc235a879f98076fa3cf259b286796e507c0a85881199b9acaee8224b4c2de04a229200224a2841561ddf13d35e8b4dd43b8622068815502274b00d579db863f3f809f27d6693191b70a11e4479caeed8bb84504a06d1ebba9a8485630e852ba5f7e8e966689f15b51b003074ff662538193519357a53d7c9de2715f20b62df0762390a5255bc99049d852a0585533f3fccc908bbb56323de50120a32e75746899915e4298a3eeffcc81da3e577cba4c0334c48051c43032a5cca7c5e300cd29a0e4b1172ce70a7d28adea8a89898351f71d200f689174e1cfca2df0d26b82c280e4ffc1d5dab5f0ae0d661281b38ccdcd7f74b35eeea905bec192f916513931a2843bd4ea6b1be091b706079eb2624a4edbdb7945b4a29a59401c4077007b107ac2f43a8be1f0441281b12896f2f52dfff3b78b739ced2f683563328fc3da68b40bb08349cb5a866cf7efe240453c91d5655723f1d43aa1655df9f0026781952856fd5f78356b676e2f78357f5e7e6f7836aea4fecf783fb4136f587ff96cd686e46d5cce85525cf40695d3fa8f283eafbbdb1deccc8990ad8cc871abd66af17660f50496d32f043d6bb9e83a38cf55e25bfe7b35949d7b7fe078997f62ae788973377d5f7a4b1fe4a647df97d93b5ce4a7a95c1cbc68f8ce8588b627d56a9d9c3fa1a52600ec1b034d628637d38ca38eaa52c7cd7585adb076aaeb3be352b6d8f4e59a32c1c39c01d7c709c95fcc6d265d5e97ba38515dd19bccea0e4e827222ce41788f8d0716f9f53446e48a19fb7f7de9f67dd9d7867f77aecba518ff8da592b943927ad47984c364fbaec3873b5650c8ec98c15accae038c146921fd480550110728181961e4c4e49141982081840b083d40c4c9290e1614d9427f1abc16628f45b62e58420688ed071631a2254a2eaea0f326e3fd08842a105dc95104a192e4a3b9e7ed000d252e204395f9315256c803923f2dcd27d34c8804081062d4a43940441a1068d204ebe0889c244070f5a98a28c4c40c404f45b42a48409e685363228e191e5cb9a23c0305d478b76ae8cee7cccfc4d9f532e74c969f16c5b6ea0924311294cd43092440c34d8ce14e9f0a10a8f25723fb4ec9316224e9f532ee06ae8bad8e04293387738153917f94e9f532e2475569f532ed4e0974a56223e95904606282fb6265838a93212a6860a3768513244f47c54515500c812391e369248f181028d10358e9880bbb19005f79099ac30c1a29f8c8ed43253c02a45567607fab940bf5b9fe1048815486982ca94344f4325ef754ab98042995eff8f7a758146873d897921cc982c5ec20c554ddd96d831df49e3389428f5546495cf9c38077438e78e2e59db4307a14628d2bdf78eb89edf013d84fc9dcdf776f77e972f3969f331c673ce2962ab75f79646ebd601f6f83eba64e79972aaf131d2dd7718638c31c6f9d225101c4b12a448e0f2657cf3ef8c2fcef83e257bfea0df89bb8cef1de9d08c4d42ad79856ff2502334086dea734a012119916c5e8d788607a1b914591aa740573e5664d553f53929d49c57b6a55bc5d12512b87c7fab0101f9f890e43f52c724a8e9d685888bea7846531645ce279453f742f59fa43753af8247ac261a60095a72e8a0e4462537d12404c286204bbe317cf7c945892b59053a0acf7d4edd96aef017b6949b100f08dea5d1686e36402d3713e02594d03144054b43a0c051d0ad991a4265049863078eed43eacb8102924e82f292c8d1e5f6191bd9c74d4f01c13f3aa81b443f8a7045781001b1c2e183a8c7158e221c4449493943b8dac440452447b5e3d34265020d2f49a48007272f637286984131d8cb15829fb775571f5f4b2709b4b6d2586cbb10e77b31c658e7dbe57cadddbbe2ee929a243d7bf52535497ad786fb929a243d8ca3021ffcca02f0ec3c0fed628c43ec61bcf1b5fa7a17dfdbe9d77acc2449e26bc94b6a2f939a24bd0c8644f8c318939aecbc0ea7c2d7d447a87dc2becfc6602febaabcb66aadb556560856f1f3ead6b5d65aebe862ac19d76b816ca562adf586652b0194a0d5de18bef66218ceafdcb93aae3516da37509bb55d425052ddfbc20f04c1f0c3d7862c0f5fcb6aed16d7dcd5b95ed9058b234e35bf16bf60185f0b8bddd88d15e2f8efdbc70961dcc559dccd0d4e857a11ebc78d38210cfb6b314e0ecdb911e73fe71687c3e16e84aa7a92a8b58a70fb08b8cf9873da39e7adb55a6bed8a7baf0a4a29a794d24b73ad3e64497badb5fb8e7cf3567ba7d6dafb2ccbf5f262a0eec290c8be0e37a0f686cf39e79cf325c6b6b6d6da6bafbdc9b95d7e127459e7efbad1034b9b7fb342852567cf7c8cefbdd75ef1c43de1737d449bae36576bedbd16cf5aefb4b693ea74a73b9df1add25dc6f716830f2191fe0fc49dfeca7597f1bd75da52db69d108185777f6d6e94e677cab7497f1bde19b3b8d6faeba18df7cd31dbeb74e773ae35ba5bb8cefed09d5b7dabbb7d781f04147c3d29c61d6bcf74618256dd22b8c1757dff78178efbd370882e1d5b7241856d39bbe6118b2ac101010d0bcb2390c35a8bdfb15b5bead2cc055c62c2812bda0760f831e91ff9922c1d4565f7730e811654191405de1aee851eb7e8bd3cfa7564c6d30e8059ea64dd40906654191cc0bea43511b9d61f654bab4d4e98cafad9a6e29d81137f8d4101cb6c76b03bcc75a83e0016b2db6f63d60ada5faf6ec2d0dc845c697c78857295aaf0f8e9bc2c1e4556d42a6e816905a00424f0d81e2e55a10a27f54575a0092ab08c1a26f8d011d0ba911240b4700552f77ba0860450ba932dd4ead90d4ed932c14d1edfb04d1a1c20a9d7b26f86a0334edd6ceaafb0190900b6b497e05b0042f815a581bc571ba041df491dcd8efeb1c40f4fbf7682aa9a9df0b046562e92508044a37001033449703f5a07fbdcba382a2d0cb15d78a374315bd9c6cba05dd5edaa3a446faa54bfdfe2c6953bff4c98ea27effbee6e293738ac709fd3e90900b0f7aece8f73f00814abfef011851fdfe0876f850e4e5c8860d47bf4f936e3dd428f980622ad2ef9cfa81a6e3b45ce1517afdcaa528e42974247d6c3e5ba3ff3e404fe670fff362fd5aadf5e7da00fdf36b2d6a03f66f58bf9fb3f732b21d29d59fdf027ab4340b78e38fdcd26e8c2fdc4507452358c2e9dfc7fbd2a37b73aebac818ca04bc9cb992e77ee82af5473647ebd4efb3fa7d5a84e7b74cb7dbd7e0763bbe8ae8bdb8a85f8c54c98b6d95bcf7666917060553c949ab2a3961807b16c2fceebf193e0957bdda906896328ebaac7efe590878fc40cd751c12cd51565f365e76b97e8d2a798ffadc473d92b4ad923727099f6da38d54c9fb096082db2fa955ee6efdd69af0faf6eaeb7a743dfa5502bf216d53ba373595bc353755f266a7cc64ebf75748e1e536eaf782e3bd6d239cd4ef5f5c8c18ae7ffd7ce170aee7afe9646bb217ad07bff5e0cf77cdf8ec6bcd580fce0767b2f0c1d1893547d9f78db2e9cd4a5c85affa6502af7aa9711f90cdcf3fcae6c801eed3d662cc18a24333ac52b347d6fdee46991d39c02eab4ac61cd0ef04eaf7d69167f61080077e6ff5a7ac4d46ae92adcd7aef5bfdd51beba19b55a9d9a34799fedd7dce9ff1b6e97aa3c437794a166ebe623fdf65e5ba72a971e55c6cea8fecfbf92a7abd30833cef7b9c68ef6f91f774c6454bf3be278abf2701325461a628f5903264c89b714313406e599ae030c568c84b63e68713362c0049e16a08031a5233dc564084106686bc7f194d8df4eaf10ad2a7913effa5d4a7b5b234efef113896fa1b2f9ac9e24333f391ade5f73e4bcda0efbdcf5a6610eddee71eee950da2d6e690f7b7aafee8eedd7c6854d0bd6c3bd3bd4bd5bdbf4cb6f65d75539305ebd651d59ff0bdefc0d41fd67baef7bee33283c0f7fe8a50dcbb72eabc748f8fa5c8c1e45cf73e6f9935cfe68de95e36737573ddbbdd9badcd213117f15cf7bcf2ced8e3bc056e3e679491f3378f33ca40f222e76f5e06cec7fe6626a39f436f9efecdcde78c3172fee663e0dcc4f28d09676b37494a4e194aecb119b734d8ac0e692b5b8b8df7c8d22ccdaa7b9f54f7622f543f0b42b0ff1b35b0fd7bcf666b61ced2bcd79a73d68db2087bd00bbc67ddca0da6fe54d95aec4126d006dabed6ec7b584c1785395b63b182505b04daac2eb261ce86391be6ba67dbb9eefde71de9db57f581a9245525bfa9cf4b0be0f871993d9efd7217eda25dc4bab182b4de1339a52dca0ad2bde91975efef91ad7939b1a87bb0191d72cdbc234bf39e35f38c2ae97d38f38a2ae93d38db6c668ff7610fca6233312ff0dedb6dba17f6e8deb7c2a4ee3d68b335d66dd2bc1745ce270bb475af0499baf7b1d95765695e4eeb9baded9ba579aff5cdfb9fc24bd6ad7befb129fa8aea4fb96f5ecefbcfa8d660effd87546b0f9b01bd66af39dd45dd0b595f90eedda3ee1dd9da576569de7bbf6f9e51fd69bdc7675e6ef678adf1035349afe5f5a8a4e72555d2fbd6e8d9bc5cf73e014cf0d2b375efbf0afead7b544da71fd2ab339dbe2eb25a735ed4bd9fb5c81b4360e16439bec9531280a983fff1d7afcfdd7c8db60ec67a74f0a6a883ffdd2055f2c65649f0856aecc6801570ef3fad533891a50882b5144e9506feec29a2668f15d75fd26c201d65f5f97b6389c3d4c1c761aa24f8a38c8f1ce0ce9fa338eae0e33489fd666bdd835fd26c1d3ceafb614ab6063ba2f595eb7b2c1f76646b30a5b1e49ac38e3af87384dd2c0d1c1a82cffe95b05b079f1433c9aa19444b92880e7e49a6e960492ad1c14f51557ff6839fc2aafef0079f749a41b6832982e8608a331d4c71d5c177cd7425f5f34f41656bb25949f0e9500c3a047e4f541579656b0568e284440e26104121cd10f864ced684b054e5586386c90f1686c027abc027adc04fe1d41a4bad5963c9793896299c3af893071c432000539f02d051b00dcca08a671e6dee1e51599a47d5f7d3ee3deee12c6d2c3f5073bdce5a0f5606ace16025f733800da7dde5fa594917f8b8875f47193872807b38ce6f795495aa97dcaaeff770b666bdb1e41eae5ba85e7eb754b6667319378358bf3f4f9941b4efcf546650fdfd38676bf6371da9fafe5cb4a6972c2840f4fd57cad6f4d0de7fc1cc20fafb2fced6f06fa8beffde6cade5646956260b108a7650f527e7f77751f547fcfd9d94adc97e7ff73483707e0e894e9cc949a9ef1cfafeb2c3a1eff7c69acb5566edd33af02df9871c0bd7f763aa2b5ef19d34d3793c3bf1940273685a40e7317e19275ee72d806564f0f5eb3c1e65a0cebfd0af33cac017dd9ff8ee4f8c3210ff0b9dc7630c24e0c738f13a0f8e2f707efc3386e88c8296067e9e694b035f07fc13b36969f9084cade97cd22d2b31f59d9dfaceb6be5f482f23366abace97ae337dbb82e85b86ce9f78f02bd3ce83ff511a1289cf9dfae64f7d972d2a9b7351d99acec8d5d4fae53dd219d954f5fdd365e4a2b257610670fe9ddf61eae0cff0850efe137f62045b54f6448b5a80f3330c8106f3f5ac5103fb72a22c5c5ce805fb5daf2a5be35a7b571fd4cbc9d65e2f30f482fda2685f4ef6e5645f4e3da47ad97819e2fafeefb392cd388e3fe14e95e435f026613e2b9c9137cd1e2de09720d4abea0586f5afaa57551f4b34bdbec0f4cdfa194a8551f5877e0da3fa6e5159dabeea2d2a18745e360ba52c6dbf380ba32ab93f67164255723fce2c7471a12c422bf382fd3bc4a16f1797be5d547d3f97b2b557d5a4ed1745cea57a4875d5f707d1cb1655ce0d7ee2b3b235d0cad2f66bcdb955dfff5378d97a55f5fd2d305055f5677f8baafe4c1e928efafe5610ad33a518e2f6874da193ade93c97eafba70db7a007cc9e6944af0f13c2c12c68d2afaf48357f4d5e7c7382a453ea040910bca109d71330ac2852587508294737529008a728699b3bc2b2b937c8cd97d748a73f2fd3954e3f4a719ed21c4aa7aaa4d0298b52f129d5a1f475d19153a7392a5abacedffaf3d3755e0c8974c4cf0989c49c363de77142a21c9cbf0989706ea630f59b8f8544373af6b09028761500b30253d161b0e7493aecc5311d862b6106412545088b285970910bf630d6c3bf2114293d8c02e4491991667992c32526cc099a30e27b6f9ebef7f32d7dbf78c3920d337c376583097ad7e99c9d3ce9584771e9e9254fb74daa9c96bafd7752d4e40424be751d8ae344f3a757e4e2cc51240d135b901d47e0987182910e48669c683861ccd07d524837d1ef036d315281e76251c353af4c7ef45a9938f5dac4470d347af5e1d124a5dfbff7022da14149bf4d27f4fb2c0e82239a54787265873336a830fd804223446a8729e4646a099c3476001b38bba3a4ca12157a9d5a5244af3400e9f5c3af437449e12608a45e17254e98c6f4fa1f4fe2a5ef245933430ffd3e678aa1dfff412509524f1227fd5e114b55a843228b05c91412a45ebfe39a6b90e7250c2464fef4327684887e976af4fb571ce1c9aa85a8226e8092e201252a2f446e48a14b1821271e6c7c42b1dbed11252b29685d06c8600667ead37b4f0b8620186a5beb3ebffefdb3fbfc2fbacf5aff1e6f49fad45ced1e45dbd997e17db73fff8bfd79ccaf6574367c915f8f77e7efbecae8bfa555115ee8df4f813924c6e076c650f97a28537a2bd6e1d3f567ead933a7d4b523797d36f020cc9ef9289038fd0f2a59a7c5511fd49fefe7833083f673cd6728264def28800390b6663793a69f35d3f7a762dd637377430e5a2834d0319e372168ed6109d8be759751d820f1bd95d69a858828e8c8342973311072d101ee734a09d785117f278c103160c995a025051c88d4b082448495a321301656137c62c792238cbe38b190d4820f1d3c20cdd0840d0f4da0d94fc29be4a98d0ada8bb63c86b09f28bea8c4d44b51ea4b522565390ce749bbcbbf2825a522945ce07656e9f9a484e39b5252c18a8b5ca9a89764962b4d4ee8ae30b1815b4cc14044fffa9c8221cc92aaa6923747af906cf4a8d4fd4ae1b22eabbf5f66699d5504b3f68d14a9d2eefd929ad0efb8a6df7f1edceb22dc3ad3b3e7d2ab2b9a2603968f3fba3deaf3e02d4d9164f869ee9bc9f0e801bd1afa5e96f76cefefbd3186f7dfc7d0bf7f86ede8ebb1bff59eb5fa9bd298b4cbdbf4bbf1284225d345a8bd86a16966cfed75a45716ca0049701b659f7e3cf5ab91d8aeebf467acbbaeebbaaed3f9f72c040168d3a689bea37a39a3a977bf4710cca8de3d3db5e85df7e50a9edeedf4aeb32a664dc5a4cddafcee27cd33fc5f37ee0ce89393ec3eef999ea4ed5ac892a38a7c3be6a9647d71ea2bdfe4e140adcdda678d5a2dd4670174c55802d19fb785d08a1f1ca853a119943b7d0c98ea122e46a8b56e02574cbfefc10ce2fdfa70699776efcf4b3798b47baf8bd973ed88410b289cc7ea8f9d14d7a700ec9a0fffa545fd1ecd201a33a83efe7b35a04745dc0373a8e4fcde7bd9c4c8b72808d5db0777776b9be938a9cd96fa00e1a8cd7476fbb6d7a758a2be153e94fad82324db07575655b6db6b2b9d41b4b71873259582124b486942868e1cc2acd1727444d5017cdec7b57be9d3ad66cf882b29aea45066444162a306ab1f662802c7100694e48852a54a1521b20cd5f701fa4e9877bc434bf0f2f60fcf6e073388641bdc05f4fb333abe20c663ee9cb2f9720b9ec1fd39d480e6fccd9979f0ef4cad855f9faaa935d65720ea03eff5972a355269f57106c7528f4038cf28ee5bea74caa4d5c7d2ab965e7de8f57b4c71b3e71be913da448d3419a93f4a4bf8290b8bbf023d0d15c129146ec50f8ebfa438d906b43c4090a2ba224c1108b48836e131e32aaa00a6cd0c619a92b419aa06a052c39a2f429890d445b4b4162c7e16d07d15b9d4188daa3f5235e32f359ed9cf21510bfac49a851fc555b20aad78e29ec5185b10638c31b5ffcd424042ff7a161a812a490710032f817a15fafa2dc00b8233aa97e0475612acb41cab5bafa02cea4f8e401ec94ad6c72d1b38970e2ae91ac2edcf4a7bfdc08cea7814bab31695c451a9fa940af7555898a9e273f6a9b4fcb409cc03cc58cf394f313e2c604ace4b702a96ddceeb0c5c2bb32ff2e0b03e6710aed5a2f9f4e3f76c089602f6f72c04fbb86abdf7defaf7d8e19fc0b4346b67ddd7ce23caee18dbf1c1c9f15718e1f3cba7c265ff74fe30e1f39dbec953d270fdfb4f83e058d4ab51afb1ab5e636c2a598b2a596dbd9638b75e7fc88aeb126683d9aa54aff5edc3926ced95b3b4faf7ebcc8e258ca97ffffd2b676bb0244bfbfee3db7be5fa67b3b4affb1266ebdfa750b25a739e42a97f0358ea5f492a759a0cdfef0877eddecac2ce124104b4dbd75a145f14cb8903e1844eff86f6d1e94b48a7ff329a3df4eb91a5754250f7a332fbb3cb38eaf9cb6aeb5d37caecdf3c967694dd9103dc6d51d33779ca0d63efbd4b6d71f72dd47dcba42d6d66dbe46499ec979649db7452ae35e1b23a7a00e6910da5b4247dac2c932b5749fa202545f2dfd2b8a5cdd1a5864b81502e5ca7617562ea34bf65aa358a029375aa3f4fb7dfb7602e1135bdb44ffaf5a68ad4e8a5852292825e5a2efdde4b874a6bd5efdb3c3353fdb99f9beacff5c1f6b6698a488fdefb881ecf0cc224bdf46252931ebd98d424e9e1cff729fd281e6fbe95a4176bb292dec4f88e16187d8fc16a3178473d29cdf2cd9ff3739f636bf650224a3710e1f61170b73fdf67ce49de7b2968679e7169ae622fce9df6aac5b9d3bbd67bb37d3c70ceca5ac91a3e98edd5dbfb58737b1ff896652b9d20aee37ccfca179471bd179c21c6f7de7bb1bdf779e8cc9de5c163860c09f3455f7dbb8c875cdd653c64c8900e0afdae77f1c63c33486bada2ebc06e8793f4826a55f0acd8c117db4e671e152a54a850a14205c8d35129ed34d585cd0bb01878a58349695db610551d8bf5255aa8a1a349083337864a8e4311545f4c38a1c697a112c8d021dac5050480b12d1b2c1159c14a102d4f45745aa6d8cc3801ae0c9820296c71a14a842d648e78a420099b995965ca0c6bc6932455369401223584099f1523e49eff5a5a248481b557fdda99d084bac1eb773083b095291d7a22b164869c18272b8859e1a3a226cf40c1881f5d8cdc50418c113290d7c748a7dde7f6f001a4091b58c64449c272d9a15b3b8990ba51020fb829430419b2d65acbc34304032f796a0dc8c85035d27f6c0d05aea8a884a5a1fa76265485aacf0ab8d01053ba1263244b103694e1e123048d125c96a4d880e4062a3cd7cc0a246594d440e3cb94102af002440d34b4b92a5204990e071f687ebe293e158ced9ce8738a8a86973548bfb528f1a6a543402c1142093329f0c891fb705245683d34f1e0e40586a61e8488d26409187cf8408608295245e1067e2ca185082078d801f7f7c230ca7146054945b838b9519aa80107131922587821072286eebdf756fb38df7befbdf7c664697819abdda701cb0f36344e6aae38a5f9a04459c9e9009a1e44d2740162a4c4ea940815a498608997a5312b987749072633765039a172e35665052543d65a6b2b09d630c859e235d6506575a1aa424a8616be285193a609245418470e45f94c0a8418b1c4c6121e483c60e204dcfcc71a1c0b251c5992443fc1120317810c8d15ce340121a688eec618a8ebebf933a75045c1112b4bdfb50a20a288981a88b449a3c210082eec77035453b7f64bd392a2281f5bc4e03064adb516e44eb3f3e0290a0d1c8d1344a161a8e4bd7b105e546da70dbdbb72a477dd0e48aca0043246640922ca507782af761deebaaeebbafc621b5e8aa217afdb55d7aabd241cd6e7d4d38d3d657bd14b70ce041e826b2492ac39411855a6bbc273106017fef9b08190fa98e01b074f07df51b40e4e66aa28e97bf4a95204479dfaeaa8249d9354110243151f3ba2beb33ba2f9891f6c3954703a51383854895652b8b972cb6112c3f1d130e480f900f9ac00c2e56e861cbd9eae623874b8a450c1b48f0c4635b8e61ae419e0f0e249b45c6bccb038191da194a416c80a73f44d910ab7d8f0705420151dfbe9f6d5704353b9f28ed4e8aef62d8329b6a91872e85062c323674647064f38303932c01d65c96153b2729441142b14436896ad6ba1871ca18f1e50f88c701712a011fe9501a7f01c449681e3ecc0f2f194022d4fb410eeea938b96233cb4b480464b0f50082eb2e94ce03a633c2aceb7544955c16a5856a49c9820b54414fbe4424566c9376710f751814715956cb1485b3be79eeeb2b6ac6c5916143ff1b9e8e303044423802669042067cf2d75a7dece98f2d972b16aff904ebcbc59619a8b947ea4b5ac3bf254928714bfea4b2d086aad758b833196dedaa5b3b54b67a641506fedd299851ff8e9ad5d3ad46a0d825a6f97cecc636ddeb9f24e5763e0d554530d629e2ec3629deea8a7670f7d209f52a6c99dfe62ed3bb49d5e7734d5e9f42b50afbcccbdba5e1376224829e391a9b83c0ae8d34aff3248673cfdeb403afb8e8bf50fc4d7d65a2938712a386d553cbb393f002c1b5e5dc371aab5287e597b1dce18676b4951d45af7bbadd5faededbcfc81d75a6bad65d5395b97523a72dee2f691e0dc69be75b7bb0eeb9db3de2d97c7ea32f6e9403d5f4d67b5aceb85df07821e80e1c7c5d73e4056fc5a94ee3f6479a44f6b03f94ccd279fe2ad3f535f52eb16d723108ebbe8764dda3cc02449125f4be26bdf955f2f0c8391b11b6b2d50c2e90d4e0e758993b434eed3a74892a4ce12194fcffda394ce3e0bc6407df99c53df3967d7e9ed7dde07823cbc32dd672c16ab55ef38bba53c22e75b73cd820e9c7eed1068c36f2f3140c369c7000d9ffde5d25ae711637ee7b4ba75adb5165b6badcde09c736a6f7bf35a7bb79e136baae7c55aeb7bef8ded94e283219105738851205d6badb5355c458098478164adb596c750305db5bb7753248efa08b57be0cb78b64b87e6ef4ed05eabafc5214ebfad392738ebcfbde3c86a8173ce39e7c4f567bb74e853dae5997f3f7651dcc0a2ac7657c718eb50d985bd50dce03218ab9cc1afae159a6dfc37d77ec769adfdb2f1bd42f0dcd38e0fc20e37f87dbbbc2fd65adfbd71acd68d71ad1db22fde37e79c654bee1e62adfd62c1cf7b101e9c35a118d597da160e8763d1a06151d0d0b931ae942fd6da2ffbea2ee37d5170b7ee32a601801c60ba7ba83d5d543a5533042ce9667592f8e2dce9ed8512b83dff0d37b893829645bf570b20bb02013270fa4277e456cf368b87267d1d06dd7bef89db38560b9700e71647c17b1f087e1e8c2b0ebe4222fc2f18783f272579b4cb9470fa42351482792ac818f873ef3e67ed9bb51aa34228268969e505a650d5408b8593d3e58899fcd99e0f48f2ea0fbd6ee95587f02a2909060a1b5ce784cc42e1703821a1d903e515beacee883be04e48847fc782167d4527ebf379b2ce640103d70e7a109d3281099efba8348db9f434e9ccd8080000040003160020280c0a87842281408c04c2a4e90e14800e65843c78603818c9625190c3280882186408310418428021c620c3584d750004df988abeb3198a56a7683730dc5a2d97d20be5467b9e09b554ed8621f6348f0087d2b9ef1de1d411fb8f88ab9ae4b2dbff687392403201af1b9d0924df9caf1bfd1dd123ac273817ed69bb56bfd151770c7538e069dfbdb40ee2fffcd2d17202a18efefbd1a800d3ec26427c4a4a7f94a16d11f78ac161a20c2c28057df3c36ecdfdf60472a7327c77758ac1d7d597a6a0a6dba2d97831fc28d113c1e6dbff3d1ac6cc457e9f11559937edb5f3853fcc77358bc76ea3ef9e877579dc367a35e26a6e230076a7b1c142cf8148910a59a0fb27efb5a6abd77db7e3700d7263b798b7fa1c2f21bed91b48c63aff9315fdd5ba2977f2332c57a29ce13bbcb891eff506a7eb9decfa74a8d270b9819e4a145b00e6dd0ef2ca188452646807db3e074b9f9a2ced5c432fbe8ad8731a1b35927a5e06d9489c941c73046834f4577e804dd915d5b750220f581eb34a66edcba0851fd9b810e9440de6a88ce66686bf1d86c6505f7e0a73dce605284b75a3915d4c44e6f517a3752fe42916b746e35853c938024578f6585e1fd2d8f881b134e511a9ccaa7e22bfa155638d812f9c2b0b186722be88da9272aeb442ed1cc090668144fcd9f7f7ec960cef7b66cc4748e75a3156e81e291da60c0e1012501994d374274d4b40e9efb780878fa5615802cf905374cf266af2b6297c3a0a18975a3ba90923913fe8c538c6f8088784a3a6037da5e53c1bc97501f31208e285a20390e18d7b4c183845dc9a6548f932098a3f7d357407e7633920986e7a535ac8339de87168f06597c267dc7025f7c021b00c4fbf9c9e421cb199c734caebd41bb955ae452152889b267c020576dd032b163f8868a79586ae1257947ef07d1f46db9c754b050ac21463c3d246646718e0bcf7bf89d30c106b02e79dd229756c00cc2e04e06e37019f92bda8c4308f206df4e6697a9751c278f41ea84867f0bdb35021216ebd877dea825e1d0428f9909bf35b11f057946d3fd0012eaff18a0a49a3413e4b0d879bb97696b50ef0680a15f5ae6b52959bc06828a76469a040f6338943f4c8d19a6d3a8d1cc6702f1ef788bd2fd91068214e6a710ee8ae0f68e9123877155560cfe9998f3bece6f52f68333f135eb0d00391e997e15a247973cb2d184db9345e0dc0d226c7153d1b08e8f10322900d17b395159ad2e82e1ce99048c8c2bc366f22c1b099aad619982b850f90a4ddfa52c98cee43e8068e050e56aafe801b744186553b8be6043a4e3fbed0b8bb8a348bffd888aeafa846fb287bbce71a3a5c409abcb3701b6103c53e66e210a290c978211d8dd44529e0a33b3b053fde907f5bc0c8041383d9b9268ae652e7b9af226a695065996052941c43a8d234c23da498888a46c06e44202e73b02163ed971c7e89b57670d4f80aba862a041f1016dcfadcbcad253388f026ffb7dc962342a2723a4bd492c3f7ca196fb17714a459490e95f9c886c97a847cffe7a0544d8041a60edb3b76e187ed15e621c0c4da8b21c189d3a6683d37e3d6c7cca7563d4b38f1fd3c64033f4ff2a5c6462471ea1a4fa5cb0c58d9d5f88f2d6592e7e00619b5612fdd162d8e21f6426b283e2892a84fe8963efb4365fe6574d60d0b104a11d5f9c9e9121d1bd803093a5cf415c8224bdd185b8e8c70ff59502c9f90a58d4050349ecd88646a4ef8616ce23a6838e1db3b23c2be20d2c6c602a7706da4e4a415e0351e48453701282b45f361f36bbf74abbd097b59c8749a7dd7249e17342635e208b55bb23c2291c62a10ac8a0aef9b2b912eca910e94a724d4f1a0d9aaaf6e0d52cce355697bf8d285bb401b747391210742abf71b9bfc7ce1ea52c23f3a4768098c8825eea612f1d072786e42f601bfb84417e782b0976055ee382f2dfb4be92c3222728e532dd3a1485081a3a4893ec143125808f631300eab11cd4ca265b6ab75f03bfffed06f2e2a1a89f03aa13769ec0bfd8b44ea93227c01bad7d34f25f92f8b9e385cc6f95f61d2c6cf23a75184f635746255fe2e9410dd512d0bd7f947384aa1c0d106b2f8bb4782cb91518cfc4465371fe914be58805fe4b9ea13c2974e3c1623e326ad3092235932eba4d38016d1605c8c879f0e612730e593aab098a2737ffdf4da6eb0b0b3105b0e666d961c517ec47a32c8e82bd7dbd125ef27161b8d4734eceeea68211619222e6e9924494720005c97c42e2d72cba0876fb77130915122cd0a56c26dd163c32ca117d423fa7c2b27694b63fdf14d6c9b99d55a5db19de45bbe8e4d8830a57a391159cd956578c41ce8a9df760cf63a0fce3369672eb9f6d1ddafc1b6efc2da762c34d6b152112e96110db72af67c1821287df0b9a9d392f04522042d7353b2e61fdb2df725c118cf9c4d37c1751b6f62598f097116c4f5a6a98450fd702226248abc8d1f98d94438842dba65b6b55bf51c4bc612cac4d7acdf54eb1bc2432623abb30e7ba7bd3f9739cac9b40d0b34b130a4028e44343bc60ac2d94be3801a6fc37fe009f44855d07304d433399dc05e0a68c006654eb2ae0277a9e20d92a8d2000ffcc68ab47469437b6a39966c88130dd0057f8b43381f4855ff2d6f02a558dc455e2cd1dae541b3690f66e528a7a716e97d5fb8fbcaea21a5ee9ecc59cbbd7647db90519809aa5fced2ae3e20f492b52be028c6b7bc4bba24d35a646848ce689b554fe20a04d1d9d3bc2ba06daed3c5ae091a08af2eec8250ca0cfebb2e3402d958443086dc81744673bd97a0b56fb1c06ca20815aedfbb00a4749bb70ed02d30dda41e073508080df185807562ead6ec9021e8dbb3e3c157d2de021545bb1fbf2a4f220851d9e6747ef34b1cca2dd1a47273e62eb7d4e3308d00828539e582b7b28274aedb4ab70e0c9831381c5595ea768b1cce8ba0332f35c2ee12b1462c8d28e3b86c5920da8b1728d5a9951198746d0f8d564102a570ba720290aacd83d1f8c26d01520ab6d7dfb68d5c35cc64f8088bcd86fbc4f795a78c1576e001c3bde028ab908be55ff9947de42675537825b430f1361e303430c28edc349f91ed140aad7567e4aabd8afb41234c7ed77042e7705121ef4bde82aca8ecb2569118cf3b4f92a125b50ceb0113591fdee406af568f8a3a911d1e2b26845ab108c1fe5bd0a30336d7b138243ca2d0b610220b5f765487249287edb664ce032dfa763946f45dcc63177cae2fb9758e6c4cf0d667f3e1e5ac82351f970c804dbee9c3461833cceef0efad4ee4e996aa2fa54eaf7dc7c73e462e958dec905b66d3c074520b848723b4b55ee9a33a0c6847d714d13e0ffc4ff0868ca4159ad12336c4821ba54a6f5a86c6e8e230fcc3b2fd301be4eccf3bea78b66623c4e472c7b41e2083b25179b1f7fee52c1cd183cbf2a1237283e72335895ea17497dfcf5cd269348971a1163a886f1b6eaed77576916cd9c999928f5612b8de5f324a17884b8a3bd7093fb3793af287bd0c38e3fa5eb583ed5de01a66fa24cc04dacb573e952cfb8d2dd2060e934b6d26582979056d61c9b6bb6d426882b71d2b8b09e797b8b47b3d252b2d8446a52001573f95e45a356af3f36b450091303fbe08115a9a28060652c5441a2878af4dd95d8a0bd5b04694ddc52b34e9f714ca88350a235ba5525076b06af20ab66e2e0055b6c98da419a5b9592b58b67547913c04206070a44a8af01c2c515e327b066d95ee092d581ce86a36894fe5d4324592eb7ab7715ab8b0ee16858636b0275a97822d0dee104dd574fb83557adeb93f27c39beb28cfd181e4f9dcfab60562ae036573e69aeeb40872da22de8c8d57ba45c446d788173234ece7b1c359ac24c9f02c34cfd850e353b30f2fc6581a79b4c9e48695d5a5078d94698b64508800ad19889d083ce940f2da9e740876bdafe2da89d4721ea72d9ce9a979545925faf327af232a6e0385d6c25bd00a4218666e72a54ad8a767277b780cc9539674d34559644560f39d5dacbf79ee4538b88f591a328f1080106a64cc3cc4b1afd7b0759b97c5947841e5f970a1c0871556ded01175d5cc159a137ea36331c88bf9fa80ef350016d6c74f4d503c8938767e992848337144ff34047d271897e15d1f1ed12842d543d35b5c7fe30233265802f8d28f767e5bd071f367ff62065f3f84a4d30a5a18d1fc7533b4258f1d951563fcd2c037b5dc51d9822f97ec9e6588b24052dd30530124f1671ae8e7a138bf752431164ad1e83ba5501aa0edc80b73aee438093f0a7894b98be84067153038c7aae87205ca9e7527213306b100833f822e84bf8b483280ce5a9908203f41c7e1ab242953b9e9176587e9f42c3c0570aec0a8067b2e8f89d619bb918ed9063503239322082541089b08c563f5a28b5f15aa9a1752517b181d8f3d8c2dba8d5c5d1dc638c5e44dc6b32e3382dadfa1f6ea6e38b684a2e41b42f3b7f911b940b005a7c81dc284a28b87fb0cd9c5530edf14eea3ddd1a3fd7501f8e8b360074269ee3c40feca9ac79a810a03e2e24b3d65c5b80917b63a9c51b6260c8f57b88149a25d2d941d89a97a31d0b3409e478d077bae0bfcf98a659b5a56dd7125fc10d452a9d46ff6184e2d02dbb24e852924c681fbead04cd8613050c628d3744735ce2078a76e5e068d7993a8576b51cb4e3722ba3ca1a4a9fc8899a042b0d2e4e5a17a71efed3959027cfe6aa6801c4ce4568dc2e86a6b0e1072744d8cc7e5f35180d86121ba1c3e961aefaa721513cd309c99796bff03b8ec4d2dc70431e81c722e355dd6aac6f4cb413207b4c05090bb75bce8330dcac28bb4033ffbc5cdb77b0447d3f9bd9b946edfb30fa011511b29f4f467313dafce381e2f0963445bcc5cc2c45c5626786e2a57204ce06721d16fe6806cc75a7afd64c62c68715ff2c8ebf3c00774fd1c482c0fd539c9f9cda349a55e43b87d22a66dd7173f286cfed6d4134479fe814c493659eeadd3e7e53fddf61b9aa173d74186c98074d95683380af156a2b1800a75ed99f18d832d9cbc55b2f8870a1a8812095e29ecad70ca72cc1cfdd3cd07380b0d0d392627846f655326d41db34e793a34da5737f282c467dc189730963c1c97d93cec026afbb665a529c80099cd1b90cc44a3a29f99d0af615e5898d82ec1a0cc4a5957f911d9ab912c8bd0508e5e4385fdf25cd9f4f78bf8e962406caf21d1428f4978e559fda23718be33d1a46f04e8f00fc81f283a97e7ebafb08e36bdc9bcace258413814813cfb744408190dd2c07e2e62d18eab456d386595b8df44983c957d01794edd592214d4d7db8718724828680121ff9b990f983dbb55eeebb521399d8551aebd403c1facdcd932d61ee37b6c8cfeb44b0cac005290ce89772a37fd59f00868cdb4617b3a271ee98115253955b472b36bf51fd6fe0af837d3ea32a0d0ae5d1f5fb76da671135ad08e44c0d3d8f259646d916831bfc908505b1215a6a4a9531eb53e810f2abd2e317b570e7ae03c1cc69e205f1f99818721ed3b5efd0f96b086976aa6bbecdab417437d8d41fe5a8d25a58b67c92fa21f55e827746000036e1b6bfa63bc988e03709f597b65615e79eb67e8f7529be9f1d52e641527bac2bb2ebc66c42ae47802dccb707f4b301966dd10ff811eb2604250d49c75fb680e49d4ce9d6f08342c1893a4eb666e0cd450b5cdf8828d2b7969a02c220ac4ef001adee047dad401d5aab038c66e9b4aa078c172ed91b86b7f40807f51319853ebcb4810365085c99f6c28fb3e771eb0cb61855a0ec984fa92fd525133f5f260df1fbed423bd1d70877ebd624bba8aec941a427a2ce41ed72b680663eb51039d9d4b4df2357f0620009e0b5e4f6cd711516988f42076bd88ba69b49b70da6d474ba7e9aefa46ecf0e826c4c7ef1084cc755a74bb48dde29d3046975872640977ea4bc0e8bf3efc144256bffa9332e216667d328536dc2999375e5863ffbd776dd5c4dc0ba0c2845bcca8d443793d23b556729842d2872d241065043341a7de5cc5a7825b5f292ca34f42cfb083774255c11fac944a448433e5a7a9f341e4cfc480e5cdbb27ca2d1d5c4c4f526303e7298df9103dda916180d90a2f56ff663e431ba9289687e76c5f740d089bfbb8f38c0b91fad1f3d3e6539fc9f9c53f5e887eefe42de9cc06533dcbd8b6b4fc51bb8f754cec69286aec2341a8495463ef0d2ff8a88839ef42b1982513638975031807d10b3ccd6b8d8934360a4b08e236f99e1bbc961e628068c9af62b465f1881423e22e5b568fa4b4f5e41717ce39d9b519eadb94e97b83b9e2c31b76e1ae2df06fe451e32911be846abcfd78bc511eb390e7665fc3f10b3bb3f35f84d91766f85623af08998a18441d3c2b6b67a022e160b5ae953c2811f34e84a430f31987d8199733a4a0218819ea9b1d1ebe225627c92892ae4b5a6882a58f7a51e41670c4436343169dd00213c5cc8908d4055ec0017014c789a4abd63b899b0885dfb2f3304f2fe6182feb77c82c2e8c65370bd762ce502427a49cd4822cf89c05ad0487984bef152810eb18312ac9c935342f53f4844c6de0835321944c5db9606f352896c9b8c3d884a8cb31d566a04828b7c3aa3863574191963fac0af1ea8637a9888ee3ed3957b29c7d90e03f5f76d234021b8d9dfab71b1fc535281c7805fef13ee905c10d8dea70052a9dbf0a8093bac934b48d8864ee4ee5c774a66643e261fca29b23a35303c1813cf624c561eb35e2e24e61a9c1ac86bfe288c16b9d8b0f158f12c54a1c1ef2aa72635a8d82e8e62116b1458cc81479b9a4d084568983ccbd415fc1aaa45b0bc7e3a04f79b0d8a8102f000c8b2c3bb24367ac5792d4db8fd3ed4944ea04bd0767f0e941715516d571a20413d376d045c3f378568708d5c038b3d277ee2549742a8583e95eb5bcb50c9b7ba37be0b8f17d4bb948d97103d66255ab63904a5af9344db685dbe739e544b06a5a68bb38313ea91f42e1976726d10fa06800d8b04a584e66354efe95d42a60b68a070dd16b877278ad75a04824aa727c8f5cfb0ba66baf24ea8023ccd91a5c0c1e206a474efc56e3081b85fe4477e2f6ef718406addd9d8d6bc91956f28bf73fe0a45180c5a7bce5e1be0527d6dce44d6c8c517c0282b3e372932ad9ad96616f36e501a2b9a97cadb376fc53d47c29f165a8f506bf59d2474c0c1eeb2b3d1c200f6427622de294a769e2d921a3970ee8bd91ec7a7f1a5f1f02b817726b94e62061574826800bf98b9d888af9a2fd174061c383066060ad2bfb892620d5d7de83e8dabb402e74b7c23daec8735dcb4fcdae2e9a04b0f0e6ea9ccc1bc1159448f463bbac1ab7745095c9766229f2670037e337b9ac64c295b1b587299cbf857db8706d74ffe07cfabb2b97a496d8ef5f2180355b47fd24baa319a0001a88f24850ae50a691945f22f63d4fd57a04797b1d5dda54b4b23a2b088cd7d794f6677d31062b51152cbfdadfc70069dd97fb2fe26fbe4336be570000a24c9b464d944d9ed4dc363b4cb292286eef889327813e5d0bbb68db728152678e866d2f94d06051ed4938ba070d4b767fa9c09659d31102db316744f51713bc798232758599dbdf8ab45d84369d61a11f69fb9785930802ffa8f09f15b4e1977dbbf8d5426ba21336a81e6ec30fe608f1b5595e9ba6f82b6841c7be44678bc31b24103abfcd3e5db0f52bf12e070be629d3ab7e406c3a3a777fffbc38f2a8f65a901b6e3d7da119e2fadbe176173a161c0abcde10b7add2a93d9f6f7a5de85eb579afb2ef8d05712de2be5430bda8d31a82121e4914815eb1278d4b2d9001b7ffb1b0d4ef782901a1fd1b0d44571165ca49e340b38403cfe202823777d139114810fd766d9937ceef524411ff006f61ffd8808c94173ea9fa7096d31773b7e57c23274830778176ad1abef6cbcff5b192746d590606a4f02f58ae38d7090851bed54aa5545b4f8278afc2ae4dc6a6775b30a0779be44ca30abb1214ea219b3b50080ea9fd22ab6cdd9c557d9fcfe2b686237d791a2f817a9de6c7dcefcb311085ec653fa2a525a16653580be6238e030889056cb7e1dae855a0aad650c732f083d65eabc5e345dc40e58941acf143589b97fbad235fa9b400d4660ae0beaf21f4a2df9f41174b2e64fb99ac205a6988e42faa6ad17f62aa0528317677e4bc7fac01cbbfefb38d4100be9762ea419edc9e1a629322df73ae6debbc07ee032f9ac5462960590ea8b3ad16f0a87002f723ec304d0377a9abf8dd2db2d51063c517b9d4c7f59f3d6394d583fba07b1656055417d1301cf86cb87badda69c3596986621a8805cb04c0a2508b1fcd7ee8fad80dbb144a603b33879c6a8e82e1f430c0d4f020affb816f1cf12dddc7b7ce4a7e22def39be9ac3e027e25c0e570d728d18233b9d649e1ec77934edad8d740b646513746a8d138958d989d357e6b6f892ecaab8cba266d248a06ea64bc28840ee35642a28a45e493f58b7a46c81317f50a966272c431342bcc9b500743b53529be8204c5985cdc13dd4309814659fdeb63dbf3160d92d8806460580afee027aa21fad904cc1c3a779a28939230c24693b66021b4900928be31cca9c005f9c447079a70d1ac400d2f639e9e1e4f21dc82b845034e9b62d3d24ded35a3c71313ef5c23bdb2ecf49f4c98ccc77843961330a1207d0251c69efdc10ab271db361cf153f6498cf35b807c8ec595ebf1dcb72d92cdf12f97f7852fd2fee07afa231ef9461e9980c1f988bf04cb6f9f38d2b6f088474f706d6c509963f26cae82d27d73ff2486979610f7be786a4d2bf7048fc49c31457c0a360c4207df78aabcd2e634d828b40819dc81dbd33fad76b477cf2fe253518e7d7d38ac68622870f877ad69d1c9201b25249fe8a4ed04e222ff1edfca0ed0a95a81fa1c274c745d2e5b2c43e785c15320a8368cf196a1ebb0a906d23ee845ed18d1875d56c39d8585a7dee72a93f478a07dea41ddd50facda4e94fe56604164a87469978a9ebd98eca6d8200b4e288518d7d391ed542c0c7a5c21f3b6c2fe273bbc8b82ac99fe3b8557617fb87ca9e17b514c737ec098e3d39e709d3c87b0f1df29fb9ac0daa6304d28924acda069f0b43b092a0cb541eedf12668daa0c40fbf458233a9f936db49d91cb330633255914912a019f9a63c52faba7ac80e55837174c4cf6bd784703f80557d4ce5e7104a0e422a39a1e62e635a8414462d000e00e08626f92f7c8ab63bd5f39ee433d2a0f5e3cfb990e5794543a097fd21b355fab3828f4a1bd37abbd68506788b6b55d9c3a2c007a745660ef395e1a3adfeea5930205ab2414c01dd3bbd9409f6ccb3534948b1171080551d9afd50447b8ba15a7d777cb95c2b329389dc1ac7fcf1b7b1f134e020360ccb8f06c42e879e5d67e0625ff27524998de3a65f78ced944b1bf72117c5c8fd8f029decb7762b48a90a037288ba0b6bf1174da09812cdce65b82c0861a6bb639d6f1c6d0137475b191df73e9fddefbfbd734a648b331a37a7fadfb1c0f2def581c0e92ad98963184a0ec8c6b2c804db815d9cd2d5c89fb8c7f4eb279202caf0abb3357745aa25895a41a79e49b024bfa03fb72188bf919fea4c3e611198c85ad42bc3cf941b07d2691eed4756e2e90500cd704548910b19f36328cef41bc982984d4fda903c83a408e466b910f39ee3c64295b7d19defb08194f9e81504542caaeaf70bada00728c353b94a58caf992aef65e0bea48e0fa3d68b1b4cc64ae5c07593a72b468d14318e34d633316b216a799f48ec121dc79173f54482709f6bb8a1ac61f98ec217c71f21c0b30eae12e32b10d33d50c7976324754955efa646e909cc4d2fbd45795fd889d687dc71c18c4b278e19872e54cf0fbf3e24507a2092c0da2b26e8b6c24fa4f0af5e45e81518e9740798591f21bf5cdee4441a31dd77f9c451fc895f55aa644b0235f6c78ac7302167e279c657df833573734b8bdb1986f349c9c50573850a41c0cd5234323f955c4ddcdae94cdf6b8c2af722e1ab2200ae500f6c3d7516509148a7744f04a50c46818feb9e1e42f9c496bb91b0530d63cd997a7fac5bbe8960face443f7e365c48eae65fbfab28f91de52a3489dee9f4a37ba581481a78905971cf14c9ad74fe13dc2abf82600ffe1f90f637440292585018cb5628c744fbab9ce7716ae0affa8e79e0de3edf6dc15c729d27a376b96e3e3e804506d0f2cd85c4b89aa35921c070f5a2c0710fa10a59927febdf434ca1892e2d9af5c91cd1a1f043e81a8efb0c88f1af3d6de469fb20cd8b7eec54db50ad0f11b342035ce0da5598d44462c70e0bc0e62120c45877268bba9361bc14451fa6ef5d5b96465ec7b090ff753b7f124c68212d3f15374b4ab00bc5d6c87b4522c1029998f9218db6694a150238b6ff4dc4895cf96cf8ada859447742ae5b656ada2bb6d7508eda67a183af84f15faf1b71bda6ec220eb7e422a1ab7aad3cdfdd78dc82dd2c94cf6e61bbfe16a132530802f72790bd7cbe1aa452c81169bbffba489b8ff4bfd312986f80cb2ba2a6bb0300c8d72abfcfd2af8a1671199ba512d3abc3eb8860254e650ba2fb1834059fb8dabd1c3a3fe1a150faf1fa62480d210fe503968a2d67aaf273b75406cdc7ba96633641e0b8d8f3e69d2f0ebed46cead7c9effac0ca37123e6160ab5d2df53a87e4b1dfa5c3ba3414ae6d88e59a23a6880bd47918c078efa22b8f4890951072bf70a34717c57096976705a222c70016eae0c822c9dae2ab01f6fbe68b54e1965b71f30011239d0015773c3ca873df85c93d5cd05b66443c46115fb69d08fde41bb9435a72345d108061f8f47f4d2b06bce8ccca919b053594e9d52dc17185fef53dc652350b2c50cee5c5edd48b458056ab3215be16241b2c1b16b31e430d8084923b880e92107c22a7f13871cad42d769a96230a68973e68ebaf399b9e8ddfc0d1f747db2a5f35a3a4476bfe7c2e9429c63e5e64345431ae8499aae332a10bb389e2165d37de3e793ded8d9a344850371d0b3f20208a350da3f4d9aa0ea31f3d3ed06431d859ad4c242d80c164a949ee0ff9d3f4754a64020496e26a5729d8158f36b66d2babd92647db7a7bc56bdcf130a7f40e54b5d1d81a06ede8c1e52c3954ce83374065dcff8ac73c480512ba036febfe59d6d626e320615272818fd6e17bda24cdaf0a73b9b61489e40fef6abe980f9d20f62869756e0b14ca43a7a727cc0f45b1f58f419d5b1a6ab7d328983621f42c9b3e213d61b4b7364d317e2638499ccf534e051a685b8799f3b277268b12734bf751157b1b6d3cd274debc10c182d706c1b637187e9ed082be4347982ebdee23f49ef253191f63b66fad65be6c1526c17469371fb85d76fb74f2baf054d5edc1277a8cc0a2badfe263122fb22fcf7f5451417dd7e6a9055f240b5064552b5adff49c787c3af15dffee1779a8b340cb66be6fa0793d8e0beefc859dfdfa5ee80cd592001b0df39c4e762a8a2f8be6c09f0abd51e347070592d9298828832548cd1acbbd863e49c5500efec495f6c3d5e5f0a1d72927be9caaf19ad5f79f7d86174b2d9cfa8317085fbc189b918a5d08778900e876f4f01c0dddf16e954d3aa302d4f01c031ad1dbbb913813576bd0c317e8a76ec06573f043a4920ca37ed25dcb13d5eef51d0cfcc5877a0d75980719b8531ea88bbce32d94a76431cd27faef724beddbe4094c6a370799c23761546a643737ff87e0ef9eeaae83374671ed1c090ebc113bd00771e6de203ffafd51a2287e49a55209c09249164b5665edfa9d23813d065c968c1fbe8a46d7f9be270d337c1413f966692aeb80b3231f24950e014241c3edfeb203f773d52da478ea585f68dce6cef3b13e356e05a197cb7c9563cdf6e73a835073b142bfe7fb121f7d5875beb24c580b841a69ae8801fb8263a724e40ce60cdd02f4a3f61c3133b7888cb5258c18688c276cb072d8ba8fbaa21c7a50265a7af5fc2155a0efc3948ba9590df0b822ba288b5a981395a11a721f1b338bd548f953ebecdbdea79628c215b31a3f44d5493c42a5ff2c26fdd43468b89871d52b9d28a99be14f01c5a929dff61fceababcb02fa83b25fb2cdf6a847838d8de9eb4be35110c8530b7bf888d16eb13dec597cf1994724d018800b30b1bedf0822e50272016f45b73342d6c737a857b872ff7718795f0c643589afc2955a4720d9155fd5b0897584218fa83bb4b087f89a1d72b16f58d30eb84e4153706d9cf1fce6275a0dd82173c146cd2621ad541558fa30794b1875fcb2ed67412dc87d63c771318b6f67cbc2490530c07b933a48267e0eec3e2e3b386d018e67b37224951cc6f75f075f6142aac2c3dc382780cdbd39d00dfab65107cde96d15cdb8ec184464b05869c64bb64b5a1f94f027ff66f9aed8e4103e9afe5c0c38621660b5ac61749076c5eb9716a3a1f263e8a0ea69215f000ebfbef93cb421f32774f5babbf803a8f4833aedb5bfe88c2904e9aa6a8231b1816c4bc8d0152ddf808512e9c83eda316cf72c360f976c13894761f3dca9f924cf42a1a1803c1d546c245da60930e22b34119c9694653155f0dccdad18b59101498c76f99be8f08be498783d854a46bcb38b2252018c90d453cbd9ff71f912d109778366c4f579a619c96b2f85a7c7b66ef9fcffa6ab9de7e959863ae7b4857a9f7fe59ebd14d6e37a039c3c70e2d788e2cefc54f1f6e31251b9210b0492c83f073bea0e11dbaf099e478819b9a48f0d2aa28039775f3bb083dcb0fabd907676673c0c241a95dc480fa81339f45e971e92fd5553d1083680f44b907842ffb95f8533245cdf8894a8bf26c78a96621f27d4db5c376508e21d371e0a2efbb263e53096bb6a5b1f5b154e5defb182fe042ce2154ccf90cce41d0d493ba9823578d53adf237f11ea4f20a247b5e2e1d89943ca9dfcadc8506fe004301431cc7978cc83a57e7ec9c7c789bae0aa3617c2f60bda12ea56f90958783897e62838fde05efeafec353fa958da0deb130cfe7fe041e77a6edb2314a96f8660aebd0056284b00b45b85cf62965e439b537738cd8f8733d09a282231a56c3b6dd1bc57dd98fe368afff6334bec868946aeb9c1852e30b2d1ead4de15b0a40e0007bcf7e974a31110c4f203ce4be43cc85303858d5337c2b02f70788b4d93fe8518d02c0df8c54476396a8c8ce5909b3b46428803f8e13bae424527af02ddc8127c1d7dd18d23fcd0bc7b0b457caa8701db8d252de83a6a08e07b924a4e15fdde638b5ee9d9c6693237018d3fa9d2a6dbf06aa4c33231e77187ccf0b69365a5c1a7eac06b9ccb80947b3b6dce1168c50fac8dd5bac2b264d4700bedac4286f2689f04f35ade225edbce7226dffeaea56d43cf41255c13599cc990713eacb0fda6352556e97fa47ef1e7c96bce8b1dc841486e0004054f1a4ec379ef371d6a2dcc589b72c32f3d00d3ed0fa373e88e6a0bdbf40bffa6d6a4ab2f743dad5ddb90830b5b04de37420f46f2a00251129ca181099871e1ac7f89ad9827c5dc47e8d5e8273d425f8ddfa0bfb79026d26c88b5c4bc981cf03b4cc8b50e1c9e948af03431ea6cf109e641f9218408b8101c98db2954401351d6fe089dc0175ee5040de8e631cf331f4735f7ae321e61ca619e119dc76d8cea73e700ebda1811113e1ad0551cc28e5d95f22dd74993d3070fb766041f69027a5f86cf46e94bc404d38e63bca3c7dda97c0b83b486ed984f1db608bebcdc0f98c9161d6e4f4f0349bc4e58d79f0ef7608401adc5500c00a6dc728ab2b4e4450f83313071dc63720851ec77424b219e5e5c81d40c44ae828fd00d870e3f0c5bb73a08160fbb92f92e018c876569fb4e97b560fb55ef98edfead006e72cf7ad0d8c4dfe157c0d44fa748c953dca494c33c74b41bbe6132088facfbe0940022867716974fa913cce0b9e80956bfdb792dca5aeed0d624b92256c977e9d2a9e801d3eaad543a03b67acc3825e1bf1ed868803d4fd9ca5e8a42dcba757d39350a02a5e87145208c0b88d9a9053fcdda8edac559fe712f4a44a9060b7b89c5fe506924208e00468ab2692784bc36e0702237225c5f77123e717f04b9cac5ca13580dbf83b5c40ff75cafedbf049c18b1240c064e544d352becf6efa861bab9ff9704ede8ed88cf6660775a7f0e054a88af36d998a563b80001ab2ec4f719bc0c3e07a6eda11025f37a37b924ee19faa7b2de5308e9700f610d0d3d29ebde7e4d6ad735ed7738d40ff5ed7b61f86c4eb3ad3081b13f6ba539bf71d1d60662450d753d0e6f14707a712aa132152b644ddaa7397622b48a4461d57b7d5d3e38c458f35e13efdd7f7087ba2876164d661eb5c27c39079b6c4f81b79c561717b4d2fc122f814d43bd11a4d9310dcb68b3d5173ba633e618deb11b1d9aa602c61c5f9b5d42e627d986efa4d6ad9fa271a87d166696c3adc8245ba97ef6e71e9659dbb31662adcb5d35afa0f0e82f663573a20ac7fac6cb6a90a05f510b0bad7c3511dae0f3c8619f8b9604e64ca38727cf29db79e27dfee9ec17b2503bee2e441043de70e97b1d77ff5462741194a8eb86117dea99824f4c63e7746ff58810e2be95d62350fb77693fc3db29240c17e1b1f716fa5a8a2cc3839ac952648a56fe63477e5d090170cccbee345182a6c98f801c1b928d3834a658738f605b0ad8b7ffd1bebfb4a7a0e053c4812d25c4438eca246c590e6fef6ee9adc44e53b41c12c039740b15357b35eeef461d3b6e5d3df0c8ba27434f3a19a77c6ab80c0c5db321d330785a5b8bcd023a35ea406d4e9ccde51424fee20276d08e11173d37b86cfab13cdf4a262e9455797998dd9e44e684fec660a450a7c8b4e7c0c59eaa6bb46757fde3d856e39ae472c545c1b80df14e9eb2a5d22c471740d425d23782751c12e16d65dac7161530f2b7a71d87bf00f72e66289f458022167e982bae19ce81f3ae30173bbfa1176e324e389c88afb7daef339efa90e59b6b7e1c7cee2eac37b4e3ba8d2542805ce49a3093b0ac552365a9df10ce752cc92e7b49128c469c39fd810a2e24633fb010f230926c7a3a64f89f988242f127df25b6ac4608623932fa079e3c5b0a10f898400816f40a4310fc8ac07afe75459fe8cf1fad3d97a99249705fa376c080b543c8b7f1c7b06c91a878cf56b84fe54bdb43538eed959040a5595689c2b4d647246221af176669b489f1e5b90f8a8c9037c4ccb63067605d777776d097dac4e13b13cd948df8b9605e6f9879fd53cd4f7710db253ac76e46e538c9e66f96cf79dd676984476c9a4733687c9f1dfa54d05a3993cc70ef74ca5d5bbd85729fc1930a2553b59f2350b67a60809b37fac8535a4ad525b6d95d232395601058189737cf29f22fc5faaa573d941aa74787fb922317f3773219dc04b00ee62505036803dd59a2c95c697726b0767b5546335c9b13e2b01d6bf8cef5f79d45f85536c7c186c3eb0a261e5af5acafc0f83852d195eff38d553642e9d317bc5a91c014ca88a362305374bb00243ab6524c8801d5890d7f3c80287cba7ac135325547ec1b1c8213ebcb989f586ef802f85220300fcca74b677ae73913dcd0fc0db722784abe4e83eb93c7de56a8ef300c5a51372c8681b43b03fcf62354e7d4b1df5e304a97c3dd5849762432abf3fb31ab47982f46b1c4c33d6fa8eb27c39f3456760005b77872717586e74361720bfab01d4906c8cae2da6b9e4be45c41d4cc7ba399d6882992b91219b7a17ce3f29610706e419cd66541745f68c73776a60831da00bb0fce8439bf3e875ddd77faa383a87bcf554e9a9cb3766238657551c736fbf9c7e733a1f5b2e620d53bad0be4587c9db8f4940ebf5e4c2e6afdc48208a928a0275640e3a08283f53c48a8896bd46f42601650fddf1d162ba28f313497c6d6e59467ed89a5bc70f18095dc5e3122017dc42294cb4dfb9d887ca20075adc07c911368e42bbd8ba15eb5977498874e61fa6b112b9628bb45f700034860ed348de0bafedfd3f3085227a5f0b50ac9ec82ea5f2949f3a5768712174322b76309e4db3a5f702c5190212ceaf4d18ca8f98a0641fc0adea7a5c765ddb8949d5800eac82e00e68a92e6e6acf2e26daaa3107de7545bac0cdc81107b4b7a1c83a91063c283ae076a871ee0816fde6097c30e4ec5532d751c1bfb484be6f0c71cd1151041d329f12576e36d5609e3cf3ea20c631be9e19f8c7c11208e555450366dbda3ea35738166f6cedcd98ae64cc86ce3243e9af29070f97704a277adc2bea8de8dfd17342b400e9f8f06f07b10f373f650034ef03f568d84954f7b159104596ba95217550019fc56f7a128f16ccb8f1336e173ab7c21e40e5e6ec38bfd1ebf5d63f865fecee5459c8ea0c4791d4e7dcd3675790da546f8b95e77935da183820977d466995a98c8aac594a65d984dbc329c39aaf808ec6f9a2a405b682d2b91b480a6d9269ad8a15815f4a9fa16a7b7b432d4346c6299118e684c01a1472e22237d6a5f30706badc40168b00120747b5796d5a9ab294ea9a29f868140abd99ff9bd7f77f1774b6de0c4ce9cbab6ab673ded1c462301718be6cc6ed6c7f47b7f09524918ffa3f2d972d524e5be14145426c4b66d1563b10b6f0e16ee18b8a67ceaca183c1a969f553388c0496e2ee6ba7b329218b2fb4885e87ca9f3425fe3337db8883964334913f711644882af10ba84b2117aa3601b8fa9dfef76c6b7b50960a835af9a905336e1c6206cab3001a488d34a2478758d7632897ef4f1c220861da9a78f30b9f6087df7e940b8d802776f55216fb169e17620b14dffeb8d55bf6b94c18ddf34da0c3ef76b3e3c40ff3e76f81f750098b510dfbc2993dbfd25a2c42a1e3be148625b3397e44a91a5c229e3237e0e93d7b96a679d0b7e47a6dbfa84b9513c98948e6c5e2a4aab7e6f7b73e0e9055fe35b8a9b5980cacd1fef3d73f8cadc631e493345ca78f6a4035abd398d98d3c5f83a5458378b013d37286b0c7f6616f522bee5606be1e61510724210b5d46bb88178acf75bfbd041cc0302b7fa2c08fded90cc2043888e2f9e87a87c2dedf3b75bdb176c8a8beb7e39b29b09f7419f942f59bf816edb3663e013a0a223009b4c6aa7a37048706446771389e0cb238dcbdd46265da21220507c0d8198a98687bd2ad2e20c3515e1ef27242113b50d1d36ac6da26ab05b04f0e92501d713d7b55d946394fab98e8f649dbbc1b3998ca5d9627eb13bd046c0a79c7a2dbe411c2c1c9d2087fc24144f60996df3ec69b9e0d4e9980416d064ddc8e16409548c5e734fcd9faa9de2ae300a5b4d8576e800bf139ac21ebc98cf01623fde0a6fe4385808fbb31591393d594a2d6300e802e7efc639c67c4f21bbfc9b9fc034370bd18c773826713ab2b5cdb5b673b53b63516a64217e15857fb273cc2689f4a4624b6e29ec2be3fb6e3069169e30612f11079249099e9b34c33a2236783e243bf6441b48fa45ef1c138c8cee11cba6bb81a16dedccb6ca52da04bb3da24c88670b46e5148c5237024a6f0779b483b180c5a7403c53f9a795a4654f203d3243066445d6ed29f2453cb6ab322ae6386062b330ccac20be8c1a32a62f0d89ea972c10e3b1a53d298ac44b0034f669755975da31e574bf2428c2f99f21601fae43258287d7b6e4562ee036c75a937f5bece87a2892ca048f75823586b5041e3c6b4e915cb76cefe7776fbffbfd7c87704dd164691708130c98c407a890a4f089c6cab2a01d3631fa0c8c4db192fe055ef9cc113005a22e2780d8f23dc087a1ff01af5c8688adc9aa1333116b44f1cdfd8071a226b2c5c85214c8faebd2e2f34f70ca14c644eaa2c125f91e2d84bdc1984984a4beb85ca2ca886f97ab24760f4e6835ee6ebe3e79d2def0815e9a54f24baf7af08de72f2f5e9008f99ce21781dcecff089065dd4737d3bb51192544eac668a68ca35a9fc56a2ce1a35065d4b721694fde5b2c889b2bd8063824fb4ae881f693724293178b8bab33eed5f254da82f9320b70b2cac079137da816df46361bc6bba9acf424a7b9e3963fb8579c29e2cb2856106da96cb2a2ec9e8ff0330a1c1dc6cc795709a909c3ce2c4f1ff037ac2141a3a62d24af050e3cc92568c137ac1a00383483804f7bc948c5dbacbcecee230c685c13de5a232afa989cdc2dfad4857b936c7652fe3de8703fbea2917a3160f76fdfdce3f8b21b433a7fa972e583607b8766ff83e409aba7636433544561ade48d44f52a579006aa211a98e5522f7b62ee5e175c8e2908b5d7b81da2d5aeb5798ba241558cb7ae6d6ba10f63aa3bef507041b2e4ffebb4a12a34f0af0e50258e6e5b81561c8abfd0ae61a53519e3e6d4932f2ef458b78c1a4e67416c3490c4353c452b212725aeb90f7921031b5215830e03c43bfe322ebc20ea4e38b3f16d73f4cbe981ea709c407d57cd39f77bc714c74eb9971665005b731603b0bc7ae05a6bc6fe0e0851e06ea20594cf83d9d449bfd9d94ab2f9ed87eef3541c9ea308600266629f761df2eab779a563ca30717dde96295b25929bcf5ff7dadf55a402c5e883fe828117a3789bd3042bda385cb07877e4c7cd0a9566158c7e822e052d14ec4532b32a06206574805eb283332d52a223a6410fa215fc065607b09b8ff42b70b261254003524a7be1f3db461887d87956014fafb8b6911c2ed6845c5eee75ae72f005511a8f540805e4432210443f151292aa1ac09644941f3deee5b9d35958ed1dd05ce2683ffa68a98273562c849f10fda3bd62dc69e68ca58d4bae32b1f459018c8e63936c9189df091a37aee8728f88626796eba3436099d2802bbf384bedabd9367704737c9ec421a15e5e4a89c064b2d0b0343dbdb06c2b22c65b0985135256df260424e4d486ed021d51356b81c197fc942c3e47208bbdf269f5e1849745ddd26f6929e3f1553f4a7f666947738937e4c283881576d4964414dde9a1ad7efab604e5980bb25641918128865e77719ee46c0afaf86f1ab13ff7e5604d0f287de9584b23363be92c25327bb72622de13e129cd8368931ebcaae24c8a52c0a80fee2d3c999b8c424325544531db04282dcaab440a968e7e09c5c1124a0393963c86c8bc9a53bc94a5a53e0ffd6499ced387ead6309e0d9ffb0ae50ce3964b306fb43018d5530f183cc9a5c756e58499e17f65a9897a3e2e45d05b5332c1427ab6d68f391941c65589eba65faf4f0725986b93690e906ce32d7cae275ad0a66ed1ec7476fd60a4ed7bcf4861add8390eb69b0052c327126e5a70bff0880797b6463f247ea0e170edd42880476edd5ddefe8a83f04c573b4102767994f971b14ac193c4b74d1634be6fe22fae43abbc6fc71ae6e1bc1cc70914e5f7e1713af20903b6a1363d21e36b48a2cb584a3ada8449746b8381d00f7ec1f323cf41ca9dd4c0d44c8bfedfef097537629370b5f18d7dc75ce14153f65b052baefc0f30101c81075e0d9b0e12c89906a46afdada97f9d5dcc7774160e41a2233f9e51a49973932f61a0e454236c38c7464188fd291c8c473e7a03d4835384ae5eaa24daa0272855080147e7d7469b51c7e41d60ad1582e5c08288a89d636a91e561d0afde75b45c606aa1814733e944525f58c84c49c15e33f9d41cc36a99af19b646cabbd53e9edbbc19cf4071d345b4cbd53efcc7493686a28ba0a1ca27bcd35237e7af020414dae9999b9cb28c966d379763a313377d17b770c3a1cb9c1364fb185ec1f87b68fe03926e7a8f3ab1c449c3949d7b223f45a3c247fee725d413c64cb5b19a1c961733593f0affb667ad44169db4c24264a3a98df2d8cef772b79d4b8468c9ed659195d35259cc8973c0f60a2b216f4308a7b99e73c6343be27544a055d08a8fd80d1bc0a0f728a217890eed95d843025caa8a4e5604437b23c729f81c7596f3da183d1a25fca0f5320d3d41befc1f821d30fc230014f5844b8e8ef7cf8bd6e5a807a68641ee05bf63579220bedc59a7255d7c740a3c4f88300bff0372efe84ae8308b0e24f5389431ac13ea05ba07274309406d9649459487ba16043201eefc8b2213a7ee83ee607a2f8877dcab5a8a1eafd16c6de0b5e13ecb164feee09d05d322d5c5101f348464d91ca6fed48a990338ce600795a639b7614486c333d61e0bc79d75251c0b973f3199a22fe5ebc4b090458bb3f4e2c007ad1b484661b0f5ce3d3ed09841ef05bd92963609e87135cca6d9c20d60efc4b83fe04cbc6847ec4b3afe433ebc952039bf9acf57cf51ef4386191125df79ac7e333df16c24e9658d707c1def571712782490ad4ca8ca09fb20fc6c6c8e81a0a1420dafda4a69cfe301cf13e92121040d2e8772762016fe4eec9a8cf8c1ffb110efd4be38f8664fd08fdee4e8c06d7afba674e02581b52a3ae2b0a0050ee6ad64e40b12a5299771cd78d921589c87b618f57d53fdd863ac17728bde946ddb61c48f58038bb66ca761643a7da5198ce3a38e5828a408c23bb1e0f775d20b2c95ea3ad5417a8b445208bcf14dfd133321a18f9267be759ec260b06b5664abac287a303c366cb17509432a397042b00beaa047be30564aaf5d24c543194ef4d483631de760e8ca6eca114c8eb0e6fa1217edb76168cdefc448ceadaba8e8439f4ca3588b59bdbc8a65728c188ad38aefc5ed261ff40c887990cff18b3d9bf787379f31827d8d6ee5ebcba992f470d1aef8b37fd27947f31325fe39bb65059522b42af4acbf9c76607a186040844105e48da1061a9d52c010b464decf864681be2e27c330bc5c3cdf1469a50d5ec902e6d9e207c72c3c849a33421feb6fc43f1a06e559a6e8750d182598c52aa01d295ad18233980a456ec60af40873c43c4f25c8b6335234d7948a7b206245729d56feb2721fde01422330694aeae06dad973f2612d3f21abe757c399a606bc287ab74c01b2762e7549daae4249cdb93016f7d593de48abbd5a8a42538d3107d1298fa004342d985bb6b379126407f9ecd08e8e898b2957551590546c75475d3ac54946a8ccad4efebdfbdd36a2534cb0a1b02ab7aa3c2d487a0397a6ab841a141da54a41b7b70653b983a46e824e64516840366240b6123031e6db3424ee114a8f4ad6ccdc674f900c84d220e2701e185d8ba31a564bb59ca4d91280266eccd369428dde30c877af30c97e0acf7095cba1308f28e2908c2c1c0cb476ab6b237a5c47c345c16f2d6168e5b58495c83ab0a78977981281163570ffa5d838cf97d34e5c268f501112a7bee21a0f801b159800693dbf63374f6b0e63f04803d133eb5be9d3805bf714faec589987c75674c913131c6d5bde7c66db8d7ca71bc21cbe62e767f6c86feb699b0c8ca7c498c036171e440bf2d9e60b92465a18c562e77e62f38de2f6a67cd2d7a046f4b88d6250f76e08227291bdb152a5bf719b81b8267a70ba9d968dc385044a45a1952f40692d2e88f6a241a98eaa6c01486bb940b41705ab05de5a81f3c5afbbd6e5354291bf1423e0d74387297e49a92966430bb94c16dbd421ee9bcf046f32e69d67612496811ca3848ce663b3318f49d3f850647405c49698f9dec58a1081da7617abbfe3f24a4baa15a5e5ba8beae49411d891448e48700cdbcf2ce943ea8fefd2fa45fec1cf14e86900b6744e2abcb8c422739b7dc8f2f91a6c8aa70fd93e7f3198c122fb8b614f4be866b58caf58d8a48471ebaee405020a1022eba9a1072d7b26e6222f9e7bd12f83dc22c7b115befd369c8f520323bcfae691babcb20a92f899ec22b216b173596ef544e310f12a0960cb6f5c90adc5a76de04a3161d43958bb3a7c22bac9df86d56c27afb9db14245a6cec46833425bcab611c02282746237405cbd75348aff92a050179ddd7fbe6f53574c516b30c2f3628fb39eecaaa58f1e639159aa5d72b56a48ab6807b16cb8fa93e4cd98322d5ff9fb6a8e7ea0d3325ee4de732186341f6168d93690d4cd98b2a55ff12c4c8c5fee4622c862d9584db43950afa9f655cf4217967069ee8806e473346a877f3a21f440e8eb9afc9e062e27a132771d510299f1afd71e170ba6361a4a64ebf90e742fe57da337b3dff4b215fd9651f34ba9fa78c70006d25ae7aac866bcff927a03fd80c62c53bf27102e6c323f69b59b54fe2aa67f17dfe983bc2c0ad3c488f3d55759e224260734b80084187fc883126b8a92a3b8aa219c5dfd137a8be64c5ae84eadfb871df8ed3caf22050f99150511aad6b56f1fdd8b3644de61409a0a56e29f168fef317e3d941a5ec0776cc4af56f1dc99f4df2fa67bcaeb93f8cbb8d59ecf4f6b52eb3318c3f14755bf6fdae18c878e3f14e4209aea9cd38c3b7d65b6804c89040e0edffe65fdfb6b1f9bed50d471ce3168b8fea7a9e4ce49940bda3722615f72a1431fe6ffef4062750ec545789fb376eb838a5437ff54fe9db40e88ae2ea6ec0144eb2790f94664c133e9d8a40207401bcd0d35c99b438e6c60f2f3ac6dc5635a2fedd08f62d625583a97b67baffa86d08d972623c3ffe98582456fcbfba6342ac3abbabffa2c3f69333ef97f8a33b7473076f54852ea13fc78338a58c69a88aa7f04301649ffea718571b5478bea33c9879f4ef5bb44c41d462524e5b3bf1321e92abf2a002ba0ab93ccc043ecd9134a055da32b80234068102d7e5e7f402816d9e217155e051861b70da986a9f4dce0641148da5d2eb96beba7a09b50e59c2625e83a228f2dac6a21c9e0f3c51beb6a966cba0060683810eae184e0e6ed2f5deb182e69d41a279286fb4ee6018a800301a2c81301ad04209227cd4ebcb5a48895d4a054a683e8b7b904be469c02235a0ef266bd6df6e5f9001af603e0e1a688d778cd397abbf91386b7097d7f44e5a730dea2bb749f74c0d3fc4ec09f3a02a155c2bb78ea1b1b962905b3a12826fbdc6619740988cf52f1fe73657f926532b91960a6cc098f7cb780f924cdefc4f1832845a914f356775e16657aed485168d6fe116079eeaf8bfa066ed745a81421494e2d5ca4e230d4e060bef1fad55b9f9722b6f0c84df2a30cbd5fc426879b4122c1b25aa3abe9cd3b761018e1adc310f6621f247b92a0a1a298a1b649da4c50f0bdba5181243bda13a7f6df1040ab76b820fa35135c1ce203ddb826605877714a65baa3833f9d2d8a69268101b2bb2532e1109483a16a0adbb8f0bb81ade207ac158402b66186fe7ed01c533a71c29d92afcc71943dd4aadeb5b4134efa6db00ecd7776685a72a2c1503664334bc916f419e83d800b08f9a9b553c0268574d314b42a72ef0338626fc58c3e99ff413e2fbd347cf4907f0205800f701034219a09514ef0fbae6e19e1dacfe6beac2e12d43de89fe5c1bf19f3a35f56d36a5ffb05d2a00b595ced1513673115b1da25debc80076146ecb608447d4db185e6f29897844d686baa57b3fa396faddf030b69f663ec96e63f13edd8a6527d04268b8ea4091b42a078c306dcc719b885458382c1e5a04c46cd310cfa604445cafbcb0d76f093e94478e0c016bb66094687e200cf0f20a3ef9519d8ec1395ab78087ca7d1451bc9d97ac55f1b711a20935baf1f7157d6c3f2901f815493b35751802323cba3a30239a4d6749d6f1e0217354708477a3cfd93c2b6f8ab0ee239a1d19fa10fa04ceae60e46f750d894b1664cd850ad68fdbfab3d49ebd1d31a7a1f6c488630325d528ab38574104f85002f40422c28a5177c010cc4d6f277d3eeea20be1a8049e9f93c6f6682425646ce9ee4e45e3093c0620abb4d2d25e0378667e41239ca04ad8ce1a9662ff82653f8a0e8f71a7012af5eb9b9d41f5617974d180e695ad5a2d28686314dbe6bc78628796b82168aa543e0229260b9290867e6368ed98ad95cf9db9ef635d93dae715475df751c43215c06102fc1d82aedfb94daab9c67b320afd81c66cefeb127e48ac0409f3eb8cd77dcae3a43ed6db11d1a4a960cf34887e2a133e9f22fc3b604d1825c489ff8fab0a1bc9844937c3000097cb7edd6c82902c579a1ec159a64904e1a9a6876c94cb77b143f852cd5cac4feadc8936c7558213250b58371b743f5d7138226b437931ce5fc5c29ea52539696c3093e729b4fcf26a084d8b8af710ebea40f1bc6aa7676053dc0067a64eddf51608c8dad6e5307799eedb2264a64e9132c48c9335c71d6c1696d0e41c92320b0bf09de1d4badd0cc1939d0f1549cf194559fc74fd1fcf66f45a5c42245be5990693d4cede8afe094413fbe757e10ec689e1032b73903468eb60669369f9196fc3c3522995b8a448cc6f0f7b1609d31c84590235eb1aff4f509a5e5a4d49fb0b70b38726d525c39747b44116b886acf1637e819378ce94a66781867c3c6b92f32bed869f91c8721ded694ae8840fe0258239035306ec4475521e8d04de097d25d044a37eddea3a1a725e6ae6429d08bc0d06a793cf901266a65066acb086904efcf8f7489a0a4a8ed788e00895112549a39ccf3b9f458cc820a36c87dc1690e8df4c3f6fafdffe1f58b5cb82928a2054e1888422fb1b57826d7088bd7111a878004aaea57daa1e85d50ea561536321984be6fdb3297d8570b5e3915e5873ed295959a1ac9bce01941f5f9af03ed4c3a13428af028342c86a01ad06e3dfd22b3743fbc8b30a4f08a604cf8aa7b98db5406b26c388c06b2b5d14e6b6020f27eb2627670d6ed6739a4ecce0662ff173d3abd9072cba91f19257cbf84e23d3cb6afaa56ca845be97c4beb7801ac46aa0fb2c6dc98169dcb6e10a6c345c4f336dea75ec2c9e0c37de9a332d4c7efcb05d47ce0a071cd73dd0d7d85fcd240b28510c1717fa99ecf463e9ca66d6e7b3e08d41b61dfbe5eb206b36ea54808f727a4c9d2c4c62b7106bbdd4f90a64d518325c33944c177342290f0fb04d6016284b40c1912118f58896316ea1e4b84de281c04c4cf4e509207e4f7bf6c5242205d2b8db1227484a61b86dac9700d1d5bfaddbb61c851cc44422c581513e865bc7a250561a970513057bcfd60bf4b4973e8aa04888ea2f408d0cae504a590cfd25180b0ca047d8e696534f686995382c81b70ac31eca56f1bfc3da72f6b3d422378f82acf8c46fad4f0805fd2d0905370c9417543fabd609180b2ca96f5cd56f71e0f9b694b8768528fd426f793a326f8d92b371e91b1c69e50c6d3e2c2befa84816bf6c047ea3776779ea35e6aff7324f1481876c0f02ffc27a170766042c62bab5582be0a40e03b7c58053203497beb0065f4ccb5ea4ed38b568a46b389a4a0bbbc4d26222210653bfc17d79fed01283fb86c8f29cbcc0cfb36bba15e0f23cea1ee4ecfeec5add477c1b24ce6e4400473966efd2b3a476d3d89812deb92bb0ba1d0c766e5259eea187b6b548ec6cbe67f784ddedc1c06b4356efe780cfb7b44f5aa6e2643fbdbb367430ba5c54935fc35871bee5ffc3b263577c2c26c640bc5ef893fdb1c68f1e1cb617afe0e633c3feca745d3e78726b3b5fbd57a647bc5f7c375be991b832a04ad6f268f915b1e706e4f4614c933f839d2e0c5a588d0649527df54268172fe891b95886b00a44ee2157c5ca5a669cc1ac5baea398e9f1aa2ad5fbdaef419d5fd062d655b065e1a401af65622a97fe8b769d237fcf47abdc6b605d0ff33f68e9508dc991762390539680e5c0b45ba8da2cee1d5ca9166e002fb53aa3739e9f73c1ddb762f854f510a350e54d0b72f509fe72435cca64fce5460d2a173868bb7f537fe8c168dfc656243dc7f09b82a6a6583c2cb76265c71b86edb592cb6c67f7e8dcc2980f783b53bcab040e7e778c0367c0796a9b84ebfe189781a399dcbc6e66e7037cbd0c6e2ebf67ab08ed12b75ccb927e602c21cc495a7575fa8160b91066becdea66a5b994321afd3530456ab7b957932d1033a5537c0292a9c043abb13484e9db893ba56b13d67865fd0ab00e0951781910dc77500ef39adf751b02ebc2d099a77951cb8ec21b7f228c56417ab8437ab99ac69154b45ee17c22af5bd1c824f3020b69ceb966c8b865112cd0f307012581607c5d880bd8b06d84d693a1a98dfcdeaca28a79763e854f410361bd26fb8b4af03b955d192a90d13ebb6f8e2a31d22fa4012221cae36499785f13f448251e44c63230b5ac2e777f9bf33bfc5fd4dda342f6b699b739a7eb023101ce47e333f6d36aade497925215248eae14dabc8a025f64325a7a50e16cba3a266d692a42b5f824b08c3854c96524e3f547af132d9bd516bd959d59a4c8df4f16a38856be90b488eb45858a5f0bbd384ee09835a287372037bdae8e2cb440a3da94dd6864cbe5e9d108b085c069046821a3d725aa94cdd5747f74746d08d80238ee2911d13087d16b92ba99e5531d98ea6778e9294e9e24e173780fc59f5575ed94269f8a9f477dd3ab542d677870807ac16bd3c3bea4f3ce5244a9da29a7291141a6c8bc46043a7677bb5520885a351dc7880b8d93f406740c1f96c08e077c6dbe79e50d9860a3615e8260bdf2e0204b0f77e725c692aea3eab94b3176d4a34cb00178f1286ba146f7c89c9315244abb102289a1916d37b2db9adc5b4a99a40c450b820b2e0b3f7502a9a6c7c09f8063a2b7d35bb497b1ef9351507ec91f1a1a82f2a287f2152e3ee9a15c9cb528fd50ee668fd8811facbcd142050f3a0082e0ca963349c4e88973a5a45e79538b47fa5aa3ca90a59395d9846c7e7c85163947bb1be7e50843960eb6e997ee66d3d2cb6c7a949fbeed412dde3aabb33a9b893f18bff452319ea789f03ec62f69225b3d781f43eb2a91180f43ebeaec2de51cef050f8a07bad0bd679dce5d7fc0866a23bd6724a47f914b72e772893705351573ded83642d622b306fedc1392c9914ddf861212e9c367a1ab122b9d94abced379369290b8277aa40ff3e7204c5b579f4832970b2b12d28b746b558c2b121e0b75f675e12eeb42fb309ef74a7aa7a4c4d33aff180fe395b4c7d09a8773f9b5ed8fedf795b20e7c18aff4bbccfbdd4bc1d04acfd3bb20b99ddb36a794715d9afd2ecf30d5b36b6b6d02b85d03d137877e165576ee032d4842b8c1b77917d2abab365ddbafb8542eea5af8cca6d5b5bc699723dcfe63cd8a35d189638d4af98129a65459d5fbd66badb5d65bc10dbecda00e04ef579f3bcd29ba7c3e5f112759de8485ac4d925d5625158bcd6f9795caae5a9b56ae4d2b17f05691528a77c5788bb531cc482c5e7fcd3a69e9a1fc3ff7a2d253f5c0dd2b7d8fdd2be9eaf39eaab7237bec5ee995f494aeea127a283d4f4f855097e82b690f66ef475da23fc24e631be3cbf9d35b2f7ef660d0ebceb39a0ae92bd2e774ee5f6420f8c90d557339e97399f4316054b1fade92a6e14b35cc483f6b499a49e72cd6a2907eac45891f66a4d7b9f62c722904dce2d7c0dc51ade4aeb5d65a8f90909082e436d20c49f72e427021e4822e405d8b67f1506e754f6b512e6ebabfd532d0e5ff9f3537fba4ddebff599d6a922e79bb6a9d75895fbfc869ccdb95b607128469b378309b40b76eeb1eca5d64ba8f0091487ff4d5e74d9469ebbe0cdff6b6163f6b51ba179132f831764a3c183078b55ea43f42ca25f836245de28df4f6c15c56df06c1c4c6c87e65653fb2313130cf722d2e2f5d5f5f5d5eb87e65ee732bc7722bf795fdbabec0c4c6c8c8c6c4c0bebae815c5a259548bcb8b172e8a55ebaf8cfaca7e3ba6fd34bb62f09e94bec464aefca38f0123f332f8b687aa48796e700e1a34a8ccc1f6fdf792ee0830edab4b1e9bd6a28e8230ed168f8494e73e6aa1cb405a68dd05b5cde26b9bc5b3d01160da406c7f796cf069565d2aa1c7ee6160d525fa2578307bd4aa2ed12741e961e8a9297ae5d3b32e51f54ade85f1251923571f8cddee676f89f7b3a754e351a5b4d35f977cb6afd9f6600ec2b4c3e7651d8fa5d7cdb407b3b7447bbbd749d1deee696fa7a97af4a9ed0eda3467f4d657e4286c677fb3919d596c84dd28d3bd02e756646a34c3657fa51dee897045396a86d325deb8779fbdf5d65b6fadbbab7479b7d6dfd5dd55babc4badeaf3f67d52cabffb122bf1947619aa56227712c2ed9a88ee22e7721eae28d38dcb731365bab586b20b6577e23cacec51b267d5b257b995923164e9577bee6864de34cbe33f6f0a9f7e03d97d2e017d06321d7309e8d376f4917220bf2af1d1b9afa0ab5dafe84ac0ec5cbc6839efeada35c44649aed2dd973ca5afcf44c39f7c5ee53c57424656abfae53cfa4ab966d525fabbab5d89f328fdb2fa6a97f3d87479d3ac89ed94d5a3ef5eb3c6dc5cbca9de0b88f1fa52270c1150fa1c9901cc106532cc49531fcf5aabdc95f828d926fbaaf447bb8a106f15726b2e83b84fab2ceb773536d6356bed62c25ff3cc86547546c59c47ab524e8263a6abb7cbb347576cfad56ad6a0978ed50fc2540661ca4549c8fa545720a0a6636e7ccea39f630be95eee74facea5fe7c2a04dc585fba97ee3ea557cee55a58028954ac3ab99618d6721efd7a55b1aaaf5a81be247740987881dc6b77cc6d5fc7dc567fc0867c7087f62dc6ce24bce2ac89baa42a6757f97b16ba28d27e367b3cc3339ca5c525e605ecab8bfaa815bd722c8ae557561bfbc6c87e6265605f78f635c16cb5118fb3dacc369bcdd99cb3b7d5c60c5543da05e19efd8bb41988f596e13cfa7857bd732010f9646e623375eccdc2dafe95252547a77b89b1e9b273cf0b6343c34f6c233a9ebc3b0af16c3105a82ea552c61147d11c446c6bf55add5d10e76eee5a541815e220d65f9d613ca3d57e3ea5d16a8e319ef3d27e16020f3ca6750f9ae66922e1cfdeed6c4c1c4571a4b55a0b9ff6f36be34ca4b45ae913c1338ca9ee31f31a0974109e61f2174a21626fc2cef30c8338771787b31eceb33ae8bd598b2229204ca9ff5cc25ff23c477188c336323071affd9241ec3e85b17972d3441134c1a7bbb9d454c350fcc9035fa41ec28f59030c79bcd95273c97e8ebc1bdcf6bda3782f6d76ef054910244192835dadd0b612f85125bc20026896628cc3b7ab1e9d67c71fb306f6eb6117cdea81844392334cf60b8166913912dc336c8d9f5df2c0ba34400bd9972a29695a3843bfc8f913e58624596cb85f50bc9cc4247276366796adc1b3fd43f0ad99f362cfb03581f4114c8079028615ba90f990a10a2c459c30d2a50a89bbc40b1189a4aa3f5b5c9ea0a303983131d420860a2346aabcc0439e313c448113cb50c0c48c152086c8d266893659539a90a2ca113990f5a175998256a3ccb035a3b1c982251447dcb8c6cc9838ffdd0592fe888622316738ddd3d19821c7314a84f814d861801fee15337d1295a7017dc0273079f7710d7188432cc50af64f121a46a93f4dde7d5e75baa101fef2a95e3ccb84ed9b43b5b699a6214106bb4b43835d71f7eb0e01bbdab9749f96c98d0b62a72c1876dc82145534118420365631f491e008b23a3dc0c1227302dc4265493ce2ea22b6c4501353e508de4d3130a8b1dce7aa7222172db46113b2b667985814b628c4faec92acfdc4e2ccc2c4983082b1a6ed98bac89cd8d716da334cac875df2c04015c48c87a47b862911dbf4e7076c48fa4d969cd65a4be23b77fe8b11b416bc548706b6dca75ff54829d6f75ef05e0d0c3066b1d7d39c117e89260cc3d0da7b7fb728221a0a97d411004890e5b85d28419623edc52167e56c36239ff64c97b3afefa3f3a69fd9d7d903a9b330d415d73a67504c0150872c475ccd3faad609d925dc1da45e6d41544eb610bfa1bb20b45d4fd5beadba14da25f865f8330d8220d30ec35aeb6f6bf7e3195e08d26d49ffde2fc9d944ff5e7af575fa46146d2e8771a5d47105ddbdd65aad056dadb6ea5afd5af2c7af56038cdd7b6fad3b9aacad1498c1709be6684726bfb7561c087e2d49100449ba4baa5d67f94c37ea5fab1e719ac4157091e5b81d07fe0866dc086a1c54adb914023ee166b8ad8339c26df58f3983feacb34b08c01602ee9f5df9d3b0fb57b22e4d9a5b5bc35cb533ebd63ebed6ba1e248a733ae19067adbbbd61ffebd4e9ac178b68fd6998e792b50ac0b5566b2bfd4a75dd56b163379890a16187b026b26879c091256f7e7bc888f90157194126ceec8f2001b326861692b44900970c4f546db921e2c9d39c01c111b2cc3d5955a1609f90e20e146990a0c3a48733338d11487e90723565cb145f45e0217351a8604416953016ca1c11449aabb12e3cd0f961f71028799a91bb6708cb14352f00813503561460a4e89304123f40e9954cdb5a718c28464d9cd93e2a63440a5b7cf89386ab6797f0c1cf1826a2209963a567adb5d65aa6336449d6f7aae7f6c29120a24081c99a2da2979a3661ce4e152b209933a84c49cf3e6f628bbdee4abd8c48cef9b9397fee100c79f70c539366974cb50c129b057629a94cb86e55a3c5e2ab31cb54f10d2c34f15297b01a2849e6765d06d9ede9bc999e3a98fca687210d1453b86a942cd13a62c5828e16beb091315c6a5fe42c075a0f244dcae5c3c6891b3647c624d60872b3e609167ba271d375efb5f7525a0df4592d042dfe5c9d2068afbdf6da5bc17aeb9df75eece53768f064ec063e5795668fc1fa21b6bb27bbedcfa89d596a9966996e4ab1f59d57030ce0c25af787e00cac153fc6fa826538dc8d7f8240974fefcec35d5de27e82fb5b0dbc007eeb49973728c843c25d650036be876640970050d2e5d0633d04ef2a03a0e029025dfa006cfcd60400d065048f07f05b43bac44fc100867e0b00363c8800630c00086ee89282b7e1c18ddfb211812e19780078f05b58974a7f3dd046aab6ee43a04b00fc8ddfa2409710bc0d9e2e697c037a08c6e1089e9e023d64f49f400f1929f8ad0968e892f711e821244e970dfc901e42e27e6be89f7449e329f82dd765043fc1d7dc8176f1441b10553d64ac80c8852e89de6eb9d8a0d6c843c2a7dff2e7a18f749941c84158418d770e3c035db6f8500f21f7d6912ec317e240e8b7a25e9739c20a5ae0104759f015e82163d56505ef7ac8587fcbbf852e8f3e4a0f21f756a8cb166f05a08d84bf65df025dd6b7e0b72ad0a57f0535fe490f09a330117691e3a3f490b1862ea3fe490f196bfcd6d3bf2eff5de821e4de22d2a58b17d243c85d65036d84e8b7843e872e6b7c8edf8ad2e5d3473d54c52007e02fc84ebf2337bd8e2cc1e788b2a0825e0ec0efecf450b9e97164099e821c809f203bfd8ddcf436b2045f2307c0c99eff949dae9a9448a0ddca79f3694400000898f28b7f2023bd0359f733328b97915f7c8c8cf430b2ee97328be7e517df40467a06b2ee95328bdf25e9fcf9c57c1719e928eba2ecf92d328bf9b94cf42bb2d01b65a22f22e2b2e70f6521e7a2ed5b069384f9d1d9b65c9f14f9dab36b393cc28a8d963d66704d1123fc6c31d3f26c83c71c7c28800773950df414ed6df03757e1404f796f83b7b98a00f454ed6da0aba64b50f56ba055f8de74095c978e65cf9fee13a2cac0957ea03b8b3696a7c89f1a5f88be05b329e79ee6bcb47eed31b25983b6fd433bd309cc63b346c6422cbadc79e00ffc45d12fc3acf91fc2d9fe33a4126a8559be31d8672ef98352881519db47fa4ca72b064a315664fb253bb2fda5b8f21af89b33aa034d2ad5d85cf29fb59ba33e60b3cb302b2aeade92ee114afa27ec306bcec8fa51ad23f7512e176679d305ab4e20c6f782c1a1349492e54013079a845963643d2964098255fb5edb40fcfbd5ce71a08a0cc9c231e7f9b7b8429620d80ec7a89025c8b57506f7c5877210ac3add1f069b815d855c988af3b4361dbbbfea84abc2283927a492f2fe04e5fc5c8579aeb6bf037848aeea44e5421c1870d80244a74c142fd5890a8958152d332ebc50244a96960c2a188cc410041d16e6b8f99a520320af21bc76a0e2c3086315dfa664c889a6ac6c1fed89a66ccd1e7db86ae5c3f52a0866c1df0de1cc257f3bdbfb845284637386fb715e19f81ba17e0578c8b25ed1701e131397fbbb02afb8a27420c3316f2ac1393f326f2a6f1e6f2a41b0f0e74de52db3fd7d827913e8457781fd0cc0b76f7558e63c0f0539cfb91e8801e4aa4ee00f04b93617e8c59be60ffcdd32de74b5ae828162d589bcf1f4f4bffab5a7aa5a07c2682379e87abc4d57a980a357d3ba6a457b359bed898ce4dbc6a7ea81686c59573f24ebd5b2ae6a1ee1585d02c54030e7f9833fb0edffab4e35f0970bc15f98270cc9daec9179475d2273115d62ad5f7f615656750ac942aded64eec3311e561966856375c90137e02ff4f98756fee00f2c4380f30ce03cb10bee1edfae7ff7f8f61caf9e41bb6a5d0823886e7cdb01bfb02c1cf30fc9ee95375dacea547bb7bdfff572b32ed7f6aeed2d3e4843ba6fcf5dd690ac2ef9db72f8ab4bfeb51c8e8565db3f57c9736497e1186dcc012f716e408efeef2396d5d6629c736f9457fc483002f3b781842fde5eb4f9a6c15c7baf45d5dcf3fcc8ae668d8a456997ca97195605cba654e60cff1b45481c5b77012d75196cdc3f61a22121f22919b5e1c69be6763cf425e9ef57d59fe8e7a4fdad45d1469bed71d9affcca6e7f8f82c445ea6e7ffbd95bf157d5697a8975495e913992746297b36d7f7c9a3568efe1db7239eeab1d64cc25d09d4b9a692194f3fcc65316b2f42bbf7227fe944cfccd30874c0e0d744912a3cfe5a22f29d9938d4f0e3d7a48fa4fb386cdaf7a7c48fa7f053a30266b6a1e516587197a27d480f0814a6fc5e7f29468a67702ce4f6f85deb21044f1e932b840783278391da82019c361073d717a4eb482991a5ee8722106197afe7ee55846d96a15592ebfda442e84459ca48d0712b7271a375854c8e3068a203748666cc8714f346daa18bb9056882e3170db5a99e6ec69ae4bf0eb8f9932d5a2aa874c19145d09bb82c119da6e0d0f621778248f30ed1eb9b88f69b5a8d90defecd26633dad10e1fe1d085b5ee6447af78dc39ee8757c418db708f08c1166f798bb712ee0ec2b49dd25a6768132be85eaf757777771a75c3c66344913ae835f74f50f5bba06a575757b5d686b75e5baf1dc3b0080ce28ec00122b15808651d8ba9ee5e6bb5b6deeaa5ce19764518100441d0ce504abdf55a3a73a5903ab37eadcdde446fadd6cec09006ead5ce8680d4da19b520e82068b340f0aea194d23597265edad8b556d6803288d4ab05dfdeeb5dff75efbd985adfa0b516bc645dfe54cb71a7dd16cbe0dd79ef05ebeeff6915d7259fae0158cbe566f806d28e5290427b86e1299b19419264b718f03471d3c27366e319c3c2af3a1e304728d313138d272e2cbe3437e6e2e24b7397186b21c33dc3f074f1bca62bd442d4a60989a56cc80826b72b5c423f5cd9b4c64826b49ad4aafc6ea38d89255044adac1a13be2534aed18f92991532510e135c569726980b566292eca8e2ebd2c28e2b6258907c6139d9918395921d5b5a53085a6187152f616e7c4a7660e1ca7ba271b3068d1fb06762ca614c3e69b9ae0c7272d8f4c61c35363a56483a61b63a454827c0463b65b53b52ccf0e0405aad02d4c1a2c24496335128d1a3646220c3e6481144504abfa8a8080f0abb68b78b8a8a9e2422222292b1899e888888e89f7787883b469884705b484848c6167aa1c7e40b5be8736479b6d0bf901d2c4eb861c2dddede1ed3d93727bed461927341470eb647747cc0b56dbde6d08971268a375c6418162a854a3b0ce530b1c3395ae47879366ebadc69618c0c13e70e9e95a411a70be6da5445144785e9bdcc702a4c087689db158e9a5de318d93527068d6dc48d24cec25961fb5f2a3077948c15d1e60c1333c0e841909d2447804521d6f31e94e744d81241b8bbbf1739f70b194dbce1b2eb93b931b25dff7995e9081966d51fd8e5517eb3a6891dde78d9fefe4e7b8098a3264dd611afa5234800c14216b02170e8894af0ace6f16450eb00d2f6374898d0b37da422ce5d09fe1bb2b627a5521b9f6e2314cf84744977e572ae1916facd19d4f6f56b96897d0813850d25e42ee96fd6bc09fdfd6af6c370662d0e7188431c86427808e370180ae1218cc3212efca1f08542213c847138c48f0b7f28cfe9847b8ccb43592843d5f0fe0c8b0f5a1cdef0ee12a2c2a85ad6d11e6f5a081893642ef7cfe3317169713931f1be562effcd19d5fb686d2729bb3e4d974c4f784cb0feb914e1eb40104f3b593e9faf085875d3a66cd72fbb7eed5a6bad3d1c86a196375d8c9f76d163fc2290f0698f439cdf665d51715e2dcaf52ad7acba547f280be56a691fd2688eb1ffaa73b98bd589fe9c9c989878bcff5c8ee4aace559dfc47e6bee43171ed3afbb072d5a5fa1893375d92b9dcbfff74c9f454b93026c95cee9fc7c354e55399f3aafb715ef5ca356bacd8f5ab975903dc75e8b1581dab64bbfa0ff765d5a9c8e8a58888de88c8e889107d91d6853f7b453f7ba15151edc2e527cad5a5bab5847ee8a99637d1663f9499ea12ed85322d7cfc6006123a884110a499105e9bab08f9cf97f4a654fce7bcda55bf2a57ad5e402e9b336045b4f87e0568c8f9f835f8f84908b875a1a6b16fbc3fcf9fccdd0a9620678efa93be838db43ef8d873b5d65a7777af1ecc32107fb056fc13fb835eabbb9f2c6bb6c6e44006ec57eb0e0b34f05cdd9169fcb49ac90117c8aa35a051849c140c4b741bce5a062190f0ed8ba18318bf8eb9b1d665087e887752fc73ee5ae8cf5995f214ae224d9db21eef77798af6a7889e12cd53273ca066085f8f819f9a3a616af70cfc093094b8a1d7c09f80bf580deaed5e294f9d30f61a085b9e6062a64d1419f4746044155104a100e80c11221a2f307c00857142d00c6c04d0050a2496c8c108170489679c60b0d28488296eaac07af3a7084b6c9aa543d71b3e43f850438fbee1e186384ad440e589208a986d7010bbe4a5a1036708324da43c41d29ff4319f1cce5029f2429cad2d3e10a65c89e24f147fc020d12bc96d66e3ea44b5258a3b4ee83044941d94e8cd9f3efc89282964a86873e6872e4dbc0f6e02e7cf9e222b845942410e2834214bb3040d572aa082e68da02b489410549da66c5d61c094f5c09f9a9a3ae1013543f87af7a7a64e38a2214e0ffc135ebcc1eadd3fe1263605949e3d02a2377582510c3d506fd59f3a011743ef6adc0d3d5ba90962bdfdd0156983f26d8fc65aa5a07da8992fe91a0a87daa15f73a9d6173508e66cd929c618042d9a5d5230fa45cba0d915d4d982207803c1cfcdfa2008f2705390e03be08713f9a07d3c9489886e4ffed0cfdb902632f4424f6a225b44c8bfddc80741e8e910d153f5c8a1ef41fed0df1f1a7a223d25f4433f757b52280f91b93ad1b1f6e3287ee99b263e8dea9ab665466dbdea53ad5a2758b526a0e572823dcbf72687f46529a151bc09d4d3abc0f726f00716728c0cff867fcbaa934e2775bbfdecddbebe57cd1a3e6fba56ceab57c99c51ff96afaf2ed5cbc27ca07e05c3813149e672ff60f42bd494cb477d15e35a7d115041e25f918494babd9026b2d543eb4092870e24f7834feaa92d50f7205f484f416926aa1e55cf7eae0ee53997dca378dcfec51bfdb2372c208e7e59b09b1ec18261f0bd6c831728db6149c9b6d5ba1b6a9dd5574647444ce6287da6ed4ee9f4f0f14fa13d59ccb278ab351de1d7fbdbe24ff14bac1b9fa4fd8d467b9a38427572b1ba243e49f6c8c899a5326bd0dede309d2a0f73497c71e611dba2a82b9739437cfaa58bddaf2d8a5fbf3026c929be5833ae4be287f9eb9228de2cd2c4a7d5f278d3dca28f7d6980aa59636ef1bf09b962d71ccea64f69ba2462f5c1ae9df0db232dffac4509695ded6936f1c74cd3370b5ca4b1c51bde243695248d873b3d0d6fa22f8a8fbf3a852f3eaf3ae1179fac4ef6c5cf55a7fb39b23926be9b993568afb33df9c370441d7356fca33bd12d603e9faf488f0f975d7736c4a9d56bc573529f6f4eadcbc0eef93aec9e78d674d01dd65a3a755d860f7e79dfc18bbfd424542aeb1a3b6fa8da334f57b450bb881ef5011b3fb3c36f9393b3433c3bf41faacabafa384779cca7f3e7d3f9e05095482911ab5ab52eadd6d54a63f0912cea3e723bbb3a9c5d2b05dccc7632bb86d9d5875dab33d9d5a5ecea5676fd39c5c0f0fca2d87356e8003754d1eb3ee7552fb629aa9eed67cff6f5dd6bd6a05f79f4d82166da20c07ca07eaee20049f2e6660022b1f62a41392a2668570ad4a5fa18e724306215fef8a1ff29379deebd77cea67f6f94be4894296ef66c3ff452e4e32eeec9bfe19e7c2243a21dbf0939dbd3afdcaabe2ba94e481ba9dd6a4a0dfdeda5702fa489908ffb9bed876a4dd781cd463eee45702ccaf4d66ee4db5e4ae86f9ac8ed85de26f4446c4ffeec897824cab3279475f7966fdf63e86f7fff867b213d453eeea76cb416c583e84952d781edc907e1f642194fb7722ba18c572021ef2dd3a75814cdac01bed59c519f864d1b2e663ef0643af991b954bfe2787a820082a5a59c59b01012722bf79a33eabb0144d231e7e9309b649df76d99625d521fb622e755a5d4f37cce797afc2624d29e64ceab55fb9c39a3be0d41ab75e1ac57ce7322fa0a24c4b9a394526a2d9d963aa594523ba7d6d5b25eed39ab10d99ef36310e7ae0cb9b67522df4681ea446a2a26e66096a2c1cd1a37db4dfb974d63d18e3d32b28651660dff7086e9e43c805ddbb5f7e890d3fefcab3ad95f5db26f6d0e0e69665b1f996d2d0f16ccb637af6d7362996ed0579dc82775ce3784b11049eaac6dfdccae0d19d914dfa12a7f91ea7cfcf069adb6ab7d8939a3a6753eea32d4ba7bddcafeec6fdb2b1eb61747b0b9ad62995d27178b8ad9f40854cc9baed6bafbd83f747fbf612ed9b75bdb72d9d6562ae0e3fba106b5eedebfce25ca597145febdf75e8c2fbee0bdf75e1c82e1dc5d2ae30c17e250fbd8cfdf9b667835fdd5a5f1c73a8eeef4e3e57224497fbe34fa585d1a75f8f83d3272f6e5bd7ad26623fa9b67d600ffea994e8e041d3a79ca7bb5c71fbd4c8f4ef8f4693f823fbe1d9b356a03b68a8a3dd63f7bac4af6e8648fd54f59b1f6f84219cc730cfc11f7e013e9d2cbc01fd225a97542e0df84b40ed453b4877b1137fad8f8eeeeb82ebd9b3d82994be38f62f658cbecf1cb06f638da74fd72d3b5af8d815c338873b76209e9f3c36ef0dab91bbe4c1e3d1214e2bc6aa9125a250449ab7605f5087549ebee5ffb9686a7e7f9542a23e797b8fa5e6badf49f9ef746a49e4df0ed3e5fd18a39c36bae8b6ad19c41bfd67250af396a83f2f16dfcbec56af73ec01432fac0ac1b296764db13dc5f3aedc08ae4511be0579f4bb4e8c5beb986733e807fce074afa0e84fead3f6b1bd08d35c843525dc2973c0736097350151b7caaa3d46258020974d02ec10470e317e224e098350ca8f604725b486e830fe5fbd25aa7972f854dc379516f78e50d1a73ebf1ea02b9543a751759d2080059ce2e0378d3d5210f18dd4cb489a4339b6dfb6d2ed92a0044ee709e0d4a5f2171102735829c688ae0da134d115931f64433c6cfd6c365fbfba65fe98bf5b510e40cd3e3b5cb7acbe731e1449ab36f8a3bda806ed71ae421e9535d7339cf819a04eb9c354a985ddb04df2450417bd628c104bcef0b01b76fd0fed524cc4183b65b207e82ee6f5f8a7ed55613a944683febc0be3f08f5b77a6422f6fd6310e7ccba0c80cc5a33105a469c3b0c82535b1583f7751887f7de7befbdf7de8b43f05e1004411d74eb3af0b7dfc3c1a7e929dd83fe4c4fd5a75f95803dd5e8329efcaf35b3a5be8ba93f77394b9c1397735e9712536c5c085bc8dd755e21ebdba0d5a3f368ec99c6ce6f839a0905b2d4e9660dba7df4a639afd045b2edcf2812ec3e9a33287885aea64ab6d5b82d66cf30b129242ec7f44483882c2de022ee386931020c637470b3c4135bb28c6e7c30b2a40bd8d618af2a83ea9bb15ed9e1c8718e7acfb03c5b1bb767589e274b44ffb92bbdcbdd577ed1276753294113ce291780f2a8a964a1f3da21f1f60ba6d954d6f8a7f7a251a3aca1cb275dd6f9354371f0f4ddca9b5a3c59e2ae9c820df414fd7297e514782000fd250d0a9ebe6b390502f8f9d329b0fa9e00f494ed6da0ab36780dbec51fb93872df9737367deae54db45fd194fb79937d5cee6837f4254f068da71bbb3a21e0e953abea04c2d3a73d9ef2f80fbecc11e04b5e07d4a763c75f80018ea71f8237d978fa2378933fd497b832d7fbf2e8c697bb09bee451f0a58c92c6d3974f35bebcb1cbd9f5f42d1ec9f72608be821297f4656ef7e51100bedc45f0167c4963974f3936c8aee512cce7c0852e9dcb74de912e9dab46eac843c20b328e3c24dcd9461e124e903d0f099ff290708714089a497c208743c74d6a070e1c3a747993da81c101743c02b403ba147f851e8267e81283a71d8036d6741c40c76f5d20ea727cda016807107580a043d443304d97e2e740a8fd16eda6878c3b7489c1eb0061c76fe9b0e9d281af81f05ba22e673c0d04da6f89a32e6dbfe3b730d0e5ed755cb0b1140e0ca42e90c2e0b72ed8ba647a1c520f48e57e6bc5f818d4fe8287f2e0032de3c11846fbb7a070fc53f640c6d64348280fc0df8a814397323c80ea1500c71b40c3d0655ed265ef6705b0b14bd2a53f8e02e0f8ad9d7f5680d9db2840110e291c5997fa8bf4100c4ae5df0265e8b2084a97bdc72105f55b38b42e617c96faad992e971e949afd16f8bad40ff55b3d5de6c761f431f4103cc1dbf0a0e8b76cf4f49071eb2163efb7b6912e657c911e424ea0cb186fc303a3df2ada7d2fe9f7df10000134ef6f03babc1f1644a1e593561fc95aab572f4146fa4e6b39407004219776857a0e4bff52d71648415a3aaf581085e84eabbb3b35429cbc116aad73da398652ea7846d9a83bc36b67750a868e258ab7a8ac1afe44d140967886a828513258f0872c2d14b2c4514f2cf0831503595a185e7012e582055034214bcc842cf11559e216c8d22e61812cad922448a28e5891255e214a0523169455010244963805af18316a3ae82d0a05b2b4457e51be41108c1654418520b2c47b0ad22918c88228c89187af4f5a0b20d21965a79dbc399dbaada472a758449152f75aadbd170c85a0d93cc2994bdc9ee3ccb49a0edf4c3464d044711c6b4c3a7ccb9833e678bb91a490d0d010112e17611c919191d19010291a191919397d11b620d6a36a416c71756cedbd200886e1c5e08c4669341a9ee59c379fe6ee9627c3ef572a8ae358abd96ed7de6eb7db0d04316d4613997460717cbaf1b6a71b77acd56cb6db8d2485866cf5213a54b3d96cb7db8d244921a1212f7b2ba5b9a19a0e1f8788886a3aea9e73061985ab4de7e1a28a6a46434246a491d1cd6654331a8d44232323239a91d10c1b1985a0d135b2d5c88d8ca811d578ce983f94848b172d2c51b2aea8932ae7514050905f08737a88ed2833bb9868ec7839b1e2112de84382200882f7576bbd59d087f44a1dcbad7d9be7d35a06d447b59d26943b6da65ad3813fabac70cf0af74ed8f36feee1be1efe5956e1a9579a60f77ddd05346bdf5b3dfcb97b903d0c829a84dbbeba0ab6b5a8f9be9d2bb074ddf2309d6a9dbaa43e13ec0555cd66dae51cb4cb4aaf902ec17c5a23e137e9498873d6987302dc48a9069fe28a031f0805b59db50c6ebb56afee4469ecb282b386b370166a1e343d2b6df615a0813370066a1eb43b079784a47f6b18864f6bb565c439dfbeffc5f4de6be55cf05e8cf5fc1986a10def052f08d60bdecba6878b434cfb89c77bdff6b466a3b8d27befbd955200d7469136cbf886b846ab0d75535a754bb3f6be78adb5b7e21c669f33ee83598c5a6a03d330d4d3799603faf652fa38cff9c0d5d6b56efd59eb83f5b19e6158c35ab5b56e2914a2a5355d072d1ee90da0fba3b779f64748ffe2a58edec523fd0b9d1024ed452cfbcb0e9362cea648f60c2b63f355c6cd16272d829c6181a26c510c477ac59b7475d653f95f87401fe3ac75e3d5ba712432c946516ce093f4d4d267f2031f949ef7259941153ff4602dc77cdbdcbcd953ca3afa2f95ff3511fd494c44de83d9e3d5257fa6ac75b487d2e7a79f779fa4a7f2ef7e2ae99598485df696f40fbdd7381873159d8e7e147d2906a844d1476ad3cda4ac9b3f3feba9ada97be47f3dc5fbfc530d7cd25329fdbf94d2ffcf9ed4eef5ff4be9fcff44925e3f554fea7fe9973491fcaf755397f0da83d9db5197fc79cc1e94ffecf13418030de85a0655943729cfde9d3d3197547bfc233e6439e70cbd03bcc9dff6148a4c4aca4f4497f3933e4913790d5597449da9b0f3e8d5e5fc21327bbab6a02dcec6592d4ae845a222289fd5741db4f8170f428b7fa1751404ddbb48fafc3d923ecf24ada39fa4fffff5946ee69752faac896cf5f8df3d91fc5244fe77fa7b5aeba8fe244d648b88265f2ae9f56b4d444927e9599748f126bdd24b2529bd14037f59bca84b4fca4a3a33307f7e0fa54ffa1e0cbcd6e9a6eee03ed18b445fab3d0937a59cf40c642d12113d0ba2cf3a5d07fa935e4abf148b2fc95df4a42e7db378a3a7b97c9df8f475f7e793afb34e4cca3a516bdd7d0692b4d227bd1403fa95f4d4490f55c95cf42cf22c7aa30c8404ba8d9e8415245016796e5df449459fcb24d04d7539070d1a3488cc452fb28b4c7b91d6c4c7d17c7f452ee95ef146b9a4dbe8837893a8e963f18b5e2ca281a45ba41c50cd03ea6af2e98ab9c5a22ffaa29fd5a28a349ef48b9c6181f26c5abb80c7acf1a8fa9ba916e9d0cf6ccb494f1f27853c8668267a320fbd08d6a288b01662f7f8b396018e418306edf1b38ebea694fe0f7d7eaa9e483ecd5977ff9faa9773d2bff8495a775f8b3aebfc49df237fd2df4ffad77a0aaa2eddff9fd2f9f3d09399841376ceb337f3dc4f8eb3e74228ff98e21c6db9b474dfbe968378d3f8a510dfe33b600949f758d3f1c3793e9f4ef129b96dd9ee1add0ef0a6eb446a6dfaf7d6a2fcecfb349753aca4d2e2201c3468d0a03d1faae672ea20536cd3683f031f29cfde519e3da86a4b9c41adcb73925439d709126775f2146c889355eb621481a7204f3244e0c9840b0563132e0e2390f1cfc2bc677f8b9a90f8a775273a8b40dee1aed4e608ec36100fb2db4547c8f0e77d289f39d91ead716002dd54eb08ec36a881d89964acc6065fac632db365f84afc804d5657ad6bcc7b80b36d0e0d86a965de43d91292c4b56cfb475087a4bdfbd5cefde65275af3793cea37abc63d7cac91250c4cc5973a68cb80704397eba18f9f2052805724a145c73beda586922eaf1610d162d4abcf400a60505acb0039a22ba0c12e3e5cf0e708c3c3196e54ad71f10b898294226cc141a58c8a3a4cc0b64bc02bd1004d7123fec48e125858a23d49c411226414483105e53a4941943e3e3833129e80102ca147cbcc2b22a55b869018815decc20848fa933442001458d13236e443c3c981984458531265570e698085450d6f429a3e384cf9ddaa708962c5fdc7889a325830f0ab879120686df9e22b6c22a0e60e54bd70d5e390caa12610054fab8006789227cb0846df40411674b063f37d4c9f26113eb810d16132c28d161f279020621eeb47963e585277c3020832017da28616264cc9d2a7c88a8a14816288c10416acb9c3855b2b6447972ad605dd10153e74b136ed0f0f0618622509081f323e3513ca04b9a15be06a55153254a0c081da88843049a332e48083d67c634a1039434225c912150154db889e2e70f5e61caf1e24211b22850cebcf961aff86800cb22c20b4f28a7499816aa6c65f130c70901ecd4d9c3820f498a3811ed70ddb9b2120316a84e1b1f0b00426b890f331c49d28348968021c0c08183c49f3d604478eac1ca0b3f1b8cb0908377a940e688228e3c21abda814b861b6a88d3658f135044c952c44d951a7c5a7e68a9f3831b28a460a100286462471424659618f3458f94098c61a1e149201bbcd488758e58a28a3842583902cbd69712594a18192285d04e1b167aa0b2e6cb1c1b7c5c20568787346337fc2026d2f9e345258e162680ac94d9f263b380868e117efa042168e67920105712605a646c00e3a2071b94ac90a489234c00f1e2d28587c9113556423c5536301142cb1f414ad0f11143505694316c7e4fd2d82a274062ba3c9982431b2718e0e5c588335581ae84854e54c04b9d19c6ea48298325021422e2f8e0e54f1910e15813577ab89aaca1222bca8f0f5a00e4848e9e3e5cacc43965579e78020927eaf809c2c7971f970c5f557298c18f2827022870081436c56b09d9c573e749561328107185aba6ec89a2458aef6b4b880fa498c3040a5f9e29c8c23de4123994c9c1073a6ba08840b505c31612314a84c911140a0202451c2e4037d0a0c49c212377c28e84b103840f21147bd00c81756507ab89241e280b74e7c8923d7fb0c4385a02a500c5d79f1a8e84bd99008e151d9cc8b3840e1a383ee6a8e0e709b1417e9088e06de61d25b400e9899305cb9738b694421476c2daf019228c8f3ac62b852a48c829224bd716b189b9664a163e408c6df590e4c72e8824588842501b3450de4c3f5b8c7801cf153d657e18a3c6862e4f7e592a884cfcc6f0bc50832fd012187eb81d1d5424414413699470610a0d6e7c88c3842025b4d484bf15543831868d1616d668f181825513587af064c16107186e74526833050a126260f021812ac6ea5011d4c29614ee9511c67cf121d01f1a5e5842c99629b4c480a5099d991c08844d0145133c7461391121871f9e848f3a368ce9b2c267092561ec0e4954b44cd1c2953b7bb47c247da5c07567cb0e2bac808d28b14706416c50f8a1aa888f013c69a342d693185c808291ecacaa9a24f91979822542035881bab6f021628c1b371cac10e648123230f0f9418424b05461c5c393377b6010db8c60266b86372b88f9c923c2708394344cf8bcc004a292f287893150c6ec60e60c903128c01982ce1524e41cb1c49d262ba499e2f526900f0bd88007cbc80f525899c1280ca5500497122a5ac4b411e10a09104a6cc1724510a090ce44c386862969c8a8c061881f5284b08365cdd72f0929d8e703cd0c542ce1a10928bc269b1fe29209f664d09d2f4accc0031d6b0304f864a912e68d1a397dea9d69041b2e5bbeaae8038585352ddae851e1cc97415a3d6c70e7ea852a47ee3861831806585a81ea2cb932041811aa964db584852a8e1054e54543113503d00a0363840b191b347d70c8e2840b3c78f10121a629810c0c75e6d8f19d1944fb1224852a5bbad8c04213416159965439d1a70c192f28ca5c958531d246ccd4d380a4cba8240df664494a2a65cd88000000006315002020100c08454291408ee5a1aaea3d14800e7a944076561ccca328486214a4903184000000300080800cd1104d035360df3f0f5522f4701ad499d7e338bacc7de485eda06454eebd43c7b9adb9a101170bdf5928a61bf4c88b8a7b8a3c30af5e252606235ea510b723799402e8436b05c37020467ecce66bb46caaca0c7384f6998185716b9cb597891f5cad046acad908f48cc0fddd0bc40ecd48f6fd51e344d62b98f1c86fe0be226cd2cb45c12b8ef9e4abd4a6376798da9b768e36d12b4ef6a2918f00c40007f56df3fd743e2a7a7d8baace25df92786251a2fb5cf37573c559355ae21163595bb38cb5f4c0e39d91e551fa8c5a76c3a53e14cec385d5678b79a009dc6d6576dc472978c8850aa753ba565e96076db66bffa3ad66aa127293aef28ea4d4aaae160284fac55723646ed9a1c095d24870ac5e2b96900fe1283874764e50e98817b4be4eefbd92ad392b8e718db34c155dbca1f7d46a64340436d9092addfd75a47905b151283c86868bce3ec62b8c44310e7f8400ed53e0b90b92e5fb6c49700262b8bb8899c43e73c100734a39a52872d3535a85469f7b74f90789276ae99cab8513fd84dd5cbb78e5f2fd29f69ab9106e10347abf9020ab6134f4fdfe3b8b40da6d5e034c0461685746be61f8ea09f7298a7ee7e51c81038682d3ce497054f95dc311e2f4aeffbe52d63865fdf7469bc6ed655e3d657f81b94c922238ae717b7044bd0629391d5b1c05e6c9018b036217a08fd41b2d19c165b59fc9db879c2e4c4fd3f8b0a11a5ffd7b328895893ccd96654ed727dfad3b2e093dcc18e599e44184ca7b71ef921fe8d7906af1a80c5dcd216bcaba22e44ddef4ef16275e31578a837dd6fbae6bc7f2f83b3bf9c066fba45aeb06567e9de506588fcf6ee6c63474ecb7e721eefd44d93312e818efbb8ff171b77091941777993e218bb507289aa55a5054933e2524aeb652d5c9c0d2f4ed0dd43aae7630993ed259dcbdb83f8ac064efb27ff67ab82bf645f0d2d66ce9df954f9d6628bd616b7e7543a938d1a14c3e1580f3c0527fbbdddb5fbcf42a32e891d1d5648b62b512cbb4d768e2010ea64af719ea0d056fa49e237d87792ff9919559dadf53f2b5a825e7a63157bbf740edbe2cc4428001e70e50f987b6132a9f095a30cf8d5ccae26c08a3a5c10932ebf6c1519f348f7888f41ddd484472bb9662a763ce459e93f72d9300fbd68405f18c7b39ab680193040d7f51f6b54f6aa2ae177a67bf4e3d1cc1a9e34c3b5858d907a4bbb99c2b13e14241116e7f55b7c3a54d9a243cbe60bccae84af73a82c21592a14647b80d0c69942488ffb1e0f985a43172f5bb7f592e684e095299de1f0edf29188074a6aa67cba5258fd184669c99ac6e7ea277c5bcc07498a852b0acfed811642bab5284d585130c561060da55a88fcb72356b0e17fffbfd34042238abb247650b9b97e52238330def4204c4f286ccea2f4de2e6c875bb486ee4c0fd19a6d5a1ca0df7c6d75a7ceb216704dcacd781fdf988f4cb7213fbdf776e5e6abd868a06797646c9dc8977291ab78463d3968e241914b631d8fdf3c8155a48403529acadc87593990f9e973f8b4fa4e7990b9653744e276016e7490290e3638cee63e4483c6d4e42dc701db44152834e6174b7de02dae1357beba68fd9b7d61e957a22d1b2e2db20e5c092d4df45af000cee8ace8792fc40d2c6e45dcaacf4c37a4bb3ef3a546c97bbde2da1b4f6b5701aeb7d891d28a6c35e30ab0b1a13e1cbf0168eb2b3a4ad3f3f77d3e0207ea51b373bb2691b7c79f770e2697a1731835bdd8c591928e3ffca2b089bc025553ee3ec5497da979af559041ea96f8b4c6cdfb348555bc742a33d19e6bd16b96ede85a2e0320bbff47359d860c08746eb26a628c21f4ad7f117db70f0cbe19c68b4e695eb1909a4cfb0248148c831663d681f7c82408812f0ae14629322a56be66a9c11171cd220cb764fa2922d69690e752a1be56d87c81c219cfa7b18555cb61b2aa196a9c71d15abd61ce2f90af01ca5a99ba60202bd9caa5d65a36ec440f93d77f7f7b5ba10f8b663a0802627155fd2681bd5ce73d4a200ecd5f4fb9b6b2f948b6a86528cedf7f0560f46fe84f9d3838475fea04f97eb8c2c4a4920b3585a8882eb6066e4d665ecf67c9ae698d8764c55a3933b8b02e2f0d7b20059a0c9ac4b1a92a22fe30dacfab323de5b44c7848d034e642731cc59007bb1bd0ed6d64a564b020af7b9444949f6776b2cbdcb342ef321d12080693a40b97c61948e1a7609798bc93d97295442ed80181de69b2d2f1144ba75075571736dd08714391474efb655955a80eec17ebfdc2b75aaa037277038ae6dbd674d3956378305b278bdb577a5a61f1ea728a912799ff4c80ef7604716fbdab334719d1a79c746c2884972eb08e625dc180160a55213b502cbaba59a693fb28010104fc954090a63f96a26f6bf0d80c026ffda06224b7df62babfb15ac63e44e1cac0edc71628e97c4f7cadfb4f4a3e3b232d487166219e6905dc9ef016fb6886db392a0f4e75f00b4a184aa82c4f06e4f75d0878b303eb61d30ff2be60b6e8627d17d5859fd71581d617f7652651c75fb77417e82cfb9046989a056dfee4930cfb4e92dc9d661f1fddea5b3fa960096202dc77dd71640c7253f7554ac999012f02e82973626fd033845c630f47a15d8df70d18bba481abb6b116ab1186e43f8faae928eaf883533131fc416dfd2561163b408626bc3174dc40a3c30d1472e4bb5f571a3019688f60bf70c21a47da0575dfa1a361073a4fb76c4b6b5073102afb3602661a4c0da9df2e3887e4288d6058985743bb3832e0a927d0575c2ad5be524cb50b645057e55c0e6f2aec1cb11145c64a9bc31097a0e4e32c872c9cfe17413f7addc6f0e5320e64c3fd60d3ba782ab183b33eb4d73d4c11c159c3fc636737a5aee9bd6e65ee6341a609c7eedfa4630491e6e99adf126f67e0a046f85c2e4302e2a323dfed5fcdfa8f5b3bf67d4b3214519853a9f946539e72a3be6ef8dc30962b02a4b62f309a25f13b3075f599f88c6fbd1ce9afe2bc95aa81f65857ee415a3ae460a957d4ed3e0233968f7cd9351cdff98680453e129f1d58d3207fe10ae12b0c9a1707225b231298d90d42526a64e8c38544bafa4130fad0651b7e777c493e6774629ef94e4829adb99190afa79b7b8c11b4fc39828302d7d6040cfe04107624d85d4d220920bcc63e1f1ce32293f7960df2a1962d448082c4f6cff9a610bd45994c95f738f585018a1d540165c7b142916cc4890419081425397ae83b0c70a6e6106e89133d3a117bc5fa06e216c7d9c9c4c1ea833bcb54b0983940a34ce3a6daa560f1e3562a281206cdc22430a42de256d2906bed6c18b2bc2f3bee165af8d45e8150c16fc28aefb5b434507796afbfc4572f65184670c0382c21880bf5711e0c796c0f08d0a6e2dfd0c1defa82270b7bb481bf175412ea196a35b1d082ee01d2f50fd8fe14ecff81c86e25e559b4326e00a5bfb22cf54c72b6fced27ff51a0a059e744de77dc61123ee6009cb1a5ddba6b9fb669b8a2b5de9d8bcbba67b3a55a504e196a98aa3ac12aeefe8d361a0ac5b8a6c0301a36f349b71f2f8939d2a98af3e725507c02c23f40ec0dc030ac3aaca9d088e82dd54762e2a8c5a40134e48d709eed643abc529449309effccd0ad335022005fcdb3d38ec804548e565019797c602c3ae4c60ef4ccc03fcb4ab0a3ebd197e721e27e7a758651542e9f88d4ecbddcbf7ff0a8c67c623d60b11eb459dc4d19d4bb70a9d9c65670d0056e53189cb1c99c6add6aae8f5c07af35e6ab5800f2860ce9d0e2e1b3462527d1370a56dc6da1d1a814cdbd139c72ec43307819458ad494f7535dd35b66627705d3bd6fcf0b5482c7828f0f97b98949668efbc6f339a35646809a187333ecbcf33d8cf6c9d11005cbe0b3cca613b621a5d8d81806daa8940f3d3624b12b744845a4018875368cc3a5971a7e19ba143d8fb16c02ff38b323e1eb6dad5879ae723ae710f4fcd1b7a8a0ac6c5e2e4a2fb378486d27f31c92753f1d50c2c5b4d9536659314807afbe74b4bbd03f115f9542d956b1f9c3e30000abecbc3ebd4331bfff45a804344982af4542249ab76ef130c6dcbbefa3531a3b800b1c9c448fd7e70055428e7e589c732ac9623bd5152d2c74721999a1dc61d72ab3eb4d72b05c853b778395af1766abece4d679be3048b3e24d322b2d39c8281589db0536de5a20ce4a220d020225b0969cc532c90911012c9ec5f2621ba38df861d467dd86d3faefefea7614224f3d01086b77fa11f66a403db7506d4040338b7165b8f03e7d7909d1f82586c025cd6d227d8bf296d80bd178af665e4a134f9257d5a66f2d00c9da1e8f6ae67a4a369848491b8b31c1030dc3c8278a016dc783584e27ec0e6ff51051cc8d469722c8d2df9158d5cfeb5a14741542e3b747569251742454ff453509735d50e35eaf794ccd3c11177b28c605dcf77f86f3a41686bd745f8654842153747d9b4cebc0d28561a37ba316392d84ffeccbc10eb4471a8bd3406f4bfce86935c6f461043112321b7e4e4be1735f9c6be25924528bb8db3a7547d3345f50d86eb7a592043253f838edbed4f257ba2faa1af00f60a4ebd42f7007c2a07174a10dd659f83ffadc0a9855ad709d767f62269524cfb3a3d04ce0617301b82aa98ad2f654074ad32393d90ce5430c1f5483f5fc775d211196b5473b64766b91969be392ee2756ad5b1f095960aacafe8933613623b49a70585cd5c15145292a167889ac2a933b3b489d44897a53a535856c3b91a837c9cf63664570a16e7df54bf2a233d1df88a06fda44379e69d2113c0ba41e5794320b923745b16a606c34846d79408dfc0af5e16580c331b7b74a36c67ae3001e03da91a4587f8bf211b2f0ce5afbc4408869270fc216044a45830140668e7e7f7c9adc288eed77ccdd366fe21d77c334f05d56a25fec3b839af0cb2a3944f7dee9eced49e884355021d162620213603dd9226cf22414bb43a8d7637a4d834654217dcf33958f6187040fd9abad950dab911a7d24207d8081e914b7fa09047bab535f0513a3ea7d6817671a2be74a30e34820bf12a2d42d1b4f31329a4ff0a0023c0a10876d2904080082b44aa057695947365817804ed5a9c40c8de51250ab6aec9851d53df5c61ea075e39ca83d486389516aba0135835e4bd475a73dcc1f747a1baa318fc9ac829fd5791313594ae936bf68e0613e16cd2cd2fc50282ed6d9bf39818a88bf72843e61e7acb11383db2daea7e6be5ebdb01c34a0829080554710de03d3e8a083651225a8cc9410ea539ebc03e58ef7a456515e4dd93484e4add34dc8c551011dcc4b7b4503058231c9d9b049b5f0ac50282e96d8bfa6e8994e936548c8a15e629f01f845e8becb0d891c3363550580bc86922d4c81efe1dd445352360774f9490883ac1cc46d2764ecd8def1d52b0a92f6b077522d1f2924cd6ee48f4db0458fb2476c8427fd554280a98e0908d08e1b640d5119e1233862085de81ea9b9e88ef68dee3abb12389ca5a590339ea2532e2a81bb5227c482d0424b531559aab4162148ad50484cfde6783cf7d0f4acfb25d9c113efb0e6f1ef4ceddd63f8a3d73d277147906846af2cd1fc1ed6069829d34641b6084156152caaae9d9deea4844b78a1507912044374c6d82340525e8d44d27c5b186b2da121011e069829d34f044d8b60505158b65172ddce2b895c27b3562a137d2fa43b3ed2ad557157665d3f3f04eff4697441eea58a89fe191c84e765a2e997088349f6ba145d56b8508a60d85b68423557371fb3f5aef67d45c451e01b5d5860ea64cc8098d3a9a9676ef90fb05f0ed51588a912a0cfabfef2b9c56c1a95dfb4f99013641269bed055546de6a8ed0cd63f031f9e48921840f45bf0951dab2662c59a9d00798664056839b91b3dacb8a6584c0d243820ccff9029e47187ee2fa31f30125d1bf8dd1633df1c2d02ffb4c9379d8a15aa61912522865a15902b76e310ae430b098fd7408bae698d5def41784abf155eda5f9384345c9eb16db8ab3ba757cb357cfcdd6c48dc1347fefae0291959fb2b08439d546c790990203c09723ce9c59042e192f7f1e1677f9b0f8e404712f347a564a942da2bfd21ffc6c85faded49bb220f4bb78836f97a3f0c62e59b29de4a85ad33e8b1758ee27a934db3d42d91328dcb25b062a077010610038934e58711c378c27683df4f6cc81591dd8071dd39c2337e25cdb6d74440085b28273e485b5a9129c8311a6e9ffa0a5e23c1035b536f8f092a70a1533e825ea80fff6318341dcb260cb480813675c38d05ca1ea8fa021402caba10ed2fa10ef4a97dbfccd1c73862119b027084c7803ee40d3873c63887cc949c00adf83a86afdb786a5835fc514446c24eb50b93e4afafd5264227b924bb7eff1fd498a72aaa7822ef648a1aea79098f4cb36d18e71f8166e2a80a64d89767c163918282259c695ae2406f8526ae1ecae7be24826897ae1eb979654f5d13d13db3a40b05c763477594756148abe8476c82314c1a82d7e67c198161ba29e016229d1d4b653aa548f09d3ed6a6ea7a36f422ce9caa1e7acd8b8562b6197b5de48b3626f994109dc18a972fa8d532ef8027ae202e5c856f848fafe2f409fe10cc01abf32094138f01a4bcc829b9248274bb29d99a0f4c848b99d53fac5281977c9003253c0da7d457273e216135752adf22cfcdd151e0762010f925fa24abe685d5b03dc969e21065d45bbfacb6452becaa6c85194483619d6b94926e86f628c3b8b7e684d2e786e1e1fba56fffe61d17fe797ca8310a3e208bb0f6cb97ff0f97a6ea4fd44e366068ca1d7bb406b12dd52aeb91032eaad60265b3589719aa8066617b299a8399c1dc5a18d91f08ac2f7788d42ea9d7cc0115b1f4cb0a76a27b1d3509466444184b918a3b090a898148bc02190c1c46ec0a013f2ff98bedb560aa99b13c8cf4cbef7cd49182a49ad22a3de15089f17154bb4f0b3b4206da00314c7d04990f76acb1abea04efbc8f1ffa09ee78a3694a43d6db9fec409f2f192dabd3894fa3985451599bb201e9dba6aa0e897a4ba9868e0cd6cf56f291c97ae0519620abd494f0cd147a98527cf22ec8039d3b8acad6c82b0b951006e81d8dca4ccb745e3ef6bc62997c483aeb0c12aad430f575c141d84930455c15543acc3bedeca086eac93e1f9539e84ffaf8345fe3b21cfb09137e2c14282b66a3110ca67f743180d6c813aa9dd676f2bf03dcb60cca44e395c7834204936b36ddf2b3be58b3f48d58f2f4d9d9af95efd0a7cbcd45347118ef97f3a0b13216e42641ace7c6bb627ab3df43923425c0453158f4a3f4a84bc1013e6fce725fb70852e42ea8d6943bf2869970a77a4859ea4832f07a65a3042f559ef74cc9904c437db9c3b619134f2b1cd6fd9f948d78dcce471a788812232a11c03d9d18479840042ba3e77c86250d9c10521e72165ceb45e0dc52a61a42613d4378e5e0f1857fce344ef09f4558a204fcaaf673cf81a3ea41a9e06bbaf36e2dbb924dc5e6a7f6831e9a5d473aa1c6dba8b5e9d0c299e7d5421cc7f262edaa94be4a1628173dab827cc15c3b60b097a1857d19f3c858a0dc2029aa7a26aae869e80e7944af11f732742a1a10a3f0875cc5a04ba9e62a577d48ade996694dd5b2b4d2ac6cf10439423e6c938181d712ec337290792ea05ceab300461e7cc11cebc206cebd5036e09994cd6632cbbb82ef994f101996110c3a80b910173cc3f13ad3cbb16a9c2c5e3adc679db04096e38d5cbdc02d34250df77a2bc0d3c24aee66ad84f3c30894f473652e8cd3e8fd02fd7f148e2581357afd89c52a1d6a96bac5a0007a60646c9d8e1f3ed48287ea082e47c3ec2bd8dfbeca935d81de100317105efac6d3015bd1fc57b5b41d78a074725054d31b5596f0f763857d9503dceabb04059468c4c0ecc8c7435a15446272d1c155fa4768312c70aee6fb7b21096b5b5efd6815305b56975d8aa8210ebafe20f9cc8822277a72db4f9ef61a13dd6b2b053d5774aec25c099b36238dcca066d69328250f891c25016c30e42d48a586a9ae63d9051084b3152e7decff1778cedc056a61c8a05f29713b2a10db1c0874c3e1b5f087610c7111f0b26ea2c0e0b8836750971d8110c99135a4519400f86145836a410701f00120e7d8984350a4633332e2af0be24dd1d628742f63dde33e35878da6ddf2d87831489087550670fca4edc2ac159c81045d157594270c9810308748141028344854e520021c39edbdc2408fe9a781224f6a03a5ef61b32a1d8635449ab42280d98266634a72f18ea382b42090d52378e485e6fbe45fcdffb5e1b01d086d7371ce8f6a4e7b1bef48b52f63c0a817acf83d95c38b96e2d800a5737dd1ef6d15a8d427e396ccd31051b8b9d9401d4b79271b80c2da418c110f84fe5ae1e88144c2b07605dea6b88a41e0287ff84ada77c1985842dd881a88ae7b209dafb66038c93811f242af3af505b087c60e0e31ef51ba4ad413d2abc6a570ea20ac0c51a7e6653a41a17e25137e294ef99e5d9959b9c067a70540d21eaf44c86bd5a76a95f47ad05ac338f30faf6d77d2718472046de2402f2df187590b1933781db2156359a3f99a413e19a7ceeeca638e960154d843c50e456d53245972c102dbcd9132bfeff72450cf757a9dda83de1c263353e42f27884519badeac26698b9bdbb95fff3e01230763d6d4b78828a00fc4c2f98ace9b00d22a6bebde88da0ae9c4014005964b8229cbcbaf5a525412f33705f34f0c151796b08b7954b34be07110236d316a9e05e3466c08c5fecde37a6f033a5a7bd5834743de73268b616b0d8bf53175705f6b848a3f09da7760155faf0835c036bcfe9b5ed2bf7f740def0e0191104a1474c18d0471c1fb2dd3df57d593322deed0615162c858e00c804273e0bea6b07a1a71a854972d9f4e71fb2027f844437ed8f0c2bc9188da975b9bf154049b45517610737e269ba6ba058b3c3073d2d8e580e118f3a3cf1f718af07d2683a5bf2fb850813c6e04e7ecb862f2872b61a8ba1af3494a4189043142d86ee08fa16e1d95344037d4dafad4f3492b1a92f8d928ccaf8d192613c8171344ace9b4a30bd18be7a04d714127fe1bed795922e4a808642516b6f0cb77fcd3ffbbbbf48b413075c3996398722fd97f3adf653b7ee042d3e4dff003d64bc31c150d9b710706e46731423b68885140b76e98f61143bd1d4466ac4c381faa5b7cb7dfdd8bc8ec1a81a3247470c3a4a15371fdfc2585db0714166256f094f50638249f7e2dee33ec450ec01db14019f4966596494534a1885e4112be455b54fd209080886e8afba813c187efd4f93f35f687b5a956b413b49b5c6dc8343c8514c1130585969bdf8dd4f12c3b01ac4121c318cb09fd9973adf58a575a6819718ca33bc4bbd040862754b50affde976a05afe0866a2d0e8bdf2d622d3905917ced04213d07e6b008223b9b22028fa550c1c970115ee8ceeb98ecb43ab48695e23bcdab1cc30cfe65ae3fbd3a101532b3eccd53052954907223fee50a4d7b24aa2d461148483f5624ba9ce4d88b601bb411c0cdfbc0b75b9f1b582512727afc03d9cca1ec38346dcfa8077178cca789317dee466e8038e5557685393baaeab7f88f1bdfe41565c38ebbc02861a43e44f3275b4313504b9a6b2969026387d02589a6e09f5a8c434f539d7b174780864978283e72191c686fd175ec41c83b185ae12b1cc4ab0ead5fe2a5fe2f3bf8164df5fed2ade8b065f216cb14576e119c1e29ef61ccbae37a01d78042ca4b7cfa97eab2ab7c040522dde05afd1a8dfeb73ca7cedf18a415121c2436ceea45bd7396d5f72639e7e2269d8094285e203005b654b988ef48e77d9d7401867ec29ba7e8355241abd130c6d6a51536294e7f816a8ffc8430f4ea81c4d01e499506430903868a2ef1fec10cdde11e9083b412c9de8b10c4893f41e131ee379028d7ea013c92a3788b7b5712ec24707242acef4f4c114b7a96d7b2ca9f6f3cc2d672cc0a618851a4b24378a1c414c2a69f13c653b1f8bffea2035b55d607467c9dfad0e561482b012ef667f6802411a3a267873253e94e703439aa017cc355de63657ff3d0f76f9a04fe7c0f4dd3d3a38fc29a38c4dbeaaa072dd92ef86a42e11344a64211090f82d00ef844a857be3f137ea54bc19061d71607f22d007dc8026cf9943f00d531a309d286dec5612c9408d45498f015ed6ffc6a3af23fdec55b2e480c8471344a05555b88d6893e4d98e66ab9e3179c169bf394c6ea0123ce6ceb5db23f58f5fd051ac0787280492af7d705d7cc1b7297919e39260322244caa4b6a4db153195d23244516bad65403967dad029ad26fd043b8a7aeb16730c2a36e52da553c899a62ce514a33b6404ee35e958fa328127ca9e6ef5a073c70ec947b0052b8c01df534192016c9b38ab9f42dd803724de8f7a91a65ece9515306d4c1743acff6dd681088b77ba61f083611cfabcd32de827d81742c462820682700e6cd2f74c0d06e5d309427097a8f224a7fae82ee62db8a22be6eb444e9a01342583fc62b58012e4e75a84c2a65e59daa4761e583c4038d73b48d1654c02f67462ee823e0a52d0320ff39508e1fae8c76773a1bf0e0846952c9edd50cae6e1d18a77b32a278eb736b465f1de033f927c53889bc0c83ece7e8c30e521b903428178a3cd863517beeb88eb045452a6e8c10f8fd2c71856467af4d903fdb13832230e79a772a6ceec4af29ba3128990698342c33583cd8f87accd8c54b9cb565f0b3441a7bd4eb1f49ffc1c13b9a70e18e86ec3e4e759e35d4f0e17928a27a0570c01a1b6909bdcdaccd0c2670d3a3110a81fd418229090ff65a20d5f2770747bae9f0f8520f51cf9155c744460b853c84d669f80ee5317115c3d79717143f21ec271db7c14aa7aa20adc3a911fb63dbd2c3af420a85212cb25cc1401462204b7ade9f81c314cc0d7cea4b1f3ff7a5a6c4477f6ffa49f6d67ced50f210a4ce4d4cd6aba81069ad45f12c93c0c2be51f4af9191b413e18b07d4cf444a060a83d40c71242f2b6973424892a10977ea920b2f95a31818edf39f6cd7efe035e6d739755a2e4dccf07e0d1f2d5323bca38197090c7cb585038fd0585658abd4f097cc0944299b8de83ec00a9fb56a9d189c19195f2e739344cf1110c2c7e4a8d28ec7520ac29faa2512f08b2d3bf3a2a15e463f055825f7fcddd27b4c59cf118637a7fc9f0fdc59dd8b8ef7048f51750c80e80a0ee2f389542d6f51f315c6ad2ac7e59a9f71781878627a01f5dfeddb29cedcc73ecc8f48446e79eeefbeb06061b60aa94133d1851a07a19304d2d8b91908c3efd390dbdae274c4b0e70260b79992bca0b995864ed42039a15270bfd3213c48198fed4fa65110796a4920f4d214034c09a6458790e15031fe94e90ab888d2188a33a200aabeb36030f744a6944e7d1d0ecac2db1ec19dda5125af336a6b5700807e8c31140ff568703ea073155391ec7fb1211697e39ab34cd53d9837f2b521d75a9fd22c348dc8ded7652f6870877ac74571160ad7a705ead71203b661b28cb7800de5ade1be69dc717463daeb8181b655108da7e4e133ba488b40134684260a667ab39c608a50c5f902cc959e1c0c9a2502e53bfcef1429ab2cc59ad1536118c720e61b475f98bfca71aa55dc893c660339f99a7d4d9a16bda53540678ff0b1a2ac603b83d7a63bc3f3c05ab9669e27db6374d288cd98492cb13c9927784b0f4c0cb5cdc322031c5fd0d7ea25f3c93c0e0e04ac94d336011cb2a60c8febb28c00bbd5a6db9f04bca7006460e785e921e2680c829e240e37e9ba4ca6c6dbd57e70aa81d5f1c6bd2ab6c30375f70e55ed615bdb87d5f6b7dfe92292a510ad8e6537d76c238f370b8dd43417a5f53963942d9b61eaf12405f600830cc39491b8e3f322c92d1875e600acc6de502ed060591a60644c08b53e4fbb96927ea0f9099e84e8e83635605244cc6593d0011b1b53a2ad0353956601dc71122533a17e02e8421f0ff6be0800bda0218fc711e2b89166358830a10b41f6a6a3a6d6e71a68333eb3d34fa4700fa538742cb71708638b421c99ddeb4e88b4e840f540e8c9c5f2db4fb5647d37b39f84f32640fbc7199210acf03c1f7019265a7e429ff86644c48a3388c47596fbde5705afa1554b065ca7ffc0cdd0d383d6710c73dda8ace9a7db5843f1b83c91de82f168538d6d01fe7742e68385db28b76d78624e8fe940cda7bc3e84da4b23b23af0fd1f17515036827f0455fd2ca5dc5d91dbcab9fa49dafd6ec4520060ebd95b42a44dfbc6f6d1d83d1f4615fabc208bd5039d2956e96b6cf58d8f2b9e856853b4158b25ba07d0b1d14884ea347a379ce0778517f945880aaee93cc6f27377f06f542b9b420253ec7c7aeb8e8472fbebc7a795baad717be7f1d3c3c48f03ad51d400d6f8d40c13d55987ab261566e686aa749ec534695f11f663ff947b60da2022ce597fc0fb34ec15f3e3918897ff5eccf1f07bac2e362ec7c86aa73cf85944bd1e6ecb20c307eaa1c649f4382c932530b0c4fe8264764312710083d456ff2a47bfd1cc78793840c83037aa3d59c1d0f81cc6d9eccd30ad57a0c0e6d13983798a996a80905a0c8d90a37ce066f73693332a7c8efc200522ef1e015d69360b8494997d333a4f4cad936cfc591a5a3330867692b3e26f8bb810959ba5dced6c3d3ed4b7f5c636ce9c04a84e4f11f929d49d4d4511e5f21969ee445d0e0165a8afd473548612b885dda606ffc7c625e995c3d240e27552f08ac2b15cfce5ef19e512da9b5133e1838c87161e93b24e0522a760a1f8c48ac5a4e4d28853c63d9c26435ab6cf732cf2ffa8c5f5c296c12d0e22a19837c4cf5a1b4be55964fa4bd75c1e6bd46f823b1d7dcb9fdc3004bb589633a5112158b2ce8ec0b74eab43b4f99afe9bce21e88c703046cc0e902abe8940462090e1766ae49dd80a3d5c10592f67b59d3049ef19b4aca9703677ce7cc7538481eba145af590ce15ee1963807c51deb81cf9658f2828f0ac726074ac72be304288d6e0c6a640108383ecee783ca6d41b2233e0850005022e68bac2ab4a4865f2fd9e967689315e403e330169b530c9f1b5a5016e2ad6abda1fd8f3144f5f8bb70c8a10aab62625b930624bff0ed2cb2bcff5ed87b6126d77a7c4762321f65c2a284005149073bf312cc9897567c569f49a555bcc5dbe3bb7c4e222ec34fe623ca6bab2a5f8b2dd85ec3a321b57685e6634814f5173103ffed5982da3ca96abb2598009b37d14b00cd3588bd9aa522746652e93241e31b7484092cf56d8b32cd31fcb56f60c7fd26091175dcba06fe59a0c5c497c6f34ad37eae4c3879bc859504c09f0210c1e1b7f5bb8dc67ff3b9b596b3601f01920b57fe6a4e6de4c10f7aff55358f9f36dcfc4a3f4c070c769366bd02a93498c226bb2c19d5c36317f5cf50c6ebbb0431db02d3c0765e331ddb16636c16428749ce81d0748e56cf2d3933f8ddeccecf1cbd36ce0941d5c948bf7bbb94c9cb6ef0a9ef4ce346af930657bb82708347e47eee4c42370434418b279a80464a2449cf99d725f15975facc1b236218c4641878c75d910976070f13773a5a259470497e848835025954416d5e37b1aa1fa514855818310da5e68a4492a093c7afbb4f792dbf1df293ddf57066a85f80b409ae4a7cce42cf67363bef90eb49d439f82925b83b92a45715c3c75b98a552128c36f7d2da06f077c33d90250c98a0870d17056fe8a5f13b836ca7e5508adf8c8277c6eccb3c0698f071bfeaed4293caea8ab6a5493eda8f32df573b786fcb38a2c102399276336cd832c4b2790922b127dde5d3f1f516945470e27e62e34e7ac04bffe2d2b3cfc22f0df40c2fe939062f5dd3b9d353a529e2837bbadf93d51a5ed13fbd7abffe068bfa30e205b320b53040ba9e64149d40a392610754cd660437ff3b48a29237cd14dc0e944b0090270af7fc8cd4beb764186f2e6e13d0fb9fb73772ba89678010cc8ed65b30ef5de7d4a3e40f2113b4dd9022f0df50cb7ae3b30c96f16266ef381f86ad58b922f6597f2d1a770890b2e81f9793ea185a8a162d0131992fcea24e0710ab467a49dc02aa631e2ea66f7eddb5f2b2a8bc3064d34a5798843f2454e12898400c2c08eb89e0b70bbf65911f75ed06a5a2966d5783a2406c27b13db449f8b64508cab6c0d3264d286897739b101c4ebc90b0e9c42ebe9726cf26d173f2564e414c58bccd4976cb550810c12d9f9736368b2e20e020240fce9b9e0adc77f7479b1f7fd67bfd672fa34c95c75546f19db2b47cae86aba52481b449340a7613fb2a1322f2558590494847e931452093b234608271c462ca31a972b4b6a2c1ce102878246401748d9dfcf86ab65577e4de1c018df6a6ef889b3990486fd6cd1eea6dbd7d4596dc9a8706e615931ee039ceccce7ed5394a1ce33322880130fc6d82d70c54667753a8c3dc03a75bbc7c1830bba73009250cd9f12fb175bf208bccb8d6a43829717a7c26fccdce67dbcd38a707c5be3b3e2ff81c30c342c79174f37afebd8949f561856601aba33afce703db49d086fe5d7d9b2117ecde06e04ea6518d09592f348d23295c631dd8bfc4a3afebfaba3a9bdf441c4a5bab5f8e7d0f2bc43822b7b4d40a0f68785384f5800809ed7042bbdebc18b47ba7dd0709927165897d26e0fffc280496b8989a78fc82a3922827134d0379e34723732132439b069285bbc3225b5c69735d947910238a9be754fe3fb55ec8ee8f1f7ea25de2f63c5c25ff893e64bd03914444d3f2aad3b3b4928811aec53699efbe9e2bae7ed9410341813522d605b0456f618d2bf4ecf185dce1578856ecff3e666d2ff82152dd65747415480fd74b724c522aa5e4eb1f12014a9201f9f284a1fff0ca605737e58d7f3c635bd1374f59533c6481b1c69d4ecd5b751366782f5f6e1b069c51e9c92ccc7972ac708a135555f4bdd9e80a0f0dc828a26cfd1ff7547121364fe626fe00f6efec41a2fd33774ec33eb94b107fa917f86d8db62f833d23fe42cd237a91a4074d9a1645a99709d8ab5dcc69a79da584516d16d283f3ca89b7a53ad56ee410848c460874cb20a7ccd30e5d6492d7da04f8e2c1fbf26aa0506fe7f471c7865b926a0a1be1b0ab038e655f71f179a08ef40998b2df39e6b60cc7d796d6f99ffa92aca33d85feb53d93b5aee22e8c408f2f34890dc352df3297ac88b05c539aeb5b9d4c7702a42d2ba45f551036d9b7c9a863b6893af9d320423aec1c8c974b9f6a38678cbe64b94ad350127773b0fff9225dd27bdf124a38692ee280b7e49d0d6fa646d81c5437f9a95e555770eb3b5117ec72be469180991aff029ab20f2f91de973dbb5ef4e4f69ffb9f75bad01138a8e9fcb0341a35b1edf97087d6ecda132dff5d024993fddaf763375e7d4383600e27be7f618efb7a89fe2211c72833395fe292965febb7a55a22f306a3ef82325c281fe5f271c750c80f4b45d71f7b0bb887b2933103f392c891ec7f53f22baec770b82be68367f6455b2c697356536c7754e74d873cd0013856c7e08f81912f50cbe49cf0a0a108d2d94dfac76405253dc07b632a32a953da5275f46faec723a770a9c7c87dcbfffe87fda95afbc92439536b57cfb2ab16cb71bf85ca13d5a96823081373989923be6515ef4f047ae78cd37fb49f366f16446f793cf066639c1f205d565287f64936d70ec5587809e96f8ed83011ba5658ce0441e560cbcb8060563a973e93925ad6225bfb0b10e2405ae395ef2d16f973c298e891924208c5290a851c82d7c418eef4e5a09df5d8ef2f79477d9c993182f97898cc0a4563db3f8f0c24851426e93808674f098b1ee0da719e38e45d6a57ec9e151bfc4943056bcbf45f05bf1e94ff3f1a72c7a620576a26a742951ccb0eb5525114a2a0e1af4c8b5e32b7f6fc285da2c62213da4a000c250f46bc46928e65334c4bd63afa541f564c7ac72b4c486e1235e714ff418d55f05cc349a30c88217d46cc87777582a49a3c354172411dab32f317a36b4bf15ec8af8e5009f8cf5bffeafeab6629180146c3001eec45aff0d6e07207fdda676713f699fa58560bd0559dfc614820a40749fff886b8c5f049f23b415b33073c131f3f5ed9f875431aa4840604f651c6420077a9c8a67028a071e3b09ca5904b9dd2590b9416860c05f66fd50305c33be05773edfcec2f72f847ba18e2dfb5864a170e916be5e7cf727d8d6e012eb6e72c4a46425a5f5f0e0946a86907890aa7bf188ce0748a508dc2329752e2d3ac6a1d7a28fcb7e41e83746269ede1294585ca2cd20ce4aeb3584e551c4cda332b5516f121c14181aceef9c2aee1ac20711a282f848ff61da4190def1ea872769a7578dc13b92fdee4d1b0225a94563eeb34046d8faf62de039e45216ec7d4a76a67bbd9075ff3efdfbd6f509d3b63ba0d152dca69c04ca21014c448e25a2be2f33c4b9fb1237e57d4687d7554974a1a3961edc607af8588dc960128747cbe7a75778a3c02554b1011d5e0f978c36823a4ab84378b6d29aa96e8b513a04c56d2ed729186cf25b51058399a4451d44c36a8c80efa6421d1614908638f5e1d1d324f97f8c4f0898f83403d821fb9a3c0bf02b9a00764c7c8ebbb1d347471403ab7d5475975e5e2a416e1857621bccfce9877b36862e031245c99b228036b2af0e3815d8bfd048a1e1c1130f146219402d3841efd4e8e0e0f2769da99fa10caccdf3020050f73d8bd03374864daa2a8524257e04016007fc0d79ab03dd3480c06d6226ec46c485a4677f90fc2b197ce238ed4b97efdb1176e99dbb86e84c7d8bb2bc92b822d6326a649861437c665a27d609b91d7cf94384fc177622347e8da54b44ec3cc3ce1eac1216e563c920e786e013e4ba92128336ad1c6fc0468eb580ffdc1c42575a346c103c44b27b8b1e0068164e7b882554d1f4287f3f3e104b7de6b9ac7430ffa3a7f4ac0f068879dc464d402062519bc6207177ca12a386b8d49e52945f680ba93d8355108737383280a1030f806890141d398c6f347c66e08478db52f98c8db96f8ae9a060aefa4a9091ecaddc5b32fbeddec4bcc5e30a8024355eb951fbfe5353357e98902cd458d66f15ebc9f23708987ea1dea707117e9d0c308122ddc533a68ec8ed060e27a351e712f8a8319e03b194723d0b5c9f4fe3263b0648257c017d3ac38a103595772ca55c7a1980646385ff820564a087066a9701acb4f92a1f2ef91d24808dece54ac72099d82c89352b637fa6efb3b2f8f6004c796d6ef6e3286b146533a04be7c3c057f14bd1716cd37d7e96bd5ff2ae6dfaaebd496d3503a7210420a7f0e9e39375cae789ef91623d739a7e3c8c82e1c73c165c556470bc2bd784683580618a4083dbc35d330bbc34732b20c0624ae80593a899dd4305c63a985ce292cc1ea03b69bc226761cc7bdd2833025bbefef9b9e4ba3befeb2648d75f2757287cf6f421f9acd411818e17fba652718d2cfa50eacb2b920438b25880aa9dd5c1bd7bc2b1db7027807ef313f3d74ca897a3f4962d45b07ade0de23ad87d367f11e0f29737ff51e013440de8100f645014939a31b46c7335a41d9e3e7ecab6e59d1f3fc767a9787fdb0a41fdf38f921f6e2805cb9c39ab68714d07effa2a8c265ce69343a9ced22e57dae6a6d36cc0916c74c3a8c8cf88f69f449efb2aeab9414b2fcb5586bea0e873de68a51e96a95b73b9bf549c9b87499855d73b861c8e9915e66913b9f5793c43b119cdfe031f1ce9b9552bb51e3e26b9baf82618adb386436744a3f80039068429635883c6d493f12d23da32fa9826349f1768837cb592f503e5c299229c0158375e04c44ef71548fec1b4568012c7ca6e3419607005cb079f451cd42d11df57fd8d32cc9806b1b98d343774822b0b9266013350fc32454b137a4c27be3a7c5de5cd986f4ed97bddfa2607e861d5f5f77818bc930b470d2d06f55799fbde53fc32afa38f89b7e0cdb1fcb19d72ddb034fda134b85e57479389bb81a136445cbcffbdfa760b552f8b827470d13f8b833287bde84e2933547239f63c34b44a60726ab4709223934ffce97eeca27b8ad2e48ee3648318e91bc9449e3482f80ad2b100dda5be18a8e154f5075e26fc3062a06123b2f667f2f709e2370129cf5c99a68878133fa67916d0d9c825518db75ced399af4763a0175c19ba1220b7bb10918150fc6cc581887ad0f78e3b37951a01bc293af86c1e458969d07087a061e0c0e4a5b07bf3ddefa7ce8ec1b6578b2e584f522b9b268766e4ed097eb75b37f1e67f012457e916d1b3b1b15224b1a4746c1dfda43c83814df20bb65ade9ff3cb37cda03900bcb7d64faa5c87e390f933f0dfd64cd821730202479106923b2f2ebd57baa8542b025edd2076951c38083cafe9e9bfdca1261f56c4820034bc4da5440a93e22a1513536983c3782f2d3c4178eddbb8d5c59b70a1519843a7351cd973e175aa17ee117f9635489b395c5b26119133666d82a4a32c53f271798ecea55eba81e9d876b81b52f2c8a47cd9d1fe7f088eb0c485182b8ba44ab1ce8d37b850e96e6162cabf0d7565dca3f2947f9a0204e853a15107e3b8ad113878c8da5905d42daf3b2be2db9c07bb79d15240594e95a988daf425461949daa0ac78fedc28b9f04a2d8e9412141cb9087e494551ba8c9dcc0b9f0bdf0431feddad7e9eadd457c60a4cd8d6aeeef6f6fafa9c50b3f32805e448d277b99865395a9b8afea114e53acdbb5849ca99b3375677d7916aabd026aaae0e440df5f114962f8ab105b6a2d3964ee85e4965e7270cf35d386db3d02c51b69ae6081386c3c700b33052b5c581d076759f1d250a6917a51976e5a56855cf79f6ac9e640631319dc0399c61127fd47eb4e0be4fa59356fb8268323edfbdc3a11841fb592175cd7f98892c9f8d6e3cd9713ac135514867593843f7bc93bb82638d2fece5d074af1b35ade1e176d16994006d1d42bf0df55ff169099d57d9d52c9819e477e5925f52116c97939ab1af1faaa42b77e4521a740df87ab6a20d5624978aa3c8a6df579a67174146d6166396e71ca971bc1775110dcc0c690b998fd1f5e5dea9b631cd3eb6853a1619559790c06b9c53f6b8b09f7f53a65c9477a12524a4882921b265cd6d25d2700212e134605ab5009870d8aac5a23678bfdae47e31636b8d8582ee1322731619a167f21eaaa951ac0ae22791b8a3bb259d38b3d197be249eb3e06fd36bc2f3146e75075b5e5587e07082ed457d45a30709205f8d52b5b7432ab85d9d47993b546c1911846e33ab3cad2331a2b2d5c88783479d4cc9c2722ea2de9be350673c6760cf8c0334a00cc9a8188acbc152509cab6d8152ca3dc05cbeac31d6183f568f87b47d40aab909eebd031820f4bd206822223f61100c50de2c46e9534345ddd5bb14a6860b7840ac2d8f18a4f001783ac7f7c4db7cfc3182f2a1b4fd083d8428692b0c808c2f349471a19190f52fccce24f93d13446e1af745f3346a61d695f4741e98f4913fbba83d47036dc39b15a8f8ce4b2f20081a8b3836e83447092381355909194cc026aa72501d7cb94ec448993479ac88c1308bf627fe47698db06334613e2db3bf4756a2d0341d9337bbb98550fa2cd428236661bd8ef06ad21c8f16b6ba87dd7b5694d4efb15f6ef091201d15586692b2ea84ad90166a7b4c02b92df270b1d4a203bb391139e981b2e5430dacba359018b85a1517c972e5514d30e9efab297f29a04eb8af1d86d1ebd504d9463799529653a13f7620a99377af4d248dbe2bdcea5cb80116a6af855408eb6463e89f27f124b331428b138f06cc8a30b5b9ea1464cd403433f7eae101d437c395edb3114f0d0a16a93e08f72ad6543ed3b5b6bdabbc59893c16523489ed71b55b08c09f74fbcec227604f6977546d6f8faaa18da7d3481f198174b05c952795c76adc80bdc3424e8cf707b9dc828f4b54664207ef9d972decf16967e979a79476106558b225957d40903f655234ade272afd6b19abae2d366ff98243f2868cef3e1dc3e6a5916804f3c057dcc4e679d6d63bd4d2765fcd301190eb2dc3de0f5da31fed49be2ae35a3100c51d966343e88b3b0c7c638abf1af094b802916558ab6e91d960641957b06d2d4422e7d560f0c6506d6cbf061ec68ec206f9a146796793685c967be1db53df4d5d831675a1d16a27651504091fcfb71a9b80adc75e672eef2e633defe12c715cccc67294e0f00610722719ae635da759f83960a1d8137d8042c4577b5c0cea63cd982a3b07b73986bc6ab04ede19e970b3190b3f04a8d2a5a70e55768a95671adabb4138831232b1f3d9311878819c8d0cb0c8f7f99c18bc808c468c18d87bec9c4c9c40ce47c658e4f842ab491969084b52731f8376924f4b48be239b2676d6966911f21394e0f7cc8d08f6d3566403656d3bf1dc5285d212d23117b75568fbb27ac698962cfdcccb5ea2a9ba279b598d00759e115a870723a5893b5d177ce767182d83c764439ddcf5aa330e4214edeb5ef9ab7d79a88b4c898db1ddb2135f3620953b64c8504f5bb82980a34252222a12adc87d49d2eb16354999ea3605fcd5b01efbcb266253f9646b1f6db5458d83a97607f8a9264a374b6c334faa8d946f27759101e46dfa45c0b8f255dcd16cc2a064c737628e3f3f1b018009263c40c83b3c8efc40d01f5234d51f31a338f698ab0c31b6bca2b6117484fa4c9c4a390b419cd3d192facf7eaa4813d1977704f41bd5b0bb7f707417a5e025f1851dc42ca08b22be2c905b1b0e022799f1f66d305279981faedddf6fff550d855560b06fc1f21c2839ed41952d051354f9ab83904e9ef7b818376a26cb06a36d1308aee40869838460575f58a70f06671b1a69d01f40a64b6884d93f7f359c971c75b0d5c5617cbb47ad4afa554b93055ddd9c47e8bc0e5aacee15aee0102054ac5503bc1da1e4da5ef12322f5c66cc35b88440c2cfa59403228fadf566e815f7d7a2ae45c3eaaef13b21e774f3c0ace009d0a85eb56715cb74d061cac3773d1dd25fb33f3d987bbf252dda64d14156c4a46f3906523ca376e30dcfea6dd8c2560dcb68e226759afb45b20d9a21fadada9ad1eda91c0fcec2e3f0b216192e5ae47fe8ff31a8c1f3e025e7e0fe1bd9ee9ddbe7954c38b2b0bd01c4e880d0e01d3238debe82ea2706f38992913e0d7aba43517aec891f8c24a73414c8d9e1bf22a091b0043e9083b80405a28b644b003a4a7e12ae1d944c3fd6831b825aa85d6bee7ae7f99d857244cc3ce301f651ee71f61e9bfd2b88427c5733fc4695b42240d855c9fab2c842396ec0fd15e9ced8b85b2bff84b3ca4782d7282774e25c5d2f43bab2d6d70f1c1d2b6210d89776a722efe97e6f84125f89c7dbf8974120ef66d615685cd62df6215ebc2fc5ad7621e5d6bf2153697cd54c56adc5e45fa36156ee84b3d770e97f085f55fff9b712503616a411e4b5dba9903301fb2850e5505b354e414146b68ec6dcc2728d8836aca36d98c6df50b542af543359268ed85bfcb7fd50c08a0e4c3d725cd59e3c2dcea3be9c41a35f14cd5f7ec47c46a0ea0b493977eeadbf63959edf75cc332a7ecee656d77bae600c6a71b48613ff7f6a617ad5b08c4b9bbe6da03b36aa9cb20816056cc2fa33d3bd6295fa8ddaf0e2d1fa3a96bf900a3e4cce1be33836f0bc5ea2e3ffbbd29bf2238056948b546f4d683cd2b480a419f4fd800880de87ac69e0b91c6f4e5dc0899c4bb58a3a9f7a7eab4a28a2cae798a988678ade1d233c3055623fca2b11dbcf29e60a275b963e48bb68a477dda827f5b545f4429dafd4f09c4c75a3413e6f9572ef9d7f1ffb6306b84d6320b4e4ba5d02034549e810e65705a78712a15f07acd38feb9110ce97881b49843fbe2ac05f0769daaa6876b4285be5b08b297d730ce06a7058976090b3b12086ed5585a5106b66e9196bf8e82375a197e581d3304a7fd01b6976bb6cc37236a39d9745ba67385b8a89a08b3401333fa5a3c386d491c3c43f1e3fd6f5a31cd66876eadf2ecf249808117e2435a236163d0f2072dc76f65ecd64ef2826b348e8438038c9b023889b151d96725dfe431f793ec11786a0a9845b9279a5c957e747c1de588fcb2cc8adc5871bd7e7b674316745e43837cac7f93bdcf169a47438988d126c0ce5f32618d04e4d53d7cad337b8633df2c9e29a559af3929a438fda89f7c1be45accb8964a0ada5512a1ab87f498086d935be700d0dc8693283d91ab003e42c33750e92942b0ca240a3915e26c7d8af711d48b916095c281ad17f09c5ce078f9927ff1e3251386b02fe2e13641fc542a85df3bbd8b94e1fd91bdccbf256666dc506e6a7118bc674edabfd52bca2705ef42b9cdccd5716be8454ce16ab1eb936fed249f01e17b6935523d73dfd022a873c0cba8f06b1ccf03849453919bd10c025f7dcfe5abf9ce47dda71f76944b83db10c6f86ead0dd92c188fe78704cea3a3d343bb403fd9f5d358960e3421660373d20cbfde28c26239bb15d50c58845c1c0ad73f3232c8ffdbf11f689a24ed8b57b67551047a4c9290deca236a096415217c234f598dd867ebd98fd61206febdc7584ff3085ba2f0ed3fc16564dd7c0f6c8427e1c1486648f727759c3693d8a8e17aee846f1e500958e65d066235029767b43e8f423f2dbe144a39b292f19fbdc348e5df3040ff78dd2c410a03f9d678b3ac16ac19d84b1d5a9ffd873080e5369f858c07133cb3db6ba0efbfca0e3b0ffe05db70aa70537311ca201e6de3bf16bc68bfd8ecc995a72ae8d28a30368d2bb435ebac1f45e31d31d17322bb28b18f9c8af88d2944f78660b00e26f22b186b7f2843fe76762d5c3bbedd1c334285fe1f4e8c5fb687862ac366b0089182b64a16f316eff471af59ee2af56080521f7f0240727c7ad8bb43fd724c8d5c1efeb7e55e209dce43720c2faa428014d07b08dbec6e7e6800b92d0f498a1e23bb815ff77cd3d330591524cd041fc0e268a4e94f706800af7256f2baa60f2fc87999b1774a53885c174ffc2d33553b417ce47294e07072ace858ab547d2b078a3bc789604c775ef89a19adc88f801f38458eb26e8ceb610abed0be0610ba72089f3c8919e30f3149b199a11d4def828f444b603ac4ef5e69b470e0ee8e06a2cfeefc1d593cc1cfbb6c30506c5d2ec96d326c30da84abe4a32eabf660b2b871adc41da4ae70317bda6bcace7d28b4b5105be15e1417557d467c950f874c51d50cccd720935457952e73aafa15e5dd704bf56c9a7fce9c309c57a103e1d031214cd9ef8e1b56956339e8124cc8681cce5ee84c13d561f2c970d719db12747c66c4caa3c7858f7d17d39297dcb1c2f30fa708dc4bd80f4083eea6a6972503dc5433a0bf0b27b2172b7dd4fd368603ee51923fcbe6c6adbabadba04a6bcc1ef0ed085d3eff0d11dcb81dbe322866c58d93c9e0f7f532154437a96a80ab84822e4bcf7c644bc0c5d9a320b9b71f84ae9e9aed41a53115b07503fb9dd37e31c7e02fb0ec10adb5e638ce5403ab0259ab8bd581979f6b8ca684ae7dea09cad901868db54f3b764c6d9e865b9e2cb2f93b75c4c77413a325c158adfb22a8f159625bf6541d07803906c121d7387b3c6dbd67ce4a278e943540838289ce6e69df593a5fb7d2a47c9a853539966423e5f237e1c6b282db3d555b67ac493aae4803c2795657ea1ce0698d9f2143b6e56b9d3f745cea49a9d3c2827faa4c629a3f7fb4784af695a753b7033ceb48a7687054b1ad4af1a076d0d84dc13d21a92488d7e407a44442deb6995d8d5c5eebf9e8a88079810c48e394b34bd4371890bd1036dcafc751d5476df0652ab1565fed8e852331d52ec1eb854bb1625d0c8dcb468a578d157982b45bf0e111a087508a879a1e73422146896b194cd39479dcccb2766968c8314f113c151bd20ed0d6e87a1a1ec492e06424331186664f7670f34abcc91ee0b0230d6fa75bc034247f81024d8c72a7183d930dc539453d9521fb18d1282da1f10cd3f815879e3d310cd33e36114cf3a6ad422fadc3a38463f240f7c7084c609d692fb051c4ca7dbc4460ecedc7fa34dd3773b7618fea51f08237e6f69fbe22180f10035fb4b67938fbfdc094e211b49f5c8381c5417902af069ec7f66001e5a6f71050ef68041eaf0b2ce0e66e3ae5bf9af8279a4069a05fdfbeaf49d0935544af142e1134f2516ea4e231582b5c6bbc7be033c0f6a708a2be9525174700643306c86fcf2092881f3373d059893598fa6dda2e58f887fd7c0fec0e349400aa02c84d8d0fc32c598c461fd0c4fdee6508015d4bfafa52580d3d003fdec126121e1c4411b6756b3ea0ef3d274bdcad48baa2e64c745650b22081f7f8ca597f03a757924cd2a7630210479c809c7b6a001ccfad2f09e2c82dde0d1eacba427a5fd7a908f588db265b0795728026287831dedc81d1d0fa8a628a919cdab9e0c9d41d6ebfbbde77cee514f98ae8aae3ce09a063e3cfccce9585b176765cb5a11bde31ab2975e9dbdc02dd315b9cad54c4d92695dc3434654a0d4e61c7fb8aea717b0b4f151170a1a76c6508be74dd46e1045cfc24a7486d2cfba048ae8baa28aafebe16d7e8605eaf5811473c9f1a2093efa8312fed2d68902d619b8e7fcea13c6d04372246661427a98ea654a173a931f16f69dc9ef6349e85710beb761ffc4d3820d8fea5bbfefa556ddfeb180b6d695f26f07e9f1ab820245f52057a5b4a56e19b36d671635334900d12d37f1db77060352b3a317f9521b3ba46d6f12974279952bf540f7692dddc6359a5f0ea9288cfc412a654a092889d323b951c19238c555e74221724418ca43927b8755a62fa0f4393bf242e9eb438d538440072f8f65c6cba1ad201997d73d5a0495b5a86a4c4d10b010dbb703f2f112707267efc656291a232307321a30cb7b6702d4a9ebc4b2c954ef15ac00d4540de4d8c108e7c5fc1262d58de278e4a581d6d3f971d82f65a00544ffef1341696ba4edc7ee6c4d833272c56870593f22150253ea751f07d517e5290258b19dc8712b1c6ab778ca29fed71207265639f85a034a2e018528f70236a7a5b2a6dc15b1184cacfcbdbfbceff32cc5c6886aa8d474419844f1c93f3ac8f88fc7c8128f133cd6c27f0bcd6dfc321c78438086fd0bca2739d0945213941f2802a48e8bafa3b9325ea796ca5caa7c044e4c729a738ddc850f4da4dfa2031bdafad6243ebd950c0d227f6237ad047cbdce96a7f768a5b29ccfd628cf69fd0545891d7133eaa0a23ef348a99a76971ccd8d94e5cf5160fb27841d357ed318cdde1a84a89d2632927eea4b1e26bda7237f732240374441155e13155ea77437eefe6321acafc5c62b664c5e72739a47aabe70aef15ab564317a6e2280d2b8dac79cceca9bdf10622639e74f34bce785ff4c8edd345ced2e33724000bbd931e2650c59bf48e8543ec44d37dd4ce2074e4198e1dbdf6e4ea59bb696bb94250c847319ae1e11f36bf2a83aec870bee10a5152b666400edb7ce39c456c55c11aef9f4b31642dee0508d2582d275043b68532938f7f94a7e1ac365fe379092ea852e61ba198e307ba71d7f24fea3135966adb11e28b601f7906aa23b14656bff94ac16fd26865d0be09a67a4e1d434d99622f783e0e9853f278fa4ef3750911d92e3b3ba9dd7f86dd94f7d96a1849ebee4c2bbe1fbf174fcf4fb7df8223fde793330eecabc3f66f39feb3260950b51ec0aa19b0c5b1874a01ccd5e2a19f10f10febbb8fd8ca1c09ee69bbaf2e79f04be4802828bc0e64b6b0bd55cf57b12db8b2ae9837be2ea0d5cb3e3aeb80c23cc4e83d396d2914b0851a927fc4e7e2e45dc7dcf2388eda72e31344f20d9be44e3ce7c1614e0dedfd131ba2452d924d1a3d7a0e16892710f29ccf500219ce0981cba52781fae9e450ecac54358c3aca75fc0bb1afa43ad47c638a5ce19da592656b16254f6b74332ad0139b454e6c74c82ed09da304eb3c206320ed41c447d0e26c791e6330aac86e5ba2c86ebbc04527d0d697594c452d262ae8ca873e3105c9766fc15c1fba05a39d35af63c0463727d9e7f231189e6af342293cd06acc92b2c585f10dd842f1c9ce961e1ad7394b72489fa75a3b480476459b5ab42d50349d472d33f0979b1b3cbb016824b0e20c715f90c1525cd43f6d8fe13fbe5da5d3cd7b4daef1b3911246114c7a58f0ad5454f5b102ea1c151fe0324ccbd0fdaf93c91065842cc69c67c44a977f4e82ec2e66c4238cacfe0cd63a62502af2db91919f81fba9dbb15f2ce3ce2878e732e37788f416983c96e86fe1c912627ad9a1088a7ee132e29b1a0abc14c2da7a33d2224216c9bef60c4163618b19f4a99ce8fd700182318f456947ae0043129e5e9870a93b5e88b66697320f54878fb230f176af42bd7c511d22604e3b1b60c7d298bd1783f908590453d241e3300976c162950ec26b1aedd83992f877e9406e5b21dbe3b80f23a83d44f1010c22aa15ca1af1251ba310837d8811b27813ed951e11ee6f8efe11b2581b4a201b83e90a9c5b8b88ba3e007fc2a11da087ccf6ee95d720e5e6fa181eaeb7c90b636217d34cb868aa74203a6451fdfa4f49b345af930f9eaadfffe6e116958adcb977608cc58332aa0138611a18f837646d85a84f0264b158326b37165014cdbb73e0ecbe41d7a4de85d313b291c5f1871aec8480be7914b78d062e4e93431d5ae0830f1eac3ded695eafadf4d1b34d14b56318a36577b853f2d20c5fc6873b243cece275d21988cbdd60ff4ca0b4641688d814b6fdd7f6e8b35f5f492dfaaee36928e3189c71728249ac4264c25d1c628e56877a3fe9cd950cbc0e98460ea8391e26cd2909471a2a0c0dd5d222a1bd1f04c3d0f693382ba2485ac910f4603c18bdfb4a9b3fca1b205073bdb0701b774b11406199793f1381743e0033d62d498a0944085dbca1ab4aaba454abf7d186834631a17653638cd0cd16be84c3c99a34c643af2c071f30a6d0e98aa7dc29bb379ef70de3f18326859a12bd9d1cd0b68773af1b2f482e58d85427935ce30a3ba71a39514ac400a8824d6f15a2cd48d89629a98e5e39632497f4c716102c67281196e6f2753b91f0844263349333517ba569c483954e3a4af7bf7132300e914ba6815d4f9d07d113b72710c79cf8fd673845e10040fed5de6046ed9ba625863e71b2a7388b3b52e1b48026e7198f6382f6d374389e67bda5321ecea975011380f112a4ef0dfbd9dcb9e98c59cb26b8fc18c512a9386671e80f2a7a02776e49251db1d255719849138d9ec21cc2ff152025f32e088439b7032bb39c37a0474bafe18799f4d32b927d112c18eb5ae565f5dc2bb660bbf7232b7d7bacbf79fbb1ba1fcd600a241b61b6c0e00553e2787cac5fbbe1ac8338e14f55290611676169496ab0bd04d9da86fe7c54f265ca4c0eee865ae01077d75f1354e2bb43e1a265caf29a20fd6c8c7e0a706f317a3d8c65ca26e0b83ca0ede45e7a8789c192fc63362de7e76eae54acfcda396f0789401f5885c0a43f751bcb2275c7eaad91757f0815ec04c9db3a2ec5a59b039164f743ffdc46a56ab7d2081ae5a7d78740b6ce2231eebc5ec531f8468c021787d192969a1c893338b5a5c15f1c7d89e14b29ba3523265e228da863a92f27e4a8feefa25a6dfa44fd7627adfd04d3f0a1be452b9cc48143081503e724af47526fcbd610ca2a73de36a926436970b1337210f1cade2e91d385e0b123f91e1f06c5350afdfb402c31449b50c849d424a9e235649f904434d8c0ff5f85a6cba70007cfb8c3d2bfd65066afe8a0114e6b724c8675468aa7f2105dbb925ebbcd5c31b9418904d59714b88e379201b5c19163ff33a3a66983caaa6f3ed65345872f4333dd52e28cf84b303a44299084287330c305673a6726fa9414f419e7daf94cdea20fd057faccbd2c6e38329a43e04c4e17895e0f7a53eabd628cfc93d778d9a252f5d3b808a7fffd04bf0f0aef51d775eb1c4481b93708aeac67e73c9a9db666ce1603fc98bf0bac76a9218b854fef0bf957c8e75c611482adf165232ce1b7d7cdac92b4efb5dbf1ae571424d5e7c7ba8c9a343405dec67322e44e52519cbba69b21a6fd361b279fe3c66d1251cb08f91c26eb97b6bd8ab9384edb3062089a91c7d4423a3178ee911284615c375a572ec4cd77e8062fb352472e61016e8f7d48e43fa150f561c4a1f9d9ce015eb3b47b3bb8daa4c97d024bcea9a50804120ab29860c0501e039921addfd8cd949d6cb04dc32a0dc6685d8b92952f5ff6c49524ea32c4e7e7c8a818a906e995549965bbbcf11398b401f1dffcea887bfda5770d0863790550e2c2a9d38b6ab21e363ff93159df21b10187cc149cb65923b507ba2bdaac43ed2d5655d4cce9659888f3018c928cb17c1b5b7893f4fa26f3db479fd0048b8e1aa7a667c057b7cfb85a7ac741a5f37119f3130c95dbdc484a58961b9323a256a8ea39806e514dca792b355bf3567fcacdbd4f86e128246a2c317721853ee932086a3da1e64c469f15a90e9112ba262b9dcc4a171452f84ea9047546d925f1f2a89f8636041fa505b1208f94af2e3abe3f378ceb145883062f82e768d2cd384d5bf7e3bb613304db88aeffd129e4849e36425d14e41f8bdd87a1b4a9372eb46ab103fdadd084e7aac3b788b0c7b6c42a120263dc6081e6dae1f403bd180566e275ccffd99fafb55239765a4c17dbcf86bf776f68492aad77830f3d8978848b757dd58c31df1da38f720d53c657ba21238d18e15462d6c82c11ce75b81d8ac897dbafd921530403ee9c36021ae7759d59bb43ed9d64f064bc0178c9eb9d90423e03681f2f837dd3a9574f76c5ac77c51412627d0dedec3280625c3bd8739b7922d4ec95e63f62e5450c18f78923f30208fa4d50d5d485e7f8c4400417ad1683c58445812ad90d83e077600e1bc587370638caf873ba43c5866beadbe55afc162db30ac5cce76c8dcc9d801153ff86ad436b80f15b158d782219479e863242446e8fa569e6e2b6c9fda9cdc32f46403142841ce116b2428ce29b1f0d8880880b4ae130d0f869d18f93434d24a7b9b6ab8b6c4430c77bea6471ba4fac862e32479cf6d4c8820894f404267228982ec13b3dc1aef5a21fc5a1a8ae621e6b386f3e1c522aea350884eba9faa50a4d8ad32e33a5df009516d1655cec9bfd178fb12c34a2c638ba376e5c4e16eae698cd6829e7da4544233c0cc4356f1fae2e765882a46ae1e35b28c0e4615fe14eb0b6972f950ebb9f2f58642365faeb6f4fb35d985530a8309a08fb6201b0a440a15af6b00d75fa4fc2928334613a94427940b4231afe00c5fc0847c4619a92188b79c943859a64dfccf059ffcfee2559f8e22d535d2f9d979ad83faafa75ed9170f31e35c322f11bf17d397bc449aa8211d2b1291007874602d28829ab92451fc754f45d605c0a7ab5c8881eb88b2f9b171c4ae7791fbd054011417dd3e09997db9004bead72c7f09391dbaff80332e7143e8f8d8cf1773b51044f9b9534cbf10dfd9f59aab09857f36017607bf2467c9c920c71dd60c53fb452cff77ad2ea22f9d8600a4017a0ea2121289e19a49ec01f38c749ceb8ccd148e48a000c976f34462df34021c623550333a6b6403ce40b53c37c1c3fb886e7a307a71f3b15a6080fa8f60f6b566feaaf1e4631086e06f3889313d34ed67a34cea12d53cfed7570418d30889c36e18a4714ce7a9c636beb40cac9257486c093224c26fb2dba328f0a903603ea02cdc46ae16a29a6fad406c81ad17c69765e5b7c218afc862f4a182a8f41ba5cd395fc145ee8c0c852b36c1350485262bfe7601147a082408baef83a8f661587cc6805d781547af5e197e59d58c1c6bb2b32d46208052ea882711b419ab02ebc485d987952d839b0c23098ba1a9bfdf07df8c476a4a15811c81506f79e07393ffa25ab074a892a920eb1b1b378661577f4ad84c10e386df8b90105f493925819e6782da71d8b12c31380368cf293bdebed6c03eb401a240946b1121c018d4000da8ce39708e73f629ca422cddefab5a2c46a71ad1a0d382d832212673c8738c191c1b04cbe925909ebaf7782e6c2bb926311cf6707e0d0fae6c7a8ae950a0d59d76d8095e9f47c70645738c1118408110ec9aea086d673502b7fbd0acf8c30f00a1a18a170acdada314e83e156d2e66147cf7a696614a67e31be00f89f000ff67e9fa0dad44a31745c9cd3f21f56a77cb602eb7fa1c2d8777cd6f565601923e098ca852c5eb41a9cdf2c52d293dbe0b9c20e3a3296e6d15a366252d354072b5a1e9b0a1cd91a7d27a87af14e57e23b9f153a879735aacaf4afc69ccff1d818ef2b28f6f411863754e2099df2dc3e31479458a664a948c1f9afd202ff640a332beafdc2b8f76cbf907b6831cf555854c0742adbcc5735148fee72cc64db2f962699ab65b04f2539e726cdeaeabf0a89450c8a96ceb908ab1d2afbbed0be94050d82e282e0eee85403bb32443d85bf1246df604af826febb9ab0bb2f2c67f6712bd269bad77be8322594f59d6c7f7e825ce21b7ef5523bbfd6045f1cb97f33b4d6334956d8570dc7a5791eda292950c914fad0906bb9da480a7f99b37b9846ba6e09ad001eed8870a8d996322c058b1edde2580bda085ec371cd0851384eaabc819247406862987aa34247434c10df075489178b3e2a3607c1edf5a91fcaae9c446b6f615517704decde29259f09eb76b4a655478abc2445a76b8d3f27852e5ba1474e4a8805bc2426d5d62540fa54e03b1a7f42fb481adda52b3ae4ee70af7d18f6fe176d064114485ace3bd3c572a5d2d5f13e7294497390f7f6a876844138ef21e1a81a7bb8ac329c47ae5a7dfa49593a7c5f496a8592414e2e3c6a6623325374c701a9e6d2ed9ae04ece59880910b84e330a3674070d8b1417344a51237b865039e1ab4dedc13179e487fa476af856cdc0348c16c2ba1bd11e6639d480cf1bf456a4ee4ed2bae0f2bc5ac491517a06fba40ee8d501309d668b12c18209fe7d920c884f7bbf8e5214b967bdc183035b0a85d3ac044281bc85adbc263990666b82956dae078d276879ec6c96a2710a3c6fe25d23d23d8e63396445f0ab37f0377ec9b1a79cbe6e96ef8a99db3fc7f0a3954dbf69cf79dc9bb0b9087119342b0356edd04ac97b01af9d11055549d75d8cb11b3cf8851be573344ef676d24fe805c25e66a1160f808528e19490990e1991bdf1641cdf72234176a4d879e23b75d3d456bb9132e7dc5f09622c0c358adce7c04ce90d2f48963a9290d980ccd05e86c169ac2af091889a6149f2becfbb1d33ac5d99c78c7e702e2402f8bd2662314337e1d0940583baf5510a376e884957365d3e415e6f9556346e1f0224c3d30840d61051cbce2aae1de8b987c6e918222697a6dc9795b5d344c9203aaf1872dfb263aa9c40f26f19a3a3fbe325943a8cf006d4664d60f08f90d007cfedc3770620263a96d5f0c084c8102a728ae77b5a22b7b59e574e0b2a65a01921d491ae334c84962874f0c77f0ba2145db7a6a92757ed271e3c2cb1001f1eab0bb9bb0283daa616a407145bcd60958aa395d65fe54e41459e8f283bbee217dd10706011b4e08212d284a093a4cfea975036c27bf648b0844938aaa0110b8367bc6dc60ff1fb8693eeede426f15c70109e1975c81b4c32e471d7e48be36cc17bf54d9eb59c86932861c2885132eb4beae3e1cae086e805c71365ab446f6ab12d57fb07384815af8b7cff51e0056e492c2349fd229852a7c58c229d3a00b8f7145b0ffc5a93b2acc1be91d8941c2d4029a093e014b020f3f953355935fdef76fc1cc0c9dd56b3380df5fb56b3f3a8dec5ec14b91a5a771da8329a81184fb0c3357e522bdf46052b6e4f01a9fc032930b5ac01b77702b5003719e2ccea851c7b705e6d0b03f75a85fd6b340928e4403640b259e7259308f364c53acc70bd8b43895e46f5cb7e331ce5e85bb2c5470d8b388f2f61cb40169567e540b9c9e934e21ab5c9ad201738fbdf0ced0068e57a152555736c9af2201d9957683fdef1e81132ab60bff2bec82cd09e20518bb1690c100e135f7c39657ee4971c6da58cb92c94f640ef30c6a3c6e5435c1ae87214804425da7a58c244fa1881cc396079d260ffb909f222a0119c62842b5027132547f1c3c4774f17d83abf3c3e0b69ee1c944d4f56f024ee502701e13f6357295ce2a4452d9d5483aa0cde59f219acfb778f98679beba3c24ac1de4d661932abc8c7dff298c8e55c792378f386c4e88cdc320ce46b017ab276a7a5f38035207a95f76ee24ef0d2ce9b7cdb9312b8c8f3bbd2bc5c1c1d218a609a955a577d121456b6b5320f5c4c14d981b1d2800c6ffdf57b6935f8e0d74ac06612a21179e72726ba2f666ed72bd021cc06049ae13a8f59309c19a5038d6e1e413493ca32049671ab75b5f648a9e5e3254b8134885ac295e5a3472f731f8cae3ede2fc2e3f23e065213f4bb9cfe48715ec560fabfed52b0a795a9927ca9e0b711382c89254492bde5de5b6eb9a54c4906b30806092e09230a50b982341e5d2030f4eeccdfb15ef6cdaf48ce9b614636573c5a1982fbe691086ae3baf25de9e6894bffbc745b48948442fdd5352c44a7254b48774e13be7eb837e57a1ca7353a0d6a83f37a8bcebeac9f1306671ef30281c17d77ac9751b3ecf59a6f2d33053bed2bc43bf7970ed4ecb56f20a741f9cc4c9d3ebbb07c36b5f84c71ee1fec8f23fa1257dd28d5e45dbf0c832d59722d0971152d90d50a47b8ddbc6a9b53b8356ed41bf6549183f1b73b5f4ca436bf0cbc43276b4fe10848e1022982b0253fb311c88a3a9cc273d953ac83c9e863d82885fbeed0a7b22986b99cc2d9e873d72e7093705fa0272702a49f8004488f81ce21dd219d43fa3cfba9b25fb1efa94a36cbbe8ee87d2f26b3dabfed86f6d9a58fe3d7579b3fcbc08e3dacf9a673f5b6ddbe405278875ed4753102e21d6c5e7ad989ab69651d01bab88cae3fde3abc7d5e61193ed7e08df4b986d31cf120cd0c9f27deb69f410697134b8b476d2397d1e871bc814ab5c5cd28967bba40a67b447dff476f466925121ce2e01037f49a0669cfeb45453e0497c0251e65d69a7594a028411d25a8a3044d3a972c71b104d54b1a67b6888e225d9ec3288691b08a8db0896558876d8fd560580da48140b486d6906a6acda80602ad806aa07fe7da05ca267781808080e66fb791d400c50c45a9813fa70fb9fb90fb90fbd0d08b2cd4de1ec7294c628341f4422015d4ebb50c8170cc146a8640d7b77cbb40b5bc98d3c5bd56c4d9838a8838fb107620162f2101083b141999dc8304ef68bf83bd7ccbde34e6de4b9f278de9bf67ccef3759922dd9d73c176f568689da98fb2c53f338ee63ce5a6fd66ec67e6427a594d2acd26cf4d99c6f569addac3d36b2130772d8dddebfa6b77fbdfdf70cedb77fbd6d4073a2344dd32e0be415799153ab7ddc742636833ddc3ed336d6ee1152e9818055aae490ee43150f41a65ff99703ab5429bde98128bde93e10a45fb938506595ae15f2ffaecb2ba18b5341128e7bebce36d1aca0ea69d4c610d4c6dbe7886f6c8fe375ae8c68d17a4d6b9235e92b64a49b68287c26eb2746fea3cbf668c8498152e00eeb71e066637a0a538d5ef429a549764095ffec24aed25e96f50eef30ec661ecb02f2a0609a28a16c7d89c0e6d5847749bc7b42e70715a786e715b93fca7ad8c3f2f0ce7a222026c5b26c486b739a85c6da28955ac9d4dc448b41789d32501bbbe39830eb288fdb7a007b7be0c5f8d758ad52ddc4715d3e38e012f8d1fab61d4c77bf95c25908695d20a96aa2e94d8911a0001e41b9079a54171860f74092ec0748b030843b955dcc7a8be36e8eb8ab1db57337f76c37a3b49f3e636d3622bdd96b364fecd9c4cdb3c212099e18bb11a37577e29d977e54828888e8fac1ed429d657dca67b20a6ae3ee8e027e9b0e8d17e3df751420bc7e66d37831359e4003fb4f21888388b5918b4f0ba3e709b47bc91f90268381e1b70ac326126f3ae8b07bcb92f74195d0cc30fe07a4e9259ecaff047305d8db8927300c9c5f94be4de4c5f80faa298adcee5a5f56205ad5dcdcd4ac8c9098431f3cb1d6d4695c5cde0b6a22413f3e73c516c24e1ba8fd1f853a493f8ff2e3513c8a47f128904813717f077279d8cfc3fb77dc1aec6f59d00708ea5025470dce382e901adc7727c66f5ad3176ef2bacb106aee24409dc47bce5a5128e8ff3aefda6a2ab01fc9fa6bc54247784ab2cccd232ad9e7aaa7e4eac9dc7970832f2d628d62cd843517ac7d4e913ec36019acd5682418ec5fad8b8962bf913d997b0bba4fa5bad883796361852ffa796e19066717b31ceab9ca557ef3051d092782a647ad5e780da7f981d3625f581716651f5495be8569d2cf3e40eb11f29a6ee9926e16f5e69a1fdb90bca32d0a763b0bcfc2bb28511cc84f4343d71dc281940aad4c6a1d651dceb28c0877707433eab99bbfdb6eee70ee1cc9aaa606a3501955eb35b3b88e8039d6cdbfcddb4ce4a0e60ebb3b1054790c156a762418f59e27cb09755bccc972ddffbd8b5cda11faacf88604cdb508dfa123614e254aa0c8bebf330cfe934a66431b73bcb75d126b9f82163ff3f44081ad8f32462bb447a3426df47850fef1336a7ebcd33d02daf419f8f0c11d5a724058a50aee9b1b479c9ec161af815f033fa7068e887ba6a5ffedf09996ce1e3e8562caac0bca3bf874dad7a626f4adf14e56d2a3a97915ea80e1cf7834d155f0e1f30186bf514bfbe5bbc1a92952adbfbe5e37ded8337a704f4ec47198240a6d478863ebe9afbccb974fc32a86fd9015ecf5e46c3daa1836b12cebecb18cc3b039b25232fb22cd0e74654040cfe60576c7eefff277dd6ad5483c3b132bd6c463e54d2b73e575f8427d500a543992a88a714ea0f4a4bfbe579e87e9ae5cebf228dd26dd174140e1389e0416d5831cc83b999faadd07d4527c905c5789075b1f1b3f9b20f31bfb95ec4dda9fe8b36cdf2208f7a8d1bba8ff02fb1776bab017caca162c369e2c34add82edd5c39ab69a49b2f37053145cdf05b82089ac0b2befff56c82e0f8a320117b3641e26fef9f519b2038520ec7cfde7fc3de9f7b3641701c3d9b20efc564128e7f6d16da682dcc5e2fc6622f46dee7a22d2c629c13e359e19dd8305a1c0f6b9acdde7a382bc0c3414c511bf2ac7ac2ace113b497daf96859d7f7e0d1cf2851f3bc9ae51d856bbd48ff208d0fead24bf6e55c364ffc2f8280a2669e1e26f0cacab6fde962e146d7bc2d9713d70f314129b1dc0755190e2465f78d6cb493de67772c4c733a6794a8f2ab10fffe9e454d5dcd92ed1c1ff0661f50f20e2c1f079625fb725a0ec0f2a50782a564fdca6bbd65a63ffd5cb92dd9b37c4f4ebc2d198fd2af7cf62b2bcf72879ceeca0f31c587576229d744581d9b81367d6627f3f420b9aeb703dfad7f3dd8929788fc9a3c9f428c733e8c5a47ab1a50ef6e4e619bdf53f83962cf3cd0f1bbf3c76d5ada745ff103c79be55fd684f3e241e1f733132394f3bafee2e954b0baae9be57bf3e5673d0cebbdea3498f3bae675bd9c89f2bd97f03517665acab7de5f775af3b2fabdd7535018e60c1b65d6e7f7f37a38f0659ef73c03da7b52656a9e0ba9a8ceee9e420d2c6a6051038b1a587cd1c23ee433450899f87e11f08b1052b1f54250987bad2aa9d6880b3512244248643082e486f5f0be1773afafe0c51879312f46de1fa4d0d87150011cdf877a86fb3c1b62580d00bd2717600248e85d94b31143791d095441eab99a5034722e4376560f70fcac113d1be214128dcf060ac908c1f8b82a7e76e1acd74868255805cca0720fed08bf208b285e00a5096b0738be2379f97682a4488848c80892262d48a25bf083c488b685234f4819c3142c037e5288210abe02b3340eea7b52840a76f19048129cdb09154f42b004ca0f49ea7b52840a9cdbc9c3edc4675e92a025d193c0d17da870a0263c6962098eef3fd4d201ce143f31c213d805bf274518c2dad35e687c361307f8f93ccc9966f8d0b321be56a22fd69510490cad86351ae8103e83bd55c57b1f4f3c212f7c224692278e38e2e5e5e58978b14778a0decf4fca8bbdf7df7d1b31bf3cdd7458d6a7febeb5e5e0fedefcf2a7cd87fbd6cba75edeb4dd48fd7d274ad997fbc3bb7bedf36ea508512d6d3a47e61412fae11de792df1542ac217ef4c01ebb0e43a21414443ee4507817df85927ada6e68dc75e103ec82b2a2661f22ca28eeefdf9be56df9a10a35fbd01119cfd91fa6f08368ebc17aebc69761bbd1a673e4c5e0047e7e2691bb1614f7a3cfbcb8fcbd3fa47f94a8f2f3a382ad96f75f2cc48ffbd196a7c3962ff199fca208e183e7b38dc7bbf84314b55f6eeec12fbf62b3e395971609920b8590c86004890f197fef63cf86fb7bbfc7b53e4450e1bbfcdb6e0801af8ff762565e93617f647ccb0e1957c6cb90f1daf3860f3ec9712fc3669bce911554c507420bf54951a5099cdb493b696ee571a08b959607effab6e4900f8d68bcb3f2594863faa5160f6f91221cc77d13f1ae8b700f8309ee769116db8d895ffe5ac78183e37e724f7dc6e5b997e7643cc73d0e6771c4a8712f0eefacd4952eb6a1bcd8ae228aabe2fff0819a5dc84772b6866c26fcc769e2e963d8fc8858ae4d07cb9fe88bbdf04b79c703cb928763097cd13f3f524a29aff53f6d3726c78307f72e2e3f9d46c6bbc8777993d374ef72338f0b76791e5c2c8f0fd4bbe371dcc5decbc3db0927c336145745efe277b6af70557c209aa8d999f8e476b2a38bdcbfb79978d8815cc88837f16ce4cbbfb76128c3f68bcd1b4ed9fc98b878a8c3c5c33b03e5ac63cfc19ba1e1230d4fc36bd7cad764a0554995c127280828e8930822826f7d6f37ae65e589537f6d9e98861897061be35e6fc2810400826a7dcb67f7f1e1c697c0ed467622ec4a641729d2448ac060a2089326a8edc6c4a9d75cd0de6c4c9cfade82f410e36f3c9c6ac2c5e643f44102dfd75ed0de7a883e3e38c67db1e9883e3ef85e8bf2ceba3f44a9d99930e12cc42f3978332f1f5f9b81f68f35c4bb1feb67f0719f1fef6e4cdc83fc18d28ddc265e4cfcd4e3b82371216bd311e3ef0b7d31d6c7b8d6fd610a35bb8f8fffb850ee5fac855f8c8f71fd5a47e25dfc94f5266cc0171bb16b3250d760d018d68db40df15face3af81724a6a11d1bafee35db422f4c8b5e488f87ee37b3305f0cb3dd2bd0bf940554c7d8cfb2f2fed11196fc980d25e18db7a784d7aef8470f1d2fa1e8c6d3af0f6b098f0cee26eee9136a8831e0279c7c30315fe27713be8da9b1befeec3bf5ebebbf1ce7a1e21a8f0531669d371b979d3bfd86b4d8f035336cbe870b7250734654fe2b88fef423e03ef8ef6d90f1e372286f748f7323ebe13e9ae0bb92a7e8c9b67eae5e67add07cbb0d15596cb5b8f39ebf23f28a996ad6f6d8ef82d0c9bbb19ac0cd685fbfa2d4e3a4afccec2674a2f5c5cd49541ddcc4331cbe9de78d791c784e15b9f67d17dd2e74afa587282e35b240be3dde3ecb4f9a9767fa0a2f663972752934b8a48c6716a3c1b9e2178bcf3e731827afd75a56c928b7743bc8f48aade59ffc367fca1bcb8cd117a5e92d68c3ea4377b5b9d478374fc7181dc9dec63ce6ea6d3e6eea893e10c4be970295c2085111cff06108ae3edd11a5201646559281ca872dae2ade7832613a5b5b01d44cabea544fa9ee233d5bb96d2b5e1b894bd2048f1f1f14182e60726290276ffd182c210053bac62488a30086187d8bfb3701a98e35f6a62a6e56952700403d6b4809b28cbb2bf01712624d492ad9c9ee5c4f21338bde9b6643926cb622b54ad602415f52d3e3f281ac9e688495fb23628a9249b87e0ec1b925a90ac8f167f42e50eb7b00f55d985aa6d85b32bbfe363b67af7385e92634720aa62089e5afad216c481ea8f056df7b9f7fb7574fd792749d24992dc217e38c183fbd1cfd11d620158a54a8e13b95f4757a982777880f4e5e93f3281d17377a569413ca9cf39d15f6f1037a85abf6e4b4abfbe7dbf6d6842fdc262dba494524a4d4eb96ddb9c9493736a94529a4d999b0aa6611bc661179661159bd808c3e46318b6dd3cb97bddacab2347e2459cdb681bc9a2e6ca28342bc6fb71a3dfdddd188c8ef4371ba4313542e24764594f1f51dbd150f5cf5e7c6c45adf6960c0eb6e46bd84fdc9ba66197e735d1216740022644b28776ec8290c9f4a98e0242a82b14b8d4984ca81e353d8a8a8ade18607f6e148c0155d3a3a8a6e6c5497b409a9e0c1429513482220abc181f09a1c2cf8d823706ecff845c90fdfb39b59aca8da9949cac92244b72f41390c0e831d039a33ba473462fb1543d954f950afb732a18d8e71c5118ec16945266997c6cdeeb4aebce1999349519ad9926c4d558bb4028ce3f70b6d257d636a368bd7eda205d85e22c24a3d77b3616c62c4ab3cbb95acae245b95197ba5bab0f9fc74da7af76f36c3c3b1ce31cdd8c72e1aea96e2f379d2da81e59791ca7f6bd6efe0ad2c4375f9b9fcdef951b5d6539c9b12cb0a8021be178076acf9a4638de99d34eaa49ab6afd3de7cf39affc86f09f77f0be9ed92e86201cdddd531a98cfdd7dc683621c55a962240949c09a086ea3da13c1ddede63a8af53af698559be7358124604205a189bb8b4658419bc323c8c0ac563299fb12dae8b299f2cc1c81b5cf43b0f6af6770afdd7c9d4650736320263ca7a671ddddddddddffa865c2d3e61eb1b78fb36764afd11660edb6e880587b88b50bc48477fa66531058450ace2e8fd504670790eae8c558ef006ea35af662accf0e982fc67a07602fc6fa67417c5d6b0530a90e26734762ae2c18d49c72f9d876e2965856a952a509b6ecc4aabafaa959c9c800a9914b74a5302b1a4534c630058d1a4c314594a217ad189f18c17add11ca1cd615a20356a942af9085297cf04449118d29532451a483125178f2683ce1e1200184af97717e7eeb7590418dbf23ff82f2afebbaf275fdc4ae9fd7dd87eb667f697515ad7b958ff8417befc57718df7bef3d293487317e775fc1145f8c99c784fd22515aa29696a8b9993cf10414445dc4b2608adc201c631654ae9002a58a185732a92e5e2153f0de7b0fd0e047cbaa7179cbb2de93ed5cbf4cec6030191829715a968c11fb793d283b785c33e5d2e138df4a93d4b23a17c5a8bc36faaec7de7b19b5acb6e9508a3d9bbb47c4102cdb9e7737f3b860ecaf29ffbd37047e3ff0c39ecd30f8ba2c494acd262b42e7e2e55dbcfe8ef58a13de9295ccfb14c947f0ededaf9d5425f5868d9b3b1c5f0c4c61ffb8ddb829ab9d836f036278df8bf177991c2a1cb9963804bf17e3b7c5c67c9f630c2aaacf009ad6f3de8fe743853af12def78c54aa64688246ab1623ab1b460399956e4435507e7c82395582dcb826f59d1fab6cf82b1c3d031bef5b03bc2f8967dd1ddea2678d61034bab9078f7c88e6d5f05d83ea1b004e93f3fdd32afd981e0335a7e67f9c5879224e0535e50a219ce64f31dfef3d0386e5fb2ba4b9f919343e8797c1a5e5858befe7e133a8efefe1332dba096eced2d899d74ef6f1e089d424b1fae9a8fc14d4155856418557e13a5da8392e41d11a77619fa3ecf316f6f9235aa2e629f39615c0dfd805fc0c1bc4af581c74c0267ba4478fd764ec0282e8619fe3609f770260b9d13b79b23494ac44e16473c031f6c6fef033ac026eb0c91e010288d77eb015aae42b0008fb83fda93e00f9c38c8b9eac0d4903274b8015db5578e75f5292c3084eb6e6646956abaea381091a3dd999192d38d901dc5804fc0c7b001a3601cfc3e6f0272b834df6c88e5fb1477c7892b5ec0d3b5ecbc1f278ed050c2fa0369d12dd617d48807d10425ab2ef21e0003bec7baa1b6c1142aa66830ff6e7bd1b2c40019f1c1f4e16871c804e5600256bddc03dcb6b2e361d16140b899eecea8648cdf1646d58a1271b0052152da638d9185215319850733cd193855172c3132cf4640150524285e9072cd686bfb13d3c8c5dfd0ccbc39b6c006ac0963d628037c06b31f6c25ad3182bf1ca0603f4c043001ecb98989898ab636c630d454f565505cb1eb1a1c136393859193634308ae0426fac8e93a561e669665e83d1a23a0660679e15a1cb7ed7c9c6000af2814cb4cfb3898dc4b3a1097a36d0c7e7d938f6d7f1427d0dd2f6f969f2fea92395864dc76a927bf094819e6cea645f686c00603dc76da0d85802d886626b6a56abae83414ff6621c52f0f4642d8d0c6a9e969eecc3e842cdf3d29385e1d2f2c205a98a140b5ee8c9ce50523243498a9eac0cb80096e6351a5b80d7fac662e073660c7ab22e3f3dc507e039fc4d1435471ae8c9b6e0af4564d0937df1828acf40474fd645ce0c54f46451781583936d8159deb24768eef3fb5ce5629fb7d8e72eacab665897e1b94a03003d59161b2ac0d0933d61d4cf7812434fd64414034a00e8c9aeace88dc5f1336c8e932d618da573a72c386c2bf1266ae233f267b8f7d7c942cdf40aa1e69e153d59d2153ec5a9b8cf0e2ca839de404fb6e21dac10003dd9110ef464b99b2832f46437bc03066a9e3394c5d2f031b6fb1babf33056c6cfb035be859de15116c6bbd8976fb1f75f58fb2eec3f8d9d7900d8184fc3e2bc0c36f539581d3ec7de78cb1eb1f1267b64875fb147f0976c3c09efe03e67ad28d47ff7edf3d047bb617f6a721e03ab1c1a9fc3fb80340f894a3f67ad28d47fd7ad563535bce955bf83fdd961c663609573f334afdd6c3aaa1a686c3cf4e01a6a68262adbf8641b77b65b867dcf061aec7b9d0dab63df53d5b0efa976b0efdd90d32bc0f2691cc1f273e81460f935f6bd1b62d8f7e43f1222eecab72e12f849293fb7c0f367d8f770c831b0fc1bfbde0d5906964f63df1b00b6efe1d8f774b0efbdd8f79eb5ef756fdfeb60d8f7e4cf60df93ef49293f57f9588ef571fc641d6b33f464359a1824d41c4f36c32b9f1a7ab2182641b1182000a5613b07db32d8cec2e7c73a90f5243cc8bbcf51c2c49a0d3dd98b85893b7125aef22755e154b8ca1fc650cd71063d59a9ddd093b50850222a2a6d21077a3a424314e3091af474c4e64df608cdafd82304f81b3bc3769392cd6d2202dc860255fe3516a8e6d0dc2e5aa2e689650e1d1ec3dccd13c075c6d27c5b0efe00eccbe17233e92ba2fd01762bb0f78cdd4447f442088a260ca2a107070f820ae91b375e79bfae4dea519b4c3132140a85aa7152184dcbac1521ae24989549869591483ffafa9ab6e954521d7529cd5a18068542416b8bd821d620dd388a8241699462196d4ca335ad8cb0c8d01656b5370fd0582d3aca66b4d7f967efb011c4da9b09028a4a7ff4189d943eefdab10c73edd9641ab7d539ca46a35ab9c69b968d1eb3c1b24d7bffd173a3d1d6f6bd98cc6211b70dcbb24c3a702001132a58315fcfc86ad6b1b36e1bac9f360a89d1df6bc0450c23aad9ba0cf362f1cfe99846ad152dc43385df0866e544352f7464b9cf7edb388ce360de06063fb3f2b1a704c36879e4c2674fa986b38e4b703f7387530387e9bb2fa6e5151e59278bc56a61a12cebe6d1d377816ac1721a3db7fd8872947bf916679956ac9570e2d7c41ab9c5826ce6e3531d2c629187467f77e8289899cf4097719a708c37cb87d2cab2d8d863ec7879503548e1022962d63089d1379e106a2bdb7333dc778d2549a452a954aa1bf7bde96c741bd511c7fddb7464e315fbf2e62a6d587242386312eddbb23288fbe6d7cd88370bb1f69bf673d3a1daa5518d42bad9c6d43efcba4c1bcf37257c6b069e14861ee506228cb4b398c91c168ece65d79226ef762466ef25656f524757e9ab734813f627ca5efadf78077f35af0cc3329865ddcc1e0d2ad594e714c2c16d8513217289154f18d9b1b242c9aa01760a8ff5f1555421c412427f78e89068051121de282741d0e20bdde87f84fa9854a10447dcd67b16c9f4ec235a824f917733fc79c3ef9c96d6f83bf0e767f87fcdc7f1a965af6536cf25d48733cfddd38779e17b29cb09d4fbf0d1c34711155050ddc40fe69c557e5043f054f1a2a070e0c0c15103071344a8d5aa5b996056319ec9e68e65f570a06e6e646e62d4dca45e0c9b655c52162a9572497dca65f2e0c1030f264d9c388949e04704d749813663a05e7cc8bb38e339785df40705ce5e7b528409a62f5f8b346e373aff9066fbfe9aade09cf55dbb19b65dd7bd6043b81159d8575b0f5fbe25038ae9a0e63682bd03f55f33f2330ad7a07040815254d4a4c9922519852184a8eef6c4ac961cf3ad9f77e7ba2b1914401fa7132302c3aecf450494f2861c0a7fc29fb8b21b89133e2a2adc21a51ba1c27ad1e4270cb5817cfa02d58994a0412f5cf15d88d20528d853d0ba7908b65e7e9e00f6da65e75bf60a02f17c400f966fedc8b7aed8f1dfafe7900f53a78939b107da4bf5503d098e5873ea4e65fd7c83a50c9652ba6069c252ca978f159918108a77e65f52429394524acb5a31addc1df8fd905a56da39bfb4c34975c46d10cbb5d64aba4aead55029ed6a14ef3c8cd3ecd0b42418c7a5bc59ce87190a5f432e218d81a030f697d51808c5d8cd42f07577e45f42f0359fb675c121f0a33dc2bf7d5ce53f8442c2044a48890753569a7ec063dce84322755a378e73adb55618ad3c7116d218f51a471d38de96f83df847546a3fa7f11115224aa569c48db6111d8d6ece34402b0ae350a8a6b5ce793d7ccd6990d452f8b244a89c56f967b3f4a2cb9726f70c33a050b5f2344d137195cfdc265e18c9ef0add45f2bb02f668ea4095d89a33a8835e8cff0808f5c16723d7d9075638e2be3b4c43b0a48dadcfb45e9687ab1c370fde3946a1508daa70855d1c1fa13e2860d415daeba1c98da7502e2470f925cd44c96bd24adea33e73272922765dd7c146a2110155b2c70e29b8f3fb3ad376a3714d41859f6b27895852e1581bc197857fe679100a9e1e05cfcf520a9e59cc69fb3d088c2a55a8600861bc421a43c76e1ff607f2b2c03bfd3e831d59f626da9b3579c8e87671a835b1069a825f46a1e644a1fea59cd8cb9b3b4cd33e2b9ff1293d4663882e05c32944409a1d3f86dad811323a1bc60cc4894df91e67736259d57cbafbf65f3dc50fd5b2df2c8e2088b3fa8c5f306b0bcb3df8baaec93befab5e0fe10fee96f75ef1be1763f15c1b98472956b4fe61b2e535aff9bdddb0a86f12c3b07949695119ac489384e1a86572b563d404c26dfe4ffb4f85fd6677b4a5056a03d435bdeb4aaf6b25457bd9c581317b6d07eb01fb88697fcdf9f2bf679c364f6cfea55d91f663dfd9c74d07fba8d538e9bca426659e2d39fe922d39a411fe0fcb8ba93cc26b827db4a62c64088d364f4ad4c62d6b44a9d767546373f6cf2638e52af7d835a2d46b0583ac4c5edfdddd6d9f678581acf00eb6c2d75ccd7fdb0d4c83af65cda2bd75634db2dbbf47638cf671a33a9915053cb1f5a2454466b79962b75aac7fd8a5c5ba261b4c502b76718042cdf17dc7bf2f4b7e4b6fd1e16fbdf5700aba0d20b47cf0c451fe654d4bb3a83564590d4508cb256a63d943706630fbab879e5391e1135c99f800ce328804ce1e028f26fb239e4dfcec623e183e41420397cc0e8506c3a975bcb0e8c5c0bf8107b5fffba38f4585a969d74529a594d28b5ed745b1ed29fdc78d2a690555f44bf4aba53fc281add948237deddae865512e71d2e96284c43b3bb37bb5ca1258ee1e84ad2881ea4e37d6018b9a2b6e97504ac9038330f42030e102185ea8f58c0f93507275c0a276131a40ed512c8b8fbd6988477304f4f166b66fa0ac61f8f4cdf48c36a39d4008e9d393506d4ce911a4794b9f1b68e56e36b08fadd9d85a3b65b7a1683ec5b378b17dd6349fa23d159fa197a679bf46ad53f129768acf74f654a7339fe24ec5a544f1286af6293e85092a3e932111cfc267eafb431f9f19bd37e1ddc39088cf9c6eeef12590c6a73c954ff979739de2171803e6b24f31add86c82a2e2ec5320139b0ff1b31fe2f97833dc67269bace1ece99bd93efbfa66e8678fbd1942da06ff2cfbf96cb4cf324824a46764d9dbe0ae0f7515517e9c802c780258bb0d454b22e836d0bda0c0fe50c8e454071afdcbe614beb85aedc862dbcd17fcd7c5cfe237f6127b4a309dffafc3fe6654760991c2d87784d81a82654751d4ce3b37410821bc3446d760956eaeb7a61f2fce0f0c51a05ea5754eece65a6f46cd9b1fa8c72557343ea455fe3f495811681ba2a8d5bb06837cc2122cf00476819f1460f0897e59ecafbe30ccba2d39e4fbcbf78731c6b8c323af0b44be779ced4978abd168f4a3d103416d197d0f1ec55fad56ab95e556f3c5d799f21aaddce2cc6119305aac56abd56a75d1408bdc4bd4108c614fb27684dd2c4f10638c31c6183d62187c4c30e79b0ff0a5ffbc32edaf0b7b15b3afc36260ec9b01f8fa9eff62b0f7f17206d74f22aa4351cddd65510db3d4f4fdf2750664e5919a5026b7aeeb9252da2cffa585167c6845fbc428c33d1733d02316cda25af445327405c36f21560fd3a311c255f0a7c0c0cf29f8d905ca14c914c914b58c0cf6b97e66600d93cf701c37daa80f3ca249d416ee7b30775df292b2d6ec2dc1972d22ce39e79d39734e795db74547c4f22396f707c9ba350a8fabe0d778d443253e6b7807ff39296e7ee100529f81d76fc648501b438fddc5d79cb68c12a27016a7367f421a1a9f0a53651e7c7d9bb4a63a46780ec1d7f715dd076b1ab4dcdd7e8bbc3e93e0f84238fe122a10841f7e395a6ee71d8c311621e4faf7628c90ff5e4cbcd93f6e3d780fb9c78888df8b6999df326f908b7ad7a2a3b3e07d1172c184e1253f7b36cf667bf9f4d9702f7f7b36a397cf3d9bfaf247cf86f4f2ebb329bd7cd2b35979f9a59e314d589e94a88da5d4b13ed3fcc5584fe18bb1e28bb19e1bc9abb472492f063ef662acf72f91ece8c5c0af96db36abbd18f8d4662f06be66b1f962a62db50df032951a6e4183f3cdc6d60565c90bd15aef177e0c32c2d6d367435fccd5fd8538a3e597457d6addf3e963f7480b8f51952ada4b4b7f06e9761afbc5e9da8d2ec30caa13337e748a9a35472c7d001193d24a41cd650b1c4b18e7162f6dce8861727ba772c6ec61952a92beb4db53c1923ed6f206815536efe718b30fc74d87de386590410d02238c0ea5cd421afbeca5cdb34a1ae76b1be4f7f56dad0c5af8b2b1ca2148e18994299240852734a6d0515a710a293af84cd182272498c28a272808a4c8a8748db694450c159a11000000200043140000200c0a86c422c16038249336397d14000e88a44e76541949a32446510a21840c21040800000000c0c048da000288571df742b7621445137b24b3e80261382691c04475410f524bf395691bd49648b9db2e4557c9633e6151f436eb6dc76645478374880cc1b4016c8f822e7a57fe254410fd296872fd0513632732753e6dd064c353210c850213a8ed25b2097cc60b0d04a5aceadc7108745ec000743940a2490b95574f6aadb3355519abded4df4aa8f957693abc6429c80f4c2c033026fc78090fb285d0d6c07fccb8179c04cb35bb1c1ce0368a06c6b6d57bd75a813a8c2a9aed3a96cae795ea2458bbf0250a2576a307c1f4883c3db847e604f2cc8d5978f6c9d30ede379b00393708d77d11daa5794d7d93b40be9879b3b73b91cad933a57d30a3b6f85be5334f399064bcc6a22a77ac1483809d664e476f79d1c26235cfd89c8e455c12221d11d6652c172ea1e24bab81a6adfda6510e2796c9c6fc04e495b08e824fda29e38a377415c847265f088912a4854e7c76d11fc8f113d9b65e62406ec21b73cc1a11328143b01cc630aaabaa68f9c99ba9f69b040eba9d67d4d0f93c3881fe6a4da8a72779d9dc8abce681f0d9523406ab292d22874d32710434ef06bb351a745e4b2e0488ca56910d20c8f2f6ec381c72c6ccd3e09158e68ed297aee61f21b7b923cd13e157d849ed6ed7a3d582a2cae4917c10a2e7e2a5485ab55c9e6b0dbef5323f5657b4f48c1ea73129cdfddbc646bd4b15028aa907af2f2127d19b975b341a903607eabee9115255692e45f2e2c1170ed9a7b586fb1e4aa530315d6428c191ab235e3fffa9f5811b87a668b5c7e2314872046e2fc1244598cd2a552009072115d937f8a27aa0e7c133724dfaea717fa83b625d28afb94b83331d0f789866ac8de6271922afc88b4c6586638546f1ef0dffd84303e9910956e76982b62e7fa40d802b8a2dfed01c39216b91a3dcffd129b7107fd1edec3003456d752e346931db25edba4b3dfa368b5a4c31dec8c3f552e1c21390445dd347c4669e8644d733432ce215a99fe3d1d9c8847a71f2fe7ef5a23bddd9b91e0f41eb3a465bc4478b270d5636b59eddc22e9da54d430af6e37bb9eeed034e36cdd8185891f61ed6eca3a30b30a8f788173f49765db70ca87fc1d24596a7a6e46e99558720e6f28f5d986d532a841f235cf46134853a87e91c783431ccc96507601e8ae8e89d6c21aec575cf98c99089587e59f69e6b3268264932c95776f9b7f70a645bddd2e6b4c6c6f24fe9acf5412a07d55829ae44d95637e790091da7de1c3e0423963d84ed82997718e637112b803860bba226aa1c5851b3723b65b6f3261c62d062d6cd213379170d116dd1519320383a99b543e9f2cb6c769c2c438ad4c9da6c669728d9ebf302fd0491a014c033341809c626397fd05fc20c97e04314f3cb37fa3e4a56e1921501aa4920ae5f27e3d2a69e35bc0558855d63c1045c3aeb0e63a7ed13224beb0560254b95d1297b649f9162582691d3609196fe3fd6516a83574f3623728ad6a4f0cbd9d53ae263e91ab4b84291cf2ee8b7ddee8f60356d8c1f36468b6f9b43e5a659464bea5a999289863ac39cd80cce03e2057175857eba116e146ba84e4078a02349c4323044a024809de53d8d142d3ac4fcd58c8c0e1810a32a63ddc7ace01da4b1fa102eb044bb370bd0141720034868fa24b971f634b850609e4622079ef98e312a970caeca24f49e5e4c7a0fbaec4d777b5f3f2627339a4a39cf2065145182a0a40c08e7eec98c1c0b9e64a5ff118966e89267772b1dc06679f53d5c91681650edd8fd9e0e4f206e901f88de82bd6aed42077a851afc56359ba47440f588ea7d004826639c2fc47c68854ca2af2698dc36e82ad8a9cc5ec479d2b2143833921e3c8dc488b0792e860216c5724b32c1fc9e52098781d15b19191c400771189f94931c7703ffbe793ec08537c2408a4aa8dbde39b7b864a5a2f81ac8f39c0454f4ce86e157a0d428727c849c242323fc6272d00ed09e060a338549cf98dc997a865841e4781094796af9218926f1009a3749227020ed62e85f6755cfa46dbecf2eb5f89e22a692466c6d3f89c69c5361e54006e34ea9c1f029ced0b953d1fdda777d94d8a0e759f5e706e529e277b5608418136e5a67b4be41c0d1e4e2949e4e5e90e84ccf50296e80e3101247fb40ce48c4d31de576a4bbdeae0e1a658b56802552bb2cac74a0b18f1b6705d727a67bdf596ad6619ac0558425b184106468359c63638e82c4c6dc959d8dfb5cf93eae82a1c1102d1625a7f21c25c2105795f9c00eac98194bf5d0adf859454ace477b5fd3df314643ad253f37ad13d1195ce40eeeceb059a50e8476f87e23b67e18e46813086dfa33b46aad4c9eeb462ac93daf63d6f929dc22f01c4c93706ce4b22775fe31581239d1c661a2e932197f36175b03b2fd86e3fa33690116b0c5ac7c7e0f5a2e869905427e3a0145c0c20bc32cbbf748419ffe01213912e6ba38edaa5a8edb408d614bd902600427ce9505e1009d3cfecbfa648ffcd44c0ae2df5f83ffe4e572a8aaf7575680b8f68e96c5266a67291fb923874bc574cd36a1a7a90bd4329b97cf2638f3eb26f0615a3dc761096b3d82d59e1460587d90ca0a21ca60704966c82b1b1db1d0c4bb18b4f1231e42f26ba9fef781d93f988221bbea620c09be0e24f18b781c33060b900335ac788619261085505f2043b50def7c71f6fcbaaf8803227e65efad97069ae40cc5f375c4652347c25d974b12a603244062bdfe3a5c8619998c44536b152bb57db91419b52244aa2642da0b3a0b3718cb69204ac19be0addef6c54c678a1f7325b6eacb8eef179a85d9613b808e253ec0901fc696c367dab9e26fb0fcbe121182a87f3f6e204b12941bb43c11f48eb9aaf97c752e2ea8679cb9ac245c91d1df512f11e892d9958620a8339a58029d0bb2e03ccd6b3b1574439084df9955c5c16b7e2773062604000940bb169fa2352ba2a442b9e6455d26921c48cea4fd7ff26ebdf0dd983add066cd2da073f0d9bbfdcb381adea7042199476bc6e51b99d4bebc811ea6070993a05a73f50e73111ddf527c2fc137da73237e2c00a58edc5d1f5a89ca21fa10360c1a561a4c8b169e4b3b12ece21a4245276044303b1de9eca008181d76b75b0f8d292e0152e34e2378a258db08fa9e57b5b4071b86065f7eade542245a36a81afa2dfc16e60e8d11b1e01ff04c3bc21d46c46d48994ef6270e7e49d0b0cbc0d2b40021efc5c86eafc02a445783d35aa94a2abc40aa77addc99a28cdfcc8dfdb0c2abfbd9598d7f70e0790e90087b422917d10da45d510f306e378693ca5603512d76aec8514e9c1386e3e544d4327b52e2228cc848f89d142db3ff21d859100d764e8e5dff15873d0ab1d6af630b8969200c454c96f12f7ff887a17a0c1cf65ca0d3fccbf9538cb125bfe9ea44cdb1e113f48a6abd98a26b73233c9e65c6dd67ca4029adb9293f762954865e4de2cf11a5db57ca36e66b20ea6b99e8fab4c79f231a28e3d926f74993fec84d1d475cb3b21167f9f2062c9dc046650ada5405e109157a9dc89f965db67e3070b2c6519206372e034f1635b8d1aabd66555804ae7a786d2678dfd664ed380ca00380686362568f0fb77e6869313d96701cbbcf5d01baee7f389d5813c10f1c36389b80eec69da59b79b49c5c6f9af2804a8248bb81a9acdeac0b488553bd7a700465176cae0478ab8e19449ea14f0ffba1e76312ab12237884035103fb7dc0c72566d1cfc72e4fbc71c425242f0d20a51235eee9fb07420762f148309732a56909d5ec9a8f01aa5b557719357f86d506c4b83eea07eedbc666fa66a3b63ca4a445683f511d87d455e36712742219792de0437c86a12581c093915987f0e79259e27785167117a9cd0e13d9dd0a94c7c4f483c8601a0b01ce227fc5aa97493601591b0a340154b6364e12ab263dc0543cc1f473559599cc820937391bfa98119e8c0dfbdd03a559464fb6a1ebf0cbd544d4b271c58b01aee81893908a0ea194476f9753a1755cc1ab80aa6a4f940a25e53df205ef27ca663432fa4e14997618326a10fdf82a4c2d8344319e0a32c5b73cdf6e7e7e83715d43c94256b414c56dc1877271b32e4d6f97787a5f3fac82157e1c587a8b685a74692da03f53a6ae42174c1b9508c0b2fb73fe865ac421633f14765b410204eb78c225b988d076fe43dd35294289210870782a12253313a143838f7640a72268699b63b0aee5e816f7ead6c1dbfa5c02f98683142b4fb681bbf0aed686280b6575251b26086320857b0cc9632090a4a04a447b9b3e8b0a3f7814dfe4a086251b84ab955d8f2c43fd9a70fa06613facefa0f0ea8be8b5c1d086e848f80ae67beea86998ae34e1559c669fc5bda5fcf43d8651373e16868b7922386e90fd800889ab5d468f043652e9337e31f0981cf7d3e52590822e4b32fa710c691641bb97f439fc4bbb815640fcf0054cd7e60909de63d01835795f31fc2a7fbd8f5a4c3557084097aa4fbd273d57a21e5b5fd03517686d4a01e314cbd1dcce246c8ab86c5abc94dc8d0e3286f8b29a295c823e7a58fa70b2991e37ec535a138ebcd7b3b9df99ce264aefd25e0040d9afeaefffca59d4e1a9904a9fc6b64a8c90711242d0ea1e3a3a4898e5bacdfeea17078544ad8ae287aadcffe0403dfc1045020c1dc92f37e43158bacd6138eefb6341fbd92cf40df462d61f2cbb469b313b814176c1a34faa421c719ea808d407a1bf1399dd72a2d5b7e2f74143b1cd4128dc67fef887626f069a04e7e7e9832bd567a0cb94245bbcba5634e5cf2dc0930b099b888cfcaaa2881989bddd435f58f0ffa266c75570dfd23300aead8eb45ea01254396091d0c7e781312d84589abb298396e33d8f6928c6e0371dde12865f3889239eb6eb7da35be9cb3bdb036571b2477369f7003578e129d6077e8fdd82192f4ec3893aee40d122f811a0a99a9067e4065f76454a7d6fec37ae3e6342fa9d62c68cc1865d77f0186d3d27a2bdd57b26feea7173e264752c4c7fa265f783d111e95cca1cc6fdba79023f51af732c218ab2141613196d592d48bd81d8975b0ac0a382da22740651fd8bc969af634d7cbaa6ebf20f564047feaefd16c2f61af209aa7e41c66290985d7af6dee3bf06e999d31499dfb5abc34cad048342d27cd90c932361957f7ac371fb03c21fe1a279721b7f4b4f36615ffb7170df145b6d3f481133d3085c8f16a824bd6fc06939a9651940ccf186727d587f90ff6825a8469ac812c28b4aba1cd1da8b372154a11094ca228cb637d24e701af777f4800680e7cbe36f0a2cf54209f7d08e0b57c02227dab8c67013d0b4a4e9892e9e055e76e3929d65953b942ef91812a6f155a8e1c8a9fe198f8affc8901b64a6fb3a7c11bbde7969726d3c15d17c81d2b2186f8292fb93f6fe6e3e5e58d3e6332fea994e22585add86938d854fd8a731a7d74da20717b8b2435a492235bf66877eb03cf0fa23e120a43854a1c43d3d35496c11689b8ba97e8624fb441b74df56a0094578a582f33c599ac279290883a647fd2f89838303095fc4f3fdb9cf51c6175bbff186107efa04f14ecaf47bb4a9822123dde96807481ab98d7540c8debaf4b8aaa0b9e8ba680bfac6b38f0c17ad393944e737d99047c4c7d530389c2691201ebcb730c1309e462a741715fe800d1e35b8e0cc6dbd55d43f38f80e3f82e6f0b0ba8c2ce7ccdc8897a2c497dd3471c7fffac23df8a4f6690c7ef2d23df742ee81d9a3f00e36e9d78c64f358a84a69392c55151b8dc4cbdb9d3b72c80ae1ac157d9dfcb24b5880d4f3eada4cab6ae5fe9a4162fd3f0d0196fa423556c27d140aca265e07ca746d9ef2c840f0f832adb2e83e27f34265d90f438836dace0a2d485786c8f7b95b3494a6fa2ae56c9a1b1835b71018d22c004044fab31eaa3fc2bf313f3ffa8909b73a862732abc52fecd4fa086005061c071e80e97917def80a9b1b7fc08a0b3747668800a52966a28d437e22d3a22495eab15627bd1d892ceb349b8624212533cb043b40d04e80570708ade848786e888f3dd1331932ffa474054dad9d8462b7954d5a9c92f71e548973148821f73f55adbfca07d5029f3d26851d96c531f342429eb69a6ca3d95ff8c19a60c4d48e1d1c41d31f2c4cc154793414a9d25e64deba08d698ec0eb669203145a9996ce314d817eb125ec14acbbfd43bb0c165f8228898347a8dfedb6d8c6f0896d97f60c95a358898f16347fc53d2878c328b4e0808ad96450ff9b3e9ef872ba0c9e4281e801d8c3d5e9828f179b0a226ea8a15bfeaef40ef2d7502941eeec9f77dd9f767d9b57faef81274f38b70c74659e329bf355302f86f17fae90a2f76626473ee841b39163064bb8e0d70fa8c568e89a6962b2a0a9946dded5e98f182e648065120f64b3fdf996fcf14e207e905118fcc9f452fed26a2eeadf0c0ce4845d7677f1c09a798cb6e54fae517227680a11c86ae4b3cd62895f227d21c3b65c1e47858882544ece8b8861e85b7ee708f0ad5f854f1dd039fdd0c1f05c3d337515001e0f90faa52b5aa18e81e5bbd403ce30fdfc480a659353e2c04a3bc67c31d7066ffa9dffaa5231c72f6382f18478a8102e213e64df2ff54e342b6dc8c4badc6e58e3d85ee195112edebd9be4e3774bb2e8bd8ce73e55bb1ce72d46aaf168c60140e10574c043d5cfd235946a0180640737b3b03b0f76668871eaa7eca75a680aec696afe44521e6e6ab05884ef006b50a7b51d36b258f8cfe9acc42a0d8c825f35eec13e5a86831071ee1e3f93c6f2859a392ef6b8c6434a7f28e42ee5828f30abde08c4d88ccfa1328e89ce2481d11d44936b0e8e48a5210ae5e061f4b685923c7315265adeea0b6988c8d584198ae443553f914785ddf60d940f993ffb270df89b733d6cbcd62d72458a6a642654e4d00f45b997b0755797ab6dcbee1bac6f92b026f02a3a194f9d28503365d2aeee48852b430b3266254d823b3b28533322afa3d41960614188f0d128b833c19d065c89ceef70c1d2ce6245de17a09031db89c2497f8c35a0d36523033767bfbd33caba6c2c1b7b9128fc0945bea646674b2b889d4840dcd4969ab34facc3625464e47e2be225cd18e2219a7e066490658ba685f4ed54ab2b4292a49f57ab770124f73a73d0c742828f17f3db23271a6891d8622b151e01f15351318f783d27b869c7baec8c1e70a6b3f6e61a38ed5154e316912ec1393f6b3d99e160c2d419ddfe81ff45d2c7cd441e6d07c51907a0eb3f12fef441309a657539919b1709a455127a8511f7b3901ad39b9824ef19181c82692646b3572f3f752a8c64f196c99b8be4b10af119e33db77b6ccc1eb72fe769306923ec04c98b669c238be4d454a4a4f74c04fa83e5158b8b23ec7d0c22873463aab9a26b1db770e1297c1cc05cc13012afd7e92c07821346d08d183ed09f67469fa71b1b653caa14d87f558c463a6675ee8bb372edc70e1cb8ac9c5e4ae6a1fbd48bc6473ab941a532f4e76eafd8567b13bab7788dec8619e49c2267d12a4f91562947e2483369cb15ce7258a57d3dd4f9e807e2b17b4124e49d2ba107b0091adefc627e8264ca08917e2b043820153b6c675851596d4d865c362c2dab1434a0aa49f0d2e2c8cd9c9d408c7c80133981e7f06c642aab25097e506bbef782214fd6bc4902cf3f8c0d7aacd5efe45bdc8821227dbb9157f8763728ca68179445644aae6b799c8b908fa36c230cda34fcc00c5a550e6e425553e9ce84a8b955a530a1d1a09d044151bad169e9076534751f0c2641b76ba53939813ca6fe100f4df60fa30f4f24f9da2d58b2405f4a20c8dcc8f8d13e4618925a3d4198acc5800066435c12919d67badc0f556f54431993c86720173ba5d75da6d26e04b7279eb669939b0c5346ff2452e2ab7b553b9a1a89fc4b7fe39512b799a437fc2e2b7e211379f177ccae901e998b1a8c516b6e19a24530147c73172efb6b36567f453af20338985dd4b9c71e04037aedfeac9a480bbc055f5b166e7dd681d8ff72e58b2535a6a3629e58ba973bc6fc5f920dd5122fd4b6a969cff1746956d8d047265791762d50d865856e437c18f7fce949d819764f9cc83f0079d3b50e5af3995b7a750e80236fb0fc7279b5180da8e5054ba16a4bb2a2b3ba4549ebcc7ff5d595226ff31e81a40d6d03deb28ee0e4c3077fb0bea28519d890693c3b2cc0e33fa02b56862fb00b9321d2525d954a8e11a2a4003ac84a2698aeb32008b4278251d8caa4f65929fca5862a3476cef6abd543cfca380ef61573c04f68455ebc69bd9c6160d7372efb2bc0e18a268d92855235dd1b0f27ed6f9b28f36565b3b9ac1b60f2cffa97c3a9986ce6a1777d36933b245b66f968cd2f231889367750c4350232cd5148441239e3ca3125db0a803f8f5eaaf294018e0f137e9bbd3c4cfc211bd6e7d981ed37d2d40bc26ee78b5098d278a0bdd433557d9eba64b13b8ae09b66f11bc4d3b6924b22f779575f719fdff42b5b4498b2a89e1627734e0f9d7d420e4b1e0ab0996dab681daab846b5612387d5a54219778401129001d64c2266add4518d5776c36403610365863e06b8c062c6bde56ac0d90df572eda2abb09c6ceab2cbaef623d5722f7a4a70498f8bffbcbe4b1fa9a5d03ea949b7b787348b09876b1b4dc9afdfd29d82641ca501ce852cf4223c99b4f58c4b155b81eb02d14c0d8cf86cf891b7f03fabf2086b721daf73a00d4409adb6e136977e08addaea86d40b4a7ccb91e18c0254c816789b786c9b6c7d3d5dfdf63a6946e8d0d33d94c1588cd2afb2093a1fa89337a47ad4aa67b09a6c4e157aa84b90662e81dd354cb1bf9b3b447aeb1f41530ede531a1485f39a0eda7c16d71914c36c2dab9c6f4d38bf5c0f7ed73094e688b474cfb1255ec4a2575b34cdfe80cbbe328525f63e09e45c7debf79897da37c94cb56e41c55c02b38028fd1cb71153f4bdd682fdccfd10bd7abb23e413c64be272c24fa019623ead602c22929bd54f58f7e88309d5747ed19df368e22a249756d68d93b656a05e22c4498df95741a1aaa50c9acf0d41b281b61e1a5ea9951e22065b44e353b831a2f6a80ea84d5fa4e7902f3e621c7837649cd0eaf94cf3592ada512599d455133f58cb44e5a3ee67fbc471da1a5b6adb5f0da6d20c3bb317f8ee4f27cbcd67f8a1885db7982b19d5e8348a7cf16b816bc075e4c87fabc7d0fa13376a88ef503ea24a3c185546be46678ce600239f9fcdb901b2adea05e8b49b981995ddccda91bc69b0850020015b16d68816f14d59db9941364cde7b5a5509faee174294ebb350833fc9e8572de0fec4f832f66f116af85bcfb83da65e76120f7bcee2cea65fb2054463202fd463f2e264851d4e8df7eab31b2d1dafa5e66812905b2d7d8465223426f0e07826f4e62d13980f43b8d1034e12f769d73409346f367f2a83ca7a2f84ce86e22f7af67325866cc449e09e405a282ef4ca330f99422a293c23f5364ebeb5ffd8980c08b33abb64051f546e974e97f78eb571c171e1c0d3c6979478047da91235dfd0208fec2c45fa2ca08a2b01369a8fe63b3a4c97d5900d2f91dd43046922567bd729273d92c2e08207d382c4bb6d8281ba71c72ca1167610154ecbb2c08d6abaebe45571afd12d49629c3c2921a9127f1c2f55b6e139f8378e17b64a8aecbc9b4aafc2b5df36a0c2016aac7906cd5dde3945dcd7c943f59bc203923a776d3b07ca0de19d92ec2e735abbf496822350956d14142107a14bcc57b6dea1f9379cae88faa326bdc87e6b53aef8f2c4a7321fe6d0e42d8782a96d282339b59fef2988900f040b33a562384463f7bb765791575fb86aa3b749c05111ddfd5bc7a6896ecc1a8e67b6b8d11f8f2763693ae5d6d0a3560ba12bcc8cee3f805267596a81c987af3dd776522c6066c4cfa50628c37a6189b28ab844d8f3847a0a05158edf91e5ea7094c41030215ae677112c2d0885a2c7effe464cb2a0e6ff2f8a6cefa1366d6ff5bbb31258f8e27a7afa45005ba15a41d78439f2744935c7fd528f77cf2f87aa44e03fdea41d3f0721fd114caa3226853b7c2c74c63a8228b0fde19fa53384c7950dc6502a5905774cbe48b0b359a886e96b20108ff69c817346ca7d944c0b9694a060ac6049dac29497921078a8ddcd021c7621684606edcf0d4290cadbd5707d8ad73d4268946a454fa05e135df2ce28c68186a79d2ef489466185543bc79b84ff898d5eb6b6811d51f7685917703b1ee752146f579a0f5a92ba40304fbf777b21961a4b1531cf0bc1e16115378ef4146632c77207c78c645114fa16d99be834463b7ef1f70747fbd17070bda07370e443d1dc07a3ed0f573206bff01abfd75850f70fdece0b82f35eff4644af871d73880126e6d790cec7b55badf1d5e5d326f2481f820e1b7d0f31895952a729ec1b8b584c5446c35b8baab2dc38f998a01273f2226c8bc3715c8f5c89aede9063735e01ecf092e19282812a301b172601c5ce139224559cd42f0a6627da60e7e6285d35acadc01acff035d3f07b0f63e90eb73806b9f5ea11e096cd615a297473215337acecee5a9ed3f4f858cc135c0788163e1539562d36f7511f1c735c98c1adc7629671ba14b4ddf2042e37bacbe904ebee8352e7f2d1ab0cbe228299c6e3bc65be94f8ae16ef8d683578290dbf54a084172a658241e9e1bd6b13a537eb7e1fe32e61b7022fab70de02173e0de1b243cbb4a8fc1e8679af94a76f8259161ee9b959101567b091e0e051bb275a517c6a1b5af32df53123c239567bd7370747bc14edad086242dff44876117ac578e4b165c7f6ab78c7091049afe4cb399d3499d269b7474d342b351b3c1ac2390fbfddfc5c781a3c2ac86e284c450b178b73f32ad90e5e0f13a0f47fce0120db2fad153c4e7574698a7d6dd4b7bfb4ac3de135c40b37b8e96900d104a7c6b38511177ac13a178e5a24aa2f5d22df05d995059234af60fc196065a262bae2e175144d9e973cb2a20ca0b260aa0d211ab48241eac04dea8e712523bc81cc4a1d77fd339ce1d25eb795a8ab1d4d9b87be9f15c4f0cfda193c58224c9fb8d69f88b7a988ac21d8d65aecb5cd45292d04f5d998dd929c89502330c67a0d57130e7ef29f02223c3a55b783c266b155f0c5c4a94467f42ddfa7e25f3c4498ca3e46b65cb7e57aaeb44553146d3c22b150f9035720e9092d73d7128c94fb625b1f5a0f051b3c0c90e9134fa281f46f5698952e7c65292544449deb73cb1ae87bcdb643a599ce5bf27d32c1467d304c25bccb953379171ee11d342cdd2e4c97574751320a1be1e2ed5fabe18e5ce30e3be0990b691b61f723fd903ad95c93ded7d5ce99ed58140eb7e6fd5117271d2c899fabeb13aa45b6d8e58d2226c03a6ff67ee0a7585b26dcf8c4eb308c912c9e3db393b361cb54e1e65f428578fe3e37984a77ca851cdbedb372258ce237b33097bf0e70f5f05e3ff158cea8f63ee2902af4f0742bc7d6afb585990f06b4302eccc249f168d0c82fe8fde5ba156c1e63489a5d3e2702bbe4879894d28372009764caf6daa29d3d5039d155ef481d7c02c6003c31d45965ddb6a30c1517f6ab52aaf31285622050888c38b42aef66b96e2ddb14fa08b7c33a197a801f4fb6a09c05f32006056bbcfcf58b990d3fa9a780811a4650932117ce35184d00ef2fef480d9cff2cee99b6f8e7e13c8588f6d9a0dfa0a4569c55882f0fb6f1a2f7612766e977ac619fcdcb2f3b0d17cd8d602a6055d4c5c70f3089f3ad59fd1d4fd825238fac323faee142a0d94d19ba535d3bbd17185b99fecf5a9ba8a45049be76198d754ecf66d64f0f8068baa02727075966cbe8c6b2c4e6795e98ce7754eeacdb87710e4774be942808dd2368bdfa5b9e16b0f4c61742226645d400825961099f083fbf98064117c6ea9bb2c4c36906e2357de393d49a648e7e7ea17d639b8d06d94350ee6c8d579e1812784ce7405481ab234c15d824288cf201581f48c1c91f9ea9063ca2d5fd0d51c4864e190df546cba01a207fcd8f608d1e83710abc2818053e8a4969c800f3dc457fdc51cc7d61d1118e6442000c1ef6244d6dadb54de4e8ce589c8b65a380945d873970039373382da6584fa2db4d202a756a464a82a2df2dc62791049f547ea87b982fe4cdaede3ea0a6b10d84e865ac3edbb69cc58f0f8f3be7464583c6eb8e3be0500e9bfea8db387bc98692830b809066b0cd229a155c420d7e6082d5d8f47c84bed4664705250b5caa0a2e3785cb9253a208cafda192bd332a2562f28ff701633c02c960bf671711e9ae17e4d58ba44a405d4b64d969c774f5d1586dfb0e5d114f72c0b0e97aa3dd0eaae5c7fe767a30d83b050298c86c0c61696602c65527ec0f2a229bf02d3c09b8895167fcad6dd18eabafba250af19bdaf8d059355c3701f1b3b19553f7efc8eb929a431f605d00873449e7f3cadfb26ccee76f1b860849caa95cf586004e085e9032cb05cd9098cd37bf8187ac46913504bb5525ea302719be23536a0f2fd3f2b3c38be0f4ebc66c204dc8ffe3b26dfd3f51d99876ab9345f707d8bfa41cce59a192273283b2d4f4744109e8c8c88519ab079af1b38e168ab0eddff858a7cd42d8c517f06e1bdb6fb59e36b582efd8c810f60d01c687a2f638df1f68aa1fa46280fde591b65df1bc90ff4d4528756c3225950a0eab9f5857022bcf6eda682122c322684e8b91fac2085ffc1d810021c73cc2e773b114d766655ff882396b7361b330637ff39d397b0fe1a9dde502d7d3ca9e4eb61561ed9dfdb58c78266655a616fd10fafca53ea49a292011c50f32e1ec20da880251de179e4c26eb4371aa605e034c1d8cfd213d4ed7ce03809cc9ae53f938def49cdc10334cac97ee2c3706967f8fc4087c13d667087598f15602d75552884ec1b5f6ef02ef414077e780bfb480530377dec8cb110905f1753311b332a10b43c5013afb62045ea2846dc80dae67aeb41cc55148a0d15402d645149ed304a5a5bdf8a50b338a5cbaeb0f420f8f616cef170a012a305db7cc877e77a22b7911d24e307113be69f6207cd9ae3f2da8f8c240ba601e2626906c65796ae977b08726f2354e1513fda1d02c14129094406da363c429870b32e2b9be49192fb46dcbd24678deda2fc13e92e2f6efbd8baf08449cd4a9d4125715ebd961c1ea1778aad58678d8499bd1a4977bb8b53bc03e9e607422325c55996405a4cfbf3a6ed7b3062828e6e6fd1728fa4b3c1bc58b709e771f143859e4ce7d7eeec84dff11ecd2d751fd859b861580f2caae105c78645c4dcc1faf439a57c093eeba590fd9eb7943df77f9f77b50cb929fe74248aab653c1371f13545e4a8025d59097dafc16b26db83b64321ccd9faa4fee04a4d2ef21961db22ab41e2101a2e2e537f21b44313ca6b7cf3cf890d8f9b887fdf00efa52ebcddcf60ec0108905bfdfc25439b150b4f3a0a1a92384d3ca93cdd0c61b559757f2f19c752c2278aad4094ae2723861d0b86089f2320db6dbd04dcf29b054384a6c189312e6717b11fa33ebba831dd3ffebd31b0af46b94e2480b9a56a5107f1a4dbe997f371b11ab47205153b13320605e49641a493b1007bafe6436d4dee2b52dac5d9b5af0a122f82d73fe0667c11b98d06b94f497edd1763922c2197a4a290992cd8d6c0ea67dc1c30de4d2e970204ef8859bffe8334b0b2d10a41a7d1fb453f81a5726f75bb23fd2f664cf73c61c5a82ffdfddcee1ace440fe63a4af23951d2f0eb3d2201f023c66f18732cd3fcc5a868c2a89c56667888b9571e80330e0418b6632fb2f65ba9f4b787f10f0dbec6dc7f9ce628c1595790e526b99f66db8f44f0adbeb522a06e99836510241f1b0c1492d7b8b11f414716d33549480198d227f3b693c602a1cf0878c8bab60829a1c84b434122faa40d9cb52f6b03ed2e59ecc8bf20f487bebfc319fdd781320e08d224d4bdc0edb32252c13a5cbabdc771e0ec87addded8e1ac94e74b7101210cdf4747d8f9a9f7db4f62470f917a975ac5cabfcd94d43b81809a51f3d5d91ef5c1b34d6816acd8d46c207b43ef2fd5473c97c4f5ff188d7e8d9e83b0194f1c094ad2002cb840fab2256e77ccf968eb2f4a7f87f25f1571f22231d2dc50969fe014c918f9b6dbc1841742988c6237182e762ed05973eac80f240ac9ba098a4bb1c8929610cdc34f1e1ca03c802c5a3d70364e38a31b22a40f09d519aeb92bc7e4e36363ab84f7976f27e68819ffec250df01f51bc523394c36011d431dba20691bcbf63bc7cdc29d68e601d996613597ab49a8810db82992e541cb54dc645f6b9e07463833135db607e3aae26e9b82885fe0a0159e07785e55959528241b22c7b5030379b0ea5a02262440a24835e5e503c8fe6edd0f5ee41ef605b7d551c2b9f86c2e14dd514a0e06674bf5e11dd22c72cfe9c8fd75a60746a960654c122474c8176a513c1ada8b4983247dd9f8e8919fc47625591117164051094d7788014eeb0553386ddd670587da5eabe8f05c319761e1e52986771f9d514d3076d9c41ff612c0ba8888a140bfb3d41a0b537221a3506866ec28ac037b7fb48173b93a16695b61bbca559bf7ce583320a004f2edc9fccedff536d757adf6868334bd303e386440d43e839409d43ddac3e906b7579be931db174483e737bc70200ab9de66cc0cf5296e5b9e0509faab05b76fd281852a6f42c885f37479e49f1b6c2bba41f351e8ed1dab676d4d1b3cd2671fea6f624054b4a092526ec43533fb37073a6c3fc2e07f7265f0c7df480e05e18ba18beb02c69bc2a8848bd2ec8d2838bdb6ecb4ee50d0babd8f3d356fc5407f77d6d3531ae6679d13018a1894ceaf89220d937c51b778eb287984988ecf23d5cc9c61ffd8c12b0e6f82177154782ab39c3eb1c98bd0f90891b2b46aa74cad4ecf8fc4355fb91f0dfa4dcb50ab895fa869298cef5d9c354237d96e9240075e07bb91a4d4addb2b9467d75b79376921ffc64f102121fe7b524e309fe3a3483b515a32e4b5f950f944465ce6a9724a7c7d1b90d062acba180da5d48e0fd8be1179ddb6bc0f387a559b4300946f4faf99a8e642507c40af5900371e6e5857eadfb5d09865513102e65b82f579dbcc073ce1e4abf21a1006401aa1f45d0eed6a0858be89d35011b36b689a1bb9175f55d5c15bd9bfb67419b3b350a1f20fb52077fed3ff00fb41e69451a5805018f4c5704bba9d72320001ddda7a040a4871130baeb7c8687f018af23a5406a323f7a3f82fbe17c17511db15c724f58b355823abfe073d0760afcb03d0d2e8960122ca769c093474a7dd838534770c79fa08efdecd9ceec46e5f04bbb9fd250486f7bf9284f1fd4e8aa9c2c92ccc3edf1587193468214c08448119e4d842b09f7edadec6befdcae85545c8f9f453c343f3509a2a1990150ce171f9c210eabff156e6e73f6b61ee99c354c03bbb5e2cf479384bf21cfd7053f86f2e91dce89f9d5a0fc193a3d991eee3eb9f4a102bfe1e7f338646b2ceb45061706314c2d74967600b0ddb974de10115a48bd6e407b65b96fbf68801e16f5676c80f909e8d8c44bcbb59d1fbe816aaacbda20fc079ac463705265eb3f5bd6d5abd526012e1028d04d5d24267e3dd5461eb76bf75cbd23666f71e4475e5f4dd2569e55f10f2f62535e9e870d87526806f24ed1b5ab23ae38dbf798cc7975a3ed26e5f8088986708624ab40d162a06577e1747bab0702c45180b77fe3504899689ff66bb0d9193e614db0e37f35a1a5d6c25029d431158bd01c9e816960c7fec92afb2e61541603c4166c3cc771b8d9671f7ed8427c703acae392c8192e7a7c9ada887ca4c672a518f4d5a694829292130b5301c5fad9c9246556d57d965fb34bb287bbe7ec2a6d828443e3c09b9ba2589a40dccc5157a8d35c531f21bed419a893940b6008c09b3ea261c54b37106e8d3ad5c8c3ea601ae7abb381c15ac35caf2994784835ecbd5b267446bb6741a94620319a945424fa09a31a8f20d9a8529d5979a8b82a1c3684c907fe17ad4c6cb9cb7d2e54c11eba7a2d064bf8c9c44fd636e5c83a6c901cb70c36359552a09cdf10bf1eaa884b590dc56bc280df884d5db035a089e42547bf73e58d4e920ffaf971920a1d5d36b3dc8b4addfc27ecd64bd8bd5108b8d750be0d4d17ff84cdd83c05b357659fa604a9ae226bd4f29fefafaa4a2cf7fb5290c273ada42530f5789f335701aa06d0e60337ecbe8e53add6a876b8d2d6424ae37540e3701469cba69d1bca698763a2d8eaae7efb9cc746df6fb59f70d38151c36643d54565fa07ce651a5fe66a18f1e517f26ea4d3e33c3764cf8d52898ba0758ea1abb93930601de3efa36a681f8d3a82a62e3d6f36029c93a04713480d2f0d5063f1a5451cf3bd6c6b243647a06c051c8ffe72e8649f0d39419d2f65cf88a35c7c3ccef4aa40bac1fbb1839f02dc0f4cb058a0b46f84910cb5a7b4a1f67e128df333f12ad6d1141628fe8087bd478ab2a43ac9e6b5539bf46b0d093201b0b8b8172b29ef5c727115753bd166debca28cc46dc28da9a71091052a6fe4050f2ca8945d421750bde5b3eb674dc875dcda387854e86cdaea3024003dd2da178788129701abc490d2a60e65cd6e58668f3e6acc663ac5a582e15b6186607e888f5133227554cd231d65b0355caa0b0b30fd609c0007864bae7dd4b7f94b075e892827eea01b48e145634a961b3ffc4668ee70059f3302a9c75027e318bdfd90ca0bb494385980f4b07ee641a80e3796bd8026cbd7f3397abb27daeb2a6e45e64a09c7998d48cbcf51242a81136253b9ccaa550b6d0d738f41371d1d1374e91ff953eb06d2994347c611de66838785bc490d4fb43efbef9830cecb99b9c28357f407a33940d2741ef3e1e6d610d623de8f5e869f6a369cda5f07e5a97a9404f39aaa9514c7c5f5cbd15dd6d48d656773c388be6c71e16d17533940d220c6062ab4e9be25914ef67a792908325e195f22ca7af4fbd90c7c513fc5f6a7b1591c2b08864b99055eb97d28a985397070e0003534b74a73cfc9b64b6bdedc0e7cf413a1d86674c3069cdb7d57f19671d83773c9831cafd8bb5deeb2a249ffb76bf926ef89c5633b7cfd6ac915e1e3ff16fa47e0d5cb355fa7e1dad9a17533593c00300c094d7f47e7ccb7deee9b32ab6c3e7f82f3a744435e3edee259df40c0693e8348322cb221373c7d680d84e36518bea05bf899c14a806083da78a9ae98971ae80967be23917d82a7d806315bcdc13cf70510ac45bf14133cfdfcee61c26523a1521bae66845b811e7a8ad000e6e248d0b4c1621d8c0b88b7941431061f2591bed26af37b311f8aa1f2bcbdb89f9bd62824ae124cabfbad8df5430a5c5f62251a159848164eefb3f67969c365232b806ea967797fa94f5682c622afdd3d32edb039569e6c1fc85de75b6251dafaed7ecdba1070076af31d879315d968c52191c85aed0811bac2fe0997a223990188c897b5c439ce9c3942d1214f697c11a1ce7880301910609eb2c4173d7bbd2ca8df3399f181fe75cd0b9281b949b1d3e95158d806a51c6f1515d65bb9122dcd08dd18bdf4aa94ebfc25efd0a18bdfddfe136b097556f6cb445c21aab47f1c20245b9017945f3318bd7200b4b83f786d30dcd6de0de2ca60700aa8bcaea7b5f90ca13ad2e32b2d511b719b811552beee15cfe03d266e3b2b86f1b07650ca2c40f1b597e5975506475a0bc571d210e584d952da10057bee68ec05ca31a4c5685e82701887da45a0d73a810f2c68cb1aa3c5b7422c45fd1f2a9a1c88878e9bafa1b3f6219666daa573a15287ba59f39d52110aae65e51bbfd8a05b3d8d67ced74ae9bf1bfaf568e3cfa2c9a4f85dbf428d78f166c27abd76826a745ae53d20ff771f8be029a55b21cc3d342e4781b021d9545207506881bbfe03158ac881a69fa158c53a754c18e13ec8ce7da8d9c38aa1b02cc2d4791d7808301ccb3d4326123305520e8bff40e5b236d2352a1e5e99415622a9faf03269d5aa5c4452631e4f0c83145892881d489b86a60c02597f26db2a71d644f6888b95691a8c07e1eb59e32b0f3972b7543c5ed30c461e967f80cbc254bc128979da7ba993629fd87c6afb3b7ff6563398737b1aec41bd769b645c83871c8a6bf6ca942aba777b175c6f155762a85883f2ebafb1f65ae5abf6e84fcf06a301f9fde430b501a34ed171479ec48da03d8519895422906f8e6eec296efb83a6317e19bba83ee54e7deec75e6cdfab17e46176226e11276561f66ab7e5be588d5bda4f6c92c9aeb996cfe248a563b3c6006eebd1779ea6099d4c8ac3d0c70b231d7dab7f33884cc021e7e997a121b776526473d0702bab457bb723dda06699bb87f19ea6ac0a6935a8da8b92db5e55420ea9ecfc5a4b8f85f835e76eff1e92a5e870f2f7643b04e80a622e8a41c5709619f65a11eeebf2902dfe2c6322b463497f102695470c44ca0360fc78dde875db9530d6a24cd16d8325d84fce0724961cd2927cd0d0680876d60e1490c15c28a2c42255868f82e0e7007346d6ac2bb8001b675a92ff87209b83ced41ccd9143e0bb4a5ee445507c2aee73252b13b2cb72b578fbe4dd49fff1d308fd8c3965341ce42616712e8e42020828f3739a042893bcc291bf8f7be2a25223e0c9d858308eded7a86174a2cc164ef3179cf2d9375dc64111dba695cdc6e2d804de67b721971953cf4e9deeeecd39f1b627ea990728d2805811e4533ab14b0a14c54f18503ed2b29d32442d58c183a47650ff5cbd1e777e9705674385466d036c8caaa16ec08f668ba1e8d5096765453c7e7c63634bd8a76a1d13d9370120058d0f85ff1433f4c6c0a44c765d21fb378e04acd2b4bc65e36e0c21f540c59aa4867bbb930a13a4b204c24c1390042cd703c1da579f5825e4e8a40178b1574c93be497b04fb0bc0e6d121edddb6bba84c2a5642ba8d62a661ed9e56faa665e7de2022891ee3b09394ea5643a44b5fe8e7b6564bd0227336627652b25872d9b4f0d75d178aef953c97b33d876d57141c4f1b34108baee98d3a3ed0d7247d15a42f630fffbe0c2544fa69a197636f9a105588114c9c09f029e4b57ebfc1f8618b14c01e1225fd5c2accc9cfc37e585157ae1827bd94c5c778da377b6eda86b5443f6fab6843ee658a0909475ebe5604193213962638a8073e039a4d03f07a02b63cfb0abc64056d8ca7b59e71ec05f034775799d2516bdc4085abe23433d529afa0ee6de9d15d0f0838849eec5424d4b89b68198f7a9e33f09cdf515adcf0df72a72f811330b0840364a8399f6cb927cd62dadbf0152720dcc8790acada951ddc4023213fafe40adb4c30c30523a985d2907feff0a0adb56ce2006fd5545e848a94e61c5f235e1432bd6647d6b7a29062495c858a2a2a5646eb0bf9cfb45638002f1efa2260cdf248648aaa126d6a81073c53977b5574cd1338e2fe9b651b970ce801335f83e172d19ee1965ecd4e1ef46ebdf7d2a66cd7dc353b196737a9cbaa21f371bbd259a0f5e81cf4ac1169810254b2b4c18227fcc755e854b1f63f7ab08f2d98314692f8e209506b0c25f1f1f954d9c44d8abb4a55acef92439a0a1c47ded26251a0371e76bbf838ae424cef55cd5a10cd0635c70ae91aaa7357cae751dcf65a74dfc132b4bafa982b9e70e0cd008b8a570170d1c6bfe7754cb694e77b37b9ddf88fb6ceefa35d2200b273296cdc7b88ce09e2206a21e0d80db147b00fe44764b385e29b34c45619caffb5616543134932d8fb56c9fc68b6e19565d9fcceb2946f909252fe50f843a55aea15c0396c64c46c1c81f5b3bae1b1d9ab8be2a49eefff85bb76fc0294a9241649c9599f10b7c790a3b795001d7a742d008023554703c41f7f976fe8bc1bba829a7a59982bb813fa1a272df2cb689fdd877b8266df380e7148e0311dc482d2a893d9b30670c0d95da83823d9a51d84aba252d584f15287a8cd4868dba90a1965b7516a056506407101bb4c361410c01f44ada2b50fb148485cb6ac863736ebe263bfdb51bd7d1166fd208434dfdc2d416f8ecbb250dc20e64f79143463e6e619a4567dedd0c242a6916debab73b45b8d1eca850cdaff861bb5af151ba00a1180d858332c1a81cc5bcae9bee2b0c23e32020ac9f592826abcd039d5c5626b85dbc3955abee5c27cc40bb0c88f91320e1fa1bc5773ec4e84d305cacc5feaac7bcf829b42a0ce8a6aa2a187d3b1b17317997334424db6ebb11599b1ca4ea8384ba8afaa809f5320416aed186183c0214be82d6c3d49442780551cef74a138fbc2902791872a5025058cfae15ffbfddd602960f635232e557b4e3e24388080986b63a32cd3ab510e8e57305bc7ca3db7a974ed4174924191d6a5c25230921a871c385309c9148c574b36f811dbd7b96240d4ad5debf356b5776797d56e4fcd7fcc8e1755d2e218af5df52f81d8c1b316d421acdbd4eb1788cd3ee83b161e32f4750e3c63acfd3e590f6998f5dc8c1ab982995d31c8511ce743533c0fdeafe10834ee574f0a3072daa4c271c5d485ddce51e5b7636bd97f9e087d4e060767ba2f08757901f39056e0e3ddc573b6e469eb82a0f1d86c47da50e860913b35e5a3c66c104f24cc793b0420db26b687fbc3fb6787c669a20cd5bed14c563601c3bf44f53e9a8b83828910c636d98d880411f741787cf19179b44b4d8d9305b9f83ef00e49ef1bb36404748c9cd678523f7605317fb1413e1626602e7990de4b15a5d206028fe80744dc8a904759c0e691342123f68bffd6ac3d64e08b778c2c64f65c41bf13cd27ce92c4fa10660ef4ea2fd1043c763a0679801b36241c1017da492afea213b82d5a976fd6b0cc6776df52b25703b698aec8dd2ca7337b517e38a78f5bcb86d3738725e30bf4fd9e3ef8fa84c35e16231d94a4209dc0b001da3fbe13baa9282dfb61af5d98920899c3150880532632d8401e91660f44eee4216a22182a806a0e8ed6f32746f6adf6aee162ebd513ccfb08540603d67ccc5fcfb238e12946c9973ad4843300ec8dfaa84e4b3efd8c3606de70bcdc2c762d7b3ea6ed387d854d81021fde89709bc935bbe683f722b1c50a38b443c8d4913387b4ec010c9287afb919aeb8bafd430f148e92659946e8b176d18e54962323f957fe81c182a7f9a21a35bd511b9235e7e53e66a9f9bbf22346ff325aa3e5e36ac72d510c21e1be34d22d50d0a753cdce6f97576ffb7c8d200b935f27b8d16a4402e506684fddc2348436eae57a2c87153058aa740bd48422599175e177c6f01ea203cb7d5baff31bc72e42ee19a5d8b32844eef7ef2daf54956d70eedec85e5f9b7d114f06f378c3940336f99314ed5fbdb7ff62ef9e6a4a0ab739553e8f9e0363cf02ef2365d16497960aa93571a031c7327bccb41f466eb15c35b74c221016343cb6eacf721575ba74c89e2ebf70d3b3c65ff9fe7d341ca4f3dc7d5076741c329498b8f165f33593abed24cd20da66e14be710b86a738a3b945e73bb147d304c0d0bccd09b03dad138bec1fd44e751a65e3b11faf657ad5aea85788baa4ae1d25a4421554483b3c6bfe11727771c2a3d4acf699518167a848a1e48b9105de9ba5781f69e451edc069e004d0aa342650b8f146ac97f3ee37e3acd9809ed66260b30b69895fa04874e507a74a446fe9e9669c14a05753cbc37198f1dd97cc529c89f65cbf184c806c025ccf245db37c19c5a5d74c03a2aea7cbe2db5def57fd804b0353d1bdab3c87b91cdc159753878454504f202043e1ec4f9402c6833a31816b5f60a19eaf378a0f627e9bd02b050ae0d8dd6c19a1255122a82f8ad1e4716d1278c01e8b17e44ad9d3a087fd5cd6c7e9d3ba59216a97e089bf41774b658e73678734a0da05579c84c6cc51b88a98c4e32b5e43a2ed4c2208c7c3ad42ba7d02348f80ad8e1588b2214573518f241ebffa4efd34070ac481300ec344e9059c5102f6a2d03dfbbb967ffc5e84431f298cdca963141c6b195d9acbcbe187d73e0b30fb11531d797cda5165097ed81ab2bef2f2dcb974a74f5ed1a64a2e8bf7f5b1ed832cd78399cb5b989bef662e04eb0e7b65747ed8963a9602fa571e30d141d5234597ddc1fab265d04ffc61fc0e5146c74b9ef1c39b8498b4ebdbb1f4aedfbd418463412b39bdf4d6c561f9dbf2361ab3e62407e029c4cb2bd43122568f02423b463c24d61df2472273b20e60c5455c66bfb553699eaa587d77dd435f573c037704ab182216071a168c60922bc47351fe35c60741cc2bdacd685cdab70f5baf74887fb9e089057d6c350515d72aa1da9cce97d1a64bb184bd671c154963849f5c24038d3564f2a42cebb6adbdd624066ae9abca3a19a4238e56e149eb6348388ceaf6bc5007d7153f03c69e79864a07cf57d55e086f0fd806110edd51cd31eb80f82b791c5146467fb67377ac3970185d1bf09e2c2606d9d457b637aadf664c74ea125b5d450a708ab1fb62ed4f012ae37303d832e9b7d1560f72ef954b52adf477cc90f9259dc2c8f84a4bb52c5bb95b9d9bbc494f4f42926bb56f5124bb226ab13e24fa2d2a258f2c66fb49b9c40a0d6fca07be48fb41bf05aabf454337fc2226fff3a97b005cfaa0340bf68dc5f65de108d69f82dc5042c657f42e48db7306d273ed10e2621bc70d020275b788864a5c2c32c169cd222c166e4f9812d2dc2ea8b65281e2332ef9719ca67f5306d0b8ac8e52c2d9edb90e95697aba48f8930a2b70d364d11b73e131de32243a0149721ad78a6fb5ba0806193253a0cfc4a78b4fdb7f14c1091aeb7e360add5ba00d66de109fb9a5fa75f32220ea58e4b2ced6e62bc816591294d915df551b6256b60a87f7898b26d2eb0c0253012dfd65d12080be54c3dfe7d1348bc77bd135651713123451492e8282d58f3f2c42897faa1983ad3e144e09e006c3095555633a41002378dbcf82bd23bf66a853eea0b9817bec31ba4125025a3a32af2027ed0200b2823ed1d4782dcc67503e1a3152fc46a9ea53dac194c9518a636fc065025c2b45462cf30b31b877695e064f2d050bd6de114f17cdbe05187d760d4b9916d0644d99327db072c5d1eb650d0de6cc829ac62e4a0d477b52620d8f0dc20aba26c171e95176e0193689e41b10db92298c181fb14f9ebc30acb25501509ace5eefc025caf986d739a6ae473f14320c632df0b2f1c8436ffc9c5d8c2bf3698161a47ff484d569bd208392fe20b950ccfa5e5a334d92091b5e33bec8c62b495625411ef61dd54ccd8f79310942676e2ce51fad52f443bcaf428427dca416b285253508a5ec7bd0a34ee1bcf21ece66a8d33da8520f80aebd315cbfc5575adf760a591d1ee98f4895ad464e0e7893b7dc323faf655351cfee326bb6f7f46c6ea9c6fc0e52633a5317c5d38eefc61c2a4e382d11520511a2e14bb0340a09bf43de119191af0db09938cb9984bdadca7629845a621b996ccc564c63c846848302affe8c54645d8aeebc7b5733b51cbb0a17b1043ebcfe0d5692f7b5d5ab437e1285ebe2ddde51bd1230823a2fa991b5128ad3f2f40c114f7debf80a8e695a7537f7e22e5b4f12ab0d399e536d79c43f432a7fe92bfd366d7175ab11487de00f26162411683b93f61ab2c819a5b7d53e798c8592d5526444d83ffa590dfbfedb9fac2dd5d244bf7f7523d15f4ccf2d148aaf3a91ac5ea4d554fd9b5ea8ff929bf8cf50826fb3fd9b091ca67e697b75b27c4882fc39fd0bbad2d2b2ef66cbe30771aadf6dee8f3ba625abcdfbd19096b8a3f224a2e1f7f350ee4658b487bac55ac475b96a0723a8b1380892663098b8bc383480ab5b1f4ec53ee1a7915321f7eb9941a9a9fc3449227febdb030ac11cb3b58b012b3c23630e7401efd33b451b8f4b46e9a62e87291b9b8c57d11ecda22c3da2bc1cf386729381e7564444c74d87c8a24dc1d5d13fcb67917f06be75f41162752a81132d7f0f49b5c9a12f7b21f3d21cc8e295f5201ebf506c754131bcaf4b32151993eb67f0801a7330411eef24565a355c2ee2d2f4e1603e3724f99085ad43db0ab192b9b82bf67e42fea076012b73cd7c489c911abe2363f94942272028215d4d797af06637a2b27409c9e27ece956f61b2c0eddbde5f14a5d7ec4995a6692423a3fa6095a394ee36087792bae88a8bf9f543ac4fc8440d3135acf91a3bac0b1bbdcb438fc7212acd3541236ad1a44d18acbf1da6871153a644b19a7015527e07bdca395345ebf8141731d3b064900e082095c3fdc2a7c01ce2f5c640a42b7b8f860a372d41eb314a348ba2b1fd3d2836dcac9c5771726406da41320e13277516d3beb460614ac3d0283f743eca2075bb8444e58d35d25b4bc93ab7952716bb2145170e1beff6a14b44c3b9b345fc2ae8e2cb73f1916999e64c2c8be0fa1096594f1a9beb36a70a9a94d11ead3e18679dc6c70fe44e355ad4152e5d886f195e698fb83579ed1c77709349875176ead0512b651df9ed87753af3073c4aa94b794719e55228260b9aa96929cc827961fae2453e735b43de7db5c08c5db0e18b306520a9cf9ca780e29c6440a0b0fae533432e347bcc4213027ab677a8cc841ad43b662556f58dc12f7d4e9226dc48cee24e38d454ded9e2612b23a9251e7cfb4138a0b80655485b192409d7987a5aead5deff4992b0425e176640e838a9afd2c01dc5d6f9b729be44c6e906b031d2eacca7d195d0f23f7537b7c784588591be071bfcd68c7cff4f24d9ba21c94f1570d6300a679c20f9ce4802f6c146f814cae8e12d6f781e2e2cbddf71bf5836b55cbeea5808364951252e1cf9a661420ddc8b015706d09da62e91e1609f1b65fefeeaf62c24bb68e342525bddc8f7403a94e1a8879dbb1b14c465fdf27fcae4eb95d6ed2ffc5f377eb9f2774028e5446a3b417bf0f20975bd5cf6fd9cd31460ed8334ca296b77bf923441f2851c82e680b0d7e2982372a894592c756138c0f67865a85c73b83d07ca92c309bc0222a3ba1354488d66d0c8b68c4615f513ba29eaba171442cd9cd8cd17675e2de4fa4b819c2332530ae3744c53504dff0f7e52322c9c793c2d363abdda780246b88a30452428e22cbdca1747847521672782c0bfd907462606c2d7e2b5d3acabb36567730e720188e66fbb6644171b6a4ca5e8a8a2e682c942f917cf84a2335298dee4f45fb4b5f72d378d8eddc2ea0a832c1671d5d9f5e1084fadc1ca57a3f55b9165e935177eadf26b213a6e42e79b91c6435b00831f9d5310c767db0c507ced63f41c84d752501b9d4281dc14a11fbb00f3d0bc24a6cae52cb4dec60ce06430b48fe9bfdc07e8a3f9fa56249d767181f549881ef6122ea5fc2600447819b68a763563739647e0b81c119ba9c51603b05ee342034934661e28400f8ac7cc6bd2b984885560f6eafb86047e6688967a497c8199224f33a0cea627abb70f6d29725521a396abd345919c253c4b2899fadf68ba1a29704c3ea887ac48376808336950d3160f661e69380da3a1c09554566040cdc4d36341bb51abc3927f3ee8edf3c048b829f6d00c732dc593791e7859a24853ff8d741e1881a0d846d733684c322c81b9c952b5221bb7c98e92c50bc73df7243c443238c4aecbf56853c8bfabd69685728b8b999bab13ed60ae1c0f4345409926132f7bd8b58f0277a46847d545faed429e03fe767496099560cb511def501034c80c45a9ff25380dd28ce3bf335a7d0a4b1b8216267ed0462e6083a90fd778347d0452aef40ca4e906bb54f8a77179fc8917bb306e2092e77a934c8138244c8f51f93fc896a648f2337fd1ff0cac747e423b4d85a6bd7f138e7afe3be58326f025c34748f1f1ea0158be901e91624d221aebf1a2cb58cab64d66fcbd9d77614a521563328ee761835cd70c276aa69af308cb49479925c542468cbe3e94377c2fab76db1121e852b896669b051d1a5f0df9a5e61e45d324ad0b7602c4c0478316cb22056a3943d35225169d9996700fc24d58868f7eb540bf256991d75c7c256cc77c77c860486ac70b58cd9e8e81c122f7a5b5e1c39d9ab8bf2f94f4a75116c38e6412ecd20af6b78525327c7aa703c96a14132c795f673e95513a43e1b40c40996773f3672a42ebb682260101d8ca93e6d0d5f1737420b2980628cbce2c4a464095258a1d976af41e6e05ab4e3027bfcc628697c5427ca38e44593948735dd9dec65adf9a9664dc5f177b83497959bbb4b0644eb3cb640ff16c5932f34830023c44b634a4c3668697daa3c4b48e4ada781400abbad5a92199cad5a508b01d432de5247b32474513d1c5b2b3db3456d3b8efa21dd7dbf19d64d36c159bab4a6b1a617b9963da24d2fffb3f3eec3e84f6c277e837395aaf5927d26130badaaed8d3a0f8e714a2efea51016cc469fc0265e8fa7829d722199b03bdba49ff2b89edb791a4db2e770edf26ac9ffcc6ba75616cee1778632d06029414707f5f6b368bdd398ae56fe0781e05518141e4634486ac015a5c9519b3836163e897d1fad3a4b84757be2ed6c89aa4e1fe8adea21e7a2c14354126d3cbb2fc98613a8fc7ea1339e74afef8bb4ce8f76f4e4cfe41f75fdd69aa1cfc5b5472d22c441d2e9a829a92663cfe815e7746de265693fd7eeab23261eb32ad0bc9f219559882963a959540439d5681c79a91953742762ce9cf78a124a7c5cf218ac18ecf7586897a96e4f20ac739c52ef7d01aab3a95436e800c1a5ced538762d23edaaa92924ee66e27b71f411b10643465c542e6ad7981d91215a96c86e0739688b3cc121e33fc322b59c813b261b6560aaecb003d8bc98cba970683cc40c65117de212fbdbce8a1aa0306d564b9ce41ad6ab3e9305345d958d115e7bf74ca095a955a8e56472cd3575aa77724b0958ca0c15392425ec9a40e3a52efa0ae53767a1df5ff5e044ab4879079ecda1157add15173631339ad49b78599ba78cbafb248dc789030b5d8c77b218f864d0be4bb5a2cc68c1e62b1050650a6af06584be07708e071addb87e100b1ba0a490b14c72478fb5df1aaf407a6685c326b44b75d6864f1c586fe3c167741e5a09672f45345457dfaf076dd8e4e320ace19cd56962fb4d2b7b2b0da2cdf92c84431b1d48c13d68c484d495cdb94fd80b8149093f71377aad1c898327b30d33f87984bbf21b7644f86e2a19d1b6e4d19cfd1c6b7315be74292fe99475b7668b23230676ae4ce45040f9bdf82de6ee34a2aa55ee44dd7d4a3a1dc58716b61dbfa2063badfe34495b0283839dca7af8b0a673fba79c59b93cd9758cb98d49c93391a497d72dc36e53bf9a8c0346b5d600500366426aa96572523fa247e06dae685b0d4a594540201806a40ab634864437a494d84361d26102a4fe96c083725765ad965efd04f297d63da1a359d4d22456aec0d2a691bf42ed908c4fc9f43a027e77c4757fe94b451bb5affb9ddab0f0a828f24f608d76d14ee13f3caf0577cd9dccb5966bd25e409f4d79784841c11074e8294424734c7890b56dcdd9809be7311a2728cb8532a5e757e0ae9df0b09b6a6320fb9d5f950edb0c83d3251ff01257e6cd3bdd46a957dea7b48843ab1fdc398ecf8040c2ab7e503ecc1c09c5d0ad3f71fd3374b5b63107a90b2e6bcbf25391b687732c683e8e4f2dd97ec76589070260221eaa56773fc874c301ac264ec81eea7cb7bb1d2884de9a3409db788b8d217b784923f100cc6ed9d43198ca79231cf4549bb3743df9698530134e1c4ca85c9ad34af3bc359356f87e8a8a772f73ca67b6c0ee35375a022a0cc1d8152320c0fa57eaaa81dfce540882aeef1a2dcd6d04a614ab863e1db97133d23a86196618a9097bafde0511435b28c2e36c9e475610736dcea9debdf8caad79c50134862575aa20c4959751a60581a72a51d612e06179be0e9b3c3c9b74ecbc20fd0863c5d000612396fa307e09b17b3a8433832c64704bcbcea6a44c16effed2652877059c4161df64a5a494e5f6313e871f91e261541ff829a144dbc20c6f9912e3cb11d6b3ee836bfaa963f1c4006fe9653aec0fa28fa1dc498a94bf82f91494111ca3e728072ff6352f8af1a39a7be20ec3421df866d2f0778b532970f9d7256a30a23249c07b91628b10d87a8422e464cc578d7c14e71dcb5dae772c51527498eaa33495f8f78999fef8ba499b8fef88e75e7ae4d6ce31867a447c144aaaa67eb87b0c4f49d448cf76d6a04455786379cb87f6a6aa5b1a0330865df5509760c07383243e9d03ebe5447b61ccc1d54de96e2bb3cf239e6639474425c44687b3b94c9fbd11385dd744211a299c0105927662c1ef765d0cbd0a8eb45a0f620c982e8423956d413dcb4a59989a8720e0740573147fe0350f158f67b281072b468f93a4fbde3a6b601468090f5b1c0c570bddd4be80701b950e6750e0050d53387c270fd9f60877ad269b3a6753b508146a43bd38275e028388fd51c07b0263481271253a755e93080877bb4e4ee25904365e2db67c104c6e0a124e13113d10f27837bc737f2560243562ddcc8a2750b96694632dbaefd32e04ad9c6ed82c3b428f0f74fe3ac2659f47e02b07db110aa444fe70dad05be53e2810ba503fa7c01163d010e2e651202aab1d36e9004d4e6bad308d2c716bffabff8c134d0de7018332a00e0d4fec11775edfa3b247831ed10de044004c99d507615661197594f0df9c6f8634db962289dfee05860ab557ad3469d5c8315a3f9829750efdfa5403ec73127be38d10a18782fa30bca08052d9206bd269112d7b174a6c17b30641e990ee88f0835e8adb471cdf42104df06efa56b98025445b8a3889e9639a6c7186e14153601689698233471fc31d2153591d3f0927863244a4dabce648aa8497c855803b5f1246771b9ff399d60a030b855bc871a6a26130626cdfc90bc820a88aa592b134cd9677a8beb080ad505c3f213c0693c44eadf24a0f31b2b5849aff17a726fd3f48156a3e92aec248916fd4e0a53110ed4475a50abdb6b582d7d6dde8746baa7a2aa859cf49a753ac5ad609bea6f78273c5b6b4798ce2e08e9e97c2f77474b27abbdc1f8ae2df844f1c3c57f6ae71a638fb17f9a037a2e9a4dcf32836b43900a255d69aa0b46e374baaf93dd2f00be110e3be7f45d35faca73fd63b7a8dedb5143c13fb1bee16f9fd96ff49144d3e897528a207bd74281861de1a00d41e7f0627c2183957be936764a6307d3983cfe627ac5d181a2ee2e43c4461b29250a4396944a99a1968022dbe2fdfa2f9ab0ec4d090f5492ad173545c379289b889fa394394a25f7d074ff9efc1504167b0c72dc7dc4bbf9c9e2feed26c6e69a41cea92354b1228821aaa479a3aac320889ef7968c8d8ab698f91be67a428e1cb2bc8e221c1082c95bc42dbf4672a8ae814faa2e1db905b11621cc1933a13eb32c3263ef193ca854d27d7ba05e0022712de952b16f6c4464129834ab02eafdbb229166f4e29541109323c1c0d229ad3c1eb56e096101f9ceb45427ba6fc3e45511d016f521fe0baba422b846ec176206d29fe0628fa59d27f801b11f8a2ae79645485296d8aa65e04c36a9c8a60e84fc0b1ca42ec1ef58b700ad8f72f17bccf67f0f3514f66ca2cb192072e039c43478b0818e6c90fc8b4f0b40978e5625d6d045ff076015434ff120cba585bd251fdb281cf41b24d70e317c92a9b849dc82fb4908d1e823291e516666f0bb6b4183bdc230c9d88caa30d331a72bcb4a742970f2493d9d38c17273dfd31c94d43a817652aed381436bac530899f356b566df43e4cd3ba98308acb9aab23ae739f32463e150b0103331cc8336e3d74a59f5194a0626710f6e6ed8565fae41b89d3330f5cbce112c05821f4495071d91c3e03fe41efc7073056b43e55c128e05f11b443702f32c35609fa73f747825887d1de47a83e6c0a5268ccadb05a120819de8f32aefad8282d633c5edc7b8f29070646efc7a7deffe545eacbfd98242c465a4008aa7208749130aba8c1b4ccf010ca091f4af41eaa7cd638966970a99e76822dbd59e3932aad83d42b37d6b04b6b5c84395ecaaaf212d06aca1e4e63844a78413ac1b52c7b2d6607ad2e4e82bc1598d21ef6d3e1dcb1f3a6ae84ab58e1a6c29385f926476cc0486ba6fb8cc137d0c4ce3fa31c6bb37884e5a9dda6c79f2c3ca7f49a14dd849c7488bc0f4f73f3c29cc232277e29a947cc857eb2f78ba900f727e891913890ed204e63d88c6f69118d480528c5e4a0d91344d201dae535b647f604ed4d184bf14d21ca366cd4651f0f70df7c4aaff880d65cbcca27a83ccc6c544027149593208acfa4f9cdbd35cd2efc94a7fe1b6ef382475d8a5479152d8381dae8cb247a1e9b8289beca33a45425c1d9216012d179ae53a20cbc77d6f9a9316d9f7cc2b7a691d82a90905a7a2d54fa438f380cf97e8186fa1c19f240dfb22500f2871886a1aaa78bff478f12105dbccc4b9a216b91782854a348776f83ba2f31d60aa6c47b87243cf3d9b2c9054db59a0646ffd54fb6bcfdbeaccf0a1c97074c7951c31a796501cdcd857e1d53f4094f89e09d56f424517b9767d2b3f48c5d064ca3cfe59805eceb9153f268f41c7dd92d74594b8e4c544b86189ccb0e384b48351a268727dc7fcc61b9f2cd7de7e3c954b7f3501e8f033f2726cad2865c5802001a5cd272006e0555585d272e78b5c883c42391a88756270f29bd8385bcc03a280aff67af4209ef75b449486dc6648ac449765ce12fdf476b6c5c1424923a4566b7d9c389c26f44b041ef68f531f4bb1e5b666eb06d3145da5835ff77627b5c0050df730ab36c9d5e764508fccd0e8e7b2d7c13f07301dc1f4354c6ae863fb6aa470f7b684d950e2e1ffa99a8d539b7a63a640dae1dfab9c13c89540a8d287805df3b8f426ee1fbe47b241633ac55d8ab37c575e77ddc5cc7bdbf7a47d5ce30c64f67cb3cdd201c05de8620f4a7a5b61106008984f1d6fab0c8d8f9e0e96d06e5dcc7a8bd4c0e3e61a41a1d972627b619aa08152f8f53e86d1e3a6837a77e8d0d20d43d6f3bca966cdf24f13a5fa2b352f4afc3ca54345aa8e2763509f62ba7b0a579602e9af18b1cda6b0f1bdd12e9256bab025b364259ffba7d0588bbbc3c95b7aba257a55f2682cccc53e80315181f40e3f6a4280b28a078a7b529ba50fe22b98df61310351ae43cf475f84d7cfa025413b80102ed9db172ed71fa9db750b800476d4bf4c8cc7bc604e1be6b1afbbb05e6a12fd18de6a991a610c0df30c49b6dfd3e18e18da6cc50d7ea202326299f3bbaa411fe5d0fb7a1ae8e54ca60c27619d25625e9a0c202ca6d22a8debd07c196714f112a399cd85a53a79da938fde91b37419e6b4473547057a3199ac0f378d3b3377b990a88f24582f83fc495e7938de7bfefeba9922dad98ad199d58ad55caef030007e5496b3ab5f1634928cd4c081dedfa1bd3815cdead98b74b5d9d03184b1125222337d922179881b6aed65876e021a4c411fb15a578dbec3cd8e0e440ee83b2764a08a69b0a10bcdf676b6b60fdab0036abcb7a95ac7f7f64a53603974586af87c60d5e4fc94c9b53f8b87fc0a783603d562b29c1a660651741694c4f6095938eacf4c92b02345138a349370bedbee4317ab42c4d7efc9a19fe41751980dcc3c9c759c4050d5ed1f8129e72a040985e56a787306f46b2198dd3d09e192c436108cce320083206d35bf217c5e70156554feb437d421ffca8bb0baef75faebe4da5ce78db2c51ead485c03c582b7b9309b7869ded9f1536e1f581cd9abbf34dc3159ce52f2485111c2071884b8225082560415fa1ca2492b7af0b215ae81ac5638fc4893ad94a56494b4f7a25c4c375a0e8be9b36163523e6226a35fcecc3d772c6d6dab0ac098b336c577c7bf20a05164c092518c8eb4e27998fa5604aae7763c4f21a7676593b9834c9bb11f0e1695454a1a6331dcd4d2f9560939d15d667a63adf594dfeacdce95fb465062d0e0051c43421d84c8302d38c2b904efbdb7fec011702c3029b05c47a69797c77ff5bc0c43e566ebe68b22e47f4282ecaa90019ce041623a1c6d3e53c0e84a404cd45ece0fb932ab3e4b3b666ec1b7311fc73e14ffcc71f6f7a52c09e766e294d42cb6f4438763906858dbec7211dc87acbc7f55b440f5d69a9805980d884433f7ce261ca350906617753561d9e229f2c5f8519a1829f4f94025c6e99d403627cda7a866a9b8502c24348a413c609b4a02001bd59dd833dd4550174b14ea8c36279b311dae5f40ece78e66ac812f904d2b981e08391ec8f66553233c54d1f7f51dfcd8c6c610b6774128ab618e7b1a17aff7aff89f4d53b39facbd02eca12635d7dc74da1e8b6847d5607701846a9d264c49a0ebf04aa9f2117df24c9e6e89ceb30e7277ac34159fb15f2a478a8063f7bf2dcf25ecea2a346d5be84b6348c7c955912c8c8fd3372f3d3578d82866ae430c9e070cc9a2f9b26835d4bf9c904ca0b10fb11bf6744ea6215f127945ba264679d9e3e12f30c3f4a997d2195da8e2e03018a041f761086cadc49081c34640a1aa6bdd8cfe21b6d95f4ee8c9edbbf34715f813affd6894354487ac35ed704a5e26483af04c22a2b741508f97e5f67e479f5bcff8cc7353dfd866f5b68a69c5903d858553430bcdc1088c05d33cb8b070d6a8093d46569673020f1432534bf86f57b0810ca779bd1abc6d40397c2723e2563418822ab7c0df032d244644646495c8a58f6703ded851ea42ea1834af2ff298f550b6019fda78df6fbcfc10988b61dff172479dcea861be74ab924be2c1454f9b17e2e08c8be44d35e09383071c52b49c7b321db49e4bca24cd5684e3c205a2a1f1e35a474f835f2c50ded2ef0dc8f14ed16ced62ad5e804a17e3b381a61da9b1d05636b9c5f6420186b26a37aaa2858d639d3385f5541874df259ef5b954a1a30ed06cf1b75f867fe61d0b17749335283169af187fd21e9a9e18d90afc5c522c57bfeaa2a28957e8c8eb496e65c54e1146600deb178ac6ab17a7753fa8bb3bcb684bc4628b41c950d2362d029c17176ba2bdc4e4677e09e57d143e162b38b5b889ec6c2b19f4e84a8b5b62f02218a2c218a9c100466396f49966a017ba30a4506ebe480d217e5aea7ce3ecfe8a2e034b1a431214d422f9d8dc53d256ccf2294d9262d595478054a462a8a76ebf2367f865281ba6b0b8de8af107efe0b3a7a05041ecb94ce04a11420d1f91f64efc1407eb914363dcd58c02facd1479004391dfbb373eec7b029eee66e099d76a4f43bb28e0fc47b613478c9ad6d834199924accdb623cd277f5387d599bdace578b855dc3fa116f059c4be5579248621e91f02117d5933ac27049b46a434f5a4b13cee56286c353125bf4bde46899c4be71eec2aeba082c617489946ab1ea57bb58bfec987d01e8cbb7519cfabdddde81deed345f705da9f89b39c69fd54e76d2a03d8565ee7481ddfe80a1e3786a4195de25b797c68a2c66607486e1307160e08ab576ac41074e4234dba12081c1f494435c0c9b0398f4d5e91320cc9e02b687da3858470f175561f81597c29a0aa904253f339fbbec634c4eb09cd7ca35e309301fc7a01ca1dd13d5f404e6951073646295c87158dc8be6d67aba4ea6a80c2a5bd2195def525a157fe6c0bfa4349a32fdf3cbc3589fe94eb888a683ec8f75916b4ac07b06769170a4a0f4b0235bc492b21fb4d372d08dda61114b6cfd5d26bb24bc8de5b4a29a50c6a03bd0302042b5e042c0838202aea57187081a3833d67f4a01ab15ecadcaa0b45e9a27469faf664415582bdfaa73c018a87699a3ecac23e9add9533465d7761af3f828b1cfbf944f129cb8ebdbab2bd386b2bded166f292a9bc55a497bbea4cb7ab1b63b3cc25d19d9df70c893a0df6e0d7b3eb58d67f7075aa0efb759d6b5d672783ff009f3bf657b8b4e37bea58973e3dc88e755cd6cd344d9ffc209fe806eca32eeb22a469faf5f1a9735df64c914ad3f4f3b9a3f33b2e125a699afe6e91a6e9ef68f0f9445dbc78173e53e4344ddf3a8b0ddefa8a7b7ac07aea4b99ea657deda85e4f1dd5eb58571ed4b739aad76ace089542a9be54d6d84edda31796becc26c64232a935f93a8157286e3e2700745d747c492f4f147bcacba06d5ff562b15f87f49dfdd55af2c38589a4abc8b3a6ae35c162bf8ef59dfdd684f5546abb4500bef6b4610d00c7c69ecfc7283c289ae64ac7b2afba8127cd4d3af613d5ea74963c4510ab0bdf81fda23665ec2399bd96c03ede1b7cddc2559fb8b55fb4ec0b9d38642457905e7a89923e6ed1d12cb6f851e565f9225df4725491c27785339abfb4235013bf4cd75ee6e05f615da5729365a6289d3c51ec52a1b2aef2fa2e15e3eb5507aad4686e96cef9ae52b8548c2b2cfae8e3b9227f99730f06b381b96020ae880bbbf73f7061f76e8034c90a656d0bd626018b30b535cdfca4d6a74b855b8c573a2613dcd64bd1bcb007dc3ca08640915f1f46206d54c45f51e5a28f7ad5c188c2662f3d96bd7417af5faa32e575a55dbc7eeddc4f9d0ab0081045dc11f9fdc282363e51d8dbd2a6a878ce26916d9f7421926f5f771c4772a686b8aedd5ea719da7567d2ef0c2c92dcbbd5c2b02c92362f1a49f9d5e7de39e79c372b9314a8383754369a3f0a597aea85c23e959d3cd1107c8ef10f7cf6c919e72cc2c678d47d69fa4ac649f2c67aa556e64b841feb2ac5ce2db29e717474e46fa6529e6d6492c4e71db3b5aec3986692acb55835358331c6584cb9d633e6e37345ca718679d6d65a2b8aa6cccba6e68e98d9d98825e65bc59a3b22fb0a85fdfc9a49d1783e519c5d2952f9447362f563f5b7e7c4509b49d1836fd167f44bf45d26e0854dbae915b8236648dc552eed6ae65cad665ed96944d14fdc0eb69fb8fbb55f362fbfb06ab45788eee2c5bd374cb4b924687c3c715fe5686ed1b1b8ea605b4bf3b2f5c6e0d2c63170df981f3246660735f59e3f5151785bdbfcb3bbd1fb8182f133fcb90146acc60fd38f5f7d3f3f2ddaf8f9d07043860fd63672f011451b5e68f0d808cee0b911e4462dd750563de3e4abfb6e187d3d590b88c168818c5fcf4a05a2f599d5a8f9b84043747cee164bb4dbc7043d305b6aed43021e983e6329be1cb0befa7c887cf9d5e7637b7463a8a81b127f0a9aa1283a6ef08a34a136cafacbaa22d43cfe9be2439197a6af797bba54d8ecbeb2de11d69e1fb8f8eb3dbc4d7aebc30c21b35ba3c38c1f3c353acca8f5d4e89065befa66c4c8e1519b27b96a11373566e6cd0e23c081e886ee69880a48c2c4d48861c288a981b7c90f2d8f29c1c102edc90c5e886a7037044584060f0b55b4642e29135a4e833e21d3e7cf87530c485cb8c189072b2cfcf09802acf18295b105a3f9a2d56a89b021f157df4ccbf3b4cd372282d96b095ba3437ec167137072ce353a64a6476bdeae60eb51d52f113639449d30c3171fa0a208ec90c078f284e58ad213d1041fcc1476936d6cf68ac2e726f84ec127ec5583490da27c4a4743f4d1b0fdcc57df0c22b301bb6ae64d03f7b98cfa8c93f3898a70836207fdaac9f904158b6fd6c25f27552cd9d5bffa66425ef5d537ab3dda7ad47cfcd4136b0d31923e23d14884faf1b5b6b1b9b92348388e7eed1f4cc0e9b59bacd73f123b589d5e3bec8ed0ee52bebaf61a0df52888d7393bc658dfafadcd82fc8c45511445bb5bc568de4aa921aa8fb504cdeb5b8a62f52b5617922bc85eca388af1ab6fe6f3167b697380043c39972c4e5f680873c3d410d84b8c807d3ce5d3564b645b45fa5a43a0369fd826dc348f5a9ecd9af8514bd8dd63172d890bf4f0a81cd40bf408a9b06a55f8fa28cde31e5acdd6c4057a6a1501155f6baee064a8a2e8b2ab4f4692f7f5343dea9331f4d717c349c5e9317abbc36e8da49f5faf2460779f829c9ab7cef376674ddca8dd2a3182e5796ba486a85e620422a2c7e7ae9618217bad21b0d714d828b584ddd510d546a921aaf55a029f396436a1ac766963bfa62fc6d03f03ca7a3126512b96c066913f9f1557bf350156ca7d61aeebba372f3acb41d4ead5d1ba4bd55c0eaea75ee49863d4be56f9ea83b15479c15bd6afb9acb76c814789ce0e017ec45122b03f7ace8934fd1d0f2faa3cc7be2ae6e2551de86022d5eb19543dc56b8785fdbc82445f688e072e3e25ab4fae48413af615d7f54b7b75c548bb8a79705da73c9f6425a1ac2bd2f38b8555614777a5524efacb953a3dc8bef3d2614180c72e9e28092f5e3a5597a69fe380a8a8157927ebec64bfce62453e5d3955978ae03d90e380a8f2be58949f62a73b19fc3d03b7a1dbcf36c48674bbc5604d6c01fa0002858043a061308844eb412bb215f56eb6db928e48a7341c3254f2e1834a0a945a6011a012ee869b0199f576b8dd8f1f47bbfe96d98c7684a694e2522b3b243b1c119cafe884a2deccc84cc9e6c3d613f61062d9f9d8cd84cc7a454145f705951fd14f0a0c67290824d8c30d713f704a418228fd7afc9e824682bd14497ac5c3934dc8a6f4a8ccd3efa7828d92598043804833dbac472342431af218f682e0944eb829ed76bd1e3acb13c2fbd990d87a44843d223aa150dabb09b1e08ee072457245428a7a3e723c5b119b5291912225a05d15225c8f0750e9888e0a0e88f4e3d7b3059178413c2ac1a1a012905bcf08cfcaaedf0b06058342825476fdde905cafc88e3754d42b9262d9f57bb81cd2ed8704d8137243b201d97a4a3f84484333dfaedf03ca4da96f47d497790a9af18efcaaecfa284ca9c6e603ec8a286533e4acad3d2ba0636b473fa0565fd46acf3abd302b43c1ceb9fa826e7f735abc05ba9475a51d665f9f302c4bdaf55192ac26549544c5a1c9c2b2de2d217001660186f0a5a60b086140f01202da6a911e82161050f78d396003085d0d351a10f240780a0185597c43c058035cf6755d0186bc2cb02d30e1be5ee3651b20ccbe6e53a3655faff992bbeceb354f60481b4c77dad76b6ac84a720ffbea4b827bd90dfb1a60477b9aa63b1a5b6bed8ddd30c6f8deebf9efb5d6fe6ea92a6ef0b11c23398ea7c92ae14b1724a125df0947381b9370d1c40b16db8f051c704f38240c3fba69caf8711cef19c37163dd647d687df5f1d8f1d0e59e2b8a464471870eb3075766d1144591cca2288aa2986342bb3e9a499038f922c1e529220f223a2583c24c47561136374144183c812285461726341e0b689892b402120075f048471e323430635c2153977d789bfcd0f22f313baeb45258ca3e32b36385bd6388aa25c2863479b478a30d5584cdcd0e2059474f9e318ae26bb76241f60e1f03dae3575f8e302060fbab2f070c1e85dd1fa15c7341aebd20858108d57aba1643aa0285a82cc9312546500e14d40822bffa7218391113b2f3575f0e22398604e500c2130b7a7df5e188010ea7476d785a3a70e4b382102a2f641886c0870b744740609890a5a633797068c1b1e52f0e29afba2146243654cbe960a18426a5a0179ca2c400aa4f56825060e487684a915a0eaa1d317a0505a0f04b41464d052635aa93901e488e7e5ae002a5d625d76c20f1302684439763c99b5f7d39b0d40a82ab4bd3b48653ef0d5139b80e02c425a1caa569fa02e7c4071930bae915958fa6e5d16a74f468e5f59668b4472b105b1bcb6feddb95bd55364ade4afe97b262122dc428493d3a9c1625d813b46096e228b95e82ca8a0d47894b45d35b57404d6cc68dcd256b1eb18f36e3c5fca228bacd28ea9375c668e0573e33560992643466b666694f98c862581a90ad246292610fdd9e1025c970f686b3164732a52acd558ccc9ea1f1c0ca40830d5a000880eb830006208055f60f49701a7cf53da111d9d65d4e724f7878db6a0f0094a255181bb60580918e8686dbb6de3ada9931ccb6f50d7abc0c8c86b6d560e947d3e467db0c9a8031433fed2ceb64834e6a494bdb03182b743283b62d8d85b2435554926c891dbef6199e34c60b93976db56f9f598c1713b6d52e53a331c1407bed3140b62d436c687bedaba11b4d52120adb9a4970291898806c5b3ac9a56008b3ad0a4ad1aa04493eb6d59e32d2cde092b26cab9d3cda31f5b6d53ef67819e8488a5511977e3219bfd7ae9b8029c0b0b2adf6ec146492dd08be760ce60a9b788951b9c20b75874d329e3be449b70c4c33529f591319624cb31a2d005f7d4d52a0830664dbe0abaf490e06b6a19b87afbe2641625c6e4970adafbe26316439704e708ec90d49b11a700e4a1113196448709191ae7705ebf011de318121490adee11ee63129c110ccb37809ff983099827fb809039910c574c040ec84834c7e74c1410c060b99d8f88285180a0f595f7d391c6427e0214faa456623a73e332c31a83cabd1724735320dc8d642ec28db866e660ab21eb7241997236282d3d949cee56c483928454c4ddb6ac7463a9aafbe5ccf8f6dfd1eed989e76af732ff35450b1a8cc5bfacd6c49f26b02ca2c25c56e0066a71cc45f7d4b6290e572104506938522152619511666a83c14a9243dc9439e74e685242cdb6a9fd96882a4598d46a6107b010d03d9c814622ab00ddd56444ce96d85dd26c12d214ac2817392bb30bd64882c88ce41d145315f7d4b7008d14517672d8e644a955a616da4754b5ee4b0ad8f47bb1598d80cbbd72ef678a92d3130bcd7ae977e2530b6c3efb5e726a07825c9b6ad63a760995424f8da2f18a196929482f0b55b0da5872917644ef4f0b5579e34e5428c05290a9f59932c68f6dacb8bf30afbadd198b46cabdd02d94a15623118baad8e2401dd2ece5a1cc994aa3457658c596f36b01168041a878c4363105fad5024c135c948807beda6935c2e12655bed2594a25c4476a4e8b5ab8c7464101c74af3d75b43371c894ec5e3bd9e305b7d53e2efdf6571f0a2f686802964f3127e06bd74ec1f209187ced5904230a575998606cab1d8b50e270952529b61387affdf2a44d3cb6d56e7d664c321566afc57304aa21b4cb96f658a37df529e9bdfeea539204f4da633edac8836105253ade093ca49c506e05bb3e4f9a72a111d17a372337a534150611f280f0b2e87ee8aa0c8586ba9b4e7844b885c7ebe17ae0864586588648865b70b827219110490e4b125a957448da0302017f3f22bf222045bc21de95303ba19da505a159098df2a8942b996f7214a2a1010010041443170000100c1087c381240bd42c0f547c1480126d842e56402a8b442251883410848108844008030000000008c020000440100364b40e68975639f4b1d279c6df040856dd27f71f43bbb9a107565bd0e04faaca28f26fb812267c71d6c1d75022f42753acb9334aa6ca7c66960c9df9cc5c3255e633b364a8994f66c9783593894fa69aa9663e193543cb7c324b8692e9cd28195ac693f9d252bf9bad28304c07af36993acdc37f7d41a2eac65a2046a59ba6f68744ed69d2861719b0e7e6d1718030655459a8bb393b80c2e98f511644d3310940c29c2ceee2f697a53acdde3f307288f60201ebcb93489907b22cee61cb3addeec9285e00e5b1aa2c5402cae139568dc08907d61b8f6679abdc5ba383c360470d663c1e2d1d9c333c2b3052c12be3cd33d4453d0c1da6aa29506a8339221e224655dfde9598ab90ec2adcacf442ef2a477390c72ea8bb8318d6a2c5e23adf3e02026d6a317bceec97c08ee50fa18986033f243ef6b212c33507fa2de80eb74275a3877d44f67e7cbf93a2343f034648b03364fea10101ac11a0114c6dff052fbd2cbc1357443d03da3eeab795ad3803eebc47fb257baff7d4b55d9c044bc336b96b9d8427614b569f08c263db936f759f897c4cd374a1002dcc2e175010769e58e261e2d1c281e7a2827a22657fb1f25069b41e9b3df833637fb54a7cb48886799f1df78b06ada1818d7e549190f70f4d3dd1983ae81ec9b54c791bcbfa76af0d53aa5396eec0f8561cb8c02b069687006bdf9181d541baf5a683c7129889ca1155b213540d8a7db14f105343fd32760b4013a077460abbf0bc502494a603f016461d202d979d2fab62bcbed65140c31ee9345a365dcbde07129cb1aa2db453507e4f016fbd6cc0d54cbd0d1acac3d89917ec993aae15115fa1c4aa6ccef2dd5fa2b1df1d4164e51e74fc02ba342637f99e3948f48c2a74ebd831809330eeafeae173bc723f613cd6becb93ad7b395e8b30230daf5b8d5d540003c2e7fa07d07ae44d9cd44a1817324d7a654fb1bcabf906dda5d627a91d3250aad6803abd2807a101b6e3a63084f24afc87b604e598206062b7cf9fbe072acc0791822299bbc3a0be1a9dcd9467de4c9211c9e43348463c631d37434b5d91f406bfb8005c0f5b4a7fd6779d667daecfc2ff4199733476feba2331f2885a1dc0f33e2900a28ff4cac9fc52bd5f4581abd2e9e0c086a9eaa5dec22d3c6b9944eec4974c950bb1f2ad0c8065ee1e784833cd99845f88e1a146c797ef6ca581d271ed24c001541ffb136a28ae11a4f20d0e9ea311a88678cc677f6b040e97c464129951a6cfa433e24c9799ce8c327d269d1165aa130ca86955a3430a8a967a93f126d0ac1069b9fc0d3715708e8936f4554fad139bcc7a31c72c653dfcdeb40df30df01e21c2888dd4eef31d9e026d806f5c86fe2bcdbb3e600c2bd15fa2add4cf2c0ed86208db0a09d2a87b1bd93ec01a722f9c009788e060dfb2f32edc32803d097b4e3dc902f0dc7255aacb90bb5ea008228258c079625bc7d0a85fc71d80da2057a648008dbb4b34e3c509cc20d6a2fbfe435c2725e6ae9b5e248031fdf085988715724200942197df42107c13840d78fcd988197b2b084b64ddf1efd2880e1142aac76195928137e3008564c341b427dbbd833378591cc2a63f72aa69031406cb321cf28bf234c76305589406a6a31e7848086a791a3e2576db52f3977ce2695450d9b28101967dcbcb474a056e89c5b8bcff20d88999db9f32a538044ce97d5189700aee94e527f03ca5631d80c602197f7f1ee5c620cbaff8ebd2e28afa1f8abf1fa2a4c1f35dd1084c1b1dac9168b324bced1f05542b833ca4bd8f95f840354ee38fb934dd10b3f8ffbce4064305bae4a952c5878c03ea1f0ff68477e103ccdde4d42f58ba235c75c3926ebbe58745c71b9f74e260101545f93da5e2167d87a27fb554584396c7edaf9258283db09b262c66c93238154b4aa5fc083d3180e4fa2c4833bea1373a9659f9f358f75fc0acf480622cc24ef9537a1e63c9a2dad39bc2507d4f63d16c7cfff2b6b5d9882e4b4354fa403b552532c8350ba501fa6375427fb0075696069b09b1f3b078864c3c80a78c685e10ab38eba779b2f05d4db2b86e9cdfee759c25ae48fd15a4d803875263618bdfc7acf70d445e2662f8c0f5a458b1a403f6bd20598a24ed2fe5d3ea80a0c982c0217ea5346c915fc9f9af3d8e585e1e8a172839b490e57ad6f8a512d025655161eebec8e9fd21901d96575e7ec253d6c939682c08e5f7f3121f166d1a4a1e152a3e204c50cb53fd3f25f6434159f49f8a4fb105acba59dc11f31e9b4b0debbfef924901c88293b57e9953ea1a99ee64ae33cf037fd665c15966fe1b271d429774451710384ada9983cee2c73e7f64cf681e69c3c2618bfd3953aebe2852162ceef4aed2a8fa76dc533996851fb4fa71257610732d39c9c83267164a406a9684e7d406ed929f034d935d0145bd2c118dfd4f97e2d6124b9a7ef341a57e1de1ec59fae9dac39772140ccb1a5bf247a7028e6b3c71e1acf5df73baa22b71c2edc4fc753f6db0688645fd0099aae2d73c3e217672fed83c5d5939e858e0fb7989efa109a3f8a753ea638b929386d15fa5519fcae79287e1640cf58c3d1976e2f63aa7921032dd495f273c0f2c756421cbafb2f905993de02d9f341d301455287e7ea4fa89bfe684dce9fee14b330ceda7e57ff4e94a1c71b0a466888fcad33f65014e767bbf2c01fa503d6fbdc5a55685a3e684dce9fe317faa72e3c68905f1034a5c2079f89b4a7b1f7f4e6e5e59ea0a8c364edc3d93f86089e3c3b16445c9d3a5b80961d917653c1a4e01a5637a32ccc9e4f14e65199d39a1d479e5ff61a556143fc5125738fcddab31965541f331ecd2551ce84faa3fdfff6753011b359cdca43f58eaf90843cf50daf9d47bbe7dc8b23405c70c272d820f2cf13ec2916f9e7b7532f1ea4555c5bdc778c8ec133d27ce079438b6184bc00a3fbd34b079ac8f93b5f0cba5a08f57273baf702e95cc5973d2ff74f1b0a5313e322b85117e4304bd630f8993c9c6374b3b9ffacfb70f7356bab2c73ab1cb2c37de2f834ead43a9e02a5ad339f83c95b30c99ce3593ac5730b7109b5c4a39636c52e2fc953b8d8c159c7c40aad89a9bd534bd3b075104bff917bec04d6288e7bcbee66129083968d9b971c25de1336ab77c1baec3aaf45ba01c533a0805312a4646535fb6f4bb2b6a48839029b4459f2fa8cf08b1d622f43916694504f49751e47b2a2cbcc39d0af25c09a035637e6d2d8ad179886e588389a92e49550a95e1cff1f9fa0c465f65336410f9d979981d9c351ca8391fa1e5449ce55928e883236d65f60d009d243a139891a1305e218daab4cd6b84e535cac8cb9313889c5a833f271b2aeb6ccec99e7a48902fa3f8069f8df22e2594a1186f0e6c44b6f2c7283c569ea740e3b9f965c6b89225e691a366ccba2b965e768c2361fc9cd6df1fb232523cbad9632f80a59598eacffc8878a90a23455179051ab769854eb01007a5d1f629c9e9b4475fa3caeb6670557e843935ae4778dcf89c666beeea00189c54e8e3a70dbee1b3e2566df6fe0bc10811b7105d659d47b6ad14510ca542501af59801162c72b2280f4f921a0bd69fefcf3f63f0f88e245956f67a6443f3263c8be913a7c6d404da48ca97a0bf7ee6abd64120d56d8bec13d82cfcaa4004f934b6ea7a0bc119d30b91087356d1dafdcc492e1659ec0a2bd5e1c475803ebbafd4f9db29ec67da0451d8be454cc28a94e7987ccb9624162e23084e5a4b36e9956abc1b826a2a16e83ff40a0c278552eaf6ae88bcc9644e7d64b982aea997b8bd62d2c9d3585fb6cb61e9325e0def785acb678bc048bacb74e84b6955ed9aac81e0c547ce06ee14d3d2da0b84d44d6ad2a3218cf87876af09b734e3c6cc907c30b66e0ce17208b882ff0b6384229c1cc35259c6ff7238a2d7c31dea5fdeecb6340487c0d29e490e208a5540634c23338e01999b77e4e0d38a247e60192387e7fb66343cb2f79a89efa645def7a641672be2d1e230b8e20178a317f6cf02d8ae50d8db07a670846d37b1ae09df889d11206a678e2bfccdbac5a0c3814102c84773df043f141c76d85203c025e42339d2a020f43f854405ec284e6aab1acb2ec46ac8c6b1b3ddf0f02da83305c9477597fac751a4d5acff13b4c65ae1428a590a76c920871d24ff1f0d76a9d850db922ed21e204b435cbd26518411c3d6e4f311787040ea6a39828a003938132015819fb9466d3cb720f9d3421e0403a6fe24299ee08a3a4c5f8ad82a71c841a95acbf82b9ae84d4f96147d293977b80dd2750acf2935be331ff8a517e1e1823fb0c11c0d9cd5432c28b94d1eed377463996a0807861a68a70aeac6e8c0d20c21d760042e81a48a6a86170fe9b722184b6818da73072a2b15f3e6005dad252229ae214ec980c12bf614cfee5fc7777bae061db4a4c352a9bee02b0fd33932644df833d6e3455886d826eb5fe82a47cc71c65eca2e594d87bca9659eb5a8a754c74b927ce93752e2e522daee5a0daacf3512de983c3f70cc5bb7480f82ddeb0d80f28eb1f850dbb1ba7c1a63181dbc781a98fd20554f3c20fdb4de00804a916ef8080a6db7b01bedc3361bd8263321ea707d899f6b08fb0791de5cbca273782282209fe41fff535124a05376004f00ba4238584ec32f251334bab86375eef582721d4538a44a843545bd7098a0bb0ebad0cb1d1e3826d1f10691169f77c61c1b12eb683c749dac4c91a96bb18dcf71afa03fc8511ae611e00e8f472397dc7ede8b959b2e225c1ceb811ddf8edff74e7cfbba90079f706780803b142607f290d6e051813ced345610a6e1c1c7b4da4e162d060c38cec866f92b21f2c7b69cbb5245333420e0bbbb37b0aa1662e6a5fc81d4a2f68d216ba5f671c0a24da13608beca76a094e5c2f74608e41a97a820e1e378de5073b1238082984b8dd25da307665304f650586efaf37fae9de8c181c9c62232caf209bf322a2f9fd1a53c18ce53dd68ace9230832111358664d75a9e8229eaf7717841aa20150a008a1b3d556a1911c2d19b7f91fb11206fc52ec35b808c09f03f21479606c9b6a7733472bdc8cf2907441dc4e8d155ab026cd6a8ee5736a6d716559d84a53449bc3c58e02d3b9708cb9eaea0d7fc69ea52ee816e826baa86bab6bb0dc25e2bf9930e204369e4a21f208b366a98a51c9c1f68cddb29d35b77329127aefb1b7807a03c30239b27dcbbd40f299270e7c091cf5bb8caa81cdd79dde31df8bb92398e7a136a269fc205786f6c61894fe77ecab26023285cb0f8c46066eb9eef97641bbef707e669e7a4f7a4d3feaa3151a490cf401bb515f0eb73f42a842dd1572ef7172673bbdfdcf0b025c1849af38abeb8c5d54ef570f9d256f2b9cd90c08dfac6c2b6115cc0f5d2c64d383ca0eb54c23e1f1eb2bef842130c6093f58bd533b2147c6516a9dd813e5ef29a3b83f5bb91815ff15f2bb1314271cab0637cd0f3cc001de7e890d8a75bfad4fc1ef4f3a2ba6911dec3ec6e1a4487d0b761c2144aea12be720e8f5642a91c12e597fcca76e8b788bc3b5416d5ba451db5748e8af485eb884c6cd17061d61ff243aa3e6a37d5da9fccc7e74f67bb578247a08b071ef63b7952ca3e40979784220877a09d08a8c6e756905c836ab292e90bb9c4098de92d3e56e6ba2b3cedaf7f0f19bf17a42a599a626d69c44d2573b71297cfbd59decfc603ed29a3a6a2b2c2d7520e4f1055154b1e14055ea557eceaf38c3d6cb56875e027fb88fcd073fc97c9f60d8082726bde67c4610af24f7c21ff0840d005931d4a0e2c16af232f293fa00aa9dfd166cec107cf870faab86bca5ab1d43f1f2117d2dab02d67c900d1610e2ec5333ce260c2e48d925bf0f079bdde886acbea4c5da637bbb840274811cf26c7faf54be1db4a8fde65cbf4a92758e1822f4168b3d0ccc0345e1d09dba57f9d1bbd2f836dd80ee3afc80bae5e33c96286faec3c7a737e7e2feb52e5c8c82286fe2ea34ae106ab4bf163517d66f7aa188e6de54ea7eeb402d29ec95b004cf6c3bd326bd989a5b5d6f2517c4a4b5da3c2deb01e48454d512bf0dd86321b264a1fe74504612b36f69079c8c363a951573211470e6401836447430c245e8d6148da01326367b2058f3c374639676afb4e4ad5c9c5c5bfa03a873f5560857e409c367e8f5067bd8c7169a0ad0b7bf04503c009e99398ac56e8ec73b4f77037950de04a1b37a1bc4f3131e2174c8ce8038496e2a13f9ba07005e1484bc2184d448f590efd326bc3902893ce391ea6b21478be796782af78c01f8155adc48e746f09bdcbe346ae75bb234ecb80f6bb12d2b4f49bf8749132c430c87130227b880a86e2404cf692f281e4b37f213b5c9516066c02daf02038b21f27a07c5f747a68cc1f4f3791a7339fc9c975f820280e38bbfdd4ee54044cfc226c738022cd86728f5219773bd24ab827c3025065aabdfe86fa9fbadf1966fd7f32f4095a5918fd1c3d0e8f2826c6e6181f53ffa845e0e2ea97d18832c32d6b04e5719b2679dc1920a20297a2ea6e460e18bcb80adc74851ee850e9bb2c2d349368300a212aba0400cf12f649c67a7c6d0f61d45cef863a1bd04dd20051f6718b4eb45991223ce098d2bb341fdf09560d939760141c06dd919eea0578493aec0baa09ccf1d88acd6b0eb60cfa971214b661263618b162b25173474ae6b0ef9de5e388919b0a43c59a9a660b015837f4859d19be1560ce125e54441dacb863551b3aa7db6fd9b050d2388f943caf045333795a643947399726457ca46249f239fca0dbb3fa23b6881975393a40b3d15263e0301c9e0ace32d1b52b31443305f1f18f2450009a67b7bc8520dc534af5a49cb22a6a0b20a1b50c4c79552b905cbbf6ba9dcfa85679480a77e61f1dbc5d8574f3b233e091a866810b5b5359431f8681efa87015d540abe69a481704b2b604b4a7e0ab872b6bec5d6af119d863c273c1171f687a8eba551b0e23ff259633af5047e33123fa231f689743a639493c447ef4f1350c3723bd9e79b7e9a013c5b70b5b700cbe58215ff1604cff138383c9f83e79537e840ca36dec21e241adf34d04b5da8d1959d0462ed6f1215b898f9c1ebba78f1ba2596fc5851fbb6ec924ec2f99104933a7710edd90b5c9311562c026138acd74222e9119ea24bb08c7fcbe6544a96b6779032e3254c68725239f83ace4438e8220290fc70a31bb4fb7a4988e79c61a366a5a9f76df77563329d09731e7b4d63a19ddd2aa9e2cff2354a7225db970c3b2073219323cebad2aec72d8a8177d16c8f86698f30d2730014263c19f8a4e1405f25ca573797093c87a46c2d57979660bebb78fbc3b8b079eef5c3272feee8a6809b625d0bfcfc399119d48b384375347322ffbbd4a7ca81eb13136b05d30a63b30a26d6126298ffc89bb9014dadc2298732229cf9521b45ad32f917539abd144f620e0b2d8f4c3abcb76723e67cf72aee3c3afc9467aaccafd7e74f40ccd9a98c883cc0320b10734ea91be78586c9009158227e0973d28af5491d95f9f4d53f7a9ae729e57d3ed0d64750b4b8c2392557e473f212c281fb077d861f4009e90a7c0425c4a07b7d589cb7c7dd0b26c9fd50147fe96a1d9e09a68d6921581993598f8ac4a443217064768e1e8aad8b03f9e3691c83767b60eb2acf208d0f3a8f848740b90dffc319dc3b2f24dff738cb6bec8d7e994c5a3d083778fe5c90249b997310a36eb656d76e1db2db93cc3ca524639f52bec2b55061d61ce2d43a1ed187c6f6271c238cb830ba95e986a22ab55f4da82c2e87f76c11f5f065ec1a5081ad62eb2484daf60bfe46a932ec15940b4d1d6246251e14634d9920811166e98738074c28f34217873914dc913c86dbeb91069f10cabdcd3cc94ebe9f7436c6644f2561ec3042cdbb1d37b252d02a3c7f47756654ea84d666a614a2a05610219cf09e9ed2b13d801b0d629b9f447c81dbf4ed86e5441f254b523f9ed93f416908d89afd296c43b4de045ee36ae36cd69c40ca71d73adb7c2720ddb0741e290c87258e4151ac923a4d332fa16e5164636106171d38639cd1ad65160930ba5b0bd1a6ed73952db680eb85f313d1389b0877b0eccba71009a3818cfbbfb4115d75a5b422ecd0923c6c20851d8fdcccfae59b5f188176e7213dd84e4e56ea347d8f8e6e776dcc6acd72d1d4d99b343eb4adc71a50ee22778ee5876908e60159de5b343110b08b3c56ac2c8c8a688400fc4372bed0b7f652162ce5e7a0304428b0bed1021e5865d7b1647f57514afbf9ba0d7133c23c99c34322375d2867c4bf3026517006fb6abe1e66d00c5a4a6a2df7d95340f5636ad934abb505912ad8f5f5ff4852745c1527c50415309c184016293d04cdc31af7dc7c2c148fd401d0636ab9ab2f287f1f4e4f84d405c4d474cce9189f8982c00e2529349177266ee53b02e4b52273773bee56379b1d7855a4b50a90ff3b48add3831fd124ae6514a789da25f200346a0b0fd50fd9ad5f3e838edef6137b10356f459590a0fd6d977639937434920d8d3fb3d9b49d569933579992382a6cb0f603d86b5f95412d4d8fe286194b9822af40825b861341a4426173d93b1e3f493afadc02eaf33e8c133a67912e5b665b62fb833322e6351c411b9aa2500e91b4f1900e59aba51e546d5a15e67470b6e3f4623d03fdd0a7f7bd05ad31cabbc329dfc88170a7da97e4522062216f28ef19c93b8024ebc99745a2f846a9aa5a9738237e898598f5593c2a1711daab78bbbb49ccf2214b041746e6143d6c0f2e51ef2f63d1e8f9ae3ff5bdf4f7f07448e45765e5e458f4f4713df088fb82e67dbcbf16e23e240cc17c2bb6c1ca1871a494902a7658922bc0f2b4e2cb2c32a6e71034e4cf67136e3fd35a22951fe5683b8c4bda7e2b5506bb7a4a1abe96725e39e685f9889ddcd012340c7b64da8a9c39b16e2c0370b342a6f6d864c63c47244d4623ca066eb2a648369ddaed5172f8df7c58d64586b91ad469873179f836e341e2ba9457fe2237bb66e1e8a6e6b95a068e0a28d24002669fbc667f170880fad33dc72f4b0a0008dcbf514254517b5d0bffa08ca1f92865b7735569fbd4053cc8a467050b56254787b493e73b2b291a5794c95dc66a7a3c3ab406b6b8e6b4f0f4028abc44bdb44c3df047a036f15839c6c016ba50ca7e04f0b7c228de843364df9db92f890914ca25d58ad4bdf715309bb4cb91d4022d413d4af71321ef256f6875dd34317eb547c7789a864baaace326196fb5bff96979ab2e693f23621aa2610f1fd705dcb6df6397e60aae9b655779c125267eb07e783981143ba059a91429c5233bd7fd62cd65eaff270aad67415cd7ce90e578c8255064b18fbf665642f0badb4d0c0cd4b666f356916acdd5f25384603584522080c667676e31950fe23996c15d3a12a0d670f4820236833513ad198ed22305e5ba3b148f8389722d122d909397f604f4998621ed5f6da5b6fa079502a9d103376e16ed454d1e8c7eb1db80696f578dbcd61c425b810df751c9ea8b5d3dba84a231c23b2beef89a06b7714022f3327b38157b3b49f5d2f2ac90f9432b11d7bf30c2cdba302cb460eeb47d328d866840acc118a37e96dcbd40a49ed6e8d881036acea16a06975fd204f99a07b4027ad29912d661df7c7443da106699fd52d4a73c362c3237f4760218a8594b26c91ba8d0404b26d18d0b438a425d14f01f7807fd319a34ce39c64acf7dd789457eedcc051a29f03ba1e94371ee4571a9d3d939e9281465d8bcde9e86c751f8738c0e143c7ebf65ad21f09e0e18e712b81f7732dc364f070906ba968cd25db71f347ec3d9eda165d846498445592a1a814ebb01a065e9829e87661b0ae1738e8cc09340007ca7d25edd9c8009cdc1642e2182358394f55a52bfd3d4a401e11d49d896092323fe341f78b87416e2ccea28996e5a18e2487db581e4ef96bb0a58b2ee47c26a7671956ca6a01e7806776e1051b496896c0ba1068b4aaf1e30d705f6c25ed46e794251d74c56ddabed67fa41f518930cb9972dd6a477faabbde0e69d90eb3bb9d092db1a00a3a9589bc840130fd34c45d257527d29dac1e676bee00bb6269b030b3bb0ddb7493dbf44f002b2132ffc7bed0af3e019a7844040cfe6217fc224d19cc19e838f4f84126aab8e7ffab854bfec275874a1ae58026f155d3a85e86738ff73798c38793136003c19d903d270048e2f5236157b7f21536d12e960466fdd9626fffbfe514ae211359996ad375b219de5f4b138857c99098cb45ef89e4d87fb67cd86682b9ce736fdf7421ebd11cca9f7e2f1bf70b710081f459548512fe49699e92d8c46feae84ef1785fafa352eea4fdf197521417e4d8430bc1018b9606b977ec058e1020077dea42830a0d090e19458811e9b2a35ef67bc40df70d72a57d3385255c98a30b3d3e554a4226566180a4e5376397b7005a9754cac2e81986c3260440ec871f6fab77a39e45c7ff28e81325ff30524aca58025972bd5e4b5dee89fb0746de30b98b4b3c2e8713138bf70230f22c8faa222f9d14ddde049d28730724cbcfc092408e2115e642082fe17b88cd24b3571402ea1c6db6fe65f6b1a2581496205978a500a2aa09924eff0a4063c0c41fbfae630f034c82e5a9005f90bddd0e18e3725e0ed6c924ac77c54166855d9abe32962a1f09ef6b4772b7e48703aa8ec133393c08390ed1f3af22fbc92b0ef79b88addf691ebdec2894aa3719c238827696bbaf79b66d973895ba260a26adda8a8f31e0ff501436240dceed94189b14d55e0e4d1b9ced679a45c788fbcf69abac59378abeadc95f2d9a155db296d7e6482e539656067cc2b2525827b9f781a89ec921d74b2db005d963031f18551dba53c5ba05609c43440f0ae6b2db92f759ee3716953699634c30c489ce34ab4df084bce47e3af9176b5f146abd3ba0a6e837011ef3891b6e14302a468744f17b35fec283117dfe559729881b45403f9b1a0985607fe144398232b13c74de25dc2e5be320dd5f163194162db2108f1dff823d71242057b572018fc20c69111d73836a9291573aeed200471d43bc13b069c78b6877cffd5aa6f109acd8ff417842f172fafc457924c42fc31e27e249faf50dea285a92e1326a54b5a1686b8cdc149d10bf613c7c5d9f95aa05bec095be6f37eba3aadbce7ca55fba21cdb6dc0367cca7390b4e200fb15ae1d68eeb104370531118bffb53857ef84d6501800656313bbd02ace3f936cd84e7d6db9a723bd4b205233ee71ced7ec72c6380849d25d2d1b18cf1abcb9fd30f5282e625ec5119b6a7e571112986145e9ce4c8ac239c285eac368f0915fd6b5e4ac6d35f409cbc02050163ac8ab6d121e128faebe0978c2d30661889eb2eb8cb472ce7b4b4b5098651c53cd62d77cb49df359ff5e3adf249be8793d52c3ea612ad0cfb42403ea7f168859308a69351d0049b4d61120f028c0e2c475a2940ca8d7c65416aeff140d8479bb2b081ae0302b62fc4b8cfa70e03a0c1c068e358cb87f116f60825ec7fc141b9d4204f446301f99f207dfaf5a137f5bdb7b77935b6e29a59401280864097a08667290503263a38a04ac8b9ef2caf8293306c6fbd240f738db3156a02ea7fb502377efbd63b6fe5eaebff7ee1a1a74c11b9335c6ea2b9792f2c2f83c0dbbf3a7be7ec3ca7cad8e8511036327ecc7958db0116c84cdb011765565238cc50b1b39ac85b02299053254c884594a7b63bd30f329afd7420f078f0748367edff7c9c239a519100443710b8f97442693c9c4911704004f7962068dfe9427260de9e1294fccd76c2449929cd19e7e15a3f535517c15751007b22622b5d52b8713786444e0915981f57c70ce7c6dcc171004b58c27a66b8c95312b8c01f2352ad3e1ecd6147af0588ad824020d5c130d1d0aae720c8ba1556794d5e9a64562b276db1118186480e1a205868916981c60b09af054a5481f07de7ac5f5b31c34e1a9a9e720572a016ec26f474bde0eec675771ff93f27aa135d5e53ec4093f9bd3e53edcef0b44fb94ee56f3f8b1ebb12a317dc9231662fc42c60a873587a7bc2f53be2801cb78707fe29e1ec9433e1ff8c6fd22e34b9595972d2a5c9355f612c78bd89f39309d824871676e031db5d84b16180f0d74df74b5e129cf4b112f4198e0dc45ec853936eebdba89c558b349d52f188cbf57031c52138b922675e992a7cbd89f351a4d2b705cd458659b1f3109b291f9be602d978b142b5b363d7371c14ae9dbd2c6c62408c43de571b9c105cb851886c28e5fed875f30c325ce5312dbde4bbc990295f44f9c7e3a527678cadb52e7f153de96387fda943001d2f295658b96193e6bf97399fce0b494d102f6a58f4ec8a9d76c478e438220f741a794d32931a170800448726c2c6bb62347aa693d966051beea0a353d96f7c6508279c4a7cb7b63c07a2c7569f3efda3a88623d9635db919ba5cd91723aad4d804024c750a61d87449a54973647cae99464d7da16a82e6df8da7a67c457afdc1179c4a7ad187d43883392ead2e648399d1253185619118e9069307f5e5d973647cad7c6e065f1daf2d6cbd908da0872c4386244384236428f0047e4119f53cfcd4c72346d3749974da68be22661bf4f3e6951ea5a0b46a4963ab5617921c2153b38705270952bbd2b5c5668d917006c38db911f394e89898445aa56664dba4420648e18a38eca9316a18e4aa0aca3b207d451019db879107482e7415047451b3de55d59e1f353de152e9a1ef156bdc31ffd67deeabea9a8af9df2aaa0f95a07bdf9eb62dd7444a635e5755c454cab9d5dd1b3e9e18a8ccf804c999ff2ac5cf9d04193ab488b34916340222586a71429747d33bdb373f7b22856b8bc6892b035df99e8d934f2f3e2be35e1df2708142859a4af9b0153ca0eff999457e54b33804e7996650e5b6ba37f35b048d55d9ce2576b2710a1acd33fc13fa9d056a1813fa5fe560cd427385c15252f72badc87b1ca112b9c14ac1b6b4755705489f1270e0b12bf28a5390ea36d2c6b4ec00c8248d50c160351003d67912a0882590a489f3f28c40964a50aeb859b3532b0e8534589d612e864cb8320cf899707c507c7131e0441262ab85a396add583b12f4a5dae88d8650b249d5992a08b7d689971796677a026610dc36b748726c589b6732344010890904410d52e9f220086a80cb4c5270fef0b53826284c52c6fee8298fca0aafe1298fcad69f39b06f10151a52c4665fbd224150a3e4f95a675504f50cc0c74c5fa5f6d36bafbd4e25719ba41d8455894f741b22a7b3eba39af6230b82742d9ad422912efa584973e6f5b1b5b666e055e27bf1ecf2a26cfde920b46b4a85c982f86278fde5f5da717afc3cdce4756cce4c13e153e8d7ac4fdb9814fd135de98ae276bd3180517e8ead89018cf2bac5e90d45c1f21e6bad084b9224d8f7913967046403586b29bedfa518638ab7b6d46add7baf8bb85d30c6780a0681ab6ef8d57507e5b5b592506bad52643259962c0cc3adeb3aac135451acf8abb5d68a71ad9f78bbc0c7188b96a7b5a634a96e19adf55aeb28a2fa2b59175f565f4fbf5e7c7dbdd07aded7d4531e94a93f69bc2761b0e3ef53b1c37afefcf0a658cafadf7510045d6bd0caf928d8d4d4940b8c41e092022b5fb27ee211d6fafd0e500b70e2b7b63ec1b7b45eab5405a1da3a43a416d70e3c3c06a4744c516cd48dba3da62838982cb1fadc539e0b61cfa4c813e029af053d633f7e91875f8fbd96fc019ef2bca6be09589322bc26622f7e754b654e7f24c9289b159e35c9eb8db7cfc813e28724698228c434746b95359225aac51629a4444e35b82886fbc4e5e31abac6d5f5c5503307e1f106adad15f6ab37dc1a6e3861b334847b56abf5999f759f3834cff243506a074288cf0ffe43cbe34fd0b50945e4207c35cffba163b2e9fe0d41d7a16babf52788ef89d33e9187a076f03af69da4bcd84f4ce4441e9a67bd1c7cc305b36aebbecddc691734855e3dc4aa22aae37dedd713d44e44234d1479dd50d5897c56649ef575cdad0c1de210bb1612da6714499a081d0a6b1fc913e387ee779f1a8b6409f26726fdfcb57ac56fcdfa9508eb4307491344d56d26e91cccd23798421e9ae0e844267d6b6591c0da1eaa435af4a1a15a75d532aa88b3bef68a9fe63307691b2a74eda4d35cac24e933d2dcba3e891e0e793545d743fb26f3ea9ecb3003af320a3f19755ffb8c7421b334b145a2ed33ea9eb5cbc4593ff2c498ed3ea3f0a9eb3e674eba25ddcaa822e8938ec91264d68fdfcbf2cb4e0f5e3c39f0a2286e8dbf497cbdad8c2a0198ab5522394c577038a62a18e398ac6ca0ab35ac981699215256ff5c366a2d68caeab5726849096575f0c8d6c2102f65759c173de5b51003abac0e01521f3965c51f7235365565f54b81aee6e54b59dd925082d28549c911136ab0a44031c4e34a19018bf4b903945c7519534e4002694c8c6960913eaf000b322c89a2c5904685b27e1aa0c52002e54335b5818b56e9018e6f3714d9174097f2c6804624ef0f906ed27dda53d2ffc0a66f12c5bd3645bee8698f8d9849e4439180199f7f4e97bebd43ba49f6694f597f57de24ea37145449286e299ce6ad7493ac7f9e8019e54db27489ab9ab7a7ad6bddb7a77b2362e54b9f7f1b04ae0db057fffe1e809644a640c8fe1de08cb2ff443714f56b9d2e89954c517e7b8a0b3b084b5cd7e6294cbfe4fb4207ae952faf90829d7c5d4ac02b654e0541d0c7d2820041a7252508d6ea60fcb5d1383bc68e339e401b3a4dbc8e74b5e942811677ec8c70644d921682c21e1484666cf32008964c4abc844bc7708838a1900315f99c8c9ce0d495c32985f23ee501ba01011220acaf11280b108f405b9f0305713252d27ff327cf9f37607427e0fe18f1e3c29f335645fe58f9e34524882e081faa196ad8bef4a7f96001b5909252d9248a85811f2dd0fce027881f238fd960ec87c7633f5b785c438794f42bc541c0e7cbc627071fad3f6d5f68aa3d8dbee829870d445fd3f05488f4b3a4d1fc9c3d9d40c8a99fe4906bd050abd7219396248d606656274731946970c357cf1cbebacddebebad450bd2894a140c9db4363cf1e1e58c79e365957c79e3056c71e2c58381d4774e8d8b3952bae8d7af2ec692103a703eb59a327ec4f5c933c5a60d83c535ee481429547c99f3930219f1e2c79c2e011444389049e37376c78bedc70d281c70a96930e0ce6f99127ebcfdc8e1c383c5932f0c0e30563043c27e0d9ba21e3af8f314c50820947e0f47a70697900943d2368c93023c4c797311a2ec660bc18a3aa9aed916105a9c60259eee0e14166861d49340801cf1e372da448d1f2854989849d3b2eecbcb9b2830646ef05a9e54bf2699045c98f332990f112010ba9d292c29617805ca1a3f58c5f96f0eb8c1a11060a7ac4e1f1e60915a016940d0c5763a6e88191a5048c9d2458764c50e1031bba187b8061e6825fc6f9bbf8de81f257e8ef884ddc1ec514b0028f8c215d5338bcf0ec5c1d408e083ce0b4b9e2076cc9edacc87d012b659851c24043d7e952037705250b7755e7080ddc15aed3e3cf5c3652e7c68b3a35a89caeea50ddb11abbc14268c27807c7e33b43ee9846e764a5879ef2e8c840670d17cee985aeccd56a3a73827c7478326c7b74a22acf1127d1a1a3029d227fe2d2ca706a81cb7d78aa41d828cdac4b2225156037bd4926e9593bcdac4b3313ba9266e8b4baa42dd0dab1197ace321fcdf22894edd12245dd77701b4dcde16113f32de7af68ecfe7507f0f92b76a7b0fe1cc92d3941ae9ca93bde9b3f8c33f3d72140c4c8595a3fcbeb35bfa2cd611ad0bc386151370436adf012f66ba62897f079fdd614fedd2a684f04db3123961d5d5e7396b8f13365880cd7d51db12f7764f0e812c70530c3117b53c769051139348680d9b8b174da3e0e0ab4710c911f5853cac8f1c2829ea5bccfda9f12bc0278ca8be302cea04aed1dfdd45aeb8daa6f377629f7c3a576cd9618c2723808de84bd09f367ee48296651a1947d5179e38257293ee5bd49e14fdb58e5842542fe1c9bac6cfd691bb1ecf873b4a570e34fdb3885c69fa36d05ac3f6d63d78b3f471bd71b167fdac61602fd39dab2f0f9d336ba80e7cfd1c6a5ce9fb6d10b9c3f479b94357fdac6af347f8e362664feb48d5bc4fc39da9080fd691b9f74e0cfd116c5ca9fb6112cca9fa3ad49f979fd691b9d2cf973b44149f2a76d4cd2f5e768eb80913f6de395227f8e362541feb48d5db6fe1c6d5a78fc691b59c0f1e7d8f4821bad1fad9b2caad18efa48c5e14c2d2bc6a6194c8a65c537cd509ee38fa695154d3394d6a935299515d482f88c7006bcf2faf5cf7393ff75ffebb566b244edf39d32ff3cbcf7f3e75aab8add7f0e9ed53120f55706b201e466ea4fdb1a3ebc3563d7de3bab8d4d7b4a99acee13ea7a7587ba7e6534820a6630676fc250178f57d308a890263c78707874f408831aee0346b60d99760b85661d3c901f916b59e550d68aacb8c1d00663cd01305a846d8d00088e20307a449842a3a5ca46d81876458819356eb8c040a200ae213ae6a440e76a47cf07fe92c5c79f307d786409538444869e1867ae005df16a8f8a913333b4a8d1228805b87c8159e9f9fa73430cd1043702a1b0429609417a1704a9d38351e38a8e3f61ca4140c664a18ac1220ad70362c0d123060923648d81f10146d045a3cc113660ba4c6831070715921e566ad4f9728db4b6a848c983644e9701783c7eec90c14b1e3a5e7a70a06b50381227ce951156644dd0b3b1a6cd9c2c3ab2807578c2820a2d64b893b5e78d01c64c8561632584333dba64ae376d90d8b0c282338856315205c38e232fbcacbce0c126a408a030535db0e294c0a5c58d205df4d0a1c1c5640200263e8e30f0e5042b429cf829b34304096964882226479a295b7a68c87205c9972871568c99f005cc980d1a6239dab8e9c00fb2ca70e1020f95979e370308240647a0155880e1444b8f210d4d90ccf011274a0c217642289205c78c1c62c464916199495d8dd0012e1673ba58397380291750c85123cd982157429a67889733488a8085a06343921472784d1149c18a95cd44acb2819664461b292bc431c1c7d71f357bd870c942634545688a0f8f408b313c884859c306cc07ad1a33ac80a4469127527ad89c0c92c2c29031557a4f3288c2e7ab0a989217b444f1f195a0a3cc95ae2654e808eac1c5470b3c364db4827cfdb019a8a2c42a899a11b2aa48cd10abbaa21a41498f0e141f9a466122d6820c2190996243d300116302551e2980d83cf971937ac142cc9dad15e8102961cb40c2571a2f5780c0718263421bcf8041f2c29229407248364576d40864670d1aaf1e46032873020c5c704a18244747d599de9b1e42d274357980035c584c413921ce9a315240ae6c2122468e9729515c0800131f454d7a928c4084aa6bcc0e231168c1841b6d50c81243d7b8a4294f0f18a888817dd1aab11a23ffd99c4e0776d50cf9efabbafc308861cb5a3538fecba07f6e7322e5e767eec3b7756ac26e1205cd516a2b89086150e8b3c29a3f4ba7ed3f3562ffa9a143fe931a61b6a684d4f15afa5af8effb7491927e4ea726cb71308ce1c110467f1df9ee77bfef9321e1ef437a2adad266851d27128df3d569755ddd362a19a21b820302e4cc9619ae4c822c6179d0ac10124c625b59ac881896ef86c8dd1c9a2b0d423ee8d27ce1325daed418a20296913020560c2a807932c38b491a2c609a2efa6ea519bb4af60c9fb1acd9a8102634603789ea124d180f0d9ac7b80629cb1a0669b26e12fd4fbf65b2213038337693e8df8b7b4aa1a46758f8ef29ef4cd79f38293f7ee8be7ab12d2346668e19126424603327dc9185adfbe97e2d325b54b0f4c1032e3a9fa231a337477edd8add1056ee37bfbeeb91d646e5251d3f5942e642e6595f48030f6ab85ecd53ea654f86d8b5a84b5c433e245ab36637072906e0454e8fdcc3007607bb73907e9d3991cf6a33dfe033df706b9a79cd675ef3a36d734a96e0e04ad6669e1afcac63509f7fd9ad596472e1cd418a22f7e0293a78111707296e5ee41db687bd3f28dabb22bf1d6dd0adf965134a4505830609fa5b1391874e54c4c15451bfee5b53e81b3cf40d5b4515f2d2894c15b529f49a875ed3b0a3eecb1ce9696ec36e0831300960b9c04dba5eb4775c298afcc8efd1ded5ac0a003fa9181d0bc09200bc7a9179e4d54c51e4477b677a911b993ba925a3232f720c8eb63fa06eddb6d32523a57b333fa85d198ca137c968d7afda657a911f7dad64be97fa4a367d0f3087aa9129b5b4cf99cb7675d285caddc1fd13e96966537ed20560d6005cc79955ec265d078059dfdca4ebe636e94d3a35f0e759c140f384aa3bea9e750c070e1c76cc83dfa31bc2e8e6b7c8afcf444a976e5ee54e6f523d3277475ee56eba91b933f22af70e451eac8adcaac8cd4defcdb42ada5c78aba8e0f1691f4a740a7643d8254bc0a05a54b074e41dfcdbd48bfcb6b33ada1f3ce074c9c83df868cd0ef28fac17eb486f882af7a3cfa6bb54974b3f00fdd7120b82f67e785179bf213eb8f99107a74e731dfc68fb91dffc2c3d28dda4eb1efcc8cfdc98a28de2265dcf804949978cfc03108cbcc39e32f2222f720f37f3c8d4a402e892116902ffb7cfaba28217ddcd16152c3de01e76d503de61d39b947d043707f63fbfedaa07dc688f550f78d1a6e38eba2f6e220f6c0f8adc2e09f7a96dd78bf6d9417ed765696f14bca188dc1cea73faf595b4808807f4265928221e18f9f775e447db66daa917b149bffe667a406fd2cdf4c0c8c54aa230da7aea8d767993be9e9225501479d1b69976eaef144d6a832d42227ed51ddb10aeb170231eeb4a97ac2bca33877d1879dbdbd27aeb1f282087884f551f919e0f1ed84570501f530a8203fb9f7f379bd466b2a97e6413bef7f2c05eb4db64f729f5d552ecd73f87fa76f974024c23b021d4daeba1f5b82308ace3226f5ddb51863f478cfdfcb010b548d422551c42982f187c9ebab6e4f7f9b5202a79c1f50f04c67e9b30d2f979bece81ef71935bbd4adaf381d5843f9cc90b8eaa04d633f9b4a23caa75027b6dce2e9c043905a25f6bbdf52d69dd4e6f47584fc79a1e8f29164e7e7a3b04b170f253abd9768ced78f3678d86531fa73d55ba040b75b90f62c62fa7cb7dd06d690a46c8181e5e991462c090a348eee5383286078f1d536d7e086231de293b106ac72498724c91253ead9fc4b838ba6e122df129dd21386620c124a6afc62103e3068c50e4fb7a225895b29d9b217703cb0d30124a37c46eb029b1eb1b61df8d333aa76b8008531e9a38ad2c5a5a66695d6275b1f6741879b18e79fede7b2dc677f772783dae1e8835f2de59590afd776da538cf6e4d1c3c0a3dad203d1b2b6459fd2e56d251a0f5e4af63a5eba78e826cbb4f3edd0d41226f2dafbf2142bf2466286998f7119f2312944a0e02edf789d00c32f006312983b5b5d4a7ca0b5a7d4e40624584a533a7e5826dd2d36af2d6b5236925a9c1c85f0d311a754c08753b663aa7311b367a36703cc6638f31761ad3444f7b3504d518fbb3c477ece8f247732f2bc7e78c8bb39ff666cc3083ce9f3814c0ca4fdf4c0347161135a34ece876994798c69a4798c31c6ba9cbb8c3a2739b6a75124a4a1c23f60afe8e48054c0cca09299c0d1c1994125c3c60c282c9cdcf46628717253abd98c9ef666f078fdb43743ebcf1a8d36b83c633d2cb1a75866e80c1d0c32ac704f06960e06dad31e16974031f8c4a0c2ca4295d37d705293eb614da91a9dd46010004f7b585b5f3eed6165fd894b410c27a6b360a526a1c44480337a960ce292e10b9a0d98308707902d2c2340ee7c7bc8718e2e4c9a215d183153b42e8c5507422b1664ba30faca2b84375853606e4fa5570c653dcb40994ccb340882206882aedd6e4d7e6ede9e30d487da6f6128f3a34b01d387325dbb6ebb5a6ba8ec18f3cab3fca3bf51f6f3b620b0b5db29c864c4271cf8816006f3f77ddf87b1fe4cd1494c591fdf5d5a24ca13bf7a30eefc898341055f0ce7de7bab29f594acf673e2e58a852b2460ec0b575d5727bcb1d545892d92904871a36982beee40598a55c416e7a7ecdabf5a6bcd97da3bfb2c98535624088ecadacd39677aefec73257babe06eba649cbedc7bedd4d4d454941df3e50b18a73060a5665222f1624608174cef45d51518415660f2c000033eed55d169a157c5c2d58fab21547854f1f1d5e388981120516408a9d3260a982b19e1150e7094334bf3a5e9879cce6aeb85112b2955e44ce942c7861b2448fae800b3070f9222564fbeab16e218278c55d767354587a9f2f2e4d35e15952b250c4fa97f92896ecdb3be95faec779fe33deb537ed182396576fa15ccd35e08605f710f86d708e7f195d763c7f7de9b7706434a3ffc0216374e59aee8ae9060aaeafac65c25268c8d24d1d3674d0a4b88c0f10143903e3aaa9c003a5243ebd830bed165a99a027b552f445d163e1810cea2f3d8c40696c5d409d9c83ee4ae19191b1995123079cccd8205ecb9e8a2cba2f157b18eaaab0a4b112b2c56583d2a1d3d174b7a5457403c964e5a7a54547fe67239877b54538f31c6383b61c9dbcd5bd9f983e5ce955e921796cef2eda0b773d2bc28e2048d0a76bacafcb4d7a2cf08070a0e8aaeb782cf0b3dedad705162fd61fdf5588085df1705cc26d106b408d3a089698b5e0b3aff7ddf57035860d9f0b4c722c67f4f7b2cacfeb415e9ad9872d1e78553133bbda9ae41507a536a623429e9db9ef6a6b4f4a6beb25c68a1850f3a0a046d05e242328805a7154aa1a7bc41415428cba7bc415a1020090a2488cf9f4840c49bfdd6b489e40d02d706d42f17f6dc8d3afd4b6f4f17db038839ef1d1738056eaeea79fbadf7f3fb5403e563a716c428ead067d92fcdc4fe912566b8745c96a318ca6cb596566f0d9a533d96355bc5fd679eb86a6a07c91263d6d8b3ed2bcdd3bfd41ace1a08a2a122afb9cdc922d3a6a3ee131d346890cdc4cf61039169b3486659d2489ad3669e7f34f18b269599f4c1efc3b6fad9d900875d87363d92a2d88fa0188632d9e7e0a8a194a34502829f9e7c3068d0202c38a9dc4067a784d413044160ff3006ea832e1a3549e02f0427ae50d8eb49c37c751416091cad0975dd82bbb71209a6263ac18c4e503feb41bf3d55076b387c4464eac1de90b19789df58431ff24f9b1e41583367aeaf8b66e9a159f31325664e9e68519764a336453dda7d4abdb84f8c7d1636c91c43cd5ce635f39c79e81acc73e6d987cc53ea8299cb662ed246902c714d4cc53c52b209f45b5da8f46b9ea45fed59932740d79b3c2173f2047671864d501a41986bfbf624faec9a54948de7dd43f5ba062702c913e0751c112b4a0b706acf4e249a34d7609e43fb94faa82a6442cdbc7e69429116483d8dc82cc913e01e77f52bcac6914e508394b44764eb3150bf249da4a054d2444996c015e3bf6f5fd729910315746c6aeaa3865ef41b35be7881e74045056f6904328fca1f9a1c841e954f48e0557878eda1a9a282af34029953d2490a825c426326a5a71402f18e778321798ba05a60ff3e08554a832579b57e5b8fc9b12150043de37befbd77e74a92266af9e6ec78cc82a89e7d244b644c96c0a41799a5e79aee86a0456ebb1d3dd0c12d6981cc56f7e9779f489ff729c17f2e8a325114c5286a248a32997b158d8cbc4e15217a8df270c2689ff6b42fc3631df62981d803fb441a73b44ff772dba72d8b4d57b473cebbda53830f35cb3c2a834e4aed6ead1703fa9374d084aa39089fafe8f84907afe33c7f9255ac39071274528fe592cca25a5df47abdee33f762f5d3ba11a3dfe76701be9235aff935ab79cab668bbc056bfdb779435aa456e0fcc88dc37345dcf9ef39c2a227bdd623e8f9c04bd66d24813b5e633f204b8c17d9f1278d81dc6ee03fbb6edce4e56ebb7a37df1935e9a943451fa58eb2e375c279a5d1fafd36ef6db3e734fba0665df1be53732e9cb7276b1cacc9c8d6ae49ccf0e92266a2e3a695e57ba4566e93653c83998a0d788cc994933a9ee8670ff24f853a7211cf24a9ad0a5d3cf8724404272bb4fb7919f06915c3354c90d15bacc6b9d2aa2965f362c37179e1a7ca82ecab6e8a7ccbaa82174d9c675ec0fed9b76d0b35fe07e12488084e46eb3956345c6649e3f3ce9a7061f9ee63392e6d54f6c91766952d204e950b47d56903c313ee9b5c8fd72bdfffcdba7061f729fc93d6e5ca74a901dd7a922281e1365611886a10cd7f98eaa0f0ab2e5fd69af843941bc3ef7b41704eb4b30f30478da23c148901f5f3be8737a4292f48450f58298e909d17af3fa85b259ba288a3350ac1b388420cdb1e3907e08d63716448803832128826005c10ad6d1417890925da15fb0466e5da1481f871cdca77db2b6cf28fba09f600541bca1481f1d74300cc11c8279fecc8e4d281aa85d04c1da5545808eeb9c1c6a1acd41acfd243df453d737a10ef729ee287b923bca3e080e35d1ce2810f44a5e30560ff7599f74d03ca3f06d74ec190441afd843af62a1d6279167ec3493469ad0349fe10afa49b46b18d418d71ae8501a8358147190e368d2274972a4553113340f3d9bd53598a20f6df06b7270d0ccf46b9745ca5e9ae158cb5ac7524d1591b396e91d7abe21ae8761c55b6799975e655eee9b769a67d0f348dba467179d8349a3ed330acf32b9c7aa06f4d145faa25735550415dfbc89bf2c93c95c26dbfa75de1a8e3cd978a2f1444347956cddf227adf21cc71a095a5b5b9884207acca37baa51d23fc747c2f930f263ce160f35628d235c2d62bbd72ed12f4c96b50c827b97f76e377a06fdf314420ebaf825fa6cd73171ef3e9acb66fe79ce2e7a0a0d9e7ddce0a3872091832e24e443bb7e098db2dde829b47f3e1bf299d3b290d35cc306a2dade6998cd2430baa6f99050b977b4bd1bf74e147df4998cdcbb5194e90fcca1cce952ce59a6c1fc6990aa16bc23529ca84b290df483cf5384bbdd2713fb44ff1ce7ece157e8e4ae63e1de61ae1433d7a0a7201dfbf779e82986fc73b18bc84597ed1435cf5ecabc74a15dbfee2eebbd03f76e173ac62e7a0ad0b1935b424efa6c57b09b34b477d9879c68d7f6ee730d7b37b477b3bd23c14809dc24ae14da4507f70ef4990bedbab5c34edbbb59b877bbafd04527378a1d570aede3de897ba7b4cb8b77fe647bec2bcb9613ebaa53a50603eb563ee91876baf46d2d06ee122c6f7d93be4db11d92aa56b710e90d01d21b02fbfdac3577dab3d714a0e7bd035da7b89ef72efbe59265d0efde9537c9eeb864ce8502ef5d5dc25c32a7648aebdfde5199b9d337e9665b0521fd58f396666d68922ed29cead2eda5f9e80ba0f93873d117307391f4d017407ae852370cb4cb7c017a5bd5a521a1d267a55755b03473d2a4b2aa4b33afaa6069c8c54b5e1f32b55f33c590ebbd237dc82f59c912a4f6a1bd1b32694ed27cc6759df4d9de913e64ea68e68eeb3a178a72efea529982e6427be729665eee1dd2d38bd2ba1d7d16ba3665db45b7e25251c1432d81f7eef346dd5cf5ed0e96ceec797700fe47e4eab4075aeff2267dbd884714da175097747993aade760abc225e29ad71d83492ee5693aaea924f52389c1da844acf76549ea948208000000042316000028100a08842291204792385bb60714800d81ba3a5444140923811cc7411083310cc4300c020c200018830832c84993560010c888823999fe157f5e5dfdbe04bc4d1661cfe86d00c4d34434681f1ccd230431bcc75314adca758d6be05d51e801904d9ea4b392175b54b05e5d54283fa78b77f8555f0a360fbe54afe8aabc4e0dd36ace4866a77978ba9d6ea9ab71d1468e9af14307ff7873a506ae5cdd1caa28aaf2301d7d289df50106050b89caa874e4b8e8f29cabdee768d0c4a56859825c88f9a8171b5e3330ee65f72663d8ff83dcbfe43bca0fc4fb1039b85adf13adfc160fe14da62d8a2f5c6cfe0e0e52c9e6e0c8c479065a045f641ec3525b8933962c1260d442fdcd759227560f1ad2eae72a75852188065c2a28765c7b8b0e515ee9e40e12e7071dc88425b67958b2ee7d98eabc83313e8686f1510e00b5e0a92e491146d6730d677708cb09768d526ad83f881a395be7afed71484d774a1fe404b11d4a92a1245179bdc491b5afef7d80e8c4453ed682f2c00c75afe2d18c559207a045a8517b389a5d5f1b0dd5fd8db89d9d12823feed4a7d62d5d9b9621502968061a7a604cbb269591baa23ad261054e612053103b26850ced7323e962bea3b8764ca6611d3eaaa04103308e3bae821c1b1f5729f1f96bc08baf03b34251c90898da4732596b61abdff155e8b3cd715b1922ec187f58a5c49bdf9cff8b092e61f494f875b92fa3ea13e5e417f7ab25283be8f070a632f28e81f598d20d08bdaacf9a6a6c5022373562ec33c415d6b3d4b5fee547d8a30d6a92e8636242ccbb60aa6dfaa9a52991f521065d1482f4802dc24523247a4358f3cbd9ae89219813ac3ddefe0e4c0e654074facb3a26e8ee08719d976437ec724075fb8c069b2dcc6cff0816ae3689433ba379a51c8152917a29e26317a0b52dc8782119b77f6b5d783377dd591374c307d4f0c41c367ac5ca40fee414499f109633f48394df1f082d18afa974a266b818bf567e0739668a2f0557a17ed02d3dbc69b155ac46f7467eca06911e77541d8e6cd15d5064f80613aa3fd2e7edb1b2673b6ad885dcc177a5d5ab3451eb971fb577d0c47f89c7b15f43f924314619a3a977271d8d9ea3a44ac307d218bceb55efd7f0464bd006c35244fcac360219dbd2150926e3fad649701f6313d3fb3e72810a0868b8b7720bd0441f2fb88e229a1b3c54a281039fc6397cfde52c9cd40082490113040f48e64ef489a595b099b79afdbfa612f9f30c3f9f73d6f39e1a66cc2ac94e1b0c007b0ddc90282f9d7273bf2e068192a3445f69f81d15c2995a1a9256bfb1304c7e1d2ce41ae4b6c23a07c08e2ba97109056a847c6a8ac5eb2b28fcf56fbfed41da3a6f6e3d21e1d08dcb7deaa759e256e9db7516555230ddb54a9ada989eacbbe65826de75a1ef9b42a793478f756e0dd7d8bcc1b7d72eb85f4d5882e8f0aa08ee72f88177043a4ed857248c55fa5831fa0947b2d647b5871a7cfe3ff376d23f52ee13d88f63d2da8632926f3a84beecb67ba66ff23c34d07480ec53f162665b04a27c109f10029f7209d6ffe2d72a7c90ad06024ba392596ad14d733ca13f0fb6348e4c2e4edbf4f4bbf3870019760bb5cb0e814070b5f9cd52da491b103660d88a7308fae60005470993fa06480497940aefc4044ac49df5776baf7af0818a1c150caf6cc7b7694cf639b10664f143de8fb41823c2b670e808c5a05cd408b2694339c0509655d8e5fe94908b716740ba6937c79ee2e3b8b5b385a58a1bf108ee34cdab7c0def36d65d534031dc3fb52c5bb13a8c85911f4be1b2ef7341ca8f6ab8bd9c2f7fa6610c933ca3439c159ade413ff63758e81e93dbf436bdced6befa7e6780cd0a65e3e334dca9c66a4ed01b529f92bf7b05198b99a2084fb166e8abb90e768f815b5b307d38f95db4694bff5b2fa0256b5e73356270939e06ac52fb4fe63d7f3e49b5e4e869240f80785b9da92a69896e18daf2daaf84c9b60fdc107ee527293b50ad5b95e213c85b291bc4850e645c44adc9c25568d0efc1e863e9087df44566471b9dbacfb20fd28034d5b886e723b019cb3e0ac9f4af968fc32995088982a19223c2d7a2dd339236c4d5a814ab02ecba304ed16621c9f159af0355e662d93383a58c67dc1559c387d93c3918c7a4fb86150d6263c48ed730339f0febb56bf820913004a46bcc404f4a4eb559054fb7ab77d4c130ef079a13a629870bfbdfc567e617400ea5ced037f3fe997591808f55f1f4dc0bfcad98193f448fc6f71fe84d819314a497e2eef0a9b3d96de8ac4ee998b1d8bd9747e83f3afc1f29beb5ab96fb25ad470b93fafe752c6e940ce9842971a1e8093c88a81a919b3b2c7a1cba435844a6b95a943b7fc21121f7cd0201a276a59fe94cc776397f731997a0096d5e1a7d5338050103b10d854ac2602eda101024d13facc3c994bd1865c2389e4e49c6c0e8b727f98237da6ba40fb2758a782151926c572f5c48772399fd918ad5d5cf97206e7f7901f3d8345758fcc36513ae1b92b13740f6b477bb91aa61c90f9cb2b9930a9ba9c6689925592549e7730dc6b60964ffa251e5f2a794269c49cf87d3d261abe3e01dc6a8d077811b61f0406d84509d64cc73dcd5b2ab0cc3705fc3dbbde56a207a9b4978eb4b4335a158dd0f4231d44bcabf2c4cb4c8381d47ce072aef75d14d47b76ef224e4f9d4239b87e8b019cfdda778380876783af519787f77ee88220cfb3201764f69d2a16347638500968991e5818a4376c3d5a9bc35cf2c4906311b136555eb8cef94e40c8db848f91f4b2f6737bc8ebfe920d72182aa43ee76b0007558a5f66ad4ee4245d85f0af8ea1299d4c8794399c3948d310986b4ed51032e04097dd001ff4745fe28659baec15a773686d239269015e61c801300bc7b47d692cb28b7d7de83e48942e75d0e660ecd59fd26520362972ebace1c28f7c11b2383ff82677f2922023a2487c9ba3cb6d9b11bebe514e09bff1beb572287750ed8bee28c84b7fc890d237fb7cea1a288e2b96cf9f1c217e079ef858a094eea750f42620ea736644ba0c78947c5ca07aec61de570437da366cab29f497014a6821b32ada8fcc597cefa933f25105bdce870abdf10f0a67d5e4b777f13c8af55f929eeefa1cc560cc0f7be536efea6e0f2c388185a22b3097047f7d262e1bf3cb9f9117528117e0b48831d7128929d2ec712e295b2cdf513c3ad818307a82a6ddf96920f9a0bd3e3572c3dba08af52f7e27cb7df6d7393c7fb9812e6c254f2ebdfa498a913334e4f285a5b228dbef0074f80bd812b31f7d5a26e6e496d9fe34aecf1c8fe6d4d3807aba3d9e3be5fc5bc688969850f88f2624ffbe77041aa4bc2c45920a6b4f0a4c4be2627970e54a48527fbb1676cf6fd07c4aadc8f7961b34c06e4444af130c85c9d83a5de1381f139b43d773582e673bc2721a0f9ef97c130357babcb6d30bcd387aed5928367950d86836414d90e530d862dce9919d7a405a237890e83e19789a340439c5af87e004f430935479201deaa7ed2560b111976624bfd1a9772440cdc86d549b1201786d3726322a0ca226c782ca5fbf9def9b314d95c42a8bea123e240a3b2003e2c24fe07530bff68981e2a7c46b2951d0d43bce91579f1b8aaf2755daf14a202b158db19a2cbeccc14e94d95d798be542fcd245cf54d199c86d19118046bd8cd5d2a3e023afe6219eebb359d75c3400954e3ba614c8be7f901fe2dd323c793c820ee28cda7639518c634b7bd725c4de379b476ca60145438b75a5c08e43b1c0373e4b394a5fb27b394815843c620f00d9efb22c96ea9f97891f2e45f587bb801887fd7e53f777ac8d7d0e6e368bb0183ee8f14016a87052bfc3e859bf890ac8d7c87adff081c543f64ae298adf8588d87782bb134a9b4e3b16cfc3934a82696896b1b7e3a1b747a83058f11070089ef5f0266d731e5b0f7bc8fe30c51653d19a133c022715a9f9da42a55d6add94ac9591b3b2b19115fd4d371ea10decb40b24398a95174e6c0125fbc38b19f9fd3947e63e28468a674800d63ac2d1147d0910c7090271d3639f80c3b2bd438027822f75b838702a2d03db71b8fd5d94a329a71166acc0694b50460f0f3d18655e4c0260caa19444b9bf732382fe4d18a47559aff60c3f6e6ccdef561100b99bad3c1e63f1061fb72d4fa182c4e5b5c7e52b7d8c4c1399d1ecded3064a2805477b6d6eb946686c2a0b9c8fc18bd2b5a30a8510e3c476236c9c220b5e858dbfc8539eb2114f6505cb115c0eb4f2ef6b5d6bf552c16b1a7835d71a9da095a289e704ad291b6be6d047ff1accf56c48b4a1d6c637b47f636d466c3e3333082e6e69880aa3bbf6d2f4e1483bd95dd692595790d8773ab558cd827fbcf3e385804f6627a4c201f952a2fd8daa69a85bcb41570a54e2af2736daa9148b6bd71b8831fc4445f63377d3add893653b260558e747627bb8db027be68039822d1c32e2b5fb611debad5f4f86a7b247505db015f0fddcbb42fa18629102339912740bf9fec8cd38aea8d3033ca657afef2825adbd59aad2898eb7029d61afa00d6518eacf124c59855faa17bc547198fb53d3b73f91919b98d6277fbd266f2ea71be66380012a9ab223d21108198ed60d90b6fe0550577b4cb63912a473d428695e93ef1b3dd1ff1606e974b847b6af9ccb20b30c4fc3520ce8feca1215a09f105357d300c325f40cca7f0654304f595a03dc9ce3c4fae39258e961ce536d04b95ecb271be25afb40a6b04978e54e49e62e41bba66015129ff7773ec98469dd75ac4d772039f1c99b9d4df20d67014dc586c8bbd17bb30d653cc85170383bd5cf289c6ccb353b05a818f0fbb841f0e72caa57dcb640dc18b8172f3e1c51934fa3a6233446561393d09e05c00ad0eaeca001a90a7eb1df6579b93b055af63b2c1b4a2acaaa89b97505570312417a5312420db26af57aceac3936bee04630d470f1a6ae0ac79dec35788c60eec592fdc49e2ddc84670521e9553f980973e782539d945cde352d7a721d57035d1395aa0f075154f1385dc4b1c683b8ae342cf07109e2352a7dc1e6c8ad739dab14d712f1ef34e56e164d3943d037ff4a13e1f0fdc386c6b7d3f66b617b4acefb9a3aa9317112d5283a540ed2fb0ec0cdf43c87dcdc2a0770b9ea6ce83d6d760c5483c01aeb8bd7acddd3ac0a98e8ab70c4c281d809c10b72055829d1cbd6fa937139a0eb6eb18a7e77c052d8fe3c51242c47d83a88b6171b890e694d73ca73d1256d22d01d00ac893ad8771695a4687cfe77f643d181fbd1f845d55e9b9a1b3328c7bacf0b63ed0987458276867463552086f5e2a2d6a1c055e30f69482ad2cec8a41d0238502a8da5d292a6c10fce44dc9f6968dec86b8204d21a8d2a2a6351d622f0fe1617d8164a79509082551e51118a1d1a54322c7b9bb50649610583abf4d1cbb9cb38e94c503a73601b0bde3516746a59f43bc870a4468f50ba40f91b33dda2a611712eca6e5b34b25b3c588964467ff93a769c96450d31a6a27b18b9bdbc3a3d01052d9d8212604f8078ad38daa23e7323d6264b5a776bdfeae81c0a4614af6dce689566e9550bbd5a1191fa6d403cf86766494d0eb85c17bccd3a4a8316899fb5755d0eb0e05411f7db889e565a15a14c03b508baeb9910e841b353a42117d0ef3665ff347b74dcc1563a21c39ee5aec6f64c61d98b184b189d465c9eeea7620faf6c80ab36c268c2c0987e8aaeb3b0836c1075ccca7f9aef7838620a0405e9c7a58e41556c40d01394f9a9e5dc87149285e546748df146adca4335bb22aa38f9c69fdc0a2499914a5c7b0f57ec5475298a443673c625530086a151b0668ad4ea69e2cf9c37852b18a084045aa36e0e7e211b3db2fc44cc5ec0867ba1ed3ad36ce4815b163263dd373add1fd9491ad2f6399204134f5ded1f00bb5e509070b2ae1a8c134e1e424d99098657db889031f5efb455ae40aaa78dd8d1b3d1c5ffbc23ae31573b16c747b27e65e59908c7a00e3cb8cb78d22f801f59569af70b01f205a8984635e8639e80a642f4c7ae1a9eadac36462043cdf0d5d4b89e76d42adc989198b8f692cbd89850ad4cc6d1689b1992a7dbf605a955b25592f6e5881a59cd7e07aeb484f6a54c1d24268d32480c91f3f92f38437162a3ae8091a9956d3887397b7dca223b748d8423ed499bb7d2905686d05d79d0e325b7cc97d5a56898b961d65dba916979ea1f900914b355dd588f0ce4927f82f7dcadd748b31bc2339d5da499e3e8004c51d871c35481419badb4b597df1656fb57e573b8e150d2921aa98b526e3133be578efc16b3bb2b4e5b88bcb2467e54d5700a07a4819133f68c837ccbab6c91d7c4003cf08f87eca6c85c95d9bdf218ef7a5e077ad199a103470dd8014697c5aa71d3d36fe9f27b1d4cdc0521838630a9ad82b3237b1548bc677c1e9b0fbd48183fcdc4c56bdf820b365a1c936c5907a15015341c693f9c755871dba50c8bba35b34ba3228da38eea5571035681d071c72d58000fe95f94374a0a82435ff5f4e3b9c22f88539a6ffd454e1d4645c6d02865160c932e43cb142ebe67567c007211fb8691245ad93a2425af571d4f80d695cb28afd156df853ecfa5bc96cd905e0f467d9d452a073a053799e129364a0f4d71e5437f7102f442838b5054d974b00c1c752dabdfbb0bdeaa33cd2e8578f80e4415d015326900a26e8c9e3c2872a821b5f827e49963c44a10d45585588364e486865fdfe7b3f3b65dd1b6e2425dfc8aa614d5e07db640a0b3e56e3ac1edb0cb119a69800db7e12d3a1412eef7a236de11d029fd788eb09da6e047d45e7fe145eddfb9a388a0ce64a41823e2bcc93a27b0447c182f7d52a990d6d20d8acb81b1c0d1ae8a9864fcb892be1a2ccc58e0bb481bd9a662e7e62de8218f2c0261b1001d436c2f2173b640e43b756473afea47a8da5e849afe962fe905e291138261a8aafdd0c336b80ac098a982b93ab5e1dac349a3c18b74533783da5c5f4ba6ae31884e8d9cdceb0bf311369c2ebe89777cd15f040cf3e117eebc244af350c9399b31a0697de370ebe338733c7689ac607260baa0b0c8bdd04ea2bb35f40cdc637303877b3fe27da076bf68ff59c668fa044cef8d635c82132dc34257b467916587ee1865a3ec20ae1b8ce1fb021f7dc6d217c71ed65140018ffae90b1932af1280dfcc4682d6184b57c7bcd5325cb787348107eed15e3bf38d6f59dad7bd2e6135b0921003402425fefc0dc4c845b4d99bd50f69fe0a499a646f184dfe645cfb48d4a07ae85710b40b71822ec42b860ba39227d957866d08915604ae98aa7f9ed7dcc54ecb10746d18bdcd8427fa15e9e580ac764b037e8f14b3bbe84872b48be10e355bc88c3ca48c703e227e41bd96afd2fba1d2ca5b561b2ad57e80a271321fba46e8015628396f46842dcd7934486c178b4cbb1e74689d1a7d563e7ebe571e0e15244c54d341368bc2b8a4e6890402ff4c533c73a509062d08067427090a99f4340456b7e93d207be6661d4cfb7017d28ac4e04b956325451893257e40bc603510240656f40038c7c4b289ec0b5363ca57c6c870bd1d1f4b22d9a12f1fc3cf09af0558e03dc5b310fa434a1cbc7e7a49acc0a75206ffa818bc9efe0e7abac983639b221d502d3da6279479ddcf8f28f6ccf524920d461ac69fd767845a1ee32a76a8ff8a9134d17f396c4b55c4cd4feb2273a878e8e2ccf24923e1966d571f58703bde5173ac33adbc132a5784133c6dfef1c853a0f54e5b68908b528030f897772d49a29c70979d79b932ce930238cad324e6c41aa995b88ff29dae8addfcaba961bd81a60b9218ba0aef7b87613fba903955d04f707e3e8901eb4fe16cf794678f89209d5eb7c8667afa41e5a359479e6dbdcd95869d3309c13c5d458fed2e2573f67601e0b9a3606884d3b2174094cba46ea4f2a18925abe35110f37afdb1659fe5a54595398031d3e2226e51c88ba766471195c8f1793be49399042b0203b143050a6eacfe9d07c48a82c18d31d2ae697ed996c5e9e622d6741f7799e6eb9292189ebf24afd26469462e631241274827803502c61ce1c674f06a89a0eeee00605514ac212d0410704605c60aa078727432b8c2d594c686cf8d32bfae40748c171be15ca541a8c15b4ad92f95673c154ce2c01180758f0704f534487356efb5ba5c352f3245ae098ba786e60089813d99061437a0f42f244a9b75d5278056405da75bbe0e81aa3aefd38c730548e49e066237e371be07c5a530d57d5ad2296feed6d50c3eddb3628c5f3d0d3e6e9c37008c222d30e71d798800546159f86e9826534fb33668a8a3e3aaaac1df46bcc3f44ffea1f1bd286650da5a4c8eed44c9438b70a588747a8be72311f13f6ca285194a6d28fff9d5fa158fc49c031a45ae7366b46e25330d394c9e64ac0f23bdff69cb3ea3301b93883eda59874b6e263110bad2bd34949df619a143c7d4cf0302f5432df81482e484a922ca11c26119a99b78ffd6dc77c8216bcff215e9140595ba4aa86cc15001d96fb5e583f89407a3434bfa564eb7ac694c1a545aa19749b7367f3c947580657273309a51d9bfdf780d06212421d0a23ac52adcb6ecfae4f87104b47c51d39ccca207a6f5177fcd1044736d81d407aa6dc097dff86a7d46d07f15b78ad1a72f0e515047a89d0842a018aafb99093deaf2920a296ad65b217dd49b32cd09b59ba0a916df86a1edca5cd02bf83c58d3de35e09bb1b76c8b2a23db734ec07078301c4920141884604e0809a8cd6de4a0c6c8612f90f21341066967076dc8d4f84137c2a87eca59458b8c813c4275836d4955070b191729f9915c04b3d6ea88e8182f8941c9561981c8bb77ce9c5c166a5f6ed369d1cd5dfb43cf383aa119c86177ac4e376ec6e5272219ff3387beee9a15f20322c4c1916b015384249d9472cbf40d8b041ee268d8af755cd98f4956fb508414a717de845bc015e8794da0e062c585b05451b4f9f83cd5c56c694b888faee81c369171189d6cf087de5ad214ad8fc3325ad0793fe7c510848671a44b6e45fc8842cd15c017bf2512be78c74dbde4117b5c867d6e434bb4347c6d9dca13c9a725c361e93f79e54772c436aa60c4459112d0d1256490941b5a930950c243e412a41c1ff9110e5e90e01d063732f92c8b7b79667893f7034e1d4ede9f891492fac80ca5cde874e29dcc35425dfd1c8256f3e4079076ef956b8a52cde6fc783382ea383071a61a616769c204232282a39cd5ce1ea042e50f2fd4b53ee7e3483628d15bed17844a9904203230eeb6daa967108f804bc49c3ce0719a132dbbd33f3d5bdb0ceb35537d935bbd9d2e23bdba7b4ecc3c4141de1fe49c4d023c6eb75f8ffedbf27668d1572dcf1c12e087f90502d48c097a6bccc737fc059b4a1843fc14de5a71553bb5a15896f1a862624936649d6715d1e8e061df387b1f61410f2adf09f1a83618053ed1fbb0b749beb6a0874ab7efb16403076e3c5c99a3a3228c1a1479a9b3e26745f13e92112541415abae461be42f32ea4c304faad5187a5f455283b42876c172c62fd9af4bb1cf70fd321a14a3273bc8f3e8ee5b9e25f3ce9f29f09e9b2095057bf5273c34f35b74062c1051cbb17f99e72c7433208ad652ab4376d96e49c228f6ced5373070c7823cacb6df851b02d2f6140a022aec492da18bf70f8a154086d1b7507d8be58b232660b94f552eb9666fec61e511a5fe4188d53e60328252657117a3138afb62029859cf0f385291519513f238b06130b36ac3db68673cb087d2c083b8834578eeacfc75aad78d163358a065cfe09fede0df4b4e0abca15b00d230fc1cd508ee22baa2b2f176e165adfdd7cedf82095a0ece6a2514dae0e328071c6020e1848c84bff1e7cf0d0421a0a03e3ba7ba97c2ceeee761a933e3de4ceb3af17d0753eda2779ab6638775158642aaef1e8149327922d772df067b8398a7295475ad6acdbcf57d679bce3f4d3ffdad43b68bcc04f3ef8d88b3a5ae1f38a4e205e0b61ac3416ceb3bb6c280d7368f6677cbf74cc70b4b3d238b9f3ccfc13312375cf75520d245c7f11abf3f6a95fea7cde28b040e1e20b43f41ce81a74e80df72666fa379fc775a1c90217c7ce2e9c4f45c018c1711b0a06f778a5a84034a55d3a01da31999baceadc1f220706c80785eba89e8b7dcb319698607b739b4af588dc2976c43d4bbdc4abfb168bb4f3de14ea1a6a03134405b80f74467c0b942fa56fc2f53d1da76d10b3ec20ce6696cdb2a316bf0a62af6deb5d8ba8001ab064d2a158ab69723e1c44e3f5323fd9c7edfa1af1b2eda7d496f9ab86aa8c0f2eea9b5a9a80fffe8ddddc384f1f76c3288b589058a64fdf39541802e3e6069c0550d10a90a16e378eac1ff93349638421e0c60ce94a942a7af7ab9b8131ac10624c958a8895b3d1b753f5198770c63fa78db2222eb86b682f4036085dda9484a80b68c891ded1e3ae670d69109c4667b0691ed2b4c703dd529032de0a197c08c8b998078e6c74db4c694a46f6313326fb00a1f161c4605fa153469f40edf53452868ce0c19b22ed615512d82f021c3b520dfd5a627dbc9bfaf900c52676a40c79ea33498dc252a6558d8f59b0f9ca9c8e0d127f41212dc7d3ca55f76e8c471b78a08a2a6039705877df38621d1b61ce14e7aad45ecccbab09ddf2611b0d36272fa0a4bc72c9978a997669b93e400eab650d47df02aab5ca6ca3f97e19f7df505cea1ae2bbc1f3ee4bebc8614b5cc360e1615f71ab24dddd737ca82384af029b399ce3a62a56ad7c1d560abc6cf76a5a36a36249a37b027f1924201fc4f7b99953f1c7cf4537306b5ce8c25f77d5bbbefd9ff5004f2047a63e7f4ace3d4a4e04d947eb49181fe4278cf3e293ac54ac67f02011780473c7e6c80697666662c7f731be4962fd8e00710b61dd3d06283baaa91c1d835a387b908fe429fd960431c2d2483133f7208ca01d729a19da6c097f088cc6f385d79680c351dd0010556f8e98d346f131ad96c5de97d9ca2f2fa2df2f07bdded4917e83768bf2d20ea2b02dec55ca152fa4eb152158e68c28bda60effc2ace7a9d1372c4802cea25d78855665e5acc56a2dc9dda6b87a81e2dbb32824e2f8af61591cece25a846f493cf92cbda3c49f241f502debd85952f39650f10eebc0635854359fedc0abdb7c6decd364e1e8f6c89754f2116e848b29abe39cd4406f915783e2224d5f2b72e0ad94a9db41ff923f9766ec14bce715e677c8bd7e66c4b13fc16933b334a9cff0fe200b378fec47ea086fa87e4b84a7b61714dc1c29bb28e064316a7f6844f04b8c3233466a176fd9b57b4e672384a5eb9ca8dba2c8822151bb38d42fbdb1001c84cfb090a517eae92cc5e203f9a4d3dac246c15b2a4a3e5db9a8279dc8690ba6144f345a778df40028d3d1681111ace433644701cbbf8966e7a32f1ac058cb8af2eb1652741d0d2f9f8abcb95697bee42c49a455e65117b99c9641047755e6a2b4ec072177dd4b352a430fd2dbdcf89a7e5774d31b42ff654417011bc3ad7e586a2cd62bff5f182023e2125b5c64346b208ecbba0121d5e81def317f2657caaad870add1dd9f52aa86c5dbf1525c6508550488fcd0b602969087116010a98e87679bf22f41f4500ecc08621e97d124df2bc92a48525d37c50e4ccdecf5eb4a08dee3af6aba6caa3cf0f9fb13483d16fbc26ca63b062a7c954f4f6d64f43a4196bce635704adfb9aa7ed77f752e513ce43535cdccc4765166b016f5b9054ce91652e1f12b37f65a883ee0161f67ca1daa3a8ce4f9a983f6dd9a617ea52aff8fad3d7172d8c37f3a03438e1afaaf57794fc86f9d0f4fccd1c564bc7e7b78ce9c0240c751624508979d086edb6acd7d814581a4e2fe75b677c556e23451dfff67f36af9f4aeb56c92846aa0e585f696dccc8633ca82456548086c0d7b8bf2c91c39bdaaf385b2ad8304f06b739267bf8bebc0ee7db2168643b74feef4b3735b0c5920dac8796f8bf01c9f8816f78a1da42ae8e7c20957ba05c7cffcf9c8c401f2d00f392c5adce9cdac857a1a21c94bae37c4333dc32b3e804ede35db817b05cacf3ce1f5d816f444edee4760c8b5ad0f10dceddd143e7e2e17968266bbb6723df8ba4f0d8ebf045ca6577a3992ac012aeea57f80fc89ed661084aecc9e808e280c52ca209a5cad02d790a404b9eb13aa008e6330cb2d5206701b642d03c5260e8d6300906f6746fe299bd3df757dc14a76b8a42e6e54d93ba8f4a08294c37950e4c22bdcd1bac1a06ea3d182388138a1a261194a50fea5eef04e3ac6c5f63d4afc9828d26a17323f7f19b7828273b507d7103366957f1b651c9e1566fe9b84861bb5d67549b25f2fdf822599df055d72f3cc46adba3d0cf3264c81947cd6fcf8c7cf74a2761b5356753359060a80462aab8502582752dd7c8091e2ac188f85e661c7c4221a2ba829362b77e6859b6c9eb2552971a7e1ce36c7c706ee400d3caa5b8da13449d08f63e2304e9ed613d3c26f8f730b509e96ffddd2652d74e1f0864d7e9c9021b00aac13aba7929c5dfda6a9b4a5fcd22f2cd474dc1816e985632188b0aa1057107cb45a63b6a87024e30a55255ba1ce4123b573ae9b15d9df47b2009edd1088645635912ecb56b6b658d2d709c658e4d42fd5b4e09b7d9725a9af014884183cc58313669b9d1734a215c2d8b256b06b3ff75a6a7e0c38451799673980e4047d94158896c062238eda717163b546626ceeb53e38c325df3cb9632b5e9d1833fa1b7b95007504523c65f5f251aa9dc970abbdd9f769799d933b7dca120b28964cbbfcd903bda0439b1a0cb15dc914d8b6e99c9608936103097a0d155afb037b41018d12f1ce08646b9318ac0aeeb786ce5ac0df416a0e512422f98c7f2997239395e0ee04b5d166fe574a8295de01c10095eaff37818b016e4f8bc394ec31d0c3fc9f288a62002890adeceac6762acad7f45e622b05557b9a3a249476956594f302192d59d9f02ba513eff50025b27dd12e4a826774f3049a68cc5a4f7dfb21353ea20fcf01fb2c873d4e66f827237174caa6dc4ab93b66a7195988f177e3be4aa0e1b89f116fcfc94aebd149e1b4c35ef77bef85a616ef9a3eff5ecb5764ff2eeaf22c4900feb3466b9ee0c4cceff8b02cbe61516b15dee802b9bf0f1654c1d88adcb0cbd6193009cc8710370d285c8a7b34c297cfa4c0a750830b87104c52888d7f71257ad360841b7cca803a3ee09d25b1f9d0b88178d788fec8e14b2569a5ba8fe19a82f24236793b93e2ad8bcbe7dccd5263f04ec39e424c338df56585f7db4f695900b0dd32a4aad812be24b111e5c67888c1fcc63e8834bd85b7b129b291faf8f479486a5438b1ccd4a2d5c80209eeaffcfaac00a5ad009aad1c864623ef160b62b430cb7109888b9a5646eae7c6f9ab635b58fe4791cc2643408c8c9083a6153f83edfb3edd2740e9754d7fcbf8ec9becd0fc204086ce6697499874306c5852d4988e88840197c929ed3111f61d945812a9f705dfde281f3c5213000331c32e148305c847d019950b873d732b005ca4a7d9faa1a7b682c475bb2105a00a2e502f5f1ba93db6a816e328fed80236198da274243ab6c46f3d453d243dad0f8341526d53d476c9652f16b6a2d4978ab4b7d52e8c723c75e1ba882b2cb9528059b44be37c37060f21186e166e2f14bbb883b588ffa55e99bb2225ab0a436ba994e8d95e488b18dd3c4b9e9904c6378b211cdd6ad96cbfc1232deee920fb2ac6645120b81c93afbcf749dea6380b923af7735ade5b44552d6604d92b280bc61f33a207f4f15bc2a6da8269709067e0d1f5d644a647a47738b39ccfc5432a2a719d6594e8bc15fd16e323325c670844749e5210dbf3085eaa4c5afc709850b323e8253c5c92a594c96cb9daac22adb9542aa3ab334802eb3671a7abc9313105108a7f8ea16113c22dd3ba953f42d4afe9179f49c51d1b2ad423acfda2fe685e3083b6423272436e338706f03c6d487bb8835a628ab109ca6a1413b20f4453084cba8137e8bce9c324fa3743a70f6844416c031e438f008cab59b174938a19e27dc5706aee6b726c91cf526e36d6d81fa506294b23f7df28aaccf0b21d172f13f0e7c0d485570f11c6d0463e0ec6ea950b2be0f281401d6cd71152a4f12199a097516dbf1281ce2753f8a85663e65ba65d3a1e0264e02f51a15d24c315bad0caa8960e887546e5950d6fbd69eb25c25519ef23fbca55a7df1ac2fc6e81517027c8e79f81f1ab4ad1b0be1f94eb9478126b52034f19b97a03ab85255f34878245de2d02483380e577b0ccde72ca56e5e86e6f5be6fece73d630359926f99f90d0590739aefcd81ead1774f2f1bd00d9390bb0ab7e1343617f9ac4564941618271bb3b821b3f96b00d6f40afe0d3c26177ed4d994448f9422844059d0c8818e36d83b7654a8e27cf17e9de7afa4245ed315d8c161a65b594055671c7be538e91498319a8a71e180d7699979364af1310e67a93c9a3f366afc80d39fc98e90c0e7f53e9547a7ad9d60e0aaf384f39a67c4e1fe3adb8c7fb14e7ca1892276edc244e42525e58594f2176cb851de9b7c0be60af224ae2b1c1533a781d481e8a85f64542aad246566ab8235d3093901fb8cbd3b2dd5bfd1f175919d28dbcb0c79efcee67da0dd3ae11fc9a808186606f68c77a3034500c0d6d8120ac7e283198adce81e57e631d830266eb102433bdb6c26c753475e004806a3c0bee01a56605660bdae593744e4e6e48c50e8e25333e516bb2d99422cbf88937d69fe8819790bb0e691806b0c1fb9dac5092451a50cbc69549123ae234ab5af738bf98ed4e51738419e954e5078b0bfd7fd66a0839828c2e923fe535e5ce5f5d87f4dd6dc4f6b8662a18c01ee0bd353c9ffd16aa9b940b02a6bb3725372aa0297c9f7d512ee23d6adb851232ab61ca51e72fda32e44e78a18557b862867a79c4db59aff68b190cd6d89af743beed7de80907427dda40e927aa177eb00bcabcd08f1a045cf784ff43670342b217ad00161a984d5344f0c4e568b30a2090208e5f2bb6cb0d47f167c924fa842139918cd75b935e55184ac593e528aa656bb22999a60870a940b7a8473f60feb4a4bfc589699902c549919d845bfaa04373a8873c429e27a6cc8710e5c06ae4a1c2f85025dca81a420e5a98830ccb629cfc10791eb8521e521407ab818f14e247a9f29895b4f83d8a70609c684cad3667cdb74966b2abdbc96a081cce531f4886db3ef2cda260ba7b97d565fa07348f353063b5522a6c71d114d175f92a7a7112cf9cdcf745880f13d0f99676b597665d3b4f85aef8cd59cbda4055bc82cd0cbb9c47aa581624b3acef0e3b7dfd71a9408c0f80edd32b72613e60a5276bf6a58d6167ee857471a6c997b8e1516cb36967e73874bc15388a4fcde4495e71eabe7975a84d6d4c29de253314b6a794d0c8ac53abf184127bbb50a77ba7bc804aaa23f60235dbef854087f74c92bf9807d611c4aa9c6a5616b68327637ad5227498b35ae9731a6b46aafc3968aeaaeecc95d5ae0f660e202ae08be94dc6fd1ce0bd3516696f33c6a82026fe9bac24ff31983855d2819bacbe52f734aa09051fb1d42ae9cdcf1568c607ae89d4fe9d9b63701e09b0ce8587cc7362082b907be195686d91c69159b595d49ccd625a21c0c1fa6dba4f756dc89329c8a38b01ac96e2694e24e7a68156e3e97f32f8b0e9ca5090107a97108e0404e20ba26cc94a5843cc5f178e8448813774587e2d9fe5c7f25d3f56dfe5b37e2fbeebe7f2b37caf9fd577f958bf8b8ff5bbfc5c3eebd7eab37cd7afc567fd5c7e97cff5bbd28f32e5a5182b466064ce60ad01630f1012d30c59f20c94345c5d25745841e6b2e3b4e1487edf3a2e2669d481f80c2de30ac964da4aec265e7784b68ab1ae6201a3c5d801ba71207f3cd11047f3d27525560c0ad1dc0f6f839c9c9452bb3ddf51326222b6c578bcb792c6eb4b8116b7e2a62c29263259a55bb1583842c9d555448702a1dc6af227f7eb28724a99a7cd2349dfb7a3bde10af9856b0489991231bb221ca40d47f22b310e77585ebaacac42cdf7dfabaa64bf17e0f4153146e2bb2374f440fc4468eeccd1ad702c245ae5572bd18135f715790524e82b142372443097d838dfad065d237a178ca917082ca686590f1f723f9422879e69da74407e59d79423984b9b47e2be6fcb1a2e2f5c7390a04c8923d8dd119a7924f1cb224973cb9c663e12fb6551903db790cce9562c160a92f2abd5e88ec8a2901ca4cf07c487720d7ac4ab2eabb8a23864582cc9a7f756838e11bd2b52d49ef194a231e06e44ca880910a09e3b041c715ccce962be07f453e0fd61400069180fd055dc60519957af053724be41dd7bdbe2eccc1717dd38e0354704ec8631d8adfe1b6f8588a30d6b8cbb43072c0687f4e6dcb8152c497dbd1efe7b74f612a20e23a4187716ba13dc69a06e24ab9d1285b428b858b682f0a7130cec103397224f3028a89e370ad95110fd46ae4244b98027a8479c6f84a53a812a1b8d57c8a3d4164ca5ba138f7164bc925d4c3c8691dc2f12474e4bf8570313a9a1db804c6b8e62433ed1d8bdd5fd43b02d0845c565b4b7482262df0e95d3181ca1396350372047e99067da1b7f481a37df520fc14340c931d677fdfc5c9df904fd8d38269c016435e88229202643f1989a96b7338d2d19c40d9afb5a5f544b8ab66912ca40940cf62e24452328fe7527f231ae1a8cef6a33087c3bc11e604abf149301a9224f14400ef10d0198cb4aa9240ff84821601f3d0251bdb234e726a607c2d9ca9aae4e1b8f028e42bbdee50395c582fc8317c780a5c0b727df98e6479a03e0b4b5241cdaeeccc3338761eee4b941eb23e05585524f55eaa6c54a3ae34a61e7d011eec946154b3fcf076cbd264277a9539fa8582b4e7a9ff2c3711b0b264c9a3dec38ce4107b642f6ad8048a1c385c5142abcff1d7f6f67e498a92492a87e2ae744ed1547f88c2fa2a646c28ec165cce29617c61d1afd7604af5d8686ce9a93b528240b348833dc9f92f0daf303ba32be541382ddfac3d0c219362eceb14cb704093e37ec94cd2685cc8e9c9fe677af71d468eac18bff34191c411e4cbb0bb709c0215a0da0aa5187831ee54be450bf9533e5f9e8b8355cbece40b091daa5294bad242f5351661386570550d0c9e262a7b03ad7a910857e09009942eebcd43170effe1c40f05a91813ce95676b57897bc1e08266b1e2eefa5e71c2af8b54bcfbf042efe9967495c9cf042029939353fafe987c577191915cf0751cb71db6a8b8d2825e66489f34b741189ff06910e555792490467ba7f434f028dafc9c9c2caf0f5178d9a70e43012cc157a65c4f1a0555a23777a27bf069ba5abb4a2acc4e94c7f0400b44a2ebb88b092991c32c1aec48012ac5b6cda56f8c13a753c0aafb6531d9b137e015b9c0a63411227213723152f7902a07ef0425340b6d82349f2178ebbcdf671c21e7ba480235bc8e68a402044df6705479b2b9a6f5a6bf9208cfc7dc0eb5f54361d8fd938464707b4ceadbb51b2fce2145c612ced71cb9b40e852e2c705554f3a4ccc968b76ea4413c2c2b70d084017a40a43f754cfe2702255dda6f49d7077e7c3cb11ae6d796efb3334fbf372bce7175078e9437aaf81d9f2acb19c6a4633b93cef7b681d347f43673ddb9cc2c9e1c6b8617bdd8910267bef60737c065cca3a58c13f0152eb0d99ab0bc34c5cdcf13f37930522665e62ca22f2c9a8505c59e994b51298de99c310b5b05fb3d66cb37442eca52a8c3fdc899d723f38a1433519a2886ed97e713daa2b3c441c2d2b958748a987a7841183a22ec76e25b22c54ffb0b44b5d090341b672e2d4f80dcff6eccdb4e0970d2178daea22e184144d800802d98d32c60c1fa52da16df8490e79b52203b44431da7f1b792ef4c9a1ff236089cfc0aa4522d390f08ebc2a6453ecf1d651ecd7e5384302f2b90b24c4e9346bb9016a9e1727abe1d88977878f755b722bde435a4b2c5d64a22814d0fa9463bba5ce46167606866cee9720f6d2e7820d765042b9affd08512888514b120ae48ea478df4802b6562b475d0504f7883f7d88c927e392b6b1ea7c107d5509595011109dfe6361f9ed16e68c4e8bbe4aee980b4108a475a2e745a4af1fdb9012bdbd5ace05b641a39266c6681d16023deba07d63a43bea647887f93594ec0647c8a79835151f42b63ca26af4a09f494dd32df42356b8b1ec81425e911bb47bb01cb48d7a78b3f66ce5d60178bfb01d3c41c9324629fd8fc131bd4aa56584fef237b6bb62b15c739b8f2a6312a40fd6071638fd0667abeaf5bd92077b463c644f519bb8a04dc1241f739f10abcd9d603fb5bacd5e8f8f06e533b6890f6849775fd123d0fc598d0660405c897f3765e15f4f67ceda39fa0d944213e671e8a90953fc66909e1a3c8a6d3ffd2ce70c41d9044921657c9417f95820a544fc264125efdd431d017d603aa6f7a9da03a6e7f5dd4e69e9682ff3e338e24647fb02408132d61b1e4e8b0be49a1851bfa71f17d7f7f337dd57f9255f62ffd61e9b558cee63603a934a2ae10b9e7df322d8319c05ab0fc7100823d43ae25a1433f2a51bcc0b95049ff7b8db3477bfaff7f78b423e1db0939f5237790c0c04c1c7e41ffc0fafde82818e8bde129594adc63c0421560cf9d9c6e628faf75d3b2976e8a9185a7e664cb3c8a3e6c912663a0537fba5a7eabf77338e2af39ce62319617f183009f641a885a3282f7198fd25e432ed7d9cd347e5336b5270fd12ede32807d8a080b34172cf6f19605af24ac52905ca5f5901bbc73f17c8e0cd6199595c737571f915d25cc2dba60f40cb39cf0434fb7780a2511a250d510ef48cda83ed9943d078839f382b3c8498b3e62c7a4320c49097a3a84e109ecaff09e38e6bb64473ce55501e4d638aefa26b16a9454d25574d95cf33c8b2267a12d08ed26a5502074e8eb8bd3be1dbad12ed72b9f4708a34fd8c41b10906e41fef693c80f105a4075577c630f6ec40e697bae890c60f85d21449fe8acbcbb6bd4bc8c028005a5fbcd65cb7ea4f37bad765f87083293770b1fa33a5dc9df2b5ddbd8e188a53d68c8381afa10a23df35f3dc785cf8ca973b27874209834dd25d478d8ec4851f43f22995dc0195810839f8225458983edb1ee9e859248ce19f00d3545edfd1beb6fb62b32901c1659fcbb82d39213713997153999d42f2de016ac6a38feb9aead0fa747f08d29913caac6b7bcdb77b62c3e420efbff1cd0724c287b1236bb38008c6cd1bdf2049cf388a7a21aed8d3481fae924d60beb951d107f76898586717eb2de1da2e047a2260755728d366dc6804a559865cca9cb42527d66c4b131f71a6fa4d1e0f506b48da77cd65379057e5050b88465ba322e4c241ecca5bfa55bc9ca458e78f0389710edf8844ca96dbb329be32706125ec3149f667cb445be84b2de1c0bca999d7f225f29312731573a06c5252b44c7333254f92b46ab1c040149e4fdf1973be2133025e0e4ab5796bf058fb07a29b3d4f08f8b7fffb260c90b712c2c613400026d3f764300f9a05beb204d3341308c641b53bace6979db9cbdb1781987eaeed9180081d795971e43096152ccc1b5c2564dfe61ad4fe25c0099665321e2fc795288d1451460d85fc184dbe8828e1d801b350377b28107f2a6a6d44b003604850afc5121ad2d8addd899dea71a954b9b3cb909b1027c1355cfdb4a8372c8d5421a2a464e14d49aea86161a162aa4ff453b8f4f016b4b53a84ee51ce0170e7172b39d6870b5c4e0a8dfbe6ecb10b6f1a3d1177ffd9e792c06cad98b3adb019b2492784fc5e4327f09bcbeb06069510022f459efb425e2d6c67df2f0ff44b764a51a65e7bfcf26a723b1b6cac65d746156a39769d2a0dccaeeca2bbfe2741c42c44ad3624d10d2ce1bebc8b3ca8cf6d4e52259d595f6044b9c1a2bd08b19f44ea75d630635a87e8f2bf4c1ee6cd5514f7203e453950d16e84b0da5107a0ae4bed67f2c81ee91a853b7c2f967a483b5deb12891db0be7553448ebdbea36d37431c33eab85a7e0265f4546b05d59a86733111e3d2a49b3b1c5ace33a6609266b6d74f50a793d633790b04fe5da6b90273b04c249cad06e8ec19c1df3b844776d7efb9395ed151dd394c0f879f7306e45691008b438684f16b09742f0b4ba4213b7ec085668273758a267560e523ba8ba699e14ee6cd95a1633710b8d74cf2dc0c86ff17e26eb508fc885c91f4baf006f362fd1c10574fb47aa74cd55552747f9ec2cccd21822210f08b783bb7cce6d723b8f7ae55f458dcf0318fa674f848c2ae4d97314c01f4da09e0f9300b657f857419daaedc9ea9ebec3e6660b6846d5a7944bf0da820e7e5c93dc7c12177520ca3da6e6ba7c1f8b213a455401d8d6173e392e263e44a77f772716769ec326628bd8b3628942b0505c4c7e3fc6abbcbe0b1d06607fb0b135a706731e4422043276441a797cce7908416dddedf2b761a315047dd34f0a44a8daccc611c0476a21daa67c8f137e46b74a85dbcc9152dc69d7d87618d0e3d590e53081d4fbfd61360ef718782ad7696744625b0a17eae873fb740f872cf667ad76ee3bd157b472ae18d2c87a4fa98268bddbc4c08bd91eea2650fb8f87ab1c0e2671e603bbb9a064cc18d24ff9bf2da02e546bb1aa812f85a660b9e4c07d295e89b3960f1d121ca367b7004eaaec8c03186d3de02998509769544e040a4625d14ea4b6f33778920c33f97d9ebd8b70a41c7c25a047a95bea62a0fa9e9504528e7451f4ba7b3aeeab7668da320e5245e2e706ae4de69c848934e98e2d3a831f83b1d98b4dda2381e895541534b510b459929c0f2104818a4444fd260fdd3114b799bb38ed5c9f729ecba9cb7d5685983048e8e3837d8c2ce3942320de1b5fe0e03c3e692cae43bfd1bdabcca331811339b52874978c861b426631273b20996201e8277a3d5d519f0bf86833f1a8e54445bf67cac3a38dbcc6a09080efd377b9ed6b7d4c1cfe60414d3e193d439febdd33ec65c74c78dc6d30b8394edbd7a838c6a20ce5cdb8c120e298ee29ff82eedc3587ee6233828a92e9f81955aec661841618136b029315b3fef4d3172498709b925112f363e2b2fd416a731f7ddd2f16915fafb82dd53c335a8d63be30dc8f19f41f29f77a49290fb8259c2d1ddd52969dde072e98aaa70e502045c59fcf793c77492f1c798902902610010f70dd5d7881528950f119a02645f60a6b56698efab72174c75fcb0a4243b4980d3913db8e6f5e3391b6ba1a09c75c0ea048011fcec9c28312d0d58ca137779ab7e49e035c2320aad5d2306ea8cf436834253278568648b23c1b7ddef1ce39ecd7e12653fb90456528dc62c9c68a78ac16756b61e99a114f42d3bfe4f3d0673b62999a8172d791689535110332b3836469d0e860e2bc4d35ba61970cd0ff23109c0feb40d1b6249ec77a15b2e1c7457c9e33f2be14af8b0621edf4d904127072da424564826d7117d8e32c6f5bd992ae25c3171f3c4c3c138f07bec1d22b57bf7771211a1e2cad8580c91310efc1d6b07918b4dcf58d4f105aa48efc535582b16a4625dd98158469133ab2a68b0706c218c93185d997993648f8d06d66714096334d54a9f6868c8116a3d5c85dab5a4fbc228453c2510864c1d2fe81422eb52fd388c483f7a2c3a0a0a07f2c70152f57d3b45b4dc394a07c38935ead75b880e38a927a83b08c7743d7bf2921fbaa017292227383c6139cc023dc7bf48eef38b9f02d92e1a91b738594b8e861dfa5c3df2be9b2a72ce51c92d7b489d772c0755f7d61491f0b62c6b82786bcad1cb385cb7fa7f969da2b8c5db5743c296869ea3897653648af75b01e8e3c9379dbb20152b2a6c54d55a9af416664edcb123a35cd747761ac2740064d41eb2fb540f7c37cafa6ee5341ab20779d48474092ffa03fa75a9fa804a25720e368a14334d2572bfaaab8ea54978a5d82fa4e45d419980977bad6728c9d30a749becf6a7a8885f29130d0457a0ad3310b759851b28a2e942b6e26dacb785fbc9bcc1afc35f0a2cb50bb3f77996940f4686004626c56fffc1dfd4d0fd536cc6ef1a2f3528f0b3a6be665909df3b201db747bbff146ad835ed6bc24eabe71aa3fcc610ce3ea0bb13293effc4f2f18702f0ea857e4671312f380600d7ef5c6a6b2877b4dff968e02bdf1c1d03c37d9e11f85ef8f06a4346698c20205a937716dce641a4cd01077360e55f144d193662bd09321fee955e370ff326c62023ce5469cae59dd94162726fde7191557b3e410d193adc591f0707c0c556455e3e613416c89d26ffd10a0fbd1c7d9215570606487391b069c5d5611d27569c0a1d650e67b7b4b18c66fc8ebcd889c5b23ea319f3b16e1121bc8b72f551fa7f48f09315320e7d98c77400529a11ea94dd68e9f7dd10292bfcd5f6a6f2372fab1882e7c55bf5902192154aca0845c857635761cd17ebcdcbc3ae3fa18cb971561c4091a3952996e7023f5f9fff92569ab58f058dabe2ef681c85fd00dd78b60f63c32c74903bfd7f0c5f94065a4d87ef50c6cc2b8dd19d154ae541a1afe2adcf93ffaf4d99d20f8e3545833bc78909525422b5f77683f0d297076f19687081541a0ebd2bd8b5db729cd79c21d8cdbadfe640bc764657d57c3a90e5fa506e8ac1f7812dbfae616e9611c94692ecc8fe8bfd207f8b72ebfb3e5fc0716c331909f6df684ade7f456b90d7b1b55f801213e1e6a26906ba0c99c170b4e5a3b78b480ca3a23043882bc1066b1cc86718cda270a8e17e820d8e0a42d99ba80ac621622dd24fcc21964006d39d17182cceb0910972dc7651bf2d85711410339832ddcee8066635a1f232efe7d6aec67de1230939d1abaaae0000907adb4130370845ebdc61ed449188cdef19d0b21a1f852a595ed34f34c4970429e83da880b4b0093eba55b81f617f0edb900cb30ce6f3116051cd39e1de913d4fbafc182702eec3b46c2b1b026a0419115ff57e51e1cf767686675a5ef02bc1c24ff0f60f9741f9506f20d895860fab69c2df7673988a1c8a9ea470f35104db5e172ae71710f7a01c8ed2b1a74649cf9cd32774f1eb98e89ac8b168ac2b077fd58af40ef34ad41f0f8a873bcf1f4da053c547e7112d584306ddcee98cc4849ab5a9e8b7a1b78e798e8e4e0c3b2b310e1acad634d74ef4dc36d53565925d089fcc6fc0449309e0d534a461095207a6497ac75f21c983cb3c0a45d24f0740b893b52daebfccb6ec312bcbba50fd913e195bff25c6780244d0e15fb85f01b85d6c9ef7ec14dac0eb4dfdd320555a9cc76ba608130669522ee015e7828fa6b22aac5611ed2cd101db57a2a98e631052b48e2a94a7fc9547ef928919918b14fb09f824c3a14ea93753b3270b53ea4c2a993c51c8172400aed0058298fe4a06e10206b60530df7b45189b1ecb84788b4d311aed84e23c845fdb8c373f6fdecc80f4ab6d23fd282c76a59fec52aceff0798458da6d6b02c2d0b5ade52b33e59ea47bded95a2f1d8a9fe1d13993b67f01917353e12ef164adf5bd69a55e93f14a8502bbebd2a6970e56b14d5110da7b99777150494eae634f58e72f448724a928e31f9b300705b0f4a886a2fffc66ec0a040db7ebf86c94d6059e4a761b14c1888ee55ed795ec4cd416a65f3fbf2be6975f4c251415fd322cfbca85edc2947186948310e12f65bc69c48322129cdb2243f5413943b0fcee468833efd1a83c2568016f04f2ead224239e02777bc7ef2e2537d8cdb81795f740663dd748486fd7e1ee093a10e6de063c2c0afd1a7881911f2a0847bf726e63c17df7407ff3bc717d6f6136795792daf5351d159bef08947dc70604054cec71a9edc3ddcf87c0727c03780783e3000e6295440a2345f170b4afb6e40e851b568b025cec5f1ed1e2a056610d869626820a6214d40ed0f26148e87ec6c5b7c629040de3c9818544051f82b8c1b722f482039ab8828d59300c434a07471c7c5c549861390d03d0978e09f57a8f0e2367f25390876de7e90749f9a9296a2b9e66bc8861fb2830308e729cd4ec87db918297cba643ee3cb0ba4f9511d7b834168921cfca6f89dc7b6fb9b7dc5b4a29a50c570835089c094e7d3281e535af51bef36c0938df7966a24975cdeb0e41b7ae8939f34cb061a2cba37428535b14afa7bee3d4a7add86df65cd4ad96f210f5d7f39179ec74a84e7a3d3ed0f381e75c3bdee3a04742e6be7ae8b927bbcff3e1799ee7437368769e8bc73d0733eb99a691504e5d869e8fec7687c7ce0e37b714a57b76887ace3f8d643d7e0af58147aa8ef2c08ba8e1072ab6208112545a3102818ebd1ff735cf30061d779df47af0f8d0a40e5a476d1e1d6e1bf5e91161df7c80e03b0fb7e740f0d5b3b7c3edad5724ea16048f75683d1e1b8947abbcea1aee69a41a1bca339d7940ac6b5e8fead9add7a3fa059dd357af5ca0f738e83d8eaf5779a8bceace3d8d943912e8de75ceb7cd2510cdab4f5a2d52adde79b657aadd43e93f5ffde071d0791ccc9c477799f7e8ccbb6f7a8fe699d56db8d5d946eadc771cf480a47c88e2daf5e8cea30fa523363c498c0890ad216a435fa4cee3ef68a4cef10e9a2c89da422b57e7a0770eeeadf3360494bc9c00012522252fa0e7c36d686bd217f9b879d527fce61c87b7ce89643f444bfaeb6057648805bf79797cc25f6e6f4a7ff197c3bb216f1f61619c9eaa26ca05d7ae2a7258e5744a6365408e11b604d3d7984fe0e6234c0937bfe3234c09a7c7608482e9e7d24f9feea22287307584d1e928c8d411df5f892b1faa648c6070742d51c8aaac3af261c8fc942a1c2e2ab2ec640f58750516a6c9ce9b6fcdcf09707c843d51438e34a9311a7c848181a1823476d454f181e99c82f8aa38d1c28e9c6e0c1b652af0b2fa086ba2ca83b0269a54e0c2028caa9e1a3ca91d1d1b5fa60447ef52f1e7fcf8e3d3a5264be948d4c973a5c994e2d93dfd10ed4bd0f140af84ec479067be84eee508f2f5433678e9af9794defdb8e24ea75edb3c9d9352971579ba6440a506884952495269050e92413801a2cae3b9b7fc749fb04bd5a8a3915a77c4169a9feea329f52c553d147e0641e5a7dcb1aa8288fd749f1fbaab12d8022c5d4699402c5136958c75cab468572e942dcb8b6383535a629df71223bd395b3e392288c2804b0d0076717235030775a380fd70e64654063f4f87f34222c9bbc60f3e781f613f4881fd0085524aab85fdc0b4b4dfe038b174e3fa9223aca9cdc39aa0fc7c693b589287c82741e9edee60491e42bd8325d9ea21d63b58927bbcf422cf19679cb1832519024a6f41c42189a84ebbb71e614d4c1fdeefe28fadf5abd71c6076efb3f86a1ebb6d4351b794cefa28cdc218d4daec409dbd673f6b192fa0d62b987af3cde3e16d1bb77115d415d4f403f57c4fd7c902b5ace17660acae28996e7a6a1dcd75f49d409b7b3e89d4efa6cf2652bff3eab936e836fda00bb7e9fa95ab97c69cad911f5d3864ce25fe8121873f40d5c31cf5eae0ac739c7ccea9c783cba806540326bf3e9d57ff993a42ec59d6798e3d4a277510c9f46f2bbda743ce33bf9bd2632db33c27b5901874320d8e3fdacf63cfbe6b7da7dba1bf6b861ce278eb9be3983a74503a1e0a11b29e818e46e96e47c729b153bfdd0e7d88621d3fbcde65f69b330c1c7f622844e8a56b544af79e3e032f2a3979cf853ee4e0bd8dd43992e63714aa61b74321893d46df228dfeac8f3bec5cfb9fbb8b350c96366f5dc3a0f5f8a387f0e0fc0ed90067a4ed503e0f6e57ea5ebe82579af21fbd1e110524287dad68defaca45dd3add5f9e73f79c472371cee33a3ae45c070b99b71adef1aa95de06f6182fe8fc6aaa3badc30ac42aa5341d4a7cb556bdd3dcd53aae5dcfc7f58c7ce6f4d147569e44b636cfc755ddeb2ad0afb6613d2076f380704e37d63afc833ac6d3f3e13a1ee3051e90caf9f5bb572eac0dd10a7ce558c7dfbcce63e62b1f9ad7f371bdaa34128fc7eff4082aaf81dd860e3fafaed24038cf5eb7e743f407e73b5e43fb88cff94a5f24cf773ca5c39d1d2abdb63da1ac4325a46f735ed5abea1aaeb57617d7cef17522d9e31170571d5f1c97847bf1d649af87b6b975cd3ad59d46d25c8b59d3d24ba75b9bac211a26ad7a44ffa169bd21262c1941e1f531b2628c386cf522e9750f49fa904ab7313b2934597d7a782fb51fbbd770b5577325d00f4d78223a14a2b21e0f6ebb95be7671e160ea1892efa2e12794326a598644c5b3eb30fee2e71f96b873afdba6949c7bd8c97f38cf351fe938eecb9d7bc85446993b4250e3ea72e593ede330875d5c7274b90504f59d409eb7551d0fcc6922f67e7d6d1f2d4d54ce7f9d72bc66c07c7082f9b025460df3c18a0f502a92aac6d7713743f2231d603fba51ec5d50b2bc19f081e93befca780aebc1cd534a29fdb13cec7651c9a18a7abd2d2ca1f2d1a6a66929970d59e51382c68120d201f2351761ea90af391113b4d76c82f5b0e5238c872f9f808f301e5cf89cb259add32b09729caccca9dc52b2d19105a403a4d421ddba7579439e1f613c38f9ea7446c171c6fa645d3ce4a8452db376d614585b9fac9e16058c71f43c0bc6d3a31ea29d91de0fedad9a900ed15e9ef051ab91aea5161283e8d3a58ed3e311a509536aa926ea1a6315a376384ece7a4cfacc6dec3edb91fae8d3edf0e7b31de2f86c8741f7e5ab9565599605cd2ccbaabb62c861c5b2b34a9dfb98deb9d25f1d56acbb4c2b7d2624c76fd64a5b4980a5a6d1a17937ffb99366d323629dfc67ce58ab8c3646a54ddaa588baf2c4c3cb4a963989845996e9137864da13a51e3d4bbdee2831c87c6a36b5a6406230bdfadc115b26d4a7c99a3fee675e9f4225bb87689f65b30b95aa12d66d4cbe6819d70d75ba6e20528954d8f5faa383c6af9c166aa4a75a76d9d5768fea7496911e0e2965c8ca6475e560f4c372a1f774a7c34826874141414141dc0ef3b643d5dda1b3de5a60d6eab1c6eb3a22fb4cd6cfcb1d3a69d5fcfce0d07e7e58f7b31c069da9659cf8b864c8d765e675fb54c92bf95ac9a5c9f2f139ed9c7eb78ff3d02a9ed57e5045ae4e3d4bb964c8e1ad53b22c676ff330493729683f55ce634bb662ab84cc696c693a944c8fd401eabee9d8aa63449961d06899618b2868aa582ddcbcf51cd6cff8f020b664f420eea426a39d245bd235bf1dd04d013a9d49b6a86b7e34a76f7b29c9062dea4c4314c85a8f5a065120eb442c64eade74a42535c92c5297d1a94fb77356a76c233aa2691a114eb66012b341891f340e2848a30c27416401fb6206ea3971c9c9420d1a255bcc8182e90ee92d3c75112d7a1e4cadb9f44898406c699b2351b2414bf36d73249a4fade44d40a975b79dd464a4f9d6d25c7a464b2ba3e91ec4d6740aac3a903efd48eea6a3a36c271d91adccb9cd245b99cb3a6b75a98328d0ac55f3ea52c7167d2c67ed6cd649ef83d8ba8ea5cda6466b94f7b3486411cd91685bc906ad229923c9b6920d5ab335678d0253f3044b03876889cb0a4230f5b0e4c715a71219f13ec2b2b0220b3040b226fddefbd18bf1c94f9f9c8bf09bdfaa692235942e357d6f100882177bb62df19773a9ef0e833c0fac518dba9e30ce9e75912623946710d429d26404fae7772729b58c96be1d29a0f21ed7fc5ec7285d84a6bc08e83b8ef2241dcfde135b1fe89f53807acf2eb253a467e9a7f7e8223b457afc73e9f5e826b98f769ceeab8be838b835bd79a6278f4b8138af9a9b70d8fcac9ed152de459a2e4a833b49a985f2ab8d50df077ee0f48c96be9dd464043ab893644b2e6547b908b33ae820f4dc7ba6ca4fd7ce98f9017c849dd1f2d2e371f43998a4e3dfcef611e87427ed38b82f05bad3b595118fc73faae129efd1557f6084c57e543f778d9143216e0394ceba488f67c7778742543dbaa9f3ac8b64e7d9ae0e5d1537e99ae6b26d7aa78f509ee234ce555293357ce703239aa6f3ec224d47d9515e64c7753cb58b6447edecd5d5d92b0d49deabbb57d88f8e507ba5ed15de1d805e9d024ee505c087378b261f1d737e3f9d397d043aca37dd41d3dd479fe79df47952a49a4b07634b8b2da76de618be5c90af1b76103855a4b67aed1c3b0899b641881428e376a4404654499b730a32b0b739e89b7f8e37ade39fee76bcd3f1ce330f08e8db0ab57d9fce5ea17cf6d1e63776e7dfe63b3acc1edd73d4a637cf87e6b63f1d077dd36190a2cfc31cdebd42adb283b0721f0701007ec3e3070957a8bdcabb8395fbf891cf1100b608dff98d2dc2839d6fd9b3cd735087a0ebec0fba64707bbe6d24cf51b9d321e87d5d8731eefc73fc61ec5fc69d83fe619c71f7e1cebfeffbbe8f0cd0e583de752ebdeb400c7e9f77dd0ae5abaffbbacf517a887edaf32e8320083aa83f0902082008ee50fae81bbed200b8e1473e7e631fad4070d5c10df7f1a31b3b52209fedf9d16a0ba9e67726f607f808c3e2ca6310cfe8350209f2995b5a6f90ba43212e44f53354fa39ab74e95c62c89758b080f2d7f11560ae78bdfc544882d2f3b8a75a798fd7a80029fb86b3def14e834f2f7d3b6346cc6730567c79ea1d7670c7c10c44c7519ebb6e67ffd0d971b2b2a33ec73a44797408ac5c27ebcfa31701b9ed0fbae4ec9dd7a21ddf3ceb30c867cfbca2cec1ec31ebf8b6c31510947f9b833b5ce9ec1fa81d27ebdb9bc70ff2a0e710e51907f257bee970f39dfd4197bc6d21aaff1c04b2f26f23ad5c6723d9406921aadfb610d5abbcdba110d5dbf0e815e8b07e0da79e4bfeb0b1eb64a9b65bdf76d8b3e364d5f03a5935c0227087f2798a78dc731e50da6ed39e4baf28ccac3084ffdc7a45f43de91585a067ef367d9e1d1679cfad5baf68bee75b11e85984ff76689d087d2fac9395daa1d27b3ba553de79b74322b4f3ce394d44fe46a4fee62e31f2ca253fbbfcece046c21374f918097b3fb8cf170ba6c7f111768599bf1eb5f46bc6e9afe34e87411edcd1d9d961be911f7494fbe8db39ca73b004f9d9abf7637e76e97787d8f30724cecfdb418df24e53ef07e8a8f99d9e9ef5f41cdcaac9f27cfeb791b0cb6e0b513dded763be615018e4a3578f8715a2fa12e40f9ef7486005152ba058e10466c56b090909ab42cd478f9fab8b2e7298aace04154d9efaac585a4b698d9652af35d65a6b8c34da1ae3a4b59bb39b2c8981f428299d74ab71c63867adb5cef8319bf407f56c73d5bb4a69ac91d61a6bad35466b87d0b7d3baa8ef9f7b4faf3b4a4c254a29a58bfa0443e618638c31c61863940e901f6747271551a40342e944ea87998744ee6bee72f3995d7a3dceeb91cba6ceb6bd72d559a70eead2ed8ada3a93aae6994bcd5a5f65765aa9636ade4eeada9529c03ce75d9e3a34cf324dcb344dd332cd87f5eab39399a669f53bf9f8c796d1ccc480deda592ef342ce916a176eae3419cf5a6bd5f5533d9a567d1804dfa5d48585391f2a7579bd9e041ab91dd6d7ebb53dc212afaf4e8413f3caa9a76e5e61747a7ddd352406342531a01ecbf8ca9372a538aff2539a6b3aeba478b8b89d4ed3ae2d72cf5333b2cb78e349d5c05c8a27bf2c27bd9ae995fc211aebf5155e6d9caf2c9765b26655e37e6835168b6179e90151eae2e4f5242879c9f27aceabd7836e797dcdf2faba875037afe7f6d7490ca816599ad1a15b447575ee50cdad0b9bef72a6e59b73de329773c6d9cb5dfe8ebe50031fde6903acb5725ce52ae636cf3c209687cc21739e7abaa7ccb22c73755e7df378647b0a3858d5c5a9a366d5eeb0820fba84584d46c2dbd5adbaaae757cd358dd361e6dc2a1b425f0b57f8fa6a5bd9eb2b796bd5f1b9a4afb5f3a149bf765c8ffdd8cc630f398c77c879845181e5f1dee6d77da98e8229a5af74e5649aa24b0dad53bdb232dc3cbc1e6a1e663e9dead5b67b70efabbb7b702f7da5ed1edccb7801f7f47f88da212ebaeb7e810c98677d848d71faa8836386ea26aba63c8f3fac789178ea170a364fbd0bbb32d9a987048a259ea6be36c1049cb75ebbcde3d7acdee93bd3f2c53c3d751e27cf33a9fc8ef70499ad74429163cc08950f6bad633ae001218278e9f14a5709118411506a48410634504c0f8868822a528c11e28527c050d18a1e83d0988646fb61ce171ba899bb831c27738698d3036c0e94394c14c7a972b6904326f3786459a65d989c2f72788854a49623c3a7262b4a0ca2c7f0135a2a4fa7acd25fafd7cba915a5474f8aa13b2a156e8742db0e833ed776c8f2b25db798a06f47969779e8aa4a85ee984242412c96ab54934aa5f254a935692c3620be94fefaa4a6599dda974c92afd61005a24e89689fadb4cf36128fb987c4393fbd0425252f01bb43f96ad1372fbd6a3f5df1cdcf0ac8711259514705e4bc1059f1c3e8c4530fe5124fbdea0fa8c8f1cdc70f23144fbf587a03660e0c67b8b0448b7211628d98d80e3d84e1d2a24574498108da8c79f2a1455d457728e960258e151ddcb401438c1675a73b62144a9e40814618342089a2456b3052450b489479139bd2a21e4477587084194378a922091a6b5ad48a27217268a1063748bc69511fa23b628bca9d17081c671742445d4ca955913539297cf863648cd624e7c87f65448929c100cb0287129ca0882f2ee010660c228c48a20c1173e030b1000b166c68886920c90c492c4901142796108d0007296a96b819420469ac711fd27c58c48ea82c682f1375d44ae78f20bf01516a2253c7f4307aa4734697932a89b3c4cf8f17b5fe7ca186c279b270cab83da481530507074de7f190c6563acbc411228e9527acc49142cbc4ee0e69cac479c559210e93130b5ec627c779fdf4d48f77c5ea1d511046e18418497c91a20b2ee03861e50338616e90228831395401070927d240a34c1a66ee0e69e0040107cb8cba8218134f624cac105b22cea7b0a83b9bb1959a8968bc114144838ab75688a8898bc61734b2f040c444126fae68395c3766de3c7113070c19148e78018c2fda30bdf93663886932022fe6fcb046078733a4b09d1b306758f1c4142d69a66cb1821671b0a0d104196c98608121093766bc1b9438a3ca19469c21049921b4283a1f6167b4f03d684499809532348031c5112d2e2000a6268c2dbce042a5091d32152e42668841b98c600d1919b85471821adc2451f20225892e496498e10a29cc80e24dd1c2c58c2e66446186139d53a5617289b76ab0329680b5814534965428e2862f62d0200756061a00f0a43481a1f0c597248e2041145a6e19282823f60411424243dc2b644311657c710a22f6e68d0d3e60505922a5e989112978513e64bd74e9d5f0d2a3f42b5d25a51242082124845008491c298119166658a18a0cbef08105187038e20ba6a730d913991af64989fbd485ab639e80c06da458f3d48346431b2e3d9daacba99c520509e510ea523e6d98a08842861535c04046096c80818c209afcc050c9d8818ad7d43dd19e62e09ea87033a81c831bd818d9c204b1a614e29a2c48a85892040e61504183c3208007656b9ac6bd10eb6898210ec258228c299ed8c040c612c7065fb9c20c232d40818e602246914116c0c70b3ee6f80204e0234b7ff4209fb742461ec40b6293b5791824cf58210f62038ca403241c89814fcf05a83957ef76586378873e67e887728e84333df5a19c037e28cf781fca397687f4e5fc9c93449ef3d3e596cc04372cba43d5674ec50256f5310f6152e9e47d6202397979c14a991c7a906203302d7828a3430a6d584881173d3258a1f1c98a262728399c09d3e6470530a23882cc0d2a9c11c68b27862b50a2842103a70997265f5290614c162c483c39a3a54cf660c893076badb5d65a2218b2b59d76660433b4a0448c2f28b05bc680e2081ea6c072a6150695309abc27b793a206229e5c41030aceb442d55b2b98b042c314629894d1a515060c328c18de5aef85b7d612c59063ca7bacb06913e6d49924c4e4bc13770c4599adb24f949c52f964b073f090bb8f303664887ac8df47181b259ee84ad63ec2d878f93067150e962a957d7e38c82a6743c4872c31340c2ce79c97ee88b95a5a83881066305e309dc8872c3d046d04aa5f49781959f5bead96b66aa55a5c1bd8dce0260a09ddcc563a6de8f90863934298284548288ec185044ec230f1448d0a5b98625872a50c297480e2e43dd1792e10514416304a46107b938291238660b3d4851723b6d42e758e79f25a0a72e0b93670b0e6e9b34a4c96860d295802c30529b0308c784d238ac1863567d8c061638613d9b0a6024a608982c9182e2824d152ca22839133495cc1a586245ad355412fb910128272af10d10c3f3f32d4fae3b540f484e8c90f910b423183ad71827df144adb03562bed65a2bd10b77f511f645105f60099a4fb31a559fee192d49df7cd541b629d0556fd541b6ad1f59eb5ce64cb2657d73aa65cb6aadaa8d740831354314e8fad0246281f3200a746975ea95bb9546a739bd4a8f2d9ab9f54bd5e0f8535d524e635da4e988db514bceab1f715ea773beeda3cee94e92deb9e7dfdc395320cd1d44f538ca7bdc939a8e6af874291dfb91748c5dfab68f54aa6d2477521005d21ce53d1ba5b94c9a3bc92990e63536d59dcbcd93b257dff611f56e2749271448933b6bdc9e3b49beb693297792e733e9f34881eedcd1743cb6a4b6c393e2f1d8925a6a88561e9dd4649442f98e2e829d731d5da4e9086f49c58b7c5006b52305ca9ae61f1891b322494d1ec496f5cc638bdb45ac47cdab839afaa763cbeba64bf742cd17afc771c6f959710ac89675a253230253369e6347f279e7d65b75e039f623efe8db423ee88e4a2f7558a78ff00752f5cdb98d243df3ccfbc16939e7397a9dc8fc6d6790a3d61887d039994c59160b7b1ef6e855aae4d775b4235221872c16abfb3ea2263947cda1410635003560f256cea09ef39f779af7ed4891743bc76d6e52607cb50c4c9a2e9f656a3d4b9a5987499f1d671d2ab499d7c33ad2ca55fdf3ea9f6747f9d448791399ffb9e756237d1edfbb4e64864426a8e3d440c781643e43ead933d7d14cded2f14f8749fff9d4a15292063a3b29ce05584fd2f113e25c00cae35cc00724fb5a1885f2eb9d9207a43a2a7b75cdebe179de9d5b0dfad41f52e79b7b7ae5aa5dd28744e6d32c93568b3686e0b431c0d2980171a5568772ceb891ac4bef87d2cbea75bec20e7f847521c6c9a8c809d5eaeaf4ba8aee30c2b5b4fdaa6ee6886b59affac5b564b68b9c106f3443ed7ecd49c76ca9ce85181e484264d4d269979a3ac21f9f8cc345e05edb1e904e7d721ee03e4aa1189a9f9e632309a12e6475d0d4313d47063fb707aa164daf8ffb8b76459b52830e94d6907d8475318396c36baea189bd8d8fb02e5e5cbc89e29a438402d10b0e1c22d605c7f533a5cad70646cecfb14bec494c1bb43a9f3ba9e968fab7933e9f47d2e74eaa3b692791ad6ebac49c5e5d576ac9175dddadd48a1448033d040a54dd933c4f6afa76d2e7dbb7938c2850f56d9f0957a65c20c5c94d9229d2a5e40a2ccd9b335e78934525a82002092466de7021442bcb9c2cf9cc937345b610ab90628a3c430a1253e23831458a04134d90830e535e53b250401a4152cc4c29228ec932650052a66821d74434ce4833229b23809003c31429924a2c634a97292829d32849166301cc8c561821f114728cadc0f4a834618e3115dc7c74ef3df933632a2cc59abc900685c55634860a48c4548042a8688cab02102a54114368882e7260d852e0e45ed182164513274aa0c296244c8050a28649d3929a18131b6aad456a543982aefd186302e5c320ac432c852d5200b324968219cd7be3051325bff33196421ba13454fc146d219441996ce3636c89171c2cfc31b644cb872c99468dd647e561d040022742a8b0254b09bc2f9a28824a0d66e2201147878985ce732384e6e98c0c0d0a3635d73b038df631b6a4c9e9d6186d8e20a12ed46031440b478a283384078028c2cb9614b668fa218c1dd379660cf11589cefb185b42650517624b8e3019a3052ed0acc045fe186322f3ddc718d31239e854b1798929598a257121a6e449111a9e8f31a61e3efb1863aae295e1b6888b1b2c530d6f634c528ad04429a594524a4d4a29a594524aada34ae06aad95d24a9b655266d2da5ac29d5a5213e01c387c52d64dad9a46a94629a59452ed6ad56dcd649b2a19ca4b974c1428ec389f1e242936a0fa740bd01dd86718dd681edbe8ed5ea754d3e48b6a6d67b6c62228f2119d32e0f813cee873871c662046c76f78060ff871eae33400db6974f20ac43c21e439e7dcc7397523ba43ab9cbad4121bb0e3d439a03b809c7a087407cba99b407710c0e900e495a9636345271a4a2ceea15be0a1d08712cae69a16222444e8b16f5b2e417ba4ac08965553870da78e6de850beb0f50a4229a6884cbe1c101949adeaacb3b143bb8968afedac5369961eb280085b4a27c9d78e4e16b9849667da4837120e0134073a0401fc68498502490f80965b2890f42d5d7ba44016dcf0b9f2d2574f38d4fcf8a438981c983a3226513401c6c78f8eb34c4a39e79c734a4d66b34adebc02f7f1508ac932d63975d9e686d3cca51ac9e6a97390edcc8ba0c8210e1c2111ede5936433592f6d424e9a2ce9d2372da14c96f4aba59bc9823359d26f4826e944ba7919ddda2c9b73ce3967b62b9c972e259ba228f21ce1a798acd433412762121b0c4c20e941a6c097ee586ad23c8c668ee68ea309c4010592ee814243fe75ba4ed6c7c96be5f3ecdb9eb6b186102f907e0255c273522175ccd8b9e72a11620392e205d2439610063a5fe9eb3e3491b418fb1b72f0a13cce1d3ebec3737b3cd21d007015e819e8e19d40aa7d43c709d4b36be838593c3b54fdddd961fdeb413a3bf4f98bda71b2baeae9f0db4284aea7bb6d34592bed928cf409347d1689d134362f7b66063313c56499d164d51863bcf129c864511c705413c9587b79443558d33eb05b1ddd148dc99ca379ebd7359d3a435b984eb4ac2896c33b75d03a3fe8928ba4c8a174b2f9ac6f47a8dc7463c2171c5a78dd973aa6e2042a419b4ea240aab5d64a3d20f448f76a38e60e94671e33576599b3b20ca5e304ba38febad769d5645dc7fa47df09743d84c7126f22f6b1739b355997db3e59f36e4ddbd7d2dd512c7009f69168c7c56d0f4d8c31c618eb30e8ef646d9bedacd78bf1dda13fce792b0a933d68eab89f4f17ca204f16fe743759d8b147ec9d754e677b7735092a43e64a7767ae599bb9cd9c4a0ce68f2b8b9cc8954791135d77efbd40cb9c522f587afc4152e5636c09cb87e047cff13176e48c8fde8fecf702721cc23986c839af1590807d337bb3d4645d0fafdbdbdd7bef66b78d007712d4c45a6badf52226d9c77f5838b24931086a820f8024cf8fb1244e5e7afc36f84933c7318644cb4b1caf8ce3679571aaa6ff8c209ffab6225973cc8cb2cb54fa9a7775f5509a3d2a9722cfa581af4e75b89fd2e9d3358f47dd3bb7802fc0912f36409ece15e0880ff15b1c2fb0452964fcd6ba1106acd3492b5046529424b308706f7640c83dddc145202e5e80a3a80439c4f1d47104e510ca600079ba2402f7902f804c9de7de9c553f5d70f500e4a5264b8b98f27430b887bcdbce9a67ab797dbb77facf25826bd6e56adf8aa6f3f455b655b40849b6fbfacc0247a969d62bcab24ed3b43b71c0315ed405aa8099acf85decc8d3cb2ffa2187f9bd266247d4481224a59101597a8c1d51f35272c16e010024e823bee6f1c7f3215ff38a5a59aff1367e65b794725bb92eefbe91979a668c3e34d7e0ed9389f02ac71bb5d65a6badd57fa4d711e44b973ea59cb4822025b887fce899d3386de4a5a66a7da969ee24deeae60232d7f465ca34fe642a6055f621bf2747adc60f4fea003b3af74615ea68c60834773e00f879397acc709763c55c5e6a9aaec2716a30fdcebd9d202503f0cdb1e22ccb3c4f56e6a14a173549c9afeeb34eaa65eb4b4dd47d26c11df5e83e3f9345dd27ab88490e7d9e5297d3ebdc56321f9ab6ee2c0719c1455eb2cd3bb887fc9a698e35c9eb630cc91312279b79368bb2e4e97604f9999f7162c2e6ad683e34a58e31245a3e7ada9e79a989bae64333cb8f626203a20e89cadc7ee671b0cc1fce4b4d7227f1d69d0b98bed4143d89b79aa4471d73ce39679c3fb7e7a3d24c4a2d947e17a150d444deb98c7c21060421004865e36eb1c678c154b27236812595a2da513aa79c73e66a5fee1b671938ced891d8c79891337f808f312359fe5e23997a982a613ef5e9fda835697a406464d910505a696a9ef09407d56145fa943e347f969aa427f168a5b6b8ce4dadb5b6084c0ebb9f4560e8f4a2e8480e53d54a3ba668299331c73a6be6144f3ba7239d80688e5012a233a2d3a55acc729752d2d2c598264ab8a0f202194a2ef0d0c51364ecc0041a3e785b82a24c771b7efabd1f63469e04259155bb199d48f4408394131c41860b4dad50f54656c876e88e38b3c60c21b0d032822a53b4543ed4c8116cadc734de7abd73dece34574b7d8ca190460ab637568dc65e4eb0394f28f5c0248d3170b21013c3a2049fc5504042005a945690c28c355f6448c20a238a5e417cf73186c20e643045e18954218ca1b0f4d1bf8fb1579b975e27d39cd3f3212fd53ee20f9173648cbdd0c45e62ca604ab59deca8c4ed74953d0c992a1a091080008314002020100a070422a158401e51b5b0ed0114000b91aa3e6a4614899220875114045110429031841062003004110308ddd4196848475aa04346e6d0a02964d2416e3a48eaa3114b3c332d0dd54e4a0b82d4a039c7203b236eea7808c2671cb37707897ab4dc48c0b74604e8cbd347b869126d39ad4c9a25cadc3a4a3fb20bba712915c5907369a399cc0cc7373a76ef0e92f469dc5d318d0f0d3a25ee1cebe928373888d04b0bb1c52c19694b0adce2787a7718d28d26e89291b969a01533ede0160ebde2408f8e6fe7a0671cebe978a3e31e1d434f0749b7344e5f46e2a4811e71996a24ba2422d6e671234442c75e2db46233694b1097cb230831c83e8bdae9b1a3e5b45c236432644d99a8c61cfcb10583a2f5ff495f37fc62414e69b1fe128c30d3564dde2e9c2a6dbb916003c0da62590bc5d6e2ae9ddb639e83436e930cfa1eae990f10a859a6f741fe3e66ec57882b0b7fee9290d97ce6379f49b4af779d5892c4864b8af68cbd59a4aca8f086372387f6919df163c6f332319a7011b2a425d05d45024de8c92991f63af5061dcd6480c80a32cb44a0b6df7973f3ecbccebed66cbf1614651e6ec6d3d186fcde6ea8fb15ac67efe27cc2433f48e330015fed674d85056207bc0381b4dfc4338cc0fdd445d904e9987281f78bfa9e93f6de8d12b14c6e2fd2c175edfd370f556202357bd0b8665d9d50e1346b5b4550f05395ce39b2e44b5a047f4da46d0794706c49943887262d42a37eaf1c500fae87e796d1ac027df39a03697fb1c669ab2f1fd12e015ad2b720388bbd4a8f3f47b7094d8f68e271da274c02396c0243cf6ada86aea7d6ce757d13034066df74ce68f1faa34e181fbcead5ee32bcc7a8acf982b7b6e87a91bf6709c900b18f89224a4634dbed96d3453e4d2a8bb7b27dc8855464e5c13ba49c40ac5c9b37d7779e1e92c1adfe4c900465403a7c5f3b60a74765e1011b4ce0cccbb4020c58ee2019c15743b993b297a4cd8689273f8fc850b0d4fe9448c03442a2de40dc96c35b89045ce3b485d4c475b05f703a050b765466c2059b5f485fdb57e07ceac3f0db3cc9fb4c056e511226cf4f11ab5cb5bb9fdb55648115fb391eeec5aa37c59f214e08ab342d97f6d7cb5c6a9edb0c333ece03d6add53ec153a19af47788f53266788bbd6a1d19b812a121f6d006495f4ed1d3f36a09b42a919ac575f09ee2588eb0090d92733ef28dd6bd13d40e5887aad52f3969bb7bfa2f9b14ca21b5873fc6bb775f2ebdd09d59a9b4820515c1a16d30ac24f7a9f25ff0dea765b257efe9dbdeee5d308628dad008e3b15a4148a01a90d273401e4860e0d9e223a5e5b1f7138fd9bafac6dea98bdb051c8047ede4c331c461c5d12b3398cc8761fe50c2c9c286aa5d209e7bc08b8101835bfd633cf5ea20d67e0342675fb45dd6b2155df9448c76cfaea0620a35abd63c3f22c1506d003f3442e815e8c727cf3cf893d1618e669ae144c230a218ae8079e46f98bf47fab03f751b49186951e75184d2fe1769e388336c5b763168ffcc7d436811d04f49c70d78c3f447a6ea44a309d414353d5cdf5d0f8d5bb72f38a430fcaecff4e686fad995bbd444e8e444b43096c6a803cfb9126329e360d87b25d6d9cb5896fd07f1eec41d13656f7703a530701f70499c0bb23e815e7018e46fbbc1f95fb129e9886443e7c6412f22541ff9a713e1ca4ffab81d261b0f3ff3bb42969bebfdb9ad60dcaa6801b0ac2bc2ddf54965f40e3bd7629cce327e5a607cc0f2bb0ff1957de2093a524c7199f9112c3d220b302b8046e4a8dea51622d9dbb0e83f95e42b8a9da43d645b4a5b49182eea84cc7f95393e06ffebdd4f0a2f8d20d3e24234051ddaf91783c5b170b3b0df5dc123a49551b4a2a3fe7a5f8e8e1d2df6874d306c47bcef399ce616f7d825a492226a89523bf5007bc6992611fc003472a794102442c0a59a6dfe7605b6ed3b3be61da126441eac9b8f6e43cf72d319f2e00e0064132388b11235713d68e2d0f0991b31f2f3142a61f860c5607c409c309f1c7de9f3e6e60f7763ab90ab2f72128a2109e25f27ed588bf8b5bd0b7e285787f0469335f3910c70e424b8ba10356dc32f5ac6167d48218316906f4e996c3918043e18fa9b67531456de1c63596f3b0e50eae11a620be6247ab10d8bfff0b7aa24c45c74ecffa3c0f9f86de75a0194d1e04d27e156766873d4325cdfde96d2db77ff94d5ce96663e562da39828ab7550c17ea9d28ba627a8ebde0ab216033522c1c14b8c63e05d44d4444b15ad10c89110140fe56a889f30e031daadc1a9575e276f8a61d71bebcb81e351a3afc0f54ed1b416ddbc61c0ac510a988a2c3cf1f63751871e19209688bfaec5b65476daa90fd383cca15f714623047013312d4be0c8d72edd68de079419daaecc64e52193271e3a23f3d5e048f8f5f341f7504cdb2b12251ffa75f2ee8dfd39edc999a9737b8186181a11b068a896c8ef93803b6a0ba87da9ba342141a9e2cf17e36bd1d0deb6c62393131528c25e9c963376f1d5567c011d1b5a3c974a3ab5275c16a38655234db6b491bff6b919112b96459d061b67bd849dcee27135af3e828b8c34c0a7f702e3546ac26b418f589a109450dfed42895996cf93168a40802695fc4f2d6e2369a131bc360cb75c95bcc462659b5c10a48d290024d294c54b3bbaaba064e8700d5faef9bd031c0bac46ffbc8c363ca30943aecf2e4dcc4d89f4f6b84a4382d9dc4d7160c4f697e3e34b0f3a23761aea9cf43d029bf2f5ace4239b4cd7edcbedf22d14954e2c87eea66f704de4ec845cd7b9bd638472b08850f1b331f0f53c02383a54d04335a665d5519d0587dd28f9f9f61a066a2d7a03dd201d499e5d803df561796b32b02baebcbdc50a15bab66db0da763fe101d96971f4518c12a6d1b40def959e569340718f626eb28bf0ad6def27746a5e6acfc903b264820e63e94f375d78a017c7ffece08bb051ac74bfdedc040e402619d4527382f05209bb649e5f740c15792858af8e33d30ea147fdc07c8ae6657173734c0b264433080a4ce26bb3cbd7ef7eeaef5766c9782f38b1eb774f9ea9e3e030387255e521278f1c51bbd1bb7a5dd415934793003b62aa1dc43ca5c72f2afa39da1e4018f10435cb443f664c7129ee93bd57446abd495f57d6847b622f1f659c7c56f5ae62ccd39d3cea229ed1fff4700fc7bf1a08bc1a592905b248fee77f8e5c9748b53279f17eaae614cda198c71e15bb46253768205958b169f8e936d1f57964bc6e447fdae3497c4c8b540ada6e3cd21a96ed3c28f64e20db3e18982592cfafa4289d822a40512cda5e5fe9024509179fbce8fdcd85c2e89674798edc04936d5b8debca729dbaedfa3c3c7b0e06961e41714b19c18c22970e9556a30ec669163f9b5ba2d83402ac32cfa1c5be30ea6479c1d7f9684ac90c1bc84665551506e1ba1904e7a229bd2260e310a296a555f317fd1704a0f4324d7178db42e889206a1773471ba8288a414b4c9105ad4c13972fb34c6321c256a5d8e8b53d354bc96bb6090f7cc749a0222879b3f56ed830ed85821fd5977a33e7302fc8de709bc1ffe442b1b095a595717b15a97e9bf7e34d93e19b025976be6e351c86e5315ad08dfb082c25465887468e98a854ee077af2dbb999ae818e0532d076379aeed6c8b3983c2866abd4537d960a75009af078d9981f9f3b5b88d308ea9584f0eadb10eda9881ef01b5392a3a3a3e18d592b9d8c271fb0b86168852af5d3764889e5b46af61a2663f1cbce7fc9b3c1bfd0e1fd41cd65a0b2a960a0cc37f0323ae1841625858117af39f388ac773bc1804ff8c7a52bf2e29737297e249c87475fc16c26edfcfe623692298b19f2da4d456e0317376ebe37b68c15b0286697a9dc5963040415a655e60cb60c35a62bbdd3c72b241b2df063cbb72dcd11d20c59994d9a433dcb3f12f2a20f17ac15e7c15b82f383b3678961094704496ce3fd6e18988f17e85ee3aff946f74babf72181e3260f743b563fc0a6cf7a717d15a5dfde838595ca129d5d186c3d9e3166b3c5a6e0c704812f818c7b2fdf3b3dab6cd093e599e2f4d79919bd6d5411106c4ac2e2aaba36dc9f460f3b461dc74747f783f666d442fc75bd7a454da3e826d0be3152d68dd464caf2c9b6a7f4790852fede4cefc144d9da20bd7c4d88fe1802130002c5746f16e96fe107b74fdc9f8312e2a3413d41ee6c42c5236907a06bc2df01ffcc91e3ffec58ed6a3dd9df82aaa7e81ac9b41a04335a4fb6aa7ffd9f40aa85ff06b3f692831a49cefef7ebd27320221efaba069a0a36d44f3373814331e188e2586c940a8b58b314dd7571ccdea00c42a16865aa9a7d149aaef405e82c689500525d063ea7b2bb2fb7d98b9fdef637594ef0aa123beeef7277e2bee8cc919ab9d0a7ba7b45a8b65cf734238614ac881cbc3709cb68dc066c0fee3ae02ceaa93bed500f671c1976e9156167103e8e0a18a8f39b9c1bc38b3dd8af353582995deb568c9ad2a8df44554d9924002a791e7de8ccef2dc219778513c4ef0b8cf8619cf4221685c2692f6aa82c8b249ac0a2502f79912ba47b735c7bc306f9a9d7431bf22ade854f19a5695ceb376de3353c54df37074b2f353df366b34b4fc78f319b5c5ae565d0e40ef21251f94082d6398070d3e895ba62e624803c56b4245ef6ba3ea3602daf70be38a64a21e1443cb678d27a2c142829cab825c55cc7c63c003d6a1b3d63abd1f288cfab01c86903932ee8a5433357663f154c374b2a253af08df50cc71ef1f9963ba24daab508bc7205b3f4acb6ff8482e2fa10141077281f7f11f9ae5bcdadf21e73b30e851a6666449f556e19945b9123cacffd0fbe83722ec0ebf3e6ee947e87fc1c9fc34e8cac9cb7de278e241a8dd1fcc69b4c5d895fddba9a95f0ed1e0127c28215f61f3a6293834569a30e265c10c51a13dc40dd64bcc06c8df42a446051220f11789a0cfc2ee550d0ddeb89f6073e022444be21b0075bf151ce007de4e283e7e060cd2fc2aadf2245e6ee6efb1fc4b1cd650e24f8db0ac28feaa9b84a593d94d3b0ccd0e31f376ab8be494586f04ca50d55b69e4811ad54cb16e609a441a91105cb06a878098300361082c7a3ab14d15af1300893309311c74bc741a599e9d4ef277aaf98867082f419d8bdef642342f5e51a2ac75b46ef37cde7c44c292d27e982481917f869521b225a5bcb45d5c87e4ac272f644ea4bed69607cc16e6bd8c897579fcffef8e5239398c2f86b5824d53a0847560e58d39785cd23bcf8ece94ab4084510d1bd3101455e597f12bcfcacb9b3508bf00aa4c7fab2d0f72f044db8cdc3d3d817e6408afc4a69b2f6af13c171b84ff00a6caa6451c478d1748a9b3a9b82e2200105a5f28584024c43698b85b08933a2210ddbb7b033e2da46bc7b125a8f9cd1c94502b1a30203ec713aa9b83fba7ed000af2012b2199094ba8de08e52cd120fd7982ad274a4b8d054bfe014e050530dc4d463af707c64b8cf4a21bc7b90e6bc40bbee1178c725b2149821e1eb90181ae2fb8aa72725109de8f500c72631242094933649b405215650d514081ec4dd2826ffd8a2a519525d2a2ebce1b1cbb273fcccb26bc1290e3389d18c4f88e369300825f70dfb4525b2429e0282e5adf86882bcde7f60f4144c3ebe73d54d033358bfdd7fc6ab0323ca9ad4eb1a3ab7c74a5dbfeb04e9de2c597bf0a0bc6c3f222183a9c2a086837508180e3d524cd455948ac93a639859398cd21b332b16ce2181bfc3cec321ae67ffc0f8c3efee3478091e89dc46af93247a2e185686b7d12f09e2841e75e4530bc57cda750a4e84d100b29ff047036189ca5fc86348e588c92c2bbb28f6e5123b668ba1b5844603b08ac529803788c18d0d2e869c5056b29708989248d494d4b6fe20ea1a9742a9d90f07fa9140679c5b862ec1c1120828a6d28916fa650639847b2ef4a3fe436ad5dc15960989876eb29d4c021c0d775a11925915f0d57061f5d61a5cc935106810dbd817abbb418bae6abec1043506df9371d33f574c56eb41aff228b73455f6db1ff2490b55c699f88040073428620de0034e2064c229753b1c185f67ebda092df9190dd1e983eb4f0ff814839c0a8fac6147c8f2666bb592a3bd2ff297eb915409ed0be182d44fcc1353149fc62b5851b4d017c6541ef18aa5e5f6e5fe2eec8f9c40056034531581c5ca49cb83bb0ba2b4c488f7b3476da19e5bd2ab04b6b59570a75d806abf8467374f6dce0e9b1d479d6d39db8e7d2ec1bff9f6fecc49604ac3facfff6ee1da02086789cd9a545cc783b6e7124d3f01a730ea62382f89e078af40297046ced302f04012bdde2a73814e6ecf6049a1aa7e5d1edcad2a4f9a80082646c5d79477f2d35b28013a55e3cab908e505a7090ae486981b863056a303b911bf28baef5e30f1f0f76f2770c7a19751f9bd76be2b9abf604a5b37b01ee1f63345059a094b2bdabd4849db9db6bc4d62bf3eb8c41d8493c57c4cbd018b4ddca19b2b7c2471b8e1e30bb1e267277ce8f7dd9f63806753224593c3834682e94625894dae5100f457cb5a554a766787b5f8add37614c7fd424bea617b03c7f542cf52f0d980868bcc76fe7e907cdb30e2297725a6da77ae8d8ffaa00ea322add32633cbb53816e8e72d7821f470835a99d1f6258d6f4ee73661e08e0f141abd41af663566b9098ae9d3974792a45c79611039ec4983d52dd33952515c1df684e0f474648c9b6df72de3664e61cfa04d018aad76a7c14c6f301b3b9a301fb7884a5ad8c8f654b09275b7a2071400ce967c84db5cabaf98a950d7b0629f274484cead6236bb7c2d62974fba67840547fe735a8e74690691909b016c538791aaecf1110595088615de4c08b0eeaccf3e2456355087f95c542eec793f8ef6379de2782e015abf835196e25b8f1954a931d58a5a13d3d70920b9facea2e36362144df468f0e9d38b9502f9f94d0e0b18a5c8b0455d8cf03c9b61a19edce72cf3bd6861a78166a4c2c2506aee78a01a589ec283cb28430e0e1dc057b01d1b7fce9e891af1395a8e27a36c0a85fc7f21e3ec3948068dadf782ef3d2efa2dbbeb6e6c4a6627c5fc233408b9de440eb94a8b05f8d46b9b01a175b2ae9a6b3b77426078f0a70edc0ea8ac101d7f15f69d80acc39499aa32a45c15e1953020ee39e4643690c7ef15c081de62d07d814c13ecb5dcc10aea2445dec791662b9f4a3452142f1247c95be69a9899337c99f56e10577966c57cd5e1a18634c126b04dd6d70cf6d5386fb1d41120c3404bf6c4aa690a27730f31a5ce69dfb3df9b54a002028d7e747c8706b1762b2fa53d5ccb835abd43c7aaf003dce2d8591c80ba0d0a85e8c16113f5662a1141ca3beaf4127bed23ea8d1dc7cae0527d9f22139e41bfba1d9460e887a3cea1c58369a5c3e8c803b9a44526d3006891387fcdcfb84bbe29bc31b4effe3b5998f9c6be9d49ac30200ed1f0f1d709063db35defacf189ea8f1f1d6e62f2c976e49a40915278c7ba50c4d358eba14daff8c4f3a15c4a3c957e66f406cfbf45c82245d08772d6d2b5c9a595d73e0c27239280f3b362a41f328e3244764b4498a93cc7c618e76eaea09bb08b6679fb9ce55e64de1fbe29c0471f536f0eee461bc30b1c5a1ad99f97a6ec0d1f9e83297436a43f1fd29c5b2712433c69dd63ad19080cce9c58229c2c84815207e77cf43a0656af3e687509c3e8b12fdd64a61200f1dbea9a65fbfd31560c9b08c7502458205bb73c47ebf0cec3b8f3d51b8be243fd0158a0821bc4f8eda48db3e583cd99aa3a01fc2c60c82f0665067a6af8e4dbb4192d1eb00e2e5093d0ddf4fe8af0c737817801bd2ea8d5a62b276a50aada5e9c7fc87fffdbbff60bfcf5187bbf0ae7adeaa8daf148da1850ebe83258add429c938b4bee5bdfb44ec237a293850facf0c3b35ca7f5e5ac3f35047c67e5032383b0ada32b20bc6466513330ca9c73d323bcf463a26d64452bf16f0778f2dbba3afa40b5d4a0e039961608847368ed851bb6b65a3627d78a806336b2962ed5fd195871da7942f26d7c05ad188637d90976626276f0a86bc3865181c28e626d8061773bb9b22a11f542f54fdbc626c4f53784994705ad50207b9af7f78d2e145b7c071752b1607cdf23bcd058e96b8b86058af5c148158b8ebfdec7d095834ae16c95a913261203ae4420872801684d16aae59ad138d1fe0d89882b9d3a3f32ec5363b78bcba54deae7da56c97b7101c1119f1525d685cc5e1d19a6ccf53e99697e46f99fe268b61537685e9cef8f3d1aa9a5d5b8e173f681c5830bff6cd283a86c5f18b35d4a6e1849198528e6ca2f9c0416ff38db6d424f88440ad6a788c040b87f5400f3d46e4b6f3628f6fbc622d70e48b8ecda8b304a0b2a9628e01ab19410ba2055da429dabde55efbc07bac25eb83e938280739e8b4c173ab5c44f3d826ec6abcc639d0f63703e4666a386544ec2b0dd0003ebcb8983d82b688d435b126247f647a2561a46df0ff3cb718cbefe07fbd67ad29718c6a13d3a0ba9250ce3172bbf1f42a38e74098334ffbfc8630049c9f2b49dc29f32d9e141fd2b5d150c0954eec582c047f52763bd2d404ca952ee038adff183c537e95898a9d67d3d8a2ef0ffc8276b0e95f54351287fc6bddbe4a81265e172ad1b5d2a2650a88c812eddf43f70788453862b2440138f0f41e622e4422af1913dda3eb158f63214feec650499b080f29886c4fed7c7b40f64d62925542d71b62443c943838b07e9e03e9463375e86e6b7d8086621cdc8d911cde5fa71ebb0e969420cea12d1056e643623991766af16ce9a2a8eb18277a7f937ac86cb57218c01228fee52839e7c02fa3979624979bf912888a49dac9c999b13f68fc7889ece24d93ca2c935ee0e02a170612fbc73e391c04c36fa146791e768571a8d6e39f45caeee44b7c4c14c24c00b10e3030ce99556ee03cbcd2e5087c04f0c3f8f7921bea9da1dcc2215637e83b8f209d4f2240ddda8a797ff3c7bb0af66ee66e73043625f73865ba87a9bccad3119e53f2fdcd7e37106a9bbabac2331757405131ea62fbe117d2324e7883d3a77c9ef54a311a830b4303fa1b8d457dbbff25f843ceef265c19073d9ea7edde1dec4039e6aaefb75e3e4453c5506b953934f529b83a88ee26ce17577e773a6ba30bcb8621f8c3d9fb9943dda612791a7afc30a21fc4f7f480989952397c39c5287a77688035a2cb4d9073a148f7b47356f77c8c718ae0049cc881640a6e1d99689f737c40ae2ba6e1ac9bc6f2bc64640f764be5c11996d28671ee5880c94a4bc4770a6d77629ce3e0eab8a7ace1163869ddd9f9a049578e394f124a0bff24755ffdf1e785ef465d9f48a500cd509724ee324f0e31de593bd10e185e9e3c67b03b4572bc54f1e1557232dbd32c857978ee030e556c792c99493429c03c528080cc3ddf8febb44c66192305e8c0e0ac889a198e3a3942d311faabf2bd0df82b68466cfd84e3b3fe69cb71ed75573445f1bfa1f4635eb664c646abecd4093952c4fa9129ab04ff84b44cd10341b67c4f56bd4a78054c65a548b89b1d580386bc4b310a3e3eaa2a419ce6e3272ae03cdd763e0190e785ccb42028dc6e85a5a097321048f089b76169e213d77329171de3f48ffa9107f3d495bd639a5f15c572d57b930c64a64a24a6a1ba1f0f4b58ca2aacc050c94263bff8e226172daa322182a46d64c2b2e6009dc1dd0a66894f09a03c88191325a9ccaa10ac9f8c14a649a532514d19d9e76627fd00f6f04a44aa618b7baaa88b2e7cd0e2a1b5fde2f99bc54110ae4cdcb4964bb8ee2127e27bbbd10a3e28894942e465a8e20f0caa3323de84f31c49dc95c986d2de343af96514b4b09b75d4f859bdf02aa439ba67a1c30a4a38b1629c76138c91485c9836cf6afbd71a39bfd1ecd9414cfa1f16fe5017d7a2be0204b6eb736dcd09c0c0726d42f9c48dab672ade064e6787850286147ce06881f0a882312a3a53adda882e64891338b6d21818f1c04ec8b5c6ccca14cf873b43199a8de7b282a418e785f085dfa22e093896c43e64f1a88fe2ad09afbbaaf7942655dbd4c8d55cef2b30e2527020580cb2dd8aca10178f9bd84870fb081721c8dc7af960c529463fa65e7fb339b0a7841a567a3b2023ff021fac3a5bfc548c0c105008c78ff29181ce6115383e0d314be1272b511087f4410eb0a8fcba55181c1271ea7412213cb564924487412bd83ecfe2a657f3f0bfa381f220d0c860e26442e69e4dc3b2e75fddd975911e78a2a8f918e2a1aa76b591d1fb6855968f32c57b154c478d096a1bb12324583b0874422171bc0f7e54fb27b15855430a04658f939fd05fbeb687b4eb47f92dfb685d980d59c8a97b6cefb84591c8d3b3b02139118d2e7397a3599698a96afcbbb12cefc2fadcbdf462d2f5cde2bbb404a48b3daae284dfd9765611ee6f699f8a640272369bdf6921f24a4bc4ad5f607b1859e0dd4ea8512a95d7123bb5b0b9c6f4a5da63c3f740049d0f78f8839ad2a150a6f2a10fd9c54de22a8874087f56ada5ca6beab0ea0b00f9551094d4b057464bc85b0ead0b43750d55845b8586ea56b9ed07581f5dec449aa9562b1b75080a7861f300413ee72e5a0579e072000cb3f7b6f345518860f5fcd3334520bb3afdd7f0d2444fdec1e0d49e4a5411bd1f22ca39264f5d0ac1aeb3dffd12c77484a9a0ce31c095a0f704e5a3ae965b976f9de968f99a5dd149ee9f8a497fe90f33dd7f7f300c55a92c4a436aa32ab40295e781fa9c15154e85b7705ff70616e1f4f0076200cb76d096e601d9d54cb25421facf390fe9318a3286dab12633a22c6ac9b08e3b6183aab53870f7203fcc07d18d42bbf4e8652e6e88287b0c38a1049f7765146a9c874d5e5c8d434ee4843d8775f1f5c941923b50fa85cb8dff607bb54f3760b5ab2a7828d0aab482a16a77755b55556073c959d3fd31608418acc129ba0162c99410eaf0c1a6f8ffcc1c619d55888961a25f52080c9b41570be2eecf0fb5048c7a95c8f55215a82f94f962a92fc18545bbb9d80e12c5a897139749ab4763a3d352dbef696d2a8428413f2780d6b5d9b810724d2c88ebd94bbadc6251e007043ac327ca9b19c21c9910e0e40a71eb53823fb0daca5b3479afce9340dcccaca4faa47e83c04d5d811af27098fc81122cbae542682b30703daec0c5e55417a7130fcc42fa03e221cdf2fc2113293945077503c030488ca7d11c02d6a0b59fe0127fbd4140f607a25b83b184ad06fb4d49998d252a4302e9c5485555d1264ca326fa0a3935e733d2ea220b32c888b44e1e4c4d830d94ce66e5b8d920f4e68c4c87e2ba3d13198c2694fef41dcb879d84f76b5b899f0fdb7d22661a6770c1d6183caeca3a1e9ff58ce4e6fd017c33f333429cdec7b05afa425f72757bba4fe80f3ce4cb40a036a454797aa333e308d3e3165892460a6703526502709d6bef35b66ba07a299199922a1f55e620374b0bb3f1f9b39dfd5393617596c15f83fefa44959bb929f625e58c264b58bffdc72a9b3e6e82e79196bf07f3d781d95981aeafee0fe341aa46253709fea5bf0cc225c728e259a5a76cb5dae371c3ed66f2e7f94370340451f6914c5e3b6fff6993876f108ef1e51331fc50e474f96244eb5cfceb593a12f75b9f6b731f5babc50958bf17e8dac6f5cc7e056d8444958e311eb2e095bd8bfba1106bdb986e32b8ce30b45af3f0febbdef1aa9a943b29e0095da95c77bea834ba82d2368478c9f239ceb5971b05e2229cbc1ceba224874f468cd4d3533f13511af3bec0a69e6409ad7102ea4b92e779d6f1bd4eb419f6b8d1c41157ba304fd667c0264018502311eed6880cf00096bc985482febfc104181eac1ad6ce73ea5b8fdc4115284c022a754eaa374564c941395a6a913afa8f262aa9b691077c472a04c0e191d9bfeb0aeec0049608b6c278da3d256d5435940752f460b5c9570ca14c524110bdd3553ff122fc1b25e3e376319beebc37717adb9ce3705a7ed20a98c9fd61409d0176b5058150cb65dcd2d30ace606526b4a492ba46d75cd96c6301eb86faec71a766deaa182a14ec5687ddf80b42b6d51832ff9e520e46bd7c94a875de2abfb5450034dfbcc66fdecfdf40940ed7a8792b9e34acbae3db27fa460bf90d22213dd708284de867f9154ed633f41abb8b8c8044d7caf7e01cd04159e1c6d0ad4da71643e1675ee385c6dd8045a0803cf8d084028ce991d0278fd127fe2e82fd2715cf9e16a651cbbec951c046662344f417fdcdb61f9d5209cc46fe7c5dc3fb10ad9a08e746170b4c41144eec03667683c0009e4619b094bf06c87c7b19f466f820985ef4d3353ef0a79f129f4d40095a9b4862683b38c9e387e010ff41e484e76bf4aef15525c909c990ad2f7293b90a23622d018c256497c91bfa39a112443b5f831899c1242039efec05bcfd87e19005d484691c39f6712f8d4a2743a51cb04b7fbdd19ca0dbe0d11c8975828bbae3d0cff4a417440b8c35a180361361c3833fceadb558a37c0c379700120f113ce70812d426b80cb52a2071df559f4d6faa4c67c2dd36afe6b08a829825f4329a3d61db08f41a2bcde7f8a1512a85a001c314d776d49d4a6a00af1d4afe5ef8caa729d3bbc907b421c16901d78228889f07cd4043a4b087555a579f7a84d45a64e3e3b708321f861d42599b03a2006fe912242ff9ce5caa23118795dd6e0930773bda3be8fa8e1095383ae0111f95674ee5781a652ce963c2cef8db6bb02ce04d733809f65b855d90440ede3eb517d931d05e66ecb8274265922642a43120311ed21cc401587a2c1a6a42b64658bc33340445ac4c43017643398423f0cd2c579e62438edc54dae8e013eb6c9ed611b527f677d98cffd1314574add5d3f4e0cc8c923159d4da323bf42564a6863cc0165e126b4b718a286a1ec06154fc201b35aded917b25493fedff1b31270d83101721732c228010bebe3627be325ed4d71d9b971fd11291a4f9514d40af7f04ac5be20fecf4c01ed2844a494018872d941a03964a07d9aad65b1fa09f9305c6b40f868d5501f9a68708644b1b7dd6b67641545a16c8413924252dfd541dabdb8c293ed3da35eba12dd931be6e6bf98f6e353e99e9161ceb3ef240359d16cc32f1f8aef86526a6a92056709a0cd44eb89926c57ba89ff26e1679e411fb25422aa08a45a519a7d25536c643a5a95d0122a8822e34c3139181b41b8103912ae3ba10d9f644082b38515d727032f13cbdbb83b35f0592beba09f84f3ed5f72bb8f6237444c2cc3f867ed81983c127360167509aa32cd13f23225d672046229978b2c35dd61759fc1243d4b97b097642fa3d66e94580e73f07ed9469ff321b6ca6d517d90164a2643632033f661d384f10225ced0189214fe723387780355b5168b86ff263ad56bb77686169e24af8c73b250ec690c9e1f1bb4e79b3e84ea82b6c23fbc09617296d982093b90f9d49aaae4d1b52d1ecccf667221338f44eb124a7b5721406f420a0699376723ea13cc2fce062486d9e3c2bc223848dc8bd85ce2f46221a1ff19d9d3add31010c84f3dc4617a0d3ccb8369cf0c726c323f148e4a4d00c5b06e77a4286e9c189db81a31286f27c8e6ef0172b68630b944f9454a22846d40ce9d7b02182effef2c3b605939363b6c841daf9f6281b4aa088fae051323bd39bb88f78caae5714a90c16b92540204c93bf0c341ad9f8b57cf00494c714efc5bfdb39c648a2b491d5946c6f515c5e4123a9272f97480980fec7a2bddef53dc24fb86bf76af7fbdd8447162c03da63b919905f71930240d12c673a5c8bc18ef888c08890e8a80397023ea26cae1c7c2b23285b0a6fc2c5ddcc01b6754fdbfa80acd514bc144b5cda665fad0f41d7323d0b2e25eb88e1eb17ddf1c0621066f04349848d01d932acf583ba0599fc8e12863fd0dccb103ba294f8767da3429566b1541c230b7c3533e5a8f62c24844893b0b719550f778a97768a0f4758afa115e193e8ffa337cc37c519b3d207ad887ef92fe7f8b618f892fe79e836909626f12373f01dc0724520790fea3c358dc5dae0e4fe46cbe9aa43439e0a072f0e86d969b95210548428191636d5ba95da6836291d80a947836ab4a39afde001706dcad525605b531e0c9756543db96743dec63b78c56c3a92b6b57123df8142c73ef4f13408e70e2711b943bb91546f2168d11d7990198f35360f5a48401ede8c971ba8e47583e8a3e240ea7be7f9ef71100c314aa5d2f251bc190d34d6f86ebb528209c16e378533359f25985e5a23c8a846a2a5b728e1abd12d84e9f55a4efbbb40a8a3a9152b6f86587ec0cb4a1f3148f6ec934ea41a4fd8e11dae7beb0ea512dceaec47c4846873cd9a44c260171a9812ee8253c7bd3efade0d0198b03798125e7e0fbeb0672531cdf3c3162ef92a17a46ca97c74ff3cf3152d98e2e767e6b405a5ca5b0b6980a3ee4f1601958d629e5511a4851655ef29edc0795369e0f1d9efbffc83e047d2e55fdc3dfaa8390481f230ed9ab39e3eca8f0d620504ff353add50d2a7daa5ed02bfb7e5e61f18db03b2eb8ad7af04362350b1ca26cce2028ff6b8a2796ff9ec54666a2df80da961f6c7d9210cac4469564292c38b9e8a7aa57f5f66ebdbf8a542227b480fafcd55f7a262690343c9079d47d2141ddff2787bf1ceb4a97e3bd32c2234409f6b14cb0a606c2ec6122c393b7ab1d07d115c3f38b804da869501d70fba72837376fac48d70c8eef41d7daaaada9e21fe5b3e258a71bb34da4186a993d5cd980f7e43ebe8c83b1c700c5b91c7ba0f35c4ae80b63d5fe14b2016b290496d64cbf18776cafe72663aad6e6ab3277f1079002e31d10998928d09267b2cb739a86cd2472a2364c509ac1e6b7b7edada6830c2ddef676c9966d03b48da3f0f4f3100a3b81d4f865273b6db7ff59a053a621808d90f03505a09a7fbbddefe13d9a5b63879aa4b28fa416db14e79210cf56080bfebed8ac1114b72e85803b60b2a095685f610508016ffc180864113d63559aadec101312613979a534a53d3a231d14bf8079b249cce2a083b901656f1cd658b3386f344bba04a9390690f077bf6ae3a718b2a6af1303ffa0d89a91942982b4343a16754934b152b6826347048c768a8730f20bd9afbd0dc8b170985e6de69694956a860432bf1a4b3654f4312036764651c7d7da8f1cd29a80060ca182c7760aa4292d6abc857b8be6a7917c4c5d2a32d306dd776bfdfa8a5eb457bfe8a72c98d54124cf72d3afc50da204f4a3fcfdba4d2181362979f6a25a090cf7a0b736e85de272c308b92307dd3ff84877ba300067a96520c67e5dfc3f0a47f2bbd96132c04bb8a24502b154122e859cc28337ca3a504beb0992c8c98e2156d8044f6b858ee1a1a0a18fba08059c4b33f49dae45e5f0416d3ee892cbb29e4d1cabea1ff6083a61b462717633ee629be6b2afed2d4ca97a7ebc0f4f4e0c958f372162866ee3036af138ba0caa6b47768264280e5994db1873a2fd773f50d6d5ea53cfe26a13d9d213bb5e0d970d84949d25589af309a4495f4c616275144fd46d1bb2e149f6a6cd4d27d127c1630d33ccab6a94b65260051536ddfdd9dfedabca84cc0a2e69d1e101262f7cfd76551e281a3a169c8e824ede641827625efa83eb94408f9ed82913c5e2024af570100f832db65dc94c1391e6c8ab9d53ea0da20942a7fa301d0cfa51f8c9a2e211f577acce290f68975d6b3cd979cddb1a9bbb115ec1a1626b559d2a1901f748a51efacfe2614ed7d3e82e7ca2b8b65e9056df096fc89ad118e695698d40b3f12063f89cbfbda71d9696201ed21ccea3bc5f603ea827e66e5c95929dbebb48966c026880d7c712c4709b88ff554e7228833173b2fd3b76f522612e19f9481cc6078e99540547a32754d2103ac49dfeb475fe6d43b99c4e54a97a4bced2ba7f39731a04b6469339fc7ee3cba4d522c37dbe19240e5b93a598d803c05d5881482d3ff09de280af99be658281b0d0a9d712e11348fa8ef3a6a03de717e884f74f1c8132d7835b75171958d8f66ffa773117e2493ae30b537db46e86089b5bfa94521e27138a7c96b0a13a552569bab9d7d4b3fbeba2cb6f2355a49fb5487639beca570a502c66fbdff2b3f5a6ad0a75fecdb842b96b39e8b0829f600463718725ada5d69510cd53cf09b346bdee5d188f7b4eb3e44717e5d47d3e5641532568e9539f74044690f7362a93a4493b2d174e3de177a151f2d6d3d0b5f4749b1cb6e1fe3c09e860e7b5741c99ff32f3db9093daed2991bd70a59d2cf5118b56b729011e0e357ae4ea40d002f787e39817001bb88c319d92d8ca57645ef3ca6fc17ca8a7bbadddeac3be907ecc77f24fe0e8c8e1f8558dc9ed683bc9580b331176531d87cb76e02cd9a89953c7951c6fa47b0dde41f4d8539d7752db99cbc81333b6999ae562cc292a578e6c37c09a0c9394c95c0197bd6aae582638af08c9bdefe5d1e58120b642675ea04e1913d2d800483452a1f8f0a738160d020d56ac71bafeae0ab6c08b234baf5d2eeaecb1bfebd64f4722517d075127f2fda4f6530b8483ad9630b68ea826765a96204060a0f3c4ad8c4847e9706af00b13ed7d3dc40b539eae3400a969ed73b1508a056b36fd4d30edf9249c2c0fda21e7d62be24a01290c02c8453cda8c98ba327506bbcf4769841da024536c7e93750e3f512fde1dff623cc175b7f03c82577f4775e50c4e430571e0c0010046cee780426075a3b387279a03841e3c5c5b13d01d90c89c1ebb43772579c881511a2170e64269987be568494e9b02f9c78df92ae491ecce2072809dc08a04b32a0629e5a5c208424e0414cbe722bad9c984bb7dd011e124fa9a08ca142a5a166569a5ebb3019d75d46856dab93521f5fe43068a9a4102c0e2033d54438ffc08c14cd93d1ddef82e835bf4a84abfce0fad0bed7ee434ddc21f12bba44b90c54b5cfa827da1dda7c6bd43ffc9064a8b1f0e50307d3d28889931c21190742072df297a3025449293fc3a795354da846728f27bc8f4d7c16ef13e50570f03328f4109c02609470a3643be206d601a5075735406bdcb15aba2ed9bde334e967e051711d71980430876ef80c8446c968da3396b14065ca32e0f6dd9f2d994995fbf7874958938975c2a8d14677340d1815a1e59231c6db37189adb0dc10d09f853c97fc4244a890ca2aa9fa779fb1996ddd4cca811020a75d1adbe7b680631f49a5fc4b2ae9895e9ed23dd6c15ffe836ade3d71902346398bc4724f4803d8cb7d6b2ac954931d29e84024dd1fc415161288789f7a2801fee5ecff6f0450a1c8863976884237600e2e7acaca69a46aeb08840cc1ce1d0507ee246afe88abc8fb9f40cd3136789e9fe5144a80663b4d4952046fc4b2c3ad4c9b67398080fb795cab3fdcf674cd74265b08141e3219ade141a951983d82ecfb3ca685e0876b7c1b97bd177134cc25c049b25737cd36965a20d0b06f92339f64139648bdd8e676af01695e0746973e762610efb4ca944386ea4c7a157edd8fb65843c8267596e938540efab57b3d90660c6cbb663309b777cc5e338b788469aed12294fab9387c4923a5e8f1308f4a401137872d5d3e6a7a9ec5c68df56152f618cba360e4371ae140785a04c8ec8af9a090b7c57fded052af15a2e02d7e8263dd565707082bd31e8b5b43d53ccfeae12cd987b8395b93146017220a31cea8fcb7ea878065350b1ceaf86f251650bf156dde21900314e13991fdec74ccdbfe761432415222daa3a7480f00758a2a0f2e54eb891a02a42741c90352deef199ffd87dec06bae1dbbbdcb193812707bd05b63f7977e40b4766aa04ca254398c001e461eefa505021392aed384ae57252495d851f51ab176c4684af3aa93312f9e7d3ea7a5e12421efd12687773147341e53547930e83f37080c760be8ed21d49c5267dcc48c117c278c3a7e2f4e73fbedba5ad7dac3ac39cbfe77508f2b74c58835648b8d4c4e0ba9410b2c9486953d51e6f1d8de43a1c33bdc6be5e40f5682331d45c909e6835e6796a81f6977d10acc564703493c6f632d85d2390193e270262ccacd6a8aecfd54889312f02d2913be27324cc2dd0c187bc222df027f80648af90329c23871b16f8867854dd07384a41c7bc6db25dfb450f5385c2814de3ce9f38acd3e44e0f817c24b6fbf460760506aa524ff7e71be08f7910c6b38d0b8139296bf22d144f87e8f1171cd983fd7df0f91ed58724cd503b72de7e1bacaec836622681baab745f81f9950a095bff4ff6192e0f0e34366d19069b5553e07c62002d54dc8d948479c635e8ea91443743e89980b4d273d52e406be33a6953cb3148c3746029264f868d9bdaeb8e00347ac37bf2c97e89df7e19f58532b8770e4ada5e8fb1a58739e062be189956ef84124e82f0c0cd0f4c8682380c2828b562dabf047ca0131069f9b8b2a969860dd846b7051a2a2be67e05da9824f85109371becc87c144e909284e85b7912e0993088b561fcf3190fc62857522f54a70165aa7b7ca3c1fc9806e1aa9af0aaaa7e33e90be40a984ee81c05c38723a14867a7b82ceaec74d6c8d8f7e5cd4e54d32f241402ca9465b5fc5245b01255607680180e86c26a678c6d14a2a832816d4072f1b6bf85f7ec08a64f50ec37a4c6ac3133ec366e62239e784cb6b5aa259ca3e02a55fa6f304056616dee673d1ec0c47936b0a5d4908efc728f0638c1eaec0908cd2e5f57d6646c14d7cdfac683e2ddc0b5ea4394c49e5aa2e85b515880f3824014320ac65505cac85859a0d4ce527ffa087196249252e1e5d641c72061a0f68bd7723009fad9359ca1cb617c1d6d26dabb2e3ab6905df780354cd376b585dc4f10f230f1267b457781c71f1e71608074c5433872c62ab47f74a462705b203cb7d38abe841c6852ac735b6968e73a150f29c8789ad43e5cc08a6dd04786e18137208d2929e61816ee0fdc8b8d0d4b35eb0babf282bf38bb9d995398f5740145b990c86967c526e987a4fa5459968d6a9dabe4e50cc344a1c838915e79d0858404b0888aed43432363c8986c8217844c1ee2ee2ecbbbbec00e2700dbab6e9b8552d38ede2b3e825a5be233906741999ba096b30bcfe9016f74eb74d6c6dee96ce3248d5d7ce840939d369a71afbded86f5bc19ceb26cd9306cfd10962304aeeb912c0295b66f3ecf93bfc3698ec0c522ced8ece5d9d3ad5f0b858fe4d0c4cc4c8a4e0f3b94442a10948aba1b8083f7865c3930291676dd8d79a97f4e09bd442263cb3908d607a421244c0073a5dfa71857c9bf358d9f4212ea4b5efd14662ee4e7160c869421f9de6dd70922aaceb499f42b8759c750fc282afd2d8715f8eccb40c965037134dc2132f74c196d4dab70b0dae42a4adc06f234f356c71d94bd9571d9921397544adf8a915c4ae20e86c4c40b5df82fcbdae40d2d32a6dd35f6d4e4da12648be7d150bfc0f136bdfef6f5e158a6178a2f3c07cfa15a87089a45c0ffcd4c1e1cd36a5f1446938cdcc996fcf168882021619ca51bbccd2acec8d95255c83217c44d29f955bb12c97d5c5ca59f20860fab5f49080d8ec6b17268f7e74e754873e00ee040d54dfef921dc1641c2626dd035c24026f169e715fa065c7ae3b16336979b907109045969a541a5e5920ee873b3763cad199fb46fd41c2e35c93a0c55812237dee8f453958448b229fc3d346e64bc4d700e5a37bd564b5659be1f648766d50f973bef47b14137af92116e5d79d4884b0daf0dee8f75ef3a8223e55b16359d3f7b414a98393ef149b20d3179eb1c91213dd459dc95e23170c8b05803b9aa9cd37f39ae06649ccecbf98c5f23072cbb9be1b7f7e6a9210e80eb88eef79000487f3aef5ccab8ebcd9482489fd2774b3f6470420b53c62dd1e079b6d261f918ad062d28bdc16464a25e61354cc1ee75cc82049fd215c8d89e46f088ef7d577d5fdec9fe1c8c9e9a595795724fa89e17930ec8ae5ebe5732618a65f721264c62c08e6e67498d84150ded8831d8b8279dbc28f2389df2e9f797c96b498f9bf834e58eb145986738d9ded82e41985ce585c56da5c5616af9826fe1619d5a74c93ba6bc71de39561e95b488fe1da7f60954e29a90926dc4efdd21043a8be12635ac7edfa99aeaa9580ce17c6336155b3eba91cd020813aee4f27bccae731bf2befaf8dfda329929744277ef2a9be10930f4461a0cd6734b8beb18062818856ec75ea35f0db36d850bc6c5d27021dcbe890964b5eb7ed781ac62c8dcd182772a47f37ab8987129c89b81e9976fe583f3be49a34ae4b1a2e89ab6541601865c58562ff1cba3819ee3d8b8ad2289a90b8ea9b8926827e09b0916a93a3a1b9c7c9bec53b0f0f07b247df2879ee17ff19123448c5764f918c215d215f7552b6f8222e320f91e9b48266cfe83bf7f9e38037c0f14ad98f597c565fd1ad9643fee401a1f815253fd8ebaa701b196791f14f0213463fd739b12c38c10755228d86b0c3761af0b3feabe7d10282503aec93206da9f8ebd08c59d9e872b06e55c865efe1b0f119f2173ae70672115de102303e6a9e98fa219495588ce0e5e813d7922fd18b60831ac17c3d6efb9a3dd39f29a1515f81189f3fe1bbe70e7d9f1f6221c79f6ef0941b342a0e07a0921d788dba4b70c5cd1307b85e55a837ea8c4eeb226ba5fd3dee6bd2a7aad8849370617fa7cf8d99c4fcb94180103b685c51066620a942d1bec678c638aa00992d60fa599b865b983e2625c65589742afa521b90399e00271ceddc520120f4e75e10a4848538b49246468945026a154b658eb504208a79478775931ee1fc6cd04cd44bf63dde63f3815888d7bacbe75f7fe27297948fcf51a8e1d8c95f3685be1be63645e87a99e770ad25186d2b1998b3d16f7ee7743470671091e900de403c64da3d09d00ba0f5f471211b0d167dd5fcb6a919900be00cca448447b164277519c448bb4cf2cbcf8465b8f788bcff22926e191a243c3cda75238ca5c76230e708f5155c2d64f00cead769570b91b447d663825925ec932d10456727f2eb2d8452ca810419ca9836eace87571c0dbdc471f1c55b07bf38b88df878871c13cd5b7d54036aee98afae717f94c3e90381fed08db7b661683e1dfb8856b3d0912c05f4520b9ca4d074e361a1acda0cfbe79d82fa683ff6e25bed08c7d45bc06df18985275dbe96b8086ca7f29b01a0ddcad1a79359a80e69ee5f284a68b03e182c89f7c7f1849037d4bd718b496a7def80a2b86e9c16e3c7e363912a4c71623be9b270d2f623f6c9025147e3846aeebb6111eabcc177ef638398ae605ad5c327d7fb946725f284ba51a4255105421c81e70e6c0f37fc8695589a0aadf21ab0a5df5bf4f564ded45a30a8aaad3a89a2e54f5df54a2976887f7650f8775f5ae70f921d3eefc4158f9249e9e7d64c8560ddb6db66018dd6f07c1f8db8379ea09cf0d3face60370da10926f4649d0ec9ea226d1a2187a2b6ecfbe1fcbe1ffea53968b44086780df67a93415335e40d944fc41596818f3f857da7c635099b4082e921166f1df4d49bb1c0ed284d41fa87b2a6ee027fcd17e116023293f095c06cc01da921dbc559bf22a436f806c167a6eea5e8d43c4b9af1c84be3d491d364162c553d1687f3e33c753e9e4415763d491ec69f5ce8ca11af4036aab844f22686314be32e6599d242cb91052f2b3862c56d8d2c663e23f3cec51d8ed1516778497aefd0dbbad7aea20d6b06e6da4e924d97f0a2d26f81717d3257830341028be72462312a625dafdc74dfb935778202fe5e39b6ffb5bdf187e61059b31f3112f20f6f44354100c6413843068604119cfcf5f57b1f1f1ff2740bf71da84dc58471ae990251a63a95e263bf0c4e3a73a91f2c60c5684af95a1d218bcf61c93e11729fa1ddd4b8972669f5a13e1e1803d446bba2f68c909c5a5726e85ca46fdce55162feb6e6787c4727c9e07a0ba56c500a909851195f2ee57ecf8370e42acd645c5c6b071d06079d7953ffe260822acb92e422bcc6c4047a50d401af2d63e0b08d6c2026ba0e26fa84448bdbca9e44a6ba3449dd0507ae087458665a2699108f18621f4caa8c925d3941a2c6ce7d1a7c1e5b9ea7d9190a83e0ae2ab6f3be31ae2f54c9154bd2c2d20d2735ee9038edbe756b69c0fb78e719fe2ca146ced748792c8b749b6aed1ebf427a10c52f358a673402255283f47ff0637d086ac424a19c4d9f2cd6edd182536ce6b7f278cdc4389cd0761ea642104df2df7636c065b68746363274525c3ca9c4fdd7596b77f1a46637606057173c456304879ad36a945d7f68b268d78359001667f75a763d4aae49b1630f527314acb71de36c592bfde0518fe6f63bcf5cadfcfdb7ac1491b83e1ff6aa2a76688447c097e9198530d82ab9a385c31f624d6ad7827193b733b76f2240b42688b140ef60ade86480bb77a0a63b4649aaa264ec41629499936fe81e124291beabb399a68b05a302d5058d61c0ca4557d85d2aa4d59e218c196379d483009a3cf1e2170eda93b8ae51555d1f1766316b48275b9a4bb471f2ff78699d7158b5acfd3b1490b8aaca8fa22e0ad7c0884191da25136d5a24d4af3da1086154902528ad29ca2514c32bcee104e9053b1a8766b85b31cb91a6c63a931090d854b8206c7002c3bfb55c67d7bc4516cbbf3c52217428b593f823a3fdee86a7d3e96508737c6e6e35cd841f4b325f5b6ab8afc7823681b7ee293c0ac6167f7c1dc2c0f659acf682ddedda04ef0715d85cf22d7f4127aeba860651002a766920326b7aa56972750db222aaa4eb31b223927f2062d4998520c6854570ef27e1edf4333831a8e21c73d90b0a0a466cfe667433e8d8db1db430c4b20c58e7007be81685defdaeb515d81d8ed40ab278e466b87b4186a885133e0a5d407ad339cd4b48851115896c30bfc226547ef592fa0746741462a7fe6f01ef0da35cce5ee96be7d815280b6d3144d380d6b624188b04e0c84c0d64e81f0343a879cbb600befb4bde8db6c0ab55db322370c4cf60023a0de2c7929572702dc831d496db0d48dd507dbdf51d8f0a1d37e0122fbd83ba22c3171cc1913a7088b1d97f2955ec74b220df5f7bd8e06c14b3c05f293f9f612608b13f7216be02e7d58683ec0429bcf27746d561661233007d0d0d7915ae72ff80db18edb6258b0230d0c1ff1b794ecf2d52f5b896eb719c6c68197a4778ea9ed6416666b646b9c9757f872ad979f331092980da93b05215f627dfb460111337cd7c30c19f2c99690ed09b234bff8a522fb09484680d6783123b936d24de12ebef4b4c8cfa0f4d7a35bf1649415ef5955c7e8621eae69452a2e89870d7968629a61899c01422421d2e68f4103537220650f07a897873f879a8b2b399f1be357e52d2cf7293fb76f624b492ebce9d1c13807f72021eb72aa3909a2c1f1faa47683a555e8a99efb79255857371d36f85ea7819d3e37d754a9341d3e7515fc402169b1bd70260b8dd6f2f5ae61fafa2a17bcd9f6f086938c37ef09432b3b3def176509e4caeea060640c08dadcc19806e4a1a4028fdaefed95e2748c404fab39d70948520fa3c7c14ce8215121b90b2513b73437156323392660eeb514c9cf1cd25a09ee2efa0eb342a3d10fc919c25de3543f1f7c618ab5d33751021e30496fc2f962e911337ae99841e2c7a1fce7f411e4b800733cf809bfbc848de5869c1b5d09f909c5070f3f69d2282fbe151d5cb26a1602ebf5c6a8b58fe13adcd03781b7d15c8237b50e8c35a12adf73bf92ab66b7dd350513f4bb82ee0f4a44f6c718219b438343db2a55f2387198b32aac8b5ec8cc6720dd913779a38b22e32d99e699aa89800c3badfd91931b6bde4ccc7b51c8ab6ec87b5da9fb53ae482717cd39275fc39bc8fa77e38fb0c080661e8ad5270fa83f5b1d28b16119d59232297acf25048b2a53d45b91496f14afbc6915f2aac4a6096070cee9c0c4e919345a565b9099f513195cdc7fda5c784515ea0cbb0e615c1991794d0d30ad9609555338653ae31ca24e4010466c11afb05400643bcccd8eeb2b536c11aa4a1c1573c8fa66301801c24e36d5565efd0754b31fe4869cb05bf933739a826ee104327bf6ba4d85fbd3afac0a0ed4ebb4fb4afa6d7ac52f3e5661914ce29c7edad359c00c26a1928637fc656914647ef34870748d8a6312135889081a4c3e8bdfa873239d31ced9e0e9456ca7e8e7c8d09e3e8e2d12ce845d6a1fadfe3bf14aa44c694b29d5fd69059e308bffc730ca12c129ab87412dba6428fa667972a6988ed5416af328d294bb70f93dbffdf02d1fe0bd661d54432fc4c85fffbbcbf6d987b06c9539535030690b112120cf357381e705514387f04829989aface27c2438a310f32eb74287f845245fc1f0aacbb65bd5aa4748f78d883cd24dc044cb26e27c654e04a0f7ed113644ccdeaded70197201c08bc8330b3e2a9229d05704a9728219748737c85356196ca55aaec070d27e8781c4b9c48aa645994af8d7c58a004cfdc7137c79745394ace3011e91bd8796634b8344a5eebe73061723e357c89113080c4dce895ba1859116a5701c596c9e6a64ced296efa2912366b53a25bc47e1270c1682989b6fc3315d6dbdf1defcdfbde716f09a30121db886a183d0cd3a102af10988e6377753e03eb082cd07df8e85a439e0d7e8538467da72411c44422f0fe2c9135e4c67d10a119150de43c55d1068a59b5f5b43610cab57d36904e6d8b138c83056254ef46834b213d34713c3f245b5e9c70b836e2b4fb001cc32d54ba189a5241f7395a85b3461470b4e5f17ab556502a0e46a8d16457e95dd67bff9c789cf50293e42e297e7aedeec57dd042d37e093808d87bdd885e148e4901b2da15a2b97c514eb0f3e4873ab66bcc981e15ab657683bd503b03c01043a1813da6cc16bf8b99bbe39f684ea72b1a5e38d46e202c94f0e597c1d0ed09a44156844746e4829ab9d28af7de47904970eb36ec68b9caf771005b40d2ca5f33d052cf087700fca6a5a5edb17a5b082c4fe5a2453c5efae64aeaebb7057db75b94982c63c04c8546b1b889cd995960082bce015883df4d939ec28cedbff1ebc75f5d5581c30318a3fcbdfc2efe38edc8a46e3229faa93be75c7fc7e763419a01f691a3c76add5ec13e2a0120cfa51b035306aec1ab94fa587007adc4451561ceac4130471b85c836045fb1873df13e619f709d789389af384d40a80f5ae4f650c2b2e0fd8a0d953bfc9dda3743fd7caaf9d775ddf7b1c2819c885a7510bfc81c0909110fe8da0c47e4847b49020d8f69372441b7e705e758e02013906439fc91e374fc21333ffc0a9b859121c74d972c4b1f6fc08817710c8fb193c5ad1c0bfc92f233be85d7b398a402b456db636c2401558d070d30065b5af4865148155ecb249e907dbdcdcb387d8af02da2db584875e8f0261f69584454c8ae589d774ec7907919c74a6c5f1abcb887e1021e3d582271cd8527d1f9f455b8629c6f4890ec465e8fc25f309cd316c36393962ac6d5a89e48bdbb06ba92fc7a266a7d1a74b32fcb7bf96e4f8f666e9695791e7a6df76d77dc00d51b2cc2953f4316887e26c131440cf14699cb2ff6ca65648a6a32fb7bcd3ece522372067e75562a951eba95a78de2ca945a8e8ff15c7af0cb902dfa3591ffb1909645f644ffeed0d3cca4083dccc5cdfdcb182386028a3242e9fb5156fee0c66495339ca753b46344e3dda2a2467dae05638a7da4f40cef7d486d86bd8dfd869ea1ff76b240050fc03635dbc27a197611e39ce5283775876c0254d5cda38e0ea016c3ea7e69ee46909f917f7a19925d825566684d3a1c800ea7b17ee72279845ce60e78be1d34614cb959fa719eef4aa5c1ab60f10adfa4631d7397f6a1ae361068403554d9e0af5845dbe71538d50ed8a376c74686090e76760cfbeeaebc5b91079f889b8d75eeb0427484751fe97836da5ebcad432d80982c78fed71720b0c3e0afca100c087fb78614fb23c134fc0fcd5837b25b416c8542540011acaa3b8958796354c21bf90c848c62110261630ccab788352afe6e78db5c1bebe23706aa0f9ab93900d0a20e36aa30a3fe813bb88d5e90aeea7a6ee2c057c0425c9cfebd856cd8ec050484a2e01575a4ec9a85b098634eb4ecef5053421721072b170af23717d8a20658c51518ce8741d94c377e926aae5a17bd3ad04c9b4d2b693095ec4f6176058c962100aaec933fdb6c0dae80599a6c58319dd0cc528cfcbb4b504eeacfa47506a320100ac51853aa524465c2b77b43d2df2ab526c00b2434fc0e8f62ff271ea4fdd82335e1a87c0fb69fcda339e0509b27ec8f2c2792ed0dc9123106bf7ad07b7819f00834f356daf3657e5262ad3f8fe9e738834ace594e84666016883b600214d97405c1cc6019af7e12a3dce6dc63aec6dd0d08e0c27a4e20652cbe0dc90ea5ce37a78662c150ab8545ebba21003efc0fcea75f928b3f68b308aeb897b7210ef101f6f1c45832eef353e2bbfcd98ae5c4e5d95f61756c0c0b2a3079642e5267da82c05564b2c561a6b171ac1cd5878af0e179dc84a04414678fea7cc2e6f6076d4af290f4947e032c697b575ff600ef4e199a7426fbbf806d5c9f6e6423c0626aefddd5108043a8617d4718576a3da7eed721d502887bbd4d8e8d1fc2c973ef89bc7c6e49f4ce2e5fc92e2f00607874c6c902775149c057a6e47b74567e4d6c84f3ce61c884cbb560ce7e2f39478ceba5f89836ba49dcc62073410cc904a30d12c9d3ac3c3279060978242c17d2f03ac24777c0f5bfc10de8cb7859bca22a97836b70466c379408bcfe59f0c13bb6a2ef96a052dc8805a2c1bcae61564915b3183e0756af3eefa8f78be6c3374e14a04dddf13c83d199c20d6fd4a448c3d4088cdbab8a937b05de9ffadab77c25c400baf75cc602761f3a8b60f253395451689ed4d0d5b8bd607d0516de120fb374c485368f789c3d2a5af8f634bb3e42ea3fc0fb7c42ffe620c1dd1d1ab83676b849bf5a6f8de8cc0324919850461e916f4d9e8b88280f260d7263b3b08a2311a041d5db23d6def6a131b444521ca31b5ef02a056261021c5d46d26ee06b437be1a31f17f5c427032b43cdfc30b572a88ac6c12bb1e9a7763c8278c01fc457cf43cef4eea1297205ce250369d4f24b86b06fe96f5d878703d61080efdc1fbc2cdbff55e6a8eaaf384f1a5e7d1d53a02e345f7cf2bfa52f11b6bf8f7bc9ee368e6475132daf7db311911a0cb25e59173e4ae9be2018736157c840e9a02f4e10ce393d6436ece222874737dfdebdb9f5a131aa2e78255b2e0854fc231905899f64cb3259b9400346f43e050623cc9a032f8faaa17d1b604c16cda14e162484bd1a3775dd0bb7ec5ec02613263e375a17750fef0e61af3384b2a31c907a7799e0c260566917c417c732199d9d92cacf38ec53dc9da1b86c091b1b0769f908b56f6e71ec7e7175d69fb1a9f02c72ec5f1ea20f1417a0f884fc2a62e9991efd5cc178e04cae8d7b9229323c9497db6e8b6b08cbff666141fcffc3487a0f28e4927ac4cad08f29760b6cb87b3a72e7e601f1db8652d5625b0b045312ce0177cc79c6f0d95aa8954a5bd05a80afd8b7a6aa54410c1c01769c95ff036c1fbf14c468a4b25298a5f1273fe92e18dde7881718ec6be99422c071cc5cccccd31f42f62422c40d6cccb02cbf4c8ee035beafac7d7faef0d087b132fea473c00720dbdb9f28cc9d22936dee6fd1366c66aa34853d6537c0fef78580036814b1018a3fd9465b400c25d51caa17d15355dcf5c73e0731a675bffbfffefffafaaafafbfbbf3f0ded1d76b6b6bffa2ddf814db66565849983e7744ce6906106d423935817485e76794819739d1c2caf3a900a2994e82245366bdda889881029a594016f04a8045604c20d7c8b5aff5201cf056317dc5d5c7a1af2e75ec1b680b77391c65b84817d1a45cb42c160908820cf5bd409f2f0e28a32a1a92f09f0e50c4d5992259849c37b8941c1b248a1be4dd18e5ea4c423629ac274a39f2314ef7bfc1ef16833252225ada3b9876bfbd6447bfc1e75fde3f7c8eaa8c667d503e80f77de97ffc3ea5bd479fc1683fe4501fac45bf1b1335715e50caa02494a60949908fae90192e240542d3e12463ce88bb6905f72ce39e7188cd523fef20283db98d77dff8bb6b06130d69b8fbedd43d0bcd4e6d8c7b2a761f373d424ba4b31d65014e5772f43c6c2dc33de1d4577dfea0c2d0f6618803d080e799f3577c0cc0c0d07c26861d6c15db4f69a8504b4d6da847444834ab9194b979e8fdf22b0678dd2ab0ffe1ebf4548bf7bfc16117d0bb3e7b2993137f5b839b0dd39dbe4adc7dee69c739b55b384c2276868ca29675d92b5d3c8cb0f9a1d1c5816f844d0ec18255930dc619173761155e92192db21821341c4b6f9264dd35c8968df622d362b2d1fbf4464dfa6e4c8b79aa6301de6f14b74e3dd30482dd0bb24cb0e68a610210da52a8efca4693af2add314a613057d2b8c915fa09fd704d1502818241231623737742af931fbca24251fbf2b8cfcf600e68710a9253452f5f0a89dbd2206cf9288770592ce3048c591ef8fdf1520be82c7af8ab86f67cc7a3ca8fe5dc0346f74d7805f187376b39b2aeec16019130cc6c4a4302d1f7b0ad3936e2014f3a29ca29fa6d72f0bb4d72a8efe127226e1438ab510630c70169a8b7b85e08a01087a59b4b030f409068723380f0e4970a0a826c5554cb156e499e9c193b3634347c6091ff0e5f038e77c88a3efbddb863a22e0e134a7b42711f05e18c0622cc94b70a893c6418088a11820970580c899a4ce82106188380bc6022201616e317fa1708948dcd77da20062e631e6e6242e314301e637eec443a8b81f10e17cb85945aec349f01137db20495228c59364d31317934500ca159ab93a2c1069965c341257ca0d6c90159fec88b204a20beaadc8e5c3ebeb84db93be9d26cce612ab70151858ad82a52d26436eae8d120950fa590185890ca320202a3e1d277c820088515c0c886998ee440b77cebd801886e7ce097c882ac194250dc855912040c89094c8d1254248882f44130aae1597986f602ba30ff78aebc2f5297189c405107390bce666b9ec26c4258542203d6123278ce3388ee3c833c7711cc771046ae1e203d1f79712977c85988e98cc5c6c4297ab01d1893bca103f64ae151805351cb90498dbe5ca7089580c03b952f240eb6a8aad4814255056a0784981e54061e20448c993be0f4d5f2ecf6f1b10a7b80820e6c84f4b329221d724b23519e19a58e212cb3213578a5b368970b15c0f0078b8790792fb8094244992244992244992048af1a42fe7a9014122462346cdc06d1dd7b1708bb22eec04b92a91eac7157339e880e800627672c4d579730f4004c24c7eb829b86944d86b63285c4a4baa58fcf83852638a0e1e2933da666c9d3dd9ab8391b18878b9c41ce2870b969d3c201680e8e64671d762642397888968b93eb80808c4dc83cc1d82b78401a699a61dede80e05feaebfcdae9f586c77549f5bafb1d6dbe87eee80eda9b5ce6ddfed763bb53d812fbcd3e6ec2f9b86666646283ccff354773b9b5d4737f8dda9bb1e2ad1807fec2d6976ad6ae07ff66de20a577085dcb50b5c214e0bb170850c2324181c82711e1cf2081b47b9176313a5bed7be7c49c497fd16bf86fc58f56616bdc6b16aecc7aa3413c9ab6fb6fcb5ad8a50ab17db4ac4ce4a886ebf55594e5f317f2559b272737a321557a541c9dc0aaaaba72224be23afaeb76bd815eceaca81820a09498b145f0eb35d0e213c9f3bdc91e3aaccd135dc91e3cda1f46dda9f6c1175cf1fb24fc54bf59371a059bf536d3f84c3b8253f0f5fd0f86918a48537fa78a729cc3bf54e814d597d2bfc11287eb2b79a54db9167c02a1d752f81e711f8ce14d48f2e82cd86d80258e6f3e66c66c31140a0c166c30b8cb081183df31dc03c7ea74efc7efc4e017d0bf3ef14cfd760c1b2628e056bb29630b2638da56176045684b57eb8b13681c291542c62ad7008bde1e81982a863974ca9e144ec08cbc6a6036485e3b152d16299a64e9031e505dba2058fa1ba1b24766e7c00aab282786285843d1af2026df5e9b1caed707320d13081894d229648b16e49fdb03ca442b05552588da0ac544aca88b04f6a6c16b2a52e14552b938db50c469223a9152c8928132844edac55575815726c10932326d4d4bd451f6bdad77a75a5235553e589e54262c95858b111b49ad910b192c8f22385950167e56d6d13c2a6fda8c91296c586a327c60c25d6cc68ad7202478d115b3572d6242a6c0a28889d20d4c686385b4f88ad6f5bec13aa9a1466ac3c4b2b0a2e581828d8291a3e32688050b3b206895bb592b0406e6b693557c69c7049d1c152d570d104c45dbd54c4cd28c1faccd0597dd0394561c39640299224c89232d7ebcc6a0d8b5a7338b1518aac10d11a2403687d65f0cc61919b639d9ae430b286588b61c6ee00638760ad576ed4588162a3925625456b8d1842c39c183d45eacea6b0269cb0288ee4b04501b276f1589f68154d0591d1e4058b959e2dd4d273680583f2615d40856057d0c1905ba19ad87873631372c67af5585b70ad34aa9844517962b592581d46abdbd088279f9da7102b171d4b2427a4c9eae48d05c286e44c450f1eae13aae2a2a69e3e246519b12386869c7c889c42ac4a74eb931cfba3c9f0c39b11b6a6b3b5478f158d8b6dabea1175e3894d2a62b48e0dad2660f8b04a3042b04ae8d61f39b22650de90d8d81367743dd62fae354b15eb238aad7b1291b44a1911199ad1e4f3a3298411ba754d2e45932b6f576c4b672f7a747161a962a544553d2149ba61c462883dc2e4b3ea600a5143856e18420e4b93a6b775081b0b772622357ba4909a5c2c11abb91b6b0a196b0ca6a1233687053be5c41ae5f32d36aba15bd23133b7f9beb8d2d37b2f528187128f8833c94a093369495099e4e64326bd3c63d2d80fd7fad949523f494d4944414a25be9d799283c12412267a48753e3c2429245024b8113bd646ca82485b18f62b45ea09228b587cc6229c10c74ac7823c45ad9f0c6327c8c34580e942d74a18baf7de9bf3f69b4402a96e03a5ec17098e73cecf5d5b6f8c244972875aed6898a669669487748444b45fa41e148bcf05ae85d76b49db8a696f71ec5f747d57aa1e3256dbdd31c6bf0d65df1d273f69a33b4efe51e5196ef273933bf15ed2f89a57ec153be226467356db1f07e1cbbc99418715e90d5751ce39b087813c7149f6d88c66b07923de426df630f0de860d3eab366437b116f26e76b2b781ece697e56833aa264e7ebe4726af58d08ffd26ffcb4bf05b99c7bd438bb41db3cceb9e3978c8bf559db7d0165c21f7167c01f70b36ecba2c7fb3994660e404571e7feba14a6bad73ce59ebacb55e80af2da1e9ec7a9c018ff978dc732f03fe8a7bdccb80a32cc148ac1e7722ae1b1d922adc0685d7dc70590e4ce6e3f1da10b71472d88b0eb70f887c40621c4b5fbbc1ab88c9ca38287b6194c75d35a2c192104a063b652e2b347881e1066fe57c781ccde1e5b5da92008dcff8da1264b9a8b0e0f628dc63b5bd77bef60466e5dbe3be7b19c814dfd3301665d85414205198691ab612e79b73bef9de9cefbd39e79be7325ffb7bea716fd1baf058c599035cb6a8cb1c6406ac1d79c3c4de30b4c7dd7cfc866585997162bb99102c7191f6e2f8a193c23621041622392a4b6212c832b7541630b8b030a56e0acd9fd79dc7dbfae7a05803c12358dbd7922ae3304bd8dc1b06f67befbd69865954fd65f625a40e0b69969afb6babf755a62780b564585082175a33529c205b2b416504aa88c44cae684912672a7d515f2b785f3ebc5d647b5171f9ea41611c45e05eefe965420fbf99a5579997168c199ae563ca02920488a7ab46093e42ae44d9a9810508960f48f1a2d165f5a48fc6708a8fc64f49876a6a8cc7d28db7abca0334b2e2122d33a3acb78b8a379385c9f1ddf16e71e970cdf8bd67fcdefbdd5137be5c4da54fc6f049cce397ebe73178fcee509272de35b7c0b703c6dee64c427e1ccdb590a72deccc4d0c3ca700818c210a34c3265b635b568f5fadaeac55e2d1963df738c769217ed542aa1343e706e43e544bf1e34ed4ead9d1fa706527f8c5b39c64b4b46030ab4889afac35115f593f7a825f1c2d6bebdb1910bacbf4aaa23aabb676112f341ade4b8c068fdf2ca42c1463632dcc92c48ecc42d8b9dc9d649a87696559253a18a163ee262042058a593dbaa7306916881f5d98f0154d8cb63544c362323c636938e98858a2028b8a0640d972a73cb140ea79e2335a7c4e1d82008198d2c2896d880059735c387888b481b83a415e11c1a0f1da573cbbab202f2b39d38a0ef53579590d29ad8eb4307995563a7c5661173079a96e6a60625b4e504e28c352d4ae9ea008794184d434c6e8f99668865e260c4c176259218156d5a4e346dab0c7dbf047ea7bfc62a57d9b0e7d60950dc9b0c0d0b06e60d1f85668b683e2209a978eec5c34c0f463a67b9be69c0d937eb0a5d7c2f206fe169202c3b607f9438e2994e630e087e51c5c81bb68604967840dc414921af9cce4733f876a2dcf1bebcc7d3bc79d43280ea2198cbdf3ac72cef98b75f4fcf953a02ecd8f2f98bfcdca4d83d439c8ec2590c7551cf79a739224494d344dd3ec2dcf3475b94dd3d45deb8ce573374dd3345b536bddd334fdcfbe4f9873b7c0df052e9430a096eade8220a4a80d0b31d2fadd43c8a5368b5ea603106282276f344da04dd979e72846c7310383e7ae9b642ebbcfd771cf07fc913df62c37da511eb0d751b43d7f64f7f5cc2b5b8eb6a5da4296bd6c01daf43aafcdcff370aa3f928781ab3f72b741a1b0a792fd57926a05b450b7c11db0d41fd4315de6efec641fc936f83af87aab37d997772850ac5f35b8c7af5ace9b8616f70631dbfbab830b1b279477d344f7eed216ca30b3a3e6366b46dea89f247b267b2ecb6e66b38cf639e538933d0e596adc907739e7dd699624d947b28f2874aa762fadbabeeca6d4ee639ad28f9d74a9c0c5a50763308a7916f43264ad2fd596a7b6255027463b766d93f6386492ece686f1eca7fe10360f263803820817e8800850a013d4a2495b90425f7817e81e4f87779a00e08d5d9bbd24bbee678f434e93faddcbd2ec6d307b99c71e87bd8154f9ce588f3e5f4fe658e51a6740b11e5f34a2c72f5acf7bd6a67ba3ca5111f0d58f3020448f81f43cfef13eeee48f2acf7bfea1e4796f5bb8076ef630fcb80ac4b86760d9319043fe8cf9d9abe9d5946a5be68dc3c94ef66ac88ebbcc8853f6b22c7b35b9a6fd953c7355e64d93fd3d4241b12e73e741e9eed8a6ec1d86d2963fbe6076de477ce1ecdc86dcf51378d372f60c6c776a9bb1c9969d2c3b49922539e6ce339dd2efbecb507cd9cd329dc76f76ad1fc0e337c8d1e3e46fcbf2cc65e627da71f8d84bdeae87a12c7f6517bed979a5892b946ab9cfed817fe6bd1ab397ea2fab1d43eea64deee5cfec6dc8bd547fa63a9665b97b2e7bd90a3b04a5372d9f7185dc7127a9a032da42bbbbccdc91c78f1fed777dec24ef42cbf94bce6a9aa299e793d7f21ef89b1d87ff1863c2c0a01957e0bd3e661f093739ee31aec071851e0f7893bf25777d5733aabbb39f26efece809243bdf71de7fa7ba4b20f9e325171291a1788ccaa03fde5be1e31f573908ff26c7edfecb5cfd6595034ec1e75e96d9d4bc6f9bd604ea8f83f073cf37f947d52677ddb52a83216f1fdcc974fec2e3772cecdf20416a579e845cc2b7bfdd851bed630717697eacc78e7f631f550ec2c75df8fc71af71b6642035e0f47a197ebd13f71ef026d79cbbc772536df35639901d6b90797d3646f5683779069cfcb977f8495bfe5afded6ef632c3efdcf59f07feb8dfb43c563bef26d798aa87ae7b2cef58f590bfec6d3543d977c0dfa97210bea90a65b430e3e44f35588fa06fe1da02c6bd872f8c2d4ffeee3d72c6c718e8219730e61c55e477e73ac47c10fd38769bb26f48df04baa3a806a26d0abe445bdab1e3e4adfe36ec8ef6addaa83668d7c016dd8076ddd1cfbd9b963701c6155ab48f3d567714e821bf465bccae7b1ad0b3ff6ef2e3ee817fee372d9fd59060a894eb59525ac7466a000083170000180c0808449220c771184ad9f614800757bc344c382016cd258128200883188861188602108461000682180882200a6548f003f85e541411b6f7471b1a1ee4a6cdfb49cf48f4591f13ee874fa9f232a5d44eabd4c87c1d205f6a00903ecbee47122c5ca0b18be7b0fb818f9d756a30e9e00d404cb5ea46551bc81c9e614c15146327275bec97ed50c2f544fffee7ff8ed6b08061e9cc05c10153276b97f0ef17741c1d8ad07eb404c309f8652872edb0d39444a00990803cdfdee637669f3fae13e4935e2a6a922d8a6f784f91152674ee3855b2e5cd1990bc55cfbfb873ef857c87578f6fdfb90eef871d3f600bc7f63d7c3aece8607286d531557cd220853fe1c298de71692bfe0c172c76f9cdad8826add82e8c4cba238a7f41107ae9af4f8783e606d310ca7cababdc418df67b26369d7de6b88d571e50e6d096d8e849f2dac495e5cfc6bfbe5663f5006b0caadfc8ec8fafaca1ecb8cba0be08d4c060a33c993b87076841465f7f83293163db7addd1af62142e8c6cee9bcfcf81c399b4ad3b9d62d5ef96cc04104ec77ca640757d832b922a1bc2d4095096faaa00880cb112a2d8e45007b619d7ca2361a405ae4957cae8a2f9a03a5608775c9945c075e6d5c2f41d6d62b948c0e42dd553515b8df55644d651ecaa7aa601823c22044529d41536eb8567d41a18f24cd3fb09d4c98ce54efaa9967341800ed6a8185e3069a96d8a9e697a0ffa36db4aa3d5c8cf23e2ac00f523668a74ffb6a1de8a072727909826e428fc3fb762d392a6dcec7013a0245e6eed232cd3e2a18216c8641b1755780f521c34f8de2da1517a10d5de9ab515bae26debc1f3655d3f813776dab6cedb4769c95a084c5d1925e98c775c46246625994736c1fbb896a097662ac1db103eb763dc9a668ded22c0cc21acd9016d88343f52287687616f0c38e319017671b3748c6c0f30c5dbeedf58f12561379c032ca14bf017470cf31a23d074cc489db23a6de39f0c5e18e020f20a98d7f03f61f53d256182da606404830b66276c30831daee9a91f00167cf5da9c9715301619240d2226883cbb92fb79d02b5e39ebef0f909d03b7b27ee5794c3b1bfc078a843c4ecc4bd2f915f561119a74a4ad8512650a04df8c187d046d31b2fa3c5e862f5bdd1e973d39f681b6c891cac92f5651e3b7d4e4f30d3239474da7d3ca70bd69546f9d3f6cbcc7f44cc6e59f25dc9a1272eb84d58a0a7ffbd736ad61c13fb3163215a11913fb41f99da192b475c7bce96e4ad03b5bd2a55a6d766be94f32ba27a5422412c316cc7c28721457a22ce80ee3f446a101a1034bcb73473dfdb2a8aeb1f03850a5cca5761c4980826fbdf51af22026a280dd249e792d378ff671cc22b90824a12568a73cc5f1c868de07047138c9129d617fc017631a884db3d64ddc7e9a6231750eb86a570cc3544c6f0eba237ea5c774d003c6308d2f88f70f49166c4072c80e2b007d3a4c186928179147955fcce494d8c9c7a408b5357774419d1d2a1dad407897ba4b05c68553660a0b8b065d9ffef5d075e3d3d14b2ca801045fbe70c58bb68826d2df3d6f528003e3e42c5f6d3b69c6f35646b174b994e34437e409c1dff487048dce054533f3b7abe0283df9987766c590736bf63489ab8b19100edeec60c63aab71032644d90804f4fa2ce97392da9967d0264288dbe71710b65d63cab3603f6c2f275c97044f524e365a1e1c8e81c7b31d5717eacde91f43d3013f4b070e7bed17ee79d15e31228d57f2fa216d048d4baeb9262a5f61f84192ca7db26b15c967be97c76012dbd1e8d43662dcea6fa741352714be061339548ca0c68378ef97e13f5261087c142d5683bb8f8a1a28f581ea059eb0fc38ac923cb0e8c2a34f05e10402c3c1293bc1b7924ced9f2bc56b88bb9c8fbeb8bbf15bae70f683c206ceb4eb5b359d0b75eb634e632e19b5fe557f3b65578eea6be42eebc61dd0879fcb00ee1333783b0c79f2cf4da2a9d461681cfa93895ddeaa9aadbaca8b45e22b35743277b045854ac7f113516a72bacfd6a32377eeba0e52bf0c81ce4dda698d6e3e20e9c36be2dd1f02e60e3bf2ef444dac33e8fdd7728a83b3ad3c8d3db359b4fd2501c055d1b1a9091d2fb73d6e28b48f59b7066f2053775f899a7e14ccb57e1f5e819241193da229e854acf42e1efd30536f62479938e929b53b48b8532a731754a72ed8522d680064c99264a33e56c39d155d1968b8e8d95aec87a4837595ea5041e652ec56eb1b255debec82207006bfb6918f64f7ef0d0554b4c0afcacadc93fd40b2d25f255eabddae6403bec77066fb5ffee53196efbe989abbbb5bc8121764664cce7cbfc7f4ec5f3fb222c526bc0d4673c613cec560a34ad303f815b555ca5cad5d11a16b7d81c4377d95802f446d056a52fcc2f3c2f9dc480425540f84fabab01725ac94de46131cbf4f833cb197ea434d1735bbe866dd17cdbbd60236d4ec00ce03873c2cb0040a9b3165afc8fe6ce46f541f9059b855587f8725e85145e21200883aafbce96b6a9a0aa78aaf7c668cf87d4227fc207636d5da1688f6ec2d1c2215e6f2a9782190b53cfb3fef21d4781ee6d5b85b37a346a8a9fe2bd9fd2d2abca315e3155c8f13bcab490b0275d51b0ed05c53329f3c3ba2acf7ea62fe944cd35deb84551eb4097484bef3293c615326d8eb77a0362b7562a6ab72656f08236efaa10f6154b29ee1482ed768553f1cb0c926882ef730153b16a1c6db73829ea65996d033d4ffccf89502f6147489e90499f910163524a86931c865e50b8d22b4830278d87dcf488d07c85c30f40f422a7638d050ba3992090573bf16f4c1941e27fa89214d6bd156cfb1164ce92fe280d0491ad55b2a857d34c4aa547a275adf2204b9821acbc184c3af85f12015fc8bdc0adc09ce428a17296615430403d5e4096d6ed61976605dcddf5a943f5801df3f2366128c5760cde4b833eeca14d98d9981c013ea3dc7780046f05158a83cf200464865fd8bcc27698dd67eba35be00a775c953dab80b385fb7b9e25355999fb81eb15f10cde7f66f1d56e8af346a8c93bc03b9b37891221e8ed4c60e1c781e8fdfde083f27ae4f2bee4c0e0f0d469717da67e7609a908b59af2c1f2b4617bf7258c39ba34bf2eb5662eb139480d8989605a5ac63443f1df914230d683dddf996d97a030f730b3646282ecce5533c775093988f6753a04051f48d6e2d2d31e42ecc855dfaeca45f2cd0707ad29ccbbeb09472dcaab43ebf3325c9dd8f8fa68f42fcc51b3c0a96368beefb39d048718c23ac99f7daa0eeef195c1d78e2e06c98847f6b442a9301705d824987c126e89af68c6d59e59f9e693e9882309885bf3edeb16f13cfc50fcddf1a69e32f44c19031ddc2091ec09b3d843a92a95daab0be16d9ffad2ca602851b90e0b3649a03bd3bec5a2da2c6e56eeca2631c5b3fa4e30ebebee3a877436bb558ec736d4b1b954f7ff5993c93c5c1ea199ea1450027cdfa1d5c349a3e48ec88fe22838beb2915211c1dd1a78472e467d8754342612b1dc5f9313cdd01c88557255edcdf36d907fe2afb8e2b714619a0a9756a138cc4e69fcdd4ad308215e83ea7f8086464ead1ca4597d16fff994f238a641355ca0a6c4b67c16437cacfd82e877c06b3099c26c36c9ea20dbddc220eb17c6dad630f6de63233687c18e512714e6c6c71aa83e5b9c1a60054f35afa4efb75e4c57b63c8771febdbab8e178504f644abdfec36884bd6fec33f2d2fafc6768b9b7c0df3e2fb75345e131a1415a8df35417257dfb6e01c4165be8f04fb71da80f1719c4452d5c89972e4d06e190460681c8c73192a13cef98cb6b86381e665e1a469b1dd441b8ab24c3e4c9c3a865cfab70001dfbd4238a9b1d8db81b81735264fc72b0559483ca575b033677d9dec4b0a44c0c2912812d4952e6bc947aca30fe64b4cbe88af69f04e31eccb9036c51c7cd79a03dd3f5190ca9faf87fdc12a0904e7d1c31747e91f59e75bd718c98ce219b4f7432237a8fea56d2c96f102081dcf576d423180918971c1f9b33df51b596be0483babf01129f031208904b88989cc34fb7b7ecc2bd2b53107eda07d5b90dc38b416bf917abe71635239988aaab931067ef8605739aedd3a4da09c41ad4fa46a6b2fc5028ea2f9f2bc70b7082cb67ee88bfffa32c8c2ab8cc5def1668b6f8a7ea007d21bf52e564fe1dc38677181b277a8dd7061171fe3b6cf3f73757042785fe354ed07c6eae19bf9842269fb3f9b374f94d32734bedca9532153ce78842b48400100c0edeadd8037f60193202935e1383b95619931a62fbd307f8cf2d747d70576db8599605724960dc1abb6a54481e0abc72ef2701aeb3b5cf0d94f60896c1c803ff84eb4ac92fd76ee1509aa6e9a6c4c62154291e4dfae4b39a4322af6789d4a3ca01ca7cf2a1ee1bf928995d8034e4bd0e5295858cbe29c3412c86c98de2c8fe8669cf6fa27ded9a49c8446fb557e7327780b5fd0dc5a38e9ddb10ddd303e4d4568f768150cd508a0cc5404cb93cca261cfaa8e7d018ed8b2ad2075ad1d031b75a6557262afc94b70a9764d6b84fc7b166339b1eca91f1ed848b8142464c1eac0ea57d54d8ef9438dfc8281db5f8ecbc81a5a1b18885625f3f1e399de0db5ad8aed44e1243870429b92d37f8c0c85e333f4c9ddaf79be49fe4b28cc328ced6cdbd960aadb3724fc1114e4f1ab1075f847bea2954252cfa683ea416dcf5c05377855881ba6261598e51966d8264123b621f77d555a50b67532aacbd94c47744fce402f356a67230620a87bfa7994541bf38b0cdb18ab7064d7b5cd4801d5e3287878cb42b9d8fa614f9a5752c01448f461babb7e9c52635abf6d5c0b226b2d6446504d79f1643b8fc97b424a407443c3000df11e1a25e443a36df0c2b6521844e3c21693179cea564528a5b3010292cb973640f9aed827f8c522a1882a18b2a2c1796c4ed4084dd1d7b55cd0657348d667fafe6891c4e6770ba57375f58c168d59c7113b617671473089d4c0ff3fc7ab805bf9904bf023eda650b205f7bdb9be8d70a0bc034a6509f3ef3b1f91b76c0b25203426a200db9410892bf2584ecf40632ff40d951c9ee4970b61555841a51d376f0ee593fbef34b9107f25c1bb4dd0b2acc100f824131e167c98d3aaac069719a4b321339422e8b35c039c897790cb95929a20370d810e8c1266d14038537e75d1d336504e3a148d2497d2a958c819d20b01facf9d17c7ae62e4b7f10ca931a8500a7bae0c288ed4a25121996262505538d8c41a92a558c5d84814f72e9db82c90391678504a9a43787c0e6e5bf8f07b6fe1a9f905d346ff40aa4603327474f085ed20d6b988c3da093fc021376063205f484d8b7d8460538a923d78752a5db048fdb34e424e472af6e81aca7619dcca8280826db0131c2822c122f3b4f50aa4ac0d0f4e9940cc3c36281d3b2445c7ae154aade364e3548c9bc2a040d7df7360dff1081a9dae42b0ee1e54133ce0ac294e38c643751958e09793abe0f807e0e96017714daaa5f9b44b3884e4d3bbb0f62a5faa09bff38cc7efccd3ccdbfb7d18ca228581e2733cf023f9acdb57e359a3ca275a615283dbf75059c882ef7fb5dd86f059d4345f75109151844a7c7a596d84bef5751dae1a95ead41a883acb38a26edc127b9e6d98ad42b5927e6ce36854fed55518f428eb023e0355efe1964ea3e6e76b6bb3eb6a9dc1fae5302063b136ad382665b3d53020b7e9b2e70a2ff5a1e541b6cb62b964401742e2175e13e0f09db56e10c8b4953dd20caa072814b10747c0abd89186857a7a9578906d3efbb01d6c751fee8537b9f607277a4a189a98e0e2242eca51006b2671a05a9fc4756c61c671aeb99bddfda0747ce2d17967430aa9d860221bc48c2f3bf09726886331f28a41e4c2c020e4ab941bbb53d63d71503201225c9e284427269571f80b393fe42548b5325f08ea9a66bf83395608bd8668b1fff31b470da7fd42ec24fcf438beddabc8d3456355b21b961d591b5db1672af40dc119414d3380ed34dffc706187a4ad825b0ef493535741c4d347dd59b1f859a404cabdd51b288440fd4efa9e8718230ac9714545bfbafac6199a3821067ea237bb4ddcf741a8aeb4f4d918f07720281506b4766b2c550bec69c711166f5517ba7d29b16130176ee8ee1dc4d99ae6025711a5bf571570c4fc412ce30067a29151737a6c2c9407df073e7e1a42d8fa6ddc0dec317dbb6b97800d43f93e5db7bf567e4148e4d78723d9d64fab1eb1ddf3159c75cbdbf50a7e5c2da56637cb1f57a5d71167152d72db070a770fc54b3b0f5312a93a7b0b340b3e882826678c6c61bacaab2e07392ace388ade4dc8e2a504a34ec70a07f5579788c704a7ae0245842dd06cce582bfd35f65c654fd36645b08c3f0cefd3ff43bfe34a383edc76afe867c19de476bcbf0ac515e1308ae34677200f806123c0638170fab2b5b640c1e91a0170ed607f45e409106c3d4639608818d639908a191f496ccbd98ca0d2d0911707fba83f49dc877ca680b562495ef53b1f42e0e86dc1894c7343a6784a1b0f07aa51c9c1bc0dc30d94b2757ac33d42572ada373468a18f830fa3c4df19e22686ec005290727db611e25501c5797007b24131bcd1bde4b600ea0a79035ff9936091ce69c63dca168cf15f42f18885fec23bb9424542aa0119201001a89a467f63a193a0dc8f241f280bf86c3ccf27f351019f343a710f9056683a80017fc2d6757f51bcfba6fa7d130dec3e68bcfac06278fd35d16a5522a210a590bb1a24490215619375bf9310f246e9c713732144294f4d038f27c3d90f93a86863d3431578eebf654b1afe554b2922f876db57ff0dc61f9113b203be2433f43449788222752528007236b4b3d515e103d8b24b07462c2be52550eede51203cd50ca7da875012f6036fa1b03f1bca1680349487907aa4740753c30543d99d2c0946a217bcf41c124eba6b187b8cb63396eae994067cbb26734a6e1777874ad5db918e9d31a93c5a4ef392c7e4342816c84895be4ee0147bbc6f8c7be189dd688505ddf515245953d5742ca8ab8050597711515cf64888e671aeac186d961ecd952170781e960ee711108b85a2ada26aef4f568f109de3fdd58980e770481902c3043acc8901f9c9226eec1090b6f4dfe5e910d812e20b9aa55d0f673414d34204b644f479ff0d0172f4001dd881368635e19feb7941f349d906fb4bf9cee20be4433e8fdfa19174aae1bdab52ff40d46d287211d77052d28da524517715d22abf12fbfdf4f6257e1158ead493843f6abbf11942bc6e39b97e0c1f3998289a628b8ca837b113addbe76dc8af626d8d3ca408fc0028f65f9f1ed2a5e7cb9d4a79c126a2135e6a746169037a8ea6d0ac3802481c17b86348c739f5a2ed30c99be2292ed6c6c224fb5c2d594ed113d64278143fae4e04dfbd009a7c39e165ebb01f264ad74bf712391fe9a24a85e023611c926d6c07473ebd5de6192913cc7280446c87a20aabeabc869ddd8a36aec71c11e070672d9312d8e340dc117923f82e4049ec4f47e46bb7b22fabc721426ac04e91a6555dd223859f3c4f206876779427bce66d4b23e52d44563799cfe0341f396caf0c8be4a051b9515fb45ee68bfb9bf1663064ad10bf6e661e0f2415a0e135082d441b930ff4d4c0b060cc932c80efc9b4e4b17cdb33033386ec4df00bd1d3406c379c49f104d1a1dd88c510d580ee305931284df595ad28d8d9f8bf182c9df2fa27e0b2f220dd5490611ec57118acd4f6f6693a53ba757cc6f5a18f33c309bde7e38f8b1228ba24d3fc520ed6ae4f424d90c7a206b5bd55c8baa51fcc710885f0797e0347a6a69337321bf406ce0fa5e70fbc7631d14f3d2c2bc14726009e1b8aeca3581c407a0df3e3820f3e60bc1e2d2c0071e6c14c65b385673ef6d47ca4b90b643ade60af3a7c597734eb154cb9e9452c1a1a7407d38a58d28cc76777563c90b980c9522359d5f0c372dec7c11857212e43f7e91667192319f3279447e09709793aba09f61c5dbdef79e524be688661fdd8fe41f5f1b1236f77bbee8c87386ae2581dc19cbd3aee941235641b19ec66b7482ad96128dbdb5a88b6fb828b90a8681327aaf2813a44bddf12e6640a814ed6d82b04fc19b05316118854c9f0a080d19ac6aa2c01764e390f92238a5457e2a8fd3415e83207395e9f871c91b768d70ca39dd87eede26350cf30c67b79e17a024576223364b4a3400bd9b7763ca216d28e1fff2e3853c963c37a7f7bec0183951e939d9cc9028cb3576c17dc6e24be75c027e1d524a3fbc39ccdd355873a810bf68ab37811f2d36b24a7132daf0eacfe568456bf743f3546ca7ec2f158413ba7034a5e1c28f9694119b650baf834fdff10cb3c2d8e786c4453a44bcb533003dbabc326072d3b4d01ed6f0b8e0f1f7e6ea759987221fc3bbc57c14353bba3c2b257ec6f24f9c8ef4dcc265fe9b05c89b5bcb6f0f36555d7432c6f171dfd6a58d2d835e0cf4722724972ef8dd2099397858af139cad5a1c1d0505ad925cf93d82823a622590c69a81624c31733b88b59fcc5059d43ca84df2fd4c5ef65b4bf96a3c6a94cea950d77bf31e14b15fa67ac4e70cb55f118c7d1af0e4df308b097af4ddcd4406cd2d19e7cc52fbb340fb1eaf964411dd0a05a6050ce8eb6eaa58ddb1f89f03850a43baaafc729c05abe067d523b3d8981be298b5e4918db164880c74b82ef23b09d07313a271a88f9d2410ff2acf104b054ffd6f2242cc1ab9808bd381d2e16d439120dfc7ed3c02a5adaf34092cf488ade99cbfe9995dfdcce6ebea7cd1330c5199e06868472cba671b315ff8c6f4a94dfee282147980ad421a8b98712ed3e22db2202d1733287ce338cdbbb6201faa1379dbd4cfaea3e8fbee6880687c928e5f7f8c1a82c5cc9d349e717b8273bcf32507a777e81c184114923304fbb539f4e64d49731a7cbdc09f51d51ea0f6ef204facd71b76aaf858ab63900112a15516654dca80564a5877be01868f72bdaec9a307615322712fc26035b1a73f449f85a7be7e67178382eec981f741a2472c33b8a159ac39c7f7a1b5498bd5251b396e497c298570645219aa08b0e60964e35c2b4098ba6dac114b3b080b5a4425cea270642784eb9fdc1facd64b44f17e108795278010d661207fba8d11e5d2a5d451aa3cb930bb68fae2e41aaf7321a550dacf644456c0813a05a0fc9581ef01f4498e9509bfa54d7539796417681d89a467d25ef5f839dd473336e892c1866902ee6ce6553605039851c7faf9453f08fc82b21063c6fcb4c3c16072d32f864cd9bff981e541ff6b471fbe7f7dc5f11df9382b08507688857f6b7916f5dbd217e013c18d910afeca7463ada9aaa1ddfbf572a4d6ab4cad4af1805fcc77e1fe215725f37f0e0f0bd22e6895c20656dcbbed077de8c044e15d065818374bdc2a3354e9005d7c1831040503b4e47eea68d41b168a6ba77162d98cf271f560f0da1daeddee0945bac29d0163d91d5312ab4bedf01980301b267346cce9ec31bcbbfe3e10611de415a91a4e4e3dca241b1929e26a9d811e147bc26138de45c97aa72cdc36932b501476702bcf55279f832595babb0ce127b2983186b39dc95fec0909311a4fe5a106e7c9a0f7f3b64df3f8154b19ca5fb3ee82aff0ee9b1f735cfc877cb89c3f72c9f7e48c3b22f48de8796517e2d8e6ae04eef599780c03abcd6c523d603ad1c45577d49c2e96b7f40014f3fd6ac53496a2497f12a2bfbd8dcb4473909bc2989dce3fc2b612c7ca05f6fef8b9b0c15d198cc9d8d789e137de0be0583877380ff185787752cfc93bde45b990400a6a0dc301982d86ea16c1ccde5cc7541021574543afa2467080fa60d31139aefb235ac8b1949eff26e4bad2dae34f0e2413540e0b70e3b6766f6597966ff4a0f6f733de31d689f061682e0d9905374207e968cfbbe9d7cfa8f9c60c1364258246ae91f7965dcae324d907a1084c507b1cdc3a14c4336ac8a29b06d69570e3686d74668166309473163477cb9056284deb36f36c01a6cbc61f6b3b827493c7d06d60b11388178b7cde7781ad4e238d31bf0c060c92b03276d7415662882d85403b922b123c14d2668dd90aa5f9362f9190ae1599fac2863bdf8102eec0cd2a5899ebba7463756e9784313dfc86f2e24706187ee97aff80cd99f5da8f57ac0a8ac8a7dd46d069b7ee055ea360852b5a6a1cb627c5a448f21c2e8f46ee34529280c55474ebc0d91d51045ff9dec7230cc5456fdd985635e44f6f2bc099016d041c156ad03b2ed011aeb34d0926b5ea3990646d21f7babe63f92ab35a275d9d990d5d62145eae6e52f3fec08862da741bda2524a1ad16db2fda0d122fed3f054f55240f0381df87e86240ba9f1019c0784723daaea09394be95e57d6e8ae65cba86482971044a764a7b8503b3d228afdaaecf5bebf704b7661e1d7f187b1fc6d5e66ba52c4fa672cfc8e04b3a4f7d6e798e96966272f7e571747d559f1ee15725a07a98cab3b5f9d9bf6a576626bc00c2b34981b01858c03a61fbc34b4e04513ea6bac9fddd44244a85a64db057427c9b8525e74cc3a0bb7f425978b046b6cc203eaaa703a7ed97cb8b1c9d357c001b3f6eb3f86134a4c57aa9db6d6535def3567e4a56a29d9bfe65544c49c5914fc9a5558010af3445b92660f6ba08108062e426cf5900f49830e12df860bb2986cefc7df4f4ebe2438e894dfed41518d0110ac3b2b0fc202a8358e1ccdc838eecb7d7c98035ca06deeeffc1da1c48c663ceb58787da54ce7aba582b9451a67d89ef43c705b6f798c474fc6e87c34fc598c2a839f36d464183b904b525f4ca8811da45e0c5d4bad44bf6731b2ac80cb3599303a4e2671404c9031e737d0de418f7a5cace9945ea356bc88ba53a3de26e1995e46d8591709d3cba7f7204b609c5de55914d496809c970d88a1e6e5b35f704eb0ff7a8dc3ee3a06d8cb935a4d075165e430b2f4570f27c02a0585c5eca052bbe94176227ccd4d99d4282dfc70c0cab0b1dbb91aba30c7c1f87b6dd9afb01907fa3e5237c1cc7434480edbe3a06f663fd406ade1e9d983faddf7be9b29336bd15dfe037f5e139eeb04ef24547e6b71073d1c6c7d3752a3b4c5c57d5c5140ede07f22f833f26b392f7e6887e25f89961e4accb362787820c58c4a360b8ef352b54763857c660ccf5206eabec98c7bfef9331cfe34af7d1542ad0a6c827c89afc375490c2966d29144577f932add267e7e8b990cc6604d33d5b76e14846be76664d9613920a245281c82b0ec6a4571b1f65bcf4aef283e9376e39cf32aba9cc4ce95950cd8142dabb0b68abc4c16cce9c071dd359450177bafac59c72451594f494b3702f435c690b645ec3dc4e11d33d1538f3b228f3b33e1eb2b0aa7339b965a7c95ea0f7188fcae85e975b7cd7d011a11e0757bb53936715d83c99e4881be95856c9a876d35e2e218754becd86f9ae77a7d758eac36e20d40292736d182a4922c6bade054ff288c03958c27925f2cd9c21e73bcfedbb9d2a05439d1a2ca6bf639bae68659a4fe587e536872af74b3b5f538bc92d25c652a0b9de5dcae80c9921a6b4b3afc4878ddf826ba1a6f2d82e31da4d59725e9624edf6b4041f91681c3d6e0914d52d84eb230c214471d52f9c627ed0e8fe228249ae646be3940726088da1cb04b16589788ade063627b05068d4786bbab3deb9576477407b463a23b6aa2a268e190b22f3447e29a03a403cc71a18ed342d29ee29623dc1140220971401d450582195a570b4919cd28cb62e7344a093907114b5a0522eb4857f720b5a63c8173a48524d29a45dc0200cd1bf17388e310ef107188e6087147d9112d7d93913fed53c0bfc3ac88f69df8e118c7318a438b1dc6809cb824e46a4ea41813b32f17787b098707ae9785beb13efe59484034a104c411b51d44ea342119704721b4348332200eb2b534018150c7f869698302eaa8eda071d43fa82537cbafa42efd629e8085a0f944525804f906d26ac137009fb62df839b81d1c386677c87de12eadf1add6d5576f6ba68c494a74c741a495c6eb729a8ed6ab64444753155d1cad1dc8ea20a92d271105534b81ad8d464f32f242738b1b0e1047288b1bb15d308e886aefcf384ad9681aac4034122db8a95a68b16bae734967d4481b0e280784748d4f44e99f4351846178c1f58c569585c89c462123ef20045946462a315531783ef8c8a5d0688d62fe3d9026dec4227f9a47f28b0347ae800d3131c95c0eb1ec3897855694145a94039359b98af3fddc19457e6742b2eb60a96d1df9e4b447be3b5fa57f68d7fe34d768f1488d10e234162601676f1acbcb9543f3287ea7b5b7ae7f519dc1622fb39c47b9e7a5098ed65b0334e7fccef4011bab138e23dca711d3771c594874692ac8e83a8c65d1548d90b5a399aa1cab475b11d8718cb468ea451707bba315c77647bb833d87b0761461d3685dcaead0685d6644fbc8d4d6d1a344d19ed1a890f91c571d2e1d65f1a8fe9568522c64512543019fa0d49d1984529a9eb6263a39d81cde1621bb2a21445b9376d8d26a14adb1c810988a3c83b31360a3133443b9c291ebc8c9f1381d2b82a785818c58d20cc5da91eb405c83daf92296d775ccbf4d5395dd0e761ccf0a56b9dd7247b20d67711245831188c28281f01b82721a8d569ad03b4c6a2472f58ef9cf69e588d43a2ccb4c2b2549abc12d9346ed81f1265bd55bca156858552c9fe47c0548e38cd4dba896d12316a3a74714c041768ce641e02f8278f64e54f875a4310ab7c31f8e1f0e3f0ef1ed38ed4f6314ee8e1fc7bfe3fd3bcafe69cc202339348692dd0e123f8d980a215d5a934817c7881f0d18a46c078d91405747fa7f1aa3206747d91f8d1864a493c628387280afe310f711d25bad8dda4afe56ac3958914d46ab28f20eeb1c568ebbb20989ba4de41e70cc28774f915bd016773283487d87b9239823ac2693aae5f56a0e6d93244e47912e4d5bf070440747695cda96a8bc0e6f8243f36d21c1a391b69c96a76d0b6e47178ec08980ec066d1493a000da77e2fe8e2263344ff9cfb1638eb223b49e647c3acc8e69dee2874334fade6b455c6d028a923d4c5b50d41da5036a7830f8808fcc72481756b74e3c50ec1e62685a639b979b0d668e54de513942b69d2a7a9a2dd799f80198376b14408c31836c420d41c0035f92a6ca63fcbf5fa9e26c953c947198c6d16cf7277b6fb2a59432a594523805750457044d449198d6b4dc66ccd0716f25312284f45b3db41efb4a83332acdb2b00aabaa0aaeaf55bd25884088ed90be7a8b84c1d576a18661d7b5cea9ea077ef50ec301e515311e4b0e059d704a4f924340224e49faf001e4719c2e801f880d0ed404f0af36803f6a3372acaa776d17425f391414714a4e66efc395cfc18f3b500ef9ea563d54929c8263ddcccc7e3189882b32dac2fb33560c136ad5b47608c3306109a6e5239896bb4230ad079f16192999abbde99a56311234a1d646472602a6166539c2b4f85acc06a6356ef9cfb822257a4cf72727d3892bf3f5bbe9b60bde78328763444ef9d6c27b1bf729f7348e63bcef694116ffe9c409a50a7bc5f4ff79b28bb591537a59219244097c6d8264ea43f8fa55b6bc11284274a0615ad5b599d6f0eb2892c1d77fdf3d23467903670ec7a81a7a4eebdf70aa6748a635640ea77ad31f7df811c3a1f2da1f7803be62382015572602a61671842073b11c580e28bd6fa686e5580931e5940f0c3baeb9dfd8ceb6bf213b38710121c466599e5c4008d1d3a387284864d9a1079accc40b84cd0e7f42cd645b663aedf20a21824a11459b44d681227091e2888a234c61842e3b4042f3a05dca0671c58699796edded527e444104289a60628b9656c20521106558b8b8142780e871a1c785279e5862892774e7142874a50ea34ce7fe76290ba6ec1336bacb595830775fa74ccde10a2b8ea40445f143101453b8e81ec124c77eb70538a59b3a31f38fc9d6e4f7fe61da20451098a8a2c50a910e6468c2cccc59672c430e6c7899b034313373c6ccccccf105d304cd87a982efee97a2bfbf311bcafa4ba8f6767747145c331be0809979090e4afa067d744377b70dbe8adf245c850d7ff435e03faa6169d8ee6e1a6cd6249bc1365919ec22591b8666e8ee8ec11166e6ac490603ddddcd9ac8d02f68231d4317691734916e010bbabb7b05dddd3da4bbbb55d0dddd29e8ee6e147477370c275813fcd812fc58213f96043f76043f44102404422008fa2a7e3fc0ccdcbc581540f6c7fad817d603ebc2f6b8c28a25ac12b68a4dc22261a9d8234cd1c408bbbb4dba14818b1447518080083fa0f8f1c40f277e34f183891f5b7e68f9b1c40f258c3a0b8e2ea636dc062c495c41e20823daca10aa14516413c58608b6894245084304418820a60021e5878d2283ec03507ce8e1090f40d8c1890e20b841a63fe8f191e904810f7090649bcfdd0f644f78085abe21d32838467c8097874ce793a02efd5abab71c75b710acc5ea29c2f6f0c0cc3d4be420882b91f137c9f8bb3b885116255894644149dce04a1684c40d8fe48fb041f6488c5062e50643a85244111149a82411c21041b041081b82a8c1141a804822c5861f98f06e86c490c97f45c9c9f1b7f47b8664fddbcd6cd92d2d0005073e2ce90107de23800061a877c836356aadd9d75124f387935f799453db063438a1cb1b4ec525da8562d9870e00e107d90cedddddfdaedb7d3043b65d52870b7ac68c120f9c50c21b8d67113249538398fa57267bb873e2a40e1d64fcebdc931862faa31c8a2fd11fa1830b7430838fb5d9dd1e1ecc20dbe24c4a867bf68561b3577670246ba26c5f470f82b889d4e183e8c3890e3a7e90698f073c12b5d034cc2d2a3a32777b72906d6ad46fb5a6c348364fa819ad21808e18b26c89f8052639e0e005bc4bb22d461d30c8b6d3a965f43313714a9f61c4c0294025d3cff6e32e510f0ed9a6464e30456127cb2d85b9d978105467e440806558af16b800cb28bd3e0676b00cecd59280071a46378c7e4b23691b6018373518467fcf3e3dd9ee68bb991dab10d9321130b54a0b9e4cabaf2632b70b154f48c003d9cda67a6cc85c6e6a34370ef64d3fd72db09cbe74295c395a6c07befec21dedf7b6dd9ffd7d11c64bb1851f372e89e41e8f191f623b108b5ac34b22555bedaea63bf1498f184f9443500e596fc158edd3a7d129d47defc1b7bbfb225f5d987906cdcccc35d8a7623a3e9910e24a90bcdfdef78db17ad57baf77e1ca1c19f53d793196e3c9c85b0b53f6eb28d26f5755d55909bc3b36d84d2d3930bfc32a96077e93d63433af5badf1ee08ecb22cba724539d54958feee8e61bbbf7edd1d91285a5983398b298b5984316a10c6f51bac185f64a6fdf66ab51817fa6ab1f4fb6ac2c764aef282a3f95ea566f13cecc67bbda1b30f2bb9e9afb0d34ddb7ee494dbf490dde95ec65caccd76dfdbd5b9bbeb196be9eed65e44ad799abef73558dd73d5e6c6c1d2d774eedfecaebafbeeaeebb2afbbbbaeaaababbbf3bda1957842d7b508710a50c9fe94315114dc4f003b694d0e4c6bfa2fad69f72c84e5aeeebeebde53a7ea54abb4a6866c85c859b9a5d0db23b0a00e1a64fd7ec3291b5762e0eed1ba184d218fdaa8340877611ec23c0c8cbfca88f1b8219827d1d0b8199a2be58019fa6ec6ba5579f33ce65c0ed371d239f7d87e8d76339c721a8ea1349cf298777228c65d9bbeca1ff74ec695de188f5ed9dcc7683e621ec8e3d4f02b5d3ac6e386622c388420bf3a70bec8a1ee55da80d60fc5c887dde069dd64bfd92460012f2fcfcf80f7f2d68ba63cf07533d053051e3de6cbd790a138987ba8551f0188f3c25e8103f32f72e810ccab1c9a98ff52a04bb6c567941635a7c16835186ad593e48c1b184a6385880045610587eec11937ec6486d6f0cfe0179609c23936122c77226857951efc39fd5c84931beb2aacdd730e717c0ec78e4b58474fc61496425b0e426c27bebe735bbd35c3b9aab2a0052174eaaab98dc7acdea95b6739cb22399273ceb11df8e370389eeafa78edfe6a03567fdc6503b2fe0ce720437e4f2f27bd3c4e9d5377bdab0575e1259561ec6252ab18f87d1276ce39f75e13d0eff89784e1e0ada22e7749fd693b81441ce79c73f9ba7ba7fb411cd7746a4dbf23b21cccaf1c7a51d5ec4536633854d6688510bae554e550e90a134f8eb857393e20ce0b3c7ae0949e84dd805385a1d25b7b69e959589cd23bb6a339d6c278e450c961f1316df32d4eec7acefe3488fdd330ccdf93391b7ce594fe0ffc07a57455b94ebbe2537f0f73ccb11b104ed51d7d88e580d265e4b93e0396a6028f1e93245fb8bf993f549219c3e0af64d41183ecd21af8ac345668456185d364a73990fb43e99a99891c263374980d1d451ade70ca9ff38bb11fb4bfa9302264d7dd9d479100926c0973b5024c86b258e66a2f66635e654a0e7335391de355750e96566bd6bb862b498c08f96bbf6a52a59122a9d262bc2e7fc776fcab87aef1b0d85d7ee95c56655555e59c7ad53f2c074956f2e2d4c31e6297f3f7ded3c664c0a4320c8bdf0c47fc57c8cbfb21eba3e6e38514486f69418fb3cc9035affe613bfa2ea3bcb61b9ea1a0134ef52a87a2041271aaee5f6d403ffdd72afd77fc955335d8a915381c83dd638a82eb3141e6749c330cee611db9d9a5a551da13fabb9f1330043146f8e40aed092ee3981eb8ea3ef8dc2e1596ae0e8640e0d930e0bd77b914de63e0fd8e7709f1ebb252294ebd5df9ebe323db9f49a150a6a851e08a2c7ea58019258a530fc894b94ff3fe886239dc5fdb6fd1f5ee6c4e0e5f4be3c669399c7a3753f630bf6cf676c920fd7b0cb40c929cd902c4326c6820c0324e37ee379db25ddb23e28072f78727d2bb138904218424773ff9bb93bbc32a9e5033eeee2e83cd0816aef27bfdb234737b0331795b8bbf26821d6f41655996bda7eaa62c7badaaba11505597eccd2f0a3333337777373373962106d043b6bbcb362e836e6e2f62a3edee45d4db59d0ddcdcdbeddbedc5c5c8a8d37b1eb9899b915097666564581b50c7b9d83ba707763177165e6cefa08ee1c3bbb6aa6ba0276e79c73ceed093533af58cc0b5999e1c2558e7021fc279bdd99ddd904ade93fa1fc994ea8999662e4dd5b7298ddbdfb6f7b9ff61e9c4fd739e7dca53571dd09cfd2a454e44f5a59b933cf6832136adb48486fe7f0fc4b09bb2c5215e173de8ce51080ba2beae42777d309c54e0acbdbb3eca9ab9b32cfdc5d992633a190b0ba93203277954dd01ad4099eda31774ff1022589b5eb1a333be79973ebfb32e7f8ea179d99af759acc84f2d84f8ae5aeeaaf5f7f96adbbf79eb4869979d7693213cafae1c90b9dbbea1c43c8acc1c91e39f23b2d46f742a7b2b2ee8bce49eda6c94ca8784561ca366bc7349909c549983276ddcccd349909c554babb793233a34ebcdddccccddebc326426d5b76f754ea5c94c282e2ea58bac5de5d4e2a05bd7d9d9fdc4bbccccbdcbccd7114cfc74e5c8ec476d33b3bbc7d7c4467b77d77442cd4cf102c58d685777f7554e412b1247bbfceaea7b7a27e67ddddd7d839d5e5ac339f89d7c6d3aa166baff396f67659a32d70ba335a62c459399505c5c0a11ebc549278a53abbbada853bbbbf69efaaab2a7c0eaeeeeeeee3ec248e50cebc0bcecea4658d1c829b681e5235e4be3cd969b4df7bb1bc1a45f59982d67b4669f00eabbbbbbefcdeb025e26ac6e2b4370a05f6091e25ecebea66a96a912684ef102858b8daaaa3452e8ef75d6b5cd59984afa16a6babe54f5295ea0b8234a921811f25e5555bfed1e250b8b533dc476fc7ff69d741ddfe5502581449cc8c28526801f461b304d1c43bb7785d80409633c976236541dc529f6573404229deeebbdd74e00ad393d20ddadccdccaccdddd7df4a25572587d1b07e6a535fa3a2d6d38d5fa2b7f56794c27d40cfbc0d26d82446d3ae7849a39b96d77870eddfd3117116432affa7b9aadaae9849a794547a2bef3e1c8872b3696db7d1ba38cafb11cea2e3641c43c04f7703e6386c76b6938206f13645127ea5a31515a1300add11183a3c94ca82df2b960711196a259948495b933cea8eadeddc5ab8467a87a9643f0df739b43c9c2e23c7f87c3653b8c6788e5d09340220eccc9e9df9c9d9f5c21f23b77ef70d48d5d5aa9c348b64d7dc0fb7d3569cd5e0c8385d6ec3f1e60b49a490fdfbfb92149ab2a12894482ce3d84ae8af0ba2ccb415845e70e3af820f65c073b5226445942c98e54912bf2ee227697bbbb9d7b42d0833e291161c2459f14796f333313713a80106640e5e440be0335d3830962b00345c5dddd1d0a6883d87135113d21d8a8c4b6d16ec37beae498989898189877fd3072dbf978fc2acab61d66c369efbde7fe3dc76cc0c824ce39468c924dd2fdb6f0583346db245da601a6161d4591c2c834616a91143ea6d5978be24fda09e7b0d3c9244e2e134ef503c06d3e1d4f18ecc69a7ecb9ec52bb388f97dd7323112a867cc93fee5b7ea49f2e55bab00519649a096403dad5f9d1f7f9f2d7f62beffe5b7ec5fe4a645f35912a83309d413e6dd7c31f207e61b078cfcf177b3b785c678dc74d94cdcbb786573dd6a15f48a2baeb062f6b75cc1adb7beb10a54c9f687643efbc674de6f246995e65ab4b421995f997f79d14a5b76c37ad7e297a28ce6a30652755d596bb2b5257b427fbbf7741edd42c62f457a898204a99597f71612c27c848260bd3e413e413e41432207350c472116116e1c642e472eb9fce18f2427918286604d2205092161ce414cddbfb12461ad564818568a7285a24f106973f1efb1c65a48c8450b87edbe2d5ac8b22c228ecc1cb107b127596fd2ae97871816532a758c905ab1482412894412827d9584848482545028666560e8ea7d99b82cbe4e0b32bf5cae647409138ec15b2aae54e615e62dabd4ddaca6ee52c985c9b46469f473e95bbca985dc786adb32996c7221f9da9661b6f4d76fc5fcd8c98f4c55550a7f952c8dea2111b78ccc57b07f2b3db3dc96c97c7f3db704e29204e259f16fa66596f995f96a6b98e5afe46acdf2c5f52d23c3aaaae25f25dcbdb5f8f7db3299f065b865bed430e677490b175b0b17d5fff44bf5dfd58bdc2598b4b6944aa5d225f394ccea21a623f3cc428395f6ac97918991312bed66bb25b9a55db21b1073694ba56b77c99eb0e3f29965d7632f972cc9abf4ae84c95db2347697ec125f26bb8445112d20c330dda8b27c3806fc5209fec2eec5b272b1ec09f0314c677de0fbfbc07ef81766033a66c3492df8b44fb7dca3f98379c9dd87fdb95483b194e243c858843062fd1b5cf8f1b187fe7cdc7ddc7ddc8f7e18c2f70db73c8fcc0fd7a8ff45b846f3fde9fd4d3091599c7ed32b97fbb70661de844987fd0f42e8cc4646b39fd4825b748b86debdddb285c310b11823c6fb241f4e41f99e8576fd4973f126ede561b4ec4b9a1523b325e6a7baa6f5db8e6bdb71c5df803a46991898c5be04d3fd72692e34df71a9151f231896b1220a22f3a71641411464da4c2d22829509050d4e28a1cbbc26fcf745474445473e8aa218a2280a1a8aa2301292bd7e7c798b44daad5e29c6ab7456affdaa5769a5b7acedea7ddef78ff53ce6abaeb7aa0a5632af82fcb9dee281fb73bdf5d37a18b9f1bc6064e406c496bc7e576e2db0c0e3555b077a730fc4f3ed836f59414be37dc3e02a58fae700500125bf5592a42483f2b74b02f17cd56f0e0647e9fb696ced57f285f58de3fdfe56bf4115849be9dd975e301d58fa52efbb078049caf4832bf3fe07f6939b0648a4bd2c4bd3795d572968be87984ee9ab188df4301af6acb1f8a7b9571f4ebd64b3b2f665ad17a1a5b101c10aca9ff8efabdfaa5fe71450c77fe917f04befde3b20161aa656a6bba425643de97d849686da20398c0199e6a874eddb26a95323020000450193160000180c08074422d1789ac549d2e50314000e71944868542e8e47429120c6410c06310cc2200860082184010090610a12c406f1aa297d7058837f8b1b6ba6a3b8da89d1f84a5aa68b30e13d60385e72130b19bef353782d285777e3bd89d566e9052d618c076c4c808e8500728c8f263a684805390b015d0acdfbce444428b4cbfb0f86a096e182ba0791435a78ad3dbd979bf5724751718fc17e493b7bd46a4c5151462999718751b334a9b008287b845d690e402665510ae7dc076e317093071a124bc8174783f64a5b7d8e745ae5c15166fabedb2bf5b747fb077332f64217482da436a5fb07ba04a95cd6931ede4c49c1021eeadd3b99c01be9461087682e8cbcfc22e0356a558965f15425002f19baa154a91c6ff1fb49aa6e207ba3d6d0741af75ac4034dbbefa51eb864f631084ae52be461002f6f6e8208539d893d6672ba87cf7df15a40878ca5f90782498f7a24db0365ca3af222b1e5c51a7065ef2e582a19fa29cc43bb45d58198ca7179976ad19587758125487c092826a557702c42741466d2d6a2d4e341fdd4fb54ae27b63eb3779151a080d0f83d01bb1b6d17bc62a79aac957200a35828c9c2f2c4007d474a70f84bf8bc5e099938c89c821ee590c6094ca0a1bb517b2f5375eb4fc18f852631266cf9f198566cfa47c02c04df6489964ba4e76012a1ef892d5488256fde05fb9159ab0df7f5be07661c81e400d9dde857733ba854fb80b1d0eb88c08490951e422e08fb3e8ff9c36587d2a368ac38febda8643f72ba3da01ae40e32bda8c30b3d3e04f9316c4d0218c7bb76e38c00666d68f5d0f851081cbc539d666f27282a877c33926ec27b1a2a72f53a6d4f49e924cf03b6c93234e8addc105a576a3a245d155571a7e57ade80a5eaae159affadd15307a1fdf323ebd23bfdd0d41df1ab9892a1bc612c95d85a73749e2577999523d279015efea0c24817036df00c1d3b0e0f24171651f8e371b98c1c041698571975608392b8da919886024c379bcb3bd654173c928b169d6442dc342d87a587c7098b6b1fda20fab51f7490a56e2110204efecd23031460ed27b558f93b03e30316436b0864d7ec293fb36e78c9cd36c48c6e348b38f1085c2ced5c7953e8944ee44094d88f46d159b1e356650d22c3eae2510c821ccdfa28f074cbb487abba532896739b645a4084556515565fe82e0e94593cef402bf53b290061303509286c9fa877e1920b9feefc52697b99c4e2e2359c86e5d380123a184ec5c8a539fc1c14b4360fd0a1701db54820bda9385cc04ecf9cd839f1855ce143789da8752b4d10f49c1625745413776030ac05ed42e0920e1f46f1f0fe9a07e14220e3024e8f1a6a83a4874d840c1e92064360b25b18ea5508620952186ee4bb268cdcee469e32c41902314b6808341ee860598eef790d81a3aa6dcc817657d882e1530a41e0f0c8542d71f0136678678e4f6143e00a3ed6566a56f861b9f1f16bb854a85b3719fda4a9bfbdb021d06c157023086ac699e1fe5a39b061bd2078d2d0a8432037902ccc2499e61d02338139509b232f18702102c184fcad04767f2a37c75fdd34e70e8106fb4afa03aad5498f3a7d2fb07505e7326067bbec08ce7e77ac46d662952ac54edc215056400a9f76d86a007708dce721707a61c0a0a94ff4e1b6fe98c57cab0d0f814b7f58b76a58e2a78d831c5e97a41f026593c41b4f6999129485c1cacd6522b7301a794364571d8d5a601a93d1c4177263e19876c77e4cdc38154420d854e1544c8c8d260b15040411c820f838bfe74b18f69f26eb2c47b35e9d85d3e48004f942474544203218ac222210b5441e1b9b8e8b08dcbd110bd5f2cc214a03801d657bb38b5b6e6fe250461a5d7953372ba5a2bc70aeb37ac727f709bd4542bd3e491db35f39fcadb71d0b844786e5967bf45bde123f4f55163a60354f52c7977c270b68217fede7065d8be2bc92165cc567c219465ff22ed01012798b33b5747624a60d3acca201f1c5a6bdb3fa27d06315f58a1cfbaea4d1c465e2c42aff5b23f435a0631daac354bb2a25705df2bdf38ef57e1ffca72bc700e163293633940990b038e33d7e995d953aabb74bd20ab9785690f07ac424dabb6fd8b302c5abee19e4a391261ed6289ab4a4bf6070e8176b92a1fd8570b2ce3bbe1e767eaef77610d549edada1f17fb6211c91ac71d38653810bf6c5680a2de393f36e9ed5b0796a08086ec44691d2e31bceaffc707dcdcecb3f862122eac32dad881177f2a4515a068847bce0ee0eacb1f7c21de6f98910a9c490c28f13bd2e80134bbb6699625caede7908fc03f915c2f66c20d65633360423f2a67871bb2ca104b501745a6fc388e221640562f9cecf92c0c7acefde7ee1bf21f58bef2db0ea057f697aa762c0ba936ff7a5c21d5ad98006c532dda13e3201c14df00115fda881f9144ce52e2d3527c7400ea1d8a396767527e8e7aeeb98ee81565dbffffb40911fc826e244e9a87b06d2076ab72ce7f49a2a60ef4e33a58b5745c7bf0267614e4a3fe21ddca8ad2c5fe6385f1101f9a1d3017772494607bffe0858ec2fbb17329e13fe79b007353df199e0ac836f8c071e88e776952c35e4cc75c161bb3f9eec6d83aabfe464b244a6f7e6d74096badceb9011498f1dcf4b788a70d663a2180596afdcbda721f720ffddbd7732ee5e144bf7dad078aadb8b9a120577b8c8f47acf855e707244a29437897a129018e41053f5d7f55e89737475dd2c97f56979eb5d79761cbb3994822ad2becdf46c2b03a715428c76fb5e85a0bd870045f46999471b4dddd8cd65829ee306d414a3824085a0413d8a4fc51f1e5588f71d11fc1c756897b7db57395c75613b29bb769df7a63bd29e5be3c8a5a3a63ab1aa3d63df63eb34fd8f9b5bfa86d074029d8e3a9254e795e1d8053085504adb3198ecc0a5155986b2ef0d153c52a9b22be2b7dd548dbad72b661029bdf63d0377c3ae55ae9c27dbf780300651b46310771c32e9eb1d930380b187b4b37d4f522ceaf63dd9dbff8bb69d79f81caff1a21a6b4df34c19f168f3e451c22e02ecc9e699f81c80fb0728a7c990ff22db1199dec04a7490cd48d048a10598fe928ad42908f6a9076614e66a0dde42a3be6764c3a7be37086077d8b95e570baaef1d5593526879a24e51c65e60505281a52675e64dfac36972f5bda2d205aeb24b89fcddc89901a0f067cd1923109d9f3a5a790987d69c9eafb633374e402b7b93d0f7d4d4ddfaacecccf41ac81b272e8ebb1e766e944e699b481b8ed4d3915cbbdf40edd46472a554a6d3daab6ada0265d16e4572dfa07ac3180234c01eced2d9841ace056f5ef5f0033b4abe77bb03b9b91195b55c7f7f6ffd810c98ae44cb3b55c7f73c26707cafb53262eb9aae7e3f03ec5f90f848cc4442fcf1bd42a67944a84d81b66ee0ac2106dedc0aa03f15d4f75e18b10fcb5443ca40c48df85d853bbd8ab9ee10903b86f4d226436f3c7c8f9c637665e7bc5183cf5f696bc82a0c09cc2e790794e507e7fd1569f2883364254a40146aa627eb762807f0d961ce0871eff55866bf37c97056dc7b32b3e2422e575cbf1fe8fb14f7de1151cd3e0ebf3a0adc1e9481956d71c96d94bf597befb20e4106db7bad51512fc3528559a37826c26053485b1e97b6363140267bbc0fc087b7bcc414125fe1396b1f0efa839807f9b89a4b4df103e0d4f85f3aac66e55cb614a70c619b050d997cf7d0342eefb45e1918dc39ff576b59e9eadc73f6e1d8767cdc006d15f5be80dba6cb34b2c9bbd511da8b12d015bb2b3d1a6b8df0439fd50b01cadb346847633b7e4ad74a1d52ef226cfacf220128c61c67540031ea32f3950e57e68a9d4121125bff0cb962a7879fc89a3ef1a25ae9cfcce3a750e46fd17afe1f31b4c7ecad1d1c1344664c194ba21bbeee417899ed7e8455c5da0200ba6b19d5976db63e86a947804f1832f8c7e3542f9af95ad0213a012c719d222101772ce158cac31155f4d9d0b871efde4e1e6c07db8137eef554915ac339a19c8ea83989eb74353135c6382bdaee017424dff859d29806dad02e4f1eecef495c5748264e658b2b8dea95def39a0a5b745834259635036c67940747d7ff5764e5ddcb1b4ad2916d536092131f90f0669f885fa2a198c3e85399489dd3a22d3a7864c925379d802b031970d327e679575281bd2c06089156fd18ccb57b04465432877c4b984f6004832a1cbebcd0e5f40cb52ff89ade584fc991727ed45a169d96a1cd1ae511b0735cbcf3ed64a1c21455a7b14665e62fef750ae87b139d328d36bc9d33598dbe69306fa9135b862536e0cabda9d55f5ef35f3fee55054054d17a0971343cc8e5220284de932052f25913d1aff87041d432156e5b9c2b5ea4e7b47f04f4aee8473f00f769502884b777522464efb6db63c975f124f85f7a7d820d35a9d3f53c51c44c567b913182c368253450af440ce169f251f3308fbe85e0615ef07758a9b90eede85957f551d5dd1ab8289e42c7fc1aa9a98b287aae5ab60dcd4e163e3d0eadca41c5bcb70279888a79c7dbac1bb214bcfb1c62a2bfb6ea5058ecccf6d1d4d8ee030ada008b3e745b82ad23bb20bef8a5a7b43d660fd4363eacd8bab733a294b6bd08bcfa2781ef286566740b629b2008ad6d7f88988a8e7eeb90499e04bb7c596ec7376855b89d62bdf040f91c360a6b5cb44da441b567f5fde1d40067267561a985dd508246f403308a3ab95fa33234e409b8827421f3db301fd203b39feb11d55ecef8b5c8ef5833148761e1c2638d6a500d00d09e78800257c8bfa89980777b8ad6f974646ab90d6dff4fea9b41a7c3aa091b82e7051aeacce5f41840b9fc023c50a5a00319c4728de0795489cae16fe5c4b7dfb9478e05015ab7eff3660a73fa8465ab968cc78e1f1cc840392c0ad7963d68e4adf01c3de3de5c3850824e8206024729a88808b6c37243beb2b739084c9f8d46642b4bac269fd0ae9a5a149c559dc63cb90359b2f5abb55d7b3b43a64a8139261c97ce14a683769e12fdd61eb0a3600f3ea8e6601118d8a3d70b1477a9141143615bd0499ca247b0bb8f54c40077eb27898e2b5c65f898198611ba7e36a123d67bf3a730ee23ee2c24c5dbbaa9729801855a18141988b69278241dfaf14a5aa05f79a872d6e1cc567804aa1f3402e6aa01c076a1ab90e2437f4fe1c5b23148c29dcf3b95cd74b6302a620d8f78794c487863e06d08b66658813fc595aa9982233e541757c4f578767586c551a80294ae773f91c004549b4a254350c7fc446c350ecdf946f945169084fc9a106baadb71bf1521c0988617b131008174afe9a2222f1ed3096ae52bf430c46608b919836842300ac0d4eb56cfc3ec97ccc1f4474703b741e68351e9a4282cfdde6a4266ef65bbc586f80899e0d8aa2711bcb08ed56189bdae174057fa1472bca20c33621daddab6352539df48ae4d1d62bc7adbd5c5bc3f9322146d906be5aaf96cdb6a807c65873f68e4a82f14ca4795dfba20fc59538eb0c32066bc6a3231f0b3e50b55ee4999ee027108ba4f94e7aaad70eea4a8554ea6b5b01d357d21d0a3d883ce9371e0de95a000f3b0c5472fba931d2bf72b12529fe89b01099fa552ad4152607eeb61fff9115e23009eb9efc97e5c1b43fed8f2ffc3272f251292b5f8c442fa56d9931b1fb8a71f659affb0ce803f4add86782a1a456384fb4c37d4803bd56a832253032eaafc4766f875314885ad271ba52b41f2b97ed8bc184cd28ff12636108c9e166ba00c8d9b59e67e70f843aac8d53455f3414eb14808ec9624807c2497c2bd6b7856edf3dc97a95b37e43756d0581c073d4408123ff55b2e4f95f3584c2a218256b8d458c9e1da4d4d6612adbe236b9ad39f21eaad1d7bee0606e077d5fc259fa8e4922b74e13fc2961c4fc4467ece269be8213eca93eae941a9412e00622e6bf194157a26c0909de8771e9fbca6fc08f05f00c2d30841fdff46b425143e84c8f426bf134337852b7d6dc827962095960082d5cf43fb0bfa9e2cfdd74eca45a418b91d778bb4e847d3a83e22e01924e74972f61b004ca64d9424207c18735508fe86426b2f6479ea65a7ac009c223ac622e4b2efbbcbbaeee5815b59edbe9c113d4fd959b7173829886936e0db61e0ee2e2f34b374eb6f1dc066f61fa825e0a3dffe1943bf8452d6990c1d1301f9a07cb4f3ffdaa600433df0506b2da25936cfaf521f384d66b220948ab035949a21b22194be95e277e8b2a1febce1770751124815be31779dbbdcc8a8a4fb0a21d2cd2d38d0e282fa307c012523e4e748d016c5439a7b3cf9040d10101677af34d1c186fb05f2f550c86c7cd6e5f2c95d8f7270ece6296837b72e18dd5e329bf5bc3b5f148bbe2549c250afdc0ff33fd1496919bde40bf21ac1bb93fc134eafdf54f9e2ef548d50d4184e38a24fa785c38f3d0b90ec02b22e4aff4791e0d84f44d79bc2943f3d6ba05fe81b9e8c29735d73785a75165b44e87f97c855f1bf2243941a2476b7c546e1bd111e8f32d23ac04295164a30ae3ea323621d160121315fa477a009e0f8a3631a8bc0f1fe1f31dfc98c6194f9efaa4d1e11c456c3e168bd69a22343c14b9fa941dc2b4f5189f661524d16031cf4b80ded9ecc1cfd1a63ba2cb48f4f205585c9210fdcd8f5303b8468a578aca753ac2c3718a95422f90978484f6b8e75971df8a7802437da2471cc0d32e4f9da06d16f5f378b7a07c9044265ccc30d2f41a1d9438e698ae03ff1091b92318bd03ae352aa3472f11a92a5a4c4c953ffdfc9f5f2535f32096403073f577e78d53a9846f540ccb4014619cc95a510afa1c2c45dc9bc923575d99f86336cfd6533a17fa163a103c71e32d184044478436c4478cb4c0aaef9855046077bd3f01a658b10ecdc906f243b6ef4123180a6ac5f6c5c451781510550ad0b3f776a403bec80f55595c61f5ae9fe907e63981dae8a25680d32cb6d79479293922723454a9684843c12728d0472039494f9768162f7abd210842535f11a37dac89963af80755a33e8cb09dcb392c4ca679e4bc7eab544a2de1e356f231f485dd6d737dde8e761403121e1602915b27516e43f3d09e7d49c4f9d4a711d53e1709cff8168058de9a6d3a6441d24629549e314d0a7ad95f416915ab7f9f9b5c64ce3769ac82a513dc0b39269c476a6121689b77fa09e4ed8b57f57ad1e454e3966fa53df61d9481e38795ed03def61e9385ea20d777c3d0c4ccf4e7dab6f8647ed4578bcc3206889967c4a0cc01380f51769d2a05485ec3b5ea8b5f47a7e5535f8440208af7475c68c74887a235ad4ec67cfffb955996d405fde307c0224454a26b57c019163ba9a98b1af1644709ea283f9958db02faae7dd27ba56cae4ba0fccf2bb98c322837529080f85ff8deb0f52fbe82f363ce746f265da0656fb7d7005b100c023f2c6b3b307f92b77653c32b5c07d069b7c4d15ccb972ee8c25a193404cebef7bf3443d5be6dc253ccb7b27ca9ac42f286d959372c1d86833c4ac4ed5cb09409685306dce3a3523959710e530e7aaa346d468f30f73f3fc1bbe95c10677ad977ee6a6f0843333d9830fdc7e3cef52824d1bbb09ec9c88352d6fb4e596bf4447617472fa0c9f09729e8b84d48d507aaed8d9579c5b0d5106bed65287549b49b88a9be1fa79b46eee6f94a143c3b83f6cf7ad2f8e14ab566bf7fbc50048dbfdb489dc12f20a5625745ffb432acbc42ac2dc9545cc8254884866bed6f19dd620b78a3d8752cb94e211dcc8d157781cf4f98f3df22db1926163c44d5cbc11ffa5b90fdfabf97d213fb25d0290ef5e09a085e2a10f8b29905040489c9b928670bb0ab99f2e5f6692abf674af09dfe01a8b1b2570dc20f316d57554749cf73ca66b8e60f9e6447f6c3acedbed20e6d2946037b1dadee565781040f2de70ff082e4e7f7571e47c1fbd9b94101bca4677f1036bb5481d9de3b7dfc07b63896c8f30669ed166d2235c60328fddc9c5ab42b5429769c85e96a6b9eb6d97b8d12da6f0c2b7b4b125f0cc3f9618193d9904db3811e87d324c0d4073c209e10c0bcb572e855cca92d17c8329198b6a6256149e4b3c6c317228594eb2756b6aa1493da7b0bc9057cc1abfbfb8dfcb67b13cdc83ecfd007aa2f605f0b29b60ec33e9a3359e494b5d798f89671c56ecf004f45ce37d5dd2bac0aa8dab3a04cf3d683b1fa7d80d0e20844a72416783e75ca09cc67ebf808293fccbb2e4521fcab5f21438eec964cb8250d17613a8cfcbdeadb8ed15b2e10653144caae8bf38b2caa15465abca16e79258e84f8bb531262ec0040f378f58ddceccf4b320c47d04abdbba5afc26a49c7cd2ffb6b96ace21877c70a9816edae02b0b308067076f1b6675ec21ed5480bed64384744fd808af4398d4380effc261f080c3be8242c91925d2ccb7edad2a3dd2a55c209d40b6518d8a55cebd2fbc244eb96bb5080dd82f918c5580e86a12b847501e10ad3ad03b61ee6a03ed628f8d7c3e2ec1ad73b0bb5789bc6b27a773807eedd88c4e92ae11cefdb3aea10478030e1051f85365b6c8eac24be9d003dcf8017c2e00abbfea75569643d3ff59db419839bbb3aa75a9380870929ec1aadbf6e825132f2255b93901957a38d3a77f61b05229942c904a38447c102d8b9c4fe19061585961f3f938a814902926089c222f70d1442e0d5ce10f87bb590733201815942cde74c20509e5a7e5e9011bf35c1b0309761c224d663661adbc10cc56f5324dd2b5a509b672fc54881810c22235756b749caedae0858a4081afdcf86fb47306f7d406a61f0e019bde2de7b83b6f5f8a3ec48513de8328d85d2e3c8d97a6cf9c2ba6318a818a5c2f76d9cbf98c0f9aa17175df68a3de374a8627c5ffba3a4d0498cd563e9683e9f3ced7ab3fced4188c2fde4f8dac2b40e075d17f2cf69dabff933bdbc9189e3108251e803094db7a4e25b3263d8d29cc628ad3ec942a37690202f5a14524ccea7fbbeb17887d99b04b72a2784445acf44044f03f92fc297199e5032e336c0f3f24ee3785ad4dc2f156a5c451791603cc30b545ac85959b7f0c6e076228b017a2ef2d9fc3dd9defca711cdde4a322f65ea891c1cda8d859bb36e6b13fb45194053250ff13f10cd6175936ab8ab94230db48beeb2c01742c163fbc2e8cd61727754542ce781e141810ddba270484dba7ff9a19cd6bbbaf91347ad10dfc7918c7b3cd08d32988e3f0285eb07d101e2d488be85639714d337e95086150735b08ca8a8ebb3f972940beef9e6e75c0d7e746f1fab476fd2c9dd95d4e66a41180ca87a6d27fd8b1f0322fb6a267eb1ea2f93493a9f5eede015a7eebcc36360a62bf9982edbf8f5065b008a74d56aa152385273f06e2bb88a5a1a61c5759f982637ef908d4410e342ecd03968407f24fa2c3ea2c2b7c536913d231aca1d4030244edce9e1f0be8263bbeabadd8c6673c88e70bae8dbda922e4204eb99562949fabd097b7255f89e84f8e0275568b7f643c6c4c7f823f1673afb25682a8847bc0c57ae84aacbf84a5d3ba0d209ffdfcada1d64b5be347ad0f9d40d7ec05f72b91ce11ab384c9868097ac7f0488003fb086f9ef9c512b1c1a7b0fe5cd99ad528844ec922dc3b7214de776672332ff0d786e865d27fa34eca03a3aa2c49403b139efa949677256f87d06059f0bfd381484ab9c1731f7edc19688ad152869a3dbabb20e2c3df9b289ff214439c15b21d79b152f6595a2e421734dfeb17ffe9db0566aa4ed4edf8b1a740d0251530c8d79752c592d9038a1b1506f41051a9c0f67b820c5c592a98c3000fa59c7be13ba494e9d9b6fab0ac0175e50b88a72f38acfe16915faef8db303f60f1be4162248690355823ab15a742ff15fcb293fb096ec3e56c77181e53a3a9a8216a71e7cd856b8e6923211384bd6278c779940fcc9bd9561708127e4559d0728db2c912f6bc5db394f771a031b78d2b33d862a577928e4976418c2354849b5812a754a83eeb0967e75a9b8e83c31c47cad326ce86ae74b6613d596b8d121b564c36a0056ce4a14996e4a4b9ec4e43d6f41ee02f6e8319fd1711f3527e1aa729daaba201553e5ded94ba843bfa74512e7be812e34420fe6f64b829f3c9743c5b459d559485a82852a60abe83d423d71c35634b8923ca31b3b223d3ffcabb8231b5f3b427f5929121c581a1e75ac35d1d6c0f2bd21412309a3192bad001fbdda9b089daf33250c02de79770cf29eb1b0bf7c2e1e48e9aef9aeebdd1c55d1032baed57790d606f1118ab52ef44eff45c190fa0c8619983d6ee3779ff925c9022602af2b4e69a01ef3e18ba5eb2ea401fb77fdc140df2ecc7b773a1efafe9d445f44b50546cc49387f0e88ac357e677b58fafa7947283918669464214686093ec26a830e465f3b84d395f5100a6e13a16b3aa297bfd42e94adc49a95b2ee085bdaf5ce06b59578fb047db6b2122dbc3a90d7f3755cc41395c8c468452697daf9b69a49edfb787689b54dcd036685d7ada809a83be54dad6b5f61bae0c3fdc934b6a8174747857f2791972e43f9d6fd276708456c0586c34101c846ea1bcb799849f625c2efc7d86c7906da8ee855c77839c36703f8ca5c5d1652139c3a89d3b20e6d2ad9304f66925b65cc3a484ab53e4f97896b828966a791a995e17c8a371492f75bdf108c9d4097f3cda84a723109a55f54227bb7f3bb1b8de473a1daad80496c8ddeb7f3a81db77b23f0a017d78761044a3721310f239bf9388465738b1145e0885d05e9d5f13d1d4e4bdc19d588a1da36067a32d504c1578d85131b324f6b57f02dc1f8d8cd76fdd870b0963b90cf11e23474dcdee4bb3f47e2ca86a2282ff9710caec1ab54b34ddf32816dce851f81d09d269299720a1b50027a48489c515f9e2a938ce0e38bee651220dde2998957573ec2947114b3f45ce9fa875fd072e86df856597c1645ce5970fecd5e83c0c1741d0a864a903c139899351f9352d261419d141f235d6dc2b88e7ac82c92735db13a4ac61b1a339341c24deaa442bea0c29a9a1cd37754def2941dba0175d14739d07b5fc799c3303ed6e9bce1e41209430484ead526fb86d2bee5024804e51edb07be4b922341b80719e56ec9ba7a3487b0e56efbe3c44a2b5d255b26a288f9cbd14875bcf109358f6d94a2b187e8c29c9e0e41b45cbfa41a57e59283e2f95cd09a44d2273426f781aa13d127527adc23157c233d9769def98dc85350b890441444130a6bba5dd0a5a93eaf6570e6d9b1d60112cc12746b14819d481ee156f4ef1a5979bcdbf41d0b63bc59dd3496131a0a525a53fb462d31245d83657185a1f25fff1ba5bb4e025e54b122a16bc9a41ea06ab7cf7116e2f165b035f0c8c5bd1b2bf9501f0cb672f044d1269bd0cc5c3194eff5c33183433a808bcebce0b63238f382e3d0e50a6c3f75bb3beff915a75dcdb65cf4f4ebfbad1fd3818cc98021b97ef82719880e3a543458f670ef2e66e659c7ee3821a0a5f7477cbc788450f8c1ac17f75377a008e874a871f270447082d13b735c33fcd64e893b4543aed7aa884e49ede04b0a5614d690054598c396a8553adf8cf04516375e71a97b5dfcce23997010bed2407671ccd6f5c5c34dc85f37b8951d8b8c46490f3f1f711cdb54351c371127b701ae90b5d348714fe1deb44a38016b260062297a0570382882456d8eb966b5642d7405e67b5993acae0f4d15c0056961bc3312c83e2c239c8e50c5db9a040474834b2b27385abfa722b3f835f36cdbf842978115a1ef4619028885688133ee7ee296a8ea8a376fb238aaa9aed3eaad7377d9eaf999c30add212e0cc28879e8abbf4d6bc6082d34505a4a3472eb368d6ade9f5ef218bfc3b0f4b79c5d64a595309ec4a458c365d7550b046887de09de7da15e09dc94ecf8a81645290d7c1d827ce3a8d59d84e0c086174547b4986db83779970073d853cee80b1405b3eb135ed0772ebc36e1b0072f4e4dd89e72604917ed6a1a09721a59fecec341b88fc71ac1e1202f88dc8c8d64901e1c22bc5121a6222d77d631c75a952b86076a884b58527f4d3dd81a8fa2000c8cbb833a19a96586ed27f3453fc133dcb4bf4f950a2fb54015b6504013411768187bb49c598492996830980a6371ae895c39eab3b68a9e26105b63b2165765d9ab9c9c1dd296c93707a25841f2653c7ec810a9e89ba380f009aab99d3aac5a55336f98cb023ddbbbbf3fb62e820805961d2f7a143e848245fa28a023c8bef25288e0c32b9259cb9651c6e8337b2c9221ed24510bd6a75b48d11d6e15f88e32958a2d36cd2706a1676778e6770d1a16332704b3ae8ed081c3a56318610939f982c22ca64632cc2a46daa4e88348fcd8aaed0a6084bd1a761fb42232f37d25d4c141b80efacb88153b622be74d09c355d39958764b572d73a64cfb5ffc87a5886a3a6c306d6635e326624a0df57e32c7e3c8440199c2e402688b22c2224477a6810213a9d5b85576ec0bed1cfd3690d8b54f22355ae79e2bfaaba2e9961c523bbda57306ba8076785bd191d78bae262bed344de3d5a05629c3b3a63a1ee42203c0acdd8813cc7e6274375978cc0db3d55358020ba6cd237473a28562f7dfc6db5d9247ce3e515e48459dfd1ee7cf4e799d536843cde88a778e77eba2b604c747605e24dc513825f80e47ea52887c1c7ea15f623af05608cb8b6d289bcfd4d606bd7fe56e550698ebd801ad51146056e2856c8aa9c997a87a7026b0bc015fc31aa6cab23fce7b081ed2a96982d98db58ec622cc9f11e2ef00e07253e5c4db2ed5bef18c70a6740852e028bb9e058a32729617babe66cb817156a86bc0f78c05cffa62c81981848d056549f8b1dc64e41e7e381ae3798d159603d0c61b20f9bb5e447515e65f3861cf4447bfc5adb01a26f4ae111f85cb587e4717096cb5a8e51b037b04a3bc66d88b0ddbdfe542c502da96b077d82291ed1475621dd916cba0890e78f52c782f89ea92f462be2dc644f461951583558b774c0cada65222fcf8e14a4671e14a3cdc48bd919790b3a9d1f597f3758ae9daf3a95814a9cbe7329d7aeddfa0405049dd4c2e38c003a4efeb9a209469c2fa21386c30b01260fb6874ec62d16cde0a7e5eb690391de80c0c31fd3f8af845e089a4657d28e20ee19aed1780efd5448136000df9b664e29a20d10725609dd0b0a984e890d1e47db8798e3817b1ebe99688d5ce182e7ce39f894ce7ca8001bb761fbf8ff9b7e5500edc01a12d7022889fc3927e1d6e0604933b93368261315ba516c5bab6dcaf3e32f25fd3bee28c9d8eae48c9bccfe7884e91374b33cfe412f1913a088573d15fbddfe164fec344605ca1819240443ce2ca1051c8898a3c2b9c2b01d8f8c3747d69e26d9eca69462c8a51cc92cea240a08ba5347f0549287ebf7288f5ae12a67226ef20be9b9ed8f53d825a3d02c1ca8693c4b2378057c3438138a19a4ef1636d3a7778224c6dcd0831515fa10b0ed96a7926d1ef04c0eb2eea7ff08333a9691f4970a5a44901a7ff9d26378d1d81c2b2a50b3c851739b5ca54bb29a597e5d3d58a9734e6627dde041da2817451fcc18e3a2f95b85662761454c716b27a1f4f8874380d3590c60046d98925725a068433650513ce2b2be4e81321d972e87bd6972fe16d35619907a5ad373c9b7ded7f2255f142ea67e31c317a10a33c5892f1d849a0ac2e59b4e346576b9aa8107e2c68c3dd4403f9d9041db3b5c5739ca9966f0814ccef447c69c9d724cdb2ed8ff56433472b317ba3189e3063e1505f6fb2e40ba9f9d6bfea8c87e04c3f4ed6969c58c21437066724103a7564c949a83b04d65cf5fd512ea8d6bba2cff41cd3ad1ca305ce4d94ccee8cbd0f73d0c77855933c0c329570e567d0b9135a122dad6115162c33844c00424ebc53d1ac6f950711e9801c5a225307e903755405a3aa0b0c40dc8fae59f4f286f905f1276f90d6e1f23274cfb54726fec389543779abfacf69a57b2f3bd84e05291843bb7ab724293266f8534237b864c58a5c55e497cdd429b901268b02143eb808aa76b2f806f563511813fddecf2127aa69b733ab568d84c1198af4f265b9014774397682cd35212a09526661552281340943040913a69e7113c92445edd73f18b0e642a06d69c80bb95ed3a0b34dca92959fcb8d6647471870ff16fcafe86194fbd45519a116b003313b6158aeede3e7f654d8430d0e4350aee2d952a2f6bd00c00e58a0590f1e4431c21dd444f01f2ad1d8aa2f607720ba18655fab147f3f7c10797dc82eecda0832947814f0a8bfddaa314f897cd38144c7d7c4f8db7e1b7170b1cb6024141718291b55871c74c5abb20b39a138c827f31921212c5d29fb51de02a315d0904cd39c382277b4529b36f8c7a91e0b25161b008eb617f4b0f93c0a30289ab849ea08b2a04945ea5a43344891bc1aa74573d1078e474277861fbd63074301a366c550549f897c8f897c341cee3f94a2bf786fe937e9dd528842547199b6368ab957af20dabea902d0eb9ea646074743b97daa0ef46b8094dc836f72a828ccdb174b09dd8212cbe7a2d2341aa59886cd13ac88f0d99b8f523eff0e99111efc687fc0967f92bd9353a494f21a835adc068d6c7b80f94ef41bb8803e50e10b0369b2bc797bce7e77115e6bc45d0d11477df845b56c97fbe220afeb296680e5ee0489661939e25cc1beb580a7bfac299a370857d57717e0d932a059c807c42fc713d2e80b464565d2324d6edc8b2be606c3cd2ac1b07c78e961314c24b162076fcd728824a861d07cb20d1fef09fc1a2d10e58a62b2da500aa0dc2355831b452e458d5bcf569b52c870bed62af7e585bdf5ca173706af17793a34c622d147610524bd55e459d0b311f4d797b803d6c71dff0f40ba999eaf27abe3cf0c8d5bfeaedeca4550d6d40e9742a8ec069a29b07a7ed27a2f6afe92f0f9801a1a372fb818597847303a733af21b79a46af56fc680f0561b858e72ddf1a357eaaa4dddf0409a5fa573b0651c148e24bf1b0d4ce29d06fd3ea23a279aef4a45e0a604b2f3ca81ba45b71ea087868e4c45957bc090e0cea27909c80f804dd08a35cb7c3eaada0ffd26e1a1392853ce6196f4eeb8cfb28d748473f99a3bdc2d4122b8e5e209694ef1853462080dab833235a726a66c628bb7bdfad07ae93042a08ab3bce4c819d73d399b1841f3297018d39efc5f8a8ed65eec8bef5e8c44462a0b43f3fe59550ba09f91b48659262f7f68428cd57c15135ab97288f73fd893896bd8e7f9a68953b088917d148a1d61e5a9729ce52e0cbee1f605a51f0cd17c56ac6d9ee450684a53faf7d87c2a2f36121eec289ecbf96b2b0b88847aef2accb08ac3ee4ef75e7be126d9c3dfde95f7c2888f7ced25fc097e9d77681c05be95790dea26439008ee49710984d26ca312faa33016a436515fa9ff8c0ae7ad509606b44820841768f1c29de61080257a3c66ca9d29b1b62d07dc68c43fddd8883fe56545c11cbc418428a2529ac08745fb270c7f4816d69e3f6bbc1fd3389ae59653d9a39f98c8c01c246e53bb49afd7aec93168d83bd149f8af58d0e9e56635972e4e1f2b2b9b19a451776ce694fe764a2d2f4e63989d5b87766eebc9e758c6b08911e20760f85e36a5dc1682a354536c1a8efd1fa573ab17bafdc04f418396b88fb7fa529597a64c2649fb488d0efd13846dee12b70ecca404c8a0fde255a2b164e9e97c1cb6472e1ee15f78a436468a01341800d11e140f4614b254f3944fc04e39ccc0d9dd076bd1ec4834354c23b3a6d8cd17911a04dad7def4403f90bf6601b8e5ab28844ebf4e5992ff4a576c4c7a00f252ea068865be3301d90b8e842519660d94a96c10056f85d7885f154be2b57215e688dcda1be9d3c473f9fa3e85b725c76e962e6afb88b11a3869e283bca18c31dab157a5040ae8283a1b6df63cc78dfdaf23346a61e4b7df597169b6f6b9bcd24300234be2ab9ee8b67477c36f44b3f36ed9bfd7c89070cf0ae1bed6ca6d9b54b46b251d984209f151fe21abbca0ad157ab94f6d2e4cf92767c792b3bf941d84d1323b61595ebbb98c5c4c1277b127ca4607f0a53e6c78124786aa5a5a29652cc6abb557c998ced856a18c5507abe698816fd113b816911aa0d2e53d1e820d1aa7c73649f8ad553dce9f5901f9374f32f02149242e7730965d901a123b43cf9a442cf7e86600881bc62471e46c922959e3155fdd44080f699050c072922bdb033144ab51b549625d327b5b4c3801933561b2ac38e3f8977d0f9388af06feda81af5eae07f71f7a8ca7e72b9def229c18d5c5eed2742b12ae3b47119fe08a4ba982bbef40286e80878b700de5872ec415998c120470b4fa0490007890466271bd5371b2a95401fc4411a1532e8078c08035a25edd909241e7b707c2a9b05a3c09ae1ae14f16a1596844acb9373898d14531f12755da60e28e6791ea67f359bc3da6c4fdc2a0c56f882cfbaf8aa02b953295bff3e647aa8bde1742b37194392b09ad9f52bc061badbed7647f87b7e2fc96b097d636a6a4d46cfc9605b6551aefddadae20e90ba76b63539403195a1be5453c22d5c55ddd1fd6a1b7aeb72b17558df47d986a3c70923f55151a61a651efa0cea684b11e8215837b03fe5498b49dfc7fa4e5d0ddbc25d5d83474446bbe7b7dbadf174e9eeb3547b547a2d216cf724809de28f79841f14cbd7a1c39b64f6d0a67b94b6ba1939992a25f63e1c220e1b1f5ff287b20d4aa1f5a6de07ba3db23c41a632af4809d425f1f2cc1be8e6d3871eee9e7834f139ddaf3fe5753010d9fc8a06a59c54338fc38fbe0646025bdc6fc0f77827111c5a23635212902ef77c3f1d3710f983571469f01f3865e8109d9448cd91b4a28ea60b4f1171b39d676c61dd19bc1901f5ddf34a4c8e69fbd0051f5eaed917944572cbf26bf822c03ad3d429ff70d170fa4c94f178a74c5c8b97bb658e4a8a871b1586872239ebfcffe5e49ba74289ee24ab071a34ac3864aa880559d42cbe8654cd48660a269f27616e03faa270dcb1b59bb4e0acfafa942b1460ad10c1109b8c5443943370a7675d9b3cdbb1447ef7f0f6f66e939b99522caab61a0463612955cb282e311162c4eae124f8596047006ede98fc3d9e34688f5349b6eeb2e5d70a4ceda2ea51ea82f732a31321970e195ee6605ce12e341b83340bcb8a70871828a09ffe37ec551851e5db8c57d1fa60219ea48b68a64c1f844da223123f604adbbb91b00dbdef8ba542266997755297dbb16e63881ae972270efd917ba505e815e653f33b6a0a11b8258cec370119e16278c45d44a81e9a37d9cb0cfc61e3f663e5a6d343a9323af74df531fc734b377354edb75d2f7ed63a0138120171175e5dca55cc1a79832e389cfc81cda97a2ca8f2bf6d34832bc74702560e2e11f11bc45a60a2446e0a85b8308f6e7052415da44f0394aa1b6d4888485e8f7c306ab40ecc36fd708cb5b3e42b1472ebd75cad12bf17b06aaa6cee63527fcd744a836556132555d9f11a2d74dff43fc38834dae95b6d0a9537ab521bfa4efd6413895d51812aa879725b06492c984054a23a2e12e8a1a76e40abb2b2a436531b915976ba118fc8c40ba629ea418d9cecdd29b6c697c823d044f74d765a8506ddaede2f50d4eca8214e542827d4c3f3445ae7085c2507853bf20dae4e76804a544653a690323ef8aca5655546919cbff0ed78c46fbb6aadc13275c529bc41617ddddfeb89084b1fde69164b809c8023eaad739b0c07696be79fceb34ace1039ffed753110211ee87a782d88ffac45d47fc2aff8a1ffc75ff39b4918186ba2d83f18750b0d8a04283868c9108147377d30373adc9aa00e863b965257b1128ea524ab6f2ebc3aad5a96795b3443bf71cdef03978f19a592ebcef0351e8b18cd767b3484b83bc57bc0e04c5d150c5984c875cbc887ea35c0b07719050aa69c0f62bd5c4f9e60be30e432aa8e2b3d84594487a03fa02f2a8cd1deeaad2198133bac1fc6c5fe0cd0c26b2cf06ccf80f57d2169b50e5c13d57b35f1ba81aecd1b17c4362e6056d67d9a7ae74d0114ede2a8e1cccfe46f1e035d1ea4575a1d260ce59bd4953c8814670fabba5430ea861ba116aa483fe7f014e8220c3d74b71beb91d4667eb9905173ec07148415241ddd72cb816e4713d59f21e3408eb366fc82c8e3d6b1a9e1b7eb847dd0a50f9de6dc660c53033aecd5d7cff17bfa7684aca6987826f23673d8fa28ce7d22f3da9ac5d0697e2d6482c52c2067c0de818750340ed6111a9201e506b8ac88d7e00fdb11299ab71f2aaa07868da8c8e2d9cd5a636345087e1ab83fb232232a3627062a6849ea1361397c0becdb7f6e627880b61669126b40868068c57b52ac919b5278ad45f3684525813eb65e85ac04fd3140edd3d2a7fcc3f7ec6551389f9f12a5486bf8920ed78abea852e68cf0da2c450b72939129db52c06d2aa46d620e550d5ea6ea1b1ad370d9a900ac305343cfdcd12703f4b4797dadb8e104013c1a97df2c9d3141ef29e2304890858106940dd6dc79e98d3f2af7e148f216c0a2d7a190dc613a80325369b43e4e08307ea7bc8d130297c3e863c6bbb669486b4c7b0c75f5ef2b2e222a9847cbc3747a300185e058b69909fa37431d4dfef30ab136a522018b5ba75bd039281b1f5743135eaae0ed9c78f03dc2a2760ff5d5e37e9cba10ca81aab9920b475d004d44219afda36a45135c44d467a91b9ba7a6e6fe07ed6363702887dcf9e4ed2cc97732d9ec580a3be27f3b1fe3b910e0109db5261e74c27b73684c663fc4ca921d8332a36858e38a9fcd81094c56e2cfa61d4c5eb395f867a863936f6e2dd619eae0e5974932e9a2f856b69c2830eb7ca5e115eb8e17af671efba53c5110cbd96a339091e7769e9e3cf5e6b9c9333d2f00e9bdac2e88d13f4b5dfce53ad80c5fdaf85e7ddd7a43f911162f1a4c5211c4e7305119ba0f809497e2a8151ec2e875036e0d7e18a08dc167435a0dbec3b407f49da2d951161253fcc714ff30a57f5ce91f53803fe6db2162c1d9bad00ff7df8fd2caac8cd7ef127b9b16de3b435efabbbb8fd30fddc3eca1f2007d301c0ecc95122418b5f38446ded30224f456b7a61ad29d2574424f1f446963a0687cd7a2ae344d2ba4f71164e6ef66bb257418e5bc97cc18368ce1a43a0ce092554a74d40d65e713bbcd21caa0d711d99ce9344f36effb1ce71aec953f253aa55f394de9c3df2d2b452b71953e654a83d10a9a0e1779ead5c1b4b58b195d03cac8b9ada249bfcbab63da6e916a6b06d191b07ff81fd20efc87f4c3ef21dac17f400bc62af963a052bf434a13f10e8b43f401eee1774877e83fa01dcc071cd814d67e2843d16a3e178ab8b0d8f7aee7866561e89d8de1d410776a0a2225c6c609b54a7c7f80480c9afe685d7f4c4fe824ece56d7cd47e382f8dc08763373c0700174bc86c5e5528feeadf321d7400623067923f2de02c3428549036e8cbe891c668bc01ff0c41f8e578e2b4a46aacbd3a1f7d73884046fe9453037e56da4f1b90114ff388d8de85e18a9b06d71097e2fd5c08cb3e6ee06d2e0a5833029d3de98d39a8dab875919a91145bc7f4082ddae63ecbd723c6092fa961d5e279e7e5c355aa122959c72d88ed0a6cbb060d0a0394214e832fef75cc731d0d6886bf3cd781e7edc07b1f78ee47c4e30b9a3e0e7e4d542473e0885bb5ee8768a7260bf4d80fd4e28782b6cae2722cd210846ebce9a87ec63c87e1894e77cc09b3ac11c019232b876ba5649d1cdab92755757a3c29c946981a8e7a3c06370bc954b8b67513de0900d68d1cdd50f31643cdb707f8221aada9c0f5bb4ed794ede12dd1db0e79b0419788170d382fd4ab570ef3939b8c7b3888688c640f2bf6a8e862fddb3cc249eabf24563141e4fe1903139afdd60431cee36aa25ffb32d6a58d2c2ce103f384dc0028e708bf473dde24293d5009c9f67e494d404ead12ca3414dc05838bb75693a407408b971b1e850b88bb3d1c91ffe25308608ddf7014483899ff38d79afe319d15442c2ec9eb41c03a5522540284480d8cfa11f7f72e85218bcfa8b49296c0a1527d940afed95b03071ddbd84250466019d74bef2fd704c05517f37bb91084a579764adba08936fd57587e4f49a870baabf0cdb058d557853f750e3d6ced9b205c15989dc3b26b493eea134a0d17567889544ac59162d17e8fcdf56d1d5afe3ef2658058cf89093631e0f41d3730fb351849f6a71046e8d9bb08afd58497bcfae6c88e3c533fdf2664164432d19276e05b87d6d29b2ec00036a2b94a1f82e75988a80b612bd30d6d8de73d3cdc8f6599918c4ff1d5167567f0793768bd3e64a859bb8b86413d895e91fe12d909ed1b78d6cfb93174bd6bd4ee96e9aeda900202c1ad416a96f5f31221fd98b72c5de788b4a952075146e410c5767c92cc2ce363ecdaeee68d87abac86355af56994c192f52806ac9812a9718dea8005be5676156a9c57f0a8be7304fee4a6eb117b683de734f745ca0cd707b0a77894cf5b84be1abfcb949ba9111d4c83343a02769bffe277e04de70270fbc3c44d43dbbac02a8a9990f20c8054a0c64bb93986fabe56b482cfff5eb296e8c1b092e297d912a9009ba05590c0072c026521450f571f62737d58ddfd2692a57cf2155ec9b4c31406086a27f2de857b6e9f0823081bb3034671bdfe1bb3d2f85b91446ec3884c6263c204cca6d173b452cdef7035e5bf24c0a202414cec2271a9186773695ef75e6beafedc4aee5399c706cdc4bc1d5256854c80179f4765675d530cda0c48ebc1990d136cb5d61f32f65da02faf65c3cb9f13fc9b511fb849d3c6e5fc7c7d707e5dd4295c11448c03dbad978294437e82b6f08ccce689b5dded1f7fee2df43fa00482fb8c264b31084d3c2d041096d7a2cb2e1924fc55ff26bab0a345288fa519569b2323ba4f8ef589cc28172e88aea2453fb5fcfb60e4cb18edd3ac2807db3b94574ee48593ad022aee9ac7237682d36c2fa570ab5344a6502bf4622d299f4daa84efa17d82eeb60b5115811d9b6afe9a99a6da7da8c2ac51afe1767acddb12fa18827917027efd63f0f286a06647c815698c9caac06cd931c8f0ccffd5e400a65afd56123efea8b693e66931c2f5c5a155041074d8036a4803b15310282d2b1d613099762cbf801591ef8664043b488ee9ff7409aa38b00ea422672ff2d955e2628df8149f075b4121cc7edd76785a75f615ce76ee4a15d5cb6dcfb6c8c8268180022dedde7213b2f79652ca2403390b750af00abbcbbb840848a26bcef97322d981820176f04080274de3cffb601a1d236965ce017809ad3cc979093f78931b9df0a8bb3dc30e7ac0b5f16b0408405858d8111d5fb37dd00769a69ce3205da5e3679834001674bc1539569e4cff127e20674e3fa2e36dfa6ed0c1609beeb6073a5e0739690f356b5e4a930f5b6c21a5e9072c6a1082df71040741e40d260852fc5abf8705d8f13b7e860680e02120dfecd06fb4950e6c72d002040e414cb54912469ed5871046f810afbd7c6942aaaa164c29d13291bc79285efe355953f2c290c87f322144d2df84446af249081211b67ff335e79537617bb435f980d823b9a5276c535de11d5e557dc47e87ae8d9f031defd0b50340f03b7e2a83afa91d0fc1cf50c90b43d27f44bdaa5a000189c38eaf8da49426a4ffa9234a4c293134756468ca07049226bdf484213d0929c044b2837c23815979301511c66484d3bf176f7e5ebe2fdacd175f00a0c98fc0a2bee38342afc30d075b59c70b81d4c30e74bc8e9fa107422f442221da9080e10d8e9ab4470f2c32498c99809b2414c893f65002532922cfeb704668da3624eec7eedbc81a9319b683be8452b66ddfb4836ce3141ea53c8708e4c961d4733761028f6f7b70d45b48d892638f6f422e97dbe5fdda9239f71c75cd43f1a8ef7bb8e57e1059c24896be839e290440d3be4ff32ada23f65e458bc6442037e7111d4de6197bd4a191b80ec31e83c8126e6c5b13f8a3433c262756784205289ee2a410051829bec871d2f232050a54bceef20f3a15a72295fe298ea449131c49d452454e4a38078bfa36fdebd73f435c13d2ff11d5595670b9020b13b46c45800b020f98950753164c751ca045095b9030e9edc60516b5b834e9edd6f5a50b2c6ad169d22174887b31e990fb930ef9420b939dd76b1a607b7082e0542c7ddb5e4fa4518381457d1930fe150a2ce0bef8b6bb9972b95c6e8b3f4325363ad8c730b8789de015d06201055c2084496f97e94e0226bd316120032040f03b100001b9839cd5871807f8ba32ab0fd7800166f5e1c3c728c0ac3e7cdcdfc092ef117cdfc783e92e7dd7ac08bd8eafddda253f102275904d7b6e3206e0651060d21ef727edc1010fc03a98b407ed6186003ac08107aae4a1f281296748f130a5dc065d702844999587170c65561e4c4e4fbe04008c931434786aa202005660c2c292304ac460518b9f64d29b48b680935c78ef0a9f787f49280b8cb0b4c70b960a19e37388ecc98c2f6a591aa3bcd8b9e2c117435e08e9a20b860df4b001327ac013051543f63278f032661e1378700e5c4159b579baca75c9208e2f92d766cbd942c8227a89e24b61dbe777184227b62d4225414134202b57ba6c33780ca11270db1e04e79cb38b8b2a1ed8b66c2e80b69f349b8de632b80c93deb8089fd068b62da02869d9a0b04fa39800f4937f442fd697677f1b2a8b680f248a22ed471a592e5520bdc5c3469b06b703bddb34ddae45f8c496b3d5b1bde76c369b5ea2812dcb66bb34886f7bd0f3346df06aef42b1a8dd89de62b93a591c219958e4fbfb072c56a3a4ff6a4f533581c4fe88566541a7c848d119a1927e92d43a476a4d5ed140c753d6e4efff47f1694fee5f2534f18a7a6848d44286c4515369b286d9a6bdf83e277c12e455844a6c4f415ac88f30e3a86f3f6eb70c2825977ddb9ab68d1cc923ea555481426f4efbf13d37dee8ed8eef5ae1135b4e4ea884166a3092367401bb404155ea45290d45e13ef9e2f5aa28355256de462497a4280618e88fbde7280624197bad658ba3a537d90d58d441e0145a729c9c9c9cbcc891220aa73659fcf23eedcbf169ef71c4b7bd431136b13dd0fb132193fb406429fe1d45dbd32f36201a49f5a4962d0691650866680a2980a1e01f519ac2bfcdf657e4f183bebc3f8e8fe53eede953c8e43e8db4f4b6419a8d5ca2377faa27c5203d279051974c5378cdfdf141ba82ab30814c289ea02b986167cf2d33e6c4cc38b3bd6a1ac576ac1239e15fbfff24e7134e501642a57f4dfb23aaf5eb9cfe5a139acb6ddb7be909cb93cb2181c948ff9f044593414f67073d48b187f1a70924f652c6e4ef6d5f66193d2b7c42fba0f7dced9b087a5ad0c79e060681ceb583c8251b49f5e4ac3cc6a60d521c667448d08bef70c227b6bfef39254225e38f41fa6f33f0419a43993265eed5c1061b6c3873c30da288e6023321136ac6cc0e46f497f7c7f7a92951a4228243c8e4c301872a0c720899d81c724843448790c9a7830eb69f18e82fc51fdfcf887fdfcf844cc4bf67c471d4fab5961e86a04183468d901d422676871dd654404545358e3e50505555358e3f4c9026cdbd563cf0702f9b0a7a0899d01e7a18472028501332a16ad40431c19a35f7b6f13287cad187f089a537eac3bd42f0f82164f2fdf0c31043ac4226d6ca8a081e6c42261f1b3657780e29efdb3ee81d88f1fe483a102193f12f5952fd8f0fdaf4a437a533d96d64d02d02cba83e23b0a847285ab6f862c9b44521a86c5b0ca105549d3a51e2b58de338fe11b5e932b3c13ecebe3ea51a9f52854a66f9ed496fe3037ded6dfadb9e45e824e86d16db3b9df0c9f8f7923fef5ca1923044326a0d6afa672b7c329265d3c62254428ba25461d2a53d25ba24d58f7583b40adbc6eb57844f687fdfa1ac0895d8a272369d7f6821392750d43f86fe6a2134b1fb42f46602250a2263b3ab7d4ea8840807f2ecfcb2f736a193fc32d9d3ff2912ff87de32bdd1a769ae38277422922e4438e94df65345f864a4377f51fc2431f64e45a844f662e94f3bf6b117b587a1b7d8cbeee5210c251a3ff6e0a88dcce82df6a31ee92df64a3be4f1fdc717426f14a46f70cf3b156193fc32dac3141cb28c9c2274729fc67f9fec2d25b2bdec3f4a34be8c14955cc8a268d3a32e3f3558548249a81bcbfcea438e35366a33996c8a1c6459e3713cd0d33561520d1fc2241c4037344d2b544264e70944f62e878d959c5aad661526d5d8d890a24d8d20a400aa410ba24d98f4538b42092c6a9a11a2288a366ad0226ae39dc97ea6b1c84829806ad09e161126d920dd6051d37e863f479446964c47e019da6c3299ecfe07d97ecb7ef641bab43b68362b3359ca9ef6972c650ff4473568cf6a359bde5277ed3d8a3089efda03fd90658d567bf1a99b30a9464e0f428f08936c90d483c81ea44b9ca0ffdfdf8b08953469e910d93f39a904b03781654b76d7988c7f7f24cba67d65bf848865fcfb228e4be1d8c85fcdc6fd9ac652e3c51a35deb56ae020cb1a144e9854e388fec861028b1ae87f92a0ccca03882c99b2f00c83c8b26907fda8afae17cbf8e25f5dfe482ed54d0baa3d4d9776d36c5fcef668fb32efd1f6e5b747b2bc0ff42359de9ffd51a5e9b9ef961c615d7ba96e1b36fe88d2b6d46de35d4e98c4b78d9fdd204b1bfff3e203692c4b75db78f1691361920d727a109a1526fd90d38394b22dfb1a5a8a5009b8bf09e4098702cb6a5066e5e171b04c9751306d29f0336df1412a078b5aa6cb0fcb52ddf6c507a7c371257c029e8463f91b47c28f70376e8417e112f02b27c2877021bc8d07e140381bb7f21fdc075fe36abc07e7c1d3789553f90e8ec6cfb80e9e83e3e0536ec66f701bbc8cd7e034f80c2ee532780c0e834739191fe32f3894bbe02db8180fe32cf80aae823f790a0ec6bfb8937b7114bc8be79ab89c60420420f00026079440c2d208226cd1d200062c200b96520121240004045c3980010a60e503020cc0830e04c041152a53a4286d808b02e549009c68d004004c9628499284e408d23ecac0971069e8cf47cf1f8d3f7a2bb3e49d47a19809f404caa536ddb03e4613605e087521546bad5ffdf11eb1c501a72a2ab1eb8f65e0d9b556276d51158ac562b16a2f5519521328e3a9c848fec1da22e32a896db7c8a812b1acb5d60e596bed6d52fa6499859256237902eccd0ffdb166198528517daf6455d2213b165b78b2b0f8660b0f960f5e190c1fba7ecad9b5b329fd1bfd1f7436a3b731cb9154b20b38a90df7c9256439e350ead4dddd9f6813a5d4cb764e4095d6ce524b3b928e017eadb57af130a43535fbf76d6ca7355bb8e4b62593f8124c64e59ae8daf5bd62ed6eca9dfc7dadefbb7a18ecaaa9be9fe1941e13bed934ba60d30f9a187c4f6b49e8f625b6910d565a3f9d2b0f3a458c3cb9baa8b32797d6d6ae64c9446f7602f1fe66795273583a3cc32775894dddfb68bdf5de7a6fbd5feebb36b4d65a3d093b349b55b2d65ab1844ceadb492b1428c0d9980b0537d6dd2d16ff5abf4259426f5dadd5566babb5b51bca8091eb740112980f698dffadb4d25a69adb4d24be99d1f2477f749b93875ebbe6b20cde9d4adfb12f7ce28512cd65d1a9db6dddffb1d96119af6b55f7763f77ad7bbd7bbd7bb37d6dd6db3c8a9d93af6a4937baa7412a9593bf95c2cf5ab576f9522ab17d0fe149a57f6b612410241d0c9dba3bd076f68c17bbfeb9ffdee97c31dbe16b4969ca5f5ef8b3ddd31fb59b05aabbb3ab6c9b6ced85729b93c9b81c948dd0d91c03cd2a4434a7792552711a97e6d77124b7daf7a329d032f88045e59d5a575cffb3c295a9834f320746c9371d5aa73c0efa3f3b3144c46a23ec4c32496de9c40245a9d3a24308f6429988cf4d1211e840b753fe327bef75e2f32b717f17ebecc8bd49f5ec4bd48fdd9751d5942712a3c64fa1efbef63ffbd7d92e641ae7d0f671ee47ed5239b5cdfbbce7ef767f7c7fbd3fd2d9776d7e99269775dd9b43bb2d26e86dae5a0830eba137e301f52adb647bbe86dafa0bc517c09244cce3981ff5215426fd308259a46e86d7ed83a7d48fec9b02329615225acfc420f811741bad1a74f8f3c087da537ffe5699713cb8828c5a67ff425b7e92331420e0d819a0a9e6cc992c6de1b1f3ba84beb0e3edd6075fb75b52bc60358ebbdf72b4d0a9717d65bdde6fdb9bb7fda09bb7db7f5765dd7c51cc455bb95e1aadd6d67adbdb6d224407f10a449c12297b71f6edf7329f433fba149d9caf53df00b9d949245fe9e4a554eca7d5f98e4e99bedbebc7dd6ba757b3ff073b7650f0f4229f59b07a15ff50f2536745410a3a0a38296955dbf64dab5ded0897f758f02dfd3a7d40944725ab394b77d308f64bbcfc97ecd961a16064546fa94873446a9f75f69bdebb6d7c5a8254b9907f187d225cff62e78b63ff6ea41d8644a964db708d03ec552a0725964e7d32fa21e39290fea787b693faf64897f7ec6d26edf16e3254be86d2a4d232557c9884c7fbaa7bb234b2edbbebd151999db5a6b71a5e3ae2ba8d9a52dc2516ca7b3c299edff155122ff1eacd36395bea5a4634929914ba26b837a16f9eee3973dee79eb5d17f28c065139b36695080d3d8b6071090d99885fe5fd08dba73cdbe93ce1d9eeddd71a39e71a35665e6b90b3f2b815e3bff7696a5bb0279d14ecec20f0ec0bf6e402026b8317633c7d66919907f1bf99088dbf9fa711ddd69bd1598d7bef252b9217cea8f090bf1cc35be3ded0c925e77d905e7ae9a6b7e96a97f6b3086dfa35aa53d5767f310ed1e4729ada6ec12c923d880b29e2318bfc7810ff2e13a1d1f35eeaa8b1cb598f8cbca1128af5beff71d9352676fb3cdd3e64c9e5deefd17902b92fea9fd9f813c87d992e7df6fdec45f48f17f19941eeebd8f76379dff77687c52ee094c2264f3a29ccd9e5cd3798399bfe0f3a5fda6cfa427abec6a651f77932c731fc222631bd4d2f4c32ebd1be31d6f57d7c3e1ffc4714cf2851257d6aad1f4e278be4e18d0a0f7956c92917c83e5f2ed52e7452f3f7f43c987b724faef9e9ce3db5fa4cbc6bc54f8ed8b12e47f065325036e7bcb11bbb5dd775b687825a6872bbbced198562d333b94dc34c75ef1583310f6f586f4c8758bc172445f136df0b93a6485e12df9ff5ea5963b12fe6d7bf6277f72e468317acf1e6a56ad3ff21beed7e7efe99d55a3ff6cd72c4126aa1fb4734d44c645f49296172697769b76c09bd4d4aa99ea0c6d665e1d31d625916a12dfbb9699824bb7bbebdd3a8fb6262f28d5dbabf0e3be9484b6f3fd7e97881b3e9a0b035a9779474f75e7050691acdbdddddddba57b75ea953db33f70cb1bc6875a9da3df6e4cae5d9f4ad755ad6d9448949e7ac35a9754917f529cdb316327d72ca05f2a54e2869bdda5aa7d255ee4e6e8e57afd38b78916edbea45eccfb0b02d827d4a62b14f9f54b2caf45d4a982d454c16c1eef2dbeeb68a96ecbe23eb15f72c56a657b7a2256b74db4b2d598772d80acb83b7c2ee5021e60cfd3897106e663d58e657304c2acc696bd9be5463b2275972f1603b16ffb9adcd4b2a0af6e96b29743216fa554acede3e8b040abdcde954a099e26a5367cf2bf6e46ae3b4c19e2917c8fea4756b6b4cf6254b2ebbcc825de7fca1d02193e4e2d43d40f534ed68a1444e5c68f2ecfb592e94fafe6dae26b4b67da771e02643a957a0e82af4763db0426ff7a5b490bfb9e5c4c9234b4eecd3886eab24265b25169ccdb2d5b36bb5933327191298478a9d8167cfad0f7c6ddb9e5b1fd0da212059a51c23ed532d34eb926ef60d594ae4fe92b9a7d2d1d02d7fec2bb4ef58fee00de58501927383d958bfa8e8f63f8a8cc0296f3f868a8cd422ad293ee4496ff856df0805dc85c659a787b4e670817560ceaeaf41f5b8e4d45fe2734e29a4a8be91251ad436396442ff864dbcf726737af49d56249488864abc5caa37efb1ccb7135b2cee1f956227973f6af7439488cc56fb8cdeeaa88426dba7df5dd2edbcde8df1d5bfbd998d4375066e5a39bf767f724581edf27bdca4236b170bbdcd6bc9e95b4a05f2b89574c87476b3debd358eb55b66446dbde71658982d2b650f8a1ae81d6bc7ac37c10fdf31c9f897a461928c567bd003719db5f7f9dad39045e5b208653fa24c268a3799cf572732f169fc14458f92611b9f0d8d457cd0622f2830a2ec4465e1051565035b4a347e9068fb32d7e6118dddf19b405fffa3fda4b7abbffdd16836decebef6a113da5b7ab3617b227b9bcd5e599d9165d31e95047d61d2184452e518be3f32d9db9e8c2f937decffda46992cffdcc837681f7b1048033dd8899ef8c5409b2d0402ea11459f7b6bd8c03e8d621b149a05d16aa30d470eecd368c45b829e841cfb7e1e3c778babc506b6b23690e505c6939d9c5754571417515d515c44754571d1c50598d8444e64626b0c3c534becad3172e21b2f309eec60517a95556e738d716384ed813e106603fd05cbe5de3c2191c55607d4cc3c229cad0e9c01c34e16505d515c8851753697d5934b95a144378b1d7b9fa24498522eacac4de3ef831de481caf314b372050b03680ff4e0080ec0403ff340996db5e581a81d7b57136bb3630f32a0015ab6406004bb44022e01fb34b2fd7cd0a6a977a1a5e05eb0a544e2485f050c9ec0c291143240fad2548030b623623e68425243428e0e5ac035dbf801175fd4b830425301a0a852c8c0004d5fe40c3b5e2021c71ea1a9833135db28f456e48ce09190c383a6dc9c4784481674fc11b521315e32514ec1fdeb30c4e012c830e70f292326ed314311344860561e355c95c1444c7ab36188597ddc20849936b3f2980a62d21b130e404c7acbe1ca1131d81c212104e1080925e870e508174876581d510284235d0e0811a04497339d21c00748ff4df3870784563ec83d00026808d084e4c3075c58f92002e1075c98b0c3102a21f7abae6c31c2c2c2bae644b2a3871d20cc79801084fdd51422e0cd57ae0069ae6c2ec2c2c2b0e644b283871d3fc3a403ccb0038424400873cee93dcc39a7e7e038cc39e7f4a839e774167c8539a90bb4052a8686a12cd015a80af489a640c15028f7329c0cc7e31bf0315c03fee56278061c037ec72fe016a03088b1bfb55a2181015acfdeee8b8138ec0963b9f3f168d4f8b10174631644ab8db21ddebd210801f898deee7dcca3878f087e682038240012265d09c2a4506fe0c5dc5e900c4cf10d5de0ce894d70e75221a3a08b21097c801574652c848b20407a8443bcbe2c44a22d80f8b8f510b140be1f0b43720328f2cd9e5784d322cbfefe871abfa7655a04d92f79df833ebc98f781a43f8f3049f89db765de77e1771f7aa40c244308c2279d4f98a97091c3f7f07eb5f049f7b2072d3082635444890f1431320123172491e7020cb030c8e08d07323842e2084fbbb1a70444f62390ca69272437e8402e73a63fb38db1d8f673d5ac21c63ef6f641d9dffb312d42ec972e7eb0bb21f6fe73d0dbb1fba0ae35e93cefe767c91dc02954d6af5da31c91cb09c694732472e94f4f50f44d2e5d4a6aaa62e5d2abaaac6c12b9f4ab2bac3b815c7a569656a7442e7d6babcb83934bf7f2f2af6f895c3a9883e5624ce4923e3d41c99ac82595929a02b37249abaaacb013b9a4575758e113b9a459595a2214b9a45b5b5d3d717249bdbc7214b9a460142ce723452eebd313140d39b9ac52525335b47259abaaac7ea6c865bdbac2b241452e6b561610b63a4a15b9ac5b7babd62eecd58b12d5ea55ef50a219c5ae2f38edfa48c0203a794f2034ae2858e4259587ed521c9ee788cd075d8793eca93a7ca8508dbac30604372208a2b71a0f9bf7c8e143cf1f3a80ec70092208c2630ef9a81300a11404a91384497432dd1560aba31091f70452f7e482aab341220f95d48460aba300917d88557690085b1d654d2e671d0f96489845389841acd01a2e27168e2a13c811952c88541561aba3506523a31d72595464c48222458a9cc9e5d09090092a306244875cde6e3f78f8b03a4a0eb9fc2d448990e859644f1dd3e8c80452bfbe934754ee5c807784f9872a638021083fbc43a619e008c269a5a039c25647a99343bbb1d5518edcc2a4a309a43e075f8e60ab7175327d1009b61a9745a60f2661ab7174327d3009b61ac795e9834ab0d5b8ad4c1f5c82adc66191e9834cb0d5b82b327d1000d86a9c15993ed8045b8d9b93e9831a60ab715564faa0136c358e8a4c1f0c00b61a3745a60f3ec156e3b4327d100ab61a2727d307a360ab715264fa200e5b8d8b22d30737c056e3e264faa012b61a0745a60f4ac156e39ec8f4c129d86a9c13993e48055b8dcbcaf4c12ad86a5c13993ec801b61ac744a60f0a005b8d5b22d3073bc056e33cc056e394c8f4c10160ab7113c8f4410260ab714964fae007d86a1c56a60f5ac156e3de64fa6001b0d53824327dd000d86adc11993e78006c35ce4da60f5ec156e38cc8f4410460ab714564fa2008d86a9c04327d3001d86adc55a60f8680adc61191e9830ac056e34a6c354e884c1fc482adc6b5c9f4c12cd86a5c10993eb8006c350e884c1f6400b61ac726d3071b80adc65965faa0166c35ee874c1fdc82adc6f990e9832260ab716b327d70046c354e4da60f2e61ab713d64fa2009d86a1c0f993e5802b61a9726d3071d80adc65565fa2013b61a4795e9830fc056e376c8f4410860ab7168327d3002d86adc994c1f34015b8dd321d3074fc056e372c8f4412ed86a5cd354ce4c971b50b0c14b19a71abed000668614a49e64502186156060212a0c1931635a78c1052828175e68618c183261a258806185185490e1492a8519b0d53830995a8dfb92a9d538a74cadc679c9d46a1c0a995a8deb92a9d5b8dc54180e67e4f0011df29cf1009a0eec600615581507d294c103193de051b3813563f8a0811fbeacc4609301203010c49d361710c20243548008afab3024408122c030c28e9b2f8ef002892ede74617191c41613d0024e551870b0d551b6b27d4b85024c204913261d81c104b63aca15d9fa20258726acf8c1ea2873b2b572e20b3656e3bc00020a3741c431a24d1445082185048690734584d610530841459b2a8230c20a336eac60734468b1980a939c0a972381c50f6fb67ce05293049d1e26105aaba3f090a9d551d2c009ed16fe8e264c3a42a243f6b73a0a9a4cad8e8243a60fceac35b9470c3dcb79f0baeb59b652a7f22ea68789dd27c9318d3af2d6af2119402b72691fd31fdae4ae51120074d020b1271d3465b6176ad0f454979e08dd2fd1df32c376ecc11b96b0c5db58e84f0d669bdaffaab73bbd6586edae76a412a0a5444e058b8ca97c914908da4b4164e90ff830d1b539a4f2fe7a3f7b864986badddd6b1d6b9799a81c9a6121c9d4abae5279d08762cbc9852c0a156797b905385c2db899964a0bb9cc1edcaa4443f62abd744e52152973ce99dc94b5cf42ce66f097cb5991553263bf1093fe556442966462c14cce397f5be34f158fa9f2a0bff53d5325f24379d08e2cbf4b82816d5ac9cc82993cd50571dbdd5309f3d4ffa8f2e8a6b2ef2f167a75fac7ae0e6549aa1ed0a17a5e687b24d6e8512247d39be46f6fd70fa19639e3e56ae8aea44385f1370e851552cf4a09153179466ff4876ea6ed55a90cce326d441fe925e3a6023f52044bce66b3d9c6b35188de2af954c4e42fad0a4c219860e50abd635f06ad092605570c739cc9d21f8b6fc8d493d85d64e50a25b2afa401147af39db4444a13df97f36c7697541ef4ef4db23683cfee25f436a357ac48690205a7294eee947e0d006bf7e5d9df86acddc2b46fc965fb166fdf72a96e251be80a25fd12ecc6f238976037162157ce17169e3378e2ecc9b5c2d62eb227d70a356c7b37fd3b16ecc9a582179b8b853c7b72b15087823db954b0da61b2c2608989da540c7d073b27a9eedb7a2fd57d1a0a20d7a00964022103aca33b570a75f6e4025367973936e5026375fdfad5b5e6294e546d29d5347270139167dff6e41ae26b5b2e15a4f6f7344cfabaea3d8d832bf2eeea7b64fd1263a9dfbd935a3b72296f9aebb2e987754abaa736a6c16d7fe8cdcaf68cd5aefb5a13ba94778cace572bb69df5fca5f1581c97dfa4d6c2e37b31900897cf467466b13efcb9f4924e6f3f3fde472fb8bf9607afbc8a5bcbd6742735db647d69ad0db2de51a45f71e1630fcb223a9ecfb6474ee4f168bd1c7e27d0782e42c47688ae9cf9ee9a916044b0fc4a1d893dffabcb59fc9b26efb3d6469cbbbed8764d995deb60f7adfbdd7fd11f55a13fffb35d6fd3bb5f5afb5d6da1ebf2f80b3d65a67b8d63a3598fae696b47fdd3ab56ead15aad38b00dbfe154b7df2b364f89c8d6367d069214e0b511bd31173a6c749ab446f13fbe40233b57feca744f3e96d4bddb58917f6f3bd6b7fbb9c60b34964c9149ab73a5464c4be065528918965df4a085ae81225aadfe349c422d9ff994473dbaead446f93d20ea8acc80ea8ac9aacd33276be38593c4e70a2ee759fd39dcecc298565a2ee3398406fb72aed49a79e378f532efd69fb157af3da7ace39a54b9e82422e5d6afbc7d1c2125274fb312a9d913dea7e8125b8972a1377c74e4ef192cbb1c9fd0a38c54b2e85f6945243a664f9337d3a387307b461f973029c149c94ab0529ae16a0a69491fd7be84465d1895282ab851c9798ae5d7e5c62aae012e3044986feb8c47089c1da3f1c00a2f3e5ccbd56cebd370337de77d63fbf9dfeb05fcfefbdf78be27f84111e39c41b7f7a8237dddacd90c16aff4e2ca40ffb673fb2a376e68401129847f2eb555bab3f0d4594302ae2a24584e8845a6d572da8b676b5d6198668094102f3b456a0c404b5d65a6badb5565bbb5a8728a594567a295da2d65a2938412b0852adb5d66a25a8b556fbf56dadb5d65a6bad407ef8e8c1e31601045057ece0027585900e527f0e1cb6b1460b9af90d24308f148f84defcc36cfad58d67a9a93694d9f42b257b2625ba7b96f6297d3438feabbdcdffb928f379bbbf18ceecc905c3995de228b00dcef9f3952811ed3da044b6cfe34fafdc81a5d09eb73de4f910c98830fea9f163e3817ebe0694e8c64f1c5ffbf1c530695cbadbc71a7966fb4f95a9e1f8f171fc4866b9edf16b6ffb304cb2e120b3dc76b6e5dacfb04926c75cfbfcb4c76112ad462e519a48d3f967d8442427bd3dd972e2f12acac31f14ffc68361d28d7c03dfd0e2cfb00926f33081f8815e1626012df99601c98034fe1936919178beb2c8444c66c11bbfec6d7c2c4cb2219259f0f6b1e163a3890f89492b3eb22f4cfa91914b767b3fde8ff651f27cdefb1aef854935ac777dde7b9ff7c82c3fdbebc2a4cf87ccf2b3bbfbd39bf2f077f41ae9f9fbd427fb944b76d320e90d6b28fcd1eeae8bc5625b9876096e8f5caa1b874966585858d813cfe5dee6221358d895dca03d0d6140fb242537b6fd7a631d50b32797196aaa1425f2bce88d8b863a60b5b7f3be98ac07cf79c19a12beed46d694309b444bb38dc1a6b375752f9687f7411a787a11ea65cf07cb80c9e58502cb03769d6c97b54343fd294eb9b47776fd395b5971dc6059d936f68cadaab6ccae36ccaeb9ed8407cceb4eadb36bd5da73e0d42c2928e4b2c2d9d5c90a87deea5553db9ca1b7aa5dcb7a66d7af5265dcbdebea5495a244ae661aad99453c2764a03250a85dda5dde3665adfb925e9627912dbdd1496f240d2b97454513ab863844758a12959ed79e5c35b4d97557cf0e58c35753d59ea69f3ea41a098ef8411b9e61e713a321abf10302dd9805bd102542fb1f4345da0892255094b4075642c8426ffe34f41253ce9db487f13bbbbc58b70dbdcd904bbaf5553c94c88b436f601403dad7f7ec4825a1dbb3e32597552aceae5f7a55ecfa73533d3d12ed4bcfceaeefcd99446855f5aaf0eaecfa5e1c4a14839202bfa627964fce2106a79def4ec633cbe34e370f33e451ef200ec5efc93e4fb72a59ceada24c96536ba8872c67d6edc9b2686b680b24ebd3f4bda23cead3aa4ae4263179542d22767562d7bff5832ed604523fa66f1b7aab5f05895c52a8cf69fb7bb58b12957e237c72c9da053585c37604a6361c3de40103039bbdc9a58381d11cd8e77093e379b0d3d5d51564442ebdabcbabab7b50e334f97e59ed746495226e1b4d56c5c9cacaa24920979e95a545eaa06a63656545bbcaa55b595d59ed102222972e2535e555423b767027cf79ce7343e4d2739ecbed80004d9610bcbc84c8e5f40ae1cb0b8208ce2841a1b7fa5a53ab4d2ea71694b915c14d07a1ffaf0591cbff1b4d571b767d304348734e505633bb7e9d610e71b24a4d20b5ee293964af7fb5a6d1dcf5af1b4a04df3694e8eac6f982c24b560122971f4d839921adf1ef11263959854d2e6f9b7ddb7810dae8c3265af2c3ba41850c013a943f790eeccb6bcfaeada955b467fd26a4f9b50bab5ed13251356b4fbab5d8b3c6d9b34651a5d855ce9c6a45bd6273edf965a5b36759b5b298587891b9cb4a859a3dcfcc20a557b1fd3f2cb6bfb7b5fdbb2bb6ffb562fbdb29b67fa562fb53ad55ed50a2e9f505f6219537f7b4eb9dfa55c1724f505253555616a9b457130b2b0ba9b45a7be6ecd69eb62bcc8ddaf39b3cefac488395e6aa4a2b4c1aa74d691a3c4bb63c48736753fae199142d7239b13a2146e86dc8df88f52e74628b8484fc8fa1395df8ce88b327d707e2ec72c88cdc96e2424acace7e1ad5796d19dab5619293227cdbbb5dacdc0f1c7239646dec28e675f7eea22121462a133bc5896ca964e44879785125c36dadd60c1728c54b76cfb27d5bb23461d7d9ce76de90cb71a4434675532f70d2211144e8defb89652f93ddeb1f7b1074dfb719bc36de422a0f96e536587197db5d6e839dcd6dd0c31dcd6d3016f3c4eeabbedb6ad0e23a521e949412e5b4e63e7ecf846bb5b086fe62ac91407bf1d34d854913b820ed294465b4ab620a0ed7949b3da566cfa91da6ca906498f9e232d33515866b2a07872b0a0b3261cccc996301d7183864cadcc1f2b4e8f410a78726e6a4d3c3105b8cc9e335c60e79862bca8b2bcace6c5bff7e56ab143885ca4fcba1a0a468579757cde59eac16d5ba5f5f601d165696d7d5e5f559595dc5b4b4b66453535520d6c5ba59505052565657a297cb3df54c4d55e52fefcb03f3818292fabeafca0638eb82f097fb72dfd3b64f69b11aeeea1a33904b4fcbd3f2b6b6fd6bc3402e3d2c0fcbcbdaf63b1c9e9567e55d6dfb5e8e9ef7a03c284f6adb8f691ae4d7978eaeabebc2429d56a7d56d6dfbe18e0eabc3eab2b67d11825904dd5437d5556dfbf956e3d1e5ba9c7d1a3dbebeecd7f071bb6ed7f5daf67f7e5cadab65df06102dc1b5ba56f76adbbf114468e8425d28fb4113dcdccddda76d9f46c1d717d8b65fabc076d92eebb5ed8f427a0cb15816cb666dfb38888010b15376ea8b2c9485b252dbbeb6c0e66cce3e69f4f5655f47910a8c602dadad6d7fc705441854ab6a55afb6fd0832a85353f66ff508ca3e8fdd03c9c811dcd5f503490649186b5b9ab5ed4b90e44e2ea9955590aa844e4d0d2da150db4ec0240900f8ebab82264b34c05a5a439c5820978e8545540350815cba951591273e355504250051f0d5382f231cbefa6b436ff6a38449be01be1a178691a9e475c16725250c0ca65cbd0046815c7f8654c038aa55ec6c0e2ef05d7d5848e167050a00df0ef0fdacb6fd2febbba244e597f5c5f9acc694d9f6bf369f1bb7953e11636fe90c5fea9f169031e014a2b1271d1ebab6a77162e432e799ffdfe8d05051c53acab25a50b66e9795e9d5cd2f2d33a6815cbae79e6463e4d2a1a05c0af4a929afc26e657515e2c9a563618122f634ee03b9f42e0f631299bd7dff62d6a86ddf92b6be3083b818db92f1a22793e15f3efee5603e65e468e47234380055c34249d5009bfaa153553f6658d9c85615eaca4607b0803e2c8a05e4811b566b6bdb076de499cd234a450399d22e2fa00de4927ed12ff006f634ee2bd72a5579d82febd3b60fd2bcb006de0d58c8f5411cb6e6e8e87f5a46621da250ae3b6850087e3c02a0795b81870a3d9e7ca4f0030c902f123805f13284c2041474a9007b7a839c902161b9be30818044d8d3b8337259a16e9846e1dbaf364ca31b6fbf969946406fbfd6308d6cbcfd4ac334fa79fb75866954631ad178fb558669e4f3f66b0cd328bffd0ac334ea79fb356a1a896fbf92a963ea0bd3087cfb156a1a99f1724fd823de1043a010dbc0e00f28ab218bd1887d3e9f97bdaea7bbe20d2d8dc56cac8631b2ace190b0498e0d92327d65df11b98d918b7a580b7e1849408b0cb9110ae61582015106454746db081206f5c8119d6c9124d59044c91226006852460327017802250a6e831a94a44ca142439519381040071e0c80001f58912a80010e70050120242084310a28b148655900031aa0658b08238c5922a1042907303d00021130e1042e4db92e28788972fa024686149e5458810c0b616210d3021917a05e1843260a861864909a8186a81acad820c30d66a6702093830e319c41436607aaaa343cf4a0668d0f3f445949b101228836420c1145c495046428c20837479041e24d145612314c204a09384b30d144161927a29e9082224e145244c9d1929a828a2ae6587145141658c8b0c545270ba93a5a446dc1450c5d5d7841e60b3b5260c4400118c2f0aa8005a22e40e60e063220c69706c6d8001e32cae0c01830333ae0813c1f38c3c3725d50f0e2f4054c0a4f2aacc04218312db800f5c2183251304449cd4069a8c196b181de60c64ee190c3a7c31934358adeecbb186152859a40ec53d140cedbbfac50675e40833dbd0154ae9edec0855c3dbd410bb97a7a0331b97a7a8330b95e2d7b272364f21bd332a113d977d7be6b55294a54bad69c0a1567dbaf51b696f10ab89787e1147030dc8e7fe15e7817dee55cf816ae85d7f12c9c8e73f99663e157b8153ec7ab702a7c0ad772392e8547e1711c0a7fc29df02c6fc299f0251cce0ca2d7a8248bdba8821c3234230000000004008316002020140c08c562519444619e15db011480117c8a4258489fca03d22086511cc4514c2144002140006004464846e30031c958d09429e149380e9a18cd10b66149860fc81709b6fcb3106ff15d15e8809fb4d3b65810b5e72ae8614ca4e35351362580f4271baa4cdb6118e0d88bf99deb30094bfaea69e1fdb4bd0cfa20bdf0668e64302cefaa268d013a155fe8ca8038fa98459b9b136e5816351d546fe02a1a33c223907753f849294138fd03f7a97a92e633c4b1fc57619ffd2a843f1bd8d72ef8014cd705afc876838e73a35ae1defc600950e14a7b162d5e77577a919edfdda6e175953f43fa8541e6708029a6b9fd7417693b483792ea893b5acb712be59d948558a39e0d2ba59b65fb3e951239232b54010b60a88d3f3e278835ea536b770033bf530ab62762e8cc64f199101369723cf1c423a61001c2691e5c2b23522bb64f8852d5dbb513c5b3bfcfe9eab2c7719df6598e3d5facbac5cbe8f144130088868ace706fbec9a15de7694ee48f45b626dfb952279b1930359d5f32ca664b45c04d3a05e6dcf83632992740734ab80a2090546a5d6de830ca8104c1f6e1a4b32668848ac09edb4a96dbfc56d1fc24239fa40ee68b4efc133ec485230de8021699de9120bce4c91161295bdc2bb71a12f50c2fc2e83b1de8403d5d907046d201823379b82d75e6b844d7135e989df130937785c0d01ffacd4e12251c2a0ceafd16f07bfeab933faf8eb857795af9b9006c27cc255fb3cfb7e49cf85d8d6d35ffa0fc74f2e4f0d3b590e0c016c0123cf6ac7075e3ebc94cf6a0e737c85213b9f04a181287b6040060d074238c0925c634e6dce05f36176a041b0ab6041ca4cab69cf16928c09482bf995429abfdf58584f5c53ce5c335ce0581f0c8fd5d885ec559df77a639489bf5c3a8d5de45257527aed497d03275c517af187c53b86fb10442099ed8c01e42be1df4099489d08e89b92864db9952c165a1035cb834039301ed50db574d2d8601aedf672ab89459709c678eaadfa452f6f765ac56ab196f426bdfa3730ec4896d166d303ea04bcf32802fc9ddbe3941d3ab49b44295f1c7a92c75e99f2207d38b2b980c1c80fd0eebad869ace5d36ffd9ea235a141130c9da20b68b791b0f79a9eb2c27d392d4801fcc1decde51d1417a51ab07544fa1ef17e1ea471e268a09139ca475ddea0f7f10c2f4dcfe2a7ce79b25622349019414d877853781c7da18d10a3cfabae15a8f4145a50ed8ebf57efa4fd23b26d6bbc43723108c24f8dac105faf0f03e8f553b53ceb707bdae112c5410d9c41b27f6037a5d0ccf28274c4c47ab04f23781044e08f0c454a157e8a3f44e145cb15c0ed715301f59173d99acf5159ab6f6d088ad0e673d466cc56805105bd1807d145db5ff5d97f3a7d49c21d0e53284bd73402ba57510f5407af35946e63887a4c6e8276d300ebdf969aff306d66c3b867b8215725576458b1b84a80b9ae6d643e92411f04992df9cb16bcc45811b963982156de46e7e61425cbe904554ec19471d7757ccfc2c4bc8d14c5c1d8ffa06624d8e70ce40bfd524ab8158f4b8584454cbeda62621c5598870ca2f5bdf5da726c35262deb2ea38b3424dbed0af2d3063bdf5a349ca11a593853fedd36d6dac9cf3f3d6ffac22bab3b46562eeeef9388859a9e12eaa62c64a01fd3b43123c7f34e3e3548c7c4bb14e0aa2fe8a9a4896c90420152896a4e2bac528f22b0dac9a07d0c6d23bf3c8499f4f11045f747e0dece08ce9231eb0012e3273eb7274cf6a6fae44cf951e4040e3eac08de3e680f0f0368cf8008b98e1256cd52c16ca3d024e9880aac39c7bed0fa891e6779df0e7610c4316eea493de8ab0e6a539ff5e8fdd016a8ccac2e61509f450d7f5583d6b02a44316d4fb20e8d9d2dea203b6468d42f9382bddee0274332776550db14b232563a47e9b664933393f666fd1d071cb0ed3640f2a8458b7a376a9848173d177de607fafc743acec9dd26b774f660f3f45024cae6242949c4e498b07cc7317c971cc0eb4bb9dba941274cdc8dcf45ecab42820cf9d108e34761d8112af4f73919430ef33691725229d1e2799dae3b674aeb39ae6dcfe48c673296fc1403cef48bcc7b06bc4178fe64e810f604a5a5800debb929e64ed1a81a02a0db88ed30d9c6e576024057fa4642dac75f5876dc95496b799da4a83ba4721d0b91e3a354691e2e9cab7b87f24ef269bdb2c88f63355698bd69fb911494bb611a73596629bddf36890a90b485f3f0e8c55be05fe242fb7e704abfd61e9bfd23745e1e6ee87e6a6490ee3d39d3e34d786d55ff7e7c2b3d80ec63b741edc324fde0dc6bc3d60bd1c8e9c443827326276c1ec47550dad3fcb0cb46ecb489d51d80cdf9583e204b8ce3516aa7eda3bc4b78b76d0b64ac54d12ceea7a820c2464fd21e3cdaf15c5e6ada52b67746b928c04a3b28fa147ecc3cb545a697ae6c6e9279112142335a011b3256f40ec41913472e2a04e41a73dd3e61a3678fe9501cd8e570a73100b15927a65a51a7faf7f910cc91175aceae154c7de9c88860653115342f5d1393bd0b5a46b111b7023ab206ac4f4a72d3af287018d10e0c53610edbc9c05f3b19c452e6d5027a2919a48338bdb417d98cf30f0ae301a7203b77ad0c6eb2fdb148cb45917ce765ae9913784f30a2dae51ccdb68395fb70456747e436d1600047bb6bc8cddb69382c82e5568f6ef38e98636cb0245de35f9981d24d7ea562249d84039b42bcdde774934a9266d220b8a5586caf07a514abc8b16cc2f15cd9fa0fb28a5c4a5e05d47465b944a0fcbf920ccbb3010a3ff213526547c334367d6e6482dde56c0fac6a88709287cb9cec80afa86a8164c68f55fb19f4be3ed65ae432d86d2586f290afbdc70f54c5aaf04df79300761afe1d8a6156eb19e1265ff6a990a54304dae285b2f0235fa163763a2329e37843f3259106bd738c4e233ad6e20204144de83cd3358bedcf4738537ca5a4a69e0da203720197bdcdf71fd48c1cf3031219e1f054e6f9d9370ce9fa19af1d4b3e3e9d88d1524a9269a49788a0709f98168c7e66d24bc9b28f67f06279f717a85554d289acfc512d7dd2a66ae78cc7f3d39e2e99af82c5aa688ebcf2763419b77055c64c779fe7a9a40d6d3267479ed9b726f4cf92103284b25f595d88abb47094458b697d410fc441e5975c87816fe527af711c8f7ce32b1202c8b1402ed9c59f9479cbb5eeab268a77dce7c7a539a6bb537787cc6e3d538be72dd1f41e9fc3a1858c45fbc47d79c212adcfcddeb00a6b5fd462c309a2077ccf1dce75a3ad775e89c1e3609981d0c37e8d7b55b7742308317c018a2030186c879485950741cc1ae5786bf44c87cad0437d02db4c19e88615b85f0efebc4f9c2db268e92fe82ef84ee277dc8dee644703bc41a79bd7b8a2f758ebb02ed665475c3c6f12f68252b74242441cdb7bcef12c4cb21ce92e39f37b8dc8d86d7a570d86c3fd4c2f76b5edfb2d84fef641533e9e05ceb1960f6882997309a9bf5955ff17881fa42e102836bdb395f41e46fa668b67305a844f14dfc0562996b248075bee4a7f29cedf2a912a7d87e9c37f99a51eee696c4d3d1757039935d867519bdc41d97cb2b498d50150b802303bf8b0ef1cf51ab081aab88277b93b402a710c30cd4073384608110d19128348a205036f59acd0a586b086b179af7646470549b8b1100cd48b31dff9b8a1c65178d431d05a74b8a7e610202ce31cecb004ebf56e027690a91a67af95ca4cffa670c506d80b785933b28811c34eeceb8e7eb93034677c1b7a5a341bebcbdaebff080c0b5daa2a9e81fb608c4fe2bdb74685f6326e4568416dfc1949233127f6e83dbc4ab62eb5415d1135c1f6592513123d51e338565006f11c30bb3180507ca0930edfd183288d887e85701853c9e6fa24201671788459b96eaba1823d0bacf4ab44b4f16fbbf889ca0f4c800ed3a9274c12ff0406efc40348544ebca6c070e613ddf5467a0d4ec464cfcf659bbe1d84119ecd5a3b10738686c1560f5c3754fd0568e5c5c698d36e8c7c808c7bae5fec0f3c5bb4981b842f53cba0014c4febc41522feb1f0c811ca83f17a8b540331b6ba4e1408c291dc53412d9579fa03e2361229fe49829bd09d727014e573e41411f11e01eaaa087ee49a07bd3162d40d028214a91674913518446baf5aeb67ccb67e426e4c47746093a014ad1aafc37508722f7ad3e7c213c870c13fe6cd114d4b2f0fb629a00eccffbb91e6da06c54eed86bb979f7b2e93804358fac34d23ddfd7df0138a4d56f6c26385364129ae00f84d105b2d25f309784808b4a738e974c5b298cd568b7854aa3982e99a6d24cabd12a039526a99482a652c8cc75940e8459e43bb13a78402087fb0ce0531a385ff3dc482c26be647c0df87ec924456ac8770fc60c27ea716abd12d7daaecec5fecd7d55e2e236d4d425c96aa4ff73063288720af97b79510e4271fd9b351d2890052923447e91c51f960ae2b13a2de2eb4c27dfadca345a6b01ef9742981f2555e7a99f2403689ac25464c521cfde306a36c49f67bf955b54260309432e5a57c27c940238f34212a48923de5ec903682dedf387e04c26c18606f73360a6404dc6d9645d16b905e8c7312beac50c216b479c3d12ae505561f39e41333866d9a3b52178da6dce9086adf3d44f9201344d612ab24212288e2f90c10d8df0f2571470ef2a6f6fd138d87ce608b6e229c10313b60658e3e91222ea6fd01af0543584ac1d2d2bd81587e12ed239f7f7443246d3b4e74d7c0e7750b22112cdc23caf75425aae37f20ba5ee4bc015bf37f69743f820322a575698f38724cd01116655cd50ec2ee1ea41838a6c71e2e69b2b292d0f11e08ffad1066e2db09966e3fb7e5bd521b0416c0d45f6ceb708896251296273993ce20c214a729d59970014273f5dcabb122f2565660e31c8aa2f1f219e64338647cdde4531ba10a99687b8d9ed1367c806f1042f7e51cb699af5a599137e549ac07550abdd3213986be70400af24258b92afc4dedca6fe43418c1989a9e300cd6933e3c44518f2a43c132a842bf0877d6f44e1afdefd63abfaeda904f3316b6f15fe5f90458eb46a71b043653d95e7bbb6606e38ade3dfcb400096bdf4cd0cb10c9c279ddd83f257b696ed1ae2459945aef06bf4127a662bb150b6deb84433e489727fbcc9e9592f45a436b31d0ab0e0f769b470f249ca03c75b88b8d130c74363f8789c75ee88f78cef9ea4f39c79755ba8eb08f6f298a49b371aeb862e0c00958188c7c2c210bcad4915b990af6496b3555759cc5e81b7f3f45df7fc84a92f26cbb7ad6a86dbe11ee4e0a3db6be3ee999e22144aa14fc8f3290d717bd73e57ce2b918f4cd4181538b4abbe5f9acda9f0616bb8ad2b41fe4066b91e001c50b9a8e57db50716464698b5213895261afff76be308536944e6f3fe2d1c75acccc96f0233093f440c759dc543072a5b5a0ed82e8b30bb061433aadfb5ec7dc063afa51906d0c7e4a3d1a79c0842bc77a1e50336b60b7ad541da43a5e2d94b70a8dfc0a9575a63abc9fd221f0f1815f1bd8ba043899e366633877bbf1a038fb2d7a7cd74e8b8842fe165a97f50fba5f2698a8b0b70575998affd80ec42f30213a1b4f4e66b72c7658f4f831f517c7d6dd8ade7f7704766ba0fdc6ef1e14a9e7ab927fa201716cd0219b276ad6cd08fce0a777d6dc1dd638d97cc2f5cf9426f4c7c0940e255b33721bfa0db133e2f389c126162d5262fe15fc137b2ce0bfb03827e9721efdedf9d3270695ea55d43d60e78a75955419d070250860018cbb479d2711a7dc0110194c482d7df240b60c6eb6050ba78c5d53fbba5a5acdc232c5514ac1bdcc954c682696aa297901dfe52f9a4fe43eb1e8506ab2e65f5ba71bd86765021c29a5a8df6e5b80ccababdfd46f51149e2d6407200fbfefe3f5f0f263a56a8d169e8c92fdf615a00a2699180dfc78f8d1d0b1081c358b6dbe9f52eee2e3dba4790c40b754f09a1869b727d811227c4b08d0abf0d3c5655ffb1506c5056fa420ab4299625af1139dc8b6551f9d8c3727d4903075bbcace24ea8b9165d237598a4af222a81435d3c8b928fb1b81b9c4158a3fa27d23851fabbc570a2bee0a7fd8db75a0912ceec36aa95cf511e472078af389ee125e23868c7b6565515007cf0ef6d54152776d96da1d0176b9511e001bda766515110bb521d001e90e3f9f900039e1d9605d4c312c03d5002a84324807ea0076580d50f54e1d28841dc55289768b94663a1b50e5a34c9ea480b1bc33490d8985ad5911871a8b3d32c8969c29ad9a2c465d50026f6d9d2a3e7710d039e238da646a2ffd59c0e83358bc4f87bfebca8f0fc3559e6e64f229abf68cf993f98975cfe0abdf2b709dc4195bff9048bbfc0c5a6913113aa5efad438a1e3b72a58847103bbc4bf39bd8f970b6b320687b9b158f5f4342f7c8f18c2dc196f63b8dc97e60d1799f67071d5914c909f8d81b7750e8e1633f05baad9c49001ad2b8709ae1abdcc7d91244356a4416aa61545e2559afab74037d718c959acb87341ef313552e3d9dcd910473b04d188f57d8ccb21b2bb21f7d3487ed2183163ecd023b25ec167ec668a6d0f74c801255d003f24b901ea15400743617efab095b3347093e056d2207eae98c1a098377d64f528833345770f460705cdbcf5512bb7d4c2e5e6b01c90c432e55f667e345db979c1d7a9d415f7f745e2e188ba314ecc224df4e65763781506f0362211ee84b39083639ce2df0640a5a8748e2eb3a499534436b00330bb1921493d431b5318d5540adafcdf5311433b9b997c117c642fa0ae64a3ef96477c296923821509d5af589da1ee98d9a14e6d4acc0dc9c04d1af23c3dd80d49e02e0de93c3de0c64a06e249d02d2b29548e9791108a356ebbc09dac1e7b1f52df987e3cae0fc84d33254374cf27eac79a95c5e81d7f6c578f1bb8570f62d321f3ea7dc8be00ee03eb29c97e6d3e7575c75c80fbaa53be5980e5cc79a6097d12f06bf389e5d66b23c75825e3983e2961847bff653708c0da6434a0071de5b6bf8599a99f2c2d9785c5e1c41753dfa62ab742f28fb853144def7f3e798bba26430f2d58d6f0041f39100d3bb15fe2bbc4d908caad20cab07fa60697dc712a751c00256e4e5bc325c79842e4ec241514174094f1b65c0d269deb54ea56004ad8bfb6864b8e31957a5c80a2f4c7d6a0c804c9ef4ef8016ef2212369cf46288176f81a7dae469f82c16edbe8c655cf0f867278f3b7955e5a1db074d3e1be7e815a94213987d3a748dbc4c9a2537502321ab67e0716c4b339d590fc909f2c4668c507ee45cfd1ddd01a26284f58b8e1740ccac1a3c1984ce99f7018d81c3877979d17e7d2b1f3c83f3a063cf8d73e8b07cfd567e413a804c76cd5b139579c4557174d2dde99ae8986804321550a0da9d0fd534522bea7f1d7eaa57e1c3ecc0303706155c85ae8883cf426f86e8a08a37e7aa5cc7fbf1af6f9d4953e233cd365b9dc8b6df50e2b3a7fcd481dba2726efe05afe2d30b0110d8824015ead8383810c0e32e775d875668c894224f7eeac65a2b8c87b6d3b7310405675cfcb221e83206b14cfe7f5b07901dfd1afba40645a2bbfd78d7e90c082d43f2e6ac58f4d0f0946b629a89fa37fa022ca0ac8f23334ee148e5b16adaf7aeb90e9f20ffe1284ca6f42a754df22c0ee44182644860e694afa38c779c7440a90d0081bc128bfb8c32dd608794210868faa5cae575d86b6a2cc2041b519a2439d01b4f819cae6d0b06bfb7a53641105b8f48aa150eb7dcf790a59c14002c885aa99cd0ce77a13c3309119f0a8dd92e73dce3b1b1190da842f80ed61d1ff30499340653443f17611573c1d8d53ae2681e7c8eddabe53d95aebfd6210b054ecf5cd745da8ffa5bdad2cc6a67bf5412dad575ee71ad551281552bdab26bfe538eeee7d814ee7a1f76170e170ebd197fb210abd57a22318d8725bebcfbd669dc6198118451148a77e803ff0ebab0c22b1cb1849713748d658a55451b0dfc774893729fbead8725b7f19ad03cf0c2962554145a6bfb87021aab274fa55be9e86f4a9f44610a87028531d1ef84a74ff088e143cf8cfa726de19ecf7e78a5741d068e5b405a95f05107148182cc1c1be7a0ae2dd3c27293d65880d274f08f25169a714d0686b8812c8aa048f487a2971e87228c74ec82de7014641b36b56f545a337224f33fa016350da6d2770fc527fc52441d5a039ec3b0ee93f55efd917627ba1499de40f68d63a3a5cd49c17512ed33c2a9006f51c327cbce74258a220d36e29c2813e545c827c61e2e041309928a50b36fe95cc58867df0af623392f5797862d7e5ba3b11a4eee93b75eb5cf1f635a061a15336db0f65d07a6039d2490dcff3c971bca2e526ab0a0ff4d062e7c39284c3e9baa36c0647c94672606beabc23b7e5fa793114f4ca90b1015c6efb6890933e0ddc1dfaba192a65ae10c50d298e80c8efa91b07661d8fbe22855a36aa3d69456fdcb642c1dcd68c6606f28133f3b8acc7ff17e2e6d53003aaa9569e3c7d5f080be51d27f075fd6d368f889dbea8abfdb531ee31c1be520ffd8bd18f40871658459dc98ae8596f00a68079b91dd053e2569f8ea65e85b10d208a9c1d5d236802ef9258e06891d069e498bc52dd7ceafc993d66a06eb9a8ad0d00e467882227f50006dab3ff8b845d61a52b3fe63411428a5014452a43522dd62dc9810024ceb8e1b63705c506c7de2bcac129b9444131213f6ba237671d06717b0fdc72127537a2ddfcb4d1dfcc8aff018b2e56e61bc5af3493b4a38ca7d3cd403e11c34103cdf5169610b8c4b076aa155d2ece6b1a0470731f8f445a33a8a9d5c114e31ecad4dd4176401f00797dede25c42e0315f27017cb12411844360ed8fde4ffca6bc5635be89661faf0dcf0c3c26754a140f0ed281ac28db1439666aa7975fba94a7752f1a45bb492d3ae3d4d6b15e26ed0d596a3f3c1ad21ab1964dbd3ef8c0c372327ebc6abfeb0b88cf8503a52d3b96a6f9382a99cc518bb5016a669bfab1b5667f1e52379d3ec00a97c3ad3cf2c0e467273e802c5b926396f7325067c65cbfd2ea10bc4de7cab68660a6bc96290411b21c829ae3576530d2decf5bffa0d7a63e53b9fbf949fdfb899229d2b752caa0e9cf983b907f2632c64c1959cdb3dc390dd9ba2b59bb8eef73c1cff51666df19ae8a735b9f720d90eb9006434560934b84d83aadcc421d04842a48f521d8ab9821c2d262040a085a1e47836a669d86cf8ebf453a63db7f49b7ea97db50a03e3f9d0eb7039dbe92278b892ae9e936058c183df824d4adb6df21752d4410d8638bd4832db7e1cc89d92f2401782f8406c1f01fe04611d70eedd144b861ea971cacbd13dab54859f3732aa848d4967bc5d7528cbbc12086cba7ae79333be9857cc3508817973d58bf7c8ad38d3dc890f3c361d221f9d20e8e1aa6bcb3805e0a0aa11500305920453065d99f79fab02e578ce99966bb74b3f6e0fcac6fda5f5aded8fc41e6e376237eee7c7ac003f9a9b4333baab4b133e66064a0dcacb74d2dc40891d1e96707a4640e40f77369684db3a2b3a97c7475d889fe9cda45eef20e52b7d1bd14c85a81199f16fd08f66cd233cd5d1b348c20bffc0c176c57c8db8679afa37e6aca9b5b15ea7a23aa90de20848dba78e9671a2e9f4b097aafde4c1d03e275eed286113dbc026936d8b2d6f93c1da1b3b7749c83d5948546bb9759f15a7ae40c031e243ac65766f1b94465048f497a3e7527c5432aee7f2fdee6dd2cd9dec3ca95d249360716d7bb3989f94c6504d3b4c5a64c3117df74f5073094cecfe8f3b97af404ecb5162c78336a84e580b28b4997cb07872ae42f00a5b6c19323014223ecd77b514742338e8af234eb64436a44604d60bb7a6114f3f00132ceaa7d7338820460184c7e009f52383eba240c7a2a4e1b8c1bacb026d173b5c9fa43b2749040343e7462158c4aef4662a19071087aada720a51bd827fab8500ca9426064f8105810211f13042dbae0e4acede26214946b3df0f4abe0bc5ae5b062dbe161ffc50ed2abf531d2f60a1e64c795544b7e7e1893db30b375bdb824733f3c5570e772ae5b70392010f280bc76e135837d00c2cdb4bbabc00391f960cf86fc88a312d28892ef0046258110c53ef0bba3628201f06f1bb62f2824ec1eb38f9a286bb07af183ac916d273cab934ce3c6dff9c27ba787e26109d4a6d01d9cfbe7126d918bb6ae028097145ec972b26531e52fd308cd060c1877dc35497a65b7dd4a9b82f31b5fc70adf845c8a47d2bba1561de03f018b4254e5cd47d760f5c5496fac4ef1a3e034c400769479679e450b8565257f622d57914d37c75b6e105bae1177a707c4413b295e3e238983fda01f1b9c65c359b3ffcd5adfe431e584ff38103fea0843ea3f5ad085378bc5afc6f06185a86114d2bffce38b2a76bf1e7a5720a6efd649409a65675b07749d1a613ae620f121399c5903be1f4c6d9af626dd396dda8826d50d84b6ede79acbbfbe612b7d5296227b36bb73fa459616954bbfc5823e008466bcddcc071c318352171b848432f8f30fdbdf8502e675c49e628cf1bf0638837e0b4650a48b5b948137555d28c7445bf2315a8c5709d943a040194e8f2718cbf4d0eed81f75d9bbb3f1e47a421b1b150a0b688b41d767541753f99b5d19c3b7d95c1a496e7df175a81433885dd4dc8d5fcd525bdc8343cf089703329d404c7563f0b0a5b8d6acd6b57a155c2d08157a0dc52b318f7d3b3a68fd891f78aeccbe15591df43371e1469812a04835b1919fbbaaeee21a743a88bb9356f5e805569b0f2c93362327e5c5a71f362566660fcbb5d4e01b83885ce661189e46f3d6fce925407feca6042db3be79896eccb70bf4a328d27d3a2799c53354de88d893524b0ae309ecacd19cef53797f15e2e79661386dc431da3fb6de38e7f96326b100cb4944e85f79476a03a94f6f438511496c1ef044955c1fdb163e22a14d5f64f5b4633118adc48fd346b61b60583635bb6c300a6e6f38546aef4a11735e6e86da43a083ccc6d485c2dcdd37855767579ee3649e5270109b749297b9fc2ccce94edcdc67a7acaa54bcad9b8f214cf59279cf2975cf6aab6a6d2afc467f359a242edee73a371c9a3177c923ba7e5b948fd8e8fa9be482972a715e3e929177cfde685f7718f8d4c16edcd9c0746c0634356c49b4cd995c59da8347c42e3125226d45c7e563efd505e59f4a40b80e8e5982eae4bbfb0530780ca1fff24bb19bc6cbcccaad4e6cf817d36ac9b1b638851ed9e83ff2281f937a74e620a5ea9be342c805a331d39bbbdb7d6d356e5c71135e13097829a5b9c2c2e66acdc9ce19a131631088cabb7bae260502b9f5dd3c77fe50a9a376d329dd41e2d1d78d5858461b45a7ba5fcf615f81746c77920ba6eb241b69e83f1999118166c3f34ae1549c1848c6979e66af6cdd805ce80fe29b291a2f39080a0c490de071aa841d3b9c8f9cd8edd0b18c68ef63d8d2ee49cac01280a9cf357655a238db61087280765ed51e670bc68995b5492a9bd4553249f4dece62d4957316abbb1ec7308713249f405b33625ec8408b299d7808ed4c6c65255892bd7c62a62bfe2b85ac930a1f010d1bb5baf321897bc46233e0573750a9282c3faa686f132ce007f5d39a2bc5936152f9425a6527d61415ad88988565f62fdd48e9afcbf85b39cff92362b15213066e8a0cf0ee0d933dc78b7a01e645888b69385354c74ea0289bf18f0a5d35e587c4a30af7b88cc4178bf2a48b556868dbe9564d06246639f5f89adbfce65a959bdbda4a55d9d461539d0deb17a132d85b1c54f7577d01812c0a6f20b4ab0efb39500d48d82d873b8bb2fcff29fbdc75a4403722bd199eb63effe1ce1881ae447f0332bb21163d95af8836e5dfa3dc83defdef31ad44383c531c4698920acd74d970fb8f8db1b84993055b5753848c3fbccd61076b09528feec91ea75c0a2a45908b28688e7b0bd2d9213a32e0184b02ef629783632b637d6761f5381b35f8d8e73eb5d7857aecf4bde6650097d84228cc463e74005c14c37b4f1d667eaed57f018b37a76b6b016aa48a2aae5ace098cce3306cc7797aa6a9058b36116fd3452f862fbd3cf707830bd069bd6965ca66d03aae6196caa8a2a8007e27703329a50bdf350733859f395621eecd1ab0f5c24f674393260afd451deb5864134914893b0d787d9d00f5fd1493c083c9dc05c44b3d4e09a5bcec135d5309e131d2442f6cd4e8c452f30b8b1c4ac41752d53fbbb8bf62da5e06347054ea05499c4afd30405f0841fb83d53ec92411a1fd05958288c1bee73275049f5a8c4d139b9ae9e0096cd57cce3c4cac5fdb9a28e67113113a771cb597a9ad72d34790b8c0786792a43f881bdf49465309bf9f30d3380484eaf2e8c0134564d5490b7dc539476e4e344f30319e00de61c6d5ee5d94c920a648fc434ee2baff8252efb0d28feaf2e90a6bcb36967a3a93ce315fdce385d177d63957bde5f0f7d4b261b365156c9dfbe583d3eaa90110110e9299989e24719565264a29b9fb4300889ded004b3776b9c8a04312d57c1c793b795ea81a52d0eaa5cd6b8fcc2273ebf58f1478fcf7927053a6596455944e7173c1e3bc50dd02234e8a6a22b7480a5a3b644ef5270c1870342cf2211da2db54108f7438aed998f70e258f8318d4eaea701085454f73f4592052baf4d995976507d476589f4c031f077867a40949658d40881207d07cc42fce1b8e07870d3654d708119f35fb040c0e85b03f920171ba43b6dfccef6d8117071e62e27afda0c06efa0a10aec13630d2a6cbc3f02f8cd1b6ed35256a141f7d13b43af67986fd6052f09381045404db2f5dc217077fd48ebfa7d6e062f4904a995f0f6b50b2a470c67ce46de38ef1c768c943e86b1541d96750dbe791aebe10acf7adf7cf9180e0aafde689086b557862884c807573a41eda8bdfd4e46246f5ee74526a32e27e8d548713711d35860f8a97bd70a11bbe0e986f7861df74ea9339eb8b1c9c47a71f595a6882f7e17c8086216d61f344f4294fc98366ecf7ee48f351262dcc480a0cb2606e7647828ca1b8d7ed6582f857057a558efd173a4e748aba439c58d6c7243f7d6823c56f19189ad4a44ea8a72d83ef9702c384afa7b1e9ce0cdcadde0adc56c2c6e165cde32cb468506d7ffc1bd7dff500e6216bfd3fd881abf16aa3ab3114ff8b9d155b0355b7a2807c4971baabda9f6a2b217d5dea8f4a2d29b8af6d84ae3815e4f78777aa7daa64caceb2d3d6ed0c4e70a337a9bd563a65eb37acde831534fb37acce831a3c70cbdcde831fb7ae86d0e87c25ef4a11af07ae9697658a081a58ee4e98a22d316140a8011e6d84f619f332e2d0c51bc64960550e606b7ba5195bb911f7c0d233848ef93d1afeb8379e4aa23a9b781714da7ed51c005d233379426104c2252377f9355b2b5da81b504b6d1ca817e81ad40b8582e12e04c9bced64700f55c50e784b8e891cf5bfb3694895e352b834cb8b97124676f56352964fefa554dddeb2c2e7d2c3fa9550689bb42e3461e7c12420d924dcf07aed38699a5037f1c6229d45cef12c1baa74f5854f2e68078e3bc13581e08a0be8965b34dc86be33f1db669e7c1c18b13ce79c1f23c9ed918ddd607bc3d01a87bd4f7595ace0ea2a2f81ab676e55d53909aff8911fc461048bc42f5d3ee36d33620298f82035f31ce3717c6fafeab4b88d30840fe60afb11569f83f28a1e007c63461ea701809f05ee9946e0ce84a1982a76f5204d59ff43f6b3d7ecfd60365d367dfe4ac9af4625193e8904fe571aa04effc02a986e7dd5d64eac421dc523cf3e97f3eb56d20a949d0081840d8d04c59b21b163f5bd5620102a970e9898c11e2d03ba3adcc3d9dafa7c7bb82f0ea03009af8c97a157686ec6dfbabcc302b0aa3a05267c2bc99e861f5eaffab25ccde261d9626aeca158fecefb227b5fc257d7be083c227362d4790f0406448438de62d24e3bab5e776d90f5adcb78cbd2349a75f55e74345adf64d691f4c752d1ac24828bd427a9a7b23e38d02495bb6d9e308bc6459df11f9b6ccea7b8458d32d34707753a9ad618f8c55d47722df02a0a5db7c339772e3244c5284c951a4926b617fb625da45a55f5b0b4a0cc57ffbb9270453558350df31c36d80f0319837069e8b70f0db3e22d25b0f5e0d6d4ce20730ca2c833aaaa47186521d678c17987872039740b7dc32ff1107367572a3e6147072e47b2c1b3ccc11469124ddb4c0516d944cd7e276e7dc0cb70bbd4dacf580be8f032bb4759a4bb18328de658d414e48bdb723721ea3ff59a01936358dbf89fd1a71d46044520cccaf7cca036fde8970bf449339f4e5149cc52099d7ed2f5995a474a2fdbf13fbac3046a153f4ab8bc0a4993327ee88161b37086ed02e1a659f282a2df632be811b2c0a04e52f7b9617d5d73e81deafbc69ac2abe51b85e79d485d073854f809418f4b9756646c223ad9a0d2b1a581c7013f187b14094222d5143b6aa1f0cd863013c4ae51589e5d9eddb03c17b892d64872b39d38df012a637a84ccfedc7343bd53c7e8b8866b1b4659bdd5f751eda0fc0c8547d29c914eb69d66e937a6c7afed45022c2e276a1f4ec01b88d87f99778e7f86570790d9de0be251689163dcd03602050fc7ac0dd3198d52d94b09de2b76cf922d784b6235f799cad59c26dddaf77e78e0645a8b5adb331f6c0d712efabba3487797d7e3c35b87ca5c70fa5a0b0d28e423ebac834f60032c0f89bc352ef26b0941cf6bec5211f7524fb0f8aca84f7b7487f3532fbc96377602497790a7f72e7102b3dee6dffdee03e788c004e7fb3d626fc85c9a8006ab39134cbea5c2cb968a0f3bc7df88f5430d9d1d8c61434dbd4dbefc923dda7086416336a86f02a1e92a2849b794d7655a629c162af130ddd49c980022ab65e34a32062214eb361364300fb4e942c34e077f887af7511718bf7b100fc1abfa92141edacb505131922496f951195ccd54177d93d139b43fbe067d110003b7c7a0dd432d50145c4ad2b2f9ccc24ba358a14832946b858618120ad4d82da2f44101329024876d9f12bc172562e8b23587a780017befa7cb9bc4daa7433d3aa69851d20122a99908d10b8de2a18a812ef5410fdc6dadf3f0927724112c3d723253184c47a088a4c45b4b7e0050ac81a91b9dc81f052422ed40be17c4390f21bae824894e9fa64d45572ec9d4d82239eb25ab9081f56de23219fa49f43a129cc240d49c169d1b83160c0026a474a9319000343a2833866ac5494540358437bc2a9d05b331567dc7fc27fb51a4c0f8cd60a6a2cdf74d145ef46327842087f18e7510a3bb5e3ffa16d37885d77f10b7c1806330ed2b02525e4e86248fafd65056c0526c1606ed94c93cdebf51c7048fd05e983519a480774e53a5c93bb51c839b4cf89aa45da91010a7ad37077f4e274b7a236c1d506c4b42825e968d0f25626c51998d783c379377c44a4fa2c4c4ed833b524f3b193ad6fba0e68eaf7a95f82b82853d30eb1fd7a88471471a3350e8532ed385d1afb1f189c685e52aa8849537cd005373dabe5ecd5bc516f8187226db69ce2a191b72833778da2ea07cfaa9f5d84e288c49fae3401d1b7110ebe99a54df26cef989167a6f014d8664f23b8508919bdfd6b601b93a3a9af7d6b956b3f83d833517044dd8cfe0b3a27cb8a44c2d3a455fb24a53c535958cdc79208121d35f90889b51763f47bc3ae83501d11e8fbb0ab8bb83bd453de623277f5a9eb36ad23ecd4d6c3b500e488848e921031071d979cd02afcee5056459637b6187b968046f3aa71365e44ef9273cc9a6bf4de3c7fb29fe47ee4cc5e509dfa24bcfad6a4339aa980f26047a18dd20337da976cdd39a0063ab3772c78be7a8be9eeec6347128d7df5c996ca35173e5cc627b0d3e670b948c3eb7251305459fb8a9b0bd0889d59f932623304c49a3861743bb4283553194300f54a188691cef065e497293159a61639c850457314914db34dd4f0af256c744eb6138b918f7eca30f1e81acaff24763f06fcc73cb5eeeb6536a8558680f101ad8041fca948599659cc40bdf3f9ea7fb7bfdce8c0a170d65326746f64751a3e99def018b301f6319fbd2753972f0323ecef243858c40accc1ea56967f1dd63fb91479558808ba17cee57a9d8d027e5c7cfe391a999a7ce7e432a98d0a836f49ee3fc9894714f37ee2573b2b620e1260f36840ff1ab1ce09fcf8d5137dcf090b242413e9e2ccf50f752319690479eaf6f4b19d8a77937ba2d43401e012f18a4e0da00018dc4f382abb1102a2b927be5cbf20790b919a351186a97e1be665cdc40ec00aacabc6d58b0d8ba569ef576fc65f13e05752abd72bb19ba59ee6a3b8c92dc16773a238ebe4eacda758253fcae1f42e491ac7caf671477b7c1c4b8c156ccc4a702457e5eab400dd6e08ad2f90a9a56d6e104eab158ebe13456c7a8a0c279ac6fe6e2a6c4dc1cd2646d683a03dc473a2d9e062db818e22f356e9455257818cf5f955e3797f87785b6ad8cf56ce725510b6c598723d5e7a070397723624a373296c6be0843273457d5d247c567baa8ab3a06d6da10d0da8048074924339fabdb07577c337a378c25eda4c013efbae09cd16d872fe8c31ff4a66f1a19d5bd720df05dbe7cf0627959c5d9d2ee6ca25c9162b2206fe63ff0a916c58491afb17047c8a0d186dcf907235fab4d4ae566ad83084301e592e404237f3a98089834c508704d95dc51e2d474242439a073004a88d73c1700e10105b851573e607c149c32b6708e1480f6fa5f62e490e282bca9e3f7c2c7bb9f31081eb23d398ced1c65858fda3dab0041578e724b582fd306aa0a512006652b35bff018b106d2d8e4746ef2599599be81dec1f6796818d834b1d61065550a37ecfe98a7c546b625c0ba0b362eca4953127fa7c4160ff8405c871448007bad716a26c008a257237ba3517003b3470196a74683ce6b701b918352e03230d901ac5a23b86343ffc4e9608d1d65e708956185117e02d1b1f926f2e46b73f7a50407d93ebe84f8440276c91d70bdd4a008cff78fb2d4465e252ab4573dff0a4ed5bf4b4e6f087a89e03adcc57b55bf30be64039ebe9c6ade83102000b4bc67dfc602dd2e93516b65b6dbe1a8350a180f5187c251ebe14971d7b42ab05b809e193a2899e3347221c1308ca6d89723ff96d341a23f89c24597dd408b4230edef83d1339d2d8d362f276239520fb5ac57895204ac88b2f376ba05d7805de2ace9ae03728ae6ddb6126a260f3fef35add8b305190e66e8dbdc3cad9077a76becbd4354b83ae994e3e54ae53423c8c0458c04c20f18f5ee9088ce6c918388e5b33102708662056688a26c238facdaced8147569c3bb558a1abeeb8a1e410302a4ab8ace0f3cf3e742c48d3b1493d0b8c4b5745be684381ba4a6fca3469b515317abf81506596407ab50340f71b97c1d08c719195c520c31bdf10b1e3d272d19ae4245f8f6522e388ef3c99debe69ea976a220b08be355146f4012d0e5cf501eec4774a576904831d21b52cbc94beb2e35c78d548f0b1cd848392fc55dd5801467c7e225f590961a4a5c8d73394cc0c69f50d2d913ca159d3b83e98cb9618a938488a5135793afe36dac61ff93a2151e0d6ae321e7242fa0e6151ca074bfc377ded90758b012ba7a0c6cd319d033efeb359833f5158ca6820e99e2bf6c3532da96ab999080a58d2ec8c8a5a1ce849bfc8c11ceeb69364e37ea7a66de1654dc2680257dc972d85fe839412431b1ab2dd7f32b7fabecff91798d75ded7ac7712665cef00f156f4ba9430d29e3e5934a34f92cb59e29609cde2f1e56ec4e335dc212d00abadd6f736f16d13d36e915087c8b65f2d91425e0a977095fec06f18984690a46e93fa1c2b3b92cb6b743a433568ae94a78b20d77fbfb28b6f47b09b1ad57c45af9fc92cf4ebf2e982035a4799f3456ac1e47f790af3b9361d5050b7d050b6f34a534244bb3821a761d9d593640f7e8defbb06f2ea8cbca4049ac2bfcbb62fa7f15266070552231186d3d215858668b79e5cecdd998898525b40bfa97b48b2963170397f55f7db39bbc8cd91fb56e755702b7f1c9f73ef36111a3b6b58c44375dd3e41386c8b5d7377983a0b53595d3192884f142912a38e34abe567aa10459492f4da1e14bed288e013dd1c94663b4bf49d2096671f2070909a7c3992a2af1b612d2a45d4a016089e0c7b07ea20ef9e209dde51b22f14330d62a56f178c1f9d660299785a5942d4134ec98b3f19e350029d32e39232cfb3e4a3acaec243938458884a262619f14a84617c7c6d4e0a1f0e8c22d1b65eff14cf6c72264ccd377b63e56c061b191eb8c12a8bea403a6ea74fa3db8846886182ebb36ed2c0e2583232f370483e8268e55dd648b9c92abb6c0290aa68cc5bf7289caec68f9ca8b2aa5f56fe8d40daeb3e824d3b48283f9b9e898cbf8ab44b024980e26e307c9799283e29d2b239aedb98b8b2e9a79b97c129a3bf2438f7a6d00045967ec573e9091611de723ebe72952c066aacb0972239e6b2b4703c4811fa57e726682e5103fbc609f37ff042f675a29d723746d054359c5ab0cd5cfe0eccf01e713e6884522d9089d31b3308957fec8b393d3e871e0b9af81158e13069a5d7b87e0a4954bdca1dc2fbfdcb46b90b828832235d87e5c1caac76f6d972599f2d4c94ca08e5f88619a6c0c71d057274dd63d0eea150e43b9323c90463576fbd6861bb35d286003a493741987b91c68868fe2f84a4e9569862df2bb0fc7e314ef685c3e4a233bde75f4199e89bf0bc2df77976d247e890f524deb58edec8fa6bf22acad27bce53017476f065004847a1551b209c730aecc618c88205767cdb8a74e9bc3f6769e651dc61555aeacc2d52c51530e82a3e5dab3ae035fcfa7e403a1ea33eb8d81857a14ab5dc119906751413126a556aa691de92fc073ff169db5ef28056323b8c7a6da27f5cbc40d17ef71949324a10039ead10fd3fb14f263e31196598925b3c2b9692bf3e25a6d60f35fccfed783e89feee8334d443c346f445a7b8ec4c9e2f3832029bfd4145bb1698bb70ef32b043ee71a1daf39b0242fb9d1d12e391d85803201f0d022cf21f85779a6225f3f7e50ad565d84f6a677f704e8780a94a78982f8bcbe88883a220aa37b5f0322827abd2689ada76b480e26e5ac45ab757e561a33c1b9ee4e0ae4f8c506fc47ec4a1862a0cb8c446ad822e9b6be05759a25011234897954ba95094083d59b7bfc9f3e0263f7d8331ea6cf519849c8a2e1d036e3c211532448f5b49fe56b81089acd727aa44a4456b190f2f8fb30ece9d534cdff61163f7ba545126f22c3c6ab9b0478554a55c48d3d2b444386ade28a6f83068ceaf23a97aa9dd88a39cca55208475b0d3ae5078da0e783bb283616792c56a326b6813cba889762e485e111fb9d6291d8b35c1bf1f6ca01f84d1630614140c4991c15f9922bdbdfad621f759114dac38475578b7ae20b36c63231a0d7bbea47c28d5620db82380c9f562eaf0ecc08ea1419415e75f6bf79c3c7ee42abd2c02934415ec43204c056a9b64f286ca4a899813a138c7db34ee45c062c795cb36458efed1ce860ab676a0b3876807cc2c852559b38b296d5d03d7e8603a7a9ee4141943ffa4f0f91070a9e081fbdd3211161096bc89bd87d2dc0ad210e428122b57d496214f2a529b256e273bb00792405994327c0af71d73b22190cfcd072b38fbca3dd4da737bde5b4f49b6c6aee37f911178423d0b91f7f0e065618b21dab5f6ef87a19c44bdc4e4a423430741f932a417a52e3c7f1415c88c8d83ce9eb510b44a45d662418027d4613de6ff041f9b77a4016c55d52b757efb75f2834a627511d35e796ccba1a212b9be5f46386b4bb9869763851085539d054faf608f00aeb60a64af5e90d4d36c5af9a592e51aaedb34b3246356bd24a254c12337bc6436e7e2d4f8e28281a7514959e93132617a2a2b59d2de99426303870d5108bb4ed782dc6e68be83390a65c892576254dd1eb563c5b156b245f22e6fc96b68bf1767def69b733185b1ab49f875b2caae471c7910659770f8e0b4948fd7f7e9462034b37e0c015818eb0669655727e769157ce312bd0b7cc9886eb15bb9d63e15270bab8679aea500842c7115d5d6733cebd9ad6a42fec093a6db076130abbc5d8a1a35b17a85d060fbbea545a0a9a2f60b94e9094cc6bcce98966a49d51c866f88c3e04a35015844c2c26ee3ed7b77bfb5dc4cf0ac5d1a09b6ef4c3d965b64c32cbc1f7098be51abac66f9b9c542175b8f62a88ed53daeb69f8e1e4ae4e2ad77bff16264ab17b5b8111e43b576cb4a3fbf6b3e1c4bd32ce27e8135bc2cec2df6a390f7aa072865956d290f00d29f902d1b5caea9533e95ac3ba46a7053b9a0ccb167791e2d12d7702c32fe2c84da1109f83d1d5d402bd86bf3ccc62dff530fd4914f8ef888292dfd7aaa66ac513943d1c9996406a4aa46ebd74e248a665454f4fcc0467543dc02bd36646b46e953367fc3924769155f6a8803aa585f5558068e88343d99d5af0e7b5d54a08acab6af7e7881bd66e4be7d16818a9276eb52e5b5b2962e2b9854443c83dcd90e92bc473055187d69a3b34ce436c570ac9365703d65b507a7fdac0be144cb8602ef751a1b1d1f1179386c1dc13b913359e72c43b9e90bfe85564f58ebf7d338d56ed65b1f6f3f7c018ae40b23b294423267ae88ea69983bd1d50af6a24a6ba8d28057d479d0d7972d567f61d737d618d6850c768cc252ab4cc7f7f213597fc2fcf28bf01a5428487dc4c212c6aabb2c5dcbebcc2ca961671b01572c3d4a519dd91500eec411966a1e517fd45ad41ae96d269393abcedc893b426c93c5f326d03b6a1d3912d2babea29723f989f4481ac2fe7ac12562ed9880ee05d097530fb81fd2afbe9f002ebaa86152a9971f01bdcb0283ef41262257b94265974b5e4125dbc6600e8ba5e42a16f8639aee74de2fd0c243aebb7a584b315e28aab5d9f2031d2d4ce0b3132505ed2dcad84eef5c48451a11783ee95b5adfea3af90387685a29aacbf9fc872c8cc895bdbe90de15a2ca111dbd368c5850e3d4410f731c4708d314cdea0777d1d43b1fa13b14e2b27ea559da1b21c1dc0c42cd16191ff9ba9653507175afaa1ba8b6e2778f32414638bae10819be0a1e5231c3e09f3e9a4a3608cfc7c3e43d45d10a59689e768b6506e4f98833ad136bdc99f18554563b969961aa1bce34f02846318898d65531b7f3d6942a88c579c0513f024a1366c8b63183b32374c12789c33374a2d5774ee77e7f2d603f6c71e0011cc01a8efa21b7be9f2d1d32efd8e0c53a712c803806af37cbfbc17f11cf114d14828ea37cf23949d34b007aafbac098c2d4c0ee8b1d7993e5d098184b333df4df9d023c322cef19056162f75d6477b66a8e202519e20407dee7fd8d10cc65f2272b5cb2efb9983d6c82c27d0cf9d31e1ca77619a18d3e77810ebfab2c9ffffe310e998ff37413c447c1e65479c3c17ccd6ef9b68365d69ac642668dfd75b2d1a7fcd59dbc4c7cc3fdd9a4df0f775b93eb30360cb46707d348185fb1a1a1264c6f061c7619e71ab35fde183e6d4b3b291dcd0afe49e4ba98f4f66de8e5fded63fdefbd3458abe2a885a24af427e011c0437fc0c3d139de6dd7f9d7c3a7d522ea53fa9134f5006944b345342186a59daffbacaf80754f93ddd3e0a3feb4e40aeda44296e510908214f71a03c0a5f042b76e98b351e5912f4f504d9e52a02a9d99ca76a82b04b3ca9c82ef14cf55691ce3171d4cb2fa5e23d5256328308f46168d72ed74545eec14cd74787d1569bb550481dcdb14cd1e13a6f6b429e8ec699d50c020e07b84d574a12d0f15a263bba987217e8d6ea2494fb3410008a0aed156b060551706b4374acc8c5cde4466c98ac86d1aa4e86ff779587118df2e0d276a5bc124f790e29432b8187ef5f213ed43e2a03f6a4c257c89b0a5d074e7ee15a282cd2cd2ffc8e8f672d3fbc0ac4f70f2908d13d28f8e9e23758bafbabc37a927e8ad6263edbbf95fc79e727544f24e90f0751e9c041b6149f68ff0a9f534a379d17ec51a63703876631c9127cfcab4080189fc083e0fbfe1c143c5f9b31891b8b99b3ac9c0b0206e76577aa387583bf13833e01cdcc621dfcfcfd7c5520a1759039d144c04913d56fcbd27005c3c4b458ba0ff6044e83197c31d93ed41a8afb80cdf59d64c6f551f94e54e646e6a59e2815b7e95d33f692dacc1d5af2cd322e2120592fe24a11405617754b0a20eb8a040535ffffadf590cafc89bd4b9e89dd84c37eb24ee7589426c66f43434791d8f30cf2e0c461d8fd6ffcf791952a7a9512d7091bf7797e85050ee87ddaa9c7a2817b0fd5411b3bbd6646cf3bc5627a0b744603c57e37c9adf486f2176e15f4922bc87033543da38a859126329b83162ebdac52296a173fb8c4fa6eed64e73302afc8d8655f8d2dc007a85532e6c8f64ed782bd20a762ff2b15164839eb4a8a9c0b1a880ab2d76474a07a16e47a037ffc7c2c4474cb4392b0a008ea02f175477c92a9143ce1cd5e3dab4a998c1f47814a978b1d78fe0d3fc5634abb61e390e547c605af54f29b132134d11aca02e6bc1ef45ab8601347dd9806e75b42758d267a45b7c65135a7dbb2e97633685284829c245c69a5ca6fd1cbe0c4ecd91e081cfcb64c1cf141ca190aeac67f82665c9d0368b0a6e627492d446be2a6ee729bd3412675a33a6d3e5150773c728e5335152c575c1a5c9ece0e3e3af653858057c641a08086a375f0ffa2ce8b7ab1c615cd26a3dc3acd88e0a8d0b788706b685f96249a0f745012eeb371ff9902c3fa9432d2c52a8a545a57772ab4f68ab51c096bfab9d24d2fa778cf178a14d8270f97bce776b1ac39ef924ea31cd54da9ed9504952a2297cc1733920e74f0e440cf62e2a42a5f19b2a42d38d6a1ea71122dba0d2a7fdc15e20a6953ff07dad51bf8a7b9d603fa09690ce81446b3f1abc76a3bbbecb46d80d4f55dcc7c0ae40fe57e4c90611a4dfc3d3259d2d80529b2bf7b81251c0b08506f956171b17b1a2fb794d001aba0b83eb0c5feca019d8be88fe9fe9dfd9c68d415440054f096234521a93e4ec263bf61cc33e99a004bef2f0b494c63c35d7c439ee6103947a4e9ddfbad7722b995df1e672a91f458a43345d245de330a124245ba4b243462309f005ee880f32c562fd2a2ec13cffb21c1b492c24e0a10f5813c00f729fc6a44f44c0d407179b433d25dd40d207c85299c8de5112126645545e34a895015b0e8e5945bbeb724dd97801c32962e9ed459351b16155147014fae1138a802873e10d37894dbf9f97f6f1524386987bc2742b831261c302c9bcc7e98c1b15e6ff3126ab4775924c0f7c624c37092eb3ad0a458e29396661813fd841f40d3554d2510fade0195365249132f83ee8fe9458928e14b17f4c3d13cb774dc894abe1a31f03d78f619b6aaeeb09e4f13463e16e1a72c34500c31e405f3f2e7716ad46a44b238773542c4a173aed0207dff0b9a1244e40e97b9b883b2884b2f36c4956426ae6dbe14eb58dbde21b680cb631571c00fce45904639db555e0059747143c5419c6de57e46c736df1724ddd9976d08f4f9738b15cc825b278ec7298a281edebd1e7143e41b6b4861c00b95f6d5526c730ccde5e308d586d35e93713e6ca3b832d1d40f8c207d325086db4c838e33e1ef7d64d166d9c40a8fcb8b54662b467c3d53eb9fdce1a56f2500dbba3cab70360cea33d35a06e15d409435568b317a074dcf3abf9c09bd6aeb7828bd6e0c98c6390a8492a1345819c7b7292d280a08d1b0d380522f220e01f0d934a7041cba13f80044a531a1ffcbccec20eec9410bdd799d82e02fad0fea1b79d158dcce658f426872709f28d4e9cca4e4e62c91b9ea3fb04b3112f3b94cb32573bd86b07ceb44831ff3e63c23a132f50b897941dfdea5a050226e0346c74e6dec3ca670d95787dfab932bee4b81e0fd5025cb62d2ffe30c1889a5e193a39b1f41f613b31d87a0a17f5535bfd0e2bf9c9a07ddca761452cd7e99640ae26c029f4ca77b63c0a9ebeeb5123d5f38394432925db2733b8f0f90ca1195e43f4745db1214668495ae6eb3bf763ab1353f3079ea7c23a99314682aee642ac8bc462ae9a067c9bed12f451eaa02c787a5e62400b9543608941a8ddfc6afd988ff3f73fc7197f02420186208b028ef66e29f037eada4099f64451f66ad7c2b7f31fdd607c06f2aa212f5b1f4f1b67f45aa6d38d678d6a1b3d3db58ef83e4b213119679888a4273170be3efb4e6e456ebee2913e05d1e1bdf3aefadd0262d041d8def1bd52cd665172775f4069beaa9f992a969079f4dc6070fdfd43822968a4089235564f028ce69dffd5386b19a8b72668fc853c9bb3d640e330cf4c0ececdcff447b37938fdb22931999197058e82d54914ef3fc20fae27a95a51179bd483639a0d11c82997dcb04946bde680c1d71c6aeb1bb1c081434893bee0aafa0d2489cb16fdd4625b886e8f72a1799d4c84ec13558bfa32c88286a8a77ec9a2e658042a9c1b863f6fa6f4a13c923f09bd442a5b4918a7be40469799694cf9f2f232ec83d7310805b57c0f8824c41b1c737d6bfc9d7c32bb776cbb272cd2674475326458e09a17d9b755125d8cc3106653bf22a06674f7fe9868956370e6561761e07510626249d5f48d3242ca2adbc750545f18e545ace6acf1cb6dea2196101ba006b6c69d33f24938e66db12c156886e0b23729efe1c37fd291cbf8c1e31963fe10eb0cf244503c005315c88a0c940e92e6410a7c0299cd359d6f26949cc780ae1655036f580fbde64300777ae257db9cc0742104005075f56510aea80c04706bfffef1e9dc795025a482b2dbd8f585b048a1e7db7311678e6ad988d2ec13beaa233075f335e020e12f84cea6672a9be82170ef04bc2d46740ce199654845d517ef164e763f260a6bd201d40c1b4d94048f02be9c9e5ef62f82780da73aba57c122f0c829ce6bb97c58787150b8df29710c3be227a00c44e3e3e2ac82691d6f9084470616479c5f77769fd9005fe109f519f2356adce391b31691c74c89c70c87fda1804d5718749f0f48a7831a7957ca9233af84679ac156258ba1000a94f652abd453bba8fe6695c3cffc91405817cce351e3a3992285279623a52c99b414b244074dd4468ee4aa8764176edd957d2f5f148011d0dfcfe0595cd43aa136985cf2352c35c7f10587da8ff413aa6d9b2ee157a58ea1ea892cef577429145cf0c1ec6df5ef169c136aa55ae0a99e522b116bd7baa4571a36f37a86258b9cab11b47437d42d84178506ad29302371cc6a5f46d4ba143e6b78eff1038c39b12a5f4e2e9602d4e41e7a43bc2d6cc37828e88669515a81f5e33956dabfdb562d4060a75c864881f895e4a563f082728f92eb474c6224c35b07eb5b6f08a8c6fd5dd64ec819010ec93b0019977f6b48f558c6955170f7deff41738a50b9876704bb6546a78a28175a74bc7fc9ba9659a2b7bf2eb2442b6dcd9da4184041b5071934c463df2d6ebfa1fb1a15f35cdddefd3c0860115a56b7f58f79351c906fe7816de7491d66bb3e8a7fbc2900d7cc1bd721a630a844b02dcb86058acd1d2585159a3391a7d4edd0fbbb1371c5da5f7261ef86a6e54f87377363b30ffcb1b91033bc828786789e42dc0d5952d02a3202c69f4198441c7208d9807cc3d18ad862d0b9d2c6f2d52dee51966b03b0f01b418dfdedc6bb95e470fccac99b740fff3fd5385576c854df68a812107645e975ed4ba36fdc3311568797729a24d8447dc3e8aff6cb9214e6093006cbec0250c093d3da982d3f3db8234f359d398fc6666967f85b39b7278433cb178afbecdb0a5398cb5cbb8994ddcb7ee798a5938de50a56ad8d3afdaaca54e8c2332b6631166733ce4047d6904b5df1bb467759a16614f53a8c45068a0a82ae4a8cf333d3b6c0522d413f90cf994e6b13949f8d39e118fc30ea69ff30bece948b6d3b0168c3cd3be887c568112f18abf9111bda5c400364ce41720a40296e80678d912ace6478f21c10cbf701b6bcd412ec9b8d9c5445e243064986061d9b244554064f8a33778efdd5ef8a6f7724e7af15adab3a621dde0dddf9b3ab032f246cde5cbc061d86c23dab88d66513ecda7ec94869523356c2c918c7398a67e38051f2138cda5708ec36ffa5b94314d5200871edbda492a2b3dfd8c05dc48d58fef172a1e9a5580349984d2011422bb34e7357b799956bc8d93c6b4f9ee949136cd22cb53ffe661361b752df80d944a15035f5400c7ac9fee81b68ea5b70686ab3a72e916d5e6d7076ec905f9b435d2fea824d0df4c44ccfc61792d0fb4c259f5e955a62a26a65b4df1ccc0b255256d3da3390b4776248cd976411d245275738c51830ce705dd6c937eb66f320d7d1c85118efcd885a3477e64b52c01e0ccc73d1a9d9ee2e930cd368481ef0f9ce3ca8864856a06dc499ba2f016c96844232002ea2db6a4c31209e1ceb845ecb1fa838fd364de87270dc057b4618ad3722a7f5ae8aa703b7f3994078ba6a8a4cd56192a1e79fa8fd507fb822ef58a0bec958a0a613a240a712c7a0fd54de642fe92f0bf9b4bdb256f40d84e49e25f04439687a1c230f55e685d0490b19b4bf538ee4af32c04a1d1d1de81ae5ac5dd26286a445ff47a087ea420e89ffbddd31b85992b0e77e32d74458d31593981148253cfc330c8b792d12bc78ee2d138604ab43cee7ba6dea36fa80f70e8fe5517e92fddc44e21a26405cd3e8c7ff20a1f0634e2e82c8fa82aaf19c4f0df85bc86c69e492bc697827298cb310ae9a153e164907f81bbcf1fd10e6c7b18d23ef3e068b0ca5d448b5ee1ac98b3a1a0000865cf01ad66c812c067b727c809047658899e18ad6520be4cd9d98621f68a04a9418667bd8bd87c8d330a07a6bcf22841b5fdf2cb13a5af968b2b4c25867e34a2605b41b6da99178b86a5a5a706ce9f9186943316f04eb8b54ce3b048e6232b483db2e615a76079e3221046fbcce5cd47a8b1f22b658df91323684b5fd96656eb9438fe69d0f0ab15f7eada7f912cb591a85cd46b0580c5716381fb9a7b392d76c5411e05fdf8e8687ec28542d08f99624b44dc7c8de68ea51db2978addafd3aab988664f5c0ccdec0c57189beccacd56ad87ff3ed750a59a8548081685217741e4454928a3a6f88f6e8d309cfcb6643816b99a1f4cd71a4203f5546a9b8c5e0c3184c9922513a4ae62b7892a9febd425b65f831c2dd11c0dcdad8add340a2b16e2ee241d61141430b951047878ad4d1fc97bd9633744c64c3932f4227f2cab0310548bbbf909b87701aaf4a4f7f073c0ae501d051a6f1743a864ceb503f1955c68f14571719cbc9a1a5df223e8f18b0c2aeb0a7ed3886e89bef947cb461fd3d8a60f0128b7fb23ab7d06eb9dde4f14cc5c2856f5e8dfb03660863c8796f5e4dbdad12c92c4807bcc0085a026d7a737b51217abda524b206f9826d9a048aef3661f50d096a322c4e6cda480dd1ee52ea3f6a422b550052bf5b38e12417f005604df8200a18ea221992810295c8e868c8a1180ab39b99356052050bb3e3da9912cf62245e1405798416603a797b9e64b1f6a3b6a1f3c012bea14c33c14c9de21f0db3577890db35ddf9951b35a98dce01576304a61ce0598d1d8354e9cbeee3052d7ab1b12dbf36fd2979d14a5486cd4e0632fdcdc262fd2e4e143208d2bc139e4904b4b5142155552b16637bc9b9e727a9d5e1609fcbb7c834d09af01dd3c72a8698688343341fc28f4de9e77e0c1eccfa82cf4095a3cd504c367af9d7f23e9ddbc42c646f1595534a1fed37bd8bdbe200083fab4d3c0c59484bb6df5065f66a4f2dc82cf771626096599a9c83af8f8dc553a7af4f9a4ac71215c0944296f2d0da8bd75dd5f6922b53320e217cddb22b1e3581d075cbceaece5a23511cf9729ecc49aa6dc14db75cc9088404f5a949752a46df7e1814ec0ddcac261f84df76159c66912316aa24c4a9d12dffbb3ae69d700975210cf3102ad8d33b2130886c104df8e885e18257c64f44c4d31100d2b123bf1ea95999389d2e72f72f2b9400c632610367b08f8ae2c97dc9f7000ae3a8b4962791da09ce371dd6103c5523935d9db9fee6b0330fb135c9227423dde2d950850717ca67d2d8579a2942adee5d6665b483a6f19a78cfd10270508909a2e318d6af860e9ad9465cacd82c57ab396648efe6c06caca38f6a8b22c7e1b1a35a8464a78d35159b78ab8513077d2f4f89d62d692cd87fdd0d29f38fdbb8324bc3274f98977113162fcd522d2618798b2a7f1cf691604a1b8801dfa730808e975fcc90485505112c601ecab035ed95a44fff83144b7030a33cfa35110382c291d3d54d9ce12a6a23b6afa87c752eba0cde3a6a6962875fb9b5a375535d9a9ee7382e3b9178e474f7259604d3be3f37beeceb82bd378fc3ac346be15bbdd8cb359b209d932edbdf7de52a624032d0ad90ac709b18718197e5c4dd08a48ac7e5a24bd2bcb02cf67dec3c76730bc56c3a3e99f6fb59fc1200ee438b072f61a48b3d904d066cd71def9a669524a29a594daac50b4d7c050ca779d7f40407c9d7746997326641950611610bba863de51924c30a88b020589e69c1f89df793f7b310e615ff7149c9953a7ed18872473b0073679f8a861b3b70fc85d449db36799ac50b4cf406de3886ddf48dd091df8cdb2ab9b14eaeae40fb8a53cb7d1b0e533488b85a66331c846a1e911fc64e4581fbba6e6610bdb343082340eadfb1c588cc1c20b172f5cbcac091307282e6d160eb224243d85a62ffcbeeffbb68ede376e9a8d3768a2f8f9c3157abe078fa997eef113923b86834c5fdf332a4cf9c21d03543f29247d4b01cf17f278c983254b9649579c218a578c79e9736367973c32654ac79d60ca0e30b06b8f8e360e7172c4ae9d9e1d755c05815df207bb2483442a54f1858e61e0501c921be843663ee290f414ac704c4e303af668391f46a7cd55c40a382f5d04124a686fc105762de61ae8820b2ce402bba4831cc8f2491984bac4381264100fec40097011058b486e5b2106a7c5a236212e3b1bcf2c7a5a81a4c733d2230e496fd264723e1d85e9da9a991e3d13a68bd9a494eee3c7a41886f9acdb06ba56a8f2651ebaa4f4946c8cd3230ec9cdc7a453c598afc24b90585405d36a2391f851e9c8b54a59bee95ad22afdf8e103ab3f263338b7134ec0a66b4f60d766d864e70de9f7c9c52ee9a16bc61e729edd67029be7efe3ec1b878849da8a5a47ab4261e963573d3912410410445815e97c82ec70666fae2870c00521428884508dc5f28d83ec7016cb9ba5390a583e966f4c5860131f3e7e7e7ebc07bb7cfc3837d9198c580927b06b7deaa4ecf2719742d2811ccbc79ec9fd1f312ddf517fb050cb49ab728085a4af3bd272805d92c116983e222924fdabab1a8230151285312adad976ce03fd463812d88a885278faa48744cf1b131dfde949ca27a79772a6b0c6170ad1187405e15cba0f76495fe20303c9f8844ac442d289240925843e5efaac21ade293dbe745b5d102390fd50238ab7eba469a6b1e1ec9cca54723f97948b017626e609b3b1f02b5916a137e6c981e836293f498f7701a83ad6a78a72d992fd31be9fc63209d639a6fd873669aaf77643af5d6c69ee6ad9e59e6c9229cf56cf5f065debd20df6882119c5d07729fb7a623b3e03c614e2f443763249d04122c8100cef8e8b4a58a95e1c33e3a6d71f3ebea08e70c998f505ae0f98f5070c67c848233e5430ae7cb731fa1e06cf905370067498532be75da851651f423941671a0d660795e9e4fb841a26ed069da02836a6a0a4292b14b2ed154869bb87c6cd2d2a4e44c70989c3edccd474a6e1c37ad8f504f9c717ec2cb135b3e423d91f433d5434ac5f93e42a981e2d7b7b5414dd3472835653e6c7d641af33b3e42a9c9f2db03cbb04c0dd287112a4d969ffa100652b2e6c41863a6d1b8fb264d1ba83465b2283c4adac640c0aeeb3cc6b8d5e098949d945de7b30903d1bc7326364c973d5e769d6ab5f28060d1bbc5306f22eafd23141352df926a55ce0eebe4ecee0683a81bb5b35329dfd570cb36d6c9aeceb92ae5b77a24b35a4462441b958e4b3f201e989c12939bc496a3569398bb3c3a77e3c7e55927ad941fc3beab733ed61dd6ddeef42cd3344dcade994646c30f88c7ac733b58ef88bd144ceecfc9d84bf0db5686515252b221696d505aa51f98484949d1896242476a0bf69b13fa430b2db010e7b0d0420b5c4cecc7fe600f883c60fef163c2e124206ee22656c34c9cc46ab8899bd02c2d53c68435816168b689658a980f4e5ce4f9b0c747272de4387181e7d95d70640c3cc038c41e87d83735beb0c7ef165f7c2165f985f3c51712d287f1a904125aec52e38b1bc123f137161121fee6d8d648243efb00e2901b3ec2b182020d5fb8853d1e7320c79c82d49b50ead499504aa53e8c6e9994a6699ee7f991f81e18a47223cfa57b2e5d456b57b71aaaaa5727bb689775f5483eb7d530c2c1ca74fcd19401dd294cf9a201e040adb9b3c6698d124c4a4c5ba0d67c7942cf1370a441628ac1339df9703f32b5f1e1f6cf64077b09c514f5118aa94e1a2e6976d85a845d22380a367c617c622212f6ccb7c317027dd4e23f09b6d8c514882f04d2d3abce2905690e1fa5e00624a953b047d217f608e31390cba31f7dea93e953ead333428178b4a4c81d3b5a985782945d4ac1d8254951d1e79caa7efc88ca7f5ccad31a4a89433e43ac23abcfa3475d73560d375a833e10c9caa7af38ead9fe7a4868c6791109ca6d8b93b6964bc209fd2a2545278a099d959272e345893367a2be576078249769d16c13cbb44c6b5acf7d500423d419a78f5067e27c2b0173cea9c337cfa823159f4478b3a78d8a0ad5146cdc75829c366cdc1506184e6813a9a830c0c0304c0a738a61d8d3761e1df3f143c9e6f388e6b1db5a5c15418299c4c2c81335e75c33e7dc68af5a5b7d346197d41b483c7d08443f2498a2887e4c1702c403888839f3d6fc6411516238e1e1e3071d748e88a2ec1f6fe1d1fce8444ac015c2aee8c475409d613aa20c9d617ece39e79c330c9144830b94993bad337e429991fa39897ec8f08542bc07108fb8a540e5dbb8d104f6f55674c6d874ec01c37a9442118a0c17ae80f409c2b07117ccb7f2daa7cf5f695c4717210ed96c732206b2f2e8f9ca35cfc8eadbd5ae360e1c6fe59eab3cf38ca856ad6a55922ec22e26ed791ba11e47390a0af9c1b573dee091ec38cdb5b9f48c6c1c385f6be95ab6daac05ecdb23853abed0f5aec99e916e23e408b1f3d30827333e04e1a7d46394824124c4a77e243e05833c370257787d4148a8bbe735dc4e10d2d7bc1ad9d54e375931efaa94e7ea91fc0d738dc9745aa39fa2b8221c6416316120f17fc4ed2cf3f1314a297d69d5a4a67dcff7adc6e7b19e91f6d8ed5b67cfd8267c4e9d3d239452efba790947128967647359e7b6377d33a5ecc012be639a75a01895cb202af0070bb11791323efd0f37df8fe7cd73a6ce9cb7875b771ef8835d14047645cc29280251cbc79624c32618b5c54a8534be4d014bcf7916c7cbd78f502ed0f32eb8c3851c2f9c30ac0ca8173861679ed31c7331102830bc0a416831fa7e0c8f24a639e640aed56dd36ae889e97c862b884a3c241cb8b9e61d9790f95aeb699e0a23384107aec04c067ec07119c8812d766915a849c3649c33cead18b821654b44afc72d4e7093b22c583ea123439d190375c64b1c5b98be8c79fa62074c929ca4707ec9d3e9b9f3d1b931bc3833e85378f309c1f403f80825c4d36b92c7b36b60644f8974f618bd24d2c56c2bd070c408fcd499c91c5fb8fdb6641e71c846d1f4a79179c6373fbeece87929a5cb1566f8a6c7a8979b4bb952ded012d08a36df0c93425bd58abaa5cb07089f56b4814cf47cd335e9a1f7b0f34d30dc582b8abec9e82b7b20e24584d3cf8d1ad9d805cec9ae237387ee2518b703f62563600b2485315f38dde92314982d1f6e4a288f38643f0b3c3dba4c0122cfb3b7e212e12fdb20310e59ecb3faf9ac107360e5c330df2e4e5d98661c9a990aa8953445aed0f48e3a8f870a028e2a2a88a7acf61801ec4159663f4347de90fe06d3843c1dfd75c3180af5ec40777ece6cc53d8dd52845d04d7d1f5f39dcf051a08fad8ff195c314d6c79715a9232c4e58dec868263ebd96e6bc96baf8c5e28baf25367abc3b31eeae8c4861b030edeeaecce2852589179632df62d7bcb2b9716a00083e9e3ebe969280ba3a5aaf1ccacc570e4b2f2b6fbc10101a1087bc96cebc0f06e23fe636256cb578f4e0f2216d7d38993ee4f1e17c2d7979e510e7432249e775e5cdebca1c20f98a618b967199a6f9b67d72398ee334e7bcc581234837c2b275ec5fd3a4672493124b92a6638f703a8519f39ab7c645d3344dd362d05c6097e624bcd1344dd3b8cc63e621f693a90c4f3190709e79cd359f671808e79a4f347c4773c6c340f8b533413c0fbb34b9539b8785348f532c012f5f283df390efd0c6e8f621f6f1a3cfce329ffc1d3dcd5308f385f4b527e99b67f5c89dd2988ed881f6f3f3e14e2deb89439ac3f14d0ff94e06a270c4b739691e12e998568681480c5c3245d8d1acca05194f1c8ae30b778a91d8a53956790abb342f22398d93360f07613c2ca4b9e63bc5406a88442495d881e61a0df98e26a7c421cdefbcf14d305cbef35ae4384076ce6bd3f70905335f36bb305e54b27cb8bda828c9181e4dae89ba8f1e7a8c43e1f4cd7f08e9e16a71cc41488c42cca387d3e311f62c033129c180a2a3098a0e25cc330ed2fb5df804fbbabacf423e8338e79e1ccd168e2657e18568090f7a96f49c818a43e9c763b94fb3aacab9faadb3f44c79966f80678ea887ca23e7034328dfbf10f4ed9f679e121f6781212b88821090f2cdfafc7396732c57d5907af415abb258cef97495fb38ab864f9ee5996702170401294ffd033ff72181945f812510c05330a8dd88824fdec77d3ca42c9f1afab80fc8028d3c5f81461b38eb68fa80479303c3a3c9627ddfcfcfcfe72c6fd6cfcf8f8fb3e88f8fb37e7e7ce8cfc7fdb0582c168bb584071fdff7f1eff3f5efabeda3e7cefbf808a5c7e97b3d13b6bd7daa6a7d9b03ce6fde9f470ec2c383fcfb7ce53c6a64964766b1bc886455cfbf1a1e4deae3e3e3e33e55b51e04a4f8f8f8fcf857a9b3aaf44888ff39fd9cfae7d457fe03c3b3bc88f4a9fc2c1f12e207f9b80fb8c2eb73d0f3a3d9e3c984a2edd9b307cf1f49d51468669c579595d7a1e7a77b345aafe3ce875f1d52df0ab78f1bf5ea98f32d76a5e9254b0c64dbddf51f67192ee8235991c562adfbfcd4f0c90af40137f04786797225a7fbf8f06a5bad563edb6a864f7ca4cface37e346d5bcfdbc2275a33338be59f8f872cf77c556b6cfd78387dbc35dfc7270359f90fc872cf49ebd9b7276fe4b94a057a747215a8f2f01e2e1f44ec92e2c31d13b4c54030ec7f0b82e4f90c5e445d7af7e6bb65ce99779c71e75445330d46d9765acd64ced1a715c94cf64d397ae694b3f4734a4ca57911ce3c231dd771200f764df70d1c017b0dec1187a6afaf30e5c33c046ab18b7eecc2269c9ede737ac8636a98b66d1cc0d8c949d334ac72407b0d6c81cd3725b7208488c8e5728f8a6292e7c3306ceff0988c35d1b1c746f493721097149ad8f3f08e64bf094d9f18066271b52902bb36b0880e5f368d1461d774169a727cdacc66b6fdc6373fd73096afb55d7c8b4ee5f3409723b013b8eba16bc6f785304ccd3338c61aa21b77dc9003e5061400f808e5469839e7dcb82c5996719d1b4878e2b66d5db711d5c69baeebbaa66d34b581266e4148b687b27b56f05b171b17aa8d30506d0001d5060edf9ac37ae292a03f4ca980c6d7fa80b68ffefc80beedcb8881e79b2595cd8e6bf97c91259bdbfd40356573bb969b6c02ed8052ca00ea8e065061805e6f36f862eae3e0a587067d3167290fa838dc960180cb47a000a011c00b89bed3ac46a82fca7ce43ecf885ca93c3a55dd7119b769d95461de32c3a69c2accb3a83c514ddf1ba7e4c554714e8f9e8541b39332688249883e48fa0c926012c979be98c55834b7c88ac86d9baf96aff3dd4561862f6c4921b9ed6e4bd337072479113b8039ef5de255819dfa04d8a9368994a0ba98e22ea63c73b303d62357141784e183c872f4b68161679aafd0f4c4c598f72617505c20bd6b3ef38c8025c17cf3173e20e583309fce350863300873f9d3b5e841189844fe0489e4988ebe176812df4c21c44b43a4844b23e39b104058972fdbb2bd61c5690b9a37aa3069720138a4621c14dc7c719ebd156e3d22d00fa90f81de98fad0913e7465f99028cc8742d07c189ddc7c189fe088f3619c78ead835384a6e31a3c096c8c2682b2d1b1b3570948eaedb685a06ed2f3c2f0b151ea7151e253e3c61587876f0c163c38f9e961a3ba2325071a1c114406a363882030a2648cbb7b6ae9104003d01c0230029a7726a9705d8520c604d0f2708904401c818600857168490b6e5009d1504a831838fad8e212d8e04b0d1419606514729e0e5419c0564f1e3e9832880644d4134268474641820c490ed07225a1610ac34204b72000ca884204711375ebb5354c603b22811b02f8c645d8c90c5112a487042a2a581c01249cc9490893181eb12812d4a322c27dc20813b4813a083021a1c28e04921434305acce924c0c267256d8a20256584093a2c99a0b38c142960406b8312d80c940c645033c6c000b0770e8409207d2a8f2813a5c880108a6c2358cd0705227045894085e2388f3240b284f51a22041d3511325c8cebc40c604181127f082021f529045055660485a011a31b0408f1438a66478a8a4110356469533a290ce80f324c3194c332c9d51868633b8e8b0499a520d6720d96067cace0d9c184a5ee0b06961658a1cd62cc191c3a1b9b295c162878b9d2b3ad8a1210b1d5adcd86ac6193c88b1a5eba207ee8d0f5d143f7069b8240144115dbe04b1f5e025872f66c800660e213a36c2d819821383882ec474578c89a2082e8d114a902153268c9932b2684a4794516522b1c5963a726cad33b5b50e1e25a496985168681c26dc28d1049c3c75c63851674b9d2a4c76f2701a293b52ac460a8e145ba5989aa4c66841acf1b0b0d96c682355c549d303c51db61345941472b6aed217a1c8782283cdaf5321675a053b2fa438cccc7b81de183be84e810a48d491b95590e18b1eb5a8450cc3b0a4ac22611812866559966172b08ca5e40fe8e3343eec0a9665485986a940db36243359a619c92ad0d7da2aa8a6fdfca47c5ffc584b86615926264aa1e92da01610500ba8f5b1184ee3b4edb9ba45bdd539b76ddbb6f87152c4300cc3a246d9f599d18e51ccb32dcbc0b96d73fb607a51f46f4e73948b1c076efcc1f42f9a2ce95b56a704e79c9b44471964a327a323691a08c41fccff5a5b45631e6b2b6a240c035bfcc194405268b6f883e9add1de9869aac9a252a8284a566bd7b9cc186f564995c5186e9cb08bc188fa211fa1e6b40903ce47a8309c7e011fa1e628bd0beb06f8f852c389b37c18edb0186228ed8e8943b00de3cc7318639eddc95477f83db665bb2bbf08bb78128db0cff219a48149e4af8f303f68ddd915b46012f927fcfcd09164d174d8b07057baa50f5d053cdf2a870f9d36d775ac0a55f098b76af5b9a0021a5f18edbc99e9ec2e8811356665e5d9778981442831e49c40066122859688511cc240e636c58876c76d5a16555e0854e10b2f3d0e3d9142ec4c629eb9c34bd085ed608cef041e7148a460b8e82032bc7c842203896f1d60e372aa37eb719ae2307d387f3b884e372ece19563ae3898c2532a84ce559e14c2766ca8e9ca92726b951b40a4ebb3be5dc2269a2d9dd9dd854980c0829a5c4323b535bb24c9b4a72638fc6d42ab0f181e2d21803cf1874a6e80f9b0e749ee0d003471b2a359ad2187ae824410016b440f3411fa1b4d8f24e1ffa673c5c0c2463da2cf2ac360fdf2ed0aef18b6f10d0aef1f51dd2ae11eadb88768d72be9dd0aed18bef10d0aef105df22a05d6317df23a05d639cef27b46b74c13714da3572f11d85768d5b7c9380768d70be8f68d7a8c5770968d798c5f70bb46bc4e2db04b46b7cf37d02da355ef18d02da355af19d02da3556f1ad02da353e7dc340bb462abe5740bbc629be5940bbc6167c4ba15da39bef9d42bb4629be970aed1aa3f8de1868d708c5f756a15da353d710be5706dad5015d1bf043283979484c0005e703ed2ae4698dd1156a60784a9cbc243f6c1b4ac6271dc8d35a820dfe6883a72ed9482eb4eb074fd90041bbfe78ca86cd049105125e68d7c522892fb42b8f25c0d0ae41cf041d2168570ec43841270cedba81983443d0ae407486a0402fe6092268570ddeabac38b4820c2bc63bb2afe22875558da2f2234aa9d7647823485f791149abf6aaba92ae1aa26b06dfab8576ddf1bd3bd0aead6f76aa6304edfa138511748bf0cd2377f19464aef29665ecbaa953867665c93153702a33b4ebf7aa223cafb6a0be5539575baa541ed71ce72bbae23c738e7baa7304edbaeaaafae62bca3843bb523158949104edda62ba76df0c6709da95e3020dedba711cbabb5c475955bebbbcdc9ae18d20dd5bf72413b4abf611e41de32959216857ec5b3a11361116af229c98e80e4c1b668558300b068f200e7677777793d8b46cb129970c0f2199768f8af3a01a8bf60c71da80578d35cd98771d6b9aa44ea7d1f4aef3aeb9769d791e333bf522520b4a8271579959a3cc75365dcf487cf66570c918df3ae79af48c3033c62c59738cb94d6325c93cb1e952f29c55dbd69040cf6cce8ed2e8f39bf1c39c9a60c439c66595db6a94cd8f6636676b5c9679b775599629d96496b961e648da1c4733ccbdae9d1645f3234e7294f3224cb7764f7bad4e6f4ecbdceb2c32108e9feba65cc765d8469dabda77d3f6224c6b8c3e42ceb58ce33c28c9e4b8cc356e629ac4c04dceb77d7c8571c16f53a6605c74e63d31954f06e269ed717a90a6791e5f442ca9f1f1266b8728405af90c66a084f09a57897b8a3e6fe94d20162599a9b27b4a10f255339ef4ad3b6f04e92a14fcaa56897b8a56ae929eb9acb27b8acc68608c3ee4363d48cacea398ff7c7c8571fae8ad0aa777beaa66bc8ee2a9bcb1ae53b5977999f432e97d71689f735aa3d0f6f6ba5554c5a293812c09a2d3739d3bbd9452252595526a320329656e4b2ff1e29bcc72e364c7cd6dcbea922e82e6dcba2e79c1a7f9b6daf30a7386a377db9cd3f3cee6364b00f44740ef8152cea0249b9c9c922dcc403ac964207d390847c9a92814c1e88942b10242c41085e287aacf2088b85a12e79b724ec960de7cf4a42a8a7d6320063aa17773d73705cc1ca9f22269dbecbc8278ca34adebbaaee3eac66d59b64b313e9321bef508cef9444bf9c5699774b1adf678717a8199d2464bf9fab2e44bf680310eb9e40f26587ccd7159aa8290f04f977130d9e28b2f2f715e5ee0bccf396f643b4b76a3c96d9cd434e6dddd5522c18dc119372e2eb76d522ed9f349cfb08a6572825382dbe693f38e7fceb9648e6f4e599138d00c2f79d298bbd29f080b425c42057789eab2058d3b75b2f899711ca7699aa67191779bd9cb87392f2f5330cd8b92b78969345b4285966993c37c623830785e4034015166b5e7d52529cb0bcc99d51e2636cc38447a648204f2f0d5922ebef5027c7cf930e7e7c6ae257bbee998120f3efce2f4e858ac05f88d33d6a0e73863055fcea9a9b8235dde626f40dfde8540f5487c15f5e845604e074395ca8fc45781419d1ba93cf34ee599abc0cda34bf9eebc885c2740bf49e9e5391ef31d6e7a4a358d638d63354d0c84bba331c773876f3288901f1683deb26bdcb26bfce455a395b3e05972eb1ee71e079ab71ab0f415b3b7924dbfce01181eb1c66b247de5ecab498181338e9d9f8c7678cc494c4b845d63276ee70ee72366359e87929b3e73ea1ec77928418ee338038ee3768773fde115c86aa42f18b41202e41b20e19c9938cf0b839a5ee33ccd5d0611b20190b79cd58441e011bfe71c68ec710086acc46ee45166d50620104829df91ab558d2fa5dcb1ec9a77648706957a0655e55cb3ce5ae00f186e200bec7cbfddf53e56c34a2b5e81469c6beed1f5bcd009d07eace60383365f49f73c64a55f812b347d4e9c00515785aca48121e629a1984729e43156e3d43989d52c116eea3856b31d641aac0650739b1ba6a9b6d958949aef71dbb64d3fe2c7b26de338a3230f9608e7730bdb2905bbccc306335fdf0e3ce270122d916d863f360cdb9c68c33cf8c14036c6364c7224c2c2e8f4461db6c2889608e699900f7d7ce315689479b7f26089b06fbbeab21fbf65de39966d6050e79c4f0cc38836e61f1fb29cf3a6de91f6058d38f7206481dd981bb11a730f9608068624e0b8289575599675bcd8e6b3ae7f95f355a58ed5393dc0547533d21cf30e0c8fd8f3c0a0cc399f1e2c11cca773c039c5bc6bb0f360892c1876ce71eec11289cffdf83a3ffe6b9af6da6718e8c17630575cfc34b68eed7a635ac779b8497e7a28f3fef1c543139727faf8da72e77928f308f8f8d2a2c707a4a7efe3d9d2cb87372f1fb2bc7a907af5d0f4ea612a46fdfc5651ac7e1dc735316ac9715dc749d068b328169648a8712a578121e72a8cd7b59073ac5bb91cc84d9608e7ddfc8ccbbac9724b1997b5141858d0447235d29c05bf59963559229973947a1f76e91cd57cb51cd1fb80a18f73b2e5a18feff050fa0eae056a1efa80a10459d80ef6998b4db8503ae6957a477c7c41a3ce5990deca4009eed8215b9d0ffdcc595822d9e619e996340d493f56d759b5f395e759d7f82c2c914ff34ffbf190ba8f872bf70143a2ff5860e621f5f590825f38ff038334ef1c6321a4de39185270e5a1afc0703ee62a0f3c625e1658e89c8525d2453d0bdb01064629ac65d9d1f246ea9565eaa5c5cb86458e0e5326d06b30de0d84c0cb6453a2680b924cb139412fd3316600067e991e24e354e2598b980662644f036d3c7a190821035750f315891a08e14b96d536552237a3739b27c1e015692ea5a828abd3370d4cfa5114bd0873b04904ac63b54d15cd659052b4f986f96abe711b075659ed29dac0a41f451ab80603bdb4410a618d3d7bf654f109b681414a91122ba2cd346950a6974000cfbeb5a4927f4a8cf1019bb14ff0053933ca1e14de6a1b0f02529e5dab31c6f8804c4b93361e3d0b843025c6076ce00a667c4562116e12820edb56d940612cf365c7e4dc6ae692336f0e281f605dab6ca0482781949f4e355fe9139b2f68f0126cd2402c6ca2c838f6ecd9f350d8302826fa0ae6340b58b082f575ad7d7de952c6c2058b9617162534af2b637677625bf8e36be90d29259625b1f15acab3748767e0f2d257d33bf2d8c223e98aec25911354e1cb27c1d049d44b29ead7b7bde25749ceafcf9db1d50269cb0a05a5b762308f1e0a4f6038c10acc489ffcc10ce174cf3b7422823dd375b9781e15284aa1d0b5e8aedcf48d24891772b4ae0c78551503000080310abdf60b09d4f9e6501a8618514b788c15968e0522191758290cc43a1990656c80cde880b4f3813340808611a711823b23581840518304718d12e031c1b28182365410dd58819c92c26f50915b45061a6ab801871caed4d1c5d7defaf82aa287efd5c2c3528ec183c07afdc24ab542f2ba78a1817aafaa6278380036a841b5ca131e608b85d8e9121142c0b37300bae2107f5f7c420c21a6882583436665e6f0aa28acd801fb11d0ffc421feee744fa179a389858329c6a166f334c518b0917238ed1c51e871b3744c11eb78dadd63459cf24652c922063855968b45da3851867dc1ceb072220dfb92493b876bd8306cd8a8bd61e944a5955a1cb68c6865edc81c160d5eda3b57568dc513dbd8a90887dc3cbc72f0ead93aa20f3c657fe0182217469240ccc05d9238081bd68b52fc6205cc92108c250c67198277602278cb8af1218ee1b245748946789164c07099304cc48e89466c9978843cc3ac848724f366c2095e2436420ea644a5f21628a59b3403553d00cbc640eab0737096a5436ad93dbc0395e5a14adc22430f34b00f35ec0f37443569989c688209344b2891c419248e3053e6bff05bb1562a1f95f7e3d116ed1ddd65d0711a6419976d401ad5322dc336c0e8e4a0bb254725e522b6ceabeb110c4a62e431196a94b9e7649e83ba8138c4be41e540ed401c62a7d50371881da87e200eb16b505d8843ec195410c421f61dad9feaa486200eb1b3aa085a8843ecab9a8138c43e8238e403571a8843389037101d90045484348317998992fdd25f9f7168ddcc11d0cb0fc4201f84fdeb66a24439fafe08e8d7a31c6dcfdec212195a8f7168413341cc23be482484e033436c1262a212452c41068d192690682209279690bf5b9989a96566993a4c2cf3ca3737d1ae73e99bd7d0ae33876f6643bb4e2bdfdc86769d387cb313ed3a95be190ada75def0cd51d0aed3866f9682769d357cb31bda75267d730b68d749c3374f41bbce19be990ada75caf0cd4fb4eb44fae62a68d759e5670c93ca37bfa9e39bb1a0e39bb3d0f3cd5accf1cd70e4f8e62d62f0cd5ce4f96617c4f1cd71e0f8e62edef8e6174c7db3176e7cb39c36be198a8d6f7ee1f9e62fd6f8e6396a7c331830f8e630ee7cb318667c735419df3c469d6fa623f5cd6490f1cd5274beb9ce18df5c46d4379b21c637db09e39bcf00e39bd190f3cd6978f1cd775ef0cd30e8e29bd5a05db9ce37af41bbb2d437e3a15d998c6f668376653adfdc06edca637cb31bb42b477df3549c6f7ec305df0c0717df1cc716df9c07ce37c7408b6fcee29bb1f8e637df7cc5375bf1cd557ccba76f49c5b794537c4bd9826f29dd7c4b29c5b794517c4b09c5b7944edf52b6f9966cbee50db4ab5cf32d956857d9f42d71a05de513dfd20aed2ad57ccb1c685799e65b2ed1ae92e95b5ea15da513df120bed2a9bf8963ad0ae92896f9985769568bea516da552ef12d77a05da512df9207da5526f12db7d0aef2ccb7ec817695665e967949e6a5112f8bf8965d685739e6a51849c4cb215e867999c64b212418f9e55b8aa15da5976f39867695417ccb226857d9e52510df920ced2ae50fd287973d7c4b246857b9e5250f2f77f8964ad0ae52cbcb2c2f759058be6513b4abbcd2552e7d4b26da5522f12dd3d0aef2886fa9867695397ccb27685769e55b36d1ae12876fb9867695687c4b36b4ab54fa966d685779c3b774a25da50ddf120ada55d6f02da3a05de519df520ada55daf9966e685799f42d5b40bb4a1abee514b4ab9ce15b5241bb4a19bee513ed2a91be570eda5556f9de39685719c3f7eaa15d2595efa583769553beb70eda55cef9de3db4abfce29ba7d0aef2f5cd54685709f5cd31d0aebce79babd0ae5cc73723d1ae4cc737cb40bbb29e6f9e8176e539be9906da95e5f8e624da9563f0cd35d0661b6857b9e79b6fa05d39cf372bd1ae1cc737e340bb321cdf6c8576e537be3907da95a7be7989766537bef90aedca6d7c3316da95d9f8661d6857c6f3cd5968575ee39bb5d0aeac465786c1f39dae9c465746a32b9ff1cd3fd0ae6ce79bb9d0ae6cc6370341bb7219dfdc85766531be3908da95c3e8ca607cf317da95e774e52fbe5908da955f5d19ea9b87a05d594e57f6a22bbfa02b77d195e37cb311b42bbba02b73d195b7f86633b42bc3f9e6236857d6e29b91a05d398b6f3e43bb3216df9c04edca6fbe5909da95aff8e6256857b6e29bd1d0ae5cc5373341bbf2d3373741bb3215dfec04edca537c3313edca2df8e634b42bbbf96635b42b4bf1cd4fd0ae1cc5f7c4c10ae7b034af60611db24c2d3bf0b06de961fa40d75b3c1e928ff7b015b42b43f1cd57d0aeecf4cd6f68576ef3cd58d0aecce69bb3a05d79cdf70c826ef5e4bce299e0797667a73c244fde7ba327181ae12cd3361991b4b4c5fcc2ab727ee24ff05040697b92aa64910d3b5c61821b78a8e205a52d549400871e7697bd56adacf8d0710b79c4658b2857e41b1200f1060a9609274a17384f74c0b48012841623c8e2e58aefa2f0a045b3e2c9172b44b003982abea1f4c003f73402219e42b0250c154f9ffcd04337dde54430c4144f3d27bd3e10d182f7a4c811789e47849b6f1623c5378f89e29b8b80e29b8d60326dbeb90c5d2d9b18a5f2422afea8385ff32dc8dd6541520fecbc893702e59a52e7e82a35e90a42114f49e65d89fc90d768d76dfade68d77de29ba35d57cd7747bb6e9aefa65d97e99bd2aeebc4b747bb6e13df2ada7599f85ed1ae8be6fba35d77896f16edba4a7cfbd0ae9bc4f70fedba67be5bb4eb22f1bd8376dd23be33a05dd7ccb706b4eb96f906a25d97ccf706b4eb1af1cd01edba457c07d1ae3be69b07edba62be0140bb2e11df01a05d77886f01d0ae1be6db69d715e2bbd2ae0be61ba45df7cbf70068d7f5f2dd8376dd20be0940bb6e97ef02d0ae0bc4b70168d7e5f2eda25df7876f21da757df83e00edba3d7c238076dd2ddf3e68d7e5e17b8876dd1dbe1340bbae96ef0e68d7cdf24d44bbae0edf0aa05d17cbb707b4eb5ef95e00edba4bdf3f68d7cde1fb03da75ad7c03a15d1787ef20b4eb2a7d0ba15df7866f06d0ae6bc3f710da756bf82642bb6ed23708b4ebd2f0dd00da7567f87600edba327c8740bb2ed27711da75ab7c3fedba317c17d1ae4be5fb01b4eb4ef91681768d7bbe8dd0aeb18eef1168d748c7f711da35eaf92681768d737c23a15da31cdf10a05d630cbe93d0ae31cf7709b46b8ce3db04da35c2f11d01da35bef1ad84768d53df27d0aed18d6f09d0aeb18def09d0ae918d6f0ad0ae11cf370ab46b5ce33b05da35aaf1ad02ed1a61f0bd84768d77be99d0ae318def1568d788c6770568d778c6b70568d768e7bb09ed1acdf8be00ed1acbf86681768d75be3140bb46a9ef1668d748c6770668d748e75b03b46b1ce37b03b46b8cfae600ed1ac5f8ee00ed1ac3f8f600ed1ac1f8fe00ed1ae704a10ea814ec582a631c2a3422020000001000001316000018100a064402714018e7a128b70f14001077885270509ec8023990e3300ae2388818638031c418831080199219190480b1405a1a38666e41a623b341afb10d99edf763787161538e975fdfaf633a22062b834ff782b15980e69af69f7786dcf9fe9a8e5e8977c17eea7b03c6a379366a833454f075c8ad8c9c0de8f49636d95279cca1be6f2ceedc5e19debdae6f00b7744979ceadeeefc8e6aa50ba523e4fc8f1b7fa7f90975f29cb2364ec51fd5fc84bf794e58e765dfc8da73839c4d384457eabb551dd4d40db19dae33fac1d31b31b70dfc13b8c627ec968024d259938836fe7a98706a046f567c123ee2674968eaccd4bdb4389e78cace562817234cb767f68aeb52edd46624a1f7ea640af01a16311e5d76ec941828e262ad495d439838137c8a6faa0f98a99e9407e64ed00b13701a74f82f0c18b45919a759a63a842b392c6a954bad69efb79683c5a75a9f6f141d4c32727bd0738eb26c2a0abbdb86897a77820857f04e19b51b3ab6aa3a8b4150ba3ba642fea005ec38d18cdda4fa439ab6d7342daae98e9fc5803b0d15c775f15b9973731cf72b02a9f052d8c2515f42b85a73b98d063b082add5979cd972cb81ada9cd18cb6ad4fa477ccc835ef131cbc4912f674bd0f3b2d2a1386751557e0ea2100b8d60c1101c0ac1412114123f709a4124e470ed4eb6ddaf467df7b07f8bbbf7c2732fbeee83eb7e420b2e646effc5631efe129777d07fc4f1f18444f9bcbb4823eb8364060846c143cf1b9ee526844cfc7c27afffe917d64de92407b478dbe286eed8c03d754a7a8dc8cc60101deb01b065dcd34ca19831431f73fdaa5726b52552b7dfbce9edace5b42cc4ef83d0a830c2cc22caa89ee9318afe7ce21629024c6c2af96176c68c52032ee12449c3560c1a53c5692e887d86f2a4365f42f3640fd8316244e50195252d12f6949a6f17b2db8a32468d6183e73a6e748755c0095329a8c52e2abe9d261179d2048442f2caa181863ab010ce7215cda5344c4cc9bfc18912a452e116517161bdf60bb51277a6bc07333710c87499b11f8d468c250835b19e1ee4760a751ded7aea43b4834b929b73a0ce84e7404a835ed0deeb4093cb0b0abdad9870076052405bfed276b5be3ec309359e51f603653ee1b6733b783bc812f816f8b2610c162c63d86dbc3d6d13180d9094fa47584c2b1a3ee5704d96e580d23f98a1ce39d9ef3df9c1ef3de903ef3de103ef3ff183ef7bf203ef7bf283de7fe283de7fd207df7bd207dff7e407def7e407debefed5ef1efcbe27ee2c7469147d917b8b4a0f4604bdefc90f7aff893d704219dac405feed0602f81e146858854877088e8913c8223da6679558326159ce2ee3a8b0468c8089a77c1f21c5fe4d3116a4854e66988d7bb3d9dea573cbcdf4fc57020582e1c142af4a4a8cca570b20c4e9e6d4ec6236ca8ec996e2bd388836b2eb3f5ffabf3842ff77e7f08fadf625d6c8aed61402730df2079bc7b247b13dbe19cceaf8ca344be323c32c8fcd8cb36c6c331f4b701dbb5426914ebbfc85833d0ca1a33d49dc1bb2d9c7578b4c20a205f415d39b6d144bcf2f1a07281a054b1574120206cbf7fd2ae1da3a0b57affaa10c215bcfab2b3088481a93e077c6647c122be534267094b4f7f32b29fa4a8a7b622c2532bc71a4ef787aa3ec7c908a0c1713d09ab8a9e471d139fb4305af98ef580a04fd7c2653c6035d5adf3525538d893292e9ad642f238b9a9abfc984bb569620be374a767636ef9a8aacb5a81c9191cf26d4d30f188ee0a81313f16a7ed1a923fe881793feba3d80a73ec111476cf2f57eea714d09e8559db564010974a5eaa716328c544a60afd5ad25058e802fbd3e5d1cc3dc5207f6b67574017a28d9b1938b4b822e83064eb2b784f361ccc97fcdd1b19803445a3bb697610447cb7fd603468fb6f068ee39335359885619c2782e2343b182158c011ca0749d823d51e7360458613ce5464b667840ad8201d623a34e0eeff7b5006f6ef86c0478217bc7c921907a58a13db1bcc198aa0d297dc7a4d538d94448a96dbb69c44c2f9eab9b69485384b56354b0651dd89ed6b42c1104416fa5b9424343394e46f6bb115e0c044d2bf2a4273115b5a11188ec65974870386923ee1188fa3d9af8146ad13aa55ac1a67a306fc337331c10316dd3b508533a01e480eab663370226cede37e16baab1971077af1af0a8a750488f269d02c47b228a25ac9891225a70c11416aac03b49f8ee3fc9099f37577849a147ce8d4cdcd7b8f86e6aa2d913a471e65315b74a9562aae0dc6f9cd1db7db0db34be13c5a415f53eead544134bbba2b754fbbfb482bdcbd3e804208b92208d7d974137baf370497ed90cf055f5cc6f80412472023faaae22975f8491e019cd998075b00104f9bf02e5e65c68993943ed4a2c665ac1a58ff4362692206aa9390b512d1c25dc8204c5cff8999ece3af5143540626a0367e9438acdc0527d1b967431a889d9e8c19ed5542b931bac7f0f3db1514227bfd6e568fcbfa26f19e3ca2d60aeac2ec417bb1733d3d447565f60cb0670f490a00f3b9f4de20b39538e8963ec483181e123c4c3ea28dc55f2c446727479faf0191aa98a1f1a0220475ff2519ea6ce4e143bad98fbe89858511c2a7c769b98d6ef26134726b1b1f0979b4cd9cfa180d297cef5ea24ae99a6433eb9c9789021d46b753eb3c411e5a398825c8604934d653e3e8f0c4c72e147f00381a803dfd4e9c6b49cba71cf7525e37577693a331c230332661277c9778a4ed7be9226208b70698b182d5b7325a7166a3c79104558c0ac8a870613da76e187cb5312fae9111a44ba05d032111e82a3fe343e8d4f75f6f4a200fdfdf46a9636f6582eb300832a2c7da8cf84b8bdece358a0a5fdfb88eaf5161a66029d93ca73036eacc816b311b96895c418d32eea8d65345c312a4ac393eb0874106291e8f9bca6430b9ad0279877a160383a0e746d8916c01529c4745c31310ba2bb47210bf26fe18759c86d44406d7cee265bfebe2fcebbbe263b55fb778b913968a0fefa9925f81e379627773aa65d6fd27256602dba5850da0e87055a5c89755cb545bc5fbc3c59c68a9bd411dec74b357aa8761b7f7274a367ee95b66b0b5cbc520a74fe6ea8fe9e11a99cbd5ef8e40555fd5acf710f23272fd275c8da450ff090feb4860dc69fcf6b301a3950da6f5bf4b8b7d4d50f535283cd943c12e5da69f28898f2b817c3ef26bb18ca14b0f67b7d06a2e7459a349f152197813cc4236820ccd579a8df888c1644b162396ec8d00870ba6462cab3bc954a361285299928cea770ed4345e3ae4614416c4fb6969a072921a768d0bcc13de06d8eea64a5326d76c1c03b9d78a3cdc1880db5e5049928808baca20d4a8621bc39023806c832ddafd93801984cb2214a6e031d6d6ce7208b9a12e818fb091750d8a3a33a5198a01145fc7e00f3a06ac445b403cb36a29a316235daac9c6e6c563615ac9eb95cb399949dc941b9549665aec5b18b27379d633b9c0cce706dc910c232caacc08bda0032b9b6b858d870eb9b701327060f3126f53d520248bd06004e36b1ae39287522213eb9e7b83871a588902d3c98dd8dcfbc0c010b1116de0d5f9a586d45bdc555fd9764b31ff1c617d8720d7ef3d1212c875736af838097799959fbe1ef1ed6cd1d9bee88b98796575860ff2a8dc13ed60f265f674f7442e1ed6574c08b70f077fc48255ec29218a452660a00c8a5e3510d491f845ce8d111fec1ebd2c3def4bf16fe9b273485a40b4d0213036a844af4a993522e149b00c780bc842fcbd2ad6115346ecf992f8406a97cb23f1f3d3f523570d35a0a048790b5d10fb3e2a9dce4c3784625f947ddef45004ae473f1bf4eb4e87a9d0242a6131e6c4c600c4a086104347229319b4e8a76b3f2fa852bcb0a26584cab0a13efc49010aac7f8b7d54692a34de6f8ef33ba43270e5e4dd3973a6c0c093a3e4f1f13fea7b432514e8617d9f81b30c6f3bd9927be188e0edac7c92dcd8b7c20bcb079ee580d4e27488d59d741bd41394f53c94cf8f195003dc4db500487223d211d1ce23995a4c8356eafd210f463dcf3f818e12157c71c5ee6a1a13b4a1de1c45112c723f9b3a2765e1f6ae09ed6ff075417d4b2e37d6415a3da39da52ac01be24c2aba281d77df068695f4e2b4d8e9e95e0d1a68957c489410c6640e80cc175fab9b8d5f77bbfcb2e1dc877dfe16dc761107af177dc8ed5813d0d17f42a1dd4c51e2f5cd769459f60d9f099a61b1d3ad5e64a58f7c267995aefd0f1c166b5d4bda504be7ccc4fcb8ffb96bf7da88c23b206ccfff10b147503ba2a1a07fbe12ac344dd10fd95482a7b6b895961dc160432ea06e1f2eb05cf47f9b643121d94a16e70f01962a850c66a2ae1d1a15ea739989ce5b36b09ee4ea50eaac05c7f95845b5048959b1ea2b7340293a71c9326516d8fd25a704f31f018dfbf4566e3004c41a2ac35d006c541ff0287273e18c7cc73dca9a604fd2d9329c4453ae2ee962d0a2949d7709a31257aa9eaf24c3af2e378446584f5f614499af3993d669ed708d35aad43eaf738765c7ca6b0ea6bbeb38a06472145801d406429b921e30ced4a9b01bd44eddb4c8e9357398a56de4aee380f2c5ddcb499dd375372bdf1a8d155a8580725b075cd2635e8348da39616867fd3e888810319d5de4705cdd51e2ce3860b48cb29f48bdd7cf31876bb457f19ea6d9286e60746889683cca0fe57824b9d33dcbc5f959ecb640167a095f090df4d315ff62d46f5569a56b8721be834454b2f4c61cc454a5ff1aecfce9437d9ffef0677026db1d09327d9f3ae0e69b4ca11b83872ea459b26b42a10749e3f3196d1c53e0099bb2a7dfe7e0b5e8730ae8732cccc360d2bb9320736de0e4ab2c1b4bda3033ed02a01ee0a3c79fe62a8d3f88a1e288eb6cb16f929349171c6cefcb6d326f5c48f177a6d49e34d53fa5cf4beb44e70d0c4e7c69145d44a7a012cc6d7da51cf5377d829b88517ddcb2d6b164acec059d2fc0fde5972064094e90b53f24595093ae4b715d00a316bc8cbd2717246b799eb25612012490eb254408279330e0e4a2a2eba863553ccc5ae3fbe728696fdbe396373bd762d6eb0820f83af19e35fb8d8b26e623a74915b483b74ea2eb6b4dcb583eaad49dab3cfc13c56e4620ba63e0ca5e92db6fb69e1db7147724238139b314e10f45f738b20635b5e73ce847f18c409892fbc7aa2822032d62ac19da222b079bacb18c2fee97e6716291ecf65543d3d29305321496fecb7c740bd1275c8a62f7aff54f2e0b9c77ea4a5732caf0c024169018d28e2fdf1554da8bf3b282d1ccc3f4a6fb675689369f79196be12c2b480e7610fc832a6b0d054e9cd58b8b6def7a0a7b5e00030ab25bd9b1ac5bac2b43c3d00608386233390e50b20031f9fe4dc2c4ccb48a127a057f681acd36214cfa95d92a39f781efd6f9272a016bbc49ddecf5c4f25d4a2b39279c92da9c5647f705e8dc0e282ae3ce79ac9136f6d6d9e61e7d43faea387136a99bd8da33589508cc208c17568c16e7780a018bc844e9703763f0cb60422e8ea707fba93afab542b2f902dbf23d4c209df3c698188b4ce3c5f6bb751514ac5872fbd4e8e37ab5779ff644c44e49c42cc76ea2b6698a3463f49bde432686001594119e30261b75e441524715e4da75c3e97d2ac1b3b4fcc9682df1d4494cd4787ac3320e01561fc9862affe98e8ed2d48584447e6cc75cf8d4223eb16e436aab2dc46a7a5c2c65146f911c338642c1cba35700c670f05dc7b0098e85b78c5f6455d71ff514fee9f97b1f249c2ff0a9236107eada62d4b95eb0b72468f3bdcd42da5112c1201705f9dda5781e9c8e2282cb47977d81ca9f737fd11fc4bed47f76d8b4526c4f2bae32e7073998aa33f14ed8c3f1c6482b0979b0d49a4995469af8d590a491f671b4ab9e3f3fcdad1f25ec84c19d5c5501fa501a89948c76ebb34c34f80230ed45fbb308a953de160f86d063926d9de9323d542634033fb2b3301886386709c59a7c145b78683b2b2d188136e0fa38ffa4def1153287b4d2193a08796e9e00b75ba5370fcaa24d994cb900a811424c2448738c03428be4e44357fd23ce54ba3b45395862b79f1ec523023c00d624409e255fb2fab2e458fdadf58d0fa43a9221fc63417b77084ab361f3074db3fd08b1c1c8d3f340378c65ecea09221b394bb4052a5c816a4ea96791d94826a5d1f129b0f7f587bd77b0f9b890129492461cb4819fbcbd99d400194f0143b77154573db5ef9ca6da8303a447b12adce0c8f10802e9cab545f8ea19d189ac3c3583feb822b69c6dd78aac07bcf7188fdeb7fd6fb4e6a200969bed8f9b5c2a9271fc5da7a26a57131f521682d02b765ff77d5e9d6108510cd77b6c9d48b4bb305af7b41970e9efc5a5911893ef021673258e93ceb5098039eb477adea77900f78128dfe58701a08b68c5feb638718db44192d358f6d2a18c5a1c1ed8268b79699495ecedbb48378f941343e3264ae5b9b16902fea417439ea3478c814e69856ae21dfcbfb9f6826c460abcd33589409146cc79e6013239476079e735a75276b564abfe01ae4b0a1f7b571b8ace98fc6d6fa1c7dcdecb1e223856856546ebf019ec5e4b3f8f083f07a5f9e8b050fbd74dd9271611a239deedce9a1e1be7060d122a9fd2640870ed59a4f7529048a1be46dd6dd3b9f33c8d5140b49e489a95349c6a61536b4e543de7ea9b619bb0ecc591927e6465bf54a43230b62adf2fa9d29a413d35a827599d69ce3c942fdd5e0b51b3146928adb284387d4d75e7143f25da3f4036bbe6595314367723cfe327f0ad1bec87b3dd0bb97f63119792f2c0e54e25e37aeded36f31f957affb2c9c01840a0c520d5fc4b87b22f3ac469d5bcbf4c03109c17ef9ad42c71e7a61ecf970da2d16bf681caa8053c0042c1c5c8efa797f38656b315fd54aa3522cba68dc547a8f01b8c32237aa0fd9616a989ac912a1492ab784f0ae8fe7dcd9a4ae89a579dd0048a6c883a8ae6551494f88f2fa9c54c01093c879974ebbc8867eeac90cf50087195e196ed14dddb538d0175823f9196eed8256c1c6d3fe10be4dbd6bf0ba937fdd860b437fae4217d6314850e2fa89f67ff35d4ded4780ac4b55f88c6c278764859903bc9aa21e1a26cb4e6d94ab29381828b649245c57781e1220322f039b58f6f7e5fc8be82dde673368a7b78487e5e1bef97eea92c0d235245137aa28d8ae3198dd3672da790646ba4c7252ebd4051eaf84d4708203092e0e6bfa577be0ecd821806ea5d3e5ee9098ced982dd89c768a4c363354beb400e868078b2962410cc82f02988a51322b05639cbe8f52a12181921488b91db2fbbb193f486517693d17fcf1181327878bab46e9ee06e165752460e223e6626f13f7c96139c685915688165ba124d8b2725848c134d746c6b8477f29e7dc352908e7d0952dfe5d27b93e894682360ff8851d58174735f02dbf6a19341ead2982002f2c389371d4213d551b2a6e2d9950e9e2b2011d368c3e417f365b01300fd187508183fd53aa044712e2c6173c3ff86318a1d9c4c8525363bf62b8f1da1e3083b2a3ca385c13052fb57c6b1ba8fb4a193a1d0fa68eae087b348d4f0a4770c3319fb29dfa258996f3ced72b503afe5ba9abf55e081c5edc7b16b01493d8dc98088e163937b6b1d17be8defcb4614be7381baf158a4e539a3493a7bb7dee69df54f6fe8d05f96f44d8e983fd31f41a760975d2d78e08a7bac69abb735fe5ce6b2a7851e14a49c9546d2f3192772445e8b86e529bd5f5762ddef881ef59cc85901a65e3ecea37eac1d7fcc1c3991ff488a6545c5197117b11e5baf968471a491e6eb309d60106c4c8d42e18664e22a2cf2331fb0e457131490d4bd164ae6b1ade792f256fb24e8e6e65dfd8cc6375f692c8817a350570a96cd21640bb3b4da801ca9d8876b9625b144493c1aafcae175f6a3f1366cc1a5e01910546066281166780104148be75db3e2b803b075bed98f97770f6fc610e2c5f3a37f05d0eb6aa342aaa3c18e839845427a0ee4a0e258d29880cf33776715bd21606878282d0c2e549b348e62ded1e2fa63e9ff7c2a614746f087dfd2bb650c1c1aba451676ffaf5b9a98e36fba502a3c09fe63d81465986267953d8ad692db33ff732b52ad98cef517d6c8339e84e0986675c74dfaa27d62f813aead19fd2b6280ba925ec82186892ec7f2c1c801abdceeb8478f979d08626eb61d63d4c66594df4e123b21ce98093fb171dd7152589890cf4382a755d88b6a62da05c6ecd92a5cd3e12e6f5a1e0b97d058bade6fa7cfc0c803451b1f1113e4d86314800e70e7bee3a3e3d3bad5fd287035d387fc8fc017ef78b263c4dd55b68a6209d8db6a9521c0b92e39e321637142faa4ec315b948fcfd9edbbf2974b68230066ba22f4afc7de0cb4acaf3b1d8169c71adb8a986bb6837c7c3ec8e9dac5bdaec8c732c9c7142e24c823dae80ed31fb930fd7ce4169fbcc7356960ac878d0f3ab928ab2da259c359347a7af2da4fc6512dbdf23f05e4a0de2e551d7128f6fc813e8ac3b00a4538eb1ffa690c5ffd5b28b44f7ccde5b3170799ae799563140a529bd8213b1958761a333bd49bb91746eb70f1c7166c017ce429531eb19dd26a426acb3df184aa03d815b6346adc30e5b5621c784377b09e13300a3fecfa78f19fefea732ed68ac6a72ccd0c9119eb5761454fb61e1d3752bdb78b8c2d1949f59018fbc7b9db0b794cd01e7c41d6182c2ae0ce05176e701c557d5c75964790148a7a3caaf89fcf0aa9e39525ad6b96e5276768e14c495b8cb2135559d2b2ba7433192ab3327b57ad3800ce6707f214c8b4ab8f81d9f273eebfb7e6a3507d82e2990d5788e03143eac42d2ab7b0fa73c403ed13cc26bc10fce475a7b70b574563aa167d6f9907abc7768005b4363ed903c617ef1e22a9455d2af1f1bbd07bf9d13fd892692ed0c034b82bb76134b0ffb9c1f47700e39d7992e163fd5d5d8acce481e08f83dce224309e9cfc881cf8389a423ef4caf98c0fac9608b3de40edcb209201ee3e6856cf190e90cc4dc90a117dc341a0d9faf7340e7cd3a4c2334e7786fa583123b583f7e183c6da07e099e137440cd5f2b4e48c00a55bca47469e2d8fe8cd4d6f3e8edfa16963b07c4f6209a4a976a855e6c0f50813eef0c0ba7529fe9f7fc85fb4b3caccc0ec08f6c3fe5fdd9ae57462a2a58f47895a919888086a49adad209044954114c78727c87007439c222196ee13bfb65c6950753fc3101afed5cf5c98227943ddd6678d32de5c8e2df0a2f95628534769b3057068cd3f7344f0a8c1091830a80b80545ce50592c64023964844b0748f2433501c2e65b4cce7cf406700cff4f312c5d3835664678d1d9491b279a3d6c40fe57184314c9b2239f1f9727ec10378224441b794b6db56335aee511fe3c8f8e6258391156b8a95ab3479cd6c5dab87065b8d05e8cf6af5207342782d97063227ab1eb9421855e8ec03d6a48a4e62b537fa7ef7eae969d2481569ad35bdda63ec05b8b357efbc69168304d6c326f3d376708c0d77f646b9156652dab731431f6b0f5342b17c631e24ec5311c1f95f07e04cfbe052c3cef014556099b6a1c9862d344fcd25d432401f660c6d54a3c33a9067c4bebc19f28567ec053fce4e1a105d7b142b4bbc99ba76fc4a19d727879cf8642ebe56b7fa3d56c117e7de2b94fc9cd5ad889233e1a880d21c436b447ceb32aeeab1ff114b7b7cede8c2eff3b942f65a2f2f3f5c42909c89499bdc9f3c02860c903df1821154608c75bf408a61d3478159c2cf001a449e6f930b4634573e5ab8ec3d7f6b6de03f2acf59384b571c51f1a9901264fa75115bd18b9085a7d45a038e44634f29e01d509c888919a8338b652365e8732236907877976a6deba1fa76064ec7ed711e4e01fdaa35b5c03f875b5b6520372f3b042548670b9c2e0de62aa67f2c328a2a891b3aaf98b139d5e1ba8a29c5aad41036894d566d7aa50a43d0568657f52236a8025ad15a56411ac68a1418ac65c03980f8fb3ab162bc8883e61347931706f17cd483e92b7b93c38720139af47c49cfe88a4912aa26dc7cc0620ca64a31e1c7d4bae84ae93d2f80c1dc49d08f50fa29fa8256e44339545ea4c41827a5caf3ce0f496ae8eabdd1c21a0cb1af79ac8e85f2629d10746ef6d3fb2f7a1a48372693a7e1f16ca76bdc41812ca10f37a56dd6a311f8d3083e5b4a667c5eda0793d03b2acef287f84f999914c334a22fa6e4ec95ba51e3859d131dd0f3da4898236b50ca93f13c370c655e1ffaa1ac2f3ccac6842feacef74ff30692da87690cd9516adcc8a10995741d19503f55e2be4d05a96f112a2de31c60966c9e7f050a961a6948784763e0b8d37c24b69026456074cf7be48d4b9e7ec3c7c03348cf7ef8600dd3ffc5992b4cc05572e6607482f6ce14bd7508142ad8a4b63314e55ddd97ac32c0a30c6cf20e6253a6384b3891c914407affb5f25e34457a935dc8f2b51f25de4cbd271fe494521c724fc97e2a709d439f0991432cba14aff95ec7ce37f43a7645dea96a28dd173735a13f896a9a90f8dc83c93f26cb219f0ae9ab47269874d9bf15179a39a8594083532f216698bdd21cb2242bda9ad1deaeac7ed647ab572a0e9a4a8304afa46586c17c239a1fbd71704b05a5d13b27b2b0e70891ba4878de5a764973227d40bd49d9656e8843e09558fe3b585b86652c7fd88a2cb1acc81df7683ed9a2d15f1597c53c155a784e837b1c52349596822ef167b90fc28446ca643b92d23a4088fe27c27f14e154f411cce627ab90c9e946720d5aa34993b145b9d75c4736d322f7a24b209894f950ede2ea7a2faf6115819789574fc0b41c8d66c2951c9174602b84e7fa85bb732f9b1ca496b265f85c987fb26345e71e56d48f9dccc6e99e91548de140d07031a992a790cc9f0e462f95398f040db3510c8986f07bc4483c417d862f83da4eabe574cddd17c64a45654812e8c1cf0198f1e804de9d222a63d47be748adef1de9f36394956c33a58baf48c751c9b9de62f2ef288f60f35c01b22f431dea63f0ec292da607d38cb458ea050785a527fe93f304eded3ea1a6a4fa12612a38bf98f6b7812d41af7312a9e12229f777da7d62625cc1c39f5d9fd2099f02aa1a386e4e326c89685694888f42297b0ad4cf407440a7ac0cea108e649ba2b32dae1b186a34d3780120a8722d2ba3281864cd89eaa84f98e13dd7132c2ae60d3a16f5093df0c46b1b2ba098d0287ec81f67db519f285428fc0230c0f5196eec0fdf6c5353357fd2530772e5716a5f9896845b3b8105d52d816086946a0022cf9bf80e1b5a4eadea4d960cef24b186ecd7c1a7e478d49f21047ee9b6c4792dbbadc0a84e304da3fcca677bc920d205075b9427bb2d4e8e1ca0500ffd75d26728402f0c4fdb619b2f124645ca3aec869f4551c16e097469c47a242439b25bc2a6b393089094ebcbda03f20d2ff131e548eea062e758c127fcc23be200c5e0cfe58de4363c94f157900bf43f479d2a26755bf431bb256efd3d710645c391f6f90c92ed8e7394d300ea48002e718357f16a88e1cc5fe9ee87128c1a79184213b8f0092a7267b0c221824eb20e8770247aa03989245b33b006f89c56e813c5c42c28a023dbdcb08054d0200be7b2e313054702b480bde3757613edd0ebd2cd53de1243bec630b15c77d12962f1d8c442769a2cc8ce193e7bc20e80e98e51ad3c317b42f14be0ab7482cdaa217b02e9c0e41a6b33632c285ac1fd5ad19d5e69b0321fc47475d61a97bf8e4aaaa4f60384a70363f2c7a12717a3a6d9f9c24797e531de08304aab6bf1d74fe804338065f1051358800305c9e4c112063d1a99229bea251d67d1428f14ab883c0f54e5a4ec96c1cb367d749de5061a03915ce6f59048ac2e767d5f3ccef800d2d6f18bf34d1557b4a59fb7387cb4b780402f08aeecc45d9a5586a662fc0f2aa5a474d555d75a6a881ec415a467b0a01b0a2e5ffa0fca08971984bbe8403641678bd124910a282ae99c6792e98c95683fc59f42bb9f69e8ee0d1fd18bdf617bb699a4f944255e73d256cc04e4965546400a0dff27e5400518e18e60a8af9893fa1a216f5a88bbdff3317212717155bf3a7e450c30cf332f7bd6b0a505986809efed4ffb122f56beb476af9ce4c78f5cf5d5ab04d879559506e7c034c9f2a39b6a94ba05d514070c673cda64b0c0d78d1f9c93a3f984270ef8657fe207b22f86b8cb360b4044761b2f7bc6333d50a293afc2342be60ba509b403dd45da1f3432eebd6fcff354cdba283d7d9c7f5146b9f0f62adf1016b5a8df5482adb21363e8a476df318b48896ba2b8efd9b010ce01eab0fc3298dbe3e3170f79d0e8d7ab6fe33dfdc58344eaa4d2f2aad005c990c90a4e18e0083fc0459550f3c55d073555cb83380e8a5c1cc30c3a80067902f1123365aabff68aa5d9f718d9ab1d7f362195f2bcd5129c39c51773f2aa1c4762bf454058fede5532010e313f664dae4b6f63e4a60a7576cebf04b15aff3cba9a424f152647c4048e2bb096e9b60945f33463e136befe9ccba87007f5fc016cb6debc3605bb78dbb17604124fb316d5d6161fcc8d975c456f1b3224011fd0544330834998932e29ee8ce54edadcbe92d0b69b3f07575f658eb66595cc94c1b79b00aadd9adec21730062ac00ee633da21cdf1f24a27e3ae6ba43d4df60ee149f0c4b481bff544cc86f351c0a91d2e548a50b041bbe06084086b44fce5de6732a6720bb67d1baa68774ce980a3ddbc06f8e4a0fb9ce55c71609788cff4e9fa53110156000469fd2132bdbd38f418f6434e0fa3b79834bfe1816ac5ce404c4fee2e5394ceff438f09872cc9deb9d9f906e738a10ca957127f617135985a29c81b84e07617573a077cf4e33c1cda9b9ba4a7dc54632538949c2f83374d219afa2d98b6b6a5c2e19e9670039909e26eaa29fab23b8490d9817bc394ccf86bd63a8504bbd12ae6af8f7b146b3db8a9d441be19e34dc360c64280bf8601815af6415d423837ce855f99c10a4299518d5c1a7803fd76fd20ab84b6e7ea17af806249704c13e0e83666191564fc6b7d0e63605910c1117e538da5fd5ec3a3b7b1427a8b727b1e4e83a74a7ba4461e878756884100d6810be95edadecceac5717dcb48857de56b7eb48628418a6511c2e9e01ba99103f6e4f9f756e1bf002f75e626e6dde6c43553d70e68153241e1a480003e6db707176296d68efcc595ebc54704838fc1a92651d8a2637e0f877301ad3d0b25be4ec82e30c2e09d739b5a586f2e835959a1cae472bd6a455bd14470832cad31cd3f6cfc0d12e99f7bbbe0c1c0fbf9c34390adb1219271b935d4016fd6408ddd1f014de03b7f3c892c5647b82493005b553f744540674e3279a5abe724d714f623c730056e69b72719c481b3d096317b76809d36308cde11c0884e4e9123051a77e218eb36ef61b220e895a0897d648c29d9e0fc19c6b38e84f948b1f1a76e7eba61c0f8b5235a836361e4d22715f294e5377bebd9e81f8eca3d39e33987a0894b64046d8d1142ba04205ecfe01f90b37e8b6d720118aae5dcee8c6817b236cff0afad0814c7e99244da69987e376cbb899c76b82a9a6c54b62dffebb261d8b11ad73f06912210cd0f921761bd23cc00aefcbf985175e338b735abebbcb8bd7fd2c0ad5c3ae8975289a494a8774d8a46c1e823239e1394504c269c23654548360994b5f0a0fa1f7157ee65807ceb4478db3afd04c6129390499da2168b5a8072087432841f234e8339a9d735339c099a8e4b902784a5c0454c85f857ed890cdd72d09771a928b9bb5534d45fd3387a8167fd6e8f8132fd5d620aa60200d7fbc6385ae22f6d3035dce7b8206d0d2803d2b2b47671bb046b6dd9f3ec33b6f3e2d7bba80c3178ad5f1d1f61fefab58b82c6d83f587b51a30ee7264440c3fbdb50600ff5d2653fe8d36480b2b3492b2725df332801cb5d68001f740d22df56e902b38ec115dd83e484ca525a16030593501923e64914bc6c5a03322e8b1b15c65efc36d9a94ca53707ddc555f9dd095bb656e1628cb731f2c47f376ee9251bf9aadec5ac1fbf4b162bb8f5282d3aadc49c3b934970a09e80bbd2574eba8d7d85b95efa7dc6fd47a1593c99afb0fdedd109f1012c78696db072d1e83fc873a4f763e43d9301ef4550e5b8780cac4cfc8c0f21ecbfe586e21849f79dea10d6c81dae18390a3c2db7a018dd1d40299e7f90d70d25d10a9d645709b6cc3760be72a5b7ba3018af9282b1de149dd707f3526e4c361e0c7707b22b7478e9dc8b20c865f81bd9aa0aff0b10035adf36ca56bdfe17db6ea1391cb3e9499571a44b4668cad42e4c12a96d4ba8242229265959d5baf8f9fb03a227e7e1e8db52cd628881de986f6ba2a704b739210522337d2c2e2011e6c0b876ab72686f2c7941a5e6b7aad5bb2e2e56f613054d8290ea803bb394d09b5d26858ebbdd522c12e7a24c0aa9b7e17829156c75b41e0882168ad159c67dc586647210ad86c6e5bbc1748edfe6861e12aa4a108a412cbf62b0fc4a97c895c08f0ce8512fd651270315a42c0d630edcb9f507f2ded9d0e6e47bac08aec8e6908a31a8f467febeffce7a76b5a50a1d6a87d1f0319e5eb6640860f29b50b6446874d0ba77810f62d830b1962ab90b3c219c211c44ead01c8909221ed0436587bae6ecfa40d7dbd8aefbfa07f999cddb13106e75d13619d500c4c539d2a70990a4efd28e686b5be3ba80ae9bb8970ebce01e534828f8edc5664aabb7adbbaa5bd5c7c25497626b3503ebc603baf0d1ae7cb00b1fec6ed52a3a6beeacb96d6b7a366bd7fada7a5dbd2cdc4d55bf55bfaa8b85a96e8954e97b567df4bfa68c1a290c9d69820f77c5075df1a1ee5b7d7d5dbdbeaa6ea93e03eace85bbf0c1eed7ad71c1ee98a04bbd2e3ee88e0975edeaeaebebf555f57b7519507716d88d0b77d5d7e1815db158577d7d3cd645b575b5beaa2e1fecaeabcf07bbf1c1ae98a8abb2beb65e553f0b7751d5edd5e561ddf960b75e5d16d8adaaf3cada523f1eeabed5c587baf2a0ee79b8bbaa7eaf6ea9130f75d9ead5ebe283ee9850d7ae2e3ed6bdababd7afd629d5b764b5d5abd7add6a9d5afea2e75b1a1ee4b5d755dbdbeae7eaf7ea953af170fba57eb6382aefabafa7a5dfd55fdaece6aab5489f5d7c47e5331211b9fc360ac4fdaa3537ecf0e2e35d574e64887206e88b42c7b47219e9ae272eab35ee72ae91453f73694c2c3efe879705e09f2da8faabeb309f7db52d54c1fd704449fa408991c1277cfb553cd91987fc49d9d357c509927fb421bf03bc313cab71c373c15d80b8bf8367cef086de3d78621681b6f3d26b00dbf2f2cd176b8ad308936e1ec854bb4097f2b3c814db8de23dc86f4ef2859ed247cf1a988722c7196c97f1dc7e0aaa0142764bdda38e93a3813356f09116e71dc7892c6baba2ae279fde3c1e9b94809b65f28b4fe91de81f6ff932e30d491775459e5531e65aea996f46f9c1d9f1d0ac52aeb0a2411c9b51e3b3f15f40f88a5dbdddceb3a2eafc4f636f1e531374e580a076baadffc32f2308cf552ce1bb22dffd6cfefe076519dd310e5fa01cda36efced9afffffca2eab1ac6d459110fd5ff8b96e6a057b85bcccef5926297c852dece99fa8e1000052cdfff2e956dfee138b796dfdbdf4211a1469fbeb6bf7b872630736d4643b05f5e9255c9684576985103d3f8c33c41a2d55d8395e015fdfe53d72a4af9b0e9165001e36be273e1ad735b2a091127989acbd2307a1ab84e89f2ba62486a34d75bb369953181e7bc616d922b9099c56af200772fa5dc2b452e5f51113c25b1b0bd5fef84c121b527fe80ff14eed232d28d81dca945c5b000aa5630494b25fa974d4a20be93eb2fcd91a60728746b5e4ffb824cecd6ed51934de537a7366f12b691d3d3b7a196c1be9443c1145e614be82da4f87c1e5d1e34388630b181432b61471717033b079d805904cd8b209d55c822abb3e91f74d5933227cfad56cb6f15fd2faa36eece58b9b41c8cb69be0666719fc3e94d81e5313442340b06cc2c10957b050861397b996a4f676bdc487592cad77588b3f3e308e9dd719c2aed283132ac02177df02c23eb010e07e9b3302dc945cc33e688a7be29a3c978e27a2562f8b34f38fc1fc096290042034180065a9faeaae84c5bc767535243b59fd5fd3f1cd544f6d4e3faf37980f3a93b91a61ee29351032408711be5acbe595c852859f57489b6159f0adb281bb71459723be972c518bfd8d0604527b6d1e1fc2fd20e1ac6fc06b40bea757fad0897043fc292f00b3f20f3a6e8d210605be0bb1d52c981336225f5cc0fa13421eadcd52048379cc4a764b356bc468d98e0d100c4003e6341653a8308f8c587a791663bc56a1c57548489ac3686ff7c29fc2854b5502922ea6389b12ed529cd2ea6cc8f418c90ec03ec8689011d29f202ca45227dd33aeb6089be3959ed0691f1336aa27a1a8f7467b792a784fb4b53e436ad74122c4e9d9b899a5a9ee524f4cdfafad92004a2dbac68875e8edf328b5bf23602a97e69668b6e5ff881293fd1c5e8322ced9a2f174094d35bf9bad1b13f1ecb82504dcdd400c3b74f6e75ab9ec00b8bde547e9226f5559f987ce793df7be83c58cd11ce4ba1e85974284aaef4bd955f73c26414b7ea9e2a391a287996d86f9ccb793cd28d7213f4a09d80ca1031cf273e70485fe4b1c548f0b43069d8010fc46c4ffe697b89251effaeb57a91df55333a9ddaacb1754c42c54631774b0a98b81877efbaddd9a463e817dbbfae7dd9a0bf1e2f947978b75d57d8a83d6c0c0ff2ef4ff6e5e6f9996b16f8f56a6d68d5c8bd597ebe47a55d0bafb20569e07284e57dd8f7edd4ee597110642ee9f8b4176d195ae10a39aa5de0d7c1ed15038a847e4f70623120406584cd0d9968de400958948448c0449875aabb0ad9e4de81432027a4aa75cc08ecae792fb96461a0fa9ea32ea6d32817dc171b0d56c5d67367180a466418392b5f7dbe5c23fb41c473bea9daf85e2ef9a1aa4831f0b2aeee4a8c62d8d0bf7322e5c9e0cdbfe569bc8440259df9dbe46ff7ab607301855ad4cb01a29df89712114d5cb0fc85c9286cb857651b976d5efe50332da3bb02cf0ec3a3c01fab252acb9d88526f0be8307c33782c5f33519c5f1f85992211f81e62581c4be8790ea169d1e34e50204e62ccd44a6bc2ccaaeef5966ac295bd7bf558a56a443c3f3b5b01a05fd739ba955045f01e3e8831115e13adc04f4d836e01023d7e67095d08f7a7efc5629930cfc6fe36632cb47a2453b374f77bffb8eb9b7a87bab02f9964c7ee73bd70a2d43d087cc097699fadb24c7959847799aea3d5d24534b29a62b95a6636c3a61cb4c6d5ff470fb214fb93633012e8345b7efc87208610a3fa3c480d858f782bb4318c3528866c8884a7c645226df5b229c68b194db408b41aa35d5c6199b1a27ec9930666e508b427ad833e22c347dac48d1e669d1e985e7a6bc8643cdc0b096e20da85e7971ed73b27961e88f5fe6c3001d771867f3b527c4c82eaf1d2bb6da54bdc8826b9092155f69b28118b5672c2f42613529e0b757417b250b5b76c827ab2113c5dc4d6508e834f31f27efd141281697c10e140f79c8140ed40a1017cb740e41aeb095c8f259ee8302b7f9ecbb0128fc5873ff4e73a54c04d6382d4c1ffa53374c30bffd331a03edc3ae0e2d42429da23957767e984bba9c6f5c2123ebd0533816f4b29bd020496623ef1ba84fcd9b9e1daae3759eae9175c85dcd03632437c806ae4a6007cb0562150458333a62d44e871f7d43da09b91d81c6891749fe6a445ad30497d34056d434f746d3eb89592a70549dcaff265a76b0e35ba805a0c8775ac20f6821c06049c725d21599a62714920e8516782be68d2833c7f207fd2e2b37c08011e298caee601a22be3c097b482f15e84f09ae79284368337e5aab78b19a4ae91b36d2dfdcd2796916872f0e70a3d123b98fad97ea045d8584eb5a2bf28856808c77e9caf9e5468329c6cea1d789350a8eca1fd1a53b4249d974356a4d0519a4e391912ccb698deb5326c6cb899676084a0193ca6d4adcb1bb6c0055ea0b87f5fe886815c558690e0ad6db139a058c01b2d870fd58883c80cda635719842ecf4ef229a8776835841c4b18bd0e043738b2fd8c47f540bd761e29540343081495e29421b460a011d233209317383224763af518b7563f8f451d1811e3eb15b6281b2c79823d9be46774639754b3562a8d8075205a43b1f115f1f59e601b7617255adc8872607ff72dd704a64bb583e524bcad93d56584387a3b77676b2c61b6f675b708d74701e05b011e2d3256aa7039622fee019b5537044414004c432922493d5b9fd106db5cbb0587826f49c5b7f70e93bd277b2d2cd8b964dfd689df4816133d7395e439b599c6a280637a1746a9e49581dc1950bd3ed80ba02e1051da955628c4606d175c6e3b03704788e272805cf425f9b972f1c5d992af6e9b63932e5c00e99c4c62aaed30bb1dc4b4d5a7dae6c32d656561d8529aa3f2a1b8374c82d904d8b8799e18d86add6011ce2b717aa337802766ccaa664e2bd3ca34fb93b3bf305468500509730f801b79a4a6f726bba171dbc34053f9fd2cd5d58f6045aabf34f74e55ec6a2c0072520ede9515b5553f4d584daed2ea2c536114eadecbf288c97efc16992d98e202158677edc0f2de0cdb60116a672a64c754e3de833b4c8f9ff4edd346ce2657347836678197f5a52703aba4fcfd3e047932a349171245b44d63eaf26dffca06980bae401f22a5b680de39b35fdb06cb1d3f20598e7cdd21c4198ded8c56bb8f687d8c375130237413f5806c4a81e68d79baf032b831175a7f05c13cdf114ffb0220101540000a3ad9f733d06c3137165d2f48a226c60624fbf1fe63fbc8c67513307589544b251361e0325a94638c890a9370d63e12561dfc632314bce51bc3d181ecbd53834ccbb533b8b67c79cf2c9ba4daa28b29af03b6178c8d613fb8a3811cb10bd76aee852bc99eb638effb3680f8183f16f1589c42bb93384a642f6446360e8ab2344c880af0a7c2d1683dec809ea22f30c5d3224aa77035671d27d3726383cf9164991328b99d99428a1def3ee3a47f02210ce0c92be2752accf4e60516095c2b1d1693a89612adb145d309b2b82820579fedc03deae9990d5a27b6bb2ed23d2c9405c73dce6e4cdfa0104485a5ed8956cc3ecfa576641201c92a026bd79acda01781b0283501722ea3a3e3a375ffe6a8077d958eb8a331f0870abee3d80d1711ce92286f8246991e1151e2d2402a518abcd23076c44428f0d9bd48a18529ae37eabb4c8304fb5561d0563c52ea9ed75642a2409b2b5418f090ad9b75e86954f642fe149f7207801bf6709cd563d6b41a0bce3434f8613847ca807af894a1f9e437ce1341ca7118b2a8a5057537f876f69902b2939efdd02d406512a2643019af2f5b7fbb03b350c5571b2b4e99d29201ccd58ac136a1253ccfc438dc806c857243bec155654547886eec7bbf61d08f88cbf9de49ade9ba6329f71a8154ec0bf4f2e3a7a491bcfb48b433d8be56a227d5493fcac557a2dcaa9b0fbe62478cdc4de9e4a566a9486332196392a4e82b580ea33c6a6baedf74b106fe099b8f78cfad7d331ee2610ff324192d10210cafdbf97ddc58985d9adcbeb79d4209caff8565aa8bbc6953c035ba522d095f1824a0a8cdaef6d7214269082063d7a71cb2428f4d34e81a4f29d09895a5a9c1d7daaa251862668f4c94644257c26212f5d88fc44f957c641df279a39acd38d4b939e71447c51c17647a94aaa4fcac2410963c6f36bc755a2f26fed79fbfc46abfe15e7724305e15f782ab4ce1b9a1bc57a8384829503df923497ea86ba74d23614c73eb3d8ebffa32401d7b19c02c62f4bb2a7c26bfb486ac46af4f073baeacacc0f0e6997073bf7f4388f085c20f2b0d0ebbf9085983476fe850ac46e3ba00abe579054511172d0b29055b2523dfca1d3d02d606521a60aa7a1795b4bc7b8f8679f89544e99bda932a991eb2531056b9d181316c28cf100f90613df40a2b72ccdf9aa7e855573dea8c8ce2c11c54b7c81d7d10ea0bd2a64a202b23597435729e16f28ce7ebb5e562f8e76e5aadb30636af8d2a535f2efa354246e6f6e7823a21207476159d073c5a452e247c2af92c7981021f2fca6e6f442be0d9785705daedd7a58b37b63a3b558ecdea9c91dd2ec9541d7a76b652a71310431f4e9deca61d4100deb05c68553fcb2168b2d78fca1f1a6f92e43e98dfbde1edb0c682ae7336d9685f6203c19d3b41e4a48223138a8f3d63d4673b166dd16e1a14456c534396ce3de482b9e4a10d08e0188617971f45062aa0079f65920a618df39ef913acbbea96a38c98da197980bacfadab768773ab1f2962b1ef328ae6bcb20b376d1c8481b88c0c7db89796eac8af5fc1cb58cec11951f17706563c885ecf9d04ed08ed74a9ae229dfc4038dac8827905b1a50a74007fd0fe083da1f16cf3cb7bd678728c564e34b5eb595b35d7b9554ed6e3616f7238b62f9070e42f776bdc316c1312253432a3fa35a9b6b6829569f30754c091d6c452f84e574036ea5109f7ceb2fac9b6fa400043eaa8519fb8f20f2f500359c1a70700597ddff9aa9cb2f08946c2b7674d38169f885e7704ebc37b582021091c1e00231e5f600c8e84649bf804db74526cbfc9abd7bb6f2f112c51a5978d1939a73898e2bd91237368dda22d1572e66fb0cba9a9e4285b31aaa48dfd46b86b41865fffa0ea5cdf1bb45f277aa022e02270b5eebadc69915ce411ab5a1719b9a609898c46cdab4f7087c84e8c8236e9496b7c9855eb945d40fd996746170697cfee9ecc5b7d6f63a8212bb10e41285d3cc1b9104437afb3f340d07bcf97d143133554553d7c378321884f8ad109222eaada366082ceadc56e9a0d39a3a5955d9cae2a7edee0d88f2808f8903fadf1df616e2665e9b28d4156b5be74516ee9f5b30d9be00a7ada7b856e162acb7dacbd07f28ba0272c06191b3c4aeda84bf406fd9af6b3d14988a581e5a02e591da2910b64992086769cd4fb6b05d8cd065aab53afa3a26c6cf23cb4d825d64720d8713e720dc828c64c04707984ba10f6c71b0c7964be941a8e966629fd4525937efc9f95649c7ccb3ae9dbafb76a7d0a2de1d6a5acac49af41a4899d7684bb8b9520397a9ad22504fe00b20cef688e225067766ea6821fabfc463a9906a0e80e5ce2a1082dfa76f314c68b5c6107c3bb502cc19af577f840f5ef66013bdefc22256a3c16e050a92f8bedcc7dd398b9233f805231f98833c7a43e0bab6103072dbd37324e4e2719a9e179610f726c1ea28dd0595153adcded7cc7e3ebe795b738b00683f30960e26115b6bbe8fe51c900070cb5b4f02f696b86951539482c1dc09f78cd110d0d4ea47e1179e8825fb9f5b331dc31f8058c535db46f2fbcbf81200fb8cf1e1925b46425bf9ccff08aa72c374a888670d82f00194e89104d00e191640ca70646efb85c4f83e0dc6dd2eac990588c089ed1af7c4850002e6d7d16c37087f61bc440c328ea07b9878769603017b174c3fd763d93d7fc420349bb4f97cd0aebd87168c1621c92ab88d072592205c820eb40a8c9fb35d2316d83792b0604979b2905ce53ca8669e40b002e680075740c4308aec370564dec00ad86da32df054211420ea39bc1233b62f36d7668df3b4ba80c19d28fc94d1b399fa2141666d4725f247d41691d7c398a386cde619c469667e4292ab9a33a3134e88db3b400dbcf522b4b1c028dc51d61d3ad645b59058d99d44ce06efb17627e37b7655ad711bfbfcb70f8be332a01280817cc491f7baf30be8bc3ca710aee674338d8633b7fb65312f7819a76e84a4c1df716c41f91a00772701ad5ac766983b00f4c356b4a98644e387d407ee44d39e8268043774c8548c457a0d89d14bf958677e5a5ac661d4b5c69f8291cd60a6789a08d549b81d793823b5afbfc0774dc4d16ee6d607150b30504bc6c462f8849b05a9c95b2308d2e054c9db5374dc6bcc950b2e212a91c494e9deaafc2b6f0425644d4090993adc75610720fbdb939fe3e6f0f88760d29bdbee41faf188d2fa4dcef1472a3ae2493a9e00d9120c54ee0a35bfd54fc49a8b89e7d5488da8f958c4996cbd38388a7502153db4abb571ecbee7e37bae84d58bdfd5ae358a3f9033db0014ce3fd5c13d7b69c35849af651dc17c64e84c1c33762d7735bf623fd5bd278363f59984215313ba0674cd5d04a331b264a8319cc5be454a6643a3ef299f00732aa972feddbe35780f3009333febbc86ed823b0a65b481555870d7d90b331bc9d8feff9bab899015c144e989faf7fd43a07e3a17f174b7df4c763cafb7b79376ae7e9457e9c293573f99bb84e221f8800faafedb26875c3920a2104dbef74d4e792b947c28dfcb8287466fa332f58d36a44e7c70b942050c80d3d97c3da1fa5429dd6b93e8721dacf1a71eb87e9b7e8aee57eb869ea6ec1ea39685e116d9a4ee430e81571d0400f7ce5c9d8eec063a5cf5d6a504e763940aa84db193860ebd481ad845daa8368d1b253acd317da9f275a58959fe60071530f3585725e75d0d771439dba09516755ac0e02f1e0409055baeecab3426bf2c9f0ea0075f8a8366e9b4d6db1300b40f44e8bba9795b9b05834253293bd44b0b81edc4944cb9fe877650dd058ab06dc26ee7707e450e6f68129599f9406f2ae8bff3f5e06ad9b943590cad277266c5df6849881965fafdb5f5ddb10a654941859bb1b18654e94ccff373f4eea305f063a63394c0f5da23ef75683c554ce1aeb20e36687c59781561d9e0c5bab41450d08423528759badce0191299674af7b921ea6c506716535ba73b19778c40924f2bc874364eba29bc1043621077a31694fcc1856dfe4c0d257bac060e42a77a84cd6f4cb11c476446061dd5e68a75fff917b3648f012e0be91dfa6a127eece8eab590993b67421b2d6c1c218363b3d3d51848681b9883cd5226d71ffe11fd116d300c5310f5f67719b27492eebb5ff2fca50af989f54dbd373fa4ce6b69f1a808b2a61700e6959e1ebf6ce70412c40d9338468ceeb79eb76a6d41fcb433381bc9ed075315c97799ada270fa54969b00eae7d5fca97dbfed9f7f936a7d27e6f7767a3e035e9e904f78b5720b2d45141810d31f39228df83069b3256869c60d344550f483d04e7ce64723567e09b08212dca771b7ea201171b26c0127618609f2f803440c7d0813ef1e4234169fcb2a9a3bba51d935e193496309650f9caf875e8d06fbb98fd545be405ad3985f0d815fe20c2dc314b6df049c2c3259cc498b5b23c9b8bd824086fb6806092f07b3fe3c94901ebddcc660310a2f9cd05ad874fe825248da97b2c3249018c2f091e8a7821ad1efcd9095c3d7e2f885ee863c04d7fbfa9d474d0e37c7e25026220d0ef3f9035712f9b29d098a0016ebad27e977a25192816666f2714f68899897369dfc317c80438ae83d5513504e6f13ea30f2414253666e4ba6b7f4ed034d9222ab2a85148d2924d43dbaa3987b5ea9e8b133b1e0b932acbbfde58a5b50d364dc171c7d0832a598a9235ec1c079320fcb7130d7622504ebf291ea9c3211c7e9baa968c26027c1d55345c439c4f245f72c000f384e33062e2630d2a941438bbf33d92a3ee84d163e45d90d6be59ef73eac02a06700f50a52df2779041ce4bdfde9399bf28ab286cfc082f5b2886aa4c56bb3f2480805222fa4706b498983f5a83b505f5be6f74ec4014bfb7bbb0d1fc242090564b898a691ccd071ac1ab14d6e1d9c9afea7b8668991fd7a893587204b43074a943d4b8b96aa5e73a0e2da49227eeb69b4ab98c3dc75d5e44fa232c9e2ca64a8e26c46e7225480165b6529880ca2da40b0082cc68d5385686b4bbf074d43d2e23209ba3278fc9d1aac01cb9ee926d51c390072f63710f2e317a30821551d8cb7e00e4c3f2ba08ab8eeda4569c2c831891469c934203ae0c5fb52780912fa84073500aa178420a80ea6a9715af04646177691f55a2be25fddc9a9b120d526a995d10527490c7a1914ca70691a2ff0f6c99b2f2a90589fa83f3b992505d8bcee70e513c144474b63109d0321435930e9f6190b8ca978795fc7f2b4a2364f524ed754825e2782d5ea72722ea28184efb8c35970b642b65f25e13e72e8a1444f36542b1a6a8895bfe3f77b9662205753fbc0d8257da71b82ffefe7fb5a42627c05184a6dc1c8d2900e5f586d21d08aff5d11f4fb13a636482b990677a6f908a8356d8862d00b95b09ac624b3d8b05f2945da73bad3863568563a2b99dae1e17a2d80de2a3905294fe1f0d783dd60fbd6dbefdc33e2a96d25754a944355adcadec93ed94adcfef2f4aa5fda624b32456e3c3b8fc9310ac8c9beef0da39e8caf9a8f02f8a2d6284ac4722c04ffe1852c2c358481705fb19bef04493de59b23b6ab83c096da72218576f5e27299d9c572034b32cad1a306e3a0bfcf5a56a2719fd50e66a088ec40f3b852e98eb2af1271f03aef7e45dc35becdf95012145bf44516df1290df48c420369ffb6e91b2aa0be90cb44b62d166fb824b108644495cc82d4e0d2a1d45877df301882fa4081a55038defaaa92c803777677c578c00b60269dbde4f3504be3167831ee5a8886511bf109038dc3180ea22c4d397c48e9e60eca1d2d46adb21f3ae828428440224df3a8617b4c887fa2c55ffe877ae9bde2a5740f40bc06d6e630fc06e2c7f5b8fadc6bd3b7cea6d8e37f7e6a354cfc7a6c168eb854e4c4899210ea8278ed2dfefacb7a15baa88c1624ae90dbfd49cdb344f87d40b20fd16ba705687b5b51d580d75f97e390b19129724845cc3c55d3c9c1b017daef129956efcda6c8ecb00270a19403f327dca5d8c50f3e4cc0960ef0a2ec34a251cd48924a14104621bfb54799afbc7d6432b32ec424a98785d7da4bca1f698cb7727cf2cfae88680604c8ea8b7cc53e4f75165559a8f35fb1d361c7610c0502717d371b5d3dc0864f223ee9269808387515e5c5a958df37c90bc483bec6d275c0eba041b0b189668078fb2f0f2df44518ef8584b35330de5cd3927c815a665940e0560381b821af835023dd1fbcacdcfc0f2aac0d7f7ef42f4a4044b151f60bf8eb0980f471b1207ddfc4279b7a211ce187a6546141e462bb1100e467e4e3bf6c1419d5051080e0662027a924b803043ffcc11fc344b19e4b22416b5e8799c9fcd70a120928f3b47d2c5cb22692d1200262d089e9fa89ba2384380c6b7a09997bc5e78f67a64fa0cd4adf6ef4705c34657aedc553ec3e223758840b3b48e23425fe82a188660dc6a7537f3aa621973e4cf3b4c8db0bc7b30fce2b7884085253c20c4b24a6b5a61160b82e1f49615ca16d0cf74a0abf9ca28f5254d03d26b880cb47c5ac199d43794f7fc7f1b6a980681d080e14422f0e588fc383c025c1677c258425926a378a206a03a9019b184a86e7a3f95be325e359e613592800499304268b0d46db897716ed15d381e04d6dc96c24b6a29c5247ef8f8b71167b29d2b76581aa9b2eee1548c0027619440c062c62521ee1b0fc15a23bb985cf93dca0b4eddd369a1307f23adaa9f2cbb88cb7b49d5ffbb0309b21322e35ea347bd7cbba2ec6607a1b27b16acae3500c21b04f15550cf6220c10766531539e79ff90f866e93f8b409f31213fd1b113c20a9435c60d2e085b272627f489565d261c5f92ef81f34ec05af7b08b15c69948bae87834f90212dc1283f709d411d875068ea6473f2e1c2410e36e281455eec1c2998e75931cdcb6513f8ccb099be8bfce4de017b0131383b6fb1dbd0eea185c239c8e33dda75ba749ac362f4957b8bb5506ccf773323fc8bf08a5bb4ac4f9d1545910670040e66f88f1ed6ab8b43593bfec86c08cd9e40e1db5a043edd56aca85ea83878e71a2f4166477216e2c4e0c290b722695d773c3cddd0385644425cbd7c8c6ffb942789b01e7280354d41df25d7bdee59a18aa079b15b8e327d3c3983073ab726f2b99717a6b0ba019d10362f4d9816e1c18e406699d14159dc290c8c58957c42d6119ec41b0ae6c0283143d6d02b2b9930555a82bac728f49a1a19e5ce4d67fcae26ae80f9f4425602c60a45e5e469b8dbc8c50ef06a8383f7bf2b3703cf24cee3fe599416132ade5bcaefe2dd214a91fc3621af3f7b8d0784fc718a32e5735ed7fbae5f842f85b8d761b6c66eaa64e255058cfdc2e251cf31a6046fd2e598592705a0dbfeb1b4265f1cc5b8f01bad3011798fe658daba8ca2cd65c9497b67a9e6d71d2f2874a8f8b200ee6379d96cd5fe30c8facac73b631ba647e71406b02608636596542bc032fed518b3e5c6a9d61e91f288b8edc8a6a44483adab16a4b74e8ed5540f8ece1057c81e6360567e4a736f2aa193d26fddffa1f97d20f0fdaad1d92240769d55f95fd9beceafe0f89ee3d225ccfa5fc7b955ad3a885a3280afdc36847d61b26267c193ed4bbd723bf64dc1baaa2ba3745aee272831eedf5e40f8dc14fb053a6aac72c2355516c8ecd9c250793a6e6e0f9133422058f37a2252cd34597db00e25bcb78ccbb71cf8c9ab5e94e7c8c16a99f46bd1fd698c9030f2a5ea578bdba550e25a2c9ee8ae105d530a26230a155bd2403d4ca0635d93177f1bd55d60b4317e24151c627e0a658c3d7ac38a005bf61afcf2a0ad03fdc609e753f4ae467edfbc88d9dcd6da1669be160fbd41fcfc900756b8ef2267583f572bd253645d9643212367302e3655a4a6d9de7b5b84526a28abeb4885d895627fe5bcacb802018120968e9ace8122e1c74b5931d81799cf6ec11180995d12aeda599e79eacead0bc89c8d6a1cba2c035db699754150d9ae8b3f45e67facfcfcb06610ac49ee93b06f1bede92d7b73ced7dfa2b3357ef8dd77237f62d33827ef47e05b88752fdbf0d601b85a83c417b3b6b85fefa9003fcc38a78aa07d97ff1c3e2e56325f21c9f8ba4ddc74b0226c121c595abfcf2012e9f538968d6bdfc06a7851f07462d60534e3e4a679b23f221671b75a8c88f40ad3826d184d7da988d0fa5dc753bc53a941f7abd3678feb2cf01be3beef8cca878e6e57e34a8faa0e22d0587b3d6c9a89e38e459efee759084a10d097d63af4997df34d31e45ff4f483aef95dfa1acbe511b07024b9ea8b2a4dd94cf0077068af9ac11580c1547f79bc381365b9b609d17ee7ab8528592193e9c9895c81dd0fc5c7d83541d596e7afee17c4d20f49cbab0c24fce13c78acdac630ebde1a6b770dcad4104d73b702996d15eb1c11763392312e581be68bc72df19e05358c4292d59bafba0c3a8afd221d543400965eb8f175cd279085e51600033c0b07b4e6db96542973e8336b0bff15b47340e542b0b51308c9479272a23b9a66708a889bb37b28a1d4a1bc1edbe0dbcf02b6d1e24e2645d9b44e21000c2d74d975c6cc4e8e7b99f9b8cf95171b27402366c1035e39eeaa0e854d4831fc5cdee34bcaca9a0ee4171a67a137dd7e19aa826815a69af58804e418257266c89ca5fdd88128a57a94b504648cd605b2d21b2f894716c68a138041083c88bd4789e80d174df410a2b0c2cb8d9e01c6a0a030ed600a58661115c9b016851634065e1e7c1a18084e7f01b8b21c8f3f4cb24182021b75b398c6e8b02643a52972e9bfd047f0975430a0a1c24557087bc346a5ddb2b2dcb5a77efa717e8088f62351b7d2dae0fb0dac9ed03d82818d3204fab3678358c80c40f6a88f3822106f823939eac4855cfb9e8af3755fd94063d93a8025622e9a3508f4f7dd3c58dae396fb0a46af4b9514b710f79fdc2ccc8beff22520e222a9ca6e743c250d8de832cd2fd06898840d5fce0d13c61ffd6c682f6ab116d9b4c8c6dea6e8079277da7aae1d2bad416d508fc15285edc85c11ab8e697a10e9f71b89752087f7f4ef659158aa98fa251046e0081a7bd1e371efb5d105267cc50ca72cefeae8c5b3cf635ee3f1108c26c6a2863d3d0798ddf021292263cc283c2ab8b3926729cf54c6409a4c2465e4109390f01fc0d048ad38e9152105809291d6062fda7645cce9068a4b2ad47c14e098c7806122c3dc8b4d560b1e37dce35fb45f7b0d79f763b920264510a7ce2d14398b0fedbf709e7e83f6d62af014f07ec59fb25217befbda59452ca94523c0aa708a3087065edcf53dc8e68c762e2537d11516ca2c55741225fc59def2833d23b3bad39d36b3b1c907bfc288e00391c8e3d7140541bf7996aca44e7a7da8b95d6123f9ed6b891055f6e14a27d779f968409fbc53bbf3ead42a67fdd6e98bfcdb81d51f91bf7dca7c5b8ba3ae5438dfa2e3aaea30743681304967b4e9483ffc4f75048a060fb3fad51ac278a2011f6f1f3b9589783ffc44f28fa0fedbe5abb322c2decc76e6e19fb7123dd253e5446c90a2b46259e036b8cfdd1c4e72e41890e9be05afc4243e3d13d7af402891320ec08d1f8f47c39c21a9fe8d18bba4db4820549e83667543b557c6185aac80c184fa413dc3d7289627ac2e9726b4b9bcbad2d54b6acb9dcda52a6b565ccd52eb7b684b9fdda0532dee47bec34f72e7f92232c74db53a243b9b0ab5173ef6e284c7c508ab8b28b91fba0f41019cf07a5c9a852042bdd978b95fbc4bb0f0a13773e5543c4edad08a37167e4ad888cb9cec9451e7748b9be7ed51823ecac288106adb870b95505122efb7fd083b8d0a7193bc8c25f7613e1eb65a487eb164ac66cc4902384b091a694ecb27b3a5358e32521363da3aed5de2e3661a7cc6a1067f31c93eb9c1a657907c746ce0d1d9842398e1d4fc146f3dce09e540e1c004801eae0f1ef712e477700601574f8fc0a1c64a1f31d2ab8e7d33f2b700b2cb8b003c883413ffe420bcec3855601310c4131bc10001e5048e532c0e04331345100b848480032180dc11e44eea3c8671040d360c435f4e81f3ef8ce0057340cc063ac018783e267407ec0a31b64155147d602c53337c629e784186683bc5145462985145248218514524861a66d2c15d82fa583894c1f9f8787a2c9eb1e3f3b5ce0a0f85f0a188ec5c9a9393a5107e5a81dbb63a3de80366e0020ea985f218779a7b50a26f6b12be4380ba8de6183bd9f165c000a7a81870a861802202483e4f89e4e26d3b56dda956d18765d5bbd28dde625b7b8399157d442140090d10b3d543e628842340cd550f4c3e8fa58d10007b01d79408e820821c0101b8814b9a100468e18008703e480001d90b0922440014a16c080062c71c00320c024021298c00e14f8786852010b5ca007273e60e049067ed000101be0400782f00084481f188288a4228c384209892494882205044b4c61a289105071e2091154190109a0b05202134471458a294e8005055464d192822aacd8c245052be8c28216b8c0cb0bae80c19718c8600660b0a0410dc2d8200b2dc46c71031c7091031d743166073ce801191ffcc08b325f9801e30c9a1610d2044108435013861863ac2102194560538611cc6873061a692c1d01094970a3842530418d2638a19fd06f1a0a1d855e03e90343109154841147282191841251a4806089294c3411022a4e54198193008a68a5046e8228e21529a6a827c002e46141011559b4c02d55f32d4bd886fc2d417777775bd1dddddddd4da5bbbb9ba384f106a5f60bc64bce8b5e55528a65da663a599c1c1dd48e8d1b291c29603c54ca1c590e00e8f84ea31c5fc83c38f8860a30d5367ce20ddf5941da80281666266fb4b083ee481daf6ad406d0cf85a2392d60dbb5f3820b746b1d1ba05c89b31901d2a4a41b679a66dab1d900e5d65f613332ff92dc052b6a0b221f5361127b41a33d9a8ee9faa732472b83b11d463969bdb04cdb4c278b93a383dab191d262ef5015f1206c0ec918dbffc341f0b314aa6069b1fe594f0e1dd4ff6a2ee36e6b154eec830357d0711676e08e1b1e8e1f1e6f21870b3a1a880b52815f5881c78e56fdc0e002c7100403c0c385608001d88e3c1986888ab4e65854580118f5f0f1450d3d030d3f8450c38f159a3b006f003f803000204741840c1962830d448864453ca12dd5b394ba4193a191a431b455f7d0b04cdc336205d1111c88b6230f8703e480001d90b0922440014a16c080062c71c00320c024021298c00e14f8786852010b5ca007273e60e049067ed000101be0400782f0801050903e30041149451871841212492811450a089698c2441321a0e2c41322a832022e24e00285951298208a2b524c71022c28a0228b96145461056b8b55c10abab0a0052ef0f2822b60f02506329801182c6850833036c8420b315bdc00075ce440075d8cd9010f7a40c6075ec0a0085ea46006647cf18508cdb1b2d816038c18a0391383edc84383a6058434dd1c5010a610c2144398424dfc9e623bf280d48421c61a22905104366c8c80023350d01c121d003913f7fc0c349a8aedc81382edffbcbbd44760e25e8b065e6ec6681acd0a2a9d8d4646d82970ee354cf1e30e368acd6486baa041ee5c6ea520e9f2c6f235d628ce2bef85379bd9a5d54adbe115e5c53f4cdf8f6b24da26f4c7184f6cc4ec13a330334f57be6c6971e32736b26d45763f28658512cafd341b975b5ab0b899d4dc3b819d382eb7a8207333a939fc24b7119952ae5cfab5d60a83c08cfba05c4c3e775509238c4d0051e13b0fd14810d77bc862527d236a5871f1f9ad2c665ccf008e356e8544475c6fc4c52d2d52ae3bd6455785a19e5aa0365498397aa4cf4e9c2e4018c3aa7249154ee95300abca71992ec330f646607f3d275d6f44cf8acbe5569619780672dc2738aec7ea3e3b2b2e53f2c7872eac2e2ee97a234c2b2e535e8f1d8d6175714944f01a2b2ef38da02b2e35be3c42002b2304b0e2329f81a8c33299f4a1fe939e7b82dfa2a28c0bb9ee3694eb5d067aee131c1766c0ff897f7d6e6551e2424e759bc61d6843764d91fe94dd3397732be7c3137a9df01a400c1f12c146d7ffd3e1c3937a4f495c4ccff3fc39b21c3852e0726ee619d4727034f48fbfc66551b2aba41ccfa57fe37ce8ee4ae1f44e3a4b4f52921176e79fa42eea6ddc7823542b2e393aafa45ae5e88cf855ca49af71717c0d6c64df9f0636c2c9d179ff1e6c847a7f2336da31b271e3fd89d828f5fe436ca4bdbf0c6c44df5f888d70a4f0fe31b0d1f5fe30b0d1093e0298873fcb3dfe82d3887127fa091701ac1247204930a1a0566a092e1360516453f099939fe0b27c08085603c702614f589090729092702c0a94947494947270a8983205e553a8e8e464a95265c756b182d2d172e58a8d7a05cb0e2a055ab4dc885ab4741597e543ddc5bdeef17597cf52dc385c0e2e057fb4eed25e76aeb8145787cba2a45ae5f81c2e8b52d12ac7a37672bcc5e952dc0ff56a7f83fbc15eed6d703fa4aed665c9d1a57ca86bcf594873e2f8b5eed15ffa0bd75e749929c678f9e2f266468231cf5034b57501014b93054113c23604939a5318560c9c3172d6e8100145c64e116cb0b95146ca0838cc48a10dcf193d68e44803004b3a8ef048e092d0b95141093e4b5881092ca8b1a3099e137e9ed0c21b17a0001485202de37a8d1790787c4035040c44c490148022848c90e188212522248a9210801246517a48f101821996a0614a0d4cfc68e28660a5659c5359e28007408049042430811d28f0f1d0a40216b8400f4eb48ccbe183967100d0f15ca742c6f9acc0c20eefa7051780825ee0a182218600a4e04fc611a5e04f2bd12af858005e1768292058620a134d84808a134f88a0ca084800455f56503b366ea470a4c0a3754f0e00e878ae53c167051676783f2db80014f48206796430bcb9450a7004871c746025400903963ce0f4191309ec7003464a2d1fb8b9f1db4d12fdc6936ebcbd61c05f08cb8d885fd9f9161cc4dda37dca852663a1b12c34f6eb315ebe7801c342d73da0b6e25e63c9819959b3f206199b3669d49029c30517ebcfa8cbdfdddddddd9d7499bf9e72f9bbbbbfb02c302c333333ab847cb2242ab00e615be9ce5255f4802caa072e719d495b2439b0ddac0307edc0b6bfd690db4d9d921d28c04154c067ee8310c228a6704cdce32a9a2fbb13c99ab3b8dcaa8114174917d0e8728b0645b8df93fee17dc5bdf831e6e08bbfd09cb153c2c47b00eb470e488c50763c43a05cd931ec326474c0542cd70805764f91996e9c6526471cacb9b03f26b37151046cb9c69c1c841f23f47fef7e4ca609134e3772728c5d67047645e017795d6ebcf1c890df6fd2438c8da414575f5ff97a4bf401e243dcc2410eeab54959acb9f4db1fbebc2c1f8ad63e8dfedec55a5950d8f89dad515e91559fcbad1b68b90f74b9b54515770b28dccc371de8eb40b92dcc5ce7764424a4d5c5714bcc9bebdc0b9737c88a7f842d1417227ab3c9c4a0b91c74b985032bee31e7b8dc1203e67ab7f77b478d83f8fb0519a440aa2ccad0f70a7fe8c3a24bbf222095900fc518ad54baa63bd63ae9533af4558d7e11a5944a89e2c657e243403ec4ad2cb05cfa2a1fa297b2ec8d83e0ea79d321ae6a17841094d5482dcd02c39f2fe7f2634d94f2b672e1bb0dc05cf851cc96dbef3fe5cab9ca4dc4cdc29d392c29acfc8d83e0570eae1c00360589b0fed960c7ba62a556395f39c7ed3fe94b7903336e8c5db5eecd871caa755c6edd60cce54de320f8504628e5363948ce8d524a4ddd6990f3f92c286c57ad8cd7fbcd72754108b1aadd749765642ca5853dbb2453ec97f2ae04720f482554e444dacbffd1e3444b525c0f0b487347dccbc13df99c42b2856df3a5964035b503f24e5f52fa18770379f563f46e0722d7f8a7650fdb8a7bfc45d248c96ae40e94ae944e95546e86a43037bbc262a5e08f3cc22253e68c7497594cb9f4bdeb2aaf70b96583316ee65928ddcad1db57ae0809d10a24c47c3907351032cfab1752fade1b4bff7b1fef8b5bb9799de3811cb4e6d6af5d45f2045b2be5960dc6dcca5db7b1602952847e11222c176358d3a4fc0a89bc2f957529f8239f6582a553994c6bcddaef6a8578ac1f58967bf3bf1ecb1d813ff3594fd83bad0f5d4feb6b3ce6722b0c1bfada111f9a2c26076d075aee7cabddc964eefcde6e9821a906b71f880fcd9014e64e1b78b9f38bf8906c1e6ae69a96414dcb9cb9dda5e913c2a5dca23bc7284d9f1027de86f8a99bd3b439d1ee13d3e684c7b84f4cdf57e34ea72d08a669bf853933afebdb8260af09c9be8f9a6abc098998c9b76fcef41b8699e076e4a4e99cd414b73771bc717cb32d08f6da67dbd1d741b2efcebeb9eba536398cfbea47ffea2a3666fed5e24c6b5a58811ed01413e5cee9fe50459f7dfac81102b877840b4ac6f987534a1f86cb2d2cae5c0723c6fd54aa22eec9a3ee80b827e50f25fbd92ba5122ede5c296536b54e81e585f5da9452cab1a0f0faed7683fff53eae0ce55ee55bb4f5534e08daafaff84d92844dd5970fc446d9cca80a975b58f8e0f636248ac1e50371a39f4f5f94c300c9819babd21e54edc97d5d3f792eb7b028e2f626392882d1c19def123b42b60e5855521cf43d91cfdb0d957bf766ad1565efed343238e54a29bfc8c7952fe59194fdc589769ebfc3f81013a1c69071229d33699ce8c6f3f71a364e64e3f97bc987d8b449a3864c1931ee311714cc0dcefa8f7c1b5c8fffc8df4171450ec47fe4d300cbe571b985859bdbdb510f1c243f83d03d39c4adf622bfbf84b952c6332c1be94e029184a4c4462cdf091bcd97df44b249d3a6db1839df276bda3cc1c2ff54f087b7171fe24b0404d01be94957ca06e38cfd6753a8eb25aa6b2b40582fb96c35aefc5e235fd6cecb950f0424d279f9fd4587eb2ffec3395bb6c2723a9ceeab9f6d3297cf5cfefaca95fc971abd74f9a9fcc93ec5e41996ee7e1f405845f868ee228c165b4c1f14bffed63b56150b9f85bbc1c9411e7dc32084d424ad4391a1509facd5da54eadff35473b286b0107e26bfcae3a4a1701f66f26794905297cd1443c18f5faadcf9d32794d8f1888ca38fe75ea7b49e5a2707e97cec8a17f7c46fac335e6cc618dfb5940f7ddd13671161e57f3e777e8f13f14b3bad13c555cf8c7bfca7a9cfed946629e7d5bfae7a03fcd96ba6c8cfa4111efc5b0645973b1ebc834ec4df7fc80f0de54291d117e3050b951824b959f3a5cce93ab1b2ed48fcec7483c641d83d76cfb40de1f720fe0366725abbe1102d0684f0ad9583f87170802b9ca323f373b61c2cfc49a572b62042f8e2e020ff231c1cc44f371c7ca5435ccd8ee1cfa9efdcea36c47550413a1b0ebdd2899ac7eb1db509b9ea9fdeb41d5d1d8b8a85bf6dbc1dd58e4505251fb5e9105792caf79b45764108b18a1d14023a6522eb353ed4f62f17852173660949a9ca152ddee50b737199532a27802f01624ab36123eea233eb43a8f93fdedcf940a6853f3349082651ad421ead6d73e7a3666b076bee9c1c661b32a55cb9d7e54e3bfef9ac068ec9ba4bcb622ba0e2ffa9d477d6d3b21891af6265351f2fddf9d1e7d121ae520fe566f171fbfe8099ca02476e773c365e07e7f499b448742173a10c9062b0f445cb3dc30ac6023532154a8b95db5728ddee9ef84d9dd658c19a1be3a738863f7635375608acbf7d7f1ce2a45a6f068074c3c11d6ad78643afaeede80811a9c7361de22a653fc3d150512c122dd872a3ca22d1535229d467d53dd497caa34dedc9a5502ee59a68d7d4f515cd63e73b09f5d26aeea150dcd7739ba9d8e81e0ad555f7be26ff59d6dacecee770be1de57cd694be10beb4e3a95a735b367fe7330eca9da89ddf763cfbd5fe89fb8aaedde97c8050f66393a2db6fbbe89eceb3cefff0de8e6c7441745690c49b4ec7a262af4c4c6bf1a1ea9e6433b514c77ac2b2e2771735b8a8b999a675cfdfb2d9dd5d392742dcfabdfdc6a5dc8bcf3263af6f245703be004c8c2d17a8b9f19b4afc4c889daba8ed347d945c45944e2a421ae5a59f9383035590289ed2e264dab40cbb2a9d3242ef33d2dc4f8b31ba00763bcf19bb591da58a2851a224a1944494250c60c0922552b24cf6f5026137840d9b9f9b33f27b0c1c43e1fe17f347937f72fc1c4f1885b80f3aa137f64f277dc44925b4784594327ab9228a762178d98efab38ca9945232d71fa394f1bfa4a9926683f47edba3b289633f6a5f73627761751382fde933de8e268642713daf53e45e5fe97634619683d360acd44ef2c46d47ded532d6f485fb8af893a39856bfbed9cbec66f235b91d651188a814af54ea2b9a47ffb51d49da03afb58b36b0ee5abc4231c64b48ff753d944bb92fce8772a9ec62809121bb1fe114b1bf38a0fb5d2f2f2461506fb32baa7c0832a07bf4bd584dcc5e887fd6650fe5f6f5b25e4ffcd28e01308a561a3745d88aa395c6cd999610cab4d2ac6901618c0f333333ea6eddc52e8913ffc5baf2225fa3b5a54b860515e572cb8a375620e1dab8dcb2228d04e49417dff941b915c9106ca55ee9ec2d5a9f4143d47f7efb997ba4fec3c0ed4f0357fb8ed06c3f9675776b1d1007f5e4725cca7d41d72facbb7ee31ea9e7e8da95ea1e3dcdc37f7e06bbd65a7bba4710f3f00f226fed8038c89f763caeffd773bde32395f41246d36ae47c7811fdaf684acfe283165ddddd92eb49b9b15f642d31d68e0e6117e3ff8013c9126c7767596f42fc4a8ec749dff8f77dccd8cff31ac64d08652561fbd60c084af13d46df8a301a2d1fda783f6badcb9f3308bd5142c901751e07215142dd52615f49d9ec3efa526cdfe632bfbbfbea50f33f94d5b0af4755d5e332787c1ae93bed5093e5c6ca8ee11beef6715434040bbf37239de79ed481853e1104b67b5e73eff3bc5a236482edcdb2740005332c33d07d6ed41e8b19f7fdaa7a5b4564a78a2faab80ea154f7a520e21963bca2b9e24b177ec6ea62c3f8d0e74917fa900f35b75a539cca85ef4968ba403fd3e66651630fe33f4d340f0a960a79da55ae775f105a6e7c0f7cb9b1fbaefaac272cf4284ee461e00f7ce84a562e742c177ebee542f772e17bf630ae321ee36c5a8c93b9f08b97d951da7dbde54230fe03cf5cd8e4ce471d41da0475e94724f7e01f817bb852f7121bcdafcdf066c341f15da97b7419cc233e6c336e947fb9ac990c975b32107333aab15650abb529a77295fc073efbd713690fed522c27ece74a5bb051ec584b58772dee75cca4165d064db80ca3907ee3decc2857b99aba5f4a8d1b833495d6959b41f686d1b4051bf9922645d660facc95a8f1141b85a0723ff8aec53dfef9b5893095ffc06f0e08769e7b49b032c2cd08aadd4a1fec925a2eff6449e96616556280aa563df994cde58d0865732b6573a6cb75755576d4b5b405aa64ba5c7f0dd5cdd0cf30b165cdc2e5564bcde58dcc6c42c6483c67677bb8638dc0c297b44e02c4d3c79329db22e7e3687645ee359b8ce5048bd52ae98c7163a38d4e2952fc99a4ed0ec58db758e443cc19a498f95c02184b9c9d22180773c5dc762f952f2cd7bb7817227de7a40f37231d0f7d89bab5b1b8e7473d67cb2eb6d61d3983ed0cabc669b2093094180c2c9863e4ee6ed5e759ffea4e58f86054b9bd1db51635a82af2c117c218dddd1d0c22228721c34c187733646e8cce71e699bb9bb9023b2253e3dd9b11544fca27762c12d87e4ea3c48776debfb1f850cf2b4b5039d6f4ec4438885278ecd989789ea76b2d29e0e852db7fa91bdde779b2fb54372e71cf773a25ee39a33a9dee5379dea9fb9e3b8ca586adff719a5a299c3d4436dec7464cc2ce2733e6ab4a96a4a131be192aecf530946297314ec344c91236310e71cb4c14d7517e99f9c24d9925334997b7231ffadd7a8fb9e2559d234777f75ac685afc1771f18a3e029cc9dd2dcf3ae67f3b8634561f9f64ba11e20d189a7dd0c4057a7ee08c772cf9fa5a2cccc3ed8c8f4fe45b0ec894eff798fedeb03758fad3bd23cd868037a723d733db8e75717445e53170407f9fb1fa14990acf61f2f69aab9b45d79cd79a2277a4549a21a106472e8e189f3129929e5cae529e54a1931aebf895de5dafe4780c8a187276f5469ee948b0a35ec2302cb5f51d1f5ce7eebfcea7d32f016d71f462124ece7d3f3952af9101346abf40b7abd564a6917f97cb116f910d38339843c7a0ee20ec51d6b0adbb293526ef29913929d2a899da5bcb85e3ce54f869e4fe4397dbab8945239797a2a2166201f8265b8289382cb5b9830f163849a7bde5354944a3d915ed11b1b7f138a5d51ec585258f86e03301cc4ff15c5186311243abd3f139692253f64ed7f4884d3edf0f323e7b33380af4e5d11ec3e5bbb2bc910d6f45f9189cbb8afdff00471f8b13ad129d573ba2212767efc4f55244463918fa2d83cc4bfaeabe3a95254ae01f7a98a688c53462923b389453ec4c4b8431928ae7f13242c8a6c9511c5e5cd8875cf51cf413efee3ef233920f958c7ba627daa7c4f0868832f61e79384085b31ee9a14beccde639447f85431d5c7f3e9d8f15c9d93be4edce973d93d662963f4587d3c959452caffe165a65cf72d3818dccbab1284e4a0a49fa5c43d96eea9ee9ebd550e328ae87a20d5452f0b049f065524d4834a390f940a9539e2fafb1853bb0951453da8d417ad712b3d41c4a16395c04638e79c4b605b9952df29331b80aeb08f5fbd955e58a7823ffe49a2d8cfbb8ebd8f0ff1cb6a3ca0254cbc4d13ae5fd1a245e624b96359b17cf9e38c400850e488b330aec87ffc85dcf3674ee59e6bdc1b9e20cf3789124044d8f56c54dfdf8b1c4b8a4d5deeee3ea64d17646ec692ddf441799612967ee5e7a17a141eeacf9014e6f2466486a430b72af177736be456838dfa421974b9bc1db106846af500c95fb8dce2011437839ae476b07433ceda217734753c436e04f262e9faab6af42d7ee0c67f80e5eeb8dcf2c19b9bc12ffe72cb0b32378b5e70d1a54b9bfb35e936b7dfb57817d6076cffe75a7ccbe5f72e4dd82f4e2fae0cd16edf762d2e771b27e223dcd47b4ec4457c84b564871e804072a24652b25d88380c174ec4ab5eb16d354ec4aba1197ba9975a3e1873b9e5831fdcc8237fdeebc6f72851cc8deec1cf9522d1afe2f73c07bc1db17bdf37841d1a3f208343c4602000ca2abe07e41721bb236a58c58f9d97e168180630702c0775b95f45438ba7804695fbf95c5f22f6b773613f1f1f59398efbe2653494ce50e38c24589c33da58912589820504aba5a1461a6cd2e0220d354a80b9dc5ada72f9270ab6cb4b562eb796a2b4968cb848b7bb274b6ba29a34b260c21299d61217b12394d72769c27e7f61c5b086dafb86035d9d3a4e02c6c6ac6e47a688e2b6ed356d9ab8be04a8dc4aa3cb850fc487e085ef03f9d23c9691b19f5efe151c9ced5fb290ac94ffe33f0bfbd9af916223751f0aa9a56c257924b1797d2abef53edac7e1e82a7b4884f3f17ddcb3a6d495917e0e959476f28d9cba7aa40713998d8c543271d763f527f625fbb81d65a7e7e1f4f5a1dcbb99fe64dafe8743b91bd744bb1af692fbe2c5b0a65734c7b06c74557da87e29954ad571145c75045ada49d5a7bad98bb1f25550553fd6eef3b9b1bbdc68b2f199ae549068fba8baee36fbfe53ffc9f66f9dbf09a849d1adcfded51d94201167dd97ba6654ddca5d5125d458b6dcaeb75653955feb51cd5e5a94f63146a2ede337e5549c5011e783fb01846b2c9c962b5bd84f75e3f5ad71f2b3abd3aefd54d7cf29e5c569421f5fcaed88f60ca369f9786b9675550bebdf31661fb318b32cd33ecbb2aca35cedb3e74cebaa9c73c624a212c05cfe0a26f3b9f5596e46b65cfe5a69965db0fb9a702c232c7fecaa7b5d4a8cfd2258ab7bddbe3dff44712519748fbede936aeebe94849ef5ad9dc791b3289fd232834ccb8c302d23bc699911838b32a30b904a08853d8544ff6fafae2b0b7e112452e23f6bb0ee086f15fe0ad2ee887b9e83ec6243c805d2ffb4083f6ef121a7b917bb3ab3389d4b7dd5a39c5dbc4788f4b31e366a89040c4be1f3b8d7eaee5eab76bdf5a18c62f36bcff46bd60e769e3544835dff4fe7f2e3708fda3cfcb95db3dd4393753ee59ab3eee508e217763aaebfec083fdf12df79c0a6cd15badc62f3e5c296b07f7e7777c38673567864999b63ec7a1c0885f2fee1202f63256197883eeef57ccfd1bbe7908503fb7940a7cbad32902e65736b1791bb330c1601a9423823572ece192b2402af1aa5912f11423aa9a6c14cdb7cc82e6da331a31f33396146b76b72d94308b16cced7306d42fa7dc950c3b742ad290c321c6ce4a4ef0f7db31c1cfbbcca3c835083518317195e56fc55bb24a49ad62fb36e6d4bc2d1f94cea70d1360d07c7b4e570bdc2d1bec2cdc87cedb7ed08d32c9764250ec5915cb6aa5d7203d772260d425b5b9374c3de725cb4cf3296a7cf20a52729a5849a9c9993769363583e8f9a1932a640876e620e8a7c5b6604e152de8a301a4398d053caece5f3cc5935ec79ce096bcdfea259f6db963d9daeb1919cd3dfdd1d7b7f8bbae68c5a4f9896194bad36517cf021fe93ca90c8f473053f8bb3e766e2920c61fba92657b3c2caf18d70b571eefd3cdd52e37c55b91faa93209090eefc0cfb1863166346b15a63fc4b8b3b3c7ff68fbe63c3648d509ae62c634a3aa1cf197c84db9c53b66f493e80c4fdd853fad867708bd9a454831af614fb264a32fde9f97bb6e7b4215857631acb5e5c6ead41739bcb89c35efb3038047b0abbc8be6d1a36b32bc3ae8d085b6eb669b03d4268ba780539be58d59c4ef1905e50421861952cd7684139b6947f754f3cca2db6d4e5d61a2b2284f08a18ac5032817d4c35c3a9e3e3726b8c18ccedb30d334d88a3414ec88718ab3a279c2236ca79fe2cc7b669db86e8689487d26d6bea58f6a72d08fc4a397a21d7db910ef76d43e089833ce250ceaab1391cce5604fb8ad2205151cab144b9fe3eb26d0874c2c97b62a31ffcc2ce4934717d71b86ffbd8691bf6d84664767f6d43b6c7ba7a63831dca360f7f24616c198665db35b559449bbf991e87633f86126e864383edc48dd47bbd8665d01405cb46ad3524e0d71ac22c6a36301a174a230dbb2f8e20631f9ab3bbbd7bce88cd39d9486eddd9166476cf0c83700bd2d30629bbc8503cddf0aa713a1b49385b62b05ef36343cb417eb5d7007e2739c2f67fd508d6c6e5d61827b8f273ae846468854fe2ad446a67690e62bcb623b91dc9ae49ece05308a57cdf88c0cedec0f6a0e8864af55c6e89e1844bd95c88411869e59cf01a3c4468652466d8ed726b8c272084ee268a453b94b4625a0af1290ffdd33bfbf4e509de74a7a57ad8d8d850421e4c1c180f9a8c953b1e20c35aa7949473c26bb44941869367fd7ee63b84d0c884df04085144e647973eb8f02bb492b14fd6f974f4714f6add2fa3277d8851e64aa02b9fa5fc232c5b542ac6ca041b3b289d88c3547e3ce588ddd2de2823e47c8050cee884d7a8dd171f12911f7b3694924908a3cb009f7f4c2b05c1e48afc274ef42bd94945a25cf947c0f0405b9b4afdab52f0c73d69d43de0f758d30fb6938ea2e69edc8e628e9be220a97dd6198fd1f552fba9695ac742826bac23408db5c44a8385c6d45867d0ab6aac369e0f7d9fcfdc92dc832c33b4ad792034693e1435356b52da8d6d07f774349611688f0f7d9aa799eefb5cdf6fb31b548c256e8669362eb7c458737b333279a0afcdd7beb71b7ce8cb5ed334fa3cb3be48c0b0383456193c2936caee4b26d8e556186a6ec6a3b1d8d81c3945b05f275df92c326edc27eee343f0777820276ae23fdb11ec9810c1668fd26183b5c6cacbad30c6dcec7568ac3174682c3152ac3052e034969a1e6f3b8a8fc48cc5fee335dc0a63cb95bf830f452972248b0b39ec722b0c301772f3662b68ac21642c682c21743b3456106cf63e9ef63ec405befc1ecab3e6887b140182837b30611e6c045f8ec1410e3cdd0a894e9d0770fe64bb2070de1289d97b2d6856c3c230c2cd80741a4ee9384ca6fa1ad7c3419dbd077072c0e9b8cc3f7d920f653e3465b605d13a7a4d3e64ff646ad334fd66d73604727390bb7f0d73a4d8a8e7663d39b62326489260b31c5a8a8d725cf97c51975b613ce142274799cf76581d42d3fc2c3a8cd034bb76596c27516cc4f76797e5f431015c603f16a6aea8d46c1aa872e814c9080000004315000020100a070422a16030cd43796e0f14800d859644644e9e0724490ec32016860c83060800800800000844d33612dc812e86c086694ab98f852db23941376fac464705ba095040d5b851e52c5242ec9a7aa39dbd70a6c3be4eb3698018e82da4857ab1ec77303819924c419e13c4fb8041e206c1abb44b59eeace894f59d2e91f51514aee42be8e048b0c3be04f3daf2830ebe38645f05a5575e852fa975e13361820a14735fd0ebb4ceb60cb4d49f661242b3d77a8b3a8d7434da7078cc15a165026eef548583ebbde6bb6418f8344bc3b3a6252497cfaa01011aedb12cb9e94120d997f392a234f738544f467ef8f571e954dea3f046d6a15e9409c63d89bdcc9eaae08aa30360b751bd090122b5ac066d23c3695af2f172e08c843cd304d66d037c61827a077bfe0441d002ede5267b676e42fade4717deaeaa37025b5d9ce48772a07655ff10c25b0d6fd4454bc6a78bd077c6365e16efb4c6e060272b6b63eb589edd26533f20774244bfaecf825bce795dcd5883e30005fd0ec8ab4148427a2b7387f34700a340e9ab24fe7ec1d5543f90379c672e10d313be7e9d128d06f5e413901bd8523c86369eee56464507d7e5c782676d31e02403cfacdb78434f2d8126657078383dc3052b9b35833a31bed312c0f25780721416d5defc8019f2545d3d3af75c636b0de0062381e065fff8b215416bb492ad50d4e8da7e3c522ee24567a8ed8f864eff783652302060c48d4811844d83a97d92c7ec6f6868a53b880835572cfc41355b21ab5f8f1c7f1f4bbbc3507f15827c432873c83e8b411cf67151316533b1bb5776e0e87d7a8ff485b15aa29d561584fcde6f8f3e99a683e7b175249474fd02ec2352f7f9d2e9d5362024dba136ab9c7e88a624bf61d1d00c4cea29efc620f2ec42e0f1c71c68d09b5c3554b7a699283993f85484f2a5d82ba5951b55823f96ced225cfcf6022300533bf1c65d65aa0afa42162430f0a97c1952de4a4fb7ac8fd4583af030b300d4fd65a4f4eb6c1c6e6cadcc222e30f2113c3b278f725f8b5c480663e796d9ea27a38b9e48e95ebc24f4772b91af245b49765701bcbf5e0aed2da26c0f074556265fe15f94122d1cd8c500b3c78d0e1a0407212ed26db7561fb1532d55692447601856d278dd8953139f8732c3212dde20c7b0a06c124d08f87f34741e1f26a0e70ab4953e6b876f2976013a71e371a241e9db8aee387fc74f4874bd8d0e603736dfdc9b3c6a7b05016fe65d388a00ef711f8e6cb019e8d2b755eeaaadba78d7ef2f969335a3be22abaaee1735f8f30de20b1df3f949276db6f2dd5913b7e1616116bc798e241c0944841ceb9f26b1ff7fff4041d12820d7bb045ab877d368891745f65a1f3c4168b979b671b15de8933d8324d105d102aac6c58cdb51eeaf92739784ac4c4944ae544ed32343e2164eec9e3691b271a910249de0ba866560501f034493fd70f4b16120ad21aa4b9c15822699684b4d1eff1b306c01035dd2c96c035d63e260d58f42ba8494470239155847e0ef1a6d451ad282a2c288ddba9b6872e4a81e43494bf2b188289980857aab6abba9c9dd910c23ca68359953e23a14f69ba34e8239ee36ab144a8cf0120b5570e42d40ed05c5010611a42144277c482557c3e5a36c84cf0cca4e2d84eae57820a8a7c1ae48841f9c49f742c4a011d7397d5c3c378781d99ed57a9770fe47eda7bad8763ad9de8a330e653630c77211308ead976a547cc88a44658207d1b5ec525e00efdf1ee61c57dbb4320ab9171525d9da613c8701d733209054fb77e29215d60872d027c5d19f6aefbf2ce879acd7578a28a2f8525b5e34125541d4020af429868012515b8ce137a43e847516a693f89bbe5970fedc0eb47675c6bc3105e03e2c4597cae0d628e4aabf07b251b772acdd4c00cb66c0d5a0a18b97ebe289c248e21d41bb9c74f6707df38495ca53d3f2bf3b4ca3976a5f013434d1b38e6ed8a92f584d4bc319dc844e6d27db8d38ce3999910fe4470b385813582682667001edd045c17ba0cb7c002c869f22fd14bfa62a0085089a74aa99e9077daf63f1e7f61d3f291a3e991a26824f3daf2483c30200d3a7301147a977b447294a56da73869fee73d00fe5d718e2b16801644d2074cbcab3a4199f634f37510d004860b0bde6cbfabb51982cb945ab56d265438ab724ff1e796a03a300be5da5bd8dcaa4fd8b4df459a1a191c4356ab8128ec5def547355115e91211c8f9aafde37c83a75d114c4b7e43d4553cf2320ba9620a567fb0923cf3f018e3f85388f26e80334e39b14dbd27342503406c188166436b848e58241ca8ea33ba28f3c967148187750f77339129df1415aff44b0fad44d92cbe5aa365836604976125c8c680644dc18390f4661c63129ee2da7820445d2676ebefa8419358f7e3503449addd3ba5fb6027f253bf26487ba60e3fb57a5aa75fab4dc67c403a5f190aadc85e8e6e7d754d87d80804a1bea9d0d98c2824ba9f9f773de903730ba6ef0425d55ed75002889283e4b13feae70f6b13f1fb1d6f329ae30cf773db2b358a6f95198cbe95c47ce4c5b338400700168885ae4086026707a37053d36058025c0c73ad0d437136ea0c87cd6ea45cf2a4b7a4fdef4f0d426158b8e7445ed771d21ee015c04843f37c42b14df2dc22ca6c45f6bbaeb28686b8e4452326369e393906338bdeca2fb07f9e7365836c2792d7132838371b90f742e58a14e75cbccd011457f2c0b5f1445074ccfdac682084a54c776906921e7e9b755a46b10b23be13c0f248b7d33e1da9867c495ffe808801b562f73c4a4c7a6457a3e4990398f2b775318666dc14f31ec2d07514a24918a05a137b49b020ec80f925f7b4074e00461b81eeefb5e9acfefb10e7d810da758978cf868a2c7e15ed9c45cb24929d41385a854864a236884631111c136e419e1d3f3d2313b176675ae96fae48cb2ca1b4c67c5f76b1377fd9bb7abd7ae013c4bf915c301184a77726495c49ebeadab10afc91ceb9461849de3c709761479b02207a10e8452dcfd7f0d6c2a9da3794597483217b363e06b2d5f07f6d48fd626dfbc070920a473e43ec66bf7c268ca362d05801718437310971f8c9b3f0d0a976fb0e7742041eb4a57a55cf492166a9334ae76e91ce007a039aea9b3c3e5486f6a78db58dc1c75200c397b0495cc43308732c622ae4c58251f046b38eabf1e4b0debed4b7c51164f91eaec6cf372ed18b1015ef2de7e22df8cc61beacf42804a9cc8bf8032a917cd77a263a6ef40601d05e91ad031a3a650cca8f6d438ec85a69b8db46c59ec51eba214887245a3a5653048f2b928bbcc0584c32993b27858870aeba030c365028a7002890dc51a09656f0715ae4c49e14fb779695f39b8d8f0c0d4441024dbbd5fe57aa67c58265321d9b991ac42c360a2feca4ba2dc1f2464c80b6903d874e28b67eac603f43f98cfc584b0330a40971942c98f50fe6eaac9188de07a8789035fa818f6e09fe314e541a2846bf51105a2245a84ce74494774891bc0fe460af1be5e43c2e4c1f923a1313842ef89ed1afec0ab3e91278e3fcd6ed8d181274f5a7e516f8f49dc16c11a5e2232c715374258793d1d39d9ab9f8a3bfb03b76547471ae2a2a449ae2efd17e5166158829c09418dec527db721c215426aeb25f99f47f1b4a71f9c8779c9f05e5bc8e19120972438151f56f3f7198514743b35c63ab38ab9be64c4e76d5972f729f2e51179489e16d9035e93c537a81f137eb0253bd1ff8191ef8c98d487dca025e0fc7dd225bda045b5f658e78f3980c6a26c3226a8be7ca0b3c8c31156ecc19ea29e74c97f9aeab5c99c09a41ea60c8f4638ffc3b7f4c648b07294ded1bff5d677ea686dc14b556952957a188c7660a8390dcb4f47401ffaa87a5439c9029171a7a06e934cfce3771fcc98437e4e969e95fa3efcfb4e7014ef78bbe0891e44df6f482e806a1362d4e8ddb02599c820b5ed0590eb9f4470d4af1200c0594e62bd013c62824050df3eea61860412c3d5cbb6e6be75a2fdc22a9f09da1b2c39195e6a76ec36a2e69cc4b917055aa2b64c1ee86be36bbbc800a120d805e5b43adbb60227a6003dc605662a0a9f6c4d71c83b2fcdc4d63e494922ae23bd947e14e181b8bca28ee3a9537ce2bceb4868043d2032dd531663aae33f6fbd02f426c3d142ac86c8653d17cd5adde09b2b45756a757843dd0ca5b1cd112f058abc9c4f01d12b6f46a0ec61c969f4846812c4f05002023b282ad37980675063b5be00c2267007411ea23c225fe648425da787d5ddd24add73882c06cb56ad5c87548e00a5d46f5ce1f1055b2924a4949ebf83fd6f298c0515f658d3046c370cf1477caf866dd884cd8f89c52d75ee033d680fe1e050e226bf47c04c6def9c11a830857d9bca48aaaa49570ec9cf87d8e41ef5510273155fb378a59c9d613b85ab6f65fa04144186bb552d1bed52b015ca468bfa572dfdaa573c2c1f9bec698a10c3440c12095f4292114d2e1bedc8c15917ddfd0a2f346e7c1a103973a8021e4941b70803b62e0b028058d1f46eb25a32928ce25e816f68eb167900be53f830f747f2c58a7f59e4c3c76b51e026a310faf8145e4562e4b989c0b9a525d8c31c4cb17d45ac88213445a7af1452218d59f6d8b7880f0bf69af24f459f28f25d6bf9677dd04cc6f132d9920c11b1dded924400d574150d0c42443ce7f3a9846a277bb2831d6895f77fd3216ee81ded95d5055b46b2897a7a0fed828813354f4b95c512d88957870bbdb4d99340cd00f8e8618a881374254c05e5b688920a74a5600a76eefe4aa3b0f914d38932d8600619052510b1ad540e502b9f740c220a081f13301e80816f9e394263130d8eae64eb5eaab694ea76c34275d9500f93ff5c4eac7f3ce1203ab30ba718b29e016de95c5533a1dcb1970b468af10b56249414ab51b8b65c9255dc9cb68ca5e89a654b694f30b80de347b5acc761f9b4864705c85b4b5af3d29c57e62d66417671a1713084aefb6aa140bc6b6b825a012a15bf4480f34299efd965218d4e87784c60e280230170dca481f0f7d27b26de497a370368d08a980310edf5dad0523514b9bd7ed6ddaadf041ba01353d489067275be6eace19d28f33ff09ab59e2d1d8ff6660d4f3a1390327053ba17e683e42dc8c71e3d3880ecb8581ba34b0b01a96086ca87b71d81a6ff54287485528a18fe08e323e41988a8395c3c4c057733dc03863eb6c006c2c608a1baa778b8607d2aaf4042fc740e6f318eafbb1aef4bbd6a9c2a227b6c33d2099b191f23cca56ae16ef113016cafd7bb8d152c46613625446ca1c0bf1cd56e7962f4a6cfc0c80d75fb5a6ba8e306a85f446a9b8db83d166ca3a3afa7cf5f3a933613c5c545ae8508098ce4517d375c518a1c30ed75041dbb20f4c3a35c06b9f38f1fc5ed45cc87fb00fd3f38825595f74c67d253dafff80a563d85c3522c35b458acb3833128871631eb656f8e66e416e5a538dd47837698be5b6fc5097ee01920f7fedb0ff3812bc290e7ee5d42cd5a69904612ca4b5540b09f2509d84319f00e4a98d50cb326da46f8a818dbdc71ca7a782746f6565f4ab989df47b5435adcf0221cdede56633285166149c2e934141342c73cad36e817966995225270f134a849ea7285b99ed3b25b710a4ccd45b75dad2211309b8288a266547c28c19e86c18baf4bf5eda0d40c56bc1128ad74a69015cf5df7dd8317efd5e42bc9bd240bcfbe9d3aacbbb1248272d2381db5d58ec5d380ffb12e6338afa50f36816dac641c1e1db62d4f9b27869b91b06615f9018453d0150c20581dfe10cda857dc1ed03fc5d419d6b328f04c1cba4c0309301335a97ffbe9cba91a115e8ce4ce7e93e8893fe53ce5953286446f6fd4818ed50809def633e9df59b2bc92f2c230b36451e5aa23278c41a8ad9b345ef1d0fbfb733ddbabbf8f2f81f19fa22e29c1fcd17ec0ffd9955fa8c315a4a15daa8723f9f3d05d8a7076bccae41ff00288a10a718c804434ca699d1b1a16857ed65bf7a62d84d9e163cc1cdae5c9b86f292895a2887c63dc7b7411edbc2c90a19a56b23f9810023476dcdcba21d34afe3bf5ef4e6b0665e33ddfde948d32203c40cd79ec332f8d67ee21d143824c48197f1182b176a9d3e39dbc381ab124e3e1b5638ec26c4fb0763a5b990f7f80a57b5668269d3273fa6fe3911a86a57464cec7da6c91d0a4007c65ac1267d7c4d051d3638ff46bd4255f6b0063964c2db91e62806539d3eac9548008b861f4b7857174805521a435ecd208bd1e90de3ba0a6b7a1ee22920a2720f19b409516263b6688f6ec9b1b6230d0c449422fbe0f62b0272f6eedbf6eb7aa2b462fae7f3811c57288c4d8fb52db6f1900f9808248fd537b89633a6a7b4ceea0be9d2ee69b9442f0a71fe41204021ff0100edb47d8e61576ff15ce04e8d6d0d630814c591a5553f99eab7de0b8561ad1f0b6856bb33c39879d5bdb0c5c42e681160ba987abf36e53fb84e0ee8cb3cab1589adb9a7c05995b04b28245d47e01b0e9019a29c3bfc21b00c4e0abb40c484f7b251ac32301361bfdc9a2a6008683fd3f17f2bbe54fbcf2e546dffc61ffeed68bcd2c3d3c7479bef51796de36db28068983120bfe777d07e11956285f26ad0a643ccd7f028cc7ee957afe574c04b7eb06b15f044d13284d49273cd3d1258666e333280fd70659d19c996224c2a6e621896d0f1e2d9e811555bec5951baa2ce91a27e3edb7e116ff0da0a40188c6fa42e04edf100e9908c5404552d65c83e9d56ecb942dbe91b22f50ac0ff0d5554ba022b85f9c1cebcd61beeae17e56acf71516d68072ede173700d786d1cfc139b5173a8b60dc4f82b6568c61d6883e0314ceba6d839c6950d378260def4443f3563d306cebecf309f6bdb00493907ac23964a69e096259454593056862bc788fccdfd4814d0c42dd97e781b8021145cce3392bb8e7cd2031a6ff6d047cae1b419a9e20765000fca89317219e018b92046ad441e0f2c837dba71bcb6a8deceff546ff9c1782461d84eb337f29da129624c43d5a1344104d11737fa187cdd48f2735fda5faf2a1423d12a992a94b67f7a28b2ccb65801665ec63325405a7645c134160615481762a4bf318b5440204a7cfcde6e8a80404020ecc88db70f5b503857bf901195301298bb3b49bb3fd5c0012453302a18a637d80444911dfd1e348024a0fc028219e7614691523c9b5e83e4315bf7bf420bc04d1bf26ecc04fd79affbe3767ee605c7008057ee0cfbac35b720cce5bd33724dd509717818969686c9a48a6ae7b4d96b6637eb99e1a59c63ab7e98feb2e86252af79c1e3dcd2072f7d6a12c52289d2ffce47181dc35ae60a50d8b5f98a58402fc8e5324889d2bf820631623c3586985bf3508ca81b7df0848e04de97dcd5f80e92895b51cdbcc0e2ae8c477d4e8f0717d1fec88972e29063171216f87382f7024b3f5de25a3f5097c5fca96161e9d5c1bc9a8dc07a9529c277aab7b20c3621361c1a9370ef0b5d9d6760e0fcb6d10ecbca3d80a24f06118ca6e34aed17bd38319876eccc981c1b96a1ba1d9b9653006108e3a60d368785c05442ce9b97748ac0ba0167d16339fd9a24a1f45160341587785bb9b03236295a58267d075c398c01a074be62de63ab462006f870f729b26053497c70c41117b434aa4f376211da14d730a2d35467f744efdb772b62bed359096d22e91b7efcad4ff3510c321436e8d0cd319a158307d2b30ed3026203c1fca30935494bdb05aedd97912d823c80f49bf08dc5bd17e9bd482f8b7b2dd27bd1f44620592f82bc41e076f69e6ad84696f700ae469ec9b2b112e585bb8f1e3dcfac9ec1d9376464701ef1d16f7cf076e1303b279bf0108631646173980659d8f859ae10c8303d172f90f5b96acae6be165a5f36a57ffee4b43402d5047bbf88348f7031ba868620df0828b470edbb0778fbd3cba1244c2c7d6315973f7c6d10106d023716ad5741dc7bdf50e19f46513fb1caeda3c0c05994a85697980ef74b15f9a97ac8eb9e33d5598f7bd220404bfcd2a3db773f5657d61f538c55b1f8271c34f8e5f39eee5ca5fda91f4b60b609b4e46fd20060a80c6a22eb6307dd3e96d9a0d026eb1121ac0e2a22981b09064c9ba7f45043dc39aa30fec9d4eafb0cfbabb3d9dc3f6799e234239244ba9d9ef9d76e203b246a24eb0303facfdbeb58c4013bc0ce46fffd5d102958d9459cbead7712562bc8d75f1c4d8947ebd130813618f7120323864f3de8fbf0e7c5b514d71fe965d2b6b896541cacaa5c5c755831ed0f640c6305b329b25abb10978acbed53650785a0a0184b17d862a98c4e7745ff68c30ef7058fd3ef7359ed52413df9fd599cbd13ef45feccb5c9b26be0c3d39d0152ad7e3240c2c2a7f19b56d8202f00e5eec53c45e078decbeb41cefe492b0b214a29eab68cc2a24caef8de8cd855341db8b548ce4012c4f7d4e2ccae9a751671c31ba75dec84b08a18bc29e931bd8beff692d41636c1cdc57a2fd6dbe2de8bf65e84bd17483e0da16e00b512a93100078209c37ac554b3747d7f96a10072f0877073819d00d0d9c1a6a6147699f26dfa96feffb67ffc13651001d358129c6711b766caaac69168839c1fe8091b875b34e17d5e1a77d61f71960e19c444845909b5a01d8e7866454b67b91f2fad72c0eb46a2bff448337bdacd1ce589c24ea66a2a4044acfbdad6d7cb9ee5f1afb5e346d4deab12cc5dd19251715cfa01e143b8fb6a7feb4ac9dfe23b5fd10cb8fdcf755db74233b3936b6947bc0b6211a8549a683970e7f5ef7d463cf0f6f203fd82d22c6951306d1227453f2a6acd6a072701b00354d3946e341a6471ce5a02c638390118a106c8c58c13595c8296463b0f99165f152f5c3cc91ac03af1c3e9c0d68d9979af2d44dbf2d54e00b4b8934a00e7d7e69ee0934547e9548b5ec23668c2d9528170810c4a4a50ead1dcd2de8f478180260191466036cc032813d47721a27965276ac7fcfe9d533ceac4773254144bada95b6defba612d5acbdba1686ed2e540ddea5aaf98c6ba07e9029e139f98bbab1940602b962fb48fa9fc4558c46bb50fe50561485699a920fc6d0c52ba3f4b749b519213432e2ce97e1ae1af1eee56f50d0ef88f3892a5ede72e7ef8e64c01085c08cdee0a788af9f6f43d7bec9802ddba4bdadb86a173895c160c3f74be1f196e0e6c7cc6bef43dd98ba71c2cc9912af860de6db5f7c130c6d091c3994eb49c4cb0f827c7f82de81bcee76274e4736e9c70982b5c63491617083482f2344db18a4392b9c58a56ca00978c8165f55f9daa3298fd748a6d2fcbd6aea1178532221e78f0ac3fcaa02c39929e232ed91c10ddb4812ace00e47aff381a792c4182b7a028d156f7c75a68f0c1482ba9bf8fe1bc874f10691f04840985cdec19715f230f0dfdb473d6f61521d743ba4a8122cce9407ecf708e1438b394260ad21b678dcf76e607afde52f8aea64d6e4ac8a47d84db5c0155660e663928c8135e76fb06699a213ae6a6b927824cac0fee0864e81cbb0a916d8586b2f6614103edcebdc6c98c916d7b81f281060143c00ce50c0a28b8da368270741a250a94b113544968a5770b6c582fbe16520522b5fccf82a26c855c880f2038ca5ed0b2657bd373f42ce226ef2f96a95edaf00c4a029362800f5b666dc043566f7c27a169dff14d0456ef06a5abf36bb2434fd587095e4eb7f99a2ed51778c5eca37a070c3dff26ef0f4c31c468ec7b596fc00940c172f6274d4a82615f46ef949c261f56fa72f137e15213a751fbb6e086b1894c4b74cb1569a5ca5589286937de180a39192acee9e67402ed82962303ba3bd3ce2a066c198f387ceb7c91d52f06c38dceafcb2072944afa19c4dbbe5ce348d5f784974ed7ec59a1ad6aa7dcba31d6af975438de2c9c74e3a02db49557dddf4237633fbf72652d540ea6440f3698b23cc4079870622736d12762a2133951133d11133fb113c3f37389acf99a92fc554125ba76c95739052476bde00c1652f066417e5f1c8321bffeca24c04a05396a2ee8aaeaab17c92e748b5128ba10d8e2a3b56717ba961e55fcc9e1135c149cd289c513aa00adf767f0fca78f6db10f6ce64df83cf4d0edfffee443d89fdc2161a28586eca74e48c01f7b38dab53299ff9014b501aeee837fa49b7ea46b5ba1cda42973fff1c666492413f00f3524c5d3e94a3d97127783c86c4a85ec5b05f460b471ee19a29ee1696b7ca2a6141620def034aec59d4c202e3010d172cdf868205ed8951ea8709ed19c464318c52bdefc19289f6002f91468160e5e3983fd7009ae840ea256e4e4aa6db8d820b4cfb5341112acade6d2d85103dd5937457bd73d6b13829248a10d615c983ae39bc153461bd16ec6a736b06432b14ee4731089549ec0b08fd87130616f6e536ddf472d62bf5499e526816ebdc9077144d5e18d10909fcc308b0ce64d848944f9a5d4a2a7632234762d4523d5b0bf092a530cff673c33742eb948c62ba5d41542d759458d558c7c6ec500d50157516658ebcc666451b2cfeb385123b40fb4038b8323ece9238ba214ea7537ea216276622831129f6b3a5ce7f38821f69e340bb4779fa69c4305872ca4ae65168a5fb4111a714a1f6c84b443511eb3fbd7d41c64a0460453b5c82cf5c7616aa56a2562815bc6320f916bbc430c0e36fe79a6017f689343581bcc391ea238637176dc47ca9e55680e70dfc13bc4710965b3d6f11047bf9eb8edf7bcbc08de23a775e5c3e34ec3d5e473e057e11d259cff5d03964bd9f67604bf35dc9de6841f9d68e8874f83a3d4284a00c41ccd05bb82c03a0f65b5a3b90e57ccf36f3eb33d353ff2108a5f3e3308a638ced21b859f6f26205b93f4de62c79b9a5c09ed7f44fbadcac1605a0b77a6122965df368d02012cc0ba457c1b26c960ca100040dc599699476ef787c8b41c7298080fbfbb3d534acfc4ab40132e13df095522a837355f8f37362e88e2b47a09b66da8526d45095ee0ed537147585ca681472175e419be9eb43b4e97f40f7226da7caf72144a516a3c0fa7d1f18562cec090d5151d7c2c47e98a04f766c936c82fb3590fa065b2f34f6f6cd3ec4945fc96a50b80c56b7677fa7b5d8ff83b0892fc65166f3f3ef891847b6995a0ee4888648365f17c2937c9cf1a6854db3b0ca313c0d51acec610403aa62fa3ff29d7dcf611420ff428dfcf6e13b25f856aa62a30ff4989bb08a201faa62ab8926f62c4299beb46c838ffdea8677ab6ea80a87d3d4ae86ea1cf490a71ac97747374ffd63e2c347580aee29c41cd76c17f48be50721944c949cd4fe268943958caea1d59a4957dd3be5c7f0b95512a3c7e65013024c85144c5dbf33e001ac97b6b8ea38808f2a47cba0428a904540dbef568b676a68ad1aab5ece34e01093f8d474853c9279a98673672d0578c50040d434f95776e5374ec8c1806da47171940972648fdf9502dea31783d20a000f6803376050137e287840b3391a2556db8734a5b32f0d9bbcd0df8d1cd3e8767caf20bf6f6e15f0204eb5b7755fbae546e02ca22f43a3b5f752ce0422bff18de13b2e0b29a9c196815b8095e0532577d981230407e5bf03bdc605b5da7abef1302b2200b33cef4cbb0bd793d85b6388a9cd670a4047455ff4e707731b29b25e016da18e8cf38fa674ed936cfd3fda91884d102266a4654af1556d8f471a46b530b071df7fd7849e4719ff861ac5eb450d2aab0b0566bb0f57aff3600b9a7748ca93e7483751fba32c40ccda929355e2dc54dbe5879a9cadebe58ac9ae006c7be0de4bddac2b0315f682b726108070f873e596f1c60df022d85001561fa780b84ad6c1a8ade6e1c8138503656f69ad21d286b6d0e11f3a4ce0a8705ee6c5463821e4b04818b8424d6d645c1400beef28f3290036b66d291e31407ea4f665f0908cf8a478ba062e170b930697ed3baf14839b33901be26b0d2d7ea222e6616227761816c1631674dd25109506640ef696d2c01a8c18da882dee8cc4fa97f07998c8ebf0be1fc6500c27ead4815244d8c40060316fb458ecabaab1ee1b97b20ed9f506caa91178d1443cc2c544d94074e19c123e9cda182c6b30b97a03960551f9789bbc7aa38b4c472db9c0f4f277683df5ecb924d9dd0223ce41cd2dfe95807c0ce9354fcd5031e876429a55691fb9ac1a31e1d6796a20202378366fde984065db56834ccf65b1906e59583cc9f3c591d433a97df6310c3cd7f86c9e69b50f57ef91853a1193875f1cc97368455692d6b4ce78de2202158ac4e2f5b81cd5ac188898a49ffa73556754dc82278c4986c04fe3a440626a70ebe45d5e76a8a2fa404f7d7561822a466b900a41fb5dd5ed72f44a8de571ca16efb2e1ab94bee4f0684a1ca658895b70fb10ebd8fe30b0eb620ffce4363da2064fb09712259d278b7f0b838b05e51e0f9094a23c5fd35b2523373864f566148f3755fe4ca48f69ef9182d677d1a543239f95125fa0d00d5fd41ab455a44bdcbc92f145f2f2d4b902f03f523957b6604e7933ec72bb4e66ae2b48358441bbb411e01f814102785e327f6f0eb8f07631e2c896f3fb067a172c1b94c2e1b0daf48c47e26e2b8d3f72e2a478a647b4f4e79719fb6d1464464692c991e36b0d417c37913c6443c77375f167b39e6150614e7bb8a303de2e169ed4a99ce8a92644f81b2879e298c642f48d6a42fdfe3347fa540c843ae43eb6b3affb3a145a8bc7ed5f016a4b2884f47808d82e391ec94852ed626297a78e621d754fac5bacdf863834a0b43bb825fa5021ac0c89c950b25096c93b371663583dbcaac7ccdd0409d679037d2b30f928f156559c17eb9c4d2c2a7257c5f9b1c6c2be8fe741c4bd324350efcdf41373b2af964b4a9983a8d825de9809e2ae365f663667b112ab18ba27680e83881266ca43cefbdb4f50f04328905b273a5b844645b0a3f52fbc41a54daac219111056807dc9212761af1fd3a756f8324d3d6d72ce3c8925b208bf7d4f220f0b2acbd6525d0d6aef1d14471cf901eeda2cde81bf378b2588d74bb12bb0379c10e37d37436161aa82c150b0eaf68b93e1c4f8b95240cf7ab9d8dd0ceb6d8533742ece3082c56b009d0355630ae65b67e14c7994286ae186bab9007bb46ff9b3fe9f0a07dd0b5421b049d7d9bdd269c65795fccb0cb3b6f2041211dc8c0f5ad2172c6ccee0d7b799710aaae48eafb33f22e2478d4d360db30efd1f835421b5f6cd802e0c9ceb8deb630af4f2fd4ad453db9c46451612530270ef5eb8616b62eb88a31fe5788d9bcf2d9d096b639677d4f332aff30b46a8b98ada3611fc42eab7d354ce1e5a2b80256e86d07f65e4adc1e65ac5f048583c06524080c71317d4d572104a381d2660c8f9e405d24f77c4040e0372ae418341a78fc9aec9e4b48563ee4220ef0006511ff7c0c46bd71331794391d86a6d5e1a4be7989e2572eb90bc4e0db146b3157d1a219e31d766ce44ec07b50f5e6890de73b2ffe2c82be24121404f19ff80013f6236f00838b96186c17915bb4cc5845d705746cd70201a4768310eb2340c130d5630d282425fdf72d190ff00271fb267eae05ba83d2906006785ee9fcce877fbde855dc9fc9556755091604beda8971de329097de09e4b53b74702d89ada3e3c635e29014d51ce91cbd4e854a89ede70e212f0e53cf553c5c3ee328bb6e90b5165a7dc00e3d2d13377c5be5093b6e69eedb604bba909879516ab3b4de758f9c62415f7138a6babfb009fb8a6c96c09e3ea15349baa51fb5d5883dd341107f4a9b4b1a313256ee0a3557a63df1cefeeaea3108ed4224bf2b3d0fab0d77316b4b71a674124d7f8e97c1a77b35596eed47ed55888e32f547c8bc5a06da3579e1265db52517e45a7aa053213e5e40e103450d09d9a2254e7c5d25dfe80ef0993a657a1046d5101ec94b31cdaa44b0db440993fe706990ed0cae9503c847f9d6829f7d1f28e41f65289a5ca68a6a5e40b07c87be4d9476c9dd04d399e27dbc1986bb545093e53c0730fb47b295526287c2fa89adc455495a8965c9142b800e0b9cb5ca8af359c115f142df904e068d0d6848d9ddeed508736fa9723aeb812d0cbdf1d29dccd174b2881879cb3e78b04073316c431bab1a7c65aca4949395f402c01baf4925b97d024dd045bd02f45dfa7c8b4e32050d76af5c360f68c853837f35219d206c7ea64fed3e8ac674bac5edc364acf859db599e0d1de466693065432b78bb1132a71e8e729af5698efc41ba4a765310ad624fdfabeb21a336f57a7f39a3a4d73a7933a8c33fd2afaaf2d1269edbc07a555ab76518b69afe03506178e12fab7e411a7201b78698be1066ac61cff4cb307ba75f77e15735b2a2757139c3e1fb59b6695f05449029fae82a67a8698a9abd5583f00ca762dd4a91203c4bed9d0fc2084a1bb78150d21ec848a835c5132813c23b0fe5353c332bb1d7aa60c42a99663905b8c497c8696ecfd80c211c15b18fda2ae20548bed70170238fca972df0a02c209b2bba3b0b0c1072b3265cc5b59e51fb90df6c4ec1c1d6f026ea93df4739af20750727cda9c165fd0aa67e4caf1766a6c0246d34c147600ad133f6354f02335bade2219331cc3f64cd9c27dd70847092c1b76ac570e10133175b9a2f0568c8ecc6efa364e48bb07c0d18a0cb5d161268c2255b835bc836008a89f0d74b0733953995fc0107a0b8889cc6509c70b0cb690dae5fe69cab177688a3afe5df196fe6acf86b490b9a7554d5fd6be731258a04fa35be083699716d471f6f073d166a704186bd927243104cf1c7e3bb88adf8da847bc5025fe3991662b0d0002c203dcf9afe5fb3d78c0ba3b976672a2f29503c64c518f0c7b4f9e28e308e21a7b198781170e25482501c303b3ec660bcd69601402ded90b341ad86a5e0ede43c25d27e7f476092d3acfc9affa09b4ba482c8c30eea448f565a5da1cebba0e3c065a7c3d3bb40b2c4923ad3d49559b90eaaaef61e9d8d03be6d85d4b29d2e5b9d2c88f6e5282f2de8532cbd51f51e7ca61d541a9ba573ac1121ec7890d5eab820900e81fe9159248a93d510c921ff8787235bc342756605de0c078287e143a0a871f98ea13f9d598c8a229527c96209865399f53802be3c9c1422aba311b149cfc9aa26b7bd95302ecb2a2921c9ca5233dbdd0706fdbc414dcc8c041470d96c7b8988c970761255118a393106826cfb317ee119e06ed4e4b8ff04141d7e65f58ef2193f7094affb570a33656d147480cb521d987fc4fa05a4b43e0c6939c097e71d0e073aa50329211db70156920a8772e1271aeb509712bd6627ff74f4805da45e1f1488c9201cfa658f977854c50e43a8bcd21ed84edec229ce437f3c020ca5d0f29f98be6e0c9b548ff89a1c39c5d19db5769d1f90f9099b1e89004f844778c65c53a8b5b839aee118e93671974be19af17209a0e1f45d9049647e0ba9d3deeee72df87bbc1661949b451429214e4984af938bf3fbdce674154db674f6fc321ca409e244927f0e7cb3f032737071ef333da24ea103214ef6eb55d1094c6e881e2a47a16a6c8c2107d1f51960760e5e52dfe76ea7bade4e85f67ad68c0fd56bd4c94d556d81fa849f5bb0e9f48a719d6bafc6b050d2ac6ff300057b42c1984f0443c10525134d69f950c11b8e9f2db0a7c6760ab766e8c07b36a5ae50350ad67f4cdde87e4d13addcaa2fdc9e746635299d57724aa6aafbca4e6bd30347bcf76cf9f16aef98a11b581b751fd4db2b756ae97269914d7a0a1f9d2f4ea6d44a49f8ff01c1f1857112e29f765e5ada2f7e1077cd8fb054439a011dcd42b7eec52f519037c468d3fb4890967216e585cb912b5e2bcb4ca246b9957e00b436cbe690b265d0454e52b9bb78928ef08b8b6d772b4b466c231fc32c254ff2eb60747a846423ad8934d3a545b95f646cdff781cf421c5c7e53af84e3345e5acad6864951f6a4915f223a6db58e983d1ef1442e6e12d3e06de0826bf796b13caec89ae611319a7c6094c9e50dbdfdb850b00892a1caca395d6e288f3b7bbf768c882d96f67fb2214812abd4e1dbd31ed0077e546b3bc07662ca4c94b86997ab50a85ea800511a50f51e9ca7c778ff24debd2ca5924c22b87b584c8ede39f78ac2d1ac68905b8424f1d374d424ff96e57b1e4339ef2f49e24a330d66deeefa271460b46a8685ae470ad93094d54b323fd1fd4150e41602b100fd3d467fd9a72ff8e23deb57bf22f945b104e34e979f02c4553a70da895e472dec7bd951fdb1f815215057836671ece421e8b3aa1fe4d617551e773d627db18d829a50eddd06d84f95860ad5aecb7a71d8efce19abfa2e3d31c5ce701dc54d5945203208d98945324944e2e3ff72bfc9608788ec427514f32b97f53e19b75acf91c2e038b3e778884824f31840ba934a787decb587bce9cabf9290142adcdd4d08f54b35ef7d618735f0dacf1f32ced922711d68569fe0c9a52d8b4b7022215cc5b102b0f9c1ce7dafcb4aa3a0dd8e7cdde997b886e4af91526e1c807f2b2963656016ea84c88b51ea970b4cc3c4d6d3570bd74c43273d952069c7bb330ffa17b924952a4523659c659c3224a1f698360e2aedfa80b3b15548e6542f3c2f5f5886135e03b022d8ff8d3140c4dbae62b81cb8fb85f90b59b3c6e9acb4c8ac5c57270e0c788edb303bc455d8dfa10a23def5f09aa041b63b680eba4648037dc503ef500087f77e23c4418ecb85eb2ee902224594d5551b861ce20777e325c23508741964114ea4ad003974d636b3176284a5c6b7c0adda1c5ec272bf59a2cba1f4c17b6a84041dd2b15fa3524c32eecff9bb1f5871ffd5942d34887472b4813ac85dc1d429470af7e305f996588812c9d516d0c849a1704fe60d22d27b729ef4b088d478833c71d5c90cc08ad0114a862c55b797910587eb767cd8644ad68b2e7463427cb3a477447fc0b704c8fa0d987571eaedeceb76456668866c02e520dff8b01560aaa8d8e63743626da42135a614ebe622f1550d800a2c0312e1926dad25e0812d174b3e2dd50f46946dc3bfc71d3ed25840c88864587ae3d30335d4dd78dd76e92c163ea25ce14120d1fc65de409f6985912a5fdf38dcd4dbefa28e20ddbebfcd49c35cb64e4e9f63cfe57d4a0268c3f9457de52f3e0d21bef3c11e1afb3265a92545742bd60c365a41fe204d489184727e3f381420ce9de3359e01ff96d0724c0c1a1c899d847ed3c50fe0e24261aeb9fd7bf1019bcd52dd3d512c1d7481f26e3e1cccf49ec9faad03347ff66e5b0cb70f7ed79ef397066ff368f9bcf8de9ce3b4816479c8f3963f8f6ad3a6712d182817b379c8c102360d5132f6f4bd0546b3d4a7d4cad098a18b3644373d05119ac4fc60739cc23257c38dad381ee15fcd476017a9e349e1312f9ddcfb9515f9773a0ec74f4bbee38084edc7c75c69f83d71dfde1d336df0a780cbf3a7d89e0ec6806087dbe8fae1461a3e04254ee3e2c8b51c1283110b72012d660c6939ca696dd59890bea3d8c8bcfa293e846a4daa2b51e4295084d37d7c8e1a4921d3cb5fb911fea29817d6a08d28dbc8ae8afcb2bd2e96b7a8a4d5216db3a51cf6855a72d2599364c5b0353dd4b424ab4ab5a63bf8c24c0aa6f3f4b7c6b6ced6d76b1b1ed9cc7d86ed38fcc1f93da0b1de0bb2d36c0e07059ea3b4147b6816d99bbdd16071a3e533babd6f08f3a5a7ce67fe516207173ee597a6daf0abd43f8db5594de12f0b35e385c0bce1d3c88e9e5b6d5edc115000e3bc813f4e8c7fee9acff606a241e8e39a3414f6b4d457e74008668dd25ef98f5001af81de8e1e167354a02e762bf88f1dfd78e07b2e5425d3f98c110290488f569c32e007bacf26cb485328f5d6c44ad820d580b6d7aa7bb0a7692e16079a437037d1bfb2af3e55505f3de43ea42d0e051e0d661b87bd78f260a8b51c1a6a2005b7698bf994b1f48f6e3984e115028d88397f6facf4a7362198132627856ab31b4bbec0480fdbe5f29ecaf339efb9e10ac60e74791198412dfc1ea818d0f8504f551ac54588c38c0c2dbb0a351796cb1fbd6e6ea31719817455a32765f7611b59a151be7c2657890c062a32729a9679d9d2d263fa4c9cff36ff91a52b1189b6a3549104b0619712ca935da93ae5c2f7039a1d5ca71f49258327e957ce655a496591ba92dbf6fe566845fa5b2b1fe5daefe2916699c582ee5838b135fbd1a9903d44a4d482bd95fbb72275480019da142232c8fc32d806f15d8f221f88d68f57cd02a1f29ec4056e30760dbe05f65964b8686b74cb7e0f8fdcdbd059278b32ea175ee9ba68430f685c10e3d61b69a19a2d9effb995ec3764b50ad768afdd164af7977202cfc1ea1db01487d5ba12e25d298e1d56f018439317b218a1d5a59b366a25ee4c33cac717615b57d15c99e8e5b187e0ab833650d4b4bcba8175e0bb8a72d8198ec9290a14b74ee4cc219c67c5d114a1f821b7fc4ac4e22476f1e1226c5da7eb9f209d1d6e912818b9cf96f8e5c4b8fcb5f9101d65919aa6efa239bebce261afddb4a08d6be6524c1ba7a53561d98ebbf061479c1fce5e5f132095c63f1407a496a52717c4d81e286de1eb3fc345205f5b0e66b4c0fcbf9aea3260971a8cc8b781fa11edbc81c460b38fa7fe3491c106f4e636e850cab003efa2ddc2ee82df5602e0b5fcdab1a6ff0f607cd407872a96a91671e541b075071d37127d2ac93af8d7e580223df2a8686061a6c62d2d4f926030d5b0c6662cd7370c8f173f1b76087a18e724bb6c70c7de02d3fa36d322c1ebbfc1c9ab5b5549878e0eb846bf2875b89fdb94d2d30415e34e552e9873275bbdb91290faff0c3314d5fdeddcc0b5709bf68364c0e8c2d5f6e0e9d550383e9be40077474e68b0b59e9f8acd336894dba1748565ff5f19caeb01a80c640440a663d9280d0ee55999cd1bfe09fc074835112ded64cd380c966e47b19a1c3294e0ddb52e4e69f2745a8626e34a1a1208ce2e849b98ca8b283e0a097605667baa55de551bfb826da6375225cc3bb36cebf8ae2db80532dd4ee46f194d8b40cf7626d15a01867f3457d26c9995e63143daea7face1bf67ea49618a9b8b1e20741f3c1611b51bfb173ea2790cb740bd4e682dd10ac4c5286a85e292d200538b15e8734f656bd2d3a825a6b8114a8d3cbfdedfbdaf13905e2aa2ee26a76591fae4a9decc801de894b20bbc1f738b4299b0168ed7333472aa899fd752ec11d401e19b361811a5fec071916c8ffaabd2d04d9fe97bc823337c16f2110e3f0cb2adec4e595e455d40b4e246e678ae1089916d560dd88c4985e019d2a4591fe6d8b369fde30590fe8188644027a8e2d115268200ea631edc81166a5182de0c7bf11155545e0184d49bcb84e35cadaa0e9591ffde9d78f9f4d51730a059a960cead8a95f1ac366b636dec821d047a112636c69343f9a00adce37365c5bb753b89bca90fb4c584dd409eb24b1baa83ebcf24fa9bca40324cc6ce0024b7e2f6fd25d0bba83cba32d24a0d773ef285558671ea926867ab7a04a4c513c1c6f2e82ef0992a28851302521fb1992ac3d706d80498290b194b4f4444d36e5d54a4269f4ed2770a2d3d3edf5e1d3921a146a3202fce4829f30af3566b3ff41df435de0bda7524e71d431cb11f84bee2bd70571c34c216182ce1830fcb70e32d063e745063890b2bdb9493e23b1ad65df1b8889d76ec1575a427869213e27bd41fc45bb18a4ff5806f62ff7b10a1335284cfc1a828abc12431885e3186b9c97261b36d593e92b4245f59732d206a515812757e8286f0964a3f5183581bc6a3adc863785af653bac6be8326d5163e5b17c63a4300533e73cb8effbec50b08b9a247b3108e55e668b77eeb84ce1d015e612a34c8172e85b2e199c271eb735993513f7cca2db6cae4a643abbdda35a67e7197bf7b190edbf17d352289af9762b864007e93358b3664bcd5116f2c94b711928517e788d319c0d138f95df511d85efc469f012fa121250a035a1fa063192174c578b383ae0b3b6822768e4702dc3a6ff5e31d03b64bae819edc090d8031733d0a837ce1d7009511069825c393052c2cd6c62e1c20071a56e201c62c2f8eba8f7b48fb3a45c32d61eeeda023cbd32d566613ada9f20d970138a5d811852515e844e7efa01a31c7343f3b8e0ea56a63fec6b33aa521615675c447b1521168af93aa00323f489fabca1af91d536e39595bfd83f3bda284e0c462da92681a4e75330b1bb458e3a18542f0e3308a50d24b2052a8fa9a02b80289ae5ac4ab69f7c0071fa7cc6ed6ec39ecfd438dbe8f7b766fb4beb3184f238b3170e21c0d34bef7940b0c71e461793ff414592751c8ddad4c10f88bd853402cf2d819573646091e933e9c774dd556638bc14c2c442a528638b1546b8b04218bb9a7886234ee93e2dc8f4619d7bbd435eed6d50785f49f02a396d03efd04fd5ce2bd189a9c055d34597527954d71c36f5f0ab7f41394df29792eb87e4d0d0767c122836bc110b0c73b7d868a297b5bb70626a9676f5be5660d32aa2236f3ebe2aefb1687ca12b8f46e7a137228ddfc9ac683dc1331a1a348c82caa68773f32d1c0831bc55bb21b429ebf53a7672748e24501fab4dde0ab971fbca773abbeecf7b4c8c8fccf8415ac1cdf8b9b6293513e579cf1a5dc234bf59fdd5400be8f2ada777fc65e7873bec2d97d8a6b8a99e57dedfa8eecccec6e87a35f09e7b0265c6c7e8ebb1921721ec99ed1c7127db2541c3cb92f39f6b41f5abbc965e419e729c6b37813c56af65000f1cab53f2147263ae6d469f86640ce70ba4a23d3c0792ab0f0336c25cbd69a441949fd10cd28bac898f82656e526fd741520909be033e63bc583f364803667236e1f9da3418c2e27866064ed9c3c292893e697d9a4e71376d0d802aed9ba1694ff82980718c3446d1ead79f101c53a706e095cba9849b94832be58fae431f851984986a2b9c50432842dbde0439a2a997c86bfe9e6baf5df52a61a2e1722744169605ee5e82b631f27e9c4b6874dadf3d7cacd1d7669e9383845cff6ca093af9b4186c160d020b5318aa0773ad72807f0d108a3a08f8475bfac707f51965097fcca759dffff3412d5bddc8f644f78c83916634ba1b2e8521a4359b9a7a766d6d606637e5d0052beac86f8f1283b364139bd10d7ae6dd6101d6f82b3b004a54a50441b4765f4ae44a57ebdc289e74e3e48d7fe83da5d9ed73bddc4f1e9fc4369741793ab16b6283fab4ad9a1033d766f591b16ce18c1007b2e99691587f49896d55f33cb8772dc006dbe8072ada75a1e2d8122404dd704d28b2fd725889a4411e51a975be61b66921990370b2ab575ca37d8b2ab7084128dee302be87c364196c456b47e3239765b7ca232df736c1fbdc54637e697311d52ded34ed47442e18106c312a0d08b60753e4ffa2db0b04e17a66f6693d016e3e98a0f99351115a0c41d1391b2db45aaf19e1642d656dd8618dac15dd1a16dd200aad86d8e403adb1613570e5cf09b7a65e1b35a6233744afaac61d874475196938eebf3a0c0806ee783f9a94469bb41dcc476931b61d467813cbfef58f59a8a3db3f522983b2ee2be896056f9a4880f56d3ec7613d2afe7232991e6ae59f1469698dac00ca907bd905360fc5328981315518f781f29d8dc8f67eabb059d2d67d4528c1e3922b5e8662f92e9b3c677f4d14bf1c451b9585b2f09143d8d8372f2e1d754e4a1ce472271b06b5dc47d7221701390e955d3a4a8de22795eefa9c500ae98f7428bb652feb02e701d7880d24b4691250c2c51fed5060dcf78e8302453ddfa97cf80abab6c7c6fad603d7ae74a550b368091a1d79c6360b6f2ad94b571566314b0e413bc5ff38bce3418f168e31e162973e995f663133f0e2b3a02817a3b7b9cfe29ad38f25f47f78e6a10dc51f8d51bee6286e5b8e587821473e80a874ef4f3fa1f256ce013b61a55b0bd8e8523bfc03d69981b8b7b3a287cb5feff331272e8f6b32e76eb9380cc832959d58c5f8a9566308b2e09a08c633b4ec4a0107dd43dbb46e127f87dbd1d4719ffae5da4aa84f95ef4f8139c68b2cd069d72803efc72b382851ef03cc5f1549912ebb3e4115029c04d9baf1ab2757396edcadf49efbfa56163669df9e22e17bca99a41b36499be81f45ef5dd196d46a23212fdbc05694160b1dfb240c36e9404ab3498149d39f411fbadb57cfe355eef71703f3ebe533e64ef373e36c078b98dd19f4403db8f441bc1282c1df2b29d59e7adaae129eccd9b656e8be44a7e60be373d5d7a4b97406aff04c83c4d37eb6489384bdcbf26d89ae654df5258fdd7636f38dac2903842e0bf97c8d22743056b9bb7ee06399116c1909683ce25f5cb15c9081f330f500afb12cf186b7e474534ac5b34b10cf55d637730a2fdd315a9474b6c9a7e13e0f1c10dbdb2fddbb522ee9797db37fdae20db64124027dc3157f459726bbf34a2a391ac1b495c309b02c1cdb7fece1208bec6d1595d6c374d122512e832e4ac1167a87d20d8a53f9afac66ae549afe48e933b9539a4a12cc08516819290b32fc8c47ece5e410dd6da7721f7b0a7e5da49aa1d7e8b8b1ca0a56bff9bd4f31f3633311979f34ffb61677a2a241b5a2c9517585ea0edf6b47be15315108717f1986e9a56989977b22dbd6addea996231bb688218dcd693a76b06cd70872ab38d277a1d9a86faa3b8c4066d7aaf0b72785b00dd64fcc522ecfe63f427a788812510d33fda5b606d03e1f9642d03e369fbe5655ad2c7fa7700f0a45b87e00e56a7bde5697742aa046f86136d4c926fe4776b9b18fa33229a8e8faeea690424ccee4e3021fa11358ccc1385fbb2129136009a8b6b00cff30b7c61aaecf80439e9dbae30fb8a08147da38541b49c6be8d221372719ceeb63319ed855bfc036d666264abb7e5ba20366d83b957dc317ee1bf1ce36e3a7c935fc08dd396a97be6e78fc079ba8d5c5a7a8bcce985216130540a252143be4be9ea3f623deded89c79cd3686e11c84a34f18e3875783d2feb1dd13141f0fc8fab3a74964e9fcfbab5db88b5f8d4b2d364e5d6ac1cd0953a0144bab9b9af1e6ac3225a6d169f3d16374bba5ba39ecd9804a0399ad59d30c5ba882cebe14db5f72f125227035c59456f0f1cadcff00480f319c9c6ae954fcbf300dd2d3215a97329240b891c29ce777e21c7514754009e159133e22827f07cfc5a429589073d94a6de85cb0a382bcb971b19c09df76095083bf1e906b1dca71840b76114381900de323c2e88b68debadfeb7f54a45d12bb728167ad56bb4fdb62b4d5c754c6444a1b2408308522262124c34f90d62a0111cf694ea98ef68d201a389d98e44120146a8f32a2a60fda92147a2a3c88cb37f97491d0e48953194d2865b33f87a61c68a428d47e2b9b61e28faadb65bfb3309dc9ecffb9f820300e8f431156ed14c514af3fe9f1d245eb72a075f614d6ce47c4a94c07a663edc39a2df48fff1c5ec06758b1ee777416a2f3233afc31ced13867a8a4733ce6b3285b7fdc1b81e7e97ea0668272db6e9000bcb52d20456274f017b701597b68b85bb350a66f780109d6c83d716ce5b576ba8abc45a078f6cde95411006ef7b0308e4c0d29ac3dd0d3aee5833f714d3cc0d35d0e827bc0bd60702527a7cd4b0a4149b7c1c44ab324667e03adaa87898da05ccc32842aaf67d957eaf64bd755f1fa41832214535e37fc2c2b3469bab332304e093895e3ee7dbda3f05e49286b637ed3f0e37718f1ccf4e6d2c07c54cbf8c5d8d511e2f113beac2673c3a2c7643b59f5428c86c996238293b4faf00c8c22bfbdcd40e12b33e950da54abca5b71fd29e813c0ec7fe374b7aa6a8fd0bbbe9d257268e233b35ff2e68683674c8e42e9e3c5261b12bd3ed12d326a2e3c327261a07c83413b05019d06abf6c4ca151f67ceb008d5605c5b4e3a51a502cd21435101d9edca440bf177b4f8a60e8990623466b5c0953824f4c3598af7196c35a407f64a71dd9c12f2b3221804a7855f80fc4b6dbacd508cbb304db9c284a424034f496d7d087eaec12243b200f85a8f947cc2c2f2132177a618ab7c05c35a6afd7dec6c0647c8c3aa23af1030798f0044b7b0b1930af3d4468b82a1bb732178fdf3d1bc9b2df9d355275cda6f3e80553cfed70763549ff06453ebf6215e941afacd9c4f08823332365cd065af4033ae63c2a389bc00052b94886c2da48000a7ae923eb0e31e772e7f515ccaf98b785838928734e103ab1ead67dcc180f6e1f364782c67db33b5c88601b9ddcb17114c3c590c18b84aac966dda0559004c31ac1653910e058a056c9e58012b49d9a717d5cb5cc4558141f3eac16943c4d23c862b210a0c04c451bc3c90f3afd8a8905ce77bc335bc868047ac6637b024e3b86b8d8d33c17375cde61d76af4718f7a0cc7c41e82760b380fa7ff5e1967d0a41df364fff1828d0a79a4dfad7921cea0983d17e09e9900619266f34dbfbcb4b2c30ef16fc13b0680e7707fc491f0ccda0a70622a951aa7a3dd04290d705a5219ba7218a8b340f6590b40d77524b2f355aa0a93c860eebf13e48d66d946115a2703e08004c5997e1fc9f78b3a2153db8d6b18547244dce58abd0c310da5461d8bfa602f9eaae2a04c8113ed1ee2bb758309e0ddf4d567b364a855e73214334b95243f91fa8de83ee04792d4aba5e523d52cc6a2147957164c7a872faab9200bf4c3b3f65ab6a78e2fbaa7edf49c0b7468533369fd63319ac35c4935be314d0bb109cd06f358340652b0604d6aaf3aff514296d7a85332ffb139e733d375e2a34668a6291f10189dc622e790bf004e4fcc1b316b0e559908d32c712ca84543bde895105e6e805f16c4a5414df6fb2e1d2d646933cac4ed8955d06388b6efd9745556dac66835cb249b269e1af24cb4deea03a516f97d1b126670b8256ff7b3471f752eb2da612405f7bd5f6905b8fa8976d4c4363ee457e7d95997f8f94f4cd89be053028fcdd2469f485b6b2bdf016cda7ec470c2de9898046c5a56cb1bb1f4116d8ce4d2a0a7adb41dea6326710d6687e0b4b89443ffaeffac420e11006c09d7f72c5b53967bf00f7eeb4979384fa8118f8591993a6f1a49fc1d265479102ef8c3acbaf18bb2982eebe4479cc83e1e7cf36046a817d108f2218b7217c6a17151e88a4b98f3ac835079859526f26de8f817a646c0528ae248caf829dba76fe202b87f42496ace2b60ec97979283b5933317cd8b1c150305205137ac90d442e4b1f208058e5e2667140f334d5c3105220bf10d4c2deb070f5e75a8603c37c72603c8d1f77aa35c3bd90c1c0e890711fd5b0373fce8dabc0c00216229563a6e48b13323d5a7d8806aec246e3e4c7ab46043f81be270ea73b2a0ab45de4461746cb12adf59b227ee9d315602b874930a1161c905b6067c863558a52159fb7a4729667c20cce4bc29409caef5359e67d31755a98d151a80a0485052db52e94e49869fa06d9b5022f6135d1345a6e2f935d604098f21eb452bf510d4ab2b35bca281e992bc92dd472707f211cc77113431fd22528bbb7ef4b238ef588acab66201773219a500fc8821ab6af9bdebc5936a3fb7f1f56abff42f4168b7a7fd60b139449d4682c0b01b33703f57a5c24a888ebf04157871f9602a0f689492b7d30acaed0e8741d6f8ea2f7c70b972255beff3e131a0f9b29b9177e8adec526e1d6273ea785670c34d36ca3ad009b8318593d0d60d2c37d4aa60dd62ebeef2b9f31011c4036f7a008a13e78eaeca3a790d0e68c80661d9c017a0b13eb739f007d60f0571d642c9ef4b472fa18d460ca0a60c1da2210b2e01762b4eb63f8e88bd1cc3441e388ea29d94a3faccfaeaf48cf9640331ce414f0809153ba18887e4e75344159bee975b2db89f0374c6dcf214f3b15386e876724b22906946542b21030890951b68665637fcc04a73ab432dba5803117625351a3cb0fc0a0f18df5d9e4d8f740a3ce4aba86542956b7d1e35c2d9e29d5fb6e4e02797db00ce7bae4e34377a70597a5b9440bc01479301d1c80bcb63328038caaf80fd15a27b0288030b7d009bd4e1e55f38561c831739c856bd5d0c6b75c8d631f00cc3d91df175fe11b57c01b2bc460058dc4b4196371a841dc1eb268cef19ad17b2de8f3c8abd4d5488806aaf49532969474f0c1eae0c52e819e48127d33500bb00e38241d193faf2938b164d9e137089784a8f9aec09499c0c60978289ac4f9c00b238660a214a1d3264b83ec94a7903a2ff2f17f6f6a9b3a0b6f2291424736ecd7ac1d7088977e1734a7f65bd9d6537d2462c4c9f7c1ba6011ca4f4124213031d6cd40fa7eb5e1d2937d1d24d30c7e48cee360dd5f0ece89d4ad6b7a28774259eea258dc804cbec821063266b6dcde9009b2498d4369fa0d54b44b7c6622c472317f1069f8c9f56bd13f5eafa2b9bb2dd4a3dc29301dafec9580121af444f90f512162952c40df0f086f8c18738e82dba408136fd89dbd53b320c3a56a2c6a2fd4b1ca0289e626a5fda093a193140bb9ea2e4e264eb79c831ff30c6d73011b810365a295f62ac0750553815f3e7f810498c6dece4d31b142cb0ecd5de80085326840092809fda9adee822e4df63afdf35898ae1ac20f2d019699b332b94cfd375c3c165e8c25e9c4b60392c969615017c778d4baee8f5b39857e4b327e2b2e5c949f115dcd95bdaabce6195d9433b7f98b67e4c5bbe4fcb01bf085c02b110764fee9b058547659b39354a25bad8bec4fc05ae78a8651fe569eb0d30d7ed42cf80075ca825bce7c7be68b0880149d23532d5d282d95b0c8c9623fa8c77fc12166b371e736c9b0ea842f0a8a4db5b6f0c6e986d1cc0843600c95712deda44d8561cfec0067620364a1f4ea4b5a567fab7ca4441e148ccee4738b2e897877ce5b7cbbdcc8d56d94f87f05818c2f1eb16f284b3c52263830ca4b42b198a43fb6d3905801905b115d4194af8e04ddeeafaa3c1307f3aea3e9d02cab3cbfcaf36724f3bd0e876aba6f155322be53fc5e11343d9e2aad9cb9133cd14d18ab6854b3721d1f0166a607e30580d95f0a617319b60e0b993131fc91344af7595c2a11ae2d1d068ff58f35b6617688222444da30ead11cb78a60b7b831f85e135f92f908faa95470d8d3fc8579dd2be73c13e63b5cedaaf600c8872847bd9a8a23029d892d9737b62e131ff58c066261ebca1d9edf5560018c2caaef9b21252de06577dd674e52a925116f3b8ccb921d574d6c34e1105db6b6651f32cab6d73d76a5211135ba31f5cc40ca2077668f81711573c31a5b208d28c2f7a5213d8428dc7c63f103a69f21e3134dabb3c56fb4070ba4e92c1924f53ed7e89421608f2e7f1a3c7e8fb24a845d1a42ff96584191c70be8989fd5ac0952bfe1b18164d628b6f9b94691da96f598aaef69e7b14059eca5b0fac25f50d2f2cd486e3fe04839934ae0d7b71f1abedf0ac4c3299abe1d3f9036ba2c1e34f19256a506575f03e79e67d97599b0ad89e436d43fd31457de12de8fcea3eb8f57e3eedda301b32e548220c2d60c216b48cf9b6f41ef4a72b89e5e0d2134a1d7b2faa7ba5d78e93c46a373a414542b9ee50d8b218057deece03aecb6c47aa3e31143ad077ae52582ced860eac28e8aef072d85209942ab662456cf6a812290fe6d1fa6fddf6e15971de488a3225d7e0f69450945205a2d48a022032383b43c979c04395617ad01bdc92bf6d813dff50b0c6c7c1aad90ed05461372ab752b9ef40545a5d29d62aa5955a09151b8f09c76ae5f60fb56ed4fcf108748482d716c7548a41c5f6256b6d992631ea34f41bd4133c76dd023ab2eb56d8d59c62940be8389114d19f2c46b7a2832f0ad0a5e961b1559bf419dbcb693a89140211e7b415e77b73393151e91d9dfa79bf647fc8d5a82724b6e0a214d5075596ed7180c733620886eb856559351adbc98af524110938a99d95852e7eb762aad99522cf643ee314e5a0f8071a4410ba11e5188c5a3e713bd10e7034d81e56c347bdc8ae7c5990d17f23b9b003a68e039a8052fcc81478b8027a59914addfa375e3f890081a3235efc5b389868af88fda6e08d82b4783a43670abc44e6e7fba34143c2acc65b82a06967b91d60a102895b9216b77b5a76073e292a15d04888940f6c42a16025ad20c0a9a013bd59d43d3716bf40dedab57b348f823955c913a7bfacced3a0a4a67ae6fb01f52325751a0386042986220a36d8084a28c91d39d93320df9323a9c6d0e03058a6f3874518c0dbde3dca0296eec8a8420e5d36ddf819eb87ddfbebc98f6b6b46eac6c3483a6eb5fcba8785caef06004284d980b91af2a1e5c6f0b9e71767649289856e48f2ca21d1d1299eee0301e45c7da94b8f135c47262ab4f2ae314e94f9a215f0a9bf03a53355982f31c18e8ade2c308754ee4fc1a31db6d869edad656ff94ee6615a5f4a876723552e677664b72e5e43307699c71bb1a2bc30d1ae4dc9425ec99f74d37352d4211d936d202d8fe23071d0d2fc326bf93df5042c8a19b4608278bc6fbef6a8d9a9eba6a2c7983bb6a63cd4a1e9fc5743ba8b57c04e0a23837d26c98449443cebf84a46f303ad4eba9163488c9431d408bebb48530d4ce23973e63c531853b82186bb74f33684fa1bd36b7fc24dcc520ae7487b7125282c1eeccf64c99b447503b7b4307a28557c3f145eeab47fdd875e60c15ca15cf94c201c83d91d46ddb7df42b05cb32d0fe5125c14638637febbd1ae80250888140c908040c563ccf062ff37cd01540e011180a025084864bc199fe87bafb88024e1000104540e8110c59acf8b7c17f5170809082c8180a4d0209138b3fcd1c34d7b0d120020e51088040a2e1663c61bfcdd68aec00204480a07914060c563261349f382e260b2060a4648bb2bc5f054f7990210c081a51060125b4f067eb9e710d2711c5b48cb005eb064b483e65f3f06108a484966cc22e7769f6d33a8de8fb0dfa95d342931ade2cf52387af00f9d8b436349d39b98b93ea9d6f4efd722b55de9960c2bd57f3f8c1dc5fdd93170341c241578d8324871d0fed81725735a99da57341016d4c6082eb1852c49c41315848a6d73151ea40825c94feb4cad5d731a6a67696e9cea708607c4ae5edab06c56479ede81bceb5f0db7bf59cd5ecebe28af539503d66e53bee29181b52e0eac75dedbe89f04d5215fad310bd60aa5ebe579aab3012aadf019acd0804c336816561a37e84b0341f792c44c4cdf506bd5960b1cba64cd3059f7148f441b9cf0fb996a250292b6041302a52b9863d7c08a63521d9571ca1ffbdc34f73c83ca8080121c8430d2b6a6b919196056b16172fdbb32b05ce7bd2c59d47e8f4c5647bd77c0c204b31d8286d0b6de6b8c58831f6b8d5bcf9c51fff0351d888a66f1353b8f85c9f1351a951412c6b11134940896afc1ccc0409baff11030f069c1e6a3e403107d4d07a4a271fa9ac56716d464abaf71c835c0ed289ce3fa5a7ad594ae9a252cfb5ae17a0df83a51b4af496f5f7b99054a8d115c5e25571c83b86ffd6d38dca4c8aaaf5f33e58033ee4fe102b48b61ae879952caaef80360fe27b336343aa65936ab356f968565dd376467a1f69b3258afe7bd8cacd57f47260bebde9685c5ba6f64ce42edbbb2b15ee37d5959d57e836c16ebde2c0bcb5adfc8cc4afd7765b0bece7b21cbcb3931e69f4579e8c228e02e25381ef7e5c7c7afff3e7e7cf8f5efe3839f4fff3efcf8f8eadbc78f3fbfbefdf9f1f3e9b39f0f3f1ffdfbf8e2e3d3bf3f3f3efefaf7f3e1c3af6f3f1ffc7cfaeee3c3cf5fff3efef8f9f5edc38f8f5f9ffd7cf8f2e9dbcf1f3f9ffefbf9513ef856489a108678c291466e5204f41f69bfa9fc52fed1ff43fd97f69fe227ed0ffd0ff49f54bf29fee9fe51ff43ff4bf961d521d533c3b6fb07fd57ca6f9aff947f94ffd07f52fca7c03f0bc51faadf4291f99bf3ddc488bc373192ef3906e473c4c8fc38df21868cfc8ef8dfcf98833f2315fe2cbe49eb1ffe08b4f537be609f71c6ab5124d2cf1c6404fba0742cb8b09116f29c6e807459df8894ad67bb02ec7ac67082fe71377f2124d92b774a4092a58bd303fb6c625f7bebe5ebd37ee2831c0647a401543c685ba73f776d5ff7f8a69fdb21d105a30639df96a655b0c350ab7a50c3137f26b011fa7649dc81d85d03bb69b82b1a76a951f735d25563bb69bc0bd4209be22b70c868885034c41eac82b7ef2fbd4f86ee5f7fe67bd0cf2e968852ea5b8f8822bcf1b437d03f00de2589b437d17884ced224da9e09fd411709b7b1bc961e74ab515c6ad89fe81e389318dbe5652981db1b05a5d4de88e6b80f89db5cbe940ebb058d629f2de1c2497d601ae40a576cd1b8f6af24fc3b44fb3568e5e270039424302c22ddc38709c2d95958f53330908b69ca82617fbba2824fab5851115b90f6f1cf421502809ca48bd67a1e6f31438a5e62ecc8354cf5e229ba7ab25e957d19f51c4a8eddc1b77cb439202aff49364feca369a1cd7a47bbe1f83ef1db4a85420f7bb124b01525bbf9a3790530bdee805052a292d75419f34c039c99cdb066b4e0cede8031d314f64c1bb831bfaced59c8a8434d227816dc66a8f635c7cc5866c9eda1f60704339c9b84489c3ed48ebd83c43213a15cb2b13cd38d98ddaeb0e5b96c5e5223110c428482840160290458000794e0004420881802161831cf137d5ef447d85b8acb05da23483c82b9a55d5da0de02e4104021005a80b0687c1098404d2594a7b93c31aaef0a82abcb9393fb2a9c49681425262670daa84742eea9abbb1c6c001ef8bd50450adf86b2b86f9e4bdb47fc2e31aee7432117f09311c66382097e64f64d4d013f3ebf47eb8eb4997dec28f66eb45561dda2f2c93f49dc4e2b7f670e444b21b2a622a1621f4ce6b448032c75d41f247b898d975b4e8bb253cae14a81b2e028ae903eadc1bad933d784866e47855641f03ccc76238cd90db0b3b660cfd08439d31ac66c5398f92db0673660cfd28439af1dce7c43b8f92de06736e0a6f3db9a57323a0f19da5ffafef840ff4bfb8fe287e67fda1f9abff4ff9afec2ff249ab42955545c0415a3e421a7f94bfb47ff0f5dfe0313bb6fcf865023afa88550308a1731c51fca5fca7f14bf287fd3fea1fda4ff47f343f13fe50fc55fea5f143fb4fbbfa1e12f43d453b8e0a0b86cdee92b921c7f1fda4b534bf56b042631b78310253833323339ee1e568e29fc6b2527a4bcb25cf4b33756d79e054acac8415e088dcacc15991d660e64ceb98c8028829083dc447bfdeb8e1a75c859ae3b11b76e6996ab978b9f322f48911f51c2a2c2e727a25b40854eb861f61902c3b69317d7500a0bf7f42febf1fb085ba9fe99df00a3ec11929e61c1e45f16a1525c814fd8bb560021ed0b345600fb2f1661bbfd18bf44a92dd88f07eabb12c772c403233b734687faa379c30e56bdfcf8e939c2573342932da5d6c13551aa177ea9270fac6c3c44ee5613b9d926736aa80d72e846bfa9579d3358ec934e1da65b8fa5ada3391395769a33941f810f164f6260483879881c0b4534ecb4e467dfea0e08dce2cc469e16e485798d87c56e8689ca1b838c2860685d8310b1cdef001cfcd13f9891d6190074f401430b80b22adf81ca19689b6123a471c5719874052d450190656866cd90840028130177d23b58c3b3afd7a651e4ad007a6a96be5a5f11e2c59efa8d089a93627d1808cba433b630d1aa32c0341392157a1e8f73137376a75b0618f8f381ee9a17e4415a70fb81845c8e308328515edff66254dc70a0beefd8b972998a5012071321b4c7148f08da86b626065f4140ac1dbd417b40f843fa7f3b10faa25aad8720a498facd61b17a3210663aacbe2473c58907f32d4f317158d2b0f69393e0aaa17fb11cc86115b2e0a9c9d5d9799bb2b25329957f0779f5c096538d03fc18d5fb42d8d5aae8284ad2663c11b5740475cc393e83c71f3051d874b49fe99b3ffc037832bb7746225bbfcad5259bb05f6c40f5c381d9aa78374cfe49865d323a67145a9aa829e2b7b453421cc21bbbfa85e106f0524f9a88c1c19d231178ff1f81718d8f747d5f9237f5c9659050ed2199a842dfb41aba4da3a3d784327a4c6a079d760bb8178bf0afb7180b9e0f97b3ec4a2ac2780d229aebb5a2710d0ee36714fb028c99004e4f0372236a793800a644f67ca3aea84ef4d9c869e247082580cb6fb334ada0b036825c7ecbf335a9f0bc7a788d38a151c767e7f420645c010e7a9d5a81011c1742d6aecf3a4c4b03805782fdbdb2c389234442479687d9982e215ec84d8418c7dea73c785c3902e563642672e8b5b0c493503a02aa708743ad743bd06e9bd23f1aaa855dcf1b8ffac077ad0dff35d0e88c646f633fc748f06e4c7141885c870862d090815cf4e03d825f965bb3e44825b01b5a2feb7abdd8115a7ae9e2fa105b8aa5347efa03470eceb722fa0e0110ca162e58fcc925f0a291c4be4da16735ddb71cad9ad003a895e0fbc392d1c64f3faa18e927a1e6bb11254eb0e587f76a0cbb1f487c6e7d74b226e68a022c6d0f9d0a130e7bac7765fe9e975a26b72e7100ae8f0a4e76c12ec35d659f1c84b75b902a09b7a5b38f55e801ee05285303869d0bb794d95d7c297ad15ee01db45a7f2e83babddac3b6aab3cd4d857543ab64a1215f7a62735c7b5a1c1bf840ef671a99f791cf764c3402d9760cc13eae4a972bc6ea11d74638f53073a077ceb774a57deebee5c963760a17f1786795bfbd8adfbeea6a5777b4af7ddb55fe762abeb48f01bde62d8a83298ee3bc72b35d2dc85d0b615bc70a4f50d5e37c2715532942e329d737300220e60c40b27d3d632ad94c2e57322b1f589c1502275cac6465a5ff909f0c165da08ab5c057b10f8bc92cc109296b02ab111bd06091942630a1b23ef0056205382c2eb30427a4ac09ac464c50a18be40fb5c968bca2df00815b4b2afc1ff405fbc7c1729fae52e55655bb870299619ab8dc4ea1671d0ecfc3b47722730fa3ab8d9f7d4208db7ace9d7a21eac4e6690c0c3ec6a12215cde2fa2078fdad82389c637862187f70f95c2eca060745261113bc6158e19612262ff4f2587d1cec3093e7a14473ce114108a37c47e36d6d342abf0465e8dbd60ce2ec208cce999ea30f43fb808e74427f823c8b3a4738443da01f401f221d239cd19e90cfa04f1187518ea807e807c88788733467c433f413e441d431ca21ea01f901f214ed1ce11cf5847c007d883a8c72447a403e413f459c473923d913fa25ea85ca729d45ed02fd1275416db166a176417d81ba54b75cb15cbba45e405fa82dac59541d8bc5afb20b64194d6000934627180883b1890fc4c04882036fa6caa477694c943213ee300a12e5bf200857785110ddc34541ba4a8b82607099d3d677a51507d9ba541c64aba53888d687e2205bf1c4416c4d138320137a2d7190e797c4029ccf2316e07c8b5800673dc4029efb2016e01c805880f3e1c32a80526733c021d0e4341e70ec3c18d6c534f15161e8b485b5e84a79d13d2ca9d8eeaea69a425443f6b2d6a3c821fe3b9c62bfe02e06bf26e300a9626ae96c5fbbbee7e059b332c9ca9c05b38390b57a6686c5c13367659d253bd38ccc59b267ccca384bb6c8089f7190c550ba838d80815297018c3037f21967cc148800424c6425408408137e04880fa19b3cf94e1e4334fe06f4f1059e45c60716491068cba603e4b8140152ebbaffbf004ee31f00a578cca099959f120552473a0a895b2acf16d9110b3522db5a74b2cbda69817288e27b5f67456474a8628862cb650a8d2008d4f6de296218f0141516513eaaec6a550d8ba2d24b776e6c3900fdbf5393b0a3c09be3b8eca5bb1d3166903a481d86b50d86b526450954d1485016db0a4322a225230496c8523341aa76632985168a3418d69a20019024008e2d43a42935084802947ad1d2d192a3a9a224f2088e24a22186476d864c55b2201521cd045ae233244a1b122de54062b8d479e83044c22163343a420445e481171b4a0184a0a506663863c78c1de48f1bd4118e5b9a1622058ea68c909033482447290c492e29a8a2a422354352a92847ed49498a146b4bb5a7a425440a184d29ca51945464658969890909071200465348435a8a72906bb410c9191e60a506acb90306a8512dcd28bad544f2078955f35aba51341a3d60a4c3a88bc8860cb1488924aa2d9124399246e411899424408d34826244638657d2cda8c848248d6a426a5035f12800524716a402885a18ca5093e55654d371a4444b8d8f161eb9fa6987a850228f9d3a41c8497d5f62cab2ae16485244e73f5a40f9b0cd3832a2028193ae343a778c28204c9459085664f8245104103bd800c319a8120110d21e866f415b00da83e78e0f3460b120822a104871d2c564490104dc00c04d0e586078c1820a720308a0730132f8347105384c3bf4851755a8dc00e09604103ff0b0830d35c41086830c72114c79c049d75611747e20e28d99969e258a00c2871d745821852f176cd90250127876d0c18d0c5c86d7dccabac5002445147c82f021071cd8a411b3c135731154a1f2c056d6112aa75b8c22e80461a68c182ed78c8081ad2559475e8a288aa023c40f39e0c02686346338e012c6c056922354456a9f2645144d0811c40f3ee480430c69c688e160032e4fe4c2aa2c0055160aa34903336430214019982f521e883a61832f42321790d2c843a321a23046308e5aa8b130a619cf88404629324a2c957e900a901580024601441d4639c800441cb51b2200483568d0206db5194b326c31722c05a02440d20dc9e8a8c8682c2a222222c52fe29274c01043232423a49a8c23224648e4004b6059ba781c3515251d4dd5966688b5a5a25c2d48c6206fb53c5bc80c8b648c4648b5a718034cbd304c8ab264d69e64641985e8208252138b90c0192669a2e4b665ac25d59a387d319c424b0275b2884454b702acb28cb51ce40f54dc5145a4009e615151015e5c6cccb8ba80649205836100480f2c312d3149b0c4067ac493bc1822e9484c74636c4648640c22b15a0660b21cd564140d20ce0892858a1390124082cbd1a010648c4a4456372323b5062e95355a6a1035252d4942a0a84a2d0123235a6e3081891616c200608be21283d744833843a5b457664b0c2033c4280290478c02209225c9c84851d2910cb2c816137280a4255e0c938cb6627c1d69e9c85a9284a4b5f46522b96178a3f64424a988aa468ca224a52c1e11ac304c3ad22260f7654844da88c422078a92888e14255075a59422f938d22a4a320a208612a41eb52ea41b4c0220900380048e1468e0090259928e4aa320318214d9f2325aaa19e520a22289202dd57c542b2324a3a41a145103b5292b914807b983088028a4231e6924eb088ea32400908a64c1ea521272d454eb51eb51c4c23001193525440a101180d4a326c00c2972002dc3124a247be48f1a4934018f083ad04167185ea883b606061652d0004b05645cac7779ba08aa4020250a942faf260c68514d056942e000036aed071fd2fe6041c5025507f0c81180d1191173ceace040d6025403d858522a8ae3060717d09c49010513cecc4069f20155962103f69556a88b1d047fb4d821a76f63c2e05ed59124233462ca8a202991270d1a2a23446e3029251d1909a0c3861aaa5cd34917035b4bb2a8844839d1b8c988512381830c30a0d167c81b185e6001cb03518a10c1c154b353878b28554988201915c5d00507194e00a1832f1394400209619c74551df1b124864182310eaa01aa5a8c7e6a548c4e10f511971893189140c2b37467b4331631ba1963206118c56a56c41e620147031009102380f1c6684364bad520a231de445b4dc6a8449434221d1d8d464644634d24455181ff4ffa1c36a624fedcd99ef146a1aea97938a73164880d8877cb03ffe2588f7ff1ca92929844d6649a56e8d474819ae7382e9d9a7629cf99578c777fbc92c8bf283e183c48f005b6c5644b498ec9d6574e0a8eab26a9aa4e4df99e652fdd054f74ec9fa719034bf3d3ffe7f2361a1f55ab6acf16589a7c9759fbec36a184bedbedee1c8a774d20fdec117d7d91dbf3874e17398b3dc33d407c01c54d53a04be8cf8d3950381a2f0d4c0692ab232018c006911e2efcd05b83800c57329e0ff2cc2882818c8a35e1f5030d1b5018e451a284adc3111850312b2910c7ae2a0a40805c21089600dc10b1668938b53d47471421080b037a1450336c4c1922f98880547e5025e2704256b100a12e9638134216792a0b73072b05885afc00e2a85ca0e64f1603ba04d23cfc078778f04a57c07951eac73f015c864fc6b0faefaaff4675fe5fce78848c104f24c8897f3310863fe3caeac52e67ff3e6cffa49fff37ff3fe9cb1fdff31650ef25c20df6ff4fff22699bb21df19eae3dd595e36a9b91c736a38e6d060bb61925fceb6a4f57a7da54eb3531cfb8725c3bae4784db9a39d5bbbaed8f576ded3a578e6b17ee6ed65dba9a35eea893195fb61958b6190bd86648e974d597310f9fbce6fb0b56a79a04496daa66be3509929ab1efeec2cab2a452abd56a2469f28a8634115dfd7f7f5b8c1fdf65deb7778b42edce93a86ab7d5bc623c9c2d1a55abeabebfaea38454249577ecc36650efad773abfa8c6b6c4c5877750c0348f6f5b0afe7f593a3521353d12d4ffdf74f7cb4fdbfb7fa70388b050ea511dd86bfa7f1fff8fc001a21546a46a55dd3be52550a9b8356264ca481123448c0c3122c4481023408c4819893262646a6aaac81491a9215342a6824c0199929a8a9a325264aa489122448a0c2922a4489022408a4815892a6284c814912244881019424408912044801091221245c4c890a921458610193264889021418600192235246a88112153428a082122648810214282080122444a4894102341a68214094224c89020428204090224885490a82046804c012902840890214084000902040810292051408c484d491591222235444a8854102920525252515246a2a6a28a4411891a1225242a48149028a9a8a8a85d147e029866a80eec91451191f97ff46d483a609aefd63c1b928eaf664e75affea8ba302241ea13102aba7a7dd9ee7a7fbd665c2f3e6be729b052f58c7364d8b43bb73bcf01f5ee75adc497f189ed06e3bc8dfbf9529db3baeefa755fbe4d4e9b769e356fe75d942cab631f56320544ea727be5c3575a83f1368eb72d6fe3fedf0035ff5fda8ccc233147c37fa7a67d710ff77ccdadcebb56764ed0fc7f95b71d310179bc79815bf74e0bac4ab69c2081fa0f7b9b91f9bc6d879446caa81f26d63f3acf9ab7a3faf6e5e277ccde26263eed58deda7a49be4cccdbb746d1f4abeb2e7e4dddd5d37a7b99b7a3e9de1aebff0b20e0ffefd6fdabe7db39e659f3f296b0a3c0aceca46bfda45f26fcffa5bcade8fe0e9f7deb9dfdff01fe5f80ffd7f1ff5bffb55b8d2422cb11c0ffe3f8ff1bff36fe6bfcdf8494523ff8edc2f3b4c02fadc1f6edf5d22b1115b9fc3f046fab61714dcdbb665439a48cfa313584efa07a52515143a4ec6e0704885944aa47e487c625bfdd6e5e29dc9d63dfdd50dab72d6f04a0e6f5ffb7b7d578f80feab3b7ef98aec28e7916b53cbe4bde1dcb05ed06f22fe6ffcf6f23eb7c1672db8cbfe969c7aa6eef2c5dcdb6665d754e4da8ddc19c5251f533e5f789ae9af73c2defff65fc7f8cadf7ce9aea752840bd97bcd9e18f086299ffd76f1be33cdfa56d54a1ecdfbc27b6bdca6f17ee6aede92adc1a78814a49ff8ff4ffb5a3a39f8db78d4ddff189f2aaeb5647e36d62a1ffd3e2b9f136d1cdff33bd4d44f349f6e519ff7f8c7f2235ff7fe56d620f5303a17877cc261e05fa7f00def67bfe3fdfb322a97757cd33d53f5e9d2ac74d95ec9a19d73ba68177e7501be4ff5fffc7ddff03dff655fe9fefb2037b3c7d9e164ab8eddee1138ab739d40e9f9da71b6a874fa834fb7e90a5199f3f725067b19cfe10422447648aec475429a4482905c533b63fdea9758742d3ced35d4265bbdb97435da0fe41fdbfd1ff8b5bef7d6bb6d5bc79a7fdee9a35eeb6e70bbc270ac4b563bb7bf565dcbb056eddabf6ff89c8ffaffdffd2ff8f3a5000a3f468c321ee491d67ee28294d71c286845691ace0c0bd58ff4a696907b924eed03256712487646d690909a9d67670a9d525a4da2f15f1d0b1c4a8168919f138231c6b118f3342b22e703524ab58c7b156c7185eb50a94aa58c3321c2aede8b2c01559937670f1225e91b5cb0257b54a2eedf82b718716b226552ff54aa91eede0a285ac4a3c86644de2c1c54bbd129f1ceed012c301b28ea317f12aa9222155a5a4ea45bc52aab5a5251e15287139aa48758947051524d5f168c75f29edb0ede8e2c29505704555bc9a32854dec8c70ac6784b55af31aab18438703b53a5630b25e55a23094745409e3c3c343439b27a29892840dc9861d6c6355823385091d3a7862fd293a28cdd06113d5dd6fe0c86ac568cca8a812ed30e2d1c5ad71381c1a6589315054491e56b028cdf8184695c888875893a24a76b1a22ae26a4646b5c8884747c2d5967880d5c5c82a126921e1c418642ddac1d545dc07621579782056221e6ec4fa31aa90633770230f375f8b44720a0b5cf8ea82581fe9afc46a3be3a55e9df9fa444a3625b17e4de9ebd7948ec82214b8004656b15230d61a0f0ac44a16a06441172f2e5c5900378e5378b05115d99c888cea143a453b9e7422aa5153eed8a6fc609b42c756aba4155a52ed52afbad42975745380b071f152af906a977a85c403259d88a61c6143aa561e9038249d88a614619b7354938698632baa48738e764c31c23665089b519d3284ada81aed984244d18e2944882399a68e6d4a9c20a6c4e132c58720e24cb1639be283cd8a15ee49a72942d8b80411c72646d647c34df1c146d629726ce3c7b8f26838910425b22a91319810f16840e9c71d57c871dc711e71d192451ceb5813451a945e144531d188c715128754abd56a45d508a96654bf46d6a3a35a13492b35b1d648b23652208a15a98a5b447b6cec643daa443cac50803b228f28303ae2d1492d1167c5a846010e898758511d2b11513dc22256c4e30a798502dc58c72a8a89f5abd548b446694a0e4f8e95b472544522a4fa5bb5dd6b63632daab51d5770e0c48aeae392785ca1e00a0e5c118f4e6a89b8239c68c4432caad52b244eecebe3c60a47694a1f5b0d361d55be7ed511c684c34634458af17b1021519ab10317a21d5cba08b9222b0564455e8aeac780f25764dd8265381c8f7680d58644f56348f12aaa443b8a8a78545023a11455920705589466103d80e5ca884705b54af4405125ab51add5ba545054c5ab9a91512d32e2d165e9aa6654777039da623456a5193a1c203ae1bf4b056415af462858882ab983022c57e4d5c7f85aba1aafc418595e6435da51ab1f430a512de2d145bc1a2b0a6215799c40c4a38b7855e3f146ac1f63e7c08cb42b92c7961969575e845c8d3cde7cb5a068aca5a034e58d92d2943d36243d27fc394189137e384106143cd073c2057a4cf0a28f106cf4984082091ca49dfdd173d6070e01b8d77396c2999e120095c0441025d07056c2972ef490c0c4107a48b861053d2474a0010959086d5185134ad8918366a68d19352798310b63a68b21415948c1041e22e2b81981cd0868481861842f5e3c5186883237c490c604b33261ca6010a809324190a1210d19331f90d9605014221421420e7a44702185326344c840842c84b6f063c6c72c09382f9889607601a110b290220426e284d042082084a005842c40500284227e78c3068416500801842f206cf9e2832ba058e2033b1f04c1e683331bb8d7f3c1173d1e7c31c5f086274b105a96de6cb1b9c045850b8ecc74f1800b06015ce125c9890cf26850c4971fc0bcd920060e9654087364a64c8c980e2e187364a8832e3c40bae2832328403022841b0f663488b094868c1209654018610c0766c66c2121861725fc392baac284243e27e441c14e0a42a8d0c30a6eced080e685346758386b410435635cf8f282182e3018195a2328862c6490620626d82041431135006143d90e6dca6cb8a10c061ccacee45056829bb210de84d1c1cb0e6559d008f1b0059c2a7a70228e123ed8f92108208e7890834310463308d1c21028cc2943440774be1411664b9d30ec1c7161041647184971470f1e3b480091c49b3c33884ae8e1208db8841e0ecce8e160833d8698c8a20926f810d1e78d132e3c61068a0d3688a29014b72ba6b0e9a142083fb71baa00c3068c157ac09881d9e08a4358fcc962461f2d8cf81307500d5bc84093819e2f29e05ecf170fbe7419b94032d4858c3f826438e185115fcce861d00c368464ac0086062284a101984231d20cc508241e5a9a626989e19111590070a3258315b66420860b00615c60638a2e476080e6a5860b197821a381172f5f6a080243038a0d6c477060eb210c8d18ca3028410c061c8ca151a883db151eccd8f3c10c2240b8b909a105b32e6544e8a201191b1865646031828c26ccd09843020e25a439bb2004132ee872c21728ccf09302122ac459618633344c40732b4bc3250b0b3302b5d0470d1d17debc40a305186e64d66cf912c38c42326031c31e3644d0607b53c38c176c386b2363cc0d5ab4e010280728dcd88e7833238e0e316cd8210b0b687ab294c043960de08431f640a38aa33831f6f870c40f48420001470e0e4120c52004129a12f40c4118e208f77a861cccd133cc20290d87e405116958d0c9204d0a5c5a13b83b4763116973c63a19a4c1496b33da4963441a9923d2bedc2984270b249a486246117966a029b1c46609347accec39248689435d9a10c4278a3e47387183f3440c1aa0381385085218fa3285212a96b6f003451578ac00e20a193760e142162668f1c19f4219002ab4458c3f81a0e022892e8610b4b4831749347ca1c4c2a014089100865918630a81190d85d1e59051da989624689845962329b41835b1250f9722232e5002a20b0f18e4e085860c60d020cd972214c0188db041d2180e3420c380a1a52c0c3184048d21f4a703427e3c20e4c40784960081d011211022c28c10102210824386909b3284681881d00b66089d2181d0590984c89c11f2c004421c9c40e802148ad25220a442a0158cae386314051a2326d224c1829d16e6a829fac1851d5e6803430c6b8c58882105194898a1c88c0d52181a32a861d0161b0eb52174431738fcc9c10a3752bce9a3839e1d9040b3c3c31c384440f4c0439c1c7ca0e10718804823078520cc085114c21063e6106d40040674bec85244187504d9f963441547407187093c4549206144124444e429024209b42596c41d5ed88063d263b466dc736676c484175ebc18360148909f233e82f2d4c11dc9a9f511a4c3483a91c112826a1034439af189a412a0f8200a4160a410a4650a2442546ce1a78a2a9cb0e248892b8ac0c2872c72d02229863f68002195b0c5078192be70d185962e9008090ae4c5155f4431888b3b4544e08c7e3822f4068ca518704868c2382b6466888b0db8b8803ce467893f73704a609069455d0c6b80b22c893b02f9d172d4674b0634e81c718973c19218884d9a4024e070bf44200f027919bb8081ab79814111202f7d70569632a82da1c198e70b89078c0c207046681be4c001920c382217c2902c942d893bb65841cc98c298da99e8c5f64b6c51b6c41618e08870bfc4165a70625d5a02501aa02e6a1fd43ca875501b5313532bab85a97150dba006a6f6a5a6412d839a971a06b52eb50b6a5c6a5b6a5a6a596a43328d3c441a220b916190609084c841e417a417a420b20b920b3210b9050988fc436a41664162415e415a415641fa21a920a720a520a320a1209f209d20fb907cc8264826c83da41e72095209320f990489048987bc431e411a41da21eb904590744822c839e410a4106410a41c1208f207d207320ed9030987e481442377207520df906ec81c481cc81bc836a40d640d240d241b720652063206720d0903f902e902a9866c8164814c43a221cf902b902a9029902890279026906764092409a4197204b20c498614813423432041203f203d203b20c79062c832320cc901b9010986fc426a4066407a213120bb9017905cc82da416320b391cd3c643a3a1b1d018c608c648681c347e317a310a1abb18b918038d5b8c80c63fa31663162316e315a3156315a39f918a718a518a318a118af189d189b1cfc8676c626462dc33ea1997189518f38c498c488c78c63be311a311a39db1ce58c4486724629c330e310a310631ca1981187f187d18e38c3d8c70461e46b471875187f1cde866cc61c461bc616c33da30d630d230b219671865186318d78c308c2f8c2e8c6ac6164616c634239af1ccb8c2a8c298c288c278c268c27836963092309a194718cb8c64461146b331841184f183d183b18371cc28662c1b2f18b98c5b462d63967128a6898744436221310c110c91903848fc020419e2192d8e4892249f24ffc927ff9f0423254f1e9b9438b6e76185690a0cb6a7232509b1e6d933a74e1c21534a0154bdf37ee9a8d4cba1d4f2c947e6b8ea74b65fe0dd1aabfcbab5db9fee6e8d856dbdb5cc2acfd36295f502b5eede251a4c87f6f4dede795a5ea93b4f8ba5bbbda75a6ded698ce27abe40a1f5bab797d33d97bbb7a77b19e7f23d3b598a511c3fb5f6ea2a39bf3c5e4ef75c2f17bc39a77bae3cb54675badad3a7e526ce9d5aa3b972ebde0e7881e6b6c1bbaffe05318abbbcacbbca5ca933b770baac3346715fd767d11cdf57cc769ee376dfd2eebbd39eaed76751bb6faedcda560ed479d7ebca0175e729eff6748777ef16783bc6282e6bac7e39c7951cb5415eaf54ad2f5a7910a37c638b5661c7264eafe0f34a803306e67aaa734ee5f55914c527afa7deba571d9905e632cee9eae5509a6a69de9ef22e1910f7cbc31bad374cd77996ece6b6eee574546ed7e9956abdeabdbddc357b4e35d00291ea97738b519c12216eeb7e40f57cf1c9d361d462744cf33836ab905f5cf6cbcd6cf7c53de1d8c59b49293c7b3d6d66fbcbd8dc5af34ecdd35d6ff472ddb3f84451cbc3dd02754f6dcd4f5c8c577bda52f17e79ede97a5e5303ab2fe3d3661fe63c2df9e53f84b86bdfcd785b20de28363137efeefa4cebabc26eb78f6f79e1aa896bbfbc0a2f1361cea266b6db574afde0b8f6cecb3bae576559d627200a5cd5272905ae9a7ab666be3c7ecdba3bae4f57f9fe1ea8a57939ff55a13daf597d19a7e6fdf1387a79643f8cf352d2857bc2a45f26b5bce94daff4f6edbd9bded40130f3fa7c166c5f73ebca359af1dd012bbf40dceb3d51dccf14885a6017b71c739d8ef39b75bd621698ea9dadfcc4b65fb3e66def5975afa7d66815d36339b2fe55668d6b6eac8c52bbedfb96e6e53ad7276e9e17dbbad3e7ae9a36d7cbed3dbd6a69de7d7b4ef9d67b5f7de60b046adedd5bb5e2bab5d953b49ad99e67dabb66e7c26c6bd6dc4a2e774b7e377ab74e576ddfcafceedb79e9ee7ca7cf5ded72f2c540b595dbdab10e8b89aef633b5bd6b62558ce284bd7baf4a13d77e4d9ceb97f7cb73fdf2ba75b763b8f32cc7fce6ebcb097bf7eecc0b9579caf3e559f3ea9425595957f5eefb0bd60de42a75e7fc9eb9caf18f3b1646256b5eaeb775e7ddb1aad375bdab19d77a81965f1e3633ae3d7bcf6a669b35ca7fbc94575eefeee9f2f4de31fbe375bbeb3c63ebb3c21ede374a3d2f3fb36aa9cbbada7f3efc848beb49e7946b121defedad7b4fb8b872b9ceef8ee77af69eb90d04f29eae39b781c0b26bbdeb132eae8a51dcddd9ab5fc7c12d2f5c2e972b3bd9ed59f3ceb477b3935a3ae59d7673db5fe5b8e9dc598ecdca7bb896bef2d6277e62dbbb9bc7c5b60ef69bebfd756e79a6d57b57ef4ee7a6d3f2f469de8e5e1ecfd6bbabc2336b33dbbb73d2e9cc9bb1ed3bdd546d35b3ddbae7b4665bf957cde58457ec9e3b7b623ba6ab2fe3a76cf7af9b97a7fceeb4a74b6a9975bd63f8ac1cdf5fefb65661b6b5bc25ae4fbfeacbf8eeaaa97ffd0275e5179f7757d3dece2dde3afb70e51768b7452bb755d7f5c97562b6d72d2f9c2fd5bf5ef31dbb952a0bcc49572d79df1abd7b0ca7572e06ee525eb7e6fcf26eae775b5ecb9d9a55d871f5652c663bc7bdf2abfb697978ebcef1ef4453cdab1cd77ba6a606568e7fdd67795aef89022dd9ad195751fce3fbe6a0eee9dad37aa3d5568e73c28eb7fef5d4767d72b29b4b27f3f272aa73b65578566e834d95ec66735b5fc6b95cf9e369f49a579f65d615ee2af5e15e29ecf8b439ed55f36e9c5eb91bad18b555a7abf70796b3bf5ec578f787c54bddab70dbb17a9e38586db726bfbf8c6fafecf9ee9df2eafdf5255578a2a82dbbce756b8ecd6ba6278fff78f817ac17a8793dd5e9c9cbb8665b318ae35825dfb7675cd3fd43b84d9ed62d2f5cbd3fb05cbfbe92e3fbeb77ccfeb6ae4fc2dd562dbb8fdcf1cdbacbccf6fe3aef1c93dddac355e7e454359522e1dd284d17a8bf9ac49ce83216ee9b3a5085578cf3bb4dd39661ba6b6a5e2ec5b6fa32bea669f58942a9408e3306eedbaf59eac230155df066dcb3ed3c6fd57e5a6ebb3d4fcb2bc374e76979b9bbed8e8a8a8a4a47a5defb55cbceb3bb67cdb355779eade6c53dccbb28afb602f5eed5f3b4bc6a2b70ebdebe5eb5a768c6d7cce5b8f5757ecd8c7d786b8ce21e705262d4d67dc5b60ee67a3d5d56316e7bfdd1ebe97a7ffdabfeb8f0365062d47ed5f2a2c25e8557ac2a508376737c2ac9e56ef7953c7cee52b49ab76635c1617d55f3769b6fb7bcac79fc492d79d54df57aaaabb672f3defc25bfb8e3d3e67d3bd9b578ac9a976b94ec56e115dbbaf3d2bc97d77cc7b08fa755789e5673e115ab5963ce2fbfbcda7a7b35efe5155cc124ea7f07581714275839255d509c3cc92dc93580c3c2ca6aa066fbeb75df9c9953bd2b4e48295546fd10b33cde151b1e89c3619661d2f07f38fc71f8e4f03318fe972fff498ff4ff5efe35183ed270986538fc32fc1f0e35f8a196ffffcff2839bfeeddbb26ad06e206510a932ea470eeabdfb71fbb3292954eb8f5b2d9b124039945fa0cd9d6751a0c6a2a2e25d53f3c6800449ab72fba2641628c6d3e76e9fb6eb9e23b340320bbcb9cbedae0a489014099905660d06c4faf2fb7a712a2a319e3eafbecabc288a77e754406e83484436b6abdf7fe7ddbd35af769d79ad3d5c2bc7f5fec0ea115d6eeb9ccebc577c97bc63203e7fff2ffafe752f6f5dd36e1f0ae549e7b609ee386f49804f9bf1121ee619ef4e96253c511407bc9d0bb9fd79edebf50f666ef57b9ed6cbbc63fbf2fbe4debd84c731908a8ae72ba67bda6dffbabc6c4f7bc577795a9b15962fcbd247bfe753b777fb6ad75db5e4f5b4f64c79a7e5f93236735aefb6f53e4075deb17be62ccf7677aaff87f2b605dc5859fd8fdb9fd5edfbd63f5eb5ee3f6e7f95eaf27dc7eeae7c973f6e7f56352c6bccf78df2f5ff09fc8b5b80885249fe45192291ad8a8ebdbbf3f3f29a04493531100a0a6a9772283193ffe8dab462a746a138d4e5d91315db3a0865bb352d362f10cabc3f6e7f39a5a2ba3ebb75e7545417887b4e375954552d09a0af543a5dedb6de6e3baf6153f5c8544aa50a09175aaf7b7b392eb428e7f6e43d20c3ffebde964408dfa579e2344aaa04f243f732fe714fcb336ff661ce7fdd7a99e7c553facf876f70df3127e6cd509698f68a03a9a8b8e5fc72717e797a77aebd742f6f09b7eed6cc96ebb4fba24e4e0bdcba8b737b6229f9f1ba453936a9a878ee02edee71a1f5d25dfc4e517272a4cf0153de76a4ca7fed019fed15f35df68c351aa42c5246fd90e25dfe47a8e4dcce6fceeddb718e77510ec5bb63546afecb2080408daa4976d47e79afa7898a20800002354955357394ff5a0e35176a18d4b06a5735dcd78418b16dcda16c535dfcd615e27b4e35af26a9aaf99eb9debb67ce3cb591009d9b354912dee6e3d9ff0fdf5644ce14b02d2c9c170eab22a96426fe1380186f44fd8f538838f1ddfaf098cd50f7eebe833a358fef9b337e40982d97d660ffff645f138fe9ed651de059e3cebb6716d76857bfbe6d7b695ef35e1ed9ad7cdfaec7eadd29cf59448a887ca5228b6af259b03dff4fa56681e1a26c3df11ab2e69f4ac5da5ab28595e5f5f5034c4a16589713ac211f0c0163dece4bf71dc31d03f1468598d986e421f6ff9b6a1895dae5640b0c87b5d5c4cb0be7c57585398e728118ccbc12e0d3ee9b2f930bc46058605086e0b6f4357114b2dbef79c1bc78785f60da0596f59585d59505c581ac2f5fc6bb7f4d2d0183a2240b0cf7248b0b4a5756135cd69327595b4bb6c0bab2946c5530ac2c06ae9c346902a52b0b0ccb0993aead27605f156cebea4916932cb0aead2e5c5613274eae9cfe1febff9534c04094ffdf9aea7528be8c33b6c0bb4ddbadd6edc21d13f233149f05bb3b60dae5b360d7d45c3e0bb6af69ef937dc79c38f165bcafb99df4fb75bbe5e1134d95f4fbf5ff5935aca198d80997899d9c9687b3ce969775d7ff2b799fedb7e38c7bd7cc5bff8ff5ff57f7ccdd9bb7965c2006bbdd2af97fdc0259e38eb946ffdfeaff6bbfc0ff9b198b6dbd771690332652f8810cd4468868230b15a305a69928c88ea15187b1a9d7e9813386008311a2213434c4094a1de23d810812861e9cd7722a33e210d27c99ae2b4806844de21d0222832030448cc28298cf82ab7e124e88f18b02559f830b2023142df83cca278a97a1888bf883952d46130a391147f47e8e8731512bc60ce31335a48974ae989167487210857ecc5e44737a2b4932481bf9cd1fb1b99053c850109d90a1c75701234df4e02a8f98444eda8b79acc6ee46cae36084d2f8c011467e012b671f6665459a98969646a6a56151a6c327fa004c134780428ab412069f0b3b514f0e9ffc1da601c6049890405c410aa451862da6d8b806e0e24dd600540c01e13bc0618400828ec8e285a5315f2b3480e8c4c5e3b009096218499cf9374bba1f82b17c181c66c42e411831ca385b1315658b228202f4ff19777ecd7ab5599d9a2e6fa79ac761f35fa96c5063a0268012fb4a9554a97aef9eb526e9facf8777adbd774fddfdf1ba0526d99124c9ff233902f564835afaaf1cff3ac7f7d72b1527bb269591ae26b6f25a7df672426c4201d31c55935455dbcf6bdedd04699517f26306d4f2f8ed5d93b7b346a68a101922240810a9a80734d4bd11d0e86b5f4b22bed1996812dd44a39f21120120ca108f80d48a3ce9418d00a3f1e888a8468ae2df18cb1f5f74a0b680f84647887e4691f8a2281211091995c61745911cb544d1481c45912c92601447d16804e089281689463f8a314a722c2a6a4aaa626d1c6b65624d14c72451d028223d91581bc92b8a5646511c8fa08c3a46712caa8de215a328168da203e20d5124c7a31e884823192200a2288aa391d1c611299a1147b16814c591cc89632d0949c8b824561d89443dc824a2d138d6a4c8a471149d66101127a849292d21bdc6affda88258239b6a44a3483ed107e213e28f6fb3d9c451d4423c1a1310c591681c49510c22428947e2d2388e631196e8631c6ba31845964a011c2120c6a091630c41241a03106b2229fee835d624b1f6232efaaa1337207f470fe25bfd309262915833126388a4d9381e5191e214298e63ad8e4b484d2291281a45d5a40a8812c7a4a2a3d14814a9c471d443168948638d1c13798ca928923f4424a5513c321247ab918091807100f2c917678845e328c6a8d9c8da18c0388e629158eb89483d4425a25124126514d1316e1929218de2ee68c968141d108f44911cc59aa8250e301a1905189546a3914824c5511c452a7180516934aa892411298a4544526c1291c42551148f88048c49a4917854134751a412c522004626b1368a4435d1c8a82492230122498e636dac8946c651cc31268948e2516d1445914a1c604c3222c5da514d14c52255c491c01112520122911491c41a0e1109894a898a0e0244036ae238168d4657b4d98852d212c5511c4551fcf1468f3e0458444053b4f83ac5043f75a6ec88028b07ec132f4071a2cf83ed58e2bf4cb073bf6c11ffc40437669eecd04e1c30c10a202f2bc4aa89090470a16505883262020e282356460b459c88d1a3c88e24918813a22122ba341288d4435feac220e0870ecdf8d46705fd54a31250e0ece94f01baba5440bd41e3cf6a84bd8e48ccd7da967ff2ab78d99cd0bcedd6cc5da0feba5977113973b2fa3f2db6f5d771f0c771c60cd89a06fd0baf58e51dd7bb75efeeaaad6492ad09ddd73c71ba83eac0de92b735edf89b75e5a9c66377a3f5feee890235aff654ff3a0e56e1eef956d4026bf0e66aabeed5bc61ff5fa446658224a7a7a4a6a60a6a05494f4913d4fa5427a8b5d6eaa34fa5f291c7e683cdb9b33d05fa30fbaf54e6ad42d3de7d5aaeabadf7ce0a927df8b45702cc7baa85b6c9ff03c9e99e43d3dcff43497d8d1c5f3c20d0017bdeccb7f674576bb7951fe0c6ccd77680060790d5b3f674bd5bf7b6edbccaff531d80653b00c901489ce630f03ffee9fa1fa118cf91c818a40926c43d6a5cb01263e87d25a8c25dbd261ec366d5bd7614787bb7ffff62120c4e52442a122455aaa922a95581175a60214d05ffbfe56d3bd09eef32e578fb9ad4665c01c20e19073e4125949082480840cf183650e84883845ce24e901b664600d306278444e3c0370254044ad2c23c912aecb0230a2b520d133f7a905f864a1a88408233455c200089aa69aa4aec8e74e1c44442a1c256260c13465832b3441e29634b418a2ac44839d53a05fcb1adf00097a74264d1971638f85383d50839ba18afc861ac4993332928b16131d609a30c054aa47046099228c61ad02861e7ab0a143380b0672cf3c4190d7b4228208aeace98c50c0008b89860c7179f39636f4ea553e6882a642ac4199b7829c4c58d403c704fb819a56cd8b3c31758153ad0613302e0c50f64360a66255451231652a10c1c217a8c80392005d189269694f04684b31c142388407c90009b2a608470368307a21a3943be7c900342581230e2982e54ba8ca152c607385cc4201bb0284c10328123488158251012d9046c2a10bba08b572700511081cc9f2003a7e86309510b3307ba8115a618630c177e5a41071552fe03c5091b80d0d59501c8807d9e2d401c7190a385aba7c9bf59d3c49d0223c705342764c13b41ea4e9c307cfc7b29c1890f046e90e19125e481788c984aa1852a86bfffaf301600a133811555d09f420b81ce044118d998e19f802c0b18211be40112977fd205b22b7c50b35b4af3e3e78e0ab6343a2358154a9bc18e0d37a43c11c07dea224d04306ee620692f2f73b048b3c08d1447e6985b8e2ba248e319c28086405b5e08197bd2b658e8d14304ccc71c7127ad8ca28a2d4e020a1c299a93c624c2024ffc5067022c6ae21c2244c49a03a05c29a91adc1ce2a3c111a0413bccb021c6e6509c1b94a01d844153a6083587d20c4a932bc24bafc083140e855981cf9b12da48d126cc08873a1f42c11ea893056f3c380401085d17801183030250c01c5a200837693a213c447d7139740006bb1cd14901035f28389444030d2ea061216dd8a61bfac3c513833a68a2872d10380de141a1859e9418b925bc300de1a047cdd9a3829d0a5caa183aeb40ac043a391c10040860862ef08109253e721c41040e4d0c89719173878f113f2c704489212f19a67c61243044060e90181af2474892d98d04d44821c4908eb32e451011c20e2174f164e893e8170c7180162a207a149aa20c042bf494969913010a0d01c7e60111ae30a214612a1483162434846135d07960a910082fccd9126345f6054cab159ac08a1178040dd0e2cb10850a593357d4847161852068e8a2d092231ca8d2240585cc162c0a3d6d50a70017cab014421245a19b0e51c4fcc18921b1b4270c2fd2823114d2c1cd1e2777c2d8d3027ae80610647e10e2ffffd09c30789822471164921c597cfe7fc492ef4966812395a85ec65db64bb42262057e9451a50e4278df167de3a34a72a67cf7c46378a3b7dbd3f2f8ed588eeddf342d16107ebeeb6c56f29e2fd0bc955f4ca637b06add81d02ab98f7bee70b7281007c411efeea7f3b4b5db1eae4fb81ffa544b76ab7244a4d27d73d0a29c8a0aecc7add6795aac1f7e3f58fd507d18f4ffa669e574deb5e28319f08e691f501fb4723ed4324c1747d0ef14cd5d2199dee8efc7edefb477f38c73554f554f5454555e288ab349489eccad38505f86e98237e7fae5ba97b7742f633fff543ab4ffff8cebc1ec51fbabd9490f64a8bdbb072db387dac33f0e4e9faabbe0ac81e3b579170cce130f7eee0df6bb03dacc039adfb79fb857b9dec683976fa7e84679bbea7d25f89139be7a1b1a17685cd8d0dafc7f19e56e8d85b3cae0d5bda2895da0e6fdc826e6e1f44b0891945f9f45ab7629af12de0684574c781bb8a6e6a11d7d9edc0e687618eeb0030e1dfaa439f34aa0431b32dcbb1bcd9d2716d3c1eccb309dd8b6401d50d4de5fae5fae43925cee9a3f6e7f5560a8ee597cf39e2fe6e15e2fe5b65b253da71aab779ff07d8129cf9a6777161515188a3bfac64bbea80edefc46ca9b263783de4d9bffd29731d727af727cea1fbffbd7f9f5f9525e51dcddb889ca416d765eb98f8e6d39f4f912c51dc59d6777b5e5e085ef8ba2b89b50d9f22a8a7b0e3f14f71ca67c785739ce4129d5fbe6ebab5aa33887e2fee3568b8a0aecc7ed0fedc7edc97130c301056a7e833687835719a60bde9c4371c721874312eebc1be5c7add6beb797e3b8c72fd727af4ce9d42f37cf53df60795ab5999e29bf01c7bf530f37056f9b3cff4e4d6154daacf9bf626dbc88e9d44ad566ca2b4e57f67cb305da601b20afcdf46bf715bcb9ea3c2d5655e5b682214142a6afced3f26cc8d3a60cd3716b835919a6135eb15cbf36fccc9bd39c36536ec3963653ceabb6def73c2f3771cf97d720e5bf86a8ffafe1bf67d406390d3fd0302c85bbaa7ba5c18b8626a0bdbdfa6c66d3a7342f9b323652b8d834fdff60539b41cfff7fbd6d062fa56e861fb7c119847c69dadf0c4c32c8d1552bdc559d4d06b2d294c14b061cff5fc6d0a7ccdcfe9cd86230fbd2c6f003665c0c5631d89e87e5e82e6feb253afbc3adf1629ad6b6c6aa34efe665ac33b7cc5b6d6bb8b0874d0dacbae360f0f3258a7bc5c18086da200c655dfbea79e26090f2ff250c535f9af7446d90c380e3e74bf50ef7829fe0ed7ac1ac6e5d75ba6a83b7eb05b2ffff17acfe7f6b1df076ac73c18f4e0999e5d26d17d05cf0527d59ef2077418a0b53a80dba60fb17eaaca64fe9cb6ada7c99af98ed4ab6aa9a32355effafa6b600e8bf8535ffdd6eb5306cc1abe41d73fb6b01c77f699ad9b200e8dfc6c29ae197e76979fba2fd7216bcbe64a12963e079e2d20c4a2327cd99bd27bfa7def502751ab234b50a77f70796c6f65f3add73677f649d9b2ac768f294be8cd1ac41a3fbd3a6576ebd3b3438ead85f306333d5b6335eccaafbfd819d89fa2fefd64061b69ad727f39af677e6ff7f649debedf7bc26d60a72fecb6c956c55e0ed2b90fd9728fe71fb332fd0e67a7f602b68fdffed3eb2e5d5159a4ecbeb06debea5429eff075615d688f1f459b90fe0ed5b2a947d9931974d05afde69abee4a810bfbe3c0dbb190cc02ab794d3c76795809f0760cbc1d036fdfda3d13efaa388ac1c82c178ac180b76ff5aa9e311712b2aa2a25f5a967cc65bb35f7e63d275f777b09af58d5171515d8dd69efd677cf6b026fc77c5f61bacb99375855d5733de51c3f8085835555682aa675938c81a6adaa4f55555bf5898a0accdca2a202abdaaa4fb633b4b3b2335d4ecfa61e88edc93bb309d39d1f8ee29e135ab404b412cc4a404bb02ac374b7041c0fb4b793d02747429bcbcb74bc8d84df3f095665988e84bad39d9941779bc1f1363368ca309d50efceaf6906cd9da73533f5dc66e6a80cd38dd0e77f8436ffb611bc7c19a6bbbcad7b2348f91f21aacca0ffdff69ebc3272ca949561badc7979d996f9e5fae565acca305dee6eb48ced2feefba27aa364007dc6403272de0679ce4606cd97613ab2cff5cbc96ce570cebc1bf36b56fd3a7e0078fb564e7866ade4667c9af69a55f50909ef46a9c25d9ead4ff5a967cc0524482a3cc92c10783bde77ec0b78fb16bfbc0ac94585603d63ae8b0a7bd5e5e1ed5565e6cb3907de8e71fcb46355e69692aa8e81b8497d32af99537d65bb35cdadacabcc2de0ed5bc0db71cebc39a8ab7ac6409c92cbc31b9bb6104e5c08361c087dbe40c0e0ff4f6b376eeb8ee2cde3574927bb5d555548b29090e92baf7d73d089f036404505f6ff3ddef6819f0fdae4b23dd10f2aa8da4ff635f735f3edf5f4f559af1cd4555548b24e9be6ad9eefb6a892ceaf0f9b4ea8a87edc6add6e3baf42c2bb51f8bea6bd5aba97b73ad768581490302041c8ae993bb0f3ff1d60d0b17937cfd641d37f29dcd9c65051058664eb25ba03f5eed9c6a060f6ded6a9f5ce36c6ea53ce71bdbddeb58df9ffb2e3dd35ebdd37c87b3acfff8b89f35fee9b83545462cafe5fcc6fdf1eb7419c4d4c9469811df330ce5636a8ac4ec2b3737bcfda6d53c69599fd7ff974d6bb35b03e655b7b967777d5bc28aab75926e54ba7a66adaca8e4edc735acdbbebdd092d304c9fffd2acc2f34c7b29afdc0671ff3ff5b630675a7877952b795b18af9e2d0ff7b20ff35fdf3ab883f5fec0c234756bd62b34b3beb271e0e74bf3025320ce1858efaf83d9385863efb6601c78296d1ce8bebc1c57301b07b572fce3d9bb6bbe7757cfde833f30db0679febfe41cdb3638cb1ae39d6d03f4ffcb9eea2ab4e8797ff56e5b6fedba6b83a9ffbf59df1f986d03a6ff2f53307d6c60cafe4b13efaa2fe36ced89de1dd467d5baef6a3dcfb4721f26dedd1f18182b5feaae2a30243d274082a4661598a32b01eef36ffbd2e6b45fcadec4bbdcddbfdbed18de682e687ffd8bd5ffbfb087730a046adeff0ff0b62f01fc9761ba8e79b877cd9c99d35e95537d6a126e8c925df306edaf9b1aef8be63ab7e779e29e717a655f2ff306752e6bbd51b26be6ad27e6a97fb9ac73bca3f8f2eed6bfa0284544c400272922a9acaaffc70d911a7176878d3f0069879894c58bb765c1e26d59921020060d73ec6998103c0d9381a76126791a2690ff5f8a2183090f0978c43c131e2ecf8467ec99f09c358c988cf8f14c475431d9419fe98822cf74c4d3fffbb85123490f5f23090b5f2349075f23c905ff7f2b3ac243e599f0783d131e069e098fd533e1997a263b411ab61935accc7c0dab2f5fc34af835acf0d7b0a2f235ac9a7c0d2b24444c4a7a3c9392029e49498ea2a21a3d9cf0357a00e16bf450f6357af0f2357ad0f2357ab0e06bf420c1ff232dd1502281a7a1c48ea7a104d3d350e2e869e429f434f26cf134f2f8f97f25a41a709ebe069c02be061c00be069ca5ff472295984e60f24c27543dd309479ee90421cf7482d3339da08306139dfe4c7476cf44e7c933d1c17a263a446c59d4bc2d8b096fcb52f6ff4c4b454c76aa3c939dae67b273f54c76843c939df299ec20f03366301d81e2998edc79a6233b3cd39135cf746485673a72c2dbb268f0b62c5cde96c582ff5faa41c5e76b50f5f035a8d6fc3f138d251be5d3db782af436ca1c6fa34c7a1b3f0ebd8da6194c544a3c13d59b67a262e16dff4b326c3cf1781b4f34dec613f93614f8e26d38f1791b4e81de860250fccb3812c1d738e2f5358e34f91a47947c8d230b084003cd99a781e6cbd34043a614a3069c375f038e0c5f03ce99af018784af0147ccd78003460028453ba6f801208708655f3658e16524e90c489d3effff474f4ca0ffdff31d33b18eb2ef795a2c27e769b1c678447171b271c9c18506975a20db163f4fe8b943440e3368b9d1429ab6c52c4c05635b803ddb58536e0bd796ac2d5529145ba678b7be318efbed3cf34a70ef5e9235b7f789796a2d2d7dbeeab6defbe67a8aea6c5a2ef89b35c7bde2b43e2dd1a2c4a6458779da6e7b35ebfc542f507f6933e539bd3cb528aa75eef98edd5cc7c07b6a33cd756e7bb93b8679bebd6be6f6f5f9f0eee7897bfcf614056a5eae5f7e6fb7269a7e093b3e71877277f60a05dace2f1083e1b678bf9c93816d2057cfde261bc825e4d9cdd3c0abe4c4bc9c6aac0bd45828fe71ae1fef820977caed7dd22fe7da4cbf9c00b7f8e5e5dbeb39d142f1b984f39b81daccf689b00bfbc53cfd15657f65dd7b7a32b93e0bc4777bf930c7fd4cb9388ac14eadbd84fbf6ae9b70dcc56f7a056728bcf7baf692deeb126e7bda2f14ff78509fe75d72b7c6ea1c37d9b7eb285963ae8b3718bf57e6897f58d6cc77dfde7d22b62df03ef18175ad9ff832ee3a0ae6f8bc1dff1ec81a77cd7579d9e2f3e4e7a9bdee189679c5b27d92a1746e978c69afcb53eb4506764dcd757bf66b5f31bdafb2b818b76077098ac5becafec5301cfc8b1bfc8b6034f8173310b778f9173110bb5cf02f7211b7a4a5a5a5a5a5a5a5016a62460e3406d07fc204010051c113f5788e9c15d9c0ced4cb39db53c1106fa4bc9b3848287959f2f3318cb0040b0c7cfecf0830e6461822db9b39f2c6ac0a2cff1d0032efcc1084d67f918ae106739fbd962fbeb0b05d4cfd0446c89e28a3baf31c501c548204d83c1080ad21880898f33d14b80432dad5d78d01b3004b13300fc11e2ee860c01bf4502a10944105627d2fb42ac8a34e9c6f00864f21893ce7990ca9e1ce55076a1eeb2bd48e1e4fbf401212243912b8fa235e4c6c71c404fa22746878b3400c805e881620597cc15be2a57c65d072809ebe9ca010102b74e1f20ab80953351c63be130235f0340fa647c0864285b8d88285ef916b90545468e2792c1902184505565fad72ec48a00a0e4f80945ba13e6fdabc0060a0307a20b23ec79e3c32b8a0078b0f608914dc8faa26fe06107c8ef492d81e00dd380645e8f336625819ab01c2f335e820f102173c424f03851b44e8a8e4f0b70c6c79603077781b161ad698b1b2c4cfe89224e3811d6c2fa34cf5208532023e860e0168315507f84b5a1840c83c7467b89480f0bbbc1860a8b4232804061e3f9fe403027e50074e1826f1786202bb1a3e9297233890b285e68f067d0173451a3c7f840a1185094d8c86465bd82e00228120684664508833f49802cdc8a8ce0daf11005915993997649981a215197982fde82d56447a0c8812a706054fa4e5022da810466844503d5c6080869f61ad4f0c63c4806133ac81e084191a57d6a0d51cc867462c90fa9a0d800fc29218c08a34a24c9530b644e9439ac1d98282105e86e40e4a92d893b44a421500c404a73d753c04a88999f79d8d76c864902a81e56c5c215011e9017cd0460bea8811800a297e9c12630511aa30a41b877471aa4097ea46261c4fca08d3acc42e5298a2c509351493589292eb5256620e4214987213b446344184c068cc88a1e80582423f6ed012255e713a21f844034391ca0356419af8b0894b8a0040ca53af4c0c524109759ef8d1893bbc2cf0b323ab23da888829b1a78733f10be811f61b327c4061541912436ef84fb87921852142a08f074a190e3d32987a393728217b02407d377ae6c8204a31f531c4e0c419d181e19f899a8281244678bd99ae261248c1ca790f465e17322c69fa2f57675bd69059f35b8cae24104083b39f406b6c4a159ba6e787f8d88034d83cd0000e0a45f1c108df5b237e8d1933f53a126a68a1c120db43e047245b02a8cd43f142e54f7d53e7bd24309a00cf973bdf409b2120f46842c833a9d2ed3f15ac79aca32536541083975fe0460510890664fc91072c20c235c5145f040f16196000238a17e205041f649246782920095e779ea8f36596142e1a222bbc023c38c1c01310b4bc9302365c01060a003c026e648803029a96efb1b370c95f58781e0c78d184a11a515f9514090508ca7902a8c0f1624b12035e80b22a3d6ea052fb1c7d06c001c103810f604bac0a18e6f93784e8a14e9101623c003b1ceae814d0f136668051430215be7c0d3b0b7cb91a14e469a85005c8214ce36f5f80fcb95a5cf1b62c3660310b32fd0c0cb2b0804615315ec60854a0395c59e263ece003153abc78f24b7f6a504190510abfa400177c7297ec95780f633a2011f9a41fc69c10b185f94906f8d028908a79a40c0a49f0c29e20fe88d009582835d0e68faed84133008bb4370a6494440716b47923e1106caca0fae28d8e5a40fad123f24524503149808d0a5f44c594646a088d27d2a3049bb42f5a9e688b140e42b5199e08ea8702acf89caf39b125dc4ee8f0b510d00cb4f84c7dcd014101a82084125fb37da0230f19db9347d0f8d18121cd932200b9c090929427773a00814821ed49282d5480e030e1c7342eb33354a8f9d14e20075ce042e8c73359beae1e757ec442001301a220f3e39428714ef072e1c7214208ba8d807f649a12c300a5265eecc2092b2e70007931892c1580e8c1f7620e566c94104190174d10c204a4818417bd685083164594bc78258a065c08b0f422952c5974d4207b71891749e4a912be180405233619f85edcc1d7a09d30f6a2ed810c7448f1c48b5fd5844b0a41feb7c0a1c6091e0bfc3f91074b861268fce3d15c4c0da6fccbb10383152a18f87713e807034610f41f0310587469e4ff4c16122f46f2dfcc4eb41d91fd7bc074b37ad4f8fff22526cc09f9bfe506902f0cadf03fc103e9093ba4f9ef4b61f8c824f90746e1996394e6bfe7068b112e48f8d7a5b93307b5f20f011736098848658d7b7aea2faed1aef18e8d135da947cc5bab2512e4c4dbc6ac440b3ef81d2123c48b1698993a327ce1275aa0a70d550b4854118b531e23769cd0885830309b2244c34fc45248ce9400467811871b7815a9e2d146cc920407111d9c3ca2961b798660c9d346dcb2834cc899214022176c16042dca947841188080f0d1a18a18f8a95269281c891ae0d648d5aa256ee0a34fd40240acc4b21a8ea02278004dfc60865769410c392299def08719601ff12c90d6939b2ca6443485fa28b047461d51863c5e0984f15526eab0c5a0047200a588440881e664243814f91cf2d324e5cc8fe80514343e8232f4196f6fb41000214e9e3108046807d0b0449bb1ca07688f3b837e639804d018d0850cad9108233a036a542b3280296878000132458eed50678703487464155f792abac44b2d8d62aa80305e6b887880a111f00204798804392156406695bb199f59e780b877ef2e93612036539b3510df9ddd65bb7d776777be8cc5f2be639ac9bebdacbb8419279631cff7c7eb58eca242302199de5e6397d299d83a16127f98247143d08730fe5ffc7245014e9b08490bff2f6ec040597df49084feff514a1146acc1c1078f98ff27d72c6900a603062bb6fe5ff40ac44587a503c864f0ffe414f4490b7898d2b8f87f118ba0162a15980c35f8ff1a9a13d278d5c8414e91ff1fcf2c10040f13c46a081a71e2a144c31797ff17171843c549590666dcfcbf0887c47204037724f8fdff8881014c254071801043fcbf889e99a00614a4fcc1f1ffe20c2fec3e869b156efc3f29288b086450e3830859fcffd8246b0129bef8f8f2c5ff8b452c19e608624d093afc3f69234c1d2d42307363c4ff1791f960907887ea90d5ff8f5108124341a110a028f2ffb5323a23117e4358e1f3ffd7d4f9c73575c6288e736e7fd5eacc2ddd982465c6ff0f40c4fd23648480baa6ce5019ef308ae32afbe5e9cd6418580acfdb81b8eaea53d7b91ed13935e974bd63e0bea8797fa5ee1bd51b456dcdb6b7557f54aa275fc6bf2eccb66ab3769db9e6aaa579cdcaf153d6784cefec03b5347959f7e0ed55abcbdd9dd0024dacc7ec4d77d7d527f3725c6ded6dd56aebbe9d639f7083e5c6ee46cbcbeb357526c340ceed0fe5e22a75ba6c79dde66a3533ee55dd6b988e5305b70eb2c60c2a3b3e71b5dd2a19831b23665079a262d0c4f47f6b6e3152654f94c911eecc6c8536782b33fbb2e2caa4bc509f68598d304184a9a0e86f618261bcbe34efb6f54c4f6c31b0665cd17bc50c08d3e33940820334bc72ebce4b399052561eee9c8326a0e5c292b2411eee036f60f612e02f5dcd7803ab6025d33b335bbec1d197b69a17cc9affaf5b5eb82d30e803b599ed4ef90d4cd4edcba02ff68b4e67ae2f516f77af1a34a101061a0cc9000b6eef2f586fd5fda23ce37d2fdfaa624eb0bc9e6c2d3c79c9fbbe63bc6bda7dcb60840c18f0c28597355fea5ecd6d7d779ffaa7e33f7455f78cc57876273cb3eed9ee9eefdd3fb2ce3e9f3d7b627acc0bd61f0c7cc0e00a0604f449c2cf1f3ae1aed61eaef7d43c6b1eaef31b4cb5d09771b9432ce3dad336db2d2f9ce63eba98fd97b72e5bef809ad7e5885b5fe51da7f647762f6873c1efbfe4616e773578018e2ff98d8b1cde31172fffe5dde95ec6ba8b8b16eeb6c54fd6c25dc63d5f734c9b1a6b4b9c2d57b6d492ebb3f27e5aac5a668d79c65ae4648db50879f99a5a6ac99d6449cbb2a6d465e965a9ffa54e8c673bbf27fe05c18677807ccb0bb7bb0dcd0cbdfe4b1f3ef24e6f2f2c5c7cdfe29d67cfd3725d1518927e5a5e75512118155515b75af501f37482450a96a9324c7781586cff16f469f36f8119ef668194ff374f9db3a0e9bf0cb3a07777bea792aa0bd45cbd4a6beb8dc772565555affaf2e57ce9ee9a668e5bdf8f5bad6b6a2cde25cb32712e7833053ebbab376bae09ecf47485c271930978b687db178fd9fbe3d8dcb7ff7cf89cc0ab0cd34d10e5b3bbbb27e8e95ccf7af77219e77a7ab7e67d515181ed8ba269ce67776377a3a6bdbf13dbeef4559fa23469fdb8fde5244025980aea2c010e611f219cff07daaef34c7bc26119a613eab699710363fa3cf5366fb7d734718e2c07b2df975bf72db2a99dee76aa6b4fdf82803e68666be6fb40d0ec3cf53ec2edef2bf80bde1cb4b2c15b10c797e6bd8d01fa726ccd677c1b23fbbf8d758d45ed9e0e4ae57c999699d972fb4ba54099b7172abbcd58ac2bd1bd943d5ff4fe7a509fb5ebca3ef565ffdf611f3e2fe672be6efd548584eca25ceb5f8c777f3c5ecb30dd1ef4ff26d663bbcee7f6d926db5e65982eb7a1deccb8013363b12a73cbe66e8eebf3caf04a14eaa76c8232f037d44b03d268ff601afdef427b766c833a2afb79f372bd86cc02739efafc9f2daf5a609dae33d0cbff0502b51e78f43d7df64efbbbbb9af569a6f7ae727cf2fed1b4f6cbf74d79fceecef57936890daa73b9161b4af9324c2716257664c5899de3760937f3c5bb77b3626605b5a295b19f7f5dbb6da00994ab5c9612dc13265e50725a5f38ad9c141c97aee6adb9f0d9eb7d2500c35a55676cfb49f003bbfdbc645ec6fcf69bb29d6ffb33fad2b76dd58f5b2d7ebb70e79393539f594e7dbff759ddecb391bb554e60578c97efc9f365eccbb8a7fbb257ff0235bf802e5af0e63bbc5a6f0271e69a2fb94c9dd08cfad2e96e0d6caac26ccfd362f1fcfcebcc43fb72eb0a845756f2acbe14daa0b03e55ddb50354776675a7fbbfed14386bf0f6fac55b776bbd48e5725667ed12ee670acc717b8118ac8acc72656c813a32ab239203842db05bf4ee1cdabf70971b7eceeb4b316e73b627f346d02fafb808c8fee222d0fa8fa009778bc0769784c9f917665b4bae30345f72be4b799897fb03fb8569bdee0a6baad267eb9e456bb63be5f174153965ae72564577aba2550547507f511944258f508c87fb179535bb9453e9e0ffcb7b7b39b2aaaaa65dca7729e749545455955bdfdd6710907d19a683c02bdf0d41d3ffefd229837e4a9d9f82668a17dd94a9b7bb73d34eb1fd779c5e91e22727052dd72f97725686e94c2be54aae771ceca7f5ddf3c416787737589f9c6cb74aea93ed5649552f87fa508d771577aa62a03eed26ddcb5bba97b1795ebcc4dce20f0cff01abffbffb1e79c056398e8216e5ecbfc4517eff258e32f555b8ab516c5000056f17142868fe6fef06858cec9a158a5729bc8101fa7f3039ff25f7b12f189a0723fb2f4d30295f3e013bc2e6897fbc8a6f5f387c95506edd6daa85f549836161c7658d4d9cfbfa6aca75b2fbf5e6b641fba4cea3793294f2e4c951bfb75725ec39d557a999eb36b775b73be539a0553a99b77b0dca537a99fd974efcde5e35aff522f3b2fa2fefeeddbc6c5f3a91a37b53359da0f17273f22bcd9b93225d7ef4597bfa945583fabcbbaeb22eab7dbb3db9fc3ce92c18179b7f2e312e1ca8b0a7be6d6b933aa5d3d678ccfeee8e6360e92b6f131aad7715ee2aae49b089d79716d8c43cb5d6a97f0d00faf9f0af6add1b9063e6cb1b18e6db805603470ce4394f2c06c5009aff52c71920fb1f77a3570c50d9bbefdd0c6ce529c3745b687e8becbbbd662eb7e5e40917e3e926dc67cf25dc67cfdebdbb273c4fab3534b57465bf3cdd372d1ca51314e7f6c6a4ce7fc9ed8dc999ee38263ade71aa9934e16e4bea9826dfaaa579979c2d91f28fabd9d6a0ce60b556dc92ffcf5af3ff5952b6ce12da13e5d8bc29c94289d997e6ddd5ad753f6fd02af12a755c49d497c2f3bc61e5c135636da55f61c51a9a58521eabe909d6559dff3b667db82b34a7e5b7ab1f5f7215f540536b1ff781e3c25de1c84a1dc769718b4f1c8eff1278af79b3f26325a7b42a736acad6caebcf0de501f3367902a5de8ef9ee5a25e15eab0f9bc2f3b4f74c77aeeab45ca355555b482cbff83cad89b19454016fdf82828477a32c10f565986e81a35b559db35e6e67abc8fe3bceb84a8ba7fa4cd174f3784e73a669abea99ee5cbf3cc9a0d3e6f29461bacb93acf9ff241b775f1229b98cb5952453b72435feed8e63f3dc5090a84122a529a7b5f7ae0f49d39754aad48cbb1de1e148c6be7d8115ab96376b1ed77132cb75448b6a10151a5b75af54625ff28afba2a2aae2e16efb57e5b65251812191d2bdbc150588113423666fe4971b33a2c5efd8cd88cd3796bb4d4991bbbe7d81be8ca756d85591e9ab1cb73a3b3575cd1cb753b6ff227efe7f1d078ba07deec7ebb6c85911b2ff225a45703cef4644ce3f9a1b91e13f119d0d128922b2f5903e43bcf07b1ba21b3225840a216765980e7d2138dfbdbb67de9eea9c896def4a80edbebe8c795b2fb9a6060631fb28417ebe7ab7f51164070152e7bfe498e36e4086af812491f2f316c8713df2e348bffb4a4971f9f2442bc7d5eeabbb6a291581d451b5fb3e5d7cd1a7a812a29a44e1f85278774fc27367bbeeaa168f855579a252a59650729c9aea863afbff1218bc198aecff6f5051a06c1d9bdbf23836edbef6564e51967da9d3dd4aabb272db79e5f65792b71f6bea8fb212ec87ee47fde7f6f704482ca73f5ecd16eba9ceedc94b59cd7a796a9f9aa4287a4d05b25080849b025aff2594addcc7cdbaeaf0fd75a7ae8cb9743a33ebab7b79936f6b2c059a6cd0eeabc051d9bffedfc9df1258f325c7c1ad2b2e01b2af5b0938f9e1fba2c25d159e67dac33f9e66bd4b9dd0fe4bee54f6e3f6fcba39716c9fdc9afcfc9737a87f17a87913da7f579359995633dba60ebc40ddf4c3479effb26779e515bd57ecfe4c7bf381562af151e6b328afbaebe6c3abd465cca5e3aa25968f032c5af5e3757b95355692b7381699e5a2a202ab02124409cf16e5395fc6c0349b59ef320656559959ef32066edd79b6c77b777b45e1bdbbd12a2041d29e2f6f5f2f24a8931c99051ea0f507d4b307a01e6d7af4f0babb47f5652c06e8dfcc7a97d35cd06ef3d771f066005acebc7bdfde35733703ccfedf00f4cb309d015a390370e4331dcb371e7e3206de78acf9ffcb2d8fb2ac773f1e56fffbe674e67194dbf73c356f879fc7623bd06e3bca72fdf21dba2fc374c2dd8ea91d369bf5ae02fac73fdeada2d9e0697376df0ac2e7508b5aae7b37d815ee196baf2776df1fb79d57fd3a7a950873429ef5ddb38a4311cbe90f0b8a2f631345535e554566b9ea93dd5919e7aa78378a89737cdfaec76ed76362d93e11cb7657993702d6e85fb0f67415ee081812603500a037f10073fecddc06d0cad8c78fd707a803fcbf0072fe376eba09704600afffaf02e0f8ff92e39b0e3fff655815b16c37952a6155a854a9b89b8e35ffafc77480f99b8e056e39fcfc97e6c6bf2ecc9a77f9c6f7d7cd6cab92adca7de05d35f12e071a34d53bac0aa75225c7f0bfe372e852bd99dc721c559b6eb481bf05b02680b22f034003982a79df5db3f67a192ff9ff227fc331e84b1c794af3eb86c3cb98e6dd704489dd701cdd40c3b11dbbe7bddd18be1ebbddd09537ea693baf1aea06c0a02f85e70d00343700c8feefef064054ce765737978d3e637adf6ca0fdbaeeb251f65ff22c5a33464d13efaa0dadffb751ffedfddd6c58a636159875ed3a3399fd97e8bf65d22a99eabe1c0abf67bac92c30b72f8afb1dc3bead7b35e4e4f45603cd580db21a5a5fa38af1b018a0ff7ccfd3fe783934cdf69e3c395f86e96e34d0fcd318feffa939c7260daf5f50777e77349a681cfdede627a7b75b9b2fc374284f79eefaccd4caadcca277e7ee18b6c15fd763b97dcddb6dea85bcdcbed972371b1429caaf18de1d9bd9f2ae98b5409e23b340de8dc2bdb899710326be32331613cbf17047af1837f1cecca97e223c4f0b263c4fdb6d4d5f2ad932bb6e33f2fc97ba03b1e6c2dbc08cb3bbadeebacd189655ae5835eb93194d33fecfd362c94073f9305fae7fbc60c5c990f2bfa3e26444ed9071f4ffb71868284ef5941865cfeff6e98d567c8b21e56f319a621cfddf96f694f59ebe8cc17837ca6da9ecb4b7a59fbd68e7b7252b311eee39e1528d33d7ed45ef5652b2a5bb92972f9d72da54d1b42ae9febfc4dd942a9479efeedd92fcdc92d092cafeff9604e5cbd3f2cc4c76cd9c54910afdbdbb77438a73431a964ec094df7d4342fa2f3bb767d69a57cdb16e473fdc8e2ef8d2a9a9fbc8153d7155554733ceb3eb6c735d555d483ac74d2ebe198101dbe2da6a9253f204a795cbc27a02c5c957d6131bbc192d6024c0736c51e1ee02f597aeea5e75badaef57690a2102c5bc647849f0e65bd1adc8ace7c4dca2a2aa125aafca2d5068bda8a8c090dc8abc1e772baa7a0b2dc74537a23a3722b32f6f44dcc78d68eaff561bd4d3f6c7bbc094f35bad4e69de5bed6cd7d09ad798c6bad56ccfcbf5dec83af6469addc8df973732aacca98ffba858a42d63405f86e96e639d4781e9ee36a2c9dd462fbcd4ccf836eafe361631b74c6cd19c7973daafcf4c773cc713f2aaccadfa840488ed89754f9e10cb121902448b8a0ae5e2f0bfccb8a7bf6ea2d535abae80bf8938bee26e3f4877fee4ff6ffcedd17ca9a3a2ba5f5c5bc24ed6408e4cccdcdaf77a9938b7ef457159fce6d2f2fc97419dd3ccd2d2b40e0ddaf6f2436d0ea1bb435a86068199a73684f6a52143ba2f0d15c282eb423114d2e97cdeaf5a0acffa749e97db60bd857684f14318644ee5a9ed596f76528661f5651834bebcc08e9dea53130fde0cc69ab26f6c429d270e8281c1c360545c090d7a42673c42bfff7f425183fafc97c2337873e578909aff41130c4ae08b3ce505f2acb16f6bbcd11abcf98bb3f2fc42caffff17b5ffd2c9977193576d62f3220a2fcc4a2f745e4c3d09deec458c9c796a414bbc203582221084e3bf74129e287af1b9ad3d4f1ceca24f176dba2083eaea22807ff30a4f0930cf9d5a73a1e6bf4c33ee59f336d9cd5c48792e627c29663b060b5427d0065feaeed63c5dc63e9d2e9057a002bedc02d097e616685ba4d5abde5fdf620856955354149122437a4e78dfd6ab3ee1eed6583d5f20a03aff2520b3ff7fa006843e20ad125b1450fd2f779dff2fff0c4fcded1faf3f362dea6861f65a5c314fad058e5297ef2fa8dbd797f5598359002ad1b2b0e0b45d67a1f559e0f82f7f3c8c451d2cd060a1fbc7a2e987bbe2079418b73d6bdc15e8ff5f31f5bf35ef0a1bce0a39a7d65ea61565e5b667cab342ebbfecf9660c04e2cab199adde56d882b78a365fc5f0ee2ab44a5c15f5717eb0f8d4e7a78c1fad3b7673fd753f47d6296361138e0ab41f59672a86af53938afadff1b667eabbbbeecbb9bd95fb3246517bee3ba6ab0ef63b96356f0a3fff53c829cd7cabee5394899de955ede9dac0dba6987ad33eb14901c897b11467256a93c2cbccb7deada5688a62d09751a0e9ae28ce44e1657927bb193745d1f4ff358aff87e2acf3a0208322eaff77bcfa04a027e4fcffd727ce9ed04fe0e0f8d779faebd5a95f6153ed3adfd37e3951e7df8921aef7b4dc3aa1d5afb08f9f2f2ff7d1c7ecd4daabf254df6cabd9e7f7bffb4ce9dce7dfc7078ddbf8e878363e584d00fa92877dfab4959bb90934656e027de1c61cccd6848eff9cee2660ed7a0c0bbb69f529b675d0dc9a779f985b62dc828971dbefd6bc7c7f4173eb8989735d8f619409ab6702c7e7740f20bb47ceff9e3d43297f5a9edbd374d32b7bf4f429c3747adaa4b9321daab7a9672ad72fd77324ece1aef3127e9690f35aa34b9c9561badce5f6c7db29ba44055f86e9fab6684ff505e29e13daf33eb93cdc75ce5d5eb663a6adcaa1c074973b6df0e6bbaf999ee78977fb7ae5c4ce7467ea7c735963dfdd7d9f969ba7e6397eda6be2549fe7e5199bf69e5bf3729d6fdc33b145cd7c3bbe12e396eb6e8dc57798874fa145b1b2c6396edee0cd79a6ca3cb64fc2cfff97499c7da9db5a57817a5b5b1252fe93684242b8aba7c521e1c5e9b4a6896b4242ca97483421b1c39307cde321d3553c4dfe1f4f8f3b794af30a7755a7abbaf7bb71cfb7f28e77c6dd4173e787ef58e95f5077e7e8083fa579041a501f718496115a1861e6cbb8eb2ab73f0cbc298752ad111c1b11f5ff570c9f770c9f76aad076def1d84eb99d333b28971d3b75df5e67d0d7a9f3ff5fa7ecff4bccd39cdb9aebe87ed4d915d1a7de5dbf9c1791411144e8f4e1641618bcbd9bf58fde79f98facf3be26ceb5cce7ce66287466f89ab518cfeeced36209b7cd779777bacb8179995b54546026a6635586e9e8d42fc374440c7a22f21081e6892023c28b88a6bbe70cfadc1c39ff73e60cbf0cd3cdf19ad334e7e883f6d787c833049aff21c8c6f06973e8bd624378fde78688faf152dd87502ac37439bb3b5996dd9dec56d527243cb22c9e3130c7f154ca4f0bc4bc6be62b81debd1cc7a7de0185fc026dd6ba199f792bdfd3dca2a25a72778ae6eed641a0297b57cc02332e082f6f0bc2ebcb27e1690621444e9a1c395fdad4877740cbb119bc79a7a81c1daa36a834efeb26b220051942ccc0c80000000000a3120020302c1a10c98452b932cdd60414000666aa5c9a509f0893244b6114448256190233000000000000001000cfac9db35cf110d768d4a827dd93fb8019f68198fcd9a9304fecb53cd5288bf79d70be24febac10a2a7525e7fa1e19c7f7b3a2b29827e0041309795b7a3599b9c2616049fce02bf6333962c6f907e4e5b8bc567c57d30ac943eaf83e4fc8079108e1ba612fdf642639ed3eacf49c122b03584857abc04fb613f28b6bfe9daa0b0202c142f91d003b545252ae4ed94fbe9f1269767a1ea9da2a83527783b5587aedd3ccc34fe456c37691901f6b32d904a926de6760c35c3c03a29663fe8f5190e89928ceaed7f35ab953210ad871874fb03a47fa2e951a49f4be7d67f505c03742eedac0e4db1fa76944a83bd1549640b26cd620f65fdb33cc862d214b6e9e2cd48e8b42ec7f06113e41d7c2fad7ef1267155aca815dc23b374b09f3cf25af62cfec597665fc71be4ac7430cc129c2899ffc2c35fc29f835dc7a6b6c7134dd0c28653db05d6ee2646d84744e46bcc6de34d6c4081eed1ce2284788d56758975954cc216ded58266fbb6f92bf14f0d39a0382ab61e480f5ce6035a4897466b2df9e883432e358f402dcbcff50036d14c770cd91abae82675f1b3a2a6c266d3e20c4d587074e704f48b864e28f2003ff7f65d9d1b3e2c6f20b113356633060fb088d726a6579f27e1c51c3fb1f04d60d6985ebcfe54e4ed1b2113092c629bcc687d0d36f7bb71198c2fabb354a935f6a37863fb895099edcf01462ba93e038984aaeefc69b69150a8266b9d01ecbeca4fdbf4153118f7ddf01477010fa251ebec6d6ea3b0ab5c8e60a1dcc945d78e1f1c5c2ac66736215d74e7690f77d51d30a20d4040e5ad0d4b7f8aa60b4c93f9e98fd6967ff1d3769f558e1c971caee9d163d8b305a174218ad9d205bffd4a98c0c8eb76d6d91e1fd12dab055aa82c6a62c87c40ca4448cfbb61d271651b4b9cf30880b64357c5998194c790d3ff97ba7780b1a65105b197888f58327d45fed7f4d29fbccf48f7669cff5348691100239d71b8578d0cbf6bc39982043bd0d6b7241d0fbf1ce3d67011ba04af231215f86c404adea166d45b68ffbc00deb2ac6aea9f4bd087561c3dff050ae0e86dc2e9ee88fc1b3c984b5601ee35dfa81734c2bef8cd66bf1eae7e672bc1fe0b427888a17843a39979df7871776d829c64cba8ec9680c06ba0829a8988b82484c7144dd270084d2a083cf4282de9988a6a7cb01e281fdc223a9e8ef013d86b32d4568d357d050f534b4c074c8ba9ffe8a4d334f1b90a66729d133100e02b012f4c1adb9839908baf8b07876d1378debecfbc8b896d41e51a2c0b1093e02a1cf805dcc8bd02a3e242d63b02d2b38227ddc172b0ae94d9ec2e05ff89ae6db3c9163e60e7baad85ea25a9eba6a9e9feba6de0cad24b65d7a7a95dedb3033c1a37322f25918564cc4a273d6de47160152814824f0e1e1d414e2da69d99e5ec34d40da7cc46df5466982acbfd1e098f311437ef81b5b113b99f7fa58d3b98276eda6c90ef5510379ffd73d18611cabe01e28dfa7d08f2173f3a9cf098c2cc5a838d4dedff4ccf3d47601793cfcccb38aaa49d89543800b447df549a343c14d89f4fd43d7d3302f4bd8a49f3d7bdfb8d85a801f964814038fcb6d035ee0ff416a6e81c6aca0fad5b7dd6b2465f1701ed892cfcdd031bbd7ca4891fc138b61aa61f3600aa728c83aa04e0c835595e5f2ec2040f054f14e121373556023a75a860d4c1959834b89e8f55fc2f508ec48161f4b3fbeadd18d5ac4a47ce1aaf3e62a18897cead919467daca0992723e2da496fb982ace2336f76112af4d485fd63ddbcea698c728668a282ecb588d08d7fc7210947818046ee51b042e9fae6b5d152ac6f52756fb7624cbd2bc31706b06153245670bd35fb1a1fb9a620b87a014d93bb34d00bebd46812ebf8235f815b5c8fa2b50b659d101ec8f6fe43424935388e70c7866315f173bbbb176ee1259b84470819ea27e06ed43852dae4fc8933496dc316bcb1628e8866796491d413e7446f8feef214847b3327f693b302796ac08dabc8633f1082c18abb1c31ed2fd5b3309681dcc141b8926a5bb06f5f65436c0c9b53507296fc8fec8c2067ce018a48200c7474944d3fd3f496a9f8338c977ef6ba5cacc24e84839db8c36c7c04a75f7ab4e5544451f873b48752f46a685a60c97428129e51ce960fcdffddf0c459b87b1e028c1ec878b1839ab86fa4465385156b4395c38d9f1d423420dd640d574ec074f0b07c782736b3e333a3698797ccca6c61206411929eec8bfd55557519d7fe2de317ff5aafd0cded62a94b2205856acaf64da0b6fc9e60b0d475531453ec392b3898b3419085797c0cc65dd8ae8091bb2ddefdd8f25f13dda0091e76e79541977fd3928059a83981b4c096b1a01620cac4753520d0008358fe44d5a1fa10e830fd9388e03a64c2edb2b6c2c02cd166e28166f94acb0aabf4edac637f7968e1ea6437e27341e38295e98bf80d4a8fda79a8226799f655aa641041eac47014fe70a9b48314fa9068453ecfabe614e02270fa1b9b414c965d40781c15a4c54f11ef7f0d4f6c5cacf8af4b5b41be972df7358a5710546dbbd246ebf4404d8a956ef9b69448b10a5392229e5b8469222133f9762dec76b955fcee7a552cb26ced1cefc249a19d90cf1a60dd797a0c3a521954aad534dbb5ffd68177bb9cd9e1cfbe1da6192424522b6719a689d95a5814b4530d54abada12280e1bdf54d2d15b81d36f0523ee66d82b03052e6f3b59b8546530d61418329b22124a57d51eb17b12eabdcc3e1fcc2291e27228d04558855e6f3efc14b83cb86446940222f6d8503f03fe58e2c74706eb7c55c31b1b8573365fa812bd7eb3ace5d3b6263034b68d154bef6c46bb22b4e639dd7457cd48e9cb6408340d82b6a3032739603aaa0bb5d142d936e9b1741d2661ec4c4c55a60bb8bb3d8936692285cd3f88832cb9175e13b19400d1e298e1f9644413fd09e89735eae1e756c3f2623edf5bc4a6dffecf05a23bb8049ce96148759b347a142264e070e2eae4a5aaf1b849c3d5324274e6acaca1dee0ad2cdc934edb08505d2e30525ab345c2289f256237b430a01f79835061d83ebf0de5b9830a1a21072f59b2494ca3730c704334d39ae072e4cc869febd179ffeb752c898149d352d348203bb2f128d9440103af18a169e2c2ce7d1bc90c2c977367fbd6df1b0fe0277cde4359c4e3813275369455f9817615ade6d8fdd0de59a4034c0415b8c96f74c6043dea13be58c4c7d6918ee44830f85752a9b135209462bfdffc7a3158631d8d750688452d3da544bafa45a691e99ca1f0a6090466aad4a3da78095c9d20e20a04273f10ffbd28b9a473ece3832461f7b89cfcecb7d1a2b6d721f7f897af75e8feb974c61e604c024da1cc909f8123859a6bb50ad0d8d68c320353030911bde39a39d29b8db6e4d7f04006912729c6956f3a5c4d06cfed1af0e2a78e3104ea39f08ee6ba2e60114a2adba156a8baf8eb69a385a73e2817199276cc1071168db80397204a471f71f9c31e60b62e10329be9ce9ba251d223eb353941b61116d83c3c52afd83e30135bf8bc9e14d1c336ec832f5bc7e07452bf731d48b54b55310fcc2f41d525da03074ce4fedc5eec037e7f0c408ed781da28d594f2f2044e8a80433328527cea3151be2670370605639b338fa506079a5214907c73c203688c6bc29fdcadbb4c402b061e8da93abad8dc194b24b65f7680d9d818b73d8cdf6986ab89b9e31e98157ea5b99e58e06acb0511d38c6865f48d2089d5aae48ea2562182f8a3f871800d96d42d44862f260905c11e9aa31ebc7f5d65df3b797cbdca17ad79d1e719c538861ddea4160975d23d5031244864e2f996264c44b5543a2fbd4f47a63a1f15c18dc0167a2d9a6b66d1b2b955aafee854c2e83da8ea5e0db0f0338dee5343b1bd53c208844c8b062668ff6b4663abdd3179c8dce9e07d2437874843fd6405ca6acd25a73f4214aa6531a661365dae75fb0c64f43505e387b22d49adf01b47a8fcf711ac0edfb250b602d2b00e5f3f2ddea6c89cea5785fcb19056bd744c3d236d86529278a5926c8bd54ec8b885e472b054fae9d205922fe2515ba9e9b605d3ba18552e141e91c1493d3f68750b0b6d6b9adde16fbed3b096861ac97e2041b1a6ebfe295176f378cb0ccec963d1918cfba2ea83a7a38364736a2f00816ca31ab0654c44e9839e9859fb731c1448dae7f80215f07215d29fd75b27bb5f49d1385868099cfb4fb2ffbe3277e367d63909c0032fb5570439023c9490e234a418233f6498076f911f8c32a85de9acb6ca3e7cc12161455d6db514dc23aa0bee7ff829db4d50cf89ae701c8c028eb3deab2b832d520c61406eb14b890b68584cd2512cb92f988b3ae45334b9c198aab6ba0f77c41013ad2adc7dacd582ae9e039439beb75254780f2745674667bccdb286fa5c5ddd1dbc0e22ba7e695c9e1f7312d7dbeed2555a6b7e054a5470aef9c99509c0df1c4c141b82196d53b31ca6e6823b02dd405e56ef9372b204daaff2b2b182be04a07bf76175605aa0e6197043194b5fece29b37739f54a95427e49ba5f089612543a05ce0d5d17bd372ea08a352f2d98b713e37d5bbd73a50d9dea52fea1aaf96ddaf9431c21bb0290846c66acd1928e18a5dce583260d84b8ef361970d8c2bc1b7881d2bb9e575fd0737fe60302a9680eaecc2740f3e415484a63533a4c6fb1fa54b4f001976859ee0ab4eb08bb6914c5cd4c7eb2a26efab3d8e1b9cf6df2522c9da340c6b8b513272d821bdc390e79edbcdb59da8445ea14bd879b6fc08f6004969a99e025b31b177df3689391135e034eae42d7d22f823faaa94b7d88446a467e7ba169999445b81af13945ba718fe641d756247eccc43672714f60db1c635c22e8d5b39ea0b211b21da33b0ccf198ac400e644917d9f30680732a22af3f126fe93f5e3b77de5b84878c06c0ec42d98aa2cf725e2fa7fa363f32896ac5222d92d1e577d6bf9ee71c82c2a662cd918fb621e3770c198f54080cb335779b933eda12330da77a11321fb3d1fd3e31c8c782be1e8b376af57a90087cc05e070984f08b8ffc6004c153804ced557566f1e96a77f9e8e7772f9f94e6d5fe033d30d057b1cc2a0f366d85d5ed5de792f71cd50382a844497575e2338278b2f9c523a9a95f67e2ca598ad569d25107952c4807d9398fa87981f5eb1b8112a569483ddefa39c4a3b3b43169443eb0e8d324869e96ab8b5e466f0caaeb0d2fca020768c9d130f040facf1026024870dceeee4098d1b1272e1a39356d831d6d337a42f0bf5b1cbb7ace29c5f2ee459b41ffdd538133cdbb51441336938fb2b6e0845ac4af89e5f1ee8d5da75c4d4945b23d48608610bf2b88417815f856c69ee81d89ee276c0ebfc41f6afc97e4c2eaca73015d6ae850dae4cfa6c44804372e66edb7f0eb3f28bbe8fd1c9de506e586c84f902dc1a660adb564a9fee70ffb3d083d666819e2a5d58504dc86982fde0abca1a6eb59d24d8e84c5245b8d9b512616d354117170b9a0deb908364c106ae8ba0a9181979b4e2ca61928163ebe776fed984dbeb8ce4c3b3b496abc974d3e9f89149619f51182a8c65d2b81a8ed267dc44a143c1ae52209a252653a736a4b0f21ccb89d7b0a717b7571845967bd9cfcc0edf54699b11b0a7e49f52580c3448c98132f370e8f370a8e6e5bb852cce4418c9e5da493456f6064618bff7fb27cb188a19f0d661386f966da50202bc0eb904866d4284c499337c0ce4f707ffe9aa225cba8722862e2ade09ddfaf3ba12b0192c1541f809dc5de0eb4751935f6d39c26ccc2478662318cd6bc706c1dd39b3e2ea97382920c35cfba049a3f21fb33ded5e402d150b3ee8800c61995d57e59cc173ede63acc354d135c99dc420372101a306d5932f6573250f956439a6241bb0181ef0077d6916d11f2b1a2c6461b1a0da652fb0947d9a2df2e4bfeb1a19076c01fc1d4c97a29828c313bb84c7d74bdba2dbb45457351a94371e7aa8739151d5b7d6dac3c4906932e4fe71c5a3e5336fed5eeb3ead5961538574225f443a1ddc6f28479b30ad7c22dc627debfdaeb87c13806153872f763a5c4906a5a4746d08f82dfa1fff34b11bbd86fbe2df44453f7a2f1e681cbca52acd1032f1d6b095f2c7bce03605bef9c8d61261936d313f6ac475d905867b69c72315479a850d136c7ab483e42ce954d5c855f14f30801bd7857539bb1714e34c6c214bac0b7375979728af1018f21b9c9228b784178b44b5a0e56478867be946cf20fb66ed35a9e4c0529c722128a43974b970fac9f39c67a23a63f61cb1e40901cc88fad1ca7926782244d8fcf48f40da4a66add6ddc829ec65484e149429b9982cadbf1527405d4599db0963f11665dda8773b9ee4f2d75139f7f5bdfeb78b6403bb27fff9a5e66812050c7074d6987cef3d743f8f6322be8724af9fe085caad360e4183860d6172ff7479775c8335c60167bc10cec506f11b8a701a690ccf6d2d75d83d71d60c41781e7058c0d792b2af6480dc2e77a2e1f3e477f72efc45d2d884bd762eca3af40b22267270c4e86185ae2d58a344f51d99bbd4113fd6ceba1b6f551a6e0d8e508a2bffbd2184513f7c4c09a3e67d1d60b5eebc91677630f2c959336b26376f26ce0c2dd774f11c2b8b76ba83550499e650f8e084b7e78efc87bd1205bc62cfec082b6dc2b58e3c3afd0e0a663be0b736516c00b8f677b67061eaf2fc7cff3007af25a9261326d27aa9f3d4b66459e9298031b83bde25791d41311886312f8155bc93deafcaea6e7ba7442db57ec04ab629fb60bc847188298f70550ce417c56f1e4687c1312f30766559d436a12093f4013c8f9133d8ae1305920b223cc95649813d62a05f3a22190276a96ede8e7320344dd66f20c4b2318830a62000eebfd7ea74d1c0a3357c9c987363822aaa07ffb03e771c494c3eacc6cde2c88981985a395af0f374266f4afbe5fb6d14e73dcba77cda208431a0ab0cda4e831ce2d2d9ba4feb7f5576a71542c90168fd379e091e22bb05671a2144c7b0eb7fa03621705a25b9e90f4576a8fe9801d53af17bccf405a853515285787abcd7da33a3d0a64d14419c80fbe9a3fc92bde8724268122c220fc17f05534c36602e15c36b454bfd020b531ff8651f3d3b0d91c2ff1e88690ed0befc0b0dcbc74a39d06810aaff8ab3df8e74144f923fde7981e99d1568ab145d890c088d9bfc38ddf50bcfb69bf270728757868a7b63587e96682519a0ca9bfd379f9bcb780e68f88657230d2248d93ef09f52695a71c376396da4bfca7cda8a01d2397decde907c56cf1f53602f3264f99e79386fde5c5d533eaa2b44f5bcdb66b2b9d1c6c5758fd3807e97329eff95fab54d6e6ca24d66d1d2c98af25cf1b651e7d7e19b5dcc827d1a3d5e5a4e84a6a3c4da3843703c56b5c25d0b80d619885b71e5261269fae1374f0f141c83b63e06c7c9c88bfdb606b66d68b458168d45792c90c42115f15db5f7bc594b60497af90db55f7960f172c19a9a64ead2786895f9d5acca87a5297b66e26745180669705b27ca0b99f3f9aefe35952e86cab1f75f163cdd10927866d6c95730ce67b852b9339749f19314a644fd3e682797c826649457ad8e2fe9f3382984a4673ef4714be891357bb3de0637ffba9d07743c0c56e58acbf01d2618a1c7c7176d0b8a1283a14d59e77cea2df59b28e029f765367cea17d9d5077c4271693e2741305ed39ccaf7deefb360cd3ea9e41db9a0c0256fb6502943b89575093aa4003421428ebafbca2a56be8592f755d4b14d7d34400d081e6f5c02308e5f8a3f9950633c390fbec944fd8820fc3aefbcc8ab58aa9773433466c80425941ede7b068679fa324bc96af7bae0bb555eb92dd6b1d2ce9d348ec152e703d20b386741f8f7b443870d84a4c0c43fc04957f6a91bc8c89e45093b158ed38912cd9b503b3c3aa4e1617e6f59e3b25848201e38c33d053f7e92c87750966ae5d62d2c8f95ed00334b2e584de9bf453d38a45daee6caac4664dee6f8545775d3fe92c2c456453fbd8b7455be24f1dbfbdbdabad328e705afcc4adc2c518cca7ab11b225a02d873ef35013675e93db46737ed009387c2c10e2c7e250d4ab1a878db601bfdc934a1d23acbf10ef9c4654d367b2f22be88ec45ea8c59553389b45359503c0a9f758215712d537761e138dad61bf7d8f7d3a8278e682a7f34be50b4f84019c8b2475867f9285683ac65b586cbe93b12f65f61c8550266c614910d71a16777e082bbe9b48bd4f482232eb90542fb03e5a407471c4b1ee6d2f3497f09e992054b7c48f747c97468cd582b04b8e76867c4e3b4f5465b887c6c897ce71bb1e616e89a20486e6d9b9a0a5d407ad0cc63808a40024b0a20adbc3836b24fcf59e3363da0eb16fab47d0aba95f629bcfb754bb0cb513dcad73990a87226d46a04b4d4d7ec377e016ed6137eea1b22679ed8ab4053f5cb2aaac3678802f98c366e80c41f4592435da288ed5b50db5bd5a3a36d421b7dce56da15651e422beab7d9a30f01e859836ac8b21dd8f6e53a6bb86386ef622f37a3620a2452875e8ef14823f1b78d46f69bac4a4ca0838ba53064807f6802ff28a2eaecad02c91446eabf427a6c2bca19a2d006ed59e481aae610a26f58b0a6b8b06e4d305f5b29029cde2015ad572c668e964c504e43c4028bf428ddcc76e6a97c659536e587f6c8664b2c9da03738c9a16e6da2db860c8c7559908fbe8030feedff6d2a58985bd53c4c8bc8fe49b80ca969d4c74f0c26ac362da34ca5b81262664e6b3865940e9bde7f740988816c6a7b9b989ecb80c27fce7729cb8cc0081a3cfe44320bba2e4a4827870212f4b4872563fe8afb25a3e451d473abb8f4253c2a361ead3ca40c7dea43df3a659c521476f96153b110d3eb2bef94f57c4c5e8c8397af30c70435dfa193664ba70c3cc020904fb9f3d74249dcfd637d5ae1e5526f25f0995ee6fdd1bd9a43e9a251058b6917a44926b3215ac18ed21d822ac09089367116de31919fe044bd7e85ed69f140b2a3900adb508cb98b1286ebecf42ee0436d6964e0af1b5869c307855e6927f5fbd5fae492c5a37cc76d15af8542f685d08839f501bcd32b771c7e14c0cfe73c843afa92b6dcd34576a1dfa1b89b7bffb3a14c206a112a186f21f7bf5b3d878d69b0183cc73ac646f6bce47db9d8ccd3a107f7821bdddf8061adf08a0e9c1fe086a406d81502e81a933b42aeb7cb1d26cb8511da5ec65ce75d7a2aa7f385b7be46f9576c653effc9a9c6182de6d52a98a332ba198cf83ab2bf735e3e0278b720a8411868647f6485da6bd4b8e3d999f4620fb616048250ab2e17394063b0e032b61ba69f8fbf5350528d7293260a0ea8b24d30150026d49c95d62c323b1a0953cbfab846bde9ca088885c8c6024eb2eee9d9fa7ecbb1a1b028cc9f03f478221121cda3858c992ddb7c6507f7e9e419f6bfc13454316ad833d2be16d284975d411e359860403e5c935589661f969fb26021eb8c3db68ddd54f1e767b3ceb5bf2a8db73bde0baf58ce5629f45e33bec22521e3b3f416255d69b3e80c9b3967719e25156d2626e4590c7c0063494c1391f3a1ff31e03a241553a33d1c5f0bc99ed76bb4b943c96665481e5e691cb5177379e168d9958d810ca33a4a7c53fdb698577e7b0befb50814ce62c4d0b6c9f69ec12b3219bde32822d3e2112c17f7302ba03b6af212788608aba176c742eece58a542ce85bf93d3c4a1b63e94c877527426135cce49187cacaae53dd0d053fd677915e0fb97ea9be8145f5976edb39069d02b2dbec49a99299369df5bb776deab539a4195696f116cea198e9c2742be2a6e1050fc8e196d7f7d1bb33109f5e0e082bda21bc0c248469f90c99fecdba7d7c8e2ba6d99a5d33729eb84277258cf3656c2800c531c42e3bc81a5314c441c6b3992f9a499222739e16792d87db7c6f500cd9b33bb2d959cce3c267bb9a791274ae82ad6f0de21bf78f8a7aa42b77d09895eb1a3905e40476cd459a735c187f05597743cb6e69e41c2a0d69af03f2811c704a3db8240f448750cc0640e0450903820d7da40a9cd1a1a8531be86141787f72e26e225155de7fa8374c80c77ce4cfb3a4bbd57ea54adeb7915ad6523b691a2abfc78a0cb7a76820e8a878a3a85a9de559e7e72c4e2413f1b2c433467284dd9be8acaa1ac714d4c6c58b4369df039e0bdb299a3442f93662b0d6d0fa0c0dcf0cbb1a72050c8153b303805f43001e47e442934ba41a5bf6bd47b1645c597593c5b317cee1959759ae33e615415243bb0a2ec6b317c14e9d1fe64fb47034a10e15b9919e45cd0ff1468ad3afb52cef17da993081163a936510a8845e303295caa89d3aeb9e0491b6effeb739dd409649ae42c6fcb330f267dc8c75e099b9df9cf0416c8975294ae661880dd2d72be00769300a2dfc1d4bada5a640f4726cc3c86edcf64eb315c7e6a1eec398440635e31d20c2c5b3a9cd92a8ed118ef79912828b60c02c105d693e060668f6267add4c1b2f879f8a9dfd24a96ad6c10b94514bc7b2b585a46f6ade16bb26f8e09b992d4fa28d8f136a43f3b978f84c014527e0ee4458d9314a29217e853fae4077123a999895622acded9183cc16efb5f3c6e6629d393dc26750baebc951ae9ecd7e95fe5ee658e52c16ba8b545b69d0503b0b0789a4bb64840f0fb1bdf1732c41fd343370d3e20ba689c2e501221a0db56d21d25d7d2c7e514b24cec474f76a05ca13a8da472cc7de673fb002e6fab454977956bce3fe24809f036cc949860fa4d8226ed19272d211c782432c53e072d21632d04e1b4c5fa9ff8cc51bf9d7ad1583311b519025db4108eb98ee0eb52c6d87231bf1f3eec9438df6936df49556f961d60aaa2452f9f832ebd03e4efe25de85adac2d2cc64d2ff4636214fdeb797cef33347b53f805e2e3a8f083006d3ac3640a4712cec909db1014bf34c89d22e07bcb5de42125f3f35aa5249b8b29a019770f3e179b6dd0ea991254515023d80135e4a5e02ca725a34b75d0276fc549aaab091665420a89e491b319c84a52c7108967d17325e8aa7b2c3bbcbfd5cd9003aaf45e141b574fc6f65384667058386847a443cc6a24fc9cd5baeb4b19a9507b78d8dd789caa2f8625d57a99b0fd07778aee33f92561ab1254b681793c87b16f4b707c4e5ad44fe1a783d9087e39bd3510b96ace37d8737fcdc303428b167b1b569ca87c40f3c4ce133ca50d913221f4830360e69ccbab03e9d0ba10b1d5d17e47843538757cd28c657a14a422d22cd5a56b8216dca8ae6635c813eb95b9c519772058e6ceea5a0afb61af68fa3231fe35cf36b6a495049849943a9400087e0678597b084056b8ddd08452e3ee6e3b9696a4ab46c9e9b8263da90466d975b8ceaf11ec9e5024d428fe73b0db420d296ce1d79de74cb8674b6c3e0fedc2f18ea650333f96cfd9968b7c5f5f3f2137164caa7e52232fe6629df450e0850c668cd2d6a6e7049813f4d5724d92f3bb3dd6e65c90273954baec227a7d4cdbb4ce72cb64f73a6a3f957a1c071bda8df8da3868a592dcf94b79d662e3bb028d8b4593423e71cc7d0fbbeef9d1358fcb9b2fb86b81e6847ea0b9630af821f8fb8f5027d922ca94523f4496c9637fd3d140617e930152dc6bd1a901325741c2adc768a80d00f9a53611f5ae5045263339c85dd61e372722f186495b86f6cb8662f16296554ca844b55a172a1896e8ca5e69cf39c71d0d837b455f2ec5100e4f5db88d142b689684b6a0e7dfa0bb90b53c09506f543d98e77cc94d461fb2044363865e354a22ff7538417f9efb35ede941dab54083c98d20c27bae850456bb35bf7ab16cfb1ffae2db0b87ef47393811f60dfaef8316b65d50af0290ae73ecab377a73d7fa154d7709e4d47426d57b04c0828eabc412086ffb83ae7c57e4c9f5c6438e8751d7cc9a69317b6fffe416ff203c4bde267512d90e405a364b811a77b4ab6ec01dcefd5c29e2d8b65d228ad2dfd9ed21bcc4ca4411a9b108fc2794591f5ec9cad80b4b382bbd601e49ee089fa6b8a31217e2c5ea26328a19050fbac11b39c0417fbb7bcacd8b536563dd50382669f230cdcd88dd0278687add815b539521b6f54c4d3b0245d666dc2bdd6e9699b3b133de8cd507a6e058214b2d4f0285160849ef93eef1d56ab439e145b412ff76667377a06f3978e3982fbd635e08fe3c76f6d3350fe2d44b85bc215d57f7f1f6a562b20dacae165a4934a9b5914bde9d23696557843b6df9a7e40cf7205fb5995bdb97b8a61357b5fd5e216bfa99a7ed123e704b055237fb43bf1763ef98e8e54b4be066428f225b4afbb74105a8beeb6d303225c6e2ca572cd47bfc6db1d1a6881aa53439c0da753a785753a0b8f08ce5d627046fa60685cb464a3716168d9a969f70939b83d92474acb4595fd9d89f7636e9a3e00eef2c487afeb5daa2147e71f4281a10955984b1bd53b2ea6df5ba0a5cc4804413fc25c59916aab62383994bcbe90787e7294549e3eb1cb96abffbd7294a157ea51f698350d71f85990b66c74da6a4e3efa03687190e5fe32b3c2f2c711be34ec029a665f3f60243b5d4b40470ef51c41379295e33cf34e200e3feb1dcec6802da5e361ebef29e92edf69790262eccc56604232a062ea61cbff82d789545358e7003f007eea4bf5b06f42d0deccf9d2f25e42c6faae278d3854953fd0563a402e598d8c13390668e838061f06330c492b0bb80d18431d210478a90beb402549cf2e93e768b04d1066a5d2298c361be21500bbd11e5c38677f01a0a9a6a2fbaa2213bad8a91f15d4769cb80980dac6a39fb9ac2e690112a0de87000e5334758adf0ed31fb9857faa419f2bf68e96d165038976dea1ffcf9ff381bea461c598d84be7681d0ae3b7ef6b60ef35ae1201f59326a7878e9d9ed0eaec1c3d64b9eac29493e37fefd1a0145be9b4ac61e76aec34680a1d905514abf9bc428091b7434c52897ca535604662a99495616871353d6906a7c90d976ac2ab6f36b6ef82a5bfc91a52ddc9cdc38a998a49cc68c3147ddbfc742d1d93667487df7e14bef968f3e090286971cfb3118fb8a2a13746a57f609ad5b4cd734109115fa6b5dec5f8111835e55b20251c96195099f71db24c0eea3e2e21438b29d458b88fc8cc22ccb64f5a3f9542183b7d651b6dab93a2f2bac92493686d41467460817588c37485fa799b30e108f44560c07f026be99cdb4c07319d2b5d3ceade68cd94b1ced683525386208f328571647b9d7844b5bb6fb3311a6dded1ecca22d330069eb305d29bc2cc0718efbadde24747fa24392ab3d5b1e63412f50e1924d48a54bd3cde4c26817d3e42bca865e7181078413c74df382ef2be948f1968255438479592e86a6e1740fe64b3dc79fd6b047580e81cb15d46bcca0fb0572cc80a51cb85c6f3a1da76695dbe17e154003481b271d719cb78f4927acb0380ee642777fe6a4b8241f3f909702b21f62c106f95790dc4e93d3a8ce0c614eeeb23f9ce90f5c752c8f96a2800b0fc3111625ab76d5e10dd02c2079c5dbfdbcad8274fe46741781658d175de29ddbed94784eaee410dafd6e59e410bd4113d684063d535c6a0e5be6a78a8a8f6c7737ec714a836a72cde8181314d90700edd52978bbb1ef8a5e76c89555a28b9ade3b65ef845f524ee82c543b0e5f09bc6ead954803ad5270c05f499f5f561757241e9ac630aa9782c48461d45911c1cfbc3cbf67dfc70fc686944d38a7dfeabe206380683a0a4364dc581c38434c4e7f6044d58c631993aa12de50eaff05230916855c2a753f615ddc3647f4c36eee6b3dcb796ee27fe17cbd0b9d2986c7b466c2a1ee15bcaa515a3d2e053bf6f213417359bce9c13f76dfad1cea35ab0fc8fe72e80d15ce9e47200f0f82ed12b86e3937acbc82d57b1bdf6a9ec11a2b6b2539ae571ff7495a8020641d18cac04328a04cddd6f014bac4ceff9aed9232b0167384bb8eb00417524fc1cb2d6a64126b959d0ee5863fe6ccad7c1ecab70ead611eb9d25c46500d40d778074e5c8f3d422bac228e91e8b9017adb5f33314c1e766019a62d73fec290779561fe8c5dcf2a364a28f7a0f1c0ec21e8309a3d928db1cb85164adfcc8d6d77ec4dcb52d168c66744ce14e3a54809d0fb249a6a68cf5221db851e9cf44a84fe9b9387dc3c55fa487a17a86549a6d90b8c2127dc5c26bac58bf617c3e2247faf69b6da9808cdf2251b3fe33732323701aada568da352a1064a1f0de629ee0f6ec34effbab5e6b9e142d47390f461934f370d3a1b42c823916fbad0a418286fa6e0aeb85f8f0f9a6ce7aa13fef92fee7ebbedc1f70c7ff2ada999da959c2959495fe1211f91b8fb872f2ec4c57e99ec34daefe9092f3869b49244a601e82b6a5aab648aa7585da6d93a6dedc5a757a1787d681266093b67de978dd19cb9adad513554c73be100ac0fc1268740e07b7d51ae9be26b52fe63925d22e63ef55f1050b078359562f57c1346b23e33793ad8651b20b423805ae9c2777a1fc49f1df115bd8835929c28377d1205e37698c713ed8b9490e5071a2ec55fa2bee8d9e75ad46fcc3b6d26fa5f443374474ada4f308ad4e4a7f7769a4c9fac0c1b9322f5363c7cff0a48b4d9ca49b6f1a31d8e8d4b1c66b515ea9ddf617538ec2f46d3f11bcc26029c49903e5289abab9d7437d49cfcc4a11f5bcf7232f6b3d413f12ad8f4a53bd0011d22983339ee30244a040a0b2c1f7717f1f21a76e9495cef6f1acc3b13583e3f3461f5c704e4dd5ca0c8d0e0d0a906535f18a9d8042cf9f3cfa39c3ef2e9ec1cfe5c707201c1667c78ac5df1d864d8d5ec39966c296e69c5850d329fad8f10ce39008915927e6ba223910fedfc747427a785b69ff52903a5e8efe997b12980bb8e092e48418ea4319d1f7eafd0b911a4221177728dc103a908afc3cc5eda2e5b2257c20b2ed42d626b0bec67318aa807bf7e83fed6ebff03184497d0ad7df0fe9f0856148d99252c524261dfa3baab54e74df4798f0020c0847e5fc0eb77e77a1a2e4b109412c8e0227833c569e35037dabbd26d5551673484c9c4fc5a1102bad2f5f12fbeb730cccf9fe50c3080c8acdee1f9ec26762c0e0023b0d48dcca8e98b860d39f41f2290ba1b202879f04e66942243d3b890299c023b7a76f315c94d669edc2d442095f648efff6c007792c3fe6ad0a2150fb1d85fd7188ebca6540f78b3bc7218026822c22de1039df01321f24670b0fd6cb50ea6cd68d21bb2a611b78cd6ba8e11806a7512b0b3822c9106bcb291e3b49828809dc873cc8796ec6829a4c51c26c35c33fc97f908960e10ee4eddcefbb5599d4eb2d72de4ca04380bde8e52f91772886b403151c7555e2ea05cd11215800d367e8707e754d612250ae2209b928e7623c21e5e483d660fdeb4452c5027245e6d46ff04a31aa68f4b47145f0bdff5412b4258ab01e45ff3ce276580ed7e79e58f64c9e56203f6e9e9f990d760e010b239772212d445d4c4c6637f943bfc4377dccb167796fb2f85b9de28182f20201d6415d369d240688388e30f27e0cccf2ba03757191e4a9e9c6d6cd40722cddc4185d6cad49e8d96dd79fdfa58ad917ce3e97f919030a19eb58384193bf405e09f916dae7447d573b07970b174069b79a0d8919b5e39c59567b69957f1d4952273ec5a2ed20a741dd279f39d8413444c9a04dd743a0973e38a29be38e06603e2ee4c97ea2323b4a09f393fb450c7ddd38274a7797e2bef23144fea2865723c3ad0a7c5ef844653f6f4d8b961a4a1c5f6541a9ed03f39738c9df0f66aa983cf6ce595f214213ddd63c61b6b57a939dfde4eb5c94e554474238d0569fcb994721f235a971a7bc164826bf288fb1ffc47d5f391fe1406cef2ee6d6a50d9a37040ef8074ba3c6adcd0c160eac2a73b9fd10376b898937695b871828c2584768b944a0c924b9866a57ee88395a478a201e3f3bf9c06261819fa74a096a97348e2be45c961e0be3b0f633aa98bd724551c8fce7f0fde3c667c8880905969929f44e82b4209758ed9bbb354e9e6a7f21d1d49dee5427530d645c07cf0d75fe15ed53dba78f9c88498e5a11338aded6a0cd97d0b7de81245b98a597a0f5745b279b17584c171f3aefb4d764d8b2b54d2779cf61731db9cbf8c6dcb9d858b7634d3afb237f54b7c52e670225f8ff6805f5e8861a93a8da2c8b54e2b4027aeca9f8dfee1697a32a6daffe1606f7b541cf5c82ebc6dd1f6a148d28396389bb2d76b644a76dc18b21ae630b83c37bf17230e6f2685cdaa8865042f3402a3aec73c17a7515a8b263ce04a12c028ac47a20d1e351901d7a8083d14517beb95157db61413c6f2185721caabfe3ca693d226ce797b93b1912c55e0aed2de0695f5d4e98a911d87b6aa29f1c285a4d2a9ba8a25a915a65371e6f55d0adfa89857af1106462bc96f4c1a1c364cd4511a675e77286ba8e5a9dbb5da6f4db9e12fbec6688ac2800d065e53d38fe5035393cca2e8c8b4b4a98a181988968e780d709874821be2b729276d4748850cb073c407e3b726d81904bb295046e624562fa0c829ecf44e5361d8c95701932d7f306c3bc0fe2c5c88f6b39ee2164bf183ba4c3131026040449218a2665d2521845d4d071ae58ee86764afc72038cf7558b82698ee0e32e3b5bfc2be7724e21b77e247564ed951cb52344982fb2d04a2831acad97ad04f6077acc331a79ee4ba6165bc24fc2a278a397e0134600f0cd9fc48fc7273f202a661e5c667b563663d9c1bda61ea7e6ce2d48e0881715a9121e1eeb056240285500af94e2c331fbc2eed83e7a72b6421a5277296bdef6213097ed355d7690b1dea104e86648db76fb27f6236a18636ee19b51b4a3fc595435f08c9784da16ab62ddd3b5cf25647fb2a8a65b6e4c09b1baa22a6d261462fb0f2631eec9f6fafed26226e5adb6c3b0729700e0dc19bc0f102393132321f50f3a637c80bbb86a6eeb07c09adcbb4dfe6000eda92e65d03569111121c5eb207dccdd170af5c93867829d0c1af992015a32f98a2616872a5355f49cf9f1dc318a311d8c3cbe37c85fcb4a232df0040377e522bb473514d86dc417eb7112f14245f8176b3f69524ea9bd1ff82771d111ad791906f32487bd220ff1a80bc1f28d479019e7253dd12cc71d37bf2550e73faf0da4205c6c288aab1524c17a79ac7818289d6bcfe72fbf746e1d92b064be5471cdb951d528701a2d178765922d247a4c1444c02bdf9a38d00e0ba3aeb09ab5463c5a28d461759b609952c1ff1ac15e497949bb1da603b5cca5d1dfc2e9e75e0e65c104dc126dbce4681167b2be9cb4d09a3d7c6d922860b179b0ba4113101f782a5e0524058907b07a2b5119a272285036e517724ad731f49dc83b4467a83c148d1612ad4e8a073e7007691ab8d8f6c6401dedb76303af230ed5c8cb692204623c6e35961febc5470e49317397303a3719ca6b2d6ec95b6297b346a938d52230d234f1e122cbca681a88de6675e7a62d3e3387d905e7a1d01597909e1171f8ee543858791bf01849f4b32be22735c799dbddeac2324336df7c4315aaa0df2a88865c3890f0a16c22bbbacbf4038b226eb903466e1a21b00d18d8485f4c5ff6c83de9948257636f38f8dd2c2ef7cc632f7c5388226c370620eb8427fe07954a15f7cbbe8936ee51620ecb47c106f79e6d06bc5b2a1ef47116deace5e33e55514c464fb584db3079d8f2876e22620ed4352c32aedd0f7ed4641f6cdc0b08c7a60ee95da9b7d48cfd5532012a6dd16c5cefd7d83788d4803931ae40231c51cbe8d9b4361d4e6b4b3f9ca5b6b90318ccbcbb07c8f593c94b67e007292074fa10f4e754f04fb898dbb7fae3a116fdb90b8a0dbc1fc4d02c8446aea376aa76bba5c1c18fefabad7cd9f03edaaf074b333c995a7b22ea3e3ebb475dd3e9c84f709592b8953505e065a712b2d63b05c1f9662e76306dc64e99afc24188bd05a601b7114c36ed29e0f717f121717de6ac35281fd1a6adc79618affed02df54b36af91f78bf72660cd45458cbc079e17004919a4cf83bf3607dd579560606abf5917f40c2e60df4000c5523ab6929447c563b32e853de8ee8e1ec8521d274124010f9cc0a20e25a44901eba954a6f267b7ae45890e7c8414886e39032203c6ca2a0f85b778c0525a78126ddd8c6bb3caf50a8da0c32372966af34c576e7017268d058f0bda3ae32727b17062073ffc65a4b836e252320e7d797a52f392903db0e0a872d6743c9fa3eff917e6f1b1fce37f00f4c1d67fdf4ab46639931f2626d6a2e81d6ac12149192f21c893ade20db44ac964e5f15146686d757fd18c3ccfae8a15f0eee35b5619ec15fc638aa433f3470311f4972dec7b694eb5bbcc45e0b1b08d1d2b5653f7795f898bc39be6a66295b5a9ce9b4e75e0124780e6d392a7b1e0acfd3e309ac371588cc88ff8e26c26d2904236ca45295ba12ed5b870a53521411edb9ff1e6040ca4065b5268674310bf3feb3af2fe8f7b816dd4fceafddc5d51eec3050340e1363b55a641885dcf7d76b3dfa2ec4444354930cb66510a0992d827674c2d4c8337f6c4b885c439d48c8c80c2fc391041dd3394325a03319c9f50567436b05e1413505e85ee77135f950d87b5928b193316e6195a325763f106c079b64ee9cc58833c00c9c5f3294730cc446b192987993f818a83a394b22c5c810288405fbc3080b8b7a58d0d3a3b7b4c76045f94bb709899c43950e4cc97385130ba438b2ff66f299a891dee0dcc10bc6db849453e37b9c317116f90aa83e906b9778af75038da595fe3ad6ba3da20589f78b29cc073c237a21fc13e87a03c8b2e02d9792f778c50bf4397859e0bcfd02f79a0e47a34cefc8c292145a4f3b3e18387257f162c27df13c5a89da83ec7814db28aac179d6c1831e9307b9bcbcab13d1f3575586df0568666b9e75fcad69fad03ee8ba3b5d0e5ff1df79d69b514b6698f638b57c5834630d117a1cbb30a3d2b0ba6645daf77661b570da1e9ef2a125ca1a10d6ec5107c0054ca2156d2eb927f0790bfc11c531ec981d4c5874593313382ca19d463cb42e35e233bd350b135ec872b6b6e9136d710cc033ae07e6752967161fc673e151d1c97638a1668b25a4ad467c4cd378af4a1ea3e1fccd24f0d1b371004659845e550efd64d7e3afd0768d88de0755b8ed536d68a00adf4e0e6109503f99e18d84dbecfd6da081f507d30206a6c5397c3302751d6a5bfbc50c09a5b7c48be6e8dc67bbcffd18833f88e728887d37fdd6ec83e4360d2c31bb6870caf56444e3cd031ba4fe4bdec7408c1b35175d7cf30bcf278873ffc2a6c63ea7867cf243cd3f2fb752e5e8d245c76ba8b6eb15fc31bdcf8ab5deba07658db372bbe61402721f1d8f9984d9bcafe0c8aa7c2ed42fa6c6d36a36b8c7aee31f91484fe322fe37f95e61d819099640c0a7a767853bf1759050ae1038dbc9e2f91145f4040b5534f862010f5f83b128a120709cc7067d541230c52ba5f58239bf5612bc2844250cfd1bdf5b13dfebcdc42934b7e9acf8ef04735e0c7c3ff9507f70d96499fa72a6f3bab165dbbe1936c4ba73393307932787e6a4981a1528cbc27bee0ded51253e8bb4722d97dc70ffc25e0acdb9fcb5cc2f753224d0d0fa6c7d53e6221ed9ca76cba29ad9e6b2506b68f3f92f84681fe872d63a0e3e089bc3432dd22a6fd3a20cad78896ef9779e7dbe8cbfdda1d3549a1f6072008e86029b1595986d9d677e8bedbc34b3607b868241424ebf903f73ab5517fd14e139277e298e8173dc1070cbacc6a618b07a2fbb8c527d8dd83db3485be966b70d0b5f08a721d2fca947d2ecf39eb78ebadb663f7b31251ac68dd76cd9c3c1bdd855c87db9b5712ecac7c3dbb828709d9c6de3f9e454a78e928df8576c0716f73f087636232554eb64958ac2305f10ca07b3e421bcfc8481574297ef38739e81642aef2596ceb2596aeddc6125ce6aab93f36c3f471f9b57af42bf819617de525b592f5aa9add4f3dd9eb4f165dd5685bbe2a63916dba6ca7329104a351ddf5268777661c661249bcb75b07c632bd3bf61edbdf0006f56d310782bdd624ae85d3d3ac3ddc0f2fd99a69116e66cf0e9f6bc79ea8872fc9d6396edb8671a5479b47d131211a56dd054fb80bb74ad20a8fe1f3df95784023356f0a93bb79a0ad772d449923d717e7e6fdc900111cced9226c60b1d95fa5aa9a330651e1182dcd061dc781ab54428545d8c9a85d61d5c59a38ab01e92bd35c115586cc580aa37a2f2aaf0b8d9342eee0296e2dae3f0d40cdedffd0bf5a437733f10d65d2ca6d416d650fbba0c331a4ee3fcf94cc79e4194a7d113195a7781e8e74afa0034a9929d5d9fd4e8e153d150854205053647f8468f7b540fb0ce467031cfe18be5dbd5e68fe27139998bfc0fb7e2daa4a0de048bebd62c916c7068452fe2514f0bf23c5b6edcb100162bb70b18b2c9b9a4fbf4b9cadbc8568b233f73caee542254bc4530e5680f11db844e86d8cc8000f39b7f5e008b2960510559b3afd869cc1ea7793b2506991717a5c04421e0e65132afe76458770e5cdf8eead8eff82c74ff63939784ce23e76db559b788e9ebf76d353fe1f3023c249c815c0d44438dd40e81075f9be1a59f12f6ec5e1006514024070cb83b7b8d024ed3214457d3ed5e3df907a618ea79c5f413e1c1a83fab910a8b3347a4d8cee0c4f1bbfded7742bf5bc68a36791c5111f2420abe3353eae4c7967105a3b180467d1519e68b3c347e85b9476cc4f876277237efc8e8151cccce685619e31c8b6a5907458ea3a48b7930a94bc2631867218f734f56d345d34b3ed3f6d1d55f97be1a164252802f516626fb78f33590f1914515ae96f4059b722a7bf0954d44d37894093ec9d527093f12dc015614843148bca6de59889d582f58579cffb0765fca88b75005744d784116ec5d04e369783b9184926c10fa6fcf8d2236c2e401093ee5f2f3515a511a32d99e46f083ad8be51585e06aa8a8f4db2c9a5799bb457ad3387076b1769a9ac1bb8371861ad0577d9e0954314d176c613d2a94dbaf66e7b21a29d13390347806c6eb8d8e2be293ca36100e317135e9b3598baa484b02bab3bffeda1544b091a1c7746afee81d7d5d35d00450448ed8836489c25dd16d1b11410df100691a9a42630971c168141050108ec2ee17a6e5a33e0e1846dc8076ae91ad1df7a91ce0eb40fc0ad2335eb804cd27523dcaca76a6050bbba8aac8a5510538f81d563a1311a006efc7e0523279cf8096859931d338c19073cb156a97d7ba2aee13d8a61272144e6b59057eacf9720cd6e7d28ad6a7118e6d39ace23aabdfb4243970394f244972fd6d7a1b180b280756e22085bbe2146f2476087737aaf3caac93461d26cd447e5889f029331cecaaa4eb86609c29466f45ea4b37c2ae3ebcdf66d43e8b4242ea71b0df9376fc39c078a3fde4b1069e99929d99dfe34624bca92afb48b00d7e85f33058dce5c65579d6abe13a041d5e00c2f91046692a5a4b5fa5e87560f631a36dce912937585eba7480a81ba91af6c2186abe8cf7b4e13ef86622c208e5653aebccb63130a71b7d7174b926fc74de4a4bcca7c8d48b0daf7d319042ad2a949c55650917596a9417ec28e4d3c90ec0801ec01858e5d13d8ccf3cb1f42e428817d2baa86173e4f9586adf51141bd3d08267813aa4b8d638ab9c111a6e69454ab558cde8f1ae91e0f1e941e849ee7ef53cc6bf1139cc2522ae8d682e1b6c4db888298b90c499f3f79d1628c9fec96c9e13a1fb62280e3464bff531f5d9a0217fb14e7257b512eec1997224175a26655aece977060c1de4564cb6159a433d26dbf2916810a6ad68f9ee7c58cb9028b89b8ff7854c123acb1660a1658367e4bc1cb0022c20e2e3e44673a8d6731ed0a01f6ee9c602470efa0ee4b9b3d8c8057dca32156f5dca987a08ebe13ee503e65b572e86983faedd806c77b23ee499edf47c8d9fa0586a301c553c2e66a74f2d604e0c9657589aeda5659e3016be8d839befa905b7ea6ee790d945bf18b79edc533d6c968eb23beb3cbc000c57e783374ba1772b5d82e115ceec461f581f8133189abf8adc9020625a1b843f2d5004f4ea2ab2adbb6f3701d6d5959ea78576f1d2fbeb792ee4cb8000c53d1168b12abc0e0654f2993716800bf35674702c9869feeef309f99f5829642376385423095e1e116cc690da62c6e343fc601c243669dd5164c6186dffa8c19471b95ecf47ca301eb6290ec3bf210a5a2c2720f3108d181b91d64ecc707a7908f43c7fe2ad28af62854bf7b08b6abb25b868fa0a3407e87e28b14bf87308cfc272b8563a56da825205e946e2a1199e26c1b91e2170fabff9cacc1fc0d36b56d59f5420b33324fe0342afedfdce1d7578706a4dadc90493669df4a9d8854ecabde9ed512ebc43bdbef94cf3aa733adf79d6c70257171666d6d3569bfbdfae0eb8b64afcf1a8f91d61026d913363b5c382a86b04e42af32dbb6f4aa20e54e738ebe1a8e7959309f6320546787a2e27053e1e0963061e1d416f71668259e02036c408c781b4fbf060fcb08558c8342720567a62f3e71fade1facddd1dd41ec33ad4a8a45a2aa0d5429c4c983abdd640da1d3cd4b4847b6b23622e9e8c291d19eccd292e7afc7b021d200027418851c124dc282145f6e06caa427aed0266d5b42d570f327c72ef7463c2d43611dd19700cd94dcd998a4165d0153c700a52d7df4528181b51bbb46d9aba9a2f09cb114119c850102a46bd8ce933ee967e78be73b553ee8f3c4efe701fdc3bf9474c0429227d380141ab2ba9db26be0cd05630b5c69b64547459af74cc7e32e5259d9db70c5e6057fc96dbf6e224dac421290bf64b86c458c14de9262c458f593a820847a972ca04549a51e9cb65a0b3e6962e2279b221902805d7e7ec8fa8ed1e450f5aa64efd293cef930bf494bf627ad9b5559db7500ae09bc4e683cf51b054962b78275a38bd1cd770ea5f3eb5fe6ecbb8d4a97da8e144fa4c1483c8bbf7f075d7eccde2344547bf5eb4e123e32b4e386cd5a33daf30790e75e241c64a422c5bffbdd8f0f7f1b889b6a0c1ce10b9b4c3d82b183ef19fe24f3d0a50e6764b2c471d8ffa0be624aec667bf55836a42453e1ef829206f83fe7f9b82b5fb1d0ed23aa5f0fcf080887ada006d788587a0303a2d01972d67838dbb34c6f4db16fabd6adf768a678be1158ac0f5028d8aa4f9c79c8a96e84850943036797096edc4283fe8de56bf1085c12ab316430919a3a4ee0ecf9a2c03b68e46f61c416e7bfc9fecf8f9a2dc5023b16ef9016728018a708073cf73923a9a92b8c02859f22d580831b9184b35ab83513dd912341a1da805de2b60601af2ddc3278acc150cb048ea90baec3f7d62abc80bae49cfd77c86b14bce26887d8cc5f43ee4a50fccc26308bac3c34e0097ff90255ad25ac586635cf53f11948ffed951abc762b13504ba0ec3e2130e79800328fc1819d6af7cdbf53ce6faa2821b6c80b118606f548146490e3318100250d38fa1d60970e765c36e8735599428109381426e81295e321c5b317cb61cec276010e6eac659f46a0dac4f1697d64e73b59b7d8a90208e7bda43ad698e3d7c842a9cd438fab919c37d19b92eed067de966aaa99b67330a19f6770e66eb74fd56c7ce5974b7d7ce694af149d475b968c3adbdb25801fb0cfe863f7586475e3f7f85946240ebb68ae3d87100aa01fef0b2153c4e97e8538891076fe31dfe7c7820f64f4079306f1ae1e545fe176fd42a1eb79940f3fd29e0ddf471f834c316cecfbbf57c89d87b5c0c6c7b87305821c08193f56c2d7412fff92bf8a1936b76774df04ad09d8cdc4c8c203a59efe638a348bfe19c36db386f037df7491e37b99f1d791f581cb6aee730be0c34c9d4a8ca95932cebda112ef6c6bc1752eaed5a0c7737bc87e9c65513359e2d8e50f9c1dec5e5e52df841fa79903b36017e29c131763632e5ea5d4b9c7a76ce59efd1c25f1420ef682fa8d3349d0a1b9d4adf989cab8c24a52a3c61c9b0ddf8f5f2e914777c39d91e0ee3c059376bcba5bc5e502209145b9522cc3cccc912c9034d1a1d1331201b5b5b821f27ecd74a00d7354ddc345c5525bbf6bb655a0270d55e383439d2c6e723d053da6545d00a4819ccc602ab36a5a991b0488cd8c3851fa5c155bd8ebd0cd25c4138a5e420c426772132535dfedf1e3cee6c5bd828d6d1b67c697a36fa8fd6e654940f464e9fe9fff9761b3c733ec42b97c3d8947b2baeff39bffcb465a6a93fd09323ecc1b4dec9b6d9247816e1d21f91b7bb3591ef24bfdb92df5d5f5ff6857affb13e0690fc5e897cf6bb053d9b8d2f6eebcebc07e6392fafef6c636be67a98bcdfadab7f3aa9bd20321537ed01645d6c639de6f06f7d47874dcf9fc08377014eedce74ec6858fdcdb146f03fe6ad667896844ff9a581e75f267f4a70f010989665fec476f58761055b020701d2a5379cf44ee1fd5f12e020fa5609b17d86fffc9f13feacfeee80068247b6be7c82922a02353ab2819ae6bb492456dcd979b5b13cbe8b14a606107fdfdbfab43dc7d2d353a050db90bd93b06a70f6caaf6cd6f6396dfcb679b577a687db46f043d8f3aa649676ae6f3b5437071f27d4da4b970e236334887f8ffcb3b5ce38e6e185362da12bd1ba655bc178e2bc9c81739498d8ad43cfa14c0d3aa8dc388e8e2db9e8d76af199138cf1eca9eb77480cd12fa1b791992ad1d2a55378724a371792730a9fc567cdd6f6642b99468842a794d8cbb4f4edfcf7da62f0a39137f0ac7f8781a68149d89db4693a58f17c1dd3a18c9d0fd7de2df14a1716649dbd829749c70082eaffb65b9a62d6e8c6c7e7df1f6e09bba8404834a0c955c46a63540b52d5d3429d16de1e1d504e5cd93706a9a756e4ec507a6ee47f4959c2c1d1fe500d368738e57f7f1a4b69575035bcba2f2f64c415be71c246a7b84e504088694d94d550afede42fab9242d4389d696a463d84d53d84cbbe73733a25b060af67a2fd2c04a0ec1a7bbbac6a3da27b28d70e7a5cba5de227ece49601d82f761986267e640c003236335d7c657dc4e758d9c9f93dcf0729bcb1f74eb9d8763651b49da33db4878d51ce45fba5d5e4c54f02c2b5bf01e288ccf143b7693698fa5baeb4fe55818dfc0b0e20de8effd2a032c5fefffb78c8e32f64809c5226f2d89ab5588e756c8de8d87d19b8a227c5b6d1854ba8e628dc0237d7678dc7e4f6e9b6c399b4b94c7bad0a76be55ebf4afcf07ab52108f203f8d86cd5b9e2ecc21a0378f9efb424d649f98c9bf98285935457d5e257cfba04979ad3b573f8ff9420dfa2236f6327daa75dea658e50095701966042b1162da3cee50be17fa9a6a9ef3f47d22cd487a7bfbbe119c6d41dc0ab25eb139169606020a3f45c40e3ddb626e7a5fdaa304b3adbbfca533be368b06263b84705a49d4e35572b6637ee2951146490df5c9309e0f1888dd970857ae8ea6f0829df2b4c5d0461cef026f11a745a30fe853c4d6a6ef044395a5c30e42bf0626acec35ea667a70e97aff074e3ba5f4e6879bae894ae408fc9ade1bdd0073e813dafbda09b0caf54884be0ab241e23ae024800f6aedb073c7cf1f3a2e143179c9f1f387e119513e84c441063d64fc15ed9a3076b86bf0577f577e7bd647581f9b4f2a105e21a769be2176d46fc439266a81402090c47c78efb9d1f678ef36e9ab51d99f0a355b2b37f3cacc1f39c79dd825005e2f8561d9c062b3d5c7427ea3de2648634aa9f51fc77e55fa82feec00bd5dadff349af470d458f5f7b68b6aee87c08a56eb780e54061166fbd9965a95f57b3348298e10f498bc2c1791b86cb7dc80b9fe4a465a65c39a00d3f80c05eef754cd1272edddf9c1c9ef3d2f62c2258b917cac6ea134c8541d96b443fdbadb3eacd03483bc86080de7407a6b2a10baa55da9b73328243f5e9f2ea72a35317dbc80697d32067c736d3c09f8f54761866191f4413e080aedecccb862f275f348947835ee74c37f3e767ea7b481dc8d474ffa9b4901d786b60ac2deae808909db2c9a557aee54ef287fc0a992bcf8eff2e5e5ba28fb0d3d890f7db7cfa1bcaba8eb3cc121a9bea3e8161dadab45cf886b93044a4e24d58dc456b8e44f26bba839aab96efe0c09b278f1f1d6c211f21a8adbce790ce6a82949c2a3bb4f06e20e59174c80da13ac17a33201613b80188720b89d5d6f6de42efa45c3a632eb451883d96e82dae06f289933ff6ba7ae0d2a6adb4c5f488df4f5641e208608e867c0890038eada26c1a091373a41c88152241b38a14eba2ffcc171de81386d4cb5ade563d181ae71b59524bc7adfa7d70c53cab23082d40533428bc062cc19012377fa04de3b85596ce05cf31a399bb4c6b4890aa8773195c3cacdf59f6dd171f64be4538517a58667f2885a65624b228e8354eb6d91e99a8adfbc714ff4d6bcc3bfc8d82a08dc503e3fed5e607b13101326c34c39fc40028e0d939b0e89d949c489d632e0e9389123094c34795a9672bb0ea29b7cc11a4aa5f87f73783fde9ee4749efb2bda978f73ce0e46897044ea1fb5fce1aa3025303d7a9c4e99c78d52047b3fb0f66d22603a0368323723c8a58178d21b07e5b61218fd87cf3690fb6b40aa7444238e40df6f03178c91823bb2885f289a85def11ae17d927544b52c809fc0659c80428becd5bfe60810d253eb6cc2afd35818fe38f4672d0746ee8e861c127162a86555866c347215c639d3d9c43972711aec4b35205b43235ce6bd354d2f7485020516f9fc7b9a4c21ae9eecb6364936f3e78b446890d20ca6c954f073f6a0cd214d02bb7d071107775a1f66e6ce40eb36309dcc7bb8c978aa5f9e1afa9cbad9f62bf813b4ce8f1804f871bd466e0a1297c9517c8580e2a110827c0ddaffabd3068748f0de6f9310650534b3834409cb0e40f09fbe0d735c2e826cc9130fd9d4d2255d184478e0ad4ad15c45c3cbe3bc4c927c99121104aee17d5b4307e70a1003b7e89004672b5701702299b44ea85a6f79161bda9b1419ebe8fdc816fc58afd661b7d84779d866aad97561a9f080c6a5a78a25ac5d4f8fe185d13df36c154098588bfd6448c94a8af2ee058d0eb323cc5082952f18c0c66459f01e2cf94b22d081d698d564bf9e30dadc7e0ccdf160685d1ae9b058c077a3a69af254f24f4a2d1b53722b3864d4ad93e4e6cda41b8d20312152da35fba6822638b7e2c5753396e10824e50a08b56d6239b11f2ff9663326aad07240bc4b3c71205c220046e30baeb900ca1f62befead2ac3ccf48c1536152b09a1a739e079fc0e3eecf0f7667b413496428aea1a64bbf36f4d73b969a15d2d421cfe62f12f6d62711da4258efd2e7788d2453a7959af2d5aa4283bee032c6898f6ff97125be79c3e1e58e5c8a65a8c0b97c65825fecb58e0b12d4b06016e879c4100aa5442c95e6b4e22f06b5ba1c215be630211a9117fa382ed6927f8fa00f299ca8900901dc83f6d15cdc073667ef89d9335a10f601b9851f4e0fa84fe0fa8d09dacdc16c7d30c4de35b3fa4bbcd8422ca931a43de0d6b4c7dfd3c439b68098c386f3c5cb53a3c99fd69bde15e101873d906ca719f9f786d2eec9cb86396caa899ef897e1390361bb4b634f140f389c5320b8cefd7101955ad2ce57c2b9adb5644233cf5fb0c5a4334c6850b46685e637509c555ed5b8f17385123179be235644f58e683f172b5e1a1fb983ea32d2d340cbb7c4eefebe33cca9f31a2ebc7a2c0ed9675158c341c47465f195cb6d603984322d9b624bf19d707eb3258994ae8eb961c02089699e338f5aad69f515c4b69c9a66ba3da86ee83243c3e7400433d70161d247921eca8df4af44653753402b9ac0da33ad613d1c511b32082445caaf5dd9fa55205a904498597903b6c34ff133055099efd694c1bb1cd75d143332444c3c797a9c110da818a4b5a5eaec7955c50db43672f694ec45d4df7f66661d2c2a6b4c3576baee7dd187a70b8945b50e6b71c53281f7d7f5bb2ef3811db89407521d41e4ec2467c75fbd65ed35e8997de081e0f10459c9267dbf7ec6f57ef83dd299ca944748a735f06ce6567227b660c490bb484c791c304ac6ecd3de111b5285371885a19b201d408ea884f75e540b73b32cfd732b3e9aef0a7abc83012b5cf7526ddecf8be70df2b1d735b1029fba36a8ade9f7012fcfd6a57763205bb5c423810632cb83d46fa613de42219a23950fb22e6c4286f8ef5405bfbcd2ad748457f901e80f018b481b1943ad0af8cc0b59ba8fbece0df00f198a902fc582588f80f3b5e71973ef2789692ccd34f55565b47b0dff5d7ad884bb2c5436bd1d1c0c37925792cce169d8a432df560c61392664eba771f829c9b30a69937ad7f527e51d1138176ebff2f6a38d2b0deb60cef44c6392ce292fabdfd43899a94371fa48233066d5655d6b34a94f102f8af5bbb210fe091086e605b9126451052c5c511c63847e5acc8ae3b77a71fc5bb665646c5f99796a7955edf77d04759fd25851f50f9ef06e9968e430124bd0c0df827660e6604df3899018a5ef0a4cfe02c4f84e1ffbdb159e594c161b2ad84cc41c4f692aea26bbe5823375f1f916e2e8e2cca906e3a4a17d936c72907d2e75e50bf18c94ab2b76c89b62f11b72c10b05cfaf1a06f46a9d32ccaf11573f5825af831a82b65c5a5d3b41566cce612604f8c77eb8e910af2d6e86e3d18bbe5f1b249a74d5b70213bd3cc507bb1c22b48a96e49e4af0e364cd7a965477626019de3f5cc234835f238623686cf87f2d1395ce90568b7b4b83bb863e1a92cbce07372a2e2e98303b8a23edc9030c23bf90191a1c08074545e52856eca92e6c885f8f851d7c4cf714a8e09519b38fcc41b71a45a93e592df934d1565f3589cff73c1558c99081cc86d85893b99e38b8f07c2769fc0ecca0d6824b6d630668a673694c4ebeac09773b0251c839bf62a883208cea636079698ea0923a0a65cd00cab9b0ae751f8764cacfc8e7d10f4ac4340a2de874e4bb102f6ef2b5f5c76cf4b83dd7d039f0a57f2d344e12ac36e05d2528493a54bfd6518e89ae547e92967ab1311f7c348742cd9782e47bb6d62791a8c5d3d0e07d750b9e7ba2e95b6045d9b96911d69c4ee6b38c0543ab5580860cb00b23eeaf1ca42de20195f9350d1191dc31d92068b1c1c654abb1f597c29ee9ca70384d58dc1dc7935303be6046d416a080eae95fdbbbc7bc3768844b363901ac24005e7193d2081516e2f65451824dab3c92e4cf271a1129698f69a94d34f9e94f92632c600a0ac56e6e77cfa2f08025af1dca0157867bd52f2ededd5d36dc860404f41c9ad5055e9a42b026ebc06b201bfb704a6ca6de4c25d55c322f381bcb010d29f95a02a3457d88820b61c3f449d21be6a35077f4753d45f85c5144e8bc70f9c37beec2250dcfad7f37d43be5f37897c33a5f90862576f78de3bb74f6fba982ba0138260596926b0ff46e5fe61173ab5e5dee21bb168d806d2ee6baebd11cdaff296f3d735b4635e66b0f72e568c150fd95798584152d1bd41cc53adfa34feab41be01aeef69fa7b88fc2fd461bb59e957fcac1124336751765977ae2d3166f5969be74c101973a090a6bb79bc48cfbbd7a90326ee9036ea9b952b3f6dbae2769ccc7f50e8c305627983a43554747cb6e758d03dc1cd013fa3fd092511877e6c97095713af64696219427614fc23e3ed552daec217f30c4a5df2d9cc143ceb916ea9ac9fedc2009745781bb9d1bff68ff215b9ef961ba29cc897617f2552c18ccfd5f57fa966b1b7b1e4f3352432571826eae9037c190edf02e564142fb8c6106d4908aed02062ebff97667bfe7d2a3fb119fd0a7d541200597b07e3dd174797a9064c98483eff842f9d799a68f0a7e6e5e2ba769381426dd965a05a3482fb76929babcd55c6ae123471aa05658509fc43f0fe2af17ebe499ec3d96bd0b40a3c763e14765560ced0778d3696cedcf866ff528a1d44e68ecdc980b1b806dfbae285da93f53d60d99f7b391ee08e6835cfb3b04bb086e062677f799f55c1a3ca7972e41e94212aa5bc066850a01d55974096fd7fa9772094b1ac2cf132ec3f391adafabde8b37fd9f2577ad3d48fe7d663f33c75f7f8f685e579adfda61513f7ed0e5cd50d36cc6bbac2c0e296f20f2fcdffba2e6ab0f5de5ff6e2c7195ef6bddc5a309d29e465273a11b87f754e93f7ddfd1c9f1fcdf85691a527f4e96a9eb1ff4d314e670d3f3f8b07e2a17772075e603f52e18cbc3b6aeae653fc06cb027939df48e671150835426aef1c0e60e70f2b63bf569d7e02c93fbb2144fbe55472f6ecc358d0efb8f6772c7e3f4c0acc2ff275bc1cbb7fc6dfb3f513ca66d4b49c98637db97d71e0d8cf8b952e3a2ed888ce7a6aa191dbc2acadf2e85a714765d066f6c4a08fccbe9c045b5eaa9935ee6f0ddae900598db48c61e6946956d23bb755ff8f5f1ad59e340e3a7cff680ff01e870a3b3e2d3c17331d2f63a5a37d4ed0554dd3efd88d79df328f853d59055ae8369b44ff192cfe38ef3e8d0fb60b4f0e84b7b742e2216a4c58b3ec598eafd6f25392f839a6749599aeb2477d24589d500d1f0f9fb46d7167d96b3ca918f64920a30c00a0fe4b72a03f9fad18eb751806b5ecd4e6f760246164c12f0a4e8dafaaaed98ba3d7201f8a8e9c01455bce3bda8b9b66606efdac76eb2fe7f17912a8f1d550e8656f1dd9109e5e6e5147b03c285e0c8ef8fdcdfc1e91043e11357d72cd73279f85e947efbb1144de18e7f053b037ad9c87b895d047c5a8b4be06f128594a13a76b3f59e214a52eb58fc544097d2f6e4bf811315adaaf8869897e407c4bf50331d55213fea7dd34c67e2389cd5f510a323fe8e3ff275b6f958ca00b52e492ac7a2a94075f58725458893f528c4bfb756228f10f156fa97d4ccc4bf8dbe256a28f14c3d27eb5184ae4c3c5536a1f15b312fcb6b8a2145c128db9fb75624829c74f87a2fa9a6881752847a8ed189c48faf1577874a9649db0c900533d46bcd2f97730fc3e4ed94ef70c8bd0f3b01c2cfc83c372fae415f96ba576f66c694da7c3b6ae8117cc0a0e70898728e43e3b99781003c241e303e8f5c4f2f49c7c6e44cdb049559aa01c0a4c4242a198be514be22e2aabe4fbc807b1e07d18fa4ef4df06cc3d2a3cb2fbe7042bdc2f470ce2c740d96c1d3fc70f76065da8abaed6b1bf29b27f417fddbde7171c0b50ff62f881fd4174a3e7f37711c2bc0efb7731b74c51f625a0c7c4f9671afa6ce1e38272309f3ade0b85b3a7eeb7fc8714e093dadd60412cfedada741585c7877d5a983fc7da028ea35b5ec6c73f8e442414402899c27fddf7320c3c680abc8787d975a149b64e20ff438ca39a09e8c2fd47e274f341fbe376fc76fb650ab21bebd8a84a83c94cb017d8a26f2c980b7644dbf1981aa2ff2b5dba720658f2708676642e80eb1ca6ff4509d8df1e013c622646bf77283a342f98450a4e9f1363b0a3a7cf7b80d307bc7f904bf2207e63de206fdf225cf393959d397e8e30a1bd063f7d197ec2ff2969fba259817ed9c73e4cd804bc43f69ec4300d9db04269d03b2c7f289a3fbc65cf84dc96087069faa1d27a71825fd2c56c59c531d5dfa231372c2ba4871f3c17dcf7f82e35a4c17326eb696859c0d3e32e8f49a32580d08a037908f88824c338a7ed2dda36079e435e238c2648b282ce971ae9cf3b5ef9e7d11d0ee0f161c726ee3ef547f57226ebde3409d2343ef7bda5de655c26a36cff1c2ebe97ae11b4f09a8ff7f3787be6fa42dd99c20b68509959eba0103fbc3cd0b85fcda59695747660930e71cfd17f52026429be673076b6e906c8137b556aeceb1bdabf7fdc17731fbbb8600dbf2f663ee7a977cdc7ac9d806a7e5115a8cfb22372a5ea66912baa88f2cc816a7801fe481d6509f007a8567953089b131df0b77707fa33682735917cdf7bbbdd15e8a9f9178f9eb0d98f1c5d7253620254103e407edae0d518be79e2542236a1929be3ed1db6e80e8ed27b349e93e816696a49916274233abdc25e583abf54abbcd7fcb2aa5b84bdd4a1b928be84251763fcf57471a851fa933a866d9c717cb49dd79704c8a17aae5f23dad3c03060e1f1a15a9aa8d425cf7ff15c371ae29f7a65c79bb6735645dcb2457405975dc2193a17c361a336672e9ab5852bb8c643e73133d8c541068ceebd3264955c86d82e0cea063be16a27e01fcc0ffeecf0776b1028a601f0d286cc2c7ebb077a284d1a9b858e750024ff51bfab29629cbed7024dc7cbd069486d8e728a2766208028053d9255d1b0919cdd9a9a22115508a8a7a742dcffdb1bcd54f17a53687ba5c06adcb2f422e3daa181c661909c2ff0a0c6a4c8394863e81f959ce80f0462a04f0b1fc589e517faf0b21ff51a55b24c88fd0c70f575b05027e78141f444ee24ca8821e27a3759f047dd60845cb07337c28d97ccbe8f4b878937da77ecb135cd0b975df8e41bdfa6bfafd50d52ab64ba7cf208acfe7e899d5b733726a7f138f3e385151fd80c79b1a8e530b16374e437c8bcaaf4302c35e2e8a08a0f6d56d822a81bd7a375c2fdeeed844f2f08250e2a1e21c28faedb20bd3bef37aa41292166a077e905ea7dc963cb002c8f8f8797405ac117e6a85296c6bd696b712555cb5f6b08753badabf6e6cd8a180d1d7ff4cfc3305847655dba6f86e63a94b0d305fbdca5f76d2e47a9a71a4e5d0543eb84b52f7e5f72d63eb798e3db4142f3b6a813b48ea07ed2650048316a968aab17b3f88de9b1bf31b6cb589014980860312751de6646772a7de7810e7c384fe0cf691ebef9e755280f2ebbe83ee0f91edfb9d606175dd5ba3afff4e1a973a0040da960ea1d6132b2d02e5e15599aaee96345ba18e2a5c2040777f9a6b8e5b5983778ff64a2f429e24fecd70dc17d3b0ccfbcfa1f6906e0241580ed52beae68adb287003b38b6d5a876a72d7fd2115e8bce66224437d05817dd9aa4e4e8b184917fb91127809e2f1f7b0f8305834f7bccda695428170040b0040202909d7e23e3ae28a06f38505a860a6a6d7b329a8f88b48e4eb14121017471484d1380ce43dc2393846846347411741beaed5441cd711e32ec06550722fd7c2e34606a17b37da567757ada31521b130d7d68c3d8c72a3a7923d052900aebdf7092a25880e58c7c0570f5e25499afe3205432500ef9394a4470a05a128304fc094c6ea14765a615c76129065a25bd42a52c70bb2052149035d44dbb27eb849ccd0ec4baa88222ba097fcf3dd06481591e418df18b4615048a3c1f6bd7b731d705f71539dd6bf7844ace455d16ba46bf984c5198fea58ef4e885f35bbe14ad79093a0c2fe031b84156d44dbcf0b9a50125f5342e1923ac038ad3e2c33baed7425d0200e4632e4ab098b855cf27b421d153ca006a5b454760e35b16944c77fa8649fa625ccd7a029772c0db051614f1a2e843132862bd5673a79537c1ae2a5cda1b23498e8d0b4c29d033cdbd7a426c1c44f3219220e3829fa4be0be07fdbe206d5392fda5ec97510be25ce457db8adcf6da9f25c5e8ad5fb6f7038191faa05952b06cb6dc2fb738f2d1998f46d9a425f79c7ba6436891741d1110f26252b37f7c32bdda896d39c8dddf5c69cb332958513ff6cc8844e3ac608770e6b3b0b7f1efecef90fe61a92ff3e932e91046f398a060101ff73deeb5832722a521f6383fda09cc158200eb0a8d1dddb146d16090516af44240a8eabeb36ae9f61094c3725d08e958c91da04ebc23524d0c82c69649194864c860c34b0b61ceba813f849cc0818d8423d3278799d874839da961552928889aea34aea06e63220f1a4f6a4c2bd241115cd25d61a078b401d9228dd6ab12986c8a864f1a574103eda1e730005ea4852d3fc0c353bdea272bba9bba6278097b296e489dca86208664b15da4808d0a11585031017250d885ae94118ab6056622d37fa4089f8a0500c48bee72b5203e12a41db928378a9e7906250cebcc784728004fa88c1e45913d9b11e030e9bf76adb05d12e0ac24dbd4fd694fd74a889ee24333b0236813eb239147f0a92bd1ff4954a4d088ca98f9d9016359229829a4ebc135194bece23756a3cdce90bc0a5055387200a5feb0d2454ec9ddd0dc29d32a897f43e5d4fecd7f116d5db3ddf994e01bc74d4049f24e461bf7e2a9b02eb6c1bd8671b940b364898ca36b857b011a0531641972a2e22afc1be47307af6457352828263e829ce94488e152d7bec4112140be0a5ea2779820f25540679480b82db28a951cf3dd5c9695d556420adf3048a40995c7320e283c9794569488a9c41f1811213e60715c91433c45d4a22a12b235e2cff6ab17ba95d6e4b70e19be266d9d08cd4b1e830668a54710a9222d75cfc983041cca5e4c92501eea41480e782b3d595e071943daa839e1e9c031994e42183c3dca97f187646feb878996386f86d89045c8118a31b123c4899949e4820a8131ab04e05acb74ab154aa1124069e1929f62d026757d08fdd6f7b3b59f81a8db90e4c3ebfc1099554fda31e261d4afe01221e20c9e197da0dedd099e411e162a898ccc0b59b30bc2bc973c98829cc04e8b3328b5949f67901e34b90fe1c50570918be2231764ada9daad4b03c3a7f48a29be45cf649ca8c14e607ac31c4a1e00202d3f12f05d4061ecd0d50b460f2bdad083dac08faafa0bda998bd51e1fd5ac5f07eaa68052ec0923ade6031939f70a27ef371eaffc29bc784302e04369a8eee31319787f42aee136484045d104c066b9e5609d5b44c58dadf4315d4b44cb8a4f784189d13a636cc0f9679fc71f6d2189d8db67f6e7aa962d7e09d091a7aa2c21fad8629fe506da6da4ba5fca1c2ccfb413599e3f7ca3201176205f466da1f2ac9041f576bbc949882e9d4c75cf6631599f9a7ea66ea0f2bcfc42e8d5569c8fcff553073ffac7a26ebe10aecc10affabc24cf596583e6d4cfb673532fbb7aa66e607abcf447f57cb2cbfaf10137d15cb497326fab84a66f879f598fac74a32f947d566ca1fab9da97a4d4575dd160b6ba41953fea362e6faa18acce073f532e5879560e21eade2ce5eae2817c2723268c094fd5dc12f569e69eede7673ec79c51cdeea46163ca1042ce21b1f799a98f1cf8a6472571bdeb4fdac70d736bd9165267b82c4fce223497b26fab9ba4ce8f8e636733f2bd2f90d6d70c9244c70f13dfd1875b9e105259b0485a29b89f6a142f64785ff5a0133fe404577e6f1bd4a19c8ae8de8f3f93b10be04032c7d6212acb7eb2c4acb9be6623bbb149435dccde9cb8af8b8a24ca087d630b266e399a99bff6d4ca524621bb0342557cab2cbc1e4e11bc218134b69bc486ad2552ec46acc2e6903040cc7de78c0f2469cd11e19b83e062398153dce720baf910302280cb921efb40a81510dd705928eb45351548f5fba2c540600f04403a27182b4289d905314cd100706ac3026512a867ea457885456209dbb064d52587c5b094b3c4062c08f7228c32d609116b4a7bacc510ac8f48d00c229c222da216202eb06b6b11a93b30f4579e13874c0be640f9224a0307c17cea80ef4d3ce9228027d8266d66981f9d024c6075d3b84820ab6cc7225f38fc237930a61fe736a35221f4e446d581e9dbb5ae8a732523c07c05d32d3af268c4515843fd7c4495138799ea2e34d286a0411dbf6d7c6ae6cffb8eac76d7cf8b687ee3ec7f687b57e68e7736f3d74eb43f63f57f3435b3e7cef39371fb2fdc3ba3d37c4cd07e711897fa181f1154a387e4d9c148593e789f48c9122170e18de5879a95c7026adb7c5bce8a5d489e80e04ccf9d3445d4860f035b599b8882d27b97c7c53ca2810b1d34168c60a0d581e95ce520ae8940600b302e9ac6b28b1622d41db105cc62fb5140a0600b8948cc0359831ba23912da02f74209d53488b6b83144bbc97bacf510ac8f48d006105e1a0eb6922c3b2af5299a5694404e726802a6e004a881efce312dc0e48d78efa3893f8ba9ec26528ed6959f05aea41c80075085a081918662fee8da92382415109d70862689002d942cad77427a6c663a629db9bfc286e8ca27756f83e59e16ef7612142f4caa42f57ca34f6bfe2faba427bb0c23faa30d3ec6145ef5305ee6f45febc3226dcc3cafc7a554c739f15f9fbaa98d057b151ec1f3ddeba6e86bdafa01e6ea6ecbdc49c1b06ce1eaf1c596ff8ca47aebf4d4d1fa8b29879ef84de7e3d560c7a8669f4f4f25ea93a6d997501db2f6d7016cf7876cc0d2c92e5032b5c33dc886d5b8e574f4f03fdd44b34998f43c91381b79ffa4b92b898208d58981057b2e945ea5fdedf546ce685da1bba8106222ad8813dc8972bf18610db085ea2642a98089a28af7d840ae22b9ec0b99a2d69a4c11cdc76e79ca1dddcaa82a35299f3472beec90cd767531dc851e4e1cafcb02a84104d94a1bb3432944ad7a8cb4919e3a52dad9abbe970005519170de8995d82c5c012f40530df0e40baae7b0448d77fc1fad1d137b24dd7ff5cefaf7359bcd29547623fbae2036c3fba18a8c78b29dac03fa311fae140d6adf68ea36ffbbe3f28e944ad9be8bf2efff6e7252508e07e8fe207fdd00d014355f1604899cd57b077d4f3d98a7632e423c54e0270b6180b379c2ea0d674d37d54e89fc1454b89f779513b521594f5ed369d9baecd5880aeddb6d72eb2d8671eccd9f54e635d5d9479c53e1b4e8d381019fe8ee7ca3a6ac50503e8a68b31eba03324ae36b09516512c452f005d56afda606a9ba45140a0ddd529794b0896b2c45e0c232e7f029ccf042a18fba2561040cb88d201e332d72fcf33a7a7b656bb4d8000740ec792c193711f8f18a2f7c8627cab599636ad4d93fd7e646fb2b96d5fd8ec6adf387d4daf78b9570054c11ca34f8f08e851ef92457d63c83ab6c3af7688369d02310a020a180aa530efbe1a9b8cda6aa6a984fb6f5ba6920ea652900edfa633945913c9cb644913e98a575b083787562b8f8a0a37914c249b8f494c336366ee889ddc34e3fa6f9a919dcda69771c799343d09d3835236cbefce9b0937fbd8426f1fb68f6b67f25a69b3ace2f9ac561e1559291f63fe1a141f59dee5c6f2081f955a1e44cb0793773910e306bfbe49171f92ca3dc2d8c3ee91821e603a8f5a02543ae4d1ea576decda79aded508f2c3e3f2195b6a547fedfe5c08fea61a447576bc11e80b1b6074d7cd5c6703304ad15f1572dcfad2b386316a4e9e431e5cf039507106a79c0030f2b303c5c303c8a941953c64b192cff7397a99579f29701d255f1300fc4f0800a18682d6ed8edd5eaa5a3936751e7796135281d174c47e7950345a664eab6ce2b07b4d60565de86d96aedbd2daba38d81d6bab00e688b406b5d3aaf1c9da6dd59bb23067758e972b154f7cc1369f6525ef70ce6c93b9ebcb3a38fffb7634b67b3b4a36687bc364f1a955287982cebc0420694ec9e49098234bc0dce3a6a5d1d367f1d747ce9427b6774f84007ea5dc7f04759a0b52e32612e844c1164a69009320716731cf1e4d166eb83923a2a5953296c07253b5af7d3dd467b6b79bae6f0f161cd01448e313efbb6087efdc185c801851c51ded15aeebb5abde408f22e075efc2f9c1c8c39407d757ad702d5b6d957964ddc8f386f469eac65cb23e308035aeb9ab96f4f1c56fe7fdf4e1c289950111c64dec1e1e57f111c57de8133a4592482e3c99f47fbc69837bebca1e50d9c379ebc5184e5869723954ed1d6a11b3837726616d7f214c784f9c764f918efdad9187974416bc7dc2c38db69438c9036b2882c1aab0d5c1b32bcc34792d86c330ce78686b09b3c5a9d3c451c36e4ff35c80859a3cbff35b07c0d19ecfb3e9608ae61f3bf4ba2861b5d0ebc754b67c9cdadab1a567e355cb63ad5407569d49196c60bd2b072b3350da134404063cbbb99f564aaf194c99cadce7badcccd507678de84a0e1fdd7ce662d2f951f1a36efce2053833a43cb3b95cde3b462c65694a93a7486f8d3267806ea97b6aaaf4b8c98dc39315d9e6d1583450c93bfc34119695b47b4768abc1baac201141cf4a54d109c3910540ddd808bbd81ec06a7ae6b6ca4adce8b92f427cf1aa6526a98de6036ebe4e02c8f0db41c771bb8fedbc0a6abe2b50d80d4fee851c3720dc65c2b86b40661603cc5fea8c0aa18e5d0da29924da8541a7e77dad86c66319d597b4533c8fc6674f9cd304334439e0692065174aa0fa4b5d747611f85d1600a0d50fff7cd3233504157c5cbc16022a4ae4ba63ed66a45d369c954504e182ac2a06460860c222003da73754776d5cafae6020c21c9810d5a8ca4ce0ea5602c0318b26c0ce5cd067d8d47580cd4f89728c159a2042728065dfe1838200653ba18b00083316070c53b3cf1a5a9bad299ec7aec618a56e672ee2bf6adbd60600506ae570a039b97010625bd6bbd3286ca9852a7ac8cd4ffee6b71be600c212fc0a2aa2f78f27747b7b1acd7056584b8800c171cb9402877735fdc4760e3f008b438f575e73aef1c6932db5a938d465d83b159af15c3ce1253212ec06941b675d6c4d997365d2d90e26f410f984aa3d5ead58222bf60dcd0d1c9c177b4b11a8d7685d1a64b47a6da076a24ce0ecac1a9018acd9525534c4671762de309b60fd4080c0bc0a096e67959908505f43af3360b80fc1d56653c672ba06205525660f36ac5517635599e5f6ddb9da14c61cfe8f3ec4ce2dcbc81730541fe4e055ffe2a8964a7825a0acfdb3115d878d95632c4bc23c30264d4fe6e764886cdffda3d461921637ce0ef64b38364a5aa3ac26c1e033746d01830b40fd4a84647e79543ab143787bed679e5e436d289225339c0b2058db205711be5daa623531f4ba63adb283a393db976a8e3faa60573537c7dacdc461fad41d9a39f1c5947d199cd16ca917594cfb6be7ce9d27df982fa3b5bbb35964d6ed8dec42873045722307f2ab4b9ce9a6b470c2c170387bf29c613318afcfb661864427ac3f8f28bf3868584a105f7308afada8a3b174610304800064ee2d9b773a849ab3425ab05a3c85f2dcd1ffde28b5f36f9a2892f5c9e37654d2e86aae159437d1124e68578a35e5c79c18b9a174fee85fcbd0012623ad4c59877a1e51d3ef2f0cc5e4f7621857011a64b496b33c84515f4ba721d3ba457ecca85f89f0b5757c5e302064cbf9e212f585c263837f35e7957c5f3127bc6d655cb548a97229d48a4b22dd9e404606a345a3b019613d4feeeeb98ec043dddd7b541d807dba2ccb7f8d255f1b6c0b2050bb65a6d61c4046c5cc786e7cb0459fe1e13b86e1f759575ca4c60a3459877f3ab4d8b69d1e5d3c23bd6a2c8d7452528c197125cf9a6ac56361e8594c0f54f1c3a9c2d1b9e5990f9b3f0f267c942cc22482797e96a95cbb4c34933c5fd90000b095ceffa88e2579732ffbb7891fd74b1f209e9c2640465422bcbb6f68c40cbb5b31178ff3f6b424660d37939592dd71d1180e92c0229fe7722104f712260226bae45494c553d9b180b2cb0c0c2ca8fc594ae8a07c3820916458470e1e2854b96ca45e4c2e40a317f4d2e7645972bae5c21c1595fabd5eb0a54c7b2a28cadddacf062c5954b2b3c6ab342fe9da5b90a305d155ade5521ceaa78f22a8a6c11f36e4b976e4bed790b934eda64ad2d0f81172121c0e142f0e4bf21286269d582004c4773750704582a083c1030e972590c6d3210fc0351cc990d3ff0530106d6d552b1e5362ab050e15161f33a4519d81465e8609d90be746a5077821356a94e4a84944ca5642af5b16cb2795f3a194b7c64065aa5305ca5e1a5b33bf6541a564b3195f5f7597aa7d857ac1d66d9ac0dab34a4551ade8f059b3a3aaf9c06c5f19523eb281d102fb3b5034528389bd9d48e14623aef6379b7ae5278f9dfc9cf470a255e6d2b8825850bff63f9ceaed50661b896c728c844918247a1e5761456feae1645501440ec111463baafa1f80205960b45ad83425a324f7891c91a3f61e55d3fe1b2b98f769e00f2738003300e4ce180ec9c18f3ce864e7cf9efc40f4ea0de89b36f1dbdd487bb966de79a136f22ccdf4496f1ab56d604ee4d04e1da58da66d8d54a9b6513a8fffdcd7003659e6d940d84f97f70ca0d6ce9368093ad0d04f5d106a49630efbe6b67b3a9258b162bff3d2db44ab196204c88f9df327acb92092d0769387e4c884c40b98e4e0dcf9a68af0b04670f6bd65703e235f04403456036f7d11264ba2ade125ffe53d0269b606c892cff12de7f7a2d0f33842d015b02c82fe69f372bd1e557024b1d95f09478a2444e563b0372e426cecd9a475bef983bdb283205ce4cc52993e9d86456e85a7a5d3ab8b38d62a384234ac707574b73b3b38d929b1528631b3483656c6b3aaf1c16ae96528c1bcf98ac6d33574b290cf7fb26139c9b5a6e98cdb0893f59e76014766917c3f2ac333831ecb678b3f5036dbd59d80d374a94e05c7ceb4afbbada254a7070660d33c1b981e1b46d82b11a9eb5db226c89121c18ac86670d862b9de3d7174f1ddcd44704d8c76a7a5f1f8535bdf976ae63e7dbb85224be2041440b09171248de799ece2be7de0fecda115f7e84125dae7d746f1fe11d51c4ab469031028cce6504f8ff88f6ac052bbcebc4957e0922dcf8f7186304197f6ce6e953c3f3be401822881148fccf8dc5708c197153012d2a40c53f530022e6ffaeb625bb26b362abb2b5b78667d06a25a3b85714598b46f9daa11f3a1e1f29bb96bf3ab16db66829a64543439fad41b2ab41c9a2a121599471e72924bb6b5f1e286202b45944173174b99279e6daa6c2e5c61d9b31228afc47504e7e52083ea32344163950da8833e39066554893c010036ac81c497cc81c563e648e5a00889870c3899850c2899410e6444aa8e2444a48e2444ab89d48093b9c4809474ea4841f2742021d341c910218f29916f0f8bf809b2410c3f1edc41992ea49d3546a81e68e5cdb602f9086f849420001c1f511e02749e027911a40c59530b76e317145894ac14a65c7b2b832e5b3b2d595205d8fded7f546d49f6d799f69c18e0e2c1304c00663314a8331a60790794988076c91ab6f66f5009fe3dbddd4d0d9a81e40e40134ff650d4ab6cce4800190aefca739090232009392a920a608424b1058644ae2be95cc4d0b225fae70d860db5965e11673d9a71be83f9157b909082e0ff80fc401a9dc3836a630cdf4ebdb23ce9bd1f77d3ba0b5ae0694b9ccd5f9b068144b9c9ab83934455b93950ee54a873a4bc10e7764e71292dd40dd8eace255f1b038e6eec43137ee99aaab953bb21bc825d4d5b2cd8dc445726665903b5204b3c412cf6b29189b19b79d55cf13e7d0cd82cdf3b16a79baaa6dd5f27489f366742d9051b62d7bfb00f6f601bece950e81f336ef5789eced158eb97b28dbd647bb127d7504ad75d56834c8da571e89f2ac85eced05ce3a6b2f8c5ba82b11a6d3f5f5d73f10f1ff3f5009c7dad2f3409b0035eaa4771ec9297b4070f6747594ddd1e2be56d6f748df6cb3abe27db3833c2ab2a6aa785f5391317967aa8ad7e04761d5e6292d8fecaa78b75df685e7fdc1cda118d8b199b291567a3699d89d83ec30bdcd6c57f16c96e258a9112339337263ac52f29b912377884d399b634a712da538e9f5df00377d67fca4205ee9a44718f70516261c14195bdc35fc75138c1bc405e176563659dfe6b8ad71e3e2568574225329e944a6a4d8c9b6353b28db164f0e0447a06c5b5fb6adced4f67f76d351185aa54eb0f0dfd0371df11cdf4e85ad589360b9aa657a331dd1bc502da5e15dad5ee83bf1d0cc5d7be4881cc2d8b6ecacc7668933b635f9c39103201a40078901242b3fa6f8b6ad52a19672547bcaced06ab5e46694370b366eda14430821841042102125ef68251e714b7931c1b9b9d90a0367370d06638273d3b23a61b9da8c63a1cd375b6738e06c7c03cec636e06c1cfe2018ff0f08c0b75badc022e0cc3db381612381ad0a9b14b62c4e2438573225e7ed2e1560828cac423afde2272d80a4800ecbfa487efd4dfc739bf6b5d00bf35082ff21dcc483153c7880072dff4e577beb56b6ad0aa58d7840bdf18b06f19fba8e6b60704dd63997e99d6292d0cabad858cb949624c90a8b39d7649e52944dfa8862534d04a6b945aef0ed54023882a9686bd0c8a08df1cb999542515e5216d1658e065c000d22aca0218122982023ab50d96931f7fa58b93bc1e95304b453c7d907daa093d2f80fbb69d6e52a3c0be2ef7030cd6cffc79b7a079db4597ec6d4b40d607327e513589820a3fa2a7079edcc014aa01125077c93dc30a4d57955954e5583b6dbe10d57ab1b861fdc24bb2659cb5c9752622bca556e2c63df0d4355cccb7fb9a2219e3769f36780e850823d02c562315788e72d96fa6fae3da380ff546e9a5e8ee78df4032901608fb34a69b5fbe8484ba19926093fbe5d1ec318139cce4615fb544d6fc658a4b6230babc96ac7322c5b8b73eda386e1320ca70698edce70c232a6200cd366ec5a599e551c91e61cce5efb8db876489bb726c2300e0c77c7666c5cada88db25ac144a80147e7a665329563b397e775645d47b63bc3498df28cb68444fac2d95b64bfd1e8e56364d4b1c9a36394732d1008ce1e70f6ac5622c0fa83d5fe3e5a835171c244bc5a55fbd910d6b389617956695dadf0929b9b9b9b9b1b9b9b1b98086089121b6ac0b9c9cdba7972727c726033a7639327a76333665f31483c654ef70ccf9a2b89149d29c90e4900d075d1851d0aaa38baae36b4f6de308d7972b57a79b998bc3645d4d130e5d5a0b0b7a3324265e5dd4727ceb6d57d2ddb51a12e4d9199292d7f275fa6d4936aebccb9632038a68248a121cc1d8d689042c395ff261a823c1a8afc1d1231bf0d4713922da73755ca36fb86e4ca9d8d64caf1ac9990e4a65843e648fde85703a6a609293d441837439d4a8756ab57ce8c28e7368b72709607769bb77da046d9d6b038abd1253232a1bcdc5c479809358399505360b0dcd88442f21c5947d1c1cd216c545379640ab43686ca62db60b023ae9cac52b973c47424045bf3accef0e5ef6cb2199b218b0f2fa0966986da5f402dd30c412fa0d60c43ba1750cb82d266b933ab1f2bcf5a795665e8220305de55f12c0c631d26234cb4b947b459e79523c38f18ba749ef7b55793126d46e11083f85f856360f2674b33c500248f1386c9038397ee03290f0c59baafbfc6cd21186a30043119b1c2c83482c20b3330bd80c40bb5ce21e329b45a7d331775b9cee186e357a7ace27954c0599378de449bdb078adb078a675f974d87c92bc786e7cb86679657a6dc669344957957c583d93c4e98c905980b59606d724114a9cd8527ef8c5c08d28298b7d0058c8dd6a7852c7f37d442ed6f61664d2d0471b130a688852eff59c0c2c294ff261698fc9d69051e8c18caccdaeb3232ada04557c533ad70c4bbee19ac7b06ebee994e03b17a060bc70aabe30dc7aac216930a569e4d2ab860fdc15488e1d6dcceb3710a4118a5e0ea810750808202cd3b9b535fdffeaa8d59da8eec1a5bf18ee2d7958613d7d2e6f0762e32c654244be785b75fdeb5d23315c9792d00650240c5df795e4d151da8e8800a6fbf6eddf2427b6712d39a6b51d2b602e00a00109132e0144715fe402b8eaa7bad9c8d658ecd7231225b885821c2e41da6f4ebeb22826b604c43b00cf1fe700893bfcbcd13c8bcf38abc2969df13bc0c994e383aa1d6e5ef04d4a94c8fe9d4a5a3a6d31599aa6fad63d1ff20379dc0ce36ca099b4c5d6c755e936909539037a5d7d97a269334090993034d42a4b84988159310d74d422a0d42c61484cb25085ad114c4ca4d41a69882a46ec521dcb909eb3b632613bebc8a0e295bbb51d141ce9a09564c907f173399605d257cf92f9a4a107320c5d354028f0f4b82a01575640acf1e5ab52e548eaca3d099716c7e5da9e5e1ebaf9a4600f34b2ccf54268e2fd3082ed30827a07013009a00009108799844e0e2bfcd4d2250c024c21393083784a08629040b8420beb362d898d5cddbb44aa7aaabf154a610949880e00048122620e2bb1b9ac2b19982e2494b436a74a90988f4a4cd9e9c5913101308606e02410b08a209041be68f34fd0863869b7e68f9bb9a5a038213257377e63a82f6c8f4a366faf1e4ff8ee9c7ef49d30736307d70e5ef26684d1fecf0dfc7f48189264ccb44a3e5eff0d8437fd3443345665cf398686c0225d090704737650acb8f0432fe130947c060247cb44a3b7bdb8713093e2712a4c575bcd2021c40e1a711f4f8df9d4638815cad56abd30857def569842127a2cd52b4b9c7be6c78be6c1e7700d002d60900405cae2cc00126c8c82a3a4964e2554d7aa452a96895e66e8f3d501fe88dcd5c6fb386bbdbedd68d8196dc60c312b9aa41aeaa782ab9c2b9512231a547df9498d22a55dd3eb2e0ac2d4a70f6a55e9097c159d3c1b161c9cd4d921cb9a21923e9711521c1507220ade5eebc99c66e154f9c432d8f0a6de251562b735f59b5b9b6fd0ced1401c9ae6db6ca54e3d1d616b621c5b9b6e1fe26cfd0e4a1d55ce7804f1f8cf961c8b38de8747503e15eb76ef1e026ae74a8738ea7ab96ceacccd8f674980ec953298e223f95c8e8249777353cbfc95352e293c74a8bb95c8afd0f65ae1d9e4a466e67957587aaa5b9c1f66931f7a2d14bd479b931ac26eb7ce40d43d869860b15a7190cfc05dc41af1f6973eecfb658b4c9739ad911c069868699174e33289c668ad0664ccaafab50914a508024c74fcac14f8a038ed3b9fccf980a61dae4914d6833d69f6dc9d1076dc6a4cd2a4c9bb18c29d8c71107e9cc35b9eac3f53e68fef311033eba9c0ff0367cacb007197b04f1ef91b307cdf5a85d8f13fee3f4e08bbf0741fc373d6062934799d5ca260f2d7f1e3e7904f96f838716fff1c0d9e091fa6a7553864c992d376570ab954d191bce83325cce83fc9f07363b20b30330289b1d60f90e72feeb408c0eb25c072fac832177dc815136770c71478e1d54d8917f3b6c5e871a75f8d401e4a7830b1de0e958818c1a64b490f94e26867f8e39e6f87218ca668e718ed73f07905f0e309723081c399e5c8ee7e08bff09c881d0cbfc717089037c1cf26f430436f860030e366a00c7113741ab151c2b4827b206f5460dfe8696ff6fb8febf71821b61b8a0dcc0b9a1c48d22ab95cd182dffc7dc31afff37e39b316a8cbcd9da46196f03b7e1fdbf69830838b14cb191e547ad56366c786cf8fc6783e6bf1103e6026b40600d1fd6c06b7c6b087dd2640a058253b6460b6a94417151e3891a7f1a5cfe342290462dd7b65cdb506904f97f830608d0d0120134ae87460b8d1d3462f8e50a75861affcf50e2677c674894183450622c204608536d106651626ec4c42086e629d46a457ae327b9f193c6b481032e7060822a70f0040e84f845904e648d5cd5066f166129b942ad5636b279335ead669e9f38362ec5710330c7b7fb58330bab96d671b5fa58b54ca55ca2d6677b7eecac1205b9ae386f46b9d2214c670e3bb3c2ce2c1ffbfa1a43f958d5aa7059458302cca0063320e3f5f58831cbe7a33c451fe5717d9467063d0326b28fc6c224f1519edbacbd707308a4c9293b0652dbcc95d5e5a6dd7cfb56eb4fda51862b1dca33ca53e950479ba9ae95b6708a9846632c71c48d274ff7d118c6f6caa60d436b6714a8f36c25026201c9d977266b0be1e65097eb31b7acf4084d269b299c0367188e46b2ab4175f8a3311b2f66ab95b9580a7bb8fe5a9439b0f19d2296cdbe163c9a46b29358ba7a321e7d70dbe6d0f702aa505c1fe5f9c9b6956d2b8b506e56c8dad74779689447b502a11530f90a30ad2ad062ea526feaf2ddd4e500377529fa0f4404238ab8c9082b371981bbc9881e6e32c2769311df4d461ce026235c371921f4ffc70fe44716432208a14c93220f40c3043ccc18e305680c0c74908132f54008270200706284c889f9ff18b238b9f2ff24115cf1938efe032161f11fdf4e86699844866938c6165aa55986f602759eb23ade1927ad21a11c08108403d08f4f0fcf4e1f7df431e4849349481f414c28a18f99590a703f0ac078876fd72818e197ab2f6cbc06d5c6172daff64bfd32a5937952db9727353c7e8141ae8a868632ae47a2ca022a8ad2b1c93343c5b0428c25fe37ebab7d64afab7d3e17d187c3798dba8e552ac3b1cb75cedb47b65a6b64edebeb6c5bb44aad8f6dd9ea2cb2d55954a1003163e500a62fb6f8c190e2af968ab36b7205068a0223a892d8ace5691fa8116dba70bff0ed6ec0d5aabcd8e2c510bf6cd1cab0cca091ac8f60b6d9b7d50a576b9b2d457eac5c6e2353175f1747ba98f21b865ddcd005935faeaebdb7ab5081dd3084897866ad0cc6e2020b2eb27031045051944a27e832faea4eced5552bc79d9903c13b5a03c80e8f79de298a532241d23cb2c3366b6b72da8c69961d5187d6e8b3160710dcf9fae8336d91c671ae6d503a9cca8d673bb2f3745e391fcbf3e4cc4eb9e3f52893cd58639bf28ae64dcee894d75ed1e6fe28f87d34046bb4d15e098273d6e36d4776366bca4204594c918510590051235152ae8a6415b9a2924455461636ff5fc8811483ef2771215df167109c3d20387b48b0632281fc5ba8c3e9f3630465c7258d76a4cfcf6be7a7e8257f78a490104b8a34fa19da69491c5a44429288e8253b0c82537654464111d7606c7e5030ebc32c2090e86b28b96d32fa9a79fa147d2cd308625446f0caacaf3bcf93b5fb1a678ab3318b8364d7329a6593870e2959229d481e9ac38d44226d4a96dc64df6438623c439ab194b2f1eb8b6dd861c98dcc538ae1c8834dc91269b311235d932a709cd12ab5f526ceb00367c6597a32d8d8dc8436dd8d273b6fd6d7935738715ce95017cb3d3b8c5d5ffde99b9ba1a5347736d9048dc2b1d5616cc559e3514919b1c926888dbc8efaba8efaba300ec7568d675fb78f6c8f87baedc2dd3e5023dc1ceaf091a6e2d877369951d93769b1acc966ee26596c9bec9b4a0d75b936f1682d7331b0afa442072a5e125331c29b4c01e6ff1454bcd2e814b8ff53184de1e3013d3225d1e0012f3e2c9903a71168adab5ada03ceaeb695ad2dbacd225c0ef16af559597f764831e66f29b69042f502c1d983afed866487f465935990a7ab99d9934995bcf13c9927716ca4d1193da2378334366316db6416fce1d9e1a1cddb473eddf8d964f4c62c96f6cb81194f30cf6c41dc219db8feea6c9bb519b78c629acdb2699e3715a6551b9b9b1dd9d5349e9e276d1e6d0e45a3339aea9851ce623ac5d082f26683c4316524bb1a7c6356e2e84cb4336bab14afe57937aa96275339e5c1aaf564a598d600154591531ea9f6abf44ed18a60533bbb2dca19ad994d94ccbd64979b364beb5c3d234f358548cacbb36929f2265354568964e705bd7068fd08c15ead9f211c7e8c602d22d6ab074ad1cba845d4032bfaf16941f1425aaba4c86e36b3aafee6cd72b694a2964b76f866ab4d55a995a9264ee5eec4b78fbe29ebaca580645783c196d74641545f396f1ff5cdd6640acb684d9c9766b398bbb24a0db033345a2aa3e00c65b5477006c6c24993d7ce5e442df932823294cbf48eb2369230c80e09926b23c3754fcb445ac37d6080498944a2c0ff192b763a4623d0f8f611ad639e362cd901475e40a893b6d25824304837a0d293b699bdbec9263459694d66c51f12195d2ef76c623cafec66c392b1abb56149f7750c8f3c7c73477678d656b44aeb9d524a422421742f6310e3dbad561debd88c59c05e5569928e4d1e248a4e03e50832ff6b52b9b6a14c4768f15f665b736ddb62025f7e5215219842488a2302ae99a7cf6af5f2569e9773aadb2e9e2ec2ab954745d61a94c4542696b7aeb08cc71026479b1b6dced379e5a4fa8e5936de7ab39fc434867ba98ac409b6122512d3db39374f6764c488c4734a1c52d9795e6e3c7b26bfee589e478ecc2cebd96d3caaecaab3ad12676faf6a4749abd4f35eb2c332ec5a06c39e797eb24cc71e3c5ca9e7f5f56a640ae5c999eda3d4eddaadbb591053710ee1ce13cb1c288614e329e22379caa8271b8ff98814d9d9489b5344b2cb79369992fe488f4ae3aee27954640dca2e17935deadad4e7c970f6cd581c65d5f6ed504633b69536e967ad3853cda40fce40ac797f68d5de9b8ca8261b87ac7d7d5d6934375d3d5f8f40b6d939f0ce9f4b43040f3f01a510840d3f659c82f84f7702c20112d3d467bbf666935930890a88151a20a60155346003a7060891ca382879d6fa3a9cad0e67056d2ccc1975ab93f88808d4aa23386d9d291f967c01b53860c509f9759eb14ed0e305c802c87c015680382d20c8cc185a42a0009b5f0502cccbabfcf483eb3f1f0948e30d946ba0ceb9d8ddf9fafbba6e76cf5461ae4776337b5bccb6957382e48fc97c38fa92768518b4d6859be1572d4fa56198c7f14d889b61187e3defcf2957f31a60ac13ce02d98a18a4b942790f6e74fcc3b9b669c135dc7afe9bd3ed74846fc7c2210b1ce57c860583afd21c88388d3eaa31f3718c4393f3d720387b3adb166681a014109c154ad366c8eaebaa50be1b5c38980b167a116bccec5c8f4453e62b898145a88718f0ed41b435046d3c509ada4f43fb69663f4dd3503906b8fc4fc20afd453d1506c71d187b499148e44bd2206553b26cc6d6d664df8cf598eabadcbce5c4d1e65216f3c8ee2eb91925a661387be6751e95b9c3194876b2cbddc993c35910a4d9284a6e82ed03c666bed628db166e0ed9db0798a9c9312aa2766fddc24098d651de16716ac8b5ada606859a591aa40df5769ee0ccc9f0cd0a59dc1ca2557b6dabb26e7f976846944722a35b0359fb6a61dbfada04ab191b714e043f1b8619e2797c3138408b1901c85e9f241e23373fc5640a312da68b89233fc512e01345ec49f7d1d813a798bd499c6696f7d169ea8067849439c220387bae840781f3849d59b98d768c8a721bf518f584b35f5fb5b7c9e3c3ca34a4425d976b5bf7e51ccf6d9711237536b6f99b9d8c762e49c3b1e2b031ad3501bbd6b64967aece06a7d10d3bb3721b1519e1e6d0d7369915aa50be3eb2d7b69a56ed9532c3801bba1031c00a277421bd30a5a804526a202505ff6bfb60fb029da430406657632895f575b6ad1dc01125cc4f513ef0ff1425caff9343f5517b8d478a9b8236dbcaca1f8824d796f545e2c3da911d96332b8de4c6466a688ce26a451cda6a655d292ae3aeab49c9d588bb6848092757eaa4202b1d7e9a0f37952b303bb49a7cde8c03c1d93342b10288f77c932797c5f0e7350c05b1dd19f69d61828a93840805bd70ca018c08760d761b268bd9aec53c489b73b82a950a9cc16a936200cfc58900404a2c9c581cf8e1ef1cee4e0eae2024da96a4cf021ce21069aee119245291be6a8b44f61b8d667a7010b2df8849358cf9f3ac2601c1ff02fc0414c4e967023f43c82b9260828cac020395cff4e987e8e443830f7c887c06a0cab31e564fd7b3c2ff138f12279e089c47e87265effdf969a64703a3c14283811d0ddc548b7980f5771b3706678f1704c71dee03c51dbb3355fc77fdf42404bfcd5abef58eb15c69e8e40d9afbfa7b9c9a6cf95fe53f101a1dfeff343e54ea8e0fa7d5082c985cd11cc000ffe9069aff0d830d8102f62150147d08144f3e040ad5874091c2874011c2873c91c7873c31c7873c91c6873cf1820f79028c0f79628a0f7942cb873c51810f79c2011ff28402fe8370326184144068ddba7e90811faa0ea994131d27b206f751549eb5d0aae812e5590b492965d5010112f75158d3be86fdb821841f403ec003054e726890b5c1920d686a40a344ac8892116c6d2d4adc489574e2a4d635edeb224e36a4c41af241c0c009478de3dbe53459a16e6042230092a559a2448dfff7a71b2fa265420365e0da95b44a69b4197bec53b4e24cd07ff0279b2dbf6188a38ad9645d270b435a7b2f6f86f1d8411c32fb852e37665428a1bb434673cf334e1d11c7b9b6ddc81c945fc9cc13627e1790f929eeb7418b3f851d7e1292dc06128ea606d2016870fed708912795cf6f3a9bee4685a3373f8dcd4f93e4a7e97e1ad54f93fa6968f84f4383e475fc76a48630e11f98f03ffc89063d40b065204c71a22101343527e1fc77c04f48a47812718634289a2334339cb44314d29218664c98912f492919b5414ac109257442a13e53e674240a954a95e4d6f4e8f611d18c28ecccc24dedeb63cdfb8367440ddaa20af6e08be7fdc133a28f655ff86b0b1465de9fca9a11cd8866445f0fdde019d1edcfe8f5099c64f061c0b1fc595c8c43b1c32906f03f1e9ff931c329062028793bdb23199be17f6c660b2e66ba98e9828b8e36c6e4a4b54cafa581537a3f423c3b413d3b3f452d287bccf4710309491f1e0ea4e99d640b3a0924d9fecb7e32228f6fd7e4bf1590063bbd9080d79908cc306066088cad586122c986a4e4249b936c42567beca1b19c9dbc758a463f4909e5e40216ff379e5c005da8fd0d7e2c11376dbafe5329210414b880a3820fc81b0d64c08686150029a34200c2c8020051061c133320f1ff2c2c2183f8d38f283ffd70f2d38f1a7efa21c34f3f54f8e9c70828fc229851e52633826e32c3869bcc30729319a69b68a0c77fd309ed03c535f7c16aeefb495cd0e0b033adb9af8482ff34a52f176d3eb12083e329645f27168448604e2c00f1e2a71572eab460ac24c65f0ae384dc91ec2f81f197be18a185eff0930a2810022d1b64f137f8d559933fa59000d7298527a7146c4a5e7839a52076f197b8f84b5efed20948574a5b944c70d2cf0985389e2fad6af1794e087142c106df0eaca941655ce72ee33a5583427538f16ad595d2eacf67ae0831e39d8a303915a1f9acafedda1b482bcd5afca51264f19748d0e52f8d40047f090b2e7fe90a2bfe52155bfe520840f0973e40c55f9ac2037fa90352fca528a0f84b4f70e02f39d1c45fda8096bfc48406fed2124afca50c60e02f5d20cb5f4ac2027f098923fe921115f84b14c0f2978a98c05f226288bf248404fe5204aefc25083ce02f392088bf044403fe1203acfca50528e02ffd9080bf84001ffe520ef7976e477f69cc7f09dfbfd483f8976cfd4b21f8976c3cfc255afb4bb4d95feaef2fc9627f697a7f09b6c35faaa2c35fa27280bf6480297f494a94bf04e5f5978c8afe52015c7f89a8f5978684fe520e0428b182fe120e407fe9c7e72ff5f0fca59d277f69003a7fc949ce5f6ab2fa4b3730f94b0258f29794d8f0976ac0f94b37367f2949f79754a9bf440392bf5483fa4b4766f84b32c4f0976030f2975e907fc985120b2bfc251552f84b2814f94b0120f297869cf0974ea6bf2424c85f32a184bf44c2087f090022944200f29740f8f1973ea0f94b25d25f9a2991fae0e327eda1c74fea411e3f098f323f89073bf8493ab8e327d951c74fa2834c09349460c229ab34a8d4f316fb2a788866040080008000d310603030281a0b86c311915c382cce011480015ca662a2604a960a93204621040d410608180000000100811031dc8cb207b9e67caf7dfd131f251f071a37d4b5b4b159ab6088e53238ada2392b2069fc0810a0e3f1a6d7cc9d3667bcc54034fcca1d7bd321116a8191ab4f7b9a6d08976056b23f4d0acc4f0f00663eb14b52f61215a76a7861adbbdfefe1867a9281ed9c34b70b23c94ea93d0cbeb781ae3f284b3419137cc7364fc52299d0fe8a6230a96ea57236a270d23268aca0fdb4f7b200599feddf15085a16a306738a4974499465a5523b429da9dbf39b6a6e36d21c79e2edd6e5666e96d6780519d561dd7de0fc25b5f819a5ccf04c4cb6cadd47ea020a0237323c0a7664cd109aeb5c99d1db48dc37782dedef81b93703c9c73d52461c9f6972f4f5030af27c5a6c13accfc136bb70de15adb315810109de1527dd5d008e7735f2759a82f6086a6c2e53184852b61c74a98ff146258fe4a645b84c96f61f56a36da2aea073e83972892d5988d39161836abc0333ef9a3047d7cd69e3e0ef6c692a2d746ac9df7f34b5e8aa31eb9cdb9f6c08ca930866125630e3fed917edee7212c0b0d20edd15362887fb74821cbc840ae3d2a1bd2410230a08362d7377ccab5b6558e2a2cda33306411e79ba3e3a09f43e4dd2435a4428ea3917305bd00d04520a9932af11d12768136295a657f0fb313008e73e2d1c8e89fbc461c4effe15486bb62394c18539385547401add1c6644a6fd0cb0d2272491916ff11eb61f9bf8ee1c8d77559c6da812f328f0a1a8daa47b8973e5dc36e37e0ded029ded51594828ea14593b866f54e8bc600bd9821004dac7d6198143cd2e67d4f5726fb083c49610a164fabe92c0361d90dad2bdcc75c7e1cecb8794cdb7e75ddda03d5b0a6d2a06db389f4d6993677c3609cc766007cc615fe3cb72e7993c87fdd8ccf08003a11c0f558d51dfc32779b082e562766da87fc341647b450ba1cbce3ec201560019e033b5c56591bd8d464fc7492f5d7b0f385d5bc37df20d0394b9321a771d01f8e2ba5aa798205e3a0c8d004d9580048b497e24e21ef00909994cbb4f5eaf88f29af30f4f03bf0f6cf18859f8eea2dd427fe8621d5b9100173be5d4d08f5fa32613c2111a73e5a2a5a3c3b4852f0faecbf332991ec0d19206ca6940968802013f97b1209d5df894e3753e7b83c83cc9bdc39bf151589244137074384ad71c8e8ea85ed96f45492ff5c2941851ff47ee31137aa54198c8787a0aabd89cd941cb0efd161cbc9ccd1c12fb2ec8f800acae3d5d087b87153a63c7064300fdffaa967dfc7f247de94b4a69a3b76e7df52c3df40e6e18ea4263cc9707341c84570fe508bd19a15ce70f546d3330c120845f007765cc5ae6cbdc00046ad6a4c1c4a5b56771322333ff7bc8715f3b7f4221f3f4c76d1fb8e8615bdc032d7cf63572961a3159ef3e5773990ad374af8276902d4dcc9f1f6657b2189ac522c925176c86f1eaf903f2c16aa74edf5310224936d89d274de1c9c62e22ee47af804722aae3b4777668348c9517a03219dada489466e05a865fea0b0f35fbb0ec0aee1ca1240454cb9bb5c83c5051fa76e896be03cf02ae728decfdac3adac6b3242ba041bf9cd5aa53c471025df9046c923fd2fc8de1ccc18d8ac5fe3c93be328ebe4efe965620aec12a1ee6d122fe799b7e911e3a6703c76dfbe93244e9d30002514e6caf9d819abf6b6db3dd230daf98a5475450490aad6c68e15b3b57ff3e13412fe10154f0fa7cbdc3bf30bccfcf4d839dc2c6e4f8e7b79d1b5212a11ba5aa190bac3ab5ef264602f429848062be4fb78787c6aa1e308f478d83976f4757451ad79936f70dc0e4e1ad0bc12deb81e48c88bf85b93cf75f3df563dec7f76a634a2e9756ea4aba5176aa5d89057581c7d2077ed9d4275369c132ad593f6a633d1d55af553ad4f2fbb3098f6cdd37356afd2e93053eb6e8592d72eb8c1d48c6fc438681829eb2533bf7c3f3649c406f0feed64a5ed70a7808b7fe1be883b76f774de72e9c79b6ade08a4763539b1275e88146124909dec6270dc736d2c8740a5b1891f9b893290b1e70964b3901cfb87fc1a69eee90af87563318258460fc40bf9e9a514d590c57e1e4d49407ccee3ca3ff72a93fa611feb4633c7931e39b3abb27be1e28de8cf72b3a77e3e59f5cca0bf22bb1b19eb6ede9f9f7d579783d8464cd278a142f3ed175e3efeaec42e8fe75a75745d4dc3b8d120c5e85a60a181dd43e6d874f228f60d113d570766e3d75a64c798b4c0a49730c178befaa7247688fe8c691d5370c9a5a4ea36442e80069ad85e3f5049a84ffe7814689509bb0ffa79f12a8ab2a25d59f78fc03cd234ff7a31d070754a7ecff2a9f1ad333219ab3092ed7d1f5671cdc728b53a29a7f8bd0e816bf992e0e8ed4078d5a2cbeee9fc268d7ab295c31de22abdc68d18f75cb70101c4e8cccfa269cd01f3c066968725d1ca1aa594c1b78b2a0e2b337660aed183b58986abea05fba9137f70c5755a35f43f233f118b8d0c4a4300900c7b342194fec42cd1c35fc61a68b14c4cc4cef18653549443b302e05a17fdd5be7c43aba5cdc8070f1d3fde70f0694ae760040f0cb7129f557bf5683e90bf2a3313f2d888919e0c13d3431084f9fe863b0160c829e74b712eee61ee048cf54309c45670738b0e07daee47358e137f0725b8ff714c632e03d4da7981214737556334cc80c22de5025859368e36c4444cf8090200377846e8bbcc14a8f68a90c766438dcec3265d62777e9b87fd0d941bd64b27bd9baa73a9b329897ea95ef8d5dbf650edf6fbf01c27ddfec49839536ca96705b85c55e64325ef4d637255c050badafd2b835f47899d577080a119ae5fe86f8f4b767d7caedede41c6288f733935efc150104fdb9107475575e7120e3e99d40038fb0986789cd0e39703826660e6d806fa7e66b2f03b76f9dabce89f02bac01657f4de732de46434a63d10c60b763d391c32a27f6df9ffb4b6220166ebde98656054d8db75f90298a5728f589fa8abdbfef075b3bb2659de63b785260d578279f9d21f8ce31f1bbcd256dade08bc51ff2d4e61300f04630d34a4431f36d8e003f1f77d331d836503d7c70aefb2bb445311246da102692d8405c32db5ef165d3051fea421387383a6327f87b1b059bde93ed3ba19ab90afe6d7f645817570428750383db0b7bc134cf19c7851de7a0da80224cd9e7e9d180c3d16e6c2675b2a032dc274be15234130eb134048f21744cd39ed4cac68d7542656fa3453f7edcbcf58dcc63eca4a25593f1f4b89f783f54f1a17d71f58f994b79c8768e1703c7264a2e1f351643ef2e65206fbea342590a9410dd497894396734ed6062e706f78328328f57a8710e68dfc590112a2c1454234c3490a032a28b4e156642265327af9d8fba26e9a6562705e75e88041260844837cd6630df9bef4fb8d149c1caf436f21b181dc0aaaf7a44004fc385129595e7642d74dc28e06ae675430bc0015f00f7142c06de1c34775860c620fc709a8b3beb258fac7a39c4c6260d095ca0c1ceae808b3cd0a1ecc185824287180ea798d8fdd7490930e6383282e084829d4a563c46f993e273aab42ab19ce86ed1b2803fb690c39c1e0ff15f5a738665748b1b720ef453fc6f6027296edf4e3c25c38cfb73c912430bd24f9e1db883fb5d1718e1776527969322a6940b5302553be7ad0d38b65439c62a60c1fce0d624a9bde9201abbe2383921a14badd2a03e6cda9a7b3613ffe1f98c0af80e01c3c2d33700316ec692998aa0257ba0a28e3db2ebee48a9c6b2e8d34bf4fcdf8517e6a4376b5d7991fda88b4e211563b4637cac372627b332a0bca95a509a02b53ff2da5e23c3f9d3819bd8fc901c1f01089cbf353c7bc81478d1ed23820c50873cfd182091c3a90855fdce96f95a037b372cfcee7cb3f3d1b354e8672e1edcb3732e4d2b6781f0fc3b017dbac9058d8f7ae79180b4fa65f7a89d3db38b18c02d79f3039479ee216175ab670440a7a01aa61542a32db3130e1bf5b47212a54070875d79897e1c4c16fbebee3d9c9efaf095a8f74356ff5fca156de3b9cc021c03fe83779cbc2a62035f7cfa821d13ae85783f2b4ce01d258bf391a270b7fdbcebb1bb34ba129ceeafc8f8dbcd887bc8a7f60b213882fdcae42eb2a3721df0c118e0bf7b19d6b933b54afa690dca1a0b397d92921691dc4f8b7ce47835db46843b7c743e6ffcdc50b6656ed36446333343e18bb9a14e3bcfb14ff775a4d29c6f5f3d0b8c1b41e02e3daf83c5926eba57ebbdb3d1c34b1202638ea75c913fde95c21f5eaa35ba82a4a2e19d86fddd48a81a818ca297a583f916569c81fac6c94c9ac6b8defd222dc17ab32f65b00008535534436d6f70e1d8812f646d8e29325f84fb272cbc320372311ae2ee3b1e3d9efd6ff5de51a72ec19f3985fc7c572911f7b4377bc32d81c0da10a1fa9d610a64840da53ce1552138c3b47f02960e699601098bae6efd8806bb10d249a8b9c9aaf1b163622629fb46de6395ca71d669cab3061e5511d94a17592571dd398cc9b4a8a0d16648b9029380af2d76997e01ec476cc526444d462bc2807c4154793450c1a5341e7d4d2a00259549beb4fb8d1059e1e30097d684c72176a9d2b0d30057d87e382392396abae4a434136a2a7736ac29be4b23d3ebc063f5703a7f058f4566e3e43329024dfea141f6f940b7f9929fafce472a89adb84390df134c984a707f5291f382c3f6729845d1af624330b5f27fba2ddffb46f04968f15e1043c5ac6577af6f405f36da4dd2e980632ea35f4a6316cc39fe44a9c2432fa0fa3c014f2d270de664a6b5b8b539dafce632c092bd97a5aa581a13b3c216e704ac057bdf6d0463de8cd2262461019bc8dfaf31fd079f657905e3404ed6746fbda32d37cc5369f7e80ff109a97a6eed9d424e9ba6f94b7f30997ca52d47aeddfe9f338800d69c342b1b4c102e99db4355017bb1bd05cd2b030e79469f5aab1cee53c6d10fe2ca336a51d7551a2d63dff7e4af84b68acaecd6aad85a26ebc9ea37a98574b7347c705e86325f68705a211c452655f3ad1601afb7bf27a934aa69c1e2cac70987a746f60924c4673994d9aa6126e6a9fa63bee0740e5b97bf9003890a92ce13181e8f72a999be6aa68e12f5e9640c590015a404e246356f946624f75f09501e4a8cab7fd43f7d79d4f8d667eaa3743918bb3a3d01e77867505e65d78945398b44c4d3c78b1e0837ab1f0d5656cdebdd8e13ecb02d740ac3cc6ca87ca8c200f44530e0469b8cb9fe7c20a1525b8c6a03ead5d581e1f2841ead2b1568962df0007048d605d1ea08d1ec16bfe579a99d5745b57d335e8e1b03f944be577a0443f882f800ac4df3f0d77c88b473a012fe908d0409db527d4b2322932181f11e7742d2f5cac4fed3fbd304de9480b92ed8ae96230d85b009460df7003c1bec09ac0081f500aba88a483ce6055d8143a0e02d8573a57af923617916e4af3e711e2c46f1fd177ef0592d3e0d7a6888d0337b4d457a626b45ecbf058fa07c9ac09a36141835920709b6a99879ac726842cc213c12784a7477718fe92fbbe2811b47b9c926b19e2076210fa007d66ed13a60e1fff2d4ebbe66a2f32e6b69b4fb09907e5ce0cce4ff24a48235fbb3f67011e7af78762e0df673f99308b2aab27dfafa7ce1742b67bbd46490e130992e06f52948d82e2c28c413bf347e7dbead023acafe6e2c8c059334c88afbf8b853851a3c4ecc8da4ca75249c25d676cbadca178403c37d02b66d94c69a53c23e9b559193414895ab280c344f4e25515993e97c0f3f85bd5fbfc323e5982234b437c91dd358c458c4f3a065043cfa078e0a59b0da688f58e033ecbd3c4674d7c4d5eacf1022d8ee428950c21bc1aa01831f0ea77e12649214ba82e494f6bbccf471a4aae53e03cb991825b1eebe41ec30d28f3b168887f73fb4728d7464c5486eefb14a2910df45893d4887226a1742d41f2208fa1f42d81d22d7f907ee80a974303b49ac71b18e7a4fe3daa5458ce69e8961fe147238160bbae918d28af219fce99a287ffb4013d0baeec4c6295876e8988d1f808e3a7d8a288144200a53e4a85bf38fc6dd0dba2b52c13d53e51e392dd294c9d59856c8fd8d952f4ff763d0d71b083b6f0e4138148ea29b69a7ccd3e7e4be0b5d117f96637a33ddc444b2025cc4e909f7e136884f19f00b681bcb7e542f8b2050fed5eea2d4d3732f6cfe363c5a40c548f72263d03a0493a004caa57f708646f032509c6480407fdbc0a603011817902f7a8aee3a4b1c375ecef2743bbf2e8449068209cc8f1ab5f7ecb2bddd81ba039e4e3c70069a2c1206aa2f02740fa350c917cd83c4c388c32fb1126dfbed7f1c75c72068eec139972af1acaedf3efd2e644b6b23cb6a0aaaa7e7b2b20c2a6f62a5a65951a098f13ad42cecd88e834b6700e24e6c703b4e12cca0a8abe58280fb02868dc2d7e9b805cab1eb9a289177b6d71dbb6543118c7d629005253e0e94b11cc02b269559b18cb2ff7d9ef8182347d4e2283b5281e2534228a15b29b0ab2d24e38701470a8540bdc34f4c35a2c414b5c93b4105129aa6da4e7f7c24a683219dd08da17430d2e604a8bb5ee0e5d965db330d3bbb657dea34c10fdefe86c7387fd97e42eb0450c07e54bb616e1f6f96a4db17a60b5d4bc5665e41f3868e869948f4368cd1d9ea1c8d17ef336644d4219a6e363f3e276ff485a6682c1c8dbe96325bbb943107f6f01fd00bb5e57d95fb7cba6627ff0498cda1eccf301948e3dc9db786028109c916bcac675788e529248abbb98d6b244fa048a380287a498563102ef1a858866047f281186328120650f730ddfd89cbcd63d7e4f6eda72b05cce0abead6b7af57a327d49a156bd3ff31ab2ccd346b43d6102df9d2156dc1601be94caf0ad6f34f850a33f0bfb60759c8ba25cb939bbdfeb8537d0456fd3eaced1e0d4df2b065f2dfe23af89fd2de4b1abdab4368cf23e4541a47f5b2d1a5239949e8d201fed940f84e15bf16d05bead1f6586aa3fd86a4fe0cf6de60236fc7660b76aee58b536e3959bb305f2ec0407ae01ec7cf0ed9f77ea49186ea6d3fff03d9a6fe14a3455dc888b640ea65e96fdb62180ff110c572835875c99fd5e0a10a6a384736850986fa1dddf5537ede38d6fc739a9a4979b301b645993d4c0ecf84e3b105ca5bd6943d9cecdc3af42550e9de0849f16ba4f73d8e5d9cf12bf99d04b95ec89f91724cce7efd83856e3d8c7a607f50f7f984dd3f5a3b19a463566dcfd1629037062333039cdfcb4a7e4a662e75747925c715196face213f47d33c2a6938132c97849c313bb5e8138ddc4f673606f95b50f40e08662d76ac8ccefaef56259b501f74a33382777f6cddb24ee96437ffe0632e000e85e03dd6e9b730427fb78223c6a6211c1c3a47994272aaf9c1d7509b5115d32d06fd2f30d6409d7ab07cc525531b666cb76e06e6e7173321b7c3a65f3de6a1f4cb22747f12630e2ba4675de69335261c7e4f799f409ee9b920eaf2e369a65a67494567bc26bbc66770ad4d26f7636774f0ae2c540620ab1612767e62265d261ed594d69c0b033aef00a2a9cfe1bdf2115dbf80fca1a478ddb279f1bebd152ff6047d403034e825720ccc3254bce6b4436ddcd74b31bf1c73e6deea0da7a7aeb07e97792196018cebe8ea004971999aa1d766788d24d9e63ce62fb0fff6cbe52c7bcf0a92c557bf4e2f5a4475c3cbceebab3c650e91090c456824cfec2ee0edef935f9d823989ef462c52510514ce19839f2f58e7607e73e717eeba758f3cccf0c6400c3bede65fe9fd213a17836828677ec53199ededd8445107dc1b919608da30f88ed7fd0d98ab08f8718be30803fef8aeddd8c1962049d2c8814508c2aadb48d72c4e6c4bca3de784e9239c95919d1833e8a1b785cf9268fb7a9631041b8fb258ccf5a7a6dae6379810ae266283fb74184cfeb6e6ec44288fa2d00327aa45883d81e2b23cbd0815b2ab53f85dd88dd7b937d14e80fc7bb4ec2378d0783830adffbbf7972573c75f10505fe49a6339978b9ff6c67e1dae7e72b118a6b8a8abd6a6f06f288037c835fc4301561548fd6f67ce41eb1d5e6d02265c9c8334920300369f2b847d75ea261191365bd711783c0b637d7ec31a9385b9e208ab90b0ed963bbda70f61a1e5e3db5b3fdc575dde27abf376f5f4eaaa7f70d50f2d4b30eaeb91146d27fd23c18ab934f2350aeb7c331131979fdf7918178037e6065b05de8be0b754a547819f1dc53ffd347475080dd09fb7cda754a87b1c0cc4663dca4a736a2c8d252e9bed8e855add17abbaf128801a4bdaf0e880ca4e73eaab39f8ec0e5b7dcfdb64a82c81c36c81e5b36a7750e885793a3b8dc0d5d528e358438827dd65d51133e744d617daca30228057ff7e970e2018c5b2a64825f6b68796e9ca0e750774c351a1c6d823ae7699bc7be19d977c916e6e4f2af81511fd3453a63d20c2ad3c51fd6313e3ad8fb03aa977345fd4cba79d302f935bb812a83a3fc83d3028760aa75c35fcff765a3b34b9fd779e62c72e338a528bedee867822a16d6f86d4491e72f1e362d9b4088fd3b90bc5643330df50fc51aa2e939d8d46ccc92fb1da4ea83dc0a55fc9c90db95e2bde8379641eeb732fd2778e38906ceebcadb8c73751d14b8cbe8021f212622fb0a7ef0c969cf5522cdce7825eb046931e4cc524c9eda21a7f2aa55873064dc5906efcc11ad2393310125d04d1289d990511a202e23355f88c34e3c06e69103c9502ce08a9a6e0779c448d9357ba1d8cf0035743cdeba89167585c678bbb0a5fb6d2c2d5575f60bf03a2291d29374427dcf44257f870e3b816f61484156037005669b05bdf0a9c99facb4b850bafc79ce30aedfeeefb3db1ed11efeef11f2e6bc905ba8694812b57e29eb80b714b25f945b913fe8b791e0e7ea45fecbefe9a42dc75a86592f955bcff87b383953c03695d9bda845123e679721c44d5425afc8bfa09e43fd9cd4b3b94c8161e283c4d44d15d96eee410df3a3ae2d86240d8e4c6ff4b06ff38932ab729e5b428a7e372b18216dd6f8793cb5be5adf2bdff3ddaf23439d5445ee03941e20e409fc080c32185366086f0512ee232efd1922e463218b45c9e07621dcded874e62ae3b288e2d897230f9318a8f8c1119fc913e0face88776204e63f6bb439a902ea5f19e94e8640fcc78c32274b00fd8b23b8931478ffa9d1cd090a7cff72e4771202e53f30e2397902ecdf19f14e8cc0fc678d36275540fd2b23ddc91088ff9851e66409a07f7104779202ef3f35ba394181ef5f8efc4e42a0fc07463c274f80fd3b1d90db34c5e408707ec6687d6203bb5f35929f1401cd6f18a54f5820f75b46f0932800f34ba3ef130ddcfdd0e8fd24057c7e61547d0201bedf33a29f1c01cecf18ad4f6c60f7ab7082e057e990fca2f9cc68eec40616be7aa43829033adf30ca9ab040eeb78ce0275100e69746df271ab8fba1d1fb490af8fcc2a8fa04027cbf67443f39029c9f315a9fd8c0ee578de4274540f31b583b69006f3433b1025b5f1de94e8a80fc378c32274c20fd5b23dc491400ffa5d1cf89c65da14f730c7721932500ff4523989314f8fea179b307d9c6df8e696206763e6bb435a901ddaf18c94f8640e607b399f4bf7c440f7cafd01741fe1662d385fa3df592b8d01ec7bee3d984da100420aeac319b5b39dc8634cb649be6b2cf9a14809c1a57c017391eeaf3504127367fe3b5df3c0cf37d0834d9b322841a760170fdda60ac4a2dc888ede59c95bb326377cd5ad1a0e727f07d69befa3208e82649af61b959abcc6dad7c1c4e27399a1695bf9b68bc4bd95960df52b70bb3ecba73f6e65eef28d5ddde3ed07fb3f9c7b43075e965576ab770e9ae29accbfce338d9ab11871c41ccfa5f9f5ae738c399a20d4280913c14f6d7df1f4a749e2ba1c838d715d958dc1ae6fbdd615469b60bd11a4344e4631b134c43e5713e0865d8e6a5d80d8257b1924860ef53632d82e03a8685e03542a8ac8d1fc1153b54c89dd9dc24598bda69906e3a459d3e761f4229bbf626d91a675fa1069d1bdaac424da58d3863343e639cd162ac04da6ed56771aa19ca900ca8078cbf0ad43e266cd5b95e3ae1d486c385e8f31fe505876b09e5129570417032d480ed967d8aa27573c3fff37732c0c670bb3f16995d1ab006973d2fb0ac7722fda586856bc5ec91633cd51d8f553303aaca73a8a81749ad049c4fb675bf31557858b7594cf07ab40eeaffba8cd0cb09b6dca8edfc5ef9ac12f743c5c6c1bf2ad5639e2650409982a67d5e64d134a40c9da9c859bbc75e3456191cf2b69e2167a480199117006bd42b758c95ad94f9605041ad7195af5300161998e898dd511d8d32ebe495a15ee7ccc1f402635a58bcb19436bcbd4f49a0ee114e52603cca546437b46bcc7cc3758132d2950211bb2216dbb4079ce6046d185deb932f404f5487dccbd86bfce13506e6b39fbfa49f5782eb99ec20e937fe79181bd76d609fcc3045803583b632ad33e8615b961b6d0564c591b45110b4b6579868cb204b3f16c48de813c54e7674543a9ac4e2e38c0546f90e1c291c26f2f50074127d57455f858c2d6ad883a87232f196396b4e11c98b18bc8bd6c648032c10c0162d3dda99672be8f0c30876769617ef31267e969b64bdd3f27aceabf2fcfaf2c22f852652b4265d7bae63e9df0dfb075f2a4f494bea418e75f8d62e1fc1d0806ec4232d510adffc047f996be360f55b199d07c0b06310b03220958bf324b274457d130fe2d65d5aabc629a471c5f64503d892f8f4da579eac71f32fdfd9902da0be72e5ad151bbb15c96e3d2671bff1e95134d471a62e6ef5b3e4ef16931d86120b88329ba58b1fe023b85351133a6fd15a7f91e250ba9cf2b84810cd9ba892fa57e6370fef33be22b347c2244412c70b9593aab15269354fd59fa1bd1b8d266cca007fc4c72f1e2a2a972c5015f755a8cc397a7e5bf4df8d589dfd0d51dd3e813e92213af6a67bd7f25bc5e3487ecfdbc7b9ec93cc0196cad34ff52128e8d80901ee0c13560a020d7d6a3f06b8a91b3dc32b87892a2e0697c07609c04e9cfb21c188af7232849cc2f64deb4dfa24192a2e1349f9b7679714177505a2fc5a36773aaf7b193dfdcccc99d30fb8893fa3f1db8ddff9a165f3f9382dfd9687499b1f5564b9930b26f96769f872281a104286b5f967a363b71d0fd83f4bac836888933939fabdc3ad5b18cac6326b23138ac5ee6600a7e711d67620b4ef6cd880555ed1d31161ed862aa10bb3d2b4ca865bcc8bd944728e847555493185758917866449740a4842c7e6fdd104ba0f37006470be077d1ed441f61b64bca852c714146ea7ddfa4f29146d3611db42ebc9fa7257efcbecfc8be9f23bfa6fef0bb9f964278da93e7ad4970b65c67f404be4fb5f582de9dd3e8297cbcd8459d1cf37de3c4c582d9dbfe0e210fdb556191445ef33f82cad653ea3f15d30074dc871eb67393428daa39241f2bf7f3398debfe55f2cfea97ba2a11b6900f1a7d5ffd77c5f2616bd2bcaa9893fb1b1c1737e8947d9cad6036b8d16fd71ec3eaa254272f59d1729d7c245243d1adac81bc57aa1da06fc08057ccfb2d303e9861fe470ae9568039b7fe88cd4b84896526949addce5168ed37b77e5482dd9b7093435fbaad26ff523250c0b2a676ea1f931d2199735b6e20fcc7fc59dac74bc689b79d9a4da49808cded710e2c966920cf27e1760c581f2d1b144ff0779c980f815f5f9ac561416574100c2242b2aba18661fee1f7736715724b20da13b46eaab83b618fb69ff7ecf5bd11afa52825e130aceec3ff91838d6beb7644061796fc3ca9655ed06f847a0df6d030cd2afcc83ec23439088891339db30d7e6f6e001906f4a43f0e2620e2d8291ff47733fa9bf8c8927373aab775103d33776fd21d04763334ab32668748ba2ace4e5f50bde05aae6fc49ba74233bf06dc562fd0c89ae626896fe318e4ffa6606bc3b42f73b253af9f7c0192971d24d7381d97d4dc47ae3c9079a6003f6c47fde554cb91e48b709421f1bad7fe33ed4306a33f0a2a1db69751143f690f7cfee360a7ca86a8179bdee868843247b43cd0fa2f75a3b43681febc10b2c0f2219e13414d86c657c77ffbf6bf4c3a6efec013ff035e6c23227e4e99b0fd907de9b58d02fc2e6ae003388720f66353f6efa8449ae7c0ac18359ef7ebf0c9349100c0c862c6ad2064f1e8ed5342ad701e3ac588595a6881f1ffa81e00ef4e9d82e02d20adf7fecb2614be72dc5b1c874b99fdd89af15853977d45e5cecd9c95ac2555b88039afe852f23ab56214555a46d14ef6bdb8f2c4d0d6bb72caafb0c21c17a3563e79938cde2edc8ace2389ba31a846df4c6bab01ae6d850cb1654d774573c71e3c09be5ce5c1f2214aeb2e6c10b343d9801f3627047f0af6c045cf28fb5dd845f68b247c48836eec19d4e4f7acb073cc38919608f1ca760c2352f13b64f8d4f6e1b0f6fb17f72c6c3fc0ced3b9e9a6a3d2cb34c641f895d3e65abf04bc4072da86f9e33d5fe7a3e0a10d6968804943ea20aed45b0d43dc0eefc3adf63e933f334460f158f731bc1915d79e1293f270d36df780107b2764840a6ca6c569fe8f7aec32c36d73de779c7711823e8e2755bf751bf82c25c9fffced0d79a2f4d03a3f6eebafc73bec394b4a4451ad4073f2f3a4c833f742ed1d21c6fbca6d8c2136363479445bf40d6534a0e027c4058084bd056168f86c3c60692672232ea0b33a7142b05e29a182116d48544f5b7a403fb63c82f07ae56b553b393d084c8400b84c3f4f5e3d0d15651c2457b7c80990852ae836bc8c67911d16603802d6e7e543f0d4477ad989174d895011c597fc56924f0fd4ee6ba651ef8ef8fbb8701b7ad374da677ba2beb7c96edf4dbe4e2b3d3df03d779ea0f7475ebaf7f487f5385f5c8547adc1dcf84fa36e1ba8a0af2851ac63a318d772992345434a89d635528167bdbdbc01db820707e698d1f89a137e1411f924e9e842ff7ceb94bed3935494bf98394d1b5eb25546daa0b3831c585a16a352b41468edee81a811a60b3851325ef62110ab0f8490b971ad4d0e8976589a0f6dd108f1e8fa3702260738734e90525cfb22787cba0bcff47e671e89268631e42450283778ca58c899544d6fb6f167dd90608846f4cc7114b19af5c2391228737c5feec1f1d1051e78c98e538ed3aa498708995ce8ec81e71bc9deb61e79c285b1e351a5175b205b238f2e94ad82c0f8b237ef621db9ea70e7a8ea0a2a66ce0cc92ad524edd25ad52905bca70fe75bf50d995b25617d31760b708f7ab9be267c722f37525801f31cade3e362d6b9d77c8dff400167660e49ada6db68d1eb90b2347c5bad0ac44ba6c6b279a9f90c49a1b3930763401b9d8c8db5b3fd407cfb96872b46ec2485178f6de2b9b441316b9c2230be5e4615d3f9328cc41717907516dd0f39a6fa0e1c85b9b931a36d520200787367a615157c4e8ee1248963c84390c1711759f0d59115ba1b838c981193f9f02966191b344a35df15769eb5d12b6eca768340541c253c7f588c621318bc3a15eb927c59b6a93f84d35d1957d9a9ea7c12759220dcee5a5132383f8a3c6729999eefd4ae99ed80d9c865bcbf403585684b383127587968bc39c3e1623eb32da8a61a63ff82e10ad173211c9b39637e79bb620fe6259afca6eafb8775512431d11be270290b11c3bf1c54e4f445925d2506d8554079f09d3d946e76e20fbbe6a36c8f4a64c6f7ed789978652f938ca59674793edceeadd14b317575c6fe5f0be8fa7bb28d3b4e675d6a16e4b37cf37bd1731f8944d249cdc9e492abde319689e61bf8da4e7cdf8bb67fa1f482daf064af9bccf24e983c9754228de3bada21cdac98706f18940384df099564de95d6451b9b5fa329c59643963a821dc8411fad299831755e55113a304072a57c52172d57c653f8eaf42a7be4683fcb3aa0f86a874cd591a423a14861c9375f9dad4995c0912737bfd8b8c14855e1fd6f85917049890f5f6b32489ebc9fbaa544ca73655efb55bb5fb04d92c97b5c1b6fae9d4386687c2a58f86fd0542d6feb1c45339bd70b16916e5a7950993a849450be2e6760d317f6ae91c4ddb480548cbd629404859b9f69cdd4c296bc832733db2a25af81187dd2f013bfb513db2f853f756252cfdb21ef2c7e96230b0817011f2486322e8ffa522bab945dfb2e9ae382d36f350eccbd1a899a14bf1a9202f8a593d3e37f67cd607b24df58fbbf940568ce838098e74f25d0ac870366e0d6ae095a4e0450847b4085246210422d954a5aaf81d6e858f3d4a26271c3977eeca4e34065b0a8b1cd11074de6e4e3cff49382be38e533d620542420a2afbba90b75916f7ae9ae1b97e7365d80d0998f24a4d6942ab7fa498cc24bbff3e093d7efcf703e991dc66ad5f533c7fafccdc005d04f6faa725ae78588abda3f07b3dc4f73ca4e1318b58c681bef3c505eb1237ad39b20223e045de9592a5b99eb565098010603945168ec87a21c04953b68a7eaba706dd0e01f8da811c8c7b27d2632d0810e814396b23a698f839444963d483033dc4af7190a67457eb54dea712806425feab6425fe94c8ca4a3c0c77723904729bacc47f5bb2124fa214997facc4ff19c57eeba25c5a5a1c39ce6e1753dd4629cbe9d7e9c2559142bc8086c9b9c0560dd3226049e32f42abe0759eaa896f39475eff00d5b9f8f44ef1940ecd78dfcaa1f35d702adf8e7bc8c8dfb2fa7d47fbf3ef486f9fad1588f7cb337e92cd363afd04194696e9f9f7e637f5f5296fd8c6e8e809a1d66faeabe8b2d7d0f0e497170366f1a6f1a0558823874f60cb9b799674cba9b27a63e30bc86612d3614d69540b59fbe2953f1b6069d4d886352b139cdd994c68b3517132177db0374a2b0bb832c63990f7832c215a596d2c814c83904111d0720167a709e580279b93f68a19a5b5af86933e074fea1b4b966247fca08d988b2432971d33f30ab7ae7cfc9318234103d40e5f0bb17ef1e09442e336d690b5605aabbd59889add0edb439ece48074e469a5186011fb7677ae93f00fac83497f7d352007effd6ab33e3b3de48db33b3cc6c31f9022446167c2fb06c80b0b2961384ab7085ad6e719503686d6043f629d592a9bfc5b08a992e6dfdbc1ed73cadeffe4c2bf4af6ca46050db82cc23cef1a35d39bd1e563a4e86568fff2e1fee722442a4c2d122ac4628ce9bfd34d612ac0164b4add92ffd56b116b61eb4068ab8d3ac2c3bfa93f48287ca62f8c87620fdc586bb68a354b4180682bfedf86995554ccb7e0eb33c0a765308dd0c63fdb525a27f71d9417dd6db9bd42decbf415ab76ded23a5d7211a3b67173c582be4a9e83a697468be3b7a3e4ba32902b35f056ed90a372ca4c5892c7406728ee781eb2d8606bf36e29eab94976ad501b47c9e1365f6dce9180f3666d45111f514f63503ba243e673d4a398afa8f247ea682ef97eed27ad05d6cc873e236fcb1a19e00d7d4fd8cedd03d6308d5c7b358b0efae522e6a12b499a3b463eaeb1458a21a3a85c210c170b746064f2064821bc2a9a2469e470632feed2df7ffab06c48acd788b9e8a8303b8092c4665156f5224f056ca099b3d49b900835987777884fc3512c9b4cc5aa8429ecba8252059410710a0f5cd501e9ccfadf7c58860388e8757c82864e806959d2f138dd076244a0b54a6329e03297c389934fd0f119b7714b73fe9a51a3f1507be73261d10ac609b91223e878995490c3b49e7601c1bb78f4309d9fb698bd8655e2baf8de94e81cdd1c703801f61b2f3e59894f33fe14127cf0a604ea6ed8766a0a67cac436328d9fc2d346a1797376a003c3148381d8584a0fece8a147532610ee3a41193808aa014583aa003a3ed5de170ed761ff8e9837f043c7915c66351cb4df0a449dc400c63d0b2c199e4553d06645e3f434309b72f70d33a59d419f743b9846f9e3c1e915c786de1ffacb1c44daf0895b143514d01158a7596f3b1673a7179420d9aa2f63d60533634fbc534a17afa08fb35cff925247df032211f63b3327ce39ae1f458b64d65271e00d77433b9d51858fd2ebc1c0d6c203dde0a840043e8e2e5060a711a6431c91361e7c545a14771f327eecca0ee396e761e90269e704980f44c35d7b3db45175298399e890894990766a7f68964bb7fd40de401558204b740166a40aaae728bb7da36f96e454e6a4d347f78205afc4fc3e85f289029942b6318fa0ea4da2038bb0df9db1d1cca0d7df6518ea9221478fee0b7738be0f0d2028e980998fe82530f678c5e555c2a1c2fa1213813aac90a86085840854ead8b69837ef64a53ac271b2e49e6e8aef65d88de96a472d8c52966ffd7e5d85c242ea05f00f2f0d26541ed4adc9478509cac4f33473705fa7b1b199622dd1470951a7e426835f6d4fc5e6e7b51aee57b79be002b3e8e05d0241e4d40a445b11f235b1da8d426590fd6f03610dfaacc080ecc439ecfcab9d314868462611f65015d2143cfc2d618f623a54ca8d46121aa318aa5718b23d985a8043a3a2b3c3f0415b130e37760312c6f9c9cb31e7c1df5dca8e799371c3e141386ab2b499193d4eb0815c9d1da7361b396c6889219d4f158e9d22d6ba5ade2033b13cd9776919baf1690d482712c712d6964b699d047b0ccb1424e8eaf50361c7094fd4a590a7482d5b708fc9c320431a5356ae67182242fd804e6a0c2e6147007d9be07a40c25cb34b9b500d21ee460947176051b8ec8d6639245737a064f4f359032232bc27e04276881576919e12d603dba8841e3948e069f4cb74daaea862652092506e270005448109e1e9918b14a47ef3e04647fafdf608c30d80a4e34e009b6035edcf78ed46e5bd44c1d47bebb0713b0104303ad56bf99a405f1cf06ed2c58143eb5701ea3125d6051bb1249a9d1e6fd46f902404b80ac8e3c34f678c569c30728ba95135181ca76e5fb05a8b941f94cdfe8c5604725c45b549ba52607d9ef9c00538435d0205cf5c4b6fc918229e9b5d723c8aeb3711c1cbe6cdb159d42e2ccefd142e4539ac0e722fc2a9593fa73b35f357db46e34eef1d42ac8a6f539957b5cc53e051de4b429a29a405e4d817416d8a2630a331e2581158bcf62725651910fe2427ba7d266fe1743fcfb21be0d7a49f81b6d9b60d4091a5ec36f9e4731bd8e905e43cf67fad87e049957f49d978f74af8012aefd7ac2ec8d5d784853b83be1602140e7cddd430b0859084fdb60d8c79e245e2dc9876168e0896c07405fa14b24d1f834d4096e4978f6c3624455e8507daaeab823098c8bd7e3a7eff1c78e9d1b98c77ec55fe3c49f6b4bbe78b0db47124bf20932fa954e97ebda863b9bb194818e62a349068f8fad107b04a449d5313a1a5fc8ca240f7a4e137105f84941b780fb8a00c62a7b51e988e83205728f731d8998924022c358f815ca5a2187494e0bc0def6e058b4467879226796005767f91aa4c724a06789b29e1797b2e5c5287c5d392bf648fd9a50a952e3e28a49dc1672491efcc33f275774a064412364058fe565adde7851fe6b320fd47aa733b14b1540bf66f12d1ddcb67e98799481301c51194d5cecae3d3a7592f9d315169e3df92aa88d2a824f1cb6a7329a5a58bf6f02686e3e794d57f1ccf5f9ca56c729df21845ad02b74669800c31d61efc56df8a5cd2a8469ee8b22caefe41da427c5764159d820309495f37d8644e5962ab2709940c968c48132eb6d4edcaad7b6eef8d4d55965744d296396b75552d199484c62f97191952b172010846b5c14635af795c6387d5c7257df70c642ad2b86c8902460a3895e63ab55305b618f5c42780cd00a5a76174aa05c5ae5e3074c4bee34c44b0d92b6c06d406a6eb4785a613fd24a1ca3bbb312544948c4ce9aa2afafa73c9319388f583e5b8afd161cf8c86be86ec52507f6a491185b75cfa2b2b5b0f1d408e8f2ddf139ab31d17444931f55fa30f1cb9fec3989ea3014d9ad3ff9304a2970d6a3b6bcc9b55c8ddc16a62800aa429a9137b0ac42925656c7df38ebc652e579b90f222e238cd6e882b3ba2977b158d4f87715566456f99845f4ba83aa1e34f0e8799d1eb7f9d2d59094ee722896694f4b36c296a1206a3b49a54be05620e9ed4cd87319a044a10414da2cc452660e461113c47576004faa450c9a2639f082ce3ba6b04ed1db43d2d3b306d0800b1f91bdf848798353490ae6fe79563a90ae472533d23f486f84b2ad6fa013e84be0dde890cbbaf69f91373191d5b704c4a43c2a6ae68acf0649e1768520fbe2288e40a540a5b6d276d117f858f7212530b0a57f042f8af4d423a53c14081dec031ad1187ee681fccca0447f364cf39da8d0ff2cd200ec1a8061da00caa65edcc8a48817000b17857a8c2dd2559030442c92c8889e82361c8e1c361b4b02b8250939dc54d0951b2a4256e8ed823c26c6fe00b4e12c5ffbee1a6f21e2febe48c5dd8aa3bd1ee59798e14ba1dff32aa9fa753cd86a39d17511c84782875c07e48ca5f3a8317647bdf20b5d25ffb48d346252a788ecb94e05822fa837540827503c581250a018533b4590dc60a2ea4d1dea98c943c2e0326de581a17ec26dda305de07984532ce00205fdf26fb3f2550f01e1f54a0c4673cf4f7c045f8dbf5b14cfdff6069708face802895bd98284cc18f78d6f9bd7f05d1dfbf889f18b1c040b8a3ac3f5b4a76666046b6bc8e447cff2ccd6be5a0b2f27892dd9085e782399fa1aac20270708144f19b98461762db06330d66619a46e29bba641784936dd5c59549fcd43335c5bb33c3ebc058b74b51a708f9f11def2f952f765b413b3404c4ab6955471aa479176268cf1dda158492ce488795d752ef8885aedea09840264d7985e706aa0575b4206ae5fa809ca675682a1a6f21cdb9f8e15d8ea6f6dd0b1b16fd6a9e25864c7622d7f79bb7e28b5a17da971a2bceeaa4f5238a11ab8ed5c056045656bb7106deae17fc6ec208a9c14074c1b5bb1ef4bffef596246ccddc81676d4ea65a07636a784c6260dc2b63c51a28b50b6d2f5cbb1cff020e1a9c66591413a02a272ab214b5c0a8663b5a682bc8297c01f63456c9eacab48234c20718ad37dba0a071fd39ed8c6568fc12abf7fd46eb54a03e49555df20a0314f71689842d82bfdfea6afd5e7d195ceee0d5c9b5cdecf7d2755a9ce87f8037e025830bab21cdd186db88a7aeac8c994e002e4646ad4cc824a52bdabb2ba954833ca82a4534e4801cd84a601b393160fb13cfe7c352988c14417ca1506849d9338b741d2a70185580f93140d9e5c646c076797abc371b58ac357696fbf47fbc3fa380b7d6fab93b4fe188f70aa48b88eeb891830018218ea684c1eba51148cb63e55ac81a7e1c0fa6cd11e6e7b0a0bd236d0a594944b1e2bc86d3f2415c33d0a2c9c2dbfc1d435bf2d160fd6a12e7c91d578e7ab1692fd5cda6ca7f44c6bebe037d87cc20fd4079475386c6ac52a89cfbef64f4b045b076a84d2425bd27fb72ef6790ffdb6e4cf891ff0d1bb63bfbd5e4019a8ba8bc7a8063af313f7b9d1f9ef8bb180d768218b66cddc80a6f32fd2bdd1b1029f3b6a6b4c5fdf7637213be497c6b93c8fe16e6f654838271f8f7a4353bb387037c61369e759cbeeaab92d75294719a5fa7800cdfd9d841f292b4ec224fae2e3f3db2f4ab44db58272493387708a9e04c6050f3565e2c1c8100b2e849280d6cc4da1e00aec31fd83ac6d2b06aa279436212597ff436199d667f38fff50843744752c061efe31ec9553b4d82f4dd394e5f4323cdc9ac62d0ad3f282f38950b628a99045d6b6d6ee73d27653ebe4b0a8edd4752ca7b1579ed76eeb73040513b9d3cd4b77d9d427bf02eac8a1d6d60a5be95f33a44923deff2dc81ee4754c6dd8700a3c65ef0f5f751cc276489f71322f163e87808e70af7f2f5ef6db63162e6751828151979d256f55f83b4b9a60c30cb0c61fe5cab4b66a410dc7e09d821ad1a55c753b03e5ff05bd95357ae4f1ab93861f8f509b3ca2bba955336aa4d88703baf1d8d2d92a08726a4c07dd8aaa5a562fa98896e35befdef34f4615b763b2c3d8a7310ba957c3a6dd9fdbb4cd50bec8c4243211c2ee41759378130b437c6e2c487300e3cbcee39edab41d4c39cadbfaa0b715d369da944c6a0659aed51cec735455fe222befaec88068a6fdc92ed8ff6b11950d1c386b126afe7f3fda01341bed833dfe8e0e373bab37765f4bc8843f8af526712eef88053a4d828969bd8f4925b08d16cd548c9e41ac9c037f347e6edeca1fd948553460939b6a76a518b877076d9864a8c2a2a51aa30a1d2a9a98075933a4e9c52bd6ad16149a699c6f5d04e95e11a3d93bb22528cd420c2a8ee145b440ec2877a811351c70ceb38030bb38cd72617e158a46275ce5c7baad781a511e4a3e9d0dbab98ed25f9c7b5530614e84defd7e5e3b2b5741c1b135508abc3223cc3654ada375aa1af46da90472268c0bedbec865edd34e655f5bac7017c33ff36b10dec4f8bd9f8af4ef4f6b6ea20008eef05e8e1d06dca8ae946a729a18e9c2c41dc6a7bea2c184f85db18fe2b1a530ec7e466954ef7a3c9cf93c33a9c256760d93a2f9e3a6161c3113f15f657c764f86354db09186cf8109794312dbe2be8e15780b04be9e801fc5268e87560e724b9a3cd05dbc60c5ccdd0670f96ece2fbae03c4fdaebd02f64523424c707132026895d249ce94e9fd61761da0ff34418ac3e40e774f783a82d4b9f9a6195204c229868b5dcf20fbd2fb7a540633f9bc3d25b4f36232191dc49e33252fc4a65d66396d2821acd6fc7d1a70b83ef4276dce08eb832782302f0aeaaf0e976aeb01e8510d0ffc9c867b3bcbb6e6c781952e787072caded1c329884cf0b2a3535a4410e2dec326bf231a9fb17742209a0605088b6b58af63fb11b1f19391be9c7079614e24828dd670b49cc3bc32d81e8d6bc83e5638b584f77b2da17fba9d3dbe32ee0b50365e0774731a3d5956cfa7d80e8506a98a52c3182db63c1426fee19ef8c170b8695afa698350f581031a7c5e235ecd9d80db040d3f423fccef559f6d255bf441b90f64dcc2a841324d056dc0df690920e60611e461c4aa86b388c101ad7b253a70817c4116693922120a8143e699e3caf161c89a1fc1c3d1c7d909b2daace187d2858de915884ab5c74032044a7dca58d23dc9954b2bd894ec2071bdad0f6cd703d9d7887fc131f9ec52652224f5295c1c6c07bb5729e3fd00bec1af321c55fd6f490e8cc9c25dd2cbf37cd006e66ba78e03d200fcaeaca94c40eba6370aef5223b6da7fd0b8354a59098cd9d6e790fb4b9e2c5088030aaef1ee7ffb9538df1b3f4b5040d6cc25c0e66d2207bbcbe0bee3d9070529a63c22e4dcb39105cba0fbaee7c01e1103d14875ce0602eaaf1ade881ab134ae846e836c1a9a75e3763b685b3b46c5ebaafdc59bd17bd46b0c76b337e596c7af4335dd65360efca5d43754fd15ed41ed4b1691a7e7bde5e58d01131565aed3c67c9be1a6965643ef7cbbba594bbf3034b5b0aa006a2443cb392086978d33c8f8525478c9102487cc8d881328c0a0ffaae1b796fc1cb3571b72581e919679128bbadb4a36a2b40765f58a9d5cb21d2fdac16f2feb8ad3d958fab7890e31e904ee72a56b189d978997985d6ccf9c7c71307274b553dc92e54619ddf32a0dab9fe3acd455603541dff2cb4c05d100b9bb6bb7ac64d3569b00b875779ab2588dee98778add304c6be5d78fc4efefdfbbf125e00db97e323799ba95a2b8a8c28c71ef3ab8c5c20ad5adc99f0b4e48a13c814cf9af312acaead76600733a18189bfa6641f5e56d2987575243461df61e8a01b383f293d8a7183e2ccf1695a8e8482268356344f9d01e7c30797475335a84dccad1afd75f65efdcbef7c43a23385066002c3db8d8d8f53128a5b0b310786b12835aee5475ceb18e416a186a021c94fa976229cd97226b8731a0f015689a91b3d3d38316bb9766b83fa294d63f083e68d7dd1bb98fae44c796ad82fb4e11e9f749afa50ef2ae1fa66507d0c6eacdd926ba287557b84bf358a15e37627c97513742b1cadc09078383929c4c03ab4decf4ac5c4c7238b696c5ccd18fa68d67cc5c13b64e559190aaca7abcbe48d698ce3dc65afc617ad07e30b90f3e11a58449e0f97c117e8c67736169b1514504d9d3b426fc74e2e73bdb5b5fbc59fc84103023c7c157db8b1cb8cde69ecf6fedadf11f72efa44001ea569a793e81276c6799290838bc93d4b47c813052d7a6931ae927d821cba357a59c8adb80df248a8a81498bfed5556d7e9a94bfb0180be09c5dae6064c49537cc2cb88fc75c58c27454ff374bc403dba61cac4321857c41f9fe2085662ccdc45054d53e652778ae2578fb0328e63190e6d16b8e6e4c577ed972d86566ba55015aaf9d44d79d526f3e5f7f2f5f7eed7a20062203f791bfccdf3a1b1d8137e15d33383ba7abf08ce343a6e1468145df6af9aef9e073c571820b735aedec4ebd3ab27432ad88e4a5720084c2ad323a233f0008031c2cfc90e37c76115c587ed0ecaf03812d98bca5b537a944ffe5878c9aa39f2cfff0bd41ead0814bd8f609502615e589a35642a4b8edca335fdf42444003f7b04d8e4fa08ba40600ed0be32abe079557117187d2515cf6f57230fb484ff33953266d1f318c2e2b819974999315d2b2c5d2822ec52c14469503a424e1ba27c3a40718b1f23026e48425e348de92bf2a3f1da8dc27a34d9dced1c57f445bce7ef6013e4e5f971958d8431685c8f6c50d5104b1c3160920b9fec11a847b0350cb2b221a0302d6875ff0145ffce627e38c09194de4f1263e4a846223547ce81d68275d21355325f8721d281e4464220c683be69548b5a9dae6d6eaedf94119291e9f3240aa17d5b5b32daa692ebf6e88768602d1d11e9424113b8a95d07e6f1969e5d87853c6aff3220d0e4eb0b3ee9a6038355a298c4ff2e7e7622b2167304a09be4c3409da9523f144ce7960f45e3b0514f6214500e5d83b6d847566842158d4083e18d0913bd9c6aacc612208ea6ddfb864ec74e277c10ed1a5849edda7c47904bb6e106e5cee54b3a2510996952cf895b26f55a55e0b59de26877a22b886fdae6f5aa12aaa3e85ae728aa8b660981dda51cd5610a168a1f33c61678792f28f17896057a4b3511f8dd4e94d5771fbaaad5741b4a80095aa513cd57305ab760afb157caa44d21db8a1153acfdb54a6457dda1f5531403ada611f00d0e52f2de19d6a6e40a52e60a3f6ded329e2c3fdaa8182b7ffb2447e8d7c0c6cb96dda21cc5cde0da0f17d284f851fcd9dbbe877a80660ed06a8e656cfe4e22be56be4e9aea08c0b742b6d1ac2561e21ac8bec7e0e17cf4671c0be35b10513c3ffd283116d9a28e62e33f37df6c47632d73e1c43704f0c2ee117729147deb778f302f7eabd35e75b0ef9a4ea5f7f023daabb7a02c61729f947412c47cecd6c32da6f80d34b054b60a51901cb52a0b9b4e2290467f744dce60c2a3f82d573330925e37c8fb7995fd67aee5566db6c121c34221d12a804985af0a4733fb1ac38e3057e9700a232a77f0a44e70014b3fb7f04fd92d7744d5f1cd3e2ac28b329a78b9a9bc42323bcf357939fce01b88a50d0fe334c2b04106d5a2a951e46e13e02ab09c0845f391fb23448f2ab22aa7f0937b17211cf51c965d6e1ce3a6972bffcd86584a696d7f399370cc1b4a5ce6e4ec2999233ac7b6ab26b6bfc70840905f2b5f8d738d6c5b34dbebae1e5e0500c0f74edac2ca52ce1ef0f68fa85858b3e8a89bb8c09a1b7ff92fb8a5c533ed83abc53e838eb740634329adb2fe012563095e087694959ad342d068085c1fbc22f1ec79adbb55736c99d0a513fc9d0c50334f58d6521d186bb67c8fbe2392ce2e3602b327c8ac5e4be810209b895c4c49a7baf8d6c20b41853d27626cdfe8350c65858b0726033f617eea2a601f0eac9940f9b477548eed38b7ff9b200366bbd6bd9b266747bc09b7686462fa309470ffe5abf72b5a7771b0d7a8de8c8dee6dc6b108c111dfd4cb24464bf69c94f2b97fead27dfff675f1a2efd7c4beebf8eebde3a86b7afd8336673d4e298888b642e98d8a368961c1239d17e6c8bdbee55ed8743d0b9e5cf1c94d2bf835c54abfa9ef36714863671d3d0ecb0447eb9b471072716fa603d375d826439adea7e0bce72e1d9964442617f38086903a087bd4b9ecc49107a35133aff7dfbfc6b97b613166fccc66f8cfed8fa50d70d369aa00ee3e03f75aafd6587eea9741e071fd81cc4e975b8053baf993d825b0eca062146bb61582604d07f44e903da78c206e215020a8c117b067a46e7482e4480b0232e4d5523d8375cf2c89de14db0995a7ddaed210a91bd1891328efa3adb0714223d4d0262abf1cce6d6d5ded15906650ed0b9807066cff8b083e8d24a7f110861e578b68f76efa780544ca10514a1f396ccb7e7531115567d71cf1af2bd2cbf2eb4dc87f9208ef939342be031271189893e085b406646aa31edc918058b4ca08906b1b08704c9c688035703117d7ef90691ce58f67d3e1f3ec6924f4144a6edcac62f56eb4191c62879087b57748af347e8f52304a10996e13564c4af223904d1d0c5833310d79d493b560d7f0c548ab06b2f1510f29f48acff79eb9bacf0c8084c46644faaa1df29d5382289751333106cdb4d610d7fb0db2887ec1b699ef15c7d50c73d31a94e44dfb104889ee8bdf27701d8d3e4c054cb978faf070b23a0fd656c8fa9adacb38233998468fefa0db451c9f771000de1368d21c05834bc4eece0c9565a71a18e9d648c742549c127a6d171859848233a9b75ea0a352c294974ede1e75060360fd42bc11ddd7573b890d3f6df0860510dd355b25e517a83befdbe20a876f0c1482b6efd07406d25d1d7d06c30bdd2babd234fc463d546a33f4282f9f60f73a03ea45d60e5b2406ac56aa8477ec2292a4636c0e14f2562cf1524460147774ea78d8b970538c22a920b86121239d8d486b37c06b012bf647c607c60a116b12f4a32c4efdb3940bec4b66d51443f461ee37833ef524ca4e0f0196ba1a3ca0301162372e3729647016ba9dbce164cfd43311aa1314a4f8fe57e66961b3c919371f2205f0f4f418cf521586fa6151c576ec8b980a05b426f85488f59d42284bd60684fb70701fc7d73625f08cd280402f66bcd06ba7b8729e8f65c2d8d861e83f97cf0198861e2983b5eb0d3024ad81b8027f106c9a1355d3d64d6c62397cf9e80a375ce4948bc933791a56662357a04adf368563f62ee23ca4c4e82ed37fa642273009aea91041934af7f2ccba2b81dd4e9d83ea5ab08186f94cd959accfc03028c88f95a92992f70680be90ac7b26131abbd206b380cb7f74a6255f132852591adbfd56e10fa6f8d8ca14611efc6c5ca27f4168ec42aa2438bc2461f4cec36853b4522d69ae05b973c4cef18587f3352dcc24234e34a374256e5b88c2b1df25a6322d9e1f66f790f32feb25b01bf33c05056685307db937580985e0257c02e2d146f2933df8d46c428a7c0c98a17558d9fa801e38b300fad7871f51e5e26a398aa37306ec05d9a31d913dae81d30205c150a89b875852e79058cfacc0db2e2d52206448bb47d6eed2eda9a8ec12d155958e8d6f79df6448957d7722b652266bd849685c00b9dbf71c2a2451125e2c5bbc6b240970a013b36ad316b87bd18f3072c3a9111255e54e9ac1315f1de6456f94eb05d4fbc7a22592d17743b231167bd0a526970aa3a6c7a250dc4b02a53456aefc8a03d4edbd6741b74fb2a6bec369a6aa0481fe24e861163bd631029a8181aa6dc5d1241a9ba7b4465b91f1e0aaffa15cc12e867f6a243429503f442edc1aa7ac96f544eddaf55a4fe67fd484bd6283c3a8d9b76133cf1bf5459a8c6ee61b44a1e1bb3f2554f8179d48403cc29c0ee031b33d53d469ac2bd09cc853e80f80cccda78d848d3d7b8deba0ace7bb2c37425610a71a501caf3dde72df653710de55ebdfb47e9f3576e5d0e98fd7a3962d990d2453d74859aee6d326c9437bd2c2b2bae966e060d489cd68a227262c245b068633ee4e54f8a57454fe0aee289d18d13b605bc3c8f8b2492c107223e75c11ca9c868737b03ae533e1edaf69b0718ced238916bb1e7487a1c4b841307aacf957cbf867e8d6c0130b7688feb77bb030071b5d603e2f2a04225f57b21fe0b6537664f163ebf47142bcec002d5167ed9fc6d349eece0926b3b68d1e06c7036049f3684b51cc1169a03b6629bd6a9ba50f5dfbbf1df583f3a2128c7b68738e64dbd27aba683bd39db57adf54cf8ee73cb617a664a02f3782592b93dd068a721f303f53f7dcdde36810aed18e8631d81e77b55e34cb3c9f98497d30ece2b4aecde9379e6f439a8082abd31c462f4c8940bb7bba7f8632aea009f2dc5c132c9bcae6caf591fe21c3f4d9936d2d1d24eec28dacda5b59282c6ab75bc3384df1c691804e762b42a39b15ef2dc3b3a76bcfe5fab682b1a94ef4909dc89ff85932ece72a6967187c2b71a2262ef2e90ad85ef3384db0582139a2af3ffd598d2901ba328c9bf21d7523bf764e06a6874e4f3ea944fa129ae12b1134bb15520dcc99adf5304c7e3ca170b467812e9fccc5700be6d73ebc1afc1b7d99870b1c47a8f0dc97d39eca05a6a9522087b9b6d4307b706aa3344783838a6a5ce0ba9bc27481eeb7930b790c9e4bf51f02dcb1a6f7f9355e357a48ebed2a9537fbeeed885ceb5f2b30006fac46ee93de69745f05f3c36ee89312e2ff2ec28b02ad3b2d3482ba1339732be981b3b874b56f12f41acef4aaac02edd0534d502766cb336e9d0a634b62ad4648a01289fb444371f9913a4cc8f14b524e064704391f1b9743e83066ca0e42e13cd7d65784a1bfa3b24bd984a527295570c64a0211bdd43f8709ebb467ae066b49177aa2bb4ec4d94bf9e85951b45393a2bb62e42ec9f1055a39028eb2ee884460009e4525ed5659584a5de54a2e714bb41bec850ab303dbf91b1779a03a5462449b0dda065304e33f9f93b74e8e3d2c917d7ce0e067ecd175184398122b92d5c32348dbb1c3535043d1cc0957fbf687a5858041e3b5ddc42b9c3777f0a9e5605670eb03bc891208c873942d306fb625e09a68ff19fc1746772fc3d6e1a4d92a23f9b49a808ffbde36abf1973da1a94ea0a8ffea73b48c490625790fbe8217f821ea63a36bccb66573288ab193838221fa72ddd65c3067bd1dec6c780d833773820a9b92db0e490b90db6385c2d5207049adcc9160b1926f95ca0f27891e621b093fc760a5d5693fc6510cd3f867e346a0fb14f8ed5fbfa433446bd23e1fd48b942d1f8e0f2373ab24e21741f3371379d47d4e82b95de64822b5289ba7bc12380337ba3a09ea420ca117bb7cffe31c3eb9027ee9df0d5196ed3514940bcd9c5e10094cc6d14a872bd63e2b4353ede38bd1bd2614b31f20c4cca80aa26c2ca64e3aa0a01bd1c289c283ca7ef26a2448e38a19db0d700f4f4b9e14ed7f771647ae7cbbbb44c870c33a42f86f54f284d03324c36ccafa24bc66c46b78a86dda676e532211e72a6334643438d4d899468dd82fe8373f1ece0f52245c7a656fd7c83a48145dd9c20d51b33e3b62e71998a1c170fe99af3aadbc76234c045ecdc93f3ca89578c4c1e9defc960eb0c1e797b156aa168fff72b9b6dcd61c3be1d344c02e8101cebf8624a63a095d9c15ab07931eebd63c29c801568187de7a2bb1c337050c1b2e8d9b6ceb4517d9b4e9ea4939e1ee322a95ede796b3dc1aaed9e17dbacff6423e3300c7c838cd8b1282435b98645dc911ee5d8b70907d8696887558fb506aa696f166e6b34411da804b1cf3f90734dbcd5c0075b108d92ca9974d798083bfb410c51526f176ecf5e2e6d790d8ea610153e80bbdf8207c6124e977cdf048c2591f07280c7b87abe093e7af17186f1a04f79de1bee852df6fecf99caab08df05fb3edac7bcd0b3ca9b6564ed7894fdeb2208831143369daa6553f9510bf105c9bdeb3444ca53e9c5ecc0b682744101c18ce21532a9a77d19917a046c7aa3dc3e78b3f06b5fa01f7ea3218054ed20449a598ed086cf35f34c6a4d4574b4b0122571880b81625e017c467e11d543fb6426f23df81e2efdfd287b4e29e927a270fad359158a07b6177876932bf96ea7aad69c6461a1f68c9262cc53222d955157dac9b7ff42871b731a46643df86a88200d378b9c3177d62a24cba00fdcc630d467ca12c8c00794c560ea830d56e6748410fe5d5864d76b52c8f35819f9e94f9494f7e83c717b6b0d516ba69830c6c4d8da079a631266f1319835ea4ddfba6d65a350ee2385d1bfb9d8f542df3697dfafc573198abd2f7f1dd3d4aa71fa1e9018c96063f89dcd2fb65d6605824a47c7452e60e2ec5562fdc9e718bca98fecae17bbf70ce7352571b5906ba082e20f7db811fdcfd8287faf08def6087d85b79e45e1f7adb0f6c5558e0ed7bdc5d2eb144b78beff556399adb2dff6166280d8042b4ad191d3727be71044d26c1360c64809f383b74456ece1f37c8a752236fc3e96a2250af1c6903578b4c3912ee9918d502bc799fb49dfa65ac7746e449342073e5d8b61639c54b44f6f04995511a6075d0b94748f048ce8694af0ee3a6c02413279b86a51cd6d66887a631f32c8f14c3d6be07ab3361aa6e226c06f402b395ae2ed8c510b7e65755673b8593a60cd8e4e5a9fbb64034c627beeb6fe34775d3f41f17506d287fd5a3b5722cb577ca7b589ab143aec64aeb655a9b3993aa3babb898cfc4e8f6bec0071e9b146880ed4fd096283b1da7d182b3066b0b362107d36fb3e87c1f14a4f33af20391408ecf086981eb59300010c5a3eb018db6fe2dee61896d3eeb4ab6831f09d80aae13ef6beed55c50fb1e934437a614be19a9ad2d1e33c043d28aef6ea50915a8e3ef06d79f803f8af90a3519302c646625b648313d804c3779a481b7a6f80866585b3a20e98c585d5440f5ca9d52a003d62d2269bd4d7d4a1d3e13a40f9b154e460cd3ce8ce3c4ab4f1e13c41fd0a39e8a87198c51cb3d5195fc85bcaaf066ec91c4af792639f56f8f69007004cc6757a824c406499658dd132fc82bc8fa63fc0a0cf7f79a8b083c7d59478c6fa1aaa3db1a0c457d791aea60f940a1e258695a959b65e458b64646ff9bdf27e5e6b7111d8ee7b240fe6d252136049b58c65ca74e6c498f1477e9632d14fb06f4dbbb221f8bc2bbda9cfac428c74b38800a19c1ad34576f7302152f947f643906d43640e8b503ce3bace0475a614190d9d5933eeb056a4f4721a130fdabb279b039df3b2e1f585f8823904bc013f8bbdce7032b67c9f1dc34ec556de2dd4448cb6ce7b79a20b90354a9eec6b909795d1697794ffcbbd2edf349f45e6eeaefd8bf69008366b7dc6c8c2f338fff181c5d0d4f2aee3902c27ff7149b98c463c6b114a25c201126507f14b2ce5957540ee8ddfdf1ef272f5415678f3a179c4b53b0cd683682ff5b1b625cdc7b136be0f860147d4f406862c70eeb01efad356cbcd3ce679fc5e8ae3e2517affbd69b428683b3d9839b6614e2de934c0d9922f80e4bb015534d1702a3c6e77d30334e2074f00c9772cb79123b7bc1bf467b24f1e9811baba8e510a563babf52a6b42d29866516611256bc9eadad9f4fac3310a348f661982a2a05d398d9b4db885d4ba9925cfdecf847786aa01857a3e23ff45120699f981d57632308a12b6b2c071ffac515102771c753010cf1a517023a304a7256b19237962d2a66c2064195ccbd35fb9e1a5b1d0db188388a2185e52e4419ac4fa5f3c56fc30c340ce1e7e954cced8c5dfe883f5940262004f678580eb00103e9cac983a3a533a068cdfe903e1c9bde731aabd825cc2d7903717cf28dcaac4e1c8b0d2672a478434f6be5cfb2c1e4d947173ecefd4a3bcc4e6114acc6008a8469bdadba8a459e4365585dc84f59e0409cc9860b0ca98a7ff5c97adc392b6b4fea0473f6bedddf6467f642c5e1739c0f4323d6c0e6956435f9ae0024a5fc3da7ffda5f92935ac9215c08dda59751dc3fdcd402c174635f83797980b01f9cb89fac450fcfd1e5105b66d50aec0296fd9064cd07be617acef6d85d0ddaeede84648ea6879985af055c5a0e92a8ca13f89b1e6b6c5fa38de020fbf28c3aaf3a112d9eadde9bd7e43256e01f909992f95497a07aa4f06a0c78dd8886c23a60d44acdb316de5a018bacd1d7308a762697a034e22e000b4d23005b3be316404d145562ced18cefab5a11e7aa8e9f5a12dcbee2870cefa009dd6d68b56a0e14297cd6df74cd4dd46ec1b9398ded294e9d43e8215b4bca118fc195ae4da7253fcaf019148f516b59f0650110ae1fedf3875f1259e13715517a80bf3a86c3ca081789db40a15379189810f38df20758f7704b7ea4f13693692ff6ad08eb3fec2565f73d0b1bf85a362d8e842b9db3f03d8255b7e54eb4afe3718818d26d9888c12f91bb4175d5066fab6f1bf151fabe6abc40999917625f89892a4d55204b8118f678bfdb0a0e531b267acb1af36c5ec05bebcc4fd3c41d0b6708c25386781dd4c18fdcb18786006ac1606a9433ae03da5d9baa2f2d80dd4a4fca8b35f350f36a52d7df7866f98ee2cdc9ff708e4b7982edfad5113faa9125bd41e7949b2507b241b104928aa0796e6956734abd2be426969e258072d7a36660086e2ca1b9cd5fd445a44881327de3c73ed65d690fdba9ea66c247148a0fb1edcab9e050b09819b51b3632e1599d57f6bfc4037b9098ce469313e570699ee7f49394061edf54ac39f2d58344bcd70ac8776caf0b38632ba8b638415428bfa2243b9d6405980bde3fa51a0bdfa72c3136f2220c17c408872a0a3892aff3257108909e621c971caff8d01a0ad853f86f4674fc753d1d8262926538c26aff9909bafa2ef5f8df4e693b312c8f4204e43c1b12eacbdb90d312489f6aeb7686cd5fb5e35b099b2b2bedb21a34130d03c2c8b759ac2dac68ae4288d12589f2080f947363ada602bd56da68e13603aabfcd739802b01c8cc97c476df5f0f7ffaccd8267f8a1172a1ffa84af622f7c7d7c1371c9f94edbb91bf737c534104703bcdae712ffd994fcd2cd1cabc44709ca2f3987a89556e761e498e7b0eaf64f358c466e28e0f0b4edbce1dacb4493ed7a9a76ae3321c7bfd53092c3f9821a9d189ef073ce536e4665eede26b297496be2b7f80de37db1819c681624b2444076f3ed6b388ea9069a59d1acdf572f6d62de14ca626c4a0d3e88748ba8830239cc52b6c9709a508076139a53ad64ce138a4f88a3deb0abad520b1b76840d6271ca8b45bfbc9656c02daaa09d5fba8d16f2dcba81136c4cfd6a8c2b58f31e90ce6eb6bdb34eb36550478359db8468b47ded3e09a28df9167da5be262c9126b8d61c5675d57059dbb1b3fdd690f80a5695bb80d51716347747ad0b3ea7dd98fe0922ea355e00320fccd0d6f8be70d2d2ca734c0f226682ef31bf1941003059ad9ec1a0e04fde27537b72bed4eccf819f9faef168325cda67fdc181e7562da7c19c7dfc4c40d08ae58df02a2f763fddf17ae70f1d79d9281bd0b9947205d0bb444216dfff9feaf9c83be12e4333464ed495c518a81ddd6b57c353d77e6ba0beaebd0f970bb7ea3d78d3b4d180e70ba2a91d2fe1e57628bb2a0ee843c482da3810a5a2b8dbb9699778f7f80a3b6c5e9e093f56dc56b1829e10d5e2aa0cc8646a49a5fb476b24ff1cc4b31f4e6c825b51a7d160cd8c6af641c0317faa3fafccfbb358af8cadf87009ef7619cc78f1d327782ac27fcc4530da6f1e9fd2a4c5a794be9ab4d26261a99e6fb8fc923e7261f5e4ea4b7635f39c1369d9d4c615b9ffd463cf24d4a675f99aa95705f9025ec147f3dae578f17ee922b867e5207b695270ed4a3508ed473b5722ad3895b21f496126310670a43d2dd2ead442e939f99c7dc75b501b8e04754bfb8b23714e79cb61e3b684696555fca3f8f5f14c526bc43d64e87a99382b55365fabdb2e849808d7e257b95691e29565e7328dfc61e6c47549c5ff8116b6739fd497323431d698b3f41f15c7b05d53b937e433b115d1bec0d221345b7ff1e9cc5709851c2e598996963253ab28e3372f44a293a3ea58360ecc6328e77c532b1333c1141368b01570cc4804c84140cb97a0141ce951f9c6bd30b55d580407dc40c498b8ac03f06b707e6cb4a6a8cbf109eae9bfffb7e45a8f334a13a94338716bfe812b8def3648fdddc20603b4f9aaf68893f1f8b613a71e1d707038b1eacf8692d6592e5d4094888e8dc4de1692767621cd620427bce6ff16059505c42277c4b972cc0af60b5d0221c400c70dafa6585eadbbf2a92dcb7f6efc499290b939c467b1cfca2254a44ff1c397873f7519b9839fd311682cfe1bc043a541ddab5f940e72e0917c4e896987e55606c1402ea54f5b46a5f14e57ca7397b1e103335033b42d84c2851458bee6d610c9af2410e13fab61fa60fc51aae65d501c55ea11f2ada2ee36936f25b9be0f4744c48af2c454d3eb18519e140fb6b254d30f39f9e35b8d54c49328a346a4051f792ad299c7c5f6d04f5599d90f07dd5a05fed4ebe9006e3421720eb4e469a4de6abaa1def174a1f58c844807bb442962904c00dca4591b37984b4ec851fe4710ef015bae10ab49408c3398968b2fa2e36a6eeb20798b8909f0ab324b5ff59cc42f66c68d4b1f683c1a05039e1358775a36954ef318171fad194169e4c69ac9138c606b8707ffb7af7a89809b66d0ed72ff5b4d0996110a48aaec702bbd5787c9c5d54bd66acece92a9c8b8cd15a48e674b01d3a7c7b410f720688c0c9eea9e69b02f40d327068e39d83eb7d5b1d21a7af264a60524fd491a9dfce4cb127465ec2fee8bf7a30ebcdd59263db85912c5c8d1e432ab0989568f27d4f47d3ce8ce3cd347f4de01295cbb8e8a6dd37e26df42a1e8b557b2de2f11a693fefdada441b1195bb4903fb277727aae88bdbd3c685301bde4d371560497b7932d2bf23a4a7bd02c398fb54c052b71ddc083cdca37234c468b155a08d3e6faa9617bc6431cd5f309d4035802de7ba406450fe2c2f7f9dfb6c80b2fff29c79428953646a074a5da4fc21ff2fbb575aa1e809c2376ffce2f2d2d86cfa7f500cfdca2a02f5a3800110905c2a91df2708d21388cb3792cddb355c8bc7b88ab1e30ee7c8dd2f30bc7249ea43fdef01c61389e6094fde3ea74f9e78aed3005ed6e285a236f0768ec632801f608f9a3210affb25b7d2ee8bbbd56b6ff1f315b0b0471bb1f11270540ab1b7e1dbc9e1a1c57140f76aa1700e00f85ce1e6a330fa8610513d4a3bb957adfcfa2bcc03e3bcc6feadf045195c3012362f2c76dc80ec36da93e01c8236f056ced47fc2fee1cfc02a4fbd054bbddc37e814dad523f24df4d103d6819a578b54a3d74d12ae261eb002ba9a813637d0a0f87441a2681f89bf1383377b1d1581234c54f50c22657459a89354c745409c1a686240e8ee5613b21530cd8464aef7911fb46ada7497c29654edccb14bc1557b92c9d776340716fd2a4660738b2d1dacc7bd60cd89d81d4e48813e49d2214a72acff43ebf57f59f50642a2b475e00bb779f2433967ee81934ba66e5116e1e55a927ffd2f6adc20a70912d3874e08e9706fb67f373cbf23a9ccd3c68c8208fe3ec5e22e44c00dfeae6710c15d67993a205347b9bf6704ab0ce5bc0cfaf13117af78f0496ace9712c88d2a88d12c07eba2cd77041edae5bc4148d08a63f56ca901437991e2f0c38a22fb98cd7578123efaf2f8d9a5b9e1e0e4e60a247393abdf5f19f2e5f9239594a450a605c6fe918c5a11091338e27270964f99c7c1d11d34d181ac3fbdf1cdc07978c82b64734b6ccf3778f875d6f1fc9d4f9fdf907d634f78e7d1a7c075a91469a4ab70b7c80a4c33b5c4dbe78011a374ac110475ac12d9deea420cd8ec750a019037aa0e33c813b69fb01c8dbdd769ea1a29f9351db8b20c1240b465b0a88ff5fede6ebd58c16b091a9e3a14f580cb93da271b83eeb6ead3a66323cfb8302865d309da6a17a969da2416c27f0d99f301e769e9490df4716a915641ab74bebf54d4e85d15219491021ba12cb21993a24a93c7bc61bbfdb06a8d7d4123f83ec84691c23962d65e610162895f59fec9671b810c167b72c147506cf449e704cc0ddde0005f11084ee64595e0c97663f114b81dff3e6778e2ee38a49289cd8ce30eecaa85e420b8e139bca9f8213b488b7d08a8668978b309bdf7ce78c48e2b2af84aa1d383a3e92305533ff55a267d796161c89c5fed7c5752a8cfb1a096660e50c4e2ba8f7de58b63cae39da2cc9623063d425a98f8efa97204cb3a3cd42b52b261ebe06be2f76e136c439fef1f9b8368fcf61a2bb2b5095abde2976f31a9e5b2e147cb7c0707f60961e85d27cb40a11e6b5940b0b0f963d2f949fb415d367f9422c1e46cb08677eb8f57a1e7c5ddbbbac20719b13964d1d9dad47f58f2b45a8fdc0f9597e46310656d258cd9c02cacb7b9eb0c21d38657d989e0363630f9b1f93947d838e67e0018e899db9784709105f587172c131624d7ddb46ad5834ef0267606f2fc4d6d0927676d3c45cd2993706332726e12bd956ec26aa5c9c0460a04ffede4570439444406dc7523e4463664341e666cdc818ca90da03a98c0e86a0f66c39b88aeac94dba67d96de0c5c074f3c0cfb2df5f319ebac09d54dddc61e44e9842045262de53601ac9afba451fddd085b20f380619103c7acbd8c7f32e5bfe2fb5ba21f81c45146338ac2c8d29d45b69aacae8019888ce7c227a299887676c7a329eb74a1b73b209de1b78adca7c7d0a325972ec404908a2c7ec08c0bb91737c0fd3ed340c19c5fa3af3ee75303464ceda11545f762d72c5207a3e2d22c29a1633aa662de31e6f95850301616a1169088443e2991beaade370c556a5c46bd47f2d6dd81c7ffd7341257cfbcee04e40048e4a88a8754b1685fe7d412980c117136a23997ee45de6a4b1e947163f02c3a141462a398ddd4eea1c4d0641cb507a33622f6127cdceaad2e40e43a8567438fd7aac5e2825112de80f08906f05462716c902ef9420267e687acf324ba9265f0600495ea0404731423f9e49fcae67007a543a7c13f2e81a9dd769e82a22b85f9db7a4344706b098f4279bfbc2590c058a3144ba79ef3e5b4fdad93cab0c4e18415735c074f871921d97c29d9eab4b75ed89b90f3ce5bd9d0ae3488d5d9261c889d0b2d41262e538f26647ac313f7d931df00e50b7115163b35c5b04b3edc6df750e655a62f7bfac23194c1e563b0a2e7a100e0dc35e4e1fd591c355b78bd7e19e35a1c57da903e0dfbb28a8b6799010c8ca27f362e6baa809415ec93d65d11ebef6e8749e321de258f02d370300a05c326af0fb8fd8690e15b062b9296f38b3af7d3e693f4a321ae00e640eb93029b651f2ba864ded425bcec92613c384436a2ee64ecb9ddcd132e0a9d66218ff334ec1a03ab8fa66555bab3867b74833364cc04b67846799e800c4a498c310d3cf7db5f3a62cc2f7faa4d622460b43012917a871c5601d9a74a31e2ac09c335e6c03793259db58d872321b4f8bc543a92dfb7e9287d361a8eb0147d073ebf00bce6960d98da768c5fa4c0774412be0b1613710c916dac3349c9469a0dfb9d6012045804d9b6e3d1c02bf45c8078c30021b1e749a99dd4cde3173de04fa6b36a7471f3b12e554450fb9201ed8a670372a2c67525f3e3a6c166f0e94535280bf00fdce22f135427e2a6ff9273c9f78f7dd792484c49a8cefe1443bb3e03b3f2c05d12700a1824a9092dc7b03678b4ee159e372af2441556eab73d68dc46bde1ebaf985c881f846c3d60dce7eab7aec3b9aebd72e1063f2a6014818c61414b07b9abba63aabe59d69cfca3036ca60288ffadfb1e54b101066889f724ee60a9558f0ebc78958f05f299ec2d073af978ec00ff2b7b8efce1a23f1d61c3613238eccd23b21be10d5b02cae011501d61599bfafd135084268b5895cfc5191bb3f12328c246a0beaa512903d79278ede3aa32dc4828ddb16689317cbe626b34bcce88e21b6526377688650741d776b35f765d5a5a86347107b1cce758b2f812901bbd5cccff6ff1c1d133132bfa3970a36f1f88301bdb7d418965685ac5a6194cff5f99daa8cca1e8975e5033e356695489cc022a6405e5330116e90ca5484a18c49fc382738f7db13a7bdfad068b4f5d3c94eab1f411d932efb41e45f6436ec67e9a153eb3ad6d0dd73b761be07338dc4922f0f870870734f28f126e0e1f03b897caefbcbe7e0bf3e0c17488a1415f0101cb59b2eb37aef1f60b96c8efa33baf3a15fe574141424c390b82b0db395d25392d116f7b8b08af7ecedb0f749636396d029468082b7895e15e0be6ce8b8af43b8de9e8874cdee334ce52546caa2b64331cda55a63224a3e5006b8e13770044ee3fb3685b4af733d36ef535d567c32743c2fb560190eb55b1a31c2f0ad4ccd9c5e8749b00599694699e3211a12f8c96d591b10372d01b53d4d6f2bc4f884ea4a97334fad28508a44b9f8b079a6ff1755e58b8788832186d9e99e70d36048efabbfa1dd6f74407eb6e325cc0c1cd17f1853bccd0e8be315cac94a08b092f40f953e43d3126b4f15b69d0ee11cd45d9b1775909c5cc4c0b9774ca32b4e1fff10d56362623a628711b9912392ce0291a804a7679071f96650286d2b6c0d2ac2fd268876a56dc6a87594705563259ec644d9984cc0aa36ada2f8ce67c53fd20efda449228674fd2acb99f2283cdd2d76f93465969621a334b453acd29b2734d380e20516a6ff0a6c0cce30ae51dc364d9db57d59a288f812a13dc11d52a3d9e263e1d14e9d6e0f6f120dd05d47e8a9f8a4e65499fb8bb4947f20badb8c3bd5335d7a32e8dcb18a4bed2bdfbf50c29d7b990afe4ceb857f8f2ac249a4a1374df309861cfdeddc6e0917c82fc2e1d2fbfc75391e4a7c760069bb64565d771868583db7ad75a227171cd62eaab9870f61bb050c60e4b33f716d986d35bc7e0bb0f78b50c5faad1c4aeb6c2430b76ce51b0f544d9c4e290b10339b215de8083af622a7ba1fde39301e7760778d1ba0a8de52661c6d3ec81d4d48afaffca72d36c7dc5b670cc36f5d263ad0cf72c3733594c1a3634255becbe01a91807147b737f53a0b2b9fbb63753e8e7bd91dde8f0c0b7e3de1885b72560f3a439c6a41d6f78c98fdb3bb04b1b469d8e9bf0ca2c86d8eeed02fd77c6696d2626da28b27f4065b5ae83c2bd76a38bbe8e5f59ac10ebecf3633b6a5d1517750785fb1bc14e9c50af6c0a3696bf9982c358e6032e30d7e7553fc4ad1d5de2fa297ec0351e5dfd8591efa6a30e1e631dc07256ff0abfdd8142a7540bae5aeddfc16b5afb2ae56d855ff082d761b86c935b9a4c7a401f949d216d4f9d68be98d1b6724e4e7cc536ba35b830e49e48c067f54a9fec319b2f1e6ed9c992db73f0ee7535c31064b69e31c4cea5c84df49ecb12e869a170880fa0bc1aac2d09be2c8a8d0c9932c00bedd74ef0251a302d3069d8acb946a6bba0557b5fe496d0a08b7f651cedee44d0afb4d9ee66060366561af051f15c40b867f3d2a7036b4772dd6ede44c859eedd482327ce511a3a3cdb1ce7630a4767ef086608e5ae9fd1f59e3a1b98ac85e048d8328b30b171a5cb0e871cbd84d9bc7aef90f744648e4f69af9d4b66d2405eb80a93c519b8bb0df64b3c0a00cdc0075ab6d853b716c5398384bc18346dc6c953d847c6bf3e9bc964bd88fe93d85956bd606517b86b7b329d94b4119503435297588e3fb85bcd9d32dcf4c9424de1160207cbe2b702ccfd562f63303850ab4b3db82bc58130e74434dcd9be2cc03fefbf3ad2d8be60e4d12920f51960b0a89bd6a2ae84d05d518c5e3b7b849ed2dafeb1bbc1bd6d2dc4630ad91bf4a5de86abe065df05259f84392744c32a3706104266fe3769cb3834567374ea7f2a1eae69b7bd0191da6f9dcb6a3d7a5c484170895a08e0ecf9aae702d9de7e1b5be608cd13814035747830c399da985a4891d9352442adaea85a18f9169492a188fbacf4412ebd42983ed15a29f5faf4a064069dc01465bd4f280c4cb3b405c69f9b06ed5d9d9724834693a0edc5b0ca21eeb9159c0fd62df5f059a0ad1a7479e3fafe7e0e7869c433bfd86a1def995424e0ad2ed49d26e2f2d708ce188b37b5e45a061a036916427dbe049f76567a6f8311ade3a24ac22c8cd383bd42063bdd6294cdcb778e1ebd04a76eacbddffc055d99ea7494d9d5f627ec80139ca6e5711fcc6b6e058c75ff0543ddf1b61e67b7605c9380b863f9503617794e62d3113adbb9891ee62677daad8660599ec3515d56311bde359466539800d8b996e973a3016457ac853c321a15b4a6495181c0c3e33d4e821f4e4669895032105e1be850f6421dcb4e1b7ca7252766ab065f3826bf8125f8c33cf4bb98d356d676d8c9175d511104bf530c9694f66884abab8837dc9bf0227c6947228e5382f952949ae740b141729db80e3c4dd295116b4fc3846eba8cb175ed9bb7dd4d3d9b9774ef2506b7c82606355aeb10858064f9c4a14c77521dad4ed859fc6de3f1db39b6bd782abdf1256712409ce725ba100391be253201524b2bd356ad612fa7f2de849cda61a3f1803651532d6d94622e799c75cab6d4ee6d35460b6fe7a3fca8ca093c251920654d56affac8d5accfa088a51b78dc86787c3746dffd5a534696dbf9d8bf54301e96f327abefb64d8e89bd76fedaa79336dbcda32a92cb7f61223f24aa4100d7c6f691ac0413c3918593727853a8ee1889623c8b2a870ec7bb23b96acee13c09759eee5aafce08301b3c3bedd39acba4c9adf9694f28032645f4fcdc77c18a1453fa59434d6ac3e324621f75e887800754c05278c4ddf006d1b016aa41b190d88d27bc81e89826ac27915a3fab1d8150de480a47ce78abda03ce32eeed41df3f6702d38a9c397f7d505a59e080a69fbb64d6e01c7f329f884da990092115b6a0782c7a404df7f714b847e047ff80f3f697e5c461bd8f0703b6d89c6b36e7a67a5155bb089656f0837c0d061b62e20746560260dfe5893ea69100f98721cd7378cc1d29630e241c08fa71435ebd9fe18776f0d0936d5e428ef9b2cc18da55260b83f9080df550e37b9cb2db7d34c6e6ea60bc33e5874074e208b02fac50ad1a138eccd36d1d604bc53e7633c370165d7bea099fcbe31a724ca518e1c89083801e6d8bbd36166a2d69c85726030eb898bd7231fb8e1b231f34b32f427cc4419dd8d2cc41da2fa827601ff34a17927cb25fb3d9cb1433c0c7a6958da843d74272619c91a7369854512502b453c146faa779c6212175cb6e45f196cdfb224e718addc0e2f5f2f9bba62eeb44985b6048114c7e2a8cb5c36f39e34cfbb96bc2fee1cb176fc9d3f12bee04e5351098b256aa217129206154cb73274754ad442a0fb98c497f6986cb0fdbd7822289acb2dc54393158f3c718e866e7d4f59b33ebd6073f1b94dd8ee5413dbdf0353ac35898a66e0deda877474654d9fc7a03291199395f38b84119ebe58ae0ec467b5a3485d34ba54e71a597b2f7f793c5a9df04f36d53ee5fa3c88c912aaa668f383b18dd04ad88e17892831de2e5011bcc4780e320273be92be1231ab53108368e24818671f618e905ac5e6a8af2b5dcd1a7b4d0f9f3c07a7fe6566c61deea03bf970ed385584fae037bf764dfc1cb728596e08aea92c4c4424679f2fe6102ad90f9d947710939c79eb0fb022d5da98018bc6419c5c3477374050b1fe0d07013d3e9cc584ad52712a21f989dcddf42bcf36b2d380cdfbda1acb56f41682391e9ac9e425b430896ea37f62285f0ca5f3785078dd62c37ba082e2c0d9c65a6950552e24f3a22164c4b0691ace5779c9c010faeee44989ff4c240b4c592b3e43742988708c8be22c5acd6db6f17baf8d78fa51053ef02763b6263949addfd9d5c98cd34c044dab81bd6a0216a93edd9819be6e9b23903d657e9675f2af8fb06cd7919c7eae81da7699b93c0e8d061610f5e99196f0b2e0eb0884e337567150ccf2627e5c1b9a11007451c0eea7f181b1de540cb8b0a4f83edc73244131433daf323bcd13e9016571e88ae5691a41b0eb2d9a85827730a61f6bf5b82a9b076a7976224b8492a46c2f15775597c80cf683e868bc444ea2764c8a04f49747be18e1cc0a59a61dcafa9684ae4eba675a7cd05a30b0e082b948020a95c5dca1b8d5bae0c4200307e02868b8a18c78715aed4b9f9f406c7e76de396e00f495d72d7a07cd5215d5f049c63e2c4762f462b62b3902e1319ae1911c3af54591692203b205e1440389a5870360d89513bd2f30e327db37e39724dc58b272ce54a46a25b9416f2756b512a8a8f4bfc88d18bb8910716cb6ad9f31522e73a0e53079760f9bd9b6503baf2f5abe365811c52d2b16646bd445f9f1200c8c84cfa6e532206bcf49c6b9508274e591dfb21684bb938c37b108e75251c7e3643e17b14e363687cc79e071bead8237b6823f29ab9e790770d113e65923340d23e3350ae8566879fe13198e7ccec8df44cd7720520eff7c80288770050e626b62b7beb35a1887ed9342ac91779868e969a2c854623c49bdfed5445472eb5dcafedee0443448cfd4fc06f92b4707cefeea89c3236f0fb34d7e37f0fa9322ee69ecfaf3f2538cc7e9788da400f34b0ae2a49dfd5aac92500565e2047835741d1689b2e455a80dec28da7b392070b4d97ac3627bda37fd8fe9296c391471e4d12b969e4920152db5ab358dd962b990474ee2d07b320ec2fc1c44648ba11fd876d7d211eeee361a679306c0a05ea45a7ae5710380b6b1a03a3c8c4786215cf5e6986c13dfbd16b0f7947a101ac0d420e1434e882b204e03c9d3081e296da60cbeec90a3522db9adc610ff8969a6b8c6381c3d4543bfd88a2f69d6008862ef0a16fcdfdacde40606d0a360bcf0a830a9535c2aa1aa9ac116a6d8d505d65aead11eaaab674bd52e58ab946868e71c1ab8bb59a597393d875f12c9b97851999496f4c15288a761c5fde18a8836344f80f0299574c1b4fcc18ffabac4ee35a3d31653c314afc49c72166f54f9142686a76012d8400caa2f5eac2ed1b79476d824634a0ffea929ae1bc000b33b6e004c142081636aea8e18a17aaac6e1c31ae66715e219b978a0ba699947b4a9295374bbb66a93b691b93b88a0fec8c3685d014194ca1f3df93628b14384f0adc5f5dd73cf5c5b30ca04126c792286cf811459020393c2d382049cec0e2468edf83c100f76070e11e0ce63d18c47b3048b907c309f76060dd8381837b30dcb8b72505f7b678e0de1632f7b658e0de961eee6dd1f27f031d1af8e8400b02ee69d9e269d974879cd32e6e4ebb8071da65cc69172a4ebb2871dae5885359cf69972ea75d6438ed5275da25e7e9f8c80efc23b3f84736f18f64c047d6f08fd4f28fdcffc8da3f12ea1f99f48f54f28f6cfd2383fc237790cfd163c78e0cdafccb608c7f197cf12f8331a76f7efe6550458fcf6be29f37817f9e977fde0eff3c037cde0bff3cdd3f4f85cf9372fa8606aa23e6548789531d089cea0871aa6380539daa531d2aa73aaf539d104e75749cda50c1a98d31a736c09cda98c0a98d1e4e6d7039b5d1c2a90d7d6a633cb581c2a90d28a7368a4e6d0c9dda18726ae3c769ce9bd39c139ce6a439cdc1e234e702a739459ce6ecf0c1073e40be9e9e2c63de938589f76481c07bb208f19e2c2fbc274b95f76489f29e2c48efc9c27a4f161eef798104ef79e18af7bc80c47b5e90e13d2f6479cf0bfa3d2fd4def302d37b5e107acf0b1bbce7851bef71418df7b8c0860aa938826010667c4f18da7bc2c4de13e6c97bc230794f98a0f78421f29e3042de13866ec0c29a7b2c8cb9c7c212a73700717ac30da737b0707a03eef406dae90d51a737309dde70747ac3929e1f3d5444bc876a87f75021e03d5402780fd57e0fd5cd9b6ae2ded4977b5345fc03d2c13f2038fefd38e3df0f11fcfbe1817f3fb4f8f7038a7f3f2af0ef8711ff7ee0f07f3f806c16ee6ddbbd0dbbb79ddcdbadff1904f97830fde351c23f1ef51f8f20ff78e0f8bfa3c17703c73f1e34fef17c3c1df8c7c3c53f1e32ff79fce0797382d337659cbe01017dc3c5e91b32a76faa387d7381d33710387dc380d3375e4edfe870fa8686ff3f3ea92affa49afe4925fd9352f24fcae79f1408ffa47afc93d2f92763816c8dec03ff641cf827a3e29fcc02ff640ff827f3f24f86807f322cff64b97f322bff644eff6449378050376e4edd983975738153373b9cbad972ea2600a76e68a76ea49cba513a754374ea66c8a99b9dd336679cb6f9c0699b31a76da0386d2381d336429cb639c0699b2ca76d6ea76da89cb68172da86e8b4cdd0691b22a76d32386d83c1291b179cb221e3948d17a76cac386593815336113865b300103e1012a4c70e1c6c8edc63b3bac726c83d363ceeb1c1b9674609ee9991e69e1954dc3343897b661c71cf8c02fcdff1c3fbe1e11fee611bee6118ee612cf730790fd7ee612af730d43d6c740f07ddc344eee10dee611ff7706feee150700f57c67f1c3a7afca06c70a76cec291ba953364da76c904ed99470caa6c8299b11c63f97bb77c5b8773970ef4a71ef2a71ef227183b87769b877a9eedd7befcaeedda37b17c9bd2bc27f1e94cb16a75c3070ca6502a75c1ac06587532e0638e592e5944b3ee5624fb9449d72593ae55274ca05c92997d62917114eb9f478c00303fa44ecf409274f0c9d3eb13a7d42c8e9133d4e9d58833a81825327baf8cf63c7f7e4867f4f62f8f784eadf93f1df13a97f4f96fe3d51f2ef4908ff9ef4f8f7e41a7c6570705a06ce2919233825e30b32c29c92b1c42919469c9271c3291953a7644c392563e9948c124ec900e1940c1ca76b5a70ba66cde91a34a76b3470ba868ad3354c9cae81c0e99a1b4ed7ec7cf4f000c80d0e680c2c388d0104a73174711ac314a7316020c84745ca3d2a4df7a8bcee5109ba47c5837b5478dca372e3de1435ee4d49c1bd2923b837058c7b53ba9822e6de142aee4db1c0bd2945dc9bb2c3ff1c1e0f8f1d1a129d8643a72191d310c869f8d399094e67649ccebc389d9d399d39713a3be274e6c3e9ec00a7b3164e67f674f6743a3b3a9d29399dfd9cce38389de53855e105a72ab83955418c5315b8385561cca90a52e4e8e1018407511aff884af08f088c7f4463fe1159f18fc8897f444afc237ac03fa223fe112de01f110eff8868f847b4e51fd1ee1f11f98fe8f68fe8ca3fa2d83fa227ff884af84704f48f88847f4444fe11f9f847f47f4d4ef0af899a7f4d3af0af49997f4dc2fc6bc2c4bf264900b981c18d1f9e0f1c54b6742a333a952539957d702ae3d1600d12f7d6f8706f8d0cf7d660b9b7a6bcb7c6766fcd94ff3d74782880700f057a0f051ff750b8714f4a1aff73e088c2e45e9410ee45d1712f8ace3d2816dc832ac13da8306ea809c13d355cdc5333e69e1a2beea971e29e1a0bdc5313817b6a8eb8a706887b6a74b8a7c600f7d460b9a746df537371f0f8a04ae44e95b872aac4d3a91244a74a203955e2e754890c4e95b071fae58cd32f659c7ee1e2f44b16a75fa838fd6281d32f0f38fd32c4e9171f4ebfd870fa2586d32f594ebf94a75f6aa75fa89c7e713afd72c2e91724a75f5aa75f40f8cfa347c78d2f090eff9218e05f122cff9294ff92dcfe2551e15f12a97f4996fe2539e15f1225ff9214f99724c8bf2418fc4bf27f485ef00fc919ff90b4f987448c7f48bcf887a48c0f1d3d6e7c8174ef0b13ee7d0174ef0b11ee7db1c1bd2f80dcfb22c7bd2f72705028644ea12c710ac5cb299419fed32065cedc2b23c5bd3215b857c6887b656eb857e6bc57a6cabd324d403c0e9812708fc900f798c87b4cb17b4c483cef8022219e2251e51489a853248a4e9140728ac4ea140921d40bdaa91750a75e189d7ac13af522c8a917189ca679739a0605a769c6384dd381d334634ed340719ae602a769bc9ca6c1e1344d0ca76976a76956384d23e5348dd3699aa3d33443a769889ca6d1e034cd8e53342f384563c6291a304ed1803945a3c4299a1d4ed16c3945c3c2299af2148ded14cd945334b05334ae5334ac5334209ca2f94ed1f09c76d182d32eca38ed028c9e0d7af0c880070dc201060702a48726ded34311efe98186f7f4b0df638603ef3103e63d669c788f1925de63c688f79801e23d666c788f9918de6306cb7bccecf798b1bdc7cc95f798797a8f99d77bcc08f1c8e1e4857b4ece7b4eacdc73b274cf89917b4e82dc7382c1bda235ee15b9b95724c6bda233f78aa8b857a4c4bd2207dc2bdae15e11977b4555f78a7651aee876afa876afc8cabd22a87b4500c84177e0f0a19383c8ac872b081213dc8cc10d4d6561020ca840557d79fac1858320ff0f04061d61fcbf11056c80c73d220eee11e9b8d7448d7b4ddcdc6b12827b4dccdc6b32c5bd2615b8d784013dbe238ba7f68ef822e8887704161d2e34d840430d08a0a1062e3570a961861ab8c87080196890610603c8c0458602c8c06506196280610b010620002d59b464d192258b962c5ab20c41c47fcbdda6baa427841505785ed290f7051d17bc58cf4beb7fe865c76b10260883b86289ff671048ec108641b410c4f8b7aaebd7c152420b2b1d16aae4f8e17f796f013f6813dc8d48d5fe3abb5fa7ead7a162ad409cbee2986b574a28b4a48e5043d3b4dbea7459b4424b621e10278040ec00498ca97e30f3c38e555b559a884d2a9be78399833e44c0072e58e70312f601841ed0705533db80ae597a3d30c0f680eba1c9ec41484e120f1de0210a1e2cf03fe75d5b7a1c6d8d879c2d8ec3b6dadba169071cb58b992e3898b8bdafe9758122aa15146bb6daba0401ba66a9031895025d7420428704e850e52aaad5a5c3930e4b6aabea002487315ad549cbcbc106b0958393cb85430e1e0ed7255e9b4c490163407d496c425559273064ad5cae5f3abd52b2aac6ab7abfe58acf159e6acdbb84789f40618a3fe7eed828ad8ecaca09bf0e921d0caaa451858c2a5e54c1429bb9b6742ec95a455ac5ca4f95c9ea8213570bd5158695c449529862b024a524a42a07c1a0aaf1ce53f696a57ded40a960d09a77891ba6607150bc34a8294b53904cd159410a65d014c8b02a89eb08a335af2b859d42134de1033b9675891b4a1d46018b4cc446b52b451f494143ef6e4e8a987f7773456a28325d28e1cd593d2373b8ef8dc434bccb9babb6ac7dae26f1edd2448c33f5d530bdbb50326c77a18822d32bc368ac033b9b20d0cedcfad6485b7772fc3b3b37fe1d9e7f67e7179bfb3b3a97465113a5cc8f9070da2e45d15170a75188fe5328332eedeadd6285ac55b8da1955d0688a5252929178f5befa383d502850228522048a8e9f02a0c87b5891056502a3eefca482acd92af7c485cb5574b535aada56974bd684a84965e54cc1f4e3a04866da92174b4b9c20e57f2d22aad575239700a3286709006f9977d6e4f409185b13d50cab2efa0402d5f524c9130e9ee0f8af73aa1402252c4ec8bb56d7717ea52627484a43f4d998c417d7d200d16002a34930fc55ef6e2edcd1603819d8b1d10516a132d4550692917f4850123d0a013d1a8facfc4f50570aff4ece0eceab6ae7b4dd46f48e36cbd5700ea733ed9ae4994991ccb4a0a1a12354364a64aaba2279c5b5ad9856482b362b342b56ac10b1d2aae2c2710cc101f2e8a04ea0f835256a821265306bf2adef94dedd1975e108e1d4842d6ea38723316c18a12313e39fcd4ce861c28e7f08216e630174c90a269ec26679c5ddcdd18e234509553325657e902ae9a2a4004a9e58ab3ada73aab256604df22509016892f2206bc55add48b2c2c9419148b161a748707f5113194e11392cfcc7d109c169678c76ea1c3249489d1e39811e61d12341fe0fa93114c6ababb6aaab822d9e9c212270046b93c6d1f766cbd25e9ceb38b4ffe469501a3408061ab4020d4a811a496304cc5f5d366ee4f0e0f0f0ec00c9b1a183c3c6ce07e48a7aef0a1ef7c2a8712f8c9a7b61cedc0b53c5bd305fee8501e25e9803dc0b33c3bd3058ee8509c0bd30f75e182bf7c2c8ee8579dd0bc3e45e989f7b61e8bd303dee85c9b967051af7ac50c17f10e80e0e203c56e0dc0383827b60d88051730f0c1a301bb807a68a7b6096b8078601f7c0f0700f0c0d3b9480e0032dffdfe291f3e3c7c17990137844e0c6ec8c9d333d44415a7ea431c509529c5049d141981db4ecd860866a248a2c126881841b1d681981880952a0e1818667c7c7104e2ce9800a172c41916809e40aa8257428e025051228580861a1de9382e75e1429b8174518f7a248732f8a32f7a200732f8a0bdc8bc201f7a210e25e143ffcf7e14531742f8a9e7b51e0dc83c204f7a010c13d28bcb80705997b5060e01e1413b8078510f7a0f0e13fcf0f0df447086b0cca62c0eee658fbd5455938bef2b242e283c6abcb078c8f0daf2e1f117e12a4380929cc4630c1081538961190e808f4af2e11c0f88c8a90c45f5d54842dc209d54545d831dbf706a6ba42c0525d48d515c28eea22b2c55f5d3ea7448a7875edea42aa2e4a8456171d52c638dada90248660f9ab4b85d321f4ca6985c0ff8a04c2163f0561a4200455171a7f7549f15717fd6086bfba3e905517fde0c70c00a71e3cf157970750a742c2f82f864075193915b25f5d54c89299109deaea404c7569da41f89f76d0aa2eca81149a72304375510e44a01b98413758e2afae1c3de80650348819bfcea42befb334aae9a441d305175b706003674eda158d6830010d8ca01a78a966cafc3aab32394c3483235f699109d479eb125f7ba9c2b0d49db4baefad956315bcdabc782cc330ac4c58452a13d3e95ea5d1fed4227555896a89f76c64c22af15ed5465b9b11ed3b1a31525b5b9f661886156cb14abc6b262bd06e34ed8875a70914563297ba5cb33a0c439d899478d7d19edbc45344eadda7b661c55120608c59acf0eb18f1bf76a7aade5d285adf5a55d24622b19378c79ca1a444729f4f22b6d4470c4f02c7538775968d106442c6a6256f4d575b71b533564121579050b565a1abcd4c555b24b6b820a15d83842a78036995aa6a1b8e53596b1c92b7cc61252dded604ca1b488b7797b99a78631163d3da6ad6e368cd3b95443b75cbeaf2cce6930a42a9b6bacf6c6fcdc4154c527ac5762b0c6b51996f262d8f1a6b4b45abba8e3913b93a7bc3394dc4c467992da87d42a030acda47efd0691c6db84ff19565e28ded0ccb30f189eed4e1287da7ecd2ce307d33d2ce30d21e6927f2964fe6937973350c6567d8ceb09d61398da3b2d18e7c5559a73167a82cd3463447643acdf9f19fb5a23858dc31ef71a4385bee72c9284e93ef48fbbfe9f465b85cd9bc54f678da3c03afcb1573b9644584f4427e6d6672ccb97a6fd2fc419588a8b24858bd89c0ff9c3314ed8ced1b2b7386ddf148df314791fa5e53698d24feb20a2bd6d0b2c6d2be3a6b5aa83570fc6aa4a17737a7c605d480801a3ea8a100356250a385ff699ce064b6461b43c16252a09456376315c99ab85c5147f5a712d5b0823730a982d5a9b6405b5adee44e87b746e659987b8a12efed6669376a6bdc04def06e8d9bc2baed98cb96d6b88650c1dabeb52534d40a12aa66ae4122aee49523b535545b4255c2aa972019028576635550d0d090c6539976cd53bcb51a2251526f96b6cf92b5daf7e672e99b350af51d4b9d256d4ddf2c0d48e7c29025548b54591dc89afdd42bab4a4454af08d5223557256ce98b4d735f5dbeb76a37998f6a0815dc8d996aefc8dc22b3de29d1429db6b62aa9865041f26669e6bd65dde725efb665d70c08ebae9e51655b4bbcb8927ae38bdb5b8bb89226264f267d666cdaa9abab1eb1ddfa6669374babb99acd9178ac30128b997c55a84d5e9d88b31426f296519b344fa328f17a273041f2561bae9a344f23f09ab6d450a016c9290c05be6af5a9a48dd5f6dd55bb336c6798ceb6ab81aac8042526dac0228b2cfe0fa958b054f156a2a28a054b65ad3406ef356d5e0982ec461278410233ff7d7c7c7c2a14332b95522e17097e1c149a9ae53d0b9aaa51b319a8c77134710de7125b4cab3993565b275b1671f509c7d11ed970dd91f96a7d8a585f73679d2aa87d70359b544171cc7ab3a0aa5e5570df5c4d9c92aa64921e470b25922493a8f114ae4647e215b185122fd3be37f134027577a465b334cf5cab601856709f7967a170a6da1976a7b0269976166a97a79923add1be537686e52cbbdb36e5dcb4a44d7056b46448e86ce2728941458c251f42e2aa6d8da4caa20e993143427890dbee85c0865f9ba3ade5231e50c30d6198400868b4170b31bf8e165884a1a28a29c24c91c5af8345155468a00a30585c41c515617e1d2bc05441c575a6b828be44f19a27d4aeca0341e88160c91225214edba5b0b6940895bbbdaaa2ad377267c72b025d1dde5055d689b5027336d4274e56c3b10459bb9b5bd596a8cbaa6c96b6f1c6324cbc23cd92523bcf66b39978c59b33ad0e0ad585c53c2f745e24a57103b524492c06625bceea6ea9c7da15eb6e13515a92446b22353b9675499258ac8a775bd0878604de5c9eaa91e7d2aaba340922c6853adbc89dc96ac395b5aa578f56a982e1d091330ccf7b9ab21a86ba66b26e32ac21abea8a2453b8356edf11a8ea5bc3e5ab892d5b56ddd156d53a8d24b665a07de69aabb2111089a564281b892dadb62a588661acb2ecb6a5d5ad6a05f52dab1e2d0b4462aaa494f81af111129961bb96654c59a6c57b61576761b55bc6784600c59278035099e0ac364f7c04191b0820003224194b860a9928649a90719131a1cc01b5d49d62a8c7aab16e0c5dae300cab0d8bb7b6ce5b2373cdda9cadad6bda343e61a4142c238de3a9245a23bbb4336c0747c7e9fff9245e1d96914f24be61f329db4826316abc4b22f912af79c57c94245e3064adb05d61b4d7244f5add1627abe46dba9db4db4993ba36fbf3b333f9f3533352ad21541d366f5975a7ae68af0edb3c8657ee48ab124258b5cd59a70a56d28a599378b5dbd80c733937559095abd91dc2ea4a1d475ba55edcd61657cfbcdba6add16ead3c73b5dc049e345bcd7b25dc55492e575825d716682f0dbc15dced6eb565506cd5ca17aed5965f2436b1b97753f6e22a9e4a12730deb8d5443204f9d2ed7b60f0a15bc269548e28a59b06315efbee315b1cdd2ae59992a78a482151caa2028545de3986b96555b22ce3f3f354ce69dc9acfbf9a9f68ad9ea976dbc31517ceda060249396ba495a244f4c5ea45b3333c9e47494425286e91a2e63514a5177c43814c42bbb48623eba623ec2edf22269fb641c2dd555ca59b623ad5386899bc4f585348e2f00ecc6f1457561baf18ca2ba305a02b104577e701c5fa0cd6c8a92aa34bbad79ab64266575977154b7dcedbd2381742e6dad824735a604c5542f4e06b5332cc3601aa7ed52ce4f50b891fa25dead71d3ce30bbadf9242ac376aed90cf6c4148b4a923273b9608d086015efad9d51e603221003d4393f8800f77f8893172a82201c231a3046191fc7178e123a4814f008fc973acd028731c48f51f44b6624fdcae285b2bb50442c9e313524d8dd9c9d65f1cce2a9c1d8be31bbc91b2bb18c498fe30b4a773753186a8431268ca95f368ef64809d4d7665e28701c6d4d9758465e0ddeb04d97964a57bd54c1506462aae02b6a67589575b2db22256d123b9178675886218919b7af5369a962ba497737d3d6babb8b9a680d54e29cd6b98fe370f1672e40d8c2015bf400ea6c1d479cd3e7bde329e27ba7844021a0da9d225306253300f22c2d959e653102aa012d1a40f28ff019f10b801271c62911233825c203a7449c3925a28a532228704a4411a744e8704a8497179c7a19c1a9170f9c7a3973ea458a532f1638f572c4a9171e4ebde470ea0501a75e6238f5e2c2a997f3d44b79ea0577eae5caa917d9a91728a75e904ebd30f90f44074f0e5077457933edac469eb62b9854d7589e5b5f599933a9c449a8dab211764252415bae4d494ed59ee2d192d6dacc4a1743d99e48ab6fd608691ced110ab68ce923aded68a4afbe6286d99eb4d666568ad2175765d9b6c1f4986df7ee2c94dee4abb44e1ac9f6949574ae969bb4b6e3911eb23dddab445ed3f65495a964a575926272122aad93eda9c9cc4a5a1cf392edc9f66466a56c239974a7d64e4a844aeba45128cd5b9eb12be6a36b4289a494ed49d3ce98de5d28bbeac2b4d646312d32ed76d58599599be79169ef787477968224326d3c9631d1b4226977ecee3ce572ed2c6501460c408aa49fcc58e38ec42b6544e22a0b8624b64edae2aa99b7add526d376e92a1d6d9a1338dca7b60470ea048e2a2bd648316fb15ea726b268228a2628d0c4114dcc605e1f9fdad2425343424c10e03f4895c7f12a854a61d5a32ed4ae21212726a49820a24df03796a0b2440a4bb896008b806aeda187204c701e1b8947aabc13ed8dd264c637dddd4ce479bb46f74cbaa2758a8a32cd7c245e6dc10c0592d88ed7bc66be35ad6d1671359beb1ded6869a7ae761c6f4d639dae2c4d628b3b226f4edbbdaafa9af988ea9219f6626aca48597623314e24a5ce2771cc31d1bc534f1946dab1cc9919855d9ea629e22c25e3bb779ec25064c6376d82498c439c4cc08c09a019022ae7386e2660af4d232f1d96e1e4208128feebd90daf70cdca24a81631112f4e9fa5049afcd7340269d82b424123e0e3ff295657d3542e8d88f7a8c4b212cba82e8c3e803ee00a7d000fa671b4476089b72eb10cd425968125de37df405ccd82f79e77c4b6aa73cb485bdced5541bbad88f31969212be3a86a6b158a4ebac4b2aabb261479cba771c43ba6b433acc4b21c2154882cfeeb1ca1c508141821c6f7358204238218c1a388358ad8e26015af5941d9beb19c225a84907f2700ff71ec9407c7f1dc156088247e15fee3532176fc273a1d2285ffd9bc2cec46bd31adda304e97789778ef9a12f00850ed8ab90674475bd340b5d99873b993ff9c0c907f958867a269cf5bd2f904080b573282100e109c2146e4a911edd4a8e9d4c8756a544f8dbe53a39cd3d71aa72f159cbeda9cbec2387d6971fac2c0e9cb01a72f1e4e5f349cbeb29cbe56387d459dbe9c9cbe844e5fabd35708a7af0e4e5fdee92be7f484344e4f40c1e9096dfe7390818701cf0f647ea0c03f8e670e0f0e1a2dec00f9b1e343a7849d1e383b74feeb4e7df0a28de4acf1e1045b234f5b585d60f430e63aab1d1e1cd06941e74938f1e141e9bf78634eb24501e989292a096a96f4e415f5248bcd644d522fa52424972bbcb61dad567d33edb648e2ed92e4ff06a75d8430a94e391a25827f67878eb36ad501091d82d06187a87bb350494f5020697535d42e973ef36ee3db1d75f7ace23d5be25963d9327825b43d91b7a9ca3a8555ea8e365afdba379b7149e21b6b55b7b6328d91a2c43bd2461c25c3eecd42655802cc68f3ac619a001bfe5bd1dea55898002b234e5f5329012d175198805359d990053865c6f6d5fbc6c09d477d7536f7aaa0366f14ed8c1dd11aa030ed58abbaca3a81bade485c5bb65c771b57c12aa8abb24e15c4e62631996db4538b35acad519849d65813c91ba66d53e716c6af0a6e7daea0cbe0c69508edd444465b366f79e6a0458c0ae569b7efc6dbbca5999568e79dc24f60e2bd4a3a0bdb19964d33e98c42959beeb64862ce4f48aa4c42b923cd4a651bc9248e172b894ce6684acd00fb2fcea0430a899dc03034a92e8ca9da9ef6f944959bf66b67983593c42b5e16704c4a6cdf1814b3a63192383e89175b286b26511898bed8a20126b63460cb10386c11c096dd96710b0a5b983e9b55599d1449bbb91d69936c18eeb205449a5929672fd5cd42852e97ccbcb68b044e91676ed9706ded68f566049ad976ad99645e286d4d70d7aecd469571ba86bb3c4d9a9dcd6e24defa822128de300c71bbbce20ca816d510bc205305c3b0b6c2aa2b6adb35a15c616d9759a9823b90f553659dc255ad0a7fccacb4c9d3485871fa46e2b0da70156f6d553568af842e5758a546ee7425b1b6b47de6aaad2d75056d20ee86cd1c5ea94c663712df5995b0bab413107982acad7567cdc4b5ba33ad3577552dbca6356f76920531f99049d556927647134b7cb350d9c816c9b36a922ac35615dcfa66a1c2da295e09ab68f1de2c14697555b461080289b695455b3e6dfa96a3ca3aef6c0b2b12a1a9bb7d486d714c2253cd8d272d676b5205c32bd64c6a2dc9a092906653a29e6431a6a50a54ad995425ac2466dd29bcaf8455c02ba136335315f382d6bc383363aa8c6b59f3d64be62ada3655d0bc3a33db5caeb0ded2eaaac6ac15c85a997763972b1c4bddbe3ab76415b3b6dedddc2c34f1d5d6bc12da9dcf286195aa7d80c84c9656b7bbbbb185715ea1d4ac4bb32469a956b45dade66af94a1856a93bdafe91c5a49c7e4e1c91ca5a65b2b6c2a070df319b448854f18ea3bde4d6d746b5c2edb4bdf59a3ebbda95b21b69b896c9f28a986a1c31eec81a694dda327623f1ae4989e4cbf69465d6ccb06b66272d5e135b9c56c105154a12ebaa4290c6fa0a1ae59532579ab8b2c41fe701b2fa797c48f8794610e1e70981c8cf33a4fe3c207cf0f37820e4e7e980839f6783203f8f0619fc3c1ffd79bc9e9f07c88f9fc7478f9f87c78e9f4707063f4f0e1e1c396d756fdee4b4dd396d7524be5dda9520212e64b23e774cef764e5bd9983354cddaf0aca69be1c7ff217bc990d0696b1a3bddab24c3fd3f196efc8be105ff6238c1bf18caf8bf636b3cc26ed6e8ea6c8c64c253314cfdf74ee1260d8311ffd091b326a5a8688992264347a4766bc9d964eb7bc3221225e71573ade8db8281717c298d390a1f09490992828bc96a77eae5d540ba2cce40002e3e023c71f1a4d55ae67ae62909f808707fb3a3adca4e2c33150650817f080c0285a6928c9ea264b110e7380cc0d1267869d9dc3a083c0244e2d1bcba9d35d4f80620844b3b1b0291804140b73ccea672a13e2dd0ce0bfe1d17fc3b2d406387cc7ffd4f00271c9b00048747065a76987a7d5a5ab92f8b142c58c1193b59767654f0efa4000537d6f85e787d2efcf0b970001768a83b5aad0cb8e1561e002e391ca1c40fc57f21be1654c044a8023119d2f726de14be16b0fc63a18c8f05313c394384a2fe0b090121f90754e41fd0907f40f41f508e160a747c4536f0afc814ff8a50e05f1122fe15c9e15f912dff8aec7f456cff8aa4f0af88d1bf22ae7f4580fe1521f2af88907f457c14c1f1af888d7f3f6bfcfb7941063c7e56f0ef8704ff7e40f0efc7ccbf9f2cfefd58f1efa702ff7e82f8f763c3bf1f2dff7ec87f3f54fefd2cfdfb71fd0cfdfba9ff7e32f8f783c1bf1f9e7f3fffc742019a7f2c0efc6395f9c79ae21f2b897f2c2fff580af8c792e11f4b003b783c9d1fac0ffeb17cfc63f1fc5b9df16f45827fab31feadc8fc5b81f9b77ae2dfea01ff560bf8b7c2e1df0acbbf55eddf2af66f75f46fe5e4dfca847fab211f4030d840874a082a1b3ee456d6aa227d5329907926de286d8a6638cb3692a9b51bafc647152473254f13ac56675e1978454ce24c8ea3d5e5bdb99906592b91cc4635bc497bc3b7ba3579f511b8ab699f4b9e55fb9455b7b634aebd44d66ceb4b9b8d96cca55405595baf5c24936e67bb2d925229655ed134dafa7412c96cb4b35054b9294bc932299d993f5ffdd23da12be207af54a99fae04f3349d8e6ee46ba7d39d48fb6aaa580e0b2845df1ab6475419c6a46d53ce515a8fd649ef2e14b1eac286ee7846ed2e945d756149bbeac29cf4c54c3b8f319cb64b4655d6e98e25366599463269d19a49dadca4947849d28e7a3ca374dee7ebd6481c1b3a2295654eba2c92d60923555d1dd3178abc4d49e3f83a91866ca614a8524a9b9724cf286dcda45c4daa299674b1bee4ddb6c92957cb636c146fd585edaa0b336d9316b191933ed24866d6175f6d71505bcbb49995cc2b5e53bc349b2d8f391f814062c65609046b6bbca4999b40f1e26ae46947cb5a55f26e5bae54792909bc53e3de98265e91b4a4ad35ef7163d64a34732dd46536a1c20a54cd5c9984a14541b6b56d0a2b5075edabc322d5de7837e65deecc9a79411eb488615e6b719854411a79caaecdeadbba361b935550aa829ab5326f594a5d32e77d330ca7ed92d3ad51e5261bc944667c7396565d514f515149f588e9c95353ac84ff1dfc8b098942bb36c1a816fcd7f91775c61735c60762f1b76e2417024429c0ff0efc8b1202f10680498e1c39726020e2cae4de1893aa7babaecb55b4444926d5e48b124294544c8ac8b42492b8a66f94181525b5afce4d5b9f48e2a5ca2299f474c53548ee93561b72c97c7353d65691aaeb9278acbabc7736aa60de365ccd53eb443c75e61d53056319a9565bcbb392b7ccae9cc66625a97235cfbc13efacb6b27959c03f3f439ea292a854d86b4956a39ed424a32a8b49395590bc65ae15b4d76c8561b5da14b10eabbe365b36aa6138a58661585da8b5a8c86e8b545b2253abd5448771b1d23a11d56be65a6b0bb5d63be252976b990cc3b06e4c9e4b5bfe43f9b764c20ffaf8549788672d6dbbe6f7c402ffab91bd4837128be42dab92f0263326a5a82e4cc434522aeff3256223f153927de7528bd8a8ca3a8134eb441e813a57cb4d55d60914afce62d2d640ad3bc58cc9acc112cbccbbb314f2d6481cbb356b3ed117ef8b6b2d5b5b6258a9ee6e6bcc426232711eed0adb969871cbcc3620d3def1a882ac4bdb59a7552d02aa661150ada058621c6eb156e4152bc85a89a46de920a01c69cdb05e11a91e55703c5f150c5a899856b5cf995ff584da198694613bc3447b977686997767183612ed5d32229f7686fa4e097646a07980e01b22f82ffbe7c3459f4d30f1eacf05c3e792fa4c5823cd678299cf842c40f182bad0bc25064d5c5b6118aba03eda1936b5afd6770a3791e669a43192389e1905d11a65f352212f0bd9a4ca4dd6dc554957eb6c2a8d77297634da236ab4091ef1e03b4287d0181aa3da72dc7c433f5457fde26bbd3004fb75aa3ed6cf378481ce27e46503960b95b57281b5d542ad35e3a8563d9f8f0782d81cd45f50ee0b8205b9c0e37c4692f88c7819c067a4bc8809f01959721c1f7080c8a162e6bf9179b43b8010c0c04742183f6b95cb338d41179c9ace9cfd0139f9d561f36b1db9fbccbba919798a98469e22a6e16a67de5acfeece533a3ab800e22c04e0cabf11c07c240cf9c15a86d5c44c6273e3f08d0055c227c216da04af591ab9463e1170c0bf4e38d3b17fae04d2914036738a47086650994b4013c020201297d766ed35897616000415384ce088398363e623920592234336e37d493cda6cd9b5cf0c6433a7480c6433a394a2a4e0b45d528a923274c49aa6ada43d5513c6a91a2f4ed56ce0544d064ed530a17320366ee48c4085021b56d460c06d54816a0a01500aba40635b09e3bf50102bac81c3ffa12015ecbcfeff04200c9839ddc0d006e8e999354ecfa4e0f40c9bd333684ecf68717a068ad3335f4ecf2ce0f48c0ea7676a383d23c3e999164ecf509d9ed9e03a32f06e9c01727a26e7d48c9b5333223835e3c5a9190e9c9ac1e2d44c15ff3f0ce8182c4ec730713a6602a7638a381dc3c3e998049c8ee1723a46cbe998f1744cec748c93d331249c8ef1713a06e754cc19a762ba381513c5a998244ec500712ac6865331584ec584a762a29c8a799d8af93915434fc5ec38d5c205a75a94e0540b34a75a5871aac513a75a54e0548b244eb538e2548b214eb5f0e1540b049c6ac1e5ff063a2808427a78d044ed00b205035afca84e69e4d8e1861e3e00c4ca17667ade58f11f2978f3a34a890384346cd040054170418cd0c00d93097e5840512d6dd271a49419c0bfe3030ef760c9fe3c08f2a3f109e9428898fa0919e21332c30f0a1141d90d20be0e5610ea293b3db8c09c996d60191f0763000101f1f01fc70e31b18b0e3a69fe9d1c70b892cb9564b33d9146dae2a0c47baf528eb4513e21080685f5de485b7569db6a1f9d23ad59bb39d252e5481b75742371d425332c4b893712ef2c051cb1dde4addac4e6aeadd19236f0e6ddf8aae0b9cbd572ae5923aded786178df29668689f7ee2ce5ebb9e2076976db7265d156586b5c2b88d316f7aa7a67293ab3ef8795ef87079f0f379f0f3076a38f17a0422033acd547ef5a44d49d3a8c64aa5e25498680866ece8e4648a66a11503d3245e67a336c6b0b4532f56451747516267e3b5af86e144fdcd63bd3bc64ce9ab4da6a11d45787b7ad57c21dcdcc9aeae2295d8e17b754c158ad2089ab58f79d42267d3c5a8ea37d3c3822a26fa78c6f478b2ec0c8b497cec4363223817ab4533ad38e2f50bc963c476dc42ccf9bb354f54edd7193f68c52f799af0ecbc8acf50edfac0896ac550d435bbe599a696fd58ed866e6ab6da854f537ca9e746a44040000000000931000303820168bc582d180503c9f503f1400025f8a58b666489c89511843c81863080260000080800080c0100100c0ba7ee276ac3416fafbca5a4b7a2609323aebff5ddcc4b1cb4a0b447f2fd611356135d6350b7b4b176474d9ffa7d3fadb2d8ad06b63bd6573ba9a7f4ebfe3ff65203dfa7f79f240af8ddb5e26ce93d54cd464d09f69a5b5436f4159479d38f4d66d9a38bfd5a89a5880565373e217d1fef7f337319456db26eec86a26d46a6e23706254fccf5e9ccdc8e96f373ae8c9ad1730eb34ffb3ed8e75c30ca0fd9fd32ff97fadde841d5923c67f3b5dfd5f37e93efed53d82fe0fc7674c3b16718896258491d43cc7b68fa890ad1a5f38aec58f261b12462b0aa4f08a69b2c05144c9d5612c3a0af8124a2e5040261b5ab9774e9953e10b7f8d8162b9ed785894178bfa853059a1d54386cb8da4e59ae5fd6353e534416e74cf8386634dc5cbd7930e44428b31621ed814b616921539d45a5276959c4c6cc5ed26476895ddfbcaf2d3fd617b6fea9a1af0ade12fb24d43530e5b878ab9300bf887798125eabdb27bc5e85a66edd2a419f10300e4923786d8933c4effcbd011e7b7ce7d33b4a5e10ca987826a816d55f093a6146b0ec2608ba0afa0a83b0a698fe6b3c9012837e57c98b046f9d71370c7f5b440823c3de6d2cba4d598106ce29d6fca7af72b4a8a44c5f44d1f3ca1ae08679a0e4b9a9c166d270139c83bd41a4165879d1bef2f9e48b3cbc37f86493a34b56248176044738c1c845b455d93c11b251588886574849ec3737579e9f0480898732d9ec4e7eb3d5bc757cdc78c3e11ef9fa535e9feb6303289e4cd4d67d117fb6e175845b5dfa55c8fe113ecc7665e6c30c560118dedbbe884d745a5300a27840e415f886f63dda2a7f37e5a0e840c5d83a9e1c05fc108576165219d51ebf8f9c2d3dc87e2d4c2d334e66527f5071f11fb324464eb55de91b44cee3f35ef7f563fa1b5959a59ba22b54f27b42c2318cfa0cf3cfec9af582f09faddf6cedf82b5648313bd18b37e399f8ed789d358b7169efea8526f3bf7588801239a59206f7de3e4784c567f09c379fbdd21631ca324f21411fd920ffd1c3fa6baed45819babefa05e056e0765e04cf26bbd58cce730ff3e497e287bf535825533e5ad8e1ddd688d67e35e9146a358947e00fa3848f5ac9d2c767ac6cc959e1fbe9f63e2690e1913aa8b41fa5aa1953c9923d0dad3634686a906d82aaa2d3abdc7a11059407109d6fda7128d03633eaac721ea70c74794550510f5b77a05e4a0c76d833b1a065bf1303ac13d8145ee8e30c3c0ceef9f23e0213ebfb672400b4c9215633917555a9c60879ae0fd14119fb0f38ef4911b42c8e74cfa7f85e12bb6f9e14d163e7e14cc47bbe2a6cf748e5b09d1c415d2f38adf7c8d035a7e7d4eeafd0564d8300294e21d75b4afbbaca56719fd36acdf21fda741c62873f46f39dc7e6eb7cc2f3d9c4779909de165787ab677c5a4f34ff36527df3e6ca3952d2f989f9762d0f947a7b2f911ac77cd06a636dfa5f9f7332c4fad0e3174adfc1861fa0b4bbfedcc0e2e551688ed416567dfd7ee6fbdd370b8c9c2c7d9b52bc5cd7fb27f8eb2e701f290099b8abe6f2fc0a1b005675a05f74c55d9ffad13963d5648cbcf92efe121c4cd4b432c2c13fe7e568c6654fc4fad2f0146d65eec262403e26aa81c270b511fd94208824a728020747a3147a43b703f234174c0f9fefb026e596aebd677a247e3aeea85bce64aa2bf95da0f5781d01d42bbca07427c1ffa01aefde87f61d2854f79596a3263e46c8fa431f9af845bb077bab7c3b41b14876be6ffff8c5f31b4f4485360d8b5099bad1a587ebeca3dfb304be40d8cdc3f87521a2f133218ebc2f2959c3b17204387d1f990102db11828f180ebccf6ccdbae54e98a9e11dfd906a20f0a4f953e3013f38053fa3472dde0bde6c43d71a04bee02c8563ecc39cf6fd36c41c4ac23a7fa4cb70ba29f6bcf3aff50c81b06becc78e1949e6ea9bfe1de393fb5aeddc372adc8d6fd6f8731551b70fde9afd52735e88218b78b950370cefa7d297ce5164e3839e695cb67720c00f9e71ede61380c638c206862db90a1ddaf351fbe35e41df198a1cd45e2766a91003fc5a4474e7414c2ffab2e1964103515dcea385a5f42e5fb109e060f5f5beae41548ebcde3381e1b6dc215c4b7bcc0c773677ef69158bd2d207ef15309a0355cd29cf3c39ab89047ea4a2273dd9ebb5986dfa9e637d6fe5a765d1c0cb2ebda506278a9e903b354d1ff4cc3c8857a33c4d8236840e6cd85b335f7a534311f815eca97b35e65d1bfec280e927d9cd3015e6460cfe51e6ac0730da33b58e08adc9675e7167a8065acc68fbbf57b6dc6b11a0b74d6cd9d39bd54306a0ddfda4ac6760c89be9f4fa7c4cdc8381ccd856b062bc28eb1509897289c5fcd17fd0ad1cb8ee5529ce5e250d0cffd747ea02bfb00dcf79eedf1b30e5c7186530b57aa8809bd18fb0b9529a02a9ba73d2b3a55dc0eb111c71c61bc0c14b704bc642d1f86e02371d193303eecbacc223ce449b7b194a321bf4d9fc56c1cf27194dfee95dba956f1fa1843013caba56936f64968a7c8ccfea1a60ed70135ffcf0b04bacc081ee7ebd1b4ff536577d5abdcb2e876872400c513762071316318b8caa7a9ebb0149e0d66c5b9bda2d8d9d6fe8f3e1a2c5d905ff90996e10e2cc27ec35c7a75a6012b0974dea37f40f264531e41126f4ac296ae08b2d07b9b9aa0101a1d5450feaec1f4b680bf19edc5ce3c1421d2ebc1c992e289531f9900ec7d7f0b86a9c0ebc167b718092ec67edc978775c84a192ca19f5c18ea2d2c9497506f7a2581bf9267fed98219c36ce7cae582d0fca4f5b833d7c3aff6a90c889ed2e3f63c10a541139926ac02038db42c787ac25b84c3101456ad2543c4c96b29bc62702fa88b45a14271b136e015ad1a9bf850e94c1474964c7ad3998cc1d18ea1f52d79a6b5aa014fd76b502e232f359056a7580d7022984adb4a82749ea2a036bef12b79ad6f219f74a04bf3d829bc24c1de1ad707aa0ab1d3c06b0c4aefad65e57efa1eb9637b94b5664d77d5eddcc0652c8211c40aa9e18e9d7d3103107d106cd511d34723f27160127d8952ce33705c0ca751ee762229496ec84149ff4dbcf36a9f74bc8f85c7159729b419a215770f595b2bdf74c6f41264242d8b6f884767daa4432dacc0695eaee3ab26b9b5cc75139523f2ad717d2f7cd2c5e5d101a5562b96819639a957c3942c06fe04514fced43a3b59498ea93a12c618bc1c0d888e6244edd963a61b3a93d6a22466e5777a693a1d50af961521eafd9fd935da8fd882adff8d512e5be88106902560217758699212d5fa074f87f6152c9dc0dfacb5b05a4ffd63070bfdb2562009b852afb4a392894536f85e09f465ac7c05a2742c08a4d88c24da8313e644e80b87fc567e7101426409c251cb76592e87e84faaf626218f24bc497d42dd1a00be24a90904eb1268a9c294b89f1aa1a320d46810c0231be805b9844da12d8bad0fc606421905b62f0ef588e45439f7900d566bd73f6bec57679e68e1fbe58f700de2baa028df9b827b829a01e7d96d4f80e42a1023909d5069ca77aa36c574817c01465dac4c342dfa24ca76fbe7867a190b3fadea99287c9968d31ea4c2d12d71bd0f47ce1b4b7c35e9482fcce2898bf178a998b084520c27225a4a14574cefc1825c55fec9e093801d87651e378ae05d13adda8b9faca6e5147ff5f2db69e5a2636be57f3e4dc81895d4ad7203f41672582fb218192936cf4593be6e7097652362a5ea44b2b49b4c0b36479ee61e85a6fa084fd01115a8152525546624510a0f1b017e19380152abac860e4859c7619602dbf2b8b2646a02eb71c3c4913383058e4298177801f58009912b5cecf03c5357869eecedca16abb8da7857d89e866b4e28b2d11415f42231c7e53f53f7caad37dca4745adb639eb53a746ffa36447bbc1ff58d52e2cdb445e85cf1cae9b272b8c8dd9bda1f277e53541ac5fac06be7a9d1ac8687897e91695a813021c9365cb9d48d9226c3cb08b0a5ecaa69dfd3fbe91487cb003c93183155d8336274151507636986c08ec103f2b54c055301723b11268e402ec25c342732e89e37bf8d026d765cb9d2404ef34ee2c06a3684d863e8d8d198fb17dce8ffc9fcf50c6f2637834662644154a1c84ca10170c32d2c7fbefeb881ff34e89aa4e789b6a0be20ecb54ef4cacc8c5df8414a3b69e2551a68ebf6d635b1ff30f9976f6923371407f069f96102ff4515144e9481f9e6288e12b5922224f8c2a472d12ea1635b11638ecd92d726b7f8566436ff1939428aef7732bbce7124647c82b880ba98423f959113fbe680e74ce7f58830ff9698dba9807e2f966578728fca8d756848a79c31b10388d135908a26940a8c753b7af6611c40204b42d5525d876c5b4d31e55a3dad8c5fa9ff9311e73094162c8b1365deef6820edb4db371d08ecc7707d916e3cda9eab3090064ca3cf9b45b2db85e8f4bd3211ac4296370ed102b0311ca92928455c41da4ddd003b03c8321d1cbd50098a744153db4411727260b19fde46e4616eec81bb64fdfb0bbc3969b98148276df1df60be4147802695e6962c1839f6430c9606a5e4c0fa9fe7a05ee9200a3fe595770825e712101788fd544c04f22a1565a3170a291621b0b0657d01f5cb5d54f4e018efb640c52c5dd917867081b165b0e572ae177b18aa6cbd973ce66e8eb841f0084216ef80ff3b5f5aeef5dd39df38f46098bb8375dd5ed2364d97a975ba78c6407f1d8801a9dca7f9fe46d1ada458b1a96be5ca0730b5c78cd43173459581f43c405b550e9c3a234091017153cf640646b9df788fe0112142c5c0b26d94300ab6f8e5da88f71670802f201683d1b2c18a5bbd15acb0710fd541334e7f73c2fc5f2cf5b9a3521fec184ec54468b90fe5fc2c9bc4ae772f9196caf689da9bf60512b5923a9d0975ca9d60c84a14eaf9f9189ef3c44361ae24706c38013253c26fe1c392ec9fba6dfda93de5a2be615b653afe590585da1420fd1684c56f2e18043b0b8af39e5eafe119551701acfb8d311fdb1b0e37c443fb295e00e83fb2474db5b4d12ba1d6c6d5b57b86d0405004e8b036ca7a334ab8f2ec145bddbc573647b963d31f0a4a0f420a11fe707895c510444a1108340b413727bc47635837524f1e4f2f849c1859fd2d7a80d4b0d627db81f516a4c1782739707b61fbba892cc770d9b97b12882dcfb6307a42757ca36e3b60a2f12025327cab55e9702231954a12152f03a89c53998c43d53a39e416a7c6b66b7f53c6cb5c76aac2a67f3c34dfb2e2e702d2c8cdeabdcc4c17015d6676f862e6a2697c675f2fd6b68a2aa5a41a57470c81388b265ee812225d51061095b757428cc4765c3a15095a3147b750f3e21590ab61a0745bc9d0d4094c6ae44eff9515a530c5e032336b8d36a19287951b4a4139dac38520e5efe2049a3b1629890712b0fdc8fdcd3a18f2bdd9851facc1631b9c0af0406007e004d4e0a98a74a2bf7bd03b2e82ed79123323cf5e4af7436bca10d8d5ad2c1fed6e3eee69dc12a5477a57bf2177ddf88f718a3f72a992abc6438657f486a99b920e6d791a3744a32352b540e5962a186be2065c811402b7cacd79ddffd7936251dee0aa0e67b5e1d54d2b679b10648cdf5ec6e90e71485cac941a6b5237f12bdcbefb6fcde03e646e8bbf35f6f9ba6cbc8ba50d1b781bf949ab7c5138bb9bf457ebf86a4f571aa9c460c5598a6c61509a58754bf406ef439f983922794d850720bde099234c00709529f54641a154896bf76ca2c9ecaaa53b943ee95c63e4273b675ff122d3fcaa978088e3549e3881d3b38f973b621d65c9b2a582b2b2327250ea59637c6f79c22950d7ff5b3e7c5d5a93ad63406809d884b6ecd1e44c91fec7935d79d060c498fe78101000ef84cf37e2a53bd387c694b84b166fd3c407b1563bfdb83a1746ec290ad95ae30082c1b7d611bac41260157e34aa2ce4dd4e81a2cac6434ae65811be54094d252e1429eecfe71af003b02931c08176fafc7fda5472c25b358e19c3b23c3129c078ab615e90dfee24c21bf24f81bfcde7d37370bee9d79f1d37b21f4794e7ef26a8cde336ec0c376de86cab2341eb4a726635af8fc1da8ecc7e9e447c04a51557e4d8388679813b4130302a8d6dc49d115ea82232ad8225e4331f16ed08ff1e41f2240e3b0115e8617eff524f2f930832b01f233e22bf2fbd567cec123c210633f076953cb1bb6671f7849c7e5070264654e6c41e74e572897fc2ffe1b4f6f98c41049733c49ee1127ab2735cb1780d6d42bc8f14f1856145044e966ab410f02229c08c88141ed9b8253984b071df0f39de2881969d6f95abc548fb2c8c93871d18930963edc2c1d1118fb4a02ac4a4975372239dfa92d501d81cc8c5d20c9ce6845cec4426e51fa2ff9e9736621a2a23346539f269be6020f985d9deec0a0a91ab8e9813f50b9bfc616e48123c4dce706b73eed4d56ddffc96fc64fc7e5c06752dea7ce886aae4e1c663188c59888b93242a74b7836c8eddad3f0e636183c70a6cc39f3a9680c7dd191473923a94615b9fe64c32fb96528d53f46a4220ab4911b4f8ef8a2883b27855bb4d74e1a6a21013e69a279f45bd9db7b726d2710911d0bbd1b31a3926a527a3329f724c126c7bc036522001921fea957155c77d1c9b9f0f4e74ac09edfe1b351aba850342bd7cec5126354346b68ce951ef03c04f0ce03d5cbca4a61e79a7a033cdfe308de1ac76d40a8ac96e00b28210748ecc965b9036379d734c38748d3ec2358a89603057fc5b81d7b9d7fabec9ef8630b5337ea85023caf0689d5e283ef10409cb9b77155dcae26f1bd2d9984d98eb4c051f35e9bac50449cf4119b060c8c9bbf43e1e66a15c67eb4e833e494a5cd053df725f9086bc44d502423119b980eb858f347aec8f1532277472472d68a0efc6611a0ba3106e3960c32112ad375b007b86193e2f9ebae83d04a7587a5247cff2a47d62766b4026bd821cb81202fbbe5eb042055ed40cf44a2e52295362ce5b9e10cdb65d986cd35af07ccd286742cfacc5cffb948df1077782dab50db3c8fe0d226cae2a995a550ec072e75b5411e186ce4c2062c5e49c619e728d561a62d6e970eacc89888a93674ea0628748282d12ec4290bac16f2978525259c15b2c5ffe0937f404ba345a64e8f132b62d5309a32ad832c8d2f989ccef45bd44c03b7a08cb1ee3baf9c063fc64f8a247bb65a85d30e66be87ac63354b7fdb05492c7a572328d11cf8855a1ea2d370839b059dfa57eed4b99fbeb111891861407bfe8ca94e308ba257addb4cd8ca3d4154fd2c50fb7afa9769673f66db3990b4067c8713ac8232e32e91fbdfaaeca3b2b4f1a621bdc06790ab7925efd7f57a30e3b69fe590970fb310332ae2ca97eb5ca6d9c6eb270a66d48fcb6dd745554594bad2dedc50ca3d98e8b383ba3a9acb2e0393933cb2175ab9ff3d5a455a3e9164a932a392257486e9e2eee365e40e6555b436a0761df379f21adcdc517c52edcb0c818ee3d65209ebca0f37c9a23672e2d3c92c2563da1596cb683bf7abecce0edda866d05aca899d78c27d3a4b2eed0d8a11eb2b655646d7d3d3d83039a1517fae3abd86e22fecf3028affce2dc81314bbc8d2de7dffd496c2ad238d8aefa1712bb0c6a4a951bad41a76bb54a34efdaaa645d50a9ac71bff7c3502e0dcf565311d63ccaeaa51787d59531031315aec746d81179e677ac99f36a2db9f36ff0763cfbeff58e03d7928d8946cd9ca002e3aa220fbf082627922f832d464e7b608e38887416be5b32bd5ada496b6851d163510e2349cbbc02b0bce4352fbe6838019c8105a39cd1c5d2905d85063887d305330833c9abf584c1199068a73bd253aa8bc84f5b89a822816eb6b320b9033958730fc34129c1fbd602b93a723bdac157b804539160a71033e4bdbb21e96b81a1f30eb1f2f06c6c040c7ce26870ebd07413d338b952d245613af2d9d94627954747de5ad5575b8ad2fb18f7eb241c42d8dbd56ff6cd2dd1143d57454d3dd25739196e47731fe9d4f182e8b06b0e4fba01a6544fa23737748b609c6030ad32ae7731c2540d6cfca5e85b52b1f5f0ea4f570df33d59b0707828fabd4cdee442bddb0383971127d7c4b7ab1e7e9f02e0126d74167c7daf57fa9fad30b130599d8e65846a8df9c490cb856a69716e1c2f8506bd48725c769927b4f61f69c5573d2671c4e6ec422ca6173bd184161ec0c0fcbf5fd0fb6c3e45108e8c5615bea101dc317a7cdb7c59b64b449710d8a07c46add6831dbd9bc96edf2c7c1e1d4b8857573dddefeb4d4495156566de223f69c97c16c764a7368f7f0b73770d7334f65db24dd86a29ad29cf4328fe3291a32e43f2116fdbb849e5c2d7226a778ef56079506505fcdf04ce26c25b02c19c906c480972733d596344da114ad031618e944bfdc4770e15e10676f92c63179edd8e1252cbe4a5a144e922a55c44d09728ba841f9c570c9a34d491a06889dc7f492ced4fe2692c664fcfa543ae828c96dbb0f7035faf3f357f6d54feaddebf2338354930ac27ee33bd2cc43addce6cd3a8172155b7313bcaed7a48bcfaeecbe23ca56c7f71ad199d71815ff5083518f799d45bea82dfa93371156c3710577c85f2c271a94b704d60e2cbc9905e63a03be5f981c1c4e22c38065108980634a586c1254bc9404f04017217d0f034688724acedee92cc5f0655a2148f843acf805d1c871994425481914fd0b5040395b86341f81eb75d440cabb5f6c6abcf448393faa521b68be84f28d197be15f2c02b5ce84a85eb5cdcb4875de87e23d7b58b82a73316d72959ce6d893bc6bb3833e4caca75202b750f9ccb8b27b3538f893729248a577bdaab51a54fa41e2569df42ff48ad2890fd0eb0d4fcbb0fc4e74913b370413caf138145b89cd039055474b608038ae3b60f27a540da594768c06e674ff194ba18c59b237b36e02b66dee9b1131732113b0ae319fb3c5a05be202aab3c163c19bc39bdf6bc50a77996fdea3a6a9b85aab0ae5e87cdc2d939948f967b111919e093cd5d571639b825833bd8a6a71d6fce0254c7efc902fcac24e55b1e7cd15905672a25dc9dad3b20ab5d3dab4b74840c6fd445b736e16389cffe657f6a54c8d6fb75f0f5519f9bd868a7fcb4b678e7ac73a65f87b5bb65c71060dce89263dceea38b7e4a88827bddb9baa452111e15a23c3ef62cc48ba612ceb729d7191f565576cdc98c50725fd0ad4749fb437f4f7caefceec513b1f501ae6d41f6fbde90b9bf783b405c2f40c4ba1c871ceb1fe1cd7f2780a43eb0567c6972e9a5d0715f1304c04336bcc1d9da92eb559216206c547a3209bb703be4be1bd757e760e0f0d38da7e64ae5f7060c3c2bc7f5dc19fff73d8d2b8bf374def6d30bedcd1df58896cbf829f3502ec68fda1374a707fc097ca6ede0991a70388cc0d0057a9a4e742bbd13a5cdeab79fab97bcbb48939e2efe77b66d7ee6e43e1658fba1ede85f26fd135aa582baa537871a869f9db83cc50e26fc5daec7f9f93a17ecac199f8fac861975c0e6be12b3f98e51bf66e6c4151deefbba3a16d8c3929aa70d0657d0e6606800400278b84726acef0cbf2107763d1e0472329834445374cf2d3080647f52ee762b24f79e71c918c52d15c614d6011c899322556da3e9e571c80550cbc4f4bdc6a3f5b4bcd92f50ee3f298875d5490bc2637d3a8c2b1bfcc1886dd316a23f207b16a1dca738852738ba2eb97c2cc394f1252da27a47e3c74f50477bf057d091d5d538f70d9591f180ea415aadb722c769939bc20c958b8c3bade1ed4e086cfc160e17bea165c11e1589708fbdb0755af3d1c803e266346255244da44d394946b8fb041fbbf7812983c5437af09907dd8a1c7a89e0fcde347f3c10ff11a0659585ac01a65de55f8ff6f3382edebe45fef66d2efdc89f2e21cc1d734e553d11a87ebb850572a789115b9252b65d490612426d0ec3d83831d5ff746b717a9f524716c3ae774b2154fa74e2501a2fed828d4381172eac75aa19ce077ae2979cf50a2717687107504b62c956f4d2f77ba06c1db511a30f0c853c8a695560d78d9f3ff42c46c7b80a920ea02effa9cbbeff442eb106366393ec901134876cabbd5a38d4c99c0925318e9195fb1a45363e55b91a118738011f9017cf4104db86ca1d6fd3c9c2dcb59d2761a24f081dccd640afc19c0968b8aaa3dd9a9b9f61d527ac8398557aed01e57d7ca6f2a8644379ae8ab287795923bf886c41300dea8ec065a7412f4fddf123ed270a1d3a248a093c3c4d7f4054eb1eb717649dd8bfe77564eabddcdfee00c4eec246d93224bd61753cadfa152e7b5976d96a9348c59f8424a0c8bad76b9924a88fc8cabfd889d638c78184a8ae86dc3420c29d472dc32768bcf610d66768ae623f4fb82e25d4402054315de81a17680f803f940553d2c4c441bae39635d62cc8dba847670fac2c2034301285a15722fb362b7b0a0a8c47913d014e5df4a0081b0ac40c544ef86da84e110047c64f172b66d2705ae693aae79346b5dd03fd9f64e458a759aa32b1f5052528d0d10e112583fa8f19a71a6452e6ab8fc411f825874f3389c9cceb18ca46e4450ddfdf861c69257e40eba16653a543d699f191ada102805b56464b63792c646877d21a7013aae2975228562133a2c91120590a46bf80e564304e43f55e890d0a14c58304b52377edd18322720996d74cad3fc68d4aff745bc9ec2e10ae25ffe9cf466da4b88ffc91d4cd8052f61b31404ed7b9afb9fc4ffe32822524e558d625155fe2cba6a91c134f36b410fd87ef17511935963ed9ba0c5c39d3ec522130da65a8989f8bb7ab3388ff0050634dfc00c6177ef423375c0074fb01c0601f364fb5fb3c39e78559792de486bf5a36f14303e1c83217cf695e13921d43308c2f621033525155dbd3c19cc9bc35cf591994542d4a397c24b2c73796a588e6799ab221060f74dd157f4472b6475588caa1d58633ead44ae365257694c2158132388333deb4b875cb15abb868c226ec7b84a6d0dfb1e2fa07767349712c3c9515744974f7d8261906e5035d10c7189917e7486062a844750cfc059b2be0fc6747a74ab8b0022b4ca3406166b0a2e2f8ca4a185eb4c263012422dc2eab26e250349e37f97bfc893f6d58c5070459ea4c244ba48e6ad7a45196e48ee381a1ee79a2a0f0db29c281184fe9f3d4c3b51bc19e89eac6de247a06c72a3f5053c452adfc318ba867af720a73618e6647c00dc5163778b6c3771b80ceed47ddfbe470cb69b7bd8ed9890e5379ee7414df41a803c7ae5d24aa1b5b50470e52a75a5f1c41402a6d5c1fde5f5715c5d40b7078c8a1ccb657981b913f1aff0d0bca3fe07adaaf49868cc3a7498492e2752cd335ee92f2c1ff9509927d626e72b83e45d3355a22772be39b6e2b222ad80b118ea06f8222909c4da3d5f93bf7f0fcfaeace7112f9ea90eb4279cb687ee4a0254bc84478d689b2ede881f8201d146849f66f4f44343aa84acaa160d9c9f343bfb8e07d166fac6a593f674a9fa5242370502cc7086ba4a5e6039ea2f3552dcd262feb66a317eb41c9baaa95edffc466fd5691013d0e43c1a077e27e2943ade0cb4ca9e008aba857827784073624366ca4e5a41b6385ad186593fdb37c5bd04673b1f0c158490b9788225601ee474cdbba933cae2bdb09b8be3dade9ad8a3146e81d55196c58a77a2e84191aad4a6ba34984bb781af357e3db17c4bf4320f3f2ee08358d199f31cc394371cfd5c8cee12590a3be4dddeb2bf1cf33c03bdaced33d028552801503d48ac7c18b88cef3142595fc5922e648eac146f9baa614a086135107e583dcc5850d7978a873c45c56334c4cb67971847b0ec389f6d13d2c78c90aa25af2dcc47420344d48343ac169d454bb5bf58405c344616308be43b54f3864e65e82e1f434c60d75f1b40e21acce3dfb4b4014dc4691beac355c187b66b7d814d1ad68216bfd0148bce32151cf8a68da468cf4705f7d9cb894a5366e56241baef503f9d0e8434ed1a337784524f2407996d316f1edc2fca533c98f418032e76b0785f77fe515044c5a8a0c5b011b7ebd5f41849b8c0437c9231351bba0770123f0194c32360c060f1021d5421feb47cf75f23856324dc706a70f25d3a36d3ea6e6207813ff4cc31633fad4c20475b252dabd0a49bd6b0032f19ea85f293b5702f58ed321b3c8011ec3c7da9e20dd26e147dbcc65cd5775fe0afcd082565769373ebf8f8effcffec618e62c0c5a9235a8432ad2f0ef1d055ea4e8e67172970ed6ead8018a5fa98850406071809c135ab805987c478932f695387ae9789dcd30e230aeece316dc95ee10ca6bc81741312ac6bc9b773ce2b129a814932457b48d51c6954238a566a70128c1dc136dfbb687a28a041227d6e43d59bed792ccc21ad228a7ae8b3cbcd31fc73808c2628f42c933b771b24c3ae7d139212c93b49c68e9c11c8b986c15454c16029fb9d15b5d488517a550cc564d6525113334572fe09a33f783cebe271ded439818e70e37a6ddbcfc0b84bb0e625e69c9b30531fadc3b5e79a334fe2d20cacc06b7e92aea52101faaad57f2bf84aada33975d68caf272b201bea808b7673540ff9a40717732fe5e14d6d76bce82e5236d7b33fe48dcbde056822273dd06998ec7b08f2fe195446a8353e3f7be069614a67a91f69dd00dbe9c0fb30b0efdaef3d7350f9ac7bafc9dd41a464e818e34ef94b66b9872270ad072d9b0ef904d77fcbe5fff3d3e96947bd97513778db38e3976f8a596ef80d37dd0872d60bf827b85179223da52275024053acc414766f849bc9af7ce057fa1bf883f9269794370fd2cdd72172d96f73fa1235c30c039522ab2fcd411b39e7c4386000e3b3a0c1b90a3a937bf83ac091090da43e7ea514fbbd910d2d28761e702fda8282f3db68147268375d2c0b70c88de297ee109b7ba88caf17031c653d5eba987372462a3c5e1edd1fd4b5863045ac495e52fd69f82901c693562e8b97d93297318d072fe3f55c65dd60c68a10a6a907b8a6c7383c9395b10d5c6a31a11dcde81ad11ca761a9d696feba6674c95ee793aa65c5cce53fcd0b11eb55b4cc85d3a676c5b62c3f0702a4c090b4aba6f64a29f6e8a239d25125c26f02dc767ed7be8f64f55dbdcba70713b9057ee8c5e876230d4541a12d488f5c153131d760491570e2a42b3db185018bdc955c516043d236a01ebdf257c12399c7df999171ebf3bdf19fbbed1432520eb68c7f29adb2c296b5d7102cb9769cbafed941b7c7e19068295e4da863d8ae31f7b9dae7ac09070cf466a7ca32b01618b4d94727487cf2904f66b5ddc814a9979405133f3aa3a235eecb427a84652083e257e42c30e53111b47dd43c5db7a5c0059eef5233b0040bd3551b155f08643a11f1e0cbead68fe093cf4fd16e31cb05b79d40233dc6ff059a2c8016d9c46e526fcc2837ade290e5e8857a6d86981d247a84cca4099e545f1456f4c1a594e362562c78119cea5f7717821a47d72a9116f388a61ac688f304cd4bede155fdc959b39bbcbe1afa5d6d20c0af5fae291f7e7a003e485a4456dc770168c5ff6ec0f70e50886269fcc7c4fb25a0bea33bdfd4070f0644fa25433b455009d8632974d95aea7941164eda22ac119da9ee879d2b8c61eb2c640890f82a26e7b096a687b112a111cef97e1fa8c0143fb3f9f5003f27c6350418ce38626f13ecb73a545845550f6e2c2760c832c3bb8ae0ea06c1bd856748c754b013028d13cc6da4e33b38b67b9846237117f0b6e45761e06f207222196c7082454940b61f10c9dfb21f953807905d41f0a4f4977d93997fbf6e54afed374e158e2e0608bcb75f1a588e42a4db0c7c7fc80a77501d6808281c5ae76762f9e0a1177793174d4871d21fcdd85337617fe6467c44e783f315e9e5a08ca013d023ffa6733db95ebe706c6371eec6d6705e7c84ea853737982a37e8ccef1597649c610169365e6fe44f0359e862d23ab9203d227960a9f0d538857d8bcf988e384bf05d0326e1fdd925e11f8905d5fee6c507f2ecdb7362adb7b7fe707586133c5ed84366bd4918a7e8193e9d182e259353e8862c331a1ae1bd89ee2714b7a576a74e6fe7b783469eb0d825f069415ef76e857ebdaefdc8b417b3c06f6d34531d40fbc936f320aab3e3fa0ce2be377a990591fb405ca07b462fff3c2469c86fafa3dd5387d5cbd8c8d5ac14071b728e1d43000d9c8fe28a1c15226225d4d4bc0db21d364b1053e7dd4a5b919c2fa80ff60a96d726d6eefc868f08aa000847a9ef31c9289f511438992fbf9259423eb95ed0d4e4fc7fa8dc75d24083077086b7c40fb64963eb97c0db0023fd3ce238a63f8bfd97abc5f7d61986313d6a870d5c5024c8ab4647da1e35cfdc8567dd8fb21766b7fcf8037d25043b3d792debf1e176044742b4887ad7a90651fa5b60814b6d875758c35a14c9179c026e9349c437295e8b586cd50b158e58a24ad12b84baaaa82c157630bc2a398a1a3eb1c8e509449689392268b76c0aa26f5e94d8d8aeb09147a71f4374126f1404b29d77d2104b21d22d5b0f3a7bdec3a641e27cc9a81a1e09a430f5e189863ffbf867cd1fd62e47a3db4e3a49ce8b5221e921410c5342051927991777af0a9cdc204329153e355ac76321639e9d23fc320f4900051f3b2177abc6f3dacf4af88c4bebfd986ea00631a70d02e66ed7028f8384ca5ea170a29f7ad3ead4e931d7a2b66a1418159dbd18aab8121bf309af769d016f7796b5c6c978af12de7c128c040f4560800d2db82a1ab68b7115d6a410423f6b970dde798cdcf03b6d986f09254a05b56151454031b0f8cab8e89d4eee2dbe1e6fd942de8a5a75e1a20c6dfb4152c7214b7880084ed0d45a7c5d6febd9ba4f94fb7a76d0c64ad1bfe73d421785d7f4f7aa8159877085d88025b8ca261934ee89a7c89beeb8d5ef94571375ace512b1f8b6c1c4b12db81c52ffdf38083136c74cf4f821d69f105ac6f501606c9acb67d7816aa15c38933a18d1bd8695e9183a3be2a1c0ff9852c1d167d0e375ad9f90607ca0e8036d7b69db030a410c5c779fcb37594c08ae6f81c1c72e2ed8216b6355fa204db022abd33e5d32462d2f4aa32bdd54f4f89bed8e3181037f933b645767595ec797f14356c32320918167bab7328d5ef41da00684ab8b26eadebd934c8e180deffb7cdf5ac449e2d71ebf8b40be9d50344a1451dfaa85ec5c40fcf20d4a8adb50057bb4e4206e2b067be133e0be4a4d84e786ad8b0036428ea6c3bce0916d2941f7555400a4a5f1debee17c53a0718dfb5020ef23f84e69837e251eac1381a86478c0bc562ffc891a3342f0838b1c4ad64c7bab1b6609b656afeed67f70bd51639ba57430a3f0359bb2d19a5ce8e9b05ae9259942ea5bbc7bf0764b3e6b9210ea8f6e9845f0d08c1bb591787ffd05e9eb4cbe5768b9e1eae24fd641ebbc45134b508dec232c6d9f35e31e4d15064bb029915df50c973b08fa9d3284929da512a1f4f85882154e09a27d8adcce8ce0bce2039b0e4ac0151400c01d9c80e870198b0b4ff856b1716d47bca29b32a43835182317201979bb5037b39d3d3200463d594fdf25c691ae08a3f70294151cb33f4c0bfbddb075112ecddde968303314f4b0165b5b011b94c5c9199a2ca0d69674dbe08e69d333b47ef022538c93dbdc16a819b2bae15ab614190e1e4f3b95a7d4cdd3df988b86f24e960abff2f41e7c7845eafa19d063c6dcf84f7a07dbdfe14141e0f4e81ddc843cec5c500a0751b81ef1ba6ecc205fe67d11f3828b8cd756f0b4fe84b5af1ee2c92f8275d53aa20a3ee79be9d36da9b8ca3b75caf8f02845ab4d6f03a7396f772390e0eb485629331e57f789fb99f290b108255660b2d486aa04375ebcee013462109967af73da460706ce9dc3bdd639ed25d70adb165ebb748ebb0b41d27ac1fad20ba7b26495b8136d82bcc20217d78f6fcb5d759d7b93800a76abdaf27290363feaa55fc0dbeab8fe85aa2de336dbe4ca77117e6d50649fa0d6d1e749ad4a74dfb3e05d4d265b9a27b23b0ac31e192559367ad9c0329d0b99051af161c0f9646b6f697fa5cb286288ea6bfab02f8acd7649f867f29fb8ce9e704baaaae56ebb4bdebf77151948677054e4a74bb5c32d5b90f787c5f78d27db9d7bee025756fd895d81dd515efe2783f17b403362241da753d53767dd801fb42d2faf20e052a7b2f8c57a4d4d8211e5bf55dc9a08a562242a94b421ef521994587fc847688a7af27e9aa73739abe352bbdb7ea64afc2d1facbc3e9a0c7ae2dcfd259b17c0e0f19f389d19d289698e470035fc59e3aa8887a8a582d73611757294eb7a2fe25c006f48153b0eb88e08335f009171fdda78e8be3d7ad4af73fb41b8055dc3fa4af11e694d1ddb8dc16b35fe6fc9ff0b25e0e821ab80bab3d467b06bf103420242a4869f03067004e244298b392fde41e315a4314e026f56f5f12d66268925dce92995320ca1696cc8556cc36a68b2651d202751b7bc2c85eb53cb5e6e1e4fb47ce4256a97c93957c2dab93afc2a1ac4472d6c444b9f5012891d1aae4cc1492d18972449ca2bc19b42898dfba299d2924bbf125a34ca9911cda8eb4382f14fc015d5bbc5b24d22cf2c7b9c605f1406c3cb11fc46da4e5dfc8814c8dff810347d07056d9ab0c874944a6bdea61844a6fe8038c69b923141677a509fe78b8a84a92c66c78d44ca0d36e0c978534d40916ad282c285d0209ccbfd40b821651127dfb1f87bd02a7a31fc651a162d5d347314a2c6687ddf6b8c0ef920be0fd49c7a8ce2ae4d7ec867eb235a1486a08335b026a3bbd90809bd663210c874239999b0c5d6a6c2d9c457d5cb5d033a1b0670bdae3e0b8d461cc401f907e63e5a4c1f1d54e0c9d5e12c32de02371e332edb8ad3cb6118db018629a7009ca5d788f3c98112eb5b4754526b9c9f666667282a225e21251d6b8e656c2d5919c6d85bbc75a4199aa71155a0f981a6df5c8f7841acb9b22f40c6b1c223de0902d73b8a162716c70436ae4a6c45587ac0f76aff889d31b4882172e018abc4b1e0510547a8d30d8db218cd981b3e2de0ff59e3645ae6d06c0cecd26ff40a51fc2d5b4a6f993c31e61f0daaef0af4b58ee4857c35bcf28f4c160dedc8c70a81cee36ec0188c3403e4df030ace1edcc26b59fc4cbe709f408bd27d463ca72e26746fdee1dd788afcf7df52da37449b51a9009cf438d41a4dd169cc05bdbb2f4a7138904d413f200dc1337850cbd6a84a8f5ea74e3005e46efb38047bb59e06e44179d0cac97c6387fa16dcdad70758309e4bb0d9ff7c9ddba4c1f27d96f2e231d42b4301dc18b732b10bad46e41b91f27bb4548bc6548dab8a433a50e68e2766a7d2046ab30bb550a6abc53e948556f80d8ad87ef7138f57d9db7504b1eadffb4a62b7bcc17858473cd36b042c9762eb720baf55fc0520a3a2e9c5cefd3106da27bd1b2617b19940879413a3bc9fb2a9e562e3ccb550b59078d04ce71f93df9bf7e568cfa5bcb8d1b8ec30a523b763a65a4058ddc0557dd7942265b3ec3b8fc89bf8740f38c4d9bf8fc742bf41aa4b873c8fdecb166e619ec09f19d6a71cee8b9409c302a79310a3ae3c81918363fe971dc28a1bf2920f35e4ba3b5a24c96ff11b9c830e32355b61dc50ac534a61b91821b88009d07bdbfa1bf3859d38ba3026f8fd8190f60a94d08ea2753921d2a7be13d8dca53a55d619ca2095e890e8a1efd5a74ddf8d5ee14da05e34fed87214439366ad3d3171c069e7e7cc016694e364285d12e0c9391d80940d720aec3530147ae695ac3bbaf2d28099cf1612ed46aa160ff52d0e3d4d2cbf3b1cb003acbd66a9c56b3e5d2b27ee537fefde956da284d4ebbd51624685e131a1bcc6205485ca614f35ac9a5332796bb8a698632f0fa94e7efe4d2cb1a9db40dea10dcd7031c3d4cbde3be6747b76303b0c6d37d635443e276a10bcd65babc42b32738781318a501187803f38cb3ad548b6cee1cb8b2330627027154382df593140c05e31e7390dc7485027bb34c0cea71cb6d8398b04ffa4982330e618b0a4fa61d7e892f07b0b33a66b7f0744872f9933694387275b9910911911d74274428287d684bbd2223968870406e44675c16bc414bba0fc8c2bf563b9627ea178287a4fbeaa20a0e3c828ac137ac048d6edecc01f871abd87cba00ff26a757e6d01a8004282c184e6d2d1bdfdc114e6f4230dc1461b85785f7333c35af4e451da7b629e80b0212e87d7d4078e5525225eb20662e214498cac292f60b94f5cc9eb9e8bcc720046ac72fffd343b21070d6b0f730a20b176d789bee99c3e8aef4de96b8bdc7a727fac6a5fdf5892e0e80bea6bbedcf0b1b14e3074b5c8a39859716b7fc61fa428e329bcea22197fe2ff14d22dc62a7b44818c31c2e4d2b5fce80cdb40fc918b9af88192e07baa47842c8f88af867de24d6ec0bc95d3a40f1814ac7d4be11c4feb80e2a58d9a786e2bc065ea219fdfaf8697825236800fa152bbd0750a19c039d7cba3966814ad3033b73584977cc8a08fffcaeb0d6ccce2bd36c764fc30b0426d3ede6c4996ee9c976d19d3c01a43c6f72abf8dab00d4e5af22e10e04bee3105c67b11f82c8095b380e57fd7cdbf49a0236ed8788d6eb063ac7719197db0bc3262092b542270a7c91cf724480df17e859899a3e964076757c7532334cff6db65ed8596e2d78157e3da1457484f58c7c00c5729117015103b0e2e282c778f4cfebedab8309a509863592234a93e703a8b58e22468abab1841b221a49a53183b06d3a353912489d164c3b2e5a83ed6f3f4e78527cf69223872ade8ce10e308e2308d180ae4e92cce1592e57ad693c8c9ff6ce9ff01a284ad2c238c07b1709ecccf8d4e72df377d1bf70ec7ea95992e846b280c547672c96cb63f2ec3a09f117a2768e5e9ed5f9122cf9adbaca55a2d5338b3b15398e8cde83baf954ad831683f5052125b0f7d3b9749cf0571d40bd0bdc7dce08eace6fd86a106ab00cbde0490a9c0f1e0bc2b660d13bef82e72d48e93cb7a7eba8492c41a52c0501d72724d19a917d640b5690706d51f23e3c005cce10c1253098cb6ccb75c068a4509a2a4fa157572b039a59bccfa944c17854078cde6a857bc22737512d41bf5d204690233492a5b7c973e843eb5cd30685411b8c71f0bcc0d680dd780982a76cb92e9f6afdf232859348351c6a88b24bbb7cc87877c28d1155361017034baeccd056280488540daa3e2a8886993d19ebaa9c48de0b444af7c55aad157eb266144c56b066aee84157b6a0c4fa3da57c48b9600261fc3aa49ebf91846ec45aa90b03da012c32a80c57a3675cda86523a4c56cbe1a088d82e1449bd9cb0d50abc7cd2f2575d6232d482ff6bee8f907100949843d08130954bdcd8758bd1d55aa1268285aa1e6055766dc8164821aa86e9bc6de472597e99d857f5ab20d7d9099680b478c8d100ebeafeb09b909c23aec536b049bf2c04981f7f39da20ea80b942f683e4ad26482f297eee7c833a97846edfe0398828ce568b5c3003fa6e3315102d17c8e8cc17b17c5af2cbcd11a138fe71a3436b321f346e1e34195182a41725e20ce03ec3085211fc1e74260e8429e95c21a3730299c7511dcf76b3e7fd6f332ae769a9b3aaeb3b39f58c3e3b0e5df5931cf0a3d45994f46c7a46cb40c627967a1aa1e16d252d67a11abc2ae99c8f12ec5177c8a008d5536fe215744c5793250d6fcb8b14b061cd937b8c8659781ea58d7103c8263cb4978bb87aa68c045ce78649ebe9f9ca50a5e7e15302ea0b40f7e9cb6f9993aadd70d2918f9ba9512e661f571079464a35e496e70283a7b322362beb5facf4f04fee5e4dec42860ac2bd3046a2d0fb71f4b67ae76b9a737dc38c675ab0642bc822586134139ef570763deb23ed17faba50f15a492c2c5e8429510374e7c0aa245c5dc99978bd22ee765bd26e69090b55fdb785b2a5620d1278d76a6d4f66712582d563c329aa4aa0035f9a636680310da78ee9613b26c6b4879d2b31467c71fcc5cfbeb66a910f3ec906840384e9620b49637e3bcb045247350da9f96c045db6b9e40dde1c5aa3ea7ec5cff453cfb0205ba311fd2b02226c1657a6178ba505a4b25a688fd6d0c7c19eb31ef41e5cce256458392366b9d7d6eb8e3e429589a138309d07c8aba724ac88a036af02d8032319f8a5c6dee9be0b616791caf9d970f19c3b44720fc2411eb11987486b043713947417b0a1245e6904bbef91588dc3ef0ddf2ba905a3ea740ec353cd8d6cac2cf8d57b802314c24bb5ea129c5c1c18c5a7a9945c417af0ad9156ea72a5c03c51e40a19afe257a301331c1045384b4a93e026177696e1258dd9af63f98b728d1145c41fecff569f03c9f5e826ab8b1a2560f8b174a9307779630d4ec3651a594a36a19436d696d6c71d3d83e20d5e10f07e1782f0277fcef15219bad0cebe32200035666a937d0aa9408d75fc1b49a8331995d267befee9602f2c9b58c0b0d780e83d0edff08ac8262e6c167dfa9398f066315a176f3fae13b0fe3027a89649f17779263a0e78b4702223c2b738e9177f686c52e4d5e005485e81f68576833b9d7148cffdf12452f1e932f9bcf52178b8455a45972f80a23e2faaa2a9e5525fe26ab037280919d766debd848dae02f0e77d51747b9c545c5d5f67210fde18188e2434613340e3e3836d1ef672ae38e9535ea79623204e1941eeb5f5994052843cdbcba9393f1c070ccee91abd847d74fec9a2d028e8de102304ec9d0e54f130c42f83e051de0588c1bf9a340c7090c9549e15330e438031bb1dc12ec717795f570f9362f39288fffe5667176c131f3377d88edab7633be6e5c9fd993fc1e4d2b1ab97c5ff0302090ffa59b556c37180ded0dcdf9923017daa9c939b574432ef8310e891a35432235d54de75120f32e3c137959b8a63eae8ad6775163f9f3ac9fccb0f18c1899edd1aea560dab68e87dfba89fdce4b71d66ab420da10644c4c419b2eb1996465dcae0a64b3e9fe4e8ca3f83238f1f7d87f040fb6690ae64feaee2b74c54d5d0027b66280902442357736a01d98173d251c795f80de13ea4c89b2ee31d026bafac9289f41a157df211afd5071af6e156b8c550258c513366454be50f4f628055b458c055c8041403e4347559c68b967121d589275c6e18d22b2b871497e260a4d52b8ded7489190f45ac0c2a894ae3b93817f22da22a62892e1255198c3ba90320936ee607ed8c48f0025d6c5c1a01da38a6ae0b572f3bcac31b5b7ad88898308bb7d0eb36e825d94aeb28e7a39868a7d437e6b789a41eb4638feace5fe4ad7ef8bd6001da2fcdb416a300cbd1cd3da0ded7df9be5167a0bfabc37c49c2d0b27a438cb91189980e8c948674dd0d2fe12974e14a267d625791635ea46364d21a22db86b21c54d22a2377998691f3d3ef8fd80d31aaf52125f62a68d3253e9204aec33b4a2acc41756c8af761942b8d7267703c09cfc5ef20678cad16b6c4985b080f8a0a68c7d58a3de6e0ae8832010bd5591241663f6ad97c9cc363902d0f9c7bd4515ef6e43ec0d6b33d22ee3f0f8c29e7047b67d2aff0624aa03406ab2f16115934aef0f0e77cb11d82adf255fe82cbe6e27c16ab1450795c09439f217f0d14d33ada2df44ef997c983040be3f328aecad76cc57b275454c42387d9d5ed3412904b022074ce10f0c7eaf7fe87eb02eedc314cb762162cb3906cebd1b9ccf2b9311f0442d2a53585865e27f7abe0775099c3fc655e46d1cf76b8038e6fec6a6ac012c8eb31749db5b8b83da7f42d7fa24d22af1bb45c4e19641dfb1bce7a99cf49759e474da1980b72a56ececdaef9b4b924054c66a4583f935e291f84feb55e82fc47fc5cea62642c44d1d6ee19724cdd518e3e7fee8cb031071fe46c45d15a5a1e663cbbec4144a735058e3099fba83f3fde6b0ed4e565a8af7c199f5970e24d73737eab9905b31a2770bf6f1b6ffe1183497002c7a0e6affab3e5ed8db9d8031a80f3fa498510e5e43d7b911faa994a258e22c3a45c36eed30d5e6b9e0ccf8f8a853f615e678ca72e56e79c00314ed01a37f93dd06261979d7eeede3387eb8918c0dc86d890fb90c1b325a398b4e4e37f57d73ca91f269b66cccd8dec5cc35f6868e99b7d51037e3661886e11ac3fe0dcf8149153be0e859264aec5d559c575e02750500d87bcb51d1954fa0806883ada2e290cc291e0975fa47a7a9ba413628e08edc304da45c274199c44dd0f1251a4d8041961cf7dc6180fdb0e85ff4c890745d8bab27c449623999be5b2e050371327604ce919a321634c4894d947b1e3e14d10b9486c0ede9fad956932ec701afd9997739305260c1fdad29678b9b4e4aaf5e47315ce5d0b8190ce05ebba4e74d04cc410e9930aee1e4c2a5c6f47f56185635046edcb84fd496a82c26b831e184b37f628dd7d785a51b73e370a7c7447377545908dae3187172a1c0335f3dd43b99e42abd876bcfcbf69f78e48dcd6e8c3988be5108bbbde8bd830274a8c3acdad908c6c914a0b57004268835da55a768065b1485ae00acb85b605b9333c616312a0241aa67c0dc98282feb13efafee65a64a72aa0654c5f9f2a63eea214a54f4693cbbfd00f4c4d06ed2b54bb70ed87d9717ee1aced97f385441e8a89ec5bc10a2633549a971fad9880e29de1aad02c240ef9129dab6ef693c20e2560c42cd1d1dcfe389580c249bfbe680bf885dc8321b82624b12a03c5a8a919d912bbb03ffdc1dc9c8ff8c2194e9010ff61f6b5d49433a692ef38ca2a74064989af0ccde514034132d2841a821ebb5fb9d1406107d3bccbd641d28874c072da3bd768e00bb300f206a1d06562a4365b2b98404ab25285c27c28f9f7b3dc7034c0873cfab7f7cb3c2decc450af7ae185622583b3b6505e9e4f47e6a7309ad76f5a71a27c4195329363a0cb657b98d807d187abbfafcc16064ea6980cc0f83ea569861bd949a7248317afd7a415fdeee1b22b50f8e850a9afd596114bc27eba1187051984f9c12daa042aacfab9d72c35224c603bdc5b21537781576df2e43e39240876077b0706d41805ffd4873a40e35c5da9c1c8c914eef7ca884fd7b1ac7eeaa3ce70aa43b8335c3b4209263d63c0f58bc948c282b88490135d933320d8d183ed2a464f34420995000a78bb6839ebf1bcaa146a4aad89337f8209c9bf075c82e1fa8db8e6969af3566d35f57411bbf550b6e6fcffc9148428ae5117b6d02bf4a8923b3e1380a07418fed829bd4acbe1e38c55ce26c1d2d334bae9e07a4651a71c484777d87f10d990968f36575f2784ea4f0cd0f8e9246fa42701b0402a69e9d986cfd6edee404f7e98a91ed93aaf293a9f649b6a50af268f81e5b9b6579e70c3d9ce6635fb5fc6aff0eaab5c747cb8f9ed182f314e09e20927c02868d48250513fe2a771804fde932be6d1760249032eaef85a23f3253bf1c548a0e9361b5fe0b2a9028f42c742f333b2e832500edc4c069406494b73833bcf3e40724d20df35b19b6d2b929954ebb4fea068bc27e69ce6caa62e6578d6bbca114847ab79e64ea998c1dd6a9eac558918d543aaa30cc0b4c5de86306fc075a6420a5101c92e1b2a92ebfd3726ffa5e9b6ddfac71e1afbfdb103a5d806ba7dbb790d8f1fef36a69d56fc9e9950b4927cb7217fd8da9a5bc271ec390401e9f91e4eec80c76be2936c49807a3d94ae1bffeb5c87df15ab1bf7693a3618dcaaba7f4604a0ba51afba6552c9a33ab9f13aca27259905f815600efddd4e0030d96ee0bf74b178ce080c94434de40dbb6bf04044048d448345dd05b45f820f7a760b06f73c130fccf25876b6388b15ba247c27d968cdb836adaa98b82f48d812f4d599935beb008c8dc9d404997c1b6f804ca93dbfbfcff0b0cd608ff7746b122fea1da60ad723fea89ebaac3286155e04b9e012eae94b569908588309845f12bca2b9be365fe380d3e98da5307dbb353072eb6945ff655c26cebf26444fd10c00e383546d6d211404c598d2676b523f49053b626f8272e4d068c272864208412ae49aabafe9f56e75fcd547e97c96bd3307fbde5421d12e52d9d6c6d669a49900f4190b690c01f0c2e418088f24643a00d7fb9ddce7ea320805e2201955389edf1ab422518c75dac137c9a4449ec4d23a81a3fd02c79d22601ce2938fe7b8d2f3927f8566dce876b58500f2595231090b54c9e4b3a8410abf173c73068439152072f185ed278bc28ad47887b977d226f92ab8a29911199ccbb65bfd2f0dd9d3581cad63dee5368527c905b34c6434b4b387ba68052cb045f534442b94e49df118959ebc429c16e10040ca9a9e0e669b3adfd3086082df0aaff50337ce00e5711910f79c95ed05e94ab67a5d55965bdb1170f81859039a1054293fd8dd14f02601fae504082d908f9486513afd97afca1eb81b1dcb005cbea767cd119e4cafcc6e74b62bf37a7e9a8370811374fba04b6a912ca29ed3ff63a8b51add822871f0648fb17e4a750c40bfa916c0a548e9dd0223e9cff699b1f9f216fc9e1e9085adceeac80d63ec072dc50c836833dc595114b3b2cc36d3b15f7f7ea1297b3fc852faf2504f21852558f0685c9ae91fa9f4f1625fb9a52249a0bd86f58f8b8ee8cc58f772f9ba691f3bc686d700b3e705744621eabf7bc1c3bc4f2da1884d3e4b37626d773fe87f78009995fed67935ef43f076c2acfab23cf05d810dc5cd066eab7ea156a92e217329834e5a45c9794c5bc13d8388dbf93fc722a2c22b9fddfdae4968be65c95943f3ef779bd131dd5432365e0c1211432af849d7eb42c752caabd0ae5c1f74ec03a84f4916826626116ef27fdc438176e156e29ca9bb48be5cdc3b0616384dd4d18fef79cf3c81b5f16156bce6a264a9c0fa70d6c9aef73e810b62f42f9325b44572e6b821e009119c2812c72cd9bc35dd5eec52384d81b475ab49cbc2417fc29202a834b29d1fecc1e801c00c570fbf22fc76cddb20cb2e15efe2431ac81ce43ed65d485637efde8c3b60831647c41a8f48752b0fa5fcb545fa430e10ece04022a763928c57179ed0f2a372ebc02f87f3d1cf5e7b8f19753897bffdc816718493dfa2dba5576b0633113fbddc676828257367edff49b8d44c87118ef8cc3843a4d70d5d6e5e708e04c1eeeef81b07ffa5d209c6e8250447a70dbc5000f7d8ec2c89540814b747ac9c8f4ea0e7afcd35a5cb47a6cce5e0884b87c6f25ce2b5231f67dcb063d316cb4a0ef3e90bff1603fa8dbab80b8e23da96c59e7e092c8629e0ffb0456d5ea79c942075430cf7761cce6b15df754682b8083722bc13b4fec5343a1f5235b222d000370401c1149ada3ba24c7c202afd77b66da081366d53e6b0138a8666fcb1e71065955589acff3f83b345caa06ade31addc5d851839b23eae1d0ced161ce58bc01ff2417243e9017dbc5bd720b65a791cad5310fb1afec0f4f5ee38874120aae08b53ff6e8e52c006c6cf69a0faea55de3df53e89680f728e05863fc7243914929af05df640da11a37539bd9a4affe8413840ce6e0fbbf73776e0f86aff94231f1cdf82601db51b704df6d76417b8e5dcd1323601a24b822fcbac4f8d00c027bfbecbb01180f429433b8b84694ea7284eb8bb4f890a8c624337dbcdc0f653a0920d050363a1c7d30aa3c1bd61409347d90c190e0b7ffdc6ddf1e7098e38d0b824666ec9469fc069d93e61e2b9cec2e4e74dab30411fc8fdd4fb6d866939ae10b46fceb9b0d6015328b9a2a2b34f7af1a3a0f4174a14e0d6c22aed401787aa2dc24a83dac5519e59fd5bdeadac8ffd83bec3f2fff864b07cadb52b4daf20ebc85de8f0516a7c5e6b75605685347fec7b3a8ec1066b9ed2baee0b5762c10f39eeb4b6e997240bb0f0b40b37a878b11bf4e4738f9040a1ff98997e8f95e5bad3d6669a64a0b82fc2d7b257637867ebc68c2a6efbe06cd46fad94fa2ed187269932c06c493922e0d7a369ea81cf217e884f33ac835d74ca5b774a59b685ac02d2063f9964ca765f0d3c452e71e41f84b4e26a3d8475faac7d5112d2594ef3fb359cd643c3e5dccbe73971839adfc82e21f8985114506e135641ec1b779e05df103cee5b5c3088d41f70813e448c967bbb806f3d6a302b83bd657dc89d259438899b908fa46072459d05ad6e60a926a00328781a63b97ef38e98fb39e352b9a3d177d4a4c118ee1aaa86d47dcf187eb85e362b979aa27eb628e433e912c6a5c34d605bd5f5e3754ebd3a579e9ca2586ae4c1d18c683104bdcaaf1fca925ca2dffa4dc361aa0c54112c650aaf6aa1021267c56c276746644af4371c6cdf559a4697b1f0d0ca110a024046fd4ac3397523067b520ee5967385a9cfdb3d822ee04770e9245702247e0ceaf85eff5cdc9c26420a8b83741d0ec9eec261cf96c2eec62bb86dc75d7d2b56ae613c0eebdae2bca0ffab9de4087c820f31cad314e320e978d2b26404b332b245b41523906213d274c97f482b6f2f6504197d2a2f5346ff8141fa51c734469857d1554802ab1d2c39582890e6fd99ab9451c8c23dc98f2e6b8c230d65675c0382828bbe0ce29e61e912647690c64bb377cb279571275405bca9c7c06d7d912d5f396a741700ba283d3a70521ea4b1c38c7d11ff51042202b3660931263623a23c93fb73c76e21a86a47d055fc5ca2054ca046fdf5be565cb110eb7b07e164e53458a32b3aac3522b4d01d42d4f865440fcd423ec0e068169d34ce5d1e44dc34d62af369c2b103bb3dc2eab3fd94aebd20c42324c6bd52d586d931d791abbbcc5eb97cf450b30d74a5353edabc8993e7c7160b2b8dea6724457eaa0338784bbe96a20e9c10f86147e687266b52f2ceb2536c55bd84794612164515fb77aef3a62d5bc89b527506d966b32554df4097c0857b48b21edf3bc741dc660e5ad7bce06b7b4ff95282d4ecc8495a14feb3432355cb47771f89f4632d119dbe75c889700f7f212ac2d9d92013d4424b8d985969e3c62ad9044786fe4c25cec8adb8cf505083bb498886d55c70db6cdfc949c4a98e911fc78c5de93c787004d4729d9d8ee8ba79121b6eee0b7793d98d9ea512030d011ef5615da01ee7b15897449a7e688c329b6488cb443e5c220bd1b909729501ea2a607d0ae46c76a35940f21f2a9fc0dba74ec5e7bb0400856bb81eaa97a7ed92806086713ba502ffe4f3ca0ba26fe9f4b97dbc06d947f9d3f7190b304ab52f96c0c5f0b6f340fa322dddde99fff595bc920de61de62e85a216d3ad613bb84dc76c7b9102258ed5d180b2b8b6a4ccd4afdf13ac1cb164ba4a7bdc8abc5ce0dda99ab833c433df2ba4ab73af686bdb4cee9d039e6428aec45cee01edb8be7d041045c9fb44185e5eb403f21e84ea877b018d5b554109f3db4a5b387b2e854cc9f38c61ec2d50e386c753b0f79e53ef31c38984c547be810bc5970645a1e3c1fc790dd4fc0905d9e853fe51f25512376c588717cb9a4a39156462fb28f79d9729853e68ce14b3ba5808df5bf6686efd68b79a39f44514584aa516babb952b9ca89360b6576f75ae1c76ff1f9cb76ee6a0b204f1b10f7283b027a00da981ddf48193921f9c9367593f1cd25f44b41d5502edee85087ac6b8e1675108071af5c61fd8fcd7876a5cb6c0eb5a7695f75f0503850a1b217c3331c65bf154dab73028ef382a51698bfd3c53bd89320c0eeba07d9f7f9c41ae2202244e8715910f1c74117bc96901b15bd5bf9c542a83cca65d004ca8492ad1d5c95d747041804c00b0efd9b9603f8c7f69b4221c1708c8bc816b0d9f4ab913f067a0a449437d6ee7da3cc3e7a8252c58b484230b14c5140d2c5e5ee32e4f56b5fdeac760efe08f05e78d803e36ecd6c48ec91489e203682008241ff7dc008818664e40e3eae4c6d9964cfa16be15d501d44b372776c13c63cfb115cec033d9b5c6f7b8044e4adce03110ea1860f859a216e014eb9df27ede8fe97f128c3eee3d6d0778799fdc5eef92efb5b778d85615d8ae5cc0d40f9d8291078b87e486bdfcc364f7b18db7e9b333c5d94a91cd6629f6194597a57d8b892fafece67d57c627e8f0fe6f2af109e8c1b6d473b59b29efea81ec935fd725398e4e3a99d825a80693c8270db4c6fb26f5ed82202bd3fe7dc602c07163a8a55e4028b3b5fa3744a7e0f9c70350989dfea29bafa9aa33fdef3e188e539889216fd8c322868bdaad1264dd1e4e2c0f3a09ab686020b6dad5efeba6fa688971f36b77beb03171b4439d4fc111c67784755ef0d8f9696b4f0b5f6ce921b27928cac0e18727dd7e7cddd4ad0fba7199ab5f14c56e55194800d40fc9d66ac3d800ce91ed171cdc48d7d2a53a6fd7ee7cc0648bd0d61b16c7e8c03eef96b1a228933b1513f4b4c877ca02fb099864fd59f23baba9abc9916cc2da1ea7e54c1f13ee075665946aa5b6781148ff308e2d41d7fd046de664d5e8281b0190b2c1e0f89cf77fe7bc398ffafc7986643bf3c6c84b347a81296f7a234de87d9adbd3be1abe4d5cd73b49681da914cae19d8ffc979739614cfd8ea622a3eff463e2a16de4977ffe59e20cbba6e5ce51918e40c5d195a20560ea15226c8f6006ec92998ca77e3fbc3e54361d39500329cf6c12af8a57926299f79e073ca3b3825c051b1f156d5c6c38a7c3ace905cdd5cd1cea47e09663c6334fbe4fc0a35dd96f3f850f2f38aa7cfbc09f0c996123cd496caf3e8503ecac86dfcce9b44ea017faa85b7b306cb63eac4f18d618a53e50048c1620621f196acf146e89af50ba4fd2d40ac5ccaf7e3f2e6ff1fed21f56400658e4c2a52af3303751793998eefee0f278c59c01bf583aec3a0981bef5305ec3828993ff8b95df2ca5e633481dad69163abf24198bf43751b2c79abe9decf041bf36b8439abe3abb91b104dbe1052db4be6a156c9baba72b60e8e799df01e83a01d8117dc322a3b739d8180e45637f2f977ef75f8250dc207cbfe04fb1de233e6307e3ef09636aef8342da36d14bedc7bd64e1a9317e47d4f4b7e05f17575f52922ddc02593f7c5cb8d2ffe0b143fa76c7b2f77dee547575cc5302792df1ba23da2b42be5a64429479a402c023093bc890b88930786520783b8f32191f856c5552f2993cde3886e8d223d0a41f8937e09858d87178eab8b2ee3b2417dad603b0f1a1a3e969c5d53e2da682a75b5f3244065a0d9a30d55371e7066016c294006fcb433b62795b15ab5eef24c745785f9d6237e7f688cd9778f9283c81fa73a63f1e56d3e7cb3be29f8d536caf1d13977690ecbbfdc7f8b2071a688831619f1d42dc548b4a93dec670aaca055ed78a3ff2786894045545c94815dc667074e992fe6be31b0bf2fa7f998befe7c69531c4a3dc3e751c9a899be83441e01b1504f6afccc054e7daf3e346a3c6d59fe26e91c8216a8cc0cf36bd9bdb3d2601c881a83c6e3a328e59259423ff46bd410ee31deeee240e8d6616fccc9271fbf98c398ccb14eef09ae9230b1cb10c31920be42c268121ca03cec38040ae66699de5e9c222587e3f7d2033c54ce603e13eed7af036cf35adabfe773d052fd7827e6b71828ffd2d0ac7e5429a193ae239f90553f821c7ffef986e6c2dbfacd0f376e54ed42ad39728d93d02a5782c03078b779bbad35e3a7d5f1d710abb309042a6c179593c4f433a80a0bb643e62fbc992f08d86ea3a9e8bc6511d05ea298011ba7bc6d68a6213b066d87682ba5b16ecc22d040370e11b5ddfe2125d530fde53540f6f28e416a60f37849e8cdd8f8bb03175c0ff3bcccd7fd2d7502a5ce74f559c825fb5be93ea1f518ea06152863ce825a25f62fa799dddd9a64207d5184f0dfdce3d651be04cc63cf9e1a012b78a89ddcb93e10accdbe56aba59982313a0e416c5ef83e0ae68c50ff5e01aa9333d31402afa54703532f20ecc7ca1a61b2dfdb7d0e4d12e41b2e1623a9416d9d4352cd26ebe66242512a1c51d1ca49209be0fda4180164198285a620ecc182cdd0dca5ee084ded325c4c73eb13cd62a722d718fbb7d8b66eabb23c37f95e83cc8db68ccd1e52a3fabefc73105691bdca7bbacf7e794a43508399fcf8eb225cf918d1934b42e59dacaf71020a5a76b6fa7a38822d7d4a890434d1081fedb9fc0c397aab28ba420db32106154fa830837f85b4692854e9d440d25643f0a1e051e4f2b8ef8f62860c93ab3520565b96627ac70a83706ce6d9a30222111e16f466103f84cf9d3123ef500da3ef206e9aea22b769913b3801d441a74a84aff77b0ee9ef5efb60841d226fe3a8138caac2ed850a66bfe1c87e3e79fb65586a342484e0c98175b60b6c57f7486474769ff7fa734851792d63fa08ff54bda93270522c5f04afa1dc4ada3f79807986088797bc47d80e5ff01d2a12fd2a779debd7f9fa837655dd3bc779ee5499cd1b33c0dcf2ab34fdf55e0a82bfbdcd5d253efce1b2f6d960dc762ed921e4573730706e0a3091896d16eeb8bdb96e8f65c7c601d46b1dbdcd8087295fbaa01af43a6026835e83a1f4c43a46ecff30ce60dff7c1badc6a8c314f052c0a0c11008000618289846071f2fad5acacf0f01e859e78f6df21d5fcd71d0f1be83d76d2d5dc2cfbf0948c170993a65e62d7a55d41f46ede5087a93f3098ca362dfae04d700e95ce609f91550630212df80bc50e7fa3978f7d42ce53f42c6addbc9c6d077f73075d6ffa88b5553eec6a4ff83093370982001f5ead5615cd573aedc7f9476d747f0873ce76b83caeea5701071ac06f357d2eb900fb7ad14a37726f649c35f73e08afe9335fbb01503c9f0e3d162c5ee35fb58a5b63e331f26f62feabb52da8ece02b8b319f6865d465e9f57efe4e08ada9f02eeb52353cb5fd25343f32115e685ce8d3fbd8daae759f447e334a816bec2bebfb72f8d7b2c33392c207d81c81a9b672d17e32fec5dda4577068ff6367cd5ed1ef59ede7c92b91503855be08643f71183dbd7997ecf97dcce397f95cbc94bfdb6609c7398328aa805a6181529a135877001bc365ca2859234c03291979ee678b9cbbbb295782dbae5789f0d2fe7089a0c5cd8272fec1b7743bcaf68b11ebadcfbdbfdd0b6134bfd14cc3d5dbf71e88ba17756ab6b96fdd1b61e64d4b18bbbe9f0c589f7e0c661b39d1b257b88d17616505998c83d6ca39d1c4696e50bc23f05e98eb449f957258e553de5cf209aed1c11770457e3f19eca077f206e81cdd6907d88fd76231fa5d83c7ddced2012d9865bb3c66f114fedaadd2e31bc95b228008afe157109d3ffacd1cd757cb1f88b99882ee5a0537ee7d352e7ee71b15bfee6e67f197db4d76e52f23816eb0dfe999a6a1f685087900da4f99d3853f4117c730ce745e8e024e25494f6a0238fdc577d61e83763edb09c141d67df27f3648a067ae805fb0ebdf485ee8a885a1885e335531796f01d02753fc3ded3f9fa3762e54ea6bd5fa42cb005bae3d5c0a80a665698682e6c30b4116a1c24ef0c2318504828f93c6299eb19d5c6178d5f57003e448fe3c179452fc7b496af084f32f0084d385b032b08f0eb44d89581f4a5bb497e2773ee455d5f6d3c2b93fd71ffbbfdf00040fd0c99265ef4ceace8d0fbee333c1a51ac62e0e6907747c6cf8eec86a76962a9717536e873c07cf0c2d3d034772fe9389ae9c8920ec407ea6c8f6213a81b1d1081bf66f5c1cb238ebbbf2099810fd204691e96ae1c3dd8997915e91b500969c120136f47124a1ef50124cc95fc9f49e6db4a8b8b4a652046798c1d23959582484dc3bb4c441662fc730f2069f6631de546e83aa6a284bfafe30aa4d188fd3a9bf12af84beb159703f92af9672dcc3508a9ab1059756918f3b8d5a295b823e006857d5ac2a8bd830e4eecaefa31039ea4c4c54b939e895f35619818443d4d4af0b0fa6651d2095d050328454b6ce08957bec3e08397c6aae23b121c0b598e464505a3e0bffb9ce4018d619d5d7592c742268fa913efc12e5dfca3f25b73cb88e86881259244c690e08c288b02384831556c1d30339462e095e51172128634fa2dae00e3f52ab927b8a5bfc1ca3f2df072485045058ff29a95aa42d78021fa9e9f89ec3d2f51c20f0d0c708ef984826209aee8e71dccb87e1162c05700f7bbf1295cf71e97691c5f57c7050ee5d7695e0a68e8ed2062bd9db0652c938dda80ee2c2cfd8de436dc0b5e76c0d8f8f1186a9bb756f2cbe83aa739cbe34868892ebd11cc8513e5d730d39c81502e7e7859fda453c2b2fe6ea1f4518f93bb5ac5b10e2016279c9ce1c660e6c90445c1a54dcac27ebdcba2d670e636cc64e73d50c3bc35dfeb2a5bd8ddd6fd28cb7b84d6b361fd4cca2a0431dc6432c2c997df3e22656086f78ff2fb65a1264c5970cfa7f69e2b3e43589e346579f7525c1442c4525596c98d857c05ae7958b7ffa54e36455a693768f9425d892bb41f1a49e4eb6300725db003dec8f7629a63cdd692f775a50d269321305bf5087786f0524aa0bc12ac2568ca27e5435411a54de2e832f803207d388a6a556ea9007f7b021a92b72b089009820f7d6b3827e9b8b7c5f809f356a5eb780d16153381f24d492d2e8f00b95ff304dbcef4944bdb1a64d0f43c5ad180c37123e893612c4dd61d390e2cf41c4659b38e3846ff4e5d4d7277cf58cae35550e70bf14d855d95f4224cd70e6cbad169cc7fab20a340f504e1427bc609535c802f06349513abd19042b135b31fdabf51802d6dd1c77b7a1fd37de5c00cf5538c38e452b6981500033d690dd187a935632ed168468e2ebd35548188f4182beaecd7b65412cde7a8da723f8868fa691cf701b9ebc094d6b3b76f67756ce8a9fd14b7caf20b689bafc9b8a8e37db8482126c0841c4379ceb923b1cc2415dcc0b13e02e878ce261caed002ae8d14ff771ee8b0d7213f630d240096d9a681a044e22fb7107cbaa6df2de363a28187947cafa440d20140ebad983b748e4b7b7df6bcd12f1f445bd65e6b487329b9050fc82305e100487058ff5917292802c490c76bc5afccef39e36ee6e97403df4aa529fccc497b00a5d40cce9f26eb9850f37bb1654d009974ee7ed8950b4b47f8091f6974fc024a6e174fcff243001eb6b41411d3d96e921eb0b8000404a0b521aebae9815f7f155f6c0540dc00040ae0494191e0e646a0e784bf5126547f0c5950a74afd4802644f2cbb1f1da03ea7efd619c0e51ee1941a308d18aaee81f4dffabafd9ebd8592a487a09ec4c0d2f8c9cbe97ba03fc00c48995f0675c3c1ef53ec7f2548b3ab0c668ebab011207ff7dc6903563cd4cfc435eca454e050987ab3e5dcc8bf6da2bbe33bd50ca630decb8b46f5a04e022c78bf8a0ce2d409d8c5ac77a82b119137fffb1d1383c8027109b9415f42756216d0bcc0e1f302bb96b6aee7c3f946460be2a73ee2784a6b3c86c83689d33722609725c88f0602832da1bcb87d4487c75b107880f13ffd4876fd5dfa0241e016eb74259b721ae097b870bc2b16963f205b544416a3040aa1dfae42dfee86fb5cb342f681024d9d59effecda549f77871fc9fdbc4791ac9236a855f11e795fa65d112c2b306a4af1c8643a954fdb8019a117a02e3405ac0f771aeae3c45126fd89314a1fb74475063b795b6d9687c13430caeffa3c63f5ec164e40b7b07799ae9019445d604802d479f0ef387682d70f5b5c7da91f1eac15dab5a943eb65c6fc33bcf68bbbc6688da6380792d7569680bf434938e2542dd1948ab2639dfeec8fb400d5e58d5e3df035aed3510eb6702a51f65b43fc641771a02150e4b9f4f9740d2c8dcdb50d82c18e5400681418fc04260a19ec2da7909d561be53de21c65605cf79995c1d40afe71364e8bbcd896eaf2a248cb189153572f53e00db2154b7d0a5d34b6df73c5a92a5cb77b70c654a567b67fd7abe07acfe6a39f53dda3891d15caa829405e914a099412f533e1efab7a11a5b1d8dbb932d074f1f761e6aadd5a0379d85ed371d6cbf1be84656567870fe2a822e4185ebac455d82ac032b6b403fafaf2304e274c1b00007e63c018fb79a42c575203591c3aa19144f6b34c40273001e885653cce0900b47c592f1c360c9a884d4626f972115e85ef89657e089b411135c8521a7c3e418dc383969b705b58d6330a907d40f54152c7ebad4828632dd55421ba178ab414b8009dafd8ab92fe5f23938fe415ad63e27349b788fb8364fa5f39b41fa4fa447dd554eaab7d21311a3cee53daf657b4d97850839dc39f6bc45a41a686556e251dd48125f899c1fe7678544f08c2c5f00733631062d70a6a9114afcb801dcfc3995a7e5969c34d2d29fc6d7c0af3565bb7b3106be3d139b3a4e9c6d2679e27f1e9f7cd2f73363c4dff93ac580bd3c2dd50a415a620272420f6772d7c8d3a1f017a4a03ea095df1f1fb09594d43967d36d4a47f78a6f6b2f2366bcd09a02267d65f237b632e29ececef168775c5e07986b94d2776e11777c834f020c3d5f6764f6ff7e7a51e89403819b1fa3a686695d98c7ae5a0cda21068730a7e8e1e21929c97af4cee597b62e9fa648dc6455aa118f88c3e6738db1b43206f1e162d36f68dd092f05500ff8b9bf48230c2e594f589f4562d1a5cb88d59ee31c459cebdcda455066f74fd7be7eaf43f1c709501388b34f5e3a5a17f2a38d6142e8e4abb96b0498044dfc461e88ce418c47b6e92803b67db5fd8617a963b417d7c08a77f431dc4b28475a4d49de25d2861983ee03b3972659eae6a7f9c6008b4cb2f2184ac8960d16b7331fa01a011f7b8a2d44f8c5ddb317be9a03ed86d19ff8b5fa020b5e9b32ac28fafb4daa754039446102a8def0d8e5ab127f8902ec9b3488bc54b7d475968809aa28c145dd1f13ad2be3689d19b24c7550433b5d6c6e6c962e276d216bd8cb17ecb0acb54bf50c92ea7dc0905441ab0ff7bd29deac35eaf0cb896effe3a0563445ab84d963d60e7b0a1441fd7ac1a372c9090c1d608c9668a5581c3c06b14e1316a5f746085e6876f16c29388bf4398b2b92e9fb0c0bdd21a42d705021c4ad2ed10436da83a09e99f8ea8275f96c8f304b9d336064e555ac1c8074992c742aa23d5c0b06e61570364dd8d64d8ba1c21aabf199f87eb7c4c646c86a1447f9627b03947e2c0c67547e201feebd8986b13108744882dd661b24154f765a1312d4a12fe8212455c7b825a665c0fcb6bd306822b8cf2779cf9b3424e72e1efeef7305a0124146e309c0e6cf8d1d9610021b798e50e8860575fdb0afece60349e704f47959dce7b8b061f93e496eac6c1acddd4e9af441b81469d202463083daf14383c7eb2b56e5ceb8a5b44f3482135fa6c7befa2559760cdb584cbc03c630025fa03991121c14e7070b8251c295c5bfc9ceb31810e92ef200f6c2c1c1c570cc881444c5d129abb4bf2eb23166a389e76d60ac51dc8f09aa25b9774e2c59636bd60ae529632b324600f93fee8edbfc199a310f4a016b1372673438a653d8166c1339f3031d4d7fa468841060ad849912d86172b4922d10b00dbafcc422a5e563199277f866439dd6d60c5ee1164bbdab3735ca18ddfad168b3b085a368a83e06ce1470f7ef76a25aa53408c24158fca54f7c383f00052f07cba12247c0718a1fc91436e4359cab87e644f7143c8fb9f51c018c866204b2de629b596d465f0a0a1c9ff9e7dc972d9677a064e87c9bdfabb2f18a48075e42b2b53a2b37a61c21ff01bd1aa3e7b0a1279fc127bb9036c8f3c86114921ba930c245e55359e3280e3e13bdc4b7c885517b07b51125dbd1676fb3436ea74ddc8e37da24b7c8e12f8392f7bd2e3e3a5e163491b491f87d8160654becc32e85744c231040ae35fcad92ea8a972f13871182dd312a5c74ac09bf2a5d9a82f20a003eaa86d52940397c060b9d9d3be6d3df86818aecb03aa73abb04c6b9a99c5a2c489ab0fb49a84321b95759dc6d7406ab0c47b912452f5d3933cfcb69f3b66607408a6a0a0464fa8d87bb11171716a23a5af9b721ccb250cdd490515516bbe698132f3d6b9d16baf29e22d316a25c431564cd8e84a072f2c0b76fd325168b54651fcbb471d270679008ac61eb63d8ffe37e4744f0c25e955dbec1af1c1bc26ca79581ae0afb0e6aaeac6f307121714145aa1b89b88b87df5288bf72d67e3a2b13b49c4dd744ad9443d781b87f4a87bc52a2c5becb14bc2a6c53feb65ffdf9e27105a69154492b39c06a9cd4e591e4399f8dfebe4caf6d6acbc8d58182c489a0516fbc012491a8080418218ede8efcdab3c79c4d206ad878b673ba0d73d8d03b3d50166c2be1ae9d0763cb31c844631856be8cb679b41db91fb8de2df4801884ded10e1d7a717f162fe0e98aa591a05d0b272510cad53212124037092e4863e81321bbfce00b8d634a1c4c405c7f5f7d17b4fbd09af04e0a86629cda631aa4a645626311a450ef863afde4d563456f037c1cbb8976e26244206443612ca22f62737ef3adb35fc431a5038ecbf1178d88e20944bdb8d0a0de69cf7831f17e58fbf83823c613338ef24b7c05c81bf734664d9f14de44b164afc38a8b3abf7496b10659f2e9dd744a2ccac766759e01b79b3b66184b07f49be273493787ae30ec7fe73709928ce07c863131f5da87284d8188d2ae6986b8fd963dfa01ec76d517e486198425954c8235a747b428b24bfdf0e47f7a37dd29a0eebe732bb20d74a501967aec8f36a69d03ae0c9e3a1ebec9531ef6e8f511d12f586dc311febffea3de0e8132f7c8b36bc0ea0a99b6a13917feee9433939d4586b8c80610bb4dff0d9e73fa7077b7d9c0004c6f9267be79cc6682f9467d81f45ffa1c7520f67b8d39053dee40871273e17eafdb20ff5b8ca0ffc612cf7acdff88d2ed9ec3a48d827f69581b56c5b2f04f4266cdca006fee7ff7820b691de6e55397ed36e73bf0b0d9356c10c57f8b0caed09df01bec56af69aa78a5af2d5af85f555b4adcb17d84a44c520b98b48a26f43298931c78764db1d1dc29ce285f9cd5ab88712ab1e837700c28083293d56fca0174f40e7fcca3db32baa3ea37c6ebe48e25e28d6bcc2183124c4dea1a02b80174f629935193d7110c907783fdace87ba5ec4eb5c3cb2741d0622599649a3292eadd20118bccde5a2bc7897e67d99d60bf5ba8d808d3116b5625a258cf1a8226e11ed6c1378c15a349089300d88f9756b04803db0cb6fe03bb45ac8f84b32f14efe51479259d324148ffc22a96f689c1532a5ef7d2525ecff4a871abfed8b1cd9a3282a44aa65b82779161c874eaf9a8cdfb39c08462f669118df365cee8a6159db22568a1e31d954a447ff487f0030ed24c37aa10f06f5317d252baed0aefb41966a6c66302c65675de6561ff22515998412b22653f9aca04d43b96cb7d1f5565c93a415c501f86887ddc3ef047b6a76278068fbdb86ff9a379416917a4e7c060379aa22f9f63b0083c9882c000df2b2abb2928692e2d07ae5dec70d5f159777eacc1b3fe4e55bf88e679f5dabb2c1ca60b0a781c0f58dcd01f18d39198dc931908803a6fb11d0812591c10d56263aaee0686510dda42373acb5be6b5233cad566bf4fb2248e36ca181a319a378e44863c1d1b72de4859679a2883177abd8e0fe23a5b4f02f652e0fb6408d304ef16f106d5d23b8dbb4691841452807ec2db38580bd82da36e8368b4806192ee5505716227574a9bbc9071c1370b292a14ca3c6d9a849c1f302cf677176441da6b0e09608e5e246e2d174fab979662624dea70ff40349d416b59e9a6c276a906c84bedd15bd79e63585916a5246b32ef474923c5de148c5ba51fd679d7cbc4d32e9f35c0fde99eda3aec46532f1394c53ef750dae421ec2102572250dafa936ac9d0d675cfd951b2def55c4e605291b28132577a08fa231c0d39493b08a0c8db96a7d098a5cb1d43562d97ebfa2f2dcc98a2b2369665fc96080d7f90adec7ee33b32562dbde1ddbbe544840b5427444d6e31201e1db12b2a131c8f2996e47b0afdfb09575523c2312cacd488e2d4934723c1c0a5ba6f32cc3d70b71b7d3da6161b09a68614f62af228bc06985efcc2f9d44b7722ded66693c25fcd1cc09b19939e24f8c0658536fef69e864bc7f40a69b826a4263a1e7fb3e41bcdc4d0dcc803cf511341a33a0aa967109accbd1c67e40375d1bde7292d754c7bfa3631aa0aca3f5f7d8986518d095f5879340e10180785af8be7bf8a41da3e733444b725c2d559a766516a0898c28e10f8cdd750a271f72b005c6f68abb9dfc0c50f2f660a04ef67e48f56a376807ed93564d61797d32cd68d2ef751ce4a40b04c4bef608fe6027427d231308de03f886c4cb03dcdc1ebd51b30a22505d13fb1a0017524277325cc3fb260f177136ab229a06b61449607fb78428901c08c91302415869f9e7ce379a4fb42fd8055278acfcd4aff1c470ef53833b615070ba80787bd346ed6c090a1de8e509b57cb7ef6d09e67ff9e2bc9e00ee7de3a728444eb20c6d685199f90114213b1c72bf8ea6451511667110f188c12e2e14f9125c805d161e67531d31e47b10091e225ec581b2a4390ca8142046bb8f087bd627bd690f66e8a9b95713708c0a6c6244477b61b92752e178b4bf9ce1bc044136f108e60496a0738e36e1c08895e043a3f4cebc7a38c5bdb17b2f959ec1d05cc90a208eff54cf0fe0037dc0d907f04c2b78b2cec92517e4a3c6ef3ba08530da7ce5744634962c46181ebd7a9ed10cd140661cdf43c054e114c2cb01d73c969f64ee1fd216f77fed4c162970801ae19b51d781fd4804a8bdd0335d4a644b02d5e2ce1f237e83b8cc9ff684abfab59ab7f3cbbd736f370eb3116433fbdf3c1a95088a15ebebc87e621e1136cb38ccb6fe4953f34b709a0f79f6ddc8a843f3fc4a327aa9dd0d0d833465bfd821aad4cb07deffd24ee98de01364e6f8d83040a094ba1f23a2af5a967d426c73f9c020fdee5a261ac2a1af29b9ca2e51f3c6cf222455135d0f38bb5800e37606c2e450b224a6e81116b4f278feca2691b557758c0822cdeeaaea2070c84fb8bbaf2b2addba66d8bbb95d5510c97f8dc1773ee6e418951e5e31c1ba15407bd161e0a0b6dd789b386559d745c4cc1709b419c0dfb5236906a8ab56336a9accbae0c04af06aeedacc4e26f695b8234b26e07cf5be2952a318c3786652ff664bb58338ceb9051d023173668e7a56dc9cb11c22a574394b59b224f9bc2ccfefd895e4e2fd377681e6a2802c4c7d774a399bba0159079ac4416e3be9337a7dd29ee427e2b21ba1ebdc1f0e7c3d73b198de2f217fa368659b49c27f99440d1e6582300a7b5d7aca57e644bba3988000f1fc02041f29700b933a44703bda51b1dc8ef91fd309d980cf20183353012896bab3ecb7e83b303854c18e105e8f0f844dd680f12e8239b868c7d83cc395d3949bed6f0aec0fac4fe969e4f64ec990a2dc3b73ba54849f9684353dc5b4a2c94e8a04b0592685bb84ea174c736ba108b015d9abd508ae550fdfa9b2deb4c57eb2aec2f51e151c2b145282ea9455716315d2ed583a0daf7eedad32c07e09670d4992957236b953dab6be3a80e84bb1c5b3d73261a778f824cc17e1ca2d1af8c68b3ec1339fc8e1399cfecbf07a38f18dfb08209e9ca0451a2b55799058114dc33f800840562ad2ba95610efe35be0174c18099ea8d09c04ba698ec539a804efd86f781f32fe4a7fda1c73d082bbf4a1aa81cd212004a13c330fc96a4af0715cf7f50d1ac442e8b90efee38e7f9722ff91f7be7c73cdfd87e11362d85f556657d8eaa7578b0cc0988ff9fc9aa13c22dc202d78dbe276a7578d0293fc8de7bed3dbd0ebf39fa38fc19dd16f8043dd07f22fd5bc9f5a6ebce6208c0218b48bc1fcef97f3a6bd4d277d2a36de93468d8a59d7f4890244dc176dad737322f7af211f7dbb7745069db6d416d7919eff7dfa20b7e184c9c188b6f2eba5d30be27d8c5692a7c7df4a539a6cc0979e77efccbf44566e13752401edaf3fceeb883f7fd23e6436ce4b018c1745bd5cb976650e7ec9f6316ed50d0a718dee3ffe27a8e31671c7565c12f98f16d79c1e91a5eef4df38c5fdbb0986173337affcffb013b7fa11a92f7ba77d5ff957a47326a64ac6bafe93d9d9ba87d6d0400cfec6f873b83d7e0cf38ace2cab662b141734ca7825df1fa0977f9d2e3afa10e603e5689de49d8635962d22587aee7f6976c6b501ee2cbe7cf7735c9faf9dc92db6a7e98619af520bf3b0ef3dfc31e872502d32c5beb3d741a98b9145f1dc23c9be37cc34cbb331836d79a816804f897e7d887ea2ffbccf3c8afa5cc07209ec43d85ecd0df6edd55ea5f99f97b994b1a7a9fac6ccaa1f1afa7cb5f667fcc41f1a376f42cfad7c6ead2dfb87501d653de57cbf97e2b3cc679e739c11fe7a4c141d2fb2b8f5740832e5873f925bb9f3cf383ca0937b95b5fcd36df634e8a894b7b5f0f467467827b8be23378a32e7da3be46a9fac76f15eda18d3109064a0339905ae765db253b1a7e50b9bf43ff541fcfb7274dc8a2fb84bd8dbf14cc603d7f62235362e8d6eb020a405fb33c9fc38f5aa81a6ef836bcdf515985af1a19e6fdf9b61a3b29a99fdced9e6670cc7e0bc6afec4fac87813c02f1cae4c502f7ec18b507510f3f9181d8b39bceab62fb836ecf83232bcb796c2459abbb370e4fcb8fa3e0c894d511823c22596e9fe10efb83f548529be75575ce72a2b8d3d977d1c4f7bfb6784ce48ed73ec2b5e3f21428b64c86364932f46949f2dc7bd633beb9c0c5b5b55d71ef3e66cd54d8c8510fe6799f817af3e703fe9f4b0ea5a1ce06470ec7a1673723b03aca59d074a73becd4483b0fd4fe2a12de1fb93d8c648fbf5eb353897b6f832cfe56884bae385e1893281babc95048a7d9909c9ebc5e70a376a8f28f4364bc1a522e46ceae6d8c54751d64793f1e3f03d21924eed8eb31fb86eb16726ebed0fe00c9f9fd1807416e6e8c5863b8f84dc20a0690cc8033669bd20e43fb5e05a948fabbf5f6704c00d5c323ef4e32680ee891f9109947caf421e84d5475aa268f95b67aa1da90da375898f518e6478332ed2759fc801590622705b3d4b3cef261ee6c317365cb990333bd6c9efd66bc0c3e2b6679592313cc5a9940d6cc84b21664fad82cfbc9f8185c56c8728ee96453ec1fe364b0b012968b353021ac25661dec3764ee0cdc26d00493e017e00370a26441923c038bddd441bf25b92cd69aff67d5238c8ae7d67b896f6f4da6c87481f15650a3858b4e2fb63570237cdf2cbee9f9be92fbb61c4f866fff5553065f6ec2c23c3ecab1fc3fcf420037b28ecc36f28a0d53de3cd98b2b6292027e5caa6e6419cdec3a0d4f4239389f6706edb22114b7db5198ca3606b00f4a1527efeef048fed372ba2a1734f07b43020679a6b2ba4e71207112929a5201e6c2af09163209989c98370f1af2acf22f37853f4d971514ad4ba32b68d5d392113ffc38a774560b983763d746daf7bfdd1a34bfc906241fcd27025408a308bcd51a7fcabef6783198128a6ba8ea2ef5425c08b377054794bb0d2edca57220e5820bf18e8afc9db0b61df8df3dbc44796690044afb4f97b39d701ced60c00c925f80c04f53319b5d5c4b84d3272a86b18abf3bbcbf7d976690594dd795f5261fae87f8152e7631f4aac6664777a3c62a3300d44e92e60acf9f4c637928cd7d03415065ae287e8cbb04d4d8319ce6fa4092b74a791a49bff5060e79f2c3e0c617dabe7ad100dc1208cb54d191ef4fe95bc43126f1afcca23c705aab2d97d8fe5f8177534eb7111f4e38c8b18814bd74d259d599d465609b1cba788fa2eb56d641088c067c8c93ef2bcc5c31880f506c3b2539b09847c047631e833d804684b0cb6ec3929dc5e18b44fd5ccd4f2e025c62aa8aa2ea87041b7ba5362e43a4e0149e386568a9e8e6ed613386ef5b4cc97da98f0a0a9d8db75c0e2594ce67423b423f835a8a4f1a167c3b0dde26d0f15c118a3e54b027853d74e281573c1ef6d91424f3716b9fed3f0d9e088e0841bfd285ad9c67d11f8efe28a2dfc0e2bd8f23c54ff4e54cc59f030a6fb9a4043ae2e1f6e8f3b197270a43bfc048e53ec44f8e2cc941574fd1c9e98676bfddbf9f4207c4c4d6aa04cd8e7c7fe774af9f8dfcd4b6e61a641baa9158f237e1e0c9b4c66b82794620443f39d9f723d0730db5843f7be2c7259f88a29ba8ac389cd8cfe67d567b43e5507836676e0d5aaf25e3c8537c82692a280158996a0b6295aa58af92b30094d911ffa2720954b895085ef6a3f6c719cb727ee82b96ebe577919f76086c603dd769e7284f3b76d99b1e00310d0adf3e08a2dae617af2dd971601e6df9f8cbfcb1dbe030aaf0cae083a0b23b806b9d658fcd422152db27548960295cd92cbe71a4e3ae6db55732d7719135fd0bce7a830016bd2bf7f2a96f2c0d43e9b515f900347edc427e5be7486d3278303c4681a000471e463bbd65adc92135304c90046e2605f1104b1030b33807ab991ef0d4c00f55303598eebc5e3f3bc0756c6e169f9af266f0a791adeea5fa2b7d4a4ae4c69889007e74b885b3dee0b10b2525252595b2a88b3d46d0e64783dc0a82304429461462125e0e14785f82764e5ab208b9d06116ac85829c28ec98e05b2d9de22824f915acf88e8209d4c2becc592d2727ecd5821d80e76541a1bc8a7b79305faad3573cb0e0bd9b03dc74706380f76e3878ef6683f76a0eb929c07befbd9b271abca739af39add65a6bad94524a29a594ce39e79c73ce29a594524a29658c31c618638c5042092594504209259450429973ce39e79c33c618638c31c6f7de7befbdf75a6badb5d65a5b6badb5d65a2ba594524a29a573ce39e79c734a29a594524a19638c31c608218410420861cc39e79c73ce19638c31c618e37befbdf7de7badb5d65a6badadb5d65a6bad95524a29a594d239e79c73ce39a594524a29a58c31c618638c30667c6da553462cac530ba50c529ca752caa0c92b6130c92b6180c82b61d0c72b6190c72b6110c72b6190c62b6100c62b6150c52b6180c4051658d0fdaaafb62b49ab5696d7b601bd7743800c6e3078dd055d57b999e025699fede7bd9b0108e0dd04e0bd477353c18d053715bcf7b4ee475709d3d22fd8eebcdfaaced37d925e9956ba6b1fe4392d3aa50a765ea9829a57a2408df75e014a202101b944c115af44417f250aa2bc120514bcd2047fbcd20465bcd2044bbcd20439bcd2045f5e69029c579a80c97bd28819ef49235fbc278d5cf1de13c04af3cde7b4fd705d57696d5d57d901ea522f4e554557f11cec054b7aa95047dbb62a4195b574a7fdd62b6ee3b817a7da266d6aa9a2207996eb7433c18d132b59767e3414501620200da5f90c59c98205d54507cb4b1b69d7c6b97cc2a060a4853855cb1f6d4218c6f2af93d1b64201c34e3ba59b289654f25e134a9a90a07b4ec3c074a82358131ca4adb5c2abf355bef63eaf6d037af99e5407d3e2cac2559c67c17eb4f7596dfd1e1344dee338adeb60af309ed3c27dabb5f14e65258ce7b4b4542c39612c582bb682ab6413421428346f8e2a4a35266c54d76957133ae6782ddd52b1545c89e690374789c6f5de9b62c67b57de6b52c604dedbb242b7d22ffd8fb60e0513f44b7757b7d2af16c678efbd266284f15ea75fdacaa9047dc8d9b90da9ebb496d44b37e9828bf71eae5dd75570d55534202db80605bdd755db16dd75feb93097d8f0defbdbe6392d9fdb82f29c8bda9c1ccf6dfc694043423a3f3da7208de81484b2a2119d7c744e405a10aa056d05d4cec9a7ca90166a090cef510beb5edbaa7baf8914665edb2aa89234baa76411974be73c8eea272d2448f9adabd0c02441e23d6e5aad341215935645a7ca7b2f0e852826291d8a8a5ad86b5b75dd6b5b45a1166692422d0c0affdc16d4e7c2441245dcc203b48507684bd779a32782175c2eedea9e9c301b6118866584510ba3569505121b541bcb88ea2009c0a3e9830a1e5e98475c783023d5eeb9392104abf7562b1b8738af85735ecb1c22745cd6a138ef7a128210742943ed901321de7b3d2787db7e23873862e63962c373c4e7bd9546a94ca8ee63aa8f72753a4449558618a1e259e1609c6f482d9d271f88e3035dbc264338e0bd15c7697c5bad74768478af49104d8028c1043653d4a050a3000ed0cc4103078d1b344f24e2a5e3b2ae3df73240e490d771d9a67a5e60dc87b55e1b06230901223481f46188217d1842872155bcf7562b58cb94e35d492f437230440c678829478a1428869c0c31b558b0d5c64d26df52719d7ec57ccaa48d368e8375beb5ada2fc966a0a950598b8cdf4a37f4cafcd088ac9d4b5fc51149e0821cccb140821847981e2bbaa052b0261862f528a728a8c5a9ba9a539ede2c9a201d147941694244ea3389de2a84e95fd95bfa4090583387922480f4d7e68e2c37b4d7a78af090f4d76a80190381ed1419133656ac82286049890c56bd610e60c211808614c941aaae4b0d0c2a10365d41000123a1884c9106368c04348100fe8e03c40031457645121051702a181c5c70a573c08d8d0700731a187072343838d0796e42446d0c50c721471c64b94207c664002a949171f9c40c10cfc01476918e0881266a0a2258b3fc61149649824005bc8e8207943863628c0c20d3648c0328c71e2c3d11c422490a1052aaaf06cc0432432e0e8204713629aa06268e4a8022f28c13e319461c58f062c40089e1874b029a4c68713361083963914a93947e81183010ad13e18410b2f88214407261d48e9a9418c17d7ca10c2ca8b8901881f8ab0169b189e094ab0610a9720c46050a692ff4316aea43de81b142089c19234c518274a78c0991392b800f850a9a24c4c32211002d4f09a3824dd7450250e2f91d0c436204375a9f082518c0908f4f0c515508a9891153951841e2123263f70e6830bd69804e992530ad49026bc209dc949828d4568e80209025b033268480520a16c84a650d20017129439c20041850c5198473ab000288298e149980aa8e1070c62b419617c30220404677ea884110a42409732280411c65485062d7c2eb90396888d2581688001476060cc71c90f92933460364ce12b7800cb08a6421476f8a1858b0a604fb2f051435701135e8058e0855ca304fc8545cf0d89680089265eb00dc831f412b3c14b0706868f48ce68f0aa80110f8ce032c50edd1d5d04c122098849f7c41f6280f0c68b8e6ea5041a4c38a11b3a1b08a4c3853019e86a7e84e8644055c065408518142141c4823ba275011f8a80c4076e57e0e6899d48ece0a65cc22de1842341604670c91a250e84d8030c1b92f621060f41c038408c322c21a28523305d1e4025ea68b0054c085588a0c6e303031723ddb6042d0211d704a228e0091b5708b972302962854c0f3b2e2d0618a263863c878b0336ceb0e18c971ab641c818910156298ead8b19343038199cb089d94ec268d2802236ad831c128ec884d92e08a408109c318394961e4c3e988104da8f9614640c3982921b6a68815101c88f4a8c926895700502e6146e8856930fbc58e387352c6069000c07d412e470b1c80895cc78802085b0be15585ca04a164558f2832d394b7421ac2ca909618c2464dcd51b149114dc98c48dd503c694a1047e4303ab2f607c61c30116e0b01a810d1a6c0527d4a3476ae07861eb241c5100863e2ca9a1c915473d0cd510e59119474148484002650b3c4a80086aec3045233e301ca2080dd641080a60f882113ae59a7102430d8498aeb4d0a483e19403077588391a02060d545b5439b3c502d51f4240a4ca58b9437585c98f006420c711d5cb900df0c06313a95220e38f2cb2f8e14245811a4662b450c18b14078c74a0040d0e10a59e484013fb122b5752471e03d7929c00a4aa224ea460a0083c52343dd4c1c50912018ce21000021ca10247112323c04880689103f860a42171001721a86087919432662004005676f89150724422303081ff1adb0f1098d1c5245f08184a3008ea86213e971ee21043027258f041a8e30e4986a8e0040f82045080888698f66470e09fc4490ef10de8c9e10248de58c4ffe451c78f50a781df400b581e3b43ec7441d018c11fd602dbb930a2857fc61f5b7a92a60110fc22d6addc9dd7236bb8d12f9052471025e504efc01f5bba5449e1126ee68b18cf124692bb8680c011173aa8c1736a00d20881620e0e0059c54de41029361d2208423162ca612f0102024a40c8b3637b300849228767c58e5f721043c7e3415372a68e117c412dd06ee4ec4819c2cb1d9a8833150d06cc10d35e3a1f32382881442b600d3b44d82a61a32804354c0e2d1c51538406085c72a038c244110f3f59643c8ce0451190145b8070020892a20370808b06c7181f4019c2871f4713a01c417d51004218c9f96204140d4144b1c1174538d415170e49839ce1028a0042d44c8b115cbce0c795a192215c6a78c18a2657c42690411c2fbc003034a5488f3b5e488189151c2c3260f1c20465584d02d1197cb1c3062e380c03c0be94f9594cf9b2451b5f6038e18f2b111884f5855e82a5491f5ab87c7970b836b04297e405037e1820910c805cf012811aae98a1a3870c5eb42c1301394ed0cb0272a020085205161722b1f1728818a6135c50838c0a416d1472840b414cd99940091404e1c2961fc81441a584285c00c1c90c3b5d2ac18168110f6c00b830a509a2319e747065c0a1810807a42b93c00348222c405021020ece64212a00148bb4a1411906b410c82168a8aee0208e16b6d0a13280304368d1428c8a2085249c232dec784944912950d4684100946010bba253bbe471c6036e94a1247489a28e40b00d51cce8b24d4005c9ab62812e597f30e6d5a32e4cb080d1cd2f8c70a10385282258c38b20b82461c9001861e2903fb8740c740a28c0076ce0029f10011904c0f95b4840e68c16c8c839618b0554803d6e1471c916229c28c0890d5c00c716175238218e06fc64b04584382e39a1e6218021475c70f40510800143661882451d3104606068072046f628da008a2116f478a4f405cf21431e4000013f9001a6132a648f0d5a9340e2454802272d4428828d198466a8b205143c389109f5a4800823fb8820944119137c79c38580203e2281ed3cbee0415448f2e5102dbc6409eaa614e0035c66b02008852d82d822045a8b202740445101283f3840754081889f401e070072e26800134469e10d2015081cab8c2d3210edc00114c81c7903e8952a80a38b1a2b162e70861f58a851c5b050c4111c6ca1249c61a1280608066c0cb15820c1051a310030148316113c5142122656b69634fa780201cb44075a7ea88411161aa104a565e80811f418814a0d5a3ed0c60844870a24914511282a4007074ae04216313a88830a0c922865b9818b3b161180061864f1f1018200a7098491a5140514303b8a20e227100f6e18011f3b54fc644102551011c816fc206565dcc1c71b27fc5401e20c168338d17f0290c58b27070927b0e08146140d9c11c30116282c31430099921e2caddd86204348c261c1596c1061c02422c062c3a978f89a089f390e0093c245a6031f240679e1008f74f1c4872332c8206b3c62c587ca1e4fb49890c15a619219b038c244119715dae828100d8285002b8cd11203d17282152b107180080c1c54a2b3020e203cf4a0c105e450a11130562b3e5a28a85046193d1a446006a8820e7a0361f8b0240d1558e8400016a0a12ba142072fd0e0040339439c0821249679e24c77f2228711be00a38c97930c4da4584468ba71e2391aa3911d2f4d9c3060c48d16e698c1e7ca1e12b823920dce245d994204b136fe28a3af705f48700dc08121574ee0511c61c38b14576e70e00112322a1ca0670372d44142e9092f7a9a2800193b5c541df4a43298648e2493203db38ae6dec08203cf25742c91481e32d8f09c99421010782e4086070264841106005a05e04109c1480f4ebac0e18982420bb94c10896890c43f4850081e1f68698c60089504647083e64307c00c72490e359a9016908c216daa6602820429506a88b092486c27a9034c8061258c29356f00a24224566c68648e265838f0002b2b1860903b0261448b95275c1c2016461029ec00d2659022224e783b58a8c132fa39f376c2502e3ae451e6ede8b09174ffb0e1ed5870240205d0f7aadc71461b0818f35e15282019425278af0acb00454071af8439e4bd57a5a60cca94810cf823f0c8816740c77befe96439d890822430bc14d8e8e1a530440a29b4f052c0790c68e4bdf7a885c909c3b00e14bd6792d2012daf033083f79c10f2defbf29ee421815eb3ef9cf741e4f17a2f0f2f795cc9c30416ace5f380cfa5594ff2c8c3c97b7840f2c77baa160c8f131e679ee9091e59bc2213e75f5c733ac5f108a2c8f5de2bc2c30b1e41efbda2229351aba5fd6adbb649bf542dd8f67225713bef35912186d8ea74fa1d493c9ac9297ef5da309af79a88497a2f048e0374c4c2bc3786035dec18f338a22776d8a15d54925e4d909a84e938affa1d0cc8d4552bddad563a39394fead0e352f1c1174f3650890682a0038f2f72d2116d95579eccf114308794879ac38d189cc38aa792318353a670dfa318bd277298795d0439b01c213c91a3e6994e30c164ca292a8a5be0960cc0de7b35374de2e8e1491cf8091c87e89449b3fc4b054717efbdac83ed277070a62e270c0e8b0140b257a74d5260dfd4ab743addb3fcebf4527149f197ae8201d405da28c13375da64c219ec79e49657cbab784b276e7903c78b51756e44a0c9d6a4c5f262545d67013016d862012baf8d36da38e3bdb7dab6dd3d0ad4729b8a73a53abd6a6dad967675da15c4061aef3d0e0513c274ad4dcb095b6ddb5ea30bb7f12a6a54f1440da297c13a934efda811c27befa561c47b5c960ad0b1d27ce35c2aee817a90b7c269df7a2f0915a3f6d47d4cc5c36d2faebfcbbfbadef22b95e7dcb6ad3e052830e53dfde39374d058e1b5ad823c4b25e46160b42b4b4b757446236744714696977df1f2da569d94de521db9e025eba24ce92dd51194a2de521d159d01cd882269d53a79ae5d41da6adbb494e15bde95e5ad563a2dd8e6626d3b9bebf57f541398f29e5f6d409d9c30324668a9585d87e3fc6a03d248419c90d04b55a563f9970fd35b3ea8b5a9c4a8ef89218067ca61b19e84817aafc90b5fde7b28974be7e4e4e4805183add27b2e25b482ad52a7826c951b92909c481a284e240d04279206ca1249036189a481ae44d240562269a02a91341095481a684a240d2425920682124903e588a4817044d240372269201b9134508d481a8846240d3423920692114903c588a481329206c2481ae82269208ba4812a9206a2481a6822692089a4812292068248fa0b0b9e046212f0e205225e54f1b2ee8598ac53f9f80ee5c57c2f43f23f48fea70b46bad0af8b8c0b49de7bef091778bcf7b2f7de08ef0917483ce162bf37c573ab6ddbdc132e16f0325514cf4179f9a02de0786f0b14e484b986b498218b04bc275914e03dc96200ef491613bc2759d438e1364e4ed87b4de87b4d662b0be7c3acb6a08ee3362cdbcff6238ff8e61361b7da362d3aada1f79a506992bd9c9c2bbc7f6d615a4859decb7969939c3093e9b585a9628a96d6e681545ca898e1bd292889d94aa7ec3efad6f6e38358bccb57717e4b90ee3ad7562bbdb3f9206d3edb86e2dd8605a1bc9cb0eea5da39392a9786a1ccf0f1c48cd013331ebcf7f4b6ea90ba56cee6b61ef331bdf2401aabd348497e059d27c4bc67da562edf5b788249c76565d828d3c57b9dcaf4a48c9527652e78e2c49828a8965fa15c2dbf42a1b8ddade48475af960fe3f54bf7265a7842268f27644c54583c8662f1d86bdbb827466809704eee67a49853211c1e201c497f8850453a9aa7df6bbe67ded86ece73eac617ebcf2ce33e4cb53f44a81752d0fef4f7c7483d87f8cf6bffdf50d98701dafd916ae8b5b6f046dc51d07495dcce2c2f8455d2adede9042d478d25ced2cff9e5853d75236ac6a883b383238423e483c3fd161bb90f33b39850e9be3866dae5d7f0de9eba91d3290e635209514209adc63df26b73ffa91bb95787cafea5e2b8741a074a180ad71f2214528e666dbdd14f19fd9fb7fa9bba1125a37db1feac3f44289b3ba4fe626f65d77fda78b32c93f4e368b1a4f65e6969bc96d69b6dcc586156ab4cb3d6ea0fa5de9dca9eb94edd8823d48393bd583fc311f2c141b55477722fd7f4dcc6e90f114adfcc461fc6af5031cd4a4035da56a8150774c239828412a5c011a844c94c53449022c2026408247c1025428122c20892b57114d75d0584208208382184400208dda3bc8a7b91f001cb143df751dcf6d21e24e0654240940378dfa140f0a083d2011403f49646510e48d8a0538550006a0f5042c093d886f4d2000104c8c05669c2e015f3a60b220803c0ff053b800058b0560022caa750af968a73a178a7627960c10815741c50200d30c1c691e0447bce003749fe08014d22ca1b710080ce0326118a8d04a1a6039a88eaa898f7e0b57008173172a0f12cdd62c2458c3234a8e0e94185199d77b300481e0981238d3002820f2ca24822881c624821840c22482080fce1471f7ceca187073a90071e7770c08e3a36a001393210071c1738f3861b1668838d35d448a3024d28d0048d2667bcf7487041ca7b72431befc90d7bbcc004890a9e1e5104a1f37e95d76625a8779d7bdaacac60ac1a598869eeb58f66b57834aba5593c4340489b4f8c276868e33cd1508c6728e814d32d958c51db3b0f8f8c511ba336a6450b8dc9190ba3b2c2c3c3c3c3138bd1989cb1586c2826a78c516be47fbaad2363d46e568686684cce582c151ba231398dfc4fb77586868256302c412b1896211896a1a1a1552a682865a4bad25b1e69f319c2311b71cc466e05c352230b46fea7db3a432aada5779d21ce288cce50504c6369a9b0b45458362c68c382867450ef3abdeb0c0571a9a0552a68280869e338fd73d469d64b5565b532f23fddd6817142492f5595ad0b96710b9705cbb845a7a5b3fdf4c8988cc9988cc9988cd1188dd1188d81d1827c8cda18b53130dad0d0d0500c8c46633d3ddec7fbf4f40c05bd7cfc0f18ada7c7fb789f9e9e97cfcbc7ff80d17878648c5a1a93f3a557ae9518312aa4201e1e1e1e19a356c6a8a531394f3426e7108ed978021a0af22dedf3e29d6fe9955ffd0f4b05d918c30ac0d4cae963634bafde7322c205bea57d30b51be789e4a4564e1b5f7ae50ac23226a78cc9496336d2988d43413886bbde7cb08c5be4c431176b474e6ca3518a77c14629de05dbb875c172622e8b8d5c16dc6ab55aad960eb671c382b08d482ca0de7570d7416201612ce7c9f396e7a1f6a5d25c92beeab5fde870ae7b759de55928ce755d3ff1bc3ce702ea4edf03e1501bc27b4e4070f2c1ab3bb13c8be5594e4c469c66799651f7ae24a1d54a0703ff4adadc734e12f04f5c15ae4a6f692820a48d4b09e9578abff44e1227e4bb95f64f4e10e0da7e9c1c00cbb8e53d271e50ebbd3fc9e9bd3fbde7a40327067828271c38d9e019713a2c8fc549019e130b98088d11c418408c61f4ba9c2293ee9c949c64f01ee79d3cd1e0bde7840019bce704830b6c6e4d095e1d5e8801c5a559b1ae42bde764004e04e05d4942465a48c3326e09406fa98ea800c38fcebb9262407527986042b5fc0a882fcc7cd1c37b5fa4deeb8cbe30418caaf39ce98b0d5e278149deebad9c475363c3a4c966c469cf3b2f4e5e5079efa9ba28828b4ade7bde88d35dbcfce0a29212175eded8820b271654c0b58004003459c451ca220d29ad8d890698a8d18b7acb1799562b9d858f6a8bd7d994d1fddb589b0f5e57d8c0c833d22f23fd4aeaaca8c28a1caca06f654a5a6d96ef3a9dedb95442c5982af478a69c2aa27826dd59c1720aaae2022a287919152e50717aef75df719a6687325390f19e9f628c147494a690e1bd2705258f090f13274c9a5492d990808e6723871404908289993bcc9c31b3849920cc68335a9e190fcc6060e602334e4ca6f79e141b2e2623fdf262545d52aac3940412e44bb5a7506be2b61fa58aaa87423199ecacd5d628e180474a4f1cf25e0d4fdcf0c4abf54495271660a45f167440bcd73921c8ea67394f98c8e2a15ab0ec83aee33a1f46a77a4b2f72a348cd249318e957d1a98eb06509f89678e2bd5722f381572263c82b9101e495c8ecf14a64ec78efd928a1871271e498584a34a1c41825b81242a62b9490f25e29891224d1484e12412471e6bd9c2454495879af171525e1e415959038f31e123d3c1b406cfc40c204244278ef25e0959060f29e491715151d6143e9880a1c61c6883f5ed1df4c454526d37baf8acd214754f0de2beab80c004e1eb5469cd64e6e9cbc26af962a857acf0900de73c2c489cd7ba7f79cd438a101aa92c379ae32d2ac965e45c084085c50c422459c29428ba457a988a32282de7b3108054fe1111a9ab353a90ca136474e188ad3613a4fa3d1e0941ec0c14a9b79ef6daf44c40f0fb552fd297f9bd25bde440411113e44f8bc2831f8d2504c56b09c822c5862cc9931488ce96f0c1421bcbcee575b7fcf6119c350fbe5fcd4aae4540d91c710560c81c410a921a00cf11ce00107ace180d87b6f01423c22040ecfca8f66cae980d803881fa6bcd20f38aff4c306aff44305afe483085ec987425ec9070dbc920f1578251fb878251f9a78251f7a98e082d2f740df03f1168c875a1e3979a83d5d6249f752b1543e429c3782fd6cbefbd0e53d53f7aea4977fa51e60afd4039857ea61f5deab0140f7de4d258a7857921025b17e72c1baff1e68e5b7f679ef060b092691e49f5cdbe673c4b711f496eae89fdebb894404be5b79ed53ae0d12d47b378fbcf76e42f0de8d2316b034c7b3da78c031e53cbe43166f07d77ba61c534b654ada7e1c3ba460cae17c07f3ef3d0e4a3a74d1715957d22187f74c392d980e47251d503a9810c5b4bda0984c2a97ca45430e87bc95dffa2887204c39a6a222d3cb1bd138c901bef712f1ad0dd5a9502d9f7aa1fe86ea2dff26d0002fafe3b2064879ef997a0b07301a41220f468e0041073eb088d1bbf18abcd20f47aff4437fa51ff42bfdf0c22bfde0c22bfdd0057643d10d505e67a93a1d6c30d371190e251b4c78ef3120a7d6d080d7715977930822ef7534ec714869062f7c06134a28c97006ecab610815604a3258792724760c630c5208218308f2de4d2080fce1471fefddf0b1c77b377a78e0ad3caaeb780bf63bbfdafad563fdb4430e491dc8e37b203ceee0802b49c80e7f5307b7719ca6574343433a48ce939c3c9e5a9ea1216a79e4e4190aa2762848ced35010b543a7a15310b54341276a4f2ecd7191f314d358a8e569a9b050cbc3c3c3432db5d4524b2d8f51b775a8e56919a9ba24d7b623274f4c639193a7a5c222270f0f0f0fcf8b03132427cfabf39c969387dbb6158f9c3c2b95df9193c7a8db3a72f270af6df5da82b8552a88da13b775a1f6c465a1f6d45b3ad49e86a83d0d514b2db5d4527b12f3daa1f62466b543ed897b6dabd716c4ad5241729eb8ad8b9c272e8b9ca7ded291f33414c4f240729e8682c2a8acc8795ac1b0c879dab020394fbdebc8797ab5b86bd322e749cc6b47ce9398d58e9c27df432d8ff7a196e7d5432dcfcb875a1eff432d0f188d5a1edf23278ff79193e7d52327cfcb474e1eff23270f184d4e9e21dfd3e37dbc4f4f0fb5a7a1a0970fb527ff43ed490c188ddad390efe9f13edea7a747ced350d0cb47ce93ff91f324068c26e7e9bd9b0d7c0fa4013a780bc6f33d906be3acb06ee648726d3b41be67b552f1206d5c8f5f6dedda382b72bc54ad53926bdb59ad543c481bd7e3c5a882e4c436e2130f0fb527394f4372ca69e350101eb2d1c6a1207ce2e1e97af3a1f6f4de4d06bade7ce43cbd7c90ef09726d9c9538e0c0c0cd055a43efdd9ce1aa88f13fffc455110346fb27aeca7b376f7055bc177af9a0f76edc78f99e8db3e2f27e85f76e2cf0b27818cf11df565562fd14eba7581792935a9ef76eda78ef868d352c71f500c8eaf5d1a5b80f3633a61c4f80adc894b35ac17ebe57c08d1a6990d06ae4216dad28ad2457cca35eaa56f79ec3ba0abc77430134debb39c38cf76eca98c07b37646c30c67b376284f1de0d185fbc7723811b2fba78ef868b2ddebbd1228bf76eb0b8b9c28af76eaaa0e2bd9b29a478efc6cc4d1450bc77f34499f76e9c884013efdd304166af36781d975139a2e3bd3782a32b474c9e29e79b29c1d0c32bc1a02527c7e4f2fee8bd9b256e94706d5c7779bf826be3ac5479ef039d92ca86be71ff4ada2f554b85ea5459aa8a246e9000802347dc181181f76afc7842c434aba56279579250ac9f8278ef0688f76e847ed8b940c9c84a0aa56f474cb35837fcbe22faf25b609262cae956f069409f7a8fa60025afc1bba49f494410de536f8d28fa050f0986175a10e25e58d88774b1abf05cbb3a7fc3bef2de9ba1a4c7684b9e90ae0085e45b45a5a22e1678657c514483aaa4ffa0c878ef3d125029a02c08838a570aa3cc2b8541e695c248e295c230e295c280c02b853186894d0d1f9a4eea85b4713defddf4c043925fe14bd0cd0e3ac07278efa601177857d26bc382fc6a6b1c6eb0e1bd27c45b309ef76e6aa0e1bd7733830c3731bc9ba21a40925eefdd8879b5bc2b4988d35b5e4937b19b30efdd2085b91182bd07820b48bc8ecba8fc95f762548d945c607285a80a221a88561d977a4da9efe94eafbc77c1520b33745c86726dae521720561ec68365e56f841ef7ea5aa739b8e461cae1b61a0ab87c51e2d2c31866b898f08018e195b65412c416301ab0a5b48584d2960d1e20a5a12cc60ca54c524c27e44c31642a0d958698bcf74c49bb07213adee391814c8f4b28f584e833e514156529059d41a51484c483a5200bdee3501dd00780ba784f4a4e2176d0500272f2ea5aaa120b8aa89e152c74794fb73ca75139efddbc3a0e8c6b6bb16e563747efc6bf9bce3d4bffbc77c37323b4df8b75fdd256bc94b22061e2b6bf258b96f7b494b25c4073fa89e3bd67e2b69fd19040a3009a0f2259e48f0dcc81658f0060e9a284658b1296d57bef4b96b9d0e5ac0291442bf9e4f03a2e3bbd920f7c53c09456e8f414114a2b78e9b86c05fa9e29a7e3b4eb63a102185a0fde82f1c4fac9b754abcdc5d29c50ac9ff8cd97573ad1d182fdd2298b77e3c505a29b166e84ba9c70dee9f9d2153bde7b45595117fd4a101bd699f88fc12baef762d094e3fbc65d9b29e9a5e274a9278f528f95520f941a0a6c79ef66a8f3463ad64f49dc7623c4e4c53ae0e9426d02782c78afd35c4c450a58c04dd0142d7503f49e504e4e57c9c9ea34d27b36615881b2b3c87b9deacbce8a8552953698eca0bd52155c64034649e78ff74c39bd05dbbec8c46dff121d234a3a449474841ecbe350d2b1e0bd67ca79713e0ccd512905328a90b6d56721059a820152b0e03d93cbfb235c6280074a0ca8428a2965caa1b9eff9d5d67a9418a0575b4b96f79eeff40680564281cc7ba6d27b4c986042020a26cf914a2764f19eefe9a5134ce036249b134c80e43d530eea921b154eef9930e56d699450c4eb5b0aa512a0bc0e72ceb4609fa6494e12395d7414a57cc87b9c3e2ae51c1e942ef982126ea484bb30e544819253b27b94ec0813d894c624e095c66cf04a633478a53118bcd21801bcd2980a5e698c935225f3de7ba5eaa566826a2a550dde33d22f5a08cde3bdb7caa92921f1de4bf196e6b62987c6ac603905d12befbd2925cae4bd97f4d2a579e6bdf73dc737a3966a22519a363c93d02b4d9c29af15acfb2ad7b6ad4c523a094949a621c7bcf7e4248104693ac1849c928c49914032e71df1cda4afe85a9baa3319b55456b09c824c5cca6405cb29a85ba104ffa0026306a7f457b7b5a6b03a8d04cdbc2925985aad602d54a72a419a039b5091c494632a51f9e3bd57a252e615bd7c9715e5c0a8acdecb2951b9f2a8704085c9cb61f9952f6583bcf74ca52c8dd73b53290be23dcebb322fbc9449796fb582b5b25f9a32659197539ad2c67baf057bef4179a5294594a65cf9a5294e8a4c3a0769e3522fcf95a4c4f15c545e494a11af5b69cec8bf5aaace945392e2e5bd9214292f897bf19294f78abeaac8d4d2ddca37216401170060899b1340f0011a0fa04173468904285f4ca0608f26514a517ca240294581c23d1e7a687835f400a5974618e4a684d208f439d104191eaee870e5c5a9aaa44a9026114c2dbf6af9552d89404798774224903c2d1e1731893143bc2d5a1e034a38666e72b27fa938a4ae3df7de0dbeefddd89b2ac394702a28856049298445a2987272a08420c6d561d84bbfb8dfd2a95c3a9dcaa5572e96cad58180e509216d3b3d0f85d20766bcbf6d9c90299228504c423753de8d94f77efea672e99c9c7864ab74718fa2b104010178e7dbb18e98c71a2034582dae9f53af23fc72eed48d2dbf426d2d548e1585c2f18708c553f383066df7f0ebf967d41df6deda32cfd2dcff214281a9f1c1f648b9ddf6ca3977d59a0708474e2f353dd4892f855bff8c2feefff28061c5f65a78258db046cb7fee70c36c3d957eea9a1d342c3dc6d15658e98457effa438462a14607cd6f5ff79491cbbd7fc739681ede2fa3ddb3537f6fbf5a08d63440ab594b3d39e6f84b3d21adc1418b5beecd7bad94dbdae1a7a79a1bb47afbafb2d30bf1a7d5fa1a1b340e7fcd13d72b6709b439b5cc7b7e1afdaef642a14b34fe7df772cabab1ae9cd7d48d937bb92cd12c9dd1dafa3bdddb6f6e2bd128cfb55edda1acf15a3929d1ece5bacf9fefbfb1f7e9b38c049acdf25a0fe7de3adbdefd249aac5fc66cf3add54b1a75fd214205d148a2f5bf7bef7ddf5e79af1ca7ae16ca32cbbd5c23b8d9529b71ad955e1c618438c689bf9c1d6bbeebef2dd50a3491681bcead71a47cd7f9a917816629ced15eee7be534eaaa85b22ccb8c74a7814483f667aaa39c59e3cfe97f44dbddd2fcfb8f5ccfee6508b4a9b3ff7c4a8effcf1beed48d11e5f2afce3aa2752df58d596ac8a1ac50a76e04e3512f5e71847a70c0689ea5127ab5749665996d44e3d3f65a73cf10f739f7e6b6af6ac170e442c3c89c92ca9b3396325b1bb7ccd956dea186d3f3d48ddc1646af3e0ab55a792b633420d036d550e77ef39f17d699e907341aafb43bf69cb587f66adf21d04e8edbebe5b957a7e2f2221aae7dd3a97d979a772f79d7f92142b56814d126eddf4fb9f99eddf70f5337f6aea796655de73452f7af966ad3d2adbceac787d9382d59d6bb4eec50325a4293489537420ce3c4514e3ca1c4305a7b31a6fee20e6597d622a26d3923855bde1c31ed9f1fa2718affecbed32ff5cd3a622d348668b34b79fd973347ec7fc5a91b8fb87665199465f4727aa579676fa02944ab77df8d33d6f8e28b378491104df64a2ddef852e8e1963d75a3916f19f99f0c81a01944fbfffffefda636d21937acdbb02041b499b1dede5a1dfbec76fed48d4712697355229a40343d7395b356796fb47af7d48d2b186b0af5ac6058b28ce23b6800a1f8e24a6f95f0622cf39d386aad3f845062db67ff32c640f38726bfb47b578be5edb57e9dba5185e2c07432cbb24c4e5896655996619a31347e68536e8e23e714e6ff3dbca91bbb4ee32aadb472c266677bcb1f71bdef915fe9eec370306e631fdaefdec3597f9fb272fb31aae55737a2925c1baf1147a8274b4fc38746fbe717cf08259e375a9ff7d026cf946e1c71e45e6218f5d0aef794e2ac27cdd457f8519d07b43ce1c65572eca3f7f4c2d48d550a4d07343ff9d7b1d2f8fdf4f1efde5221b5605b0b85630e4d1e5aac15d3a8f7e5dcc2dbab514b7594f1d0b8ddb646afabc5b76b08b79f2ce336549661313477687dde2ea7a4df4ebe6dbca91bb1e45e2e146838a0ed6ee1b75ce7ac6b8e96e56b9451051a3bb42c71cf756eda6bf5f9c33ab45cbf873cc6ba319ffa579a0d68da7e5879a593731879d5a91bab06b43ebfce92cbcd39debfcbd48d49fe68ba34164c07863453186bbd7366692b85f0d77fe7a5fd7f4f254fdd58e7d0bcc61073a821d475d2bdfdca0513827268d5f64aef95f2ce59bbcea95b8362c42fd6cf80b621a67f530b35cfb37eada28943933e5329fd8d3bc3d9697cb974d7e95a4b86ed0f11ca88060ead477da5edde6ebab7f777460c68f47798f1e6f5f78ba7fc336ef6029aa4f3db9cbf94be67bef10ace331ac7526f1f65ae996f4c77ea46144acad5ca73fa86a6f7b498e6effbce1afe3bbdd0b8a1fde8e5861bf7ac73e6726759e6391a0b6819c2ec69f411e7daede6346d685f4368379d36dafa39bc6c6874caaabd8c5547e9efd76b685cdafc61af76da7eeb9ed4fe10a1bed0a8a1fde77e43be7985b3d64f9346ecb1ea98bbbe377f1c25124d0534ff33fc96475be1a778cfa12cb314d0b68cbfc6adadd554e33f298e500fce29cbbaa3162cb583ff6b28cbb28c7b7517ff10a16034686875da2d23e7da46be29fe32059a33346bfdf674cadd61ff19f696a766685aca2a3be7d35b2f3b8d2dbf42c95aadd09441efac17629a6bc450565aa9de3a5ee9af9f7356fcbd18550793dccb354433018dfed9bdedbc62c9fdb4347563126d81860cad67fee5ae1deffd2f9cd78ea1d5d9fbb4d34f58b1ccd7b5a172ac34626818528963d4df77b8add7a817d7380c0d43dde3e75eff3af5a57f7b5530349c299cd9f7287de73cef1b4ba0f94283b0dfea2bbc11ee6d6f4edd88ea54324a60cf3d71b6166689bdaeae7c69bcc0534e1ae1ac94da38ebb513c72f23e75c7a7c799dd8a76e5cad34cf9eb7b2b4782cee5c9b104d171a9cd56a0937f4f56e5a398c0bcdd648319616e60b318554b585d66fb41f466d3dfd99efaa856663f63cc38eefa515c7b869b2d0e2d758df5b6fae98ceec6375b15453d3607161ad19cb7cefbdf8e23cabcc73c66d67d65762b967ea466aaf8ba59a57683056adf7fe98efefb1975668ddc20b6b9c744faa23ad3556a1d92defcddfcb1a7f9e10a76e84315b7c59b056151a2a342fbddd9ededb6bf6f06a16ac05ef0f118ad34ca1cd9aabe45fe7ed319619a272a591429b77ffcd67a654c37fbb4edd68a3a431a3c59f6becfadf9829bcdea66eccdd0b73af2e0a2dcbb9bbce70ea4d6bd6385a807070b4f8e0e0f000e14ceee5daa18142bbf7cafced8edbd23c917c6b723e887b05c5d8e2fceba55d977b754f6872661bfbfc53ea1fed9edb6f9db8aaa5b564d9f65b2ad4fd21427d9a321a9458768a2db453636c65eac67e5b3a5996d4d2d3094dde1ee7a4dee78aef86d4fe229a26b47afdfc72769ef5b6facad48da8158c05a309344c6874ffce6d8cb852bc3595a91b25d2e642ad602c0c694c4e2355156c59b056a621a3c16ca18ffcfece7df5ddd6697cb5601bafdcabb3344b683d535de7ad1cf64fe3ab935309cdcb18e1c41372ce716e6d2bcdda5ea82c6b12dae65ceb18a9c4dd773e69ac9f8c5a1a28cbbc514b7359d6b9b6787f88509d0609ad7b2bb3f4b0ff7b6dd7f4447384f637c5537fc96bce7d5f2334db6797d86ffb69f630fa0868bdfefe63c71fda7d67a54568bbc39febbeb64bccf79f3410d07aafba5efaf7bff5db497f885040340fd0e08efa7fad2d94587a4989d078d59f6e6cbffe77f3e9752a8ed13aed50d789ef8573c70e5fdd105aff7bcf4ce5b4fa6ef9f5b6ed2b340ed07297d1775ef3fcf8cb7fa5109ad55ac6dfed8f5c7a1867d56882d02efd9ac748f59539cbdc2910daf7bb5f4a23e4bdf6ade9fc41d3b84e8df5cf3bc3783f943e6899e36eb5a49c4ad83f2af695577d14caca1eb49bf39ed746482bf65df628756878d032bffac6bafbde5c6abd5337a2ba7fa1ba76e5c8009a1d34093dbd596239299f96e3d48d5dbb6646a383e6f98eb6c34dabefd25b9fba51f2d0e4a079aba787fafe1ee5c4a8ae5d32629a0668b3fb4dadbcb25359eb876d944b734898f3af3c6970d0aece564f4ce7ecf37bff53375605d0dca0655bad8c7e5efe79ae1beaa072fd214275a1b141dbd1ffa823df72cabd2d4cddf88a79ab53b2eb5beae55997d3294e836aa852d21b63c4f9624aafac97d2a9abbc5acf5bafb5a91b5b491d8707082753eee55ad1a0511f29bdb16be9338758caa99aa819346be3c5b872ede98ddc5b1b274a06cd4299abc57ee22f2dd4317f85f3489b8fac2fc4a04dfa35a7b346ad259470422f62a485fae75969ff18df9dba11cb0843bd581ff72469de6f9cf9cddbc3cbfbce5846d8f671a084ad5c2cd5aca818a670e67b73c6d45618ada530520d7fc6bafadca7bed4c2502fd6ff41d2a48e94f679e7fdd7e3fbc3689dd6a9abad717f18fddf302dff9a73a551ebcff5dcfaa561fe25a537d3ac7df41da76ea491056bc14edb34ff1fb7b71b4a8ea585f68708d502a7c5dd7fc4dfc2ebeba730a66ee45eb8e39c0eed38a769fe21425130dad57ce37c29acf05368f7092e2dc2acb5dc774a08bd8e3ccbba6a43bdbad6667f8850a88d42082b8cd3da4c6f9db062fc2fff7ddbdf21e4b6d2ddd2748eb9f77e75a43fdedf595ab758d7a871f6d8ce0e61cf4acb3452f8f78c9ed79c3ff459767f8850aa234dce3a29e6747eb9fbee31756377a4bd0bf5f246d9a250a87dc4abfc2142edc0c029ad7bce19abd65d6aafd27efff97a0f25c478ebfc65aae72b75ac11734fefb7960708c7aa8c26ced74e0aa78cb6562c27b453cafa79fc7ee2bfe3bc455fa37c5e1c77add64bda37b76d1d828f3cfe8efdfebef7eca30a9d578d77a770fefdaff43275e3e415df19e9c5b7de6b2d9591e67ca9cebc624fe7a5becbb8c2d6708f537328fd84dbeeab7bdf72c45acbbfd77b79e6766a0e3f4fddd8b79c22ad77efa98f9ed2edbbc4b2f70d66943679b59243cfeff674ce0cf30b9a9eb3fe58e5c6546bdb7deac6958ba542e1fb45e31c6eadbdf478d33af796b2042f1a8d5efeab35c5de43ed63aabbd6054d7a5b37acdcfe6c7ba5bfe5c3f88db571ae28738834ca37e65a53faefd713c3d48dae8deb11b6a079dce1b5724aaca58c72a6b6d7945d349c65ffda7aab6dc5fbf2d48dbeb5ad384ac6fa43848a5cb41979953866aa3dac7873d9a2cd8e23a45f62be6feeb16719aeddb6f587083534a45daeabd67efe3c6bdf3ea66edc5e2d152a468b6bb78534387f941c7a59a3d4f1dbd48dd873db0ea7b76c49a3fd2142dd208d7f1b2d95ddeb782d95337563aa83b950dcf66df4018ab6461c238e37e63aedb475ee6b63cc1d66bd2bf6943342451634b87f9f3de6ba23e5fed6d48da8ad47799134506e418b1623f5d3fe186facfea36ebc388b96afee52ea09afd590f2fce2700a3f1aad36ff2a2786f5629a7dea468fe3c58221b413c72827b699c65aabbd15fa89b5b5ff47aa7ff4c9b22c9b957bb95c3e1a9d315e59e78c3edb2ef30a2815be9c346c31861fdf6ead9dd5c3d48d495db7ad6ab4d6842bac6d43ad3a87424dd0e3c343319f53eecafd9479a62e86e1f000e1c82d9ac627aed866bb6b84b4d7fa627d68459bd0e7d8ebdedfc3df31c7e915862384b32b0c87fe10a1b0ec68dd7a0d2794d6daee61f73d55e0bcb8c61b6994b6563ba395b8c28c03ae8dd3d261f963a348bf5cf7fb2dff2f6f344fa89efc438492c126118de78ceff454fe69fbe63ce9ab5e55e208f5e06459b44144d332e32ab7d6bbfebf3d4eddc86d1f75c435b723e493655db539449bff665829f5782753fdd606d32e540c670707c370847c70b22ccb70b4643121f9868d21daae3cde0db7a653ebd9d178f2617e9232942bcb9278966599f73ca9978acb4a7b2bd026109b42b479eb8fd9f74f7dedda7f42349927d4d25e3ebb8e91fb4134eda3de5272093fc7767741349d299cd17b6b3de774f740b4bf2ded59db7bb584ff764034bfe9dd946bdebfe7f0f33f341dbfe4bc42abbf1f9aa6955acca1a475e76c791f1acd935eef29d65c5aed371fdaf75debf9efedba4a5bf71edabd9eeacb31fc5a0f8d5efa39b4bcefaaefc7da035ad598ea6975a4b55fbf7307b4baf3d45c474db9873fe63c347debf7714fda33def0633c34fbbfd4b47aac73fdfddf3b345c6fc414ce6869d5f05f0e6812e76b6bef7fe36d79b676689b523feb8651564bf1af7568dd53f8f99e98eabe3da71bd0f4af737248fbc793c74b35a07d3af794dcf63821bd95d2a15988f7f753cb2e2fad7ecea1599875ecbb47ece5d0b2bc77ceeca58e10de2c33a0d19973c53c77dced9d390ecde31befe532db08879677df7b4b0b778e105b88eaaa17a30ae28223e483936518d0249691661eb7949ff2ca2fa0e51d27a6dee25833955b9fd1b4ac356aeda9ac3bd32fa9cd1b34567cefdedd5a2cbf7db57c980ac6c60dcd4a1ceff4f4efecb9b6d2029af53bc6fda38d98467bdbd0a0ce705a5b37bdb857b8a90d366c683ed23bfdfdb77b7e67c76b68f5427aa1e4dbfa3aefe6b1ad4a96751fdb36be6a6895d67a7dfef05b49bfa5f5069b34b40aefd4bbd2ce23e7334249834d05345937b5174bc8edbc1f569c830d05b4f8ab84197b5c3df513f6db001b34b44b2fbc34fe09e7febce333344e3bfebc5728bf95f6eaac838d191abff94e1e63c4f3475ef1ebb7cad0ae9ed557f8a9d6bb433c012d477a6bd414cf1fa184930c0d6f4be9ad915f3cffbcb973a95e636853db98b98f565eff63e662685fc6eb3db7b7eebeafcc61685b4f7e6d9638c77ab98c6068dfeefc67ec9b5388a7c55f68957a3e29f5f0cb0dadff12d03ea47b539be78ebec24a8dc278a1dd0dbde4955f3867debd0b2de76833edbc7f5c3b9c9a0bcd57ebabfe13e2192dac770b0d620a778cdb7acabbfc7debb04e0b6d7fae7d945dfabbed853c0baddb9b27dc3e43bdbfbc170b8dde99a5cd76e62bb9bff90a2dc2a969c755578d29ad3de3606385d629d533f71fe7e518c379abd0beb772f7786d94be4a6a93bef754687be7aab78653de996bb09942c3b04efaebbffbc32b65b4311b29b4dfafacba66ffbf19edd20ca9fe55df0fa5cc77eb2d5f3651685f66ee27b776779be3de1523d940a16df83daf39d68ffd9d5c6298cd13d6778a23d479fe5f794fddb8b36c2a6253a6e21fbdee1657cf2fb778eb59967d54ef3acb549a139270d62462e344857dd24e77a451c3bbe259c6dab89f6538423d38f01662d384a6ebc4decf19affdb342cb8497b3deaefbee774b1b329af5d1ce9a3dec525aae6bf461ec13364b687f724ba7ccbbf72971fd522ba1f52ee397117f8e39deb496b149428b94c778318c92ca3ea58c3b5232618384f6f1d53e731ebbc790d35a896c8ed0b4cc1a5a8d75cef9ca5e5337cbb20c461b23e8f4fb479d77ef556ebc23e0ebce30c6fa2dbf5717a165d9ff9f5e629c71b4dca76e5ca978b2cc0a1b08443be787b85acaeb0338ee977b3f39aef6cb2989a03af64d6bf639739c694cdd88d32f0c87a54a7559189c7d613890763663fec53dca5a39a6f6c2582f1896164f65c166086aebcd95e21bafbd93563cb1ff5cdb29edf45dfbc97feac6d54a73dae2912ad83840cb30cbdba5949ff70f7b1542f3f1c67cf3ee3bce9f2fcc32dfb3cc77ce77364168bfc2cffdd431ffe9edfda91b2b0442f316560921861b7e992f4edd58658cf387081564f383b637f6d4d3dcf7ed915ee983866dc7f6f6cbafd45c72a8844d0f9a95b2de7fa39c39cff863eac6d963c383a6b1fd504f8aa9bf777b9fbad166d90f112ac966078d530ea58ef67edbc968a38356f9ee7d4bed6f859ec69d83a6bbaf5e7b4939d71b5f6bc56a360dd02eae78dbeb35a770da1a2f123638681cc31e67ffb4ca69577ac75b41c57c84cd0d5aff7feb083dfe555f8c69ea0eb5b2c8d85b30546b9b31c3606383cc34e339698c53c269219e35f6bf6bacbb6a3a39ed3875a30b856d0934fb21dc7147bf71dd577a301de5913a35976099f1b4124a2a2d8d95c2bbe3ff1fc35c3ffd51df6b890669d4fae6fbbdaefcf6bfbdec26142bd12e9f5c52dfe1ad30d759533776d6c6f150a2496df9c7376338b3e791a76e0cb29265198aab5e2ed56ae575b2ccb754ffeb1c99a8218186b9e6d44f5b3fa5d87698ba38aeb64e5afd2cb3551e4da2c50b61ed9dfabef587b5a66eb443359268b57bcc35bd9b43ade98f403523d0b0d739636ebd9cbdcf8df362708c44c3d87248e3ed7557da59dcd6ca5d6a44a0c1bfaf977bdf9ba1c7fe6e2f0c89e669c55bf68eb3fdf4ef9aba51de68650c46548c30da2a8fe8235aa63b5229b9fc3cc7aa43a0e939ffb5f5daec7995343ba2f98c3f96144a0bb5bed037a2d91a278e31fe4b6785b333a2f93bebe4fef22a6f8699824093917bfa2bd5726bece9fc00bcd8427c27b658caef67cef7c3ed7fa7d8cb45b4bb3fa4b8c66d3dd791da8a15d1fcfe9a5e8b3b4c44abd167a8bfec9df6fe637f400d22dadf515a4af9863547d963999a43b41a7195bbeb0a7df751c67a7f8850a91a43b43d65bc996e3b65d7d26f8ca271404d219a949b4bccbbdc7ffef8752a4b42b49a2bf792db6d6d9f52ded48db893d1ca41e49432e64871b6d4568a7185b0ea5b659fdaf3ad27ccb2ac722f578d209a8656e7af29855f76fe7f205ac797ef1967c71153bf2120dacd7e730db3bf7bfb9cf5c53fd4fca1f5ad3dc77dc73be9a6ba66d94545197f885049357e68135e1f6dfddf7eeff7c67d687ddbc9759ff7e7feb5cfb2286af8d030aff4ee8bb7e494675b6dde43fb916268b3bc93defdedd4439b7477af738ed5436c2df68016b1c59f62bdb9fd7dda888a1dd0e8a6947e2971e516730db32c83111579a762513bf3d068969d7f7fadf41ffbaf390debe17c92f659691b6af0d0769e18c3f9e3c4f2d66a5337a2ac8f4e952c3e3df615f336dea175a9aff49ec628b99d34c6349d202b3b5a96e9ae739f65626a38a0458f69ff557358f9dc17daa1754ffd9fdfee6e7d9db97b8ee208f5b85aa72cab4346b8fb9edaf2882dcbbf542823d59ef10573c51837f061ecf4432be9f4d3c6d48d351a80564a7829ad16df7e75a5316249afd4fdf71a3ab48ae3a5f1c319e1bc54ce9f3d2f0d357368b14618f59cd2f64af3cb1bd188af1c39464d75adfcc74e2de56a32802da4965e3b2f8d554e2c6deef046f873ac77ef9f69eac6984fc99ca4394ec7188746abfc3bfb28a9e5fa730b8796b3cf1f5b28edb7577f8e01edf74e21fc37eb0823ccf6021ac6d8573de3d5f6c6ade5992a33b433cb2a238c58ca9a6de71cd6de6795dbde4bed0a356f68d9de2da7ad5d520a71d76e6897db0f7fe6326a9a23cea92be483d3dd58add45840f3de5a2c65b732426d37c5b60dad6799abecb273eff5d659e6246ad8d0bea79ada4c7b9d58ce9971046ad6d07a8fdad69eed85985f4cb311356a6856eb7ff3bf3dc2dc6fbfa91bb7dfea92b4962ccb328c8a78a6a1d9dc61effdfece33c5d75680de1a33b6994249619ef75abb2d9d57776c6db4d1efd48ddc77937bb96a28a0e1b867fcfd5ef93fa6b8a66e445559838656bf861773afbbe4fdff9bba11c617b775b4e60c8dfe492784335e59f9d732a362113566683d4a2f6d977dcacf39a5a91bad65404d195afd5cfa5c779410eaf92fcaa5593726617ca566029abd9b7bd827bc7cfafb7367935e128a1a32b4a8a3e67dc7c8b7d578cf2c7b71ed62d1206ac6d0f8e59adf1c638e77da49c5d070855e66bd25ac77f2195f3561681cc6bf73ecf15f0a77cf6068f856b8abac556f0963af5f683f4b5e6fe7dcd6fba3a512d0b0af5d5bc9a78cbb423cbdd028f7f2c308bd8ef1dfbeda3e0fce0ecea9d35d683fc7ff278f3fce7f6fe4b25e51c38576adb6fade7f39d79c575feb161af633f62c3b9fdbcaeaa1165a97db42d975ecb17f2c71eac6574b95aab566a1e52e65deb15bfc39b7b9522d6ab0d076bcdc4fea7da499722bafd0ba96585f5931de5fc369277ca2c60a2d565f7b8f7542efbfbfbd56a165ea7f8713dfd83b8e11c328440d159abc18e6aab1ddf3665c79ad5368ff6bfdf9bf747b68b3dda91b51dbaba59adbab75cab20ce2502385062395b57f6833e717ff4ae3161ce94e8d19ad43f921cd19dfae71ac390aad464b3feef9e7fbbdc73b28cb28a55068df72dbb98d54e22badcc2a974ead5dd43ca14d9861a4d576afa5bf93673486c9b2185191c630738b9a32dafcd5c7be71b47377db2d04c2d9c1812ce068f1c1b92b174b65699aa87142bb507bbc39dc52469a2b3e5ac176e6b27ced7d767670ba6f2165c932ee7b20dfb79fec461b494d13dad635566abbcd30fb5d65ce354c6897c21be1dd7bd2f871e7a70ce58275df67153564349fffefd2cb6fb7a4d55e219fb8c4af35c38f2be6b363cfa9514b95d461dc5ead53952ecd9a3546588d121a87be4a5e65dc1bfb89b12b49484b966554e436172653938426e9a49c5b69ebe63c76ba25cb2a8ca878935e728a1a24b43dbbf7f0c73bb58ff36aef4a12cab2a45796c1888a492f895aa2e6087b259e74d66a71cdf6ca3a739f35f68979d732528ca5a8314293be77ab63b5dc63edabd7b22ccbb6e0ece0ac8023e48393652ecdcab22cbb70889a0868b2560d31bc53fac92bb4a91b591bf7bbd7926591462b6a8ad076dfb94f8f35def7c30cf30f118a46871a0868d1764c29bdf8fbba23dc0fd0f89f1ec2dd25f6b0c66e89d078dd306ead2bec98635c5d1b6725cb5c1bd77bcd184d7a8db3adbbebda7bd57c082d7f0af7c713425c71ccdb015ab4145f7ab7a7d5ee8f67eac67ce2fc8b7b5750966118398a268b1a21b4a87be67bf338e9d792ca9a202a85d0de8ca3c576de79b9ce019ecfa8e4b06a969918a4903184104090863400340013130040502c208e06c3f180a20b8af7011400045b8c6a9e42970aa5f1688ee32808828c32c400000801c000048c71a68805eaec43c9e0c6228abdcc306d12e8ef59889c6a2bb9538ea2ac0ec105fdc688a82539fecb957486b6f56afa4ae7ba7925320251b09540c9248128398e5402ee9f752b618a386237ff88c901258826c525180d4442592748bafd99e5a4a1cae09051719983d8b4f088801ee7a23f1493a1efab325126ea8926d6e6f541af6923e7ad38516708f5c85d5360de84a3da15959fe481f308b4cc0e6c4fe44d943b5e11c224a5bff1509936b9de7875e0a59b1769f0fbe7badb259eb556d399739805cfef632fafd509503cd0517254bb4906eb6107c81dbd6ee402fd68ae5281abbbfb052fc25d5c2bf35ec402f3218b8ac51ae6c7f3134ceaad11d886fc95cfb23d6e4f75a41a8de3a03113e3ba0bbed9dccb73eadf7040e7412bde75ef81de9e37e41db7d19b90acd8c5768feef1a089a73a7eb71e80ba193d2e6fbd7945075eb7f57227eff4f1d089271af77e5b0f77f2a48f779d7884c6fd1eedb076e0ee113b7cf316787825dc25821dde8180403b9d583440b4b036630df90a34ab8959b8940f458ba9afb8c669ca2b80142a3ce08081444550bd2c7e72d719875f04358cb3663bc49b8bf565a7d032174e491b6b956a168ff4788e11d17236c018cafff9037e4597455fe6fb002625bcb7e362140cf265d7d247d67b193ece67fc2f505221a85aca0e6fa9b787778f3ada851142640e8e4c90b683226693656e423c681ca8358a8642fcbdf8c0ead9c8af7466d48ad7d152443bb38c7a793814f129efa165070d15649b814a6283693d0a421489fca3f4b29be613cfb73e99b58fb941718e77f8cc3a36fb945093b969a1db043d14f565f97599b5886deda4d1ef7178ff1a49964fa36d27664dc334c7213ab38f557093d572af1dbc21eb183fd6d8bacf54715853094f7979c3ad19b32c92dd4bb1af18a595f921cacd2cbb3a6b569d557d9abca4f49761d22c937a9d23c1979eb19c085539b88d1ffa02d46f77f29c11fe3d12181727643465cbdd9df7d3e138b12e1b67bc76744627deef59ed81cb502b027f771ef6e3f3e57ee21153bd950ed57ed3a3aae4bb2b1df9929aaec509dcf95999979e6a760b0de69c917b3af714a1563e68d6ca06c155feb81c4ee4ccf5a4d59c1507907f34651be54941c1ca5f05e50e0ff59a653310755c051d2adb40ff7d22654bea0b917e1db6cec6de2da9166a0363afd9c4d156791ee9c4af0ddf8073e20ef9ee00dab67dbbfcc6f77a50630064ea4bc25b92038c6db218c52c2d8408e39c6c49278d47b6171ca29e43ed22ef7bf117c5dfb8fc341eb614971c52056d3457d19d9c36b508368a2c01859fddd73dc2d1106485537fca40ea7e4cf9fb741fc11b8b5d32240d1180f855c950dc8e8f1672b0950ef33671be40e4153901572f7d4c172adbe1993894edceac2231be209630246af4ba6575b3769b363dc82c3d408e53232c4454d8e4c993902ea7ff2821d9e8cb3e61ff54d1fb21dfa098afd91e6e3a3aec982eb0767bab9c0dc443e6d81ce2cc7bc43b1d35ae45320759348489f9bc89152cf1a8d905989983f172b0de93a7abb07b88b732493be2b678dc40b65c9303d01fbd9a89c02c5e500d978c824c2f18b83dcb58f16486d21b8f5e1a5f95bad2ac031e0d9b21d509a05cf9d09ad4051e1cc1473e8bd84c403fe7293b06f94543551363f410ae5ed52afaee565ffbb40633922bae1d5459424e6fca79a1351da356a3d1b5e422b9e7afdcd0936b2d39f75e4f18bc333d0853bb359ffd3d83607a6bb2e9f4d0029cfe0f1ad56a27dd23b347b1dd0f1e905dcd9fbbb7e4f223d4023641a3564aa922c4b744e42e110890113cf410f628874fdb2ecd85d3c404e8c7287a2ceb1e06bce7b8954b57fab6e084497e997aae33bd0ed273344aebbceac3721534319cd4e3b5e9e44e2e4d89194162207444723e585300f0861749769790199800d72bcc5b7b9fd71e56afa4fff57f2df3d32100f73b5665c1dfb781e2843cd01192f58df43229f07ed3b436993be710da416cd82fb6fcdd6f0988201d0028c87fe0033986cf229645f133fe39cc9b1d1b722f925c3beaaf765930a54eebdbe770430ac184d1143ea4bf332ec63bd1aaf1ab33557ff202ba4e398db68c00c77851d245135d1a2360808088838dc509a6ecb2297b1c929c2112471be2e26e6e4bd93821aca05e7506a5c6fbe5346a7c667264ab37c7088025e96e79d77d31f281d1b1529b857991f3b4a2ce11b12c0df0412f24659ed21dfe66524684a990d0276962c9a929e634ee100bafdd220291a573fe8c018504bbe0fa5a0600940d0b3b3945af142d36714189f047e36361567adb16afb345f99da96ff8dc38eb4fc35effaeb24a4f12efcbceddce2ee47dde7127c50c78e1eb2f90aad30722e794f30ab6be2da823fcec9ac5c062018e486583047e341c1af52bc79e01b321c0a3d0573434597231f3e0b48cac5d75193ac6a88600722d2af1d60b3af242c8ee583ea847110058825e89eaad02540740f1c7df76d95a8d54d31db256a627aa1ff02823800be0e61caa858da30ce90587f3ccfb5b36c54bff9ac114bea021ac1a10c83cfb600dadfac8ec8ab50250db370d1738ec72dffdb31e68b2d308bf5b87e51030ef448d5f7216d9a47d7aef462cd04e1d0f80f855a496398aa8e41236cf620f24415a81e4dc40df3241887649122ac7fb7e9ea64d7f89019256dcb78611c004bf61cf00a1d0cb602b05bda516b9c3b261a6b950522f4240ec0ab91ba60ca4f5dcda07f3a514628e3d3c32f288c57e9ff6a4e9073e1bbe097955f0420445f1030dfd60a7ecee9ceff6a47147722169461b39ab8fa0315581c0bb48748fb89194f7b47526b1a9cd15f1968d849717a9ce6e515a72f67920645b5d2e16723e948e05baf0ee11163a10573075cd752f4dd982364743b01991b35ef7ed151e3bde7bdaa1444289321f25d81004cb41aadb07ba7e798ed8ba31afdfb5009543e0ae2e3c6109a1279204ba032bf3adaec1fcc0221174f3dc0243e465909514730fd9ae64528713653a5ab205a2f5fdecebf104be9b5930ab463b0a466c14178e0b5f54ed841830d301d12a91e35db70346e41a371eebe750c1a2bdcddc919a9da76a0a02b39625aac2ed410a744e30cafab36c1c64ca4cd8a71f307a1948bfa235284d7c059952b4b8abba362ae884c6e12ab643323b335d9518fb625625d955123fbb3280e73fa642dd802b435bf9ae4a6958cf1f404d23b7a97b8b43217fb0da3f5a7ec6f2fa0accf49b2be5bc8e7353dc105e7352f4943c5698494d0f23a354872a02d49a716e6d35f5c9b706531b2bc13f959607bc7ff63fe0f9f290317a0acb767702b92108bec76e5c15957084eeb4359685ec1fa3332a1dbe56cd55445380cd51681cbd6e51424fa08c5f2f9505c93826adc7ea795b7063307073cede1d7207e38a63338438a544d64fe17e206d16367c89cfcb1f9c8f0755baf981ee4704948e6b4429c9e5cd21c4b407fcb2b49971731707a3f37242c9a8ca6994d96cc09b2b768273bae197470f7b340a9943f1b44024c4f9046468d78df1a1000b0dd0968926e9ffd07fa543ddcdcaf793fabaa646056e0eb4123a6df3e40059327e86777878d31874ec59acacb626169e4214dc35bb5d9d46d407b085e24d1608643b50ddcd2288996e23f167f1174cf2ceb5c341c11c6de6d683312a91f644211f2c3710436d50ff93523de76718ac22d465a73e8b2e0e91b7910581527e8f1d15356d62eb3912fcad2fa03287f1263eeb53e830bbc5f5b5eb99616167eba5c071896b21470be6a21d580fc2c731a7b1efd99e1fefc9fe9f331b4cca06d16c5981d3c5e484291e91c299f83eca075c9d287be36adae5fddd86554625a402f89e40a083fbe9ee6c910bc24ca098338ff6e3eeae49b89a52aeb977283e834047936944210be8560728cbff5570edacfd56afc82465f8da0b35f0b61f09fad8e24026254407baaa24f4a1f5d58a47b13dfdaee917f0bb82af5b17215b360a8ea992647ee29da827d06989616a3be9f429d680198dacd90c248191bba25d25e268a81721eb0d7df9c1affe607a46e6257fe8946f5c080be2023035aed710c1e1edb601dd145c95e82962cd03495732887da8644695ce35e995103f200c6a4ea437318ab603b5f6c874d168842ad1903a80966cc85a2277c0aec0da106d87d2573ec9b4c8ae29a88027874c518d96bc0b6b14540acaa6238c7aa8d300a61316f3449da7cc3b350c04bbda4246dbd323284a3514978a19c4b7c15ec4cd6c7a51a6ce9955f3d70abfb3908281541522d8c00fdf4c53eef5d8cf550562fed4dbe8e45e2669e42ba27242808e83e4e21a0467a3d83675c8c86c870561183b008578b044bfa8c927d40e1d5541bdf503513ecf4cfc92729d215e56ceca5c5f108d1b0452bea8e6473ad5674b975b43ecea5aef29526ea28f1aff126ba7f423698480ffd2c4e31e85b5373c7b7dd9f91bbae3646319a4b837f44994859806dd9f0470c30688763019513df8f68ed75f7a07f955e04891145b30ee7837a7af13a01f38f3da70626b080da476b2b6067b90afef10c65479ea0330e3ee04c2a219bb5cde88feaaabab8a20ce8bba912f6166666b9bd6415e943ffe866e28780d6aaff377019adfe3622fcf8c31f5534a4b81f8aa43371c3acf2fdfd7341985c1ea2302cb9b75cf80fc480fedcccb16970ecad05c3474ec0d606010febe7cb229633b312c0adda17f140233f6684993bbecf79252813185083f523054c971f03d34a816be38a4ce60eb74db4791ba5e85b4b8296ccfd801045dd0ce930455a42b78b058ce4c7aff79c567b755137a3697f8ddef62ff27b70e1d8de61b452698fd44305530fc945e9f1189a2094677fcd34757ff898e6c512e9079d5edca1bc292d2b41c3d91c34d7a0c8c94911ab738e2e41567534796e2904fe8bb0997cdce6c229a3898c060197ca8aaeaf44e1483d0782c03889a370cdcb56468491570eb8c73a9bb246883ccea621834ee92fee968a64362f5ee1642aba86db8d6663a8f31c5d14709e8ba7cc4017cf9e2288c15d462254c02c498fc1eb050eef52e9145aa5d2e9e37fc2e0e72f511253200b5285821018c007474910291ae4730b59f713a27067150564c2d2f9aae58fcf3581c308622a4c17fd0ee57ad4bb0161dfd68c008c3654842cb020d3e50caa937e08fd460bb6e067cd7126240a21e5b3d4f0803f5ade33fca99ad00d405dc98b3cd6a0baa2834a99a60310a50956b428450ef3e3eddeebbb2863e269102c652c21383123d6526b806bad20c6032186a0074a66515e286ba813262c145294f0c630870659b21124f640df1b176a62735bf3f021f4166aff5b5e94dde26140257deb159652bb8398b47a42568401fcc8855703dcc4258b4da945c1f87155311fd75d33f825b634191b5cb05b5dafe8978c5a2fa76314297ca3dc11de7426e30d77102e884ed97d3635a96215469fb1203adf6f11652ed00fa7900550831e2b761cb6eb1372bf117765244e261ae6f4f7e2d6fddc55004c65ef896a844b4c7d08b126db2ea25781792f7b7dd0a98809b0c0b53bf718da56bbc27fc43d64bfcd505f1c8e625c190326c5d29c5b33db01aebc0f1123016d29ec4865b4096d8798a77f7a4d4e4ff10aaa14634553aec2c7a5f4a8fd4184f525aa709709d9221e605ff28506c78e0400081be1b07b122a4a2691600ceea82f0bfe1170ae2f15f93b683529807579aee7a59f6bdd5a65877a526f4ce5b671ddc506cca7cdb0762cdd755e9ffed9123826ab3980acfc10fffe892c2856d03b75cb1f8f600a5f1ed86601af3a1fa57004140d026e0a10137ec42d81c1ef54f95ed4b0932fe44c79138fee3d74e5b30de9526059b580c7b8fa76e2e4a36b62d4a43c4396dfb95bd903ea34c88336cb19ce2aca0125c4dd59018c13ede4cd0908d0fe72382ba05b0fc2d832ecf5ff802171677313b12cbca4650b9ef1cae5bbf714765ffb16eddc19ced01e40f501345530d4f3a9e7faa30108b60a479e3371c6d4a967cd4680e75c933a1598e063b353a80f488bb756980dcb0cd8a8ce9584846be42cc226eb2285c6a470e6a9b818f4641706472a22857e4f770b1749b4431864f3556decc594f6abf922402ed9be87376a242b13bcb821ef2e4614a603d159806403e986e058dbc64d756b7122e90d4990d29233a4a0e7305893b91dd15964f3e3df763d7f3c60f16f52dec7a6b367135538ec922d333304e295dcb2ccd60ecf3584339aa5d95dd66c0064c5845708241992cd12da7b049d4881803659009e60ea2fb3e40e1135e29b0b5711f4a8609f1a886d25bc62fafb74dd7e457be5f9599b21f407101e4d3af80e52234b2e84f66f43a8a1546136340d770f1cf58a4cc2461c50154ba603c3499fc5477575277d5171304d60d04c42fa75eeed8a39c733680824753312a352c1467dd23536eb34f6c990e5c2fc3dbe8c3da7496811fad2ac9495bb4545b6634ca57444eb9a5a08c37f903caac9324cc9499dbe780195c4b7636bfbc980b4041ba72a431c7dfce0ff22de6a80e84a3f505c7bdfa14917c76ca582024b617c5696ccd3a122517e610235375c09a7866efa9ce54a7e506dccd91d29393dd98b01ca6e58e9cc5e5751fdc32419017c0dc6405cbd6a22f94f9fb94417771d485585d70abee80e4522389f0c0b798c30015a9343cdbe8ed531f2e6d07b1abe1827e4685e8798d44b0f88b1f57a30bb2c85e5319e09cd8c84dc16bf7e1022c3292f81bacd333e47b262e0cde489ab307b753f4bf5e66a4fc4dce4dc81e0a5e2b6417e8a57c7a7b5008187cee58c2925ef245f63c075368d845ff15d67cf9b4aece698c388169e79ca95a14062ee8aa9793a3795997f0afbb36f64161845502cab86dd0b49eb79351035357dad878658c9db4efe44e45212dc8f1dc7679bd0c88eee0c0cd67e92e3777a570d95700419be52f552ac4c91a3b96adadf6b2dcae1f392a39156c8aabeda4dbcc66bfd43e4d64a2e35282a259d7c71efb388e6e6f7c647818a79b243e2a971521d9fe27cdfe671d82615685884536951a75c292aa0526837b7241b7289981803971de709c00af886286f79b3828350080967aa16a7b3bf8a3b6702f76386c88784b77517c6c112f7565793a7d7860310199d633d1a51e40cfc16ed4ceba2b76d3209253fcdebaf2a5977ceaa08d68972976a3a75c3fd57481c2ea48667fcb2af301d88e5936d940646171dc627e254b0e4bc5f2543b0bdcc02eab24e717a2b2c2abeb2cde84112186561cbfa9f5d895ee8ffdfbc9180e9347a944ac67e430c393c5fd6304132c34e991c75b092c0595c6e84fd1496dcfe7d880f2bd4ab59a06c8fc7bbd133879ec43b72ec2cf2bbe5ccbe0ebd7a36fc0902768831cfb3d71b4336424581c9ab2b370746c3a49d8c00a76b493a098c3095e9b958a6ec99088a060bc177d9129d8630a61b2bb4fa7a63e27291b4ea796756d3c17023c068046ea9bfb0bd28fa39be36a5a48e9d47f9c27c6133e2b8c609d50134e4dd0784723303ec9c43ec0b667823b21b2d31e05c8e5bc33c7f92b484437492f0e073a26185483c433b1c3ca07297cc8c7c49f97c88071aaa4fab4b698b6856bf08f457185ebc594f1a4a8f6cd6e70029944e0f04990e297ce5868ccf4e31f52e734cfee19d6c5044a2998c7dc2e922e0600c0e2e7bb70e2ab8dba0cd630bd202cae7a66d2c1c2f27a9b3d113cf1ff46cc78479e105ec6faa7440b238ef18d0f101a6d51be381f64cf911043661122892a32c87b2bf99ee1f6e4dee4490d70bc4d3edf94ce0558f896e97f3da89a3df3a058c956b8c6da5774635d618b8fa0cb952393c0790077a1ea3f9371a0b67c2331a83d383a0514d487057a8a5524a23f21f3ea138d90cea8bbfbf6b14df84a85cd3e6309ac8035531bc17c6de6159632928ffcc18879ea88b8eeb2481379429026911c79ec3e72b93226e1991866f259bde1a99c868ca41ec890f9006d93a4c676fe160fa4f388a0121e9caf6257386037a70e77c1f8549802b48ba5db9dce5a1ae02a5a6558f15b5d04d39d0e247c4764fe0bd6ec0eded5239fdc732ce97724ffb3887a67ec8d7ee199ee43b93ee3c97f8495fb46ee7562776b27dc092acfb585545cb474bbfe85d75df79a5f30a301e6f3b68057e8cfebc0ec1953df74c800ebd962a6a0b490417509e2b9e26093d413c5f33a1d62bd096008964b7123f13d8b23e06e96ec27597ecf5867daf647a7de6b6909cea2b010309e9c515095e15b8787d3a8e1410a00af20067697da602f937f52680d1331000ddba44a3b04baa4d01f4dbbd591baead3b840c81e26a8f44f098f305159259d50cd07e023c3184a269c7d58926969577903ecadb967f9164205304d01b07f4f57d8925b3d978be7151d030ca794f3ef58ca8ba11db5b568fbb82c1d6841ddef2a665c206e3d4ae995c37a4023c0f0206dfe759b1d3e09adbfe22c2449849e5787c955c632a30025b7574349462cf4ee9d631373b2a7bf3633e765b6d428f0ab2321e6fe1e0de33b2e9ebb5eb016064c94e47634c7135666caca8fad6a94e7c912170bf98271f1ab1736ab40cc343652705c1d0b8a86dec5b665361c071d84fa5c5840250455b4b7c5610986b274f882f1d037d7c06bb9a872262e349df0b0fe1cbfa50c837a40f8614094342da721ea56c38182017308639522c6da18b88f9626694bd6c545ca48631f887770e5c69e0bf35b6c4552ce89cf7cffe03e2648e40ab7b2ecbead1d237fffd37c4a272872c7107e09e386f3b648327b6d7f1b1f151def164c5d7166bc27e3c34617073e7519f616f30904869c6e398fa16d264e68a66399292330d313972931cbc4a8ca9400652a6a3221492631a5095e2a47e26a53a86e1347b92980996a210d2e344c80990ae10db34ce30efc50263203364e2eed44a6ab5ab6e0259a192189251e50cc3e48a06915ada408daf698a988e175e5503453e220f04571b4ce060b4cdb41e9fa1e6e699db29be158d301850c0b141d774ce049a62cb19aabe368752c4d2325ef22a551e84df70ead366934f807457f11447256c1aa8161c10dbb2a439cbcd48cf15aa134d107834404f1747081f896bf49e44d31667fb346f66468dd2acb4d380bd4257b982463c80c2b11e3214187b3206710f139e78212969509eed91cfe54ada379dcd83b9014a3ba59eb660ca7f5575bf51d946c09e7d7342a15f2990f61b43d31cd798b4838cf1b36a613cdd0f8fdc8d48ef9d1ba2edf29ed9bf0a1fbc17cadb45b99f1331a282d568d555fa2645fb8564caf961cbd6ca964cb2ca83d40f9982eb282aa0ce61c0c8f09ca73451a7992e470224a2e8a36aee9ed08d9b6f26c879f60e34a367c4d47165450ea9affb0069c90179b0e5b0c2c7132b0e96087c8b80902a7ccbaae8a7363b4053c0cd641c4c60883607c63f7252a12e2a0db46dd25695cea1a77c853988b5cc086f24ba165c9fba01770741146f1d0467b37d545ec7cb81af6e978edd2d88c3dbebb2ee9ba642285829c81a110d1fca9f57ad50c397bd835461bec8266c8ca9c9e7936534706313f4ef66304659e91a1097c165e3b1bc1c4f136a473d8882e8d5cd06b0c41029b58c3d5868f805c3f9c45e583e71d8dfb193432f9009357fb9cef5e28e01f7e4d264f770720c5192e383c38a5986bacdd98f19261b56a1a2f9bb3abffecc236c77757eafec2e91822ec0b340889e7f6bb3b8abe2229adbe7d14de6c4faeae0db996e24b1c08ef0f74251780ffc410b53ebd757142a3562a0b5fafe4be062726a658b8560f55caf4ea492cf3de1eecba9822bfe8d9b88277b52580974161feeeefbe85cfc97bb79264fa08268a0afac6f37afaa913c21e8026ba41feb460e36d84f001db34aa9962a622c97ebb844feac2d6a457b46576e20a8b3f2468472e9a36ff05756718af1bf835d5d4bd4d96e25af33febb39df5413cec690255865a26afe44e2dd5746cc531f54673f6fc9f54fa24192ceadac37be45e63e843987b5ff949ed943d3f4b3a328f55b32791565e3dfb3f48fa41501d2cf6f17144a962f871ffb674a1152e67d77e339749ebe4ed3255a4f9082b77fea5ea65676fb4b20cd0ae6862a5c26f74b6afc2d1f87eaee13f16a9ffa416a68c814ae60893abc7db61daa0eddeb602d821ff26d0fb56252c3cbd5cbabf1c192af4460d2eb81a3343259533efef22fc45114c94e4294a8efe8061a1ee7ef1db14d2a4b36cf131ff15f0adbfb413a6b985eb1a5b90323323e42601c13089631f2a6e57b7208e2c43e29985353fd9553a4ad2458d5dd7f9d53e8406f340b94a0373c4e9d2e6ece05c715e88378b564e278a338c4eeef428fc4817630ad99d12fee5332b5a587cbe7ccf9dc8379633fbc4423a5a1c86f2ed88dd66953f42ff87debcfd3b9f7fbecb77ffe3082c2cef66b2b19f19025a561744f77ad663bfcc28e381947a8367099dd8643959d5a4a4052bb28d8fce241d8b42ab99d9c67c7592a9fe7a36f20f88d97dc3e38660f9b8979e5762b432ed735b0d6fe8456b1b5b5f8c8880472aa2bf4681f37221c1927fc1bdcbc0f1d0595ef0c01209602fc8d607a8b6b10e588fecd3c43d95a9119c298af86b7e201b46b5e6742967affca43e5b8b49d3f9357adca9f7fa069941e276dc286038ea99a1c2b9bffa54a50e2a6a6144b28c25139e529bd0754a9955ebe31a4e1fa382fb40ae2b08d664280a3ec96cf3aa81dcd3607aefeaafb454791aee51cb26eacc26d3ad5cd7b82f98cd63fdd86bb9218075e4eb6cc4206ad691b9d3ad39093bd6c880ea056874c430cf8538096fd2310320a18029858de21c0b522b8e687e7abfa138c2fa796b6a92fbcde3776c7b4d40f551932ddf746aaec648d5783bc9bcc81cec2d6d63b1f5ef376365c082cab80a15912c0fdc428e91f6caf170a9473e30002bad12743a58e9bf3a53b41dcb561d22942b451a96ce489a30f7ca30c48ccbce2542fe2b0d0d61a4b159ac320d882ac531126c8b54fa181215ff0815c7c653120bbd06bbcff7f37efd5a814baf13fe6d4778efada627bce194b8a55bd24db7579e687a961eeb3341c4e3935fdda4707b3a72dc54bfbc3061a436d21b0e756feea8407c6f6f18a9be1de75db29294165efe1289dcb0e45f3e8fd4a56a4de4574e9b417ba24b3c856ccce4bc76eac35b65f51c36a980828b117e890527e0e0dc74250a340df77a09548e832bedb6af0c93a2ded8ed850622531c81a842db58c215b4ab286ceea3a6b3c39fd3f0f068417472de2f87ab05e30dbb8c527dfd4cf83ff35050e0fa6765d845710a5b96de0babf3f1f2e13dd84f204c3fb018bedb9532aa41f1b7886c6646f7bf27c5ee62d361208f34986d3ac54be802bf715b95b3af362d97a5dbc3ec217412f754ab3f4aebcce7124bc7ef1170ae85194636956dc77c7479bf33b9502ee7e1914ef1a0ff374574d3568c5d04e7131a24e2a732fd447415ddc9430e0123457438ac036edbaf4ccb98004275bd0ddd7eed3ba900bf855e289db0e952a23acc3f0891d77ac58313ec7bf8e5e0c3152f4ec768b866399406ebffafe88e20d671fd752234ba7ea7e39180b5e73144b081bd7c71e96f8a244718aa1d76a0459acba2e8b140c2497833670907c9e3324b512e01596f669a25c3532f3865c8c6aaf0e1bdfd6107945a1cbcf1b43a50031204164ae46cbe609b6c533a746fe8c5a9bcc128fc07ebfc5ef0bd27cd6416ffbdd7ec0fa742bc21c08e4c1408ab061863b1618fc110ea3291ac60302dc5a8688172d98c39651ad8e804b0dfc234ec48f29580bae36ffac3a61367ee5fdaca68ddf935bc058791138ed1a38b9cbba91624bca77dc7aeb6cdc76963ed6c0ea1f3d4f3f09730eac1f371d318c84c2b7fb6a14859bdad023224ef7716e24892e4553782c099a79d25c9a2564c73c824f34c1051c34cc730afdffd3f7d1d78e05738f0775f17860bc143934e9a557d902afe4378dcf6d8a1f9d9d5c8f7addb2816f3c70ea57fb6738de5d118286f43886af1097c6e555849aa54e32a88d7cf41f449a9e6bc6ce533e09345698edd087262fdd3d3091189d0941be4d66412731e346600fdf052a6f7c4d4e046ee43067d36a54e46b634daed9ef31f7dc3d44d37b74f6210918dd0e8262da41b1d53be8543d0a57dff6c077d160e8f2cbf14d5a735d1f83332b150fc4fca7437876ba1954b1db6bafed838da8ff6f3a33c75d92ed55731767ce19cf4043f4eed16aea86e89f7ed7e7b29aed8afce8fece71fa6f603625057d825ef9d2b4ad52b41ea78cb4b7edbb3a3972ed93a5ae7e0a5056641e82598687bbd5a20a1ae70ae590c6e4291f3bdea3903addf853839403c8faab679819b2a56d1cfe7eb6326794c3786672b957317929e6fbeed803baffa9366899c49742383c7c1f527406657ffc10363f4b3d750e621af86956ab50810031f627dde8876edddf48487ef201ba289fc55a0f474f93b20737ec79d888ef807c9957f5f9d3cb5f9059438b95e72464afb94d1b607239dbff026425f427c1fba0f023c28febd1cfeb8ba023b063f91f3ec2e744428a2258c042e85134549cfb9ed10528feff41a62159c360d63603bb29580ca3e67816fad8bdc8a4daa71f666911b759ce0b07bd01f1bb25552729fe250a62ff439824ba94eaeb39cb3e8ce9e5471d939fb403f03eb6cf011ebd2f84ef180e66b0bec14c1984a8cee85f57101421111e3a253cf27166bd4cec686b0daddebe21df35be601e6d11aeaa6b357f77e27ddc60abd0c5443c39c481f9dfbf49fb1807d78e753ef1402979479745df1a9d9c44e5b8bfc68e22dd9f7c7f66a3fff96a179fed310bba55e56a6a3e9815ca3697c3f560da0b7e6b17dbc4e4fe6080a272019f7f25bacf4d349db7e31614a1573f6b690e55e6d2c959a2ee069b0b4eef2f5be47412a1dec920dd67561da8d762c6895939bb8cd47fbbfb1c1c8f938ec458cdc37b6fad272f4e030677026db3b01be7cd967d970e4e4654ce1048b051b4cf7d4fe84402729f0326a4e80f68395f9ad50ecc3fcea224ecbf5dc6216a3266d1f898af42db0799440171b4ce56d8f255ccabbc1ae7fc463eb0da36df29e1e4b2e08aefe51f10fc96e870275c89c71dc1f561aadb74b6fd10182f2ae0be313d754e99723b1ef3a08f70ba88c0bda8234d3a0a75ce19046ed62fd26c94b4e9125e9ee55ae43eac7a5cc8c4558e4f3e02dea53d9233e30bc9c770ae84577e729f3db9afd0186589509aff2af0b47d7fe2dc06124fe213f3642ff29e9dc5ac6492e3d2e663ac627519e93eca9ef53725d9ebb72a1487e1b3bc54fb5056da1e7140fbf24f243a24b34890527798ed361504f6e653dfbfd40f2af0b6cf194f545dc7530ec16fe49deb9f3d9b2721f23fe43917f6eae28a787ce23079531bb1bafd0fcb9b69f333c15e4c80cb93e53429e8c42cfe7476db57626adc5c0fec5fe875c3be7ed6f420be0d9dfe8a28e76ded15bc5af990298f74b406957c501f38c119ea7a0178fb4e6a34fa7a7a9187e636dc499daaaabb4f24010340568a55a12e22396c54fa0837588c2905bfaac25491d9756d8e31cca9250a56c2b2b7646d8f4b93d53213d32d1caf7d826032b3cc4f90a3dc58ec94a3678f0b8cf4598cfd73206d0376a22055f7d9c0fd13f7b108a6641f9d834362b26aafab27a6ccd13544e478143231b5410ff02c77fa2f9d74d48f1bd882f7d43b77241ce79e7719aca8949d5d7fa5a994db8ad7cb0e9bf4a99bacfe04776a4384d67c5fe57a1b6228bfa9f08ec64e198179159abafef41bc3dcd9b14fda3623a9f6cf5ff7cb0a9b019066c5781e4b51883c279c3bbd1c494f0cf051c3275a518c1dfabbf98f57cb7764b2b79b1413f68598fc27c5f375cf7fb4a2cf0e85adc713b6a9c3b81f0dbc0924019e2e270f094461d827f0cd038276cb63aa8fe8382690a08c0c22ba7fd7e7edc99b78b87b0453165bba1b3e439fcbc3ecc44bd2ac077e4e34357d3409e864e5d1264e3246b4822f74768886236842aa1cf2b3c3a097227f52808ca0cd707e8888f03af591fd11236657c4ef0c65fb19d5be72a01693f894bfb5c083526a00066e35dd340246afb9624c6bd9b052f2b5121d1f33d34977abe2e68ce3814976d9383fe3a5407d43e6a977dc062a09b56b7c8aa3cb2dd399f587b969ec1313a39f2e47067818f663510ac27c0412b44268bd10b22f4e826a1f1a03271ccaf1169472b088d076a7feaaf21d2ffa816b30676f4df835a727d4bc88e342165c324d720dac89893cfa238c342ef5f884c7c21cccbab330a6a47aeae65a88a73ddfbe5c89378e6a76d08511f33fe7826b059728125cc7bcab29242a5132ca23a4a2433f9832f47994b1795917a9713be1f02a183f38588e8dbbdf74d923d5466740b411776c00f9ec08ddb46ff942fd53e70a259c4a5d2e73c233d585d5fdfe29f2d528262661e380ae3e53fba7576dad1ff4dace9366533553434e5b2dac7d73b0e20c69be2f23a8c50ff1015c9e7cd14a43d21174a8182064d25127965228c08cfc5e4d794e243e0ff2c29ca06d64453ecce3e11f6bc2315e7bfd10f82eb97e7d8ed2d1f5e4de2c1f602b896ca5549599ddf9e81671e4a3d4fcaca9864ebb1df8a00ea57893e74f33e4eae5750563059a85b27fc9c6f8fc755dc9e21d550d3754d7c147f72a7531f5055604ce8b682fb8ed0c2db71d89e30897b2e3cfce06eeb9ffa6454a6ee195d2d4f7ea2f2a8496e8acb52665cc50d557d255e49a312a3155056e7be8114f72fc603a47f770502fd7bb24f91fef71644f31f9980e4fc1ddf5058a4faff45ddfb8f536fe33f6a2fbdc54c7f38f558fff17240dd0ffc2edfd6f88ba947ef1f193709977ffee0d4ae060b9989024d7f9550f5600a0ad7cc91465ff83f73fd7e8a804c0ca54640f2f36e1977e683f3b7511d5ad22b66708e980cced267edacfe71f97367cebf089631d86d21b103df18f53f7056efe2d1b4324d9cd77ae1574ce2e0a763bce02e37105942fb1a1e857f02da4a9110eb95a0ee49d6eb3fa0e29b0d9c2cfb5460ab377b2d76ee5eb579c8299919bd1c104cd32096497118546b856c2533bb3084e009839d36624abf34bd5ce5887f24094f7957e8f1dbc7499a98e84b8738e334eed4f608fe481b7a2ac24b40fbe7a7d3e25db097bfe695f16c698defd7e6afa55501bd5ddb635386cfbf9889d8c9915e0c1fc41ef1df9a0294e6e330b85dd991eb41c156d552290b28a4f570378a7d1509c8462a5d29ffa862d7a5a52eae8d6b1a0068a1fc1e2fe6dcb44053dd8a34d1e7e8796c5fd39d45b4112d0cae6628371bc33d4ca7f0094f8b3c6f73770f315b32a835aa70aff7f0c700f834e89ce48ddb1b14c6f6d3e79b67bc65d832d0b0d10b137a5b9d4d1a50a910e9d4f1f01b69b18113e165c4a8d193fca602c9cb154f3f621af9b61783e4b1204c00a7b987b650bdaba4a63ec3570e846634bc639e2789766eb43f971be5179dadc9cd2231418fa747a59fdbb35ad3cc17efe68e0b6237b70c370cd6e33176fa20e08a7cce4f8557e422a308c661b1cef4b466f04972ff66cabc8e69aeb743fa27bc8e2dfb59f71c7a4b0e52039c9ff13325d22dd8f287dc6568ada0dc7ed3e787c97887eefd54da918bbc5cc437d9bcaa0c6efa7590cd180202ab45df7637a3e454b9c54e68df2208b3b5499819d90daec395bfeb96b12a733432fce44062f0d8023bb6c7b6f9d933616ee11066ec2f688fc55896291e77d644c2c3059c9dd3851d5f035c105acefef3a77c5b9cef5233d540b7610e85f7b6b584992102777d59daa7d38b227d616b81ca7a24d3d74827ef05f12794295dc475ab21da74dbe4e7e5684ded70074c37aabcf013b7623b9aced14113bf6d9dfdc7ab8b5f81a63eaeda6633b6d8cd057b912c00cd30e1c27b1b7dadef9665b907d0d7bd01fefae15c52b5999c171536a8ed3846665c8d612116bd32e4e0a1df6b2ff9659069dc8c57d86a647ea377f3b02e4e4b800b75c022742903ced0d958d0de539a8c1a5e566abd833f55c2d8351da1b50bcf779779e73fa1e17634b8e617f08fe4ed35e9bada150026f282ebfa02a59d2a7de9a8e70a5d897b239173dfe75f71c03b910375edfe6a176e7978df9f3f8a1a8deef11cfcd016b8fb71e169b30476274967025ba2d6db493639b2f529df8dcb481bb1f391ef79cb960c01f405f21e6dc9dada4a74d3a9b6096bc872f4975863aa63e7da8b88c9b8479bcc3ce87c10bfe6eec68b1ea1afa2cab3eb85270c390be8805ecce70beb3bde25a4ba05ead57238a3c2c846d593490c92d5b27f2c7d41df49288d8f59abcfcc587ed4be296eb68839f0b4fb9c719ac7926579019db5db5bd00db9784fb0f69cd761d4147e47bfc3df71fa3e93cb2d95b09c18c033dafdfa02410159d3b4673e1346d5befa8bf04bbce7683b4cb492099f2d267e1b5aab5cf24acfc11a2c4fd67bcd8fcb055bc4593dc440b29484fbdf3bb9bb666d56a5413fcd31e9bc37f4e7594969fcaea36079bde429bda16b293ffda6f299515941e2eedccad9fe5d046649a4222402f80a84b254927d392428117c55d60349e17f6a2cbacdfd62fcca55d4828cc60a39179c8f9393e99778eea84463f58ffb302863a9a73267580616dc1e9c6653741953bdc35ef12ded6194416358180bc1da65d90f57b3d5151041265cda5f6af0a53599166f623bf013649e9b87c698491437245d517822b35bb8281f9da3ef6c1a4271020628a171169a1d94640e535fcd0ec7ef1864513a0b3b0b17793ff1a1fc97d205fda55144ecd9476d0c16b9d84d1db57b3d17fbf41d39a58bca3e320bd4f892b23515276068901d29847a29a184ffec71e2586c3cf0a82350e6a01dc907be5e644ff36af919964e519ec2d01c66980ca85f7ed4633e0b3d356f9b5add663602b75bc1f140d2663b7f682e633579fe659ab05f19d63de3703cf12f442bdf74541317df7b532cbcb55f3d01a0f719f504397fef3c315c26d0ecc98f9ab91b2098c72a4f459132ab73650bda0e761ab53276df8f2730209ea4550328f5f0e09906b433e73e391f4cc4ca67265a97ffdd07d5e675f0facf82aec0d1e7899e1fe68b9f1b97ded1b3e20ded75c78d9862e6e96f2637e10b47e886d6f2ff69799dd36f909149ac27633bfa51e50e0dd76c20b886bdcbfc9ec2fe312c3c63ea678bc834df39bf3a37ce273173619a6a6bd0af9231704e069e3b1911d31c61027747e978c2f6f679db1bc7f8496c3108787cd9918853b02aac173d34408f9f29d9b60c764c02e7a7b6bd8e24cfe76fd242448c7cf6b27859c6ad40817f8efb48fe98d11dc2cf4f46f31e8b1e9e0e8fe0cbcdcfbc22c9cb508d1c0876cae06bb3517513a6e0461a06c5be84197fb10eea6c8e39d91759b31843f4dd9af4d324410c44be61907f59ea1044bc6d4ee6d091dcf16008c99e6a7b765fd2852fcb7f7307de9a045e7f4059269092ce28fdff1769f415e05acf8e555a225c427bdef0144395b4c729fbd5627cb082552e2aa10c92b43a7a8b3b077a17b79727124df6bbed0182211cbebce27a3197e8281e8ce2baa8d6b01fc38db17286ed787667c3e7bc66a3f1b6fce301d0b3bd717a997c0ead324d73d5dda64b541f0dfb567186f7a38f977f8d9fd3dc12284b1f7631210add059e147317d5aae469a85888fb07778081af3c1ff5d205cf98e7701c920895fea550341b8a976c297a62b84b2d3b868b92eca089e7175c22231a17a1a88493605be02254607013b4d4e7b51035cec5c3c6a1afa2a619a1668e8664744fb3706a3b662377fc0cd46db5f03c330ac23d15dbc90cf7464fbc6b763990ce694d91b6d7e45045b25749778e7d4e1d24b120104bbe343009bfc74dfb910177e3cc2f2d0e8dd1253a52bf7d8d6e97cb2fa33147ca9fffe4dde27c49feeb310d19c35f5acada711f225f84e37e15f95d06335c83f90f21c5bc8c0a626bab89f9fe1f1f5f28f02fe278af80f131c185c6738499459fb87037cd33ba709d5350a6fd86eb093cf60788cc21e903b647128e0b44222c82b907b293f52e002c1b7b13c670909552a625ea1c33f3a30edabc0dfd9b29974c327d9703cf0f9ef8e791a2c6768235dfaecdc5b15f3d8bb8aed01162653c166abcf374cb897e2afa4ed78f90a38792870b17b25e973d98d1ba95d16258e42c3713465c5e0051d4afeda74ae70b8dacd568f36ab5c0b979924a35ffccfb1fdc94294898b7467db1d2036444cd56795e2c4fec577a4da5726824e157edcf6dbcfe041f0836cc3d2d1a792af959f6083a03d8db60a66c5e87abdc19a12c3f620fc69c88f30eb27f68ff6653f1fb9f8b9a003330891731569c1919b2b58396edb9d84336daa9f27b51d0643ff126de80001dff2a34c8ab21cad3dfa252ef18851e0b611f2deace48675944376d15a0d2704fbe0364baf3e21f2add2a59d60b6dc30196f1127a63b095770467a3a26747179fe6bf8fd32ad090b884b1a634dc8da1ec79e93f55dda78c302e08063a751ef3cc1830ef041d19fd28bfdd6a3629d9fdd9537eb962f77688bf4b9ede54ec77576f707b31d5cb1dcfe120f7c51c6f01fe54518515a81c080f3f147a9bddaa0313bb6875fdc7a701b95edb1200fb3c84c20baa81bebae8d21d5c250b669e95b30dc6962e3a517924d74a18df8b62195773386fd97b5ac4fc33d0333c9341cbe7b189e9d975d4d12007e1fd1e4e972d7822716622514ce6abcc5fd610abc5a397bb17c4b973deda3a6d467b5bd8000e9146849d9ee0d5e8731d9d26523ffd935338964c1e76e6c5ed4a2a063c5a6a630c15f0150f2e51da115849942f9e21b71686a21453cc5ac68e3763c73ef8c11c77dc622c71a57a451da8df1864cf70ed1f9dfbcc965f8d6c5c246a9c3a5032fe164025bbeefe72354c0072ed61acabedfcc23b9ed14dfe3fe189280168a25addc5b6be35d2f920dadedd5c9d608b36d1c72ef98de2324c7d9f60201f43bd0ae603503e4ccd4d2ae4a502590f68c2a7dafa57106ca025cd005354d499ea58e814f5c4e35f3c954df731b2d705ec022270dc1b06585ff2f7158d879cd6bdb80c22667415e4c9743d753f1e0ecf50a341720a8272160636beaab99cc675c0e7e907a7947935e5a6973a9cf939780dddc85ca8cf0854f916c72052a5443c413436b0d8841aa21b41b7685544b4a802be2eb24a01dee95d31625e5785643766b719904411f421140702601ef4d080b4198f84eb8d23fa1bc507d3e00dfd085e1103408f1b5a3c3e17ad9bcddc9f734164d402fd49d42492408826d167909b23e0116c6d471e13fe98fdab8d88943739a383a3dd0dd1b15d1ee06a1e3cb54542c2967087101c9e198bceb1e342a83ff07c4fe415f76edc35574da2ab768a5433567de2c06cdc9b577f917b121f4d659165e6015cee1bdcbdfdd4915b2d5d82ebc70a84ed5df8cb87cabd156dc16b131d2bf428596f83b803563925ed5589447a1db65cbff8eb7bccbee6ddf0716156fa5470d0fe4a3cf0a511453cb88b5befbbd34af1f050da7cc6e6ccd2ca38420d9ae52c91d2bde7e02900ba8e08ff7cd4863cccb80e55dbe0f61522f7b74db8f584e38a8ea8cb49f69ca36f17eac0d7c455817ec8eb3d159c1aeda6085caa473e89e4945ccd477e98cf2cd43fc527c52fc1961ce573c7a7540e0d5ac26c9f6c95d723ececffeb7951bb30d7490d2fa4f3293addba4f3159f018fa169c06a4ed1cbe20f5031481e5da88dd7e150840760779eb30fc1e50d11ff65a5a0ebab630fd8114ddacf2da77dbdad2b48acbd15452a8722eddc52c1fee0c9ac27c89319ead9a3d03d0c5daf9fd0e8e0d1e1c7d85e0676f2d5e5a4d0302973d7c99ba17d20161f0934bd6053e8f50f1471e10128b92952881682272478dddf4cbbb087366a87aa424cf7796744b32bbac89228db5119f0b0eb5e223160291825ab9dfdcc77c662f50d485c429f4f71e9ed472c246b15e5534a253ff61a7ea71bd447e5fbf421b1380db85643d4cef1d7076de2885e2dc9e6cf867009ffb8d51bbeb0730c3b7cc275ca856624e64d197d3a1419c9c729719aeca3e9a0ebf4dcc417cf2e5dbb29339807761d5b621f0834714cfb735cc041a67988dc36433eeacf99899634a6e14681f2f84ebf7c61137f4bcc6cdd6f9dd099c00b3a02c8ab57b3948bc5ed4e73500ac0b8b5e251210f43ff633265b0670814aeacdfe8695fde75775ea0df4cf13713c06cbbb0feebc5c9b9f0a3fd66da650f0855c72de64475a7fd3520027dd6077e33731ff2d5c2e6fd3542290bf2ee4e259bc1b6614e211d5c7c1552ce56924680e12d3673098816ebc68992348677cd45a905f0a12783bbad23ac98f5aa9871acf8d2cd45e9c8449ec4f5fcb270aeb5ee28eec2065fd778e2cce42826f308609eb34258473f61206ae7ea5c7e7aeef3de2e99f635dc7c0febb24dd37b8e80fcf7ccf2a3ac6eb3fc5dc8ec1bd7764fa7750d11fdefc055a958f704bbd8257ef2780d623ce751cc8bd47d27f028afdf08dae6ca2e32ced33ccfd10d07747aefa0413fd6319ef58e28758bd27bcd32198779f48fd0612ffc29addd8850e79bae728e73190ff1651f7052ef4c533dd33098f71fa8f489d0f97b66d29875babdbd2d1564436e8d866790d416b4aaa7d939aaf8b124e7325f913ec0cff60cdef41dc3df2cb7bc0937e4fe6398fa87f8ec5ec17bed90d9ceb733e996758f9ef087e67c9f54ed819ffc333dc83ba7fc691f7882ff785cc7b3e99e61cabf93f18b35b78770ff44dce4a9547ed41441ede39121bfd99e02d1907d8632348976f6c9d536a9ac2b4ebfda59d6eb2f2a52d480b72ecbdd8758a5e74c878e2a1fe03ce2fc0d6e9312bb78bb903fe1da6d5cb681cffe9e85669934c5eb198c6b1a9a3822e1e4aae80a6d72a32f0523d32f760ab0fec04794e7c1c774c3e3df57eee8e48aa0605ee0d5fba84b93c6bcf006c9b6bf644dbb85298e4241a8e57f1229ae8c18784ec309fc9e94ce108bef3555afd4dacb680a75f6bf5fbe3a89b0e32f8046fe8efcb10b619dcc21cbd8d08f8bf309415aaf17e8aaa7818a8572cdc8c4d855a9744e566f2a08e093d68fe3a6c5fd7159155e10c4cd9df51f13e50620db2af39ca7bcac953a63d7cd5fc7fc11f48b4736b429f8969e9e6a324e2092d3c4e4bac38c1d6ee4721455ae4159881fffe49395741ff78c65edeca1d0e80c698c37d95d6c9fa9194946560e7f8d51304386be680a04dc518ad4f86a186e54f3797d561a8ec8e75c3e97a3a3d0a77568b3aa10a03511208ff9f480e69aa21ee33e516ab15006ca13296cc245c95ea94ea89a65b35832e73e9baac586b429ddcab71386a9f250ad158d021ba8224cfe9ac63a518ed6821beee14cd2672591f4c33aab95ac1736d1936a7f5e6d4adfcc2e168785fa5fbf454fe18d15c8bc7602072e640eaf8470a9a7837d2d567e12699ee83e9858c1dc6a44d200d6a1dc7b3af546810d589a45e098d607e2dbfbc5075512e10bd11ce92d621d373f11f0f963ca600e518b3c15d2e107911ca2d6593dd1a73e0e65f8e966119ce9c442cd733ed6cb9ef7a4e1f433cc1d3b38d344c18341df44ca46bc38941deb0d5d42a2136a9538ce5e2de1438e34b077976eca68c954404f76e5d2765ac13562edefb6226c37ed7505206b54be7d7f7f4dbb378881affe771a735bc5154f2bd43400d8e9f487ba2611eb1a4e31683f1014dea227e389304764c879408e65ce67a3004cd12eae06410ef021b86db4ad3c033e93c9eb95201ce55e5153475202a36715c85881cc7e427b7a101719e94631d2ef47f5c05898503fc27887edf1d6c0e05a8fa4e08e5b81851e866f723a425f4267414d6977a1811a4c01bd491b3458c7328c2b9c3bf2e42996ad1951418892eef826d04c0964094e5e55f3b6cb0310380d49b9f911fe7e0291c113970c90587bd764d22ff57249359f363cb6659772d81fd146c4b2f0188d07a6737e7a2e0304e9e4b1a5fed4e4c480f395d20cca1203c79e50c644f40380424cf9bbf3b48e57cea25e7258bd0e42a79a04e618841151feb7ef2cd54929a82d7fc44738ddefa66157d07e570cf1e8e30c78666a08baea2725fada2b5e5721dc1b0e0d6ad8f45b934161bd30029dbf882ab4732e800ca2bf2f8a9469b5125b26608ee371cf4a944e6325b979ea74679195f4eba22c6daeae081075a151ab7129bf2d758a4e436a107d841aa7445e67298245983d19d6da82947d1cf8754851765c2aff167d9648299371fe7cfd5d457d89bb34abce63a4156a29ef0c06ec06ab7dad08ed6380f393d14946fca259c370bda56ade1fdfb425937d594377886c589edf8ac691b76aa5f601f4160ee3735b734f582958e9ea98875794ef890eef7ed1ff6ca8d178dfc3e4fde7b4d37c4f68c5cef11d574e03f1f96204eece4cc295db2359bed5bec49d2f8800f7150f0d0dcabe1655646bed76a0589f5dc1cd215def980912a61855114a07c3b6529516c7caaa0418ced58c3335d1a328168c258531542a244fc79d6d03001b36f42012900f01527c81ee1b69fe665949bceb747d13de22832c3ab4739a9dd60458486bab6d90d37e66f77be4208a597940958a4b56b56330ae69fd69e3a47749a9db66320397d2c68d78e77a5f903dc699b818392d25cab566abb755e3e8e4fe5aeeb76e1de2ad260c3d24371099872cea5dca15c4cdeb0657511abedd57a909064c8052bf23ef8d465830d841530a144f77b29884e8aa423be3d99b0e8bdb66748c4213f901822fabccfd08403dd98bfe3b0740db93b1f84c57eb5f0baa991e8c008e03cc75cde2dda7d591f9c149c5b76a7e27f06d4bc46d3c26d9381599a633c868245152670822c167ca01b381edc286b9660a91f842116f412c4941b30e61f6903b3f79c1b025f751e88d07dd459ad4ca9418c0cc10b7e70839a9862c4e8e396053765883d49ce2fa7958470409e50945534bd6ca2fafe919ba913e68e5acb3c5eb9c2408446f61cc0bc3e02c90a2a588c254d4b240d938ff2f1eb8170c1a31313ba2c44fba5fac29d88d23afc26af34e228f0515d4aa4f4e39830337e37f9cac17f453d364f6972868c442f12d2a0d0ba24b5bd359ab568b816e42b68f216337c2b3f2cd1d483298704b079fd588410a6d82a5dc528d660cbf2fe6ff546284c5f7f8a7adfe542bf78afa20a6106a5dfd3de9e081210e7037baac1d3c8ab641e2428a715ccedac9268296e78e5461ddbdec2ea373a9e243f0af9c777870235750c0d437e88bf0fdf7b6c5aac2682aca3c4532a1247adaff7402da9ae84d7fe639e51eee5a694b7d87c31934ab6b8e53ef4ec53edaff17e3b74a0aeaeb80e47cce8bf9825ac6f5fccb6a5ca5051837f3cfae59ee7389916285bfb371043cdda561721ca0ff3a3b6a89410b86822704ef6b9042dc42d2ec5d281f137de7795f5c1b80596d5a70e34b005c64cffb76c4c9d68c7bff1b57c60f080c780cffd8f8482e8c16f8e15a3fe87a19ba0c8cf21e78a65f4888cc9483bb7fa2399b3985c031338561c2c66f9761c29a7f39b5928f7a96fba7da89ba2dcb4ff28efc49da5ded0c9c6230c89d7e99676c1fbe80fed125054cf6d18926b7a1f33e167433ddf9fb2127f98fce0d8f70e9ff76b386948f38ee2503da19c87217dfdea6afbd0dfc1fae378554d55b425bbccc701f69c91be31c047edee9a37a542dd4d5ba8f77c6073727e7de82d2590f645b994e31b4e475ba13a52336f8b96ea23b55830ae79c751acc3ea0931b6e752e8fd2e6bf1b52a41a8e365f7a8dbfdb47fa047d757f4f4b3a0c2f90128cd7cc49ee8c20e883ffc937b53979ceea530fc57a67b65804838f5cf4ffbffae70d78f6c29e0d5f6dbf987c6cb9523557840964ea9e573e11abd44913135ffd658b6c5862279efb9ee4a0026a23a80b31d61542571e57385439293c62cf3818a8b044f0cefb78657765269e2a03aa20f070683a4dd948cce189bff5a1fee18657e3a11a1d9197006e95c17472b81d0f73625390358228262e71e20764a960c1761251f5f0ad62eb667d31fc796a273ec2c181f7e3b2e75c9268c28199548ff1514d38691e307ee31299795c98182638a8ba38a2f462f51396270c093d77cec18b4ac99edc3dbb6f2fd3b91bc2e47b922e1f3773002cad4e7e200107e365fde93a9b64fcec2a11cbd3a53c1e5c5ec0180c7dc3a88d81469006d5af37439269ad0eca11d54c46d55b7038716f791ec01a8251d00cb65bf73ac09707af1d0088f355fde1aca704d6d29c48a734ea8fc7d7b66c715a182b28d8c8a61f81518ad06c7e1ddf3c702868e92e3749df5c5c63bbe7f62d3889e9ec5bd5a3f21c75f9873deefe0957851d38bfa4452e019cb59f6704212cc3c9d5aac803b98e162f3503a7a19f50f5efc50802c001c0c3c861ede7dc622cdee600d9091b365681b1e0aea0dc3ed685c53d7ff8b7fba02c8de07b95d61ea7cf0270785897de290ab81b5da2f54f05638498a23fd89fcc3f93c8d7fb7e2efe561d2c128e119bd4c9b78e6462a66dc8cfbbaa98b406f59602070fc6351cea29efad12913429d1af1e9b47dfd9c39a0a1835d578d9ce2c66d236ed03122955e1687ed3772079e7fc14ff72e1791a89d8f4dc1b4ed1583412c9afdf69642af255d0a3d5b1184193c3d9d1c7f3d1b8f408d1a24458920baa4221300a8da6e98fb486992013ce0080be5f2f366066aa1428100b1f47f3d299d33f3a146b11f88a54d5c582003a8acafda7e2249b06fea31078791dc6c89c6073cbd17fee0a0178691f3a8bf6fc7072142cfe1097ed8f7b8a11cc7ad1eac2a3f0bdbc32b30b9b223dc6d2873b4e7bdd7ab11372651f6c7a77eff0f797b42fadd48e0cd6ba28e6779a5c50a516a75426da820fa9dda08788b4b3639ce7c03b21d644d8906970eaa1444d638bb10be3cf01b7e48054e04f7f03994305bdbc0e2f85b4e8dfa0a320e288e64fc3635acec94c1966d2aa3e258bf1e3ba7267a1dbad3fd672f28326ecc7994f99bfc33c3dffcbbbddb194e8049a0ab45f977eeb2854764e668f019a2cd055d24e837c261bc30ae2dbe71272e44647681857f82074e0258f411230e79eb3df49290e47a587341633919aac847b193cb9a3aa5b03a911b2318ad8d21730cf5457f8844f53fe887846611f35c30aef86f77e1c3dc5641a0f38d99c736b0ebb1bd0efd8842c6ea3e575d0fc83f59970a6a3b0b82d685c859ae7592e74db3db78b13906df5db8dbf5072cc46d9b73ac4857438f72275a754bc9542564cfdd1bbad45f23c03f6929a90686282d3ff2b22c1630de14c5c4140b63281ba06779b80aacc7837ccaeab72f038663c1365ad85e515c5951cc324c0df5fb94cf8efa816b6a8f50ff6b55821ed2e5dcc355b3b0ca8c6f206d5a33f30e6d51c49a6f48ea067f8d755433d660580fcc7cf69afa8b81afcea8ce56fa1358a0e9a0826ffed89ac0ab01c32e12fbf2f8938e7ed6b7206c8cd7f284faf7bdb224252601cebaf4708cf0caf79d6911e7b7f0699ad0403f629185424d03e37de80a54278810d4859854592c80a8d868c4261e85ee2b332ebb01ce4fe9979d31e41384da129c48a87b664081b759e8b2aac6474ee7840ae04b5a336ce3777720faddc03371a4c7ddc3112c4fee924d8b96002c2f3c51033ae59edd636e28e2eae168d5fe21a19c70d9d755481a21cfa2b45f7a1a2c5b707c676212027a2a70d1414d222b61df192284584f8bd3221f640bf27ce24a48a1996e52153ff1d71eb5a5848dd2fdaa5e811bec2db09dc45c09009d2cba298c768af14194aa1ce6ad22bf07d264055123ecea8f8552e20c207521340c7900f48ba849114b5e9b49bad485df18390c2b4b112f1be2080bc001404a25a50eab7f003773acb60199bda8cbfc1c19f14adf8de57c5d442299a4de5553d4b2a49caf6fc4b386943b12f10bf2654221abc7227a9393a45b72e30f18b9ad29ea68e8475cc3a4e7ae65107266fecd565fb7c62571f86bfd144a8107599130994473c05f718762069a7de8332be43a4bd21a1b7c2d0da562612a198ef7d23deedc69c10f29ebd3e5cc9bd1142f29799ff92e58254f76ceac7d93b1858fc44be0550ab70efeaca05d911b3c8730edce6f5dea8739daadd86d8c7f229405808434e63f92bd7a5e9bd013731ea63a5f5f96257da410c7c9e2f0b5eb4435346b2a5b278020e991cbf074452e048bbcccd6cd37fd20bff9c59d8b37f87028acbf7833675437e6a8f822bdbdd6d55ce78ffab18cddd25a0b6c6bbbda4a565983441eb0226ab1a0436746760b0a39de82a8d945f9cb2d2aa3f9498d859daa439c1e553f269ea7d54eff10971fdff77ddf9034e196214bf15a475db8c318c88bfc4178542cfab259842141242bc5457d3ea06c2f135f66eee45280cccf260ee3a3d942a79d0ed370bf7cf5feb147c69c59e59942e44c21d6decd8a65a120a7e0403d93776f7f141789e104a8a5ddb92052b13aacc4e638b273b7a46a66330c3607279fa9e18ef448f6dce913b9d180432126850362921ecd5ecee1d008591d439e0b327122a9d0446d8f38998da0936a6d5ba442074cf0d2fb551b806ceac5553a94b0db55312a847ca3c35a85192d685faef3f9ee305000b5707c67ccf7bf5316efda9c4338222198dd85beebb13c59f0234b3ca94d73c84bc0eb8aeab5b2ea129d6f05c52c7039489ec75367fb10662490f82e1e0c6af070361312e9cf79e32c91ffe7cf19e686317fd371faaf1e810801bfce726da49f90905feb71d63cc9a4205623e0bc3cd59754c6306ff8eda75032bd69237cbd01287cb9d8530405f0ab68877b9bd9e0aa8ee432267d7af5b9ecc15d9525672f12038425c5d7abde9ce0403518b70ffee4a49df2f5045898012ecf026cb6c0dd9cbd2870becb97820f6e3c1ccef5dee9c841386ece9846ed887a74268866588c22d753822d625e5236eebd23bbbff3ee01a92f1bba22b8a1c70fd17baf1cd4d820ee3c6ba0a52afe0a86e3fef037c42da5e24f3e6f340a24d07276fcfaaf8ea0102dc33b05e8ff21d466054ff7c8430ba7711608fec67517b5eb4ff2165df2bcc2ecece05d17e5969353270a53aed14332d7c4d912a99727276303fb9c3a8baea3dc392cf92b20dd4b97f317a248decc7ae80638e1be9c75296fc8cffc998fa153afcaff3a1307edb209ba18d6c917b25a40b85ef1300ed01c389bbb5b6ec3600e63c78ae3c1eb2b05d24158aa0a56510719fae621adc8f5bfc2e1fd26acff09f46fbc6846bca42509e59045e535d9ac209d9ddbf7daa963035f762c53e5ca5513057d2e6ae2a151c673429d73cb45ce9d58fe5c8eac2c1e48c73180d310fcc9990b5db47b2940c1542099e497b8f6ff87037824abecef984a3df9774b9e4df45b05b5afe47d66c685dbb9ba84224d82f5707b5bf4d6c23007e01588ac3f89cfb65c19ffc5187083b9e08b7b77c060f485cf8c63c3fb892fe93a2a77a67ccbf97fc4cba0fe84b6279784ee999850cb07508bcb31e711da409e61b778c9d0ae2b52cac618e3f5c205264a0cd586507713b56246b756297185dd868fdcd35ece7f769e70096d2ed1e31f9ef3b465df0a4e125d43c2bbfaf0c1779c0870b2f2ab65a0fe95aa742a371f34c4bda98b4359110a739fc9fee704a44f7d6268e01040a07ffbc3059d3fdf8ec39ba96e81fef35dffb7624125d68d14e015561d9699c0a403ff1d10fd500491cb252c2abd15f5c214bf11966b4942c4b5234073f3f7055bdb357df38cddd24eb18cf7969016f9ac489f40c365a8eddda1a6ca3afba9791f411c213ed178ff0dfb83945ed1288aeebd382d064097c61db6c5bb11795cdb7acb8e845bcd8610d7629488a8b4bf062807f8860dd36e9a2271d62b3ed052a31653764a0b4a561d22bd266878f32a56f95908163512fa75b4ffcd8a3b3586b029f2084938e5ff26dbfd27e35d79de0318204a22404d19185ea7ecf6a799127ab5cb5bf8f9c15b459309d1f9e925f40a30b5934947feaffcecff16fc33fc9fd5c8dfe5dfa1fb99f63bfaefc47fc6b99f79fc59f433decfbffddaaf768233507f66fe2ce177f5affdecebe77eb9f3fb4b24015410027e2d45c00c3080b442e5f030c30c33cc30c30c33cc5a4b2585984d994b45ddd62969a7faa4a44c929bb47f9292724bb9a5bcb37fef4b310d7f0c830c6883e52c052f2ebe7010b41aec97b4217ce935b892063bac3f6c0c32833dc7bf2138fcc24a065bdace9d0821e3431983256fe87e8a7ae34f00186c9f918b26cee4fdfc158b173f79fd43e7bf5db15ae51b73d405e10bd28a6de2ea9f898a76c1acd8c3b91e8308aaabae6271d0738fcbc18b82aad822478e2c7ddc0d612a96ba345d79f2622e0a2a76ca8c7299947a61e4143b97175cdc85606b9a622dafff2fcab8a01917a5d83148a49acbd0d322c53e8e6a572a6ef3e346b1895788d417a6a92d8a1da408f2a8e2e7e442b11735fe5ee9e213fbc240b1797a811773813e7c413eb1834df895b8ce943db18998a84aac7c56756287d45d58e5290e8e0b4eeca0299e8b8baabc2864137bc388875ace53a5269648625efbf83fc9c4f2e3c520ead9e53630b18a84d5f5788cb1a94bec11a526ffe3ef828a2576e666580f1f95d8211739be8d12ab9d634a25611994935826f57f911724efcb49628b7a1a97b98b6f9c1189659d72793dd4b21d126b6ecd5c86663f9347ecfc2036274c8889c8116b4ff408392f57ac1bb1797e7198cc45050923b6f5b4ad2ec905b62d62a9ce7e0ca6d352a588f552ceeb82e8dc906606908875af27848c1c95563211b1ae4eca8f29d2c5c55ccc21b692bc4cb9b8be92b921d6b5f988eac50529c4b68fd41e4391e7cb1142ecdf602ae30ade20f694474bab0ce63f7d412cdba844cc513c103b4a6692947f1925b300b1175d55e385179896fc87c5e2f9398e4809b5f8616d946ce6c931a8cadf87f5f24846de17be22271fd6c80fcbf156e5ee2ff6b087881705f9e2fedefa420f4b724c5e90e9f8c595e73c2c1ba2e618945aa4947858b6baa62fada249c3efb0c494f0eace67e0b0db612dd1bbc887f9a315acc3e6d8e0ff24432ecb0d1d166f94921a85840bdfe7b0c57c609efa8c1cb68cba8254feedf5e2280e7b35d4f4df2fec4876c36151bf8712a763baa6f1862d7add3eb058eda23dddb07833d85e90d0d023d486254de40bbb3472a67c362c3ef9c58c2e2c9e49c61ad67df8e18d0bf641eda786e556c531acc8855ed8751ad6460e96ea19549c09a3618b0b61e476baf9ae3bc35e0c2b7c3755b2069a9b61a7641e19a84733985c199670a152f4118ff0359361fd024997dbffc5e53019c3fee0bbc88ba1535f7e8618d66f90ccab7752cfc161d86e4f2a49797675a1050c4b6c7f91ed6d838afe17d6e98226c7851a0db242bcb0173ec686dcb491192e5dd8fa72857990e7c2f6a80bf477d4ab8b8b315b581acaa52f9e5ec745266b610bfee963c1318e956416166f38123ab77271cd8e851d3ac317aa84f5142fe60a7bfe7753548815f63107b152b053c9456b1596e8b0d3730e34a7472aacf538696bb91557196618c01496f853798fa1b7d1cd4818801416cb69ab9137d67746617998d8aa7c71d56383c2a2f1a0d224470da12b3e18c01396fdb3c9f4c53c51224e58bc60b51e1ea4b9f21a973080266c0e961bbf2849ec7c914cd881d95ec6188fa9834bd81e598a1ff6bd12564ba1f4316572f15830097b9117c4798183a59360226107167fdb0d73f3d51f619fe642f5a20c62e432232c16bd2cc74fa660292ac2ce1d8dacc632052d2f88b07a71e99e85f9e28bab0d61f57aec6c2835e34c0b61cbb3c6f45f54191284fde23c1c66751a3c03c29a5f5f14661b584891f2832596d6443959dd6dce07ebc373262f14e7b1abf4608b5d5c703a71fb1a55435cdb69b81d41dec1d62717274b2b6358193a58fa81e3ac982ff8623207cb1779a1845e4bbda6100eb6c745cf4076e2cf46bac1964243f2e2fe0cfd306db09887a5e8c59f5ed5b001d460874ce73e87b8670e1a000d96caf8a781830c2bad170398c13ac10b65e6baa8b71e320019ac5ea4e233bef7c8bce001c460bd78f31bfe8fb9a80b1b000c7646121f12673fe2f3572c9bb75f5c78299d86e35cb1e9e5c2cf2fb8882feabe15ab75e47e74488cf84856ac8e967285e40ffd1ab58a1dbf3066227a4154b143edccf96628531a49c55e4ccd209f1fff3292a0623dd5abafda49e3c5df29f6dec818bd5ce943ba30c5f6382f635c8c5d5cb18f521ccd5cf81cf720c5eab9eb5cfcf01ead3da3d851ec82cb1de1d138a88862d98c183f378d112617a158d782498559799ee400c5ce94bea851379e4859f9c40e9cbff0f2652e99ca3db1855c5cb06afd99eae075622f08d18bba2067772dc29cd82e4f74b4de475fbcd32616871352542f7c1e17179a58cb312e66a8abaf46662676d8051d79caa1369a11134b45d549f514b441865c62fd82d49fba9a961bc4123b173fe302dbf45d0da7123bead45d486b9332fe94d833a40b6abee021d62993d8e2ef5786ce10f5b04b62ffbe493fa1c2e9fc1e89c51aa567c56d4e9c1d12ebc454def4227fe0188fd86942b29e5c5c9be79023b68c34f5822aaf115b060daa5e5e297c51c3882dcdf36a2ea647a369115b9471cac593fa9e4a55c44e29f94e46a19be2c389d8a146955544a724b97044acf1851d8ef6fb436cb90bd5f4a46b432c8e0b7c279a776b532bc4d2c87131c811246e454e88e571a1634c0407fdd718c45edcfce8f29dcff3658258f2e983c6d493d44f09c46a96616699ff173c8d80d8ccbe687d82447d48973fac96a21bbbc8baaa8b563f6cc11e84fb8a72f85ffbb0d8c58306a1d60c3de1c39e528ee1e4973d2c3f114bb6aba40b75d3c3faf3053df3a0ae2995872d3454bee8db89fb0c1e364b29831a3309178fdf61f34effb094b9f0d6473bec79d1a9e13cbe3145ebb07a048bf9e9ccbe2e900efb6f17e3c26e0ef5c77f0e3becc529b12e6cbca3c9612fb114e743eeb4bb12877dbbb860f2d417eca389c061fbd1d25013c9f90dbe61bf2ef2d16cfcfbcb1437ac166cfbf9bef68bba6ac3d64556bf4fe6b1619baaf891d5285a2e88ad615f070e4e5245189fa41af6c2c615cf4feaf428230d6bd9faf77f51367ac4d0b0aa599e83cc20e93dfa0c7b79312ec8d7203ece39cdb0cf68483f92ca2e78bc0cfbde78319e7cccc8c149864d72918aa73e6a8c3a1fc37291feea4f22e4d5258625be48a57ca5a1719f61d81b39ca8314b6cb260486652ff6f5fa448edef6851d832fd38693341ec45ed82bc71b7d312ece49d77561092f08fda8c7336b2c5cd871a9e5edcee8af49cb80c51656f59bd23b0bb3ada711586861fd42c7781cd2171744860b8b2c2c91f6a2c157bce846222d021658d832d623d8d35ddd973a042caeb093dede452f9eb87c5f5861938ce22087c33c875514b0a8c2a2b3d3459615378229a803165458b4d6714efa6a8a2e060448030f584c61892e9cff294779c80317a482159c40052bb8c0165ba08004154001094880675ae8010b296c4dbde314aa32a9588a03213841035c50fe1d801739c0220aeb7df64ff44b1965170a02a41999c0020a6bff34dda4bbac9f140448ba000d448038900215941298168dc0e2094b55491785b05d346212fd010b27ac5e0cee6117983a2ebc10042960099c0d096cb1450a16f080079402ee804513b6f0e27ee0e82b56d22e1681051396906ff4428a57ce05211020d5e040084eb005e1b6b1062c96b0854d87728c0fbb982e1020d1165b9c200422c8c0165b7cbb40052150c1165b6cb1450a1ef0800a6c608b2d1eb0805112d8628b2db6e8101c0750f023e8770f6c715159d8010b25ecf0c5209c6869173dc5408084495852aa2f7caa8b0e2d6420407a149c60d00234108105bc000b24ec941b98a5935cace34080b4821378a0c641608b2d8e80c511f6eb825c58c9f4a24f835b6c91021198c0042030c21e8d1e55729a99f06111361d5f2f3c67f8dcbb614184edee4153fe7631841dd68b812547c962c7888510988d905d4c9936231020a120041e20c20e6011842de5d47b24fbd1dd0c0f78608c126c608b2d9c800510b62af3c28f5809cbbe418069810e78a00558fc60fd4e67b4270e233a0502a48fc0f8607fc6b16929c6c53c9082104c998008fa41f0002c7ab0e41b7ff0402272d13f1e50c17f0049051f81ca01163c58ab23bab252244e93b583bd31c87839177d917ad143073bcd85c385e00cd9d3b040073c100021609183bdd1f76737f3d2c48f2881050ea6495692634f1ff2cb031637e8ecc2579983918480850d567d985ca9ca05b9956c01638086053ae0010088028b1aac5b958ec13967a2e44bf08110a4e06680050d96beedeffc228bf5008b19d09043c3d6bfa13997011d29bdc6d471a48ec12893e40851a41c1ec8f1062c60b017af8374714cffd6f7572c5fd67026b9c9ab92aed8ca2ffd63e8f478bb4010200d290e04d08a1d7e41ec5d79d4d32edc060504c08af51f5ee53da72f2eb27b011a88c0029a51b082ee06a0e05560020ea8a0044f02c2820b0258c51af5552629df9978a18a1d671768989da35095610201a4623b33eba24a3e79c2178c8aa5721788a4a49f10a2758a2d7f51f8ae70eb317d5e100304608a4dbd20725a06292347469562af20fafb0527c161c3a4d8672b4ffea2937cdef851ece074de14721623a442908210b04017a08108a82004290801073ce0812db6f02db678087880100210c59e17eb3f24af20407a0a6c118ab50bbacb67f5bf51761020b5805130e3020200c56a35a98b5208b2155a810029891c20804fac5dbc9a0da236acb25406c69080003cb1a5958db3957e0702e8c43651b1514aead8e9c5451104c0892d65f062385f10e6a00b0ce658177c58fe2ce4a43cfe94af3decd7a85197cc1bedd2c336f2a7937a1397ab3cac1be7406fc7a3fc81872dc3cbdc2f4c8b8b8c3becb87b5eccd1b0c3663efa636b27961975582b4abf792333a4890efb3d58a4f2f5c645d3c51c965c908eacc4e9b9a30b39ece30529a99c3e358c2ee2b038ea828f7412da0fba80c33ae3685d7e710fcfc51b9610fcaa391b1a8673e1864dc2b38bd18b442c632edab05a2e0eed95e6820d6b175e66a420c9cf52d6b023c9055e9061c5492b6ad8919a4e4c75777117250dcb1764101ec7d6e455d0b07a7181431cc79bfa9433acabb1395e1c5d3bbd1976cac511950b3efd992fc3dea0fefe4127c38ee1ae31d584b0e118b690a13bbb30924c4c0cfbac6ca58df59a5c84617310d4b1c1d8d7d560d82464c8cc0afa51f517163ba7f38dee08a1f6c2cee9688274d685e5416ca835f17a245cd862278a3ea7e406d9c2328da37f3bba98632dac158f1f533959d80b8295748eaf6c47b0b06f44fca38c5c614bbddcd554eadf05b1c256c1e1ca64cd7717a40aeb7ee96765948a3d15d62f6a1ce19ca59af21476a4d9db9b4961fd229b1016ff723e1c857d7c22ea7f7158faa1b0daa3f353fe8425c33137d4ea84c542fe08996e42c1bf49fe74a24c584c2aaf4cf0f21475095bfa9f8cbe702c75315409cb17c7351c95a8be2461b3eae2ae348f815490b05f888d61329ecdff087b316e45e538eae2dc083bfcc90d2699852eb8085be77c8e1704d34626115627f18be3bbcd610e61e74287f8a02b646aa41036cb05bab2b6935224087b61f7c817e487095120ac631f16b33288ebfd60a9745f28e51b5ee805fa60c97b3c95cee146853d582c3d6a98e4053212f260cd2eec86a32ab9c8b2836df4bf1c4f84435c079bfa4fe4c6e497f21c6c519df145f17e2f8d83f56672173ffc459e6fb0996d3c8dcf4a486db09617fac503d11bb1066be42e861247527f7834d8c17ec1dc9c56cacfcd60cb789c5f5c600f42730690c18e6ab91b5ed4c5a834400c96a7d08f5176e144680680c1ba22711de5f54dcc5eb1ed34c3925cd445dd85b96289795dd43df9562cf705b7cff5c55cf05db0622f8c088b679579ba8b55ec4536fbfbd8852a36399d47c1cb71e3e222153b6e4ee58f861bd3052a9648d1df7cbe87cfc52916f9a22e7e7e9ac64529532c21b3b6c1fbca51aa14cb17851d47490b9b1729d6c72058a7669fe6358ac5b3617f777c43bb44b11765c3034fed2f86542816c7b8316c17058a352bacf1b3ac741f9fd82c8417173f9ad4e01e9ed8f24e2ebcfdc290894727760c26b9c031a3b36e7062bd09714d93f3cfc5d8c41271299a04f1427b0c4d2c325f5c27eb3c17a64cec5d8c8be70b272389326162b51cc997a39b23d325164d2771da98502b5962f199eda22fe8754652556279864b672a9a235251622f8a2bc9496bf00faa496c8f0bd5223f48ea864a127beca77731fa42b17e2a127b832f2e8af8a220159f82c40e61792f8789e437f5884dbef6ea8b56f2ba9872c4d62836de06a6b58da9462cc98b1fbbe3c288f52478ac1747a6189745eca8219848b84c911645ace760c6529e5eca4549c416c5d19e51b86b5c14446c51170e12b93852ff432ca9ffebb38bc21e7f436cd29712511d3306bf10cb5ce38ae9c21bb39e104b65e862eae807b1448894f9932964e805b14d7a10c7f4221ced81d8bb18c4f8c2887a0e71406c5197bb52708c22f91f76c6696bf9c2cd45ee87ed415e065e3c99c2a5fbb043fb505fcbcba79b0f7b819e6f45bc4ce5e83d2cfa999751a4d0a5133dec93ebe9624cf2b0c3af54c3ebafc7e361c955a972419434e47758f2a45cbd8f3aaada611dcb17254aaec3e28f64b67fcd67643a2ccd13e6c7e339ec60ab82a663fc1162392c59e705292f533ec471d892438613d3bcc153382c32b9a3d249b4fb37ace75dbc1f755749926ed8bc1817e617c6d98635b3a27cd2a30cd364c3965233652e9b942dd7b09dced9fde95e84520dcb04897afae242ab4ca6619547d1a8cd2e2ef2110dcba4d82faa1bcfb0a335e9fe88265fa319564d87106bd40d1f9661fbe29d58ce38a6ec23c35222918bb9482a7fc4c6b037dcca2e5b2f52d9c4b036e66260b9931a432d0c3b467c4f03a9f4a481610b17718eb20fbd18f6851de6d40bea51aa19e6852576c1d4e58889e55817965c142ca475a558ff0517b6eda27c0d65b94822175bd81b494ad5edeea2e48516b6c84dbfe92ec85fd84516965fed10fbb17d5c5c6061fbf00736f7c50596d61596d11aafd2ca7d66596153cf932e8ecb38b6aac25215b1c67fb491174585d58be24878d137372e6a0aab5fdad0f4c2497b9414f6ce9af0652219fe118555a70b5792e5922e7e4061c994e1dc642841d2e3096bff4dbab49420f370c2fa1522b52fe3a21c8f26ecb8e8a36922855d720c26ecc515191717838c8b611c6309ab897ecf9e77317c8ca184e58b2e552e4c93b04aeaa25e9f7534261296994dbf46b1cb23acab2112b374a43f23ecc5a02c3c99f3548ab03cd45eae53a67a414458bb22352e0cbbb279084b7cfc450e72d5e52285b0237b8ce651175f7e3382b04c2e2e1c9f08dfe403612f8a1276af71f1ccfd837d52ca8f8fe362ea83b51c6a32c43dd86189da455a78b043f54c700c698e2c3bd853b6be98411c92570aa083551f75d103afd4f8a21420075b34c31bff825cd14529000e76e8e26250952117aa540a70833df772338c8a8da614c0067b3f99ef78a1a5a67c016ab09e63f8bcca48f9ff02d060e98c5e8f4792667f0166b0c54a5d0cfbafaea15f00196c92a99b62927dc3be0031d8bfe87366be0bfaa32f000cb6d8d0b914d6a13fff8abdb83a72c52e9c9bde5db13a4e8f8be705f9b0b762af89e65b954d937356ec5b3f192b1e4de47c153bbaf14621f145c973552c12767e463245fbc253b14fa420a19afb9b0b47c5922145efca7c2ebcfc14db36452f869592cee1a6d8bcc02c4555a97ebc4bb1c5b95427eb9342dda4d81a8ae46210f7e75d8f62dbac2fb4919bb017228a2d4efdd39e17e5e2a290506cb75eb4162b17a30713502c26f12aa2483eb19405cb076179bc20e2894d57fdd252468dff4e2ce95fe8409cb21cce89ed9c419457ee2ec636b184ab340e91ba19d3c48e8fabe131218dc499d82bcf3dda2f92bd8831b1765ceaf1868d51b9c45e5c34b79522679d5a62c7bf8e233f4c17c42ab1daa86410bc504aec238ecf8b7f328e4327b147a58b48bf24762839e36019617e24f646218394143dbd87c4aa72195c849fd8fb23564d3d2faab423f6e82a078ee139bc68c432ab998d95c11755c98875ca8bea6cf7a39c5cc4f6188f5a38a9882d3d08b9d09bb7cb4fc47a124f322435478f882553c73cca0fb19a9d48906f06b930432c99f514bc53b31e85d80b2f7e8439ac141b24c4e2b95e78e1c50d6269a6d9c74f105bec4afec7b810d10bc4f2450eae52b0758c3b40ec859691d105233ab9b83facf27b978275355ae787f5b471f7e402fb7a5c1ff69595faa2c697533a3e2c19e50f2be57db2d81eb6a998c8c81a9ed8a68755b6cb6953c284a8e561bb5cbc37f90bce3e353c6c127b97c1a40bf3b43becc0bfc22369873d257a3166aa7c0cd661c790a3ac52081e191dd67a1e1bf3f1cac5d81c36c7455db5f9c585cdcb610bf1ba502a9b2ad871d861f6348973979d705872eae136e5e9e2e22edeb0ec89f817e322f3e2dc0deb7f31c685151a3c536dd8be68af31dd552e6a8a0dabfef445ee54ad94352cdecfc520c58d9c1135ac531eff78ce67b634ac7fde90e262894c030d7bda63e450bc7eff336c299ae441c736ee66d842468c24e10c825a863de6d3228744645892a5b01dd218966bea22877c0f9d17c35a3b21c3cf31be6818b6e78911e379219560d8d3ef2a3208e2cdc517b6e9b9491bd7459531e485a5caaba3aba19d33d485fd77b5524946d5457361cbfd613af58d41b285352e989e7a917717440b7b31a68f8b9fe6f14a1656a7702bd54cf9ac8285a551a35c54f65f610b7932194e8d0bd2b7c2f2c8b361785f851d452bd4197d41d49e0a7bf1337a7f71dc86e3a7b02589530e2a8ed67829ec5da69bf3f9e8178fc28e31ae5aba9873b04361e9cef99ac62e304b3f6149fe272a999946d24e582467a5df5907237713b6cbfc90fbb2528e9b09cb558a5d84f0456a214b5827549a901a2f468528616f5cd7bfcd05b13e49c22213d65ba9fc8b7b82842546caf033d25a869323ec2035ace7746184a52a786168faf317468ab0e4da64b8944af34188b054aa78731aba7219c2963e53b1fd28bd2842d82617dcc37d545c9383b0d59e17ca8388d9053210b64a7517215f10f5f807ab39da64384f9671ec831d6de6eb1ca5a3dd834dbd203546f35fa812e5c1d6b35e24217e31235177b0c44e443e2ec6dc40d5c1a6d1204509166b3234073b088f2746fe2b6d1c2cd120a68f575a9f6fb03586d818ecbfb8e82684cdf6b457bdb72e7a1184d5e7bbb80be6d38ba11740d88beb33f4622f23ede207cbed885afc7d34791f2c13b940a5fff16bac1eec8dc90b672d35c9583cd8d3d2452edce78b5bed60cf4d4db310a2d8a374b0d5f74eea62f0fd98cac116ccbb40471e6b263858a546aa8b6bcc627283cdcb36b6928514641b2c29f95452cb2f2a71d46011331bbd14bcd0c391050d16754629e6e4ec42238b19ec50b7823d1717c47e461632d8276cf47e39c885cfc822064ba4eea2bc73a7716701837552ea6248197931d5f48abdfeb22a23e48acdb14ee5d671e342a9154bf94a2ed0bcad5c112b965bb189d89fce0fe52a96ca7067bf12d3f293aad88be269b31c93a9d8312e486fda6a0a7912157bf5e4085f8c5184d8e429969e7819a53cabf5c5a42976dc2f922e9208ea6b29053dddf7b05d1452ac71dd202f3d8a2de5063d1e8d3131516cb9e217e759379df6a1d8e75234e74d54e6e241b17da32f2e90a673e8fc27f6c7208fbac841cacd7b6253cd95ae99af74e9c41eb9e871e117dfa7178513ab64d450958b60f94d2c1975e17f93d6faaf893d521739689e89e5e1425a3da7c605c1c4f2575fdc393fe5eb25963452e245e1617a6789d572e5a5f4c22bb18d2493f494d9bf9c127b7d5185644c65a47c127b43bd2e8a674b628bc619e11b8a6fd791d88b1f2faf36ba68584362d12c89fa66eeaafa117b37c6e363be919b38625bb3a015d3bcfd9146ec9451c5f5c24a5ee40561c4f20597fac6ef523a64116b4e9c8c2edcfde29215b1694ee3860fca21c889d8513f178f365a129111b1d6470ade97e231e4436c294853643418eb820db163080fc149bd301e5c88edb92232bec0f74725c43219a771323f5da883581bbd287cd1c959c8850a622fbc708cb6719a930662f16894418e14105b48874687587923fdc392a3cd201ebe201af5c3feb85e0c25bebb48927dd82383e31ae7a25c5c5cf2619194e634d6d4055ee41ed6dbc694af61177431a98725ee2a4985f3b043b30c998bb14967c4c3b6bf95c6f18bf966bcc396377fccf277e414edb07df1538809621df68e0c73c20b42bc07d2618fd9e72e09fa450dce611579102725b129f1e4b0347cc32ec605d1c5d0c561b59f8cc6e371eb1b1ca8b8387ae5db1b96c8f9f0cf2bde9de6861d1c0507bb204e396bc372e6055f9dd34d9fb161c9307f3562395717b6861da3320bfe118d95a961eb22eb48df05928bd18b342c8eee7ff78153662ed0b0e5e6af4669d0f3459d61b390c7b2e932c3feb09b317e72265565d82a3588b29120da0f322cc9f134682ece88eb18c392a2c5fee78246298718d6b18e8ccb8b43541c61582c1e84cfc1b03cd2959ddcc705e11796cf075d549971f18517f6829110bb384e1a3ca30b8b4fb28b4cef473d17369f3c2ff42e546d7a0b7b431baf86a3e1102dec5c3492d3fc5342cec22231e7b9ac99ee222c2c21835017b151e6afb0e675c446aafbe6adb01754ee483e9146e12aecf1dc0541367da3a3c2a25f909e6bcfab4d614baffd28098e5f486159cb9b8b4ea132a2b086648ce6d8201476e6e2bdb22f069fb0a410662be4641a17834ed8319635652ea8d028a509eb54f0ad2f88f8290b1376a07191d40b4f9a2a4b58ad4257ce473d4645099b67d65a9cbf46964fc26af98bb46133bffb47c2be5fd4a1169b2e247f84254fc898dbe0bf607d236c67f1b3b5635fa47d11f6713a9591d8940b7b22ecdb301d8f66e4a28b0f619d55077a92226fef42d84aaac2191d84655246cd0529f73475202ce228c5e3e3d4d1fc074b2ef82e0b5d5c90f7b80ff6c295bc865cf45cb0750f164b5d5c50c92cff71d13cd839b51e9ca6ce8b263bd80b52ca5d94a30e16af0ce79aa01a19c9c192e4d145788c243f0eb64c3a97a6df60ddee8bcc881160834523bbcb8bf1c18b6104d460592f2e48f277e6dd5004d060897627b3935e347a2260067b913fb29ceaa2a079224006db53374e985edc241110832db4247bbf303f268900182c2ae98d15756572be62edc978277caed81e4e867e769ead58beb8a8e2aedce5da58b1ea55776723157b154bd58833598c6c17a98aa57241fc825cdce97f49c5aa1321997abd988b43c5fe156cc3b2e3f353ecc51dd10bd20b1c5d85a6d8bbb850c4bb2fbfc02fc5d6f0c5c5b82817374f4e8a3d52ca4521fd2474318ab529cacce38c9e5a148b547e849a5c5c14d250ac31fff15fdcdd0140b1f9fd4df63ab078ee0ef0891d983f55d28a6b12bb037882bbcac65ddc7562e9bd88a2a5fd78334eecb89be471514af128dbc45ea09f16a33b6c1fa6892d38705c1869fe5d8c6562398f09f569e605154c2ca316b3c1a49fe69758ce2ecb9f1e25634b6cb9a2c41a7851892d4b561ac2d31e171794d8baf0e2e274e4d7ba98c4664126334ab50b8e0b496c521dfecd57249610baf192889dc50b124b1724ad8cf81d7ed72376188e4f2af43143cb11fb9d9564beb0625e5423567990517cc1a39aca60c40e1c524a7627f10b1e8bd8e7e966e2a188b58283584e4f32de48c492c2449f2e0a9ed20d446c9792f352184bb9c621964793496b2f171736e30cb15688e7b98f724e9eae107b783196fe34ac98d3116247e1d20beb192f6f748358e2c2e9c2cade6d7482d81aa3b8e485bb8d5fd005622f7cde2fcab50eb741078825452b86ac7fac64ee0f5b4e8ca61c12e3e89c1f960a91561123429f737dd8a477a6bf20f67235c7871d4c481ef685a39231b7872d5f3fc3c97e1c8f393d2cd2fd30ce79939fb93cec75969265bce061f3bd70753b65c152eeb0a58a36952bbac62e76d8263688678e312a49a9c3e2b0bf284e88e52faed0612f1a890d2c539d73650eeb5c5fb8a9dcc89497c3d2d12929df715862c8c57fc549cc70581eca8b0b1a9d7faf6fd8babc463ba72a76ef861dd3d6410c099beadbb0a8ddd417a5ca5f0c61c3da58a1cc6c3c42780d3b6c53f22e500d4bd843869291cf6d69d861ca417441cc0e8086a52af433fd7167df7680336ccd10277c418585d6760033380ea1a30fea326c910b2a6a6e438d0b21c372f9e05333a9422763d82cb7329c0cc2324ac4b0fa494488ecc7639230acebc5948fc6ff72c560587291a3c855f2470ffec2fe253e5d217f395cbdb0452f94f9e29eb290d42eec38db455df1c1e322950b3b38589a8478675ee81656ff6a5ce0205c984a6a61fbc26908e11c3f43330b7bc145569c34b1b076e13df8228b0fcee515b654933311252587a515d6aa68c129ce42335985edaf1aba988b412ec6910afb8fd8587afc34294e619df0b848d26ccf8d288525764dd446fb42cb6114362f48cbdb17eb8d0b84c2fe5319e8767ecd7e4fd8cb19a64ffa9cb066a54cbd1165c78b6bc2a2a297c30b92cea430615fdf2fdec899ff4559c22219175da94c2e48bf12b6abe8301fff0ce624ec2859c613a47e7a45c2e2a791f78117e77d47d82a4fe4e282098d42cc8cb05cd7e5cc7b26adac085b69a3f0a994715646846d627fa77d51f2902f86b0c7177fe13554a44d17425824bdc81e74713fac2b086b33b414fe2c202cc99ba7faf41f437eb04803df2f6c2e8c527db0e676e1348aa3073b682599f262f06031498996d70bb342dac19652485157299c7e413a58a3baa00bf21705b53f076b844891488ee160cb089d8db137a58bb11bac9df5d5a0b1c136b531497332b4d4608b27eb952725bf69b07ca13f33e9234bf20c7660abfe28471e2a83ed46825590993335069b17599fc5b01c00066ba394c53d7e4a2fca2bb6711cb1bac8b9f0328a2b16912f46b1648ef2c55bb168aa171777f1e345edacd8f2bbc0474b5fc59ecf545e4cc9a13e57c58e0bd69247e673f1e5a9d86caa1f1733d5dea551b1350ab26662211fd2a7582db2b9482b793adaa6d8c2852f98ae6429bae8526c599532883b0f1a3529969cbb24199517a4a647b183548306e1e28b43228ab52f45919f06950b23a1d82a5f9ee6d328c710502ca141f02f942d6b9e3fb17fe4bfc6912769ce9ed80b2a467cd9d5a4913bb1598595df48699c282796f80571452d5459aa9b58a22c7dc34f532355133b2eca5f705f97be28d44cac8efa8f427ca5648a891de59ef4f115f5492fb1864ff3440abd18a925f60211199f90e38b8bd14a2cb5132e6c8a634792127be15cefd3ce543873126b46a8ca0f1346ba4849ec142ce4bf31cbb832124bb464a71f412b360989e59e74b229698a878fd8ec52ff252fd4f2e2d011cb582ed44d0ddfc80536624db370d785215b9763c44e1d951e4ee7a4728b586a529c90d26a24fd14b1749aa3fcb913bd5b22968df350ab69d01343c42251afd2ecc34ed80eb1635c200e26678658b64b4eb39963bfb0422cf1f08b8bb9f21717a58c10dbe5e79ce4e7c545960d621f1309fd68c66e3241ec8f319d839c95d52f02b146cacf5f9093f1852f00b1395e2f98d470e4c48b3f6ca711eb50cce6bfb8f0c322f25d90511dfca52efab04dc805ce95d71759de85c713b117c5cb45aae23b611d47c4f63da315826f832fc60fb14ff33dfc8af3d3c5105b3ea65cd48d71173d4a21d6be0a3fe220ac6314426c258e17f6bc30c21ec40e7bf67e2d85bd5a108b76518829151e251c88fd0ba5419234aca802622f10b10e0971a1df1f76e6c96169911917e6872d177d17397ef17dd81c052fbc9beee2efe2f9b0eea3065fb8b295a3dfc35d747964377a3daca9a1795a9352359f87bd19956a737d3f88e3618da895e6461d950bbfc39699cff6f1943cc6edb05639fa82bceab0f9e547f9aef9c1d574d841ecba73c81b9b7a0edbe6d433e582c861f599a05e8ccb4184701c56bb248f8d61382c5dd894d629a4bd10bf6191935cf4c5c5a00bff76c3d6e8a18c65e0cca5b66149b12faa095f3d51d9b05f1ad187122d6a17ba86252223279906f5c2d5b066a6c307a18b4bd269d8ea6f92833eea4ed1b053f2d3fdf4e2f22fcfb0a3c38455871e174a33ecb82025b93cf9990bca326c9132cc51322c416239cee7c8938f61b3cc375fb86b1f2162d8e472a54a6118d6467932c82fb0130086ad62f45d59beb0acfc8e4db0f0e37961799ec827654f125d17960ddd8acdf8e282980b4b9687e4ae6033b92dac93b9b92825a33bd3c2b60d9a8bb9fe1a17645958f2e5ed8328b38bb1b0e5252fc6283aa506afb05df89d145369b5b3c276219e4e5b15f6c2cb4f6bf949001536dbd2df188994f9ea044c61ade7825cd4952ba3ae4e8014964621c9c1786505ab131085bd24cc4e9c0714f6a2ae07b95045fa7ec26a72dbe79bcde33b61dda87e588d1c3cb209eb997a9184abfc851f1316ebb2ec5fcf136d09eb69c8c546b5e9a294b0468a9ea79ee8820c2561ff82ce8a355edc057124ac5d5416d1718428f5088ba45e4999fe77bd30c25ed87b212e4f3968a68bb0a4a34692eaeeef89b0d77d17a7d663e4f021ac8f1eac43e6878c0a61b1adeb223bfb4609c2961abd3278e4627815202cb15e10d39ad6af1fac8f0d8f765e540ef7c15e9442a50777691bdd83fdeec9feb1e31ecc83bd276ee5a2cf6a7e078b58d8a6adf407eaeb606bf8d38b9df977c9c126abd3916a1cecc5946c4bd51b2cd717a29ffdc5356db0e32ec81872e9173ab0065b2efe6d86d2c8455dd0e03c95b88f2e270998c15629faf7bed642c3490264b0cc8fe572d445d6c53749400c9614b34130b5a706699200186c7954352ae3b30936d1e2159b794124918907d545132d5cb1a84c17757181e44839215ab462c735bdfbe851499a102d58b15fe4c22f483149c326448b55acabf2e00bf6325708215aa862a7fcb022aac8c409215aa462c9b5a37e314e2925440b542c67ba8ebb1fc99d8468718a6553524682ee48498816a620a5745d14e62bc5f264f18bd7b9b8294548b1837951c5b82e6c4679144b30d92f08592fca4511c55e3a635f1052482f2e42b179e3a8eb4d076a2928968c52f7da17463dc827b6af6cc88567194a2c3db13f7c9c7774d9543ab15326278d39b104effc89e6260679263ea6424d2c21582ee86d3013ab1734bcbed5db5331b1e48213ab242315b44bec615ed0284f47b4b0846b2144439eae128be4c39b0619aa394789552c238a4d7810be4d62b17c4e0d2677338849621b11f9997fc6c5a345620b292776f156ace41881c4f60517d39217a524e30579c41e11fae6b18bd1e52e8823f6ed2e2e4823b61afb62e83f5e92b9208c58d2d2e5e2e2a2738cd7228b58e56aebd64fbdce228a58c6fb1afef6ba602c9288ad31d066e4d7955211446c8de6fe632a9f2b831c6295b8b2465d0d42c82086d85205c7d457e1721ba4104b63fa824a21242ff06210426c2921bb20e32fae5c3091416c17a1275ff445398708622f797266b461669540ec8591416ea385c79507c40e4288d340bdbfe2ff8765227eece5ef87652d4ace873b1f731f166d8cce450fe191c88735f28bd71bbe20ddb6874dcc421f17e4179617ae87fdbb7eef1b595a250fcb8a846824e245c1c3faa8f2547fe964de61894939e951de8a54db61ab905f98111b7d1df62e46a99bfd0247163a6c695b69a7b9b81f3e872d849a91ec42098de5b0938c6ea42ed8b4c461a9a92edb9e5c2f8cc061edba8914f5c164fa0d8bcf7ee15f1c355bddb083c9a45f34a1bcbfe0366c21bc1e52faa2907b36ec59171d484eda8bac61cbaff0f56f8c66356c5e9032547ff5799169d8699f0be21bcdf987864525a3df0c6dfc8d9e61473b2b96b319168f0c27d79e65d8fa29cda49dcd2f9e0c7b5e88f0dcbc53f9183631e7b02fb2e460a218b612eb116b8cefe2300c6b7a7a51e57d8a5c381836fd308996715fd8428a23f90b7dcac4f3c2de29c18b34bb2e6c8e376a22e548fb7361e72fec66ee8228726f61b34b5f50651a6ba185edf3d7fe1bf7ec33d6220b3be482f2825c150bdbf58a7881c5875c985d6193132f982e883f2fcaacb046834c772ad122635558725d2e2c07de18a55c5061992ec80fd1b8d0ae723185254f6ed3f11752d8f285468488bf5cd44514f6bf1cd38ce2bf510a0a5b72ca4541f523d35f4fd8ae29e724fab968524e58766f232b17175d5eab099b35787591ca84bde48b223f3377cc252c1955cbbbf0762c3594b06d4c87470ac9d71949d8747261f78e636d3390b03de5e2c25ef9112fca11960821ec3835ce84901116b3b26d0c2ea35c5211b6ee46fd248dd45244846542cde3d89f8b7e08cb844d9e850c0b61fba2e0e3bf5d9192e1206cf16e7775f7d40b1d06c26297bb1b7731fc83e50b2265722d7e55c33ed8c2178346da395e90f6604d8b7bdf1832595978b0dcd88591b4f6eb951d6ca7dae3e02188648a0eb6ba114db1e659fb73b03583929fb090b53e0e96b52f0a5e94b791bebfc13697511a5372a1a5d8603fc71559971aec207e514aa970b6111a6ce6eba3bf3f1664d762068bc3a3c53f8f2e185d0b19ec64318d42adb13bd722063ba47874f6c574ddb91630582c6454cdb7161be5158b5855aeb85f50f9b72b16afa029d2347f7bb762f982f8911fa359b1c53cf1bcefe242a77a159bffa4a33b8b6469556cb9c71ca923a73a155b68522ff00641c59226a319eb92670839c59edff5950b35c5965fb45d107b32ef17a414cbe5620cd2d197da4f8a25522a6ccc7d4fc828b694e18b5248b310c5dabb3bb930525e47b166118af531b0d3f4ca3f21d62c40b1cac67661484adfb86a169f581ce5de1c3b5dfd54b3f0c48e91a21ef3cf733154b3e8c45e0c224206124e2c4fcd82136b434c8bd3b822526a169b5873bcf0b6c254238f9a8526b6f1a2886cb4683251b3c8c4162d43113111135b76815fda2ef0127b918414323fcf536d89a54ad5b367b6247295d8331ba55e5e89231e259620c90baaca319acc4d62d1cbbbe3cc15cc39496c4f167c3bef9c5222b1d97d716d9c64ee0824765c9495bfa8bb483cb6472c213a859c0ec2546a8e5852322e905ce8dbd15923f6790c152abf7139c6881d7645542c6d275ec4fe05a35e142757c278a1884d2ce7e9769188257651a453294fffe202114b7294db0cdbe9b8b838c4fe85360f328a6a769721b6fd862fbcae0ab15c689230219ea65684589ed71c175f8613b21ac4122bd85e7cc14e642588cd727174f1a4e708191588cdea0b9ebf8b3faf29406c8f2ed4f4c65f5cc61fd6f993b067e945fa0f3fac11b5e72aa8173cc8e8c3d2b8487ea2cc87c5cacf372ec506e9d8c31225176a359e5cf0bb1e76ca95e8b8a00b6299871df255252fe8bf4cf1b0a38eb2f8690a71de61f90b517fabce184576d87203c70df148d3aec3f65c345791a1a333e9b054e3824be5b38db639ecc56472d18c6621871df38fd6c676f8a564167158f3eea3c6e724bfcf2ce0b0d798463faef4433cb378c3e6e85f1cc96924c39e59b861fdd39ddac84c267a66d186f50bc731ac895d5c5c9c67166cd872c7a5fba291e9e23bb358c3b27d0fbee84923edce2cd4b0fe17d49543cde6a4338b342c9966c24e9a5c5c63671668b03a2cf93faacfb08df878e4c274f2a7cdb0efa64c3c17173ff5a40c6ba5e32fec2f6af03c417756b3c1393286bd28f9739153e7399ec5b06663948b520691be600ec3327f125d4ce1b2a10c86b5e28b2b4fd863a4eb17d65811fb91a817b6a95cef6d4a4d49edc26a93be74f7cf8b26e5c2f20f2be4546a9c8f6e614bb35e89730adaa816b6aa8b8961f7458ece2c6c1ea172314834a824b1b049549abce605df5d5e618fbcab2ebb0ab14a2b68e1cf28969155d8f4b9c3bee852da23a9b048acb4906ad47ae414963cd653f6f985dda414f6d9d91b3195cb4b14160d959959abfc3d14367bd4a8f9fbbff07ec20ebbb968e451d5d9e884d51ad74ece17176d049bb067ada4a7a4758e4426ece8297d95f3b1425cc2fe0de269b55f640d54c2fef9c55f187792d3bc24ec61963e6ad671d17848d8e60b35bc487c1c7a7784f5b920a346d11b3fec8cb05386d3e91f5f94a51561dfb554195248e12e23c28e0ba79f42a4786ad910f67a342fa849a9ce0a8750a82393401c0c8582a1402014040241e1acd701b319280c487220c9812cb7d6031380c086e18030100684816030180804838140201008040241008140201008040281205c0c195f03046dfdb8b660f01814820bb1fecc2a87bcdd0d6746229a07f674bd5e000feb36923f4addff2e52bd144dd2218c5d453176dd5ccc89d3c986c1a45db75bc3cab8663d355a532a06bb241d75a8984b52ec74a7879abe81ccda6884c480843a446578141c661b2ac66a975b8f4c9e399c87fc36ccd242903854d684c18fa0e1f0892de15e817086bd9907a6624c52eb89367e9ceacd721108ae8c4ac72ff6fb1a3e659e3e6be660f2b0e9807123c95c877b9cbb6d51297bc6524725e9dde1105f25b141e99f0895e462e01aea0dcb46f791b281afa572b30939f623a5d3011feed7b3a6c494a658a0fbca3382458bc668d1509323a5204648424cae3a4f73b7eaeab7dca41d894c5b588291ce2f1e3ee2e9ce10cb582392d6a0a64a4ee9df0ae94f59eb5133dbab259a9f9bf230c228b5ce3f080e8b3b50b6834db4492a268311c9fc4c63c12e2f3787fbceb7565877923aa7cb7338705932be0ca421a8fc7c63648e0ed32d62031b05f714084394ec6d40244b234aeef7d7f3c640482c8bc48e63e6d3d2a25513d74cfb807d3db19ead91616be49981fde050671f0abbd9246547a1a592cc416c84cf8c4e183739303d37b9694b0173a1ae7c71464d664a1e4f871d933b3e2ef649907d5086f5bcb8396efd27e887b359e7d575b8df0e072c4b66b14b9db326a12b50093b0ac185cab87128501b9a993c373b60d8e4c8ec04d289657e393f8fc76b70ec713abfdc4f904d6665b0cbf9f6badd1f97b9c525573c28e2d9f51aa0b0accbe176b9dd4eb7a3eb72bb0e7786e4ea769cd950b8cc6d2231bda8a9f3cc1a91ad47cf2bf62874d54a34cd5f085512943ad78f0aca9b4b86c6b394484c7e3d1dcc0804ea0b3f0883d280413038ecc4b2e9d0497872995a40eea5e1f8db79793a9d2fb7fbe9767c6ed7d779dcd19f35be661ddecff3f395d53ec813c99a3ddc02afb5b54180a2c3cbf57c879fa03c8eaef9d3fd7e3eb92e07c66b5532d02639dd8fa7d7c8cd11dbff3febb0b901854724d74047e20a6f75abb85501d14145a0139567d841e2500bcedbf5e5be3fddc7c7e977f444ae35fc4f2feee3fe447ed84df6b1edd42e2e154bcb0527898a316c48833c09357d124912e8ca8b1d2d6e39116c70d646a4b01716c2d05538c254fabf63e2d809b2e616f6cbdd9e2e7b1c7e8e1f9d7789f4ebe53af9e84fa8850cbbdedee79303e10202928edb767ab86e4b41998e96063d420a69325202a42d2a6f615c6447d7f3f176b9fbf9530d0a93bd36b0bf302203e66cb0a846c52ae5997bc240b2d60989df8ed7cbed70749deeaed3584b8673986375be3a4ee7eb727f08b9f2854f937a312362387c24737fbbee0f20c3b2616362b3f0b1a85cad70e8eb7d1c1d5debe9b65561446a6f1a44e4256a6d94c0bf44b7b28672ed1995eb775ee789ceeb79fb8c34bcf7297776df0f0ec7d5e93a3a4ea7d3e574381d5da7bbeb7076386797ebe870b81d2eb43687bb5617c3e1f17abe1e2fb7cbe9badc1de7b14b8600824a7e3d68459084981e2da168ed28bffdcd51dd6eeedbf96964f46429d6b219014d9dafe4d90711412dcf8cc131c50863ddf970f06d6647c38714873733f97d58395e4c97362fa1a2055be394412a5ae0d3b32f3bfed695fe01acfdcbdb618f41f131f9fbcd8c4625cf97111f4122a3d0f4db5dce00e986d9617f02dae8fc08b56426da5cf1c1753d3b9db7d301ff1e03eb68c8703dddaeebcb717dbb6ca3418e9280343192545482b2eca871ba3aef83d37575005c32867471fce578b9dcaeaedb81f13ed427e2a0da70885f8ceca8d3823dd4586bebae2cbb3a1e2dd983d60a3ed68d3dddaf8703dc5561e00b6af6fd7a3f9f5c97b3e3383b5c4797e3ec70ba9d6ea7d3e1c49298c25357396280036b255883d9dbb1b054784931acd283d66c8ec46e3886b29d5788d112502349214d8e9040beba0fc787fbf8769f9f8ef7c3856b10798dc22ab7068c8dcb9f2d480477469c8145af33c07d4c31227b5878a42a7e90cee1593477003cec6e6d883003df2f7e805c9d4db1b0194e53fabc973df3ae0ab9cbf8e9eebe9f9eaeebe33a3e915c401da1ddc442a6ad385cde82c9b770e889818e1aa13276015f6f8fae16f75d956c082c1e06023986ca3b002ee24717c68f07c702d01e3bd4d5f97eb9dd4ed7edeaba1c1d0031a440b5acc3fdc18acf5f0f375bde7539590834440ed63e1a3f979b8cd57e8842f07158ba0585c670691326d9c06167267ca12b394b182a69c1c2cfcc0f225ff333111d2f67e1a70c780406a392369d23054a9c528d44e9eee84cfc894ad16ce98ee0014684124477295de249de0eaa342c9d2614134a095aa2986094702578254a09522951422b699ca5ff2746bfc75b09514228812919951025b4529c12558a50ca29412a11a568a59c12aa84508a53424b28a68c52c2b5f485e38e9c9ba424a4c42a4528714a1d482946de74f62e9ad29052b64abdc7058435b2e5a79a97d65701ab6217433cb5d13d95b98ab347b2905322e4455b96201e950d08b6f044a2d1c8a828d25cf4023a54e06f0d5aaa2c44d5f54a884528463d609d792b9322702a090e6e495b32f0f64c41e221c591781248c98c84404221c195843961915048914804099a24b861b5948ae449514a192418e98e0475843c428ed0477147f40802098704894490143aa42c2899042b34240b098a94400a4312232451c038b7b79e123c1212298cb4234521259110a434521c528a8440ca21414994120c128e048f44214122a5248492e62265b1305b247820e191324860243b524385c47b4e47624c25c97eea06223512036981f444b220b99176482fd205d287e42d41d256be711563a420c95482464221219110a468240e298a9440824322912248890e8989033b14e487048f44228591ec485048245204098d8443429120907048482404291a0970483c4757b94219958ac4aacfc2002a67c92ceb3417350ba5419726f68d68a81de916f5ef5f2c016114ad6147047ceaf19a5268f09fa3f027167364580fa88c8934ab023d61ee5c606524725843c0674dc176c3b8ca1aca2ab5c16b1976fa5e32c2e7c259dba4a6290ef3d63c1410a0fc286458ad8b30b9cfb8503aa69eb1a4bdf774c5ec5b3701318a14ef7af7fb7e25d362811d2d5dbfff535d775150a1c4286ff7ed43dc0719064449ad0db7580e8d1910324dc34878777ad7ff00f8c078c6e5b527686543a6b800bbd1a0d3f8838ea98fb741a355a30560be205ca4f49846779ed2e4f389a22cf78e94e4ccb15b3353e43a6fcc7c6379f782a303e791e1b7f51b19ce2e50e26d5ff9dc8e61347b24d375bae048cf9c4891e7ca67543c2d2d98a84871b7c885d96d8eb68645baaf9a3800aaa501d1af971419ab0b75323912e7470e228d5a180fdec35a2f58763a7ab2526ddb8919187ac19b22c7943470611a36c47345c862d55f99dca31263582b42f5ee5cf1d0286c950399a15dabe14ccf2c5ce2d758b1d6ecc8c9287229290671e7c9eb79a977a4aee86d49aa6376afad5b0fed3f5cd4be830cba1f8988ee6c09efed2f201420f773bea9ec42a290651cf947c755bd9609b7aa4a8599e46742b73a89888b5d4cc559a94db46efb421e5fa2413570ce535b277700b5541b25efd06c2eb4486be1998f071cc50cdd544e8a5ed170e140ff41bf81fd713f9be106a03290ccbcadbc9d416fa95469d6e83b0f43a7cbca31a9e70c642312d514da0ceb7222ce0e73d2d238484818492b145e139ba122267d97c596fe383423e4401138224dcc2522f5365327c13abb6712aab1fc42de89d4c18e0db214b8d56cba90ba3d3fdbabb58f526e2a4f5db90794a42a103da5f6c9147638f67bb85e5f0ef91eec50b893e0db02c169b78cc98277cb4040812c70006adcf1b7ec16812068c280d9b3c5bd052cafd753c99eb1da99d5a320b76517cff6a45229d281beed49570a518114ef578a9c24dfabd378509edb0416ea1095345279647a3db0af872121aa20c5d13899c48857b23165560e4241e479a101860f762985b41e593c75faadbbaad38a2634c053584bff64a1ba8f2aaad5d5a322b8d786e339e74a089905a5af4305bdec65ca1f4c620ec0658d2570f25270176d4938055507234de364e688fd59971e578493e62a5003db0100015083b4c4609e5e2fd7d1698a4152879d6a60f184c9dcf7002dc934dec0140fc30c2b0650e555126911589f6285d479cd243eb294072e0444bb9101571f5d4e577cad9e81ddf1cd790fb5f57a377b8579ed7f80c2b3dbdb303250d73329d891315df098eb340ba256b282fe16a9dd881295b654d9d34dcb9b0f41eb1614db137003643633120403153a7533574a9938d183b7fb1e49970d1cb6cd1dde8ae88242a53c1a4a22bff2c220ecb05f0972f92c379a789300f3c80b5183cde5f35cfb6a1a659794ead5732bf7c7412a42d1abe56c35e666f703d98dbc0f1377cf1d6d5382d59b6cde7cb18abe8d752dd994a2933392cc5011f616bb04ec0cd882ec2f6d798056143e8500fe9f135fd85533ef8b32a44461cf639d60d9865466ae1693892626d5bd844d2e1d0b2e2ed6e990593395f25802740faa8fcb6a9e611a635a1197e09faabe6df1e60d18f6f9d0833304515a651fd4808590c2ee8342ee6737a82a41ac4f777ad02a9889b52f5c86e6798b515809780a595c1fd02e9cea9110252bcd70aa5d1b48061aa381abb4d4d19ed14dbd14d0b43562cf67c57c57d0714c43c5f82e1cabc16aa9540a0831b46a24cbe3da0ae27da86ee591486d32035f3c98ab8d0cad7baab3083890018eca415744de45d50b1601604146f1cdab801d071f1a137caf7164fe408665456814fe35a7f97f6876bc54e0c90e89e7fcca17c77cd52a394dd82a980d9cc795ca3484631f428b3992676288810cd44fbb339f07fe5e42281edea5fbbb04f059f1c8057d93bd313db4e9dd487043b6a891083c3ed8004e09c4cbb7eefc26bbe09f198224eb6036c15c3c8be05aaa94029e767c900ca23b917795ca6337e56003462f53c507aec1a09550bd5ab3e1f20843b120f19a0f9e8a3a58b63b816e9cb5486b5b0f5c72df09eddf930260ad1cdc49a1cd14b845ac7cd9d79b027541413863452626e6f941c9bc8537599f96a6451ab6929865aa570412bb375d8719abc4fe7e8822458fa6efaa6f946d8c3a424cd0c1bb938032dd53313727096e772ec80525114e1f28586484a3c20117732282467e3c37c93d361503ca0265d8c0cda9aa16e4a149205b5e47b3b220228894e9b450a0e956401c748c010cc9026e9144e60b3960b26639ff000000000000000080b8c9cc3631d2502538252995fdd10b65505e729229a5945224bb8377c199894f6739111121ace035d30001670b5e0ce60bef683325bc8451e49efcd3f99f4c3c4b982527254ea8f02425555b6cd146c0a212c6b2ac9c3a2499e392a784a9fc248720c4040f739a84a9944e29f9b8a550b148c26ca9927f12eb3959072361f4f89f4a8ba70f1d868449a28de6a41396d5a4e511e63555a5e242270f5a39c22cf93e2413ffa666233dc0a21126f961e4c4fffde4717901168c30bbfd6be9bc4d0c1db15884d1cd4ce7550edf692696032c1461ee92fa41fd5dae3c1e14701e5d7c7cb8179dc30b2e126191088369b7f8d2d17dded357c002118624b92ebbe9e343f5108611d2344c8ff232f5e2d83ac18e2d7af0388016d291821e58002c0c619093ba4ba658759fc875e868004e008b42982fcf88104252275e731c5b6701d801168430c7f06842c8d2777be1e124d09103021fc8c38b2e2a80c5200c6164f98ff09f8f20b2a30b2e72dcd0d1a8879505b01084219d7e5fac14a7238e40f2d43b2060b55cf4e8132016813075f57e0af963eec77c738005208ceea93fddebd78b5f204781f9f8f8383bb64000173d5a031f1f5cf4e813fc008b3f98c32567c7f6df0fa61443b78ddc2b797dea83592b6c2e7d944ad31e3e20a63fd325bf573007173dfa040413167b304792cf36a3a51e4cf1ff4a788a0db17d1ecc79f2541251ca4377050f067349c962e9ff87cf1d8c2d96a523ef5d4ca87630e89323b2ee6b3a9c590743ea0ac1c445ee43ba38b6b8f02dfc86172e8222021d391a60430b08e0e8d10ce03181f6a213a005046c58200211f8b8c1830b2e2060230b1b0db091850d2d6c64c1830b2e3e3e724d021db811003260410773d8ccf31447058ff61c4c91c3423998435475d221a9117f4227ddf01c3cbcc0c5220ee6b151c24a454b42aa8963b58080e7a8c5020e068bd1f5df6ffb26b63798424de4cc730e7b31371854b84e2acdd7c94d6e80451bcce737b26b7222517d36186364594a2adaf9f86b304612a7a6d229b99f763558e259c48b18556db1c517aff558a4c1ac9be7418c76133975349836846c6a842bb72a9dc18cf708d61272580a1516fecf7abb92dae3c6160514e18085198c9dc3c751736254e45019cc2363e4652e25c9d6218361e488988920a3fd3406d3e438a21616ce6a6e31983563728a1b6a3152c260886a5d796ee54c09190c86a8719556de3ba760f9822964abf420fe23d55e2cbc609c90ca7d537b424a2e165d30259371fb49a8b491925870c1f8a62c890e0fdd17c6620ba63aff9a202e24a7190b2d983e2fed7f5b2de59f05f3edda270b62c1a0468be98eedfd90bf8241281d94ca9df3fead60befccd0ba54258a70a8649c193fc3931a2a6824923e52a51217676a760bc113ad827a54494b8140c3766dd134456fe2898fdfd52769ba060b24b4a94999e60ae302d0b4a26a8607282b9c3fbc40e69b1aed404f36d4ddc581b53a9c4048390e4f951a49834a12598dccc7f744cbd9591120cfe1561df92970951124ce5b9de672357fc10120c2ab4b5460ad9f742473084f3aabdd908c64895d45aa67abfa7088634e25abc2f858e8960b64b91904fe78b3b04c3c87ee809316f4121983bb4727d4bbc6075108c1a5ae6dd44df8f180826dd49eea494fec094dec32525f481d9b3ec576d4eec7b605a0f213e5c7508160f0ce7f37ed26e6c266507a649cacae36469cd3a3086d2232fb9c4486d0e4c39957fb8fb9e912d0ecc23c2bebba4eff5dcc0e07b417d642d7db50d0c39c7554d6b95546b608e9cba91e67e749006663ff70e49a258ccc0a417c94fc85d0f7e6221039357becfb5768964621103b3a82c15b163d5ac88050c8c15bb44f8782f41432c5e60aeb1744a56e91c2788850b8c1a229458b5919ebf5618bf66b4322b88f81c2b4cbb9a2b42bfbbe55b85d1ded2c7247da7f854619878e51dd254982cfe4a5bc812f73a5418e58212952ef67b7d0ab39cfcaf3df1142ba63089b85e21772befa5300915f495aa5eebcc48611695a3a7e53df949a330fbc4b75799b4e5118529c95ceda148e7c3e29d5d7f0528cca9426fdebbdf5deaaff88421a4d9f2da39a95efd159e309afe9045c8bb6421f2577482b3f0f1a5644e18672e45c5988f2293df84214cd813a7ab445cc96bc278d24549d1fde422f94c98fe478ad9589786e4316152499c9abd3c5a11f297300813f549c912c6f2dc6982bef472254c695dc432de4789286148f1f3db0413f5e0240ca675396a9a94ad5e12a6f60f1f97bb5f110993e409da3a0e09539023a73f852a95f64798ef3545a4b3b5cfba234c5e1ef7625ff6f3bc11a630ab8bcb39ac4e9c11c69c53a192476599d222cc49a7ba583a8a30ac7b75de8f367127c26c55ae35c2fdea821061ca0942cc9cacfb121dc2f03af24e68e8901c3284415384ec8f0a613e4b214a2348ca39210c1792b8145992ae681006914c27eb20e52c2d08931619e79d130853488ac9f2d67bba0308637bdc47999c3f184ea4ba373d91a1f783f1e4c4f1be4d39f5c1189793cd8ddaafe08369d72ac9c88f12e6f62bf6600aa1712341c4d372fb157a30aa8474e111febfd27e451e4c498a5a07fd1b9e6abf020f06cbf693c3772badf62bee60ce3ac9a2b32d9fcf7e851d4ceea7df7284cf1062bfa20ea6b594546eedfcbeb25f4107738e52ca74abcb48d9af9883297da77a285d2672ec57c8a10fed252ac8380e86d149d2747df6990a1ccc99192fdada41afe50d46d3bbe962b5a554c50d66494ae79419e2c76f833949ce12d1d1e494d87097ceaec16821af4226c5cfb96a30f656b6381aa9526ed360c8e1933f77ee4eb668307d65d35efd19cc492bc98b6ed941c90c06ef90465e2ab9b1cb60528ffc398914720a198cd9fa41d49598693a0663abbbb9ae05df93180c96740ea5274fcc4f180cfabefec14b771c0cc6ba14f2058356cab8c97bc19c63d3d7e2d80583955a2ad70b9572900b26b37d17cf168c92f6c2e7685a5b6bc1a04eeca44bb79b2466c1242feb9665446b8658307e94a43c9676a7fd0ac60a9362276a28d9ad6074b19454aa4962ef2a1882f77e4aeed321850ae652f3c1df2ec9186f0ac66ff71e2d1e84474e0a66999073aa1b517a8a82d953ce90dee92947a1600e722ebde80b23567b82e9db4348312c6858e60443acf8fa53130c4ae809f3b2fcf330c1e859c277ba7c09c68e2d7247ab04b3574753d92e8b102b09869dfc576322c8c948304b786dbd541d371ec1902488d38a353978c48d60941c795cc4a7ce9e22184c63cb2ae553b28960ca397d0e21e88760d0f5a1e4952f04e3deada4fcebbabc07c1a0ebb2726ccfeeb803c130c1845d9a5c8f1fff812986ac7511edf39efbc030bb1652bebc07c6f55159564fa6ef3c30695aa96fe98e39edc01c64c5ce331f3c641d98e5db5bd667239f03b304b3c9965246da120e0c2397b3770e4a57dcc0a02d2458078bc9a693aeb08171429e554f6976e493aea88131bf5ac4af25ef7ad2153430df9795e48a26969d74c50c8cf2a19e92909f2475d2153230c8f3f93bc5c094add6e91d8447c98181e984999ee79314e117984f729820e74de5f60a179862e64edef29845bb1506ab144595b24e396785d963f474a7390d60154693b0653db92d89390d4015a691b816caf3b2a39c06900a83f80ab5fc719e2f4e034085d946267f302de6794903388539744ae9d2d6c5259534005318563d4ef25c97824a49032885f9de27e69bbed15749032085b9538ad7c1df51984d2bf96dddc9feac284c9782d2f28e8f9ed7501882c7299d2a7dce5550988238552109f513c6502a926357cec4d31386eb0f8d14f2cfe6ec8449cae5d071a1546a9313069596b5fa44db4f7213a6533144fc7b8e89a426cc4988d7ca57c23f8d9930c50bcd17a174282d62c26c613bd93d4e902a5ec2fc6d394fca2a524eb4844157c7f54bc81647ac84c1da939ccae8efec51c228f946958a49dfe24dc2dc327adbf722a7de246136f1b17c520c3dbb45c214943ea97d314818cf42259162bb9c8a3dc26cb9e4759aa788d71c614ef3f813ef456dde08933ef3dc18d58e38234c41bdf48953a54598b4ec3e6a959b1e5552847154275372e253d44a8930c4482ad58814220cd9e495178e63ab046e5b740e2f7834053e3ebae002414004314261d0b14ade77b8153b0d14a6511da27e35f285bdb8a18595f909c3a452310f4259126ff18441bcfbfbfec48beb924e98ec442c75937a4e983e8730ff126ad7f9dd8421491f219e7cb5fa6f4d98c4adfdc4e26bea9c0964793c915ef49830cfc534a54b9a45fbf8254c623d61ecf6630993472ea16584e95dcc043bb8701e953085abb0101f1f4a7a9e12a649522788d29663f63e09f3db8e1eb9de75a2744998edd48c52399eeef84f24cc5b39f442e80b0953beb74b651e7278523ec2b4dac992cea24ca986311c6150fb94ec2531e7c26a844982eca42b4f0a238c257fe48d5eebf6d42ec2983d49681991922e971788a1885e9408497d749097449e811ec4488449e343089af6a1e12d224c31b553b474bd8fc9310e61ba9c66a5b3970c578b218cded76bea3f5d340f2d506314a23e08511f83a80f84410c41d44720ea83470c40d447c6f8437d580c3fd447a1418c3ed4c7c6e0437deca13eb80631f4501f79a80f3cd4c71deac30ef55187faa0437dcca13ee4501f3de2501f70a88f37d4871beaa30df5c186fa58437da8a13ed2501f2c831868a88f5d418c33d48719eaa38b8b5186fa5015c420437d8ca13ecc0431c4501f99821861a88f13c4008349e5a38e7eca4e417231be60bebaf06166f17951dfc2bf50004a2086174c2f71365f4504c756b1a200046cc4e88229e4ca25ee92a8d24f9387175dc4e08249f80835ea796c745ac70dc7811a7d7c64b221c616cc61e25c3645e71467c2b15f6cd119d8420c2dd44716eac3041a851858a88f2bd44742218615eac39a10a30aa69896944e6933b75b4220c054c0f453e65d374ce98a0b31a6501fc40731a4608a7097efdf2f0488110543d01cad311f5b9be7e0a10542c13cb6134f58d0e76ff5134c95425e1339751e7fb303319cf0a72b29808b8f8f8f8f1e3988d184444f9425a56409719d550c266cfef7a37264cb02812f22808004780e1e5a94f2e20b2e4ef21c3cbce09540076eb020466a528a6c38b64a046228c19c722ebf5cba5369331c5bfa80184930e4483fff231e3752a0a30b09262d0b313c2795021d7da347023e3e7af0b8a1c51dc190b463c673529edc92838b1b5e54e5888017be4517397868f1f181821c5cdcf0ef06502086110c1ec48938d273509fca05c42882c1b428f923ca83758c318860d68dfb94ad4a8c21184ddf82b5e41c75430c2198654667354f9d263e8b636b6d68b100df2235c08a1a6204c1601fe5dceee28e1e2d0610cc29ead7c7fa42ee5a706c00c210e307861cb44feaabb4b03d6d64617788e103d3c5ce2df3e949fd7c7786183d305bfc531926baa4c4df5d016588c103939c79a55cd14c057f0706a97142258f73b1132f5588a10373d029d3a5428c1c18374c54124f7b3e4a7c420c1c184d490aaf30314b4b929d10e306a6901e26ff2e6703535ae910ba7476dba56b0c316a60fe1339e84e21a9c0108306a6edffd473ad24c287ccc0f86beea5e424f52342323025519ee3f3a6c28b6288110343fe3cb59b1b51171b06a63c219848fd0922b37203005f88f102738eb53be31741ec371c5b27681e098717394e502a10c305067d77d183deed8f4db01480d10ae3555c507b665a5dd2ac30888a2bc1db3c5b296f1586a0aa35c64accb652706ca9c29c823091539d07957bc4b1d5459fa007a6c2382792ae3d4c82ea098ead1b3b52e580810a53f6cca99168659f378ead146cd145175ff0d8f15d6c71036dd1881c0e18a730e70f31adb33cff4444304c614ae92a076f4f716cf198c0c787177e012fbc078c5218cb2a7fced1742c550b8e2d1c5e741737486152425ec5a70869278f46f198748932b91dc8038628d40f299eb2ac71dbe3d8d291e386173abed8c1455f280cefa32532418e63cbce4061ceea9cbe372c4d72f609d3ba58aeeabe0b793fc84d80e10993a754a62a9a5ccaab8e9900a313c64a4bda934e73519733270c397878aceb507977dd8439454ff932eba45f76760b303461be5cd1b2a9ef32166064c23c7a2fd257b2116135c6843953477eaeb45fc234398f8822e243ea060c4b98633bd28fba45e3c006c0a884c15b23b9278b6611d238b67a78b1031953c234d26487cfb14b8820c7b1a595c53509c35bf064f1a246894f12868f0b9ef20461a193aa877791022fd22261721d554a8849c3808429bf47d49d5ae8fec500301e61ec96db154ba336dd7584c1d64ccc5fcc64e5ac11e6e896113b4b25553322ed36f7a72b02631126ad10f3e2c58e1d3c9c8717058622ccd6f15408f1eec9548f638b1546224cf2248e8ee813224cfba3659e11c566a28730e64acc9d94730afb8b1b3dfa86dd086018c25841445c141d17c21cca948c0a49bed75c42182fd575e7fd76f04be1c1c3075102188230f8a98524d4c9458e6f717a3d002310e6da9d1c4dfee9c9d7b403300061d2f2d99412def726c4a37d0b74a501187f30a8fd0721596d3e77bc871f0c39c5be32ef1bbf14ebe0f18517ce03390abcec068c3e18cf447449e17289f8513e9894d4165139c7716cedc1ece97b2e5acaa1549ebaf0e28b1da62180a107c37950212d9f9ef4290cc0c883512dadef968824d7461c5b376ea4761eac783058b8e0af39b61d940227c18d3b982f7268ba6f6707c42389ddca7ab4086e78d1e38b11a426c6861610b0a15ac0a8433a9e7a8eaa0da1530ac756f6f0a287d526187430569e07734d8b306a9d83c9d453b3d2a4c09083f9f2f64c9ecd8ff8350ee6a042742909b26a25513818de6e3c96f8784258d20ea4c5d60360bcc13417f2271d74d2e91a99d201861b4c3d295eda274dadbaed00a30de620d4945027721299a52e3e920830d860f2584f4f29a4d316131b5964a105046c7c7c5cdda84c038c3514bed3978a3123c401186a30e4dc9d2b52781396f438b6b6d8220709d2604ef961753f6c9f8eee80810693120bd984089fcfa7835cc0388339856fbd4ed1feeb2f2c8061068308afbc3ec92feb5828805106834af6d5e66b6bba2a0006198c7dba4aa938722dce3198ff5330f71f99e02602430ca6eb11a1477e483977b7e891660646188c67a77b74f7e41131c46030cbc858ef4aad9d4be90b26cbcb79628885cb4dbd60dc519315a5adfe2c461fc0e882a9a4a72d95e4ea556e12e8f80247160c04185c3088bf86af564e397c10171ec0d882a94b7fd093e42249ac7500430b0619d3501f16a63a4453c78e2db2f8f8701d3bb6405b6c00230ba68be9a2838d0a92afd29103f1d8a10019c0c082d9fa552d8534bb00e30a260fae9a154ca284927e6511926ec80a30aa60cea6957ae269ae67870ac6cdd4d79ccf140cdb6a91c65435051852300517e177d2bb17c0888239a75d4f21a7dce95281020c2898dbb6a34553f539c1a204184f30cee88aeefe499755824780e104f36e57ae10ac2b766c0b46130c3997be907e774ccadd4302370a06134c19fbc9dade37ec8438b692f31d184b306ff955346d261c5bbec5692f5c046701184a30874b3c2dd9bed1c32a00230986998f16f3928663eb46046020c1dcf2aaa25b44f87cd71600e308a69c65d27ac81249e88dc03082399f8a5e71e32910c02882b92fe9a748f9be3dc4e4e12248be856e0183080651f2be64952e9f58e2d8d2b1a34c6033b0430bcd807fac093e3eb00d3086600af1736adf86c91149566180210453467c53512d97051841308d69cd4ff2ec4ecdf6a2bdb880106000c1a4c4e829bd1492942dd9c8020136b480808d8f8faa1b95021ebd455301c60fcc37e2767257c70726d91d0b6fb31a47555e00460fcc9d2aa992d5caae9e25c04616362c70001b5a40c0c6c707b9ba51850f3078604abb102ae96d4fe5a61d1882eb9ebccbb77ee4e8c0f09556e7c7e652cee7c0986aef31e221a9af1407e64f62296a3a7f8a29dec014295e123af8ad47fc6c60b008234e8cd8aa174d0b306a60b80b11a2fde934715483410343ee399d42533d2d7f1c5b5cdcb871b8c7019cc78e7730c09881496e45fe509f231faf0c4c61c12b2de48e88eec1b119801103733465219244fe605a2ac04616df00183038bd52d07d3a42e7882fc8b389ce6781e18272377f44d6d8fc5a41acd4b69025cc3755566c93540af97c1effdf2aceb1964b1f69e384852accf1c5d26252522a4c62cd74fe17f79473091526ed5bd3132946fa7e4e61b40bf708b2da930e1f53986d9448083125cfc7bb14865cf983858acea5ad26853162595514934761149143f549f8937417511846bc7d55ce3314c6ab20c485a474952a1d28cc934c567c4f9bf4697dc2d4a97d77ac373ce53c610a49a627dd5ec642c8c2008b4e987aaf22093949acb6cf09935cfaf8a4b73cb97436619a4941a8a950b127c69a3076c4f0acfa9cb2769709437c1515b473a82cb331010b4c18f2167ec50f9a842167e95421a66bcd3fce22cc9084b9db84d227845698467846244c172e8538952ce714f7fcc10c4898530aad6fb9235578d107331e6112d284163523a7dcb23785198e3028697b39be8ed75fd035c298eda3a9726a3edbc30853a8f1d02d9f4598327259b692774fcf1561da8c2c7a7d2f64ab2d9f302311a6a03fd6c55cad92d60333106194e8aba619f38d1da97031e310661fbd5762e9f8e2c68e442ad310eea8a4d1f094bac48c4218a4e78cba5c6a6df942086328495f9a323ac4fd6e0d330661109fed49728e96200c49cad7281d55c962eb9174780e1e0af8f8a84098c469d125da3dfe2a8461980108736e8d39f972416ac5687f30cfa5fb37d5273f182505154ba524d1c28c3e9847fe8918b12efaacb5c5043e3ef860ccdb9fd475f35da2d4c246167b307548ac0ab2427a304f3cbd7fba65943a551e4cf9940e2365d33da4180fe63415cc3beb291da6bf43da66e48588233b406ac0d9c1e019ba2e4a3b68568aea6070493f23ae96fb419674306731213999acccc1544a52fe24742e89ddcac158b99e2c489a94fae4d1458262461c8c5fba9336b96ea9230901708a197038f8255dbde6696a807791022d52e00ff8f82845021084196f307ddc7793ebf197201664c20c37182cc5b336e1f184e5df06636e559e7a8738e14384196c308add7dde1dd5d94c3884196b30e7dafb75cc450833d4600ed9d129ff08ed9d9d349854b2a0cd3be6e8282133d060f65c9bf9f717433eabc08c3398928adb16f468cf934fac84196630ad8912f9333cff57a58030a30cc671592bad5f63dea3a283196430e438b1dd4ec8158f7d0c06695ffdf129744e982106a3568cae9e981b1f1107668481cf31e2a3c00c3098c33ac57a2e474e23c5b185d5c58c2f9845770ca5e9922224b92836b458408e195e30fb9fae20b7968e1de500808a195d3008952174de9d9b685a916206178c1bdbb5dab136c28c2d9894b89452ea2dd532370e33b460f27ddfee8e21e2789d0583cde7f35423cb7c26e78619583058b22e51b5a71a665cc110d45bdcb4bbca0bb3150c5a2699b6afe5246236b220c38c2a18be739836cf7e79fa11c30c2a98a4f586988bfc36af66a15d983105f38cde3d213c5f9f772c0b33a4601a1dc1b2fc5fa953ff0a33a260b4504224dda96d2626148cfb41a90a298ac813cc5e49c8f93ad5176638c16cb56549af3bf558c40b339a608e2621c73f954c4511dac20c26182b3fa65cc5273391635298b104b3fba7d8f1d7267b6b25985ff55292a97949306905c91b1ae327a78304931031c44e12ee118c6edd6297a47529b51ac19879f1c15e846a7a59049397ad5e8dfc271f1d114c6b7a57ba7287aa980dc124a9f2577ceea49e243876c70dbf32260473ced62a9f354525e883601cd5b555a1f7bb3b0f0493e493edb3efe5419e7e60facbe145e74b32db413e30889952bb4e510f4cdb21e43011f9295d9a0786de8e2af2737607a6cd8a3e13c69ca103931aadfe21dc4ab7bb193930ccafb86c76fe0b75392accc081d962c4229ec88aeed40d0cd9f396876f5b8ec756336c60ac5c49cf227e6dc977b00d2d16906c6801011b6b1585193530bbc7becea63da850fb8d9d410373f8d6f87d8f0586193330a5fdec2148d58b57711918c5ca82e9cc0a32d7130373d4369194e605fde98681b12bedf4e68a9ca8f405e6a0738e73cf25e974f208335c60d049b885d051763bd756e495cdc57556982e545d4ad9b2c77e7e157dbafcac927fdb437a90a10aa3bae7df29b3aa49662a0cc944478e904419a830eda7e494240725459f4ed1e4772b1ddae6b1973bc83085414cee60a13deb876c955218921059d7b2583a395a19a4304b0a677de16f23c81885496984547fff79211685a992888cfef1514b5b7b202314668ba92e17e7b35abb048549a554397e89a05452131c6b03199f30c5659351a191d3e61a90e1096385ea904b88d49d5ebac0c7c7c78716cbe884793d67a57872c3df452901199c40dcaf58deaa646cc298a3df1e748fccf6c6c9d08441de5d10e1a49a9af08e2e8e04323261f01bd10926b3735716c7160e1998306b8adaf0b794ae4de8c50e1e379c1c0a5c02ee457391c38b1ea66e15322ee1b5daa452f91406322c61bc58935298ca38b6920ebfd1a3e830698b2f76e0b8c0c787052010322a610842774a95a745e31b3a76a0163c744ca0402183125fb887eb0fe9355c1c5b5b3790310993cd969e96472b1d9384f9363ce50fef6451822261cef952b8a0d2c4adf62d900189df44c7919182dfc4530e1378161f1f1f1f14b091850d0b5ce0e383a441c6230c6b29b76b2244c70e2b14c8708461cfae549cabf437e9c8f107483a7228e0e343c78e1c67d508b3d7a89311c6182d5ad7ca4ebe8c166136cf1574daaceb9a5c1146d3f1655182291186f110259e697bb31421c2582acc7bfefb7f47ce210c6a4379109ed527588a210cd24d569a4a9642184fa4a8c8a92aa5945b4218624decd2916162231d842945f018e229c5f01b05615e3f3b13e9be4010cc82a7e676af9bba200310e62041e4743b224f49ff602ee9262f86dcde0e9a1fcc27c25fd058f756bf0f8631fde6a53e4c2e6df1c11cc9472f9e56153791e5828c3d244595fa155529eb3d52e024c8d48351e455cc2c934f41b67930bf24d753a92c87a40dc7568f1d5d9c2e41061ecc71c2239c07515ff95325c8b883398590fa17420e2e3ab383d12766ae989ae81664d4c120a9444862dbb4a504e920630e06d52987af12a120c89043a125c7491136eb2ebae8aa2cc888c3dbab16a2d61bc5ca861610b071a32042061c8c3aa97527fcbb784a6fd126d8c1855b40c7046c6451de60d0163d4c5aef4090e106c3458f1f154a8e68b370d13a5a02d806d3e90c593f7223e932d8600c613a6b89d293eb10418e0b141264acc1e8bf3e2742a54c52a5c3820c35a4ef5fba112fcdb51c24fdf4291969302435215aecae141a8ca6d62e5c849f8f79219504196728b85bced8162d494962d95948bd297ee7f7fb4186194c797264f4d9c8102723838c329864f59cc969dab6490643d21754b41c978c31982a437f487eb9f04086188c1f2d4c08bad2a5895018cc755b912d4d8e7320030cc63bf3493f13c4c4422d07c8f88221077125dfa2ce726c45706e90e10563f667b59f9cda414617cc973b39b495def2e8b951850f32b860fcc9b7167c4d37aad020630b46d5109913f2b951a46468c160412f5f9e284ae75930c54e23feacff72853416ccebfe61b2fd87d3ad21800210b0a15fc8b882c9f3842b93e8297e5a36b250948387eb70112c916105b3ad05f91df44dd2552bc00236aa60567939094a843ced08046450c1a0dc2deb29d34bfd2a5740c6140cbedaedf3a95a54956eecf0e2c6d9096448c1d47a63da92f01291ff2818d2c75f79fd7cd9f799a07d8bab2c9207175c10195030555b57129b490afc013a90f104938f3c9567b282f4d48520c309e64e3e9e745e5774237f20a309a6afed9c73b20ac7167e7cf84006130c1f562ca41965d2d5ba808d2c6c687103194b308d6d7c30cb22164baf04c388882ba2a774e7ee49306ce82549a6428e5a424830977fd229a7b6e48cfa08a4d8176f66231bc1f4c9e3af2c8c88a39522184c4668f90b52f2774804d3e5a44bf7971346764330badef7d5474e0886b7754b33ff21262908e6bc16f937f29e2ec88060cad2397fd8a67ebc4ac60f8ceebf3226e739b324327c80da954ad2e5d38392874d90267fa2c8706c7dd1e3c6a91564f0c05449c4defeeebbc8fd0e4cddb115c3752d49fee8c0a064790515b5f2abb8393056d89691d941a71d7160f44dd141c9f02bd7f406c6f0c9e6f162d9c090427e9d1c94aae79ae0d84a27c0e2e15d74d13c34c0326a608ab10bc9a63ae9d82b0d4cb13a975d7d9d779f9e8387165ec89881494bcd46d2878b043a7043870c191842f85849a5e9f95f4a5becb8e1a8b7e8c2796c5140460c48baffdaf2a26f70cb8081212721e284687172f2d8a123c78d09c878415929086927ffc76238b65c860b4c41de43c9901f7aa52b1c315ae18ced47cacf91455aac30a48a64f9afaaf772afc22c4959d49bb3687f2d8ead1e050431546112294a440dede11ba954184ea4a91c41c59510725418e2bd7ace1a92d37d88159ec2d841057dbbfe4fb0234d61ba146a963b524a61d07145e452c58bee9f6290c29cb4cbcfdce754c4138f1d379001314661ca16c17343d493509e284c398924a3b36e96590191e094cddfc5348dbf1024f264b2b4bfe9363de24a29dcfc85916aa976442541f2c44fd39e346e045263278baa2c714628e716849efb9794453c222e7e2792722cab8855653dd492d05322b41321db997bb0191311350ee1492fb5f12769245da50507a286210c93947ea79abcae327ba1c3b928847184a768eb9d3be40b962ed42084ba2efbf164cb4fc741ec2342791a9d200c397b1c9d23a594321fd345f3d0e2e3a38b401ce69ef196715516824c0c8fcbfa582bea256c011b5964410108d8403abe50c0c78702fe500310a6a47fc35c843e6bfcc12c1a6aed94b89c66bb420d3f98fb6a82896462d5e883494e52adccfffc4b990f8614163172689e8e55eec19444ec3ed885adf0413d18eb2c7e8e3f4a092f6fe0e8d13816478f66006e8d3c18f48a681331623c98476489aa24ef3b184f5f104185519eba545737aa9c216ad8c15c17555d2de90e67921a7530e7c82d93d79699281724d4a08341086521091d25d5e9b414a1c61ccc17e22889217272307fc88c0f9311437e521ccc1734925de9ea892f1ea1061ccc714bbf8538fa37182ca78d6041c268dd990835dc60fc49d1bd4d5fda600e7de2d627726f4db9831a6c30eb998420d1e3b80929eaa0c61a0cbeba3fa6d62da40635d4601e49294eaab4d9a1621ad44883b1f76429070208136aa0c1b8337349ce7a96b864a0c6190c1ecae3a28e8c6ca54f2364a8610673cc1915569e4f3be9e4d0416a94c124ae35f1d2fba4c7240235c860caa2833421afefaf631c5be7801a6330877695ec23d223870eb2801a6230e809bd54d9d2d34cbee07124d8610218d4088339ab0495c382521f977950030c86c97ee926049d3474528d2f18f24aca26e9fcade1056359c493cf2273e4bc14d4e8c2c97e458ca9d2a613c4052f7dd291e5295fb585b2ffd3f7fdf288706350430b680b57a276c3b1d5811a5930957a5ab59cff8e1a58602fb85cb6640f439e766451b2c705589d478d2b18e5e254ee8578ab56ac6054fd1ccf6a74749d2018d4a882c954092dd74bb2d4e4e8d8912305ef8e00632b810edc10800b6a50c1d4a7929e9b5c612bf75330c92a5b0ba5c3da7518c7d6165bf41a17392080c38b2e3ca1a08614cc7f567a63740991471f05c309ab9355fa3e4df640c19cfc647df8749bf6f6138ca2acfabf4d77c8bc38c17821e5f0f939e2f2a80906f966a63d04cf08de32c1182992eef9e0b9a2bf0493a7fbb9c939243d4b95601cfd6b4fb997fe92926010936f134a662e5b9090ecc92172d647307ec9bea7d8d2080631a2bc845ab10826b1f3cf7236c96e44229854b7564e441c8251946c2dbfd0bb96178251c692de33ef1cd78360b620d2fede2711230404933ea51745429a8ff50f4c918376ccca5e93a00f4c2bf65b49a5247b52d603b389bcb9d3ff8a2e311e98e26fc476602af535d31c57d7560766d32367eed64152b272606aaf0eae37e2c01c62d609752a27d748ddc0a4ac267f6b570eba0d8c165e2ac9d2efbb423850a30626b32df3a0b4c53c443430efc67edb859c52dcd00ccc7931d499ac4706a64afb71467ed211942706266921ae99de0d037398adb8255ae761bec024a9e5b783297dc96308d470812948d2b7d36a2b0c177cd6bb440825c3c20a53364b13f339ec7d7a15a716152374af5585317eef826faba930fd575e11fb6059374585e14f2fdb74c8d9eb93a73067ed7ad1f9235bb4d314e691973dddca5218bd2d698c1257fb30496134a5dab37be57df171148638a745b4cadd5b0745617a91fc392eff6e9d180a73e8eca63c8c0e191782c220bacff737e255a8ef130695f53f776cbd897b9e307a873be9915a7266d709a3a9ebef3d6141746e9c304e741fcfa176fb9a6dc25c21a7dca1a7ed74669a305608a9ed1666b2edca84c194aaa8176b4c984492e894a2dee2ceba84e12f2e8ab08fdf222b4b982b5f56a7ee8e75b21206d321a976748a21a6849d9b99dae14998bceabc938fb624829230bc8e597e51927b2b120993765e15954ff3272d48a474b4567ab31ea1a5fe20f565a49d588e307ef871cfb16e418d8ea3478e2dce178d30968db2c8722544ce8b0a1a8c3079929fe4870bd5bfac6153d05884e154056dba534e6fd1a408f386673b11e6d0b93bba96d0aa2643844148eef472ff7ca7910d248d431865f55a72d43b131ed228d03044254a7d845b937f7cf0e871f20b1b361460011b557640a310e9f8bdd1f331224f831006a55bcdecfd4547f0706c7d7c98096e7c7cd018845f1a76e3a775d51e5df4483404615267d2fc258d6e773f10e694eaa7a5272ea93901c29cc422ccef7f68fcc1ece9fc2a674d145795861f4c798416a12da90f064f22a9c4d9bca816e48369dccf93ae5126a2321a7b30ed05b74ffd0992043c766800f5c8c1c51d68e8c11c3ee8dece6fe8d8710dd0318122071a79306a95ac4d1ebdb23c0d3c18d3f449defe3c8ead1b3a769435d0b88329dfa8ae8ae3aeb2e19681861dcc2394522162b39524290062a0510793941def2f0d1d344e7cc3e860ca11b6372731475d07051a733068f8f569bb942c894b0e067db9459f9ed8b9fcc732d08883419ec9c848c93eab6b28061a70309f7f349fd12ef377bfc19045b9ce8724ae72f0dd60acb6e8219b4e061a6d30571a1d4d7bacd26954361894279574a83ac340630d860f7f21dce764ea25a606c3ef7b7ceaf52b0de6cb6f531a6a65822ea1c1301f577d7c44f6d47f0663d5969b7b88944c84bdc78e2e7ae4486612e8c00d10d030834959f688a236d22ab6a38b1b5ef48de43aca9a46190ce222567afd21835994a9ec519475e9500f1e39fe0609dcbb20b596011a6330271bb7ca0996188ce71ee247471da540230ce69df3d02a419e34718a000976ec40c081c1e421e438ada2ad2f541b59d87015e4b84053e0e3c3be60eabbcea21d42c30b46115a7ee9d79f343d34ba60dace32a67d1ac1aba4051a5c3088659f0ef7a0c36db405c30497146ccfd22bd0d08249779fbc529beeb365c1f0214a1a0b064b1139faa1152dbf70a07105430caf8921848b7a48c8146858e15f13d5e39663038d2a98ab83485993af22a5ce5fa0410573aaa07d2ce5e7fc92730ac647ae4e792fcd020d2918457efaae94d593ec9846148c27d4a8dd984afffe40c1ecf1f2a2b333b71f7e82714fae5fab444e51b44e30c55c9967bbf49772da04b3779279a9ead2458909a6909126dcac57082a5c82a94beede45d3962cc594601c7fef55cb73128c75a96f29888c047388a5d4bacbc716ff1cc19073bc8b2e1e4d09518d60cef5b0d4696903d028029fda3efc28fdf01f238259276928552a8493dd100cb245b78588721d26b8001a42389f8af1fc0856d2523482b08a88794284fcd6f9f8d014bcfbe9030d209827a78a9eed3fc9288dc60fcc11b48e8aa7e38a901626d0f081d9ce2f6be6fbab8f2e09347a60122af7fb43ca567e120344a02347a9020d1e183d4465d297a59408be389e6e8860c7169c04a0b1034396243eaba78f0e4c93838c8564229d4a3107464f22e85121b5347060c8d9c5f2ed99bf63078f2eecd0b881d124a4f72a4b19020d1b987ef3d684c81dc374707b40a306062d12b2f6dca8a72cd70b3468600ee2bb5adcbb4e84926b0b3466604a95268bb865170b346460ba3c29476d51a92fe5eec58e0c681468c4c06cd1937b9e0b93914230307f768e8a0bc93ebff902836c8f2a8b5a9ef34796860b0c124328152da8b5bb76ff30a315a6cacb5c75f5a4f95956183ce743f477e7fae4ab309c98fa34de9df4fcaa3095904f132a6e9632fda5c220b447d979a58baf1b2a4ca53de7ae2e1fef0f398579c5cdc342f70759d514867df958dd2f77797f290c5b2149081a22a63f524a0ab3ad4748934a386314c6ba17edee1a06618628ccb699ad193967a7c86b284cb28448227ed27e323ea8a0307eb6cea153f67ecad1199f30c8e9a45310beb9fa7bc25c1f3ba9133ae51e25ffc08c4e18acc794e4944538cce084e9a37e2525d27feeb50993ea8710c2cbde473c8bf2608626127a7325f2054bdac7b13d72300e6664c270619d6285c8dc7d8663eb866f21021d397adc483abc47590b6660c29452defba0b7215b3d8e2d0b000d665cc26c71c2d584bd13fbdb0c4b18eff483c51f4fe9e62f05802a6654c2e8ad95d3880a9184f430258cf7a26e65a68edca88450a6226128100782e16010c4406cde4c01e31308001834288dc7a2f1809e27997d1400044a362e44302a162a281a16140a44236130140c85c3a1202010068541c1803018c98a998a6c001ebe7227d4ff4c893a1c064a21168346bd5a80a05e7fa38ca88c544a97dcbdeb3f410c15ad4c0f654f4481054f01525a7aafc6a1a6cc756ce2078c35b26381801428b4a1783f9700161e2a190df0430f5b96a907141cd86e6e49d0f4dc2b40c7bd8198b07905844605ee355a157a0a13506157bc09510879dbe28150eb0b13d6b15556d24bea44dc214d5c5c119c928761b35d0b211f453fb783c4a7868095ec02f22c443f29701609fd2566c2066822445123e254cd230e826c0b65aed9aa8ae3b4e9f3e4221442642ca0b6ad49ae92c5e1dc7cf84529751d0b5b36bd0ba903c0736cdad0e1747d3b86ddd59343269d9b64eefa6fb7e47d9635ed58b06b99c2c31973ec4de60866d9b8ea098769d6106fa543cfa28400e204a9944ccecc1cb41e2785b33b3e281edee7254bad143bf127ec98c8e37b7534485810fac3e2d10a030e1d1ee259f4c0ed454fff1515c15f2104a81d8082c9f74514aaadd1e1c4569f549942a71e21c164b395a092009a96763fa9d4d9b9b4b3946209c38faca2af0ffd709d622c8ab39944bc69720283e981d49b409305343449af35d4566398a1d57ddcabfb8d73b028ef67a2c166732f337821f39558173d877ab24704a1eefb07943c924799015ec6b1357db092fd68fdfc11685a4b2313915b24d63b2cc0a3e12025bc8607a79e7a825face0c33bde3f2bbe0ce8275a0c71c7bc058372f47edffbfb9caec227fa023514c84f9934fc3514af25960409f211c8eb8d43c671ddc616dabed06c3dc6d334e05f527d220ad5dc86d0d81f6c611a76d7b18f13c8570b138a6f120bd61a2fecd298238662124a8cbcf805794fc12d09c4d15f222b9f2ac69d44f112af67c0a6368c54ff3ddcc311c6dfb7a0b721c1b27acd6cc55657d755c9637d826ae2c26d8c2b9f710e6f3e0af2adfb4594077b53d11984c22b330461c57489c4fd280a180f85cc5ec9a608729ec7a67271b2aaf90ec612a9d5119df604f5efc9bd3da94922a8c58cb564747c7ccd10df70faaa424748158c2e07ef51993dae6b4fb963e7c6ee6bbf2facfcec6a4069d6e8db71aea211f43c40dafef579f357895e41d72b0184e1e51a83e3606a19002b13eab7ba2f9e0edc5df12d61f8d87fee5fdb0ebe5f640f6747453bbff5494fc684d6f68a4f5daabe277b404eb290780e221112259922f7ba497742341cc2cbf7fd92ecf37c5830a782bb763f07a46abaacd0d34301df36be03920921b9a82b84ed7d2998a6af50dbb3bcc461ba0001b3908d4458ddf8292f5ece8eb6086b33b5c9c4fbf35ef51e66347defc2eda3b73160c0d4131071e93a26ba3abd3d70f01f717011ef59a2ecc2cf1b79a4551ece6f31f8ef6cf5ddee94a656ce7279ab1b9781be0756fa3159b46bd4330a7c34122ac2e9ac77b1961d83be9f5e0c7844c1215c7781655e53008076727b29bf01971c8fc55bfbd398a450b0e50ddc2a791d042f2ad9550ea33e632def971e001d3922cada547a665286e7f332a15c3f8949deae5daa965693a69a32806af7397548eda04fd25be9b3f44efa34bd853e4d6fa14fd35b684f538e1d2a9b6c74033b9250f9bcc92e86fc0539852e49653369603fda385e8631e7b68dbb8fbc1bfa0b806d39be2d473b1b10a90b5d8256132ac5150a41c1853ad6a481ba2b819abfd0b8df4cf9f37e0605fb44a8b3324f4a31f85465c6fdb3fc78822f428c538a1a3f5078c9d01dc97ebd61c40fa62fb1eae7f221289cc140cfe87a8a269bf2fac8eb02175bf788735b8d74bacce2074a6961b5acc2cf3727a37d2779fddde632d08b608e4523ebde6efc8194f5ff272489abc9a03f49809cd64c1a8207c868fdf4863b8ae2bcdab59d07f0de58cbdfa772ed167329496864daa8a7d93782a803e11af70db5e2dfef20d1662b68d3a46b206023ea33c6721e43102fcfe974e7d8ae0ebad590a94b7d9b01a2e28b8dbc114698b897f0a5424546ceb14a3b67ccb20ef301a39a2656459db12f1e477c1c1610b37fc8d385a40f9d4c9f63d0f30137ae935469a8ed06ba9648bc7c0041be19c00df3858540fc779c9d76983898af01e8b3b256f4e870195e03cec88e8793d954bd6003a782ab8edfd419999d21762cda05e093ff3309af01cb9e7ce00c961bda9d5db55b1c4ebdf579bc1d932ffa3df1a1ea9b1ea467eab0134c157b82a99b73fa478a3932da10fd093d0bd1085883c71b4fc7a00b697cfcd475c38e36d2b90adb004ad09c4c0b2c3ecb3e78c2553bfec9c12023942ff556d9a6703de603e60063cfda70ce2d91aefc699a5cb0734133c33cae8c7ea6b4a6154e6e33bb2523e845b931f7680038b2c59ee74bcaf3d983e112255c4b071f383f317ad23c52eb555a150a3f57480cd37d8c9344a9af82d12aede763b72ce9563196d537710510d4c31e2dc3b81d1f22addb6908e33aa6e46483104728777e0e92f5fadf737acddad86aa56aba7de371ae0dd032c63a1344b82989142281a6274683a8605765f49f1a3291f881f8a8ec3f7c2d1e5a901f9ef410bc3ea15f12162872b0f5063375bba235e47c690188bca7723efb953f2972ca81d821b38c1c66c24f5a1f28ffe012a2e049314746971fe8c882cb6ecc3df93034dcc10e465468ace5250c8c0723f226f0af58ad03e9129e42cd10f4c3cc943d65c91983c0ecc732883662c92b54e52e9e316e12c5cd79a807102bd0d829c82c166b042044e73bb6e22842c0784abd1815933e9f5a09441e07d25ee9a7f72085e60181ae33dea35f7a0cd8a91329f12b86dea3300d8057b28cbadef556a968904d1f3cb4e9ad2212c73ccae654870a442e9ddc61c99f3efb3afa0c586a9176c586781a0b84161a2f4a45c34e095e2884d7c2b470b6308e102a44a0cb5a741e62a5d76c446a677f1404f5c861753d91fc613fc6e9007963a65ddf9ce2b871442d3c42ebd02f0954faf809c4df72eb0bce19705591e8da6c17f2cda563889b95a0b7d0672126ed0e0e18e269a8707cf87f25738afc92583c35658f082b91fa32fdd40b4acdf1dde608005f6e31b9cede6eb5c7171000603d3493bd9a0632f5068a922404facf76faac90ed6982d4b8e2ddab8805365616eef1f65890742ab8948506c434cd6f629ae37268f6b09e7ee3a28371fe50167313cc316497447fa4229e54d8ec7c7ac678bfdff7f8455600ec57f61a5aef0d049ce147b8725349f80d776878fc083a18be147ef46d45d8e8ae819bf9ed501cf0024b8b66489680f0df0284c4b0512550e9625959a5e415af762dde0d8ae9cdb4a94417c14202ebbb5ed65826bdcb6b4cf610e36a3a4fee1ef4bef0ca69b2546546a66ed47c6a2a0e1c42a21f2de434d5f3606ac2e5beeab92bc6be639096960e08f29f9cf3b27784087346a001ef01618a3fe14828d4a6c46adcfb3c2c73ee777a467a4b7aef867e713ef7d713717d2e85b60759364f97a2b1961d13009313bfd2621de3625016d9c0a916508d978d2689f902e7b6771c2da70236e70a4aee45a22f619c09ed63406639925b52d216a060e35150ed630ca240e1a063b7379b3e182ad8b684eea4466a9ba11d62583691458d91022a75d1de257f3e8b8deca30571cc18caf3f84d8c19009e9c17a2b532530154574a2b15a7f2589dd1da3d758f691d0ec045dd1a604fab4085d422f744f9b1740e9329d8981d2c19724ba17cbca91333c2ceb4a0657dc0b6278fd7fe318aef4dfaf05c62a31fc4c91209aa7e1bd5f53861e00d457f01dd94370860f7b4ced54f7dc2785d2f07b461f6f74bb63845d970485211d1321278cf106fa9fb12e1d4539f1dbf2153ef76ed8bcfe4676029716735c21be22c100c6424c022d40f4cd5812b4ee40afebfb6d067388723c09cba56ca16e3c20db67b92320e0b425aefef539cf24bcde020d866fc09da869770f0e59f68d20379986b6141bf53f1d0593e655250e89e4663786f83cbb68c77fe25033283f43532bf183ec2c8ea45f939fd3f20f8205c830203a90bca1d5aa61e6ad40db0e5781478faac4cd14ef9ab305209664fe211e05db04ec34e6114657a54779355405db2f7869f44628a802a60b2d4b70504458a3b271cba314628a866a394c2171988d314e74bc5c29a8247551b712e7986d98336653ad279fbb05f0950afe8cdfe789d15cec79a67c690247c3b686984ba445455044fa776fa4d58bf14ac12882c195f60b2f64e91d468d022cdda3895857fe00d756116190a4dbc90ab314482133c8ee0557690b610213bec0697dc09aff34d112f84dbec42d672f801319543df6227e67c9a2d88f01eef0bc36cb0bd7a610b088d0db05c0d4cdca415c35094276e287343312d57a65033201d4cda7c89c7864d7b10b43c4ec2cefc70b6420fd1fe77ae6d76650b57f8bcdce22818b0c65aab6aaa5a16d1a575729607b8f66ba87be04163a2f080f5651a1bb30a793437a17893d632ec51c7f9f0df18518298c85c15731d27f354b3e49266068b4365800a6f60df392f0f7a12eb0586f23be8d7052c59a1fd41095b69b3a2b9fac4b4518b8aa981555940ebd3f43a29f8004b8d71b2b2a9d63e0f8f8b79f5289c340c072859de132e47d8caad74b6e7c2dd5c9a49c57db5f3c7759f8b761b85d9033fd38e6cbbc7538890cfac798a631e9154302079c29a271cdf87f347a5078fe55801ea2aabd171312149ef7459f4ad27bd10c216e1d478678d25b6bfcf43a8b1f8eb9c5ccbce1b121ce5ea8536ce5f93af5e7cff83d3d2358292e3a847812efbfcd2995a3906c5c140ad70ff037422449c7d2a6b77011597e80458a3f24a68fa1a351c1cc9346b2a92a828142aa9211d9cde5ba6ead09014bb5cf2c0c652010671c36efabd10715061d92e2bc4f99e2229723f5b7cef0ab09a43fcc424e3ce955509ae2da20c8c865122953456a9668b15948447977b5abe75a98e379a0bd31b21aa14e7a07c30fa3072fba029a3e37de88f76363bf0609ac2368cf82b3d4e5f4c62a80fee81073befa72c6b57a06d138b9290f11ba37d2cb36ac47a95c007e5985db8c0f6cd8566ed85bfcd92dae01acb5f476c6d50603b0d6be0cca324fd6a18f0db873c6b9eae044822083d55ea42cc1388557d9c45ece35d008fc48fb28d8cdf27d3a328437afcb8dfa046c633e225b3a47b17898a7309f3ebd84fdf355ffcabdb49c22dbb474f2c1329d999487a1c00b581d771ad87703b42118eacf4e76180f231bf9b2c86bd019094a48d79edc9494e2bad7245109b7b7b59f9008f8d1aa0de33b59acc708472ec59bcceec9baf3c9248b8078f6287a939a297e87751099ff340d8c9ba26df39d3d7b01a531d89eb951ebf9d17af2c1d5e2e885d0244a680112048d2fdaa0da6b99c3b255fe40ab6c021c03864b02c0e7f25243057890f6b16b4120922f8b94c58535d2da119255c99eb23c12dd9b0c1e447da2b8c721dcb54e9b5dbff79a88c3f1ac6b4fa319f157d4c9d230e15b70efab049a76924723d81abd21dec20afa548d8b25578dc6a45db4b95c3403b1533e05ae1c9777eb55fc55d0fb3921f03bd9d15c18fb84950cb05cb2d0790f38861bb338282855c52453f78f3d77dfbc5334a944e93e8a3f46635fb083e2d7574f763f10501a6437fba2217245c47ec9631b447b0703f814f0c4c4c948cb1143b3cb0f843c2336ca0b738d815711ac9c907a8f05a0847a876f1629310370510ae31b29eca1fc4f68f6cc830653e4cf8beb0705cee3da157ddc5a63354b1c31599a943fce2bbc14db0d143460ddb01ff71c7a8af832be6ca2975adaed64281549e18da663aebadec940888aac4e2009d26fe06173a972716ae51647c0ae4094e429ba01d2cf5357c6f95bc292f7bd4f8a2d8ddefd25066ee7a1ce582bff5d0ccdb620e6e74c4bffa5f4521ee00313a08ec09012284d9d2adf4a7e26c3d0b2443e4cac98c63ed078fac70d67c9448e005343c4799ed9e0bc97d859cad16dff72a779839711546f1293da487d181ebbe6ad327498ddf04351be7c5b90219843883ebe6181cd78f590ef4c0f66ed9d0ee237d946643194097067330116ce6ed76f9c54f1ace30f3b66b37161a250d51581a8f0071411666710cce9e3d68136c2dcf7ab0ff177b1e9545273c48ed2f36d101e1ba7a09db9a1a1b2ad2f27332b9287003c7fd9aca197bac44748c127fd0420c7e71990dd2e3123b71c7067286c2695d2879d0a30748a873af90e4dcab6a83b90e04426fd448eef7d343264ecb853178cfa7c4d01cfe9002701caff8addabce47ee4bcb09d37e59c38594eae97ba5c55b44b17936a0f1bee7f625d620d0a6cfabdf2dd0e6a9cd62bad17ee0d40787474025ba132f537886fbae33c05d36f770a4f582f4379149fdadc76b2980afb2e01e5e8f3bb39e2ac4c2d11a5d06e94bfecbd27282013e23eb1ff0eb47f6442412a2e646d645b3bc0f342c7157a3c8d246bc5ad9bdbe34d0191db5a5f588b8d0a13b3fa67202b3958b567f4b5b65362d16353998193d076427b5e56e4e071aa9a9228623e1ec0ed2d395f58c6a57582a32d5aac9453723a48dc01220818ac17bbae3e936012b243c9dbb050520e0d7a5aa02b45dca5eb70b891e7fb2977edb97b13947bee14165255e58944f3e851a9979a99ceca84719db084c80a47d3f60c42aacc87282ee78de8d0bbfe7b88a5ec0c4f0fcadb6cab7b767e6e4a8f70af4f4a273e4252962da29496f1d2cee2a919046f22153eaaaea1d765d25c1f9525a78a11e2190f44630b44411027e11c566a6c4a0cacd4e45ec8e1d25fbbcda08476b90ad68d820056bd90b3573ce436f96c2041fb64adaf284938960c219fd549fb7472ba793eb22c5e5b84751b3d95e29727e046a1aed057ca261bb28cfb365fdb9e5869b6e4f2557c607516dd309b3fec718cb9a2e61fa48411acf3b08433d0f4bd015b10a085e03f04a127e18c774c6f4b13028508a080109d42e0380c13a1c81221d0bba40595bd836e155e3361b714386b1dc23ae8f248680f73e12648e5a495c3443a35d2263bab490e097160179ba408a93cad4878e61d8ed43642dd9c93f68d8048ea9ce03366e14b34994415972594a29d2fc036c24fa3149883a216f19c60dad940ac45f0068179856d91d7c37d58c00280a345ac01d9a1c530e1aab33431310ca7af84d96a57f6c45d27f2219f1477dabe046f95183a34e381fdb14730506b80c48b1b3c8b8cf719f7991f4fc87801fa690bcde01ccbcd5dda0db2cad234615be4a8c403d20511e7f574f06a90067107286af8b5d36f28c176f79d7af0a6551fcb0a281d1c5ba1c4080d86cf670d6df1e605370d6d3145dbaf2c87a07eab1413fe51e041139f887c51557266ab551fd59a256f8e4024116429c1e18d384a6613f53e72a2950c14b014df0e43fc7696684e0deb3302fb98f7a7123037124f8a874b084d1d5e156a4b15ab28f422bf8aa1a9592daa3cf6eceac7a78e3fc6bb1a35eb127acee608ff2591d17a7e1de90103692f7f0026c2869d54412fe296181f429c1768d9e83d77126493311fe5223853a7f10a3d80332fd886c12e02b05c22d8fd31bc343c5350b79e933562c3874df75c7826280edee110d9bac9fb90f9d6d22110dac3dd9cf55c087c3d468d2e84c0342098a79a8ff830b385f4deda0d5508c1400f7b1712c12d716f4d3b2f105a02220a502b581b0516e105237ac11126cef09b5673a32948407ceff73756d9269a12df29b82e623cf8b8c984559770ef92c7d08672ceaf580c3b6a8915680d2e18588f4baa3d2efe8cf293953c74770482c7b19b33df5a9c1921010ded94bd715c7273a82958e436f5d3a4656f3d867bd74b43ec15b3dabce1d90e91c3ea3c60de041f9fc98e6720af6d1b80b7ba8bc206d3c0f0f1a106ebcde046c9253111835fe06dc2f16d6fde93002c0197e73c3cbb2d00e6a71bb160264f879058115f8bb280014e8156db682cb355419c5bf5599fef3b204c3725e18c7da095bd77b878bc3021006ad58ef02bfa78825154b73e77ac2b60228d5b6e2064f3fa023233602d554e0844e386cb6c44de7c9d90f16e3c51a23e56c2937886ae920724cb3d7821017301d8f4c914643b53f40534435eeacb76689845a41721995e442b2df21872a398e5b97ba61dbdb69128226ace5020fc1097a96fc44d8758ef92384cfa1a1e290901deafc804c8baf96d97f54e30bbc3e3a2b1923e3d96463461c4cee7d0ecf090a4ea25480e3c2ee24f16c2e1cc1af5d9590ffb35ebd4f6f7f8624090291f69f81a334bcf719b087447bdab08eeb1e9796956c0af0248253035facb71982638e60bfdd9b24304a84b970611a7befabc8f3b103b244d401c9ae30b239103c41b0ed5a8c05c5ab66cb432dbaeda240b2a3b48263819e0059132b662e7416441a5822a1d941c4daecf3b08e3208e1744ccf35b6e0fca2c17170b22a28e39a3fef20095d92285c032a5a5baeb5f29ffd17e452957ab959a55bb29362ac0e63ae6bce63ccf79a1e37b2e321fff0dbfcd5c08fb70250c66a4c3717cede40fa888c819132904829e84b8b4ffefe30274378da8aca937a09a74976ffeebd0518f071d1b57554ebfd4c6369b494173fe116a6256068310262c80e0502e2ebfdf5e3e3b8ab3b72a42ea7ab86ce11ed5cb5ab09f6527d540245a1cdefc509fc6bce95feb87a17f785cbf203adf537d5347130449358c1dd0ef3f785b0552190fd6e20393ff053572d6d3bbadc2935b9a4182479b04b7c75d67563456c2331b951b3586306d0a92e5b31f95042968f23038b7579b919e72084b8d1f22aaacefa90cca0e7f826f5246f512154cb5d0a58b6a304e77e4837f44aa7d5d674c7bcb1807844ce0cb3c888e942c9feb72ecd4aab7ebf50b432bf2b935c05abd8b7abd607c99a452b6cce424beab4d05ef1e02c61f15d4f730c218664e111b2e449c461544f449c0241a7618683992b108d80dc82c84156ae75bce93460e90b1c6c4351069a1e31292038688c39c00ec02d4273226125150cd6e72d2051661177179f398c4021aec1089cf5cb7103f4d64a0a18d80fef9bea814dd1b5a68b5096fce55e76a9d33909ffb86f761893337fc0f78e1d90924391f88cd305b1e1b09224eed73df5a414030f11d5b6fceeaab72a080055d6b0672f3edb7a012179c750e899ba3d9f1460a4f0139280885e133bb3301012335b37380105524082247d88b8ff82fb34bf3dda0cc90cc6e67dc50043c66272bb0f295bbb55531bbd301bf8fd3757e85d965b2e67344376076bb38c0828d8abcdf3f4b3cefe57653355f76cc629c8570de65b7d998176374df5c76cec9e990fa2dbb75ea7f89d7b25b073cfb6467d96d07ede6f463d9991303987865671141b3615c5e5f935bd991f90573f3abeccc4cebdd98ca2e6d91cd2f338f6697d44fd9cd79f9495fcace1d9acfd447d9adf3c379f2a1ecd699ef94ee27bbebf4f124d1c9ce320289b90e50c0dfdf64b77c1ef08f67b25bde0cf8e7bc64b7acfbeb97bf033154b22b7de0698f6027d9bd1a3453db85c72c921d78a98b7e63a7bfc483f6bb4e444cdc1f280ca57703f48eec5a0e6df67f3823bbfe8d78ca5564f72f30c11f3185c86e769e5d7d6763c86e7755a4f8bbd90b63e8f9c4176cb1f4cd55760c0c1d8f0a041f58e2dc2da0200170d476f9aa73a063463531cceb7a95c1cc7509046e21285e0d3f7207559e5bc10e1b572f28b2e0d30b5cc2262780ce45469be3208e50dacb9f3d80dd3c05727a95b74eb35045e98eb69306ac7a88c29d75b3efe217730b961f360a73877c8557534f56c25dd5618abb857027f4386ba6ab737067b968d9f23e6d1a05b7b26881c139ac2d838bd5b12bb5a0ca5a242f8e310cf14cd69194858b6bbb3e6e7ddb8495852a2cfde327153bc21052850de3d5de4ab76ae1592d9b0b4f3791c434c9cbc735d2ceaca3b2bfd3fcb1af9428cb30d4f41a78052149b06255b68f11d9c82f0f71988a2845b56e10103560a29b2e6861a77c999c3f21c81d37771d4b244a9cbe6cab26e71d03c3158c3be2a9bc07a2289c15a8b30ccff1cfad9c91dda966af3b65114a95c3d160b102dd5d039fa6ac0adac0696239e15807d3815795e289591fb2993b2fbae6134d5ed2783ac3f898ce94327345aab123bedb068d747667912c532e38bb326f3ec300c4fec6496e9dcc562d4927d4829efa0203b083969734e30a9e7ea7893936a36d5908a4b07cf2311539f54d0fa69758493f57004b5ec96d98eb26657d945a8c44a1d6941ba506017054ffa6d5cd347c68a81250c57e90c5de569ff21ac73f8ebed491dd56de7b09538e5f82b95fe4aa1530ff39c51b7b12f7e93963af257e17bd1d5a8931f9e2583408b9912ee98561c8944849eaf4a36ebff4ece8f0c296151a0b0912e0b28a184c3d6ec421ceada6e7dcc1fee569aba411a67621fcd3f0e562b346b4072c44f318bc2fa7f5114939c661835127ad878a1807179f6b2781c1221561263d799e825da171f1ab7c6b09eae5ec4d664bf7d5a733ef7acc313899fadf4d4e80018b5a5302de7a1aef011124cf267602583b3533c4a84e1b69200b09efe6154c8cf6c00aa20ec3e3425c2b73ec5c8be5a7a82b265f195826a15f2ea7f25491e75cc5865382cb05681ded728fbe0db0d3508de8090e20dcf42c6329472413bcc34f19527e6838431a05aabcc40a17633a9b2267970a2aaf00c4d82f137354559538252d74f5942cccabbf42ebd9395ebb421f08f617c3ba8ae3c9630fa44abdbf1b7257ff66a1dd5cc8ef93f4f58749229f387d61ec83ef9f292c462a7843e80f6188af54c69a1626b9e38d66aca57225b30344142e4508fe20652f89a250d29abef6c52728485a2cded1e96710ac267665ef90fbeca7dd3e8c9597b789e34038d4c2103844f700aebd4fff1d6e5845c6dcbbdd84a5736f0ce2f24388d8ad03c89489f4aa5848a44e3e8ee7d502cf9ba2249ac1b8105ba956ca0be62522cc91983eb042ba4801a859bb17d227813055949d4b037f6fa96a870da0e360f9fb6e5a5994980019ae268b40397930edb870406811117b6b8ce35ba5bb61361a6a9220079e4b880a60595331340fe8301566a460f81904f231ce0a86e4581decda9a815e013b145b160d1c3d93ea1718589bbbd5d2a657df35c0b8e863d6b03190b7f93a277e9141390840be0f072aa5690de3e92ba55c3041ce7485dcc8fe47c2b5f946deed47380fe8060311bd456a4f1cdf7d2062c5e4bb19ad7f1b326665fe6dee892c5f76a8db8fd7540f390b2e2c32080772f6ac659503534ebe9e6feddef4c84a9367c5535754490ac41bbead31ffb6cbdb2cfb0cb786c08b504dfda9b0333fac951cfbeabcd2c1a4188ca7bf26f36586f529fa5d18bc0cf43620d0714f566692e3d70bc110de1570982e8b59a5c04e9bc0900cf686af0330b90ec1db55c93e68910cf4d4a512653a12b0eb8c169a9724a8fe9368785cf507b41c7b25dba35d8e4f8a8435f07fa64a91ca52bfb34e58e1756fea21fdb11634335d47a1200c30ef0e13390b90b797baf21e13456c88a7367ba3e0db9143d43770842c2b049f33c0ccbc1a4b727c279f259a22b8b5c6db8b327215db84a1506772088a0253b54ff9d265c0062b0d99510d00633fede1cf1c9ef92f0dc200a18e8b5266327a7564d050417dc08d42b70c7f2910f77d6ad672b600ff91803f533b2e2e97563f4bcb11e6e384da6765da425c3dcbe4f9e629ba767f5bccce9d4b5d7893e655f06941f1cb4e90e8f16b0963c2e5686d0821133b16627540325b398d0149e3b622fd7024f778c150aab533df1d65dcf13456121cb4c42bbab739eebf2f17b938cdfd541d59e4975120392f5df15447ad758c64984ad25b3421337a8a88b27d0a0d9a83fb552ceb7151c5e1d5fa258dca4dcc387413c08c8984a46d63ca7d9eac1c63d6f26ad47f34407cf3cebbc9c4e3883a5ccea3236608511de3da112b8838ec0881d19090229244999efd644aed2cd97f313ed102ca2daf074e65795ba79377b3015352a9d6ae7de0f92fc1d5f0ba993c45dd8c7e16add8f61094856ae5c1d96630825f44f285e0259b025e4bf0ca32e176b85ffe54fc94f0319f01b38c8b1578822f301fec67b22423edeef5a5827493e94b7d108b2209c27a9bada187d8ca74699a288afb20474c4b3f3080c30b6d9887a0988e59b112155f88d967307e512bb00a099458aea6f83e4f15af888db31de122a0569f68e849eebafe9d29ac440dc5d0f9a4c2e2333aad0bdd21f62f2a803582420dec0100abda0aad36649e33a5646e6518ce7d95dca975293526c27803fec6ea8bbbd886401b0d8fc6b7ba83082d908e4cf6d27ae405dc80b1d863f55a7fddfba48d016be7a2cf947b8ac842dbcb9950e6833500ac88042296034994041d217e1922f457536ef19e4274cbab05f378d0bc4a36fb34bad78dd150763b5dad2823cd8a000162524961d964f83e656c144562c28e2b28d9abf0e4510dbc62593ace27d0267732447568953019e8cacd0061fac494c71ce0359bba502975ad60d1be957ee9622c5e2f2486528fb993f8baa4aa43edfa6cac4afdcc16444ae862f8a99da179f7cc2ba60b54054953e00fc0bf594049496440fed02a316e1b0e0a5d7d8461fa1675420c389fe6d48c77044c72e5c0a30e2399fcb4e9c4c805cc66040677e5e22ec0df8757f141d7442ca07bdd8d5523b8621253a9b2bc04796c8b50f7844aa53e9a1604f39f03e8b989d3e2b536c0208d3658ddf76db120f08470805951a85ae267c1198d3b33d6b75389a7e9f72e41a425e87b7e9318dc01713ffd381b400c8e7a73685aa56f5fc344d6a5eb5f4a443994d0b4984571419daf0f2cec6030841c6a23df58bf07c048cd0c98f3e99dafeee9dc760ae812d09bc526467d5f0ffad7c364a919563db3309c16ab8d5677c31dce6bd87c69b3556d66bb297bd7da8223a0e74f2649ffb00d8fc71e1183ee8c36d9fdf84534440062b37e14170844542c58a59f88c8da9821056cd4400d2201d14904a460fae0950ef8bcac8fd8a30b2905a1c78aa73b4d67e528a6c831b0adaab3c93d1e09701a661016baac54670e7f67432655950d0baef2d1f908205ad461195c0d975fc91ae53efd5f599f3c9d54445a64c6a71e4edc4eccbeb895b83d11d9597c00661be914453ce9b8c10fc8c1ba5806d1cc63e690099a4deffb20393564fc8e26b3fc959d8c1e6e7bd548a4c62e354eaf46892e0c212c2c2ee35063757264c871cbeb4376cbb64be25444d906c7312d413a2e401614d309687697222b7d9049b0bd33148f7ed370dc8ccbe02dd48fc7cd1f9fa79afcfb257637c318fbb91663180e5e1cece4a098c8013cc85bf2e08262bcd54175f88b03c16bcd0c3011b93eb67b1ec72568bae23da446e593431a64826aba043d62b55e550f29402e247a8df8afd4c8d236877df8a84aa9886ef90d88e6129a5ccdbdd76ba385220f28203cce0c9c7eda4125d5a9f82501abf4d46ca94e5452fbdf1392bad81d5fad1fbfbf225ed45c264082ab151b20c4c5bb788725f56b15cc92cc9142a87481ed337b944789242a4c9b158434c088fbac1edf50aa867aa2002cbc296cce78142d66d64bcaa4c26c3b138c626fa8d309e91d55996152af61c803fff6eb75cc55cdb52903d7e83b180f64534c21694c00c1e23042fdac24c682ff0099a742d1747bf816cc49581de395714c11fc97a2cf38938c76723fcf49a34224a66ab986def170b230e2c09201054316bc2e560681d935ac544e30dff9b226a8b0db088c814aa3c22efa44410803d1f67df897a7b188095a0c6bb4106f8bc5d8142b412dcd2cbd2c440a7495a69f8395262f4c68e44ddb3384e6beb5bc6da6d47c303e589777f0f3750ac35e75a60e2a940e2a1772dad861049c01e3e95683fbd3a163fdbb05c5507f86b8ee8bf237dad1d928f19542d29fba2715bf1f5ee649ca7dc576e643591814f4d185258859a08d2d6a8e8b22f28ffa39afbee01c1c8e0861b52c9baa8c82b9472f54b41fc9ed6f05eb7bd00d84d74c3577310aed229edb650eeaf4d0b0bf516aa4d752af9a5a5f4d2d8a1a28e3daf31ae7b5a635d0d4ef2ba65a3c4ca9f29508316c07b98763462ccbb125781f3c089fe487b6eaa84c1bd63c579ca022acc15d1fd7f2a67323dd93dbf08e7e6f6e4f1c7dabfcf4234fed9b42180a7298afdfd4680a6351afa407f12b1cd225c524547ee68a31c52b73f0f61837c50570d8a8f00771031f9a485de9055d2520e8f56d798abf44de8eb8b45a7c660ce30c3e0eaf5ba1593608965161717e9b68ace84e9686e8c7ea603a8767a67376a76088b44a5bd0519a4565c66ce4306a08faa7a6617812329b42e9676a942cf20708acec86b8668ee20bf4c6a09981d744e9d7f86a667b469eecb88f7d721605d1fc0dd1e02c6364c552a566749e70d8820f422cc44c0591a82add2e06fe69964ee631669c479b313c6ec6f3a819cba3d1611f20dcfcd7d13db10b1141f303bb685d94482f38de9e579e5312dbe17ffdf5dbe25bcc525ce8ce312ef1f9f15754a500d63e13680a903925dd3037e7568cd0706b08fd5994575ef9f5ab4489d6269d771c7b849fe042bc7a9e734bec3e78503eb91d5e642a9e6925add03415233f51817e55f4b5e0d101b3df8c0ccec1b3d3529cce52e1c81af3d266b6bb7d289e63f5a6bd316f775c6b1d47a7266c68504b34fce862c55ea66000e50f612c9881f372b6ce82cae02ad2f6a66fb3e0205bd1a6082a1237100ff2c88e2e8675ae98a1f362b66e46ef1fa77fd9dc9137f38f05fa70aa477c70eecf3bfe66be536fc1dded8eb997f7f95b7c97de09376ace8ccd62017478086eb3760ce24462894b0e2153682985b5f25ce2eefa1fc6de4842ac40028e1784740a3a60ee24850300c3300cc3300cc3300cc3304215c2bcbc9fb4919415f27b81941aa16fec9b64a5ac484a86e799995ed1a2456d04efe08def585702930a310a620a3fe8d0c3238fff6ac9ac6eb1ce3c3ce8d821598fcc8a9b3c820e3c3c48e675b182a6f4934a083aeef03072548cdc526f8f7f871d1ebc4fee887bed1d9a89410603c610830c065c1d1e4c54f50ff67131573c0130860e3a3cccb018e67e432c871bc9d031870715ef2ca4d6486ddf7388b1812f74c8e1a188bc59de8958a1230e8f538e73dbc9f46df30b8707d9fc4357df5f868e373cce1ed93ebde2c4dbc5d0e1860739314ad654a591901b43471b1e7588c9c8b8561200430c312c501d6c7828e5a997e25fe89d1c47569e2a45c71a1ecbff559cf710520183bf68141c27235fd1a186c7ab73613fe5bdeb2a716441a0ac230d8f6ccd25e5944861dee2c852144c800b2eb8e0a20c08d8b861230c31be20c3737c41c60d1b373060e3868d1cef12a84018627c11860648d1818687a93a7bd0af8ad49f9f81081363868771239e36c7e7c79d65781cea7924427f54d508191ed79b5af6f18992f58fe1718cbf715d2c5d22753110f1292ca54f17324d617890b59579cd2a44bd0e181e8e84dcf169ec2f74a77e1ed3ec8507fa1fddaba39a8985bbb0d768c8229e11512b4119db453ea2830b0fcf47f384b877f12b5b78106de5b311a5161e9fbb25c90e294e0a3b175c601c3ab2f038a365c5254f3e3e161e456529fffbed7cb9ebb8c283ebd06f3ddd4b5b96047458e18197c6fe5499eb29540ee8a8c283e49363aa525decfc53e1f1bba510fa9b9ec2e35e0f9fe5c647235e293cde0db142da48b66057141e46d8105c52e8f28a5307141ee43cf92f2b4974c99b273c8e312293a5e69379d2098fce2da599ca0fbf8d7534e17148e76dc59852e8983a9860ea7665c4ba4ad66dc7124e7e96727604bf8f122a7b8b5975b1fd5a7561e3464712fa5d8df1b2103d1216f9f81159a5eac2c60d00dca0e3088f3b27fc5bccd77fd5a9247418e1d18f946876e8cb17241d45782ca94763b2905162f40a1d44781023565fc55b4977a563088f24f7377a88b618c4c2057708e1c15f75c7e74ee1f28438b2aa051d417850399975d88f28d0018487fdfa673fed6261c21f3cde09dd297af826d0e18307252de671a43ab63512e8e8c1a3ca19777737f642bf83070f3d2d5dd27995760bc191e55f9091c30b62dbb103b7d7fa2e667571647159870e1ea876085912e5adda2b52e8c8c1c3fe3297f911957c1b133a70f028742fe844ceb19385050c1d3778d831359727b16c6bc12e74d8e0d17952cb5eb9769bfb116c183b812d74d4e061ee9bda2c99b4eab283064585cb888fc9193c08999092c1638f386fb7e7f5665d0c1eacfbade6f94b88ca74c0e071fcf93029dc5532df5ef1b0455f43f77ee8a8c5158fe257cb6a87c90061462b1efa578ce1ef35e59fbe8319ac78705e65952e138841c69bc2aac08c553c0ed1b416ca72ce783b43156f7f087aa1928a87662d21ce3e3de7f6ad2061062a1ecf75ecfb687a3923c4051739caf8028c728a87a67935a74675cfb84cf1c0c3afe4942e6639e4cbf8a257e0a578dcb369e982c5ae28cd7be185a90dcc208512c363f5878f3346f13047e87f4de51b57641c595839caf84202898119a278d017ec443c4e7f481f4756190446b00b2895a38c2fc0b819a17810f7222126f63c856906281ec5a814747a369f7894d2eb623ab1bcf992e78b1b4498e189ba639bd8c72ccdfd7622d9b8963e94f44dcc982e6cdcc055cce0441a62c60d75135fbc797fcb932b21ac09d27a8a9c93945733c9c4217fbbef77289fbdb40b1b376c6417366ea029666042dd8939dcfb42ec5ca2f7def9aab47461e3c6716286251efd85bf2d8baba32ea9c4a3ed334d6aa5f9719202b428f13844d215f3ca21fbc71190a1001c39bee080f9c08c493c9c10cb39e92366cd1c10cc90c4c38f9c7b4f35d2d57722f1a8c2da84af0af519d2907818ff5e3a57cf331ef120b6f4a41c6477b336331cf168bb2c8fc86f64cfde8c463ccc99753396b9fcc59ac188c7792ac53f776d9d75110f53b62dc46c4b31353a43118ff6afc4dafe2e763c23110fc37cc893215c66b1f455620622b649113bd2dc357988376c3b7e9428d16288ae2de8a706bbb071c35c624621169bdf4fdba71bd213c2cecffc5dd9320d7d1006ff8898835ed2d65c1058468fe1f9c9724e20d064d65a3157ec00a21423c36a5eda93ff60f2c88ba96b8be9c27e6822d785bd7d504c7b64c667c307264befc44e4556f65078e631750d5b153d147396ecd9701e08b5b1a623f87f59f040659f8494cd9c90ebc2c60d2289197778545d39427acfe2c812a3ec0033ecf0386544cc5135b4ad5933eaf0f8f7dbb38cf53c9841878756493e868e891d312606059630630edbe94f5ad098871266c8e1a154874e29a6d34faea861461c929be4111787c32a3f53dda53af37943b925c67c54fbf6b8c1081fcd7b2fa5dcd76d20eba4bcf8b0a133cd1bcdac25de3538f1a9be3d713aa4ab86b24b6494f6681a8ed8aaf2fa94314b45c39f29ebc77a99889ee1f1dc93e19366e46c9aa1dad1a0f12d31e85bca50ee0ae99c2b7b0e153214d52a69bef91c231cc3521997b24c252b550c64109bfd5e49f7e085a1ed3c6e31d8a575606037afcb7c2a46c817ea8d0c9297bc62e685e2220433baf04cee34712293ffe4022b955267fda49513d2858d1bd688195b789c27639428b6c1673734c30c2d24a173e6bf593a643f0b97264b4b79d368261f0b6a7ec85765ca6cc7af807b97cbb9c690dd0a5e92dca6f3d3c143af427d5ee3361ff3867ba8b0a5b4b17d3b5350245a0ed1fb96c2371ff95d628c3747418999a93541c29cbb50f02cacc6dca8cd84fb84adf37f50ab5c95b675c27177e6729cdcc9724c13cea59bda3f355ac304f5d267713353dfd52cc13d4b271696c12b659480df650e13a349787fbea348e8d4337d18ed949bcf23187a625ad6e5ecd20855fc60962cd3ab7a8a80ed4a44c44cb3a126823e159dc56abfe32d43a8435aec7aa5d4280ac16f919390b2ffc44d10d67031cba43c9625048279717272e97e50ca5069c38416d907d759540acb197298480fc877d19c32ac539e076eccc8914290307d07c7afdd9027abdda6037a63aeafc2e7883939c8df3465e9e5690ee3a0d2ec94def6ee14ac1b78692feb1d1b9c935845af8de6af21ebc2c68d1a3cca92e041925b4cc81e2266d0e0a165abacf9236ef41443881933786cd3514276ab44c95f060fd7a6d356da0d0662460c1e5af7fbad598e52d3f3f83003068faedc43bb3d5486de4ce06a0f58bce2816c66ae8ae9b3738aef0e58b8e2719a889fa79249738667072c5af150735bce88e94c3d8373c082150fc4a3b8cf46a69eecafe2f1658b10a385575cf3081cb050c583d2741feb82fb062c52f1a0baf635667b6cb0970d58a0e2b145dc98f1a143a88eaa018b533cdc6951b7378f98961b637cd185093c0704340d5898e261c7cfa4e98efb182ce862095894e261cfc51862a327f91e1b376c7421011ba478904ddfc36bc76b148f64a3e54a296914c5c3b829bac66bb8b471b33160118a075d319e7b4a8dee75de00c5a3c908d375d1935ecc9618b0f8c4a3905a9a2b7647fbcec28085271ea5dbc82929513060d189c759a45e439ea89ce694130fbdb3790c531b39215ad5052c36f128e999dde8775cd76419b0d0c4839e9ce64c37757c88dbb861c3461712b0619589079963f84cd5ea7dd1928505261e66f7dfa44126ea44d5049ee3120f5e356e9e987aa9f252a68085251e44b4496b9d74bd6a458118262050c0a212f6fd8594901aeca644132b7346d32cd7153f0162e4c02205d0f0c343d98c713c84ae2f3d716491aa0168f4e191897d45fbc4866b9e0f565bfc1839de84ed3640630f8f3f55fcd54d71649503d0d0c3e3fc0d9a93fd85a4f3f3507e4c89f7a08187479a3ce52634fa3bd23b3c1219d16b4d115659000d3b3c48df949d3a7ada6a5c87872e925acd5724346598c0735c793a80061d1e06ad9014343b07066f17550e066f0e441a7378a43b927664afe3f87278f8fbe9ddb642e4cbe3f02088f4a756cd8e331c1ee5f4e17eec634e297ec3c3bd091f155285fcad1b1e59fe965acb8b9f9b363c38b9bad594142f25d9f0207f84bbdb8e395259c3a33c31dc2edefc7e6a7828fa396368f86978d0baf9f1248f8647e7693f6ae28f78cef068e492c7dce6fae99ae181e5464b6b113f53a60c8f3a53a8f4471ebd90e18188bfbca6f339918ce18165efaa968de19589e1c186fc193b1e27d5158687f9deb2212607c3c34ad539d3eae70b8fb3e728b94e9ad1f2e38507fdeaf1ebd635687cbaf0a0fa323f49f01d1f0f171e4d8c7bb62969c50c9e2d3cfe18529859f116fd8e161e56873c99da67e181c690739b85d9301a2c3cca2f7e531eeac22e5778f09d3b56ce826e8c5678fcd12edf7d8cd179151edb6ebca8a13dc60e156acf197332957a0a0fef2b2afb67293c08294f91fef3dc3f47e161c4e74fe529756767289091222fdae64f787c6297da63d4a9c74e78b8e9976db29fd6266ec283ae5c73f7b92e2acf8487ad6f91f37af4fd2ce1e1ce679fac92376f253c72999c2fbe9e2d9f243cec9bdf4e39f7afa68b844732d6f1e5b7eaeb1fe1d15c0831c6758cf030588e8f266b111e5f5eda4a1aad9a62223cb4181ec283b4dbae697762e78811c2638d9acb10663c356582f020fc424e5d0f101e7b96a42e32f7d13a3f785c97d163561f3ce89433742ced554f0f1efe8755affc10a990070f53455e8bde9052b61d3c4a9962c8cbe4996e1d3cea18fb0d1d2add5a9a8347a6da95248613078f73375f55556ef030ab26bb1ca653ca5ddae061c40dea9ff215f6a9c1e3ce61af7b2b57fba6c183ddcb34497d3e84aacce061ba328b11641a32786cc1b3a79a2faff0d288c123499d74e7b593e9d280c1e3aa7d8fd6561915f38ac79dc7f5dec5ac6e75c5e318ce275c8cd88a07e9d16656bdb2060f59f138489ec85ab15ab1c3553cfc1cf59c337b324f50150fb4c2794fbf988a07a335b9d23379828f8a0771a534678424993ea7781c3ecebae7892ee936c5231ff5898f5f134b97e2c1f4591299cfbd9225c5c33013633d6b46f130ae7f94ac9c95f3a238bd76ca259123a17894bc632a624240f1a09268a7d2f3aeccf9c4e391f1892e292f1d4f3cd60b9b663d072f773bf120064b3d1fab764c4e3cd2746b13227cc895d9c4437135a938c91fc29a78a479ade13da2474d33f1e0f3561e4ba121ddc4c4033b8d9ce2915de2519630af728f251e6bccf3fc714a3ed395786c1183bcbaec589a29f1307d8adfe176a2f5ad493cf0891b11aa5aa1b192c4c3cd1936eb128987993b9e3e6f45db85c483948f88d2ee231edacccc64b214b61b473cd27fb770b535e2419cc9521a221c59632c192a60c4a320b3ae1adfdbe62f05c862118fa3a5deb45f17453cb091bcb55990c33a0c1434e03a0c14fc11208b443cf29c226f9649658613110f2b5b48c5ac31a25339c4e359cd58bb4aa9c863168678541763f32926b2bb9745211e6a6ce9945b16d95917162c19642c9a200b421417278b41e05395dc439ace95c59145822c04b149e8ff330f37f517609471830b2e8e7f3186189d02c700175ca4c0c9483b641188e2228c2c00f170466a2b5a30b1cc0b4756292255c8e20f0f2fee237d2264e107d7bf3c04b95b8f6f70c1c5152eb810838c2f5210c683a8c8c8314600ae90451f68b7b5245af6eff3e1ac6de926e48eeeefc1bb946ce6743ef27b3d7439d7c4f11c542ff679304657cc5c6e5cb31e0fdbfe67895927ff7fbf0316f247eb1ca2773bfc16c62d4de27520b28f77f4cd11a60396738cb7da392b278b391cb243eecd3de3c9420eb4c44d1bf43e77e260de8544cf1d5672e0f0707ddf44434964849c2cde704fdefa6629d7dd709ce5e0773eb9e236a82fdb99626c77d9f04fbe188f9d1395ae2191ad49c9f4c14335e8d2a94218b9300d9bfb4638c91ecb3f3418c5f725c5f49d3b831dac2443244f489b819d30715a970149ed10b12603ed79f6791e83c17f72dcffb41a1683393cc7491a7437881c062bd467d19ed280e1cb0931ed9025f9c29664d22ff6c2afa721b36d2de22e6c5e16f31683e6b9706c8b36eab1d1ccb385a7bb6564a526a2d40231d9547c8daf4b168efc9f4b97381670f5749247422e0f5ee18ba031544abba93f2b98a5691e92c507bf0a5e956a324fcdd0664105cc37763cf369dc4c218b97979c31eb113752407724a9955d691e852dc5cf2c92dc365940a11027b2fb39c24fc8f38659c6b1bcab13980ff12e53d38463645bb2654f1a261073954fcb651acd128e5f6f51b93dfa4ae0735f489d847248edbfaab8f9374830a4adb238022d5fb6dad14423d031a5ca5a3a3144488b60a5cbd9397c309d08c4c921b6fc4d9c87c0de85a01f6724bc2b04643d7a2e8f25c10c029b2fe74c13202ca1296bd6385fa9fc81127aa2922f69ef0373df87b09bb3f33d3854c8265ae101d1eb5177c9620767ee09297da84f962c7460e7983d4cce295c88258b1ce8f3b152fa14e255b2c081b26add19952c6e80546ca02789bef01324bdaf019bae63d2febf21a601569925e4bb929c99192873163366bce8a5c8409b68562b662b6216317814268b743efbf908412fc64081172510430c30f202366ed890808d2e24604302260559c0e07184ddd48f69e7e9ef031daff032fb2a64637b5cb1c614ab424ab373ad78e2a4d0d375151d3c56201ab919f74a27b78ab6d62b63e4adea5451c7accd7a1a5d26ba5498e144a5720ce1e74350514448aafc3b9725a7c05ee42224a6c414a79aeaf54a41cc0cc99db5430829f21d114913320a2b45dd91601715c591455d4cf2506853c1ef75a7a2078a7e628add88465ffa89f24cd6e85091c9e3892468b8e53a511649363927f90827be3c3a312b17996d82787f977591dcd74441b46d627d0e7726bcecd7112dac524cac194252d81999dcea129c64c5649725dc2475d6a9accccf4abc394ebcfe53a488727450a24b99acfa39777a80961f31c23806744ce2d14bd478d29872afa1ea90c4c30a59da268287e43f7544e2a159c82178c5ab6a4b8b094407241e9684eeb21bb9e3110f5272aa7811950e473cf6f2d08e1352deb50b8eac33137434e2c1ef5dca84dc8c641b471661c483d4741e951f438c1c5e789599083a16f1e8fdafd357864c481a2c7428e2b16a77d84a711b516c6c4347221ece797ecc2ff97245357420e2819476748fa71f73d9211ee68c89a59fa555300df1589256f4eb8414e3856ce828c4c397bc92e284b1ae9609f120a3a5e8ec2893337b4b39740ce2c1bac551af0f71d2c65c1a3a04f1288987470cd265201ebbe778dfc1825c0889aca103108f75a3e5b35c0939a60c0d1d7f78e061e5b13f713f3caeb4497a377e6bc4d7faf02863baccdcc986c856f2e171e646c9cf9a2f584cb5d0b187c2c5ce31ec4ecce1d535d6f020bd4f0c492978867925a8a18607d9b3dea5c91e928687e5992bc538c1a25eb0808c1ca42c60e3469132b66a0435d0f038a4627ff2f839c383943cfbb2ce33123f6678a4318b56f60897e1c1a6e0ba9aced57337323c328bf6b1e2848f21158eac1378fb060851630c0f45826a1eebdcc92917c3630b221bebde0a438c2f72f4175c704155230c8f32f5b484a878eddfc191e5fe5e9c30d60bd245053450812e24c0821d03f750030c8f7f7bd5c274c595387194b1640da8f18587ba219468eeb9d85e768c0c58a186171ec6fc2f6f8d39a4f5338c1d230335baf0b0724c162e458e993bb864b816036a70e1a10749f9291b3bfba2c6161e861852d346aa753a8b23b58616c888cb9a66c41a597854d942f3e64e1250030b757d6dc4fd8c308b71b4c6151e8e8d55c7adb22973bd600118638cb1556094a108a86185071542929dc62b4d31af82fef792f2788f6454781c2dfb47fbdc994295a3c8fe2585471a25bc2f557cea7c47618b8b6de1e53739283cb294a36dfacbbc93e6277c21e50d333ae141e9ab77a5d9b0cc2c8eac7230d80c359a600a41df7eae35baafc184c71f21dfe793c81cef97f0583d86b460d351c283add07821d72d2aa693f0e82c245795be487878a613f673245d65f7088f6235eae7dc18233cea90fe5a9ae53e8564111e55e414ecea6aa2934478143cc4dd0afee13a5286f0c8def732e50ad9367642789c37a4f8dc0c8998214178d0f71a3675e3e3250d080f239dc690d773dd42e8070f6328dd0d29c929d9c6070f5c42a5d73c5e0f0e9d1c0f1e5eca1693d2a6a72ca11d3cd8b393f01be3a45f5a078fd7bef56cfccec1a396f388f1edf0e0591c3c4cafc982c44c77d13537781c65394395b8c8a4c6060f364e52640db5068fb3d36c5b8c21d53a4983c76229672dcf6db579a9318347eba923f3f62334a5d490c103898bce3c61cdc72b3562f0283654ef46354bdeb0060c1e9c4dff27f36c1779f28a47a9de7e17dc3e4d4e5cf150a3cfad4d58c6a7d68a4723714290e41a473563c543b352094164d2ba59abf846bac6b64254f128a5aa31bf743259552a1e67cfbfa4de7183c6a878f46672efd5122f644ff1d0734376c68eb0a085291ea5a97d90494bb039ae148f53d984d7e81469354f8a079e22a66b4c9656223e8ac7bab935e52cbdac9a8be2c14df6ea58bfb2a93ba1785061f773d81cb34957503cb8a87aa65bea271ee4d28c9b11db1183ea89873da9227db2bc896776e271dc48fbefb9f3641a39f160d24ad2ce0a6ee2814b6d9c1c93929d68e261e8ba09a2c1d6dcba4c3caae914e2591da26d4c3c4c933dba5fbd9aad5de271aaf1fd8cd029e55ae2a168f29660f613430855418b4a38a17464524a3c0e3937a77c5b6af9f649e8977636ac54522f035a48e241cabdc9ed3da77496d1326811898763969b337e782af340e251f09814721cf3110fcd4fc274aaeaa9f51cc14c76bfd9f8b1463cac8eb639d667c4a3a81f53d21833e9a68b7890d33d5b2c715d0b29453c96a0ba796d3d57a813f160d6ef2ba3afca5639caf86205ee4592410b443ccadc9761527ea51c1fe2616a8bac61f37cbf6788c7fa13ac2b75f7aa95857860ffe529e4f4b447b420c4c309f12d7c4a3183789016dbf27c6a1dad50108fdfff7c226c9c285719617cb139c21023108f63264da25da2597103e261b88f25bf3a21edf61f1e5bf458a14adfd6d6f6c3032f2937edebacb16d1f1e5b8707b78a2b1f1e4aebc667db46e97f0f0f464f3ed8dd590a991e1e7baeb798a32964a5ccc38309d54e951483794cc1c3a3a42312fb8216777838391f25e7cfdbe1c19ef94fa7754c15bf0e0f365ebc4899633ec49c0e8f247d1ec916a1b2273d87473a15aaafe36c889fe5f0e062a2d6c3e2367d1b878762f37392b6b1276de0405ad088217656dff03853ce951eed342126ddf0a8729e997fb9df0d651b1e6e8e17d9b345f05441363c8812e2f6aec429d16f0d8ffa442fb2cbc9cc7c6a78a8729d346987a4e1d1cf45cc4bb1d2c224687834e9f2662b3b99cfb1333cd68b8e9e7333333cb0704972bef766b60c0fcf72d8df9e3091e922230739c02260e3868dea8216643883c41847836ec6075a8ce1ec31e6f38755b2ec8be1c14c447f75abc79cfb309cccc6cd652a471e0c7d6cea9d59fbb1d1bf60f85eb4fbfa14722f3c8c542a65299125634e0e2dba60b28eb13cb9b06cde33c94acd1654ab0c3dff30a1a385a3b996c5578bbd942c2813a3e4fd0e318505bbdf3a487d053e4e1491143373ace0aeff269f97baabd0a4b8853c16b2612a342166696b908d780a67ab884d1652d35230c5e76dad3c694adc281496aee4266a730b855e62accfd89c7ef384ee4ee762639c8058d2a86162f04d4f134a7db91065c2ed49b2c67e092549b2d9cb2f85799540659094fb344afe259350d87427fe91f30609e7bcfbfed9536639026916c57e3c68088d6054aa4b1bd3a55c11d69c1ff2ba9162227496fc2c9c4f30878004ebea1021bcad7551daa24b160432255be54a8f1e534048deab3f4b8c3c92da183b810c941a634de08583c12810e3509121468e353dd0e2078f7c23b73aeab775922c202387b2808c2eb4f0c1e38b92e37d3e867b09bcf026438c2746ac045af4e0519254613e850b7d1e32728c41e5393687186414d482078f76227ec24a2d5bba706469392fab163b7814529e548d2595e344cb60417b01c61826f862085ae8e081879e8be53c070fece2eb5e30a9baf771f0d82e33789cfb377874ae96fe72d84f7d6f83c77b514da3262d87ef35786c12ca273b731a3c8eb89d381943bb3267060fa2443b05bbc99b5296c1a3d3a98c5bc9dea39b183cccf9369bfbff4675d502060fbabb2edd85941aa2f28a0759ee6316a3a4da1c573c0a3ee9cd52a615bce8c6ccee1269b0e261cc4962d0ecc92a1ea76da58a993f1793a58a0769eedbb388da5d94804023150fbcd2c273a89074410315042fc918424812d31c2232b9c63576db8c67ba40e3140f323c9db7c4541a833d041aa6783c61d5723445234b29041aa578a051faff7e32a61be2c8f2010d523c347fbf4af9525f4a0e5681c6281e8678a468971337668b498186281ee6106df2f5b7c5df0dc5e3bcaa31d4e755c7f443409d4003140fd3939574d0a02329cd051748a0f189471129e77d0841dc53ec868d1bca021a9e78903745daf2ce77e2c167f5968a9d2d23dd9c7828af9a3cb359460a7f130fdf439eab48cbd8af261eed844dcb336e261e576a184df127c3a60d261ebea7e9bcfff3613f778987af69dd2a916289c795ca3288640a4975aac4634d9edf2a588a167ba4c483ef9bd42974b0a8de26f1f05ddb225a4845d610493cd4cb38fbf29525b55264a01189876295ba43309110a5a20189c71ffa43b3e86c8efc88c623cef24f494d9a3bc54fa0e1885ec2698eabed9353028d4694b913236abc7f4f1824093418714aa75229d34716b017de616c0ace52191a8b78ecf5a19fe5f22ea0a18847b569255c6fd5be480c8d443c4a31dd84709fdceb530b6820e2f1c5774e8d1b755483340ef128794be89c99c691758386211ee5d4999a8046211eba7e7c47b85c021a8478f096534273a4b5a3b36280516a023406f1a85bbc7370f368e9bf32561f7086011a827898d64effec32543275e4755b12100f67d737ed348b8c677024293f6250e094c61f1ee50819444543de18172f02b5822f4ce005a3a08c540a7cc08b0108e00a8f6a42afda586d5c20002b3cc8cc93719e591e97992a3ccc9f7be352b8f0759f1300151eed4eca9039178e2c3e5e94b1546528e0050298c2a3f05952c9df367db92b1080141ed9c48c143df37b351a850741bea24cfb8223cb049e2a1000141eda448b1663b7a698aa1408e0098f242fcc73b5044fa97940032260e3868d07942100273c8cab9fb12db6da84dd46170ef02fc8e8c2040268c2a3cea89d2b6bccbff630e191cc7828cfceafcf97f030efb63be73fd7e4b0121e4baf7c06b50a493127e151c514c6bcd38b94ca487874e1fe42a47ff0caf2088fef2547ffe46329a534c2a38fa88aec5829c28354f5cc09fe1f7c73447850e5b943f768c8b4d5101eec55ec9c58b80889d4180108e1e14bba507e6666fe2519625cb1808c1c613ccc58004178b492df727a47889b231c1000101e966ce49c617fb743ce0f1ea6906b26d43a3e787cd371224c925fba740f1e6dd87f9faff8394794070f73aaa346cc1009dd0e1e8e060b615e738ca8a50e1ef84c8e93ed36bb37078f2adfa907f19a95240ebec8ab9b2a44e5060f3742dcdfe56b83471b82f6efc6a4060fa35dfb6850d10b01d0e0719cd857297743ffc6bbb071c386066cdcb0b1011b1690800d01cce0d18758f2539dc66dc32800193c12ed10728821774e591e631d870a2006e7cc4d5b39bf213e8e2c4f01c0e061774caac4da84e8498eff0247195e14bbb1c52b1ec449ac2467a29fe5dac2150ff343f0dc6a936ab61386185f8c6196802d5af178736e86201b2c3a2f4ab04e065f6ec18a87e5933da35b75395bc58318967663e5ed90e855f1a0b27c5ae76f52f140dc3536e6fc34768e8ac79b32ff844ce79b18728a479e5a62a4dfd11ce3c7140f4f636c66bae6dcdc94e2d1865dc406bdbe1015291eeffac61b0b7b140f6532ac44deaef7a011c5a3d9991419164fd7e7503c981c528ea58e2189c740f1d02e05b314b19dd2c99f78747739e67256bb4bb2271e6b907877af77e291f686fc7ceb71e2619098151f24cba4cf6ee251d214daff1ee1e27f9a78b8fab9b5daefbae5cdc4a398fe36e3745a980531f128672ced38329342b397781c6642fc48225ae25164afedeabf275b4d251e7f554b878447b3d22941f57b8e270d9a493cca185fe262efd4ff2d89c7d31d63c53d9dee1c8dc463cf0b49ab315d6dc540e2b16e1eb91ccb2143a68f78d435d3d12e76a6c790231ee5d092412ba44a4dd988079f3b93cb7bf3a618c288c7f391fb3ce33a868f8b78ec31f7654dddacb34d118fe273fab6a4ec1a1626e2f1fe49fb58be20e2512e7fef5a6d8d6adf211e7ca5e4f23a89f421c5100fd576b2e84e085129528807fdf9653ce689100fec63674aa6cf17cf201e4699b493fbbf201e790c2144497112ba56201ef9ce58bc102a3a670910c77ffd0ae993feb08798ad8ee0185bf8c1025bf4e151acc8b9584c8da8992df8f0d853f0c8de5351161678047094b10fb8b1000670c1051f2f4a9191630c3d6cb187472185b02fdb32495414984015906580318609bec01c6ca107db220f8fcb66a27fa2c74f63f0f020d6e650b976d25f54eff060926b8c22bd66a1163b3c920cfdaf9d4dd9e432076c5187c757d696a33765e14b3a3c4cfd9beeb5315888a92de6f028c947e8cea13757a1346c2187076e79623649840bb52de2f0306f8e8e7db96a35f37078f0d96dda327d7eb97fc3a39035a68796d20d8f3dc7edb42bf79c42de868797638e9d4dccfb420e1b1eda87dc888a0b113b6b78a84127c4ca65353cee1819ff9f99625a4ec3038f6f1a8247170d0f73fe5e093e6f31857b86475a29845e4bd90c8f536848ca9f6a5b925a860729d792b2e620297e92e14155ff9c75be8ce1d169cea2f9c22286c7292f43eaa670223e86e1510afa59c2a7c1f0c8f54e2584e654dfe0171e6806ff8ef1d2db15bdf078b2e28a56ddc899d88587db2127a6e7a68eefb8f048937db88d6de161a947a93cad103d745a78542b36faa6bd297eb2f060e52e6a8a040b0f7a42c7fecadb151e5a9209d1a294abc6cc0a8f3dc86af418f76ef6aac28398e22464c45478381276937f50575f6b0a0f3e8595dfd6a99f18293c8ed673a92d5178ac5796f2e97a5eabd001e30b14f05519366eb0800c47c1056cdcb0628193e116301f6c0185471e427e75480e056380608b273cec38ad9c62494a2ad9090fcdaf3253f0490e32c428233fb045131e86c48aadf1ec7aaab205131e7d9ebdf6d465b1e3c0164bf0ae4c3ca6a79c2d94f030c9b889dc5b340db9126c918487f729abd5d7e5ff2a121e45ba0e79374cc73a7984072a134e2fc7602ba9106c6184c71a43d6caf6d1d4cf17e15178bcf590a613e1514852164bb3d5a9c587f0b83453d449fb9762e74278e49d83daee67d3cc74101ec508e934e2da407898a2a1dfea2a46f1fce0c149ee7e1b4be9a7e3834717f2cb9265ffeec63d781cd39f273d479b2c310f1ee728ffbc95275b2c77070f6bce2f534b88715246070f5205f74ae5239595e6e0a15f456f89b2117fe3e04148a5b079f10d1e4e9db865b79866316df0783f96c6b68fd6e0f196ded8844bd2e0a1a5563891d2dca4cfe071e518925945788af8163278d83f59691a3e5ec8952d62f0b0aa3d6255784bd8ca163078fce9cf3cf2a4cf7795573cb60f6721226cbdf7e78a479691c16252af158fe6e43f72f818734cc28ac777125f27bca4c3b6553cfeac3147fcd254f12873261b8f10f3bc4fc583df9c2645fa0f2a1eacad4baa9da778545351efc7a258de4cf148426b64c643f4986a94e2a15aae9cbdd38668779382abce21a4728cdd811aa3781cd267cd669ce87ab2281e5f5baba74d9b503ce8fdce18836b40f12866c6e87fe40b26ea271e5e7edc7f0da1271e4c68eacb9ead3fd9d789075b6e92396bfca4f238f150fb654b26bc4d3cbcd06a6de13a3a6b34f1a8337d63ccb56d8648261ee9bd4678a57c4e18138fa35ad64cc94ec2667689871ea4ab63588aca33d5b0c443b1b2330f2157cbe62bf140a565327d4a1716f3947878e17379e6fd241e65975afebbd12c3997c4e39c9b5255346791bf23f1c0dc35fe45cf1b32dd90789453e96f0e1ff1282385f34a8b9bcb6a473c9e1842bbeac5aeec99463cb81fb7b0ea9e5df2ca8807b731789ead105624b98832fba6edac7851c4a37049b2bde49288c7b3f2b923bef96ea820e2417a6c64e4c74d551fe261ecfe5dc6c98a8a1ae2b19af56c1e8fe31dc1423c7ab5cb303157a68a90108f73baf3cdec591fe91bc4c378b143e74bb9f35c228807e121d567f758201e67304f39d64ea8d801c443abe87f8fadfef02068fa092926c90135fcf030468b5d9539deb35f53a8d187071af3ac7ba659dd20b100146af0e14156edacdbc1827688efe141680a6b0d3d3cce31ab42db7d8ef2538d3c3c88f943c8b621d53c849c50030f8f623a89ed9f5d8d3b3cb68fb8ab9cac6cd36c87c7efb2493d8494d56c6ad4e1415b8e51e6ce73cadc38b2920e0f5cb3d4e87d68c78b13781956aa801a73785c97f2a5ef9ad2725f6bc881d5c8b0e09735e7e0c8f21bfe5b46181ae0820b30c0f02e05861a71781034b7f63a334be3476ed480c3a369dde8c86921d623661ea8f18607e1c64a42b8a6ab7db9e0a2861b1efeea5acb57acaf7ce1820b23d468c3634b9dda6288b92a32044716199e2387b31739bc2046d8f030ad56f8cf2a3d8d8a9123038ae1a8a42c8962c250240e0884a1804838121c9d2e00131508002030200dc52191200f75517e148003482e1e323c2c142018100c0e0e0e200e04c2403040541213476140181c0685c20151293c83e3038e4769a01afe0dffa9967712820a93d1d22c3bcbf4e230f8cbdaa7cb1e84201435064c9bff13b64e4cf41bbb6e949c408c461dcce080fd3a3859a5c919c827ad7be0b6c1da0768929dcd03559c4a08f9bc7e30dc75c0fc6460245e2d0b8d399ef48d8f8a01351644fb4d743d22c1e5cdb225ed301f9cde41d5711e4ca558268ab2d003a966978983d4da2794d6c4c63c62198fecaf0cb797127d458be588e51b695a641d4224a669f1fc164bef313b83da95df584ba97860a44af233cc549023105d3fbb10ef5bb563e61441ef67a9474001044544419635212cf68e3590e7f85c5a30fd6be7e1b6dcb8f43f7b79f2e868da9075b93965e070459795114e47aeef92c237f33057027e98381118a4f51663f08ed1e619fb8ff6af1b1586c63aa7e5889e3d844d6a46a0e7593db94463356be43654b75690dec952d889eec34c4f2fb4932cf7cbab9de11e2a125c5fb4b63fe0d8442b6d8b94ed315f3d0423e608ceaa2a7c0fa53111409683834e4084b71adfda402e6f827378ad879aceca9c933a14ba82b61ac628507d0b824e2a06df09050b351897039e55524434b4f81653c7ae043c2051d85907616724009c654120273fffa4b1c1059d972af81eba7f914a34b8843af7f30f4878033ea86af56f14206abda2d652eee758aa3c2580e7354e85445ade4e5a2dedb36197c59bb4fdcf1a7f7b7168e760377e73e7ff4596ae803461d0333a8bdf63e700cccedef0206ef93f5f92be0cde7a1c0c55808b4b7f538638d1d5b9f7499012e0471cc0d640a308c5ee8bbd20a53c7e0f03ccfbcedddf332aced894538ee53ccd74fb272ac5f45fc5a036b4959ca5ffe2c2b32273a9bb974173d18acf4f81556c15dd83400e8a06dec8fef6963a2ac4d30e2df0744d85dfae172b124699480fd784f4476a9f9e7a25fa654f7f89c4ac6e537d2efd2afbbdc27f82428b5fd252dfdfea9f98e93b74a1beabd5cf193b6a1e50fd207d78a15fa11a0a6446d4fd13c78a58ddab5f2def7725a381d626bf87bebd3e96be02eae7f4ffce6400c0ff77df1bf1576846724165d5cf09dc592f55f493fa525b3f678071f3efe3efb25f6efc152318f7849cf85788d5efbc4bfa1da232e3eac0d7111326e9c30280e7b4b7a53281c035f3769789526f5eeac6737a7dd0990c1936b8900f730cb3ce1426e0f895f5560c5edb35e06d50ec75012dc1d17d9898d0669f41ac14cdc3c6175a451125bcd10794d25c6e9efdc986ba2843ef9b7c9c297a524fb8907c69d24e64745b239d90fdc93369644762029e493cab49e72f05666a30e64434bac7073a1ab7deef5f178d6e8db0463cb0d19e7c29059c7da429e90989d068c7e8c228cb68a42374449a6bb65bbfa022f512a35d845215ccbfa315fe8015d67ec42649eae8ada8a2e8bb116a1dadd886683a5e8c0a1af9c9680e5d53ef52e8284a9176606aa9856134c7f82bfb9a498291b47bff88ea9279f2858788aa58e060ea2cdcfdd0d6818ca6e2b8b46cd2b5da01b93106b05619c3292912b07b761209f289b126811fde053701f167c6303fe3545c6a2828c8ea90a52bfc3186bb57a5d29b1411685d4b00e2a81b0c56d5ea6d7a086d5890cec428d72964d976be56c2efbd9d0f4ba933aa7d75ccbde4975148cab7ffeb26c728e05eea365c5e0062c1ad21224a193119f00cafb623a49c7cbc975ca753a9769777f06f19067eb833864d87424854a9a0468998655c54287e3b6774331483a06a01b6910013e90c00bfab36a47948bdfadaf35dac1c4808fbacb038759223586cf8d04a6db9d2e14d308cb0d1bf086d1ffb21e0fc5fad9e0c6dcbef2b6d99632a48847ecbab392991f1008d34812fadaa32c3b97cab39d532fb2c1bc4961265c9a629fccd776b666f60e351884ede5defd1ad3da06d286fa24f81450b7a43929691337ade5ba013fd7f00f7c6dca5b3499002a4958feb029c73b05ddf68da245cbc3ae0ed2b7cdf88b0b5e7219f8d89bf68becb0e95b93fa53bbcf08c4e5cce26e18a137a736b830b69f07d619cc923cf019bb6a4a7230a8d2655c39a2da755c790c8b3ee15299a8c906203b3f8cf332841e0e38bf0721b1ab0c3d9bb2358134332cae15696ec85e5aeb3641e09145cd8aece114c29877a50c5685ad3e78f0cfb717b732a6fe6000606a80fdb9a53608d18bbb3c3440778857e2f525e41f0180cb374abfb1a448fc1e88c6b9681f9e5d7a0a3930bc2d554b91951a24049863a457aefa33d2c1e425c13f6279bdb5c648fb0cad2622e19ffd95f48a862046d13ff21c552c1fecce76cf3086dac88dd972b4e57e3da1fbeca9520458377da6b0e0f4e2d0d09f1648be90042122ef595a00d78cb1d5820c7f67585724ebfc7d1614f863039845237a89a80612fefe3c9202e5d165ccea9b913230cf1a0400ab2971b7c2f6e3c2fd719e498946958d663bc45c7f8f8e5b1be3235b113e1ccdfbad09d828e30d8319a3c96c12ca6d9c3a3e29760005beaf982614c66feecc3c97c5458e7adcb0f0ab272863d4d1661ea54482869f8266dd1d061cc1c3dfd4475c9e123a20ae3dbc9355e625aeca7342179a47bd2159597260e7bc54460b7075543e7d53096894237e838db1b361a8019a2d8aee15363e52bd9292212c502a1c2acde28bef5b275d7b83949174ad7652b07c4fc6874b1d2badc22077b5837974f2f38302517222efb5d8ebc60e7d87a785a109523db5e5e54332cc3e297176fded07fcc5b0cf77d758a636bfef49a9fe3d0b9cc825c2ab9e342caa5caa59b5e0ed0faae57a32e015cde5aaa5b6c2d865ab45c0c2ea75dc6ba5c7999d554ea2aeb802179092f46ddc1bc6a2f867e813d49592d5aecc73fd818b128be40ab3e830aca11947c285694982ee55400d06fafa168a2245192244a7e47956707de296f158d53d654c6a68ca1c2228acb1f320b0948583fd486168c06263cde459250b98ba00fae9d47036f3264e4a9cf92f742118f03798685b4a91384c331fcc468ae60f531bd46b78c76240f335cc88dc6c55585105d257522653e6a65d22eb96e5519b786d4cf6812341b28d57c6ea96ca461f684a4abd81e9bb7ff4a11697f818a275cf8e2a9519bec0a11ec0e0f494f20c9785e793279f49447b0c4c98cead1f3e98fc70786e7f5786c7daabcd18ec1c26e1b539e0311633dd218da88bec9972e4e194e189c058e349cc138e7e3a4902519ebe13831380670dc70b271a816c7c2521067dfc009c2c1163865d96ca5bd20ce4c3c341f399a04f5f919d08f553dc0477576a634d2d36695639d1aac7799aa5399dc4539f46506918ea9395186dd82580896d115d1824da7a9c1b83cf0aafac7cdd3364af192710ed6eb0020ec40c984ced61759cfdb4cac75c4a7efc202c0566882c18c87b024d1137c3f11b020a551242293550a9eb942ece1cd2e12c3bb26efc9e6b2018b44cf397c78d266d4312a4c11d5713f782ff3da117577ead0f75c8e222c86fa621a26a038a6bf84b37a491fe8e9c2937142ba4a98a5a8660f267356725d7ec346db4baac47dafbac8cd44b53d42c00433a381920d745826bdcd8d5a4feba8e9c0549aa90f3de0b3ed32efe811369531ec085a07a4d15345b09752ec550a58b4c32d3b124649a9965d1b7a6b5507a57ac3199c0519693749c2f570971ad3349d4eb83b876e225b00e3f1e1aa8192f3eb1f5c5a4e9abb748b2593068f0e7ccd3ccbdc3d95ec55d3288c3ef5f52172a6ceed277c76405d551c8fc8c6adbe346f34ca0e734d36c50949edad15c9d8eff9ed4751b22f51314d95e4771a0dd176b5db9f2e4d07150136e5c12122a7ad8dee8f799d58611190c4f03e24dc2086f9457d8763cb9d1ff4a09ec27f8041d6ffcbb4b92228d267df17c0f8cff540f85540ff513fa0be3abf8d1e607fd5057009cda503a1022eb2b0f993626ca23ec1468908df37fa970678a53eea64ccf07f2274166c106d8da1102e4983a5118c82a676dd65a0a8869097d41a20f833ebba30fc476c5e280307d1e0e3811056c15196c44c95fb4cd8969a6836bed8c5499ef672400f07c03775e4432d5bbcc58c25e3cc2d7f9153c333d142bec9337ce46e1f7b0839a1f0c1505961600886a25423fa74ae7ba9554cba346889dd968fefe226767b720250ca4266a9f1b3fa23952c87d9310c935dcb9cf6fa3943d2513ae99404fcbf1474f4d1dfeb11689f54be4a7ea4ea874ef567c1543f030786547f3fd14b8ba0711045267e2dcf32322f6640e4a149e70e9dde57b9a6bccc882b44b58f661469b42942c77d10b283ee91ef116d2c60cb3048a3c970c5ddd30243ce0889c1c7e8cd1933a50f819486581253109e211c0878f13f47a03be2b913e4ad48d560ec384e70f58e842df914f2e458edf279d56201a3e80e08b11d8dd96b34f8083c057217c18185658be252a4128eeda5688931e9800a54822f61b893b1f1a9695883578cd06f41f67aa09b2bf7b70e356393a01740b6cee49a8c7d120f6ec6b13c7980564f9b9dd5bf560204e20c451a6719c12043947c6736cecb4207f97414f57e550d1fd3081c641ec9238ab12b38c7e0b5930ef7488066edccb80b0a34d0a1e069b3eaaa20b291183bab2d0c5b2df3fe42dc10fe41796d9c09d76901d0d0b8ee180dab2c976254f7f4f8384321b30904d309a273d8dd30fc9f2a104d4fbe2252a5e63cbe19b3a0566012826130c23332b0a46841868fa8a30584c31d7e9622474f270e4397eb8ed1730cf5956a39704bc857efa0adea004ca4a61b0189a0ce7023dfb5b4342ddfa1909762ab50647163d2feb3e46b8b6f40809f46c69c1e4b7085c3f88031486d0b0883af867ec28c0d7528b103d46845e8f61c8f339ab4c10e0108de13c963a5c23ea437fe6374c79e8f892b731a0b823ca5e228042aa4654b7561cadffd05cad75c8c1e3a47c9191ccda1bebf57c4460a901e4abc7f04cf8f063417d5f4282d78c592fcb703f79a7358942fbf044a060db8c3b8c97064c2a83e8ffcc341454c4b6b7ac1599041fccccce55391d106d5362edb827d59807f8d7129ec66e65ef737080939a1e1cade191e1b50ab52fb2c447a1196612ac6ae88228308afc5160bf8a89ad6315f4dd8fd59517cbc218a7dd43048c3928980baeace52bb640e12ef298b82be899c19d9595221cda3605484ff878f42ae9c2a08297f803a845dd021f59b69d105fcf7d111c28cd8cfce3809246d6b9a057a5f15d900274b7b8658d44c6879754ac1768c1efae5983ae15360ba1131838c04faa94e508a2c11be8e9dae00f31521d6fa527febe697b466d672a6319386f886572d82c9297b53b43541c84d706f5e8066bd2b1d41b55c7aea7f21c958cb962e33e51f647d99ac6ce546198493809d8870f679bba861d0bd97eb4f36ee0749aa16ec8b3d745593ed726943fb54ec30267ae800891adec1030f8773422b95b01de11f5b3e73d88ccb85d5feb6c55fb8a07615f0b0dcb40493d371759ada13dfc82b9ca7ba4d9fc5357947284f6f924cae2a79721c931f2f541bb35b9a815d78ea36415133df848cd91d05075d5ee62581e7c03672a0aac2b59e3c133a86ad0cff228bcc0f9c8136453ab664510dd997c0a470bbf9c6cbf491c56cf88e5189f822def017eea9be0cc3a3916f6b7cb816401cc816b653e0df386c18df9ef37e28ee06abe1bd8863ab076a09c543a6ede238818f42c77759d8a049a615ef27d35461b3aa1c42681a01d43094d1272a47fadee80236ef1918b2f9f3b8bb8bd6db90c68b2a473cb24731b08c12ba8c4b9724dd0f415889027b3426809227d61028f56535dc120897ef012a88ccbc27370f1cf650b3ca83ae400c24cc5bed79fc8920953f158ace21550ed4b51c29af27738c62187a549b130c6624a982e4bc145c332eca0f7537225356df9c887b414ab4128bcf008ef61b40296616824ea26bffbe882ce827768d3d048f19448922baf55417d1ef5e8a2ff50b55be622836e0d7f8cd73f724f8e3599d5621b2214753e3be2eadc0e7fb5e0ef3975058bc974d2b755673397ae77311a97a36630442f79d9ad06719728702d283baec4552bf86512ab938246cb2c696f4fe4423cae8d7f9f891097bfc98a13df7f01c4fab9d219afd132af230eb3b2bbd3df879e684b554a65e29d7de964935a126830800be20737dc94c8f216cd401304990ea265a46ef42a39dc4cc424a23c8c9b7e686685331e366befaa60d66016e81bff409abc74c52a656651c81ba0100cbb3e58695babb6d971368e99953b97be6795f4e65bddd5732e1c10a17df62d9d4e94267e6da8b26b6c25f97eef3c73e1d84ca2471d7b2f0fb2673083a756eb79af0ca0765b58927efe711c5b8a4eb9977946d294d055c72dfab13952b82a6e434b37ba1c267936023accee3396c2529eeda78371e0a08aa18133eea23cccf0c426594a82c046098721e8da3668d5f3697858c73dd62c27d11650f6d3a8f4f57814441aa82595775e30b0282b5b306a9f5afcec8205d564cf40ce52aafe28ce4a9938d370145fda2d44faaf14c84e03750886919ca0949fda78262e4075e1e0cd6f604921730ae538bd7ef14132720e4541be4b421a67e07e7e6723cf5f382f864f48f064d5049df526959fad8b91c8886069165f6388186e2387d206f8a6b65a93fee51c4a88d2da8226f09092564f793b564e42ae0b10c4a3510e05fb5885909ff6b97accf5ca7fa4784957f3c78f534ee44b26ea762d2b133d826ca2a637c93869b972aa4d5c46304985fbe9f5e9969a2aa71ff64c6b8c0b840c22fe294bd5ef4ab991d7828df42086cbea04be6f09852e34a8adb77e781801cdd41b29995719707e078139f19ac86326f04ac7688f951393dc2ac913994e164920905d8a30250faacc25357c7d91e57caf451f7426cc8b678cc134b7b23908b0f96d2ce6f1b522998060f9330a5ccdde67996b30e95d3250b3ca2020d0a409d5915509cabeac64470d02ec9db21549538e0d779d230157e1ffd7a941d0a079607789534c443b9e1237c89a8e2d300a3c08df995e2022196765b4898350b08e23052f9cb196a0bb0c67506bd338fb8d39a640438db5909f1636d6755c6dd4d250b450290874ab194780266f69d3dc0a949dfa33f3ce933fd6eddc13d49d1100dd880a07456421681412f3a9aea74b350200e745792ceb173670b823b01a344f0474de0105b1cbcaea10942ded972be5c964a59b8e035c26702d3326003e2be4f6cbcc4a83028f62e15be21c80177c4cf38e460521e2a3770437d8a5cf7e4e560ed8919c0579721b77fadd6a3ad703a088e7ce4b26711b5abbcedf83480bb97b3be11d7d2c19608af57367d4fc9be5049ea44556d524b97fba79648c927ce375edf4c2cee6330902a65c3bfb79cc9be0e0a11da203d0cef6d37bcd18be7cc0ab0a348324e6d3f3667fc59a28e635a5cccdb2e3b96eed8d13b52f2640d5f6b73f6013c9b0594d7fd4a17938894ea22696a39b9a4816f5d59875c968f1da65e13a05e421e53289bb8a7847c6bd7d16d209dbae4ae4f9d029a716ad5c77e6dfad07840110cde2bec99dcca209b886d4a879f5af7b15702b4f44f252a3502439bb0f680b08ad3de779d183228c4aa47279412116f09ba4b6ddc11ddd5e05170d7a102b81ed07b81ae6190214cbb06adf91f57d485aac22e57e842d4afc3b94a90e720910df863ee311964a4425d02cea8be5c7145bfd6e2ba4b892a8444fa4910b5afee11479aff6bdba44cb4b5d437c50e7f647414f88cb283e44fb6c2f07352d6bf02cb62b01a3e5121e8a8bcf6351956d96091dfa0193b4d39de98a742ae4c023732224714a9ab84fa2345096b1e31b819825b6f8aeab476a850e4fabfdf17933ab8e559bc8e51e5cd45a9a760fe83c58667fdb684e40134fadbc6c64cbeee2ca939a12df45576fd138dda6b942833e02421c32fed37c1df3e7a79a58dad6af93ab486324baf0b2b2d4a15c3fc41c9e0bf1da7c9fab0c84de3305fbb0e16f4d60f42146343aa042baccee71f576636458d2e2e6768330f1c6489467ec4fb8daef4cda59d742ef116d724bcd4411b2d6c66cfe0bafe4a2ce92bf4e634aa19c69622da797cabf1ac484d6e11aaa443288da49cb1a42da234de86346a473e42c56bdef1eb209f35907682473620f82d3aca40f0c8a42e3ca5f083d04713914cf0d8d2129fe76414f88128612f23d0ff7483b033b3409d84bda585b9ce9f6ccf1d4708b2831af2e7479db28933de45e8d6f99a0bb0891ce97a0872498ddaa9f298a53b38d8e06d4a3394e8f56a1dfe99271f5dfaee646d73dd87af0ed4b8a026a3ed24f89f82007ca4a8939fb016814087865893a746c50101858296bdb163366bfc4bab1f9dffc62502a569fd3aa98c199279f5226a6a51229956fb9a4c5c0a838646435defd516ed22d4da9d892ff022230488bca0ddd87210b35cc3b09cf8f235eaf62d9dac210b052afd42a50270439f45232cff76ef35c32cd141035903d0023e1f6cb4b6c0382acda16a7dd2e7851113e5d3aae6d2c63dd5584f4b365e4bcee6b98b5d54ab9c5f771bb50889a10091d06f71cbc780b7ec42552db79251539bc241da419b413ccde35a1b702707c620e4071206653c5aa4f30880e7c75f6219bd8b3ce281989dfe942a0bb165a758a585521a22256f1fe3ac0a3a9ed0a7a3073f30f53b470ff6e006c6ae47b552fc6dc0b91c367fe15e3364075fec632e5e063944efeb21ee6c9d0352b71a8736fe9c93f3e322ee92cad65dec6cfe721c48dc74e92f14d990111c146951b1abcd7c3e50822eeb41d79a17a35ded495be518cba0b08d577457230c69a97132314a9f75e5c6bfdbc057b58cca4083efc28cf1bc439f60feba8d65cbd06083ab200c031b76759bbd6c1ce7dc5fe2544f1821d004bf5ac6eb72cf63280bc7273b5420b2ace606fca1ae5fe272a98cd604080f6b39ece5f9625726cc97c32e11efd9653f05bedc44fbfabf687825e3de3f70701e4a65bc963cd0818c5fbca32975b44df5ab5324930a0ab71f06f07b3059d79c0c02297345ed48515ae07b4d4232bca937fcd4a15065ca8ebb77e224f7cc360d1c87fb2d9da923a582cc880ce2fc66840493412c7001ef848a84130011482cc30094ba6d3bcad50f19179258a9c3898da66acb41ac36aa8758732f21136325ae431986faa839f0c8e6b971ff3dbfcb73133c5b0276619f3f753db3c9c049b5e95212647efbbcf9f6f3d0373f639cf12293bfd5d28a2ea7809bd54a9e8c8abd454fdfb7e7b6003616cb6961c2addf9b73b417e89636da4766bbb9d58a92f92e899b7a4615a78270ed664a5cda38344c25c87a010459c2ec2d61ab2d5497f9440c3ab7308d3b3085e2c76298d066d96096dce4168ddbd47280209d588906caa14f5c4433f2679ed8a6c9ae649249e80d5d522b19a0159339b288a962bcd1c7235bcc58a01e1b40740a7b4f8e4fc61a3ab10751d9504894620cdda5379d81cdbf12f02d05062b03fd93b932fca9f4d61db84598277b39bf97d39e28a6cc75848366b03d9350b2accd2bdc5259cb5c146564ebd027191a490da3223bf10e966c769ebf65c490d1094646d1b2f5dea1cba0491c99a9ced59af1974d55860c8be8971d8ee439b117327bea221364e7ccc4f9961523459f801619e06a3d9eb65646467f6977ccc59d64453f90194ed3ab8b5f884bac94a26764e202d8671c819344c0beb92119fb2a00612cda638105febcf2f43eb518a496b3945aa26169fd498c6b6e89557a0b42ed2d9ac2b90b655bcaba350e8995c84178eb2e9ecc5f11d15a87961635225a82906f290ebeb5ea9bbd0306b7b530f416b6d85b9aa57f5af94a3a42cbd21678584c2e8cc6c3f7f256cc55bf75604de8cce4694dc3ac0b73f95c88f3696951cad6fbb9751dc7d4ae2f315ec6caabda6339716b5cb9b4e12373a995530b4508b8fcb2864bf961dec13d5bfb5ded9a5d7bd74c60dffa1af6cc3ac14e1b46e0fa4a472e27b808aa072942cb4094b8bec3613929530cc6b63bad6964475de435e5e647824f38bd208a03880d3a954f3aa6e859cb9deac45972c92f0f7baed77e47593ba5d394e8fa9895c3b4562a56452b1594b1323a5df78a79301df9fa7af6f643faf6bab59ea3507e12f7ea4cfcb11ff12f898a70c9f98d25ee4d342e67d8658ecd547e607f30927b5dbd16252964d72371475352d06fd538c90421dceb0890e22f7f460dcb10668acc36e02aa0a6419128568b8497a47b191a5b768ca286124eaa0619cb4848ad4ce84b2aa86f89a2ecd0fc6be26ce6438a3689458a538df5ce22f956f4293eb78807d6785c3dda132fc03b46b28079cf4b511eb8402a84209ba32cfec9a8ccd3e98c235e57a5cb91c3ea7541640d6172e50b243792fba7d3c240546319b7d4650eaf2207d71d170824c10a01a521b72ab1cd85ad845bf6181d9b803a9b9cc8f4e78610aca12dc68102379bebf90c933c2a5c9bee4df85b764509ade03970ddf0a25faf9a9f37be84eb8f6da83f1425b555678aa6f6f405b5afc10064c2a6e221d04880ef30e97a26f8819acf7681a03e368009ef97775503959bf8e8bffa69ff416b0179f0623af6fe15a404d879c07f16febfbcc989951d0c2ee07908155831a5a971d9dc65e80502bc68b0d44a1694f570880596f295fcdf12341c20e9a5d7abecddea0ad2256a2a0a9792664a5f2f2508ed39170d74ae6a1a3997e8e271e6ab93f5e1752ecfee7680294e3076adb57898dc41e41cb0b4edb2bd46392ebeb694763781c134ff624a7468eccebc12e16920a7440fb9dc0c6801ac4c022a9fa7953870b46439000c30c000030c30c0000aab1a21b811b21004cb2493643c048c520ee424534a32a5d283c60566236defbde26242e36242e366816a09590959091c9568420afae45cfe9854f264c141894e476ff1a472fddf619e44a3ed129266de14a2c7382461591447241acf1ff4354ebffc277040a2d1d8d4a2ac8271585c400105c3c0f18856623c93fdd31029598ee85552669c9ce279521a8e463472648a5fa1da839828231af9cad68e6cfa44451c8be8621c19b9ad21cd02872290e092acd2a28e8827a2f1b821e8c99cbd9bb41c88a8f445fbc4d36f1617380e5188d08d1115ee4986307608a6648c1442a710770a9a63dc891222195cc73288d8fe0641ccead9d25bc213042aa9b37af0d4f81b5ac848008c2b7004c294749e609ae395d6868c2d00d1879857fb839c1d997b1238fed0aa26a53c89a032f77ece0d1c7ee8d22f2c68e9eb9cc7af3303471fba9cdb4c9ce914adbb74030e3e3439b4e53211731b70eca1d530f1525e9ff8bf68061c7a68947710224a64454e122670e4a18f7f9252054d4999c660718107608187f65224a56e0ba72185efd06f384939e998f2c585d902069af1db1c7668a49b86142dab52dc601e80a30ea8eb9bb68f8c76060d2d68388c1bfe213834e870fced4fd9b95113c8489773208acc9ba9bcc41639919c42ccc943c4bfb838c10d1822f8e7626570c8a1758b21a68ea03ac10ca312e08843db2f929338cb16b777cc00071cda2841926749d3aa919211e07843275b754646486ad0980102196ee8d763e88e19090866d0d0a25080a30d8d2a0df26364d7899204c1df9821830dbd9b1c9d3bc7e9d0096380630d5d52396a4879a51a7ac9222a85dc0b2ae4892602018e34743106ab68967a314243a35237291144b3893e1f460d1a67e8327696921c3d31d66eccf81934b830c1e30338ccd0e4d3a89943c84992d2d9a28b1965e8945cb6679c454f91c7587b1b350c17d6000e323439834eca67742a6037865e74d663566418ad20317432568a0f2da7c98481f6e838c2d09ec7114a7b88736ed6781b35cc04ce1edd0038c0d05a92177c2c68ee5ee60b6d88dd612ff4d1c5e7845eaf387e179a6c41827ba60c3963940b9d10123c25d511f444b7d0c860ba2f68bd145555390187165ad17e39beb5cbce2665a10f26b2177653881039161ae9bf253be7ac9ffd2b34d2cc6473c499909db1427f21c3fb63cf55e84dcc658cc54c852ec36b8e6ece513cb553e8573dd553fc989ca952e872cea02c4513854e27c50891647a9b9840a1ddd0a9ddb1b267f5ee09cdc43c219f5ba7c8d39cd07cf8b5ca48ba73fc4b139ad81994caa8694ab687096d3ed9fc1f82b8843ec72063d852324fc8120e25742a61e77485f992933a1b1c49682cfee74345d6a6c08184464542ce179f7829c61ecde01c701ca1099ea7345f4e8b18366a84ce52582815c225aa78388ad0488f601d43c7b35ba43888d06904d19798e121b4c18268e457b39c933884d09c48e2ee23930ea5bb089c86163060c011842e520ef98f70d2fbfa0107101a656131377682ca5a25e801c70fde0d258498891cf21070f8a09170dac386c58be3a51e34faf1257a924131d6ac04346ad4a061001b000804070f7a7d0fba123e63acee3b4065cb12d43449077de690d173f5cc77f6e4a00b918338f9f231635770d0c76b99121db49690b9415ba54d5f78502231486cd087aec89dc28935683362e413ab508faf62ac914004450fc14183e66334c9124d8510cda0d11284d24153535432c9a02deba89224664ba67b0cda5c8dba123c6970d5c0a0d1682673ac631049885fd0b578d008325e447beb823e94104a87f310f49aae05fd7c4a22f2a6a9942515638d042220960107e405200f1c2c683d27c95d1f51d2c3b48ac645784715ed456d1121553c119f49456b3abca8cecfa868a466eab78cef295addb61049589bd83c4dd1c61429968c6f293f24a5683efe777cd14a8b2a29da14117367b07014cde984a4954ce396eeac10459f64675c6a0bd3f75128da9c115227271d654f0714ad7a0cb91a3a28f58cf94467ed1bd593ee8936ec5a50dda0aa132d9d68c545a487923a49c518279aa49592f0d52432f3bf894665b81c4d341f9f66f9a654e89689f692a524c27f905a1563a215d9d1f92ade251a153f436fd25aa20d4a6b8720b92c620702f430f2685851895ec52a4c96ac94a39228d1fb5e6fbc8aa051339d44af71a6cf2a79a9fc1149f49f72d896d3cb23738c44fb494ac8f9b207894e5b10c9628cef1fe3f6882e848aedfe3d39a2cf293fbe062531660835a2b94c4224a1954afac519d128956343f474c630ea22dae8793e7bd65311a46c22767df444b4192f0595f923d6621dc2744b87e8327fce962a84d3967943f46551530c52544a15a342b4496c6e2d69794b258810ad4cec389d527c109dce882f419b9644d705d167670fb324ff96924e20da6c1ded275aade73f8068c634bb99f7085d21e60f7de99ccbca338e069ffdd02495734bb5c67d68938cfc30192fe7a7143e347ab2dd920c770f8de5bc2a9aea6e92523db4d55d12d6f7cc431b747347101153b23d3cf4a3e3de715d4cc77f87fe7d377a4a9d891a353bf411359b289134430608509721c18a3a7441c6cfa5bf4295dc5f2d594187e6720ef9f9934fe450c558834103150f5831874675bcf49f9d4b5dd36b01430bf3376ca461710105dc30c1df9841e30006e07b2be4d084fd7c399ba61c5bac41e3060cf437fc53328f68cc80610219c91002269091300340032be280b5e54c97ed508995bd4a92c8ee41fd432c25a002589cc10a38b449fecebb9ec9ffa0b1e20d7dd632f1212b276cf4dcd077524973de50dbd0459324c28636726b254d158b0b28e002af85086a3c04c81abace485a36bbf5c7902a56a8a1cf19f45b6a3c13327e3540400ad0c5081e01fe19b0fb2e46f008863f09780256a4a10fd3669a7d84fe1f049c012bd0d065e52f71fa4747eb7f865ef7934f503126cb7183012bccd0c8f0f5f9df0f05ac2843a32b68d9785da9838c8d18356080c01c340854000210a8abb1c516d8012bc8d09b882bb233cb25ed91186bbee50c03e84d2023015964b1012c0e8005040e8085050af09f00f4371e0435cc05aa13568ca14f7db9e5a3c7c5c7e7095688a189f39573e7896941e75684a189339a7412228ab1b6451733b6d882cd8616326e74916d0518dab930a95246fb857eb485b9587d9e2daab2c20beda99c09fa45b39aa614208b2cd0ace84213ddc4f47985095670a159b11073f5bfddf734012558b1857eb3c6b87afc24b2838f60901ae667c878c0db905182f7973181b427418d2e3c91155ae8921e33f9b1421615f21b589185de32b4a5b2d2cf11190bfd289debe6a23a97dd2bb4962b5cb4202c0691294133b0c20a6dbb898d395c468dc154854e695fcc1c926b0515da3de93d72723d5a9931368894d9eba37b72d2698c35849ec60d1830166dac8716fa5895af9b92e84515b3d0e9fdca13f984852e556ae73d612169115da13db1b14779b63cfb934282327858a1d7cda82124097f5a94f6021e5568dbb3f3446fa98753522c2ea000a5e1418526cb494f62dffa1ba6068c9d429fd43a8685d2661d742974215ed433ad643ac3ab1e51e8c296570822a87b078d081e50e884f0d36c3f5526e6c4fa038f2734f26e6dbe659e43aac5071e4ee8c44bc53525d1167ae4d184364faa929f52c683099de8ae0ee92997e4ef96d028a5928811424e097de81826692f21469b26058f24a4f457c6102f4f48682f630e1557953a22f3048f2374414cce133a6123f42ea7f13f3a3e4e5863accd30af857b14a1f970f1f13294b48a3c11faf21494d27d5af26132844ec424b3dcd5cb439584d09984cb709eca921e61101a19fef4b46b0a10da0d5ae112b7ff411772d2a4c26a9097f0c12f78f8a08fa765c372f4760c1e3de853c7e49a7bd64a57481f3c78d0289d62e7cc27c566320f1e3be8b3c6a786d9dca2831b630dc60c1a660548826a1e3a68becb924f5096eb82470e3a9d47c798ddac972e7761c37c8d3078e0a039d914af3b990aaa278f1b74b1c4e81864e3eab5ea61833ee69ce3915554323979d4a00b22ecb6e4ece1848e7bd0a0fd20d973b57708f9931e3368c492e88919463367e92183e6b3fc86882a412778c4a009dfa52ce409315906069d381d637c92bbf94b2f683d792679b8a08f964c82ba682d7d8f470b7ab310b3a4101f45a4d683057dba04ed4dd19672a7aca273cb2f6571365a925f053a54d147cca295d1628555988abecacf7f53306cc840452fe2f1b37cd06f162da768e4c591d911ca6252a10e53b4f9334fa70c5974ec544729ba5cedc1b364592da5ec20c5219b34d11d96e941c7288e1034788a112ef1157488a28f1e22c3c94b964c06f1a023147d9410bcc57c730a8b81a2ef205a63f6ff87ac1dfc447bfa7297e5e6f8b60a7aa2cb9a72660bd7e9eb75a2b390b2964ae9612ef89ce8e29b5857e4ca3904994db41a2da998cc4a4d34729174dc2cda924e5d36a12313a86969cd969376a003139d086ae1e2c55277c5fc16326ef08c8e4bf4293762d2abe13cc89c7658a2cb95b031db9374f7ab4547251acba3df84d01f25da1c4bf3179142522c91cb49349e4b83b84471b5900c184a820e493413628e399294a8a3f48b443b594749b31832f2e490e8f7c57ab457a58ea27c44aff2514bdf62cc1b2a00c2d0e1885ee77b3f85ebaad0d188c6e25e5261043800230089e86044274f4d434cde22cefa9e348cecc8c7f0bc438722301115b6e2c65d043468c480a105927107878e4474d25c2f7fe978e1598cb1968868346913f9629578ea39c69a46a1e3109dc8b83039850788714386066c68a14501b0380016581c008b0360b1c5dfb0718226654f021937baf037c1a721bace22f3a7c629eb9c4d4347219af914b407919b446ffc868d270121daf6e49d2429f7b0231d44bb397f2b8ef6249f1935b643108dea9452b42a0b51e426c61a0c1aa84e061d8168dd3bf9c66ca96234d0a9a00310a7de98925fab28fda19d753d93914b5683410399a90d4e41871f3a33613168e8b10f6d87c9cf9a63397c8cf2a1132293568e17ca849bd7b187fe3ae560a997da0f3af4d0c41893284997d4d4958e3cb459e69b630a311ed4d7de924ea1e30eada9ee185e339ad2ddd50eadece4554b16ad3df275e8f552980e5d56ffb63ce723facc8e39b41e2d8a8c513a72685e43c45f25cd79c78a4327d1bd634ad598061d7068940825314653dc91cb073aded0c851a5c47969acce508c3537b4a9aa175af35ae94adbd0b58b550c9528133574b0a1cf19fd677472ca1b5b9ee0c6cb701a6b68adf22f8ecebca587d5d0a6d0ed73912f77ee943474a55f7310214e34f4a9f409d94acd199ad8167eb263383d9d64867ee4a71c64d439a9f1538636c4b0f0712b676c0ac9d09b3edd2b2e49452aa17b42c7189a943f89650c91634287183a193ca979765311b2290c5d588f909952a7c88e83a1bf681a22bec75ff8e417baf82673ca932f71c1f7422722bfdcf22775a149e19d47a4c8855654bb8296a43841e231168b0b28e0012ee386b9618121746ca1cd9892d8cc5d314ae8d04227c45a65091dfe52e78bd09185c654fe76c530aa314749103ab0d0785c70398bad1b93520142c7159ad30b527cf4260fc9a2830e2bb49645cec9dfb3602157855e46c9f90f11bd4b9b3aa8d0abc7cbae3927a75c66c72ee359362934a6a489dc96936c33dd123aa2d0bf9e46ad1ca63decce810e2834274c8e5c9c8c3cdf763ca10d7349986c1815c4a738a18d5b39654837d178cd0c13c361a48d8e26f4a371f4ae965e994eee0b3a98d0a50cd3d99916be42dbb1843e87a4c81d3aae828e6a91603c09481d3a94d05be59479a5827e5015f2858e2474aaa5aa2d45093ab7c60c0a1d48e8cc737c0c0de5eb39e8088d67ce8e5f29dca36b4450c36cf1358cd0eb64193d9ebaca424711da52ddef1e3f11ba7c22a8324d95732a4ede860d835de8184297657b23f68aca2cc252860e21749144cabd2ebaa3044f4710dab914647cb51408cd65edd3d1ea3132257fd04e1829639e233e68a355ec0d1139da3ef6a0136722b435887606ad83078d4e3e17155274935359a063074dea242227e5338c0eb1c340870e9a134b176de28e1c744147eff78ed172651263ad58070e3aa922e5830565a542528cb5b31acf85161f030608ee1ed071832e2cf2a5f027345ed63774d8a035614af9e924b64b8b6ad0ea466df30fa7693aa141a334b257d4ee2c1d3383f6df3fe3dc930a292c83def2c9f2f9242c870bc62029c2c46845d4500b1d3068535ee7c841c8f75513ade3054d4c9ac3e8d39e0968d4e0c205cd47fc97ef907e612f2748ffa7a3055c74b00019636adc30416371002c0e008363155d8a9ff5f85e21b58b54d1850f162e267fa79813182eb63881994016599cc0705152d128d794234a45082ada8a49f5cfb475f4e8778acc3a3e6328e59ba299e09fa524b7fcc54d29faf45242e50933293a9fbf7c6d6a2aa7d151b42b792be46a98583045d1aa9838cf2d85a2cf563abb4599d0e021a06825869645ca9dbd165c7471012c26f0002c94c0f189dd2aa92415661eba61056491c5095e0462e0f0441fa7d282ce3b2f42765de0e844734a9b98092329c7bc5f143838d1a7e86a3a893c6542e85cc8b8b18936a78fc8c93363e0d044a74db73b59aac0c051b8a89db7735a3ae3b990800d2e64dcb0020726ba70e22aa6099d06eac2c625daaa1617d5a54a6ce8dc4896e874a8eacba3b3c2e4b059c9d445a109de1174de310da331147a8f39e760f99127b421678f4b41e51f0d2a4e68f362b9846839420853131a117d3c84dc5b1abd6542efd1f285cb5af293e72ca1cfae962839688a7352421be35a8ea163925b21e2a28b1b7b45127aad18d961d62b90d06c6ab618ae42769ee5088d0e31dba329d772548dd0697f132fb92fc7b5b8086da6a472e14d25429b731c93972188cb6c1942a32a755cd0a74c44890aa1ed55b31824c4d0bf051050822b82d07f705f09410f84f67be385251da7c4647fd0bcacc8f124aa926a890fbabe92593288143572a4078da43efd29767ef03379d0786508b2c327615eda416f9974d4f2cbe9a04b49bc68674df2939f83e6ca25e50b51ada406bbc041977a2f868f15b1acbf41bb1d936b9ccc67b16283ce52d2961c4abce7500dda54218504b19c4b756890aae4d88d13f119b4b1b9fa344ccc11b22883366b4ef0ecf1c7a0dd885f325ae3258eee0a1834b92da64fdc0d534bb9e2058d283915cd4c77850b5a5f794b315808f5d05ed1823e53d42a17cb5dc18246c68fc998a4584ec155b4a3352f972ca9a24f5611635f2e13715452d16e771891256aa868e49555c98a9d53f44967cd905699293aa1bd335c58c512ad97a24bde23ae42e79159448a46c8aaa88e6553e22da3e8f36263538594204b51f4fba362b8d8149355151b7c84a20b95347ee62c07f340d1e7de10a2941cd78f538cb5117c7ea2c932fae26faa19b28ab16723780b940f4fb4225e3226af76a2edd60bc9c3cd186b053f38d1a758c695950e1b4f63c3c6bb17800b0301de445fe14d49700f4d214d7415c388edeb1c39aec9fdc84423b64c46bb6a4eb2472098f15a10fdc044eb3f736e32455a6eca8c12d0982182195d7c5c624fcfa05966296a894a98e08312bd78859015cb7e4ca217f5ee9ce09d64583a81077c4862c929525c3dd9caf944a288a9264765d31143e24e2a89a4539b6810298fb852929c294b85ab8e30c34bd61ca2d63fb246206736a5550ce61523bcaedc91492a7efe5ca9f1376410181f8bb80f45dc4722ee0311f77188fb30c47d14e23e08711f83b80f41dc4720ee0310f7f187fbf0c37df4e13ef8701f7bb80f3ddc471eee030ff77187fbb0c37dd4e13ee8701f73b80f39dc471cee030ef7f186fb70c37db4e13ed8701f6bb80f35dc471aee030df77186cba2041f66685be63fa624f331d6b630376cb0053eca6087cc157398a7a9c807199aec1f2108551173b8fc3106b466650d22c74a1e2747fe430cc879d0d6951e5cdec04718c8bf1d64f0d279e3474f031f60f8e4578cf2b3959b143ebe701f5eb88f2edc0717ee630bb7840f2df451c34e1825de4716cc9e99d8197f60a1bf1c94906a651d4fba1f57e8c5ac622cd3a1fbb0827f54a14df9b954fc8a61fdaf2d3ea8d0688b7e7dc9658c35cd220bbcc3c714dad29e73d031e5a5d09ef2500f9f8d421b474f0c722ab8c7f5a1d0893f0f4a460ca5c48c9ed09cc506255d2734325a991f596f42f3169bc7727e98d0885ae887c75ab5c74be863fd84882107b350294ae8b3bf85c9122b75bd4d426b255276ab8e897814098d329d9877e3e6dc348fd0b985d8782d22e7196284f6943caf08cd27992928ad989eb5fa2042bf22b44789592e7fd2f9e16308ed99588b39eb5032ce0f2134f1d4cb62444d4bb8cedaf01184be4b52aba76992604a448c00076008e00c1f4068c464122973c69ef614184df8f84113e592cc5a458b493133277cf8a0c9154fa49431d8835e644af95b6724264feee183075d3c93d76831674a922478f8d8411f42666ab37c2fddd4870e2c8b8f1cf479b488cb4a2afe2ae40e1f38e8d37a25e50e62e4fb738346c644fd245ae134646ef8b0411fe365d233dd416ba6b4e1a3067ddcec9d30b162347cd0a08f599272c51413010ec090f13183ae735e7ad23339c3870c1a2156112e3e62d0a9aef89035061184b720f880416bc282aeeca8a01f83e4101f2fe8245e261327161750400d00fce1c305ed66f62ea5e2aba63a2d68ff63492c53caaf2405a3bc16e72b70a0f86041a3bd4bc83719efd09b55b49d31853ff5a82adadc34edd0bf165e2706821a0570800db3803bb3aaf1316c187b84472afad425234b631eb3725d860d730e15fd6ac754d1d3539c8729ba0e538b7022c70c4bd1882a2132a8927912181b6818f02045db5956e53fc8b7dc1b8c9f21638bb582c728fabc243e650eddab5cea420b1a366094c069c0d0420b1922581345ef1a840779d9c558b3b1048f507426a2bf1fa213648ac4585363820728daf56bddd38c49f464c3c4e0028661c1e3139d0e1e3d844d3d0de1e189468f45d3dd9311b3165d834727da8e97ac99548a060f4eb4e174628519b19ddfd944bbdf23e3e7bca3a4f79ae84c4e25df38d5e09189d67304d1b9ac212b7c30d18886ad205153ca25ba9c4c2396e82d864a71326a9a73f7824725da10f334e6cd9bad735ea14463c12c665149164b2f57f098449b713575827996784d0c0f4934f13b97b8d41d5167f788445722774b9cc5f4b27c7ec003126df20d9e3f36e6a062326f1814c8d0c294f3784497332289e4ff150f47b4fd293d45e2ecd188368c4eaa535c1791cff460441bb2cf72484c3993f211862ea24fba255425f11fb6afcb387828a2913ddb9783ff9612d15528cfd42d250c32070f4474b2b3963e99d9b443f8106d7e1ecf187574274d6a8387213a9d703dc14256a70cf10d1e85e852ab96ab574ed3202644b31a31454648e2721a1d44fbf9d33a964a21e6948268accd45fba8b062d193048f40b4f172ec93632283525a247800a2173d39df5953c63ffd432734757258b6580b1e7ee8ff44c83041eb04d5c93e3429ef088f3039e466950fe8e7d021bf6fc7058f3db46faa5a4b08a9f922d743f31b3c5f2bc62c78e4a135ffca272b67b764663cf0d0c970c1e4a83037e071873645538cd6f9ab91b33478d8a1f318c6f2b2eccf65609ca0cea30efd7b52ee22c22fb227508b81071d3acd122e625baf794ff60c1e73e874c6bcd27a26cba1112694dc0bfa3544ecc4a1d7244b4732f90c1d11c0030e9d7ba67685860897fc3734fa738af5f5fc9e8f71431b4c997eebd8b4a1cfe4be33f3153359c386b6c4f8248b96a39f45d7d0c885d8c8eb49659ca81afad829263557d3d0898c7ef2aaf3440f130d9daa201a46b7e40c1e6668bdbd4c534ec28312923234da2ce90d29e4e01f2183e5b17f6a96ba31f467a92b7f0a323134e6175f238919cf95f208436fbafa829216d7830718da141d553b973c2572ebf185de524609334de2b1f284050f1bf7ff348f2e34d922c738a7123b44c6830bbd27139d6554df7bb2850e58b0a06b0ba7db7592f4cee62ada5142bd3fc6fc99b02aba503a5b262525a9683e6a668c264245232687508fa64fa589a7e8c7c375b40edd98f3a6e8e256851e4b292c91a273f6ad8e149df8044b263f368ade228a9e8eb124f3a2ff1a346ed8b80070e18528c8e133e50999473450aae045283a656e41544aef0c1573a0682624311a624c86c98f0434608060868cc287179fe84c5ea7a07c339aaad213ade8e0fea792531297ea44179e936e4ffc1045cfbb87179c6844969f8f29a7a6f092179b68c474e42da04b78a1892e430ef39e696161549968b68299b675b0147c9479788189de24965b3cf1fc20df4b34f2cd52caa0377e2a19c1c30b4b34a2e38a0eadee5129568946a610fff44c4c923bb2c30b4af41652f582efe6eaf062128dc9a434e4de143a278d245a33f92d124d48326685522acbc3874497412d7e45490b9f9847743aa88a93b2481cd1c7043dbf419ae8f0a211ad0709594ccfc9458f19d185092252de2b2d9eea227ad571cba656baa46e780e2f14d1b787e4a9734f0a32c513d1a6c6ace4a02f882843fef110edfaef95885c2968f80cd128cf8ef2d9a27ac89a22871785e883689efdd3ffe77d21446b1a8472d3b9e4e9e7717831882e85b4a8be162b59a80cd827bc104497298b46cea5fdd4c381e8f3c9bc41c86f901c1f40347944c82571312fc6fed08e56cd661a7265220787177ee8e224cfea79cf73bcdbe2451f9a5f8917de6385561086d5bde043a7215f8fd29ba24d78b1871b2ff4d04539693a67075fe4a113c94c5e2a599d459e78e894d21264a70999afb73b14d4b243e42b931d7af1989e538a715355b40e9db766bd1c83f9861774e8fa54d2f9f26fad3bcfa19fb029f29c8e1047a5e4d0e596ed8f123ce48f571cda8e1613a225fda427028726551041e53391347bf48676b3e2659f0e1e2f4ac40d2fdcd0558a624967e4f833216d6894ca1651952fa2278d0d48e3c51a1a114df93c3db6c32c3574f95722a760691ada889353e9cf19ef41090ded6c6cee28992d3ce46d787186beb5aad54c28d15e98a1eb947abc53c98e0d2fcad0e6d6c831785f8e53990c9d32311d534f09770d1a435f22655a78363d152362684bb806553a05f119a32fc2d0848d22fca2e6c0d0752c2d5abe2735bcf8425bd9d92c92d6a4624c67340e5e78a1f79339c1b2c4a9fca62e7499e1f91d4e5710a343800b2e34eb723a29e1766ae1c516d8fdd44e16fe4bf783175a68945222714588d065e65916ba94d344aaa99ffe3c81617682788185beb4babb87ef67b56901581c000b051c0001072857e8c5f4a8d4abcc72252b3417735e113ae7203aa60aada9a6e8d4aaca9541546892697bd01c255246d114da0c22ee9ae7cd2d2129f4d9ca2526a535554d1e8526954aaa94f956148f43a1d132395589d84d113e4f6844081531730c4128df38a1532a8a9ece163c59c634a131b198632b9c52cac44ce84446082ffa71da92ca121a992da3938e1625345283c49d2841e55169129a91f90d493444421f256ac6182df3e208cd46c99a63d0f80b2237421fda5206a51b165d3459647145e8e322767569d341df4284fe3f99d4cf9a53b0aa1660835f0ca1ed8f3fe19f545a28a9103a15164967f1fefd3883d09865f86cd022101ad9d3783298dea41ef3e207ed58c58567ec1074a967e3850ffa682aa5a9ce98d3f0a2075d88f2a7c5adba24a5141e741123c89704a17496cceea0117aaa59935faafecf0c22bcd0419f24c868a19363237762ac95e0674cc072042f72d0a712a782be6af6cb9704e1050e9a6831334f4ab820d94520bcb841ea49cc660ea224bcb0411b735a8cd3105283d6625f461d0bd1a04bfa438366b8062f66d0cf66af9808c601b0b800125ec8a0724b357913f7bc884117f42de7cdfb23f75a187432948c5d8d15d33f9583172fe86298129e392b2639a446dbf0c10b17b4af17f4629e7e581f5bd09a28ed2a79f39c67be83172cd862f04f7e29b6abe853e51083b28ea9a2f718929b8a66e2c83c5a434b3b86a0a2d7532a7a8e213e45234e5e8ec77769519aa289a263e625a6d6a9548a4e46cb3e29f6a4e872fae4d310a551349732bf8fe92051f441455792ce88cbed0945df2ee2b3e2f787181750b41d9373c790df6210eb27baf8b3aba761f544172a08511d2984cc32e944ab21c4f0304fa2cf829ce8446b86902fbe894e84f829638eca72a226dad321598488e9868c195d6400055764a2f38ed91eb73b272813269ad46be2e46588534176893e567e082a714bb4964a5336ef55895573d23c2f0f314c09f73ca8d09337a47e127cc5371d3d8ac6a091443b6f1ec4547948b822127dcea455767488d26cb3c822d52041aa410264cbbc1a36b6085740a26df1de7c5793abaef0e08a4734333262b0181f255a7785239aa47be73cff46741dbf3fe9dcca231ac4885e52c9474fba63a45862ac694183c6511a5cb1882ec35a758aa01d4bc815d18c6491ffab62221abd6d16323488685288658ff177936ecf21ba8a79325ece72b2626388365d4efb256bc9dd0bd1e759d5f890e3e7728910fd68a5cf6abea8eaf120dadcf92b5490b120da8e8f2b297edd276803d149cf3f2a5f8e00a2df3e4da592c53f742975c6affc9f1f3ab3743d65ae33e7f93e34b219234f2ec929cfe34327744d6759937c39337be8f304bd9f57d183295a439687564353afe9666f034616593c2ac1157868535885dcb3a97468718b2beed08f2aff97fdc915a322e30a3b18576525659c822bead076c7d417ac64869e243a34d1ad93d4581637cb3e8756b3b724d929cd774d3974e2e486889f3bbc879038b4f135a3766ef10a38b4eb4155562e778cf7ae78439b734de5690ddf94d52bdcd08a8a6a9d3afbc957b4a193a031546e101bfa60163646be3bac4aec5cb186be2559b05c625383f1437c3f8f9a86360591bb6f794d7690a0a179d5f8b97aea325b3a43ff25ceda4b5e0ad19d193a134ae9c850a532b4e96241f74e86f6354e089a7268ef44c7d07b07718aa18d19cd4334193a8f8784a12ba1fe6a2a7bd8c1d06e47798d1df50b5d9ae9cd4dbe5fe1853692de8eabf0232585bbd05ff635139bfbaf94b8d0c989a95210e116da497e2d26628c20bed14263a2ba4277b99c1e4b167a8d3dcd11540c169a105d2f8f482e1f22ec812baed0b66c676afdadd024212965f870159ae82a32c6d7911397a3429b339ff0f98ea7d0eec9f8db65b262aa9242133537c4f6bc068cb9a874d1e561612c0e87c371180741088a8c0fc3130000000c1a15c7e2b078308c3369fb1400035132285034281822221a1e188c05a3a038100602434140300c068301c160602446743c8a871f071cee47b916901b6c442f1b767e7c4eef0639c903e47bf8f12e077263fa68da0f27e406775d71c091d91f37ff4ddae645f5e3466e53486121a49a1b303cbb2b0fce3446178ec1b96b8fdb5b09d43ad8b3c1918bf86c2093dc62f69d1ab1175a1ff7fb086c5c9eb6a4aca8d8d5356872a97bb582bdb008a5dced554494bdb4154d320fb4e8023107c8d1666efbef91c4ec69a0c51469496341775bf081f2e1034342e63ae991b2826b5498908a2d9e196215d63c3affad86d4818d957802c70095c89f3470a777d86fc58435aec0bbc041db0d39849349ec48c79d0690270251e68eaed547ce16b90ab22e65d84491e0909b177109f7bbd3f6152552905249ba9b047666536f1337eac42891fcb4630c42b8fd263283a066ee2d160fa481d75e2834d3b8e230b04b091d72a9f60ecb8c274431502b9f320175d202a2fe230afe14ae2228824e083f261a76171c004c827ab89b150dda0b377c03c2f10e20ee99459a03f150e52dff5b6c274527753f3f7d47957248e9447ca65deb56a76fcf09e90a55061892e5f523a5e69e1b1b850a3d5c648c86c9ea653ca62d9cd9f40e9b0dde4f9bbcc30921d67da5adde17092b75934abe033c976fbaf7672d53734c3f96444e54c0fbbe37ebd28d1d5d7d8134e6a60eb2b32dc613cf6119648b9faee935c1f29d5a1581c7c720b0c9cdd1aac897c4f4c630b03f687fc8d1932b9bb56e5903b7d7c095c223c1525241b2fd80718e0aa5dafbe55cd6717e14f8f2c29d43936720a8c7d7ce963c2c8449b9f9092b675980423602c64cee3003bfc3c93f9730f43345edd2492ec301fd0ee5437ef6ea88888bff74fde39557ed788e19cb7720dc6eb4236c4daf57fc97b7a06dc427fc4459961534ab0143bbac8862f3a6dc939d682de27c6ef4e5b33f595861ebea16a5522bf8f25ac51bafb3d8c1b1f4c5ac298d2990710f8f42490112148a5c6cc64de41d549c0236156c1fad8b0342612cb236e247b9dc838e9e9b1b537924a09ce6a56aefb444050eaffe51608c2e9c7a1d351e5594ff7686da548144585472bc09e28a3056a6d45f9ba22a5ebcdf89aa489a3841a0866401577c23d39003902b8a27803454bdcec69c0ee4e78196b0b07245410a51f30ac15d6efc0e1abb44397026d4743069a771459dccdb4e1552cc35c491b252d5c3fcc967e44087c1dc8f7b72c913262f355071add30efaf7215f53a0d8c68b4e560994dd2b4c3801e502ccf79a51fb711495c8043b3e7f465b0f7a5e1328a8c208923747b412a5055c616c4a6414179144492bb1083dc48982106f23d6cbc57ada2935d79ee17c0054d84f12542d08bda3ab16166e4830279985f54f0cc1a93030849241883be5b5bf4caedcbef6cd59966aed0e8aa6dd6776847c5d2e0ad14d62e3234803fd88f4b0e06d7e2926c12a9073362195c4f708ccc7ca12b7b924d48ae1f117c20d39a5c827a66bbc608d4985250adfc84c440470d81c849ae96ed07e716ac6450b31f8df39af206a4e71e9c27db381a608a78f05f11975fdae56158298e7b88e26c18c698294f8ad92f9986015f6dfe69d55d2e09ec90f2418f115460d289733c2ef7f39826aaa384bb0b4cff083816928189676f536b37172a1b0778cb3c990c2b36175b0f9b058581fb0b10a7784dea6026bc1651a430e12633f34d219401b1ef7716fff5c1864f3b6aad7428ff8edc001310aff13779af7a94f191cfdcd0042c9ababe8d2c55085e62130792654902262701c248778070b27324c65a995740d3b2d5089f55061e59297334100a6245c33ced22769c7f5b8b8888c5842d132fe19ac98b193f64a7f2260ec750ad8bcc992454d58b29d74c3c8ff09b21a9fb3ff5b5e6ef98de4ae5c56a5a5248e83e32344564434abb2254a9facbc884064b628e7729de8809a40fc3ca6678add62e9f090fba0240fd139e1d78c9878903e5433928eaed234fc294975258d762d6ba70ab1908433b90bf35412bd4c626af936c7c2d233209f9b951bbaf28cb70c49807276798a03cc58f773343b1f4071e5c4a8ce367ba695f02884c85c516dac4021597beb0c18d4e3c4902d488a9e76d5d92842104923552e50a0bb423cc078767651b7af77ea989393a67f2130dfd97e38f73f7506ce27d57677e3c4b688d5c8d37f3b7df48227871c81e278771fa4e120180d2980f1c127843e11fec1454bd26be345214fe35a71af51cd3ac7891655d569a41bfc590b6ae6617ffe1a99da18680923ec57e12f75e63b9285fc5d4672c032aada718cca4aee8c830a67a0e0f175a1c17bf689580ff9588a1c6709048380312e0842e0fed37bc0b846805562655327b76acefa2bbd383b4d7b0e72044882caf4806cea211c393fe4625fb42ce504e86035b3d258cf0f4b1a89b9618bb06d599f90755858fc3cf775d41c6fe164ca69f7466435e819171686d4cb1f66c2a736c0ea3e7172e783cd71de109bba952aacbe16e148b361e5974a86ee6e4258176be7183588f9ff4ccc6f5e9b1a989b8b8ffb189e203b9d4694b606c055eaa3e4ece2074a7c963cc77e0625a806c8af3092a15789821a79979d3fcf6b7ccd8e00f375c130790e1ab7bb5a829c385b82c71bef9b8b00a042633d38bddb56281f68a2a7dbd909313db7ae4a42fb11a8b0908a2bff089605e6bacc79722cc84a5fcc34e5e75a7ac963162456b6e2f9b1dc6b8ce8a5b942ef55faea5ebdab665b7a3fe92b944f9775864fbfe84951a79ca9189aa57f7e387f6e31084db2ff51f2cc030ebb9d2bf14db84292d3c9740b079b0d47de2c06ac52ee9309a3fda4c08635aa722a81c5ab630189167c71efc0e355a7146e6150ee629d9c0142be4c13f8f0090d4685f2cd1f6f87ef30e9ca4601ace9d5cd4500994d9f30604e2cfc29a532d8311319e3c4f820bc0689048bf797f7d8307611acbe8d9e08eaf133e321628fc57e9e6d9284ca1a1b1404d0a81d8c09178fe84c79c0d21ee297894a39ed71ff5ca22236bcd038239a36f51a9f0b0ff39c3532b820820dc212d57364553f429747bc2c332777f7d3dee5a8cc940ddcd77c50e666326bde837e80ce87a680e6cacc3503c355c52fc48759499803ab0bc2b52dbc2391dde2b7c4c306ec6f668e5b937ceeb29e2d2955b56413c8a34588c0ee32b70ce99a60570497bd275a0b74a491bc967d93b9e354886c360c4bb694b5a229fc89b2c2f684c5293de12f2fc355481d23d9dc584e664e1f20ddac651c5dce99e1383d70ca0ccaad3645d8a0e5c95051bfa0cfc70168daa78150e60bb659e8865ea852aeb31008d09ddc1c4672cc83de0ab15f7e4e306cd213b4088f0a1bb9cf83bed02bcec16fe7d08ca3955d3e8f1ce84990626e2732a9d0e6d6a0324f6aeaf16362b655c0690e939fca1ff9db9c18ad3d2564c26b5bd5c843c6227a25951d84ef1bb349731c5a542df2d05f4a7ee5011d93b4ad00cf4a8f7c44af2da89e183caf1a6d669e5007a92294bcc85794ce8d6ad98b66364629e4c25c2a896f3e8bccbc96ababf43a1c127572ac98ed826a63a54161b834bf1f7636465e993193d03c29678e668584ee3bb407ba06e1e49164bc51ed3fb4f1602b16d43b1249cfd78560a51364a7867741a04f86d308389ec3e70fc92abcbba1b7782f9d1a07aee5efde24ae6203d4840113eea090e8007aab94117d536e781adda30c2c8867800ed540ff7067aa8ca6bb3503cdcbe8f46cf78f5457ce267e75319011ce70ddef9953f366def49affc6e5acdc9a55b94b5e3c4de21ac71d903d834467fba526299a93d053430cb2abbff0a7a759d942b8256fa327f52c061fedd76d8b4a0b6944cd6de1239c96ba1421e0390296037cf1dafd4910102def3682210fe2f20950b8d774cdaad99a65fae1eaeb5a46a57c3d059b60c375f166b77ca53265c0eabaa6595116c8051b400deb7bed66d942659e81e54824eacfbad11a4b354c913063804608441d3b8ceeb53375035f7e29c83f0c735469c2bd21c8dc7374664084b7008ee85fa1ffc2f69c07a372e634a896eccdd06f7611e80bec33d053a103ede0e30fcf9d514cf9c02bd8063d4afb8cfc5837611dbb4593b1d44a0dfc689a20e34756ee8ad0ed2e24970990c90ea5b4fef4250b1a77974ffc3fce234dc0f2e899eebd0fc931a45390f940c639cc11710f1d1d31527b153aeef038883352d836f518330aaf6cb9f749e3ec084b87eacc430e37e6ce9b2d5942000ba41485d980683048d9f7fcb9362613a3514925823b6656f43b75f30fc7524af7a1e7745d837cd0ab5593dd31b17013bd8eb44239ef2e1b070f11b39d0ace00e93b2136cec66ef4407cf7cfbaed81ffeb37a8ed46854b0ef04fe69f5ff05a2e6fa2dca86636fd5edc1386179a2f0d83b2f8c64971afea9e6ee32b0166654a6f2ec4126121aa4da0a3d2870caa97ee5ff5547da89e6abddaa68e0c417faa26ab6668a37ba9b00c7bd769fe1bac78e8d98f8a30da19064d7547b7857ebfbae4b12bdefdefdce50ac85f40d2c201d4d65f86f7733a51f961ef7faa7fef0a232a9d661e24537147b6a1db5fce7fcb2e11dd6fd702337d01b155a2a62681261be20a0cb8487a18cc86d58a174c24cbd31b6456970bd2dbf932c07fc1a9d580a11e31c348774f523aa0c5914339724730f7add2fbc8bee88a800c4078fb6f85fc0e4855c99a6491fcb13dd082f4f0cde891460e9514ed8d00d45c780c2d83f4fb24c37e4e6b28e5a9fc1513441cc02c9718c32eac769e77f86d6eff9efc87e5a09c9d075526b1a490de7262be29fd5532e82d4a715130db0cffbeccdc5ef25f88705d4f36d1b81d2186a4f602267358f5467d899404faee01a2436cba0ea5b5200e137bea5d16fd6a056a0a75f1148b1c310ab014835344af441861a23b68001c1878786678996466761b6f4a1a24a03229723337b697742681c693bd8750848011735321439080645e4a0dadd02c7d58a4d4c42315400c149ba4718941bda07cc0f3b31a85520003de2d93e2c0d8ecfb4a24d819290738a3209e5f4ae471b030b9e1125989051d5249c1b8c179b1765e286e177868ba0e8e14a9525ae89f9f7c877b056d444d9bdb55cb450b50e3a2c1c09fed11fdd11f07c81937077c4333902c529898b3ec93d5136a30f7099a582a229eb5984c584d1b3657aa5da3597cc69d5f6801beb51578807ecddf7bb82abb4cba2ae742ae5689aceeaa1172965c81c13f21f5fd0ab7c4ad1c9a827d72e2e5ed29cffa768871eddfdbd995f835c5ab4311a56635c768a1f2b6d7595bd138a409d2cfa4362885998711f1230d78c45ec339578dbc99f8e3791f3f02a46f6157781954081f6f154992b775cb5e306891e0a580d07a500949a6d17e05abc886c498a693bd24220dfcd71d47e2aae65ba4d6dab19fbd26a48d42cb4989bb580c84e436446b1ac2093185a3d64ea59b98e9889a499b6ccd5a73553079ca36d2fd5e7ead74a753356165c1de07b7828dd64ed5d8c8b5a50177f8a46e8d9f5b96388c6116dde1c11d8b8f464b92893e4faa3aa2d30b0b79479758c1f6d410909b61c4db943cb37b06c94809dd4bee2c4c0b3f58100145572aace4bbebf29d9d784ee692adcddab02a8277701cec5b784a5029ff9fb9ccbcbb7000bdc73020bd16ad90ebbc0f73df2e359f1a35e7f55371b944baec8b4f260d15fe12a4907bfece9db9f2c20c9cec1f626aa56478c5e3a04c3a2da4850bca4758a254465f01b7a025bd3310981ce538dc535d4d8b65a2b683ce6fc0be909cf33eb599a1c3c243a9fbe24de262df15842588a3c70e05aa6171a32791e03240635e654395a51a82519047fbd921b0c954ba239a42751f2d586645576af35c1f1f81d4f71801e6cf14504fae01c97349521e52be37523596e09db19e4c895566c7d9b5cf1eb6e25c52a4ee44a42df0d7d182664da05b0b22d2207ddb0b06cf0f86e6812b2ccc7f1a031d749589887d6ee3d7dc19331bef157ad6a7ef68088243a3e79c6b2e12d2f290490b679fe7c5363cd58c94f3feeb39515d0d5c1e68001759d0714f3c52d084d061195386fd8730685633a000c0c6f3d6628d8d8b7bf17975960eea8f7b284ccd18e82443319f59cc0758db59008907cb23b562ba99a509034542f6aa9dd12de6f0f03785bc36cdd65e3c83b48c5bc91649ef1ac3188295df4e4a14e9f02ae046cc9384258c257ae4e46ee08a469cd70ac20b6a7d7c57708a41ead3b52835be7ae45e989ce0e1c7301b511bfe337180a4765c67fe19a32a624b1f4735a1ad6ed173d3665b6bc5e847930b49092f7a1f5751d67249dc5a0a5c6eac347b51399b750011b671b202a95614b00a08f308851cb551dad75ce69054061b25e2c8f489821f8fd64a43410443c8fe8af0efb8b448762655e660660a9eb1c171e8b36710bbf6e9cfd028b591b22714f0c4140290120e55e8db2bcc5360e581c25d1792852bb5ee9e3407e2bcbabac4e41202a7d639449eb07d70bb31f430c9f0b7550e1ae3d0230cb5815aa54fd86e4df4316ab1eda7357ff2472664f6ad28d046a7878124151ac5c750c8514d6c8e54450eaf25872b29cbb0917dbd71fdc6c70b15245de33113ad82f2ca9c8bd63b8863fd85694966332fbace8901abae817672a3728a133342df4d79507f457e731b014e34f5c5e5ea7a1527372a8956692f3e85a1d2ea30f14b22969b16cde60fb6772a4854d7c8da644f85c1e4a0b594ec78c074f06cd6425b5b389f9c7070f166105ae5d0755e67e136888788060697136b8c77a340cb94f71a8c31ddf1e22578ecd1b4baa0e460e48fc927f909158086395bc26bc0b8632e7e67685912d0860a3cb36f5c57655bba9e972d017e70b8c08a9fae904edf169890efce46250f08f8f1fda1a5bea875cd8a7419a1e08d4e6e098a488ec1cf67ab9366e5cd8f44d7c16eb872cd88a828dd0f32ff29514c56d9fc8d2e4dcdef625cc24dbf5f60fb8d408bb28a4989928c9bf8d8109b0ab5036f902c41de42bfb304dc219472116b05637d1e55bdc74d6077956170ea15a3857587b96981d4ccfed41963c1782239df90712533014231fe530b4a7f445d71373221da0bdf917e2b54b72a58025b5c95eb6124f01d8a88ee5e953b37c22909f290e8a0ac2e68450b2284cba2dbd018184c84a95429af6df0e9e8164d56a18da5e3c5472ab3ae930264b4d8d8147bc4ebf02dde82dd43c1bb49b0c6db2983cf9011a859c4f5eb2bce115c62f1fc80031e0d2e3a41db004be37a73014b288481bc81abb57de00ae3d0d894e39ed90ca61103a3d40248b2fc2c04089c86feb71c34634c9a1fb9feeaf80da562cac2d573ff67bd1a29d74df43f7cd40cd8d5c0c6fff904d4b749bbb85d5bfa4c4874ac4ac5e4a4220b7aee030c82253e5137a55c5ca8ec31d194b1fece46b3c2b61d96202d1a42aac60a66bdba5cb7d221b099ac7cbbb5d1a5d8ae6997a6e97431777a13753fe710810482baf8706c6f2a064016f275997b1abe6418533e218d76786e2e3273605652ff9ac4825a23b562ed2609340a847ab00fd7fe0682c69ffef059fb4a433fff469dee5b2c3da6c9c57c52a7534be9aebe39dfde4e0eae3b293c28649ffe4060a5f0685bee2745b61e99c383de35062da7a963f66f489111821b2b76482768bb0bd697d1c9aec16db9c41d886c7e10b0c1fd6afaef549fa287fa8202ac04127d77dc05e88307adfb1b745a8ccbb330b42501858fcc08be2ecc75f4be3df8b5ae7e833a12cb1bec8e91726332d9a406ce87d5b3f176c031857706e4db62768db81f13bc7017f95b825f5eb6b9bd0d2713297a80a3414999e7af5a1e2ca25c912d212084f6624a3d522ad169ccfaa66ec2e5e09635c40111f7abf54e639db33cb5017d73fdd88dce0cb0830ce14c42cc4245c1703bd55e17350c551a6dc9beb2a95ae8e862967a59036c7b77d4e94ed9dccc3ea549f4590eeebe42c27774a4cbc74a300e00c93f61f6e3be14eaffef2b304186e5d968a1c425c977702f3f402dd904e2c38ab1feac5b1889b27c49ee5bc07af81afe3e862cdbad00bd35d76035f4cc4582e1ef7b461ea13c0d3a35862ff36ae4e26ca8e1d36a83fe53ae59217e735f538ebdfad4f5cc773bea66f37580c906adde9377dde27f180060e093a3b247c20f2324e07ff34b4c5dfdcc887d28069cb040bb92c461afd509e246f325b9d998d440ffd9113f6b6bfed0abfeeb94c58549994dcf5f182d4613e9c94843f98b3b60d318ea3b5e029f4c8481a4529dc01741152fe5f3ab63c16620036441636bd8878d3a1e06700c85ebc75a205d98ca2c4b55622b9127d53c8089bc26d45acbe505cd7902d43c6a8e1534477548b4a2b24e2ddc17ca5144abb49c4f9dd783fe8c748d6a2060ddc5419f8dde0e5416f8994a120c39b82f762f86539f44142b405efb619ed020a84e4e4d44073a1c8555b00d012e7a8b07745b33bec16c7738158501f0a80a14119643de433036ff5841238c7a53f628267c7c62eed8c1821d89c42555352b8ec0159c9125bad3b86fc81a96e755933d2ebe201f586b7edfe014ca72e2eabddab12aca9de48a0d22603158b667ac2ebcc77c6ea027069e3edaa04da743e5048da501a056450d19c1e082e398416f21c91bb184bce99d149a70e127c68ac782de6630fb563c4eb0c6909a683d9525704244a690ac6c88a29cf6fc06b04576e7a980fcac3dac2e4ea24222416a49f06e2c97571cb8cadd1f384ccad60fcfb0f9d44748d9ce9ce8a23095adfb42f9b2f874f048632d1e68865b5269930d138f15cf13fb28273c52b7d58d197705251224a74618b93107eae95eb477a63c530c28f84ac098093b88cbd70b422a174c7e9d820abdbd13b4dd9c01108e22d51099969be4c065ea347b2340cf9976798c6adec79426ce7ec329d470a440cdc2c0157b96f81a58e9f1b631c151fc8e00abe439f47495d9a6070aab81542f86909549e495d37e01f037dd51a73cf1950b65c661ca329fa48104e2069800a645ad4fdb1c9de1a515e0ef2edb097893810dd85d2343b398bec78a119b042cc3726db3e8846dcec217f42d8440c599c0f6c0d0e85b5a31a6e3061bfdb710bff444ae03259ee612527244cf84523c7fb84fbabcb138e04a0508c2c66264c4ecf552a6361c87dc440fa4bd44fea5a8b30fcea0bdff62d2bb462163c94a88db6e928e3d8c333e32ebd36f652bae471a40fc26f4c7ec16ad09164e43df4a8b9f7e767198e640494fbc767c3a818c4637aad77c0b6a0a1187c0bbbb2e4608876203971a5c3bc536ae92d875bf74ba7ffcad4501a9dcff882ba903cefd1eceba256b5045823dfeabf46fbadbaaaa236440494bbbb118209d964df7e2016b826a821803492c0ae215be389c1f098916597fe15d6784c016c328d58906b8637b9ae9156869ed7fc5992ff5a1db63f15132d3755c2cbf871883bf0d3867d8f03e66764b785f9e43086c2121390673ba3f3f9508164a979a0fc2160c3abf317d5267721f4d9845eaf49d81ce29f3a591d8db9fa06cb8a19e4e2e534e103a7fb7a3203d12e33167a7f6c4b716f6e70dfdb3c8fc657349f92c416a7bd6f285756a0e91fd1bb3bf843fcacc055101bd9b2d5786ec84f8071a6dd653519a872fffa356e316967a94cd3e1412fbe9fc43023cb1f41b0b92ba42d9d7fd27667bcb36521161f35c855eb9468c1ea203a78d45d6f17e163a3f6930a8f3b2abb92d991ca45851c37518c32a84b6497e9d8948d97060bb2bd98d8e361f9eb8827cd43c3e81d207aa013c61b173b87caa4d8ef3f231a50f20d38195e31ab8b78de38151b4483a70e80f45a1a994f88c871203555fd9488dbb405602db3393408932be20094f84f65d9f44651d9fa8e008cb10fc3358169e12a6f3da22ad318d6ca477fa181be6d2a849a30ed43882b250e74372d4f38d92850d815e4bfb086aa643aaebeaf492ffb79055088df9c6bb9c85d5bed326632f34344defd5790d066e3ab1470117fd7ce313bc70abbb80b70143a35b81f4ed9b5c7201405959dac77449b2fe0621547408037069dce7341547b9a5e0b5db70f42b78f4db574407486ad470d4e2838bbba540c4040e6c7aae4fdddabc3956cede0ca8db3c886d4e48e2b856681b98b69edef67040d5dd21933b5935e59bc974d6d0359a1b7d30bf076602b35862a3d4417c44ec24b48d1156010e9a75cac77e73c77888563f31b0f1544e51856a0784b533d673558ed2f123a5f83cfc5ac412bbe832e90696d81d0b6e1394d4dd05fb611e44847fd951af6265d02a189b99f54410a275bdb5b008408dcfd54197760ce0071570539b6277d0db9591e99f2f215bf96e28145fb307c2e4151f44414085ad09e103b5aaf3a26d0c1d97d15ff44da25548f7801f00171189f68116c14caa0982ead57053fb69bd036efb8efd00ac298d0621a865d949a10c71be8cecb8a5e661d362c57f274d4b7456e9db9710b61f636c5fc3a6216c8cbe17b5710ea82f58a2ee6173d4b0b7b129d5583389b1ba6c5368ee25a22cdcdd062a0c23c75aada556c44fce4273f3fbd9b284b6e85ad9f7d17b35e0a9e681fd6ba53fb2010612fbe37fadf605d8bb27bc60d83030be4e58d70fc8be452e06a6f4f601b76b48d502b438b26376904a6058f5abb4113dab73e3f84c9f2ca2e2db0285375cb8e01ae25012e864c84b3e78dbac7e15da61d4488e4ca0df721ed406ce033b1e8245156a50820220b4f095212be626fb61d85afb153feecd0fddb1209b10a195830ef0cdbaffb73179446cc0087a5d5d008ef807fab3fb4b62ebbc2c259e211271803c834c943ddfb07e9d9630237b52c52ea7157d4e9157a030dea13a759f1394f247e5d460f0f002b36c1824144367243bcac6106a4294ef5c54b7b404ed821a1bc23d0f3649097e13f7aa595f8be10f1a0b0db0872c39dc02b9f4d9d3e755f9d0c3781f8bd2107d10979b064899b54f3098b4b64ba626807fd584b406f356af5d966d3ee846c72f69e1a7f883484f43a20245a353ec52a72b8b844cf2ba74956ad102891ad304948e6d51aca7dc6e624eea30f53fad9cfafe6c112d4177fa2c86e0157955198c28354be96abef237463960cf8fa8a5e7ccaefc93e641301ab3df0d01111bd487920413f4429ffebe65f97b1f28c25c9bc69038eb4731521c1c327ee227fc16b5ccb916cc237077f4efc242440b3aaeb2c616dca76c0fc9e486b0898177391d113a036153a76af1f0337fb26524aa3945c8eec31f846bcf95a01f28fb3ae9d244c54c432f0fd721426dec5be34b96f7ea5803a25527018396e1f71fe3d9e172d627249ae1a461d2c6de28e3ecfd1f72d0f22da7b3423c97054cf12646bef05a2459c1623682f0150591ec6278ea0d11c22e7aac2f2c77fc1254ad4ce14c11331d50165ac5bb823517e34d4022ea145b86f08e904417d110911dae8d4c34cbf19e06bed14abcf4018c0c0aa6594680d9adedaaacc968d2e4c404ea279b0ba3f55c0dc2131d916aa0066350d905f0bcfc0c3798500631d07e141c86d66cef60d7a4d3dcb5363301921ee9714eb1e96b640545556466870fb9a1a8bee7a3be69a258b346f40c37d9983ec15343c3011afe9d5f017fd4146ddd0a599a66b08d52508c4a068618d1c032a91caf83955ee7bde09b3174d85819b310b928b284c1d41cee93c321668b0bce26ab2da5f85b47d4172dafdef1e0cab94fd42023256f7137ca0d0bb7d4bb9474c74af5b384b45612fbd4e17d88242a892589522583c42a457310dc2922ad323af6ade89a4fabf0a03f9e63c4e31d787489c77af53c544a9b82462d11a5e42895dd91402d31b0cb2d34aa061cbf6341a9e8f27d3d5f18b67f11ec3be53550b97f90b7b67d82f27a9521db28573949655bb26ca7cc7dd7c4018610e53e3f925b31b5a0ad942df57648bb7b610e192fad1d7585c5f4a7579d155a2fd46df1186b91fd107e8cd13574a675d5cdd9e74c1882cbd5bdd752fe47ba3d9432aa66a6479d78dbd6d495a39821aaa3375662e5f6a4e415118b879c4891a09b2adcba09b0319931d263d6ee5ec24846cdfa2ea356a94f68edc150da00d88dbf6df036da6d81fe2d40d3c259d585614bf1afcf8f5b783d0bebb4602c2d78d78273050b43d240bc6a582c70775b18820ecfeb08c702e526160651778f9e61b290eb2ed81b064f9385918c01f271e1510f9d6e78c9b494287e0898d5e2c00fb1eccb1e06f529b2940af840a526af12208607ee4cc77222ad3bfabde5ccf27457f0a159aa5b6c3b113f03aba7969540137adf52d8a10b6976851728db6b93362cee979d9515d6f2a2080f159e45a3dd16b5303b51f1c8d3be35adb33e3ea305e01f91ac136cad5eabd3e47e5203b9bd7763d7f803ad65d59cf61a13b2893cf7b94570b7438cb37486fc38734a231963c32cfa2e28672a5827bafa7c6c73619d84d78978b531cf5bc2f9d512f9b3d2b9fad4288a98f8c6ba3cf6e58716c0920b00ee8a88a1326a43cb0312bc58f7951c0e129e523366abe28e27482f40fc5e4ec8046b05c0c300b261bbab275659d226522162fef396c46abc936c968c6f462b1034906eb8aed479dea56269c8c5d07633c0ab94a12833b4261066cc229c750646270f08ddcad971482ffec50a6610c0839d1dc91e0c813909b6027f683bf4e66f0580d904bdcf2d6de75c4574591789c346b64264e7a82c01e5ed11a7f22b4685ac0b69690f892347e26e19cb7454c69a15d928a095609332bbadcfc325f7b7a6162e86a7ef4f9ffaa5ffcafd0f13f24c44713f3da7bc45dacb41d9e1432faf479c919e063767f3369ba797bb34dfaf75f3f956d9830df3c90cd3b6043a45885cbd28295e1db6edaabe7911e455fa093d104c651bc4896fb0b184ac61b10e9f09f2ae1960e303e9fce56dffd7477de28a199fb6193eb2a57b4b22560a5cbb2293e67c08847a96e4f9fe17449ddc6102de5704240b3540b2a4d001ffffffffffffe725605a4231e151dbdab7b665da9749ca042f819230cac780dc29a59464d2761984d00b797b606f3b170d0be20b8e0ae5d5dc69445576c156122fc79272ce5c932ef8ad15a5475b5ae53c179cb6c91ba12b03c10597241b99c474b27ff505720bb64f27d5d70f265f9f6cc157e8aca72cedf67b4e0e20b56073a67e8ef9745af0aa9fbc63297d16dc89ce9d3e5aa632af65c1e73599b457d468d12e482c782ba539082cb89cf25e4e6ddbcfbf80bc82b516a5fd9a46617c140b3ec2f8a8157c84f1512af808e3a352f011c647a1e0a30529f8f803882bb89c429b98762738d65ac189ee3d963b765a27a2006105d7dde79ec4f3261564156c65d714936c62aae05a94249a5cd2c64e8f6105482a38fda6bb1d3d985892840a1054702546cf59526c8b51d4c929404ec19a66c7d8aea6162d17828f303e4080a3470eb661630763e4a0038829f8de35dbdccdd163b2147cde92f26ddcd027296159523042ba655dfab6a3e0a49e9c95c4749b63cc8982d14e82509663c994942643c149d131e69b89e6319a7241c1e611162ad52d557e7f3fc166d1f1a2768d3cc1e874dbb13dbe5ef0773bc1595e4be2793527597f4e7025694c9252696329b153d700d9049f8489f0a423b73c694034c176fcac62a9c4682618b7710f91fa266d00c10477426693f5b22ba5d0eb2558d331785e3aa12578d1c93bc9995e2538bb3bbff89d46e752b10184129c5d29a5e209f62412215c754c89ab69009104af962d4bcabf414d7455072091e04da9986d522a398ac88040823babb392e5a2443cedca03e411fc68ad182de69484eab6078f1c298081a92e401cc149a783da746a4cea24db08aefe93e4b163954811d10b208ce0cd57db4417f3ba00b208ee7bfcafc2a3208ae0b206cfb96a4ac58a3989e02fd735fd8877a7a6bb061044f09bfafea97b3729b1170d208760fb422bb433f977ae1882cd9f56195aa285e0f7d5a4ec9d54030821b81195337352cd20f88d22dd2459638b2e590a824d629097aa25760324107c8e6562eb68f9778ae70c4000c1798ee117db524a59a782fc81934cfad1c95cb54e80f8810ded92bedccd4afa65c306481f58db54bf9db32d08c147181f36ec864102840fac97cae972922b7f9b1c1b0906903db01574929359255d1d73103d706b2a9e9247e540f2c0a91c648c31293f8f29080f9ca0cc946d8bc91db8d396b4efb7036f920e11ea4135c9f9ab031b2c57050d1a3a306ada842ea5b5a4cfe41cf87ead13cc547bb0183970b9738df0342edaafc581d3984ca80c2d6db31a0efd9b50d76ab26b500d9037f0ab666fa9ca9298454cd20071031b33a6f1d4180469039fa1df2431e6b8d14b0e840dbc455defcdfc26c87341d6c0bf9f6c79b2e9133ac6d5c09f983da8eb9225774e4a039b3e284fa75e43c9f240d0c09752cba74c93d7691fe40c8cc97a52e9f2a4a3b6098819f8a4d42d77a53d49561148195853933746731d840cc56cb93c8aab47c6259031f0414fbceb202d1c8b3d40c4c09d947495bcd6fc39c343870e1c0777808481354f25a9a4c57c93dcc1b1d6e37e0002063ea3d567d56831ff461b3640d6e0ab34e36d8a96f305f64f3c413c087981b3d17f3177cc2706cf11438c1cbee35b60c3860d1b5d60355a32e982dab8c07bdc4ba9ea6b4927495a00d902ef19e3c68d39ea5892ca028816389934fa26abf30c2059604d5092acbc191940d4e02479a45baaaaec1a333380a4c1c61c54491d6c2cf0d9e4df0c6ea1712b650c2057e05adb4d7d2f465f0c767c0b92322bf049cc1fcf5cc221981480a0c166b490d67b4a3800a90227494acc793ff518809cc17daeacf64c55167fa3021fe47ace7b7ef9db537e0099027faa6e17444747d4480a8c923fb61583997c521d05ae73a9c92469ef126e9580070814b85056ea426b12ef35fe046ed57627f0d92a57eeb65139dddd043e9ee09a6c3c95a73d6102fb25fb86ae98eff30497c09df6249a976f206630727f94124f87c9a73ca33c0051025bbd5e824a4aa8933ca9a6ec04204960bd3c6ef9899d6d4090c0252926df937cdba40906a3f7ed4907617d2560302ad473e95c927ec1499fa4b01795e40b468a89215357922dd8df0b4eceedce4bc2d4b57e5ef063d2e66e5728a99bdf059f4d7b4428d1d7059b044fa96ec4366efab9e03f7bde642989d5ea3d2ef8cb74212d98860e22740b4e3e75179465d82539c8167c775f096a1d42ba8e6ac1eb6ed0bab9a7a6b28816ecfd9d2e2d59fb5ba25970f9d64add567a2ecf910527ccdd324cae68bf4f2cd8bc24e94f426aad7a07168c52751adf6d7f0597eee3db49f2a6979c76051bf294a4e437a97d37dd0a36ace3be2839c8a4df66059f35a698f43a7a3adaabe0cc445eee131545575a156cd709cab3eb4effc4a48255939ab265e55d491a54701d93bfdd9d49424d730a6e545dc614fc5afc3f8b9747d5a8149c90e7153dd826294c1252b037d2c4e09e3d074d26a360bb7429cf15531b2f1105df3ac2c3ff3ce8a6a1e0a287a9e4698282ab4f2725e1efad39b69f60e399ec1e4dce4d926a3dc17f8d929a1def0417df34495317cbefe4049fc23e6fa69c6e824bf2ebdbeaa69ae03599f6b4d9368d6e32c199cc9b360725263821ed5653a9e4251813cd43c99782d0a94a4bf06152544c335809469d74e209b5a95f724809be464b2ebd1d4e82539ae3e532f91dc42309defb577473ec507d72916094bcd020cf0309362db7a5dc3e82132253a889a96b4a7704fb694c67aaa42d69b4115c29dd122a9e6a9930823d95be5e3da4473517c14751e992e65814c1ad5bee4b6227117c4eb5d1d641042326a8698a7988822c7943f0976bad742eb142b0a57a53f0a8158e1d23c78d31cad881d64308af4608ce829262dee5242da7d120f88ec13e9b58e9a02712046b425b97f294dac43a0582abab20a2d54fa5c73420f8bc41fd3fa7fae441e50f6cf2be4dd3d9f526ef07fee4c874b208e58e2e630737c628638799c9c1471f785141e824dfad8a0ce203a3a349052fa57f4d4eee813bfda8fa56a94d0926217c8f327c70e313bbf1a1073e55274f4f42e53df13cf0de252aa8123ae73fc1213c0a8c18fdf78107be7544ff3593c6cdb531e3e30e9c8c294bba9c59bd0104e3c30e8c85d29cc74ae8c50b2a01cef8a8033f324fecf465b94c7cd081bd0b95479b1cdfc5c71cd8912958dde516ad9ac3b1b6bbbbabaaaaaaaa9a9999999989888888887877777777574a29a594528a999999999964350b07c08a0f39f07e6367164b5dda9de2c0694f25b70495f26c5470e04b89bc3e1def923df506ce3e27733f9197b1533730e275c2fcf2e6bf4ddbc0a99cfd723c648ad9e4d9c049f18c5d4a303154ed6be0fb46273749f37592f26a38c2471a18d3ffd3a759b2a6894103e741a6186e7255ca113a0327639ddc9636fac5136306f684df9ad6dca6af82cac008a5b4931ad1e6163764602d3ca791a6ba3130a6e45fec919618b8f5689e4374af73bfa30c32c2c0a64ad9db6a95c4be8620041d3bc0c0af8e965cf7a4f29be81a6c5fe7f6f312adcc24bfc055dae07e6d274b8edd1a1f5e602fd4a41ff56c173861f2d79574a3f3c454173eb8c0f86b4aaa4c94acda295be03d5b2ce8935e2b7c6881cd965bdcb2ece3a51d8d8f2c70a5bb4e0c95972a4a8fc2871a7cf2e09d4525213d49591a8ceea9cecdd99764530ac30716f8affa53a6e92f7c5c811d0df14cd1ad0d3aabc18715d8dcaf110b3ed0602f556e50a1c1f2fa8d632dd9c1471518992633c54ee5d95a7b220c410752227c9cc18e5c4d529eb858ce6211c20715b8cc24c6a4848812b305081f53e0dac744fec93129991b5fc68e73fac6187daaf4f890027e4481b74fabd95194e058d331c68d64c707141875c2e434d154da0ba1311e08bfe309fc2969ed26474fb89663f429627c38c1d7cb78f0d1043e9364d14d3aaf4f821213580d5dd295da30b1949c25f09b7c2b2c84c70c2e83ce266b893985e794c0291953a894629d04eee2b8063791b1118529299950274770a53c4da3498255db084ef01de569bd79ca6304a74908d1dab1b407cb22f8d8f99a4f6e8a604c3a95d39d08d6c6cd4e7f4c8f314304af26093e2a2bd8670ec1be989c9d83bed3ac2138b5ff96ecab52082e6ad44d295508c1979c97828ee7f5aaca20d83049923628a961a22408ce2cc934495220d8649ee9725797142640b09e4187bd8998a8f93f7025dd82f6fee8207c3fb02929490c154c6f507d1fd8a0c40d1af407f3e4e103ab4974ae5f329d92670f7c6df4136fd773785c0f8cfa8d1dc2cf032373ec4b39dfef36c703b74965eae62427a9dd8113bc440fa26a3bd415423de554d78131511baa6f3a7bc7d0814ba1ab2edc4a905133074ed347ef241a5395123930ba9671f39fc481512754ccd368cf4f02076e5bfd4f1cf55f3379031fc4925daa0d6d82d60de532b104d120e62256c9401b3831953d6d5b08215c36304ac7d0a393fa9d6ad7c09b949418c284263948d5c0c91cd32b9b9c3b3b9a06c6dab6d46707915945036392cefc25bac78fea19f84ae57e3a6e8977a71938b54a9681ad136f4d78ddf8956460838e9ff6a397343dda1818d7de24831aa1b44613035ffe1fb395d2c2c05d4c8b5f52478ad21918386149f6a4643e0ff2b3353825bd8eecb2374b39fb02972425c54b6db5778b7981ef52b2e5cd5b6ac3625d60ff54f433b5bf0d997181b3f49f2cfdc413add91638db55d7a444899ebc16f828b237ec6ecf04a12c70bfc1b6f383d4e0466f6dfa0e936ea1343825738e7d2c31a6c9c102d7c94a52d946c852fb1518d754c9ae4ace546a2b701fa23788495194d56830a6efd35def0733992a30fa95ab769aaedf33381dffb1d568d9dc840adc095121afea4c5f9229f4157c54a7929402278d6ed3a4b3e525330a9c6827d6df8750e052bbf692a6b35bef097c1251aef9f62a2715277072847c6dbd348171ebedbe8fbed533811b531963be04ae3f6713649514ec36834f72f4f3efc61f5509bcdd574c7ad7a104d5c4e86341069210810c20e1432418151001068f217c0f2e20f20b5ff0f00104447ad100115ef028a347f7e0e100915d4c4044170a10c945d2a1630719b85880c82d7ca0820388d80244a4162a428b1ecfe306106671230719206080882c2420120b58bc020122ae18438703445a6100115694c82a74a43172dc10438c3e6288d161a8a20222a94045182a720a536840a4142222a4b891830c10584064143b104528de0122a010438c3e0810f90404443c3101914ee42003042200c105443891229bf810d144024432818908885ca28c05885802032295e81e3acaf8c10d1e39c8008104442831890f1149808087183a74b4000322911011814422f20894e3468fe7f1001147f0f81c141069c48d1c6480e002228ce0f121b2881b5fc697e1821deca063c0011145f0488405441011019143dc90808821202052080988104205081019c402440491009140fc0e1d6114400410ec7d98f795d0233365ffc0e9947e3f68eec919227ee0a3658b08a125c5e8561fd83f5dd9adb137227ce0360615913df0eaa5d9269e943356498f317294f1832288e881f39329f697637c900736f7455113558212db8520820736df5996f45b9fa6ad3bf01dc73d5ac64cae3bb2032f1a4da9ecf697ce4d53072e9a9b6dda5237f949e8c0464fe3d164a97360d449428fb6682207eebdf7373fe5c4813f4975666e2f4fd7e1c0a5cb6257bd63edb97b03772157fddc32afaf6ee05ddb749235fb5912b6814df2c6a4154d59595547840d9c9fc8f5b513269a9488ac814f6f7b256c64226ae053733c793905edf9fe34b031b424e15779347099b34c274de29624a25e94fc129ab62666e0a4dd389e7312dc3dba65e0730e199efc36cda4950c8c4c313e062ed58534312f29064ea62cfaac378563cd129130d8d94b1ebdfa70ec8e1e641c0e11309cc81a27f28513f1c28974e144b870225b38112d9c48164e448d1349e344b070225738112b9c081a2752851339e344a87022533811299c48144e040a27f2841371c28934e1449870224b3811334e44092792841341c28504e342807121bfb8105f5c482f2e84171784905d84e8821ba9292378c1472e2e041717728b0bb1c585d4e2426881aa76878e3278d8b0f13bb061035d191f3ef81e26f8f052468f166304366c8cf13d7ab418e94c006e089905bfe2d549bae5f4d6231c9b9c2c2e24166c58a80c3a3fad2e69d10421b0e07e2bf4d76d50a258fe158c5e5eaa98973f9914ba825361a9c1c43531985f21ade0f5537bbc4a924a49920a61052709426f67fa0b268719b20a56a4f7ff855a3d72f0d041068f11249c085145319df75e5039ba584252c1c6f39354994e631f4250c19655d0491aa13a057b1bcc847865dc4c5138849882adbcd9dc2d0695a4da524829b8caff39f34449c19b8a5d9972294949291dc5d7fef77b66ddf68dffa4a2606df74db99fb926c19050b01f4fce56f289c14108284c1b1acf94e8c69c10f2094e067939ef682c4198a9ea094e9dbc9b84997854370b00d008e904db55d953f692c4746f12c209c69298596b9997092d64139c2a49cc270956a74a4e12a209de4c923b6b9398184232c19f9856a695e26a6a0e26d8fd3429fe65c956d9bd041b2c5dcc55cb12fc282ba59b4cb212fcc8ee134ac99c4daa9c126cc6f320ac44336412ac49cb2e0d3275094a5c12bc5bec32a159d53c7e91e03d9ea867c7acf28c438213d36add6a53fdbe097904275bcd4c49552945660e218ee04d122bacdc5f4ff4ee843482eb5842ffd2bbf5d91fc20846ea9569cca371e36771ac9923842c820dfa2fbd59b725136370acddd081ca144214c1a935dd295e8919774489e0346875775bc711c1d78957794d9b86d2f010ac4919b39f9ca43caa1c64b4213849895fd2d5514821f8dd347a295d73de87105c8c99453f73335732e158bb91838c360685904130bab269dbe711c7da0d1d2899102208365e98672e490c96475f061981e06c747fce111db5268400828d96d3c92e2a5208f903274992c9d7d10d1d7ee04b9b6ae7df89712f8663ed4ccd08e903eb5aa206938289d4bd7420326430060b30008f08e1037f55414fa816cf98a13df095d924f9a4248a474fd2037b2a79aeb86af2c0c692625e7db2a8f6080f6cd29cf9c4f3db92ee1db89c47975a6ccda35662073698a01a749964b0600739d218e785903a30f651735252496ff2d37708a103dba77647f68f88a82ff81d8cd138e81032877a44a7a4922466840891036b6f9a9fcce399a5fcde101207d62eaf29f9fc7f4f5edb100207b64ad05e7ea2e528b164c3c6bd81f1dc49924db2f50c216ee0a257dc94a29a98a56e481b18ad9f6b93878c39a26303671f4a54cb63513b946cd858036fe671ed848ca1cbe4d5c0494a8389d1fc4da5a03278f0c89128084983a99210fa9952ca0841033b2a8ee8568af9ae3c38d678ec3803bf9e73974edb256ad0af195851f1b2c754cab2a737870ea5414819387df30f96f2fb572e082103e7fea1fc244992a29ba00d1903a7a4876de8d339e78f3b769471121b8488817d2d29552d42e830c2c0abc9d4372656e9272b080103b756257889b1d2743338d64ac81a5c9f1c26069d6bff198463ed06215fe084ce5b62d9f63ac8af8cad41881718d330bd671ec5b176b20bec690699639ed2e2a13174f88d21ece8813208e102771b7bb3c7923a7f34e1581be3c9d071e3fd868e1e377aa0e34c0c42b6c0678e5def296830313cc4d0a1838cb5b5102d70edb14b869527070db21092053e9a98384a85924184a8c1bbc9bc33fda1d46e3e0d3e6bd5dadd43e751278008c102e7f1a4b54e31c90db343c815f82cca24d1ee55b229b51a42acc0a9abc8e83faaead4db5f84a0c1991c356fe878928b902ab0e39765aa3a8a240839c3d14970cd6baa84721042053e65cd6a952799ce497e45052153e054c537192bfd52602f45ebd726e9fc93941c42a260da1a4d197fefcd43844081d1279812fb5fe3c7bcae608d90277092e41e846f27f93b495ac147181f25208347951027b05d9be99eb34afdd9e57c10d204b68465ce499b4e62fc0e131859522fc91fd525b077fb9a2e7bdc1c6a33d833215b2c3c9f9862651711a2047693b7792e49661dddf808e3c3043d4e19680c13fc8e32788cc12624097cccf9b4e8a68d17df1482044effc4ab60fba627090583b1118fed9da9272d0718acb97b523f2a9eee925f707135f75234e30b46880a4229d1682f38a1f2657526495e70b3e05347884942895184e5b2e0939ad0d962792cd84a494ea73b2c080b4edc36bd825351df354925573026896b2a5bac35df0adea4ca9235e8a6d03e2bd8af987bc45d057b49126d73c492b4bc2ab81c69e3fd76ada25470a2ae7a922f4305a3842ed962da4fc1066582905fd929a98f29d8be36296a4c6939e69482efdf72f75cf2847948c1da9f24a764957bcb330ab6aeee7e647f76eea260b4a411e223bbf4d3a1e0ecda84890d0a4eac14969be927359f6043473fc51c6476497b820f259554c2723d844c2758bf68399b1c53f8ca0976d5549f96923f98c92638595a543da535c18f169944c63513ac9648bdec2607d1292658d392f5f45c4fcef4126c757e49c13627edd312ac29d14ebeb236796725f84abfca19ec547749097e4d6db2ae72126cbd4979f27fa54992042374a9e59f1cd31a09ce3289a6d7249ef221c169ae7e06111fc1a5edc926858ee0b582ae92a3c757af6ec4e9639adc752746f097a4c96d8269116c062b258dce310fbd2238395e6bd0a0edb3f58960f386490d11c1280b1d4a7c1d611674084e379994173a86603b75d36350217837cd27bf643b39c609c16a8be8e07b3997d020384ba164a66c19b22308563dc74c09cb9c258160e45ea709bf6492ac01c19e982429eaa14693fc8153914155a9891fb8b57f31d5fbc0fde853826995e0f7f281133dc7cc9f599398ec81f35d4dcf5eb93a7ae02f44a69990264acb3c70ba3a5ff7a74e5dc2035f415f129de48b6a7207f63cadf607d10edc09d9a17fc33af0c1d275d2dc39797b7460f3dba99dcacd81f5749564bff616ebe4c0c9f9b3a74cd3577e1c3877dd649b299d8f0a1cf8cdd831097a79031be4d9075522ee5b7103ebd76979f465a86d6d60fcfda41b99b18135c9439a9c042bd954660dec995c52033f26c95cc99306b662a5b2bc20e3ed686073d29dc4edef5efc33b061a797a4ada462c60c5cebf589769fbf1b2a03eb1a77ef4acccd9c0c9c5a5b6aad4b828919031b3f6b786609aa248f18780b3aeafba59274260c9c14b324cbed5937eb606063e78aa1c4eb0b32bd06bbdb673b965465e90b7c4e615a974fe9aebdc0094f95b4eb6777922eb031e4e86cfa5316950b7cea943665f5122b66b6c0ad85951cf45ab034369085b2013518edf9df7aa469b0fe79a3dae53325a358604f4e69d208992b704a95daf793a38a9e56e0529749df6a69949768f0ae632969933a5606abc0584a16acc32c28153c83f3d49e4c4a36dafd2554e0bcdb6b3feff59494640a6c8ec9c44605954f6d891438afdab713e2af39954481fb31b5312fae694d2550e03aa66092909a314f2a7902233f28bb98ad36582a7102a7475a3acb6902a74d4a928612967286095c7f6f12ea256ebe04eeabf4e54ecab6ca64067fc23309d5cad1bb12f85079a2728e08ad49022f329ad8614ad34f3680042e9a26b1fde482c17596a815e927880c30d8939a31e5f8a55fd12f1293a399a43fc7176c86f0a05f737ac169302928995517eae1051b2b6f4966b235c877c1a9d790594c5b4ae2ae0b46de7d2a957a2eb820af83ac125775745c704ab2982ea99099d4be05279644f7f4b72db8e47d524cb22fbac8d4826fd3aa5049acd0132d389117dca4f42cf80a3ae496892cb8984eca9d25a93a29492c5813aab67a3c58709b157437449bf8fa0abe242958746f4db193ae604377765d2c5bc1c54a3a9fd011f33cb28293630819f349a1dfe32a380d2a6626dd90297daae0d3862e6d4df3de5c2ab82ab9af26ffe9c8145430969a3da9ef148c0cbe31a594a4f698820faf247dec0a2a67a5149c7bf4cbd977f3049182d5dc189644efa05d1b05ab1f541c253a3f96a428b898e4b42685148582cd62328d8e83824d252d5bdc7d73f5139c1415152a544d096b3dc1fbdd66f3a0f4853c75e2db143dc33ccf094e0a158410d2df041bbd937e2ea9c1ced7049b6eb2a651efb14a28139c5bbd8aae933c5b1026384d292a468d95b2722ec1d8afa94e1b7a92752cc109a2eba2f4c8cf9957823bb5eedebd166dd494e0d2995d1433599ed393e0face4dae2c42e9182309f6eed269d226891b6322c156fedd58396e7a3e8104df764265f29247f0a6e498f43984769e38824b52b0a0d72bff539246b059ede946a95af22c2318353166567117c1a75cb931d99b6a5e15c166b7ba8b4ea2e3c9447029c7944dc955755d2282b7bb3515423c771a0fc15d0637f5dd9a4b0e0dc15e59a6fbe4a3f78285e0823eb1d4765d55f608c16551528c7f2a83e084d06fda84b66db40882cb933ea7ad52322c16084e965c92346a1a475a0a086e54d079d22cfd03975d3a772f46bdacd40f7c745535419918c592fac009ffb41d13f1814b4ad05f65aaea949c3df01635a5796eea981c3db02988f41332074da13cb01dfaa46793e424573c70fe224f948ed237de81bf54d2f7c44bd15cdb812d497d7dae94dca4ba0e8c6cd76fcd2769532774e0376e52c96c3407d63ba59cf2bbad9d560e7c5493fcf53a4853d938f0f1934a42af8bbfb670e0620ca53d5b2c31eafa0646af7f96249709c20781105a0543e85146050db8812d3b4fa21a63d6a4b681d31f4c836d4ecd2436b06b4a7a8d4c3ac67a0d8c0559494932a8063ecc3da9e0b934302629b1c404ad277d870646ecab3f6de50c5cf25c497e332994ccc09beeb49d4c37ed6f65602d5cab527c2d6fc9e0083b95d225c7c0470b2fc5c06dc9ec4ea71406deff32b774090c6c9f6027d7e8daacafc19a6bd226bf674fb2ff02b76a164dafe3057efd46499b67171821479ee74b311f11173859adef3ce88565ce16b8ac24499289eace25470b9c524b0f154a28ad9d2c30a2fb3928715783935dd3823a937485d2e05392b3e5acd6621a2cf0a7e3be9ddf57e0af46847e92f2a7b1adc07db0523ad768301eef63ae13e429a1a9029bb13ac52b515539c9196cd08d9594b6a766091558d5939902175764954aab6b72540a7c9f6a6bf6683e4919854cd5a6b8ee50e0b485d2eb1f747f4a3e81112543e9e0e21ef3884ee02e9d2ef13cf9773ba6095c287d9efa64ce792670596d45d34b492a69096c97eec6f0fe769119acdb8927c6246a56764ae093e4b5b9b449a59624304a8e3165d2184d4e150d20810f3a6df4495b303825698eeef5a994944260f099b39a6ad3f7d1fe829157f94bbc245ff05a3ad5e4f4824db74f952b48b79a179ca443dad788329d5d70ea84d21f425badf8bae08452352a688ea227940bae73b865961c5cf02645db6bebb7e064d478766da649a76dc1588ea75a70f13e98a756bfb40d2d38695d5f54a94c919959f0a77cfcf7960567a2376eac12e29624169c0965556ba19d1d587041287194f59fa0f17d059772941c3c6dacded4158cbec92789ba15fca5f8ad67252b3815352d4de83c9a5e05f74198f613458979e2bf830ca882cb596a5667dec1c354b0d1e47c53415430da46ef8252aff1524ec1c9dd247ce376a6e0ebeb4f32c9cf748c5d29d890596b74b7755776a4605bc55b7454302556370afed447bb0921445475a230c968d27e05a550f0b92d2b94decd577950f0a93f448d6aceb7a34f3096516ccfd553edc813ace5ab513a054f721075224bc97438c19aae98259fee7936c15fd4ea50194d3255135c554c1a54496d93f24c3026a5ea31192abb8d09c63a757916fd16847d093e5436653ad2e4785b825396d5ecd394e69b54825dd3cab4515182cf496b29299a042764776ebd25c128ebfd1a158d0417937c27a64b4830aa942428e149d0dfe323d898c4046960a3a55a292906a55a32468d0ea08153ba753736f61fea0de363c7bf20251ddb860e9c812f79ca24abeb4aea5f0e3330264564f29893a0ee6afd8801093a5006ce64055fdfb3cc1a94628851462aa66174800cec491d470925946eba14111d180397a74c2a9984122afa17031b73f6d589d067232f85e84018d8182d93a8563a4fbaa3078f1be8c9e8c323b11dcfe33cd00130b09fa35ad2a0496bb049e9a6c917477bb3e90b6cc6b42707e17b81913a76e2199a4dfcbac0daf656561471812de1ae963556c88ffd1638b1d5c4b175911638295a5443eb270b7edc9223aa1abc2851cd1b94e82978270d4e09eababdf15dd4c8b1c07b7a3ed97a474f3eb9021f5356c50c2fe51bb5026bb57e992d2d07ada0c149c173e6a06478ec5481f5ff3c194c0caa2deb33f8922342e6c91bd13154e02d594ac2627afb8b53e0539a32cf5816427952e0e4f4ce7f9208556b3151e074084f29a524739f2428f049e4a9c5759fc04951923a3dfa76c49238813dab9c0499208c1d7ce840137853b32f7dd695f46602ebda16b5da257072edf22953ea4ee8bfd88e3d74c00c33a5104de9424ae064ba9ca2e88c7b95d50e24814d3ea221345499386a0790c0a6cd4bf9319ac160fd4776141d30b85172f626215e9205fd829167f7a1349a9649d3176ce51c3af999b6ec9d5eb049a63a2965ed9a9c435e703a7ac8a4547e3779df0563c193e89719e48af274c125d5d49c718427d15472c1ad97fc16939be77d71c128d51dd4f2abaf5fec16acc5cb8b992ed8c9235b70a94dadc6df324929550b6ec5ea3de98aa753cca1059f974bfc93f6528a419f051ff452d03456ad9ed3b260f772ed4951e9e4d8492c182578ecbf689af6dc830523a39fd4b2b0bc828d9a3975499224baab36e20a5ec3f5437b641ed9b1b246186905573a5a0ef14cb382d54a1bf521ff63bacec82ab83139894e62e9bc2638a20a4ed031e6b62463a9e05b3559b6145554f0316f163dea4b497f3a051f73d49e1cfac953923505b7db49ad5f2a75425d0a4e92fbf45a5a4c52754e0a5e8310a272f4935170aa69e4888d44c1e6d89eda3c7f062b43c1a9f0204b9b6eaa7317148cbb9baebc1884cefc3ec16693ca4d10d2a386553cc1650a269394b6914e704a75ad7a12954db46c84135c3e937641fec7cbde4636c107a5bc82ed6ffecf8dc78826381d3ba67cab3927294b99e047ab255152b08c6082bbead11a533baa85914bb0716b545f2769a9a764c4127c27b17cf376d509eb2ac15beda93b59a341a8a4123cd2b1021b366cd8f81c2394602c45959cc40e117298d9e7d8d1c38c4c024724812391c01148e0c82370c41138d2081c61048e2c024714812389c01144e0c82170c4103852081c21048e0c024704812381c01140e0c81f70c40f38d2071ce1038eec0147f4802379c0113ce0c81d70c40e3852071ca1038ecc0147e4802371c01138e0c81b70c40d5cee9c64526d4238d66030d206ded389f28a99c2b136c2061c59038ea80147d2802368c0308c9c0147ccc027b128fa72929132304a8f12e3a606a955eb8b60840c6c995c32fde87a2f6d3f303206f6738b92513bc7de2431f0b12e2d2935377f531818cb9eebb3256bef1218f8adabce5e7abbb65f8391164f326db29dd4d11738b595b2427a3cad212ff0695c43553615f7425d60d386dc785d57d174b8c0be49499ddeb7c09bbceab1e4581b2c5a607f4b4e1f8df93775b2c0fd67d2e655a1e48e1aece756be94771a7cd0abfade3416b812a5769631ad273157e0456e56e0ea548eac548206a75f3d96e454810fa117dae4c954626770a249295bafa502db4999c6249f0227fd6d6d6e1e999a4a815f8bd7f6251905d642c7465a100a7ce952b267d01358ffec5a32e69cc0dae9f18b254d6053b0d8c9466ef7e598c08fd0e65951a4ffa72c816dcd7984fe9646cce0b63208e5a34bbc636944097c456f4f7e39491daf3492043634e6946a3ad5e42a8d208191b1463cc96425792818dcfbb78bed959f0a02065f4a37b7f342a9e8f905272dc8bc0d6edacde30b56fb828d364f2fd8536ba6d3e3df5a0e2ff8bebcfa6d5de1baef824b4abcfc9ec7357fae0b46bd5f8afcca9ff9ce05bf396ab40cdf24268d0bce3df66f4c52ad49fb16ac8923f4968e6f1bb3b6e06e5b949d6e6bc14517a5520c6dc17a5a7052898cd6254de4c92c18cf3726cb4a5970720a91a744180bc637f3983a1f167c5d0ad3fbb5f134f8af60f44e37c520f43683ef0ade734e5ba973b274cbb7825f513fe92959cc933d2bca2a75b3fceb57c14992204ab359c9d9d7ab827b139390395e17b429155ca74ca9e7234d7909159cdc270921ccd6a3964ec17a8ce934c9f132eb6f0a3eda077571e37f28f952f029e71a115a52b02628ff1661f904ef47c15886afe96a8a51170527646d4cca3af5d450b0aa59bfe28f8e8d08148c65ca693de59c5dfc046f253c0725a924878a275813efe486ce71dd4e27b892d57ad717723f9ce04f6e4d7ba6fd5eb309c62fea5f9e8abe37a57ec4800432f888410a3e78f4ef38c6101cd0449bf2e4a0a567821b913d9643c704bff93af52729e9757e093e2dab583e398af56d093ec42b67dd5e0976ed2e8e5ad87889127cb6ff4cd35f95e266125ce9f7586961279846125cbe53ee69349160f4a2b5c8924b734f20c15bc870db24e51cafe411fc7a9a523dad23f8a45a3e4288f43b6d23d8183bd5626a19c197588c17da728668115c294f6a66412c88aa0856b3966ccb25821364df9a922522b89464ffd8bd9ffbca4330269f0a512565999586e0c3cd32f4a7106cd6ec13bf3ec68a1282ebce2c7d5b724a171c041747687752959bbe20b8be1894b07820785d134d610282bf132147dba4a0e4ee0fece69c7e6355a1b6f3037f7a6a4afa4b1f58ed124dc91363975d50aa9e5e7490963df0963a5baeb09ce9eb81310dea9d3f79e0be468b8a9644f36d78e0e424b62539966c3ac6d01df86f53926ef7f18b1ab2039fb29f87e678c94c4375e0e27f88e8c02979aa2da39b4a953407fe2fa8a43beb63902539b01b376d2629dc4cff71e04e8c2338b0161e4c14bbcc96436f604fcebd126b64b9e9b881cf1a63bfeb06a9a6d3062ee653b2f7e8aa0e3a6ce0be369dc8faac815d7fef3f0d266c3b6ae063d42cfaa4f230514f0363e28f52258892a2316860e4c9e4267fec16d59c81f1924cccc0ab7ba9775353e16d1938254b4d0646254b621231c7c0a5ea52295de7a0741403a793d0fdf73c428f18063e37fd08edfc7e213070265df4247a6b25736bb099d762922cc912d3fb026331d967dd5b2cb13a5e6037c58e7fed79a2d5e902ef6d7b2796121ae45ce093b89b9c92aa2448b7c0985cbb9559435f3469818f5d61a562fa4c5bca02179316cd6d492e31e5d5e0d5ce2ea85f7768280dfe3b85bc134a33c60f1638f1d624edcaafc02659cca275fa49635b810f9eebbfc54683d78bd994a79827afabc0d5589f597bfdfb67309a5799a53996b4a102a79d6d41054bf79a29b026a63f9db99da2440a8c8ea2b6cabb545f130546c998f14daf759a060afc874e1fc77254d2cc13d85c52ec587ee2044e4b90953364de92264d604c9a6bbd9fdc6e2f13f8f1a0626d6a97c0df8895d60d93c15433b8cfa1258a3a6195a24ae0fcbf2ef50559dae64012f89c243dbe96bbe40d0790c0c8ac37599294547c83c165517bda1b164a99c0e0f25e9f300b3a6b98bf604fab294178aba7205fb0278f4e4ad6b1177c1293731e9399d7455ef06997e3bbb95db09e5572fed26f93e474c1c724b5a41013deefe582dbd0984345798cf9820b2e67ae4927536ec19e998ca7dd3e6e6f0b467885d46892dc36b15ab099740821ff44e7ce68c1a6730da13be5f3788ba2a804cd854204a25828108943e240000c8a6f0b00531508301848280cc4811c86d24411761480024a1e2036282216241e10102c140e120c8541613028100603026140200c0685c2c140496bcad604ca512105ba8c75b2cb4ba7aa9113c3e5a4ac2e278514a93ee58e7344760988dca5cc6894f2abc16d32d22889de86b08a6d2aa8796f1b72e6383163c3ada86ab5a25dbba25e71bf7c174d31193a2b6048166d5fbcb393055e7cc766d316fe881992a85bf3de4ccff0f7c2655b0a7d47fed1de1b79e4c8a8b20673928180a52f67ef284a277b269972dd7b99d1ab72c79cb0e46c3609fc7a1bb3e35b0aed60c0307e291ca5963fa4d6b0a12463b0b34235505204add079a04a3f6b52ec5a91bbcdb84c1deb9421e6b1186a509401d9126dfe4ef1cdbb8f47bcdca5a887d4eefa789daf62c8a6a689d6afab4dd5599a8c57c62a5c14125419d69e2a6d90320a151869cbe9d0fbc8482ccb0988602af4593cb6cbe2f752bedd1e03a2233e8f259a96796980d505248cc1bb8cb8c3cad8d14d2c25232acd14722af6d1b7acc42719486c70b9816626987acf5d2d372fa695ee3e5d856fe1e3ee5d55ec9c27302b40e335901b859aa78aca8829db8ceaaaa9937a293daf0289624f8dabe5a5b7a98c990e9d6451cc33762766885d7e19e18a00054e3c46b0c62b104637584a10e303d14b42ba4638d052e1bf1f4598648c838a7581f41745dbdd0fafdcc7bcc866d4b1439121969976d9e5e1d5288cb9be600acb709dda641d97310f18e0a03ab893d86aa122bf0c41cb193b6fa4832ca3b12564357532246323df18978d4d8e3da0e0a19c970ac48204c53bd89998c29733b25800dae29d0f5469252cad51dba20825d33a1445a7857b1fe5547563868280d3650bdcef38802ce40b8c54d05e611d1e8fbef3f416d8709de12a225661da8ff6d082d064fcefa37ceb5fbbfacfb2172caa6c24594b3d6c2bc09bb86255c6a306c0e2055c04c8780df11a09c8e3074bc0ed80e5efea4255b36adbd52e9fce5d21de86d4893b0bc6c6427bc9da1edfddb3293cf7d56aa52e280eeb48177e262e502c9bd9acfdbc50f66e69e04359c2e4662b92a16279d7729664901cce025338813e3ea5e781a53b3ada8126c451a895417e83aa7774d241f734d30ee2b1b8cf8baa211382accdf1b066276af9390c00bfa0efc6367b1bdde8a2c3d04bf2a97668cff167f007beca651ee6e8539f02c2448c41fbed0a19d122e8468b04b47e55d5debd6e7dd22101b188f8667c1500a8f1d9dea75e0357963d52aeee02939d38b8a2aaa900d9c415a603be20c5af1eb0aaf02d9d2701b150fe7287972be7cac34b3336f3138bd13d75d0cba5272182219aa1ab1d377e031ae840df88f383f13bcc825d67ee57768a36c1d5753508c7eb7770a7c526e05554ac5935552334480dec9968486d0bebaedbfa6bf7713962cf3fee3e820177bc8307eef88189f08a0def94b6bf45b9155c1a791f90f21a8b45309a86731f262e84d475b641fdd4d1b2ff446a254c3d5faaafa4226227d60686c297111f2e23086d7d2329c8d1595e99b6778ef7d6c453ed2e1c3bafe5bce0f9d9ebda6a83e625b9bc3a2f8c7db48de77cfc55e2e0a2a16ee8938533aea8abeb8ff3272a568be5e6d7d0d5a353da90ace7d1d88443d6ef4d405e025c5901e49547b2435f0d455e0f28dcf34bef52a2f0c8b60c9f2e12dc3b6ab30d4638051006e6ef944502d2f64731aebe35905dd214d907006d26b1f7d0854e02771e35c9104f6a03cd36ddda8e37ad72a724d5a2566eb601bd76c47df2dc7c0f071e9b32ddaeabdafd1590c6fa6755a74693974e2f71ed4837ccf39036b94387daf1e565dad9650b76b97c52097cf1bb1e7e972be8cb4ad7ce61c43fbe71ce731ae936e33cd03e4545f5a787d04b60541f4ddbb8830c776ec39fed66fef7a7f96c5b28e9d8f012d0fd5e4d6e5597dad6fc6eecbdf124b6f9a5399ce181d9932fe03d8232a5f7474576593e6c9f0874ca9c4f1bf1983018f9a4e1fc430a8d223c9e8be02bc8813555b483b872688c34aea39defbaf3bd44f9bd0bc3bbd9ebc7b704176f20ae8806ee6dd27ebf7a4d2a54ffdb68416ff4807b09d89d36188fe0f00706fc0a358e8a53d02720a76d1a25166c15ddc42f88599d0fd9ea30e8a8d6c4a7cdd4ea14fc945d197b9aed877b0721803dd8fd63f6ddc01d3fb0117e451b79759ec8413c54dfc4f90133e64d1f0ed6f0627805cc817615c027c091278ddc8ff21211fbacde753a1b7f62e73ffdb7e669b374c97c723be0261843a1d5520972434fe82520b547aa03c40db9db5fc0c53330c38d4ff0e17b9db19beb7c73af2f0957205342b8f2a0af83b35426e9424515f9c3ec77fe80919921bd96ea5ec6a75f6a97026faf751f67d957bf9aea577e2850d92949cbfaa981b541886884cf7b470ef620e0c1edbc58bb0201e8c4b87e74bb2252166b3fc84b032626d8ee88596f519cd7e6573e8ec6db469cbfd8f531d9133bc22b7b5721225e3fbdc16ce8ce75bd38bf6fdb0cd588ae0d7e873393cc9c46bbddf26e3408f43bd3c31e37f7a70c36ebffa00784ab40ff2cf6a84b74af530ae2dadcdb1baec8334bb4efeaed9efb628ca1efbbd0474b74d08c66b4ac7bbd75e0ee25394b4ee31b6f423fc29e14be7f1ad7f3965bbe1f5d3440bfa0975e1ee435d74847b1bb376ff2ec86606b762b2a970b6dafbab90675c5a08e38fbc94e77d8f6c9911cc5a92b3a3fd7b926c68a804531b090b81bd208ca8acb6816b67cb49d55acdc8656148f91c8c28f8a8ea84c7f4d7ed3738f2d66183c3b0a7b45204d81f4d6a7026cef70d6eaf3525226d73b5faf1f04fce1556ec6219deef10a339e63369f2e69abd2f394601372be461c5c55967e6d73f5f6abeb29bb533ae9bd6aa536aded1fef7c980261af1c7135fc698f2862b5af959720311f00cd0dd45593eafcdb13b49f1c0909b48edbb07cb386e882d47ecd4be5f74e0966677f0213dfc6b732663a1bf14099f92a48235caf913b290e96119640a62e3e6c748db90218ccc259119fe0005f8eee27713e60ca3529269348dc155de2eeb42bed0ec5abb8e9af36345734a4e2ee2baf7af09cc8dbb832ce7fb2b3e9a7bb427876d42a05b4e150a16efa4f775a056c7cfaf42f21addd08dd793e1275d234d71d1dd511da09029d3ce39bebb0e6ba729e44be082ee738cc26851b38c0780663dfc6dd47bbab7d076ceabaaa46e36f71d157c8ec6ada2b5eb94abbf708fb9d68673bc2b78885cffed9a4e58ab1f6876da09764667af69d82c2153786572f3897756ef3aaa2402f4ba74bac3c69612f8e02a3818d6e6cf31ddb750797f3cebba5c427b26ebd42f3143481bd74e1f3080e3bd187fe202f511cb7fce0966ab54fe45995181ccbb4eda496fadb49431bcc5ee2c3a3f27360db16562f6c412b6a6f865458829c62b55581caa0aadad667c3bdfcfa26a2559d92ef5687c66d60d3ddcaf7f77b059f36392f7c97068bf33b034c00d6ff2e223e25cac309c1d3f5bcae355b3502c0dd8057749e9910c47dda0dd46d4a64bfb970675aefaaf9fd8607debb2a07843b0043e13957937276062773a4f33d95dd9d04214e76e86f10078dec06c22bcac446e82d2e36d4f5d3f373a437db3fc2569648e0afe2aa2e3ad21dcadf200f870eaefd6d42f8ec4fc2e3db076f2815033d754477799b4101c7c8e74241b02439f1f9247625a0636e8aaf8e582e8c494f0c5b145639d61556c95ce71ae93aa2af4971f6f6e2f33529e75c7fc201e27093fe51fe9c8cd23875213e4f381d485e0f737295a9a0930be6d62f87c2f36649fee5592553c0ccf7b6ca08cdb30bf8137f629b616db1c25ad97baa0bf809d008cf56534ee32a623d57b907694ec52867ca2bf2d04475a6d6ce838ee8e3b9a664c444a4663a312ccd576949027ed6f46f6f91c247837a011f8d0262a6439cd1ef6616650eeeaf690a90a1840122a90cfe57f52e116bf9452823caa5c8aa4c4c09de1151f7b11768f9942c0706c783036994e191bb0445098ff4fee4ec25bcf909e5a794808c0859609120a98f21206703ed85643c2ebeaf6085295f600abe38c0c5cad2b83383e373677455039e94fe3f7dbf7286cf898f01ef8d7db02024b50b796255db69fb74ac2f1021270edf54c2875c68a3c9b7ce31466d6591c1e267c4650dbebb79c1be4b4102109725f77c1e21e45880b8c566e428018d9c727d84001cd563d1bffbfd26e36fed33014fa8547609566fc5e0d3f640542af9de85938019442f8e4c7c5d15b9b4a4736f2d79f6c7325acaa5ea937d7d80d51a8f2c1693c9c1fb2702e2f06c1956228468f0301611f8fde92d5c049b4d4679af78f9bf1de0f2a42f8e0140fc9b1b347d2afe0cbb482c70cbfc166d21f6d7b6094c251fdbb13f87765ca0651d80497f0df0a6f6e734c1c17e1651cffe9c14c464007c1410c019f0632138a0de32b9e435f20f4fb6f4e26fdbe52ab1ecc8ce389d673f93cafcd10573a72b06dd85e1ce572022501a01767e01607c43d108c50d8a282c8ea451dcbe149f2659f2431942b1c178c3911b7a72a8b6db28cbb4a3c45e7ba356e9315875d12426160c901de98f85bedf4bf1f90b783cec994c17a82cc90d9bc55e8d95e75fcd5c238d88ca26d40abd4c444a747684609a04fd6f038374ea4bb54795601a32db0753ea22bfa9b703923b12098866809200f45cbeafba81cbbeab094b0dd4fd752d6c9fc6b30f2d8593890bcacd869ebde5c58dadd45729fbf5b53b8f63f25d0c2d8a8244e02eb49a7ff60ad76a3c4f5bcbcf1f2519eb2aea4ee4fd57f2eb4cff5813ee37fe5090c84a28cb9594b4eef86785bffdfe6fde2f22409b5a7b6ec3cae677177a493e5cdc6dfdb28a7912f7c4f5f43747485d42ee80e404fa98757a2c31d77bfc252289b0e6cabbd5b00f193669b5b30017393702dcc5c005c493c81a2639824b4a5521b88b610d9209c6c664428186343dde7f585a4211d139405e66f2faec93f2d7387724c886801f547e3a0f831943f2189d062d46458938b391ff99fd52a63ca3dbf59f9838c10b0beafe1af8e3ef2fca631ae52e2c39731ae5d45ec8ae47742d00fd3c06b7e02faa975513e1b48c275fe80c0cdb32bd66e2d40a5938ccf276bc8b7ecf2e4b6d53e740858e94478091922f6e72a5c686b2caaa4c44ee505d43833a3f192f6e8e56e53f735e07fa6cfffc9b92db2b67819446b5a143ba1d435b021fea660336f9bbf06063ce4402e180823f8231de31c17a5936b529d3ed8424ded588aa6781e03aa2993e346f344036429ca5a34bae17b60a599e3d68004e63d18fb118ae17af7558fd4cb66caf73f6d3d53ee93c383846c2c27924a2fd1352560782b9f551b292a86196eb2cb869997fe3c38bd7662a89e44c02ef054d35d51e1a8fa7d8aaac0dc53963ebd6f2efbdcff43734615007821cf6da1dc79c6d7b7bdda9c038a49e9c80a445915e0731c14a853300995d9253750415c751abaa97afbf278a76c89ab2fe6b6ac2160e52e473316e98928a375696d5a5be39a35bbd123152921fc18647fe3c8f295992b887280f955b024884417077e534627fe6e1e231c90dc8bdcf2912325bf5360c23bb07418de1a24e82b2e3aa202cc449aa25a5b28eaedc4a2611e8a610493d53968b5ba9b4432732ec03943f01d043c59ad695396e102953634aac7587b2ff9081a26d1557e9fd069ab2068de9d81bde909ea4f8606217d9e619a2b1371742acfa08fad8dc15880ac38b5c71b4ca917011550ece387341aba053e8d1329e8e0bc8902b7b2e54390652cdce321738de2f560df921b72ef77bb4db7a4f5a089e2e4e945e2bf226be8629120807fbda012ba1ce46190af9e14e7f389848d749d64000d651efa0981d6232ea41036db5d5932e8c1698d6c60876e79cfe8fbfa07104e5ab0f504d02505fc46e704a6bd195a5e24cdbcc87e23b48e0dae3b7048a7eda48b7835fb6ae32d1e2922483ee83d5cb8805d91f2ae7cad77b0849b4430efc45a4e2103e46c21db726893c67c80f100d9c59a4a23adab2d451fc07f52a07e5369821c1e0f9112e50025346565140442bf964b828c73706d8c4c269136c222f736f59270e0587f2d2ea4248c3e4bef423c5f49fef9b4b6461d72bec2ff8461557958fb646f5e1a862573b57b4f1a66d3835fa01820135d01f0ec54cfe86864208509a601dff72a7a7d4096ca09a282b45a1b6ec3e64ffc636ea563c4252481382b352b50c574ed836820212714776191263418515124d91e9bd1a3a06651d5da70586fac369f355c442bc66ed585046a1f2455f7c32060e8adec92dc57f0a913e3756d4aa40940aa994dd8dd8d3d3bf108477053e0b8f5385c85c6a69b68531a6e24b09eb4f8e03851debb5e500958300182d00a3b184e02b5b5047c37111a4c343bbfbbd961293273ce91b233f1c98e263be540bfca945ddc8d90e5d163d0c0532c6bab95da84b2c902260c66c7a1a837e0186b5648e27b4abe0812f8eac31ee475f54da9c7d25bd374139f76219a51ea96ba9c4249e134f049234d9c3cbbf4e7ab23118a9032893a19e9e8abde640f9478faca9dad8743e52791ce1fb0e1b7330cef2305df6c20d9979b72d921b03880ca222c6b07f6b4e7feac675e36d2b3bde81329b047c7f762332bcd5f79a031c6431480492bcc278d21eb7dc9d4c4e2183943b670eaa68010444fc72f73be68a5dc7323ba70324e5314cf430825bc979a5c97faf538193a6c412626ec887db1a2cfb6deb826989a7e9ba79c9198d2844a0a4336f64d5c6bbbd8151ee96c49b4f4737beeda03891c293638c0eb1fc4010665ac41e904160f96acc2e0428e296da019c0611b76321b14082278725984ba8c44678f415d25bd78284aab2744cbef08835470e450f610176a09b64414194010c2d504394eef178079b55d95dc38007d2bf2652b872f09fe95492663227908fbe3cc30ab434ed9605eba7f3287686b443815d8a97e47d90407a0653fcdf2cf1ba3ac2ac124532dbfe2ee1ad8509c306d30f704856ab98176872146478d2d12bb14d3bf700d2076c11c60ee5c75e06f0a36b8019609c263a60f5e4ee431c367845302238eaa5ca4ebbae939e69c8f8977cf3c33235838fc0b0b6e76c4ee06392fc92a37e017cfe0e82c3ad75fc017a00a133fd498cc6f438cd9fe709702005db89fa86be2843596a73c9c34ed7a3a4c109d285dfb3c55fd9dfea2e3217259696c132e0edc38faca30a1c9c96a11ef98d7db8ecf544a195b576c1b458d36a562c1b89825e4db9d7724414f9dcee5a95e93e0e04b6642954fc828ac70f0f12d03ba0098945d157126392b500a30e8664b7c246064ccaf980244d32249b225424a536abc8613b4c59a1ff4c2a2218333a698f2305a28ca4c6d8e282484edad0324da100c8893ba5ea3f651d6e34d26acb4d04360f46e33aa5a33cbf1ee344410eea90e8311e4d5a55b46c41395118b8129e8ab50f67e95b6fb20c3f6b6a9830062b6018e9fa568690825853545c6ed55c0c7b4b711f0935626b6a56f0ed7d6da2503bc48f48ae9cdea96b0bf2ea4dfc1156d12a6748e6d70a9b80bc08c2a964c8837c7ee273aead1e2dc6c944e8c8a26a4e2fa5f66b40c20bdaa284a3698719e48883c2ca9dcd8011f562b18d868fd0542560385013d4602fd35ee9fd034d4c6d7e50864bbeabe6077ca6faca6cf12280dac99857d4e643aa9acd583ef409b1e62c8c7514d8f6d1d6607f972940abf7f240e23be2194c1b1377e293cbccf36031385df8b89c2542494cf5eee004aae8a269d91f39a1f82b5513715bf58a71d78fb88ae04f687dbf5136f06497f9fd5179617fca550188ea863219ad36f501e9a65640b5881b586381631c83df6c516de14351c8e0680fa446105c780f509bc4075d7d419543072c9808cd20052f5c3acfceb9900f16e3f13632e7f3a592820f1d6422be988e6676bad998bfc8f2542587ef2532172f654e8001a96b950c12ab1b8f2c8095829dcc4ba3f59ed6e93d4b6535106225736e1610b85dda3492e6848eb5f9b5c012894be5fb02db47b8442e8174571588f8c481ce8425a5d50c18038595dd6731adeae5c46149db43af3d906b2858a735e2d23d72e7498e23f4e8b4f0578aa4ac38cb85c6f608818c107e5d9f3184c9077a839f260b5f8b7870e237a3621b507e00677f1158e45810a1ae4cb7e0e7c5c2513e9b83bd1ad9bb7f809a3f73e263ba3cc1ebf3cd357319485e2b5972512c9cafb111aa00d5c7e35ea9b535d0da5695b05e80ca0c80a035624e6c20d66ec9c410a8df77af3610405713115895d816d7940828d80604b4cc3c30f5a631ae3a47233873a304b4fe74b5710826806ad72ee514cac81aa881e96266a3c85b92d9c07c35a91f9bad4451e535e2ee1366d8cd2995760e8edfe1d53da7ef60d0b23e73716bc9eaea4134d55319b6a838345503c1237a5099c887051e1b43484bd0e1452bfd724feca8b5d07b16fa02648b19608260396fd6ac965578b6b8f10695346cba9187dd547ef4520925564fe14afd1620d9014482018b9c2c6cd18aff8bc563181da669ad245f14f150d63688c408388b4c1f87c5eb2b6d8404df7779197d41e6d62ea16acc7d810adac7127248042c461416ec8045af2133605afa6d0657735a723e59252a5ad712d38c208b52bc29e67905af246877ce0a98915f7392b5a146ab0cce7a032436e2a6ef8a4eee04e4ec473eb0a03b97cccf18b1ada6fc6c773d43131e807a76a9209721021c955ae9cde1620a2f2ad3aa91308e3417d0be02984c327dcce6b973654b0f2e1c452fa8a35395a1f99f4937463e5f2585e7a2919626d2d806f95e6e13ae05d2cb045919583f01983e4b4164883461f7d4c60c40b982fcf7787918c489fe6482f9308a90b3f288e200e98ea02b893639238ac4bc133366340ba6fdd976d220e52edb7060a51d46fd2c97ddb0b9da9becae3f39a325def4917651129095c88dcba0b6c43e4109e6cb1507ed1330bdcb5a24ae0262e189543629c42648bd91110fbe067995f298111ea6a8c054b1534397eba81a29f6a35ae66c5f250c875d3efe2015dc281b7adfdede88668b5a701c0b8cb44f122e5034fcd6db7c60c5f958d40a033b4d6e30551538db4c413998d395cf99dc28c26fbde8d15b17ffac113b0a295624f5af10098f08cff92d994bb36fc25f392ecd9608895d48d3e4deeeeb0fcf4cf832af6ab59bc45765631966c22a31036ba603af9cf1b46f90517109e85c778c4d4f7091b8ac1236be9c3496fd64fa01e33e77bee1def9a37e5a477b1bd5970a8b19077b11a4c234b51e90e91803abcd8881c98729aceed628950ebaaadd9dc45d5869125bed0d782a0ecb18962aa6a5f99d8a8e4b5834d436e09762f9ca0cfc0d10c27fbc230bbead8936b11031bd7cebad500ec150aca6a669d064cd24f62822c30a49dc9eec20c89c0d7a046e0eed4065eadc856ad89d0099701a4a705d52178968c11ea338a0e6f7792c7da3ab2566520737150f018a220ab610a0611df677638f9232b42154eb6851584a5eaf322b4f6264a57365790c8c4460f2c0c30265c2424985c18a6a37088a1be043f621221d68d5ea867c751e51dca7d433c1b7090d9630f9d2fe4dad6c197b1fbecb793166bfe182aab77082266d209b6e8761f118d245b8caf8e6a0f67d0d2a6d909c395ba4357ce72dee45f916ad5643f42f0e61045cbc2110fa8940712514d0fdd5c9511931df676aa43c633c28134f4fd0561774b91a38d4c1dee028c82abe302fb2135b14ae6f81658ba6e99c805b845134612333fed210573038efea36ff8960853130731f13327e105eb78d8e5c17c6cb0d8755c5e1d448de795d0d7b71e70527d2f6192b76fca2aee41ef09d47f3a1cc7a679efe0f38aa1a37cef561570e025fc415f34b16965dcfb92c36b5d7bed5f5b8315c373f6561f902a610736682d9c530f534043fbeaffcd560fc00a62b736ec239d9677123f1c7dd70c3ee8c5d6e0cf1f97370a7217c4abca93883cac75ff8efc7e60e6e2e0781db9e990783fa1430347666797396c30b132c268b462083846d03d7b79dc73cb22e18d9f5b4372337a3d8cfdaf3b001ef10d904d4dfc44e137562163d7007f78755ca10ce77e606f3177756769a183f09e85a543849ba1d0e1cd8c17f06b6e56acecf3dfb36d8723e3f5b4a193501d836c55cbe3952d9a76be75facbc8f4c12d313ac10c10d8b26554b8fd535ccb00f77a78a322cae3e59b178753a2b98870b44ed3e39457ba742a0ab01cf80c1bf692251d911e3166d3dd8ca70ac29f5519e8230464c34c446071ac16acdf4fd0c63e394c4b647e3105955bede09d996af911fcc17b1692bf0b7933dfc284e119ab6b41d25cffbb83621e7f197e1d29a38431174d6a16e7aa77782bae5bba03f61470a237030b5ffea6e411b8c0b549e9fb292ae157505c04dbbc6b1417459ae1b080e3e55a42eb046fd1973fc23d3b2000f915e656eeb68ba2cc22ab1d30c7b38911c7b3809ec32d1bdc74c65071cf2ba4abbd3b929590953ccaee9ec704a26466192d9e3c92ddb67c599551254cc947a88e03c263b41678967b7f6da4a2099942eb51225c4b844701c458d5e215614f1636cf080f22e8a3c2dd9d9e8f1fe4e05bb17232f33d683bb6bf553e4917e7eb4cba24bca45bc2856680b8bece81c50c9c0b5a00461c79e3e61cc8a46d74851b1eac6c9e2604b3e4a1c87a4e2cf8e3e42fc5149db0170362c72be959dbb40494501772de94f23e430f5410fc3022f69145a4caf567564e917e2dc782d0bec47edea99ce2bf44cbf2458bda0ab87e4a3acc269d4e6ab2f7a597194c1b260d3636ebb9540fb1ef1dc255948dc51aad418b0736529d53853ff32158a82ba200e6d975e6449477b5005249fdfd99940e405439a21f9e6561f01840e0649a19e313474a051409b904c5e77b8cc12a14987662ddb0b8e95b2e7b2747d2e76cc707a6ba11398388ccd30d5117053226db95c212c279d120c2ac650840b631abe4ead437c85dfe6045a6f692d377bca5385b2ba6434461e681451050702d3fc912c626fbd8dc5578d146ed438a1e08ba5538aabda5af70345f237951dd4f7c4dcdde4f7024e03766f7dd7a9bcce017ece8119f7b4a9f8dbed2d60a5d4e5181ddde0c56739bc5ccca3d78f1a4fee09f5b87a33a100dedc66dbe922795e39bd07e8da8762be11b0313e507f43988b3c5ffb8cf16da7f57ad955eb11f080b4ff31f2169f25d1efcdd67e02a91b1508c95e7127a36f245ab1d887e6194a10b2f967e587c874ce8e2fbe6e20bc86bed816e1b9b93bcdc8d7708b92641e8a3b8378c6521fd8fffd58c3cfa551dab73ffc7f04b9b9eb0cb77e5ff4e366de9317f7badcf82d1a7c56021e4244760a2e70b4940e000c30c000030c30c0000aa0a92e526ecccfd2fbb974b673535252921717c34ad6064ad6064ad6066c5d800aa40a610aac4a0c338fea3934c20b361443bc67cc69c57d3f5e434993448c98ce6a1e8e5a78a186425a8739244a565f75d2500c0d1c758ec778818652b769de104a3e74c42fce500671268e60d40b3394f1847bcc31e97c7450172fca50f230bb7ce8a92a7d4186b266d314c7d1b78fc5118c1a4321a6a379e70f53e08518ca042fc2504c123f596140042920dbc00b3014671e670c9f2d3156ff42d941c8cf79ef593eb517ca12a366d37be77c24bb50b84ed2fde94d2e14676bf671e6bef01bb750b2580bed0cd70b2d946ae76e32788e6953ce86175928bcc7d459a25ccc67140b65d049a56f6396861757286cd650e6dec8d3853d8005d4175e58a16c9a7f1983b4de8216380bba1330000c44e05e54a114d22519a5042b871b2a14fc2b436ac9ef148a217ad8cfa9c3536d2a8542838f517782a9e48a0cf0220ac5980e246734c88c3a14cae03a53cda5bc86fe84e2bbe3e0158fe1feed84c2c3f8d518378b66bb09450f53cd21cf6c43870985e020f5a3968701ce820a108000e58216b80848d0c30d6fe1c5120a293f5eccaf4a2863f079a2db41af9a4928e9a39f90d4adbb4a241427ee366a91bbbfee08e59fb1d0fb6c1f9a7a2314ce245a2eae2f42714343bc329678f810a164ed9b46d7338432d01c93533ade501e21942a22e2746d7dfd2608859cea7e9c5b525e0b8442da8dd1e04b434bc60f0a21e45c6515faa0e4936a734cdd23e37a5096c92a19943b9a889c07c5569f4ce3f01d689f41d74171a25bc3681119b426078524ae5932da17382837460f46a3245b7b8bc2e66710d3366c51b448aad3a1518b6206abd08f11af25b4288f770ca1d9fecabd5914662c2e3c87b4bfcba264bef9fe9eea5814e43392a6861a1685ea8f10cb61f0fcf62b4a579a2dd6c4537eed8a32dee8749e752bcaa1fa1c58e6ace9ddc38ab274d6556c74693fce2a4a51361993d551456163fac77c87f3189d8ab2de4a7f5e9667d6a8286c7a208fb3738a6206591b771ab9871853145743bccf38aa36d294a298fa5dd2fb542233a4288d6b5c472d9b5194f1cf67f8dabb8959238a1b230f07bdd15014345bc4cecc874f27280a21744d985744ede4270a31a273637cb5fca027ca2d8fb34bc34e141d7bce1cb363c6f8e344f1e3e3f8e0253cd79b28382aa9cba89eed68a2ae897127ae994c1442988c23958d899264e6497edfac3a5fa2f858ce1e74480d11b544e1e3c36815d61f9a56a21c2aad37f3665d9b9428987b87c5047518c449943c56ddcc71d00ca124ca923bf4c71c924fe422512e4dbf8fdcf7923d86441966776b94e7967df1238a6b71faf851ec88b243cfbf67961f33d38892dabcc4b4d2b1981951f0e85a8b075944394634dd28dd23f52aa2ec73a999e3bf8928874c7b8ded8eaf3582887208b13454fa872866101d86d590f69b1ba234c9d6a1a46cf7cb0b51ccd9d7632dd24b3f4b88c284f107b136a6d4780751869d7f8f23bb6a475610e5d2183fb5330251d6924dc910feed1c802877c8909bb234479e7f283c88d61856d717e2faa1341dc663e3db9890db3e14e29b64f42b9adfdef2a110e34d063656fb75ed1eca1173ece8da75d4b71ecae9d8ed1b8f86433b0fc5bb5bd973f81b8d838792b545a9e7983b946cebcef57625488c1dca69bcf3ad6ac41f4d1d0a41420a4fb96ac7613a147284df878ce7505ad1902cd2cfc46ce55086e96388a9524fafc6a11c312484d0713bae83436926f23b6a655d6b6f2848aedb2751871b4ad78e1a6d28ba7b83ecdfeda0aac186f2a7672cd12e33c3d0584329cd357dbe5089110d35947262ab3a7c2c82270da59ef4e06d5d4bf28c8672d8847ecd3843216446abf5e9f9cd50ee0fe39e717d878dcb509ed4b539a4cf9d2e2143f9adfd524b227ec68ea1547ae9ee1a561ba7622854844c1362668cf285a18ce5e34d77acfa1f0ca5741cc6c5b22f94543cbaab87d40b856c98ef53c52e943573b27e3b49f65c286cc5e7b488caaf780bc5fe20d18f5395b6430be50f2b131dd93aca9985724e1515314a668d392c14a35ab9e757cc392aaf50b8aacde91659a3a4ad50dc4f9d2a14a2fa4f67d84dd3182a94263767f4c5a96b3c8542f88346ebf35712ed097800042c208014fe89deb02fe328943673e286774c99170ae508cde01388909b69726a4e288d94865bf96e861736a1e4b85d3388d5cddc4c28ee9a4da3fe2ca1609aa993c6ac84c24673bd168fc11d2409e57f0c6ac3a4ce3b09128aa983b89dba47283f8e105232f617758d50ce0d1f634db9185d8b50f0fc20d339c3f3341e110ad1ad1e42218e85c95d5e7bbe855072d59ddb48104a9b6972c3395a3d0f100a111311923e8de7fd41c1f3fbc3cd6dc7d907c57998fb61983d288470190fca208e44fad46db877606c6fac521e1d145435e5afb41c143623e676840038287f6b6dc38ee9f6718b82d56e8dfff778670b8247fbf4ae7d2d8a9e22a7fed0d3a228936bb2cfe166edcca2f0f2199b7363183a238b32caf6380d9ada1a2416458da13d68e8f0d2202c4a2d91673d48f58a82838b1c37b62bcab81ce41063482b4ab1de9367ccbef3654531b5beefd345e89c5d4539fef36da7aa28b45da5ba4b7a87a6a28c3a22f7a7cde1930315c5f1dc33f3dc298a41d6f5ef334539d455ecd7d5a74c4b518e97d7f13669e41492a238394dc5476e1465fcf051c986e7bf8844c145280a3f1d9ff1e4b8c5d8a028c388ccb097af4ee3270a95d67d1bd6b13ee878a2b491961ecd2b5f67ee44b9f3d6fa63ec0bc7124e144dcb3d73bacc50b3bb8932ae8ed16198a73d493551c8eb967df4a1c6379928399ceba89b93ee6689897272fc59249b67dd8897288606f50e29ff111e678992494c8c22da05b8a84461dcd51b48d887879a0e5c50a20ce557353fda4ccfbf6ce06212a5b919cd1959756c3e06b08033702189c27ecc79e41f7b0a1240000280a0bec04524ca70d37c4b1c1d12e5f4793447b5e611e5920c69ff2482bb795c38a2dcb35fa1e16123caa82398c62c1b3acd6652e0821185981426d2afdd9a365c2ca218ad6f2a72a7ff7e89042e1451aecf3187ab89110217892883fbc76f9b3bb3f8c705220a1a26353b682879b93844d171b68d6e0da23d14706188c6c374be4da610859ce023212847d5f02eb62b5670318852c464bb7fd654f3c81b702188d2bb453d825149032e02518e321925a5c68e310e40941b47c823f1697bfef943217beb448ffc688e3d3f143bba3d6db22672e90208741718b03e9423ad9c7af8501bb8e043e9537f63d7d4501dee3dd00bb8d04311a0b8c8431987c91f21c6b48e63100fa5fa8679f2dae8838c7e81bf600577288efed9e666c8e083b4062eec507ed5b4c731731cc0451d0a39ac9eac6b6eccf800c172810b3a943d5568fc087f6d4773318792afe7b811f6ff315d2ee450465911f3845cc7a164a32351fec0cf4d8343313c083fb73e9b55e3084675918252010946d08241052ede50bccb3811b2de5d3ddc0d658b6ef71c6248c62fb96843e1ccbda7d6674349634c194387b4b7915f43a91a5ecedffab67ec5822e0840801170a186428cef161e1eeea25dd04517167880bba08b09d435176970354ee370bbb1118cc221708186c2b4d6b55a6896c0c519ca188787d7769ed2d3a6cc40f2060ec4c3b17bada416f7b4ecbfc90eb8284321328a48499f1bc12823437144ddb3764aa7c0c5184aef5ab129e3c68518ca115b3f46785c84a190e35ceca3f934da0c14b80043b135466ecfdc1862fa09109ec3db1499b124ce2a43f93c3a4f12c973310919ca62edb9ce35749a5a6b0ce5edcae811a266652831943c7c830fb1d2ec7f2319a83014f3f5276dff4e3de3058642dd07ef381e624aca2f14a3a5c32357a4b7e7bc509cba95903b2589631d0bd5859248d0fbed4e75aee6148a0b859ad7d5ffd89d7bbc2d9472f75553dc63cf505a286de34a471f54228b67c9505928b4656c1022255828e5e9edb4d548cca9b9c230b75bb48b07cd50562863243b0dcfc155a0c5e23c2b8336c6505428b4a598c4f0f2386b15829a42e1d37c908ca30715d1a4507089397f26f25d74d1c3865051288a5a4dd4ab5f78207011b00a40a002d64141a12caaabf95aca118040052878811939a827946eecf1abcc3882515783724269247dd8e884b2504d286f6cfed169cdf3f25231a10c25a4e6cd187e8e9dada82594a3440b1d7ffdf021798116b8c05b40fa504a2867b7eb7dce2bd391f0a19250de146b7a159d6bf5e5a19050725c951e9b2e02108000297014b880ea088510ef2488d46f84626b4429098e2f42c9b457e42ef2638e3e114aba9da2d3e664fdf02114c2c418c4bfb7546f2194e43ac39ddef58b70104a3732a71f6364690408259bec1f83ad75e6f50705919192f7cd1b77b90f4a2f1a3e4ac6c1d322ef41197acc888cfffa3aa7795018d5a4d1c3eb6ede7a07054d1fb41b9547794707e50821ad9da60da69bca4161c436571fe867bf8583628e9fb24635ae8653a90d0d357a326d517cbce99141f0d4a21032fd310c261b1e1e5af0fa481c3ff0ce2c0aff7e0d3a63676c7464518c1ff7f389481ef34d2cca0d24633fce8ff658038bc277c49a1c6d19f333af286ffc9879fcec8ac27da3dc541611dae55694b4771a7bab45c3342bca923119c9db6415e510ca51a8e6aef218a28a4284da13d51c21824c5251c626629399464541939af5f9b66ffa9ca2b4de1982c6c6ed549aa28c716d4866897a3e96a26cfd9b57d26d16ad9614c5fe48679ae3c4098fa2e8fd1a2ab3ae114529c3858c833c14ce3db4ea9c4f415128bdaa8f777fa25ca2c14cff633c51d66b7598ad31a813ad384e53b38772a20cd35afbacb54313751305990ccff71b84c6966aa2f8e9f756d2401d4c3213c588cc20657d42a7333151d4e87ecf71bf44a9e636eec3db63842d51bcf3f8f5dbc87a8c4a945c2344e4544a1442cea21a4ad7ad229c44197bc6f6e3adb31b3949949369466ddc7b24cae3126673aa7ec7db41a20c345477e6d4b2a57b4441d20707993323b59b23ca1ee62972c333f2a91a5106a31d2b636866071951d60eff58ebd9228aa9e2376d624a11e5f9098e1ac62b1145b7da9ad4d04b631051f8e0abf3308738475335fd185a431422c33f483f294439e3501e23633b712c21ca3063187db60fd237681085d4fdd07fcfa8f52182288609339a32e7b8b9ca4094336e4bccccd9b54a030834bcaa9fa83e78017004fa43c9d4ffefe3a6fd508e09dbd9d7b6c367541fcae91939f8f8784ed7890f85d7d89189fb28d127b40763e364470fe5f4b923ff66dc212db334501e0ad3d9faa1b85e68203c94d57bb3c5ec640a7487e23dda709b8c61875287bb03b19f5c1af37528ac9f48472acd8f99d2a18ccbfd2d250741d00212a81c680ee592dc7c8f8dc2cf6f3914ef636375541c87d2fbe3bce6fd99325d381447b3677674ac213a4f6f2898c4941ad5d8e433864581012c6000160038901b0a99730e0f25d4415ea40da5d78e4725f33f81d85068541aa3ed685a4349547b3734378a0e39524369446334f76e4b6928ddaeeabcba030d6d69c6a78bf75da03394545b73e80c5d7fe23833144de3d27d23392eb5ca508890e1a7aa3e32147b3bd5573634c75018977dab4eff13cf144351ad7c0a43a9573afc7a85aa468ec05096f38d9c1dc8a45195be508edc7caaaef5c126455e283bcaa492dd66d2aa9300d0037521b5fee499eea384a41f880be58cd239cde7acc794b65018c79af399e65a2026c94059284bd664e9e835745772021664e0055d9ce0052a78010b0e61a13466122e6d3a57283eb238d3d28d3e3a9315ca9a43c8f5f7c8ba3a465528b766b598c98a9d58890ac524398720a69f2994d3aac4db1b6d58202914328e28b1ba53e3bc178542ea77c99929de3c3ba050d6756de99cb3359116e809859cdc4462e8f618237642b1763eb765d8a809c5554d7912f24f4c285d454edecc1c5a42a9ab6b630cb255f791120a6b2719bff63667a3049484e2ff4966785ced0904ed5df4c28090500e51730c5d1b9137a477043a4261c2d98a36babcc9202318e52e20010b6270648472f0b2cecee8988a506a1c16ea1be2d9cd6403c080030840802e4e6001200211814cab3e35e571d44bd0100a1d4d36b4e3e6d44c2d1d4808854a2fe9f48f4b248f0305a1e4206fd41a11dd40402847cd20754c7b46ba660df483820789bd90cbb1f4181f1442dedaf48ee06e32f6a0743a19a795473b9a7c1e942764a3b4ce4a3b285fb6466b44e867dd740ba483428bb727918d152807c546b10d6d25a40a84839247de891c0d36a6e5b728d586a49f714caae1852d0adef59b19c4768617b528d8e53e9e36870dd6a645795af32a3b648bcc661685f33035714ccc17b228379aee7fd5ecb425c7a2f867b9513da4f873191605cd69d79fa3323b83af28c70c4c43ec9c889831ae28c64d7a88f96e2bca259bc4a52342a6ceb3a2ec307bc831b1414ffe5514d63f5deee74915e59026d4da8e79862fa6a23c16e72182f858c9898a92e41eb9f5746edef15314aabe7432c619e3a4bf29caf97a1926ca2d45316a4b47d39c56636d4851c822b93ffaec5194f7543534678cfc42154569f5afce35eb50944532160f6eab2ee30145318686928eb2ee736a9f28a9f45b6f48de4e19f444793c8dd587cf3bb1f5c78c992a269c2889640b95c90efd19dc44e9f647d7e5a6b3c71042bcd044d1266f6dde706a5e1ec944315c63f5634f1952c74469626c67f0eccce5fd258a39397c52a9d790e19628a5e35e930e82e14525caafb976b26d676afaf90525ca1f579fb19a2cf2e4002f26414e5b2e2f6115075e48a2145a9521f52d7aea17e145240a11abe53363d03dc183443123e48930a1ef613a20e8a21f51cc5bd399418a8f9b7146302acd1185d9897022190d21bc68444145ccd34fdcbc12230a0dfb2664f1ac35082f1651ec89197c33e99d5f070217780bee85228ab17e32e2a81b034f010866c002179017892864af59d9af57052f10513a93867946c23f47ea2660141ca2f8e0e454e34ff3e3d5107ec89ea531730bd8052da07a5188c244ceac6772d79bfc110c10a4a00b3a2738c10b1a4081148c13c01c5e10a29c1fd8a84ac665fd5de4e0c5204af7ee7a3b0b5470d018f14210455ff706f1675bc516b8c045c002c3a3102f0251ec8bd90cbaef6536ec2ee802062010410ab206f1021065e815a99127267aba6278f187c2fcbf4d4fd506f97904a34e7002128ce024faa16cd38de174fa58bf0fc5e9f0d1c0ec737b6752400210b4b7a00b15c8c041d002120ce40349ef4bc10bd0f0620fc58e0e33738ce68f62167895195ee8a150e7d1e53c234dfd9ce4a1a82149fc67b6da68911778c0e168d2f21ce35baf3dbcb843217ae8c9cb7a8c1a511228a05ed8a1188d1f787e66000b1859785187324e1d4a42e494dfd3d3a10c83f7a4081faae0055db0c0018a851773286ef293c712429ac60fabf0420ee5d510eab3f6e41bb424504039094e172dc029bc8843b976cf651b7ffe6a8c177028a665969df0e20d250dd395d2c97de186427c4d0f22ddcf84176d28b901c97a662878585987fe39fe665c19ca9be7ff22d4afde7c4786426d7630fa1ed9f13c79b83114a3c73209194d871343d9c7835e4c978766abd470612875dc786feb98972c83a16cd79911abbf2f10e306b38e5451e1bc50c8929376a134b7a3f3e9bb45c26709c78572cc132eb7693742354409b785c2792747bd3217e1b4504623adabe3792e628408978562b4b94bae463a91df65e1b05090d7cdb998d0d5783f2bdc15cad03e7786ed70d42bb14251d73364667daa50b4ffecc957f437832c168e0a6554598f77a64d66fc29943dde3be3374f154e0ae5903f64cfb83b4e5cf1031785f2e46cc402078532cc1f9edc4ebb34765d9ce0740a18046bf584324e9169c9ce13590524700108f204e78462928cf6a3b34bde15af09a50d9fdc3fd5c584d247f53d9e901d51da5c4229235fa467980e5001a3e098704ab04b82e2b8b21ba48c0c42558ac69cd363c708461d9541914111410a5ce02820c321a1f8d52d9d71aa3f52734728e7d7709ca275ee41d98433c2931b11538482d5c6d4fb716a2a7722143d5f62780ca68efc1c4259f28c5a4ff2ea54b710ca6873b54e6ff4e42e0885bb8936e2c97340283b0edb0eb3c7a4eb713f28d76f9610971a3531e67c5030f98df461623d2823c9beee911bc73ce14131223b1edb849cccb78362cc9e3ce728d16d3d1d94eaa3373e3df58c8d870d2e07e596cf8895608d3ec68783926475fd4998dca29419ab6959551b36daa230d399336391ec1faf453194398a983ac7fe67b4288b7b08f97149461fdd599443cebf4d723013796551aa083b9941c8f8b7da5894b323eb37f00cb2da8145c161f6eb7d365e519a1af3885122daf97145c9a1fc67e8ce0899d256143725ad449993158588e93c4a88731585716f7c9e3386a9a214a79d7b3be120c6cd5251944cada9a37fece0932e34e02ee80206a85a3054f4a77af3290aea9b24fe5b638aa24eae4bed5413a71fa528a6641c294a6dba6fdd1223368a2d1f7976690755c0022f30511462caa22667869bd3a560a128c3fc1f57eab5cdce1ba03093443651d55816c13e51520feba96352d648e389a2fca48a8656796712eb44a933482bf2ed9fda27271827ca799b1f6434e13a566d9b7046f3872b1b7308a689f23ceaf041cb26ef16402258268afef770f2f78cdcac98287ba8569d3af30c13bc4469c3dbc6edc71d3d78962894a4ba960d1b42d24c258a91f1e863e703ff2452a2389dafb7c1674f0d429328e41fcf7ca95a12a4b7cd9cdcf046a2b07133bd84a83d462b244a99a57f19f67b44a183ca78580587558082f28139a2a0b136a32678360bdf08d688726e448a777f95f820398231a29c1d47b72d890dd5d13fb045fc714223a688b2fba7dcd4597736994494b39b9ff73446bd1d4244411dc3140f3a8a7eff87285362c8a419e40d510e1d6b93761ca3fdbd1065e8377e1267be5b6f4294ac3f22ddfcb38e3d88d2e6860899de9f1d13445162c3583deea43399401422fec76b5db28b0b8842e408d2b82763ccb77f28544984ce5aed3946c30fa59d4c1f3a515599ec43e9936d6ef0b2110f1fca20f8c7381bcb3d14675e3cfb43a8876224b9ec96fef25048bf992a32c69ea2c14331c7d08fcea541dbb3933c880e77a62a3b94fb4745ea3b9f669aea50940913dff7313a9f9d0ea5729c9976de3efce97328845489af2167ccd97239146f42c3e8fbe350b417f5ec267926730d87d2ff7dfa910ffbdef51b0aab17998efdc273dcb8a1fc11cf51c3505999316d283b90d89d3e969e64980d654f11b9d3a7c69f425e43d91cbd745e4ed450080d2ff110f3e67ad35008aea6bd352d1aca11bf1dcc83c6194a99375fc8e498a124293d9b1197a1d8f6991d9222e74d92a11cd656227bd431143a7fd68bac413194cc91886128558c438d6af41b210706454cc673e8f1be504e8f23b5e8a87498ce0b051d6feb7cafd1dcb62e94b351457bc7b850f618c5fdc3e3c698b42d945de34f9c456437cfb450fce88854978c21ed958572c4b74e9225168adfb39d513acedbb0ae508e69d2d664067956638582bcdd494c176dc9a842a1b67d454365a77d5428967ae59d87f4c92a6a814da19c2b9b2649b87e5caa144ad7593242de4408f12814f67dab5d34acc894502887f312797c5e7a353ea19881a65489bd63d0c5020840801874c1021698130a9e8d24e67b79865635a190d17ace5b8d1d67b78d0985baa8c79f69b225141e841cba23f6287325146cec53f49644ca4f05337001088a019684f2a7fbb0d954f2f822286801c760140bba404342fa1a9212e34823187552f0823708942a25010a5ac03138801da11053d59de36fcaf73742a9df265f422709fef92294d1f9758612791e8e4f8442446d586ada8750d6e00f3cc766c28a2e84720eaf0dd79419f7f220942f3e3d7e8703a16c33b2b51a9398487e50fc906e22b9b235783e28474aab7cbc0785488e3287986a1e9495311942c5c77650721c8e63d3a456951cd3413933bdf3867fc4d58de5a010f12d936674f84cc6705090aa7f511f8de71edfa220ff6f6ef1dba22c599ef9333bff36b528dbe398cf7f71572f2dca29eb699d3a830ee52c4a2d9261fc8f9b0dcba28ce14a48ff911ed99158944ed363774cd1ea3a2c8ad5d958e75a7f32fa1525cf29b267ca7cd0705d51ce7e7d749e2bbcee56141e6ec3f27cbde93a831585c75f71b67f6536925514e54e521a9f740379a8a2e020c6244fc7dde0938ab29707eb9e9c32414645f1fba77388e4df68e8294ade386548f89829df14a5fbdc19464ebd14252f4df160ef8e3f9ea4287afe9c3e5755e31093a328fae69a984d8de7648aa2a40f7ad65376b6103314e9da653efd24f1944281c2499fb6633cca4f14567f3f75c6a0278a699fedfd7ef2cfc54e941e4e5d476dc88962b8cc217a7d7538083751a8099f2497b929fb69a214dbb8761c573cfa2e13a59c98d140e481c6779828898cb6cce897283f90101bf74eff6a89628c6d4c0e53d96d5d8962f8ce1fc73c644d124a94547ea443f4b3b66b64bdd14cf3fa4b42bb6d90b73723184558e02d381e54244a1f3ac3f4a0d3a97b6c2151483989be31a71e51948ff89235c611250dde1a1fbdf77c48230aeda9abb3f16864924090a502968021a01851b4c68d2ff4a1df956711c5d278e4e531f2b3271551108d0df66f3c8938acaec4d0a1358588426488d11f7abb4afa5870012a401da21c3b84eb8e8c1b6dc7fea00cc126113d7f87a107aa10459b4d9b53ae7e593a21cac93d84a309b91a4459bafb24496604518e8e4d6f2435fb6ea302510c1ad3e0248608e3284101a2fe50042044f941b5d7368914a1fc1fc12844f5a1e0991affac5dc000f6050db0c000caa8507c28b56a26f990764bd31ec1b0000108c002af62810b54b084da43219d6876f44666ec73e9a1643b495f33e679a8a3f2700a0f25d1640de3f4376cf72004ea0e05cfccf83a84fb6d98ed5098f4fcbccd161d99aa0e6dd0f3c6314a0e1d0add22c9daa36fe2ad3994c3973dde37b3707825224a0e85b0be61443a2544c5a124aa930644c1a17c0f92c4f47f0ead372b887a43396574d2254f086cb9a1e43987dc6033a7fac1016843b5a12cb2f52ea29d3eb2e7856243c993489e183cb6d9cf38875a4321fd9ddf59830fab1ac2a1d4508ef9ba2e26fde7b0511aca92414c584d1f341437d8a5e69ef0a9eacaa1ce50ccbf9a7cbbbf194a05e59118fd57ed34575f4461d224b78f28a2a47ed6a3a92336499f8872248f8dd214229ede102a3db37e88923836eb184e374469fc31ccc9d1c7a4a30b5170b03d16b62f2ee14388d237a8963cc9338862b4dbf840d7cf6386200a61ac2e36f678ed650251ce50dfdfaa0c204aa692c4cde17ea8fc0fe54dd620d7c70f658c4642e3eedafb461f0a6beba92e1df3817ae459e24488f75076cf9de23ac65587e8a1a03f8e7c6a33884e1e0a418344a90edf1925c143593b9987ce17dfeddca19873865d11dd61886b87a279bcc77bd4504ddc3a94dbf33398d20c3a94f3fe9fc6ea750e8560efb15355f36843e5509c7d705d27f925a5c6a174a5fffb333ed6208543d9739ced1cccd6519c6f28fb741049b2e21de274431998a69ba026fe20876d28787fb668128f0d85fa8db05ef5403dbf86a2976eb2b18b1093a38632fc883a1ac9221e676928cd7bd67e779d8c3a6828bd548e830c1e8fb185853c031db777c5af73cc5048752bd511730aff983294f6638e983f21ba1e93a1b8b5e9f56a5121c7508abf7ec9729fab8c1143316f4b9b499e5c8d69180aa90f1e5fb449c6196028fbc6c939e9c48d12bc2f14bc25ae697e4e6a784d21bd509cae8f0dfeef42d96b7ab3a977c8f673a1981bf74444bf88b7b750c6ee6da731a38eff68a11831049b103d27799c2c943c06db6ad160a17c8e3f59249fa82db94221e69c1eed86dc0a75963fdcb057a15c92d327879a0a85b8f629e2fa14ca2211e235d8f7ceaa148ad7f29bdc247bd8d551287c5de847be2f5ba9a1508e99653d116c25429e500ce1ac2eafe184f20791b7c7b3fe8e6b4251a33eb637769850727bad4d8d9d2514b36dd44648cf17be51427137ba6e9e8ef6fc9a24943a3f4c7f888cc6f148287c06d349f5365727f908070fbe9b71974628c6ec0ff765fd3e06b90885e497d937e7904722141c456798bb1f426132d3a4873a1142415b93e67bfed78748108ae932c2d7c38150c8f16db1ee0d83cb3f288e468624af0fca18fc4e671c96ba196142f6a078da12d27f1eff843c28679c365eaadadc413965dafb9f6cd6d49a3a28a47410f1ffd1747e68e6a0e4d932f321638c849a38286c8cb2b11a8e4b2abd4521a9a567cffe19c4326d51889343fbadcbfe64590b1a66a7476e079016459fbacaf2f029217f4cc05994be4cd33dc44c571ecaa21c6552e33caf51372616659bdc77ac22672ac3a2d0d55d11caf5323d5e51f2fd98328bcdc3769c2b8a29d32592d6521a79ad284c7c6c1f3aca698c8e1585f0d00fd27df3f1b38a92c324792aed1373d85451887b1a624a183d4b2d15a5949dcb9adc382a202a4af9206470e73eef393b45d1273508129133e8da14e5ac3df14e34578756a52824dbbba86ac7f2a82245c93787915b4b3ff7979cd26ff8c1e324a0280a353a1342464251f635899edf715a7f415196cf48e7f04fdc1293951d424fe899deb3677c270a3ba99f421fcf89231ea97f364fe56f4299903f26499ec7d7441abc6dc3cf4411352479eee03d267cf55c7b9b21db7e894332eec76ba1d21fb7c4b7fab357d31ef4e395204fe68bc88de2e3943063d5089d499467f626355792b8c61e630cd3636a0c8f045123a663209e3a24d4e0a621e88f28b3c3abe8dc11e6c818ed7abba98da0635a2fcb911156e8ccbf74fce4b80863dac818e458ee372ae2f8cd7fe3f844f0a2da312188c073533d3ffa10ed9b98637095ded036c4283feffae464b20bc164fb6bcd988d4d08d3a33efe60e320e890d7d63787a31a0541de48677520f8aeeaeafd20208831feb3f563bafce01fc8731aacc14465fcc0e7f468d6718879327d2859dc74c4dfcc21321f460ee61a670f7c4c0e3ebf2da91e3d94a333fc344e461ecc9307325ebd7da877f0c0bec3d01f6fe2bc7387d54524a675d4603b589e93a70f4daec3f51372c8b76a31a183fa1923c6d509923998f1ec8617e5c04a46caf509b161e2708ba3fb2beb190d1c0c11b78e1ce989e60d9d8e398e279132e306bd432489ca07396d184bd9ee6d0e3e1b76141b526ecc1acce8769d276a38d94e7c90349434a7ab8a3b190d6e47447744758ff10ce6476b9b3736838d537c1855d96c1997219ba08da23f474f900c4ee62c19a3af04c770d2becd301ecd542206e26548cbcf7be848128632ba83e99220187695c81fa33d44f2053f35ec852b3dc68c60171e6b8fd2987dad29825c306609a33d11dcc252adc937f7c2a75ed4c2601e8c4f748fce62164c963949cc2216be725309f70a9564b3c858a1c6e2308f5b054be6c1cf630c935420577b1f079f700a86c6e50f3dc93aca560a667f701b8f289012ab8166a5640714cebe1d39a3b5738c2778719e71326685c30906c996db878d26901d235fc7e5526f0d260cac5b42e27fbb5157259453c6f0e34926b37134094ee3c99a7d1e9b22618c6fb2f6e147e8b45c1f369698636e041d6a4c9f93755d84dd7d421e6b5d8408668fcfad791c4236492194f4321a679c7e2863820083c0d5ce3bf21208e69aa98911e951fec0601d63fc883e38976a6418b378927b3006f171cd7fc851521e280f3b84ec9e873bd8b1a3741843d4c151a3870d21e6c0fdf22fcfaa8f75c4c139aacf1db7c8ce7348f758df0c5b18bb29bda73a32b4163eaeaa8e272d0cf2e2c85910aecb3344b70967ca028d4bcd0f7aba8b457a211ae4ebb175b0b836d6346d78dbafe06dbddbec7147d8aed8af7388b5e2ca9cbdd2cc0f63c59941e3b3c9b9a11eb60a2464a4d4b80c2166982a481f2277a794685a2a0ae793a6ff34425d68a858ce81a4868c553b85fb7152fa759a182a330519269b4d568ad23546bd435b9990c2983339e8778e8ee2d6cdc024925ff556a258429ab43eeb1bab501c66ea683573961f149dc7f08bce274c21d9d3c31306cb4a07bbb154ea84198ea19877ab038913a50db9c96c42d6dd8c364187fcfba842c2224d904925c7333c8799a8cbb1c6c4ea7730319858ee6cc2918e6cf412c59c322eb3465c3df52d513607d15357dc45dc5d09bf5646e5a64421f875248f31823ea8275198f19798d73276742c89f277d23812a568f598abfb4df348489455d6f3f2e43b69d61e5170902c46be518e20737aab31b86eb311450775dafd38a9d5458c287b35bcccaffa22dcd81d43349ca41e45148249c32a8fd1d7433811a548c9d974e64744d1c1962795f01d42dfb64d91f71a821082b8ae6803ed520b51cc7882cb3edce4283384289d4d249f143912a33b886378784671b0200e9b1b63bc5b2610254f99fc5b73d6db1f10c64eb549b488bc88feb0d569dc0f7b7b8ef41db31da60f9846dda4b268209ee143b94194bf7749f7f0957f7e877a40334c9a4a466b827928858ef687479383d489873623dfd015dea1fcc026c57aec40a8533755d98cd7ea3a0c247d8ec48f666ada70742859e4cc993d5ceea65ab839d4b5e3eebd1a299543592a35af2a73bb2a601480a03d0eb7e7b8f37dcbc98043b935ad8ae75c3753fb0d441137c795b9a1f019c854d78652cee757df7061a73e1bcab13c23a45d323ddc1a0a12970f937a497d9428200106e0706a28a6e6c7703388f7c0e53414424ce2c3eaf6d05096082da96375063932ee0c8553bd92adfded028b9ca864cd86e2016930160b0502a128248892ad1300c31408000030260e060291284d025dd80114800260221636241c16181c181414101612148501612030280e07c240302810080483e9921c2302eb07902535aa93488b48b18fd372c66cf09013f19c79b16b1eefa70cad94adc77f0f3ef378e7cc379f02fee106c2af1f4bca1ae8f6bf8ff30d59b243d815b508796c424eacac8e035b3efed0efc7d6237c4c03a15984fb235c486920d67e9ce42e622e718b8f3f248468aa7c7bece0f1f520e6a1c423750f64fab879115694dd1fec843003a1f8433e90d3dc3ed1a74c07a89a58b7540b460bb45a8c1612b5fb64f5f4e365705a0a2a2a382cf28242c48e8bde9a85293a920519b41e91fb44cf8942265046a20712b04d849e881b0990331f806d600488c7dc69c4270a1063597a4c400445d724d7f4138f24f020a28890be123dd3b7dd693bc1ca09d0a8047042f3088a343950106308e310a522d049040fa14d980fb53549b81504cc5f80bcb925c9e5277a4898c6a42b21ea38a227c37711ff9b98fb09901cbb7a082a099c0dff3bc7f7634c80e8920b0f420f261e547bb07c90059123443a23844a873c235dda2ff385eeac13ce5f2aa48b4004f413344cb0244241940fe1ea086d96257021ae0f849e1c10affb5e003927d4bfd142f8ad083d896441f480103129219d6a816f9ebee9b6d0737b98c0f1a5a609b2960009074b0d6d05e86dd13099e0e80d614b7c3cfa9f5832d54b6651398860cf4389cec560d3a25e07f3bcfbd1b2cd0e267af51e23b0e1568389348b2e9f3634ca942e7a6d79dfbbecd4836e31b88d4dcc0d6ada2d70b61a15ebd0ce7bb151951b89540823fb618244f668480332941c1da9c97aeb2c71ea8b2f827b62d3f02c15e6c1d21232d6857276a1489fde5bd761ff6f73202f625b0647a03cbb0343e90361394b1fba358a6399e26a23d3237f48b15fd9db98dbc01a318e63d675bf55c66f2c77a83feafe2aee86905622132392ee47359f7dde4e87e074633121bbede40f84dcaf52a830356b7417fd35d73390c7e3f50820b3980bbd06874b4cb8ec62f3ae6c3a023e16dcf2a77f3092bb9bb7fbda32740976c9907ab552d212c987bb1e99ed886ed60e002151002828570b6078b2e9f51aaad13a42ef4c1f59d92eb762035d7f85ca5823cd1ed1d4f97be2dd1e0abd4e4d4d596e04fdf16253b1fc2d63558d58508f440fb6bb93e37bbaae20b372af40ed6dfbb8bfb465d7c82c7ad8e00b3c9299ddee9a3d4c5605667b39409b865181b3b5645423d490f63c7044788b109450d84e7fef6aa679cf5523f13040683f7197dcf6bfaab5dd23605eefda2d08aae984d2fabfc7133c84cc808dad6a64628214454eabcd5a26f6cba1e506d197d55b4f994de153aee3352b7fafacd772e6ae1b696fe2bc474784caf6eaf111fcfc55dd6bbfd1fe92ff9ce93ba6ad98fda37bbe40bd069db1dd800ca239d754af1fea1a817f8f9fbb8640a63309fb626930b4d9280d206811e3eff989bf3dbd8339f5d3ae235d71eab249dd681d4d5c9fdae3b52b9be5af0b32bbcab2e4948183aeb9d6eda393a397100cae96b477688c1c775d51ddefe496cd3e84c8a93fc4f06e3d5bd925a04a0d22b5e151b00c2d87d1bac6a4858b7aa8fdd8d8f170e1966496b5a7e14f50b9f75716d2035103fc9b8c6e69f2a7b77c549cf57a0d4f92fbca6cef7759f41c0cb1eeb83a7cf29a76d9f7031cca5ee791049f29337a0926bd4f8bbd970f4fa2b0fd6882d9e977713b99f1dd68e8c44deaf754295210b678cdf561cf1360019fc73d9ce5b59bae177bdc10db86ea8afb1b42a275ca387da0a3df0c765a8e2fa07703bb5fb0a5ce98d96dd0b07168878ba5e4aa0dc1abab455487166d6bf439a0df52d7c8ffe1781284182e30503a56f7e640af039fc5487644d7e541ae79b09ba421bc5fb7067a2f2a69cf9b62420d6a993635c3e7b35c0c0a8f61c3b00e862a317a04623f43f71dcd7583a39df89ae970516fae4391acb347e8a0aeb78682dcdc6e0219f772a663b4a8894dff88960157a686955e06147111b92c63c004479da799cdd1d7631c121146224f64bfd2ce6641d3a722f28aa456ecc8b2342fe62d6bc917c2977cf08b3c37d1cbc162efd2022096b9fcc63f51256e108b68088a91741c710d12cf41a4f4d5a55ec7214208a3b001f588776d0fd3f2efa68b4a7b7d8af1721449e139e29d41fc43e033889c767c5b7ff79fd2197421e9d9d894a0f0861acf8e790c143448bad097448174d2e388485178bbe805c2a445b69911be3e282153ca69851561bf560e94eb981e0a80409183641059e707d82579322d3ab0926944b4f6f6b5d8f2ce3d980ef933dcdec36e00175244c904066bf53046f7b4aac248cd4d55e3c670bbd177f723273d8e1686ef9a760daf690a70360dbe02eb739cfcde14f71bcb9ba8f462faec6bb328442676b4e9321756e8daa020f2d9706ada787ffc232b3d094e0472d24ac2db9746fab34869e688eb3c5a65727d8ba8ab245093400ead67729c3478f9dc333704cd1fd95f27d562c98e009939817d367399cec46f9a8617c07f77ecac196a43fc71fd3372308b7de6e465bad53e688246b7669eca42412f11c87b19ed68ff97ad4b0e1b6e6494224aa0043de17940140cfe927d595602088ff2162952b3c76ec5a1db96cf880fb050fd400bc183f649140d98ad780c568ed68e86855badd4e965c789b5e54e3ebce8d260bb83ae44598c06c95631be5d8ca26a2c9858fb278f3d2ca8bd80289ed3b58973e3664dd41f66b81b52bc07acea25b957d2f866999ff7888e3dd1ac0598078d87bd560c7ba274344a7b3221cb5cb3ab708e8997ed2b6ee91d43b5f7a63971a503ab9429473a3b1d05a8a39c88ed9d2577aded54bd29811f6a7aac9e92e30b0b458344a6cb804ffdab60492aefa51a71242dfae7e43499b2945407ea98d4b41d760805d95669747022c0811b90e971624a1c8fe0bcb528670d5867904cf05e6cb2f6ec9be5045d2c1944095f5049dc390d74231ee79641864adb466d98eebd05e16ddff59b572cb4d6b2cc1619431005a105b5affe3c497ccd483c842691a7d3ebbbb6fd04c7c27ec0aaa42ceab060523773f4bf87931b42a6198b6299dcf73c7516b0b583effd575b321698e15fe8281ea346258009b91555ae2d1b98192ef769091de6e94691127c18c06bf5fbead769da2e9c499eae9d955aebc7f42e175fdbeab2e0dcbe2736845370072416350f38aa8a24e3cbedc27f3f48fa4964f198ef452651356e064217b5eede21084211dc21ce713de8f44980d5b8c63cbf9e2496137d047e7b102db30daec62c0c25192d9f8c4b8b9a60b3394162581f1b940610619e10609bbeeb4d8db525cb9a59cf20c899608300b2341cf7d70c2f8fbe4ab23dd30ad5353faf94da4ad46123eb058a1083ef58c50a73b241d66ff24d9f5c779e61e3cb0e80e862de6d8001706849497ae5005863c10314bad8b6c2aed9fbfa398a7467532703d1f747a105e4a41003efc02922636e0b48a9c17ed54a6dc4364bd48e8504dabf0c8afb9b17210a21fc8ed601ca970fd05122a384c089b72f137bd3d061b78f6ce45542d1d2fc8c83a1ac348f921d46f17eae6aec4a6be71b7e7f609c48f6130064653b08b66340cc94840f2fa48f52226c2429574ae43a00c6d025bc8860bfd5540b4b2dcf932428947cce0b433583e488d0d913ed58dfa3c667a915c83c52490ba567561060fe741ed64c1a31195504f85b4196d096e5734696894c82c2215cb5eb492a96c0432e5b0b6af3372647a2a86d4f30de931a7e9a7b7c87e0b7d9c2f20b2feaa92307cffb86bf360deefb344cf662c90a3eeb180c88c6259804d04c91792842b2d78059ea2a549d507469af4f2d1bc53144aa42eac5d7743549460d2ab56150ea17c2501bcf3e8161d79fab55c497553d67f7cfb125f792576db40c489b100c135201ef48eeb3c8990e9e95d3605462489f8bfce1b87cbe1edc0380bdc5ee5e68617ce55b6c90226ab0fb1d07418fc9f705560f0ba50ac777ca450ba1e5e0eeb6218c2da5fbd2c2a90e765ede45bf96e9dd2b3fa00dc114d5eafa0c4ca192d8f4a15c1f0b206d90c713ff2f73941013184a2110ed24d58a7467f8ff42d824894cf8bf31294f82881bf3d9c705a74447414d4eca55797440f8e9854848eb028f42d2127a1e8ea10e71c4c1859bc26a424f81b5e09e87775d1086437098c445de7078fc59a884fc636dd6c2bb430e8629ef2ce3c4fbb68168804431f48a3ce0257d158e216f4c2e22be32bccb48fb134490000826d06b280b972e0138843b0229376cbbebc001b684d7053c85dc3944e9c7af513924c239545214a6c01e914f95309968b76668ef575cee74f979d921381a8e4b439e2c454aa29b94db55f8eac33cfc72e9921bafbd5de2b20fe1eda4c1e22c19f841704bc4a9e237f42967c598519e92f644e501ae7105cb6d6637e4a3b513a9a356644ed211925f2d00f60650919ccfb5dcfe0101122fce324c420c0acb74ac8e80f64182045d322514e9ddf47f214794d830d48f0f5e09c3e561ca2cbc8629eb7c4d74372e68109c03e30c2fdd3eefdfd97e2f4f8b7d06fd6d2ae769a35a9fcb51150d6ff41fc048a2c684eb19223aa6c68777f033d5e34f0689254624cc1fd505a7cb73cff60d4b26e85ca80c533e004a41d0a14dbe7c3b39921ed3534aa990bf2ed7569258f66bbba3c63087b77c254f9d7687f0ae82c14a13e11bcea2c39a190f1547a33e517c1820532e4b2c0667321be289193b44266d99c4c6dcc41e89d645bb8af4a732307aaaff61c133513ca15b527f2d3608ce0c71a9e6cc0e19d7e2192ce30017efc48d7d889834adfe34dd6e8e08430d17556982dae5ef52fd390269f5085ec4cdf32fd7540088a4f3726385cea2aec8fb12358cfa7b75643c56d829c2031409d85e06d92e5f75d19dd0826908a23f3eea4f81b8fbc921b826f5b7e65ac874f2b01f31d22c7a6f89a1cbf999efd6b2be5e8ad680644f56cd4cac719d11cee0dc5ff9c28d149978a5f0493a728b1be19e791e5a89cf1427661415872fde6ccd09a1d2730cf24ca10b9cacf0910a5e6895ca6adf886159800658af1b07766810dc198996aab8e39478c93fba4b44e2ef338f74553da392c4f35cbb0387cc44226827d7751093d67ad4a74ddf34b0036e966a63b0365648aae41ca9feac0841c918e97cb56dbf3428b9218f39b5edbd972d3861caf7f982d89396c47672a234d4e3eea9d86e70affc349f5cf9bf8bb7490f1fbdde80a949fd413a0a45724394ea45e1be82013991507d35dbb21bb4165ceccae5700ee3f323ba4362a45648dee7e09495893f3006090f57039fe2eb830f4aa96483b08ef8d166e5a76acde04bc1eb08518deb60e863c664525e8447bcee96d73b2a42614f1e10ced287de3f1f305ff99c07c9d0eef053028075a7cc4be0fb303f6e080eeb04ad49f23fcba582ec4d84f225fa0795e2119f8c47633a987cc2e4376797f805dd6e2a1beb4126624ec5e2310862c7c269d0eab25fabb30cf57ea9491571eed860a6da3241c2c3136b3e5b4a975026583f9fe74a8147a80d0200a1aeb2f94f846a011e34d13a9e1ead199130d4bb2fa30e319b42e1e319834ea2f86db9287ebb25fb3062d29655be3b7b381f4948b575466a36a3a1b378ff13a04212725603d897a1fe203569ad1f8000cc0c615762bbb915e1596525ceea6532499cbb9127bca209157d7af72a959d73e621bf728d4cff3088acbd5313a52514485c1d15f3f03d43669933cbaa73824656d2ddcd832e12336134a3d2c43874f417e59221c94cae5be1ab9e9a3dc017e9fab123aaf40b7f418eeb50dfa82a0974d079b58d05ca2e2740079e01475557535587cc0b2a9fd028a4655abde482f1760259de43998a4850846034d3ca73305c6f2d7634f6b82c7bc224fe9a4fc9aa2fdeeef9bca7bdbbbac0ebf5b243d8c9bbd2d0e97d6ad4d28041bf3c480467435681c8bdaf3a3c675e242acc7cffb82cb4a33d2d3ef3a90d492098046d5d173cbe6a0d41f6b9e33c6be4b71113b487dbc3e8ce605b8990cd683de0ea58c9771638c7ef21eb3c7bf46deb9187533672a2ac07a9c5070b50a1dc09c22fe9f2d6594431e9238570cec4753e423eb6ac50bdcbcdb204189ee102b85ed7f8825731dd24042f27f50a884231e86e050920957c40c4af754d253cd10eeb9a23b0e83660235570a64d3e4a91189c71ad4725a4aa0dd442c1abf410d18338b190c46af29a880ac2754f91569542082525fd793a49d13c05d62420b5691a566c1a1814adb582212774e2055074f8032dd9619c14ec5b810c26f545f79093c09ef8982f5d3d8ceba3a5b4fad61842d9b18a70f7c111689ca92a93ba4a0385d42cd920b32bfaafa11dba3d248444fa728554103dd54f04484bf4860855965512a1449f20405c2cae79c5244659a17a31d0a2eb80da9adf51bafa2e32c4e9d5722b40a395722d9b23c6ed95e0cb20aad3eedbc5dc3d9f40d9520b0b8653f6c96a93f9a948e0096b38982bacb4d97a92a61ac00418ff500016629d79470f3f102b4bbaf4d56616d1e9397f873b4a146394b3685db4e3409fea1e5681ab793b6ee16aea4db306daad837ebad4283ff1844bc59e586f4e166b31497a32d350b03152a8a3385431eb06b20360d99d3a3ebeabafd0276bf99f078dc0bccb7cc713201ea404874921bd3425285a7128ddfc2723cd5a2a01df04eb65273fa0dea85159e0e487f7d649627a6637888f882b5e19005824ae991c82c210cdcc1f37b0b18fc5d62e665e83109fc164cfa20a25e538be8afc7af03d6e8d33dbd18be45234cd54e16a14323c0588f1f1b47119e4e9a8ae027374690132b0e440dee6754cc2a03ba6c7ce4c76da2318bf0c5c053e960b853102baa3cf9ea544f8e0102c9ac195e611d787dc6425e1abf2d91a3f7e60107ff07e82215879c45f8998284922146a174ae92c25af3c33c03e7657bf49be00ac716edf4ad2191b5b107f17037887551db8022398ac0c6b188ad96f8580bfe91723140e6fc7e935a7fa6c7810d28074a861f144116d551f0ee857df0d6a814647cf8b361d28bf1f7bbc5364ff397b39bae6f2c814d8196dc8b72bf7def1d46c45c825f0a21b3301889ee1dba286c2eb37cb6ec67d73cf62cd80d25ba18119470f83c24b52a09cecb3dbe45e6287774f8e127f1cc0685508a32e827f0609ff58c313622f0ad23260c3206c33931864359dfd0a56cc5fe5c7c56b6dbd4fe75689e56378aabc39743bb2c2838547760845a2da46a11d8a183694103f89695387cf183af652bd31b98a2ce94c10d9a05486e3ef815cb3859b50bc0ef8cb4fa26065346bed4b9faba950c5a6372fec1b71201569025f944c389e935b61f391f5688785f109e7647e7a834e28b327ff5435321b845060c3480aa0addf7553f9707c19ac7598f2a0a3aa79d970409c34184e6cd40f9feb5c4e4fb93f1300abe0710554631682c62c3d4aaae15de12f17ec29df802dec46f301c50567100d6e8f2bf03c3d3ef406fb19bff67804b43ad670bedd2f370cea5b795750da23bb889e964e7a8080886dd41cc1e8341296cfbb82f743ce0af3627ff5d7907c0e4d4d624480a7ab049302b019de38f821776831614a53933a174c266278ca6943afd511179257c59eedb09d9c00ad8682a000288472af188f236845ca3aa578630ba1fde06f4d4c638f19442f1de512e046c0d7270875ba1eb4b7f114cf98dd540f30bf8905554e7bb5395ed464d90246ffcae63202ff1bbc28af17547517957b43d912d179ddd5c034f97380998542f4c094aab48fd17d744ea337d74665406510118d528ed28fd25cbc28e07069e9e2ad4fd1bbe61f1e5d2e09aefd36b7240e4ef7f69f40af5157d842cb2963dd3a3e7e8c78a7a25dfbb725543d1a217cea9ff38194edda9bdc0072942accc63da0bfc4640074ac0bcbe3ed1b1f52add540bddda71e4485491a2f773954da750e2a8d6e230281ade4fc378748708790124310b681a6ac05cc2a03491a5c1f5c97d3e15979a2bf1e3b5ba16898ab83823b1e41f0f4d2e2a1184f2fac71d7b510ef9a56c00eb9acc8f818dbc376d0ec06cbbb392afd1d0716bb37ec82cd6ee8ab01cf30d9b1b28bd12edd7653b8bd2bfc53f3a7665ea73454c96ef43ee374c4b18be4764315ed17aa033b7676467656dedd740d3ec261b61bb50d013661b29398ddd4c41efc50bad762b2559ef7b58c87c71213b878d77b43dc163e5ceccf65072998a75f5c0be6250e0af7ae5ba070915abdf9e34b25232e38f9be40c69499c1fceae6a0fb11db45db8609f20a6703ed7280ce6d0f4dcc6ba577a0b7d92170e89183781387ace030d0e75dd01f96ad947611d77518410fab19687df9d8eac620da7a2c2fc815f8cde386b0262000542f1f99e3fe9c41d485417fa6c20d08ba6bd311146ca83839c7b20cb02179176c59a2eae4091f3b3b02624f0e9c6a39842f34f70a97c0c6f93af7e51cf06c56d5bba5a814fbbd3cb80cbce32e4e11e09b1a262b8661a862d2a2879d60ad3c5a822c5c129dcda28010601a078e74190ca97295e86764b2f7db5dff2f18b8980a09b8cf9c7b87c668f85952b7d24e69301cac92c74a62354d3774a026e727137ca371a2c222ee05380b1764a3bcc8e0da4eb71d1cbffcbb3aa2d71204d31a3d6b18100fafa9973251218789c8fc03f127d7e3c03da20721e8856b4a301ad820c9a99a7008e7af92925998e7244325e9a0d4df62110384b4fd8aaf7d19162701e89db33d99f10db76f6f92b17b2af01d60e52c5edec255a69f4375e6c814f50e1d59593ddddd246fc63c76029cdf428869e77ad8e6c0a40ba9f7ad1ad241e2102ffc6baef1f2d3da4f514d7d0d41e25ddb190fafaf41c5c5416b9eff75342b46934421c252824b1b5e41b4039be91fefcb6a9d9ac6036c8a057064c11a559a161ce33973900b8580abbf365070c2285f3c3e56a4303afe5652b7ee4b8ade32e7540ce9ce69fae0f905e2a99f48152c0fac715f544c90021013b4b72a5f0fe5c02d4208c190cbb38479ba5544cd564ba121ee6cbf9e37c938752e6584868221f5ee09aa9cd2de2ca130aced9534c10dc63340d2702608726d9653b47b25bc09fe57bbc63b81343c0dbf8665505fb78a32e5a94080330b591b30c99f3c58e8c82bf3844fe4f760d087fce77ee0b508e0cf88901267624477efcd95536e7302c66d3465dbfdcd28c5bfdf1b44197bacd8ac0020342efb8b50b1c804034886f549193badc7779e6c4856c40f277d457a76c4c0e3a8104206299272d19741803d63c37bc6d71d26d88a3982587e97523b2d890deb86ba81f8d03ad5ef1d203e2b7ba56ef127b771c08bedc788c04249d3d5f923733bb949b3dfe2eb4ea625057eeff8489b8a250cb0d21ca0477bce5abe38a006ad63f4ae57778f2ab4d9ea0c6f5ea450dc6f4daf65e4ffa7564812f7c0db8959bbd36c04d9273b063cfb4d2e9811c7b60832fc64b9164e742b955e2afba00a4c900521ffa8ca7f95f0f370b548ee01c13f951667168ccbf967c07e4f82e534be103ffd3ebf12dd12b6b49f5f855957108ef5983a32d3ebeb6f76faba7b358668588c436170d5225c92e750e064a64a1bca42b5347422586ccd435e5d428eb8be21d5ebf6296dc062d2776c6042d9f6fdfb0110b35e55b9ed2bf52c6d387dea2bbeff1d1a06a2489c367c20a41458eb52876c2d87f5b2ef002ddadc2db8d5849903f1d338e3a3ce29ef3969740fee5b9f31ea128eb3cfa96bee96455e40ac64d0e66251612ba45ddadf4d39929a6f38db1c53b09e07d27556bdebbc866c6f47f971097e45444a14581ed9e8943faf9eed86ee188c190b4b1b9c1121951ec3620f32b5a04c7fa5fb588a6c2e509ee3639e3dc81dec1e35a25e6d94984ab2fd3a97ed7540007d467aa8c6d79369001a9f3d59719beeb734e21dfe1a289e8d9bbc23fee7375ef2176652cb013bb2a10a39dccb9acf31db4609cd6e7c30d94a3004646fe4e2a0e7b65a6caf7257936da76ad58da1ca65f5a03c3daa1aaeb2986affb6678028da20917f686d327119f2dda9fa9903c91579b170389d2a76e8cd87eb9e22539d7567be0a4c6d487979d7f36a32f7d88982d89c12acdddae2cc0911c13d5f4bcb57c0bd6b1a5c8d9ed74a77ad633587b2e2167f45491025bca49bed386fdf45c9cebe7d248a4a2776abfe23423a30ad30c6079701e41f83c1416bfe407cd8072b799c8235b16ab0bf497c83cfd61bbf35ea07edeebf58f6229d80bf99d52a8d8f8395d0d96358ff2c45ec5f59de42b883102ea5280d2ac6e688c9ba4e6bf52edcc10aac39e3c22f039e3a629aa63d7394583a7ab1ec85fbba6d7a40501dfb429cd0df76849ed90d4aeeb8cbe51ee8f289817c5ee7a4ed79f0558484a259ffabcb6e63f35cfc2d2776d0e8e2ccb9fb0e8a2db8bb6353d0eae5ccfeb4a04373c0fc606225527360e639223ceac81629bdba6f0c4efde84f2aa8e07f06e56fb197be31ff98ae230d4df686833350c451be996cf088ed07de9e508fe3d87e6b25b70ce2be37ced032c8bc1d965cef86b7d9c473226f0c27e30449914ed814ad87346257280aeb40647d738f819d84599cfa4e21a10f6b807ba4755796596a8b376278b76a726e46d6b21773420ffdbaae2e926db10cdb9029a3a93de02a355aa10d19b0ead3738376573c272401b632d27ac0724dd14a9b07b22f1011f86064c30c945bb4d4cdfd50eb93241c374a7aa46a459a437e4d3c260580c440f22323804122dbbb68a6c6c34fc5776a2e6a49bf92a034b05c89d0d57e24674b76c0d04effd7299e3994a390250ccc6675b046c224366bb0b5e227d84afccd67fe5dabbf0b6fe2d480e22469add649444429af48ed0118bfccbdf500f8a4486e8cc76dc108e4f8e61b055077b54b4f01cc6fb1e73716400f3d35902c6c70ad3713b5613e296c46a7ce6fc110b64a9c9a96531fc1acdeeca135321c452c7b804b8da3b2a5200b8b96b98ba03f4be62119a00bb7e018a0e6f9509425274938136f4e6ef0ecc020afaf5c58d87d2c65fe67d966515507439ceac8382ebc99391a66a09131c2aaca6a189b9877cb3210e9d26fa609016697f37525592d092d37e0bbfed4ad1d1cb21d25b610f220d136f3e964182061d9e469259390ecc2f3c838ba72b1246cbff034fb7ef98d369be118900aae502a16f90d9ac91ace0ec3517cedc80c65ac43f66039c6daba6a74a6005e364e82f4862ed488c6939770cc1f5d5ae14313d8b61d40c1382c62a5633be62c1680597690b6ef637ce47ea23b0024628d07b332ca752d0c0e5d15c0041b023ef72e3b4bf531dccb32c33721784458e0d966b39d527328879d12c0c325cb601faa41995a0b256e2968234d289269863239f9f865891dd66f0180b8c2921d317d9c03e3a23b9c5429bf51a78e5ca5391e46c739d3aaa07623f6cac2e31da04c4eca805b385bb607ecb9c5a215525e2af0b25d468d88ad5f183c6458f70b5876f50d78f31a5b938f0c381bb70ca801c01cc44d9c9771aa3f573759912311db57f1198676b5ba6a7bc63d67d13445c43a8749e74261b15f5d0a3b5cfb9ffdd0433a77d18e9026b43507920e916dde60543bddab472b6078f39685d9c8947400e4c080f38e5182a174afef586433db2cfe702ced6511d2f5ddb5f6f541dbb5aba75cab1eb14e7d3b83837e3cc364dfc9afdb00eebf02a6dad255716542199fa5889add195888506a2e00f10e49e69dd0ec290d9bc3c662d4e239faa874af12fd6a17adb2e6e25e7c5bf91efc91411eca8ea31c00256eede6fef03b43d9c7ac00a23cc5011a17af7b3380b4940ef030c30c33cc30c30c33cc703cfa185be766f66e29e9fa6efdf70414eacccccc4c959f842ab6cb398aed728ee2bd2080078607b007b68eeb86090de9119a7793cdad8ea246201fea56348e4f111a3debad1c424389e07ac8bf7014161d42fb917b83abc89603154233612cc390e1c4d8d6e24083d0ea7bce8db4bd524e1e10da1c9eb2fa5b83ca9034417f70c3d4283639d6a40fea57f9cc8f65db82d58333de149284d99d9f07648f54d0ecd9330c7770f44eccfc7440780c2d87bf4ebec941fee1256276e5e0260e4871374ee706c6ff4bea501b78559a35e32cb935d8ab2bafa65c93140deec665a5d90c5eb3ec4e1519dca1e1623762e0488a79260e832db53a5ff805078d97b363882c31e602ce6148c13f6235de02bfd253aa3594056ab67bbeca4d1aad8206335137a3e43caa704b5eb30771298d5a2a8a9093e1fc848d252af2e4622df213373d05492ba3534cc1496b79060e4c764164295a29ffe4152f5392a2cbfa188864448b943346d1b4066b201ef137c69ea268bd32fcac9453e8095a86a287137422a418287adf580d93296af98936377524e253f34c7b81f444279f1d912b4988a712086427fa7ebf8a5ede99abe1e4449f739cd88b8ca347ca6da2cda90cfbb2e3ab01a989fee7f561f5a570b92d44c880cc44e31de7418392a81f31582815564162a2ff70e0793d1b29c84bf4b83cbea7b2d8628b0f5cb1455114a425fa4d198438651d3364453830ca06598936c730fed0e322659094e8f72d2a68c84e02a385e16212fdab04cbc8302c944c80314849743af91cbec6982c3c127d4f639821c7190ba52bb6280783848422163d61a1248247f4d539435f6278d4f860a1e4881e7f8ac9df75f4410835a299cca854f36a6898bc67c1c516a55c908ce8e27290a4af295e615a44737d1d2547b662fcec7321820f5cb145a116a4227a198929cb5a050ba5c1824c442fe68f634a8e919024254122a2934a0f21a3470b2986469087e8ba4d5c11a421dac8ab51d47a46534661a1948577318c4e9085a8421c27b3f02eb6e0e28a0e3c074230e8074908c5f3630f7b21e57d10aa64781d7ba9d515411c354f6609e1f10dc429a2fbb6c789116203103fc8d413e633ccc03f701d2ae6ccecb6de0fc33c8ef39494c4fa6023ff5c9261a9e513483ef41539e71bc8bc667df7d0acceca6988bc97411584d4439bb356f4ccfde4a18b5d0b31e2af3a0e173c741e312e9546ec481eb9437b9d9b525af767bc6e873e364aaed89eb674781d9a89e8d0b7472f630ca7439f2bff6f889779d5c3736883c4c739a776a98cc2726862cf03192d390ecd8518cd4146c9c8c784439781b4b5e7c9b8a5e01bfaa01fe263495cf36a6ee87306b142ccd2a71db7a139f5e9f8e32042c68a0d5d58d18c4a215d8db3862645372a93bc714a1e6a68824c8a98f23376494e1a3acf3219af7eeebc77d0d049a5907b3e328f85ce19da779851f4d598a10d930e97ee9862ca656875f2ac6f747cc972860cbd85fefebc9e3286b652c8d6ccae88a17d5f0f968137aef87d187a20d1cc3fe6ec65efc1d05883a89357276570fc17da14b7a722c60bcd6fa4a9eeb6ffc55de8a1793e7d57cf6a12e1422729877f7114c57ce25be8e5d33d7386aa165acb3866b38c7316dabfd8dfcd10c30475b1d06589d67929642dc9c02b746272da40b395c9e4acd05a6b74929691cdef55a14d65d629399e0a926375f22e898db33c05fc7d42d0d5580a4d34af28daeed9e25751e8524e512e5ae570ea1850e8b3642031e7cc79429fa94bc4a2729cd094e498fd2445c6e634a1abcc8dc5e1e49c1f84099d3606d61badc38796d0c4c81327e40c253421192e6c044d12faa41a7f7d7d247c7a5943f2303942db9ba42aaf5ffe2e8dd064f5f468c828456835a4fccf6411a1d7cf101b633577985186d06695cbbf6e92561a21f4322926292d85142b1f843e9b5b4a712e40e84c4a47bc75923fe8777d3f7ffca01131491f68217bd067fdb79862d6a873111e34794fbb43d6cc93213b683a84e54bfdb90e1af71ccda2c5fff4c873d0affb6ec36f71d096363c7fffd8de39dfa0cb9225dba0074142ce2838ca78f11ab49da3242eec4b83f6f2c60ed39993e5da19b4216622a6b132e8675ffa41ea652c7a0c7a3cf916e163cad0458541175eadb2483e066bbea08bc9075d69bebe9e0b9a5f89cde71d3a7f942de8b3520a611d849a9f2c68de3b6f65e8afa2c756eab12ae5d70a51155d74ff584fcdc83a928a4e76f53f7e4ede63a8e837e7ec8ca54ed16488775fc7b0921b678a296029dae8d952d1c2e64f8691a27fd06a1555328aa6a3616444149dbecec5d8217e6a3514cd673cbc0ee399cb03451ba941cc78937e468dfa44ef1b32e4b58c277aa029ddea51ea449f5264941d3de244631151aa1e71a6379b682234471320c04cf430be32c68fc7449be462e398b14bf97e895e1f551e4ff2b0449f37cbb4836819c5c855a2ad68295ca63b94683ce33dc50dedb91533891e8489cceddc2946cf48a2cf9f6732cacb47a2cfdb5931d1757f4787449fbbc93c384a7d808f68a2e774cd196a1cd1359c8d145c66f353a6114d6cc9fe58c3c61b328c684f52763ccaa9673c6411edc72c75cd37cb214914d1bc7b8a29e4f2522c49227ad4206a399c0dc7a123a26bd4112b21c30fd1f47e88a4fe5321a96b887e236eaece99c9dd6921da248fcf33ca48521221fac77e9a4134d1aa3153ac25882ea4a4c81854148836cf6554b966cf8aa30708886845aebc610bd1ea6b8e670e3a65c4a5f5000c5c0100312c213a79fc2827c7de17a6c742298bc6e243e0058880031cb0c5be8368e3c6ec1c42b2d3f423887ec6612a0d39849468d406a2cf313f535bde00a28752d19aa9671abeff8776434364c8f80e5abe1ffa6c711e7654c7b143bc0fbd5ec8cd9f71429090e5438fc1c4ce5ae2b181b57b701bcc35cc11a37ae851f030615db37e8a651e7aebd0fdca0ff1d03cfefcb09cae6ee90420000108a00bf301138420157b875a3cb7435156b753747c1dba8c2d1d7443b36c2c1dda933cd2fe32a1913c73e87b5cf4e1c5946275470e4d6e0bb7f889435fb2d7a5b932960287ae4284984b33f386de628a0b3133e386d61a9b05dd1425a6a70d7d1ecb293776776c316ce83724cb1afab4a8f01a33f249a786369c3f96e49d456296865e245387cbdb327a1534349729c3fc41e50ccd49696e104374acc89ba1472a3f9a1ba40ccd86d9a83129379e4b867662335f55b2f5cd3134313148388a1fc1622f863e67f93821668a94611f86ce4d2284d4d1d44e01431352a1249c5fbe10f2855e7c2ccd624b63247aa18be5601cc5f5adf8205d68f42383489ec3fe380817da102de4388de573f65b684d262f6bea60c9f15ae83a83780a9ecd1d8464a16bd01143554a4c51c74227f2f132846ed838bf421353ea4a66ebc870b5420f2bda3fc3c6ab50abd0f43a92ed4b51a1fdc60fd53242d8957c0a5da9a534a90c9742bf193986a69ea37a4e14ba780cb6b2f750e8734ed962fcc725984f682663cc25392d6143764293d52534344c13ba384d1e27ea4c58f2c60cb3b6bb844e7a52caede82aa1af9443c4713cfac8dc24f440b3312ed7c849bf45427ff132b7c884fcc7f6085df60ddd6f7d698e37c229454b51232f426352791a66f554192642a399d124c591572687d06b7c99f0b0bc783121f4d13d69109a0d9728ab9004429b3b6588fd9d25c6983f681ccfc6394ee12fe5d107adac767bce9688e9630ffaa8a739eb45669424e441e720a772bce1b0d5dd4197f242c839cea364e8e9a0c9e2d515ddbc1cf473a171e96c8c59e2e1a0f714d3291a5648f2b9410f62ad572fc46cd049e5835d89eba1afd5a097f814d9b69e089fd120bdd6cc0c33c366d07e48652933b61cd1c8a0cbffd43e2de911bb1874f1f0b14c66771409066d686d8d559197da512f682ec550211f65c2b82ee8adb4a346df8236bff2a2e77459d0860cd22a9a1df90a613aa6078f54d134ea06396652d1744c21bab21ba7c3a0a2c91599749c728a1eec4f50cf19f5cf628a26c476a728393eb1528ae674cc55b5428a36678c58a9ae22b11f45bb219fbb639992e48aa275581921b5d3c3aaa1e8438ef7e44023e5f540d1851cf1ea9361bc0cd3847ea2df141b49a3b821758827da3c295584c610bd93a7135de497e46be6e1449bc24437771f37f9984d349a9377e71c299ae871eaf2cbd2d02ddf67a2e90c7452e898684352ccae14b237f2fc126d46444f39a7c8f91fb6440f2c738c5598781cc34a34579a9ab91a4889be577b2d85a879d9b949f46be69e44bdf2c6d324d124cbd41f5235852857249acfd0632b79e3090a89ce32726bf8483aed3fa2df98b08c2b398ee82c3e3ed8761bd15c6af5c76c4e88b9c38826658d90d8a067b92fa269601663c89e62d9338a683347cb9bdfd42ffb44f4e13d5ea3f382882e669c3a441b52720c642ea7cc540cd1446f0c363d87fa64be105d6a5e4abd97bc632284e83524ea87cc90924507d163982de6f4cd071741f4ef289be48e8b0aa107a2fdf8fe6fd1980c6f296feecbf80f4dd489b13bf979f67cfdd04e83cd1959a27de8bcad3c344e99d562ca87267f9cc8a830f7d0c5c827f2399c4fee510f4dc830a58fc779e8233cc5fcf0bea82d1eda9910711eddb773eed0679fe7b18cb79165a01d3a494fc1f2b754af6b7568cc24e77f90b742fa45872e25ed78d9bc41ca399a43f30e5b324e3a9e140e95439f35070b3baf39a2e3716845e5724e9a2c387421ceaeb6a9e5a8ced037749a1b7483ae340f0fea863337254ed6909611822d2850027740000cb0012d3810822d2880086d439bf72fc75e790bca8646dfc4bcb3816b681cc6a808bae629734a0dbdc791eac78fc382a6a10d1aef2fd1bbf3fba1054543bb122bc27de26594e780073890051141175a182a1ee8195aa9f83a295958a43063a1c4853fe032cdd0662599f0e4f1106cb145e509b40cea396c94246c8e8512d2391c38c0a503940c45fc96ca1be7628b2e88671b0790c023808517d031f4c0552aa25cc6699112439f92a5c7e70c2965c5236818da509e356afe38a69a342328181af34eff8c43ca345783a05fe8637cd7608e4d20a8175af9d4292ba7b8f475bbd038b688d81d16e5429f92446fa5fcf1f398ba854ee3eb86884f6aa1d3ded89f7128c973250bbd86a9b06fc12486075241b1d0480899517abf47b77c852663240eb2486e6e67b5c61b4306321db956612429fea9546835497c5b74e5cbb08c023081049040a7d07f5a7c4e51baa1396a0095c2b03bb7a58abde98087a06859011a855e4230738d9f1d140a4d0c973fe4b49c537bff84be91e48c330a8f92a939077542d716a3351489696fdc16470b0e145d1ab409ed5b4fa75884abc699093d8e793e2417cb129ab308e141e795d0871c914f5dad2434f1730e991dae4868639c3dbdc87b8e49abd7423b6a51e996ada2e193853e64e8bd98aff7644b2c3473d9a93fbe41c86657e8aa7b2de9b6398897add0470fa249a2a5aad09f4903c7bf59536e4f855e9256454e9e53a5e353e81a464df3888751f99242e793e32c74c2e3a378147a14216b64ac17cd370785664a2364d43182a9a53ca14b07f91519a38e1db913da8d5149cf523927cf4de87d2a2a658609cf39cb841ea6e5f595f89699e34b687ad242af645f68cf28a18de7e31b9264d1d05512bab0c161ea939842702412bad8d9f03115e6651a4730f535f75e088f119a78ed1b1a631c0d5614a1c97231a67db6835b6e05117e18229464983a8426b8a53b9e103c523f426866572e56b40e6dd1c2042b82d0588621493f5254510d089d58bec821a4c6592afb83a633af44947c6ee4283e683a69b8f5ac6783e97bd04c237714db330899731e349259e2216b6307ed6f6a27cdde29b7bc3a68a7a593bf7496837627f2c741d795c2e50cd28357e437e891698810515382796b83be32ecb890315207e7d6a02bcf3c113ee5a0b143837ed6b278debcfe56cb0cc699b14c88138f0c7a6b9c9d338a3f593d128346e3ef76ecc0a09393deb08e626458cf0bda963c397a667ea59a2ee8e4cd73722349cd496b41971975074fba5ac1824ed45cba777b4aa366155d54704d0d5215c93d55b4991a544b7fc5fc1a4e459bcf81866688414527c9336c46469da24dd1d0a7296c9ca8de149d7e690e3b9f97a271d354d7d5b7d80693a2cb41f6245c068da2cd1d3a8986d645d1ca657a860b5f28dad91eb1681986395741d185145f590dff446b12474332d23dd16588f110b24b48cdf94e748ec27cd2c69ee31ac389c622fdb389dee1c7b5a0f9635a8a9a68a36bd6d8df21aaa77026da5cbdd9eb184e8695c74457f192ba8777556cf0126d65d093ac33e73cd259a2ad301273a3101353e354a2f309f91673c70e5298127dced5172e7c9d0419752811e97948a2cf08f958125112521489b62a870f3bae797a1990e8e34ab4f4cafc887e73f484508d3c23d138a2d78e949833921f89e14674115ad167ba43c6d818d1764c21787556cd1a6216d17f06da25119672e328a2c9da5e9a42ba1cc42d116dc630e60e175ffad747442bc1e31f446d18ff720ed1ef3e8ad2fc98e79a32441b3298fc62d992e5140bd1e6f1a029bca5235f94106db258b13b5cd296141f44134cf3e6ec76d790344134711be7b9aecacaee02d1477f0c4d7cac634b05883e855884d849b20dd63f742297b1e7dd14f5a3f243d39bffe181c6ca3166fbd0c78c3c94794a54ba7ce8da61ae2c51c2e449630f5dae60c932de49aae6eaa1df3c195e56e8c53c9f3cb415dbbcb23a428639830733f44b21760cfb1ddadc0f9264e7c6153e3e03dba107d12a6bd278cb93b23a74164cd4652fc57c9860a14487a6917ccc19eb5bce5c4370b4e039f46072a8a8e13fe5eb170196c3302bbc7806218c85920c380e7dfe5e44e89421f2c658285db145a96238b49e2b3497fa37a8aa7207fc862e96c6cc30ce7ea89063a1c4859b41db45088e1654037643175af625c7a60821f65a189c40175a6ca1dc0672faab6272885d54d980d9d0e5f41ec9c9185768b185073cb0c527751182a3c51a7a2f4996653d54e4cfe98016ce8546a008ac8636fe573ead0cdc820b0d701a5a6df76baf52cf700ecb00a3a1c7b9de21fc5cc73e0c164a21d8a25cc16768ba3c78a49c99a149f165523cc728cafc6568f263ce304b0c5177dbdd0293a1698cdb93583a6a89ce185a4719597a8789c5d0a70cb6322b7018baf00fde4d53e3c8040ced75a33cdf38525075f017ba101db5c38e29724a8f17ec6e24e340017860045964d1852e825845ea4971a151d7c89134e7d492744c048c08b2700a6c03780bede7fce09aab167a20f32023ef4a98f4b7700067a1dfb83c625a39c6425329e3b3eaf8a4f9295fa1179f7c106d22f99e652b349525e6f087ade6c9147015ba103d95732c1553ea71d3802cb2100102f81e80812b2ec0546853081227e20745c0536836de1fffb86809029642bff157d59671a4d4ae071c70c6516867934954cc48681c6528d821844a278712262e3c404f200138a18b169d0cbb32a3a7b609ad56b45cbd9e1dbe419409fd37aa38ef07f1123aff907365ccbd127a181d34e3cbc9a1cb93844e563af33be325c46524f46fb2418345ee088d24cf17536c673c602334667db21f3bcaa43a06042e421b1ee3d69c5346f9fb418426263f98945b31aec50ca16dd8f959c6fb1eb0105a9590f366c722e3afed8083d083ac6f29721aee6f06e78081d044c3f78c9d9072c607014cc0c5047ed08f47b1ca1462100f215a5cb14508cc0ac03e68629286bb52f91e74d15622e13c6e9610a9ec22045c6cf1811218dd651eb41f0d92bb4ece5758b150eac2036ef45a880001835801bc833e9eb4a5e48a6e197944c0012d5407c83940c601f20d906d805c03641a20cf005906c831408601f20b905d80dc026416e0ae025715b8a9c04505ee29704d815b0a5c52e08e025714b8a1c00505ee27703d81db095c4ee06e025713b899c0c504ee25702d814b82ad44d7b8c167af18165a82a200630e584ae04e025712b891c08504ee23701dd1c48896fbc5a1a7e7cb36a2b90ecd979edf33f0ea0ecb081defe6ace8b08b68665cbe3b38b24e899f1a56116d9658191b36116d903c12dfa5afdd9503c322a2f7aa48cd19349e96710fd187206e39a599bd9269600dd1b503f15c210e5b704001f96211adc7e538c9a02ba21119f7a89beb5de948441f979a42ffeca587f205221ad9528d97518e082f0ed148ee0ba65ebdefe1e70f5e18a2711d2b8ded55d2a1f4c18b423421bc6545f587869513a217cf943f266f8a1acd178368561d9f578c9a49a2e485201ad916898fc920a2795e04a20fc162fecb92636a905f00a28fc1323b7bceb061eec51f1af354eb3cdf50fe653f74396591148ef184177de882c7dc30135ef0a1d99018f443671c25272ff6d007cfed0ca7177ae8bab33f735b8c3fe7a1cb913bf94744dd08150fed7c481e17f244b7d0b9709279875e63638d1ffac7b44397b16b889032ca088c651d1a1f178b8f963c89ba7841872e380ed96196c91cfad98d166f8fb229ae21bc904399c462b0169785f0220e7dbe0ac93a744ae1e51770682a2da39347f686a623a5d25307130b921bdae91472b9686ef3cbb5a14d3d311fecbbc63d0d1bfaeae83e3de717d23f145eaca1699425be2963ac2e991adac8fc33fdceb8029bf0220ded6445fe0ca572c9e744e0051a5e9ca1897c4fed31d30db816ee0115bc30439b428750d70d3bd296a193c6678e3f27c72064e8e16e980c25a76e772c164a6368277f77f4bf440cfdf8ba5978702d2107c3f0220cad47c716df9b8fcb75f4c20b30b49f2957d9b28f4ad2fc42d78d2ba5529e249d42e984175ee87276658c61d9852e788b05d9506d71a1d1c8b3f929e545cd21442bbcd8425f9addbcaa73aa96b4d0e51073bce80d7734bb2ce0bfd12f2ca4f2020b6d89e4f7a9142972dd8b2b342731690c7f214ab9f7c20a3df090961f7ff04515ba3ced6495e1e705159accd91647d11edbcb1753e81ca71c2cc5b8d497ea0b29a057e6d8db27b77258f7b1cc7828342e532905cde48b27f4295bd0974e8f13daa83ba5e2f0a1879db3095d0abd3efb196cdeacbe604297e23846c6d12a1b525e2ca1b9a0b329a6725e28a1871f219fc5ddb610c18b243471e3c7678a21468a267881842633789815938fd09f5f8e13618d827a8b8552b912bc304213d5de71627b5184b662c6134dfbc242a90bc7a25e10a191d20aed88f9118217436835c39883f8e96a0ebe09c80b21f48f3be98f861d89218685121a75c10d7811847e3a2654ca51669613bc00421b2fe6d4f9602db6e040175c98a305bcf8419bc1c6601a2d3784b9f8a0d15cd1111b553d68f29f452f78d05839d2cb783af56a1278b1835edf2f4c574236c7b00e9a1c2d34f0cf991c3429bb4e8e2a91da41060e3a8f4dbee6d538870345cb5fdca0c9d4626ad52a2d13b3012d1c8ba70ac0041230015200b8e0850d0a998adb9b15828552084c174ba6167851832ebfaf59643b481edf185ed0a0ebb3289d537f8ac7194afb000c5c31801733681a997be3ec34d3a4074c08146002e7820b0210a068614250827e43812cb2700f48208b2cdc035d98145ec8a06dcbe21953e4472539066d8a6ea96223b333bc80410fc232cc7052d8afd4d90c2f5ed05c54cf78982c2e687af3ee664f9a2192dc82f6e18f85056bfdc84930bc60418f67c39865b0aca28b89f942de0c6721e52f58a18a7e43a7fcbcda21ec7752d106b330493de5711013158db8c5a82d9de3717e9ca2b58cea2035acfc9e95291a537f29714d6b608db2a2144d86911c68de9415a4e84379be07ff09991128005e60c528fab01b728aea5839fc58218adef7fd42f6f0fb578d5034515234c568884c6a48b002145df52691871af327fa682fad0c4721969927da994671e3ff9de83483e4eb6152526b86159ce8f392680e3ddb17f5b209ab80159ae81cc967d58ce304fd7733d16c9e2499325c44b00213cd8bc766bcd166eee7257ae08ef4620cefbe214bda8115966892b59a876b3f4af18295e852d6141a2d2aba25394a1c2b26d1f7c430d92b24d15b87cc25eac05a3c6b45249a89915dd12cd515a358286d5144a0002b20d1e6ba63c7e07d260b042b1ed14a688897715bf2383ba2cf1796395ecec042891bd1b77a5891486d871fc142c96e600523ba902f326ba59ca88b682b3e8a1247178ae83f2e6f2a0fa9b3859f884e52069de1a59c320af922a289a417f2b487e85752d228cb65d9c08abf62811585e8743ecb356b02ff0021fad2a4317688c1a252258b2c4c175798400464106dacb09bb28f859209c8151f10c1165c6ca04a106d96c5c50a1e2c9488506045207acd323b71e24bcce15a88e08a2d8a01a2ef4bd267b239446349f5872be46148a9edc06f91c559e1871ea8c4a8f3f8c17ed587ceb254360bb3f8d087ea0ebd1bad6106b5e08007f6d0fecba306973a7ae8e1eae65cb9e1e398a5811579e83fe434654ad92db8b8c20495c5165c201eda8d1911737f3fff576c513604268bbd431b36fc638c3fe9bc1dae8e950d164a4732b0a20eed5f849a3ec89291a9155841872ebc854c27f17f3c592c943cc001b70f3809bab8e239e0812d42e04431b0620e5d48922286d119d788b230af855b11ac9043ab95dd23e6e72167e3d04a047f73af2831f55798116cc1450fac8043937b1a26cd78b2b954c8032bded09a658e1eaee9c015563ab0c20d3d968b611fa5ca14dbc442498b2bbae080156de8bfd563634b99728a4ecec00a36b46b91a939639c657f62c51afa2a87922d4d25aa3a56a8a18d8c2221c88bc76f981569e8a5f39264f8c40a34f42df30d45d2ad627c7060c519fa8f965e95dd71f0fc304333c95546b2d1042bcad0b403118f8ccea0274786d67b52d6892a213ac61943931a78a85bcc9ab44f31301fab7218da904a4dc3e56332a360e8bc3ae6d4255ddaf72fb46e3197acfd9386102ff46a31d7bddc524c96bad04494f43f497983cc850bfd56b6368bd8a94367b61088faa8a48e8522c37024188cc30171308a615aef01a3140010002068681c8a44921846334dd81b1480024f2a1c463024161c202810160e0e85036140180c0e0383c140100c0603028170182c160f44e40f32343bb919004fb7340d7ec15f88ede742830afa986e3d94d0af7a8c0ba825a42db4210eb9871ed9f85cc3f27acc7e0a245fa2113bca081a8446a7f2a42de98b0fd8250da9c5ef5f669e9cf7ebf6ee06043556f3edcce2173e3ae7f75e1bef50a25200c128a1463b3d894752fb9bd3669799ceab14640a976973de3ab8bdc9f07cfe7ea3735b2bfb92fdfb0d825bacdc08f757373e375bf9813d34dd9cb8444731ac72894ade758d8e5424539c19e16f47a3f0697521baa55f58ce087aad96a942706939d62e71518d74d3d7ef0295243d64077ec09aa22b491a6552a6462bd3e7c2da256a4383541393802d8ba12f183e40ed1d1244c69ae0bb17f1c37f6679a61cfabe97739a66a9170651688dfa3a4ae8ee60d80be8c82328d926a508edd1c89ac52a7bad3cc6f69ca4ca04cf35199287021a0a5614ad8cfad1ec3020431bebbc95302529b176df0db7e01bbea43d620017419ee76cfa16f80ec56a15a32b6dfe5eea8eb6aa557165be31aab4b168b56208d2701a8c50e4af609686040bf4b39369b1a22836a49e4aa10adef69192c7402eb9350a1a24f101b8a821dadf0a07ed52567e36778d54cc530c77358ba203b4c9ca7d796912c7568c7d1ce220282fddf06be03b8fb7d60baa7c69265ad0f3d7a2b3a270fd2c6b80ca3c2408ed916cf492fd589bc93728e7ad8626b68c85aa5fca2605b45a9b94065c6c3ee9feb119ea9240a67fedd399798298acaba9743bab1ef979c3f064e123675fecb982b291750f2afda16b60389eef56688fe13040a53d347687def84ee81e685726249efe896dca3735db51b96362f393a6b1108c4750fba79e116b2daae92fbd65454a5ae78ca6d156c89a6628414b8ddf2907a12a272620ddbdb81c4541a4821194a08694a18bca1dbc0d99475815ca3e4a6eb15b29d627c1030a421467950419629e02c4ed6e20fdade6a6b9e31a9dc6e9fb8f6616305dda8d0c8653057ceb0ec548a603ec792d123b36a599e4ade19535e201516bcc5328b59d1efd3f81d0fb02a87db13126823ee26a4bad180245d007aff4819548745ddf4b805348cc79fb8dc5c87efc183d17a9904da6820a702297324343b354863da2caeb289b742a0b3942b33a8db0c64552d526b0f7acada464a63972558b99042ca001c32861e736346b5827bc346fd6cdbaa8ff2a4b88f9e525151cc90ebb226dd6266dca6dcd263a92b0f00fc36e61145691eba83cced5ceed73c511f750f4e1f71194eb8865a946289f646443ed0f1e3bdff0b27b0b0bd204669370b1ce39c55e7c2cf3b48ed94878397386c5c72a64136e3644de9a2cdc65a4bb22e9d4e3e971ca283bc2729bfe1784a62f13c592d9c364e26b07542110484a70c8445aa21da758ca7f0fa0ade93002b8e143da32a97957e5f7ce72c127e781068d8f4676b8ea0612c20092c79428d27aa8db074ec6b01a6b59298ca99140d114b16d1e5637970ccd60a8dd30f14dbe2e0fec65106f9f25f417926153acb1b77dcca9046881adee2485afcd9054af2e22e2eebefe94411783a67be8597c4f080f105b65df2fbb9b4477ff98f60cab971063b6a6533ace85607ae1d427718b4cc5f706cf2747c6b32ba99056161900a0ac5c60e39436d408bf2b494e1f8d93c516e310741473a67df1b6e74e51384dcf90c4e387f947c38ac8f832415eca5e10ee1c72042d26cc06e8854d42c90072220347b92ba69df8aa02fa0774ed6bd6689149d20c006456301fab337035dd42221899f8c68ccd671227375ab3c5a7a065bd82fb5b690269789934cddcd525703268f6122ca2f8f531a36128547d69a6888f8d3fc59e92e9d7447825eda9f1215ba193817c8dbd87eab9d53b9698165046c9e0df9e9c9582f2241954e238a794a92c4f0610809aab6c4a2475fcea805c2cc4e2bd0d672278547c4c43edf8d8c0eb3b357a1b1ce9af4412f31969c0e8ee10443a4332574641b16946d9463beb13bd21c4d541999646b90507bc4a3c57bd8bd23df9368b5812e93aa745094f7d923716251220f9240954c7c8f9819108c50b7831aa88408d51b4f29174b2be930e5dbfccd479368d76146426e024553ed9199a8ed1775d7fbc41b6e9f33e4194d68c02b31f6f057f3309f578593800e61855cc71dd7915cd5ea4d70c084662f208181b63b7257843f8a3ccfc041ab6f7c1d9041431ce833be95c2a2a666a52c6c80e726083c3e990840a984e7b7b113bd759e1538894f4df1c540381a3202a057295b50761d3c221df1c69c36763629e4bf5197537852f7a0393e23923835350c4129fdc5423800677750904376e1fe7cd8e94ba56654a39b3ac906bd65b0e6021b6e97b46c3de3a6259c5060088368fd1e31ea6d7aca7dfa820e32504dd950f12dc2bed41e01d14d84427060d68d559e5fa4cf503430e86960163c8bc0d6716094ea2755daade07207eea1307ad3aec888933d243a5606a8f5af8f22c1929bef4bd5d67f0a149a66346ebb8172bf5f173c136c428897ee8c6c08eedb798a30df89083b9d5b4811a39c1a14a59a5a1bc3fc0eb5a1b7faf32efd1007799d7564a3e380dbcbe3d9751516a8d2423d0d5452d30d4f8680730d5bdcdc53c860f449da8072d77064a25a14901521972752e97a150b83aaeabc637b714a07a218023f2a772ac87d6aa55e50bcc73e7ab312345d8e427421b4c6b936800a688f5624fc15363ccbcdb908d7f37dbc664a1991eea25a99018f4263b081cca242517f7be5005d6e6ba055a49149831412f46b6c0c5073aa3691cd53e7e2a3d40a00fc64b34c8673aa95c502609d6a3f3514f87881e4ee01dc4d7f8d481fe67281969ac4d102450aa3da19d8843bfa23ad209e91cd6aa832f1d746f7d8ec8e2e0f9443c2489ca7d5fe2f1339b76e5aa82c23b600b7027a97a361c48e0fbd2e02fca4d1951e20589db1ba3dec5105e14a7ddd2776b640446e74bb222a89eafd3248e92db03c77677de3e060cc224b01ce9ba322092125d719631ca8d4c4c44e6d6513dd0b7f83adea0052a6d6a4d0318208bcb21eb2978c7c9c5637583b6a386f013e72b2fbff5bd5fb8416b810139ac375ba48cbd525107acf47059cb7e01b503118163dd7e0f5b7812f220139b54528cb0cd2e7e600339bc7b4d38942f8af1ec1a74bbaccdf0bee8d3b695726d86a312902d027ca2be351b54c0a5aa37b719a1b841c5116af47f46fed5dcc85c728e61b1217d23e2f8b21d5a9d33c135d8cb8fb1d0e18c92a0e5b152a304ec5fb7eb021a654968d48955e0fd5d53e67b697e652173344a9c2f1e89b2fa1b5e748789ec26d89d44bbc7f4ef249cc5230934b0fa9e9e44401db81a3e4e5239d08119a91e62c256a0d572574315b6e9cbaa3b7ff8b732ad64b972b0b65679abb17735bc43ec56a9587dac7c2b8995eeb71a9a86da07766b35b2c2ac2e564a5633ab88d564a56625b41a596d568a5622abb1d57084eba41bae86211d3b4882a4697d76890cd490c42320dd381f9d4c30cc29760bc72a032818e4f5383977ca3b8a6ab3e7854883a3a250ada8745447ac0ab4546d1fa2a820ad1282d85e2044a4eaa34eea350df2f5c2622a3b550e556f95c24a095560854745a2a70a65aa7f62cfa078ae5514d58e2a642aa1a705ee7b4e05a986a8e24625f43e8b62ac2a30594f8761a8e2a20a041654c51b2a575542bf267ff6e9aa8480b252b1ad0a0cbc9fa993ca302aa184425547cc5540f4eb093989eaa7eaf5aaeedeb417681a19ad5780f1c350aa3e559a4a41854d3550394125147af022d0ad02128afcf9b4a908545a896a3d1663a38d4a05a2725059a85e54e5584d543e2a27d517d547a5a4d252ed5115a9522a199520d596aa61a5a5f2a71a53e556091d50b60744520993db181e2531934d5bca5ad16c3c4932b2c8bf5b537ec670cc98663e87d5d96f633290e08b275eb1b0118d30e9467ce18776590af9fc3b38def79eb08c684208ff66dfa56bcff329667cff410ff651948c4aaa4e7cb875ac1687e6ccf0295ab49c96fd8158573e13840121847e28665ede97132cde3e6fbf1a084f549bb297c034b46c4e24ea5c256ccaec239595419ffc3dcd500ba9757219a6636924a6a2da3a0e1b3aa7cd069b29e90cece2b39be3d5163edaac9b476ed4a53e89762e2da5b732e662815bd122b4422aefbcd9543cb4e547efcc0398919b5c6cfe9fb01eae88d2c126abd4ce9d2b4c29d798f995f6dfd8653c4b7865e3f6d001e251ac46b993951346b41b9334aed07f69a7d7c4adb4a581335d7c0efb9f56450623477e3b278d6863daa7268f6004607b5b6a217f365d291e7e64cbacbb6a7c8d4da8eb353f05061c70a6516c079e67b50cd6e49ab568b4b76f607c1fb7c96ee73205d9fee5815f949687ca3ef135cee6694b0d864f55c11652ea88279b8c89e0ea11b5fc6268e76821bb733d42dc10159035ef1fe8e123a32f7299a90df55949247d6bd736a1aaa5ba5e53a655c71cc81085aa53bce0a936e96ab3cb50e1b60993722740fecccd0a7e7df3af77ca406cac51ff7389cc244b1101fed0d3655cdbc26c5b1174415802f2b10d466e9c76294abcdcb0447ca4ec17ff215029e0e02b5a641f99657805f2d005a0107216d93de996529553f7f729517fb99769ab965063c20b809b36a1d8155ca96c48ea53f0fcdd7ad78ca1d1a55bf674aade6515fbd710bc58a3790184648617a3a97149989ef1238100aa0211c99105bc709b8800694f17614798fc02c49c738fc194d42eead80d072b9433632e849afb0f5559c2ef8cc8cc01a5b90595d45d9570f91f45e82dec0b203c59515e41e03cc400b4874af757c461edcae2b3390c8626f2f3d3b289da18d8ced257e41fc74176f293f7bbb1c2e810c4225a3a205810b20c09270101772806c955ed3104e0a12bed718c568b33fd3956a6eb5e9a3b0eb8e15b0584a4b44503121ffb3190936a91c8869350745f5d364f80a0c41bf1861f504d51ed79b310e2401aae3fc0b97118e209801c20aea529307ef38fb19002cbe65bb8f9879c95e5ac08a655c4f2a8f271904bb8a988343d7caabfad0da5f8cf65838001b44aebf16b56b770e82cdeec8019de64cf3efabe4b800c08003379bb887ff7d35507d9d31613752f43d48024b7c73db63810a5e6ae4f06abe205700c4401e6707dfd5c048eeeb704ff074efe870bc99a5fb0beb63e317f7ebfbdbe4f7d7c7f18f7ca7ee1fadafac4fdf9fc16fbfef5b17d2c28165e03b5f6b78a7b75bbeeb47e6b951230c7075129c46c1351db08d14a567c17ba3e42a88a492bd340941e0b94609bc508dd4262407240cf9d800efcac5c20a341d874ec6be1c0e1e22b029e9a8b47c27a478fb3550b143a2510a6348ef54ba80eb01bea7e11027300891988b43cf8d6a76991e19362f26b617030b001d244b5dd21a2402d23e68349d5dacc1f4e81b83bb457ec098bdcf9a27441e2b38075e0d64cd6d9383da5d8486d02201b89ac610886afee6aeffc58c08713f68b2b2f9450bb086d2b62b2fa8cba86304dd023c2f15f3d61d13c0714a5d7fc7a5a0becc66508911b2cf5977eb303cd29dcfd290dc5cb22d1816d1251216024c52a7bf81238321430b484c2113df3024849afabf848300eca0c1950788a2d3a8a4179d2753ef3df31146c32b6179b8ffdc6f603bb00288e1f62c5c67d6c0209224b2f149b208aa9d0b46f5583d0e649f7b2b85d08bca154e608889d0d262dbaf22eb73e3055d0ee9d790dba26d1eef926d095c48f77bf6f7d8765181165bbd94ed5a8be7776bbbd1dd6bb1cc67055e95963dbae77706f84f7a2bae756684bf7852e85ec5640518cee99f73eed2df33a7471dc1de8f5d8ebe3fdd47def2aed55d3bb716fc5de6cafb05e85f79e97a5ec712c6fa4bbe7de9c7e72febbd2f666ebb5b97548bd68de07efd62bc04f18756fbd699c67bdecad9fb57a47c7dbbabde88c15db35dd86eeb56ea2dde1bccbdb292412aef756e80db2778edeba4375c75351175b73375459466fb7eb1aba1e5db9ee8ebb01de21bbd97a8ec68ed735b6cbd6de6cf3e8b71f4c5740379eddd726d1d156f2bb957a4ff70ebcde774ddf5bcffdbbc3387eeb47ff3803ca75eb12a65b40f3d5e226dd58ed9e436421ad317b0bd29b0db0379f71ec85de2b73bdbd6056d96f75bd127bb1bdc77a4dbeb71e02e6f1622cc117fcaacb920986bb943a2e622945bf2e7b3211174914d669305991146c49d4fccbca9f24e42cf9043c9ca76142c2267190f8bb249f66316a573cc941a221b13f892a816a77d6c43b4cf45796e73f966cc82964721f53b47adc9cb0d12f0664f2470644f507ac414e5e1f0860f9e38f7a175fd85eb98c0b88e361e5a1eb6324484e64e0c7c9ffa6c8cf1fef8673ade841b98fa567650788e981491f4be2765793e3210a3dfe0881ff26dd215b41f422120f93c7c0238fc7c95487da34d88d524df842675fa3d4501826d2070a30c3657ccdc10f6e4c8ba613187bbc4cc29fb260ff71128a118534a8b48cb6a88752146e9779af872dae76c3e20743bb3297a190c96063efc4630b64831e9b59c0be8a9dc98d2de475c2600175a53601632d6a6e34220b14ee6f50ba0da3295214fd4d69b44d29f702caf176602d74f081884722dde8a0c89e4ad81bea5f6b9acb52f5c03de799005d29b92d4ab2fe280a8d41ecc34abab949be8bc725213bb80fd5f32fa49e1ac4a693fa901101a928da7d828f72d23e0245122c2e4ec131a70d205451829900758d40dea7e57b3bb9c9334be8dbf98bb52e0127c8526d6b91e8bd8d81dbe94354af3c9a973957c4521db33405cb243027342abc02f45d0002d5b72e2ae1ad10e0b89a793285f318dd7067093c543df3cd2a98893725d6230777715384cc5b946ab73f4972bb03e7326008042627be6ed2ccb9a4c5770e5c46a362f460d71ac206d0a1198437ed750b2897d7f8906fc23f215f5df73c0aeb6e0636037182baabb711f75737759ac5c0fbcc2675e69286e7c3097362f5c9cdd6840d6cf97d812090e9042372fda4256c60a3c9be6273d16f88ccd9c8e5ca4bdb15a9f64c92b2d4c4cef9bbe54513ac67d4fa1ece46d5b875813dbfbad74c2654d3e5754e00309c5db3319f52be30004c6ed5263a95cd79dff9a2ba1e4fa0f785288998e3f094129a1b9d321577c494388a38194c2a1f1dd96db80b67aff10f4cd10a51da130db680d5274f21041a4099338349abaf908c2d5d1350f9d247932b192116422532002388513280514b5c4ef3395628d904afa3acfe112555d334b8e37626e7a6206e3b29a65aa4f8a478db0b899f39c3767e624a5b107a3730e45ccaea97db56c686b705a2f92ce7d886e40c7e9800c75b3d1d18643ae192e97baa9ab2c371ea5b4407d6b116251c40b1e7af48b2d88743e4cfe978e1e6cf93ed0f529a52d6b3b2278d769cbd6e1a1c111d403f759563bcc86f1ec39c3d81c208a838dae2a663ce5a6c42dd44719bb00a9a11bdeaae4f3516bcb8ea5e6da2d41b6fd53decd171ddb09f4f70bfba9529f60e05b8b29dd0b65a4bedb71e2e8d8db6352b68765d5fceeae30cdcf678b544ad2a1473b15508b69eaa2e15aeba1a3147a3be0e83366c751b527b352554f37dda7a232bbada9b6bc14e6606a441151aa1beba4d96f7595f35f854ea4a9fdddd7cb466385edd622efcf4155b71b939f586fdf4abee09bc37b9df7a910baabae5b8c5aed58fabb57c9f94744dabd916c1eafe6cb00ae3ab554a33556136986ad59542ce2c16d9455cc155f732980eefaeff19ef494429842c3c6dbe4cd85a09d45352ce00ffd04ee5ea8033b81ab48093e1c55ef7a94a282aef955888a7f19bd8344852423318efbef423b103b82592fa5b061f026374abd2a852e92de00cecbe25af66a82d021a3f678db71897b3cd3900273bf32544c8c32003201d3e59e557f0c6111688fcbb418858da3c2d41021b4c090434ce22ad6b7b50c571e36de8984a79095fdabf05a8492f1cf18386fbc3a62164f35ea65d158410f5199bf206c3cf5e41fadccf1720e6941d6d19e0e46788c6e47c3d9dff58ab18f5f4e07d27aa37a9dcc4cef45f7c17a0ab0e438287d165b2d62b0b2c734a8064e35674bced13bf88a4cb4d31067299b3d210ec92886698e8f5541295c7db56964ca951964485c2ea86fcb69e53c02340a77c361d0aa2a70ebb74bee60f17cef07d7618fde9d65dc42f403e4214bc2eba4153d93dd2eac6eb211f261c402f65dc5f7fc0a6a5f66b71d209bd630570a2fee27f7dd0281a7384d0d84b7d0b37005bbf42790a2cc00b9820ea3946e151fc8429797d3214e1b04dcda4e217549f52faed6b9ae5d9bc785690b37a72e62af53a3bc05608c1b279e6a7b5b8fa7d8f909bdc2a3495b3da724e07683c2257f7027d7ac8294bdd24fa6cea72ccb0f445e050fa08316dffa537de61dc58016ba3c1c700642030f0188c0c1606aa64b0422df36dd2655032f0196c3e0842f83af070a30ef4980e359202d23603a4015307cb5c24f7cd23c145003e061b585ce60affc118fa2d61a9de2069c01a7cfcc1184879a657222186b06910dbc1c688a265511b4c1e0eb4721031780ddc0682065b83329882aa4f2d27ccc894d39301c1a0c12638b6661aa537206a899f3c06636e375df292077d091110a45cd8ec220a7a96b0219cc5c4c2834decfdab2807083361cf86894012ac1a6153118dc8d406630839e4160aa1bf83374284838dabe47297541236398e60b12800160cf32e2b123a8189cdca371fda033621cc642d9d37cf208c18cc00c739ae08063a9881034c5f3196bf751dd89730032a4054096160e28315543b98c6110fb208f30ef22644105c18284dd8eca574882608d10791266c43d858e5f60b5f1136900e8cd00444ed6467a446b892acbe0898069b1dd6e489a511c61013fd0a8812162480206c35d898e9aac367206c4e18cdf0110f66b4173807bc07921036e3035749d6c389ad114eb37586ca68411e8246099d481ce214b3047910360ba1902937d5271ad19b989cb072a3d2c91d489e1ecf08800adc2ef0625b51b734018904324bad981b3164932c27550cd0958f1c401e4005e002f00178029c75c095d1a8285b116004301560d9014c361d337dc0b3b8000c648dea82550026f25c4cc305c0c88b734045773e4d998c6302fada8b9f3760b26639ff000000000000000000d06c9488b545d2ac4c524a7a00d4ffb5b7847199524a29a5086f67e6f845daf01769c35fa40daf0017f209df09db095fe89ecb3a866653f68ea57fa2c48b8de81043df5a9e5754d27d420551111d61e84b6fd45cf259595445447480a16dd1d910e2bfe7ef05d5d8c206203abed0040d9ea3670da1e9fbf9a1c30bede41c72d2d4911d3944878e2e74252b4374cd5dbda1830b7dd4f86432c66c72962d5be8e3a9088daf17ad4765bfd0a185d64709956d2926647c6a7ce070191170e1e2f5c4d09185929f590a2ab6040b9d9ce68fd316ad6a3a11a4dd076c2006083a503eb2fd3b53c7a4438715fa4f596df2e4b4868e2aa466f1a9a54217ce9308ca849079a1630a5b4593215fbe5439438714fa597113312c7f98ff3ba2d04bfc0e666262082977a0d08e54dd94e13bfc86d4137abddc9758aae767322774328b6ffc88294de842bc7516f1c9740a29139af8221b29bf7ffe4a5a4217a2c7102a5376a64a5142b3e23932e8670c66f924b4917d2f574e4c27ab48e82b7c663921938ed0f94c1c8f9b9465850e23349aff12d32d450dfd8bd0264d1d7cf3a825157922f46649e3e9a09a344b3ec18d1c1c838e21345af6e3279e39e81042d79a23040f31c7b3781a8fcc061d4168c29e070b1bef22e4a269e800421f4544ac0e4256124149cdd0f1837ef285fa79eaf8a0c9a23b9e7278040da51eb417533c79b93cc7083268e8e041a3fbeea14573954a7607bd99969339a42725552d43870e9a98b1c594cc6e6eaacb41a79d37929e2ff9bab1e342070e1a95de718257899c74665be8b841a3a2645b2496aad061834e0521d7b2a4f835c9e8a841731d52f613334288cf1d34e864765121860ed67f31399e0227b8210211dc193a66d0e90d17492fcf85b28e0cba9e68a69392e25d9977c4a0cfd9989208fba993671e1d30e87592124929378dd8a617b41ba2ac93c8e147fd0e17f4d766593b45eef25bd1ee4ac89d8487e7d141ace873ca3a2a44cd2aba0ca122c908aba27d2def3c69562ada705d3a6ed8d4264cfb0215bdc7e61817b77a718ae694ea051153d222b3f8c2148df897dfbeb2e8192d04bc284597545f89182584b79948d15fb41ce67aba43c4e028faf8cce14936ce688889a28be1e5a49c27a52fa75e84a20bab31582e9d63ccf881e2f82107a5338c6c0d2f3ed155c6342536b525dfdf138d85bf944ef4a63e6a218893137d509a7f7664c6579368135e6ca2f9b3b0d010665fb2af89768466f278b135fdc299e872b27c8b17bc83086962a231313ad6d9f4a8d86f2fd195b9b9852c1327e5b2441b7fa3c8d85163cc49a8129dc5d0413788e4f3174389fea299a775f6e75e3589d6ac941e65f152b6f042126da824a2c731952776b79168dc4aeb98a750dd2f42a2ab48497e441363ce75119d5468695a78e18846581895542e2eae5923fad6f3897df2948b9030231a9dbd7b62deeadebf72aff062119d0c394fe6e63d113be82f14d1566586cb25fc64634c22dae45adad73b49ab5344344ae4d7e829bd3d7a24032f0ed18ceeece6c8f92b82ce105d55852449edbe28441f271e9f520e11a275d19493397b83e8228e76fc98351b395e08a217f1e241639893264181e83735dc649809f9df054417640a952a8c56c6568ecf2206aae1693578f1874e3bf6235fe5fdd056860bf24c57e9f8f4a10da2e389c81a26b4797c68db4dc614e25228e1eb1edad29e2d25c7fca99cd443232fec66718bbde0451e9a247c26575b8f87366a1ecf417347f014748746a950e9b94526b3ec5ed8a1931954a37acc9663aa179081c313c0a6858be06a94c0c60d230387cb280fd8400c05bca8432752c6d4a02f49c696d2e10da6beabebef1783458c101c3734687872e142060e97e10fd8400c15bc98432742580ba3279a63951b36520c1403c7231b356c0b08b87021038727c0858b2d6c9cc01bf0336e54a0010d88c40b39f43ee243a9c9b013448e43f3a5730a5984160efdc75610da92ce99be6f683d7fcc562c31265977439fc47b68cd8c6943977bc12afe677cff081bfa3f99bb53c6ea08a5ada15372545ece39ab863e469a8513a331c5cda5a11fb1ff1b3ec468e8f377de9809797186ae33ab93c9907962432fccd0a9844d539e47c59caa0c5df814eb2394e79482870c5d0e5d9a523c750cadf7c7c8cc7545984dc696a31a9f85c7d0628b1afe340e92e085189a9c333ec47c4abeb446c6d6711a5a9030b422c55742b61864cf0f86362b7cbac5ce3108dd578cdac38b2f74a97164f0aef645e00fb88a517178e185c6729e90940ee29b49ec422bbf41fc25cdbce0425b394e9ccae4961bc9175be83ce77c5da91b2967f985169a4bd9243d250b841759e87392c9538c481a9309110b5dd0a3e44ed24129bcb842ff19bb1245e95f58a13fa1df416232cf1af2a20a6d4c3a678386242ab49e2db9c2c7bcf62f6f0aedea64df3c22c8c93e5f48a1d15c5a9a77de175168c7cab4b2e9ff05145a8de69262ec64fa84a7bc7842ab93cf5284a841e78ee5a8f1316c20b6f1c20966998cc724cfd295813278d1844653a6d6121797b1f58209bd8cd2643163d22576c7e14fe3c68b25749d2644f68f2f132f94d0ae7fca9f3dcde32d4f423b523b3e82845f20a19373ed1b3582acb49c1747689245d1d556d1089d92e9f9822a11218b854a785184f644c81946dc641c3711a1f74eaf98f78464d3d922bc184257e18216e13145841742e8b34547c8be9b972a18843e851825f5e55249730e088d7ff0ee513aa6281afe4117629e903935f2c207cd9a7e28b9bcf4a0cf94983187aaa98ae10b1ef49254e6b088e30e9a718ba67a2ee71036a783ce33765f3cd5acea15165ee4a0c995e35b49aeba92100eba10fec428a557e1c50dda0ea2a16426bcb041a324c98bf96729d97ce0450d1a5d61f7d4fbccf3e768a06e8e61f51733e84c6f9e4839ff5250293268942cd9b9e43ae2e72c062f62d0e6d3484127e60fe7261834b12726b95f41eba5988c2db42f5ed0eca8e0b194bb05b3e0850b5a19ff145d7e3ec7b4b4a21d8da07dd5b40413a109bec6ae6000ac6853964e79724e332bb48aae634cd2b9f247ce9c32b66accc8e20da26000aa68546c9811b11f7312948ac6aa5c27753866282ad8324fd594f2f24f821b5b14e0146d0aeb5e39e9df232ea66882c605d79e5329395b8a4e874794a8db2105314292714a878a0c06308a5edf2d47247f4e217944d156f7bf56f61000bc6000a1e8534ab2bf5c5ce6c4078a4e5b30e939b62ac948ed2906f089565b724a912f9e683cb3b4777bf834e9b9a20057a04e3451840a913ce7b530004eb47a1143b69238e3bc0136d1b84634efb5501a79441e0c4013eda8f40aa152939726135dd00d396f0c1f5512c10da7e131723c8ea28a89765436edae14cabac432b66c90600770897ebe52aa0e570dc012cdbe2979d9216274f22bd125a52987ce12449e6c204a34ba395ffe1fc78d1a58b870712470e1026f046012039844a3e4b46776cc4f8d3936b488e1350049f4e1b784552c1d1b59d4b0110387933a010d1a5e01172e68d0b01101172eaa140388442ff1752ea8e59068c35bc6155d16172e1ed17be71c2cc46e896f4bc6d6b2231a4f21ba5ac997e89247402df0a0439f7f25bfc8f01cdab418b3b2020f393449c71c09db6d1cfaab24734ccd6b5e56c2a10972a54389cd9071c52836f07843d71e2466891ae6ac7337f41d94d04cfae794c428c6c0a30d7d862453d079368a3eb1a1b590ad8862164c95716af80d537545051090802b2ad0802b5cb87081c71a3a9d3395ce8c512166e7918d023cb2f18042ea85871ada59b98ea47d79c3e8a4a1ff8d1d2adac3686863679207622d9e77f86c3e8d2d900d0758dd5033b429797ee8d84a61e6df8840d5dfd0e274860870780912e051865e626fd808228666abb00719fa605a2a3389cd1f1ae52d32e031066490b29e8d009a193cc440058f307422770651cd188f8d1c35667880a1cbfea73766cd3cbed088a9c7301ee48526ac853ca2e4a80b8d5cc97153f2adacec70e18a225f467cca6ca10959e5a2853eaa788a163564cc9eb3d099cb06b1d0a808095ee599f4a56825c393b4609d151a8f7ea247a9089563aad0a518e583c459d111f4a0422796a6346572c8566c0a6ddcdcc91a5382574faa3e8b1bef804c067848a1cb902a7a18d146a117a1836815cfdcf2c1f2e10185ae325eb8cec8794233726283ce937142972fce760a4a57f0246f429373a5707f1113fa52b9c143fca567cd2ea1533173f7e2e6e07ea512fa68a23a0f8f24b4a62f7fccd79e622b8f844ec91c322725848ed09bcc2172f08d5ed61b23b4e55e1a52debd085d26b9507123ee795489d0e8fb964c16372486108f217079399a84d0e498bb64848f07a1fd8d15a38809089dfaf687e749cfe4f10f1acf31674dfac90eb17cd0e5ce962b4cb0cedcf42015b379bd7d1ef4712e3b682e891052baac83368b50c9ccdb1cf4f9d52d1a39e65614079daf871493c774837e2cdbaf847b52e5251b744984a8faa3d6a01317e3a65ef7890e0d1a25af73615d3a85549a41a3f96437fe8b0abf0cfaa48268eeec1aad120343a9a8264b250f1834af218e0515e3530479bca08de6ff1daf372621e3e18246cff2b54b4a2bfaec1f42b5b3ac68836f292d22fe2adad312ce53e768e7ef55d1e87ec668ba6265b64f4573328486123254344afc2f6a129554f0146de54db242acf20d61533431c710628691cf1f45a5e853089641729e148d27a167fe1f459f6f2a7372b1fc151245bfad1ffa4125252e27149d301147071d3da06883cc5fd9609e4f7411c62ca43093bd499ee8334e3776e53bd168a5707965e6449f5404555a4cb389de62e6f45331a3893e42debce5b26365ca442bc1cf345cfe117284894e46d684fea7f6d2b9442f93b4570cad25ba982426aca994a46c95e8d743eaa43ca88c6c94687486c7bb5f3e89365769a7e49d44f4944ba237b7fc31298f449f326439b52463a98144fff1624c92631d9e2d8fe8fc7fc4a2af8c6fae38a25f8d22721e2ddd18521ad1a74c4935b8468b3931a213dedd39fa223acf49dee7153526ad22da34515264c6cfe92b27a28de7abc9628e11d1262f8b125d8452a2e243345aa5b3414f10261e43b4265ddf63ee5b884e5e0abdab41d7525f42b4a6c372727707d1b887c9ae96748a4e5710bd868e9c458aa8c57203d17bc6338d99e24906107d16213b87604985e60f5d56e5f89c41f9a6203f74627386c5389d8288fab087cf3122e243a7847cb170619348da43bb27563d73f4d08bb0b6b69ce7a1ddf73f931f7c63bc78e87368a41483f20eb85f5c6a87deb2623ebdb40e8d5e5cfe2a21ade744874e774bea84b79852670ecde48f984dc4c98f1c39143a88f8ca8a671cba14af278b8c9eae6ac2a10b17999c437e3d35f30d5d9e4a34a5945e6b31ddd077ca792ed694e968d986f4728b06917136349f92f0ac391e47e76b685c4ec8ea1771dac46ae8e274f87f9cb294b469e857af4ff753c771130d9d85e097428767e853ded914636cd378a119dad59331998f65e892af56084f2a23629c0ccd9f4bd2a816b53fbb31749ab26d9934b3c4901343235fc233bca4e9905c187a1119cf2829694a4a60e8bfcb3b84b23c71de2fb4ea99474f4ec6a44b2fb496829253965a24965d6893d2137a41e87e09b980f89082b685be2a2b55d8913bd2332db426dfff4fe8ff5f6559e86556ce449ccc9f891d469590a69695748526c94b119eb96304a1b242677d22245dd913d5a92a749143124957b5cc888b0a5de9b19c2f9e45f1c84ea1cb59dfdef4a4d08bfc48a6438ce9c8a2d07948612175b98e070a5db6e05bd1c24cb9f584aed7d7e28a8a2773524ee8733395e6b013476f42133387146216fd1326263422f56ecc66f153f84be8c5a25a8eefef23374ae864886131041393aa4d421797bbc2e9915d7a22a1cd51848afc1a47778ed0757a4411ada7326246e8dcb23d76500f935345e847e81e21b3a1244608111a1d29ef885a1022bf6808adfb06f949669f2ecb11425f594a0699351e84c674a2b8a977f614c44068a29e8ae19a1ff4a734aa7756c9929bfaa00fbfb9b287912d27c61ef4a242e4066519e3a2e3416b9927fc08d15cb858cd030176d0c8d950c23da92020800eca99e13163413572b5b9c9888a98335e16c7590d1b7b830039684b4fe6d41b8d91e3b360cfe106b0321c7451532d52ee37e8f45998dc682a4ed2bf8c1886451c40001bf43e1b2acc9388399554835edde7434e4e0e973d4f82520720000d9a9f194ff197baf72db4a83123868ce33972f8568e2d20f037227080095ca018800033685474b2cc959f548e2d205043010798c00538dd20c1d1f810dcb861a3868c8383104006ad0791cfcdfc174080187421650b979c434fd2210d1a5e801c100006ad779b101ea344649cbca0fd90945fbe06190f0f015cd0bc966c915fbd4c49d2d18a4e268d494eea181f62a6b0a25149e90a1932dc27269555347a728a9e891f46872afa34b3eab89b343368d0f05463061140472ada903a4b789b52aedbdeb8d1a8e84da7be57bc98e4995754000126785443012e5c98e0518d19363a4ed1670a89a693f498a24bf9c8b9964d58316acc58430a58414729da5cb2831295829f56ec7490a24d62a4ac89753b46d19725ed2639652a914d87281aa5e4cc798ee73f2a0f4552c5f374944e46a00157c8c0e13210147b89fdc9dfb071281081065c71fb095b4f68d1d109ede084766c423b34a11d99d00e4c68c725b4c312da5109eda084764c423b24a11d91d00e4868c723b4c311dad108ed6084762c423b14a11d89d00e4468c721b4c310da5108ed2084760c423b04a11d81d00e4068c71fb4c30fdad107ede08376ec413bf4a01d79503c1036a874cd9202141a1d77d00e3b68471db4830eda31076d42871cb6230e5d9b3e117d3f885a8a81439b5dd14c9ee8cedb56d140c71bda28af117c6345e674dcd08e76aa48d9781b9af0bd23c492880f0d1b9afc7231835956ce5b76aca14d210591932fa4430dad5a48e26355b4230dad5a94d8ad1fea40435fde3e22a2c7ccee2aca71039595a0e30c8eee7a0e2175ca5fc6568e2d6cc4d0c24b80a3941a0f3accd06eca16393b6545d1518646aa08cd2243450fea62a2830c7d2679ecbe0a8dee129d3d0511157a593d0d13c653fe670a8dac98cdf289527a72293492cc3d4327959c338f425f163e04551114fa7cd3414aceca13ba182bedd2ab38a1998f39a90889263ec44de8c74a5c8a103e37b48891c50c10fc8daa1360c18426c83edfb90a2a95c84b68763c9c582e33cfdf2aa1d1174f85cfd426a1fff989296c14a1e3a8486837485395359c47e8734839c597cbb7683242574a7910a73b45e8e369f790a93fde5390084d7c5f932c161c42bbe164728eea906448088d898e98abbf0b426f72f2968a7740682489cba9cc13255bf007bd0711ff5b413ee8d245356911117e44d68366c4080f7e211e3422c9139944d2f5bcdb0e5a11a62eeee62984a9833e6326b1246339682fe9f53c524b45dd8483562e88f1b0233f69ccdca053f1548c9737b1acba10b0b0413be67fa5bdff3cfd5483565f4d648fe14383fee3646ef86592a3971934ff3172531c15d2dc94411b45768ee7a03ccb081f470cfa38b3b926c39752ba04832e67e80df365a1b4ff823e9cca95498b850bbaecb1e1b22b728cd5b7a2dff90b23a6a383a4d221bec344abe844a4e70a561e55f4953c5eb8d6b049bb26156dc990bf59555434a74909cf4e266465e6145d7e694939996ccc1e53f46726f47f672f4597d7c2a4e86747e4c96e2122297d148da7b867fe9b534c998ba20b1953f35e5209328911f2b28c05650245a7595cc3bcf4894ec643484af982d6139d9ed857d92c9db82a65bd1027a416c1e0446f4ac460eda34db47a41290931ac4fd0d144a7836e32d16ccfc65587d029c998783ec42a5530f5129da8a425c994534b746aa11bd994a720645a892ef799899827be3d4f89ce3cc4ebcfee243a95922473cd31e84d4aa2f964212e960e23d166be885e79906842f8a856aa5749f98fe84412c2428a7fe1f2695b68e188460449fa256b8e085b23fac93f1763b94597486244f3f9bfe19abc54d2fd221ad349799e0cf38ab3221c61d2376a485122da10ca37a5f68b8866652e3526390f8fef21da1ca2769e88a5219a9cdab452cc24af2b2c44db62318cf2ff08d19f26f95842c975b0dc204cbae33b4134572d9643ce646c6c81e873320d994ddccc0488ae24ffcee456093aff03dbbf222d7b2c3ff4aae20f60f4a1f3d63719926a52992d4a80c1877e7265ca4eda82beff7b68cd84875c12b4c4a7bc1e7ad316c4ba584f1ecdc94317f405393956994a3e78e84f56c8514e63eed045cbb95bbde69982ecd0588c9c51a552874e9f7c105a937ac558a143b3416559aec96502060024c09843674a9fcc79c4649098954327b206d5574be3d0492d5d8b793b76d2261cdaa45df9435693cf317c439bc5753689085a7eb53c020c37982284ce51d386de3d4dd6b36cd033b3c1d8d9b4a9a66f96a43534db39ef2411496a70440aa97b2b696873dec949a3c5ef57111a9a519122df744578f19ce192b950a995954433b41fab1da4c419f34e656c154b0146199a70c9f44429914d7c4486b6ddbd2c04d3c8dfea189a51d75429272531b4b982ca97356ac2d025799ac154ccd9b2e360e86447b50e2a5b9cf6f60bcdc8d821b887d12532f4422732584c1583ffc6c68800a30b5dcc16d1eb495ce8926ae6f776b352aab385de3ca9e63da921c610d7429bd94d3de4c611d25421c0c842eb1a4e2f88fd9c421661a1393141b2c4c85ea19f0f3a889c5174ca1eb542179f34760ca76e4a885568e7726508e5a1422336c7d331bb20c0984227948918848cafea1262020c2974ae95ca32c958dd258a42a7f36526c99d745670a1d067868a1c92928e18b127f422b7bd7312296fcc14010fd0c24550039700c3098db236f37491a7b5b24de8845ce7fc3d42474ef1b7a0e19600184ce8e49312e91673d0bd95bb323096d027317e9eb39e49114f095d34a1c2e34bae8e658e1b3628b0001849e8925a8c944108f7d421a1f95ef7f00f31870ed923b431b3568e52d3154f82008611da9c4ba15a1942a25a842ebe49f94ed199ac7488d0682a21e227eba6c872085df6a032415a8e99825cc6560c2dfe861604053084d088659223f44e6004a1f9aad822727a20947373c8259466f00d09307ed0cfcba657cf6669366ea48201183e5063ca8a45f08af9d92b2a80001c8603ebb800a307ed24655512e37f4990e3283ce8520c9eb73d437c01183b683bc9b2a4ba93ccfbc91835fc18f1010c1df4da91b2b5e42a630b460eba686262d27f6900060ef0c939d4c347c6de1660dca0f72cdb2be1f349d97d08306cd0448fefdf8e2119316adcd8c2140ac0a8411767b4668d947d96372b011834e8b39724d964116228d10360cce07ce2294616d5cc9b8c2d19b4a3fad37d2b45d6fca01abe1d80110374fe8e912b7f6add701a5b64f1375605306090ce31ca0a305ed0e40931082dd1aae2335a9fc3736ce100e5000c171863d21a734e13f1b1d40a3b5ad0dcbeaea800022ae0c205a26143860b17e6050f56fcbf6dc2f324cbc4a86123860508bfc063157dac2c79cc4c4fe58b39723c0e7580872a7a4d49c6ac9c3f2ef04845271a94f4dc98e15a20033c50d109d56c65217249d8a4960e3c4ed1899d513a33759e04346c307b98a249519358d3314604fe377250e0c63f0d3fe6048f52f45f497af5555f06cd21451b3f264cf018457329e7b4a092e8218afef727c6bc49e74c8aa185088e080a70021a3520f0593c8d192498712302347c8b11f449c123149d88e8ac7a9648eed00314ad58ea89ce8f7ca2bf503a467f984c316f50f0f04457fd39ccea24bdf1abba4a8f4e14adaf533e5c9ee0c189f683889bd07b19cbb42f786ce2903911a937c6081e9a683fb5868f79750b63ca442f4a55d64e4158bce081893eb7e885a78a0e15962e785c02a56267f4ea09494b3441c5e0c15f3b454a522548e1d9a1a6ee924d9bb7bb4ccae7cad89a5186e04189f674d46fff9c4da215aff8dc299e391e070ec3bb838724baca2a133dbaf84c9023d1a727cda2bd3476f8ed40a29da423a41474fe83be8fe83d8593d9ff63381322817a38a2cd31ca72ce8d68535b44e78d2160f06044173274cdd75369c8d06311cd8f06f778e29f1d3445118dc8dfb1540e9a2a8908091e8968c42b24f687909e646ab8c131032d0676071e8868e3c6e09254fe1e992c7a88ce679499f2105350164c3966cc70190570e1c2858b1b7818a2ef3739ea1d495e9010227814a2d370a1740cfb272ff484e83472e86b5834a91f92836884924173468bf35c3a14441b215b92b9b19b7f4942f008446bf293dccd7c098207205a1fcfcf0ae9a2a6321c40f0f8431ba48739f9b1447ee0e1873ee694b993e5d1a1c4028f3eb41dd761b24905a1846367301f1a959a23c42088816cd8c8820b0c1e7b68a3658ffd13523362e070196727989166dcf80b6051060f3d7439747432b90a934d270fed5f0e2622e7a6fe140f9d57d498f09563fcebfe0656033ceed02837a53a9688af496ac62b50029f405909fc46013cecd06fce299ba8e845d6be0e9d6cd5eb8ec193b1e5c2c56771e303288502c4a0cf215aa7ce7ff2bc210cdabc231f23e6f4822608136142c9930a0570411b42b2b00e2ae86ff2b4a28b9d6f1e4d934ea6d6072b7addaa1251b1318818f4b18a36654c5aff2a2b9babaa68f34d478e5031c43e52d1578cdf1f2c76f6f0818a367a8ce9a32c7938df0ef1f0718a2ea43cebda49a62ce1c3145d5b7211627293057d39387c94a2514259c489a32b0ae0860f5274a9a595b26511fde3368ae637833e75dddc5a42a2e8f38ede5c2a55e80fb38d8f50b4b137a8f788e76ad3aa290c3e40d105f91daab447e7a0da8f4fb4e2ebbe1b36278f1fac31633f3cd19f8a7daa7b926250ba8cadcf8f4eb42faa99339208f8e0442b31bce61c3926492d62c83835b6701af7b1895edf3f248ec887263addb97b72dc929efbc844e73b2293bc995c93adc61637f803136dce2046a498dcb3cbe6e312c5c9fd7296d353638b1b96480761429af454a2393d29af7e29a9247f8d2d6ee407255acd219a5f588a374991b11543068e2db420e53928c075de048f1f936857236636f9493e4b1ed928c087243a8f39c78999a387f812fff011892e4bc630d9848cf07fba3b7c40a21d1926a8169da735f747f4a3f47455b85c51800938a2915e2a3dc78812ba3d96c34723baf8d4a632e227ca930a30357c30a2d19c44662cfdcc2616172e709002c3c7223a0daf490509313d998c221ad1d2145db724a2af8a987352954564084144e3b121a65e583d1d9543b449b72a5c62e7301fb980219a0fdee1b45e5e88be67c4aca7cc3f08d1969ef89fc475a694f431884e368f783599f3218852498f61844e32217c04a2f71769a6c4fae66906107d9b84d429083ffed0c6d0a8f329af8e72cd871ffacfa2c368d28d9754d6873ec7982de6f00a1f3a913fd9bdf48450f95ae1630fed09e9b1d7527ad2a0d543eb1ab3af073f350f6dca0bf7030ffd088b9f2596e497e4c0b1058a91458d1934500d971183cdc71d568f21e5040f7a8c0f3b34eba137cc544c1dc9c0471d7a0956e2249e9717f8a0431f7459bec81124f855e6a0c411fd9099e2c00f39b4fa417a4fca39316426638b3c0afe6f24172e74f011874655c59e6849a53862fa8043ff723af4066352d9db4145836a6dd0b00cc1871b5aadae2c156d8f943a3668c440550d30001ce1a30d4d5029b48807cb209b0f36b41526c89c93f4fc319f1f6b6875848e95fb454b7a2b636b86091e003ff85043237272f9628510346b62d8471a3ab1eef0399f27c263a5071f6868dc457f838a27bf9145e619fa1c8fd721a6c8df485636f83043a33b66cc25441e6f2b95a157c9a93f482c19e2e3e1113ec8d086a41da35f15e39f6b46f81843673a98588f1eae5a530cc28718ba70af702129b6694d02c247187a331946ffa834a915048666fef4fe6b8ed9184babf0f105a35b6ff98494a352f8f0421ff2989c8b099ac53b5d68e406f538990f1666e242a357deca255f5649930a1f5b6864083185a5ca21576a01179554ca0eb9925968b37598f8b1f38105ce640acf5d7a841ef8b8421ba364e59194bb337c2cf061853683279d573d5a840caa42bb6f6139c6b9780a95cfe1336ee4702dfe46a9297c50a1d5a0357b538597e825195b27468ef320f81bfa318536895c9663c36c6491c9d8d202c71638f0430a4df4a4da31641585b645851483b6c8d83a5ba01a33a07058091633a8f647646ccdb89103c77d3ca111597fe3b5332387161f021cb7c58713da18214e3cd56416339ad0e79ca363c7d31771e6c2f1c184c6adbc7d434cc614be89413e96d0c789bd561a9459b647c6968d1c7fe843095686654a51ffe7440fa0c0143e92c095e79bca7bee14bba200573ce08a0a34e00a327c206113e29226ed65617d1ca14f2a4b86f07bc26488e4f82c580c1f46e8f3723b68b24c32a445e8b4f2e4645329d1324484bea3a8e610bfe428f50ca1535a3c64543c73e794b11523c76781001a4e8246394cf0349c04efc2c50d2d4cd065f810423fa663d8789e92b657540001577c0e1b17f01c362a70450168d0f0c28f20f49dc4456bcb5920f49d29269d739025137cfca01f21af73649d2816363ee8bf828e619258fe659c2d6ce488610371093e7ad06a875d89b9c43ce824e714afadf7456326821d3c973c6c5212541df431257daa62221f39e83fc45e854b41e7fc390e9a1c13ad4f856ebfe9e3067d8e16475b7c8a0ddacde56b399624cf720d9a6ca13f4a248906ed99e8b2a8a7a2e4a8ad113e66d056122df937e2a4b6a88cad187cc8a0cb35953c890da5eba218b46172335bfc1e0606a55c3f9fa82863ebe3058d88e8a752cce95ffc917db8a00d6b59d994d269452752ca691e4a94b15582af5129c08215968c86f896b28a7b83e5a91c010b55b415e4c54d3148f524b154f49164e2e790723a99858a76a4e506a14d6e7c845811b038459b92d66c0b296c8a4ef49448cc56eb183d45042c4ad1fe29f99c298b85148dcbc6d19bd292897b3ec062145dfa840b211145fb3986090fcd62118a66e454688810c302149da694a3846def138d7f892092beec89c63f47084a05a514b0e8449f42fb9e5217ed93474eb49d84596cc96da2917bda5ce2569ae8e34bf4c77494897e946fe78b22a388ce60a2add2c899bc4b346742e8789a432ca12596684c75d49311479568c3e3ca259aa7c6f828d125179d5b35a41299a249b4979f64574464d06e4aa2ed58d2244ece45a2cd933c95cc49a3a71c21d16b5a9fa99cd743888f68849e982bf526a1f5774497722b3c65ca35a213339dcde4fc8ce8daf45fe90d9b45983cc2acc6b8a7884ec8104fe28a08915192883eb7c455ea0822a2d9f1d3b9c5bb43b49f96313aeacec4d80dd19c52a23b94980bd1486fcb9074f68f372121902539294f4b924134f14f4a54913141f4bb4926ff594d206c4b32c424d15140e42135c6648ece1fda0b13473e4e16ad94f8a191f54c416c88a45242fad0e8dd14a1b5433ef4e1329b848dff9221db43e71f72123991b3a0bb1e3a3d952de278bbe98fe6a18d713ee58e88f1d05abc77d8900f2adea19332922dc431f9b1a61dced21a9a3a5ca6238e859852e8d05a76cdcd3c55ada69c437b41743d4e7f6993961cfa9953aa2ffe34c5f6e2d08e0899ac42cea5c94b38b4e241874dba226f683744fc121f4c88142f6dc0c20d8d8491292ae6601bba20d152fe78180b36b42b41a51446a578cd1d166b6846e51c3534a7540cf1a6644a05b048432f29c5bd1039248c7249fe010b34b495fa42656ec534f11a018b3334224a8a097f2263f7880e5898a14f25e73dca4339605186466c5c89fbe4dc9eddbb376041862ee812a6654d35478ea8018b3174b27af1424a3219266357062cc4d0a5bcaf12e44d46f4fcb88045181a212d09b99944e9e68a8693c0c60d2db4d0021660682eb69a5e8566a7148b2f64aa7fbd8cad1931b0943a00f8000b2ff449d7e297dc32a541d9854ee65691215670d323c2853ea54aa963e66c01165be8b4af65732d9551252d34a6494bfd4bb5e54d163a9966c2e48ad2a4592c74499867859d28b97285be839a98acb000e0042cacd0e4788d9994bb018c93a8e4af45628134128a44227124c33048f01e01b3130800183c2e8f0622a1609e06822a7e140004572e22443a2414201e1e18168ac30261201006030381302814088441c14040200ea3c441221ff369839f24c1e7efeefb444b946a14d67fa5555a94aa8ef54fee8ae5244d40f693a8bc2fa09c28a9eb48e8c7d3538278e7bd1fa1b35870cc244da6665292844094c941223d641d5656ffb8fe06a909038c0f371588b76e81fa0d8e312c7dc984464efa20a726aa747e0bead82dc9e8424fee1819d9645184e80a86bce26a73a18aaab4bbd4342dc0b6339234885a7ba0a5a489a768bf7944809108f01674b3f466890a601c9531e920c4a32d27f68fca9b975cf96e8a3f614975b8fdfc170abf168442256686cac8f12f0df1456fba5ea06d508bd11a56473c24947ad36c5eedbe2fbe60c51c10363f93b334077054fa402c1a7282d94f55fff9c139b4e9ec2a33b73b2407f54bab81665b685069d2364fc598235e00622353aa9e8f292154d2a5d86af40ff90d91830b930ee2ca01d8cfbb1ff5a49821d9973f9f358e6aa627496d97a776bb351d56342f23de87f7ff2b3d95fe66a45d05b1ca1aa94daa1e903059646e831d08c5ba1eebc60f085ce334db123c78337a0a315d164a10c6e2421f6d3606039b9e9def95ffaaa9257b9ccf828411f518ab8fabf7a80b4f96c696546e625071219e152554014acad5095b7924fbac526f46eccaa9392da13d4b7870b28319c4195c14a12cb177d1786fc6a038da84f73ad7acb015a4d8d21b5527cf136a77512c4934ebcfb5965eda3c090b437e2d6aaa4b2e25901984d0450e124e82c4edd8a07e1f7f1ce6ba34a67f8eb7c8edb7968bd9da3de782ad9c77c18d5aaca7abbed1716973b2b63c49cee060aabf4c66fe5a7a19ff6d29bf7d9ff7a23316786b22e4f464f84720dddfa7d0212beb49ebcacfbdba59f7d9a9a1314426037eeef624ce6db040840c6ae0195488ee28275277e3a4a56e5cadaa490ec81854922839adc025780520e74fcf97a78f45a2536e630e2d77091d2ec428b7f13b05f1d1137733f0271eaf059f4b06e64f8149a5a82ed993808a92ed117ac237726b0aee9b062bbe0585b0997c60e70022c780fd74431709e844bb96875bdc6c189e26cb886057664f02dc492c6076f1bacab773d05d5e11682421dce410bbd0a2b05861b15316c950632de2ee708dcbefd05f6cc58a9fa1e2c23ee669bfe93b72d1681865c963e759c9e228547f079f935dcf47bd42f4e70d7d2caf6411a4a1dce2b43079722bee7e3511bbe3b539de68bb2cbe1fc5b7b0e577872357bc768384dcd842494a39c2922693abd871a930eee22ef78e43d2a633b710c7ed29fda8e3181ae365912a47a5f0083605442d493bf3ed2289671429f9c00c3049436c8e60d58220d255ad7e4b3b05eea16d54aca57e97009bbdf14c04e81d37cbadc256605090c3ba5f71301c4e43865f3f9bcea6f3efd432216d7306b14f381ef594b6a727a578ae13e5471e49cd1010bf64c85e73ef134964639c0ccc9dc6535f600d165ef1f720fcbd276993ff062940da2b10e2d43f026a4e021da8a77114e351a3808effee38802981a95d3eb3f41b146f90d1caa5eb79376390c013f369b99636af1265b39c13c97280c00c254113a986f7d28d4a332075426e70f9a32bd5b7218d29b832519329333d4eeb4c6eed781b583448e33bc68cea3e204c941b48945df79a00246eb82c3d852edeabc50d61dbfe013045e13a5d15b8ada09154dd60093df0bd0d550c40fd5884c1e16ae9389e309a08d832109e25f65369a1ddd8366c05bc5ba54d54781f1ce2c8640557323bd06c47f46f20d23153e5a40b5917a5f0374c8f5bd05ed2de537d2652652da22ed2a449b4e8b4a46901b15cba71d753dfe8040ca1df21e3f9ec2e584539bd410799d3a17979e94fabde588edfbba4c65dc4d702d56090c6f3116356b6321d11b2eb694ed223a587f05f1cc551d0507b13e2c8c5105fb8ccc969787db5b638d7077dd533145ceae6cf5a7da4651a803ef73867828b9d0a642137e71307740cc932db6e638426973910d574bce6903878c5f58dbb0a3d7b3b57f15ac9d477d9408720f961deddc8c100fb4597f22a7bdf393b969a0ca0540526244a20eac3f2a6ceb896ae2cb10878b3a45a1ecd0a241eb82c29efba700db49728d5d65867f0defaf11bb441df21bad3616b398a08892600d5b7fd8ceaa1d951f9608b444142640d015345a3aba583b8c0dd64e598fd8074c04abc272d06bb24aae0d3675c74993d2f6917645a55aacbde0aa92b369d486002a9c94779797b122e310c9404206a3aa4bdcd07270857132bb1a049e1186452e983a09981c1451b6ff83cbcac6754abe995f343979a94423c20bc1e4027cfbc286f9b053d7a9c720e36c6e94fa9b5ec01464f7d2cf5b377b39353e96d6e055415de183f9fe7e17770cef191643bc792e32156fadaba5df56d258f67f87733c980f00b95eac026360f813de39670113ef18bb4a993f01ee4acc4b995e9eccd722e3c443b32e30eea9eb91bef75c21b54883c1a1670b94899cea5c2055cd8e16dd2c7e283b47e5e11894d08fe10d294102dd51f1df52a40c700d004136a8c0565686133759ca517aec9310560b5421409d16d9450604847645766abd301445549013d1854c2f960c96a0eb0cca647a680f9cd39771a01060373c80316a4a71ae6efe030ce6ef603f9dcae73c38b7dea07e15e609296bac9612c7b77035b1b8b4051c130788c958ace1f110fe413a413e6a1684d8776bbcb88143ab92e7c14c4a1ebccc4c5600c184cbc8e17128ac1ec7f607681aa636b61e9eddbe368c10628277cdf28a5ca259314c9fc4c391104b1080962d91e40e640dc3e0223581a69ca8af7cf1ffc09a993c5cdb49d274fcc2d1e7832fc63797af3d7c9cd34824d440b0e7d8749df87d50aca4c5ce3c94aab124f9a92535cecfe00377f4e251a97910f76b974405cc6d868f413ca5c89d8dc34a389b84e0657e279a7f2f5b8ca32ae8753aacb6cc755960b002ee4c2f5100f79a0277365d4b59eaf24f43212fa27fa5681cbb84b39254ddf656cadecd3b9a12bf129a8b542c7758e5dc6dd10911851b88c70e3855e9871199dd4b576b8dcb6542a202dc287cba86239c64ad35c460c08debf8c2ee3dcb8b1303797113556da0fb68b092ab99e44e1b2cf85505d0fb1cd9db8ebb914736d715d782e2613dd76d44ab86a00cbdb65a445f11af61cdfaa7c5dd2b30b3c31d45c965c23703de47a472ee357560a6d692e230576c22b6b0b9481a2a872264c7982a57245fb3f99ebb41f20f9a03e264c0c10a498ae7ade1f2460f7a8444d3b13123230af364b42423e86bbbd12223a60f03c94b1423527a1fa579a27443466f9b1843a0601fd9b3edc0774e61e82612a2ff174e8f907b53ed47fcd9fded84c493b7eee22ec32b7882c0b962fd7f30243951aa4c22123ce735f800028258c9aff470b6db6c96392a49e566f61ed0ca95d645f4c97b9d218e792fc7f1146715fc8478d108f860ae8d75e6348b30c393575fb3ede95629b920f209453e9db56af47201b2776ed94c8053c9cb2565ac279afb7f3bd86a340c9e43d5e960f69471d3c52bf8e37b399c764b03f693793629f8b0a1db80ac28c9a701c7f693cb6c6caad89bced2dbb5465b9ba3b72032bd1a766e99ec970cd9a1e894575885ea1168eca48cea1ace5a157b7222517206ff880c065bcb4a75ce6ee722b4407c1b1b591a8c14041c51052e8160b30f913ce9f0085089bfba0f01bc48ccb8cc875832046d69a17ae11eb805a456e068331b82915aac90f1c98708370620c36483f5fea18113637d31435bc8319d993cee09041a718bc4aebcf5ccf8af22952da2bf10971db511ab058ccaf960886b416d190018f1bcca07faf8ecba03d06332323583e9f0f1c366166e84b0ee180e08a0d66262629873b3eb012c2c6b0be80479b83199f7e8bafc3a08f1bcc48e9d8a041048662b08c8dd1f04a4658fec1fd11361170f9ca63af300d3b3d2334f041d5d0366fb0f133a44a65bbe75d698ad681573481d0410068016a00203692697c04008b00e69fc0a92c20c00601981419d5600f7070db7b22c5025a601ae81009c06d00845d6fb28b8f4090029e8300e67fc430193a802be9b4b3b23d3f1d60024201e614f0054e74bda8b62bd092145fe88004eaeb01c60907029b0d00a21780f0487031ce2e2504aec9b1d3b8e67dc09d032d23b6b550241887bb6dc05c010c925c11391e00847363b4b3b1006018808b065ad086663cd6068c21804170821a5809bf76b5055742dd168611a05d609d9c5a1da7c02c00de03a016c044922690ed11a0051d3939ac00688d015a3061f8fd5e00ed0dd002bae28024001d02706565240e9c6c050f4b01740110a500b500262055dc8d4500862e5f7af1f47e4946d4b37a44370f2c13625be56db85f886a085010381ea2e744840e728928970990e9b5bffb2301829010be40cf2463ecb0954bd90f03db90d69af3ff7377f26f17820929939386f361b10ba7a608ed807a76e67388da10908000b1af973f5b22883520de4aa8d91484d29b7e9ae1f53a0a9854581ab2a4f585942a6180c55c931270bae11ac0679c80b04091f990938084e66c170d5231f8412a02262b554e02b60343e107bb4917f08839d271776c22f705712976c8eff58a27171bdaf44670840a1da463eed673de191db5776d5061cdaaf193315e01b4429502d0153a7a28e837e9e201639516821aec30b8d2601309c147199779960019af66913a825e8253a04063cd2ef92e0f34b02c0655627443e527a59c418c9a681dfa9c4d7aa2ab60fc148374c5046fc4e44931e7e84e6e0853ff64407e7edc074f457e4c3504776282fd473fdc6e679a57ab53f054764c2216dfe3f9cc9409255ef2299b3737dc36ec39947e49ce8075744d0b5d14cd0cd6fca3e3cf92c4da00a6a254ff612d8f0908a3ce04d683627f751af37bd1cc930ecfaab2d7aa7b8e48de5f9fabb7ccd7d05b9fc35eccc0c34453b96c7b45332eebdfd4999d725f3b4ed47ede4ee969664dc553fda63b03de8e1e7b9230de6836634a903b5e12f80c6258ede98db4d790fceffa273cc6fd52c29bb00ce808140dce2aaaa618444222857332c625acabbb0d6cda1c2dde85392214aa8c0d29f9b7877cfc7273f394e1868051dca598a3a3bc089e3f317063f5b5c43f4cb264429450ea4e76e330b821666753a079296e907290b6f186c431114301f46a2cef1b3eb0f975a505752a579b5b8e6b7c15545183e2be3c84a2e79e3995f7f04066795ee3d34da1bbe1c0cd9cf22d2c792c4bb740e75d06e3c454656cf36f8d150e3138045fb50acce2b02f4e889539068aba398c00b34890ad4f2044352fc11205e453731e198df9c114077378725b4e67bf1d2ab8aead0c4ec4e2e105ce39937cca4a2c7b4fc9ab3f20d2aae16b33263a3a5b51bc81e03e380e2807cd43de3aded0585d40e610f2658f1bc7250c72f1d400d8f7871c420daf66e2e07fd0415464499335cbec27ec0e7bc78c1facfb8b05627409a5552f81001fee642598fdd0edd501d6394c1c954eb15c5800d4dc4ea44f891aceaca1c8e13f05e588ae8bc53f36398e79d50c6334d2fa5460450f394c42489d4be2ee3f0ce8066ce69eabee84a365ce302dc9c136c2ef0ec451a2bb1baf7c4dc8ea5ee865243b5639de62dc40a91df684dc4b7e5231b00b1dca81dbf4c81d2751d7ebfee5be42eba38c11f8a621e9048167b261fb3d0a942d4ec973191b93eaa392bbc83e1554071e85fc0ce2421840026151832e885f0d7bd2c6dd1aee42ba54492ce6693f8b8548c9a91c9b448970c34b9681f0150f0937bbd77a279a17c2d0a7c3d2b61919001d00debbb0ae934e7405c953cb310bf1714135537f8d01f90ed5f362f32a87c66a615684062ca9e3c5adc9e631da4b098a28463293f5e26323edd6dd93c9f9be48eae36937ff606457fa538088d85e0afe0bed40bf5a65826b047c350e91b80d61d07e801017e421e198568d9abe6a0c0278ccb8312e35723f019f38a36dc6e8b360b677bd9d75e3b15a93cf8db26d062e9eb76c9704451f467c47626f6ec9e647b87991cce3c43e9c98b56d06e79c5bc8f6b065e3335b28323b44f43d01b9d54c207715f30a5f461a37238f80d7c5a12e2f46cc3ae3f9976e353e6fe32721e98aad571646d70f0b9eb75766f3c50a7f465178cba7559bdbc165c6be41d199aea7631207a753c87cd4088e1f5c0456ac2d09e6031020b3ae7a81bcd7084d0410785c80119ce1e496bcf15c798cf50473554b0a8d095b635fbeb58776bb39a27988c6ede5c314fcde1d81e523e32239c7df6cfb6ff141f909dd618581bd6879ad1449cc0cc8fe2463162f627dde107c0162b0e7badafa37365979b2b78d69210a1cb730ebde9bfe04de2a5881572e1d2e281ceddb22a7d22debf84016625054121cb2e0c285a946c5ac6e68d3291f9b2c47cd1da2efc948f0390fef0593dfa4dd60a3321b8834a0d2c44a23650f4f872757c779647dc453df99ad4df447f34d6edec7ad938047aaabb06b7f9f3a76208c196f3320167252040e2343b152425dd08616b2015d2da140d305e423e38105133c1224c0bc9cdf49317158d745330c16122293082fb9e56a764c5d3310dc83fb5e3937c5f224653bb8ae40a2c7e622c71ce78314292a7fb6416684dc225a3bdb431e5eb576a9668594ed52b1fad2f84fcf15511729d6563132211745aeb0c883d05ab95d34887fe8daaa15d5e61bfa107cfeb3ddab84ab6d24c4d300531ec9efb65af476b79834aa17084a3b90b19aaf225d903d93d356543c4542a4b47f605c37cb9ac130995550a0cfaf4ec68df8f73b15e3aa52fd7c0d4dbb4d2aee42d69d737e352615318f001b86c1acc01325c14420cf1b42aab000f0b080a5f0ae1a6e2b1800ec12b49c3cf31106c75327023229edd71214622a18b8b3b97a7c7b48ca5b6b74d235f037806526f84d6bbf2b9c9ac7db088f4dff478e8a3df727bc8ff5c5cfd324d47eba6e860ac0b79b549071a847dcf6feae7b04f0105fbd1b11114b846feb809ded9261acec9364b688df4e2d4f8ff508189fd498fddb557450e922a02ebda8805504a1b048d4ec01b3d0a87e9ac0179bebfef9adbe5de6cef3a0477e5988c4a30642650748d1ad69c5f133b249b7080945dfabe819f18e25f9211910309f4784077b6e86fac2111718b45ffb3b68c090cfefde4ae8eb31fbb99a0b31734188b85800587f5934f63e970a47e8d16c06fd333321a92309a80824da2d8ba35364e23f01c1d06865e6af4fffd534d485801dbf4b12577a4abeca449b12130a5faae5231a83192bb85db5350eab26197b8613bad2acccffe8347a771038e33fb0b2e8ea525a476addbdec3700fd4025d8e40c2d439be4ab987c89c47b5e630e39386e97e3c3ccb9a409f6bdca0a01b1734ff51cc6bd45359aae1e58e870079e8aa9113d5d495f3cb712c77cf8ba842ad4b7c39e2baac30e4dec6eab4af5bd38be937851a45fd84bceeab00aab05a00d21e18fceb5c27a542b80bd941399e2701ba86158d9dab1e200a09fca0030a8b4f9ec746f1eb1dccdb295c9c06d70759a99e5b647686982bc52429912833bec275ae950f6c0255fe3af15b4d4796c6fac59112e4d9b53362945e617f28a11664601160fe51ccac22f8f5e97cee4c43951c6b596d4a0837a5d02157d67a152c41078025f58d6069ae7cea58088cc204fdc6b65a8371f6fc028dd9edac7a9cc2b90999cce0a247c94be999c5619685869470629932c9bbb5a2ab388b44cd9503cf1922ff002274fb1c7dacb5d2f7649877dc15273f35c2bf1ac71beb3e8333077165d9259b0eca2e12339247042fe7a1f82557d1c5f0b34dfd04bbff8fc9a6013f3075bb9796fb7c0a0014c01438933d422ea1a521729cf3c6a3e2f805a395e4a1180c481bf19aa22af0088d74a1012323bd6767d65bea07325e252064bb805b95c94aa4f832784b9ced3ac65c45b9705b3c2d925c74186c1f5f115dfc4a3126e7bae8dc3dc4dda167e51b490dc8aea69859228ac1bd90d60e2596e461fe24b7c8bd3c85becb6f6db1ba41de89e047bacfee7d5c5ac1d45c5c138664a7f4fbb0cc28ed5903a044f32003f48b4ca29eb287db35feaa4302d7a5bcbed056981b6a0571235911753cae040a4852add8a54178a98730f17d035d2743f735da3b042ed2ad005a443479d342cfa1ceffffa24b10a9b3cca80dd3e09d520ed015f066e7c5df8906a68f76e7f3ab174189f2d689bca1fb1c9f66b3299f55977ab0960e2605cafdbb33da146216c82c5684bcbf148ee12f9b4207cb1fb33bd31f0e22ee74983553b59a2a2b2524300fe2575a0dd09d18ad100394ef6d940ca47a2e5d459f1cefe237ec095c2ed033ad77148269fe7082490b686ebeb56e01bd4e9b2b7d87fa8d6d1b5fbd6053673905b07c7586659af7c98fe0dbf609931100cf209c6222c5136d4275db1c4d873d2d6e4920a38b693db23324cc42b7006eea62b96135fc4a08af501ec223dfe694e10c56e02f05bac9fee3118aeb8bfe99f8e8fe33a8d54fd8dd86dd11cb442c44e5f5e1641c13d7cbeaf4990d07c2987db265f58df38c7a42ac7efbd5ccefb950e8a77088ce13fe98423171ad89449f9a94479b9ff7f82ea9dfb56368927404e5b46867a47ce7cc4aa76f03b9f22b1a7894901085e5a0d3bd36db806aee41f4083407e9babba785ae34daf13c028e46ba121e4857197d01a0f14f7b741f229fa6f18591de6c06f8fc63ad2f20e60a3b8e03dae25ead2025ce03daebcac1bb2cb02a2194ce44c2745693cdb89f020a60ff15ad5be3903abaca4be08e2a787d9cfa1a7b54449094062a0018e05267172b63aa8a3e51c84d6c2571308674760b10b2b3151296d97b91b8c5813187c51dd146bf7606238f5081be6b5c99bab85d271096d8646995a00521a181e40df97e98f09010ef3f4088c1c50ea8bb7001a93e796172c8f4dde5d9ebcbca2bc7bf506e6b9e585cb639677972727af30ef5edeb07a1750026632cabccf94975996792773589c0eefdd1aae65e5f23b0f72500a7bc5f033d5ba81ebdb2593ce4e643daa2d3104921064209c40201e92d18c3388d2376df841c98d57af172a17c64b220010ad2c6a1be579315372b535b9d255be4356ddd728a64ea50c16e6b4608fac17134f0c1c2aed00b9215484afbb8c67faaaff1d5cd65adf0db1e4b3a4e0c98b073076e474eb030f1284bc23f327df913da692dcfbdb3fadc676d18b4dc9bc893107f045875bc1130b388a38d2e20a82dac2c4315bd3d326e09fd15e63e2fe237b86d46a3f2cb301983818327febf0adf19a4ef7ba6ebfd19d1be1e0e848565c523bf71ef8f57d3064638967277ef3286470670f4e73fe11a6c8d5581f4fab048c756bc4d18763fbc8d08068420c03310cdd0ca5a64a46b63034b04222eff31c5a4383a72a9a2f35b852d729cffcc82ba5173b4475f0833e186d7cd9c00f27d71304d0665edcb4a892b6813cadd8b2213d5af878addf733b35674fc7bb18b24b7c34746842f33a69032c63f9ec9cda876aa7cd4670e7cf5b1c2e49e993b6f9b21e6b2a2c161ceceda2043a079edb1ea3dc778aa3043e56a46c6fabe58c30c7db1634270727667e9c6ae53b5671e69386c2de59ecb2d5d0fe0cf6b243b786b0658fc3302f69c8e6f4e245698e6c81fc661292a05cb944890f4da2396c4090b91d382fde4229dbb0e141cc97d7414f2a7aab08ba7e754399020fc22c2468a44b749e123bd74cae68e1c59b3dc3d761a196e54abfb7a9e8cfb6c4dec42691cecc75e91c8b83e3793a6d02e40595b49029592308812a1c00d0786e134fdcbb0252634d01f09781a3d5719e45c9bb8dd12c339f83d41e50a6a01c96a0e7291cb5f34723255c5b98088c9eeef8c0f8098b803632c10039c802f048c2e4c33bca46ae120d986f3c6d2c8382bad9b5f84cd52d1f46a2c5e5e90b75f4b027d7b82eebf77a6bd0e1e0dd6879caa6475094cd53095f233238a080d94ed97caeb1770cd4c700a5ace27c13634b3e86ad9e50a3b9d1a5810021622e44726ab15b578b61eb7da43fc7de23b870051a15c2f445ea034656c0c58fae0745f549fca786f27d06390244da7676e66c246623b15eda6ff487ebf6a1a5bc3aadb359a920615de9cf8a0e2a611f302d932fdca80b5297d048f0b911e4e0fe576b798800296dd7fa49f3cb1dd0e6cea12f9489028326f130781bd296d1e862c7e580656d75071621a3f2b347796b547320543dd13aa1569745cf0c8245a80c204c51c7923b83954dcdd7689a392136a39e0502d917f62b7078cc08c7ab2f346e69130724e14cbe4ae2581c07a7642a47792fc8b156aa02461329a8d88794a2dd87f795ffce3640bafe3eac186d80c4117780b869ad5ce080fae8541739c649911214cb03f2f2b01fc38adad316da05d892ca72604e150d9a6fc58a5b96600ecc610505f194cc790c96e830a9a2b5fd4848be4e2b384c19f74d99f24a0624d20c3379a68e4b8682f318ede3f885ed6a0051a344c70e58563ea789f4faafc0f4181e1701ba12a4a64e9df1e9c8a4c780ed5a6601c32200cf02bbead455b064407e7f16dc88f7d9b78c65c0aad2b6ea032b4efd7068389c00032034685e3e26b630e4163be3c1b897251bcaba9dfada82bfb5dd778524617374182a06d5356198042bb9593b957ccc5a17ea9373af378f6d66b06f6f7fb015269f04296618d83158788f59673de0133c574488685e6cc282e74cf92f2744ff1b402d4f4581f60c1b60b61d3c61062e3756fc8340e864c739e60ca998576209d5308e7efb63077580df46814c377ba5c15d56855eb66176e70ea1fbdba1e810a29977405eef6657c108ce0a27588782612ee1ff604c0bd7ee9820e9c91ade07f50aba145e82c8a268c974b8a64bcae3e7681980200344042effeea62b908197dea244b2fcdf02dcfb0fc16defa7bdc31ec1f5a367514d688e6e58f88cd614aa76899e9a5ae4ce1e4dc32504a807baca33b345e75fba356dba7857693baa93e6d369a13b18d13d0b18676e86482e1c311b7c2b94ee46c75a9a885bc529e5ffdb0f3ef0f705a60ae8c66ba6bbef205da40cc59e1d41140ce6700c76a6423e48a57129d4bba1b874a0c2239c8d14c0a6c09686ce818d06afafcd251f68d125f2df1c87a533ca53f3f5c0d541203f8ea6fcf348aa8119540bd20d1751edf1df0ce67528ee6b599337d28eff1e1f6031852b9d911b901d73a2b59adab8d1c826d039b3f2b1a7a5c5d48c0579b144a2e57c558309a0d25a55cce096bd6f377656a514e8c5c2b0793224e91b3180bbe26893f5b0d6f182810711b2da65501bd29c7cba3c8d2fcd3da1f6927fc031e9992c408cc9e0978f0c4bee966c240185c00a454c43bac74279ed4825b6dd09f96c66670e1dd94a67e6f076e334daaa76f3ff8c4fae9b46198ba4c459294fb63eaa356e36faf144057685bc905ee7798f812a6fdf479d02792e3d1258fcda807290caa38929a74688934a1d2c0684c5037145d8abdb9772736140d9f102fcb62fe1e4f3ac185914ff794337cc417abdd967f2447d133b6d7c96852f531f67bbec58c339148a65e456f0d3b7d7d9cd6ed8398a0a00c541b5290aa4e3ef023099a24311071c890a275144d75db3b34d31517d5ae05ff876ef58ae3c8bea6aa7976336464a952b40109af891348bafdf167b049d49c4741954595b5f9c711ab4e46ff0b45e7235bb80b7649462c2995966ea72b725a385ace1cf287277ec104cc389c92d15a40dfa5ca99fc3a7346bd0145355f7add45ceb710c614f1b861c57728aaed8525a20a73b8d6a46b42328bde34a5cf7161dc4602b69ec5d92f9e172e691bf4c46641a72e9d147e4b97431cd456ea80f38f53e7f9ca612c299a4635f0f6290d8b99745aaad3507789686d72585d6a8377231862334d3eedaf73bd52d46a4afd7cd5c6d3ea0f651ea35fa0cf83cf89d14c30ea4fb2a2af28709b73f8add163745bcb369fd00ad074d0dfb93aa2b5de6d31c6137a0a59123166864acb5e3986fb31f1846cbeed556a081efbcf8f8d38d1a44c0e525c8cc9b1fc3b450dbcb0eed8ce53f89be1643d6e05726e6db01ac6179fd6c43a56b7191804705ca52b822f873cbe386c5aae3b60a26da6da196a60f590ea1302e56186c4dcd2651881d0401528a2c8507b41828070b8e1164947093abab807ae7e97bc8c03a0aa584863b32694761dc0d9a4c402a30997f270b666ee80c94b40da6431f552b81f1c10006d9ee1d5be7dac983660a4a6457af1e0af158a81685a4ea3c07ba8310b5ad014d00f4908a7a98461d2502f07bf4fc8f7d220ba6f31b9a48b27f1d321912050a7dd5eae51e1b7a10cba9482df759f2ec4385694608e92e773ba07221115cac03e2996dc5dcb62f6196baf9c2bbc19392ce0bafa2ea7bfee70b8ec26296b5c8ea01ac3bac87e3840a1ca154ff6dd9884870dc0100a85215d6d4829340522fe1136ebe98d000f1a5fd3fa0d887fed0043ff7a365e4e0ec2f1a006c6f3e1806f9deb89835e9f28bbda958964ef2f193962a16d5d940ea92fe2b9a054c64eae9f6bf5c661e27318bbdb5045122c45d5cc510c500c9b893101289c9b5114d92651eca4e19c32a10e907512b50156d42b68f9fc0fdc95503c59df0780f3080acd931088e56e9b95f3f73815d440b2c1441b8b71e8e4babeb4e20cd72a3c5fda7a02bf8d2e9ab9d00b4242b115c92a752649513fb82fc3d2c803ddff3152d0f0addeb0580539a92d4e22276b0d43475f63ac472e50cf5fc9d3c23574cb916ca9dd36b3816b3833137d8016abe1bb08661786d38c655969a2ce5426044dead04d4ce6b85010d8ef08517499db718edb7ce91ba30faf0f2f621a0c5adf6bf6d19f77870947e02fdcd3adddd7588b1bff5c08e4b1280ad5d4efeaf0199e42fe6cc3034d8d25b50209ef45109e15dab3d4d46aa4a12b5f8e6ba0dcf3b502de73f33e3d3c86c6f407f2e803d0628fef394c5a79621f8f76e8de35e048028eebe7b083e160b1ccd6e73dd55d905037aa967d5685ce1958db178025845125d79d2f45d0f008e702cf9807289c191bdb6715d3e8e36804d62afa48db301e4a5027ea204c20b3960eea4900300c3300cc3300cc3300cc330bb138808941251da69cbb352ea0cb3ff7f39001491b22222c949a78d4fa78d4f67263e9d997ae101d70bb50b540bbb76a5862e5984740fab82ba9986e6e37ce13235e242a3a1ffeeb4d2947c36c54d409fa1c917fe62926ba9728f199a241eefa7a75439de7ce16594a15d4dd51cdab2a6c77e802643d7b3e1247b3b2c7cf60b30c8d0caa2c7a0775af4cc5d92a0c5d0bb4b9caf9819864e663c5e7a6e4f664130f49ee5152bb78510365fe8ff93e765965ee8bc3d8cce3e292a067417baea94d9fca58398adc385365b476698182a2ff75be835789290e3cd16fe51b4d07fd4e928fbc7e543390b6de5048f3af8147a3cc642a3d391254bafca1e2357e8c356f659c8f1978b678536451d8f332b4fe7eeaad0b547cb2994c4a8d05b6cddad1c8798fa9f4213737b4cc922d252e84c2b63737c8fa0c1f7425550c6176584d1c76c1e1d056d28683f41db09da4dd06682f612b495a09d046d24681f41db08da45d02682f610b485a01d046d2068ff40db07da3dd0e681f60eb475a09d036d1c68df40db06da35d0a681f60cb465a01d036d182816af502c5ca158b4425180052bfa8fd1d27321c777543b461924c06215fd454aaed4b1fb1df45ee886092230020c4021b05045bba1b5647318bc7b542fb40670012d360660670224fb0416a9d019a810038b532816a6502c4aa15890429f80c5289cf89073e6b631801245cdf80216a1482060018aab2eb0f8c479000b4ff411f92af33fc365988004659860020fc0a213cd44c6d6cae1ba7e30b1e04427f2126773101f4b5e36d1e558d3c7a73d28f10a0b4d346ded93e7f9cf446ffa2f99e46230d19807bead1d532ed174746cec207754d29196e8f279943775d29ceb9325605189564314ed8f98541084f10527000b4ab4ba973ba552a4103e08de046174d1450a7c04fc000b5ca56331893e4e87df1e7c24d15f897c67c6fc13e21a89464e7afc2b9390683259f488ddcfc93aba2e60f1083c3d2365b484799524123487598c374fb9d002168ee8c3bf4abee4a8ab6f4417624f6875f738520a237a8de13bb6f85b797c2ca2971c85fc105d7fb2a388b6b53bcc39c8ced83f119da8b9ac45e6f8b105117db8ec6e8f1353ca7a88c6c39cbffcdd3144d3f19b98e78568567fa7c7a3b52797107d071a938354b578d80fa2ed56f935cf95c717441ba2dc5c321f882e63c6d071783180e853e60f0f9a29572de60f9d65a9f4907311216cfcd058859863f86d9998983e34315bfef5160d1f5a4b21850c8993f972660f7d183fce81768728ab193db4f15af3e25fd2ca92c9436f1e4bf8f832828647c143a795e6d93966128d2977687384fe8f2e3b967bb143dfc17f2ed509993d973a34a255c94f7d37362c7468e2ae9a58468be1b1cfa1d7ab580fc47a938c2e87b6ade348e52d2205cde3d0b4cc761c0f391c5a89e8629ae34bf1a36f683fdd3fc41ca7b44b37f4b9e1e34f1231dd10b7a18fe36d1ecee7f8d0b0a1f9942d9a490e394ab8862ee4104cb3bf3c73b66a3812938c7b1eac6968bedbe3636334f4321de3ae6e8c2965cfd0bec5a09f2c7cf323d50cfdce76f8f0d0a1bca765e862f349749c38cd3819da0e3d9430a12f445fc7d06ce8fc211e490e37440c7d1c8f650acf5c18baec28c6c3ff4ca97209863e7cd4c9346cf9852e6696a40e5264d629bde0ee788762216517dacba251e6efef91830b6db7a64ca56d1d69670bedac448f25ac23cf6aa1cda1e3c0225a4e47260b4d8ee7c50c162cb49d793e9049c9155a378fa23c9c88159a1ccbe7dcef883948b00a4d478c9e1f8e4885a62584c8915994c7219c425b31c584f45890f3a5d0588af93fa70e5192128576c23f46d0984daf02853e935afe38f8af7ef813dacaecbe9e21f72dec845eb5e366fe28865dad096de870dd931813daccd7718fce4c49dd12f420b455f37328a18f536576528e247415e43fdb73fe421c09bd761c72f8916c47e8cb3afc7c7c9b4a6746e85fe743273f8ad07a0e34763ef09c7727425f1dfbdba2a7b7db1ac2a51f3f390e4d2134394959b0ee144ac6203439f0a49fa27bcf4b05842674901ff4e76e1ef7075d4e91e22d7bf0f618f9a00d952cefe566529da807adc74172a4973bce1ea73c682e4492ee38e64a12e60eda54edd061bd92eec6e8a00f3ff4bf728ea3ce9fe4a00df3b0e13a52434faa30c00207fdf95a108b1bf4137228ed000b1bf4f93c42f64c69011635e82b3cd8f1ebce39087eae000b1adc3933e6206f620ab09881f3a1a5390e13942e180b19f4b22157c794606d211a835ebcb37afc59cb1a60018336e7cf95731a13b2c55774def9a45373eae9ddc2408118ae6836dd242ab27f1bad2064fa0792c18ad63b42f6c77157cc29f2426b15fd6fcab4a7c7df8ebf14f4862abaa0bdd9f2a772fcdf918ae6376a9cd81d8e8ae64bdd67b4443cbc72e31407f78bd149fda2eeb4810d537411dba5623a3c8c8d5214b934a64c5aca7e83146d2a09ff5132e2666f14edb7e97e3c8b09c810c5a11e690945abaf9e2ac7c96df9bc774146176801156c80a24c50818d4f3426317718225bb673b4e189cec26fea2859ac94471b9da8c3888e3bfee33638d1aa87d972f286364010460540104605c8dc8b0df762c3bd303ec6171b9b68e65c67b543ede41b5a3c6c68a28d1759316697d86123137dcad12fe614899c2a471a3630d1248b79e37708bf631ebe44177290b25561c3126d2a9554a61f669ccb57a28f2152bcce943fc4a794682bb253f2771c92868d49347d9dd4f23a8e573667860d49f41f8739d2714891e8673e48c8c48f0a5a42a2cf52d758513ba7d8091a361ed1c771a01e6c59f42cab3aa2cfb264ba2d61239ad99db228cb5962b80c1b8c68c437e27a8c1d5fce2ca22f37eb38b55e868c0e29a2f590634ef8dcb17bdad948441fb59f751cd63d7724756003119d8975e4b2aa396374f1c40ed1bea78adf8d9862270d195fa40e360cd1ce25afd6bc51314e4072b0518826c6920bb764395e33c9f8c26cb04188a667afc1c620fa40b542b2e50b195f706e08a2d37ecf98b545420cce98414601e0061b8168644e4326496fe92da5b001882e4795a34cc7418e317fc0b0f187e3284274143c0cfba1fff2cfa972de0da5550406b0b1d1873e9377e4dcfed1c1253e3c63613c4a31f651d8d8431fa1cc22f23c4488d238b0a187be35458fe7cdc233e571d8c843173959ce7bd581872eeb48fecef5971876bb431f6bb6bc317eb543b32a5b2e5e5193ee8c898d3a34923f4f78cca8c694c3111b74684b82948454e4462cc100430c0a0c60830cdfc0416ccca11f4b1d884e47fde7a148860d39b471c38697f03025bff6b0118746c235fa4737934c297068264353e56e8ee4a2586ed87843ef512c0f35462f4f5a1e0c1388e1051926c0256cb8a1e9a9544d91ae0e1b6d68f62b5e4e1de51cc6c9916bd8604323e7b12385d48e9dc81936d6d0b776188f951c952594890d35342e21c60e27dd3b9d4f431b347ec6dc1972c48dd1d047fd71d13c7c5348ee0ccd69383fcde172e6206486a6c377e4165ede284393f37d35a5949b31a36c830ccdc797d4ede06d8ca19309298f7914e425fa5e68bd9f31b80c1390200c2e880336c4d066c9de9ce0df91d74281296c84a10f43d860316fffc6e4f1860d30b41e74fc96db63d7ed950d1b5f68a2e6f7aaa58e171a99fe54e99d25c548e942e39929e538f5cb85ce72e2cae7508247118571898d2de0d3d571a19348c70140061b5ae827532d8bc44a1e5b70230b6dd69c253aefafbb7c1b5868db5bb4ff2b49f8b8dcb842a39db36abde586159a0eafe392f5286e4e6ca30a8d685b0a1e32e707ef0615fa604d3707df39b3996f4ca1ed20f7a25548b9c3906c48a1091111f2e5284f4751dc8842f381e6206f0ec1cbe3bc0185c6e2bac418e7ea51e8369ed05cfe6e497e12a5fcb3e184664e25979ab6fa668f8d26b4dd3926712598c7ebc1847e4255febc5d2da1b3dc7fd51eb3708b12da8d9103f7603a4ec349683fb64ceaae4868bb530c5515e2c6609e239431232b777aec6d56000370d83042a31d65277a87949b2c45e8e32847e9c713a193941d73144f1b42b39e79c32b17429fe3d8e820f407daa706a14d8fbe397990044217e72fe3c48cfca0130feee18c5808a6f141df61f47ccb1cf6a06f0ff257ea8f07bd85e74c612ea587d8d84193e15274d04a6754fc38cc6de4a0d7f550a13dae9041f40d1cf4f2ff21df42cac60dfa6ad70cd736774fa110366cd086cf2edf221b2c8fa5064d07e223e6d55164c378850d1ab41ee60c1f2ca7520deb08024f886626a74e593e3439cd209a9f8fa1a3e74a109da4ea70443e4ba25781e837fbe4486240b472d1fd520e13151e7f68a364e64891b2511d7e68f3e5306a6c4e1ffab2d6e8fd973fd29e0f6ab84eac30993d741db59458b2dc92a3e8a1f99c3984ceee165acf433f12afc43fc74357319a84b21032ffdea1d7f35d71bf0cc92479a145021f030558002decf0a7086144f282c6b7072deaa04a46e4a9480f1de8d41cc4b8acc9c390cf812ca117e283858b1c8c987289ba71305cf3e7e7943c5f0b8742cebb1ba299e4f50d84855b0c96a51e7383632215b72bc7671b709fb0a1c857e6a2ad014db596a8153653433299429c69783ffea0634db2828586dc7552fac87568f50c6674c9142268863cbe62ca51195a94a1d81c9f67b6eec9c960871d7ac7f11b821663f03cea147f69218672abe68e343fe69f6811063dd6cc0819f12ab400c396a3915a564f225f38881ea847b91d3185165e28477437768e444e68d185cb622275f8e17c092db8a09a94856ce11c3d94999c2be6994e125a6881f61859c62a746016f61217f5d852dc082db050f0deaf18c4b305115a5cc1982c22351a841656484235a6d44d425e225c43bbf6c75a1681d0a20a5d0ed537240499efc950a12ff198c9251933eabc012da6d0468e244954caa3462f855ed4bce3092151b0da5d5258446487a499e76027babbab840a141acbd9d4b184888f931201191e017e42ff1e04f7de749dec7138a1dfd48a297fbf4de8247e3bccb3d482094d7cf01e9c996c77cc92e107022b042d96d04f44a890d2cb39318712faff8afeb82147f4f8c83041195e4612fae8384e22fb931d11720186a3e084712ae00024b4d15775a37f4e0fb4c343d0e2084d78cbd8b1223bd0781aa1c916d92dc63ca9a08cda8116456836e7cb79a3a5cc98418446ff33f57c1ce7feec41062d86d0a9f6bc6c588a8ee51042bff9dae25f122d82d085593e8ff9bf7ccdc90fb400425bbea3a2b1311868f1833ed888ed78ba73143fd3c2076d8c1f232e4abf3102139c318e1765b418177032deb40a8e731e306386163de83a9e690f3aa4ccd3e9620c4e3248a9e038a7f0400b1e74317cfc41b5524716f41db4911ba13bd0685963a7835e3f8cc7f143f2f0c972d0a5504962c829a84e0b0207230ba2050eba1c9db2e3c07431c8f053012d6ed054877420ee795367ca63fc30c4cee03f8a31c6185d06195f4060c68c32c8f8020c2d6ad0c7a9cc75354483b6f7a5030f966a31832676888a297f6402410b1934d51e3de5e41e133bc7075ac4a0d91cf762b01ce247086b0183cea35c31ca49d2b278456796357b94424c88fe7045e3bdeb9eb2b15624251fc9cbbac223e5598d56a6b3a2490fd23a948ea44116ab682c696c1dc91e7e3e4b16aa6854f3757aac7bac3bff171b3ac82215fe67e7c57c90052afa0f524549d9e152982010b23845a7b137e4f071a4085998a20f73b57b01734e505994a24b31d9c955cf82147dac6c112cbce6bc3082208c030618ee8521358a765a4384ad6065918528da6819e3e7d2903de4a5a80e9045283ab738fe9147969a73dfb53a458c31cab00067185f8031c619414a80035d6c16a0e8af6389973b66440c922c3ed1c58ec31cb917242b6a0ac8c2135d889de358df25bf8766169d68fc3dc5239ec50bfd8204dec529c3bb380970a08b195970a2cd8f77d5346369ca9a008c83d0c86213cd6ef438c4b7f8a852e9851608c400e3b2d044e791aac8ee0721e6202a06042090452608d51e2123e9f22d551edf96d949523ed30e08402006044820860466cc00811860dc186590200b4cf4ba71937e283dcb41040990c5259ad6b1e496272e464af142eb28638c129041bc28c3478023285f808112e0401706c8c212639c32c830c1185d7421802c2ad1c6ecf3207794e8e2f3587453a96c4da219f13c97949f0c1d49b4297e8e0e35ad23f44874f261b00e793ab8ce42a24921c6c47eec11fdfa460db95287238eabcccb50d2d1882669ec38984d32be3a235af148d1a9938be843644e3cbda388ae83dc6731663e115d8c68e6974924ff4744a79bfa39ce07c9f410bd5c7e950f4214918c217acbd2a1b8c40e2c530ad164092944b7bea54609d195c44ac9ed39deec0da28dbd493d837acab21941b496bb2445bcc8dc712510fdc4d329f32846f0d101d14ad6bd982fb387acf01f9aaf30c142594cd983fdd0c40f37da24db3e7461a62ba3aae54363c9f2afbf6884c7ea1e9a90c3585ceb540fed4e84e02a1a1d79360fad640ff3f1a8aabc8987662e7208d731c4c75cdea1cd1452e3a2e5ca41d20efd4f9f69de0fab439339da726f071d5af19461524ece733973e827d552336b08227139f423e13834fbf1c857cee0d0eef5c7afc6ff67c81b7ab1ecb194b1b059a11bba1cc487afc44dfe13b6a10d935839760e1b9acff31ca29507d13f6be8446545e387d5d04fcc11392db588721aceaf4e296644d0d0b7799877f8c917ef0c7dcc3da61e83e62854678666adb379c66a65e834b6598c114286fe3d5b7210f38f879d8da16fcdd671a46f96e8c5d075055dc91f5361206a86e78e3160e833e44e53cba925972ff479de839cbf63fad3f2429b430fd22cc53a5b47179af6ca593cb34ae51c2e743147364c27e9a083b7d0640bae5bd1d4422f39d210f1255968de32cfc5d6200b2c3441734678b01e3e3657e882c42011e79ba442acd0465ab2d01da44f8ead175a650e092c3063c60db2a84213e6fae2314c947e850a4d5cc4eb28a93205067001080c000c1fc118624880026564318526e51cea29cc7518f948a197949009ab1a33ee47a1f999f4f289cc6715287441dc2466d5cd13ba9842d6095d8abbe961d0b1d46c6942337111aaef1fa75e0b131a0deb28e4b778098da77acef31f7f0a314ae82df7724f4d421fbc65f114292573b948e853dcda72fc087d301fe683185523b4ab9573243959843e34cdf1a97a566b8710a1cb51cbd2517363cee0101a8bb5907b4914426f1ea40e7d32333f82d06528914915734068abca2307a9723f683ef4ad18963e16397cd0e6789523ec7becdff7a00d9f8ed192a578d074acef29e1eea0cff88c4fbe7d66125a1d346dae3a5539ccc2c822074d8af3ce33abf4c8c14133b9d7fa913ae2ed0dfae431a416978e99efb0412ba631b6a3f02956fc6bd07cec39768c070ddaef9061cb2f3e832e44881c2f83c7ead465d0761c98b556c8316826ac058f96439e89d92c60d08ca5ae5c9af38a3e788f1fe669879faaae68772a4e0e93d44b246c459ff3643b684d7db3a2e9ddc81142e458451ff9c146b467fc2c1e55b495afb43cc24f4513437fcafc91ea8e0315ad8768f747ba39459f7c7673d04d3145ef1dc98338192f4513728c994be33b6ccfa468a662cac88c3b8abed473d8281dc50f1ea2e8cf355392e079729b1a8a36e67f9c3151c2f70b8a36739092e01a3bf6f844e79a2bbd34c97590f24427bb1151fbddc39fae134d8a14bf39289389184e742e972e255171724eba892e7b4e8dd28146139d4579cd269a9a59c5ce442721cc3fc27260a251918e83f4b29cfbff25daf0fd71e49a3477d6b7445f31ffc30f292fe4c857a2718fb3ca871743897eced73c28adf4d0d949f4417a641e9a5d2eb22989267a904d327eb8b61f89be323f6e8f3106893ece96d97114e61ec7d406f1403fa2ebe0513e8dec396c4ddb119da6e4cbe2714c21bfd2882e076de9d4bb1a51103423faeec84d9153e94afe5844f31a3e8893afa3883edc5f13d1464bf9348ec6fcc51f11fdb4c51cea21e4cccb215ad5205163653f79a518a2ed950e336f6abc58964274b12e3973c79e105de7114bd69a152c5506d19f967c302d2136538c20faf84b2d457b64a9631e8836b76ab9071603a20d793bab439217e9ec1f9afc4e1a311a24735b3fb4931d1b2eae82e5a0ed435fa1da6e3975b8e1a17ce873ce71f0132b8bb447f7d0584e3172e8937375563df49129669895c790ffcc43339e039d8cc871dc7ee2a1df24f2add3ff71167287463bc7e5be133bf4e7c1974a5cc910535c8736529ae70dfdb5b2081dfae8e1454b1e3ae5708373e8673b6b0ee35289c6510e7c2c16ffb3321787b62d55e538c64aecede0d085a87b91e330875ce61b9a0f4c3dec9c310f25e686be3df2555da3f524d6862e775cab47b779ac6143ab91ff5a2985df4dd61ada543a69e4d0e988a231cb1f63b5e643d169f08e714d2284147f5074b13c55c4289a33fe4f349d32c48ec7e2893e8e39987bec8c28c14ef431b63a4869860b4e34135f43ae23df44279e2ff4994eecbcb226ba1831e6c78fe33e0f93894e62deddf0788d2663a217c94162b997683efce72059e6f0bfb5447f9963e690d24a2f5989be3c3c2f6fd54a91524a9c235cd2ffad4ca2f7cc1eccc75512bd77788a493107216324ba30723197b18444e33eabee697944ef1e6f98605e61724a1cd1bbcc8aea488ba8461ad16fb67c15438611ad7c8c5ff1a23dfc45f4f103b5e823a322da3c1d4c8ca9e312d164a568e5b16988683da49ce2e7cbec26b143f4d7e5313ad6cc10bd47e465d8be9c27558568c2c79ee548c5657310a22bdd0e24fd22677a06d16abc8ee161760f4398b81044d37156fd37735cc22310bd8ce9479dc87d591d80e8fac552c5f4cf1f9ad0d1f26eaedc9bf1e387a633557f5364769ea70f6d4839921ca43cf6e83e1ffad5b10cfdd9e3c81d7b6872495fcaf1d143e725dded61c796439f8736858839c8990a21afc143dbf126cda3a7b943132e44e548430e56663b3431c741fe706ea94393538c56913bc7ab60a143ffe9518cb81dcfa15dd50926397e0ed921873e54066d11cf78b91387e6badbe24b98b6b0c0a18f9813da417d436b1173768aa3bb81102533760c1f6e439792d927847c990fc36c68fb336bf4c8c7392c770d4de5850ac1aa55432b9f3b52225906ed330d6dfcf839eb2741437f56392ea5e8b93a44ced06c4c96dde3383b08399aa17391f86172f0389a2f43d7dd6e1d7e4c227b214397277ff0a99214751e436f39f8581edbd7579e189a9d907711cf79bbb530f4df31c764ed12a53ac0d06977d4ac1cbc5c7ca10f3a0e959e1a7c6285b8f0429b3a7a9544d3f18f232ebad0f745c80ef2422e34a5297dbadfc37afc16dac99572f8778ec2b7e2420b4d0ccb323fee9172fee0220b9dc59c63c9593116da20d7b36715bbc212dc2422b6c4a48b55b96b79f8dd1459a1d3088b931d4ec7dda30acd6b7c0e7fe2a142db261973a6f8d296680a7da821a7641e75889e890b29b41d44c81c0716acfae5283431e7c07205d7183c8a5068f3c7ece9a0544206ff09ed7a08123adee9483c8a042e9cd0bacc54b77967fb894de872d64849b3a5eea05b03174c683f73868c768921f2161863022ee06209edec4888a9628e650771a184ae735bcc26abbc1e950d2e92d064a69e484745d0900be38b08cc9881062e90f07b869564efca36461924e0e2085c18a11377d3eb28fa2c66cc282e8a60443009125b56d32df898c926cba1e538174468527e881ce3e370318456d6fa4a3bf2c997a3846048b4c7b7ba77474811526668900dd3d8513008cd5896d198290c84254f8790422cfb8326c418a5d7c1c86492f8a039cf1851d9f093638f8b1ef463e65125794955708bc0050f9a78fa9df42f5b56292b0b5ceca0b510fd63032e74d06952f9ec9a23447f3f074986d81a27a3848362b632635e23a8acb7c418c5722e339fdc3f1737e82ac59d2fc9221b8378c240c104980b1bf45bda7a9583b8ec129713b8a841bfdee3711c9368840ef7820b1a7461279a570c7e6a96d345190fb89841a7313eaa14547c5b7a2e64d07958d1617967871d87b888417329535c4bd2d18517b88041e3611de3fccce38bf12bba50fdd0436732bbc9ae68c72d5386f8d48ab55c4244258247f83cbd1f937285ac683df677301d3b3de5dc8c19336690010207e3205f90c04dd08513b658451729ce9fc7b971f24b55b41324069db82a1e4a886d918ad637bb589689faae1ea86855323e0eeb2986278f53b41ec68e8ff90abd92638a26c412f96d8dce1df2a5e82a2c24a66c1e11534f8a3677c8fe0c9ef3e78a1945fb5229b24fd688a24f4d16225fa8f09933a1683b3f23cc5ac741e41450f41e247aec749c67ae7fa20df11292c3989e68226ae5b6076e1653ae139dc7241f8f858c137d9c14772eb2ade5a336d1fc07a3bf95d5b1624d74154372fce41e4c4712175b64a2f970619571c1e3a4cf5b60a2b594535293d05ea28bdc1e7ba85d96f1c508be804011b6b044931fc7af973acc1861b821c3aa025b54a277d71c558ea550a25d8b1ede33ab63f0a8056c31893effc6ea47c88f808c2f0e165b48a2cb943c94675ccdc145cd4941cf98b14524ba4826bd993437f59684852d20d1f44771f6b367b56e8e2fcae82d1e516564c99512633213a92e939365ab88394cd90f6ce1883696e7efe4479ba5ef8516292cb66844d7ff95fe51698e929e046cc1885e73e5609d5e79e3c759446bee1def9b47119d68862ad99ed9709e44f41a39c8f164b6e4bc31886822e26b8ece3944e7ff563142c50dd17cde10c345f74234111d84cc1b6ae15198107df410b16ecd6761f1201a5f8b20bd513d52cf0aa20dcf9123e71c88de8394b12c47471e4a40b4e153f01069f5c8b2fd431bc137a65645b585a41ffaefc8ca8b11d287d6a3071f9a6899a3f8e71ffc7eeca197b594838d7061e2e1167a38232c5a82cbac4584ec1ab352f37394f7bb451eba52935c71a73dccb9c143d71f9e4a2a7b873ef72b876e9e07ddd40e877df36024e46c8b3a3493f7fc37594607363e7eb79843a7dedd617cfd0e9dd52de440ac8e70e565b26532413cb4a065f94253e535b688439fe251a69d434747d11670685742ccf994ff0d6dec9d4e5e39e786c6a3858bd937d5852ddad074c624536b990f1eb9051bdacd3826bab93ff5838cb0c51aba548d50a92ffff9e78c600b35f4392ea6fc8da96d918646432fe696cc57d0a0a1edec61a54ee919dacb3a162a74984b4e33f4c15cf4d59094a1f5143d3d98c9d0c67ff195eed2b8dd18da12cfe8ed6187181a09df610ea984a131f349ef1cc6670e0443ef2aa9439969d209cf17baae0e9ea5d2f142d79271ca3ae8380e7e179a385a923de6423b2e7a955956762b5be8aca3f77fdeb4d0c5109e7b739985366f4cfdc974c4a4c4422391c9523fe4afd046ca731a916243eade0a8d07151d87aa7d15fae01f967d7e36f443852e6af40ccfbd9025660a5db6bacc6624ebd4a5d0c4fca15fcc1185e623f6e3e81ff8e40a05552c254fe872f690425be3f3049dd04e48c53f89f6e86113fa1caa634217436e768be17bbf324b68bec2c3aec7a184d6df75e3bca624a1f78ceb91249c24910b127a491e85d35096237496e6ab7f39844ead18a14d613263468addcc4a11bab4cc3166549c601d44e83c72d18991433e9787d0e4d1e411bf91e56421b421d1d783de8e2da94168a39f4c274dd7a44920b46e69d1f5ff4193b96246d6d7e82bfaa08f674d5ddfa273df83d6e3c30ba93992871d0ffa203ab28759f31db41956b93deed001d98347e6ab9d1c349121235b3538e8243d484f19bf4153b9355cfc7c7f8d6dd055de309d0bae31d51a349165e4429f3468fc93ea89ec6a5e67d085e7ffb8cce5838fc8a08f0e36c69847ff25e2181862f428f5b9050c3af9582be4149e4288bfa26bf9690bef9d63905dd16908562986755bb1ee25e9a05d2d2bdaed8eddda320459cf2aba9cd4c3582146e5aaa8a233ef0d1762aca96883ba48f2fc593a0c2a2a7aede061081f876ce1e929da0e3ecc7dbd4953b49393f1f2648b8fdb2c455ffd319676c790725092a28f190fe37488acba194593ca5a62a6228a3e304f5db1ccbbc33c145d4e7e1e7c9ca942b4a068cddfa307dd9692a39fe8a2a323c98957412de2893e4c12c233c7924e349ddb51251f9c771ce5478fef17249be84c53900f5dd1447f6126cc64ce44df1ec648f4ab9c4c31d1c797e3f15bf2124da58cde418e11398c58a22b8b29eae7f78f8855a2cdd4965fcc23c9c194e83cc55bc7f6a958164ec2cce894fade91c41da5b3753a26126d0a6b5176344874de2ee2e24164dee8239af81e269739e7284b4758512ab9ff7cd788e6326818d17ef2689f0c5ff1f24574b13c96b5bc39165545f459c7c7b4744b447f19bf22f64888685db7e7ba43c8ec9c1da28fc3c91d628a9bf93c0cd19c84503e63b911390ad1476221459cd0a85d9cb04dd40c09d4d044bb121fd4a233fce45623134dcc5491c1428889fe62e64dc22b87fc9d4b505111d63d24d2e53492789ca7af9a9a2b4bb496752b475ccce341a322ad44b39d247e0e3b23460c5551a28dd39f4366d49844f31e1629f2516388312fb45270bc18a38624da701e85ff7924a767196474c13522d1a78e544127119c4382ab306a40a22f150dda5a9e23da015c400b3f1538e60b302c3063c6fb19c38b1a8f68e473cab58e880423f862c60c31be9831230c31c8084117c403351cd14ccced8fc9fd734c914634391583fff6c5b3ec1e324e6b30a26b8f42920afb9695c75c44ef92f139be188386f55e689522721177ed88ee08a6153b07965fad2562944186094ca2a04622fa58637f8e8ea310c6224434932d4bf3c76124c0812e3a50e310fde720227d3da61c3ef203350cd1679887612768f430627c6156a31035a38b1a84283288ce427514fb22c1a22441b4212edde3df51cd4c0944dfb2b9b22da91e203ad9cf1cab8669f587262a84d8044e1813f0431fc6ec71181de7d63ef4c944f2f54721e5fc9e5386392448c109030335f8d06b85a62496e13d5c650f5de7e461476d215cd4d043172722776e88a229df3cf439b1ca83abb8f8a8bd400d3cf49ae3368f5a35e5e36bdca1af0cf97d3a9e7668f3a655b67c130c375f8ce10da851872e848ab2da15ae4187a6e273a4882ec95f2c736852aa30e91e1916f372e8f2bc8558fe6b7c1cc7a19d8bb7b48810aaaf630c31bab8e2426b8cb312a801874e3497a708dada1bfaf1ca1bb365e8863e3d4ad69be12ae88f5f1c647cb16de843d5e9fcfdea38581c12a8e00227a8c186b6d5dfb727768c71ae54b02a18a30c32be00c11963b1a8b1862e728cdc815bfa78ca7b0d3574113acc62c307a7a1394bc991db927277fb020d7d1ceb257dc9e9ce397f71863664cf8ed62329f53a33b46b123ce7585a3ee71cb30c7d8e7c18faea29c4ebc8d04cfec8857ea6f4d70b4550630c7dd47164de117693ae19821a62e8e727cf4352f2107d30c410a310306a84a149091f997e1a9bf3370118670c12e8d6004393323df2735170c2c87a408d2f743929f84ac830f1438f17653805d08b329c04a882320c6b7821e9f8d4e8f430bd28c32930638617653809ac46179a92eeb0fc389ea9dce142d37158de32294948c71c831a5b683d6ed54b79f92f1d5f95811a5a204785747a8749ec0e1d3b88bdfb9d118c2146162318438c43c728830435b2d0cfc9acb85b120f9d030b9de59cd692345f08e9d5b842fbe167cc4791eda08615dad02107ab942c556822277ad095e32ed3920ff2955353682fe530c6ea9895821d25662e2b12663f78183db6f0fed588423fe7796e394228f4df7ffa71e0639d73fc099d58d27cfdf93aa14939ec5e74ca3f51bc1a4de8e7a427abafc845e960427b1d37d7e3093d95923596d059ec652bad2c73b9d750427be63e394a981ecba91a4968a2e61c7f90e3188db94442eba1c7b52d68dccc498d23b4a512c334e7e04f623542932de4c0377a90e203ad4611fac0cce320870813d7825da84184a6b53f0e1e650d9183b2c610da301eae64ea901a42e0cb4b364d3626e462d4a4ad7724be5e23087dacbe21a2e7a15103087d4758a69c72c4dc8bd4f841177be5a76a1e749c1417d4f0416f31e7f0711c873ad12b1aa8d18326524a29fb8a575427f8e279d0b59888598839f40b911d3479193d8e3b879831fea8801a3ae8acb5babca3779cb7fe88c01c2f4c1da0460efa97ce103a87189329eec20a013570d0c5987bdba7e3f042ebc518411727f8e235896100498d1bf49e33e4e88670123d27b6c58c196470a0860d5897c932cdacb67c2d6ed651f270dc628c8302312050a3064f5eb42aabd04a0d1a7469d5fbdaf1bee50e6bcca07dcb59ae12353564d067c6a6103289bc6e480d6ac4a0f5958af929c67828af9231860936c83865a8e00141a80183fe554cfd7472102e04f9159869e49462ae1474572021598ac9b424b398f378637fb8fae1d26945cdb00fd06005e617e3356ff6e862154df010931b2e55342d9d931fe4f1ca3e53d17a386b49b2ffa86867b5e28e75d0ca9a9ea20d1db327da79fafa32451fa5b89cca41a4aa2096a28d91eeacf33f0d52f41ef5f587f230ee5f6414edce699c102cacb542a2e873a4e38e7a726028fa30a49c7312cd609283a20dd61ac2c7fa31c7fe137d309b67f27253537e3dd165f99c28c13c59a0d1897e623ca71034ed82137d98a398a2c904ed1c4e3671989f7eb91a249a20a453acace32542965cd1f17bd2426fcae1c633d1e6f8653be69166cc5081930013ad46650fd233e6f5642ed1c5f550b3bf45cf0e9a25fa0dd1bb9a2d6235b7342ad1efc967cb7192b52dbe30d0a04413f9b543aa87b7dc6904480c3426d17998e3419eff3424d14694c76747ba2922a511095b4248e99911d11919e1fcaf54727621d164979cfb51d64b924fe31148c311cde97e141eaf97bb4e341ad1c7f987acec940623faf7bc39548b571d4cc80b2dd23416d15fdc19d5f79d046474f1619cbd2d6828a29ff0881e62be89e8f26e45680ef3a494e28868a2a4d0ea703356b0ce00b2a8c0000ed18a6699a4e13d06cbe186e8d5d5df633d4e44d86814a20f7bd64388463e54f0ce6a10c746ac96f530590db30a8f3e9f7353105dab455089cb1e926e8168336e795b860b99e9bc8006205a4fd93d74d4f148a56e0334fed05c4aedbdb8d471c6a04006fc709ce30939a6e6c873822fca300ee8432f9e5f5d3774f8d087b5aacab1bc44f5e0c3f6d0a6b02c9e83d0d1431f66ff353c59fc60df3cb4279692d139c5cf2978b023424a6db1d2ac70edb2a811aae330436ff40e7d75ec1dbb849a7b920634ecd076c8d376491119abb716d0a843fbc1e9e479ac1e5a6cca021a7468b6e378bc7942630ebdec57a5ae86201e87d390435339b74e87e415621987befd224c0e2347030ecde8cc871c8efe78ec69bca1ebcfeb38639a9ebd83861b7aff9c13abf420c5cccaf82205dd86debca31ccb8f65bea794061bfac941c4f030923f25b9862ee79f3889b21e58af862672acdebc93a7a19dca3ea142a40e3ccf6820c442cce2552ba52245348751a3433fcc9fa18f4f63e67ca41ffe3ad20c4d5a79676e4497790f2fb454e0609c2708a051862e75bea499c3fd9d49bd503e2718c3041b840134c8d0cc4731a7526bc8ebe163e8d5a4474c3f500c8d793cdd153b6278ca85a19f958ca81e8480a14b219faf855416ca6234bed0b55694cc1a294b8aaf1a8186171aab94ff41a33bb38721814617b610c272b8d0a6981ca7ce9763e728660b4aa5b49696ba8be7d496e85042c866a98523648f1fa4948359e8e3883fe529b246961c0bedec5e0ed9b7fa3ce8aea069d04d71d541acd087be9377c2a7860aa92ab41dad8314298f87217b2af419f2e57b5290f880c6143ae9ca294fcb850fd52c1a5220bc749046147a55f954c13333776cd18042ef139729abe70b136b25c0812e4a40e309cde84f188f7288d93fae40c3094d88978c31b62be374b20a349ad078d81caa4a2b6088210605864083094de9f768b05066c1b41933c848028d25b4bbad1fc45eff281da884e3534ea4324224729849a3e473fb49e8bb227c7aee0e21a10bf359653acc8fbedb113a9f95ffb3d41aa18f994943a308fdcf44f74df2d7595f22b43e7eb953e9440af9131a43e86310f176b11ca42184d63b3ecdb09b6373402308bdf8678a399d41559260d0004219e54247d5ae9b0e68fca08fa37b7b902da3684a9e40c3078dc4ed30787c12df3212e0401763d0e8415b39de439c077371f1328e0596060ffa31d11c8ebbb883e63d65fc7520131a3a68639ea89f43a3b9a5470efa9839211f390e3293904ddad224c485c5a9ae786051835845e3068d8e88648787d0b041737e151f3f7f6c1768d4a0cf2db9d271c4e2a9478306fd6ed23897b3874d39a331837ec6a247d8d8ce3c7d18dec509c304639040047e4880c6050d192c1f59450f271a1a313847e6e16701346080879db35264c82b1afd0fbce2e58aed7e990017aee8237fdef2ce5ffff1080317ad68a72f75c8d639aabac0052bda1c4faa77f0e72a72e9904b17d772d592aa88adde41b7aae8a3f2f8e7c3f1308e5952d1947b76d49927756872810adea4ba5266a2c746d66c8f7390a1e2074143f414edc59dff08ebf8ddf31be0c2145df418eb96a38e530d29459363f88b152e9262b7886032d96522d77f23ea6ae5b3f8289a8f538a9fca038cb9a834ee6422a3e15030168705e360140347b707e31308002844240b4502815018869228fc140003642c1c2e383014201c181416188b04c240100c06040301e1200c068442817040182c8dc3b41e0d78bd0b74d210351b537ed4ef738f22d158fe569b435324415db28bca1caf088f9b9e24c61accc9474d01047755d27ff9fecc3daa277354eb7d174e7f6078319f6ceffeb4da352abf7c0abb3104701b7414f3dd049f55230c55c28a22f445bb7f4689ca9cf65adc0f96399a72920f5d42f754044f5f2c3e0590ab9baa5d166e9469d335049a08e35ddb5f042b88660efe72aadb87907e72958749a5f42f22be4b019135f7894b9dba40c0c00134650488a2858d13a04527b3925caac3e3877d0a3c3e85c61c8fecbdce8fd605fae56a70247242e6c441503a98a33e295d45afc6cc0b918c06a633980ee00d7c9f6ad1af100f82d47687d83b5407e3daa6b6ad85c321a7de10e0487aa9b2acca73092f2765b7ba4d13c40d3e36b874dd07a1c771e3c0a4c880734c06bcebce4d8f2a6358fe0537d57c1b0bca051b68a1a10d467f1684e7524e169fbd8210cd81ca5e83049dc41b5b5214dd2dfef16b223a8fade5c54ccafc48847526a7886fafac7f08ad9cbf4f0c4794e934bda01dbe39abe8a455fee381993be0b62cc0900b02758e7e75bc25e56609d45d848e4a24f963b814d96a93d5ff4ad1eec24d455a5f160a71922b5a4017210e809868c4da3473d780f37ebc847cb569fa659ce862bd88df41f29f8acced19c5607ed08cc5a7da259b36176a24afcf8461221c906d25bf62a7f7cc38476b56456db2009aafc5c353a17fbf7119aab3aae73ffd6cec4c7790e1da154aa840dc42bdfaad4224253ac422fb6b0adeae11403bea7cb69905444ce5f6865902f8f4d17d689d5e6d425417bc8f065109d933791b2db186fcc435cd452898abd1cfab06fc5b952e7377b735da569750787c20a06a956563c0f8d9be36ab97841866f278011cdb18b440f280f0e4a7352b32a369e5949d468676e1874a41362d6329f2417c21278b7de68231ebd93606b3decbd1f1f415ae48bd6e67dd177f6b4aaef37d4d111d44bac9bff8a07ace510d82401c218951e5db7de5d58316202809a3bb594ddd9d9081b79ec6848b7638cdf3a96e2989e39d58eb997129eebbd3f4956a90e099504f1ebc8208c7ea2c1139ec5a6fa90490e6d995686b60f25f7b4d1c3d4ae3f9a3998dd98ec36187eb7dd91ed3560039f91241e5aa7f4bba784cda6971a608c54cb79e92c560fde10b1621aac423057c38d49b5557da235e4569d3a88c56802012b2ed923295f800dc9692f114f6ca68aba51316a4fb022283fe3ef3ff628bdc7db9b45754039c971728dedc7c912a2fe9846f61a030e7b157f08884f53fbc2614695006d69295d58732d6e184cb76588016eb5f6320b32645356419a1052730395db6481f5a9f33456a6104ffaf029821bf0ae61591dea04d161d1b46c3f33424816e5de12a0cc8bd498bc84c835b749f1dabe2626007e6285825c3130c9a4a53176fba6691cd95b5d56c9262e7c162af37b40304c00106a0710617f25db78c2ba080d8ca1d23dd7ac1aecf735e76e6b925b7c806f9be8b5aa5d94871331964741c82d730f750722a9a29b264b4d9fa8ff1945aa9874087d6086ae5d7127a8b59824be5a771c5255fb4840d4bafa0883bd854f58f2b1dfc9ee282aab8a0328b1852e5a72027a1231df1b5f84c6bffa2867497cced4fd14967a68da3075bc792acd624a1e2912a5c1bedbd3e1971c37adac889737c4183f9854d09b9c6a2c93ef9dfa7c3428953a25c4e96b35dc1c1ec7f750bd5db36d66dc259e4093848dc6a864fb6d58df6edcc19ff6374981a8b0fbe924fcea1483c9049c335045522c4d8930727a7fae95eae0e09e5057ef99f3614949ac28d1ec8250178f8adcaf38990439c7d95456b70bc44dde93817fc37081c851a5029140daa0929f208b489e944d72d806c3ec09df8b43a7ec5f49a4ce6cc86f746ab8c017fe6d750a59702a0cfda04275b8d98a18ae56c27ed7bcdbd8604d966775e048fae4c95b27c4be12a7cb79292f6549c1bda79c699e97a5eca33848b3fe74d5072c2d20fe0c4418b8fde536d39ba528fec4ac48c6cba61c9c9d2d11e47147ac6b16f968b8f7233033d5ee535dbac927a71fbf13619a7e61f8d3d59e703699e3568e64f67696cd2da06392e7539cb439b0e672bf4ce9c0f85e5de6fb091abe36cd33cf2e6c201d8ba39ac34c3cb618e4abc56b9d76200f67f2c8fa39c3133a77d47e5e8d0e60f0949f68b54aab5dbb52a909c0658001e69275bdbd2a95bcb689d3e639bc0320c9d41cc855d45f8014fd28e64a7a4c2190ef928be7ccceb3344a090fbc30039fc648078d9a582385c9aa21d3be03ecf7fc70530215c7c91b615e0bc384a1486ecf51c136debfd61679a2142e77bc21ec8bac5279a9de178812532bff8ee0118a530a853f907a64ac383e4b822926c982505a6559a31fb4364e8d501b5c713b9a4879b455677231018a4217475f15934f251555298badf3814d6e6e1866f72abadc50db23c717497193a31c80102bd3be4195433557eaf476a87f12ab4daba30411940da53bc1833f53d5f43bcdd77dd0bbef57d4fafdb72d63d65120c2c0fcb1b2cafde8318b0d7171584cb96c9bd5547cac87f705c47c8c672b03cf03a47c9a524b5325c192074a49c99f9fe8746812d6e87452e55faec08213693326edfd70673d55659d2257c1cde397ec49847dde1c74825020054008fdd535cc679fc64cd08b86c868d71320356d09d01bf5a671bd589334782671f2701f7b46c7418a714e5ebe7981d508fb66c1d49c7fa6f6a374a9c1b6854111bffc64b5177357a6eb6d5aa1794c5534345d8fd99eb9124cf362db1cc48ebd86647933289f31cd57f3e26437d32e0dfb3704940a21bd1bd5d181d44fbb676a10281983c2fd345fcd36ad56066152992c42d084fca752927d7f0888f140535382b161d0e1702ed6337457d6c9057611ca022e9a112edfdddee9c48a897739f1bc83af19007a69104595cbb9e1950f6bc5cc31cc057e23ae6b0753d5ef6ec19f3d581bc3c412e68289e338c3b28c88ec65a1eeae85655517dcb5239b2a29d44c4a3add644cac87626e9ad46270f6191bccf48549108b70aa62b92644854a52cc1e707660ecffb1eb635dbe46a9d20d9538257b7a7d38719dbfef551fb70769b1a97fd094d3bccc7a54f051ae0d9ad1853a0f42f68544a66a8219f3bc6343ba42784013da430776bda2b151c697fcd13536350226d874aaff1889e813a973604f455ea890fc3c12abfcda72812d582e3255f27f8d8a3cbd1f1d358c3703bf1921cb21eb5254a19f2f683dbdce0d7a789e163513d94fce3c7fea3588f1bdde306a3dd94c6fd6208766fcc64e44aa21da9d06f4327d8c0bd14191484357a8b46476a2ef8364f0ceb650afd48239f86f2b1f3a5878452ae0446023c117a57c1393828ce39c103ff008b74b34791bf557662d4d5a22947897ce7a0521e354c3479c805ae334b006ee49e75995f70a10812c0048e71c02c3498575948bec41be5a01deeaa7865a749f141151bdde24b63c56b83e5650eacf8124059e99c6b3707e74401c1e425bf02330070bf19b10b6b25079cebd1a640ff0b705b84a154f23e2c5344672136e856e9a13cd6025f21691bd9e679baa987d0db1836f3ac32b3c72347d73b70830c1d598f8f283b0cf38b78ccb62b539d06b1332b7919eaff07b1b38fe682c6a8e7dfad4c270c298443eddf1f3ba1ff8c7c904f5355b24452c186523dd2e6fa88cb522842a12da56eecc459a9a88a4cd959eb75b7ca729c0c59afe0957e41b1a18aaea9d1a401b1bfc4c05e4b03a109c0db2a65369cec2d66e6b47a99f6e615b38065171e8308f13b1c626f130c8254b4d233b167cf94af23fe169c718c4bc8cadd7691af2fca4367d93330b40021a7bd63a4aed16d4da8c0dd55ab9d6ca7f07a11e433245544e649e9c6c81bebe6c6e92537bc206b1e62538dfab68d217224e95fda90f48fcd663d54b2e43bb72d97566f0f13a666d4ccb094ec586cc616cd62bb5680e857accdb425ce46c0a5c0efdc583698be7227e6de8cd3b643b70396e867a1437775eba0c93e23388873b8a6632bf0eefb6fabcd8d34c241d92c75c49921237ed3d7b206085383584182296695d7aa9023480c74160a92114cb5200734b1024ee56f51023358ec806d33be203fe666f6cb36318d00e5050377471dc432bbe1f6215d93878425ad522b6e58a5560846bf33603abf227378cbaa4454826811f3ff2cb823e5dcf5c1d6b82fe2f29643f6b6e929aaf2a92371b92958e999956b0bbb4a9aa7a1d2f2948d2b52f17f4bbfa598bc0489900fdd81ec25412ef6eedf6f9d6d49ebd614c8140375bc770e8161b31cc1ae0cb19421a1f4f6956bd9b66af2ecd322e64cdbd44e9beab804b772e6941232db695b5bd28e48350a327cc02293c412716189a6a103f20787197d17fad4e6e7764711db16de544e71324f92fc2b9971f6e044f3e9ee8259c8e09b3143c723b8ce06e753af8b18473ad65bf02d263564e1be4ce81293027b8456e7990dc75de2ac279250504facd3b63823850462f0609e0dd164cc098ed36fc8b5892dc61160051acb98fde56440303d9036f28fde99f37757286672cf0a32e6b62867178ce2fbde8f3ed1ad57c6eda0d35746a39d2aed6476ecd8912775ee92331636ec2eb93166c32c4c57819cce35cc041d36f3f094682641d9054063b1e3d50cd52092d74a8bc95bdf91453aa54cdccff625281e15e8624edc8bcdf46f6ca4b38ff90876f46d137b09f5c9431fee71c28eaf595adcfca7e3847cb077f7a89cf7a37d28095a11f6b03d105756b7d26c54ae6ffa7b8175405893b4b4da60cb5c3349fcd58d9e8ac8984cd33ddbc488976d232da6b8ee443758e0118a4f6dffa7af9465e42a3aa15f14b35b5d23534e7986fb6073e16fa693661d696cfaafc2281b833e3e5c929cd95c7e22a66b173e10fdd045494f1a3a92dd2ca29f601c8a1f53dbd1bc86d058c17d35d23a24615612128f137ff7572cd2b33c87bc244034264036372ce419f3f50588a363fcc104ab353be2676cb7604e6cb2f93018490b9e1309a1ce0b408aa46ad48b0abe5f68b5cc8d8c66e738d4ae684dabcc5fec4d76a3c2c9cfda840c060b7b1134ef3d13ed78781fad634a627777c9084c5f49422d40a79321a178f6607b21700bcd560ab654ab30d3029f8dd349b2913cb3c6df5801d14faf32e09238a3dc1ded03ef8d2e7fc5212fd1e7f4119d996f9b7ce64d14464275a46ea36ba8dfd89efa54c33c67fa335ed2928aba007e28c223f8ccdfa003c22e963b64838ac894388c3fb04aa000d17d1f4214c7c7605ec72f7323e5e676343d673d6077a7d2556e9e1047e670b4111ab27e30e6cd6b5f593dc1d50b205ef5d8eb515264166cc41b778cf07efda114fc0ecf61e26a40a981a906f9b37510c75803f109f0245ca9a68a1e0768770e2e7bdb9506b6ecad958db5e6d4cea5e2f58dc05cd352b0652beb48f9b9edcc97634d2aa7bdde6cb94971c7769b5224351760734fdb72c3d61562774a5891815f00d5e129d7844b2fca9a0633e476f670a4ecc728344e26500359f07fead39ece8b41d9c15f58e2c101baf8fa21ae5c253dcd98e885b194243a79b33d7f108024aadec27f8c49fa379de36b05186b81fbb929f7c1b86cf4a918e276cf352b443dfde664e891a27eff4a687087fcea3b23654dda029991dc2650f860e02cc0561118b08faebdd24d5755ce96edc3ed98645eb7d9a07ebcef683c022287ed94aa97f2b19624119cbf3d0dea52d1392c193a80f350eeda8cb3a8e52c2f3b0ae22f0a2733f3f586877e0787b6a292363704726886cc8609b4cc7e02bf73c32eeb56debf1552579d75f8392f45159b67d39e9083b11d98ae31574a91b5c5a086e6b154d1e1fba479550609a8a91ec0a89966527baecb406d9a2de6a9c2ee90a769834c58c424a9db7eef88584376f97cbc490d77b27b9166df0d410ac43b3d7cca304ac3a443b915ca2b474833254304cb5a4564f5d50742b23063eace4463bb3acc16b8cda01122dfaf36e20a64bef2b9a6f7e2e17bee945e361a80d440d7399d769c0bac231c6086760e5ce66bbf7602cc74b237fe4eab12d642084f179302708fa9b20a0a8345c1f7795cbb5e3a7d638c7e1aa4aa03064665e32bddaaca5684065692be6c379f3392836c4ae63dca74cbe38f39e7230ce9b2ab3b31e5017a0cfe9be5045ed16d9ac9225e23b5fadb01ec5260783444c2722e0b253a845e61b26fe2390cad437a381cf4452c9844e2af0eadd7312b1ee6cde1db0d8249a727d53a7dd4831833145672d9a998a1eaf3093252d1f2b8bc28fd27a15cd8ab167a30b81b869e9c266846bfa04136d72fcb03d8e93004092fef78223d088777684d5816b7f4649fac8813728340fcf8e009c65182905cdbd28de4551dae7d1ab403d82cfb21596cf18b467ff7f428f43e24bfc3e4ff0da15b1c923923e3b947d86c35f0a2e75f80d0b4d59466bd3bbb0e69cbf11cf0c7468bb26b092a068cef99378a9b62542b8ba9dca24c2416822a2d86ff3f8203055b64c6dd24ced5cc515c7e4c73e8b0da26176ef1bdf0cd2529d5b15fa012869fa5d39338ad3988a33005f8382e1e990e06d9007993f8f45174a60535311f195704060b5d934e4157734bac7c858d575625f1bb2619449dacd095961e035c141cb28fbd26391ba5bfe2728c41ff07768023160cf5306164aed18a6a10b293783ed31772177935e1e03e8597ab219feb0a5d59838f255cda5acfa538015ada9d4cad23d059504297c0ebf3695c87b4620e4318b486cf50094524dd23e24422e1f0bf2b7f10d62163b78d69d978ce35e5ad022c71a57d03746e3f20ab8257ee1348b4087b7c93e347361030f967f8fd51a6974c34624a470037e2c8be8ea5625b122354856e507cff009d304bffa55282cc1cc6e74a8bacf27bc52a50843a0f74263fbe9976a3cac068a68a4b5bbdabf3cc7ef84e677e4bf7ef616ccd3e21b48987c90a853cc5e0b1d34a6f9221c602dd7ded3d99956a4a3395fe0b1dbfc86395a6a9d5767200a9545bf1b35b8bb2d94136e7db4c6912e04bd9d4d81b4148a03dcc4de20b5594845b25e0cbb4c4d4db6728c2911b2ef94c729f87c0833a5cb8e482048a78243955cdd1cd466ef077925288c5783c00a800331338c3498176f5e5ab93062174b7ac5bbb4054eaa934d9152b734158395a260514caf8860c29ea75eef9487fb00b724e0e6387b9b370e710591a854eb25b2bf1bd726b545260c253416365ce2e58a8ea7032ed1113adfd88d2f9dda8a71a2d091a2a4bc11d65ca748ec4119ca59e38ddda1524488a43db78d64efa718b16132fc2da28d3da7ffd62566ef2b4f0b92cde304c2e40fd01671c3c497f2eeb04ce3ab0558da3686728131c9a0499994023376414635d53a014a7798bc6b5434c523d269929f6c08dd80c1de115d57242429945cfb7689c8b7a70167e0c454c11c368c6dc2dc0663ee4349d13052f30454ca0350a9d19951a93163665a1ee242283872cd119d5fccdc5a0259db16fd598534138185c9f821c83855c07485d7ab33a9cae10abc2f0c5ecf3c46f6f90ee2149f4c8a16a0b60e6e336354b3f54ae6dea1e8d33078b0f9a543ae4426e06c465ab828dc620ef590a604e32b5deb39cafa5cc7dd9754bd6292597a455fbc0bc3e02af487cb0e984012c2b58e0a07e348858006c039080a9f5fee35ad3d4ecae8da7ad96deef58356f49605d0aab7bc3be318851990d03c7595f9b3d1370fedd47e80580be449175c47e8989eeb75c39fccdb159245dd25425737d54653421e16891900ad7a773214f8bd21a031155457667a9dc9de421f397b7cf2f072143fd20c9a2bc8ef3bb449011b088d868d826475a96581539f624d2ce8bb351050cce6452695f3abb225428cff6905bc2856ebe288ba93b86c6c5bdafd016765b6566172345f0ce9647beb7eb864b80179594e8e2dd7598b34af6897e79c09b57ab6915cb15b3535339ba708142d28d43e1ab48086974c297f30a9577f5f4231b0435d80b186301fe1bb7de382cfcc89f1e990e40f15bb27ed9d38964120584a15115b621dfcb66bae261af5efdc6db091865f8064affe5360b2011cb74bbbfbcf82bf135f930464dfcf3fa323840c768c31719617cd7c42b43dfa19032acba251871c402a6078dacb5267316b9005238f7bf6f731834ea731e3be98d6f8cf178345df2f9f0b436f4c9a27d5df001f251abfbd881d059cf9f1a10bc87de8c3cb800467581fa551912c57642c3ca093cbdc8c77958260d62d18d8868a1b4c24eb5cdb31abacae295e1ab1f6dc84965e0118e7bfbd10a1fed1b9bbe53fd5e1998bb4644b93258e1b5ad8291be1959cbad804ad555a7683fac475fefae9fd497e8157a049d7c3aefcad09928921aa21541544c4a3c6a31a6b0da4b3d754fdbb6fea9c7a42bbe32f4922cffa0d413adfb86f66dcd6fdded9581c271c8c4c665fdd7d7138a27d5db59cda933d1f1a615a54d98ba115649552b842d8d3919564fad9eef8587a4f78ab7aa6b28c3ea460a410bea193fa5f96554b14d075665cc6615fb69a539ef01c2cfbdda66eaddf4c475de3a4e55062e959ad2a93286e1a00bb8fe9581770cb15d696ef3e3c7c1d0e4dbea3c36e251b62e486683ca62129e4baad5176b5e8776b85d3e1aa63417d978493b4c5716e36b01941c4d5d7928c15e3743207475d5156a18d659ab8ba5207d00c27168ecd65b241d4fa69435457bd8f4660048d33e97b6a17fc7560e672489f778939ab4b161a58ecb83118354f6674874979b7961889ebe414cd3c8d4f332f16dfa69f694079863aba7963902017708c3405cd6e0f96d3d2586389d1ef0b00016b36cb5ccb59a3096a7bb03d04dcba2fbcbf707a6176ecdf4ef687a50deaacf64881ac51cf4c239b6d31cdb169983d7ae022bbf31ff570f939484cecc99dd7c1b99e1442d571b97476913c51d702c5a27760f890af3b2e32f417686fad72d53d761044a647451d1ab1f16ab305dd4d07175c2a121daa4c8a00954fc80a6108c3d0be39054074ac824abb36d007d916068961f34bd14884f93018a195626b8bd25cc42d442000e8c111b5a8e21a61f0660817a907d9ee6f361882c4c282104b3bcd565fcfb54ce4e28e05eea6a6205b09fe3c42b1f7a2b08ff0d307c78957991d3e4ebb59eaa102601b56613a25d82bfc1b5166bca2ae479aad30d4e7ba36414298d038ba4a9ba7725a3541faa65b0021cdc599769743ed6276d222169ff7bb36a8ae260c59b191474ab54a09bb97d52a600e6bd334b6cfcbd191de7e836ababcdb0b93044026c46b429d286696933eeef895a1bb319c5a6e836eadab86a239d8d1d3636b3d1d94659b6999b4786750261d3a4cd7c3697d8ec869b6926049472646da47d7317ce6d363bb8d912cedc763356a36875ca72232de2ccc09cbb23f9401e89a08910a60d0d6e175a84e0a4ea710ed0b9d1d2095e8103b6bcd044cc62d15e883b28a2ad1b567a69abda372e9ebacd89fc43c783ecb6d8305332b8c900ca99fd7b15ee648b58a023bbff1d7a8be6ccfa07336d57a97d5a8d484b204645ee9e90bfd8210de14b7028680330ab1058b886c59e5ed37a0f205ae94c3037e61184df3ad38aad6cd51a7eef86cd9de0ba4e4d5dc70a244d2ca1c1d7d837e4505904f2037e0a8c32e0a8fbc8db9bc01fbfc284670f66f56f56f833d76727b63fcda3ef9dfb3dfaf2bd091f6da7b9fbd983ef9be66f7cccbdcf7e597026fc36ddf38f775fb63fcda3edfa3414d0574485e8b10ae57340b40fa1cbdc230d135871373603d6ef3d79e08cb7d144e56204ac0a562fb41a5dabf83ec6176f7cdb7e56db0b84224a90170275db7a1f4adf8f5cc52c76892ef222b586e2cc6b656f846d57c8ad903cce21ab2a0908e7dadf37e62deaca42925749e7a792fdf7a1cd3dd5c194599c919b39ef8ea8e3f94f6d236118bb711594ae132cd4305655218cfbc2028134127771ceb1690b7b971f82066371269e454643a3725fa4c5d4f5104541b6074ac7511c606c6c1a9f8c81edf212789865493bce959164a29cea9ce02eb1ff131230d11ed15e050d6c14edeb7f835eb6fefccec08676686be7b55f72ff3d001cf470548aadf1673e074622a7f3959fab0560552b26d71a75a81ab7fd4d5d1bc9d96b8e3145d0d2d028fd3518506df4c7da59f3a510718638c4a9ac08920d01ee59283a924244350b233834710c6c7348b0a27ee7d769d87cfb5a4ea2e160ec853905a107872a7d6ee8fc173f15a10dad96edc9fb74c426225f91fa5ea9c8d1c91b1c9a6dc21e331787b6da16f81047a5b3daa1a97e38382cbec5cc7276d6a3e9c14dceacc7a4f528b8dec31d0c97de63ba581969e2d33d218df41a79c17c95711991863447534ca8843254aac327cad89e351e4cd585dc0c8e5f812f7f57c203c2c9843381074dc7eacf8f7d130ea6be209e84b8c097bdeb150f1300cd9e06831312090a9eaf5e086f326fdbbc1997ce5e80220f8cf7defbed11f6eebc2f9e1b2f3d8fa837d51bb3ef3327999a70e6033d7409f4fd191a5a8072ff0e3e24a727f4f63e67561002b787ae40751e01df44c3bde144042ed43ac8d0e981ddf719beb089d0edf57833d09cd3fe940d6380388cb11d1e7a70abe9fef0103bc08ee1ecfc1658a5f984d9c3b6df080895b213dd0be47b2ebc3d3c379c1aee11ce1e7041ee0d8bc25d509def00e03ce225e9700151741c5812261c70817f52f9d0f3f05cef3171ecd20a866d40487d13188de9eacc423910e76f37e08156debd235e2537ee728da39eec8c3f38a460133f7457ad98424b8c38e461c9b5500306f414a5e5468215cf5a2fcc572a462eea569ece3fc0208d2466c674c0bdb866f64ef54dcbf23bb8ee1275709c703605e0a22ffedfb31825cc7ec6cd518621aa0c2636cb0ea3322f03c03f55a895b05c709399ec8b35b19853eadb284db57aa0b8cc1063a803830d0aac13808577cae5002506c205d7083121d342826645a91dd2d54e6048fc7d912c497ea042592fb7e41ed3f04114a3b3308bcfb5d0de7ded44ac786fd885581a0eb1c9589b5038105ccecbd9f31b187333487e2d8341905fc1ff1e8b2ce5332d796a22b4528a001c9e33c43640004cdee1032837be475508592520b190de6b46c53e13029924488285cc1a745bc80c836310f2ed802592792117c540b1ae3608719816999d59ae0c55ea13fc6e0515c3a47d4c245fbab76499e366ef181c31e8ea58a899d19f6ed346770013c97484ffb4cbf0069b613bf1f9078af7078b63bbe9d747c6167dfc7c7b6ba8b9eba3c80887673e1e7c5236ea3e61944d2a5e5b2d6989cdd810ac074387b0a7e91984effd6c9564ba791256ff01c5a8ec9ee75dc55a97c9c3b9191af36ce73c66039c11726c789a78defda2ad8ed75f6b08f6b3b7de49cd7f2f7c823ce15027a34f721523c2b6806a1751bef48b96c0f3519a99c1dfdd262815055f261603915b2392769cc0195672f809a3d7269ab7ab7048011556aa6b2da5120725ac90f407ec89b716deeb8685dcadb4fb13bedbfad0a4036509bf42fbbe9a298fb5d0126aa15943d891450305b1b9dfcf8f6ccec1560c8cdf520a5227bf3bc0cc8dbb1207e851e32bbde46d0e7cf138524f589493229cb2a31e2969bb281d80f7b79e27585200f4de33ceeb43ba1a60a24d5974fa7d9df5186850d509364de24d3269b5910444a8d0c86f4b844cf9143c9c6bc228a3c62fd864cffcb145b23ae3d21d7a30fe83130021b7a0cf62010bc3f5558b0720847ef91158766dc329da63a882c5e4767249cc4735b452af44a6263a28f66fabc813e74709f0be1aeeb5ad04ecf329fa65ae2ba75b6c682483e390addb6040501ee8f6453d06c0e7651c11321ac89db8964b0783431deec718026f91994ff067c12a12a712893dc9e1182262a94d7ec461bf472cac1f4132ea31a5cce04afcb0e0e98228d49ba6dc50d17854f09376ca0d201397179874e4ac76ab8dc40bb6536cbac72f08fdcfe52d716215e84ba1fcdd646e9c24536d5930f37e366f23769f8109bfb141323269608bcc1ada038776fb57a2e7791d64903ddfbaf2f91044c2874dc8250575ebb969ad1d78a2c45b1925464fe8ab163f149acd98583d22c199210b9f57297d9bdcd084048e0695534b9277692d314dc23b1d14acac7c8e002a7d506c994bf04cfce23c4a47a2fdb58adf15c2b655ffbb1c2e29f9a0b607635082c5346b86335314440eca9e73bb88a64707836d045a97be7c2ea59d36b5e219a0eed9c3f828036d4fcf39685f1cc9a68aff5a11ef6517d19056b2d6f3e1f24af8f09e5080dc9994393824e87ec993d2a692330c342b4353ccd8358de05a8b592b8ff92bc5c294431fe5b08f8366601d40a6edb594124f58b8bf6ca8fd83afc84a3c4621c8e7aa620afde143ccfdb21a40d21d7a95495a544eafba27c88a2ebfa961d0dfc4d3027b01850083b83c5153dbe893a33ad1d41cc495e40c744d5b5279aa3e000c30cadce9ccae16ce7b5edcf49c411713cd86b99c225254f4c70ac66bc23b3e6f257a157d9ec21ac73ba4dccff63b2b43a4b98602f22183746651ba977115954d422b9ce6e6402b603f486b22f21cc84e71d6ffb58264f7f0e0d49c92e129b655313cb5ad20bcc9c6fd4c5f08b5b436205555ea2203d9edff42522f0efac8571215321527b1307ba0b4a01d963548040bae9a3ebc092d89b73cc08a0874b7baf5b4d4e654a3d8cba81839ecc1083038241f01796decac2412c570229d8f17b2c2b00d4a36f1000eb073e8d5c244cae1eb040bb061edd3990926d871a0711187589d29c51a8e157bb7ba51e9a9a0a959dd6bf25eac98834e2aaa7075bf72996815978f71a70d1eb7a5fbda9b06fd480980866946978c46fdadf33cf645b2f70cc8ee6313a6fb81c0e9799a9ee3792b4198718632fe0046726c7be89687affbc9b1eda59a5ebeee33c7969758ead98ee03e4a4d4ece75657e938ccd90fd8531d005a7cdebc67c720f2f396d5e57f3d17b7ac969f13a9aefdfd30b4e8bd7d17c7dcf5e72dabccee5d37b3dc839e01d97f43ff01d4e80378faa3daad7905d2cebd3d4238a1b7a3742d4cfd6152b5b3652ea0b5ef96c8d44faa87a8f5e5b8b6e1ba28e5e436f149531809c2e2367569e5f6aa74a46096377402d1fb00134b416705323d6f93454a11eda891c3faad0f53728a5d1eb394c09d16a1cbda89dee8d1ac65c1b9aad3ccf31626df442e7014c04ca98eb4f57aa30ae46287af4765170818d7e462fe6cf11687268f4f2232a9663af5715c2965befcbbfa71d692730289a7b87ca73a3b515514600e7ed62637315175f3c4014160f7364d49f81f76d8b250a7496d3527c945af3c7f42b03072dad8d6f1396acb8ff60da5224eae76c1947ced1a36478cc95bddb7fb0bcc7c1036432850bd8aa04bd8a6c53f134f499224025d4c732d10c0fa81302f49f025eb0c4f70b3970b0160a073ccff33ccff33ccff33ccff3bc0fbdb1fccd22d62cedbd48bb827e7b9807db467f999999999337ce05c9da40c95af4244772acce350c6a0b150cdd57caa979c5f5502534e6e9765f3482aceea39e7b3c961841d2df7cabebe50a5e2c82d8b1294aeb5bbd4fb318bc5004b1eb87dfe3a94b3e89321241defcfea164b6f1c1aa8708e2fb78fbf34bb8c74533787108c2a6ece31f7e6de69c694390fd3f8c9968f2452148962e5d7cd9eb7b7a268082178420e4670f6b2ed78b4110a6366732ce65ed8f7e21089265ca3016b2e28a596ed4702c4e0772e078bbb20e04395cd6b6dbe669198be90520c85f7ef2d1a3c7e0118e7cf107d27877ed77d009bf4ba61fc8fde9efe2a4886ba6601b5ef4819c52d8f4de715b0101ac105c8e1a33b2d081f5820fe4e197f8ef6c4a96079b177b20f565cd3de53af7fad103a13659128fe5e9aeda3c90b2ff73e6f17c361fe75fe081187c7896dbcf6394dd5edc81983d648e96c67b6107f284875952ff96f8cc0b5ed4815479d4b3119fc9d3ae17742055928d9b4a7a1a5b364e088e8d195b38162d81177320868cd3dcf374a003386cc8815896a242681eccfda0fe8015075ec4813cb8187c1c9ac5871f331d7020a5931fc694e9e8c364be811c4fcfd26492a93cb633f0c20dc4fb78e71d2c47391f6d2047ed5968aa6dd7bc94b1811fe69ca2ef176bc836eb26d336c3f2420de43ce831f7b8571d2e9305161018810274e870185554512fd240d0bdeff1020de4918f3f57fa0eeda134586720ab6f4626efd218b23303315b6f282d8fd9e2981b35666c95817c71e2326ce69fb88f0ca43c91bef41d4fe777a0860e9bc08b31106c73eee608b7d1d469311052dfa4871e378f56db301062e3db6b2a87b564d1d89aa103cfbc0003e9fe3b3c7cfc71fb7d686c7d81147dd97c50e1a256bcf002b12dacccb833b0ba401acf838a1b6592161d1a5b5c2059a6dc39e3e7d3b31a3976e016c803eb73dd3cf83cb830cab061a38604aaa8e2851602f0220bdc5797d8895dd765658d8e6d8a31f630477760f197801758205e4afd162d58e81588d3eae3a06ba93f554e8ec7b602c13bdd0f344663a57415489b27b6ae46a4b1c516784105521ebfcaedf9fea40fa5b15553209d8f2dc612adce7051871448e9fdc39cf2836aabfc468198c25d66374df31750206c6bfeb8cb72fd04f2e06437e64b591a6b305e3881d0c3c80bba737e6f311a5ba8dbe798744326105318fde4c334696cb1d58c2d708860c712f48186549d860e5602d1b3ad868f43e7035ecaf9401288e5e31e850e3eecc19a8604528b77fdc8824f638b8ac6be78710472ee185231bec56713d308e4610e2e8d2dfe1d5accd871a30884f26c39437e2f2fae1b4420ded647c59dba947b1a3376dca891238b2e3a6a608143206679fb686a663d9dc377e8d8bae28510c8e351567accdec31e58a62308a4eee10ff3d87766f27d1a5b3b70e0000271ccc7a3dfe09fb2477681173f2069e768f1ef17f798e203f2a0544ddb3d46b3e7ecd8e2dce008bce801717ad83db25befc80b1e1055c7b22dffc7af31dd411e3b56ce66aec00b1d94f2d352e0450e48b963144bed9a87df378dad1c7e6c9474c00b1c10427fbbf43bdba103078d193772e0a831230b1d2f6e40caa39b1f67eb6cbf98870d4839f6984ccfb5e6376b400cefa16f4c9a8cc5d80b1a10ae6ac63e5c9cff790881173320fcb87d30ffd2a3d8835ec8e0ba68933b4b8bf4f59431dea38f7ea32f6240f091c6bab0c091a3014e78010392fdc87ca015a51aff581068400370ecb801013ec57fc6c1a2c68e1b5ae408c28b1790452fe6f94d9ab33bc705d97d746dc5acaaba466c1eb7d799e5f66ef0d102e2c6be1f966a8c41ebf2820504efef2c9d6ece64aa172b205ae4fa65c4788e3ee8850a2813375b91682db1d3aa36f5cff6cfec6b2a0cd79c3964d8be860a42b5c6bc2cf34f51c9b76497986a6a0cfb298fe3e5d39c365390f3c0628890c94b6ab9280531de89a6bcf843062e48412c13118db9e5be51d92888da1f1aad800b51105c2f58694f950fa30a0529e74fe96555d9d3bc800b509052f9ccc9864ea93b85c616b316ece213840b971eae7b68e8e5e109426b4aeef13efec19b8f4e903acddef6e0c772177338617886d46969d96af6acc6b736418e2173d6e0e96357e04213843a8b1e79ccc448889920f47854638294ec2b66fa70f1f08197206edcd35c377d5576e1d4a18309e0c212c494a92af6766cc8a88a2a66f80c4e1d3a04d0002b2a411eaca59ffdcca10431761ea54b1fd749903d74897679dcca3d4c1244eb36fff5bbf0cb722430af6cd112c9c852ed109d6a4f3985cafe40827836de9f9ffe2f7c780d1c16502c5c3c82546a31a654d33cfacc43042e1c41caa3b8ad569a3d7b4553e0a211e4cd3862199f516902178c208baf6944e58ab1f2f8459062d7a2520eeda97f14459075da63cfeba5a4652782ce2599acc7631161cc080b9b7a181e82fc035db9176003178620a7f2ce9643962e0a414e5d4f79ecfd1282ecc31cbdb2c6c53bcb41907bf812d6e1ecdaf3b855a37fcec3e4c3391084decfeca69e0604318fa5329e87f80f042f9773af1ee40772ffb5470f838d03c7075cf48194827ad4885d3c0b177c200f35a7b2b2181e672c5b9c07545185d9e2d070b10762fc5ceae1a7b59a3fac079248a578553ebc8a2a4e0e73f240bef3d1f7069d9e8f79177820b47cb44fb6a98b3b902ff4a37df49843da8300177620cd655dfd8f2905cdde0e1c36645451850b5cd4819cb66134e4c696d88d0ec453cb18f629f479f0612ee6e006b909b7cd41c4800b396452f22632d2911da9d6d9d33b177120f765f5804353296a9be221e736ad1efb46b63c5c6f20f4b8c2cf6694f361c88ae0c20dc4cb1627ef25bba6a605828b36907c3cab610f5cb08174712a64f8564c39ff6b20be54daf794e3758aab06c2a7aa90d16f4d4d22a781946ab5715a616326b840034935f9aac6384d97f73310b5cf47e1b0611c878d1178163b823f87cd404e2d1f6a3c3a3f2d5306d247e91c3d484806f2c847fb921bc363208f72e7613ebf1e0fed478a81b0417f1c63a50a9d7b6c18c8b99af436fbd3f8c80703e93de55196a6b6d0ca17c869cc3f6c5f7fa063b9f002f35653b59da1229699faf72395f2e802492ba3cbfb3458ded02838b2202d70c105525696be30ff5d6c81e0799ca12edeaf2ddaab05626b1ec88d7b6d34709105820f2e7567fec83cea7f01e7e10ac8810b2c9022cd24338f7ce6a2efe20a84b38dfb61d3ef312e2b10ea3d561e8ff2783765ad0ac40f4df971550ab9f107150832f9694bf2534a3e0552d0cbd3d81c1d67ad14c8efa76939c618035c448158b95ed3741e050ae470df39f3603521b87802b922bd7c76ed2eddebc209a49b4d974eed7e828b26903c54ce39edd1376ab80d1823c8e1e6068e726444c10513c8b93a9b8fe2edd6f635821c8e458d4e828b2590dc639a6478cce33fd50d5c28819c1afa87b95575910442e56c793c0e1963e7e58104d249c5fbb0bd1f81b4af612ae6d11f46d98c40caf22c997197a2c44711c8b7fe791cd6651744206ba5d7e0e3417446bd0c8194dfc3f5b87c09811c73253fced4c6cac94510c8de593fae8d69e6ef5d0081e867b753e53d96d3dc0ff2aef0ba99adeaae10b56831f577d43e20591e3f1f498f56d2b32e7ad044779695a7d56689986d887d4ac61f74ca5df080ac41f62ef36d1e0fe7471659f89905c1c50e88b9f5fa43980fcbfd9d3182c78c11d8c8024f032e7440f2f4d13b73f8b20dfb18d06c756c3cb4c0611a6b022e72408c1e6f26ed1e6a8f3647632b0b2cca51a08a2ab2c0a258514515361c07e4c98c9e6feaceeb2b808b1b907de039c3e42635cc4d632b8b1a3976e8b0a13b6ed4a840076a286077dca8a145076a3cf6002e6c4098c8aaf6afeba01af7105cd480dc553ae631e6183d4a260d173420e65a4c7756da95a37ccc80947fb4f53fdaf758a979b89001597e247f96ed621103f2c8fb87f1935a01f4810b1810c75fdf629c8d298fe2f403172f20851ff576ff207501f947f95536e2b4afba16906a4dc3f64573c1027254db53938e1aaf7eac801c7ee5cbda7b537fb00b15102fff28984c6ca920a9ffb6bf8d2b0154904d7e3c216dfa831fa64e51cb6d684d596549c7766fd846f43005a1cac763e9cb152b76c44390402948793ff4094ba71b99d2d812018e2c24400aa2ee7be73cfcb5951e2b300a52d6eec62051a1b1b5c6a2208f7b5445154290402888b9fe545724ce41860a0173b6a8d100b64202a02058fee06ee3afe7a0df7d82f0d74983795ff8981a097882189235f97da9f3309b9d208fe3e54a15733a49b89c2025552fab2099e55291c02688921e62aa4566a253aa93802688a6b147ea5379202e6a2688577933b5ebed277c4b4c907e6aea5c5e6ef3b297b00e351e58e028564a0442691e96f557da14f78c60470d32184320ba5476ca194463cb683084405839cfc9e3887fa5288c20903f4ff7f833ff40200fd7caaf62fe07a4143756ccd6479196e2837cc3fd30a40f46183d20f7286dbedeccf3801cc39975cc59b397ea0e48fdf9a153c685cee7ae004307a4dcaceda37c2e9eec470e082d2bdbf39a52f8bf7140ee4cb56e0f328c1b10543f0fa7c7e965e5291836208ce7dedc8eb5f0f9ae01a9334ac5d2f2a274480352fa705b65fb0c48f17353e6f42a03306440cef9bc7a63bed03dce8901d9f3a6f3c8bf4731e6c13020e58fc3c7e3d0616e1bc27841d1aa66259535532eefe93dcadee563b7340c1790ac47e936c2b2a6bc057fd6fd2c289886b1e83fcc0a483edcf1c10f74db323054401cd7bd8b414df57c9c2ce6d04de2312a485ad1b355365bba4f4178ddf3d8694d41bcca6a2988f2da29ea8ea42005f7cd951dc2c28aa3200ff273688db7ffcd8982143a5c85b5f0f1c55c2848ad7779ec1f7b509007ff9b53666ed6b8fe13c4dcbc19cfacf704a9e5a3aeb6bcaafa4e9063f64b113d1e8c670d2748b17ff071276d3dae6c82e0223e8e8add5ba26b82acb69b926682b0f1e647dbe35c7e3526c8e3e499b91b279dbc04315575fb47d23e634b103a6594ef6ad14e5682f8bf4942b3596e8f12a4d4f519a7512fd94e82e8ee1d965259415449107dd4a5219df3862512a418e2cfda77c36a483c8ef478ad559e479063aa79e9d11c419c12f5143ee9db5b8d20769ed4609bba3d8c11c4df507539329e2e3a8b20a6eed8921e8867e72882d43fb2177c43fb4c04e12da694bec7b9f3a0072288d9bf624c313f0429eee5fd8fb28620650a7d132d72b6d1429052c3fbeaad84205f770e6a69defde32088a649f366854610c4ee6871a5a2c7fa9f0904f1fdc3378f7776d3338020e6fa7894d2e3ff40f07079d0439759bb1c3f903b050b57deeac1377d20e7819c755af48f93860f64774f1f665cf640b63cb21abf7d3deaa107527d6558edd9a6aff340b094953125998a1ae3819c63877e8db550e00e8ed7d7eba56a8747f1f260f4dc2c75c0872a1663b6aed081783b7df9c1c377eecc81a0e77ab59fe31b3b7220e5d1acdaf9f083ac7120edfd9e9e0907a28aa5aa98699d836f208bb5af9f27d928193790423e446eaeb4817017fc3ef46003613dab3d8aa7dfdd6b208f274ac407b71ac89d3a8ba4a84ea62f0d64eb610fbd7b98e37da1819432675ed2628cb51e67206ccc70e1abc79a633dcc40da9c92ffdff72803e96d5be4e577c7260339a63ec6ca34cd78c640fa57eb61ef450ca473fd6c5e973090357dfaa8723ff061050c248dd6a3f44ea173fef802f9877bf5a30e7a3f8e7b81e023b9e0030b35de7517087be52f7d3e16d1b9401efa78e8b1d4c2ef5b20d6e68e1f44a5edc65a2085d8d7adbcca038db340fcccfaf723170be4b9dc9b51c9727305d286688bd6512b9047e153ae46af02b9ea3e5534df0d1fe654208ff3e86f3ea77c0ae41fc7be39fb3ccc17722990f2dfa65bda6fb5c9a340f2ebd03b2266559143813c08f3aa97b71c32ff04a269f4a8adfc03738f13c8c3e8d41dba6902492bc5fdf1783cec916a9840d8cf35fa8353f7bd2c8114b299dc4ee6422a4a205d85f830db7ff7872781d4ef51ade28e04724bc69c97a292962390a793a875c708a48fab8a400c3965713311c8973ceb84541ee59187404cbe1b5f535208ccfd47e5a06710881d539a4cd9f9664e2090fc7f98ab876251dcfb0131e78b952653fce1a77c4048f951e5a8e9012973b6b7bd2c5f15350fc81a956d31fe0e4abd4dd5251e1d10fff2407aea1c90e237f77dccd1c7c9070ec81d2b742a7cdd47b901e952ea2daf3c181feb3620f7555dbc3bcb9fae01e135a654ce360d4895dba3fbecce80b4799c3bb60fd347561990f43e45efc480f0659aae25530006848c3fdbf0812f200f2d252b5dc8bcf85c40b67af952c94dd16e01c1d234fb6d8a1a336301c1ddd7c3dcefc69c159034e7d8de797ad942011590fac73dce988395b4950ae2f679b6b3885141e8f83ecc7339a720a67423729b82b4f1539ccbb4f953530af249d467eccffb91a46873dc655de9310a92f95c4adbc3454194ff787fb7878298e47397b8a53f1f0b0af2bb7b671e78d4abf11344954d2e99e17a8214126749f22bec7fdb09e2e6643bb6163b83b69c2066fdf84716b2dd04d9b634a5ba7d8d5bab09d269b6efcdab0f93b59920c65ea5b6668f87175a4c902dcf85d81c569dff4b90342d5be476c8f4794b90c6b7837ff0902a9d4a90ece2c476faa004b9538e8f6e7d9041f24990265a5abf435de7b1922097a60ae66139a71fab9120fec887ae966f7f2baa902059daf0f0317d04e1576a738f25bf7a903a823ce521dfb3d91a93368298f9e7a2d5725afb19412e8d5145bd2a6e8fb308b2648a41f687510459930f33e7fd9f6a8920bdc7980e9123829c21e43cf7e843902ceb77dc0bd1830a1b82f4b61a5d935c0892df0f37ff72be7c4210d22ff478b8ef204841cb66cdb6c35d2b08426d1e180872aac748a5dbf8090141e834e93132fdded91f4855c177bb528aa1991f4857196f534adc7efa401e7d8a123dec74ffc1074255080fad77ee819407fb6143a7ece15ba9876d3ef34eb6ca3c905c53cc4ad7e51af37820c7fc72cda97b323b7720ac5896f7f1610742f7f033cac7b3123dea40fc8cead9f34e0752f0f8b131ff38fec6e740f461be1f492b07d27eceedcb3c9c303d0e24db3c4a292ba6a01f3890f3a7a45be397f1f51b08579df6c3b698ce47ba817cf1623caed60672f4cc9ba62a64033178cc831f134de283700da45039e506efd540cceff1873f8cb0d44e1aee9c7fa0811445e3a5cecca2f13310f42f63c7c26c6e3310f378fc793cd4efcac0568efbf6579381a4e953748f22c35f1e03f1a7f348cd52df922a06f248e60f3425d662320ce4d018638fc36b23423090326baa62fe601d635f20c6ffd0c53efaa8cef2027950b59bb345f8c6e9ba40900a12b9ef617a3b5c20548c6f114f9e47b30562d5ef4af4285a20a5bc7c1608312b21fd55afd9030bc4a5e8710552ae39e9f0fc61eeb815083ebaaabc6e3fb48c57815ce13e26938fe976a702a9c7527b72d59bf33b0562fce99fcfa81408329fdfc3f42fc6350a84a87861b62b7ef4130a44ad187b02f1cd3325d1ca2932e8049269a55df8a0c73f621388156702d9e2e6dc1aac3de84b20b5c7cce39eade0c15302614c4337eb2410b5b3eaf7483224902a4867dff84720ddeb66cc4ad7501e231063949ececaff63db1481ac9fb42e53f4b89b07114859bd7954793c8640fc61ca703f9a08f9f11002f172cbbe473986cc2308c4caabab503a10085aebae3969ee71d27f40caf0410f57537692dc0704fb916a6cdc0382c6e9717e1f8f2fa69807c4903ecea39b7f8d3e760744cb571e43f6c5ceb77440fedcb5d43ef1756fe58094d2c7ef7ed0251b2a1c90da2e5750e906a44d96d5925d485e6f03529c7a8a3b1f2dc7d4809cbe53e9cb4f03d20597cb7ecf807c5ff6d3e59e33333220fc304b79fbb8ba8e01396965d5e89185980506c41fe9d866fd1e48f902b2766acb03ab5fc9dc05a490ec94b356dde6dd02429ce7e6b0ccf29f05041f65141fa9ab6f8e5740a82c9e59de09a8806c63e6a39e2e1f263715841f255b1f8af728cc8a0af2e85389df6499c57a0a625ef3e84e36ee999a829cb633af7827b19096821463a488d6490ae2ece9be668a317d14a44c1e2b4a7e35ce270af2f53055ec27f3e8eca1f64b7d855f040a72361fefc719f7b185f1c5274852eec34bf53944e75b83179e20ef68cc8ce9033b41981e8bd48e7b5e7082143e97c47de83219e7179b2887dcd015ed2bc60db042137e54fdd496a2e78b4cd40b4c10e7b56ea6e27123266ff93373ecf1787109427dcaa7cc6cee6fedd60b4b9047179be44c53b86df2452508d33f97ab9339361ebe83179420fd28797812e4f1b8d7dfe353baca2989b32a426a6364666ec3dc7bdc5aaac36591c0eee33e66ccbe4d5e6624734fee3284179020cb074d29371f8f207a9c6fec183dae97e9085ea37b56f3b1a588889108040d17597ae1431d0259f5a3c4928a9aa73c84409430db1e75abf7b043d420104385bbb0be1e3e27191508a4f439550fab872df71aea0f48f36a1f11e5d1ea39541f90b2fdf04367364faa41ed01e97d7c6b7b28eee001f96f347dc384ba0362ccd891fee9805cb69be1375cb0de77e0c8814ab0220764fdc16d9ee9718a9a611a5b5ae080f05ef1cc4143c70d083bf131e711d3c9060d1d3620e5cf47ff7e6c8b1a905289d6e4fd6d5acfd1d8ca8163865d0d24584103e24e6b25dfcf197d7cf119907fe8a6ffe3ad0e977d1910b52533e5b1fec8fcc3589c1c3120ce8fc7991b77233dbc686c69010332e7d24a086a98197635ac7801b162ae5a64f4b9fcb70b487f21a75152a22afb16106387ca2cf5300b0837f23dcabfdbd73ffe46c902471633ec6a58b102424f8568d0fd915a4ca1b145821d6586dd25c10a1510cb73d6d01c36d80f561b65865d2a88697c18a47b725410d655c3c96492ce8d4e4194e9389d4baa6d9b8270f71adeaa21fa07652988f661eee1ad91823cea5d97cf16fc51103ca5435ae6c14f794441cebad187394d0f7cf45090d2c36bf4a75bfc70760014a4e8b63c58ebfcb1f10992ba7778cb6fef09d26bdc5cd8ce3dbff23b41cee9a25e397e3841ca8e3ddac1e2e8d784ba09b27abee8b43ae9f49f26c8e1b76e36fd7854f1c299200f7f903f1e55e7696c69810962aef2fe1fdaa89720c7b5f9b1ff7898ae2f6b09e2051ffdbc94cbaa7ad44a103a4a56b592b5e5c18e4a09f2de85c6ec96f2c19320f4ec76ce2b4ff959469504212b4487cca1c35de50e4482dc9b2e6dc798ffd3b91d80042954cad55e59c9bef238361e415ae96d5b8f39f546fdd87004b1c7e16fc5e73659851d680439457cbc1d6225346e3ac00862f6348bcff251ab5a2c82243eb79a7cff4766db0e4534213fea91f193c6d6b99108728fc756b443a794b7d3d84204f9bb77a73dd9749404203833ec6a1c829cf1ffe350e6b1727d438b3704c14b7b287e2eeb63ae8e1a33fee42804212d340f2eff478b1b33fee42004f9b2761ebd64c8ece50f826896492acce5d9fce80b8298f179d0923e0c6a20487776d9a3253c7fd60e1004b74c3a2b1176e00f04bfb31ec57468a5cdfd40f8b4337f99abd8edfa405acb5cc952cadeb4ce0752a778799ce367a7e4e3ec213d1bed1e584a696ca91e48a9367ace15dbc30f298d2dce03c15e3e5c10956d9bf6f1405a89eef1a83ec5182dfb3b907d90d9bed38f47793f07d50e44ff1ff6b0534a9f7dd0dbd5a803c937e6d955b5a0034976e72f9cd6767320c665bb9c93520ee40a1dbae288e696fe11075268adf48f473f363d0b8d2d2de04036cdfb797db73710b3475979709bc28f7f34b6b4700379f5aec7444f237dac561b88361953ab746a6a5ab081d8c31f3583d740b4948bf0cbddc3143faf0652c658981fd525e9d340f218a23a558ee7619250d14034eb1e789ebc686a393476865d8d33103c3e0f7e28efa6b1960e339073a51897f14a65428c3210a57d70d1c3183f1e56ce0e321073a7689bb35af0cc1a1d63205bcca136774a7d315a311053ba3cccf9573df5614e1623d8c14e88110672cc7cfa71dab498af0103b1aa2ba3ca94c37c81ac978729aa079552dcce8c5c420c2f902b8d95e78169c61e7d686c7581a06af2e31ef7603636ab6685185c20b80f56c63d69ecfc285b20868bcb1b753f218616c8e3faead2e328cf1e5920b964bf778c9e7a2d87163b4e0e43420c2c103c9e79fb864a887105929955b8985bcff1b002597ef0e9f32876686ce5785481ace2af49ddf3471f73e350819c76511a73741fd50f3b392e0931a640bc1ffdc033a3f630e5181a3ba44058a98fca1fba871e8db2c34b14c8e3bef9e1a27a48479063471321061408273d1e95995cd3916d9c279037858ab18717cfcbafc14388e10462f68cff94471b1c3608004688d104f28a7d5cad8d174dd7a38e108309a4aaf09b2ed6e798d3e83b6ae8a81182ad2c28a023c7995145155554d184184b20c486f994f3d334b6b4dcd0a20155e586166f31944076fd0bddbf9ca2344fb800182e04d0002b04c0871849e03da3233ddc2cc6c6ca3a742f7bb0151e43a71d030956dbde450bbfc63802c13ab3be77d2603dee11c30804cff2ce4c21d71a218d1b6e03c6313826c0c7e0b88117a308e4b3e0b1c783174b892e061110cd72ab945a95f1e86c0864cbdc21a611d9882104526aa864d3d2ff83eff13568e8681d59e09841318290b5685bab98966de74adb95c70002795c513bfe38ed183f209484a79c4f1b6ea782183e20f43886eaacbbf9f159dc88d1036258facf3f48f9c4e001297b8c25a3f79936e5a1c36d507920c60ec851295526d5f7fdf3d125860ec871963ae7d5ca831e69686c81e058391600001562e4805ca5b9c7e6dd1eee09810e1c9087f1c7316f473862dc80e0e3ae9cf36df9da7b9723860d8829061ff444c66cd56d8e19b523460d483fd49c99b6cb19dcc331812aaaa88a4103e2874f62f16aab62258dad2d703c667ca0b88d47eb043430630031664078cd238d527567e8a8d11743060fdf7c3ccc94d5628b1103bde6bc25bd32432a5a3b6dcea9ba62c080a4a3ab55525bae9f478c179025fa624c0fdd3d06b306315c40f08a9febf2f37820f723460b8c1d2e49a6ec3d9a190331589075f7a694f4d15630c60aba142b0d2f759b62a880746e663f8a58af94b7070374a482d8e3b07831f7072a9a4c3be97431bbaef8b8c8cca9e2c71c44a7720a724e5ee39752baa5784d4112d198ee9e9349fa08a314a44edd8e14648bdbca4e1f390a82a68fe4f328d3304441fa1f6d180a529acafd1ceb4051cd67aa856e58c98df37f82d47960b1f2d0bf2bb805303c410a95ebbea870163a6600c00a303a41de6872c12c2567d80260708228b29f4e43563641cc983d7b5d3255f7a909724a1dfba2a7df5f8bc904b6d56a339559675a6ddd5ac10441dcd2be44e529c4f95bf0acb104d6e6e596a6fdc3ccea8f4bf94a94079ba632a2cb433028d145a8dc46c985bcbc5d3026419acdc31ee5c94e69312b09c2e90597c696568a004624cc3fdcd0d9d5cc29c08004416462d7df37a3758f2ac07804a143345ddeac91854b01862388f3fb29f54d55f6cb3782b03d1e071941aaf4b6f5b1c7b946dc4510ad424ae5c91586228862d923377612411ec65c1f5adc983f6d07118495ca1f0f63901991f610e68b858599d31004bfb8ed29d6ab5daa0a41b2f71f5799a567c0200439eec3da7c5af4dad00c600c8294f53eb28a2a5e00431044bd58215fe1d30a84b11afb31f7bb32fadc38585800062008659ff19f57a36fa5fc81e883bfc83a09fd40b20b97f7e55ff4d6ea03e12627d7a3fba0e32d7c20f68f773c895b9968ce1ec831ce69ee8177f440fe71e56c3af13fd84ec903d97d3c968b217d74a17ee0811c36c5d50765de72e93b10ef87c136478fed40ca513d8bab57f154ad03b9e2feb25ef80c3d1b1d4899ba5c35edc5a22b7320a486bdf06371e5402e8b293de69d712088c677dc1ffc8003f9d3a69cf77bbf81f6166d3991ebb6b834cd948f10dff83977037143e945c47eca95622980d106d24afe7fb04d11cb7936102d43e930d6409e6ffb6198f96a2077cc637f6d0d6a79cb3490d2cab603030d04b96bc9ff3c691f9530ce40ec3cd150a9c55dd3ef000c33dc2e2fed5e6135ab526b251162f5172bd93085510662f0168b397e31c5709a1d3a6664a183c0200331050fa9f941a56f77186320fdfe78fca3435ef8702a83210652aa675d1ff930f9307e8481e8517f7023e9c30003c9b2c6690b9f551ac0f802b1236f7e643f16478ea3812b607881e0797ddc692a93f66b72ec9061851630ba40ec0ee61e7ef82a1b25185ce05b6543aeddfa567da417b70ac0d802f97a64b197697e7ddce6205554e1390e0c2d10aa73c877f5f7183df2c6f9008e2b8e0430b240ba710d753dd5492c7402185820a74baf96acdb93ddaf406897f19186940ec30a4493cb23b3e868ed9a8325805105525ee51f689cb81ff68902185498023953bdb7fc732dce72ecc8a26148816049d4addd07f6f9bbc60dc0880279e03ee2431f0f28b839fced65981e4f28256554a43d355cea56f378906a220c2718b4a2f98f5c930a04184d209d5e5fffc0f330ac33603081a416efd38fe5b66d74c05802f94767f13ab8de896a0516670704aaa8a29540fc894d36a1b1b9077725819096ac879e9fcc731ab100030944f3ce58b3eef1b9657f01c6118879da62eafa0d11e0b8f1811b153002c1c24796da3a945dce6701461188ae1fb33a774e8ffa37025b1cfe2ba840cec1ddbe7cb0e3edea8d1a7cc514082beeb1c53ceb9776d80057488164bf21ce6ababa2d8710b8220ac4649dc3b257a6cc520c0a04a9e9945d3fb168f3ae7802417664248349955a2ced8a2b9c40f4d1e7b18faf6ff6b4a1853b0e1bbd80ab43a378c9095cd10482fc956bdc914a31eec518573021af5802d952f2ffd23c8a3e0cbf120865c92f5ef7baa5529240ceaa5962e5712aff0309a4778f3fcea93f0221cce23a7d78d9b1071b8118165af58731780cf91681d0a1358525bdfc9a2b1148a9753a6768ce94c7da154320a46b1eed85f78540d4fb1875f335a6953e089fef66c8b10081ac99c2d8c8c63cb6bf7f404ae11ab3edff285f5a1f10e3c25cf733ed0139fc54680acd95d7421e90562eab5e34f5683cb703627031b18a771e3ef07440f441f75d882c07a45cb1d36e4564c43820a6e5d26cd9d91537208f2e46f447379703aeb081611b77f1a19df15eae19db24376dfc60bb085c5103e2c59c7207f5e0153420fc38d773f6281bcdf10c08ff25fd5de99401217f3c28159f399d0f5e1103f2c7758c1ee64d3d735d0103f2e0df344e799e7d1e9f37ae78012ed5e73ebcdbb2c0c23e70850b4839622feace23827383b73270450b08763e4eb9ae63c470050bf48df7dda1b4a7edc1152b20c755a8f5c7596f56b70e57a8809c3e141f6cf841c7f52815c4bcf7d9037155fff14a0719a820f7f674a79ca4ac837a0a72ee4d99a65c5310c37fd039532905617da4613fbdd6874ae51c6490823cb69d96642a6f771a0559ed27e63597a220cf8fc236e865a120d68ff3f8c75579509067531efbd8e3860e1f8f4f90efff82f770b366f9da13c4f01b73cca30f3b41dc3c393941ce7934591f237fa3379b50ad4307e5204313e4d167aeebf8f1b374c904b95a62d67e1061823c7ab1ef680f12135b1c645c42bf8a4a5e59526d371cc8b0c4e67bbb5f6d3f4ec971da7e20a312841f754a890c31cf792025886df92e7f593e09b27c98da70ea1e4f6f49105735e7fceadd96a3c7e020231286a91f58dfff288dc63490010972104ddf9ffaed1fdb1b643ca2d5cf0d4bdbd60c643882b41a2b57c7bd37df6fc45639a76df05139bce8a861dc208311a4a8997f6ce17c2c82942cfd38f838df958fc7a3db204311d9de67f168cb1aaa1bc848047173d7e8f45e7ef09fd9200311e44dbdfbf431a50a1f7c088286c6451f554e88680882c56c2722972966632148bddde3a1a74e08c28d76caf4953208e254fa81485d8bf7701504f1ee534d45ef8d5f331004b3b01faa8c8ffd471d2008ff3976e1bf3f10e3c45a540cea23d1c30fe4eb8d3d4a76296b7a5c1f48a672e3a5394ec533f940f4f187961ed67cd64bfe1e4811ef19bc3fe75fe9f540facc9d6b2d9e3ecc03b1e279fc6e9bcbb71e1d7820250bab3affe37187a6b507deb103a937c7af1e9b8fc254e63bdcd481541bead95e957da9a443c9e285ca58132a6a6b31878795362307726cdcc830adc58154f17dfc69d6b963291cee74513d56c24752cd18410ebf51e36103196f20261395d0cb9e4d67bb811895b176e907fbe361d80662b0d41c2fe579a0eb292c74f805d840fcdca6a59e5573cadf6290b106524af6d96fa9a981a41fdccc32753757260db4766d5bbad1b0688e8c6531e6944723649cc11c43fbc6f09e226498a11f3fbf98d6ba73b86b20a30ce4f6a10f7e301732e41d7d18ab39cdbb061963307b324b75a81a6488811cc3a896a5d66120d8c63cb21e7d861fe6748081649fc799f3fffc02a1aed5c424ca3ceee205a2786789daf46e6f17c883f5d18e69a8ab858dc61617c8d63df0f1cc0f274f369906195b20a8b94a5fb6984d63ad059226f70b6eadfde3414c63b340121fe67ae9dfbc544663b1e08a8ff3624e63ab03391c8b83c5154841e7da6b73fa85bf5881ec5917839d0fe762f254816031e673f6999af61ca2410615085ed7b665979b0231a618e9de69bc33c89002b9e2e332f7b06266901185bcb2bb85ccc4f78002b95ca387b14e1be7e136ca03329e40aa245626bdf9e3510f7602d1fe3fe5df3cb86434816439fafea3fff178e681430613889aeec71e936dede674059241c6121e75dc5a05329470c8570b162c6dca468e1d65461638b2e014c848c223938e3a773d8ee90c194860c25be46333463ac6d849635d8ab6ce1574ddca02194720f886bd5e4b61f3038d11c8679fd793989bbb8ec5cb2802c156e7a25bcaff3e74b88e1917061944200f732e887a66ccd9c26dac5d41c61048ffb12cdbab0f194220c65f1fadfdf7c6ce1d194120f59a8f52580df25b1d8dad0fe8702c76d47800811c32f347d1fe4163eb0105193f206ddaa459f9d3b5865c860f489ab647b3c7348dad1d386ef480181f2e47dc64d4a82b2a41060f4897738ad97920e5c3cafd0e88f239666bd9dc4eebd7c1a3c173fa5cdbc901c982897ecaf97f467c1c103bc6acabf763798bfc0604d9d0a145f33aaf859b20c30604f1f138ceab8f875279928004354420a306249f1f9fbce7716840dab1303e96f219103a4c8ff74abd62ec7132204ef778fd1890b35767d7640806040b391fb551346db8d816a82f20a7e63ce841cd0fe673eb029266afa5524f8d2e1d1a5bb8855d0bc89f53a55c95630cd3380b085675d939a794b4dde22db46ac858013163c5b04e313774d0a8204305e41c5ff33045b310f3d98ee239766c7152416e8f61f231fcde67f55f0b1a3a66686dc1a8208f3ee7dbca7ea091d15310b22d5545a5c614c4fa36f9a9cab1d4fe5290efac0729887e66c187fa9d537d8d82684946a3aad4e2f228a8a220c897e641268b5b9bb20b05597be0dd31c6a8050ab27cec8c172a1f1bb7db98c19f20d665398dfe69deb1f60421327d6af270e438249861d709e28fc7913f4e1fe7edb86b718264e134b5e7eafa407d1a5b3bdc46163a666c82a47d73217ca89941bc2d5813c4d0de175f17caf34867ab106482942afd9b5898e7ce1a4c90f5d3bfe6f128a6b1d5011a658b2cb0288c052b2e4168ffb4d5bf5a82e8795c27173d2a022c72548260bfc92cfbc46cae8b12c40eb6d1620c3bb1719f04c95fc3479137a34a82f879b4a3adf9fda7deae462408d5835cd7ad6821e30512c4db14165ac47e04b952d0ecb5eecc69ab1d355c04334a0d2c70ec702b58e108f230d7edc71bdcaced87158d206ace94d57fd03715744610cc828e8f35848b206d47e51efc6d0e1b3716c7c6510431074b31b33f7a2a661241ce2e3e3ff6df3d6a0459e028882076f9c6dfdc108d3edfa87188df33466b4f591a82ec96d96131ba9aa35208b28f73b8d33c4e1382a89ec7e1a5651a043959f5c79c7627a2335608823c8eb2bda9a8d6f840907a28b1fffd4936d5aff18020e6ec26cfece3d772ff40f09863fc9f5b7e7b9b63865d8dac82157e2067ddfca144c6f24d250dd4ef032957b40e9d53cf077285f8f1a788f0b1e6bb07f27e0ed50f9f1e889f49235ecfcb033166ccf651ae643186f4c71014acc00351bc572bf8741e4d5adc815429c8747c8fec40f2816f0cbd3144f6a70ec4f9f6f1d891e384e0c64dc10a3a107a9c6276cee7f1a58c9533977fb8b4cecb813cef771bd2d3f9d91407f2e61f870fccc335cc0407f2a0ddb4071e2dde40cef1d9876f96d2963a504d0a56b881a0f2631f4d19e52f6b0339adc37b3f36a86c207eacf4169129aa8f5b03695fe37da8bd2c0a56a88194c721fab66ce637d41a33b2f01c22986157230d04d73fd9b3aea0a9353410eef2e8aafd7d67d4672056ce527964d32b1f356620e54c41e3ff682f03e9da5384c5ecc940eae1c4ede67c8e8118d7e388c5f0f162b88881e4e3689d529014350c449351df1ece060cc4a42afe66797f327bd42f10539c4e773dda1e7dac50bd401ef9e8e58165b8fb8650bb4030cbbd32a930f5f17081e43eb6b0dcb551b740f0617009f7c94790050e2bb440caa94e6fbb2d3c0be489d29c83df47dbd4c0020b448f4acd61b6de9fe51548f94527da4db57b3cfa958a9767ae0a04b96c9e7d18673cd5a402796cf367ba53d1bbc329903d588abf292ead7cf8e4702ba440de3c59af79187dc762686c4581fc31def93de7e0b0f133ec1e0ae436dbe8e6932edbd7384f2025d9ef71fe1fbcd81d38379c40aa4aeb97c7d6c367d87d13481fabca079d2f2690744abbdda7445d02d12a6de56da8eaed914a20a4c530b9513435e59f0472c6d69cb91c2a12c8b1a24755cd8dfc4e413d0259d376ca9d4aeff118d508e4f19fb6d9599ab1ec178168068c65a854cca66342f24830148bc4e2602808d12d4f00b31308000034348f0563a12cce0441ee1d148003754e2c3a361c1a161687c4216140200603026030200c0400c06040201000034221872cc3e3038252f398164567e3239f9a8407e101e0223967904d257e6c18d827133c4a92df7303ecc3738f10b58124fa438a20a7c79b3f7b4904eed9c60bb04a328895b5743f6f4f7f1177500bccc5fb0775e916d8f6ce03163531d88b2a1eff3eaa3b0f5f5f0236ff0cac80836ca7006ed53d7390bd08d77daf1145a745f799787363dcdd740897fb8b4be2b98f3963823bbf6741c968202728b86b458fee6c4902e895d68fa3139fa3547293041182f2295460d925d53579c84ca935d407da904d82473e9a7c458a03048f6d3ce0e00316c221f6904c23f084dfe367da60da4bb26c6f5ba9b630f26baa0300c62c8cb03f15663f56689ac077a20288f2fc6242165e9d330c97c32158ae0ccdd96773b0706a01181214b2054315da202fc56db598491a3fd940127d97f36c20551b3a44be9d46f08057615af26ba6b001a269074f8b428158b43dce2403b7b348c6a0876071ab382dac07e7f5333e8242178e5763bf02728841edbfc534838b70e4818ff8280cd0edc8aa9cd17395d9c039049b20413d173139ed8dff83f3e8398569bfe83c677a817a62de426481d1731cb6434843f43c3ca93821df64b3a827b20d0c0a0aad88da930a2c464f83aa5366413d213948b98d2863745c2921482b835b16d71ccb798d71357ac6c2612c276681217fab2297c5909e245e1e04c5a24c216a5e07319cf0f5e18a49791052eca4c2f5b93006f5675c72ff90abbb07409f9a36f4bc2733534620564dd725329dad9aabc5c6fce5e40ca06b99897b34b877e473bfe54d160e95062f3b23c2fcf058b293823c2afdc3740feeeca52985c54e2859d52a50649b24e4e07b1ad1f22e145571ba4c0420f2a742bebda418e5858300ccb9719a2da574335fe20dce992c27899b23a88ed903ef690b410cd368c46668e22215e5812b8b65b95c84c4c4dd18a4900b8c5db552c8e1ea392c53777aec8a3740847cf57ca9c846db1a217581942a2242c2bf48a99211f2d24a621dddcb26f1f555138df4802aa194615744c7d399e67ea8e38fe3a13e50c72539503e411d91b9dcb605d4f1ba06664026656a2f61f4b01947d22703339b982411341fa08cf6387e979b4722a7a22af96907dbf797206617244f935cc9db068641895f247e898ca3cdbca50e2a679fbb035fec37b6ec6aea37635108992c0036d707ab20e8487553d16e23ea3191e7c6115171a3d16ace562a54a39c2ae4f07a3343117e61589b2454eb2a82ef308ae2d247253e1db9f1255092ed82e0ede66810090100a423ad91ebbdcccc9a59d59da97bbbb885ccb9f4f9bcdd0fae189f223a141aa7284b21df73b1a66aec2b999008da544d544b986989857637ae528cf6554b0f7712d9839e68351bbc62cc9c7eadec959b8e296f4269a8dcb6c94f452283cfc4e678385ba76b14c9aff576b913e9c47e39af892481cb9f14722726f7bb8b65a5aea032c7188c79eb67625799376c4bbc86874c627b92a8c98159d217d5ecdc883f458961c00b5cae5ca549a22925dad2c828997fd5b14ef9afc8b839c78803232372af14da939049a743288d8aabcc66cc8ca8b876b5e2f7a8a9eefa3289e77e42e7c1f62935085f86daa381904806e13059d14ff9f7b72ac9bd686788519ca204becc3ded46447c1dd59bee1204c98a73e68ed5b754b0666655d9a2d829a0c22ab40d59aa7cae839a1146a8b4acf8113a366758f9e4a4f607ddcdf7521572b29170cd1b4d669336eda75d994928df0b3584b8210ea60b2f6a59c846e445404970212ec924ca15e00f62cf97c0f5d0c17dc927a6daa06c30712af2216efcb7e01914f3b28740c28c2507d7005161559566038781a1f916a6f8f7a26f9589011ae03066ce62db1c6f1270cbce3cf148ad4669a42cfe29953307dc0fb59317aaf5194e280a3c0ed2d2a37b5d8fc04b537e59d33d82c49a1ed21e096c999efabab3cf1609c2f0562d8bdac549c5198a97d85798da685a3f55236f7a26f1421332e5e2d6280f3f15514bacd9344d970742e49f952c68480d6682e6ed0a7461e5280ff033ba6fd4e8642243ed65143dc8469613943cf0d02a2287c6dc0501867032c89132bc13765e9221e0b9a8d609f81c11385f17849f3a2bac2daadd4841873feee50a2aa75f8468d23726bdd0e462b1511f104e84aa0cd8b2ebae632e7c15e08438cb64178782f0be8aaf227628efea8eb404b95f7e432aa10150fc0a0540cbafb05dc129c0c497f3153181e6b04c141e78ba37535608de0e33e80780c30eff616f9c9f55ac59f6688e4e6d9d6d07f0c7d223825c642f1b855b15fe0f7600f67d130b82936869f2c716660ed862d582a903b64a71f79dd42d2c8e488bf5aa50a2aba2ce3a84554ec2c69436400bedc64b5b34c38f6f5e9ca40140467c1a4b02e488e00baf768dc0e5a9845d2ec7d53114256cbc43832bb660ce2ff5e0131e50b6351708bc0cdba8bda10a44786a950b24b70202074a104a2c97166afb984561c42cbbd605697fc33443dcb34a4bae4d548095c79e05df04fbaec5b2840853b11343ab3c155ef76f4b87b30c608505e4b0d085f5d95ec115a988db645f334458aad4e5636c9f6bfc23346832500be0341537cb0cea650a538c8c1a339300dd38430179a045e01642ef53042706b17968017dce144e6113aacb3084bd5204d42765de0408a49106d4a53f0b958b95ef264efe0a3e415ca83617bd213e1831395a5078b0fa7bc1aaf5afe3ee7d4e3bb7295895d6c5d527cd4b5cd60b0871df72f870d723c5af7618c000954d42eb4961bb886b84876f9d20216c03609210dc33310a23c8a4f7f891e8ecadbd5dbc93c8f1bbc017a90402b02716ed02c778aef091b0601b816d06d98756614fa7c0842f2d42bf617f87842d6705ad9a47480c1116f1f1c636ccbbda102ca2c0e87f309855ebb7119878e24f07057698bdcc32ca0be2c908d08f1f20f0629b0186ae7621dd3dca6567e556182a5e5716855c1db03f63af4dc100fcc5253b4a614d5e9823ff3524563d4007f2aec2f727cb0b12973e62976f3f0b081faebd4bd900896b47cdd9c65e2a8a56daa103047e85348ceae61e2390e635db1d48a8701030a9809f1fd30a611a31256486f88198234cf7bb8bd4e547584424cdd8b05d4ec54d51108f1f0b18f17d66f080208153bdc00f62ced4240633e3a980b83015760250401e4a0540f931d708d3746e618616f811b005a711ee5e4bc5a35e0077b85f0c480573f23c1e634812769430c1fe8c547408d3dcfc12c30b61fa50b759aa89f02d2425b8d36e0f210d0ee33ec4f7941affb00f8149456e34a29cb08869a05b4b1b4d69090245b5ca68d65d4dbd25fc51d2b14d99d244c44168cf8ccd5c24c2f44e9f7ba84d89d0718d00d242e18636c6f91414171217a87e0f2cc7bf021b760955414189e3481033cdd41b080f140a1c47a9001083028613b73a4472fdec8b327d0ab497a05e175dfd299cf10f955a419de30ae482a7801a0e0588e1bc001b69ba90b8a813837ea64412a64420dee7711387c10a387323ef0569cb84b1bc38c53e04ed12b672c8be9a810a42d1bd3bd1cc1031ec1f1d441fbbed4086558e30114809b46b32f33902c9d893dd8df4c8847e4b103a87fa211322a19b883384aa0c9454017398ab9b59a50196840309a696261303c244c49c3c738b30f93d51387d21cb8b02828949368183413fb39e40d83327d114448dd89eee9a7afe30443acb19778e10044290514cc74c05f5cf351ba2e4a8d63be119098fc291bfc2ca29d267d43781fd0952efc4913f559e0262e7612ca2a4a333c46d32e228cb85ed7aa185f0536e6535118a03226f677463268573d12b400a8750c07a85f78f38f9f46109e49c225fc175ace1d6b2832485e7399edc15ca405d0172e8555078e23bdfa69c0a1d069582c2039c40004487e0490c828808421ac610085d8212e2341fe6c4d8e2b43a165071162e088e06962142b311255353b120b427ef203d256f0998a1a0f166ca0ae1d45a55da9e20fe5a5ca97b554c9dd20419a1fc54042c6daa5d0494ce50d0deecbf80929c64e5e274be5017021d34a91301936316d5e6224471d368d6c4849e5a4478dc1319012bdc474129c90a7ca5f5f3ea02545124170cc9f9ccb902a180bc9444842cf68e1821e16b624190167d0594b899dad34108b5c3664cc6b8243a903c3d56116d5aaf9e3c32a622cec9a0c27e57011594166a3b08a890bfd61daa824641c956281d1a81c32be80fefb17a450a3f512646207e219a39440ed5672f57ab6d7e2d54b227b026c117014be4980504e8bda40da1627850383d47e8565e84382b7abd480979fb7485cda3e97735d734ee2636200f8844d1b89802d57ab0ef46b20fba09927a0a2b28c3153750445a1a3d06c125a59fb7b0e4365610d85b273fb1138292f5b94fb86ee75213213d076b054325b7a06874536c54c7839b8760219346e2bb4c89d93adb6044d7cfdfa3385253c4b504249d6974935a51ed53f483fe3acce5bf13dd0952777093f20261b0470b84321004c9a18cfc030661045b2a439c812106662a4a646d92d631f679990824335da0610cc2471577f8240ee8dcd12355375d4393084028aca660e0d4d94c3dc28d7208d0a05affa7996f69a41d04f481cf5c81d2c327b1550153ad0dfcfa99a52d56ffc72d897ee2351009b43b73023ae81f57b481aa77538c9156d7a70291b472e0bc29c1f12cb4414e020047b05b1cdd90807102579c60d16eb4d864fc1a024489b64979743f5a3cbf1dcf9d1cf819d384fb100b55faf24723f32b51f3d23ea67c673259d7e040c3d04d1a80d0eda1f10437ccd3e1e5379abe01802a0fe096e774089bb35a8dc21953619ff336082a9526f359369388ee920fbf7acbbf85e694cb3d84ad7b1049856d7a4c8d9b1df007af4e8283a81464d590ebea639cf035efa029a2c0b4e4039916dc1374a80ec9e2cc3c91ee1dc128aefda8e4169f77eb75513f8584605d0e9023d78a45102640ac9dc7cd75a785c54cbaccbe02c8002ee3edfbf26fe58db8de4faa63ff4d07e76f71397ec445b7e4529bc2829b4ba190a967085d94160443f9f75118f78d4440b986e5a1857e8b017acf16b042e202ae62aa0580c3d688fcbb7689972c1599c67b64014284308cffc7cc0395d00ee6889d904e95bcc6cd029eaec25dd956665abf623cb368482b83ccb8483e9e1b83672b68b0d6234db88f88dc7e79baef3b0bff111b189075f1befdb3ba008fecd0495f3e5e706674ba36c705cffcf945dc8e9027f5bcc4b1394e1b40c4d2ee0cade63774d48644d774ac75e49205d11677fbd87295f5051d529f1cb99d2c21c77d2ab0cb20502919e8d1c58a7a846eb6c31eeeb39e5652ea69183d3ac27b0dc48b6b4ed24bf9c3e51d700898d0948957e39ef8417e98716fc22768824350782632bd031f85407c20ac15df5e340ce43d121d8790e9650318dab38921f0d2b64d48e316a3df63cddc7e48ba9b1a81191da597b13c8e9f0cefbec84632a72ce5d2188c3a892b57112613c6e7aa02bc7f8d3b19b854b32fcebf823051045331e6ff7c8f29754fdb6d044d573c668d863e39b840ecd5ba1c6b53bb57c09338593747280893cd2f52b36db46b9003c2d973d98517d842420462a36bd253410dacb57b07e595fbdb7340d4e7007307608f14fc01c850f45436cd507f23d972b8d58442a595554f211d3b44627f5586cc88a13b2e8b5abbbd8357f0da6d835d038a6f49c634edb2561fded2fa17b0234ec81cd4b6cb8a2a30c32be660f2e68293dca631ab943e8931fbe047f83551caaf83b776bb08714598b601dffc51931a8e2ef881ca32c7af54cccc64f4e05ddbda8d76d074caaefc50d96cceca54ae29169fc9cab753f82c94fa01832cde0d8f02356c5f76f385838cf806a99ea698f814361392293f59e4f7819e6167f71600093b2f7d2d6de04875a4136dda8e5cce2df8636029ff550370755a54e230f708d51603abf49bae940aad68b7f55313e191685e42af77cae01081b838cf498a523d2c7e24c633ecaa1801270456dba946a0e0b2f08ab9b19751ac41c623f752cc160d0d57ea91901b4b8560bb5501e8ee7e50640cd21895a1e6a9cc84164ae82ab63c08add142033b33db8bf60a75d2487f69f632a3885285b38ee394cf70b25078e03e2cc0889103dc2a8bac4545a2985900a518d71428e3912e150d1c590062bab303cd29fb67d4292d1c77e1c4eed47849525dfa00db388d6be4484b748414898b8d41083a3629602533cf917a9f61d9ba6b66ef8bec5f7ee0d472186b571dda669a2d2980dd43827a9148aab8dce7e1703e985e87b9d3e2c58e35f0d0530c4ab8518c33b65b98a428565352570aee6f726754e8b359231fc4ed598d3d50e398d35cfeca2332cbca14179c9aa3988f66b776b40e700e572a8759a7cae03abe46029d587a7119f0214f399b37356583b4a687b86d4d8a863740ee61bdd3b5090b656fa1601eaeeae8f9c4899b14974ff78c831975bdf775e226ad3f524a4671e6afbe256abd512f7b3814ab4e108541694585cf49354d8d3b7d443e0cfb767671445d82f97b2b422a18bd8dc8cd7be80ca39d56074ed39d4fd4e30387a87d6bd881487949062cb082d33519978c9220440c35d678b42a728593b11d98cb4968278dc9ac6edccbb5d66a9b6c26553d798c04a026d4a5faaf889ec70a08dde5dd65040c49896914324f59bf1e3ef5dce6722bbec0232e82796d7742665e18fd905180388b38e280d7ae4ce0186d6e191ad08742c1258b22bee7fe8f1069aa3fc8dc1de12ba5ce9c112827d56c8ab6312af27207b67a0f3ff1e9ae60f89ec0d2c278bb77d84a75301564b6403a9628ef8808562db483f8584475aae92ed8414aa31ebcdd72a8e37a04a309890dc0b9c8d046637d1ac6d723556261e6c84830616ae4d221141d988d8b05162313e14e3e89ca0a8b67317789fe5210e6990a57fcde408506c7d85090dc725eaa5d4c0d36507f90554e99842d0586cfd2913bec164d19326a35e4e94678d7ea229fa5e9776109f97254f34a0bdf414fc34a9802f6974ad96f12c63df8cc6e6f1e22b3049e2312fc56504217c7a4addc543072a2dcc1b6791228aba2609c48691dd122fe695683a512766992aafb292f99d29a7c3cff864153a9dff6bb4584e256713c8337aef7457acfb8733d589c7903de7a2fb5d1f6271303af5c28ed609da283b5b6d5b7c9183876140225f196de5500437981eeac4f0ae7b733fa57e210107f7a21cee129a86be5b6a15f6b56e4a0a40541ba90ce8d73001c5a7ac58d4c56c55e5ef60e662a7a7505ff2b998765e6463d59108df57e2d9c450a77a2a359761f0d10009c50fc0e0c16e72c9774a66c32d32148522b68f6ef82a5ca422b95365200a9b0c904e56dbbcfff2f0291572389d65ed9b27b086648c60c772a7d145007795300591c1bd0f47cb18f6aff899777496eec3dc6222ec1495b17d9b0ccd8342567eaeaf12e3886074a976c4236ff9133ffd890dc6bcbe05b1ebe98ed1a2239154dfb10713dd113e89fa8a1ffaeb1375c5543ed4bfeda537a4b8985122d1294702f5dafbd16e93eb8bb7eac6b58a705d28fc6d02cae8fa82272694ff47dbf27b78f49148aa4be12b7f3529529cc56a86581310d7eba91294e0c5a877debe35902a343a08cdc567b0bb13e5558cc0a2aca473de5766528196c91cb7b576b10dc7333b371797b2be706df37bb4c1f256cca5f9ca9a0b04cb3535498df9e2f3641a9c6c5cccaf376d7ddfb8bc006927c96eac3ba45d492c8f65a9e005619e18bdddd2d32b3730e22a8c4d41a89db898cfa688b16abac6fe2cf2c3c8562b1ce9a7bbbc577e717c11b620768edd75139a3adde6a54181d1524a1b0339fb40845f4d45a9935d614d2a7bbe0b90f27641733c333e6801cbe1729cef9ca9fb00648a1537dc6459ff2447b19cca0996142c909651ab37d79df3e032afd3410106691174e025ff0fb5e534e269a1b4fa5c2944101048362c7b31e4947d07e66ae76093219484e49f4a487f12e85d9c77082ae61f3fe590bb277acdd4705f4cc8c5911a7e824e6738436ac05a53cc0abf1a2346c350ca44ee99fc056f4a541904c85aad217712cc88edc01fe9915069c91fd67fd31183a423499f529844a80662eb12d9207eb45a46d027fa81804a432a08090cf2c02051f88d2ef4e72118a66ef6d81090d236da72817d29cddb5d6746bd4c9fa69f43fdb77f9656eeb11873052a74cf5e9548bb0e51852360b4ac89df52228e12da978962c42abc95541fe80f3cce2ee0e562245d9b0dc7e479c29dd3a5413f422e7afd10125b750240b7f0f42f8fd1b96411fec1d27db81a55143ec23153515651e57b2bc48e853f969bc276fe925725b0fcbd8291206482a8e50882ada5a84e3851da333a8da557966f97ee271027600a09c0cf7f04e5e5a0d6be5bec1f447f8023eac40a8806d048de32fbefbfd61bd8b36b67e1808a2f6e4694d7919c4633c2a6ecf717ab0e803e95d535d9fb01b77ff7758e73f47667d46ed17c466445f818af7c89df65a3b1333e43c9cb9cb6fff892261a2b0625a19b459848d532a234a811afa2608aa8353965f3eaa979da14f00c7df284839640ac958403b22e73b7c9befda25f2fb00dddde780ca46e6d7fb644a47e34fbe0291d129872c69342ecfbc8e439a369570e6e7d16a12313d1cf53ddf44249b748e89408eb134573e25584cbe1c83d84e6210efb56eb074104fab18593cd6d2a5965f41551e68f58028e3e894bf2e1f7d446060ffe05e1b0f9b533eebdcdb990ba017c195600eaf5a8fed6e5b9c7224eeca6bb1709e5384d5888e3062474e250a313620aebae3ea994a573545438c654e02fe2f10e45a882d9e102843f3bccb874af2232c4392064c3d7c04f4247f261e46e02a5d06e1d0718032dc66d9731f64be92048ee8036cef2fccc791e74ba5f5f7d947639dac1542ca285a132bfea42703d1443484a29ffc95588b2d5a9d69e06b41c18da14f30a41a3d54b62e721af55d66b8165642118e8a6f3940cfb824d704d780169ef180f09e4e41f2f4ce047e3e43dc5c0ca188a19dd15d8df3cb961257c7cf1ffd0e2e02f1dc900e6be2bb7aa00df383466f6e88aabbe754fe36c6fba0c1d8269638c8ef9d35b3420a4f1c21dea9ead37bd4cabb7047514daa79a8236bcb6a72b5f5eb53f7f3bfbbae2802d9ce42b400218977e5a131143647a98df92d55e2f1e525d2e3f69032e8a8ea5b6b5f10d828cdd714b71cde5dc9d28e057601c6d28e25b8b419dddb0a700f4b0084124e8ddeb5c817d870af94463e3ab1812eba0e9cec28338cb3a9c96656584dba68acfba5491634805a4115d8de0e78209dd030763e79f2e53eb62e015569d4f8ab502481bd1af76710063a393f304efca882523b5aa34320dca0089b4311a71b7f41c6329ab96b43260007c4e039409b98ac0a0cfaa231c40437e8e1eec202bd04a637c980e447e5cbde0aa0560da52bfff0e40e35a7e63267648eb51b46c51ce03e42190b8a7760fd40a9fa87acb89f96c346b3c01897871adee1be6c551213611c97536cd080cbd0290b2449eb0a928488af55671f476217e324ed15e0052c605dcdc2bcd8cbb5606d85e9123cf683a806c26675e8b7dbeceb6b9cf3f6e5d65467ffaacdc5c41cfb26e7194ddc895ab02c444da282de3fcc2111b0980649a141e1592f12004f43df29baaae0da25bdd80d127dc451d4b20fa829095b12980736c2abc356dd5188b514dbe7e6c0bdde52b220eeda023702cc8887d181a5543f2766358aef5f12845ba7cd644ef6c5410c111efbadfd0593fa4c6ec8116600aca7dae239a6518c64695cbc85e9333ceb65943aa10d4fa7d13a2594d19c5e7557ef68198b16774534e4fe4bf9411ba69db71c45d7139a4459dafce10a9a70acb72d97920e6fec00d8307afd91aa372ad53031bc157298505675d39ad33d4bfb6091cf97577b758db261bab3c24c01fc267117afe92c291dd36fb9318cd7b4627578866e446731885bba1714ac3c634f5c4c33d18dc33dbd9d0289767d514c9cc13b06ba59bd5c71bfc3ff825edb519e1c7250749298d876dca8b4811872ae595c32516147259a4e41767a3ab56f456027a523810e1fe2b23027d60efaef1bc2834a11e8b67dc380078506f0fb2559c017f92d05ff3af6b1cdcc6e71b2babf92a9706ebc6c533783aeba39e5067ec9a63b0e977e844749e4ac2042289ba65148ef3676c209735e61f43f98a334d655c45fc0bab60a1d306ce30210dfd530c67bac1684ce4533ea78e009411e5d59889a0dd0b0f000c5c3743ae84a6931ee0c9f3e70420a3fb92247b289815fc72e80b61b85441df801fae105ac0351dfeea1b354a0b0ae11eb8ce0e984fceeca565ea49b1182662436518d470bad36c58c8d4dcccc8983c71b004aa4ca2c60d79a3900ebc0e4e045fe297ae351068c1c6928a86005cbf7fbbacd6c13c28cf83e0fd92470770ab97a8e969bee41213f3ef58ec1af940bb89c747d160d630877ab4eaba281f763767ad41e7984d2c0cd70262f207f38d06a59d94efa14adbbb064acb0a0ef31215c2b48784cc8b14ff56a189353f8b531675399b0fac2bf20cd0116ab39a622c50bfe523d2b7ed9235786859a64b61eccc6ae64b29d3f417482898bf20dd3034a5830fe5b1890d0d3e3e36408aeaf07e3ea8b4d9e3b457f0c8cb02baaf427e052184e56800b0925fd353e85f580214b3c34f7245ab02ad0254d3c5d4419601585059b63ee4ad415a5a67bcd4fa9e359a50cd8684d9a88f7cc8f4e8fb47808cb844c795c30adf47c92e9b673783fece29d786d9463cdeed576540455bbb0273f9d5187d874a967e29f806dc4eafaadb0083f7c953b25fb604111ce09c52ec0b3086c41d2f7869fac45a11c64ab85b793cc6d40ebc2bb1560b1811bd391452b71007b302f51fb91927dce579d5d2b2be9d5a8d48867b2a97383ff1f5497560b69a4c412c4e82a4f41d1c889bb4071253a6e7af7299ad802eae73e13e7c0f07092cc1b5a02e25d87c08be4cde913d29b915e23a2b8b392320fbb3f037a6c1f5ad8f4221e19a558828232d12b64da44a2e9144a04ac101a6b56bc0fbe45ce03019d67ac06b1313042abc41c505c19213ade6399036079f75935443e6679cf48aa014c37bc58e3c20d3124efbbb07e278ff1dda74e394755577d2692acc9cbbc546094a29f2d975576cd5e9878cf66f18b3893e1d0d4e308370155c176849f61648c38cdb138fe85088793350a461ec4159414329b90a730ed2937ffd665135f7a88a293f25435f2f16a2190d2a2b05b5e4f8ae44a0025be18d4c694058fda9c1e9dca458819bc83616bf7fa43f84ab6133a56cfdca3e0016efe09533ed71ec263cfcc639a1340a24f40c2a024148f55eac9b67a6716d0307ee8fbd677f8cba43ca0d6e27d38456f148241bff58eff0d800a56afc128ac5366c8fbc12809413ac43e5953549657a1e8b7d104e692f64c2b63230e55ff21bc2f59294d137792911383710d113bd6a33b211a8fd26485a85a1d49d34442f57ea9228afe1dc6ff1aae3e64f1c791039549ceee4817fce47550dab99924b170145ff92be7539c83fa382f68a4ae08c0143f6f2d1aaf35d989a99b58b83d439c78ae8a486e2d85c3b0af38aca55fc5742a67ecc1d3138e7cf8c7b3507e4b4d91dfce24d21d40e7f52555e889d88659e4b39019eeaf770d19b6a0f690f19da7143f45360269008c05b73c83c1fa8fcf4ef17814e02f31d919a59a0f6d781e9d195bd8f6d41ca3848143989c39b4b512a67cbf1cffbed0c068837a8797f3b86dc00c95c2c8f75df490d1ad7e280685b9e05231445a2e06f2858a51a591644ca1206795de0f341b9ae470ff0be1376434a6d4a6243baedc649a848d86cef6c434471df7c044e3b16318e6bfa757fe5238231e92fe76c2f2fb0596cc477a93e1c948d81c59cb36b4e938aed67c8d0838d030151fe47aa142f1ed1f9036a71346bb5c81865fa5285d4fc02078f8c9aa55ab1cbf55222357e99e207edd4e3cfc948387f834108ce6c994b4bcf60e3fa4ded128651b9029a23c02cd7cadefecade2ab7634611ed54dad3fe37a1c73e505b58cf22a5081939e2bf89dce51095538cb868a83b5261388b4f2c25f561ead4b830489d0974e652b6fab41b1d9626bae23a8b54a9fa75f6765a3668eb2064c987a3f8622f4321b9c32e9b2ba3a779c53e1288cccbd8387f7e99bf35ddd18de7e3bc39a08ada7535c9bcb398acc2afd4772acd768ed65af86362bfc22920f4d1a0b6554587794a4b8c0db639c20ba825f2b64ee3f295cc01a260a3cc7c0b33027c57af104cc28a3347cbd9d88f64f8652eb58cbe313bb47691b36f44b89d949a7dfba146d588866f996ea16839b42fe36540682d296f11860b3fdbfc65968eaa0050f1de2e3643101367ebc81d041981734d8107b4d21fa079e5eab3ff75779fbe79a72ff683a836d67e71178b0e950328e0461190f01d630fdb910a94242b7136e5cac4153a20595dd81dd81536a1c5a3d057ec28c6fea56b1735fe4da6c21afcf6c03dade23d876bacec84cfba59c93d0c1919e265d2fdca42cb859732b2d6ecad94905b122874aef15fcadd7f2533ac9977e8533595c420201255cb48f12401df32fc23eed272091fdc238e13f11e63ef40cb6eafd274ac0e4fafb58334b11a513384f55f319a4da2b72f2357ef4231d32672ca7db26a1779f41058e7b560f395cd3b08e03af44e52420a5bd7e50bb42465b2ca61fba2be8fc41ea9f850615b8334039ba0d9943111b9c8ffc8b0757487ddeba82621fd822e744814b1d284af522d07bc4ecc1b6fc2a81f5b6186faee6b7b26614efa8d50d9abf4b0826870a6c0a0dccd04250ebe4894d0885dd016a14e3813640b224c301ffffffffffffff7ffa34a135f25b6bfd97342b9394c9eb1042c80351899a524a29c9b411deb60b38ed33dae7731e736503f007fd07f0073976e09898250cd6e45f3595942827469283cb2a61fe4b2ed2b47d96cc8f950f4a185427cd30f1499330eea9bf96bb25616ed23b7964d99349dff148183d4d58ca5b964ab18584f1ab3e6985a7cfa3d44718b4fce80e5b31cd74e808f3c81d2765115ad2524a234c4af4ca7f35298c30cd68e905cf13aad76411e67c5f9d1292c621434704629820026de34b383031117c28c24c7eb2dc7ab5854a279e088393443e29ba8fe7d78d0893268ede878ae95fba3c8439da6527c5f925bb101ac254426c096542ff2d90c247218c9f4cdcc7b4788d46c107218cff7b42dc3e5f5ac9fe63100665aa4db75269b9e42447181f823093427f6c2793321b25af0331f01108f305e9e4adf8031046d9ccbf12f19e432c33148b041f7f309ced28277b503a3f97810f3f98f72f8c85061f7d303a29933c57b056f1bd3c3c0a1fcca322162c3da5f7f0f76078d28926adc6fda187908f3c98f32fa9924fef1727938f5aef64ddeb2875d8f81a607c0b70803c3cd0a392de01868747dbf8929651253a7084e1e30ee67c275b7a8e5ef1a5cc31020f0f1d253770d420d1c2871d8cb5277e4159ba0ee67ea2f93d39cfe9d3930ee6f89979512a3707e3c5bf28b38f4d12138d1b386a74498c02830f3998635fefd88b6e1d8b1e1b3b401007a39b4a169fa0a3e8e71e0ee6cfd1267f3a99e49ee26f30c5b59ed72cb55297fb70835d99f064c287bc39b19b14ff7a545cd30cad4929d181e3a30da67a0be99ee7375f84d86052f5d6afc13cbab23399d8aa1acc49e876f4b84eb6cbb934983d47d869db4ccb958206933221fcd52c65f45f1f6730f80571177ba26433d4147c98c160954e567573721c4dce97c1b44df8caf972109b63213298ddb5b27fd410baf79d8483c918cc61a7de3194924f1ee4430c66a27a4e719486b0977747180cca42ff4ec55e8f4d4bda06c602ab52313ec06054ad9d13174f85b2ff0be62a21b7a255929594dc0b469395b23349ba8678b25d30777062856cb298ee8b5c30a7a5b2ecf2799e4c740ba6584aa830fbea430b8653a70976c1c7496eda2c18ce53ce973269fbc082d12d09afb0fdceeb64031f57e0c94d26132dc54aaf604a849ba913e3f549193eac60d2e4fbb48e9fffebe68f2a98ce4f890b0d9f0ac6ce57d9779c6c6117e2008de0630ae6ecd044277dd89c8c15811821c8418344c70e9cf1210533b9744e27e7f87978b48e46f6110573caaa8a159bb06aaaeb07148c5a27579553934e6fabfc7882297f4851719db0b93f7282b1fe936882ee4d3067929893448acc04f3a528d3a53655cdcd8f259882d0ed41acc9d54be58712cce139bdc8137e1b2460d83059818f2498e3b467f2769e90904853e61fc1a4b3274b2ada82b21c8d600a22cfde4b3db4ae2b82f13a077b920aff213b2382d94d5367ffb35b5296cee06308a6a0b29e941d132d27b711c687100c722c7c3a416882e8cf098271646ae51c9df3eb1608a62725eb18c2cc1f183e3c65898fbdcdd43e7c6054ef131572dac337a95e98edd265529e52b1ef9ac4e0854e122d9692aa27382c89b18bcaabdd82663a51ced2d53aa6cfc72b8b67fe6e0d62e8c2d41d1bd2ab64a5d928170653a1f9243d2d9e931c17a6601746e7954f1556be852956968593ce49a7494a5b98b329e5977d2ba5fd945a1874a7e81d7ef6094f9a16e69c4a3bc94961c5988559465a13439309ca529a922c4cf23d747c79e795a5c4c29cf284a66558b0303929ac56b87ad4515f61d8d27092324bc9e10aa3cac7f5ad145779f956983ee4f43f4169e2936fc40ac3a754dd72175f85513d7aeace255561ac389fa272e852617691a24dc7d250610a51ba263244f9a9e8290ce395495f42d5988eab29cc49779ccb3ab914e6b097b3e777fac7635298fb64bf7638f95198c3cb5a26c8b34e37b6288cdb3d4aa87c5ed77b098551fffa3241f5579cac4061aa72e257bc6fddd7ed136692e67f78edbc12be27cc3984260951f5e9c42427558f8e5c9013a6d839c59c8c534d765236516d5e3269c2b4a63f0895e307f95f264ce12c2d634bac56121366529eda269c6e5dd0b984e1469acfa994b584399db23c263c5dc6ab84d15fffe456987b113e250cca9de09e2bd23de74cc2202fc9dbdd4bd1bcaa8d430c4998ab35bdb37365b3120993f6d5760aae215a48984a998fb0a0ba7ea1f208d33de1dc54bc5787e51c61d2509d63c51a617673ad32df50e1c933234c5ba6e67413bd43a89563116627cceff75beed1a6e71b6228c2e8245941c8d22c11a6278c3f296d68275d767220c29cd642d3629d7cc70f61fc4c4ee641dfd907991ba227939ba0bb2146210ce7c426eaa526b667524908f33751c4bee5493aab671026cbd957b71db21c6208c2f4dd39fad91408935dec3365593ccd27e52106204cb5174d54bef6076393af3fcfa9ae4a262f691d326c1431fc60ca7227950c7542cbbf1c36488a2662f4c1e864f213efdfe4d786187c301347769e0acf244d56cf1e4ce617ab2b88a6b68f33b44a5c0f267922439cff563fd1646b889107b37fa8b05349c66788810733b9b2ea771364094bcf1dcce4317731dd29fc4f66886107833e99a4b4882e5d4e6c92861875306efda8345fe252430c3a187493723e39e756c937e98d18733085712ff79e73521f430e8d5f104d4edb61f6371ec488c3e7d7e4ac71bdee2def20061c0aaaf19ea6ae29f7be63a71cc4788371ff9da4fd6458f253224133aa5e10c30da64b5d499eb4e6478c36986bcfc9cb28c60693bacba4cc75cba40bf78d636307088e060b62acc16c9915d6d6538b1c251a396c740c35989af0f1b5279a287fe93418f5743671f19eea25666704d34953b9dd30af2c7a110ce263fe6e857e709313c1f024a593ee9c6af599fc10cc163461dbec444da542308ff4f8826090e5c4135294f67b2605046385fc5d6b27a9f041e907e654f9ed397b93101f98b45dd2a71e1fe572d40b7326fb5589ec6a52fac50b73b0d2a374126b17c67d824a4d1ed3a75312d285f973a5eef3cb240bca85e1e47eef52789727888307c185a976d6defedfb546790b9395d88da56d491142105bf461c3a2c6c70f482d0c62f103420b734aeb848b1aba924e3190591c94ed8599034416c626ff5a760cdbef0e6b2ccc7e16efc9233ae9a8720b6c80c0c26449a91c26df9a589dbdc2a42af5b409d9e4d24e7c869682b8c2a4fdcd3a3fe93497439f020f0f6d85b9f4b9ecec788bc8158415a6daf69b4b3a3b9920016415e6d8a59e684fd6f40a621a376ea840478e0d80a8c2a0d2badffdf44959eb5d01482a4cbe9f9e4c36f984bb2768415061ded2a4ca377f829cc27c227734b1b45a4ae2648aadf72b8f1069e1498d088080051198cc002985599f2c76b1c6c25b6e02420ae36f3859e4e41e85e962dce2c9a4abe0e4a0280c6a9bacf5e4bb84c2a84e1c195dbb1f942636430bc70d192537781b1e1e3c0410501846cc7e4e6521ff1b7b78207fc2dc643f158f1d8f279d38ee880088274c25c4fea710af53d1f7f02001e9c4272a37c2f15f021c374a3ee0e1a1230c07010b223051104e58b13ca77db21f860e1c358c874701d984c1da4767cb24d50c2dbc0088260c4a6bdbb47c0e62d6b5004826cc66f304995d39af0a08260cf2429bca4ece7965f497307c924dada4479630df6582e8d0619e83852a618aebbb998fa5a64e4d0983a786b7febb1345d59330a8f8ecca9d2309537abc2fedd93ca71147c2dc1e6fad73362f1e8584296e8926a9c71357531f614abac9a2ab9d3ac29445aa77cc51f755c946982fe4e2c77f927b52414698eec5c63a8a6e1106952fe81e6da1e9a75284d9e48b4a8f66224cd799d664729576f2208830ab9690f31ad3e4d49970090e1c3cc821cac310ee8e9027c693c92415c294a3e2c513abbf840a2284f962c9b020db33394c833067dd2c131d178449a9b439fd5cb14b3d81a8b28687656b6b93da2d3c3649d5439303020853ca97e1a92d6f932dfe07e39f4e5f1f762e57a709c40f06916ee9828edd07637bdd3551d5e7d3a7207c305a780abde7953d1856f53cda27e9c11ccbd45bf2501ecce46c4dfcbe54513e8e07538a7ca2853ea57348ef60ceba3ea376513ba47d46a57ff6b30ec651e7c43eb399ed9ca48349a7b727d149ee8e8573309fd41c3fcb5962343939184eadbbd3a655d5938a8379a4c685cf1dda46650207532525d79aa103f206738a93b5e4b4d9e5f080b8c14c30ddce7a1f7384655904a40d46d7d0b9beb5e2746e206c305dee797e07f5416d63878c1bdc2801c30a640de670e298699c1a0f440d6652b2d06995d60cad054983b145c87a94dd7c3747190b40d06050314b7a52bdd5a49765e8f81c7c06a3573699eb9719cc9f9df4f29f2f85d2ac0ce6ac5d2d42d52d6430dd298be1a44c0a640cbb134bd74a868e8d1d690222069377888925b5d42031903078af63eb991cc62a0a020653b75baad1dbd6a472240d4eebc8812a00f98249ef6f96fcca965e421b3b40809e0689870718205e30c9d0e426294dd66cad2c8e3ec1a31b1e501c5d633500d20573d22675cc2f2596f9ff8edf41a36d00c20583da8792a23b09a900b28504d18229ed56747a502a77873702902c18943931a47d3a2d730f160c42eacdd78b9630a15fc1204e8d52f7575bc12094bddb557b161173150c9af3c4dc6e725430585acc986765b3b0a66026fb6982b6f448c198ae63714393e2e7730212056345d7ae5239f788930908144c9aec8453d70bc8138c17aafd53d2f63b764f0e88130c5a26d29f9c63a709f197a009c6d972cbd3a74295d85e238c16848030c12446dcb8934d678909812cc1e42f6ef7e4787d273e102518cc4a75b839f33c228224c1e075a1d9bf96dc90a1e3c128751e004182e93d64788abd6ee7e11a39486ac83882418fd2237253540cc40836a9b46856865b65408a60b8f3daab4c6a7fb53c11cc494598fe709d2198ee4923dab34ad54d2118bfb3c3ed5e360866827ccdce410504c3e628391a1ea37226fa0383f44cf8ed9f1df57081f8c074dbe9dec43aa1c0053274f0d10b636cefe9fa25cf91f3c2f0c4ed8fb5ce7d36271b25af034b74e0f8d885c9458ac8588cb85dec4317e654179a19c2c711868e5c98f4652d4f2afaba8b7e86a60a3e7061f2b83619376e996c3921f0f0d0b2c2c72d4c7aeb532eed6d6126bd79fa9c47b530c9316d13f16499770f2d0cd764b3d1667d7e41b330d9d8a5265cce75d26a599893c5aad1f85c2c8c9e1f7294586161f49c3e7fd05e61509f838ab993c3a8982350c3872b8c77b1f494ecf4339f451c3bd07f000dc70ef4084bf0d10a83ad8a13ee73c40a83265f8c4a8bcf49e56bf2b10a83e78efa87c71faa307a48ef981db4497da4c2d8aa21dd7a0e7ca0c24c6ef7b8d697b68ede514306968f5318540e63af152ba63007f9f04f12e59051eca314a63bf124ad9d7639763929a43089d2d36d7175b59ad40cadfa188561feaab65be4661fa230acbbcba894217c5426a13079320b77efe9fb0085c9e2c9b373d77f7cc2fcaa9bee1e3cae92b7616304ef09d3e6e5d19379720925cfd042a897c6ef00c1617d74c26ce294b251ff99e08313a79c77150b3e3661fea4266fa24cfe5b651f9a30cfd6a69ee8642a238e1a3b68fc8e64343e32610c4bf2ce3349e7bca5820993f0949aa2779d60c9cec1dbb81b1f97303769abad3d8a74d2c74b5cc68cfd574e6a3c98b3cdcf88cfa9b9e5b983c954de10aa74697ce77630e93e49494f6983d13a8a0422753069f687fca09efb21a283e9897df37db949ad962c7330ab7cb6243f32ed3f9c72308ff9a730f349170753f6add2e4a0ab2fb3fc1c56703096dc557f2713576523f206d37c689dabbd28e286422cc9b8e75fa40d66a2bbc8afd68a0d0675a9db1b525e83416c9d3c49094f5795974488a8c1b8374ae92c31a72e935384481a4ca59bd8263e56d3bd8406833c29cc4942fb322b7b06834ea9c309e2213398a3bcdd24988b102983d9499e83125533a3c3981e1e8c10218329e685a9269354434b37920d226330d5fa5c133c9b4a58f02568101183c12c8552d154670d4d4cc60d1d32ca4044c2604e6a9f7a7410a6f35b748440040c77f01cd474ab61d010f9822594477372525e5b8978c14c6e53fa592ab63bc55d303ef93cff89b295f425225c308d7fa66578ab9e225b30eb6593a3c92928952d2f02112da4c694f4363d18225930c9b3f3e464b3b7dcde0c2d76810816cc992c5bb9b3a71e9457c042dc2b68134ed3924effc40e6e298e03075f03112b18ada4bec85c9c3e99f0a46a05225530e71125f737945ca96fa31f471831f80422543097b692729a9c9ca1952122533057e567d9273d29139182d99314274527890b3ac777e4909183c4ec718411635231108982b1669d78fda4344fda9645a06054311daaac45cd5e7a6603912718b47a4d7ece5a4c9d818813b4eb64a13b2803a1c67a1dada3051eb8928148134ceb5677ea3c452d8b9860cc6bddcede97603e7da57ea7b3124c41781e9b1162e5c43709261564797aa51ee5e92221f5ea4d70ffff08262da3c995a6f2a4c58d6038bd9b714a4487b754a40866d3fd673ace4304639db470a2323d77dc43306978c976f8931f5b158251d48868a2a717cb490d82d1f275888e2d104c39754eb272c2c64e3f30a94cd2ef3eb788f8c0749a4cd47de2a6da1364bdd894dd67bc30a918e2099f9da4ecff5d18ae820c6922d685c9e4133febad492e8a15b4cb49299b5536374b2542362dd8675d500ac1854144fc93f2a6760bc35d9021dfd90ab185a972ad9afdb5c81cbd16a6164fe1c9ad4f6861fefc1af9d1ad2e932e2d2984ccc2acffa549a2d53d7f9e4a646190a39e09e2723362613c5195b7af950d6061aaa0a6beab5a1b4de315e6ce9b1521cf5cc6b3ef0a73c86b93491d74425a610a0bcfa77295924e9e4358610eb5b467972b8bd8d32a4cf9940edf164b1506add0991c3abe62fa940a93a5080ff3fa0415066d5ad5c132f944a82760d82041fd3426760a3329e9beb0dd49a6602cc558f0b21406534efcf8c4d1fdea9d355298cf4c97127d9e4e2b360ab38e9e4e2a3a9ba34433b44ac911234414061d4c3f9e2a8fd3d29384a23c484061b64cfcd427ccf2d9ff467f46831c5782104f98d73b67a56c36338341e232b23a511e3b423861babb70a3e499df9c3b5010b20983273fcba7a255dab866688926cca42795ccfbcb65c2ef195aa53e4232610a4adbd56552a55a10820953268fe954f1b493c9a5d391a38424a95dc298963ddb2747674b7a53418825fccc7d929a1475a98449737b4d98e84fab9e12a6a0a79aec415c26934627641255e5b5dcaece089184e9635dac736c9343cb21910881048e904714ac64d53c768e48b52a7c9441c082084c6a0c218d40e40963c943d4c21b8430e2547a7a4a3f8e1661d0049fb7b0344a5dabe34388224cb1b477322df1ca75fb21241106a1a35a7e8acad9f9094184c9ce5fdf4a8e420e610ae65afe1ae214628884a7ca6af9e9420a610e69b12bcb95bc2446a5648410c22064986c5265d86e3b091984f9e48a4e79eb2308f3a85ce72935614f350f0984399ef6f9967c324908350410a6278dd68b172a64ff19f207936a7229d395e3ac4927217e289aa76c09e98399244649ef772f870e92103e98d3e9dabc89ef3bf10cd98329a91e214c78bbc77b3c3c42f460b20aadb69ce241b7290fe6273fd9ef2b45557830c8d123f66694d8adf30ec6bdfdb0735247ce9cec60eeff36b91e3d4b74ae0e2627d88c3da993f264692b74302721bf532a4bf99994399853d4f5706a9d98a344fa613a0991834943c9cba4a0d2839038144bf96a9d9389d5e443e090897a8913adad9a4c7815599b1bf5b043de600abfabcf6462763e294e83738346073c3c3c3cdc604ead22e4ff7eb8073fa40d66ed1136571d4ecfea216c30e7d80a95897aa6c4440c598341f698a79927e5a4846a84a8c1957d9f374b3ec70762012142d2600cdb7472ce41ba25b55486a0c1f033a245763a41fea83c3c72849cc1e864723839f89384c793ddfa1a5d02021a37acca0931034fbcb98f4f587f86868494e1784929d91d0a2183ca20640c9d922eaa9cd497c37a319854d4fe7a0eb92c310a83f93b6927ad9ad244d91c0c46370bca7cb352e669bf903759649b2cc23a5eb0642e4527d5a814f477d8893d83902e98730e15dcbd54d87a950b26e57fda54c772cb6a6ec174f2a7db9ff469c128a3ed4be4933b55c9b26078396d728aa3bb52a72158303a999c646e3ffc68db67683d0d121c356e9c0cb98271bef275ce79d2e5396e608558c1a4f45d7253136af1d32155308710cf349dba4593be12428520844cc13866e9ab3c93acf70e91c26e95dd2d13bde472a5b206215130a8b027a726c9d11bc20405739e7975cb333ec16c96a2dde673955525c40946279fdbfc8dcf69f216d2048313fdcbea5326a7723d9960b61fd59567434b30878fc65e3d41436dad04c3a8edb26de2eb133c179204638acc77b75af4ee0c0946d73c274527e98e603c27cc686aca68bd01132845812a0a149b1804f864293fab0420f080a323c78e120200200ca7007a05002047c99f1de846090e04642007098e564000bef00500bef8e28b007c0100057cf1c517097874c30605f6d10d1b0c58407e9123877b0c2000ada391070100d03a1add28f130c017027000024a5e868c057c0180061820a11b351201464a81801152988490f91ff4d5da3dd119ba563bac6a7c890c1b902019e8734042a3b974d82029a33098af25f53a950d1251241c748d4480915018540e9af5261eb2dd241d0e1a14a6cf162bdd767c865a3e619cad78f2fdcf2a5a269e30ba095b4b272e7aca271c742770d035d2004638811a252d279d4f6e86166ec2aca1c64b64132c13e41bd1442670d4389838c0c825920d921a8900239630cd9bd2a4cec1d29ce499a16583a446ba4ae8f81c9430e58faab74e26fa67f208dd403726611a4df65dd166abe51e124918f43a3e49558a87e52092489854d2f8ec71a4070933d1aac9379e620b32f208a30915d5a498d7763b99a165e311c90d64dc28f91c4c44e008638a92abbefa1f94c88d30882d7d32c13f8898a530c2a48267cbd3f9215984d92e93634b3c0729f22bc2284faca4a9602411a64cb2fcdd5e174f71977183c6a41061f4a042a8caa3c28a10676891cc3884398dfa5229cd42ce89867d60071ac2d41eb4c8568e92bc60a410664b425818d7905e4f0e0921cc4dd8ceafa5332ac9c0b041622e181984b954e99eac934593443348c0b841a36a041e1e3a6c9078785cee1819110402460261123b9a9eb37b76d490216369eca8512e30020853503b2154ab49c98c1c34fe6036b9365a65331a3372b40c198c3a6c90143f18455cf2fd269c3ef74e1f4c41bdd6ff99c90793dce668a9783905698eeca100237a307fe9f0bc2fe3a9f135b2c6d72838920774a3461ac0081e1030720773db79bc1c251c748d841b18b183739f732c53ba43376ad4c15ce969cac73359ad3399a1554874d88004ed9021836d4082769c0e1b242503237430098ff3149a183ac4e86668a11b35d2d570121a374347d7b81c36487494d41cde06376ad4f81a061891830d921a6900237170d43649b457d96c83113818f4ea625466da36e91a7f829137183e4ef7895935216438e206731cabe87ae9c996f536184b545bf2f01cb74b618329965fa7bbe0e14d6e32b206f38dae8fb4f4642765bc8211351ce3adf172619e944d83498ace7e2eea1e4183f1ee5326c5ec949133981976a40ce51183113218bce52c6793f289b87c640ce8d0e3229fd4253118f7f53df6e73e0cc696afeff8a9835efe80c1a4355ec109f317cc29c57ac2e587c74dbd60723231dd2b75ceb145ee85912e98f742c713b1917ea9e582419ed2955e196ec19c4fc8ce7527abf7b560d80bd2b342280be6399977ea4713f5f5c382e949d2ae2c6c648a7a57301376bbc4097fb1824954eb3bb1c5c9a3d62a18f7b4f63b399cd73da9112a98b44254905bd92ecb3a3285bdab32a99ce0c4ca66b315f3c9f132e1b45446a460bc7c167e844e14cca1cf6edecad2f775281866b4826523187982a977b54e992537261546890e1b660b47d72838bac68d38c11c4b295596ea6b4bcc4d305ef026675cceed24d5986018d9613ef4258b638e2cc19ce6e7254e332f9b4909067992e94ab9e7932a79128c659f4f3d8e96b45123c1244327ed1e3b93438716e373a49482193a4842ac0b234730b6fe887b8225a52c094b0a2346305ee7b1ef687af17cb5b2e38c14c16841bbd3b509d6e1151154d919a5452d139089134686604a67224d295d91f52a1839c0681dc7871121988957b34dd250212f7e8e04c44810cc4d329de4c6c977102340307a9eda5d751959f9532a88911f9853f4543fb969971c8df8c0bce324dd8a39533a36484a0046c7c824d20b83d22769d2558cbdcc92082f4cb2a4857661f414f37d415fb4ecd3e308238642414417a6b2b8a3acb39334e1d2f904915c98ca429d7cb77bd1c964bf440922b830e65afc97270951297d1d256210b985b9af4aed8465824eb54ea220620b93fa9cdbfbc535412dcce5c1c3892f61211f4f4c841606e59df3442d798d11733c185a61a01b1d0081d5a31be77294bcc82c8cb36d692544eb74d095708044071844646192aed5974e26c75167aa1a374a4090a34462617e82369920df09c2c230a3969f53dedbb77a85f9fabc4baed4a56be80a8326986c15a1e7259fd20ae3c53949c9ef977e78c20ad33a39f8ab3013dbd4d3924915a62608f56517ba54184f05ebfaad0b2acca1d23dbd07f5290ce741d46735495d0e2553983d5774d6c9d1eb33e1195a341eb105444a61f63461eeb1094f343549610ed50a4d7a273d0a739890f92cbbf5bb9ca701860d921c55a23098ef8a683b1df29960284c957fc3d7ff4afa45416110f65953bdcbb2fdfb09933e4fa55eb39f7f164f9834e1c2ef2d77891dbf13a6d12feddc173dc5573961164bcbedf92d62e1a32bb209530711a22c899d1910d184d1bcf7e2c856acdf990963c8a72bd1be79fb1c4c18befff209b54d27aa7d0983699c18a589a7537c690973506fb17d7426a8582b6156cf6fd761dd9ed41d2526a53e1591494c0c0bb2152e57a5f0a45c166e84874806114998ce32d9b4570a8a8461cd46a53521523d2c2290c874e377cf8310451e61f0cb12f92907a9d9d90d8838c2ec77aaa72f9fe104954823cca4dcf1dc246933627182d0f3cb96e261f409b84e49974598d355b827134d13114518c3e4ff8456279208731899baa283cea9ef66b4e0901c41041126d1912fa2a487cf27e7100627da0919c2703a9ef9a517c2206493fe74f4480883b4f439228330874e8bd541dd8dfaac88204cb25354a892539db32d120893b68aef977544fe692280309a14d7dbacf8d7a72b1c10f98369d5538e1674f89349253f18f4c927d70793b03315e59eb6f393f860ce5fd154fe51eec1f0417dcaf478e3646f570f06137621339753ba7e8802913c9889237454b701892fa8146e66c3026130168a04027118c4b0f4f200c3120000000c28134762d17838a467ba1c1f140004774e2e4c302c28220a04029148200885c280301818060302a1500042622408d2a575921f0cb07cb6f03f3f3b27a1afc3f4563941e87c201edc1fb8a20bb45b484349d10bca47c02bd14638252abbe83b3103e6a61cb3746ed0fe92ed943df2c83fe6e5e1f337b1c3eb24964a0a72641ddfa0c444ec52c2d314462e6e2005df7094567bf830c43a00f65263e46c0c5e8062c41c6b883e7c9d84283ec8aa227badb7a40630fa47f489c26e8a2961dcc1c4c6049b00b6bcb894569cad2be8714f449a6098c916373bc6e66c628bfc95370aad701ca613803d43a0ce55be1aacd1b5026c3dbc6bd12a9a689da5be71b15098afac20e84af5f560ad1b66e42c3402ef9304906710a319c8beae7f57c0495a1ea1265c1714939c5b8b32329bf0213cbcaf1834d808c082742effc46a491436439764c1a44d92bb85728aa8942f359c12bcfee33c99ce6eba22752642efc8b56fdcb5020841af12147b68e832c97418bf050ebe89536853ad2d4430025187c3a6f4883da28409151f0100fa8608b8da348419744c2aeec8d5cf1ced0b02a01304c1916f40491e2df2382253b7cf943026cfa99667bdd595523f6e12a1d4832232b9ee2ba82786817ffec4f50a0f935880d4cf890330882e33423fdec52ee4b27a550a7883ed1f5af8172d814f19fb16f2e3afb299b88d9a540ff7293d535270c0a19fe2cb2f910700a1d08f79a5ea3136f1734e1772ca8eff8353d64d46204eb96c688c12a8a79399200f1c82384891aa198eabcd5124a87f1ab517fd83d40c33785225973f16806dfa1b7e9810b260ee2050a3f4cef7efe56d987080d561d106f983465901b731138e27cd6e884564249069984819a2bd4639158c30ef4914994d13e5885e2c84d63585b072d86188e109c20ba65033b25e7cc444825561c5e0e68a72cb19a66f9c8b7fac188fec98ab54890c9403d80a7e5a3abff993fdd98283e9388b5b71dcdebcea6478b8e675d248632da408c6d7e14a6a409db9bb361d3239809c8490ecf4485413e70c174e17004b26f2b94f97b511fc07a74fd2b2a5e4a7a437d52872d0c4714e1ca6b66ecd452dd2b8e680d03b19ed60e370aa48141c3653dbead71265c14b77653163c8328659ff262a9f22aa67e6df4f643d717db979c72be2d3256d477d3259dc53118b3802caae92d892f4a11195f82f15c562cfe4f738246cd86165fdd230a0d78e8b36160d94d762cc7ace334381a63bccda31ace879c9104ea538a930b8fb3b43d48b720665e3501939d6b87ac608ae6d30ecae89c762b31687b3a60319c3b002508c31a8c87047a2171147bbc818c02e84b76ba1ce428a5e6eae10e26aeb1c25f0239ebd8c29874c4c5961d61f2006658f8e7fcad9ebcb316f466a09c609f8eaecfd945866245f26ee68bc75c7d305bdd003e0445f5e2b5fc11ec57198a9f0e643cd704ec415b0c16a02d7aa5e68b299b3eb5c076a5a735751329a9c4df71e63cb40cc59ce9b4e2d171c51fd14c6e255d1b240be08cfef9df8198a6449fe73424cd7a4f1ac1e4af1e8761ce7ad23863efa3674fd084d76b47341969dab1e9e4c7d76b5da64c1ecbfa78c7df9a128341c595aba8d0248dda3ae7562c9f0e46c879076026b64ad5c1b038df1942ee122e6fcc352249e60a04cbe5678328d47ab0222f191b2e09b88234f44bba90f249ed769c7738a227596bf51e59b0e5c22c47b606f1541af5d806f2851a454911aa548920a9e28b688e8f46123dddad6420f82ac6189ec517c299cb837f120477818589f208718f698680721c2afceadc351ca568d7757b87082da49440c274fd4bc3f9c5ce906b201ccc1f119468918a5b72686d853c16760d088737d66f17044bc9e26b45174a968884eb17933d25738cae97b57732eba6fd1930ef6ea0d9d1d406409e0d53a0037a05abb6db869e5ef066f9f52871a9f82ca1c4a08587424613be02b9a8962d0a29ad9a4181f0dad25471993ba6fb5fe1e510a65d468099984abca98ab79cdb052062d24b88af1e75e8d3d7546ef7338997ad40f1138857101c79f21e16a46d1344487ba12873b8bf59c7439f71d38c7fa958a677f581137f0f3853c96ca2f4bd884878f084c7dd1aebeac1379ed8b72dde2b272180e58d55cc6def9dd31c0dea93e13f2365e3eb28229171f1a27a4ebb8943a62415356020b0e8572323127c4e32404e92a49db1a448eaa60d55ea984129611a6739e2f293e21bc6ffaf247aa44ad5d190f4aaf4442f532e25e5a5f3edd47ea3ebdb1e66e3ce41f18a87f8d13c53873573f2a84ef2754605b28d47b665e6c16b663e46a7c270dd1ced9865a8f7c2330083b3de24618f45be6ec00eacab0432163620a6100d83e884931ababd89b527401ea2ab6901b3b89132ca5ac428cdacd3d2d0e07a35a36d39874f89d886231eaac1dc3878002a7a16a969ce089ea89a442efded310f2c72ef8704cc9ab5b5b2f4a46c33a64a4667594a25b931c04c1b145d64029afde488620435823e7a59cb10fb1715a2db6326170fab86e6ac0317e50f5c4410635bc628f4105a550d7345b1a6611a24d8dd660dc60ac270c17b864a66f12379d3b2bd3809bef624f108b2db6b208ae551daa19a64776a18ac9fc5d06f852f7566acbe406caa8cb1a1872781fb097c91307dfd514b46788f085d1a02bc8ed7edda06a195a716495653825a5d878af88526330c6ed2bf21d6e0c3dca3810139c5174bb6d8f6450218928ec102fa6cc52eb2698e49e8445b7b18ed4115f7dd9b88baee7c4565bd1ea3f314fc40a6379e3ae6eaf7849237f49b5187d88048e6741bc237cfa624a76fb521b1f7be409dc962826ba69697cb4bbb16efba367f6b8508076231c0b1a86328fd6912fc62df2c4bf330851d3e1efb8184df3c328d1551023154d805e0887e256cf8663bc841ab9f2117cff5ffd62dcb79b8025329c4dda94b3a6f589fcad295f12919e9a9ee8426315f2dd94b420ed17a58568e3704d9fc7ed73c0b96cf67d872b98796056e4a47475b000f54f11cd1d46fdf977f0ecd9df0052cb335b16d20526c6df7d104951e2507817d6b1ab10cbf99a0381b77bb023a04f648c03fcae26db6413ea6529a7536792b368e659a13d613c5547d4f3e624e53aee097206e62af4df158c1750507a26b5b99c9469f7157c6f4e52625e0dfa1a03e6efc3a0818352f0be7f31f707760df018333fe3a685aa38922182d39dc0d502a521ceb87e8ce633f73dbd75a69203459554f418190de036dd16e81b7fb0e603b8f90861262a1e96fe806328fd3ced328c0a80ece8da701b3815e7409b0ce4d76075b3fa856cf1bf94b21bab9cc0f984348d2f64dddfdc87319f03faa4909ca4415248cc1762ae59761c766235bd01a0c9e42063a804cdffc26f6c41cc62709fde2aeb630b7ce16cf6f685de7e6d182457f03ef8a48a0a5f5e854fc5b8b9c2c9d5acbf9211b08382658c4cd903f5b50bb5338602f43c809bb4c2f9324aa8ae4695bec0c8a6fc4231c795475735835ae747a83873442d6197c339f5d44907bbfed136d8755e8c87e31e9eec1c04c6e3e75389e7ca66dbcb57823e89804294cf0540d34c60eb380b67a13cbd85129722e446081b21319c2d8b8a7768227610b5a534f5fb2f2f2bc9c5cab7809e3a1800f67397cf7cf30a7667fae14d64006dbaa8f116238e60b62cd98aeacf85c2966d3cc9d967f55d3be512b61186d6abf6920474b2b77d4418c18ffe18e247e65c008366e9849d683d193fb99d27a19e15b88e27a2db44289ac9d6cfb5a5ea84a12278cbd9fe55556cb7d88bb2c6ccf5e334cd94e286e464f38c4585a52a5b4cfee914a193b2b97b1a916e625847756af47227a9fc55f2a90bc3c7a4eb07ecd9175034e2047d0a1309e7da7063ae3a9c28a252f0265c4bdaa59786d42abeb616dd4cacfd062cb9813c969c42988a93f33992438ba5d18c3ac7db00707d876be44744cc88a478e2a29222fcceacbc91ea5058de8772b0736783f3afb61670e30206e106ad12d312928dab56d385613295828786bbac0998109e28b8639517fccdc9b485cf701dcc683ec9b1c41646d62b15ea850aede50ad6ab2840e62885bdf5e1176cb564dba5f54c601fa8c22efacb843b47f896430394c74ca9013e04da7c5bac95f95cfff3c6145347961903835741d93f9aa5c147acc419bd416abc0be3a0f2fecd3ab57032ed567dc891d755d3c9e6e8ec25d2af1ce74a60167ddf0e1bea5bfd841d6b32d05483852061da4cff4b9b692f5b69b4d5944146c8e54f4a8f54e27ea87c6e1e02e2ca4294b996442570cb6a9ebe5f619ab223c417f23b34347a04acae1e071680976500cf3f401476e7d4baab01dc0abb5caedd13a8b59bbbdf287917b5e5a92356afa4a67211c378d36ffbe5e4f33dd077d1d1a925ec8441fa760b4247ea417786abd336b17c6659b2a9380c9ba7ab14d81df4410a9327091e52fac67664ddf50dda06da467e53d8dda209f68ad4ca2d8dc177659552430c420af809c90a5a76518b970361ad26f27dad8aa6bb340df1c92b384fcc5a2e5187f2920328528915b68e13dbe2d5e0858bb077847105ace93e405d367e7425c4d2e8ffcdc2738eff2dec288dcf86c1f527351c55e58dc774ea1e3e8452012572965e9428896b17270c6c1608e92f9b4edee7e793bc992a36923caba3c8a35e411bfad89d2a973636a71be7511f2895d3a518658da922d9810663920c1c7a5ccc6d529202a17f88b7740712b87ffdab9151f374fa8018e7e01e9af07b797780b329c3765aad3ed02f1963ef90aaab150286095c6fd31838aa6bbabcce54e89c66dc1d8e97012108a70d73be7dd6a80c27eb2c6daa1b1a780c0943ace62c60661a77de932068306fe5ee2005fc6af3f012812112815705492e61813079398b9944014780bd0d600b145483b166c81047e9b702338e541e3c16b8770594ac5f8d6bfa530c647a84a6caf288b280a72980ba91cc941d360083445a552ab5d25f7edbe004b10e85c66b4bea3733d7258c46d549cd66ba206b806fe421953bc5267af1538dfe3f124643fcde43b726634b04b34500487557870d36a4408d025e5b4abcb22abfdcbe5f86af40a22992ac320f9c23ac18617058cce6e29ecf1cd65c95c56f70eb21511ca6ef4500c2462799ec0e0c9c720b29209495ddb344c47c9476b7924cc4882bbce637050805d690bd2ec0fb7db0c6f58c2c800f92069f955c7b9923f567c00052afa0dce8cbf90f4e39bbc1220c817c33e22791821710511ec300308382e6951d3e33671235a46db735d71e68b592e8f79870e41da2dd0d87b751d5cb17c027a58458eabb68d98d4ff24d64cb99f5f63d36a559a7e81968155eb852c6bda8515b13d4f534ebc00c1158470ecde7358cb5b0b9db262a3f3223c8c32e9dc82c721a489263fd48b1c1894879f5005313681d0e65a41105ef05df94e107fa9dbad576b52f6e28eb32125378371722f0eef7b1dc5c28b9dd757fbc3ba34e294db8117bdf736c4b8864ab8421f334488871d248190e0f6e47681efdf7c066b454b83cd2a2dc2a974d24dcc477e417b54b48a6f3b407409c4098dbb898460db9e6128837a26b68127156952182ca763a8514cb60320756edbe281c7026d1d0e72be68a5a35b3acb72f25f74e03e06fd0f838f40c97aef57eea8e86986d7d04e00470a279c15f89d74bbd485e6af8b4a62013e91323e35df2898b49138850f84e384887775f048d5a03410a66298442514360ed06ad1d26104ecfd85bdc0ac868802f2c08aa5e945c9394607493657e499a8a2e716fed9a1cd800943078385392c8e6949a30a218e03ef7b3d8a1603a6b75dc201b81bbe9d003c48971a38414e65b389f5f6acd76ea938c10a56a2b2cdc2c9b2cddc4b2261c221d32072ad389407eafc43c8e0343874cdb84daa8a8911c4072782fabc6b8001ada9debdd44dc1934a7dd157bff8bb21d85a4112960f482872aba7bbeefcf898d8ae2ba12159e3b298c9ac6d5e3698053f8969701db4b29ee08c2fc4dc0076977d6ce49e48f9fcdaa0e470b8a249af43d1d2f5e61d8bd8d7fb5929c493f18a537e462d9f93f34bea72bea549c751c0884d31080a972c0ffd0c57610ba740194730e0a36a5b715d1ad4765e235128c57cc4a0c04cb43070c346bca829bb151d1e3a6dd70c7b5ac103231d54b23ac1f0d973aeabf23190744f350b62a97224d26b1e9f951edc592a63949b02053a51ed897503dd04b10c7ec8cf2528bbcf80acb2ca2f5f006e5ca0166bb7ae5717b6a7d33c3d15b078bc88b2f7e6fa294410ff516ea6a728340d1b683289a40e82cc2dbdaf329dac31901744d1494604ee9695dadb73d86352fc48c8ae2ef444084824f4e2e68b1091fc052230128528eadb1a9c3bb0a9be92eaf13f0ff10ac43642fdb17bb3ddffa6ff632d9378382a026ac0dc74cda2970536112d6515be2778c081658d61080e3cd6b84f3696c903e6dc32285a7fe3c7c559fb145584d6c403b77c8902f64ded87427281804a14fcf60920e852131107d1a6d05794718d22cea83f0b91ff49d880e6af1966b479785e2c7e4dc2702a75778e01990208d97df62e6e5c5ba8221660698cf6aca9121219ed3a68e97801ad37e44f64c30b080a264a2fe7be5576c689e54a13e18129257de081b1e1885030bf450fb1b11105c3ab860c38672b88376f18abf03440c61bd1e3d83c363c706d761b966ae40845879384b447ab2f5a317fbaa64f14e608027bc6a1786dc784aa58a9f5c59fc9da3463ed45ac6ddcacdbf1f999ed09924fa60bd16dc447f6a73a9b58c6105ba59bef8aa74c90a38b8961ee8c7b55b262b1b841f36e3ec9b95d3d395853a815af2b22c436c676bc3147766bbaa4dbb487cbce8dd348e263bdbafaa86eb6007c23e1c921d9f3ba14c09907bff9f15c24ed4bbbee7f077bc01c1811f067f54905e9cd4787ab4fc92046a15c92c69891dc228ca2e017fe89bdc8db39df19bb3ac73b907b622a31c35676d6cc936559771252cb3f0d866d05271018d7dd8872842699ebfedc39d73685c132847cdc1a1f0298a2d1aa7336d6047e78c72f7699b17ee970988e3699b73640949bd6d739466b6db827137fc6b6a1a1124606cb939c3bfdf1aabba3e61c5dd8fe0af6b695bcf26afafabdc8849f565015908255ae018a28b9830340e8fb5c6261caf8a966785a816c00beac345fa45106dcbde934a9eff6921a5baac46aeb4e789d8b8df27e690e699ea21e89b3ec5c2bad694907a63850628484b4ffeacc7bcb8e49abdf57d8669075370a533b2c9528698ebc5b8809c17313181daa3f9476160a0923dd89e961f44b1eca37e1960b89151d72c5c27ad27e40395438e06d3142969da9885e2db82969044a4fcaf36eb511ad67e769e9efaef4c2f1e73524dfc4f40ca69d45215feaabd3e146f1b1b9490bb82054f45c59d5559a3d5f355a737274ab859e4bd9705daefea69f16aba5b8ff6b784a35248d147a9a73aa6b2d596412f4281e33ea4cfbcb0e1756f8aba2ac0d4e38ef4054ffb2987b4af6c049006d6c56c832f0df83230a40e361e2823831d9bb62afc30fe83da048fabbbcb098d0877e7f7cee9a4e6c58fba7d0ec1207b38247fe32ec405128900790d4b21bd1324b51000fd6ba5b10f3f74977c8d41810aba367ca67126080e9a6ff57d0424694d8d15d31b5d52e071d3b9e7fe13588b68d470d9e41d4eb9e8ca102b2ae04d6713028dcca268575b9dce1a1b5a82b758b5f7b242a6c183ff95889ad3a70729ccd205527d8d6e7dc15a78ba3ffadf328805873b600982de66863fea2c818afee38eb93dc196ba858c722f05f16ee4d5a9f2c3a82c3ade4e0d90f55256c6886a8d4469b39465b290480c9dff84308d33b73462732e1a26a820c3ce4da2174d83390057cbb564bb484a7b3915f083e6228ce0bd68ac002fab150fd537c208cb6c19fc6c8b6655491f189b089d0f384f141c2489fcfd135de47f8f3a22d470b521bb41a224c49646af7be3119e1599528fe218b4c2e8aa2532269338c4ccd2c13b2c5183722169f7ff042aa391cc19469ddc1426673a4fbe0d5fb4085601209094c3590d35220327733ccc7679b98df09595669dd96baae15e76a1829086d0f4d626a8d21ffa1e4e66f9dd5457a9a8acb11c22863957185b725a7c0a0638ab4c8996f4e61d8b8138ea655f44820958845a7181325d58f920e91adfd4c496cc890e4e79a882438824d441218e863014044f4398ca0884eeb430989354cbed44d47cfeba57428440e8ee7187e767e20cd45006599a74034a60fbb7f9bb914382c88621c32de689811b06319402bc6ed910b8553f2b82e0c19e176c0b889cc0be02abe1580021c7cc8f5e06d97d67e19afd27ce9dafc5974108e6823519d477e9e40eb6fe04b1155336b4c58acf385bccae1a3b4bb9316794ead079d9921e409f6a0f03be0fd7556a324d4b5bf32ac3e36ed098c2189dc0c336e4e75b16b9cd24f1ac15e3ac189222c4f33c98929270e8f3a726a5cc90f7a441256dd8144c7cf84e404decd7b34f930bd6f1c75548cc8bc05d70c315c4d7c3010137bbcc5cb575223a5614a53106339a8eaebb3da5af3def7c8650aa1b0733adaac5908953800a177e0d1484f0ac190489f6d18dcaf0b309418f424e5946c99c038d25327b4ee55e9d102fd891759e7b47ee3139692ef744ab47e9311ef7a0173cd3cdf5647d5b9f64f74c37987f9c7bcac4734394784c6ef943357c27931bc3ffb108a2029aa8fa84cd4ead333bcf80000bce644940beccedb1e0790f9a2c9659106e9d0caecd218d85c1dae492c14d5c75f35d86a0e232b8490d5592ee55df3f06f0af4cccdc2646f7c7540e4d93e8b17eca2c9b26e78cfa3a4b353960f5713c8e591665d3e42a97eacc6e4dce9c722987b90ab4d624f7e077ba990314124c1cdc5828b8c32f222350dc2e0e5220424ad1b8df4bfda86996e6895da75e8f72a9b522a2dc78344ecae2086616931b1ba5b69b29b78ba5ec8bdee9deb3592daaf0c93073d0b55e4a8f8e4f0e474bb9d14d6c63bc148f8e048205c67b7330427ebc8729262c6056fea993a3d21e016827e5c48fc7009ef2e8cc18885cb36ba1681aa9f9185d27671f25d6ef67e06a823fa361087c188a8dcf79da164f6ca72d727de49a99dd8162bb5e67de40131e8cd04b8303daf281f2c4868a351e9292ee37c8d39b8ca9973f7393f8973702266a3a454068d1e4ed33fb3e436f7f1aa4463010011882a04c472a33129b5c40b26d81b0cc44cd3dbf771854eb561857c8020ea0fe980e3a08f4265d83305381718c36e51d89dc2471744097f8caaf9ba482f2037b9cd1fc3d0002e1c1e30158c63d010ae3b0e9867b2b519c7df88485199be942ae446ac1ab66e4a198e58f0a35314f3906d392f00296f1bdd37a29bef422b40098e3286cd224c091048960096de275ddfe585714c1d14dc83c58be1fabef1569396e04384c9d22452be49e42f6ddb593b4c7605cb2ac50271054c5ca3bb7bb49e0f85b93efc8c5e182239cf8abbdab9928e7c665eef7e2a04ca593b62039f39310c45ca2669b37a747e3f8d39e1958030010f2080377ae7e01b3b9cc540183d16256d5cd9719f73808bb6a53fc3e4b074df6cdda45d62417760382e1adcd1ce6a8249e6e75ad4687c0246257375201c78cf5b40424677126755caffb5dac0e284f85db010a380ce9334dd0f54b4eb7803029fa1cf087de7f8c67abaaf91d846cc5834bcdc82d2c797e0964", "0x3a65787472696e7369635f696e646578": "0x00000000", - "0x3a6772616e6470615f617574686f726974696573": "0x010888dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee0100000000000000d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690100000000000000", - "0x3db7a24cfdc9de785974746c14a99df94e7b9012096b41c4eb3aaf947f6ea429": "0x0300", + "0x3db7a24cfdc9de785974746c14a99df94e7b9012096b41c4eb3aaf947f6ea429": "0x0400", "0x3f1467a096bcd71a5b6a0c8155e20810308ce9615de0775a82f8a94dc3d285a1": "0x01", "0x3f1467a096bcd71a5b6a0c8155e208103f2edf3bdf381debe331ab7446addfdc": "0x000064a7b3b6e00d0000000000000000", "0x3f1467a096bcd71a5b6a0c8155e208104e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x426e15054d267946093858132eb537f105fe52c2045750c3c492ccdcf62e2b9c": "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d", - "0x426e15054d267946093858132eb537f14e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x426e15054d267946093858132eb537f195999521c6c89cd80b677e53ce20f98c": "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d", + "0x426e15054d267946093858132eb537f14e7b9012096b41c4eb3aaf947f6ea429": "0x0200", "0x426e15054d267946093858132eb537f1a47a9ff5cd5bf4d848a80a0b1a947dc3": "0x00000000000000000000000000000000", - "0x426e15054d267946093858132eb537f1ba7fb8745735dc3be2a2c61a72c39e78": "0x181cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc208eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a4890b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27de659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e", - "0x426e15054d267946093858132eb537f1d0b4a3f7631f0c0e761898fe198211de": "0xe7030000", - "0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429": "0x0900", + "0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429": "0x0f00", "0x4a83351006488ef6369cb758091f878c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x4ff3897794d496d78686afcfe760a1144e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x4db06ba1ca6f18b1edb06ff082d244094e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0x4dcb50595177a3177648411a42aca0f54e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x4ff3897794d496d78686afcfe760a1144e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0x587e3b7cc2ee9dc4ab69e46c4d4c073d4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0x5c0d1176a568c1f92944340dbfed9e9c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0x5c0d1176a568c1f92944340dbfed9e9c530ebca703c85910e7164cb7d1c9e47b": "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d", - "0x5e8a19e3cd1b7c148b33880c479c02814e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x5e8a19e3cd1b7c148b33880c479c02814e7b9012096b41c4eb3aaf947f6ea429": "0x0100", "0x5f27b51b5ec208ee9cb25b55d8728243308ce9615de0775a82f8a94dc3d285a1": "0x01", "0x5f27b51b5ec208ee9cb25b55d87282434e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0x5f3e4907f716ac89b6347d15ececedca0b6a45321efae92aea15e0740ec7afe7": "0x00000000", "0x5f3e4907f716ac89b6347d15ececedca138e71612491192d68deab7e6f563fe1": "0x02000000", "0x5f3e4907f716ac89b6347d15ececedca28dccb559b95c40168a1b2696581b5a7": "0x00000000000000000000000000000000", - "0x5f3e4907f716ac89b6347d15ececedca308ce9615de0775a82f8a94dc3d285a1": "0x06", - "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe700e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", - "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe70e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d", - "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc44f9aea1afa791265fae359272badc1cf8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e13000064a7b3b6e00d13000064a7b3b6e00d0000", - "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc4de1e86a9a8c739864cf3cc5ec2bea59fd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f13000064a7b3b6e00d13000064a7b3b6e00d0000", - "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a000000000e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x13d4fe63a7b3b6e00d13d4fe63a7b3b6e00d00", - "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a00000000e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x13d4fe63a7b3b6e00d13d4fe63a7b3b6e00d00", + "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe700e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", + "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe70e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f", + "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc432a5935f6edc617ae178fef9eb1e211fbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f13000064a7b3b6e00d13000064a7b3b6e00d0000", + "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc46f2e33376834a63c86a195bcf685aebbfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e13000064a7b3b6e00d13000064a7b3b6e00d0000", "0x5f3e4907f716ac89b6347d15ececedca487df464e44a534ba6b0cbb32407b587": "0x0000000000", - "0x5f3e4907f716ac89b6347d15ececedca4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x5f3e4907f716ac89b6347d15ececedca4e7b9012096b41c4eb3aaf947f6ea429": "0x0e00", "0x5f3e4907f716ac89b6347d15ececedca5579297f4dfb9609e7e4c2ebab9ce40a": "0x00", "0x5f3e4907f716ac89b6347d15ececedca666fdcbb473985b3ac933d13f4acff8d": "0x00000000000000000000000000000000", "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a000000000e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x0000", "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a00000000e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x0000", "0x5f3e4907f716ac89b6347d15ececedca6ddc7809c6da9bb6093ee22e0fda4ba8": "0x02000000", + "0x5f3e4907f716ac89b6347d15ececedca7493ea190d0af47acc70e25428f8b1a3b4def25cfda6ef3a000000000e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x1336fe63a7b3b6e00d1336fe63a7b3b6e00d0000000000000000", + "0x5f3e4907f716ac89b6347d15ececedca7493ea190d0af47acc70e25428f8b1a3b4def25cfda6ef3a00000000e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x1336fe63a7b3b6e00d1336fe63a7b3b6e00d0000000000000000", "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e169030e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x0000", "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e16903e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x0000", - "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a000000000e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x13d4fe63a7b3b6e00d13d4fe63a7b3b6e00d00", - "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a00000000e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x13d4fe63a7b3b6e00d13d4fe63a7b3b6e00d00", "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade980e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x00", "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade98e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x00", - "0x5f3e4907f716ac89b6347d15ececedcaa141c4fe67c2d11f4a10c6aca7a79a04b4def25cfda6ef3a00000000": "0xa8fdc74e676dc11b0000000000000000", + "0x5f3e4907f716ac89b6347d15ececedcaa141c4fe67c2d11f4a10c6aca7a79a04b4def25cfda6ef3a00000000": "0x6cfcc74e676dc11b0000000000000000", "0x5f3e4907f716ac89b6347d15ececedcaad811cd65a470ddc5f1d628ff0550982b4def25cfda6ef3a00000000": "0x00000000", "0x5f3e4907f716ac89b6347d15ececedcab49a2738eeb30896aacb8b3fb46471bd": "0x02000000", "0x5f3e4907f716ac89b6347d15ececedcac0d39ff577af2cc6b67ac3641fa9c4e7": "0x01000000", @@ -114,25 +119,26 @@ "0x5f3e4907f716ac89b6347d15ececedcaea07de2b8f010516dca3f7ef52f7ac5a": "0x040000000000000000", "0x5f3e4907f716ac89b6347d15ececedcaed441ceb81326c56263efbb60c95c2e4": "0x00000000000000000000000000000000", "0x5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3": "0x00", - "0x5f9cc45b7a00c5899361e1c6099678dc4e7b9012096b41c4eb3aaf947f6ea429": "0x0400", + "0x5f3e4907f716ac89b6347d15ececedcafab86d26e629e39b4903db94786fac74": "0xffffffffffffffff0000000000000000", + "0x5f9cc45b7a00c5899361e1c6099678dc4e7b9012096b41c4eb3aaf947f6ea429": "0x0500", + "0x5f9cc45b7a00c5899361e1c6099678dc5e0621c4869aa60c02be9adcc98a0d1d": "0x0888dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee0100000000000000d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690100000000000000", "0x5f9cc45b7a00c5899361e1c6099678dc8a2d09463effcc78a22d75b9cb87dffc": "0x0000000000000000", "0x5f9cc45b7a00c5899361e1c6099678dcd47cb8f5328af743ddfb361e7180e7fcbb1bdbcacd6ac9340000000000000000": "0x00000000", "0x6441fb391296410bd2f14381bb7494334e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0x6786c4cec8d628b6598d7a70ace7acd44e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x682a59d51ab9e48a8c8cc418ff9708d24e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x6c63e84bfc5a0d62149aaab70897685c4ba24bcd9ac206424105f255ae95a355": "0xb104000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x6c63e84bfc5a0d62149aaab70897685c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x682a59d51ab9e48a8c8cc418ff9708d24e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0x682a59d51ab9e48a8c8cc418ff9708d2d34371a193a751eea5883e9553457b2ef71f22775221b1945fe6cfa3c6550c7c09000000": "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000", "0x7474449cca95dc5d0c00e71735a6d17d4e7b9012096b41c4eb3aaf947f6ea429": "0x0100", "0x74dd702da46f77d7acf77f5a48d4af7d4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x74dd702da46f77d7acf77f5a48d4af7d62556a85fcb7c61b2c6c750924846b150e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e01be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f00b304f91831830500622780fd38770500", - "0x74dd702da46f77d7acf77f5a48d4af7d62556a85fcb7c61b2c6c750924846b15e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f0001fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860eb304f91831830500622780fd38770500", + "0x74dd702da46f77d7acf77f5a48d4af7d62556a85fcb7c61b2c6c750924846b150e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e01be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f00a5b42a473a9e060035c953d5088e0600", + "0x74dd702da46f77d7acf77f5a48d4af7d62556a85fcb7c61b2c6c750924846b15e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f0001fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860ea5b42a473a9e060035c953d5088e0600", "0x74dd702da46f77d7acf77f5a48d4af7d7a6dc62e324093ba1331bf49fdb2f24a": "0x02000000", - "0x74dd702da46f77d7acf77f5a48d4af7de5c03730c8f59f00941607850b6633d81fad1867486365c5b304f91831830500": "0x01be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f01fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", + "0x74dd702da46f77d7acf77f5a48d4af7de5c03730c8f59f00941607850b6633d8440de572cbc49d04a5b42a473a9e0600": "0x01be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f01fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", "0x7a6d38deaa01cb6e76ee69889f1696272be9a4e88368a2188d2b9100a9f3cd43": "0x00407a10f35a00000000000000000000", "0x7a6d38deaa01cb6e76ee69889f16962730256ea2c545a3e5e3744665ffb2ed28": "0x00020000", "0x7a6d38deaa01cb6e76ee69889f1696273f0d64e1907361c689834a9c1cb0fbe0": "0x20000000", "0x7a6d38deaa01cb6e76ee69889f16962749d67997de33812a1cc37310f765b82e": "0x0080c6a47e8d03000000000000000000", - "0x7a6d38deaa01cb6e76ee69889f1696274e7b9012096b41c4eb3aaf947f6ea429": "0x0300", + "0x7a6d38deaa01cb6e76ee69889f1696274e7b9012096b41c4eb3aaf947f6ea429": "0x0800", "0x7a6d38deaa01cb6e76ee69889f169627ba93302f3b868c50785e6ade45c6a1d8": "0x10000000", "0x7cda3cfa86b349fdafce4979b197118f4e7b9012096b41c4eb3aaf947f6ea429": "0x0400", "0x7cda3cfa86b349fdafce4979b197118f71cd3068e6118bfb392b798317f63a8910c174c55fd2c633e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e": "0x04e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e000064a7b3b6e00d000000000000000000000000000000000000000000000000", @@ -142,40 +148,63 @@ "0x7cda3cfa86b349fdafce4979b197118f71cd3068e6118bfb392b798317f63a89a647e755c30521d38eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0x048eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48000064a7b3b6e00d000000000000000000000000000000000000000000000000", "0x7cda3cfa86b349fdafce4979b197118f71cd3068e6118bfb392b798317f63a89dd4e3f25f5378a6d90b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22": "0x0490b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22000064a7b3b6e00d000000000000000000000000000000000000000000000000", "0x7cda3cfa86b349fdafce4979b197118fba7fb8745735dc3be2a2c61a72c39e78": "0x181cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c000064a7b3b6e00d000000000000000000000000000000000000000000000000306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20000064a7b3b6e00d0000000000000000000000000000000000000000000000008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48000064a7b3b6e00d00000000000000000000000000000000000000000000000090b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22000064a7b3b6e00d000000000000000000000000000000000000000000000000d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d000064a7b3b6e00d000000000000000000000000000000000000000000000000e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e000064a7b3b6e00d000000000000000000000000000000000000000000000000", + "0x837adc8a2ac1180ee049d9a9f6a5a6c74e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x8671567f6bbc0021f6f23105f33002a84e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0x89d139e01a5eb2256f222e5fc5dbe6b34e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0x913b40454eb582a66ab74c86f6137db94e7b9012096b41c4eb3aaf947f6ea429": "0x0400", + "0x928fa8b8d92aa31f47ed74f188a43f704e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0xa0eb495036d368196a2b6c51d9d788814e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xa2250336d7088646c66de755c066e1294e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0xa2ce73642c549ae79c14f0a671cf45f94e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xa37f719efab16103103a0c8c2c784ce14e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xa42f90c8b47838c3a5332d85ee9aa5c34e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0xa37f719efab16103103a0c8c2c784ce14e7b9012096b41c4eb3aaf947f6ea429": "0x0400", + "0xa42f90c8b47838c3a5332d85ee9aa5c34e7b9012096b41c4eb3aaf947f6ea429": "0x0200", "0xa8c65209d47ee80f56b0011e8fd91f504e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xac42112d5338b6d943fa7c0ea6729c5b4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xac42112d5338b6d943fa7c0ea6729c5b5281a136c39eafd1d9a43e904579daed00000000": "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d", + "0xac42112d5338b6d943fa7c0ea6729c5b5281a136c39eafd1d9a43e904579daed01000000": "0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", "0xaebd463ed9925c488c112434d61debc04e7b9012096b41c4eb3aaf947f6ea429": "0x0400", - "0xaebd463ed9925c488c112434d61debc0ba7fb8745735dc3be2a2c61a72c39e78": "0x18d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a4890b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c", + "0xaebd463ed9925c488c112434d61debc0ba7fb8745735dc3be2a2c61a72c39e78": "0x181cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc208eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a4890b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27de659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e", + "0xb52606da80d02ab374428369a5f246f14e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xb8753e9383841da95f7b8871e5de32694e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0xbd2a529379475088d3e29a918cd478724e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc632a5935f6edc617ae178fef9eb1e211fbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x047374616b696e6720000064a7b3b6e00d000000000000000002", "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc66f2e33376834a63c86a195bcf685aebbfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x047374616b696e6720000064a7b3b6e00d000000000000000002", - "0xc2261276cc9d1f8598ea4b6a74b15c2f308ce9615de0775a82f8a94dc3d285a1": "0x01", - "0xc2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x0040fa7f398074858a02000000000000", - "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb30e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0xd17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae698eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a488eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a488eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", - "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb3e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eed43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d", + "0xc2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x024082111592a2351e02000000000000", + "0xc2eac8c3d5c3234dc0a1a2cbcf2683444e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xc2eac8c3d5c3234dc0a1a2cbcf26834495875cb80ebaf9f918457db6a86ac6ad": "0x0000000000000000", + "0xc2eac8c3d5c3234dc0a1a2cbcf268344a60b3b950949d0170fe164cd975925c0": "0x00000000", + "0xc2eac8c3d5c3234dc0a1a2cbcf268344c946330e6fb55244ecf7951cd7f85c4c": "0x0000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb30e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0xd17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae698eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a488eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a488eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a488eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a480390084fdbf27d2b79d26a4f13f0ccd982cb755a661969143c37cbc49ef5b91f27", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb3e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eed43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d020a1091341fe5664bfa1782d5e04779689068c916b04cb365ec3153755684d9a1", "0xcec5070d609dd3497f72bde07fc96ba04e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19500b42ace3b5fab73c6265656684020a1091341fe5664bfa1782d5e04779689068c916b04cb365ec3153755684d9a1": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f", "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19500e3a507571a62417696d6f6e808eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19500f0350b468be487e6d69786e80d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195049379ceb4b3a90d86d69786e808eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19505905fe216cc5924c6772616e80d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae69": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195066b8d48da86b869b6261626580d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f", "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509d4a4cfe1c2ef0b961756469808eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950c7e637254b9ea61962656566840390084fdbf27d2b79d26a4f13f0ccd982cb755a661969143c37cbc49ef5b91f27": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950c9b0c13125732d276175646980d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f", "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950d62c40514b41f31962616265808eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950ed43a85541921049696d6f6e80d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f", "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950f5537bdb2a1f626b6772616e8088dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f", "0xcec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903": "0x08be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25ffe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", - "0xcec5070d609dd3497f72bde07fc96ba0e0cdd062e6eaf24295ad4ccfc41d4609": "0x08be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eed43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860ed17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae698eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a488eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a488eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", + "0xcec5070d609dd3497f72bde07fc96ba0e0cdd062e6eaf24295ad4ccfc41d4609": "0x08be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eed43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d020a1091341fe5664bfa1782d5e04779689068c916b04cb365ec3153755684d9a1fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860ed17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae698eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a488eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a488eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a488eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a480390084fdbf27d2b79d26a4f13f0ccd982cb755a661969143c37cbc49ef5b91f27", "0xd57bce545fb382c34570e5dfbf338f5e4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xd5c41b52a371aa36c9254ce34324f2a54e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xd5c41b52a371aa36c9254ce34324f2a54e7b9012096b41c4eb3aaf947f6ea429": "0x0100", "0xd5e1a2fa16732ce6906189438c0a82c64e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xd77451b0cdabc3fb7fe20813c2e9ad4a4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0xd8f314b7f4e6b095f0f8ee4656a448254e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0xda7d4185f8093e80caceb64da45219e30c98535b82c72faf3c64974094af4643": "0x0100000000000000020000009394784c9135e2e98a0c095ce594f572650285069b0464ce74c83befcbc17b71", + "0xda7d4185f8093e80caceb64da45219e34e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xda7d4185f8093e80caceb64da45219e3c52aa943bf0908860a3eea0fad707cdc": "0x0000000000000000020000009394784c9135e2e98a0c095ce594f572650285069b0464ce74c83befcbc17b71", + "0xe601a78caffde57e00752be8864bc48e4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xe6ff095c8bf38992ef748b1037a308af4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xe8d49389c2e23e152fdd6364daadd2cc4e7b9012096b41c4eb3aaf947f6ea429": "0x0100", "0xed25f63942de25ac5253ba64b5eb64d14e7b9012096b41c4eb3aaf947f6ea429": "0x0400", - "0xed25f63942de25ac5253ba64b5eb64d1ba7fb8745735dc3be2a2c61a72c39e78": "0x18d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a4890b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c", + "0xed25f63942de25ac5253ba64b5eb64d1ba7fb8745735dc3be2a2c61a72c39e78": "0x181cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc208eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a4890b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27de659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e", "0xede8e4fdc3c8b556f0ce2f77fc2575e34e7b9012096b41c4eb3aaf947f6ea429": "0x0100", "0xedfb05b766f199ce00df85317e33050e4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0xf0c365c3cf59d671eb72da0e7a4113c44e7b9012096b41c4eb3aaf947f6ea429": "0x0000", @@ -183,6 +212,7 @@ "0xf2794c22e353e9a839f12faab03a911b7f17cdfbfa73331856cca0acddd7842e": "0x00000000", "0xf2794c22e353e9a839f12faab03a911bbdcb0c5143a8617ed38ae3810dd45bc6": "0x00000000", "0xf2794c22e353e9a839f12faab03a911be2f6cb0456905c189bcb0458f9440f13": "0x00000000", + "0xf35b44951b86069d9273a961f1e3fbeb4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0xf5a4963e4efb097983d7a693b0c1ee454e7b9012096b41c4eb3aaf947f6ea429": "0x0100", "0xfbc9f53700f75f681f234e70fb7241eb4e7b9012096b41c4eb3aaf947f6ea429": "0x0000" }, diff --git a/substrate/zombienet/0001-basic-warp-sync/generate-warp-sync-database.toml b/substrate/zombienet/0001-basic-warp-sync/generate-warp-sync-database.toml index ca78ee290c4..39f3b0fb3bd 100644 --- a/substrate/zombienet/0001-basic-warp-sync/generate-warp-sync-database.toml +++ b/substrate/zombienet/0001-basic-warp-sync/generate-warp-sync-database.toml @@ -1,16 +1,19 @@ # this file is not intended to be executed in CI stage [relaychain] -default_image = "docker.io/parity/substrate:latest" +default_image = "docker.io/paritypr/substrate:latest" default_command = "substrate" # refer to ./README.md for more details on how to create snapshot and spec -chain = "gen-db" +chain = "local" chain_spec_path = "chain-spec.json" [[relaychain.nodes]] name = "alice" validator = true + # TODO: Workaround for https://github.com/paritytech/polkadot-sdk/issues/2568 + # After the issue is fixed, we can remove this. + args = ["--state-pruning archive --blocks-pruning archive"] [[relaychain.nodes]] name = "bob" diff --git a/substrate/zombienet/0001-basic-warp-sync/test-warp-sync.toml b/substrate/zombienet/0001-basic-warp-sync/test-warp-sync.toml index 773f5020bc3..f4586ba69d0 100644 --- a/substrate/zombienet/0001-basic-warp-sync/test-warp-sync.toml +++ b/substrate/zombienet/0001-basic-warp-sync/test-warp-sync.toml @@ -5,24 +5,24 @@ enable_tracing = false default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" default_command = "substrate" -chain = "gen-db" +chain = "local" chain_spec_path = "chain-spec.json" [[relaychain.nodes]] name = "alice" validator = false - db_snapshot="https://storage.googleapis.com/zombienet-db-snaps/substrate/0001-basic-warp-sync/chains-a233bbacff650aac6bcb56b4e4ef7db7dc143cfb.tgz" + db_snapshot="{{DB_SNAPSHOT}}" [[relaychain.nodes]] name = "bob" validator = false - db_snapshot="https://storage.googleapis.com/zombienet-db-snaps/substrate/0001-basic-warp-sync/chains-a233bbacff650aac6bcb56b4e4ef7db7dc143cfb.tgz" + db_snapshot="{{DB_SNAPSHOT}}" #we need at least 3 nodes for warp sync [[relaychain.nodes]] name = "charlie" validator = false - db_snapshot="https://storage.googleapis.com/zombienet-db-snaps/substrate/0001-basic-warp-sync/chains-a233bbacff650aac6bcb56b4e4ef7db7dc143cfb.tgz" + db_snapshot="{{DB_SNAPSHOT}}" [[relaychain.nodes]] name = "dave" diff --git a/substrate/zombienet/0001-basic-warp-sync/test-warp-sync.zndsl b/substrate/zombienet/0001-basic-warp-sync/test-warp-sync.zndsl index dc84804b70b..bafdb7d72bb 100644 --- a/substrate/zombienet/0001-basic-warp-sync/test-warp-sync.zndsl +++ b/substrate/zombienet/0001-basic-warp-sync/test-warp-sync.zndsl @@ -13,18 +13,16 @@ charlie: reports peers count is at least 3 within 60 seconds dave: reports peers count is at least 3 within 60 seconds -# db snapshot has 12133 blocks -dave: reports block height is at least 1 within 60 seconds -dave: reports block height is at least 12132 within 60 seconds -dave: reports block height is at least 12133 within 60 seconds +# db snapshot has {{DB_BLOCK_HEIGHT}} blocks +alice: reports block height is at least {{DB_BLOCK_HEIGHT}} within 60 seconds +bob: reports block height is at least {{DB_BLOCK_HEIGHT}} within 60 seconds +charlie: reports block height is at least {{DB_BLOCK_HEIGHT}} within 60 seconds -alice: reports block height is at least 12133 within 60 seconds -bob: reports block height is at least 12133 within 60 seconds -charlie: reports block height is at least 12133 within 60 seconds +dave: reports block height is at least 1 within 60 seconds +dave: reports block height is at least {{DB_BLOCK_HEIGHT}} within 60 seconds dave: log line matches "Warp sync is complete" within 60 seconds -# workaround for: https://github.com/paritytech/zombienet/issues/580 -dave: count of log lines containing "Block history download is complete" is 1 within 10 seconds +dave: log line matches "Block history download is complete" within 10 seconds dave: count of log lines containing "error" is 0 within 10 seconds dave: count of log lines containing "verification failed" is 0 within 10 seconds diff --git a/substrate/zombienet/0002-validators-warp-sync/chain-spec.json b/substrate/zombienet/0002-validators-warp-sync/chain-spec.json deleted file mode 100644 index 8c09e7c7b03..00000000000 --- a/substrate/zombienet/0002-validators-warp-sync/chain-spec.json +++ /dev/null @@ -1,192 +0,0 @@ -{ - "name": "Local Testnet", - "id": "local_testnet", - "chainType": "Local", - "bootNodes": [ - "/ip4/127.0.0.1/tcp/30333/p2p/12D3KooWFvMbTsNZ8peGS8dbnRvNDBspstupzwYC9NVwbzGCLtDt" - ], - "telemetryEndpoints": null, - "protocolId": null, - "properties": null, - "forkBlocks": null, - "badBlocks": null, - "lightSyncState": null, - "codeSubstitutes": {}, - "genesis": { - "raw": { - "top": { - "0x074b65e262fcd5bd9c785caf7f42e00a4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x0e7b504e5df47062be129a8958a7a1271689c014e0a5b9a8ca8aafdff753c41c": "0xe8030000000000000000000000000000", - "0x0e7b504e5df47062be129a8958a7a1274e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x0e7b504e5df47062be129a8958a7a127ecf0c2087a354172a7b5a9a7735fe2ff": "0xc0890100", - "0x0e7b504e5df47062be129a8958a7a127fb88d072992a4a52ce055d9181748f1f": "0x0a000000000000000000000000000000", - "0x0f6738a0ee80c8e74cd2c7417c1e25564e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x1809d78346727a0ef58c0fa03bafa3234e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x1a736d37504c2e3fb73dad160c55b2914e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x1cb6f36e027abb2091cfb5110ab5087f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x1cb6f36e027abb2091cfb5110ab5087f5e0621c4869aa60c02be9adcc98a0d1d": "0x08d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d01000000000000008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a480100000000000000", - "0x1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4": "0x00000000", - "0x1cb6f36e027abb2091cfb5110ab5087faacf00b9b41fda7a9268821c2a2b3e4c": "0x08d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d01000000000000008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a480100000000000000", - "0x1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef": "0x0100000000000000040000000000000001", - "0x2099d7f109d6e535fb000bba623fd4404c014e6bf8b8c2c011e7290b85696bb3": "0x08d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", - "0x2099d7f109d6e535fb000bba623fd4404e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x2099d7f109d6e535fb000bba623fd4409f99a2ce711f3a31b2fc05604c93f179": "0x08d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", - "0x267ada16405529c2f7ef2727d71edbde4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x26aa394eea5630e07c48ae0c9558cef734abf5cb34d6244378cddbf18e849d96": "0x00000000071c0d84db3a00", - "0x26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710": "0x01", - "0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545", - "0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746b4def25cfda6ef3a00000000": "0x4545454545454545454545454545454545454545454545454545454545454545", - "0x26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439": "0x01", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9007cbc1270b5b091758f9c42f5915b3e8ac59e11963af19174d0b94d5d78041c233f55d2e19324665bafdfb62925af2d": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da923a05cabf6d3bde7ca3ef0d11596b5611cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da932a5935f6edc617ae178fef9eb1e211fbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x000000000300000001000000000000000000a0dec5adc935360000000000000000000000000000000000000000000000000064a7b3b6e00d0000000000000000000064a7b3b6e00d0000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da94f9aea1afa791265fae359272badc1cf8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95ecffd7b6c0f78751baa9d281e0bfa3a6d6f646c70792f74727372790000000000000000000000000000000000000000": "0x0000000000000000010000000000000000407a10f35a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da96f2e33376834a63c86a195bcf685aebbfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x000000000300000001000000000000000000a0dec5adc935360000000000000000000000000000000000000000000000000064a7b3b6e00d0000000000000000000064a7b3b6e00d0000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da98578796c363c105114787203e4d93ca6101191192fc877c24d725b337120fa3edc63d227bbc92705db1e2cb65f56981a": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b0edae20838083f2cde1c4080db8cf8090b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b321d16960ce1d9190b61e2421cc60131e07379407fecc4b89eb7dbd287c2c781cfb1907a96947a3eb18e4f8e7198625": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9de1e86a9a8c739864cf3cc5ec2bea59fd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9e5e802737cce3a54b0bc9e3d3e6be26e306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9edeaa42c2163f68084a988529a0e2ec5e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9f3f619a1c2956443880db9cc9a13d058e860f1b1c7227f7c22602f53f15af80747814dffd839719731ee3bba6edc126c": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0x3104106e6f6465", - "0x2aeddc77fe58c98d50bd37f1b90840f94e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x2b06af9719ac64d755623cda8ddd9b944e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x2b06af9719ac64d755623cda8ddd9b949f99a2ce711f3a31b2fc05604c93f179": "0x08d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", - "0x2c5de123c468aef7f3ac2ab3a76f87ce4e7b9012096b41c4eb3aaf947f6ea429": "0x0400", - "0x2f85f1e1378cb2d7b83adbaf0b5869c24e7b9012096b41c4eb3aaf947f6ea429": "0x0100", - "0x2f85f1e1378cb2d7b83adbaf0b5869c298ef7dc060436e4ed803af07632b89b65153cb1f00942ff401000000": "0x601de9615313b00e8cea3ef84e79e50b2fb70e2c8a47cff478b9fe8b3fa8f2db02000000", - "0x2f85f1e1378cb2d7b83adbaf0b5869c298ef7dc060436e4ed803af07632b89b6b4def25cfda6ef3a00000000": "0x601de9615313b00e8cea3ef84e79e50b2fb70e2c8a47cff478b9fe8b3fa8f2db02000000", - "0x2f85f1e1378cb2d7b83adbaf0b5869c2ff3ae12770bea2e48d9bde7385e7a25f": "0x0000000002000000", - "0x3a2d6c9353500637d8f8e3e0fa0bb1c54e7b9012096b41c4eb3aaf947f6ea429": "0x0400", - "0x3a2d6c9353500637d8f8e3e0fa0bb1c5ba7fb8745735dc3be2a2c61a72c39e78": "0x00", - "0x3a636f6465": "0x52bc537646db8e0528b52ffd0058dc2705bea5c66d15541040ac6c3ae971bcf5f1040221a8d1f8b7c17e61bf21cce87411480b10bd8daa5e3c2b65f8c4aa364e5a8ddf27c0313827d06a2d6334e074db9ca7d876ac8d052862b9984530f4d340bda4edddd6e4de5ba624536717e1139e14df2d875c7f7086dc3fa3d398b64f50fffc58fbf4fb73ffb0d39cc2b86761cfe6d3073b9c1fcee7fe611b7f4875f9a7d8cfe208fdf493f4d3b07d9a73ad05c8cf39e5c4dde679c3c8391b9ceec4fd78c824d218e4cfb79cb8be9cb301eace3b7f8a274c182edb72e2e83349855e7e4a2a795d7e27998b94f46d92b42eb543afcbcf5f5c9e5bf2d52dfd9b2f93dc33262710e3fc79b943e09fe2d00f8dd7edc4350b92a692a2facb7adddffddd3d89e9babb7b8e0b9d61050b2b4ddf3efdfdb3f629e9edfe9c18c4f8715bebf42d6f6e3ff74be1b9c0c8b9187cb89c83618e5bce6ebf90cb3918729745244063391ee9710cdb87bfbbbffc6047f275725e904518e7f53cec48efa788c4bd67d104a4eb81534cd2bd67cbeebb075b4c32deee59a43da30fd2d0c979410f3db2fb2972cfcad89d0f822c7ab644bade3b59d6eeddc9925eef8f34e8645980eb0fb2f8d9b2cafddec99273d7bf234bee5995292c3051e1fa97dcb31285eb5f76255cff23de917c3f72c8afaeaeac6ef74e96462e7d70864ed2ef48be2c9ef05d8f1cfa6e67cb79dd0ecdabababab5b225d7f4a72cfa6a53d9bcf739903246f521840fe916b813c65e41c0c50b7b60fe76078bafc61ff4c1bbfac7d3887b3bafc37979f73580490ef389f9f5920c8edc3f3cee7075fdc3e4cdba79f1f9c200db97df896f532c31e008355cff83a7dff7e1791b4e5097b400cb89ef19def24533b4524b567fe2c96c02292fe233d5900f2edfed96d8f34d29c2680f3270934e67054b7a4b7bfceaf95fd879b568e777e395e3aa7139fded3ff484f77779fef3ebbbfdeb6364afae9f74c32bf6dd9ef3de714c839e5df7e908f8c208b30f2fbb388847f8a2354c1e170305cb6dcb3b2de7eb0436e9ff9edc33deb3fd24ed29ef50f602cc7dbfda0ac7df8f683331cdba73fd63efefdb2f699b79f45244e492a38b708a9def9f54e6ba3643efdf9d41acdeb964524d396f3ce3fd247fa2f7380e4736a01f2e59c72bcfd606d9fb266c81ce3fc32bc0d3a198071be3f3f8b27cc0f725b7bc6cf3d2be99da45f916a7e3f38c349d21b7211a2597587be4b05e6ceef17b908d1c4dd21112e95f0ceef777111a289bb43225c2ade9ddfffe2224413778744b8f3fb594c4271b83bff48831d3217995ffa73cff86bfb94f3faf3834ed69ef11719fdf9592481f68cdf6ded19ff91063b9c64df908b10cddca5e2ddf9fd2217219ab83b24c29ddf3fc51346dc9d1fb60fdf7e16934cdc9d7fa48ff4913ed24c72cff839a76dd0789903a49e5d06c80dcee7f629f9a7e59ef1f323cd2903720ee774f91b22454f610414ad21610c79c190160c991a32c6102286c0604808865831440c2057860431c469881042da10f28221370c9961881742e6186245881c426630248b1035848421248e214d42de18b224644a081b42bc08a11212032164081943081842d6102203212e102286902e84782184cb902d845821a44ac8154248304520a449080d3d36e8a9ea99a3478e9e387ad4e8f1d233464f0c7a723d5b7aace849414f153d24e839a247aa678b1e287a9ee889ea71a207891e237a44d053821ea89e247a94e81941cf0a7a5ad0c3821d11f448d1d3448f163c3af070a046c68e1a3b69eca0b173c68e193b65ecc060478c9d17ec84b103c64e979d2f76bcd8e982878947069e251e259e241e2b3c31f0c0c083dbb9dab963c78e9d3776e0d891c1ce971d2e3b2ed8e162678b9da99d1becd86087063b74ecccb133831d3976e2d8a963c76aa7063c1be0b9b293c50e163b2cd859c18e0a76a476aed8b162a78a9da89d12ec3cb143821d26768cd82962c769e7879d1b767cd80162c7033b42ec7460070440ec0072c70e13901b00b9da69dab101481640ba00f102880b807001b20490278094000813407e000204902cb51acc20a61390a51a0d80c850fb52bba376558ba3660710a5da1c409280e06a5635388058a9cda026478d8e9a1bb5aada1b35366a30a86d51aba236454d899a096a4c0059a386a546430d57b3528361e76987089d2f74dcd0a9d25943270d1d2a1d18e88ca123860e1b3a73e880a123874e0c74e0d02943270c9d3674ccd0214387063a32d0a9814e171d2b9d3774d0d0a143470d9d17e8cc40270e1d2f3a67e808a143848e077478d0c9a263834e0d3a34e8e0a0d3019da61f6afc80e3c71a3fc2f8d1821f5dfcd8e207173fbc981ef8f1c40f277e90e047133f98f8b1c4ab04f34b8f0c604288573fbebca26a54d0c8f083aa2af9f0c2c71735197e88a1d3c33787ec8e9009f6434d1b36573a869a0bbc2f3a778473d49e422ec2168453e11630203c1bfce0522347784527869a17542d68984219603d7442c086a8f902e34167294cea425023469df26e50e3a5878c70a926d5259b1d6267c8bebc5eb0d303cc03a1d2384307467490a583a70e74a851eaa0033d8e10bfc070a8568c3db8be78687c74f408e2c545b481cb4a8f14e06c51657851856d8c3bc8bc78c5c047d40f2d6476c83421bb416581cb062f2f2f34646ed42d7c24e164f1ec78a9e15223e6c54b63d4e2c38a48c78c1d95a9068d5a11f54aad04b51d5c68b86010adc61a6ad4a0597aa541a39463031033726aa08901c9445e21ade05841c6602307a9f423f827300d1b19f4d4f1657000825718382da827e8b0886ef4808123021c23708ae809030704384ce02c81c3054709215d709cf8f1c1f900ce062a10383e8852b468d0b2c26962c686991a7048b09303ce08704a504bc306861a326ad8b0d9400d0c6ac0c8990187861a3a74385063464fe12ce1c4e003063ec6f831831e40f4f0c04b8c1f67782ce8d104a8460fa79d257afcd003043fcc905981103764a2e8a1030803d005433e007ab179b201818d10f406a01dd48ece868e0956431743dd42bff4e8402743074387ebac74576a0a2a15758aae06b1aadbc07f60c68c971daf2f558a1e5a3aa577aae9a24bea66a077b8946a9868c8a0a1010d1d3435a061636606345e66e2a091c18c1c346bd0a83143c7cc1c3469ec0411ce40860b4d0b605a68585093aa69a131a25ba2c982e605b52d343e8c1bb0c901f6011808604f3c88784551b9c8ae646dc072f820fe88991bbcc0e88ae888e88c70c9d03dc18aa8319851a3f683c8c60c1a325f646e206303992b19ab191a66b0c850f1a282460c9c20707ac00142e60a192b6049302b3255c8a4e03df03f00d181831d4419d4c6b0517a55895334493b30b41534565c4b2e1ccca99682300d980e5e0d6057604cf306e31a3655231b3e62f08241f5e245c66b0c0eb48c408c3f8c1eb08943868b07e2d5454d1aaf2b5e5b6cdc78a9604c0387089c271928402e5e55d86001af6aba8871d4d0a0070f3634d4d8d1c3071b2b21ce268b8d0d3367d4bc01bba1c68d1f2ea859e387979a18c09a6c7880d95073364b3565d0ab9a19d4b2b091e175831a2b180d3859d4d421b6f17ae2d5c4cb891f37a89101784718c3cb0697198e858f261717ae12b846e02ac2b585eb042e295c53b8927081c015e59a72b5c07584ab0617169716ae14b8b270f5e0f2800b0bd710ae255c4eb884706d7129e17ac2b5838b07d70f2e1b5c50b8a270657171c065848b05ae15b8987055e1bac275832b07d7932b042e205c1f7005e15241cf54cd183364b862a8b99a2943ac439cc3e606110e9106e21be21d40bec0711273220a8068b169c3956433c3aca3c6c4b303073cbccee891c30e0e385c841b7899a1e30510aa1a143555b5276a4e4c2d707ee080033b576021d88961a7069c295810af357464086100bfe0203141600387cc13322600bbc0f100e8458f25c02dc030769a00c1787d51b1709d51b3807140acc1cb8b9a06ce11343000c204a40c58075e65d868a9b1012ba9fe00dba1034137448ba047053369bc6cf0838d1e3df464515bd0566ab8ecf0a0d34563f1d9507bc0116205162a544da22e5195a81e783272a2462a9e8b189731052e3b64553eb8689911bee18901048d57171d2d3836e0d48033838e0e325f006143c68b8f06b5a57a458c8b2ae5aa636c72a5d1e303a21db58a1a11b5281f31e058a92800a2850f18ea0a5e50d4cc21dea0a606231a43b8801101f321b4e25b8833a82a10e5a849c2d10296c533e3470c6a5c5073064e08bc1fbc19bc2b5e0c3d33e8b1a367e81a7a072057b4161b1d76b4b8c2a01903e452bb41cf17206a0021a3cb0244059d53a743d7d4d1d075a0d3d2fdd005d1c305080f3d5d741ce87ce87ae878e880e0d1d2edd079a0cba1fb40874377031016e00c61f3464d0daf0d9d1c7ab010b700d7d0b9a1870d73861b367676e0e14167079e2606e060c101838621e3820ea39de8259a896ea29fe82e1dd55f34091a0a97aa5cfc106fc423417304cd123448e41891e38408845884e834163192603402e4400d23c6464c8e980c649e64909029a207971e60f4e822a7889c12e488409c41e4808885468a460b1a15c4ba88c120e60558450503b442d64566860c8c19ab993b66eae8b1460f1af460237644ac043124782cf168e22143ab8adaa56545cb8bda45eb8b2fe245f042f838818f2d3e50f02178103c11b12b625bc4a44627c629c6a81814b12d3113f810c207123e86a8d9e0b9e1d1e1bd018301ac0cd8182316a31763163eacf0d1021f57c8acd00981ec8a0f86efca1783a884480271095087ea0270872a06a8e585e5b5c38b86d612b5205a4c842c08c908b1a835d42cd586fa058d153eb4f808c2070fad21ea0b5a21086f107e69bd117620ecc1d3a2268697453746774617032058d870c026861aaa9a1bd8d450e3854d520d1c364d3638d4dc5113860dae260e1ba69a2f80cca16307101bec28d145f42cd136340d4056d0589aa973681e3acb9ca3710d03902ee6d5acc1b4c184a3c76a5acdaa49032052736ab66066b164a260b2604e31a5983f4ca989c584629e60e6a609261573cbfcc05cc1b46246318998219843cca46965c6309f260c1357c50215983e3c994d4ea8b820a505a1261098400424f08006a49000144e40c001941820090953082300100091282c38c07979c648c16a072a6a528125539a00b1b0640938fd4914a0254b5abf8127529c003dc1f92b5c548401202551a440292a025a00f94c1cbc0c34bf24d4c40914222946455058f0e0956c3e89895a68e1f556b8a80848a8c7c7c0310f03b7700099c7f1e05c090935712224d48400349c3bb848084a1323a0274b80802cf0018e1d2cc50251a02cc10011900b434ba04cb94651805ac04013141ee70b03ad7003067a22c5c992274da4084d71c1060c64d4048a519426464551a0c870ea6021a1264e8c9c3421328a228500301c2b067212454a94254d9c44918200a3282e4871e2e4f6c0a9019429170345500a80814be2d020041c3a7270e660189c19b01ccc82132953806c70e26022175680628128529c2c8132e50255a0894d06a78a8b9e1035b90010d19215a24079120568ca1228536e91901429284481d2821404581c38780a14168a8880a25c40ca120c00057d80f3063f018ab20294a2282e18357122850a14178680961811499902444404c70d7e026589115011910b4e6870dae0222028465088a4b060e44293252b2c8132e53699f2244a1322127ce0c8802f0065ca25020a2292e28013481c361808c80520171290c213a015566892c20f9c35b828c809100b4ebc7091511420222016a240791c35a240b1800d4e1aec044a5114284446558096604068ca94264b88809e084171c116e4448a90ed06070d6e614913a3264f9a18011d0086734606a00835816204250a14191c3338c88914a10a2c013272c109501520189c3298480a01429e404215686214c5050b2c3172024404e54914284b96d0e880367c2083918403c3ca97cb4820e770b83b919cc66355b1aae694f951efc6c6fb273d1bcff3bc27c99b1b8ffc1beadfc75f7f5d6b77adb39bf963effa7d5d2be576e68ffb03e9f4fad1a6def7791fd013fe987a7b5f777fb4995b74ff9add99b2338b226566ffd8fbbe9deea87760f7d755efcfbbfb1b476ef70aced44a99ba7762f56e96d8ac3a99bac74ce64a65cd72cf9d3f0fdbe9d7ec2f661bfe987ecceca4dde9e73895dbbb72f5cf690794fac7edb4d93f76fa71d3ef73f7bc8fb6536766ca9429534ad9fb28f5f6ef83317b53a64c993fca4e653e66a7cced9476bb575ae5cafef19021428430c8eed4e5a20e7a575abbdd0586cc937a5ead1f738fcc9f3b6598bb5377efd1dd2be0eeb0eab5d6dae3d8b4dbdde79c3e67d3f6f6a6d4bbbf6edaecd46beaf5fc2af5c09d3af5599dddbf70c645db43f7daa42ba5ee2ff6f656bb7fee1574265d57ef4a7b093b8d31b37fd3dd41b052a069482b0dc31aef1a760fc309788712a8719ed3bf5ab97b727fdc13e4eb09e21e0176770a1386ddd3b9bb99fba3f9421aeace94db2140a97baeaf7eeef4f3a8473d66af52eade5fb7fb473fef8ffbc6fb3effe6fc981bf600dab4ddbb2937b37fdd1f7bceee7d2008a34054a820303bbfda1dc0cc3e3bef98b9fb989bb9eb66c7ac6eba772c67ee58ecccdd64ef581d77ce9a5dd771d7755d73d779c71db3983b666618666f6731c73033b35831cc95997aadeedd9f7b8e7b7737a51ed0ee80f6cbddbfe6699e6e8fba7703ba76f7a49501ed7937ad1fe5e9cddd1f7f5fc7d49dba376d4f61d20528c0030e9d7f780218051ad6f41ac7a969202774cb7cddb06eeafd79b57e8e0098ce016a351d6f1a86ec734e9eacf6febeef874c7ba594c62adb7ccc95a73bedd0dd457710e6e476b06d427666a6dd4ca33edd41f77228655a29ad94b6f70ca5b45217a5d4044a5db429f5da5e2b58bfaf6777fb6cfe3e9c0efae3e993d99550e7ea6cc3ce6266af71f7cf6b6776f630c63e67c8ede2768ecd364077e8edce727767d51866f7ca732661febc69f3474343536b7dbd5e73ce5adbbd84f6f6aa57efd09d046feaeefe7277eef9f5d7947e1f87cedeee4dab778314ac2085e9eee6ea9f37280382ec3ed929ad15a4947e1ff7d7d49d7d4e0ec3574e873e42483d44e2341e76bb7bddcdeeeeecfc7ddc55669e9f659cf979e8ec79dd4eabd7dab47af5efebaed56937add4a35e53da3da7cf39270c4c7be73c3bca6af72e403b28d33dfba360d7fc79d8dd9336a594b67f4e00dbc7edec3d99bbdd3fff3e76e6767667766f6766a6a0e73ebdbda977f7f4cf999d5266fed89ddb9d32333365fe98bfef6b76ff989d7a5f6f7766767777fed8bddbbbbf23dff7cd6aedafcee97d3319113c99effbbcef930d4000edc950af7e9fabbdfdfbbeefebfebe98f77dfc7d9ff3f77decf4fb78ec9a366d9036edcfdbddbd73ea7ded1fcf39448a2153380f6e0c10496901a805cf8805a448219a0242009e0011013d2192b2c427841e20284446207c0043d323a5a60b72d2a402424252402852d3c3470f1a1e464550aa00dd742d48e981620120a22996031b98284053a634b9f10b00450122ea0e5a806214c50522cb81058c5ce8c14115201696184581423465899322282ddc0cf1e95145ca058c7c3461a1c8475013274e80827c42e8e1c14188f40459d20314d444a8024b5688028585a2262cbc102128413c00f8800807690244e4032868895115a0283a3e3e807922048505274b8c845c686201a027b4ce88a88951d1073d1cfcac00a5888c7190220c00052d710245a8022e4c99111575d0e29ea22220a2292d4871b28408888a142740444b9a143d7102b42448904f083d539c0015fdb0587062d4a4024b58288212058a05661f60c002508880a870608980a200adb00400414208a1e709d0122946533040e4a4039610101520a125559ab480035b418ad09215a240596105294234b3051f0c446401275284849adcc054017a12054acc94169a181501b500c5e87b449102c5c84993a2284d888c96184169a1022e14d1584f80808a96b420e5499426443606c8a88951d1922022291730028a92032bf2596116821150d19227519a2c01226a32a5052943c62640424e9600add084488a51d112a1264ea4088140250a90b338c8922852a014110151594224c5a8c91328424da82c2982b2240a94262c38b18005a42c31aa02c401952840fe03aba3f986d44cf805a466c28dc462c247472c9009b7c20e09e9e8e8ab48ee47484820528b09231d1dbd8e8e68bb33399a4847474794c9d13cbacddb64f2c27c611e1d1d1d1d3192787474243261a48f8f908e909c9190e6d1d16482348f909ac96dde6ecde485f9c20bcd848f90909cc9d13c3a6a2647f36832e1a3a3a323a48e1e1d21cda3598f26d264723499091f1d39133e426a267c74c448481f13a47974e4313942ea98204d24a46682349991281346426a268c8484e44c9026d264c248938905bc342633cf168a9a70ff6aba2dbecb9bc2179ba6703ceccdfb193b61ec6d8ad3fa61f6369d5af6e654377762d95b3bc9d8a6622aae72ea625e8cbd219102ec61fec6fa1bd3105beb6f48a4d0bd3775fb6f48a450bfeb5c0ec6de580fb373b4b709e5b4fe97bd4d97bd7993686fdd14da9ec24d2876c109ea68a220cbde9296425bcbde904881f5f46f93eaf6330db1517b63d949e5b47efa9ebdcd29a7f577f6d6d5766e7a36a8a2065a90800530cca9a9c58c21d4f882082b9f3dea2b9a5002872dbef460a37656517915a572a2534d533447713977a250de975e0555e5509eedb450755fba13d5955367bb266fa25ff6d477757507185faca087266a3ba6cecd37bc08c30c20a4c2b0b1cdbf6cdced8f8b1dbc7842862cdcb0b1cd6d87735a7f39ab6eff1cc138bfec70b7bba9cb1c1c59a4d933361c31c711671c31c611611cc165882e59dc0c8c9c1b4288db0f5ece0d41c5104fcc1a30bbb3b395796543826b58f0c86e3ffffc59fbcc3075fb6f74daa76fffecd86d16fe36cee5c961ce39d9c66a98c3873984d395f5cc2d371260cf8668c26947f0b30d091c10081bb60640bafc2fc840c4b644c4d6cf362bf3cad61609b64773ea809492486310fd0f6e89d41d5dfa25eb006cc6ed2c11b57b26eb7724253b57a2ca562d8eb568a25fb228f9c105278b10f8e01e4da4ae9b0b281f40e625e61c9ad77fde00f293f00738346f3f0f5e6ef8dd3759346f7f8b25f065d9a0f9ac269a5cebdea8de21bebae0b73842f8ad16d87db348ce817ed8e586cf7a10ecc26e3dab45253409ebc33fd2247c0ffe24c16791e1bba8a4fe9c96b936cbb6936bf3590f9265b3a8d43be477e08c269237db8dc9f47f5c3a9f7970bade7f28a8b003166eabf159fbd878dde7cc98b0204667f3d1a38ddbe9b44fe9fd8c3baeef25842a30699f8ea54c689f79bbe7d1c274bb1fd2519edb3117299f9a5bf219b7ab3fe57edffc46deed07694efb74443d45254beef7f5fbe6cf32ebb00559a2094852782dcffb727edf64b51fe99125d2f5823c31c967bfff6cf98267cb79bb497f70762bf16f25d3b34ae677f737e00e425c8fec260cb7accfb9197c18c158fb78df3d1549a85fbe709564c270eb83dcb8fbbd47d68f2cbde73fe21e0c777e7b55f502d6fe793dffd83ee2f3c7daa7f5cc7ff339ed539f7fd63ede23dd16297e25914010fc231d9236f559396cb9f4451dbc07b95cfa1e07ceb8f441fa208834c367b1c00727f8437ec1076b908d92ef3bfab93e259feb03bf3ec86a3d5f56cb8e509ff5ac1db25cfaaddf21e9d2a0eebf0fbf92f3b25c1ca1d56ab56c50f725fd22a4138a906ef841de9f40ffb3a5f7a165f165d52e6431b4e5ed86ef912fd27b89394839935ebfc41cc4fb693be2210976a147fabf48b6555209cb06894f5f7c16910c896314df3df03d5b8a0f5a1bf0bfef94d017ad0d6895d4f7be821ed9fa2fa8d64f49fd6a12fa2c5b7a0f3e089265f836ace70bbe47dab0ec08dd830f5abe1c98e3d2071fecd06b3d68cb794befc3073d6c91e197f386df8d002601c1f767d9a179c57a7ffaa02d5b1f92e0bc1e396f8be43b2ff3ed8618b9fcec359c0168182ebf8b87c8d1446a7568039884410f5924c16d39a75802fbcf13fafd595f562e52bf6479e86439aff760fbe5760ffb32c8a1279e40df6d59af7bef950e7e210d3bd10095eccb22e7edbc9fff89273458c5138edcd6b3c8790d8024c56d3dd80a5926208d10e50e1dd52421cefdaa880024a7db7ab04396480292d31d62725b0fd6b0251a00c986db7a100c5962121eae1259a20948b7f5a02b641da0cbd7fdb8997976aef2a8e97a0f86218b65cbda2e5779e474bd6f91cc3a65ebe787e209fd2d5b4e164356927ecfbacaa39b4588ebfdbc959c17ac618b49e8fb4f71c86f903802d2ed3eebd9f91e34df46498981dbcf17a94e2f892c583c0a0ee4c09405072f138710ecefb7e99e67f7ec9136ddcffbfd07a3ffc1f5ffbec9ee677bedb5c7df5ee59eecfd11f7c8ee821dd90fce59c3d83f3b0f3b1a765dbff7839d38028be17d3357f3dcc976ecd907d791bee95b803c3b3082b387b193b89cf3418ddb405cce7540eace2ee778b04a6264a5ea96485178b774e1062b2eff6bf6303a1597731f58e2ce2d977340bc71752ee780e0c01449686541758798dcaa1feed091eb9646658c2103e296464f408065dcd2688632ba5b168141821f504cddb2286aea561c8eaf2effe56f1dc0a179e98394ecbeebbeb8f300fe6dcb5c08dab8f4e9cfef49da28e9beb8f4bb2f6e598474e977cf7788afaeae1ae9f6776ddc79c4964b5ef2821d3689733bb2fbe24e9184a72233ad512b7927c1eeea5a9b24f3fd4998efd608e4dc105eae51dfce96fd54e6f547bae47592bc6d045e7ea46ef69739ee7cd9eb3ffbf9fd5d3401490adae4fca60d23e76e38e3d6ffde6b7d25cbd607b1be7ef7dffb834d860fba481bd7f32d91aeeb3fb2ecb643af4bc5a8afebc31769e3fa79c70769d80f36699384e270177c7afd82df645f16934c5c8b24b8fe458eff91ae6fd2c317492f48c38f643aee8bf40b76e147f20dee8bec0bd29edc7dd41b3ffc8f643bee8bbbd9d425be5f317c316e48f68fe4eb8ff88bec38e8fbfa6e029214f5b9d63fd260f308f3bf2926f9beda24f11bbedfd0964851e070b749f0c129ce1a46f05d24f8305cb04317093ee86f5c90cac1735cb00b5d64d177a9f45d81685ef0a98864d230820f52710416e3820f7247bb72e0027f0b2e86eb22792ed8627d83e233d75aa0f8618b2cfdb23e64852dd6832451288afd21eb5b248b26b00e8b9fe707ebecd8336aed752beb996b7e5ec029c3482fe76e78c19461ec2ee76e880173ad83eff3bceffb496ae0fbbe2f0d9049708add5cebbabbab5ceb7e921ae8ba67711124fddd73e5225420097c5f0f32333373cf6772dec9af906baf6f3203a3ebc50f1ffc0c8cad677dfdef33307afe7af5bf5edfaf31c05792efbf1659de777d677d7dcfbd7a2cf0abef2495796bfd6f72bbcbfdddfead36a8fef72c1ea0b26c8974599375abee5eff880fdd6ed76675edda3ff9491bfff9fe4ddaf83b59c291cbac537effbd937cbfff2a9151788744b873caadcf621226b77eb5cc3a247c64593fc8ff7bb092966888ab70b86b04735bef6e14ded6d767f1842997f547ba92444322dce69abf91776b5f7f164954dfc8bbad6751c992cb7a9c2111eee41aeb2bcb32ebb83842f7b592f3bf725efe8e2cfbe733b5b5674e8e757e5880ecc1bc7bb0f307a7c86d03bfb625d2ed79fb9899ffe33bc9a1dbfd6693437e5fd33259d25a2793ee43dfd5d5d5975b9b1cf25bed9077cfde7f64f93d95f10a511c0cb7ec1ffabec07075a9d4921544bf3edb72bcfc4d86fd54beb27f8888ca778b90eeb42c2261efdba86febbd6fd9a1f9e5521669d497beb5493273d7bf4524fe1ec9e57cef9da4d29ef7b61cba5dfa5d8974bff9555bde6efd26677777fd598434e423f0f77b437e29b5414aa892f96e83f89b59b3e2d03327768055c6166f787a2663152e32bf6fee52f1441f1f7cf1a5ede37df8fccc7359dc7a2e3243f2b9c673f9bd24f5c93abf4e92ef145b606b04d66b5e904524fcc1c69eb59ef5e04f11c9b425d29d2cb2458295a4326f392feb2749655e16eb2bc99782ae6987fcda8ce077feb4cf35fe792bc9b241f5c1a7e250bdde8321f862fd14e7d2e86f59967f82952cebb35ab644baad89a405daf276c19f248bf49eac33bf340092149759673eeb8ff8d0ed7a3fcb5be490b3fc59e4541afdc726f97e64ed7a6425c119ceff489b6987e6f52c6fc1e1ee8feb8900f426a431a8fb0f6ed9d989a5677c3937830fe0c4d23e7ce9037111229e4b043f12a7f1f399ad6793966a36ef99626c58da2776e9d70c29632c85eec4d233fa3c68a090e4fdfc23fdc2584e2c977ec9685cfa37fed16974f8e004104e4051e17036efa96d92382a821a4010431027b0252dd56cf399626cfc494b6dfb9e6900b6f91ec93400db0d8914e6df50701afd3975e97b7f432285ef3d7b3be234fa9fbd219182f7d3dede69f43dcbc3b9dcfc92a7980632a8800837c230820c2efed21f1283916d483a6071821f7e98a2cb1233b0b18dbfe4b9f4594ce17138dbc4d23e1f5cfa9c436dd06ceaa63f80cc454a1ea457d93e2dfa1da547d73b332eb55de97df43f1bc5b3a5f742ae44d5edacf7a5dbf276a92b612d6cb89e25a2765f1e5d21241fae17450049b9db7d496d59e57a14d6a2e9765f66e052cf46e1336e67a79e50b0f30515f4062df7e672aee9cb053bec48226efc47afabab2b1f6c2c227033632861650d1cfd39e4575797085c0f1a86c8e244d48153125238a3297cc62502b7f30515382a0248ca55c1b1164d36fe3203b77be60030ef949cb3a1896b342f1131f0193696c5f11936b637fea3283f7c000c18bee070b66a7149389c8dbfbcbddb720a48c34af253d2bfc506ec7c31c5958d9fc506c0c81823047758b9bab2f1c7aeb77702d02925bba7f3ab5df7fe951cbbce6b345cece2b8b29e754fc979410fe97b1d9d9776c3c0bf72112f65d77f7a7d67bd7befdefbb3bcaf9ebf7befdfbbfb77e4bca047f2ed90b41bf48f74bff7d37b1bfaf3f6b5a17078df7d5e47ce4b495ab9c6ed06c8dd532ee23d7fe791437ad6bd1997a767ddb3e865ad52df7f5adffdcc7fc0effea67d68cfea774f848b3cd7ea770f9263d3eab7c8dab4caa3fa8fac69f5bb97b50febbbe72db71c72bbe7c145ea3b55e891fcc1eafb43dd9b9ed5ef9f3fc5fa36dffbed6bf37dcfb91ad4b89cab018d2beb597d6f885e96e59ed58e6bfc2c528f9cf7a891ba7625406e9fcf9ffe47cedb91f45924a17be6da08fef4711082c503f8d3af4f6d592ffd7e8a4355926280017787ca0bdcc08eabeb7d11d2f56cd1674bfadd91423529061868951695545b56015924a1a34fc511bc67ae95dd47ceeb911d126a6d92f8d3f7a736a89fdaa1db2dfdf677b353007e0f4e1109f8e1775f49f1998bb8de7bd0458e8074cbf0c1677184ea0aaacf1f9265fdf9e014d9835dced520c6edb8e6b53842f78b64fd16392f08b278807e16eb4592f52d92e7b3888465cb79d996ac6716d90ffe9106990c1f24f9822c92c0367cb043909c9745125a97b956f283e00cc1f08f34872059490c8ce183dfba654d526f688358df2059b27e2ae967cd568be4cb22f956be5e475292f68cc3e95a409e32d22f65b77b9eaee3b9dd773fa47b5913b7fb9bfe695b67e4763ab7fbb17dfabbaeeb9e733a1bc4b923907932cf27207fb0b0673114daa77c1adab8b92573b9f4bbff6af7f7f3bee42ef77b229f4f594b689f7264a17dbe37d23e35f77b15da87733534ddef25d03fd4e6dc85b7dcefb97d6c6e19bb2591fb757fa46fc0263f21a608eef760874df6952171bf07b927bb6b685e5dfe3ed63ef4bfefbfe79ccf0671953fcdda074baee797b21bf6e176ec3e092ebba1fea37fec9200f20e19230d586eff386120bbc029c3487b369f67fc29e92414d0b9b87bcdedfff096e3cd097b46a3009e230826bad0800439dc20031bc760d4b288643e1db17ce9b17d64b73fac3c6d783987a58d4badac67937336009968ec1ab6cf1c3b00b91c1b745dcd30c70d888445871b9e7000a34b1177d85804e7734ec943ce7bc1497b36699f4049f06cf9d7fbca1f8cf6cc96467e5b2f6b1ff0fd6fdae7033f16cb96ac6f3deb0b7b36b6cfc77a7ff023e7055924873f451278dcd096e1b7fe23f986a4915fd683b379baeb23f98224df168be49e95b23bbffacf95b771d3986be5cd9db6f4409fd323f98a30bf9246dd9d21d86195eb3d93652d2b7fb0c9624ecffcbfff9e7d4c52b29cd7238dfcf24f72ec19dbced69ef578bffa0fc5e170389ccd7fc645fc7acee569cdce03eee493b1d6366e7f289bc187db7ff3649ccff34ee110c96bc42b6d5cce5d11e3967ffb0a16f7fd47a769fd8d047c79df5988b40fe7ae7cb9fd46a67882ff7c1681c672d63d11cecdc074fb75fa67dafa8ddcdcb44f3f933c3d6b9d9ef57b47922cce581c615e9d9e4d71d6b37e0a8c47b7b60fe774371d0790c9381ff48e9832e2703818669f30bb7da4670e23e736c0e57e709d72112e1a3977258acb972fd885948bf4e5d2bffbf9a00bb26b24bbfd4e96936888af6ebfd177e9839ea8e4d52473adf4af9cc4fbee5924c1ff3bd24ef2ad64d97d39afff47da28f1bebf6d50f7def3a5245f4f54f2c1f52c73cd9f8a48ba196576fb67dae6d31695700da2cc6e5b3bb9d6efe209b3eb96b9d6967b3691be498d00b9dd7f2673bb2d274e54f2baf49da4422fb5cccecc5ce3205dbc7a7693bd05387f82977332bc60a6d132ccc0bbcb3919eaa0fea0fbd0bc9acf62166f06f1724e863ba693f37e97734c42b02ee7984470653d6363d620037617b9d621d7fa99ccc0c839a62dd72fe7985070cbcadf2f32c9d4c495f1e775d535763b80dc0ee89e1af9ad1d69e437c9c4e170b83b9f92464eef7c4ae7146386ee0f3a39599c7fa4bbeefd5d44e23d73f2eb9fe2fc16bde7a40138b18cf3d9320d387f9224f0052739831657d6b2cbb9a52fae2c1eb688645eced55075653d6b71885ee61a7f8b4886e6d5a5e15a7f8b24cc4b9f4916f927392f9343f3eace771109b5b19ef54f52c6b57e273530724e862362345c846fff28e322ad20fac10e1685174e923d58d833ee597973e7bb2ee764c8e2ca7a361f64ea3db973790e20370876cf3dab5df7471a04596c40bf2d912efd239b3b8b2af8b7bd21d96ef4dbe64ede906cf48f746d9fcafed35f1af95561e4cb29cc777b3bb22d213124c2f57eda3a92da72deee3db2f4db7d93fe47bc6d2ca6e0b6f9479a927c9b641bf74fb521f9517733813c34726ea98ddb5dce2d65b90c63918479fd8fb423cda9c4a70246160d807429b521d29c0570b204e49e913091f8a74842503fdf20b64347977fb200b202e81d2ff8a29d9b8074fbdb863df3f7a79d4742bfff91e6f6b119a1dfdfbd9f4f6bfbb82dbb0ff2a7ef791fb64f5f6fbc2a00590123f8a2bf84e5f2fc72de69c39ed1a70fbe4c18fdfb878e2e1d9a97da0a80dc20b74f7bc824c8394a6d8497a77d4a23df3ee5cc48fbd0f7d7699feffa8fedc3392531ae7fac7fdae639d79fdb27259834ff120097ec88e099bf976002e096d4a1fca71301d3fc69ade328fbffe0961fb478025371fb6b869431f214976f49adae9b20e91af5a5cff405705954d25d6abb6e7e51204319f90b14e42eecf21727e052afecd2f940a0187279faf7a5ce65066282f173da87763f85726eb524bd030a19dcf9a3fffcf4ec87acc6ed9e26d9badbd95228e73e1b23dbe6b482883b3830f586153a9c61732ba048e3baec7e4ed3e603891abdcb3928a86ef9777aed5e80dc3eedd94a96f5d6ffb8c8e77111afe3229d73116f2ed2938b4cae79cfdeb441defb7b5e93b567f57bef67b565add7fbeff3bcaea3d4bdb9487def6792ef76d523eb7b5d3f3bf4dda07e4a96fe4548b7bf497b98028bcbb929a2e829a06e0bd13ede50fcd3494cebff61a6958d85e5c33c2b3bcbed2f6197610f8021978342ea1af5f5279a4d65be006e8b27787742b14e7f0f31f2852a29974b446fc95d54e8d9a463246f433581ce3c9b30da339d9e75397358ac6736582e7d1bcf8ed0d77bf642055f6ef7448c4471fb5930ea1fcff517a07d38f74413b779b84c223ee3ed248ac3a27f9240272438f7441bfd1ef9002b73900fc045910fc045d133be3ced53d621edc329788015b639447c76ec9b9e35ec0131e47ac677bcdec30fce56f25c2682f4c412414081613583191c61632a2ef3cf8ef40fb5f1330466940f4fe0da89266eb71351dc6e9e198ce53febfb6e0ab2489e32185bcfb7f5f3bfd6f741f4e9839d888465025292efa72d83be9f22fd8f0cf23e4a270f6bfa1b15ac19e286d3283c37c83fec197ffdf69e7e29c473ebb31eac64ed591be3f77c9b45d6cbfe536dfdb59e4065de69a98dc2733d1b44bfb32358aeb3677077f7f9eeb3c7985eb610caa17d93dc44c5718650cef422c4236344172210e2f9beeffbbeeffb84be28dce5234beec25d7478867011f0f96ffa67e6f530cf1f8e3d00a6b7c9c4629e5b16461221f331b171e61b1623ebd9477bf67d0c19ebd9f733e437edfb1639eb190cc917f6ef3f32b0960c599bf63d8c1c7bf6fd48f2f4ecfb1739a467dfbbc802f4ec7b912ca167df87a4093dfb1e2451e0daf7ec3f449af67d3f7f8a23f46d59eed95763ba0b0128da92874b17c6e2b22dc51785786e149e1b147eabe4b9b30c6dc973c3cf893dffb70fecf9cbd88d79181869a467fd317248d3622cf8230cf94e9bffca9189e28ffe03f3e3f7c3902c22196d19fe57fe15df4596e3156d19de72e48bc20dfabe1e39d2d8b487cf96b3fb31598e2e11c808c67f1739739aebbb63f7fbf0b97fc2a67dff3d7873bf77912212d1d69e7d7fc443922c6577da3246b2ec67bb882ee3f89e9d43e61879cb9d638cf5997462ccb83c1632def295467e8634adfbafd67194c9fe673c3debc68f2c6796ebd9982582c575e6be7624c039bbdd29ed989cff8948645f8c6cbd18d97a3306237fe7e22a76e8206d752c2fac3d63ffce3fa8b3b567ccb3d6cbcc9fabac72e9e5cbb34507a50e7ed37b1aae75f4e69486d487be77e1e4e2fb96eeee20839f0472b808e55cfade046bc8e4bbe82efd4f4442ffa667fc32aef14f19c930a21d2dbfeffba8571a399805e46286dc1b605b9670895cfa538c71be1091cbcc52e8bc80bad3d9656a4ba4282e7df79f618cf35d88b75c3acb18e74f2e287da702049fa76e39a48cf5112ea202d7c42fdff5e5ec87884effcc9ce6e1f74cbb7eb5338db11c5b3cac073b474906ba30a28ba62bc4c3c5849eb946a74d7186e4bc2209640463498488ffbcdeffc88b046718b2fc27d6347fff58f86a8c446e8b88ff2421517fe96daff72f40fb94d5a7be7f09edd3ad677d68cb1b6f81ef42442eeb5d547253010e42405d21ee7259f4b2c8b23d7b7d2491c953617b4ed417e7943377bbef723b59ff94e0b4ee8938ad7b7e06b2c548ffd6b30ec8d408648ab19c5aa696f6e96f6b342f121fdae7733aa27d3e4b0454fb44b58f4d4f2cb77bbedfe8b4eebbf17295a55c05640463f725a8c045d0184ba6badd3379d23ef5bb670137a56fed530acdeefcfeeeab98506dc95c5c44e259233a9be05af71d4219fb482023602d3dcf184baeba5df7538c4a2255e6531212f497de2644fb94d3a97de8779f0f8b48be5aad106f51a28121b8f042758598ea4e7a3d925e4a7208f363fdc3b66aebcaf176b652e7fa7733f7d9c0df97eeeeddc75dd7f1cc72bcefefc85276f9fbb2eb3aaed1779f1e59c62e7764195eae43b8c66347070d27173d3db2b6c6e8d9dab376a6773ecffe32bc73ea08d7d8081109e480219433847f96c3c577f937936a72573bebc541bbae637ecafcb2aeeb28384da0725ba270fd2759f2dc39e79ce5ec9ad0b37e27857898cbed233deb9fbc85889139bb5c29223d6b4a96425198ea064d8b44a73fa1d333de22813b9fff36c5a8bcb94239977bec596cda92c89ddffd4ce7bdf7294444c65bbce9348020c8df24ebdce6b94de476f9df7739b7ab48c25a8fb450cee5a79c33e43291cbb2d28bf5cc93fdf5a6673b7276bbfca6946b311691944244eefcb6b3fbc299bffbd2f3f83dfe208fe716fc938b7e3ab718e7cf1890e075dd7bd77d10a5f426d67d4929ed485b32b9dd53727631cea746dded3a4b72d9755de74f20b70fbd6077777b7bcb00f697eeee3d6bbfccf432fbf897dd3788a8af5f5d3107807ee9de414e49a2795b095f5d5d6effb2bb8d5a890817c9a76701e98325330d625ba70b2a7391c945f896f4b9b6c6382f7dfa5e7b367ffec806f885970dd0e6394b505582d9ed449313b8ef8201726fc0eaf60c07708740ee12702901167480f38f984c7c694288af7d027039c744976be4d7bfc8fdb84873cd595150b18aeec585f791f1b1bcd4d7e55c1371b0445ccb69006b53a8456c05e1a247bc6050239d02165601d3da2226468232623130323cf50a3855408239aedf2e0196db3fc4c80765c84528002e915bde9044fe4454c6cb3ff4978a5fce5d4af6b8200d295943ca2ee88594e471c12fa4e4cc056b48c9980bb2424ac25cb0155232c805c190923c170c434a861714434ab62ee80a29c9bae02ba4a477c131a46477415848497a419890927ec19890927dc1180c2c2626e3b24446e3ddc9ddd0b580f30aa8286e49a19a8082f280169d86c262ced9ed05ea0caa840f4a24415929d1841249283184a7441b6228a1c496fa8d97734ac8515d31b0bca6568b0360750ac1277189dc12276831e10ae7d42b146364282e505bc46496f012c25c2616de662249092c4b58dd3126b3c41bb5c28493891a6238c74416d8f8728921d8625518170c16e04cc1571954d3edc94dc059c41836146e323373126d24e18593f8726524c87c11d39fad4a9ebaced39673887333b72a798ada72e6b69c35151628d87f3f8e0ffbbcf88f0c4dd9552fc8946d35f323e3f15134b6b574ee3fd9287694d31aca69dd4f4e6ba75c12b95bce2a9eba652f4199ec74923dccccc7bccccfe75156198c2dff636c29b3e5e8d45aaa6664ac66aa50cdcce0bccc30cd3055cd34cd3459c954dd923249d9d1025bcdccd4cc8cac8b4cf6fd4de53f3c686c6c2ccf6a6a2c0d0d0d0f4b79f008656f4566ca66acf7f3a7d37492eae9659c54cf1ff3b3cbf3ebd9a614fb39f52fb2e78e71dad74f29191a1e5353aacb949215999fb132a599b7223369ec0b323b3363a79722a4db39ae75c76c59636c39c2d85206b3e56cb4e5f7bfc8ceb195950b9ef84007d0880304b6594b2db551830db87165fb5c8ba8343c80abc3043656d73147087032e08ab0816c2859e9d2050c4e6063a7b95e7ca79af1c2644714554d6ea585e25ea04e2fd0a714c0616b24a66e4999a46ee75cb3d9d8b2a54c566df9f7b3b9dced9fe5b4388d9d3c5bd6a7ce962394d3f8525bca8e2411e534be6ecbbf50311dd303c83925cddd999f89e241130545c38366522d4eebe741e79cb28ac9c46233333433333c66666a64646256c94aec9564373ff333df3236375f4dcddbd467ffe161797c0d8bc682cf36997d61c6be20f3ad076913283e65125f4f712fd8bbd5b7555b5575eef3a8ea50ac677fe2a9b5bdb853d15792b1de45e6adc4629e6d4a32d6a73e86a45ae69496a9db1ff3e59c1a81d32d1b57c563d556fed34f4eebafa3ac9f6e3f68ad1ad731b69f26ae9fc62a1be7d47c9a5652d3d64f9d1a14fff55552b7ab6e4ff194ffc8c4bac81e05a74d2a1e305e669e9d36be8cccb3d35c6fc563cf4e0bbf63969d063e28533ff6e28c65a7b15ee65f3c2c3badf5330fbbc92ccff7532dfec3c3a2e0b4f93330b6e42e773ecc965566b42553ddf92f5b8e31cb4e73d992bddcf9a22d65a12db9eace07a996dbcfe33f2d5b56962dc7caf3f178b6ac9dadf3eb6521c1348c1c20e780ec3face707adaaa68d454e1b4fd127a7e12ad3d8c44f71fee3ef24d3323631ddae2375f72e5053fec3b62e54d40b7d826a2aae7226ff513a8ab1d5af4fadf0c9296c396979a55ba8a5c97f94beb7e255eb4c4eebffac37b93375d465bafddec5f2fbf7f4bd9fdfb2b63fdb9e65a7cda6a6f2a2e5f6971d75fbbbc97fc62a1bddbbc828eef697dfdf915063e950936d2fa34fd73673d38b97cfab9a39a8692515859bca35531729a7b537a99a3edda64ffed3475831061a1da86105b67e0ae53fae830dbe1061441054d8fa6994ffcca519c0b8b2baf2c2d64f73fe13e40a1ecab85ada62eba752fe339da82307263a70c0d95a4bffd4e23fb76903bf5bdfacff89f21feffba784fd55fc07b42538adb79838ff695914fa2793ffb0ac0afdb3a95a262f789605a7f537f52e5cebf72eb7dfddbd9f8971d2aa0f89f6584515ff61b0b2be9c5a2e2f4d1beb5fb077f173abf52087e2873ffeebcbc974f92b09b333cacb6827d4d2b4bd443b9f467e1496a60df6adfa254b7dc939f04b2297c32f792effcc7f6e283c3f8c9c52e48b9c5d5ce4a422a717d6f3d72a4ef347c169e2f38f22682753cbcea6b6a5cc4e2d4e9bb6fc3bbf9c52f367b30abe3f4f0debfb13a995b258ef5f82ff80e0cf9c361fb4ffd992a5eefcf23d5b724ec6b263674b22d569d4963c7776cd8a01e49cb273255b3dfd92a7a82dd996b3cbb664abeb930463399d9e6ec9565655fed3a50b1595172fe594f29fdb1fc5d8fca793ffdcc4f7befbc207bf64a9af6b3deb4bce755ffdef4b22b79c4e2e7b7b41f4eccc697d7bc1fb723a85f641a95ccbca589c8baa76fc884079b6b2d34a9e6e2175d31480a327fb76da7ddebb9effc3faac16188ab19779feeaaed7088b81791ba6698bc9ccf0a8f9a4a56aa37999272df1d86c6c0d0d199391313c666448598ca4e120f363c8fab15a1c040c6b6c6e38480f1f381cc425be46184ccd746fba8db445df738deb9e7ef8370773b85ce35e56bcfef737f7a77f0bedadab9ce650537846960b1c5b7ff3b1a79ce6b73975e3d9e404c29acaebec6d56fd847a7d2e741c2bd7385c2ee46155415541b1fe6b2a707cb6815fb693d89a4ea3eb4b1e5ff65db64e89a1958176ec26961dab954d1dc5d83e5b9dd6cf36cfb28dfa0b69762b0b9073ca59553faf7bfef71ffafc1ed991569c9256fc236f325fc91b8f3f8ab1252d8936eafdd2b4794d947e47ff567f69daeadfba168bbb5f9ab6ce5b323154ad5f9ab6968cbd252d89b62426116c32bf346d37245288bdccdf78d8db8c5d9a3619ff987f8cbd4d2aa7f9c3d8a5696bf9c3ec14a7f9b3ec8d89d3fc47bb346d9dffcbfecd6597a6addadbe8347fd14ea71b3bcd3fb44bd3e6f9837636396daa7aef8d9dd3ccd129ef998ae7e3aad69793aa658f626cddb3ec518c8d3edbbeafcfb6fae584aae4477a6447ca9c369f92efb4396348b3bfafea8ef44b59f9b79cf5dc31127dcbf5ce62bd7d4104bf5b2dd0bec00a9f3efb4f685f68bd7e3efb8f52d873c73834ef2765530affc624c4f6b22f802efb42f879569e95ff88564914ad67e534ffd02a85e1f753eab3e583560904676eda52d6b24aadb7525fa96539ca69fed47a562cabc47a2bd5be409f6d4a2ccb4eeb9f504efb703d778c44def7cf2546ce2181eb27a927ce2181bb9e37359f9efce766c58f626cb5f5dfaa3259fdd638de723edd9884d858764cd9acf80bec3411aa6c4f3d778c7fdb9673887ecf1de308ccb5b256f6979fd44c629c498ce5e7e459959f5397f9d4b7fca43e29ff994f4ef3af751c65b25b7e52d79ffdffe23ea74fea73e2336ee94d7956de54cf2d3d9cf7e4e13aa82e1d54ec9694aa63a26add9236d128dad4ddd2735e5c8be7bacab5485955b513aea59eaed55339ad7826ee4beec253d6eb7389712a31cedb5fcea7afea32074715a9eb97179066c766c5a9288e15ff52d361ec26e78be9b159695cffd2fc6cfeb2390f9be3d8fc039bdb9bf74c426c9dc454b359712bdc92676ba6b675cbd630b6aeb1b5b53508b6b6b7ee9984786c24c9ca6763e2b1f52fb9cd3b9b8b3697b1790f9b7760737bf36712d24ebbb637fa4731b6ef6bcf7b2b2eeb3acf8e6e6f4c426cfe4c426cb718b7ecb4f94731362621366fd21cf8fec334b6d34f5a7a99edfba4a5d1e63df8fcd57f929886d89262bf44c4d6faa5d096b4f436d6d7e797f94f12d34d28be5c3ffe528e0d7cfe318969664b5a2262837dd2128f2de6976636985f92d9c64f5ae2b179335bc741e6272dbd8d7290f9cc21cce78f215d1c643e0c297290f930f2c541e68fe4c821cc7f91321c64be8b8c7190f92239c341e687240f0e321f24652c647e8bfc38c87c16197290f995ac1c020799ef91351c647e47de7090f994ecc141e63be98383cc6f128783cc3f8a99ad05e8d15f8a6123494c3c36ff256a6ba71d7dfeafb25addf3879dadaed70883f1e78fb111262ac34698c21936c214e3c146986e646c842987868d30e9d8daca9c6684a9deb011a6b1071b6192f960234c6febe7c761234c331b1ba1964536e276ac61236ddf69f3f98fe86c2a9073ca6e0a89b1ec9e3a29f1add05c14ebadb00b4e500714d3101bfd9b9527ffb137b732886013eded86f3eccd7b1944b0b1ec0de9082a64e8ec0d034a503029b18226ae6c371944b0517b3b52c38730b43c75c9c1e6f4bb4f5a0a6d5e8faf55b79f296663799de7e35bd489aae3f134f63c62ddcb4ce13ccc146da2f65dfc1b1229906fff063ef9379b07e9e76ecbbe86e2fe657fc3ddfe9c8b1c7ccecccddf904821e667fed6317ffbfec614b3f98714eab6573914cdbbfe0675fbab6ee7d89bf81cd8b7f63692f6760404dfc6de68aec6dea8ccdefcade778d81bc7622f636f74caa7702c6d82c9be656fd487a5b4875dd2b1d5677d39e658f5a6e66d605ee4f1dd7a98538beaf657279967395131958dbd895f639938ad7fc6de50705a7f8cbdf138adffb3b7251ddbf7a1bd5128af72a886a2b15df53cc5e3c9441e33cf637c2fe6f523d46d575d280e21c40b47257abe100422480d636ff0b0421925c6f9bee3f44b77770edddddd8180618e12351a86620e3a345dfc10c3d02592e0e038b95d25d205e1be42100b1a1d43590c66b090470c1fc0843de0f020268c3131cee79c58c8030b0732618b0576266cbd80e411be154f65a10f2a7068c287818f9a3096450f9b7044c10dbd0963399b1ea10f236a7c846710118387cb0c8be72d3223e390a9537322dca0508e713e75777797c1096169c4ea87231731950c7d60016343191630ca41f82d8d342714a35e1d842010aeea410802217e10be72086761cb0990d2c2708c560521fcae60fd087d00e1e9842d233a2021521312e37ce7aacb5f1391f07750e37c7777770a24a470305bba13864174e5093d2e6690b053639ceffccc3b406a3a3f40a0cd3ef0a0831c0e2cf9383e7adcd8d4d0c878ccc8c46260785c43f3eada24e1b93eaedbd202b608af5e3dfc3aea125fcf2292f18f34c82212d81f6998ef594412c3748c7d0ecf902305402105264fa618e1926653cf3a4bab95e32d5a9ae6985a9a6696f6d1021391cc2ae66c82b7cc288edc1614de64ea59e3dc0027132ea97d7c1ce793771daa00469c3052654a1b56538caabceaf0c1881025108922c2021339bc3079c2822b8e26225a4c1832c5101550f0d20585145410d7984943b0a0c043029e128ed0c152470a5042488615cfc4a5a053021d223c7610e11942045ca30d9d39549849319bbd0c669f336bd54135f322811c26847264630d1e7cb0caea773f4b4452ddb84e2f483a2994735b767eeb33c1c82dd2a8bbad56cbd69b198ce574fad6b784e8a72212f08477f0c90d15df4d8cf5e54d7973c1564bd602bf7ecb96e07f7fc46364949b5b3ef944245f3512c7752b747363be18cb822c0aef5ba4904c268bc53e161945764b16ae7ffdde1391781f8fecc278304484622808bf450ac5ca5819bb2d4a416e9fd67b6194d82d85aeff4796fede772292d0bd1cb742b10b0b613a53c613bce8077e39dedc502af47e0fb6c872bce00bfcd7d3fea14d03fff5e10c403877c07f3d8fafffc872ca108f4f45242f6b44ef28bbe3f82f925ea3f009d7b748a1f00365b2da7a6f916578c177b20caf0b7cd7d719803a77c0773d8b43e1f56c697443f09d74bd8b485ce183e477757555c70dad5078c50767e822e975d156f97018f9bdfb1669e4d73ba8919d9c2c67cb967f5bb29b1bd9188b8de16d7d19b640f0f35bff48b3482a2db2acb7f54e96357c7f3a03c073a7a4b7f5fe21c93d6bfd1107ed90b7ba67916595a1d92292eeb31e299e403b6a67cce4a00890bf2231f2cf0180ff334aa9fd2029891f1b500308aa314b07738cafcb393594408063ac76ccde185d7074808291950608368ca3173433466f8a668391750508698c2214514fb33ad200c20318a4418307b934965890460c52e377830fc8183d393ec861a46f7840c358d360638c0ed0183b30406862ac5b7800c4c892ea800553d0e2780206682cd102348ca08931d6343ad862a4657460c6c802c3832c63ddc28df15b0108478c314e80f0c4c81ac1075d8c303efcf8800e5acec0b2c6194a5db8d8f2410f638d0c3c9861ac29f062fca2e8e089b1b5841523ab08da0c660c7141b0327e977366fc70671c3043cb9d9fc3050f6a9871cbe761dd3c7f09fe439f7f8afff8b3cdf3cf9cffccd6f31f61c17f68cf38cff6f5fc44fcc7d5e3397cfe09e53f391ffb98e757c17f609e3d781e9f5ff6fc28f88f8fe7afe23f33cfa408822deb05e19bb499fd07dfc177e48d55aaf99bf748cbc1dbffff481cabe475f0b3af24cd2a75f7b407c91cab94f3cfc18b648ffeeeebc3480fac07effd072f439256c9929ff33c481f568926f3f56948259b57f2f15978b9207c4cc7d6c3c7dffc8b54f261affcb02989efe36bbe5563afb86c386f639568fef537f68a8c4de9fb9a97d97cec5b1f432ad9c4fee65d37effa98bde236251eff7a16a97463afd46c4ab0bf717deb29a9e4b25704605302df47cb5eb9b129b5bee66dec95984dc9e6e9c3904a32d55ea1b129d5aff9b657aa4dc9e6fb9d66af4c9b52ec6f5ec65ef16c4aaef7f19dbd02635392f9d7cf904a337bc5c6a6d4bdcd07f64a8e4d49f6aff7e04352c9037ba5655382f1ec95974d297c1fdf81bd42c4a6e47dcd8fa4921525245b8ebdf2814dc9e6fddf5ea1d99466fec5fa7ff227a9c481bdd236a5f16fde8a1292cdda2b03b029bdde87556259a5f19560af04f34ab18ff92bd3e6e3497be5c7a6c4fa1aab54f357a6edadd27ca57e257fa5eee9e3904a3656e9cab4d9bc0fabe4bdd2f74aac9fdf83548af91bab646395645e69e69578bc12cdcbfecab4d55825f095c257125fe9f5ae3fe2209047b94b43b2d3f865e4cc69fc3c48149cc63f4356711abf0c399d9cc61f23abd3f863481ea7f1c3902a380de734fe919c4f4e637e1749c469fc22c9c469fc2139999cc60f9213ca69fc2d52e6347e1679c469fc9564c1694d4ee3f7c819e534fe8e7ca7f153b204a7f13b39c569fc4d4e2d4ecb398d1f691ed1ba12017283fcdc73c738c284e25abf0a5cebf6c058765303317ee397b381184ba6fa619cb7ac138a8b14f10f054dfe8f6a4e8f6a2fcfa45d62087e3b8d51dd62d5afbbbb9b54e02245303f14f47abe4530b6a9b856ebe787d97236bebe9c512b98ba8d858bbcec7f2d8e9a358ddf6539b4207b5354546b4671b5519f8dba1dc5b5fe26b6d591868061b3aa4175db73652dc752e6e4d04bfc21309cf3f54114ea5f41f4881b97f841f44926065121626010751abd20ea43cffa893a5b06512d3deb328836f5accb8f36d1b3fe209aa567fded14fbf7be7bfafe9ef39f98a5514eeb87b1ecb40e46479bcbe572b95cee874659772fb7dd8b7b712d5ab468712d2d56fdaa5aacfa55454949494949b5935454545454543b39393939d1262ba7282b2b2b2bab693535353535f534f5f4f4f4f4549f260e377113377113a70277e12edc85bbf0f0f0f0f0f0f0781dad4d342a2a2a2aaafb69136da24d54ae2ef234e322e00fb59c862068cbefd97ca2962d6f7a36653d9bb19ecdb167734eff30ca25866054944b0cc1a828aa16ab7e54542d56fda8a85aacfa514545b9c4108c8a72d9b28ab61cc3a81b2515e54d2d56edffbca9d56255fb7969b1aa179d5c2e97cbb596afcb75aa5a4719ada202499d5b555555552555252525252535a5a6d3749a4efdd3a98a95959595150a3cc5533c35f33a3a6bafe7d3ea55fa51a6fe80538db2060093d314b79c5d3ab2ec926b531c8173458a3c5abba9fba0f97c51e0daa4f1cf6c62f1cfecd234c50880203272a4b9eeb41276fdc18ea47736f98f6cfc88fa0ecddb3f9b6617ff91c9c6b1cbfdbc26a70d5cf3aad9e7d1ef1ec67276995daeff6c721f6532dad44e1e0c40ce017bee1887986b1f0a5c842f5bb23d307a141929b841e1d77cbf47d13e6590f83639d7df6c797d0fa9f17d60017b9c29987f2e314f7ebf77699f92af626fbfdfc5689f3248e639285dcbd7e780742c3debb7a433f5ac9f243da967fd4f3aae67fd3864fb20dbaa67fd3dc8be21bbaa67fd3664d790eda56773d24cd9e43167a60ce9627817e7e2538e854bf916cf79141ee53476b716b0c5aadddddd44aa8f54d6a19792bdcc5cb3e03fb58ea34ce6e57e2587442691d9fd50277573924d5cebff6c39f3d23ebdb47be9597727f5ace7979ef59ca367fd234c25d336960e8ce5f40282b1e78e916f0a5c643ecf8b4596cb392c926ed95e5860753d4bfbf8f45cd3ed7ce1fc5318e2f926b2a9b8083b55d3d7677debc1ef20c6a27ef7a74ced1334ad479111059628ec68ca65d9a245ca072c9ca684e0f2d43e41dee58a1ed13e412ec6d5d597ebdf3e8c657b89baccb5efcb49e54d5eaebf37799337f984729affa4f3b3448ce564bafe93a9a96758faa7b364e99ff6c187fe692184e89f3ea29be8997f3b8d2591eb445eb6ace0d8126d2963fdadb63af27091cf76d4f765375151f97ca69d37a93a8a8b7cefad6e7a96fd6acbff9494df1677529df15f4ad99ca367d496e3d06ca367fe2328999dd481712289930505a5df7bffd510fcd68b1fbee892c17ebc8979988f199a5f24f3b197b132b11818d8f8728921d862d5cfeb6833d163bbab5dec76a7dd77d8c25f6a3d75dbf676e4bdf72fffa6dd1fdd34adfe47acef64fd47ded3efabff512b46bfffa8be077ef7fd51ebfd975a369817addf7fd4bd0763fdf74720cc78043ee85a6ad9446b0567fcdb52cbe6b256705a7fc40261fe1efda3eefb996a6cafbf3deb8fc0ff7ea9651bad151c97bdb1beeffa47fef4996a6c626841cb2dd6d3ee8fbeaf7f3beabe6b59fab72396ad7f3bf2af7ff43dad479f773beae891b7fd0e01363f2840ea03b8d93c538dcded8dfe6dc9b3f90fe11c7d5bd8dcde965c367fa6191b1d9ab4b3f2ba62aab1f9dface02cb53a6aade0dc8ec49f792baf1a5b4d0c667481b0f075139b81195d60cc0b269b81898d2e500616139b898d30957a3132638f99188ceb8fc21f6f40d6d7fd91f74e440f1b9a97752f93592b38b7a3dab2a1b156706e472d5ad9064db69b9a9918cc08fe51f8aebf2db56c36d60a0e8dccde986a6c3ceceda8f5333198d105b2beee8fc2f7bf1dd59f89c18c2e90e57f14fef7b723fa33b1bf1dc93cccdf8e627efcdb11ec5d7f3b7a3df8b723f1bf3f0a9f35637364ec18b31f636330f6066665a395bdec8dcbc6449bf347a17dd08e2dcb2c1b56fbd9da21f4df8e3c1b760821f41f515b3b84f96e6987d0cf7f6433595220fb73fdaf7cb074bdf83cfeeb19e661cfb18f29737a46c690dfb37e1812468ea4cc458a64488e2d16890433671b20b74f10578d4145b8bae38eeb4135280c1a836241b2a09ba0b7422204e5f8d5d51dd7e71060cf1d2351918f21fe21d60fd51ffa7ec8fba1ee87e80f157d53b7bf0809d16422b6e5b39e8865cb9bfa44d596b2ef893e5bc6bc27f26c39764fd4d932ec1913515b52a9b9fe44fddedc6da9ccdc69735873c600e4f629f2bca2aefba12216ab55148645afd758040313f345ee324533333c8a643f34bf48f643343688686868841186e60fc57ec87f08f643ae1fa20fbe92fa4afa8766dbf2f6a4b1a56cdaf279d872e62626634b8fd952068bb1250ccc9631d768cb97cb9623f8546a405b862d5bb2a8d45cfa546a6e2da9d4dccf96df16d7f3efec10ced5d5d5a5b6a45273dd96df16d7bf34f2ae5b2a33b7ad6cd227c09b1eb3c8b44c33f3f26a6c280f598d89c9843d9b45da8e21172132a2b7fba1d7a532c3e2224446dea53f24c2a512bb5d1122a3befe437ea9c844eff95d9e8db5b80895f07645a8d0db15a102738b506951e94bed4dcf66112ae3eda7e2ba5e848a77dde6f46c1669eb47804c9fc8e87b7eda7d5eebf96b6db15ccf1f82a14b7cfe1136fe2bf6fc31d78589bd917763de68e60ebd2e8fe7978557e689a8d0cbe38de89d79a3d81d12e1da1019c15cd91319b52ecd1351f1aecd1bf5ad792222a3f1fa7822a37a7bfccd1bc9ee905f1c2223d725a2d217c736d7e61b7977be0fd2b936bf0749b936ff86ecb836df8664716d7e0d59b9369f86fcb8365f467a5c9bcf830cb9367f8604b9365f866c716d7e8c7c716dd66a23d7605c83e1da0cd764b816e35a0cd768b826e31a0faedd70cd866b355cabd56af3917c4cb7ea26a9154859b1245585941452725f4460031ee478aafae28a10b0ae48828731368e35a717d4000c28a83881162fae08afc8218771e6724eaa885b8eef6b744edd690f358c327777291bae63b1b9ffbbbbf70da3eb724e0a861b5ece5d41c7ed2ee7aea8aa01581241dd1e21c18f449090107fdb2877fe5123cd1e01acedd34dd6f993e79c64cfb9022e5cb8542e5c64df5812b9a38f7fe3e0e978f6bb9c9e7161755688e77a9ee7d93f03acb4769de75531c6f5aa80010c150b1876f0210926a82742d0c515705cd1e50a29afbb2e2d83c7e58aa4eb793ef4522b1db9e08d29b810e38c2fbcb03117ae250fe74ca29e2d5e688163ea06343eb0851561b0ac30e3035dd7759d155bb07458baa2b5250b261e991552d430bb12b028a55356f4205af154831532b8acd0e1735070cbe7f18cc86d69aa62cb16301a872e72d862820f6879838c2b1b6dc1a53fc271691572e8d04ab1cbb92d465cf0726e0b102ab83296fd749bca7f3c2fb3ca9b534ef3ec0b1eae8b6745c5349ba6962a4f4c3cfef37d7f49a47b1b25df69de5447da34807ef79d7da13eb5b10d9ce1870485044c9bf77d47ffb347ded3ee864403e61b245801ce569ffeedc8fbefab3df2fe85a3cfe25c0c1964c1d9e8d3eefb65fe4343701cd94f651f71e73fd934a07befbb299b06d0f79ebe376d1d3992b643eafe3cc0e33f6de3075f4f77faeb5d4fa442eb59df302caa70ab475a01e20b302f3a6883bd5b2414a6c2bcdcf994eaceffaa5ce6e9cc53d807f3627d507c5004ad4d3fab71534e9b0fd3c5a6adee7c5733b55337b5963bbf2389ba17c1fa300f635f807d7db689301ff331f685ef619e6de0b745d2b18f817dec5954e1fb986f62baf3452d777e8cb4f11ec9167bb02389fa55783debfd895468bdebfd871a70033ffcd737e026fef8ad07a7a802eceb4f5185ef611e85a4fa30e1d787b136f4679eaa386d3e8cc4d9d0e974e7cb58a8182975e7c790365e54eeceef4652e634a2a27987868814a0801f2252c1a601ad7f7dab9f48059b06bc5e10fff56c83f9b648baa70ffbef41d8b3a882f81f0c09236dfa916cf5412a2a806d49ad7f3500fcd6b7a882f8af175508bff52caa30da97b5f1774d89644856929dd6226ddca2c01d42974ada34928d9d763422755d5d0072775227c5643763cc47d9181bc7366698819513d440b5851646884ed45063e3e51c1549b0018eded9efd97432a767b418dc510618531da0428a2c7ea82148a25688e7765dd7f97377871b556429430d2f6164810596ee061afe676b7ccefbcfe83f9ffdb276dd8fb8ebdd6ee9765d47ed1af53f27bc9ca30204b77c9e6e066f94c5a8e8c0951e65e5786354d8304367a9b8b2e44d41b798428c18a618c30a8fcbb929d0b8f4726e0a32b8413abf2fc3eb799e57dff33ccff3bc8fa43da39ef7a3ccfb59fb08f15c5a1b07907368bf0da57d3bb8f38914a07f2ad5cc9dc0eacea992e7ce1c0a7077feecce2a140c714b2377caeeb4bad4fb3ec08ad50c99c21e1083975bdbc7610f88c1a9677cc1c9ddaeb6338e31e672ee04572e4f39317af7a5ce0562022f2935c11b9732d9e8c7fa87da28a5b3ac945213b07129a5fea3db8e83cb39135c71c5cb39134071cbf1697b1726f0c10447c891e3e58cf096cb43faa7daf87352545dd8e59c144997c5fe233ddd18633fffa69c1d19eb99900c9c88c1972b1a8050818d5e71e98fb92a2efd9bfee11c0e8793c1463fa77fd8466de95688675c63e45b8eb7dae6fc26c79813a3783907051cb77eb9e5f828005fcc3e77a6902f403a521b92aee58ea45c73bf8d9c7ba2897291eefb3b2e22c7954d27e9144e97a7e8aaae3f38d4fd34724e055d9e6ec9530eb502dca5560ed573c7d8cf391574f1efa4fce7880aa09ac65153b92e5254d75530d534be65e7e5fa774efe43a7a895ffb49414e788102969f5c68e366e8a8bb42dfa7ea8e8b3fec435ff69c535fff9d4a58318dbce2f5c73ce498971cbee72fd5b88b1ac01e01f87fa1ff6e11f0fa54da8c4a9150cb4899a041d536a06680441400353156030482c168e08048a26d7f80114801098b2545a9fcaf42888814a19430821841802000020002030334c0002449b3da1f71f290cec0d6a2eda91cd9c18032ff0dca5a25b87109f947ed71b47ba08981d9bf2eb8274611b9bb453e3e7ac8da1b052cda092de2ca54eb20d304da0082804cda4a1f3c20b1db431f06a0187aaa837b4efb965f92729070114f4bcea59b995635e6ab964472cf4a36ab4b19709c2ca9de559662a421ffc529d1a7b238b3f2aedbd15738daf14666fd4f24795bdb76256f795d26a6f84fde51b60d7db9446a2d08e90226a9d8d122b1a6cb88ea4185e8ab8e828c0b547bbd13679d2e8eb62008f3df7c003341b2a56a1313c5bee8c133f55ef2b6be3a8f64de1d95bb8527d6f859fb221f71f6bcd8b6c8a9d7e5ae19cbd1d83b6ef5dca812c912fb71f29ccf63e3881fc2ddb5d2cbf8e2013a84318cfc5ea0ddb63bb22e7865cad61f213d625e0059b3965d0d0ba019f1b9c8f463543f237858748ee5ea3cc8ce2e9169db250f69c42c4957ef25f05bf927d337805e7a9c127a68ab304437b4fdf1cec75c4976720c5cf675cbc7c9600104ec31deab1daa6da90ea2e68b2d3fb183b47fada1739a348859ad424dfcd9b5a51a636050bdaa24005bb3e09d32a06af898c3ed46bd7ac2df71250bb69135da4b3230e9a600952a3cc8dcc1ef833daf8af458999fb360a2a0b55ccab6b747098d712665194cb54527b1c476b4e091333379dbd6d06867ef58142c14f115b2b940d25b4d25e5dc424683aff6af940c398b7e6d19b796ea7247d57f6f1b29f5a3042643962d66c46aea38ee900a581e4719715dac6a44d115c8616ed20a5c64ae32713d2162995829cb618dba14a67e654b9a7aa0ad972cd3565b969a3ac543a5ca6a717047923c352c8baaad3acab74ac18f070c0da4cd214b5d89b3bab2805208b9e7870c36ad252ece6816850c9a571009a29569705ebaac0e73f4d13750b574673759a8e009465223fd72f4de9a84d861936f12ed4982c4395d1424c35e51c48136a3bb71e1d79b70b521edddfdd699a24380f1faa9b9e956b7b3d41859a768f66a9d89e720e4ef1c4423e57ef896749b13efdcf6ce9e1356c06ce10e06fa93e1305e565f67da0669b831e088c05fa2f19bc2ebf67657f7d691c9ce87d1f5761c8bbe256fe5cb3f027af104fab7322ded5187c0c5e42ee42ce8a270b5b252e3f050235054a7b7bf28ab5bea6c6b4f4964b56e2cb65ff8d2cea2a8a4b3f71ed05c0442127b2aa9aa3d5949d533991365698308826d8568c9a443f916060611e49de48596136deddaaca8651c4e1c762906a01a1b40da9f7888ada2ba960e322b592daa3de0455ba1582813a54d77f8d896cf131506088a9bba9f2e218a5a46f5ec66a4faf1697b1753c30fa2d759189369d38b8d6059246990ab474780e435d3f1772b935304f056102dd56386b9372ef6b781125778254d44995bab3eda025a1b15072bad43cc1afd5682b16ce25195ebae8309c013ed5bbfaa9c7820349259df8681249971dfd2c01ddc3db884b424f3a0126be38a999dec88aa3d05b904b4bd83d2ee6043c1d394cfae52f77a340521e074963371f336152fe576a72774a16cc67fe0188393e5257b75f154c9409184dc7882e8e76c44c617f8bbe191a9eafe4d9243cae15e21df29d5863ca452ef3245a288ba66b90922243c5425aba5c8c845af81354dfb276445e7638df27521ac547dbc3cba9a395ba982649ee347c062f49167dbeb91b7d93f4daeadffcdf3b893749e28ea96747a2251dd12dcddf32d81258ac5e1626fd71cad511914d5d789326ef8c6c39e122d373d120c1974946253fc4bfb63eed5e467fba65f46440959dd836ea6d27bc4a21e599bf34788ad8bd92bc90f8902deffc3049c8b70c9de0629f23c561da895c73531c7471978f3e349ec1402aaeb5a6420bfec49334613ba38eb3267466eb8ce8d59adf4b3e7fa89e2274c0b2c1d5e34047f6fa091d695fe9d1064ba530cecb62fcef245c4b8f43d09f1cfb284d2456bb7aacc819ca1888b7dbe2ca0ff83c8994bef1da1806f9c27a7ebb01f4066e489df2076af97793f05fc779fded8cc8857e1fa2017d627eeefda020eaf90d931dea0bf2ef799e2b75c10b0f8c339059b86124a8db6a81dc435fb43b9890082202d636438c8a86aba073f75df8e3cb00f25ec6f0720a6cd342f71ee185cf3ecc02d4534e7487cf64be6feb6ec18d340400426452f811407ee619e2f0a440bf0d20f1252a42c6506345663530c1585405f964c212073a6ff8b86b0d61a2ae9c0511f5e57ec7bb433e6514688a56697d15b4c70ba4dff9ab8ba44f7a83dc758e4cf30c54e781d89513d83d6c9915014b882ac53f346c1c4b54bdb424b3db0688c95498cb9cd1f3912197cad54afadd7992b8f40e38baf374eb32a5e899740e46de3a43a8f39bfe7c9f77fb734e886a2212d4c175032075d54e4f44663a096901c81b5d71042a0f83841fc18dcfbda063064b2b09936097c6d75db9116b120847d2f7e01baca50e9ee5276548f69e0b460954143ed52ace21ac28e0c83f9e3d68202df581b25a558ab3dea6f7903571f32706ea6f46e7d1e53f6d15283d8ec329093f492b9eb51e5911020f4c6275593de84cc4fa54886d513dfec010bf4ac8111316299d70238b13cb64835f4849c7656d2e0a85cbaf474a1b9ef97cc84dbcad93e7bdf19c407ddfbbdfcb660f84cb303a705bea1c8ca65fb7955df5a2799b464b5499d4ffb010399475a9bf24a1a5aa03ef2c7dd2742b2336842a1b2c0ad87730a7c4ca3f80e15e3855f446d650449477629f313c4f6fb4a4217a4a3923e2f24408ec1d306fe55d3ce2f2f74536516422b51e0064cdd56b59be5baedd1e0d3f181055d0133f7cc1fe93eaa5410f74a11b148f70902a9f4e2676a6b4ac09fe8adc5f2a4f92aa5b8eda56735b937214772fda15e585d2c2a28777e3e755039e14322c5e88726dd471b446e35431e4a16d93141a72c3cc5fc1e0ce7731033d8ed114ad8b28fb8134a6a282c1fc20b6c5bd8caf1dc90d42bb6a4b01633d71b7b117faef2ff0a21c6a04c3e80736d1bbe6e843733cfd43091f91d2457f54f5355960682c21079aa9029fd89d215e307f6a4302057a57c42e62e034e52adf29c32f54f2d3d99d80053b9635ef497c564f733fd658c2b2819f189c57e9ab1ca23f1f2edf474eabbaa0371d966c29c6a30ec7cf09e866b7f88dddf0491ded82d9750976336d482c070633bb3b74b3fb1bd64564faff999dc059947cee8bc9d7815955e5e7a395c65a9988e184cfa2aba11d7a67263257d80c86466de8f6608bbe5ce27fe78cec69c143a2f2fa3064b76765d5c5d29e4f467b4d60793bfa8711d61bcd37bd612e548d115f7e3601fb39192e1fc068ec54b4eb8c9bfbc03f0d32c346d587193b8ea03f89d7c3b0388800ce66685019b0302d438b54cda15e038f79fc73f15bba5e4eefa3854b37d6ed5b9871a4c68d574525fd6e5007eac2a7ab425f0f09b43d6b8bb407bdd007d57dfec15cc52977cc66dbd6aad4cf6ebb25c7c66c7477729dbd1e4102b4911dfc436e9c29b3aad343aa41ef334246749f382e62d8d479cac350015db653088a4e93b24be39fa1beb8e1add7776c9826d28c4e8a96d554e4e62560277dd21e413f73e700c1b10e90a442a210b5c402d206d083c21b9b9a166ce94ac1f82a51040b1f3125afd009698a7b3faa49f4758298e68b352fbaf599bcece122f88bb819e604cc23088b88bd725c06333d184a2fe4285c4adb755ee942c78e0dffe0ca705cd465f6cf41406053e51ba9f5d14894bc014deaee964462db16cd2b60296041e8c4028d9db38eb6acb9a1451d6f72e963f8a96bb4ca7913b7e16a174162118e1d94dcb0593f660ee859b9736261b26643ce67ff9f7cb76152f0f222db9042a421a9d4b642938423414faca9aafca9ac52a4e42fefe1fcb3a9769c4daabe989c05ddc21873df5c3296475701c66f8e8e05e3e4626b0bb90c5c81913b61afcfa5bed9f78b5d667473e9752ece61a6b78bbdc0c0f572d765d9e2566c5112dffe7a7967743bb8568337ee2c091e2cd153c350a1ef642ca8e59a70b18be35a73b227334de8796aa5a5f908ce82566553f0758566843c57684a09a19e832946a089080e73ec42c0e15dffa5d3fc3a22ed6eee702894ef04c694441d3882bab5e3b19b77bb39b9134f94c88af0dacdf39e785c32ce9e98219758ee795b329c4a3283c89609c765679600e120e0da74e43590531452a8370f7acdc890af227ef833ed3f89dd90c8c4212c55c15753ebe2d2d9f8d70034966d14f77a869443d5e7dd4f25387ce285d9fe78cffb02122ba74e6ec3d7316672bde6f746497f635c08deb205c8fba9babffdf05937e10c0ce4b7c43971ab6ccd20005665d40581912a831504cc53d99e2078a2609b21aa271506b5435301ef04c6d6457862dfae833c81651b0f1ba9dcc52a791f2aff85393f5d68a7855ab398698775e08463158fb97bbf52eb4ee24fac01c1a5354f3d257ff4745dd952081fbdd08ea83dcd92f6ae1863a07dd78ba04d4290fed64b1c6014814cd81c90ec593fd8fc8c9e66b6c4284518ca65711cdf049454e5a59a16f34e93c1fd23c2445da0b891957c66f9b7466cbc1fc32b0a382351bc5b631b89834eddb2a8d35d2c4f2261733aaadb940cfacc87c0403e7d8ba238d3f1314c24f4941115f54a5041b2fc58816ae3864ec399039a91f8502577fc5e9918a5c0e752ab49da983b4b752de08a80bf1d76cba9f556393aa8ee96a2d9d76f3a8fec390782b9205334370d4f25d0f29510e2f471c6684044fa496ac299c91e9cf4dad132aba8437a109d4b188b6381dccd4af3d725174dbbca4ba552a85440ef9cd9a2a2ce1b0658827443de4eb17e69e3ebd75c3eacec4710b3ee4c188d391abb468db4fce44553bfd415f77672ba125a64755f54e99547dc8ca391131c80eb8b647d9f2b18d07b17d015be5927b2a40a66bbdc312e16731e49afc6efadd90b887593c8f0b8ab7c48a8837d2918e7b9b2ce4b12cc5211481b78b474713c641762d99a8aa0aa5fb258a62a393fb6320e78f168251db5e5b57aeb0d02ea9adcc80d00245fc80b9b1000f99ebffebcd30bdfd3fe403aa53a590a57f94ebb7d4511a1e9e0442465b695f028e6eba26cab08cce4bd653d01a2494db4487a3dcdc294f84dc59c341ce6f57c976863b57e1c376cd23fea5c09ae5ede3444c64404597f3f3700f12dc40fdbfcc89cb974adddc12545701f469326f207c133d0e620693202b01a031c8f102835953a465db484773104294f553ce22e39a560466b228950fe8594d689cadaff46a6b27f4e6e6b26313ac6365b1a27268a86e41bdb58d392abd83920819849a02631c279e96adda9889d39e3be786535a4ead7082aa2641d98820623ef3a77bcccebe6adc609d7d2eafda7efdb410b95844a8542b575d27ccda880f4c430f8c40f9ca179b09fff92163c85214f868e9a91fe9dcea6fdc336d507b73aaedbf3275509a8ddea008f3a04e5847b6ae6b006c7b4655231cc72021e81cb57cae946139c848cf14f3eac4f842b16b066d8e2354def71ae1498e3b6dac3375d7f1653a41de6187acfef508754220543135350ca52ba889eabb99aed267c66d7a7627acbe02a279711a81bbebaf5eae1c9133973f49e66f9c6835bea8ee90033c0dcb5a3dea5ba9d7c3a65c454448d6eda84c84ecd37120b0d8e18f3bf1491ae04dc9fb8a980d92486aaa7ff1795f166f6ce68079ac865491a2b63250b5eb7728acfc0968cf9f753ed242c871a6a4d98c43393c93d281ecf57fe38bfbe7df0bbf3f5cdd764dc7cffb471273a2c76a9810446a1c374f97bc526978649b85703a35e6a6e02429332ac0d99f08a41bbea26920312ce7a72d4ad4bcfb2682e1d1de0174d36aa0d34abd484d402463d7916b493b31c135971183a4214ae08f2ef4c8d5b16e2ff523225e1d5e2c263d71fa0b1e0e2b9739fbc53e46261cd3e6f7430c2baceab7dacfa6e80f3c78406efc56e47a642c4de674c8b5d7cd35161e98669cd281daea8be38ce44a3a790012e4e78f2da5c1c0ac58c0340db48d6e7a1e13255ead70dd2e4a27c4d3af4bb7a517290d679628884204515a079c8ae88ecb4681903a942059fb88880ddcb8d47415132e20251249bd05aa612adaabd5cc0832e680c9faef141a7ee4abcf6c5613159737bc49cd19fe629a5f1be80b35cf8c79d78d591a96cb121569ae5c61df116e892e4090bded4b1b15628c1f85e2831f5414c8d0aadd23e8950c7d3694885a57ace181a0bd4b93dd6742033b4b982c5cce4c66586c3f3b1f682a9ef939a64b197e260b6c5edfc670847719916f30c7127d7b410344119fa2c0af3f72066cae9a77af860fb5ebbce040579efc9174301ef5ced5da526b5f20689a7905da5c733fcb7f638ffe874cc977a9d16eabcfd6f82734be5bac2249c28ebcc59e54a2bad5c69e546c0080ed310755e92eaa5a74d9537f8921efbc44ac80fa2a7775c46ac323495bf245eec0a02e64b99e2e6f0acc6f7a2625bb6d81124e2f7c857d09d08c9f065f0d70d78e3aabf2c8fe93268e87915e7121768a0c5dae4a80b502002d86d462394dfb084145326330cf6ed07196d69bd5ce3dfbbfbc629e78ff792c4071317a6dd87cd79fab4f436a6ec909a98233ddb29e058b802a16b4c66d537bac5c8aad17412ae3d0c3f3a4f663dabb21d51b393a96c23e41cf7acb5d10044a7e8146bd97e9f43dba6bfb67fefc076d7826dbf2fc01672e0762c4708c5cb2088307d946e52d7cb124cf662a0cb003702adaf04c0345175b811ec78bcd83989788f4e1b4389789fe4dda5ee4d74da8d54fbde74852312ea0c790ec4ce2a98a419d4b735def0dc3f20e6c0177c1f676532c82487b1d5648541255404d0cab3c6bbb9483628e098e6e823a18406276b89152fddabe3ab79a3fb063e06277a710a31197a50d815da9ba850d8633da651e85bf2945d10f58d559a9eb2790fdfb65c841e04bd5afc866cfe55bce1dd1738d1d2526e04e7fd7e59e1a35302c3511cf560c8fbfd080e1da8b05137ebb0e1ee3afc97bf49fc18031abc78bb60536b59514be897565860f2b22db46d52daedf17e0476a962ca623042a2a79ef79b8f2815258014be8610c01b17c89c7a5111ec4bbde5e67255f7ff18b4ef6a23a5e2be22186c1256b5b985809773e3ed2de021e8354add2140e28e298e31c7b19feb0c3fe768aa8c33f9ff2c6895f2fc12c01713c7147e1ed5238b6f429e70f6dd475e5f2f26645005e23ca1bc15f2872c9f985331550a198863031a98da57103656a596bbec59350157ea33a60d0428a78d711bd6a807d49371cc728c1abfb8a6aae18c34d0b2b36fc0533f4c929d6d01572763904996ed490ff3f41c37a44fa6eb8993050330e71b5463223bd8b53788cf6f648d7d2db560290c1051e6450723fb978a0c213f0bd1af931561c271da4881e8397c02f79b1a75b67db28d6f6f20051bdda420fd7c4612b20a3cbf9778f96301c4a70981940a072d2f16feae28627b44a64981e84bd589c105d1406eacd04b583fc2d78b2162e5c2b6b32026ca2794d38464d52211b47f2101ec587dc58e470e0b8bcedc70e31f5e02e2ae12d31f99fbe766657e943ccabf125d627343edde9df62e9de6a5b5838121e3f9fcb21d66a893986b295dbb78e95dca72a153110bcbd2efca9f860203b717b06e1b2a2640dbd133a3c80d3b7f474f176898ceb2b2772e0dab1f460367f61d11795fa715b91d3f17e507b47031d7a432bc7861d1f45db58651491bd0fd197a30a51ffff9fa2ccf40e934aeb4dcfbef2fb76d4e74c7233840be7bb858202832b39cc70328959c10045cbb234e06a2c1281acac44e7a2f84c7f7fa30f4308bbd045612a72f1377d55dae2ba29ef36bc95c195437c1a2cc4313c5528f6790c9120f38157128e41cbf10406a72b85e0507b7e1228a3f2a80e6b85d29554fb1872046ed90deb2d0e170023928856dc52f3671e60d928cf63edf42886fd2d4bcb17359f59a07ce5048edf58f6fd55965d770220ce1fafa445a0c11ddc30c271540d3f8135d170bdba4ded555d8ad4b3534296f2b0a762da4bea83d60d89373d5c742bb07c4cfb76c0b823edb23ecf1871ed27300461a3d38e360ee80d2e338fca6ad682b06481e8e83888d758f9c4f37764f83d8ac023944ead7e0a5664559e8bab6451b120d42088dce7ada71cf4a1c3bed6fcb48193d39482b288abba24643bcec7442d5759e9b3094c52dd1a1390a166713d6a0a37b3c7350481b187e25d71cbfc1feafcda1eb22b5d8730dedcf9be91adb6ecb16144a25631a496c5c66ebcee41d00b4640003eb9b1d394f5f8ee79736e2929ce3791b1cc3df155e6dd80b2bc7f91ad13c1997874e15ac12488acc3f4b56d50582f0423087562b03c5e14cab16d17910cd795ed4c93e496aec1c8e42b259af81988b6fa1b51a5e488049e14d63290d30463343ae3cf120486af08f1c0f37fdceaa01ae14858b4a7b33a1b33c1a12588bd226edc4b4b9e1950f63c6c1b91ed74cdcf08498cac054231dfda990740021df3369b6b917e083f70bd4650c5f4debbf50c304c2c02920f1ff289abb20c24c23f22a7fd0d09b3913960cfa389173cb50b1f33181fd6abcfb34618c82a073353a14dae776fe127aa44a747296904b4dc0cbb7d2462e042552d0f9a7770e103a780df978a841f8cd6e4d18a91eba4e27d15e4e2bbb5fd1ce94b332fc4737a572399f759f2d2de70d92bbdbf391252b54d4f9d2a85d6aa832c5ac0f259bb6e013ba2f6d387fdefbe287834c341e91eaa162ea5470ea969e6aeacab5edc457b0bfcf526f0be7d998d3acb54876ee31fe93b885ca08e03fd1101a9f6283b664cd8b66f7ae81af8c330f168269a3a00a2c0835be103c2365db06607e1b80df50733be2f24002d1af85080efdf2891ce24b98475708d11c44a9ada84e8ec23e5b6540f76a277df5beb0078ff182e145082c0b48e70b745ad2651bbb70bc8e4a44da8bfd261341f8b1b9f0eff3f5bf8f4cecb0fe8637b6414d0fe7dede56801b0c153b3bc732fe6905419785c47e72f5c74dca782f222d82c987d84d46c3f83849577f2f1312d9f7c43231455d231806b26dfb51d8ba02fa1be8a6899e3eccb2f5296a1ce3657f20cd4173ab6d5c6642f29621cbff6f5f3ffef84151fb5da5bee1f5de807e861ef139f4b5d0c8eb07ada9136931878d4dbab9de4a8a783a8672f17e87d089e3d744b63154270cfa78a78fe1cfa704129f5fa478885f56fe8e6cd20e377c600fdf148f36798aa837e0bc17ac305960771d14666f739edab5822869e9f5131173b050a24d269c7bc12eef2af6cfe83165b10677ec60f740aa0e14e8edfa28e6412999eac68e15de1d1fff9b82492156030b289ba7836893213fde4d4ca4d6489c2133a8332edc8f8e483452c05ab127846b65fc5930b858c4f6fd0adc85e18fc675aeafc65d9b9ced088ef36a8602b422833128d4263be2cf94612d8b6809da3fc68f4611417b55ea332ec007171df88497c2d16f589402e30bb79ed859d31d9d83f6904bff7f2431e7120b7517bd94dc57fe1ccc3965094d4c8e8be8a2e5481b575cc5ec4f76122c0318b34f5ea50322def9c366a9a9956b9089d7326c330655b82edbad92b26b29f2fd87ab40b833cdcc711dfc62f9cd7bf9eb0738d4cbeeeec7ddd4b6015639ebc1f7d1c01f716642d54edbb40c3a5c5aa960a7dbe6a063966885fa62d49b28ea00681281ccdce548ebfcbf26e751f1b299a8dc3c21023195d54d3347bd3ce61a69da8605f89c6d161737efe6b5e527544cdf3827f3e62ebf33a7d7520031b79f3b8967ff40822c9467bda6d2bf3c06b0e5b42791c3b04db66ba7aa48f10424ed7cb763ab0cffab6af5e679af3183869c74b4e2f63d2ee48f26712972c2d4e1e4849dc4c75f7a3100f5a165f5e15697dc70a5a3ce1f9d3998e8ee3e110c87ef83a5fbc2a20f64abcebe87293ac719fe5b20ac2afcfa7dd558e9be395d0d972a074512b12391d7a856e1eab046b1542cf803f928923f0350a1d76efe4800c91d65eb9659b051104f7163bedae3d2157fade540eccb48e49522780ed91c88b4882f1e6d5a9e4e956859ef320223ea68a57c7bb565981bb56086007e70335f42c08ff6d1ce6a24850a91251ccf43e9b9617100fee0f149ba9b3bbc944eb403286996ff9774228e77b6f9fcec469e0a3704fee9f7077cbef9c3e93117f8cbd5d915b3c53ad34a76cc7decdc8fce33cb69fd1a3db3d11f9963ec58c302e7288290b5a3614a0be453e048ac50974dcbcf9dbae46a11a2d01ba9d9493d386007defb4108f7504d77601c4925a6daad1c5363942e014ef97b2e7dc4a6bde641f4abcd86c5c178ccae69e39aed0f09980653a7d598a67d87587c06110e005a754854af55ef79fdf2034e5efba7bcfff842e16cb8ad4f524331a30ed6ca4b7d121bc637b804f90307a5c9175644db5e0917add4308549dbd5e51a4b45a208df16be7b50dd54e58545da5ec79bb82174614fea40bba4e5433357ff87c143611e007b7ed55347838820b5364dfd7de952e6fd5bfb344420f8ecf3370f611f1b8ca86c9f1dfc5151f5c3b3de30d55ec60359d2292e926c6a7595f5dbc7300730539f47274c2ffe43306cf8ee6bb2b18693b1dc4095bda26f3360a7d247ec03d03693849c8e3f91a802bad6cc4a9a4620f93c0d3e1a4c744c6cccc1d7a9e955431c43649497d61f3d162d53379f79cee4cbe6bcdc2d61751f09612519cae44ba28c9d9c481806c777a2070465aa43dc7b50ad106e6dadf39cd189d95d647b22a8ca6d931d7cd4da0bf9fe28cc59e705ee3a7e3368e5df8e746a0540ea25c8e769f6dbe1d9b5ece225b7c796066500bf6ebc057520700e429d65a4bf05bd72cead9948242ae7131f21941a627a08c6ee5635749207777ec455eefce4c13a8e956b4509c4a88bb6d7190c73399899730719b5c97974cb960cb578e885a1e3d1e1099dd25a1565d2e3cbce28987d10a8a7d9125c41f0163c50d7bb3bc7eb4a9bec9cc4facbcc08e202dd50f820bd081f446fe007d35b7c60d01b1fa136a46e92cf79aefff226dc939b539589da8912f1a6b4481dfdccad4b23ee88ac7312ca70d9b3f2073aa1a579d8fe7573bc7fa2bef54c696c6fdf7e78d4519e4c70c0c24eb83497faf40dad191c6e70faa3e93ef1d4c0b9eb43ec8716fdaa9ffe9f2dd04c99625a72e36f9ac234b0b681f406702964653482d682f1f31fef22bf1fbfcc0abb32da30bc7887cd6e1080f2d610fdc3c070a05da2ff98797c02832842b37a31486af908247de748b1b685700e2429d718f46ca2b34d19be94d8182562464ef17dbbf66dc9a516a2ef0715879561d631f86bad67db5a330f5d3143db4864349b4e5e439e6a145353bfca7928f2feace6eb5e4f935d923728bcfb8b800028ef0487a83fbe1b680b9a91fbc49d1847f4b0bc6d1d810bd1501affba3eb024258d5b681c5257f7bcf598307101af3bb497916507da43ced9205c51360fdcfa0ec6f9c3d6907a49c3944942ed6b1403321c3f47189122d85e842c1bfea28ac0f786ea654cfca4badd50bc7521af9093e0bb0ce3af8d27af12451912a7e03f9ba0884a04a6f63c436d3e690703b53f8016f8b6c884824a342b9d4bd811eaa40f474e30e1c54b7ce52f91e860f07616aac89882820a69da2f20aa2f5a7e48b6ae869c82ad837cac55af7c9e5a685474730c7618be629379d8a54b4bf5d6354c2dde2d975fc749a699de5bcf32dfe13e06054df534d6608db699e91390cb95e39778d8f185a045c9a6ded78cbb8bebb23c9a1657a9b4865c78a40a224b6ca1b7e087d0ad7113b3ea9dcbf4e5c377949d01abf2c32bba86950ca4d43aa3e271cbfa86608830fed8589fd5f57021ecbd1e54da6438a2454ef04a642a9fd42f4fab6590527517b7dd68956e86bbe299359914199efaf4397ae386da63f6c14e4a36c81f054218576a384b5108b23cbe4cac271234053799dacbd91adcd74df345dce2345c3a9707059cba4dca3537d37ee0ea4cec7a8fe6a79446e06814c687a9c68818f439d39aaeaebcd3e2cfe75774397f32430b66bd3877911495c0b90ec1f01cb2451211e8fac316c1084aca550cac2d1cf43f788f935a21c0a17b13f88290c543e6931996c1e25e5f1cfd818d68f1d718a14012873a7568e4a9c3ace3871dc91a530c3f8b3c08a115bbc421eedf719a144536195e12bdd800777f408e6e9aaf1d3b1b0bb87ffc3c94e084a0819bd9d3abf590030552b44ce0fafb924615dfb78247e8c7fee88ab90e7e2fb0f2f3d0369979b5e7fa727d6eb82cbceccbe6c2cfd363a489149a724e02405120bf626e544ca0fc97abcdba3054a11e20cee642794a24f5032853cbea21072372b64424a011e0df224280a169000737dc72ca147dfb1449e13e8e677e24480e70a695a9813dcdc5b1e3b94335331815de9e233d6bb925f0d7d308a3643d99d31fb370823cab57677ea5ad136b1b45c389b3894ae5f5d2f3b31d2ebb1e1d08906819b867c13fbe7975824bee474b0ed6c4081ae26e36685abb04e98ba00838ccb34b2f802a02014695e898ded7a225c4104411f9f92120a301c48795bcf49412e8bdce70dbf5198df4dc5113a9d52dc7ba1289e4b06191ae36940f6b13dfc92f6f18f669e92e0c3d5136c18859daa4a2557298b148187e29d8705f06809d260a3e5f676e2316ab31df76b55d641610ff61c97b823ed61e45fb25b89ad18d96d9168c1be55674a901cd7174e0498f1a1959721c12bf32c59a6d1b0b7acc96e006f714aaf451669379fb9637e82057cb1e8ba710c43ed117efddc17d4b67ecbec195561f8d195d0b51a654142b29848324853cc777a8fc1a561382e3e232004670bb3cd56762ae8341344618d4d47208f9ae5cc52718b08f889da9a97e06a80f700af8dcf73618428cb7379e7c5b5052b59918b751a4f32224c61a66047a9d609ef5cf7252744b2127b7b0dcd7f4d8d13419201b06df235b024967dc87a922b4aac44fd1ef94ca98805203aced89ba43710323d67c2ffd03dc483c224fe43dbadfcce5aea24ad2bcede482b31e9ab7a13b324162d56635f5aebac9329954e1d1636841199d58b8b0842b667111739611d939f35196b8329c0015252758e78be56e19c3f1d6e7b73d4973a07edee1c8f31d9f1d20c23403b2a69d1afbc501a68c5d04a537f5b6f7f7d8170edf8dfa4ea72f16891514b5d8cbb41345bf16564761d5c89ee29274db5a9a08350f6a2952bd1a9f8631b85a59ce5d056e32625c6c658d19dbc973c83bf165489269f42f7c502bd3c52ebad09cd44b8ab5e1762a868c442724e615c2e6aabeaa3e46c1ab7e6104a9f8312b55e914184f51eface583add07f9da6228d3b514c31ddbaaca1e2c5399ea3000df3342ae2ce01dfebf17217421e038494c4b3f8a52cb91b36c77299fa336043a349a2a5f5d4896a244afe4726e94f2f1cd02e89a8cc400eca22979c08e8fbee7aa0ead455ad470eec33fc85211e56fca0e18f50dbb16823a543c0268c73bdc87d7a13ad4465e7599845368875b45e64e77f9ac29910108941c4df04224bee7e0af26808da05b6f30a0d558ff366302d5b9441918617386790e390d43dd8972b5025c6c003aea8906482493b7eb6987e1c89e66b4cf8d66a6432f225636563d47896aa06320b538703bd7233d2d1529cbe7c7ee2dd4423412b1455299adba9e05be87f440f5e14012d7e44c0a70f243ea516758995fb4641dad229c4b2df55f4ed2569830fb84e55ddc040e7687690240734c5bc05981b9d3ac122aa490e35b08dcf2cb5ca0f9c3affeeca04cbdbedc41302e1f76e456709531f609d1747f497efa36735819d20bb73efffac7e9eff52b0b59e4d3378f92827dfd5044f3097f927bcc27172a13e535873bc7ee971f36e2991b3e5285ca6d09c9b166b6b2383a7107018ab6b541699593207c7925a0c5050de446612391dac6b634082cad3711cadd66844153421af90ca6ec7a352020316d835c08861f77717622817ab926a6137490c2df60c003e46831b23ed3539f988fd966b029475e30ccfdedaa30e92e76fdaf4b1ae25e58bc6623d7b0929aaeac3d7481d9575a46aeda762796905a64186caeb0bd257d996e9fe03c602b168926d04f5b3968ef45f001c25311619ac1114e23fd8b1f382abdc0b49754ab15076aff23f4159bd0fe8d8546f24b812f542c1fab63a0b775563536c8fab6282a5450a59ba64521d033718dbbd107e388c2a55fd0e4711900eb7ffb18f10f7f17ec0bc10d484c1f998edbfa3218494f575857949868393238dd66bb50341c84409381a5c5858a3090a9a5e3b58533aaaedaec495607d3fc465dbb027d826ee187dc2d706a0e058902d099e6bc132daee3c5c5e197d20835cc6942e849f9fd7a20cb3c51f707a9caf9af5c11c19bb3a83385cc47d78e1191d231f8ab3d1d9e783c7a17147e14f2e8cafd98a4cf8f1f9ffe7b1de3e8fd2385fe6e16743bd53565ba155d8b4f40320b9581ece0b38edf24bdebc6ba75c1fcf395c07a846cdd367357e89fe81b277ba6c89bf63ea5ca94e4784b72e43615990f0c0d770aad51c735ee622927c9ac3672eb2a61cb3aceea79f601296b9ee528c6354265d92cf2e03311e97acfc850799408287c1e6ea83720320c2a0e42edff504fcd6828da11b30e5fcaa543794f068cbf16518f78073053f5056c69896d91d70b7f471f180938f2178d0d091153276065fb61fe168fec0a4768f2e52ec14dc5c6281026d6bca4897d4a04f074a38b2710160171b4d2dd41e0245ef7da941f11e1c2d79d6ca006d018b395bfc52b92cb4473910a29ce103749da71e5f1feb322497717a0000ecda2e68e412d0ee340f70aab402bc7fabf24c05ecfed15496fd39a6b658b6f098bce75a34662085a725f364e6fc72b38368ca87693e2ee25a06cab2f13c10633ad73b4610a0edb78bab3efc06f38b29d3540aa3f72bc90efa1e3bf52e0bcd928af40844e9cc78b7df1e7d01f822e608089c4007f1578090ec3b3c1e9b25b89c2b07d48d6c7c7fdb0dc4b3899a32c7456fd13a8082b44dd67413911bf6bc98e8502520b8b90edadeca68de6641375b4cb4535fa9283490fc18de9d4df6e03e9b66b13103cc9ba7d5f3536e4e8814b5d70c2f01c7fb69161128cd4aff928ec7a4ab49e6bab1c7fe7927dc7adda2a08f0d1c37391d73346781c2aefa346499ea2e5d2ede2108fc44a03a8c38166dd0c4a95162db39cd9b834c7d804c4d3ab9eb3635502deab599d5bfb95d72b59c90614a5b0d74eaf9cdfd00982b5aeaeba9ccee837140dac541f5d0f80381e1a6a9730c4f8f7e8b592c539f96e73b7516b998db9b6940b65d5a0f0221eda939af58f93e7d77a24b06c49ff53589f8342ac16f6fc94ff29dfb4a585afee9ea933122e8981223bf3efd4af410088ffca42ee334992d706f527a8d8f9989af067e5a9a2cb1dcf0bea18232260654431dd51726d2483c29add94c217d05bb8f8df072f3290689d49212f3cea2fbc337c2c0a9812ee72cfb1d7acb55f9c35d61e5443e6aff8c447252f4aa7a1c1a61c06ecdca76b8edf64881827726e0601e59b5fb844b99f7ada63a13627730e93ec90310a41ee5c744b0c1870a1844a91155f0f08c4e160f9e8ba0a0decef6d6ced168987d707bfbb50e03073924d44e4238f11b1b9002bcf11b746dce92af119f877e66bce32ede73a19bab999413994040d76bc561c893cec7801149659b8ef301d6256931b573ebcb4b5ce0df690b72f8c242a9586967dfecfd553b34ac214c3dae889f4ff465a916d8849cb108a4dc1bb46d2e4753dc85642762e9d4283287ba83db9657a2e62004f4b0d620a89cb1a8784b54e34aad099ebc1ad7da627aba9597158639a5bfc526e68674a278d7b0587598890192478083dc5015f28582c8c423d6b7df57e2c03e92f99a19231ca14db9243bf11a8bab0a0e52b3bd1d4669e67461f34c00dfd0c48617bd01416c725384c3ab741c7f9c3b6da7fd521d4298563ef8353d0496a901838de4541b4559cbd589b083a13a5fb626ea4c8c042f89535ce839ab143ec88a50e3db04b581c7278f551a8a0c88f2dcc588482abcca00ab84d498b8fe29b401bbbbfa42a4cc226c1723dd88090ae5b22ba8917b5a060f2238fb5182ee2d41fd51783b1ce5e08f16626f5150a104e8d63eb005c41916c3b78ff58b8c4eba0dbf7ccec9aa6d2ccc3187a3a3c3e57243b0440e80824362fcfce297ae40bf0dffc84b19e9a44a14ae41cb024b9744ab18ede9e9e2cac6836fdb89bfc895a99275fac83c1baa87f0efc48166f755a68405144199f467d9e57b559937a996ae5a5f18f8295ee7db7a98a459850aeed35e90a245a0c6575de32d8eb0a2a7de98741e77e219d80119beefd82086712390ec8a2a37e78aa88704aa86a250c2f91d85cfafa9debbb80f82eb54509b6bbbe00e6225374e4a47fb5554c833ca88ba7eec656e9a5a403f7c0843687d500d2e66659f5ac6e26a922e047d0d0c9e25d47b4e48879a0caef173b279536eeea391eaacc1c095d2bce4f5e1a700839dd29cff2c1a158d13d28883594972f14f4bc943dbf18c1486a472445615dbf93f665fd7422e5b5382f6b9d148d0608df5f9209313c53139c979a50c6ad89841cf08101b2c6a84b18fab12f08fbfc2ca794c2c51817d67f36a01b56cb36ad8911d2fe033cc1359926ab888be8b04e6456ecd63805422364c752783210f6ea0dbfbf1607c35e9d40945be8d54d4d7fc90e7571e20cc7f8bda3b6547dd170a3e917606cea48db513251ec0129194d1342637a7ba2387ed867bfe195e002436a2f8f93fd2e79ed9eec513d79d2a185daa39101982a301e09c7c1c225ac2a62d9a3fb42db993f9a3f774e321c6843008dd08f367d3ee56f0543be85e04438800b0a64513803b6ab4a312663f544386e738e6f443e3fc04d0a4f81269f1ce79121e9f9466cad5c5eb475f26834f72cf718638528c3e086107f32ae58b8e29b3c9b8583796e9c240c0faf9435b770d89b007d2397b2746a1d9851f1b9c9b59efeb06afb1620d64dd67687b5745721b673c94adad2a4404c602bddbb2d23658d969318f449527b0f128cac9931845bfc300420011f792e93535fd3ea2126caf2c6b864cbb6bab4d30214e246464078127706dea43bd1db23d6563ced164200c029ecdd9e3330ef7d76092a4c2806c348170dcfdc08625bcb20cdcc4ad32ad2d289bf6af7d119037f605b5afbf130a6092e072dce1beb864023a9f79c5a3a5f98dab3a65515609b404d5ced7bc1375aa94ca605f68846ac4ac88bb194d6f6da7aef92c63733af3c43c30810409578e3d8e22d31d0b06283d6924c9bb4901042a939610c44bd3feb72862b816866ad20a54de52c01758813ca8b6ac36be0c97708225c799a837cb3cccc967080bfaed5163cf3d8382d0a7c5f482bfbcdf0a4ea2513670bc39a5e00fdf19370dc6542f5c3226d04b4d2c0c8a65bae7c481bc49ac926aed78aac0af2cb110aece11b8f2b6fb6cad716f50441029f1ffddefdce253c4708d22604a82b2f5016a63271cd02e506c7ee1c80cb4ced4e47f6383fa6eee82aa0472af9552e176672d5592362440923fda58a8509a950cad878e023c075f585dc3552eaa4af92367ec4659bf5cfd8e6afd04c17df69629aaf19d1855479b5f1d7c722602babecbaa9186e8895c4115b8238bfab23413046e63be7970c971d902fb5ca2ff4dec4a236343bea3abf1845c1b469d73a1582d164635cfcf2a04ec1e215e89b940fca1cbafddc50fca43805600a8e086e85195800ed609459d79690f4a0514c53c0f32c1c1b08222a1950c04972abeed430e0f17eeff06544212756bf8d66c5dac489283fc60846329da5412f28a0a83d30ce860d16f201887c0af84de974d009e0018964aff08d4a9fb14785d023bc804899568df516bfa449263b931b92fb3cd3a4f2708fdd851783d1362ca45ff38a0cded50a959292da82accb2164b0ba6e0d6ae606d2109b53f666359995afa62923bb4c3254b0bef114505603218e9a56528fef28461b3483249d1e9be49f2445b7a3b878eb4cfb1036ffc01f57ad9908c34da333896b780d4f748046462c192b269501842175b0e67d9d29481ba563f82c6b56f3421c637bce9bb65f7017c4cbba2ee7d9616657655095c1319e295d1e00c640eb26f2f431e1ae4587a4343a79b870d4528c8e0f69595a624599e938458ba643a20681980ab6970b017ac0d7efb1b5e83f1b1d1b063926abd58deca36d3565288acc2d4088b8e13896da1e46350c39c5e761abfc4703271e668c1059894bdff08f0614aa4772d9f72e40ca6e04fc34193503ef1c082e75c79095e9839c18185ff4a1551f946cd70456766db1d0a4f39e59c52f62cdbce32ed8a8d3dcc41fbdf155471ab636e474c6eed245703acd50824f44e0d6295915c1412371d0dd2536287265c93a71b58b937d47b6a8671bc106c95d7aab570c244ccba305e40c4d55127dbd9c5a9ba9447fb46c313266191a701c076b04f76ec98206554d22c4669aa6c85c0c762d20bbe3f6a9f1ca611594438f7895240610c58f75aad70cd75470f9a007a30d8b5a66b6cd5bcf836809b187d1ae86248f569bc749900106cc2baf43949fc306c496b9a6a34ec5baddea773dcb7be6e2f04e0e8839f302abd884c807aa696edf973eeaf905e67d6d1ec80e4026696ed140ae4713a22c64b59ea37cbbfe1b35c3ca0e35f07a2990236b360f30ad7e84b23b55ba60505cfdf008b59d44305570b0a6c4b61ed2fb085c6be5482d0a77ff94280fec16f228d04adeeffec810cebc7be2a3943f40c67fd14b0b35c4a3764e1b639249720dd7827cdb22a04e235c9299802b7cfea5b7e9b07a554046400639ac884ba9f7ca5c0315daeae4ad29a4a780f5bd9929780f771215b229624002975ab68241f120a3611a03619244c0cf5d911a6e70449cb23930c93c99c03bb04c229418c1d2547720e3b3f5f11a0e84f0f51fba5af4768708271f0d432dcd8c1f808bb517fca85b7eb18b4ed187e5fe7dfb29277cdf1e9b9278c766e79590745e3c9648a4a94b9f5111b59ff4aad2266bd4dcbb7515195fab0ba485c4b62bd46873652e4fe998bc4fe4ac1a50d4b0eed44010b2540927b78d2ef5310655f3234c947811482fd9c0c6cf8d57d82494189b66697dc8798404ea234f787ffd54f04af4e555e138802ff0328b4c181612b4d80208dbfe6fd60659c42b0cf8af21dfba0e02b4ae205ceb8d55ba19c43d801e50abce08d4456940b0b515ad01552167dd7149183d6d7fcc918d5c22d5a993660a5d87f30da0149d4d0b147d6e525d843a242acd3368170c7568ac5c4dc2c83b5623bc4197daa2e0a13c07552705d4dc3717ea70adad8004b6c51d8766d22d61599fb693ace46d0d7edaf0a79f426834864b8fc06c7faf4e63cff3dfc316a740bde3001f18212b212881d40245ce78e0ec4fbc0ff945338c6d62800ae1449d7404da370037535090fb2dc3507c93e817a9f9b5dc5ba646915052059b0130c385531acd4a53d6ef234cad7165e4983c14920a6b1dd439844c3e49a52035ee80c3f81caf89952fc057db6bc1bff7c84b99672ba5292ae0930bb2ffacb8c8c6eaacceb0de43af7b79575dc5e36931cf83f68165942fb9de822b40f64fb78069f6d9c4665b39d6c5a356dea6c7f23c5f638119327621b2f5921f5a38475344a68af2ac4c0f4c06f1dac3127766da05c31da5ccbcf18b6cf3ecd417178c808cce370407c25219795f8fd540c9cc89977073c9fc4d8638d7f1b18a056b42ba00da1a4ec79674148924d98e4d9dfd73e5260f663507af88dbd72c9b713ed17a919c655c4fca9b71693899e4d54dd0d7fda5dee217f563d1dcec94593801d3a5284a4968d5cda17684dd1ef507c10caf1ca437aceb7d0af69e89afc4bab4a19d5a3cb79d2061cea20e49495ff6ff4f5b6da38298de4dbcf9188b581a927935ae7da7395a63d717c8ac5eb18f1f5915e6dcfb781c4092d23fa99817d889bedeb5190597d71c448f9b70346d64334d17cae44d9fd1cd6abd6a1d1d331ac63e837550d40ae851ee34b314dca48f9de4d3d458cd0c7b422494006ca41798f11c6fefca4879067a76c39bcf38af2791c92ea1e810d041f517ea35690b4c32cccfa2ab67cad629c718014d15d0e79764f1e06fbbee7388d92db5c918955692f2e4e6ce4802bbc02cbc6016b35dabd0b3d7c5e6c50973edb775a83f9f51cc05e6674d572f0bdab7dc19438ace4fcda2c8787ed7cc0094b21c5127c6ed177f6364cdd5e92076b7d9b7f9a4859ac965fd2e454bdb77ab009e205a2b8cf0ec12c3cc6800e2745c3cd5d021e34bfb6cced466231f4446b3b0843de787a01c1c04d7b7380246d95a9d82bd2cae6d967b9edd23a9f8e6a2a61f96d5e277650b2057ad66aa25138cc5e91266e3be80733d781805527e225d91b044f2b3a1cecfabb3ae8e095f8b1eafb2ad148b8c6d410701f6c4dffecb8f431a49e70f337d1dd584b9a6095069ea7d87e14402c5483ccb79c815860349a6fc9eeb639cfd52fe2fcd5808d066a66c6300322d74e199fa8c014c78b5424abc5949dcb81c7e5cae3d6dd813a45c4582bd5bfb8450b03ae76ee5ea2ff5a1a3db944a2d5c638414ed72eec1656b46e2167f77dc9761e4243021bc45f7990b953ad35eda2538395ed7870f350cef1ba503aba18f172dde2d46de2343e22de42d3ea1c2ce175a73bd67f36c108ad619e7fb06bd27262e320e95d21774dc1b8cb65355f3db34c36bbd2f596b1e4334be8265e6d27e6667a8e163336ffaacfec3473d3bbedfd5b8b964210594fd36304cd97cb09daf43e20eaeebe79f08829e0700e685a3f98078c98e302a0f5fdb7d8d3a1ab30521ad8f42dfd27c7f9974f55f2978efe8f1124b194eda34f5fc79a825b8868e3796bf411bfbea58b0afdb042941457f3f321dc53128a36b89dbb2dd85bb9f96faa21961a3448033f29b2ee181443999cc30fea01d5e24ccfd0c5463eb8f51e9a1a8983a30093ba61393e1e8aa5287c92009f1a7058b09acdddee731e7a6c4861afc55c7091f2aa5c8ef698fa39eb79e0af6ba2eabbc5df753a0b36cbdfe42d955a3143cd93271cb8f012652c43e54775a31cc3e3c9b60fe8e495c395937bdfb8422a340a3071b8245a12c4f2480edc87ea8fc93101fed600f825a4314fa0482adf0eacdb07a029c1f2f07de4c4fd3a5c0107a6631078867a3a812c272cd2b97addd7c3b4c0c7c19e13396721783c4f9272ea714669dee5c51d246dee723fecfff678deb7c37756c4538a2b1945250e67c6c117e75d0a619163be94891e7f13ea29b7fad1edb8988bb19ca2af144ac13acdabff82d07dd1a6d72f527d0c1c988f3ed1bf0fa1cdde0bdec42b838035e659a8b2c53e1231ceb843235bfb1d7eb52dac6a6af0dd4feda255bdfbe90a80d5b24ab259f358e4f1fdd42ce99778784529ce1088e9ddb178ac67345e4c80bcce2120715a1ab4e17c0790abaa4b395439b5153ec5ad3fa4018bca598f242c5200df5c3d4ca72f72f4236e70b797355843533b291a40c63ad423ed5c16838c586142cefeaf2f4073fd06fd1198db10d4e327a9454a04fdb0afbd25dbde2d15179920e06664e6986a9551e6d0e750231c91f81065aa5cc56f313373c110c7f022e05a39b2b021b6f59d28733088dc715c31a410483dc68f022e9286016b05ca4a306182b829f5fa3140aaadf5160359b14eae2daaf5d9e0e55d52a97313d46c0ab641de352f092cbacdd880d85e0ee3be096076fa84c23cf3280fe1d4406da0bf9f233e1ea908944b8bd1964c5f8f0f765ac4c0fe9a9e0dbbbe42a6f8fb8b4b9e423fbf56393256669012a4dc005c89325a5ee52f14f98402e22b5bb2ff04692007853f3f3a376c7cf9c23c987b5e443c2d488a05c8295d0f0f84c6ca7360d3f22f3632f0c30377167e8d75b10c515fc21ad07824e0ef2b53971f73edaf1653c5ccca861cc44cae8354b3e92b4d99bbf7e590ab7a982dbfe883b872b2bf4c72841209f0ca3895360cdc5e7e484738d7e4b6886e227c1e2e2f1526d583117d7c654a75688b0c0f1310b6cf6f2c7dd49dc3a84d0010f2b83839852265f1fff3c307404f18b5926493b6de12288b1e703cc5f7f5ea06ef1dd2011202c80ffcea302c6758de23336d03c5d25f3df577790a4de49efd09472ba626a60573fd3320afc9893dbb35cbeb08014003cc61bdff6bb1d5c46590164c2c7a0b82f1707b8f42789a6e9b96640fff53f71c62840ddc5eb34aa4d3f3ffd8b9cc782a993dc2fff8b636b75ee60087bfec016c72cba50c76d30f9da80d8638f029d4db221e00d40a908fb7ca99f32c671387cd3448972d84a69459dd1a17f1b40e5512b04e46cc28b5c8156ad54c13720b0faeb614a97e08bb4a78039ea027bfccff6db0637cdd6e0ec832423ca170ad3deb57ffe3343c34f069a5349fd8eb8de975a56587044472f49b370550fff00b16e9fe39ce7e0afb4b8c0e43e234a4db043c88d04284e5228cca274ff92236ffe0f68ee67be398a65dc407da34fd518f807840732e79b881a06fda39874e17964b0f4742c2714e3e70d92055827725bbc7942d9dc4828d3227c7735267230ed24fbad8e9883907a1e336963125a2366390709741dc89e9448fdd2145be4e6d34a4d1d91470dac20b4eb76b970ca456f8572fc4633fc2598247b792687b1c7b331a3b4461f0012e4e9c9ee9b04dc587dc8371141a655998648ff89e91ea9264bba62c8e825489d9c7b6913443b8b2141bea76f451f489d05cd8241023b948b112a703a173fd65c849ff96ad41837bd93a18a59dd35fee4e6f87a9e5aaf775041f5da2d8112a138c0cb8594454a45ca083886b4e310d0137d663668d80b30a9ecaadb345d561049d459bddf0ae98bcd165f3d1ec3fda3e856e095d7d0800feb329b39f95c9fe291876825792a3203f4cdc3addca09a724f687018a24e104c3dce0bf414d27c0bb2d14bfc1f5860f3bb1d1b84869e0c8949b867e390207d96b9506fdbd486deefac20a0b1fc459983bc0e0b98aee13da113a36ad2fdc654a2f9fd8128409c00ca213bd405f60f97c85f4332738288791db25ca328b4e7b3adb7c0fef638f5cb4b1b31e94e47b9ab1e2e9a13753e1ac41f849edc5777d3e79e911225d79a952d93ac11bc52b67451cd6b87cd75c58e5ec3d2c1790d1637276914bda8b547057b6f09f9056cff04dfd118043bae7b50b13af90a8cf86475d6391ca5b22b0a23d769a35ade080c36174db8df670d0b7555619623dba5f03abe959f440ef0fe46f5c3b243c71d9f7e8a50aea522d08a3a89548150983254d893e3c26c8258f62008eac8e3187c0db5942ae141e62412aec3771cd63e1fa224b42a59847c6e7484ed31b26a1fd8381cc0ac1b86e6873ad8ddff7a50b08836baee156592c2e418a7c6b3294d246683b645f046163430e170d4d989fae7861782e9e85a4a8d677f8bbe23ffc486cbe8efe00a4832bda64d452a3000311df6aaa591268dd750376ae9ae734810613de6931414f2c3d202c82bec35f761dbf0588b62177647db07a0e9f9643862cc51e6403f02914657a27f457d717f19afa00bf6084b6b34731f5b9964ea7cea07d5fc5a85c12a00210272f19b38803a94e9a412f7de54621888be887f213fc7d9c336a07c5cb0bdc4dd73508109047147332fdf6ac19d17d0afb263dea52bf6a651a5a55ca912ffb69c71e36c05dc2484dc2aac4d0f848e18ee5718edeb123600c02b8df0614883dd215e67070e83b980571522882f83a1e9ce8e828ab2bfe34f42558e6a9817745974927ae5333d244821f67d9df9c95495ea16745e861e5f70b72027b74e25f0d125871b44f3463eb9a068bcef7cc2e5516bb9f3328e897121b563e302d606248b579f57b2deaa605316584c1ee99e24c5a257a590124cbde59c00253c501317b40c2afce813c59075b831ad1e47fd01ce1b9ea012264450f8d083cb43541c6b772bb254f0ea63ece3168b9a27ae823339c97bf53bcc40755ef1ad035c9046fc2f43d0730498fc4f82c511b831d1f6f671ffbd0f60aed8d1eda8b0a6c318dd5006684b14fe4a9b0d4289fb208146c66bcfa93837cbdc17268465e11b3bc4ec000eba5b06edffda7bb5b530b8f076b6de88621c368be445efc6934f7da18263e4945fff49415072fdc2432368dc42cd6fde6a9dbc6999eb59bea5f2bc2c1a311322b57dbbc7d66815760a6245b0a8801501fc46d4c86204072ea71310dc2170ece85a1a4e93fdb5f3279ba9ef0d8b214e89733782b3073cd170ba670e47d832f8d44d8cc452cbaaeda04e4bc0c8a5243f98713b02cac0047c88d02d7be6a9e661c47367b2d984668ed2631e89d848a37ff8f8b7466fca64fc614be9c9da3cbc16fce7138d531ba6d1cbc5f82cc7fb4988c4693f6fad48d115a621fa5a1386c3a158c28c25a8ef9dc7afe78faa7a3563650455c591a0d943da8b1854a3284fb24f48f8520da6e6ce0a50ee7b2deced0701ec88adfcbced1801c4f10b605819f80522e20b15084141fbfca155e9687368b7bac253f77f83bbea5c3a0a03ac22aca32e7dfaa5bc33b3ddd928ab92af639675012a1f14c7ac8e4370cde2f184e1ede5465f7e7e567f3ba9313ea13e3b371c0ab55900b58463fa2b623f2c2080b8bd6f0f040552f2a3177953cf405d8d64f1cd6f260cd10bbb1601cf91239eef86da322d064eaba184c4ff115858062197f40b1b91bddc8db374aadd3248036e6107e12d416d5b45e4e0a87f5e7366446c84d16451d93f985e9dc5dbc64394b513bf93b560abd74eb79bac566cdfd7fb0fefe8da81f9fcb266991ede82bcc349e8bf7302175f6abc5a2416043252e160e04c232deba30f24f5b9cec79f61801c199db899468416c198e9adcb709034392d70076c5eaf585cfc1f102ca014081a18ae0a5e32bc6acca708a6c160c57acc3aa20169e2bf91ea91c10aa8a2a58b2d498c69fb5ee647cba92832fa4473bdb495e17f6bf2cdc42a82b2e2bc0f7aa8884b16f147021f23b06554a56a21f9b0d9f235bffb1a1a9edb2e3b012cc3777409541acf5b275561741ece824ac7d026f0c39ff21e284ecaadafa04c34bc72ec88c8082cc287295d9c217ef957de0e1bd90401db8dc3b7361777cd144deb06d680236367a2b055381d645d6330af6005ce078240fe72b7ca0c303286c50f68ac2a419106b6d863a9b97f5cd88fc70aad3b8cb8cad39af5f736e88bd98415ebd8574e562f1c614eacf50215e1c82a930f3e2e82df5a21da4bd7120bd320b8f2eb6cc6d542e995e34d900988f5a94954c33bbca43fb6ade09cc973c836d9230ee66a2c0b4831ad630f49691ee0a1cb1465ec1ae046407f225fa016553e46bfdc4ccf459105440ee49e7da5db84014e2ca337069a8998de3b3cc25aba6db94dac1530fd577f6846e09e4e1f5c9914d6b0c78bf7ff28e9881437cc0e00ac98277405a7e8066963a29156f6a41d2d6a9630c903da922c9d720ff8fba2adf52e117f595cc200ae9ef0e7b51966af7e78c5ca656c549b6d617b8ed4aa9127f7ae7d80630f5536ac75ad2b56300dc9e1bf14a71d6b7850c312c702bfae60d0a6d50f76e07a9e3f6347506f636b13d271468b01ac1605de2217f5f0beb2f2e85c26ab56e6a91a108275b0bf844c958b0af0222ae7ecac2b96ea4f56f9ae0aee3b7845a7dd181ee81575fc1f440eebe579d10078131b2379103566478b904b5f28680a5fc9f3684f84bd7eb99967a9f2278595f330bbc41d10f7088c540d0d19a93b65aabbee34b26f2d6002aa1dd673837adbca65866675b2a125a352fb68384298c38e825f986f052db5bfbd1216aa11855509527d20411442b376f6424aa518d081a9371b6cd032718b22a6f0cc6e9667db39525e5a671575a706e6e5e644bf8b3b158ce06bdd9593f11a0f1d641109c25c9c0ab03b9349633aa57318914c4702a53223eef1923db68cb1c5020d905c01d0dcd38433006ad5255116a3dc5aa7e084d8ab10d1f270d1c786724d6c8760784d109314249181fdeef836d59c79ae748aeb2fadf41ae298d92d0ddba53f1f1f1ff30ea125361a23578ad4b937caa11a384fafa1c4978c19b71ff2f3b609810971bc6be60c0fb31acc3ef21cde2b85fd21aff4958e738b981883b7f30dc7ce85aff73e4ba80d4759108954456b8601d3c93c4010b24ece63159ea22bb69f02b60db70af792a2fa220b1035cc745c6018a5e967edc1bcf2e9a2ead4ce3077810b6f5c2847b43b85511e3ef8dc4dcd31a6158fa8ab3ec035d8bd4f134eeab0bbe1fd52c5c141e06577af66599783ab038af045885f2aa6da28f48408f667f8ea5b59587b5c475a1b1e55262b217157993e50549d4927766119e674a733cbe8caba446bda7cef55a0364a41e1aaa69f965c139b829dc7427e62d36873d7e19081ee1ca699422c92bdf8288e340b8ca33a9a35c58a92263d3b5070c62ba0b6313ba837040f4639a22d34982149ed38fa1204117cc7af4c959e0650dbb161f97ec704463b16a1589a08c096da40464431affdb0d6c0ab84e554db7aea6cbc316ac951f79a8c9459daadaff17f543c9c4859d36334b7518c52e9e06dee6723a41f96840d2386d329eeb316709c1d95caddf882b8cfebf27ee199854b124e1adfcd81b3c1e5f4ccbfe23430cbf72b49bb05c7879ed1aeb2acb1bc7325b900938318c7104d8dd2057eb604426907a637ed7e19c6d7336d83d112b83f3aa5fc6ff0984ad06cc6b576f6ec62c38f37f7b5080ece2c62d3025205eec7ef77c2f5c618669f1e5bf20d792365e6c44d3983f83128179a89c7cce1f7f9add93c736c36eefabbd2f501d1d423199663227edc8b90efa5256ad8c8206dae862489644544aae2b5342f9a2f4b325477667b2fef471db6c1144b15fb04e1f41a87a43f14ba69515b4cab35d5ba326fe8ee6917f867b9bd4e50a8f2230b06c8bba75dfac5785815c846c533e0983e997aac1dc83ff73577f4740df9ca1fcc3bed13b611da3ed055b25b12780f32cbe708a56a79952bc6e3d23c99312246b90d38d3e3c6c2e3c55ff2f04ea1303ae45b3617988af9ecfa86c6808f1b6bdba20c4cfda71e6430c58fb6c0e9c82cc0d0a9a2e63bf8e93eece12a943eb702e748081e9b4d2e37fb920ccbfa6dde536d9f6dee7f7abf2c6c13b0effcd1dd4990a52cc3cc6687ca703675dd1cc074b308e7fa60d57076e56383d5e5f02e1bfe29592fa6ae0e8c90ffbd94e8757f89cbdb196d1502cc598368cba4989beb574a8ac3022354c30a9fcd6a560c9e53c4975fd7757d74334459df724a84d6706975a56094de3e9d39090389951b903fc16fe19e6f8c80716f7b9137f6911e40b5540f57c27a47c68f40475000231e8c613fbde599d0a08d9276c2f58fcb1df2f111428af03f2e9d7d1c942c4fa58c67eae69bd5e51400b097d544b6be51e8c28c66048315e3d5cdf79aebebdca54118d5f32f5e024144027a63c6f162cf51527d130c5a068c8a213318b7f40776de479df22dba62d764b5b57b88c7b864a62d088466307de16f7e2d36751ebc1e2c4d046d2d1b6fb46f14c592589eb6fc5ed105b73692674121b979988efaa673f93b32dfb4641ad085da16e1e3a2cd9a9abf9678d3c6db4ac74c51132a0bb1d858bd9f247c016bf870a2dcb824231408875fda4ef8fa2c52114c7ee586e213834540e622014d6acb682ffcc2cccbfd13571f1266051578669dbd9622319359d66d27f14042feec254952d3549d8b027bad35780315b0657360aa18ef18c10917a0a9937d276cee2e8a4495b1c2d7c6c3ac8a06a69f31324b026b0295fdb3474d5b3c1b606eb62d851a1e2d84fc3576f99a300016aa356b11baba1e0dfec87eb544743ba15c92ed5c3565706ca8b521e5ba8631070dc1d1d63b5307fd2e871acc1268f0da20719202ff0f99f7f0f53aff74b773676415e9b1455e749d291e126bd032798675fd4725a2cb877d0e83d9840c74cc6e93d4c0011ca01a4100e396ad83ad8ba3bf80d3e3a93b4048edd829678d3bf9060af91c49c06c5c92d5d4827b310cc21d75817f02cd8bf4515155f90812d30ee24f69743314677574515b5c0463fd3a49aadec3d61be3067e41755a76cfa96e44d4dce5990ec80cb998ace89e5c8c728af14cbbcad72ef6559e0d65100e879db9934b71c4856f53a49b490509c2984f8612793afe9f285d17338e80a47ce8392239a1c451025f70ff2390538b89a5c1fade36f54e28cb17391294919f780f945fd047b639787c588ff4e9913e77348fd09e8ffcdad96fc16f52f72967b50d2de81ef3037455bec94e6e6f36809804b7306776c639daea9a85fe120c60eb6019526d3493490f65d5c9f4d7260b6dff838b311e1240f849c44e40a8a082a86843461a033df32f2c5f10c13c642b22563f15e83696f71c875294cf5706c5fb10fc7feb9ac57a4bb033ae537d35b204c4a9b0e6569c85a1e4ddc8d48371519ad438a7623eaa621a57934518f2d867b65d6b2582daee8f78be9db3a1076d945cef90d7edc816074cd461f4a71171da3536e38517aa1a7c1bd18433e0d86f82da4eddd6defbdb79452ca5d0c400d950d3e6f5e740975cdbaf8fce0bafc74d1527e6a3d2009cdaad4805cec0431010a42e2484bebc5dc1bc82648c8c802f16f563d929511f2372dbabab4173f59e082b69c28d2dfb188b60555c1e566f563f5fb665d50fe7513f250516bee2322fa4d73376bb0ad185a31b482546188288bad5f42d1b7055b39ad9e18824b4b1f134254c2ef9ba5e2eb0df3d7c777909f766f3368eb9b762b2202cdca2ab38ab0ef25dc8bbffda6159d3d7c0ef45db384be2dc821118538dc02c2f466e122310516687ed3bcb7857a1f74a48505373f852a0e4cb418af5bb8f3ead14bcae8a814abffdc9b8a37472e4a513497545cc446bb40eaa97d282da791bedc219544bafa8f0a8b045ee1ca9aab9b46b33547ab2e54735724faebb5e63edf483aebdece68ebfb66fd75f24559ab8cfa0287c3e170385c08e6d09c035f0c94ecdae541b7d977c6212d0c43f4b34f038be70ebd04bdfcfc9d57443b507e46f78d0f511bdfb9bffd4380fb7dcf0cf913c1d26c212cf594481e99ad79953a532289efe7932c711903e641871ec2768ef7e03fb7ffa15faf52889a427a82c8311ebd3faf8e1f077f9fefc68f553cce589724974cebe1943c3ac4d9cf67b73b1e64d92b566a679633b618b63dc0284f3993415ba7953c3f7aca5717d1a77c89117f4acf522b83ac64a0d287082a673c08959a4a9e59115f10bd3ccd267b96a083e7be9f7d67ff9cc4e78be0f7dfb9af8a526646b495fa871565d00e43258d4b262ac310f2ad34a31495e411162579a445191b221a95f52af9ae9edd82f0b687ceeef80fbed6a3b21c23ba28431c2c5219b4c3952f26309e9030cca68a3fbbfd218005ff7bfc96f715c328b3123746592211934ad04ba6a0fcb47485f1028743ab63c4dde6aa458b8040de6bc3e826eef4bda86851c8b68635ac210882a07f3db0f2c4ad5fdcb4174317efed3b73e842cf81d0bfed1fa29846d31aac9ed1a334dabf3ec6f904b77b6f89b1115a6febad22997b6f0c245555adb5d65a6badb5561c36e24ad1d55e115b9ceb91bd169b35f2077ee1a7f1ecda9b74034caa3c2d74a9e88dfbefdaafe62f15fd7a908ab808a3903f10346b842888e2f88de398c7118fe3388e771ced388e63ddb99eb3d974d10f346b5cf3828bf3675e604bb3863541f333cd6c9a26bed634cdaac5518faf6bab6e6a7ad9d7eb553fd8ce318eaf175996668d7bab47d54d1396c1f0af63fd9a69dacb34807db234611606abb9b437566dbaea982607f60d017009dea233186d26c6625acbec27e1e0dc9a8c6adcb7d5235a53adc6fd593daaae5303415f746b2d3565b058f176496c9408ae180d92967034eecd4ffaa29a878746c3341a8d766d85c1768effd120968afefa6d7f8988e218414ae36a194e998473c63b7767c7eed411b64d2093e1e0e4e4cc664d3bb527043f112747cfececeaecd096684b3c97c77eb3593dd2d1d9d9e1e1b9d1683d3d311f1f5c9251ad4040f8da71c7a67b2abe9687a67b74896bad866bb55bb322cd6c227bcc1a3eb4ffb13f15f7f8d89f5bc340b9abc6fd1bf5a866f0d57b86e53d77c5caa01e55c7251989e8a8e26523cb7bae3022cb219308768b156916b2f29ebbac718d8c4a23f2351a1989a191ad3cb0d247cf4a5befcf4f2da82654ddab9baf4ef6ce1345672a542ccd48aad5665b3134444434a335dd6645452c74ac458b16b0162d5ab468f1657c5bd8da53339b6640b4594dac41b66c02f2201bbed1846c4dee33dab56fab3f43f1b5280ac27e0800fefdedc15f5488f4d3ac71ffdcfaaa5061eb07733f4fb309b5e605e58a3a7487ecd0a7c2244036c25d5bb1b862e887be2811d1ed5654c4a285db6824d228864848e08794f145b24848485506db3986cc26a2dbad286909572b8b92058b580bb3a9fc8c32bed6a88ab08de38988cc1a96bc990618c1772002dcad88450b23b3c6fd5a8f8ef0b5b51e552f329bc4ebf8a2b5bf7bf6778bb6d66a3d8b9f495cadb579cfc0d246ddba3316b4598dd455377f6b43f445599806b06f74a76817481e64fd30d1d769607bdab03a5ba4ea464797cce72e3fdf33a3d8baa88da02fba4b24dc8b180cb3a9c6b03144d8cef147f90343717c91a5098b69d9114ece4c678787d6e3f353030a12f21355615b3144742b62d1c2081f5d5b9182fea21b036f510838216bade5d72a02b25eb2d65a6beda006fe6c91acd7f879eb625d72496bd6c05fe33e07f64350ddf2e8d23d3615b0f315bd17a05ffebefce12f5f20d82ec1570ffa8a6e0c7c05edad6086596b6f40777e8ccb2aabf7265a74e7382f0dda7a07f9b768e27b4b6c7a366bd8372ff89c03fbe641149b4d1fca817d83f3f6e0e782dff96d8da4afb37b13af12ce68ae471fd8af393bd5bd4935b951301e3111b8d136b6641b94c1d1204bc4e0deec6bc6bd595ec525e5d86eb3269d7bab269947c7e78869dc11631c866088437c86a82649fbb9ce5967b9c4d556b0fcc8b004cdcf926399bd963d332c3d2f1d7fc57268268c06334d8f5d530d6e8b5b6f9af6edbe6f1bb797682ce1a01b67f418c750186aa2dfb967dc974ece399b5245659ef50a559e505010134035dfb8194035b4de22dd0d70aa8914ecace68c2ddc52122ee9b7d5cd48b28b8a9d1516b4d45bc344cd05f57a3d23c8a0a939a0ded501add15253a6f6e3fb9644d67ed07a8b2aaff2ec54af17c512d490277dd658121b9cd1cde877e525f9b03caa06c201d56a49fc18fdd45ba4857323029cb3ca8cb8fc86baed77e51971d9d8711a971c4bd1dc719db3feecac9ff3af276b8db465362f7839462f4fdb12aa9209355743894aa1d26bcd95636c24fdf3986fd14400e9a2d3b8d78afd604755c2f51642cdfda061b53acb542bd2ce327d20c7c37842af3527f3d07f646809f5196791b26b748bff64c2d09e2570389e1de7c3e39b66b348d849ecc383d65b647b18e7dcb5d7413e77199e3bf6dbeaac91cffe9df5a6b55366038c6edbe3711cc7711cc7711cc7711cc7711cc7711cc7711cc7711cc7711cc7711cb168e3e91609635ca3618c6bbfadce26264b831f1feffdfcf47a3e3ebd5e8f8bdeb6b7ad4e4bcd56199e1a0d9ce3a9b7c842ddf8aeba6050b3d2b470f4ad67b519361f1eda8f4ea3b550f125e70a638c4b1f2743d78e4d04947ebb91a10ce63c8ebd5a267be537b7dd7078ceb07e20c7c3ec558865e8be619045caf64ac7501ae65ddd5bc6bab7fbc4bb4f50ecd57dba4f3d3eeba9b7483c79f6ca066d2909c7d333e3e1e9e909122228485ba49186e65b346ef1a9b43133bad974199ccbb7a8ac5d6e64afd1b0d49beba191e4575a74973f3aad6ca1a2462dcabec31f259863cfa9b91ec75e2f2ecbb284f59c5697b33c5c9443d27765122b52e915e631c7a6024ab7569bc7ea62386e9964ae694c342c920df4deb255118d2d967bcb8e516ba54f5c6fd86967588bb065aaf8cace0fe44000d66e9178384723866627419a571a6aafb2e72b9cb33d5c943d6334db5e6d076d755769e39cf22e9fae5216af52f8f5b3e346cf5e9ef8142dd2e83430e8e1299e1de4dfb8f2756e1be563073fd06cfa5ce7b43f3bede79cf6abc539edcb4efbfab41fb36fda27edfb540bf47df4733c2e3a46cff1ac16892c1d9f1bc7934e0b63be5b6c15347e94b4efd88f5e6b8ec777ce8fa66fd88f5e5626dbb348d9471f3d8fe8b661f4a1eb30bbcf4e8719a5dd9b0ee7689edd2d137ef3e685bec763354773acb3e3aa84e3d8c39af3713c3a769f33ac45a3e39cb8de46979db51ef59ca387423f3a6d44f78def47c72602467474b4bcb78cbe3e6bbd6df2b1f39cb516edd863a791ddf62c935891b067a2c71e137aecb0d76374db3035ec34cf7db397e716c1dfc01f3a79ee325b2411c561fe7c7739d7fa3882acb67d9f1ef41ad9e2ac35fad14551747b6ea3174791c6c5dd72a45be748ab93d7e2961e74129be6a9c12d02fd737b7ebef556f7d662b3e9739cf4721ad79ed8bf93036c36c57cebaf9bf675fbd77dfb5ac5ebb1f3e7f398cf5c9f3f5976fe64f4670132375d03999b9edd4471c090510db4eba0384cd78e63e632cf91c2ce9f05c47ce63f1faa41cc673f1ac0dc74989b8e73fe7caee339d29cf3e7437f1690e338ae418ee3f8e738280e183e54031cd74171fc7cae7111e839521cc7f1f3a11d68a0e33bce809af2107111e833df4171e0d8f11d5407cd91e6788ed4ace9ec9673d614e7aca9ecaca93e6b1a3b73a4b033475a9e9bf6a0db8bde001d708623e8514435b8b70c666d34f69b331de499e8006e1148e3de40bf4ff4e719e4815e6d20ca81fb145ef108f1c918a9b3f7fa6ffd585b5d35650fd83155af32b82e8a9ad694b484f6f377edda2da0166107a32bc229cdf9bb5e6133837a84773cdd5bfd8dabbab75aedc5b0ab9b45a1abf7aca0abdf1834f62aa6f8695c5e0884d669eb4d28f5d04081ed495276eaa744516b1acd337abbb70e7a3d124dd7dfc09fef0d076c8dd52ef500e7a3862a1e47a8c0c3619db0814956ea81a52188375569b53136f8d6ad1367c04ca5624ef0822e253f304c9a22bc948c9d3ab4d15b8cb5d16f64527052d8eaa51e845ae59945ef4c3eb1a384def982fb6280fce0a578aac8d653ad328e2c09612bbde77dd29638ea1345cce8520f88f45b5bc29523572919dbc9b23fa4802295064037e429256f894f2bc5c30b4e2989afad382b398344554ac684c6e82dead03e2488524826ce2abdb310114ec24e113d85de59d64368081cb687901ca4521c1ec89670aaf1a4d27a29d8b7b7be6342ac4b6f114848ad0b171d78b5fc02480fbc948c65367a67120a718a29466ff127434d255195de1d9c46d8a564d797035010bd45924de53255a54befe39cb64c38ee94142698e8520f5e5fa052187e0c50cbbcf55ae62dd2972bba948c8950f4ce2fc6a0ed25a9ce48e19091e155e68c68268af04c96b18c11b90b9b714144e3842ce36334234378e6074e991e6740087110c93019cb44e19cf9209b717a911973660d4c099c32278468869067ce9489612433251cc28c4e2c53430e9a15341925f98c0d26192e386782d065b68466bc8848f81c09c9408166ce8867ae40abd10c980f4d8f98192be11929ca7811cd2891cfac5006cc2884c606bc4a395bf9e94ed5dedd81533d98dd39ded226c8d381bd114fe55de5e5a97a759fb62c2feb70efbbcabc7b05ea763c7c957b1f0fdcd9a99e6eeadb029f2ecf5e7d4fe0957dc2b96f07c3d75a6b73c618631fc771b4d6da529cfdadfd35fab3c7da9f81bc00202f0dfa96f8626c36651367f382ecd96cca68fdf087718da4c7582b3f59afb5166374976fad78f517e77bd1259eac38e75c7ece18573dce5586f59cdda2376c6dd7f51cd7f9b9680633c7f12eebf312b7c02f5f9f9d77ea52603de7bc5597878bacec94f9f8723287312dd3315849be463104a770ce56657dbc9d9f6497b481ac7b09976b0f43de7a046e4e5bc0ba8d9bab3ceb343078eb349d75c739a61d64e0e95062862dbad4faed955aaf5d5f4d5bbb1e0ce993c4a555a0db03afc2ed49a25eaf52be81ff7a154dd0d77116579cf5ac16c9bd5ea50c8a3324fafaa967444367bdb9c8af67507c95344f415f17aa79d1adde2c0279bd4a2dfc7a06c55709d3b3bf6e33a2d2d7836e462d5814d59bc572f47a958efc7a06c55709d33833da5fc72dbda0afd792968e8c5ab0a8378ba5f6f17a9590fc7a06c55709d338b31d9a8dda5f9f310021fafa0f8d0120b938326a516f164b3d7be1d73328be4a98c699edd07c6a37bebf8e410647f4f59e0364f00287e4e2c8a8de2c967a46e3f17a9562f8f50c8aaf12a671663b349f5a905fd7200241f4759a03221003c60b1c928ba37ab358ea19ad76865eaf12057e3d83e2ab84699cd90ecda716e4a8edf6d737d080127d7dc7021aa02029068c17382417f566b1d4335acdef39cbb93832526a41018ba4a2183718442f86702b906c36ee0ddfb837ace3811b39250a9262c0788143aa378ba59ed16a6ebb275801928ba325a35c0b2516141425dd6210c1187ab10267f37b5d04ba26fa7a8e57b3060e5d054b39250a9262c07881ab378ba59ed16a6ebbc9bc5e2526bf9e41f155c234ce6c87e6530b72d436746361e40297c4c3470cfa3a8e930f2619152ce59428488a01e345bd592cf58c5673dbcde89e00f0eb19145f254ce3cc76683eb520476d433716462e703092969ea060d0d7f5102800cc609251c1524e8982a41830eacd62a967b49adb6e4638b3bc27cceb55b2c0af67507c95308d33dba1f9d4821cb50ddd5818b9c0c148525a9a119544067d3db64b6241000030834946054b39250a9262d49bc552cf6835b7dd8c7049f77cbf9e41f155c234ce6c87e6530b72d436746361e4020723496949c68c1ba0d4d40afabad964ea6958100000cc609251c1524e8982a418305ee0905c1c19b5605174231a5a6143cb7b0ac0af67cb94e4d741cb14c3af8b9609865f7f59a6d4af9796e9855f8759a6f7ebda32e1fc3a8e65a2e1d7679609c9afef58260bfc3acd32b9f0eb3e9629007ebd66998efc7a906502805f77cb64e4d751cb34c3afdb2c530bbf3e649998fcfacd32b1f0eb2c2c930cbf6e64998afcba0bcb54815fc759a69b5f87619996fc7a926522f2eb4a9629e7d7972cd3905f97619994fcfa0ccbb4c2af07c03251e0d76958269ba5baa74f94be356c156aa708e04cc1bffeafbf4e03f6d72dc0f9eb01d8f9eb00f0f9eb3382fe3a13fad7650cfdf50a58fcf525177f3d07e3af2b29fd750ace6a91b68cbf9e74568b743dc6792dd2751867b648d75f9ca245ba8e3b4b8b741de9d416e9ba8b736691ae1f9d348b74dde8ac59a4eb2d4eb748d7599c368b74bde8bc59a4ebb7d3c8225d273a7116e9fad0996491aeaf38972cd275db39c3225d2a1aebecc53832988af346feebe8e9a7d01974029db5f3e7dc3376c5b2abd563a761e7397715f3d8774e9d7357358f7d76eecaf5d873308fc72e3bb7f5f1d8f5193bb78d7aecb073db248fdd3ccb735baab753bef268380c361001cee5d44ae15c4ef56b44f752e589e8ae57352bc420baadcee943b785da6574db295bf5d8df1a599135337ad3bee646b8ab847f30fa559ea59a5279336e8052533396664425594a5a7a824ac2253df62f3b68847bec9fd1cd480dd7cd76eb69d9dc860d4b0c58fb40daacbc38dba83df64f033411dcf0c00c475bb23113c10d6db33133f280164149bb91fd46b9717cf938679ff349578b847d8be5cdd5d42784708a2d25903085ae8717352510117eb50732388ce912c4051282209115e69081d72386ac333a22241ce1252c011128d4c0c584294af092664bf8840b574ee083102e1f2768e120d38da03ba1491256824033259c80133444818035c58820cecc109aa0cd1340bcf940c90d55cc3819ba0a13840a6d94d47082324c3c18a306092134b4095302191680382289102098b9210d162354e0208a287e2051831211ae1491c2f77ddff77df58a13595db6a420458931bd20e80b1282d8f0f402991344208284f033cd0891a5a3049e8e26d23cc4e7127a7cceeeb7abf47ddf057a14896255e487ad11c6bcc981e9f7c1bef2802893132409149128165a5882462b3bd1c2536865245a4bb4866811d1ca45b4f0105a369c3f3014c717599a3272776f37c9bd5d276153f776a9eeedfacd57e92a5da57a95ae52bd4a96eae62c8f3745eae6ecd454b5bb5d92a79bb34f4f96c7cd599dcefaf8ea22b8390fd8b8b90d947a5c5f7d833bf35a97d06abe337af59b118f57c7252dd1bcfa8cab642ac1bcfa007abc3a0607c8c0c7ab6be080085ca5254e9efe78f59f2278158bb556349b6c93aca91b60b8cbb29b013211f3b4f419b9929461c0dac2e117ae7a46d76cca41ed550afa478bdef6ca8a59e2e469cd73fcbac5ba01a85da59cab94e3d76b39388d2ec5253f3f3229f4ec5ce2e3398d0f49c6a2746d498fe7343d262642dbfcdeee121acd34c99c451b2de1e11983e824dcbddd253bbe63863df48ca57bbb4b7496febace87b7f400ee9299e734da62dd227b756fd7730b1a837bbb9e465b191220b09e82af3c20a29e8cfd344086c3c608596276a9cc6b7aa5eece5c404d655ecd05dc5486ea0ba2a065cc4e8b18aa1f231ef49002892198f86063450c1018728200c2abf22901f1c2e585228c40e31466cdd83543ce194957948f1a6648a28627217ed8906f789203c8981c80a0d2040f3acc0026081f6fc2207e8040e583820f614029524723a465e9ab5dad6e8f5bda00575a57ddaa3b874e14d19d6347e3310284fe43b13f4675d809692bc63bfb5773ae18638c6eec1f8a2d768b51119bf12763d65a6badd5daeada005b895759342ec637dc92dbbb4bb1975729fba4a0eb571a37973f2760ce19dd9f874e7edf9773fef2f77d9f8bf9dc95778a637df988e67bab34b1ee172abae39cddd1b2aa156d49e3ae886efdb2ec2097204714f1206a7bb6cc55027368367d4c501122cd6fcbcb4df9bfd3fe0b225c31e2b7dde51d50570682d9e7339b3218fa7590891e65d0fcb6f7011f9cd83f27b3d9f4e126bbf572aa392ecb91c95ce6158699e7380e1c9fe5a01e5c29a63ce1a03a1cc741af0e17d92e5c64f5059900b184807db061041f9cf8d064874f903c7ee5f9f0f47921ab6d83bcb7d5b1e8bef2aef06aef2b0f87153e3f551956ab1e5906dcf442e1a211f4ce4f6015ce7d5074ed74dabfa92a9c9351648b148f87733952eb9fd5778573301d7cd8f2a44bad7f5938b7012ecaca3d9c6bf1c313434ce952eb590be7725479f3e6cd1b2bbef207e22cabd1fdf5defa063897b770917574572dd4b4254aa2dfeeedd3db4f2a4fe5aa9ef54feb09e7729a58c2422fb59ea1b670ce3a815579f76d655e9109469e9cde7e4f34fb41bdfd2eba7317a8ed2786ac968903fb1d84808310fc1af56b3db24cf5abd71564b56dbc55ad16abef8d096d7d6b7bf1ed8729460b153d543867c99f0e4e4e6f26f9c01cb41330ac584211872c16e49088664988e37805a7e3647c895680bebcc8320baef270608ad14205f8611ef766734296592cd83433486966090096f16f997bebf162c24e007cf51ff79910b0d80c724b4c972bfca631415928da105a2643eb9d37329c0a8094c0c9917a5a3d9a4de5cc723c23cc7494b6e8ec7ca1e025c40ecf0f49578e858796f318ee413c5aed19abff70095584e0e7617a024f5a7fdd678773396a7803b5440a13da30712487df3e5c9ae8fd20c148942474e9f6c1f2dba792397383086f8cd031e44dba7d70f8ed63a5c46f9f2b1f2c2d3e44b444fddd3eaf2b9fd795cfabd7f3eaf9bc7a3e3d3c9cb33991850c0f4c7c6872c495df3d25b061099b10ac38a10211e9eeb1f2bba7891d9a10f245ca153247d2ddc3fbdda375e677cf16d70b494f941792297f774fd54baaa7c94baa87ea55d5b3fbdb23f5d7693d9cab5746b6ac382199e2cd90b4ca6f9ad65f29765052f5419a3457e9a6ddf09be6e2062468b2a42cb1cb92ee1e2abf7b9c9e86fcf5dd03d513b5040dcc123431fe9b96d545ebd245c37a39d1aa5e4e34decbc9eaafd3743857a580e255094105104a3062ca6f9a5391d490ac1c74d0ea6242ba694f527ed3a0aad090c58b0b6894880122dd341b7ed3a4fefaa64dfdfd4d1bc1f08c607878d4f070fddd3c5dbdde5f1eadbfceb3c3b96a35441026a0f8e0893354d228bf79a4feeea4b2d2a4f0c31133e9e699aafacd531535044b08266868d811916e9e1a7ef3585d61fdf5cd93c5236664c243e49944fddd3c50533c3ea67886f0ba783c3a1ea7bfbec3c3b9edc48ea9a822524cb540c3ef9d094031460910281cdc2c49f7ce0cbf77ca1c4105c994a91a76a090ee1daadf3b5a7f7def6ced70b5d989d266cadfbd5335ea769a8cba1daaf169076a7cdad98d3b527f5da787732ba24822a48d14179b23a0fcd691009728322d0041c20e27a45b4786df3a5d1948212545083abce1724af7ce93df3b4e7f7def3ced0cd1a203468b98bf5b27eb4aa7cb950e564fa7aaa7c3d3b1faeb3a3a9c2362d3c49724d448c98a4aa77eeb0899a201092c4f5c31a12add3a4e7eeb4021400d1537663e6063048574ebc4f05b47eaaf6f9d291d2a91481b91889bbf7bd625eed4883baea959d6546f4aebafcf76385787f0f1440813c61899c22385e1f74c2acbc9c9852d4e4ca124ddb326bf670228a2862a40a208614c0ee99ebdf07b66f5d7f7ec6a86956646244dd4df3d0bb766e1d64cd4e588ba99a89be5d0c0820845ac10a5072e5f5cf89df332b264ca1a2e19485022dd394c7ee7f040a50405ae3146207993ee1ca9df395a7f7de76ce57069c989a225674a4e931caa9edf39555739505739bb1c29adae9c9d43fb9d133ec1099fe0e0e0d07ee3845538210e1627281ca9bfbe71a672af74e3508541da8441dca8e1e2f92deb0aa1645921542f84d29221ca191f3e64d8c1ab926ed992dfb22aabbfbe6557322c7009191170095994cc876cc8ce6f19545757974cd7e56495a5b7d65c5674142b53feea2ad04a37b1a2cad250597a9725f5d7633d9cab65821882ca961dba9a3ca5b685df312d28944cd165b1c1865dba634a7ec77688b082113b62d0b9a9926e9de4b776faeb5b3f6910490c44128bc5b0fec6b2c0581518e38131abbf1ed3e1dc986508104ce0a16b8824290bbf634e3574545cbe484121871ee98e9de077ac2e2143171790eca6d44049770cc9ef98d45fdfb1a918d5126d9670f317d6f575c1d47c5d5ca0130c7482814e30d80ee7162085cb0f2976f84164f71b56c14441452607246d8c18936ed80abf613ca826ac4ee044854c0ee9861df90ddb3018961518112b517f619f15ecb3827d59e69705fbb260260fe7727c70240c12416cd9c1c41babc26f33688a561b116490a2254cba4d1bf5dbbcfab1e48413aeb658e121dda635f2dbdca6c985c48c8264ca5fb3c95f73eaaf592565424999bb6d4afdf5b287739509146890f232246a2b4d5ae477a95501178e58f9a1042740504977b9f596c8efb28b053655a474ecca2c916e13eab7e9f4d7b7f9640ef97494603e1da598b24b89f5b7ccfa9ccaaacfa9e4edd2eaaf973a9c3b40126b9ca0e1618db92185dfa5539625b4788152c24b0c26a4bb44e17749d543af0c9621b8146193eef284dfa5d45fdfe554ceef92ca0bd9c68b9bbf6457ce22d5e42c2e2d324baba7a5f5d7c91dcee500f2e508167638e10986ad21bfc91ac4944eca0a503790c025dda409bfc9aa024001b36608992b4c82a49b14f29bb4faeb9bbc22b19e90449e9051a40f72c85f12aaaaab8ad46d9287733c49daa059e2e4c7961382fc7e591d200c1145b4803ca52993eed7d5d3ef57d60d26f8b801ca171d2944a5fbd5d3faebfbb5f5e2ca415e517290d794579317d5df57557e41e5d72ebf7a38577b505d4a1429e28d115da92de1f7a895801d2660713a8344d491748f5b16c8ef71851b98b4b015458519a8a4fbf5e3f7cbe9afefd7d36b081ec1e0514cf97bccc263173c62e1b10a8f3c3c5afdf551877320b841480c63c490b01322f5f17b749a8185146a006303971ee91e9f9e84df23d411dd0c312c41262b041de91e7723fc1ea5fefa1ea7462a6c456c83ad886e443522d75fb1cb4accb2ea59ed706e5cd2c4901e42662823432ac26f512a07942f49a69440e5871ebea45b9c72fa2d3ae143161eae7a38d1a149ba45de87f05bb4faeb5bbc12b1701091080e2246bd7e8b50184af4210ec1525d584ad461291ece6de089335474d0d1c2134a52107e873b4c6d21c14b218a3031a43bbcfa1ebfc3ac0d58e04161450b0f880ee90e7b3c7e875a7f7d875b215711619422c229e3efb04a2b6ca215527585505de12e94faeb600fe7ea159e0e2d4360d5d0c312e98edfa09690962c3fd610c9024256bac1ad0f7e835d7fa5da8809a31b42058974873a1dbf43a7bfbec3a7bfe1102d20182d62c474835db0fe825957e0942b100be85402160d52449460f2258874834f7f75bf412850eaaf6f702a074b37487589b4b944dcfcfdbaee4ecddd714d7d5953bd292da9bf417a28618286aa89287a48f737f56f7e7f559fd55fdfdf15ceef0f2bcd47244dd4df0f6aebf3f1776bc85fcf5d9fee86a9526303902e42ac4e904ef13b5bfded42a5851f94b8e92125ddf94a8adf994b0a2c418ad4b0860990746737bfb3d65fdf794bfc9db9bce4285ea6fcddb949aecacabb9da57232fc7802ca8e24ba256914bfb156d5902436403142e40459e9c650fcc65d5d57968082c85615978f74e736bfb3d3d390bfbe3354f83b473dc1609e88d9b88badc245559867b10ee7aa559b34407a3abef850a4eb3776c25039e81842ca933527004937de3df11b4bfdf5df98eaaf8e3656879bbf4eb8488d13d743e1a2acbbc3b95a86479612c82c59410a98d489df57aaea5a31b9bf2fd6022e91ea25eaefbe500ef0f1376bc83bfdf59c0670975205f5667ddb285fc194bf396618a2ebc70a3c64f8b2246de2b7b55a00102427f43802831b2ce9b63daeff6db9feda24346e91f56da3fefa03aad2586fd62ffe3d8af96b9b84e9b643ec1313bfad53056c8c10420424b844e892b27927217e408982cc942d4b6cd9f284e50b1a273a1de9016e4e57b4c7922f639e44118509e9c5b9ba0686105ad0a1c908315c49ef9aaf00981e11212c99024c557a95f8eb38f0affb127acb9ce82dd3e9abb76e6ba2b7eebd75f3047aebdd5b3791e8ada7deba6ea2776cebadeb17f4d6bab74e1ad13b76f5d663af58158faaf382de31a7b7aee382de315b0c7ac3786fdd0683deb0abb76e96a037ece9ad9b3ff48675d1dbecbdf59e2d7a9b5b597a9b5ff436796f9dcca2b7f9f4d66961f42e7b6f9d2684dee5d65bdf71a37739f5d677a0d0bbe4bd7520357a97bab70e8484dee5d35bcf50e84d3ad19b9c7aebb318f426796f9d4704bd49dd5be771d29b7c7aeb2f2bbd5f576ffd9545ef57efadbfb2f47e49bdf557958be8abeaad874588553fbcb8e2458f994da2f3f41ebbdeba57d1fbe5f4d6c75e888ebdb7be0208cee5d4ba4cea2ad5add00a0a940f6d1f3acc6c0a5d08bdc7a9b7ee60f41e796f7db645ef51f7d6675af41e9fdebab6416ff1eaadeb287a8bbdb73ea3a2b7389ba2b7b844efb005bd45dd5b171241eff0eaad8342e81d5ab10e6ee90d5abd75708dde60d65b9711a13728f5d6750f7a7f5d6f5df3a037e8f4d683b4e8fd59bdf5202bbdbfac87f2200882a283601623511ff27ce8a6d9149679d14bb34924cd269066a57768934aef9cf5d64d287a67adb74e12d13b57bd75b288de19eaadc79eacc780e88dbbdefa8bca7ac983de7807bd7110ebe293deb7ebadf7e460bd078bde77eaad0745e96db7de7a5011bdafee15c03583171d4800697325cd497cbe62e4c7679f65bfe1ec349d4ea77b4ab3111fb6f8d05f665398035daca3d9048a6653b6593827d3c9743624f496e9defa96eddeba6c274b72a5080f9539c9745f14fd5f0ef779fd7e979f7fcf3e7b95faecf92ac5f88c6585309fb1ec867c76d06ccab52a7d0f66b3e92ba5d0af2dfd5aa34b157419a5ad1859e13176db8d56b352a489ff3c5f2516ff55a50a840b9fadd98471ff15a1bf5ed1ee65bc1144e9a4e82d9e59e449e1b42a9538691e4b5f29320196b2b09489e505c58ac345d8afc61883a8888b70d5bde1f034deb6eab1ae1be7a2a979accbdcaab13cb5bcca9205b2e441014b59cac298a5e804acdc71428c953b49e81268069aac9465d1db5e5d5d5d5d5d5de1943b5b39a598c4ac14d55ce9944e75b553024599c18856caa674f5945a47f629655bc49f12a8aa572b3f1ab4804a5993a0527fd02554025df172674ded2c3f1d325a962da8284536b652e45a51c246182a452432515926b9955f1ad16e5c510964456f7b7525b228c5234a71a66b34bfb528714cd6f78b5c6599ac0d6f947345dc339e342a7b6a4eac4538173a765c95f1557f5199b2579ede9465caa82da22255e15c88da2b32323c268fca9b9a6faf663a92aed2b6568f1dbb6851ab12682eca0f8af592442a3f5114af704e0cfa7c75f86660448ab637e79c69554697067ffb571df40e1f7c38572cd2ea598de09716c1ec9f69dc100cbf0fbdf13d08826808becf68c6e126a4675c7e58c962d046ed267e9e453dea10c5a9a0ad6f1c4ec4b966d3222449ad5e95212b0d0dbaeb99d6355ba6cf33ba6fe01b2d63dabde1330404b83a5b8fb2676c367dd93400f9e6cd6f1c3add67b483d16f885f91b2571c21b83f82f8419403fc23fadf35b5b4f52dea19cdde1bf8b3df376f42803d3f652c6af03fd75ba4812e82a7067d8b354a54d3b2e72ca2f8f6998681116d7d572b119b4d1f885ad3003a2e00e1c20f016e463b80d3ad21abb5b5625a5355aa32aad7db757d6f5729a7deae5f1ae700ead1f59c8c36d5db1dc0bdbdbea216fca0d19bf6167ccd6d94d72da8325e7fbd8a4f1863a85b84c590062ec24966b5f681f6dcb6123bbe50160a63df007f7e4f31f41c8ae199dfa2153c71a8d634dadeb8c7f5fac65d259427de0f8d756b64abaa76aa4a5dd036a1592a5e2d4700639d2a5230377d8ba55b290fe01c0c45f57d6dcf8ecfd0471bb6a610b551e69fe5b4786934f75bb652958751297b355e9007d1f6642cbbce4fe801dc9cbeb8a58d2b1f04cffab9ad36fb8c73b6fd2dd7a2ecb5cf5b97b6c74ed06c7dfd1aab36cf15004e9ec67cebbc132e8df9e629ddab87d64df00b40ccab93d6afd9047a788a2f7a782e8179ec7412d3d1699c03b8b7ebaf13832ae6e9e7cde8c49d49df396346ebd23fe2579ef884f6df3acb0d51e0d31880d72bf2662ad2b595b69fff88fee342fe23a2190079cd831cfb2549bb23f393e8a4488aa4e8a26f27495288f42092249d244992244992244992c4c9f199a9cb4c9224e943923d64a9494d239dd42167a4e79038a4cb48922449922449922449922435192361a4499664261de8ac9782ecb553c445d97f4e1b2996f072cd45d77f81fe73ddc783fce7a219d4fcc7813c3bf6d1c5fcf432dd6a6151d4bae2a0f3ea70d1cb814edb858b5eaf97bf5e4ee3be5e2ff7e979bd5eafd7ebf57ac972665eea382cc6f3bd5eaf57cfeb4543b7c8836ebdf3d241b7d5fd6bf6ca7939ce4bf6728d6e0bf5afd7ebf57abd5eafd7ebf57abd5e31747f4e30747f4f26fa2a5f24ba3fddbf72d7bfbc76d64bc1e73fa7888b3ef739352efabcda5e2807409ebe2110a4f56ab356c7c32d6ab1b5d8626bb17f19049d043ff0033ff0fbec67cfcff3c901fe2e309f568faef730a9ba53ae9276faeaf9c4dddb122eba8e4bbab71b8446df2a7cabee5548020f540f3ae8a15fbbc4741a97667b9eaaf4005586ace71c6b9175515753ac47d663e7cf75d26d0a3b7fae979ed30bf07360dffc580527bebe66b1a184c7eddb8f6118e210dda367979db11376bedc9a178c2e827ecfcfc76b36ddd0ab79033f017aba9ca17af0a2366e0fba350dd0d3e50c9407d1254e9e9a68d22db2e29b674dabf9a138f14737554afe2ee14e1af5c8fad882f6df22f9354b95247fd1adafeeadbe58af5e170c81b426a8faec3f4cf4b6bb7dadfe7abd17ad36eee9817babb5d6ef73d2def2dbb9da8b737514f475a1223014185bae9ca1d8fc7dd94eb1903f300cc12fc3903f300ca33e10fcb21afb81e0976308c2e6efcb762a7f6018825f7efa2167305ac6e49c79743927f18484fc8161087e590b981cacad923f10fcb2182e536e905a22e74ce6ea03c12f73d1d223e74c43fec03004bf1c953f300cc12f47e50f0c43f0cb4168f8c1bafd40f0cb27a86073b64ba6c879899c57e821e76c06e37b31d8f5808688b77e1b418a2b34a001b3c3e38a4081bcf8e6308761ce91befda56bae1cbdba5895aa522ed14aa215fbdf1d7ef5af32cdb048d7ab93e1f9d5b1de3e7386e863eafce775dfdf33c07afb5e21787cebedcbe07f2478ec7914abcfc6797df55bb357276b48d3222a81c704705b2d8665d4deffdc667cc1effb2c0c58ad479fe31ce22d8390a4bd49f2ae3c2da8bf713f06f2050c9cc2ccfa47adf94a5951b5028be8cb9010222e2229a2158874ecb819290a43a464851344552c3e2822f2e4c663280a16405a90c04209d18e1622ecc06237a445f401113a2f5c3d845022081e0c584154f0a10513ed8344914ec3c614d9a071b89c408b3810e1a0c32945635644515a714249eca981826c9321493497c49001c68b3cdbc2e9c8806481b25c581b9423738891d8f3a5c52c0c0b7287a24c2be2b68308686b684665137980a8105f3ba0e26bcce9563c07e1201494673d00e92a353bbbf2d3c4070cc393412674b20ccd2c6bac9c1cc4038e48e341766b7c195f70ef05f7332fb8f55e6dda10dbc132b93373ec84b22a7dd96dce8ef3bd5d8b5ed4de7b2f112f116a24a9883d59c22024a0f87ae10381b0f98dd0d6efcd366808f26b42c3a277feac944ffa5665dc6a9dc80e38b06ffefa0df1b3571bf9bda0770622a37307e1df10ffe702ac538fac59c3fc8a8af588a719503fbf0ec8e987e2f020e7f0cd14babfe8ce135a3c33ce395f8b03db1efc7dbf5d5cc415875f79686cb8d7f2b2a665dc17ed5ec67b7b86042f5b9248abdb31da46f13194e0a1c3951f8e20a24c5a2b88820b550e3bd82401c142f1d66553aa8cfc96039f4f5da56fcf40073cf67beedb5f7c4fd4c6edb17f32a90f95ed6449eecd7acf11bd653b190f99d355cabd951129222223521455e4a368c8df5d0425dbdd64bb22d9aee8c6c3b91a4c52d0b1c044162042dafcbe59d00684221f38a10b018874dfba7edf96d270e95a808147096fd27d7be2f74debafefdbd64db7b9e936b7db8deaef6ddfa0feeefeea9bd45f27eae15c8e11ca08e11df18147922652277e1369fddd41260a0626929cc9926ea2267e137101e20305365c88981242ba6f5cbf6f4e7f7ddf9e6e43b41081d122e6ef26cad257445df4151196ee1155e91e114ff788acfe3a910ee7aa9a214852c0c1c81a18aa30f19bc8490a0612945c45e124dd444fcfe6371114971f393061e20b5710e926da1149fdf54d3445fe26a2d244da68226efeee21bd1bd2bb213d35a4a786f4d4d0d00ee7f609bcbc312187373a6459e2f7d00b3a2755218871626647ba87b67e0f518006303a6489a2030d27a47b68cdef21abbfbe87ae62bf87b0d20c1149331405e3f710d4d6908fd8d690bfbea24beb86747ac8e9afafe0e15c03c20061c6092423bc014289df2bac9ae84a82ca981c88689921dd2bae92f8bd220b4b6bab0d4f47e449ba57a8f9bd62af58c1a56545142d2ba6ac68b282eaef5e51155b115b115b21f5d76d3d9cc340cc112c167ab0c10d9a1489df362d105c684184351fc80025ddb6237edb7a1f6831028a1e5a745049f70add0aa7bfbe573cc17eaf18127b6203137b621363eb62c3fabb6d595536dedf6db3faeb361dcee588caa18525588c14699225cd6f1b9a188ee872e689d319a874dbb47edbb0b4c023ca09549e5449b70dcd6f9bd414d55fdfb62adb94980e156d623adcfcdd2aba624e2ad43871fd85c2453128adbfae628773357448783494800505efcc6f1552434dfc80626a0a4c1050d2ad62cacc6f1555171082e68a8b10639a48926e15bc32bf555805f15bc595fead020b96460511581a15512a7ca818f277ab80826da16e605b2a78fc75948773475a469280b0638a2921647ea35a47a889828d151d2a40916ef4ca88df6856932294e8a1890f51a8a41bed15f11bd5bafa8d6ea51be5824541a3c0a2a0538e7ea355301eda8447054361280c95faeb670fe76a9b1d08563d429042e607dbfb7d563160a80851040952b89192eed312f1fbb422021b2082d8d1852724dde810bf51a7bfbed12774084c84130c4c04317ff7097b3a614f276c77c276276c779e3b40f1c16e2a4a93273ec6fc3e3da0c5083233f08010c142ba4f31bfcf18d63cb952c1071a76a090ee73f7617e9f527f7d9f53e6ef930a4c1b306efe6eefeaa9e9716d79d6566f4bebaffb0ee754b8e131f1810213bb35a910bf7d04a7204ea08a820c9523e97630bfbd4a032b5ba8a0b0830c4d9049b767fd76abbfbefdcab198381126517fdda1cc29f7313584d7c5731dcfe9af0bf1702ec71122d0a4e08305166ab0f2e5b7908c1dce7039c1c525cc07e9160ae2b75056069c78a932844d1125b449b71010bf85b690902982902982909010d5df2d54650a4199423b5348eaaf07f5700e035d636e6842c9921f74c0fa1d54a138320213676ec04ac2857407fdf03b288745489a10aa70c16221dd423efc1672faeb5be849680898203060c4fcdd4159bda02ebd20acada0aaad20de0eb2faeb413a9c8bc0162740b0a10ae10b0ea997df414e2190828411509cb070440de90ebafa1d046505c5ca4aea863160d21dd4c3ef20a9bfbe83a682a84a266d4a266efe6ea0ae2935535c3ca02c5e8fa7f5d781763817aa41c24409251f9c8025e5e13790140792f0c035029b2e1ba64837d00ebf81a480a1ca13504988d8ca4a375097df401b0808ab0d109136517f37105409e4a3041a52d6ba4a205d09e4f4d76b3c9c7b00970f7690f24215ac255c7ed774a60c3145550a2a84a14a776dcbef5a16053c1c4cb08107066b8a74d7b4fcae69fdf55ddbaa7191b528646d4aad09d5df5dabead5a07ab55d4f4aeba7abe6f4d777ede96f6d08c9e4070cc944ccdf1f72ea879cfa21793f24ef87e4fdfce8702ec79414ab16744873830b4c58fdfe410ae2861b868042450712e9fec9f2fba7eaf0640bcb0a63acae9449f78f0ebf7fa4fefafe99027fff50b569d3c6cddfedd345ea7cd4903a1f2ef2c9278b7cf2e99101a022a814091a0f7349a714325323c00040002317003028180c8a06a328c9b144f90114000e63b65260521e0824f220857110648c210a004000008000008001a588ca00984ddc1a451fbaf9cfb961c8ff7b3289e65cadbdd42222f66c6dd6ab7c1bdf1cf354aef12ef285df769b694d6dc1a333d0b5a3f8c7961c74a0d18c4e3dd24813a7e9f27ff25e9a1dd91c9326343a600a343ef5146b088a2bb11db8e2bd1fc26e9e0acd637d1d476173dfddbcad8b587b7267872f7993e8e7dacf52614b1bdeaafcd3e9be3aa9665dfd2e71d8f38ead7514b0b51baa7d7eab015f23ca901cc98c0413bace4278363584745700bc2f7ca205439e90da644d1af0b2c967765d8da3d3df290edd2f9cf2f48b3bdca118d5d6219b6ae8b4c33159f190f0ad12d23661796dbf0d3d46d64c6096ca0565c41bc82e53925b09e0195e730346a1c0642ac0762c782667a657bd58983e3a8369db82fc14df4c805591c5fbe8a63c420b9f468bce76a6f6e011d37547d5725005fadc4e0fd345637e8e0cb18c4ae6dd1061371328c52b1243f80e949c444a63ba5761a8afe2977ec36594747496e8fef731c433c3eeb1d0d4fcc9fdf6b11859b24e1a25930c61d914d4faba54e98d5ed4fa360a3d63e77d8aa7829e273a89c921b8aed9487bb9631e24bb547289d42e9521f2525d787d157d6f87f49345f26d501e97472c6e0d1eab884ca5d0a58fd4dbf8f3918233d097deff66b59aafda223d13c89e77d3a2ef63da73678d9de076508298328aa1c0f6c8bbaeae0dcca05c424cec1a375b4140a5c3e1a600280a39219be2449bdc19889004b31d38a7abb8d11953520f59b045ae700a7da6a498aed89686f7e93aead269de6e7c31b9abd054b762f40cb42cda90661a5b4a99290828a69def47260d649b6b29dd69b987a21275aada3f4c3616e554ad56832442805a962a68854d48274f4a9379ea14136e4c3e8b34d6377e003f991b3b73e4954f2920b0a5cbaf78b2852ccc7d6f7bc11981e052475c585592380b8d49ed07aad0b6b4f3aee88367545be5f15a2636cf5a225089fc7fc859ff7d41bfda5379385a2293bc6a1e9bc464b9b2a059484323829b897417ddd929969b47ad0a1ddf0339df0f15388d7c1e88a801cce4e69b09988e7b99428bbb2bc51bb64ddf4f022d57f4feb932ef720745e33c403818245b4f786ec3445ff9b020a71299336c04ddadb0b968f1081b6981a7b05a70276f8a3e2475ec520972156ecb28d02b08c266e1ea436434c9b06eb243fd122bf46219028429b3c013b9b6746ab970370f957df6fd2f64f4edc25d7a53f220339b5337a1c145c448f46f9d2f638b9a1288abfe40a3ca171740f87c1da80fc6349a5cb97f64094a383086c0dcae24701e8b0e17ccc5c07accae4233dad06aa3f31c706e046b7e50e7e9012e270c941886884026fa8dd0cb94b8dfd96a9bb854b39853bb78b30b30d209e810e5f256e703a6a041dee10f28cc625cc31ed8dc3520c2f8593c4632196fd7a2a8d9a0739414c4692c11b771f94e059c92aab39bd05bd24ec8189dccbd68b43e246ae26b2169b03bf141a60d200e280b6e6826703a008e9eddaebb7c5c3e5aa63cd390c8884e9e5f203755dec2f9bcaf695e54d5990806af7b6795acc3450fbb5534e322068ed64018e2f83ed9ef25705b193f2eb28fc91190b3c4685e17053dbe12eaaad9e4b683e9e35b32dfa544f1e87e301a1c4a6a5519be059303174506af9813a142da9596c9f9be4025a77ffb80d9de20e5db07286065345dd331684fa9dc4c352704695315322e616356d685f5aa05b043aefcd8882a949190870984a2a0ac1711d1f32bbe380a5169c09fdb553805cb7839203d0e961b5c3b6712d736b0178dc0c8fdc3604458418ef59a1495ec17edbdb0fd93e482a505b98e645884c80cfccaa2ebcc151a4a59593d76476620572e0288eda5954c755846875d40ac7c68114296488107a4231b80358a59fa70b383f0d36f684a5119885bea4c36415da8f7e8e4b551d995b449472234e3e14f58c2e75bbb060e558b7014abdce08fc5bc86dd8d83d18df260375ab882fcb42866eaec9ad651cf204ef9790048beef049781281b24a0b6aa0af03f183259e16a4ae993d60d471ad0220cf65220df03161ea5d63150ac17e5828c4130603d662d2b7bca17cfeb7cb85913df739cc507e3edafa0525d79d0c432ee0611f908d7bbc0a4774701c159ccad6177486e090f8e1c26c2432b74dd77c9109bf448dc2b1a4d2594d3f90b5260b1f31bda13e67ff72b008d1c7b5813333008eabc0ab8e65b7943d79827b130f38fa6b3560131e08352224285d60ad88cf75986348845da5b733b53b4f6b2a722259df684eb8a197029e92f568a2328bff318b4f6bac434abf55c42b357f0955d4e879607e48cb80849dc3cee84f722fe6daedbfd4cc20cbaa08904212285acc9f76b2f9955511db465e06dd0a82d9052fdd53da7c962ca46052153222a0d7e8f7a82fd0cba40458bd8105b97c4fd3bd2728d0b0797559fcbe18279dab5b9a541ae2423f23e971d0fe1d60ef654a3b512932aa0ea8e369d8240358f3d177e410c37ec8b918b4a7e97a243b382ba64e96924e571117f7458b358242b6795f0afb0fa388445fe239e16cf02d1be3e6df042448478e1bc457769af7e9705c560038c239c0132892f0e270e30408e3f8ff30388a864794d9f1d8511e9940a802a88ad15716c87d127116145711ef66089106924c820dc365d58b73e8832248a65ade3ea71a224bf922885053a7b8371eee4c3988b55d516e545bc6e16468f800f27808423fd5291b48db1ea191a76afe23448a6af1277c06994c93b41354182680169c2843ab568f9ce0718fe09d05f3aa1f9b51aeb41cfa0c61be9935ed6841a1da7d44b15439934f91c5c412857b17b4fa0c89dd026c15ae385ea91c9a906505e3acc355dda2e9ea456de8a793d5f3299d80a9230f0ce2c4874d849c8041603445b9e26aed63592e7b51d4bdd4c88c9c39a7cdf40ac46fd4b48daba5523e440b8a4a44147ebe6666fb573dbf1b2359bcc94fbb656bdd1871efcf0d343a5a1cb3f4c545905919fb0e9da13a75a97a7cbe996b30fe5562190c095150871da3088bdfb3b235daf2378c3f1a6df731d7fc8875257a1b79fda8859abab929b323932b3e8059187c810170466ec1a012018f5c16fff5837e1e203cb1a110f85a23d09b23acc203f0818b7cb9b082fa1bd61446f68b5e03d58a54e2bd96a32437b3e817b459c661966891ada83fc2aac6da067c268ad1b58a88c1fa290553f059d3c30638956901de9d54485f5269b10befd432eec6d1a1ab0cc8a15b2453f2562c781526acde7801927b34893f06373533b7d45e6b48c4ba67d09900efee3e23162e238ac260bae8ef40a22b255264c0c3f21ede8b771d884692692e93f0ef41656946de9c9c48df1125a902fedfe302622fdfd23eed8633a1ab3c00a2b65b20fc67d2b913327b3a62b8912564d3781ccfc83713331dd27e782955322330f1ffb9859f8806e76ddde7021ad993051d9d6bd4eec18a7b4644e566a86d4d83864c2c426920dcd9c8895879b326902b2a14d5362e25053a64c2083ffb9b8d56f80b492721ce0ca09e3b13a3efedb415726ac3181ccff810dd5bb28d7e79890af32c6245a2eb3e2976034bd4e6f084d2f5aa0fd257493ff6cedd36c84b4087cd42bdbc44ba029a51dca82990a4767203b454a90ebefba85dbba68e356900edff736e47094354ea2855b898c9edc0ecc225bbb48fd7ee7896122cca36eb0bf3d850d82dae5665cfa9314c8b435b858f38556080139d75cf5da329d6345f4f12ae567c09dfa7213c130a08a4e90d4aa3b149384fed197e3e9477129567cc28f4a3847701d85cefb443f7718209ef39de54064c203cc2e07a9e31d01a934a57080af926fee6e5d37fe1ea521f6c674e5c8b44ed060246968eec115a0bb88e0098dd38be8e0d2a7832ba10eae4b325cf893e13232ffb06dae919aa1bae8d0d1f0b221c40a6ee862a2cb5e4d0714bcfb4a90fa3f3be27e64e92fdd64562c1caf3a87e0e96db1888000949f57014c69543bc7f05861d99cfe52db502d7b1af734c23b289c6182b2422d007b8195c932001c6c3fef3b1b3864f2067bf37cf8579a0c28466851c129e684437b6a7ef03cf06843c5d3cd0fe73ce5b215f54e373ffcb424e03654e12654f6e8fc1f49d92fa264323626bcfaae27342a64a33d4f09e32ed5a62cc85f0aa4c846381b297093222f4d1220fb4f64465e0ca7dcac093f3eaed7c36a7d09d4cc832dc5c15084cae1b96644ed951f18fb6d95930056e34cf3a2ca5b6ed0f6809c9da8b29517da5f008e020bb6ccd9799773b5999cd49eb715def6ec2eac642b4adc5eb185e9adf196977edbbd1331e867a8ce6dcc46cbd39d08edf85e80a3a967fb6a701457642b3b6f5be1855987f1396e9991d913a99868f6a55c23cb36fa9191101754a98a8e72a9f9e4a4cab429fd3a2771ec26d668590e339a39c94d7c687f245174db142e813901572587117075de0f83632315b37d0bf7dd455e649e9be53cf49c7cbecd459dc72821124a79601cc008aab5fec97a88375dfb7681a5aa4fb89d8bc40096e803c76a7ed9b7662c06a3f1327fd75d9dbf0a4f79729b0362ceca7466814a4fe0a9484d16b1b6acfa8cb5ace96f5aaa7f7cca31322ead83cfec42ce1205249bb845c14f9e1b7208f9c389a323aa820a8fe11c95a6a7d5bb5d4e35a7b190a4893578512ea3bed8484ba220a610d20c59aa5dd4c2b01dc5933a08e4bd6993e19922d8c509293b355736992042b58528d3280039fc0c3069eca6881234248338b9553a350df75c7f3956501c5cc0dca0c3f662ca6d9e0cce59f58b491c1aa71572702580c50698b7895da5a3e135e2d7a423024aaf7ca9fa1490b24cddc0e507b86167f263e5cf811e1b086eee70a1da8813507b5a0842b5e38a8fce326bd784108ed6a15f8eb5454850ee1d5a255d5cefb00b5e7a72234919859216dcbf7764b37cf55a32db7f6a6231a9b4c02b7d9478d263aa4ddbec17be80ae16f8bebf5f897e9658d4d7debff96542c658de7725754c5823eb134829f9c0da5cbb9d2c2f7d5f80e06ea244ccb5a3bb789963589fa5bc947dea01e293b509473be1dfe3cd60277f28ed50a59ba77c0c297a28d9e84629d64c80e9b7cd8dac03b02ac31f44477532884c09b00be7de1b71ac0d2c33c2461bcfa848d4983c833663d383393c590b80e9c8d9a95853ab5783c55c9c8c4afafba0347a7d192498e7b38829ddf3b8af967fee0023afbed51f7a5c73008cb8185dd3351a53b62bbd62fc74b02948005829938a905225c98302e795aefd0c2160bd7d113181824a3b8bb4ca79a17108c11faf4be4bcc4963b6b280f107787126fe5ce523a487019daceda0ac19d0a6a982247e0668f07955033fd80f668381a07443e6d854dc63156722aa9d71c9a90824dad985af379e78812b7e0451f161351403e74ad4bf00067c7cb433478e438e06779f3d7a1e4a8d69c1c63c0590bf4ca3e18b9841e8ae086ba00822f9478139895d6ed92e9e2a905b7d2daad989f46def36eeb5a37e2eec5899755eed980d75a2fbf5a1ec6e20b64fffe8681d999cda81e790dd0650bbaebe074bb9e78dd9ed1d4f7ed8e078e4ea2cf3f5cb501ee9b49cce98601063ceab24b4883d670fd72f301ba80ed73332f0edfd2390ff702226192f95a702cd767276ff17a11b87a79bfc81bfca5d02bfbb893eac560d4150bd82989659a32737d06256323d8e61020adc76a3a741101b506a1d501416d1a4abc7b9108bafc12b004f93da056573d9993f7a2822cefcd1034608d60f3be8d22a0a6311121eea938d6e8eda267294070b23e8f64994aafb95edd4708936005ebf2ba4282e2060176d1be11558a6664ac90e4eb923ebd25aee87d0cc9f3a83ff73d935c7e72bb8e794e6025fd5bb33fbcb32b8934164120c8fcb28307face6c2afbdf80ac6a06f640a816ca84a31380a3b138f96debb920689701f19327ae48be359c9b27963eb0f45687fa95f7d888beb4836607bf022c9a71b9d649079a271dd7226be9762643c9730b0cbd1b6d041baa65a447f231f84432ae121000326a32e488a01ce3d051f2d4e8b23e53eb0b4d5cb81712760de61828c35058b8c9ae89eaa85f8293eed0b70104e3e9f0997e4e879232bd392902816b792bf96264f442cf5825da4a24d6cce9a453c8e5188fbf0d508c5d468874c374f7050d8e58726810c81f1ed0062d303d0bc289b5ae7986409d6c586e9331021e874e0afb0e915ab0c8403b0c9e022dd6e974b7b61a60933e2b0c859df4bd48e0839288408cd1e1276550810871c30bd053b50153ff758d83967fd7c1779b9bf0b829c30c98d5c71df838891845b1f4256bc45c2268a33e40408df62df428d7800e4dd0bb0ebe1bdb84c7471986c0549cc2c0e7580fa422decd6a2ff549fb350766b16e063da049a96209dec7134ac46add0c501a430358fbcc7ba82496ad61553a5c3639bc3560d734fb13f0eba8a6f1159dad44f5ecbc6e0501422e8c18c223d80514bdf5e29b1734313cbff05a0820bf9bd124602d479094885b834e18772341028abb2d6616a820739c1305d59fc53323b73b7b3887b2da9def9060bde6570e7f40564ff7e598516f3cd75557c0736d25924e958430a0519a643a183d598fa7c50ae46fa34989ea6fc4fd0b0e5e022ea0b7a585b93f871fe91f0181aa7b8dfdf48a7e78dad35508581b5f75b7bf79898aef7b8724b53680afdbcfa692b72daeb800667fdf778c3232151a33c7dceba9e904e33642b15026e027593b26de1663fd3134c53efd07a705a2a277b6d65845bc8df1b1b0c754631ecc3dc1f622c1f19608e17727da8ed45c7ad38259694776dd713bef6ae7fb8296455859cbd49fe76b64e62ecb46dc35b2015882b80bf432c04c5e97ec9183d0e94053ec7ec53a24c887bbf63b4a30f3ac740cca4f0c4edccf83663764d3dde5118177fdccb8fa922b500b99e0dde9e98efb900cf727b1b715094475dd1506f070f3ccbd5330c7839d0bc2b1355c6351ed1a4b80b8b4fd662f1abe4677a0d39a82504afd79087554074b98613db55a5161c4825d19e5a173b9486a4fe9722201f8ac91b2deb558a83d1560740d10cb71fe45cbb125f1536f657daab26c995ac93ecd5623d0c49c6c29417475c8b7d7da8a49de1ef82e5c50aa85e92e9fa25bd3b59490ec1f182f90220e6c9d3dda03e676f26ef384c027078964f11b3acb9edf188734ab8cdc889bf71abc4041a7fc64e733951f06b49b551777b7f481df974784aced2540054d8bc14ddd38b8a593657a1390701e14b6178848346e0d2431e3b9f0b83b51e02d49bb82aa8d0907e71362838655a8d1c0b798a4fd0858ed8623f4cc7847f758be0bd1a894b489a54176f34af19786657be77fde0a0f66e970f0ab6c323ed33b9a2bd58d8768f535aa686c97b5bd12db1acc955066e47cdbb8b0ee0ffc4b78cf4e1104824ce3ededa5e168f6f0275c41120fe2aa41c4d56795225e82e18437c9f2464bafda3a7acf8825ee5eaf8346b494ff932c0dbfa1873afcaaf0be3f2d304ae5ac84ac7fda4baf5d3cdd94c9fcec4ea83d1ad99600b89ba928719117223081699196c1f058f0e2f458a9bdc172edcc8d6d833ebc5cf929a0ed3937dab80888a2e19ad5d2c6dfac4d842a8fb5515d4e7e278ea572729b1d75d2b8cbe65bd5d20ca72c5e70116d4a919b0c42458a8d1c5c0db95c7147343cd1ce75ae1cf0ddda17484995281ef575a06558fcbcd8f8955b78cedf8f3ad053482da3ca8a8c4268c6388b257d160cad4bb8634a3be743f3403e6b797014b9327ccc02d405f9a2472dc05830a1471a264ea008c968296e2da4bc80fc303462614614dcfcbcd71ac0a1af1cfc79bc233a4ae3c15691501abdc18440c409000d811e89caaf57c4734b1cda101535ae6a08390cc2aa778a44403e75b276fba8b20949531fa481ff8a7176f0e4a8b527acebd2ebc2af8a935aeab85e3b27cbb2643d4aa8d5cf052add460e5d0d50248abd0a309f0bdf883f843ef7e7219a968e64f9d6f7b8cf3334acd044c63a5316e1d0ea89e1ea13c6c0faaefe7c03c4853750c8bf591e6448a6a3dd0734e7ea2652b0b321d516cc98fe5a042bf754a5d6ed54e28ef1de1e6588cc280b1760dfa4b92d322d025f4c6c0f7a1800b8c9a31a8dbf9dc732d59a5caedf273963ca7f5b83ed9bbc38fff45702159e04ad5a41d9980b3d6cfa40f4e6e73096b17843d47887dfdfa867cc0899b16f57b5dc173d407072095ba490be9601d19560e025affd6c3fd7c72b888ae28a0ec089ea787cf622e4038bfc30c9e3b14430b77d3f9e2e9955c9fc53bec34e6b2a7fd9b6ec69a7437cbd112e3a8c52e5115aa5dfe206b53b0407521bc8c62b86fca04e4960f144d7f2f24972c019d6a001e8f5f0884b4f3ea124aab54cbdc12d6d0e7fbe953293a6c1359f3d2593f794c3a2898ed250cacea02ec41ecf08312b999794fafba93070a0883a7b1524cc59fba3bb85a02942bd2e0d4160f1686b98815f8b96ffccd2b406f581661b70e921a0a2ac80c15ff39c9f133aa0204cec49142024cb765397103bf1f92989af2d67116e133ea8a8e86bd323b5c256584661fe1f366d40e3aa20be536254ce39ae4e65f812459779a91ea84a1dc9f0d58533d205820462ad75f484d43151de8b765bb8fb060fd183739f834c8aa4387e483075a3c89f4d8fce0e7a163d0f7bcc9b276611b57122ade7f5a03916a861be49a04068093a094e11deeb2fa00b21795218eb897cf0e59b555f738c92299d7146995ea78b274a69353f632d5c31c39e4cdbdf79a91761bdf08305938617d5efc49f755aa0e6b5c6bf3223c9f9058b33fdf2a88479e96428419e484bfd46a8a741f31cfc7d4d521c11a9a1c680b1bff22b306173095c6d3224274dd22db0e4fd467f9990fff220b758e21b4f406f9acb6eac1c993250de2d35cda3156d71ebb25ef04476e3e0cbea9882590744c3be8cca0ba5146fbe7f3dcef9d7a74ecb14884158704ed2aeff71871939e9874a5c6606af1f80cf558c1857dc4855de7460d4511126c922215c3e742340b31d1b5c3b75c848a71d71e6f411274e3b1e0bbc306801ccafa0c24e30aeeff05bbf99de67a47cb6f9dd2a471819902dbbe4e13f2b700ec818e7d5cfdfb759c0909b0ffb1105e3475cc00d382ed67a2a9321e5eda935e9960ccbc2da161f65fcc009e8efd76dda3fb759ce9ca624b9a51bc1d25470eaec57cd68bdc9e40406221871d87eefc7e074c5b064de1f97a7f874603671b74156e2e9e2b8416234bfabb8b9b1498df26dda1995549ecaa2d6b47e406daf69f5c8824bd11d2bb6581f3f7012b74ee68ea0624c3ef044597e1bbc7bfd047c087376b1bb49a575e6b4ed52531f1ef9d8671e77c8c6f500a0365ddf2ec8f8e58d0177d8d8a52832298678e6f27781d35a3c4fd4c87eb124863e8f644a01a630ffcd5c45a137d57a14fe3a1e2f87d2f10cec055a5753c351b3355520821ae8e90144e65b3d4410b5046da3d54800aed416770de131bea0df5d0e6fa1abac86944d5bcef9a9061f5dc82757e998fdefb399ec5584834dfc4ba4f47db06991bd1c7ea8452443fbd12c9c65979f66093a5ccbe708e1a5498a1722619a93cca0004c355b70edb15d1f5b3a601aa6b8d647cdb147a034da108e24448ff708a5d34b979327258edeeadead7b2edc619199863ed14db7b5b4a7a54adb74f45a1988762a2e1098d81277134d7bae71e526b5473ed7a8729ddb5d0ea3d3a20a57b13c4825aa64ca96e0909c2384d7b0f30fb3de700afb1887675accb6e401711fba90632520fb680e5f28c518b2784dda01017dc01475a245e3560d324047758ea20dadcbe1fa590b641d3051697069985b00ac1cf8a5c1ff7ac920093ab8606e52264cbf63d7e8c034e32699455cf8d1a2ba5a7f80f77c3795940d8de31759c66af7c333103b7fce6182eabd3fe7f051c0a515c513bc87a5ab8b292a6d7b350eabaae8b4584e6d1dc67d85f9bc0c6e912f69209ecf93291272b659e2069d0354c36d4b744bf9d744e05aa98d94d40ef903cf4a33e4751b66cc238a9fba76e1bf2b136819a3be28e6fc16d8293d73b75ddc691a393f7793154d550d2ef70c8c99cf9de43c1fb58b1770835e819d8c590f9c34995e818d4734319dee4a18cbc9a4372002663e275d4283733c6ad80f69361f768fbd9cd1805e454074d487ebd9e398116f14f22810f94f826c01b903e9b463ae9d050e2a6cc801c4ef9e3d7afa8d174f172e44914d8208699d85f0fd77efdf3d7b849e922f52f24d5238bfa59e9be8e411b3cd0ed770f34fa8ee9d7e318632d1761fc03287710e6f86415989ed8e6857b82f81597b2917434d1a72f0423ce20afd758085b152d02e07aba0998e7c9a75993e3701319e70ba52ee49d07e65bb3491c9eb96cd1247779441ad1284a30be8b7a162188d97628898a318ad09485f419f44a2119d7aa6bb5c63b4885cfc65dc284474847c8954964f07f8db960545d6ed93fe8aa96dec8cdbb208c8963dce210dffa58f45a63923feef227c4f48659b27a2452ca04573f369efc7cfaa39e90f7bbc926617be5839d9aec0b85b0765f527ffa39deb652860e5a4a53ab64d6cee1dfd345a0cf0f7f7a54a120d6e3278d78ee1145c456ec76d58f454525baea32bcf14952008939d338160179510ef2ed0324525a2470f499733857cbb5132c3bede02842e5b5347186e8f5b13c3aee74af83818643eb4c23e7f10ee10696b90a07df12444af27d75765c52dfe9211869af2c1dbf0ad9bd768a31c9c3fcdbcc3c39d54a0b24408969c8ba15bc31398af27180bfdd0e47009e8a1a553623bf67d2f281a428e1ee9a70fbb98cbf234b4a0814be188d57bdf432380d3a6a6b1a800cda084184ef999d3843bd8fe96f4ccd7042670597696c382cdffff90137bd36d7bf6cef744ac335c5dd75ccc5250a954a1b600200a758f655bcfca7ca6a2448c340b242dddfbcc5b02ac6c7b62280067d49712319607c255c78b4466610e790eea16ebaf9765fa21c5a198e64260112c05ba9382fcb9573bf730504a0b59cc16f914fb8c640d9009bc94dd1128b260184970ad6d20af4476c883a557250abef836ea1a5820ff10456a84b29c24ca66aecb31dabc89b2d98c4dd50cc571101795fbe9677c2eadbe349b1fd22ad5ba6e6490e96934886376c79567291ccc13c10020c25811ea15691655a0417566a5c163dc6c60336e6cb08ca53e903ee50bf82edd7d5508169b2cc2fb2d9e9e79504455bce4ffa821b3bfa8c1f31faba1f9dfc81875f7b2f2f97fee01ef3f56f6e85c3cb428310494dea4454f03a1f182da2387a597878ae59f070b0b640f124be61e2d7b6459dac9288f438ab90b7f22cd750f74209e10d773bc2495909d36a13d4d4b6a3d5f96f83d9096a87b722d757b542efdf670a1aacfbc40b7f724b207ed9b0edaece34e7d1c4d651552af72881d9803e3f30b266654b461d6259f36125db2a50da697d4b561f8259f3652a5b6db06d3efbd6d24452f97b4ff27e13243ef683da48c43c1cc9b64b5a176d97da9fb86f02816b329924411489c501812d3a8ad606d0146113ecb42bc8b919cbaddae0c66948909a629a246d0683b65dda31d4605f79413619c505c757c809ac4c98c7780d25b9b032f0e313789efa0a4d4e017b329524018d15b9be4dedc4edbd35e8e6568bd34cb99bd4dcbcabd3f9699bd302e137b732c37f56a2c7ff6722c43eea558ceecede84e60ef233ae2c732a8f6c9f92658b9894c8f9099a9b60eeeb0c336dc80f19d7d5f01ff46d5f07393d53373b7ab2b717fa933e5865227e6ce566fcaad56ffc4cdaa0e999ba49e39775b5d99fb4b9d393794c7666ece708a19db4b663659197d7765ccb0571031c520420edda58622d7dec7e859ee4324e8dd874dd0741f3a41cb3edc04cdfb3009baefc32668dd8749d07a1f2641eb3ecc04adfb30095aedc32468dd8771da6509320ea2b50a79f4e6ce337e5499f81713949d4e2aa5969b2ed1e457350cb309e37bf76a8b26acd7e08d4250436914111a5a5020d44082e252c352148e1a84a2286888124553031214c41aaea258d4e08242b0861214911a5aa240d440f2e4510d5ae2ee01b89ff6b6d23e1967470a5b710389bd8a5da7bd22d105c84b6852c3703faab5d09075c08e60a65707108e6cf751226990044e47cae72df795af1f7e3ea1c14bb32978fb2d28a18b0c6a47d24407e86db92a3f3655e1bd88594e436c355481d09f19fba94f2da6039ececa6a2ba1db369304359350a72516ec7cecded51b1f4064ba791aa75bffc0da11fee13708c8b8fe9057483cee7b22cba86e228915ebb46bd2143a590672c82bf340cb89463f793628d9af50fcb3ccf3a6f0b8bada356f807fbe0afeba3c173428774d5b014a5a52d0ba091adaf7b38b308133229f6ab544fb40af14949c3dba11da660d92e10782c84df32ecab758743b1629114645abbf4998a1d0126ffcc3a1d0a04dc094fc10e31d7d7de0fc53c855d810ac644a513cfedad39bb61fa8218009f4549a1f1920122cb3b891ded681030a6e5060c54291c8a20af0068ff9f402097710e4155177efdb30b243496212cd5878d58650fef871238488f6cbdd69070db7f4f8a6dfe1baeea6ecd48060088d15101c0f9d5c2b175389f6f2d540243d884f0d4c47e0373273a72034ec36ae693fb5837a6a3bc959b85c6f026966187a10da300f610d99c0c3e17fb340959320be4a683ed3b530f8496ba55a0a18c527dbd8f347bb0e23647156a450f3431d6b8d4bde9ad9c55d0004012cc62418eb10e39509e6f77f6afa0c86d96fa2c3c27523d82fc5c040b2cf6a34bc06d9c26513a23dd1771a42dacab4a0c038d99f61c00b575eaa0ec8dbe42a773942d82a923816423a58af41b65d0d9528b05dd75c7540561e1611825c33ea0179594483e07d108218e109a7d31460277728bfb887a89155ea5ab6e5ba8f8a83c5a70a6d376ef4bb60dbe55bd971c4df31b61d48189dfdcb5870631e3257e67b5248517ace70b1e4b42253518224f0a8558b7719c4c91b9f837b10637c4cae21c6f8807fee5fb803fa7bfffed9aff4fb7dfddd5fe8f75efcbfdff41f066e8a505cb01b44e6242e3fd2aa67ce67fb8262fc0fd4ca1be1a153cc366ad50a9a5bf58296ab5ed0ecaaf7bfbdeaf5632ad5c303e73572c07558b9880016a73859ad0daa24dc943d1d3b0730078a86e85d311e69d769b1a321ed96873ac9775ba1240f040c27744670d94e8209d3049053f4c9a2850a4137916854b56a84aca506bca0d115e44185048d4dfb3b3d445ff8ba469a36cdbea834cb51a259105e39b72c1132aa7dcc519557243af3b5427e3df49070421cc0fb86d0a65a0059a4a4bfb360f8f49aea084dd5ca39254d8d255aa69a030bf3321dc609fb0966247802d67e10b5461567ff8980bfc97c831d6aad5181183f71c0ed3381b7e2d0b461b383b07dba7e8d2bc92670f843ef8d20f3bd74163e3aebd215d8c890036988238459bfc3263b6c3b889aac2a461f0b643f3cdbb402773be3f5a879120d2393a1c06c8b5a8ff8884d14206f8bb414c7f7bb5b3cf29f8472ec94409bb3e3083f64efc0f9e6d220114a6a02770391b31b86f320afa6d3d819bc6660a35281fc9d170d061a10796ad6000a8c8963684011c2a4395464856a656eef0193c3b662709eeed769bd3e60741b0ec67a837b4feb9f8017f097510e63f42b76fb0a96e306affe1b5299b0e38f9683ff51bd6f4144f551c2889b1838dc22db9a3b1a742e75ee1500231fd565b5adb1efc7afc6600cabdf84713377be876af28f2ccdf3cc6ef971b3ad034709c6ff8b30f1ff76bfc6b81541088d6f53d1f24d25a98f339704038d51be8c4e0ec2745057192a9c444530b38ba8d57ce150d15774a8c0654cf19debe0aaa829a6a8427bbea12b4f1a25b2c63a94b5fe5c9429ec51a617e22b3c2305c05f5104ad034746582c42dccdd1ac5d6ce523a2b383d4e98a83ec19aecd590f1c6097064cf7f0a8bf08d1f78e55b0fa5250c99ea43407d706431cb42248e4122686fc1f674860fd0765139f1526f451b415653c9dc1d2cd5f9fabb4bf2a0d44aea6bf4efd13f89726d653f60e3bfde2c92a1b871196f7f997e85a93fe8ec948d494be0597f2c6a873f780c8ef3c8238380acb747b462003e6463410a1fca9ca27503af986504a7365ea451c3588a5f7fa23c4199a0b1e6661587d821320eb323998176026156a3a0dd04495acf90425724b9c67f441b9413a1b02d145921929d5054711fe604cca4fa26084ead2912aecc4c16a261fabad8747859d19451036ae8d8be5fa1f479d40051d1144f6be80826c7846648a34df0af6f61674cb0d56adce67d8eff71f9ffa18e951bbdf9dfe66d671a0aec902c08e8fe2297c8edf6b823ef1010f7f71a44f2318612539b58ac033df658c0fc3b2747cac106a417305a37baff069cafe733c1a19067707713a6d543abadbed259b5f74247702e053801dca07add35e77ed4f4491c5624ad0abdc05c4d8641e84ef293327c875ab65653d8c81443a571f8e5f74e5a2f240996c441eb6567d64349392e7bfd5e513453d76eee12ea57dda92c2bb35c99f8f44a18ffe04e5aa8be4fa10d8558738bfb1ad28bc5c357cedb7e067861f186dbbb3a245960965927901f5c23f9004a2e27005ecb7c3b9352d4cb0c0b4d2d630d8e32371a64377dbd2af7900d45ecc30950e2643c76ccdb546daec8e6223e2bc9bf8b5425b0a2d24ad75e055472234cb101a81e7180dead1278b1e09abf3c7355aa4d5c0d16e97e81a711646c6975c6c3efbe6e8687a5a20304037f3e9cebda2d2978bd3028f7bcaa1d09e3889a49472e7655bd50428c67731fd43fc2443e0fe4063a48b880b9b75015dc58455fbeb2f81ba2923730cea811425dbd4dff6cb20e76c33e8e4f528506721fffde6ba9dad16a32d3949b4ef1930f8bedc94df49b7c002e4285cc5c8124656ef9021ebe6b9018aa1a7481daef874c19e7d710e52d1640a4809b3490562c75feba6ead42d17c6d2e1fef5aaff8b7d012ca1aa424838d4280e5052d2ff93cc1a20b2394cc889305e324ce2b5c643a06051cc679cbfd0811e503197350f38ded07eadd56cbcc0f9d222a21f14be5741b8ec479bd388ccc517c4d42908d3c398cf37b2ac243a6c78ade57ea7730c51b30273e2e5e637363ec74567635c6056609a3c6b59eecbede479deecd0b2a7a4655f73e3569f2ed324eba9e1ff1520a2b4905af6c0af514daab6ac69232e5637be5091385079cdc2248c063ca1b985149239f1433b06081381f11b81b3a968d90775d6f3e55442a4b8f3f3184fd181e4e6762f0afde111dd22080814703b1e8886fffda8de78dbd5eeba706bb1ed45803c233e05121f04a613dcac7ba7ee2b34ac59a2ca9f439ff06f7fd158f84f8d508a3d4aaca7505c7bd07b54ecaee5bc708619bfaa0ed09709df31c6c4f21310f11bdb3f2bb89df2ba91ee7f7d425116290b19ef5cc3cdf56404b46951c0c8874c678b38986c88b2fb6b2973c13a57269323f5ec79f876612d4b58fb91c44586ac06cedbf7ae14b67fb009cdb3c5318fb90adfbd6c6c48765b0b774cb05656b1ec65762fb6d728b2aad69ad00bc8a0f692348357eb87530467343bffeb1284262a3fb3dff9a8b075fada0b76e05065b0307f14a765f79af62ea7ddb916e23d76c7dee007dca04eb8d8187516c2ffe7f505d3f5abefb8b68c124288937dadb9930f77d395be797c2a4a7e60ab9aced9cc3d4976c77f1682e847b27571f284d8f3a514482b3f37b000b07950c45955f900f31d95c937b99bab8ca47d1e7c83b0bc459f11a19f74fe2c695e72bc8ea395cedac4b38abd2ff977eaf906c0c43eeae22a93032a7870d01e19bfafae85ffa9a0f3e069bc0374bbbe968176173b38e4c5383a35d80e4e863500e21905f53875dd4d78a0a5167e30fe1b87d34b058bcc55e4e22c83fe4f84cac685c81efa79ecae4a310b5946793fd85ad07c983daf78b0522b20105b88e251a85dc8a7348328f4ee44775e3e901eba5928c2e4a900c02be691f12fc17f014a3020f68370e63c242f120f822210281406693e1e897e47446785755bc4c3899b5f5220fb96a21742b45ff1c207c99369b21494b365a757307b070a11cbf3123ecb1bbb242996e907319e05e397b96caa6efbb7658ba41e4135c5f9962f7e0422be3ebe65e6d6cf69234bc15fa008f0780137fab22d3b01f08091f96e154e218c8c7c25fecf1851bcaa7a87a93572ee23fd5c07eb0bee3eb4243ec8d5d3fcfa0ac38931664682b7506be24d5f7927abb13d5220ada0198536889fa4369e97f1b60dea267dc127b17238b89b29de63cf74d19bdeab661fc9728796dd58b981f0f37a98124019be0afeea881ce2a58da5780f662531b30dd0e44035eff384e77c3c53d7204712b82224b5cd96cd69c6e05b61f8a8421f006741af436c36b573e0c32d62067db26a0edbd89616698bd4a2d7a8626f15dc670aaf110701e6f24d03d90aac01b7ee0ce42f957f7fc73b9c40d290d5dc885a1e1b911b9211398e8be81a3454f1994a26a89ea276f884bba7e8290b0bdf5ceff1eb39e70b749210340053aed762ececa2763938c8e3e1624aa79e9a388a5078631b4bf7b1d71b7ff492b03879d24f7d4efe48aced9423421656f270c5dc9b4587fce4a1197487ab5b92b7eb079cdbde043c6b60ce5c3480b4168ea0b335c2e32aebd5c4adfa95ccdb8796f854e097f0abeb4cd2a85d0be6ce5463bb14de77c2eb2d30cc17ea507d6a066e8727d2133c62a286376bbfeb5be8f6d4fe8adc44371685ebf9d843edde3cadb992ad9eae20272ec18fff90f44a602c13a64218756e0affc3ec8919d70f11b86eecadd3e481b5334de453a4ed9ba318a7df66a3366e18e16ffc6386452e0f1cfbe6f61e41b5b6423fb1cd40ae5a884dd68c2e396fc5041cc957f4827e8b796268b7c97c25f80ba7c6f8eb8906c240a52162402c6669a62f6953c77525d241e13a0cfc42e8e9107cddd492b08a452e9845a16eaaa942df3428150915e8e62a0dca2a6af6b7cb3cf2fee2a267cb831de31f1357f1ca9263a3cd0c05c87264e20f192dd59412abdff08bd5bfe8dad4ab0674a81cb631a1a202309ffcee12bd58ed3ab9c01585c3b20eb9aed7ebebae70c6326ed8eb19c1b05d48de221504784f30282bfb3a52e7d0c0ca25601abf79eabe090855f26880bc8b7f1d77c6514ac1f09ab2d29321de96c570d726f6467cde180f895ec3c2fbeae36680c66c08d053d7816d484578de03d64c22457b53b8cfbfa40fab9ad1cfd93a8343d7db99529b5cece2e0853bc7f0c20f348797e8f3bb208f2949e64bd788c9626880e8de2e21d092e906cf31e2bf756d33f27d8cbbf2a0a06916ccac5118b3cf9a15dc265f61f874637a17b3f026abb91651d02e2f74be731cc86d4d32e174bf2bbd84c31a6ae5d3f7e9a129d24422e2b61611f852a505706abe7f21893fd5bfb0c0f606260a06871796246bff54b9b1fb4bf57cfc8cd6d72ff3bf9b31471c84c1a51be4774e5c0a17911e8c35a3f4d281a061e94bb5a75df2b9e1f0f21b6bcb0b38a37a3ef32e549b74181e32230c950bb842061fcd8f6ece4b4178ff27b8b8c17da1eb987ac6c1ac84bb41afa445190652c6d8e21457b8677813399d59d40c9d5e4038edd0eb97992cfd3607ec75d1b5b2ff97ae76d93a041a598b9b42ae5e2a840a72058ab80e854af4e2ecdda6387520473db9c345ba22eaa93d33d6991ffbfc996ee939d17cde47d2d4b73b4d10ad6dc0762b0b626a8a411358f362e89a942c7a8b466cc21770b5061bcf26faa3811df30592b8194850377900d4da4dba5196c6eccab2cb091bf4551eca27df5afccb0a955b5f43ae71df731ec3b02c93ab27a000c7304cb3011bdf2db43bf375f1910d58b6c44e270423b5e480160b8301e05b28c0e2404d403636e0114aef7181ca5dbf17a0e274f34609e59fb6b023a50b969862209d4a0e0d1021305ecb60a13fbb58ce2f81306dd7ab2181409975458129d875694ae7a13c1a35495fc76647f80b310acbb78c4ede3c2812947472f011606919b6ba04dec376b3e734a07b506804377c7ea4f6120c7d851690fbd561c01ae76b8b79e1935c122910b263ec61be06c75bc2c7f611ec1508971615c22641ef0e0e3ae003ddd25a4ccfed87b82815fae19da3573c813479c6997212fe2b215be94be2921a73dec66bb97f25b92510bffa04c25a85bae883704c91cbc82ab3fccda12732d94a36b29823ca4746affa834bc7be26afc809abeb9269b5493fa9e9fd27794d1711a85adc3a93871591dac2ce4cc39a8332dab7290bd7423cbb63678dcf2dd2ecc72f243ec9489834080d2c2ee06f4ea5c20d69b9afee922fe2ef3e4c99e80fa54785d4d32990bee9051f460fe02dda20af7b70bfca7a1e3c1b5c42d2e509961a102745eacb08e8b3019e79dcc019444bd2042d4cef10f1bbc665ee2164051a4adf0d4a278b97dc50d69d387b4fe0a015a2d8d3b95492bbf54b10400af950c9cc5b7910ebaad51e09a0129f5183660db0f579242e6ab4d0e70e98d0590b427ba1969f05e949c2d28061351bf832e63c134bd2945dadf3e36823faa5f19bcce6b8ddb8af81b643b892594f0a4c35ed9b77383083ee8e06ad155ff61359a939f6dc39ad6af842b56b4304c562089a1e5f2b32d21a8a6cbe96cab661da67ce0baed4719fec895af4179814f0741b893bfdc21d275a4ed8a4d0af98d641ff746396e0d669c92fa6ec5094db8a3b10ac697fe3ab8aac1d4318cfa36a0f56e91f6de0579aee033f77e9a757d7284368ce5e8b374a08540c8bfa08d55ca6fa036d8c30ff3d6d8dda98c2b4e9742c68f1ef89c5935b0b930791aa39bc756cb2139b6114d856d9ac9cfa940abbd0abf6d959b56c169cd211c2b1cc72a89f43fb52b0e728ccb64d4b6b4f42e9d600dc0f8542ec300258f2275afd6c32860ea73f82f1d77504183906a9801372d70f56fc6700295b99a83e4cbfa524045a33896df7015237377d9748a0341e5a5faecbdd0d9f902f429913836eddcbeb276ebebbb1d2223beba63e69fe30298f387d87e1f04755200ac8cbc93529bef2bd80962a25ae865e4bafa033bf29b0924957812c228984c2738812d203f65af8ce20c281e940e9c9f0c6b99c4906ff397173ea1f815790e3a55088e78d3fd82f3f7638e30cde40384373c1e02477d9579bd6de1993560dae29e0b12e0624d3639217ed873c6926b3460688d428fad0aeb687db9fcc3b36af336f75806f920060b7c3c01ed9e76b43a67d31330f578187e684b9a7cb0773178070528f9e1be1f3c36a96f3812050cf491a1e414efda1f46dd1c4da13b7dc1614a627d27366d30dfc5e01a52f3212eb208398396a4818d774364bb814be91fd7e27f36f2ed61cbb6f81bae58dfe61a7b19a29978c79f9f1fa23c3da26a9124c81bd8a6e7ee09a5e1f4e6056c1ff6bb2a9131d0e2e5edf6034a59d4dc23beb14d673b55ce77618ad1e91b88a8ce0955291f773ee8be47fca68f44c64612a62db627296d50f74445b47222151142e0235701d166872d863298bad5d9a9bba068a030bedc470fb834cedff4dcca543f36e84515722dd1cdaec754a591e2b2ffe70c334d0c4e12e10f0fe9fbae674b9e743ed0f59d674a45b17c44de1149d4a0078062924580ef266394d70d4f5d436248bd5c5c9156342b9fdf0496988349aea451d356ecc639f8f2322aa0c354933e1aace38c4602b6419d424e27e873cd401f4d74bce890a33e6b831260c899a1be34f709f43f68d58796b80e3fc8d3970d8a29ea3d70353f550561faa2a76315adf09ee7f9414669e1ac9f87261dfdaa4b5ceaef76f9d34f9264711033aaec27ac1e5998e95ba38da9be1f83736f0b9057d0f6477ffff38ab0b9daee2b907688bf35681ab33372cd4431464f335ffd6039d1582957816b91348c0a66623b9422795d797eb7a087edce1b35e0debaa8ab2d53665c8e43880bf0fdeb1a0b38273e5bdfb6c16d52ebcf28db601d146b4bbee54857bec63d10fc2bcb486e7694eeacca8d91307cfbec3935d2d762316c5616d02c1f91553520266aa56949ce2487dd2617ac020d83e9b47f5d677cd0a455a24caaa1244126eee3d6c6ab6d94608dc5d0675658c3861348aac0f46deed4d0e19d1981ecea73f28e2854c62f5f7f5078869f3e18f7e77b2be0843935d50be495e9b5635978c77aade571ee4aac066895332300435e00e79418362cd2cb03f4164a8c1a348b80deec28c1553435e97aeea1a4cd3c0662108b32aeeec32ff109f58914e20c1b742c715e1b50b8b47aee944b64b11a691454887dd9a2316e7f7cdf38d195a2e91aaf97a46fbc29efb5dcbc63c89ffb5143ab8d4b243470a158b07850bf1084295148b422e024817830aa615c8874c208a8537a24385054725d462bfddedb83ccb227cf4b34287970257f545f3d34148e8e6c26fff538458b91ecbfd59229f178a2b395d68da5cf4a30ce4452698f0135306e7d7fcc0348ccaad10b25df686bdc8d131c46309012e115894744663756279538b17891640d460680f95cb89a5ad0434e13905bcf9da7a6fafe672301afef0c3b72d67aedb8ed8f147e68a164c60c4b65906765e564714f0b0d534ee1f1f91da6dfbe05f3109670b76be344f044cc2690898f25de1183e8340e5bd5c2a27a4b585e32b428d90a675a67cf610fe5761228b8e6c029961b36b64a840960ea1c3e9529cb1d6ade5cae23f6bbd671546d28304979c51f7aaac25528ddac359a11f8cd632758f401bfc44fcc19e76ba8832bb11ac80458cd8a6433b88821cbc80374b057dbcf4607d0072504c14434cf61de7feb2515dd597999f9270227dd9d7c9c242e9d5d8436a46d2195accd86d90c28ec236f44864c1363b734f6570ad865fd5edf34f4ffd3e6493b50b84509bff453382097ccf9ada958380befe2966463f86ce83dec5886e8fed484b62352fe2754bb457f411da78891766bcd7832f9eaeac14e4dd693b8c92b34ad0d821e81573b7bbff2205901092429cb9e2d8c841b730abe05b9d32a3f4081928fdab4395960d8a26e70b81d73030ef2a1399f708cc4663780716cc78ab8e56414b0f1139611735caaf157a9f7829f4595c4bcf35fcc61d67507d08f0aca0028e4f508b4b052737bdbf46a0f70a2d9e43d2b24b07dcc6f3052a2470da80d2c50d72204dca81f9246d4034838aeaa262608096de97dfdf00d491f0e8be274f02ca624a3fa3f5fb46af1ea3aa57e5f70ac1d478a4ab7e0f84460013ea1ba3d42517f185f1c7c854681c4218ca810ce011c30d5d205054c58812d1ac946d38671a00b3ff3ed8ad2be3f4f981f8c59712f14b8dcdef20d26d8082b7f139935e9cde131c350ef97b1f3c29f459ac456f6b543bb94b1407cb50d0ae19f0ee428f79935c73999730e15164627a23e8b7fbbc123ecc78bd505090e9a20c2f485f0cb8e074e16edebb753b9c41b74366539b9617f1a0753581eeb44402e93c5cb01ee8215da3f4eabcafc2c639ba18e55f192b29a24f8011a54716beb885ab10a79caa3bb75a690bedad7b9f832fdd5f112d579296fef347fb487e506d2d835fe05988130b3c7ab8058f735360287bee1775848e5400b473d8dee5e5e49e088065727d72673f788ad2d63905209c9c90d5d7970b96494a2733abe136454a48722ed19f392a6caefbe082c109a568ec110cf146020410e6ae3584444cb4d59754ae8b4d22d52c3bf7f2ec907dcda65e4ada081231df4562a7032f2c4d964d10b8a3287c615e89151649e08b97008e464a0867e15286277cb9492b71abf136ff0497ce8808a8c8cbf1e52f8a856dab61e56c1755937951ec7c70dea12eeb5ae848384457212c317d46c942f377f0463b30043b41f0a0f67bb12f4c0807f0c304ea2005dffad0057602fa7c633656d18bf681bda8ae2f7ae73b336c2d034719f0692398353aff7d16ca0671c61d7f5adbc448a1cca51f4de6d571c4751706094f1be1602be5664f6eaa6372071c8ccea8de6a2f06ab83c2273be27727082661878944d76228ea601c1531a01807d7c2f9298f0fa4eb8a4a2f0fa78b91ca7e0a9210dcce16249532a4630746383c072e303df59aa34a019e25af6f2dac4809a77d6f90a29ccfb9f94ca4e3d39473035e61594a49bc296d3ae5b1a804a7323a972a1552b56aa68f12684519f02be794d06c5e9849dd3f5150beac987d80d2572ba1103230c1030ce349618d8519ca772d9921d12a89f2c83103af0fc8b5d189dd90841df9c911ab72d28319cad9b544edabe35886309e107ccc09e96e3284e0c87948b598caa90b022fef9b03726c59b7f23e02bd34ebcc9a185d623f599527957a4846003dda1bbdaba360687323df9d5e9f0a10c911d45c4fb8bdf0e8557fdfb45323174f49bb33036a7046e8deb57e602cf8b890657da8ae5c1cf97c763bfcebb5e62307de5ec47f0a7c307c61702dff064907854ca69a55493da7273bb08222b17eaaee7fda7c0a18644d84505de606da2be649464765d77d111159e96a8c44d66b4d59bf162a1aaecaa8c464fea76cbb117b55a71c378cbdb38edd1e8ca58e00d3c8c97bdd8f12dbf147c13c01a4c9000e26788631d62d3b736036882f57a397a5ee2ebb0a9946b6aaaed0f56182d795941216a947afe632b3848765c00cb0cab8aa3f7797978d3bb54b088a4058bbfbb660377da40625952210c0e8083d1623402060ebdf8dc697ef93118f15190f36c911d9088a78ddb18ef7b6a353d16bfb28952f3df6a520abaf632a00a5115ac909586741495e172c1862cb9af65bd2472be1ad2c5a96093ad05be1d113c4ee6ab50e50d766d3a1021a790b9d20a1b40210d2c9875b8ba95b5b8e1ec3e2bc85d7c5e11ed456d4303b49408a6ed7d5844ddfc2185ed7bba8a265c63e47992ca6fb0e597721f44e1eecc1100b11e6f0b96ea0e4d7a8c35d79e865a32de001606555fe5c25aab513fe434779afb16190168038c20cc496e114c7987343d8adc9976bfb2e689e1e3da4af10f6b6c7f726a9b9abc9339e988169831dbdb1a52af73cf6cc7a83b2f18f6306bcafacb21fa1934c92eeb94f26e9b06b128ceee241f294056a7160f6273c071ad600cf1ad829f164590cd507011264bb0741676e4008d28fece5e0a8f59448e4b35a8b735c1ea2880333f07033d8815bf022e2285b0ca525ce3acac512b4dd1353e1cd97140886b1d48d03a6ca31c2d0b83bf98008c8ddbbd66a6bb192ec0689ed92c93b35f246f69e8e946e6af5e81ce52af6a9c2590a2790e46f6ccf38456a017aca453e93560f09b9981c2e422e2c834864f3545b026987fa5a01d729ba98fe84c0316946fcc4371653dd99f2e560ae0b4bc60162412b0bf3975987ba294b59e2877ece0b71b6c448dc2d99e1f856e1cb4b84699ec1311cea4d29a2e3824bb703480da5c08efee30408bfd6b9272481a39caed7c82402eb3988a6893a3f5f8576a84946a8e2f3600f31f7f2c9fc27aa4a70b6bba8f6609764bb2ae05e43411b34f4ae1e665084258e4c0904698c2d6b9da455f2b3a68c876c6ac722e7cfb22d658f26fe74a9b438d48f51f4529e02b8178f6457c832f4e8ecd3a7c762037552a5ee8b7fca1dee72be675431a99a289668201f6dcd4b37bbce033a3c59e5e115ca00f7702a86df9b5b27915122a7357b4a16bae0ccc855103271dc4dcce6112965d42de6ada72f51909a08351900146c317ee13b27d8bcadc42a860b1b0472ddb272afcdb71e89485044019a3ec47b3ca960463d651eac263959f01380f8f919e2437872c0759b8e5c09264e0dac8e027e662c2abf75c1b1940c21e84e87a754d703713872cf1699547109aec7dcfc3238ff05873f96c1554eaefd0bbe377a29e80de5b85d83700e540b3b9d3ce0b024e41104ba6537aa5820da19a703cdaa62056cecf1c67c309c701df078e6b31026ed56e5e75da84c77bcc89632450232d54fd155fb03b19508b05002a310906a7321517d409d21fef5df3695bbdf86bd0ea43c5562c30411d9ddb6dc52a694640a3f0a930a7a0a49baab77559830c7a7c6777777ff23dbc3af9478632d47f7ec6c867d0c2141fd7d521f305e89359e34a89f2251047586342258a1c41caa2e939821478d31ce58718253da345236ad60819af6464ec125205c6567da9a6823679ae60f3346ee1760de63188691e6d2442a1f46397f985e029991b46dc70b368d944dea038aa0a0f5b943c690109eb08365825dc7d102a232658b9cf1de8a5c2959ca28658c314a12c827121dc3c14475d62d7fb617836c624448d8633f4c4c462c462931a90452d65fdab4171489667452d77b3e856ac618e35c4f6e552aa191f387b9bdb0756d240ff5fbcee380f5e2a3e20ba5336872386b2576d1054432c618a39452f20aba075ac728a594524a19638c2d85849146d05926d823c5467bea07817888c5253e020285fd3c94f1100f4d3efab9d19e192c7105f6386b0510c208218430ce28230ce6466512ccd2a13a91214bb22c215a32549d159fb92f0956fd21843470f5603761a8773295793217c166009b4c5af4d87fb0496d9e73a7a8a87987818ea8e4ba39bc3337ea10c3a28c58ef6059e0cb5f722ea58cceeeebec316e841c9296d25f3e74a34590c51e93f882b9517e652a7882c5abbe22131cfabb7b978461779e654a39290a4b02859a1b151a827232544a29e5bb9498942e4991247f3d967a786c1913844390ec52c2b9514a29254c179bf5c984978c31c618a5941247062ed7faccd15bc818638c314a29a5143782a1b880a3ec22482388e2db8821cd1831677c4c76362f6463e3332c903354df81a33acee6f3bff9f25ff3d001eae8201e1c1d280cf62f5926dd3413a9bd1c1bd4cdac0659616b6bfa4b2468ed30b922b2ca8e48890414230a7a7102f44550955c34fc7e6805917b9c3366934d36516cdc666e34c610b988d18f986a8c928a18e3a909378521a5134fc5fffa6408598b17f8dc286b21e4594c76648c31c618a39452da3cf119a44c22e7d87d85aacb44af46e832665294bde8eeee32b6df444d34708da62db0eedb24accf199dd0969312ca871042093b1a21a53db06c73229b2fe3cbc766b7af611b0efed14b3db0c6a45319d316a94829638cac448c3e027667c87d53e3016a1c4069b7fdba1a3f2e25bfe66103d4d11f9da06c803ca00ed4d16f32c1bc984c5b47eae6954a7ac9f97af17968d55c9ad86f823a7352ba03777a073939f84a7ad13a6e6be277a4eebb40f587ebc507c2258645efe0cf0b9c4570f9a432533024647a073b14935366922435b94919a3141a236f949a4cff9e874205712224b4519b1d2fc28c9874f7f7624449ac0b82094921a1fe190fe551b0852b7f4eefedbf444a229f40a1a6a99238b842f59c2b01d86555ea0cb03451013568d30038f842264d28312c4a8ce314f772b06a7bf79f476c9acc49229988b4eccbcb71c4c663cf0676d99e4b3f622a94d6afb66e07a6e92b70bf34de90e9930336afc9d2073dd18b5adc622946295b40a564e7cd64faf73c14cac66688cfd090f7cc209baf7dc47ebd38434926ca038d5ee4a6324bffa2c52998905e5ed3344eaee2ca575a6f1ad72bcd378de39526378d83ab12b7c90702137fbec3ffe88e27d013101823f1e917bb13adf33f4a2af590118b353edd9afead293881788d2fe9de2ce504b411f85eb77e303e0ebb11f8f1bd3bfdf01adf6b746e7f7dcec738b6dca394524a19638ccd33371aa57494ff6cdfba787ea64419aa47f6cabc828357ef41e95af966d81dd5d97bd97254a7a4ffb68a55ffb83c8440df1bec4a75a70175f7652132a6fb4c4b4d2fa58deb53f6481829e388b0d715eb866c4d7f944d723dc0b9d12b252a425d5ca930702ab141d5dfcbf1cdb81f99a90c650fd8f57a977ac8ff7e6d548fc9b41923b2281bb03303180fadda3ac84af5286dc1da6ca4b4b1e12a090358e9c7d7ecb509975fb46eb78644ca7ac46e8b564bedef8c3126b8628c53ba122637794e789e6f3fa1ad9452c640e73b16b7927c79c1482e47e05b943039355226a794513a9531658c5101793029860e5ec293d2cedddd1fb58355a5f7df4e229fd88169fabf4d9decda1f720e2184117b77c5103b222cbab92f0ec9b51e3b4f2261ba74e9327d90b24a9cb3e3dc4a1fa594b2b4a132cc83d08a3d4a4391509913892e6397b14fe10546fb48caa67ccd378d944d140ff451933b0c7e8f1d9d7f2b976cc881b521e421a2d8cc629c9352938905514a8f95480aa29991668c2065267f9b1f9bf5e933444248299f638c12462965472b40992d605d8c31ff79f43f948cff6c62fcb7ae17d306a580ac173f3edc940ff67a8b2af693ba806e32b8189cc906c8a634b05e1361afb499b48e2483b4aa08114efda0814d01b15e0c5797263e0ce771585420fa8bb4cae6074eed7ad35597083930a8feb04a8e0e1a86e3686afc35000ed51f66dd733562a0fac327f273a35b946d8112030e688cfdc055a4ca773f62aaf29deb266c131554ca29698fd89d9c78ebd35d069a0d8aa46da5196440d9d94da67fcf43a16c6c823c212434434ccbca1333ec68d0abf092242d470fa594d216accf1c359e307a410e9fc2f424e39c93e161d773251e3960a2417c3860abfa0f3940395472a654ef207cc97d471cd6df1a7fe89877cba457c067009aeaa68f729bad1527439aa6df145fba52f7cd2d8618ea4765cdba1f4a23a0f0872cad7187dc7b805576356e7016e1ff91e3d7bec6183fcacb3c59857decbe24ae0435354dbf0c0c5ad008bd015dba74f1ea7567fa68638c1c638cec0426d9a3a0497fe8b0d46362f2bd63a23552168954f9f1715a8b5becbcd483df25d63986b1173b9451c739bfb93941e5c7ee9b1f8397eff0096d71288c8a1f464e760b7fc71328c40176499a9b35967c6c855d2c01d92e409274a90628857579e7d1dda33bc767c618638cf993891bb1ece1aaa8fb84a911a67e94865865e76d4d3f8ce7ad4f19042c71450a32ae1d48265a3254d9c71fa7997bae431f18507f9f506afc2fa6ca0e026d4d3ff30028723dc0fa41a0f5097da40ecf0ff461a21fccd803a13fbbbb7bc78fc31c343b0a9b7e26ff221d7c715075af82ba0fc117047a85754dca01dd57fd7888833a0542106272508fcf60ae63a5ffe8f69f09e6bf5fd5cb7fa41ae767a82428c744fb207860b158ac157d0d869bf1f2428d01a840898ba51a6718a9fe839638b934f1b7971a3fe37cc02a89c657fd7f60553ef683d6ecbd044456d921d92e95d4c5ad8932ebbe10d408975f66e75b13bf582310d57f13105d8947d4e48882d7dce28c524a29638c11670a97bbe646d751805109ab9450a894914b3da27b1258e543f9fcb2f301d6d83918fbc26646f2a098935293e91f6709972b4ae95e7d0521a270c8f88c1118b61ee61553e2476670007d0105e7c0cc10ca8b012966537a703e918f5ef56e08f67ceef28744312487d60acc103cd0c2d74a4f5d00e4386c22e4cffcfb1153f57fef09f5ee6f6f9aa691cf2528930aa69ff14c0330c2144698a65a8475cc3e3e6dd5f6f2f1513b30ac09c576ac176d24875a6f879217ee4b9ea3368e6a26129771cb039511930f8fd8d4f8b00424c6132c5430eb9622076cea129923d9a3f8c8aa7964734286bd76f7ef086f9539ce87a51f70044ba4f8630f5f3efcc861ddbe7663c713a8ffd6f8b3d423da90533d7ae7f3c86684298c30c556034e38c5ad1ddae75da2d8d08bbdf9e582cdcb00d42a197e6d3a195ec0829efa6d3e6775eaee44011e2fc30b51c0db744aa4f42be0bb13c2e36578193a253c3e679504b5f99bf72c45bdcf407b23f7a6eb3e5759157c35cdfec48212e1e324d4fdadb1053627a526d3bfe7a1b00d9680406c8bc79d84c8f0de7b9d12254bf68a26785652fe952ce11f7811b492c2bd005e86cf59cd1550f8de2f8edf6f56b73875fafdd661d5007ebf9b70eac6ef374fab08f0fbddc3291bbfdf4f5895e3f73b0aa74cbfdf3fadaaf9fd06e2548ddf6f2aac2ac0efb7154ed1f8fd0e6a958edf6f214ecdf8fdc6c22ad4afccaf017ebf8b3825e3f77b0bab0ef0fb6dd447ad42c0ef3bcb99b06ac7efbb4e02dc09ab52bfef4fdca755aadf6c67347d402406ea986e0600ddcc4c07b560b07f7a00852e48423dd0228469c70748e899010097030b88cb8145657b80edd4fde778e213f6f69fe366466362c8909941a386c9c60deebbefbaeff41cf75cf7e178fe9cbaa51edfc11e1edc76c3650ae06c38f8ea8fa1fb260cdd0bdd67dac7c191ae905ceced9f38d21047d2c2debe0d8ef4626fdfc491b8705a8bbd7d1a9cd684bdfd199cd623c36932380d88d3acb0b71fc36942eced534ecba215692a4e3b6a9afd14a76d619afd04701a51d3ecefe0342c4cb38f004e0b3a00a751619a7d03701a8ad39e30cdbe0e4ee3699afd02709a0ed3ecd7701aab69f673702423a6d92700472a6a9afd0170a42c4cb34fc391849a66dfe3485698663ff35998ee9b1fddbaefb5eef32aaaf29fb2f98c85531ff6535786bd53d6d1c035a3b2cf2e4edd1862222818d57d2ee22dac62b21169e9a98b62b1154e6d152864a9fb1cd4aa5eed6793b11f4e7d994fdddfcf7c3875823e300a36855318104685539c82ba8fb9302b9c6214d49db20f547f92a01f746547381d006e5718f7f1ab6eadba1f3920ae52f705c02951b2243be2b59272f25f82802a442b2927effc55dd88bde5a95f7624031700ee60506644bf7e99bfeac2eea34b85bdec0802b1b70fbdd89badfb31f0d00fbab69fba0058522327009ce3096d673e7ed57e1e9df992874b5402e52752e12f078027d49344f835c2a036bca5f6f3164ec9f77e6d967a402b4a38cdbac9200832cc1da5a139c51fa462a5967acc1fefce9c29d3027d1b7461a67bf6fa73b0e7ede09784c22a29f377df35274171dbbd79a1eeef600fc21d2c58425e0ef6a012edb727318944ca489dc7218128f6e092c642b4da5ee3966c53ecacb4b721087bf07db0870327f8c649e9d73829d873a9c7ecb6090a3f86236c0802b3391db0454ff5ca838f205bece860c362b9a1ab0366acf37bb6f468d85ee7b373fbb0a9a424519bdc5753e7673fb98fa6cecebe01d4993177c4a662d84f200da8185714a7b01d2cc51ffe7c2deab7afec6b08d1ec49af91b89f29ba52dbf38250448aa854f83bb08ab3879f638d2a3c41fd76d41802d51a0889c33ee3fa39853d01aad82a5330aa6c434424a808a7becdc203a7aa4c014b859f837dec00dbab70cb10e8967ef0e4fab774034fee6bc66d1529bc2a97cd39272966393e9b1a2712d8e5c70ac108203a706a76275a6588a644a938326e071e046da907a8cb8328b450616976a61a50d30ae8e755f8455ab52b081fe38a703bc0af82ae1076762842048876972e15b2480c5305160c62270a3b2b25374c3464b418982f75da155eaed546822e2082cf8af44b78044106aed5e97356383e6705c3e7acfe7356dde7ac6cd4982123062d2979f9527712927de94b9d92d2679fb37ae17356317cce8afb9c55ce6abfe376098e33695028fc18388ffb2f5ee07070a82ef4e3d7eb05d71084ad96d1d18b3d7eb1e746157b21817e04b437b0f2bb0df6463e7f16a2ca4fd8e3fe99e63ed4dc7a6ea6769f2938849c88b23daed791f6f34511f5eb27cd8a3db429ec71048a3fcf13a56391cb81e2eb753464145f928b5e6c0dbf47f7865cb61dac2b5c5b7e98f04e8b75459525ead74fbae30fa7bee8457dd5299c621d13d425aef038d9b6137792008e3f3d8e0e081c7ffa3867fc79acd4235e9103290e903838de86e823e827c6ae0738030714d61ebc7eb185838b91cbbc686f606cb57e34aefc71a855710a512ce510c491177bd35de3ab5571e85539c630047d810138e24fabbce8856e9b669be6f923117b1363b0354540559401a4e1ffbf71e3e78badeee2cfd630571b54e8e745ce434d4ae06abbcf5463cb8615f4e3d76b6f56d59449bffad5a4b2084e1d10a71702ae4ea7ee147f57a7e7f71e5a63c842e3891b628397ba5700fdd41d88e080dee06c70afa5062763050adff4847ef107a855fcc5d2f03387e1aa3c82ca1f9b88ca40ec12e257a603fa404c7810d47120f843839bc1411e2450f832fc32f8618802ece1600c0e965894870d0aabc2180eba60100f7de1e050d3f0938ce0a645e8064e7ca2f84cf9f9b9a1c42d6cd2a567e54da0f09d09744b3574750224799df0b2220bc756dc012ae271c25ed429a27eb149e579e23d3d0ed4aaf8b38329b6ecac3c0bede2a7f26b6fe4de7021d2c21e3fd1162f2aa2c21ebbab7320f6f86100837eb1058de20bbef6a62bbfd6d21b4211da424bebb057a942d4abf8d2db8be051855cd8732bb1ee1536d0c2a499e5452d9d56b39af0ce4ee52dd5f0428d3f4ba05ffca9b0f4a3eb27822abfc4ed4aeb0d08fc5ec8ced5bb6fc9ae366ea32085240cad346e57923302dfdf091d25a854e9c9520f50d7950517d47e6d0d7f3cc5893dbf38152b3f1b716a5d5c742a3f1f754f4761d5328188b9706aab58b1c3af2fbaa2d87eb814a17e3d31e9409cfa62cbc5a9af5f419cfa9c4788535ffca95438c52d22eae7565af5f32b7588fae1a89951fca92cb457e800063552910cd4048d2d4e9dd8c55666165cb17b5d81414cd08f836ef07eed4dec4e34c81a3f762cb435fc469c622c5916faf5e3d756f78a185851bf6671166e827e3cc429ef4e4060779b0d481c13715116e8a6020ae58d1c8c5346da6e24712721a49c95c69d84684a66d3f86b9fb3da2d66d98bdd89867571a1739240af4e12e0df7eeb44407afe5dc1f7d7be243c597e7c589add0f9b1a5535beaac6c7691cc66123d9c7245cb3eef4237ee7035723f2d7c5854e95aa2ab97515fd548ddb1589db55e4785055f83be39299075a16148abf8683e3005665f2d7abf3f73f9b39290d92714998a6794801dd69c2284545285e90b781df6462ef701887530b21dc66d80961af83b0d75c15d42bbf0338f590fd0b66be2144bd3237f110324326eaee76ef6e6feff676ffa1113a8311c3d6ece7d4ad5b82e1051ca71b364c3568cc9091112386c2bc94368d944d4c466f2ef5e330dd6e7709cc61662d1af42c28bfc6dceefe12bb6ef729e95e62a0eda6f87d57d5fcb0dbdd87bb8421057cd7fbb77b994de0b367edc7aa91e6947feeee1b77abdd95800855a0dfd736cd78393835e4dffe93bdc781df886fecf57774c83db3ee7cf8717a924ed215be0b216ef799e0cf55650f29cc370db71d5f76303eec9c3d538c5d0f5e8f982a7c29c828a57c9798c4a4d7d825e10adfa9e0eef0c6468feefe53da9003ab57ffe07fcc70c297330ba1186394d284ea41a1e6464d419a97c327cfdea29412c3b028636904d24b3df8796e14a3a2273e0c2207b1d6374a29a59432c618db05ebf38aefdec88f9a8a42a171dc7a4bda6c6757d9fdd6c4e84fe4dd87d8b418639c73d2dea22d6fee5bd45bd1dca84de5b701428c5146982e3c89b076be3531e70a4e93f4113e3d57e201f17be80453ba54434ef59fd8b70f5cb1d7e6d6a51fde0cfb65ce0e4957ac93bda51b62e745c02eda421e0da1e47c602863e46f1fb8eb41c687ab23fe46eeea48baca6e3958614bc84c76aa9c1897b1883c077bf23df6e4a3d893b5853a28e3fa0af659d7575a8853d8cbff30ef6d4e5658eaf14215146ba12afda769a4730b63b0873fadea16c6e5c022b928afe47bd1ded474517d8b2a3f3641950febe90822dfb4e662d5b00de36690251ab0da8f7158d5b00dfbaef2fb8a8c51e5f79133d991df58a4785265073db3a4b0523fcf1b6b71ea93d9e1d487c3d4c33a9ce256932ad949953cf5c381956ee00f6c6a7bf91ed814cccb1712c406f940ac0afe348d7cf9436a7c3c173c13a623a809aafc60104172bda85236e99d22ec658dfa75508d26823c7a0ad4217f4aee2754f9f0a755dc6a9ad27f35de53f9301bc72d2c3d05f2682c56877ce923a8e93ecfa8fe162d1f05c2d6c82aaaecda4efab1871c0631d8b0bbe6614f76cb3aecc91df65ea874d0d6cc981c82f069177bf25fba06624f9686a0f2fb49fbc497dfadeca589ca2b4c2325ed1a4ba95bf6b6eeeb2c59117bab7133b0275fcb36c8e1d0c05867f30215f49ba9f2bf47710a56f95e0e4ec927717d853d99752dc49efcd975107bf284f51556f50f8bc5626225bf8338b5a9ead3c57a5bbf1a5a6896a5d95a7db02ccdf6c04ed54bd9631c576d7138e36417f49bdf030a7d28ad5fd1ee84fdae5887694ed8c38a75dc624f7e2605fd2ab520bf0eaaf26515f49b55be7c29492cc384b633d88a9df268ad2eedbaf3273d73c23d8a5b76ca9a7f383585819808bef0c354b054c873a542d65261f6ed9287531fb37a38f5b98ff4e1d4d747d2c9d17ef2898c52e1cf1406ba822ea74eeb59b765ddc47100a74a0fd9461e65599665fd5fd72c6866d9c3ecb3eca83a15fea1428ae591b1a00e9f2fc78c8f8d3ce29e8c057970142d9bd977f771fdf88759d079380ae4e14fa08eae87ab951fcc873d1e7e88e91cc9a3c95d0f70739e5651da499ea6c93a2ddb6612f4c37c6a14f6a0ff34cd13c8c3a5581df0a14f2ab606fec7f5f327153e73e73eb16e95574ffde4d12ce2d409e661253dfc8cfbdc0763b52a16613e58cf9be6cb2dc097612c0fd904eae0c2a923188eca14b54af2b46c0279482b5007fc37519e58d4a4d2d9c9a31eb3339966117b5b785a25839a069aa8d4acfbb028f06510d67d33ebac3319f452e567cfcccc2c5bf667533b6bc9035f5a813ca411d4c163a5c2ee301ff68eb6868b34823c6418ab630b5b035f4aa30a7f4615d4ffcb58af0a3356c6246bcd17a78c38d5c3fc24b36a0f7f1e712afb197984b57290fe93473d24a195df3bcf9342f2cad6609143328b0cc2ea80cf9c1cc2d640199471415f062d2adb81611b58689a0679eb66e6c85c12f443d5c9d0e173fd6085023b254b564b20f30d7c23d710429844728c2ee690c400a94020f67aa83affb7aa16ba8999b3ebc8f5bc5a2d14b95b684b0f35d1164e9dd61b4b6751a27ead056ed0d52ad872d5102bb4b235fe730594e10b06cd49a9c9e4cd23e88732d5ee866c8d7f0bb52a87a5f1f77642757f8d3179c56f5467c2aa77412c9cda2a5e04d50f6af988a840e425561550503fc8059311eef070cabf5d9c3aed7812f5834eaa0f55c7e16f62820e6995d734fede3494aae7a2f07fa65f9b09b49dd1b64077c3381a8333f22396ce561172e2a8a8bd198891a8f061aaf93b46977ac4d0b46d7ef940302b2c6931629adbd8830e85edb319323eb26464c9c822bda67dd6efdda576271f5bfd6bd8eadd8e2ffce7e7541c7e79e75e301b0f6774321d5c1a9c263dd6652f349094d841939d1da8e0ca125cb0cdd9bd5b317607444f44396a96cb0a52b297eb78f38f886d1a473f868342e349dd897f57349e76277e58e56fede7a0a02f5d13753dd459d8831f040dae7598a69535a15b321b77f2df1a3f5691385ec8c274c594202afbe7f0bc2a8a2a77a82aa8869580f0b0002654bad30f9727e8a9fe393db43139b05eec6dd53458f267ce077892c00b2780a2490f6b45e3a1d4f8053071558e46b784c6d378cd937005b20026aedabf0026aeda1d9425343a29fd52fc736870529a8b559bdb0cecd9b007677085aaf5e00ea70afd96b469dc565802224fd082dacf251c505cb06a7748d0fdaf5b9bc5e4c072c11765cfa120027af9b0a1499090201042f86a5513f58b6a41e1179b65b0772835a1f8053db65a2d085403048240104b8b080241a01a5d340d7914424643746832b443dfd0465be58ba37ac4a953bf026a8cc161f8f810b9b6e8d76b6f4e2ff4809a2a4c85df437bc3117161556fb12a08e44d2a7426b5bfa85f85232a08b151e6ddea8ceec0f8f30e4c0627c43a974fec7cfae19bbe7e5261d7722d68276169e067f5eb2157510f6d0d7c1c9e4103fa75ab5bada2f1f0db8855d5781853bf6ef5f7cede34511b310d7c58a36b2d760c7ddd1afaba15d3aeee83810f879e40bf6e56d011a8c0840aeb0c20aac1284ee2c62eb81971a9d1680b976ef08d4b409c61bf7c4aaad635769f076af3cbd51f0cfc276cc43615a029157e4701721e226a17bfac20d42e3ea27edde48b55f1503fec9d21232afc9e25885c0bfaf5d0107c085953a0c154bbe3d7d6c077223aeb56b9024f6d22f6e07f5ce3b724015fd590a93dd4aa1a73526a32fd7b5eb76874ddea1935a05a7f01f4858f0637025441ab58a155bd76516bab8071d45b6a0c81c2d20ddc8d6d5d02d23380e82cf558538cbf476e87726009a5f6b3528fd6e1428d5c8c0a4b3ff6bfb81bf483a31ab95861e986fdd8ed7a5e7b873dd82df6206b68ab7c81a5c25ac261bf3b243570edffe1b597d4f68d39fa16fd50d1e18fde2ff8e2d409b6a08e0a9af00e4c41d8f3b335f0fbd43dc4a958e1779626f2963761157ce26a2d9cda2a5db02afc36fa9ce53a15cae8dddae1d4077f2a7c58e448ebc06e52e1cf2c40e8f0676fbabfbb1fb6063e57f8700aa79430810f59ec4116e4610ffe0b3ef48bac0a3fb25a059df4ace0c756dc8952a114ab2f36893d3398013f803e82ec8dac39a0cd5718c0a0ce0c83f6861f3ebcc2a97df804d81af87c621f9cea0adf06f8413875a3c2ff01326115f41112c2a9adc245940ab554b85c2ae48fde28f8397038f511000671ea94e2d60c15ae950ab9637803e7e0d4c9042b8ebd81b50a196d3f75dfb4022a43ab0200b323e8fcd951c685c422f990a6b0caa687c464a82ea949dd8fd4438a5217be738a531ff422b238f57193d3dcdcc888fa3997ba91c984dd476ad5a5375841492d4ef1d4ec8853cc5c482c66c9bc8cd88347ecedcbb05d3c3172ad92a0ff302441bdb731711fac375ef317cddffcab5537bf34de0de7b9ab69b8de781cb6e118688f6cd8f8ccc6bb8d8fcf47a7c7f1f088536e63834279debfc9c4dd112cd530bfbbcf6117b926f4c3a2d47dd3e9e38fbfbef9d1cff4fde7d9645bd85ba34affc37e6a76d4d5a031a3fb4c2fd37defc9e83e0f15a3cb7c62bacf86494033a0de65af0c003a14fe9715d57d2c0aa7e00d6e2b89fb3ca8eed313f7ad95e73e3efad68a0d1a6607b940f11e87e1ab55cc3c5e0c4ad02f3b621ee8a2d014bbece8e326fbabf116006e573e30c110786ab4a005364db30f03125ef72686ffe6c2f01fdd176c1efbf5d77a93813b09f1f6a80a32385a799fb3dad21d11b023051d1e2c75ffe38fb7442f728483ea26e9ee7878310fc31d51b8c2cc5354c4a9d3101d38d126caf8691f3633146193cdc6c0c23b2f226e93a90f6fcae8db05fd3628898fe5d2926a320618b36930193d749bbbbb79316e3eca6b150f41a8cfce07c6f14a060a283f377bd9cb975363f8e285080aff232a0ac2362818803ad355e66e69fc913932fb47766f006b414a2e5b08b9bb7f6fe1eededdc61d68ee1ee72faf296851281b5e158a72499886872a502f6d51108c319cc561140ac53242deeef80298232d998f6188a828089c1886cd396d5c41a8aeeca93999c79cdd3d7fd99bf3677f4fd39c1deca67ceadd67a23d9f605be4a62ab05ed32c033090753f96a6bf3faebe593706d45ffeb7434578f801b2b6ca16a6d4fe21adca59f5ac3a4ca8d72fc9f3421e2fac4a92ac853c26abee7329763fe277334da8425b06d21a5fcec7e128a1b47e356798a6df25778a0feb16e1d82113185a0f4966c57ee1ea805ca3f7472cc6f81873d862bb3bb1b918ff7cf66214babfdf8500eababa7083ba6dc951d7d545a7d22c51c618e30fa2b020fe0c630140a2928ac05cdc0750d7d58527d497baae30ac34c32e30c182164840794161042618c8034b851e72aad0b245123b34d882cb166ae081ed2183c15a931ee7cb462aedd30d81173e3a7861d1d30323aaf0000d586083214461052bf0a4000c29fead28d2c41456149e8085a585a7987eae94d27fd0050c301da7262a432915b02c91456271052be850da052ba84c951c0c5552dd2a2e29ea47a1cc00084940c2105d24618515fcacf81f85c222830758698214a0d0a0084f5c8941fd4c0c797a6044142bb4c0e4f50fc42a28383822092944a1042ef8c7f46f031858e0678b1457086309415491c50b725084235eb005125842f8008b140844c10509b478a9c0083ac8224a9421a8c064052c7801152014094e4c38a009275842093818421255a860c21646208494524a29603efe1447909ad0993e9b18429e40081a26a8e28a294498011458780a200d8b2634a1e352d4efb5d0821cb55d5a5842d69a257091832368e1043d2862d5388c9deabac2e84295755d611ccd1bf8a854b0042030907022075380d2802d88a2f841124f68190285ca228a1ca86c3982082bb610644416cf62b148f099989ffedb000a24559ad0320250115c6042164f88f84901128ae0420411522c9607fc60092ac842062e2eac7041e5a75f8427b60a472062a2488a249a5471e2e708294d3401b40510b0f4e4e04089297494782541c78a19c4ced4b680051e37f104284d749c3cf1411195d5ee20082c28a83882111257acf8b7c4a88ae5ab2b8c292ada335b80bb40a89f8c8e23258e6a503d0c1254f8cd50fd7795850549e86942ca162656fe9453eca4faa338e5bf83532fd5dfc60141f6065688048450b52be99cca51631735da38827ef4a12b0b46a834aa3f34716ab759c56f9dad12418c1bc4bf83b14e8a11f8fdb25392b392bfa520b23bed6a36cd0ef933d511e4c386203f4026426c56cb16ed6bb978a71835838d0e14ff0eeeee6462e61d6c89ddc19c3333c78da61a5136ecb54692dc45d86bced1348d0477b0581a89599cfab6cb163169e7540ff293cc9ab5e64ac6afb79261b392f15f8d19646c1a89967e3f07ccc7bc36a4fecec29d1dffbc36fd98d2cb520fda49622d7d978080a04b972e433576473ccac1ca9da53217a4f4d2750f51c372f6c6bd1669950d4cd3df3ed8b381038fc4b3714170d89afe1b56c79459263bc8ca02876a7f7f6bdf0f593e3f7b8d29cbc77ce85a9adfac5a0972562188f19a73d833a77d89db3824b08b977a68a46f9246fa56890008192f045cc950c9e84e41627c8c4e095c8940c6c7f89c553faa39c80daba37f72386c8db63725ac8b9c0d5bd36d037b1d3b0f870e6850ef7c49b8fa3369776ee0514046272546b7a52031bad3aefabbd44352c8da9ae6536cd2ae2bfdd0497774f611c48686acbdd9da5880426d1c4c38d8eb2cec7cb0c7ff896098860b34fa3bb393a47d64f833c31e435485306633750c8704da4882d6a8ebc2821335d62d4152851c3fbc02856010e5e01574296dda7b85091a407168b66da651ce14d331313486b6c9b4850d7605dcc10a0ae2d407afa87c8581f415f0676e948353ba586db8a810540254c9ec4d12f686fefef73764fc500c380489d81a7e22b008085ba43eaaddb75da01c0cda1a6ef8a7de2c5b8b534df8a196161f5566ee85bc44508761e987d7207ecac54a847f074e1580e115508769b8053b4839ae366e403f1311e80787b4186159960cfbd47cc6985583f636ad8af1a55f2bf205e6b71352408506a87088a6428f63e8da80705543fbfcdbb4fba829497ce1bef764fc6743e6bf18d58cffb25a7ab82a1a5f2a3d8d199c0c27835b4e3ee44affc221698097b8e592b07fc376137bd0bd189d088088f142c0558c183f572d444a975363e4ac62fc6c1ab601fdca8d031aa3c7c6178ed5102b7bf7ecb9e7413813c01ac3e210167b081288e8e0f13b76dddd9d65bf599665998c09676bfcb353961539e2cf03a7369e04fc246152dd1d8baec7c14cd46fdb1b2ed62bdca0faebc0a902547fcd27b0375185f21d5be35e6de480fa0f69d59c1b58ff22fb45f50dc3d4aa97edfd5d1301102faf9562d7dc02125053240075863f1b185c5591a629e2382de793beaf3375b351b798ba65757bb8aa18bf6d1f83dba5217d0c4782e14893f4cd6d5fe2e6f7c675fc2dcde79ecf73766d92b942bfc8114fd235fea08453f3b90577f885dba669f662077f484c89b4dfd83372423a65339048ef836866a872a551f9718208e941e5d78155db05178bc51ac1ba8c822a3f2acb814525f56d91f30a2a2f1121b74d235292341287636b60eb57da2fabb49fbf714a3edc39c334d98e2f28c923751e7b9c7133f3833a7eb9124e4132d2d3b9fbd8cc3aec5b7345923135daccd5fc96cd2afba1f6cb55863d4e3787c4541b07ac7a00a63a56bb33e2b4e58300f34e02dda50bf74bec1b5bb9ecdc5aa0824c38bc1c54a0eb7a15d5cff41aaadf34e1f0729c82ccdf2a84592bed69abb2e79f1a6ccdd57c12c744089bd5fcd65c69118ad691709a94713cd4f8b9bbbb8c08a85b02b253a8db4139f92b59d70a04f34190a5dc9bfffdbb20d97b17815d651d4b8e34d0b65535bad082b5da1b1ac4a11f6a6dd29a33e2b4d4cfdce9477c7eee3ed819e13f75e7fd3935a7f6e9c7e7d4e6706023fdd388bf372cf1b78c43ee02ef6abbcb3c789779975b08389f5f6bcd5586ed66dd94dcf743ed561a49c2d565d4947b330fde8575ee4299b3dba6e95d02ed82aecb8ba2fa4d2f788884306b158d78d1f28275f28f8fbde44eded1b08a5dcb8651edf9afe263bf2dd32a621f39b92dba8a0f4b3460753b1ffacbea72adb98abf252002a8db4101417c1cf6eed285b74b975594400356b1dba659f6b6b9abdc605b9bbc49595e02b72ea6c60ed4fe41a31663cf6de376353921ae7570131081f0ea2708947efb21a56efb21fb3bb650247b94fd16d59c55ce8a3d761fd43826da538ec9f6dc0e3028923daa497ad70092869cdabb8ace958020a062afc94deb6f58fda7c64969d9dddd5e7ac93a1fb8627362327af747d78eb6ad9282fd6e15e209705f2190c562b1e0d27856fd03952727c5dddd7d484b0a129b6a2449d7f95ecd59fde84702bb544e7ec631c95e0829486c6a9236407ce64a35e464dcaebc6309888c2a716858fbb18c93e20363dd3de3cbec7c607f8c1d092bda72ca35081debe07a1108efef770e562d629c0f2cb1f7d681d6bdb1c7ee8ddda8f2b1caed33f6e9c7c23af906d8a57a27a10efeb81a81ff4988c9ae86af2cf706f26824904beddaa51fdeddd6f0c76f23b1ab61ab07b1da7a80eed009ac5446d25db854f88ca4bb7479e903c3ae078c75c0eef3973fbccf5f7e977050e2f18708620948a56fa8442c98ca9a5432442410000000026315000020140a068482f1804cd223dd0714000c7eac486a4a170985610e04318a216388210400001000011019a26d003f377ab5bb613e6773c7b7ad172515035068d34b4714ff6b36f4da4ef25b18a866ebec8c5ed5ae3710351334a1fa1a35d8d8b174c1cb07a3cddcf370caa0a4f18ca71e5e99be454e27a5bbd3b4d9de8b10fe01d9231f0e709c8260969bde5826edd42652b55b6554c5c67c4d7150b093502931c43656081818b8e4e561203835855b6ba3580ab49429c045171e75af299afe39e2b17855625631fe2efcfd492ec320efbd472ac454ac0d48a413ca6d17ac683863bc003292ece4136a8965134b23c12d9811a31c2595432145f489df68ed5a99f95d0190fd1c40642dfdc45792c4d0df4a89242691056950718080448f40d6cd63c0ea76833a10ac5466b185d102a1a4e7355839cb5ebea1d23bd392a94185e4cefe1e6720f9f29400cd831ec228dea517aaa5eaa7fd2751af49dde8252993126f0f9581b70a8d136fe121d0b971d95314e17ec59010fac9bb7099e2554d4da0ea396844a78753a088b156a13c35b0eccd07f5e52c5748f32479dc65943ed57b9e024b7540fa8ab3b360f07ad38f0b4be0d40889f2839aa56db96b347e05a1a45117722763bb0b7ee74d12c4ae40f590b045b8f6bde26caaf3b7f07379cd3891ed63cd382985e53184e3302c1af07ae6302ccb3d0162060a79104d50032e374709d3b2352aa940126a124d79d880190b85fad77cbe4de686e74b00e1da5deb53274074d1fa9f4eff58fe56dfe05ed1b5a4a9dc50998fa3b8bc46dca3da9ac6d4d5e4878a5ce0b424aedccf5ed6175071495bab00615c6cdcc45b2bc936a77e46aec17f6a6741608de59c18565aaddf8f9a98592c3e6b9420226b4510ed8b4a4a44a2c55822d87c10f7293f21a2a941620984b42b51d2a423d1325f18d98a3fb7ecfd3cf49b48e4b259d678e7efbc6f2b21d87ba3151f0b7b8d3b16a8fb5bd8a3de6f575b6f462d367ddb2d0d6d04dfa37731b791b020fce10a45e8bb872140ff05f1fe61eda5fdf7a7cab18fe24cfcadb5fd4971c8d79274cd9c019e3c3c79af8af682a2ea5bc6855f9267ffff6699908005ebd5250ce40f72aa81d73cf979c417a32fa676b7e582309174706aa7ba44be174219de7c7521a5fa8e07609ddd62350b69e245fcb8f7506f9c9f803b330f2be207b12576284b970715b935c7925b216a1fc0e73f6124472a400b158805e52178a5c404a1d65c916f563415684f90bf0fa7309fe49d7c9eba8e64cb5b9784778059d16543dd218e5fd94730d675b81bfe103fef107f1bf9ae58375e39248ecf4625eca9d31ecbc31dff20b894cbdf73e49911aebcb04e34fa05dd270cf385476397d9e7c91acb81c6fc04bfac104d93f05f0f053c667b47348c0523852215fd47c6913073ddc5efb8378a65e143b861c687e438d9cccb30a89f7072af4b2aa5199301ff23dba48c45f6ba662b9a912fbd49533e14de2da404e36389f052a431bf84983ee5c586e2c73345554642e1ca39a4d0220162bd7e23a0b0e6cf0b1f051b8b9c8c9c11da9a91742d3b660994fc5a78fc09fdf2354dc9570ca1f3a798d40b861bc03d4916845d32063d460b76ec4e5674535bb53b1631522eb46873e13419d20412c24cd02ea3b0be9780bb0dd7ad4a4146a9cf9bea45012b4c3d643de2613dab88ed250903698938a8acc6c28cd685da380aef9d36c0f5a0c1815936a268d3e41957e15804be307f9ab066f5d8ef7701c57a22b946c337bfc63cabd55d7e2f1fab31951d9d8aefaa2cc918f74e3519dfba80947184987f5f22e05321df6a8ba96ba6edbaed4521888cb65a410f893c97482b2ed783d89a103583856d1e6108849072e3036ef39f6e76fe4d3a4b6111fa7badec21f45caf9efc9fb8331219df48783a862be17c2466eba2d3679f8e1fa728e84812dcdeb1c4e0d023e7f32e1f0768fbabe1fc896184363d9f314006a945ff67042a23813cc6b53ffaaafeb0f26480e5458c774b0a493fc8f8ead0774708975ca0d9a4069fb21354fc8037cb3c8849c2fa42c7157b89286b2da1f412556e66475199af4e450d6169a8cd68e07a65ffdd4c2857be10f02df592be35e5275857609e02980a7cf32b77ef9dfee5e6ebc6e5c675d3edc675d3f5e6f5e675c3fdc6cd6eb8ff19b99fbff927c4c5f109072ff7473bdd16df1df5eb8de6a5ac0df4edb08ca5579d79dda5ffe12a1d1018cf8bbe172168e0a7bbed5e2abc6d54fe26a8529266ba3c2477e67a6045d4e2ab5ef98173209562a4e71023df1a619548448218499e589ed90975f1c6d5aa394337c2e32f214e547d71aeeef764a028aae6798cce850b3f839ccee4ec37a4be16eb11e22033e67587b863675e130318f1d1602a414f824075f8357b151b85f110723038cb02bd8b462c65d0621e7993f4635267c8ebc5068d3df1cbb41e9b848967f232ed17db6dec092ff3151bc2658e3dfad7841f8a1e56c5e60c4d19dc88b4054a00ece8b87ac0793ebc1000eec281cf8b27615aa01f25e3afd0b8f7ce03c7ef8dd00898ad28e62dcdb11b408e27de71f3321341d9a8deb9f2f2db0471ca006148ec19054ee8302e35d9378e072dfcfd44e840dc61fa2550b52af66a96937c8a8cc5fe737f43c1a2f6591404c2729e645b9487e70efa7ebd05be6287de044badf7666c4ed4feb51193f42bb9613f79e293a96b204aa383eb9f941bed3347eef13eb25af4434358111b3096092ed31eeb06334504a4edf4dbe4ba59e782fc56495355beb7c5d6d9440b7a6e9489855ecce444c882fbbde221ce00c275921c6f93d8ef43ae1d47815c49201edf2aa880b29edd166c1748b11354ac7b365c6a14749454893af162fa8b78e3ab25bbca0ad69dcf3c3ab34d3a48ae6b4bf76e97a6a982c4b8449ac10c405c6cf077dd54940365253560b7ee4c4b4475403c65d28c2c759c53d7097235521fe5f5a8e9429965a43a6f548f83ca70427f05c3a35bed4bf1b4a95da7265b2513beee10942f2ca95c8daa5c073e6030fcbb60f5cff4cb003d2df06405e2d2655def0b0a1a7243423c409eeeb5d22a0f4cd2714d87459b6095b510db21feb7b7b4715c9b615d43bfa65f89bf941b27c80b1f41b48611daa2b11bda36c5bf3224ed2a4ceb1a377d3129b3af4a492815c298e734fd96cd5c056a1ccdb93527c65e4d47f11ac058d550140ca90eb39517638fddaace56822f30768faae5237e1f55c3d08f3a6321bcb90f8a599caf72c97404484e985f8f28e3c813507c10d42ba427ab83cdb76e86856260ed86b23e5a13cfe74041450f6013d516cb0aea6afa82aae6d1ecd1cfaad36d8a85acf24419c50e63da3ec8ee934cc4dd000e177a4df31d369901ab7670dfbd494b27a16dc6c8e8d77f585cfbf0c45bc9c8dc86a4584bbc24c1385289310d0e0cad3efd8a1a862d8b06074838b6a9b52dab0827a2cb60646f16cb4323da13615342c9cbfc866646e513f53a5b4101d92eb63cc811e198a2b76b99d21454e32f02d8a06c56446e4f90783f0d72ad3ca1f7eeb8e6ccfc8361495f79a53e1077d316e7dd8758c5d582199002e666a8a5e5c64aec2e37384615abe9c52a8eb4e915455144c7949fa9b7a7e69d81b275aef28d32a69e4cd4bc11e196cbeec649eb0838cad87536708627419d5799538c0924276af4e10eb867dd6448fcece16ec464d78856b2b40a8b2cb5745685d2544bad13666b4230d19cb5ab9ce9bfabd2a3e7f6df82b02e744bd312434e1c26c68a79f5a8d9c56eeac28360985291f9b020d4a4f30fe1c1da0668eee333f91d4208996271b57e39e7ac239b24d92f61561ee335007e08b3ffb5be396983ea0ed3dfc4f24cf8d3cf8a8f4a662870e057ce0924d031c1ba98bdbbca5dbdb0478352e6478089d96adfb243cd5adb2af412ffa8e85a7cc60d3bf0ed0fed6ebb638efa405bb183551b35f27da1abf6d5864845270eb8c284e1510f8cd8a8212aa13780eca6db6a02a406ccb9c8b7322c2779828efa72238792930b88594e3f7b14bde0bb007708869dc115327065423b7671e35380a8476a70b0c4ac28dc9ae62469a98a29aa88658c1f1fb472ea88de83eee85c72b295165d8922a560e249541274f441cea02cb6b885664052e1022fe209759114609260e06bbe326c2e73e725dc281136b5cf0417abfb3451ae9d83dd52657041ad6e7f70efc4b97ca602623581181f991d06e3e3fa25803a78d12acef6caaf1607127900b7225dc81e81cbf566ab1d005735278e026e041f3d10613981aef008fc75bc277bf243cb94f7af030530431d817a0bf7132e252fb3b6c64c6b5ad53b29290a38096823f22a23961fa0289add9851277f335edb08e90ce950575c2178dff053d927456ddb8c2ef58e68148685b7c4a07a1e429f28a71df96ab8b68d294411dd33ff1137600ab2399b1a2b9a9901fbccaa97fe886263dd8b4ddc7115220416d52dae0c3c04f9388ecca5e76ad5c84d09f60cade4ef45443733f0bcc55e1cf9609b4ac71636e7afcd59e03c36a9e2fe72e2de3108d2f1b75e8556ccf2218a9739721968add49eade57e3ebc15328cd1332c0f0c0e3de997b853c3a6b134da6865fdc8867a7186017dd812a1cb9026f321e49c27f409b26906afb980c5d95ad2042394bb1db3a7a094b4ff2eab417998f6eb7ebbe7bae9369b7521b6c87cd9a666c302ba0e4deea8a6904a0fb8a9b8f920420871230a3a4eb5e4a9282855b3b15f7543117832439fc1e7aaa3166c2bc45db3877a3b80569c606268bf6327093146a0e035134298f03c8edd736412c2ddfea52cb484618163e0b47848662586d1f4e19a6d17da0a561a68af1cf04c62c8760cce06f41f09ea0496fc186c4512cb54d265344864f81c47d58c043438485835d31b1526da80b46a3bda075df8616580db1c5eb11d701de4f37e86a8f11eb472ce4ccedb8884f038e617ccc486b6b4b34d7f39670a0ec2a013ec0b99aee1c2d473e2b1922d5b8deeb2cb9b359ab4ffd1293e64702c53a927288d6ccf579387a48622df94ad0e4540b3c0a4b5007de1ddb3d64caa4bc2bd52c75c9f901a973a0a41850961e52616f6aa27e4cf08c205b20704fa84588c891be84226479e1ac6411715d6dac3c00855e37e8633963f0fc291608a95132c856caa8b9b5a6ec7d62a15ac6fb4fea54299475597523ae48917c093ca6ed24d70138c4e89a67e8df9bcc7b7998fcf8f6c32a4f1d5baeeb2ac984c382b70d3d1c0a154c5dc28d60c2adbc70a01881e7d67c980f2e336c783399058070b2209bd4afd09e929226780fd5baa2ef7ff464031b05824a8ac42e889e85d9e6212732f4c3f30d3d8701ab37ad231a655a1ae023728a303557d5e6e98b68bd7da95b7b15e9ffb6b4de2daade39c9abcbc619885ece1414cb595c3bb9132b41e142c87403adfa706f0daef98af834507c9c0628962ab657a01d6e07e5aa1365d2e248eb7cf47b0a5cb42cc2b3c32f91000102ed721b51bf1602e7cd3d5a4f6606c96b6f3aa1745aa0b1a8ec0285e46f0a01d91c846d82b83100475fa9ed12250e13641b51128e5a69e7e123fea07aeeadb0d1627483797071053b81628c8bb42d0f5bc20cba0c0df9e844854704a116c3714381c7478f64e1daf2838d8fe7fcbb629cbeb2c21c3e060d1d39baf60068327c9284575ec96a8401c4791cc48ca3df2c1a1b421645ace5c1f66139222dce0adad47cea0174ecc3a374aa3d1f2b5e3e8b48748d85e3a940d7352a805bd7c9591e549b6a6330f31d851531a3f2780ea1729b0bb145e920610369e00446da2a428912e1b8509118fb39029bde68cf02093b047533bdf8d114c2ccb956ea7a1b90b6d63684be84d37273b9f06e65553e8ef6db3d2bcdb4e2bfc126edbb54aba3015dbc3e4227b96648af98671ed6d286f375d6dce40cccd60d6b2c34f910ba84dd22aae682a23a4676b7e34f3f9e0f347301ff35be4b1808765246aee8d0193030570510c2d16471e8620985b52f82282c0422a2d603a3d387599e1c247324cd74b6ddc7ca1b1ecb890a1c857454728a2b0474d72a7bb5163fa5bce701076dda943d32e8bea413af0e13253de6aa3fe9ec13016f30b828bf3be7fbcffdf3b36ef11b2a2bf4c8f95fa36aec40f96d5ee2085578b8008530dc2dfe6fa573f21702dcb2686a64fef40160e8738c1810b2ad7c298d37eb0a3953985f0af10e08d9ae67041d50d800c38028a0e38c7b9aad57b24752a67db9f771b5a959570e2efc39c8f900a6290d66f26cab4d3bb540d069ddb31bbb7e96d10cadf7dfd9337b95f65e006f0dbc8f732293c510cb8530fcd93e15e81564ea390a80ac2876b75f24e3ffbc217dd7d05d35bdaa11bc619e7734082034c7c485d2d4041b9610eb221aed05182242cde059461c3c0b818d4a0c03c83bbf864ddfd745f9a937ed2936394287350b4ccac57c6601b65ecfdf0a81c70e6e285dbfa38b2c47654621f002f12c1b33a5d4e23b45da467eeb6578f86f6840cda781b221c3f18b97ee9a2dcfef2a9c7fe16ede06004d067436990090c2585ececc6ee86964e02dec5de68eb3c64cbd016e25746bc18c491188c1d2c7fa4115bb05d1c8285ca51bf7090fe68ac50090f3a140ae70d88afd2d085b8649d146923f1facaa537badbed807b80d662ba08b0b728dd9f2e1193419b1a45bc6bcbd2418c07ae1b037c0b225487c7db855d19d05c4dcbd3537765cba5410df7b2fd08e030a4ac17b207bbd4cb9dfd6baf0e3d31db8918784055bbc3bf077316ea1dbabf74c831e5f7518556550d3e372ac08b28d3082ac26f5b145face5a8253143239e8c214cee939005d1eaf77063aa72b7e1bb6f656eefa5ab54d451f953ed61f788461d8cd50279074d341d1691668feb7ca4858e9d6c907e4e2401c4dc29077416014ac9f1345935b8b59beea17ea7d924471b9efd8c03971ae0d9bd40c663029954e9068f3974208b688caac6b1e90db97312e01d8d8cb97073cce05fcf85ac5fcbe831613a58299f07d9869d42bb3c84f0f448a1d9ea9850a457d590353d8244d423ea95e07fb494530d5ffd538fa03b85484d939dc0d59238cbc4726f7139d3ab699bd6a0aa99ba728aa1226a4235e6c09f038e7d3d3d28ca16ce021a2fbfd85c90e66281bcd2124808e92d5f1f9d46baa3577d93e58ebda38671baa9a212651f8bfc72b61bfc85b80da9f4d6aed850fbe6512c3b1740236bac56463a497df357cace294ae31493ccf5915e9d6313048da035c809e8285a23b711052196a82eca830585de3fc564e83cc0a965dc1b25cc0432e1db47f6d89c0969505151d5bfdfaf4cf02382dec9ea91e409b6411a26b5940a1bafc3da0c14b974a5ae1ba534a5afd108e6341f8f4f86bbabd07300007223fefeef8543fbc207342018e957b88802d6ea17b398ac4cb5a05133f6eab839537f6b0c89133f3a114aecab88bb776e409612419f09dea656c16b5f4125a3cca32a2c0938707e3663d6b8b2c0a982598d9b4c8b30ac2fcf5a71f858c0f121e871a09f8b2b259ddb6219cee464432e93b2143d405bbb5f30dabfb20260b2bad0be4cd45edd8979dc1905b57f50652ccb16ebf50ce68ccacd66f35816138e06406d5a45cfd67d1ff2251c29fb378f11410dcfa5d39886f3d6d2e13838bbbec5936ad912c562945812d4a02926e50fe89ccc29001572fdd5a0bc87c1213e829ac54a8bd5e39294e71e696941c1678698f5c9eb4bbd0c5b3dd834b54bd629eba7d45808c983b1f6556570f3d2ddde0860306105f3ef18b52632fce3f7d8511cd4d129180758890113d29c1f46e3910a1b7fffc8478a7e15a0c8a86510861614af5a86c66240533f6e2f5e79a997bbc05bb70fe5c69bc5c0dbb1242b2018f684a596e6928496b605db8962f91ad2748132247db5855f27989e869b4781c37df347cef335cd61ce99393e9c78dbde19e55099cd48251574931e615d6af68fb1830e742b6141c7347d0fe89f03866d4665cec8e188333df6a8168510f52a929de4180b4dbe97d2302d4dc733d3d057a0d44200eaa8562a464d429005cb804e00d4154df4a7e7572cd8c56c6f35b860416d80f4b164945f3551ee171b0e922ee3dd3746e77432c27457e49c9baf2c463c4eaa5fc1b2e55e84142773acf6cceb70becd25377050d1901fe5dc4f82777651ca2671a0994457372a88617f47e896365fb7d0d2630ef70d250fd8ad269a1d1b8d615d45b0e7947953867fbb8f82093ecc07501ae06f0699fd383e57d23427fda748868d46831683a375a0f2d522b6bb988dd8e5693d693882cad11b7fe74397496c79b7cfacce01232020fa2b13ff0b4017aebb24b37d2cae2ba2c8680ad70684ccc01923369eb6c08b2ccf3050a85baee3b5c7657c13bcbe4df0720766037f093ea6f3a745f7031b3367d24ac6f694e34c533c47838623335f49ad5a5f7b85e1980283841adb9be0a4b930354214391e796c051b3523d11987dbf4ddcc3aab83bc818191c76278c5e9468d01a3e9c3e3d08526d9c53b39e550b80abe04bc2193989f124ca73b3e4d373c7672e2df8d45a78c85608d61c02f81bfde5afab9fb845ddfb173d0e7c7719f65b89e3864524ed14e54887da35e192aa967a49e8712947449ccd465497a1e3f8e5aa4a56122385703260e781dc0e123be0688fcd2b4f655523941ab242aad40c461dc386c160a8ccf39ecc017c52d19ed38d1772b5c70d74e2a53232b020d75c6a0bdcec0d2a7e97114ff66f49aa358b8ab63a4eb451d5230351e20ebcfe4c6470b9825caff1e82b2d7fed3771902c1fbeb6dc2840f31e93b7bb44c18ad3244d152521210510b6e3d507eabfcc8f1169b1c503631c8d29d95fcff95221dc492a06a5d8f55decefef653e219e8d2d9c655507fe0de978befb3b694ecd660db1927c5460fcfea93eab27cbcbee0521ccf339dacac74f9323b149e9e50eba2bbd4e6d6f21c54e2fb489236e3266a0b0db1f27171b70148cf8404324384b17013f43c45f32690e92d3f36d24a32aadf180d936ce5e22a2f52ee46923b44be6ef6fa2e25bc257dc63d0b5ea5d6b7f54ca1e233f12d5a6c3dfac15e865f0aaa33e5d4b3cd44b62b3621c592e312da4c3884468c861b7e9ef5cf32d613a888320b8d506ebd336f404b7532da2bf93ecef13402278d1ab0c3cc38e2faf85a00508c675fc1dda1d407af9c9c9f0cbd45db155167fddc2a4fc702f7dc45e1205759e50691d2bb31c9c6ee900b63ae15f43c32c99c3d7843606f724374933b22405aa81700fabec8d034a6453f305f68eecb3883a579d90febc625194b9a84034fb72a95386aaa662e6b2b1e6353d5e3416ce3ca67e7463845179c43f633199ac4404ccef2ad050cfc2b1c575b368e14d928a0759f34664f3d078e56b17a027f3a62e19cfca5bdc81e5eb0cd7f73aca6a40adc8c45fd6d3ccbdf78362ca2f9e8e2f07e39b571dadfe9b08a959def576d7d7036b8421d45ddf888e6a0cc384bc57126488d1ec6779d9469f4494e60d4467c2e12223a7108ec564e2925b9e8f5c91119c4715a42035b4291474eed855cb294d69f232029db6b03b1a1751d34b038dbf934eb81d46c078fcb474516e9e04e72c4979478a2fb8697715fb18114e0e0320c3bc5e79835ebee5fb3468706b1d93d96fa2a3373ac7e5e28182740483bf5918405222e13641475310e63ac60295206a11fa141d1014101a4fbd0565e8845760fe424294b458a66670dc144aceae853a3009b12770926346606fa01cfd1422cd536bd7a34849d6d331d7370dd0adc365ad720063013bbf393dbc3abab4986280821944fd81837a65850e83eeae9c9e52c5fe403eafebc83775203a14a3d0d351cd0f0b40f6a9bc8340168dec8e6aa8b588885f687a1758a2a894ee7f7e5125d522cbb5f0389764815f3da7467e0e88f3c03ec8d2e15bb01ff53e5fbc22fb4211fc0dbc0472aaa8cee97bafc190b33b3cd1ed1bb281cf6c19c94617c5f496752448656e1abf3e37c3946a25845c2efdc8efe6df563c24334103132586c1aa7627fd95707308f33a693e7849698804bc99b6b0874b5e8ef94414c3320406021455faed68f05376b6290dd288fd50227966070afad681cfbe241ac50155ba00279adfe2a6d842f14c6fe54115efdcd503a264cccfc7dc9095ae909fdbbff6bfb881679b9e3080c4aecffbfcc043d7c2d731a652f60737a209361500c02e0099f2e9befd39d5eabba98626baa854beca1d51cdde819368b67195d12a0c3e7f0bb7df218d6ec85ef0757e764b87d00674148dda870d6e5cbc4d1476b30890f74687b7f64378da481c37183347c4143b0daa1aa4c6cbe35a98d9d61175204c73603e6814dc6cd00953b0f10ce6a5b3cbbba2e703c9fa0879297458793d95ca1575e03ff265f9a9b569383dc5e94df14ba7204f34aa86e51c00df341bc3a8eb57df6b135f16b01bac7da6ca265af0e8ef8e53d2f69dd9cc1b84d0a1337a8cf0901768be4d5a23a82deff1a7f68866d9280d7df16417bfca2f30ce5b117c81c7a2b2cf789ef2372465e31a9524fa965c0b0a2da0c325d0f69720d25bd49038ab1cee418a6e2d4b8a129f9dae8d07e64adaf9cea2485f477f03d72609bb99b0ec600af2a1e0a11946d18910f495872d1fbe0e3090271c03a9e74095da90234ba249616044c3d1038eaa3183a8aa9a8c84d3b673c7d840476830e244d1b19e6fdbd6c05bcf336eafa2128072b3d97dd345061b144c4bbcdafb0b16db59a2bfab1b847ea40d183c1bd7730787bc1f91db15e7b758a966992baa6837608eed4519ba45a1b611564788fce29e0f88d5c11a26746c6ee0a3e3327efd8a31774adafed080d4a49f3b0164903009f97ab9e532770ad0cef7beffcb607216eea8026fb497d6a48e4c0d8706282abeacd1a58bd876d39e5ad8b54e78a5f28881af27653c3539fd06f6d0d66463bd557441440469332b0272793e782eff237c73575fab3a030bfa284526d95d89c1b9c041ff0b68113ba713e191e2a40aaed97bfe44420a1b0954480d8fd5db81aa31e003afc0c292984250ed599b2df105124eb7afef43045f617c544424b07f241d151509992b6f19c09479a5c92185165bc595bc5a2e02b72bdec2eaa386667911b5a54d2c1f9e75886ecda5cc1a5af1ff3203c863f98a20f342da55da62b01ebdc48c93d3cc5b72171df8fcb62b4bcdd533d90d493b07ad2428261984a075387f702adea3ff1446183ca1bd706d870f82d6fdb22c8ef905a7cf0d34ff57570eb262cfa2e6255c331b4028c215f1eef3de545e069eca52d5a3725b57091296aae4b1ffc87987b28b2e591d4717015e6319c4182193e4269ec515993a83aba7c21b935190e56dcbe33aec6d6b501384c590fd7524464c370043c2becd636f574dc18d26ae1c27909b428be71190859d94ba77d6d64151825280178286b0fefe7f6a5cd8af505d0ba29c05bea2556acb0fde62878136fbd99d26e290816ca8afa03477d6be4b0eb4112c5bb7dfdcf962828bee15ebce9ad9bd001771241604289db16074947eaa6201a308eeacb2bbb75360e4ce80c32a2d0de4028c00d3a9ac8af175a42bf564b87579c1cb37f065751b9e53e067a70683c34e02bb34b95736acf6b31605654b86810ee64512a751d395159f52bf1905d156b3ab709f68b94b976cdc737eb6d96d47b816e91230cc51ac78f7de223c70364cc2214a043d4fb9349d26e94309540078b1f1472bbae0e84893f523c31440cda29c352a067983868b1cc4935c0981a7674a89c48fd3daf4524b300b9956e54e9359ca7016a9f6c29b1fedbc99ede995b41617240a0c9ab53a72b7996533f3584d3e2c6a0011346173ec65ec01b23578c0c358c0fc7af9173b081689c5930ee4b510967c602eaa2fbc28f56e66a41854363cad7b2ae0984cfec4fbeb4e96e5d559956ffa7fb02cc8991dc870b08bb8606ad9455950e9406c6b592f9d210950fe58fdb8ac101cff9f60f0b60fdcdebbb473122ef8730552e1479f462dad68a993a7dd1981b21634bbcbe9294d41493c87ffe26c1344572f38ff84900666250402bbe0fc1e86ef30d48521463e973a42085da45dd18ed0c3d59a56446cfe06fb8d63941d79a62f20715800baacf3fb40c769d0a7f0c290dff1764538a7e37f65a996939fba1d841ba9b90abfcc65e757b9488d38f884421da665881021f1c4365f1291e56ef5ec76eeab0d204c54835f82642a13fde36fbb80ebecfe4c8eebb56b13906ed4dd22829b48a0f530b6824a262be77b9171bd08d8c7154f5c0e90fa4691d8fa696a7835020c1841c5d549679d3473b4f07d3774390e8fca31f8c8f30c524a5eff708ec4e0f53b3ac9da378119046f14693918ff3499cbea0e0ffa0d6dcc21857c905c558d5039e1d0505fc174d2faeed90a3d1a24a80c6b50919e7f5af72841c03bd895ea3ec4c84fe85075c307e239f915c38262b98d49612ac3aa4ed0f464480ad3789251b2131012e1bea8efce99b60d8bae984ecd3f6696a61a0541d275d643390998aca62a9789c04de27e5644fe52182ca337614e3961df5ede92c65cbf8a5c6c0cf4045c229310dbfe9ef8a3a42fa34abc7a606e7e69466f8486615ef139d4e257caf13eaf634f6188bd04c037736ea6a7bf783463a23f40802f43bde08c80528aa6422f4b869541100a3ad677c41d28185c86cc4c3b509dc01dd1581a1f09635c547ff7b3bf792cefe3d3104040fea7302438492345dde3ec9cb916a01891323a9c34f5b38ceabe47c1919752dc444711de5670f702142570227e161541c4d1a900e32fc6b09b4e1cf4082e676647ecf0404c70c575bb90384078b340a4f4ae76c5c1ba1088bd518c4fc14d8c32e0cbc65c0a2cee3fc6edd5ccf2228f93a93cd622082c2cd4ee614776d45c67021e28ee6ec77e8c437f85d923ec6375a8d3d1500eaa5d465d08b9eee0ce59b9191dee77e77c37695a57a546d13b9ccf42bc8fc5bbcd2f70952921c20694411858e0225ea94d7d86d48e046833cd401b72ce94a4415233dba5b983e06a662b69f21624abc613d80398ac2177667f56489b48fb45e93c95636dc8c465aab680f040ab0c773e10e05cb129703c1000b5fc0dfc4f32ba4be3d9c738a9d6a4086c0706ffc4d1ec08bb5f9fa7df24a84a3924857410f2cd3e9186b42a0010fc0545b644de56e9ba2f209d9b6f95b8eacddebc8e2dafc10acec466e455d186e27443134b6e27f591f096de8bf365756a7eb12743c33ef03531a8e950b450dbd170524385d6d2ac9469357be0fce6a3401f647c3dbe8e8343f13000f3b624ed16f704855cf53804dc2af0fe7210abd5319f1f6558d5ff40a4323601c95ad2661046d2ec327f660e6b69aedff825b90b6ab01f5354e03d653ebea6270688e20095c6492fb5ebb6268851e95f27e167b77b19797ddaca6518d7283ad3e5eaab8ca880cedc37f667688085d4a29c1d791e002d983b3c31a87ef5229d3083ded95ead402b78f716989e315619b641f11203eb49b1a451b00701383e382e080c84d2c675be7eaf48452879f88d7516ca04baf1d5fa54d610f9798cc7928de56bfaf705389d6ce4438a16b7848ebb9f6ab418369c51f72f5bc16e926628666dc63148df66686deaa9d45aa2f36e54f14538ce105ab35ac04c44567be15387643ff0fdb6cae0ce9c3a85ec15cbe485e0b4e96cb12de946be7319c3527b8cecc58fc1a92e687ca66005e87e91fa5622e978abf8f508316a6ca220445901048167d8e7bedf98347600101d1c120506002028eb1750ab4c2be3473d6e4d0aae7c2cef6f8577a200bb1e6554b26de6e965c2594d76ed3167b341c0c49b48946902a4d808b82e1a36af0594909891cec57a4486581e37c04c89daa2181de7104f1c8308604ddd1e029b747f9b7af0f228b8690cfc0c9b68c5a34fa7c4d078dd5577bdd7bf443d9cca7823fc1635b5c0fae65b621276768c030c35d9d073613591d5a7916ecf5af7cdc0897fb68432d9e93f25ed5318b86a6a0da8e4126a42a011be885f0bf5df2071412bfecef2b8cbdfa90bb7e2ae8702e85bfff1e732bf541dd2cde0f5e39f498b65be3b83933cd624465b722a4e52e3038d4efe310be15d4735ed0570be421de546880fff9d502ea49ddb98dec4eafee9c93fb1bfc77461fdc35fb034092401cf74a125015b6f09e52eed0138c4ecd49ee64380515da49957512dad8ee044eef060b7b1debc48358e596e49f3f82fb38179e4d3fb25cd99af884caab2f6764613ef18030df31784ceab1bb40e9382f4aa696f334f908a370ddc14b70d316e9ae93f82b81b2e66a5742bca027acc94c7f1290aaea9130b9ee841123dcfcf6abbe94fc70621c8af7e09ad8b3cd3258f3621e1622fbd99c661a8431754dd49f7dd1bcc8a40c81628f2c0df6e23fb897841dbc7b82c2ab877739ad4e43f7466a987c20c4a4bf0e286fd1a34c02194c46280ef30eace9cbc62dbb1c21be78599d20979a5d8a4ecb31b5e8125031da50d8b3e645fa062639bd1ba340b2e22fcf06ba4bb2c58424ded7fd7c35068966bc859fe48fbf1c2e770cb89de049fc393e913a487a0c228c6c66f564f60d4c248247a51912a1b023ee9e92d43b3900ace1e1ae30201bdc4f59a8bbe512220a65cab16b6e952e0f98c7750bec33a11b96bb3eab5b03b4e03f338748eb3482e665a6648a6349291d068c522be61da3689a75749551c5c9e82aca10e62b8f05bc3e2882d4a30edb55d8f1b3ffa6f2d10d26f52b9a38e590aaa0115e0992e3406e09270f03a3093b26d5a9feada1e7aabeeccf8fb128be603fd7313c5e9754fd074a6e533d6033b62625ab2cbe7f47642cc719654b3b96f7aef73402b1241399e6f87b63dd6fdad57aa28caa1fc35dc11d0f6abf552a2a6a12b9739d226eb8029cf4a6b57114104a492ad170fa75e807f24c175ecd20a31a3205e51248fbbf7907e1887f013634fc21fb051d6036cf8f6dc220ed39e8d3056beed5f593fa00357b9c17327d14c480683390b57888e0aef319fa56805642d9c58965676340629f1729becedb473059650264b1bf2d6e595e7eda059f595a7edef8792c9e5210ab5322f509ecc5037e759e8242496f119a56d6d7a6b28985d7c10e23dbbbf127227460fc439cd8e9c30874c80c2a1951c1a15259f12644173088300c6b80d8b840cf6bee1f2e0f98414674ee7f323538b29a5f10736aa39743978479579f40c5ef5832fa211e315415578162ec1cfcfc0ae524fbe754e3c15c56adcd7e1d1dcd0cef8b9b7f1278f56762068242138372c5edd1f883f9ec903a12333966a5c71f6293623f7a63648e5e3d7924569765104b58374ad2c2654158b1e94c3ee075fe40b20c52c3da7450fa7a3bbd2830652121f56299af10a5739b87328886e26d810334f30481695bdfdd04650eb668628b8a487a6f045d423a90ad6fbd112059bc812c9791f9c4cdc9d68cbb791b19af03cdb7756b30e9a0d7041b58e091507df2eb039052d947011eab0a72046e9c55bc1a45f708633ce5b5cac508e2018c9a512fd48891f21888094e6ad3ab2bc8cb4ae8c804e0ce9ffcd5004872d3045cce3680e2f676912562a57f6260778ff8100ed544454f6b672e27f5aa0505ba5a648c61c13eb16579c76fa986fd82e6cd63cdfa1606b17d2004f643ae1b0fe0b13f3eac65dfe906376bb02b7e11c17438ca458b01733af6915ee5b8690fcaff7c0af759dd167b599dfc6cf9aabbca6cdcace2a94deebbdfca5c11e917e64cf961cc8c29168c410eca9f3f24fe23cacf51cf6c8317f69c2601b90ca761b92f3e2c063f5df41f9390af587acb014f8a19714c8de40dc0b234c71b2c5a5b8382c0cd9cdd1fc6e1690d48cfbbd17d60e0f325ae3feab4f9b7ac016bad58e96687a308263be84c924c03d663617ef8b2f88ce62381935dbf9a5b275a3ccebc298080083cff471d819e23713fe105c30c203e9ff99ae052fdac47aa6ec924e5a53831a5fdce3251ee85824284e0b1f45676e5cca603a45405eb98fc64f4bf8003d736e869ccd99c66fb4f4b4ef1387e0a145d81eeb6acd91d7ef274b60470a04a32d43fe53f98c2475149ebb0a425a3e87d8a16d664e5073abd6ba43d7748f54757d592b8c4f857b51f9d692a5a1b4620da0d95a48ee1b2626b75cacdb17a34264f91aecdaf6ea5e1a2a381a92af3546c204fac86a40a2f01f606264f4067a902c4261e1af98007c2c46e3148784b0bcd7ec6176197d64b76e104d7236eb577cb88ff4a3f6530b4bd8583a5d100cd02db88c64b6f5a2a456284cd022cfcd2981e8c889eb54464ef1650c1b0ea803974e05d727bc01723ec65d5dbd2c64195bc2f02acfb62165ef97ebcca9295ff6a31bfb96ed8b9c43e70b0e29d3925d43d6d07c1d058398c570da909dd23be25bb2c02c1b9a7f1885a5d0f7bb13317c76a772e698369948411a38a4a8161d0dd8be8eefdb6314702ff4ca8ef02da3500cf1b399dd291d086f008708614a1a5dde41ed364206e13f15fb00e54e5e4fdd7580e5bb09b507c542b09e2f46a82d558e6c640df3164e51d9aac1864cc9b982d6c8057ae2d6fcc31ff22533ccbb95a2df33566e071a306158dc01efd77ca1ff1a7b661af5d15330f2ed55efb73d8008efe6dbea3c03743cf21e8f5a6b0828900370badcd8df6e51610c725378646c5fc300e886b22104343ea1de191b41a05796c850e3b59c32983dd6feabbff874253292c6e464e00442ee1586b0b9452002650b7e147c55ea8aa6ca6129ef227f7b6d7c13442e7b01f48d98c47870328d9f961d9bf49911861d935cb18ce5246b04e0f3058d33e46a9f28d6e156dd62b5c633440c8221d71a5c12bf5b6104acea94e69955e2119ddf65b9fc2ad3d5a0524ec4fd765ec97cb9003135ce31d674d239b0a16a59b8021dd91aa215589618ed0b2e3fe62c57f42d1ed600707b5b764abf009daf8ed9d54d458a4b7d91f51a8961229a4ac01d6cecc9d9c1e0125eec0f2ccd9bc400e3a6640a1683e8596760ae73bcd9469bcef912c2109f0675eca2438a8313e7d4c06e087d1f8a07d8f50fdb963142c75e43d59801921701004f08b3ebee574a90c92066232a037b9fdd097e325f300b6f1d6793961180ca73dc58d9d5654cee84d62027f215736c2462d8e8694ac8039633419c563e7e0eddff8c591c5bec7f5e34d809d010301a55c65272a1d50418c7ed0edd1886e49b62e8e0363bbc8fecbc987fd5bbe31d1805251d88514cdfbf7d1a113504bf64133bbd776d5af1fc3e7785ba58d4334fa0033e20b4ac56974ea8b35bb11b8de12a3f2af067742f0774b2cc99645e6e3ff048887514dae88af3aac78f2257a5c627134c40a14aa10f42c8183d01075a6e60ab94012e58a7164ef0d714ad96b27d0395a7d9df22af6c02461e475fb1c03aca0e515831ce2164b70877ea4f359036289e1c257963aa827eeafd8f1a184f3dbec109f7728a9f03fba01846a9d7121c5bf6957a00a3c95e2e3effc5cc96c214450a383cc00eebde608a37f6e52c53802b6820b1208622bb870204332df8cb425c0230bd3faa6792f514462c0554c96b39301f7bc884c07d0b2b0ded407a6dc6829202e89904385e4a6c2d0bf3550ddf5007e5d4a18311882362ac5792cbf12b0ebc6aa7a358f5b18a72cf9821d7f804ca206bc804a0ae734bc86573c67e1df8b8e5f119274766ce6e6ef295af6706876065bf6b7535256444c58445f70e80901587d9b333a6f9dbf1440173af9e1632565ad9bea741eff3896e64f17d73427b24bcdecc50b80fe31ba345c84fbc7b3d82722a46070faec51879c1e5fd0b854eea3e09e2c0bdb009a06b7d5188c9aa1f904185bb3bf1fe192b7eef5ef7791c7c081d986b0304e3f9d3fd173af2d3bc06736aa03f50ba787f0d497509a0cd7a16629853dc84a8c852cb0c9b1cd72112120e5ac57f339af7448fdfd003dd04ecbefb19fddf55778b869d191581182c84da051f55169196193cd91a6dfa028b2e6411c7309141222c2d61947e5c5230cd69df1391f3312bac67045c1adfa0caa9022f5cab051d5302e36541083110d2abd78e7e1abb6222e1d488dd89a20e75a1112c001c4fc9f8747afa88516463aa48bfbe606a219dc30cef0af2f8d90fbed0344806558cba64997210f779e9e45f2b080c3499416fbb3eac1a978318ed9f4fd34c6fc764a689177105047697acf52d93e8472a3190c6798901b36dadae0864eed48165ce57765d61272031a229d6605be903e38b3ab044730ca7f0bf28c182cb4d892ecfeba20ee72dd13d7bcefcf92a053ca91ffaf301a486ad92fb396cbdebfb3920864116a41a1d9dd27f5ebb53e4dc6a6fb4d656a6f4678b7197132046141040add4b2a135c027da490c22ce2ef5fef5d569ab94275f00b9be8a1055fd0055a19870788f1f37e61e9bc24c8b4f1852ec1a2c3e622a73ac3aa7fe57c0d2ae1bf372047d1dde0b6e46069d71113e34824b9bfd6d7206d706b0df6b389a17441954b45665bad78ec6e24a5d222daa406158ee49db4f3d964f8d7d908a132a805b65b5439f62f2a679c764b7260c2eaecec3a35019a0ad9fa4b35be9dd113fbd9e3858ea8f243c038bf283856a14642f6cba12abd3b9c7df3843e148522d2a5906b93e035ffadf996bdf6c648c45c84aafbada85302d3053b4c9ad653a57490ae578358f6bbea9901146417586e9a11e57cf050a4d574fe8087db4b98035aa6e4c84c416f19832c0737f5578829dfc64c38ce32768adb9c81cc655ac1d12e19d0d696da098f8cc2d10c66a7fb8b7004e71f91376f2f35230988784b8e911eba83ee469078ba79d1cd8097e472ecc0d5f233bb558e6dcb17509010f71c225cab060d5991004bad2014e0ff4eacae4337dc325acb80e63e9c5963b7ad6e52012ef07748b21b7b5be9eb79dc97fd8820c848c8ded194317ba556b9b58e364ef82b6986629f56d4ff65aae25e90e94271f0825996302c5cf2833cb825895c97431e5f417a483b8e7f3a61c3fabec64f8b0688be30a1588d2a337a16eca94e4228e6c5e608586cf6dd13345b408b2650a62073ea6e3038a6e0aece2bf6800513041f4073de9d53888969ae66142d5dfb7e2f0ad8a99607f2deb46db4a1dce01b311608e7562587d1adb9a1e9fcb326025410c629e0aa2148a5863d6a9c76b353c67c43ecb158ff0efaf596570614edba03f98e9f55c31daf8a7f4d8200defa06055e14337a8db6af16049fdd257aba5f76c54556489ad91466f800751c79af635c37aefd3e665d57c830805428f0ecf2fdb2caaaf55e2d8ccb7f96219c2fd5306d931771d8e206a761300e50a937782372767f7edff86c5adea81bb92b8128cd17c23313bca0dc00db8bae083496e215a0de67582f6f20ceb75dac2bb4afd98f2a6cf9dd780eebcd6fcb66203bacfc293944cf93aa72441c23df722f07c07161bebe940464f8a8fbe6f9e3cea2cc834b7c30236d3bd6db17479b14bf63b8442aba68ac1e2573b79536e6155aedfb17b82417273558261b97f9bbaa2a80ea96273f1e8df597d91df824ace3452377c5b96a48bc8b434e838d2d95ec218a35799e81833c067de69ac2836a0f57cb37dc07396ae0bebd0abbb1072bd0fb0a2c30b2d9155b304754b175cd6d94cb4b44758ebaa38dc8aaa5957a9dd012aabf7620fc425d05a30979ef357253b1227b89569b685eac691d45aea740f30701b341b51869572430f1a1c70df06150df65eacc14a1df08d446bd51ba730056b143b086031a500a2a0129211b4f45fc11b311d37b0d9e273fb6b3dbd0f0cea5d13b3a67e5856a51af7835de2fa32904366fad847229dd4af2a72d3ec12cef9e301d8ea34b18c6531867e4127fcacfe419240b427c662b6fbbf0a7b969abd2fe6484fd6da591b8e03cbe21dfae0809d6de5b0418966ea510503b8f3f3599050b6dd7e11924f429dc69b2d1f82d9305a7401e716fbfd53f8d51b0b7fd5f3ec53eb0fe8b76062ed9260a740626f8ccd3cbeb38d646dee589075d039ef7208f83e3373bcec38b05820c05fff0b681ef98a384bfb1b933198f2df981e8445729247cfe186dfc7c756683914e5df31296b162623309c2f86db977e1acb8904f8ef9e3f3665826c1c2ddb5c3411f8424d040afc982042b8845f734d2a7c0bebf0f0da25684e54bcaf4062271a080c3a9b81f601378c9ab74a3a22d8b902256efa8c48c3ad3dfdb295c5fbecf286eab755cb8be7f5205ec61f17bebf8464f817713224da978b44f8dcb9a7cf720626b2a47aa3360b91d712477ed3c61220e6029802a904ef16cba696206f455781a71bb73f0127bbd002670c9ccf1f132ce0a32be28fec58d7418c1f3c5b4b0681c3b73fca26077a88939f4960ee07721f1859e33f9b8b2191022883e724494588741e2fb858c1c823b34c20c2b1b96c609cb396d4ef7891870ac572c5d5c60e60f6709bd613e3809764109305f01adae46105e533602452572f8690f09e8ae449ceaa82386c90d62c22c5236a31aa3589c6ac38f864238ab0bee3a86dfd674db6281557a9e034975d3da35976d6a3a42cd87494821d9dd5ca0cec2753d1a45f6f2dbae438fd077500bd3268389c57793af96d834854b5f02124dca720def1c66d285c63d316ac4bd482bc492147c60720ca0de0c1f5bc4608679e1226a1150a717a45c66468b04714ef17f88ad968169a43c80d6c7cfb8f50dde222eb957e7ddfe5ab517e8d17bc5aa3426097ab67ad2b6cb2d5a56e70494673a465868277ba7d2d3f5654d180fbb6cf727fdadb85260e3383e183ab0db365dd8b661a2189df0a9f93c0fba98640f5699859212933ede180d2056bf8fde789aa1317020d220b5236fb351112c838d25f3bbc054a197e76e4addd2b0edaaa3ba1eae32a39aab52c1a40d04f85e281a69e5f24502deabc3862b004d6ef22c6ef0e97bc0b7d3abccec9f40517bcc06cce9e5e83ca14229120ba21b1e4672f6a60b53543adb6013fd60c89de7bf59622350b5e054260ba5eaf461269d222dbcdbb3b3b1ed46269929396bae63a0ed98db64a35791f5a307c308b242182d1f881335e7470f24145446a9d71065a02759047d439e714783dba45693f8f9de0e490b834bf861c68d9fea284f4cb9c523efe3f9393591e25ec9cfec12f8f37bc8e42dc3664678941ad2768c73927711dea2f42af9256617bd527f339c68c3f95bef715b442c3eef239e07525cc8e68d2590e6d4386b111b42ac60507b9c4048633a390c89ddd42feb4995b8bcc71d27acd4d4452d071d5f1a7327f51b86b8b0a747f1b46faf80789b81f4c323f67256603040095a34d6477f47a17098d4661829be1be804e3d69e95fd3a0a3fdc4457c76de7908b73dfcbd24cb5cf69041be019449a573b5d6a972b1dfaf351e4c20224e70323cde8986d509413cec84b017c7f3de1349a6b78da62b5389060f37d5aa4165bd11c7f6238de1c0c08deb6c760e108897a9e5a53f281e8863d1c4758dc0a15f3e3e927cafb6f5bdcafa920bb86924c119c44e1a482208278e222140bac402068280953cef01e60838b1da8898112ff941a4969c496309ccb300fcdc7ed72457a131f67886587344b15e2c0b8753faf395b432ac1bc82af3a2e0967c250532f0858fb4f6bba4479952b1795a2164a78fa9e3aec4203aa5131281faec613b4489109bfb9d1a6ae516af4f11953d65f3b1bc15f2d66a46ed473caa07e321e697b06483957a0f1aad5dee791b005fc57580cb4b4c0872f597d7d7b5ebe53b9c34983eacd97a18f83cfc5697f8f9d01fc280f2af023efbb1a795135a1fac6d66ae10285bfe7efa17d4911fa650b088dc6e393340ec6cbf9879649c27f59733638e4c1d260fdf808ec9762254e6cb8b66e2694933db23a8052f11526c75083f212ce0b63831f5ffd93acb91f9716d042706c4d6ce06350b72b341cfe54fb30721a97e5a2e203edbeaddc482a634efade976873fe04b93679877fa4e17e1ea812930c4a755365466517cd649e53f9c7dc99406f9687c1620636971419c85cc37539c80823c9c4472e50a7c5e95ec1bd725c02bc768d31154bd70da3b2e7447ae8b438c6387d772904551fb9ec94b8b4ff52c3d9403a6421f946e10197a016be6e401c531497ad9ac3317465d6dc5f676bdecf28a67b05380d5205f05dfcf1ea6bd031f704d3819bb332e8a57cf1d74d66c82470db235f66f96483ee3b6f80b4e6ec1709f26c59aebb28d54b757a3b5e7d4b4ac6f53f596c6d9f0deb1f2ef343311bbeaed4320f22837114d58880d05b250203abbda419731584f001d30e633aa6f8395c04e1597162a0c3ea572e58c5b423eac970b180fa25b770b9380c120bb37e7968ad5da8fb6a58bbe1ec88f368a628a8cee426274f5a20134d933d785697cb3b58859573addaaf3e0adbfe6d182c2aa56d8e52d0270c2b44813560bf3739ee468ebe74e1e8d910885dcc48504a661506fd7744fc0091f8f26d08893dc85b0fc8917e273f129350bc268ac897f1792c2752112c64d3f2c18b4e3fb38782c3354aa0b81689dd087d742895d23c98aa26727e61125f764f4b78d78a6a82c543ed5423d88e395c2ae7e279794d67a6159c0faa5017b0c4bc03d231d53cdfc3abe089dee5c4209fdcb93acd3c802bcda62170d47156adce77cdaec5b6801e07adfe56153b80325d3a37df6fef3bc623423daa63640d08dd15a8b7a2a4f4650951702fcb5307980ef1fa87d53d874931b0d4e7198907b9c0cd1fdf87a79111376184e88554b08143c091235197971cdce96407d2749fc271d286c752fa1981c2871cc049990f6eec5c51a657fcf4ee7862f578562df757d674f80edfa86a826d080405b1ee0246e60e978241a6db45ed6f59a90b82843820294e269e2ea0e6066345992c4a607641c1fb48eabf528b2cd2ed3897fe3be18992734cdf1a1b6a0497443bb6a7688f70e0b3220c5d0c73569e889976c70e0cfdd9111ab1829919d9b8a840e6435dcd7274238cb8689abdba6a0b6abde895655020f6f4d28f7edded0ceedb8d77c64b098026a210ab6a5261ee66b6d73a4369f8001ffcc67b25c6760fbd5a8bb3c4ad8f3f50b00a85ff61a8ec6e96ed2ca5aa537f9b115af98f82f46c15780f44a57409c69884bf8ddc48625c4376874eecaf928426e751d125a4db14af2737e227c98ba713f69909b2b46ff00cdd9c58e647d9b9e1762da520607e8b39baf9b707584ee277c55e51b8ea0e9cb039f2badc3b1acb230d6da22f8525f3054418711c66c69fcae312bc3808f098c17ed489c9861702ecbc2f9b9f4e48bea2914c8c158d1804b30df29af34522307832faf004ec720a0abcb5199a18ecb816e6fc5a14f5090a541d264cf9dfa83c31ead138ca5615b8b72d94b321feedefa56e8c9b4baa64c358a974f9af29134fd304b798243ceb3477b032f2c638f73260c9685623c57ac0b33c450821c78b6be2f9917ef5779b137c3a4e06c28f287d7645cce97c8891825c1d442cfc38af9b9b6e452c90a71f27b55388ff34a4f56b5c5c1cd69fbf19e7947e1aace7b60378e375ee65ddd702f986d9c24c19d1ad712026fe021b3e98b7254c64634364626b2ec625082138c9517441677e0568326eba12b939c04e473641e49c49eb2ecd72bc0cbfbe8aa3a11d91e2c32db1ab2d90dd16b001f8b4d9711d3f684124c6d9bc2a9dd885536613d295d11bc51ac7b2005a4d299a6952a903c06235b2f97dd6c4cb364d41e43bc3b445b4a2afd81b86b222729418a62806ee42af7b877b67f9a1b17ce61f9bc907f2be311b7d74f70f300b4ad76f08480d3b6aca0b48ca68a57a3930f54f438fd046ea82fbda6c6cc76a87ae52a03f006b2b75b0b6f4a832e53d496455c3a42dfa667a8d380a72e8a451812f4964b21b1a67afc228554a8488757a01523d59048a5e4a8b1ee4ef13a45aa4c98dc39ed77642bf094d45c41e83919ef5b28eb06e99e8cf76066173d4b6cf7fe5662d18a8afe4c1c26dea11e79857135d25878abc0a02ec408a62eda2d7a6f861226c9a99b3daaefb4fa3cd07b9199609fb27c0d1af0810bb335c28dda91425542db993dffb7e127725c5002cd793f33197fb82800a076178913b54359a44cf5328e149cde8c1576b83544eaabf341deb45f394da6230e0862a1c7c6c10bdc66358771b5a144dd2db223b595f8cc32bc79225034fc05dbaec1302904c7291091ea791793e7adb41ee4b22564198445745750b274751cfa052e18f550c0b4a60645c6cc6eb748a4836e3e75153787496ff230f6b5fc9abcca6a19ca4288c1185fd1f27988a21f8d1784b0766304d2da89be3781df4b8807fd735387a4299674a0c2e6e005fb953b5ff8b1f6715fe9c71404a246f1cb0f06e96c8897f271a17556c7ba0896568590e2aa41638317bedd969febc50112bfdff8744e43475d6974bdc6118a322f69fdd07493254c9fcb47dc2cf87d89a7cbb65e2d2399dab7667174d7fb21e427b39614e2963155f18b22ebd8ae875c2dcbd8e864b903c13a8d7d9e1fbe7b46df27820759b844fd5bf47cc3a5fe53d3d48a2cb344217916ece7e6c00cb847ed9918a887c5373da3ca224341025ebc9437b903de8bd84d977493f3125774bb0fc9f6fc94e7a4af7397f97d60356babb2939032bef769694d79c291356d658ce5441a67ea118ccafba69a4c8e100d730389aacf46a6a49023bcdd9aef4aecf81a3a0b9144cbe9cf3cedf8d8b4040c3f6dae8e44a38c7acf6e0582b709f90fe38186b3d82ff56b800867b1fc4102bce2ad5ffb856725b82f08a7974f2ac14e52f75422834f1c589c6177166ac552fea5623afd8587d512973a993551454aee3e0ca01b7d9a2ddf44b0a6b563ae335946e1c485a2f149787a4c6e410586f57b1952f53c75be5d87123a0a733d3ae465651a508f172ed5a1768c1cdf1470cd7f1b61fc76c67daff94c3dd33a5de821f08b6d128fc6e72ce24821ea945366e05f0cef469c064ae33bf48912f1b03ff9ea20a5e7d0f2adfdd48d5de69812a8a921ac48f7ff90b832819e2c472c82aa584360633c32185fe92257eed0161b2f8ac8d836c7153f6a51957760b35a1d6d665b58e35a1006dcb37450e0a6bc425ddd4cdb281d5254f991c0a193ae1c1824191b8fc29133cf0f180cc62b2bfee3718f875f909792f7c51c2a228945b5413e15d5515e721576889f942c97657382c29e6bf201584929f4fbd60cb1dedebdc87952e8b516c069a701a15e0bbfed1af9517de5e85ddce3281d07dc20f2a0a65411ca6d54412d5763e3f8443e889a7aa49a831bbfc9c0e84fb1f04feec07c50031c2fe91e2fb02ce28261508e48fcd42027aa03d27da747b3de5f95f95ec1439262726c9fb27a676d70e0ecdb2472570b1e70a40f853569be95cc57bab0d7e57d7a6904c749dd7955cb55d35113aa481be3b98effc3d662f7a595dcbe57cc00cd7abb613a31829756462e2a971b99e8283556ad0469a981590da86f1e14e0c7fef61ea00ddaad8441bcd631e9f68c3ad1e420d59d24d184a3c5e0d1bc3f230a4d24fd4430a2907aebcf28322a0cd9cb368e53a3420f121362dfc4843b190fa026f56f9f006978e6913fe3afa1ee2641ecfd52cb0f1f5f1fa68517d9a4567e0958255c28787f6eb294cc01dde4a82c7c3ddd2934ebde822a2cb0c1d0343a7e4cdbc638a9345a78f9380a96af9ac1131c6d3544e4e734cd33d4e08fe77fbc32638b88b7a61359c79462b131b4a53dc3be738de25aef21dce548b2b462125d6e6e167c409bcfadb1dd3e8fd937017be40b0e2bd58312b13438d9aa92e10148bb1b496aa41d818446d48a688b4fb65947977f6fcb0d6a113a053bbb363a85da5dc6f5f91d54db2892d977f8c2c2e404ed0d403c8d607a6035e915164a5b5ef8bd462a04f24073f528649bab27510f61af5669bd98ac7a15b3d706e751f217e4f4582f9cac9e42a310c3688226076f761f5fbf102f2c9dbe30b573340401dc9edcdd2b3a9459a00021959d441cd1f59b53b2ee7bd62e8382351bbe8b5e3f95e9e282bebe9c48f34a24fe377ca46f559c754e46746ae5a2ec32367eaacf56ea9360b92b31a647542b99da86c3c8a6065c24e5f9d1cac23d41b8810bd2a2ec55f4a52ac3cbe8de1d94916d392497c31c0767828883f938c090f18db508274a4e80d206f0aba97f07f6aaa59b062bfb7c7f5f0f9d381ceb4b9e54103be29ffb4efcd43d6a076e91e7ae3bb79e2b1bc512ae0e54648327e0e3f47d347f5113aec681dfc71800d151773c3aed31c03e45d7f9a7917f144531fb726acec0fa583849fa8d7c36a39a7deb0c8c150884985f402e50b7b384555610150b7afbdda9d5a46c19e6e79ec9e14c835e9685bca997141c73f701cce9d94f4bccd5cfa7e1f25a0411ac7311b08a6e10ab633782e8fc2799debb0454b5adc5dd77ad97aabd3eff8cb373ccf8032ba461549508d74f7062aad45ac7e2012a07bc91ce41a253bfe2463de0e5ea2ef32186121aa3c65fea6c667c55304f776c621c0d99189ab5bd761deaaa021c011a6681084af1e61ffa6420b2a3ba73675505e7428138d47706aaa4b630e1fcde009daea0a84895a12bc1123826f9d69d0f3670778a0320039bc1ba93a43658d41139fd7f296b863e6a6ddf6f5ab75bfe707f1d97eea9fae733268e17e8f703400169994590c6f2da7d55b7a446c4a59e50c62dfac0670f261a87374b894b405cb3623370e0530aaae36982f31f57abf2c2f5de9f0fe8c5d2a226aba51ff0d13108b4f8c9d421ba9030d66aec6d88b0226974e219ccdf3617568483af6fb37485170b6e3977841048aa70bf493fd4a17eab2a20c7d41f4960e91a5af8d09ca7da9a34b62bf95fccb07353915d15cdbb238f53d6dc1b61b6c0ac853ce216c172183d971ebd9e90f19c7ed23efd3e642e95f8488bb55c8d4ec472bff9a8fa8accb8cc5a586990efb70f0b3445113479dd6fd517aa15e36de2204ff7c181ac898bd7129c17017d91cd8f8c57d01cb4ae8995f7043474a9e4fc1062d7f4e8d0d95cadc1a2f4f44999c02d962e8357981ced71fe64968fe72486563b6e1d070aa5f523abca9f9f99ac43fcafaa452c72684492e40ba4e8a2cb3abc21013b23508c34565318e4aada1cf6a645ae0906edf030b6b4936460942c603f5da29ca358473e7d08d0d53c1b5f059559cfae579bc3ada96ccf0fd56cb7a0b921e408d3afdecdd7cf36ea83ab805ede9c4cb1bd30ada118e2828899050829e0fa9afd306d53f0b6b42edb20014e80183d73f9f7d06c69950d436f8cb1be43a12a95a7b1abb94090d790875e92232cb213b516b36f3d9d4a7cbe67d55568fd095c70db0a52b2e0e18dff623b24735d002dad91ad0368e0f6f1b3d4fa3b2384056301a34e6406359f9d408e308c5b70a75db5f395b479ca2b001a2a5104a5f89c922cd4d4482539ddf20d589023bb0f07c70bd3405521b4a86b12036283a768defc7ec32b08a7e63c09cf4316cb6c9e242c56a207c422f4c97cbe0edbc2d3be4c7d3951567afad7bce6a7b8b1f85468f97d63e6fa833944dd5d8d31fd0c5ffe6af822ac9245432b75deeb6296058345f3a8ee36fe42aaef01edd48c541099e3182e76d1f19df1003f14eb997708dc25a42f46fa300ae10edbf73b45f748f002400f93de9fef9fe92c03b48e9e8bb41e92c868328c78eeb53e92908dd85596f04da1383a7b3e6194763d55187e3220780a7a20fd501b31e5cd32052925640135cde8219955aff51ea08c5973acba08816c681569be9120c785e0ed54b9659a071a036ea6b21ef874512193d0141863673402613c2b0ea3c6161312f0007c08161607bd97bc404ddc522b42abdc1a8af10abce2eaa93465d1ca1adaeaeb3535e269beec6977ae59c76d0dd5d5668c92444c02b1f48dc356ae6ac0c9891f597710e8940217ddda28f1d8c815af094c48194d96dec3f397a460e1358919defcbe6b6011f7e04670e96e5928a9e08d2aa04a8852c9ee8faf5dfa748b9b063d7013ed7c8c911b3d8f8da1f3a62a87b4dcb4da545ef17931d8beea0bfc86dcc99160aa56ecd047b54248b2f00ad85d38d7f693afee7fbfa2128d018f99937dce7094db93f6bf0eaafb4d736bb8cbf5b7fb84efb93150127f16a30b353a6a9c3d9273ed790d90ca5cbbea36d80555c025cfa488e25eba5ae7d5c566d8540dcad41c80be280a3def80daccb8be3958f4e144d8a52290017864e4d2fbbeadb30200f88fda044e0c7438d8fde36cc56dab54264ce91140c7cb7ca2835e28748aebdabff0f0c4ff606b69fec88aa00b5dfdc10be5c37db87e3ffe8c858207429d37d1650772c9e7acb15bdc46af3353219b0919c792334a74a3ad9fbfa646340a8961037ab4f5ad1879aedf735e6d092c6b778021529a342acf125a44047eb094a8066fc2803844994b947123c1d4548a7804a9a642a1b99636574b67531884f4068d3f3e84d795368fb21399462c01f79ed4c89f24c58755c8423fd8b821a96257874ce559d8bf92e8f00309587029872e9a0ab108f846a386c245dcd1892b5c3dfd9a86ff085478f350d12b4f9f11b0bcca23d26af3c53ffafc6120f653cc441d675ca61e6384a09a7b75b347b24409633e3bce09011330ca3e3e0a04728a926910a36e0ea91c9b7340c50e2347270ddc2a8da6b816507f0657d532678004a8fc4b13abb08d28a85596f293346d9d8a42a5a70f662fc9cb07a6703bdb242fa139c2d861a9575a8f6207a10f8eee1d6a0d832fcb39f65461e7e734be83f1795bad95d21646a99a9fc5f0bb32d672780c27fdd0bcdd9404d343a7526291ce4238dd835790efd1429da4bf874964572044e403430fa9161dba21f70f703e2f635fe0c77c846b517fd2203039cdcbbf8ad13c6f3af43af3a8c92fc144ad1b4f8bf6a71c1ce9a238d256277e93aac5a4c0521a150bbb01a873c8907479f28d820a51639650d9c6cec2d0885d7724955b670a346725a04e2fb3b33082e55c3191ed6f823abfe671ee28921d919c6a1eb5b11aa0ce8346d739ff81fdf452ae2d74dedecc6bd93c5d0b45f94d5cd1eb40b15ea3a2524197f3ebd198520ab466c97b0231fe8629a8c273399e17e7a23a7bf9b76c281555653a07f986c72bfde7636d4616592a953a79afd01f01286a30f83049e489b395903b0fec128f9f3a074d986f9a4764350f0bcd0e54c6a3cf8b29778b775fa95b50f0af0034e1ca4ed93c4d3206e7541a01c134c62291125625a940b12a8e308e2fab3962764a80735cfc823d0d08aab4728565565d1fc6a205fcdd42228492f1c3a6f17cb0f6b5f9ca0674a8c592f11fc6a98a249a52c1e8f548cc28fbb73bb6324c895f862b2565a60b31ca61cd461f52b523193e27c598477e46d043e87012314e7234649958b8d3ea9fae87ec089af840f1304e061b65736c7d8809075585dad0d3699a7904aa1a3a8cc510ef7d5331ab1aba16bbd2d94d080887f8ce7d5d42f4816d70ed637486f5d00e654ffe14d52c3081021a8cfedc416ba75d7d6b2bc7111729e2409f4a03602f510ad65b33ebea2e98a54988e063a851ae3f3c0ff43b8136206132793b4a3ae32ad5b60358ea4fd3fe03e4746a945183085c6127e3c0b7ae06fc6c0b4bda553f12c9538a0f9f0fb86925a00000393c60b2c3b410cd4532ec09b069c89a819f95ae60af26ec66cb619c502b69188ff2c7ac883445008b909a77b81f97c20e5027487020e1100223817a1ffc7ce380412c0151956c1884e72bf1dba0202a6b25e2f2ee1c876f2f0296bf6a8f790fda128c9ce581e5401caecb39b0605606d6680cb2c05b33e8069569f9150d0ec2f9defae1fd30af0dd01e4ca75f829c81d6a29080cc9667985b76bfbc799a2fb65ce1a43382a9a512bc0c4185d562977ded362468a8be1e9a3fcefaa1f6f33374fecf3ea3e4150b0dc108e5335ad6e317f426e4055dee4b0414ba9e6df0f73f270e3701fbe2031cdf2927723840115c8a08aa8f7072f303bd4bc6554edbb2cedbc12036ce2866200434117ae83a45e59526342d1ead13981147d1b91dea622ef50c8d1f378b005fc06d5ee210b61f92c6267e9cf46efc41b55d37b800f2a619c2c2bc255052399650e2a5a8b1f2818fef77d1ade04b052d45295a6b561d92455efc1981e3260cc568f25a496a164013bf83ab9ba1b17df021668be876f9b61a194cdb92a731269fff309ee834e8563d5ebcde36b8f801bc300c2c1140cbdc12fc28e978889f12dc25299acbd37b8fca11effa843e0b72cf0b0cd474e678844ac4a41aa39b4d6a0d4f43a0bc05c4034134e14ac7444bbd301677a2b10837d4e24cd467058d47aa21cfec762bdb72794a0a2bc0143b90596fb4a0ef9e67afccb35bec6c54f25aaf8d4edf6d2d1e73f3cc18eddc61cfc89ba29bcd1f5aaaaae0952e79f042a58ad68628d515d2a6ed0e9b10e5a42736b3172dad43e4659fcdffe275750c9be96506a066e6d1d839c255446991457248e3597dda864b4f00176959fc0f3a7c6f1bcc672f2b0ccd4a5ccd46ecdb3b9a63a05a85beff49e8f88e98d3890349f92207d338e1337b34472e09a0b098cb43c9c9a034882dd34d893a364f65131a07a2f5da74f592834db75a9b3066030ec30f5f28ce8bf08af571ff4c47e8af12c6196c85b0975f88a3f089143e835b7a1879ec3443460d62b2b60915b88ba0791c6475388f47c398d026d3ab1ee8dce226203e9fb13820fec0fcb9b34f82e16e60a8efc192e0c381a1417306bce978eb8d05e958931c9aa533e8d0116f32e0cbe982b0e6fff77e19ed904fd2ecede624924e8bff0545de88763d4decadb6b07dd6115e9d402b999da3ce19a66317c02215914d15bd016d5cc13e674c27a7d0e2221cbbbccb0092031b42d52749212c297ecf6c4ee983f48ec0756a318aa168b934838d3c3324a0d2498ba3206a7cf8fe2dd13a9a5c29cff5c905caa9469760c80739a75f67f28cd02299e57f46b8623484cb00cbf6859a4298e5117f1cc41a61d1943199dbdeeeef45040870d5d3aa48763433f2370b0cd2a52c4bcf9440c55f3492e2e65f3914b0b380a655cdcd48d49608c64d981a47de3933385535bff5952d9376b4287d3ead35b307663c79d71bb4c007e68fa298c080ae047064b2f636c189278a4bb97784de29675ad1d8042baa85a23f810b601dab69161cf493108bcf7f6a1f67c397db571cdd169caec777dcdda34abfabf6ea70beacb82593c7f680a58f8a09e988f845616d2a7ea2a15bb166d04c1d32ded1ddc3be2562f6c252a7e49de157a2482a4ae92715ea1461a3a0159a990fcb344c37ff81bb0998100252ed801d8b98b067d53d11801145e7a6300e104ebe01405445f37ffe7856b66ce4ca3ef3838e0d6439df1a4e86fe767fd16fdceaa0d20c74fe91f3bcbfe7078fb3cbc7a67e61b6ebc8044cbe1a72fe2f7015aa71bc464cc078b630038a555d985dd73c2ad80e4ca6bd372829564690c857f14f3671d7f4737d7ff5367ec68198a1569f563859f5c60b7443980cc1eca7e4a0419a6ac875bfc598fb890cedf31f430ceb416d344b7eb007ce3eb9c8483faa824c7313b84269850ce88471b05838889064ca57c31ac480678f38f3d94c14718995aed836bbb72986dad40dfe4a65a24f2da03fc25042a6157a95a30d815271df1a9248c74b1cddde5f6e2a8e6ba65edffe82edb4892c5790a2d1d4de854167a7c90fa12714c2f6e57e904a07904ec884081213bc56c66429fcb8f0660d4baf7a451d822a6ced5476bdbdbb61142c82664ef2df70e5c0acb0a680aa44ffa19defe76eeb3fb7cd3cc96d0e74806897e589f475bd55a0e5b49cdfda846f490ca54327d6693e964f2ccd8fc99407307fcdc79d6a51e587b2f0af583e092252c968c138aa9a43de5db8ef2713f7db7441a556b62cd1699b3c3c3e289f9c9c0cf8f063210f343b2dcb5d7dc6f246b4ddb4d1876bf1dc65dfb4c4bebbad6b49efd997ebfd2533ab47387d96e4f43ae3b636283b4414afaf6c990be5dfbec35d35fdc4d18a6530fb3e75ef1ebbe8461a4dfbfb4f697d52c69c3dcc8eb42a6c8403991647cf6299ff6d3c71de5db6efabc97beeea34f74d2177a0cc5560aa9a5b4565219625c99819f1f0dc4fc34bd01249555faa6efe354865da67b718a9e647fffb2bfa7bfda4918b65d3b8cbbb5daed8772ed3bddf4dd8f3e12d54894462f5c6bb3c3eeed33fcd27ec23052ab6297e95dabb3528652ae7b9209d7d488ec4b58dbba90e53c91e88b2dda212d405ba347b38436cbd60c3404a1826290cc913b4a3eee337cde515fe8299fe9324a285f8a9e4895862fb65264a0f0f8087991a0eb22080a1a81b5f7a2503f088a404890b5f7a2503f08364a173af71a138a0a78b225148e3bd1c87daca9924028b3e2ca7cc7a23964b1240e6d3343160d59b8b39ee4b8d039cf74ef332d1b02b283cc7d1b727517322513e9d3208c865d349443287353dcce618ca57470efbec3fbe931e442691f289b18f787931a55ca956a94777fa1bc8b13e58d5f29efde694ff94ccbce16946b32a77be7beee9c0e1947f94bc651304cc71ed65d068ed3e217ca5330eca461da9dfbabe3ba9317fa4ab8a686f49ad125cd0dce4e689433495f6c09098a693d1283a7eba2eb64b4b16449cc85424ae1b6a3bed3657cde51bed2492926ce76295f6c914cae26ae26381abfcc0cfcfc6820b6b5f7a2502c6bea80f47bbbf79a93c52e53d7e1549f8ba6eddd5fdbbbf73b0cd3e14aef7e3acc2bbdf3be9d708aceacab190f8943dba474a4fcf457ca4f18a6d387999ef23a1d05c34a3fe118327dde4b5fca9aeea55ea5772fa5ec7778377d47f7d2a7c384e3f44a385aef761f8de109f974fd1095b1d8be96acb985bc6ca150e157dc0cdfe9a8cfbb8c0fe5a42fe5a510377a7767f8620bf5c5968c2fb648251cb345e6ecc470cc98a99a583af9f991959be2ce4cc167e0e74703ac19ca40cccf9c2d76ce392de5b6a3fcf49a947bdc86537d199f69e9b8489f993bbdfbebd47da615aeae1637660ec498e832f37c8fe862f366a79d38b4f1a7a35e8ee8d29fa7400c65202dba0615dcd3bd7337dd3ee52a1db61da58461a5a7749d0cda60eb64f8e55d0686a5600fc350f009cbe86497b1291ddcb7bf381c67865fa6973009d7d4dcd7885ee39d7bcde8db4bd36efbbad0c813dd98fb0394f568c86b8484db970fa515794e94cf3fe5d38ef2653f7ddb475fe9a42f65ea2ef26228555b285f6c9dbed81a7db165127db1d5c5cc16a984c7496318895df49d8c19dcf0ae061257240e3102c547d9f203b78a2bb3f10f6cc59597178016ae7c877e48d5f3105ba45b207ddaa7407888ad9a1aeddb6bb297de3855b18bf498ede767ccb46444bf9f8f3ab4dbbf2c86e9347e6537615809cb88601b96d191317dbbf6995608e6a923633ae9abd922c2291da56f4ff545b7f6a2dbcf6f2f7dbbd9e7bbd297ea974ebae84be9289df454e35709c716e9a2df7b114e354eed4891020f4ee06447e9262ca3f312bd84613a2f7bd161dab7ef109d034a20e1890b68685a220ccb6e2c7d243cfa745ca2675f4ad3b62f25c23535a1d774afd9aebdc67b0df71afbecb1b5512153356f3fee9345640ecd4d6cd9d8ca7e4cd5fca4204933b33922ba947cb8a23126ad953597559248b0649784e879a29914095aafb821cbdec8228d43959c9a9996906575958078c3ccf017a03daedce0862c1edd129b7559837af2451799c562b1589946a94a5c913ff97451e5345d4e1f0e47e8014fab93dee9935538a20a39ad6e7a13264f70c3049ed6e91fac04318b214a5a76dac027a8a5332f714a0753e9a6cf64d267f2fd4c1e7d268b3e93439fc9de6772f799cc7d266f9fc9f63359fb4cce3e93eb676025c88410d43abd0434c2a0a48582f279b1c13b1285bc8edbec923caf61f19dbea6b1a2a06058095a51a54b5d81e8ec0c51d5f79ec3b3c4a851176eec398305573ec7c7160c4fcc22c9933c9fa387667122cf4320bac4aca5663847573c4fb36f2f8e9117aeec9f79d3459530fee40cdbd0d4e8a4224a33d1a45f77c9bd7bd7494f7bd7c54945b4a3d402cf3ad194807dbdf172afe86691cda2edf6bbdb760f257a2612fde2f08a3ec2212a775ff82cbf98c3d71cb877b7a11ba125fab65f9fbd5a955dc3ae2de85a8c03bf3498612737ac91b3d7a89fcc3294837db5e1fd667827d477950f9c1bee8752da2c6fb3c84c4a8baff59e33cfc69ca2077308e62035d71f2f097349ccfdb03f06c495c9720016b0c1d9ad7883767b613030080c0b813568823c4f6337bc12e8e6d44bbbbdc5b058869686532e6d66a69544fbe254e510cab2932909d3030d59b68087c7933c234b18b178354b2a521b53ce796f63db51074dc3b012b4aad0c5709e74b13b635629cd689665d9a946c4cd88c0a17999aa3ee5d9999167a785fc08d260cd3020ec3c519329f6a6c5d120fd15375ce5db60f78c46c5aee675b16b25907a5601c306701557faddb11a675927c4aca43102945393b29364c9901b213e3f82c0accacab31764d5b07142d59a932787489aec5dcfc62c91d56ca12d1db4b59a2a6a69dcd16c6896987b88c151e4c5460e14ea07c1d5aa8bce15f3c1751dd73dc41479b19143ce6957d765a74a4619623e9a25b4425e2e986649913435437a88e9e1e57ac1bc62ae18ce1671b55a1d86c68ae58ae1e1a3c60b1874151b66a3507395a3596068ac58ae181e3e6abc445a83c62a7a34583456ab154d0b2abda71936d21ce3ca6b344b7871a81c7c71bd7ab061754f36a8fcde19570554a974028971a3125dfaa5db565cd7719dc3c5b259d1a811dba28cb83d344b687bd878c111f323082c87cb7a396c34d8e2613b4fd6060e1b2f3796090f2bba34901cf25324c80f2137384790c07a2889e1e1831557807e04f9010403e2e142175552dd16635d276d78c4f49034f2864804830fa0dcffd16d9ccc71bd9aa55fc0d249906149eece85b4d08dfad260a31a943e70ef1e72f7ded13a49f5fdd436a359c2f853eb411aed57346a744bf40250184836aec6f0a033e28a6cd06bf0d9edd7e125bc73ef66e806d71cf57c34d87fbd77ed5ea4d5d60d5f1be98ec6c566511207896788376cd886384f6933959ecbf203bd3c4d9d81d7f2b8c71c230bf7d07eebece779d693527ad6fbe6799e77ee0b676c0dddf02c8b7cb8bdf33e9abbedd3b66bdb69839a77db2cdbfb1e0e376c716c508b59d34e3ba44376972be64d8cdb03c73498fd93c2ed87f127025523ba1fe2533bc46bef3c731ce5c4167ba459ea61eaadbd17853aaa491399a4c12a711aacb7b3451e69547d9548ecb5a87b14f81588caac1ca27245e57aed8b1905ae583c3eb9c678882d98a9aa625ca9a4c1fa0ccb9d06eb27852ba7ac4d38ddc88356e220f105e20df3d3621c110a793ee4f2f4a1691c71a50c37bcf9d6e89621ded2eebdf7765d4a323379a770c3e8130407bda49138b4bc41d2c8badddd6dfae28692c607874facf206f99b53cd4906f2071d0653b001142d450a72761a5996652846e415dc20d3537a148b434343938216b5414f2fcd810e4c34410c5d48c10bc400a345a3c8947699524a293d856e509397b36cc615395469400e6da091c525648f61b42267437c51051429a8428f0a8030040539fb8a358427677f3122673d446021672f856e64b11e1c81232160082264fa1bba416f2290f4a8c8e189460e67e44c256736e42c873472868224c09cdda2a0276747d9e4ec6f96cca6670814e4ec2356a6032a9a082253c0135114ba9145a146a60f152144cf8c9cdd339249968e4e11c418999e531142103b310959258a205240809cdd460186abc5584d105a90f5d414c139ab91b32ccbb2b39aa53ebac45c4f2917997edacc467616bdb3e50718b2e8c1177e983831452b83226755d080660753f8020c9d24b4b22539ab020956e4ec349a45cb599665d96807379663de71b133bc78b4f79e5033ac56356dc990aa0448f361013da19e68925920b23062064dd505828b18f445391114041a9bae77b64414bc40664dd3b4d3207c11842733d35059eb398112596341ab5efba34bcc5a56c49156c53c8125485a1573682f0a8922f754837278df1141bd44aa3dab59560f20834bca91878b2105f0220603d0c2f572e4e12227c9ed72e4e12249017eae8c1c79b8904245836b73e4e1a209aa2cae28471e2ea4001ee16639f270d185ca095c7ca1251f01345531d397f6420a99e6d873040ec5e962086eec0102498e3d401891b721c71e1300753c59a2c0f86329cd33356dfd992ad9627dfac90a77d0a499a40b00f1939f34283f693a30834c1f76900ea52a903a48faf8045dc004364b08a50f95ed65593f6995fcfc3a2805d75adad59fd962ab882af92b9c3801284b2a04fdcc96d8720214647de28a9ca1226d00c1556356835658a10609e5809a856679ee8ba0661965f90ea743d22df2c80f67827086d70a2f69b4a60f92d84e93243f4e0421cb276450b384bd24cb870d463d92e5659d42969776489697960a4b45db6021b5f0e9427ee15333443eb1ca611fe138eb0364e346e39721cd626f6c911b7b636fec8dbdb145ec8dcdb13b56490ee993e5b9d08dc638ea14341acda6fefc6ca11b5d8f344bcda93b35a7e6d49c9cd9125b3b4a787c6aac8769433726860123ba00e0e7a626cf7469b2836c6caa1a871588c70d9ed9626353257fdb07757d5041d9e736e1b13e1ccd7dae3f3eb21e4e9ef8110426a483105d3c10ad903d309338c2c429ba45a6817e92a6c11a9a2136f2ed4474f1403d9039c693ec236e91a9cf159ee4e863852d72687d7cb6f8c9d6a759a2cf15ac681612901b7d8c009467c8910a3168b20c51a04f9329f6000dede08189533be489c31c62f6c147dc22630fc42d1a89db3c3434b9af10db014dde22d74f1291370dde1829522409ce9128c0901b89f5c9c9d9d949d248942cf16162254f83f230e878bea027490c1189e14e2a633c2af5f80331e4e9cdeed460ac8127db49170d368bc4a913d56205c6624e6c036e0f4d1557b493a8ea8709c832f718bd85c9823c51d060c8bd0a23f7971869b01f672a82368c1134ca7d181905d0184e40d9438382ecc51772a53396819a259c4672374b7711841c71c88a0fc137d8a780912e3418b97b8cdcd12587987f40c5157a525c918fb345c3332da94d19144a1c197b8a6e1cc24dbdb6db6f384efba55ef6da2dd6709099e7e35313ebe85686230eedad8844c99e55d65a7b061157625a637615bb553a5bc64e947a79adec342f917934935996c52aaa2a204a7e5bc7d1d99ce4a2260a81c82f9c91e3b3500e5e68c38d2cdbb8f285b44a9c5c6bf5116333c680c46b73688e0be53033e56e846883f15d77e3dab822bfd0bb9103cd368a3a11271289449b4824125991481365a24a4553d42229baa1b6654207e4071d6e9e77d103c921e6781e628b5ef2f85e1f8c18b7c7c3f80324440b1720413daae2251039595681849decb595fdf0ad842c71b89a715483a89924c6a03b73fc0cdda89a0dba33b4430fc9d95f6237118c394630d59d7b97b7cf005914c5851bc626303dccb709721afc4f13458a18094216326d5ae9875570c3991cbb71634ce9aa473a6822884c7118794ec793a2c65092572231dce77005529ce77972b4aa51524ca49208273b59d2c7fd7a5493dddaa4cf5e633f7ae314c52e92f6793fd39ad9b5bf320dc3742e86d98f0edb9e5d510e8943db68cfaea3bde257f6118689bceedc76ab3d7b66394fdbba5006d469419f3c49e10923908c138acd913ba3fbd347bafd52dda62fd5da97ea6c33b99ab89ac8202020a01e69f1ea2d5a8cdb0f59150810d00fb3abcdbad61ad2b9571d2ac35dfb0764ee7b9cd231bafd0eeeda65745edab9cbd88f2ea3f3e2aee154cb8c6e71aa239008e20f21d16566ae08398434811c01a55ca6d2f6d7e8dbeb372ed53cc4d6a8d5de0f201a6e0cd6de8b42fd2048234392439b5d9f382f456688916232625e4cdadc948e3a9df4a13ce513ddfb42efbe7bee1b75cacb6c9145705c1966ad563a622cc678d0e18a2b73ce3963766b310f40329c6aaef4d36b4c4739c5a9c62e6edbba14ae54ea300ce5a6c34e2f95bafba5fa5d37a58d597d712a7b37c2a90c7bdfb68bbe947d77d1435f4a4777d15316efe82e4aedf01ebaf7d04cce707fb40c10a098a67c3af528dd63cb7b6c99be542d7da98a5d35f735a353981e427e4423576c47644457935db6b86e12ebdee91bef26f49d6cdf7491c6e99c50ece726d6a46f6c6868fa2674d15fba6f668ba88814e130fe28d13e9acf4b17d1377dd32de822fa265e30ff00a4def8a1e254db7881f911a45b9a8633591c25695347afe17eba992dd2364e1ee10d631a2c5bd97723d8ef5354f58c1b0dbbb6bee924ba88d73c681cb412d987fb4b7bf387c3b099968c4d9574d2431a049aaf466822cd32b3226da459ea90fbc596bc29822377244f8e92fbc956119c9c1d253cd927fbaa0d5da4735a49fb344eef74ac6fa66aaebc99ac4b4328994699151de5d34a1fe9a65166b78cc7498c931f4052020102fac1b4b5e8f735da4975db4aa34fd1b7bf441bd660573412e1687d709234362938397207f5d99f3eed29a3934a753b95eeddecb9d7681fdd6ddb4efabc3d75ff6a3761d8e81a9631c9a4bc64b5cba0dc3ebc2b199d17eaf73232ce7df4c9a07e9ff2c1745e28144ee9189d7baabffdde6ff81e86721998fb08cbe8bc4cdf2e83f2d139946f9fe9a3efd6c3d88f0ea37dbbbd8ed1ada69d3e9dfa6ef4d2b7d2a8f4eda4a75edb49df768c4678c7f6d14730edf7b1451a7da5ed2361ea1a5121d2a6484e698676e7822eaa507ab984d2f7982d324e23bd07572cd4c75dc6d73de543f9fd4cb75faa6ea72f551f4a652f7d4b94528a83524a51534529a594d24829a5946625d26b45a174ef122551fa55a9547abfd47587a19ca3b4eb3eee4b357e7ffb4c4bd3629a45667a1e37d248b7a4f8a08f4fa296b58bde94cefd553a87613a5dc2a97afcb2ef308c746b755cf7289f8c8ecc09a7babbe99321754f55d2b9a75ea47327e1780ea72ae621b62eaee941efd18be8b72e34a254f260a193fd05bd7c119a3c67509e4ea69db13c451867f4893e7724d752c293a74f9e9e2c325b66d054cdd9c4499e4524cedca1b8831a6806379c3bdbbc22a88a08d4134e27363c441e160fe6cedc993d789e3ca078eecc9daec1bd84b7c84ee835dc453b9ab5386c9a5463978753edfdb5ddc31b27c21268aa66ccf327679b2d5e1325b365eecc6edaed93adb933adbd77a7795a49fb28992df701dbc3f6699eed8bad0edd706defe6ce74622a993ff38a3c67153dd349c7162d21ea20a01db225c2b09956037dd3e666e27411ee9c4c9a25ec2e0228dfe91b9df4d7e824f0de843f55364e95bc992d323af332a48f2e53fabd7d0da574903efa8bf4d1c4afd22fbe53652f7bfec754d1897f78915e3a0fb1d50316838148b8f4b9a68a9ef48d7e1fc6d8c453c695b8321fa76af4f5177a5c0e1b4702149863e4d0b756a29d3ec66791a9768d6aef6f9f0f2dea6f13e1d40ea2cbe720c2b1c14dbe747fa16f5fe8338481b293af8b741291652ad14a9c14913c3eb14ce9c4892bf41d96390dd27358e2b492cdbbb36b1a4c20bbbbbbbbbbbbbbbbbb5b7677db8bea6f49109bab17128936d971b6a6e6f6a5e67cd7ddc3b0d0bbc33ce9356d7920b0d57bf7852ee2ecf62d13e14f76dc66cb4099306bad5ad4773f0d6e91ab3671e85e8e07d4a9cce0662fd246fa488ce6c5f5b1cae10766c255eede5de6ccda7de2d05ed4bb87e04d7409e52ac5edbcc3f4a13bfbf61cb2778dc3794e6a9f30dfbcac974344962e2282f5b58b7c98d9625bf5ffc47d1357ea43f76e441209e170fbdcae3d9cf7f09d1f6afbdceec3fca9c13aab7d2825f76aad943951552f71c87da806ebbb5a67d7dd13964570779106ebb57ac366a23613b9be999038f4ebb970c32ec2a2d22c757ece39a7176b6863c53ef44e280a1ac11f4184fc90427e48ef2fed7a892ef337c796ee947b188f9029f707704b8cce7d36b6157af7d508c16a856e635ba38732485ba0f7d116987d555f57347c61dc9adac18633d9e2983f32dcdac9195b52d1129ee8a1bf44384e5508a7ec438fadd7a74afb08a76ce83b460f61191d9911aeb161b5ba0b615bdc778444b8665e08dbea1e5b1e76bd7c39aae85b3542dc568c090863121610862203c25845a6bfb305e647e2e6a1b75fa4d69334190aee0bee15fd35bae8f222d14f18069b91f2a5d24f1806bb33a4df4b895ff7270c83cdd819aead10dd4dd3f8c1c34402cd1a1bdc340dd2110eae8ca3340b77da9d5e2a992d293ccdc2a45942a740d1a5e485c8f2d2a01514658a61d1448b08441095f2c596e94727c5ad398c403274e3be93e2663f82d450c4ed3cc369787dd83499c62f9a88c211b01006115f006ad1d3f0499b4f0060dc27cd92d96878862f5632dc50dad8d4e98cd3194e25ce8c2fa5fda92fa5e11f5ea9cf380fb13503c32e4e3db66678f8149ef1451a3ec3e50c34c8af741a3e199fe1433d86487fe9b8a21df5c9f8a44dabe869fb1c9146a8cffd2493d0279334d8207d0acae8933c9fb459c2f45367c212d0b27c04a81722486f634ec99ccc268925d08659ab06c15879f566d4dd4d273fa7cc892bf311cb9d06230f8e1fd927cbf679992371f0e28a892d8748225922f9b6772a49dcbef797e80244e6eef3f9cbd9261a8d46229168f4eddaa7e592c9f4fb1da5d26fe932285f4afef4d8227d2989533a4847f98efb139639fd1e05cbe8bc4ef85e86f4d8eab24fcbda2512890359d3aaf921448ca08efcf8ec072b7d2fae982fb644210dcb1c9b371ddc0a06d7b605940830b8f9b1a146534a299594de076aada596524a297e5981ac06a72b8c44c861244296407f3ed62c210ba6074ae99663cf12262cb511e7ce6740e858a64db46850cb6d93a495f4cee5473b3f3932269bcc16dba26f9be8a265fa1e22b2c03448b7e89698a9a27247f2cc16ee07faa2696a32c5400fc9b49443885e8a6bf397d2d1ede84ec23542bca5935d473bf7fbd40eeef7dc2fae21fdbef4e9a476e8db374ee9307bc2589283344e499be812caf47208a594def9d5a01bf64e2b992da553d3e99ba777327d67fa52db675aa52fb5e11f5ea59bce436c99300cc433ad9055c23a1d82a6aff4d100c38d2daed59deb1b7a243649a64b32bdc1992dd6de4b7f3fd27782d11830cdd243440cf490fb23b5904d1aa4177d92678786505bb48a9e760dcd939f2f32a5b28b4cfbd3b2b599f4c556e672b0b971dbc4151ddc8a5d158cdb8f65ddc5baa8427ff821c8cdf24066196872109bb3937e1fca941ea477c1348823bad8d3eb105950f4acc8928a200522c7a0adfb81c082e0e689551ae4bed1bd4f14fa40d64f4d5cee5c7d78999abfd3fb8bbbf7790fc374267e79bf1816a7273bcf4fcb327423a523f4d15f211ca76a845f9faaec33845753458f23aed07bdfa78abefb5834a54304b79eabe1a6f1a776bdc110c4f0931590e310ba004556a7bc46e965f6507ec391f6a53c8739eece7338dc3ecbc50064798e468a71acb8707978f4f07129b970c3f81379785cba1379e4b51c7ba0c8228777053702653f6861cd29d2826cf1405bf52f1d2324bac8cf8b20f6704d5304371408892b93155d4279561c2382084ed7d67329ae5fccb985161db1d08105686a9db3d67a591bcc76b3a19da15b35cb74e9af441c62bc2114b78883a4efc6e100b27c78036a0000c061cdf2214aeeb8d26f2d6e189b8820e24043ded0ef5f20b6b060a20b6509c30b510b395221776c61916608bfdc8f724e29e7074a1c06106f90af3400904359664ef89899899cac3bf372f6f8653bcc07913ae8e2bbb3ac3d309bc956cd128a38ac5bc5f2f7e44597ea925db6962d146e189b6020ba3421cbb3a6aa87980b441c5e30d1a5de47f2842c1044e6791f335319ca81c6184331c31ffdece7810dc6b366cbed97c4a1c61be2258f96e3c3d8042666d0c5568d7c8c57e9d67b6096090b2cbfb3de5213216ffb96e60909db431ac9939ab860e931a3138a438778c3fcc42c23b05e592fb86174d2835a7befa39356d95a71443de8bad8639ece5833ed2079c64fd3deefb2ac434a2badd92773d5c1cbd9bbfe428d6adaa95671d75f988591ce9a793674233e76ee7e16c3997bebf8b067e7b066cba4b392529a6913d3ec21a594ee44eb7516636a06a81c1f67a593d619638b26a594dad43cdb2c61bc8c93ce39e7ec8e0b5aa0546a418a49062d68215a21597e5a1a032dcc89238ef25352e9a493bdd560c5799b25c6497134d88f361a6c1afd15adda0fae0d2058b38cc2e0aa3cd3ea0ceaa4d32c3dddebd9d922a3aa3e461a7d5e5ec6b85e965846907a1bb789626b53cc0210714111d900446e28c71e17d428e17239f6204186fc9ba172d68344177296654560308a9ba98aa018ee28c71e247e4023dc9b630f1231247cae82044e0ebfaa2790544a2ae795d3e6d974d22a86541837a4d9569b9d5a39a2b2fa7431c618230ebf1c278d94ce397bce49bb637777ce6194360a3244dd21ae7cc7d67ec0dcb4717ee243b905503f8632a8e7082472d8345dd3437213c91da3a1a109a29b8432890872b408430c2ab0410f6243c8a1f4d9410e654c62d1319913ebe8a40540c8a28e4f72d7cc9c808830960862084bc08101931cca224608914389238fe48eabd9e24310648083253b4fb65085560b213721db196b42104f8c410b1e317e5a3d45ee5f9cece54682152a4600c1003f99126122532264c8f43674838239461c0c90b96ba11b5c4619b182fce5ed59e8c6c6534365468352e786a8972b9ab42afeb42a66ea04045a5d11c4a26955cc4ab069d56c41a1622d6092eded9b25a4ff28fd8cdb90e2db9843546e154185ac69a7a59f9c653c4520e9236ed8b19f1690868606081e1a1a3b5bfae7e7a68b4c234f27a42e58790576e1ca10e544e264c9495114f6ca1863dd682127e0450d4ce0042a827002103d4e94411453f8a6894c4f8375a2072567286591e98d0d5880844c8f0adda07726891b90a10c487821451450340f144540913296b08230327d4a8480154f38a2022504f2618cc1586b2d8ceb158b7fb960228d1a8df1f33dc4263e31c618e3a682ac09b3091fa8481423dcb630ae9cc748f923251631461a638cf81469157725c4adb13d7b26d1c959653fac92892b1fb1684a29a594524a69a59452dab19e2554fc4049cc162bd151634716d4fd4e344b89c32c561da02eaaa88c9260439e3f9805716b27133058b58cb3e7258e9f0ae8c5157a0a647f5149bce8327f85ae4f01f0b933f245e9e0cab7066ed7168951d4663c7d7170e5e365164839f6576badb931ea92727833496679f9cc8594e76d6c91a48c73e5a3ca6c25745165e200274f7ff28bbbcad6de3b43301603820f9cb83b477cea1463c874708489c9cf33450bace8eea69466b5577727c623d6c3478cbe6009cd6685c4b559ce9d314615f4102aa707c6cda1bd3f3589631aeca15dbb0f7d1e0dcec693ca39e59453ce4b1cf6889973db68f3e83135ec9a314d9afcc4f468c2c34793263051a820df0cd44595f06e3d37dec881916e8903144f1cb9993f11078e1c4bf29c3c730a2249b6b879d6501a2bf21444bac8da125411f2c431ada5d1e012f6abd962f1276d7b848a1f1b6a4829aba4524ada5236c1d3b35b543ac618e3a3c4df887059f3190d54661744e4f4e2662339311be4a9a494524a29b5d6524b29a594ca15488f70795e6ce0c841a9b53725c79e2558b841ac0875b670349e4e94c3a756d5c7305cfad076f40341672b23cfa3c41b503d327dd5e8274a5c49a963a044707e86700399be5a8066fb6dc3a7b8321fa2783ee4792e8227587e11661553d639e794724e29a7aca11b92ce1ccdd2b3e79c731291854b26aba856c898f4913e32267d60af4019963e71a51e003cb8dbedb577f64bedc09c2af53a890a52b841196a603ae11236b265bfa38629705a4038a086a755821aa6c069592c839aaa6aa7aad630058e9d42078253e5801a9e96c51f0d2f50997d5631a2a422d8cf6c1ad44595b0d264da302b1aa48ff93448e792e812338d5d6be9ec209a0eea201a1e164b071949b89904b61dce9b36d3264ecec4f521d833dbac26b38c7e4183324c812850a6ef9d69edbdf3872aa1c8d4c79b3eddf4e927dd12c21d9b35dd90da759ef499dc073355f4351c71a1d8bcf8dae17ed238b62a9c357348a6dd1de4136b42df1d343b1ac213e7389c4428928963278e3671b28933a5c8f491dad4bad32db932ff40e9251d22aae88bc834894b95c8f41587a84c73ba90e589a94d5ca19f5c1177d263267786120a9c4c3f71664b131155f447e4c4c0064ada2674a3876472c68c8a26964bdac6da7b51a89634422a8de905b4b9276eaf4212e85ca3cf3d71b5980b26ba94327d0f99e6ba7c0d5fdc17fbe1c81eb7e87dc3dd8e6e7b5703127706ad794c00bd10b6c686d5daf01755f442d8d60d2b35e4edadc4a79095b8c6d6c5c5f71e0d43bd6733e4a641b06d6e6ca88fe842730fd17ac81c92da214b452a71673645245132809be8c283835c95c835895cdb87c329b9e18dc3323aafd0b9cb78dfbe830b9df3bc875216bf369cb2dfb8879e7a710f9debcec9fa1a90b832f4e1a896082f727df7b54d6f32c8620964a3c4460229b119722381b61c1b4cd5b7cd270c44a14cf631f10a64693736077da4bb69cfee96565861450e591a62d20994859f5a4317eeaa4392c644972fd3f7882e2497d9b6e3fadb2605e9690d5f5c170ee2dae7a05fb1bacf292ffa4ccb1b8930ec7e34d36a199dd7fde832a48b2e733fa29d6374993f19882afa3801c0832b3ae9323342291da48bbee37ea44374d277884ec2309d1dd20a3be0e2062fa0a16991f09daa968e9c4662cb0be11da593b08c8e8ce8252c33ba5f6c75a21cd1a553de67b28747df2a4774e94c65e69eb85a5c999d3d9c23aed05beef3eea98b9b61f0ab22973ff50b72460e929d9c06737696d41c6a9454a0c9a1a4024dd67a882e33d3675996512a8f9044642a83c840f33386259206692c94e1304621d37758823c710f394d7bd29eb427fd86855bf151e04fd735721a046bf491adfa4e466a73844597104e7419407499b9be91ecc0a20bcd0258c2cd00b073654ed114c52eeedeeb87705fe37c9d33557513e3f60d8e146e289db48d932adae64b7243e9244ea18323b9737de7c4313861840b4b2801c517805a7d443a914e52605c0d770e1ec2adb48b066be3cc961cefa1eff01ec232ddb94e86bb875316df06e736c5d5b004c2d24983f5b80877c2d480c455d5fa6ef694dd54442986c595fa9211892ab5b6760521503124f4840655e8a20a08be0630dc50f2f0742f3ca28b448991690c43a6d18b4c1faf90e9398d4a9ed992b2b4ebcedd5afce2be61d8760ea7ec630bc6bdc3298b6d8b6e53dc8aa5120de322dc50eeb4f66672b51c2fb9d76aaa68c6e4d21c99dc28a5ec2ad2308fb8428f852b314824d2189dc2912194083231b129c1e0081f538e3d4b96a084114422a571efbdac958bd2d31a4b9ac8deb54a744055634224887e712bada75bf670db28addfb66b1bddb62daae86128add46a543bd55e1aa477f9c034cb8b521bcd224fa190020d6f96415759d1a55b624b8cac0b4417fa18558dbae25611df80d8e29aaa992cfbae596bad36f6d859638d353eca1669f871657ef20702ab42f0f9810abaa88223bacc56b7b8af1475b839f440a6b2d5511129ae4452a68d6f5cb93adc4c7f587b5936bae5029dbcaa32ca31267b8e115d648e4d5c54c84c0306c61583b9f75e18d72be67ac1b85e30ac55ccd535ba67ffd8c8227ee479d8c82e71ccd7a3c196f23c7ac4f9f81ecd127177ecd851bb7da77d3d627834d83c9a45daf77b584dc6f0e8d119c681590df6bf9706adb0c28a1cdd3de2974c91c3db3fb8a1cd194d271f35d20580501271ac001d820c60a045567d2ceadd034518446826788191eeeeeeeea63dbb9b3261c2c4a7079f263e384a39f62c319243544f7592592a8c484204303ca9f72ddd979d861abac171b53ed380c9cebd725cf6ec3e7030cdc2d5d75aeb39bc7d309febd560cd7e3badeb05f39cadb8706bbc6aed898248ceea911bdaf823457df7f282ef6db63be77d355a555970fbe14aae7498fdfe61766d2c2348bfaa24c8fd4af30441e719a748fb4bd355c7d16870fb3e55f516b5c44b532f6eb8ca3514325373ca6ccaf53d82748ba8de064eaebd53a35922cf929c5cebcf92277218bb90118b5c3fe9aa59263dcdec8c08223c8944c8f133a24bccf2973474a3b69438e8434dd3341ccda2e16e1c0dea109365966326571b3824061b6c9ea661a359ba098d1e2880624ddc7e54e95ad34515ce4991b8420fd420ed2f32d56692a964ee34487170399ce812caa3df67f473e77ead440060dc89a495a4e44b13091039464ae2cb934a1876b19d2aedb0119e69350e9be7c6fb911d7d8461a393704ccd9e58f2ccb42c0ebdfd3b676862dbc9eef9d9fbd15ff7a36b3a0a86dd9b1ae5a37b6bdff7afd1efe8250c5b8d7034dda27c2f5dfa8bf41289849a2aad278cf4128e5355fae88dbae0fb46dbb8e38a761957343b5517a859681660ec9b21779374644b2b99aaedfd2e64e38624301f7ae82fed63d5d1c073650ed10fc19138589c9e1e239de6cd39499ff6d117e7d612ef207d8465644aa35f1c5bb195ea1da4df7b1930dbefb8279d84654cf8e2b7ec6db9433bb774424316985802354849a49209e5f6d36442e9e429e5744af9c5d7963eba45f9bd2d7df457e9238cf28b47275de6a67c32a593a8a4ac1775414c95a2190120002000c314002020100c870362f18040226b931f14000d83aa4e6e4c1ac9d32888614e216308318400000001181111d2b40920ba942a8cbde81c14c3fdea0a82824b6abf724bd5fff5abba7e36cd081f42841a3e8d589954911c46deff43d4a417d352a5d0bf67278edc51fbabef31ae69679b2f1dd7c53718eb4ee3afb8976666a8e4a974971f14e7bfdf38fbde0ca8c6dc55ec5d42fa48ad8d2ecca73c5f6996e2f723d936103f66e275c9145969712f4612c0b4531b223d07758f54d2fe9d5b254d19c99c68c975561f8a97eb15c2e93bec2a5bbd2d9fac9874f4cbf027ae16f95b9dc32c4f565a0d2dde3ea347a88ea53a6e693af227ab8074de3b2db55046dc750c71d88229e79b6ba4ccb7bf918896d0459cd1e659e21344a9c2c948c1f580b88168fd34359736516b624f824f43d4cbceaa5157c429c9d4203232548654acd9f60cf4d5077d4f4e1249fd985da0b1dca5d7b1915f5fb94fc274ae5616a5b25e6d5170303271e1b05d68bf326a82f8d260bbf471cbaf7a35e9025707ca0043f5fb7ab67a840b8b3263ecc7a7ddcd4ca2c30387d8b46b73f237b8df39c7a7e7683cff2cbcbb2193eee4b46756a84d1c2b465119c01182ea14d3cd3412a64fa67c286e7f82c3ef05221cea799a616fb80a57c5270400df974dea340696b8046bfadbb678cce68e7c8d00faa8552057e02b5fb713560ae861610cf83d2e4e6bf81943810214c7fd0402c44a772326ea421f35d8bb1800341d473566097ecf7143f5b041522aba2f3f8bca1d41f35ad19a653f799877d78ea3a01b13047cb28f6a8a34ecaed45ef33d6bf160c45298e1c6ce52a533d086fe5afa71844882ac39f71a41367c99d302a77f10f59b4bd36df93aa7b2d1552dbc1232add751559116803536225b4b0a121dba218946e5136d0e835a344bf0ba5a7ce6e16d03068bdb3a852a69785b99a7949d32f24b00937601115dbf53e1e5f7a7287eae0f4532a0d76323d926d91bfc7010afc08de1a571209d26f999481337e3352418b104402042636689f359abcf1d93235f48d5872853dc3f7f3ad2bd331c7cdc15c9d26996c706b6d20785c8e81f1f91cf58df09529a6e46d78a0955eed735b51fd8ddbb65e6aae25de354b86647473697135a38ab943b7235353d654ecb64608e63cb11a83e88a9c62b920735e21b7831b5c2f39f289cfded3b3d641d8e781679335c8a9079e768c77461e814e3e0021cc9f25738c7225091cf68dcb2006da4adb010fc4f8c0546d0e76c93b1b3224ecc30c4ff942c4781139cc82ff2293312b3bf47f2aefc7eae52618ec3c09fc1d3df7203bc0c850d1039b68cbddcea7fb8c622d6b9d9c07aab8a1e94e21dbda163626c5317278f0f06ca4ba80220e22ca74839e36d422158da641399e40921df24305e7e82ed435c376bb999e24e1260d285b6a889a0d7228a209187a20001d53b9d38256b37eb7b20a24fc8d251f69ccb4dcf071ea9432bf5f31467bf588e446c442d0a3fcac9456c150de2f062ac465c443a4b26f569e763cc131502652ff50963634a3b7297ed7edca438a27f163d318a37d428c664bf4e2f501236ec7c18c1d4c97aae59be2c689146c1d4d0d90e5552f8216bc9e2b6de2c813ad9c1b7fc487a7c1bc86c4d279e2870207f616f06022e5fd97eca0a0f0c05f5271b51f3d21e15cfb147bb692a72ed7acd5988deeda8b571b821aa63329dc7676b69b753e1e288a4263bd9221bbd1271b345f8a62c23ca5c946d31b0ac65ee7c057af86d8e3ae749202f030baa6ca2cb060cebcdb88593f0733d995bed518ad7b36225a57ae709c23847026329eceed3d0a0b680e29db470a3ac7ce5b80c0d368bc1a3993d949e9a83e1a4319b740b02e58ad6a0820ab7a017adb3d06d00c8ba74dc4ea33e52ebd244af9152de63303c1e2b38e0b66d317bf611b9fb039518c189f8db5f6a5502e2c9210746fba55065f4631a725041fed2511b0da29ec8373c15a5efa4bb7eba86802f5d5a1dc854bae79daf08254c837fc2b36db3ebe78d09d7950dfbe9a5405010ea4de4aa0807a1340e88284e10cb8d90a2f13935479c3f43df595b3440f2889b7f35d87b3356e3b162afe6b4927ec0ebe42392ec9fb999b4fcc2588912d430e4558d174f54bb361c4ff8ef4b163ec0e790f9dff1ed7c29cf8bc9e64f572ff7dd22eca03f609bab34fe18a4762c25593cd178674ea7b502874384956254f085b83fb3e2d7f7e318f08a01cf8b8c49f495ee913b6101418c659b00c640104ede37e2a3a4024733529d721d4003b5e5b786c29a7388450b3a641ac258ad9091b9bb5cff234c89b72c886b043c21cbddb5c6102d24264426ba7fbe73faf96e1dd2e69c50fcb430792c64a0e3ff061b0439e4c8a88794aaf6d299ee70f8fb3a79c779936d6fafa153a11be724991b0069a8fa52ecf46709a6c4435665917ec884383125606c7775c21a035430de4293ac57cbbda062ccfc23f546c2be6049383bd3f83964a411475d24fbd8c9e43a6712183b120f5009fb080eba7d0b0aa3ac2149a8229f3091a94a820c14219ed5f5914b32bf934fb7ac5f128218b94c128b2b691350239d536e907b74ac039f3f2e69dc721927668118607c1b68fc0ab47f85e79026b2ce30f14c29834ec3f14ce5fbe05d0f1e4e60c1d9a1ee42a79c41d659f2f24b0e1f82edfd56bbe680cacf94694a1760c3144333d55bc7f4d9529d5f8489e2350ef480b787f865293c5152fd9ef71c432a358a0829676949b0fbacc62b9b36f623f03ddffb1e3e91531ec8c128d54407a1e2b82880c465afa49d2fbf0fdf099a8b6807bb2f881ee22caa658f6ac1f1616f133d5ca35d2193abb8d4baac97bd1c4cfc3128866f8eafb35ca1ee82f2b005b8575bea9f27ec427885d50214f1fe6277d71b09b07130556a2cabf00ed30c9c20d0dd9fac0dd6696baf139e6c07ca531e1c8c6e1a3084b0e6e0d50ae7275a2e14140c8696734ef8fc243ed3bb27ec253e2366b99804ce1f90b094e00a5826500b1ec278068d9c5bc017c71c307331f2b332ecbea224bdaa14fa6357ab8b300d2dc81d97144029a9c1f87efd592fe367c51b3836c8ebc51fe6b8b85c123e6f92a9fd7f0dd62bcefe2b0f00a51c75250851df3e74ba4e678e5c49d88dacea588556380fce909cff8039b82d811e0585eeffc727834bd8b8dc6601573e8fbbfba51489b97f8a12d8fe4849761f6578df5ffb8cc4a5ec3a3cde9060385227f28411e8b282fb124558a600deed95789138c922928e4de8c03a82eff7fd4d05dc0501e400388efbd2b91920156622d7f214b60721ff5e1fd3f75e121ad75f76fef59fe249d860b505865d44e486c6114580aa86ab911ce832c155ddd186b5ba2279c00a40c89261e14c926b4490364d17d1559fdb6f79d73482d6b400d73fb05aa973a3fa096317964ade506c46db2aa910f91ae70267c83d62a701817aac49d2d8db3bab47cc7b6198bc75a327cfff3695f557dabd673448d45115a151138d2d23dc5a31788916aaf88f3ca1bfcfb1240e0c32ad0eb13dc1f5b6342a3090695c1a87c735bab6f26a0af94b57b5480d4c9b4e91935899a82c662457cf91a7616ff42d541ba3ea0d46724a4729dbe6f5a063af1fcd6708ca048152fdab2efc64e85f9c2f93054524e7a21a743ea9824712d23921a4a1302109b4783609a22ef39407ad727ce30a02ef619ce69d4886502ea8703104510f52d1d961f642d0212b0bc87d6833b8e34fb6f4cdd55aae01a63fa305fe141d7a6b20541e3054642392c0dea3984fb6f7b3a8deb36c1111eba7dfcddbee491bf7dcf1fb590aeab2716cd9993af260eabdf21e3323295a34bf5f9583f6ad63030ccc6e32a2025c429ae047640390374f01822fa23c72ce5a9dfbe386498e706069f4895cc518b49f9069d39b2587875200bdbc830372e4003d57ac6448bab4402224bce39b1d2268de6cfa0e1bef3232dcc66810fa447280227ba8c81694e1b55a060295b66735bec3b69929d90e8d51db54bfaf4008ea06e5f7eec487dcadd53cb657495bff8dbe03d74bad404af68385497799faba6eb2207b6a943a63b3f03c68c80f3275bc1a0bd332ad79416df200bbce6ec7c8551de0ba6939d0f932a171ce482f1de0fb926b94ef5685febe1610cc3edb4aff83805153de8ea2e9f9e5e332a9967feddbc29c5a00e17b75b7d59b2a6d53c249730a749b6540c870f18388f102b085e44bdb44889c2d956a70360395465bd0e34b40ab5c009f2896278258f705fd28c2f2596a79c10de9d6657336b44f658b390e4e4149bb3682dddd2b2fb48dab1750726bbe1a059bc60c0831589ac33f750ad1beca08f5cfcf0a407dd8c09b28fdd3d9ec31fbd5ab1fc54978bcf9e6a857bd794c7bdbb3a4e9298d07ec1c855ad8030b0520d42df0ab770317a3235f78d1281622604401195becbee5143bada08130deea7f2301e3b6172d7a8715e223bcf31645b27e0e558e5e5ebe610ec4a8b73ee667fba15728dd0e2234009a7ff9e6b96579a3d04fc84dbb5a277181fb379315dd0dd7d820afeb4cc69668a8690d493f3a54604f06fcb73e0dafa07befe56198d76bc7e67d47da62698b0f3b1047386e110e2b5d84da07ce4930f25bcd6ec27fb98c2c7e52f5a4e3922fcd05587c3fcf4649449b8fea7cd947df28f9da4f6506fafd229008bdcb101ff1ad4e0493eff08cf720dceb6852e5d40827881130e003c2ad9e54f15794eabae60b5a7d29075d40c7e9c264d7c5c426b00719a1ac3369c1fa29f1c89d192e1304542709ebfd8a15e724912936aa3cbb48ade181c70ae8b4635c3d604a9686e8432bfe909f6365c1ba7ca85fd3c424f9ccd91556dac0a137022b57cbd5615a189f8c4ac403204bbd61ddc4fe568aa1b24eee6676d8e1a50c4e4d3aed42f21d0b0aa73a806cfd3561657979d4c335be15f0579ef847107b0562dc126b454e39443267a441722ac106583e7e06dfbf9704290b659e9e11ec901f31b00dfaf26e5edec1341ee2bb3260a1872ae7b471307bb97c112be0bafc848de2b7e7860d62e517b6f7516b2c5f26493d6f7cc9f2de67c93e44214cb72c04d46277184c4fa5a31bce681153484768618cd68e147553953517ba55c0ea5867a4088e2d480d31ae67c9b6a3c6d6bc9e21a32c85d89a9d4733ec97e5390942daec9e6d357b2609a6c58f20a76b7e0040ca48d0bc2fcea5132e9ece05fbe4669e275c5cdc02de7398513c79190f3ea0d16410e7bec85e7b055beeec354deb090617b64c72f4075e5ce16e590b599ad61cd043b603f9085be0d6af7d586e7359016dfcf26e5e18abfc99b32e4915346d9b76309d25ee98f7da743adce963b25b7eabf7f976cbd9d1af9f2f46a287c8cb79ec0ea37861a60838c00d2ec566bccd4e812f0842d4db134ed77359df06959eceac428239e854052fdd86d14941c71bb9adc208551f39e3329769104e0c8eb24742735b828c2e2247d8d6453ebb881ae45ca8887521833b545886039302b9ac39ebae366307a4d9d9d3f4f40276d073282e3c51e5f510da1cfdeb6ceb0f45bdb38a64320810a8efd61e0527d6290adceecbd775d47ea2b8f51cf6d06b68516b2dc305f11b656f6c3b6d8da64d4c7741a2a6c056cb64713abf8bdccb655be03cf8292f271ec0e8a468391b4dbf66d975a8005c418b8a56bca370a448b59aa1b37294616ca10c59fc130d7187520dc90a6b6864d2b7432d4ac0e3a7c87853c8dacb90c9630d7c2272fa499214ba803da96f7aba412410cca108698f74e0b2513748833427eca73a3e79ca3c54c6451611367efabcdd872406d8d3b28abbd91ab70c0ce1542f4464e957a59993dbeb2518961ee07201170b1049a010c407c01d9643bc42948e676f14b6271a416e05cb140832cd7601a2906a16876605ddbf5228a00b78efaab6662889966d902bfa16467ca55db9c9dcbbf43fcf4ed74d7bad523288f494f1c3dab4e2422c0ac4fbfc7e7d8cfaed6f97981546c5171023e460c447414c1bb1fe1807374da41f78d4240c54885655ce55fd4429484da394f1f7949b0239512fd02c2ba92398bc4d7eefdd94fdcd14532eec727be4e5c7bad11381c7c2544a7d9b67a5826f11b1e4776aae6eb636c2d0bf32ea995bdfb803ffd8a7a565e23587cd66c3986ae179f6b129399f286aad7e4ce26efce8532c01e85850ad58f609eb6370a7dce18b8018c85824f37e545b95df1b7e04638c11546c006ba5c904212833b48c0caac3a21e367370cc100df488d20e221d1c071e06c16c28682b7a877475b6e123dba7c4420809d3747b653928c2fbb55a8614be89a5aec4e20b36b0430939971975ba923d92c54a8fe760f14b5d9e78f6141234b6507fa84b06c87f47c7939de2dfcbe6f910c3d056fa4977b51eee5781c4c536ab4af17fd623b417e3be4c567f18c29353d42534ab4a460b55be0bb5eb85295b16697499d165de1d5f3e402d51563c83a3e25503ecc45343253ef75d71f358bdae4fc65dbd7397c8937530371b34c803d3ce74b464840b595b84ca08671a610281fe8c1b3db9ff89387926d21acaea6967ca3174cadae1dd6585dfb606ab396b2827e0a57195524ff9a1326d427964a27fa8d3dbfbff44e550fac481ee644e1d89552af309c9efe2cf841d2126fee500d5802f22b60411c899e14b0ff836ccb85429ca8a2050d4d623e691184941ee4afa9e29ef8b865110d6861c4e2f305d9a8351979f4ebbbe759ee0cc9bb1637a78285897fd321ecb937ef08cac77666e5caaab72e2355b11416ae100b304799f5d416e59066edc0b833c01a3410c1b9f04959a1b62e320316a9268d7f1774a215ff21b62ef2896b8353335a32903abd275760197aaba2c6d8918d24424eb0f492315abf235c01b1a29a8b713d121f9f32e0d48a952c2882191fd836e085cceac673cad2f847ff40292e3c12f2764d29c4b2931f2c2b489abacd2b32aff72b1b0c58d242fff95c88cc99bd122d147f6d6a270403c0d8569dfe492478fb051fdfd5564286104b78c1c9155c048000d26276925961efdd6b8feae919f1a5de380f474007b4f9149ebe8bb5e229e4fea7ca54e11efda06d5ae5b930406e0d8a94c16bed42ce73e6d217c6bb5fda479247be06b8fabec7b99954952feab89ca34eccc4a3039c527955fd78f12c85f3069a7758287c57c27a9651e4304e07e4acafc3f6b56152fb7f5d0484656d3c378f5ab38346e70735de0461db6ed4d491f9af1699a0cf3dcf6aafbc3b7a77a053433abc351a6af39d59fcba3aea431b19d7571ea22dfb11c71321ace3b8c37fe23c874766ff44a4320a75d54130d80ec7621df0219b8a8d3e116f5e1d0e85a38f0a84c15dd40af3ed4796a5291dcdf7b012b89c528a348a06b5f9db31b4e18d345f36ded3be82a879744cce0847b0e13fba15c013ae892f0ee8c7c6840c1a5ac7318de809d9c2ea43f2e3a5136e8858f82bafc7b14ad066120226191be7ea480658ed5103c85d3224b110359236e647d5163f2e2f9603a6851bd367e395c84b4898196faabf63eebf1e4314493bd14f09eee37c4f42b4b86de4afae186f5b5d75fa5941dcb0ed5afd66c7f4070ab0b4585632d3c0e8de767d1865ea03bf397cd50e4fe0d7e0203a00b656f2003d3f6f591ec2ea1c6ac7542a567e39c366ef52ae892915081e360014adf7a594227c8f4bb03c4371343f4e24ec34bc23ec80cf1e7db1534186dbada216d7b9cce945e87614222eca43e0e33304c05939e44f5754e7ede6ad2f6268fc142619351163e7b34778a5c7807ead0695d07113e7a11c176a94021c3ed9d0cef3e4b274ae293aed5d9d3e9cfc45e35f5dd2d4b4ae761229b05f8c81db99330c207131b319a13d527980cbc82cb0704fc465ea75f02c4cf9bcb9c320a9721e27a4e9c333133737412cf8af2b3692334d3c4a0fa6b0d6eec86f69c1f88582c6d7645c9cbec53a8a47658ec3e1de06c9cf5fa67e4031e6db6895b6ae9315f67339fa290511850ffdf64f1dd5ed66c08cfd53fecfda9b66c7b49d9fa242a835a9da124ac62891871c1fa5be35e0ad9eb2b27ce3cd42e767ed91e4486bba2ce72df8c112bdd0b79b3562ee5f531d0f01a97f64238ea8b28f054fe4f37b6ae859f56d17acea721d3b7eac6f3d7a85f2e8930bf1856b8ac75cde72eadbed59d53f717cb8cb54c56589f60c995801e94391fc4724e35f0551e3b301f17e40584ee415819b3b7fc12d92f3429c3b54079acc852647a023279c2d036a6e29d480618a9df651e150166a137efcc2e309c3f72b8bb590cad436477909f0b8b0d94b9e6c7e1d682d248d67403c55ce1ca82ce8207b626e4ba6d737a16c7612a61e93984dd6c28a46f281fb34122bcb7c248ae39207674ae287a1f79387df61395cb6679443e482493926bf10290ff5666ae014d6b82b6bf139ddd89a9e34460640b3caf0b70485f4d37ab6ab6362429ad0c8658b76b900602ae8ccad4bfa3582bc323ae946d1b75e44d88ca86d0e5f637a6150882ae0f6aae405ea12d6df77ac663e28ab6e63ac9d3b8082c951d2f83df4550f2e645d4892498c52a3dc023f4bbc5500a3dd810a382966ea97d0697cb4fbb338a4f0b078f367ba4938059f5ed83a54f39788bb8404c35309bb49943d730237444bcd1467f268d8c83c6356bd751820ee3c9c576d3e538d5a87d63e0fa4d35ec0ecc6c08976f9c768e593d7229d4f3e4670f7063698fd873ed5712c0bbc2fcb87a08c432d3523798cf0119d51270496dd5e2fe3e56132962dee12d2c2f3c8f41f8fb29fc13975fe24ac35d696fc52bde035f4134584a005936c80a4102fb56d517fbca6b689da0b0cbe0652848599c0737597fbae03741fb0bd756fd40ae849d8c15ebbdb1adcfce40091323cd7f0a2d06f0fcba69a35c0db345b3170d6d03b7cccaec060b39402f8ee244c649b2523db53c25b6b4ce6512e08d2dec88ec22b203a2901ce5f433f6748b6aff81085733a1174ec4a3c55219f0962c00d8dca47fb4953f768e0a7b45f2147cbb8fd0871a2f180d82af43d00b3cb0b88fd63ec21e89e1e2221d69c7bf8a01cac477750127a4d4e99ad4c9bb999ef51e493b8c8e39c305fa0b86284dcf6c1e714c40330316d555eddba7674a83d2bbc8762a22f69d4ae2ff64381a2fe68a6a2e07871d4f27a9df04aff1ee0ba714262ccd301c7c3e4f18ec3e05a0f9d49c0bf6bb287fc7611aaacda61533305e7b488d4e03701f8d26632847e523797198d2ee4c8c8865cf1876e9b2bcfc1cdfbe6271a231922616a2aaf372894f6f30d28b065e3274f89faf3e02a24b0a541f3d5995d509511d0eba57da48e857f40882b2a65683b1a48d59bcd823f34094b754365c2db67dee8857b277a206a21f42de6ed2c55fd11ffd8d665114c780d8b7de7e685dc7f6fb36b05db99afb5fb745d74984524677c6babd41bc08b1228a2288dbc19af134abd271d76de955e0c5f4aee350a12487ed1013310a72ae9bc44af61a650d1a8b3f006044ae90930423b0b45a9d669502b90bdb098f9b4ecc5c8622e7429a0dbcef72b0cf84c865a8e938138af67523985787f0ab9b97da16f9cc888beafe8823e0a02b8b200756d81ee15adeabfc0eab9e6a3180a6f7c7bb1dacc65de75bd082d13b1b5fd055c487c6f1bc423ece879ee7f87348cecb87b6a8513032635bd29017deb751c9e08582117b880f6c355db47ad76de14a141da2bb894063cadd5c70520ba0015b286f61eabed0d88ded949251b40a1a23b151a1877329e86cdbdb1310936f05cb4550e069192a93af62573c4b708ab221d94210b874e5825bd6b2c52e78e8644773420f3759c654ba1e5d258ade0963191b5a1dd2a1ddaca4669666deb77496021ed3a14f0ac93b0c7babdc59789ae8a7280149a8d38d1ff581fa38b94c16ee8654ca1b6507a9a2b8b0bbb06b58d49e109e2d9019766926667e3fb0c2c2a41e783f7e9eff953e86750555e0d24aec890e9951583924fe18987eb161cdb84b13161c8d41caadf7e0bd6f64ee815053ccc00bc967c84584fcdbe49890a747cb647d014d48deeaa024afde198581960957923c48d94b32e93af7f9eecf7c635c68c2742cec1c880f20207dde5f8ad586e55d6f0987ee5b2519fe8cef1379f8dce8b39a42e38889f7e1e4c6aa3066b780d7ef584c3fba1b54cb268ac10ea5db8aaf13f1ee2136dd87325541233fbee10f25b3d1515bfbf8ce2e3c66bb0867ff1ae219f8805caad54b0a3191ed46f7e61d18020c3c9d8f475d077e188218459fd796c46b7598899898b03a0464140a2154bb93cea55f60d6d6742781cb0494b0954483360abf280d7460b52d3fe84d95b60ac9ed9b977cd6b65cc9cfbe7b08dbfe3af58c2e8d8b847271e0bc4542c1989982a0a22f5453e0852eb76d6eb362ffe82e709133431e846acb9184fb4f44918fe97389528384c01f81eefc1a1fb7157b3b864a2007111d5fb554a6d0ff87097af4ccca2db136b7e23f79d6aaad245ff998800442ab84a424ba24ff38599655418db7c07da9376e5a474a9c7d81668f8acdbe6e17c3f49035e01954d57538a98ad3667d2b332916cedefb47e5202d76441e6acdef3c748ad0fcc267698327f32b8331bf3234590be98077ff14537119c4f2dcc7f64c25f2f76bb187dbcba8e5a227b4f41d43a56b6449279adeca752e449362c7d0818fd99a4baa620e7e057426b15b43daf1832c4219959dbc6534b6667d13312c8ab12d38f7f5ea7f8b69498eb8abaf8a716db958eb8706451414f956e505758890ccc4bcdb44e3ae04d1d2a21603c53367a9e6eb009d4171bba4779cba21816fe0ce2c371dbb09f018c59ca15813e0a04119475bab3c1f0d3ca79884a1ba3d8f264367db973ca699a26bba920aeffb8c98d4acd309a8eafc04f52a4f5d4ce1adda7e0dc7d89e759e2ff479463e34a5676f56f796f6ad4e5ee454660dd642cfb5a874d4886a402ce029744bcefe5f81bedb06b1dd5b1f63d6da35bf22636efe884ae42582bf46baf6e0592385a31c853d564e89ab538bc12ed56fceb7dfb3e037b93d70ae7c315edab48a9c561ccd9dc91955660d371eef1548c88cdb8acb9fbe5ddc4cf7e4f461c335e0f8a3e8f2bfa8e3ce1227b17cbb943fec9e811eb3be16b4bb442d3cacf352dc9feb05c0ee0b3f044dca5477f3994cd25088209bf36fdd82424d8d695d0c5a722aee9ecf28c352958b2882a901e93c4c10ca49e7973e17f96fd56b99efa37dc15a2f45ced1cd63b972b18c1f1d7a7fb6dbe4e483b91a6d842d8e141f3bba1277310b41acee62472f184d24aa2e6423a3943c05e408a20231099174373c763e690950b0ea6e31075d414818c4536aca58f98f5ebebe3488b4a1ffd1e023ea9df786666643d2a4b729f0060eb53886182a9f03435cd75f318c2549a79366761dddd71ddc21d5ff01aec0c9a33d4fb649f99759a393764df9c3db4119e8d73b53dac303a8ffa3f92936ca1f4abf8d0629837090a863d85775d3d4e26e99dcf03cca4c9cf32c9d98154e391b6c5ce72f28e912181ee7fda8046181f69caa360506644df207ee55e8a17223bcdb3719518dcbee8796a0a5ca43003a757a841e88563cd4b72eec2c62f2b081a60213e25b810ea0fcea7dad26861dd7ed56c98767fb7b5a5a6aee612b843a9930bfe15bbf25b6c2aecb170361c67faf22a5066ac01b1c4c9f416b13f4a1081604bd2054f9e46363b67866577d0c621046f7188ce6397ac60844e8d8a818ef1fa09e851958bb252381b84afc7f382fbfb9d7c857fcd79fc8acfaa2f78f88ce3899e0cf7146b5011880d1a1946103572b4eb3092ecc77c4d744d03229a4be0599007439da4ef36fc69c5f59b229a46e13c616064829997155caf03bb0fc07dcefba8477adce1d668edabd14a708fa5a496950148901429609dbafafe7d6ee9432376415a9d4ccdeb11446da6a17bfc3015c6c449a0c9a371fbcb7b24c9d75757ffdfca3f0c043d91124c776ec3b5083ff0cf93448ac917acd9ebb2bf44aa4f5d78b138c50cea407ea53887ba4c162dee9ad00aa1e7ae861a8219aedcade0f05b14374f8d12cc7562a4058c2620308902948dfe6099b0d6ab962ca116d6d97668413fe562fd1a6308ac0f25e8034d8366781757775c88417709273b14e5775f4aaae8d7592b848a2eea62cfbfba52884742dff83cb50b1ce52b31c2896077430c9b3e633e9784b6876e32d065276df0451a1d32c0cc6fbd87e75b93049d37e6caa0fc6ca82250742229863dc0c0dd58ea17249bd06bf7856b3e28d0f5959e9dfd0de7552a892821c1e9cebd1b54aae2bd5adcc79d6937997a086f2ac7e8d1491a27ecfa0e6bddf443b797689d04d576469934cd21fc9f80e65b1c8100fbf423a0a1ddf908dd24ff14bf8f05b9fc8506e4b8a90be677da9560c2afc83de491cc4b97f94403abac0f0a194fe64be626019bf8426dca240383b6b8b7f8ee2d330d5efad6939ccd898bd0d0d8e0142389737439d98512164a7c1a6882194e72292abb10cb6590c0ca258fc4eb274ea4e3c342bf379927aa4477b962f150394ea6832831c8fccf69a5d8a0b32128e18a4344f1551cb06d2950222ba23b1c8c89655dddab670f4846308349cb9c0232deec73a8f44e26fe46f03eb45e5818b704bc967528a9e3620ab508089ca2b9588d23a9b664742892c6927e758dc1223fd388b65fae4fb55b416935de3d050b654918b8e9f78d91b49b994a69c179e1a2d80789b4e1a70843111a8d3bb7350fcba57d154838bbc1dea4f9159001b5bdc71f35a629f69448d2650fa0032919423aa1ca27b606a6fb4256346dbd0a60e3384f5bc9e1f177a4205e8be892ca8f6919246029471131f4efa04f69f26a3d23a3ca07a57a993acda25b63457e1254400a61d9e4e5cdfc13199bc835bd22a848d6fe05801ae7b8fa8a10b30bb7d9c8e4cb583e8aa5ae4830c9f14b933354dee709f909c1df1c744e6124d06a7708e5b1dee475f0a2c06719bdddbc88e4e43b50733fb956e4033bddba17c3c2b66047f32f304e54f56db386d4a0d10e52f93b8440a164719928625ef4a683e9666a56b0320717c0f9f14fb5edf9fce986b23cff84a2aee5271ce5f9798bafa4fe6f6c7e7812711692e83363c017b946c0f91d6f8be40eacf2fb827bae3d54d6d4f9387b8e92f3f82a1392b25f22f64174a19e14149a533725048908b6292200567ed9fe2010c1a7ea3347727ee569d472d03e260065991e26af101c251ba23a7d7480643295fb203d5b7a3b3e6e25af36a9c47ad7b9c38498e771dcfcf31574b8390c9191075abab3f89d01bd559effae6fd0c75e488cfc6379b8bb0dd3be1f5374c87758c011ab5b0313a0b34a32375b190eaea9760f336c664952e07beabfc838b9b8a81a5c420bc1d2856a83b67e6ec93c1b6258aaeca26b04145cf218cefd7b613aa83e3b9cdeee9fb3f1f228bbd6ae65f874212705c407752a0b1d740caae552627de4ea66e87360a180e31827b7c9fb0835d9c7ab168706ff865dfc7e1deb6e85d1a544baf53944d11fa0f6cf35c6355e202dbcecc76c52f3d188a43db6cc9dd73a4f8469a824b196f62124d32370f5a85ea45c14abfd037b752383cb7c5ce4725f42251b4ddcef8b6ad07e5449de1e58cb0fe500f6251ca865ad36c08340110ece19144bab4cece6964cfe2cc3bd1d29d1f193260ce92e734034630f2a35dc34103de3a7dd0e8b8c03d6edd8dd277ab4a7785710528ba32afe6a9225ae4c188bc5ebd50634fba8cc59ea7aaf3c7d0d052325daa473d2871e2f3161fccc44876a1c79595f6a46366296ed1b0c1cc49bd5cab8e05f59855139b602dbb0e1825889b2315de3594e6883d720db5558ab61b58efb142ae4c35b26a14972fd034ce7a9c831207f2a17aafe4de3d0bd1dce621babaed2fc8e1f561660b9626a7902a80d0ea0867508c9c0236c2900dd38d595b3d1c5e5d787b3dd92a23edec5716aa1e56d28f1987b215ce02664fa6b212ac3c842ebb7c579b3881c61ebebced8a06acdacb30ccdaaeda6ea8dcf57cbeff0eaa54252f18709be6c46358d9656054aebb848c7cd1b53223f36e94a5262215b004176f6963f05102b736dde71a69ffc688758c0961515525228552c4f630ec468399d151891721bb00a3a1ab5a92fd29ba2f3f465784c904adae0b00190ca8b0ff5cf003e63c258a2dde978f139c25b7f591c064e854521d02336fa3ed5953f9e6b66795c1a3c58affa386f8e752d4d57b8b57a88a4bbd31a297bc82da93217c67f803278cc3b8c6618154445edadf6e512e79dddfd81383ccebeadbe3ecf42e7ad28a18880963254c9e661bff80a7c84f7d7c53aa7fe71afb3c5004ce2e37ce595e88c642599718affcbf64c904780f035931b5c98985693ff9c6403a2b10be6750e6eebc11867ea182f0134ab5bb5c79a5fb7f527750958cb0e08229b4377591d30f91d1a534ff23e87f5c2054c11a57ba12fa3c2b976c00c1346185f5ce14de8ae218266e45ddddf98344364f4f214178f6954bcee6855bd3296b610e0fb69c8bd219aad27987fa31879e4743006e5e0f92d6bd15cf2f4b95fa0d8b7218ab21647b0bb1c0b83fd16ef26d9148d389bb09c5963cf9c9d4f6f539d827fa269cbe81c815c4f0752eb32d86352ba3e3e0427b78244d1e360c5504f830394b40948ccc8686a6578759b6991a4df92984876467262e6636642cd55877420344bc6569715e12071e692a7cb22711d90feb500f83d3df3f1c32f2183ef4fae32de6e8afdcef1facf6bbd531703d0a2a8838a503aabeb506bbf9fb87e2836082e1c9c55b0e5c082c0005b62a7778580858ac9d4d82171888b2c605d24b137281cc4556faf70d786dcbd9ecb11836b15e5fd7ea078399ddbeea4c4394fce1c704fde18a3588ba080cec67ea2bc3312cacb2a500d60b8e54ef07e95b3ef689ededb284e8c9c30b587443c77a1628cb3340ca7796768fafdd32442bc2b182d8c30fa54967c312894179aeb37e6002bf92f76af8adf5c12a0a43a7b419a178ca582d4e7190fa735411f01b8246ddc10d866916bee3dc55b59e58facc2713350bdeec614c937012efd402a99c5ca83b1c801d879c456ec4ae621d58c01d65680e52329ad87700789000a5c802ec7734bd7048b6b03fa009bc98e4a7eb2c34d3bd5b811042424680f5bc6c257cc32726f24995f53cd1ff4c746631f090e60892fa7b9e7d1f0d683121e2fa89b09d8594974064b33d11a9ea517200b2d570355eeb9a39f8cae722f970053879cba5ffb90c551e72adaebbdd15fefdfa0f3cf4e04ef9b67f9fab96bfb5d72d6cbf196fa98f1ee1e878ffa145c9bc4aa3e411954494aff8b80bdd7049fb3c814ec70dbdb414c34db693d6f5787592a0f1ebf7c1b89bfcb3fff936d7d7cc07326a52a57206c33ab8571101a11ce9245a6196e1e5f922edd50a3ad03b8e36fcc21667453c4399b0f4ee39f15550985c911cce8d26cf7ab1b815e7216a8e96b8a812462207f8a51e9a54923138a0ac220bd00bb11ef91e1e79f53ac8a70783e7a6998680e36000d002d53ba97fd51a09774f18d9a4220ce50c39fe527ae1024f2f285848ae29af638a1f5eb056305609f5e15cabd7b90f15442765684a010cfe570db9ba66de5ada9bdcc9456a3957bfb48d7f8051ab2234dcce2b8b01ae557c182a8e9500d4867951925f01016cd52046d8325f45add9128200fcd952cbc13230d6ef0563b0bdaafc71ae3c4f3f6e68d5b873f164fa1b479ae98428bb1e3cc034dc658b8ea4980e0fdf7adf91d61992d50a36597734fece06d591028ac47ccc25d7d988101e6b5cb656c34e362af5094e92c20e0d1f3c36dbe2f8cfa0a84372210ba20357e76f18e47e3e4006f1cfa400d087a61fcd2f101b11befeaafdb2994576a78f75839b6a69174175af485abc0e0a6dd81e12377ef180101d3f6d21c36eb58ba64c26f12a1d97c086ca5846a36eb3462bf35697fffc9bc1b97d0266f85c8118dc6594cf4ca82fb8405433583610c50642728ab66df25b1bb94c5efba828b7df6eeaec9530cc9ea33106e18a71790e0e4e531247379efde8299d39980e50a9176e18ce6aa82ff11b5c7f1694ea16294f737bcff2a0d9b4b26bd39db9d4961a32210e5321c667a95be90acac699a906accaf29ef36762e878789970f13fe6160db446ad1d868fc6857e68ee66d6d085b863ed18846e55e501a8aed72dcf5f08bb7ff70b48e50a144e7a037d214043015c69b0f18f16fdb7f9166dfb55a68480567cadb4fb21fe84559bf57e35285b43e3aeb1e5ac4feee183e701a834a55b0cd4b2f61eb9f37ca8a9e1efdc97921304be01b18e1d8a2d50f2c7978d090590f5c8ad4ace6b78b551e65cea365c8e352c5b4d6ae57c5a32e6eb632426b6e6cfb290198222b29705b4219c632e95124ea3d35f2925e45358733ba4ad75a7490ee8e77f8c623bdd3ba5a7c054e922fb8269e684ae154ecc668738bafe1a0188dd3beda462d254bccbb8187a9cc0af38f7b86ba2750b4a83b7a69da5a8316aec1db8a4f1fae550f37deea4ae9d47ece3f63fcb8abd655a94e4a13c3dcea1c662ff564e18662602ee74df9841be146c1c537454c28c53f4ccdac8c632c4991e8eacc8671782fec92f9b7d2495692f01880d715eeb4be0389c94533b93703818e330155076f9aa9be168007635b1f526d1ae5c92df354b5595c8f6bed3cde41ad916a3ee440ba1b65a93bae9994c4f8e601e079493963ee67061874ed5da40cdc0dad7247f68596979ab7105188584309ab480e699430b5a433b3c3013fbd4a1103ee8b570ddae0e9bc2f4567a94da0d98b2f182c944f3b919caf8c009fb15b91057713ee370272adcd8199de644ded7c908803c28b47eea19f486e21cf39d0576605ad7018612958263f1e672d044026f20eb1998ce3a4eb5704353e56b9b34b852dc948dc9bdbf1e8ea0a92a11c0e69c1ddfe16f39449f730681897cab56c9ac9b7d010005b1a93201adcdeb8a75390c6ff54b5bde37028332de40ec70694ce8fecd780f66c031cbfd4aa7c7d4383e5db1d2451baec921a76bbfceeaaee1530d7bec19525713c63f37a1b18df145dcbed6e981d600a6e1ec26b540e92601e841eb7114379313738f413fbade80b2f501f9bea60d12a43a045780cb4b373aa6d610e206ca386b99ec7fa1ab6681a9320bb86402d6456a8866ef352efd816affa080c327aeb164b11c3a51c467a5c78ee303787b0ac4ff528feec12ca3914f778d57b31d8a7eb2b8763d95fc40662d230d0b38b0e5054c775ff232cca8182b3896e6c8d1a2deb67ef93701b60768ab267073c7c89a070257ab1c771f9859c63414cb4f7b00371efde5d423028016cd0110c06e83069ccc4b26762deb14628080bf62b3700526069166038d95e9b1b1124775efc20bab823a52505ba008f3be66d99009d7730983766a9101f6ec5da1c69405036fe5de161db26d6ea785083ac9114148221fb14858b5f911a561296961b2fb232b0adc013b6802a2df0a766aa0524007f932a585782a54be574ef37a4db1095cce6be681302874a9fb8b1f992e2e0fe8ddbb4e84898cc168153e21d70f2bb2c8b9492782e169a753d9cb525e8d49a2500d34eb0a2e938ed7307563d48b321749501595da7af439ccf5861677e3b90632669029110ba5d59e2bb4b6f832425830e954a04d994421dc8a739c9878282fcdc5a928e20cfb8498b4687f921469938265809e04fd7ad21a0773a96e034b02f066edc0fd0afbd445f88487a72973d333ca5037a2d9f90c5eb0619616dc4c575d80569d9827e26a277d841586f9eef6394a325b5a9da5816b0690c558aa29a1331c55c38ec713216efbfb9322ff24cdc82e4d4034b3d65ea8c84efefbd3e5b116471a9920b77088a9d898fcb49cf8c4db764fbebb39b39d7b7b25b121d7ef7958930de12ab652153b0e893673c23b12b60c96f8a7c28d0ba6b5fccfa50594cfa6890e32988cf4ac0cd60480a57a84e4e25f21ac2eed7c9ed841fad933e2777f7f09a13bcf80988dae86dbe877d4e2e6d57c49d22625db425d9c44611310c5f46514c1a2c0f6b61ff1620410c05dcba6e427b9650d3baa8ab87e031f5a8cab39c1fde0be43302f8404f5571e5af37901145875c1d3fce05d7f777e1ef2f012850594b004888133fac7d0e4dff2b04711364bc49509c2f7e629b3a4f991497d542efa31b4eab2e0625f9d3272247e1c4030f9a19416fb5935622bcace9f200fbd6b7704e655e223135a99f78ff664764b0174a824c4ee3b0192c2768094d7c30fc2ed5f70cc6ab68fa1b493902d21cad675f0934c31e77b79fd45011bd0e6c6fa386f39f942d62ba5adfe773eb958318a52ba4c81e075e1411f7538ae17ad9d89d7f6875940226f6d00f823a9c58ef23480e25949414a5f090ccea2542db643f22c2560e906ce76684a618e231164ebace175f8b31e3bfed98153775b3a2004dc9314832d5ae47daf51ee6a813b073832949408cf1ad7cfcfc7f51cd2bd4bdd969751863183fe118995b7a268f35ce53443b6e12cfa4bc34c084e6d3e9215b6b51e477cf5248998da802478bb3192781efc22bfd2b2f85fb536a2e55e0295c094f92ae205a15bbf77e709b5a6b8157832c2d3e67669fb054c1f37c535fccfa7e409f4cd81fe8fabcf52ea3991ccc37016b661ff5bdd1d362ecb0d547a4351d567e1a839ca9e3c5bf27a9769528d86762e0358b7cb1b5a51115ea31c2afa086c93865c2410096e29f320b21f1c0887f25bcc50b320934fc9daf1d6589cfd66bc267f77d1128003c18b5c9ac345e883ac5ee11c5c41f543df29718dcda23807b1736fcaf2613003844b709a76c35d89173668af77459416981f036830aeef0eaeb1ca09d711bea22350f2a49db81dfe1b5a97886d6a15cb98190dbcbb877a3fdf629c30f16a6dbc2d674285f746fb1c2e4dc81f42b52f064ffb8a32da578d4ce9b76abef5a91947760496d1281804ab6f5bc079e19f02fc1ac63f76402f7a01beda48a08230a9dee6de6b8c8998cece6a4b3d3a37e880dedabe170153c9abc9541140cd00b9be5a0678cfbb72f268f145f265eaa781c34e8572b96327a64fe48d57827d492fa52f48907c0726062fd737640661d835221668cbcfd44c18b8debdf7c4efc016d4def3660e89921e037c27c7cb8c350741ccf2ac9b16c7ec14acc7e4b10d25ebd205d7728224187ea93867da359a8a6ad25d56a6e55c9b56c7b5ee3abe763d6b672725238c8c6037e8435fbcad8120f61617690bb2c454aed5e3c3a96f7d9c09342a3170040ba6e8d29021c70326cb3b8187e14c9aa1465b010a933724962ee485d4a46e1aa9d2d34d485827f3cfe37039050029d6d9625888806cdd36c0e1735c0ef6da4e709518ac074949a3c299b54168abce3198140d1de4d1bd92e48d59daa82abf6efe19c71cbc62f58b4efe1290d3e53381f0fe6915aa39492fad9e830408fabd9f25f0aceff1d41e9f51670e3cde28d1f89dcca8c1205df05b2e6c49ce41a81a9bd1907fb8fd2827f41952e5cb779f1401f3893b6a09bd0aebaab5b136590235e02f74f98fd49390757d8e55df118b7accaebeff5e707b4c2dc06e0cdf03d6444b63ddf3f2b7642e585774130b8433a322f989b485f6947a1e9f961a9dfe9fc3ef02228fa1586503d389ccf054d5c5c75c3bd96e065180487783ece3d78f79fd925ddda2c371ffa5fcce34c1e1462d54090d56ad53fc0090617983fc9778893d016ffdd7d809d440149b3447c6567ab62e4b43a90c784f4d42c777dff2554775e325d1c3100bfaa1bb997aaeae09f5c8ec8418345aed6d18de9855388c3fc992e3dc70ddebbf76cceb7fe39883301da39e36de59900d16d9db725f864746823bb16eb2820f1f6e4f39a3026e90d14a0f773fe6ff0ee3cfc8ba0884e0fed0e24c5a4f97c6d0e5ed7e07606e06aa4d5171cb43105dde426b9f227e69800a77f0797874bc401cf356cbfc83f8ff46cf1a38163d58199403ff40ab0177d994b63771332b0a7adf6674aa05b720dfe350fe87907ce62cfbe711c34b75a3e6eef46582058425ceb36c6e28e091e262054059cac5b54050ce32e8c3174db761ab30fc66972d95cd0d64961633405807e0d007556f5102dc2a49007832771b84cc8253c71bd62b07fea9e4772a7ec7aab58b23316faa9baac9a6f32395c986bd4398077f13cf5d2c0ddf0e6ebc469f46eeaf22f1e21714ecb417406a1b90192da3f1d4495c24cf6ffd5d101283b4649796ce7d5a802891d59ece54cebee724ea25adbb4f35512ba0d03570b1990b77c0578cd3364b7e51def8863d4268d1d6f3ec90d2bab2f557233d0d94e1a364474485c72e07cc9f90dd393aa587200c7680cb7e0011238712be6eddae7d5658a5f87a60432fcf767210978716a2283cb0220e5f9724a85107dbe64019e2763722dc8c6319909ccd96161512e216b137d044536ff5eca2434182c31c0662e620cc56752162d5b3fc894812f3b6eb862b4d7b8da5921f73e5d03dc8599526509cdbda1d6e8d80198018a5a91665a9d9fa7b3e841b769834d97d49932971db5659070201c4116ff76a0ee14eac2ca39ebd5baf84eebbf3cf8c2e3af8bad70d973f1067d12744c4b652ce27c2c1b80112115cdca62fff9e27de482a5ea08c6a63b633c514c73b3b52aaa47b1d79a65ede2f58f5b8cf5caea9070050d4159c71c0b9a4d6b552531ecedfec19e61b69ce0591ff82c6197f73478eb6b8fa7e62743169c92b5dbddd52c185029dfe5b558c7af6c7a919dd947c7492798112fd9772a62303014c62702ef28846a4279d129118662791a8ad1c157b9095dc022165cae6f190824e5841cab8c67a9ccbb432a5f18b8d2d3c89c57251bd22d4b62e4865c1d230c32b4b81b825fb074665699c8507af4c97bf4582ee10a1829b3994710b27e19cc96a1d4a8b8385e9b3b95b13694750eea4820d7917b322e6817dd048ef06d7bb21069cb5e5faae526cc71d9823d58635d49cc3221eb57db3aa779b5d38d94c87261048282fabe0afb000f5c53a3ffdd98b3eee06d37c8536e50fbb6b54f197a94bf8ea7ee7036feb187fbe2dfe1cd57637a54acb74ba3bf009e1bbe308a2041c61584b1644fa562000ee0320f33f50d34ed1900cecb47f91eb82a2ccfce0c8707651e422e913aea2ccee913e8ec318dd4aadfd9f687c8d27e61d30695ca6599c07f7b0a8c03d2f0f4859cb69d082462aac6634c59928942cbed1a5a18e439f5e9a3e8dda433d092d38f4a1e2dac01f36cb7cf9e0ef41b21cd4e9898557d15c1318a884a3090364245b86af30149a19866506f0d5e80d8f946142bd4930761b994c6fee386a891704809442f8b43fa770185123c9dddb3918e6c9ebfae5adfe866f66c0627553982f7cff6112636462ab2aba37c4f6ce5cc77e3570354785c2436e49d1d774ca2b9b8299805896a4a88390ad8d821e0c96f8efe651e4f7da2bab403a1c7fb3c74529390ad51ada3c59fa0b02bd22198a3ea84e291957a0554f22948ae7262f74fc312b1dbfe4363a32c04f7d126561e88d0806e2658c38e83d88ce9ce88bffefba70cad88c090f9ad9c9f5c7f933e80b69862dbf43bfc3f0c726eac154eb71e6a8db358a60670b5a310b6541c22c2d81dd250fea72f899a641570219215d52145c703d39008b6e5d31775ca33c57db4818a6909f69ec5ab55a5a6c680775d281c593cb21efc3dffd4a1b78519a893d259d525ee0a9c8e980c9d339c348dd0315746f14b1d2276e5b34c83c60be9ee5bc173c5a7ef69a5fc66a93482a6cbb45690d0ee970e577ca1998c614abb5f35711e00bcb9f90fc50e84b8e47cabad62526873921bf58b5f8bce088c99cc48a377114c0699796897242ffb2d7e2ff4e334cbc1330d3ae17b92e004a56c937c58a6a44b386bda191846ba8d140d2a09bf46f374987d330d8789607a353f5b84bf979db1fcf591174074e6fa06141bc046725d481b39c60ecd7d1a5cd9246f3485719911c2e8a8cc71ee9b7897ab385dc5836d28aa8de7da5b44a6b16545267a718db680765bde65630bb513be1fd796097da98d13ff347daf38a8e535035682b3c530fca9438f7596c07b04ca338132899c851a09b0f0b9cd22807fd9ad4188c16b68bf28ef36a1b1942d474886d7d87518e2bb7b8fa8cabf6ff95038f39e724b979a600f73526f0bcbc59155c609ab86f5e13a009ef1c201616d9f3dfd08816988631464ea60baa276b8f114a8b25d11aa70871de5928f7c6924e22bfd23f8a9330e5144f429573b65d72c21697a070924a2ba0c96fb84b83bc369809b41dea790ec0ce2205e695cdf5e74f53a268ca6d222b21b134638ff7bc1752482f8c47c3bc972d15be545b56601eaf81b55f0d0d3c1eb7aa26dcaf3831ed471bf02cd247df61dd4a6919688ff15bf80b1f16f4d017a30d7121fccbd875372f28d585797202fbbd9cf499ab0082c1dc4cb12303689fbfa89f73765943e4e9c8615c9ecfbcdcc0554a06fb192ae3bd403e834b1adfb0fbf1e06e4f8e921afe7fe707fd0ec9aa0150249c80dbeadd8c3b00e409f83501c10450830edcb9c578e443ed9a81130731c15e41cc04bb00d0c19e06d28f873915cee7b67fd4bf4f1e56fa0f53a127d00337bef1b0daad2867259ead6dc3926d096c053bbec653f99cfd89e433ef5332b0eab9cf96ec78f7e4b9284330729fc23464064200f9e6a9d1da6b487db3c210763d0b6d3bb3070ea95b5d2604946214aecab35051e2f8bf9262be2bb49125ba70a599fbc0377f029a79f32460dfb0df9ee305211a2b4d190a82130b26a0fdad7270e88a5b455d73dc8bce88e1c9f4f6e02a2d9a558a1631406d2db441b32c513dd7b2c3739be0d2d5ea4b5b4a460d3d90af5f9ec20337c7c2c784cb9fd796b1b4e2ad9615a258bd11ac8e92652188896e7799e57f7f249ec23233294b88c8151b5995739219ef0fa17eea76493ee56ddd7c5cd47ff779c361a83f2d1407c584a4c9b64193f61d14bae8bfdd45d151484fcbd61566cae7b8f1eb51e8c958e398fab2bfa08c2c8f8611bdc7466b23230bc2469be14d2c9aa20de768e4368a6ed3848867296d88a165b009de62a00a4f512c93ff57a70dde11ab1078a74b5115be11e43c39517a5ca141346654353c9094d0d4bf35ceb90f383776c47d57420a0721040966b6c1d62e0e997f7c2d3bab51e0be7549c17982bf84e6950901acbb71a44458ef48191c6a7bc6965f61624b48fcfe41ea4c1d54327cb34f7ac221d063b2e0b25520fb4db3523d39be5f20c85ee5a5d88c7da538110dd9fda0d0a62e2391945220732a02885e7b98d0a58009d00a3a723ffb9e5470aaf7e0ef1eb2012ad42522930da389e2b7b8bf6dd8dd44687c5a40585df8dced13e219fc298c74662d9714039092aa6c3e1642880c6f8d4d5243dd87be90fdcf3fbdd9bf5813124fcd7bf3dbcab63201e88d252c876ac5194b4f6d086296d5935ffcfc5cb99cb54b966906a39cc28695a1851906484b392c27b7d195917dabc9f5b3958969dc0cecb925d8f55639722da479ff0d2c232c87d3981ef17a9ab12cc8a61b04ae12edca7f2a48f363c9d18d6d5819b19ee19003bd2e87455418272156ad11ebe17492f9dfb1d3e128689c15a16844f473e628f61fabd0b88fadbdf124eea6dad220042b32e11d87c6a1d5787dc6761127566bdab8357ed1b4768f90d6611483161d22b4a8389186d6996f643496734388306ce548ec410c36c00198ff25ac2f229b9ed53a29581cc744e2e7d8d92490dd28360c14c93598baac073f86fa123f80c531a66e8affc021df8e749432c82839a3bd28122108a8442bebac3434c8a16512ab55955018555f867b7642b9db597894a75ab0000c81f2d1ba821a1a87a1b3ec952e4d2cb8286934537700c6a8603d545bd127f6cfd3e51b35422d0b2e2f007e9a55c284005ddc70d85b2f8df037d3c75406614e0e6a1c077ed9d8d5632779eb870c6ffea54f21ce636b58c94e3a5c437c7d6976d98b3cfa85bde04e2de1553ab7a214abf4ef299652a954418e423bb0da3b49a2d341cbd563cf535779fd9630e88c4de16c02a17d7c36ffe88c10f29c1558e764ba7925ef6c544493b7cdaa8c64c604378ba3a02986fd92a4acdd341a8c0c7bb3f1f7d9d9b7ee58154979b526944e9f7751faa3274230904d4011379cf228be33625d4cec99b9baef68f972fa9f3211a9576535938589bed476b56a5729cb1d9707d4cf43fd6ed0b4905db78439c4318620aec3353342d9203c745d171e85652ada68c2171b556c98ef3f8b0b54a9d2cc0e83c6e5c83ff7c4a6ff5ba22e18d42cddedce718e217d9a21d08d61bebd244b612990112b9fe9cdec3872d4be6d386a73ebb4db0ba5d9f7e21476f6e9ff929a608f52fc711a40d68bb7fae3b06a76718dc9836f5b2cf5a0eb86b529d33183692b028de22db2127c7201a1522de8f22716d09b6cbf1c49b72fb7bd212cc57280db71fc19b9d210a6aa08410440ef76b5f40f73fdf1b7abb41b532e84a03d65dc1c8fe63badb0f5227ab847eb58772ce7dc80bac4287e1e1f5677e908d91a035e5808e9c907eef7876ccde5de7987da71a8f81ae3402dbce411f4515d24fd23bf26d7005d4794ccb965ba56dd83c7cbdfee0cbda9ff7005a1c6ad912a44754dae1a1da6ac49bf288bb8f89c8e7df2d49d98e0c92a304bed8974b46f3b0846296b6dcdc1910f82adfe392decbeb5711772e9f89cd384dcb39c44a1ee077eac184bcb95133c273b7654fbc32ca2a19d783555687aa08388391ab83687ba635e7c8117a620d2658e203fdd06f835623bdc0a9d1f67ea1899e5ec8ffe6224d1db6b3fab67e1252a5ec256ce229ffd39d41259bad1d69a46ce425a005628427d395c0971d0711cc7443e23f3e34b53066a47ce124d8a70c7fd9bf5d61716309d63bfd3aff346054cd1ea73bf0eefa90a1b8cc407069946ddc5b35f7affb6a2bdaddd9792c056c9aba563027e1dccb3119e25f723815bc87de3cbcc770ccbc8ace611f10e47dbe7bad85a2a77b17249c3cafcdd1ddac81f09bb8f70aaf17cb8ca28a5c3a4ea836ed7153f86773a160bf24457ba03809a6469a292ae03a58981a8b1fd87c42431a23ca944501a3c8be85c339c32aae8344a51882a537362f392112efd0a0f62e1b89ce5abe7b08e50a1a3788f8f5dc9e27d7acefde45394b27f77cd22ffbcb26002665e29161b6a908a2801615842cff2491dc1c32a4319dcf622f9a438eee9a029eb80f8bf9e3507a5b7ea938d7cd82169964b6e7d08118982b1328c5316951d699ce2b967607a94df334ec8db489cde8f03f85c1953dae353bc7580d248af29958f941655da334a4135a24539e0e9b88bd898e944d0005640dfd4fe42691ac8b002d08bb1f63c602bf4fed452c190a7b00d93e16cbbe4d24eef721a64d3c84063a32a86539dde55e826264557fce17c04e130918369ab05f5efa631156d2c60f7469b5ccd7ac47dad4714a4524af2a9586f3908d7b2b8a6803f3d6fb58d5a25a412963ac1417ae9edbe25ae17a05e2debc7b470bbaa96e75c3a5966d9daecef89f8b201277a91b8f1467691344bb74a9292822fb6a2fb56be348509e9fc25c1cdd7a0397fd918aa89d6cdc1d51ce9ea0f12ea90cf71682ee34c3362e86d4438df91269162ec7afe9c55b9446a957c4c54a3ff475145d9a6b6888117db4e5eaef1386c221a36cef00c16a2f045b9975e15386033a40ef364c3a1e6c33b74e531ed4592de4a34a84388d2c3aa5a23ded91e4095e5c759960fcfd6f92aaa77372c47715a99b2c48d256de89b11c09c7b5fe2fa78ff22af4e45b99d2c964e4b11c5a37764aed5b30d611ca8c24441e99f960107b4dd07932c5a866d51a0e0cc1ea511541673c44bb94063254860f2679491490640f8c9fb0eb357dbc7ff6c4c2c0778f245018f4da9eb1ebd01ded5c649568e9c6711d811727595ccd4fe4aa0d30647f6796dca042f24746ee7bbe4b5d8d97893cf04944666375771f159ece94482db13f4715a4cf55369689a23c53e170e0bb06bdfd2ee15f9a89d5fc132ade3713db680b7fc368d4bc6b39f6e1f68e7aabd8882deea7461df0211c5426e8cf441e863fdb02e051f5f2f3a15ba7555ebe67b8fea237905bff2e1c2722a412b7c860c3317b6b882db62da647dcaf31a8838088e0c3c0bf4dc411d807e81401e72bf114dea5c1c6436a1a298f332be146f2fec813f1bb54c5707f06be8707c016c9c5a31013e10581bba3c5858750e91514464413e7e88f71a89c92b29b5ad9859b920d7921c85643e18b4f28a75b7060a7218eca89946b62daab95ec39468e071c3861bd773c5cc8b3b639fea3fa278d65a75b9693f2dc0aae433aa4758816d5be7c52e8f64facaa5e78a359e4e39da8ba28991ecf200a3eef2564310bd5b2cd0bea1978c5a89b1a8f5898c637afb718dded1d2f173809134cf29ee3875e5bfae417608fc2bd3dff223a854b9702f9aedc06302d0681c199142edf24eddd33505133192ea41115d8d5242f14791067755ccd10ec98b1b8c4090d4dc5d1ed2bf804ae8eccba4a2d6b4a1b017080e105656f642bf99a80f71d98b7612a1c337048da3d10769c12373ab3c3866560abe4dddd8a01ebc0f00bf670b36e232e160ed07f6a4794d1f717cc2e2daec2e579baf1eaab862be879a8c33f7b9aeced65941ebf2bfa66d2662585caa87724d639dc1a87662439131371e71259f6307ba194d70fab5f59190a0f057b301220076dcbd02320d558602f7698781f5a609ffc291d339618cdd6f1a69e4fb7eccfae65c7507d1b361d880b2982075b676f64d5f3cc909cf50f833a2ce390eadfaa0d41d7996848ebcfff4333d9cd080eb120ecb0df74f92347bbdddcfae579dc14eb05ec23fe354b5d0f09fe94beb6d672706319ef985e5693703c818356242601effec71d2f204746608c53a1ae490d4a2dcfde8ee032c99d7057d6f635b260e811fd882eb490cbc510f7e6ace0c08a1f8e38406963829bd55db708381155a81a52c2b2b4f67796144d965b2c8d38908aa8f0372c3d91e0559aa37365a669c661380d49c107eb60a4c81440c33ab19a71234d167f8a89dfbed148ec217ed97447ace156b4537e0d460728b5c280385c65d313be39baa27ce3f44a532fcd56577947b2edb9bb24c95b5932778e2a6647b2e9bb4df2267eb0ae8329ef9ff284191aef781769b9575becff7d51c5d028974b4c3981c4f4c7b0fc47614d2a99791868f6331046603f3a2588194fdbbfdd998f8049a565bedaf51df07d6892174d19b4876a3f5b1c4f7c5e414373a2ad9874351fdd092dbf8f6fca5c3c645942809a341e7c16c2ad354c759dd39a81faafd4cefa27aa40a914d3c4a5c0419d12e10e039e1166564e1dfd0d1c11991b2f7075c212b69e1b2b1287a387a133a7945213e6d503ce976a5aaa58ea3cc4b0445b24a2c145bfea82778d1ccd086baae94c9518df7e185e404fdeda70e3b0f2dc53b1928b977cd4d9dfb526cf374b9e4b34e740e4bc975f1ead44b2632e1875773861a996388d9566c8037d19943067691b9d7a429418d5387314e69454c91ae403f99d717c92eb0f78fba6228e61ae2e7d01caed2c9fe645013b56b9926db39f0c4fd6d067c8b3b9c9d0bf72e040195ff6b7d6b8bcb5b78b302017869b8690e2ca1a728c1e17d9d154ae12031f01129fd4e955090f31098d3a1655ba9b87b307a9c2c78af427e7196470eb453410ff9870e70669b60651a221166ba6299bb95571825247aaf92e028c1bb5ebd9915c5215c462c8f4b1dab28a95dde7cf2bd1f5f76a7447dc3fb6521dddb6e7b1bedfd76c53d2eb43eab18b23a4bf06d4503e84054e87e666ae0339f87d1fca555bcfe01459818e053bc99aaafef4d5df2810e8db206e31068459c31538142c9311042036c65e98090f331ed60b0bd4b77f30000ed4636610e83a2a664f2e3592c7144fa89ef3e78fecf4fd4072168168a2c5620a5c60119e48cd8393fded6962b22d5f9091f83626ab1a0d1e47aaf37cc3c647590ca6450844d460c4bd8bcad09294af2f527bf63d9c9457826755ffe4d1494839a39b7aadf80198fd179f99d2260bd213770a450a58b7f4ffabeecb6c0cdf066210570ea29d05b2905aa47413d512980a404195bc1ebcdcb6620b62b120142ba720cdd4c36ebb705bf42098a0afa6b4287782b38f514d22b5829ef4ecd30240311c795e886988048f34acc6009a2dd95a82aafed03326905af4abbd258a09f834a312e5366b35b7eeb502ae405a21b5f8b2e68c3a9e71a28e7c2699908de08a9385ed73ef65351af80faf37f78d8a2473742f6df73d2f508cc790c8c0d23539d37f74bfa2a0254fda72ffa2b3acfe4d2fb99ae727738066ddd0b6eeab8907d00fe444a38ac1e8bf63c67f93a9de4944a54deebc49952878bcccab035b0e4871cbc220a5d7dbdd2aff185a6bd5a118a345a29c6c9111bfd96833283b6839664153dc43646c2deca06755095c82098e30213c985dbc15dd1bb967370078c65577a50302ddea93917f2060be444967424c96f6bf3b2dfcd1002138439e400fe3d66dd0d38969df0f61cfea2fa041ac8aa7cf89b02bb63053c040cd416af653ba2e8b7b9271f0f56f0438a491614917de7208e63e4c926cf514fc97a7884602c348dc20d02d14cd5aac8ec0ce7fba996e2ac4a2dca2a347876f88a3706f6274e21a91ff43596fb4f088360d314b7054c25c127840c00a7338f00ea50f952ca8b5cc6c3619aff0278317a7700498a3053c764c0c85331585d36466ac76e78b7dfa88e42ba633ddd3f1491f84a0c2cc1a6d56f78dbf4bcd48c53b9e6234e32d29acce12f06f793634c236afe1f360c294c78feb8d548dacd6cb5f861ff590b7d8041037cf918c25c5687e0c2b69f30bfeebabd6b76024f11fd04855e36b2f5666de151b8b681cdf2d97088a20388f0aba54c08123bf6982b2ee4a300ffc1bf292f25a5007df8b73a5dc5dea2a3226fb400f91deee720601ab4c63df6dc4ecc54661b9a18c93fcdb0199bc410ee40192b9608f1000b3a986ace01e7823ba0027cc1544ab4a003650d12af1227d66db74c78934d7216f378a3d20711f15723fa7b4bee9a880a1fe5060282738b75afb5661f95cb7cb635f42386dd299b28b9706f6c08b0a10cacf71fe250bd90b246b430972b6cfd8a5727b62119ca3afa9918aa36424121fa1ea0638cd4e4c0200585c1023d5127e93cf585a05dc7d485fbbdef7b68d6911d0ed0f4ab6be285a842ddd051c4958d8d9d89d403560b3e78a2d7cc37d08aac26783f31e607dd375f4c552ac477809712073838d30f4e57b24e729d580b781294d763b25c7d3f55e34fb5ec46922d948d2d364951129ba75bbcdc8592a67fe1355a5a4b42707d14b938467a9d43c5fea7a2ae564c0467281a6e3ce255ab60f0b7eff7f7f24dc7b057f2f02fb5479dd954f90f15063d1b4db248429d627e8f234dc2df15d639592e550b3915c7d8ad4e9e7fdcd4d43480930c450dc942630f3238c2e7b176e912e10d7ba2c590be9da0367e4ce7ca02c63a23dc3e2aec3f6e437fcb0753447260a556f8409e24486b2fa72ded0c624b14b0c53313c40244942de5f76e89cc44f1cd62124f48d18c1a0da12d775e9c40beafc8a36770863c9a58952e03ed141240ba04e0dd4cf88b11507b9bf58bf4746bee50cf3792d1af80db365290f25837da91f429a3d064a195876158a32c6ede883a0e245951777c163106de1822c82f093abda3ce1b5fcf61a77972af3de3f7e2892ef55dd25d25f6ae7df6b01927187925ec17feeca6a64f00c64f1646e4d3b52cf75706bda87454d01115b5f67202741c19b5ea04a3c9ae94a999346ad0e90c74d519c4aa4acc6a4a58affa368c5b66afbde5a6b0f7c4fd1bfb24dbce0df84693c0260f22366cb1b2d2aa24036ac494717f296bd1f4b6ce8e75a0451910c3c3fa2a5e48ebf0e25cebfe2738a50b44f313e9486e6ae1e50cac3f20229fe1934a7005665dabffbc725140d13788984a5c12b0c8095a648699946bc37ad362d2ab79a84cf8d4bc0346227a52b40b2ef6e7f1047bd98022b88e71767e8eb8f61f70c81436bbe0a17abad222d0010c26f5b0f26d4b28a3feb1eb2a34af3ec491d63ff6a7da0aae0fd8ead6977fc02b61961cdecf001a6984e41fe7bc0b9a8ad24dc6f3789b8d3eeddd443de6bd3a12abf34ebc2ee7152cc298369f2720e10371929b3b5c38e9a6d7ea91aa4e14c00115beb87b0aa0464eee762d5eb474e77a11bc9a8fe1462cd018dc18060dc3bc8f0703178b3177ea984321610afab35cdba70e7539a8120460383d11889645987b070c481a35e713a2db71acca2e9d06046a41dc2fff6d4d9c916443b5b83b7d99fda4a3b0998c292787b65e8219da5edc0a63488a1c04c37e1ad4469a2821bb38dc9467f05b70ca3f26e640c9b14675042f5125c54b060c70b3f1264c61d0fd0479034796340290a7230060b9be7969c07dd2fd7c01dd33f8542c67665266e51f59946be712209e1e8bed1847982c4788a20839aeab4cf35ffea55e9eeeae1eed2fe8566c81063f3fc8179dfd25004a41e41e347012c2dfe66809d1d659bc6ed1e4a0977a229ad8ecf356105dc845c1211758837d55fbd9ccbf6f7de4cf0fa6e9423e2ee376b303dd4dca73b490eec3ec7fc1253f4fc898802d593edf976c9b38c5d1f9d37d0f7e6d5cdbac952664913596750ef5805413101401176be1fffa292bce4dfaa2261300a0041254eb1ff38a75645bd4c1ffd0446a281ff6f5b1bfe820ed69d32dd47f8cb6f81843801e0f2ff3b52c103dd60abbff87388133e294c9411fb777bbc9818e26e5b80eedc054c40282b280fca915e313c911aa5a0d8f0348ed7072d0147c898f2317b2490e16c0cdf0f3065c035724a19245de8926f3647db59850f32e8e29fed16aa27df418ae91f5c93911aa0205a29e9c70aea54db6c261a569a8864f1002e89db5bd07ddf76ab8c00c767d1218f40f3db05d211f027cdf7debaa0e731a95df72381ef094df45cb9ca0ad7a81ae600c2df4977fb722de929c7f0922f41298f1cf79d0ae17a3e46a6e16cedff9490356a5d211cf8dde32f949b649f493065afa31f1f34c325c425132d0b9baaa196b8302354527579ef2b759eade6745eacbbc11dc4219cd6f1a01b9f05f82952f8233485c9f57079107a80aeb11def45b06c5b0c46a3c7040677bc09de93c9c3b21be4877e02f90f01e77492f25260e3ee9764df120b830c48376c86d206b5c0b2a4b4311b845fe757b7522f500e92aa636b539c14c01fc2c20fc956ceff9b74fd087c3314dcf81ff8e24c06adf0ffc669634bac29c1cbc0d142588bc3f52de2881b6290ea00750ecb9b2a9e204d45102405fa58af25c02166482632df5cc525c751ac1873aeaf9cbe6893f494c999b4bc2c68837bafa865949bbdc3c445290f6ddfce018de6d9bc19ec01931b1c1bb918f34755fbbd61f4bbb089c60cf9b14b169ff0a077754b47a9c4945a12ba50830f3fae3d6fa0e199f5a77211a942351979eb19cd1b9d97ad5bd340873fc5c19e7a83028fefc6f571883490dfbf1bcc41e89c0b7a404ae77b6b2318c17813d9f0ff29b1b147d49cc7553646feac11a47bd2a20c59eaab4b730085f06c0e6d19fb26922f1ee1f05328d76c7e11f0aa90aad0f7aff603d92d3d5eb7b99ba39ccfad6ee3abc1f400c2d770b0af645bc652dc6666bb4f24b8c93400179e52862beb6a1254c97ce6e9de196adab02b623ddde97d3cc766173290cded705e1a8e81519cc19836b77bda6478edb5ea9fa41ef2ed53561d6a4bef3e62ef84f0ed339b1eb4c9a5677644b12824557b609541f6690976ec64d7456dc1d712ec6fe573990a63537742e586d07b7a6d5d6b7a4f2ce3db2328905014762c809bf622ccbe50ccda3742ad30c9c4c19895b5681e6f338b92895fdc217f2bc408dd02502f9027723ca9b8640abd22b39a4332240a7634d9048838e0c3f5c18acbd36f6f87e8cb9ecc7abbb8089366a7d5eb6c3d01a7842c4af95fd11fb3c48a793e2956b3042e8fe14bba5aebd16b71cce0d5d892645ab16ab19da271bf8b755d4938cdacac96e64da98c20e29cc4acfdf1b4f56851e2d80e1dd277e1fd57c86d05340b602fd52c8059e3e3d7e90b6ca7bb78087c0d1fefd90b1a17a4db4cf817b33eb1d507a83929f9099c169f67c27eb6d83b85f48da368c4ab28db4a76de41bd9967f55e0fba0a4c55aca8222a3b79b53a7cd58a462f6234c2d210c60a7adb9d69370a20993a7fd0e60f22c9a0c84f3c4b8404f8c09a47f412e9456f8babe3c636f2500f28d49dbd3abe8678d4dc2535af179d4d2dce797e0f26881cf05b0ed804922dcabef989484114dad59acd856edb10b41400c10dd2dae21503072d95f2615451580a6f8e3222dfb890d5dbe27e41b46ae2720546ce8947d2e6c8866e7467366def50ac1f37fad5169d263cff7773dbb35f8b563290a2229df50a8df80b2841ed830a81e21ffa07f2435b0652bb8c51a279e60816aed7bbfe5ea35ccc2450eb2b3fb5728bcfdd1e5357ceb26b597bf2b71872231a136e67c36845990d8a959035456032a63d67a5a30145ea503994e4191ec1e2aaa874b6a029bdd3c29cfe5f63c1694a45895bb0f30e2c0a823ea2fd6918ebd058120d24bf33f000cbd49fc7ab310afae7e6b5ab39dd9481695cc0a48eca57e98a0f6edf52dd99b6cb9a59429a51475077307a907d099497bfe9e821dec58885b34dc62a1199ec80765f70df91ece8dd6a03c839ce9b1ecb949cd63268ee59e7a64b0d670344ff31a0d3fe4c73e9e6080cffc5c19cb9e460334199c3a78bc1b2e2e48ba5946506f7a9e8b870e560de892cbb5e41a8ad262c245c9e55a720d452162b96a66686a6866a6ccb2168b8b926bc9e5e2e2ea2f5a0708a00ac46a535b6538fee632c3bda79cbb56eadad59ecfb44be9071757abd56ab55aadafbdfc9801c9e572b95c2e170de887f250ae191a578d2b860ba929caf52ecfb514d3329454f8ec0411bcd4f9f3b3e7e745aa5a8cf7776d32f33edd62209583542c757bc80191595c4e539d5b696e37a05c6568af3f08e7466b50f24d1c0886542ce34080d948e0b404850a25966035a1f90915d0da63da63271858d37e25d39540e6655e93e156503c009fbf04503c003f7b7982811f76363054e881cf3a205eb5af407bdc8f36f39b0e9ff619ae37ae57edf9db88423346d51b29f413126fc00ea73d98b781049d9376a8da62d29e3b92f6dc6d7ca19ee448edf9c6c4855a67be7f659329eb3efe2dcbba8f5ffbd3fbb8c6cd6721b1cec73205fc6ab5f2b195bb130cdb84e924242714a93dc76213047579c1d23bbcf26f2425cf5c9eda9a755f67a9ce318ca53a9defa9786ae79380fe01d37d3ca7ee536d1d4472ee6c0cd18f4e28b95df21d99b70983c6aea886a391e11ac991609ac6096d6ad9fe9d5aa0f72eef4e2dddddbddd0db7683c4c544a9807de2e2a3f90de591f13892641c15ee63faf2148a1f2cecc333fceea6cafbd6927c6f3f3f44ecd0e7d7ede1dcc621cdcee803755724de8d3224f758aa974915cd3a6c970fbe3dc3e5127e7dc1ed128e2e48473ab0326f3098d829af227a1981cd023e8e6dc52716e7150316ebec62fb3859e34de3c2d736e6ad9e6cc6cce6d13319e38b746158339f598266c621b746e8b284e14fac1189b7308f0817e53c6e6dc01686824cdd89c3300adc9e21c8faaf1807ed0b91d4ce6131a0545c5b3a27ad60a9585733d558bfbf313655e724d64ba7ec935a1dd760bdf66b3395700cac5cdc6a43b0b0f1695158fca4f41457902c40a6a1555b138bef8520c2eae2d6973903c65e5886873aee01d9cc4e2e8ef25f848edaf41829eb039b7332305cee9987840bf89c2e65c0b262c9cd3f14d709b7304a89333bd0c87c3ff40f1d7b83dc7b429e0f838c939f61a0aa71ed88d630ebbcdb91cb4051ff4e05df483ceb1508344bf89b339a7faa2699173386a70a0c2e6dc00ba702ea79ab81b4d687c6cbed0af860ad114ed6d4ce8dc0d19977302d887ada453fdcde449eda7e198885b2e88f66085cdb9154e3882b7611ce4362fb5f151eb508ca3f105dd0eded89cf3b024657171692fdd45fb80e68bc780e8077336e70240e96989016ccea98063730e00345a10aacd391c9a1816b0b03997c26f3feb51284a592cae88cce3f03f321d94cdd2a9fe66a22f9a2af58959fbfef321fc98d75638f598a9ceb5f445b562226e716cce97428dc7ada76ab8754a04b3be3d3ba8e5d89ceb564504d89ce3e83c42bfa96373ee6990b02465e1d8c5b192a7963cc553d47e966271d07cf1543f0be80423d06fb6b0615c13da563ad59f718c85e324cec22e14b8078ba3df3914aae909fda04d127636e74e989ee27678886c90406980f563a2130f28d6cdf6b4026cced9548c6b32f3936322a6d21e4fe954bf9c827eb06773ae46c5b826f425c7454c45a66322203467a3ba609a01415a0cef88d5c60bfa4158dd7fba37f48636e0d3de81f06f1847671f7be4c36fde617af89a16398f5c57ad6bafff97d307a8fd156e8e7f370f7ac375e56aeab9f188df577fe7c19bb3a71ed039ef2ab150e89c066dbc58c85b64b2621dbaf70ea0f70e189b9b717c9a9c01e5f7b8bed19b3bc640d3ba09cabfeecec528bb5bba43e85cba4008210c1146e8485d60eb7c44e0af167d1b07be38ba75f7d2254e8de30df30e3861cba97295ef70159beaeee391e1a43d825150e835bdc39b5466a1ca2716aa3470fd3889fd0ae5c5e124e88fb168dee1244ef5735d15eb6c7b9c456d156c75f38e95d1575e4c4a6b5037988c527a49baf0d07d0df04244514a5a355a609dc510c2a8292cbc1861e2c50701e4404f758bbcbc4005197891818cba455cbc1c89777777bd07e70fb5226887eae88bde689df87d80d8d92cff77361d4df1674ee8abb808b63f5175d152151c8a8a54b9010de20e2fb943fc886508b14b0e3b4001862b2a7191c312e10ae6840653d7284912499e4cd102830371050cf08570922cf0935c1159052076eece76842f00156adf50a576078ed73c6ac307e23562988cd371f8bf19a7c296b638951fd6f0135446a11d028f69b9bbbb3b33bbbb4b8feece746803407c77976e7436c18068d105b010e5e66616742bd5b12240bdf26cdbb62c7b53f7e33de53f99fb28636f7a1bf9304fe427eb6cf8f4dadb48e0f4da9f3a1b6c03b5fff43612e663303d8ca9c3ba184e359cba205ac79265475459fea8fd9a8f8f7f5201aa9a71369889b3c13a096c6f83fde989fc642f01eddf068b61c3be86adc3ba186a78223fa66f55e5eefb51650744556568cf67f061ee6ce4f3dbc8ce05acce24b074581d56c27afefdeeee1856dff9cbe6388ab23226d67fb9fbb19c0cfb31b4e72bc38f0fceda407bfbab045b315a051fcc48a23c3e1ac6cfc3a30b4cc6d051162e35c6960ef55bd7567494850918b78a8b1a8150e3df88b2fb9b257e7eac5facd84709b335a2f163e499b2e3a992072e9892648b4d0c7376447ef6b7bb522ca6ae51932c6a7758f74dfac3a2dff415c4000911484a29a5921d322600e580a48909905026a07062d54f7c71021efebf091640a8b6402285d0a2c3115478d1610b0d3a0a2962600458e504592069a2a5dea8a1355ed7a889154e68cbcdcf809d9dfd3d39806de03e22bdf1a9477cc901cd1ff9918ba1573ff297fb4a50bf10c0daaab1f3ee2b410cf4477ef16d1460aab103414c855d13f9eb83aa7a9fe655c542f3d7c10d5f885054b78aba39f0c2a546098f66bc25a32641ac24f9e32f6164057dcc43edb701fa98090f7a4a6d278cb8a27af7b1d26c2c5c8dab803210cebbbbb8b104b19cc548ed25b5d7df37f04e06b86dd89e2dbb535d3c3d3d3972701c8dd861a0f3d99ce6d14259e9a7b99d6ccf3a8abfb8cff6b030b03dbbcdaecd699f9882148a39c675c03b1bf9fe1fdbc82e067ee8e37c54bd93b67648506f43825f4b010a9d2aa03f54a420b60895795136ecaad50a0a0a0ae2968cb0b165a32756b539cb4b9be29f29a8fcdf168157d4abdc3577a94c4434b9b5571ea0a500853a11acb3ed467887e7119aa4f22f2fa9fcaec3f6cce7ef2ebb3337c56f43e5c9df4a73528a4211050505316fcfd3c43fb66e3db55aadf679797fff019bb31f143429ea9b835ac789608f9f6750f959e096f3cfc9cc44ad266a2566a1ee100d910f4d6da373569f1dd42dedbf0ee22a9c72c94e36e5bf4d6c133d3d3972701c0d1adc921dec5848e3b8a5853ad1f6c0f7f7d76a402613b210b77a4a7bfe454de479d0c32dd53f460ff467d51e507b9d05ef2cb7d1f696a2edc1de86af504ba046d002550595c269c81e7b4d4a295fc3ae547e2bb2d002938f715c8922514f691da5a5a6e2de49d5db4b94b0e5cf4cdc280653aaf313db93bdbf133551018a7c9f4062b985663df889ad90fbb88adc42f9e57452a3d5b18daa176d4e134a5390424d2b45e58f2888c8777835dd79c5add841c0f49ac641272a47e4478b5c07606783d9605d0cfd3df810f0518d1c1f55c86dedf721ac6794a0f5c3ca5159541657d2c6e88162bb9caf529042b3ba3d337b7eb66103857228fb5dd230bb4e82e529e69ae81f5a89a0cd518259add36a9d1d6a1d9bfd45d23a41adc384db7699d59e867a42f7d4a36356ebb8bb43d6a232e44056b7d005f2d4f2f2b28fcde1ef1e720be5b81fe887aaad04a891b4cebac01cd81cf6b13dfbb13027a528d47a1116ead7409cc43f27a528d4ffe7f1764db439fc0ee4abf6d8573bfbc395c50de4acd9a720e452ed3a84973a80ba46432c51b5de94e6dc02d63e3a3a6a94114d62a72c22e65ba8a7a8f9654e2527aa44bd71059402142772c5852e872e560a4850fa7209efc415f32fb3b4616510db637afafd72b53dbcf207a982da520719c4e62ce15467dd278be20bb0ee934ac0ee93466cf749225ce82a579bd38f6384d20eb573ebd591efb0ab8196bfa0bec609fde2172d58c787faf4302fabf00ebd82b282816416b55f3e219dec4e5c49a3f8257e9142dbe39b66caa0cb7768bea78ccb559d88a6531a6a1da905c3749fdcc2c8897c2752147b353a510d117465d8546f922bf90e7520fa8fa2be4936d4fe5e6d8f33d2f6ecf397dacc456dee52794b6daea2f6c7952bb9922b05c09536a73fc6b81e520eb2c0d2f289dc1c00218b2bf90b2d9dd48e4ad854b752f003900ae04a87da3648a12446628e5fe2176050a9fd722585a2f40ec792455a678dbe78523b4a24416040513fd94232022308f5934f3e0954fb393252af1118536a7f2cb283fa451e221224107018aed43a6b34840a6abf7b699d156abf73f207949f4f326c4ad0fd4d09caef10908fc3fc99f99898a72fa3c37a0d7b882814a548744e4a55aaae407b5df3343f239fd854bf14b5bf0aa5ba45c21c6a7f0dcd8c944ea4112a0959446dd9fa47a1565f6aff4a0acd2003735e6391f65a0ac52f9bd32fc345256c0bfd948b602c01fa63b818c6b2d06f02a211287e59b9746a2e8af6d2aa58eb6ceda56269b55ad9f0b3c44a11205793fa39abb6890913f57325fda5f6c36521b0d47e9c661254fb864c5d1a59e5d40a75bb1c75bb9e8a6aa2ee6b6e05eb70506bef4af0ce6ca24af52bb5df93f01f76875b9bea4715f1b55210b5df83b647e968624747be33f30dd37d936edd87cae487a25dccd73e6aafffeba30fd68f839edf63a5d78e5ac7ad60cfb1b052db7fe8209f93d25652f220131065a1ae4382a600857eada4a4a198a07bea74a05f077590efa8828e1ec0eea9566d0f7caeada4a41463ec3eba425dba297e5e4e6dce7e9f3a4606da5229a59473e54af98e75b283b07b50d5d6d322c671c58afa8227155279c1120c6050210cb8a85015a5385185922258441942f203ad547845cb912184b8c1d5c5163f108a20c85042b7f20ed3096416355601000b02c1aaf04a0ca290e669fc385ef7d57736528ffec5213254fb97e3f83c1e0742fee6f7719fbee1a9452aea1cf8e112c40227f343082184703e67a6ccb565779ab529ffd9858bea4d5c2bd81d6eb50baad3d4af5932a8fefca4394a7d9e2cd45e2b5b84d94eebce6404ad47726c38438d147600be90b84e57cd1f0ed315e55ff72c4d68821236b129236cc2c464844d684213fc1d09249cedd1da4d0e3388b33dd3835128f4364e1cc6f1f90d1e38aca3539df26a04b039fdb1f3ce9398c4a2d79ee76d4e1838dbb34daca71235e8c8448db1c6e78931c6185315fed60005157ecf18638cd1852a460405810809546cf9899da5c62d6ac46a8c31c61b75594a961c434028e68c188649214241d7a0803c157d67a5e840870844d19212450f11e081d2cb2e2855ab8abad862071981a32f9dda5547e009a04e6d8da927ba50c20a5350d30d01d0820715b878f1c30bbc60b202165e144151188dba454b10a2c2d6124dca0ff55bf85ceccac085123ec16e0e413b104695dcd9f8d8caffc256eeba0f7e0888549f765a5b6653fd348ab8d40c28e8477d053ce79b9ea1474c4e547b0a80d5d4c1d9bc5009e324f562bd39243ec7249ac6eb0ce34f7f08b963b7504b11df414a29e50f5030821720615151855505952baee400042b60384141144140c8a658416b872794ae8851b4608a1e5e43614bc056498e3046080097141900200846528600c011c5ea1a4979c1f4a72ea5f420a548fdbef20c623a5ef50e54edeea851942f5555d7e88820542d46b9c3585aca855a90ca1f3dc98e91e00ffdd86584c414779ec244acb6a2c2671eaaa8f07dc0e7221d42d4f4df9cd23aa687dd42609d3f613f44a9eaee6024f6e13bbcfa767807d3c9ae7321d67e46e21dfdc3e2800f77d48f5d7cc5d57d2aef3b0c728783f763020ee3070af69f10af3aa0a08b650f5f83f1e32e60ba0ff57468534b5424431847da9e609cfba60386f43875db1eb7752bc4abf6262e6e409b5ad60cdad4d68a446b53bbfbbd9bb3b51765377f92be2852fb073e77c1406e6a3f3f7f6b7d6ac23dde0d55054880f3dd78ab03df91000bec7cedfaf2582bf575f8e985e8b54ebf00ab8f28b4b89ec9b471bc9e694d23a830fbc180f6fa3ddf89a153bc43015e60e8f6cec7e6f43fa13efc7df80560e22f41f14585eac1962da4173d4829a554819722546104282e20c2059d2404138694219a8a2a264802bc92859222f1e33671c5bc1206108e6843b8c088c88a14459cc00737cc2956469a8afabd0f2d1e27bc07f55b24a4badf2a1da1a56e171f688110aa68b9c1122d48e2c7b11c61a5ba472104510a8660a2080b58f0e3af4ae1080d848c8c8c5870c38fff0cfe85d6353a62ca1147645a767b365effad3d7f17bcef5437e7f48257f7d30b587517e00bd9e905b9dc524a97129a60fc7d7a6e4e3fbf8908b46b3f991e802350adaed11142d81b1d11449552055a943c95f24265ea1a1dc13a0248059de8eda671bcdef13ac5af52f114151d1d2121c9d87da1df561f7513655c0f821d4542f977773b082184104208216466ee7677a1bb37ef36ec61629cefee32fce973be4318338fd9c4a07c87d9c4645c8a02e5668f2d73df56b185fb37dac389c9fec9e35aa4221ecf3d1dde411f150f8ff612f0791b17949188d062988d8cc0a1327ba89bcd41fd6eaaff5052752f0249f522aaa83b447ebab97768da3069a8e7ac1046201f9610621d01a38a255354f80fb1183101054208e1a90796a37e5b0e8690d0208a2a290a5bd48c410aa0b8e0cb1660e030742503362842020a1f562084112994cc304b99c54e477bce037a315a70a37e5bc56680a562180d84a818851edc2a5b2c11e40589269696fc402427a298004e3a37fac333685529df291d5aad563b1ce105cca473a3d93eb1031dac503f1d15f2582a589c7051e14348045185464418c9c0880c7cf004880a9fc7e7891315be0f1fd6088aab2655da3a271acc099d60590192a7763a1182110864594ae221b1850d50758b8e0045b5d28c8c60c1beb0d59f856ce4b141961bb22fa43d66e6863437ff727333fbe021419613b2b44186c8204286ac8fca0b32a48656dadd20429a0767dbc9757f743e8a509cda36b406d55e3f1fd12bc4c7d6bf0fb70b226408f6dfee90d6599e9352f6b129fe211c7bc41844c8108fa73d5e0a524377b7c733a4756a689d8f37d03142d426e1ec7791cfb055d7263ed728e37d5a4b323284ba2e33011b5a49467e508178980c34b763f4fc966f0f4de5e5d5af9432cbb239b1971c08b03a1f62523a0c1c06ac7c9a0f8ba8d4dddd2625e0869658fd9c60e0971d10afdf7cc871434bac6a9f1c306374b2f380a972c7455a45d0cf592c2424f41d47696f635ed39eb34d487bcb4166e64c2205e140b043b86e0b5c5ea406b3ede90598ff1689b7188eab0d29d4a789ee2e96f6564224ed2d0cea20ab3d56dd77972bb5a40775bdbbefac2f4b4c7e7ddaa769e6b7ab756a7ebf5bbec3937ea8cfe3a11b43083f20f3634e3d32245de602e78145aa1d8043754f351d92b38b9fa6fbe6ce74dfa4b4fb509eb3f6b2fb78ea56f82d1598d36bbf9d7a9c3ade3856c241ededdb9801fd980933691d5eb5b73f817c27884dffd6227d80dd656dcf4cdd7724eec3ee746b53fbbb9f759f2ba9fb2dc4ee386bdfa609f473d6909f1833289d018d988052f92643710f399cbfe1792b6954fb655996bd7c9f6ea19d936ec6dad4b6507b926b26ed2dfca73931804895add6e12a65c74aecda82ee774ba875be5e62d24f5a67c906beb7eaf2903c3ecc25a04832c00717ea4a5ae7e101647436fcfb23e3f77765644e640c3fdadb476a269dda8f5cb7322c5a75f96568cf480333b4b7fbdc7dde02121894df1ec6098912c3a694d23d761edda5ecba854bdaff407dc6d8b967d3e1cbce3d7670c2d8cdb781e653e343b8df8120aafafd00a26a61b98f85baec39eac28f4788ac0e39fad9cc1a5ba8df6e0fef3e8f70dbcb511bbee6de428d1f2b6cd96d1c39288c4125a0220c5457f8f0a8fbd204384cd01d361b6a7cb871c2232a61c224e878f1e85015c173e2068e14aba3bd8552aada833096a0db9768eb1be37f83aaa11bb682083b1d081dee8e7686ee0edd89488e476032bb2123460dcd8c0c8d81396d5a669a37ac563c28254d89c51831d61833bd4f9b30e639e7d6850959c4706664680ccc69d33008fc40a2800c491998c105a4cb15083119a974dca360e3841b9b1a34503364c4a8a139c26225090a5ad26a11212464c4d0901244444d141555393aba828464455252162e97164a4a4e3049e70ca537287884224c663c37363568a066c888514333234363606e58ad8c00011d61b19204052d69b5881012326268688a92942c624f63604e9b86fdf8142dc0c711047e20558007ea42289b586366d6186a52ca8e060d4229a536a1d4349865d9369526f59245ccaba19991a13130a74dc34c33d6d025284609b1a247c1c60937363568a066c888514373c36a650408e8088b9524286849ab458490901143434a101135515454e5e8e80a12921549494a2e083119f9f52f145e365e27bc6e5e36af1a2f1a2fd46bc64bc62bc6abe645f39a79c9bce82be605f33abdb697f632bde62bbea494d2a7943e6334b9c7d8d160828ec5d88ef1438fb086eacf32c687f26394cf9551e093164c663730a74dcb4c533260ca528cd221364d28fcc7e3ff3b00f7df1675ff6d134b2576dca360e3841b9b1a34503364c4a8a19991a13130a7adcad1d11524242b9292b27069a1a464d2dca4b9c91402697a8dddf421e82ae794262d738f99d330db7bcbe0e61daf87612eb3cfa64f475fe218260a26b3f87abd5eafd7ebf57abd5eaf215f6e58ad8c00011d61b19204052d69b59e2879c164c623be6cbc4e78ddbc6c5e355e345ea8d78c978c578c57cd8be635f39279d157cc0be6757a6d2fed458490901143434a101135515464456935a4a3060dd40c19316a686664680ccc69bb61b53202047484c54a1214b4a4d57a22243444833324209df01f8f8dff7a78d838e1c6a6060dd40c19316a686664680ccc11162b4950d092568b0821212386869420226aa2a8c8cad1d109ac19f9de29927d111ca8093c8c307ea0c4c741f50365fe37e99ae69ca1f406857a08461631c905f3bc1c2a158f2e72c5ba2123460dcd8c0c8d81396d1a669a37ac563c0001c5e0998586c9ec690ccc69d332d3941590c115c3d80d3730a74dc34c3332c0c789a50e8a68fca7aaf15f0e9bff74dcfca7c373635383066a868c18353433323406e6b4699c24286849ab458490901143435388888a6cd85484c92cbe5eafd7ebf57abd5eafd7ebf5ca5eaf9764254a4b344c66386b9a7386d21a2854f7bf82e7e550a97a78787e7c8a16e0e308023f902820435206667001d90076b4c264e6c557cd8be635f39279d157cc0be6757a6d2fed95bd4caff992af1a86ac260ab89545ecf41f0ae6bf1a31ffddd0ff6cc8fcf733ff7534ffe1d4fca7428cff3c19ffad30e3bf1ba8ff06a0925c503364c4a8a199e17a78787e7c8a16e0e308023f90282043520666d8b86f034a34045912c1901b562b360204c44798c54a386806674f3099c535cd3943690d14aafbbfa11487344cce68ffd56cffc940c5d7f6d25e3550a8ee7f054f7239542f13cbe70c9a583e67d004a18931c69e1707d65d319618f6d8f27c3c11091aefc8fe9bf03f53fc6f9bffc198fea3d80e5ed39c3394d640a13ac6c138fa2197c734886910c3b48c7971ccdff9b0e7cc76fe3a176fc02e4a68b3757625774787f0e50eddddddddddddddddb0218410368410c2861042c6b1ce45dbd581d07b4743b82b3dba943a107a775dbbbbfb61175386685d232f5a35092b758dbc4842d535f2a2c8b99bf93eeddc56ee36fe1a6817f3dcd1ae06a89d1e06a6b379000dcdcccb3c09683a09c8689d4cb73f9048e537c51334c524787200063f21b0deb4d7031802a5375a68ec4e0dab68b375761f528f54833176b32b4177b300f573a5947008ab1c080dad8290c3135aae349150828014456b28b5f2c5529ce24a500a6a50b4260917248104126134667d2eb62fe1c77d47653bf3bda34e3d078d7f5de030ea6eceeee6f4360cd31b1cd00f35e1eac7dd77329e1f3304414914b7ae11e1f620b07824f49b3b284f39ca860a14109e6ef6807e1e8fd6b9d13ab1759689708344bb0685e3a9183e0a158361ae61355840b1179a4e87e93e140c46f331cc3c8d4cf779357b98ee9b35bca7b29fe9b8209a51ad63de61defdb5a3fa09e98a3dccc7701f911af37dea11f31a9f5c680e7b98a732446a0b8995761d04c6015333339853f7cdb9751fd53a1397753b6fd4ee38f6625454b2551886614934d635222af2bf0423300a2459832d7870a4a3f84f5d28e8f71ec70382b40653f4c0d81596cb1a1cedf02fc591cad403742e3249f7a6e7993ac36e4c4079e3c137aaea0bc0fe7e00c87e46f9180facced5d3a90767ee9ccd1b5e53e1110015e47cacc33887cec59845397fce2e4ad3ab4c3894670df40ab7530fd6d89db9adcced796d08bdb339a2692b6b6b304a6c9adaa3c466a6c9530fafcd4159db9db92f46754ed5ad71a76e9d4f067f3042df1cc6d8157e9dc39999b48dfb6454e7beaefa6b9a6fdb729f7fc3f63e186fdea142a8c44cda688296d10c0000044100f3150000300c0a870342a1509646cab03e14800b739e42745a329ac6b21c4761180419ea8001c010430040000666a4d100d0df795064311ead65739644e40f58d6d7d089910dde5a6450c003bd139a4667ee089c9e430be73a8ea1522c421564652a7fe88484262d4c7de3442e4ef095221ccd1477b1c01742d59e3aa3c6e52e799b1cff4561f37e28ac7fa8340ae0d1068d3c4e120163cf1eea548dfe0bf4beb6593d54af47777ca04379f0fec2dd2023f1904834a15428953881b2ac036fbb044643a4427c471ec9e520e7ad5707e81ea4bb5ba0c62270eea9deb49f2f50599a0e9c6d610d24017d80d3a1af5301defb70de48e57814baa059841ad02f0f1d09b6542fb7009c8d5a04bc01bc8bd6674c5c8a265273a75554ffbfb4fd99a50221497fb1c0cf988a351ed7adecce5f0d696c3c5a6d394f4f1b5f0caab64af889fab749fd56ad7bd06a8b72d83b1130f942ea13c1a34ecbf1812577ca9ce88a0df98353b6bf924231a30d45ba4a4154174554da53a0e06540ddd5bbd80bda6c712eacb2d393e50256644ca044672ac681d5721d57a3d2b36f5405d131f362d02d360f7086530543bdd056e6eddf7109841946237ad1030cc04927252ec439263842eedde300f25ce859e460148ee615029f20850064bd01235ede6813610c8e1b4cabc0b2d70d78539d0182fa1f40e5e7ef2d82ae070ca3b048407507d8f2e7f7f9068c31a46d093d8b956fc0840cd5ae720f788626094a750bd69c9ab65e7b8035c270dd85ce8e1f1576e0f025819324b9ac586f30663ee34bd12d18f376b7cdf40cb4ed162c0d75acb7411c4bb89fd10db699bd050b32b46edfb6b6070ce27a5c241fb61d386cf492097ccc059af8a3d4e4151d119235a768d469e6e1d565b567de6a635441691c91e989be5333902c92ec5e6cd308b17a601a8b6fbcec7c83d96cbb208671c05380771a8d0b0c3fb01ce3f1dc746f70d426ba00501d3f5dec5202669d090c68718fd50413988a3736373ec778e79210a88896951cd1e514514a581fab28c82f151e4da366e94782f3f1cc0644c571be3c65830a381fa0364adf7ce615553fbc65f8f26a72f4d6fb6c8802e65f61435ca39db3f85d08bb1f76ba6c8c3e0712a57d29c52e27e3dfb34edbc418de55a8696282919a75d60a099e5817c4d81b227c19f827ac932a455832c5bf4be1bba015ab1742b8b3290a2e9b9c2a7537624ee69173af4e34ab5c49b99b3acdf78586521b7d628addddc1a36859b8f79b8217b781c8f9a4b6b5827b9a1411aa811218fdc68b5c1c0678ca25b5081c0e3152db45eadd4e8cbd613bbdc991b758dd7a5e765a9b0cd76ba891f5c209e04be9196809ff53ff3f22632d9b47cabef33078b50740ed0f2a020bc8e1eeafe34422364d82264cc67994897afd3465dfe7944a7bc6e2a997e58ef464802fcdee263af90836a2f6456aba9cc6bfcb329d99f17daf7ff2a909b494ce5df9bf31ce92bbc7ccb9e732906ad4ee29a87541ee6d76349eccf5c9d7c0814262d4badc4123a4c6456da52462decc5c576d7df7858901dc2d0dc4e88c8712637cea1d1c82ade48f21dfc7ebb2e7e574b54cc80eba0634f80db44d8dbad324502308500c92e8eef143c24328020d45474dc3a0cc2bd01ea2880f1be68222e47278a9c6fc9382b08621dc09b4729b04c0f0e63d240dad460d77ff87d4595350c42eb728852205a312d2d76990c9f1c8589fe4f5b130e2194834cdcb54bb388c7f977d7a138e3d9ff8d5caeeb69268aa4b9fc0d43bef0c71c3dbcd5f1624ca8388d0b2805287b3f16fd9a66136baef238a7c3280add275d7ef67c499c4f69a30e7bc7f668c2bed1f33779ddbd78c0dc26615d33e7df328ae240e8c8fcf4ce12012810aef8ff1cde2e74124317de6ca06c6e5bbb7a182ad3c47c65067bf7135b1ce697ff70979407b833d413c20ef708f8007b0371c9e8db0f939ecfe9e184a5acd59e91c9d118338d091aa496bc48dd9d280ae2e67272dac33c635f0a1ba7dbaec6ca50c351344113856a3a59b731fa4667cc076c0158307c29479f835bb30b24c4523cb12808b0eedc8e31e260a18082814243048c902d9502516e584269c4fc8e50a923dec5ff2998a842f9ebc68a435962aad1b0ea76b7e793a917275110c2741018cb14be13ce6526387427d424f1e13ba53b4add431c9349f50b3c61f3d8145d6be94aa1b38a8e89213b584e434a1d253546f1617772f5e838c071b9127e40ace55ff197b06f35d83245b85ea3de48088a4bd2c4597f3b16fb3a7c36cec6d56d7b1ae3ad5bdee3ad791f54533837cf5a69a32628daf4f4729ef062f0a7dba733b7c8eb1d214936c081c953662ef163e7f0ef3ac14ee73bd0ef6c2049e1b0bacc8f69514a06b623842675d886316682a7fec877e8fdb7e0ed0eac30edfc049b69a97f05533d1fc3b387705fc2492301889e45595ae072f3c8c7eb33e420846a20a5c82b23668940c50cb45c23d467fb1ea415cba14f47f037a70ee9f8735bc0da0003facb729d6a0d0c8ec68413ee73e37905d0bc6de20c572880da62e3251ffb982d41c8f2e90906532fbc2d2a7d25c6747b0511a9653a66f7ac49be061bed33989e6f61b6c90dc4be5bdc3be29e1aeb4c1a9ef16a63e094e6390511fc83e453f3ea7c9c69d8e1b4b8eb7185e9db238b3ebe78810e2eeb7ad202bcff13112d149f469f42474bea1ab1b469fb67a6fa51577e5b8ba236d484af528b1c59fab24742877332ee36c2b08022aba9cc045685f7e274b3ab3c7df070bf839f6f3aa7f978549c77b6daa1de3baf7c5921f4386ef2ff34066265667e2c45376700089aebde43b96749b8e7fcb4a5ac0119fc22ad2d841b284f0f63f353c88fd675a0f69aedfa8c5f655b6caa866868907981936b27d7f19619686d503d90c97178534ae06ac93a59520ba355be79ccd1cedd67e15497a3c997c443ec9658b23f1b5f79164d52132b29a612c6723d1eb5ac9b8fa9f21e760f1d2c142b937cf45b41e068fac75015587e3e36fb249677e54df3fe83c318075450f819cf4f4b843a55914ca0da4ea296f3f1ff1a510220a5d8ec022b45f7c97acc9a07e477da97c98ae1abe554431dd3ce5725b9888549e545ba8ab119cc04468b444d5f11ddfca9cad6e7c4eb6f3b9105d5d57e996b4191d0e3407e46d068b36518a1d6ea0a3b52f7d87251df3a36fb24a03f7c5db8c5c6302b94aa5206179293f052dc9b3eb7aabc04b4cbb80848953ed738a210d7ccda514ba9cc1476f3ee61d96f4ddad8ad5514f76c840e205457dee2ed0a9479217e90e66bcd8c31079dfd0bd32111d8208e3091f20bf4f6f4332f128b596086ad7af5e09de29efb4e7c07e657f098fbcd34112aabe7b9fe07accc09279f643e3b8541f16f5ba4f32019bcd54c1eb531607796c2d789e33ec72c23216461ffa8ceaf9fa3d866307c0a8f6e8ad6c5a0b1de239f2ed0d923623fbbcb1dd3dc3ab19e1a610974a85f73b73ea315834fa5a42b2f7f88eaca71d4ba180ad2ad6c5c77d213cfc5d4a8cb2c3e633c4f38b0f9052ec8ec2fa0ec23087d612a77d41a8ae25706f71d8146c30a9276ff05138c6b008cc40ba9bf70f9cd2bc6ec67090291a34232045387e6d696d03b96703894d074ec635d0c15fc9cb736850c7ff4f6b98685ccc06e4eff2dd1026323aeaebfaae06e2b6633b998790b4bbadca9fd68700d9338de539cc53839f6a9a8b721d880bd8d9fa196dde968eef8e37297c57dbda24f3c4def97686c7350027db4760ee218dbad664b4c05b1735c77cbc73b876000e0dab04e5c7a3b34a60dddbb1a60214d874e29bba9155e5cd1475faec963ad9889d4abcac18a2bda43ad971332e3cd0f961263b155b63b19f6689acc082ec27d2b72a38bb609078dc85bd576045873172549ad4c600bc0e1706b5bf3426dc6ca74812025330451d81d8dc643a16817af9e13385942e3c6c0de4302501a43bb027fe3d18b6e156e19aebfe6b0bf6e3bcfd181cda0ed654b92a432ba0ffee05f613fc4bea680446ad040f6d0a2ca458b65c050769f94b1fd0ff492b6a0b6fb50ef3bd9063238646f96ae75a893ae15709aad73aacc2b8a7b8fe44d356fdf879ec319ef9985ad49e17cec4538b4e00bfb2c3d8495d1480fd1f1752767a18ee8459454fce06c8b02450d6dcf50dac32e951453b0c98e1fe7e2e3de61566cd3079f4bac8fe404acf07237d0406210e2f7f800dc2534ee689f48eab0fe0af6fc8e60a821759fa76383dad01a00b11f260b7cbad6079e05eabd455f88e608c3615ae191cd60727e7de3b08ee483d60689edf9bb43f765e7e0c47ffd1047d13dac247f1268d2c8e17a765d6ff48fc1fed4b3bb443605a5ee55b42d54464497785436a0f74fa4669dea8b3921012c73af3327dc75f82126a68fa36b0e8b059e0de4009fd6a20d715fda45227b9c1d82e37007702c52cf5cd929535a777269869596a7766301d9a734b98e9a8c8701e3e1711199a014feba06b91cba96b9234a97e3fca33b91d122db83a8d142202854ab2a3232761483f03f31df63de5cc63b58cd8b61252b9507ef8bddb540dc9d8b776b8b3174dfb65a9d626ab4219b01b1018d9146f59ce21a0e7e386986366c79d2552b165518b868187328943d20724055a8b1cded27b78c287b9494110f2e8abfc61794176ce0f999953ec14992ccd6cf66c85b5ffd798751f23458e4c177ae9fb3c30bad18d0ec743b40924b4a1f2b6e89250695e6d01935e3c0dc9ce3f2c61b062e739390cf475be0eccdab1655502b070949a5f499d59b9ac08c19cdf28c1850e5d2d072bd0eb64c442f1810fea0762972bdc05e69f2dca7de0a19b63f62c1f8bad0b49ea1be7c963d85f51195ce9f1bd0aa38a80b89c22216d3e88e7012934b65db8af45671f79eff83301efe623453172d0ba0cd103319619761f18fc4e34707d1358c32015e5b58d2e1774988b84db402d051572d3f9497e57ba965e3e3cad30a43a1f25ca25b43901580108d3e6170ce01806ae1a09ebd08a04b3e1169dbab9c1aff4cc3f15fc8e5e0eb16fc9ca8d0cf9fe54a5da107fa6daa580e007636c7146ebfdc2ae45a23059b58d90f203b48680743b458c6fa916e3a368d1720cdf07855e13bd1f53e9b0853754827d16f96e2d2809ab3cf1bef14fc37c0d36679f5a0ffbeae887b99a3959b64faeddd853285608e2fa0c9bd35febed6fec065e0d983cbd8c187924757664a8a1a52b2b8239682a5f8d825fc5d821967a86390d3f67f8587cc2a46a274bc406449f1052635c7680e4e9e36f918cf459759ebe40f5cdb278094c7a3fa635c163f922471f31902eed7d9e3cde038abad625f7da1ff2405cfb3bfe5813747a1607bc223ff872c27663e9c8113ac4b81c569b8adb78072b471bf497600deaece3631666a400f9d1d4993bd3ba4a98d7598443f529d7b2949584e26a8740af14e66aeb2974dfb2908a269e07a87a3b6d1910f956deffaada1417e463f4834feb0eba9bc4e7a58344bafa5de615bab8fbebd6c604a6c28f82923c423f7b18ddbb6c0d221a0839a40a9884d694588150112893a8a72f7c1b4984fcc1f0b666d4868b0b6f46490710d47defe952a20bbe4d46929a59086fd39989c6ff4e01f33775112dd31f0a1c6b9dcdd8b1e40c4aa7e3578ba4d29742bc796cc7fff3dbea996345ff02b705e253a16c7400479fa29d257c9024a38eeff5a36f386354167a59e86e7d04bd74238bc3fc1c020d8ef2eed09bf0c5ab03ebc5dac26c2670a53b3545997577faa1e952be4843c1d474001a87bb15bb92d4b919809bdcaaf77a2427b0113d4248e67253782de84f09487167295a3aa038e9091ea44ebc09b7b2e963b73bfb07312b55255e0777fb601fbf2ad561399947d7b55b36cadfe8c39eb7f07a606a4c348d4dfb7a7fa07c989f72739c42e096be1e0d3c35525f4799d89fd26273a32b7e1f2a7e01a83b7e4029e125218276b6e5568d97e7d5f78c449bfad2b66c991452890e2ec07bd555f5c99dd50e59212de51211af6cb6827cc6f9b17381056e433a18e4f3c132a4c6fa4708fcf3078143f80a1559a6d8b9d10a0689f4fc61425db27380b00e6cca6a2b6047de0ad42af6b6b7dd3adff083c0360a6214cd9e984c8f0a48f8bab19ea50a2b93d04bd972a3a04c05abcaa20e346732c91b58a5944c1505ca36ebcfae15ad9c5c0ec3f3cb6acc271be14d2927f4afa1282d5fc7673887d6c08a279152ec4292fa2a7e6a99bf32885ef541c4fb45c9d15b181c8511ed5c9d4e44d8b656374146cad1bd6c602b892a816efe15f4234266ea2f44d45a8abd90b06e54939d05055bec508c5b76017b815c893115f164dc0b9432d6417efbd137f214c8b4370813d997f26f2f0e8c44ab8ea402d6defb8d32c1879aad03afdc204fa3b03a8ad00baa06f5196b4e0cf582ba8e2c110856ff46edd4e524583796744266489d9423e3782aa9b25c515402456613775356028df4b348b77d9fab9612c22285022b40352346627a1388015821ea8a747d8ded86809e215402a9017250fd61b106f216d465a4c6e822f930ae7f723dd1c57a98dd91bd0bc3a94b7d01560477c0846323eba415220177449bde08ed83a2c3504e52958936ca2639b5d8e6a71ca5669686015f1c645e520dafad39addb64f3cdbc510127c4e495b55201d0afc324cdd87093bd90b6f83d0e0404a25d82dc0ec66a1bf7b601f80f65bb70edbd5edfeba657cb077f4969d7c5e323f5719a7bfb8662ac24996a8f4ff1a8762f057fc9211fd0cae983efc840ec734e605f5e6509629b18e64620206d58253bb22bb03f480e42ab31a796e0f5c1ef57625322cfd184843e6bcc2a34c1f58df7222a7c3790433b7b6cbfd47646155e420cdf42dfc1a27c366d1293ad92df4a7d01a81cfbfbcc98a3de66d935c8afe64335bf1480a8af8d443af41b0bfe830b940a718fa880fc74a83a85b7952e907385eef739858601124a21e0f9a4c898b21e04eeaab7c59315e9f40da080a04b94bd2403714ee0caf44d35319f9ca87e1a6bbb5f7810a100f957f95485e85713654d9fed3233fca2ae425c10475ce586bfbd55db18562ce13e57a293b11411363781cb950e8e70e38012d6c02e4f06251476c14a2a30e21f8d950860e20028f8bab834f1efae6c6e81c0ec8f4c834273398f06eac1a065717b58410a03c109633270851a1f7636684415fa4cc530efff811b7e2571760fb11ce09e797d0e599012013e376f2e04c6c68d47cf077ad701153f3ea2fa478348e50fcb2e05a1218e862bdf9616d603a8fdfd2adff361b9fef6f8b19edfcf2c1dfee1fc8e86ee47573d83ac16d7c871877bce5751bf1fb09948bf858d43d70f96347b052bf2054008810e84037daf658b41a34c7fc8678abb1b11eb37b2de8f8389e05bcf1fdc816cc736219bae92a531fdcd671b2ea485b6e56463d81ffceeaf34ba5062eb537249b136b9564b2a83373bc8e934bfed3d8c66ad83f0e5d851d6cb23c18832a22f4ef93e2641ddf13c8791f06cb2eb2017ae72138f89fe1c85f2e57f2438348e6999c0ddd0cdf5438622640b6ee30796a4b4d4fb517e425b1aa9de428eb56285414240aa00a418661b5724124e29d1f08af8f6dbc8e834f574e6c085950342ca7209794a794e14fd583f4c807860e87029112a7c58db8915d116499f0af0a1cde3867eba69ca6fec51a16c8bdc9e750c35181d4f7b54624dc6692a9e083ad55f69109ba79b2e5a7c8706b0eef5df4ed13f955833c4d9949e2e0d44894694540fff8cf50e253a26f4c094f4a176a162a8ba2be16d894b1c4dcc572d01e04e8d3fa6c19e007a0886600ed5e5228041dea74138ce05528cba891a70b935ba81b208001a75e29d2736b124a85a6ab50e440b147dcaec352575167876bb07fba9e06f3390bf2e46039aea0188f8653456b810805cd2dfea5fb7bc626194c123e97da879e63bb3be3b830c86661dbc29d29651e32fd9ef156c95128652ab3a47c6b5fad20fe61d18d1220bdbf6ee0dedbcfb5f549e765ee92eaa151908ef72b29baed959920547f96ecf38fded3dcb668c9c703d66f37efaabc092fdb4594b46b673589c67e4df6a2dde5c9525290f9272ccc963edc4cc47133888733c4bcfae643754f248e984f476e63653a7623808c32001a191fc4ede45b04afa77da9e2524d9b7e62f44bdcf8820c421022116874f40f2338146e3137be335016a8271ba53dcbae0485fa7a147dc45253e19c2995fb68b0385cfa8ee0e7b51b0075bd75d651fe7d3ddcd948edd303d9dd149c607b32d0a90174e7fc22f4828b0403040a1d602dc520ec239a1f6ddf523322c9fcbc2ea02585f92dab2683442d7fc519df92e6f0b0a4925c5224814128538ab53962f56acfb068e00628c54edf44a2c23014629036ac7211e07919f61ca1ec7bdd6d8cdc431e8a17b15f65268d5c5b46b84bc09706b708f62613b480bef02adc1b69a6d5bf041afedfb1015a439e3fd36516eae779024b7e607e1162b1ff69c5cfbcc25210fbe20257827019ebd97ca25b9d8c639c913c715a18636bffd41acac736f050da63012a53f6c1bc918b21b064008b7c952b505e20fdf3e6ee9b3487d92442d100326ea15da1162c12039e7aeb3698754ee526c182ac4b327596514a2dd126671513eb609fe787f0c98e03b048881f613a66cb636ef4b84e0d4066f1608439be18e23e60e42ddc1d423ef57f7094587c682ef243319eb1523482389fcaf2eda2e0e9a635ab67b0b161d8c4612ae2a8f7a465881762b3bdb04203e209d4c3a5a1d307d42af73016e1c4a47140d305e5d3d32df9b6780e7f32a5b7b7532ed50614b8316ca9187ff652744db4e18faf3658f9dac1000d88cf283a3fd0e5d6ca229599e6aaf4f8ead73048d5c0803e47a5516e8e80defba2929ced244a30f268398d2e6aca80367861d605b2b6f7881fbc4bb86d0b6c03bb4704782251d3935d398863df66aaf9531ab00649afa44bc478bde633e739abc7aaecee9387af290898538521e1e1160f9429f50769daf79506e85f3d8187c20d89555cbb5c398c502e376a80b5a5d8f853ae59648e99eeba0672e121da01c3f72783de68543eb9f24feb5d9dced675119f758ef2efe309099d5c33536eea5fa0c5960b9ac90694b498f4eea9ce02ea426d14a9b1bcb9bcfe8f743c69175a6d5f83aefd3b8a60d932c24bd6bb1945dc905949138db8b41f2da228efe3e7ddc80a689e77d80398d4b50f1a414ab513a3f9abc133a91623d6d20b8ebfd2d65d872291099a3fb4c807b087aa0c1902bee1e3501cf16b2ca68898a045e3c70974da81b4a0771e81bd8e54cba3ab409e92923b0a21a569701e95f800d2f061c752c3abb3d8debf906bcad8b952344817d84a486d4828201d84bacde7a8aa2948dd5488446ed65d34c3747b3631ad3e9f16735ffc227092f697a856f366b8014bc69557d6a7062139dfcbafc5c7b1c36662ce66ff97d3778d183693ecab98cfbe941602d6e3c60bf6a9388147a45896e29d4925fc7e12c72d32a25b5b256206640e8fbd7224202e584188f52ac593e13fdc7d4a5e81337af345796bbd65894e0b5e86c19d9c8bba0663dc6bf4a4663b167bc14592577c803916b0d4e2467c1a2d12ac1463744b18af81d28cbe8f822dd51c1201c4275d6b79e3acd08b00f475003057088abf5fdaa30571ff0e62e419c8d086994cb5163abb796e86943142a8e622a6efa5ecfab5041db15e26d1ffa69136f7ae3bb9eed26407385b72a02e81f3a2daaa6e094e5208c38a84624c64f80fc81d7d9caad4b0aca4953b0eee10529b4a4272f97ef05b49630273dde627f6121e39afce8e575917826fcc131cf113fbeba77f2a265f3eb38611c8a5418bfdbd916cfaa06f4b95fcc0ca5d1c6e5bc48cc1e5d221e3664f098c008ab98cbc929299bc6dfb89ad30580cb2d69830d9a885934218be71570c08f8aac52d4e32de961368063aa7f72a913d98ffa0e09c9d377ac42652ecfd29241ee6369a7b3f4b167f4d7799ac227378aac77aa1c431796c6cc27a422919556157f6f7e7aa17aef1d26239afbaa735b7f0d4941546e6e0bc27bbd4b848c2b55e3f7b7bd639fbc31ffce601225043bc09205b307f020fbf96e734a7f9fb4919dc3c30f82b8b63a35c88b6e007f6f82ba89c30d72238288599711e000fdfd84d8d05ccce8b02f63a5ef4af63764936f48a9b443fc621cb15e439b6043e98eb58d7d2ba85d0ca354025c35524c05393588c75d4ca621ed4f66197e893b5c4e5b04b9496ea94334d32c446d995da7c8d59335a42c5a0d4ae1cda57b3c3b5b6d2c68cc873e056726b059a22e7435eac8a5889bdd2d456c6bedfe386bf519ac9dcac4740f7724eadde37cf22de3a243b3ed97a4fb834107019bc8b97092036d60095ef0eea350d29cf0be4f1e6dde1691453de32a5469d2e675f91846284cd5ea828a85746cd7346f2f8426a1c19df7cb0815d9e9d35290772034f21c756f88d5006de821cae6851125a5da3dbb48b8725fd3a31a25c3195c2e8ba295521c62e856e66d7b68c3d232e2dfd4170939f514605c2a22f3766d52b5005b92c11cc0bf8acce29789eb33ac008f303651b3ff7c645650391f46d4cb1a87a743c524c5842490101eca0a0b56eb74421541bd9f0ac39683603c50c99efc3704c9bea057ecc451baa944b0822355e3f59108a67da51103337deff97dca62378c1d07f17393775e3800100e73e5ff1c24bfcada77d9fe10226546939a9d4b58d995fe679981f0533832bb11a9dd3eb602c7f65e3d35cb15bed3a6e1d8b11e1aa40177b45ed3199edd77e0a2efd584996c46a8913c6fc8589617fdef789253f9279e76c161cbe4d3a8f439c28cd963cb8163fab40b9a0cd8de13abf7c826040a5241fa1a8fd1324eb40906f1f40f9188944362e983d39ab89b87d622df8b32b19c1dbc4d97c4fb9b4cc287ff50de6ec9487bfc6767b2f1b781c853c9f139e1dcebe1c1d7927514b68eaf2b0abeae8c442c775a20598b91456910c819132d19b30fdce330aae2ef32a90db888ef5e09fd5d747c5e54dbf130af6c29677c120ea94e61812530b76b1e60c6dfa31a3a4230c36a90fbfc8846bf932620e3e28c4e863b7992012014668cca1e7346d593a8ac436de93830077cf915f948917d0c21ec2511d831b32ecb99c77fa3c8bbf8542b01ca252d179aed4c24109a2bba3fce9bce75b80f13a3ddf96af9094e3157edf29411e677afe1127188f442ae59a6a5d2ed26c9cd0ba8d9ae3560790e40cbc829b4950585e97bdad5b3908e9a4e108f6a3274fc7915677b74a16091904c21b546bb01beb7c3fee40c8b41ffd07bca9a1187d1eb35cd2cce60b1cef23d58618b255a12ac6a5f0badb9af5abf40bf5d0f201b91b4b9cafe4b0d66c60f7146a6ee25ef7f750a81d6f935027d00ef70e9f48b75d800b0d305db87b8d9e39a1d152fbd1abe6e6dfe0340c70fd2887af99a04a36f173d5ee7210aaca7db26727a5e5e261dceacd56ffcf3fc2038d07ef4a93c12699dae49de9079616e9b38dadbe6bd1c3bedc967f150ef4f02783de16eb8b74121287049024fef877ebd8de1682faacb7962a8fecacd5370bacee8c2302191b0fdef9a79d4a18cbe5ca5ef3bad66fe55fefd8d9dc35e08e8bb11ddbcb9bfbe9b122a6b76b8dc66d99a064f26faf3096a4de5465ae8dacfdbb4840f9334475b8357d42140802c104bbbfa2fffe827859ed650ccbcf5c7dee37b288b34158a355889067261faf5af94d6d2e2cec9caca7edc1662e68a74fb41d9d5ce39fc9fb38539b89e1ad71a7fe2d658385463eff43d63f106f2171c92c559885af31c0ab7ae85a8e031208e899844278eea1d3da9aa5e4a94e8d9b73549ead2085088f13bdd567e1e2e23923072ab76220881d015e3fb390687449bc8ad829ab6286823d18bb8440dbec107c72d15f281e316e4c0548aad0fd8e9d7e7706a427ae31db9c2732d4cfdd671cb99d5c7ad6555f9f583a60930ec2da44dc5423637f9a3b655c284b8269e9a0fd9e446096468056e7a6d598190398341421726f366ee0261c6d0ad1203198378f1881d9ffe0061319105af7f2f9fe91357cb5033999c0c0f32496a4cf22878368556c146eb1ba76433e3921bfb36dc09e1fa738ef170a634a64ad9c2c93d485a7dd7d38a0895d936e29284af993f425c224c3c22c4916790c311bd120eb970b43307cb9273c98501ead19ca024ddca20ed8a78b797d4b164b3223f8a33790f94f1daaedfcdf523808207e8383cdfc5fa2913507d176d1630a08b2f8a090081c41ad355ea28606ca789cc2aacbe421e13bfffc564ea6e245acb8f7514f6f94da50b60fa95a3d256697aec17c633e1ab278fb4c4ba3acda78ffdd628cc1277f9432d2c681419a8973500ab4ded261d4b42b3edb16f4198e89302822bf11727fe79a5143b43d40dfcb1ef38a6ad491a788c4bda413bde92ef99e44604db7fde66a0ef8a3c4c3a30498e5ec09b2a65abbd1c10e906853cf88a05119aa502b8f8fd03e9647c81e1887ef754ae16fbaf6e387db28643b8b66a4e9e7faf31d087f5e1350257bc5c802a07998bf666a33fc3f60b28d9835dcebf8c5809e622378670814c30b9dd457159fb26b53e1c95e168660809b882ddc1c3d4549288db429866d34c76220154ddd4ab9e5596c13f60e13cf96bf5f831737c841c40aafa8e905cd01d7ab146bfd12aad52c7a685d8515377ebc87b2a9b1c3e6a93e0ac6a54d68a86260ddf635adaf7b09598a7d21c060a04e0c9273540f449264330a1d8d3f2a33cd214b7d4b76489a8eb05246f31457281204fd66872eb4057ed6284e4ad0f8095c26b3f54a17ebbbc427c68b12586e5104ff44053f4ac1f17aa6a8a59a4567d7e30b5394b69ac5dda4b22ba27d1c0251d2e60f627cf05e2c984cf15f84e0a9842896dc232d1347dd9a1fb0cbf58c2c039258059c52731179d1fcb8913b1c1a158858a408172d333c2f894e7877824f0b1507daa2733aaba1cfcbeaf786dfac0cf36624f6146a8173df41f0daaceb7d50e5dc2472c079d5adc8361313e20d8f575c031ede05dddbb7865d982f272dce26837d7fb61c6990e77379061ae6ce5b9fc9f3355bd4ff9a7db73f940fdfe0eb48a1152e89c4928723e9edc14bce90b22779c1b72f36bf24856720cb33f6a809bc9d2ad421fed5227bce558898c88f3f23114a453e7af0b0a760f9483396b571a37a4f255037ea0b2986f9a1f398bc80869d5d7d1de832cc72a10645984cd021c490e97306ef075a842a3791b2ca4816f3d23733ca16e917342c1203d8c846b1ab1be32eafe49924c8e1b81489d892215e90c59026138d530d1577b2f8010057e218bf92446dd05de7d6b9678420e0ffe060cb9412de06edc13e639d5a655b08ac6e3523aadd118ee1b108b5902e9f0cd94f59f9b21b25abadd84112b91a60ef254c0f394da418e64431e6eded88c865a976ae8b6332b92e02c324ce0238aeeeb94f1776b98401f04da5fb7e167fe892753678f7bffbfc1829c2ad70529723034e1bd36b9ca33716114aa3b90bd8c13b4fcdb9fc8a0235715a1463a91d7ef8814842283b1258808f4ad671c0e7611d7ff28f98300b79b63e266b7d0443ff9c99f7ca59936cfb22543b319f4ae0f8612416d7ee803b04c63c275d721f6fad0b60dc7a053fb11c72e33a78424addca64160ec17c71c5f0094cd63d2df90d565873ce629ff1f0bec2412a5253932cb1f931b36f566f757061fee36a8b4c4548793ff9e71cf318743f4a1c9488be3994f7b7e86c6e1281db3e77804bf2c7622474d9d9c4ca648988fed0e6d84bca4aac8479dcd701568470bd61f0c0b2888a1f23a35b559c0b816acfd6c1e53b892f17b9ecdb8650498a2eb11c812c800ff12a02b563beb2ef9efdcaaab337fa9572e92eba5aea0bad4877fce4843427637b7fd88535a30829795afff493e9998b5aaae17cbb6cb83b561a84061beb8619da0ca7a2e5142f10096d9890c65502ac423a1b164c23afa34de779d0ff0ef6d883f44c9628dab15b6d5dd7ce05118633e841f563d65ebd0b2614094a2e1b0de1f9c3f230f167c8dd67e2a20fe7f90ddff7b06f55b7462db05987eac44bfe9432bff0133585b7494c9a4c93b76edaff2e6d22a0e93e1e9e1985c9f8dda50822ae7747a8ab46ba238f438985335129a133fba59fcb64e969414be2ed36efd293956e3c89c5ebf846283b6a2d78cd2a5e3858e18c51cfa4255a0121b4af12ec4a3295fe949668d6907f7b5f0b9f9640b239d6d6367073680ab93f2cb1851ed0aacb307fe3145bdf49df5fbd414e3c225d645aa86c26f5896f1d7aaf13cc0a00cc2dedd5d3453bbba6830d804ad401b8fab7f6510dba3a21d65d5468e1107a7ddd63c06645ce6c7f89e82fb95439384811ad02a1ef00f16bca32421490c87f6d3d140d1ba6234ff9a3b74e66e774aec2807fe18700587a5090a6aa5f0f00e868f459d93831af24186695eb3c33d68cf6df43d2d3d1bd6f6420f1d7ef572d8e5d1d60d9f5071ffaab15d02417b4d6c94ace7a8246fb6bb4c2d45f04ec2f44400dac6fdc84798834340191dc18b137a836fd394798eed4ebfc39be3850e33893de7f928deb834d8cfa9342e2eb1250506f0d555007098d0a21cc8e4e3a636eff171ce4160a842f925ff50c3b1d257d699723b3b0d47225b092139d06c9043b87c0bd370d17064c7fa9b35ecfa6c0acd3aa3ad8170850d3c9a5d2bcf14221d77378e28dce1070af311c3c5a72247d9a43eeae38c0fbede23f500cb8a372df5b2c6a1437725dbb82f94dacfe713b8854c1607ef473d8b437bcc5866cb10a8bf9f7d056e6501d2e89ee8b52546ac2c1153f00b7a765eb435eba65bac805fe592142aeafeb5019d6d0f15a6730ce85837e2a08478c2dbef608b0c7912667f3576817d187ac4a22836bca24addffac70c15cce5604b0d7749d856cf75f7875c50b747ede9a43d3878708283283bf908efb14d4544ac28e96a7ef042a54ed91599496c40bf9fbfeea1a49c7760449c5d4f7008d7224d4b3829aac6b55a3f2295966d31821e20de126a7bc34a17d65f1db753ad4868a847c95a79b6d1b037ca9403f12639c5d94eac2e8087b0d302f914fb068290f77be34a0ead151b5e673273b54c0a986c85101d3616387644d3d535905e9baa83618092c54841479a06043804e081821364af4a5bd7151e77606ae4756e415a6debc80fc31e0f40665cb4521ad0eb25f09c307687630652570d83defe779d94d8bda202dd68b64b7f64c39edea7b911f58b975bfbc2de1c1ccd55bbd5c5d98b3e3a6a44899d4733dd5e73f5091ae98d83cce87a252d710a63b68b6b4d738e78b24b4413463850def2ac43fa0a87b9fae3d84a53df24655d86dd6a367f92eec4f52a2dfe029bf0d39fdf1562f38419a95fa3f1a9cb44d35b944c02b499304de70db1430a535522898b77eb812a54d0a8bdc3eb5c07f12e5c215def461a268a01fc77e2f3d43ae5daaf1092ad043548adba9db475f903985cf2075e1dfe217d44105466f6f107349c0290aa4f7e2f5d3a1dc1c8fde1ca8c79332014b6cc839bc05faa9e5405948cb91955c07e00dadeda8f0dea0a8e6cc6a6d93d20b769821f5aa4db2c0998f274583e6e5a648eee828a996341e1497c63118aab06c06c7195b80aacb62d6be6e8a10fc50ca56b9b94ab03a3c338e3a16be7aaa6b3d385bbea89c81b5b907a0c8c2fed07770ad3b1c8390f4c1215313e6981235160fda3bf0f46421b834856c83c6c42a575cbcd255cf4e9419f56565647bc1406f4aeceaa601732585496c4d0fa05b221b55179c211b90934b756c7c00afe15894635538d2267924c6c244a01bb536e08dcd1b35887db3d746dd7bc14923b54a3497da8637dda356beccdc18696cf58e69ab762792d874aa1e44c5a8dd577974d1c667f1e8a0aa72814bca3f937786b74a13198b9355606f8b11fb174a8b8b2d9c81bbafe90bebec204a3a93050328eaa3285f2f056199597bcc353e14b308bb5c3e22d91edd401124e03727bad236899b8fc26d0b51dcacc2b0da9414aa7683c3af2393cb106ca6223d4bcb37b77706a31bff303252e2c015dd0cd91a28fe85a9c28391e988ce70827c1db78ced988d71963e3e6de4b0588101375f33b79cb8d57c09a1c3637663da52523aab19532c031b883922e4ef836f34b515b3dee861f7907fa04c0cd4e083d68225d86851cb9f671c81672804714a9020acd0ca0be4f9c33eafd9286b844fab9c2a8580b5f79c7ed7992bb34c19eb5ee1aa38ebd620c999b91ffec0902d5fa933c47667c0628272ff3e9d58e623049ae0c3caa0f7223a48bd647a58ce1e95a62ba21b7505121cbd13411982ddf338793177c821ef7e2454dd2180c7e968f24cf53efbf7e962f769ded72c00c7312ea2dbd47ca95ca1eff0aeec8a8f331bd7405b44840cb0ba3b0cfded40a208730fe62e537c99561714de7d4f3c81e0824d7a045db8da8f9c88e1114a9a0c97e1fccb7f0126a95d942350ac132157eed442117c22cd69487a004c08d03eff97569e18adf23d2b54dbc924433b6efe4e20f42311ccdd66943bd5e31db7d4b1052446626486800a178347c5475274751719c7ff66073d2120652cdc9f1affc2a350583ede431cc85ec00dc441a6b529592a8aeea99047d257a05744f281982f8178c9a1364e21c9dd63fdae573e2b47f87b138a4b3597377a507e898492dfa61bb255c40fafc8bd9349896abe0a08b191cf1adb21432660a663656c53bae3b8f7db657878b2bb2d93e62ea399aeb6f5757e775b8e7fb3696da882d24d6f9465f1566edc0d2d6c08d2cd1a5dc56f30f9c47f78fedbd58d09ddac40b279026d513b7f9c1ab721dd1f8a6835218b0c62d8e03c6af48d530d6ba7c74ed3f11b51ac0b9a8f319ced2cd2846b6ed308a1551551dd598fd2f406e8731af3a8da3dc6fbbed744e4b22b3d73d5331bbb7245082ac9df6d72fd59db877d9b8bd442d0f671ef0eb2b872439c1eeb6b92368c52b662536b1e85645705511119f00949d5f2890652d1a71d5457674eb761b9d02657498f9b9f7bd8a2cf1cd6b1d5b45d64c00c7f2be2e546ab6e74d491898addc3e762c4476cddd4e5711f5a4ab6153e333204faa185c56c2a81628ddbf4004ccf4ce649c120d20fa33219d0196dcc0c7bafe2e34eaf327171a72a52c93528559ccc5961e1d502b158a7a701114c47f35cfedff455c23a67f5de66887b46bcda187dcb46f00c16e2225e88fc9fcbe5667a0676bbd527d371bd08eb4abec65801c226e021da0e0526dd1882755901482e8070572a43366ac23da5a14bc96330afb604b5367f64ac9fea96321efb0ddad7c329b3feee015b6a668e4473aa520c94ec95d4e367b50fbcdfcfd81e173052526cb65a34aa748476112c0c25dd60eb7a532d90f541bb948dc26018f4443bc714c6e67c0a18dacd5c6141b2ba8cca6bc820658d6de9523a8a42066fb0b3b56eed8f9ddf2d3735f87fc49ed82542fc2f8c4b1b71b1ae93c62ea07f1cc052c9dfbfa52f2f180943ca05feb7d5dfb04f57d4de9136542f9facb60af908e6c4a047496bf382a1658ec47d3a27be7027ec8555222f9f16dff7029983ba3bf0e99a913ee6f98ae03bf295f86469f935e0c0e89658d116a697009a0ab5a99a7434d55c25a770d4b57a741a55dcd7ae33ee33e819bad15413789fa3f1a6f116bd45c9cfcd8f0de0fe6c71814939633b8cc3bbab36ba416e0fc45a5ede806620506a6e5e222f0eae213c7e3a3a359fa4354a6d9e04dab5ced04bd140a0ed447f9ca458a9899933495f0337ae057093e52ad9aab05c6e4e161a540cc70e4f24bc7140ba401b836897e8651eccabf4fc3a1c0c829668dbbfc3448dd5cb20575753e7b1fb97a098386a10c9fc551021eb23eb681dca3c440b98b9bdc80723afdf5f22bbe5989755e2129648133ac04c1975118af613dfe9883d2982cfae922a19b44a875ca75ed3f5b92f704a2a0c8ac787e9f090f1b0c6f66223985544b68a5696f2afffd15601443e29d2afc6d9ffdb4f32b67e4e8720fb29102cdf4383e58ccbbafb106264e5a2fe47ff0f0e573c2e98b849a9f1b3129686a071e9b57540cbad68dd72e553dca204ee40ed99e0367ca45e42ca058f9c14da69349c183d8fc49d8236a0e81c9daed7082366627e9c95f72f67acacb320ed35c915d1abb8e49340e41bd3c04cc591a115e1664a9b6d8397097d9a6622a7c60e7869194589be5c0c7d6f0854dcb9f535625af328875c6266c3c0ff3df818ade7283bc1aaedee4b29e90666ccfe4e2b0d451f0972105ad695abde4cb846bd99573060701d477496c20f5c8a611cda86e46e6194b8b2974cad6b5fed3af15df6447fedb1922d54f71e325e7f27a8303fa42f60c14c6caab36ec22053599b1091540235472e37e774eaf461a4a64c54b9a482629495326b53b08c825e0d19a725f14d12fa7e2efac47bb2cbdc598af68f24e7f338c5d55950b2d47e09b6037e30247083a29038785da56134b57863725531cd427c13af0298dce83e68f17d13a85c2e28fe7d34a05250583b1a4732ca0090be652819091c161205f7edba145eb9f65351a85ebbce227e9aced84dc34de4cab1af36f52a01f287f1b8d58f35a17306270a19c057809e24ff4b78082df40a77de032f987d7827299f616be6249f4e5a3e190cc6aeb85ef605e27b80001a4ec66357ef621ad06649953c201770cdf8ab794ba2d74500a65aad04b9c8d793237185e79aca34c5b8d3399be558c70e4e907e9e70d798d62cb1888b1b0d6aeea4ab6c90c9a2b045221ec0a1df232b6bec70ebd5accf45927311c96e3a463d03039a27c137caff88b36ad06388da213ec1fc0c75c6c646faa14da7fc748dc01be9e6b62236053d79a50181fffe0700fd7d78815c3b99445ae88140febede19210e7dbb3db72b4c55b63cfd78aaefd598595faa58f9e72d00bd9b102bedc15fd31f33fd3a840c19987a91b1142b1f26df9635230eacc243f27b4fce3b1ef62cbcee2b30f3ac216218376d40db08bc35ad5f4a6f5ac0008a9032ed17e78798de71ba21709c63fddc113f14f320799c29e7ba89871e9225ac953bc3457e45470ede7b9fcd70714abc8dc19a4802bd06ab1acd59d69816778d55e7c9f10ed257d28e9c6e9ae0e3d53485a20ef6c2a46d6355a64ccadb040450dfa5f12c3f535c296e08e1183a685b57ada0ff8960a6a0d895e09c511fc79aacbcd03026b47eeb3ab4eb57beac82492303e129c3e168028c112518bb7ebb9fa4269617cb2ab61484914993a79a3f117434dc928047f2f549bc7fd0a3c4e593c7a554d046a94e549cf505fadc3537301f3be458add522bdcf5fdbc9942dcb34c158cb713e2df0ef0db5c7ef5500bff6bb2822c71a88b2c094d1ffc7e130a53552b4b3fab54e8372be661614df20cb7396a788eb565e30979e3c2b318a51257323b0f99ae03d179247f888ab731227111791f95134c2efd1dd44ab7857440fab93bbe07e6ca3e9b0d5468aa1c478ebc60606f5716b6a1bb53c366fe23fcdd205369178acd5dd230abbb0734270ed92436b5e73d0bfab9e956be48f2c31ad986acd2dbc06dea2763ce85e55ca73fb13e3d12fb5e8267cb7450057e4f4a0d1a7e3436ab139ec637c0cfd8d5bf14cc6e43cc61665973524a86121c07ae6611e43a5adbebe35549b42a4488fa0914243d47d13368da811e38483b67ebe5a4ea2f09a23b70dad0dd3693ba771899dce8da192f9b9536b801d3e0391968da8416b762aac180e30add2c730c85e400c27b419a2af339e481522297e3283566d296aa7691c15a87bd8c3a831ef477e13e9ac3d44e62731757b1838ae3b88ea3a5db9eb9c7b38bf16aa75cbe2ae9faede2366a17f9a208b3da4af81b2af3a7ca7b6a8c874d5f0d59e20a26143e911d4ba99925a47c5cf23c72d788bcb756a75653bd55cb0c13cb93e930b2e4ab236318e85d441b52af6793996abeac4e692961f7d335baf155068a2e99625def90b8434b80357e484381a791ed7ebf981d7dd5c202a15bd2536845660dff3a9a1ca6e9b7a2f904d1920cd7954918812ba863411a026440fbae3dcb3459d8a2c44695d23eb3abb56e2dc1935632787b33989b9876c6c3b03e50021740d3ba464d536e85a486004812ad1544ed10c4751ae13344102c44e50695a569ffe6d4083d5b26c2f46d7c5840c27856f45938bb13bd91e193c4f61c1f5ec2ce8e3a322a3b535a992633c3c82b62e5a3b81eee21d620fab80af635b1f85da35d204b07e5b6455d3db7e352f9f2968edce3a0c34fb0ac425da027b98d509d0862ad351763d7c4c9a4432b2cf741e2385bb26e7acb333b093aed231bc695330b188f140dcb89d752b9f9cf11716a076bf19690e8196f0ac4483e775625500edbb88e78a3befb70cbac0634ae3b998aa0b34db39f0c088f2196550552015a405c20cb171bccd981445b21176c24ebbbc32b2931c15a0f84fdeb8a9650f6af563f60b374da42601a6f7c9e1ac6ecb854712ccd5a9e811cdbe2229d8d517ff7e809e758bf7c03a88884bd33f7f1cff3c4e317d612e57c42af0da0deca619ec7a16f49131aaa68d42c4119565da3af3aab8804cf3e81b9c4cd389bf1c95c229a049b696d2f20b348b68d1c41441158a1a866446164e9fb4367dd861f287bd543eb164f57b1e80985bfbb0a75be18ada1ab4079301502bc7fbc086d2691082f4fd94c90c9429c99a703d724ea4287b70d58759a75ea71106b0e9745fbac0ac1d4b8d6b6c06b885413e3165f0fbea378507ff3c470a9acf63d241777f486386cbc66755d170e8a5a80fdc88d26b018aa35739993e7e8992ccb2ccd4edcba28e6cfb6241efe1689dd2f1aae17a4c1f765e5136a2288db67da39672195e702596a0b70b47299741f4e83390e3f342c046f2545766807f7b5d7ec0d867ba5e086ca36067a3e9c48ae593e101c9b517df65a4d2aaa16d3c996a1fcbe7fceb97a1f5bba29715407900f03f4e072335c34be830a347f75b74431496e01bea0f6767c3e7094be5669b514526fe0e55e808ed29f649542d2b641308cbd9b5f899d3fa8557891cc925bce017ebb6ad0c2fea702cc88dbcee394038c6f0b340db763e5fe15587df7d396da30abb4e3261a3fd41a36b17646fedc3ab94e585e989dab3ab2ccf4601e272bd1340e99ea9ed62eeedc719733b3077aecc88a1a77635003e81c1192d817f52afe089fd96df5f61f2c0f4bcd6490acbb9ee362247b8553860b5192d32b9592343c52f51897b45e3184c2986c2281572bc18a50463a2047c234fe0e7182c4f80600dd2c282209d207027be10db7e706e71f17e9c2ea51fec610fe718a5bca17387fed873dd0ecd822921d280487ffce790df1cf8e538c3d2864ca7532db8208f4bddd4a0fa9fd8b38b87c921d762cbb10b490af8262ecc0eb162b9d4218721a71c19618ec7e0392b9cc9ee104ed99474ae02a21b9af976b7b126696d075bc0c253106ad98fb7112844a6f5c91d2dc74cbb81d0225b2ca6baccdb8a21d08b3c500449aff7cf3bc704827acf1ed25ab076a0756d4f435b96c7b3f78793c311739242dff63a0ea974782d6135d49222f2d66f3a801a9f87eddbbef3d4f8bb9d14697587ef19a190562f768ee29b79563f4a7c3b9f906cf54cd1badba02d2ed7fbd5748988759103732fb186d2d1f2107ee1e8a706dc5e82149d7ed370d425a67c3f61686c652616e5eb6d782798ffff47b0a697a02a767655534c1bc1ecb71534b1798dda5c59adcf3a606a08c470d630c48c04ac34f6fca0baee01628d8b52d35257db44e995f3902ed32a84115168399107f2e4ce29733e5e9885f890cf53bab977906c42053d92b91831f42ac0f9562495c29dabe1162d57b2afc61d53cc893522818ac13cb266406b6659c2b8256401656e6cf45e43faa3b08a05dfd0307e6abd2365db2c7b13cce1b62c296d1b839899fcb4ddd31d17929822870756b93efd48f65ce56c0456ed0d376d7ac275282beacdba789253affafc7c162cb205178b92814a447c0a58563eb212e2c57693c25a42d820dbd5bd9df82c38e2e0cfb37823dbb5eb9924a848c83f5e87d53b324855499615300e8bdfc06beeb90bb2357e729f1f5c9c1ed405708ef046d602192ed4c3314b2e882ca19a175bf3a2cf2fb579ca16a4a008147684d7d10cc978abc1a15df0999d00950b92c34fec9340a25bf95e3b82f74b046c20be1ee9cea051055961e997e5c2e314141177a745c328aba7fafd05149b4430135836eca3cf076cbed9c34c3f7a93b6a8e8231266b24368a8b85c694bf7a30a046b74e25955f3615d404585759d215c38ced97abc0eec14251fd0f3541a6124ebe4b0309aad20459f750910cf1fbaaa49b7ab023a7244815e1ae4f5a299123548226d512bf52995aaf7112bc5470142587bad7258cad0ffbd9e5cd720dddfb467a61cac7cdbf0ba8be4be4d5690cc6bf9c2cc7ba65e8ba0ac2bda65aeb969502aa4a1c78e079b1cab3dcac5fad3618953660b40eb0d3487153decebee55dd0fe8f3da986268e7f980ef85395d02b277eae1a079b0ffe9df8b7a3dc7fa208125193c597c5cffb5f6337d58374fc5fe08c0c11bc6d7d114acff3898afe8a8eb47c8855983dbf2c57e0742f3e909cca9221ca770001bea85283cae48429e1466ca9669a4823e5b2842c89a462f6bad5c9b257e8ba1d1adb45382c5ac695d92683f06fe1838ee8da71a35741d3e208e664abccac8f311e8eaae2702f75199eb32efa0ba3d986638fa160096ff52c6aa2eccb10994de7ca31d1b41e75e765d546f0d29ca1596c66e0a59117b2fffa8965517c79dcc1dca80245f37960f606b468de54d8c53a481070ec5a136a228e38daae7fade7a9901044410a0622afd92bd0f75e4186316e3848d975077b9cd2f9445cdd53f8b12d9e9b84a1253f28e335bb5e6b7ca142fc70ebfb9d1a0160d6b740c7f920cb6156ace9a7ddb1eda66d2526151335eb012482b2559b3dca10980349a6a79919a7f0a27b29ac634589715ec9960c9368a5d1e5ad6a54b502b99f81a72483e6db177ab9e6a388a6350b3c9d4dc1a9568f6ab37f0ca9fdff3cebcd75ed1a9d65ac211bb086247334fbbe72d1f2a1ec892446ff72e425f1bf535a9e352d6237dba279d24f2c4cfcc15f18a38073955ad568e208d5c2fbf44f6991d6bebc2314ef3114de5d33c5825c412fe9b8e1ecfdf5e6895522a11fd82c8520579b6699f756cacb3ad361d18f726f57607606f009de77c45a37eac0a5ef501ad875632f44b65696370613cee04283529bc539ff8ab8dc71609c730c682f997548c6b0f878fa5c3a915d4a414fa995b038582c18ac14cbc38eab69a0cd06cc3829fd1955736bea523608fa040ca5f25a1c3b078bd821a093775a22e45f03aa4e3f578d18e9653a78ee96968390f999a04d4d8dfa929f14585c3c59118acbac5731584424fb8b054105c18503ba616bd91acd517c11902cca023e9b339c2745b1441bf5902189d035786038ef7468d2102e1803ee2d0823380214cdb80aefe2d9542231a63182d1a4d1e8cb9aa95c7dfbec0e45fd99e01260ccc7f6a8797f842dc1b1c4fd00adf9c01213731d793ed1ef15cead98ef8ad8600a4b6c22c0b4a6ed630fc3fa6edab6ff1cdb93da7fdb01482529b0927e00dfd849da00a5f0a3af79ca756dc81bf38b55dd992a5c4b195fbad7879170eb6583ed6e6da9567f48b6c29165e094ac78c9314885ca81dce5e83d20ad5abe1748a85a8d77797f425d0c212ecb2d9c4340080c304ee4ec611bc1b4c746c2028b213cfda833a8ab031bbdc86f1573794918cdba8b9b12446de3ab41f432c06b0473964832934b056df907d4d0886174e93207012ba0510a2a720fbc123df3d7973994a2d37d17bbde65a9052c32ea4a9eeca6376f6892efaccb15f2d2f3147e6323012227e06df99c3290224fffdbefddfc0419b35c43f3ff605622c3f1f637d705c6f85735332539ddf944f08899e9f10db362360f1fd81887d9ff1b19883e160d33e8c43303543637dc2ef471838e675033d6422e75718011fad2d2aa95b88ede49e63515e01b4a67dfdfc10a7bdea9fc44c367b32b5bf1373c93f7408590214f8917fafdac853e0ac06caf29c02ddf46e3e9fe6dd42cbdba99f3443b32c03844d7317c46b3736ff1790c121d27f58d02e031464a79d14cb8fa87a0f36cac25e161ae0c86a579ba9dddc25c9f22a894988eb3f082a4db6364d4124b163c427433707bd65f8749a2fe9e48dbb95ec522ee1532647ef4c3d3914245934d1956b65e62c480e138ea381c008cc36ebe541931164619c0423ad3f1b006b7180a670f8ec42a1c5d23adb34f94e8923b6cbdab6e9bc461c1d4e760aa02c9a58ee57060bdd61e69e418db70caaf5d627c8c28b279b0616573d1156edd31aa896783d6b9d8476c399596f6212b2118d9c4252fe9582c1d7eabfa64b63eda4f02831d2c26877654ba5bff1f7221ac21e1978691d5f0ad133cbae796a41c4cfcee54742b8c32b3b3ebf665920ff9c5064256242f9b3123960dfcd6b8b565b05e6fa4c242869cd191ecea62ea130c4022cc75d73722e90214529268a1116da3c388f7a8444f2e38fdf232d6d937a6f927ff639e46822a590bc08334165ed541fe4df286b04e692b3dab68fccca13f343cf2b7194d964600e40c7e01bd482923517bb537f3dca989c551a8677e92a8dffe401a379e020e8cfc5a50f208cb28d2277a3f0b757346c8c5949910935816cff07c5907aa121737b5ec576ba6eb598ca38df1bf9f9ce58e7bba9a326f1f79c371601885cbf5f869ef7ab61de86aab68cb84ac34d8b00719f0b9d79202e34709ccd22c865f825a4592229932b87c68c24e499a99b9be071737a506e80644bda5c286e0eb35d7619a4a482c4f07da3b2775941a499b0b3f5fbd3a203fa0d071d210b358c4f40f33f26ab5ab24db6090e90ce194403aeaecd0c710dd65795a035a4ffd32be81f52b095c2eab2cc1c50ace483e6767ff07df49f26d32563d8694edff2c0dbe650cc0e0d8a78f71854d8b0dc1758155cfdce898d62e813727465086f016468572999e70c8f7599d3a1354c71f3e8daf43b02ade7568ebf03cb076ca99107f81f04cd8748062fa4fe710ad3539493982f23e810a3cd7cb9e0fafb22b939132219f65f8402a77a4dcdf086e2f299026bd5731088b97434779c3a91f063cc9067807b9929ba5c956722dc00482329780a6bc4934025743e02e0ac2b844c3acf44352203a5947804369db5ca4da286d75d68d6f2422be879c3877257725ca3a84f81a73e5a81878164c130a1b53ab3e07a3aa990fa30144de232cb800f910443088a9cf5087ec0425b0832b30765179ff971f412c48acc27764aa2970c71ea67c2ac841c0264e80213a495c07cd7b548cff5f87453f314772d0b64523a4ac346e9a7638a9778531cbd0ecb60ebf7c801ca4a42628954b6bbfb9fe749bf421efef45f71b970627fd0832f00159414c0fa210346f2d3845a5bc917325360827db8e375bae6c56f410c79ab3a7fd70f1a0fba61c1a621bd058c16c7118420a037f5ba8d7260f0c897b19b656565d633d350859f5648c8160c63f2ff1b56819d5bc90febcf4eda5c0e7a2ef10149d7a5baa45afa7f7d423f54220f4342625a48a5878718f04888ba5c4826dbdcd4555e8075537bc473dff94aefec723d89d81838f646611219e01df5ea5515f5530b358e16783424811bcca5e5316dfb61a8f67d84106c745b0b170bbb7d42d0197e39d1a6d12114ef37488a0715d063e84e98fad7e342e2d5b3b0843cc1f456b10a9a2644297791076801cad64081674c08925bb49b324eabfe08f75c12f46308e710d3219f6941204b87322f0d3164ed50d01c8238460597a83a713ddfa14a8bb5daa0e983775317d21c24c17cc8da373c96620ff27c31f57978213bc7edaf03112cfb1fb3997129eb31d5708c2a6b605a7d4b109540c96803eb938dba7cea21c5edb5ca7255aa480ff3ae4d1d188366b91b984cde973022509fd9d301368dadd383439e5dc7eea2bb0e9cbb660c7bfc0224403fff18a8daaba7fed38c06919eea938ed5adc281643325d1de87365f00aff9d50c68036a020b8313f0a67a971cbb6350e14f0a8c06aef9954c8efb6b4be2fb4a13d688109098852e02fc55bbcc01baf052648cae44a93cca4fca29168dfea1d06b9c9344b8a374f7c1058344a47001c9ffc08ed3d0156652d9f2882615ae76d8d1377224a84dfb298c83f2cfb6c3cef1f849519c9ecf5e7e52e62ce9c66f85a9400c63fbd02b3d37e13f2c89809e12741be003afc88f995ba60b5477650f63df60bd30ad03921bb65b4c84582d912426a153b537c7d824cec8e1dfbb33b2cf30ccb31ffd013232d3d53c691cc262cc171a3ae9da97cf5fe677433728acdc3294ea79dd250cea4d9aaf2bd51a0010b586dce393017e292cc0459a835fc652d7cd66abb0500d95e3f04eb309f3ca90dfec8c1119c691fff1a04a384ddcfceb74e3162940920b76e64c80cf4ce4a5b3cd449c839b19c2e0068dd8c46fc506e9a905a4a16c3d21665a0916014aca5468390f8ebcbb375601afe0544b194eb97283aaa499733fed3944241086a1d82001691b75fc051a011e1c98651318b48b8d109d821cef3663627986bc49ddb55b93d60fd720a8759f315ef947b541981c32c403ad430e5b9cc87be358fe514d4d9b6ed211c77e72c71c136412728fb037faddf07e84a03a91bb28feb3c44a96604d781e3b8d100b51b651e029d19fb6b5261307ebcf27bdadeeee7c8fc6658785cc1323aa2a7f5d12d639ad71e91332f80ceb3111d8e701a815ef294ce7e2d247052c99e9b64413e61c87e1b7e96198f8a6244b94b124e7b2228ef653dc35b48e15a148664a360d21278907392cec5b37ab60d703ccc71f2016f33eaab3fac531ff92d840230d2a038b5e15c3e482c42b2465ee1e0542fa0dda7d5f5241cf8536fe98c4de80910eaa0bffae1397a1967e7b00f2afcddcea6023357028ec884ed5e5dc38da4d704f6259f3058d4bc2614739cc6230c9f1467c35c8bb4b6421680020c365f619a407f45cc5bc0197069e6991aac28e3f1589bb59fc99ca1b5aca2284b08e441eb576f2b708b64d414b2223e46f6fb55225005395bb1c8ef94079a7df2d26437051e149f6544bd10a66585604ef294c9bf9a783b17117ffc3a05ddd7073b629bda6a582270f3ed12e3ca40a9a83cd1d8148aef840e8fde04a4f2942b5900b7c79dd941f72be5dddea884c8421293cf08e6527400099672e1288e1ab957df1ba3090fe9aebeda5b48ef6bac2a39fbca30b5baa3691d4ec7661bcd2bdf5ec4f2d7cc3018e9e7da8f9571aa2501f9d3d5678091ae413e81bc9368f1193fa95ee437cd27447d944094cbd034a04639f5a304cca9a0e7589ed157bf66477b1ff7608fca9fdfbff9b9b3b641b094267b4eaa879bbbe76e5fe3b015a3336b8f3383f78bf2ab4a968fc14f467b68e18009de8475ceb0a13775033867d5ac9e00a1c4d5a6f5ad2f69652ca9452b009ff09ad095eb8a6db7857f58d46d363fa463fc134fa3b11e9f6771a6f2818488a1dd0eba24361a01fecb7e7fa36c95879d371110431afe5b190ebf9bf96d76a7d656fd916b7ba6a3df72a22e7f8661fc8cb2f2f8bcc402dca7903099ea45a6bad319c9925d11b7ab228d140b9602559a94af294a5861dda3ca1823d7102aa82c902ca87294fbaf8e1066773434f1625fa54cd98ca2689c6d0a40b13830c459e89145190512203021688f0c2e48a270f6aa9dadac31319ea931b5ab0b8169a685f3248d3b2da7452da462ebdd1dff1a79452002061e5652d38a4db6f474f0bee86647a59b8e61d679836600c2ef3f08e993bd2f87570154d0a799e770156f23cb6e23a6b711d851f5b85978b599ed8595428782a5c7724fe3c65b26432b71b8070250ed368f7cc73698f10e4ada265209c0cc442f66c09f6e59d1439ce10eded5aed97ec58a3e1c4d2c8c1810e1a3b3d3e1198d4c795cf0a885151974f5e3c88b9590766f6251ffbb0eddd521c6ebf7d7d1222190c84c4ca6019d3ca72c752daa42802f57dfdaa61336d4e2a72370b4f3e661bdddf5a2b8714b8f2fb8bb96c96534a798f6af795efa4cd6d9fbf688773fab794d2369b062510490c2d24619e2419a1460b12aa27ac16992254f8d61a37355902b01801451528a84070c50a2c2c9cd43047c0b086504a29e5374f6e562062840e55508e65864ea1c2e3bc10224bee8e5fab51fc54a5544b96268cf820c92029cb113b6a94c8c2e58ef6a7c097f7dff368fdabf55feb83c8f79ee9eb61cfe3fb9818c4f5dfc3c4204e41c07f3ddb2ae879dffa59f74734f9336bb63694a306866c035fa2c758d36511efc8fb22f0bda7542c7a7deb0556af138b5a2f4523ffd61bc9f73e5777420326282dedc1d7acfb23db8e5927ee402261040d9ad896e779b226c2082f9cec2281af50be8b6afa2443fbce18305f7ed17c5934df138d48903ff4a7c8f2a74a833276bef4dc9334917a35d83673cfeb231b0f31484bb4df75eb7974deb7bee547363adf45084708e97be883e52a11e80a5fff0f03cd9e6be5fb17c97759c522f99e68f47246e5f3f0ef5c9cd978487146c51dadf73a845d96423590d65961e54f4a933ff3bdb09b73d22ecda17817ec8c490342ad9cc639a409dd751fb61ec4c2c73ef20776598706652cdb8c9c8a5c2edfe57bdf2c72bd271a59978b46523462514eeb123d7fb67963ed4efaae679b0ce57bcfc3df25067105b1cd04ccdf0104a9087786ad188bdf54d11c1c047105f9bec500efe543c0e554e412adfce9209ea844993eaf7eeb8beab7bebfd5bd271a79dfbd518bbd8732eb56e87d51cbf3de251abd510ed9f6a1d8514693b2497fd2bcccd77dcff53e88fff7dcef7a1ec2513fc793f0c3856c5071509f6bad5855378765cd1df9ea7aaba3b48a85ead67fa13bb251f9f38be4cff9522c7a19c97f8947362a8e3fe6a5dffd9ce6b4a6893e4eab5fff93e0d0044ad8d1e7d66ffde873d9fffb22ff4ff4c4a27e17787dfa369da2e0512ace18505f3e8fee5d0ce2dfbd14833815f9771f447efdbc56fdee6794b65cf5bb96ab25a97cb16e6fc640954f9fc7fc2a0611833815d59fe2cc16a47b29ce5adcf179dd34f9131e712ff4c1f6f31d6934ff0efdc9c73e9efc99fd4736125adc815482064e6cce69b2d6dc8124dfd6ddb5c4bec964322677cf75e00456260c8ac359ece6f67f356883fb61b1e0e5af6003d806eb6b89c81f0f2ad8facfbb76d878745be0c7be88be053bf96c03c3991465b656947d2c55ee68afec6ab70377c04422f5c1270212fd9275fd170bd9666d38d47d0d3656e7777e26ffa8fb991477207993fce9de99e48fd2d0ed5e03275609e7bb9cefbe8ff8d304dfb1ad7b9a31a03ef822d087e9fc4e0c49e902490a7db0f2f90279cd5eafef81746fd47ddf3ca8bbdd779307517121184fdd3752f7d475dd94dbf591dbfdeb7beadea978902b7dafee9d18a8fb9d1088fce95ea7fb5619eb504eebfe25fa93d3baeec5275676bf430ae588b3ef63247890fcee7548211c71f6893c40fab00f521f7c1eb08f7d4c0c421ff66ceb5e042964bfebbc8060c915c0652f3454dd0e08fbbdcf3748f4896f47be828560d81a796ebf7c2f949d2bcd1725564daa246c7e58ec8e9c5f65ea459b78cdc91d193765b2891d6560083e4ef31acfe52e3f20dd1935d9c48e3469e5abff4db6e1dd4343b50e5e5696071848135684115a6ca39fc19dfb00fea93fd20ec0dba2080c543f47093b7653d61bb621654c6c0b5944807471eb7718b6c1ced46a6e8de25632b70e89b9d5b3b2da4d4b4c52a889d6818586ba69484b3714c4d8ba4ddf3def251ab9bef546df473ba1c8f5df090d609b953ff54d6800dbbc6f00dbe67fa291914cfed43fb2c91f69b24619cbb6d6b36dfee8cdfc8f6cdd14ce5cdc81d438f953bfa15a8326d6f5f903a9ef79d666ddfa1a38b1557efd7e924250d599a450ebeb7b9314aa9f58df25d67770075238df15ca5752656a75538c27ab81be5e3ff4c176cf77eca66eaadfb5833b54af56ef755d68821df7a1b973d87ec3c73edf87c5c23e2c96079c31e08b604871662b3afa22850f30d8ba975fd4bd148bea7bfd23db2d72d96ab0b1ddd7df81d489550d0e25d95116fa60e9f31d87d8fc00a5852cacb842c35ebab9964fbe9295d16e4bffef0322979ce6f5482e8d4777be6d59f3ac1c7b35b28698a24b1a234b7a58c346bc61b2a68d99124c29520596272d1e2693c89552ca1987bbc1063254a4c8a0851a2c2c34998207a90c0e862c5ba496f0ab2b5c58f71cde04eba362ce39e79c73ce2b5cb430320409a41470b0cd3477ce39e79c5fceda862e1560acc8a003939929407089818a2b4c7460340095a58817485071e5031a299d264652b850a384eba1c817567ee5ca085a4c388922aa34fd80431a2f8e988200586438024a0b16397421c50f3e504a29a594524aa1585862045a72534c0461a3515c4a29a594524a7718c87fecb9fe3d6c835d72210127a2f0d084e588ac2dce5c5121a74991264fcc60254a114c707028de804e1c0cab01a3d3c4b160198105154cbcc062c604ac2d9e3c59a214849b27babc98f8110f63de2031c40b356099f29c95282a5ff28d99c27577e22c2bd084952d597c81c4cb5499194baec0f04407295c38391182167bd381e86047cb36baeb36b7c99e76dda54c227b5a7727ca3a83da878f4c27c1cc2cce21b3bae7dfb1879ed37cd049a778c2bc3e68d72d95c99852ea31f3147fd0eb2fbd88adcf5eadf2877af2a7abacb2ca8e79dacbf3798a9465e8e38e3b578eb992622945963ffd1e333f03b5ccaeb1fce3ebdaf80a37bc44ffb8c1652019069779f8877f8a2f83feb43b0ce442dc7d0acbfc1ecdc65a5ecbcbf2644e29a7b5ded7f758a8eb2c9e353c6be49c9d0b3feae59fdf2985dd009e73ce89355a2cdb3fca50b2fd9ed378ced7654aeb0b92a964fa94a7052b2995799776b13801dff33bdf231a39ed8845e1fb88463d1fbe518c17ffc866413863c0051fe3828f312bb2e07bde82ef7919e18cbecf1fd93efc97f145ff329ebe0c19ef231acde81fd964bcd18c8a2714f93c06df00b621c5780c4423230c1e03d1473cb27dcfb3ade747598fc8b618e205e1d10c7370feebd705e1914d0cd916866cfb906d3242b659101ed9186cbd53fda8b7257ad50a9647f430a33f4979d0d4070b9de67f3aaf0e5d5716b2edeb20e779fe6370e771be43fb3ce128de1d91e773489c30271c7d884e8b85f07d7ff0bd8f219e7fe1c8253b8ff339e17874731e0724caa1f43de0707c9e709c97e777c2b1efced3b0861536d49138bf131e5d1d71004d03e76738d6b8389f43e684e0e384ae8785e38c1b7b1b8eaf1b13619f43c2c2fa603895427f721a94d3e4c34022973897785fbdf9e5ca3975a5c089ebc18e8ee39c8e30899daf249bf9a79b6f87732e71c7c578f92ee5423df4e53b94074d318718e29c923f522a9c54f207e7342a6a74772d58bee3c44d9c377138a93495a6d2954e257f80b03f451c8e891b1af2260a12e5e0c08d4dc0e4dcac6f119594586105218c501652104e80bb630dcb1ee9788c283cb4765ecbf5bd4058cce2f4effc8e38e67c8bb30f76bebfc551e777de493af9f3849e6f30e7efe88438a1b58285af304aabdfebafcd3e13c76791efabeeeeeef4ba4f2969f2a7264a29a54bd9b49aacd297a27bd3d04567f70ef61da197ced9ad3a67ab9bd22a25129a90e70c0116e28030420abcbe0cdc7e497fb69c68269a2128173e5f57cb342af2ec98465ff67c815becff4cc1f6bc4c26853eb0e67ac19e6d36146301b874000bb832a7c509dcaf7330609b81a890d9c47b4911dc623f5a69cdf39a44cb3a5969ad34031fecce652d50b840ebc1e6bc01c01bdb61411bc27a6aac99322e18f9e23f1c8687913101a83273c41d2d2dcb0cee8e5ffbe1e3037c9cc3ce7f2a9b0a4ead31235bccdcb6dd563a2a4f539a62f676bbfda84f4d5198a0c0708e48dd8003e788940d51a02cb5129813c58b121f43bdd44a9dd4482f9daa23a0a8d1498dd437201f8f14313bd478a48891d2b7ac36fc3e5c14d8d086871914d8d026046daeac466859e5c614793e63a8f8757850ed3c2a291cd5c74b121c6ef776766f3b291c5dcd832a0d8018294bf89005408c143143b5193e9300307c9962070402c0f0458a199271b47bdbc94f4eca62a488d9e1766f67f7b6eb6a53ef19a45e776f6d37e7f5f0a86b9da68f7db22e8da56d9b27853c2b73a197e7341b7f87b2bbbbbbbb650f0ab6866c9320d10efa9ff77ab9d0ab461bdb59f7b9b13c293d2576ac5df953865eada291101b156fd5c9f45c36bda1e9796fbd9a1372a6dbed96c456eb53857aa2893b565c95fa1feb541d13e5e54d1e99e18e526949ce8f7249e74719e5098a0cd51d254e4aedfc28a7787e9461aebfcc492ba43b4a2cd966821f6516053f4e24a52527aedc7132cd28b21f67138c1f2795eb3f71e39c7222eb8e936a86a9e0c75935fb719eb9fe136b66e59ac0b92345ba1ee329136d9272474aa95cff9142dd1fa9d4f5a754b4eaca1d698e9eb9fea61e79a2883b56a5bae4ba6749284d5f64957c73640a8f73ccb4a24bd40aa557d76d236d731dcc94ebd31d0c133ef5a58601c3d379bcc40d2b9705d21554a67021e608054d535c3db504973b36d51d3bccf5aeea31d7cf4061024a0c848dbe347a13099cd8b9a353b9ee6ee5ba4b5d7f1e9dcaddcb1d3de767ae3f7390bdff3240a2ef8f80673968e4d1555421c2e72ff831079f0b442136a71e3ec4fff7219d942871bbe27ff8168044e1874cc59521e3638044322cf81e90c882d78db17363fc8cf19e991be36d0eeac628c3c28df133902886ec08a5dbf31580443db323eeec618044b30a5e06125500c3092617c6530012c190c97e029048e67329c85d0a9e0724a26082097e07249ac0f29009c1e5791d908867c7b6f33920d18ecef398aaabf33820918e276fce5b9028872685867098c04102078704575c1c0c2e0ece5b2717a704555c9c31572ecec740229c21da0fe530c25a31d61ac0e2b8638d6b9f77b8b600d7dab74c9cb9f66555415cfb9fe4daa73581c4b55f23810dd73e0c24b243ae1b7b10248ac196007361ff02896042e07f2011f8aabae3ce7d8577ecb92fa0fb7abdfd725f4b44b92f3134dcd7bb40a2d77fef72595d97eb3d90c8555b60baadef40a2d6f5c254b99e19cf76168009e256f96092eebcb9dba25b90c30fd5a65ad65e4d8937b6bead696ee5b9b5d65a2bce6b47833bf630a18416258a48820a1f3276f4e6eb460d246a88a105092c544b77fed3a8c0dcf9b5249ceefc184834876aad3a2e14e941892a374954f02d7aa0c0823164a6ee38e34b0e253022052398b418f1e68826ee7c1848346bad74bbdd54a0c2050c324dbc6a2c819bcabaf3655ec4dcf94f4408ee7c5a8d0821eefca122a898829a536d9ca25089c2218b93275c8b2c3cd82f83a924b7be8bca13b0560008d0c5aa4b955bdf135d40a2c9480d527ed022eb4a198f893beef4383144d4ad5f65530529983441040b524800e5a6cb08902845820b9b5b7f7a7fc4a44d15140d48a84052c536b3e8d283102f0baeb0a34cc6369ccb9958106768b398d99c71a700ee9c5235dc2995c59d5c906cc982021d3c18920b5f0a3930890bae214a2fa6262da4a7ef07275e0a2e235ee850a86a458d515289e0bca8354be810ac6ecb902693470a750b0c2f48f6a6c7a30813e52d4d30f01882dba225061e448e6c19f38407529519a8cfc1a2659dd75a31e8d245959f2bb82ea6a46c8ccbb82e8ec840073bbb8ceb220d00907851e40d086a489aea1839cfb16f31096e7b9e4be9628fcbbcad3c07d5583efd503220acec89359a459250e188cd68e785b89b9bcd29f66ddb098500e0c8cde624e5b374cfe8c8858923900b7b0fc7791ba55190204284e0ae7f8e7b61a10907f8e28bac5166dd9ccff910bc98788209fdc585b12d278cbd5b715ae3a0947a1022013cc536e86d98d75f6e5aa8609edc51d4223814b19c7f82ddd35cd88fbe060ad49b9cd0b1c00e625c173dc74057566718c8a75873fb5d7a3206732c35b718cc83c2cd46b080d3ac744bddfe5c4bf9f270d655fe04d368878281fa5b0ffb58ce83d03f9c56c28f9d43a32302c9f27ba38f348d2bb6e1a9e11bb06ffeeee839b631bbfd7e866dc8b7dfef51f08dd8f7fb146c23e763b19b63a517f6d591b173476e57e574ce2879100bf510b7bebaa2e2b97ed3d2c9f11c15da9de1343f83c51dfdeaf663d52072793be8cb9de3a07339e618dbb9b66a346c038b6db4d886ebfb3b8b6d7cdfdf6fd8c6ebfbfde6485af08d9ed234fa463f358dcef9b1dddcfec6826fe4bcce8fdd05dfd0f96ef2254953b8b86cd886f7bf5ad7437965d867ae988172574daca3601a7cf93be92a754e071ba3ba7df908a5db37a96f3495297da3ab9a46f78d1ed3b2a6536e3ff912032931902f5172fb1d89c770fb1d06a6d1af139e00fb1c49a56f3813a6d1ef4e6e3f0e95db6fc39ea2a3601afdb0b0d5308d7e306c2ca75d856dc540cd40fdadb0730cd41f463dd891b360583916a8aec8dd907076ec1bece948d2153bf6111eaa27dc0eadd44b5cb0632bc16e4f550cc19406ca12942476ec250a8ce45098d24c1de5891d9bc93e15914295a62939d8b19b5e4c8ec3228527a6272a4eecd84fb72e5c18e9e2e607282b33d8b1a126c09acaa2089b348d6ba99c1c1555509921d253fd85891d7baa02aa21724cc034558769c18e4da581522e4d19aa9c9baa3141d8b1ab5e4f5db6c0ea92c552e7fa8c153b76ce454595a686a099424a6275f5821ddbeaaabb4db539c3e436e50688a936423456b779b26363d1dc1553b92bca7456bf01811d3b6b3e2d2d21c40dc9c98e7ecb80ea48921f89620a8c4b1451a2b8442186cb992ca52558ece84a4f309eb8c0d0c40506325c9450e1b2e4c51214253bfa12ceed892c24a6284aece84c2da521d24861d5e44e831d5d09b7c50d6bb29ea8f8d304538986a7efc6a40a282b382911d8d1713bb928235f0c29e253fe658a1d7d6a4c054a5262c24889b9024b4a892b29313938958711c28e4e0584a3f2059557f918afaa54b919d8e0925879cecf006147cf71172afa06046ee5576e055261ad5003c814b502ceb1bc0d0f7674ac3617e4864073c5d4c2a73484153c0c8126cab3fc4d0d76f4ac2532aa2e5a246175e982885c973650ba643d7143a2624779a34f4833507961c591a4263bca233838a9b42489ebb66407a5255176944a4762514837798b2262064b0b17555143965882e2831de5d21230b70549d29314a62d48ae6c51ca3145b9c18e92a975cb59110595155c344d81623f6ff965eaf64b2a0f9ae0f6cb2c59180f629c1a9c3c63e5a3c4926fa6740975fb5b090aa766c9f5ef97563c68e6a27c725a3fcf95f2692a197971b5aa8c81fc9bb3f5c29b5b94239ae4a465a85879b57a6d6a509222a5345de1aca865802f4a3cd95ae2914d4a59ef63205bc50ebe1448d0643372bd908ea266cae624ffc8f6b54257c82091d7d55951eb67452d57382b3ab2e590267487d41582ecb68701d9ed6f2155b7fb1a8edd74ab27a56ced2ef4414122da6275797786de6dc9cec12e1fb3003e9642d236a5b777f05506f244727a908b3d7ec82bc48fdc35f0f5f821af8b33297ee0cf01797bf077df78a2f365f28786423a2b21b52648a86c4eb3fea3dbe2cc028d1442e34d53968d7d838f4e1ab29a2b2c4b36dad5f7c49b90fad5c8a9fbfa4642e8cfefaa2864be73d9a0ff6397019070b619b2ed897ddedddd3d0f62a64dc76eda83d28e763de83b9deeeed5ddeb8feeeeb5dbdddd6b37adb46b57698fdad5aed2b047f557ed78ba5e7ab35dca1e3de99c41d26ff4ed1eece8dde9cd3b6ba55cc1c06030180c06832989599c9c17ceeb735e39e0386f4c84812f58ef4cd17df7bb9444b97f9dda703d832074627f77fb9c507ff495df0ce57fde4f7faff6140c21f43c1cf57eca64d68e5eec5d9c9e373de8aff733304862bbefd75b80840bb08dee2995219359ae79907d9ca73fe441f43f1bbe9c063e4e689d063e831f607071c4e934f073b8f5faee2c4fe81b0b4fe80b0bc7d605c597d3acd36efdc4f979a2e7c9efeebb47cb1934a5777b3f767777777beeb3d66e6f47a1e594b8fbf1abc3d677e151ec82633803c17bdcd6bbf75edf0aa86cdf762f1cbd1edefb4f30047f31508ebed19752cfeb72f878c4583b4b782fb95852e537db70792f5d9fc33de48077fd7d4e087ff4edff5e14a42cf4f2a752faccccf45be2d8ba14e7524f1c615cda458a2fb782cb5da4e0e17eee7d47df7bf672ec6875debf14caf90a03ff25be2803ebf7f55ba0582ba0a28e1d2dd11347d98591b3d369948ab30edcbfe6bece6377fed49f320dc77eefe70c9a72fa8d13fab2e7795ef764af2b90c1f673b7cbe512e56d47a1a707fb150463f9c71d7da36f6dbd8be3bc1ce8eb89b30fe4175fb03b56cb6d12174873ce39e79c5ab6d8c2ca953f63c8c7837a9aaefcd7e8197dec3352a52b9fbfbf7850470025b6fb640d17727d5f1084f92ed1fb1ed6a0025ce2d823a3ff8130c348f90a7388bd2bf6333441c8ed76f6d2fa1efc75fd9c52a34b9cb99e8a2f97e89910bbde832fa9c658c936b7a4a5284f56a6c2e4ae661645f22047727ac9a90a8220deefbdbe1fb712ff97962ddadcd77f200852ca693ba29c0af9b6402b85fdc04ff080afeb3d68bf2d90081499698cdffbbf9e411082dcefa7260882df4f94524ee340dfeebdb0ef1667ae7f072a20769981bc10e4944c8281644b34a1e594d32437a5b0f9359461c620774e5152814ad851e2a86efb3355f29c2633b3bff4319fd2e94d3e376faeebe75f5da0cb5adc58b99fbf725caed073c8913c612e51feb844ef1369e174212427ef918abceb8bd06c4eafa7dff77db1b0ef9c733a61c71ebedf2be4eb66ca35c0652d592c5ddc652f97b56425dd9d1e0f8dedfe73c2ca6f70becbe572b93e27ece77a97cbe5daf120970873c55c2e97cbe582c580b03d4ef3d6cb157af7f57a851cf0ae0b043f19c85fac000c247362b1e9e5844e385370fea3af1fb621f6e070c99eb0d8b740d87f1ee8c1843d831dc4fe85a3033bf060de97f862a059072fa7bdc41eb18379633171c86931256ceb7b7a767660b158ec5fb1900023b0b1afd669fd31716708471c3d02046169072fd08a218c7d77c2eef6dc0edc715ae3709a1c62200240d94f1c77ae164f974b70594b9698fbb95e5ec89f1376945d097ecb55410d33f687bc2e79bf594c3c0184f9c1f7531c5dff89de77f70b47ef8b8923901b73b99e9dc6379675edc73e87bb4ce8ae15c7be31317489a06520091359bccc409d43ce5bb6f1bd74fd50d390eff964ff999f681968fe50dfc0611af3a5ce7d39cd479f11e7ce2b5f3db7e70fdba8f7831f06ea8fb90e13669ecccccc93999927f374f38db5878164723e9db3328737586571e48e3b35c6da8ed3e7015f134c9897190887813c7e859681b2eed853c1072c6bc1c2ea71d846d8d7f320b681e463af49e1103dae1d43b519bad25fe08338682fb3d5602199ac7910ecfbb99b89ed86751048170693fd912de719023c3fc11751f032d1c8a973c471e882df6211cf4f70646b71ac5d1004c57e863a73c10745761a4ccce1b19c3f22b23018ec3de070fc11c679753e271cfbe63c2c0473421c9d30f63938e2009a46ecc170ac71639f43dae9b41a56d8873d188e5c55e3824d60e875e883abaeace5b1abbe17569f41b33b12c7bd2b7dc4e290695d66c22acc6526aca42e1017bccc84150cb73bf0b1cf38b9fb56add5937df7934da92696bdebce0f5609c3ef41f6c5b2d0c3f88ffc0e3f9c170e48543f4cad46cee34c1c1c1c9c9fa109325e5447fe13159ec1a23f99d00e25f54bec3895c239c36e9eb7d3dab73c9fc33bb43f799e41229ecfe155f729c0c1365cc8a9e48f95424426f87f22305e06052f3e910a3e94fd054f64f616e4b8209cd1bfe0637c18ce76c470b623ce18207ecf1789013a5970d04982c5883539580069795d03a1b33618207ce5e5ba216e799db367bd4e66ab4e0224104d53c63ccd97d5837c24b7bc4ec7649a2c6786b1afee641b55555521034d1a65ecdc9de241f25fb46f592daf6ba6dab7acac2c20f2a78d1dffceffff7faf8a40fbaffaaaafd2d18940fbaaaffaaa87c23e791015176a1f206118ef2f9e959595e5b4fe2e060f1f5fe0052b6ca6d8e4961cf12d2ee042ae25edeb738d08a49c4fbb70a4728a3d66276957b1c7a44dbb6743f1e4e30bb880c4e6089b26595417545703de352176fb93bc7c7c811a97a358f8d242d3e5a8a42fb788cb5149b7fb3eb42f36ad6efda82bb26e157ff8dd80ec8e406eb7dbfd21bbfd6065a6cdaf5efd49c51ed7ebc6fa7356b1077d797bd4dfd9a9228e2345a46d486773d2c0bcfd7ec3dd6eee21d9d1ab4924a8e4ecd9fde524e9a0ed124bf0dff153af43fee8e4ecd84c5f241353333593753925ede7fcdc71e24d5a86d61c34b5eb81a5843cffe9762967cff939efe998f9d19ef7d211823733f1d43d5826f7a1c5c4403558a6afa1953f4dd5a3c4ec266e1eda9f81b837171b05a621bf134b903fb2c5212530501776ec269ab73463a96fcc97efd1a858fbda6b799d7b1e9691b1ba894f5337e91b93a984eeaef94f0fe508c5a6d15f4397459cb9ea2a69951ba16fd06a7fb214ea3c76b968dcf2baae25d6e48f7ccf7a9d4ca4c91f1d9c1dbba99b9a264e0998cee96a9da41c1e4c24aefc190e154046bb4193d17288d8916941e3ebe6c0b96c2c175a2707cf6b87d2491e340a09b18d66a0a6c91c363de5ec9e3b4ca64fcf0e5fdd4973da1c3a0077a131d0147f6402b8d2935db1e3506d2866c3c7e3bcfde1153bf298dbcccece8cc3c809cb357a54b02c8e3db7ad1447a32b9f8f26f3d16c1ad51ca5c29b2815982e6d1ba54c9f7ed75adbf5dc6ac960f00f7d119cd632cc62e97fb114ecd838cfb356267b991403d13fe3340f8d8dd1c48eb599fc7ae79dc9e725a2d8e2f212516471c7ce758e568a8bb1a455633e076c2376e988c325ca1888fe055d58cf72e541b866c25fd84cf887829d856d34e8f4c2e152974b1c5b864b41d90a3d90a8d5b53a113665297d0ba0b0f5ebe5a823315c7939eac8d2a5f5e7bf6a388d3e1dc01256c7e5c0698dd5420363ce29ddddc5277777779fb25f3bd7ffebe934af041edb609e724e1c9df8441bca5db5acd166481bee58c39d597ef9d8a756ab31820f1c595f86a8aafacd15bed16a9886cc72c75a96cb625fc1a8902de6d0c6835cf4b1e2683ef619fdd603a8358dda320b856dbd477f874cfe8823b05feb86be7f3d0fd7776290ee5dff1283381575ef1267fe3571e6570c54bffa19db594eab5f3f0463a5486b2c97c8a28cdb1d964315bd5a9349211db52a73d4fc26abbecadf1c634ba0973e093e74882085be2394f21f61f9c187bdeb3f4f6cbd80c81fea33f931ab99c46ab562e24bd4d1a2af1cf2879e2063a06efdeb257d5848935d38434ffecc8ac07f3d28b2fc697f7deb5f624b647feec0ed102b4b9039a4d0f7f475009142afa7fc632dacc91ffa3487d653f6a4508d7f78aa255af9c37e3b246ef669320b8ad8d90e24efbbc7b97d5da3cc2fff8de5cbcabef043990cf6fbd7fbcf9d1d2cdfef5fe26cc7f7b306b0ed13dbf6fa198fb6bdbe6d2ff1e58f8c81eac7b6589907dfb7dee8b50309c9f52fa4d67fe26cfec7b8d93462f9e3fad6cf6fb5fe138d5aa251ad32185aacf572d487affe67a590b4d51ffd368d2a59c643cfb2ca0069eb442b9fb0f4bfdb1bcd910d699e68b24203153a8c913514b1446e49c9932f5524c9a4a8335777e7725411365a2e3ffd915d0be36e0ffee9ce74ce661c53dc01986760fe5cccdc62af19a873af9479824c93eedea07706c6175632b851410635b43332e490666882f1c577b2d25aa3ae9248b232bb237380124c0188ba228204575277b4566677c4cb512c48b16f03922dc858d855065b2c5826032d1654a2089b7339aa0a2e071184a91285829cac65b437510c9171396a851ab620411249282811c3840b2637de9021b5d65a398082439aabdb11596b240d4542c026290d45e342eb7294162c53522debbcd25a690650589ccb5157b8d09454f941b2f672d4151c9eb8f2441645a4086965aa0c915a6bad33cc550d449e5a628604c1c290145ddc91712c1525451452e48cd4bce63f4e4fac60c4c2de6470439b0c6ef6438341d513187861e9e5a8dc981f2ad6bb1c950bf3349b0c5551556e789f28235f5c7a390a8ad51dbfd62447dfa33e6ad77a33dcf16b90e18e4338b424943b32d55208eec863ae3c73c44b142fa4a2aa9031442d3de9d45c5145d2940a498419e248ca1b23382c490551440b36f93aa4900796a678818d1a1e8c28d964eeda1ddae5282757dc9ccb514e7277b44f83068c90220d0f52acf04413f904eadbc242adb5562b48da90a0852e7e6823612002ea85c90313921e28a53074435c86247838628635e4b9bc4f9496a66b2f476959bae3d73a2f7ecc60f065c99f389a21c907334850b88105304b6868152d545beb981699289076d6b82e471589e2c2b81c55e48b10b59ad76ad349e9a44961e5e5a8225eee68a558bf1c55a4cb944e8660353de09c308249912f2cc8265145b87407966680c10b93149535b65a8d2a92e58e5fab8146abd59418695fab81a10245052a0c946432c40a0a2570814c0a6b9a904b34704314370481c20878b805e15794c8d8e18b2263b07893c3937f2899e48eb21741d21434ec60868724ff503cd29ccd1a2b68b24082839632b51a184fa3064a22e112e4b0830b6c567022428bff20388cfb5b28773327542a31c0a188353621ae289bd3f48cdc0808bcb06213a2010b36a749a9bf6ad83c30b9a264933571c6a37e97664c931b6c426057b6fa9d68d44e048182954d488e0bb62ad27c83fe23db375f7456548d3c230aacac10c2260414c25637e8d0680055aa18926513e2512bc860abf906fd95f61824b26461a37da553d4154bf787bc19cc78d059d39f4f43ebdede3e1b0528eedeee2e9f711fdb867090f083032a574a29a594b286d736f76e8b3ed3e50d1ffbcc781835154fb6fa4e10e89ebe37c666f48db159f913847d79b98b104977ac5d2995dc18f4c18eb22b7f2e40bb1c756b73a36e672e47ddc2005d8ebae1703f64a11ad45208bac45045893636f90d82d04d10c672d44d863bdfdd8bf8e4532674b87df2d541635df1847e138e6ef747dfe64aafb790759b1d69b1eb1f631b5dc17510013c639c2fbf7f8ade112ebfdab5d2ee64d470afd49bb8e8b47d8bcfbf63a07ec97dfb7b6ebf8e22179281a5c50b2b35866ef317e93c76fdafdee9d806ffcdc969934f5934b998b2d8c273045600545d5c58b20605ef65e50e76b4ddc213160d48724aacc87a7ab09e10b164c8fb2cb1e3d36684c08eb44ea6596a951953ab21c58eb5dbbca209d7550b433898ec3834a9a8b49082d3224b0e0e60b023e3a67094bc48c17991e28497262b2f529ae84840163bf2540c8b6a4892253b8a6cb0235329cd2b8e7c57ec204204b6d891ab3e2c2cb0a4a061040b70ce958b62418a112324f880b2235b794ab92ad250596151c28f2a7664ac1615152b50210390a114a884ccf695412c95b2810000001000a315002020100a87842291480ee4d1b87c14800b759852785295caa34912e428884106194000218400008c31c42034662400841b56c86f71fa51417e37e4a71efd4006fa43a135d3dd9925766406335d98e1f3e42b414e52679ac03f9b8fadb2dee55c91f30e1778182846c5412f0ffa798402a4f097292e3f54c25f9bf50c5a21bfbc262d9f838ccf13512bf4298100996c1df0280bc341994c870ab3476634a005339c3ac35044545f0142aaafcb7d202390cf0e4619ad6342aee4896ff35f326500502460c97e021613232e30b7204cbe25e8d5798ee4187c6478ed99443a591507d17ee3f4044db28af9c22619afd3a4239f17ec93c277f28adcd5b12617c01685ea8c298b4fa3d65432d88bc90533c25157b51de23d6e2949123f0c450d880224a9cbfed72488d92710e8b226ed4321e6827097a4e04bc62e2e0a1d64c3da301fbb474a3afd9bc9cdbfe5fe9b20f199d9f0a907e4e9c9b7781d3914c58569fa7036dea1014008d1ca956e1b0e3c39d5e9635d5bedb8c92cc67d04a3ffd72f4696a91e01014c7d70bb6622a11365cd44828e603513073a02a899d4b7a23e85e5a2bda008ca259ce31112c100d47009363ef61b191bc7c2f60784631d254fd276a92219cdcb8de3125580c78bf433350ff14ba7523a0f1c12370fb631cd1d121e115a9be519f7dd5c922f02fa60dc1de55cb7e4790180facc5afa2332de183dce8bee354b21b45c62d69236ef2117f24b4405fee26f65e12f22c25bca9ece60c8e7d7dee37f2c11ec111aec2cd05792923b459d8e705ea15603cdf780e8559bc0a233c572a11c44f6df3d4f933733e9aca49e091339e428d9152f693fdc3274887c1ed38afac03b8162d70c32bcd8c4cd123276b829764c4c55610929aa9823c6b90c8ce21238edeb5e85faea737c4667331cfe8021ce1b669c6a789678861770b2a3962896746e7d7c7e501f18f50377e6323d27fadba284e56d9c46440ddd99b80e0fb7f5790c79193e6991c8db54f059fb01842936962dba14f3a73b0b4f62b1ec615d9d9c4d6d16f8b58f5f86305e517f4a1e0f6f61257baaffdd9b5ce6c01a6f85ea0dc58fa0ea13706ffa74c43727a1352e52f47229761169b983a3e23a562d7721af8002cbb03f866f0426f1e1801f62f99bb2933ba87670e11faf1e3b5903e40da79c3c87b1f4f819f9e01842de0b853f88576255d8a9ed0af895fd66348f2a07b3a5088497b9551c71de3680ae0322c1aa22931084f63b6492df2705fa031976583f01e568ece8af6c4d79ce5f5c59859e18135340d925f33139bc3a3731fb57177ebc4469508db24e289f37635f6008889323ab619f542c1f4b14be1d67b08fba2b576748c32e764558742cc1c40d583fd07b256ce20f28c3484c020155d8c8e2adb1110e8c9e3a4df7c2b33e58a9a7e91b64ea71afa9de5c7a1477e44288d3969f0dc465e5303d132924e1a10225790e101df415554b9efb7343201ce30b3b7ce9b45930a0b5ea74e296274da48b24628f4c94f004e06a5c089d88ff510c7d32d020ce5749f9dd54b6144708df323539aca15de33859670536ada3ee520a7b26f779c21fd5ae9b08c9298dc99eaebf440c4ff7e789ae30a8d221a2818c72bc07627527953e2e6e5037b9e2df569de38a95a5297d9c4db126b4c17b7054d2185549476bc3a402612353abe2e2d53945376a5cbd34cea40eb305f028f655648a4db4fefda2b4b67bf9d85739d13963ec899175688d8a2d0c33cc15831e10040f02fd3d316878e79a528b78a0c6435da6c25ce340d11c9fbc71456e2794791c94c214d9052118ed20add31cade11088cf3a407de4bbe8102d7d28132a9bec53c4881bd99f47398332c0cd517ecf456fcc1179316f452c7e6c3249c4a0165eba2ba422eae611a5465b3e8a3faf6b35cc5c1a216b649e4bdb8afd3077940ac2635f7eb166dc10edb075d5e1735021fdffd40b51fd28ac28cd742b756b4db53133ec632cb56f5942347191cd7e6302f14fcaa6645482478598055d683c69c1a592c3f6ca1666aeba3d043e40afd031d11c79084d629c932679ad7f8e465826f199954919508baa410c204cca2a60446307875713040b242b6a223352e6452fc5b9374f90ddc0684fc98add717c36c9fa0111575e43c2514e535fab39d6392017714691276deab6621e547308212a62ac848a8d78dae616383eeb0f4326fc1ef4b460d6060eea79b96318c8ea79513259e56c95160e62cec5ac56e93331a81a1639eb4b8a6a687f4c1db40cd5850b11a45db9b946fbfd284085c10500c37e26354723ce43e00d335e227acacae44a6b3539f363cd35fcc772d8726ba3f44ba304f0c2f9722b894eecc9c2da2496672c8770a2ca56c63764ca5738923b8b37d5c42a0251e6b66d6c7d9abe487c1e7231dabedab3215adff85e1fc7f6513aed6eb14bcb70c19aaf24ad82d413e364b531ea42f54cc7858d969f07116be9bb2e0300c32915da84f61a6b1298c5472abd8e95228a1c660a62563268545b54ecd57ae16fc10aeb2c9eb4855e941ec079276aeb134b1c76d03d8f5245b8379f22e82b500939b4bc17639f547948145660c96af5ce8a391dc34fcd46d3fa2b3ea23c6745f799f3c4d42e8952de67a925d8f1189692d24d0f8049f239026bda8b68ce7d62a5c0ccf09ca400f349a7631529ee4e26e7332fc4ca9f623c486b32b20edd172fccb7354c6d032b3b9ecf5a5cb960c5cfc7c12ec65bbbed92983280356d989cbb4ebecd6569020aea7e20352b3bb2fb69aee8a6a51df0d067ce3790361571e73820820437ea77f28791374a8904907a70ad84b30595491009b21887301019d8cde5688095ca3b56317d39894ddf196e1128c5629707ee3949ccd528ef7c4e7a0754c231dbac62e0577390cbd9311f60ec3cb8e96c3d4f60a1b4019771bdde4bd4a7e4b780071829878b16304288c69aebc0d34444f6ad1a07dc9f2a3083f214f54b53511246c4134be6b180219d9fda0be16a1c4d1ca6671df8f1d72fc22fa607704f52c9c810cbce163c7e8bc8843a770b96c958ae5387cb6df7f36b210fbb3459225f06b83e6c7bc8756f9403ba56ccc47c59043d04d3b750a516e60f56928e3860504956004554f6b7a0affb84a0b536980414e880133edd9fbea08010fd5c0918a1ead00e6810c51030e0d6e17c14d3ef862857e0dd2c503b7db37c234497773a5483ec6d7d9fb7beb43b7cf25b7ac86ef370a2c42ce03b60848e6f18930b6f9fe19961a6450ac39d9a55de5cb6943fe226ca981a68d77a989aa17ab483c4dd957bd2ca80f6e5f9f61c0f5a5f5967b02d7f6161d0e58a7a2176bc64f8bbb0ff17797b7a1796d40b092b78d907b9970055e4537e2a6e3713772e07a58a7a326cd600c2add81aba8dc9f1466474ee7e126fe0e021300c97162ca537083d4c88bae6313e61c46bd7ea07e456504707cd1165880b636213703c068645cf205d855307ced1c81043a691c2351e6e571d93375ecebf127be3a3cb2c2094cb8a66d47dfdf26071603385f8661f65d099ddd7c22648f6c5e861de69184ae19ca63ee7a1d68607f56aceb9e369b12e7b1ed37261d9dc1361910e633806d77a8ea7a067d6cc101f39a2503ef46247f505726e242c3d2103140f401986032a030bfdb7ce5a6b1591dbf6381ea31e88dc47b03634fb1be460c0d9d7d91d7965e67c9e70a5c833de5d52cf12f64e94ce265efcac479f97809ff9ba13cdb4d7094635a1a63fa04eba1b1b1d3b71b3f2c2b2716cb92b0aa7922872de90d4be1bcf06ea21cda6653e7f2df5f3aa0b33ebead26ab7618e26cea3040d8b83406460f79390839cf83dcb63d26280333194036c26b5716aa10542667907dbfe5d3f1197b4aa0c4e85596d297f8527defa46280de22946203a49a2b48b363850ff260061072a49e42a7aec7b10d5b4e672716cfee4ad125bfc9741eaeffb3380c34cf02faf2be702901256a5ed80e4f684b87ffd87d962c46bcf7bc11b667d728da01e4f5f17adafc0e7e61baf43e3636b695266a2433559bcf5d7698fc913c59b518aeb4b6c66e8e8c37d30ef931212733329cdbfea178dd2804411f2b6591fffd5144a787f4b3cdb8cfd083257d81bdc4edac8fe5c2844f8228b6cc45da57d72b8fb0f62f30e42bda5dd50fa2e834090f509caf7e35bc5a4d43ba829916776256218d8d43d1094fc580796356c45ef880bdd476bbe9e933150892ef8a81b897fa46de126617d52c23c9d9d0aad823cee0e4f2bbbc0758b2ab0ce0d4d343a89d4779083544521a3b80480319c6f7d9587e08064381416a74e492478bcb0830a90598b90a2e3c115ded0db6fb04a438da79ca254c54bd77558ce2612800a7db2cfe7917076b8df4cfa1cf1faf20a668dde5d128fdca12374ec36fcbb1f77f7f1c9ee2bf12a744b6b53137edcaa9b776ea94f34c1e4cbcdf2bf02092e0a691e2883f16c852b119eb012640e7cb697426b133703df66e6615fc8753cecf57e28ac8ae88a6bf800b5da25343b89b6f868393bf0c79ce2719fb825b9568569be30bc3d5806aaab6a19f2d056857d275d563211d0c11d40d06f65d7a260cfcbafea4a6bcfd422c60ec284abb50a98465537bb4a7c83322aa591b6429b3a6698913153b799a0bf09cbefc7714b60b7ac6d3e20f984bec3620f53ae44153540daa67034fc85b09aff1f29cc015478da5559651122ba8501a67ea0ec02db71dd865bb49b381374fb84a23e44644badb7f17a6c4f606f6befe6b6f89a0510a10677bbb4d7e9e165010e3646b67beb85eb102a628ba121075705e536eaa2d6fe55bf0fbcc4250cf007ea711cfe59e5b6720850484d2890d591e5d12de986e75afceb10620b96f6ac0e27c8ca34fe4ca17b1a0852b392455912f45817f39cf02a968331031c823ed8e022c0d06789c61eda6832e9c192ce590b5ddc885d74fb570828880086f5ba29124dc73c9e1f18f8cb83a1eecc8d51ffbb0bbfbf4e671ea104004c4a97b1aaa346a87e02fe9373371ee006d5a4d4012c166c0e3f40a72c77a96bdde65caa49d3f084aed6f65c532abf408ae08cf3b513491a7e09140d7355c89410f16444cd855626314a3bdd0af929772252f17672207cc8239ddc75418d3aeb0e598d4263cd3eb0c4122b866b042d4fdd6cd32b200b0ab1e8fe08f5ca4dbc302807c2cdd494b91dea769564b1aa9d4d83529d1d786f471db47f9dbf812c3843e433611dcd4b07391db4d6e4db7ecff3cfc0c1ade2f451be34cf7d00d86a482614d1b015dc99437ab043756346f361466ffe977d8c6a4bedf4a37414cf7f8814a98a06a4d11ef139081432eb85e856f033ec62addfa2f91c683f52f6bc17108662b6cf4a899fcbc4e840b858fe3127d9912e4ba84352f88c8d34b4338473dc94c206deef759957c90157d712a0e534a485a8ea755d2acd8ff22b5ec754c21487e5d96551e275b10e20338bb0fc243cdf6511a04d66dbcd9a0c59b1657c9a924c78be832b1242a65c02f041293079ab2c598aeb600211b909fbe694ceb1a91faac3f8037dc370d8af630e4637d8644b517309f9074aba1c8edbbfb857cc617e972f10c672ecac8da1ccbc7c680d4d8e38dc6f83865446736e90b4b6540e1145a7e7d4f201833df2c22317721320a43f922a629b197460b21bac26470e3012cdbc5d384c5bef5209805648a41a4c5126e3c7129dbd1d48718bb316f71012f504fe1687cbffa8358f0667e528e578a0463ab8839ba62bfd36e8216d8d9fdf301723527c20f87cfa612652e6f657fc92d57f98359e733d481e8f1cb9ad14cdf7f725920572c678782d9271c8733aa1629a9c9dea4012e5b0e8117f1bfd81c74324a28d92661c9376196bb0ee04e3883889fd99a18a4131d189d9a0ca03e73d0d6c167d53c7f58db13aca35a323c572473bd03de31c1d69aa4337b8a794cf5ea962fd49c035137dc600bdeb23f5fbb080f30e7bdb3c5de8a24954aa534d0ea27fc20270eede74fc4d270781c39119a859af32ccd19c9ef0875032448bc93808db1c4304694485f53b4dc507b52879a027adf3476269a8434272bd12220505682fbe978702073925255462b3a5cb14d90742cc29592266dcbbf28dd6c3571358bc6428fa28993e333189c60b9821cc89f813ca58b0c6a3da74fcf0387f888f1943a1e3306ee4854577b25500dd28a84ac5fd1026f76933435ece7f38bccb0ef16c744284abf84f3a24b9f03d81a3c09449f6e2e7f684ae73749e08bf4992cfc9d7e4e95f3045ee15746c3aae5ff62b10cd9fb705b9eabaad56ebf5e1d2a4f975dc27965097c833016d59eda716530ad9e29e58e2f2ba171399cc3303e5ae3907584bf5346e6b119f0b0a9fb2f5a617bdefade95f4a36e2861a4ccc047b3a3f655b4ff9f65ed139f7c1308f32a22c6f5b56c0d38054d024fb26ad4b7c6220ffd7912ccfab37b59590f1a3490c53afa5870b8463d7e6251a9448d575e4327039a2416bb65d25cfd6ee136d595e6bf28e96b60a58590a805f166d4d0c8ea09eb431a81be04dcb6a5475dea07f0593afbc7dd138a9ff99aac9778bf440d3e8473fe34a663d0c018faeb09bdd5c1d283ac464cefbebc942b49ee6f4bccf3c2e59248cd7bd3c5c0d93c9b68e34c70403a73e2d839b36ad4b424adcd7eca3a4b34b2e4aa294c847bf977559c58eee92299ace0fabd21d7439c6659d7c74ddc78e9d0710354e45f45f6fe396a247be17fb7067eeb344b000787dca4e003d133fd045d75c97e176320d3264fa91324411d3d6080cb99eb2332a26f204cee4d7ce2d8d399618481dca8d8bb577a183f1ecf971c9b94ee228dce1384ee7c76a9715861055cb09a933ab602b2920d41091eb5c14ff15809430c901aaffcd70ecc051e87fa6d62f9a97e48e4a60347f96d0bce2e8dec8ec3ecafd291b9a2dfdcb1219650d1bcd0b4685a4b6302c3351a5f030a799172a6464d3032889fbe1777d41f42a5959442551cff5242c8247a03750457c416f0662b6041352d1435855348f81566769593b1c8eca46e86ae44ffa4eb90a2af3789d3ab3c893b54778742271342e390c1c686d59a22586fb3ac42439011697dfa5127a83f1412d36e3dcc7697087d07b6fa472b9abfa79535fde6adc820c5f0e65d1cdaec158fcb0fceee5641ba6ea5623b95410ae1367bd55a265c78805db58af2fc062916dff637a9ccd0afce96c349867ae41c7a1686d68f056219aacc81a8c291930f9f4602a9e861aa0af51710e05c594434d56445f23cdee64b8c5d43eafe2e6904e97a8fe59b36c8ad1e7e8574ba29ee1478a180d0bbffe8e5db0eac4b47f9f78d91285fa3414aa7293409848037188c0750cd2a349948b7c32795d0e48b4566f7255249f48d56fb2d1785ec3e4934a3365cb35af90b02ec768685ba199072041c4b3d6fc7f099495ae99da95255adabc5fc6b3ea26ee056a445950003afdc03891bd0964ae84e6f6361b98999515378da4037c2b2dba5d5f91da039afa378fc7a382be0079792ae9fcbb5e2920e4514c155eb025bd08bd142b5bc67fc3772fa6feb355d02c50f969b281e43804804b5b01703c9fc386888d4f3bc808c61412de13a3b70e66518e56ec8de304b2901d789effa31cdc8d12331663a1a9c61f62c0584c99f5ddd782158e3df32f5509d191e06bf97defdf704688d80fb48b68b42b0e009005d8361b758ad1fbcbf655c4b2a965449a359738c91ea7f13a528a83880022c893f51020941815c8f6996c36fdf537c9ae3e11272e9334a57a911f8a563c47089a4f33c6b05bc95c002db0e040089ba31503222b6b54525837bdc6966df58548e790a38941b7b28df87bc6c7c9c66860a15913999769cc125ef58f83203833625062ec5675aafb700b489366786c14d621ca9edb5297f590ca43f71a2c93211cd7e7338dc1dd8ebb1015c5d12424470c46a0dd7a8f2862171319cb482092da1a9866e56b5f20afc1cdfa0247d783368164409d05f95807e1f7fdc143ead9269e916c125dac91d2cc0b267fcb641e4c08a28067b4508b77d106fd4849642696f820982df7344ed9910a2004ccd8704c2cbf10917ad74c242e5808f9e39122299a3ff4dc66f3ef957666564a3225cbec265086bd05351c3ecbff9c41219ab8cf3ef1ac58501442b083c09a8d43b26b8d1aa886ccb046d04e152f471b77432816139a18ff6f20edbde91351ce7c4f4be25a6109812ca62dd66eb558ad28fd6decc03263fc7ce143f60af7575d2048213b5011b78ca3e2c78c64dd6e38291b46b34ae6abc1f188057d17296bbbecd5b08c0395120211f3e9e2d588d34975f8c6cdaa3929ef58fd1f393b085bfb0deb11b433c449961c48195ff4011a493492fba7d4e54e94a3c38d1521280116ba5ff19b627d858898c403b4dcb0d1c80e39fb9acdb1b836d6a7605e93281cb1f64746e6913a8910e27abc301b4ddf69a77038cacf1f36a4ca51706aadebe9e0313585adf901482c0de6b14154724ff40308a4076d024ade8b088441d7fe1d17b15bc8bed23921b6101b05f9436b382ebea409e6be863b340cfb103608a87da97775e8cd056c688353112942790ed56ab9da46322977ba0c426af2046bf4025cfa04ad8809dd04d9321f7087b135cadbaf5126dc5c1182421496f8b50d230f5d9a103f0fa1a2d42b4407f876a92b416be125ac60f0c9c10ead93145134cd1cd8b968768bd42af51da46073c0a19dbb405cc30976c1f3874324bbd425e846303b8c8c01542d6863233a122c1144910a8b2396ad987306a4a2dc8273a40d741b60625150922d0167738bac7e4f6b6ca52ab1cd0ada5e55d5d5752d9019f707206290d49b31c3018af200419258098cd159141c34d1fd803ad74a382a4fd32c57d11a932a0c6d9561fe176513e0cdbb61cee338fb54769c20084255b3ded5093fe0783796b18b85d5d93e650f5e39c53e317bc0e881a75c542a36653e517bc0525f5370c68487183b6e3c4f7e9e9ef258a0d67e09474c70c475e761cbd19bc62cb9714c79e9cc13e1d884e4c226f133e181068456373ae0cdae6b2d141dc72b477b0d864a57f5b5d3f32b6bec7e8d262d8a694a030ea07071418da035f40d4bed45df3c18aaefb09817a51e667e81e97d077849033beb4ecf4be80b504de9baba66bca16141bc89bdeab8bd66af424b266e6fb79d09ce85775615d43a99ddef8ad2f6813a7b0f8603ab8f6e6ff9b3064fef8b1843c8915d4616921e58c93593760469b8dad6017e6b289acf31b8b2ca59570ae8bbb622a1538cf7bcd7e41bf59101d56634d39064217d21d63ec8cce3a1b746ef54fcd124607fb34893792122e5cde06d875e2a7330c20383d2af3b07dc37a3389d1ec6197ad2e0586a46d700cd656a339bdc00792a796e3a07131a01a9f47d872938a326074abd889f81f8fad0f2634c1b8c6eac8af67ff9fc9ad0c1a862748e04fad1c8454e6cee6fe83804a0f16f68a6b4737aed674b5caf706e8ac8ef421e6e7f434e799bdfe8426c359764492900d6a7f1742e3a32a0277731c82430cb7bf2c4fde836c50632ee7cffdec82c03e336a1042d3307239ced5b886bc13a23e0a7bfef22c1721d97214e8c50fceb2b4189a583610eda9ad21a0a60866a165a799184b520baace846a7e79a6ac1dc74cbc53c67f30ebfb622a9586a3714e9592da159a5debe8ef376708fd5dec1b17e83d5ebbdb41814935a69ac4c5194d13927bf7fc501a5f5fbd929251f9ec33800c5632a1236f844a75b49106adad7254e06e48a1b13ae4cc0f09463d6ff283e68cd7a01c52720e0c22c9140447295798afb48c93c242df820ff06d70928fc6959be3a16cac9854b572de7f7006af27ec864b576f3b4222d91ed2aab11e66ae912c1040e0a1cf1cdefec6eaa263bbb85ae81c724145f093520014597200a9710d9127f0b3e6601928453910e17a85f1700038486bd8c132556b894455130a96cab26441c0bc9510a2977e87ff002991331f5aa8d4700632fb2f11ddaef0203ad8c14e2cc2cd7dc0163e03582a78a78074d103cc4790f0325056dc2f044b37a80ea8397ebb9581c5d22123415506f9a081e9424dd3413000460cb144a8f093f619971faf6d98a3bded5c8150e7413166232ed59b2a4f099696c62f47a84c39930d26ba981b41aa55d0469519d6a4acb8269aa5471e45c94652ef611a88460bb31c7bb2596fcf65929e2ca36297de3ff4e6027e4d503135649d8fdd91669d324ed39a1061a3439a53a5a60a326dfeb45eec36f832018b5b444f0bf1524b45cdbcf6133bd96a4dafa1c9efca189f8e1260cb2246d8f02c4842406161ad13ed4a55a87b294eb4789fd175437eed5b028727ffe7439b1c3b4962407c30ae26991404edc855c4a01c5b54010584e81680ce4808f1ba314b00ccfba5f19c02ca4a4e14357bfc41f98a3377238f98de8844d1c3ca022591707774f4352b2a1c5d3e856ac9f5660bcb587e8c3580d6c76fe9c396e06ac5e8040ccaa46037549f8d900d9c29c40f96a1863c86aeb7c375f5d3c484fb534902702304fef264025ab229fe65e509871800b224b20ccea288fe7a38787a3b7442f300101b79ce690583384cadcb2546d468d34318fb3280a853cb6d60bd4f33d2143dfd03c062772ca6c9ba4317a3b61dc658da3e35c91a2fc6e2b1552579c52359a109e27667e7294cffddd04a0937808253b7f84dd977f9a1e00b88a219ea7dc50d329fdf0d9d0ca0c23882d1aad09353bb1ff4a53f3250949c67d1da8d420556b4d399de51a0c1dc77b64dfd5c669e6d84efc158fec2313fe629cacd1733c4a5f8c71a77218f2a56950376c64d7302c4b56c31fd3d44959d6afad7bdd39dbdb4d514855c480f23d106dd50844209b0a546723a4c4c82b2f1d71dc3460338f8d59c139c842d5b22de4709c1317182084200a338990fd59f7ce54cd90991d2128454a0823be45aa93e14446f90d808f06ce74c76f3ed2ed03b0dbf5cb80fce8936eee86dd636dba53a6c66c51b567c1262da575c4e3f6bae55ed01830892898fa9578f4596ef081fc05ad20c6c58fdd0dcf9f316b42eff73de75ae1737f10f5f9aa6898b7c8838197a4cffce9ddb44465c92bb6e77a1f79a172ded3a893f17beec8431da52cf0ecc0f78ae3d6ecd3da29eedf8769669d3e9bc7e6e0e59a160110e4e82af2894800721638c65f60fbe3e80b6d89fc99b52cbfb50292f3c7f513bb221f42234d64197a56260bad1f06df318236cea18bb5700149cb01473e335d7cd6ec47d4ae8c902077106287d67db85809837bb821064c9ae0ff9552405a68929e054cb5af4d845b6d342184b55aa25e7efd55e379ceaa9f8672817762842a1958162306ff629d0bd6d6c7e991d61c00343e2b400244c5f483a163a9a76ef38b8e8750e0b07d4be5716ec971e0eb409db861747134338c8989bd4325f3d7b5c999cf7ff595f841959225f04d5d170522941e4242a972e12f5abc280ccb6738669007b59871ce7597f9596b003b41c233b50f35c950793c3a625898fdada168fd0d18c81db19f51313161545845d8db20b339eb7acc5cfe4119b746d671b1e80c3fcb29a0c86b22088fa77ac035a07eec5bbbd364c0d7c4258c3591cc102844fa863353590206604838b78558ecb075a4cb6738bd2e4c203ef9a6990b8077c627f472d0bee8c2140ef111468d8afa022d9d76117ca87b7f562bd0892f16b574a924ddbee141166977844943c09b3e65004a5bf0c34ccc6c60b70d774f6758b860de80cd08d5dae3d0951c5bda3eb9f3ead78e19b26e2b16cd280641c4a320c051ce540433997b337f5f2110be182a954eee183ef8a93ac4d9f250531e5a921c79e78bbde82d4995da489170a73f9e4db0df0c203655f0e52f41305e35365908131867fabcbe1a54d0198c1d001d11af417a6e0a7e75a7fceb8645563e33fe0ea2aaa4c4d84c7b03c7f05ec37e2bb1e011bca3f17df3076dc4ad2d2d242c42ca857cdaed821a0a95438cb5018b43e305a8d188b890adb3504180c7536a90daa81ec34130865db10c82f9501b67a8f50a0c02fa63b8a8ada4967fcd9d7096f7dce32d854e0e25339b217382d835c555f6d0d840f72d0b1a8f8078f55d7afa537ebccdc6a75981a74f60f7f11b600408a7e417ed66b889f940fdd779c7bd194af212853687378f56a0b70fc89b47aebc32dfaff70e392f74382fd14a06f4e43a74479bd371bbf86a09ecbb77bd6acd63e2673d392f61330dedc85c4531316016c08a1c3ebe72060b7a0df1615da352da4b849123a5f0390e3536b2b020899d99ad0c2ef0d9f963e0d203764cdd806f92e8485ad4537bac7756ed400946897d756a569b00687daf7f519e73b75161f0cddcf79cd4ab672e45a6d8e97637a3b2ed1e520a983782752ec266d22ab3b75479ef5a9ef74f5c2ffefa4523dea50a3ff507dadbdf1bcede271233116c70a9493fb8943b903b84b2b340b63109b327c12914cf9f200eb131b0e0df5f7982482c37bf784881c7d8c294221c8b989cf0dfbd0367f07202207ce08d0590e9507db901a2def4478df167fc7801bebeb7633ccbbe3aea84377b533d6d00c90cf9ffa7e20d8809bcdad167cf47ad4ea2790177825eeea966c020f83dccf087dcc27cd05c1bfe448419ca557c94d7513dd0228139b7ea58561c1ba303064f3b5b90580feab4ac661677cb373f9d52d8044c40e120b5b4459c9f795aac1ed50be1c1d18a72703a42ab317bf108bd2c701a955618b240e2fc14c22221085061c28cbcc83c491780115367c83057491b516cb15c1fefb132bdf617eb942fea8cc97526fc2ba21cd3266d82412876b9a0f83578e7faa3e631c16f8749329eaa03d7cd9718b44d2c8429539cfa8eed9ef2d634692c048645e5f2c641539c83563e8514f758bfd2850d7bfe15024421875917ae698cdc1108304ecd83539766e0b22e820edd45121b336072e67acebcb2e1a9beadb84f06248e4f72b0a00288ba59f67ccca91cd94b56cc6c1e8ea77b385bf2c7ce0aaf026c12fd2d7428a5e482a0fdb2362ec17be85fe971759ffd054919a45cdffa348ab0e5e812030159cc03b19d78b2d57be5c076a2d09f54a91f91a49ba38deefc794483c836ea63ed4252b1312f2617c9948a867d6d7c9f95ab61fd6af15f95d66c265bf9a98fbd75c3e73aa30e0af0f8b1e035b13a9d0bb613e8de0556ae00be92606bc95a90ab20462a7cd6b5b9b5fb252926704257f87f4e3887eccb60620efbe4d17cb84c9424c342f989162ecf423588cf36aad32cc19b0b0eb1b1ace3a87092bd070b0464216d203aab6ddef2b2758374d2f10094b4152c7ba5da4995e89bd4765a7adbaa87d5762846d79d52e6621c10e203ba175e7edf5ede13e761c2cfaa5cc17e5cb64618f69853c091ef9fbbabd8b57c9e2d72a14e23d3ebbb67010d8f472c9805423df1e68dcd526e21891d5b0f235e7a59aab86e75f882fcfd28fe8e2aebdd6d2b19d8b9b19a2807349686eb1606dea25cf97b2e587d203232137924fca1db45dd2be7de55b6a760dbb01e5b2661b3381994eb61a24ccbda60bd322646a7ac4114ab145a1c3473ea36a6628a5fed87a616fc3ea760ca41579e138b62731e66143167f791c88a67820b56292353c9f9f318db9a142be455127972a298055e93315f9e548c6518e1cae6fa1406b6ac8f136f4b0a217d2de576672ea170824b1dcea9dd37431707a0bf6a12d411f163bb30d90b5d972394d7b6c32e87b7b5b7b88f6c88e265c2324565f92fcb17008f6c5f9e99323271165a0aa6a81494490d7b935981dc43c5296da0ad648d16551654ee2b7a98bbe0f8d0a5841d2aaad430aa8cda85a2ddab1be7d2049f241c3e5baf1ec8d341b36f8eb49c1ee56083c6d28f71cd6f4653cbd98507081e795a066e226c0fb4d2c6e1fd7fb7e177bb0d390319b4e0948c720ba8b1ae58c6280247b777a7324eb1d57c9fe7330ae227f9e4a49350e44726936775937367fb46b624b6f69ce3a06bf0e7f9480d29061d72c495e0d7b4c9d66289d944857fc37925368e3c34d03429e1e5273bc27918535a15e7336c140ac8124e9c2e9b561880179812cd08e33ce09ea7ac52197b34c9da3aad9435be0d6aa53357fa1303870de46ddb4358694ca249e4632b25d56f4b458f9b0dcf5c91764bf8a94524c589c3756bc0b0af4f2badd46e6ee0ac4e6156723f6f6746312a50495dfe4d5a1f1fc85412b61363b5b1bf5f6d29e1e2c6946868852701d5bb057df911b71f550481dc191d8901a445c12b698ade5583ae67a0f226d1247d3fa6dce4a78a0cfe98d9b4b0581b47b88f36c34abb8e7737964df85e012e77640ca78265a13f4d3428329c1e53f6e152cf4715f8b129145142156d8dfff644233ff2d175d79f87bd37e1948fae2f574b1d274b0ec13bde05ef8db54f1982cc795a40119ee01099662614e7201635d490e7243caae301d912c0b703d8dbba7a78d299d1fa70293202bf7cd10a7f8bbb3bd231bc8a97b0b0060817e13e747687db9876febade1be570d631772395cb676fab1fce95322ec350d9672423da22ea02b930f3bfa90bda31dfd614047feed67c1e4cf11c4ca91fc2f6b74f5383521e5c1cec9e3d81a8e5d948b5400c87f9a0fac49508eff3e1f95911d5dd13f3f1df388466a3af4b1c397446e11f2630b55b061d9b76f2ff7b71885a8ad424ad8f4da9f5b901f5707b438c2246983018866826cf7eade1b921ec3251f5a6283d37699964998d56472bd1a08fe463da4a91ed118af90bf3a7ff0d49fc554f5aa79e38836f6b19ba777cf37f8241aa725dee6d7fc0f1dbd3e059c6b69b75dc280217426f1f3a251dda3fe726e24a0bd10bda449bd55df63cb9bc0ce77f0a32aef85c78d69978e9de58392a631dd21c0dea658065d1a5c2597763c846ac512e0cd160e9448d1d7cda8a5198cd8a825434d4a0170cc266aaef5a78c7d030ae80f136dc41692473b059d04b1e972943d86086ea019511d615e21272599c051e54e458b5873eb3450437a251dd7fcaa5f6b549f1cd2dd1c82dcb680be32a1af7f38f20067e7a249edaf75ff4699cf5d25b52ccf8c35945cedb620f0b9236b267e804141012da3b543abe6bcde1f1e363621ae94da82f61cda86eeb1b2c0e4523035499201ed5ec1933f73104ebaf827eb8bd1fbaa09f829a7206e8369619a47be9ef37f6563e31271c9cb44bd580747ec37cb50f32629a6233c07239cd8ca0b091cb24cce0bebaba8362701d7570b8d13a960d6ba7316ccb9d12737436617e8cac9921a7e15604cb692da81213980b4742882c2cf0d38cfe221b8deae1d01bb26e4ec56486e02cda2b172a7944cc79857a8744533ecb0e5d8d59a67be46712c48ba5d2fa34fac8fc8b3b12f3bcf5a06844ae2c44462761d752a8de2cb38b0018e868581ebacd22690392810704661b5b3536c8281fcb7e1ca7f216892a1b09abe4260a96cff14138920f514a3e86139bcd09875be55d9b45e8a674980170c2731f53f221f7937c9474a400d35900bc75a41ff4d50beef98cd403e4e7b30a89041d6a107bb376dccbb081368e5d5e64828a2e302ba0b5123c048249c60751ae5c747716ec4bbaecfc1c687ee3c34bae01e5ca8c22e1d791f12a72be28d16c4e6efb85c162741b27f2c9d5c7cf704734892da45aa0cf00062c390c5275fb52c7a2f900c1029afdcedd88cdde606925011a85c42d6f3c70af95c399ca9a7322b5cc23e58543fec4ee52a87532d33106f8a4d0167e9b7db2f16e016a0c86ba70fe6c03a712897083ead0d3b31175c331db5963c30408370c08b11e7f457ea44954a54a6f1c15ed771eb2a0fb1335a42967fd05809a1f6c3c3376a6fc80657a9842eda066c91f9fd9043b889f822f83c11fb28e83fcaf2864e5785d0ddbbf60da73b86539feaada1b551eccde7df9deb238a963666179416234587ffa89eb4e19b2a992ae6d68a07e18a672a958df1c69c1f872a9e2c9b2cea80b223aa626b3b23d81ce4a598d2d7c374cc978fff163eac42c84a6c0cf88ca6c279579ded7d6f621ab72e180f5b0279c7b72dbadf5e04ac30d0764834e83d5f15b1e50a9046a94c6fb653af7ef215a08428809b8a58032e78dad5ab058cafe3124c000144920d85333c62dac934dd83c7060d7dacd811dc81ad13275a020e202f8f9b8632577249dc1a8a2dc25ffb727fdcfdb7f9af9ac6ec8a6f096260f7af709b689a22dd2f187ebb73df5e439d2f9361a14b98c48f9eca0c5259abd3722dbb3bbf98b83ca4f440b6552b1837d7aef7c607aee0a78e18a0ff430591b78f62cd99fa314bf7396733b2e7d946b5ebc34d0d86158bc6175d5cdc99560970f34e1aeff5650cf47e4237cca0b53a981862d0e8931b0ef3d8500496e04dbebbbf15ccae0da299dc0fddc597027e4eaafef71bee2d6d74829fe1dbf3d2d7836115a80cc5aace84838ab19e5714dfb010b8c79b0008c6f8d350d3c8687dcb2e48ec269d8ccfaa9d773e7207e1dd28a3857144a4d52057cfaac8bfd41a34321509e9b52c16358b068917d5832c6654647c4e2d305072df04c35b2178bd08b8c29e91a417128ae5ebb95df1a24a06d1f1b1eab3b5b1ddf1818d613909ce3234242c2aa8cc5e163009bd4403e03732846ceadcc36fa935d62209bad635a69c4e13a71f4bed4f81a9d514aecc664cbfc638763add6f8b99ec84a280cf5e9683e07b20b11f1cb0fede3eb5ea69af42e40ec973ab65fe40f5bf283aeb72556df84c4808cb28231132532d2dca7f78a99c857e7c67ef2b1357b28b994988d90a8640d8ed9083d315e71d5162c7ce8d08d4660ba990109ab991ac399b951ce4c46b3fe7873a39021e7e12b04e653a305ba793a54003c46769dee3197f2ad465a298cbc42f3d7a1f480efe98d0253cd95342c4cd22049cbf0b0c267a104c8b33f961e2af95026fbda6d204736b18b49700f8e87a21d096acb73dc1a7ff29f49032c5c2e7a45594740fd4800a368f7e08758f2450a803a717f5ec012549c04bac9163b8a99ab94cd5941671781c0f8fcfafde5279e14be8e5360e18d26e85740bd89085e1df9bc3189fdd34c6e9538f47d061a2c1fdf2529f4b2494a5f0f6de1e40b3156dff9b59f4299844a507cbb36f7bfda9c35454f47b3690986958f46c80710edd2d116c5e0e4faf7c5a68682439bb925a164969048d9e86f2474aba183af13f6dbee1e839e9c36e0a6aa342c86722b6e171280e1ed4e58531ac8129cc0beaa041af085c63c777a5a66e21c2b58b18379948c3f5e5fb3051517b889348deadb315425536fe5dde70fecbfe37a5e3660efe3c87e8ece9576674bb93db3d0b47f3a771cbd8e7fff13887b7bac15735d7c6d9c6ac15dd22a400f3deccc24949ae9219c9ca1e8fc88fd798cfe5ecc8d259a84fd442be39514c7d0b7fd08ef112fb70df9f231362776ed9a766409b8b809b043c681159bcfb72331de75cdd6bebd4c453fd704bf7dd295499067191511415a4536897bb943a6f5f5397ed9a8ab85ed1cff8782a3e889769e5306737b81249517ee2a105479b54f45be9d580f83d85c8039d9b34ad6312d86c6bc48c30a3dc1c3297d855d49ced13e2f353f9e41f252b6a83e72b6afd2a5e7cf54068ee99f2191935166c7d7135db821b3fb4b5b598bb0413b1a30d8bb731e19f57b969083ee6bf340b5547dc0fc121de1d079ac11336e0cc865d22986d3b95826fa6de54a45e9d09f63f2154a6da26dc785d33b36e6004414424fd95dca6682601fc1d61417713aa6a2e0ad11c03e6cdebe24ef83ac1191f5c77f43135db0e3f7fe515b185873d6f6ceebaf125fef4500e4754569303240d40e6d5c7308cb1d27efe375c5a6d613abbd2b196cb04becd63fd8e1612bdb291848e6089a5258991254c0f4c6f4737f27c3e6fe218f59b7e3fdb5423066cd2eed6fa539b4d0018ae4ad65ef9034d7b1592556e7d5aa8051bbfb112236bc6869385e19ced1e2fc2c4db4625d439cca0a309146071687ec3f7cfc94e3aa282c84f080aaab2e4462f841537eaa96378bb74e2c2c7e24f38a3f720aa5f37b4b34bc5d1b2e38ae1fc869fc8b558a35cb6e509670a24a4fd9d024ff6b2d2ce730e0f0359495fcd98a2199ca42b35613db27865dafbcc75c719767c48708733e65b53d052ea0922b1546b33d76cd9b1b0b11bb1b79aed07a20e8c4a99f0a37132c6b86903f556db9130b354698e3303e50c73aabeaa670a6aa297c1ac7e9c66f708fc5bdbf397474a34274f448d7935d8b040285192b6600cd66042fd41400815fa9e2f838c315c1a02fb820c1dfb36d5fcbedca77aad73ce9420e7e52a757edef19e21909bcbac302c7b1075db767ff16e8c933ab79b7ba4b8938f1ee2e759cbd383aeb18bdc883d21b8d03d0a312cb2c307d754889022acca3169054122d191dec1546eeb6b12b8bc940307c36fdb9105d512b5d631ac344dafd65096e51dab35d1c33fb1c1bdc6f535f8467dc5b54b888c6e58e2894fea19fc684dcc35e22e1126a7520d75d736a8ce3e91655dc1e8f46a99cd05c5411d72b6e1ad6b34e5bcedb860ed62310e96a431fbfcebfa14a444bb134a73251c3c1a33f75c11f66d97c813fadfcf0af55f00efd498ab1bb1ca18dda349098c881046e7989b162888d63841172a5bcf65b42af81887b60e9aee9f27b6eb1a1957e6b1fcc8f807642e568621dbbabae3abaa7d03ec80b915f155d01e6aa08f2f6d3e24bbb4c881a49dbce2de1d45f7f999c8336304838de2d3a57db7f23d8fb29026021268cd3200bd7d8937fdd2052eddeb68d8510bf3562438ea0eb21f5eb5611f4f8e6e0871716e786e552e4b480c5026bcc85b7103d65c7059dd30239ea05a4cc337b658020b061174d5c00e5a19ac7c3bc42c2b9310dc491fd37d50451a67aad59a6f12ea4b65a5077e7ea387589955108d7d838457d82c90bbdf0d2ff79627ff9b604de9d2cb55e10329daae942a4c5eec8c53525c53367b1f3e971b63f4a05e36faa7065ac35eb21ae0dd8dac51b045d4fa68babfece59979cb36c54cef4e4363d86377d0d667bf30263d4d70c9f95d620d1a9b1c584bc3f08a940dbd6db17528dcd1ffe1e68d28b54be1347ce0c91e3abb56dda5ba9b32ed448cfde6368f41910160b19b908f3b5609cd833827c990579298fdbc527868f01aa563851f094847dca8644eeb300d19dd419da702f8bd79b2b77a2d210d5f849bf6f771533a9e9a5593baeae695252629a61fb341478dd8151571873031793548503f53791692d5318d39d93abd6cc5e77f5683bea336673382b647829101cc83b2c49405d10a8a50a5b4ac733cdfd8f55d4a2cc36d2144ac51c95a6878a041fe2c79302e7d69b11112d4214a3cc2d6d54ad40b9b08953842f1ae0352bd98938bb615ce3b9197a8b39e25fc62dfc7ef784695315aceb4724bcf8d3c7a4c0105fdcbd8d8508adeec78aca5d536d34840f2d0d4d33019e7fcb75df9becc703243141d5cf935f9d42f6b36e3f67655845ab79add0f050c0ce40e7e28179673bf54c52950469aafb65303d0e27bae68c18b741ba8f7c1fe8f9633066d49c47b523c6f09d7e441895fe50a71dcfac15e0fcb13f5082d2fc94a5df8965b5e11ddc4d11d36f69cae7e93694e214a0996a0705ea35139b3f6b9177343ab967c6d848a43367be183948083883f4765312b5094103b66e8c8d35cadfe3c776154649a9385a8442c86a391b23bba19ebbbf1d0201471337522399b781b5376b9c3ded4db9a00f271904655ac4ae42474a2cc0b1d0f3528f72c57e5e62f800a2c6c8d19413e51c42f6081bcca51ef3d87f16e16db9597beff6801a76c3adf2793a939d296f302a351902a3a9dffbd185ddc24f9eba8d57dc001be14c69b5749c6f6c6a7eb6163b1e1571c6f107abb3b9a1be3f3fc0f888e69d07bf07c24be2e01913f7df895511c74ed0197681ae1f86559ecb64a09f869c50412a9d8ea3759f356aad509da3617f739cb1b95da1e19b5140e8c0ceca139274d2ad7d41247b275ead5039d27667547520f7755f9e2c5c2c6836e5f4027b0160801bfd3240e73a65d1a97f3bb48e431c241028e49eb846939baec30c42c717f4cae9f89a62d2fc51ad6dae1cccd268f606eca0c96dcdaae574fd31152524bc787c244c69b31543bd1c488b29f7101f8e425eef3c6abd2bc0c55b308b305b30d1e7387462087522117596cf1dfd14a079430e312f137220959a27864c8f7b4a2a1fdecfdf7bce75508ee81679731f32d1f7f3198e3f535bfdfa09170ff6cc0a95719916083a0e8ad9d3e47120c9e98ffc7e9398dff0d74fcb3361b51b4f24d293c722cb7a5ad8954b114192833d3b1953ebc1e8d12fbab74116e56d0e07519ad354ab86056234cef3704aa91c1262b4d3db4fcc12c7a554a10051f52800a0dc718c519effe3fd329057226eee2121d848fe075fc439955a509a5c1ff8506c68d54e6bf338995b6750f9433dbebc89bbc3be0b8c650f2352925dd5b22dfb43834f15aed82f3f70c32a948cfb11b4867088fe0569c2f5ba14c012f23df7076eba3b55e2cc70527d42ab4e57191f8a25ceb41b9d4d01dc64a8efc67fada379ff5d48c33a0e1c3521387fb0952918d8427b695e8862f40c222f20d30a13c7c6cc8a679fc2cb8e469018c977c31168ad502dd28428530d1b630e95ca75d90543b64da9470b0a08ba9b1d45b956360cd7a61e4d9fd5f339de6c508b4831b55a222159f573d55de262c44e3efea22dccd0063826ae5882ffa001f78930142330c4d652c067431fb9a574fd40fc436b4b04d3e9cce778c02569f12dc180e092e8629fc7c38a70867360dc6da0d5e37c9c14733816595ec3e418887e9b9119fe8100374c6823bf5d06d5d1d1469354971be8640850805827dfa6f0475dc530737d8e552701cb47a35498dc2e01285f910aa51583e810d622bd16b450a78089c1dd5731e1cc5bb4fbfb2911b3c8aea094426c16985f27b085e89ed84baf28f85eb3cec2d31c65116978a44a575087b72150ddc6460babe6a332962faeb90c4002887d174dd01bd4194e04488afcfe402d54b05fd70f9d19daddfa35e9427eac7f4ea0c4cd24bbb1fa04e7543df268f32cf221b57b1fe9156c034c4aab5576d7e91820be44060874136b4bcbcc6b4f27681575d3ac2c0f396b3fc9e8913c225bf35b8cbbd3e4825412f53c6b4ce56305961ae0abf8ee5412eae33462bc489b6c28a3821e2f89afcdbc34fac7fd573699e46f2b381daedc84b34f91718ecb7de5268734f547f15d21089c88b5bb1bb1b5df6ff1ba655212acacb9a1d7afc9927abd09fb7493fe49bd010d73e0c6f5597c7babcc094c915c4a1414583e6239f0b75537d975540e73f3e8bc0d1b28c073072a1b0596bb36a69696c514dbe9bed38ca8b624962632461e4a784c64dc0f258d2c383d0fdbca7a08c39224e0dfa6e13d99d70cb5290cec2d725181c86ac2e4dc3fcb2a5e630ac60ac4085d76b162abf6c90a3969274ed348ff8c2493ab00b7251da422eacf82247cb2f0b0f4f31bcd82ce43c6a8160ceab52db4d5aaede3f71f878cd109e6795a01b7ecb23365511cf890ce9a45609fe555ee41680d902141d3cb45b46400cb08e53b688df527b14ec84264d0ca6ed9b3615f55e4f4384d0c6d4489cd75ead20a2db945632752c965d06a402f9ce0b0adae1caf70a77ca665e2b3642cbf93557356ba98b4a46dbea590f6fbcdfe359717f1c465a2b7aefa88894f329c22f04e1e3199189a71955e727edb4638f849d133ea0e747b1f3043400d4a2b8d881794cd24cd299bce6cce65ee63603c56d076a4a427b7b86fc48be1f436ac3cb21d969014c803f0ab5dcf72a72e8293db0c4f0d8b4751349e144df9aaaefdfd875a98cbbf9858aab07326e3e44d91c51813cdb84861117bde4e5dc7a84f9bca8e960801c35d29e3b592543f5bf197982646e510b6d53c697bd3518e462d7788b04d66626952dfc99e652064cf68eb6993eea16ea02c30361a1e69c413590f44cae96e8d6a9e1931a45379a742c246bdb78a11497d6622eb2e0aceb201781a1a22b6c1425319aaaa10a9dad236d99eb1019b884ff186d6759e18948b8fdd46d6cf83f5efbc390a14e97f8781fffb40811dfd57bc684fece0db13aa6a1c214493f19cb0707d9cf72d9602293ca31bbe5b8d3834094a8d0e92feb4aeafad66853ae8c3b6dd410abc5c1a5e94137b325200fcb0545d6121a790afc49a8c8cec757f68f5991b0c00fa1086d54040d1452a819a5c1aef4f3738a6db25505a7b703b11659fd0897b62c36f951a4e0abcf1aa3e10e0c9e0e44fea6c1a95cb7c5a36d9933f9445fd45752fe1f1f680af3e92172c55fc159d0f911f9ed2116a323ffdd64faa074e649017f7cedf28515ce3d46cc6d01611617fae87d82df6df30546c589e9817b9694e4db98c63b0b9ec204eed41186b62e4dc60e69dd9fb5e3db4264293b1111aa1be2bf9bd982f2635445f53c1688e52143233a10d374e01895d072ab317b6e878de15a65f991f93d367e634a8019b4166927c9a24b98ac0725278a7dc9afc616e381782d503be9e49422b45377d34ac9bfc0089b037bdfbb0fc7eddc00dcfcaa597d181e39b7ad17586fa8cdea62d8dd906f56333cc6a831b9d03cc5b90c37339b6227489ea9900dd5e1d5908c28020694d9a3cf024cbee07ac85add847c1aaf2b0b62b303e2d512b7c08fe72e17c603a9b7c581a7b3fda3c522c3e30f080921431e3a4596ffcc941612685df714c506e0b216eac8cc7d9691ade7cde74edc2fe418da8b3fde3224eb882444a4392807d44d161e5d6c51dd3b771dd6a4bb30b91a20eb64766b8540336473dd097dfc3490e8de885f345995c8142fcfc62747bea4983f02bb69e1d567a7c0784e456d326a41e697ca8a8f342c28203df70ea7534e6df76201d93acc2f9951ea250261215ac58348ef6f32e1e7fb5e7e69d9dc8107d9a253b4ce4efbd5c6a8075b23434b293fab8042e9ab62161373a9679132b775394c8c6013489ad462c86a24431ed68abbda932058ddd126a4b088e3b4575752404072d48cef7d4a83e6ba7034ef779bd527ff4906b6a62e15d4869f51bd30047a7b60c9e29522d6b02cbe992283552200559a76552a5cf4d684686376d2b69572d58ef12c2bb560c54a9e17295c8727e5ed5b601eebb2ed7bc9d4f52001b12d5ab85123dd70db77b346b12eba8aa653bdcc49ed987dcd9b6fa9e8073c71a311a06c31442e39f7d6954f05400284403af0c880a71f3a096289f9c97f8756a485baca2066f230e0abc16cc07ca8119caf43d44ed5ccdea9af525b3fa5e9c363121d15e6e898215d6a9dae0764599d66bc88bc037f291c879f31b05e9be4467522ee6d36fb1ce9603202d0f6cbb30532a962f3881e604af270b9d639d622457985216e1657d25bcdcc0df17bd023a5729c4f151162514e1874e3d970be14dd08704172488098370c27a90f74e15b0a5a1612d29feeef192c412454da4040ddcd0722963c254b874dfb158253845fbf7b6015b0833ca2cd024c9200096cc9df8a4a41ca0881011b1392401da68cec795093af2e2e7f83916089733fd4ec303dd9457e17a2e44eca9615f62ccfa3870ce672f2f34a0e92bf60072799442adf708c17c163c0d97b483fce83f12893abad2b3c66c1b1ed0e2484170799a561b5a6c9d6c3fcced52b61e14cab90698d4dc9093b6e09aeb491e278eee4c6f257fe4fbdf77f79a672cd5515c78e49e9dc3e81b0d51db9f4d970bceaa75e531383c16420759d972e8f7a7362410f0a2aeb0014fa0fa76b4546b42c8e15cd4f7c0b5228240e4f0c6ef6007debb09c1b4c8e63e21798d5554c21044bcc2a6e7a2136a6757bd456ea7217bd0e88aa3226d65611c205431747d132602d7f7409cd74c167471f8a7041f60b4d41ee292d551377078a5fb9361961513278cacef52356f1064a44ae356380b8bcb6739254beb5a3a6cc5feae7c4f99dbe81073fa38fd3905bc159d13b4e896bd023bba3f076e276444d87360b3811eeede71b96cee3682a27d35282fd6f44989e73f4138c4a29eaacb47cc28f2c5f2f2933218476c497737ed4501ce3e624598b6ef0efe7de6a37d25a051264094fb366622ad6f1be5ad5c3dd49655f0977c802a55e6e570622135047dd0ac1984ad7c6b0ef865ab2e64d15ba658edf0a89595c2a96470eb134283976accf90a919931e1247f39f15296f667b09700e990ca37ce8a85b9fa32cbecb6238a493a416201f6b24beb3e45371c973744430ae02d85237d510c2a5ba7106eb4106cabf774d04ad3a08c66e84675739dad7b11268a21bf2f7e51baf213f4dbfde2ce71fed0c043d37ab246a288d96ef4131124c9f6aa4eafba1d2355ed51a15711e2b827329ab1415cf7c61cc6d2ff614a2c9d05500b310efc37d8bc05f853d6da21d0eac7e9a91ca31841402d249db15a370a44f75ed3991ca3c7a51a9b84e5d765d316402c11ddb9df587908e08054961f9052c1aa5327002f1e2f8bbc3bb594fff81d8236558cf5548a40c4b1b03721e3275c561aa58b28f1fec346091afc844435828685e71cf35814d50886a0012f3fd0857e3303d15f11b2a0a2b6df2d71a9fac43b0084e11063cb411400f4fb08cf6e9021a498f018f66bab530b20e58f0fcea73f64c6d71906adf320cff8f1556eb4c9bd4570d362d1b7db57e8115a8bfde565a4a2430ff5bee598cd0e01ffea8b3fbeba0db07286a4fa5d61aea62608f6ca5376ca18bca8f3a60585fd47d8cb7ae18b2969adea0748bed7ec7442d0f88f5cae067d899c0b9023a76c6388e22cc050eb0b55801c1634a971b4ddbc2d3ad671a57928a13f321d9e335e56ad02fa724fcae024189cca7587d498df9fb9c978a2eeee7ce73c892459f0452ac026b20f1f08dd4d3daa48b8a508a5ca9aeaa8f67bda8fd57c837877d5924a4caff0f185688c4336beeb1034b700f52ea05eca02e38a3fe60e813522e082ef724cab829511e0fbaca9a8eade836e33d3356e41bf2e1f156984b189f56a464fd8cea525b448225407c1a41c845ff5e3fc49c0fe37ee766f0c0caa2efdeae03bba2c0d1a28b28a1d14abef0274162e109a54fd0279f86e9650d038bd6e5648611f1dbc141d110eea7ae35468598dff70a8a31da0516c45f40b5dd835c419fb1844fc593d343d78a2a68d05794fa08d5630fae41036431b8bb5393e139eba0eba01ea0876ed7f6a93ded9cc30733f55d9e67cedc7e741a20f5ebac0ad89fa43b8cc78aa42c886032cef1c11293cf21d23ea0873c0ef7e5be5179918b97d783cce1c1bb965c4dc30b6244e16bbc3d56deac22f5cd50625a95d3f6e4272609e3c0d85dcf23d66bbc3197e73a096ea919a88b1f0c62eb4eafc28162623cb1e96e523f6f08a1fee78a64f6949d1b4cde3361ea87455776582f7df350a30768c5550bd648d6f4234a66cfcf3696cd337357153e2a1fa3f57a6fad70b369b6766b46d9326ab4ddc3183f9e603c9ac3409017acb59636ad0b1e7a9c65743aceed41ddc86b0f08caf5e4e980dd5f326eabc28e1ce681f62307a2f4b7e2c031765f8931c449e8178688fccfbddebf6456f475de2791e12f8e62c434cdafb0a84cf00b5490a36b4548e59bd7a9a40c4417cad2567e8ab2725dd0bb6e1f31072dbe354b78e4695ab14c41824da053256cf8a8c08e118f0d335bef1d324ab554dc01e4b00962f272e9c092fe1134f4153f7f41f4362306088e5e936642260e35bb9a8a7de6f7833a0ccc26ee9ee69d5c5c48909f1bc01028fe64a0fa55bafe8b02302f0f8c2182c254a9fd584ced26ae066c3c56fa68281489fe8cf0dfcf08cf6a93fa9a83d7186145fb5034485b99724f8a3603b54fca0ba520d87a2151b20f75931dffb2dd128b8d79fa20a8da46ea6b97e8d4c4f2ec12bb07b6ba8d781d3712af3ca4d0b1a9f37c57ccb2bbc4c53fc3324feba1c7745f59ea2c010932994243bd40268841bc44eec3e40bbf5ab275a02b1abe007bd399e0b8ce14b12a28ba0c77864c89e05cb5a78ac626ba25e9bb487c5956c8eb16f42b8423536878352dac51a1c92b25b5f583f3bbd52c50a235958cf45b0497cada21a28ca88424c69bf6a8f5e270e27599802c69fdbc0af25e8f70b6e5d66360f95499904e5516c39e7e3b1486bd57a55ba24e002028c164d3614aecb67d141a5bca59172acfa2819f860aded79af98e2107d4da7fea951f16803630644afff40b27e8911a23916f958d579f7780775556001a64a80c10b3547119c29823c8e6f6221ea62f2cb7e7a16bae65baf063169db7b4451bb545da46b5f77f1ac5df1ff72ef38898164d53b23bebcdcdb71d7d45e3fa3266cca0027f87c8e8eb6bfcd5213c01407ee2810ca8a1ac73a63fc5e345be45174753380949448e786161e1de2863e4c76f32fecbf5443b07c1e31c7c579d4fc94632797586f8f363baa792849914a98484f91255aec102e65ff4a92d5602ffef95c437179a5d2c483b724c403d0a1b84ca08f7fd3ec0a78abdbb7b05e1bf110308fdff06e141927fcbc11f340c27e9bc82fb043e1db113239202307473cf339cb291014307da46022786cfbe62bce9f8877ebfb67134312a92345d24a88082d63e0cdd4b7870203e874255b458fe5f3804f3ed0ec25670af750b50f60fb8acff97d707741ccf770928634dbf63d6dfc3925ff9efe8f32ed70ff71f2dc5907aba4cf35a661875ae222693057ddeb481c668c00656b714d9e0391bc1c8c9983f2c308b2f4e69c1620a6dc6c3cae2e3e1873ea13e31d1fa29cc15806580e534e1a48c319f6f28f00e3c817ccd451c82cc28bb95623f4d8adacb54eb9ad0fe7e0b52385281a4930c28c2a33d1b2b2a141aa219dd6adee1c59b172159e466d0071b092368d658315f9e65c6f6ae63c376adf3309f05ca3411848e14af0347c2e446915951dcb91f2ce9918e09d1cc1201cd1da2e7ebf6c3bca0fd8c40985e2519c892915de2ffee9b50d76e54051d7d21353230092ff24e0dbfbadaacf9f85d56c9873974b4382f424ce4007b93d01a37490155e716103de87055724886d57c68468f440c5ab75317b0c101260d3d3f70b790b4e8a10a3fdd846b40ad1731a868d48bd5dc0ffcaa7c3fd6c0a4ce9e085386670175d056a53161b7b35caf514e93f4e51cd54e6906356c390b8c93dffb07c7b0ca69ffdd83bb7e0d309ed6c788bcd3e3d42584af4e49e103614dba2b78cc23b35b2e8228d81d849c7ff133bab5c8adf8264479f86126e1090b897df48f9b3778171049ff92b44010f1cf03f02e32e196a14fa09717cbc829c7cd619bf03ef832d995f2848d0a265abce8bbc8fa2a2d0e430071e8feb302bccc320a05d15aa8a99e88e414f2212bb81466179e51194d1c5a01d9e274d85782d49cddbc46cacf3a14ca1072be7e9bd1799621c41e050e4f423078e025acca7e2d6603f63ef4d61a3e79518036f0e1b0c4521b6dfb4fedc938308baaa7f8833282e24cc0037ce1b27ccb0a411c3bc735a0907045a6665f80e92ad1a844fd47eb4004ee922f5c7a586c46524242603aec740fe292eaf876d47699158faec3c784d0267142d2b9a4dab63acd4ae53ff7caf051615eaaa09d4293b0233e3498667e97a475e6472d8e9cf44fdb26729a570994d223d1e3a424ed686accf7f895d9459b1d5a95d79fbebf67057248922c6751163a1dcf8471b41c49470c29f1f922a2f4d77eb6d00da4135cb688e9960eb28eac5ac380a376e04b86b623b7b4a2cb1a051f5851ef0489afce94bb94b7a8c3682c00b4882051e8b9aa6aa6bd60eb0fc43410255b19749c08d4091fb20dd8e11bcf3f810ab03e7ccc98341747201268c649bee58110048d3d2aeadf623ef2a1fd0c77c30bd7224a93562dbf6377fad34b0dcc60445373e1ec6b2c591b0a450ea32f78623bba2cdf0ae3b1fb4661d4e68a865e6e4869d9727b371a78e87d7439b3bcf7125c169d47ec8d13da26820b215ca0cafac680bde1e66288d7cd7b5585dcd062272350ef5ab500a3644d368e5aac7379843a174ddfdf46150f926dc60d0fd5eb3b3bd399012c1ba36ad0d9d5d77e88c601cf410e56f83cb43896929e6745a0f8e4a43a30e5501205119577328783ffba93e6ece4b52cdaebea94e26dc7c228703ad2cbcfdedd949bb20ca040b786c441791a45a7c986ca4bca556d2b9a42c273008aa13bcd3309db652f608582348187809e4adfeb4a24d5abd7aa26da0791be3b799c1f3c83586ece4d63a83149309296f959fba783ac627cc009ad18f050c88a30be908eac13d503fbed0f6d981f16de606ff194cd97ee6c43407c894bb5c2ba7ff3102533fe649df333b924c2d5d28bc0149723578881229239fd802a8fdf6a56f1bb53c09a91a913c499649601248acda2845d015c14af42f0c9971346139de39630c20c5a60f651f02f6926b29632b641790516582f9f0a3e42e626228feb4ed6abcdad4a614e3cd57da7fddea64ce6303e4e2e6f26bbe629549943f6d6081ddd6997b9008f0dd4e78b761249f84f5632e4800c4fb05921191a6ca173fd1f17c4af8f2171c00509a48c4f8d960906cb86e3aab7b0e79fef798ef5938c8d822dfec981f2dd3bc31375fdd17635204acfac307a3487d0451171c12ee1a209f103cb2b7c45fe2d358e9c5d2b2dd9d300271d3735bb2514ad3adf67699c2b3ef3f802d0d1a08aebd49361c0f9c5b134d1f214768bc6e1cc588fb0fa3aec1221bbc1bb3757378d82807861fef9c634f13d9e9b9c3891039de80cfae1fb7c30d78212860da6046beb7317bc7e760c7777eaaa046cc4f02ba68314657309c19a50367919a9f3e8ff1b54898cbec5cee96c4aea4aa90266193660efbae272cac2e61f18c5c3202f108aba1620d8c2f020182801ec0f2100a6d1b363a90ae07c5bead6fe25784bcefacfb1bd97b4b29654a32a5145804040483043fc46088142a539e9052c462600b059835f57a71bd18d1a8dee2eba3d6d0f057b6592fdfb24adb238558bf2d8ff555b64232f7d547ad61f92adbac6c7b96678568f9172c991048ac96ab86c52ae960cdd130002a180e31f0dfe20d228a6079ec8b68f9173a2d4ac074b27ccbf7fbf2a88d96502c58e6434bf622d34637e410d866399b65fd0a673839d69095ddc8b1feff2dab94838363e87a1c1c39164ece6549232d9fe2d135faedfa95ccc655ba715d2ba3d168a5aa5aaa2a23addc609a6be5b7ea476f55a51b3682aaef01c7cacacaca252556246f304d2565766394d9b8c134bb7384a3aaaa1cd670dc108bc5fa4d8b2c8bf4625996949794524a79c9eaa5bca4252d69b9110dabaaa48d1ba7972775295ed8cfc52e33d8a5c205529230062e84fc4197f7eeb7efef377f98b53710deedededf0fd2d58227537d6edb0fb750bf166e2ab4143448c023aa19c1f73a113899452d3fea6d550a0c92367f93479ec98fc6e79dcf26c0f931d22c49789155a86425608733770ce71b303c2fda658cb9895df65cbec76cae9fb47d59178c75c6cab8028cbbddb238898a6a94a7a86e43712c800349a517ed49ad1cb6ce3afdee22ac6cc850443c68f5a0343662fe58bc7fe07cbb73c101931dbb8c25eb0582b2596910e2396571942acbcb3947e20a9c0e8c6e829a03256328de44cbfa24026eb480e816de68335ecdaf877db87d90e1cd678d7adfb2ded60cdc9dfc132a2b1d241964fb125df6df22f292fab64bd351ad1b0ac2b46964cd9147fd3118db8325ebfc5b7de8aa5527c7959d688c675c9aa5ac96854d9c51ae3304dccb6fd6aab321c9d384cb32f7fa755551fe3ea5428d4cd0cf86e9b19925e2084f0dab0c931cad2cf4a961a4208e146194ab028f22aa6e10c3de841163d903b4d3451d44415192eb420d4d811420861b8ac86f35ad6b2afe557cb57825143fe84ee1d3e7efb30779e915873dfcc211cbdaedc5d811e1743767e6420a4040c51e2c3f70f5e315648603fa900c217865c1a7b982afe00bc80d980ff227c09af8fa51e3ee1e8537c1919653060f6acbdf752098c0a28ba98efdd0fb01212cc7df5a92bdb80cceb65bc7e4735e05bee610f9faefaf70c2be8a073f3491852c6a7c409cf7c34ccf782fc5021ca3f29ea7192c4542ee693113e148a69f4c97c0f3303017dd2139db0d4d2eb033be3abacebbdeff8de7b3038ab015fbe7ced17b9c03097caba2eab8a80cef71edfc1a8117fbed23eaed8e224307f17d2c77e349c0e3a6174432402b044f38a111d57b3190c2430fc7d78cf26b0ffde87150249673ee8c31762ffbd10485ce603ccd409f1b21b9480adab29a989df14f9f92f2ad8f614d08782a53fb820899423528278ca114454a4f474a11342f8e0eb52ab6624c69d2396c2583e225c1fbb034405888a8bf921fe7a1b403afc36808080522faa1c71717952a031dc3b1f2b78e74365dc0b1f6c53206c8642d127eae40a05fa1915d113344b539518d1641a819f627fcf7746c7369719e1791930eb5ea559c2850648b8ac80861c4c71f1a1a10916eff251a2e779bc873023b06d77b41d229e69b4c741c13a6a138f1c6942e707a55924148a1645222c45c0b6f5f16142476de24f1678f972478029400108a00cb880c6708f4365acc0b41808d335f879453a3a7a042d113bb6e7b5f7105589cd8c065093d4d882699d796665db02d17126f73196743e46f72265541bee1f6804531b87a94d4735997879f898bc58131857035b31777ffee4cb2934c4e0d758c75cd7b80373bd45357e8d8198ebef618ac5ecbbe7c5fa1151889aba00379ddd9d1dc2989b1467bd8d85f7ebf7e083dd3b58b18bb0eeeef6e8839dbf113c9722780dbf9d045a8c7d02191a3b48c2ee4b62b06661caebf7fc79630f0667c5139a05afdff3e73d22c21a28ee04a902617b15c8e0a4bdfbf573944382f9bbfb7bbe648808ca69c60b9b9e417b601a7ffd1b3ee0e4d880d6a80c853c652663587337acdd50044c8b790ce1ab1e84aff2e7f253ec19ac640c6b314eb6d40a42c055c95635974073c7f7b2205e670fbe4cb3de7d8cd556104d8bc1c931a34c4e4142cffb47cac50a6cd3283b7ac44822318dba3410ac7de6c90aa32fafc4101114b70c3720bcea7ae5724f340b53dc498c6bf1c518939c463b38275d181244db97f272a2a3b3fbf3c7cccccc9c392f6d3de0e4871042f8aff478b004999cc1e601c6ccccddbd8ebbd7b97b9db9db77e3c608a360294c3fd74419afdf830f767cbe6193f302d6dd1a83bf479cac32fb1abf63d5de0826bfebeece56659663ec67448c4d42475595a5094c1fbedd1ed696486683b525d2dddd4b647b4a3b647bf4692cec59225de5e4d8d7d26e8411427f858e3fc5d2aa5e96aa4a36aaea5996f5a41cc9fe37aae17fbd0d55eb2d592ac9973f83b5eef15e4544395e5766433f6e31b391a584307d9dfafd02a834aaaa663e58eb1dac45e9d922f05b1deccc331d2d59609b0add70291bdabdddfcbd0203e75cf78e94eeee0f2ecb88c693b0d71f6cd75d42b573ce41e8205ce71e3a084fb09d73fd9e7b19cafd7b7ed1f1ce38e33d84ce41f7dcbdbb25bd406cbe2ef55477f7dff6e7de95600183b96285a5ab990ac1367ac04197c33937849c910ec59a0ed3c4f8d6c1cf6199a3c3555b7e4508e1cbec848270468c314a1d7e8d68b8846e79749f21a584988eb6fab78ebe33f60c2847343cba8dd6d1513df7482fefbd6ee8ba1b967e3ad70dddebe79c73eea4c8589285c9b41ad8defd1cce98d5d10e1c64deb0c97d8a515530ff4d0b01434063b46bf7209c4b30d9f735d7fe5e5dd3b217d6629c2efd8aec4c54877aef596f35c26a4403be3895b9e4dceebe760f3b704d20fad7c8f5298e9594efd9893594945e954634aaca23af389837aad16f392a7ef5562c954e712687bb4bc8f022f5a8068a6922cc50a7c928ae20c3767087df33379bdcbf0c87693ce30c4786d305ecc47f61158f9460694c40ddb8682edac60005d85545bf7e0f3ed81da7a0a0dd06bafbf337c39d80e955554546de17b5e13190610996830b62da0a4642069827fd6bdae904a439130e4370bd03054cf5af61ac397f2a92cc28606e27059c4ea7d3e974caa1323910718299519bbe809a0a1db41196bc7ecf9f7764d40d4980de7bfe9ca4fa5aa3833953ec42843a383848a4229c85333f6e899d9d203b5660c1ee6ed3d06c9a768108c484859a8914371c61db62f8b6f4a66abd9560baccb25bf55e611a46627cf32746830ee183cfc130835876e102b6ad0fff4cf113a39d4e33393a6e8e080d3d39d24414a7d3e9743a9d7252806dec73f26102867f9e3869a593ca9c26f39ed486e7d545c0bc446facbdfbf5731ef1c032e1c764b28ac482e8803b53d5f8da69820f112245889060dbf69c7a86c0a498462f1f2208050535219a1b6a6e1a4ad3b4d7b409401930c371261b54806d0c04c4049e5c0d94d12ce4031b4a2d2d9d6117c768afdff32122283c7e18e9e1f9fa3d7fdefe8a520522fd5cc96cb896ab840035f15725abf480d6d4c4eeb4794096d80373bd6532c63dd107c5348e089122fde4891327575cd1a40993b9699aa6695a0e36b9cfc1010b28a6713e37f8c1ebf79c6558ae3bc4aef184212228afda2f16403cf5b5289e7714495acadc5c5cf80626d8b63f3fcc404344507c5a7b01c9a016211b50bbeb2bcbf16a27227cae3b7b374cf32858ea520936cb5db0b43909a67ff3e0e6e387250622e59584c89c7a55e2ccca162e3b65f08135a1671a850de123826f3be57818ae19bd62a3920e9d3662a808c771fc3d0e0ee78793e1e028451cac392f6055c90de1c877590faca11c6ac6cce30724574604d30a2d85bff7f62d33ef430821fcb74bc4ddfbb9f773efb7ebfebabd776494214bb1845dae08330df7ab7dc7be355a262f06afee41f74f4387f00d114159c93670c7e8842a314b3848151ee22176e278dc107ea2b1141e622a6ec70999ee9f778cc638d818c9a4e289a955d66750356d8c646e3ce42cf0214e986e7bd1b8a8b95002dbbc4811a6790232136ac33e38e889d188f0a1280a17334cd35595654130c5a9d48c869026bed48c979af152d97b103e1acf66a466c05497092ea6d1d601cbdc1f690c6c87e395b9414c8e23d5f6d703936377cb6bf481c9afdad563f2bbaede7d4c75314d1341f99906a51a8cd6905093c78fb9af3a73df470560a647f6c8ea3e715a263f1bb442eba465587b9d2c1729988cf5611f159c6620e9b5d3ebeab6ac6c3b36838197ebe2466dfcc6010e40296a4335401900821e2a93c3110c6fd4c67b0a3e2722448a14e190cc806ddbd333e4f4989999b50984da04055058292ee22286c251e8e400036c632226e22729286e681540b8430522e810bea1202127344e34cd3d01db5648a8899290a48bbb7b555553f66b20e9d40080ad061b38e0520310bbab23c6a7043a84ef46131a7aa2314dccced41dfc41414242397c3a9d4e454551a250494d1e3973377b895d0574081f7c7e5d2e2e2f2f303537dc198a351bae88d1b58fcfe3e0189203a55272a8ecce0a41ddbc6abc82890bd3fd86000dc374bf2da0a43516180d816d27d4699f3323703398579baaa66da3a0408a2387ce0e95713cd4e478a2b041a6734d9ac09c50674e601bbb2017238675cf885b8e20c2c47d69bd04846387b183bebf0efaee3e04feaea43073615363320bd853e1832bccedc47cc4d21f9410d242480b283f509cdbe0101fbb0b86e3cb8be68af5dc624fe7fe456fe791ff65f3b930f02b1f5896aab2bad730ccddbcce9fdd7719863575cead7bfbbc9d332bb373ccbcda0e33332bb36bc15a67d700d8c63666deb25619552765dde3f3d8afbb338deedac58e0d9f7784cfabe817d67bafa5e9570783edebcd5a6520f4ded8cfb5eb6fa7704af9fb98cbac9bb461af99661f3412218470480adae7d160058e073310f99122b60842c2c303173f4158010f5b502942944491dcc1922e9a54d1c5130c3006aca74ed10591c9075d3cd186740125092225446a300322b438a245920dc8dce732401865f7b231b8549300d574360603d4c4598c262f99cca2433cd28177e7f2af940256aa02ebe74b4d2f231c56a24861e90f48489912450b213f54621005c67b0d3a8194a94127e862eacb6a6c357ddae8500485a5038c11f74cddfe0fcb296408172ec32a4c09218410c22020844f4addc27237fb9dafbbba2eb391f79c70c2df69d7775f73777f1d3358da74bc533f3fa90cbfe7ce637c8d84b5c8708d85e53a87cab876ce0531e9288e080b735e776b672eb2d6ceb96f6e02e327aa6ae0fbdf85fff103e27929e60a6cfbf8de1be2ac192f01ebdfddcdfcbb5b477392d7ef515fa639b42efc8659103d3d6329b8a7d52c805c6825444586869c14a181326099b0c412459ae05004b6ad90d0154588526af386869ca4b630379da2331dd217b06d8584ae48a9cd9b4452284263ad3252c2779aec1f137a0b163688bbc2ce921aba055878a719f705f7f71c421dc23f7952852a40010a4c60021290d080b9690dd0344dd3340568cd05d4a4b50d3b9a8f108478788444c1644811137b647f36898e0ecd622a16a652406b58244ba653844da11bd514217c9d18e1f2c408e52e0f0fcff22c4f559d2047336c11e5d3622c2dc6d262acaad262dc568eab7e107655599f62ab6a29a5bcaeb6b690a51baf2606520ca5d186aaaad0ec1b737fc75f2e8b18049ea1a5a8c1080a8542a152286772989017f02e84259e6ced0e0d64fab315a55ef2922069a84b357eec355447d5b875db31f78a7db590114c6af3def3e7fd1bea0028140a8532c0d2686035f7a80ca8cc4a91496db897f939e66d752b9b951cd0c95b6b8f394d406de09394308592b4484280d668cee4da5d8c1849d329801c61f2db080a0a7a95d912065e7a6ce0c6f0a236ec2f4a524db57d8ff1e5a53be3f1638bb83406662f31103f5615b73f8f511b864668fbb2022f6ada1ca4c9e3c7644c4dcbeb8ef0d81d82110f0d63bf0dc86c87fb63eef36a0c765e6776eb56de4329af070584fe5a922c55cdfa8dd1923700f568c4157b0a96b8e0744ab91a949af8af203e3ee48e838367480e873dc43804db3468eaa032ff026cd321140e1dd446a5081eeae66d2378dda81bd40deac6279883a8b48d9b0731ab118004100053160000180c060483e180703c502451f914800f638a3e745234140844418e03298ae228c618420030041963084146a1a14107e32dc3d1252b309dd7fa2bc0260079069572cfdd25f0912778bff438acfd9fc4976d00892659e065144eb16a5cc5703f884abc36ec39236ac9c68d22f6e8dfa9c3a2e0689183a8b9b2e418026f1413a23a74a79d2f4fc72542a96905712f3deb2e4531df19e7c0e10e287f6d526f88756e52b727ec51c9fede104e2c3f650d0d090a14c493773849f2a8d8e49a7722596df977ff473ddd6bf929325352d82d02c772d2f10a1ba7c21bc6f6669c807882078fcaa7754a09af00aca0de2b5c291d08c12261090a0f716772ee185e9a3f5fd7820abd449c3d71a03acfbabca4a9aa8ead156be86d6c98de91fbfda227167382dec6ba64cac7a1273009f2c48c16793ba387921bf88293cc582e19e2e058fbd918441e4d030758968975a6bc2a24ca886e9161b84f4f619fe4cba73e775f2985728c8d7cb80f84baef87cc221d1fdffdc0e8b36261c39ef596fb889522843127c9f02c5bf723e22d9c77103d53a8b3b467cbcd70d441bd9043c416a5b9894e80a28c580a7aad37a643bc85460e67af37ace7611ce4517666e2d1737b287fefbf53b37ddab7920e087a6ada1b2dc7a9222179c8fb465cd2c27124757e6476fb7317b7b070896f2b2a5725683da7ebd52634c1d0d732d25de98b488423cb0a07be5e440b8c3f7173c48ab255a8d4f08920620a0b0262ae3858d66f92bfc215a462f4ab9ec066a74c32c4411c77cbf2f2af5bd97ca2a0b8a4f34ace709d8862ad4f5c15a5f074acb7bc720397ea0e50f9b45f845b7fca5925fe750af5e3c4e039c9be96becf7affca4afd7315cb64d276a998bf5f7aefb6d64f70c4e0497604780aefba6bb9580ed4470635a02ce349bf79a2c87fbf87fb17def7793ec92667a06c322b5a46ccf986e89e52c221293b95c33d2dcf5cc8f9fea810e38a4c257d615f359989c57ed79212a9e20f04fd1e045dcb9619677c2353b809c48787f9c1f4c119a01b0aad3a8006a23623b173de268a308dd1f286643599a366c277fafcc6b304e80fd667c9474b61fd6c82a1d998cf082bb8c6dcf29da4957f3286bcb93f6e6d497669a4a4084e54222410d0d1c543030fd0e326c4c6903bbe3d7731db407a623a41a3d7f5b6943a2bb6fe63d2621e6eafc9cbd408e214fada0c4f7c6b7003b9e22c9ac29d851bda1be502af396da6567eef582742cbf80bdc1756e1974d332d2a90507934be2ddb9916c97c88fae15befd0b1acaa06cf0ae97b65ec5104b13e2b729a5e9c117c6503c78c55cdf8e2fb3bc1ae62becfed8a0aa76989c8e6e84e9bd4a66d308826a604d0a170d1dc5d37e88f9a1937630bed3ffd4ca3899990f005511c1d3999bf833e5ad7136548c3977e96c1f9fa6a22fb7f72e12fbbf9534f8bf7960de7e0b86081a2dc883200ef0046000d7b5424c4bdc443b374118dda2a3008007b99b625e52eda4b3d2180355a9591ca6dae395db38bd5e66ee8ed179ce12c97a46bbb4aff9a361f481487b12943c8e7bb34c577a180145288b34353dc659e999fe6142f6002ea0437a472dcc4d053ade531d56f2303a59c22a6ac0f213e5cc2bdfe40bda80bb0f41c4d73525fb8451d0c2506db1cc6a1c0948b986c243423d52ad65169166cafb029e770de7a25c6100aa75cbd122a5a29d5d2b23f92104ab1bc0d8569282a7dcbffeb66251c490c005c6f1c40ffcf6771f2230b80abf8468a92bcd8da023a0fc26269c3d574e66c9943d7c28614119e4e0a7b71b54a4a2b486bbfa9b8e6c996fb8cec6248db170f020a560765ae9df90214c5b1623cb33588f87c01effd151e26bf3b45650d0e2b18b0b1cd23b04842df3e687fa28de7aaca8436702c7a6e166569adf90da6e9aa1c0fd0c65f0b64812a2d1dc6a63924f3d3e2d13d648d97380ea56509c53526b002511e933543b46cb09463ad4bc5c3e4b121bf622f015742bf76835417224e5ebfc63bceb42200f80579eec1fe471a30905bdcad33ec7e36a33b3436a2617246af64f9543a422f53369a5a6e75eacf6b57307d8410b81e239cb9c130d45d143500ece27e0253baaf3f1095eb97acda7891c5755725c9452e5eaaec3e5fc740e707854b62185f74d26b756a599c8d82bb8126b28f0f4943d59a1c5d415d5597bc2cc0f643055500b84a455a768da16ee34a57696cfed198c89b6c509e0e2635c585229404e76f7147c5b6cc73d03a083a78e2c7ee96fff9aba14e925e458618540e171d3c929a094f3c396483ff9632e1c5ad8bfbb611097a85ea23fdfc13214ef0ee3dd06b67d805306a588029dd59873a9a84882ad100b799bbff483b44a54cf4af18961fe9422b20d9a2bfb20955115995842279365c97d77b145dc2d39b4431b753ab06bd573bad8a76b55d65a779238ae2c748150473a9bf3ce516a3283b03092d42f17d0af4109d54cbb324fe109a8998e40bc4341bb7fb2724ed875bfc04aa78cdf12fad6e0d73bb8370f3cd5dea055906a1472cf2df66e9f801ca39d174db1de9da875f416b7b1951d55a7d0a4681efbd7843f769ca8a55a7535f6dcb1df52df8ad8e82773acf407d7228d28b92851c60e2df939a7e5143b1a3eb0e8048ae7cc8a415bc276c6996d73f790f9f08ff254c4b7403481d0902e40acb349ec5f48407b05d5768d9fbfa0e5cbb88be68dbdc59740bf05ceb10d6785981635a8a871956b99dd85d25bbd2e8f5e5b3c44a83e1edc5b9efbfcb9cf902dac53f413e8a43b0942f521e2d6ab2ba237705f6bbd5d8d797e3f788b6d03d87360c5abaa967e74ab22d93fd226f5ca5b9a19875511abc0d883fdb7f060e520ede22391ba4e86ee181bcc5a1347a63ba29968ffcd16cd8c972382dcec61cc72083962a8ce45efad0611d940195a9b97e0b8a162d6e601507107a40efd12b09f455ff7953a34a57137a9cb7e7d95b8dac2068197c3786d8a8a11ba05213fe306bc99c070670be8a0926ef2a4dcebe3d09ac76ac206317c7c4acf6547dd51313e7f979092027c7951daaf7b24298a116736cfc1a2bcf90a91682571c325595548ae8fda47a62d8eea2670e7dd1a5d91c7abb4b299436ef807641cf19572ecc6fa4662979e1bd145efec0c26e39678c4d6984f45e143130c0071ae448a36758acbcf521560913c2600012135c879bb8dfd75afe6f568c571899c22744fdff38d2fcf8d72b90a691be4dcd0dc71d32953a37d0ae133ec1607304c42cc103e2092858d5301cdc7bdcc2c3d4090109071fa09e20142cd062af13d09f1da11e77a0711b97d0df886c21df7d4f0f23f5faf5021eeaf942bbb853d487048766646b481242ebc5e74d5ed648985208dc9c6a61943e7962a625c2d705fabbf840893302d6346f729c087c7f9d34ff97cb9ae3db3b49a215be9951a728558fcc2564dba3cece45a34799c181b5e2c6f7b03f98984262853fcc2269c93857a68ddd8a01c8a065737585202aa172cbaedd78228cd8f54d2fbcd24774d906e64fd8530170dbff84127f5ffec779c7e2a6a57dac009c357b00c9d63a8cc0c30ea20b6dd2b8916eae0f07db64199a8eecf0cdaa0113a8412866cb1336877f0c3d8a8800487888e03e0b0190ab936dae58cbbf610e0ab9e835963fc570b902d867781327c76d5d876268ff6642042c59415be738c04c48f1d46aeafcb171b9a898ea95bb7d2a142e4816ecfb96e5e67eae12f7965312111560fecd486b761bcb42054664986ac5a6781ce7f85070a611eea49fcda12684238fc73f90dc2d9c46ab11fddd48fd7e86d3d8f119ac2936bf1ceeb6b1424bbba8f0ebb8d1dcd02442fb92aaafd9eb9c028526a29d5fd1d34b5ed9c150cf915b81de6034343ff5e5ec45f1cb8cb82e2a0085772a728112c88b88f98caca38228e0479d8d2c4431a44dd7a4b43f513b037ed8a1167124230bb62434bf47786cad4b5ca2809ffd7af6a6c700b042d3c1d74e0590193f4197f65fb37885d86ff8a710cbc451f3cefb04bb7e13a538db8cf9cea37423d8ac44e016d8cf84c44b9f63f01b170b0a8abd869d824a399c46240043293b24c567b36b5a1df40a3119d4d17b5b2f21c70fbae7aa256159a113e1813f0cd272c8fa1edc833da0ab3910523c2577b1dfaff6cc93c5ac8f5ac33ef680c14786c6fd600f2dc180b9e96f63c896e35e43e13a60b05224f8cf11fed8d85b859e75d0341235f73e60b8d385efe0db1ca614babf3fdd073b7ac3eb03e5e8cf34db305188031b1899e9f30148f444074691256d7fdfcde7e7251e08697175d25b1a2cfc6a69e63eaa08a3bd3e925513b10c766c502eb616e5e2a34545682e7f4b12caf7d6a41c81197553d3185bf0fdaf187ca54fe7cc1af5c6463a41ca786c4d60e76a2cf71294fb0ecdb9da3e2765f679e3157bc48c7b684116d5e76a13a0474db2bae834e93e1408944a3377a0ee3e48e066e1a4b6d164a1f0dad493a8bcda73c8832d256375f7c8bbc3beecc3523ab3ff53c4b59bd5d7aa76a2d617df64d87743d5601cf306f1edcf67a742b2462e652fdecd1fadd5ff5a188847c090cedbe91b07f11be7a0c5ead55724fde695667b2748da1dd4b4ccc16f3ac9d1d12e238451e02a6e568299bbc482a695d7907131f1ff76e69876570e9fbc590547d0a578af61018046788c64f6a36c1c683f55c665e5c597f3f3c04149894547d691cd93a6fd3ead19c602d385a55ae653847f812c071ca623b58cb4aeef98861a58432e499e991c33d61004b102443283018bb8ff7420a1e0a0bfd955e79fdaf57c438b6687a7c382a93a16f78147fb2087a20066d0cc3645e4a6c0a7b6fc3428af50826441e7bccbb84c92567935caca940479dbd78b569d9dae0d693d0c83ae597223bfe23024292c36d1e3bd9d755fb4d7d59db78e75d9ab5c06af0de5582791b223606790bbaa6169cf38fa2caa82a1e46d549938987a9ec3de7df22b693c620f3b885c37d2a604e78dc26796016ef5b81a3274cddff09cdf898d84f9e1e990026ffce732c37cb35fcbf8f8272c3613b9a2b7312caa9b7556e16bd7e8ca811c85d8d59d3e358c1b6f44fa9449687a01a8da8878ccd2b73697f225667ecbbfcd166958d2185041ce9b03b0908070f44e9827440c7aa87653f354fbdd4589ff4ddcb27cffe4a0755aa4b1fd51602dfb3c842dc1c0ab78b748c7afd08d1d5418d874921bd0da8b447839aee22371fa4c2ca4a182ad249704d86db449ed91422fda4311018c7da08645f46d7ed8eb207349a1cedf2e4bed7449c5cf5615c16b887f186aa44e69e0b52cace5e8948b190b19ddab7a7fa22a7778589d3e7e1964ad2fbc142063e0adde6750c238a40d39bd93e3c8087822c869c4cd8e12c6d075ed958fc7e06a0172d99bc4328fcc952c60069e14c70427a91c43d8bd5c650cc874836224f6157563aa8af9ab1e1536d1e6967a2d8409959ff1e03b6ec44f46ae70b6d48d1ce93c1b3d38e1466300a3ec8980e9551ecfc90299124b957dd5062cdf648786c70d8c6596e8b57d287eaa87aaa1116e406df1708a2a03396be27ef79338e1498a8e82c747b099b2a791827cf97bb4b70ee24d612db8f6862a8bdc9553d831114be17ba9a1223d6f919e952174802a755753337a7a7ad63e7a2d9e3a5d723a2d530bb703838b20567f34101fd1c40ba07e60ed212f1bb6b0c89f963bb1133d59dfac88f2eab5c7fc146f51d321f830de09760ed9d8afa6c4e50bc02bc560f6d2f026065cc14107471d3b40b4ca80b76a9697266e6a58b239236ee06ecc25cb4bc5e353bee892da74527310810cc6eb7ac3f1f40c3ed7cba8ddf8e270ed0c53966b98797d06c6e75d7b55014c315617ae4560af12e639aebf60232b7f852ec9d479010b3f328affea318075f5731d1f68f4066060977428b1cc935a8a9681b4b144c394f8719e80db9d01f23a18952387d513181ad082e87264ed2f6ed18a4dc1533d0a35997712718bedb972b873eee40a2a2df8de6739aa9e322bdbc4fb71601e03a5a5c05da08f179dd5c2a1eb3076383d052ba2790b19d992f1001eaa70f61f17adf456b6bccdf0aae90dabb80cb0bf303e5fc1ee1fd129f74198490dd877e7eebf9a2df0e6032432bd0699f0229803debc0da4e58ada9f4979551a51f5a9cac181db016d4dcf17090910000abfb5d7c89f35f803f2af27259ea6f8c3e8c2849e2332697a89d5020f46ef07cd770bf1540fea48ab0fd336905e9c347d3379fe41f248a388bc004a050d072f381513f64f7843802f865ff3fd9805a10e93685d59403122f68d2bd8871d5157867e9b7635842690f6532d70b4cbb22b930548640b9cdccbd0ff1e6928f70d2305472d6a13cd4513f6b46745ff86f54318eef2eb8a023ae06211e0f6923df53f7c36574664c1987ed1df5c5adc085e3e110ce91cb791d1fcfd9903b38d3d6615d3e90e75ef81b27de481e9b454dbc9b4994da8b4ce704616499645e019c21d90d0a3daa60760832019816978fda118ba67f67ea0f930fda00e275eef1c1b17d7973726cecd9b75308f9631508f0ec34f606cb92a5d1ec3dc747e44b22fa88827059ae67f32d7beb422ed85948e4bcfa0b9ae1b7ed355a3792101e67619c9f2cba9c440d7f1c51adf1c21acbd7c46982c09467c4463fad0175f16ad4b1130b9ab20671d412274338313d0cba4caf1202674d2144a9501991d4585c8ac48d00cbc0828bfb15149c7311e1210949f74beb65e81a49403401d6a669621b52ce362a8911f04a60ec415980b78fcfebff641e093465091403aa4206bdfc7767b97cc0c8e6da82e97226ffd6fd40644aefec499a666268996d2ee7f27f50c066d97d2118d118b5f754c83632a791765e500002121ba23234c49e17310ad04be4592f31221ea5faf4ccb80af8c14befea77e4d3e1f1e056111a19ba29bbf688736fcfd4a1f04cecbb170dcf51c542ff6a3df4610e173c2d79d0708f976a75f7e1e6d8476294a62af717c92afe490d6221f5d1cdff520681516f47161480fe89c043257c60ac8635a3c57db15fba1d3cd8d71b5af4b121fa3c30e27fd2562d953e22343c816317e90fcb18784bebf259a8a3705fb249c4a74f0e178190bbe24cd352775911b53f09467fbdb3de80c9424a1f73b15e82895886920ee8147b3d1498a4a123d3191e680cc0aaf7a3295bbc64eda3f32fc3aa08764c2492ec5d59ebf4a002b2f2f1d42a6308a00fda7fef23b5c892317b24b00abd135a58ce5701c5d868642238cf32969f264e28803ac71f5483212c94b66bb0b58a719a181025d17f1cc381b9cd7c3c877d236ab68be2e5ca94cb8a3847b7da3a55af18b0dd460742730c790bc19130f33f6ea11019865b1ec1937ebb98378a26a4085c04b00b21d1a62b6b8e116242c5c303bd0e5971eece4e54230ba9ca99cee962b2e89319da81566eaf50dde148327073f93e9a275a665e938342bfa3843675048d0ef8183ab4bc015775e11722490a02c399a29ba427133a25b618f164b496807784f5d8a5f6ac49349d467320e740c9eb6ea08604874f07b906293e8a71a855298917b7060a845e40401ab40ed74082a31a97080605ae7626e256d4e8ea3bf68987c2f0a7b5c653e6431261a0b3266307673cc330c8fc84441abca6d1a95707d621a2aaaee762b0e01cfc89bbad795fc71b5bfef138ed619cffef71b9d05e2c8d394954c5c21a07be021318035bd3f2dd890eedcdff3d024740c9441a4c228651ee48144a1610886d52f07d52f80046620d17dbf58830fa30d1e086cbdde0e8798379629693a9b107643fd51430f5c20e85f5f16084b0a5f5971dcdabe0696c0fe41e1de64eab245d2a2ccb4811b2b2a5de54b57357a9a80a6bca9a79e1193dd1a9a6098ecf8162ea7b2c26a21484f08d32daa41b3b1a1d9826e575bafb7eb5d74b28dd46ab98f57d2d3712fb55a5bd55b955b518b0fc68ac7b9878e61a3c69c629916a6e6aa084e4fc17d47f48e3f843c7e8010eb6c8a88d184400f1bc4198322c1aaf55863fddb0021d3b3c0cf4fee7b2c685617f49e64884b3014e836c0e02a6c59516affa8446bb119c87ffff6b2aaa2fe3cde9a54204eacc1e38d49f3dfd656dda91b5cafe586f5655de7e4658625b600c1dac54176c7b10e81a2dd75f2a25c9743ec394c8347e10a225c2e0e5c0c26a6015e6aef8bb078fa888329d40b450766d639c041d3fddc1048f99e847b0031f09ff9acd3d97455760c55cee5709ad1a40339f879af2509cd68290c6809d3d0182c4cbbd8f611a40eb62ec1c72557edefdcecdda00e3134b5b8e41fec0a003dd2c3506b4bb2dbcf588398ee49040bab7460f1bf2af4cd0d061dc7126e54988505e64f596be25fc828a0c9f1b62cb4f1c5973f0cf9ed439a4dbe68414db052caeefe64008b2ea722b080ff3d0fad241241999f9468ac3bacc28c2776644250268b7c3a4b3906b4b3350a8d141023797459f6c02ede1b74b98db06bf44e30822aca84daebd80d82c32291cce91ac304a80b4869dfebb7151493169da0c419e2d0edab5813aa2febddd1dcdde643e97ebc2ae881074762fceb1dd4ccf9a57a03ac831397509fb913f02663d6ed03c2e03a41aa387fbbc62ef16d214744bf9d96df55f78392a4d25ccc34c0aaa7ca7c4cf3dd47f508391df3e839db57f7b93838c3dddeb73e8e75cdb8898178c868e325028a86eeb271394e8ca2e9b12fb2f172405d6322ab678a404b091aa52cd18978cd32230fa2e4e6f04ebc34faf5bab8f35e4d11d6ebb2640094da629fae19de32868d75ed825f8864108873194c39ebdf25417c4020d0f721ecc4ef525f3d36e4dd63d62a0b878a91a1662315b440f3b1c0d04140012744991c2f3585dd68bf73bfdc804e394ce17c9801074e8b270c616d0160dfb2e0e6435d3020f45de64f1fd55e1b93dd17ba2e6e4a2592351b44598d732114a764c45c895546af728cc919bc4013ec5dc48094aebc1b477d396c4356aa4cd233dc3dcd322e69295e6e246af8bdbf50b410d86136e0e38c5d2ca1b887f07a99d610e5f6b8c4ce27793c1358ab34ddcf63f2b64b65c6ed06207810576fb591543600107e80e49ca619c14936c4c029fa50a4cc2034bc398da83ab6968452f451c833f45b3558207004dc060e77e437e06a17f2c93d4405316ec26c3066b6c828abeeb80ca85c52c88b8ceeb1012513dd2e298c5625a4edabbd1e8b2b495337085df65eb7f05d12e1d03e1234721541f85546141d233326dafdb85a93ab615864e96c46042f700e6b4e43bc65d454b7798df39359e2681b8b6fcdb223d2723449626f106fb9187e043e9aaea82be91247708ef1111f31a46db2788234ffe29800553e2d3a7e73ec9fdf41e6e95ed35c97a4e28513baadb0ddd952cddfa0b91002c46a7a82d802dc73f66522ad3639f886d7aa52f32bac2f1564b819049fd87d7960cba44dcbaa5453c9144df9d684a708056a596309922cae60b8c123b88fd951b0859816791cc1f7232d01ae4fd5d3ab3bc7e15dab9224dc799c934e89e06d231f5bc475a685d4053a9f3991434416fc83b103490cf4e1d882e64fccb6d4aa3d4d19cee4f91a11002ef25288c2c0085cf053b4e7a81fbd1df14ae177f66382c271f78c0f605635d6b53569ffe09b339fa90e3ba63c08a25eafa97f5c554f65373ad254c359e79ae98404b5570793d20f9a92a323aed1aab908769de5c0dfeb13a808b4a58b832f4c6e2e9d0c890e8aad48e063c1b82e04c83e67e34f67bbe963404148bdd8cf6cc0797ae998c84068f3bb3dfbc592af6268bb39cda9b9bc55513933ef62ea18d2b69b4bb5f9ae515f718a77fed7363393fa1097a126847bbc556df26932a3797968dfd63bc928f7c73575c72fcfcf38e70a93e80f9823096bf7b920c2e2cf69be33486e7c90f78c01a75a0770ff0ea613452340755cd0c83696f19beefa7988f5a0772eca56b3db6b450d829854867462465d88a5b278bdc5b75a2dab07cf2a47b4bfff10bce98576ba64bc72cdc12fbd7cf0e675ff41d002582fdcc5ff80d4bc476130ac8fab9729e746a2c9a23782bb57ee515d01f4036042df31593935ede2305d54eb2bfa4cb64aa752a952f60aca5fc8d4fac98175cd697206c7e0961674fcb1031c28b2c9ae9b2ba8a8e861a009cac598eca6a72c26541f219f2a074cc6b88040008d5234f704bb44fa1a28f8b1a4e0aba961da23eb93ec452e8b1ce6d450c01de456eacbedf8845c0ef1ec507aa684d572a6c6d510fa3569066482f40cbccb6d0046227e45264a74139d3a31106d13764b6562f82fe0673351facb4ffffbdfcfc85a30b99b3f2ceb38a6858a7d5006283ce8d2f9526f7eb942a8c886736df899e7c8c6388c0600b4479ff9751013380d0c640ef9445c2e8a9c8d86e75f4ab0a045b12cdaf1fd0d81171dc4396f2b88149f1d6a714e58857f04b954be2d48cd198cf244150c8431abfa02a551d16db246199ac36327142dfb42e57dd990aead33bf41764b8161274801148d3fd506baed5aa18a3c39ca078d08f8b1823c1e0ebf83af0c5a5697407857d580e32573f717dc8a0325c46a8782e7f10af319c230c422a5c6d4f23bcc18e016b09fe90e1a0ee05072fa07e799abc40b7ee9ebc2ce6d5d835b05c7e17db5c1c813d05ef2d3b9aca1d3388293edc512f0624b95a8ca8a15012abf54b67348462b4efa5ddfb56491804236ead4d9d2ec0c1dfbe85ba3a47ed59b12c675e19308b515132b2601bd62b2a10fdba37550f9451e2bf5c01bcf6e45fb66439bd2239f2773c38739eb5c119d26c9a38d6c7475726dc8f6db7acb1bb48d5cd055a7bbf87b22d3bbaab0937d306a408b289155f748d63683d464341118270e86b631c2cc6448e34abf3904d6b27104f80e8762c398e39db084559ae88c3309a52a999bc40be1c09b8ed0c9bc027fd753935ed3cfe4875ec0a2354aee2fab065e1dc10b9f428621cec5c23e4b9058701c4efcb1d81fa68f5a6cf5b87415cd1fea63d5e8b74bcbbc94593373e9aa8552754554da69cce451d28770459d622b7eaa0e057f5a5b2174ce039c40fde8eedee81339981f5116e4b27de56d4d42d1235897cce28375aa95508b14cccaad574859e1084d0b9d581a637c14aa8b132a66c03d1eadac01a2fae834b083c7f606d911c5fd496059bcab9ff82c12da259eaa2d115f395c2a91f91ed154e22e4aa1a8e05e4527c4a19943cfd1c42accd41525586a01fff8e66fa06c876b2e80be2c22f1aa9c2a57860e18f78704999a83257e5686b197feb97f9ebe47494586c34ff91b587b68ce05700b9b72b94f28f1522f0f08cd2a1be22a83fc826daaa20552baf3c9a9abfa88d7313d5c99767482814d9146cc431edaf7849c12ac1a6f7828737acded992383d8622847980e30d116b00e70eec3043c839259601e7378fab8cd9ccda075ba245fb6a1f0b62cbfa3a69b8c1ae753c677f517c8e52aa5e8f861e54264a2c43e524a8e36d2fbbb8b949adcc2ced9dcfd09e3d82f3fd703acc4077cb8292f5ab61cd830c6d43be9855461ab7e2da48f233d53df31c37a058045c76ea4c7a2046f572f54873bcd2db17e78bd488e4af2002949bd5f3969f7de5f7053dc844a28702de30b8b104411c2f8d6bd527ab3321efe83947ef3318732bcfcc6a74e43800240fb0f028e53de04540b80b7ec1bf15605707140b0c57eafc8efaff8182bffefa5627551462394cd8ff91c3f3e1e87fcedd3cb504cc49a93cded15f9e2eb0f0c27732a2cf846c6cc77da5b3383d3c2a50d9d87b4ed94472ea7b55ba2f2ec0fac5b98fba936aab4bea63e791b40bb270775d8497c078d046d3069d28dbda02aa3e6ae0663e83bd102dceb4464e80d0b8d4bd19f33568075f3d508c1bf060ef9bb8a4caa0d15aa6ea98a120a1b6a6ebf599ab1b74d526edf7c9e00851465f26843bac5df8a0a3f604aa6cca8b088ff5859141a66dc6c506be24347086309fb9f161cc2b035475a3424c0ef3eb0f70bce43c280698aeb960f58fc608e662f4cc046af85219b88f460786c5b78f97aa0fc8f3e34537ebf86a2c0b4f5618d042b5c99c428068c3e79a9c7997d35fbd35c0f93439e48f022875a432755d5cec569a6904097a1a99fc1348413bba428fd672553a40c595da1e721838e0a547b6ab1a1f1a08e8d4265f2f9273258f60379ac15bd15077b8656239310758b422ac3667d1b14f4c91c88f6075e742a98b5ce08d1ce57e2643333ce97e42a76083f8f2cbdc484a152ddf43f9b26368cea0cc58987dbc690527a80ea8cce61cd8db7774a6563a3cc92983ad3564bb0e83be9b52bdbd32aef41193da50cf1e1a4d755997a5ede7288e4d48f43876080bedd047309cf83d2f651054a42719f599343978dd444bc6d0f3ec99f30ea4c0cd2de5e2f642784efe7aa4d595e3d6e3c528d2c3cb1f184132500605e51c9e2642a5db48e116f650905e49ed81373d1e2ed86726604938149e5f33a7293a013e9bd0d43d29f594ca0536166e33987dc61db4e0917329cc93c2833391f398e6a4c0383fe4a1fa1f709d9176bdb92536ab646d751e59dd02db2d7a9e0108409e7170277d5f858dac385bd40bce6e0886a7b4b33bf4924bc1f2423e3cc5698ef272edaa02bca8cb9000e4120fe35b43e7e9c801c0cc5da4a93013dcfb665d05f5a954266e20a9705b8799582f8f8cbf0291e681740caadb6cbcdae5eddd814e49c080bce664cab1d8ba040713f0d3849e898d7e36ac411919fb56018b80d403dfe62d603ad6745769b60d0b6046e9d1b4a9c896ece6ce644c2f6b922273abf60e825b639a8034238450f93f822f4d96630af25b68db1b8be58a8316f2313c5f09c6ac8ececbfff4081a9a938da4e1efe57ab3cfe69115911afa49897f0eff48f450c962168644b1ce7796058c260570ba229b8df9f7e85286cf1d38d5ce78b4a9f82d4b448a0124b1dec0f47e0473a5d8d07d9c13f42734ffcd29c450538c8f6c640d56919fc7f230fdbc387130c9fc8eaf02ed16cb74cf7a4eb3816371ab3192f6d82ce8472e42653d22a5fae0ab296d935e647c5a1c5d9909ec6528cf83cf7a4d00b0f74b0e4355900ed127e64baf6836cb8c18985a0bb48b28e2cddd0c83c05ecf088f45fdc814fd915e9207075dd8303281660411f70733f50a661d57d2dfd5a2a296313ba43c7571ee5c46e464826ccbe1a6d8726b67d0a4e56fc2ee76bf0b85c36dff559c1ecf33d4a32b97f81ac0fb3a1ef5fc8db98723f4cc5d2aff315ce2e0a4010112fb97e9b527f41bd67b2a66d43dd3586207f1d654948151cd44ca321e756c5cba9d44b9e8f724344c4e94814d82314394c28733b4877013d1e6cc237e4d74101c84f49ba9a7d00dcdb668b3c3b507e900887d9115aa991fc797609217b6a3de8f7bcb078659a668ec21166c538fe894eb143b3df42cafec0b8a583182ba2c8ae314afcdff3b215ccc60a21dc18b730d59d0d47ec0245c60a65e5440acc76c0dafc93ae373f8b6f56274e079d995ea79ab561fb4c15a5c307b19a617510b3c20c215e3da04ae61b9036685c3b105026d02ab1278da66627f11990970f347d22e47170894f02c2769f5aa0d5f6db46cf3ee996c68ede1dea816bf49158eb9a3a68ea6f613d4c4edd46a9b295637a4c6b2c8c3fe690d61090ad3aa6ea10321e6b559d6a453f716bf19860ca76fe01e8d8e794643beaf0bf322a0771494a2645a95016531daaf5c7a21b4db01c558749e3e159d952b02652d5f81a59fccaf8ae3f280e727c965e1d3fe67ee427e1fe64f1aab09032d7a09f5aaee06c2d4a34a897c1134d9a220e8e0c9b7fb935ca4401aeb6942732c99b8401ff2aca2398249c590f0cfa0d5639e22ecf1aacee33491a5a4e2d78882659dc06d3f0186b09ff8f4bbec1b6e161d164c9a8e3cafa1ed2278a2c8b283a85988884acd6484b618395181c9ba38abe4f7c57aef001fff311fb36504a8b11e9ae46272f810111dcbb5a62478691b84eb9ecdbb514a69646b4ed801f3e8b78e913b89de9cd902244d9cddf12244db728227795977a1814d065e8752d885edf1b4d65d427ac0550bba5417281eb56c05753720dc997c56a08c44a1332f4b46569e13c0568187d8cd7ac97a158c5720167da760119e015bdf1db7d893e0e4a5e40bf0254db2ec91155413d9cfd912a0242e6d27bb974a01444d99436296944c4dee492cbc1a086f250db52ccd47cf478b501332138f086fd367ba991573affd6bc0382975ff0bd10eeba529c6d9dfc12d987ebc49b7954053fecd8d1725f77d75704fcb258c836faf56b7d1a04702903b5a0a7c4c217feaa9b2dcdda821d7eada0da9766cb4996ebeff3fcb283897ae568417b4bda3e3c4dc729a39ec3e4274184316e842adf06e6a528231d82d3c2ddbf9fefbd06f749602089161601e4093f67c4cfd1e8aca4167104346836752cce382ba0868226f0d9428dfce013ed1da11469c158678cd9c8fbed77cde8287702e8bcb3a5f0b12caeb141701747caf5a6d9e694dbb6c24295241a1aed81a7d7e49e22fc0e4a22756e4548e1a222f3da9d318a387db1ab0d8e54a62bc9d2d48a50e98d7db21c18322e3032dfa2d5df302015bcb687910ac3a23708fb32b3128b03f653dae55d9b7370de05305bf6d5e54ee9488f2e426ce857a5fa9b33c3863b5810a1dd8664aac0b703439ca0d038c18b2c63fa24ce3575b5c4f42430088b140e7fbbf1420712f8bf92043c01bc522774d50a33da91a2f22e476bc05dc5d8a308a9829357e1b15477e171c960dec328cd521dcc3c8330ccdf52910b11223069e672ef024fe761a618befd11814951b2015da51ed54193c22d1d6836a6d706f4a42af4ab275ddb9f6ded2339722c9f3fd029b5304c30b07b0fbc0dd092a386b502f802aafd202f554242caa1059f85c7e41fc1d1b866b4349facaba4255b0f849b225b10a513d496c6ce70ba6cbdf166992fb329cf1f5ceed998770d56174de6f724881cdac946eb34d1c506f8ba86cc69b97d90c8b2a0e4400b54debe16e69c6654d2b9f1d36b34f80272169cbcfeed61c5a22f146da42a9b3b9411cd790b2a8b569c7554557e55e555d10b0d0474d75ce281cd59fa3701545170407dc76070bc03e81f6367175d54da3f9dc3d10534fd8869fea87afb0c7f4c527066fb025c2ebed3f5d8bbae1082a2cb5acb1b7bc659ec2ce0f95ff10d8ba2cb1a3ffe56fcd2e4eac18b5216cad870c9b81f4c29acdf211990dff82d7ad422d52e7f8d8b097358a596dd3f19dad9315fb5c51f1f9ed9a0095a396d7ee36c07d1320aaaa3df05d120362dd8490ce469a55b89b0b1bed5fe317edfa1c0e19106046396ab0934af72be7be909835f651a153c2bf208269ee4270067ee0c6dc0e66a52c7340c6d86da2e5dda9dd30d8f7a34e931b7625a30efb196ea2b8b1a1fac2d3250791c79f3ac92a92684107218119ef83d5374e4d78538b497f7ccc8425ea5cd1b7512f0ee1ba2bd1c5981b9f7741164743808341b91cafa456038417a15c049f2169a44e87cc50fb549a62cdaf0cbe85a4bba4af70adb5d479dca07fc654ad1105120b877c4d66f979e6149a7ceb655888f4b51d4d4f5e6b3a82e00bd423b23d334856ed1997562cca85921dfcc512cd01bffa23b5b88053c7d279720057a0933029fdbc049f8ceef897411a919a624198bea23c89b3211c6c84fd77712c9de5b38cf2cd73423ed15de063ead87a817cb85bbbd8e58ac46a202ce112babb60f648eab22a3e9a71e702d8a5e01192136bc1ef4a619d4d0310ac9c14e8d0e80ff9dcaf887dce2795a48416f4e64ae0188a67cb9d1abc3f1e85157bf3aeb6dbd3f6ae40257f95ec3005d530def59031e6360f6468c30a4cd34514240e08a8cc08961bdbaab75590a5692043c17b8cc3d6780d955c4f1792b781a93f45612b932e221210f17429b00b4b35008145482f218abab9870c30e191d0871727ae944c6ed1571978477328fd986509f1276fa6adad31fc978fc5e96db5b7404db0e7086d5b373be097a1390c8a92e617be7848e0856f5a5e53d4376f12c3967fddfe04ff868cd428131ef2444b573d0e7e7899b2a5a869a2ed19da1b2b70453b883e74394feb55f53ccb510e5e0965e2828492022a8a7f88c6f31c5bc6d72f41dca8744a54c562b22401a5dc368d5ae15980f0da0554a0ec133d8bcc023abb40646344e6d17f486dde77ebb0fe3e49ce0acb6afb6e11cf70d874de6c7c2b484e57efde757ac154c4d53ac149bc8b77f414808b2a8b71a3091a81c3710e2a9d36de5747066a9b54cca337b10ea947944079de1791066e959b3192d15ea7959bc1bb39663dd9cef5dbd1f36f20d6fe7b0949c37b7ae135ef57e70de21042b54266ebe7a743089a783920aa537d88f09208d8b392a4fe77d24793fd3484bf6de780b65b2b3fcdcecaffc48000d252076a2d44fde6c283ac595e0f99f8f389780271ec6852f3f63608b47183942aa757f07421b718522199772b50f07580b7e4e98b848e6d5f6d1d784e7b8b8994d0f2b66bd1ea465724f6ab50fc4157215ed830be3e792b0c908a61ae01875698cef994dcf63b8447532893ef274cc25b7a8230840d1d442bc30f3eccce9485472ab1b3ae7a20a7d40089e7d7287048de485c6ade633549feb12cfec21f13e9b93877f32302dc77ebf0bd6f20325c6590236c9c0eaf156777b282724361d3099eb116948601a6f41f5abf30834ed32338f169e4002b3d026231a48a70bef6d6b72cf3df05dfba0b03e4a357ca678b885f3f542c8fc195b52b4ae1e34df456fc42d28021c8ee01c3cc9ec2b6612d17044c5ad99431c9dd7c65155c85b8e0e8760b300f60e4e41e141743820c73b011acbfeb514662c53121e0e8d5e752eb1e8c639dae88638e4ef0334e50374d508e8b31a74acd35801724e8be6f70cd5f0b3c67854283912626aa3d8f2d861a2813752bb55059354e09025da3184235f983808bc11dd8371668c39d49360a4e81ce740d03cf7a4926726b908468029eb280c08f6ab1f32fde9b9beab2ad2fd2217c8c0946e928e49d8e6f901478ab904994568bd4bcca65a92ea0ac847efaf359dcce8517cca9e42c62506ccd0e8732256e1b0250603d41223da7346b75962b6129b46665962307d9563b9813049b0c4d099ee2b31e19544cd33a34392f9a1db0ccd83c7c7ed9598f484247a2d591f0851bd728d13607891ad099345082e1592e7de18e938315063c05cb5cfda080aa52b2ef8e12134c8015dd4287f456aec4b3a842b858e4e7fe6ac348cb0c17360cc32910022ce688921394672bfa1017c757c0cbb871bd85206f64d3c4530c1c6eee1435f61b0356813951920a5626a4a1ba512eb232940c80ba154db09a4782075e87c5cd399bdf80f8a09358b22c0dc5a65f3af50db313913b5bfc6b70d93104f4ea4707ec5c6413e96a849bb9ce589060b725689d5b4ebba4b5306c0d795eb505495ff90675b2dbbf023381e3271c5631ce9be67ef2d838684d3178625ed2d5be716e72fc965c690602f36295f64baaa5507984d45e3250971d9c0f97211b6e67e44a431bf3e7c09566de3f59fd7289ca0dbe7dcaccc49b6e68d8ea5fe81d2b9f793848c2b35196ee684d15d026e802013ca54a2798ada5b29e4d5fba9398ebcd5ab3db9baad6ac6b702375e8d3dffbf6ed5ec7794ec8b28b88b5a5edf578858ec65deb1b6c4c2ee4bde05c8325f9d3ff17a72db12083265590da06ab3f875b0735971ebe7a0048d4767e330647796454572423045047011cfc903a82dde9bbd4338319785fd38c34e19014a2bd6a920f6480c39aa17de8790334c562cfb61494a90dc14a50a95f01a2a82185e63d9190f0caa75a3daeb79f8025848e472da38c13036ce84eb48a79d0b0d1267a7c5ad0733d0bb050603142edeb4a06044d17427b781b27039abe21b17024b3f273903c4a7401957c90709df19a4451e404221ab48f05ac0914e0556086e15447f7e90309edd83a96a7f9ec3bdd37c87e8970f10043441363f3f769bdc48e299662b229b781c53f7d00a7d39bd8eb771662932fddc90d40a2becfec6c0206fff2a6a8ba62f933111591fefb4367cbab6bcc840d8bdd7e052925a878bc1d1369f88629f75c4729e2c7036f652dea484396fd48124f4187d144429aa57e9106d214e7dc212db4365ac8f4e0b3d24134113d1250b3afd606ad1bf7a141affefcd99530f6640e9dde85108b04474ebd1ab8bd673b51ce328dd4e3cdb314f0c8f962e3106b68589df552e11e7903f87527778c3fef9f4fcef42f7822c7ba86ec3e69ab27316a8f96ee6b9ccca6ac3ab346815144563d07b9be14af51fc21cce51dca2aec0910a5d29a8703331df63198139f9004459a0d90638ef7534c9028ed620e2faca92fcecd3aa57cbaadecbc7a0a9159fefd2ee89f793007820d3418991d907e61baa1fc668ee4f8ddff5c77cf488059b9a9b0f5a277b28842588e75270c1e77fe0d9263e940809a7bf95224078a6804448f2c4ea20521cc7b2171de2603585228bbc91a398df4dd927f690972a8ad928167649d34b116bdb020574c04370ed6da5e7f928bfdf263cf1591a4fb63ec147d880d0555e40c022092959e0e7e9f86014334f7afc874940e1f9d15d61db7c8d45ad7698db4b495d238494df84f7074352761afc8f4dc48da95174cd84f9fc02c0f3da4d53e685159ebab0c2a6e2a7af29fb8cd5b555f091e9d20ac014d8e7a32e34b3a030ff6937ca54596ffa865199e49c4e5257b6a5a843ae49bb2c8a58789c4639fd6e769b086f174d0b1f96a187a41b0f5656b8b80237aa8066169d12eb690944835ef2f9160212ec62378a09d43153c9ef9fef570953dabec02a51439575079e680d23b5a8bfe370020ff32a5909aa828f3b5bdb6fcc8af6d75b9f8ae112eefe561f51602a97225b3580264d105ec6fba8dc052d6f9e2000be6ee3c077f6020aee3d52ab39069c4015d8d9355386e7566dbf237d00b0f9326de98cae0fe1c44c4bcf047ccde6a4baf9a7f8b8d533bab5f2dcbea68193da8289a5d068c162002e93047de2d35e4f07cc52b6a65cbf66f8b536b1aba664e41fa7f67e7823b70894dd5937649a7c0a199526f9928bdf722e8aa444c01c8e31e8882a80d5d7ecedffde4637795161d06d9be4960d40ee103a3ca9aba9ae5e4d9beaa8c18b415d7e790c966213f8dd29d4b54ee55cd580d06b99427ead75fed4d1b1ce42a4ba29a9f41039f542d130eb2a331c41ca853941393e9bd1f7596d963e66506c4e06371334b65b79cfb677d61b6bfce635894c06f9ae1d6b5e9144d0c10622a57a934cbca5f6df39240ddba8073ce6fdc8454b74e43fb229e9f7b5450aa98ba4b85c0b14415cdd4433a0ac0ce309c52d7ad733d845952cc7246bdb406ac822d95096e90d814baa71821cb4e39ec432163f6f305c4fb76c6561cb2923dde27c17e5339145b47fb9bfe450c052d893b99e4f7302364433932e4a5e26b0184387bdb403c6e26e646dcf3ea58269f083ee1911b759e9af8d141c0a6cd24a1473194c228bf562426ae37667ea055cd4fd8b7f6c91b77040e239189a79607acbfa7f1038e3187ac3f9f4eec9bf1ce4f04b67a4aeafff2ed629e6ee031d7679774afa270bbb784175cb0a7644fffacbf40438177bb03ee10ee53346403c1a284430bfdd0de66af05430fe8413a26d6bd791c7bf4ebd1acf637098711efa7eae8a6e73aff547a421587cbf508c9b5271e8a5057d136dff739a1fc05f45ef44d553e2b95ff1eccce39b7c5a8447ae1b78a4a6bdb4a09505a7d8f25280ce2a7cde2f6268062a07c8c3985a0136001bbdb602d5713543e8389debcac84df0f156f61dcf2c3e3e462e49b39d3f16c009f8cecfeab0ee65b2a5ef168a9f21ae25e4061a1c2df63a409ab85a4506a2eee736139612ff79044f62bab0a4750e56dde97248eaf9d745346f5a4d6173849ccc8d5f02c2bd55886162c8a795332c2673c7c857f5d689fd37cba093c0ee588926a1f7f5a071ea3452340d41597682663f39de020bcc3b60b0f2c2a3890a4c893d41f26c7097e679a1bc798c3d4bae849079048866861b2305b8f7e9a4a111607c9ba33fa594b7922cbb620de516aa172e6b0d41c033f890110644963578e61e6eaca32cd2e57caf1825fb93bc6f09705f06dbb88160168ac5fa76296042e17b5cccd9c3720032882ff476ff7000ed4dad02d3186dc25bf0b41b02fc53f5a292fe25a4fac97afe7965a377a9fd09779d3e5eed756bc10b6b61bcdd2d354b43ae5cbdc75a2bdeb3a18b6736ffb671d5d1ba2fd8ed4430fca2edd450aad22c253f88805e2bfb44dc8d4a617f37f49bfeadc8b8a97b69f40ed43003ca5166785b30ce424a07026d0563d3624b9e585045b675d6f88af2f2650b0a863ac375b916ef185a765479f0392e82b1fc2c59c513b167383d6704629dbda1392dda331023d02c5379d0573c7b3edcb730b3f3cff125217befbde59652ca246584074d07580746320713d115f6efcb79c4d8398c0a696811fb8f161b4ac638dc9672bb94c7de85d409ebb17320a5443207fb66451e29d163b74618e76c8d1efb8ff65890635e038243192e13aa3d09276358e289e88a8b89ea10c456bfd76b074de4f9b5d62ded9980c3d13770f4e72e98bdf41c30fbbef454a8e1a763b7d66f10cb8473497966a6492e0b6369e462ff0eea3dadad991765cfdf2457f233f7d6124e32dbe06da5c2c9189688a5114ac3d4c5ac13cf3a33c59dd1692fbdd3da7c9a8a9b96b3fd1de89cc9134f3ba7a5d576fe80ca2b355666f369aa8ca394a336b7a320bdd5e6ebc9c9e916576e9bb3d3c0dc3d719cbc76823033a5a1c8aa524ad90e020eed6e5b314867edeead0739daa7e368bd4a5a6d7733ac6d574a99d17a86a33da59436b576d4a7b596a3b46a1d05b1ecada3603d2339ed4caeb5d64a67d6d7959d2caed5522f5c4a29a574aa524a596badb5562ff294b56a980911194ac9504a260d194ac9504aa64c1a329492212aa30d7112c76a3808f57e64d8478fa60c671680016b43397f3e85644efb0b9e0b2db6c7b4cdb6e0b3b47155051438ceebd19cf34e68c9c26915f734d055630d6431a95c6834b4032171b43f7d0b21731ac914125a80c7a389ebaac469d13d9f4353680aa986c8546b8d6a427c35e31acf4f8b9e4bc920e9124fcf52fca4ac1c4824f1a33c82f59c488c9933e69c530236c4d0303ddd508689d6a444492899dfc4738e538ad1112c871fe7d2e4b2f9386363a6ecf264c9044a82708202d49a94499432b36676b3835c2e170fd31b520288899a49b09fde4b930b2945e68cd9657ece897482a04963ce3969d83c0d973f3c0da741430a134fc367783d34da490d92124dbec6b3d75393b3a7bc9e9c8a42c6a71ce5f5a45028f7bc1e54f6a204f15ee79cd7d3d56c79ce2513cff9e6f5709b4fc9b3d56836afa95ef3aa6945535e4b0204afcde035c75e8ff601d2d0e31b24b47cf655e1ba520550bebcc5625c3aa0043de5e95cf434262a86a1dc7b7dd8c205cd099cd0e204d6bad488bf4d90f99bfa7befbd4fb0ecf82d96780bf298fd090e7ffde27ba99080bbf7de7b594eae08c20cab595e13a323db164e5d132c48b426ae89971c300b6584b6262c38920135925ec91f71ee02043008426a1206d0cbc94f08582043e4c48720169a849c9400a8014c8c9c2001c4c216474e9e48c2020c8c6aceb09ab55a926d5e221991428430b088b20598dcbd443232832422224cf9090a80999c7a89f433f4c50f124ffc40e12c2a9c8ca1095119436528a1b12e7d0447d4aade9609218b3c4e8b2717dbc4e4d3bf2ef26c59b98133d6a2f530296b3e8ba40b94c773eb228bf254b756ecaaff2856cefa9defbdd8859e0be93e50d5a2f5e0c81224436d2d097eccf116477ceb2d5abff19166aef8c287232e578b3a8fc67d5db65b89a399ba09123298ca70e5600229685c689ac660da62362c571966dba25a9dcee974ceef7a67860d25b78f5c0d25198bdc9e5d467ad0d57458ab614f81984d6dbd6066a90e101062b94b5d91658b1d7e39fefbc27de1beb8900497f558fa419f66901018114c245dcff51ed02dcd39bb55c9e35ca22658bf49a1ca505b94d8dbfba99f30cef99b42736922993ba6d2c4d14adf48be5b1cee7a08390dd1272257d1cb08cc8fd4c83775b5d84a734787d163cc2a6aa3986c435a5a4899e8ca4b6e400daf81ef837c4f81c8344fe5ac431910276338c2c818466328b9b8202aa2a34498248941248653bf60cc9827a630929e8ee88f112e308ac0782ae3e933901f080864a466a5d3cf34c9a7e9edb125a963a3c2f17a86a8b5d62aa7d3d945e8104dd3d4dedf5376eaa686758cba6a0f5121fab2e16d1acda514a3445a795b25a34396070934d44343f410ee21cad44df488aeda312c2f1db986a8100da2afef1b1a1a72ad00c263a74cfd31313149a61a86b0d323fa7d97c7d3a1efa3b6bab223629eb9d6229e007044ca5b8b268f19a988230178eb9bd763712de18857099400838594297489985a6bbd7992479694357ec479eb7289b75e7126810adefab7e4ad7bef48a4129c1173344009a4a126ae2d4b6468112788626b0e2290c04494f1d5b3a326967873f563f7b58aaf4844dc60f4d56db64ddd0f752888afd8fab0be1889b1394ba7c77810be7eb92ba3648a122c3708c5944c716448496c042a00b1a4a40b20158496104999ae8c5e896d1a2a6fede4412a8900f6d6dbf5226491062644b691921d0905c5c893525a6b6d254a7d299ca199acd43b0d6b476186f9f5254df333f46b91390d93396d43961842501ef1df681c74fb0cfde3acf9d622736a97e9332db616c9a342af7a8c18305eacf826244c4628500dbb89f369516cba847de0640c4a9c80f102230999ba1565fbd2b7a2dc33295545b65e613926501f75524f1b4ed89c3c351967f2d48425f41c75b6a24c7f86da0364be01648e0d9fa3ab38796daba595565aab05a9137db24ecf3c51273379a430aa449774cc64eb29bf6ec1ceb90c95023d3f9239d4fdb90b6af2a88aa437a1fa388fde8b9f312fd87c7a2798900a1b70bdf819e382f1c7a3fa68a4443cf50e1ca90d638b9982872dc4f450bb9ae480c482a7def1a74e943a5198cca14e614e79a44ed4a99337757aea488410947b86dbde0d7db2734939e8ca488b64e486f5518bd4c71c96671ed1d65affb99ea7516647cd534debd6b954388b64ce9469349350c2f3ba0c0c4d7120ab03459c1651a107bfb528c5a8c529472ddaec5b53ae97bb20933cc11b2d5acf204eaf2c0b9438accf10640e94b7d979b48e0cb717e4c92473cd79e1640c565e62573aa350f2f376ceafe79cf34eebd65a2c28161c754ed6306b9a38a4903a66986d51253b76c5624bb228e72862619c33a543928aa2fbf7e55cf47d2e242a8cf260b7b021dade03ba859faed3d3cde92967b41919519eed888a1f679435c13823a7ad4ace9ae60eae0989630ba9837b42e650a7463267883c72464f7d33a23c0d83e5cf45f1c7cd6886238bba165444e22029112bc5eb2079b420ba72cd1d163671507769413e04c128b5520cd156bdce84a44a4891ba85cd1dd9d3c4419dba164479e813623cb530091be229bd22f494a67ecc96640ef5322dd2cc296b6a91d2316b921486f3e74d14e98970ab2bf2a6183386081afaaa62a4e90a11a22b36c03a06548a10ba62435191e6f055ede029f68b4e9eda524b8d24f258b52c5b142f8f88cb4a749f9883be0d67f3957105ebbf3aaf87528ea31dfe6810875112e9a56be0248f386585ebb42ee348c963ad49c04bf77e988180a41ab13c561a366080687fb8bbbf5fbd33b106ddc7820d3a8c73630fcce4117fddcbe604b9060f073b747043c2d286854a67c991f2583de8a42aab168ff0d966e70be797f5e086d27ce5072c9d7f0902019e6c96f2511e2b88036673251cc019d939620949494a4a5c66d69522a961ad1f783dd5034a716a98002080a7dc45041b2fdd032f64e3d54baf60371ba857edaa7cbb1a68b028c256de13364410800e00bc748e881bf39512411e7108f57573268fb547cf11bf9e50109b624c4fe711ab7d7a3ddc00c258c794478c03e7fc7deea2c89a2fdc83bff4400679c40408ea845445373627050802238fd58397ce8dd065d747c0f325c4f79da1fea42474b5836e5eeee0965db493457d960e0fba9a35a6aa481e717e52a73c6ea3ca54990dcdbd837fcb22675511271c47bbc3584addde7b25186bedbcf25e6b6dadaa5aa59492524a697777eb349d61ed30febeee9e362fa90447a9e5e5ea65d5ba9f86e30cdf614d15f93e8d410c2c92dfe418c460bc6169cf51fc35fb5a29a55d6fd42c7bea17dbea9cd7d3dd466bf52c08e69c93ca7b9db22e9d5d6bad1a94c9e0386fe0b0c2a6b47691a758bbc8bc5dd5a2740dcae4e9b8c5fc72529ab95a25adf5de7b6ba594d6ec95b9f6da5a6bd55cdab95d8b6515d265aaefd3b67a2de6bc32da56b39a6badf55acc755e190f4b9e35f33a6bd5b86dd3327bc95cbfb6d6cc6b9d30d8b56450489cc471ae69ad813797a20b558a9a735a87bb70a4e135d5f7691d963ac2b983a250e36bea8e976da28f4f18176a21e6b84d7bade332ceb3365ece53e2a01fe86eab92af732994ddb814d8e3b3010cb28794a7739b95a2a65d97a207e6a62d4d58a5ce759dd763dd9b3b54ee58e917d549a9a3276c09d6e459dab33a795af0c70a7a2ef584101c1753923c28805053acf84c8eb179db658c278ce0a919a454f514c7a9e32a9e7aa6fe35d1c55377249e22393186d1d3536f297982de6e915f473c15a47ed8a1b3e20955840f1c97208f092642b07561eab0e8a0f9a880897be12d4bdbd22babb8cb8bae2413311f7c52006302063f3419b97af0b1c2c8a8071e7cae10322a010f3e312123293bf87081195d09f2d9f2649368c0c5899c7a896483183a10c94174caf825121120a62042048e75f9d571c660a8a4d7e1f74d27b80a562f05196cd76e3f417e8741ec6fa0abcfcbf4585a2f05d902cf1b94cf49aeadd7c33927bf10c1010636e09f1d7e248fcf3df2f8fe2087782d244a86915d24151f19327f21b9a03c124c2ff50e75ecf61ed12e7287b467465be6b1cb1ef398cb637bc563dfbae49a9caab42937e7061b80372d7c426e1ed0adeb1cf806fe8542a60e2598e2490e5a1414b49e68524b94d74f4bc890ee86d613940fc95460a5f544f331075d217b89969c280f8bae700aa6d43b35eea36db2461f1ead11c67e9fc84c3d63dbaae48cebaa64ef477f295bd5ebf1b9a17e9d83b0c6e80a7b06de50df20ac4c4d7485bd82c92f649fe82d7a7c891edfa1c7d7f5f8be1edfa0c76e63168be4c9fce6b1db29bd73d43b358edd26491ded1f76492d938d8faa1fad91063e5a2a1ebb7d519e2cb446f87fb42fb03ac99c6a46aeb06357961ac6e3ba4457d89f62c9a37db5973cd6a5c7d8ab1592875597a48e49231c3f3259cc58bd7c3351235532b74774855d7a12b86e8de80a3b8fa64979a444449cd68d9eda22d3f0b19f28914d980ac74c54c3f1c35b953c5aa3948fd5db3b98e11b0df0468bd81bbc115bc42e9f01a9b0fac6254fecfd243eb5881bcd63dfb6e4544d78420eab13c83d57ad95c730db84d43c1af2680f92c85928e4490b995f0f85c8319e285af282c9d5ca42ecae9634616e3fbd94134d049916b5883d1552a21631f64b947d70f619e00cf37f481d9b63f7a13ccd4457d8714e61e750a0fc0d94df4cd825b6fdf4f98de6b9d449af3095d22bdc44e66007e50e7a84c48167cf6d4bb6b676addfdced582cd11a69e196ecdf1b68034d9489e9e808069bb1212712a71165fa8d62fc7dce8302a13fcee7b6701cc2f43ee61005b14f30887dab5129bd6ac72115cafe45dbd712722c91bb27f2f4ab9467488d90c917d47ec8d2c49205f038ba99d685deb1dffe02d0b7cf97440193058c7c177d3b0cbd93999424795b6951ef8cd40895d23bd4c9b77737bd14ea1b6997af42fef68e873c9d47d3a3ad67fcc0c918b87079bd5e499cecbd768bead5722057f0c909f2250cf2acc19bad1952f08547af107f5459a194822d4a90b6cc0029055470607008b01553fcde9b44149a8e3a73ac00fa5a3b89134014e32c35e1a46f7e578a7c2c588a319d398382f602054f38bc709072c3d367003f9014b5010542568ee0f2d2ca112fa0f19b19194315463f473724f919ea19d8ae497ec65b6fa30204215d41f2d665116f2d75ba02e5c72e7aebba42c58f3de5ad9d6d9bacf0f58ebdd6553b640fca4f90c67333e90529c8a0797b7611dedfc673d36341f3ee6aafbcdced5a0be19194a6e0f670d8e099107c830078db610f9b947d04e9951dc149cebc1b49061a7d967111d2a29d209216a36fb083f71d72032579eb1f2c6951e2c7b9f401985cbd4738416925e8a5b74292d46225cb4b6f85ab85b20048567cca793427bd9e9437889de835b0bb3661fc04717ce6e998c9de09f4a3b802835f7e823bcf496e6eb2ceaa859f731bd24f5083e7384e7a0270411e7da83e9b1883a3086b7ae9e998495af2d33914cc043f4104fcf474ccc078a8f1bd42167a6d3d2d4b969fa0cd679e0928ef10b7e63ce8cd747933e705718338bc3d7f6bae037163253f41033cc7693ec1d9d1e95d97cf35d6b4c7a1750c66ae81a38f769486a588c14f90009f8155e6d010843eaa03471f5fd8655d9662ca4fb0009f819dccf911a47e56c1f80902e039e9ad90b578a73441f319de4cef97f3a078f47143eb13ec6e28b5b002cac151a565cb4f90f519a881a30534d087eafb06eaa8052f85ccfd2f289194927c8633e585207e82e14b6f85cc259682c84ff07b892d853d75bfa0449a22f617df5c9748515cffe0550f84f31b02998f0a479b4779d722762e93b351362080f01287a30fd5639fe1383c77935ef0d24b013b0daf711e3dbb098af017f452b8a10ccea3db6380e633ac1ecab9eb61efc0f92660e7c0f91c9e586250b68892dfddb44ba4242b2f91b018f113bce990019acb1645781b3fbdae459473d43be1b62009a416bc94621291b493a246218f8465e92798e3bb934851bc7e821fbcf452981b9a414db24703a2b1209ffed2d7c4f7216617cc300df0a6ebba5c3b1478a36929f046736d626d0678c339e79b731c5803e2c61c28df03b78e4e303ec1b994042848f593531e9b60687cf1aa1db2e73304c14249e6f56991bc0d225a1332c7e1a87aec5cf7dc8979b4e4d1b863b11853ac29e6147bdad1f2e29238a80d1b8f026de85c81478c375c446346b1a3182cb684029d9317dc41e6e040cd97ab45eb63b55e8af0e2c48b142f53bc24e96879519239f2b9bbfae9ad1e05ae1ed7a6a6a332f248e56533fcd16203c55c73fe0cd1bc0ba2a7855c665353513657d03c3b613e9a3e4a41f389a4458d869f6e83fc741cf167467dd84c14d8403a5e720fd11f5d6c8ca39e29682ea4458dca167dd864e7d10d94f35cd609c9951cc244b9e833922bed0a2800f05acef3681498f318942a787a097b89d465cb5ff1fa0f5e227591f29cd669e06c0a9bba145104d1b4ce659d06cea7a32b623bb449d64dd488af8e99acb92c0a421fb502ca37405f86d94def84ce35ce51e31606a13f9d73ebf54c07e14a96e102d3fd65389d66538b5665258f3e6cc2116716678fa45fb12c5bd4326e03c7efb7e975285be6e8e94cf753bb94d0b491dea12678eb5369168591517e7d7a5a389f269a89e425c99c4eca8c9b4b8f85e94e7a678e38484b5497d50ba2c29135def0e969e1db67e6bd834275a89a02c709e4538836f1b4931b37a68b3635925e59b7363d28cff7a1c2cc7edf2f160a3d2a6c003fca2d131bb7804af5d35b6cd15a950d68a4c84cd37a32db87b72ee50863f3f0d6fb8824c13a0ec71f8fa7d69a57c3006a3a923a2e3d821e71c32ecd91d4a185fdd2e9925d0852c1ce688777ce39a7ca6f03e970c9b8f2a0181cc37b7de2b468e7b401279a5e596fcda7b7de320686d2f374cb7a27e91eb3e9ad6b7367be756d86b66d87dd3d7dc020dd42d5622e7030c08035d1c2d0a2b52fc0d0a2d5c01c39509895434bbece594785e3073e47f3cf557ee3c60be78652bede8937faa5853e3e8e428b3a54e47b820a3e2dda51e543fccce96d816a5909bda3eda0dcde70b4c05f9f5c4d2da0455b82064e47813e7eb468bd877c9518294f01f58e9d28b7fea3772447bd9e6906956ac187ea512ffc0cc7394e478152f3f1f3c17a1cba4079a63c62593bc1348f8d4fb7311bf035f6ab815ab41bfc04259252166f2d90ccb17e25bf28400515578a145d314274a548100541ca6597edb89c2ca1c6a57fde0898e1d2bb1a0464976e933397dfdc9185aaf98df91167ee58491c7646e8a1386d0d88e92a4bbab2b2f581972cadcfa2deb961c01c737c367f1cef4b691e969559e6371bb54ddbfcef78b9ab6930f40ee79b11a9a3bab5ae0f2ffcca34c47963b264075b953c30d0150c94a731ced7fbfbfa0556c03b08a88786fdea320fe319b628c5021c8a88690103072db67001c5481364c8c08829a264b1c1c9ac4c492c0bc5124058e9258ba6af8edd71b22c82b8588a135e9d91c5ebeb972f6fad95ec3858108de0d3996441c4054b5d50b9610cfa848932342c8ce044d1b26035ab0373c60757181c7c180a134410511813bcc244e941284cd21108588185b102041038620af365070854390ab3050f548ec28c910304a8307d354b61352bca8f1850641a2f917ed26071430f4d727d897403098c18d1e58627696e90f2c31d01ca4285e3acfc7047b63280b250e1b828595c2e233680968881c2868d0fc9880d20d7123150d8b00145cc754ea65259a5d539314c9a74680919c215910255a69794e9ced6789d3dafabf1e6161d949ca0256488a6248a2459e4eebcc65acf7377eebc1a8bf20e47cf6f4620ed27b40ca3e75c8327c8cf35ed1c38c2f039e49c07f57cc2c42c91f97bcdfcbdb79f832a79ec180338bf01e3faf5eb9cedbae92fd3df8ec9ce42f2d0eb5507c943c306d3abebb5c7f8f0372cf3d7c72ac46da1d650c8e4c23485a92564c846054a4b0317326446085ad587cc2f925a4f524ebd86d6061b803588aeae6b0056a126e13a05ebab48f63ce5637dd5787b69bf28cf34fcfb824638662eb0163f4ed88b0bc7d48c70acae26e1067dcd8bf2b417b9ba391c5bcc5fe75ef5f51de34290abd39ee1f811c9f56738ba9099b40488574bc8900d8a0fad27d387cc145cd17a9272ffa8e4b1632160c1b9b763134657d72f1ef353afc92e6174c6955e082687b94e5dbde3f9756aa4773abfde31a963fbeb0d46eab87fc3f1eb2ffee6e6e2efd85ab080f29b145232749e72947b9ed2209c4abdea6eead407369816af7b6037b578bd03fbcced588bb7c77419b09d5abcd733a516efd2bd1e02963aa4c2827389b1c1b9c46c6564e1b632b2282063b744327669e7c4d22b9808902035408310960e175abcb5928ab7d60f80c3ddd039af013318c4aa5a5ce13a0e715ab4dfa7815fd6b44e2a2053df52b9e67a0d28e50afc361c9c3983d8e7401c15c7398fc6a07dae3b2e03f33b9f5e0fc63d1e8a0b551d289f66dbd488641a9e401dd72fa13bb9a32345b9430089a50e96ccb1ae52b1b20b6bae098ec894295b1954a8e08cd475b5495bd21fab4d8b99579f4b9e04a84fd8e80e4a1ded46fc0cfd33f45b2d896cadcd42ae660244965afc2f43418380b250e1a86099b2f9b724872046bea68750648ae937edf480861afc1cbda0a14dca921d9c704438224b2ce162441811652b632b830922b62a990a9d9146738a06e40fa9c3c65b0f2275c8ef495e328738e21979b528640119968c028f164340ca4b4b34bcd1ac07c92fa985eb47ac85ebabedb14e85c821189169add685fe9ac81ab6529cf81a560a2583415ab4aedc2f5d79cb001089c37a0d7fc81ceb1c9c208ffe35ab2e843e43e41fd631ce4ed65a4b438bd67f380d3fc21fd4696302280b150e0cb7440c1436c2d8b8a19ebd06fbdc504f79f69b94d7f80cf73e2a2160e11a8950074dc941720688025d59af01adb5b65abfd5390faad6bab5d67a2a64512c99456dcedfe7f54bf6f10305f6a02b6b9d26e5ead662c0ba0fa9a3bf71fe7c9664787f41ef258ebd55b060fbe284c8921e63230c14ce35440c60c6bc9a7208ba612c81a523de709c4f6593f9d8f5681fcdc3d2116f388e6c1a6dbae9e9e441f274109d403c6da78e01c993e94aeae09eba0fa9a37ef3279341bd83b2b0837c64ce03e48a3a8bae288bf53d2da8d32b8aa3e4116f3fe69f8eb73272ff985fdab6211199f66811ca8f1e48799447d80c182eef4aac0d883c666fcf9e045269d2a449d3aa2d64978b490d6d5a3b22fbc8829247dcdd587032862f498a94c6a83f5e8620f535ef3a07727da401871ba8f116a494524a432099b7822c3d0c643e760e879e0aa31602b93ee2e93ed7418c7f8621902c6442bf7012a79b2a2ddc5c7aee398f6ea9bc0b8b741de6b6ceafd7aef39f1a5a5df893726f0b81648e352628cfc0142acca173da85120cdbb9e7cdeadd9c5e89d0ac67f7a4938657c88bb195d01b88b73072b0bc9e59adb5f3a66a5eb34c63d54bfdc3517553de58a73818cf6ffab8f1d3592de668517a074359ceb00653a6dead754dd7a0647052aee44803f5ea3fd64720c058c38fd22509928451c88fb2a6907f86e38f9febd47f6ca5610e5feb877aed1bfe50ff09c71f6f4306d4fc0ca524806cd51426fee9429e4caf610ea96d812438e2f086d9e29c7399b3b9901a5a5bbb0c41ea03c97cd47c03f4997460f3bb85456a70b58a081992a64a165d80310619695a9bffd4d0dac29fceb9300492b9740b32d9864cd7d150d0cb08111b5a45649ad6ab466b0b73d8fc670b2f38fe781b6e60e4f0b57e36e79c8639e0d60fa62be943648c888c1f2e63ba94f1a4f5f3a47d0ba9cb1b1287d21e8e887ecc4743eea4fd907d74169625260fec4157ed1d8893701044a6432d8a7d5d903af0b7bf30a50ecebb8af1dc4490a7cdb6853917b528851aa1c92315a2453b45429489cc69bf61ca54c85f680474deee0215ea9d9132f9f6a644dfde4e2813a9c33bf0463b42f57dde8114a8574d5f1f6c91c7a654322dea1d3a4a399dfab0348221db4969b13da66971a38ad3b7d6a12cd6b7731ca5aea72727a7a69cf4a8348d1656410b99220800000100c314000028100c08c5429148200fe464df0314000b85903a72549bcb836910a3200a32c0184208008000000800801087aaa60800c804c07847778a62af42045c3eefb1395633e29e034b5cdf2546325fbc9c514f576782761573019d19b546730653acc2cc978365d94273680b7ab0d6ba402a841a45626b2a7826cc0148433ad8c14b87bdb74671d85c2fc8e1cd5df4eff07fc2f3af20fe69ede617637829b6f1ac2acea81d7b731e23d615868225d8d30e4a2fd73a9ee00fdb3bb0379f2c623787d6ff0e60bde4e2429651c41054f1b8e5eb177d93487f1a85c27fffeb02c5ee47001de08d4d4e3da1a43b78d0cd36823dfcfd63ab1559e12971e51e16ad1d9aac40d1b8a1d5c36535fd152cdc1dd743a6d1e713dd022c657f81aa1b1ddbb6ffcae518ad2be036bceaf2921aa2705002f800c7774a43b0ce527d08b6496bed3e58b2761805597beb0c54416617d55f1b56af38d66223fbd0a748bfc1abad4d37eb1cb6c53d2572046012dbc8ad1bb71d254c3a3cb7c2e3dafb5f5a980f5c0bcf895fafada1b01c51473e5f878fa12557bf4d03819c452e6f12e2930139c8d49e428e443fa2428e924dc486bc24fa881878a5eb7e4cac4db4c33e138c559a01664d15c9de976c24c17b5706157cccb889fe8b74a68fdc3dc5d1e105186a265886585229a734336ddc1636a4af7ccaaca6ddc215b168432cb21f5cc0beff97ed10668377117741ea4e0f3bd6094655b7986652629084ecb289add5684280d798e06fe7c76f2dd87b0b80c6d881dede7223cf0df9aabd8beb883623568337f4eabd45978e1e8874268ec27d758f2532d17ba33b412f940e2c3aa0f4ddacc85d4d89299fdb772c99897e86f4d6737bd32d3df748eec647ee3edc273419315e634e5a6c633eb08a285b4d240cd05aab26cd03c1faa733e8e2ddf046250cc643a48e2f4b14500262a0095c55191d8b7e95851ca50daefed250b591c12e1f27cea70f3844a68eaa475d344ce97aef58357f5a422136c8d1fe0da71686bef4fecd995dd063a9faef2bda19214a5b53976c43765fec464fd51921955d1cb6be50b676617246b8478ca199345ed4fe1a90006ac71abdd7e67b3b1780ddfa7087d73d18fc125f72379742ea53aa3087501ed05505f77d03e141d17fdca58a194ae6d0c3040397839e50c2346a68db07d05c2dfa9d7f84c1cf3973f67a0f7a382238e01e438756988ad898382dec85da89415f9d93bad46179f09ec8ef6e037a8ac7145f753d6528ebfe58bb482feed01572e5f6413e4f7eb147d9e7570bc205523acbbe61a3cb0387a5b206768dc06055259084c297f7d579bb1dc111afb5defbbf1d15ee906a5e81033acca506cb4a6e9468ed0563273e2d88d221c33e56bdb1c7160e48a876ce33926373eaf2aa82588be50b23e6366c5704446ae843ca862cdfec095680aab539b47e3f445bdf47b92032a3487f5b76d1e2202c3282bc794d2f216d7b16bf4593d654868899018f277eae3f8faba52e7c31aeaae28fdd02f09d4032d3c3b7b30e9411460b3cab5d78d182d63484b6cb23b69315305a9d9a496b9899c4defdcca32ab49c06efa833c6e110e30e0e8acc1ba2ea4561595cef8a4bb8bc6a5520ef01a4ff440c6bfd79a6d175045316452ce210924922315e8d66b83a70966a8f2962788b7730a48439c0c57b50a3163d96adcaf00e8c58928bf5e783eee9f7b9533683224120d8c6fbce093b5cf4e17bd49cd8ec0dc92480420e5ea6fa84c455798b19cccaf848dce911cba782654134648acd0024ba76416ea60957934c9b2586926a42e08bcc6a3915093a968ed2eaf9561160d5b5a798c41377d03a62ebd9ea92c56e65eaa1e918bb67ad93c4d8c0b7e91209736a37da56e81c540a097037024cb036586efa74a4262ca2d657bba891bea062f9026b07ffcb72aaee241b57c1d563027cdfcda26064625d9adcb55825ca7cd8ab0de4595c62f72e236d5595f588094b439dd8b73177fafc8b8518787ffe52df8a56d030a1819e651fcdea99b504db92a225d1202c6c09f9a13c11231a443ff9b99efa069efd92979f4f702dc291b11f316fdc25965832d7605c31193a2947ff72dc8dd500b70802f66daea38bda1eb816f1d2eb0a28fc2411f77a7d5445cd181120e65663e9ec3d12b9b088f9a365f215c0ced12e609c478f0f8bd0fa58d2f5dfecff35d7e121921b90809b93198aa87ba951c80be1f90036629d5b15c67cebf3d496f120e9df73c60bb3b831906e7825194d91319d9ba2b65720eec3e7e3292168157621f2796903e8cb0cd5ad2b5f85f5a1fdcaa42772ee681b7c3a0209ed17218475fa3928b0401e2bad58841677bc944569126e3f1d148abec182d675042ec67a6f1be04dc4716bf184b398c903621717c280132166226e5f549901c16d963e80b4d295543bcb52fbd3e57f548ddfa59c460ddc5a1efce7908f3af2647087f57258507ea2661a66c937bb28509516795888da0695c34e116d433e305ec12cf9d6912e881c2f8a76b1e2e4ecf4742f3118656312552ce3da13a8f37b4e846503f51520ce9d76b10f2419ee8d88b5e4715bad2ddaf1ad1ae58436353cf49b1a719577186b4bd0c48403564039398b9bd6054b8bf13732349794951afcc2adc2265cc215a8e7c17a2516c9a325940469611fc5ea0aed01c03d8d035ddf7fde924dd6b32b8866256f35fca8886f5a4153c445366f61c0bb452a2ff470b0c4f1ed6dd9bd229998be2910743241261156fbb9feda06160c6201a02782ca826232e4f799922bec0f2794a16588fa930952dc4b3cde1ac6a174df06ff9eaf4e46c7caa56040a429ce1a79f15828970cf01a5c806fd636ead0e9df1953890bde4c8fa4639c05db3e0fc9bc0078c67e52683aba9d5528ec84864fbf4e42879d1ac22c28f0977d2c5cc565455db7c7a7fb5160ce50a67a58ad1e6ef4eae88de23df15a9043b9b5297179c238abd060b40798bca8731db0557b35b51c8304a9d7fb63017622a05e2b0ef967f29d1dda46d5b740d2b9f72b4b4f3ec7829eef860d9217b54045dce60b23d4bc8921e5f33caf44bbbe4c05b55fd24d3c00a7f2fff1bfc02e6c2ccd077a2cd8fffbdf1d54245da179e3a1269fee5b49c77123fea85bba483f55a507b8d50f512c4566c2787a59514b02af6c508fcb0082fed5dd2a26b356ba7ef692c9dd18b6e59500b7524c2cb0722b25d082593da662e301b0d6c39769bfaea7f3ab1244e95c9fce51f95c75b11e383cc210e55194832dc2c4b5bc9a977ff0e205beccea0a7bb4ebd82d1bc3a9fd819da5cd48f959ce2c7298ca44bfa02023e4de912c2ba61389de414c837c8ce7bd587017ae64da958b875084bb77c306b8a0c8520dfddce7e072cc0eed5e62364336c02a841efe26f0bfbc79ca321c8eb8ac8935678c599cc85c898673ca03fa93d052917a94364561bd32d3cefd43de8c5656b538d2e151e9bf018f170ebf7f2a8b5a31a79bf049a3fbc9b00e45dce6d81b8d9b4f45e4053b6c741a8a3e1bb364ec15b7718d488fc3c59449992aaf97a1e24d108166cc200a653607ba74325e1b8f0ec9cb25a87c15b4188aa8fd4673e0d68c56067ed2ea874065176af3ed165484b2fc8b0d2f78c80d7aba42ef9d66e3619d3da9d10bb6562604d5adc509b5dad6be2c0205cc915c8f099118c4d0b0bdec8dfda7d266da81ae89f8a6eb30c3e515b8bd846d985c463fad024185eef147a81aaa23b4b761955b027711d49655df8854ec2ccb62206a45f8763634ff0374b5e02737791f02bb47edfb037296d897de719e91d50b92b27ec7d44debbb2776cef3d762408c1466ccdd991d906cb0586f0947fab9987aba1ed5b7beb899f20401f53a79c084d4abeacd3777a60c137220248aeec16e8db96666627e3c4f1b8a5edaaac1535925a8b17ab9595336c800c368f078dd7c497526858b2f330c953a18d1f199550d5b13b709f66255c42c90748c4d884dd8934a82d7c832674990e2c530523a1d9b70f7dad0da3190be9e8486735baab7af0c6a39cbf1f98f67fecfd9fcd81dc4d9d396b7d5862fb0effae3052bb49f27c3c06e46b2bb92977d4be43a32d513c89ef0644447d1697a3ead73d57eaba307b29d884289744de4937cb65864650997a207f7ac5d11c3553e3ca3005e683cb74e79be7b787c31d6bc2bc6fe1025d57cb72623819ae8eca69232971d645c381841b72de279ee4e7bb7f543841c264b85501bc492424bf1ab2184b7d2f4fe1d48450bac1e91512e1e6e117069f66298d3debb42b8999a261bc135446fa74d27219a5fbe8f45696577c87f6f7096c059546712b1fe7156b03d4428cb242d2b56290caccd8927aa18ab3f7db81bd0a6efc765266b76b4090cb6420f68aab7c5db9a54d8c326602dc6a0c27aa7689e159a148f494829b82bd2ae450757536e95c89b6b4da68e897fa20d4e737aa559493b19ad5675a451d27c785f034d5f3151cba0305840c72ea9cf0c6c3369a9abc998f035696f40605549c942c8c26df2591d8eeaf429fffe619f4f9afb78a10e57cf8e12b4298b459565b6f2ab3f7d5c13cb07ca53ebecf431881471fd49b0a6e0371c7266f4bd1529b546855c5406713d2373ae3a294c82ec1034012c956c95889f36afe71b77ff65bb7c0b05071e5f398d55c13537015f0b2f2f4d3c72bdb337addd708a41eaed5b626d09b49ce479e5be7676bd72ecbaf154a11d448ce1571091657c91cf73dd66c58160b61510851c17d90a9ccd9ffc435888c1f364dba51b11f65404ec8bbcdc945cf7b3d3ca1e758a130681879002bd0332d1149fd31bc9d1f2611754cc59d788b2b4bb40215abd0ca033e579292ea907f6b0f30dcc8540fd0ac55475698fe9fc28286208ab0d0fa1bbf09493889ee0ab19d4f7902815334182359be35cce0ba28918a8dba75202a470349f3cf4a8d00b9b765ec78bbca9679179bc57008ad28b77119b8ae8f0889d582318fa6ac6df0924af10399ca8f6c8047a88b651e3892d22d76e0166603796fd69522a3cb88c59ce36312830d16a88e35a43aae866d58d4c78b4c6f116de4fde286a8d9f2d8eef7d70cf9b28633e3760f046d331d15cb4aaaa766d4ee566fd6e0b1c15b29a870f6c335b3de247e267cd5020fb3c365dab1309af01107d8d4d69ef6824ef12d4b3bc5aac83bef9c636a27113e5bd09531089f5e514c09cbe9d80f8544dcf7bb2fa0f4f65548c2a827812dd36c1f49f2a85ba0337b1e278c26358b274335a3f9e632a2f75accb2bff78f45d8f3c142d34746abde7fb592668e568db0224aa35522c4fe6291670f0e0c7ec1b4e829bda17edc6cca97df589ff45b0aea3e9a6f70bd088d6c0959741423f87f3ec210c7fb93f79e393337d8e59f68ac40b652ef684322aeaea11affcc733676310be2860d8aa0183562eb00b198ec628ecca18edc841e533fa1a31b7a98dae68d094a3396b319997e289ef389d09c251f23296332eb3750fbe3c0bc9ca3b30c10aac1af8a89140feb4560004e758844d71fc26693e5020a5d35da4648213283be0862223c3bacca945e27a0dbb90939ce7d91d5e2ce1e6d2097a28c9a3237d32580e3183187961661ff6771d74aecd538be3c0891d26f0bbd9693dabdb1ce18135f2d7db42833d7a390166c48968397abf9c058ce251b279ee9ffc4c7709ccb077c0d21d4c915ad87c9143300c3c36b277eac6c2929d903beb9d1ca6251aeee830fed76d63844d7b73805b8846ddc7be2d377dd8883064528f0d05219905a70b370113a01227cc8fd4463360be2c62f5093bd1f7881d51fa7b71c69fb1bb1f6ebf00504dd41594d168ee702d81b9c6441d31f97d587ed7abc3b70c382eda4e9d3f64e86010196b8613090d3ea64e7036fb9ab876d5390daada4c74c0dc4fe89e2ec0735d3cedc3754d7b922a6d40410e51a47022c6477f036564555ba430978216ea1681fcc3ea06efa7d32ce98ab73f4823771e2c9f022cc84143aa1bc3913f9b1867c4fd3a27c6eb1d9290cfd457907655d44addcd3ad2726dd351e98a0c2bc831745e3ddff79b9d228ad638ce92273290bdaf47eb54b2d457c6df2226981c5b41cddb291e14d48058de736720fa7151ea79a6bbdb90f3779159bbd577b011680c7a1fe3db4fb5bbcb2ca2b7008ea0d1c22970fd6bae591564070006488eb5cd0bdd12f3a477125293a1fc7515329b1c1be54f53999e874f522b4633c6276e5d27e02bcad0b75c2f4bca4529a44b8ad2231b608b280bb7d9d1771d1baffedc9dcd906edaa43dbf43bac2652cc1c78586e520da1574b3161e043e755680380a511748d8d6c7078d2cc0bb699d6b2ed7e2e4d6a2508536462894188f06f570c60f182a92882b643350c22b85eae96ec9cf1300cf7acb00e1aa2e29a3872975be0ad3f104a126e5d37e640e53bfe7aaae15e74393cbd9984c99b293e9ea4636423e811dcbc585e6a6be97db4f9e187887568ebe04ba8e47375044fe5fac39b7446dbb1b0b196530896fc00c0b012fdbe40d13e5f2172b2dc3af6cfbdd62acd0b13174e13cc126ca5b44c341cc43d9ffda0d0cafd4b8a54ca125724f653e4864d51a797b63037f48c261745311bf8d27c410b60228c13afb6c184965469f25ce033550bbb03ce70d5cf28a2f219f7a30ad2cd72ac3ee52dc9b56a0fb3e5d2bcd8120c1260649621968891b1f1de6a626e14d7bb2f8389faa8a9e97838cc2a67c23bdeb028f6862f1fde349915ac1e69d419e5740f5971f559a4be3a2da91338831fa8dda71568e160f06021dd75dcc772b6802c70aaa5588087ff01d5795baedace066395bf32e13dc7477559200d799c4c717f28a21b82945a1a4c4a077e89a149b94d891d2a377a66d6eeb3aa92dc1ecb576ed1241a96814a46da8ccafbcb081b5736d4e90a666c3368ba6792bef17b6e02e5840dafbbaef7df9df9d84fd950d4f0ab930e0d735d93dbc923f4f19341e447b2ce22fb27ceaeccc67dd6faba4550c78b61925cd7d2fd789e7e41fe6bdc7e451032a442f547a4e64ff4dcea090dfbe5eb2ed04f5427df0d8808ae5bb2e9fa79626f4e2c2a6ec2485e54f251424747308560e11a24343e02eff07ec4961221f799614b8713908596d8a400bf91e5d741db91bf1890c3856a7bba7876e1f6d3501850eaf899c0eb76b50fa51b65876989b8634215a663cc54439d5d27a4999d4fe8270a00a2b30046aec809dddd8368885324c129f3a3ecb8cec18db0f046de988643a34a533b52b5dd140b9df3897c8c0aea401f30ff0892df608b26c5e7eb3b17913026dbfe757a3e7fd88bef645700ce3947c6868e369e8e60eeaf4e746c6e3f409cd6fbb0beb404188aaa6f4c5eae5e8ff89312f6a7d8063c3e008fc34cd74f97e52431d42857dc5f7bf86e214f78389e2464658786b5889d33c91ab278d2add0122ec450ce51ec529e307fb46aa7f96e98f925119ef3bc7d836346338d18bf4859e9d67f907748675be65321a46f3312877a34ffeb3ae7500429de8bc423ea758a55279402155d106a446566f0d684d50b77cc97b4034ecfd11a059e4e91e5cd40a7a78276330ead47a3a32c7886b4e3ab94d2978ca64adde5453ebd46df2f766582a6ae39377da521439479d4e70f03bb70b101a21f8eaa988843762525236d4212d1d31785f3b7f16911f897a0b0d6c4acb63fe03feffdfbe821c0d908bdb83813558b9db6253abec82205adcfe71e401e0897f30f3fd192e534f26736359ab24a959baaee44c446eca96a1729e4b900624533c710c1a95314fb106f15729dd62b74b7345dc242ac46ad0114bff663fc011cc2c16dd093413758ad1246c435c796d434123d5798baff894a6c60626b60750c505840776e32000f44d18748ec3b38dc2a4ef87e1ee4f130e2768b38d45eee75eee9d7faa68889bf22295914c9b43eb80ca335ef4a09e841cb00b2ac34573b342d4722eaf837091d6b4220e1263290f006c2500534ca478a29504aecda8bc7e1090fd63d81a9815af311f338f49bffae5f206385e2bd2ab9d6ccea77fb1b1263ecb428dda194dd756b5fb13ce1ae19532d41669cca28711eb44c86718bfae91a382a1e8ca4e1e502e8686533c04aa4734cc189df5c12594c96eee18d21706858c350a3129a873f7c936755e8ab373a35d90b2ef271673359fba688050318a9644a66737e2b66603097e4005e783656d71eab1b5c79c7dd21453cecaf9e417534333e3c4953dec02c44da472495a0086e29a017e0c5fbdfaee1948d5e4ead29c78c52eaf14fafdf09ec09c7a53a6a8773cae0be90d2b75c3be34dc3c36b6df59dc148c0163f3480746fa027a32c953d04996d1c8beaa2fed6c835c9a56675d1f2a24e731d8cdfc809f20744cc0c56fb7e0139769bd057ae106d0487954bbe51579cc42b303df1f07e42ca58a41714cac5d669e43457c7c387d3fc83975088198b395fd3b4965c42c7b0d20e2d5b231d03ac30961d6b9fa1d12e73b7078799f8412ca3021b4045e3a6b34c976b281e327155f67e5d76489d4243eba0150d3fc9af300926debb7d394b6b121adcbc2a2351465ad06b497059430d46f970d0475cf3c8d605c16094316cdb2c6f7f6a6141f4d5ae01ea3f476502bb9fa2bc04fef37625d89614c480a3732cb6643b984549bf623d33b5ba9fd50a77e8f86edbbc83316810b0ce86f4cd2170aeb9d611ec3d8c718a83c7a20b79dde15dadb7530ded64d4b5dcf38fce242582329f9d6b2d70e7f78add99abfe700b3c0741d6ccd0cb5a8a5e913724fc3a89ba16547d2b3ee0c48e36c1a5dda14e740b8955e03debb344bfccb25c1888524de63c6804b546c419fecb95ea41ae7324275ace92a99695afd356abf5c32d432ae104654a61ceae1cb409c5ec0c6e13a513ea6e67de8101046365b749c25d29e4fb1e193c224dc03ec48d9aad7d9687478395062766f1964e7f75243c98db05269174f145149f816113382d8bf337d028b2ed03b98449e48f1c28f3dd3669d9c17a8a27fcd18d28abdbd3a5057f054a8746ee9fa172a9467a1e7941aefa9f38790b2878f2b85c4ac240b06d9019761ce37d8782db30fc6a6ed3094223a3b96efd290ccd85702a4ecb8dfe069aeee384281f705c1a1710fe9060439b05df3c3f7673f38b24fbb9cccb87ad2e5dc84a75dc77f2bb03a4bb700ffa82a017d09b48e6e1373015469c09357e0894aa22d3a0eb5ecfb078acb222d004e8e1b3f46652b419bedf149815b8cd143402f70220a76046c1c3cdfc8b28ed911a6ce754c718c20fed989007d07389648f2e4f85aad282f0ec26cfd5afdd8478320cdea21884a44e618d514eded2d18e5f51b7c7cbbbeac558751ea844d937d7f1c7664dd10408aa2b23bf87dc57f8f4cb64f04bb2108e6899ef2f7b2e449f3e429669dbd69c5ff705ec8d616781a512a602469f1880c6ac596237d602ce35fdc4d9021269a97fb8074c890fd117dbc587d5ac360906cc07f799d3f17abdd6496cc8a9ebaf5b8c2231097ceef6409e63f2a25cbe306f79b00ea9bab38bfaa9bae97b2a14f6a50fb2156c9331c6dfd2950524d1c0108dcf44aba1002ea6a1ea530eab216c731131b482f52ea75415fe8eabf4f11ada7036dd8081523a17b6010b5ea8ef0795bddeac1e7f42d710371f00d881eecc0d7e8e0900f02927764ca33070ebd12a841d6d3495b380a2fbc346423cc4b11a2fa1021bf567c3a8e3e9ac87f02cc16098bea6ede1074c527dadc29a80ed57ce3eb684659039462ceef603a9ec1dfcbc26832f5e3a27c3b7b8e02b297e8881d9a528a02d01fed9b3c1f8792a5f0570c8e261a5a29713bda9bc0fa4c9b5af332d0bc0988a883f9f1dd4b1e0238b7aa34aaee15f23a90849e7be6af8919888128abd00afa80e839852b88bfa0298f878e0a62a39af6140ea1cda4d37c8baabaf07498239a04deeeb59b8b7f8e43fac96c7e3e11ac7d6fb613d26643189e8c068cba9ac075ffbfd3ffefa4c8f26eb34bc914384b07aba06eb957a21a02402ec0b4ca122d3d00de6c16bd64b04d98ada1ca2c71bf3fda34c0cb603558337619a531f4e786224777da08fe0e54e083ea0f6a48c019fcce2edc4732b16aa203c2dc77eb7ff6b7047b524dd9bdb88b01fab841b4c3cad0ce22e7c8870d31bce93967f09583e635de14fbb8a10fe95aa6101dbc5c4c3b1a7a2722cee3b0e94bdf39ee8dd9608e6e22e92c6e2262907f72f0a5a2b7af8908ea9aa924e41d13cbba7cf1ed1841aec16051a2faed66cf96713f9b05e502dcc5722485ac11dbc3889a08112c5f6b8e72dd57905ecf8891d98ff4fa615b4fca0fe93f56a21e7831d0a3eb363d5ea20b2120942b434bf4c3586b3924d375442c59411d8f91790a16ba8f2bf8322b8631628b3cb201b08dc02eb2f54fc6721cb2beb47ff5f62d01ad019177dcf94bde373d58991cad74b0b37db45e97f03765eb7f06e8641305519801e46dd422aff8c65dd78ce8dc2ae80552e658876613ae24e1e082943fc6ec1f53ebf60bf8acde3e5f9ccba39f2e443c190286bb4b526e5fc38c69be2abd470f15e3505e9f9446dab80712ef019abbfdc16a3d5b818225313471c0b45314fd9706126bc85c3bae0b9f7aecfc80c7ab898fb4456797e9a748e94dd08ceff58f18441e8bd41df47a7022239ffacad6a79325f9421d08f4c81c621fdee3bd9185c78f1768aae42f9d6e74c5d4b33fe454a754ccbd5feae7efb687004e569d79af6cc538eda04341dcdc4c140e22ac17b5270cd37b712b6195f3c0c6c299984e78aaf3be5d8dbd785e18b0b58de4ec46038d545227615983a5ba217ab7a0d400b1624d9fa254b7d8e092f06646c9ea557de72b8dcecda8267603759dc58a7ee097566048cfa4580f790b0e9c2a8de1fc05b48ffaa20600a10388a77d44b4829569202fbe10e6e54dc0d4c39642b6b0f3253ef7dc764c896d897a0ac5ce077d7f2aecb22416ec44e3fcae0cf99f77ecf9e3aa85eb7a50a1bc5a279c40a45cd0732a99fa967fc870cde5cd9865a89362bd5af786349e737b70fe5c54f52bfdf90f829a78072007880b2df682906e611ddbab939104299c0bb78c182642f8909a93e58d3d56002a9242259e0a06a674af7854203f2ff8c55b8f3c911a140630ba6832e7ced3799fa6e2e4f7cb6b2efc26327e028aeb52865b8328bf2745145bd868b7b5fe7bb1c03bda037be8b13faaa9c9da5db6fcf055e7f0fd59ddf66006a1e2b33a815bfc0d1ee7df62545f359ae0a07e001ac56b59a019674b2e0edaf2567a35abb0b40c612f65c21af620c1a8783a09cda88c01c908f688c893cc0e90f70bafdb3a80c7dbfcc574e0a0eefa05637be9d9cfc8856527a829b0207d17ad486c881e0c8074e8e807734523d403e0c4e7dc0a0bb3eb84aaf01df34d2c00069a8d3646224a7f4bce96804ca74d02069812c538bc4772b01b63d1895fb7e7a0771ca22e6efa73d2516251da333310f095608b9b9c9a0f8d8b808268e3d710218289a1293df318ba543521561fb57ccd98eef73e7565c362319d07b57a5c67df699719a4ab70e51235c18d59dcc014df08b1d75653369dc16b7102f4cb534fa828efaef19eec0df9f10389cbb233c06631ff5eb4e25547b21bc5d25e09aefc978e98a5af91dd5a748431d774b0a1d38423d271da3a9e1731f858cfbb6286c152241a667b723024f135d2a9436a035c5633b420f38175f6ecffe8ad869a56c14c78f89712fd35c5357f71bfbdac3104642b5a62f134e7fc8e9f047dd925b4d0e9a709172ca6cd3c344dccf0b5d17f7f882e2b5c81c570bf855cda92d1d97bfe2f103ee264332660fa57807a58f9ab6530c7b6b984bbc3a7daacce621642513e85f37dbcd421e6adf5ae764b9b64c2fdc47187192c68f16f615ca7edf987d117739dc7920de9d2b7f917034b37444f488161133bcb609a6b586cb32d41817cb502f42c96ef625ef6ba7045cb4c8d1c10f8cee86805e63056848534e04b01889d5e7614c1c1d87f9194044906db2bbbcc96d88cbcac930bb02a56de121a107b51eb67c86d66db7b59879ed79faf887449a34573f4bd38525acd4a355852e0e6328aeff41343a7bd285a9515cccf7d27636e3a0f0e755eee1bf5d4c8a716e9212a7d36bd7250d6255d7868f75ceb2510d8a36a14d2abf7abc0bcf2e33585cc2bff3784b890f78fea584dbd84d886ceb93d8a1cf6829147f22daa19d85d5a006e01753f484a99461619a567f1729f286b51e8d3d4205be768d22ca07375905853e5cb8c5a4b3532625f0bb4a1563df02ad233fe0f1e3e88a791ec4e0c07e1d621a9f052c963aa6dde02df6722649340088c26c83ebeb53c49473d0822443767526aa422afce8852fac6080dd90ed81b0290d3f1d8b8e141ac258c26dc469736855636f63e0f251fa4184678bb039ce0aaf5247a5aec47d93d17344b0d701a1168df0926e7551c847111ea00f37ec79d0ab674b5c01a2762198df803b0998561ff956a8114ddeac273b53c808c5774c632e26a1344608e71cd720d901db9334eb6e36e4c27773d9cd0a40de072cf3bd71afef9b1bff0d01737a8dab3ef9dc8cfc89956dd50e5eea663b7e266ff042b22ce2add235ea5628469ad7b50eb988cf020d80fddf977df93f1031f74994cdb4d88c3310197406d0fc1379e3b91421596465040bd500e275b5ef1f77b4bb105afc2c4684e0c6d6abf6227f48e8057c184bf7313933141581e95489902f6f0ea86c643d9ba018febc98694093300f851d8ff52817f69c805c1fe3535bd9ddbbfc400e3c217543950a5c3bc99838e114fd55ea9200b228bac4e9d20d87c15564f00d143d1e00a45954053da15242bfdef7ca2cd69ff60fea8896ff9a4616d6ae84d9408ab8733a87a5e3d642e6bc92e16ef57243a359e83c51d5adf6cf5f51636c9fa8ecac699b2ce78669db8ebe04f43f38bb53adfece5ef666251bd4795bd689716086815ef76c0d8d228343c097efdd4632555de08c69e98e2f91738776ef88d203adf3552b503fd4381385f9f7e7340bc8381da712fb952709199bf570b45069903c77dcb608526e8882724dd1a459affae4d999a1267be00a1f2042ddd899a028be5331860f9b39d001ff509e243d9e636346ad4189c4fd9351d06d4ba128c1c4e91df7f96fd71859cd07c8d378927d0d1040a31184a141722cf8e96d72cadbec660c178944a7106cc3a1b97c824c741f33d137503c1e55575d538db5032717969c7fdcf89d5faa692fe9016f1c7b7477185a06ec6ed03a660b36ec115825628b22f8621fe895c04e36d6f97fb523295d70a2eb1ec2a1c5f8ec2fe9dcad70094b63b890b05bcd173407f092dc8373f25c1420ccde3bc5084c70d5eaf2b2b1995745e4cfec75fa6b882fd09c31e5d36e2a57056efa4d475bc18f007891f83337fd5a9cf262daefb57e56d830562622265b29067fcc42e64867fc71501cfad996841e60f10244b41ee01622fbdbc5615050b9be2b08b4fd7e4f6c06227f720a8d02c410595ffe8cc4aed707f022ecf917284a8d3e871c50cef30328f69c5c526138b14298070215994634fef1cc2213713e90bcda24767b84172513f066652b9074f34a0499a6cd0365769c1a3ff5fa10b3380c970adead64306c51cbfc2d4c44c8c6f2776028b49f11718466c3861e40cfc49a1860067629f36d52fcf1cb222958c8c65269a947067662bf24082adf5d0f3fd9d34938be4e22e1ecb8453df2dfdd0f81c3c52ef28270c1b08feada6f9ec6ddc177b2f24b515021dd74df595bcc35a7aa154bf6e770161d2969a54bee6c3dca42d7cc444372da1542581e840c4c729259e51fb6e753fea441b6c4197cc6d4d57d3b491d68e8e4ad2a8f4d10f99b930a28695aa80c109982d1540289cca45f7267699ac0ccdf594598d370b185a117ac3afa9764d9525b550d12dc6f2143d41137b21f1ed0b31fc430d934ea2a938fdd60ee85c742645f24c6770e3448b59e7344b6a561afc7a76fc1a2efa8da16fd3601b9a6843fc83990156f6746e81836fda5fadef4c52eb54da10792a8e6048592d0b5f7cabe31963ef48b4f0c68b0c4b6a729de7030fc0596904f1b0e25419a225f407768e8253a989fd4306fd71001408f80beb6d3e7bc30755cf9ed10f0a515cb8dac5d4a0939ae50fd5e7fbf71e0fff878bc88e040a46f7c47439f9dc6e9e8430572da2d4efebdbcb59a7df4473e9c6015a84b742c519a8b5b9933a58135dab4d0feea5f0efa413d57737b3dba0de981dfdf23aa51e08db8aa24a7d68ad2caa1283134045f444ce97473271c76572c90aff2b4f10d006149818047cf2a900ef0ef34a6406e1bb9f5e438040a6c27e2ec197c2357c8cec32e231abb48b20407994403688940c4b8d6a0f8470ad695d24aa00c083992857a00d5889d73265894a0307bbc546ba01bf17feb60e2dcf4123a721da5d59f5a47e0d08d949d19d20c5ac7d694b6417916501c89fb0518b0c5ab0be8b3d8f60f15eaadb2a65511273255853cce06e7616db6dc48e79c06e63492d5243690d52ec79a66a0f1ac65d5ea2737b324c0a8a1c72a12768e406d54f8fb5419387a270c6627bab9f3f1cb00774e639333d696ebf6666699a574a283270d17d05d68c8e2eca900eb5e72a7d0e6dbb5a7b23d4c2e99ed7808131b5b04cfa281fc0d38cc5677e55fa3eac13ba2b325f887698d59029138dd3afcec9f950c6578e573973e04e6302a33c7a0a0d10544ea43d5f7eb5b5badbeaf63d4fc2d636e19aecc54ec6a12048226a878b66ff7e35c114c438c0423982df94ada9f80506e3aafa4f90eee5220030d15b746d0ab45b37ed63bda7c0e7241a84a46d79a6c5bbffac788e9119845b83364aabd5e2c1fbb8909f23ffa56001db509ffa3ca57da35c7ccb14d1ad21f89c1735a016407d60518c5b6bbce4e79dadd126ae0f883d80723f9e2e8ccd75990b80529c04ff568059b527b5c82cbb2c14851e7b252464cde9531eddd886ba096c8a904b516ea01f06f80e682234a1071722cffcff7dfafefaa73b2431b31e88271bb7cb93a596e48470ef32d4bfa7486d904fdd7babd89e1756b850ba6318c68f05ef45c6b92ceb47833f2f81950a19ff39c0f1042be5a442ba6fdb738580713b0058618b4685e081a32c8208eed57d50fd0bf271d721eb5a0bec1e753066be82714a0b93aecbb729d0df8ea368741ebec11781c067a6d48821822b370186b2e1e6c20e7b2c4b0e55e7d6e1211a3fd6fa81adfd3a7fd114cee79fd75c7aea2dd2e2aa87632840b2c75d13a4631a87d73c7fed14ebc9f4f604d22c1408ff7d27504fe68e4d0e8860daff1b9cfcecb29a425a63e004b454deceaf5f6e94b49fc775400f1ae021c6b582774c18d280c7cf6732e455798c1f719a3c42e6adf011716a38deb6ca293a57a1d4a51f9412851db92d054f22edb91dfd62e6b52be3a64f92521238d6393565a46cf0fac72f38a3cdc2b60a6ebb3eff89b1b5db544941b46cf64d68ff555c8653cb86ba6753b3e3e87bfcf62aa140be722bc452cec56fc8647d8b01edc7071ba5a04aeb598a2eb5067dc4c375cc81f553a11d586f9bed470db9916d6431708ef4f3f162549b0d8192f36159f20235cad552e822d6f27fb9ca14b1bab94dee7cf81be67aaf913eff0e512b7904afe179466adf109bd74bc0c105251b91557f050b13ed4185b69292a9131b03298da5dfeffdd8be5dda7f65f838d0b6fec298c8c445dfe6421afffc3ab88207974af4deac3c9805243cbe41a85cecba93f8ab6d2ee0a7cf30b091fc739fb7850d190a7289a0c297207f87b159a0561d55400fc6de42bc18db19b0673d45d1fde93d6ad557011883186c0c99f01439e51a213fea6958e784b5d7a89b74a64910c758a38425b9b9e6891c32665313b825909ce7c5cc3498b061edb562b8da00b0d94e3112051023c63848087e41cb9e9d5ef30e6dc1c772c730e92c36a00fb5a76f3184113b3aa680459b4e4ecb6575644e27144f46c93e9c2bb359428dd05fac819963db353defac9ba605f6506ebdadf953895a60f23cf55c2ada02c20c16f4887385383602b23aa16a6b75940d19b404bbd5a2058905cc34b70dadc14519a119bbcabd533f47de6f4756944966a96aac379460aa55231692cbbbba35606d037561a4769f19962d01dd2de5ff4b17dfbc4a04cb20ec7e3ebcb0d8326e0d77e9bfb3ec0b17dec52dc2de60b47c1ec360e0162ddfc82018b50962a7a7efb97cc038347646b2ef453c6af4a9d3b7c9e0df8a5d9018dafeafae65d8b6022d0400ea512bb80f3a3dff9dbddd909c792d289fffd196ffcc3fdc3ed4597e182b1cacc9eeb6de434545066cbdb5fcfdf0b28205170da8032a104199b5451e6a65ea15c6898e681531dd096741dc3546f6fcac4cce11c429574065544d085c2bbc02807993f386b6060ee0b56caafba312fed026f524ceadfc55490d8f41160fb4ed3d702359b320c0ca62944a833e344a8d24079ade725b853b3ac979023504cda981810cfcd6b230540da59783ee0cd4cdd773c16b1aa68f52bccf825fc6bf701c73b73522efe067ae4762dfbaf4b6823c6cd7d522a9b84b597283cfe5ba748c42c1cf9227d8a28d37be1843c54e91e2a7fc5cbce2f689a1b79a4d88898f8afd619ee6883752eee43233b12570db76eb9fb8791bee3ff20c7b5e77fde9c64bd8e8c3146850cf0bb81d74f72ac26303a866811da35388113158a891cc2ed6746a5581aa163ba9c736031e37b54bfb6ff00b424e50102554109567aa16b814cb4ee905800c820287c1512bb241da79cb4f5eb276579a83746181a071f6215b3bcdc90cd057e17fb06e43e19d92ed01df4101d43306b60b4aabaf073e4d10a7844c0d47ccaa06b30fd437488921521de8d354da6d2af9ff5873e4ab190cdc9445e4d629b5bd56d866a7d292256d51804be07f35c336a2a53910aeb12ee3ca68221e00d3909a87a0cf76a55d4140d9c5701eaeb7d05c2475610268207ad0d674f56db3eb62d8e89d800655150174b8a4cf6c747124dc15c9798e5ba0dd62a04e8e67b82f7c950dbf8af6aa9197382704a911aff2e458ab934fd7fda4a5620dc02185e972c93cb2b8a8a8317fdef0a9e7ee03f1babaca7760a941114f43c96ea71bc00f532a6dd63fb497aa8a4421c63eac8ca722f636a27cbbf94ac3a81f000ceb3b97864acd43c2f07fcd2b55c30507b2ef1481f6387c33b5902175de5b8baca2be6f900af631c26ae1c93ad9404691d337188555b4aaf9a70820e53ee9caf1b2f284f62908287bc1abdb7d55357006326a6177890a79642b0a270e94cd629d65e0a1eed0e8d340e901c3d720bdc3a28f01a1876e26db30e0d0323111c7f8b0bfdda65e88a6da16b9af2938582a1a16e9f8eb054a01a50ecf05b2dc5a7619aa6249d865974dfa1f2c69c5524029eb3a05ff382b2573c30077485397975a9e6bfa649a4a8072b7ec42349991b30328d330c6e111aac471c664210ca01ca57db6ceb3b01d9c3196140459b42f70df7bd24d1bac7a753c014e3a407df854e157e11b833c19e613ab7e7da017e16c1ac9bb1df67236ab56c013f48504c3b2dd19931384cc055fddbe83351d074af7da1119538b4332be2ba8406ac94c7cbb2c7e98cb68f08265d17f94244c0dd88c957bc58cecd1313bc1e0f1e3b2361381f1b58920d6618890860db7a321c8724c41d826facc5c56f9705b41d3efda5fbe0f7ca3bdb93099250e495136d2f8211b88202684749f86f3d26820c6c7b0c367a1ca3dbfb31f80986b1c3389b4872593d31a84e6a25b131091974764e01452fb5270637e41bfcc5aaba6632e164e68a2811ec5d17f6b94cd79128a9512b3f2f7dff1f18132dc540b36f1f2ce798daff58ef873e1209e6e2ff9821f26101241e8f47ba58c52875d6ca85dcbd1b72238b540bc0a9c4c41ff33868aa0822c70a8870b08cb5d80914ef160a3378da4c388d1a7335363806bbaf1b0e9cd689327dddfdb327b894b091457748d3dc30e605d63abb2ab27606473b94801791e3d9d0692782546ec582337c490fe09943d3e99e46371c1f788810f32b94acdda5936304a585b3d8ebe64092d1b8f6249989785cf13c6ea70bbd94eba8f281e38bd796c424dbda62fd2f9801690e16b6ccd9b3ff9ae9897b245294ccb71f25effbe4f0256d3f514e532794e792e0fcd5b017a4a02e68b86b0d22a169a1d42b7e20da054ba4f8c4d65fb330f729231de9a258a44895c2f926e4b9b4d16befbb2ff1ae9147cafebbe32523788f504bdc1f95b9f0a5e87423867d9e2e3ee6a44211021d46db7cececa656ddf6338ea0c77719217f192881d7cec3f3a26eef04cf2b1937900bb38f79f45bc95777bbc11636232d8e198a9330be3ec4b4677afd2342b98a22d6285279b49b2f6372f259f84fc38536f3900a4d63351744894b4ae9825da6ef650e1dbde149230482f64abc1250aa1c51c4c304db7323de36c3e6a78de0a5fa496246ecefb657edd048221be03d15baec12e72e34a1727947a66acd961c35368361717ecf9177ea0f15bf4eeb7c60aa1a5baf6e1b4a2445842cc3f8b2078b62df2424e59ac2773075a749661cf085119f8a0d997c8ba1efd3b84aa090b4aeddc42c730500d295c1462e993c7c63b338402843a307e16b2409a6b4bab98505dcd4e53ce1b339ae071f938aacf44853dd9b66c17d5a85e81baead308543ee1e8a1b64badc316b1a0b250d36b5a8c992c45379fda70f3dac5382b687f470b91640b2aebc55cd681f9f24df4b9da3303a61fdb1fbfb1efb93f38193c6d08b48d0946a2a7190202d08b7f65eb7fdd1567da5541540bec7314a250e10a1b2d4b476cccb05764acd82858c857392f532b8eb1de95a82c9df013709342ece1a1371c210791ac5b45b70e0c3f0cd0ba6048e413dc458b593450e32c63edce10ac9ef21ad1b4dc825c1510c4aa3278bea3e8bf7b9893dc9fcdeb4a510b65679f608db85940bad7071b7f83bfcb61d08b211e05b255e8b022ee90812189a69873934cf8e94f469cfc7a7488d51132ab8ae55d90bff0d5f9370ea6dd847c4f2d4d54c8fb6825004dbc32d869a056e9cf3cf3d1e0967579520e3eac734eb2621576dd5ab1ceb9fbaedcb225468fd3df2b473abc7578dcc33786773c1da1ebfe2d2108018ae2f93d957f72016bd2fa30eb64c9b3b9df3046edb284a9e86523040beca619afbfa1fe873c786c0f4d1afbc71928f58fbd1bd3ee2f1ee929a5181c64fc24a351d58b5567b4cfbf0228ec373f0a15834f66191bb7ec622ba406f58ae6ce5637e79d7bc83c632350845dcb8fa14241ea1988f0c41ac20ed17d3ab20e5b721737417532e98891c164717f0ffa66b1f8473f8bb8a6d5d2933cf26b46420f794acdd8e904e22fa4cdb530d8c43be850c85ec143b21c3a6faa21bd41078a8e509e9fa09fc48d5747f37652790bc6f29b60adc9f0faebe7ccc21a69670c58023355c4da98852a2f9ed027db7ca2012bc6021ca6b6fea003423405a3c3330803e7f0debfdd0e7a568ea4e9ae51e930dda296f42ff213df04fd1a5420e567125d4f27dbe5adfc67f4e8544f78a1fc3c78507e5292bb970d1be158484d394607000656bcb5f27a830ff7cc4fdce386ab7ad67147cbc66fd57d56a909c3e850a4adbe8192bd1567310673579364780f5d7da7a17dd2ad247b35580961ee44d288d14f72c84167204f455490aa47a39f955b56be55068365f87bf1307b3fab238801fb59ca41283ad2c16f85ced17dec48590f925ee84396ce2ad70ac400381ca959ff1f4129840a932daab92112788bff75cbcf97abe50844bc4166fbe97b7922617b5dd81a91b9c0a8f46823cb168a75b5eb9aaac37e6260fc40fa3afaefaa5bce19e43d1575e4a0f9d332a29f123aab1a590182d7dc1c5624de05d4508acee1bf9ee36d6a33f3385f347f4a885be7b31e0d4a6bc8249a1641eb43f1c1e6994a2ea3b16eebdec04acde26a27d6aa9d7d0339968e7c8721729d85537e38118519fae8a41c965b23c0b7f5c65a38ef79dbef49cd8f975dc7f87759560ecbcc4026540d90a142e953e571f25927fffde1891b22e3c07c1861cf1f37759230586b499a8f4fe2fa31f5645eedf1841ba6527a492c42d6484b25b7e0c2dc4bea2a70e13459c34274e33def0535ff417a851539ee782ac5db3621073d814cb7acaadf1834c73bb36801f802b4b96acbfa4c5004fe59d2bd32a24576cda0f33b41fdce3ab5eeac4c47c8419b501e22c94532c1899f50743a4adb682ceced311479af705b43f718e08946112c486232f6de6ec16569d1da3ed57174bf973035b52fd4d780b3262a732c1001c35faedf21a1d691354bc3662ee43d9453e5d393070d32b7c62b9f14e0ffb845a6d0e1eb2618d2e1b91d20c36d601620d4c64fff067b9c54891e30824e5f77c1944e8eee66d624d69e5465d667c326a9a8ba9a2a3919ca3bcf9afa0d70300337a9a109c3b77e52e07420b161cb735f8a55dc7c695ac5cb8a2bcea0365560c74f8160b10e879693db13a131f9cb6094a16b4076ba397c4bdcbc011189a6dd73dc7e9483a42ddea5ac11a7b3c0aa9655150eba55a3ba56aba086b51585b9037283c6b65955417cc8a6b514fbce1da452ed2aa0a83fc019c85ce05de6900191589ed772623ad73283a92fbb9b07299c89dca21d452b6537a695a55b286fdfa2e37eb4dda913c7cdc96d8042659533c9707a72ddf0bdd652722739402817887bb96cd8ea77fedf9da12e51aeb58e837b41002d4b7f563ae1f07f355dca70179e36cc41e55f0fde64a823708ae088a69694d4cb5db5f756a26f21b99cd56fa04ed050dde746f06162869244a8605d766074d590e3b5d350f06b68d731be29532bd24979080d78aac31c207fe53614a9e74cb36e5f8b2e5a41bbfbe0783004c77a0a649e1ccdab450f1544688da6ddb016d10a819c2793158997924ecef636c34c36427c29f0648423a59aa0ba9860594c1629f69a5039731c898fda902e17f5ce62e541b56a84c6917cacf72cc67a137ff34927c58ff84b6c8584c68141b6d3fd3a7ab403ecbdd08dc1ca63d9ddb8c2de8e7a9fb6f625140dd123707110a326227ccbc7842bfd5aa9ed027fc155a2ef8da030a6386b3312270f548eefc6c88eb20f5c46663795dd9631dbfe45575d5fa9035af6546b47d679b02036cc01881feaaf032c5b23241b675b41801d8b37be5a8961849b9f56c79e0bda89d700f529926fa3eab15f7351ab8d67a5fae2f6a71630667ced0ad0f9d5a754ef5ec8045c8dc438aefe8c0795557b2db4a93ae0b410281acd793a37b0d66697e15c1ad2f244d537a554bf36d53e160aa8ee9a77eb2053a3ea6ef5d435bcaa77ea8c29e9a373862d17038b3f41b7e342cee7b9e180ce21ee0dbd5838e7e989153353138d77d4903631410ffb91777db7f5b9bebd5d66aec6594aae2ef16fbadf63cd0ed9af01dc57b02ed7f489ab03d5e2eba8caf5d04d511840dce48355be0da1c8c5f65caeb8149a6acb1b59b50a4d8903868729d148e8d4274d7e91cb16b59e82ab10c8c3d714f4f54926c3ac55eb97b72d4ba78b72815187fcebef017dbeeed57b062df85b7df8f28348760806fea24f8c1600b6e5c9ad7e17e32cff29d42cfcaec2457f856ab7f30cd1ae01d321914ab0733a8921566407954b9fba629c0448a6ccf3187fa62750b70c07d89db7702be336f1001b33360acc7a05f2cc374a4f70ad15ff34c52ded921bb5599e5b86ebbb1e41b3117c465946caabcd25666fd1d7edf75c0706e2ab513775f8c8a238c49eb3b0e9c6ae3aba42f60094b7c7cc8ec07834d272dd997f7f44183bab7f6f5178e20479b7216729750a18ebf5677e9a1319e0b0a1c22d9fe55adc259ffaaba8f34f3b131e006b8ffbf47e82d244a6804293a9139147953c8171e7b0be689c35ff633e54ac95e6719ea7ea5cfeaad03f31c63a8dfbe06578c1abc8569ce1f9a00d1ef61d165e0d3e3b347a0ce03d44f4335074d86ad6e6a40f692d9415a01dc76a88ebc9030d41118f33be2ac3146de9345858c0d06ae288f2a7b7ac75eef79d35c84d1a3fd42b5cb7faf16a2a9eab9dcb33059ab867ac513bca348e091af38ee6ed54de90dcac28c86168038b5f599e713240bda2c40402984ace1410fd9c8d4e8fc31570865c574290a98f5768761ed68258807aae184709bfa986db86fa690129e9305a74e884df6c5cd5b45bfdbcca3aa3dea13b9b8e982e1805d21044a969a370889cced618bb32ca38ee18efeab32246355104e21a51ade50290b3206c8cb419c844ea497bff09863dc0adb8f5c3a025dec5e51ea3eec5f3ab824a5955cf590db9a875f9dbb52e735b634d8cfe5f28615474c354f346a0bbc22ab5dae87da94742ea3e7bd28a3aa8f7b0cb9cba91401092aa77b608d3518b2b04a7f1e93e065be6ae931a0e7a6eceb93ea78e57788bfb59d3b2b45ddb286a513fd0a48103ce416d08dd331f771526473435079441ca0a060e40f393b4b3fe77e16b8d6bc1c94b0800756e852bc0ddffa73e8c897dfd3c332ba21c507aed811da3d0be39ff6597a0fe50135a74eddcb7c4f68c863cb1837e4a208af34d561e0d84a7a45fe854b961d0fb1492db9862ac80f5ee5eccac19583283524049dc578b0b8284daec6181e1d4b308b1500584e5ec0504563a1de8fc00ef25a685101547a2aff6ab62886ab5811f4fb00e2005dffd74a21dfbb8debd16188c701514c472d12ca0a93d5e1f575d02cbb6520077f997465f797a2527d4c6dd28f1d1e98419c45d76b78f2af5df5ed4ba5de31127e4f1056f075a72f716d77e2a8d3201b1dacb59d22a61ece1ffd3e3d8e1b87e08fc7890b850fadf1334853acd03b1feb2f824fbc771c050494fee381c7542730b597b5eca41af19d4f9b43c22cee22cb27ed6ae5e0606f772ff849918b7de30b08a57bf21a1b89dcaf66c999507d032610e45d5094d913e842a98144744ccfaca195bcf61b96f9a5b751ca651d0a4af77e835c3e09e0efaf6665efda482573842bfe235b0ea00437d914d93277f0d76c0c97a5fed00b014560b27cbaf94e8e2b343d8869d771c9baaa7963a4f769ec11ae617228b5fedf936d75b7fb9cfda1fd0228a066cddcfde670fef4749f7f3b5ca0133893db5839bb2f69c9cc42d0d9854259c05e179f466ca8f15d9ac52a0401c5d4dbfd1606268457b7af377bdef8524079ed339e267ae1a65478999821828a6fa57108ca3a780a382a55b0558c3136e3bd3fe451731eed7e855d713aab78e9ebec43e6310ea79c7a10ccd187c86d35e9deb96c5adb4826783d21840e3c36048b3f2f96ccef819d125ab0ea24d9807d0535f1c855753cfa7def4a2863a8be3d3d40cac6055abf27b738bdfdba734f729ddb8f894429c05ee3efe25bd1d030a8d5a8e78e0edabb5d667b9d2c5331727cf167c6d5058747388a59844f0157ca85c4730251dfe464324010691bf767e287b21337a01133f1230cfbbac12d43bb40967f3775306b13e6e4fd7097b8694287d46f1a8671fa20cf33d51665f89de15cd6b8d4362574c690ba57187839447c95f69f5120e51e4d95efb0760bfd2c4c8991e1a4a8c0b79d1d614ca444c928a56675ecdaa31aa90931451a4ea464984691d322041bd05ebc8635900f4447809e503a112068034374f2dd364e16a95b85ce610786446efa473d9a0e350be60208cce974a09bb991a6406227c92711c01c1106ceec16c7ef1b218d0285bfb34af34d7b8253083eecc5360a820daa4237e441f071fc464fefd4b27edb0f480ef192ae587fa99a805045574ad5a0dc5149808549b6bb7d73852040dce7cbf0ed5f0721bbdc5824f56bf3875bd756c258d104e1f36f94b1364aa26a2e49ce0a11c1fb9d5e8dcb886abe4f0f9d1f27c0716ed71b1342b3348a599e422f56858ed5a87093683a82fe03022a95e4aad209fcd48eb1059091fa0744853cd044e69ba6c29f460e9f4d8af0a10b7fafb4f5c9c70aaae6f688925618bbc27d09cad29bbd93c37dcf6a3c9ceb309efdd0dd21e25a83645fbbfb2b87a7e93407e31264f89f6af4ed3e4022f4640961cf9d098b56fcb129cf4971dc3b9b8fc70eccca2ef332252979afac760e20af6cf26c6d09b54b42290f17ff4a9eec01dab5aa5d463b5c55573b9c7290ee33b953cc781fe99c81154fbe121e5e66f1750d326827c263ea3a9681e5dc0256d2a52975d400fece0314c8335a32e59980537ba80cf416b433dd6b9df0314bebb17446d0646c629235c5c6393d1b0d157094a1cee84bb1aa393074dbe4f16852fbae8a09db910af7a3bd2adccfeaf013d98587c51c78e96653539b62d4c636398491758c1746ff273716d7e0d78e63aea748bf9a48237a589d9baffe2fb64244480a4014e341c969d8fe6077cff35c998149cea5bd1706c6cfc2de6531ad1aa84ecddc68ae1c37360b95ce355293b8295b9c804f72c761f3b57ef2471fc2e183e90d14afdc70c9ef4e98e0b46643596e995263606c3867f45daee83114e74e50c3149d69fc933c0ed990789aa0b71f54b1c5a01a8afca063e29f4152054595a21e101d395a491ee8c6d9bf1d91eae4913a09d90910ac0513b10b0fc6513e17f96584c7d9cfa6bc86ab1ed366df18e1b4abc30d0efe08f1d3680096bf9b376ff81c43d04dd4cc802601329b3b26b435d2ec04c12fe278c66d20979941b91ab1ac55ace047b55014c0ede4ee29d0d99086c2821556f4a91179d56cd5ec1feaf0054a9fc0ce0af4ec6c917f156a639d91629985b13542d569483751a3cc134e22d614e84dd2049aab3ec31297a79acfdd5b2e77fc3b287baccee5157fcdaa1a2cdd6614f9db583b6abd06e90d50885a23489e7a9857472fefc7a5c475352a3aa08ad5d2d18845d8f0cb2f8859f2d758f0f67af6116888b3c5ade1e2ee78ced3e5f0bfe25940940b99e7bf1e45fb87f843462f3fbb7dfd8eda26c8af81b4b4ac7160a2e7f887edaef3a81912b5cd859c81e11946c72f6ffd0168437131f03a5340e714066e67f66b2ab2f55ed676e84fb27ba9428905ced0a5f7a119ace3a840a9c9af0d903e399ca912505c12cc4f3e6cdaba7e11bbb3135b4b7e36677fd6859830084d8c4b0e74ccd02d03157c021dfd255ff3537e405e3f1d0fe836c2f1cb4deebb392cc02e6d4c05c2dd910d0ffd18e42f674647bf1440f5166266f5d52be6fd9539fc52d487b82459e73b5e0ca251216d76c69e0fb4c4019e9b4a501ccb53158a967955c81eeece059a5b0207fc28eda87de2470627f8af7185a818b9893a24c81f3920a25e196d668589492cc434bde85ba8926c5fcb23c57f3d301937d59731a0a3d2008c28a5324098b2bbd263c0f9a1074fdabe4a85121b72a74d0b1314385c757be1a86b50537998f3efb14999ab9c69afd4fad3badc61eed9499025a69283ac0bb55bdea481d09ad2569bde73c6f6927e76035ee3a7f80c49cde86b0cff1bdd4cd575391b271755e2eb54e6191c58bfec1961029f178aa74497bfdb42aa6e59bc16d58c95073ac95842b62b46fdcbc309d9ee4b424dcaa48bb17c5dc6240e5b6a2ef2c3dba724a79f4ef1490a8797fad94073897f428eb08cc76b86a6bfd465a694e3d7c33fd9efd540e9c72d2ca80743774e246d1c8d47e55be6853f5ae0029283a522f46f93fdac991513ff38b7471c802023738a479ebd9d38e638da04d557dfa8cd4573f8a3b2a13c19e6baf482e8d9bd0885a58cfbe4dc53c107ac456ecd7a087b3bea4276d52a1479441a00505c66377d6fe693682738494b3af989a84b6252287b2d78fccb585b410c90d849cfe568103712239c1704148bbda4b342fe07a46d7b0cec8046a04fa23ff468c009ca41c4565a93b432fe50b46ac56cfc0f4e1840c4894bd3357726ca7c36ac2625d48104b707e126dbac7bd7b49f8958d6af26797c3037fa6c6cc0346872f0c4ee63a8c76faf67cc06f3dc6800e99bd53c3bd80ab522e700c78b0b1e052220427042ab99e8d5920d0ba4a0789afab4ff41b19c0d004ede52fd750e36730b063c54713c06f4eefc3c7a3c396b6910303b55651867664b102a26208e9c012ec964a317dce1fb2c3685af643016533fbd608ac93ef43cd92bd09917b4b99524a018508f708df0842b10b283f09d80a7026ca1f6dd7c69db8c65251523dd29d47d943e3f628b548130a0df5cead0d2e413be2a33efa78247feaf4d5d928234d182baf073e507e2ab859430d7270a60d30747f770d48adeed3292b7b2c958783e3717b685c822653efb304b304b46ecfc9ee45001ea15f7a3cf855de4a51a5b75bca745945c0e3f13649f070910081b74942ebdcd3517785c242d5b059ceb033d592b5e373a64d15b43f643dff7cff1d9fa3faf8fd9ccaebaaeac358551feb78a3c171c1eb5ab8c9056b7596719c4179d75f1d44acf1679051bebfa68b4625dbcfa06d9a8cf125ef96338ceabe6bc7866dba76f917bb5ddd7c0119be7f9bbe84a9fd1d83c12a5f408698c43bcaca2085294354c608856d9763d1b58ed569669943c1e3510f87358ba2acedb185862e1e8623619eb03d98ba6a079d9373b04b3d974a3df34c116997b7b0b33b3fb118f34ef348275baf7cd8fc77cd196936b2f97d2e6a215ca8aed9a51b165073dd125ae01170707890e3f77fb6c7bcf1011097c054780447e22fdf3175d571aa70659bc756783539292635cfd6b8eb8a2fbd6e5df1d928321fc95a167fd398411d2ca9e5c0f11894443c90e190ede01c600237bcdf17ff8d07848448112335ad5a0384f11013edece710a09d1b1e37b5028e54dfd1ce06a3da72ac05b46b57b833f0c6e37df1db78abfdca95c7a0f6d5782ceacfab292f060d77e640abd6f6c531891e69da9176a41db5f66d47234790340fcfded2d89c9ae5ff3411ef91cfdf4d3be397489123acfa987635d4eab837f9cb27106b37d55022c94f2bf2973b41c39648d59be7a979f871b035a1fdcdbd65993bc0cbeadf1851485299b9b977c025008c9ab8b32c97eff29392bf5ddccccc1f9ddbdca4ca42757021703b46f624c68b538cc98a12121528474c1475868c19d4986804b7bbbbbbbbbbbb628290e0b3b31d37f1c8e9b0c8fa1387002f16e06aea6e29a39400309c6c3163e8b5acf164c46dddc8ed07caa072c3531151173750bac1e886a4309cfaece8b19391b9eba279970b2e0422caef33b2affb141b63d4589aa67dfbde55dfe2b66d31fa5744f66ee8d2dd37c61853bdec3451882863163251926127d34f9ca5b9dcd98948501c1276b056aecb65f4d9f136668ccdae038e893613edba4f868cc2704c945f3291f74800d8907af94154bf3d173fa005536c50f9db0f69514aed555f90f6b5e2fbf8cb83e4d78adf0882c8d7be2097bf3c09b87d12d027f555e9d00534e587bf9ab08419d22e873242640bf59fc925987224c3ca4e8c3136e9581500329a54f9a908c61893d0004510485f286d6962058c47c42f0c1369ac18c71655fe54c30555fe46b184991a0863c450e5cbb83748428818638cd10331c610c3a5c6d805e7504950e26a982c66d5c8a096a48005944c8c998c0d1d8ec814dd1023f38215349119a2c80260c82cc124ca0c2616706a22c3e5862f51646650a444068c1b88c898b1c102543c8911030e16f87284130401c058c2e40585872c4ba0b858da07644e4d929a8c692f64311b906c20c306a2346cf0c42436864912d4f2482d6a1e5f933146c9bc05b7756577a4fa737b715d712291cc51b8fd40184e2b706202bba1090c3064326a46d54c8ddf0bdb997aa46b0b488e7aa3c62f4c81f6c9ad9bf632ba103f5617e2e344fab1564434aca9fd610df46de07098a1494abb3f5a23bd758de1f60363c42c812d61d2637ca006514a9c94c8606d300e1cd0fd30d6b8ad4292daea1a6afc3589732fa979ae72724137c62825ff7e2dff50a0a9fd6d6533a4fc5ce88f31da3e8a7493730e628c51070be87ed27d77e516a594a1ac45bad8b030ae0eebf8816effec662835d3b959fb26d77df9752791dc5a382b92b342a3b78203da68a38d36826ccce58713638c5e39d2a7f281c7f766f6707804fed87275687751ca9e1da3267bf8a0b6ab1177706298b56be3152e80baa9fe3c9a67f7a34ea8bbbb7bb84cd9ddd7290046d058c3ae76cbfc3a64386e1fb79f31ca9f3f5b93114afafaf3c7285beef4246ec2f776c13f8747e09f3bf6c5dfa4b5bb7ffb87ee66f160f6ff68bbda8b3c61a41b54ddbbe3ae9432eeee8e4be3393f8489839cda6fcf693cc250ff9652fe87c03b48000c60445c84616262064668a0c90e34389343163b98e2454049f913ef24452bd0e287a41df84003154f8a4fc2d6eeee6167ecd27425873262ae8851014622ea01c64c51c516269808a20897c1961a30c1c1f184aaa0faf7f6e8da3121ae80820c8c95b07240f96ba5c0fe49aa2bb50bb4c0a28595ca7f02901061988490c2534480a2fddaf342c5ff218292b0bf886b5f0b3d2415db2e4998a95df73739b93a21fef869178ba084b6526817be166bc7c7441ab573e4b7eb5d3cdac5eb84a5490dd74989863e4d34b9be38e38aeedeb5cb9d992977c739a7cfe9cfc349a1daefcae572bc82c0bfc06da852deceeaf84f6efa967aeee9b19e3f8efbfdb39eb5e38fb48b3ea1fee1ec7cf8330bdc49c5384e0a0dbbba404fb3a62fbcd4dd528699caaabba50c3195ab91ff020afcdafb884976482843631bd53bc6ed07bc80925153a25423538dae3dafa426b58f5a8c5fa87d2e685c94518b316ada27bf7dc12b7f8575b1e3eaede12cd5df54fe4d6a1abf4ca5bcd5e9dac57146d6b6692b5e1dde38068573c518638c316ad23deeaed4b64ddb18ddbdbbbbb5f8b1bbffa8abd32cd69ccc3fdab5b4bb37d6c6d327b46b3f046ef7a04b4d4ac571aa94a66d8cabc9d9dc944a95da1c57f456673fceb66d4bb172ea4a7777df388c7126d95dc6a86952326fdba64929b79a252dae5edd7ca6acb15dedda326874cf9152935195d32eafc6e75d1fdecdae9bbda5e3563c68341937d50a38c6892915192783855e09796215d7b9bb0fe936329b18db2aa678a4562c16a5fe43687cb058354dc494a879bc86de44d58daaae8a53a53457a9542ae7544e44cf709b23e78ef628b56d5b75504043625c6e95d3a57efce5e3a3c2ea476a05e4bda254bb9a48232202f235eeab7e56af38a75d3f9b8771dac5dbca472af08fa69641798fea5543ed045381add68243bed6146e41d94588004155debc6264a4d2a2a6b9e611082866fdf191ca63236e83c2b33585e91e0f92a4b49556ea587be94d6b2828a82abfc734cf92a9f2f90c17b54bee88d1fed83ba8e03687cb21a3b3ca3258122c06c5240595bafdf6feb1d991aa9b31b5f1a91bd05aa183a13585e6190c62908bf852bb9b53e551cee11f23cb1145c366637b18ccbe787ba8b13c1d667b3aca5f1c420c34aace9fac0fbb29ab27ef612ff6c54fa64ce577352aff93f70ccabfb065bebd87937aefaf7e1a4ff5b1886b7afe2e5bf273dcf5d3190ab5b35379d67ef29eee992b6366820fd00f7ff1bc12e3591028a076f17fd0792cf3177f121495839bbb6b9aa6757c0f716aaf2ae020c7fd148750a2822d757e3fb51857c845705445fac5ef1fab7f44188a05f70a4490534a54881a6e540b322068b850a9c631228b585d1dd4c5e26949cb512c06ab61d80a29507e2d5f30ae82b4a6b0c0f717abc0055b53b45f9065441935dc99bb76a4e7e3af2b43b5178885ba92c52e3b10b4cb818a29a104ae288b448a18d515eb68294a110c3c298a13356428bb9483931a466e77a10122f01ef91de0bf998081e1ac6bc4909e86b1a268f547c2b0a2a51f70a8fe4466ad2f701b2ea31449f9236fc87e78cff4214d3274c5d03fb8e9a57e67474b7d3796d0709b90782472d73aaa8ad66906a2eee9fad5bfaa256e8041c3598dcc663bdb59ca7be6f7e41eeeb7c7c63daad4eaf403790ff7a9f8d5dffcd2bef0c6497ee107b53fb6b7363882c4c89c4dadbdccd45c3a6132543ba85ffd48bc8784f66242ec9e552d41bbf697e3c47b4eb0affe18a692271c90ac0e0fe12f88a328d155f79777797957d3de59ba74e9d2fd71982e6cc27c0cd61ad6aee62149049dc5269a18d2344dd38e905490180263831a59a4903dc1a4c687a218c8a198e44a524a29a5c6b47d318368484a29935c79028b35a6502286882e9c698a303da8be94012545b524a7abcbb483ac0cd72df93442b04147101d0307b34359ff392e1e06604206008b1504c8328500aaa05add25a62e71dd054b4ef0a07ddd25a62975abbbc474e44d96fa0a099ce1e405982b76f8618cff2b5b0f9a51d1126954839438bb03254ee567668900a4d0ad2e130f3708a3868d8728d5290ed30e666aaa2e130f5cd490fe5cc2b7d490f500335fa0aefcb0035292ebf0af7445ffd36c41f77763661cd89318f3182d95dd573e689e7bd54b6edd66bdd77d230e272326ef3d52aa714a793bb1976d979d9aa7bf9bff7d766a9efd7ed058a27fd050da11f6b9a95decd42eae5c436eaa1c26a9dbd51ecafbd347351f3d1b7e72eeb86df536de115f7d8d27a45d71e58366cacdf7cac7ea93acec0d47357925e811627737efcb18a5bbdc26f6d23c2958d38b81daba1f3fb1d2c7499c5457c5ad8c454e9abcb84daae3525d978ace3aeac14ac7a58a624d4c36f1db091bf911151db02751b5417e2e95e4b1cacf58f8dba9297e69721813466a29ed62362ac2b1030d39eae663682855ee1b8fc911af4ffc73fbc2f9313f0d214284610cf5ad80aabe85e6514d6905b9f1fbb552d829ad203537bf5f6b63128eea9e7801f2976cc98ebbc48393ea41e51e1ba39913a3213889872d356c2a957bd7c9b35476a2863c2602aea3024ab43d36080530dcfc0d0d409ce7e728efc1f982664802a200e7614801ced3c020ce1704821fc09b1b5f1008a2802b213734006f40d615fafc9579da5c000605fb2a0e28d4c5507352eecf63a80f7ca0fba9d4f37a5b395ef5735c149ff11a66039d1f721217e73782197dcad971a620c314685a6afbfdf678ac34cf7e0c2526da5c00f6648408d582862b2352a47b3e0097a3b8547e3ed3b05dda010a6e871f87057787a356879f9f78f093cbd5319bce4983f382168c17322881422c45d1f442b4040a0c1a018b2d305088c13c394206c65640abb7d0c0cc0cecd14314483118c845efe834b16558230b224e76ee05ad0da03043060a390d4ead15be209e728319a240a1550d33d03f4619b460e6040aad5e8004fac72f8865e0a48918284473c611e8df6eabb112276494c0f616148adc38f4182bc0785a2e509834711919506902395f42c31846a0d026a31b460a18249093ee04ca4a1328d49d39e268dab08596797483153230888198c129060af90e47a076460a1033b06938228a285003a306982890eb68342d6b1c29f10ed6698b2632e712f58453ff10454313c8f96ed114451228d400323d84891a0c6a98411328b4d383981844275c684004725ad79e27110326723003b9ad6b2f686540d4c00914ea34aa84818019c0cc402e654506284ea0d00e94334dc09c56407b4108c0818c245068aba0828015283102b9ae6b0f0135d8900472abaebd03b4414311c8d174ed711618cc10052e93922e512047bbf6dc8719c8000672365d7b41ae0519658a40a1950e4f14dd74ed79d10f349881dc8daebd20f985071a66a0d03a1501469caebd78650b2d92400e47d79e63a146124720373dd0d13550e982040a31bb1358cc38710472dcb5d76a982992815b85194dc840cebbf63887299e20818cc31145c8c0a03ea3062398b604092b92402166bec107eb7bfa98dc75cf751dcd8faf7e3e7b21d8597561f5f397b43871dead9ea5303333f3b6d1d4d43c57b3d56c5b951f4b69573f8dec35e856b93528576e0d2a2b173bd51a5a975aa1a0aadbef340f8b45a993eb3ff0e19b67fbfa1989f2cf9cb88455ad41b515ffae363ea2195237b903a49582fc14f091ea4377e276f2399dbc67c1e94a1ee522384143f752bbdfbdc8afb5fd5657bf54f28e6d338d9e3ef8f0114be1595dfdacabd5b3e72b2f7e77146bd84523e0da0a838645e2d6004abfbf95be161fb5cb632967d0bf12553525ba8572636957c76a33c5ca1ed7560ae189324ddf708184adc7713268e0fa4bbed7efde1159b1a0618b69a7586d294c5868377d1dfbacd0fdb063304683e3a464667ed9d139c4bfb065a21605f8b55f41fe7e30eccbd73e18aa04d967180cf2f96b2cabe3bffef2e7dcb3820ec94f0890cd0d686a5ffeae239c5e66476a0e7ad05251430e780085b62cd0007fb4a630ac700128b45d010350bef605ad164d4e4a80429b1210a0fcb61510f2a8fc49407f7fad207f7ba92465c497d60a9f267ffbb4179a33dc40e70e166d0591d383f6092e567801063cec2fe5e73c1454fbd9cd5782d5c310ef7922eeda1e5e0b44b6ede5a1fd7aa14fd55ee09e9db5d0fc0d51a29188d742bbfaa714dba30544fbf8da47262a667599a880aa05a8cb4485953a9b87a97e5da62f522a173b5f49b949606b94c0566d86b2b216b5fed82cab06a46b7f093c1026a9fd496a7f3f0da4df05ed350f4800aafcb65d75733c32e198be38a9367599bec0bedd1853af799b53a5b7af79aa8f5e00ea265dc6df3eae50e89f807cd9d5cda95acec6af43a22e4c76256e66228d33c47df3040d5766831ab342458a07b6c7cff668ee9f2d1e83a7d82f8f45fc34ff682e445aca5ad6b226d24da4894c2dd409112832994cf603886a319b1cbac848e7b0cd3245462277195f70cf0356cbf67cfbe2af41ab600b1d587186146210000a0454f61e95dd0b5e4f29a985763191fe3eb023f87f42768c2d4d2e040d295454932225d174515c03494a9467686790ea0f6dc30119cda4ddcc8e934f4c16ee0c8b152ad508926d9a91718f4b4c14ef88f11943c61828471e738fcd8cf88b998d301bd16464239a9c363a90329ba5543355145c1a45508c60b1b2b9fcc53db7d6a28be23aee3eea280dc4aa8b7240c39d4d1ab9e7169ba3a0b151236ca53a9bcd664a9369622370699f1e4858b8a3847009fc710c438cb00c5a40b9913468d8b00ebba836a9bc89bc67f51edf699a703cde11ba8eedf3dee6711e9fe20d2e768cf8f8f8e4482aa28b895ec0eb4eaed1ced9a60eb149678a494a95834f556a23cee1a870dd8d0edd0a071a32d18a0627079a9a9b266ae80d26166a08b5c942e30e269b9b3528efcd0d336ee044a191c331e273860f0e19d0f8fc383aefe5222226f282fafbac8f07396e80918395c5647573a3abe33f844be0cf6647b8f1c54cc756417dce9821c30a13319940820924101111f9fcf08f65e5d0f16388dbe112f8a70008b0d9016b87fba6053d77543bce83c71b5de2dc51ed481c208af8949a130d37c6f270a763b2e3a345dec0a0e12209194af59f1d1f7f2d2e0e1d380e070dcabbbbdddd3631a0fc5a7c5985f24edffdb40f8165357edddd0d44eceeeed8dd317677f4c254f566efd8da1641f9e3abee8dbadb366b65709b13c68e9ddca6cdeac4df1882d4be6c44b0994046d9695b472937d9cd8a6f33048d326a51eedd44d149bbfa7520456ece2dceda1efc5df9bb591d790304d555fbea7d495509ba3d761dcbdf5d6af365949299e76b9d9c40ac470da58ddae51f1849d13185c6a32e4654b99aee612727560b8d1144598c9115437efae019c939c9830f5929c7c7c8454382e2508d2f24d620699ed6c718a353c4e98f1f7fb6d8a02def9b7e1869887ff0852c1d5f485939be90e5c117521c319c2f9c4621f59b161b34ec66ee365f386521ad29f21dde3a79cb521f51f50ffac610aec99afb2c5839ff0eff863e55b00d4766662766e06ea2061f93962dae2899a8419558a65489455665134330f183ecc9a104462e4dfeb38625a6b8e2a5ba6a36c1344e57643a7fce7905cb15236a76708ff8f30aac4625246afcd6ca47a4341011e58b0e9e58d0448728b248d1344dfb20f5a44445893035be8e958f488bf83259719f60cae149e205498c5102a96a4890a9dae758f9d05c55601113638cd183950f197657e454eda3f6338caa3d3d628caa3dcb4a1355fb474287236ea8dae358f9d05c581c01e6468c31e270d951441a463451841155fb1b2b1f1aa54bc49002eae8090dba28e150182104b793ce8ede6c971a76496324c5a0c6b759f9883963681874e5438b677471b50668da965043126a6842d59629842a59aab021832664f005112d20a28baafd5639aadad3346591a166a90a518df157ed84937c4dd3344d8bb17972545966aea6254a142f4a4a645c3465c9c2c251e4da1e4ee5892acc1237a8a416638c93a67eb99c06d490c7135a96ac3040d57ed218aaf62ced9f49d5de25c41455fb9d1554ed7d8670aadaffb0a06a4b31b8220b6e4372a2c6d7b4170c41668d1fd6b8f2e505dec5883238b9f221674e036a5c42ea414c8d1fe94e943151d4700415596600e35c9460c0006003d452e3c777aa695786543896a65099223c99da26b7edc809903094acec6003a8288c80c8949682f8c208880d8a5831a4a52c456c6abc92e84ddda52c2f4882eea8bb9445869913b3073821bb517709872527742883f67b6fef2e37af7cf65ee8caa05dc39f6550aee1772d5710e83a3dafda1534741de99e4e721e924907d89ebef9f83bdbc3e6e9872b5b2f56b387f86b6adae86071f7ae0ebf8dd749de53a45ff1e36b5ff1a39918d3a871e38259286a7cd5174bc5b88076aa317e38239176bd14347424588def48716e7c1f6a16941a9dd438654c20f0c154606b05185ab45d314aeaaa3102404643972b27d2744a8b18a4356541d6ae363eefbbfcb5fc85eb64820f945251513c8a694d4949fc1c0d1b51c16691e324ef6125fca4f247a548c44944f10b3916e78cb18bab18e5aa536ddf7393316a1a5be917d7481cda3d8d6ba7fb58feab5fb0fb9045e4323281e8a7f37ef82b16c41be22f21575443463256412d05015b828192f61a0c90ea9a517749ca957f0a43bd1899c0af02f7778c8cdcc87dce55d1eaf0774882f00f274569cc7bf84914218ae0278e19ad0e3bed60b1b4546a4e6e7ee4542b1fa9e7150af3b7d7e616a3f69af69aa63113738e07e1bef3f9e13e97efa83e745556815540a010fe9091d888a1b831565081db17d16c38aa53b62f88c1d60adbcf9f1f0cf3b7af06d97efe377bfe825b7703e12f2e0b9847c130e03d2278012606b6806cbb0aa27dad0952d54fef705610ede517d49ab2e3affe7eed7b97bf3af60fa02b50fef953d4a10b19454c45f3e733c1b468991d390c894a0f35eca893665d44651cac0b0065a2f88b37f2392a95f21ae6af281c2ccfaefc56b24df4042b4b37015086527e9ab2d509829fae18b183862573445136b6879f6417557ed8f116dbc3515c832adb68abf69325a1629d7cf7f7afe352352b1fbefdc79523f1fc6ececa3554cb5a42495977547f61cf729e15030d218a2e5964e02165e84aaee44a4a3e49d876bee7a4dd51fb926f6482f4915be891595bfd496a557dd8505256fe9c50ac1c28c74aded34ff6253f4a1155be92944e6db43a12ca09a71ad20a15c4a0ea7f3809003464074d367e8c9fe302628107e530ed35951f877754aef1fd9f66a73efc9bac3e2028eddf811ea9d1a4055328b78ceeee21cc7c0758aabbbbcbb8d345530c607bf47b7f5d506e57bb583a50ce3bd512b4e917a309f1f311e10a6522a8b7093f3eed62614157c77b806145b1c58747102933dcb66a620201fafddc0e2fa85d60031318b8c30b0a126223643cc4c02af377bc083aa040b8974254ee93d4766a9e30cda3e359bff9c66a0f7ad6b0380fa85d1bf7add607df4c1e4ebb5aad0f85ae2dae6edf5468533bb598ed7b4cf77094eddb8a53dd24b87deb03ee08168668336a9eb0a554212a109ff1c2c40994ad35bb99460d0ef7d1766d34eaf01a69fbe875d20e19286c7b96c74349dbb3d3f639be90a56a1c8ff385cfbaf185ac8d05866e543620a5e6a1f9ed1b4bf3a8d0db37d3f6d07e93cf79e1576ec8eaa777f3d10b8b2c540739d2757e3fde4fa14fbd01e16d3cd5afbcd67caef341f05a292198d8526b1a69076b7b6e87b75d10310403819a67fe4685053210a680f03b3ca0e6f9eeb7e7be1049e57e7a21923a9fdd0be777c441f85af31764a15fdb775f6b7eacf313c2c445cd99f3fb8f80fcd5d378ad14668802a85d714f65e5f168d79684d4aeed456883ce57a179e647a45ddbeff0b81ccc62e0ae2ab06df377dab5bd099e4fbbb64fe5405fc906757e612bd52d6ca4bafdb46b73b6cf0587511568dd1fb076a054287f1bbfbd233ea5fb58e8178f61a24e89d95e917d4261bfdfbd10ec537561bf91585f682b050f859eb457a576f77bce20ede2ef3d3e94ca3ba5fbcd2bb24fb55d8b71a7985591e45af4199130fd19699e0d970cba83052fa85ffcdb218942fb1b22a45d5f147de2518195449178096a62183f50f3c8a3caaf42f3b0a050fe1fdc2d7911537b3581fd0e6218128e88902726e2e13a21baacccccac04c6520c5566662ade4cad1d12b444f146f9f8ec33d7354a7032071774ab5c41802b03d16a2b85cf058d9bdb24abbf0a5400474b5ebc8ce1a63db369cbd462ed3021a6ba6e897a73fc58bb1878ea2e49115565f4a8e6e100fd10a10dca83846ddad9d99e6caf71e1769ca191080b438eb4a66d5d1847f45059fb8aac530a5d18473cf199554e56c2bf9d26e8d6d8cf0e25bc20edeaa75cc352146264f4d6d7d6b25e987d90419a877f9be1e989334a0051c39e2d085150ee57cfadbc86f217b39ed0d404bb75da50298772198c363bcc7bbaafe53df39eedb74a46cbbff9dd07c30743151852afe27ece397ffe0043270aaa1224154ed91eb67d42f361f8d4b79cea22f53d09c181ea43156c1f02559db27d3020f1d747c45faa2e54dffa2bf53191bf70c044f3abe2dfbdea4356179d8fbf1884293445f35bcdb7622b7e53bad80c8a6ac84620704137075dc6a00106c230bf05443ff54940fa0555f1dfbe06a95d9cdac2cbb1652876aa4d5e08183014ab468a30602856a7c020b4c9c0d46f9fda425b260216da5fd84f7593810ba63ed82603b7afc5338ef217d450c38e70f217ffa6c9dfbe4e1ad3444c5a16726da6767592bfa648bad2a4863d6b275dc4db5a9750ba87953419542a379da91cbdc3e6d6b61766a6957ffb884af3eccf28109cbf12b4d5bfe0a6b630abfab0f40416232c2d20db02c2ad9fa2fa84546095fe24759ff793d424b50544abfdb552bfadedabac1b695af27342bf260155e3ee744ee8cece67478436e886446d6666d5582bc149521db3fc6c36cf458c9663a9e90cb7d8ab7f10edd931455f869cd849141f691d817e0489c2e15504ba87edd1411b336307513c81421cc59725c02afda0062435811f4ea369fd3fedfdf0819ef00389f70075511cd43024ebf403c9eab88deae7871bd5b56b7bdea889a30534649db0f2a1fdaea226a36c7d0ed777252809ed72c7a9db05091e6ac84426f8d4241dabbae05a40fd49407e76fe1610f3b7fe62b0fb19ec8fbef6fe24e0802e9fa04203b58be3d57e394ee809f6e5ef2f85913e3e8a3a8a95c1450551fb439b96c02a02ea360d9d51696da212e539417168a1336e67bc8b1815e18ef0c38ebf711ff990d632b1d2f7d43d4def8186ac1424a9306385cb11182454c3c3141780f4855a32a411036b825a01fe351e9256803390d404e47327c5867f0b5989abef121458aa4735cc4bf56f22265090a9feeda47b968b24180c16c32e4d61a63ae8cf6d6c85612dd7e2af6a8e1d1224341c551aa2ddb3d2d675bef2d1d1acc47450fcb44350f304bdabc29dca4afcd3dda7f23ba11060a15382ae334cb56a354143b6c25492c4a86ea00cc54fedf2ff9ad0a54fabe36fa3023a47c0f5e90857b9339f676ca679564b104c75fe74549a4154fde9a0e6d96fa2213fc57797a2fab399edb1b5bb9f6284220a29b5bf9c6f9783536cb49fb6f16a94bcd4137eac50212cc4232ebfbbe3f7d7fa515598693c01390e5de718e2a3d0709f7866c84c5c8e01161242991583630c50804eeddf1edb7136b553b59fb74788105f7d47646aeaa8f36dea4cd5f9d3c6f358db0b0ee0df55737bf7053c046739fd82a05c4f5804833e3319e23d3f29eb818474169403dcc37dfc211bd81ea98ff353de065627fe72805ff1e38c7b465c356a8c435627c6c8c31237cca0e14ecafa77ad53051888029302abd31598abc57eb1646a8e9ae372fa6643b5046d9edd1e110c6003fbf20f67eaeb6f00db83045c9989b9690af1971764684531c6d2594c7fe9981ce3588f0bac0e06f8e5afa37e21463885e4b0802ec736a6e5c0a996a04cc6b22064a1a87c44d096dde430146e98392965b11c025b7dceee2c88b4d0aed412f42b83f277165886b828d13c6100b8abe9ed129959939b9c526eb29b638c31ae4777d75ec02a6f5d3235b70c547fee8eac52b1b721d3344d8bd107ae6776a8a3ae4df476775f01e1182a4ebf2825c3a293d9bb70817243ebcfb5e3f3365f3379720ddbf0cd17b2ea46433a3f74edf8a4bc3db9bddbb67c21847803a75ffbad1415f46342d070ce36a2e669178f76c9ee62f7a87e555e0bed496de7495bfe9fde96507e2d885b80431950606090d08241620656892f5423464b1358a5bf0532644370a2a88b47f7a89e559a27ff0b1d0214a479b69701a6a8a8a42ef64435756646000000008314000020100a860462b1482c1a1236691e14000c7b9a427c56990a84519203310a21630c01000000000008608066c4120025949beb342a08da99c14bd40aed6e5ae059c18bece3e31c32031202481e301737c55a5b07996a4ef450ab8c2c9344c846b0b4ed9c39f2e3e8455d22c6257bcaade8167c40387c9bf12f38617fdf5e8a2ea2c7bab614bd54564dd3a17670f89de9fe9a112a22d00169d178fb531749f72dd5877d220f48ff91ab95c5b8268c8f25c178a7404d68694635be7478476851009fafed2039e96ab767e9e83ac46814d3d4ca2b497301e6338da96dea5e2729b3d48a6dc9a6d87dbc21cfb8d6f41ed4a8735b32a40039082e76c6040c40bc1a446ba2c5f59ca560a3c5451c72bd6bfb325a370f2c9d559ff0d6f893ab4fd1f12021e520069a0b14516b6e0305a22945032da57ff829965ede15325b2ab9320edd598e99f7b3e45d98eb05bf6f44c1bec7a7860ed09932b335007cc3d6f09de42cb657c656d9edf2369de1cd2eb564b865d9fe0321ce12d8312c8509375c4f2a62f0cdeeadbcbcc761d82f2f5b80e6ca90018b2a9e704d2c94fcd6a170ad44d4ffa4faf775322fa1579b46436aa18636555991c2c3a06467aa2d27554715e24a3d38b2aa1d61f45d7398236e5d57b35a4d3011bd71c6ca5d175f0d215d1be0ea7eb60eabdea5ebdff72ed14081ac7342bb16eb2a84f3643b2707906d419451504e2ab2460bd8267ba6abe7e26782a7d0550e3d1b826450ce28e53d3d325785889bb5f17648aaa8e011338940c4c03c2be6fa9427e5ada20d6ada7118b4f507f07d0990ce6c835a1d9ae8d8ad303a4cc1a7975b6ce2a9b378a1cab18bef6e11bd7db76dbecc43830b5d3737dee3e5f06013567dcda06c34d1438de4423fe6f985ea5ba9bcea516c58a060cd26846d2b9abe4bc1c98b08d69255f68221b9a75c9018be647c0e5de9f24a5ba6844ed731fba7e47ac6fdb12cd543dedbe1c3b10ff92d4219b935d7485d0b8bfc446c94d299a4f87b9af0a838b0978f3481cab9933c6cc36f4cb86d52f3c61d63d307c9b28680d1f364b9b1c8dab150383a7222ac62492a5c686a9835a0d513a08dda2463c144a490ed1dcd06dc77f16e3c9d0b94dcde994b0f13d5069433403a4834ae2c03f76ac35318415d3f208e3748e1ee9ff10a859fab119769aa2a63ba9a7823d9c72f4b1ef903730a7a46d9d2cdbd77ff8367e2e871594a6e75dd028f7b9086bad736b6247c859011fa399f401c43b8a742cd9ae6cdcac91ac54a1c9e7cd241bea75782ae3bc9e53f9b7ca7c8f0ad8edc40a297681b2d32f574b0ddd1eae80e0eedbdd61d69e3390e359ea48a393985c96d8397d570f74d7e6e9ed7872bdd8f299815a6d5721d05c17845597d8bf9e64c8ebc5d33126c9c35b5d7011ee389bb5e19b8808cfe9055e606eed1795297ca82966dc8ba3532dba779e7f91f14c0f25e8460c9a4ee4f238247a07f5d624d25548d8f0d15d6dfaa3bf4afced947f0ddad0d1d9ac8b9254dc21f769e44db7bba0f96354d7b45a7e0d89523a666da797c33b17572127faf0ff3ac99d0088b7e966765ee61590731521e813f07311b2251a5959c858f9601aa44d11f53fa49a8e62fa06a5efff21a07a2647b5bd85e31a465ec3b2be336f94ed4db158173fe8719450e01f99cdb3486540eb93edb6036baa5853fc5f8d312491a6cad9896d0271892f12dfa7b8f0388017beb01c3faaadfd32a4b189b72ab2daed67499490dd426de2a40d1f7ec5d56271ae571b680d48d341c3269ee8a96442280579123815fd02e97bddeabd35bb7257ea4ec1af879df3f74ae0c01c6f56c7076fe3ef7e05bf0d552ccd2c733c7a0cbe9546053c312a870ee00db5f3ee538a969fca0ce58e672824025a679ce5216e6eeacf3f505820175ed3be7a5bcba5460dbf1ebd60ef02d610f3c3f90cba9e7648b4187455f724c5f9c9f7aec75da96555116ecf3f3fdc218649260d406174def4f2e2fd267e81cfc8d7881d1c92dbf9ea3f5f154e81832cc46cf1cb0344b7962e31fbd5471f728928e93e69d692670a3c84259f220c66045f1cf5b75baaa7cb0e7ecd804c5afcdb5bfc7c4f8c8ed88d8eed88eda0a6629be786b8048da6d3a2a29f2aa7d965a1550cac60aa52bbbd72c665f54ca6a5d5b2a96f02790f000dea89a31fdf32a9091c6cff0c4eb1f6fc6781d349876f8e1ac2b23bdd70d43348a09c35e3b22bba9ac6486b4de48388afd0203ed374b0346ef63650a0c0dc33fbcd6e3d1f550526c252c313beee7f8815c809c0a0aa431bf552228eabf8864a558b2c1139bec6d35a49e2b7d9d3289cb40cb3832960e6ae2a903bbface4bb5a99fd5b1a8bb24e897e62cdaa3518a0424df95d2146611e29742899449e0927ee966cd051005f36cf42e0bbaf5ffab32b0e7b5e892a665351b2023232ae6f5e8a59da1ce9b54d67b4c6ff3b1810cae5b9a154514266a98cf040645efb3dfb63aa5270217648623142fec434f1bc7e85c4dff0c03f4375fc9cec82941e533bd73a889b932f829ce7b343e6be751fa1fc5b7e5f5bb99af0842199218465909134e78404490113e247b12328fd15b10e40b4a9e70ba961ca33ab1a8098923d29288f1ad6ae190497d2538c52748d3ca7c63276961871ed89e44d2d781b8272a8b89eb47f24007038b2fdac94fb49cd859854ac757cd192a8c4346a01c6f3f0e55f0bfaa33cc79463166a2e2d1fe7b623b52ef03e2560e813f1ee2f13c9f125a1f49f259abf95b4add92ed9b2ad2ec303c41789bb1cfb3c9cff949653f6f967f462b7175d4919e65f021189b2c40db4cb6012c6db9462b70690208ef7dd6070191f7d000dbb022c630093cd3257f81b2d2c2e9d2bac7194ea88f4228766636ca966cd997ec13b20c7fa672291090e7a370e3b5dbe826dbb9f546e4fbca1d20597c57c7ba254d4a3b5c6f625ec79561012156c77d581878412c89f76401ecf2e684804aaab91525138b7d42255a4069cdb5d2c4e54234282ea76b05d96b6772ce236068cef19c5b0438ac8c37895c8352cc0fda0bc3add46852950dc1164546f8b853f1099b9fa9ddd38cd922481aa35c12ea5e1bdca18b577f1567d391fc64b7d5d04361bfdaa5c6536772f6e5db87efc213fdca1b38f20bf81d2a7918c74a5e0c6d3fdd4dee3c6db28791d667823316ac4e01b4e407aaac34edc907d790cc1353c67accaa7380c9a937fb58ef3630662d90e7b39b38c0101b606183eb5d5da9267fcd6801bc20d79528a571e3cce59b3b2e8da18fdf55806a3cb16fea53e3728b07eebc2979e108f8d2d9b532423d231e506c0546b2a7793284d9a07aaea5d03ecd9446d6a27f8b551dc233b1d869e85f654fe929477169c237d13542ad3810ef416c39e0e4dec26d093682873d6d909dd8cee81c07f72add41da08950eb414712285b63d1fa6a0a99b1d2a80bcf4dcbd8f407f3492cb86b4901141ade321c9b7147c20ec43306cf6d8d72b2fb3c962a2e1b547d18e239f4b9c43d65fb58a181e09a0e43ecef88bf95cc7858a6ddc8c0e8c8a8d3b3fb407e37d2a17cc05832d064a4779f1d3f346b74ff69f0a5e88cc5b7a56d6113aa55ac246f96bae29a6cbd62131b56973b7bae3bf81fa0ccafbde42e1996212a081d6d47b6807ed3a5d9186d4afe6d31535b3a71dd6fc41cb83f1906ef84eb21afbc487d95f16dcbf9301f03dc10cd19ab81ad9be7bd9a68b4a4e5d70d8d7d77789302ac51db2bf43f53ca3647b4bf3064c51ec0f5f5dcd40dfdd28bc2d94d132cc829d13349c9e6a0571e3848b2b0228222491c2ac0d7b31e56c942f5ed68bea2724deac0271b0c2dd8677f707d4b0636408e0eb619c5e89def5ccec3304378e622ca32ea91fbbdeb97849da203b157a8951e1ea4bda398ff50195f042fa29a464c76126be7191fe2365e7bef6f5adc696f30c5ab448edc05019b47533efd2d1a8e9a98fe2d2f4f71da215cb33d6b5527132174d202ce7f46eed2682782c472200bc296330a43d6164f4a4c0e8841e907f3bae7b61a9f00deeda2385a7ee777a3bf1f67c65f55c81ccbec3e582f22f2897432d2dbd6e071d5bd68678bb4562d645c79950edd76dc7ce9a26712c3b788875f6b7daf8dee73f79737f314c2623a24acbdbb193958ffe8c3f834c659dad64901b437b736e823824d066221f9f296c4b07c961e8431238518c86e4a20ad19a8e14bd1b772234e0568b6c690bd31935380b6cc9f50b5ef9eed3af09fb477359a3f226e6087793d5e49ba0343cc5e6b8e41534c1a6015eeda31e3871306aa5075471542bd9b324417e10f09789e663bae8f6464847544fb56fde9f8810ece2aa1af6df348888352d3d2dcfc0c19efe4445b65721baa97730f665fe1e3dfdd9cae5c7281e553868b48c43cc863540a8eec6422cb36620147aa6a07e8df4865b62bf0336f71d99058aa51aa302fb2e3f26aa795233cce1adc34ea64029ba611fb03070bf8f5c3a619cf28f282efe9deed6ef22142bd61d9e15c360e4df2b90b3e25e590b9ba564e2944a4966e7e334c64c71ec10163ed9c9e45ebe08a3940066b96bb75cab2c3020cade315faa88964168ae278fe6ffece6898f92a4e4820a84fc04da65026092b58d522dda43c703d746f61f198300635f47dd5640f3d07c15de9c05c05bf87e463e11867141e6949cc905cd84de3175e64b8918fb9a60297b654e8828a4e5dc978c3208b52a14f34a234086da23ae5427fb012be53d3d5a260e45755659458c9624ad84813ef999b24c3c05a4f1ac88e0580b437f4f001f7df7c344cc226f07dd43cb0e8832b6a330c0d5b89160d968c8795b246065516f958c9faad7f64532ef0c20c72d393ca7a0a63afd936835c53836e3c4949708cca9bd452f24d2df384ad2fba0636872482b2c72ca73a8272d5dca3081bb49022b312925c717be76cd4b20ba54d6fde0ba3a34ec9f520e42634a59f83ece07341c16e490bd7cb0ee488705fce61b00ba28282f14fe49dada049e96d3ea7c5ee08bb984c8896d16a83aee3aeb7255296f21b01bc43a2dd4eb06ba5e208fc5c2b343b691b96aba210c06ce91439f09ad60ecdbb596d885999b6758b9ecdbf8f96e966fc3af177a1efd6fd9197f55050c0a93ae7f5a4a1c38e855b462930a7282f7008aeb9d694f6e4134dc359085fda9ca36c205db9fd3aebe8bbbd5bec90cdb3b005c809d8af3aa4c1024a2afaf5bddab8f94a50ae23b4b5bd00fb9edb99bcf1fb0f3deeb6cf16ee2cb310f4b679d9470be66b7b4fa11a845eb2acde4687d1e0b19128fdc2d8815c222041cf6282cc4f7e2dfeb3a3aa13890fe4c19e223788914aa52082578214a027dcd12ac9558d59bce8bb718ba3592a6df05eabe9e83256bcfe2a00c114f513ffa81d1064684b0c9f8d488f913d518c08a9634f09e6a0c8776bd68e7868808832a1300ed1db4ab2719cdc4c6e4f8e2bc55702d411c351c29d2643738ee67ed12ce5da1d099d57590eabf96ecea7ed375516973bc9234af21d3c0c197d0b45a662133912d18caafcb44a09a5a3cfff99748e07dd590c5fce43d50631be3ab47936ee1c4e43f171f2b865fab372a60d956cc4025d6c93bb8afc259439ed9cf38f7a7c95fa2d7f7e3afb63e43b904d6f2cd12090ba11dd3ab90d08eee8d49b8fee235238d8d3275a8ff44962c4d00eb1cd41d2dc54ab0a41d7d86d60c93152cfbef5c0ca3f803831d0f1c14100c64a9a260ed6fe43e2dd41788795cab5e373e1ade5f354f858ec509d2b6e59736cb4d25f37749703ce7f6664f47ba82c21f2386b55aa9b427218d1195ca79f8072e7f0dee8d09f0cf7b868d14061a2cfaeea8d67791bb916f7e8d2a87b05c112730a4b0a9c064ab8134c6cafebabf20156ca9840a38e7e53975f061c76e8335c021ef521f7554e8eadb7bc726ff20a4c4297221642e3a7c4923b854f6888a9985fe6e3f1ca48296385683c5b9372c609068569459c9d9ece3d452826ef245008c09814804fc097aa40a7e0db1dca621041bd08207ca708c3c03537af66d52f4608fbf49c0a56e5d87c734e39a451c7c975a07d5a65aaf63005548b6b82b9645db2d6e4133b46cec7067eb8bac33f2dcee9e22479ed878b866b68fc75e51439457c42aec219b0401884a6f8db72bcd0a662f4e275c520f663565a10610135f5f4924e9d54a0a03d2ffde49039c684b95741e0f7b35c173c8f915aff228137912fba39a768cd4575b788bff724102b929155b91d74001393cbe84af7d46552fb7a9c52b92d86500fd41e4d4cf7465372c8bad7d15db2043fc9b7ca2df98cbaa90d1df75b504a7b82a3705423a17d22acc5c8de3444edef7c41e47995091bbf47fa343924752e6e3b51e210f1248a5960a79c3590933410efcd04a52001a73ea87c9a461d9fb476859a4d64a28c651056b2c93ce99e7f422751d21738ad857212e2baea08158efd8f47ce8b74460d6c928136aba46bc3674d853601026ad5fdfb2d485780be8da5b0d82c98714b6cde9d72a2a747fe6eb29389c40fa75c127812ad3afd5a15622fb55022f8dd0bf5fdfb79adbf08ae2de79131d476b7216818d133fecb35f3bb4c5eab12efed4e125daf8f0ac0a48e6cec99c4225ae4d913c5730186a081236616611d094d3b7fea045756a779eeade5c2c38cf99e5555de212e3506614343492f7f178072b698d77c124eb990fa12f80143ea745a46ed73e8b667d6a9e072e3d5c99a821918b3615c7932c85874236e8590a7814a3b9d8f6fb2c018c5ed045f9c37885b5beab2e5b8cbb05c4af5965bbd6e21ffd0ee71dde62559804070273904a0699d07634d6f373743836c68a5c0d27fb5c9e87ee55f6408aac5ea7aecf5dd543218acee9ca3183041a7993b42da88179c1a657f3a43bb3ff16241b519e8aeee937e80d4b00f892ea09bdeb76f908cb0d81e3984e42e8dcc0df59bde0448e5e5bba48437c1cca8aa4cd69bfc138a9ae8ff0b3c352ed1a489dd720555deb55f05ad0bc8a62a5cde8a82746aca9da02342d18aafaa63fde1c98e7ac68a3f832adaa9ebc594f70aeafaac5157d6d9584ce11b5b130cc2dd872dbfff93d0977f91bebfab4ed7f92c13c8ea7b2bb6425a6e7a501c819b76864eb305b27e004786d71a2e9b0b85a64b2a2326c55e60a586adefaeb15aa6d9357b542755b45cb27431f53206ce52c11f46ee6f22641001d83e28b801e4bad813e7e83c6bbe1a6ab456384f19723c140319846d7353b6e4ca01ffb7e5aa88ce57bfb4af38781b2d388b03864df8bef400bff1517482428067bd2f285bf43ac8593f54788b404370c757647705a15ba1e5d940cdae74c7623905d6b5d3cb356ac38badeff3e899a34deb7dce17f9cfc173613dcc9b62b1cdb0672d64a954dd90370d22c6d65e89c77c72b462014370f9bd57b49938dd17e6c4464aea2d0e63124ab89c6ffe10468ce7b23c828bc51a3ba7cc28d1457fd50bddec21b738340b0b5e6b9c8ab8416d01f89e36b76a667160d9a0039dfd885d35ad84264c9525aa531ae66dcef1822f703e3e909141e29f26325a0830c7b4972be562788ac5e50af9dfb99749cb544e0b21c3ae1cb1cfb44254cb8b162973bc17279c94215d5f4479d86f94f8910b633d6797d8a16adeeff1b126d6707c99d073ce089ddf3c475fc2a328917169d7c614d649c541a659155f523e44858fac6a804a31bd1252950804e844a430f64e0a203890bab444fd84425209496c5fa43d5f5452064482029c6c6c018f069d30577d018ba006fb44e4a0635422efbca3586892c0e01d0b35bed3abf1d02d9e32d02c907e9e4f9dbed8e5bf60a28c955dbd51dafad029bbfb829da53a655c8c3673ded35b7901c98c56a904b8bc557acbc264f38771909f90b2a20f79d8f24e37e41fa898068686235cae85ba9fc32e243e234fc3995bfa3d27ff8520bb491c0f356193557716b353a0f65e5b46acbf4e4a14b7f341b9dcd6122f9aba0e6aea55d3db4def82787882021ed08665181b35084f519f86b4e720e159d04c9c9915281e135c3f2ac4a1a790a67f591b01779214bf9b7e6f9f2c0b6ed88c1c907eda0e9cf552c6448692ed9829c2dafa593b32e2f7f20f94c41ca6c8098ab43537adcb9637d4d2e3afbd12931e875882aabe67a1c034211b575c5725fbbe98e4ae1aaec5aa44f1a9bcdbae868366c43968525459198fe89d368482d8d6154c0314849580abc34bfed219f171d08173991342b2b9dd3ce1e298e3dd5c87f634ea72ac6ac5253062cc4418b5c03af73adf7319068415775135d19ca4dfaafcc4a1c5c81382f689458b144d2d5c857a4fe9a012ce69b6398cbb8979b4c177f6f4478bb92e09f033f032c1b817d99e0968ef9f95b8a3b600ff4850c4830c8f226cdb4ac9b8192a138a12d32453786e4be7eb4abe343063e6a6a64454aea7632ec613dc872b3858fa4b2d29b1de3b111d8c1f1121540970999c73821623ba927afb9abd090c65daf437e1760de8977cda703e043f7016a128c2b17c2fb5ae246408ab280827dbf5525565507bc02ca56089384d007cb9dc4e649c9a4f4870137dea2611fe7dc54f09e2d0e2e83b67ec873c64dfd44f7bd25bceb52d08662389cedba8f174db93c24b7a6721170eb804d6953da084a6454c61780a8c4cc9a0ec816d26c19f0cfd5edf20086e037fb3905d490114c107aa59a08a3e09642f8f8197b7a5f121a6c61a3f3d1a3aa7e1fb7dc2974485f021eb0064da66515b41b77e0b4503d6c6351629f55f7be94859f4620c6aef4d34e2730255574883f33b4de348e09fd3089be315e1e775506b75455c5acd7517256aceb4a9650d1a6990f713b44512526d3cfdb064df0b0ce8788ddb2a433a265c67a6bf5a5fac5a5ee633008cc4271d044ca40e994420cb1412dff0b2c65b479dd20679a6ea5268e8a0d33b48530ad1b822111b4f312a4322ae2e4b7b00c2b8c4f1094fa7dc55798f01141d6eed89f88089cdb288315db50f1477f64b48c6fa1819c38e03e52e5eb563ad94a729dcdb8916a4794fb78dfa9c28d182a0ea12e5a560bfd34be1c3c413f13c52106e604b814f23f18ad3826a0109fb14c1adce0345831d39700d6f4f9ef22e8ceb46855c3609b0cc5c34a5fc546a97b74c5f3bd84ebede1e798de74ad54d963625cc00fb45e7652481dceacbd7280c30786067bd7b7228a0cd0c3427087aad96ab11684e8b59865373102a628605471a476023c9e79ca1096d1ef01f9fbc1519c55e19286e4909ec13dc20318f434c047a6ed0887a1a973835ff0ac7b757ccadbf24febc63a53cf5add643da960a5ad78b12623637959940ca7185a5b314e5ca1a9e7d777cd5002f682e05d3fc21e1624774086d5451b9420ad8b3d042e38b90079d78565be5185a68c4b113da0abdf7a758c35cc636ee7dddd53e078d77b8cc54701536b979491600bab02832332def1bcd73b34a441b525ae77aae318aa2786532684dc5ee13f7fc52a0cade15b086cb861edbf21f0907b2e73f50fdd3509799bb117522d3a5cc643cff9d5b07ae50f188441bee420d8a2efc3bb013f582b22439a5d0464919944fd8816edd694d827541a5c8eaa3aa7bbadc27391b82d8f442b5487f7100a186818d67031ea3103db375899b1eba23b3c0f6d41fee2eb18cc795a8c2723a26145beb918792112cdc5f5dcb93e11f748f18cc525a3459f474c7744bd5ea5b1a251ca33f199bbc87ccef9c0a3a43e2b82dedd3102ab17f0dec9d281fe0969c5f175eb90dbeaf92e061b667cf5c3819e1e3d5a91eef7b6a4d5466fdf2091eed321ceb78bea8e395573066d8df8b650215771b9d3f2e4fcc354a4fda1bf4d7fe5901903be8bc7696fe436a72e2e8cdc1205e754af016edf187a8f2cd2a2da3b335ddb47bd83949000d9743dc04ad0621d42471455f2322331e744ce7246dcca279a5f9f30bfc72d4e7de8a02d24930240280457b0cf212f465b7ae951c7d7ba1a54bbd28aa579375d3f3161a89c3df9f1740356e578b1b364aba992121962e36f2b96d4178dc1142d1d4cc5174e9b11030f6fef82541da218bdc49b6b115f967ed929fb019f2df5f51ea9c0a59fc6beb7ea99c30d08093d31f49ea9856bdb17eb1a73fb953ce362203eb7d3cde1b8d1a55f81233dff4a54ca3f60bb856793a855571004363099abf71a092bf3ea3fbf7f5b7241379a3b1347c603b0489995f60fd279c973f6b9f9d8cace18f2b7991591bef90fdf5283c21e65ad024fabac0de9a61af0fb69f268e8d69b5b5e0ae4001907a8715eb5c7f5c2d8d95830bc02ac5bbf059791c0fd28d1d2e2f6ceae94de1767058dc86d82e7bad218af6ba59fb1dd951974c274a43de9236d7f5c60a4394104c85b024e99140ec6a5baaede28bfaa256336b4274ab905c6e8bee5e92c55e8dc917c966015c6315f07c1d8c822d5dd036180a5dd2db3f6508ed8ee32a6a0efb0a4d1b8c59f26981f70b811ed26818c7004fe0ccf44e758c8c28ef019448be469422514de3fe4603f0cbb8dcd405029c7a63ae74a886e4ed392f374f742d4cdaab4d326160d47d559b8ec21f725d1cb9827bbec15599ab7191ffd09b514b246b7b50404b68ae576ccf2fb6198ff0ea591a7f15355e43a11af4c61625ea302a805b39d7fd8fcd97ca915b53c989655b2ca666bce5d2fc384096bc3a55d4e0d9d79607e829a708e888f7960bd6ee06c2e4e11948c2d35afc04b88cd50ce4c06ebbd07bf54999018bf9b2fa092d1e9436b4c1f0947123b27e5137858ab55b1a9f8913f3667d1c588d362065cdeb656cb0dfc1b1fea4b7e2eefa2e38ef09126c9a39926a40db466bedf2df53dd0201e00c914bb4cefe797353039141de0269ab7719d9d477b184ff63bb7634274af6fc5169f78fc65d1aba9b8216107bbb67bdaa3bcda654722add7f2b32582e798f8d074c838ae7b8c34017e30c87f5764d82bd020bd72d544a4fb2170061c19ce40d10fe8d11d5892a4db3331f055a757e6b3a42ea973efdf1e1ea6436755027ee967a0499b762cba390a1923da2978706703f28e3fb01456f3d5352c18644f16ec55e38a3907a13f2f63ca41b75383a855119e5d22fd60bdf1809d7e30f4b62beb9cad5d2717d97d700fa14480cbb8d6053ed86b2b618c5b3f680a00518dfc4ad6236c9a4128c8187c71bfab5c0c7568b51b2aac54d62b9fd604dba152c7c2b27606c3f8091367de8d04b703d3c3a2800cbb8b3b1b0cc50561fe09059ab97233a827577a435192fe00e8f1917008723551ac688068fe5c75081e33c62a23786cfed5a5c10b1e9b763cf4b7f384e8a9f382882aaef4263e8d4ca32106eddab2f7c87f7f15ef114577e0f1e0e3d5aea118158415f930e6b0f3135a77016c65f3dc810d64d161a9bef1611b7308fa516d96747743f8bf9a60decb6dd4e9f7ad9df420c25084dad62257f963e49288ee0dd309c854f73cc34d4a53edf54d654c49047b23a59c6f13f65cedb3902a226b61bff68b3b6e64a6f8c5330da8e636e0b819c0e76fd426132dbb12436a4cd280afedaed90e772f3c5c46c76cdb6fe6e7b770a521270dd6eb1510e59713fedbaf874434bd78f297bdcc42cb4c2f4da9fa018003cbcdddfab79b432e77cb8972a130a8b4c689d23017dd1753f7dad7c48de8d85e3933f5c9d718897119891c38d4a3a93e7454abb7808c8e4fc4fa230ef4925d0339e92d1ada7b5cc5a482df4a054fd1603548234a7443bc9a2d7b664967c3b5b84b6d9825e27f0fe8f3626ac41985f54807237a95cb2a9af87b01a7462cf43556b902a33b335cd17153b08780528d56871402c5a3107b1f40f1d62548b38b53346b7434ac301d5218b2a5b1a02078a1dfd4d75a27499398d1584dae3a7627d2e53de5c3b6bbb8222ad23a904863d68982a4646b027e21f6a8d5574398bd6f30a6c913027faee3b880a4f5c038a0eb7d3af133f96273c64c408a4001870a93384474678001a88789795ef91a3f214823ddfe8b833f64f61344e9ef3c8923fa1d2ea35927e1030b0a70921842374fe8cfbe1379c0d23c06024954fd4b4b77c98c8ef93beb96c6b165aa1669d32a0897eb705a9031f9636fc9ed8e98610a24ea878b8349198945285005435485833e707b3a91bf6907506f119aa4da0503c5dc7baee6e855ba98c7cc33abae0e23dae57cb8654e1e90fcbaa1ca35697a25061d225ba2b626699b4802515fdf271f324a3af9dac3fceeab0339bfbbf00934912ab1c05f80cfbfae102cd39c978437c61b17d391788a0b0613b86b51d8f5079a32f8498224025e835077f57ff1f055af2846245427d4cb4fd97e6c526a9d7c417c0f6e051b2e1d3520a45b6865bf53b05dfacaddc4a39ab1ac06657ae2fa80ffd19003e2448de43cef866a44d59b0e211264338bca0bc480308fee2ff9950660a2813029a85836ebc758abecd548fc96c020eefd2ae1ef93435cd692b26b72e3ec803eefaa7b8a908bcfa74e939ba82f50a49a1c4e45ef0b6b610f37911f8d28d01f455cf17588d9db97c47780cefd4d32be7c9a4309d31fa2710d4d0bb3c847e8b43cbae682a2974c01ad8fc5563954ec75094bf3f4e55e28728bc425160f4e9621a3a41486dc4c641c08ba3bf170b715d486e355d5059277007297c7a8dda904aab666a411a92a8a88e7314819cda8089653c38ac789fa7e1dfa0bcae9a9aa3eacf03368ca0f59a47e94af0b09a564602734b3e768e48e6b05eaf7be03586a5fa03c73121085295397903994b3c0238fad942ffa17bca3a774abdddc278de187079b60e00a4c775409e3b61dbf5a59b02df8b77ed1fb2ed8041dbf88f9028e36c78b20037a5d2bf60b1d8f58638e3c743289260a5bfcae7946951cd640be6cb80612796f746cdd76977522c4126101d3f0bb0b1f94bcbc9728cab904397719205ed21ee1ac9409052ed54e3e46cf391009956f1884a89c7f0c2b4dce98a5419cb78067dd7a1822b46777dd07945d68d4d7d34698a1a3f7ca2c4998835212e4ad403fdae85a02c45e226b8318abcff5b791182b64c1c90b118d9c29d91dc147d5818b3681154d32d3b33ff8e56ac2192d4052527cf7e8566b489135c78286ae6ac87a295df5d6561a9eeb3038836b58f8a563643afa1680440925d5398883f10508741be320ac6c58d230f8eeaf63140d6c60ac900d24f5c6b5b60f6d813edb94c991f5676157320f3db6fd33e2a8ab87e92f7f7c7718fb507399a85adafe3942f8267216486910f6787ad1b455993c05fb075a0fb6f048d01a502d8b9da96b3752356a944339ceded31007ea022e0d4796471fe2661040587232758e46d6714f81fa53883bcf0ea5590a9ec9e7c4b94a6ec399aad3b81f60e8a2a07f924efc52701ac53eb8e25718c301e16a373b10cd997f7a2ecce6f270ec04dd4c27a2c5636b6b20889e4e6911108764a8e48c2739d83a4e8e66f95a9121899625efaba6cd348aba1fe5b60ec1d6bd2803cb5eac75efab6472a9bddfb6453bc98dadc6c246a1152484c31352cd7785baa371a8785cf59f64fb0e840acc2dd9de1a64d17903e5cc707fc986271dbdba632caf479829eeaa6708945d4003ced1017b4769ff7038f83f32d21b67a3ee778fa1a5d2ebd33776dd796da8466ee68d07f35ee4107b61f00bed982f94d8069451b9b042e78e5ac365fc4816c2c9923ed63c483c7d639aa16e7ad4fbcb8354f748bc3bb67a5bafe70cb48ac175ddd9f9c6d86d58e0911e9bb5f7e9d598012f3135733a0c8a9106358d429ad64603bbf6c57c5d0a3a391c591dda9168bd1feae8de23640a41f1d7d9cee48798e21d0fb4a8d7cd8d7652d991a246b6d57d338d7f965d7e4683f0ae48eccecf0a475245f9f33bad5ec4c688943553a0f94b496de195b5eea86adad1adc0afc65dda9f70e43d853a184df9eed774a322a97d8d1b82304263067b17a5d50928baa384fae2bc007929c22c05bb74e3c7435330aec68df4a40e9622462881a9fa160a6e9493aaf00fc665c2baf1eca494086ee05b59cc74e4cfd91dd0818fcea0f53dbb50b75965b402dbd1e82664a592af2089980799ac343ec0b70c36754b9f7c82d237008b46994e8be4c6a00b545bd1186e370dad3e398e61abf20f980dd4eedf53003f9d3307b30ea7105590a29d2fe55e02388339be7d0cb8a243fd572bb4197e5fc5f5b912a69f09b6a5294848bdd19a652da4fd5c638d9d7879c04bdd441cca7a25a80da135373b5febeaec2f36b2fa4a33d143679e4eac89f15e2cf2ef34550c590c40426a854a627bd9c5ffa2c85cd2e43423ae40c1764a6b07acfe6be5040cc3477250b9fa725f4382e57e0ee2babe440e36434ab19b0ec2f001cbcf821788c2a02e8b2a23b525a7a7f01cfced901640d87c3a48bac72169d92d2c178fbc4881c1d8e2a9f1f411bbb578950b6c5b34af6013cc16af496938044b983981a97ef8031371ae8f028eef7d649f4a0560e70153ff6ccbb72c807b1f39e473de24b6d27d7b6808376b7553223fdc63ed22eaaa595c26e9f3ecb30fc6c9e1586a14773bdeaf2da5c6003e783ec65dfc25bcf354afb64368e9c538d3708e5dc635e2b62ba7a9f62344331510b7652f60e04fa399fe5723935d44d6cb78be7ebe96b57e7dd384d61e2b3cbfcd739dd13ee46959a537091d60b373acef04a3889286789287b060ed76d189fee6708c5f8f1af9119ca241f6b934f0b9a78d487f72912d943ee74fdf7267f2670e6ecc8bee4c2ace3dc3d6f61e3de2e92d993450d10cd5e29ac7e91c0f47c4e6b142258e075356271a64b122348e072762ada3f11899d5b71c8c0680a6b61aa142de67025b57640e35c577d937953d1791e1d34ec1529e7ec01535b875f87417cf4194e36843f664d5c7f72aa31765900be30d760fdad5245d4696d35a6cc05ea853173e50fac202a4e2d903b3d876b34f6ba09ce6eda810b6e5e0d47a664072d09967c18f71f37917aeb9e47cd1c5d02f5da2c0618aeba171719a03ceac7f94aeac2f10363f09a5cb8a3240703d1b6afe0d3ea0d00a72bee9acff19cbac28be12012a37d55b79fba3705763b75d16aac8209bd164771411b3ec96c0e7bfaaf604074e71336e1b60d8bb53801ae258c2d9659d9780514b9319fb8eef09bae972ceed2bfe91f7ce41c861b3c186be4119306f94d9b0a183ab0e0a0c20dd5e217cdecac65113f8a7c320e177544e6eee8b3ff4eb76ca1196eec3b722bd0a16ebefe705ef777ff4e86ed751c6a7f80562f1419b9e7dd01f7f9c0f7b919407316d824964ee2c14663b3c3b0602565dae13059336dd9afcfd9042c4af74abf25b5ad9e4bd49795ef3e01371a5e84084494823b8f93191d14a1c2b9d059be8169866222ab532b233f7a0aaf1613517cada50f71057d6880e118bdca0d8f6265ba1f8582faf97b1d04d8d85e26b1b22f3a501ab930aca7129a05aa7e8f4ab2d68110d0f9684cdac3af5332c753213deaa98a7f079eefce267cb69f7c67634c74eada140b30b3ed83a0d2f8ccf65e73d3259942d1c3dd5de409608612869a198e21c51598cb5b07d674daceb0df4a58640716e2e139fcfedf43da2de3a64a4ce6e7a8f672f3590a1a2cda3c2c4edcb1a885b09343439a15c62b11b26b44f4ad05935722fb4c98cdae873c9be541c207437ffbe2b7a80227b064572552f878e39f838734fde73ba21d8466f8d62c83321d354a10c3a6dbc81ae53c57bf03dee816b7de38c4144b98983e71d9d05fec4c08c53622a70f80c9b268928b659aa6cfd95fe6fa451d021789a9630a71f7c2b1d20e73624d3e7892591d9cae0654052e5caa40aa689c66b111f6e70ef4d98382a0e3123192eedaeb23de64a2f22e68081e533cb840c42db55de4a3e5646c9e0d7b3fb842f7a640dca6fee3abcbedb40f6ab311494961ee2e823189bf6d8aa91f46c333d9f384d3cd43ffbabfadefdf7a7e9a6f7baebf73a483ce68c775af34e846ae009318e83646edb920a31ecd4ff3bb0eaa9badfe6a1d26c66b86ee69e23c67abe4eef8638a6abac625605dda1229853cfc2c31fcc562179a6078db6a82a38e22c3cab143ecf1866d9fc41d5ce8cfbf1cef0eb67d989dc40836246e5e88331b479959983f4ec91d24061c0c88cb7f03c78a1b76e4f9303a2690f0308542bef979959e06f78a4152eca5f9899424b086320ad320025b893310c4c36aa0be34532d9f025a88b5e11e2b4b986b90c4e0511aa0e2c65d06de49d85bd1d7823cc819504f80b6327913e2b8b5aaa491829ec66d9b75ba5ddf5a6bb6ababc950d1046004fb04ffca53a79d8673d695468bb6cee9eed83d101e0cabce36add74ba5730ed7f04876e862fd07a2998c14a0bfe2c9d6d25bc8bb8873707e97197eaf78390a080744790bd61d5dece8360f156da94a3a61d225f68c92e2b0da4a59817bf7f81ddcd16f3a20d649f82cbd38e18637da7306f8968aca7de2c16072626fed7cfff047607001a7bdafcdb52cda29897aea74c59402564d11e9ea0edae44872ee60a8011867cc53fa38401594a3d38a32e060d84c0329b53e1d9a8190a9358f4863544efc945a1d737cd77f5c6e598605956b7c9211e4d8f880b2d8053511601d6289cef348e1f9727598a21a57f99e830d030a2db74ca7e0d1cfc621fc81a05087dedc0b7a3f4a302b63e5799e50d3d9de36534afd1d5e209d6756923916010f94fa44f079fd8f6e6f27645bb0abecf1eec911e1204f529db990528d435293524904cc5362a533d278ca267085ddd44ffcc2a0a023425dd41764b719cbe5b5c8989b40def1417caf775738ae660db10b4982064272a70aadeb92dc7720ca6dddf8625ab312058ced1922592bacd722d17566d4d8ef5212210a86c8c5910aaa06b43de1ea53aa011450c12e84bc58a1acf17b2a014a92eee2b8505288b880fcf8ddbfe7da413467a0a29635d3a6e4a9141bffafa63cdfb21d124df06b2aa82585ee1f178722d4de0931e88aeb9b0823ef4a4ad0bc04c97d02358404c8075ccb9bb71364352ac4a9223a55e009f548037d98f8c6f0d53715938b3fc607983a7990531605ff47322a511a7b7507eecf4889acbe8f2957dd5a2a53137b4ef3e920a2769834e23931f45f70321dc7a425b6b131a229a8c4d7c1087699c1814d751c7c806eb22fa120e07a3f7a59fdbf51c00494d1d9cc947b14ef3103aacfd51a0268469c76a628182e6b170dd8ce36f52b329f89543d85cf0d0c5b87ea24384f2242bcc35317d53e0a91c15d1c921657c05e1098611d2fda349760ac815b7c61d2da030e67aacd20358f54c255add543f22e5afee28bbeb969a661934590ecc1c3d8cd66633ed6207c7d8605a2c9d72bbf8fd6cb6652f37b51120e634c0a438938dfd68ddc941519e8545fea41fbcb2e65e77158f7bbce6c561a951b4ee6bbab3cdbb36ff2ff8e1048422aad5099f9617438ede1979361032887ff2ce2c2f28aa01f692116994dc05450f572ab435778731277000f48ae60288cb01609ca1ca60dbb48e35c1a85824934c9a7b8eede5408e3714b88fead02c511c162502bc4d0c8f33da4166c16acc1884336e123675460d171c33f20955c894bf05737a68e3081b5882f7441a2625daeef79ec96b244423a4f992628be30db48815a9dae2eecdab262f1f9c54df3603a419ed5fd8dd7e0353181c3035dfda84a06270e3db5c4e2a3ee695b2bf5391bb2008094dc4bf417547e0785c17ea56c1e7abbf5cafb40f9c428f8cb35370ab5092b38bd2b33cc88dbe85f7cfaff06771e4fe664cd89bda8f8a9e4695f4fbaa5b0bf148c6373dc77cebc0d8009c05031722303e7ff6e4f49660202ec20d6d6924d8b716364cc8ff60c837ad1086f484fcf64cf71f747bd0a72ab48b7c8ff61fc403adde3253fe6b6f8a726b20c9ab2b8efe03e6a22dcfe30f004b2cf5219f79fb881931be2dd5a5236b3bb3413e02548b28ad729b6e263c444c41d42d4162cf4e3c83e1c6985e84939a8c4c9f5995613fb353ea5f49acb808fb872f2f5d2382f451541b6b0eaa46057fae52c9d7ad15b2d2034ca8f82444098cd644d68c4d5003622b41cff80eaba989a54f1d9ee1be8515cd41caa27c85bd30875ef752e2e27d934f9f74d2d4eb94637968ef5a420a63676c83c942fe03f1dbd1b2aa608faa1a1093d9fde94e3e835ae1c40e29251a85e4ed40c2f5b7a2fcf62768650af7634c8153203024dd6d63c3d085c0a8ab720b66f022d1b9674dfc98e0ea5fdd854d48270b796c935102cc32ed0a389e79cb3fe3261537e741cfcb5209c5d4725161d2f4cb199737debea6b7497d5883567c00c967fa432b1fd511822a907ab5019e2d0289ce79d25561c95064a3e73bd54470bae829825cf1278dee01931314fb3ab93e573807ed7df3f655050ad51597e4d494aa55c08775be61c6c62ac7336454bad1bc8b9dcef3f6b8a88107f8c87dd0ac3c0d5372513f5887335905743d39cd66f20abde60bc0b96623dfec7c1d6c1962fa06495d9723946b1318609cbb7c87c1e952fe8f61beb352ab1f0b4b6cb14e970f48a730b69ff7be4afd9000572c6a83bf45168cb9948bebece7098e2b02e89b0e00141ca8e9e7517c3804c3f1d2233509100b5fb01138f8e50cde1414cb5d33fdaff786acd6f64854ff0d635bacff49aee8a62db2afdd05736e4ccd26ead9b99086bb046250c0de2a53b12a29e81b8f8241c33f737b506823c7259e9eb37ce7c50783ec24d858cf5503b8b044c962af1be529c79f2e1de78d64a728d02ec4e9360d7d69d5bbdd9a13e2a865e9cb6f9bf2c09a5bf98e7345747df37c335dea394143d2fec9091d3d3d237fdabbb4d21429ac60a0b83fa9db382dda7f0d444ecd5ac1009aec380b5a7b6264b9c4ad50b67575dac4a28e96686004f2371267be1cac849ac5b900cc51370d5d6aa11aab3d73dc102d91f329a5e94a60cca5740a9e02531d35e7231558b28fc6455d11b6b3e88dd9b8a59160dd646746125cdae8f19ccb41a47d33083e93073e67ab23d4a04f5c2f76d4b02340183720f52439083195a2964f8b661b7fd05146c1c6f783896e3b5cbf64a24aca407f3791dcf76103bf47343720029dbe239d897bb2d66d766a8ab1710ce4a1ca111d11e17ab3f29168f315d41338845bbe3ed30f5c75a0406c1d3755155a9860511bb05e8b5410dbd6836f0429687d10ae29b2171d0c2b8be71c06322ddee6cad1b6b6b3593a77a724184499a59a00198b83e1ea944ae574f00753d64191bb00d69db13db487946f03d97a9aee4b3ec6e105a0c771062349ee4d32acb30cadac76d5c68b00b26e956528f2d474a188a03489aa88744fd630f0c889b512bc993046919a97480e96ba2dd6525bfd567f95c5588e14d5c2c540393d7e11c9438e07e00141700610229138e94f92980321ba75df15de13b17d10e4d5947122e217d488590ba802142d1069ba847f060bfd6de1bcf10cce23a22515b86c6ca7f037aae88cecb0e252c5d76c113b07eb5a463ca95028861a0890bc3bd228cb77efd30b68fc8b134492b42b5a16b0b292a3ba2247d457844ba775fcefb05bdd7771fb79f40bb60f48de308a953c093a5b3986c06e0f0ca3785e0060295a59529e69007c7a688d815deb50230adfc90c3ed1df4a9f65e27c05a7272ba58f5a9165cfdf07119fcc228e0f5a32eda758fc690ef6a65b7b887b584bfbf54e7fb559202c7a6fc628c82cba006ea866cf288c7d4990c4ad44b8242bbf80f3d13658f4f1f8397349b61ae4dd616dc24d0fb3fd0df0e267c2409806439d14807a0ac4ebfb84803c3cd0d92b0ba2495fa4f8489ce8057625be66fd40cc99539c98f7849193aab82767fd2b4badcdf70d57dd86b0f670d89c24a97da7eaf510b6a73a95592b287824eb7cf21563f0f8630f767e80c3b04c202ee36580fee19fa80abc78dd28017a134093722db8b5aa122173ed4d1eb0765605bda2e82347487c78e065a20c52862cab7d059dff69c5f01ee140330163df3fbc36f989f9dfb39868fa608cd0dcf17b9e3bbe44b4bb31b790bfdee40d8f62d1c6a9e8674ab6d0bf11c151d4dc4808ced08fc03094f0edf5f73123f877967921b0529148db8f49180049836fed2ff509ab28b58de46010ecd1603680f0a687626ff97a5ffc01f63081d6063f69385b5c8b40c0c68c1efd500410a4292106afc743ae5b054936ccab21c7946f899678d57c8ea324d84228c2ca0b24b7fbf3354bc8d5697571ce0c47744492a2e906aaefa9bd2ac2084e205dd58e25d5427ae63f65c905c2b7c3c6abe82e8380334204dbdb66c32722f645b8d0e054d27abcd5773280234feeb8c7fd907c568dedd247c2bed67d547dd6fc58faa6486f50f4da612bbd9cd68c4d0b24ce2df10a2eecd4183753131eb191859768ecef0c32a5f9e26c8e85b068c9a922bfa9e216304d37c2c49984d16450e0d2584440f91edaa6ae7e6e7abb661f436758f067a9f0f43ca9b82c4edb5583aef9da02a6d0f520c3655db6916cfd8a3d8de73cb6618ae56ffdc2e16de5e4b3c86881d48934b73db6b47f144e2d42659034479b1b398fa2ad90ecf6bdf22c923de9e304070793b4d32ba7f4f05535aeb3a0af4fe3c90442323b331a5416dcbea2edc590ea359fbaa8982e73e28485e86401edc51b72560afee7c4d79f87d7e6e1703d360707fc01f17f8a23bc24e98d19d9f37fe1d19ddc2754123e878ba26547402e9367359d40ef916bc289f36a5b63bdf336a63f4e23f211a3cd0afa6763ce09237066874ccc77ddcdde214e406275aec9eecc7c85ecd666d54ff08a508af33c958cb1086f0b63ad85815eab4617d34a71f486d835602504ab82ba172b559755e6a200fe09e25d55b12d49ab4db4f4f5d134688b22e755a7f75d6316f4edcd88f87dcb8a6bcc9eaddd31d9508289271d64c956743aff3f6666f80b7774d44f5d6b35f10c31f47f6a420450c0ba0f235c80f6b5078dc5ea1abce0cb0144cf60f5634e6c24cdea5f4140b581448b6c70950995fbb5d96499dec3c12dd1260f26c81e98ce7a6dcc40398b9d1efc62c46908768c6ce60b04be82c2510f5411ac9898bcc04f469e842ab79b2abfc0aa369e9d993f37457a2adaedfcd84f52a127b854b038b174e6fabd668ec33cd8540aff6c73381732d54b5bcb6ceb2ef10336390e0747247032da9db6b275f196bf65f80d0d1eb6d06713bbab48bcef4cf78011abaca99c0df1f237ddf34a5e09a75fe1563e09425e2e4291d50bfcf6b85dd25fdd9d0174f9e654440e991296c8c395ac6bdf03d54827a437cdf8e61b7995adb6f1d5cacfe2faeaa368be7d37036b4d40fd91900ad7ea668fc0e614417bb16e62111cf5be8ccfd95a17d877a6c900fae797fa3b6162824adedf38dd59cfa949e797cf8b8bc5369bd3ab017d2cbb95fd6637117c08582a0cbc17ffefb5307a512ac322d9888ba36bf4d8928241cf69e0f866146accac95aa59a7e06115f5db1c732e7198d5ee86186709000915a5c78030966bd95c6e53e079ebff20f65f7bdadae2348880900c1229433ec0c5ce1f22c7302a32cbe860549dbb89890f917ac4141fdcb2900eb0f840f1bc1d8e083e5d9dbd3b38a12338345581e53068a07be6a1bc605617b87986124952ced9c7d199b4eaccb366dd4338b70248db90936bada8a417ae357cf54bd41e70fdce12f05eb40b47bb8bb066a3e7b3bafe7aa82e1c32f14ec3876d9f5e0b54e66fc603929bafeaa0799547265e800859f28a0671ab0c8588b015dfc2a4149d09dc8ed197e74a58fbd597ce28b43d56d8a126e508db508dc28b8da17a6880368dd884c0d1276cb9fdfaa549ba4096d30b58c41ad1338387b3479b791627ffcd9c542a65ba49232d7f94ef54d18c3fc60c29d0187e228387598f15337b64bef3f3133e8bc367a01df3e65efd14c8373c245195380ac2cb2b8760b8278470c4b1bfb75fcd9e523f5a69d9d962b4695b5f659afe6d24dbb26a0b67b857083f7f0f718a0110eb879fff0c79a80e5f72c13b64e8e206a4b36259d14fa31cf01a80617e5deb4ef092503ee1a01ad90e7115ef89ba7a92c55196d0509b6c6c15918d738fc1326da169974f6b0da7b77da8ca462181b27d75157b757490457220a7c7e93d31862e1230c578f8f11538a54148ac72338db3c11c6e494345f7bbd3ba0a486f151bb72402f641e321251c08b82a2bccfbd4d8d93204752583dddc8fb36dea1a80fda6693d38b3489ac43440f55b8337d5b3d8412ea35480cab494dd2cc3a8bfd913492750a35ea78a25bae3221590a8d5a8e054e53c9e926120c63daed779ca354b86dbdd5d09ed5fcabdfce30c9a53329e8517715ffb89d3a89a331d37ce70673158cc04e5b75f43be68d78ddf9e63b8b35435bc3812844648c36b4a836601cbad9bd754cc0f875158a627e48f6f316538fb309532b7fbc1a3051b2bc7c9bad1889397415ebdf556be1c587513ad8b04aa66e5dccfb36bc57e03853f52e73bf1b4aeedafadf7756fe07ce66fcc8a14cd8af03069a0e5e6135045f0f8830b3cd3e2e5f23b91378af1b2a22c5b4340fac8db4456a1b165d76975caf3d4c263abeff92b6ee9dd9cc379e8321258ce4322bee5b7bee0ec05357568db17dbf4df684a239ad0b678c40147e73faf5ddf2440e92142682ba82b54297ff48f1a8839dc62cd524a62e932e39d0eb2cc7db4254f210a70f80640df0aabcea7beedc496baa5f87d2a3be20124f456a1262990e93d1e850e0568ed0354f4128424504d600334278146ffc052846424e6ebb233bdb1c561709b182ec7a67e371eaefc4a09c650d7785c588455d3e5c6f2f0cf70799278a685419eda16fa0adc03883ecb9d71f53d3a353038b29fb48fd6c4c804b09e8be4de9f0749e18fc80065694ec1662cf44de97f2fe4fa9fd0cc32b04279c3b1a3bbb18924c98b524a55a7c5f4053bb65713d07dbcf74182e8fa8a7cb1291209a58deb47997b5fb5f281f6028515af21904215cab456e90c004aceac3e2a1757b8a8963d9a271a80e1856533c3844253679cc8f495dda6addbc98d8d8f0b1903b797e6f8d6736902e535e5d7084de8b98a98a265d60f091a0ff8f0415c654877ded29c9eeb95b9aa26abb6c7a21076ac8db903f358e94ce38b0adbe7f61714fa8c028340bcf92b80126181f30a082d88ac0a07c42fa4435ee0dee6fc6917dc0a0ad0db573c024d1ab868d72e876b0e428624964c952ef79fef55f85355821db4fe1e1136dacd26825abeef7971ec42509da3370ea5ff31971d5590e03de35096ccad299602a55047c8ab3485d41563196c5b4d3880ab605c73eb5eb8165ff5ee5473820e93e46d42cc71f700982a32ecf64ff1a565e58ae1a4649dfab17096718e6ff5df6dc059e9c65c4538072336a6ee1ab29d9138d017da1971335e8a71a433f6d13781bea4c80279d2656c0fae2b011198cfa13b0989e228fe2a8c29061d85155d69b51814235b03427276ee228c79a9ff8a3005e3260a942392a9b62ac89181456c40e9665a906e6ea42ea99d4a632c67f6c7958b10662b01541fa53b2e865f3641515d2a685d408db977496d8a610f8977abfbdd27d941c2add24edb67d0d86a7304cdb9637b75f1a054d228c600ff5466a4df03cf5a2b53c367050e8e7179be9e76e8946b9c3917d146c43a78af0756011af07245aa3d74c84752f9b0d08024c532b077221ee8e695d66e572a66042e65d47a505dca98578c8adb02f7d1c2a94c83f459d58f5ed936a9274805dc4ec5d29788edb8b6818d3108f0b73f733a623b08c15e176e8a40cc179e8371f04a55418fc081e5a9e9d2dec90b69cfb0ede5be668284e337c7a6cbc3209698fa366c5c413e3bc0b199c31409c729abef337ee7073b9b1e529d3ae0418054371e9da6979973be3c56b36e12c85374fe238865cfcb55e5f30ba80ef00d2bfc2c79022c8fcc31cb137c6a878f9969921d604ae98899e9d519c75d95171073f12adf00a2ae17d0940407ba4cc0cee2bc82ef564a87d5b0701df35e417cb9a113ced67f0af049aa5953c3aaa3bd40a5a8d56c8280c0b12d4f0a3ffaafae3503637c889eda78e7faebe83bb2b7c353ac04ad8f36c3d4e587c5ec1e0d63c2484b0aab8b297ccddaa1987d96be1209facf100166d11a7d17203d6950cf1cb3bef2ef2d4039120464f7f828f3f7bb99bf82d170ffc320f5f5bda400fc6a7f300e446033bc5f7ebbd4217d853f379fe1b197a3e1b3e02166f4d54394fd3a014b1ef6f3eeaed1cf8a538051b192df38f161a1afda14768b792c609e0b612c2826995414413f65cd5c6f827e922e8b8d5cdf5016dc62db320a212aac3d02a4c3cbd86b6a4381d27be74b4b718502e89886aa485784f20d6eb07a878886e2ced02a9f34d42016b8114d55eb0ce2efe413d6f0336ad4294fa6683acfcdb79520688fd7a2db9fcb9f3e430a24b3ef359467b858b3ac4aae79ec836c62184c2d666d2b1dc3ccc21db6dfcf566689f87e5872e7938524312c563545c8c7c187124f3dd1d4bbcccb0cb654d32efe785d4afa96f5a6ff9879ad1f93bea579049e46edab020ab9e30a9e8e9be68f76e2bc02c51b24328eb2a6d0a3bcce9e4625b0a9bab52b203b50fceeb063d898cf3184f400447443eda016f1874631edd5311134d726608a4523e091b7b8b7eedb22d9826274cf4700aef3f177196bfc1f92e1042be2439c77b4bbc1dee8e5ca28a69448a9014a1a9fd2d5d14b3103bd7cee397fa9d4e34f097f3491a49d50a5fe66e00e92942740839994ff9a88db1c00b8e28102f61d2e0a37e228424a33e8cb64024d34a8de220cfd2c51ba0091c2a227dc84714a60f0f9e4a0fc04cc852542216c5a756e33c914e18e3a297556ac19ad2d796e633de97daa53ed0d66ebb8153f8cd2fd01b197f9c8f3bf89805c694edf192fd134eb942f37820971df1bf096eddbe609563e7637891ef1ffd8c1f557afbaadc7de1cf4545647ce41e51444591b072431c4ec6cf094c2716c365ed2498a81a44f4f10314b15927dfea8c012dc089549f11800b76680a4dd946003ade35ac309a4c420a7517cb1399d5f8cfd91ce8e8d92dcd680b66e6dde5902a4f86df016007d489413689c72c2d4088f5535aadd953295be45b2edf2282593b14f9e77cdd4af04c2d7473b1d3b02ddf76169695ba6320271a1e0d33a00f50c024622c7f6010ece88e03e0e238af667af9d72582dd973e84bc5477593c5611cde8d79285b41c7096313bdb1431520acdae2c1368a2fa5fc7e2012f1d23d355c2bbd319471b77a22844af1566f668bd54b52b4500bd8887a037a843b747bd46dc97689bb32b00fdc518add482328b30461954db7edd1b158a3a2d97caa11059a1bf397ff81b971bd24e8ad96067edffbfa3093d7e9f34639eb5551f3d6e9bc1743d8d6f98a66c9311a14a86f761171f931200ce45d62c34341ff4f677a24b563309b3441b799c2d66b755ed84c571ac1a1747a8e2d460ae239814c142b6ef7d0f1328e11b620b956b5c5996372b9305d001ff4bbf6197fbe40f62d19396234191ad09cd27dcfa0a1410ece3a7355b4e59a6ec71da467360f0a80b9a47fb212dda2a3b2823822511289a69f3a48f6b913207d55a2735a07333f283287b4177c55d1a309be5287b23b94b4f30597ae7a843797dfc04d9d32f3826138f772116631bcdc1f0f252214c0be07a269d9f92e09071221d12e2f4df8e846d6265f78dcf95a07a6a66b2e054cb1f401ad7abdf81bc410532741465850b06d00a282c81561daac2a7945894d2e9ddb80ec7e84dab9c9444ec9a48aeb0bee07eecfb87b305762aefe45e613a62b2e1b5cd2125b945bf346aedb4f1dcb01ff20a70b9d55d445464330a0365ca78ef64c280c25e0f2dfd1f90e9b3dfb8255db412b2793cf91a914d66ee574d8c5481275f2ffc0bd20907ed232e40cf572f650f3b9b20df3c1da05cc511eb1cafc01f3460520d59540608d83bee506c9d49c5dae91f91cd4bf6af4e7ba7ca1913e0e3d22f3fed6f9fba77096a4bfcd09b47f26f1ff64785634666c682e0a2113af42955a70d68095e9567d8d65a7af37ef9d705ad91428222b88276c01a82e425c044cceb2e4d950d3109d1d1f0497bfa5308782de55e93648329c06aa7c4d0216142a4371d0ca5e10e08afc4eda47d343c37b63dd056e5202e3d397c0d212e66a5f1d50406d8c0eb047a8727d7aa0a6f5c24f27e3be894a262862960318f1e3b8ba8a44433f13932945e0108d3ff43439f5743501b415c76d031acc351ca63299f8987ed37e74d7b5365d9057d7fc72a5f8baaaf0b107b854887b09cf2a1c25a684211017a66506fdcacdf4067505129a0c93cdf33143f0cc6615644217bf6c9e21138174877b948dfba3fbef1ab9e99d5a1fdd4493b98040f186aedfef02e1be02e6ee091b958ce8cb0165eaf629331622a5c9705475faced7e17483e220dfa71cf2ae6b04bcf9ba76ad7f2fd8a07d23a8dac6a99ba8bfc929b403f86c64991af57d8c68d8c820645189038691069634454286100704555d647db9828d0007fe4409c9c35e1cb0fa283519dbd3bed45025b60a8e83c487025fca91d8e3e3d828d9a182ff331ebf1bf5a7244fe1edbbe172ea0af4ffa4445a91d168896e42b9f108de91866970c31b6d4d496e00d6f321c933781981aab303bddd364c6ee14978f6dfb448cb4882843516417bbcb6abb0d800d812d2bbdea9d3863af8d9e6af982d0f4e95a1d53ea25534bf23080f6077ca0a2579a5a810dd8615d6ed065d0981a13d10e0215410049c4f949dfc343736edaad8a42d443d0b0ef5b0a342564da2959dcae5d02014c8de1b16f15c0c4db6129e6bc1c1ae74efc756d3d74aa2eadf1236ba95ac256450dcbd78111bc9e38c0aa0c989f6c0d11169ce76ad9f1603eda75de1a7994705748b07e2fe33f707576c80983a3ab82d9235e63dcee29eace753bd8d2e766cb8966be84d9350bc082cb4f71db2e50c1912acf8766193de087a5cb51ae7897a423429b350e314fb57d0fdf3b7419d72c257df3587c919b6dec98ef14278a6c0eecdaebf830875e591f4aa98d9b15c99aff07071b1a98938496a230159b9bcb091b064d44276ac168268246ec19bd67d56453181b12e453ce92666d5ec0b18008d0f925f8188354108fa508834cfec3f84fb836fd40b3b6ca1d7915beb26c88ea44fc9c7de840d8d65cb149ac6bc1655923cb48c449a36e94c256ab6baad13070991588e4e61aba968630df9cf5783a7a0991a8593f0fc7f9fa01769feebb28e8dcdcc77b10a795b0650b956a94597120825018daaab3023cf6091bf7a9cb98ac96078f008731512a3caacf61e5f764d8a57acf0ee61661527361ead048be13be85ad95733129ab05e4d521a1da81f08107e2bfe8bd92533c9d8a756ecdf5b6b9619430b0fb5e4684d0260048bba35ef5daf623938731956b3eacf37ddcd8e268e3bc5351aa6b85367d7da0c0cf37fef0cac309182b6571fdb08775d887e75489865b6380c599551204a0a21e51e7cec8299a31180f4158b573c5cb6d3a8a3bd61f668c36f7337443d231cc60778b249ed011f3c5ac38142cb3e46fc604d40d33084180a7e4b128d0b5c89e25c439179318c088359b3777d2c4443159057c6c5043471bdde99710b04c10999538670a290935cbabc7a2129441b426c046d33421a35e9168b8d4b1b1c6ced3adaecf038539611e5a92bb4657cb937e775325d2e0b5953b448e7b9cbe586af04d7c1aa4442e8813ee399c5fa3a9f58ba7fdc6865bd27df63692294d041a158343aa41f4686de6c3e92630fd906b4c3b16cceb174e2ea7e58ebd7447d3a3d11dc5cff66820d6a0c7364092aa0be5bf0f8d6923bab94fe830956799e47c1c430c9bb6b6dfc9a649ec90baa78b2b359b288af9334259a3bd8c3437ed7c884fb94a0e5eb7ac86471d57f865326cb15618681198e001ac8822833ea83b2095fea41c8af99be51ad2c97308e88facd973845286a98a592e86f5b93f2a6bbcb72ccbe03c7c21009ed392c86cb1f97b056bad56aede49fe6489ad9dff61d489f59571c88fb64a6d7c2019ae3e980265cb43a44e8da2111a8258140c31e93c5d14503913a705a1c1e81edfa348e06d9c28b4dda02d98185868145cc43d72187082c388ace7e19ee9e2b30f4f18f25c9545830235b46ed5838ed0b2b8193b8058cc0bf5abe9b3733a735e2e61ad6a11e435ea32f77530455aa65c06be6d1c74b9e9d385d4be1e41856f62df0cff507ef5f99717c8c98ee151f72a828472a17e73b66c303054cab0965aca620beb0a43996cd91427081d585376c4f04f58e5f74387aca95daaeb2130dbc08acb4d9b81a4f98eeeed61c050bbc0e59d0a18f9927bc5170e403da59663b295e98a1797e5434df7d8cc39f785b7492fb31a65b4ef8b791f26acc252111837b448fef81b9bf0e6d24b9fd718abc11dc1bbb103a5643d45d504b467364907c7186df40c585352abf72519e8c73abc055a8e44e4d0681cd89dcad907254e84ce83b718a1b643a6b564004b9eb36b7340e834a08ad0caecb1f2576c400be6034647b248d2bd3f8a7c6b037034edf8fbeff6c3bd04f3e952fa3d0bd93673bc332b1abaa31b2ac2792fb742fbfc6d477c02204423ea1dd55eb3a0e9acedbed6f182dc80747f488a4d9cccd280f6355226e6e0473f3805489e77c3ac8b832401011f97b6283996d347e97f98d8d639e1142626365a3f186eca5da5a39712ac1ff366e63f74e8f5c4e13f40915f3e1fee2add369bb880ea668564c2d1748035a13c14f42f65c88732a26859a8fcae53f0d84c593fc8d9754df6639d539cb612b90e9ebcb9b0909caf258aa70fccddcefdfb7e12bbe4d9662936922e31bb927817be35362efaafff252f493f97580725810213b3af048ed0b1089729f1705dc2c1572a9060e1314454b57bad6f3505cbbea99fd98490fb88dbaa56ff2221f6faee10835f6e4584e8152668d1715677ec9c70bac658c2dbae6a9a8f01e6ba59b85df1cc63c0c893e04faf53af156a76bf77c707478cc177b71e5f90f9cb422f1428467b6a7c812ac44e81a38c9cdf192c85cb74c727bb016f9e40385c5114e99bc48d5cc0fa09cd763a9d80b5647ba643b0d85d1e288954c35328f1647bae4a7915db438f2f8e3f6d2aa88718ffcaa62af6cad51d435dff35f2d98c61ed1ee68399e8afdbb60aec14c7baa63ef8c38b03110d8fb44b1c5e9b293cd10f5bb0c7c3973f7ca907fdbd72ff83ff35011d0d1029a63110d1702f9d7e61827adddc5b1068d4a3879c252e494d88c7c0e1a77a7df12934e405e00f4e2145990404c44e284bed917c65a083982e55463d73ee058051ed2b5260c501812236ed8137268cfddf25e5ec40b74cacb8c2684c0df7a19fdd7df1346813994b61fb52800d5cdc878571b448da9320894a8269813e96b19fd3ae5a76a4990fa817caff7b9521724243f889eaac25cc377d6df64c9e501d8d44b30f71aba685f85b1ae9857a23d133cb47196b807d4ebb8766936c28bd58d5acad1ceb31cdb59a6826f25cf866d430c3b34af96d174df7a6dfc252cbb0dcf5fc15946a3b3253380be242e3e40079cd26d11c9e730ed48043047f81bca6523027f88a364ecd66b2c083a3dc3139907225dc66263da3513e49bef5ae844c9e4ba4abd3a2ef82f0c31bbbdff516f9d879bba8a8ce59133464d5043e1b1101a552c9f29661e6cc3031b478bd4e1bf7fac6b79e6c09125ce59988a7d1c1b7c278ac13b79f275fe53c8675a7509e6bd4ab87674206cedde3e9af682da4c76bc8b33292013c4ec41e5cf0e71b5becfb528190b58832fdcdee718987cb6ab679bff3d31809e48628a7269abf99e4ec376cdba18aadb642c990f12d3a017e0d26c617db836d2d0296a36cd4fc189050713c7bd7963750bf1059b73b1614aafae80bd0c6e2552abbfb352a34f2639499d226177b22adfa30429c14dd992354800c4b451a374f55490bd6d02d03663f3f0da91fb52c671634ceafb7b7f3e7499c3699c130f75afedc1ddee42e5940f73ce5463f96b857f0073f31476dcc42929adeeacf672f9325ba53c189fe2ebc162efc1a8478fdcd805796455cedf8ed31e87b932b751b006a33246cb2beb94ebe44a9257a5983fd1a9d9f317d3dd10bda11438323283335bc746ed4bb74f4e3bb98d559d000d490ec843cfbdd7587557d462f09ed0620f52c5c6fff7c54e4d593c3341f68405791c1e9b01ca233f029263ce65ea386b180f1e7a9cc5eee69154479bd017484f03269e4cd7f60226e2801227012f713d6abea192cfa6089383c856b4ccbc3c3e3845a507a5051dd9be7c885138d7a1dee1dd6afda4d84aec3b7fbc31c6232af11234b3a0c95c4e4a4e5cad9b56b8b325d69c257a037f38d293feb77a59c1102504f5040612f6a96cd6bc5ea000a626249aa85d0b0fd854c68217e9db8b6e0b1fe833d13f5fbbd6b0788e64961dca7c6a9a362aaa58d508313cc5fb368dbb57f48d9921633a92256bf49a13e4c00369f7dc4566a66f46732945a49baa75198abc50e170373ce3a381cb3bad4b040285654572e6c8213e2d2b8b4407160d4c17695a5d5d9d653b16a12e39ba490ef49ca9c075f2e01c701f725a5198095803ef4601ec5432026c8ed9d33dc38ba021458c24323bfc2345e006b5b029b0434f28e04280ed1443058f53228aaa314cfd1918c2abe80c4aae3f5582bef8576e4ca7a78912fdf9be2ac9d690852cd504e07e59c8faf35bca2a785417339674292cb5a19659a8a98ce9641c48c35dc831bf61d24b09c78c2b67abfade50ef405c288b036d6e4cac9c1271411af959235f602dc3e4e7e882406110f4e47555b44d04e788956e33439d81f33e5c318e1c156e148c10e003d6008641c26d0593cee1282e5acf7dcc4eccee4ed4b36b48ab3ed1b274046a83a5f102f808aa17062dec3324a1e1e6d415ee1e2257f3f93400cb5a6efc1bcfc517024fef04e0a95b3da94d40aab810f24943854a10dfb89b9cf9d0d10fb68a61085800ba14581100af53c3c326fb103c3c9ff012d91db2d44c31579f29f522175a470c89e8adc62bc1a57113839711395c94188003edf748e477550387d636b3f04debf1d65c1974b39c75202235b2ce9e5c5743148224632df292b88bae45c77ccde542c9ca16864ebfae169e04da5a365b1714c72460d4d4203e9385ac86be04c99b090bd2a071e28570b2f71a360324c0357adbd7fcebc8d65c1693c74956ea85bf6e7d823c0268c84ce6a57c7b48e23205e15bd2a68f43606ef4e8d3fc2a1fce594df950c95717af73c00c845b10e3e2fd1d168bedd362759654d113902de61c25859292b152529cfa200dfdaf6161dd96585be5a6dd9ec6e5decfcbbc5f78b99b18b9481fc8db9327b1a384991109d01a804f38756aba10baa0324c6487e339fe2b0db6acdc1096c1051cb303af0c8278869ad1439702bca63293634ddac1856f0147b082fe6332ecad08829f34a72cbcf969c5a24cb1dca073bde74e0cfd183631dbdb1870c0ffaa61d82f80de0c6c4d616a3117574a82809c06a4883ca63e0314342550efc395355540dd8bb8e49c844818784274bfd86465350a8987586625e41bcff984f6edbb440f1ceb42edf8c759aa184f3ee9fd0f06fa6769f98062978f7438d36e72e55d9ab190ef09b27037e477193157ae7b8cf9e808c3bfab668ec1acaf224cf21a41ae7068a34c2bc22a518129f7794f966369dbaf0984c3b4f88d070ca32d4b988c3a18d7bef087233d6ec03cf20d768d41c5e1eca012e434aa1412d08026a5de46c24cc370f8d387030657ef46d4e6744f342070c77771be046210bda3e075d27a4626f16e6a87afb45c95c524aa536f00ae2782aa0915cf5e3bb038159038a58ba5d1824cb04a237d7a94a842d3bd075a37770c7edf0dd11b20a17fb12c05a8223278d57788109a721b8052b0d3cbed9eac8c48e4ffc83e97bff6a9b184118e2c09169e79e16881127df462fbb4f581099a6031e7d8380b9f5499640dbb1f1a445d02d3e9450f96f9c8a5b43eb4e3205527da9fbc799eb5597bd8c761808add79c2e59d0a2161e02f60bcb96d2013f78d97a519f5be94a7827ddae8f6af915671ae50716b64098a2d9b0e309d7158b269248dafcf3666c47cb08d52854803e6e20ad4173e1d7a683d63b9b487204bce22a2f18a2ab87f0a44fc846a3e4c728c2691caa226263b1fcd6a821e279269d0e38ffd30d852947008a180bd1ab7e431a8fc83585c8d8968ee6fb2d6daa3f695837eb558064ce81d3e4f23362c7a30b8def0e1cad6b527ada0df038ed347461d956e7fcd60a7c98bd36b3021513a403c8148f181c03d8fc3f04cdd2b8f8e4124121c408f9f8cc945ef9169c0c8bf072c6826823242e077f2325d6dd0f5de852dd2af1fcfe123cefd014de7237839ef4ae393752bfc43bc6ef06a2339046561c81a5026660293186a703631fe24a76b13323b1509dcd7be0ae1cf6c6922f8013756e8d71108f02ac42473f21f80d70e710e3953f5f1690e22bbb3b8594837409e3eb7519699ede13d5ca6b0aa33765c198d4c0180b2cfbd743afc36777a346276e9fd27c0fc58e10dbdadf3cd45540204d718cd52f8d87313d44fe9b6e9993e519127981878a32203437695f21a5d421d01a8a5c68de7c23042494758ef5d344ca8c3d063d4cb9a570e736ec3e824f575e5d59093de70b271359c5491b5997d2825a5af0112b89a96897d93dccb15ecfeb0488b83d0f731cda2e920e388728daea48b29a32b1adf517079f3345fb296e47365df70aa9598a735e317e060f8a9eeb5c2bdaa2372c3bf5bb2fec4059703a62a0185f0cfa94cf734cd26ed49c06f7a2149d0e7eaa628f588e5d5afc74815b24c04d3e0d306e0ee0a4954f2290d94e7163d5722252b18561f1f5c1476d6b1d75d000c0cf8de0aef25ba24d976d7a7d128d4e2f9b1b41e6d54d5d5bf9397ceef6c311ae8b3a08fad0dcb013a1424a22a65bf7de311aa487bbdd42e7d12797fb46016fd41de6effc87ea790049b86cd186e31c56c448b8554c416482c96d423bf7e449250ff8f1f35d52e07b3188ea7379df6ec42bf30129fdbe06e08eee3481d8888e43ee481bca4363aa6800f53f4877e2ead080625b3e0bd0c71f16640996830d79e5340e91ca80a94e565d94bf4c8134504c581b878cf64f3e87f979ebf9c6a8858786e028568580422ba525584c8b24ea4711b217034fbbe97b3aa73824ddb74df7baaea1fb54b7cc6659acd7c2df81ee5b88c1e7e6b93c82fb04af84b5d583e3e4cb2ebb9a32191397f13b648140cb165fd0803256269bfe1d4020e0c01cdab84f30c5d2b11d43a57c7c3ef5747814508607ec20ca4645a1a0a3e2445d96ef6dc5f7ec5c7c73a9caf42252370b34617b92974017f9924b66764b4e4ecd2fb5814afb2dd413a8a9b12183ec19fed07b5d3839a2643229051139805de8821b962e301161321b1823398e7c3ad40cf155bbbe254af605d610aa6b9f2635b5c065c443d515fd49594053ac6d54ef8875631679637d65f12cbd9542812b57722090da030df62683e30095887a65d7f4e28219f3ed27bfefdab21a31b1665fe59101154698ba9327ee232453eabc5cf943d7e14e33ef703e4b00f891b0e62579567ea8df6063588001fc8edadb34c76cc8f49fbbdaf152e5f60e11285d13358869156283211fb0dd002962200707290494e6a6d07fd22cf3888e40b44d7f8222df9eef51ad11a94117a706c241cbf573f44f6fd502fc345b68cd12ed202b8b89d1072dcd76855a410c889923400d1f68ab640c0ce55e27d8f1e5dee76480523b45abf216863e158ace23579ac4fdbf069fab8476a3afc580859d170050d2d39086df7be33bda9d9881e7a788de0dcf7bea40905a6bca36bc2d04dc81d692a5e11a7cc3a6a7777731c40651a2b5da7acbcd00680c5d476a74321c9fff4ff3085b7eb36103cb0bff1e9b38d0e398e1f9d67c22288c1257ceb910d0f5942b26aa0e31b08bff4c1aad1cf151a952ad91ac6889b2a79e076ac00df04183578208305475e7453d6abf66c03ede7bd3a9bcbe386ec8b3e56e5b3643d97164a06a4e1e04ea7c6b945071fd73c4e12275384f4fbee39271612add7343edcd19048e3dbc72cf78b90bb2927d989274122064d39691326317055439506bf101c5c763070f87fc5cd8233b1c229fdd02a64bbf2792b86d864eccddd7c21a133846ad737deacbba40342702d3ffc1e8b83dd2c273e0cd7bd2cc7691dd290118a64c3965e1615df8bda12fb1218f3b5a0c9f0f79153f4e4590436f6311a08ee66044bd8b8a534c674385771d0d513fcef14b43098489126497774c0ff59ddd5de28df632ccb1a353b40ffa1709a40a073b303ddb557532422aa850e31949a768b4e7603cde96d075c87e492d291418bed49b96cf69e3c651f33247a5e9400c698bfb665b3d5a4addecee71c0057c84847a65a4b0af2f42660d02ce4a8a8c907484038ac40e43092aa4d050bddcb00afbbd70b253bac8233b753990da2223c17f2f03354f4778c8fd6d8d8b1f43c2b7c02e809c0ad65822e5b1688c1f70f0685d0c31742c2886793bb122ab3cc047594d387930b10adfb88ce10d84703ddb75f393dfaa24bc903643b889611c7b03d9b88faf7060b5c43ff8464a42514c8237f1d8fb11bc6c44ddc952f56954350945a02a4fd537c9caad27f120bc8e3278f91bf2b68b998991b1955f374dfadf87a978aacf0fa253743b735678f36bf52b1ff1783f92589e1394568e5c7ea924048eb632facbb07aff3456fa96ce301c4904173ec82c728007a2e7b9402e3ae81b1fe51e980cd41b5b83e079181389507cff283a610c1d4b0aa06641344933bcadf5f6248acdba454bb054066aa3aac8f40a4701a20ad8594a6fdd14a6db03b961347f407058cce7c18cdb50661b842a081ccd7fdc0de7a0f4428b37fb09ff1da08e912d083ab20f3e53fbaad162aed0f8bbff263bcfd34978d2a78e08efca093ac15d8011337bd7617c001d4b5c45253fd83edf9151f59b9b280dd531b3a560b21d2aa37c77c9d25b83a343b993740bc5e568e49f22546a8599d622874e276aae802166b2583a5b5503cef5ae8f1af4c6e5e1314be8ffdaa512705cf7008f849a45cb4c473585e6f892c06f620954f76a077b3c92cc62ca368f2de1847a8b96d7eee47ec584bd8514a43f8ffab21bc07b41104daeb82995c30ccba9a0e251d2a102168e36481dce2c0d163f09bf18284e080c6488505424ba5c256ad2ca04381c9334548b60574387598b96fd7f1d76954156f4dfc445d8b88ed585ffc2104c7858e5cabde0b8da691496b7bb735b9a594322519d9095c094609453b64fad3484b9e93274b261268594af776caad6e49f5bc77ded7bfec7c4dcb4442510f0da81f5e8061ca0b9313198511605831005330a165cc172699116392e4f900f0e1872ac44801922d26808225082856386fd4336008c0194c9c0126d7c7e027063450810214966e505a413a0d71c39c73ce1e6f68ae7274ace8c24486972a5670c40a9acab0a18c33c4389921e50c1472fd1ede50ad2408a28647ec124446d1d413793e8f8e183c5480058a29a35c7f07930a78c091eb5f20450aa6b0c01baa1b971c1480494111b97eec36f9114956cc39e704bda109801e39cc914222d725505084822272fd1d6fa8ea3821b50206b9be0e6fa85a219ca0c97133986fc7c832c60a79be8e37346f5217343806500031a41003863c1fbf5e4c4a00c316585280c20a098510355b2b7e07bb5b8c10d4e4f99f373473c894084396411846e4fa9f4385eea28ee45adf460d91ebdff0866a17f50421b07202a65cdf863754b7271d308ec895e96b784375b3628a1f2576f80835608a57a2162f9074783145982861b6f862875cbf07e88b2e72fd1f4082e4784375bb225a10ee00a36403cc152610c204b55c1fe60d551d1474395dd472858a92ebbfc010e5fa34b0121266b821072eb40c219f20620515ce1417f8708145174170a143aeffa242b48af7755dafa09ba6e2eb17242e50f8c224d7b7f186aa1135d4787122cf7719d9e450e143835ca3960aab61b8d428c68a14acb0a28b5cffbeac3023d7ff2b9ac8f5412c72c8f57bb01893eb03d5b8e4fa3fb21022d707b294450a725dd2e2895c1f842d74c8f52d90812d98727d225e6878bd6aad482899894133edcaf34a9729baa45053830e1722b0105197b8c872ad5aaae821572c5e86115dbcfbbaae976b56c18214797ef73a620bee36518124cf5f7d3184956b9b9e92c8138bce9309b9d65a6badb5d65a6badb566b92087ae297c9862cb0979fedd52459e4f5f3f905133a3531679ce295158b5d65aeb4e9e45042db1f7058ba2498597164734a2c832bbe1128563b7486293b76d73bdb098820595d78d422a494d97292b6437d784992b8b231b1750a0a9c2a866861566b67072452992a935d14c79e1621135c3840b2d2e453258acc0d262ea66f922ca66191343b785118b89122e8b266f04ab2b689d9621544f9c653a62b718ad66d32ef1586cf2c4633187f7554bb2802a9cc25861015a142d69197364015434a9b0002b8ea4a02149920287a2055cf1248514240be082f4399a4c6dfdb295564aab8e272e8d1c9762b872e472392ec5c0c50a3184912403d113198a7ab85549d365d174b020430e3218b1e446278ea0e59d2519a05892a1cb7dffc273bd9c80b224d39f5132998c05195680a48b4ed470845ad0c2ad39c18223eeab091597660af874594a607155392e359122ff52932b4ca83a4930189d48622ad31c645cbb45cce8da1c979a7851c495c971a9c91832382162e2ae725c7292828e14eecc71c9c9121b392ecd30460fa782eef60ebcd0c20d2fc8eeeeeeee186eb6736d312846cfb12f6b73fe25c494835105827e3ac3c9184252b6a726b8ddb382843d665cebb13e2342dd07ab5f2b16c27a0e17693deb8b70dfbd11211ae74cfeb45e7ebc2dfce2aecc7bcf61ef693ecad8ccdf6dd24209667e437ab2bf63a97463c60d6d035ac8fb8ef5716db749eb240eb7928c612bb7f3be48eb65dec345baafc1600d4c9c47642d066daf3c49c8128757929125966164f9f3732207392ca5c615d785a5918cc999bf1f8258cc602040637ce0032d5c448a90d6771f65ec65f007baaeebbec320f88005eeb7f0c5edf4dd87f1098b16b64464cc7bcff3dec320f80057996e7fe8442d2ca50616f7bd0fbb080bcfc718dc772c25077fc95509799f0ad75f853530a5d3978bc3885b6bb88e8d3c87e0affaf9e1dce0aade5ff5dc6c99a3acfdc8300ee563c70e9dad8ba1edec6b2a064510f42efa916c21f9124a3a5296b827cfa2e8d2684a1c76b307190b5142f16f0ba7466beed3126ace6613ffc148618ca498299b4573891f492319258732cad1e752554297e240f553314b563df7f50bc17f72d063f2064b407dfa1c547f0e749e2a2712e33e2a1c420d679e218ce0b92ec0e248bf10fc371a427d7ffbd14b802a048b00bc7909880e4aa9fac54c9b62507de95f8b3c3f93c8634bc41f9985962b57644d8350d67cec78bd646454d39f1479d8978831f95934451ee9a59f6a2a2b8e43764327f269244a9e1ff3c4b52831b2d6535ee38c58ff1870f800e4a5c28d1ebee1fe7020b2d25aa794524a29a594725229250754f5616cfaad1be2c2ac94db263729e595745220b449bc575c07e2df06af136ef430941b46a60dbaa393d2de6c383d95f3757c839e5a5cfb405cdaeda3106c73f78a9baacb7be50c0264851b9970dd95ef6d822c4109b61792bace1b6a2d0e7abb3bf548bd9dce0c8c9cb41c4d1a35256530dbb918db5dab238f1affc3c01e5f7212931d6a7af48064d2069bff74cddbe994d14a14145d249ddd1435e53eb2a1c254713159bef5861c07894eb20271b3d70f241079e4ab96b81209cba317686e28f9e3a2f93c8aca55ad7c48f58ae72742a41f1a41c24074caa111a41cc2fce6def5c1fc6dde8810cd07f3a22330999f79966c72c1904fb27cf9c47d4287923469e4a054d17db9c47dbc972f84e65d2ff33580e65db2fcf120dfb12bf9fd9c8a741a6e3515717dcdfb27858585b8de0617b179d7d77c456a9ee6af1897bebf74288fa202459372b0dae028635d83a3941bcd93311eb974d93d329c51a8bfd0a964f93964dc501ee121aa57492877a92807a5fb181c675cff469247625c9d12ae7f9d5df9b11eb9f263457271686404528aecb8a37040b961877941b9f2b54c18910c4b40e71fc8c854ca96c1acb8321ca1e6f72f00cdcb775acf644c65853e31e2b8012021414145351d4509239dc8a14b1d4d41426a922f9f38b9d374b8f2639634ea94ce9671b21286caac84f2c88a54b7d42487b28b4c924c5dee510cdab23c8a729fbcf84f902c2e618162924eb24ba52d619dd454a46b4992f2a89564902ea16a209157dca71fe93aa883918ecff151e76b212ec77795acbd5729c7176b2c71e5bbcf741a89ce21c7e74daee40298b4d3f94c68a1300ecea8e9f704b7a1ba269b24b9928d25f746de799d0f811e082e4ebcc0c504a83184e6cbaf6b2e80f939e6ebf86291ceefe0225284e4f81cb888fc4d8a101daff345e4e7f8fb51fee8e022fe3a709431d6b33ec71765ecfe90b1f96ef3fae834609f63ff7e278536bce12b13c1f11dfed5f7aaff1b4f3f4aafc6b79e88fc71190e1cda0f87afc7e1dfc021986de01a3804ca3fe48f7b7197cdcfc1a187c9f36138b434f00b872e26cfbfc1e1cb06879228cfafc1e1bb300d0ec1192c83c39efc6ae110c89540599d5f2beee1121163f3ab402d912796dc4991677e9ddee4e0fc39abf48e945575be28e4440e4eaf1263f39700b1e449c5865d8989eb8e83882b8dde5949465d6ef8b1ff2a03c04028f7a7179e73832f8932461bc1eebb1122d87d47c4ebb82279f52dc580b2524e282eea6c51c6de5e4e1d392bddbe5b750772b95b712b1528bd0d883ba3cbfd2d3d9244942a35262644a13f29729f965522134d2abb90ea48460a555fc6c9eede906398fc2f7706024b0e5545d51bf24ee6606fde90e3d8e28676ca4e5931d6be5ecf7943931e1539d81d11d20d3b5957f41a81aabeaf2bea64f4ad980fcaf673fb8ec83b99fb548fe2b1d9b9937545ee13ab4a36e52086bae12dba45ee538418395415d12197dbff70ba750d1c2e4d8e5bb68c206ba0fd48ca7268a537646be470433f72cae176d4e3847b73e5aafeb574433b7593c4a54734949472d8c972ffd1a447b9df33923f5b918cf51fe5de68b93ff490727b49b99f4611eb4b0e3d2bb228748b84b8e1565494fbb7221bb7a2dc5fa162cc63ac50381c52a1324c7e14f2280e937f24e6fe94e4e1bae34e8a314a96c450b6ed3b6a2a777f03a6d086ed94dc8eecd496d4b84706e972016b2f2d6ba5a824d418e6452fd418d64d2e112b640a3586f513b95063291c44107463c08893a21cc470e1c315412c49117534a3a2d4b049c0095210484b556c01430b162b284e0006892701133932753ed0b8187f36b757c6a8c521fd4ae9eb65ed638b438c514afa93cef8515c8cd14b8eef4a3551b76337998a5a26b65de692f27cf9752698fd5eb38836ec47fa21e0d0beea6df521752d8675509f6e1d1ac9f439efbc0ebed0089df282b813417ff9e188608f18f3ffc99e43c38716f24608f3733831ac83cff53fd74975b044e83179e27f9593ab56d56e5ceb762c4f86c635f3381fbd211a35df3eab5d754e62065ef4688841d5d5e3a36bdd97f9f845dc87f5f17be623cdc7ef27add44c34c2d6f28adf556206eda57bd87cd84b3ff149e0c2cf0cc949f48f42d481e8df474070086c890ae81efea01733d8d13dfc77d830176af310503b281a384d5e5e37b89b6c70e85e831baa9110e0b9c6042e9a9e4599cd198f95813e12f552e6b6820c6179386c31de6db647013d3dcd75d4d7611c7429f7b73874a2ecbfe1b0c5647f2f76646fa8c8e30ffb0eaa280639ecbbbb63b7fc09c31d06aa4a4375e1331c9791eaf999423019ea8e0f2304514970a92d2185822c4d542c2b54289c4890274427011347d4b6265078188e7208eee8f172648261492da1d229636cc5e860fc5983129b5015a24253889b1dad1bcb0acc4686f5aacd93a492c478fc8ebaf225c7ee22c76f2f3108a78d9cdae829c6be32a5ca94a51cbf9562108d8f4528e49824472639badebf9fc87cd84744eda489688841351f9f7af6145bd64443c808139f480ceafe87178f31c6da1621518aece4b129c420c7171283bcf701a44190dc9175a2df9cebcaaf0ee7a3dfece2099c4fe626314a5d3c71c3062c49eaca97dcef44b98bdc8f63e3833dec6dfc8d1b30182ceac6d719e7eb6c03ca0b8d8f7ef3937949889c1a9fd3942a35a4a7a51a9f8dcdc33ee7b9ce1bcab1b1b1b992f375a6f175863129d1f862c6e9dc45ce247751e4a9f968cd376b3e995b0437af2f03dd4e723f95dc35af4fe665dee66f6e6464648e6ebece355f679b36ea2691a7ff8bd945a7ccb532c098a1f9641f74d110329a06d5b35a19341f8bc5adbca119160bcfc88821e27d747a9fcc718ad6931721518adc2fd55bb2773f554b019dbd272191a7df931ff50264a7ded413000d72a62a4f0146b2ca474f4b47d6513f2ff7fb8edcefad93376fa8d6ce5de4e98f3987e8f63bd9e818153b2bad95ee94e0cae4c8d40253d1f572646a61881c2a6801e97e0b32b8a0baafeb7a41c9335a700188abca91a98523605a20daa1dd9a239392339894444d2f48321633a53b3f5c1a53e8d002450e9fcab53932295122ef38a14409dc40491253922472f83d3d4877f98fcb63fd4aaab9b13c57c751a970707ab23eefeb56d64655b3727134b6bb92eb64951b9098251ec113d063c68c19d31eebb65a57a6a37165a51c9d3ca95743bd9a1ad652afa6c6b40102410bf6006d30326e38694c98bcd1572f8f4e2b99ed7dfda42c20dc6c09c620dfe13e1debc8838100727f3880ec1d1b87e6ffc69cb37538295dca28a594aa18a5a4966e73d6bad139638c314629e5cab9961de99cb3fb557fce3a65f458364c5c8cf12565534a698cf1467635b8bc26add1c53bf2dc2e8a09e46084d9703d3796db6fc3ed0cb3e1469b29433a5d730c4ae30ced628c118740e594b1975295ce6c49c97594524aa99452ca158beb28a59452cab1ba19b59aad6e46a9ec94895bcf50cab9bae8451c4ae0ca6ec76f88ce53eaea62e49194524a29a594524a6d7c8cbe2ddc7ef9b4bb439d1c256aa5b5ba1cc442d4248fe058667904efa93c82e777106f5b0e558ed5089ee387f5e72aabb6ca7539e2d75a6bac35c6aeb6fa7632b5d63a536ba5b17155cea69b33da5a9fbb795557df7412a0945219a3d71fa2e30dcdc773ce9b5965f64c719a4637a51ae6e4258fe0596a86f4e5770f05e7e33c75725e37382e53029d9bc5e95577f7a455ca2e5772b9b252dc45b3abb8928a2b7174b0b3a1a1abf1c2d0b470984564ae6cda9a6290dd2d251829c1483926090d5232f13061e84c1266d231b015b88a3b779e71b13dc33a885fe414814ead9bc579e5f8bde2b8ef5b71ddcb7d54acf8ed31c8fecafb4ef515c144ba2d534d42e4f1b7dd4d718f74d11204c82c71cfa43062510f37ad9b5e03a4d00a379216aeb3e96a3c8fe5b2400d04164d6bc6a99b76901ef03a9879cadc1cbf08526e26d6cacdd0b4726a60d5d874d14b6edc9187bacd0d2701073f887315243ae174919b9a9a542a2f9c4b94d3ac553d7d57c96d82e5745064efa6d844ec2cd97d065a4e8dce02c10a883c37861a366cdc90403d3d3df267c571dfcabfb8f118470caa407afac7693247cca0a3ba87bf183b56756b50345f254d164af4a7adc53baa33e825620f7f2f5d8c7237214613f7e1d078dde0ccc701135bc1cba8f20512313098925049929464ca28989220fd1b4d773a414b122c2fe2a27325994cb66405160a52b49294548832836486d73243c76ab574726b47abd5f25a1f8fc8ad9f2d26246372eb6f95dc6afdaf00456e3d8824b7be87052772eb8156c8ad99536e254912a3cf67cff33c4f0531d93be2c4a4c2112ecb9373652e27733f392e8527994ba18bcc7939ca036042a10935b273fb28c656837664ea23533a001aaf6090c3a8a50bcd804ad126f2c9611fc9b49768403f66c994bebd24a420d37f2165fa1f0231327db0042032fd9e12aec8f481984a1893e903214acaf48310a520d3ff000428993299e045a69f01fa44729089c08ba21e32653ae14ba64c011f975799f33af9a9b2cd5cab93df96b9dbc9af669ab9998e867375359d8d8b66a6e686151ac9b00e6e3a37f68091d92ea6a38e7bccb9e1c69f2a748c1d63eceed8dd91c6ee27dca42f99f8f4affc22209bd33d467713b8f84831469d3927954e1d989c2955b6fb72e5538a6d94f5ba125b1d816a256537b74fd2f9d58f66d5eab33182f4adfcb939f5bd5a6abf036bdf1b52596c75b0364c4509d9c4001de3733b5f1402bf22345000e3884c68e7b92e020267e14b91d0055f040400e0e2284a28f616c8b80fd991675ec6bf70479699f91fee9fcccc476f68c6a6c647cf068d4fc7fff0170a3766fcd6b5dd0be686b2c88fcc8e5a375afff26f73ffa68efc6cae09c1fdf79ca9c30d5f5eebe2e0d3d40d250ddf7cbbbe717c7b43aee75c2e3a66cc182c3947a5aea5399af33b1ff70dfe0e88fb776cb8709f06ced30f07e77f382725c5e108343ffd6cd89367ce174aa770484f479de04a263188fecb071d72c5a1acc1667b4614f9c4084bda279b3868cdb8345ff3f6551f4a1a77b3a972a85e7a43aa8ae36b8e987138def960f279fccecf0f0653bdfc0dfc602adc001ebff330893de081779ee7c1876dd8039e079f0783df12fcac8c71bf5357cfad6256e178ca89f023cf77bdcb254254ca12873ff2c421b85ec7ff70ff5cafc3e70f77bc4d11b6ed13c100746772b223e24ad294f6297d42975c7243b90ffdde41c096a964b1581deb6547955a0afcb61b9c100115b42652fe944e93d2734fda6c311996fb6553948a8a4c4952b925131130e4502a5dc9dd3fa52b2146892b5f02259a6c9c4d173d0e74bcebfd73fd8effe1396f9f03df88d0dc79f085ec3c08f3e78932362516b20373ac0121e0f3e0223fb003a2101019eb0fb283ed86a5c03e0af1f0ce87bcf20f5fcd6ff5f60b3fabb0857d21d4bff987b45f97f375dfe3e3b103fbf09837d46117eb69bca1d5bbbca1ee5d1feb7574cf7a6ef5dd2865afcd9a94a2ae92d39383c0fe90f31ba1f3dc70e0f78f7b9a83c3435e19c7db1c3d1cffc3c31c78484fc6f1f83f2917e7693c87f3859db717a5b1610cf4641d1adfde100dd8f7309d8fded01724e7619653b9761e076f3938b4301cde1756816190fcfaf971a0f3f7fd0f7f7da10e6e3d8daff307e5869396fb713c1ed293bf9f1dfe6cfe3e188eef93dfde3f27bbefc3f1850d73dc0135caf4bf8f59ca9c9e6a505153535150b5272737f223a424a5a626a524243f8a9a729917f98ce6349f4d452935393dd5a0a06a4f4e4d4a3d6b5a1bf511525212521fb551d37a166b112a2a6c595117b56c2aaa07282af5e0f1f100b953e6fe87b7de88833c3c7a7c3c3e1e108bb0e5b033067a3287c320f987e3577d18d85e7a43f8fffb42780cebc0cbfe5ef6778c819e4c7108ad973df95b2663fd4684769e87061c108544e0de0151087c1eb8481110708fdf791e1fde1e9fe411b66ce7a3d08e0f63144f186b418840bc835fd25a7eadf7aff53c1f2cc88e8771d8015168078e3226b4f3300f5a68e75b6807f74cc65a166b29b5fec6e79f94eb5fc36dd4a851a3468d1a356a7c9d6dd8f8ba461b19b9769ea3f9c2ceafb7f9866e705e62b007e855bf3dad6559a353df5ce539387cc1f04603d315b698c3385f3842cd37ef72798d95351f63cd4b0cf6b83e04ba71bd7f353fbff0e6dd1baab979aebb1b8c3d8cc76a5c51f2d1915f71b05fe67ede34d4c29ee47ddde746df852b4b9afc89427d5434739fb02ff87c890ba0df82afa75c00fdb12fba00e4e7448d50f392dcdfb289b4b966881b4db511c881bff33e80b2a4d5ecef3407dbc886eb4d6a9fdcf9bc04c42758c88edd6886f2481a6530cb270787b8b20a491483a2fc96e1953e2e254dd27c892bb32ca72021d9194c49c6fa618e3bc98ac4342d4edd4a2d3b9a328a6a1a54cf6a71aae73df6c41028dc3ae8595681d093e50f395718033d5985c320d27654023c3066cc18a7bce1213de0ce178566974b8b415dee974631a8c34cf9f7909e3ca427cfef28077b4ae9facff61026ee2929cfe17243497bb2f3f40bb0b3f30dfefc064123f7a118e66fb37fcfef89a11c543d216950547ac8b2cbeca79def0989bdd41cd4a1a5fcc7c378acbfa71c3bd40ac9fd9e42eb3092d6500ef63794910e9f8018545219e5766f6dec6926e647fc3b3c947712dd34504a95a69cd035ed0195e74feb2428e28c07a294522a71f28422cf773a060633c6488113279c7084a48288a93a43539e566a92ea4b511493932f96cc4878400b3424478c9824c961f60025494c3308a1e40149a03a147a3607bfdc558e4b4a4e782d2d51a2134ea5ec7ee3c5f599776f68e667e48cfc5519575a4e46e6391919ee7ee190b7ffc3657dcb71975e7ae9a5dc8febe387b688f8e3c231c65898091a6c25bbccf159cfd18ef51ce775ed7160bf22c929e57c6eca29e5949999796e662674654a714711417a1c788e52463e6c2e711f9783bd4d23ff79e43e51fce72c923f52d692fcc9bbc830eee332647feb0d61e9bc8aab57e6b8c8bd27399555197766d673fe0aba00c8d2822c71228e3f4e8b5f0c8ab97b80a4bfc45362a6a46c6aca5a6855c6ad1a90b28fa48f309e6864f23a80cd23da7d2865f3894c5a7bedfde849a4c8e3f208c71137743146fe75e6412ae54a2499342391ac375d262af5d1d7aa54ef17be72eb0b6d9e42ba1269db5e25b1f538f0fc23f2f8d323f789b2b5979e3295dda5cb29739f302acd22f70925929c9262e4530e27d13c92fdeb064c4d9eb237921e20b047de97b419fcc0b2a7c9ad1543a14940ac9227f6e13d34df061e73202986a43aef9da424e33a50dc6071c3e8247ffec445a450db42f2e9c4b097833b40f901f184b8501123424032d61d6b4e515f28c150c5dd9d521a630c928daf74f9caf366712b0e87b8f0063fb3e31fab14eee7f0a504be72f74b8544189d6adb10d50417471814700722bb39a7063a87ffeee3ca9f41087bfe3669ca91a949d2528e4c3248e56792c14bae3f9da4bcf1722703e2529ef89b4febcfa7923b32790cd8de4a0fa828e01404073fd672e22b7b7f54124d94a69c90bd8833b2632b59e847dbf445fbff8cecafe39fe3378cdb0f5edfc8c8b4bf2ed78d6e5b75291b241f5e3c76d92af5188a5290fd75bc658c42e215c52aa1d65aeb96335a485070220c192238b2811ba0c6a0a054c2962db63cbde045f17483122c6242d081394185e7cc781d95540ebfc722795b69ad7495040d546011a3c313a229b6b43013c5161c9a98f7755df7c6315a48b1f0c2d30c4e2c4df1658b628a3050ee65e264c3840b2624a0b92e262652324e8e4c4c96e43075d2ba59d58aeb58565e4111003916c522abba325f6c2266895c7e8b1cff00d18bfebb86a5e3a4322a6b9b71cd0a04fe903f351f7ffb2800426dc8c416a0ab4d8c4c36400ad16022644c7d2ec47577bfeebc8e2e57adcb39e9e0ae643890b96d0ab7a7cc8c4a2929a986a456cb1b627dcbe3c0b3ea672c919679e71ff88f17452872fc05b8064282282006a9b647723b9b4569b55adf2d3cbd157655dd6a48b547b2b328dbaccea2047902c2cd7433ded0f6331e079eebd7d86c1988535ea441d105397eacd66a5ddbac962405f84f276d76f65ed4b575c6acb596da95da14990fa88773b95c3536b55be5b420cad9500f4c1b1b9b9bd7ecc95ed4b5eee17f5f2f3abda8e633236a2de946fecc7cf8caf672f78b4232ab4c693fab85284ebfcc95f9eca521f18412391a2d9623b1fc6bb1d6760a0009285cbe2c51b3a20769c50f38d81e2b434c996925994c76245ec9f406a554504a63971fa464fa3f4801b104105053aabc10c409327d20415ec8f43f10022aceef07223b65afed0be48354cd0d510aa4207e90c2f85025d79ff186aa0f5b7c209190e75f6f68ced083095a35381080872ab2f42025d767d9d04981c20309b9bee70dd59a274c5290d0a8c9218a19b9d6e7bca16a8520aa5959e014254b14151130b02c8f284620c5084ac8f3b74b850b5b6badb56576108369075a9e4fef9c53096fce39e7bcb88acfa18f5cc15cebd10db91e89c9f51f9c814987292865e40a14047777a0687941060c0bbe9ed490d84cc9987df2850a355a9c6c9e4c417125d560c181862317682470410897a32892ccb658418896a3308a8e987020e30425990bd6056e8b5703926ddbb62a68b40aa3cbc311551551dc2b872232a5db539ae569cb52dbb2406d59a2b62c531edbc026b668a7bd82a6ea525d2f2b64326673f86205da258a902e53b61cca6032a5a02205d385b26426048b1294274a8438d5a008a144c8144d509a8e087932fa9e90b4525a2d78e1d21c979a5ce1056dc9c9931811b7cb71c9490f3b29383102cc618b135c1a26a42d3a90f0e1dae4b8e4c48a0b922c39215a7232c61126883c168fd825b7c9eb89c72213513c167308c68e80628cb991e3120d496a947d4efeb42f3fa39634c924c6ecab24cdeca2ea644e30fb8b946c5f1eb98c1283aa945f3b7ded25f2d8a75fd71cac12833afbdbb73548a61dd94a22b2f5215b1db27d570e97ba8e6e2869921655ef82726592fb6c336f5f1a49c9e1502a65fb5151dcaa5379181e1585fa03e2ceef1cca999cd99ff6673e6924690edadfbedc9837498b3cf6372eaea3107d5648a28f6a87f6993cb40fd744f4a150449feeedbb0939b81231a8b3fd767ab7eff5972cf1a7919a3a83bed26664db28c8b6bfc816894bb6d6beffd05092c49f0cb808da3e12d97eec22b2d521cfc0c47ef55c4f6e3f573d06d477e170ade522875deba4b559becc7be00f0b222303f3e02dcd5f07ed47a1d7a5c130efa310cd47a10bf360e6657e06c33c0ca5e6a390eb6530ac6228331f856476d4a18a4130dbaff97a64ccbeeb039231fb349f53b5efbd878138686393ccf7818cd9bfd5daaf6f0107ed4365fb8d74a53390b3ee61df43ba32abb556ce3bdac9aea37226674d29fdd6b4b3283db3cf51caf2b2773e27d79a3d25f79cf4eaacd6fca6b56fbf8f74068dd43da2676d876d1711b4bffa7a8b085a29eb1ef66d7b1163f64390eddb318c5a397497451e6b27b6ff61b92b4b439a6f71c8765af943b61c9e13e987a7dd502737533fe9eeee4e8105df9698d88beb3fbb890d377a584a13f7799913dc59420e6bf2fceb8a41dbcfe96097a6fe58002e72ecc902a4e2b1bc96c8516210e33fd83f7d45c7fc6b5051397ed857f48f3ba970c8c3e250878d1cf65383919d8bee6de4d067339f55e069979b504ca7f9e43ee184623a4d2db3cb84c2a7c824242f90b4f09991cf7cd61598451e7f3148536492ac85f19f98524c420b2d4d579cb2cba7ecd24b76da4e336fba22bbf8ac27a7450e25174dd28718f39759f4500162f9255e55b23b11f24be4e95a3fe1d87a67350e7f83fe69619914f2c861010ac0fa2ede4b4b77e3150ed491436fca8e7978412412f672c3396b2d1e94a0d2c4b484d64158ac8779e081f71b863540f5dcdb8779c0c1a4c530676158c51e744f571836b1072a98c450ba0dc31c43517d14da3ebef7592b1de3eb25f8515122bb0612c8c106fa2181787ceaea73082eea7034a600f7f11d3948ac9229b5d4e577c45de51824a3d71e02bc2c710da4d537fd0f885bbf33dd24f716e3d55bfc41883807e3aa704ffe0fe346196b9a8392ca98162eead4af8fe867420bb551c4c07f03e346198b42dcd32e6da3c8e3bf857139b74fffe949e23e52616b44b123893cfed1480a8beb53fe3886dbd88bdb180a7dbd7c4274dd1f470b37eca7a7277f9232e9754a8c31c87c70c782e848efc84d73374d36b1ed3845e48686eb665cffb069e0911b85a2500824611207110a6b8ac8589b715be68ec3042476c05e2491d2332497888346dce80de1143a02f57b9c6d447051e795dc28e3d634e36f3fed4f4e2623e2e07cee05c38d1edee186718a88aa7fc619e777b9b218b42306adf2acfba99247befba28cad6cb2dcf856c61f1b0011f20108ee038bf88bdb0f10199b1f8292a88b7e7090fac89c54c62ed9670e88423f646cc65509d1845b69fd721c9c8d03c98d320b064ce2da1c999e3ce5f056c182e40913201597e6c8f424891a25d01daed3ea3ae5d65deb477fabdfbd75779d34470259b9d19c6a5f39decf6ce395e3edd0696d9ea55c51fadaaebd76a3af1c6f874e6b524bbb4b819b52caa77f03f7e8f89c73ce493ff6f4a89aa136ede89cb3937246c5182395b56ba594527a2da5946e1b1254c61869ddac8a524a6b8c91d6788c2f393b2be5fcea54553a372e0a183060c0cc31130c183060c08099748699632818304761cee0a24ed8b5235b172d99cd365b8ba88848a9e46aca71f2f1a4211670d07f840c38e81fb59a12e03e90dd1054d77943abef9e257b8040ff97f781fe4a5468f2a7993ce6b6afb41114775292060e42791deba35252126773582a57917163ed86317078c891c9e315a6274732b54adc1085c6ebd4c2930d275ca61b54d0a5eaac40083a850d4972e4fa53e74a0d5276e4fa968a5ceb2da2883bbf062436d01ca851134b84bcd06484059329a3291784b880549bd87ccc923282b833487408716768b8e0890f31302e54d9e1b6725c72018a1d2ff7e6b8e4c21535725c9aa184292a318733c69c79811873ea2f7d6e34b640e44972fb093339790f3d8b41396250cc114714b3f944b325f46d8c71c39ecd9ad6b2af8b965c99d0d3f7f1f229a5b321b87e1a36b636b926bb66b24cbe99db3af9b532cbcb5de6b84e06a5d8a8248df745392ad19400000001004315000028100c088402814828cd835db10f14800c7292427c5c369708b324c661144286180288018400038801305354e3007682e79eee7040c7e23542471cab3e8a5010746afc592d0001442be9be613fda755f3bff06fc67ae8bc9ca997de96f1d991bfee11f78851670b5b4b95668efef23aa28d84cff32f9e73389ff847f590a00db04c296af65c491abe3239626006d70d79e1b50b2a8e531e915c542949b08c52a423b61c2fda524c05831051a9755895e1a838004331485d7366eea40ea1053646b76a6b3398ffa7bdf548259fbb75d0a2641fe4b53720ccb00a8e2a12e7265874ac9fe1c9598a0014341e72b10ad74c411e5592742c7d0d6560d6e2bbf532d6e3b93e5cf47dc076b5e091e66f6ebc986754743fd6af4aef6ee3a306529b3e65cb17656e46bdba337a7172f212c7dc14a71782b98036879eeceedf35b87e932858369f19ae72d42f10e70a33e4b73084ebd9d2541774ed8808b5d2434c37bda30b660efdfadf39df20e4b9134759d5195464f7fb9e90642fa50bcfeadd576406b94d4941d98490e3b8a18b89e601e2ed493990b7f6bffedf0b768360bc28de26d84ef4c2c1b9172118272f62bf53f842898cdd30bf1538cacebbc17da9c752b2af19a22e18b48ae093c0f38d82df097090c7ee2c06ebb421126d1c4266c9b584e3c7f902d10fe7e96eaa9665ede7e0556184ef9038e40695d5a9bee647059f5c304ffb41a0a73d6cc0dab4cf8e8360a629cfb0b172ee198e0fd13b5ec739f7986cba0f06980554f3cc2a3e4ce8d29a624ccef6d7e09c0c5ebbbe055339800b6ce564edabd1fe63ccffb6a773d2d6812470681e7aa4a32e34cbc41a0e63582ace32718f8bf1771e47685e7db024b98c5a8beaf54ac4ac370b5782cf42ce8c0c190ae653f34ad15f5188a6168b383498461a09652f82a8a1aa1f530afbd18776ff8850cc83b11315bd5bb196e62e3475875ea6f3047d5822bc946de632dd8cd6fca0e287071e47bd136ad41b10b8496a6ae3876c5d8e381bd6dbb1a94ced56d323cf21353bf045b32e525b0e326964b11344d8aeaf6cd8ef23836171e31b7f7181a9ba0ec6525215513c42d561f3f0827d887c190d0652c7d110d751f2ed6c67f011590d1e39c94531a937ed345eba0b992ce21a48d4ebb9d0de364478d859e0dbda75473f819729f61af4905bd86cabb1f27206f3be97e06d9d1a73187a168b7bd811eadd8953b27b00c5eaee05d885db156a8ef6c4a801525026cbac229c472aef2aaafce5ff7a8e79abd1b6ac827e7e458f481e0b791cdb5c7f5f950f5398db7a4ac5ee6ecd3bf9a2e4992188fc8ba142ef93b5a0a7c7e357dea81219fc92fad06e6605d5d4d80d86ad2b506e218a887b4fa9197525f82253494a9a1008b27403dd97f83a2a960c9c57308bcec5825f0250c6b865ee6cc2648aa84018432a72efcd72da302166301ea4f56e9f2fc80f0006b6507f724242c13f630a8cb1277843665c572e9161bda2a4a65e24c5e3a7ad532b5a171a3e3d87cbe23531d81d99a4173d6b28ff6c42bf6eac3fb72bb9e3f0af4d2a42c1e84a9a0d1d271a7a0a2820c7211ea675bb18b356681e60a28be3fcb0dd198b81c2c7e2e1a9237deb891f2eedf971cade6de3593c824b140b528b206f9efcba4738f2be492128ee5401d147f2401103782899c198323182f9deffd9181ebed7962c5bd5e3f9f34fbf6646fcde6b006d3cb342c8618f122078e02c77d27119ff066b4918c31fd57e2130e7400fee29e9010d144ddb296c9d0665c9e3de67ccd0f513362b26ab5abbdcfc31ce12a2a91e98b3314671fc95f9df63b3690ea1759b18b9beb2b84fac899206d6a80ff66d73863c79ea7f39021fc9c8496fc360d121079a2fedbe07955b2751aa6e1516b55bd982b283d37eb7f959c43c9ce3d7b94f494eec30ab16d60d0efbc2cffa157921afe127cfe10a146fa8484968cfa0eefe665107151aad7b6bff957f9f0ec3779c898698d4fca929b73074ea4faf5c8a6a7171bd3263cf97a169e1908adeac7b3d95cfe1802fa74270a3034694de89423dc548ff858e8f22388b915badc1b04d8457c32b64b9051960a5d4ad684b31c2d8543afa5672e85b633537b399a97485d4468f74985ad28b5b624dbe2c011bc1599cb1b98061bd21eec7b63b66924c3254f187d00232fafeee16f3ca502a79ae6c4fbb6e25592463f7ee7eb145dbaa4d7d32ebe4b4548db2520e3682c79a7ee34470ecbdfb4b6755443935f664bb4907bf10c5275e485cd70559b01953e147c477f91bd24db739898e47a03d6e9afa1cd9355437f3a3d2b083c3a44addb3f8613544a052804c2e75674fdbcf836c4d3755fcedc7f2488e7a9e99fe1cc82de48ad6ac17a0a9a2ad38b03d2c57bceb38484b1678aa278d574415bd3e6d355d12f02dca12677f77775506d0f844e3b3a0f4c3cce3ad081b09c3e394db22955bbe392310cc33bc5e76903c2c46541748969f6655e1986febd04cf474b1ea758dec9030fcecc1dc1a3e4d967545d7a00ef220e1a127b326d585dba2f30da5da00b4181abc7c1e3f67a9a30b085434fcca8d848267ba21a7b1a5b7634663975ce777d0892c1cd96672a6b1a646c7ab01d863c832c9b47fc7478a0b3f07bd39e11d8da08cbb2787c4e2e6f903d2721e5ef59a2811fa7065e19d64e69e1f9a1440147a8ee0650083dc729a4b0d3609e47f7f829fa1a9b59b9b06fb672f996d43780981c3e3e300d247841f76494956d40f9529c791dfac074537bf78efd8e017a8e05b986019ea70b521a24024e68b525b16986d6d2f8379c909608178633e390fea3617618e8ce5b833088c111f6d03156e9f1f4d3059f58598669a8eb0aa278eb07425e9348a17472bbe5c27f5a8051a853dc0ccfd5c3f685f13ccd4c7efd7c0d1bd3f30cfcd2c234fc5f4a29d24b5f0de189f6d67d5a7f0a77c48e1b9ca785d1c02c3ac557cd2538f11ac84f54fdc5c9644c2dd0dcec2dd598292c602d2549c45282c581096f4b4a00d08cdf503b70b33e37b54fbdaf4b987b72da3501da27b5656979f7f0420c11b354d47d34f86cb3aebf5aa992819b0fae6e8298e599d5534b776bb1fb69b56639ddd2f2aefee859ef4c5b631a772e7e416d168dd080816f4fd409a194df7faed7765a51b58218501608f5029f9714501e090a281889343c139186a783736bc48c699aa58307a278acbb86e5b1f66a05c6510922d111a0f480a0693a2251a2d0b98b75edf55113c98962c939d21cd9dd11df61ad460643519705930224aa3114acfee91f2d9232e9c8889f12ac2aee97fe262a7299b7c18236e7650740e0ae8889418646be6239c3650c8de14c6d503763dfffb5a45c0222af22c67151eb9627e2686df42edb06e6ed1ccd30c81ab17f10b428b7dc6eb066b5548744dbc33f10c037b9857b166eee6ed0cd9098c744cbb8398241b38253d37584776b7a5f479db366551e4b586f720b7d00ead598bb921c4548f49d9368273500ad01c914a8456dd005a4346cdb2057ce80cec123fbe5bb3d48520c69b367b8e6d864ab81193fa1555ccc08780686a0370be40cf22acc428360e24f018b180e2a27e9598631272b0bff68a6b02531fb6da3a61530c5aa804575c7573c8709557022f7456c2b33629a26c076c98a98a8452242558c13416ad78b4adb2bd2b972a4d3358abf44f088dbf9111c7ec6fc9212c729bc88767724d99ccae0891bde99eae80c2589ee2b3a033d301d63b22c5e209172ea6b02edfd11af599309227ee974f38d9b77ce70a4bd642ef160ffd76e853d9c1fc7a27858ccacb653af36aa478d9a6f9cbf904d437de6771b70b761da17701c138f5f1a1d2dd0930c9e5c7a4e0356f1bd0e429b2144dcc345511955bb471514771f22a53bb5ca1a178b9229cec2760c5cfe549c60fc54b0ddb8f484553cf035eafe0c508b0837671ee314c11f1dbef267fe402024b97b32b40b954080a3e7323f2eb8e58cb71652bab0c1b246bb912190ee56422e3831b6f3a6698d4051b311192485e565aa53f2eb292848669909823d1852be4142869a19752359346daf96e7e49f85f2e152cadd4259339af1658d6e457bf0fd7cced16c8e686434a2fc5c0f89c62d589da28a96b452660a78d87aa8711faae79d2732592b2bd0b3a560cad54c9a9b086b9046972729f17d53d04f9d32a9fbe5d9d0d908c1782bba71f3f0f9749abda0edb1edce33b191de79aeeeb9ab4f6b7c7dbbf1932d9ccca879c11ede04d96dfcc4994ac73d4d8f5e5701ed1038133feef02f4c01a2c8d3d5b4e767a9b512c33c16dd7dd359f04802fa2e9903f2486ce933a53a9b84348997508e10fa63c50dc57d0accadc6004dd37791cffe308d2ec05ce42c60dc60b4484ece62c7a24c495346cc8ddd71984877f02bf4c338d4ef0a2d4ce2746bfc5a212aea38545c1937008cd03e20b4e81887a20b2d0a6a8a96870bdef54f5e943587d33c9eeca1511962ec300aabdd9167a2c59048797045a4b002a626c624e4da50a2635de6b619b2af32e3e0351635b254d4870607f183290cecd3271a8835433d7d10d129b194928d6a5c06bd2e94e589e4ca8ae13c03d9183a63394e3cb220787b8289aad9c6236d35b496023a27e85ed60a14c75328b3ddb69c7cd0ee4c4def6f1b7289089795a029bafe62f7ce585bd3cd1814cfd090cb0c560f7d370d91184594cd06fbea69afccbf1f1c20c31e15c1783c4b3c144da257695487eb793d0041d88b8f60186bfc9b607f2a2446999673216bd2cc7060ac49b079ca05bbe83f83a41dce6fce9afc7b24af4d55481f59de189fff0535159aad329a44a05626ebdbf1d94d18b2657037dec74412c9c000fa5ade20e3e01f49376b6fda09b8b5de67fdf22bc3e040e1efca4a25ebf80f3d8e03da89ea107709c74a49082e39f7944784c2a29479a83c742be426d4c95779174ed814c5b3a66b151ae1a52ddb3355aa2a22cdbff22ae7695c30090c2ffb9b46e33a0b1bd500d69169831b46cb5b9673d57c01c481fef575d16dd22ff5b558de252620cd732e68421f18fbd2c2e9a3624a981e56fb684f0e296392b0ef94ef77a13cc5b4a2eac92d805d51f3011019024b492496b40ea0a2a8b318473fb9a6221970200b4311c39cdffe6832770f85569c58da0be34673e2388156f074aa42edd75f3e468273306993682db5767d3711a0d14ba75655a4c64b9061bb831b6e5c2d0c58872fdab87baed90ef512c184250ebafeae305c60f020fb802c6a169db66651ab9d677a2c971c9b71531809c1c1d0bb6b59a74c33f30e2b32200b2328513dba98e30a73f4d20c3c18193dc02cb46e52684d3f209ae0d801de4b70167bc98f5ddf0885aa2e28ab142cfbc01c99be142caf3b3bd8e8b5c202df8b1ed4fe24aeaefd6b0420ce74816c33135f48233dc4a011ab8dc4cc13fdf762bbedf24257875e2e2d15818a38cb6617283417a8aa6c6a6c36642298cc7f1a17b65ce4902eb64bf247cf84abe02942ec4cbeed68e0b9cdecb995a32ec72683c4029fe4b2d82e946d458721ffa229c887196ddddcce7e20f42f24fb7f012c40c24526581348d93aa66c09d96d1e908df8643270af9e9fd8fd613e256b8b7ff340eef5bdc6597eeaf034621d3137ce4684aeb817bc76a051dcebf2691a296732082ccb6120336e69948ee703f4c50062ec8392a5adb464c004ec477fb56f457a5ae661068608d04ecbb556b577da687a7e67c73627c4c47aae74210fea689cbca5da2f031b5e06d625c1430ac87df6533504dc9f0c5370b383172d82d93511b9d759c7bf935d5230c213962a52a49bcf748044e59be91433e2ee556ff6685ab8fe3b938be2d57db7285684e1e0eae17fb4a2d6ad272da5b729a7c2517ab1e0f550c977ae955c16cb20bbbbbc5a26a2798f5e302ead4183265370dfbeb229a4ecf2398fcdac89e9634f4c60978681e5712a064bb8e2b07a43ccacf7ee08b4af294d8f986bcb304ff82a3204a0a487b72a8f45bd8aba3f8a2333137420ecc71c2d1692e24dee4c63ffef09b67e1dfbcb222422bebb4e1009cb8e2d1463a353529bcdd97bcebd6da2f11c86089e3f20c4a63341ce245ce4ab3de841b081865ded615e8354b45a77bbd8704905a06d50c1c17bf0bb072fa79fa07617bdb52f5d68ae777e033d8ae8be6829de3a20183ee72485f73b921cd56b5a6a3ba036a1e1c4c89355856c4d4b69133ada1997ee7915b0e6e73677a1b48bbefb015595566054de1ea727e2d6513f74c7d52107fd901691a4019422bf1809938bfcf6ec19ab951431acb030ab3dc52a071498643d027a1d41adfdb31dec49acefd200401d66f30435fd0a757f15e7340f89aeee55f573e065bbffc9b3d275ee4ed7862f610d47edc0997caa88ef533a590fc52f082a472957c27cdc09651811966a5ae676a1250a11f912080ede317449c7c84ddfe6659d5d5933c22814764fce43e42cae02fdf3340f4d0a601843d8cae7219a9acf4314d4a5cb93c2eddba4f9bbc9bbcc7effb373a88f34a5bf444435f11eb76f3934a4f404add9282378e3dc15b06c008f766fed68d1e15bcb27a976bd9fa54ea0201d986bb5317f40c31cade6f4b4c203aa967d2871214ee5765e88c8b4b6401faba2b4b2302c0e529385d90b4430c657b15531b57f4c8e3373b01c225065c016998af985014e5c5e8fe99893b300b96ed219b6b5468e4ef9a1f0b960456e299e138695be55514f1e6ae3bc8ef5f525b9884aed0674da427341e50163e1da6e72a2a2674d8678cd01634473defc80520b38ba14dca438d0617ae9642afba9ad3834305f7fd74cacc9ebafac2f4c74d3bd68ee6e827179f52d9725e6599d2f0d79b5668c53cc76a502e1223c729f20893b2cbc85ed5c02ace565c9c6e2d7161e9c96a6eb1ecdb01c9f549f260cd4884599906444059193ea5b27495be531a64c60a375d1caf782b9c6e87deee7a2be5754434dfe11dd10ad41374608285e23ed834a44e2442f4e804e885b556e7a41a3684600e6bd80bc9a21aba2f51024dd1f6491dde1fa6f198ccd8f5ce8fc56d8af9c6fc798adcb52e96572e90a051e1bf94dd36e4bf40d851920eb87be3ed26ac19d32effd0d51947f1956cbfeb13b0fea0e74630915d1f79bb786363b3637f9f3709f894cc5513391db01cce56e827f34738c26fbb06043b3cfc08152ba04e20bc4bafcb94bcc791e7560f054820f3226c58715957015472b5aeaa6bd0fe0a0be6b328e14e95a1ec28928d1d3dea3d85b07d9f2a685333acfd0f4e4f9800a911d2b83accca03ee80bade8909cafa71bc4a738b05d56839f7681b365070707c19a06900a71851ab10e5454f3ca17c793b41cb38e1a70bd96a2c38d9d84c3172032436bf3e81030d26d35c2b1de54350d7f18f24fc4c70898a8ffebb14d378a256defdfec1fbfba3e5bc54472d344fc1ef7b392fda337fb208aa4acba81da0b9e03f9d71871cc1142e40f09f57a2afe442b077d05dd98921afa5289630a4f699afb81ac776a99dcdbb919728241c8b28701b5eddb2aef8e245b88407bea83b0ea893442c61370021a03e5048ea818f2e90f81ed46c7cd0e25827071b00f4a01223fa40171e1642ac94c184e212486ce299b2988515b187ca3ad1c9f45d85bea3fd4705443952de219720fac7e540a77ca02d466980e21dd140d2927d38979029180f10de1c8fed5d368ccc6f401978475de5e12091c62d0149f64c615150fd58f30407cc2bb3923d8da06da6a8b5f52d1529eb9929b32843ea11c5c8baeec819c8afc5848763657f84f6dfa63fbf050b3fd82485e49c30e29d917c29f5946fff9e6b80897fce88e0688ca7e2b878ca1e44fb4b4905502d0458041ce4cd42f948099266302ece1ed26d686d49881806021ce9e148021c6b21d0293424136d047df2ab35930927f1f41c73f42e9bea61765b54af114dde4b3e26234ebf42bd1108696765729a8927443bb53311537c043102fa466c854a4a4955ae5800c7d479abab134b365e59e9c72e83c8c8ab35a728248464794c4858ad14339ce8d4cc57b142dda3497775dca2c1ba3412840d623bf28f6448b4c2ea5d1f283948cb54924b2d423df8761c4f5782c3b12487582925c3a10153ea7bd91708e9196f57115ee4bb4f19708bd23d391a472b981285e486766209210e2c518ca341884bc22cc84267e004cdfe15cac0d7a1062ced52d1d44e1117ca4230a6fb57bc33300f36e9906b476c724b6c13c72ffaa5528c0b5b45764c747b46715688ca847a7153213de367f2b0c7eba016e299455b69d31e82bade1a677fbc3b702fae29a5689e2c90351cd1ce808b12257a0a81e02d7aa7e65f88953bf44ab5bdb6dff66251830ca3f25bf540dbac8dc7b78cdd7e29378071b040de96448ca954ebfe545842dc40a712887f35eb0cd32fdb6489e6cfe715c0e903e8b212b7ef048abd9d66053fe02d60f5ae16d1233a2cd5519050a92992ce98aefb72c163e35ba664a259f6c17ff66fe19891cfcf0254ce9853a8f6884c068031b553d9eb990ec723dc06ceb9419689a14aef187d74ef71675614fb9d753af8feec9d97c89abab3ef8f450f55e13ac0e480edd2f0fc0e53e256809d011cf6b854a84eed9c432a33f348725593419df15eb381a2e730121a881abf7b29e600d6419a008340565bd7c866e6e10a1ccb6a9049ee9a94d1fa35c5c19720b6e25f54c61821879078a03ceeaedc6362bcd0898557b693f587a70971581fd0518dd6a83d2bf9cf1f05f2b30a5f0ba290f83849587a3b795c2d1e350b25e273b5953d8ae5c8858743b5a09d0a2e9d5f772ec8f1226703dd47ef160622d3fd2b5787f17963393184a243ee6fe0861e8d48cd1f97505d6701512ef41da07bb277bf79bb973027fefc9c8a34ce27aa50a99e207e54bb40970cf63c88c8104068a675d515910d24b777619dac0b09b022b7f8e6caf8ef2c2d7c91f476f89de58c90d4c611143a7f772ca2955eb543ff0d7ef5bec1d40cd2b6d4ef97926ae1b98d709ae9a819389e26445727323fc7664bdb1c8f5bad2ef90f1dc82ce6a4682b7a9effaf169adbcc3db015b357fbfa8f9e773061c9d42eb22cd795192f4da985833de501e775f14cd58af70cd2a2c1e71849602cf265dc8a5c654411f73d1dce6997c1c6a02633edfb26da42c6a7006728ab1068f80141fa8d5f9630084026b2524186b34ccf9e3fea705dde4606a797e1c3435a1fbfe8764e4e5ee211e55cd368926eca0437fe0040fe3bf12861dc21bc736891b23112631099456512cba94706e56f50e175c1153d36ed93c85ce8ba194161efb5f9269bdf86ffa35e626f65655e0e1bbd9becbf1853d6bed5685f3fe1b2a08c3be820f2853b5c9e83c66f28530d135641343e3b06498fde7e68de70837ca49b801d8a91e9c8164e23f964979e99766431b86ab2fb4785dac439876afc34491ae029c7548401ee818d7bdda9e00a795c303b679c9ff49ea7d00f5587c8faa59e6744926d643ad35d84e2f8a67ade9c476dcc8c19d56ad6ed1456ae4f0284815427c49f2277f59fb1faa29c6500f1baeefe9cd0df345e1a66bacd6adfec55cf2a2d2383816b48b6efa53ba673f121e915511ebf3ce246deea71578581a904a5ebe1692a8b71ea8fd9635ac82084625148c9fe6698191dd9556b745f8214b257c41a3962df35058ee57b6dac70ad887e76b6dbb35515cdb62c320d3b8f284cf94ba2e53c8f8a6cb4ce4a49b607125112ae54105d918f8b80670e8ac050a41562c3c73436c8a928bba6694c99dd5d1bad666879203eaadd31cb33292999a40d16d26befc6fdb6bc931622ea8fa0333843a397118a10892309441a83b82f84ae0fca6987d56972dd553229fe2ae1e48a80b6370d030bb131fbdfdc1f63437bca62fd35c4790ed5ddf0f1b3079231a9926c135072c58740cefedf2ad536922e3012d7482fc2ed5ae6a401c11aebcb0dd28a0149095ca1f27a8c13722c782698351ae6f7819686799733555a5b22029891d732a365be636474ae59cd31dad8c2972e42c6ab1a04b0a43a9bdcf1e6f1edc8420f10b7c2b189e148c60f05ca77d8ab184e0ae977fc8ebca2c4ccd8d7d03e8f46a4f7797ade07877c1459732a0898f62f1dc0476fbbe4421c6e7dafd02c2b577a4753979b583072ac9739b79ee952aaa965e31bc34a7ce2441f7605457739c0ecf54e8cb11c9604679b01faa0191869a98bd942d11ab993285655dbe54e2e920ed5038c202d18cb7a9baba3dbe66e2dd025ec5685e2738e3c10001ee0f0f548a71e4b47890280b675a028de6f66a8082cdf4a539cbdcf2959c1a2dc148efd55218fce24d410d401b64e5a43a2bb4bb8876c75828931a1b86da756dc2ecae9c4c4d22396129a76274c92f0df2e88753bef5b4ab8fa9a8ced53e2352c16b9b005ee3b5dc14855520f2f59fe210e0b82351c0517c1d8d16927c681b2c7bd1d42a6962093373ae9294fb7cf176cc3eefca7eb2ada239f4609bbae5bbab837ef2156d40c830203efcd2f0e289aab0a138ff68540dc0712551149b4586f631ba07d6f85004ea84b28c1cda635af7c3b231733798faee680fb909cf1c6f9322da48d17072fe433b64c60b256950312dd51b932087bea40ff0ae20ea468cad25d79fc0ed37b3b9305f7864b111ba58cc4ff7d23fbab72170baa458590fde830231d98caf2be60abacfa9150243bb86c0db1504281c9fb9679f33eb505ed5204a9fb7e5c8b56b3dd3788d328e2a9d15b445f9ff60a133f4c6c319fc1dbf886d6c98a2097041870447cdd7738b7c81424106fa275153a68206ee7f21d92da4153cd83c944f827cb786538db0334224640a096050075a01044200eb135ea712472cf3fbf96a67d9180f6ef247f0f89939e90b159fe1f3786adfdd6aeca0e092c224b8006b17751584ee068b5f5695e2966b684aef5b11aeb8a8fd2044275161210d9acfc8998ee926e7ca16cf38eee05303f39a2bca2f8e081954032bb78bcc3ab956a5b2060648fff8b5177eabbb704f1b5555b5de8b80ab10947cf52c1909c7784b8239e60d25455f35de3fd4ad6f6614d6fad5e596c59cf48c98787491785c7725a7fae719da7e6bcf43499db4b14a3120bb794bd99f31404a139f93b8e9ffe6e401b7e200b3e4c9f6d32310473021aeb814e8916c3ada7a5e82ce39246b052eb9219e1ff4d5a00e37140b96dd9d18fde32874334ae6ce2a22db0e31318acf98f351ab5b0e4637282483576f3906ac7c90a40d2a7fac82d52e208be812eb4e05fbc939496122560a7be667e82763b7d60d6150c7f09e10c14ac9c62cf551c45ce322e62fade950371aef2f37cebcb8e1ff09d302d90e9b85ea974e892d929f383ade43a8d7738129fb5388e388ce8a429783d6602f1c1c6cdb7128cb14afaac30283d87f5745aae4a74e5a72feb93da962033d6f4f49400fbe0ecd5bb40adce3f8fe41abec029d5eedae924d0da2df33912e07e09f40d9f998872bb06deca410f84f025f99f02af712e86d3e5e800f7a80da30889e99d62f5887d0410931c807f70ae12790ff941721df1fc85f92a6917c4653c41dc00c7af993400209ecc4d0e8e3c3d743aa198220e45935903411f05e4a033024f88724ea8178fba0eda71999c2c00f2bf73c888875bf17f96c824604cc1688c602e13361145d9ddf11cd5f1edb9e71f5ee2def31510c1578593b75c86c6585b6ae3f2e89d822507a1f7af736133c8d1ff6c9f89d3a09cd2e1ad8dd53a91b9970430699a8da912a6efc3c19d82fa8091e28d703c37d8d2293a3d6baea2445212e8cb1dde0ca857e13257ea888071729b78a170b6b6a805335edc1fe09946f59fd029ef046003dcdf9b02b2272d82721cbecd40d0a8ac8ae0b4e9f4c71c63076a3faa191aafbf096b33ea760bc74d5d78f0826b7b03657aab5b67d9f2636ccfcfcea5d9fe9b312e155a8d0971a78288f78b6a0bbd1384f40366383733f59657cd3151592a4d7a6132cd704c3f025224170cb3172fd66f49efce417cac2ea4f2882d651d3824f9a0320b493df7b410a38ad2722032a9921d06c655cc0c2b5bc8a6476b27e132c237d22d5880275f6a48444be5584281c0d76afacbd2820a766209cdadbb523838535cc5f7f69be0f34e59ebc9bb6ef9327a24e79b60b0105382b5b7ba673ffe1251c2995cbef1ee3d6efe8251ca5e5deafb2c9df5904a401033dbd0f3fb4d09a24b9d5f28b29ae396b4fd7100b6eb4d50e62d1af29f018930e0f5809082b0abd17f1eb8baaa0211f2bbf6cf1e2a51528b71bcac670d6df28e3618c8419dc63d4d5bda899e4bd4c004f13e7bc6f6b88e287de654a32417a8e273a90c588404653687716d675302d3f58513fb6b293e9a9d0c6c868a99a129e3627bcf25cb531d7a79d5aab4413871c8a9ea543d5bd16dd3b811b6886772a65c3bebc39d4e59378f1d63a2f67d48c6dea1f6cfa455dd8fbc38e939e2406d4e7130095f732b307d98aa190a4a32a92510592198e817211b43bf640b8b795b262a9a6274227d840f7605b33181316faf3b49fab71ea06b846f07f4a95baa2ea6e24a28c514dfa730b88da2c698641005672ee338672213a88f17441710a9858c9c64d6c7755689596291866eaf2d7c09c76433cadc46400fc522429928a004ad3f748042adfd9513c207c0208048295808ce7992216693e00b57b8c4bd24614389fb2c86feeb60dff532bfdedb74da93f268e4dbffbe3c0db41aa8ac39399b7d3b0b60d8879bebff4edf4cbc52e84ff592521a3dfc3b01e98d42e1cb57d1fd6de43e9f77534d6b2922a8ca937a0a6bcfa4c70be0000da13c8dabd6777bcdc073e0e08b95f3a3efec6cef025145dd1fa7493930c8561e121457a653ff46c225f1a56edc767b0e61e236c3529f19beba65e2362ccd2715117aab698829e1af7ca222bc91bc101aa9b0a5012ad6c9d4a35dbb130eeadaab51978c5cd5b04f0a4494fc432b1e485fe3c4b8c0d42060d5018f79b3642e4bb017fa604a00a25016e62f72ad335a8ca08516f516201b7d116571092a6413bfd03e3b1714d83eb6f2aceff06eea44745634c4d44826fbef2f7f372da0ee6bbc34cea1033ff82d7fa2a831f0067ed02f0f1a0d79cb26b4d0521da7259f234b25b8b5532c12659de38f719861703dc9b4cd3083324e0478259e42483a61d6a44e84fc3285bfbeb65c2c8e4960dd0feb02655f7418d81ccc99288abf0486318c8fa04c0d82cdb46adc20600e841e4168baa44f5bdfe615c66395e141f76d45e31599ccd9189afb234564a1a787c5e1395ec8cdf4a3a863cd134f55e49409e6f4446d3c18058fafd1295b2e19d0666b4fa2a7268932d307ef6a9cc86e1ad21da32942b1593c2c3462f9d1ffb36b2d88683ba6d7bc918b34cd5f1d412cddcc2f8228b34e1d96933c6c39bea970472655c53f977348e1412f7d0e124b478cecbd58f4a5063ce2059e9536ea47b0e43172c2a7c76a8e7bfb3d84327cd7ca671c957cb5c8b8d14530791061faa95277e8410eb3bcbc6f38daf0d97399e6467bddaa5c55dbd309a32e6fce3ad2e8940f2360dfc8f77b194d2381e55a9a4823a2ea3238041a4238e8bba966123f548a933c8501b10bc6d8639be1053a756c20e46310cbd5bb056ac50edf1ec389f8ec1c041074590c964a2122ade63a3c7857efae06971a23a26a0b18a4cd9c2e94cb146434a928b73a7aa6f71001ae4f61d0884ab43299117bb1626ba9b503f81a302380eb1c9275de3002749e05f112d29f5d476e25b9f97b905787cb7c70ea14f39909099a739c17f7b532216e5dda5a7156e2d907722b66c54ab23a69e0506039a33a18a3abaf859e19e1609d7b3115a4a4bcb6e690e459150b416a587202d30bb5395677059bfda741626babedf072474110c7b8a843a17a216ac57a9925142b179f89e537d0cd57f3739f9ffd50a6f4c02ac5d8443fddc2aaf53bd9f0fdb018c53db11a97405ea87b44b59c85014fdf0a398caf91c670cdb0805bcdf1e741ec4d36ab77e48531bd6afffbb96e6218f79d358a84e313c7bf4805660c38f76e0aeb106fee5197976f2f9cb0e6dc90e1c35fd09f9c68e5f8e3f45d8115ec6f8fff05f772c8dbb5c0d44f4d90ce03336d579bd68d22101ef72a9805e9c7b152bfaac0ea15c8f3ac21b1420c820d9dd580163fdd743b0ebe9a26bd0d6d2197296225e7b18f3e55d8d26538c5728edc98dd85567797aef9298e00f13c8e9bb80a2d956c944b42de90731553906f8f41be77af8ad36e7cc4a58f165b262e9b30466e1f817175d3a1d9dfc36ff68a0da3121ebb820ef72888c0331d0f06b1326d76979d477ad0438ee97710cc1c86a03a21ec778c4bb7b18fa9e7c854df32ed9658c0734da9507b8e628f4f3aed61101d928b65bdcc84cd9c70ed896190f58bfb1be0d489a4b52dc003987a0b4689642758041032aa394fa7b8e04b3011a01c11d020944b2cdab16776f0de19e3fe91e0df5af3b067f760e97245383f4d217e44a815cac4131dc5fedd83e89302d9d38c2997ed03f868d997f3a0083ba568c8ec8cd91082f34175f74c9c9b37df2627262079eed831048b345613f15c2ba1b20bbe40549874805d1635716205574248f2001195a9bd87dde611de01cccf96932a3f51475930903145ed5a5c481416fce8ae0eeda25e966034254c8624db7a5376772e735476cbb0ae36264e044f4ff53f3870f21a7199cd1764918a0c628b054e915e41fdf34d9aec399197827917b2bba39c0471ee85ad4c56d1aad9f2aabf35eecf0240817f197d0ca5844acee815619c6afc4df5c393e8c306f5f26aad7528f80321577e391950e62d8679be6e43120e186df31a8091719dd077c32d82a2f7a90a2ee14eeacd131aa6dec47637b1ea59f52ec76e63a9cc1200f666325d107dcb41239f72f0ced12982d2b6cea4f16bb6f4fbd6aed01f661c877a80610ee1007f5e1cbc83c9507725a9068bd3f8136bfaef15da0f27966aa17cf9afe610771f678c5f70f79d0bb5bfb4b693b9ffd0928c0297ed92f60f06563a4fe924757622554f32d673493135cf3a9ca668e7ec46e23ab4b01735857d18a6bf06981958d7ce7829fe0c12c34c646732fa1ce96141a65e5b99ec6ac4b8c131eb053b459b91ab9b09cd1a223bd789ae6ed3e1cf17e0b2c76b90d34f1cbcd5a002d8354ef18c01cc9dec8dce67e989119841dc514f427ec2d505453fe1d4a932f46bb1f8e7d9a65cb9fecc307362a5d7eafc3e4605e7b2364673ba95043a78cce173ac38c710b2620e06c5370120c15869299bc88b48eefe98278a83d35c46168fbdea497c34c613b31d4e9cdedd4628c4639bf2526fe1121a1277b03dff90605746b735eaeaef73fe08ef8e7e333bdc8e9c00c245840db48aa3beadf5538b3ae43f098870d05125cea03bd43f6cd4c055eb8547bc74ca32d6378bd0af58a846ac0965870a49fc74a7ca9f4369cfad9c21870220d76c42fd4eab9ac029dd336c0b6afec4f3a48c58551d04c6d15b9bf18fb9c2c2890ada1f046b88fec1391e17c60ff0bb9bedc271d6fac69610f17e8ea37fe74a176c82702f4cbb1c1ed44071421a6e296a1945363ceff1ebdb3943e72452c35ccf7765f378c4103cca698204c23884cb6048f4576c7cfd9de75667441d29740018de41d9e68004915b9a715dcb142480469f44b298bcad5d7f50a110472c98efa412de53ca818e04066d57415b8ca81013cdb59a006c157ea511efbdfcdc58d86cd3b2d4b96b209a53591cc17e3cb00762d5f62255618be056110092945a09310fe890d789b2c106b8b6c8abd6b54066246732f7e5575628795bf7d4e503358f93505bf1c30f136a43740e99322ce49bf9fd6ab4181a0f1fbb2755d8d993d3827107d6d6f8cdfd7691de9d8ee7f96212cc5df2af3bf437a2663719d788c39bb36a1d9a59a7b5d7ed4428581c248863bc71c33f3f8a9064a504f41af47904373c583e04b971b4996907e236289a21265b375a329fd217223815c2182639a4c54c03f038f01f2cf302b8c1df57710c4e41e58a8dbc444ee2cdc05aa4c168ff056099f7d1a9626c762e9992b459eb28c3f7db9ef9d4b63160422801b711f0413e0bb555a08336aaccb2aeedd111bb913ca118319b0061ca2bde5d6bb509adcceeaf11d2ed69fc6874cf7fd4021d8d7c8d7da0c3db868499997379cb22c41b8a7a408e7e5c1c5450835fa9e10d3cfd2fc9740245f260d4a0d2bd85cf0292cc27e7fe4858cddebd82137957308175dc04811a349e7f85f2c1ca58dfb9e04cc843b66042e0b40443f01f505360e79d0c0d0d7493ce4b4e7c2e00192cfd717b0b39e5ac2e940012072d8772106cfa90d9bc180a1c6dbb3ee876a19952000e51dc6450c02caa5ca0a11a12014e4239947749683af4f55352056abb144395d9df4d8bf67d4526925451039bdda0d1c744da5e4575145989108407320efdfe34a1165aa3c4608c0bd1a333bc68ea071363b64f8e228a9734727b43eb87df8410c0c1b05ea3eaddbcd7f53bd179817454c7ad158667143be6f7c025410386475aa646816fe4d30e6510abe49c585a5e9fc61e6262a17ce2b153c192ed05ac637a34db89f52a7180f9e0022be561ff29bd901111b5f22a98fd0ffb698270bdc19718833fa847c615f253be815c2570c5c9f87fb061cc63cc50741a52160eb2f6154dd41a74658a480420a1ddcd214acfa5f54f2dc0f108c4753a11d7a9b8641e7c9fe3744ed3d183a6b888fda6417d1f27c53cac96ec2cbf62c6268b240234e4283f07323b1a7617f726151f2e16c668a78cfc22507b1a164f81e2b0746cdce2d0db3c63f04f82456189b9469d6768dd409c370526c6d3fbcaf1af7d8dc7675b6bd63e05444eea6d5e41628db2035349dc171e3af02be77f81a6822d85c29bd5dea00b6d9e45f2afcd18f0622fd179c0f05209da3435174bb789ccebe4a627f11a95692eda3d858310b7a036d4a0eef435c74a5c9fa344a9cb37983b97343b4d2f50a5a42bb88854055d14828fd99e672694f309aa168d63b7a1e5b8441d5f799ae4fafb4c7945d8cca24d40999fd8981889073c7dc3bbca9b060a0ca2ed5c130920b3b0c03893bb8fbd3b5b9a79d92bd31cff9a8fe53deca91d0f3f5c3f7deb1221d58a894e0ff93eeabe670a146b2f18ac119a02b2c74edce75900eb87b2573e091034eb1c8daf9c7a131de8429320e6d3e9116e789e4a53fc619cea1e670b48305bcfb27d8dc05452e1f851c3978d076bcee70dfb8620318b1fe7c9fe3ac3305d737f7f51a738a500a392e7c8e0f2fd2dd7930e5392daaae1ff131cdc3800f1bbd40978907523751d460f1df51c0e8c8b51d9a0dab61b7f580489eeeac852ff6e8ffc6f468e8f9d780a6a650e9ebc3abe5d797e021a0f7597f2c6346252b7e8861070c1159adf9955993bd1eeb7d0ac155864f4094f9ac658dc85f2f32cd9eea110fb58512ceb393c8ae90aa9e31012d08ece5927312938ad0669c0a1230408bf6bafc395ff6d965c0aa9b0687a66639093cba3c5e8251e5f1fce2502da951447c43d5d1acf9985260f7a092b7a5b3e929375e635bd6a8829a1a1ceb4768a912f6249f6ec062a0ba9c0334b4b0017de97017fd2a7c2de60ae95f3be46460010ee4bce35e1f7ef15fbc0ba6970f8dc202fc1c3937fa6771c8185e65fa062b7e1b7f9a2ba3e7cb829abe5f5c3a527f60fecd62d271dddf1b7ea1c4ff19dc0dce809f26476b9f37b55b8f74012f2352683abb408053415a89e912a48b399f0b7df5a15cfb7436c94ccbe6d7ea3c94e2464e51a7e438a5ddba6f93ad9369884be0034d000a401ecd5b43a68ae644e7761f535b081cc420ec76b50165d94ae85a8e6da6892538117e41ed23cd75272cd98b6ac35925b03a17492c23875231abfc0f16f7b90c3b58f4f92d8b361d31696d704bf459abd1cbbc3aea66baab105f7b49b8bc79e7193aa07e696442f3a327c5d097f0bfb2f6cec225cd137807a8f87cba1b9fedcc816e1a0bdd6e2948f07e2b6fb0b71e3cb8886f37e0bea940119a8208ebb4d06106338d04081291cdd753b1eecdaa2270c16b2093c71d53aeff1494867d0c4bd4606785e24b7ac400301901f4209c54a911466b494b4fb183f347178c0747ff1dc6432d6b1093dbb36e292cae9e35fdae32ca9486c3c0b15441ccc27a90c062c03766fd07d77ae2ba283ea85f829e46c0231099d836da229458d5c700d3aa092d510b2b4ceba1ec11650b985ba1709604ca8804c3d3c18a4811fc433980e7d99df65515c5790f10410b8052080ef208b145ab7ea40214168461ea56d93d45a8426c30cc2699e812ec620d71cddbf31eb3974c35025e7acde5dc0ef5ac054a6e30841c805986cc1a42d1a501c0abb8e6934e1b56a40d70d0499de386a66287de65e84962c86645ecad5379ea2882449035d512649a6f6c88a91085de595f4c3b2ebab803d7323aa00c0a7358a47d83f2bb9094955494fe6853495c4e52133840988ab8a72b948578afcb2b209c126a344d56cfe56b2ae33b5b89f96c7d6aa35b788bd06ef573fb71a06075868e4744af71a4aa0b665a4fe79576219e41f2ddb8c77c498ad2167f11aca8c9376a0a199cffa877ba059bf4f461a1373a93c450293c3300103d08642af2b8c1c1ccfbe3fe4442194786d3ce3ca22015bc59259a5ff83908dcbaf623efd2c0a908191fff58aa355d48b44b1a82dce31b36a3abf6837882daf5047d4f5d546677f894b956242799e3a525b7ec3e825f4e003055567cbcee91b265e040d82581a7c19f7952547b41f157e5752f88bf60c5fe62ba56d0de6f45d130007c4de68ffc66af75ea5e89235a5f4b90a00647e79a3acbc9a0e33691e4cb1f18d0a7810442b49bfba1eb77450bc27fca89d6c3f2e631e3c2d040cca1f5579891fe1752f493555ccfb29e675fb7d5ada7e02c6d026d049a3534b342196b075e135ddc6078dcfdf4422e62400d5830233ab6b24105ab164512913578343620f3713d31a6f014b4850811dbeaf506122feb2041250a77720f52e746a6002ff074c9ee00829ad2ddcfcb8abe4b1d6d9832f9427673e9b8bc63de25ceab83be3aae9778918a1b82d6549683187c900bbe43571c4dc3673c480a3de7c9a8fff20bb320c84f2d20ae2bd98dc9cbd220330e27a78bcb1ba279b35e39ee18806cdfe7d7f6e3af5bb03401362a78d994227fd90ae65a5d63996280d857a8999b02e215da8d623fa12f3444ac98a94831d38b07e90f2cef0ec21ef7edb0e575a855ebb0a5aa777093bcf435601b82bca2b22949166a751e5ff79b046b76d730b000dcc8d75f56e7380e810bee5775d244a05f5b8c9568504f39dedff95b53ce24e68fa1e98af8cb77e5631e6dbff8f3deb62620b04ae1561aec71c8df9ce27bb7b7d64bc0b8de3c2d8525778fcfa4252e51ee6f1f366889365494a0853aac874dcde127c9941911b8606f46a9cd6a85dc027b7bc9cda337d5bfb04fa7bc193d2da402cb1e9c3f3d053b6301360a3806692be13812076fb9bb56f519ce815cca7aad43300992772fbabc34a7c2a30dcb375080de4403dc5a109d0ecc2f8de6f19c8b263398b839708952cd354ce68dcf2c6561110235908d65ef5eb404f77f97fb948b8c82108e41d4337ca53dfbe15f31db3ad487386435507d773e59f90a5e5a1a3651cd45b02773d8f71e4f8064efa3a902e815e1a0fd98446a1491f84d8df6c8e384115fa6d1ffa3265a184d3b98ccb21e885831ecddd4ec90663367c0620ab7810a0dcb19f101baeec58e171e4713603e69ef69c946a041c7cc1ecf088ea2956b55c8a9ff8b619d52cd08da70aed2f47a20fdafcb5d4f8912fdb914b328670ad64da9b0d335190d3399de7d611b9c6256b3bb128914c3ce18b34abefb09db252f2107fcd82efc9bc30190853c512156166a03f52a45922e9892f7c017e58bb3e8a7f1f538840317ab8bd931dd20cf69c64b4ab6af0cc35c56e786ead61cc8ccc8bb3c3c6bca3a0808ac03b8822f4747141704e0a783b94aaf7b16327a9787226d4f90786a832c5f2ef2e6b64111d9015073f4c8d67687a45db95651307ee1df2974ca5ace5481e1f1ea2bd6e4e41cd4036b4097fc8ca3467e030e785833f87654bb53570c28f61d52ec5aa93e37dc9f72ad8a2a30058319f8abeee5846d454267c231c982bd9a760a09dfb7824dd7ffec872384b01efb78653f9d84baa3e492c22a741d1b90fce50e79a877a28b80eb23061ef2c3b623cfcc0cb8a13c819cfe049b0b0d376bd0ddc1b8d2df6f249735a5754b6d16b42607981549d74e0538d751a716192777bd23357bf88fc3141d404bae76ddf7fbea845d6c0ab2472301c1a6d12274f3d662d91f3cb94222f8cc10e161063d204f11cc2152ae5a6116fc294cf47811e202a8296874577f8aa65c7d838c4cd9169052fe26a6382fa9f4ce52e92a659d41b6312bd1b50d2860b1c7dee8375c43ec40900223d9e35bdae127c9b459ed75dbe4f9caba443d2926514b6440a11362a04ee0cf73e407280e6d607f3e5c0646148228296f92815124cfd761bf584c90ee09ba17ae0d0cb94f414a65808a15360559c408fd0cc8bbfce46765eaaed9a4e726de66914211222d901d6fe45ce9b8162f1f60d9a90b31dd0d49972673afb202fed1ef043630776898c49ef67adab577e509a0a1a6f28f7e3d12288332ed022898c6716206176d8c9a61024a9e442adc7adb34ec8046447b1d0af89e0853c9491e871012940af7d30558190e150fba91bafea662a298bc726de678e109046cdf7ca2beaa64534234650af2c3b3f5e39580f8c8288adc95090e0a7bcfb26a7f1d3cc0c815e96e2a1c24bb699ab000e8a08753cbb53d45367116130238a4daea5d766deab0cf1b75376b3e3790f21a524a274bd517334da91689bf73e3cdda52854175b0e0d9058bc99101266105f0a24f29c8ac91420af246a264fb2ba2e0ca20e361414424f9a4529d1b34ddb9ce7af76f6c977df90edf25fe1517815c1e021de8c90025f64a97a0722d9afad4ab8766758d2f4461bfd50c9a91f8ceb27952a466a7f01bf4aebb3ee739ec2fd7e2d0f1eab3336d22b5a8dbdbe802362b14496f6a6c747ac0ae1dd13c1d084eb33d7fc1acfb77623477a5acb3db14f36572abe60141fbd4b56ac608bd45462f44d28fbf432647e2bb105443529eeacc5fec45b665f5009d400c76dd6d24a99a7a4ff2fff533bf9e931085aa92fc5c9ed7875032bb3d523bf8851b154cd57fcedfe464e908c1e984fafeff246af3f8082094a92b8d10302f001af04abaea3892e90d9085a04ce7c686dc64c9bae933ebadf1c556abf84f6d6b9fbeed692fa12c6e906264ffce27a9be730150c76ac24735756313f79fd5693f399bf50c823d5fdd8d7230d389afa31f829183f079f5e68822f1d0e891fc03b0bc384550475718205b5f5b1ca2d4b5c15acb571dd3d99de1e346147958693b1945054ede4800f78c357974c4168ce71a78703d63ec9996fdd4e911cc6cf43a941c14e66f2fbd3c0433497b45546e9e244fe17ba133022791eac05f9ae3d27fbbac14e401ef94321f6e0129fd0b936f4f125978873d5d6931e6fb576a4cba0c7834c7a451d8baaa5eb7149cf7d86c43fd55e3a9d311ea3b297f54193d741dfa7b5d024499735d23e4ed0a810018b7437735935ab0d0162850f01b1be88f6f6124892448377a29ce8e4149cace7186409e9cf99d90090b3d007d3a83ff4b652280772fb9f3f4eb0ac5888c06fe1d7745769d312fdb9ed0186a13b03b13d2e241a1e91ff2371de143e982ca0b4d99b74296e47b9671e3b7d90bf9858be611a5f1d433e0fbb5be5000c03405ca82d8034ad2afe97b6ab6421cb6877e2a8000308f393007a7bf13403087068176e16a16ad61a4b5cd0546a601961a263f922adfda6950131b301632e0ea696c1921c32e654b658285a2c267501907930620641a2a028dac050e0d103627a2a6a154304de401721c3443c231988cecf63b6b853ab5ad4c32b4a1086b4c8b1e013ba52f26c96c8254ac201f85eb73d53a56eda2e4b2caf05ca4c90a9ba417e111b6d17c84082370b7e0a0951594cdc1e211d33c11eefd09653f4028ce32b8697b8837bd56e216e73d71669328718c2499b453ee458745c462c386b8f3f129382e3a4c54217bb2156cdc131286d9b68bcc7af32731a8f03d4bf602a4fbf9e14869f0aac5dbd281de986bcd23c2e00a91599f302ff39f6947aab6a329011f584191a58637c7a44f105d6b39b41947686418dd33a36df60e621c91e2ea9e0558073f7a20385eb359ee016a9c697a17ecb78ca760da0b1330a7de30694c6518311058a8502e3862e507779d14149c4409ae8b10be32d70ba038201102ba80e295da21db101ad32a508796f5e0597a49c03c04f33f9c108268c861275bbb0e12a9d57425832dc42b682d64e3c9af3e157aa4408cc48d4f16a59a7f4860950172077d2b4693275be446499064f113846ef55aa755b06cac23d2179e3a951b528866f2872a4b5b599367e0c9625babf1919b3891836321e74c30a7701b2cc68608ba2ffbd986139883a47e937ab0972719d0813605bde34bd62e2106baafa345c03d6a07b8c8181ec883bdea7d6e5aac78414ae6402e608477a9f3d5d2f190f817d8be1a80f78d2a304e01ec631400b92f577d585967ac41f03511ffc78bb54a33cfc21317011a46c1b076f84cc4f06b42fae1fcfaa409ad5b93e5f6be0f0a60b02ea5024162856e3c263758b91287a95b1ff7d6ef443b6df104560a3fcd454f76fa30a5bbf6aec7afed8950e5e899ceb586b5f7e4f112f5abb49705059d4f2339a709d226c4e8ecf57e300d060b4e753e7571a0a71d7262c974dbd14d16f4995241fa9b9f8abc9305b81022f8747fd0ebfd7d49c6700535909afa36bcdee8cf1f8f5e757f4fe51c4d37b2d23a58abe1027bf70c445d4fe540143f0dac1bdd65477e96679efb045119353e2d8bbb87ebef4ccba05460030dec2f105e4ec8cbdb6237badf6c66c009d4d9c048aad6cf8274b5789c809dc8bf4c5b48141010977d55ed8a5c1c6b1cef254fe8837b1d0617638e48474d70cf38724d6d5e7442e4cb0185415aa02b463002d052bd4ee3f92b7641c1a33e609262611486e3caa3a7671e275e84e803b408c408f922470b1129c58a563941e8d4eb1784a614805c5a56e547b2637062a1cda4e737ccc41f1487874e0309c8c081dabffb52347eef0de26a73abb341f976f82ea82297612051a4f8240150ea5fa0b07c6521572b4cb827e4657c57e9e8e08362e68612514b75efc86b805af9cff34cf78d74f7f808d471506be09d0488297c168917044de93c68c2776e578ca6b1108d79429a8ff8c721a520192bfd560ceca52390b16d06c8b649aca0bd9e9f3cce24d2bf1fc6353aca13f95b1a555740685bf7fd9400615e76b6f64221419a31d5f762466068051630aa8fb144f2f15024c36d239a2efba2522a7d8ab84d563805cb19ddcd91c716b476c0f1538cbd034ad0fa73f29ea898652f712d060cbc2717a50dee8a4f2fbb86a350796e8676ae1da0737a83736090944627c91775baffeeed78a33f8478fa68e3cb496e129e41da07bd6fb2c41f17c7c24f803372c542a0ad7e46a7e0d0c753d95e60e8913ce694113eec95d280ad4b55488db6b71350fc6de4d477aee70885b8a22964602ac0351fd7aaae7c3a0f414239d150aecb50c07754bdb8c7e566470a58f38ae4f6b4eab52ea4ee2b6cdf970e2ee609179338d5ff506d46a52621fd44f5cb1550d507443dd1044e7f22bfade45b97690906d19f6788ce2a4383b64a791dbf395d0b1cf9076b1cda679908ee4a7ddc45a14b725101b386b17e493b0ccfdf647a01f5f115273c2eb9eb9aff8e20c7c2708091262211eddc41434516ff09dbc28c36fc11b19c6e44181070af03b30f8bf4fe41e69b27bc186871d360d27b5775f93b7fe8721b28ac5d814875eade81f8b656c69e00ed7eb1819534d1248ab61d52f84f1e004a72caf5c8df0846beaa4e8e599823d78eb383bdaf47f70ff92ba6b4fe16b352a57b370777ddc87ae43f2b9f7b3a8f5c39a96f3ef7bc82ba51620f89561aeeb936e806e0f3b426a4ef0626813dcc52aaafa76fc47a5c2b943ae8594d04366b1672b3486073d7e298e802078e9464a56fe77548afa6d78f996245e623568888b98e57b1a016f3f15d1cb17a2bef10cc2089fbe5a2203f6c505886104be9b8c6c5e7b3c3b18404d5ee37d254851d495a77ab348f0ff4755e0a38081f1fb738cb5864735903ab0523cfe065236f1e6a206dd86effeb3c58565744e24d26f813aad283c6dca20283303724143ef81dbd25b625c47fb7cb478cbdbf53d6391e4a6d6df4cea26900b91062025a850b70b0feb918ff7d43dcd06e9ac72b0e7bcb43f5db7e8be0200c2df9156ef91f7aae0f97fb8463080cadce9d4507be5cad2ab54adc68bc22e64fb3e3ae2ba58f99e8639fad36371b889e7f899d214da0418dbc3c4470b87552d8508a14b7f7201090f522b13a64b765e2c42ba472b5e0395681c8fa2b272207738c4439377e2832a87bb14b6fbe7d90342e9dc69a3d8051c6fdd602dd5d1f197f862a4023426643e8f0b3361c5ec2fb76cf0e47838fed41ff25114f917fe9d96bcbee1dcb3ec976a9e2e55e8ab01abb7afb39eba50a9506845e5ae168b13b2f55f0d9347482ed87540484d3856f17b81f7bf0f1edbc3eef5b7723b06311d84617dd769000aff6c2305767740a4a44260d4408d5ee0fe6d867ac9080b378cf41c80f1cd3aaf18fe8fcd5b15f203da2df112c103d3c4083f9f184b6ad1f22425b1f188cdccc215f8e0311a8fa202ecef048fa9f97471db630271fa81ced5d8f4788d350c0f1d85832c9e7611a63ba30e31db103e2140cc352ee720e4d6201c01a96173a37e3478a59d6a046d5afa24b3473f368af8bf0dac0ed40cc1f7ce3c1647ae998804bb353ac7f65881feb846f681650c856ae1a2c6cbe71190bbe14c0a948ae24765407b168ed6f25d85c22b7f10051d8aead42d4d915b70599c57662a8d5fba727034a91af6d705d432a5c688a0389ff69164787251c00f9217ef9fa4cf00c2536ceb1c039db86ca2ba39f1b63921b941e1d42c7e98f0e290db381b42d7ada32fb6f4b07127ddcc992e2f178a610d5acc487934e0578d07d1b0a5d9bffb75972851df09b982e8340f18705f0af40143c3db451d0821600952638b05900c965a2ad665938d625123f9ac3673cdedc791d7704c3f318a08aed37e99f7eb27bafc2bc49f93446b28ebf749c27dd644f8fe245a0d21ad06b16b3f185ccabd017d1bfee04c4ca16d92a3c2f8fefe16819161cbdbbbde145c0dfd72491f31d25c6b9fc661a5904589eb84a1c48aff52a360ddb3ce0dcc9cf64740d1ea822a08b2145aae2a0119063906e4ecc3706571d595ebb63ea13034012f21fddadc68769823642b863f9d33bc241523b221ad37dd29893b8c5161422e46ffdbf0e78800eadb9da845c5d5321bf1534213fd2430dee2aaa31910b88427e2c9a42eba7ebc52dab082a09142ae109f9f5bc392a22e4574a880323c0132228988b0dcd98faf8eb8698bb6160aaf3c5322c010bf6e1688bca65d5f791f5236bc930cf7abe3dd00096f3efbcbf8ffab1f34b365ec1dabd2b1f859c7c9f062b49ed5ec2009bf90f50ea4db1f983d5fec538dc358a2ce630a96d0040a8af12bbc73b971fafe33d98a6985f5def9b6c8c9cff80b847f6e144d0ccc5f0073f57bec3432e0bc4d7de3c05290edbdec0777bd31e7a83466405a3dec93b3ca3f9a7ced23c5961574568d370293ffe64c7bf559302ea6bd0fc16c7f59d372fca6ef20e24d26a65efbf96721e4889cb4e610520543158643f43b18598499627fa4acc8632bf9e5317994a99918f8c654d4bec62411b76f68680ade5500215d49acb8331cf63018d51fee0f665d01bc3cec895d05bb6cf8f0603014c2a1eca7afa0a2e282b7fdc63b094f293a1b6ca80026526290d98197b521e2b5175ad6723ec71cece2e6f650dbeac74610154c7c1fce1f0dcc713a6a426afe73692097042f0c1b9b7bc4c4e61bbefe2818a979ceb0404fe60a730e8b8df770815465b5d7ec234ef8aeec66d14ad2f25102170c8efacccff3a93946f7350143368afa0bc65de027db0db117978c073317d4838c9a5b140abfd68d9f1b136937a1edd86604f095f1cb094709e6b6ff66212ff29c0ac106d161bccb4aa66f383263bc66c924793909b3ec7e6fca29f9fcbbb7ebedd1cd0d5102f4146359f1cc362905d0faf32a863bcfc016927c1f6486b31193dd5ca7f3de37561ed4e18f14f39343c148c978b5be431c4349b511fd220e726eee022de4cdddff171d956914f188382e5c83b2317ca21266bc761aae7648b2d7a3243c29d96e3df7bcfcee559dea2f52f31654561fbfccab1390e4c2c6a436a66f9a453f8c2af2e647b577788ee386ae6984d68ebb3227edc559781751ea0320e1626b75aff587289ce04a6a1fe04acd230ac85f9ab58b9994a8732bc22c2e25434e69f88b34f68cd3e09a383c228647930c903f88fa2ca6b8fc7f5ae2cf46b99da9e6efd7c3855406ecd3ab83abdf8edcfda9283ccd95d17b4e500ede81967fcd7798c2dc9759894ed46ae3ac9c1dbf228ad8f15742c2b2efbfdb287e574822c51140eae7983d9958e40ca8f689de5361685c20eff44f0cf0923d8f5b6de6d28c2e0239e15dc55ecd392dc68f1063679df00b8178502d7943780674dcf5dcfcabbcbb2853615c4130b5706aec20b074d2a6058565c0b7a12cd0e6880fcc221f9d6c184ad336ae21d71f187bb0014d600f2f7ae93a764722d60ed8c96e12105a8acc09ca0daa53269ab0da10827c5d8ba322b2943953bad198cbd714bd93c06f0e017104a2c08a56cf5121755040e68aafc11ca5d2e8308d62a4d761ff257a5119a63a485624ca89162a01abf7f0227d8ca07dac6e54fc06b236e672345f07a03828daf27705a77964ba15db181912376b9765ddf9a2a0f62ec03df15083d9931fed94972de4bbaf6ca45018aaeb49502ae6ab41461c6b50e512be7bb36d590068a55045c1753e0c41d92d11e096329a5642b273ea91f7042794928ba2d92398d9365aca43b40c99ce0b2868983fdbb5e3e4091bc516848fb6fa85f6f2700a287d93874069b8600d101529681fa52890e537f331a79ac32b1930a41f18503666875a87be7b3ffb93266f78c182cebde965b2b114b67b21ee8bfdc3486d1cf380d17c52788ddb06dce4c298834dd14a032f791edf2b096f83022fc0d5420b69ebb9d739239f424090556cc8139082419ac90fc030f91dcfef2df8cefae62c01c9631f1a7706681e1139c7d25a2e6541cad2507ceb3c088487e8de6a0d60124f07f32d518c14e9f35c322793b89c74d60b6ac7988061044eff19ab982d0070f5134d2e1d5176be0e189470c26bb94e465eaa37f5564fdd6f2b75fa8449b964adbf95efda31a0786ddbb54e6337fe6a6a0a8cd8b5ad81cdc83b9e42899eda552da5c0fbe43b7bd40430ca4db196904acd59fc9dd6d2d9a1fcd896416c28677ba6b741f49e36cce89abb946c8b658402d3e71673f0deda41bc7fb6b6487bf446e944f04d7cdd1fe35d8c11f1136e2238274e338fdb982477072d596b83f0a4c56bc1a294ab6c403d4e2c93beb83bb2afa51d50f603704486579fca1a56c6823972cf7886c78bd09b99251d1dfe0684bbc1415c309ff09a348ea73477cd24f1fd2a87a78f2cb1003fde4e3b9786600eb4976e066c3f6418e25dc6ee42f9e587de0d233524e872570d07162edfa3770a0049c1c792098b8807e3f23b04569b2e5383648e10fb93b0c8d790e1a0b5bd85a7ac29d15fc5d77ed867f1310cc37fe6e37ca687a518c88dd5535345fb8b4719f20719615a0db182cb74f9576b3b8f1f8a439c04172a293f0c4eb34759cf7cb302e6ad0ad0527e05891b90c3b5122cf06957b37846e12038225f01bf6dfbe94e31b675c36c9b0c65c9db294c0154cad324a36b72413ee68af50c5e8f7076af3628b2230fd72bf44a721bf4cf9cddf65c027d642a18db7dddc0dbf1212ee4327657149c8b0189933b3a83a5da495d9fd6cb0a1c2f4520419ba8a26d79528d715f10335a0d4101d4f6da509a3c2e3cd32c0efef852114644575a7ed150c66813c0b7511e9463182517aa608fbdcab48d152bb9ddcb0494171f5253c86f8ff85cb1c905e4780910708422172cacc0962edd2f9d7b08e56756ef9d0965228d5d7c128c278b456c403c5756467cf3764a5987e0fd0693cf5cc8e75bca9ad130782410cab4d51691bf04f3b4130cb514f4de8b4e1acfb85ef18c3e689b2bbc07cbdd64ccb88fab44ba4cb9d7d7312ae0d4ebf8015fa4f9842c83268f2444bac6cb057717048eda2907d68174555cfc1c5bdd6069ec460da69962490f44e20041f43c23ac04964388e08d1c2db030734c10e6e84b17ad86bda100f678967dc6a9c8523469f1f362c7c1def807f5914d1397b254a21ca9d98dab989fadad6fb853412dfc3f63168e9e253ba61b39b2e3ce0165c5fe2de1730d6028030b144c3b3db810f773ce4f98dcb3ee5084a62ad2d076a12515d790197eee0cb0dadcd55cad4614d7d13468234b78b4d29625faab6768dc806c139011752dd36d096c57a4d9e4086915bb9d019673286ae37b02506283f13f2e272a31dad8dfb9eec4e2b48541ab683441fd5854d498757c5e0b0d2b3e31dd9b58a129671243444a72bb75e92fe7f32779320b042e8e1a908fea768a3c292e09320b415865054d17da8168015f0721de685faae1564ee66900744c59ed23d2a839c6cbf582341f8eb41120661b5363188a5ee9431a8bc29caac697344b6abe260a5d304be621a9a00cf171446d6d1de576bbb97864c7792b05161c7c34f455397eba9c509cac949bf71399bdb9ea97fb38277204bd22964ed90a0c0612060c56f7106af32da9f387ffe107d9d099771e509554c1fde9c36a4b4ecd4358bcebae2e29ed99f953e910b5891b7269cc9067f2c06a842afd18d157f86eac1be24a29c9c436ded017fa41a3a4adf75d5bb1cd61b35b2545070086dfb96b246bee7424b3323f379e3e398a527611ea627fa2423ee559034f58e01c67c1573971e42675fb637bbd0f9490d8d8b0a05275651c73d0f6ef35656b58fcfc8a09ba244e2a820769e1316ef82788093076d1e342e595f2b663217e4d2f3260cc6b1c74d844440bba0e4feb2798c03a0a0d045af4a16f65038739c54ee840df2fb9561d32cc8ff709213191d6631e313b95fff0de876c058e23f9d1eba5ffc141640f445c520680c96e8bf7431062921c5a5eb5f402efa7db7efb7998497e7c0caabbc6bfa51e7311ef277185fec4d8e91e0c8d8438e9c651be58019da1fdcbe97d1a046b9c0114488dd928618f71202672c33234fce51cb15f4a6b2733eedc8590044a72aa83fe8a3f79eb1e1bbbdbeb00bab7b2282e801957a693a4f4f0e5954cf88326ca59fb19c002656c12b5dd22e710cc14e72a947050735a09f168582d782d459c5424944948151263cf65b3ae5271bf377e11f235e82966524b1e9aeed22dc3ae3544ae660aae370792182f07d7767b4cc861193b79adf7c8716ae767b1760f958be5290b6fd1b48b0a12bc79be3a6e2330038bf7268d478f83cfefa3baef16f279a6717e616d586e693846fc49462ee5936632e0aa65b05834ea6fa78e6d4a9384bb905a1fe1b5d4fb6788a109113d9be875cdb7e33350e15d038d44b485c55f637f4cf50b8b6ac9769e400d78ff8f8a3ae6c7eba2a4be0763fc70e6350c6a1a2a64a18fb9c64cdfbd52428255502e0858de1a04ee3297136e9c5e588b50cda1cdac118452315f3282082e86b0c4be17073913718bb8346dd8756a47e59845d9901718d53a7b58ded58f442d2a6f1fb1d35b07fdb0cc2cddc5f0e64eebfa18b0b5e6ce5fe687cf1f030bf7c5146dd74c83b1ab7e104cf47ec0bf01947660ca532a778c02772a1cf4d23827d2b9dd3c79e0b9409d0d91cadfaca5056eca7204ef42ed44eb1b1e9443d81d17aee5f0fcc95723961d6d5f6389e86a1ca0b1ee7a30f463e39954207a5049280d2beffa264e30192325a59caeb9573eae34741cc635bdd2322b11cf113ad00461732dfa3458d5bf81200a66f9f79779c844e20845b8a8b7b67a0e64edafa20858c3567d3fe433a7954287fee03240d983a7cb93b46c5fc80ea253a622866a994c01d4bdfc3e235e551392b064b4a434e40d45950006c38b448ab40ae852f9b52c45604235dec6145f6a66bcd709c71396c903a196258591d6cd9bcb7b7bf70b0240106b47b5949f02490c1450002bbf9e312d0fcda6ce5b27e8a6a82192700054155ccf1a118a0d84c91603ba9075492bc4d380275e43651228582481a1a7ea22c35f20be435a52b664b1bbfaa8bbc86861e077f48c84fc8df7b8eee2f522c5b0e756df61474d3e13a95c6fc96e92aaf5da158307abecace3ca29e5b7066b2db049290491380a641f3bf5a87f12ac448a27990676571ffc4a4d4d1446a7bc8f25f5c5bd609ddd79ac0120dfd0520f4f3382e28dfeab834166f4bb27af544399c117df06450565394917c364a517a7a10c310d18f3bf7ebec3605b704ca42242be2532b00166d6a3534d74dbf16085d493c6852eff9a4b002f6098923ea8707857e1f08087b0e69cab39090569ab59df8e5f1035e4e4d21673831592b446a05eba947988535ba06b3ba45bccd54845d26d36a4a8acf5b6782e12a55d90e55fede0fe5f443b57e811114263c668e91806da972a6f6d3b8e2c66237699a1c5a1ca4396a91b1531d458adee2592247d21fa938709647b1b428d7ec9e783b807ae1f835a8327aefc9f4b359364f9d6fcbcb1c4870c0034c53b7dbd09452e449bd224f1854843f7d54000a7d288613225a6c66381050261fa72a2f9d7912240201ac735ebf77e5210e5befb703ca4a6300d7c0424639ed8d09e06c41ea3a21a87b3950392a2f783faac210726220b492b38f90b45b46e671223379a6e606cbe98bf66488c5223c665151290838b8850524ef971ab8d918c70948a62be09aadea955b105ae642224c6762c520cfc44a86db2908536e7ac4782fd7d2f4c4a151aee54982a1b4485cf6b84f88ccc5ad420dba073aa574da294dcc89232b951f5cbcd89abb9eee2a80c5a3ed2114c21e24537f47c7e52b0555d7db24b300e5acb4375ed269673149d42a5e1e64bd778792ebe96445ed33c946f00b0b1182dfe1aa888605d893c398d48892d0fe6016fa3de9665a7422503d10995676f1b4991112141d832422f23ce245c08198b451c7bf9d64b9989e4b5575dc3f70d5b95746a1b8fb26c7ca9490670908d724c3708996af3b9d664b044f7e4950210a2896d13e54a8c1f7d0e6e72c37b53195b11f30d1a620462c02c65470738455bddff7ffb1cd289338ee9cf3bffd169a7650f9ee481544605c7ce19063a87777f180eb77f908f230738a822bfc675d2a4ec8efe0d24fe7fb14a0ea168af7e41bdc822cd1cb72f73e212f3f3d8cffa62197a2795d2857d0aad8af5771079c68935f2727d1930466652cce0dd947aac90e430b2a3bfcce0326298cd480b9a03f2f721eeb4506f5df67403669ae6c7688576cb9dc4aaa0f7f05a11db6c48af522f74a69b506f740c4ff115f2cea0c5d2a93d8d591175445daab3c24e17e0da5b6dda585683494afb3c7423874a235a89de6ea4dacc0a3c48d6e06d83687faff2fcea016a2822cc25d578c75ac9f9b68ebb531307f8ba97f3645361c921369f25656f9b38e547bae0685105b34d0d0e8cd3879973c2ee6f1d99e63a669534d9fa7baadbc97ff89fa9f161ae23dab1cf8e388d355433c816fd73404dcc6901c10c6cef13b9b5bd7fbd03dfab0c3100e6e3dd88187d78b3922eaa803e0ecbe3e6c374cb85dac51f0233f075337912e82e1f884e4018ae22005352d4d3d159d81bd40a5ae914f07f26926a2af720f373be19c36239f2e9b50cbda9dfc7533208a04eae2cc68431bfa0418a0b976d3a204f71c2820c4ce2db4dfa5f66d2e966114c59d143841bc7e82ce9a2347ba002a6d5777fa5f8588185503bd70362e15a845d103230c240cddcb4d0edada2be960d095aff43f20d68f34271cc69cb4d40260c368066823d03b837e0f44c57a602ca1b70703dfdc05bf56f0ef9acd46bad10b58aaae821f91b114da682e1ad3556f4c28875c2e5a3bee0378c12624825c4cc305d20b162ccf76502e3450747f0795210099606813a90863cea75133814bae7767698a76c016faa3ab21b61c5498633d55466f2d990760c00fe48e7d64417e3a431358598fc88f0b78fa200165b40e5ebd40e35decaee6fc696ba546c929c72813384f43923a4138742a443c24c5dbaaf6184b6badb6dd32450eb05ae99032bc5b1fd2204ee4f1d149f836b084573b97cfbba9bdf45b42f81f25223bd427fa528e3718e6baca056bc083b6f89994c838f910eb9b2ef60e2c3f59f9f05b1c6442df0844cb906aa7aff0291659954c1dd510d9dc99bcb9576e21e297124d771adeab31478adee2e34f27e5352d8a43e8499e2f3b07c51babeb5ae7491b4183a66bd84a1b6b4d124e87456ea612a4da147ad49b5fde21ac34ce49c8ac1e364fccf0bb099a75af914e1f60166008fdef134e3999488461f9bb227825df4ad75ca08ec27ed200cd0419131ba6335bbeb9bd623b4d9ee96dcb4126f427e8a458567b7d36f13487dc140bb2587fca48162adc67cd0769bcc09d309aa6d09b23650adcfe97652e00d1e24f1d8d2105e0523ce3deba68e3eab113c5aa633637cf7b1ee413dc288de57f0588ed27cf8ba0732e5a90bcfef8419f1acf73f6318f7610ab07902dddbd5bf84a4068f5249e6d5f6fb9fce44c661759ea3ccc76c031e814453d05cb71461b84aeb028b6143ea3e0dd4231e614650d452a423b5a601db29685d05370e369f4939aaef07c8c1f73f17a51b5e82296cd0299904a098a7c97025eee55d14b29519e75f12f5dc09f4baf55bb8e58c4e061c80dcee40b8cbdcb662a596e9daea7bb60c8ac2a08053ea37f2584c6a1ef5e2e02133d8abe25848e94e61af5381192c627f54a121934a703ca941684582056b24a07f26597e77e2fbd1946fd6760593e9d316307dd13c1cc5cd5030680fd9fbbe537813459e0f28c39d16d1f823a43ee45b6a9ce15d5c0480fb04a5f9178aeb1adec2563e0008b56d2882464efbdb7945bca94640a5b08c60743081ce4f6734b7e06e248c2862e84f373dbd21591dbec59f971fca3e6421e61422e452bdd18390e23bba217535a0907ee2d6e8112ba4e646253fc3b3ed9a64c791225174c1d9138454e59698ea223ae742e713764a6302ea9b9f1a8874b32b211cb9187e32db9f52475d1e32ff6f1e12e1ab1cb3f1d2c6b05298505a41591c202ca5e7e2133b9118c9175771e7e88a6cb11e7684493021bc62746401af40634583445baccf58f5a6a8818298b28ee91cb754cce90c4cbb821af31847361c368148d5ac8cb183e2c09643e3afed286a28ff69b0d3c1ae25127c05ffb0858edab6133faed63a282cff63dfda33de649d93e123009f2d15e7a524640030e358c407b157c827cb4eff12d763ea48c407b29db47821afa4be0c3dd8ff6d1107dbc411c7f09619deab2b1cdd67991b91c5efbacd142b14bc7a13a2939be3d1c1e7bebf4598eff7bc45f375eba14563e51617fc3a38149f439c206907fe3dba321faf41f21295d59fdfca8e58b928ba568f4c5a42f1e6151f2d45ccd7c03b13457ab29af944fa43c41698d2bbfe5af66e6929116a52ba59371e5473594ba7858572f041bc6a335a6b02c1fc6a75fcaaf76257db61928bffa9939e77cb2f20060836d8761793a9ebb16747c7b355ef4d1e1235e2935afc36379dad778ec53738477a6cc873a2e657b2b106ff968ec816032cf1e83fdcc175aec6bea65bc50478c97144384f1629037642615f6a9172f05ca97f259be7c50e25c2925273f8787c36b216fa1bc76d2445de3f5136fc9674d91bf153971e5ef68b234f453895d20d05f03096e3c0ed1e7c627a58c5db279e5c735983a87bbf27b4a3bd12f0008f5122d574a19a5a419364390cef1252197622e3197984bac8bcc6426a5c8921ca9df94321da386e79814cbe15c5bf7896126a0946294821527d6ba5a514a674b4ab9c8cc94524add23bf5ff756c3a5cce73c654f2ffce60c1bf39f93e38db367bd724e2b95e0eeee320773777777c7648c4ba639991963c6d8c3306c323327ed650c0929e7a44fe56cda22e5e7be45d62cab5ce4dc82512e1bc7338b8f25e900c93927bb2acd2a9d53c75f2f74ab29c0376d01be2264bac7cde71727e63b1a0431df3cbbaa7508114782b5f94a31ba84ad52003fd8d465242cb818c3dacb485850017e81050d70c02209ab821dfac1b7018b28f216635800d104c3304c054b2ea840cb009ec06207af08e78a0757b2ca6abff21855bca06b34acd8c1698d1b97a051458aada2835395266b650bee06537448582cc9ace4dcb0e6aa9e7170552a555293ab4ada82b7204aa56a6eea6d6eea53a92b7eb8a92bb0dcd40d82e801a8e57e0123515f918070516fad407151cf483c705284aa904191aae474485600a1564a6b2e0dc0a5b40a1f5c6a45511534e01e84418333785812f2c1aa38d21281d0c419480c61791c39515153ac649538f2e5eae80834260c1555ee2cc09d54a471670db09ce69c734e71842b6bffc089271ac663871459dcf9727e8d72e7dbd51457eefc0771a494524a1b3421a59472dae008cf0656a42062fe9cd3872f9cd8d003305a70848b31e79c938389020c1c512461f5824d8b5a6b553d11860f9688a2972788d0030a0a96d4134d442726cb830f9d1051504634e1a29c9218628342d4219d407b22c479e1244b41940d0a317aa84318695014e107fa6429b341070c668582a21ac50e3c4c178448a25140c941c2ac86bcc5350a24807061082d5140e1c4851428457185095c2062298a1cb8f0c4c82ba2310304cfb03097ab141145006a14e1c40e4554013a29420758952280e0a40726b4748b992a135dacd0ca8526869e0041145104af6856b1b10d10b12b82cd0013e19db8a2497d31c41bc6a42c66d56312bb20c03e31bfc5206ef99be0faf340c4bf566bc31587ffba212f6d552c0c6dc41bbb1e3f319f51c1b9acdb4b09e2e8a834f6d3b3bfb8b69f2aa5a1bef03b893e33fd98e4d2db3310fcae54e6d3a25beeed1ef81e84f8e27acc47c45b3ee3840d75e8e09d7ea2973e19b1c5dfee1a18c6d3088ecb1db8ae354ad17ee35a6b0ff6b1ead724d8ad0df382284563217e7dea15c9324ae9ccbe30d2c7aa473f529b6ed9e37b5c62536c395060b19f397eb0fcac060cc0a0728512582831f9c497b10138f2ebc962fd5b7d5f911217507ef09dd8b7d773a77f8fdb2db8ee188350843aa5ff832ffdb02f94f383b0aaed60bfb9234e82d54b3df6d9e2a89b882f1a88a3f3d957d4a9e3e637bfe370b4f9126befda59c72cd6e834de19b99b2f1fabe37f968b3407da4d2ccc6524a3265a2db0db6524a3237880646485910e6a58ae09891a24a108260840440d8a3080218bb5d16a52032d60036ab0342f23f5604526c5d32a0c16e2ad9dc9c308e01300b0e38fc9bef10a41ba57b4303100f35e6830e29c80009efbb12b7edff82c9b8bbf79949977ce9106e30bcd205906c18285b1f4910e8e4dc3505046df12843484b0d20eb604218d20323a16383b7078ecc03140eb1aa051a8020b50d244af95ab594dd178de110eb361aad1b204be846c327a1a42b00ca94228c01d19315b380de756ab93d0a3b16d31cae8b1b52933efda36d4dddd1b7377d7399239b20747c75fd8ecee7677f7d8e5deb1bbb7d34c0d5863c0c72efe2ea6408169107b49b1ae07f65e986d15fb9ec6b288bd0cd2458be130c7d2c9132a08bbf87980dc18262d8679956a84cc74b78de3ce89329f64661bba7f5766cccc9699ebe4103ca1583ff5a6645469c1a114aa4255e8052e7e55a494b40dda066dc3c6c7e8d3261b9f37ea853acc1fdfa56b524a29a594d99c2fa59452babb3b7f3dd2203fe52ed863d8d4a2820df2cca47429a5942ea59492c1adde60e3b39452b2942e8fe0a72da69c5272ec32659729bbc8c984c904c90425cc39e53bc628bb4da13ad8f82e6990a997ecc8c86808a329514d4d72367199b2a949ce262e534e2967939499724a2e7236bd787c9fcc2e19e717b99c3c2544e614fb28eb9cdfe3d393b3004e6cbc731ac166e34dfbacca4c6699967dd56483dbf7f4f6d17e9edf13fc8d7a717e766adadcb6d7e6c7e9fde0bb3df5f8c6d82c03468d0d573d9be296ffc74e0c7bbb1f7fe727d303ebcf752bf2965d8fbdf97d27869d9f7db6413965fd2f321fa6d3b25ff96fb3004e3c09bddac70273d3cdb0d9036773c28a0f4337895fcb567e58c18dac0323a594527ea1119c989898ee7e791a2ffcf9617eb5aa55af52a9bed008cecf4f4c4c0ceb5931ac2fe6865dad98c8bc3c8dca0b8de0e0dca059794c66647e62626038bbe2602a0eb7aa41b5adf2d26112192691292dd5b5bf2249e4f5b76ebdf0486b1d0a853a9d78e774ea3adee93a7669cff18ee4b4df78476e9ba6f18ea66519bbb4fad2abecd29ef2cee9b59fbcc33ba9d75ef24ecef61ec63c18df68df9ff23076f59f3cca3c926ffab5774fb24b7be94d76699f3ac9937fca637679cbe7387bfacedf7e117f2939a97a4ec5a99ef30fc9e993d244f5aa6fe6552a99998ff9f92b7fc1fcacdf9e6b2108baf6b9af5e9124f2da47755f68bf7e6ec69389f12c8cb73a72398ee338958ae35e5eec498a8d6deab680edd95b42a53e0eef43c5e3e4ec943f9fb9c8a30c9b7d6cba217d4d03927d614552e443fa49d9a40cbdcff695808a7c2acdaa57de8af960ed7d8006dd47639b5f04491874432925a0529fcab645ee7ab40ffaee7fd2b447c27d32d05cfb1aa7d99e6e6603c8741880dbf27b1c8dc3636e75fbf3553d9fbea755a7af764e11ecb3eeadfdf6c278bbdf5e3e36ddd46f1b6fcdc9ab39e7f9957d65fd4217279f7947fbd3b7abbf507b1b54a47941454d57e39a93af79bd3d12fae10cb79381e6729f7aee1e502f12fa2128a27df745b4efad3f24f44329f39bfc90d0f65cd62bf3fdf621e13e294d645ee6e96f350e78ee7e707c4fcb78d55b13c717840da07a99afab42ca7ccdcfaffeaac121f3f337d5b7b7a341557fdfa00ae6653c1c3532ab97f998d43ccd3391f91baa9f7926aabff1d65f333fbfc6b3dc52fdca5f377ebe8ca7fa1e87f1c2005cd557a47bbea87ff14223ac74431074bbdf842eb32bf585ddd7bf3d5feb6dcfbae1d1784c561f0dda0a8c98811041508183283e3cf3d9adfe0d1e68d8fadb56fd45c3126ea3c947e66f883e43d48749908fcca67dbff4b46f85fafd80faf2bd5b81ded63efec9930dbe62bee3623cebad292718563e8b85af97952ee60019e2cd3ed60af5d23742af0c7eabd2152e98ecfcdeb6ea890436f617951824109b7cba3de6965797df0af5fac73e415d82d82d3ce5d842561ffbfa19e6dc7caed7bbc9427dac3275006d6a6aea72b125d46fc1a873642b5df9d987f5a994a1f7d1be12b4920f957eacf3d15fdb9b9f451d77730ef3fafb01fd45b0fa2d18e9b863a0e2df6c1d4485c7d073e707f57cf71c9fe3f6e750419eece9f69f7430337318743d36ddeed9f568f693b3fcf9b2b080db31b05658c0ed5f0037dd3032bbead1c468cda6c635d87111d6294fb27315e8b8f543a2e3d69f3eec4512996e8d4b1c79e29491a79550ac6ea1fc0ef2e137ec5898efdc39a0629f8fed6bc7c2fc2abd96e26e5e91ecf96a5e91ec63617ddd0b5d855b3f242adc1a65bb3c85a0af0cd87d8a7d2cd82eb6f86c5314b1b4165d6a72f02407368842ce03d2164b785ec7288f36c6529c174497df89cbafbafc85245801d9380496b1ec807451dc391e6ebf6d918b6ddcf95d3ba7b2e06d08ddb0044aee6cbadb77b92f8caf6ddf378c9fbd772c047953d3edf19edee16a1e17a1cfb77a45e8a3629016fb045b3fdbcc96ed2dd333bd6a55c3744cdb4ef54bc746f5a9bba6f9d67a6bae6bd3c63a76bcf1fd95c586a561fec81ff957917f26c67ce10ae60b2dbfea88e872eab35fb862b141842516a13e2e62ed86c74ad1ebc7589c915fc6d58ddc754f0bd51f6859776466e62fbef65d2337333773a41f63a4941e493243e7546c6a571ac4d260fc8c1081e185af71aea051609b99397baf34f8168b62ccb237d2491dbb3b7667f1e5b6fdb66ddb16330f89c77844e784418f02db4410613771fd91ba09de6116e294ed88066583ee99d751fa8829ae431147252d0baef30be79c7372546c3f7fa1ac517af4b420ba31f7eb12b26460e33b958d19bb825d91f259baf7732fb179bb7bccbbbbe3f01a77f71befac777799777787797777777777777777f71fe2eeeeee38eeeed57d453383a326d3b04a3794e54e5d4a05f3728325a3847583663523a324060c18d58b92ee74ea524a2cead4714a68ad7453a26595e6f84e89ccd1a111d939e4155b70f4cc112d34976a15ba3e31724c3774a62e10601fd7c23e397450d9857dcbef3a439d4bdd85bbfb7b8f9618f6ad79365b11b91ec52676e4e3dec2cf7077af2291d8f86347b99b73dd845fb6871bb95c356a3e8c6b5cd6cfcbc894f8f2acfad4c7eae476dc5ba6d6128bbe88568b78426dcfcf21022e53c746452ef126bef64cde8a356b27f1e6f9c75f9e14562391c7cd8845456e9dc8976826262277125b49a9a8b97051f21797c8d35ac49bf85a70616a2791a7978837d1ad75a2d84eb468a9f9c215eb0bbfc64931ed84da3acebea852b3fb81dd1b344966acbea4994fe67333623a1b7c4b1a75094530315b542fee728975a225525cc7c4c4e44e2ceaa4c4a553e294b86c182dd2a2a8480bed732dcec4a5c1a8466f914b6e8cbec68d436057fcb05d0bbba2141cdfd960f943d7d2ccccccfdee9fbb96226c8cfc6125aae9192628fe4a713aa7c38814bbfe1b31c8db3caefcdd3d41b1f4b18fcffda6715bf65aad5ddb3bebd495479388669986f5b66958779fcd8dfbc2eefbe91cbed147c3beb0d2d45b54ca9e1e75d2ba8ab179f577e93289bd4831c62aabd58a777a48b768582b76d9558d0d965ab1974fc32f03649ad6f508b2e21dd495cf383f1f9006654c0f36642c38b458f98eb1a0c4963ddbb24cc5230a214123a5947ed635f6fe713e730dd2efe94a64bdf31174315a44f7a675cbe03124b1ec924f3d1aafa65bf235cfa65bf2376fff56ec929b7b2cff90afd86028aba1c807fdc21a8a2ef5519ffea84f7fe3066b8cb49212b726c1aefab1eafb576badf463cb4ddb5b6bc79ae6f0dad12d6eb5f8c64fa0975ff4f945bf1dddf2c7be70bb61bdf38b4166a928bd1d382028b9e8fdfd2bedea9d8d4de6784dc5309a2465e87d28f6a5d0a04c815d724a4c0576c95700dfc8df648f14748c6cc8615c39a473c2958e01704de45100dfe4e01d156e5060f0a5c32ef9f3637c92d1afaf7d3603a25f310cab7269cae0d421a961c69578d4f9e062d1d6f9d8ae4f28ba3f82f5892311b5eb9e4f1fa134189f28b1db0c341c894e78a76ff7f18412b2dda35efb6c72bc63bbbc46c0adce7e339c86387d7dfab1566befe9749ac15f40521f0ca8cf4883324a2cf758f730af7ad99dbeb3dffd0cfe02bdd57d4d755b87717d7aa95e4e24e097eaebbe1b724e9f0eb77b1450b7bae77ff18274ab63c1ef0a7cd371dc6f282f88f5f8caedfef49da058ec27e8af15b8d53d19b7ebba0f756ef7ec5de7eabea79fd8fef89143eef6e985ffe40569b0fb976e736ee66562663e2b1353ebdfeebbfb5902d3bdeafbf156f7b103d260f72727acfcd87d4c2452fda97b98d3cbab4e1f0bc54259d4dbd3a34ef6843afdca5bdd9f76b0a7eec3d5ed7e86ced1713becbbeed9a6fb8ac4a2d9a726b82d08cb0daa61c615ad8b51b4eb9f7591c84776fd6b17857cd4eb12099273b7813962a3bf69596c162bef64cca33d6fd66b40b7e847af278506290fbb280a7c43a906d84561f016cd00dfd06ae90b7449763d2aa5f4638c315a22fea2f1894486b0f6535f14fa58402fac98b7cf3e2f1fe423559f7ad5c7024ad1c09280ea6154413ed9cbcbfc4b4d7d2f1f7b2b4e919bac1cc795b7e8c378ff42e7d00869907e7b400d6adf4f8354c6041de01d19ec0698c79f3e911778277bfa30748ea66d377adacb08d9909788f00eeae96780794e4f5f039cd33dfd0e700ef7f48b70cef6f441c02f1d6fd19fd1e1ccaefa272ff24dfdce7306eb731e65b0fee66d0cd6d7f1178a932e7df6fada47fbeb117dbff42fdfd0fae9b08bfe098adddc7ba1418abaf523c22e4a9ffd6fb59f7ad587e32dfa2f40f653f56365f5b38f95696fa495b4ac6a35ab0f7a8bfe69079b42e760b9d90734a5c1faf1eb740e4d143af97067add507ea9e7cb0b171b0f10ec7925f5cb71ca65b1e39de9827e31b7faec1d6b2d8adb9ca2ed724d75ff4954817684a833cc5c636dd200873a3f6608b5f37cb7ad8254176a11a1004e3c0cee96f4757ae87777a08107f116100ef58805d3c14e01bf9d2524ecb62b51b72d6f9f00360b1f236734efdf60360b1f5fde7e9bbed39a0d367bb49e9c7a2d91bd9329a51a6239dd3577e922c56de21424e4416fb285bf7eb9efbd67efbee7b0e48fbad3f963b7d23ade44ddb9b8f72ecc43a23421ab1c929de6ae951640fb51091d785c9859c49cb1253176ff563515af2566b51aa4a995151d2512735166ff5917614c588e3a4d745de92d2eb28a827442dd44344714888a94b149ae1486bf196901f18881c252d49e9e9e000e9a95bcc13194e7a9168860501f601bde5ffdef228e4adf68e784b7a44bc253d21de92de4f0d273d203838e9f5e4e0a4a7a383931e8eb72427bdff38e9adbc253d6bc349af7a4b7a2c80959dc14a8f0501f6a9de72d90918f216c8498f05243f18bcd51fe4b371ebb4590103e946302e237df1837cc55c19666e7c18dee98f30ec8a32d4db57cb627d75e58d4fead7803d7d09843dfd3e1616560d45379c6fa495e6d785d2f53fed6081a68438389d1373c4079106fd67f7d3e0ec6910c7877f83cd4bb6f0c6652d872318bff0bbf1f9dbbfb0ef3718afea200aa101668c31c6c8aef81e5bf16f7c8c4a4a428ef4e0064764ecd84c8012853ef56cda61981c815235246717135309619c77c5894f66b0f20810b656cac4c474e4c81115143664a623a4e61df9354b42a6c1e460436682b2bd98c15c8cf47041709d92ee74c56e27948a092818daaa6cb02133f15175e94920423a8bd44b1362528aeb1893224f04d231e945b506962337f222214474705216757a51ca89b261d5ae62d738fdc2f9be756c5ec13d874d32738c07f0c2c2740eb78a1dc6b0c63f295629b4610392152cb0e189248c80c40dabd665a4329eb8a7cb483cc8610d185bd1e83064b208c21658ace08c2cbef0342a30450926306083871900c194c4134af8b0050d2c43284388223ce1c5510f16a5140013765eb69203130428b2f5b2951c90a04866108159c961e86e97ad3461a3d7702d6104932266a0841437306a1fb41449741835a805549a8cb6a8428910d478c2a70a2a866842858c13302142900c94a0820aa32fcc6062061a407409c3084e4c21c4141d7079820344d0c0062e6010c590920fc188043734f1448726286109679cc14df082cb900cb890b16404dfe25a18074c8c8104222ba46c9101ced72c965042b542c4e4486594016385480757bb6c85080b256af31bb513467d74e5092b188a201714c1a8054760b1c610429e250442f0392aa3890a9a60804614a38612436432a4022f24242424b4c589932daf4587036891afc396e82de4d19b9c6c1c5fd873830d13bfc8c3374c126f94427fbb51250ebd0f76e304966f84e996cb1b3e08aff2eb7e649c445edf912de994dd4a3d61e3cf2fda25fcf894131b8db055ece5639827035d210addfeab55e6d56fbb014e56b5c7b4ac22f19034d03863256cf62b599379d4c3784828babbbdddbbbbe79c18f6cec4564694324eb0c619647421c50bc808828c1b968ca0ba8cb434c6cc65a4a5a4251a2c4959ea610c36c640c21867c85c461ae34ad218518cf182315430c6500e4968a265088b09c4c8811855c49881182e10e30731726023e632d20fb460f9c11596062eb8302c38228816fc608805b76b821117264b142c2bc0a2888b824205b7a302e5724610714f3f5c19228b10f7e53252184a9edc4e8d2b29c88282ab9d11c44d8101c44565f1c3f51b5cf1214b0f17ab82e8a68a78b8f40527b8d5881d6e0784934b2f23f960071dae652387db3135b95996a1bb8561828bf10087bbe180c99d575c5992e5869b4971c5862c4aee160329743b175c69cad2c69546b071ab1057d6c8d2846b2f23f5a0c915266459c2dddab8d2258b126e97c695247041421635ee16c6e730c3fa11ae5f4602030c30ae706a051ea51777f2004540480bbe04549f521a238db45aa01f20ef6d9a4cc005e6f1e71d5a7fae1a9c5f6570b0212bfdb4108109580003fcd2a94a3ab5cef97702fdb06b2ae18029ac341f5c71346b28c5408ad534987d2c1ae96fb4522c64d51f33d6844666c4e6a45fa433624f2316e7b4737e2c6c3ef6b1300c9b139bd954025cd5ac583435362be660cc38b2e2332a3a02408d0d8b66b5a259ad6c914dcdaf56384c4c61f31d0489c5528079f855bf21f4931f0e24f586b4101d6cb8ba14c0b1d915c22effd313db92597eac39b1297f4a39a5bf5c213e46619198babbab7588191860977c29dc775ab86f488331604f7f089117302f89bd1660579d31e98b47f128c3c17182e3afa885192bf94f6ad147b153e2508348d90c6c4c3aba72a59d81893c1790e11d0cb08b89020cde0879626bad4cb1c8a4e9c0daa0209ffea98951b3ac9ed0f276340fb0f22bc3aa579dc60acb3ef533d495f5ce2484628c1c86b591235e926e1561977c0ff08d740ebc61977c29db73de06ee68d088c300faeb87d6c73a1fddfd61970c13ab02bf56de927f02efcc977fc32f06230ff6f209b023f2642fbf00bc739379ae1df6d26f1579b0afc53749270800c3b00108615c6a0a51877fe8b44efc8142ff40c17da0905d9f73fa9c523be9d0d9d9c8ee0737d8fdf8f958f7c39b92310c8b18d6da09094a763f5cca1fddfdf0ee47164baf96c56675326d6cc3c1649bc7d91b564d567bad734194514a83505c4249c02ef923881995523fab948619581d1d22f3669d8feee228b294526efab1d7e3587772c262f3d3316fd8d42b6a566b96d55a9bb677cd6ad0715cd771b33d1edbaf6aa66d9f0e8ef6e9e0b827b3a4db9e28875d591b1362dbb8b94d8fe0abc5add9fecdbf524952cfa32e62b14b3e0ddf14619eac12bb5babf5c3191b1c21754bbe94ec352fab300d629c7bf18838c58b4b744b7e0b8cc06a8c825df2e3137ce351a278378c464652fb19fcc57df1894fbe51f7b410e9c355dcd0fa0d1e6558aee2b27bad350bc08d4bd5ca0b53f10bfb6cb8cda673e263fcc2dea625a57c7e9e99e117b317bf5bf2d3b055e9a773429d2b5f2fa49342e7c897cf2e798212df0ba5d58a5d2ef4db2b1f8877fcca1701bf70b8255fca9608e057c8d3b15f401d060dbf70bcc53b4da441f92f6ec97fe1c89ffad4bb55e7006159527ab9e1eaa66eb7425fec5babdd0a7db5f7a858edb3a206811a940f34a48508b04bbe8f1f2a4a1e15cb376a58b20d468679b19734d2ce86108d146157e5f100dfd49ae5f0e82e07a7c1fa59e61969100625360ee1a0842c8f06eb6799bcfd5e03d8557f93c9c1cae01749bdfda83fbd4f57bff690c2699dd6f568b2213788a37b97a74e2bc2afd3179d74ab7efd803882f635e1d6df28277383fd10e7662feeebc7a1531c7a20feb2df0a25843d7ddfea22a95d8f9f25a8afbb38d460fd9313566bc2adfa462c0961939e685eb5ded250d93357351dd8556313bea99cb7e4861208f970acec51570af771675f1c8252638dde12ee71781feea3a269bf753d32da0509ba5aac7555ad91f9b1b28f393ef9e2a2938e43cd796c0486ce89482292be8dfad3671f89bacf501fe8adfaa78cfb2efb581a4bd37ed3b22dd3b2f756cdbefa30b06ecdadb1e885093892b20f549f94b08dc958794cff64171bdb586b51d7b24beee8168f6ea598a7a5e29d137ce686f64acb3b280cfb0dbba134bf08f65549c106a5ddd1a0b49db303a6b31b3b20a306ab538e51c29678c7256c138505ddd3a3b03f7d2c20fb27d59f9e7dec07f954d4a7b0477d2c20d4a73ef5d150c30bea837ca27d98b7dfc37c8ca1de3eca4e89ac18a3576f4d4c27059dce99f1e8d3c6e8a96e276f47b7e6470f64d7041d4ba1c1d9e3adf9123b256193db61d32d8f6fe6a901dd9acf7f9a73887d0cf08e0cf602cce33f5fc810dea13fbb1e18a555767d213abcd3fd7c149887fbf93cac02338073b297101d1b73dee63983d86b1e6510fbccdb18c45e88bf5013fbfeaa576de67c9fdf29609f0ebba6ce9d18b6f2d6c4308c6215a3d869074b3f7c1bfa014d9961a60e8abc314ab13232d94894813b40558a6f60bac6dadbcf2cff7eb4f6406fe1780b356def4aaded1c2d126141bc96659a963d517dd243dc72a795ba67350832ab35cbaa740fc889069f68f5b34dab9fd1da5d295b966173238e1b639aa6a27ca06e7fab2817a7ad88b26939750bbaa7362ccca79efd25e3431f27a394f60edaa53c3ab90da6e63198ba55ced2e7b1e3045a6586629847867a67784786d5b5abae5d8f0dcbbebb8a79dbad35dda230dd52a5f8867efd2cbbe8cbd86035201de407e41dfbf45bcc7302e7dc20e0456774548b3a751c10c60246ad2bede8f73418843a901d0e82dd0ad86b0ff3aa1798afaa52ffb2bd9156da364e92b9f483d0d73c5ee2a688b2aac926d53e97a27dd65e0c49e4bffc9e35bc722fa2b6a8546d58743de910d100000020004315000020100c884302a1503420c8b2de1b14000e7398486654170aa491280762140541c6186000200018628c31c814155501adb64ad121e68267de05dc66414b0192b2c99904d78b62811c63441cefdd086fa45d23c4ea2dfddcce1af0e3e2b9ddea3d2e65bba93f07f1c59389cdc74e88304acf3892d9bd7ed743c5fea13601808dedfdb5ee3a724f371604e9c3c41cdd767795a0debb90827bb90a030e1cc1dfd6227666abe0f2476168b85d92c8105e546b2f625141bc561002aaaf419ad79bce52906ea36db067f465719d7696e225044a49a1944f2cdfe99b65d335ff143e31df13fd157505f6c8d55161dfe7a963941dcf6f1784367056b8ac3af7f5e79d56a67d2f31b99adab1b456bcbb4c903d55af6a1b08d975cc1839f970c4cb19b8540775c70c497c8614df17d3c1c6d92d3c4d6a393e768969844f72dd9378672fe1767d6bacf8ad3187b109d62936792a4714f90f447c46d1e2d714ab200cd582025ecea6c41c44b72991bca4827d5eec13d91c86d14333279be7f2495e5cfe611bd1395a911d89829d4138382b157cd759061644b49a4e62f79a67d563ed009d4439372611ab04b89027da8ae8fc1ff9e26894452a0dbbe52e816fa154a9015b680808e3231f1967445fa0b6cade0e21f5af7a2a63c6f04da34723774ec0661b00eae40fa42b09e00adc0c738033ff5aa9da41b66d1628c3473c368cb861967c284e6ed6536b5c83e56f0afa8ef4f7cddc1a78472bb7cafdc0cd1ea4be39889d426dfec678ad6e36fe4714fb0764e72713109a3682a42799ba8702b186ad25858f05f5a92721cae4265b49c34890713baeea52c19ed0afc09751e5e6ef9a776299d9a453d27c28b6d2355b92920b120a556c08a7573e95b04b50e1768a299818d10d1b0c6c9094a98d6413960a1f7d66434bbaebd38f3365d2a4e280a540453a1f4223920964ead75e64f80f9c31489363b51bec9705cc492215a5821e42ff28aa40794a95ec20868a655ee4de7e1ef6aa196f3308396955d43125fe9c24ee23ccea8dc5fb48a9b02aa67ae73fc284c2609569dd126f259e793a6f130c229054df76fe23a5da284618ad2a2dff2317080f55553d41afaeaa8f31e88530de31d809fa84afaa4060733b7d1bbf0812ed7d9a4f721a0b43615996bf1a0bcc6c2c9be85ea43187100ad1db7a5cd23cf6d3b7237ea15d8920f8b6e0e4e44545daeab9aaa6a6ed7c4376879ae63d2a103dd7c5635ee02e00a1ba53d33c3261721a8cbb66166c7dabed3e7250b2a2a6ef6d24b56610f6ce4092ec34e08ea0665aa101b9c74981c65fd001986baac1f9dbe5571fee8f6c82a53d14e384038a60c7307d62d8b99de4e9fd119b6f92533eb4f10b70844a04b294dccdb7e86271bc4248c5c9bdc46104c2ad0a53bc49089f8ed65274b951adbe23bca97a17d3c55b2a3bfe96cea8ff886e2bdee6f48d59ac02cb337148f8447e94a314117c400081ef43b57446fd8ef046e1073101741cf7fbaa0f1a426cf4d4f6d3ce32478e9123d9a85d65b97488fb2b10ff4fb208463a19fef524dc6d95a7f517e1247a350b3c63ca17cc9225685af1777215bb009538521557088e156155fde15749a2fb1fda51ca913828e380c705dd90b1e1dfc973a3131b1fb72a9273e09dd2385222a2e495d4d3a53572a27eaa1238cd2ff51cac5ffcc2c02dee07d88becb4ad30ba7c4c04939deefa2503d75407a767ec217e38393a0d2ecf49581f5c84d31163c62fd866c581093f60b2fae4815d615ccc74ee1cab7492e25400f5556ac244f267636c9c4c5a21172f42a8d6d8eec256c4133059d5c53e682798c6086212a1c7d55774db521a0de1cbf3f0492386efe7d1829b3be6d50b1989f68af2264c77d78fb6a38d6a9c27006900141c17f7879b60a74e64ee56fdce02cd8d5c25722d2792c9aa1029170c2cc372bced2357f48696905c5b53955c7a659029067ae3531fc7d7743cfc82d23c48c4f99892ea7d184ebd733a70c2ddc33752b2931059f67e41a0075b4a3d17bd2ff0d11279a121c0060dfc30b1a449f612e33d5811f7c63a03f81b633dad03f9c8c43144ba623cf0f60698c9ffc860781e4b6f04f7cdb33ef6831aa06f4f6824798609e339957358a4ed42f6d777928c205fa88959fe9dec7f8532db336203713f4f21d6f6122f9eb016717b46bb9d8860ae03f2d212f52006a300f31944876959f48a5ee16d91baab620d705407c31ceb3a6b42f00c255d2f3e828625d3895b49675f695e8b66fb98b5d05afd4ad7ffb9888231160f42447bf7eff30819e938f6a52fb9c04363bf97f4c5414a13b208bacdc17ead0456093b7fb2369a244f849654e9cfc340c471993d1e3ab3f4915eb311a22d0cece2fa919be8a2597a4427954bb9076a0ae69b0469c6f4ba1c2e318db7fe076d243429592c90a360e2dc889d999d7816b9a63b122e48508aa84dddbc4d8426aeeca2bee81e187d8e2ec0b9b82e9a2c9180968426a6bfdc06cee6d17abac1dde03a9d6af0e0874d72e753e993263b2599500d08d944ab5564051a10a0e536a7a935297c985d2d09317920b5ea574b1c6c8bec7e6d7fdb98a68581de0e38630036c1409bae8df108a9707885b5cf0841d69cd09abf9996b5e475633d494e1796c700dcbd74d64ce9220c66c32b3318a4b1d38094d572a390f65320c24d4888c4645a8f34dc7b6a50fee352779e8d90e9d5cdac20e0515835cb03a819cd61724debd0383ec328abe6512ca6ca1d684b5b019cce4d17ce46e18a5a67051498bf3c42745579427c8cbd19fca8535393bf3c0c30d98f04bb8a1c99dc07da1bd04d135b11285200767ed4373f87768a660c91e51fdb1a3351b43537b613c1fb9897b4daf87bf6fa10f414709dd2eb20176c1b52428f071c987b563edd726f7db9bee413acee6ab92da64de4e204dcc74dee9719701c95c6e4a7dcfd5af771184a209a9e80673226882b136a71e609ded70c7293ad46c8ff9c02da7c12cb3a4bc537060ac28867731a823c30cb62de804a186026e937c80e8d8880ba0be97ba24805564deccf2c3189b4708e543a4c873322aff11800904e9f33992cb4e7d1ab04dd12cd9fdbedcad5d25ba2a1880fd567ea77c9c6fb1f2bd2f8e183f6e3661f61095d5e898811624806b71b7404e5dc74b1721e353576697b85e24374b78019f0682b25c779f32b527ad3ab93c88f129b3e91629438eb288db08a33af8d489679378eec838c52b407733003a8d84b998d7aefb39b1c8ff18a370f083f6387460aa09c7450bc0f9ccffad59784491efb640622727de772c5c53b83bfeee59482dfd0fe0fbd8df278a45fe95bbd3494825c2edcab25571d2ff195b756811c65ebd0ee80dd600de274489d0478a5be74fd39a8710e7f8883209e926300270effe1fec05672780d41612633cb6420debb15c6145af01e1cf8c6086f233dff5925dc97cd2a89d2737e74b0da8c0486db67243089c587de1bee42ec1977d1d457f9b75e6d988f6918108c7903495e191c21938a52ca0c9a9206bc47c4eba798be72f9126bea561470f21dcf76cae091812455de57f9ae30636ed4780e78c80b3a0b51ac20e4ff375b4ccc4461e33a8f9757b5442becc0ae8e6b5b44f0baa99036063b7a01449fc12f37561d1b4abffaf89c7c334fdb47ec4c8583da031303907e0c0ebf2822dd5a76606d278a1290fb30e62c38198f6223336d8d446d4a84f0bbd96ea93fc0d692e291744ef4a5abe72ecf1c701ae35ea15f7ce98282df4617edc6792a00342b698b3cdc68cc68811bb8c9834dbe9e0e80d0cd163845b9deb2f766c63b035027ca22d3f1f1dcfadadb8f41baf53035988f851911e8388cdf2e14ecd1836bc77cb2d42ec19e2fb8b618f8c753a78ba803d726d770eaed0d2abec200ae69c04841c15acf60477b213035f72181ab0df77b1950886d7508753c4fdb715f84de16f81a75e871e4c8eef68aa3afcbca306f854f66fea2058670914c556f22e4a605436e3c7711a6f46d5689f0857025c46f40d7dcb1690d86eb0ed6ef3fbe5e0f2e675455277bfe33b09faea9cdbd144a8ecc79184ae29cf48108699f0b4546079e4ae536a8ba24518ebd7590fff3d5acab0ee3fd99e4785c854bbc5fe7da3f5e51385d2e4cc359dc6c2b5c6007cfbf530e4f6badedda96bac0a8dc5e65acc9060fcd1e884af99d102840b2889fc592780161a9fc48c9ec92d1135bebaeab1e128bb0e2f5a2754031f01f99813b925df2c51916e2e5916f54534ad849b34878346003e9e8ccf0862e789ad4622e0f787d25ddaa0d32b567dccc81cebf28d4d01ceb64e80ff753e06a17c926f695e315c8eeb067b0aac0b1c17e279a274126463c1405028fd83ae65490e83d07acb41b2bba5c77791d0e30cac1fce9593115b6c3ab017f630febcbdeb4ab1c8f6d07a11303b00a2588377ca35d5e3249d05b7df5b3a7f4e9480bca93a37c5f3fedb1c13033cc30977e65451a3fe467460782ea48f33c064d1c205bea5ffa8c8062a29a2e099410c688dfa9a8bc4f5a2351bf3bef231a131067799eb8701bc28dc269b4d1ed39974520347759ec502f5f64da015297d3d44a061e3980b1382529b252f07a8a5250cea15aa665fb39567afdb3d572caf7f4dcaf12c9544ae24cfd6e58c1665ac9e7e1c2ad8d443dbc5bb11c29cccaeee8ac42ead27cad770c705b238b0194f77d1224f4ff98a3f5be76679f43e25fa36fac564ba76f7031e90c2e784569c8108926ff075cb8cf2724ae60015922a80725d5ca5e1643a09baad146efb7067e9775a7280d3018a3669f97a2df154d33d91e2ff7915a4a843e9101efc20aaa1a6aea475f8218eb02e890ad1c1cb35d3128ec83d9fc7bd90fe5a986c6357f2f5c8ca05a42dbfa326ab7abd56140040ee4b61880aeb680b262f26d892d77bb8201cb17fd3ea5f8856001f3fbc730d37871d2ce69bb586c81023668967136e0855989f92d9fe7e00fc4115af2a153ff6fc50dda5ef69cb5ca4449242229cdd65bea42e6b98b1fe19b5fd97e2cca219806b17e256a29dd21abf2c5a85aceca816ff5a0c047b9a61ac37eafb0745fed28bddf11e121364a1cb3bbbc25dbde661380e0e1b560fe8ac69bab1dfe152fd34065008520c9b786783b260a71f5cc0c2e2ea9181258ac2ed1a304f87482e43e6bbe10be1f62f503d9bbd6555b413880ac444e5950c55824043303e24b9a14e88e01f039367aa38829dc22721d41e9087c55132be348e63d79760ed90aea7594db9092374ff8bdffc17dfe3f900f918b50be49a3baeca61c67aa5ee82a44e4a4b03eaa10d417c9352f79377dc556e52fdab60fb7b7f6633243665d9cbc2a5241b08105b2cb54003d221bae9b613dc03494c0766d500442ded0e59de875a6c587ee0a74f2aa900d62133981d7054a017527e1f0f2a06c24b0d09d98d9974d8d5509d26f0d3c5afae09ac6de5252536db18b420ccc31649a76401ba124e338af97d71bed34ac4c443d3a945ce163c4a5626061cdccea9b9bc5257d612abdf0c8eee23157458c013cb859286cad6913651d62ac3d81248287f84b32b7467f315b964d1334658a30c4f14179e5026ec2c30e555529436899953c9042b8a196a30443e8928434c31bb0efa6f29c2f8be7108532c9c2b2b46c512afe309045c5c359a7787ef4fdc5a47e10f4a8b7cb995cef769a4287ea4bcc0cbf885d16451964d9a120287346f660b332662cc7b009228c2e8ea9f60038f4fe8609930924b6b08bd84ec56ef9cfc564d605c0cc00e265e7cfe14cae009cb6834f16d93eccdeacdac6e7badadff84e6c80581f20f8e006e0920d64bed46d7fae47a365d89ad71888580282957c19cc55afc347edefecd2522ea26e9562f84e8a0efec7f898c7f05b82743f8330556be75c0a83a32f0a3606e18b3ff9f21b94ee15ae92f9909564b4a664fa72d8ae413223ee34f5d5b3235e659f265839a27af614ffa38a62d4b7908e526cd4e302122709f68f32f74c44a55ba2c2801b66cb199a2515823dcc7436d4ffd033d5e1fa0cf433b2288df9a147dc9467920a29652fcdb29c7d717dc576943ea90ae9b5a393d6b8586d1fc1477b670ff67fd09b5be4022b7abac859474bd8f8f3d572cabb9051ca547247b43489d339d63655bc6d135e4da61ebabc149f9e78da150e02c0babf5038f0984c13ac07120f20ee09c6ddd03f0793a6e622558c994e7350bb00e8c2b5289e6e87320ffcfb3a3651291984486dca9ec8c2026bfbcb4d17507c28e255828ff01373c36d96c97cedecc0f218558981e52cc73e11745d12c98d7911f1c725cce10339321080c68a01c3e2e169e025ac61e52c0dd4e40ed7c9ebe735ef9c229d8ea7602e75bb6746c2147b735a8f6dab5a5cce634f36a737250853531be9023fd4d6412b2ea58c16d055735928677d97ef181c51d170a405c87bdbd0303e102542a9d9cc2bcf71b7ad1510d99a6e46652c3b8814a911bd16ed4a7d54e68bf20e3139ada9727a4e9a9c38266f73f25e37616b53baa7d3700fa4b8be61852ea87ac2866267e524a5f6ee3bb7850cf10c827bafc0e323f1eb2172333df3fac7db189cf11534610db4d6878f9488975c1f807ca7f89490b55688ee625de50dd8f723baa37d137d2cb7308955aef02a312aab1c241566c843bf93971b4a0c204b0368881ca0f66b5b9315e03b1c21b1b9099cc267dbae4c880810c1b6b327dcf250596c7ee5b245b8f5413cc7ec90a515690fb5ed3d481a4ae6f921227349940c5eab5055d3ee976c2df0f28f139d11f79e009ac4356c279cf2cea91f97cb5259350bf1d01e415490060ea217f56038b5eb9720beac1f0a1580333275cc8321a48f3f56cf51a4cde698c6ee246ea9720e33741ce4896eea7e1064be8e5f1af395463b9f5f6c897e46a50beffc65d9de65f9a2089e92ab7563fe32447a76dfdc327447f73c7768904d29ea15a8fb875b887ea37cd48faedccec84b239330201baba091952963db90c6b647284ff145022c78827f368bcfa805afcbd21dad9bb5038dd18a525d890d66dadc241f6f5f9db575cb72d7aadf9226ab13f21ebb5db2531b4ecd5c5128f533a23b6a0f316bcb43b1c1c9cc7f9942b4ca940591cb9e30593dba7c433808c4f8be55c8ae40d9d65665e5e62aad402a16067347e61199a6ea79cc66469f814d222d5ff2bb7c9b8c57abe74cfc6b28ec2ff16e5f25f651950b8030be98a3471a2526937a7861824678cf2ce12598826f90418662e0bc08f16b98634d494152d84ac034164541dbe4fb9cadbe4fee6b7cc78068379dc47ea9c254c405103b6043ec3fead90926710f3308ff84f1136f67c325046fb54929860fef5f78814810def2b736ecf4905408dfa1edd3b5de549bf3f1a4386ed588914572373e39f97624c928c7d70ce2163b877e832e42e37d95662462f1a151f92456c6b1376575d94a073e27e88926e56164c9e080932201e22870aec4f0c82d17db623ebae21e5737c31a6b9d2e8f7100f88439071749e7fe15ae9019e9ae42a0f1fde6566a86c70c401fa9ff88bc6c56ce0d1291dd59ca6af157694989109ab1135f55a0bf4a48848a84f530fd807566601257b5c69e65a6a604c1629fd592047719a9ad3a62a03329ed2cc44008eded2255f5788fe8b5aaee082198d2b9a1adeabb68c2653b8f97e223ff0504209cfcc68b282f391956f3119447462097f8f0ba3f829baa8a2e753b3998e04b19eb69768d834492eb6ab304eebc55f81fbbcb106dc30f6c73a519118cc5c727402f623799cddace960f82405c571733987fd652151a3e2dc672a6c82c8cf00fb5b90d120ea5bc07bf90052ded24bc664dc2ab48b011b8342029f269b27c25ad618cacd1bedbb6b08d15389380628fcca383855077c9f05240b84a5fe97bb1953970691b0e8d2390119a1fb73ea4e2a7ee2fc69a47de3be80ed10cd7bfdbdb14595a4812c1b73cb5d5a5ba1c22541ff01ddcc21637b4c16039b5ded8fc5898f0fb2a61f8d2f8d4e7997da2c1a87d294411c4841c895063d1b18d2bc9b0dc7622c8eb38e4b6eaf2ef320c2212517cb0355b225730078d29efd51fa19501929e8404d46243906e2e2130820ee00bd1d849608dbca4c3a9e8af6c44e94aa48cf5654545e9ad7dec1694481feb72680fdbdbf95c7b5ada979c17bafb3627669d6b9fd619aabf60454228a10a99049276403b5ef266d8eb8c6d72d4ec508fa46480706267d42db00390a997cb11ce81dbfc0f933c6269fce244e40d07b56c8f0044ec12f8a0b04f841f5bd44e0d78ca9ee0f15fbfe1f46c4afc03960b83c37d2f39cb0d72e32b1f8f4bf484e0860a68f0d8b3c41ddf909ac4d5b3d7c4efc8b43203dcf66091b18d51d5571c1cc96ad2d143b0af68bfab3e5d4ee37684807983a730fc53308f6defe48bb53c323e088b6577647305e24fef966301e90a8069f6baaa0b8f8dfc62ca6e549205fa498f73f5a072a63fb44b9a65c2c9671d4e2449d69e6152e8a55413f93f1d45fbe3807240fa2aeb6f1dd3b012952a8cdea136be7f017723423763dd2e089475f1cc07836e2257cfe8d6d87ecb14bd347803ad37dc04bd4b2373e530869e3987d28e0b90da2b6e8d11e6cd13e2624a0435dc5918eed3963801269036d9865a6fcf642e7879d00c41e3acd8c1eb2aec691f6f09175953d90e4ea56c95e12cf98f2223f98da000b884322cb57388bde3d7d37f2fbdb1546cc2a629a8fb19cba1c6e8096f901986ef2c866c542a7d55a36a6bc989714cebf4e431d9d4e22ff30446d7fbc0309b5031b1c02f9d325d223f547373c4ca349e14e85d4a1b3088d1c495b2f512eb8cd15c2b4ea598736625782d600b2ae7656bd9342e3daa030e11f6b920538960f0433605e6d4c429c58e5b5ed7bfb49d1eeeb626c5adb2a3bd190add64b6f9dc3ae55e2967fb870b36e23b7c15a9ef35868843a7040a0d0fe2c8c274b532400074cd3e7589ca6efe4e1090bb5e41edef21799337a627531afbcdf552abeac42877bbb8dc9d4676f5168d0bfaad782f8cfd708ac2ead7ad138cb686279f1fdf58c2adee4230e4922ff48ab7bc062f5c6918f6a5c6de614613e9845d2f0077fa24f9d1216161a06adcaff4a07ec9fe0bf3a2c5fedf35b591b95d4d828f73c0e7f59cb747b99dd3433e5e7ae32e0ade2052abe4e2f48e1b05c76d2499cfcef01427b00d67698b8c733dc2d75cd9d3409a95111c306b748692c9fc74350d6799be551adaa09f1ad6dcda31f5e460f67e06d768e40982e7c212b64c78ce98542022fd9d591bd1baf2af3a3509b3535fe31ec1534b6aed8d163f98515298ab2701dc47f1f8e09304514bca92271f6bc8602f2344424b6b410bb69a5d25195bb6d069b038e72e7dffe79f1a0291759d5af51869fbba2e0cb6557f1cfae22d5c38aed8f33da45e3d6bcd4fcd23789dd5f9f932c35b64723ef8a8190638c965735fcb400bbad5954a73a8c234c889bb84260ab13d138fc0263bedbbc479fc2d424ead3a735ec5b0801198ddb80f317dfbe84185ef5f797d5d72b4f71128e641cab789ee105cfb0926a4e1a3f9baaf81ef7204ac1ab00b46fbc9842e6bdd997b8a37df849ed4f629028c36dab6c4a0e27780273135f619abf468d8ea3a25814a8018c095d7dfc0a0172efb7c644cbbb14db5f8333d0a7bbd70a52ad448f0384cd77a3f94c31ec258a0ce37115eeaa6b62fed5c8123453809a1c9fc806db38a1541d04aecbd593c6b1e741868764c5a2be5aa9cced303dc9beeb68e7fc96a24806f4d2f280266d6441fc0224b8013194bd13672fc08ace2cb7e9d8980e600b48298cd5a82536396eeb9763cedf26a5ed9196bd43d8256c3b3137ce8115dc16aac3b3da26bc2ab9bda444d3e8dca5723d26fe0cfff259dfce3ed4e52f89d622c00da53bec616d0ebab2a57679a4a8b308dbaa51107220787df9fc594871e687d0bb91b84a09f0f852e130c5298ceeab1d2296b741008acc500d2860ce0915269fd47af8f2426765090f88f0aa002935b708a26a24d69c34cd679875cf46442ae65fb0b6b7e0c85f7784c7bb4f5a60ab94e4a36b8ec67b913e3d663357bc76370accd64011443fa9075a9ca02e057292f0212b3ca46c4623f62b16dae1310cca836227de1f3f0ba40ebb4eb0a4ab6602343222920b151e9c4011810a15a07891df8552bf72e6f46af2dfd45d79c959d1c436dc6b9462fb146636125915027582c380ebf73ff2b8b15c4b21f5b99c20f88ddb81a26f132129d80aa81fc55bf1f29a6f0e4e5c65bf4a1d4a0fa451f7ef43b950a357809a10c1ed1501fb92e447ab44f63d4280ad6a45825d233d36c5c670900d0800ae3e0a84454517d6bc1f0b675e01689ffc156ec75ddfda8eb165d41ec411210803abe492e5762f10b9a44d2105d304dbab22281535e5ff570c6d6c398506803328abbc52fbf5767e510813d60c0bd1d8880f6a88b0fe38c8435d6314374378d2ea937b345e32dec1a0cfb0c64638ff8ec2e832bc99eadfc949ec1a97b43bb51da987e301e73ffda8b2ecfb60ff0470255263069a9afefd7c75e269c8d53f0dd46d6ccbb46069ba65888e6badaac8978a31f6724276962195df087fc6bc8469a4ae1790419e2309b486b830f7fe6c287e366db1c398976a79c60c23b7c94ed66e92f54bb61a1a0ebf6a041d011c6cab0994fd80df84d6118e080f072715ee03402bdc9398f078c494144629728edfbc61e26d6c7beea2568c0fccba7712839197799683e359db3710b91ed5f2cbc9e562fc4e1a2d9bf82e69c065b3b29ac139f03ad191fabdb544755e606c59807b6ce4ad4051decf223d840e4f63b7d0a1a32a79de8f01280c02a9217855d88b7bfdcb0f8416432b3539da890547adf85fc5cd367d9db1189e6c79a1bddb73b701b47c89d971c8749d7ddfc708959b6991af53cf421c9d88a5ff1a8c041cc7e94b926f561a859dd417c8d7ce169ccd495447322793499b97668088d899696344ad964cd94c471f80f97ea5642249afbae784d8003a07ee8f588253271f1eed3bd520722eb4fa2eea55059ea65e34572c60fa52489a4e31c029a0f034a1d449eb87d3284abd77858bf7910ea8d0cc0b7827a976b3908cda0a84d632c7ee4a5397c9856ee019f8f93fc0dbf3f374b2434789796b181d99859d3e78045f0898bbabeac292c9a545a931df70e40d3cc108ae2ea732bde581ec67f91cd860cf94218ed63941b1bbbdc4fd443a5b62dee7ebbf1f00a35d1737488a096ca649d118a1b4d3b9498adf1a3d0a72afaa62821639eb7643eccb5934e8354cde6328608204703abd6c8d5c2d26e460381bfacfdea6ca2abd188b4f1a98a5e8431f228e4e82658cb6f2909c49ae72832e8ebd09c1c2a0a588bf490349614ba270fdb94388ce49c8ccca1e2b500804140f54409267342c105bea3c6c787eead27322e8ca09703b7413cdcf6296ffb438c6ae1a6c4620cefe2dd0b16dd6d017ddce8457134e2f89d58c06608bbe299be9dd91f77c028813b6cd53f6debf885c5d45685a42d035744bf77cb128c4b0fb85749000dd0ca4671b26a9648fd3c8fbfafc1bfab8be9ebaee200227bc4810dd6aacd9fb6609ca331e54b5303b58838f39784477c80e04aeb1a1fd63e7fa6568a434d675854cfc190e922ff5583d0e4cf56d8a50700a5b1f67300b8f8fef2acf72005a950f12153f194cbaaea80d5385e9236b0fc53260aa582e69b4c3f9f5b0e6a47e28e780b556eb6774b1f75697f0c45228a60bd608a3285395b9f5c9770e8a5c11c8afbf79196a854a92a0f3e007ca8bf14964495ec65eebdfe97c592c509f57fab9624a345ee8168e76a430992fc7925a4275aac61493bf12f7ced7cd3a14aa7c8dc29266086ad7aa7ab69713dd9fa418fd0e5a43525fb1f68ee103df4f52a6d29277d51feeeea86fa830366bf0b8c6fa5571d881a7e82d4b7f487a654152f6d6029d504dcd60514232d84fc790a245899364d944207c8cfad8b9481c41508e11432bbb4052abc4912e8c4fa20d487d1964bec0be49224d60508e5afc2ac903e6389431276c6cf4656be7cd5b53049747e5bfa2b47d50cf5b4756c87dc9af30459dab09fa931fc9c6362339ad3c729ae13189ad538c8097f53267fa52eea1cd7e6b8dc4427c36849da699955b4abd18d3b10ec3623922d495487fd38e540871a69719a77935618f66795442194fede38075d3600e6df797f38ff491e753bd31af6c0f3cacea884c0b62d2e308534f9baa53cf4f3e5230a1dc6ab00acf66bdc6a44760ee75fee62a1767184c852534d5f02e11faca1429800d2da226c42b82e5fac89218067bee9365942ca8f9693285aaa98290a7ccd55451b4b16d0fc17a9f6376cacda42282939115732d20dfdb177005c20e7852a4b161d6e606ae2f88288556c41dd19c2656b546a0e1af15f5368f63290e3f7530684c80f0a0d5cca8c20d0c64a6723f8375283355aecd0230444f6f2a3a5b156c0707b2635d948ffe2859410fcb05738007aa0e41cd060ff20c26e70688999e52c7b1dba716ccce36dea3d70b3e32e43a5cf047de3b057cdc1870e24f15294408c659de16cbd937e9fd7e20de08df9f7b9efa7f44dd9472a8b6a1fb9a3ad6e63eb28fa6d7a82af61245a5d9cc21d594eb670bc70a733c7edf70a37de7d861b0943417285ad6b0f7c87899235a892bcf25a37fbc12012fe0d24d2c019271832ab12589d0d0de81914ef9d89d32619862bd7cbc405bd0881e34267976cb18c62d7f6fe6a72609ee8c08d197f801e1b472b1b870ca0515125e4bc0247be43bb959925b41055db1eaa204d6529dcb4368c5d004ccf7a58a350d93a81a91b4f866489865e0e490cef54ffbecafd5e6ed8d3bcacc32a2c7d08c9bc9f98ce0ebc6b93518c87e66046b0290723c5047bc773cd7751259e35ece5c880b04f85d4ce873736e648efe11bc1b823a07a0ff8c6cbf15387b4dfa0fd0cd4568450cf468d17d01dd01b417d705b3ceb5d86f4809e7e944382e532d99288ebe023480bdc17ba8673146075ff3031ec93ee9516c2a5800de32ec7604bd311ff959320b7dd88de83bc20d850d3425eda31286533a02cd628228c8e90348bf749ec40b5d1716c7e6d63e3a0be77621d86bc3b3a3d3ac1620065ef4e25130215a49ea8312c4681a2c548d8d9bd093366d3c923ceb86320b56ef84d29fb1691ea673a311a883e16bab6cbc5d5005e5311fff76d61b68bb4a32bddd3f9fba7c509e04fba8aee29d02ba40ffbd2c4266443877cba9dc18c1a6324baca6a6b54cc41b42d11647d8917a260fdb911d5872dab819f72ae6f3576c00e3169ba0b7a2dd06765bb67df0ada8a1eb412527444d27d3f13f384249ed547b85a70d8e6f00196d3e19b44dce1f5b152463de577952cb1238023a973ea392ed895683a8ff364ca5ac37c06fe436ec91c7e91363dc4b0fa194012ccf166557804f9c12774e1dcb6907d2f262a4b0dbacb21e3d984bb725b3e48298103c97ead4dc958e5925bef578d69df4cc37b97869977947d3f49ba071cacc65159dc11837e50daf12e5969b9a52ea613769a65137ab11bc0d15eccc7d7eb98c71173f5cd548f06eb0e8507ae04d7993b34407d389b0a046f24e192c012306b9ab5b4c9497985185430ba511aada683db869352a37e93948b2a7d75a2bc72588d54f13ec7b886a558258208e4005e7a0317a721a57fd6d2c4ac6bae4f1ecb93fd1dfd72debb8f7da4b986d26aa055d2d9e9a1b15c89c62097166f2cca5b3a133abcdd152d69d1f13ca0b4708c264c5d7a298aa5cce299e281ec9c95755b33a1c3d7a046d78c7eaa14df33458b642a6636cdfc0f925561f68c1cc7e868d2d31b1e5d318e419e28d73ec1a206cd694ce0cd4637956caeb778630bee52691252958def97a88f4c3aad9b29133b3502c73de0622b8cfd9e6539decdb3f356040796bd8c9de8ce0360969877b531636694a48b063b8f350a503e60104c598f2d42d2b6ffefed4f83e4086a7fa7690b095f867784e99130efc98a39f8cd322714603e072f41cc2b49570722375e631a8691cb32fac31c84d7a81b490326246e5f6ee53ff2cd0cc62ccee594191a781e3d5336d7e62414c70fdce8119c04507bc741436c56eed8131be3bf04142815e29f05287bf5d88dd0c1ff041428adf0500f7145225d5811a6a8be261118c32af7549e53f4b10727da65702dc41aef0918cbc8d75e20ce7e46c2fd7e7145e2efba17a3fd5e865964119a2785102c1a4fba30e0cb8ba128ef9c7a3c105fac94e51d1a8c47c90c093a298eec3b4afea3144832ea58b6392476b2121a8ffa50ca8d8bb0670db8b8bf39f59d71c67b6c1908f997201f05d1dd5320ef3fa889c07809a87005eacd497a6beb9e40754d45411cece865cba7ce6cab1d0f5c2bcc6dd14e7cc8d0fbcda8f446893948924e8e4ada01d87f81fe586edeab3fc61c06a3fe889ed179c01d18d5d18d2ca2ebf4de4266f1487235dcbec04c382e67b7b96ef263cbcd0f5b8f5eee165a5e307294f35ca0b6a470ecb238880379efcd3e57479b64b06c7436450b6dd38353709ed7addc9e61dca4a69349350ec90158c7056d52fdcf2165e2cd8ea06c8159dc20fb1aab5358f186f8496864aa2fb7f005b0e68e5ea7d58ad596be96ddb6ffa8d03e968b2c599ff49bff40ffe4a100dab2e0a9af88c8853470c0b0be4eb3e44d03decaf0c2b3e77f3586658099743074546596ddaa0f76fda9c4576f061cfcaba691d20d34551d89838c9f287169bdf7a4bf6bab4d845f295b1759ddf06cb72e0349af25df4e61f83407bf273295f84e712fdcfad67d4700ee6cfba8da7c724e0280c0e8b0bd5e9d94ea5ebe3e17a537ba9c0e50d67bb3fb4e4c16f50ea8b649a343cbe72b77dbd59ec588bf915790250202dd10f3b3f5a50972bfce46145a844fce93e7fc3a39bb8f5f264b404e0ce551ca7db9000ac3d471939e1d78d29affeb6fccac41e45d7d96559b1735cae8cf7c7e32787ac64f1ee0e073c0db24b015ab3b2a040c13fb4192420401a03bd87f85ab8ccbf80c0f825328c1db39c105b8d2c7ddbefa6b69cd34d5e75f828f543c76043dab30ea62387e6e257fb20e6dcc2e0c8590fd3bc6422653a582abae4dd1377c1cd6bf4a2fbf9833b99e91e1780bda61e32a47450ddf17b06d347aff92d1002e27f177b97751520827491b639036dbb483a0260741e109786e48b8c1938126b895de91ee94f073103aac2a3a58a092880cb739c1c63990bbb160442a3ea3c62822c92e1bbcf5ca26b114a958abc8eb6545beb3e93e13811d69f52c6a3098a336a024881eda852369d6f069c73edb6142c63e1d67607007b6d37ba494603064488c2daea01d2b542de8252cc39514caad8a98241538c42d959de569c1d2043992ca71ed59de90b91da4276a68a9517336254b041d202d4f04a74d3667d95d91e101d0cacdd3355fe86abbe8f112a05b31216225b114f63ebc9204d051d2d54657c80e661124a008d546542d2876804db8da86114099b19ad230811972a196bbc76e1bff4075832ac084ce91367c1114663bdd207c10dcd7173d7a546cb41df09517639272d6252f3816b5df0fca75b5c4f20c91f11d27b70b9d6685b97b46dea073b67f373cef11aee84a07dfcfa75c162efce3b33b576f50e490717440fc336493572651ed9e11b947e382ba64f94f246d31b51f82b02feaa8bc90c19b6e19edf9263c972dca1a4cce2958cc9eb47ac4e5b1d3955b8509952b50c7206e1c58b711a3b1b681f110d3e6d5afe66c8b57ec6d4bdb581cb1e2d6a07081b6d004bc7562e5ae4ebd8b034407c6818a6f6dccf49d99c77e7b2e19908c76bcf3ec12b3376af1385165842115ca7d4162644fc0db3354e80124b5c291206763fa8c50a3a19a0ff051e0d46afdc5e8ce608ab25032d760a1582320769b439a3f958fa294c79177a4f57c85992e6f3436e23cb9017e935732528fa7661829afa83372d51a7c63e1e946cf4c9e62260743436ea102941ae82cba04a9ea739b550998cc385506db268a9455c911e0a1099f755b167af95ca0b468a8913e7f6bd90809aa429c7d68c7104577883f1c22743ef09ec7395f5b533a8095be91b7c9ab6884769131081dfbf48ef8bbc4076e824f3ec51b460b1911a8cf3eb1dbf14b696738203d5ce2bba17f45fe1b4f14d02061486500a292c46becc7a688168df040c9ab1ee8fc6d4030c3e6f06e851cc54c881c14a82fea782b1315b22c7e3f0a1da2e5db0942dd642a7c7c9940b4f47485651d9a6fbc6cb86ed4f5f1d8d99ff922828c2ea50270ee3ea4c864cecdda00a894bdebdcce2c3901ed0dc601830aa276ea90198204146accfa749a74ac40d5b82a7b648d8c36d9abfa31146cdb284a60288bfcaababadf938f67b1bb223a1bfa81f0fbcbebd24daf4ba41751fdb6e4265c5a50b07ce69c4f2f3d96c35863d4445e188acf83e5cf76bc841596f86ae16f47e8f8cb1f57579c38b976e7a7386e8e6850cf778585e553a3945e61e54050923ad7eea7639ef52f26ce0d6766887c1f62202a1b850ca3c3b44a77cb04563b30ba57dbaf2e29ff450ebf5d60f83379c5af0e7e4ac01de828db26c4c2f5c11d7591706c756f2b6d1098b852de236e555494090d706fc11a3f4f9a2d115702c72bf211b3cbd8f052044e28f4f2f71c27711916715ad96cf035d1ed588efd2d17b20b02ced01a87272c05cfc99b9fdae190b3b92357cd5e4051d5b2bec459428e4cb0ede41e848a0a31aa809208bb531e032aa797e4824596da07f99972ff6d6c1b72c911655b01530221bb10c2b953e7a1c9bc808e751fafb34db23cb349ca12bb9f2833ab1ab5b1a51c2da99cf600917e6264060e10d2db35099904f932622ed48360ac334c7788c3528e668b152e9262d802cacf413df119443727ec3effea4468662fa6c6994d02159159f0220b73496906732ec3c4ca4c9bac873dc90c479ace8f52b71ccb7e549494666658251ccf8556c7adfcfdb9655ee704514a262c1076cd70929dce25c836573b069cc26986c3c855824339d761e4357d482f5640c956a733fe214b6c0357bc247fd8e9246eb9a256a20d5a10bf7b0deab4b241a92618c793f688a1f36b0c2160ea2b2d41f66678881af4dd91058ef52f662ad0a49d75da4073814c7c601c230ea59d524fb8f911e0a6546af7d6c7288c3da58aeac4e1abfb894811e212a2f9f541864d249c4332429e0c0667e463279474f277789105b5ba03273f0f319c7185205b18b4f073144a1ed081c9162ef18d71c652f74befe7313d130941952cf4312338f095163075c91785af6c8229f2c609c6909e6bbf117892f9794b67514f2c8254fdfa5786d5bf042b9922ce2ede45dfb6bcc6e440e2aeed12788c349eaadbd22cefc184c663b1b99ede3681cc52ae0d81cb51eaa92636f966ccca8c7177fb0a21faf331ec03e29eb4c3edcdd5bc2e7db0f29f2972668872cddeb0ddc7983c7f851cb6636bc52acf62d283689e1e66284e079ee6d3604f18f8125ff92b0dad007677a43ae102dc6c21b4cc31599e26d03c5b9ca1f1596a631cc2d92c13d014259da4ad2e027bdd2cf25b72dd0dab9e41995cef1085c2e8e1846f3154a4943ce33f92ba6d1a07ce238606c1c4d415fa78a046d7e0df504df6fd099d112f6c0c1f19b231d8c628f450668f1e31a7f2c61646b6c63c3fdc39cd49cd21853a22d40c66a6e5378e82de2ab0b477d1bf8d50f0081e4bf415caf82e04b895aa342b9e4c0cdec3ebefca5da545faa162628888333b7e32c0bdde0c1343f62ec2f9a2fc23a456eea48de8cb3a9a2a4085821f2c7f749c27d2144afc426878d64829245fc75edaefaa2dd0ffb94809272fcb776b2568c433069df6a5c64d440f06516539e2630cd50282cfbd9151695da13950349541d22b29fbf936778ca390a27727165319701ea0b8b8418f0b4184b4725cd3eedafeaea12984cca61a44b77dde4195dfc8a2b3a9ab1133bc251204e8e5a24da39f82f2c64ec3ba41a7e5ec7bf828440be64073bfd17448438419f0b6399282f2a2d4f335f9ed7d9f748b379c2faf344abcbd42e3a08c648a4205fdb037ea9dc48708675685c539e9c2b48b9dbd38ddb1d9033fc41311c35b9ade22a86dfb93415cada5646b6c67c3aa017ab5942c744be4a33edc089d7bc163c224b0452f3b7dd495a10eb1d480b7428d6dbdca88a504d368f6125ac15350d6440b60f3a0a10450858ca80f93b44da4c27a10973cd323ef86199932585250a6a3e3ab408c035814190e76cf93da062b5f087c8bfc22fb91edddf66ead5450e2ef9130068d78f485c86be9802553e8e34a70ad2545eca03885633881b85507c65bca2ab747b2992bd03624b6a5933bde7fab0482b16282171c76f6fd013b2c3daa3e7d5174bf8726d2c3f402cae5f240f5be729d8b024a95fb49ae6245f6f02dd49fa511b5de45ea6b4f0d8ff5d402193912b3f96999b4a7fcbed572147e0b02f1d3a78f1cfdd6300f93b9c4b18a64efc1b649cdc0cf873692ab249306c87e27d39c136c828b94163fbed501f392989ddd99c817503616ba9c453b3b8e4326516407572dece4e4c04dbcfe9bd76face522671f1318415ad5cd38fc7c1b1972199ab7e90fdd6bab8d63d3613af408f6acc76b054415c06050726e684ada91064409aa081d145761ec27d891df81e195b0e08e8640b68e126acc23247508b79e7e9cadc730a3f451abd483f01cb6e938758216c0f6b1d6e7b67d8a99acd8c1ef1dab92d2d14c977ecec03b872a74f7632a5e1e318749d923b9f8ddf0c0ecee5b9f0b1774b7b81e91b5fb1d59fcc13c0f16993cdb78a2457e657edd9541476670d447538be79fefe945f0fedfaf24b79b030ebb1a16536bd66b87b23a3f4d763b8291db1cdbe4ba366ccaeeb324d91b78a2f533bed512a63ce35b5b9320b643214a6f2c69c45535c7fd1a3bd0b3495a59e1ae8b2f85bf3a39f3efac8e3503fe01ace8c5fd565ff5cf207620c2a1899148d9ed0816bcdbb2ab8574fd54c84d97cd4442c0ee14e3dffa83e65df4b17607ef01dddcbcac52c88363913dcc2efa57b03a6637ec44a8c1e252214e728d915c0a7184b632a3e4f1a92b520c34488a45b57a27c2e98c991743e0fd8f916ca874364abaee5744c61f4024966ccc69482af7d817c4cdd00369285a7debf869fe646fd0903753b1440995a3bab952f91393f1401d6392fc643e213146ba6cc79940cdbdb35310d4d85382a2c1205e528bb24263e850170540fc1d071c4223b441f1eb8d783220681329d1c25b35480311bfad007d8e9b85425956c67b19e2bb4e62b0f6ec495595b37a96aa053d0b7dc54a2ae2223e1227e8fc3a16229e4f9a904103e2376898c56a6f7a032fb17cce48c298faaf103b433e7edb7f4222a671a47800d25d0fe2f39f7db4aa0119b7166a9cbcf1abe35869c52f801b803a759266018ae3c349ca05756310a64203f48905146a81f8a3d9cd0091a8fa7cf378525e350aef1ee3876289b166c10187b9126d8af1ce95b482fc95d47b29b11bf70efaebc56ae3378d2f9b3160907c76f80ed08d5ae32628efbe6f216cab582a0f693e8bbed4236c06aea5d886c3d4f7195033546dfc22d731aa95b038fdcedc79f827b4567e0de2d7f86c79e4fd0d491165bef6b031f83e2078847b52d21fa6fa6975f37cd0e50f3e25e893f704b6f06cba4e4846580f8e70590cc30660c596bd291935361fa23f00803277514e5f585709a71b88be0d5a2b051cc41a5135402416e307d5081959e85af76050b453227611f6d9ddd028dad8805a3c286405eb92f010a8654a7c03183c1bee9173a43bafc2b0cd34f7018360fbec1d0bd46f215fff365159de3047f461830b66b6527eea31baa317a4b27b24ab6013d434467cef156bd3416aea227b5386c11a18768f51f45ef9fb511cfb92dc127a24336c6045d3788951c6fb2c2ea14a73206b7c69d03a2991f563a9eec1fae7d42f793b61295862a7028bafee1b9d5546ff60d8350e56ba071b7bec964b30f4e0008ec1849bd088e1cb28b17366a110a6b39796408140386ffb8d4603830dd32cb4117f70da94ddce89ff8cc0fe4ae0b3355fb90b1c620fa6d85c3b8416e8cad051825ba064cf27979bed061b0132ada91b9f19259f83e5f419918b2f05695e690b64343c382988ebc69bffae31fa57d1b713111465030aacea73174d4f0873094cbc96817ef66cd4eb81c1eae442ebe8792b388a68062c039d16071cf244c4f191a07aeb5a30019c2c8d6d40facb5538438d0c749e5dbfe78487138767b40b47f499790075b8a5dff57c70bd67f03dc5f73a18871de36aecfd292bcb0a89b6c0e33ddbe35e6a541904c0b8eea67145f9cdb4fa0a79d7a0ce50d812bf579259679360cff1398fce1dc06c4599a00332959a472a319a46141cd07805c010c58555e054c56ea14b6087e11af74c0f6b99c82e26cf88199b95e03e0cfb2cbb193dd27233fff25e5bbfe64f9863c1118beb13239fdbe3500f77e4e02606e9c7d3191b6cfef270462df39dedf9430cd093d0f85ed3d0f22b457186870c036cdf239b5d177d05d79dd4a761af2ea46b3a50409e56da306422f4b0162347a7e79e9468c192c3ef773fe6412629dd9b6b0ebb48335deeaccf31a17bbc45df14f123bbb6deb3dbf854a3fb0037f6c88f7c3482bf8b4da1b802ff1b8322f64cf455f2d0b10f9ed120f1c93dac20d0838de107eb9bd1318a61f2dfd8936104efbac5f6ffb673562329227240b2ad50f65441ee15ec930dc74b087552f254753f9ecebe2d63bd77ce6ba9a6cababa926796bdfd5652976455dc1da7ad0ff873349ef3dd10a1a5e0b92b3a6014df06d80dfa692cc8407d163b5c0c9a8ace50d1bcf164636ba49b92b7d49931405be577114347cf1c4d85c2609126025ce2080783f01737879249de7aeaad6f33e091d54feb4c45d2830f88efa01fb32f0fcf67dc66ba98b2060acf504d0ea5df09eecc5a501ca7ec9901871d044145cceec8277a8728ea34483fc480f6cca223019c9c7261427a4b418e1d0ac40dfa170603193598cea1359b3291ce8085318a7cb67548aa1f1243db75719da8f17135064b984b9e5fa96ff056f638837e169bc103dc360a284c06d3e68e79a91ee5dc14ca97ba4242d3b7e09ce531fef4582ef2383131ff5803a36ba05e260984eab61be17d5607d49ce5f6db11c50e90df29def9b44e9e48227c5a6c8a1dd37b5cd59da7f40644fbfe795e5712064042e259063b3b834aa169f3cecdbc2c2fe16ed9d588942a664f6d17a9869f6532680f3b09fb420a875c225fff1fa2e26754b84fb4cc1ae54e4101457dce3d4b2c9177c78f5caba7b5498756bd6345b18f2d3b9a9a7e56289a368f4893b362ea98799b4a76a89cf3261cc1909ba5470d3e078872f1b7287a36c986d2113a29a50964d5c80bf87f3ca481cd6748a91c31e94e8ee8cfda615ab9249eff787bc615e014a11e75cae53f9f9573e8604bff5b880ef8499703463db5a71b093adf60981bfbfd00fbaa8c6690d0fc27b2aa75d58570bf3c1fd77912aba09dbff32274e73c575865d5bc73f9f1cdce8066f925ccd31049c777be01dad7452349408566f4c2810c13b95805792513d0236b4ba7e142e5c8c7dc26e0a628396c45861b614c5f8d627587adb6574d276e68b0f25bf0e7f10e439e80db2c8370813b4d2b4a03c6a5817767d5b328d1092ce45033748f570d0ca32b19d25fb6ac12c6f8b484a8e2ea509f4a11b7996c9e6d3abfe2f1d89ce3a2705f2a1adfeef2ec141f1f894bd5d5fb9b605bec011c4753b25c4f2d4c5d35cecd409ca6d290eaa52e416cb0d601918098a9a9dfea46cbe6e4ef61e67094b313f04448a5e0706d49ecccaf23d083dc8f4c8eaaffb8451746ce85851894960e7df687bd24babc959bb71084e93a0b575db7897628675b9139ab6a9c31bddd58c014a860a64103053ed333214a4e8f928459e521ba4bc1f1936e7e2c0ad3a4f35f5545288345ed1072a302aaa4bb422d041ae5518deaf10d869d939ae43d6bde03b25085483e13311288a27ab6e211079d9141ef89664ce6289cb2dc18097b444a5268fc230a81bbf4e01aedd925ce2d1e73a809f5c1bc6a33e91b28059632d1c7feac77df453a38b5357cdffa0d234d2a86ed0fc34d019e7ded9d87cd6dbd537b474d448af3cb74aa45ec1c6bd7c59a7078820f11e8bd9e8e8edeacb24372e4dde9451ae6649bf4abd605cd6730703437a2f36916deb13b8e8d183bb4d7c32da9720e9f1c23850663bda3d8c268471de84d892fbc28e8ee22e3369c196fbda6124cfab2c54e15440c4e27e4429bce9c4297287f8ebe939dea95324eeb981a14897bece61e35701393eb3ab659a3159ecb19e6d09dc0d2a630a58bdbbac1e0c536f2b6e604eea740054e425bf34f8895719a7be3a4117580571087f49088652af6450ec20fd209020693e31fe58b18eacda49b3b245dfb0ae0aeb0d1c0f036de53c8096582b813db096f3df7aa38da5803fe591c14166bee99118e227b2c81149322489a56a696ae3e550e23f88224c8db8ca0f048d246c9507ce33f901b859235a225e26bd0f35a74a6a7d85d95745ff6d45ea5aae51ba42f5fafea5d64f7201f905155e743d561cab3f0dc8d03398852b8e24a1e27558266a7a868de044c72d3d1d064775bc9de806a8eb7d2d735d70e37f34c33e4c1a08828f333130106f69c60f5648d4f4419bd6cccd57188417521dbd1ea4f0ae2257032749fe196667ffecbb3497ed10ad35873c44db037ff18123195fe916afebf28a5fb90d91c91c702b4c4f23e4e9fc6badbf1b678fe76ebc11333a6db4340e9da126dc84c2ca815ebeda2f7ecb7654df3d1958a7778ee2678bf64578ccb93cca228d770494f0d59ec89f1b2800756690429060430e77c0b88fd7c2214c559d44474b39fe269ae6fee2ef6a35d70b219cea7f04bcd11706e2cd1f56fa8ba8d399c0cce55b18a3e995882733ff0c63c5cf184f3a38a91a902b433dd3c2d3a0dc4c50e30d5f3f9bfd7f60519ffeea0ac96d4ab84c8b8f329161f4622656f01f7252006f24ca1f23d8ce243c4d070a30183f5e4f1779703a65a48da90553b6e410738c84db270eb129c82a62c26f812d9628a15f45a8427f6f0c14100e398c488633d2ac86151388697db61992fc4948da136040ecbc0eb76aa7aa07908b72cb2bcb719a54414c3755229bed338306bd4b5491fa29ee3a16525db5c1007033db451d5cf0da302052fbb766de86f3569af6e46ff0945858f9dd52f2a72b2966d7c54ca7131aeab8b67266b94d3871c513d52e3b532b00feac4bc93fc6399237d0ee6d69665b3af154bfa646a3a578b9f98f7d858893507adf1221b073f2e4c50b274ab280e1b26a169886e2bcd4893c15548f11c7cd830505306779061add04b1e5734bc67df84980acd74574cc205543f991f118d7284ccb4c4d9f54d1871a00c6268a48f9b59dd4ddd4bf8f861a3cbbcb5748660a8182c6cb3e1d6bdecb54f56c6933817ba12afd74b8e8ff631203fa294aa2091f40e4914355da6c1f0bac085388d17345766808ae5abfa59218950dd369c6e256870bfb5789f5e1d4a97340f9a962e4937aeeb0defd980e20598bdd68425518b018d37067d1c365bbc247730db31695240b2e2883c58a8edf1d9e37108b7c5f576fa2ac269b26883f541a7dffb25146bbae4fe3900301fcadcb8bc0a00b0fa316ff8a04a6c55209fb127da406f9674009c2e20db614114fc5743383c2122c52f27daa70ead2d5e00ed2a50de4b67d8542b08675fb39539adaee2338e8fe19846d9a18e6d9682122c8a0a622a5b835db000d3d8318a87a76d769d872a8ccf01072f5f71058770d1b1dd5cfc5a5af457e62cd01da88297319668c5a8645c102158c5e7dfad2932711789a44979ad7e7337a69b7dcc29c8b1279b4704172adcadf81ae682647fc684351ae5da0ecf6ee9d900cf8d7d29e7ceda7385b98b2c05f069991061bfb00b1c7dc668886954bffb0ec5a198982e4ec77869fc79da7d95b92cd901d8c36f6771a64ed81afc8fd0c0d8d5f79d4f919ecb4506badedaf8fda5e3a9de7f8dea577def88c1e0f1b0e14e08a47ff85c2a928f95663d6e2f5d1e9dcff9f001c1306db2243ab0c34ceb26432c877597602bb2e8bf463d1f9afa8e39de67b3b43f54e80bae59896dfc7569b043319cb53e379215b0c8c8b8a7c67f2e6698d72a343f303e715db24d77ad2acfe83d3fa1a65d1f94d719c8d4516b021ae0a488cbc52b862b54cc3b2a858be86a9437856a978eeecc851c8b0c0845cb597ce6b093dcebe0c05b375a5c823aa03e0449c9772e35bcc145c1bd7e095afdec8396017017895285b31782509314209e3c79ad3a9d80b0f7f54390d54ba0699d23e53fc0eb266fa7d777fa244a7dd9dfd7d9313f8cd3980076e5ab1e62c6aefd049aecb887ddf2323fe90df38b2bf76a36f305ee2b430ceb0b2879c63800ca9dca94a5b0dd6ff768d516224ee7d9fbe04d42ae16f8967182d55155f0125526c8cbb1f651ff2867c8f301621f65dc3334fe96b5ef49f9d913c71420533ac86d769173c2e9401ab74c243696de8db47068b7e0de56b63be10cab5a6f09f7740021fb9be99a60307a90676a65c5578f9963a4cc256829811fb2b45cd13085e33c2390f21f9cce78ace23cf2788527024e1041bdc1a430f6cdc57f36b617c1a45267990addfc14380ddb3fff321b0eb61bae24af2ad33de982b0901cf760ec0bdc59cf2a1859e9f0e4269c3e82c06c354ac7552230d26f955da5df27b1957e9570eb687b724da2ea8a377bd068ab26ca9cad6d50abd1d87be51c5d15186b4e0c898c7db513b0bdaf74df89b18fc88770e32e0263df00adfa8afab90f160e7f96c33e89d3533fbe0dfbf6e1d1e0799638472e75e01a2dadec7ff6d3dabd5fa79f3d5d3d74f1ae2ed72793031290757dbbc7136a782db59ff8c85370b2c08025dfb768a8d487797c1fb3b0568af71ac2cf2ce91822fcbebae6b7b154747d6cc2855262fc201294547a187f5db21858930fc157c57f9721204018aeef0bd79ec5d93271325891eb61f06fb70e6d4618abc0efceae62c20310a9063371e5cac44185c78c67254f531638d9c61ee5fa2a4f02dd8b8327c40b271ecc475f411375ed945f2bce50803d41f84bba76bb3e48fa814d610b83136a0589682a57d852f601a757fc627000fbc4d2e2e9035492d7aef38f07aa0b2ab0e8d444d6ca9f2c5b1f92253de07ffb0a17c7990a05665d1cd97f57c089001d3e627598132e8b9e963589234398950076b0876b316eec96c8148b8a2ff3fabccc76c488cdd72a928f6a53ed3a95296833ab8fec8b77be7f10bb1c14ee36c17ebf3108468039b7fdb468bf2f0c6982bfa45e09d88356659a47e95f2fb4952ad29dbc046ad40ea9aed96027fd6243fa4b0d4e2927b06ef2cb77bbf1ca0d66055146aadf8c967858499ee6c85ec3cddf1155c4970cdad5eaedf0afd1c9e7425871e5a1f0d03aed0f042a96b81bb19772dff69f012dbe5d5ef90d2c5052b493fd9c2d0f032d9ebfbc648d5c887cf90b1fd5c93647b4628a8da8d0bfabfc0cb568faf2926d741670a2bb384b7884da13df42a20b91ba8da822951014bda239c58d4e16a4e7d046c7082e741a1510b98c376c596d71227b03550f4cc767bf3c414bc2219c7e2a1cf049bd21cab406de78576d9be0c7aa08b2c24dbc34c752a6466671dd05bb9d0ee2a35b3d5b5828f3e0ce7b48de3f4021657c997e98db2004a823b5e7f98e5fa7d010d6422a023d7850f982512a0248837c6eff2322fb7b77b6862b712b3d094eb835559d72a14689b014ad943bcd3d978942bd1c5059ead3f763339184e10a9303b6b117e2de1eb3003d7064ebabfe52136cb6c999065ecee0380588c7743c848580967695f6c8e67a51a1286565e2a01fb69b104d74be196c30e4270505ef4491e8c8d0103116093c84414cd8697484bb6357465350c180a4eefc6a8399ef384bb39ab2e52f8ac410f13741d8c52f0d467a5462e4852c208ec49f65635abc2251f3a9d7975774e076aaf7971790b78aa394f1587b377075ef14d6ef3acd7c03a7b805f3151bb09847b4045c0a2921ce4e448fc1e0dc2c7833bc5cd4b76de9187654f65e78de35e0c3db36a464fff70f295b04c0fa2c4b03f660a5e875f1acafe4333cc07706290abc7fbae88ae1fa8cd454ee1150b6833e437fc7cf59c28dcf99d07123860aebf1e36f1d25f5c7f4dc3fc578f615dc25340ec59fc27b0c0a5d2b229a3bc7446e313534d9156ccf28a2dd7366ce439da125c124aa8cce12f62f49b57b190c0efedee7d9f49ec8f91013f863474e2df0cd8782d978db791f84b9027bc804916bea310002f7ec933a7f00d10af21d1176aef1a78249ff41ca4603b67ded5bb46ecb6c3e084b465e733cba989d90a92c839bedf72b51108d7bba586494b95c5d41906474ca12e87a9f88e102f0ec7d9ccb23027534bd71218b224a5fa1f21b21679bbaae9094339aa79ca68e9ce5e4cfe626d7cc98484f35db7ba5bc1409044b5e3f6888dce2e8709efd2283327ea95f037c4cfb2082e526e713fb8ebda8417eeab48e9d8c78fbfe74e0bc08129ddc3895533a2926798009eb2f19c884e2256983882467d876d1f6ac0bbf5027e24ef0dacc9967895c09a803e858799a4ad6e5a458b7cc3f73d68527f36ef3f2659d96c945ab4137241ae4280559092d502d739c30917b3263e7321b53bc2e15fe5fa9065ddc2b81d2bc11822fff8ff012c384fdbef667b7a3e8aa276126810f2237fa9a7b1c96c32b20937963729eb527ea326982b5017234ce330a12ebd1c93d05fc06decd5abc694d046e0a517950fe005ef86dc66238610be6716b67e54d9f427c845c9965a3146553794fc236b2b050d7aecc440a00c3d46c8a5149dbd902256a1b4b8073bf68521e6bc186c392b6864311d21bbbd72684415e21f0428891655e96eeae276a1958c8fa7ee031e2bba2d75ab525ae2d3100a20741823747d892c46835803c1dd38ef419474d9d0573d303239b10fd6c104891cb98554459d2ba41382241d86db4049638b1e9eef17edc3332e9038f51b15123f95134c575d2ac7e8921a48d38f7e5a9ad6d25c0793498c25347c80cc92f6de08be9c5092506dbc9a1c9a1e1646cbf7d21f9bba110741ecf26d9ede1aba247b7fb02fb8e80f773c6af5dd4807de848e57fa0fef3595cdf71010152e67c0b4988a28d431faf8a0ba01dd423e3e3d1030f29643fe17bb72f29a1dd80324a5f92ae414d907655e1d97f688b0140738afa5d1ea610b5a8d7348a508cfaeaf2bb8924e462b6516cf15a5f882b1df813803c4cbc0f1b821ff974364e3e312ee21c2a6d3fd0854d8e2e086979292a2dbf43d3ae08a016cfc384680f66cb64c97e8fef67917d2d3e34228ee539f47ce0595825361a264187504b2920c1182013784d06d418b89dafc1469d6f4fab5d8386e940ef11e46fe685cce87337929155f15006687de0d1b1bfd9f9487c4e77d623bbcb9c96da745ffe477dd362e7f6bbb7f37690c388529cab9ccbc577ef96cd0d32ec9981730cf47b2753fcc26407e27aa5b32a229ca3613c02806859097b75cc96c46655fbfa208aa902232821c2402e780cf933608b98f0f3c52f79b15ec196283f481d006bd43fce075e5618be101a717c810b2e073914c711549fe22c39bcf25f1d0b4c636ef92c2fc97651011b59f99c6a05157c7f7aab0fa1645cba9e7395dff61e13e6552bfbb2ef415f46d5ae71f0f7cfe65f3c5b39b5d34db04c5f166702b2fdce5f04c487ed3028accbf3da510c05cf104bcf5633ab4a44ea32df7814acbd72fefaa3f1da9fff62974d833c0b732ba563634168a75cbabd4b4785c762393ca75efeff7bf5150478509df5f8709fd330df110ca2198b5e4ce92fc5c613e4d41c21e79029de18c01ba130972557153d76b21c04b50d6e1a013158f5c47e8a1c77b0aa5ed18ecedc4a523a5d6b0aee7ea0a75572a0b54ad2cf96489577c86edf4e906b1913dea529cd7e9dda1310019c6dc51b4641a038ffd7924b80b9af6a12dc7f8ab09770612152004efca8a65395dd248c96aa4845452b884ae48ac74d7eca51b40e9bbca282e14a265938706d6b101dd7f5337d4b725c61e1a79e46a29303b78d512adfefeb0b1e7540df32f7e513b51def3dc7ce29176722ebd991ab5acf9d7617403c6985cef3601ee5496c7582ae4ec98593a5b746586fde02aac4a2065be599adbe20edb135e9d8ab13ac00add4fa50eb592d5630bfc4c2d325598bb97ee38956233d1eda5602601bdeeaaa8d2904764322021c3a64a144cdc2e8b76ca3b9825144e9ef8a5b9cb2ad281db08caad09dc51d19670b975128d5832d4a44ecab2dd4e392396eadfd322f9479c637e4fc10b55b2afc66e6de7ea30ddfb56bfed8d3e05e0a4d2751f49310c4419262269bc9a2ebf4f8bba0bb94d452fc60a2ed6bb0e578e4916ebbe0ff95ce265a115d4be44b6bf650b5a4eb94fa77341969b3c0ebcb07bb0c7821bc0709a93b4f2478454b741087a35cd07a13a685675ccc2eabc25d8ad3c7f5af234e7241f623b133afa9489f8453227b0a7a259d43721100714d2857f9615cb846ba363ef789bdee76bd438c40c7fea960a8bd55513033348699b7961cad63f6f42d66cc431e660e48bfc1adf43aa0dccd01e4b1ef20decfb4d5cd47021fdceea9e16328a0de9e33187ba04011bf12683b2ff85e8602730da0eeb96e5e1f2ce64112bcf9258ca1ec60093077f690daf1f0b4e95233a4d87c092d8bb758a856be895afdedce82e5148085f7e1aa71e279b8609cc1f89c8f2dfe7201868e754b57eca92a074b05ec878cd5db88ef975ce4906255b3199ffd16caf0fdd4c9cab70ae3872cd807b8bf4a364babb7acd6a989c89eeec35172fc47e398a85490a272b8feb983e69ba725f66a4d10556db21599d82805f6b186bec99ae06d8c068dcca64cd4d34b339b5e9076ab1a4fbd8d93d0a378cece535fb0b6fa581f66561d14b99b374f18c63063e1e7b7d1bb02ce395772621fda74625592a1509bfb7476f1089809039b7c2a26c2d64c320a5252f91e4414ba9061109f2860c2df52966398af4e4c210b6b269869702a909a19ba3482e066d50f8860673122de6304c1e9f974482078faffbbd3a24d040a2498cde2b5b943e20e430a95b7f307517543042edd7efaf93c99abbf5337fa85bcb7c53361c8bcf45bd1df499767c06e6b73ca5a7d4e06d6ccd0628eb48813e87d6a4cf519c1022b4dc4c5bb33bd6f5ca7d45509dffd2e6e76fcc88325810881ff9d11147fbc6a2a1b97fcfb9b5426003eae371b2992d95c0190ebc3bd6ef09e792f93e061a6ea994b32d401febadd90de2a5a6af4658c78c6298fb31bdcce8148b972d98b7cf0d3731e6d91f840062b4afac78bfb64b56e65b2de22231bbb313dfa49704fbf7cb077598514e25e43409fbc3b4e65db3b0c0ce5b835402e66bb09dd55a86ea57be1e582366d67ea58d365943c4cca29101ce70af911d6cc3cc204eb2fbcd07079a098c6fb99d632db6ed099b602002ae7000c4231c70832c87bf8b916facb0016104069e0297a228e4f24b1ffc9e37e8e604403ce491e4469cd0592bce9a5fcd2c1a960d2a96176952e6e6c7c53c950e2cc3efe17f4f8c0215f7f4c9d81c615e7c112cf37234325a9c6a041abee4f2e1483525ed7ec6f864c25985ac92e2b098f6ae42ee429a451305383627096bcf95018cb22cd9a1140ec78319de29c8b5211874042a1a2b6b2005f714d3c5688ad364ebf96c59216c32d325bd66b4149e8acf9817483c9f7264dee0ee6c17252fab5f1afb4e41f5d513ba4cd18c818c557174f6142668932111ae8886235d28355e8ffca886470becade505fa99472c03cdb64e9c76d20e2fcf77d002c69b653060cc13920b703afa67b36190193abfae2edea2b75ba65a8a94f147cb10c388915d2e620c813591476b40526bb0487d18e28d882d588be8c1b6c01b8c92b4423a80279b31e14408086d27f1795adaaee62273c4a2c09674948107482445230d40c2d51200613e4a7801e2d09158503d1c63e1913580a22056a8523239fd8b5eb7ad4d6688b65dd946c63c5e0343e9e207b744fe28390bebe69ab19bce1671db644f5c4d706294bfcf23b1045c0dae24a1b548f832d704c1171d668e046a29055765f64cd122c83349280207f713ec6d7e3362320df75136a5305a49103ba72b27f5820cc524a0783fcc92540a636b56512542300ffde127ca48755ca33eaeb4a3fcad21b18b0a6c2379d0b877c96e7020070fc623abe006cc2c593f76252b6698f12d8255385b3bfd9974e5664117d49c8de9b6cb9a59429c914a5072608a0075147ff084d17cc60fd434a95744317dfa1ba4da541305656914d0db60632d8fed8b42a74adb921786955adb4caab6ed3afb7386cf5c686d996964d76f5943d656b3626b253d844a20f1a8cb25bf64b6db5fa6d255772255752ca8f88a505d7552ec431eea87bee91b6ef65b41db17e7ba46e7941a26cc8532ecf3661d3d8909f7eeb51b2e1dfe84d0d4697c2cac299764c0505b9504389c5a729a62b2f08cce0cb7f8a89415f6a3042b9fd852745cd08fb5d7563172737642a9f6bacff1642080db28ff94db5213e710038c4184fa85f0485a4bb7aeaf54fda0c6020d611c6ebd3f3b95556bd12b3f14fe85437723e47b1bbbbbbbbd65a8f1c8b952ae254413535e54d0daa9973e7fa57ab34cd397343ae9a33e6c63f8a4b110a0b8ff598d8138cd8eb62c0b08e68e958869283e5862e0575e39c7136cd836f9443e7862e0525e78d508cc5f735cdc3d930778cd1ca78dd3b07c1e7cf8f0760c6cacfe353f3a8f5b6b1215715b1d61381244b57d8ec271b3b35c8c15b8a032d754d70f76fd67529068acfba633da64de9857c879f7a46664f0492d0a9725d2a2e71749a6efca3168a11ca56e5912d2dc50bf0e0cebe6106ee3c2a21def9448e14462b979fbb1d57b08f69d085441063fc1a638c532ed56044622b2c53c9e8a166fcb1f62012740130c813b99c6c1524a61b72951179b9cf6c56242bc29572d42ff71e0d36acd9d31d2bb0f46764ee699023a458f71d21c5584158314887f41212e359ffa21f9f6ebf75de11ffa3d677cff25e42fc488c7b7aa4f5befa55fcd949a0e76dacdcd3a220dd778414eb7ea394fb20acef28c6aac32207e97edba851358af1acefa8f531e867b46d528f04fc59efe560c31a3bef48f7f6e30a859e6fcdcf0bdfc5747ef835fb59c429cdb49f45fcd2af48ac5f18b38c9f64025a5e52cf97a5df7e475adfbd7722b4be9751f7bd84b0de9f553b8ff5ac2772cab1e91971cecac609e89eebd35823042e223e25d80b7024d4d0831bbff5b343aa1cbd19bdd67b566c5867b6630536fbf8f463adcd7dfb4e57146375a4cbfacc7b01b14fff957df721d2cd4ca81fae3e3ef55e402a53ddd667b1fbb1fafac9ee595ef79af44224ae5ab95c3dd0faa61835b0c165282aae5031755b9f3da07b1a56f6da15458f487f186fd6fd583deb930dfa0784fb2cf3340ef403fceb7b25b02dd66bdd1722c9d80de95fc9d0e76637a3f4b3c9f28a6419fd2c760ff0cb755e9178b9af886f5fe85e96d198d4d967c46fbf5c791ce8d73e1328fd5e3fb2ef05a4be7f28bb1fdc60483fd2be6d3912f4110cc443ce1e0dcaafe39c2cb93010f7fb833d5b4ae9359b93cae539e753c96c3ca8536c910a7318b558f0d6a128050a150af9cd11055888d983f8c523ba5ce9e5f613c1e011285879310822bedcfe1f18944188b90d24defa452706923f2c61bd58a575c569ea7664ea9aaa24314c5a2614eedc6e40ebfa73d26d8fdedefe8d0245d29a52b1796cee98bd6d904e4a4106ca420a6d308f301eea98655946a3dc3e6e7960b0ee7e10e0fa34ccdd12b1be8492a684ceb9a3259973ceb92599f354c164712749994e09d5a6821455ca93357162369973cec9056dd2e4882964d07ab0a658a1e7888642082396cc07ffe75da87ea54049ec3084154ed04045455e6102059dc354032b3141f650dcb007d4144e6ec84f5041526fc258a3a429a19452eaa50a2a6a157652a8e20e8d32e79c93ce4922abd0228a0a3ee78a2e0d0b090834349440872aaeb0e2c9ffbc79f39455b14605695dd6c75a3071bca0f64d1a1c59bd0cf5a6cc0dedcb293e9b72ce3748ace077ce39c12ede68916f787012f98d0d4b2cc8374a5254ddd0be1072e4c869aefad81aaed8a4e887941bebf0c840459fc6a0c76e16f16def039d75d7009f1d9dd545fc4a59f4fa31affc79e52743eeba0fa25e451ded2c078a28a5947215853806350f8dbff0bbfc610ed7c7618ccb40714d0458a8c793c043f139c64e36f3478e1cb24ce33ea7fb941d7cffaa6a610ed787c1ed8ed1234ecd28986fb33a76374f9613d162aea05b30a160cc2c2920e924e0d0691ea2d0c18e17477899410c1776a40e52bc10a5704297b0cc610799e509a5945236db9299a539e79c5bb42496ce6001536689cc218a3c38bab80e021531a490c50b7660708a414561270a298c608edededebc00792363e08a715737ba96ed0410f884c8df3c98b71a3dc6e81ee8910ad12a1f4941fbd51fadbe97907aa4fdeab35d100d29cb8b525b836050a305954be3b21a2d92ee2ae9fa1663e762a0d690b02110b96e8df8ae27567e3abc8ce66fd33b92c27cfa47d9d3ef25847efdfa1dc93efb65e1587741e6571d5614841dd6e06dfe6929a557ab11af3134e2d78b8df1ce90b261e50924ebd95aedd71e840e8df8cdbe703aa5596c31db7caef40b91aee6bd7bfdd4cbe873d461f4fba83639cce46fad785d57fb8d3fb0d9d3cf3edba4c746b0f68528d4a75e18847ff5fcbd7ec4d79efbedbbedbd82dbb7f7fc85aeeab18725dc50fe10d7d5e86fabee39efc8eb47f6abd5e7dacb8c662f1becbc7e5f7df4b28f9da669da735e1d12224529dfdcec7fd0cf68a5af7df54ca0affd466b5d7daf9708fedd1bf5733f02c7942cf15fd2cf7decf50be97f202265b4289b6a98628c5c966dcd5572488332f3a10648a2c776231e1b729c127c931cc75b59997dd7de40a615bc3be7ee3e65dcb05e4966862eab276a758f05451837c6b8c48a4be365f3e07169bcab2ba2e1fa0bba22d7054b66b817bc055dd10516fc8caec88219cf65ee8cf7e98a66f8bc8caec8a70032a264e0b83264bc1d7365442941726524a9f2fc262a05237ccca9f3863560d77d6d73bb28244144252d0d453279b258cde76a3f57d3c0b8e26a618401834c0e28305c30c01765044085c31ad7816ef8737de8ba7781e7ba175dae7fd142175baeef7822e9e9d28832521084d405cf972f7440a2a44649621142c4192584b83367694af6f0f1adab8b2b61b8cda52fe9db00ac10b9aa252e7d59b9b8e1d26f592323ae9ca9a109942e26903c68b182e32ba59492c55dea83c10d6ba4d962882a2855415cfaac05144f292d028719435c5ca5d1428d16488ae48f1a353c74c31a2b9872a91aa815dc61228b2f97feaa2ba23f7628163c0061a1e6d2d7ba22ea0202aa8b3ca410183c58e0e1e14a2d5f5ab42b9a63ae78e2ca9f49288f2b942e6582cea5575cb9d44529a55d0d3b6899e109a8289cc81d82684329a551892b5fca6a0410ad035cd9a4c7d2a89366050bc2dc71d59942698618a70bead059c167aaca823a5eac20038cd30c3b4e96629471f2b1d342cf1a19766e7062a798a69a62d82c515a524f3d45b0c022f364c57462a85a76d840e1ca24b1ecc459dac254e9ecdc5995e1ec78a18599daa044a960a856539c645254da0d4fe8d454f58185d9942121472853459960c14798da32a558a14700c324a1acc013471853e577902cb198a5762d599f79394a69e986f63fa62a9d3063c4065466c2c0943063260c336f02800233564099c90206eec1ff018518d3303ec3e6cd0842d0f17721fb50679e38d9accbfab8a82e33c1b441155b5f0077b03d337050c6763ec048605746dc60b2aea81e2c8dcb5067daa839a3050726b0f632141a261c0461e56528343074b0049a18b8a0a90216292555283478aebc1cc504889a467ec040524af9335e4687c085667cd149c6e7b4f919b9c5c9bfa393537b216850dadb5e062cd8beaf7e19fff28ff148b157ff8c7ff97794c5fd339a71e413a570623346082f8208f326d6de14368c4edcd5b2854bf3882f1166bc8c1732e37bcd8f21e435bf2016bccf736c8637c5f09a5ef367fc8bbecf7c19ffa2f463cc789fef288606868d5ba2d30caf4e4f460c3b592d5bc442710aa7f0001cc56418cd16da5aadebbb19a760a16efa81857aca9d78a8e7ed6f5fc86fb80d0b0d198e3ac00da35310cc73f226060aa3d395641836e5423e45471b100d19eb4d55ea80815efdc2a7e14dd2c730907ce9f235505ae2d132a9f565c78ac54ce632475d3e40fd3008e65da6c15a7da21030900bc52c0c237ac3fa421d6d40344f66fb42171f400b0a75c0408f7e215755d9f8452c0cd4ffa6898d71a83450a2ba336b20e221edca0fe10703a434c240f2a50c6a50d24062c3a0fb2fc45588104519a5121a141465f5a15f0d5783f25d4f49e23031c5263c24b770b95a8c04312221c85410128884800d150fc9205808749893161ee2d897332e3251472465494957f8d2cf3e99cd7eea713569529b94b4c4431dbf081ceefcfe0a033592fe72fb6392152b6e686fff2775a1a2a27092ee002e434901c3dd5afc2359eeeeeeee524af9bc926337aebb197d38fd6ea8a8a44b68b0692029212669a064e9ef7822e9f6c73b3db8ef8f639a47f7fd318a7d90109f044025e9c647bafd118a87b4efef383da85a055f6e57cf9eabb56ea1e5cbf52f32d1225abb4da5795471a1d677670083657deb8dcc4b89da87442974f3c85483a51f910f095bff82276c1899989a877c252c12b21ecd636e3884c7c8cee306394f3210fdc85402fd76b99828c779803ffd6a784149f0af3f6bade4b1f2c75c60bb3c86f5bdfc39e641c3fae5d743d362ff06d1e686b1ca8e226c18745b4f36fed956726cebb21cdf1144801e02906c226080201ed22efd1e3c945d4a298d94ee6890067957580b368fb075e9d3a78fa379bc44982fdf68befc5e6e24ffe534c8ebe16058f0fb06a9f7848dcf2d1ef2a74fdfe5424eb15d8bd78fecf267998f23ff1b82af20b1cb135c945f12ebb098041737ecf1ce64c3ef6e23b6b8758d06df07b38e0b6e5cc1b11cfbf0501d29b788237f4c6a9fd78fbeb7430f5caf21bb600561c35aabec8af43512af4767f9137511bffef93050af56b4bfc6cbe95397b3bbb3ec9d66efd9f7aaaf5a332dabd98a66b4468334fb5c0c445d48946905875da8d6af66f139ca961d65ec2867d3bebe84c423d947a4d8ecd7be5f46dad14b483752cc575fbfc8c45ffdfce339992753c97d822596b0239528a5948af912a6c91c33658b3995d426d9145a9d25b78261c527fa7cf4c1ee75d655cd42326c3ef5a6cf902bbbd3b4164d8a1224a14a73ce3971e0acc89aa024c86850a299d214154c4f64c8d8d089939da1d366632e5aa89374450c5f5889f23fadcb5074cad0792242894f09cbb97a5c574baa25852403fbf23753f431bf768add020ff9d7276020f95576fe0555ac43d9f935d34ba766f26abd9db8a71c2669d59572cb93ed0fa55383528bbbbbbb3bcd6a56b39a65533a15f13c72cb4c63a58cc997f225a5d3952fe593749a5912175bcfc8ec2ebf38c34b66f6cf04feea00bcd8500ea08b0debe54827ba942edb3f966ea4bb7b411a74b11c638f066316fbf10586e5675d6139cbc62a39dde8aa11b5029b1b81e460f969ac60f9392e2c3f8d26cbcf6961f95759587ece0acbbfb962b0fff1fb698d952fbf23f225443b32ebcbef6524e94bffa691cf77ed031d16654357c631d72ae9e9c95aaa6ecf9e3cd2aae8c3bf6ea25df050fc3a06a9c36dd9e4591303655318d6df2c75f0ac04d3091bcaa62a4a45a9eacd92a20fff4ec2427d03c3fc5b0505ddb8a18106afd70d69950c1937a455d90978c83f1b32a7e8237e5d259eccb2afc618a43583e5a0fb65d7bf12c2c84005eb3f4370ffa0c12f96a5571692672453ca9c65f2e7c7ccccccb17f91735e13e6471dfe8573ce497d4e77671f43bf3f32f3836c57aeeceb17cea79ff48d29fff44c4aeab37e6c3e98b579d0d9834ab13dc3fa4dfef931d07c39db063bb3e7ccb3f7ccdd9d4ee7a4b75fa553122e9862fde51070052a3fd9a046e99c93524a69651b73596599ad2bfbfa8594d2f7d64aa394e9277f8d95ae7243db1c1c1b3fb4769b2fa5d632217b7bf9f20db3eff5c35efa56725b99e1b2496da756b3596687317fdfd1b9fb0423d90581afc6401c65fdd8ddac3e0b8a3f4ebf6d153ffa8842d661433e30069b7d17f13c79eefc000085ed9e7b18a5dfd4697baf9e3b23f1fec8600525a8103e2019aca084822bb39a7943828e6ef6e4759ed39698c47dafd5b31e2976f45a716fd4fd5196d567c4fd113bac23f24ceb07540e04095a7536a66672c505b9da576ff34222770baa755bfde6199137669ccc3167556b500fb0d6ef2a653a72b7a05b3b22dfbc217eb72d7ba2ae73ca5b2f145d8146e1c6f899c07a9e3c4c3d3f645580e3b2428aa156d13452cb45a105153e3b1df87abe0adc215fec351b27a06a14a87d6b833de4a7860fb6bdea853528e0dae28324c5dee1c6d42b77a2a0246c2a777efce2d2276a10dc3afdab3744bbd37f2efd420adc213f57360f198ba2b4dca960cbe001f0fc2e1a6c28a5dc7e0078ff1978367078ee0ee53ad3f5a5eb9ffca8e5d29f1edc3bd32bc2527e7d27a7ef1efd1e4abf5b2cfa1db73dffdd322e7695b6d25418a8df29d392cfa5c914e91a4ad5604f6c2a3ce4b7eb58b9dc2da0bbf30e03f5bf1abae6f627e08654eaf6bf7ec40fe79ddb318e8cef5a2d8871e89ae843aa79b00b517bc5e9125df2f61933aef4e61b0094b131261719a582944be372940a4e57724f13cac6383ca4cddbf3126183e7e085800febe46f4a80beefe037f080707836dec3f130cffb0e827cde14d1ffcf87fce4c6c67fff46dfff3ced5efe7d363ea39feffb8838ac8170bcc77770bcf737bc0e1ec8037a22df9aa311c777248b3f8ef77e03ef7bd0bbf1409e8defc0fbe7c0037a98d7c17bde919f07df3da39fcf3e0eef083b6c83204a6c7c47b218d978d81fa9ff1db1f1c19ea877b8c1f13fdfbfc38d8dff0fedcbdfc8c6e378a3ff9fcfba977f22e0781b6f64e38d7ebeff1d58d8ef6f3c070ffbf083e6f7e1f81b9ff73bb0b040dfc16ff0e0051f4409d077f03fde911bfff33872bc87c3fb1c38be1b379e633f39fe7ba31bfff3396e7c471e8eef891c47920601781168e0e1d0e003f044fd9a36bca58ed9f8f794304140ccc62f75ec7f7a416cbcf446e0988d774f88c7fe6f784772fc8d07f28eb218e9f80ebe23254c121003faa518ebe0757c2fff7f8e1d2dc518d0bfdc3b92c528c7f7f2cff11cbbf1475efebd44d0f138de28c7df781ddf5116a3ff1cdf5107ff7f04f4369e63389ec8813c8ebd67c36387edc0638b7018d703485787d7081cc3f147fc1413c18d17018ee7588c85910948098eefc637af743061de5cf22607de065e00bc977c8efd7cf18af7925facf27dec30cfe398e6c5022eaf25468cbf315c3786651692317e2e7dffe4c243f6dbc7e743ebf3af2f74f97cf8e0f599532e7480eaae9fe2823a6e28a76e5be0c509b91bd2a513a40c2fdc71c3b914ce23b8c1cc7e1e3050f6d26b58f63b82b2677d2178b3ef6453b67d2bd9247d4269b02753f6cd2522ac9cefcde33d8e6d36bc23b6a28a229262287448a05012cb223f86b2c98697c1bf07802506eaa5a8a464632ff150d75ab2f1ff05a87e8a4f36bc230e63878ba6180a1d12306462598808804ad27d01f1f94929cdc3bf5794ba52f70ca5734d1c7fd31fa9629517e3c8407a75065a9c4e4ae716d65e8e6a52e786d6095ba700f3d849b54113343770b074095818bb41c1e21811c3096ec860b5cb514d7668e2060ea6d8ec7254132a514d5450a1d1ac71185882a8264b3026b65e8e6a920456452d2dddb0c5883d3fa0952c00781d830e9391d3b48ca39ccb67b2b495c7ae39f8f3355c96ebef18db0220ba6ece07ce4fad2e17e8deeede2e996bdb6e29a59452cae972d5eadeeedeedeeee1e4677daddddddddddddddddddddcc1e6b5633dbdd168c891cbf7ee2cb96d3a7f469a5f4e8eeee3eddbdcacccd63dbb81827c7e1abde9e3be7b43d5c10e7838dcfb1e9996105671f9d9eb4eecc2d2959b29bdc26b4d2404f4ae9eeeeb23a33334797524aca75c58172cb28375db2b816e703c7c6f7766666890597c5c697cccc2c8362581968dce5486d4a275a9b34b35c6b955a46679eace59e676a92524a3549bfd612cb0d4a2d8fbb9c4efb0b7c95ae71ee56f6d0430f31e41472dce568529335a3938ed46a46670f313030e2c96378d0608f1e2c7b7a68cca0b2517a936696de217aa259cbcdb362b78a110c8a42b109cf2acb326e3e07a475b32b5b4a6c7ca2bea2803b1bb7e23a6d55a90780411804ae7b0ccee7ba1ff2d20910b9b856d6b2140ef89e8bc613cfa6553775537f37b5f74c4bd497c8870ab7327cba46833e3e5dd17c9f0e8478b7ef91351109e103063491e8e3b2eb2a8081180f118765868c18b56948d597b2baaafd2a41f974b716c72f906881a10446125c1e2a3d75f2741191b461a590c38c242e2851a25e71dac2c275289f0f5d6acc8d5467dec42dc6a51b5f32c9a6282638dc5056915602bf3557b533ae1aff036a727eae5ae7ac9e03f31712b9fcee69316ace9e11d97dabf5acdf9cc7cf5baf46c36495a42b5c4cda925445ca690b978e49639a4774aae1b6969854030f456b5f0cd419e5be90b3cd43d3be6d83fe5af36885ace7063b20ddb79e763f58dffac2ee877faf1fff99c07d7d13581ff7b1731edfcd0bebbdb776f6e372fd5416c45663cb6f296b6b5ab665f57385f2fac88fb7b0fd527619374565839d7d3472552e06a795317e1f2748ea10db25730d1777f4b136f2701e91fb6958fbc795a53733478dc50c245faae988d4d1842de4fa823556b0ab973cf4bacc1139ac351937cdbb526a14b8f5d3a17b2217b2600e192f49b1fe10788abb27c81bdaebc3403e633608d1076d14f2164720982fe70bf22708f65a2f7b0c9ad81882526280c5ceefad2b821297ec09f2b6d2f471811c59f6072d4eb23069c70d665d7da275355ab027c8195d51f3990f78a559502de058210a777b9f79675cfeee4090cf711fe76d2bad66744abf1bc771ab8de32c6bd3a17ba1eeb3b55ad75f30eb16602f064d408860ac50b9fe12c808ee7c39878c97a41b9f8ee04a2963dd04bf61816a4900b458d762fde517065961c0c4fafbac33ae3ee7e0baea75f66f48d06dd939a0748d6ec6bba29ef7aec8468dfb0171ece8211bbcdb13750cbff5930de82be3eb0848323821c1020625b2a071136386ad7ef3647c2b2f94778be1c5cd0b8feecb7ecfc70ddacf6708775b9f0d3595c16deb3ce95b08384f3e6fab2f3cbad525b38e63441a6563fa723e9dd3887b992165432458fce49c1f90ee8847bb62e3e253c5f6f21b48bf34322f064454adc72552c788878a14173684b1248822b0a041bac10b2a52f0c49aa617a03883a51ef1a5890b4b5bd4489971e20e9427636a70a18a34f38212197c50228a175e52e044132c984c0933450a253985a5bb301126490e5cac5461d102945c420e1a178620c10ada784953c606364ddacc3047094c1d32588a50f183152956cc14d1650c92152469b2f06108252b5188711c783042c30209dc2041c39a3261d88b28787e386229890c45c43c0a9326f06899414e5211601070c50a2a2559e84c8142aa480f767218020571b248e14b12121f78c0f24445c78d12333411461b20f0a8417243145216195878d374c4164c501af00186285190c0f3660a05484c48be809344c40b4c5978d12189282827a0a0c9d243122e28beb800c60b4b9078e1e9d5449326a29ea2c890844422ce1b26a0f2cc80e4c9982e3d749b33499871a24c0a787e807204961f5334c8f004551518d0482e0ee7688a9492921b92ec70c5882fb248c1c1ce114f9c48228bb02c3081a50c1e20bcd040440d5257527053039425e4c82db379b0001c12acd0c59c1380791a824a082849ba8c31c2890c42fccc2084933a2e8019834706b1c110456c21e70b0c4b3c915a6201e29c3b1828488cfd183dba7497d2047fcbf9b894f2db06e0c532736c61e39fed7fdbd1e08423e55a96a282caf5e8cd0a8faef605c99ecfb4af861b1b1a91d7ff33af2bb259966599b31cab7d4fd8ec897ca57d6683953fe78330f61101d6317b0cdd98414d82c3e6134008cb178479ab77b780ecb320acfab357f6b5c197f6f433ff97f63103655fa5fac2cc5282534018b22ccb3249b92b9f5969a35936e79c349392f9d9a564965688bc0cfb6ab55a497777e9e2ea5dc732b3e5724193f53959f21429a59430068a43eee04f8d70ce39259d35f32624b394cccc524a29a5945232b313ac2ab6c15d00fed81579db62a27f5a16fb63fdceb2efe88f8ef891621c97fa6d2cfb5ef30ba284484c7298fc1c6e2cc7b4cf92e52542f6ab37ca7e95511965af7d47447e81a7ec439ee25864a21aeadb58babeb1bde56ba706e57b66ac7f3f295929656520fe4660398a853b37690496a35a48ba1a0f55285151b4cc1fb0a85158f82259e79c73ce6f86a72c2988422a4e9dd804e2ce29ef9c73ce282876aeac320aedb3d5afe25ca0bbbb2b9a9991797d6a9a94ac56967d8b2f708d4c6f0f071b5dabff5c1f1176f55eb4aa736a9aa6d1baad3c49572bc642c677df3801514c4e709e3ace5add7cf7b1ddd9fc699817ff6a6dfe8b962459b65e45f5301c193b4607a37750501838e4f72ef97e411359d34829074d3a77528e41ae17eefc1a3be6fc1a656c92940bc5e8c7675895b65d9f552297d218437214644727e8e4b084ba5952479ea15382254f986e08e2887af2e4facf1326782403eaeac78316cab6678ea8041ea25f2debf983feae42ba27ee7cae85826a341577c670fd2368d3f0100b2399f0e1fa00b4a13b9fd9cb9d5db24b3f01309003a8940278c0f5e79e3ba9f3263b20ad1f0a6c2baa553a23730deb276aae824be0a1eab12bd2ec4ac4bc91835d71e1c1f6e02786e2a9356ce2dc59410855f47294933437fca02dcc45d5103e709102869730f2045b7871030c29b0810c1236fc8025c825c50a2edc2c718309a27832473acd3373a20cf15b94133237e427285e739dd9506597a39c28f1840b0c6a2995a9e4b201e76e6c86c0c00e65bab860064e17282658f26632b1444e0d486aa05343d2172820020b1f9e9023656e804a933356a058b303179985c9d28a09262d38993f9f6813a529b436dbea7294132e576cccee85ae382465fff42bd2baac8fb54feca65d8e7202844cc1c7449b945ad5b41ab34863f4e862ea8dee4aaec7a406659426868ac2f247270957be7b174cb1fc52724bf68e6eb60c54b0fc910121307f80d4b1973cc39841068a3f35a4e5cf66d44bb03def60201b622cf3d768707a4b2943ee5a8e6777fc9658304ba794ba9c9e0e4456b2c75ab2f27988cf8df23959e98c69985d0ce4534379e7bd7bd8f8e7b3cc595096654fc199516a5d73d6ca94259d328b9369fc9a3d675ea0eda8044e974435e9d0d4000000404000e314000020100a07042281301c1ed2e55dee14000d7992466e5c9ccc635190c32808216388210410000801060898a9a1210e00686d76025bc4ea29c66fddb6a2625ef32650a17d51929d62e56f757534b5b9e7b69a46ae0504606dd7041902b0ed88c9166c7edae2f917205454e88abc5ac38df461653ceac3153de72f6d48708df4bdc8f5494b6e6f0e589b8d05e1a32f599c0eb4703af805f5e7ba19063c3213553b890b1e3413f8104878e29d927f86f3302866c12b308e9971a5f0e562c1f5372fe18aaf8e2e40d0dbf772add0bb868d736f6fa555237dfae0d3b0d09a62de1bf91eb8496d23c5ea087cc370f1123ee8c4dd3f680660bf4b8ff0ee53012625341a6c7d3a262ef00e23d8b42b83ae8125ec0359d869361d26e8998536ce15c471e4ef808d8917825f6f8af2787bd0dea78a4cc528c7fa1ccb668f297dba1a2587c1d45e900e0e1a3020ba5062eee10cb5761b9ebed3d6a6d0672b8cf10a10ad077cb63340cf968c0f51a2c04565806f62d25b8e8db508a6099e4a810b9d053c74d86a66cec8875fddde71ff2ec76a5123d2803790b430886eec3d83b57e1dd3db0386ad98029a74eef4ad1fd92abbf0e77a4fb6aa8ac22bc1126c21b4315717640458ab3492e4d0679644ed8d371a52efccc24715b1d5a908ab0ba4bd7c94ae6032833ea11ccf7efa2c004ba4fe30ee2a1138e6c6868bb86721ae3d088a38a0e8c49e63b24a275a614fa83877dba3a46d7bc2abe565ac528244b10bee5e192a90248b978777b897ca8af3bc37313b80edf8696418bf91832ddad7aa5055822c6eacdf814f3f9f9f701fc49ee5b94b70642832cb9b883f994f2a0050fd767cb1d6a7618dd35b7f49a74726bc5303fdda29631a435b091c33f32810c0cdf439f1d1c71e520e206f798ef2713ae4502fd133463345999c6d44b54c9753a4b943d2c1c56e8cd6e248e01d70bb887a2bb224da2517a133f668b32dddd59f4438ffe030bc036072a3eba9ab97fe5a621d31ff371be3ff8f3cda7b6446c797ae9ff1a3c0dd77c0202b91eb36f6048e8b42033d1e9ec14d211a7d430a44e1c9956731f50156ea6d7b70d1140bd850de7c9e4e5409e4519fcfad5aa90cf606e1bd68e2c8f49a2db2e94a3cd7ed0a1e52790bca95181efaab69a04bc593b91ce64548bd3343ebb108e882c57cf4be98d06fcdce6aba45422417e8d4c8a8cd9fd09dc95ac0e273bbf35c6a92830b3daf1e96bd7448a6a9691c5377bf6d35ab30331450c9926b19468c9792ef4b554f52349020eb109f6ea8c8540457cf80334706f511ab5419a891c01b27f28bac0e8878f851d49142885f64ffbe325bffc7080865f3c8d1ae5391de18526bce8b43d3422a994182d73656537c21ed39cf4a578c435568bd8dcd4d1d0d4b8aa0c8cab19efc2c352b5157125c28f771c5eb7b36f7ac89eb8ae6fd25f3b9b8feb4ce8c9861a7ca6a4a6121de7eb91ffc4aceb45df6e58e185c55316ff4898059a018caed30ba1dff6e5e5d2bc7489a09d323a2cee41a363990e621e5ae9236bf1e9d04c747c1cf713ba3a6c59d23ccee2e929b1fcefdb7445e8f12382c344a3bc2bb8fd904dc6bf3d66c6924d4c746884e0300298393c069081b51d59ed0efa673ae13ac788742757d91846fffe312d22b0b064a9269be70c4f592c0c6c0de52d8ced45ef73c43a5beb5b2ea119b026b36a1effb37f5a12692677ca2c5541421b230b03791102770890cdc7c70a662f1e82aaadd35591c2b36d7013a371e49e4de7d03423f2dae50a3b90e9179cef4ccac2c355af7b1e8bda115ff7f73a32137f52a4f59eb8c6910e1a1193ef2084d82c9d356319c934e1fdc96888d0be44f164cb03cc48e12cf2cb060b0a25a9e54b91e06353967ab779355891c3dc4d5630fd838d8540f72d9e2e0a637784e68821893b91e26c441476473e3c5608e067d75ecc04043e73b800a7dec75044d97c73f0e933ce1b83430b4a851104e11e1a6b2069e4a1c1a262103ca332bca7b0e252e9c66c4dfdf2ae04954229363bea1f88c183b70ecc34a2b2302d3ba0bb9a111c06ec5a2dca278802217fb0855a3ec8070b1176240771efdec29d0b4880d4371392a170cdf200faa9804599f96c90c7dc90260072255633517ff0fb5095a771c7c1dc51dc867956f830a24485d39f37050231e5fcb01e0449c1a2c49b1e4c41481a94a700c177649de02bde910e27fa12161399dfc84bcac462f9142f5b20ac5b29a50cfa442a04ba756843f75e50becbe095baebe4b075a1e2dedb473f07352a268f32e322013f4ac1caec9e9796843fbf014747798d3180c661dd459b583abc0c72ffa2403f583034288187c83ee4262581cfb45a1e6eff1c18333dc76a1b123518cfc9219879c90dc6413baf3b142cd965ecc06d11508dbb941cdb956c18dc67141a85ae572d5e9e7e78289497fb28733aa74b38115f72453178729f537c645adc677481290f448b568a5e7734bc7e30ed2fdb19473908e08ef89f0e4f7324e7f1c9dbb86166edac1bf0225e2ce3801a1ff61ed21c025793a38f267ec88b38328e908ff60cdcb51542c8d424ef440efdbd7eab13d3dd9c8ee930882250051dc5fdeeb70b2ac9eb2ef950bd21cbd697f544aa562c5bdc5e1dba3a89c20da006ab3577c6090257b5ab837564a2eb0faf6063c6d3c8dc238054fabd9e346ee26029deb5232d786cbcb997eb9f237288aab003a534f990912bad043603937329654630adb6c17aa52727e42b9e776e716128f077f3333990953b6d51d344adff581943dceb93a3455d0b577294bc41bec01d431489a681f505c165eef26738811023a4f2a564dd7112fdff8d491e168d15e8f3501af80b5d1e19542ba325cbacb755d2b8af9717eca17680e11b6e5bbbc04bd11a8ab82dda34442adbcf5f4268d1d0adccebda03c2d016e87eb329efce80ba8b5c80addcc018a646550acf33944ce4a8c0a3a99038ccccaa050f73980bb598976e5920d47792da8ba2a7cd5e94a0c0a583de184e8f67ebe25b5d8c4c9c1daa61cc4dd4a2529296f5dcf99226e21b98ab904fe9253dc4fe610150284f374145d57f6d9334f104b7a92c2783915f6d230b1f5a9a1bed31536ed668cea09d414b6979e37ad5864ea0e712b725889622f2d616fe61611e03ea358e44e46af0981ccf3b25a462220d52f354dedcecd5d3f03a2169f892820944e343bb2c9455ae24665a05401e39b6f7867f7a178a544c27a1c51888c447f7710021309b1bfd87fcac3a9ce0babc7d84fde08063f1a8fec58de1666fe375287476adf88e8d03a83309f524de2674618c0ed83842607ac8ddd1bdc5326ee942db97e00be6c4d95042884d9363ab6d3128274de8e879d587779b72e62bb96127844eaa1f1eabfd65292cdf32cd2ab58d76b040ed1b39d738a4f154fdd0ff34a2dc6a1cc05a078814b075386993addf53cb2284628838aead645c15605ada73443d9b002004d930980570187ca6d7f22dcdac215541e626cb6888e985c4e0487d8e2286a221a3dba8987177bbb57b52163203ce118a1ba0a546844fa000b36aace6391cc654bbc9427b45ab9a484d59b48a9a16ceb9f3a1f81479393486371a2e6703064575dce91a832a90fdd323954a60820eca2fa9b24497b94651915cdc36438809cec30630136b7514f7169a381f181c4f93c2dd854806273e69b96b74da636c1af04d7539f3d9206487aba6d63eb9d8ae9f70d8499cba1750f5d4e032e3b8593eb412a36e382715c64f066c874f6970150148bf9182abd3ad5ae846b1ed687ccda5cd9b96800ab09087052ed6927c1c444a5fbf287ace9521cf27cd561892629188c58425f26258a2ef57351e5cb1955a56500e640e0e2c6df48a5dcd24d071482bef17d1899fd9f5630b3c036568aec8d0f6169bab3b695ee320130083f9f82d6ef2201de83da92fff4a66424813cdb2031f3da18ae33a7dae28d83102a9a3f3ee06c46f1d44f83b7824e2201297183c742391ef22a5b2de7472c4a7d4c6f47b809f68723112eea94036ea46fa763d8dcde494fc82f2e0606f80e583749591a2012c1d5a04f4b26d545a89ef91098c5cc8c3ca2dc80be25d28405725a46c9d1aca405028b1073ef6d2f94ce8a7368451c9490afecad731e617e682989c002f0d1d848f63340ee072ceb5767fb370596f4c182cf6a836d63757370a8320ee74cddd8ad0cc46927e8f9e64fa6c1c4587df416f96d9798aae74089c3ec5f0d5075c18c3763dd516627cfbc9b2e8df870996cc7a99d3e5631b9c90b64589ed12f1cae303f8d52ca09da7c26865a5a6f66fff17bd45245a315f5df46e7aea209535e5e30643bbf9388dd477456aa2a00ad4951520f4d115801f0be5e62670a9ae6fbece34b9f6cf672ee60ee0ead44152a26a3fae43e9f4588daa9010d97c7e7b0bf3c0551b55029443d6c9c00135f0d7830a266522780fa1cb1b79ae7ea0e8b14f0b3592de045824b857558e5cff771bfc9ed31ffa6b159fdee0964a6b7a534b6b0b159793b1d0c9a9c9c24bce3e66eb8cfc4bce036ecec3fa88b40706299a6698f4bcda375b51ad53854a0fa537ef266b37e9f2a718818cb075aa6d7703b5cbd5458bb027c58d54ef05f187c1799177ba2f7ad38c5de65bb4ab96a161f6e46dba55fa8d2908fdecb5a622ec76821400a23fd771735cee9dbae0df327f24846f426b84857d027f7b4ce3b6d9994f29466127cf1f4eb852f1509791d416975cc5576f68b2eb0813cc6cf025f77fca11b365f6688aee19c7e856055fa5202cd01dd05447bd22088f42d0d06e808588bd35394526e023e74e1eaea32b282610c7bf4fa4fde324a374b4cde461b7709ce3560abd8592aee09afd0d3fb4efb25bd9ed5a9e2a1fbf9fdba4bef0af6d5f74db0c0dad119684f9471bb57e5bc0df284472af5bffdb98623d08c45fb29d7b905ec28e353409cd8fbfc3c5e4fede3a8f2af098c073ffe6156539dd7c65fcf1e12c3410a7b69a5a24bb20af60b6c707b49b1d4bbb89c50eaa91c077ebf3c5b5db1ddfeb78d4e993807f1a34f62e6d9a8f2e9a5307703304f2787700504a8f61b467cafe2e9c80e10e9e351242c40da681931aa1736100cb7196ee7802ed58efcdb7dd41c76a54f01c2d94b38880324dd9686a0e087aa8efc647adfb53b21cbe24ea0a625ee140d4762277ba9f4affdadb938622f6a288f3206ed7b1c76ca34e9a1bd000a2dd53a424b96558974dd1eb75991e051dcccbfa83e81a22bc40a3bbd472c7f623d0d60b2bac20c48e9aa52720def41c406505c0cd064784d4ad74339ecb926ae4736ac33d5bb5c0b0bf833f0eb4feed4409b5793b879ac4f9da3938101215fc84739c4a78e81adb26dcd612959e08f19fa68928b55d36a715156f08e084733ce8c686fef5281e8d9f97fd146aa81a5a45aee9a72c426c479f4820db4dfb9a3122447dd75a4c7f69679991247902e80793237fb42853bad956f94c7ae5f2edb4638fd7b510c6b962026e3567eb26543b35f9789aaa5002ae5f311cb1a5798d42ce1f1e9d7a4d77da7705bcced0fb37af384891a470d2a63b2886cafd7d0930148e77e1200c207264232e931cc4935afe50e61bc5f8d38c09d1d85ef1994803de4517fd0601e40dfbf91030bc49e8fb818036d03ea29bd0135d20b90ca8d39077286dc7f90851a79b598cd5d5dc711f95496864ba1418173c3f0eb74a8cc7e130896e7b99b03f705f4ff8b4fdeb26c31f59806cdcc4f09d3084044554d1b052c0691e9ba0c6c1b4bfef820ce8d3f4e81411cf9d89e47575a8247302fde9bd864c628585df5918f07b270d202a938c58d1c4f70591d6887ed0c4b07916c66c71019e86dfd08831d08593892a41db5499d17345dde2f39aacf439213882ae02dbef297dc7fbb94ccda52a80ad4d5ddccf2dc73997545b6c39b1f29a105e5e10cccc06d5ff79954632ac034cc395db74b5271e0f1184209474cb4155c88a8d409082df84124cb5ce45af10656ef70b8cd49a67c5ce923ad14983ac3ab530a710638c66434738e03299f25be424011d4e2dfa94a71b63270f9bc0db460325e402953f1517ab84eb0ab628451eb0a474d4bd8d755298d670e14699611b4ae1454a0485728536c6ee46aae4bdc678e7c2f59e23fed3a6c86f87874045d571135e438fc35bbe4a12504ac96ed4309d64ddc2d021b80eca9b2c676bf9de37164d61ed2ff9ba205fb23d285d59ad5d0632b8e0c45942c17430e20559ffa7d8d69a9a5a46ab4506d0ac0147fb1e53431788e8dbbb44e9df60394c6e47c624a28ed0c1da21f97549357b16d4c998457170f0e82628b4f1733696143322f196f7d3f978825f3a0b14478e1c94de9cd0d961e82478223a705421a3a5d47ed49a0e8a57025e6c765bbd8d2cb193acd09492e6042cde10aaa1b6024e226123908891b69ac0f24205934c1bcac72d011103744640462dac81c4ab7404de9170d629d1edd2a95801a962c4d7934f10c127abcd8c21c91217ecf666a99f4f8b9bc421d4a8832618a7a1b503557f67add8e4edb6f8155d174ae0848c8800d4e411d847ab6b084f4b49daffeb5f9c7af769a887245ea40b55bb2e3be2c643771686fc5f6ca27f4a5af6b7a091f7890d36c0ac8761e8bc047864dd09cc59abf21c638f29ee78088d75de7979b759d3800363d57fd7a01a939974a912d71d2834f8c9ca82b942d0fca5d849fa3e9cf23c12611a355fa22ff3397a44a9e86b1ca6d5281d6a67f4a7bd706a7939c17cfa753910e99b730ea713ae976c5701ecabcf3323d01c0a6fc1e85e60fc82fcd4d9b4779eb4464e9f33914289d3dc5521d1f331025d7f3d1ab5f88c2ee2ec72b274583d01fa3dadbf73d4fcbd3beb3e38fa7b962748761c07d104a4a62ac9fb2442fb691d83ada38153f65164de908146378ac870ed904ab8aa0f6f6608293dea14f68a10288766f70accaaa3d66ad4ec19ff266b4427a240bca7d17b27e74f9bbd272930f9ac40aa9ddf0ad088fe16fc3f41196c10d4563c53991a27453b4aea9d1eeb37d52fe06ac2328e6382daf5c60610638b0032159d5caec79adf47e861cb439d60c8231cf0ea05edc48382dc62a836c49c24b34a285cc5783613501101f630d5b545d679918955cec7aa40cafccf208044306029cbf03bbeb2c9b7dfe2aa3102a9dde11859c45a5daea4f2c6cfc506b9e63319cb90c4c90c58de303071196b7d363f9bc82e6c4c5882bc661b472fce6c836c3cb6952192a3fe74aa3f0e516aa24655c579e052b9b45dc74da903df117e411ce32b2c94cfcfb11249990ba9e4312fd84f8e114ba6c184ac91ea88b692d09c01401802ced0c6b2718d83c95ca4f38fd4f00c08f8b8e30f019c2799df2b953995fd32a314d6ae03395ddbc732c60c7d66f428297e5d802dec21a26d4e9881016d34ab9b28ed0012e3302c10a9902f2d70d0e6b4ff4ff8beaace306931d093f5cad0cd0a1657a5331484e71fda0bf5d5287b0424f25187a7b0514ecdf6699ec5f85147475e4993eadf79ffb8016c9e1ef16362041c063dd373590d14caf8fb191410e62c23bc4b6cb04f3105d4c70858b2a41cfa0128b3c5899822cb79d047b1687834dd053a242d1687d2854f8e9273f8ced39e82d10d9c0d10399ff4d7aaa75d8f08a38c108a80731d31b792108ac21e09396d5dcf1f9606bff035113687fcbc695ba3d19110d3e9fe9307600126e0e0000e166ce053633df90058e0337d882c84ce184cfc8b9b1c6385556258e1de4031c653609f20949136ec5d639b1da4d100bb5c48d4f42b17be11bd3559aa1146c16cd2e160d42354eb84c150c1839708c646b064e06e04d085e3261e23c9fd105ac363000bc60441416a299970701609e3b541b6e5045b107b3619c4f496a725b6112e0cd5c4d6ea1fd55f9585981df823acf7939d974c98097d9608abefff5d29fe1c88519b20c652780b632683313624f1f36ef5575cdf6dab54cf6afa1b1301d5c0f8c0bc2196142b04c115748494c20d2c702d84c80d51c4560d0aa5f7b1bb10deba8833a06540f547582209eb3643c356a914661d811667cf2aef048b29ddb45a09a8eb2e6e12968b9bcf40d8bae67d89df437d41a0d063d912dafd639fb7c393fbb0bbcaf1720c09821c9316f36a36d0f0a663bb546dd98e51dd4ed65cbf240064737662d252742b994fcef1bac11060e9b1c290b8570915c623ffd5506cbf02b1e8671323ee0d7b0764d906442a240c7e6bbc147dde0c391e2147dc9cc9a916006d545daa04109458fd3e39803a85ef6ecb8b98982f7d3cd52cb34b0aafea94c562ce26e04b53006a7ad2f0c1937eb7d065eef0fcad34ff6ae80dce7c0e72cf471d69565fe5eebe158a1e95d8d6160abc4782328e5e9ca8438aaf43843dd70690b44f02e5bc894cecdcf8c4dcaffd72dc6287285aba75e03adccd9ccfea2782c302f64be619a09af731410f72614b85407f9bc9f1ac5728f8a38c8fa30bc1f33bc05476c1d4355e235f9b198760f0174120c32e400ea5a9bae1044194e79f42bc9dc6282d2e8e503f4afff1d222d027d2e80386c9521a4737d9f19d5857926cd8f45f99b84e3d5ac10883664f674bfd5d3bed864f302e2e503f3b038ae0974c2707c42fef15a8ac56aaef21b2cbcfa5658b2aef3ba27c27df53e9742cefbc741f42f3c644318201bae7540184792af7e95e87f6b27a94631543330ffb8cc2a062a366a7ade77c166490ae2e0206073933d7ec2a9dbf4e15be9e5a5a9ccab5d2c6cccfdc984f89970ed49577a9669247fde50920b31aaea972d25a7849b893cf16a0ef41b7c8977a2aa18e7588bb5242327db9008d12f5a2a593e14616c0a634fe6731741c04ace10c3754acdc06faa11d3a61381fcfdca365e41eaa37f516550589e91fb1fa34a7f591fc42270d1f85d3e69f297d5a76795436ecf6e9a8968ec686b575e703e3ea8fe10164f7bf587dc96c6f50a4a71efc3c9e070b0e98ef6a8c512edc3071ebe8d16fd89781ae45e010cf24eee2958dc61fa5c30699af775235f552f849676978bfbee5c752242596185527380f1cd40e18c5bef5e599aa335ee04d6c77ddaec1fdc1217c5c127374b3b69c139fa19b83c7998edb182dda062e757e5be1a2b6cb6d36b44968cf1dca232a3658fd299216342724067762365cff57e14bc4d6470e5cc75ec7a09fbaa49be4dd76f3f9626dd92b3755a2d11eae9089a8733630ab481a9e3d461943bbf1bcb5dc750292c1b5ec0f6113bfc9baa8d258a6c03bd29536f62691fa4a200ca6e24767e9dd9b1ad5aca15a251c57f7d615d0ebc2a8943d256095a28835d16ad3d6e60f26411beadd4ce208558abdd529f4c7ef29ac36f8e0726e5050ab329d6b041ee84db56cd83b9b95191aeaeb2a3592edf681721d5c45f001295e8a89e9446e78ddbe23f5f15bfbfdf1df1bf63dbeeb431c906279563457126b2a7481c6b7ba0fb4f8d8e30ebeb88e82f2b350d47f1bd243cb4bbe416b786ef6d193922cd16c5548f5b3b2d5acb3245019201f383d3047974cbc8f3160fa7e107f0cd0177ea67a79ffffd0e25e42138a03e0924702976104cca260c79f78c17a53800b2ca0c6603f2841649a411ceb6adabd228ea97622a2c3ad195cf9e8c029d218e3f3731bd741c018807db42b59a44885b40772b0488cfb0f3712803bec5f1afee58f6237aa9904c4abfdd09d24c22889d924754512b6e435b4ec22753ac1fbcbc8692001bbf386268436ba12afc57710584f4420e4dbc04a2716c5adf49a14a1dbe201107b737c88a07b91b0ceabdcdd53676d5104c3203a71eb93ba402e26a8764bb4bf069d957c795c62751614a91dd2003fc8f5b0af86174049e2867867c0ac114f1e40ade705abcdfc8e4e1458719d1e199c2f184527313cb0da23ec01afa53a2006f37ccaa3d50acfd8e8416aa705d49e058b2b82da0d7bcb3e0420c824d8136306e6b0301e501f00987c21c1b9173ab946e931638c9d56a794cc0b3351da7a604ef8d4b9bc3e8c2a1b004cbd60f58f72b0163e43b16a9b00e6eef7b3c3fd2b886ace554ee41ed11e31fb3816d1ab1a07165855057baaf5aa13f38d629f88b5d0901eca002e4d80357814a437357e0468924dae70ac5293bc734790a18c7910041f99a8efd39f673198574bed10744bfbc0ea5471f8c1efffb4556db3fb618d91d041eeb057f1d436456205315eb75469365dcfe1fdc22009c15d8515306c4fa61db008c9ffd70aebe56504c6c38c8414f00ff9a0084ae8f928824609b259beda0bad48d33b408adc1a10a51175919fbcbbe057ce4041c7be2c0bcaf9d772ae05b48523a962cb06070210d94a0b2822f3fb030e21a08226702a2870a9cc637f8c2b26660cb699dec04f55ae4b8814a27825f01dd3e8134d082f07371799664842184afea0442f00927eb038ad4018e760c4f0b746e19d21ef70a8400d8fc89230e151207de4e0c7d5b32fee2f775c3063238dc205b52c208a860d296bbcc2d67d03eab7e588b25f271c87e37a6bea86e05026acee08d694655c62f6c043209a868c632602271383ea3e6952b08c0ce28ec010f2d62ea4de050004451e460cd4c4121cc09caf28ecffb41d74ff0bd3ee48ea25d71748504112df0bc35a1d6e9d9382c069e63c60d88289e837638596f57fa22da3e7ce906fb85202efef24356e0ad964f6b0be5b2452678af4e6fea45d28b4f8e138c77d1f4321ede96b3bd0f21223a1520d7b74b1ac60c4d1cdde05d054e47f8e01d2e44d0e8ce86ae1bcc030af4d554eafca9cb325fb2af676aa3d125db7b4c5571daf742bc7f80be3b8ca1474324332a4db35cbf6ccc7bfef3a1a7c51a38bd02f494230ff4baf7a6693f9aedb5bd1ea6f80d9ce8a17b35f51b079bff1e76291297ac81bd95aa39a708940fd4ec86f2afbb97b4dcb4baecb008dfeabf9ca52f1b4dda758fe388ac68f6589f2b6dad34554db2b74860ec5526bed67b95dbdf3e8ff87a953c324a24efa7870cf3d73025020270207bf7c4be9bc8a09e3130473def0563ea4353304c5d4c3383458a0100fddca114f74e378fa06145f5faec7c772e9fb9c1e78cef7cfff22e844b02ae7457b07691fa49cd106e03b1b42956ffb91929e3d0f00f2e2dd6ed5db63974e18ae3cd459d9268d4e20bc9edfa95124920783bb1d06c5d35c8191e6d455ff0a3a90d309c7c25c9af449d5ba745fa10609621a9817393973bf4b4ea75958faa39eb0715c35a2a3de6d6976a82a841ef45afdc1f24b06a6003e0b3a7da9e5c1b87f054aa09efbad578037dbdfdd7d2133abe925be59f9e7fd683be7362ca46e37923f00bc8768110ad85c387c76ecebd8875e97ec47421e6093631d09ba734fecceb8af3614fe20eb778d06cf6bf4ec1bc1f02dd391ce80fa96cd7877c0f501bdccfe8487ebc87788acc1445bd3204323f871f3fe0a28f130fdce254200b3f1a36d71a1b6147143f4a430517688f82f7f4e40fbe7bd29f864964b3017ffed1bf2f69766afc7aa372dea1c021aacb624dc06b12227e0cf1600802573ffa4e113e27fc16569bce7616da9da64681e4acf896d45eab051c55cb3de88c2cb8e9d6282e5dee3fd25c88caf75eaaed1ffe75a7682d4b3558aad1a1520d7dea7ec1c1b879e099c0e5a185628abdc28035ff34867a855011efba09fe7ec1e080aa2ffd5d9f194a16552e7c57a9605076d50b79975130283755b4f25df301368536e93dd48669b2aa2e80a990952cf42a7ac1366c946a5bdd02671a495eda21a8dd1bd54c67042028a4ffdd5ec2e3a2d943d0cc8cf2cda0d608090898c939a828457a5ca01774cb12a1963c265f8777caa62b39042c8176de6d63ca2903c0b6982f45375a44f85fd942077aaa7564584259b29ace640b53609d67e0306e757699d01b30ddc2cbb6323427db79cd07c9dd2fa0ec56820e00d1012a2953ebaa1e751ddd44e378c2ce97cc6281162e64a8be58d6c59ff8bb73e862a6be3165103c5c1a845825b93f1921ab432ab021d3e095307f8b836ae77ad62e8d090134a48f2b3edb08f891c2c8ac3ce18492006d6e84cb725f1164b5827fd6caace9b0150f1462d25939f0e075439df17b71f53bb5036e0ff77547a3ac59f3da65ebfb673b8662e88a2722511fbcca8e191896f5804562b1b7e383952858b71ade6407b42ff952f9d7cc09411e84b1f2ab9a3c634cfd258366146ef8a883208307b6091aa6de65c7f5607b780093bb429429694e34ee6fb8bf64b1ab45274a1bd1b5a11615b20a4b3c175cdec3a376f4c04bdd7213b9ebfd14192fa8cdcbd7a3ea0d67c706d650558684fbc0284ad0d5566a75b2b315ade236f36c82709b561e59ffa63f6808137d157fa0ae4754ad479947fd47510a4972bbc5523b73c47b8f505d24eb84e77856cade1702aef08b9d115b99f1246d271f1a2abcfc6c0af38b51a7779c500d74353352c98e825e3c710b8c5ec26940e8ed90de734da7abe28fd5b132874c107198c9decee9626a57083a30d822218f9b781c3395761b903be931b19132748c4372b1ccdc487d56629fd775baa481a7aed10005d5b1f63a023854295e80dbeee46a99df02216fb6a22142622d363292953843f5c5eaca138205bd5a4654c37bac8865ba2584b4b79ecbcf456b6132120425d71650c2324532b982a988e5361c95e114dbf0a8897a312296fbdbd10762e466e0c8f45623356ee903c45420ba12d390ab8780f76c14b08c64839bdf1f9caea41756170bc82022834ffff51cb1fda1e00942a8dce1ecabfb7bfb4785795e5c05f4f1d1a9a144e404683d85653b758200b984a151aa9339324d48b5c3dd1588bab30e335e9cc0bddc6f27f226ec17aa8e9b92cf9ce5999b46ed016f40124f8ae8aef2b85f93ba8cccefb7b1e7742967abc134e5774fff2477b997b570d74571037b490ccdd4d1110ff28401731b2ffb680d28f80a0606ad8aee68c7d3c60ae79a015d5a1aae5df92c74f45211a1fc8070411e78df07ed0e9c27f4e98f9833df9d906d7f2f150391639cef8a3994f0e968096395d9f00e1a2f4f358bbe7ed22d657ea8fd9da9c5edf21440480b606840ded9be0b0d5a4db98dd9d650381c2f1147fffda3d51e13c124e4dae72d5b59c9f4456148e026157f4516f95dc1261488878fabfe755a65c644f11b78018bbbc429fe1a79d861051fe5aa38fd7fec7e653e1728cf6ce847b8643c770853f19741fca90de277315a9a23ea1843d6c44aba2b46d67de4fa5ec1b037fe37d59586305b1835ec0414f4f1c867778154831f8311806b2b0d29923e96a77d19284fbf5518976084b19f54ffde40508fc8a4ea41f27d6817defe93125e9d3035ad687f8f460b5b9dd0616885a4eb540f02792f93b2cf547646315633c8427b9b80401b807da220a671fe0aa22da59bac88d90a7e8a513c9f809e80c84338faeb66b52ea111be9daea01168c49af7fd67691055f1ab15c384d0104715430f32ba7ce080f5bfa05509a95d0328738b1dfd9dc6771515c19a3f4db04f9a24911081e722198753a510133a3c05ce5e30ba983ea7585905940c8202938bc0c6835127306b394f6fcf1e5836b1d9d6eba112badd6f08db63c7a706932098e312f4f200695bad3751011e8b5dfe0053fae8ff2d5c354f62ddae0bfe2158813dfbd4029c2f5fceb959824e2c7ab18f513e7f293a023c162119761e2cc1520075b2f7be552faaa70c1bd6318f3bd6cb6fa64224671ed6acdcb2e996661373b44f065350d0a2e56fea12bc6cfe326ccc1b64513f117fa47e0ca8c583eb25bac76dd47801cafa753f195dd99408ea4dc582564b228fc505ad6cadb22bd22fb5ad412163039aaafebbf07b00c8798034aa81159635892c737653b082b9d2a723dcd4b5260f0d43c41df65bef89c507b2fc3764eaae98e0bf6000cb36f503c8a584d84b7d8c42eff3d05d8331a3126846b390f198d249139448f86f07e50dba15ca7ea3a86622f4408d191cf0dc4f854fd1b52c50c5128c41ee071e37f714eddd1450a64ff8fc6988dbc3b848c4a8684d02b12d87e0d0d3185344e053c89f974a4694c47d54d76cc352d74f86502ff871974f3bbfc27cfc3aa303161ee9a84880953b275a7a759cb7ec9155ede82be28c3f182dd9cdbdf315969d52b6eeefa3a27336c255951e4ebf8556a04b4322eb431a3afc0ccd49508551c24d43a7e1f3895aa0d8e9d72c15da0f8103dfa1f9fb1bedf88d1bc1d7d3f34bcda9f41e26d44b864cc0c2895525f362cd7257d11aae8680d33f56cc98adc548b47bba82430f7d01bd0a50ad9bc9d586eee2ef3620f95f3f37d7e8cac4ccdc17f7e91486dd5018ad3f2257dc475594eb5e8dce5c5408195d052b4d92fae966fafd851e458143ba19bc4e5d9cd3ccd3fc89894b62d96e0de96b8000b760de82d7733c8bfa25f4f5ae0373cf9f8eb2fea7903be204931727066744d0f933e2b24a5e48c262367379d49000b65c968560233a851a4208bf2f89a2d7e11a37478f588c26a1072a446c2d7f46e6700aed9cb9a358505b60d88963dced832ef99dd989eb43cb4a5a69b00b49e02e00a618c63349140041a62acdea08c18c214f9dce10243d69850e5eacefeeca4e4f87396b6aac652b748d72064faa23c275d668c018a685b44e12637cc7f90c2ad8f3236c70ade26fc4310d4435d7514bc708e1e54757325d7d8aca953c0b6a7b2eac1e91152480bd3d3943dd95f636483302483fa22c4e691279907af25fcc833e1688731da7a85a8bcf2c7090a236b755cbb7085f446214e6b36c02d1b9a228769ec69b85f69f8a525e90a7f9b94aeb73d7834b2cf0f84fcc801078361d228138ac043d59e54c240c269d16584950f60a08ff46ccbb1b128cce20305d8a334d2a4a65b3e6d6e646a90c0d4c4abd7f5516f0c0f5fbd7caf1435063799d972904554fff0f5c7aa9ea8127fae8be4b3c112bd8a34ffb2547310d00466f706e10f1cc4b050260d320d1bda3f8124149a0a96243261a6cf78196aab0f7b08b536c16eb65ae7c7f97ada7c938aedd41a0d52b06224b348f505606e53179a1dd9bc540fecff4032f7d7102ec0fe345bcd7229611654587ed28f09bbb5dc032aa1526347af6eae3d9aeac9835213132ea3e3e71b86100aab66b817c7cf7b921560b354514aab3ebed138d8180fc004557a97be9015ac00ed49c3437f9019daef2e95cdc99133519b845ddaec5a02cc0d6e994ad5b33d50d393f0fe505808140852e8a6af9ebfd1db2d8f074ad29180305f87083f9e3fb77ededa663ae9531ce44074bea3e3bdf23d635a0102a5df6415caf4e1d780e3f2f2c0c1ff3494a1102458aa9c58979b554c3a71471f4d0d80c408468633d02c7f645716aa5d1959f1aaa51fbd377584f0daa34f2c6415bae4c2ed42a748b78f5ebc08a905a8a6ea5d1d7d791f236dd456cf52c8d30bd136435afa94df4689094ba1663622d6f737c1ac5202b315143175a7b26ba1dcdbb276246d10659255848206d10a3d87664fb557821a1515b368efe5b2263500d8895464677d7864e4d51b0d3a26821d214f94fb027aad69b1b35159600de727f7846f7a2ff3993d9386b56fa38a8cda76d909d45686216d8535e544bb8d3e6e9597d12ea42db5481b8b925e322359f1717dd83a2d6cebe47a94ad52e3ad9d322c69487e8b444020eb8f3a96e1daddef17b5ae478711141b3120c994371518ac72f9dd302e1395c5ee75b641eb05ec81b84e74d0829c202616050fe320d6f31d53b0fc9969912cc9c205a17fbb0c502e1245f91bfa91d0b0a1b0b042a2049240c6f0356f88fdf56efd83f4b32155d66943f92a8f5d1383a159f3ee1482232f1da96e83c77deec7e7947fa771f9596029c118dde3f9f76b3fe12ff52c5adca917cd59a9b95577e3e132750644803baa609ed0cc25122a20c14531d5cae26ff8c9c0b2a0772401563d5218725924e8b27a081814dc80bbc88a414d2546cd768fc937e857224e3b7d00fb22d82c788bd8998b8f79877c225ee130bcd6fd231fe95bdb48c883332a4284ae83483b2f83299de1780da1abcf41c8884d21667371b046eb4e98109b23eaf2715fbc2d206ff444fa664609340c28131627d622484d4f2824d9eb0534f63706043f1f03f66969121c524c269ee5c3f1970a86f61cec1e69d561c6add3182a252d333924c06ed692e22988e9adc9253e19f8ccc2ac2416c1f0fc947435083d20bb44f3572388405a1335403245a03249bf73b5419100278f563b92674a81462ee0251e942f60671bcf733733064733606070cd9b69ce6f35b785c480c341841251c33e2379a75c6e4fda1d91964c53fb1a1b68bddccee1f266e2c5394385d9c4baf082a281d304863410c3ef16cdcd45f20a6479df3f1bac6024e42a10316e1e58f14fdf56c274fb99fc20f0c1129d9a8670534cb271cadfc0fef4a7ee4eb1fe46e50ff4730050d689249336a46572156d09922a23b5fc30d2f1469d9dd9d33080455665b330d9a9f71bc7a7eb21bb191aa3f3eefd0537754dcde2d0ec4a33fdc75cbefedac2190d502db251bdcdc9b73dcbf9e76a54fe4cbfb707691c92bb2681fd5ef0c22899335eff3d41b0c0463f25dbd0faadfc31258de222b7d70570bc73bf828aee036cb2ac783ad29076daeabfe694ae8812aaa522db506ce3da6debb5b78ddcf357cb72ac488b47b517edb7acc80f8cce616d4c4c25b125e6a21ee741d2ade25fe7837e475a32669b30400c560c3f0cc412a78052f5f82d1d1eb1bdf5eda234ab55f26c7ec586f93c95154039e4eb248f0d8e3b72e1cf5ba208d01a4305c929d8b6b420a9a64542a39442cbb2990856e9e8b61669bf196eb528f9cb8ceb1a7d17021dd34eb15b9541e290609c44e436b99faa512b6cf606f6225e6ffab94db941818f03106f200d426ded1512a1d6b8d814337e8c636ed341e813e5507de6fb8e7508c9e2f8290de405734b3af784298853d9b07cbf098f32f153c70db2a14464c4854aadc45641c744f322d0a4d02bf608d7469fc88e0585acd1b3691f2887cc02840f8217016e9cc87bc205c113a689cbc641b8ce797c32153de0ec7ad75a0e89f251fbd415fcebf7e88a39166ed834e141c34dc861e06c3447484f8f51fbe67cf46a80a6e73a4301504aa7872ab32139d9536a9c1f8e0c584121b2e200f30ea6739813f008904035976f26bbad8af4e090258cdc7aefdf712b207ad71de30c07d127bdc8dd9cf713ef009834628a1c57d510209122f0e2f41199e01a6543e58d6416e8c49f768ffe8223ec834de81bfab71db97c01922025bcb7e1cd3fea60e752d25b4879cbbbe5a6dfa00e32adbc043da5c62a6c1e810f7072d7b42877a81e354b6b4bf13e65ecc804e507b41eacfce632feab55774216b9bdd40445eaf151c457a924e5449daa02640dcff2699c13bf9a96901c0c84c82e1224976475619999179a253f823a06ca6b8fe11f9445d4c995a7e82bede49db3422cbe2bf9c7e81154f07767b193a41908f079432d409f8ccfc964a49d9fda188de07244aa9627807332a6b99bce9e95f700553fbabb053a09f11ab3c1d073c6ae4f4b2da197e6a1754d0381bd9a5d4d4fe45b3d555d4012089aeb442fcf05b978c65f8aeddc6d82a879cc2cd24a7d5aa45742f635be976874fcfb62aa4ede08b7a27b75a3b1768bca69e8fcb1683fb083e069a48e369840199025b737408d365c45645e40f6bf8a3f39d09c758743ba5dc4916431758d7b468d451686402d9a81a6a602c18911732069ab8b2f22d0988bf0ba9a33f728cf3112abff76aea06e2ec4b744bed12d1e50b099583c89aa5941c38c4203a54ff10903cec4f18aa84884402f82cdb473283f91bc5e60f7bd319db11ffc74c4bd3e31b6149be4d12309420e967814f4fb3f5daab019a58ecf89244bbdc20b131c2468e7dfa2a33f7436eff65a8ca751bd3dad736ff04ad0e9fd8ca6dcce3d46c9ac185d7cf8cfb397c4888f043f2cc48260a190bf1e5a6d75ecf5b3f5a31e5b67a34fde1297a8ea7a3a9644d79b98ba856e2d9a9f3e9f62a1f144b022f995242a243cea676e0c1e20553c7af32bc847d0a4376811d688a8effd19f15deef6473dad972884460fab3a1454f4bc82305e80261fb92752baf4971dd19b49de6082e32602183902ad2975d63885a2a40010114a8c999fcc934724e7ec68117872c18c60e60d9e3a15911537a47b5520ea6a1915d0f2b73583ec805bbff55a38422c85d2c1f70951cb793b76412a8390f1478c98e24ee1861bbe9a48907143972a0a85f48e6ce0bb729f4647429869ff33003f649638e700988613419a95e5f48f4e553e8b811e79001c0bbc73c2d291beef22c48a3ba271c604d55a5874fc1b98ebc42f029c04f3d6b6a7223bd2a50bcbb470c6c7541f50c69de850413ba77a7fcd6cf539371277d38b4ef6374aac44e46658e3aca566394ff7e2733e6b6656cb025b71bd694d236a0516e7b3dc12dcde00696df3eca092fbbe3123b9747c93eb179d925bf536ae37c009f6e021281fb2303a168d2115686ee366004201ed70e2405af6d00ee2b0c1065118684297e24119130ae6df79671a71e5e101264114c407e157f3a7e30bfe2a89b4ae619ca3e10de20c843316111df289d508400d1d550fcaf2501da33bb43adce25c7154c4a843c582c29b0dbb9a863c35a94651acb822edd59b1f8bd09ed5778880374cf56999150e204ad46f7f4ee903d6f548dbe00177afbaacb8255664bfcf4c9d12148bbe14fd65070bfde24b1f1434facc9fae1593faccf316e5d3f75693fe51620a249db1f6e191ef0eef924980e94fecbc6a32f9f66f3cf510d66d8b0e531876799eda5d40eca97e9858e2637d258805de1e43b69f0ada8d46a29eccf0da07e517624705d085cc35da3a92d6d489d04af97e2d748793a19fead36dc40124763b8469520b36e9c6d8fd9186d24e6acc52bb791c25e8be971989ba84408437b0a2f0577fd27ecfdb38af4e67f9144e27e6f9aff7f9e282f0b5188014976934a655a1e2307b2edc3d81e74a8fcfe617279e6bb0a3e8526856270efbf2a781b0dd96e3a1d471bc4519c60109e5d216250dbf9905e7537eaf9acf8f71afa86535e08e511179f3ba0024e2305921d855d9295dd3df55ea384f678a55da3779a00d31d262434f2f4b682a33d0c319472dbf56e9abebfedcffb06233e689f9d0f014f0e885bb767a2b8536fb5d85a92b924e01c2cfca852212bd0bddb1ae3528b3c4175a02c590e484bbc8467e500cf6051a0bcbb315f0902cca3f4942a33e2a026a522234fbe3ca064d539d617da5ff1f1a59f15ea18a386159ea1d4668c93d58f45a4185b57ac191adea4ccd4f4378516276c84ecc59395461e0b740e6fb4325384a04a50f48fcd15dd1f69e0244851dba66db4120e14a3b3089281b13433f57abe60137e0c9fc6c52043f9bd76b90086aeb4dbe7b850b750b6bb53ba8e1e71a052b7f08da5b816b91d9122a9abbf2da561d5f3e6209f26915f60c1190af367478b2fe33735775bace397878f302c3742ace2dcee927901cb09d1123cb7372f419ba7970809ea25c6979607d37d402e64485843c47cbf5c952185f33be943d0701a9d7a0a1b3a665bf9570d3d4c7d372f5bc9443714dec33ecc847a1da94dd54bfb9ca4be2c1f195122d0cc042de68739e9fcfe2d045770800829006da2e1041b09f8fb11f577f10297a6bf55584f48dc777ce34a415d1d01f0e264499a0880634f5b1aee639208017038c4765b6a0da523c217d4a6b3bc59fb99818dc5d73f576583fe6fd6300af76371115c07fe007808732198eab5e66190cfcebb22340e64d1bcb555bb2ad0305a2e6f97535d1b7bc2149895044d2332714a09289a698849876ef651b181bd3a42b7b20c7a4c72fb65a8b933458822c85b141234d1f591489a4a7ab9e3c0b4312257ac29eec498ced58894ed8b4e11fabfd5339dfd9e952de5e7de42234654438f3a2830ae8a3029db266f50420b654a228e1c4bbf38fe863bc6d98402760eda3f949441387086947b15b05aecd7a24c33bf2d24e57e5db58bf89c1820ba54cd73919c28fa28246ce977178f818903f31c585e8490f09c483fcb962dd9c4c7203472f7664b1e6892e3b12b7ee06cc9bb18e0b53ad2ece96bbb9eab356cb3dfcf8ac35aed3b0dad5ade14a34c80c53218ccffb769bae236dd8d1199c7ec7511a493615f3e6b4d68f9aea112b5f97e437714dc555f03b084070c744a9b8316e3f2c1d5615de61a7f219559cc7fe17d58206ed80ea9b57340be35960c2c50b25d6ac1c35f579fb2b506c91a8acf130b7db23626b4c2a3ef959e7d691d5c9eba7de5ba65bf4f0cac19165365ea57e921e6ac30fb1fa381667f2d526a38667cdc94155b1f994fdc6662b2a4f3e11b1a4a4e256e819e3afa069824df70a003e161ea426e868b7f49fff155ef02531b13d39907bc000dbc72806374a8ee4e6838baeb39f4aeab34645e838cbef0189c5f97c6f68305b59f2dc7f4e126141ee36b9eee6da581df7a7f840b92b9c171c6e11747f8f2ec31799debd884c75856865c5ef7f75cfd9eb31ec7af0df66a1857eaea47f80973c025c4e456a0845bb004e87370bd76dc530b8de7dd85c862bccd7e730aa94ee87f5c825e93faf2b1d9a4e1dda35079a6b6a763748735cfa19057d94b664c46438d3c5899520d9c6d3e17734840724376ec7809e4270fe686803ea53b143789f9f21fe6aada26aaa3e136c23167a7027a04a9daafc6e7b62a1b07d2bc08d12781e5f83f6cda491f5aa31c23dba13f6273a97b6f780955dcc43d8dc6d23279c337d3562bd250d61b168969b1ecd1f2f90add949a96345c541bcdf1ed967a3b381dcbdfbc336d8dd35f14aed206300f5eb50e65be2a77c1c38b791e6e0839452ba0805231b5df19166df0b99e2e5f8ed5857429e433864ddb549f1725e9110ab1e0737a62ab476d153bf3174d3d2505f1567d2b5b0ea20dfa332893dec5881655ebe236b199de5ab4f412f92d192b0e352a4c211b0f23c2a17a8300c947fb2404fd65db5fd68173b43c99077bfe45bed7c7736b3943017a314369fe560322ec9210c1ee710fb3f8bc597b6819a64858b49f503174eb37065ee96a684ab58dcb7ce4562c80d2c20c78ec256431fa245c30981911ffeb78d659312172e73d17f4397c0a83167f1ee526cd5d12d2d48ffde9d94803956597a386eac8d66c4389797f7f93c53f5d9f4c7c71dc2693aba15d5b95d0ad4816e4304f1c6439b59cadca720fa365ca897bd73a4e133653d93332a110ca1d68b58dc98d26561b362c11dbcec605de270e6889f95b4efa159b8b1edf8982c2661eb11c77a2d1a0380a85fe761d053c8a894028374fe60094cd18a869d87f9903b81824596ef0f920871bb9e1a60c7ee860beb741a1d36b189dadc644bd0a0f95cde7c45e51023580f81e4245cbfc28b23968da0937696ba007e8cf7e404173e6882d027af461ce72092301dc90e71123dc5c70d24299de0cf7b26d3b38a36c6adf0a165f0653bea90f8ceb27e02a43cd541ca43371cf6308bc1b9d8bcc0b2f7889aabeaf138a610a6833a8245fdffdd656418d0327f5c322a3425b6a5c2e1fe1a8189e90e3f02ebf9a77f348b03a6235eef5443e8942df8d3f63ea33afc37d2784167613abea4fb1465e8aaab51f71c51d35cd726a5d5117784c314695aebccf967bd185747154ce9557b457969f490deca1a805117365c47f75a3e4cab87bd1b00064ce7c2d975f9768a545bf77691152c4aa4bb6bfee0eddd98e790d7ba913738e99726cf2f09b8495e3531cded6d96d5119f5da971579f4dda5102c27e563d174d0f12a098139f7c469a135f4b790f350c4036fb67e6224cdcccfb2e9ff1a41f939cc68dc4c0b24070c92a7b8c42a2ab216107c94e621a2c74d3059e3409403ca2c737acbb0d29fefc69c9ff99e06a12ad9888928e4a2a353855d4e171f0b3816973812edbc6f7cceb6ec2a63628dcb2409d5fc385c40e9e01dd1ba6b10935222e416665957baa754260ded401f2c0e11b69cd174799a2c5090358413fdc14ddc0bac60219001fa97322f5b1bbad5a7e1caa8220fec2b222bcf1aefd143e52ed8b353152322891fd153c8d8b6bc8d7e45e49dc89f0df7de23110fcd8b99b28f4edd1497b5d679c769f0fa8bd3b8cb92a035d6788d1dc8ff7f72454812fa6219192a4818b7420e2361e0caf4493aa2bc1b751847d818a08e3f59b29940cbba99a4e6fce60252c70bed88724dee30da6ebd9c4795076d17fc94e8f61a62d300867ef4a76cfe433c1087e66a4a1bbb81d1ad209b579c442db285c11a1e89c66604012f0f6e7e142b5942a5b40909b38805d1b3c762327012a89444cfd78000201753625c86f108f5d180218827ccc1e6bdd402fa96e80a32bfb2b720b85ddb168384d38b36bdb31044fc9119dda0482bf2a575878d8989e3f4a1dc93b693c754cc5b27e065bdca5deb7c254f83b21fcbe680f0e817bd9a800c7c150603f59acbf7aa5c76a3c7f0053cc7889868dc4aa5d54fa216067671fefc11fa04511ab513d65f2db00605248b974250806022f163d1e3bf385a80ed5d2c60a8f2814662a1300adf85ca39dfbba1771ab2b3e534fee7e51129b90cf92fce697219cb7e20a06371a09d1f64e21f54c2537a3c5a0f3ed5398429db3d1591f8c7a66a4a2502bf4d0702a24db41e9df2deeda38fc0101d5eb3654f75c474afab54e8296b60087598967c1bb8a0db4056163b4403ce6dfb68e721f6db933e606d9effba251e7d056513117031906aa79307857c029ccd87c719b32a80afe7c8e2ecf5e2f60a729f28e230cd75a377a641bacbc2221f397c9fb62b9632806e7e33db7a5e5e3ef7d96ba2b3980dca335ff4a50cf36b51c8c90ab8208ae8359d18a71e7bb190ea7fb40594252ffc1c2b1d6b86840725eeaef5da16ec0cc337888ec628e9bf8f1f5c5b381bf2a267c11bf6c634f1be8115b8d6be52ca1618e5906942fbb6a682e4171d849af3c973d414a26ea3d87c23999bb80619bed6c4d5a2906b80fbe8a41af1127b2034ca403e109b7453c73ab467fc7e472f2f6aed293c96f3f1b32fd713b298e060781d8b564541be9c5c79d1475835006174b448490bd65fd0fb1ae60d0ae4633d5cd17a4d0d44d5492394478b9bc9c9650cf4698cf795f64fd40f035d1b72d30762f245c1c8be85f76981758001a1b160a56a812d5df257a297b7e12d084440a8f111bdfbd081a1e320a2e3f0a9f099d032304f77f58d13991b8c6b8ff822977b20c66910606412b7c5d5e8978b2d5b75f7295524db7679b4331c5827f0f81692cb710e20c7f3e20e754b34118defe53fbea9c3a0a65134387bf3cc9810a6ac7b3b3b15f1c8e88e1d068cbcba076324d732c9f6ecfdedf19214f41f85a78039f63da2447e1a9e35a0d8cbd2819cb6ac6b46ad11fe87aeb2641e9814386dde74ee5667180c26371843b569c1103c13b119397a269318f1502761a5ae0c3fc89299a914d3faae9fc95c38e1a5b7ce9083a4fa5bffb963b2770b900e90d587096a9d33981b179291c9af15036b1f9d385c6c85980cf9580c7b898534d88c16ecf5ea245ca0587959c2fc791376a38abb575a8b9b05cc155ce4572d474d35e323942ed289403210f45396309878a57b54065877f3aaa59758924373b47ee929b0830ab75c6fd1fd855e3a4321afbce4b84d15e2f71f01ec0c1610b53b7b3460988a6d9534da8c385188d57c88973db4d5eb8e2007b00f53ca35ecf0ad19cf7bdad3b2aa68cd03fe58737a6cfd2c8b370a70e9d4b433953ad1040def61a9caf1367f02698c694b840df28e078a0a4f581886121f860fbef28995036edc9e4b9cb8ea3f83811f9c8ec5a28252cb80d7e3cced9c82389e410c36002ecf25842cc523a58f7d046c2092c63006d8205537e3aeda22ecf2f4c479226cadd47aadd4985ebcc11e1129845d53fa3023800b358ce38257275ab3c8095ad61f6aefd20ce441560804247c8a7d73591cb1412b22952a29bd18485a0058b9742f6feccfb86de074f1d19f498a16b65ed6cba8210787ca0b3a9201cf8de5541bd599a62d519a33c32c0f7fbf329578322c6ecbde3b92d1be8241e2146d691d29e970832189746f968ac3bd79ce43a5c5558b3a42a743f3127a329c90389fcfc22d60777210f3ab6be73ef8cdfc5ee4b8a90f026b4d2b462446ab5dcf9aa05e37f1e24b47aecb77b63541228f78115283a615d40c8ac4a9d51dcfb567945cb12bd9ce47d1a0e05781d9d351ce863065d12f7096ba11d5133a0f119f930d5f15ed14fbc152a24f5e9b10ec10a1165e3b747c7ff5de5c21603d24676c3f9ffed4048ebd002e5f5427f5e40912f5799587348ca28512a2e4ab012dc66d7ab9221a55a8aa12c977ede77e96f7c0a01aa21c0c9c937e13d8e4466adccc35b4525ff01ac17669a98e31cecf9df6bc825b68b86a27c922104f28c0cbf1a6fd312577ba7f27aa1e1ed80621cfae46ec385706a295bde402cdcb8c0c6247b6f81b1d4cf222908218cf8fa275b4ce29dce03e956052bd1b3a4ae1061095015079d2fbb5c8cbc3be96041e4b60a5a019c8d71a2402301e86d0f5c67190bbd013ea90d94dc4e297211be06015864ba75001be8cfbe78bdc2f73a12279798fd56f9ee918e2f3e65b8cf84208160cd3c113446f2a6894c5136dc033353e9a87b38fd160392cf724a5b591ce8818824415d6bc50b40643d2f61541ecdff9e62e46085683614d9849c3aa6b02ead05f8b7c001b409d1da3ca7954f1acb8281bf3f53f62e7e2ea324247941a97063a2588578ede81f46ce3f59e7e44ce42ee6dad846c8216d000ba5c0a711828bad9fd60ed399fd703c8e9f2f1cf7380807fa462187080b71658cd17c653b152c22cc1bda870e98d68996194894d0867fc7f57a9abcd496cd36b19fe0dd1c54300a55d5451d5b67ea969735de4fd6fc3f06ad07a307ece0074b0d80bcbfafb30a8656a9965ab4c2d8f911430b11472ee5ef1b3a2c053e48db3e82f1d4139aff10d56d5a8d46de6f3e960a806d7202375a272ee99114935c15bbf286a875a28eff62b3f3bec83b765d03e5c8d01eaf1853a380226b842dd18c453ee0720c9a70b1b53a681200b232bea0d2d4db5a1ffe3c65ab15200c8d6bd963422bca72f4541397575b8d61c291b2e4ea95c3784e75c663ecbc073720efd1e8556112c3a9ab2871c408d1df32ed653cd58411034800b897666ab7dc16846defaa9026eae1811785025a33f9d3b33b6b0181335194a82b99a6bc4dfbe0fa3bc6788df9cf8e9c7d1f8098d14c5f365ce355561bb4e0820aa3cd2d786cc44688d226a715456ddbf4e483a555b1683af231b32662d7a1061ad6ef1bd4a8e9024522d9534eb88ae5863afc33461eb6f0696a74762e4b8fb742536ea0a1e01d1ebdf94165c2547d8342d67bd8ca87191f7f071ea412153557fbf0580a723b420121e101b24cedfe97b6d897b9be8de8779c482538a8f4cb047b5fcca13aff715880e1211e7119d2457d3484440eaf0830b6f845363f5e63fe4abd50b301bd0bf746eec90ea03a36ae540b6cc5c125732c9b7daa7878a72ffb84113aa157cae408c9e9928600db33d91108e465e146488c95636715048b86a9155a5dc4328a990c6cadd4d01bd30427de3b4deaf3ae5f659689b5240209b61523210d0576b4362804a554ba98c9f31b39bdc19e56e8cf1611006df99f7edc9ca8e94c54c40e235710a42bc200249d377c3b183f596c60fc03ddbdae6bb4af1480eae36c59c0d11b3d6e5a8e5ae7506ccbb7f884eb6b1e72d84f9695e96d5b481a5d9a4991ea5976db9a926527121e96ad9afd23210350286a5b32cecb68870ff1b9d56a2acf6d8a71c610234ffae297d84125b182a4809f7c6ca9b00821d46ec0a2d6a59a1a805b9aaf57b72544f40d54cfaf36ab7d55d295bef11044015d675abcb831a4046d00d29e109405c01527528f0f5bc821b0722875e8664976d7deaee2ba2b58d6b70f8320895593a5673944e3fbd7e4040b5811df184e069928ff23e309d149381e5b25440902429a8ce5ea394eec643549fc0512a8477ba48df6d564af9ada1fea8155507ce1e45d30be966853cc2b0806c5a76ec92d7e710ba1c0b9f855a59cc094699788e2a747a0971d2ed9a321fc63a22ff5dd6c29bbe21901344665628c55001f998806dab99d9efa692bdd340de9e19c814f4577ae7745bf441344d92320a4dcf8494061470d25e1e26612336677018e4e439c870022214ab11d9e71a9b1491ac1d0b376f0e30218c7e48d497af6c62cf4e7722e56030c11d26b1ca51434e4fe8003cba95407ce1c6438a6b2c99cd33bfde34b2682b3d4c2f8e60dd11e6881b8414182ec2bc9bbd06e579158f0ffcafef3610ecf0d59d4ada78161b2d5fc99548d3a236436b2e38d47f21fe34dd9d240ac85a9ec54d1c4890ced77124d27ae3555cf47cd5dfb1f0a4b83984cfe51d53a56f2a6210620ac6f9c9923950f70bc4c5738d2e4e9767a37a91714d969ad66b7bcf52c9012f15dc602ca95798c59159cba69cd29b6a4232cabeafc8c87be24dd1f02842204cc1332b8afa3f9e09e6cd160704e1ca7d1332b890a2151a94387b675564c52bf662bd6119952be8150c8c4a245ccb22e6db18a05fa121b2b577a94c71b08d7d021a5e64d54438cefc5d2ac4867c10868d68d6d0a4cb48a43084a06f19fdcde7472a84d23abe8bcdd37980eeba6b9ec6a356949159187d4b2b9d8a874312b3b9983514787b102add531e6a640e8b8fd240484b80f3d1ccc95b649b6c2750f4a6397d33c59367685e5cd2530310aa9bbec18ecab748f7545c5ed8c746b34b0102780954347e5650c6c1bfc23e66d7d9f438c32d4903e8326b927d26088b1317c2e3c1aa6db9f1673bab5fd7fbc9d45425b9e413f24b886105edbd1d23ae511b45384614a5ee7710e7b784205456d861425a6382390a0f73fe10770c4f3cf23f8206b410e9639784e632d79fe439db98e46193784ff8ba338d434ced3382bbd790a85ea122dbb1dfc9d474a566b455f2be3fd6d2f9bc6d3d6432eb437accbb4db6dd83271f07828e0857b9fdc64eb88cdf2faccb7dc00be0a17353eb1b0bb6c0d7695e6037abdfca41b88004fd3ad06f7f07ee9c8a1b602c7d306d4e9cb8f75fbbc24c9da340f406ef9b1647524a88c356a14e78072535bcabca2006086b852c903032639bc6a285982625f0b36d3440798101c8d4c531be35db8e9311c43509c378999a52c6415d666c69ca58f6ad912ccf5d91a80a9dbd3c92988222965ae047f8982a412fa9f5aab07407419dd5d0d4fe961da0b013b9fd9f08eea991e4fca2edcca85d4f43bbdf6c3fdbd478cdc2e7f9f9f177569d536f94b7f36dcae2b9a7e59164259bb533f59cc22f97604e83cc41da5c4ec16e15cc6940177352f08fb5345e4da6ac2e2f695bbe694587aed814e117d3737154e07f59bbae3080afc2ff6beac6988862d3700b57b5bce295d8d46816cda8808c4855c1da25c99a205d0a9cc344b69165b1fa50c2d32803cffb399f0b0e94806dedc32864bf1b10178c014815f553a6be84a2953e57de36fbdd9989fec704ec9c0895c4472f90b501d35e95092af866019481205e60e4cddfb82880e5448b9afe51e9d2dd4099be398fb7fda61ddae8610542c683fb0d3750e97e37c055e629b47e4d4e1f268a5700f133d81aec8acd014280bada48a6371d198b3a5920a1b5b2b88ebdb9d4e0f1b972045c21d34e1b542a1923c0a2102d3321ecafee4494e0960c4d798602ae3af5ed1c681fb8e85d4a26fb8119acf774214e61517eabc537fbec3ddf5613264e5ea3f8413ba8d24f8482b94c0109c662e50f42da86da41a2ac34e38bb7991bd6b0038180802e4f9b709feab5b9c444d09473d458e5ac30a6f9bb0cc4b00c24d32f79910ab8e9b36826b73102aa83a331f7d1c0ca8433602ebf935c217dfd29aca8f8e9ef1e3e9f5acf9bc7fa003cb1fe4548b54ace0a4b619b2c3f207c7428ab1803ca56613098d859c885a93dbb01d7a222607e27e71a15a34a7d1d1efe0655b818f044ddd4ec4c91ab49ab18d58a7970021f0c92e99c3a95705a797a99a8b536baa6f6d31d2a74c4c3db08217a00bf8026555a6f869285d79d8a7f8db9a67db608dc994a3d21e07bb7b333c2f423a5b31471a39506bc823b6310441d9f6448c9c7c8aae1bc391fff94419da3e5a6b4c5edd87df9c3fa25b8d4a7da86c44c2406099bbe6e80789c942450d325a5c147f1961ca74b7e688be7ff322616cf4706a9149c9fa114dc80d704df620c8a9b4ce483085fdf63d3154c533b645729c3783c6f4a95537a230c492068e61091298b3cc70e90431e26b516ac8ae634910e1c17f9ee734165f88f366a0552890a246f7abefbbe6438d93b8896be71db18e964ae0f49e9adfbc1e1b987f212148ee5e2ea746909d8f857a17580237b41957ddb2c0036b0db4741cebe30e42b5983f4ffb452ffa9797b00d55fd33f52b3100a274c909c30c60c0907a2ae864b145ca41031eed91fe779141baf7d871b6bf351d82c415f00c7c848f937b98eef20768782670cc962bc4f51bea2c23e3539c6377464acd12eeb6ebbc623713a3b4a22cdaf4c312dc9b3c90d4c1603d54f738e6f889b445d8001709ab1db64c24f057a4350e9de7772d559638ce3456a3852f8bd5f94d6cef422c1f2c40c6892cddff12edbd983d4475fa59bae4dc9b9b1ab9d6b6c3fed4046559700c194b81bd7ddfbb16e7ca2b620a2541c1a7e946a6b6c86036862804e4596db4e4fa6619def02764163512278680fbf40bd6f44485f771cac100d379773d58d2a4d2f21f2eafbd306f26ad52ef2a8abc0ba39fbb9b985f4d9415ce937181466a0a24070956e562bb9d00549fff52aeaa4f4c6cab434d017588775cd0737b551d7b7979ee32c12361a7512a60083907a5e6b97f061a2920a210a89b35750fcbe355fd58d7211e986633101849b9ebf53912cab3d50a61069fd3f58aa08d9f9c5ed69e3ba31563316d25d7ee6c62b7b629cd0fcac976e9bb0dcef4f69eda5992f81ecc1d90af0b5189bb99072377c2239560b8a9df3ac9f9b36f86fd2dc9e7c7b2f2ba82b671d29f11f15777b30544fadb41b1620f2787975a02f0e64d208d2bd3f9e54a00dcff19ba6fd77963227c654c7e358042a7ab72c24c1db6842ab300091f3cd7b37611b94d732b2bca6703fa096d23540b5b1a80f80cf3a2af3b8530e85e388093464a98c3e30fccd48a5fec468d683dea74504f645446f0ce029575e879d855acc68cba782af074fd4ea41169c71cc488d861d31ff20918374900346222eb083da3251ba1ae7cac6d26ca1fdb3d0ad3595f4acb0679855f6535f8d0d954e898eaed73f65b62367857daa729c5d315f223cc7502bc90fd1ef70f73df55cdc04875b5f8e387f2c1efa73f090e4320f31d8fb62833c5a052b2405ae5886314b98d6330309c621862634a6879816a73d67302b6a1a57f10c2f3e627b5f1790dc3f8b9f4025aeb03fdc30744dfdc8c979985b3a6096abd32cde191087125e03b9878f431e0be8e353a1804bbeebaa6723c9832fd53ae5ae10cecf0356a1c8d0ab70e720a280e69bbdfae01b3c7cea347ae04cafbac9e9b3cd707c8c099db3526c06803063b427eb46e4116df13d33c5e5b7df524dd1cc5bba20036f02bae5968a1d00223444030a4c06795c308c4a4e07ebde33e77b6cb6e745b30d681b967e9329debee0e531201ed67bba102646712e7e606ab87e4441a758046cea5487196e5741601cfe3abe995ee48e7f0323a400aabed1d0da27f5fa5fe013c84b437bef2de5de524a99648107790758079c16a78b2a85b0f3c8e5cf38ca2f7f06da5b083b77dbb87da305b88dcbc8a8ac0a5917f7e5df3e201db41657dbebffbe22a128d15db509dd44af71dfe2083df76a5b6de30664e7f56bedb5cd3dfe4dd4e2aa4389a8d7dfbdd6bf3312d14f645656b9fdff1117f7ab1cb0a4b24e54517295d359c1c5aa11f7b54bfdc27dad155685dcc57d0ed8c9ca70dffda4a437e6ef5125395ddf5330ff97c7215403221ceead444037f7f641b8f17762a9f735da9bce155815a2cfbd0c532028a80c51c392132f5078808b65220e15158cac0eb54aeb1b870c93710a0e51462459776b3dccca00be6bb50fde71eeaa268a289568ca2043e9044c7630aa72c3ab7a400a6a0b0bb3872311966a40410a3166ec127084c8709ac4c0e9616b72ffde264b708a6e1370cf599631683a24db15b20fa626094e042e2099b1d6daad5a6badb5731583765d7d5a6badfbd0a696035f83b6f427cec974f1fbad368b4319e816ad2fede27764cb0798810e43ab83e723c4ee2da7d4bed16f92506a69a594d25aeba6744b736da873debb8f6cee63d4086142d209a6086302154bdb96ac80e3c25695d4eee33d6729a4a0046f06b950a7547fc8fa4cb3b9c0dee5d68bb6e2eec6070469427f34a7fc6e361d757e90afd91e382be34a0a5338144ba8084848418924610ab25d6a319ef7939294d2df58bb8f783badd537a5d4d234de0c0ab95615f10cb5487e145a47657150b9f8a8ac2898fc69d3a10a0524f404184e609182e504242758151698105984329e0866a0c061db4184378345c90e3fc867cfd995dad67bceaed076f9addbe4cd2077771daba78d49c5785f46e57cb9daa8ffc97914ea518f42bda638b647a13e9c17d8478d2c3aa0bbf2c7fb9cf113cb0af6b8f77239f851a811bf833be8bfcec9f970dac8c911eb8362f7d543594a5a1232c7b536c77dfe8d02ad9cb9f74422211cc0078feda3e7a1bca172d2bcd74151169871460fbcf780fbcd1bcb567671bb973a3cfe39cf23aa763e14e83df765ab14c29c88f23c07776c5fb6bccf62d9da1985aae1799e8ee7fdac42a9f7428a73c0ef537af4b1cccfe5926c096d9abbce3fbbe7ef44cf9efd3f686d6fed2ebb73b873efbed6aecb9ca69e145df7572cf5f61e7ff77df5ca233beba0ddb443ecee9ede21768805a1fe160b945f1ed9de885fecaed3e9c65201a58f7d7f47cc93e59f12bd8ca78dd6f6cfdb7bd4c7b2b5bbf7442c96be87f6edf0f85d52dcf7eaec1bdebf5fe78bed63a980dd3d1ecb17bb0c3bdf41b737e269c3bfe5e9d04a74d93a7bceb064b1f9f1db2be2cf6287e9d74477ffc1d0eebec478d30f81288e0f8676ee511ed95dfe8ea81b4bdf2b6f042102dc1fd9734f8ae37ee7fd043b2f7fedf2571022b0d2c037f7aded818fdfc6dbe650acc59b41d7ea11989a78282929d19413b4ee50a95695c4de9d1aee96f2b2713470b809e71d1472973aa1f376da789f0a4a8de15ad55dea91ecd35a6bad8558d1a5cea1b5d69a47cd51a291e8d1aed11aad512154d786425dd34f18292d618b794c25944e3da1b98d1b794c24362567d2e1b123839214159817dcafafb5d6dcf64c2237ea0a88d8b4b6422f09b1bf94a209d5e05dc0021e67d3771e4f56a1eef36fba89498f2e94e8efc1e71e7feec6559d5f470ede1357f37356b31b577304d2fd4804cc1c8178d77bfcf9c16f9c235e79231ea70e71c5adca32a2f46ef14e4812d3d528436b0d7df1f07ff93fd1878e203527a774070999a6e1121065f99626d910c9a3d5c444294d559175a94ee5a42555268fd28406793c86643e688e011d7f4c0bea73a38e334c581d4ce872d264474d827ca1d168349a75ef8046a3d160f8da2062f48deb94db6a8e011d7fbc0478db797344db82bfd0b8cd5ad5082dcaf2a12f5e130a4aa275afa3e6ea893e74705059ee44e3acdd39a20c1502a29ee45bba7c411ae2369ad39ce65b10ee3dc80c528530a69c2b15d3e5c442640d12547a6cca7854a19a0f893e5e95cea882873a1fb0d3940db496506daacb4d95b99baacac6a9d1e5d090fa55001d0cd19a001c03cbd1cd2fde412229cbbfa85abaf9cd2938960e0d6dcc6d37af5cf0b056edd85a6bb5b539ebcf596da57a1363551fa86a65532b1b7777fbc6f278a0aa950ab55aadbb6d7776956c7a7baaa93d675962b14dc986440f499cc95e9c6c4f9b52957befbd4b565051955c41432ec10d97b3e72ccb122c66294e94ba74c512ccea50abb4ae5966594698a5304496a5166dbd211363062b495274dd73666506194cac1c69d174cf99953056b47c332b55665644d8df9eb32a5434616940228592cb4847820c461449153ac45c46e69922a6334ad018d1118aaa78b9280e3218417379db5745fa324a62e48a4384acc8e5e1af8a5e53f2a6e69a66a0bc70e49aa1612a7279de57c5a12e5d602eeffb2a1123b336c399970bcc2a83fbfef78f6c22463e22a4bc5c608c7c415489b9c05491087d45b1c2e4226284f322cb4d60ae490990f355b1e55290400a25971114938ba404407d55f41f8c2863e49a52e0f08393cbd349d1265f684c2e3752692da2d29f9545691554da747111f13756b481e332429b2081ebfaa82ce79264cb152e231e1043dbd048e4c2c0260531b88818018f704d4a00235b9926ae23faf572557105a4522a684f4cae3af2c0d92908168ea8d72cad793ffc0961387fb8ede2546a47ab5cf5f1f418d90955433c61cf900ff5f1ab52a97878787a7a7a7c7cc8300c7f7e7e58b0f0e6d461dcddddbda7c72728fcf9f1f171afeed5abbb7f2b5fcdfaf3e3eeeed5ddddab7b75afeeeeeeeeee5eddbdba7b75777777afeed5bdba577777afeed5bdba57f7ea5edd3f16fad361dc5bad5640aa162e5c00bd78f17a6f8aa238864463059ffbd00d5518a4220ad23060c4881123045285402a55a8dd9d060d1a34aead9486cf1f202090a885aa45a802c2d385d3161f510b17ef22c8d2f0c58b202272877beeeeeea5915dc7175f75afeed5ff5f14c571ac00dce1a001e80763c6a0313cc6ada0023003bb71108c1ad467850123460c13741d65c890419224eb63b166cca001127d90bf0d90c823d23a8cc78821838824594d44feac1b435313a9767cee2e43860c70877b24a88106f60542f0489205ee98f139050dc07aaf5e4a396c67ad7a33543342151d67801af82e8f78343e1d46d7a861e3d361b407000058f059e0b5565b1ed1416b7c356cd898b5d6fadd7bef68810ab444d7b1fc2cb0a0d50a400004f0b93b6500166f660e7fafa7503771b890677f8229b29543984f341fde5459f47ba2f0d74b6cc0e7a0748608c1ba298bfe8092f43bf0b40e4a27b5a3fa3014150f17180c96278b3a9329e44dee4293afd0e42838acc98f9a7a1e1084e6c3000e9aa8177ede6b308339f3260e03e283a99bacdc8180f766479f362e3562594c1e3e9f0f48843f04ba3836ae088802a9a031ac49112c870687866cfe0949f029d96afd7879ebfce416b4d431720702721890e7e2d36174e9b04d5f7c1fc5e10e03896aeac54e8a851a6db1c65edb1eea032a17a4d8710383f765091e304ca0dc69fbb73d136cefadf758079dc55830fbc2011833177c8863a685daaeb5ed3997466b6f81661b102bc10f3398d1326506850d67542d8011807d6dad6a5b6badfdbcf4b0b7b75b0b5af63685fdba98f12245972b33b60d2a427f1097372c8badb5d642e00a9b1fc8a0a04413319765b32d0d4cb605b7b5d65a1e2ab6657078c2d21d2c1026b3ade58264db143e0a13ac5b4f5b1888bb1ca7a5cc931f2d4c2b2d67aa84492cb4b489f93cfdac80e449cf9657b80294253c1a2835f9ac80258a2a4bad6705189cec24f18c8192d2f2a4224267470450b42a5401565973b6c2d3955814a31e578e909e662724151183cdb68c800ac7719c15d9374978928d9a8c683a0a941e28247179d223cbd1079cf4b0525466498f2ab42094f44821294d093db6182561420f2cb4190b5158e9b102d3cc032454e9a1a5287c41abc228ed527f8c1b748bb6ae93302a5d62c0f4cf9e332a60643ce99e3d6754ccb06054d4e87f2209a8c3708a538f2935fbafa9b899f23df941a414a51e5298286b4609fa1b018906f79cc59eecf2ff63574cc83ad4aab047512c07bde365c60934169344e33232aed0dc120d11f477264691d64acc2881b652b068d076cf59ec0d0d2ab11390446164333054d4b0e2031812642976d0b7948ef5edb5e38a7a083cfa57a4b4eead1ce9d7bab2550b92962d974b7ed15a90c8bea5f6eface307dfdefeaa7c071bceecb2b563fe1ded9ca356fd4e52b2cb9615cb1a45cf2abc2c6b183da8bf71c97fb9e0af2217d8afa8fbaa66289a7ab922dbbe46cbf1533ceaa840dba8af0dda69fb07e5f83a6b503a526ecf1e7c28da75fc1e47d125de5bbc567d774cb75b3b3e25e78341344d8ee20ff4898b34321ab52719ada98b15b4bb01dccb297b3bd60d1b59a35aa62a55d9b441ff0160740794a4a2149a8cae5f6270532af49e6002aecb7e1551dbc50aba3ed2a6235cd7e746d7b1ac62362d67354252b3983a2255a34b0be26a9a5fface1914a4edbbd47b622d82d1f769e6fe0eb97b08e5fe7e1db978701f73f17e13571b16b9747fc5cde954d11757746cdda0acfa198abea3f883067b80e01e95687f6a995021216be7914db4da7e22816117fefc9c08c32e0e7f16930cb9b8bbda461fdccf0d44bb70b9fd2a836e6fa305501b8b738a46b4bf6f969d214b0b33a8acb2cd3daed3fb184a5c6d5a4727f53535a6bec8ac20155d525965794f521cde7bdeac792c3fe86077bf4d173dd8368f8ea56ff781c49f925ee78d1d45a1b4fe3a16015344f54f3425b7c75f71fd0d2afd6a77c6983e904a47226030ad78abb58ea8ed270af5aa71857fe7552b20faf10864e755757b4fa5bf52fa459efa984c4ab45e478b7efd22740c2264d2666d7374e5fddc65def26800bab3d7a2c4609bfbec5b6d0aea8d1ae0711b29121f4850afc1efc421746fafc5557efdd3851257795cfda88ffa0df4d3478df48ba86812c87d8e48912829345ddcf66da8df60e77f679c95f58d1ba08ae8df54e26ad33c4f44f528a1e9caafebeac77dd42fc03ecfeba0358f3c63113dae7ed457fd4a35aeb6a7f4f5d3d7aa5f6d23eaf5afc447893b44c00051bd1e8910019380e94252040c109ed73e5f84877bfde1ab463faa2cee9fe7555ffa9112e1e845af373ea31efd6f8c3b5f448f2efbd28d94e019551c87f281a24828c93d4adc3eab258a46a2421388990a6b36f7f3a94c61082ecf8ccaecb27ed9dc6fff65af29c198ae3421e18c36f72ba751927beead134fec922e39b14b8a4604b235bba46b36d7c42e699bcd716d7e3a5192e3e85115a2322aa301ac292481356ad4a041b3b4942307498ae2cf8f8e4ecebb3651b2be57b10826b7a8b188116ac4930bcc7d9e31b210f5f55fe7f5a833fea847b2b2eadb2094bcf2c54214bc2ad3022bd22b94b4f6099daf104ab5a314d54a631b17c58a2e6952514c6f493c288eaac63e07f382fcf6194071786f3ffb0a98187c6fed27828077fe3eca1431d91215eab9625fe9cbb67eb4ad97d93607fc666390b66d6d4b8bbc310a25adee9cf407d3c6486563280ed302fb58a462a60dfb3489929ead688f8d3ea6d1db584e37442440c59a2362bf0405169c5ca8c713d079fb7a5ec0bd5d0179d44864b5414fd24b8f458cd027925ea8df19573bf8f572a5c6490980f5d7d4eb4f8d9f7ad4a7c62761db79c5b6938a6d8b448f4d1bd60a5dd2188d6d238dd531a6472221bc5e2e8d1a894840e9ebebe5d2634fd2ebf5727914ec803783c017a818b9ea1f71856f74fd20eb33463086852663a490418c511263f6449ec9e10972891c9a72600aeb9a5aaf67d4bd2426c98e729abb2426c9ae6e1a773767eec720d22fbe24263bbf2426c9eeba777edd2f8949aeb31f750ca85be0bac6fdf246d0b3f6c67dfe1af7c6102b070d1af7ea7b6fd4a8d1ba31c4dafe9406ae5af537b4bb6edbb75ddfdbdc1bf723508c8d7b8da449920b8a111463cb01b7a018338ef03c4a291d29c514079d94529fb5d66ae9acb5d64a29a553b4d6d25a6bad94529aad78d85acedacd5a6b6dadd6564c71688a81b51587b556bfd65a7b496b2dbec1db2e75ce568a73cf58abae14d56590a8d2c7b456d4fb9cf306aa06fd26a5d6526b29ad1445524aa9a6d4da9be7eb18dce1b8c3718763afbd1b9c6b3738ee70e824b79fdbfb06b67de72ab7d56b647b1b277beddde05cbbc1b1d7ed7577270be78b3783ca5a349d668a2f77b76ddb360e5f8e26f99005ee84dcc959f4e79eef50388efa255d12b2d0a95dbad3c59f76af7b3e750caee52cb89f1d03ee7a1b77fa28491fc438dbcf74733a42a716751aa24eee64371da12c74faeea7efbb7dcffc29fbbee918383939dd29a84a958b76d80ce99625f56b991b1a74dcd480044de726072414103ee47ce3061876fe9c6f78da59cc6c671c9eec8c030876fe560e5e86f4dc81e382366739ae862336670396cdd9a0c4e666376ca9810a8ebc51f30cf7c3be4928ec7b3f6c61df59d2153430792fc4c84c21d3b219b57e20cdae3448997de0f5b29d3d53c133d46070c0aa66681234c311a784b540481c60010509e90ad212dbb2b132c8b6d5019b5073c0a187292430d44ba749939cbfaf634cc0129a5031acf03169ca89e18b134f098cc106269d2a6452f4cd4ac830981743104b7009455d0c4d4eb825b21c83131dd8f2f8c304d92c8627273f9c182529e18712a6274b7e3429aa5204f362c20f136a33193eb0e4078c89862f84474d1586155186d8fa67519678c2e950ab42a638af598d8928706a90d2c40629566238d1a83d67525c8891468a0d240b5278505531d3ba33cfb7879a73ce7b875c107cd3af7f64eba074ee0952588ba3dbddb62be309adb3e70c863755681f353386d03c3ccc4881fe6ea061a4c13036c070820a309040bed1e0130d3ae584084767bc1cf900e648461e25bda0b4cb6f591454c7b9f33e300744695027b5a38259dae313feb05801b570e1e2c58b6305412f60c49041b266d0a86103002ffcf9eb59a4d37c727ad51cf6e44a5e3accab05ad00086000376edc20000ea19616d779a13e2f7f1d06bd5287404f7a2890e8e6b80e41206d732caaea8fe2708da4718a32a13f4a5677b7d65a6badb5d65a6bb3b515d7ca430577ef56ebc5b5561e2ab4bfb5d6da5ab3b5d65a8bc9b7d65e5aa9b5d65a7b456badb5d65a6b3d6bedb7b364684fafcb5e9775a8ebfa4368fffb41d0aef5a2eabdf782f7de7befe675f7d68c3bee5e226cadde7be79c2048543f08c869bdb7de5a6bad76c35d9e5d9e9823efbd97db26b74d8a290e71daa8b372b7dedfeebd3af587ca9c73cea04aaf7fd0aedb7b76ab7bb31f04590fdf6badddbe8fdb3008125dfbd9fba6cd41699dd40eea9b14476a47c5d393da51599e7b6f8f4f55f1f4f46c9e9d3d3fb5afcfadd5faf60189eefb7cb527fc6ab5f75a8b83c577efd517e8de163e55bc66399cbb0704614363f2e14ad5d6cefb7418c0c109b0b64934101f600eaa2a1929c551ca41699d8fc90829d0493d06a6902b391425264a2328cd5a5532528aa394da5165150f16cab55aad2664b2e867803a95f089762578c6d9743472a7692384c27b7cd8b051a9787eec1552850c096148085a488e1a9bb0874d0f143d60abd5f3c3a27ab9f3bacc429c17bc601ab88ac87fd808a9d56a405688650394f2daaa039ebbbb7b0577d8bb836ece49575d5544f6c694bd70baaefcd448b5f6de6de3a6e83ababbb5eeeeeeeebe7118679c73477d568cf3e79e73eebacef3be1a443be89c9808ccc9b19bee54965277cff33ecfc999f6fb9ca26a543b83b46a72dbe501411d46a374ddf56da523ce41a1505a6b9d21a21c3b7cdf0853a9d40e49546307dd2110dd2a1e90082889ae63a9bdd65a6badb5d65a6badb5d65a6bad7574f7fc5d1e8968c085abd6eed5bdbabb57f7eaaea3a3934aa5767676542a1511518f4f1895554e1e4a1d746010310407b90811471fde7f4e854dfa449f6a94299bc640a21ac3a2c1112f81c928c42177538de85315aa5b6a14c7a0569916d047a2f5cba68fc2941acb5386e90b3124697dfea49422a184e6508ae4068922d66ceab02f94525a4413344529a54eec1d4a2b0e4478e0043e74608511580e6cfaaaaeebba9f212165776fbbaeeb2a120f605ea0bd5cf9f1e440a2bce9edc3ed081cf6f6b38aed618448a20ad9cb8531fe376208a618bbac6184525396a61a0864455071c66e7f99d43cc984465f950f46cc0050c43d7387b8730aa625fbbebd976969df2150d8778811ec4b44d2bedf3af364df1fd27106cdbecf030d07f645d3b46f1a12f64dd3b46f115e5eba0a5da6cb2484d3ae2f5ebabc340dc6defd68632c44d3bb80440a2e4079c900b36d70e802b6865440a4400041800922ceb68fdbdcb80104961940f0b06d8e7d69afd76bcacd21892b650389364bc6daa06d6bb0586d34e55463ade5b66ff9d93f6ccb83990e98e101cbb64ff200c5b6df1a62b2edeb506261dbe721dbf67d70a01467db0fd203d3b6df8107b69df960c5b61fc20f4c2f2db0a23073b634c3b63320901cddb9b570a40993315a509064042c2cd828a4783c4ba66bdb33d8be3b3051e605ca832e75ebc60e4580a006aa103ec6586bad7fcc9a272d2c86e2e9c598374d80546113b226949a6072118e8953b452d3444d143557d46c69f1b22725b050856e62405816bbf23302a3950ce94aa8e689858ca9c86789a61f198d4acf12b05076022a3c163bb1e4041a27d4f8844e4e5025e1d44326cbbdf75e36489435c59459fac1060d0f48c491648e8a52aa906644eb423ba2acb9552119d9131dda0e19214cd03fa0e89222a326ca1346984ccd494e125d34193831d06210348180a6759862429b241d567852c44b87189ca461d241c624044cf88726b8a933a20967c491114959ebd044d1e606ebf006ca9dd8e2354a3fd630717a87244eac2a8c628a1f51584159739758ef1025ca089c76e80213c10e47454d453bc8a614a114bef036806025a9e0c3942f58b4dd7336850c8c351aef399b3233010833539a76a99f86294db08af4ef399b52c5192a55c2300446e0cffc16e4a19c4b3ff3d72f73e89f96b2c0df11756c624bac6298432bea5c50ce337bea7c39d3f89773884e447d8ef8bd8b3954ec6ce888e564431ff42270a744d47ba2fe1cd17b1d31e7679b0d72306d80ef2dd9d068a858ce1e76a9cb09c410bbd47ba6d99a875c3b3aa2426a9ee7c9947833a8cc479b7b8ffb12dc9c36f7a56a03c1dd9a6cee37cf0a4a72db6b73af83b2d8a5dd774baa4275ac5b52cd3f9f6e4dd306f7155ca14b2e4efe42716cb5fbdc7369e615b93493c5855c9c79c1b46eaa0836c7856073f768ab2579e8ddc7cf81fd5c57f46f5265713f5dd8c73d72e12d147719b11125b91f63dac77293825ff7a80ae1e7c27ba4b967818db82ed8c7d78fce09bd7db9955b93d1e67eab71b5cd4dee5dd034978f9ce2ce6883ef91b5770a4121d0f2a042add6745971ba3c178f0e9a73ce39e755b5bf01f9f4ed58040c10f2e9577b7f0392fc4b7e9109ae7ed8afbf01f9f48afef68fb8aab8ca9ff30884becd39e7d7599c5b67189651127c2ae2a2ca0261c4788d9594d0df971c6c73471c8c039f2ba238ba073f3f75af0d76b00d96dd1a8a83e7c1cf4e1487eac1cf6d288e9d073fd7288ed4839fc1cf4854686baa2c30a8829e9f3497d96036aa4239ccb1581592f1e0734719e87111e61e7c0c23638ce573628ee12d542897a12cf08fd0a08131967329682c679959a682b1cc91e3c68d5d724fe44ff0c7aae7ef1f71ad7a80d4bf2311303d4f64044289904fff882bc7385865818fc7b1c45a1c4b1dfe58862fc6f2398e5659e0932ec6926c31963fae46163fe1586a9fb1958f36f89e7f3c222e8395f01266c26828093ef9d365c5551e2fe043c6a7385815c2f8e9712dc44e1ad3b00c912345fcaa2cf0afc81d7134b0e48eb8a3a31cd59554361a734c2cf118d3250e017e55a1eda8b2c0bf9ffa9e3127bf6e4ca1679b0cb41da58e8e36f8d3458ad3c523e63594045f2566274a82bf23e636b94649f075c43c0525c1e76855686be26038d35e18a68b3608eb621b7cd8069f3baa421989b2c0cf6a9ad0fc52584667311b3cda60ce98c71fd4254397d1dc13f75431e69e9e36f89efd5a059817cc0d3e90fcd2d9bfecdeeb44164c3ae7c11e3963d206df836ec494fcde52f27b1dd43352ceb10450d71d73acb2c0ef9cd0b3ccb1a6a6a6a60d7eab0a3960b2c007a3d8e0e7b8a0e94ec494ec5e8b9692dda3c41c31487e308319043b2316748506fc493e08165901195b3f8b606e95df77fe551ea7cbe6d873a2714adbe8a82c1087f7f33d2cd6dfc0f74c4524603cbfe713ecc6361c5416f818fc2c967a83ba07fd3d8ce679b40dbe3375e07b97fc20cd20cd20cd60fef2c17798831a0cc1f73e1104c1ff3eaf29e1cda0922bbaad2ae4faf7a2269f2d5ed0dd779e534ed90f77d1a78f7a1df451e07ba223117d54163864dbdfe8304a823f4170aa9ad0df7bcfbd40eeb5c1df68756eb40dfe26ab186fb20dbe0b9a2e72a3ca025d1ca1ed57071feb2ab43df8215985eea3c632c49b2be262568d7eeb256cfa7acd765a43700cfc0625c329f404260620e00d42d8c107f3821bf49dd20c5c844d472edbdb0ea60dbf42039feca8c48c9a6962e9d08c00004010002316002020100a87c442911c87f24c14dd0314800d65823e665c401f88435192c34008628c21c4004280310418620c62caaa0ce82a27d81a1ac6c4d01061b5d9edcef91f453135597b57896b298b5c3fed1607cb8201197f8f5f0b436057a8d99f0bf9df4b0982c9d8a91fb0b66e869a4f43fa1ddd75ec69db3caf7c264881990dc6a65fcde8b6eb2fd58728b77d373a70d78b6ab8db30c1258e45eaa8e9bf1378e20dd0f39bce6dc57d9ee720f1fd0bf4ec72b18683abeb89f8ecbbde6857bfd033626cd43430c9911a89c73558d1ade1cc59ecade19f68984a28de704b00c86e1033c924462667a000997ad9e6656fff6e3aa9e4c3221c21951df47598f989bfb3a747f91fdfadc6fb8a6910d74f90fdc7cb2040a317413834047e19b9d105e45e54c75b7a7c8de76a4a3cb8b2b970206acbcca66c79930d6e481c8615bfce2dec4810865abf6c19f6a0c1c2a98c2f23c3bacbca2dcf7f44cf630c6ec94b5026011c8f8f599dfcac8e5c73b2d5dd7c505ab97fb19c9ee6409494fa22491750fde0fd9467f535c948f53a394e0a3fb5a51439a474a43ffe0da2f0fb6225beeae4d2bf425289b3d7d24d1411cd89049d38e1905cb5c1f58c5a7282a2aebb4b01a7f3cfcf1e91334257e1c78ba5ef2af4f6591ce6e3da3c315dd24bef1d6226f74ba6169fd7c5f7107c2e78bd0bcdf326af270dc269fa5692034440a399b139884ea4386b2e6f1818c921af102f9a4d4776d6e1dacb78121feb114e2da06156ece0b1294d364a6f9a945644790f06d10b189394897602912627164d109876a7d104b94a02d963b04c98adfe403829338635d40289c7bf7ec49b1885578e65310819420c4340b0223899f025f244a068b79d492266c9fcff60100068c9cf3b66322c9a0e59f6c641e7810e1f95b821c769ddc56ee1acf5984945cb94453feeafde9aceda418d5068c6ddd8431a9b2431330886538fb0b5f29e2cfb904739c92981f50ba5a8a09900e1cbf7ce45b53a3412d2199c79f3d73279ce7bf8c76555c28536b3115e28e1cf42d426884fdfa5657aa83f4506f8f2c20a335085c96c98e8c841e481cdc5f8e789bce4f5fed95e47bb40a8f0d98c2bb2805ee504f04ea7f02d6119965c5fda975c2f4f89a25a6b61b4201ea3aaa0a9a9f0ebb8dcf3e12b9c10b0b18ed82b3cbd7e99bd98d85ffcc22551f2a8ddb51e579d1c2839cee2b99994c7ff68af798c5550d55ebe53f2fd9c7cd7fafe95ef8b372883c2fd75f738a45ae9d2835979ec2e8472f86e2e9dc91b3027eb487aaf74b275c9bb45fd7fb93b914fc20c0163e2556e6820d3e87f737c6b4167f9950cd460687eaeefb159345275223f0d26ebc0348d4feccdb3c955e74251d4956a1198835f2549e842e1725db120c2984255cb18ae10a0ab8cacc0ecdedfc96e82e6954497942952d6861f9b4d9927fbbd06b62bae756af2d71b39b2891f5676abde8076e883d075b9e6df8bcb3856d6e558bfae510b77bbe76aba13ebbe1c8ea3c63af59f36c84d316917d238164dedec159226a108c8ba947c9c62a0c03014eb9c8d509ffa5bc05e41607c6c1dd535b1a1aefd55f6db9f96d7a3b4266d2eb39f69bc491c6705170635417c76f54703283816e6819c50faf07ce909da0355d728e3cee04d1a8a8918516c52d4e508ab22291c139e499378066fa2098da96ecea3b20d632bee696da3f856c7114bc00c7c795d6c50aea4a5f77c8e8668e51dd5269c2ef02b1c48dd6419f6cbbce964b8875173e27282c87f2e351353154d91a39bf7f803d6d3d51d912d98309669d2010b52e5839308a2069b02be7d3627223b48889c6cb50d6cfe56f7bba647e6faeee75aa747dae0c3b80d82a1b20897a22569a1aee7de6dec850fe285470d4650fd7ed5bff265cf56e3e0b7aa584af25fbca77bc576d8f8e320a50a595325a07b4a7cc9fe66bbf2e1dfc3683c6a8f769f2645cf49f1961276f04f5a9bc0cb9380747d1075107a28e7a5b6d071242cab1cb1e0ea9e3f70a6e4bbeba8fce40b75d97b52356f987ab24fa187d438aa92fc23803271ffe4d658dd7f9d4b4fdc4ccb8e39ef21b13ac9f116ea22bf08059a1029821fbea8ce91694f634fe3e20670d28b1805ac5bad5c52de942e18e92dd1950384b594cf9ee9db5fda8399a017dc3204bd8ca37c8f9393edebcd9fd887d35a00d06b25c7481116d85c65c45232f6495ad569fb53fd2efa112bea7534b0cb2d399b4caee03b8d601c6618d213f97632f991829a2d23a0e988a01184ada7b7d6a20ab748f24b75b7acc32c90d74eae950073858dab1ae2a47d95f83d02dd2e42ba19c89c073e8394857ff25a567ae5be5d255ebee0367125100a3d1895a5c4794c0679555eaf33c0f7fc85480836be9d8a913631f4c1fcd008e5d0d9df2ebc2d77959d0417b9eb31165b5bea1430194084028e88c6f2955dc9b9bf641c3a6a718d1c0ae442a5378d747440564a055d57a5e6b40dbd02471728212291f7bcaf2a6ccce8b9c4c47b03330427cdf29f9263bdc8cf8021c8cce00b28bdbf0af40bd2d25e6b0476e5eb662ee0ef846570cfd469589934a62d5cb8eb8ead95dd475c37147410608873b81452f58247c2bf07c80f241789faf967072df51961e9fc4b31927fa71ce272e5c8be516e761f8754f05d74b9bc8074ff31ac4eaf56e8985bdbd9640b994fef6feba9e81defd161185527321d3ea19f3cf19275ea7135a42da5955200b2a990c4d2e6625f8cb513ba220f1d67fd3fe90b28eda00bdba9fa161133374b3d69d9663794b9d60e423bb4f92222e3c011f1367d71055c4f9e49f007cd48ef0c6b59517c8d34f9cc2895bae29adca51953b4d75035c7e7b437a5619d2e369b310823f197b2411afae924ac4111d40eeab670594b05482e41417a181c89128e3595a6d09c0db69a6f9d5693a3fa789ae4c1265e64768fb4ba30d5f41b7e896c5857a57722bb24c2dc61bd42f36f78b5d972703c07644f72c2b0486cdbf9042177938bd4194fc2564851ce6342ad4d864df71fcc4d3c6755480c9a1ae1eff08b461d3404ab9a28d109975dd48eb47b23a73dc73228d20e0d6981777c23b0be501a1084d4f5cca8b54773e8c85fd612003940f499e88862c0e7e0b4bcf235a960fc5e925701b59e568474ba462a9ba301524dfe5bfea76bf83959878a77611885cb2265578cefea64cc9a2456ff9436bb136ffc38633df479f5325a5bd0587342436c0a3ac35da5f019d2f536810e36076dc04219cfb3ba8fd1fb3987d7c4782e7440bdb1b8eff106a67e52948bba04147c8cf4191cee1aec8d2df88cefc3ff8cbf5b353e4566453b35be6d199fbe7d073f90b35a7833bebb682133595a7c04631904f560f184f8b8240c30dd5a0e449e2db9cb5127c5a7ac0f1a70f57da79237af81cd81088e977d097e61138949481a1137b4de92edf28df8bb787c9102ce7befce19e382e5b761ad2d03d3b71b0887c05029fc4f7497ee6aef1cfb1ec7172feb4fa09eff82041ef92c32ec5de519defc68c2736e9c3edeee16bd2f794eebb42bf65dea99b110037f29017aafdcd7d91d036569bf32e00d8b7da8925ad6fe4eb49316fed23372c42983cae806b82a4f7cc58597a8f01fa84db9aefd1e48f975b892764ad8b1c3a7a9fcc9a27aece21e5883c40bbe52821d8c02b40981d6b65fefd7922ab78966632ebbfa852d3d724b27093a6b47824b0a6b0d88d2fadff1f5901abc0959139faf3fe39d1873be45e5fcb7ed134990172dedcad8e998158b2bbb5327e5a404d95953e1f51ecac2561767e18e45e2d0aae56a8c471d7aa7140f8086112591d9cce551e38f0ebd2fcee6ca0cf604986e4d1e98527302a132d103a27077a31d525c88986c67cf4a82ebf0bec430cc8f1ffe8f92a88c69672cc364ea2b5ae017ba9d74188f0c75acf22dea894fc5a1cdbcfd916491f296fa19c755201e98a3a190cc5ea987afaf44006da82152eac9ca23e503729f814944a78a604891d0a8d0729dcfafb6d58e98603c8bc8eed584fe24c37ad1b7c09658f982fb7cc585f4f8e7e637b3be7c20dc89702920252588efbbbb8bc3537f892a44958ce2719a15f1a5ee67e5b42068d8efbc16bebe6dc98000aeeb5cc297310fb464df60bbd49aa5265cc59c4134a009487c1c97aa94f53c318170df2f91110acbc96d6a289bf75376ea0ec600c3e52c5cab8c0743e878335034ec53ea79c790e617ed5ca5c6066885f1ec090f3255dee96b256f02e8f7d36fb9c1a476cdbfc23e3d68d2a31ab99fd207e6c60e5a74b6cadfcee3072e9a551c4118f3e28faf0be5bdebae8015ca5a829732ad95e599a9348ed881a992c356381a5b5f0df5aab843e029e0f24ef7e5b5861a0291b8d5a124feabd0d0c8591c19ccf10578d813cd4809e55b18f625f879221052f514ea5629ae02e7e80ff21f9e0f680cfd0aff1d1b821be69b73d9a34fc08cf43260813c0ff7a646541136e4394c5c584ee40feb07ec8f1def6592c9b624f73e47dd7542ead4b43b22b47c40ec1b8243ce508114229a823c2d9a8c8679a0c7133a05be73b83765153decb64c12d25895ede4ff315904d593edac9a0bfe41d5d958ca9c999c775e619e2af9d6acb34d2c7f521e11ebef4dcae296c28e304d14410664e6cc9ae8edd0bc5eb6d2c68114745428a0c29a69a5f0546b2d3d2caff559c304e074f7e5c6727ec59edd35216adbd139e32bb199d5837ed303550a2b5cb739ba2f977aeb92a304c20481c9b834e5a2bfc25bb7d9e547f640821ba1a82c5526abb8014898b0b5d051d9cb5f28a445e19b3a2dd950c01204f1c7669ae2131694420c44ed42cbfae04978fa5c57548acc773861715ab9c7f047d72420fa8adde633d1156d5497a5329dd6da7c2b340897cc030917c67c974e145fe28b04d0fa082f6270fcd7443a1dc948c9c297f66b40da218fa736c8e30d469189d5fc6675bfc5f9b5aeb027c3dfbe5df94c11f74226ba670c628ede39fc2e76321503e2a61a02915b098f6ed2584d053360e58a7a6a9c24cf8b7704ed642d943cbc97d07a992a1f5ecaebc20401e7a0203729716ba6b31ce7ebe75c618f998644fd9a890b581586d596240c7626a19eaf11c116e401875c37f5c7d880b10f92237f941e269710c77c07a5acc91de1e4728c5c4d89f07a235634e62f219f18efb3616102006a12c9f03cfadba5514d5a52ee8ef3e3bbde7c2c413a2146ce87e934659d4504f71b763f423ae176e6af2a606a6170f834f82346d632448cda60f28f874541cce70ef4136548a07498c113394e64a250902b398edb23d3a2aa588830149328f483ac398405be16f72fa02b0c214c2d2564c4f7338899174d7277ab2e2e81cb2aabb7624ba23bcdccb7adf73836718044eb753229d835c634dd9e04f1ed9c1623006d9359f2159fcffe3e4f5acbfe2e0f4a815a080ad0735a752a6b2d7b378c6ebbb439450d7d475eaba29ee3a90314475edc8248f814f88aa0701cfda12108a323942e5ffc5446ab97457776a384d1e7073b85d9e8717a91b9ddc1298f4221817d378a7f2f0ab05d3dfafdcacf15462448839c82a2020495d44204bc49a8fbff7f19000d8393c670b92f5e28f051a6fd336f00651d094e25b23325c330a803c32d013db104b79129954d725bc94b807d5cac913c61b84696ce5574615d9d5f6b5ee87ef037c3ae921a7477cfffb77e9e76986055f79479bf16e1c572bc58ae94842233149a8845a279ba6c67a8e6fd357c1cc47baa6257fbf55bea7c025873bdc1ab3374a3ec4df449837d3e841ce9a90055f78f5c05e9f5217e1437c09c05135d35e3da575ea1c2ff3f90c11cd0816a01ef9790c159b19dad415457589181ae8b42bc4c9235981e0d61ef29e3ddd9747826c5f97aecb0063e132857176e11030b302c1d3ffde49776f3082c3d30f3ebb62ffa322861e5a88b238c78d965621ce69d1dbfb1a5462893067f99452f2cebb646401be4550fca1e268fac4efdc31b1f9876d55bb6f6dbfdeefa8428cd0bf3a71e3ec12ca2d341395aff4e314650fe31dae67184ed130bf2417a7a1cd577cd71b3c796e75a0fd6ce479565d2f24cc1ce97aa276b2b9381644c5bbba4168c7f81147e60d5f0874ad8409424d7db856373147d036c6b2eba5c3a042d146cfacb30ec4663701fd2a437f2f8d155f3b8cac7947f0b226d3e25891cc7a5f2f7815e9ee68245c23ab9ad76683f27532dfef21efeb63b4288e29d8365011a4335e2385aebb80d558e598400ab5be7e43cd49d1be351aff492523477b50c6fcfedc8092456d50e2aa89245a932feef1c48415f849ec4259165bcb2e7e2b3ad2782b9998ad1a8f4eb0e1f2a959a2634d643e5ab4b0bf48136b810d205173c7799a3ce7b4319821926feb0c756d78f8486ffc99c46ee5756e4fdbbf15c894814c98a1d5346e95875166b22bfc010c74936f74dee4a177b3fe1402f60540d13c36700a8b44f7fab7e4106601b1f9e70a03c7b262ad83a9f9516a01e7c7f9b4ea9b7871970f8c35e35f08387770dc88e32bd6ec2ba924b91af8830fd36a33d0837be85db1113766167f79bbe241969656f848299f88218757d2509141648a25db98bab04bfe79e5543ffaa492f823fdf4adff6369b37bb93f6a607d73e534dea327536dbd957edbf298da5d7d9afedd156f54f96fe52eea7e407536053cf7129c1e982b8eab2538206b3e0ee40f81582cd970efd5644fad9cf72a46be60c6f537f10a6f688ff4a152227c333d81bda8244522ed828692b3362e1e1489da72b95e14c402478922307856c981ce5cca51772a8712f661d441d5126f9d7cc9b5d821395c7cccc1774633c06a7874c1227bbe284b8a0695582c685817749f7219364335e07068e9264512fb0ea7156be482e076aab1ff85b059a16a99732343d0c3f01b56b381724dbde96093f716025f098329b9dd7449f02d00a1cbaf7582f49e89a2c6347477834cc210947bc3bf93adf364c0e52b95a1c2fad7d8d46345a87b2d83e0b0c2ac7e6817bf6befb6f4552c4356f3ce9bab94e91c835c372da1abdb896fd86e1587567f86506b25ff1cc8137402724630d1a6e6795f0b0b5fd4c94b9a31a81a40913a5d5251b0a82f77c0dbf6f4375eed7e34d7499c9d65fc75fcdd5f839678c6918b015882cb57c4c74d030fd5e06c60661c23b3cb3e30aaee8bb3c66948f776a705da9db7dc6c89728a0716a7058c7ae127dee1c63d95b75324ab28f68ade867531222cbfbbbc7426fa6b245e29c0ce08c05cac466e8d6067f216604e72bc4d0319c93c69282a8325ee3973d5a56ff521dc0a62e33379ed36108e069c38247f2b42b3a1edae6fc9bb45f2648a3557e4280ff6b9209ab9c60821233e81312b5f372fe9de589d205a773c8043d33c16f8ef38462ed9c434624c213aacda13eaf674c20d75d712b4e992fbb2b3188ec9776a319147de8dae1b8140c1f7dad7d16869105dad409a0dd0ca53244bcccb90a397302fd208d6fc4decf8a9c147a7fa33800f5de467238164ea008916557b9a8f8a19c00bddf4aea3cb139f5f0743a83641b764917b8fa07d047d83609ebcbcc9ccdd4f3a4677b7e7acc37467afab81def59a09b8960694d199d0b62debb85613acab89ee5859b41e6f6eb891fce67b290289c0b33419841a70978da9e711a023a9da6941d5122660c84844ebb2b087c8eef95eb0e0ce5a8a1b9494f16e57d05c1e3a0fe13730f9c9fd6e026d1e4e5b68870ad0f832f5b8d42a691bc36db8f459f36c84bcbade7d19d89fecda504c6e64ca2ab9c710456130918899ea439ffdfd4728e2593fc80354cac56a517c6d0010ac764dd6818380ced161d6a89fee0ed9afe545dd749b6006ca89220c69f8f39daf7bde019eac750a129e1612de1c5b8b6da9e438898d667645789e12cfffb0dc5a1759c98fc5b02b387f833aa559310f062db5adc550a04de4ad05e7ebe46c7544d822dafdfb8782273c8a95c0a707babe9438f76fe5ab46335979328f0bf3cae9b4757b7f3ae364efcfd06a83122f0e81bd71a0cc22ed62e9614124125af12cefaef02cd343550b8860c38fb8ad0cd2d5f7029c1180c00007cec855a43d54abddb4ca207660846fcbf12cc9834c97b2318e2706fbb8e75c9efd4a124f2608bce7b5172e7dee2b8dd24d9cf1717a505051eb659b7ac3b0ec6990e77e3411ec89a86d7c106b21373d4f5ec6aa034e24f29f9b40a1575932636256fe1c2007a5a95db515d54f2351db807713e3ab3e81f29a723348b6e0a1cbd158d36a676f3c5da9f85ba3094f7bd70dbc2f824f4640bf6f4b210923f64c061ff99447daa9fab2d10cc8eac73d8cb2a398670bda1eee8234f747aa1650d2657da29ff8ddbb3ab44ca2bf9097bcfa1138391a68482f49b86cf19f345f81916a819ca3b504ecf853840ae4d56599edd4cfe61095c9bd03b69c75921c6f4009d04da38357c226212467928af5885c8aae60b3ee956e7f96046165fcc7196b2667d276980c4f8c51c143685fac6243829f00e7c90e63a59fd993261a1ded0b202e58c4c076be600272a364d229c1c9139b3426271fa5d889eb6522142d589a0420323c1e53559b27e161d9fe67d28ca80855b3debc04c6c906072584ff6c051f6c4e997c74838fb9d157e725d55ef61ab258aac8a18d1042a5cce74833b4e1151d3ecb39d9aa6db8a0dea13bda5854d8196b41c2b61cb0ab2c1d673d280615e84e2311557d97e542a09b359beabbfc494d45b810e82761c3c049487cfc648b7a9bc27c42e68fe89f2e23f3e28e4958e3083356b54fc04d1e5d70fbf034e0db313192aa688bf60defaa81a0889793e68daad33179b924af7ede6fb6f97d6a51b018e3af64dd9aff4879816b728e800f3acd2f2ef99feb4fa6f9860be97b95e9b9efed7ca5d0d3594ff73ae50f64bff6036a92be0c1097e08c24d1525bb1f1047e60946366840bc0c559c0c47716a2c79dfd095fbb35f54a57d0f2822777bc5a6e6783981ce89a55999814a31b83a05ef1f54f99910a78fdb2202088a369fecf5209531f46acb16648c03232b24b9e0245266e3d9d08268a59c394f58acc75b5a47fb5088b5f8b3d5a9602b4d6040a999a29864a860a4cdf84b6c3d26499c6ed6e2f71a74d1a7370a1057a65d25fa7bd34120cce69e954d4f7ed3b510d6c3f6e99fd4d24509bc9ab57929b742609acf035507574b0f619a431dba47ab9b9a61cb8b09f79c694c392ea1bc3271042e2c835aaf211dc2798c58ebbe15fc4b66be58859b631949c78cb0c22b42aba140d28a50dc5c55a8fa56705028dc1c044576a9546c45ecae16666dd4a4c8d28937d66d89d54a5fe386d07c18e924ddf712dd59f4563434b14bc406def999c7e9358ffdba647b9420f4e3191ca553327665ee7f68b0f6525774899f1fc840a49f5de96a5775990a1f9c7caca4e6c55e4af053c36b95a597f5c6a262c44ba364a551f21dc6d275ec05cf7a7b95d24ee44a02627283ed6e3e28202bb5c70d86bc83a7d8f32e2d15be65d53926eb1ac2031b0ff2c860f0ed23dce8ef2dbdcc3d588fade57de8514b067c257800fd300fd1e51f3ad58691b4d0bcbb549600970cdddda5acbbecdcc277e8f01bdf693869a4234b9a6cd216812172d705c8b69a73dc97c31ba0635f8d0811ba7b118b9aa855dc0584a02d2e5941ec1b749750255b3a9bd418ac5117c0c2f4e3b52f4092dc915ecf99af53d2aaddb94ba2d41b3bacf405d47bf7886fd3b5b0c5cc0582700453fb0a906e214cd35247840a12f344939f78e7ca5adc366d90088c01223f66be5110460cbe00f1e84a9128436c299f045500ecfee680d69fe14b27cd3418b273001b43cb65b4daac709bd4b4aea000e3ca8aaf95e8f60fae327734d716aa8d80930aec558bcc424bd2030cbfbd3707de433ba43c6122c014d63e052c08d0118f14980b576591afbc204ba19b80dc5d047fa7f7a3ff92e8df5da75460d85d2282bc0840f9b9f78f043fffcd317206558920c8f5295d520d88779f75436c0171eab692af86fa0ddc7744fe435522cca42fbfd081fea78fd7f6b984222219da97851bcec481d7845ce2f55f1c33bf6ed7517d949e698221c74a21d3728b3748a1f7ef0a3bb1cc917e656b37b2f55bf3061983a21d25889e4ec34a8784f6af12ae3d909eec0d58f730c2ce008d5d5f72eb9427eebd4423c0c8b61a725bc0f9a121b5b3a73c551f71bc72fa0cc90d2a21713052277e2eba3b5c253a8eda809aa671964a7426afdcad8e76005b37d918ab051f27dd13faf625cc0686923c385d7fc1408aec4fb0edd4a9db18c3d1b1023c818597fe145a0be2fc2d1e77be16de7bdd51e1ec88d2b0d859f3a9a1b85d51cbeb90c3961dfdba70952ba444ffaec9c233604976c382678fdadae4a0bae5b971fd85f5c6c6f38a1d56db282ebe3ef698c7e44b47212b48159a00c102e4165aca1e4ba0f781068753f56835cf8eeb97c578a92d0c020c2df5d9d29c532814b7e66c02d5d5ed9201c07843c4d8df519ccebcf0fa05b091b7b60a1884bebc103bae7a71251632517c153f982862cd855b904f70108efc6951b7cac2855c2bdf3a0658552a3f4336f473ca5bd12088fa3becbc8f05c1189d01012faafe0471c262f1af7382ed398134c41ea6a16958a786677efeddc8b77240862b30d07af6ade53dad1adb8d01fac102ae29db97e1d6357926311ee8a712f5b7f23d4353790a988357e13dcc119c5d9eae3d6696cf81ae24748401fa270dc3d6c5280c4403eec3d35125e8a8d3154f84a04d6751e00788a62af714ce12244a61ae16e8779fb231a014c71005fb58df9fb37cd0a916f49fae00ba77641461967b2b493babbf9a9d544d66dea97c3015f2cf04cc93c8dc239557d8503a3824878c788da8f7196781894b402fd8e2d89d30dee8a13eea62bc8bc843193e519dd70627b56a10a09372ca7a609d589c31e755900b0e11033a624200deacd23d58d5a261dcd289b5fec7714cc15907b986fffc9f48ffdc041b6707fe507a3b91d9cd15d74176e6963e2caaf777e0555c0f22c0747b275eadcc03560548278bb0d6ffdf9ed91624299f8f070246267dfc85eb161c05f6cbd9445c2fe0e17e2bf3425050ef35ba3cc0d74a55fe8d73b52feac3fe2106c18b0a8bbf02b207170cc541b61b829e8b958897ec7caab7dc79a17a886b5c2d0b27f69c29f458c6c64e24fc87ed1eeddee1b0ad699ae2fb6f79c664fbd7fa7bc9fe62077c1b5a20289650fb9fb9427790cb786720234980d00a435a097d1b7709e40f0e33b6180f2c56fd3eee3c7ab131772f57afc39e9d735edef9b9ee0d1ab9519fff1e7f6b24f685f8ed0ac01f199585590588babfcf077a6dd39c7b37ed85da08c9a4d42ec6112877cd25e793a398b763075bd44cd6aeb8a6d040612a5c7197da9221a1fad69d837c84b8d08fffecd18799f13383375fad267803dccdc461f53c2f255b9bfa28227f182224abdb06c128548006d3ccb0442d88ee898f13fa88fff7edbced3f26c8ccd568afdb6e481c9af5b21e4e11f79abe4da39c4ccb8961891f5492e5fbf0fb81f8df23f9fb3709714e4fe55b218cd035e6cd0371a5344e4ceba07f3404e20f6a0dfcfd232202345a7bc185cda2331b4e6f38f18db2b1ee94514234d9a4a412911a383a3149400793b7d64e4d511ceec5899d5b7d483185f47ffab1f1ccc61f70165c0f68e842e60eef4014fcb0bcaf6870bb9258804b4a2179b8f372818e90ea2cc5dd208031583ae89fe3e012c818ccc361b26e7a6a67643d47d7a06788f04383c665a7d71e424d22f206a7ddbe0e06169dd0e9c900ac2edb6fd67da36ace681ad3dedaa02b6f7306816e22891715ef946ca29b12a6a2f6a43b1684697740a0ca56261073dc15941cf8cefcd7760ed44d676eb9f6590d52a7a6ee80814fc43593a492d39cc9e6e80e9f85fba34751ab426703d33dc85ec262c751ca69326e6d4104192fd9280a1982f32af1bc0f43201a773374788be3f39d12ec031e11b7008733521a20f15f38e87b0be1ce2394f568bac2b3aef576a8b641267ac81f41506af7bdadb5a75ff18dd1c801b84128f733284e4ab2b7db5601eeb191b98ce5a23107cd0c7a01500f194df7c2627fc52a2b73fc2d955d66e14e6560e88447587054b8ba6dcea50fd3ecfd184388f7c6a960569cd2a4da0be53568e41a72a6e7645e1e6c435ff92804e925857e9f06622170510743db2afde1a329dd0953f27f5344afcde33181b6f010adc49c8710961b92dfa7cd2f55f2b0781808638e209c4c5cf5aaf94166fb1824bdb3c956444aa32379b79743b438972941aa811a527378863190c31bad24304fa9e4059e8afc284b980587683a8f14628b0711709aba9cc5af570870e22e45d3e84beddbcfc382d864324d9eb0409558bd437ca2219ade60228ba6b4b4ad13bc4de71568e492f8ee78f4b8ed1e2228bfb20e17920d8924446efa5e1a4f5c343ea31e9c0db8870fad37e4a1dc86f1618aac9a91a103d4f17bf8baf70a1ee61672b3faca04535b49093a155e38361cf78521dac54b70575ea75915667da5acf9e7ed2a453b015125aad9a8679137e696c4c947beaef0e6e84fab616ef04d8b0549e835aac8ebd9c76dd01dcf1024f2fe320a171f318be32efbda1c7582048bff3ec7196799b5b76d8f97df001e7cf9ab8bd33bd45bcfb73e6ec840bff3abb3979e4d2012ee291e3bca107030f2ad2043f0601ab1ff1be9c7654bca225b14730f6792d315542c73aead0c78bbe4433758363a00dbb3418007195bc1707b0bbb00861909a70cf1d5f3e51ae57bd428e793b071c1bb1240a7e3999ca9e9f57eec805de1c6d99dccf0a345e8c1e26780f32be0f849a3390619a89222be8219617044219a5e20f6c99c2024ace24db1f5b1c10a597fe6583de0d2657ad9024e0c14a2757f0ccda2329a077313a60aa4707da658e6abaed10fe94b078c625cac3c0e75b1be553179c424866f6e8a86e924f6c365abb22f4bd80d0b52d774ad757c231fe5e461f46312f310a37534873ba75162f6febf89aeb0ee1304bcd2f63284d9ed04417df1f9b5785b39b317c565096a7318abb0da0e264e77f2a28b41093569cea1a7b6001e557a9f540a3f26b094a110d0b94687924fd1dda3ab59a3c0138beb014a2ce2a39e3a88d69d98ac567cf394e31205bbfd3a7b406a928adcc6a604f19a30c1b06dc464d514f68029c2c7296a10ad178e9caa7e3202f2b58e3488a643e67b505017df4d11b81647b126653963c701e645cc112bf9015789b4ad71e6eb450e30a957ca0bc1cc935682503a6d51c79a933fc8c11ba37a1ee0941236093081394ad414e3bac384846cb7a72cf9b92e4e102b6fcaa288de03ca052c1aba40282f219f41b43b95d643d2cf0c2c5cfdb704b3208408f3fa3b50332e06d16ef4444bda02edb258ccf0cb8577824c6537389b8c4d0db14aec3299b84ba2165ff4bc4a6b98efe2ea6a38bc84b31f6b3194816b6bf93fa543a2711504cfc41b1c165641e77a718f310967289107bc231444d3c921540aee9b7ac8e3e9aca9b72ec18c266812a69834141bb9c70b4c99d911961e7ad05e7f28085839026f4f780f808fa168b9e236638584209aaecdb0eda555debbf4253825fb0bc3cc63502dc854cbf4341b9fcde7f2faf67070ea4b4b017ff10a8f45052e50d416b58a5303fc6c74556936682952093f31f119ae24bc07e7ddf3a6c2d591a85d96a0fee331cf5ab0ee6e9a30abbd45814d9790cca5fda88f586fa09568205a7ce078d04c46356dc96865a1a15c3cc279794593521988d615582e0c3940a9dc9f37927f0fcdd1aaae0960d36df722dfcfb02ee7ae0485231ae9af86801ce4a7e35f3d3c6b668218668eea9419d2581f1e52a3bab9aa42680e4b8ce2f06a98d7cd92b42ab46410e58d2443064c60e81200b38016aac53148acfc9ba6a9272c8fec5d3e852d0af0eacd018582a007be737edf271901d1ae642f903e319af0ac8eaab754e55de24a56b338ef2fea6a20af7e808ada3c78eff9ab3193f11a4a138078c66531b0053b691b7c939357bf3bd7373e9bb316934e6f00d13a0e488ff57a4a3f68da70e302ac956ab45028908d716a3b98bde9e9444f4a13241afdc42a457cfaf7e4f00be92e45b5864d6785102881d525fcef67c7d7348eb8a0da8e415f6f22cfa9e398cff8780d12af751a08ea5ffb8dfe8e747f2d6b883347f8fc3c7a29b2d9b66a59f3d3a8cb3649456bc206d5e301c822b7be430de4ae6a7ff214d937cef4718477e252fe6bab45aac5d1872ba20a0aa53f171158852e3e1959f2ad3bc7ba5b63cb3622a8f996dc66b5b71cac32dff3c363e1c8ec309d586e5e6e8144894325ea63836d56882ba1553a1c13e153ada13b49d0adc49accecaa10370d5bb43357c8bfb8045d6c4d105b339f76746d297d07ad8f177dad9f23596a6ec75b74f6fd692bc95a29fb3139bb200c550b553a8e371f7cd1b06b33f5e308729eee3f417dd08d3129c9bfab52d32af84e57d117aac2d839422a813d7f68471cd87d322d69c729aeab06aa3f56512d8e11d093bb84ac765670b94740e85e656168a3a6717d3aa9d2d818bcab86abc2f3869f0c563b12b048054d8369f16a08ead9d75ca920c769cc6a7315bbb4094ec817622497ff1865c86224f04f6646f899a13e8da9717133ee6c6bf830c3ab4fa90f328f55d8faf5f445620a9ec07261c74b05d34e11b4ba631f5cc14d5b1d5def056d978ac35a7500be44962c22d25fb878d333f6c13c3c9c5c811c220b83fe976fb2deaa8d980535cbdb565aadcc907ace4f6121fd6075cacbe7ced5bcac5c7cdf1b6f1230ad67771ff749bb994dd91c1f19eec37d33355ecf6ca51b49ca0baa9906de2c4f2dab6704f74d9e1965f9aac5ac4659a5792b1cf6ca60e818e8d23de1a43e95e88c41a995c90ecc0ec22a676548ca6ee6230a153217bda9dabc71c1ccdf6aa967b62d7a8753cb0dc78c835b3df663ce7d700be6d90b55f4037eee03ea2a1a910f2e511c1da3342727af92d5fd7ad83b86fb6d5119d2eb6c9358ac765528273b18d831c370f8c3e626966a13679469b41d4ae427b930049649565a17186a368ea679e37c0fd74c5f55eac3641ca1f2a0c125c37cdd22f12dd3639b7674cca3d0edcef440ee648690a69e96c9018d3c41f19ee6e6ef68dd1fa71c7fa7fd6a99cd04e8e66172e282bcf9245f4a6a8c0d5840b26c57bb6e243b95e9395c79be7bbb75c47571bb83f8fec0de3e0b37c33db2188838ab67a4d388893d58b061aba9f0721ec167f248cb02873e77d59752682733eb3436343aff1a76ae51487accb15b2c6220a157b3538bf8048c8b1834e9ed50a6415ef771dfeca20241815efb838331e59f63fbd2efc3dcf618755b0e8b6d4d0d6441c5dbfd969bc3adf3e1b8bfbf5fd4e212fefb093474ae278e7e9e46eee3231394815e0e962ddc696417a9503d8399310c459f1b1eda2485717544a50418b3174954d5b3c0c30284bd8ec86055be15949821fa22fdf7bf1db0f24ab324ff74b4c9e92b623f8f7ccf1759a534ed63a88a8595530909456e571d3bd3d7c6505b28203ed41b341a5ac67fc4fd82c184ad88bf903cc33adc8d0339008c1f2b8121d908195d2569e4a81f601a0d123f1b215905a717c9d23cb568716b0b7761acb2603fc95d4eb45543e14b4c295836cb48ec97b15f2411d5e1e285dd057e3636def3bc225ad757c23362aeceae3f7e819172297f8073457bf8c4996e52790c0ae5e361b6d563b74efb22c153de1cf75cc075856c86c40ce71bdc9a3211d19654fb457f06c64bd34d5e0cf30ce0b224a22328d74505ef2590199fa8e894d3b285f81384428932b30a644411ee61626db9ca111369c172c6fb3cfd09372b6c884a8e8cdf6c3c8b6c80800a9c42cfd4600bc0817079b61f72312d5cb32ab465a5dd8df1e6f13e8455eea31992ea86041188507e92cc6e7ac90383a25c88741d19fee86760804340439e724b4736e90879cc26e3117b1b96bc78a91e9ee562a0c48012c6f38f0950f8f2797ae61acd7cadbfbda4dd651b4fcf2ba87fab9b751353ad772027847e67d033c4aaaccc05daf4f8a736776bd890c8e123ef3905d055d072426127a717829ea04fd0b62204f25e12d48c57b13a8e7463309c83cc3c6d620413e95dae059ce24692a98291891b102fe314f1352e0fd91499aa48f2e8b444edcdaf736277db2d09f80c98adae794d534de325101097ba05d739bd7cd2899583b67977487a7a6f3e0f13e25682760dfba50295dd0fc82ad3095a76292056a66a8c6cfc802019a73819e0407164aa60b27603e3653a45c93407c691a982c9da0d40902a3d0f683523fa6cffe235e56b3f2f92d4c7f77860437d64e30a09f490a5d7c70f39db4b23c8c5a7f37ad5935b9913e2e755e8dc18477a03ffdb931bea03535e136922b1e514bb0bc97bcc948a79c063e274a61cdd7cf4dc9bc1431de207f08d7cf75c938148886c47e9e988c100232ada72d6928c3530ffd85eb6eb0aeadf4a9d7be23039a88d5eb8aa6707c88b0f5a9067ce15cc62905875cf42859b1ba74c2ddb36dad5c8622c229ddd1e4174f239031037e9a7a4e0a3947d359292c092387804039cad6321936c9a8cdc17d993634817d95c1a5e4bea3bb728e60da7da5ad46f1f1f5986542c84eb55328971250cbd649408bfe9896314693c84d021bc7da0666b257ca0b1cfa811478e5948dfd1703746c30cf117f848b40f01682bbf7f3fc7b5c5c16919a57aeea9e124a45418e148ed721ba7c582ca6d14d560a9c7c71ef32f8e4f9c9b7bc9fb99d9174c45bb238a879c75bbc79fc76704ceba7258af664177211ebfd66e11c8dfd2953b87e01181a17658ed3576d572ae5b42b7df366755637108d4b431dafba62aacddb46efa2bf82d4c48559c9347305823cd5b8324c56c923b13bca18b6e1ba1ad6347ae221035b9a83a5f27b9bc1ba2c65b8aca4d36d644d22381c4baaa8d0c462439652df63e96449b96923e70c15e43254aa89baa549e784beaab4e9061671b648d24efe7b3b5ea49d21ef40eb5e5059612b820e0b89730db20ac5825057eefb25b86cd2792eb3275ccce960f8b10b0bec0020dcc93610bcba5a0acb5e135c67f3978570fdd739a0fa6343b5a43a14d26e4ebbae0ad93553dc7a6695cade9f034fa3b15ebc838b587f78217897327d8124da372bad0143fc0f063d3a02f4548343df13c5240ad4f0e0a6ccf2875f2b7a18a4c90c333aade36b3596af339b287e90f6ec749941718019b0b6dc4ae7ac0b968741d6783ecafec30b8a87e042a6ea9f53630606a1a3c4d6a9bee5aaf1d4a979f41f68c40efb236b0fcb172ba10fde5289ddff7ed50b763c35e5075ecf6449414a15bd606d616024ddbab3454f940a64b958acd85684b40cda3b6c5245b38422d7a3a54a08083271120e65fcacf4b782415c2d21ff034011a120db5783589acc177dc67694864bed5713e4516db58264657a600d2bea9fecce391912439e7b2fc3c3161094e8639b46214edfac6aa178b49550007611456b0a17bee73c1b55cdb1ef155fb7b5d9ed605964c543d286719ca4438f2071480450bc0c1cd44bad920313ecd3f70f6f8d78f2a1c5b7bf2c4b23bffcc05828a5489ea0a4b66e8190eec9120e7381d824cefdf9792495bf7fe1a6ebeef23c6af070b56b5e54cde44b7e507115a8e4f8d1d4197fd2ab7b8795bf701831f1bf0df21b3beddd2f470765a529a23aa8c4a755cb3d898d39031065f6e2bdc9c60894f12d1b79e4f13d23e79502775abfd15d54a42c59c48306ef79fec4ba76b191f4f43733fca00514d6267367a057c42e5578bffff741ffcd0c79201cbc0ce3045baa9f4241fd14809d5f32bc178bc709b6c7949394efce4b93448408059bd4204ed5cd48608d7287e692e5e8488765302fa504ccd65269f541c01086142f4a715b6a1f2fb1bbac3366d91a6900b3750e681f015256201e1173a2e6dce48bb83c114cef2bfff8c564b3836dbb0b59148274c24a041edbbfc4ce336e9eb51391ab30afa1e62d47dc11db58aca8e872fa126d13eba3729681e5cbc4b10e5faf32a7e84b8362d155a7a16f27af5750e5d223e4a004870409f02d4255973875c533f4a78b0795e813334319a7a3a4f36880a86d46f99b76b1814803f3279343814d8f980e5513038ea0f0461d9ad718afa5dfe8554e34711a00621ea67414797fc1898a3979297a8bf04e502e119fcc73353deacb4c6e910ef8ae2826767fdac30b9f4fb26fe93cc1512a0c1c0f055335f1d1026ab425e80edbe137c42759755ccde3a703fa7f8fcffe0eb0f9219bb9d2d571f9219b23711231eb48d6421e3e6cd57e0b1fb99473c415df767618026d58a73cf1f90054c681c31988ba9d4a013e1a1cf8eb9015a32c62d117db16f3e3c7424b52d8f75bd54b99d9ffe024772c10125658e814bd67e8db2075b7f663cbeca7b8b96573eec67ecc241c2c5c7f3c1e837c2685b5e733cb21201712ed0d9be67702c5f56371444fb792f10d8df6cf3b28b55b950f98123055f97c039883102a48760b25efe6c70c94ec7a020b252fe3ef5e5ceed9877973f1d7d17ae1e301dcd44822c72128ebcf149f57163901081c0e5a47a23556d88ebf51fec757f38b87fe6f68cc34bd29bb36fdc77c19e01feb061c8437bba8ff1c1c9cb8fe77d6b0bf9dd933064f2804c4635e6c7f36afa1aad138523e0e8c15d5bdeabcd68ece9fe4c06a4c98df6918dfd657e030838eca2e080443832b0703d44e454e09d0acf0d0df27e43e3f9df0a003f05d7b49102d63849de00803d2527b285d1f4f9f87d2000647663846af838b513824ab2576ec9d8e7100f1745eb3ed4fb4796142245105818d008429ce040c2376fada931a490f225c7297c58f0076a00f88a2f8c422eab67fa75cbfc4ca40be363d91df1f92d49b7bef20114aab86d3fb4c91852e833d73e64c489e44fd2bbe810f1d534e20bd7cf9fb276d0a896f5f3ae506a84d5f2831ed0c9de277079d310440f9cc564430e97a541df9188fe49b9abd8a203561e77022b6dd1ff96ed6aa883aee6f3ee00e132fdbc8c4c4ed23b5e7a1f052a803b2f052106d87bcd8940e7e687cbef6e19a72005b30762d84e37c17fe121a8846dd9325ee8df5e60bd5f30c0d3225306ff6227f06d84218debe3ee16fee70f24a9d0097a4913ac309f619832ded87858522f90ae60a84e01f592455ca38ae13ffcedcf3f14b3868fed29e7c405264d143e6704477c6824aeb2cee72d7cb8a22f56c9922b4552777833fe331cd917635534929f51768dd055ba8ab053eaff83c8265dcae994cf52b99478b471e97ebafad6f13ee52f677925e28c1742cd36baf0e61d85658e080cf5c26b86363a5002a4d535da0407a29ac5b5f8b4d730632f76e0c8bdaaa4873602bf275606813f53a82552aa44eac4bfd1a17d4639dfd3b8189643f464803781640a224b54bb3f0cecc8acca6c7196be52cd47bba012201af5a42e40d19e6f014617aa3f6306d8673ffcf12ecfc3146676103c33d41775b420e199f9a5ccd9e69f56532ad56d2f09da9dea36f59206d65e1277618b9f978836342374875ff278439766893276c298271612655093bf8df19fa8f5bea42e94337b39792813be84f84f6d91a7c22f52a86eb9605871f3d1a975ea41f42895826568bc51c4233e059792c3e9daabd2439c0e343543bef3afec0dada24458e63e369c6e42d14784b4d3d0f1a801d9c1f4d8d9d0f1ef112d1e96f5a188f9be74c55f00b8cc31466bbc07405d72e5f0907bf6f05a29c7c60e0f497f7ab2342f9d14dd82bfd0a7ac63767b27d7cada2f29aa7c7afd3e4a0745bc14863c4e973e39679bb1d016d8fabe7fcc47665810663c078ba646cd126b2824b5f2448f194d765f22bf6116073980a984ee51966eca29ddebdeb045b9d09198af0f4b427180960e4429870cbff7054e9ac0118d663e7d352393243698f55b613d8e00965438fafb4e9f2756e80caf90243a48d2b064ad4d9c443c77e05024cf84a68bbbf69ef0241d7f04fa566cb719ec6c99005a9ee89032eaa23d93f105b0c1f4ef96d83d85998efe6918bec970e158f387015843fcbe7d9fea1e748ed5ca08c06868f6649363d86100074b6865f508af811c94247fd87462fca1b5c35763e21410c705c4b1e07cb081d632943e7c1e3d4f2edc22d698e85ac112592740e03c469a7fa8875be4d92dfdd008549ff60408f9866ec4c6e9128ba031c18285686c5ef6fe31f3ae5dba8b746b7d0ad7b2f7c629fa0312155759620ef37f4bc6c349c6b46087f91fa31a4fe51583f1138c7908a344b937d0c900f058aac9b2dcc12c4e90c093b5630f462fd1a8ba4cd5251a9d91f5982a24bb3f9e8b42a6f1d01401625535d7afd9938fd84ad2701a86c81ad463c49b869012f2c9655a7a22d8a786a2c1748dd295fc289ca0ab2fc0f80e16956048c51de8d5e1720a6b4c2ed0a824b55c7f1bdae0cf278d490f0abdb350c848b88992a9e456793c853bec5d0b3623d693f65e9d12d0af4fc2519e90b5e978d3c9ef0a28649c16f6609169ddcc044bc877e50e9102a04c0570080bc99533890e0c2fee72fc7bd9f1d2ab90d079dec7fb12b43a4a0579c7cd26be8cc968659dec653c3132d026391bd139d9f9efb71baeda2200c77539cacafd6dbc9d3ff142a6940b87212ed03900e936498010f77580b62b52e6e22a2b74dbdf09535fc7e1b2c33d454b61f7fbbe9254b46b58924427e0e36464f0985de1b153adb9ecaf06b007a8dc6c5ab86e7d76c266a428b10ca65faaa1127bfbbb8566f29a697fc3178a3a9938d202ae7480f78dc79fd8eea2d261a56c17d609baf4fd5195443db72a9902abd4f488354b660eb722ceee9cd58ad881485ede5314cf48955a82d44392d8b511dcd5d7a6726b4bcae7825808c704e8a880c892f607543711c43a360c747b486899a22a731940e582c34c6746e476873e5d6ff2463a1ad7a4d266b7bc4a63843701e25d4ba789ec91073fc655f2e08ecbb91f32aeb746a37e1eefa5347ec160912223fcedeee3175728a220d08b2c314cf54569da8cf3f39032f5eb6b275c849b066f0e0ca120c41da2907fdaef2ef627e0d12834cd2756422aff55bd4bb116f5f0dca276489db87550b1e38ed98bdafecd72869bfab0eaf7d114eef5e337bd7c10b9f2c69d6d764bc7906e421edb6ed9c9ff06f58e34bc004901784489a71e00ec1d90b72819d3b55f47922a8ccd7d4c9d4f7f36fa2a196cae1998c99a9d123743b57110d0e3fb0c744bf894287a627230b00a5cce0c0db8add0b690d1862101b07e219f1e4ea5eaf4ce0cc89f65f88f078c974926819cd36804291b8cf62b69056c365ddf717f0864b46f3c7ed7e614af9f295c9fc7fe0eb3e2101412cd38fd9ebf95a7750c7ad60683a26f876e69e33a03ee7887e4e2e6e54dd5d048244aba73607e410c7ec899cd2b7b50d51f75672e90c143c63f575e644b1d6913df6930e21529778b35ec01743d95c099c76f14ed0ee6ba80b127a25697f5fc885cf6f260d299884730fdbe5e7f4b51c270b9699b5dc5f4f8eedbc5fc85d33cd343d455c3daf0300a6dced162ca522b157b3d90c82354a9778ba9445d89ded62704278e52beef9f95e7ddd25aba3afc7e47f3ee878de91ee837acab605771f4f5b72c1afa40b76bb8635310d56a2bb07a99820bf686a34e5c8ccc230c8b4a9b91e46a096dd85e16ecc40e97e19f0959846e621a4b72e5dd38104012da037c10d8c2993a94960c2d60b3bc8d8a09de0ea1e7d2b40b26c2f1446e7bfe41aaaa1878e1da14fee86d9fe51b35c719e1de5215d78868229575f5fa3b849c6fea86a2a04f9acfe106ef670e0459d044fb510424b82d3fa3ed586a052cba5356949103e945cb4da21c0ccb16b6542c2c382ef5a2935a1e9fda1451ad5907f10486f4060afca2aa4aa0aff201a49b403454d7cb4d29802884986baa3ab96280878763b51e197ca4c659d704327dd8a966c10e969ce02af81411f5968e58490de59e730ef83dab89a3a123fec9cfc8af360e27a961345dbcba8f78e322cee41079ea15628b1c382e9f765e17aade169694353d0956d87b0387bf9494f6c3881d58ca9b9558f0bbb18082d4539b747675368823213d496807fcce060c3efaa8b5b5f6abd204ff9edff6c6a1c0584908cf483165a98865e785fd0a96556c27d708bda67b057929d6d4d6913e9d64e90838b92a86addd526a9fc0135d4c162f216c22c0779bf7b0e0086e014258185b8c2ca2ddbc29af6c7bb2f3f39fc5e77680c6e0604467256477245307b8367ea480bec0c23b86a35c937717f30d3dee87a46283e75f5f3f78c74071ea2764f53f66b893f123412be41b12f8efcbfab0f48dbbbdfbba5f899d0a27ba656ab3d4f16532372806f5197b9ee60dc89b69711f88997c8c745e08fc4d9eccef93a7cc31576ea9cd0670e2e017ac84a8b2aff23b3b240e54e27046cd469a25cd2128838e8bb54a218ab7a09e0aa409576d8de1d68c30228151b86ae33a215674cd059defcde2abd498c71fb1a9a2a1319776391cbe97163fa15232e47d7c6508756b25eb81563c12b17a3477eed186bba073571c1e766e54bc79ec58a23b7a7f8d611ff75b081659b59a4486ff4518f571a8123c6545d17b200b75618a7948a703b46f375837b33f3c810b53758ccb5a76b2859709bc23da25cac032c4153fe1f3e1643018b41e733f285adfd6c392ae62d444f98100b6d22b8c3240d21ace2d1f71870eaad62cc139208548d7739920055a703de7bb49818faac984b8874c9dad3e61bd2414f95ea476e43a4f2236a65511b430345e4eefca155816af2bc16229f41cef905677a5e786d64a790bd1b2ed61698b4f92a040fcd5a896a2de9349739d5b6ad2595e028ab0ea570b21ca1c754ce95a6dab084b4a70bf18f2c1953d698770708b1c42def9becdcca4c06f3357205460bfcd901a1a0979c4dab3bebed5bdf4bfb2b7dbc968adfa08879f3cbfc96a285521c4d8fc553eb31dd84afdf382b4f5a86dcb40db0adf644affa4387b996601d657647be5d384801ef5d841da65c3fc065cec94b333d5ad8a03b89db3ec1c4c21232bfa899cc079ff59df4fd78d7216386b88e462fa40c8ba7b4a30e61f0f0fc8cc4b73cca3fa4eda9a84de6444ec58e6e338ec1747fb15ec40afe8643d325e3fd6073017f0855ab0d994ff728fe242112aff087133da467a437f29c96d0f5a9c7d5f3e158a7c9384d10f4900f015dfb1096500586da61f10183b49188971c27e24aa620a564c2128c828653981fc5e9f034e52d9cfe6c6e222d50c0cde28d2206d19f723a42f88524e7b98b9832c45bc4194ee070df3d9081639f5b91a6811e9cd52025d2d259720de8c4529f311111d911e2c0a6bf4d5294e2841b819e5d11b043d4b0844f5d6d4708901197b5804f4756917588b02d97a18616f43e1f88658cfd8a863a01ec49bc3c8c833290876039da4b4f7d48d68bfa6140a6e4c22f6503d5b15a03bde980d07cf2cf6a4c6cff391abbd24d494e7201feac8c3c4668fcf9565a18622682be0884ad162589b06f95c288ed290569cc527e5425e31d2a5bec58b53cd7ef507840a4162e3be4184a3f496f75049f55a3491cf8b1a1ca017699fa910125cf93eeba2bddde17604152f9d368bd8cc334130f94bbc70f88b8ef9178332b48f8a4c38f60c21778c08efaafc4850e0b819e68b84106e6b1fb2c99cecf181dad6aadc3db7ee7a84efe5d0c9d42dfcd1696a2b7d0eab3ebb258768ed961395576d5e84c958ca2112623875b7d998185b5844901b6a1609297410753f91e9a94361cb1617ed19b9f8e272710a1ed0981102a04540872ce7765c9db290be76af87d0efb2b0aa928e85a54be50626b6181b9ba7526a7d45e4ae8aa828d91dd917ad32c319e5a0850abff1c4c8f2d690a0fa46d98c299e91131279ad55fefd96a6031b728589c8df4c3e097568eddf76c40a6cad256d3447942e4b0218958d2363b3c38ce5b6020df4ccfa1ce2fae3892b343aa84251d1ac480f4d218dc481b3d23c49036408269c428eb5c399b8696bc079662b0c143bc562840b41829860738d3ecaa3092aa46b772cbebcf497101da277be91c042174423a6a7538368083044c27453a7469c5b2ca7c35001de8b6ad60d2abc0b3015a1a2aea46b71af2f0509e61201830f9aad4919e75c0e9aebefbf58ebb7605e942c6b210cf9129b434b999f4074a66249975cab3c23e9dfb30db820d7e629bd8d14adfb0c32bb144d2d2fa066ba613c699c469b90ace8e6d38040815ea69e575b1bc4de766023fe3b2b842a1a7f77532539d992f880725cf03767168c21ce1f4698e0cf5888c255a297731c9756795c5cdea96f97e6f28a741e310dd0e841eeef5debeabc71081ae5cc119b4484b5ac841bf61cb3da27b553f1db4968ef64379c46149ae56159243910f9c30b14c9cd1e7196a4d5bf18950333e8c7622a82d9293bb4e615aed431b40d7cb30132fcc8b4fbc68b361599fdadd228fd701ca3f44a8538487150b9a543190867d0c3b91bceedfb0156f4b020500a02125aa8a7766662a41a32fcdd3bb21a58d94fb69470f37f7e43585b0bb5450c0c9da0b88e40df21e3a12e1b11f17e223ef98829854290c5eb9fe265f860c3ec79ebf78a6921dd743daebbaf151922babb4d43fb80164937be03651dad2692c996fb81bd8ef6cc7b697d9dc47b3282a07dccc95014ebd3749bc4fbdeef468de8a5e9653a27464b4fdade2cf8daa1acf0df840266549205902376a65f295018b5aab2637a5362076aff10cedfd0d788b503bd09413b83b476e06510b422d825c62c3870dfa33aa514e4e791f3b64e293f3451900e98c5807c9f844cd57607d89eebbe71a70b85197b206ee6c68f243809488281bd00ee03758334d8d1736c74e7de7c46c1227f22c4273ab16a1f4423211550f8e96b7265af7359478ac550937c86cd2ef4f3cc2cd6618451f9c5e8c01a879223118ff7e499711cdd1f0731b70fdd7b5739cd9897498f716738b038863a50b25f5c6150c27c5536615ebf828578a29d23adcf516f836e14772f93ee6bc694f69a845f91b3bd81333c97c907c8c885822518e06fd035ac09e05a7a3706d62aad3466c923578a5746c79041029f45f99f04d4fbd003bb6805de9a8576002867b3d4d4a6af0197734baadd2ea3e903aa492167acc9259f227f84116e45d529279031316f794cd529db374cb3e59917da750ead0f3b8e9b68de0436595ec1a214ff3d37dafcf1789c65998c049722c5a4d95db7065f97b69a7e5dd57ad1e6ab7f8af21d4d5f5dc042aee323187c7e4f1d82ce11472fbdb1e2f978027dbd16940dbdff59a1eca22147fc79cf57a163a8e877d8723423e27e6c6eb13fd7f68a5ecd9902e38d0b9e6866cb01c3bf9ab89bf3160ad2dff4e9bace58f929a8676e509a2bdaf6ff9fc27a8b78971447af602f70e669ac636e62d715b541017ae194964ae5c2dd7157a8572f2417c9b89af50bb9370e87986bdf96b52e2ad0469dd3db86bea32df576404da3f3c1f5a085f7be512b24e0045e11393be74f98d2660cd5c94589360f152af1cd8a46e4320d1e885204200994515879d601eaaac3fe8c518bbad5b893b481fa43261a3cf89e14b9e3b8a928055b8b53ceb6b5e86bbb20c76ae3d9cdd002078952ecd4b89acfc3465320d6c75a7cf815dde49c3cab279fe8624f8253f98cee7519998059f6d514bac27adba9fa7b99ea998a6ee41b3631b906c532d7be0fac9f2ed29c31c99e9f30edd132f8df2650e7aaa162d21e2c1e4e2e9ea81c6c085394f7b9d706adbf5d3f99a0147e9ac7e4070624bc6add5b9f21eea422ecc48ae550b27ff94322d174b4e4ece165ba3c02b75775a746ebd046b870be555d1b636acf23b9ba4a5d7fcc7c297fb6c17356de085ba43c28208d1aef0af1488cbf65337715646a7f23381f54024f8bb9bfe387c422362ce92af0e2e2de5ac1a84f75137cd7c66ea4052981ce51a173afa843b8e7dae610622f50c51756e567645d189fdf3a5fe0fafe1d2c56b11d531d62679f10c61df024814dfd95524789ccb24469ce1280760a9bd26fc0754a477b498fee0a81c53ff1cb26ecb5f33ddc867d0fd12a41c787a5c5919e0f25cbf221d67be6a12a4b05adf4dd869befa1ea453723a4dde1e3796f2aeb3418d33208b9e8923bbd6a925ae94504a98c48b7d6127a84cc4141a5161136bc54d0dc5069af5416d383a8d12783016990d706720707f85e8b4aa178a726328e9d5b003468caf3b8cce020dae4c7196cea937cd1170f3a4049db8906257e6808ea8e0cf16051474aa6d5db0df643121c991cbfa7c0291f5591b572f3e8fe36df0a72cb4b6d9e69db7f32a1b5fa21f30a99e7742c2ccb4a1c850e19cea7e11c394c178d5055d15c0b490cd15980b97082a1026438dfdf962f14b49edc5654f3ab2a972dbbd0125e324691b711cc37b9de1445ae644f02e4a618a70248b3232afbb332b58508b7068734f523b6cf7a49211e2be59f1cf3bb2ca8b77f891d76fd3fdd820ff9193a7a5bf067e39d55814119920b19a3a8fdf5434fcd901b8565257e60e404ee02617f3d3565bfcd90f0f16a3538d20c002a7ca78580f645b75514ea4bb5076de34a1a8e05657a89830f40db422bf921d38aa287489a3250d922ec8e620ab0414d48cafa09e28f54a24ba82ba30d37174ef53ab0249f3759cf608797cc14c1ff88be8ab0580b8639eb8fccbe8d4eb298cdd5c6bb4d6473024af389685110280d6b3a39d3395132b120482b223f1040bef91ba9a51f9fa287a49ba5a13fd591f6bd88d3743d68a7b9300a984e0790aba471a66ffec552c23ca2fa118d6a5b987910706cbdd69a486b7bef9da44c291e06fc063b06313186d8f7c3c418d42cc5c499c730f39eb731a9598a7df8b11e91490d8d09bc813071e63dec391613675ecff33c94f0610fbbd94c883d6ce6f5d82eb4338fc77e3e3fdf6d5e4e9d836a937312a15ce0d7796b42a75befe89cec797cd338f43c7e3d3c1ff2bc4b64eaacef1199d42cf57c90c8d43dbdc5d455624f55cf5550f3fc27edecdbce46a82f7fe622942acefc9bc6d7ff0c0afd7e2ace5c54caf23df84da38b09161969e8c811f5f36a967c9e3ea55f7f897ecd51a7599b4f4599a37f934e3427f4d3c9c70728eba7be8f8f9028b77ca65396a8a5c71f91871db25ece66f5f4fc4d6e053d8f413e7f9b4eb29757b336e98ea74e198c424bf5652293ecd52c057d159964a20cba62da216ae95148ac0a9fc7f06fb24d28cebc6f1a6515cff3c823ce3c51290b4379393983d223fd1ee9f37cd0579149cd6c845a79ceaf6d96ea07894c136ad6dae480ac07e5e5666dbe8fe5599b50558c21776380bd3883127bd8c744263533a5fa24f0584528de5698383ef85085c33139c9317c2cf561e26c89be12cfc77efe9134421ee7135c94d8628b34c418b05411479f8a33a5faf4617f9b57777a5ea278ac17b35ed4accdf7aceefc9b0775a78735e57856334bd2e64472f3363c6b722a7cc970b3a6356b73fe043cdea69607d4e452480bca44dff305439995eefa7759647fdf161b0c7b4e203ae1ad714ddabf67ffd30fdcb3b945ee98bbb9bbe7c82f94f6b21074a3adf0e94d2ef2e9799ed771e9ba07ddbdfb29eeaed5f99c1eceb1621bd778e6bc5c18267415f8caddf89c2012286bfce0d75b1d7716ecba06251465a2972ebf2392329162cfe3b96e0c24047ad51b912bff25b6d0f7babeeff55d650c14bfd7ab07cc049e87895866507a847d8f30d1a98e3cefe46316d86b01c76623dfc76c8f12b6e4238fa885069e11f672f45eeffa91d9c8f779ef1788e27e1df0142d6575326d3623231aedffc5535cd77b52dcaf0396a222287a9ec8ffe01b0aca2370ceb682f2211441d99c70b6d4bd7f27fe84e2d177bd7bcfe36ce9fbee3fb1136750bed777e26ca96302bffb9ec7506acddad6ace1a6d3cc9a35cb238fa0e5f1850b5fce3557de239226614888898a614191b34979141027e02c9146e825411b13fe98f902ce0e428408792e4fc1c9f2469d2ac8d00a3206196974e9fe66f7c7f31596a5e5237b240a595a0d4ac1acae7a66387966e5b1362734ab2bf975df045dcaf3bcc5988d62939a6058c3d8e7dff74d30ac611873a344886be8c8a51131024274a402b18542624262f2f2e87a8c6c7f934878a40271a344488c687e3c5fa50dbdfcbe3b12abc2fa0eecb67d31900868439a529425b3d6555859ddf7816f5b625465456330269ecb23ea9ec2604cbaeffbe6ac9d6d09cdf57d0814ab955e61dda615c6e4fbe073a254ad8dbec21ac6c21a86b1ef0b6b18c65c9fb4739c9ddd765fbbbb7bceecce53745dd775b3737767263289a6cfe95ee7eeecd2dd6b6766767707634176a89c6efb6e1d13cda75fdfc9cc36afbbdfbbe77ddff7cd2c14fa73b9ac9cd057adeefef96466ee84be3dcf33a27d9e47f43d337722d3917ddeed664fe8e3c3fc7d9e6ce3fbf9ece705d5cfab554be8d03c2be4791e1da5363e77f7aeebdc3bae1a92a9999e85c215d84c347b78320fbdea6ee544ea935851bcd9f9fc1f9d4fcff33c22666666cff33c8fdff3c0392de3d073cff33c9b91e7defff03acf3dac28d2ea63a2d9c373cf9bdecf6fafba572d71b7799eb7867d8ee7795ef53c4fc9ddf0bcce465d22129d7be7eedea921474ee75e97eb72eee5d49023a7f39c1a72e47877c7ebbcceddddbdf3ee4cfa72a7b6ad7aec2a3933cac509b5867b97f32ea7061b723af7ba5c97732fa7061b723acfa9c1861cefeef8634de66e29bdf33ed0f5a2151663201893ee8576b88e3aa52831295a563c55575655c5b2b4d0482c8915e4f323036b4ce94a46c124546df3925268e41ab906284868c7acc7078ba1c059ce63636267cd28a50965a5d34be2244e268331f15e36c4c34b7229f06f422e3f90ee8582e72098211e5d7dd14a5f3c916a1f4d79db73b7aa575de5790ece32b14e43d2e4c7608d85c5a4f301c164566214b22614d4cccd35726b4b6e493bb8de9a503cb69f62ed641b06eba86e2385a6d7f41a1e3c66104827336a424da85966464da8324ab3165454b7fcc5a5eda6bae53797f65475cb5e5cda54d52d63e0d2aea2bae52e2eedaaea96ad2e6d2baa5be6e2d2bea2bae52d2e6d2caa5bd6e2d2cea2bae52c2e6d2daa5bc6e2d2dea2bae52b2e6d2eacb8b4adaa5baebab4bba86eb98a4b1b03d52d535dda5e54b73c7569bfa96ed9cda5fd4575cb545cda6054b77c814b3b8cea96a7b8b4afaa5b96bab4c5a86e33b8b4c7a86e31b8b4c9a86e2fb8b4e154b74a2eed32aadb2497b619d56dd2a57d46756bc1a58d55ddda2eed0c54b74897361ad5edd1a5ad81ea16c9a59d46757be4d2de40755bc1a5cd81ea96824b5b8dead6c8a59d55ddc62eed35aa5bd8a5cd46c7e90ed4366ad835f937effa34d28fa113dbd857fe38f2a3714d5862608241022f5c89800b10b0f28016aa5071000b2ba830e5968294063060010a4800020e8082010a70020106608200a204000a00964a20610425114200e183271e74e08483264c36d060bc4b32c0e0022549922cb0211d2139520105468cbabbbbf316a28798b28d36ba8d968ab9bfd79d06f6647ef77d84950662281379defcbee979a02cc2b48e91684bb848ca2ff2dde9b74adfb93fb826ff06263523c9bc2542cf13c3252c9b4598d6305b9df0f6dd298e725ab594cdb2a54b9fddec9cbae1b9d7759f473f57d7d53bdfc117ece592b4a63d5c84f2e7cd8a48dd6354bee47c5a292c84d5a758aca7613c62b33b9f863c3ddf13fa589f9e1ff1c7072802a09f20a2202021219a50d08e1db51d42329904b21d43434386643c7810e131349b15cd78f4e831418f990f1f457cf480000223087cfcf861e40704ff14fc0f6b2bb02f8a47441b410448221089888e88220002040908519020b620408408b14048101a2d8926a4564b52a349208112096a43865c304402cfc31e17ea2194ef44ba6ebe5b90c890a20c8a883c4d2075e70445628a4c51640228a30b1815f912ca77235d47c59d6f04340a75a0c0df29303255010554472aa802c991aa232456201d5d6143c2c2025b164916689124690b2549b8b8408915061774910106185892811777c99bf17ea1c108c6061a84c16483ab264cc4e0a0c9184e3820a30327703ce8a08c271e98f1c1933340f8002b041032204208682889a0811194d22061840d94400207964a5003004b595000b04600a0b0112500710410458e0902e8c0004c6883000370e304026815e084370c5000385030c09c03a0400701078823010890430109f0c00214b0c58005ccd10006d491d2003a529062e796c207a6dcea50610adf5941051c0b2bc8e0001666a0e2001aaa50c9d242951a1ed082162b0fd802012b4e2e40c08608b870c395087079e14a1709bce0050609e0c004430e31306189e1cb9d4f9bb0e8806bda41061c981964e0818619c264a1414c0d59a0b4d4d0c3162d639cb690b1c1a9cc0d36f8c0e506335db8fce0a54b140e5e80c80187209e7210e2cbd3103a7c39b3830e4480d9010d0f6072617828424c1823a0c41cd103549a313da82133660265c820e1439935667c48e207331488faa1024044b1090208258408c2024308b1c49921da107186093444349143e34411b9278c28028a238c88224de50976e823604de6953db8b0af144770cb59344111232314547004c91192cd82a4244a2ec020832577d46003264d3870d281074f3e00210411944620a18425004009401401983000029c500003a07000042440010b604003a4a4709ba2c20a2c38804a95161e6005022e44e0ca0b12808129062c4d8d6b197a86a6a1b3740dada5b7b453dbd0373497eed25e1a87cea19ffa4bebd03b3498e6a1c3b49886ea1e7a4c93e932ed439be91f3aaa81e8205a881ea2cf34118da6735d441bd147749a58db400748e5f3db7e5df03ba5ff7bf01381aed755a8dc29ddbbc0fefe16865ba1fc39e9eb6fe1ed34d7fbee4b6cc1656f54ae07de1c67b3d96c369b4d4a29a59457fe7dd3a960a482d17c158c5430f2e20ca83be4f294196c5ccae35364bfdedfacb838658a3f089dc856faca96b31bec9fe24dca7ee3ae053333b333b3333333773a5871d74d766766eebae7ae73f7ced9d9b99b13092396396d8eff9c57d8b123478e159e2a030e381f04255127250fa919d58f35c5c645b174834428aba494a449299e73cea9a933da14c599a2443690352997b8a8c2284a92f644d82f9334d9a0d1cb967064514654196ba8c018e2f6b84cf585d4a53c332597f7f425fffb66dfd366cd639a3f452699d734be8d041ea9c87493f9df6cddc86307fe1229edecfb28b3e67dd3e8b2b34f6c81041e95442627de38e37f5d89b3251c55c3429b20fff54bf3ebf357f92f91a9aac55907dff77f4fc599d2eb674bae7fbdabc78631f95cbf444a291ceed266ee1903c5f073d92bb3e671d67cba220c2eb25c0f4a1e71185b9491483d4e0e430b2fcd9def69bdfc4a61dfd4afc6c5a57e98c8c4d474a52a8a94ad2b27597c05fb259e87f53ccf7be21253d087df34de786be61f7b1ea59db9381b413eeca1f407f7d6746e3fe801d9858aa83454fcd0c595623b95e924ae1cc2ef6f2bb6e02e1839a693cc4ef2b054124d029f3c37d9fd6e61d79bb027733a7d2394ba231df71ae7b3ace5f4cefbc029394059baba653d20112e92df31618532d1cda9cbf61dea896aa8eb346957234e727d4f100c4399ec1f8b6fe7248df62f9365792e97cb45eb64e2ca2a9db0b0b0b01a8b7e7d02c13094b9aa8bbe948934f4f2a97c1e6b2f264549ffc65b208c8a4d66ee36f5584fd3794a79c8befc59a59bef6f9c45c5f924aba4d4d02f99435686269c35d9535de22cf62c4536e2a409e34002512130e8a78707f6469c247b17dd41bbbf4929100c4399ec9f8a4de49589b3cdcb29ec2c4993bf43149508c127e992469c249b8986aae20a893723d7f5af9732834420d187b3c450bcc9c498787b176751795d4fad1117b9c4998b612eb1c9bc3723f7c65946f6d64d5cf9df7472dd1b67dd8c48ad6bc4d7ec90426d384141444e6611071c4f23953858a08ed448679d39b8913a9809e046da51255181a7917a5a4f1880a30b2a46262c3ed6185922c122d4441d4ae046ea22838e0dcc31d217951719a81a29f522aa0aa79156aa3590801a29ac8a306f9c461a0be3ccd59b3284c88d3484b2c269a43d555a5983971bda8cd4a74a2b6f0033d566a43f55daf6a2c50a6aa440555a2639068e54165b231316a6630c183a46352278995822c1c27696787a625433457653278bab910a0505350b0d6141868badb1a9b1b49c5274de2a7ffe94190265a2e99dc8d414b03343d588e5cb1a418944ca0b8437f082b3366b73fe1499769041c3184ea38bb44e62ea08ac91ce9601ea8ca7715a1e5b76179f349ff2146fde688db4e1ecf0343a9189026a6434b49863cdc85ea8c1658db4ab9de53034f084d548bdda5926b6620b17592396971458d3ca664b1dcf160b6c8d1dd8d9231ba6781afdfb0ec8a00b041f9c48af07c16f4e127611f9a078035d6e6f4d13c6840a757710743d88f4025dfcb2409dc4254e9d51c575f166b3048d3450c1e1264c8479b1dcef13dfd288e6cb3a21e850d0f1191599e01675443ca1cb433e095c354a8309e1711ba4c72d901fb7444111ec1087ecec7dfcf80181f511410f2033213c6a6e8786b89515b9dd51c4ad9091ea3688e5d1e74a96cc9a5ba0fb592512897c7aa4bafd71eb73ddf6b80def74cb93d434a9b36c01172555b754092f91ed16bc605a2592e6d6ddce25d52de0a20d24136fe2512d0e40f75707b5031813ff396b375b22bcd96c4be4b741a844d6a407b127e107defd810f08402108892053e2e1a30704ffc3462012050122a4469380c890a22213185160a40224478e6c481624495282c10519dc25e3061a30e1a089130f3a7802c207212889304209242c410140000410c504020ce0040314a08b1214aaad8b94038049c182ae262500cc6d0164a634a08c0af24b8187156a2b619ab48069720aacc9df166d6156a86efb884b59a86edb884b1d50dd76119752a96e3b776995eab6d15cda4275db445cfa80eab6cf5c6aa5baed212e854075db425cea4275db415c1a81eab681b8f44a75db5197be50ddf60f974aa0ba6d3397c250ddb60f973255b75de6d218aadb26732996eab6c75cda54dd760f9736aeba6da84b5b86eab6c55cda3354b71de6d2a6a1ba6d1e2eed2cd56d83b9b46ba86e7b874b5b4b75db3a5cda5baadbfe72693b55b7fd7469db50dd760e97f60dd56de3706973a96edbcba5dda5baed2e97b697eab6b95cda3854b77dc3a59d4375db365cda4fd56d3b5dda5faadbde7269eb50ddb6964b7b87eab66bb8b4c154b79de5d2e6a1ba6d1a2eed30d56dcf70698ba96e5b864b1baaba6ddca5dd4375cb772eed31d52dd7716993a96ef903977699ea96ed5cda3e54b74cc7a56da6bae53a97f60fd52dcf71694755b7bc75690351ddb2072eed20aa5b96e3d216a2bae5382eed21aa5ba673699fa96e79cea54d4475cb705cda68aa5b7ee3d2ce55b7ac75691751ddb21b97b611d52db771691f51dd72072eed34d52dcbb9b4d554b71ce7d29e4075cb6c5cda4854b7bcc6a5bda6bae5ac4b3b89ea96d5b8b42950dd32072eed0a54b7bc814b9b4d75cb695cda4a54b7ac814bdb02d52da371692f51dd72062eed36d52d635dda4c54b77cc6a5dd4475cb665cda4e54b75cc6a5fd4475cb702e6d28aa5b26e3d28ea2bae5312e6d29aa5b16e3d296aa6ef9ead29ea2bae5302eed0b54b70cc6a51d51964a18810a19618a4c0385301207ccc1085c94c025acac586a49c90acb8c0fe8a787ddfaf77137fbfddc7d7252c7493ccfef7152ecf93f4e82d5245a39097c7e588c87cebff99ddd9dde9ddf9dae3befbcd13b937c7ebe9c9c14fefc0ae3a4eee7f78909bfefc702f9d820a11db2211eb31e3e20f8c145f6878be48716c8060971917c98ddc145f2ab95d9211e5c24df6567b6870f2e82808b7e70513847e8a325046f70ef7c6e3e746df5d33365403f3d56640f40a1191158055cffd9e38621c82008be3b7844d63e6ce3e9b072b281067707ef6024215c936f346b42180909c968225da6f20682408420d8b91e04c5255cc27ea3b9c112ab1c6067c8807e7abeef6fb0ef6f3c975fc9f79c844e9077f0e922f2db0235e9a16fc810280c7f5ad18822b04cb907082491be9f3d74a875228f1c4ff4ef867bcfa7dff7cdceeb3a6f4eb71fd0f7c942300462d9114a248df6830c30743a5dd7d3764f2783a083a1ac7560083e4f36e19ca1ec3c91e6855606e8b5e7303dd91e967a267c61044366c92c999925b364e6efe9f1f1f9f9010262212166e6f7616666c92c9965b62b0b7213e4e60aefce095f96b649abc08856011f3d61da74226936224fe4d195bec2e16433f7a4311294ae4d6f9c6d2d1c15a564b9137410fcc0cfddfd7ae715d40ae378c3f7e5ba9e573d8f525707e5d2939dfce4d7e5acec48a4be0265cf798393389136f4ec2b27b0cec2ae14abb4b4aa566b85a083134b6ba2f181adf9665e4d2bf06fd3ca65acca772b086a69b95c1de875567ee12227a943c3d045dac0a38cc2418eb9f3a5d60eac500d23358e6bf3d34469219bbaa184e2ee88229c5ef0d1f7f367183c31506792c1488d9bb54e72a58b4c99a881099b6df9ba6ed7755d57ab7ce224d95ab62f5b29054b279836ff4a27e9ac2e327f5291c4c69dbce5e562d157f24a369cc6126d17e1f7b7bee24ec6401cce09c411e1fe65681cae03c12f8cf5f490c964412ebfd86f8f6060da1ce2a32b9236e9874a12063e4ac2b4f936499b4fc5bebaca5aea22f33bf1939fccc9237927903b5f5ec934241288c5664a4581bbb2ea4e09e7ce29dddcf99fd7754f9ba58c755d8fd2446aad247cd44eb491b469158b6959595ddd97e5d13949def93fd2ba6e8f9ab07b29a5c4698562ccb0e6b66d20b8288876828fca740f4c9bdf4e5dc79d6dc4937438a14c82651a4e5ac349f226739cd473e7576935919eb8487e895ae2f670e7d49a35d87d59394eaab0b55aab2b623271678e8be6b3010317c544ea37e600e74f2d31c29bcce5e60cf3ebb84eebce032ef4c8c3febeaf6777cb29a79c5e85334ff7e979288fe6f7ed5726692e0508ca99c691c031c8e5a90e7820ce9bb0839801e68d335371d87ce1431d5f48b065482e6808301b000347ca0d38fe812b26cd89ef14bc9812238e1c3b5e9cb1f3459d26a82b78b89ac30cac2b92703a6850307903079c115b561c78c2ebd47e38a18a34e83c3103163f40f91cb20f813a1abaaeebba2ba400e38501e99b31a8cc5c5dd7652a33767290800b194d703953070b0d0c31856f8121c7240386902cd8042142881c5f1c088c1a0f12c82185a03d5138b2b429734689ab37ee8120564c2068524b1a566feea06163ab8c91d11b2a36535084e0652a3650c83ca1cb546cd0b02923ed0ce94172d18137f241f9619b3754312e6f5c5bc891f2b6bc19837e3d2e538959e2d2cb5462d208d1c1853b45a46933831923d6c861f485c75185c5962f6e8ce12285865167bbec4ebb42cb04be2d5f842133a9c4784165460dd7130d5da6d222cc7d5da6d202897b7ba32e0ca3967d6c847e792a8e5518278b2f0edbcae16a035dd6b0628d71d28983c5957d5371a6be08c3e9727dd3f5bee9d20f7ceec1e3846f078931263227c021ecdb5dec56e13bb7fb5825e2c19e4c97074d2d806fe5bb9ee73df1264d37d9c47bffe941d3ad12abdd7f6114c19dc738893b30dbdd93bedb2332a4e63fad4c3e99dfc4e7ac83babcce05ba3b0cfcacf5afeb5ca0f884ef5cff2a3ca5bb4feb60cba9efbf8f69a44d63bf27ce963cef9bc6177fb5209bf0065e998f2542975113e1105c1c2da5a858d162bab245e3d0927ac24a85b3a54fc9c927ce48e0d1d634468d4c3d766ed6feb6992e428544514d59dd7e6e28cf93603a2bd75abdb50667e6de9a4e63cdb937994576612c293d89bcac89227a0a2594952c2325a3726fa454d59a36b989c4e3d8df663a89ac52a68bf4f3982ed233694796813374fb659544aa61f5d41c3797cdcdb1e6c471a9141d32edb3c7749996c2658143ceed3702967ca8040c1d28a95388460000002011400083160000200c0a070422911c04e248177d0714000f65783a64523215082391381848510c84530c432110c22086102619320ca2191b5000fe119b2f79ec20e98583a718e11691fa39be5f84663d1e7d5568c5c2e90c46c61fc91f537bfc407132d6e8571cb37ea078d81a85a8fe08d532b182b5998d69013d9c71789771c5122b9c17527f21b526f5b4e6b465ac4ddf395a537c3198b9296b86b57126b6c05b3df56f9fd74c84817f9900714e928259802658f5a4ff6f9541ad2b84f154e13037523a695e9f2754a5deec90a13f335a901a3be75bd0f54a724f810c69536d4d04212658b9171312f131e35024d4432e96ee8ad01704a843c4b94703ab55e0588fa1e8a38756627c2b9605bb7c5a310961b7cc6c6e78494891b7c06226f1df093469c07ccec0b16e634ce30f42f44c659e1ddcde70e4e3946f8b495d6ca37752f85236b222e838da1db0239b2390acde82ba8f431446d84acb558c7d2889d50fa64209075818a604537fd45d2ebd4fb748845fe54049309847ada679d79a6003ddfe933419ef93dae1aa41667381343252e3fb92ce76e1491e6b7bacc8b7393f999f6259c70412ffe03d4f3515225a586a51d6feedcf6c36189bee722c5839181998b5a1102b6e411e603f7f0e7af2cdada2827c62e90268448bf44887012665473272323d353ad65e207044bff3b76984da6a5584a625ec990dad613f477212189e01be8c37d06c80662b6d2ae4e82c990bd296c850da2f6ebd3ee6b3229660410843389ce78222091d201fcbce0ae0a4e77d2e330c15cbf9babef1e4c62485c2818e097c08ae0b90b40c5a02d552c262f557b55b37ad1f6289b77dcc81ec3d8c4dabfe0870de6b9757b0a7cf1ad492d8001ea9ce71494afe960758a8ec0a4d180334b21db9e049b1be4dac63e01bac7ad1c96e2154ca89d4d63d0775dad7ea88266ddd9921ff03235860c870cf35dc2553f666e9f5a1a359c544021f178fb55e4fb2af9a357fb5049bfd32d771df33cf334f0fed50f2e765404037058271620e6312754c01d375a736cb9e2d193ea3fb8e1776a82a5f2f9bc248828593022cb73661060810d2b1ed123fe001af3340a59303ba729ce3c9ca6ae97c74964e9d87fbcdeedaf805999ba5a38d6a3507d9a0d81f747e7a67b1cb4309e6bd7709f4b39176940d24ef7bb9c43cc8c240fcab1be31190c652caecbd84b3ef5f8c071c7f4338422e878481383f05dc987019d0232ac0856628df9a39c756dfa50b696367b4da19a9c14636c2d64af06ef86828383b3810c10601af19e6e9e9a52e632edd6502a897339fe73e4ff7f794598e517d9a8980d3bbf67959b26054563f2c0a90fd2e6caba6eeac97811db36c4df002c306c30c50868753b90adf445a62d87c71b5df90056e6506f3fa22b9642237c7920c04f2ad66a1dd70e87efc0e440b2b37748938e61686ebcf81f62ec716c6a449420785d09109fcab8211d1932523a47fb19207ff60e606f1f0ab329a71b13a23da45c5472f9a860dc1320e71daa154cae3e1ed0c26f0cb99c080e91e746fa3f99c4781d35c713a4b8270a16b712e3424e1e4ac969caf2951c96bac26d3189f5db3db9b95d41d4b0d9c465954e5a5a369035256e239b3153a57238a030dd19885b3501f60d45fa02b4cf21e2c4079808dbb9515fd47f4894987c633d1ad70c06862f42decc13071533f2c63a1c685854cfd38493f6bc9e5349b871eedb7e815f5e1520a3f31f6edce2280bc18f5922a8a170b152a5624664c55f1bd2a8c718590d154b03d03371f2f34837e1a926e954fb68cdeddc55ad52aea3d67062c13655f44d7978a1483347967030a30163b86a010ec9a4da939b3b4cf66d5ccd293de65caf3be3f1e2343a37fe7fdf05125815cac8b55ce2a431633010d481c5df059d2be3de0718ec276d215b6321612428f87c7c4617cf6b56222519974dfbee97734e52b1a3890401833e45f2f9fe06046cf8b81ddf2be892545fb65119d7887e95a257dc4ea2640d781c59ffa767c1e10be6fe4da8f33798c84612ffcfe3548d501d4bf576bbdefdbf43fe1f77dd4c718c8f755b895c6365ed1dbad8381a20db3ce8325f4787dae2bd8298b08eeeb50c4b25ad4e44e2d97f771f81680b6ff3c468f26eb627d0fba81bf34dff129a0facfccf1b71d8bf35acc5a75775c4a98692999208fb8f27e6ac4337016a171b90f9466e4f8e9ff72e6f9e3907eb2f29c5b817f8c01a5e11bfd238ffda9aaf282e86f70e87f6e79fb036d285b5403785e019e3e9f019ece2a6c0e59f8bb2016025be3ee1e29940560bead25b3b381d3919cdd91103a32f03a6a3546e8bcd9115f960cbfe89ac14a099df3f3e7f5f3a005f4808a3d26d2c1cdb5f0fe3a6122687a55a1293b2d72b80ba563dd0b9bbd481d32572cff070b09c5adb6e4aa242db23c49688e19cf0c895b090a37c160276410ed5723ad5afa835b9f3d1eb8a3df8691871fe4795b9968dbbb4decd698d8726e398ddb84634e415354c3b88d2d3459d23bf03de538685e1807535aaf341b2fb70919a90adfd36d82e1a88a089da0996d824e814511a080054bb6b2d4ac78215e90654433bbb1b1fe4ee9c2064ade943968e0d4cb630296560a2c4fca83eab3560828230277eac1d61224ac55eee676f298149e6772b53266bf0d6b47359bd004df6a2c534fccafec66bb18a65988d6ac84f566e2a40121162c11310c0cdfdd645f69d3c7701947a82116e12a8a94ffb363bf0e9b30fef63c3acdd4615e567fc8c6939fd8e3950f0fcb341080306317c8d97d6a716da352a5de4ff3794eaac4a0343a42fd5db26c349bcd80bd0124260d57952ddad545980fea828cc28f0265267960d8f89ae3bcde8151e1812e8c5510a2c4fd21aecd6e6dd6234482f83a5c1c0cd7ba0f6d7a506b8a4ce3a609b4628c9e8a2383943995df99fef146ce42a104db1061e4677dcda006328ee7bc2771d29ece5f8971c56300fdf1d3242868c845974b551ff2151a8cb280f0cc2075b8dc2d8a5806c370d115a20a9c546f3e9d998b7c90fe3306f558c6454d207ae51b0a514e579f05553c259a83217f068c3997434c6a307195a4ec17f5dcf04f137ce10297df7114f4bfbea3baf0b8f25042b84670a94d90bce6dafec1318c481d7d25e4b155181af2aab2b8ffb1f4551544d5fa5e16c8141d30cb5fb5a9dd00fab5f9bb37bc658009b62bdc7b0bfaf34b4a4e8fe239ead0968fab92a73050ab64d521b0e0a4656ec944bb35138a1a3e33f369f70980feb26c69a124c407824ebc035965d114ef6258d81175d3ba17756db5d69e5a0b427f039c7640f8541b8e12123d012837a8ad7e6955bc2bc56bc5826a4538bdbeb66114e104cdb134b3e0e15d7f58978b85f5c5d556515b54b7f52c67b338e3ae502e93c3257c0babe0b1ddd8e2bf86fe995403c4d8de3a876b92a8821afe47f812138cf3252ec9be34b3e0a6e07f48f6d1b881316c97b81dab215dacac75b80e40552c586dd1f2ef997adccf62932415d645de4ae27ee25beddad8a34e707de5948c2d559fd4b974a0644da4b64b54da45f6288aac52d9704c38cd364e5a46a25252cba012a1c8c4fae605165e241df31d11be60f7f0d71e3c981f2298dde1ae60495fb5b2165a7580d8f3b32f35a587e4034709081a38ce88be45f34b31dd85232b2b3059b10b22f9c2c50468882d0ae025615cc473d4a14a61076380000701b35e8285fa602dea80850502bef6ae6535645d258bae7d3e269941d8126a813bd24bac76d018d041a6b7258413a49f6b8a6c3611da3c7547a575a2825942539373cf188d96a5e0852e9db4acf01b52c2c29ced8f9f71bd360416c4fdfa9d4b3c152d0fb220e2b12f1bc376a197a4093fd558d2adc3e839fd6050f637276a83d7758df9a3b784cf2492ed6b2eea56d769ecf287db1c2e9a0f453c65c746985501fd6ce3498275c2bd57d2aa3ed12517af954593c6169b794c812c29515866aa7465b4569bdf04a80da439d6e9f6ba7a21edaf63a7130b0474ad4a822d850f8d1553549038f049aec7ad9245b456e8abf8c9eed2c716794a016348594e0fd48f3bbfcfe84bf82f65e1503cecb947d8cc1654278ffa7237b67d4aa97853d04bc9a736629e693d794f6e43711d02220c05c2dcd5fafa8640181540f2f49453ce9419b8dee6cfa512466834ee9e7bb937d3102a504ea62803561aa2084f4ce4ce52010c1a6ccca3b54f5015773f530ea1537f5060370584242c1d845e41a20c709e905e87bde3b6935e3b32c46a951ae533ec7a01a1e2873ab8550d5801471ed35795dced4aaa8c1c312a83251d4a84f276d6a94b9aae182e0b7ea72b184eddd286488663154d12e1697b806e8b8a90ea150c392164183e32afc05733ed8292420c87173ce394774ecd0b032405bdb7abe30529106f868e3a146836661cf7615241912fd2b9f5bfa5c1852cb3aaee8b87023f1555d2832d6db526a460982282923be9d598603f25cf6acb03a71b0d9387f1d655a223b3c47261a677d1808fff37cfb8ff39e7734d73ac7a073a90060cf4447920822c10f4e11f196de8277df9d4e20e761508747cf8d63e62461a431135d9fc4f2770f54674b64a7b003c8bab13812d367173c5d96d8395aab241f10efa96109f9d3cf674dc3474556c461dac57f00cdce6678bc99d842ceea7fb5dc89a35e9a0570ff5d9c91d7b64213f6dc672c1656100a7b3223516add60839287c3e6946b40535ae799aaf0df1a5d88dd611a8e4f5684458be52b6e15917d98e8cd1eccc47ba0cba9f1972d348dfb07c5fe0646e88685b68868bfbf3dc36b261c560ff497e5ddc71ba757a1d060dd0d3e9d8b3c9bbfbf354c460cb8c33d1571b47f97c1de8a959e53f3410a8836d7de7b6d3ddc6aee4d57c1df53fac4ba00de3bbd88ebdd9909f36636db9ec74b7f90abb9935e7296dc51834185b663a0cedf69ad03d0540a951c639bff9f224b25f876a4cb6a7964acab129a6853a2b54eb72897925b5844f589a897fafa40238d3708ab591f467fa2b952bc0e56f31b07efa71851e80e2b47ba2ad49a63265faf344b014756878b8f5fc3c91c0a09954687a2d7896c4eef4bd18951a43253d6cd1dc3ddc8a0c764afa8b65a00087fe415b70926a3a995b113ade89b8a59aaa42fbab28302538926a648caaafff58e306434092d04c233c7ebe0e789a0f1d6d9eae46dd8a6325f383d36e48ef4a6131a4fa204ccefaab8b87d7bb1c91ea08ae86229f364a39b68a58729e0ff2d352393412a547b192f4a14cb6668ae8f380e12d19325182a15add83bab2099e09f3e2dd5275f26c8bda0baa5a28b81721463728ef7cf2c90101d540b12c276948413f0474905d5e7206a8215c8d8e559865a082bbadf0d2bb8500fcba31f8d5139548bff03045de92c42236892de493e813caccb82980b031dfde3ae48ef6bc49c5c6332468f4b2105689c55132e645c9c88ea186d809a54b5742d11c32ae7fc6a0d3038ed887ab7be650817ca585c100af89aa50e25fdd3b7765e7cdde70ff32ed3c32330504e7cf6f983f369018d24fe3f7013cef17c845e5d8dacfa9ba812a72b5d9a0fbe3d9a5d47bcbf67b43d2065587e33508108bd4c53a00046b63ba709e6ecaa32afe5b6c87e03aec259f716a45406bfe56adc8f5e329f1a4b80701c4e9f6ac2a881d6dc126891634a0b77ddc18f214b347d6c692916b5dfbc8414e7c64399628e65162618b1e88169e013c8815d6ba21f9790854513cbe568f00ae14ec9bfa2442ceca8c6ad5c8824ace7f569bdcf5f2abe63745ab65149bc3fbe6c0b5785c116ef208ef017d02f5aff1636cecaa05e09e5bb522e0dbe0d1ed924dcbd121262bc9ad2a6a8748165ba15c542cbea0d5fe81d826c4d536879d1f5fe8584108012736c235bdf7927a704d5bb62d9d947a81058701ae58433890a51cf8e217fc312e5b169ded94efe6b6481aae83cd820cba68c406d27f90f8891cf5c13594748a56c67e26d5fde3d11f37910e98890daa9d4306f84d6c0e983429a0a2f5819c677b2e65b0c472a7778341b25f7f42443d38e0736f00be78c809c5e7c8ef3de915ad25268be88e178ae67bb5da915005260b9c24daaa28b84b517ca3a55d0cba7e0b3c546451c25141474f0aecfc3d10c0b37087c20f050ef77ea44268241aefcbbed82ed3d95871d01df3ac4ac58122415b720ca3115305c31c708ee8df707fa8422a20e721eb102814b232586ed9b606b307e9beb259e7f1aee62038e737fe2b99697c188aa42a7620bbe2fb6c04501a51b233698b5e5f515f191774ec0e9c028ccf5562ee5c4a4fa0f64fa85c186e9867beadd179e8124f63f7b85212459b236622de6454180ac475b59109057721a0826b8d51adaf8866fc028aff5616480418e4ed45694462b7eb5e963666ca921b3e5418354a3bd6ea488282b83b5826c9bdd8e2848176d789afd4f7e62b9fd17e2375203e3fd26366b70fca43bacac9b7d0560c57d5fb5fa7314162be7fb4ec70386974d8e037d22f7fa70e2a7df0b885d1e9a9233508e3012c0d230dae0d2baceaa3be857f4576969d40e57daf6240f54d9f37bdbab66bed2300e6574b711c8b703c6856961c039da44a855cddd5c8e8a7bffc5deddf1c7523400ecca6bfb749aa214f524530011cc91e4422f1e8584c75967d9ef5b8f416ef16af03942ada14299c3d4d70a59bcb40b460a92ad0b239513e7d48f4ebd974a4e5479d1eeb4178d41ee417c1d011242c4e17eacd8249955a4aa9f7540bc5b8e430fa8d8974bd850cd48171e1f5024996bebff4f338f0a024d13262ab3fe56807bfa9d4d5979a5f0b42ab3b04d4f19c474e80cf1fb2e8d9e612723babb57e66d6a326a0db6a6e18b48351d6fa394a71ca174aab190c94ae5d589f04c8f2d9a12b18f53150f2899e89ccb27ff91ddce3345afded292707144e392b581e4849ed43bfc051babf6463d175bc994434edaf9c6789fb9850028b8d74f431a033c8e6763268b4027f1c9108f6f218414ae1e1b1b762841fb748891b8adb421803f11c2bdb12c6a0d42e5d5de84396f6cf6d407092c3bf5c406b1bc1cecd31dd990da0f075eca171d3f0ada99d16145efc1e7da565301de1ed10a915d77e2ac5efe45430a240046b0145f58b75ccb4d98960109ad9263cfbdb598f08694c1011ac47e0fe1290b203faef9bab3fe1f9f82f6461ae1304f4bdaf6e6f949130f250fa0123b910dee0e62d0d3e0dc91a2cbae33d0efcf4c053d16d1233bc2091764ca7b85f29e8e14d2747d8564829f99310d28009c8836e39e3af0ce757ce1bf85c7238f822f29137dbcc37d3f0342207516ba79c607eb919e97a013257772e171eb84da9212a364dd1bf54d7d4e106c0c0be94eed395d5aa682a1f8b8b3421c6b59bfbf11b8bc8536d05bd80da44fd002548db3d605608e0bd664241cf19744d676dc5125effb00810ef332c47d0cb9484fd46715e40f9eb6817686a3084a3a40070ef204b109a11b326294815931e4c86c9ffaf6d0a314788d92c93b3bfca1a1e1733270a194cd274a336678e8833e0bc51b77e792cf4c0e9dc5cf643f2f5d03a93b9dc4025ef80f9443763b77f8ca09c5c5d2380f3f05d29c8c0df2d5a6e49ca33613865edc8527eaed125f0af8cd92d5c0556385ee6ee189796afb64d8190dc57d4f4b8b5f93dfe4d7c07231967daf15e21827c85cac6a977058356ecce0d1cd92f60b0700bac30df9b560702215826dd6d86f07270bdccfd475a912f6e0ec02a5935dfefb1138efd8a745008b223b1886fc8015d5718d48b860db05955b1074d92bafe5823d51344650853d86f4ff773c46aab645fae90714743de5361d050e21d11f9c4a5509ef60eabb162a204d1fb1243bfabd86b7ea3a1da566e56ae370b83acbed768aed29b3b18a45d1a87e23fcf0c550dbd663f581f34b0fd8c8c6e296c0ead83186c62840143cfb76bf7d3f2a70b7cf35b61311760ca9bd6311befacd0281ea17d8a0a6aedccf4d9255c4f529685987d37918fb2e5504d174c4ab5ed72a75d7e4a2d60677214b58f653f960525addcd7a4eb9603793e4305f5cbf7bf91e8b57e498a70834cfde331112142f6e9e51101fae817b11ae2584a8f8aa06213fb39b55027257e7c801c87fee64ba66701d1cef47e7840ece7d085265252be04958ecefe3dce6e3c29c0147d778536f985b43f85f163575d5e2b783386b5e0aea373ad7d5e83c5202e9562ef0a4de9107aa50f164eacba26e784292ea16198d270a14ed60506af0566f77b3cbb48a4f75689ec8861823376d0f7873af70016988a536dec84c6533fa55ef49e277c01b5982332113856c41fb8cba8b2817ea879a3d2f34aafcf73255dcac858771cd324fe60458d3e60f29dccdac5c9a0753a2f7a60238f6bd422853cb438690c929191a91a85529bf1992bf750c630517988ef7400ab85d6d35119be8259496369008aaa0a8af84db509b1c38abdc6d813bfba97c3f62237dc27d85030c719cce17a9fe97eea3e0a3824c159450c19dab45b7a648ebafc68328c6ac55149e703da4d0bad530f4ba28ce731296b5182553000642a9bac31709a7e39f3580e94fecafee734d05d04e2982173771a08f99ddd85506839e176ab380135759333bd4fdbb9ecccfcb4a15d5aca3ded4ee24cc6d3362e39ff3a6d688796644ebb9238a3e0b48dcbceb04d1bda2d2366d3964d99b4f4e4ed42e0554a73bb584008c9ec0a8610080903287e10718edbe0c30e7e045be3af47a372784dfba8f18ac8f5ab2491b254386530108451d5902513953d47bdc9bbed179cc8e0f0b93fef2a6ff01183a8691e15096efba1fd99295c12ef159145b4420cad3f90943d4b5aa76a425496a63f05041667c8d9a59e89d50b24ccd53d85d4c6fbc03fe4575584f00aef5b9ca2362312ef0a3858e5a32d9d23bc5971596cdf3864e1c5fcd43d2fdff24eb2b3b63fe861cc75f2240de001c5ca56e1321ca4e467f3c2197100ab2592dcdb213e71cb2a0d177842ff98c70ad309d398573abf47994866c8007b79d2fbc1dd24da88b7d24ce411dc6a516bf169c8103d6429ebe638fd4cd24905bae87a8c3d743dc87d753ec43e5d1e635f1d1f739faec7b04ff783b85fc763eca1e321f7aafb31f6e9f210fb75fb98fb743d847dba1fe2de3a1e631f1d8fb9a7ae8fb14797c7d8afeb63eea1e321ecd1f918f7eab21f232b13018c0ff4d0eb1bd5488fd614f64951d4babec83d3f222295dd63765f9518d14ec01105716d40ace3659687e27f6b6aea84a772aac0727bec47100faecf492ea65d926ed5d5d34ed6a6db3c7d1035a16591f08f09cedf0abad4fcaf5086b546781f4dbd3278d4fcde8f531596b3b992efc5a7113a7369a14bdb26a8f1080b1e13a7e803776389eb96edb7a8d40177bc3be0f28bf2a64bb690ae190fba85b10021f482bfbb1c7d1e955c6cd6ee17caeb2e8b397c6e45c76cf8528db8f74cbde4d551cb164c9c1eba3d480f7058fc597998bdcc36f5b5f1f04a179d2a70f1edae5dcf3dd3bea8c0868f66d3e7be57de0ac46f77715ef7cd07d4c5a3c988b398862534689d06408389a270b6369a66a5378745b9f2aa86fcb9c6db3b3eed580dc6552f875da3ed11740af332fffbe3fe7098a4f219cb45c93561d1fea806100b8dcc67ba65413e3b905b9899ffa7e3eb495d46ce782831787da586aa8c3b5cc5bf58b77ddff7d039818060df2198e9858cd961199b31124b978dcf4f11589bf4a3888301a14e342ca4bbd5e6b89611b5c353753fc7ae0c413d416477c31805bc64138fb9247c8502644c0224b99c80fdea37828e1253b892658b9591fe010fed1f42e8a28b7ac14301b45b7d7e246cf046cd92c6084827360b411402a22547a78ea63a80962b2fc60c69c3391d7c0b2429b534e48206b9f2581d805544da231ba2a4d9f702a23627c70210f08e0af8dc9214ae9063c5afa96249cd14f94fcbe6325049f256da42e24c9220fb7be600219ee5c06c7ee57f59463b657e9bd50cb1cfdab457ce9eb3cc12995a887d5980bc65c1ac51f99810909ce80ae88e04da59d6476b8a644bab221aa502734575203b12c05e791f6d33322dac0ac1140b981b5581ec8800fbe5f5e00dc869655544575a682e7405304702ed2deb83352045ab7513ad7201b9d04ba01d0b69b7bc8ed600292dd795e80a85e48056817e50a8bdf23a9a2624b6b86a82291422075a07da4321f6cacac19a23b3e5ba88a6a490dc2835d0e3802d6459650171444955fa3a7d1615d18eac89c0f4447185740ade65d4e17a8c4c2ff015ca101846e8a6819660be959e65af6038f59e7f1b01ac2ce956fdd8ea06471127a6a88b80edcdda7bbef0027f71ebb0925024c4dbaad36cba3b58df4f1dcb06cb06c2b15063d00a0e8403cb450380767aebe024c6ab4735241ed1e28059b191ef07077961cc4c64c9f79389b8103023b0e6fbcb212b08981735f3fd71909503990bac5c7e58c49623662246fe7f7964a50033b131f71f0e9942cca8a895eb0f87bc34664860c8f5cb455c123122b273fde5212b88988bdaf97e701095838c05a67cfe78648b11732256fe9f3cb2420823b135f71f839452c8acd8caf78781b830642432e4f5cf445e0a1811b373fde79095440c8b9af97e18888aa3cc45562ebf49b42937212762e4ff9747560a30131b73ffe19029c48c8a5ab9fe70c84b638604865cbf5cc4251123223bd75f1eb28288f9132767dd46b245882d72780e6efd77aad265eedb4b84e8dda55723b69d2280c62ef2fab0e90942f5fa2557039b7e24a8c62d71f158ec2d0274dcd2ab8f854e2040eb2ebc7258e83501b5de920b876d6f13a2e12cb89e58761221747ec9cbc34e4f11aae9975c2c58f42b813ab384abc566bf08d131165e5c2c7a81107a73e9d560a1af09a8774bae1c167b35b1349fe414cff74d81cc5ed8c9b94cd2f00a3a4efecc826e73f4b7dcd74007c30dc37521bb78fc429fa85e2f633221b82062d220578d080a74e9963b505627145cd330a94ac03ae50f81a5bb055c3cc7f0b5c399ad7d31c3518ea81363acd0ed1e6b43403afc3caae17c382a1f4ea7127f8c7c2a6de48e7f54e9e96341feebf8a60ea3573054867aa4f0838be382b17bbaa49258a856e19b386677426b161529f0c858dd04997d417a6d471caf11dc094e0e72d8f18dc4f5e67a3449ecfbf89cc04939b7397ae1565534992f018fa675bacaa3d3d2102954e6eeee8a6f6b21f9a4738aee0c796ce9bf98727e73ffc772758621db8d34bc8db42bbda0567ace869a44dc142b048c7ee9a8bb6834880fc80796165d6822176e2acc124224701275b491160458d4917ba6ff1137ef0cab2a2bc6d013b84e7e1e29c3163c961da8921edd5784d84a0f9efa0432db155379f1266fbadb50cb7e0e083f878aed2f9b14cc17c782585087ad4d33457711e1729f6084f1887d42fd4644d6a7ec756a363654d63c8ecd94676ce0e4bd1067169fa6fab643d27d224cdef44a908f2715c3ebbe35adc470a532f021433382ccf21f2968b384f46825ef81aaa80c2d3339b5efbf6b44ccb07a596eb14670e09adfe230569e9b5a8d16b1b8357d966c8ca6dfdf7baaab977e4397553c99d4c5650c0c6f1ba113e1723ec0853073d33113d9e97cae7e9b6e11d093bf854f3f6391702bb13ed261bd4bb968eb0a9b736cfc69b186dd11f2d60d349226e25112ec0d278f5bdcebfedc39492420eb69c221d67ae5c5bc2ec8de209df94549534b745f9531d56441e1926e3709cf2e87dd61356f6a6027539e119df563d19f63a28ba7af9e9ec79e3ecda97d00bb694adaa66a9f55ec31705632f84ca7c7d07dc6075e7754df867dafb4e8b095372e3c6db295cab859bda9df10201f79f6120107b8adc98be26969ffeb21611dfd7e7794a884ba5c9fc7fa3c75734a6104cfb910fe75c748e1fb1e59569a5267d9e96f054bb3cbab20b38882825bde1df1f4f62d6f61710444c18716487014c517a058f70fefe79e0be48034f5524de6989b7d50b7b65457bde92ff58026f60c18a9cd8c3a11390f64eaca5db8f721d5e137403cd7adb664bf5833941d4e73023ec694802400d29c5603c065d92ba5176ec2eceeca28c5c4265f84007eac27c14eb80a1d4acf4bca5e6cb240b16510cec5a468e64b4f7b7cbca46b7656195eb83658d7b25f7f179e6122c3fcf88ded36270086c9e67c47caf7c66c96e84799d51f25747716da79bb600eef7539d6c8fc9bcf4ea7c8d40c7a06b40d20390144f8f8f54b65f1306b07341e2b935b88592092318267b14509eebb573b5bb439a0cff63a25feae606a0096c4761b67a0cc28dc5d77043b944e5aa279045c217a39c17f93e0b6eb2481ca89c2e5c2b9794690fe9a8e821ed412200eb7684de10e8fc44de51706fdfd8a75b326ba1b32c53e083709700719baf45b5f30a653bfb002002cf8b21310db1773bc429442bee053a8a2dcf438768002021315fe01d43c7b50f26d4ada50a2e5d066ba12e27712f076df2f15685955586f194189b8c005c5a22e0eaf5a114677c1052c12b9c9d752666d3b99418d5ed2972214a32eb4991308974b6e11085db7873389a8598a6bb5d72bd447fee13dceeaa09a8a96a51326abb4d9e9c608217e9e9b8e2c6915c2445f4df18f6b43452faa6b3d77596e34caa3cf92ae04fbfc0227c91e9c087611612e5541b93943b1d3cac13819d66aa9b0130b8a7c55b2bced8f63134cb6076c2443a918f5dbd52f16b1958410250f56b4a0639b2e7ff484ebbf8f41d76058c20f76d70a1469d3165c51da10067bcf77c485ced737cb06d4f94d8eac408d2235c2ad2cdd3f4526fb7cf44d6a0090ed7bfca0319af4b2144ba13806a764a4e1fe907bb8193a4b4e1cfb13e0c5b85013683ddc08bac6748345c19d04a1d515e11d55e39d4b6f0b79e6077f73823bd2a506e076b73a60728409d622d6b775db016fbfb6fbe56ea58e550a825323d8b552dce3e70657add147d15b1fd00159a2967242fefa37d8022d17a0112e373a3201fc1dd32cca4edd3dd9dd8eb20037d12545596dc1818bbf09b676abcc273ca9b8a08d7761a8515add6582f9c7249f8a3145a461ec83d8ea4aec5adbb7035d8e66e8e619e20b379d7ae071d4838234b7362f981f389dc18afb8299f4ccd6b4c5f308149f2fcd89e888f64d6bd44adad62f3c7a5eac3ace4a7521248976edcb06a44083741105aff0f7c2a6fa71f3dea9287372a81f17e29991e3bfde777668a19ec16648c4fb21c21853aca3c045f3ede91acf102aaabcfff8c6a8ad62c1e612f9e741c102f8ebf1c02ad66fc5af60902877f279094e312954adc70c1ef7d12b855c2333d14c68732ab73a8c93e00c94565b1e755ccf4113c88e8d47c432f6006c326d8359a3093b6ebeb9512414233e72f400a1934174c2d82b1cbb4df7cc3315e84a12b50de71b60605ba6ff780859cd2fe063eb05afcb6e383537566752976787a58db6be0eb88d1884912e51950740c1bdc948cdc01bc7da5a585398132b9dbccc96ecad097c85656481f4042b28b8cbb2013d07064bc1199c3f74968034c15a14781f8086f0df43389122ab3ece51ae1b83874d59c99802d05b34d4fd06e9ad58cbf487a4e78d23d6ed0b4427e1ff0f47c2247cb90eca4688ccc5629b10dc830dc255a72dd65c0f40a508b24deb0e5008183dc1061ca6d06408b30208cc00e0bb5978aa5ef7adb862434e8f2d5fe71aa0a57063f4333408ec128244d7c05d253c78de38249c12bec676f1ed2aa71e350178565646338fbe1e155fe52679d282a68e05be44483e463701174012fcce3af8e56e49b4697ffa7df43feb06ee718a7d6e1615169634f3b109599fd70fe49dc9d55215585d637297b086ca92faebf359e77dea47703bbecb70a607f44332795f64e5c267f33db1e44420ec4703d661692d9b6e88d0e4f4ab55d9c0631885b1f44f36a2be002ffc01c89524ce544486aa82e15ac9884a7ef6ce2e5640d3bd334eac12905426b2b771418a99d924c55859504643e828a40d69de91d013a2d62c61fd5a958ee518aba792ffe79813305fab11fe67f9cd2250efaeddd98264b3064ab3db1873b13a0d124fb6a171b504f9b624cac3c6082ade878d6632a4f07950cd4ba95366c1bd42bf96ffd2d1b56b5483c140c0187a37edb84df314d538f61d0b4433a04b174b8390f5b641b25aa159e81835f8832ab19d3e679fc4914938ab897158bc2e2b309112ce6f69a542c36bf861df3c06ebdc296a5189fc2dc2eb5748110a7e749a4622e8018020d22aeac517a42912d56471d784d669a7c4386cf52d072fe5113700806d77b59cb2089786d9439212740acc868e6f7a02fe30c8f6ebe06bf52fa5328503819945d970a0f970e4355dbd9464a31f90a689e7cb3c7c3435ab31656d667077cc1060f53a6aae3a6d2a767cd050bd367b101b0041ad2fe2bb23f76944051e6df5a0c49a329167b4728f7ac7ab2f0386e825b3381c4ac68048d0410f03c65b004cd2b8395cc66472fd3513a05913f8e3ad944c8d45fc5ab1d12fc6b94c6ee8234cb56ea083fd6e7142793418a253a032874bc0a2efbd0753e6345a4b53d95403c4d40a9ac3c034d539e661ed2ff06688789e6ac1b8e76a4a3af3b940cde3c5fcc5f41526002e6975a8123c3647b0e1475a5390bbfa7c6899056bccb9ea0695e38366003dc56a62c658b1b4d990cd95554f7b33c472aed4437dc505eda3487b4e57dc61f3d7e9dfac66715275fbb41a68f965a002f3c221442f3864d53cf10a1bf5318344b1decb3999b39e1c06a8738a439429f5d83f966573582f050754ca212366ddb19e5784ab41ce278c187a92bb2a24b2bef50dfd582f2624fa81ec1206bc7fa2cebe5f5b1b66b1a3c424dc7228d77ed211341f90d6a7932a5c5f0b1330eec3d2f1ebdc1d78e9f3f69c31f0b268bc545794a4a76b19df37ef42d987c74a19752915a78aa64fc5c016a683ae0ca14d1a4e6582ba079f862e9df0d5635283e04e7c839350b4c1c60978050ae78f13b08fdf37e155b36fc2cf5c7e5d72eaecf2c7573e56ada22f4fa491fcf05ec4f820ceb571cb817193dbc07ca75871439caf688fc846a10be9cc03620a1525b233e2282f2598dc616370626d4b537b7e9d43de831acecff895768e953f037fe2432ac3b1bfdfd55d2d476ee491ec11d6b6c7b8e9e5276b0cc7df4758636ec743d2abeeb797a8b46682a7a4c9a1d8e9393c1185e84ed1686f9e385ce4c0ed0ff7cb518917906229432f61dd48563cf3e3b94cad4487eb08b1758e3660e914b6f351479e57199c33b1bfe4b56248e89240455c245eaae2554a54de941bb958890d4af51c8986951950fcd12254d4ba78b5ee41c400327ec2eb37701c591987d91333942a980f327a70055954f220f4b826cc79c099550309816de8e3c814557d16a1a73f0f8e8139a2135f69f187f25cd5bdc971a912ed28d0af229bd207792310f7bc3a9732f70c187d0cc55ce5545ca726d53fc00a9f3aec619bfba0ec4b4852776d589cd315b43e07c13311258379308c11b975a438e38cc50a814edb18ecec3f8f33119ec7c0bcce20074ea60cc3750b05683cea2f486ee98eb26d17515525c3ed37cbb10a12411dd1566cf6eb8f3681a0e351b388dd8303ac60f8931fb3ca71f561e695113b976156e7e9dc11311c9c118734e5b92341199d10957bf496ad371c10fa947cb48fe2d6436828a5581dca2c7668a4afe42c3c1bb23fcb258ae3ec47ebb44ef07a73a6f4f24cb9289648162ea6b51bd85329006461e921428c310cde6125d914906222753416601d453c686078cc6a5237b78736811659927c43a2b245e5374f0a0788eb5d63541644471a390e4e62b27812b3e2b84f2f05b049b358b0546aa1c30d68854227a2343ee3293d8deaa9019047d9f5d50b172545d6e8000cbc29a6d1cde162c1f4b91429e394314a4a3f54fd87744ee82304bcdd1d55e0310c830602c74fc92e094a8b27fdea2b286b8b09ddd78a89012d66c01c6a84545727629ebd5cd96c950c8548ed4fa73981c7039064185e4f28f72fb60e115b93835df6938d8040194dc447dd971a76f5d1a85ccbfb05b2d60a38a8fb47f22d95821d1b53d82c79402b872db5984a55352a181ab3a5e38e45e8091fb015db034184637304b5eac0b1e9c0386be3cad265ca6c67d25209915c6bb0dddc0893cdddad9027c4178527ba705b8abe9a95a4138a84a7487e95651db272e7b8dc344966e58530362580f8061088174a6ebafb67646227f9a89ad0f82ab479fd8afcf063536e726451460561b635465adc3835a05cf612ea1e97e9f91fbf8be34d6b264de119ea7d1dafa4b3a76062c1643e22ec7ea17bb374a24a893d0018b73c1a0d42aa9721b42912532ec8fca885b59014935543f0149716dc72f86014e2bb74badceaa228d5537bf72b538a27e52bed4351a8a06ea638797869c25b065924344010b811eec5cd9f60455e81943189e473542b34d9cb2ffb05c5097dc2cca887be639ed42a2f8634f496d784d2020eca218bf249298b9a82f3e69355ca54a44b0ad3f4cae5eab74e4900ff7c8261c38be5d2d3e7a44b79512daf3acd599e7779522c0087711be71959aaa4ef741648cf059c60800bdb9b96001bca50c8d385a9b02cd46485c3958f5bc850d3491d61927b524424114be8660ee055559ee32c4a6e488c37272409b062c52059cfec17f6356ecdc22eed08112cd85772c0e469c1683b673d84eff8c8a82db8c3faec2e5c6b62726044c6a8deb90dae917dde4d0b93311a13ee12bd904f179c601b49e826b0070dde35039fbfce2d4976b4018a876641e1f348c50ced53db4216c4895dbc05ffbbb54cc74222b11514a533676ed04b2b50315eb5fb75c139c84e5301a0aa9f21666ced5b425a0008fbfe21a3b60957fb1779e379e8d00ee2a85a8dbc45422ab71def9b92a992bc638932ee17a85f0f425f3ffdebeb9fd607501f3d35233f9e40f1c6fea8c56491babf5a2a0f8c08d2f54a98eaeff37dd8fc574a9a60212bb74ee8c4650a9e8b7e14d2040becdddf171b23c5ba7189aebb14ea0d7bdc5496e316b2c74a9dbc235d0706bd92a2e0ea0bdf48c5e33ea053a9e283e4c67f94722cc757b392ae2123124f03c88a52a8dab26b38cbac4347e1f70a5ff08e892f397159e57cbdd15d86cdb918dae75630d32c6724bf9c2af8563dae3b8325dd138534984194867173e7d9e8b906ac9e97667cefea387ae4a997dda43f1afb857c220128fdd3f12bbaaeb7fe0d1bad7ceb4b532f1456ccd5d7af3b8d66a74706cfebe986c183f3ee77fc7e3730f487a51cd8770d4ce115ef8ab2156baa07912d3ea1822d6ba0c5be7777bbff161ec792de29f2940e10ca0ca162708978450a12f97c1c5f5a631841d3e05991e4dedb4eec91a8aa641ced9f0d01ca8c4f991b117541c19fb4e8c141d9c30f37c0378f03f10a26adb849eeb21a16e2c6576954490c41ab7a6363461e7396a5439d208e1b099c1f9850383a402f010eb8a8fa566df863af97f8301e8359466eafb6df57c36a0e3ff90f9b214b6d4ff2879eda8058e7b6b3ed7c88c636c7e588b0a72948fe10a84f23923d37f1c172e21f138f3d23e34391fe85bf90bd22742bcb86a7d20767d161acc8db632593d707745b7e38be07e745ddcd3ebcc1563b587f208930f5bfa0e641ca8939052eb71e6fd74be343818e68a311b680a058c6bc4af003fe3a21d5082b94a5b6bf4edcd6eef6de7ca35cdbc4bd7f88da7bd1efcac9c223e6ebaf08d17d883cff270c85c95b6060c6e66cc99f99e2f92ae58f5a9e798a8e6f3eeafb0c6a06f9f86c7c009d53c6585e1e8e9de8edcd4efd4128a7f046077e353afe90489ff612808368f4e0200f6334b8f38309d2a4df7541515a9d65e727e8acbfb85b02942e15c2578bfbccf676820298cb6901b4b7e03b8322fc15ab49a73f19d7361d84ae9a9947637aea0dd511ad61c1040d2297b8b0a9ea71c7803adecd828267e2ea43451b878d47578444b3faf416521de3205af9788d1bf64bc580e0b9c16c165608bc544e9b16e6a13225b4d8ea58f2425772497ccb8f8a8871de6d405fd746fc0b15af0dd4bf8042b8b07bc8c5e1a656456bd1646676fe0c560a6e067c5413a9459a88919765fd2dd0f58b50a48e958381130d881243bb127fceabea4fa5a112aa0fc5ed6bbfd638da931efb6a48e439191f010489cd32b0b31e6b4553b5a41471a85a90ed1355afa5b41c2dbd525bf1ff945dbfc3b205467a2b602fb65ebf4c09d254b2eb2ea694e2f3b5b239550db193ea969d62659e1a015f258e648189217544a0af6422b02f0e5db2a1af4aaef5c0287f9cca3ae03ddb46d3f402c52f36a4ad3675affcfa6bfff69b7689f181aca4acbb683e19facc9fee7ceb50e32536e9db29495a41c93e668ad33101dbf7cca098506f49db7c2e4f928212cef2ac534c7bf489166ba002ba738997489e770c76dc963667b8e5524e33039abb17a6bb6980a6948faa82fd97bf5cb25cd1004f3525ccefd5cb046f2396e3557c24e83e7e1c664042d3762bbfc3fb39778568fc67363696be9c8a01b580b35cb6be6b46ab4ac055f09de5ceaad881403b310c8d3d7104356d3cb109e1e141c1f75de703225d15801fa85784251b785996ca76f9884c5d5602ecb3568499fa1ce9b54dc7ec49f8482d41755fc20d89175a1b06d362265af4b2c3d07ea82c5657c6da0b660b37a66ebe6536dcd66297cc53f8d3fa6bff62fdadcbb21be3c3e63654eaa9a0e2b8977b80bdbcfe23cdf57ab952d2cb61635e5e445ebe31c9efbd1b6ae534ce7ed0e5043b13d9b6d1a09e8e81080624ba036aa12e8657205816a703f9819b4295991c26757055b82fe96e34a8125773129a97aae8feecfc88f8292ae25cdefbe214013b2845fc8cebfcfdeea32ed63c334d3907afbb01306e789d8d7d99b24cbe15ff2bbfeddd6d6fb9a54c29c922086e0865082017ca6ae58c133178d272c44b5dedfbda311848f6b6b9e8125d97df43cf35227288f41bf8da1645475da04ffddbd8e28c81c7d54298955b468e2e548531dcee55c49121da6ac86cf9a967385538ddf13744fac97bfe86742f3f9def71ba0325b889def3a61722f15e14f6d7bd28947e9aad71b26eab3e1d3827f4f20bc2395f28fa49863cd024647660284412ea54daea36385220eaba3d65a06f9bb5a512eb8e0c2473d49caee99205c9648e92393eb329cf992e3f7533500ef3d93fc99d2e3a1dd4665ab7ac0134c61d1b48ca88707bf410c5ff52a97dac3505e99c6dcbc2ca58266d247f75570d1b48025d1cdf8080569427e59658e0b4180d9b3c67cf6666e7d9546b588b81c3375ad82fa6f1d7f193180c44a5c59101004c654db7f5b7b8591c1e1ef73baa9b099259fd97959033a328ac0fec77646f2628b9dc023e71109c059e71e743105272cf6d5828ec868db01899359b713f577ef2d04f959f9c59fc04abafc819ff8ebb7f60c7ee59875325671c0b3b36ecfaab9fbfe3286baab46f335a0c3ef9cb8eb25a8d9e4dae61ad86ac51000e173e15a6f1279bb66d75ab9ad69a0264cd08a4e8353e388a59de023ef97b9be13280f5ccdc09ee197425e48cff085c49cfef1cff10d8391d14f65ce7409390d073cf21098544fce47f822acb09f17777fbc08259cc624d5517c0bf87a0ea1a1ffd4f9a7d66c82c1f66b399aac539552db6142ca9e73d3df349a93837666656a3a767f5faeb703269d1574eae4f958e97f5c6d2413d9be9c857b779dce3038f0f9d5729c4853aaf65daa9e3083c422b5ba7aaaa565df3829c4e2693d99a52266b56e17d1e15b57893999987300a08d6b13f1208f6c9019fbc99d5203fe1f2fdf82e87cc52c352a7325953256d4ed77fae1ce5393e5bf7f975706135cdfd4315d871aaa6ca513d5389c4b0e3545def3b551368aaa66aaaa6aa67ce6da31bb349811030856f0b4b58774ee6fa6fe0f51bd747d77face17a3f7b8ab9953842278f23ece839d5bac123f449b0e9d0e8f4ecc63147b58f4f0c34f5079a5af4dda110d193422426ed4dfd2ea24762d24c1d9a82c43ce987c0c03c2914220a212ea19531df27c91975ab5b2d92625e5efbef9afadaf3e81aefb570f469d15bda57d1ad1730941ee2f8c94d3a2f6fd2417b17d29b86700ee9d954811717d2cbfc8d1f42fad18f42215ec2286a68caa17ef8fda4d01444e66fc8fc0dd390d29bbef4a6973931a149fb984f920313923ee685903e26441285f7484cdb9be8c39042d37c93f6a497425e3ee6634224a62d3c22c4e5edeb2073621ee687c43c4c28441442460ff342d810498fd7109851a803f3129a667844079963d2483fc4e54921920f63432c29dc2149ce2881483ff6c851bf7f7c1c2f735ec2284c397491ae2b187a1238fa17b0e56340978701edf367d291791d648ecc0fd1f1a5979f497b2dd4b9f144748451f49b1e3469323a748451d452e961625e8852e803cccbbc8ea7610c1da9949f489fe36352314ffa0ac07c8ed0a443223de7bcbc3ce7bc3c4ecb8032c7049ab4cff149726e80262d34e9c8bce97384486ebc298c22f4329f244706bc11de78ebf242dc08b9c7becc9b9e86314ca1f493cce871b8fce82b601f47f89cd3d2f29cd3f2387d03e49c12c8399a4f8b3e5068ab35764a04b64fa7564f7c7c644099d34f80a200d150ca74b956ab2d86543d9897ce051c81cfa305b4626f5d3d11d82993cbf694b15351ba46037275cd4be698f875790a50bf1cc6b039e9cb6f6e73e3d015767e3868e12849a861b87f90a7d9da7713460b6b9bfbed473b3f7485cd71a917b344429d16a77dd5f4cf470d400a3712a5e327be3182056d237cc32d1d1fdc299bc0ac27ecc3eaf7a4117e59f97cc8a7d35ba485f245ca481716d3cc9f22c847c822a4b803d37012f2347f9271e78f3d1ee0ce25eeec959c9993888ef7ccea03e4e0ceaa317d7af9f3a1b3d385d2756ee897433f9d6c61097bea17bdefee169658ed76ef3d0c98384211d6c8d9e9de7b9c762f7485e52b67a3be97ec83c7117647e97f5c61fb8e7f04071df7fb0d748267cbf9befff3c01e72fee6be7121ffe6fcdb3770bbf2f3b0449234fd149469112cc2f38aebea4427794c665b62666ecf9ba51668a9856935d6261565a0a1659a69bb49e9943c7b761bc8540bafe4824ffe2bbed144e7825132f0c99fae98891517ec6ae6e94dea69301918f5834f387ef2e7e71f16c73217923022d2a6df9f0212c55b704e7cbfc3944bc4515f58e78f8460bf173dbb80ac0bc552fae431d72808b67e5faddf8878bbd435dbc4a1022bafbf1372060792c69f03d9899c59b1941d587eb1ab45b0087694414138ea4706f19c6c92a1243a57ddfec0b130af3b719557349860a7044836ed47190433b9baf910c1ecc82eaf0bbb4edc6a8f90a6813a57ce0401ca1901c10601393b87a378b99968326bd7684f1f8a7f09641037461c91156ce415ec46a97ad4b585dd4b0bb6c4795de53927c79e0ca2f785447d4690489035da1741daf0bfdc201cf585bcf213dfd090a3ac3e1b561ca579c5e148a3c8c031af021c05ff6eca633013a4e8cf51f846879de0c5758e12057649200e9233fe0b0082c32e094479355d937aa6eb32744d498afe23e82251a23cf977d334a78b5f1cb4c353a4b08cb3308ccbb8feb39999081fcfeb28a5f46f13e19b10c81f8c92fce272fd475748189d1f84a36cc84d644b18fa7f3fd7bfaf8bdfe56217bbd8c5ae3943eda3075a3061c5cc54f479feb651f6fd4bd226f4fe37a4cdf6fe38a44d871a8938d8e1f99c96fa2210880d087be97b20101d18430f3f75600c9a46e4b26844e48d9bdaf61cd76d60e8a927fe10c029009e486f0b08d3b6c5dace748a42e16f5b0edb739b6df916b0879f5a207ecd012116fc8af9916bc2d5d1adbe725fad56950833f4959cf1245656fae48f659b59ec0e55729d2e99939d15faaa45f00b3b83e6939e554c2833ca9472a9346ba5ea993b9fa584e5ba159d1d3b76ece0e131c82f06bfcbb5a5a48445c2bebcab40def0c034cea335e5206f8b47e70bd8c20bec894b811debeb4ea9b0ae196b8a47977074165c7f1b8ead44e32ee4c95f148ec2d191f08523b331ba8baf3c9fc1556a25c562b158ab98d02530c0207a278fc11a8bd5181bb24530df43dc2b4080c2ef7243d85a46d78c9a6ac7f5ea4a0339e33f5facd335db0e5d511fcaa230a02ea067d02b940daaa24be40c738b4271d8dce9e9a427939e4b945cd8b65381da448df18d16ce17d3f8aa36c1286f62f60c8b15292f17eb89931d9e949c093a03c69b985de79bc9869c50b88217d765333bd2d89c6958b4202d0b4c8bf1c8ae6b53d0903447980212aebf26a5fb32b42854a05c9fd2555c2368506c21699e7869ab96e6735de3b9ae29b9fed40945ec481b2b8d6a257d2a83ca681579d343481a9736fc4e1c713d4b2fc1727dd450705f9e3f1fa2679791fd3c1a8b89c0c6f202f6cc0ae87ac26a273c2939e33d5de32a12f4895f66c1b2934509ffe84abc65ee0d83bdfa497743e928a95e754ff3901e86926667812618e562f009039589baf2267cc531ee420c867115f6829df00a8fa031a9318e8ba9982891418679475f854db0a34f1e7fcf022ba36bb66f959f8266cfa56ec50b7b498b211556b6d84b666490e1f341bf82a14bc123950b6d95ebc2b179683e1f737acc614e65fa18de041a8e9cc5570e7398c31cf672a2b19ea8a2ac9c256de83777c48b515e78043bb24f87a3c68489b4610e7d481cb7558d4ea64e288b52262d1ee0009f8fc91d61433ffa6ade2e015e48861df9d53b3cf3b7679f57cd91fa24e02c65748ac935808d4dad5cb7558e7d6e6cb0e1f3d1cf60e83678849f04dba55ac8307eb53845cef85356829ca1f1974a47da009133fea1efbbafe1aef13e0583c1d8a04f5a6451271e48574c542d32fbb89c30100d704f550d527ca3853a4c235f2e2951666c763161976f6695e9c574c2f5b7a3d077b2fbae3f1fdef77cbde62be8e52beaba14e8d21e47558daa6e89f278c979781a7e871c666147a157ddc27aa5c4dd2d5fc7fda4c6449e0ffbb0cf086c292dbaa2c819568b4e562219aba6344aa74ffc332c32cd8a56c67509a3726da0311a1b698c871dd887ad982f15d3b0158caa66f049759965be1f5f35c363aa9894ec302fac1599a73ca3adaf1665420f43c684529ea6640f71abb9ea15afa68cb957afd7063a00368103e0ed517d98c6a7aebc89ce039eccf181d1993741653e7c43af5032a81a3b88d1181176ac31719e214ffe57aecbe810b329a3311aa3311ae338cef27a7158633e6ef8814303aa1a5418d000a64ce88aaae6773978dc11b6bf7b80c7da75bec2af51aa0deb5fd018743fa9938f862b592e8d491b1ac81b5781f32b083fe0178d4925211b96569127ff3358577c281badeb7fe3a331baa24ca84aced02554e52df77196af441d27ac5ee97c10f87c841e02524640488e1ca51b5336653077984781bbc9f5ff42dcf6a4d23a6b5795c7311a9bb18eb1b792334e5a6445e91a1f2c77a4b11834a0eb515cca48633cd2980d3406d3112224021190c01026d2a9dee12cda0426c051e056c023810e9b389ccae7c3615b583956f61013581ad53c74e77a96399b5168e3fa0d6341d2f8944dd99465e954ef4cd994f5aa9d28d19e684e3426da121aa3313a2de09140a7d2a73e8d5ec6f5d74020b64b4326c8197f0f43d290402718748247cc810981d880b0b75f03df8f8fa76400039f8fee31f0ddb0018ffd4a8df5180e8b8df575bdc586e52b55aa8c5f2e98273dcfd7ab6b48307436d3d9dc5635caa0e4b6aad10d6c60871d38e03d619a1a30aa82c1277fd235382f83f5761ff018e4eb32391306182f47f912a220850f460002860e63c18e1bcff5a70cf3ce2fef48205865ac52ae7fcdb8ed5c4f8244d529d2865bd5e77edafbe58f866167bd4348328fd33e4c41609ef442609e04c3313f6d57c381a53b20cf40e9a798977921312f43fa98f015f348603e26e4d776dd95c819ff900d4b5fe6c0901e66474ad79048a153d0838298af098b79524cccf277463ce92812cc8f3a607e748143be9937240260ba2ff423bfbecfebfb422b612a1cc4b3dee1d8e78542a1d00dc58032679e2167a0c034565a9cf5c412d4a27720df18b0731a7422e649608967cb89d1d1d35f82b5e854a695299b58ee94855d8c5336d615533932cb9036f35b546034467ec2f577987b8cbbce578b77d553e627ff6db3b6549a29e01ac92214182599f674cd9436678c1a112b285122ac15661ad7a76cca2efdd219b6ca3629d3989cf1a755349e23ddad29e9896d9bb53446631cce57d7cc0f78fd810f7c3ebaff0008b63bd61583b5ae384bd7b077936a4cfab6d2a8988ff99898d077b2602983ca94981f3b8acc8f0de5c7aea2144a5f72653cc6619ef4386dfa422a2c87ac228135e6ef1cbf58d5ea9ab1c6ba46dac4aa8c8eded47aae2fb9ae299133313b8a77a43123357684e51fc7cf47f70cf62df2dd50c4ab31695345a2b88b578d711581c7af66d2356c480e43b6206da412d71b09cdab73951d6458fa9d5281b45102f341ec63054b96eb3b17e554a6a07ca5a451358a85c25ec51226d743273cb4f892332e73c6ba3a5dfe422a2c83da75f7771813541aa5b1ac8cdaeafa87bae60b8d05b70b79a3a940d2bca4cdca511e863cf97b95cdcfb0ee57aeaf1c267ac1fac52f7ef14b5ba2f5809a1239c32f7eb1e6d335a394dd2a5efe74898c56719d3eb94e9d30b91e8edb168ed6964ae1f8e27c98077bf849bcb1f58cbaaf28a3933ca476e58b573edf78299924470ea1bf0d39f1c8b2a7743e4ee3a07dd3d9abee884d5dfed20a6c897e0ed96db914a56346b340234643166854817aa92ca44003caf4b59ef4e7d26f4f874f87d0735fa2ff8e12620b815be8eb735ad564619c115bc28b007a72cf7a8d6ec198c67f0d46f50b5a72bb7e5ec0285e83595bc88d615a14e1ba37aed4a28858aa0a3da0d73369d3fd836eadd1335e836f7a0bd93ef056b7357dfe7068118ce7dc601c8644f54f0bd6b29dc8db31c5f2fd5ad2a1fcc896b562abd5f37d3bb2f48c3e9d1d20477d2f7afe0ffcbee58788de8abee5452fc4e8bf9739dd8e2c9665bfc586a6feef47a3377528e4fb914988e85d5ef42eef1f1250f67d53421381f502dbf2f6e76b2d282dba11972ca4729065f4489b225ad883f66ec4ebb612d2a6732cb7815aa444b032685821a2d05e88ef5de67743cb14e47b9717f2bd4b28fa51c8834c14dbe2359d2eda5e04f6cc82b3949cf1300d5b05599386b4b902ab5544af5a37c802a87bbaa7c56ab15a2c16abd25ab5aa51510bfd91f7e295a4b063b77ab688b69e9033cc05df74e7a0597d65d69f8f1fb88dbba3063c76ec96dc9e55351cdefc6ef88122081895180cc6400ea4c308931968c643b8fe332698cf476b74bb188fc1d1ed969cf1d98807505c219bceeb7ab7ba55c33d55cd62188bc1e2a1e26ddbea562577b3b85b0d04ee1e69b3d5c7e91fee14ec15109ab48089eb9d7cb990009231c38e3d6b713ff6ec093264d81b6652ecd82d192b36f41df5b6ba79ceef1f04fa869e65ac60719ac17ab7cab354dd52a92d354b5134ecd8d3f3b41edbefd0c28e3debe16184e597a965a5164b5857de915d2ef04fcb823bb0520b1400ddb17be413aa80a15185185c91c62c0cfd58ed8edde380f9a67e4a04cb2e25ac2bfc1ce0e0c777013812a8d25ab5aad11d3cbc17c460144bc127e7b055cd7a0106183e1f4e7c36f5fdbd9bda0146f5ef868f8bf09c3de72401bd4070923b9fc386d2270ffdd8be5ad8add08f1d9f79ce2a8a9e288aa11fcbac198fc18f492ff9e9663e853fa1fd58d3ed5b9aa2ea9e16bbc759b552cd6d9b556301847e66251dd81e703c27ed66f0669861003bccf218740bc851a29fc29ff0264e5d57a4fdd0431f6286c4aa67c794596805c85d9a6f6bd1bb87fc6c8b53c219084083c720b37eece4ae8659dda2fe85507ce11276ec1fc80e82acf1810c2e1612d53d7e6af10dab68705d1ae1fa11d28b9022b73c099574150d96b8feceac59f7a8ba877e17a56f6e5bd54416acc106cf0862b00bd6b317fc4967712cdee34e3c359b990bc04a7413492345b7a07b4a4cd8b17b1a4b8fae449485f60fcf6aba35a78d0d37ddd35724d713fab17ec7eeb99f0fde69d19f49cfd89028265d17bd121689eb3e32024b9b204775cb51cd6275688a95e1c28eacba11b116728a79b6b023a7e61dbbe7867eec773f1aae4c19836312d5e5b05946a4ecb64f11be100a1b2eb1b31f79f2174217b36ecdba35eb59cf7a26fa3c26020b3ac943898f3bc2f695339bc82bde829f90db4adab470b7d9b6711777fb99e26e1c645bdc9e4118d16b71631e39b33dc8861d79b56d630d77abd94a77fbcd13a174cdc8473090a3a436f211d2a6eff63ad28657726607470591286e224fdb6fa328fe7669a8847b98270b368a104a88f9de6f510899efbd10f4bfefb1bdd8b1778fd4d46db0de6e52272d6e4fc1f9dd90e476340c7b2ba8a5aefcb8c7e96a5ff44346159ca9db51cf3f5310d1b7bc10d1b788420f85881ec9e845db57b053d7c74fdb083485defbd07f4f2916ebdf813ca5c50dc84f9beb075310fadf5760bef740d8a62267b66ddbde51dfaac4f2d3c6ab16472e0bc4767ff8812ffdf938ed59c9630b8b74ac4ba2abf527581fecbb759ad77d921c1387eefe48bad1e6749bc71d6119a4b7d3bc0ddcee9cb7e3a8e6b579e336916cb1d6e77a61a0b0f46768da3c3485deb4bdbff726eefd33857ed382ccef7e0385ccef42d3f6dd8f9e0385f87ba12948f7a3376da1902eecbcff5ef4a370fb91fd9d963762cbe9de9a3621ecbf84435c46ef12f6f0537d99d37d3ff0252267ea87be203307c74ff5394e081cc562fb6b0f03dcfadf016e7d2f01b77e07ce204ff5bb8fd19033f537905e6945ced4dfea16f2acc7ad0f7e613bc525994db36cb381b828a52efaaa556693728a5344e80c01c2375ae801a619c2a81e7a60141bc127244b64194b649650a74d168d603c70fe188e3c2ecc8f31301004b8b29329996acd41b59eb5ced704a3ebac569133dd61bd22692a19ddcdfa457d7d95bd9a70f7578b3ea5c50a83e88458adfca38913153ed58c1a0b408d5533d86755cd60546da2731f39d344cef8aa09f729a4374ffdd1573d66a852a4c8eaac56a932bea957244d25430d2e083003d50463be6898af09868a7d26188c622b9a99d90ae62a92b9260a3ca078e01b2ddc767adbe19bfe5965dbb92f03f0d03656f8f020a170fdbb1b7e3118b4c6180c465533eacb06ea041a03e3c5d5a736a9aceb7c53a7a837a0c20b16cdae691e3ab52f477ea1c346702af472f118a42f35764375428dd526eaca058f5f3870119caa818a01f38bf9622bd8278619fa01105080d73140cbc1ab2b087835562adda82bd3fc15f00df73b3ca61ce8f37328ef568382aecc342cece8ab1b8fe3475f1d69aab3b3c353430e0ce9635ee6774a6fc4d672e5e72af015308defdcb1797aa7ee58122467585602f92567f097e12401466e8294338c3c46e9d3a173605ee60b327360428ee1c0696cbea84aa632d5ef4c5e0eda646575683ab0cf310e9236f20acb292642cef8f3b4c3fce46d04c16032495f3eda89e89dee22a88d2b4197675c85c388d9b1c48ef5a519616b65b1c871b26d8992a674a76738b1a88650ad27a7d888909f18c128ae019f425a830a86a4f1e7d3c8fb42cc4f5aa34104fde08cb0e394c9ac2cc112648481b094167de4d55abf90370a7d558a0bdef49955cc2753c9ec993c2e782eb80045cef877313b5b09247a882a9a54859a8a6735a4c08ebe72e2acda64861cca7c144a94ebaf49b9fe74caf59f54ae3f3fe153fc78f3256dba90289ec267be7cec8ab26c8b673eee4dc63aab41be92994f9f41981f6f9002cd8af9005680966fced9f2cd1781324703e54d329bdc80697ef46a0d3b726c7a9f17e220bb90354d24123128354dd3b417cfda29f31fc9b1561704cbdd915bab21f00d18d5293fadf8462c2dc17a5184920fec0e3855468b31366c6ae58a327250e81322fa165260b9cf851f3b3207f14de8fd17206d385104248ab330031802b286539eead405e2a798eb0bb30089b95cb1de36b07b408514bd7bb87fd08276c92460b1ead70e4f6a95e2d20784526d631ad157fac28c574cd3346db52af57da1a93c69979306ea29edd350ba74c36b1c8dc3d3869033fefefd4835c159f886959044a4ba2e08b6cec08e9d1a6bf87e882834f177434c1ceae488582b53bfe84dfcdef726ee5ec8f748a2e0f09174ff0185dcead5f51a1a8003878ef21c85833cf9ab80ac56da6ab5ea55af7ab581dceda4b6da9ac80a3aefade94f10887ae5bb12dfaa26411a825b928d598cae6bee2b5be48ceceeb691524ae914083ca4db946529a73085124be1eeeed259d0f168517a73523a5dca3927d542295896c297668b7336a1352de81514d4461b1bc7416183823627f51707390703776f7ab3062efca6014cf3af1467111dd53b6c481aef56725bbc020705695b6d1804050505f115244a6706a5256c12b7bb881a9d3a8ac2fae63d68b70abe9fa2605f73e3e88b9d080a92335e586e5f6d35c00112ae48238b531a965e99451a4069b45cceec20290976f4eef5cbec2c6ab123971718528c4ce9060e530e1d4e9d3a75da820b0f863b78bc000018c453000410c38c0c343d661800010840001a0a50538029e058a0aee1ff12cbd2a88ae5a17d3eaae631ee75faf4a6f7c3b4ed98eba5522db164395e776e9bd329f55992a5f652e9fea88a9d2df29c1e02b960f657540186cb3ba70004ab8424765cb67405c8c25cb1c11ded43a1c42500645141b1f5ca2cae2821801558d29559ccb2fcc006f998cd9e30843bafcc62b6e2e1413453b18d84f4765c39df0339e5a720fc14b33cc5101205c44fd2467bd92c2e1cbb899c2133909f805c40409bc370470682e18ed2757b8a3b843c39c75c3e72c683662d863c48693ea8da7cbe99a10d4c23830d4b48a147e6d3cd559b3229ccf09946c65260d40fed7b34ad292067e6ff8fc7a1b3bfc5b0a39c89dc125b2fdc125b2d51e41b8e314d174186c859bca6c05e8e6225e4c9bfc9f5af1a9dda8e97956bedda2c999bf358c6329ea99c30162bcdd34c38884e4da353abb5d6aac1180ce697f6fe42b6d0c21f39e392335d7bda5639308084f00d6f2199e594e6275866999fa858af07d6c42f734cdc3304ebfe1c964a1206b20556dc1948eee11bae82892ae48c5bd2466b438a5790a2f3c05d84ecc1c24d8265adbac00e445af487f5c81997c9aa4c26639946a7cffb5081b35ccc1823fdedfa04d1f0c0eda79e3592e3f617a1e198e3f673620c321cfb678edb438e5b84fb51738c392e573b346cff37c71c957eec815b84fe46bb508f8ee98eb6695be5667353db26a5734ef6baca6bfc748e5230bff3b6e91d0d694d84bc9fa0474790e4b24ff6c071bb73765c881d8aba6d200e9cba53dbd8351f5b05c769396e2b21ca7130fd83eb01e616e1e877dd2247e9e4be4e2e1c616e11e66ab8bd12db3f964a258fe3429a86c4a6bd168e20c96d0e9caef1164a19c3fc19a2da6fcf6d1bf5aa51285da8fbdf363727d7bdfde0c3f5bed2ed470edf9b55b0fdf6e78fde9bda08641bb7e547ee47a1f6ddc0859e0da9e8bb341cf9ebe7c3d6c295e511f9beef3322de5ac11ec4aebdee46b1866a35f1f620de16517d7912fdf72ddf712e2010f5ba70b3d62de4e2f238ce85b4d9e32a47f2c7df1ada14d87e17d3a86954f3b4f9385dc11be4cb4b696302222fcc0f09b8f56b38822417e6c7fa9b3743a12d7c6f9cb743a18f646248a4972191b649c281e36ffca8fd86e36571bcf613c717d1b690391ce1d6a27ded06285bb45f02678bf66540af45fb31a06dd13e098469d13e0c7843c660ff05c42167ecbb8039a468df04be3cd93b0a4b72c6fe078ee2b5e13712b945be1789be2e044405e5d4b45a1fc7ab374bfd31999365287466cdb7ca3c9d8990962307ad959b93a3b4bb2bad5b87638e4b7bc871399ee198e3ceafcf6d2d8eea9e8e39c2ea8190b675b4f98bd4ef2ced7e4ab939394a9fd66deba17427b7fde55c58027d4f9b97f26079b845ea87359cda15d80bb9c06e4f9dfbfe0a8a5db3859b87251c7fed37edfdb5d7e86b4184ec7f2ccb6d93deee4e6bad557bd7b4f75a04a2c2890bc356e3d1a8d0f7e9c51e4fe4008a99b1c68a7ed7021a36d40ae3fa8f1d3709a280ca7db9520b1410e176ecd51848d44b1bd2a54eff8926977ee743c8438bf4c31e5827240ac74fb46b76685e42d67440320c24cad61f590797527f7b433c7440d6701252a4cf3cb4fbcd93903552d2e71ea72cc5fab47eedf1a894751e929b03aaecd60f8542a15028140a8542a1901129bb45ea6f1f0ad5e7ed4bb11a7a9ee7799ef71d0e1ad0b045425fc48894dd51f4f53d6feb72e87efb31f4a328d4ea9cd5d6fa3538aabf3e10593726ecb6ddf0fd180a4729bba1914d41ec8f7e88fd91e887b4bc281c43ef3d8e87a311ed3d2058bedbcb9003badf3c50fb7e6cf543a1ef2ae87de759db6243ef51d0dfe285a31129bb5d38562e046ecff9d85aae7492c7e851b8270301511a82bdeaaeba542cb93917171c857211046b11fa11f56496140c73314dbfc0056b6182143016b77beaca0b1825d987909d0617c172cf546a5404172957a5b56a55a3dcd4298bc1cac10c542e18524f868911330315b74bd9e1e8c92ad30c54936a52a47a443c29508af5973255b03258ac8c1a56260d2bb386959fcb75f1662335048f8c10ecd8ad1d50b07c7e72c0aa3c907881b504005708828b284be041446bc62d2fe9a0c2cadbf24f856d9d524604c1375aad35a238a8540dd65639eb140d0800000008a3140000200c088703e2e18040a20782a83b14800b7c8c407462381608932887619451c6186310218400010118819991ea00be231d829503017ee523f858000fe934e6bd14408e7c2f48bddc293628b7668cfbd82a34b80ff58d0de48ee977fe6222a58955f1a59754c38eebc5b7c60c4662a7a14ad62fdf93d6308ca6c658645293f2e1525337a4beddceaa9adb35a60284b6dc3cd149aea25d23877de2a0634845399c9e97f975dc4b0745e765e4350209449ec12970fff12ca61edf472a8dec65c563683a5663114f67f615ea3374324360f9b59f8b8f8e925bc3c78bb47c48c70514cb1321624a297052b30ab69e8bf9920771daf3e3d61741ddc2d6721ec3530dd113343ddcdc17c4418420bbc44d145f2d1019cdca430c21da2ec409670f01d9bc8f5e1862ff62a1efcde85604ccf36a60e41eefb1c51bd54c743670b1d093a14bab127131ae1be6bfe2fbe49c2faeb40d62dc18686b29292347407b046573618310d36dbf6379cc9a889a3e08101d814272c68e62035168fbea7086647677a35f461cc0120f0aaa2516b38a08a94216a1af50e83a53f990341392ac1eeb63824c8f11cb85e3a110dd3b03e72638ff878994f9a18c49c83dbd9980321eb172f4b02603f81b42c38679fd8607d6870fe780c11b9d4f18fc5b767d9abc51d2150cb39f0e3c8242a02517254c14a400a37b0614c03a2fb04499aff770a17c9e0235fc2a6df0f0525d6e2803c56774c8da1946e0a8bfe47899b04b441d37e92841480725543b64421e69531b6530a15ff2762652e0cb33294d41af9495978a48187c25bdc248fb47135de44f3435d4c227b7496bfb3b49f8b91b530f7f94fa60080fa9f42be88c1634fda7345939f0c5e0d08937a205b297654355e34881e49438c8c72b0fed9ab6c76bbb98742a8f925367419bd2a3db73d43cf59b8e80988191b498d19aa73082fbe54b07f2f9e0e32917a77b9631facc2bb9a24b39108ec8df7f477e994587acb973b682fa487aecc635b9b891811f41140f41867221a81c41df8aa24bb1c86e2ba8055bfdcc9293845829ffba1d3fecc63b2256d91b01e1abb6f6483807e418ec476c25f1b2571906044e2e19d8f54dba583a52724682627cb320d59133c676da2aa6b3a56eb81983768bdcb47e34a4f07f9fc972a2cf1906dd924583587851246d84704f0e746604fb1ad19ea2f9db8a4bf2dd6689d9b0ad1320be5b037fe0e4bbc09d7a659b83cdf2c05c770c60ffe2f8509e77cdef3e6564aad574f657199f75f8f4d06bb80f0f7d322f778591aff05e6fa7cae2503f6b22a3a0e979cd644c86443a9e245a7946d7f13731c82a53c04771922436f8a7fb7e591329f7d456afe2dc3d73b92412e8c614fbde13a0a3ad0a82a6b2733b21132876a7effe14027633bb54b183c822787f1eff91a9628b3c1faf5ab44a14c909145a0ed886ea90d8e2d7e89577a32bd6c2b3dcd543749d839a898fc15cd9b29f1c933a0a48f5b354977e01ff0d5d021e76991e152b354721490af95754fba1039494ce715b34f82e2bf47ca3fafbf11f202f481d7dd457547616e1d373975cdc5a018ba09234bc86dc91d1da138f0752cdc0e5bf83d1397266496b774657556d41b2362e86ead366b7783911866bb7c7f441133891c063be15ca86d977bf421fdb963426a2d7bc8179ce6a77eaa924c3ccef1ca2dce60a6d93915a0ed72ef1efddd737d6e1ff3527a644940c341db1af6fa9ab93676ec97a9f2038332ab555336888815155d9dba9a1b8e03f3dc4e68fa81003aea8afb2fdb9608e48f8454736078d0debbc0be16a9e7101c7e6559e1e2f6b9793794426c564a0ac2612d2842ab453974678475b2391e0b8d9aaa26e1cd46f96de73e3a94bc92ae5d0f17d7e18528db4d444f2837f33d93a3f75e2e7796ed4b8031ee25d3c8f84bdc11a8298c821630fec94e76e46821cb1f975c3351414a4f9c48379ae87d2088ebe8b9116f9bc358cf770e9d8b61a4248a16d2909acad65c2b08a6c0dc60d53d09c59e838c4f0f1c716aab44e1dfd114f2294f033cb843edc6006664473d262991c1be3f261817066fab854d64570e23cdb817da47be1f9dac4394f8aa231d200dfacfd960e0f5cdcf96ae9efb0b07f703ca50b2d3b8b3d3cc0cdf194e84c676f3eca501150378d63684fcf4613bb32837a106310c9ef63e227e5c33872ca6ac421cb9e7c7d864352192a90a146e0314e5bd9f84ef527678a609848592d523c7d2c612ed23509920303599cd4a0ed794b0a5064d734c39e33bcebf80baa1be98636d1787e1b678d532253523036f182587722876f240745b41c385634f575ba32efc70fc162a1ef248ae23f403f5aa0a443145a76b9bdeaea3f92279f9c57af7c0d39d169f7a40b7159b1f0fb7108cee3fde500e851f6e57f394bcf7520c3da842c7755b8fa9b7d9b31eb787d7a2f5867d0b87433608c164c8ae5edf1c00de6db67c984ee2c6ff6c1a894f2230f96bc71ff709924c2d2ad0fd001e2c9ccdc735697168cb56063b188b193380ff0411ec4b4d77385895e7253b2371e3e4bb17667bdc9f226647bf9d0a59b1ea296860d9fe57fd70f696998460a8220749f2b08d28599825099efc44266468207b8df5eb5591dd4a00ec167e27ae536ae8e337931542554fac246b6f5120e0fc359051c998840edc109fdd81e56ce4ebbf9eacdfab1947f453bc034b3d2c27dc0928bd417a07cf5c79e225639a2f792a028de6885f75fccf8f71f70cc0b46c5f1d539a30d5e812f34afd09510aaff8fa4dddc0822549cab8e74126dea9a89aaeefb4f0307a083617586a0e2c508ddcd706162e22daf2ab62b13ce3d99d1fcd678e058821f5ac770d208c5078fefed67aabb894323331d3fbeb9b07ecba64aeea4e47918f6afd2256903897277bb1dc319c9cbc8e2ff6b700a2f99a7a9e10e4664525d6a821b690f3b41afca6d4b504aef3129a3e020a499760829b0086651e0fc8262e80ad8d7e8bd501481a2599666bc9a91f7e84f5184216793e54f10c1ac7e7214092632e603a6fa6c75c77fca21451731fcea82a5eacf26a0e2a06731e8f74cbdb7a77ba73a716ccdbd220cee1d266657f9aa96d9d1b9ab6b9a63ca7e56faacd8a19900d2edaec3fd32bab0fdc2280a4613f46d66ee7fe8523be24189fc9a1569d4d3db08e9d673e4eec35e862586773f2126ed00cfa240926df00a4e6471533fce91396e116474c3c0106f85291e72f4dc2f28163a115bac0c8f82dac4d72b96ef6141bc6c84a0271cc8ff009c38bb6affb12ae4df714c8d16bd880ff41bdb235e4f4f3679ed375198ca3c417d03bca9d68a9dcc8721a004479092519428c9942a80cf2d1fea4bf1359a0abcce9bc687105667e614333327cdc79f46d82a75f2b106c65700bc7c2fe13e1b3db829f677692fe3bb93ec59d188c96b38ab8cb27be0098ae03ba17e35966e73ff587cb7872717d8423254ed537054f98497aec21238c0916e15568d0a4bb2d348f4bebff37cd0254a121ba9dc099f059d1e26e829567f7ba94892b2e6bec56ed354a7c435f4dda696e12322fe789508ff8d59abae962ddfdc1f6d07a0a792b6c2498e492f0fc2a9c0e071981da593743964466e5aa8519997f355ff202c5b53f53c0df38af0b94cbf1f5f1c0a490c4e1e82d56c69188a612045c218c8ffbaa50dec70d26672b44ffe742e19a7f6fdd2663c58256965e953d367e1b1feec4362c335c1f6f5be3f2e2678df5accab67144e5f1d8c7316aa5637ef939915997b923018a2dafbf67e4c00f1ee5b0052d57454b90c204eea5b349de4f8658b1529760d362f51cbbac81f275aa24258a1f6119395a41b059d16923bb865a86be5d9b31bab77e9b0319eed1e88ee80cad6f9eccec4e0450aab8881e3b932d2cec9bab0c695fb0ddba3a238df61978543e1bd7e8555dbc85163f63d42f58e2762dcf7d05fc1e48984130eb09c6df7aa6f8547901942b079802dd79efc0763aa40d4a1290a9061effaa39b6b0db3d38ba62b4ed2e24677e4b5995d588bdaa417a52dba137a069e954c0bf9d893e5887a87478da10a3e5b2d238343c8975932ef3149c139ce0e52d704ed288279dd4108868e0c5fd4d408541643466f25bc4307535ed3bd21224e36b2f0a9c44563e81765c487668acf99733ca5eeafbd6ec2f03f4a4ab0da67e70c0404928832843367f7dd8dfa3e798cc300f067e646e4cb039be3f0b9ee84e2253a2689b4b233434dc537e5285d1385b58062363ae6ec809231eff1f258cf4839f6488b753c6b796ba50da9ee60ea084c936764dca09493d382871997036073667513e39f7cf84daa19e440b18cec99959a85441435bfd08fdf62e51b895b0c17d91247681ca79ede288f1590a41a93f991ad39882360c5ae27cdba6aaf167260429c5793cd5ccd9b1adef5016e64d981bbc6e58f84290e594de303dd5c45f7fe94c4ec6308e1ebc34decc3c5bc0fb7047d05e465b311ead1066bef6f532394d299dbb8d7171522e1b5cb450bfc9b4f0b8cf4afe402cf115c2c3d56f9f7dcb4428341ef1760e68a058af0e807bf42a18adef36a6c8dd3f63957416e08f4fba4f40351eaf5a009c1f3d50d7f9ed3e95fbae627b30ee21495855a4e512850cd9360bdd803bdf8449ddb9ec73db4f2c283f2ca602cb662438f6a1e227c3c135bcda7d698db6360d4bce879e81e189dcbdbd124c04d95ca03d5dc274f0f5011c68a5791f7a6c817d95d2bef506274f3b788c44a69464f2cb0000f3d7139b9ade9ef87659cf299f977d66c2ff1009b7178054ca3fa7db27ab62178c73cb38639ad5ac4b4f9c90c09897a5626750823fa3cc05a2537fd78f294db47a1f3a4a3f0df45231440ddcda4061a57807b421ec3c018ed87cd8fe48770cffb8825350f0ad8861e7a64cfcad27a32ea9370d26e0182db8f2db2c6582717a315adb60f48c00d2a966becb3e52383ca89c8012698d30286eae20cc8eea74f4011bb78e021da309366e49d047d1418eb580ae9b41bf260f1017d2f3f22b04061a0890d9da9683f7cf16a23336ad5010d61563857c890b1e267f11647ab93899b5f62151757564adcbc5202809efb6230cd1d19947b9fe6c38af442929805a357f3c9a3603cfbb996721101a13c5b2617512b416e7dec41999db32e8088502681933ed74ca29c75fe1f1352b4b94ff99731e1e4e79938ecda428228f29f160430a8aafdd90692c71b0bb976d944d1653f3c5dc8e567154bd8b756253e0e7580c0e6fed26b12003a7a8a13ac5ad76f45f67413fa26671ed93c0385c6df61b39bd6faaa109a0829e07143604f4801e5720458188e52959a5d7d6baca94f853d4c7065bb0bc0a789b60892ef01a8d6a6651be0a5803cbb28b5f3c3891b107ee99424b8d6069313d2ebbbc35e62c5805f0c60992c5e090ba1c32fd17e4d684ba47b851809d60113180c84adafaa24b7ec3bf08299051f3980117945db3ce2fd775d91574b1e4b3cb607a488eadcb387fc028e347cedd67e5163b6a34ab912383e3726ee01b85dd017e3ff17a06040f0357e474958ff9aa76a7c45c289b5ff245589b4f06287be8aaec2ca4b1c9c8f18a68c1954cb195a915f8b4cd8edde3fec5a9ec30fbb5496450144f8e2479b68e1e1ddc156405f45e28d0581eb1779d25c272096a1e856c190bc399c0e0c0d4d1bab1388b8fcc69e1997b1397ee0080afac909e7c045b2b181e6c6591e4ad92ca8fb6ca2e1602ba3d5881090048e7cf52791a5acf6ef22e49d18cca55ed2041ce1844555aeedc6334ab92b724d2f8962b5c264750a3c11f111af0fa4befeca44aa2c441726bdd51de875962ee9d673d212577e0494b893dc9f1f2076ea2b3af4555c2499f13d27d358884d030984c59edb302313af9b802246fc50a9664702315ed2c0bed99864461bae88b3e40d254a131a20a7e6ec4cb8081b6282a7be3a6e64c3ad1a0134be3d5dbed2c6932403b629b448fb656fc6562b68bd51bb069e162e09cd03dab434501b48d40481cdfcb9daabd62da73ce2a8a3bf20fc615f166713a7fc8be1ff082195134ae95c96247a4ba918f19fac2c26c4d5523ac3691aa5a5c132a133ad894579c03b3da7628cb296ffbc0f1c02b26d2fc7944e67915601c2d5184b79ab07f6119d595eea475d0968bb2046fa9fd0275a0c9cea1a1ca459abd0e309f723f2d4fcda9fcbf35c0287cd846c27b58bfb2df41090a7cdda70a508c473e33e733ede6fe8faaf627228bffe8085ed2f40a6936244ab85aef85c5bca5d02e0240350d4b564f65d6f27d3b9097fdd8260179d0eb1fbf33905a9dd9b693abe278436450cd299399907fe14032b97261eeffdbb20785798ad16774c7499abc7565588beeab1d9b62c6090d89c31a437633e82b1c861d126619c0d2537069f7f30edc2a2b3f89c9c0ef202035d7fda3d44ed9e65cb9b50b349766205ea63e24fc764c26ee49702dc836b427413b6eab33a95f77e0eba02375da3544ec7ec50997d46808267f42baa67ab44ed7d28aed67c781f8849c86f18abe4ef4c52612525d225ad2aa9335e7a7b6da33585bf1d6f4b592e853ea40d67ac1eb14af71ddc3b482026049b7146318c5b95051158bdcbe53a46329280273f235588625a9e726ff33c793ee859d082bd3151694f0f89028945fed400869570905306138e668650bff26a7f1b02a89654f0db86780258bce146720f3a14a80fc0cc503cfd3265ed272291cba4651cbdc0e4c3d54233b67a994ec94071e17b10fc9ad959c6863de13a3509103ece71197154f810b28aac71b810b982c5f69555cb0561bb3ea3b50ab5ddde324b7c4c19d2fb1972fa2a3b74e4a10354df1de5d49e35a79a8291ebf9b2fee7f6c67fa79058ee19ce729c060131d2af4fd861b510db865088016e153b3050a407f3d8754ac56616cd460a130f98c50babc8e9d575658cbed9d1d221d8b00651cc208058afa0b8310e85cc80a7ddb6eefaffc2e24f7a9bb7d886f1ab89ea8cd108b770f5b4ae139cacdff4a5753a2cb2a986ecd8d1a5672ae03184621fe4e08e210fdd2d3253ed57408c8d9f8a1727bf22ff4810deba87d44c8ebb40a3d7b1bb00640567909b401aeef254306c34412933e4a83fa0f614c494617c85cbd19061f9e8f1cc778453a8f749ef7c45c2ed2a362a8a9333c781fde05dcffc47a7280b957c8e75dec96b78878f9f2eafd40486538f0dc8a9e39944c785d1369c52172e5804b865177c45ed0e44dccb5bf2f1a5a6ab004e73e5fea79926bd0cea3a79e3a93618e933c9c954fa3a37395753930b1fafda91895b12c721f475c1efdab64105c874c130a5755b2daa8d82f4e39a095d9fa488902783718ef9ad1bb24e65ad1c63d9567cce61e87f6b5065a3e2929eb8d70e20aafa251934ecdde984a68e2f1955c91ea19b4e72a7d97c4eb0f85d5cf6bedbd8b12760395cc5b1f55fd90b9dc34f130ea2afad88ab917a9e66a61aaeffbb2946c79c6b23b161440637c1e1b19d7a79d489f52d347dad34711c3dcbc2a220054907b8b7999ef97cd1fc1b298a2a2864974c11208252cfa11882f9bb40d678d9d05956cf293512ee9c19b81fd6469576f48e8d1ef735fa2adda5059227711937d7cd7fd1b4f82fbc2b83b198759043ed751758359cd6da4fe4951974b66fa6156f5200164607de9b8bfb0fcbb561625f65e683200c49793afb5cd2f7ae0a9d5b3e1aea03873e66b1d68336534a935e6574c593d589b44017bd5c1442d51c1377a1cf7a020e84c220038eb037822945d2066bf8bf94383348cafd4ec43f15f965eba005dfa38c5f94d79dd0173418361c2652c4ca4014c6d0cda75a790a6c3b6c77e75d0c172c28e944d97def7b9bf023278373652ac0cd40851f94470874ec892d80e4205840504dd402b76863e2303983f840333d48bfc470146927868b43caa0f9fbe56af036f96627567684cf90fb8bc94437a27313e898aaf71de55d93720a664894be15e04e6b0692eaf21fa7ed279f8ecee91c9fd8f467f3010c54e58b8c3ee3cf83588622120379851b4cd506724796c55f7c137466dd480ac5c23d954a913415362dc572455ae454a2fa6092439b9c6a5632d84ad71aa96dc8574cd10d4143870757fda0eaa43bb958222f8d4f7e664e680ee7214a31420da84cb1fb486fae544dce469705c01619d9c14777395b892979c8276f4e656f3ff1923bf5f7da8e5dc75a76dd63ed1027b3b2512661992528744afbcb8384dc81d9c1addc6d13ca3b4ac70f33e04fb5c09c61d7fd5514c3109453fba7f7376747d22356e95a6c70e4c2d30e43d4f8e52825e83f163451592793fb1c708164ec42cd069b40ef372faab79aeb5d08e02aba14c8f89772c5c113ad6d4c635d718db58157d815a4a540b357f6686b29886a4aea35b1704d1423e1ea514af9eff46b03f7e40c146befa2e4a082743a62e493c56a59388c72c3b78637e7bbff6969afd01bf16b2fd8b8e0759dd5281b2d690b5445a2600ba3bb5515997af3c8d70a40faa3c1b6087b63274a8b953c88c22225637f931d6317e1d340abfe51dce3c8dd119ce2ef6c68a957288fa3e424ecdeaf16857b9189727cf047ea352b7e922e6735381b1a3e739024cfd994f4354e97e3df4227f08e61f1badbf04485f10658a42871c8f3df3f360f35c3990876a23d97f40af8fcad37b82ed38419ad85d44b05b3792b69bbf0a538118210d56c9d4333fa67820e086f4e56ad466e606c84f4cc9462702153efcefb9738e769f499ead904a0a266ec8e39eae699386d3d1a7e69c01345e61371e855938d850fdc6fedb294ae41bac012c82413f3f2f3488bda9195b8929b8c64d9e603e042d3824816f551d775c02bd3e042014622d81ea1455d3d8680b9020ef09b143345d436b4465d050acaa6bdd20dce09b342c0965c976d7e9c25811478f4935897280789c09e052abb292513246b7292ef97b1517837dbf7584d7826355e0c4c82ef4bd88cbedad2485170a98539c7c72774d0b2540bc64188c89bd4c05e44be5e66bfae8ca6d1844ac0aa6cfafcdb2c7ea527bb247fb12b663922516994b220407241a8c15df45c6b444b39f42ed0caa334e947ecea01e0e01b4999fc8495211cd2f03f5342e3dfdb1f314381cdca1b12f74ff7cb04bc79ed7b1a33347745c388eb07c760114d84ca408d1c2c6eeeb920ddd7f4b89be9c9c319e6a46769846ad9ba88646391849671d1224732c42b43c5fb2675a15156caf76d5d332685408b87f92245e70db3c999e57f8ee08e4cb6b836568e291631cb5a634c018363113cd8b3cfb6bdb6e542bc74b74e574cbcda6fea681b1b81da88f32a6412873c804b49388c3e136da31179c529214288ebf626180cbb29ada0c0e92697a3809ee35d5750a928a5a01ea0ac8e4f3cb615b002bca4909acedda0f333409b6a8ed4e3245f99bef2a4fc43a73bef2fb7e0e3d0e7347db10beec567b7f6d1a0d95bd9ca1bec8a6c67c091fb30685e80d6f9df290de3f41b8bbb3a4fec9566cea4745b2db16939930ce3bd515f85d5b054d88475c0bda4162217b89aeb02acd805495fae0b5827ca969cdcf76bd89480d51970bf68df2eea4a53d0febb1f76761c0d640586cc66e62c8f85144b571096a6c834dd44bbf2ecbc343ceee97e0570b77cbd8194313241a8d6f814684919f26ca4f9db682b84a6d591f1627ef86871d79e8a3d83d84f62c0c77325bb241a1b45e6580df458b80d45efcf3ea95b322aa279a250de6927100e51c66d354e259170e4afd76033d9977cdc7e34b2846d1e69aa3ba28c12c3b476e67b7b868fa73353a5cb2b228ed5ef9e33f85869e1186e487e5fe96b16a9b5a272eeee82fbc525cd913baa6052c51345e9e75a87570bb2189594c749b3f56d395d3c95392e2f4efd9452f95615b5ba1cb1786d18f655fb0ce96ea9525d003f817b37329f8c345bf4eddef37d1cf1bd719028622cfc2b325821db19f7ba70ca00ae07fb9e6ff0df889c884134f86796a680473bc76ad9a9b8b79ee7ce6b782d652615554de6fed04bc06d4c5f3bce8afa8171c83943ccd4938b296410aa9cd437b9fe052d0d9d2c078716da054ad7b430e9c20ed62cc48f3b0b12857949afb94e68e2d7779447ce82038a4fa8b21276704162160b5ae71a9a9836070e28496a2df502a8c404f5a13b6880185794ac46de8f1e1450c069cef43213e6d7d067b47545ed0a2bfaff20f11d798c13cb7c0ea1a29814602aca5d6a7d1116f97fb6bb8928afe32fc443b7e03448dcf4874939d2fb9dc54ec2be43f11509cc9bfc49e80cf4552cee392d321a1e4529a54b904ac7a88097663d64d949d90f9df9482f866cd027d9394816b029639427f392b781a70971c310ae20e3591e59c76dec0c768c1d3184d78891321861333118b865d15b14f08487316573211b30fe70bd8cf11715acd5278cf10a3bea32221d5269fefbda5878ebf5e45ddf2f580b1e0a1f19e3bceae34a3ca7159d3fbb125fee3b28405df5d8e0ae8d9c9cb25ea15711ee33faed09b2d18771b047053ee9db5f54c8451d475a20e5a17b14d88d1c8301264099a13358d0639bf96f600c542a812424348cb027f0497f9fe7b13e5732f99a389429bc1f11394787aa361f293dab8b93b52a80a819256b34183c7a99e35c1017c6de0eeb1da011d07809e703394b3ec37148ca8fea80e8692c19ee376cb7c6ed665c16753b526e43c32ef1f1bd40ace941cb2aaa1e66452427fea2ba8a75fab091612876a1e38d134474b6dc3ad6b9fd9b3f94809387112a9dd0ef897e794285fb66e4ac3eb393087579e873d8b645ca62407f0ab9d8095e7d9cbf75008d63c3906ddd2f69b194ad87279b308c445cc5a508f8a2c0227180d483053a945664be07935c3d10bb00bf16f8b34444fb3566a0bf04d0df57bae4bdaedb39497190f3556c51d19fd7353f41971cd0b7ecf145af628b364c841c6d99ded3d8eeaf3d12bedc1288585c112809dad72c3a1141ef622ca7cdcec4ad074305f961212c497d5e3da196ea4fa4b87e00ba79012d0914e225461a172ebf1c89cb49baccb27c31383893d463c2ebecbc5d4e4a2c3b54d0e38ac21b90c5e8a7dfd820d074d70f2dbc5bb1c3cf01c3d8153fcfe8e7768d801dc8904f5f2a77d0b8c91dea52209aec560413126372ae7adc81f0b6ae0d884be4298a59524ff80cadf0ed8b13804f9ee9a5376cc241d093b5d04bb43d01633c1c95082b975a7bd22f27878793d7bb7ab12a665cfc727bb4b30bceff3740683a3d17ab1a07db3e5aafece1ade5cbd1c6506e4cadcbf36a82c44c8714899b699bf1a88637b66f2c9a529b2c3875bf03b4d20e451bb4411dabaca8a03dc5cf031028da62da85bc971de37975f9f4d787cf24de9f236f7fa543f59c33b8da97a6c43227be219de69717263d78605fd8a262ef3bd56c1264c03834d1dff8cfd00fa49b9a18e46bb76633bb89227e609978cd67678572dcfab9405093fc8f92fa9fe8ea643ea110080bd1bb65c107c6d1516b5d8ec820abfb7948d8a91bccedd2219c6f6cb123ae369adf1cdaf44512d425acb64e3229acd232da5259af0681efec2a944ffefeb1cf80774e41f96e488f2f4e3d9e5252364cbefc358e8a3603e4eab29bb9362d37c3a0d0da615934e2d83c51fcd725a16454ca4389ea59efefb34277ab9ec678acd1c8bb2bd39db618a5816098fa94d3fd1207fd74b547ba1db55ae113048074599f588083968a4b4b85c0c84248c2454c3560c5910b455b2a3c58afd21f71767247e475082ab953b7e45f5524e9582465da05eebfbd6997e4f992b2f4f5a4db881c06c0a4d7d67bc1f89ea57781af84669ae280a0b005cb07592305274b13c07cd274cf89909791e90d7ba5677cbc703b3ac5b6a2bbc0458d9430b0f4e52040706b70b28e0a3d51edd8c334f4659e53ce3ea64c5818b52cf7a23b852634ae66282fed75974027c7a2fde03d72f33a0405017752da647fcc6586db16759d20ccd138705eb10887dc2b1bb9f8dde688f2e05b4cb06bf1f171dbcbd80c00711a3b064f5078878e0587d35072b00350cc416c71bffc577ba38cfe9e967af0126ee13f70d83e033a285c5d09334bca6c27ba71d4e8e328cd8a3824c3210daa9f7d9a57878468ee0bca12ef01190798b1a3ffc4228f214d449333111590d5e9085957caec71d2b76522de183abce98e283929bb0c3c32741a628e284cf4c42337dd292702d28e9a063b65193aa756b9b1eda37e107a249721fa66e0f566e236b042477cc24498bb8e115ecfca982a118f28991640a8502217a6d9af9a44964c5451f78eacb86ed401f0986db768170609ef253a239de19d036e78063c364888868eb4f10c2f1111fc102250502d7c51fe605aa6002b85e909bc48b02bcf7759d2e4d8c4208ae03b9c850bfd5234c496ca985aaeb6efd7a03c2916e8861f80379887ace64a8e5f198dbcc28c6d44d9c4ce7e529bc0ca89ee8dd376702f2b4a8b5c505884c3894d7888b7a620bd351be945398c0a85df348a5c5e1e617938bd8799b804ffcfcfb56b9466af445b4c140b745c255f69a6c79349a4c32a1cfd44aca486ff290fa160413f9fd7e16088e5304ff2428d209c36ddd3b0f651d636f423e24e3320371b8b03a12f390054ccade002aae2422e84fda2f007b3e7f929ceb911de67daabeded28e3995939401ab1ccfed6cb211e1fb8e9c187518c63524fef89127360f20a76c851bd7c98df9980922f9671015a120dd825ce4a4e670314d0d5923d733f64cbb2ae0954e47e2e5c9cdcb05f3f7a0d2b91111e5c1d641c654b3f12f543fbef36f58b32b80270d27e48eeb3d44c9987368972cd5938890eee583a4528daa243cb9d2ade01318176a1ec83400551d746c05257377d79dafe0e0d5e1dd9e0445983c947223a40ab65dcef9f373b469a651da47e74725e73d077ec8e6965439cee220736b156d504384abb47256734552ea69b7e3c8c6aefdfd39f684beedfd5addfe6a32c8563234d1c9b611a3e59682de7efc3f9cc9523a56e9d1beae5aacf5140103989c2fc295ad7a234caef29f09fb5e6c8108683702b27debefec2078b7bd8f30d63b3dbbe5a09ecc83aeafad2f8a7bca3eb97811049ac0b7062fe9bcfa42ee160a889461a9d8480ec0e816c7beda7fd032f960be7adeab3b9c8caec1322938b0c99fb87ac18e95726d3589a2bd914ee15614c8e2878ced75a91ccc2b267971f6206033d6c40842659c1870f6f464d0c4966ca4eafb8389cc5c979f83f208c3a8d5ea6a5ecf2902a3fdbdbe7d55b5e16bcd1e2d120c58a4eed2ff44c5a23af32a21eafe5274ae675bd202b1781b7b977bc458f31341cfd3a5fcdcfe4d16fcb1bbc71d36bb536bc0b41860ddba15cd57ac95a4ee5a80c2ac4628206b616561048263bf22c5ff297ba0589ea6596df46e90b8098d1606bbc0d8cb5c1374f38568380e479d9d93ec01835b218b3ed3b6017d4f146672bb16272407914d98677cbb03d85075738d915435a98ee133ada2bb344c77f03229762d1a06247fe9559683c493fbb80a63901fd4f30c9ced26ef9665f39a0cb7827a2303ac124d2cab1ad8efc8815588641a00990e4063113cc3ce6e48e056335808fff5bb61c61091b26e2409cc591941127f89df7548fd6e0a8fdbe87e72265b03bff47b848ce41d279cb386505bcb86e1512a82682e08f039accaaa3f1d821f8b8ea833e666c2bedb0bb1f41ce8b1f41b25704321c5dc7982e73cbee39979d9c8b07a7c1ad72f2455de5e6079621ff4397c95624d4c4e44f563a56fb85ce99d6693187bfcdbc7ef206e312f597f6ff9b4fd2ff8f234c3c873d66afc7ed2093f3fa336ca02f5d93830634cf50cec09e5dd3433f6de986aeab6a67dc425b6d72fd445846b305e31347b76ec7c9e7d26b0228e50bc1cadbb018cc32c211f40973cdf5a195e6c31f891c26d75cca0749b4b01b4d02309819702979098e58cca06f06ab16a7ed5b09ad5a57cb942e6bcc010428c38bce727881b00cfeeee52de91335e62b9b31c3c7e1ecf528d05502ba54c4e92d902da8bf41db79a83351565998c25dbedd2dd05c068fb2d08325c480095ba9da00320370fe0cdbbd9672169adeb1c5c013deb0c6f7824e796a75f927ba961c7da8c82de7a2a60552eb63cc2e7273ae33caa3e8c15def0aa967dab2c1235d47204ef60e8ac14ec39c36dc66272a09d368693d64e1a7d8548b501b9d64436f578cc0a91d7fa1ebcc0711a8a396a00f098dfc105b8fc4450ffc77fc1bcbfba6881b0130f04f78fa6199ca3e2ade1e464b2d54c3d9d36f3eb5f6c814e08db0ccc8a76b8fe0aeb85e22cc28c6b76c48ebc9e4c936c8cbfde80d50067932a70488eda1cc5418fdf0c1161aaa3389b47e3568e02efc6a8476a7a1c95edaf4cebc1693e46c57d739fe01def2e988f36c9a2d86089a8205a8f66a017ecd373c5fcf5c9a7677e5bb2564ef4187fd61ef230d5bedb92d1f3376296d6a1f738f8037c5425e256e2d54a054a277593a3698de56f2b439364c9a8ff736e74e993a741df893fd7fe589cb2097de9d4892cd0fcc27df14b77d7d6e2a4e32781d442a1e5c3ff5a487038e8bfe5c3aa06a8b44c53c4e3fea58e58c9d6d59e43f9c455e633b397bf3547d611b6e0fe3263b90fd73e503155d8135139d6ea9bceb09dfcbee6b68d518ef4833102308f05bdd9bf5e872d11da13a5cea7090c6215cac0eab1a07306d73731c952939fe242c1b2898b4ddc289d37ffe24a95ae4157389dc9d49c8b8f6244b2b55150a2b45e149a04005988b148c8820015d5117284e9fb3b9a927bfdbf90611f5345564eac866f1a22c833b2af3582bdbd6aaab9d683f4e45240ff7aa142329b53ecbe889501b987441c07c799f30585fe236fa0e10660b4c4bb9bc5daef4d047f0d4b9e69de3d5198d97343f303090520fd3832df14cf52cb583e3a6ae78a3e313981ecd011150c5f52546ab710b1d5064abd2d6e1a250b1e325e8dfd948e9b4635af7f821fb0f95e8ae8cdfdedee00b85f71430b41905ce800b2fd544a4f19afa98c9ba5019845343640308146e5ba8ddbe8db12775e516ccfaeef95d2ca8eb6b4b7c1fac90cb34a6f0fe87649fc06acc9d45139c4b2d0f4447a9589fca8468efd3465d36e01ae6c6a556df1417ce4da61366f3b4359e082c43f7832b46c64f52da8cd249d3c30163eb948199532daba5c35013f8ff5c0f246adba9cf79a03f0ef80038feb71211ee59bab93d725d11efff58b77a708bca225c6b40eb87bd468051d9028d183025c67c6b9b8e7c1907b8ed204326cc6ec953a385a8b13b532a145d74d78808b17360117c68bef7be55f3d8f9f1910d46be16b86c3f8d810235cee45e0945e111541407b8f3898c8ba21d73806765582bb4928b726323381f05acceeb205f0f65fe50fc70b016cdee488d459c4f6215b24f8e0f5e5dd2c0bab0a1b2adadddafbf6e10a9ff2ecb0478da5d73ee4691874bbf53af8dad139cfb2a97cc9f3b5be8edaf5602ae0f6b76fb911353420ad352d76693d5b827e4604f7d6ccc57556f35a9dd8a62b4676f062a3f9e7f764ca50b4bf98e15c5fed57208ec61e6aa52410365a32a65e31a3e93dede1b81ac0b921612618fcaf5137f0316924cb2ba91afbc3f088b3412f0ee0ea5c0f05c771a6c00f637c2ff4dae3abb303c073a4860960403e720c204e7f1fad39709caa27d337b3d8f572b435cdfee518661a1fab8e64c7aac1586b56135d92d04ee9f4d63bd516c0b8373841cfbc5d25c7e808eab1e4561e0a7a93ef7c731dabbdf6405a5f8b1bdd92a736942ca38c1eb349ee051910a27e10fa7b91ca5c36b8823aabef1560e81e719523f575bd954e8e7339e6bf5a9e8898e34a5044c255519bda83282a5114250c62d9ee4ddffa2f527888c3ac010c8901da01f4464842662a07192298eb8ceac5f06aacd9ec8c095d83b6fc4750ef763061710191f7f4c928bf0213922e17cfd6536e7b33fff955b81169749f1a24fb6bf3cfdf9b97156092585e526e78c3784ac03e78a6972122ec1f555c61ad2cff36ba604390421589e045a8d8b84c40507adf6880059aa38f437afa672929e0c3aab215180009ec6aac1beee8a69193f681eba3c8191780fbf1e20b8c2f1f62a7a115b98eb1e41499b8844d362555183c6e3eb8d203c692595ddf8712006d00f7be4fdc6b42c90b9d761a1a391f2804a517fbd31befa9c2c66238b965d8aaa705457bf331492926aa7fa412072f2a55d43b667c3572a716943480992cfbab67cba785ec4599643d24691e11e90ef8a5fe71226254ed1578e01342370d100a0b908d55a319bd39f03b5e4f8ef37e08f08132b861af9d7cfa2472173224eb4b1c38bccc3248538457c8053a530a8ae51adb598f00526cbfccc4c04a98af0306c82a11749d0aabbd1b6b792271985770eca1f4997a4ab0c6d8d5338515f50a40d8c8459d845a8b275a4ef9042e753d4f5db404563f4b071639572520742d9187634997d189dbfa0de42ef91b8763fbbb5b317d6ae28543b9d112125506f9e16be829ca297f0c1b3df5090a63763051609219350dfcf5fa94678abcd5be8ca8339671a17cd1c03ff374ae99f51bd1603a2fd9322b3e8e4cec10fa41f4cc756bc46f3a1ec5d0f301ed8ec67339f317579e66fb081581c28588ae07f415013c91c18fba3b17708d838dd92f789e061d1356d24ac02c0dd0d8d3ba44f89d5c8068e967ceb94889e3e9e87064450dbffd478324cf4270e13f38285755964f537853fc403042b298e68b8368f58259cd3b0ce9bb468b55bbcde7aa59f90b3b4629364c128dd11106a82541c474d47441defa9a7f9938c439b8a2997211d64c9642a607c27432e8c6ad1ddf089a30ec1f4509bc0c26b922cb9fd16c68cfa4cb6db18fe540352eaead0413a5469fbe9a65cda02c7ee85ee788a1fce28727b3a4e2eb0d320e1b568b040b8c4bb85aec536a096d12d0c2ad7adb391190e3a986aad53d1cc8640f6f42e1375e6a17673b6af547e90ec9d18f0c7e447f8109d111f3446b3c72ffbd4e54d4e95daf9d7b1e57a0a8dd50c5395789b2d50e58a0598d51e682997d6239a6235c1e3c1d0415cd0226df024a5d5a4c27010ab4488784b62d83eb2d66ff073183d34b028a101ff8c223eac5731199bdbb907c02cb845d3abd65008a26b44b5ac8195b12931140e5271483179949ecdbc3599abef333c0305bd4f7005d9bf6366428191c05f3399ce9027f82b5f5812e71a14ed8a77c4d0cd7a8b9084e4b95c997e3b4041a64a454ff9410ceba45f069ec5ac8f434dc2172e147c05c3c255a094cd68609be864c7187b95aa7c5ea772e295581975fdc8624c10bbb847b41986a1a18f6385930a229bda2ed9acf82e043662dbfb357c6bdc288f4f2f1dd9f77ca03ff6f0466b223fdd86e13ab702b56faa9a1d2124363f76b2e59dd73d62910cf27ca79b55bcd0c179e0a1eaaee09b3109ccfa525ba8aeb28c5c329b5aa16eb2b00aed95bf1f3d53ea74f7af1c0e152137d7690c7e59a8a7442e6505a20e556a8c6d0361215711ab69d2ecf02ca479a40cf4479b4d47c8e082d13e4a78a1fb250f3a00e2a7b03470a6e790f266847048d73c388ebbe0576a69a21867b50a56d3240b84eeb1050ce30f51df03facf240fc2737b75f20f8c1f0bfc00d985ab818a44c9c3b43c214af8684d774b88823520d9986bdc0030b48be3261e90744ad06447b62123fca6aea5c073ab635d7de7d15104668d5471c72af988a05676de3d14e2ff8b2dc947626ce4987912034bb469ec6d324f24d2e0ee99d784db08fe7cecf5b1a85aa0558531a752b115c0f2902828ced5ae075662a5715beb97eccaeccc5e2204c011cfcd0ff0a73b3f79512a78d65da5f2c448e41ef030c2b793a33b53233d8ca4caaed376b14f1439904c84c6a534eae9459c69948654fbe1094bcd09848c0bacbcc65289c9ad8b5acb7253c9e63d59047c13374ef98a28495f3dda9c917b0174726125df9f9242e258eb46ea183b467b38bd29773a06ae66edc46e5d3ebb7c30b5c5ba2d6980648505cb5769e37af64ecffc9c9fba4c3e1236ca722b7740ceb09f8f65017f45029694eb6ee9366a50715d36e507b1462eee151948956beb9ab25824611e58059e24bb288efb57bc0ae052fc7184c732962b75c3f599088e0b2145dee4b46cd260e50296eb3c4334b7da4757d30da6ee8a3dc04250ca2ec6158c4b39c02e002a30545b021a93569152362e60a4fce5e2b0adc835fb1fbc91e79c5d32e3bc4491944abefef218349fefe0615bb64ec6086ed398ab56074b98787878650a5d84ad8688c1a4815f5be54c546513d381a6e744de59086391621abc8062f4523f4a3ffe4e9355cbc8ba6455ca6044d64691c215b44bef2ef281d8a2074969fc411ce749b3f8de30346694764432f467d152053262610252f89f67f47204e3152dffa2b00d39b122377c1906cc63ad40f38e4bc1dc49a3606060517cb5453d0434545ea8e02870b859d2797991933fa02d40022fb9f4ec487b812a6b2c551656b6162d6ab1759e212cf2d42872a43e0e3ec372d24f37d0f7a0e6daf41a95c80bbff0e0bebe6488af7971bdee534414e3251f37d3ac799860e7f5fd4b5a093b152940a8b4bfd6a2994eeefb0eba935904531738fa657f40969208c7f7f2994a5ea02f7a8ec9d0dbc9c4cc21d7bdef28a753fb66440fd19f869495b0254b3fb5a76310280719d06aa424d6c656db36ca44013692b63648166333396415c843628f94abe19067717ddea9b9b8f4ec0f5173844da8ddb29f5b633229295c741d50b64d846a6919f798061e383158e3dcb2dc83e171a1a0db89c16000c92fb1e903789fbd75ee15ffdf1e465c35fff4364afbfaf0d82d4a5c1b64c31369c2a72b2f484b7b5c773234f066760f09a3b486519ec1804b14f5ff005528f40c6c140be2b27d7a87ad1cefee41d59701c540c5fe38cb3f408a28ae60fb1f489c352821e5f3eec3b983c7e84f070902cf36a5f0329dea20ce823e7d52cdd341faf293e4d3fca3b6b4f59a01d18d4fb3f0c8ecfbf3645782d48937c02f98d68dc1790220554f573186f890bc1748a4597574a351d09bbe7cbbb13eea38a36032b7520b900d31dfa05b628ef1c880c30eede5673e8ef87be4c7e1eb3e55b866e0a79dadd40aabd51e921593fb3eabad598bcd788bf04b2c9ab31c7e75d4e10c224a11e9cd4ba65f08e3cc21b01dc220f0f6f5ed04294f40b74bd946c45b5dcd841042204f87a0c9717aed7ab3d2a7e0cebbb3119690915dc9aca0012a7ef3130b7536e2e6ee58f192d5b0ac29fc0b596748b9540714395b971c789a720136ea2fa8be33155595b6d6d6772a90b580180f8ce6841253249b30222e85683a470d91e0ab8f4b70bc75d09e98134fd31aea8ec283a8f09de0a7ee68f366764003e7f76ae6ad0b9d7cd06599c9ef408b1dc97c52c82833c5317b09a78b3d65a375e56e4778f4b56e9b52f5b88efcba089e1a16d9a76bde1d1a2b4cbd5482a26a1aad7a7c7943776cf268f8881cfb7c09d80e120685fea9d962354b9b78278d0108992b8e7119a2e11882358e84b6a0ca60e7f372ea5a4288b6d51fb7484338e9e5e9c055cb4eb64f71eb6fa4a97ac46df0ef065bfd2fbc7191135d0314496d5d6f6d0d4ea9d15c51499160462b4659f6f67cb5066df22d47c1472e245c4bd146381a3aa6a735dc80d6eb96ee6631cd488ef3e049664085221c92cc74329a41edc4081a040d95204220ac4b61e7d42aa30e2a0e28860eaada6da05f6e0679e86e822c548782637334fabbe432b30e7dc3e7d8b0a66d3f8fb007fb6a188bf7533a02dd17b61429582066fa45ea122d13a8f2f60397ee7b184d750926b9fc28f8c4a6d27e452aa3b6a52f239f446ba9eb5507c1f3ab679afd9efd684f1845eed7a9da8cfdbba0bb96f3a2cac22efcad9e5dbf43cd628cc9c14b5ca529d572770bdd9507b3de01fc7ce78bd3b4d4fb9ca8ef177eb6d58ddd0812329467668e28bf966fb571cf5643c7faea3059afbc912ced37bbf97b964c2784b009f2928709a1825dcaf8ec062162887248ccd996342aec5b84102d5a6808ab3063cc6f35572a62e1d60575b5670401b140f2f797353a151969c240abcb8a20228c53ecca4065eb49f49c471e4955b3b000f70e0a4be99a45fd90938b70e66deacf1b407386deaf54dc40afcda5a6fc1ef220c125caa2b68bf22ebd66b1a2b164d048e9b91f043cd90b1eed4d2ef84b7a24dd553fc67acccf4008e53f6b294901957b12f5931b6ac2b113317a808dd0198c10ac51bce247a1bc793b8d6e96222823580bcf9d5e2f028cf6116b88784fa1477a281d1478ca9f35bcc636c3f7c5a281d85d147496f99f93eb35db15e8cc61b4d7efc7d2b79128fb569443dc1a64dc61fff640d6f6c766e0d12215657bfc6f62c4750b4505f78ac4e10a64a32fe686b7615b69c5c0ae92c0a22700f846c218276444d40cbb17ee03299ae07c477e25768117b896aad7714be3377a34a3d45c14dcb5d9f716d6a977369d902cbfce970841ffc4f5af51501f3884f3e731b1a35867322e79ccf47e886d3b51a4a280833144b7a5474a04d89b0964cd6901b48ca40eb973c2bf394752dc574425f982846bd873182f02d91024493f710e6c14c9b46c4a1c08594c76df400da0f2e01a8857bfb5a898582d00ae02214b6e6ef2c3454378e5c21489225b05db4ca9352e449d2f2eee4e5bdda8cc85296e8ac50286eae97a543630f61db0d222c49d757cc95473c494f063da26680a3b9513ee5830a644aad338cc6feaa84f8582bed672ae3304b0598e44f3afd3aeafce0814fcebc18e38b4355e87072329138114b99cbc3556467c8619dc2c96843a39cf5423fe3c5f823b705ca74b8e12b46a32ad5bb82ab18456b044bd7f221badef67c1bfa5b8b8486a96f32ee7604e8136b2d3b1463569c224fd5081938db3842338759a1e62d8975b51cb035efb896ecd57b988c9f98db4b8094598883b5774d6e1dee0ee66a529f4138a8b523d5f4f2ba775c60f15d6eae4df50db6d3903c251f32f6e456bfd982dc5d33e1a89a497b79b9dd5ab2b5bd0f546a63e5fd02c775124834fc825ca88a773ed052fb968884c1f2d86d71db0831c29fb86fc8f1f562babc4a55819fdc726bb5025497ff15f070fa2081c07cc1041d733fc712687c483b40499f62515e8b23b4cd6136430e1f8114dcf68937942d3cd88069bf34d093fd49edb71ae438b505b0db13f7fa85fc3c3f90a70a73c1eca04b893d396d5ce548a608b56aac3f461f3e1883c6b6145afade6c7d47486aff547ffa1e309464cd51cc8abe60b32dee670bf29f10c5d6c2f7b35403ccd563006149c698f491129f04805ab7acbd67fab2c9f2bbfe74ad21faa31db21bd92974f4ce58600d52c957c734a6dcfc42d1043c1063cac03d47808d022b21bcae03ecc905fab4299a5ea87db60ca89c75f3d0d2d6df536c884a9d4de24943b1010180183ff4cdecfdd7ff9241fd9a3f61ec02c3eec0649c7ef1927276019a35cc76d40bbae92d2ad134498f5c8291206df0f47f7da3b3add1c53e52f71b8b45a48358c0baf7b80207945d21a5a14b029f29c6c70cd2d0a7bdd7701ae00ec42ed4f9ca8876dbd0f5a4a714e3329225f7429d8bef3b3c99d5804b695a2a18d2241c265321802d0ca5994d49fd05fbc192997f3035d7f355d2f03040518916a39b8fff20832233f1f635301b10479b9428b107196bd671ad3c79b062bfbda63a66242763aea0c90d8f195331cf40e55788661425ecec129d767ab7dc62db50a9c6a84f3822163ddd55f8aaa6f9070b4fe71b9257f7fe4279840e06a57414ff1fd6f14506cb6ae73d3e82b04d2cf3a883b16f3c95d1a56046b6b242048c0990072ed398f2284a98ede53d156c3e4e8476ff4f68ec85cde5dca377c65af6f9b4c88d5821179841d8db743c4295d300d020c28541c4b5389179e5c20b3989843763fcc75f9d857f5e82e163c75dfe661eb532b4e5578532764f12ea9714994ca643d5d1029edc9baaf7000df0d511dac74852796846c1140f720ba2c0b81615470467bc1fbf81af2b421fa74f0a7b3097fa2f612a1c85999e5e965986774b936cebb08a1615d8f89af748212b572a633b99807a0de10d7eed93b476685f9203cf8e17dee0cb5b3badecc917645e8fe4fa6bfb31a59689760ed39378155441df9f182902d7939b78b6dc8a6cd193829dd2599a328ae56e931a69485f2420d909b73d9da4d84d927462421efa566b53b5228a0107d2fced97c73bee3e59fa9b712dd61f4a8197531e9224f95e5559bad5b270a3965b34fdf71ee4cb7b007dddc6e84e02a8610ddba6924b7a9ea6912e07d494c8523827b1894ba6bdb50e17f14c40cf92aa43dbd6a21fd9b01eb48157b87166b72d1c59ca7d6eb591d4bdb5a9bf96433a7e90c7bd05156dbb39fe5f73f3cea106fa4e084904765faae98450b1e28076b2fe166cc501fc13e348389cc00953170fb69d8d17ba463bd930a6b2fac7a720f214b0c0800f6303326f030a2d08d7d76b8d8702a916a057510362d2b2dd0484e9762b938f4b76836b77c4f7883706d9d1414ecff5c94e9cb8cf875985b3e26fa47e7ca633fcd83da2d6d97df527ce3ebc575aa9aef2890aa645f1ee506b4524da4930761a56a4536f3090473a97474df0f1ad17b5b879d385ba251ac5f9a5c64b7d929518719896832d579e0052db554ab831fff57550b9c2cbb03ab063933e05b1c0293f43044f9dbb623825ac23e12b1fc4e674f0098f1acfab472b1594b522515a416917106e990b8ce03c3c34091291c4e8a813ae3685f0ef1a98500f94308a1d756dae7cb2a5f6e658950c04e4c85a4be542a479914dc310bf9975cf4f322f5b52379eb11037ed306ebfa3655f630ce5fcc01e9f9c98166db4f5fe5e623db08419def7fa089d080841320d70aefef0bf2a4509736d4381f81925b79554291f956d85ec7962c30373e2240361958d5fedfd12f05eff5a5d06742e4678de72102b8c0549b00b2d21fe392bad65083ecc6012a327240bbb1ea6a11677274c30acb7e1e5af74a3b836b195388c735e1b1f97a0a6962a55d1d9f5c813896a7c0b1d1625af4bad9f9cd41c8c43d778dd373bf0f9e755d83c2a86a444a63c997ad0447c40f54632fd0670905deb60dba56a574d4649c51f7a314de94b19759f6c873753408ae49f71aa7b714329dc36bc202a6e976d140ff3529492b5c87246bd7fdf145c56e8408bde28f1f9d5e9feda39d0c5b952a073dff8627b7ea805f9d57b96121966ae616751879a27bc0cd9e7671d894aeb0148c3f6c6b94d53e09bc35b44753a9e4d775fb5eec89dd14b66cce6f65938355d55c0c5a3ed5d2d6ba02bf1defc8d29f330871c5200e9ff49c4ab5f0ff17159cc96ecfbca8520672cf8c917a4b5f3c632e862609f695b774ef219ff7bda407a08f15b0f75b81247dba1dc1dec5cb247d8dfebc17f17520556ada65aa06d490ad59fb8e6c49a7d9f7736fa4af0afe222686b141fa0158aea41ad1e8706f3fc1692bc32e2157c2a4e200350c06651d176e9f0fa304d0cc72a4931a550b6587f31c7c54ed61ce0e010efa047a58c50b2a57fe8b70e481b387e37da9976ac9850bf24c901ffce85072cf5865dac2a908f8b882047795b8bb78919c2607f8dc3c5a718887f70d08520dec343fb623efcb9f448c1550f07c1ba075b910c8f916b65450faaec150dc6c2d3cfa2b56776082c831e885cdcb5b69235d4497e65fab67bf4ff8839ed58004fdae901f09aa887e147bdfbf5d65c65b1999084ba0f27058139ea1e60c0d37cd68948194b7c0e8be9f585c64bc6c5100ce9b7a840c1b06714eb6f7f4e2cacf54326a33a49d6480b3742d5e3554f47ff171e187c51eb6aa0976ed496cdd87ed71aa3598c8c8691360e181bb2247e3dc863f5cad877b7a5eb97135b53dd7176d7dd3006d41744b58b861f889eb4468750ee73278ef2b21ca1d5950073c1e926da58250b7aa7d6478c4c784f0bed51d158f0ebe6fe26330b56c7d07eb6809de72265587175e8cb17e3ce22a05ba4500e543f3fce8e5685017928857d4793454fc5166c922f2cc327b8faa5825437b6d4addab460aee7116537f3cc418d47155f41b21132578edc403ea7f62d4e58567f007ff4c61ab1cb90d0cfaa09a8277a97e45a8b6e78b162a717221af6fb13d515431aaa4a5f1ae85296165a6ac3363d61740b3ab36e1edc34e8e73a022d724bdcd3a980ffab6e1de5e3e8e1ffa931f263d5af061e1e56a83d503791bfaf1c2711d1ee8280d94c371afa5baff85b174653d6c875dc2a9e609f4484b3cb16bf99bf630eea650ee31b31e9bac271579a3eca32efc7bf5eb044ea4589c080ec20ee8aadb75cb7bceb7cc6890a3647ab4a28236f08a7d7fd1d82f40b82a5c231143f6261e17307c6095423d57bbca23bcbc7c95d3a72d2c35b76f67af91ebff4e8dba568c277e13978078944ba48ed8b8e1758a17236f7c5dc809936a37e564f8c8d9d732019dc49802a5ac3cc039dc8c795acf1523141dce6eb6e9aa19fb4f72852806595ad795a88ecb557e5e7d3ec0b85d692981b1d577d4c1668b822efd5c3fadd2f4e82fa47e701e65100a11d776c292f27656edecd981e89245be302bfa8e5e81f18bdd1cba40a5ec19656b02e502fc18be709cc1699f1afc16ca9353829eadd98066242e4f88382bb879148e9da0dbe338fb7d083b6fbe66f3c816a3b20ff266889bec9a43932dc638867f85e655f1384c923de503f4c1af2afc68a0a1fbc2297da0d7ea3587929a9d2838c8e09a535aa4b76d6a054e267e3d9132bbcc60447606306dd0ced5c386721e0403edb3d8dc2b64d09f9a239d512b04e0d6b3814196502292a118021364eced07821573f4cf3da7d6ba94ac75a1087c6e7a78dcfe2f8b87741cf156de9d449a58e552df95b6cef5716428b37354f98f62023887376ab4824a55d27b8852181028d24bb517f0fcf60695aa465575b7d16adc11954f650496f52d24cdc67593ac11ca4291676f48fd23a342dd4b685da3332ab5f4991be8a6c6e89c9df6ca31467d49139b90cce8c4d4c06ea3b35ce854f143f1c03bb7596f7462b25f9c8262d49ad7dec663ab49a4ae0fb0991d0a35b6dccb1f2e7dd5be6ab4a33f302331fc2b2798cdde9b71596d2319478362bf842471b7ff025bed5e28ee6c509cf363e15bc4a846241b62a212c39e895aa38478592d1516ee7b5b95c1be73ec1f5a1285a9a09879cfb76eada1f960f23f59eafc89555a69a21babf1e5978eec61b5c6a626d0c22865e14d30c6b72ccfb049de909c0e5893bad84ba0b090495ebb2e3f0ab28a5ca4d2ca62b40030a16c9dffa9136916adea9c9d1ceae7038e2ad8d831a2734b87f0d7b2f6f4358785e9723027b308fb39385b8e4763e6e67fc9b5c8ab22928039684407cc98a5e7d37803e6f4c1acfed4bb1c37e5cc1963d3bf4c743c06633c68fc7dec89c9e05e61073b5a5d4e9398ddc8c7e0bddd5f35923c931b3d44372de55da5b9506a1ce657a24645f93b58010077e1688aa9cd85404b7c4c61971ca5ed1277364535c2de422f01e082a74240677c8e6289f66e51350561b86de8f2aa2441913567d00c7aefb18b124e53ebf057edda8d7f188b653e06ca313c8ad9d723b8fb32f1a27bedf5cbfb6e1186c367a54d0fd303d7bf0f4898164f49652ac71e0b38f0052b202d93218592a76a96372ce426b1b60e2959267c59fb08dacb26e24d24627e63b7bcf632f6d3d75a08efa32707fb9a2bced37b22e81c2d9d97434ce3a6a7b0ba434fcfd6017949e25e117db16365681a49d5cc4fd7363f520380e6a37518eed6759fa062b811c833dda6528674c0ab7c2be5159a62e8c2abede6270149c965c03a01456f581803ae4773547491a52c8b295504bf3492ffe5bb220a43e1cb6001fbc75948f49ce875b3e055c1fa2d496914d7f49e98e7a1678b2351aba528ff14a2252a6c753bffb0a044f76e813b84b0538fa1060144887e98976c9eebc5f89bd03a3b4e04b68088230889623d728f9096b1b29f97066974153456f15f5fe6aa040ad4df7ea73fe6d737acb29cd20e0b87b158d053836670a23b31c6fb27fc13df39f906dc7a7289fba17c1e3b5d0de847b97058c6799d409d78a93f441be76eb8d0719639cbe3bedabba07ed830c55704aa1054e6c08b7b26be44bf6345fd8bac2094d383bb1863e625c538050df18cdc375352f06e6665313d6789299d5692393fd1d468ffa8889a866fe5a6f9aab8288b89f68889896e146a7427c5037697a0eda944a3f4cdd0d98c308fa41d397ca52fbc7d653a02f5b2ea7f08e00831546719dd025a379c9fb87fa5f1eada8d64c1c3c8e43ff861a331588160a9cbf19027d095e9d4d98f8aa358f23ddd8b598aa89ae982d8431b853aaeb7ef0d859cc9d62c7e864e4f771efb18144d34e1df75abc740e2f84820a387f1042f21e3985d25cf354388f0b6632d949cb9caac901631b9318d1e92e7f5caa3842bb485ad398d724f584b910b4b985c743128953147c49ed9329acf4cecbc7ce2673590d9263be40a25f640c19d3df2d27d04cf07aa2b37eeb8a6cc08ca470b6385b85ba5be7a19702608ea502acddcd01486ffbfdfcd5de33045c3656954c9ba1be85f4f2060fc9faf57042bebbb7633e167f2eb34e47e293714a51a3341ad46252a6f6cd9ef476d3de991030cee72ddffcbc953b68367e287373fcdd7cbf2ac1b5a22d8847abe6ff29a7577d09f8bb8c0becb6fbb2220726fdf21c3deafb67ff65fe7ce1f4e3867c8a6a818eadc00965592df155e94bac654d4c3acc5cc779abc3dfac21c553dab8f72515a061bfde0dc546817b04189831efcb38affc2f17725eb6c234247ef9672a1e89c83791321e0852e196ae8094afa8fa1f5152949fa0f8bf1f9f465ca3a994d33f7b8c825872c8dd086d3b38f8d1f7874ed0166668a903049ff5ae76fd66343d5d093fbeea8e8036d7688ea6cac5bef200826943caed7f0811df30412c11fbca212782af7d19c8e913e45b6b7b46888e1997ba42e8592dc03d6e03f03078b42aedffd213bfcb1f592e4dc31725c33e68b7bf48057fea93548e7bc4f65debc9936efbbdd883e40e025bf7441c6e357b4669b008202f61ded44344c7d0c8b5e9c9068beb6537a4c2b2c3a7b49ecaed3414fc8d9a9609b38f623b0d14f1533e27264ffacff7aeea69e0339abde8a9b82e4564bcb9d90a9251a35217dce79afea1f3f4a311340915afa33a7d4a5bcf6d2feb0c2437cfe7d4a5f0d938dc078240d38a3d9b7fed5124ccac30d29f4b09ee7c0ce7ca317a3e1cc91623755f112d9fb510669083a3f20341fa0ea2ba4857485f7ebc7069755aa734ca69c14360906d9164d84c5fa62029db6416cf029f0e7862ad9d025cfb6d1f3f11bdda828310ce5ac863dadcb615b3b931a364b0d34d101d9134bababbbb8273b3e7f2b9d411f2702aa5b6208df89b9317e2d9541c42e2ee339f4988a49fd10310c3b3562775608f19145b66cb5c34046054878edecde7831cf2d8ba59f37467a525620f6c728434484dbbb32cca6cca8fafcda45078c2d3f2b3f27bba120fecf4dc575610d4229a0acc7f9498cca52a28105ceb7817f358f7db4582d9aaccddd98f5638ec5b1e45cbc7a86ba177178e9ac0d22d536df35e5d983e29fd24e654a1e196ccb60ea7c46efc720b94b39d0f86a0fe526a68b8cfb085d8c81f5f8dca0aa9efadc06858e3460e8e18cfd92f6dd29037017899a9b7cbe2a88f623383910d92d5c36579180ebdc884f95ca153a81e0e27eebfdb6315bf4bd2e9fe78202ef21cd02d1de1283fa8b8f07b76dd4012f09cf85d141978e4c8b0ca5c1ed57f5097f1e580b71a9ebd63bc907d847a4f233f60ec5aebfb7d059840d6d6ce2ecda2975ae2459ad4765098b69d0040c23db036a54ec11ff7cd04a06d50dfa6fe90dba93b3a37e47d1dc3feaa34047122dc329d769ecd06878ae8c1e912f0b9773e1fd2138ae19c70d3dcae23265eb67005e042d415aac143326cdb63c3e510632e5ad72a23fc46b8806810b02c1ae90c6054cd09b4521e61b7a606ce456d8ecea77d1064835b88ae6eeba25c81c943a21b365d98dcf830b070d590f74d5c20098ad43b984220bba0196bdfb4bc9beeaa1088ba4d307ce6675b8f1f3b96d9b940b82cab9f7f592673bcd4b6b4291ad1269c710d9b8b0abc45ec7ac7a85a2560a8f3494432a8bcec00a73fd92046ec9f35b22df7c065b2843bd1a0c3284c47b7c1d47437a70136e0f2040bfcb761f6f148eca114cc925b37fac8ec002a44d804f0c470fa8498ade2733158ab1b913c037c87cfb4b92292f790281b4609bdadee8b8c8fc23ebc390870bc157e6cf8e17303148b2a60591679d76f096378cba85a15f07bf357a085b825fae9737804adf64e537426242861c1eafc08e3eac8380ea3898d9d0a553f53374270a4be45a7fdc088d3f8923ff4f1779cdd4c2ee98926b855985b13d1fbcbfa42eacbfefcbdefcc464e88f56aefafd74314526e408b3b23a434c741706dbd60926e0db4f99b7d8b4b8b5e2e2e2757c9bef8567be60500096dd4ddd53b0be674f347f5d224f569a8cfeccaf9e80dc5125931b737873682cfc43a62704b91964ed8096c527255283c3fd0a6b8f6bcb963380a91e2b085e8dacb81e6577e54288f8be899b6b1f0c2a21672ff176dd1574d6bdc98ecc1848b122994e7a6edfc8d29d62d160c796fd3e5fe91772476be0d676724f5a27007862e0764ef792c8e8598a79ff4157d57e80756e57e29a5cd64ddc68ebd43255e6f8c3cdf60f548f9f98c719bd7d8cace6fb37df13903322e538eb19a8ce3e30a37e7341e7e8c511a27ef302814aff8ff40aa7f1e8d96f10cb4991815fa9ab3bcf7cfda0c03adb5e878ecd99f3f40d31812b34e8034a5bdb6dddee350734a9f6ca88648f63aea30722ba410a8cac1f7a58ba319b1c3b04887e23a85c2ac01397ccab62f1102c705ee10bb878d86b66198d5550233ff8f2ed7f3e22d48bd800cbb600a97fd1bc4adc162050330f7b1942b6f0b499d8e423d03e8faba442407dd8ee0872cdcbfc15e2733dbdbcfcf033160c6c9f6384915ddbc2284d5aa34f025ec1658b221e9efb94240b3ab170e633ad0eae39ee9ea6cc1898fc0ddc662319c322ef2d0cd714b8131420ea6c8cbb1c94a49cc877d88913a9a084567aec4fdc0138b601a8a7db0d8190964b867da451ad845da51ff99fa41493aa927000cd5132b0ab93bad88a3e68cb42430c0e3d5ec93bd91f43b260f983936f65cd1a9b4fb1a87ec8ba3b1ca85166cb9e1a4ed2a5d15690d94e798e1ed24f433dcae76d72e5537f6563046e38ce709ee8b2f600e89583feb492df6f42aa17bc3cebb99cf97832c72602813a5067296e434506ae063fd5fb0b731de2e367a8d130615c9ae86f884fc60e89ec8c8191740f861cbe56dcdf5c21256106951f651ecf6f1f34b57ff1171b763c1ad4ce936068752926c5a4845f048c35a9ed64adce76fb7a34ecb35d5a12c05987cb24718576a6f9b78268f6090c4e1a85c954b504bef34f75227f67b8b06801201887692945936b93851fae203fd54d1e11f7c24334c5c50e5f79cbc3d0dfe7a8be447031e4d00526ee6903409191faaf0e4cabe006547bb64060fb846a21a120d926fe4744941e8034d318e46087b91129173cd765d36917878797c0d15837fbda0fe2206d8ec71b265ddbe4bce9bbbe9387475ec2f2ef1302f060c48db264394fa80ef270c2c09da2d995d8a00a4a500051ecfd06d6ee59f16cf4c4308562021ba1091b63506e4d2496cb0f8274e49b96b4d120e815bd508efe975fc988638e3717a514a238e8b95ec5d6ccf0abeaaac310015763c49e49f7b1886b81f46e1534fbc28ca796b233e820b4fc0e6724bd8614055de6ec312dcd1760164ba2690ff3b61785755c603f7e8b15ccc2d7a5585124895786f69755437f6aa29c3eac0666c1699376c0b467a1e1ebf175c07b3ba2a2cd3f78910b9bb6a564d84c1e2782c73a5422c980b68d1e6dc016f0ef1156bcb41782453e4ca77b2ad3bc2bcc1596fd3ed4b0d6f16243c14186b4ca764df572edf2c3115afb12f730666ca0071549d07a2ca3ad2c20a1fbcccfdd1a6641edb2d294d819b292a5e40404a11af20b65ef638eefe150b9bf5bcc73317a6d60e410417724113a629a94f231d15aff1caf940f023b08456a3b4e3f780d08d93bdc58144dd3a3afc3df3f96adaa68d6a4a0005c1ccdf1163fceed06346eb3e622bf2d62388561442d825d597af6ae31726c156a8121ac9dd171d390e74603481852042909bf596f7187b76cf6666da36c899ba466965e802722751f6997754bc2f372a032a09985ad2428bbaaf6d81ee99c9bef3019c6582974926721629d4321dd289fa89383fca693a5d4bdc60555225f11566392ee259c6546bef9ac1e26b8241ad9846efcda391e160b99160b5157407f2e396e97bd163c9baf30a45c887cd6a4e1735a675374dcfd364c1ad5eb078d511a9bf493f7d54089d36915d74a6bbeda99c742e9f034b5e5340b4f5e791b6c987368b5ca6c019733258df6f9f3159d2a298a5c1f76e51f152558c1e5da90deaa4de403f20ee8f1ca479ad61394fc810817d97f9cf52eff06c2e037e3cf147f783ca5a20399350d48e50ed349958706f4bebe6b9db4175efa1016997b88b4b7f7628c6a42c62377d4ebe88c84f9401474afd9b490b760096ecd5d7fe9038a3eaebe08913395cad829669cfe05120df11339d3ffa978aed2e7ef211f05e2d26e420b6ca07f01322c7052a441b5aa24f1223c9a8def535b541e61b3f160ad3494afcd2f092de90a929eb9bab47a078009c9a53da0a2bd6527e73d000cc5431020f15bdd85ad5f5d2129ced3eb02d40804faa7fe885720d8dda80369d5edb5b5d45d553aaab4b34857914e13829bf64654c9261966fd63dbb691494363e6017c3f98d1b15e5edeece10d8040b4c6778c09a43c6e7e1fa7aaf3628aceed347072e5ff219fbbdb6eb9a59432a514520879087c087eea9ce0a6a445c1f6adb646981096deed8f665b8584a6f16f42d5c27611b2c216bab86d04f903a6f17fa24a61a908314125b1e812854419e1524b1eeca0422f5819fe42dc702e41d29420694f6cc892c6b54ad2685325699226699246a9a449daf4991e52b22e30d8d662adb6baaaab6d1549b5aeeacae3f16c9e0d06f33cdf30b7f1ab43678b1677f7f73c1b0cb66d2fe29a2f01a102583a37ae7a3e9dd753708dff9848645c86f4b819bddcb8eaf974de83de4396fd96224c11c66d2d13c6a50dd63a302947f877115edf3dabd94aa705defbafc0fb929c9070c9f361618844d28dccdec85a4bc39ab061c3fca3542ad7612b58d36030180834ea713344448406079124e9d30e188c460d56b163e4c8dd1d6bbfdad5adae358abcdbad180a75b1eb6a5723778cddeeeddddeddd55ae337e21a04704d02c09273e7849db9e1c80bda3a49b86646847b708c3f68731eaef3628c317a3778191ff24e172758c162dc7edfaaac51322b4c74efdf5418879947f7856cc5ed77cf732d2e75ad2e4d66e0df4bbe3086cbc46d3c149740385c86351249b09d4885091eb3f6cecfc8097b03267e2d73900ad3f803a15e71e71a7f990c060624ea71e3a00f0789d0502409d79c741c1cc956359e2063c7c8919bdb4837ec155dd1155d5b6f5bdc6273fb8e91232a2837d880ea27351d39778cd0aeebbaaeebba91c7e3f178b66ddb647c61258dab854bdbfb47572475ef1f5f481cece872c51797e8f58f57b024e152bf0cf3d35cb3b9a060d9c4262cae7b32f8ddbe245ce31f4534ae112e11e13ddce0bad7180cd40ea9ee1fe216a554a107a771b1ca42e5613c798d0ab1f5459683f20b232b028169fca7a822ba8ca476767676768cec189131992756d7bf8b1c63c766ee1be6888a27af79cd6bb4298d3436b7cf9b799363e40608f8602f1836e98d83a20c6d05d7f8b37f77715d8beb322e39b3d74d298d1ea5f1f361c2865e9bdfb2ce433d2c8049fe8ab02b768aeb2fb6c277380be622ca261e06cc654e664544b93e856bfc5532559b1ec60e5f1897d81f423737b55a4be9cd4d942b1959a462c7c8919b6541aaa591d28d6e3146598c41e246dbb62348dc464712f7bfa1530da54f5bfd12e0b569c252080a2023043861fb23c035fe096892049ac63f2626f46cdbb66dfd59c28a98b01bd3606ef464700ae4806b74b0b0bdd1205ce347e2916d6b7074c453b64ac739d8bde5e06f44b02d16f58a25c44a2592a12896bd8f8a0de5f57fc5183932f39c71048140111465deea6696f10517da8936ce628db19014f6891a0fae472aaec71d5c7fa70293dce5059760de7594f418a62937de755037a61b0f836ab2f12124ec0daedb8087507c018b715d72b1509c146b4770c913ad78ace2510947177089bebf6bd13b3c0b2ecd8f43c47c1881b81e6770ddb770ddade05db8ac068daf26f385f5da982fb432be6abfb0ba565416492d93c9643299cc23eaaed55c2a95ab93459290982c268bc9e88b40a2be5d8ba423227655aaa642f5e3944512334f8f3fd0c1ee641de8eab8fe11159b38a97a17772e1e995cef40d1e7274e0ff42010687aa0771b50bc71e32b358dff87f6c37ae383e223c2f5f7a468015ce3ae831376def0e6d33961411fde88e6ed3e9f8e54804471072deb9aace6aa2e14eabaeafdb82e8b3c445a27eae1b2b26871e102e3bafb8c2d01d11ea66c4597c4e80ed7fdc3d053d09c5630cdcca24e2eba2f9c604c19d7b84c76c5f0316ebb7a4b1458b82d8bb55a3b57aa4872ad56b550c85a97aa5659fc0212c51d8822155ce36f43f4825445528c4552e401d3f8fbcb5452ace213abf88395cb7cc7bd10f90b2e85eb1f12312b20f4285c7f1b9ec5f597ae488a3d341598c61f89d00d6c105f1012030b4078e0b0b0f2146b2e03c92c16f1e43b91343defef5dfc0ac699a0f7772bb8e4bdbf37a171b870a973a7fde876f7bc9bb255e34857f3983299ecce952c9298a5cb5ee9f23dd0099826922ec034fdcc85aac4f60c9a50b5e84700d3e8d802f37e25ca0f3d97305f38616044de4724eb47048e6630c10e07db656e13c618ae749ec700f7f1c3217ec4c1f3ce3870384cc1c1f3f1dbc46e33677ab673eff992f873df4cbf2989e7e337d3df8d0ea6d932a1feacc5c19f7b8f28b6e787c4f73cfdbcfe84e8bc203ee7118db866bec80b2b67cd01ba27830eb74e2bec0cf1bbc7803ff73fba796edbf462bf0621edcdccd03df743bae7be2453b64f12bffbb66f48f749fcbbfeda0bae9913fc4449b0f2c38f1f2b9d5e417e118b11c6cccc393723b0935fd8f62f5ac618ed17b20893524ae78c94ce58a3284e4ae383925239279d944e49279d91718a413f4797e3e278afdeff289fd2b05e19075d7a3f64cbfa23ca3869d41fffe3231cf4c3f81f3f5aa07f04618eebf30bdf47a5df0d78e76de639a2dfccfce49df7521d599df6ec4bb7377d79530e02731888d1859629877e620b2b35d394fe20b46ea279bcac38d8d14fc77d3892405ef711b5c79670a471fc8340f3f8b07c68cbba4262e66a24a46be63595758544fdbad63ce23b124dea4d6e5bddaa9452d64e344d94f2bb691e1df7e99eb0db13f673fd76338a10c491f02f1d9d73e33e54e4ad22b8a6ce561e0e085f5a1f99f191c6e9562f41eb86c25a1de9a6c56677773a2708052466abd5aa6e72dbea5665e5a4a7fb745252295b5cd33070358e5361239ae8ee09dbdd2f36ec58fdd04f9d0bf11c36b0f2b7207caba856d8a6545ee148ec0bf300c24a2965f7f1401f2ae26e75a249bd45d3cc20d038fd650b246efcb8ea2f34004dac5fd07b272f3fb8c2085b708107ea09d1017da148131f86289c564ed8b0b31076166ef4d30d0f3c73c2e9e674bae9d837ce830eeab43ac9205c43e794f5930506b0894dde924dfc1fef47e5368e9bdcdc56ab6debb62ae20b12b1e9745af9670389dce48992f4922378809972682780f083cbe4bd114d0a1203a05bb17d4d206f2b92dc89477151e1aaa8135127073f2cb6d5dddd5d02a6f130da861162300e8ee6e18fa3c7781fdedf112c4edb5fc138f1f4a526340ec7a5fa56d5ee9faead8a8d53a479f8cf4e32ff22dea73fedf1ccd37d8ee3681c1dccc37b1cf7f3f7e339734d7b4baea91f19e3c74353b85d889c71ce3a6b8c31566baddbb6515a2bf56a6dea0109bdc0355d802fd4c5ce90f7fe5c158d22c9fb66601a7fcf62b409a92159d56ab55a0d0912d0ac999bc66ddbe846bbd25ab7ba511a29cb91ec1163947d7a60437f5db7c1e23630b7992f63acb53d5c953b2cf921e435aeb919f5b8d9116385abc562514ae98e118ee3385624b1228d1cc755aed46bdc7024bf27d890778cd8e047dc66bee7312e51fdb07212259627386d8a5415ab2b602f07a5d36f918dcb5e047c87209114a35061d5eae08dcc11b13833839b629e394cc0e502b00da54c30e81fe2b83ce399bf654cb04d2bc1b4e536cd9af14516ad3355eb9c73ce39e79cb3d2a9044bb94b348dcf280cfafb84c2ce26521e45b3454534b138a8258c1dfdd01a2362138d11b949cbf5a781f58471e6a6985f718ca84d51c4b7e3e68d11b1a9ebbacf526b4c5f4f65c399e2b2d5ba6d33156933254f0e42e192d499a82e369c29192a6eb7613bd89952c2b2f763a6666a862849dc828242cd9443ecc1cb04c31022e86d94810fa8dbac3a6d0dd1ad6198a908fa60449115599755ad0dd56835b06e54b061b35256dcc609931a9592af48aaf1345054505166111316036b2ad11525b27c60c39992f9195fe39b9941e667fc4c7f43647ec6cc901a1ffa1a1f7adaece74b13c988362eac77e04c7f8dee97097d8d2f898d0f7d1200fc8cd7c144433403fa175e07538c6806d4d9108db62b581a2ff322206c979a9981c6c73c0664bec6338e1a49313ff318a8f1386afcccd7781c684c1c1f80c7c0cc0be0c3c1c6cf7c003e1ca60cb1f1338f03001e47674394d3e30a36e66bfcccf63a98a82bd208d1a1b0176d459a0304615de69dc6e733f38ee3dd0380884d315f030038be991a2aba7d3313a8bfbd0e37462aa22219dfa21bfccaf8220d9a074c970bf3531416b9309f13ad28aa60bef8648698bff14362fe068d2fe6852f89ccc739d113cd10b1292462538c884d34ba4fc83fb1a794dbd0bcc45a9c39e82e51110cae710114d7b7309b8856e825b8cf0d67ab8b619022184cd3c91b9b0a60cc142db2680e7adcf9c2ced4e748e31aff2e78c76bf1e435afc51d445664c52cd189e8839899a2551c74eaa22d185e60e387d479e0128dc6cac2c1808511f31d644b58a99adb8491b5a2d1bca4669309e54b644d9f59668a6be60ff38a0c08312ab028b10897933ba33839588b446898a9ae61a68a843cf3d08ce7be980f41b7f14d554ccb66b4ac4616685441e6eb2d66cc142d66be68b3fbccd46471892fbde16c4d29b11559363eb40c7470816052a4451a6f9cc8126388248e60d03fb23c92a612ce510c26aebfcf17d7b87baa65911669916524922218318c9d1d76967891365373ced93595a231900ed663f0325fccddd2255b9265ebd6db16b7d8deea768264b15eac178b158233078d98e233b789dff216d7fa28e30b1bca4e4996cb6da4152e6ddf754ad45056556ca122595226a7b82eafc89914b11536942c09939fef1e1472ff96b0de9a7ddff711c99688e5921549202859208b6e3af849bb9ab41acb8a8291d4bd7f1a003bb0d3e2d545f4642092011aa41467c9c0dac2b66ab74593ec275b9dcf7c06f35d0085b2e059afc2071cc00de34b1ee086f1d53188e8729b3006115bad2a31462b3706c125d6d7856507a713969382d6ba6ddbb67d88648049f1ca4bf67ac5dc30be5876854932ca8bf5928105856be2a64567b9fe339e39a145b9e2379e20595c23a3482b5255a0a638edc82bb8c6d5b1497f506cc8b4193edf3d0628066ca481c27e8e965198c65f52b92e81705d5eb9ee4956a758ed4a75aa53f3c5f9278339e7fc7c3e1f4ae9a4f3f3f97c4694d239e7ece1a4fe7c54bbd13c1ff77d2fc4396984b1c562b0d7bffe35e7dce6165f91f4953a6ccb84f29a5aaecf2ad79fce6df3bef9482a116167fdaad5da5048b6c00b03171b53602b08cbde6784f55fd5d5b6dabef0b7554c4d1516b799b05904977670295eff199bb348ea3e04044ba5ce28dcdc895ed8ed89839b152cf7d2003eb0fe7c398a2e5c6edb4c96db843175533eb5d84272d30da7943bc60d638b4b7de327aa41c77d463f380f88df6d9b1f3d2022bf51e55dc04d311505dbf160d914bf7faedc26fecbd5625d8f22d912c9c086b235a16cb096dbc46f7be2a02792810db727dbebfa6f5ad8fe30a656a9a852a55253958ae08d2c95c72a5315695cc776cb411f4f1c74c6e2e9e964aa3a6f015c5322029ddee7864bf1e30f31753363aa4a3855b2255b32bb4d617bf27d7860a76a968a3207a74a0a9646beb6205d30933298491acca4103369c42c0bd7bfb1c0a54d62c134fe52b8fef10bab85eb63cc18bcfcfb0726c9163321f55442515a45b43ad58598daa61853750256019b80d4af2879c0530906e36a3261c4759eaf364210aea726cc55515485a52fd9ba79d5dc6e5dffbe3245ac8a9815b1d754bda66aaaa6aad61d23071dec566db1cd0710a5b3810c0b103b302b56acc41839b2a7eb4fcf6284c42e0a892410308dff16d73fecb8e6b8c8c58e8989d93eb5562bf7484ecdea2aad9344d55250fe95db6a48786b8ee3aac771713aa83f346a95c2073a34a4c43123140242103233ac9db36eb14306084a2b5be48832bc1ff17bda281f3737a36ddb1a4581202f24923acfbbbf17b93d90cc2259d56a35e7768c7adcf8e01a121b4ab89b993bb2562a5b69531a69ec6ddbb656b54a35a9bb8d0eb791e2a43afb32bdcc39e7a451b66d71dba20cafb25d6bed6d1b218049120c491bdd91478475976b676727ba7622084a54241941a15ed2a6132e3d719b3058d2e4f6a11f782e993b4c9611ff18bf21dc9784fbeee3fe685c03055b7feb264dd6228df770e9c541ff3837340f5f010b1a87abbf936af73e2f22918424d2344e4ef390bdbc20c9f97c5efdf9ee4f0dc9e713424237d16914922f36d08a741922631ef5c8018670442dbad3f5e8d445b1d026940965512b5445a15c7f19455068c1429fd0551435a1729b761b896a169394db44978c0f36152342511445538d436920002736a42852acd5da900f360036a0a9bafa01846f7f32e5a05314d7f8e7bdbfd1c38b75d74db90dcb1bb24c004278661e4fcd43f3ec7864d7ff46b760352600950d23ab968a39d8b558cc16c164c5c513a594527631bbdd2dd7bbbb259df3935d8ff1c186a35b639ea73dd03be84b9283a9c240a02f097d2501fde73b8f6846f4cdf4c3b4e787783c0ff32561df9e7b1d4c3a7414f5c2151b6759708d47591436ac308a1a82dbc022699afc6bcc6d7a78b15dbb2145f96f35b7691a4579fd627ab0ed9a32a47bef4bd2d5ee874d53c21ed7e455589483ce84a6fa0b47280d8091c635f091c68d60c31fc51b273676fdab169817fb1702312708174ba5891bd22154081136e458ade2fa6701a3281445511445515477b2f1454a29fd7a924b112ee1b8fe466c9032923a402bc235fe9f13a4eccd49acc52d77cdbc702b553ce65dfcc51b07c1d2206ce855dc4626817a13ccfc2458c42e65e35227650ae34423e020ecd410d7047d4dd0b7e33c34f85e60e9875e60528ed320e0728ebf935a44a790d0a42291c697e8aecfbd39952291e44b348d37e1f3854e8450fd4287c29bb88d045fa2b71697a870a9fa1242446887a2bd096fb9b7ea87a2703b91edf5b75a9ed06f7b68ba66eb7113631e16e8c8c7a787a5dc9467e592dba8597fbe7ce504c4650f24b3fe39ce0c84d58a15e3220506e5b5a56585ae56d5bd7635eec9c27237fcee6bad5f3f97bc15144d226244af1a87da20d48496218108a126ec12fe7586374d7bd5ae48530433c7107694ebcf79b7f2e0fa3f5769d9f951fa021bb26c031cd000976ef00126f5e949f3f0f76853f801130c869a4707e1c67558f33084ebb18fad0ed6533fa127da4f6606b80083880cb65aad56abd5a8c7ca52e166a64c9bfb65737222a94a493b0f1555aef9175a96d69430c963c34858d029cf97e3a371b88f86e6e1fffcf2726898afd7e49253abf461060cfad3d0384780602b705919610818d7662c2b66f3dde3e68185a5b55a6ddbba3098f993827262f22122ab44b8f35c91b922658e48294084694d7a1b69dc00d37dc05988d0b972743dcb105ea24966334f3794b957ec8d1bb24cd6cfe7f3f9eae0e73381e8f92244081b322dbc61de22fd34f847e446caf20d43a0474185d828fecc32c4ebe9d787610a1b72145f50b9a22996fbeebbb9f9978076846bfc6d11d6238a5ef480f483b040c041e7bbcd7c60e10d13029e28fc206ed3d94c520cb20797e4fb1549001def36954b5bc771de8fcd0697526069304e7f29a856864b9e77cf15eb5d7bdd779fcfc7fbe1f916c944e172f6084bbb1f1a8d46a31df1bc1d0e8e1cece1e08d833e722010c4c16e193e88a1dc85a5091396955635143a1a7532274f9cf8cb10979c8e4236c0208dfafb236bbdf4a768042d9271ce398af3e5acdf10a7e98cb07ec31010d6e6c086f6ba7c8fef38fe7cc51084d840dfbdb0262463e380c1216c689c3e1de1022f5a57282143316d368aa25028140ab56d3b463d3a06338399ebe82736d4d0a76ec234fe12a3f333ccbbfba5773d3cb0a31b3f9e15e1d9ac8894348cb98a2d66d7218bb1d825bea2966d4606ef3ed7f87ff7c726f3b76ddbb61a5aafadc6c5a5261ac7f3fd963eccc370c586b1359f348ee7065c62e2243fbd22c953339aacc99d4892f1fe13758a246fd249999c359ba44bb6e42aca28cc87f2142a854aa15cb3fae578626722107ffe8caf03150eb5d08a40709a4e49711b260e63058b5a82e212f3c7631173f6d5da50282e81b9f10718d10cb771116f5785f58f556e186bddb6214245d87645527479a660ebfdcfe1a4c8c4458c1397300c5c8a33f8dcf0bdcb7db515bae185b0d8b88469fc7fa84e228a6bfc0a1bc6566c6d1f7a1f4ed38f058b6bf12d22601c04308f7e5983112e4d0528a0fbc25a3d5f6cc556addba8c7cd5cd950d2ac6256ad184abf9eb4165655a9ba9b9b1bbad55a6b7d52f7616dff4251b061e84a5291a8c4f5ef2118076c33df85e052ff4da4691ccf97a479f88d77439e7d5f6e92d4f79bfa85355f6e68641e709266c25f51dc2074872269014ce37fa35255954aa552a938ae0a19e260ff27369bcd763ce54fbc7054173f7913dae46a4339399184a4f6e068462c51a06c9f56713991e43f1a816008d6b39e71e9b3a104dbb7ebba6e3ebd61ab26f390e17ddfcfcb077d731e902888839e811d52a20474615b3509543525e9314cec31f48f4056a6e9ff421b2af7db047a04bd6d40e87b6c60d8ddb8efeeba0f924e61b1b5630efabb604abf0ecc2b895d389950e0f6e57432a14226985702533b9d4e261d1d2502a05513cc2b71c02c6482791d253cc6eb64820168827918dc98604c30cfbd6c900f0b9d05d3cc9eb0ef1a62d6a63b3d836189ddbe9909f408e6f7ac023341d0c2ed1cffe00e6f5a8f59382a41dfee5974d9f006c4041bf6cc51b3d96c369b51ea33cf65b67065d65167a08f500eeaddb6b1043b9271123b5713e7873bc21cd7a9cff67ecc2f6caddb3665a432da3ccd79d2d15698344b67d55552934fa78e0c82b147a3ffda5f47c4dddddd3d09e80bd8ca94c388c90f5ca629fd21c36230fcc0facf990830974b9fb95cea3a7dca9175ea0607a9128be408f5e00006232ceda0b0f23671d053ad1c2acb7c3a9d4ea73ef58952a7755268ec34b7711dfec5dfbdb8bbec642097fc9238ee03eb573b8f16d6efec9e5e3708d391449fa6c37d7d5a2455ee0b400dac90d98d1e5e2ccfaea36ed846c0208495c16934da9c3b68758c8e99274f99acc7b03559173f317a778a42987843d75b75606a24b5153bd7df690d6cd8ad4869b2586beb38a9487f09781e611fa0f72f82821b9c04fa680d0025712793ebfcc53b2b1e366458ea156b1efe138b834da4b0adfa9ed8119020ec1d9c808df81371555c9062080c3ad83c8a500029322292a06a8566383ed40aa5a4a452527630d26ad156abd5ad6e756bdb463d5a33a4b85caf1d2f586656645ec0b65497ab7dfb500f48e7e1b863c3762921c68a3cd142609c2456669f54deccfbf629926efa497ca2a2a208dd4a4214ed84b80385b5723da9f2ba5cd5e572b95c9c886fbb869cbc2e4e2754cb0a1396ceaa4aeac9e90482b20623c95a2e798de35dfffac562c1e5367d1b50b047e889f66f4fe9f6fdfddbf71ba91ff24e7df0648db06d65db28a5b6e3a55e05180a77fb3ed5ea606f2fbd1f5b1525c1bd0d6ea4af9123f2044b7d4ed70dc0a300bc8502c0c6a9410938416aa05d6c100c02c1a07f0d8d83a479f8105d584a382276da69d970c4c869e774629d4ea7d3e964b1405f1cc7c5da49b264151df9454a296badb5e6c076dfc1a049978508dafdcc5924e6863cabaf5a3b092781b5849429490e323b28d3e773e8b8b032791f6b50dc660726758d4b325c9a21272c7f58721d06256c18dbd5318fc13f0dfaa6312fd61cac5dc023c39b6133d948e30f33051b46d749a2b8a71c05b2dd30db33dff3f15c1679a28f8863acd185edbeb0b7442ef10a26512298c67fca941ef4e086edb272c376f911b1567bc2054ec80df4d6e73e569cc6fbebedaf5d4caccb89d30d252ad6ac58ff6e2bc27d72885061b91bf2dca813d7db65a579b812d207066740ad4820e42a0a39c42bd624ab5dd48adfd4502b4822a96b55d45c35b9721bae166bb1166b1e0fc735421c1c4284be6c00c1ccb4b1d056df4412dfb0870a0b739d524aa9bb870a6b61c842686665b15a739cac5c00b3b826a6c541eeebd4ed20ae7f6c988f9c9b90671fe010b007901841e33414be02140ac54385a5fc04834180328486122b024bc6daa4d06655615d094d11aa227473c38ab1582cd6b6c154890921726242c310a6e9f08cbd906ebd05724c08970470fd89c0000a283d19a6582a73847dfba9967e433ad50d79f6b2b6880d2152b013f0dcfe402e794c888cc562b198903977787c60e6a992826a321b89b551eff40cc1728c49705f9f37fa7f798aafe2adc899354a7b38cde69b1662778cb17687c57a37ac4dba35c6186387c5c65e71e9bbee8574b0729b9614a61ff6eae670e5d50e3329a3bf6f6d6795811d503db0d36bf0067430dbbd6ff5e7ffe5571539ab55575fb93c7592a97f90684929e58e9119dcc43dc3803e1eee330203f27ca4b0ec604ebfbe70f46166f678a011e89b3ba31d5be5975365fde837bf1d233b3827288b52564bd6a54aac61cda55d946bb53614fad128ca6ab5f61f0447a366f58b4b7c7d764faf1fc6a5fe1fa6b84634a10b76b3a351a86d121c3721063d58c294433c220c93e7bf54ca32d7d8c993274f8ff60cfdbef4abe7a39f1107dddfeebcad4bd8203b18b1b65a6b592c101073ceba4dea24c65837fff13f291d758a76c157b0204290e80ca100eff0175917589066120d1a39187683cfc042b854e3bae806e192288bdb42827cda415110075d6efd520bcc11fc4990ab7ad2c38b95715e95759356791031ec7c820dc1eba22dd81094f2fb85041171b121087acb240c0683c182ccb9c3888e8fd8100e7f99c383cc9e93ba8e3adbe9597be9d8a45cf274308d3febe8f1ea973c5dff26820d2e729a5ffdc9d51722ac97cb59a8e8b2e58637314358ce4205961bde64a982c9cd424595cb598ef0e2e2f6eb543f1e1ffad55bc4729dbda4384bac4a9f9acb7c65893de186bdf369653942ec86ed456e348c56a415aef7f0aa3199ae80df5aad0d85fe417074634508eb1e1020ec20783ae108c5d3cb4ece628425d8bc765eafd7ebf5dab6978582e338e68e7c24e9288119638c2e9c4c32af2383fb9890679f1f8c2304300ed83cdc13b14946c4261939ce711cc7fd370e17f27e8608f41f519bac884d9c2889cfc788941c9111c910292972fa3cd853dc225cffb000d73f2236f5dd3e326e9a216a1367454a723899bcef603ec7258ce805bb9e08072433433eefbdf7f97038d271a2d6e260f7f2e19182c5e16a975feed362a5b07cbd9f7201192118a3c56f00e8fd6788580121cef5070bc0a53700f3601b4a039530e8df34d063b8eeee340ee42ddce71f49344ce38f802b15641a0eee73d41d5686877624e420d708f1b8c5c2e3f1b0876745aac7e3f1783ea311087ebe1a699cd890675abc97306157b9eede00506fb9a410278512383f9847949b273a52ba05e5ca78fb31f67432b90c5ba4eb72201084020e1ab1e1c80d48224d7f441ee794d45ab972ed20b88542455253a9b5d6eac9c0846b9c874a7bd23a6e93059372228d8eeb6134185c0069d9c0862db3f12f12699630e908e7c3c3033bcaf3f5ab50a47893277de7dcaa7c00036193152690538324f4175360d05fcdc3fb0a4c03c5f5530db8d0b296a3aab85a2d6ba18e5454ff509d340a2593c96432d9a8879021a998d5687453c4061f3db8cb4b0b6d853a236c7f884bdea871280fd73fe4031b8eee0cb9949147233a1a8d46a3d1b66db5be55881c63c766668e0fc3e50771649a077fbfa00a1760a61c1820c41096609acf1f120117f1174435780cccd26336123bc03cfcdd3fac2132820d6faed74abf9b1b29c1ea25c618afb07d638c3146902cd65a6bad52f610620e7d90213970dcf80c001036e4fd33925e003f2f2b43d7fd8642a15088527a84945246dbfaadeb6eb08a31c65879d63ff817e19201a4c93ecc69f3d8a8a24b72e474bad1830ad606f0869f3f810e97fb7e90c83ad8fd9d534f06f91fbbddf2f35d07deeed37d1495a0c7f8bce78a9d119f8b9df48000e10bfaf682f0057d33de8f803ee8bdaf0718a0a75f1f06e663be1a693ceed99bc17ecc10fb319ff7cd44a0043dc609e483bee71aef0b6d002fa7c3fd70a28f8c7ad9ebb82f6c6c62fd7360439ef12039e06bf57ca1e8f6733f2bc27156c435d25899108ee71a219e837630a71466446415a6d66a63ce39a70e9348245598da9da304db452f3a78716fcf8b2ad61491b8754422e97dbc17aee99085ebefa8482272d2c18103a777a8748db805356534020000000033150000200c0a860322e17848260a728d0f14800c70884082583e1a48b32088611ca4903106210300060404400433ac14053a62ebe1d49c3cda53fe7eae98e3e643a94226bf60417b85a91e3e638bffe5089ea7e763537b32c3cd1b038c3ed906023efb9e63f336e064a8a5567cffe1dbc0c094a9331d30f3b69c1fa8766c68dcdec5dbf79c271ee0c74b7ffa91677432bea0e7760a7cc1827b9935fc8bf91b5072e98c86924426c89c405bcd9ec76dbe2abf8b798d697cbdc896c50bd10f35b60d3eeee2e3a9e6833d8c3fdc9099ab586de87e245e3dd53f5a77d96d350a46ee4a20ec638faca8d75b58722f4c9d5bf121a79728d4dbff51812d25abf793941e0c2a3e16ace0527081eb1399986398e835311a9d843c292e10d193638c719ef7cfd7f6db872fb15176b6af55a7c41259774b743e7789008dcd33fdb5aeee4c0821d8133f78bf84d086cce763fd2975d25249e98900256f18c87ec3ec65ba3796c66396f3d40cb3e4c9235fbd9c386e20e511a6494adf8484fec0ac303cc9fd5ce9de955f3b8c3d890d84fc9f49851918390692050b930aa0579e9ad95d4f67abac99a2156e8e93dccbeff8726d19dbe1f738d5e6ed7c81f89e00e560d99582d3511fd4eae2c29a878ccd80c50717ab9af4827868365075a7a67f4f981646cae036e7d550443e5b091d11a8dbb68935740a15ed5daab9b4b9c564bedf47b8c41e2b26eb9f4fab1ebcac8d42f858421a2789cb6abeafa8603cd6dc3ae1df90ee6c4ac2ee834dd2688f12d65da7c2fb57c0b5720d571f17e5b89b64333557a8403c519ee0153a81296d23cb115ec9cc8faeced45f44fabdbb023c37503c1bda0f244dd058a0871e98bbd4e82b4b63b49ad2739856ea36ca901473eb0b125b68361cadce9e8fb4c36654b25830f9d53498c9060d377291e29da82124d2f2f2b081a8f4863e004b0616448ec2caf20752c8ec48e23aab98bd5aa73d6e853ece07c8aa7c44562ff00118bb279768075bf267ac182846526963eace6824eb4f159bc13b95b78e24f09182615f1f6c8da9cedecf86c906d856644d1778143198c830b1d57beb955188d86a275864d4f5fa80a4c72e30164540087cc42ff9727c32262ea5fc500adfbdc04c1a29e92a9f226a78adad762c357c9c06f4635c001d00ce22e486d8041ce8b8063ddf6937531de8bfaac2e6631107123727a9dd72003ae25618b18b7d7895e442553a98a6bd0b626aaf43ebaf5713efdde821caccb1fc37d15039cdd5081133f990cdbd4572ba8199fae0fd85cb60836e247223e06cd98b1a2fa39f743322774f5ba60978abce004c9f467bb2bcd1b1d1f16bc0c0b1bfe4380594a60e8c292610bca3f87e4b333474b25b02f8c15541743895ff0d42318117dd915595f6cdc4236582b62383e04de142221d853474510a33e68c682aba033e40b58ebc76bbc6290c30773b02cf76fcd1178b3a2ee7f8e8f0fc7390ab6e209eaf8cda14e00a8d0df50fb9901c367b8d55d2671cb402de4f72c2e7e2287ffdb07044884a22902a1b17269804e76d75db1de3187ae9943411682352fa2fa673fb0b818702808f2048681c5785b1afda62f312e6b7b34085bd8e3327cd5a3516ea969af67a2efb5fa660a86b841d56073fecdc848b0ab4820cf1ba6a0518546fddc3aa69f5022edec05965ae0c3dc47e8a6e85fc73ac1b4e09da48ed3d53a56bc3688a032d9ee5c8a52c55e44998a3c187ff1d5957efcbe0dd644cfb9adfe76930432b7015d19ac16f64b416e9a0b4d35431c27fa157c4d6546b94469717208a9ef5e444089ea933e9cc3c016aa0d2d87cbb90bd340d5d291e694d283f019bfc4f428959d736f5b64ec3e26bd24ca3c5f47394d134b17a824e181534f7c4c7016c5975e862d77f7c17203f98155dc4bc3dde2706189ca8a0f30cdb6ff0b7ac52c187aacf776aca195613a013c29d387817a57895e7df921f24384c56e9bc980f61534848c2bf683912224128644ca8599eb24a5afe099b80a72846470d30e9667628615161a4e182ca3ecc012a5f463a792f424412cb371d5289c610963613d2c89bf147ab590b596ad168d09f959ef77dcd554a927e8557c038723f857f9a6fdf08cc80a557b738a86981da9b15998db868ef528d12ae19edf7e79192f43b0030a00dd35ae6422ac970c657fc6f05d16c62d285b56ae153ba5ebf61882126f6416070e6d6caafc044f1410cafcbec35560083280eb41ae14101b312a1f906d0803adeca8d56e3b55c8b7d59082f6f0967ca9c3013ee94d68236909f3592ba01c801f3066d9e8f53db3ee9917d641c7afabdcef143a35918ff1e0b3ee042966632845372cb10a3d3d7165f0781b38fc300e1a6855ff14a54d9e0b85da30c8e917554f58acb08ce62b3b4d0f0cc431fe514351b0dcfa6ee4a38048fa8e95ccc4ac6a6bf7187a708329cbbfb45a20400f766dc5fbe3f8bd6c01c11363d1d5403eb63a2e564ca500c7c5ab9e57b63b842a4ca541f88c27623994bd1223e82a53e4ffd467bf353255ec48c98d1304d65a0bc0bdafa55e8ddf9fa060cf497c2745543ad5855612761105814e8c8dfe28965282f1121502ac17f9e23fd242b5509870abb0cfc3cea02d28700aae84c53c47ee4bf9f48611b8c30af99f36881d16a91b2626e9fa5b2fe34126128a51b518ff14868931744b9cefdf7d89295be661474a494f2305e25a17568dc11611278160b9ea49ac7aa0c4f9d1ae59aebd032ee838a6fe11299727b97cb6f0f3891bbd69cb48535d2f68b8e28d7a7e27b8cf0b8d8e20ffa142478c06d8a0bc22ac0d7ba8b3afc491980c809b0eceec3fd899fc402108979470025ebe8a8a222f98194fb3e9316e16ef9effd147df3da0eba96289ae5ca9e362b9fedc74695958a965df4dad6b72fff8d05d4a4be04e5dcb923077c745526bae38d9d6774e4e7e63afd4922fb947b0572807c84f889a32f90fb771a682a9bdf5155a31e0986d469b0e69181d19624d0ae384985681c49ffcb2e141ea8440f30b0d206d9815d7ce97d04067f1001a7f9aa4cea198e2bc91f6310bbd35cb4658d06a1e560182dce36c20e3ce539d4aae733fbc4a2edb6a1cbf13e18d3c52332047fd2f87bb177025aaecd21a3d78b3f859ad953338f7d710c9944a348921805137c51cee1ebf3b7abd2bd2eff48bc6c2f9f3bdd0b32de2ab613313936e325cbe3749ffa7a6377a01532bf8303a282701f102eb21647f7cd7fe6703cf7f5a0f1fbb0a0ecce432b02d948eb1bb99f850eca8db8a04a2a42df4ae6d8640c26f51a6926fbbd67a5c6f408c0d2229665949e909f22b189f71e1b69207e6e162b7c085dc9b1f84c419878845a611d6c7e1500a61d132064056bb5329615241cd71aa62ee67df9700cf1ef5725fad2508f59f41c94cb7ab6362247b7d9b9914c94602e602c81e1e69b2746dfbcfa05eecd43af1277f83745bf2a2bcc8105fbea6e82656bc44a25427fafd91311c34049fbd38599b17536390b654c662572d6180f070a5e1a5eefbaee7b186f2a51d0f94eb86423f7049c09867a6ba0e8e831c963a0895b087d0a72382505fd857e22f100695c6b2db6d500b563e0d93810de15bc602be8ef3e3e953f6f5071a3cca42145469abf001a1d644e6470733ab6f9153268eb85fcedc950150ede8e01fb480db574c85a9a2f49e5df326c5bedc8ad6e28ef29d8fcf5f0188892809f680888a9dc93c51f3f66d98713b45e19ce33b05c4f11d7bb1fb015bdaf0629ffc8633b1a0fa3aa3800fa003a7f72e4a60588ec8743207b6f21cf9f96b0fe20cb33d3e5361989f0cfa05ee8ac497760cb21e4e253876ea6c690fc812946908b79e8a354dd2665f3415cfa23420fee8b62d1743447aab966c99df93050992cda4ba6125f713a111191a8220b177f575b71426f3c25aea18ea52b6e24be13f90de47ccec53fc53d328697ffa8601d6f804022c3cb68e97f047cc83abf819d3218d36ec4d9951ade708a04561c7eba07edc995ed404c7c1b7f174246a2509c5aaf325d3ab9e467377de354d7d1802a79804da159f2fbe2af88adc376df0046f15a7c6bd109475608da1dabd3043aaa2d9fd190f62e131fabe00eb1487c39431aff841da124546423ce668fe09ee5500fd5abaacf527d06e5dcc128e77c0f530ccaed2e9c9d4b0461c8cf5af3bbefff458dc6aa2eefefc4f69e522bff8463d0343815021966c9f5aee60e025d943f37baeca3e0421500081742a80c14d9ee95d07f88d88e62e88640803219da46a860f1d8aa905b12356aa842f2d8e4bd536e625d3488720018d8663186c8cad165e9f3e44f6b6ca5da5329850b9332056d0ecc5c1cc7eb691c14d2aa9344cae648988be775ed2a5a3767493f9ceebfb7e54268d5c133addbd8c83e93504f758d452df4d7387168061150bf8d1c2e562078c4ceb31eb453672d4e18c45a5c7d50b3d76f27351715f300aa0507b2293d88489abbce4edea2a30b1295927f983f4e9fce7b547a49b1f2dfa38a0bb207e1a3a12d89eac800d15deb523fcc44cedc16afbc04e160e26662b2da8f05d238d6b81fb8abbc5c40e5c7ab175242d54e20fa0f839d54b32ec3ba87ef63e407746998e6536fa169dfd074af8a30a42996c6bc6f155698dfcc3ae14b76c556f0c2e790ac3ed65101d3f746a62e45d12556afc0841c038a7f9226ac88bff4c9e13eaa2ced3719a7a6cdf72771d3d1420cf79af1945e6299988d9630305f06c1643bc4a42d090e97a460602988dd09d55a0f3338ddb4f6898290dc1bb69701dd35b1457e1a0170b56380b06e82a7e86aa2ad2dae523308089e49c7b499da12a5826b44556984b4ce04b44412848a638881b2275c58d00ccce7200eeb5771b9895f0ed4d841fda00b28ca8cfc8f9a3249ecdfc74398fcabc720b8d458b3557ed9fc641f213abf5a7856f49394d2cb8b1a3196f55fba01a9691fe8d5c96701cb0d89f20245c76fc4ca49b6467f2a233142aad5ea75b0b4599ee4a86bf48f546db9f59396f73a836c176ea6544b4a640d6c5cb5135c29dc7ca942ef01f1e9c93e1520c961a1333f1625e04057ffdd71386530417f1a5d7a7b6c91ca2c870f23eb8cce3d44f66492c44a8f353f836afba51fc3d64c372c2e8b473a721254bcf0bfceff3867966954f999a814c4a5d0b0b154b6a3aa5f83770e14de14c8e9c390d8410ff361d5f0838dfe306959254f62e48adc6112ae26527bb0062c12ba5efc99a6fa8fd341bca9730ca51a730e8086ddc4bfda344f91bda9685e9867f16964af46d2da38c4fa40aa814aa99d13749bf4ee6d155d113be71763d80333ccbe9ad85090b228552db7b5bc3851cca82e80705b740df45251a2b3321d7c5ddb0fc8e064c802ad6907067bfb6d3ea8bef3726c87bdbef9f5cca7f30d644a1f5919df5ca9f58d02dc53007b2c001b05008efd46bff4948e11197283f84526e333ea5949f592a79c9a487ee2deaf5aa02d976a25db0710717faf8b196f6df9939ea8f409defac02ec7e97fad3500286567a1fb4178d785b85619f23ef685ce551434af46516459e00fb1c5a1b88c1ed57300fec042a57f70f91aed1093ecc1f4af0d1e34f494adc503a0a40739769cc95808f2f1e88520ae5b3f5940995ba243a12576a917d1beee263657207e7ad94cd2b06b3068c011c60fb1ff9dfd2c07386d0aa3c7f461d382f9ebb705aa3db04f03b651ff004c518e63f7c65baeb517b0845d83523f57feb52cd31a0dc803ebcc521b34e3c58081033b77650efa62e9187d2291b314604b21df488e64f4990c8990a6f36a9367bc838d6719d2ac2d1a2d7d667b56511b37271a94e6ca3caac8e3a1d013a16037807ebcdfe18bfb9e0f6521cb87e4fe087283a3875e9e60b550a0ddaf9eb2b672bc3d3a708b915eb573e4eb36cd2b7774b21f8a3504794586673342f0e8b13d13e46855f2aae9493fb020bdb826bdef0cb42a5aba683fbe60c48146a1a77da9187a73b833550c8bb91060d970ac3d2ec5757b6353eac66c81f4a8e488fe6eb69e88086ca3633b5b3655a07c8dd2ce7cbbb26589b4b8f21d43d723f80f0c7cd8535217eae639934e30caa982bfab4a6c3b38fdf4e163110414168ae9a527a6605160885dc7199f8cc3d9afdf7a369f26742ea7df8486badc6bd765a2fccd717800d46c36962271b06b00dbcfe576984c58b5e7deebc5b0d24608a87799298632ef373118d225bed47cd647e298643587c0a430b01ca837c52e0788df4030c6b52b278bf8b5847f8498a9496aac1b54815cfb50c33e5f0581ddda77c7d95c38ef4d9ff0268aecdd02d7b164bdd7267b66e91f0cb5533ba3cd65840ae0303838d390668185f0f8b6235ce490134eaa7e76ee062c82999e666f30ad251cde26fa4aa5746ea2acbbc55ea1dd785d357099c6b0ee1686d9d4942aa96081d29bab3545acbbd2430500971ed86b1f0b2482530ed2ebf14f7bd4ad3ff94eca7831fb70062ce6731ed80454ba3bdf7475c4b919f13c491ccdf5669416d170e0c5793df76518e18c3772e91b5ef1c6095fd9d4bfe0d973b3666042df85b6e02f1973eceead3aa3502498508f7c082d764a1926122900a2c20f4366592563d1b55f972488987214d63853a6036339fc387248f9da2ef7214e7991c23a16b04431468d795e3c7b2da99257f678d231d8b89cc96a26a68c4b8d82a451fd8ad2c79546402bfa365c58f8bc31137fafdd03be7cef9c594a4b7f1ab17fbe233a665c1f071e5a3073c1cfea76b9b1252409bfb16ace86d006880d08f0a035f26e689f27a77e7430d41b77785b56d31c307d2c0b4b1a33d8ad0dcb042a2330947513140aae52d98ca629b717ece28ebc04fcd85c549ec66f63ed8dd952f1aeffc971f5469330250336e774f057afb15b224c07716bc2b2b33d1c490a67ac82f84147c54181cccd0fa76f5d3cac128c8dd781158ffb581ad87c8e0abda6771283d6995cc2e27a78bc28f9dcb6ab478a95f01047a55321a3ba8b0eda1db2d9e8eeef611a0e0501a83cd3b17567dd1888a1f0aa7b72c48fcdde05c13e5c909eed65b6fdaf0ffe305445d988476f4d518566aa03dde53ea7c45cd1d63cc700457b20e7999b1b04eec640c4e03c0250477b4c24b34513fbd7a58eae9ca9daa3edc905d52069886e01351a9d344404b52337532253dc27b3685bd71cc26f8626e9b1b1f8f0d51fcc83cabc8592099d3241cb7af063e03d71f688938becf2efc9160494a2ac78d5074e928382d6412719339a6e7b07234699d5147c1b8a985495bed6f49926844b2300a0c9f7aab8445de6796253f54205e446f2cd0113a8c3ebb7d3e57361f03cd71a21c2319efa7da6c0f3c417ae916fbacef331ca8196f8d104e594b55be7f9a9a11cea92feb65579f2faeb5d2d2895044ca2979969e3b65d790a0d0765aeeaf254e1370465677b6a2366602d1328664f23693de008ff39441030f1150733fadfeb6c38cff28519b02a145a4c6364d05a756b1e78670fbddedc947e13b6ae175fefd15a10564252275495f6b34c996bcfbb743644cbf89a69b252966f9f4047f5f21011a90f85bab824dd2974a5125f8bc6ad6b4a80090105e6f8342649fcd4da0d86ecd4984e72783f6d1e657e3da8b9cb43194c59fc429709e4e5023e8bb5c50e864d27a11a6d3742b5acadc4f23ae21456b9020ee694b7de5663a7a86670f34d5217f72564eae30bc40f510c2c60b081230adc5c2aacafd1e66f9568b5703f6446c504756ee69733fad92e9aa689823d0a23b97d46b99612182c95bafc9819ff1067cb41922db2dbd3ad5bfe33b48767a688aa33f393abf4933263989a7a564345d7c83d0548487b0e09649f112201c3ed470109dec0296820e1505b76575d44d4befff5dfd01c1fc49b010593470761108bde3a441c7c4fdaafb190b564170de9ab9df051e7bb0adcd9908e391dbad9f0ebf0477675ecdf311799e69b02ee8318bbd2a025c3c0edaac4a3592b79f62a4837314c11201a84f31e9e6d958e57866040a5f2bb06982cce859b06162e7a040a5b33f2be5623200756880a328c9a19ae924fb7c896f5496a60340abc3125eec47590fb92dd03ca44299e8716bea1d047d06acc421483b6e41fc46a4a745e158aca19797068758b833d51a5179d53d42138f6381735cbbb0c2b54426754a62afaa6fa98d0cb4625e0b03ca0a3d371cd2e6dd1ad6da6d2bdb297f5f13f597d5b7077ad97108d0e98ef8ad3321cb4370e8bf374dc67e3e00030171ee1601d2f95086414f8c70209dc1716a50219e35992df51d221d1fdc9a18a45e8b29ac81e5ca93d30d428216c45440b8cd926add5519b0054bb86a61b307c22323015401c2eb728da840ef047d4c2abf2996a60944aae607e0e052139c6d12df55f4e28505a16c0e7ac134af49afc298e4f7493270bfa502282bf2bd621c1aa9383e0a92d5858523b198cc46a14067c1e00d8de0b32ed1c531761786b9e130d373eb9fccc6eeb2eda5d8f75785b906bc1c05906e0097234487c6f9c1bce308eafa1615256edc6b6b87a2e70d81c86576634bba14ef1b2daf37a283a5f4cb18ae78e59b20362d53afe4710bcf560be1b0bd378dc7d95accdcd00d0c880634eeca564b4796895b914c7c506238ae3c395a68137a2195e000451995588909204a746379ac80f54b7755f9c430f7dac534b39ad28c28b99e8015638307e72450b8cb6d56c68b791582e86757a7cb90d014c783178b14b8bfe53fb1abf2a9111591961bd0131261c82275d1628a06024cd36e44e0e4fd5204894b6e17086a8c8ba36d0aeab3737556bc35642082d351adfa2270bc1faf0ba09d661ab6cf443caca1997093d787a97413cae68482221254ca6ad099580274db1646fc195b4b105cfed9fba2d3ccabff992b2e05a6aebb5d6ebc7ae40ddde56c86763007485ae72adbc1375be6925b889e3e02259bf24b1aa12b76f9ad65306490fd405938953c69b71f50d702e82e4c451a537200e3cc349f342daf3a4c3c7ccb0f15e616383124ba5de8ac5d60764c040ff56c415220aea6222300c018f7ca2ea3dc57d508c677b779fdfb326d77d64b7cc573d08f2d8d48e79cecd62f080f04b96580534a807432fe4e4f0433472e7030652a9a146b463f83bc36b46c41ffb48b1325c11a3538a845639d98c970e1445658a013a8d9a72ba36aedb034b621b89d757e460e32d771eb95782d6fc4a726c9accb93774b04d23430bc9e39b9c2181878fe1ceb632adbbf2df4fb39fc55a73fe78cf0a50a40791b2f94d84e756b7c29e6f7f8f0f4c44a87775423b21980066231bd3cb306d03a86ebfc70a38aeecec325b7f9e8c4ac1494ee261f2a283ad8a2970450d2cd5254dbefa371d98ba1b27bfa0284bfb1e4d069735b724225ad6d93912466c1a74f07cd9843d4c411fc05540c4777283635a8ba7322b10910fba436c84809e0c1cb773f53860351cace24da7f26f1aa05ae4c0a1a1cfca141c8d28c05a16ac2cb83404860d2702cccb54f37aa462a600e70546cd3e426f7ced4f257c8a47f406b1a0696ba3af516dd6e02e3d55df110ee1ad2539d3d21f7fdda85ead65d32d69791e0ab6b3be2b2a3f158a38b2d8a25ca8ceae350e29a573a3e1c28310a92bfd4cccaa5ca4602788c2936196e7b694c31001029e7e9131abc4e57be60c8d60d90dcb73f084ff7735d9b6b40e357f528f934cc700c8d873c4018b91b15293e280528bc1abbc95f361e5aa23a6df9f4c3ff3a5c6be857892e384b0889b5c844f5f0c63a698c04bff8571655ba39c0d6d98bb355d39b4eb75e43715665d93f7d840aac0539d367298834087915c53105f9282082bf20629b93072355d70ab1772d0069349560a1901db72e359a81848280cbeaaa41a6255212fc3c9d2c035f185fb6c3f0a95daac8bbc6b7baeb449199ca6e671f1116ff046fc4d2fe77d654cba12b157f2f217f4c9d24de8e021b95fc4bfea89bda26b27e2dff3956947cd72fe88c34e647c24f80a64f157eb3537a44f4560089e81ce39f4814c7c921a1fa0c5e85666555bdb78b272bde309a023bb70ec66ca3005144d6de55edea7ec7394d1b2eed9087eff331eb5bc5f92efde73c5b1449dfb5f8d822094a12624a6de71d2efba4699d16baf0571eeab785a885669f7a64c1b5cd34d43a2e27d12e5a726b993525c633796837224003c7b3602469c8e509304f21905f743b88340ed228bb1ec4ad54bbeb07e8216d08e31b295c69dc52ef205e8ebf038bed90be5f70c60bcda7782207f3db2650d2154d7d774ee622bc31ae36232a1563d1067b4eb0e46aac2fb174a39c0b066de4ad7ff88b6625f7d7db6823b3c919769223f5971942dd7d3c9ccfa912f38f6096ada99838387799883324dbd265f55e9f8b5d34c3cdc699464517ac47a02a9939a82aa997f3a37696f4fbd9555e4189f787f9f71d3d290864aac4a1cb046a33875f5b32e9096f6969c4948b49ef670d0c8add2dd394568bd98985bc772598d18c3eed9327befa440387134671d89c27a04348f8210988b37304870ae817268ea4b03bdab17d757423f12a239eab66631fbc9b8ab917fb0d2dc0b89ea17114f80e01006014f1608233a4fb1f11c9d1b76e4ec072518d98848fb2373b034060fe6b635dd7af23d1188d3873b11a5eefbc847ab0c8308b41eee2d3bcc5fb3cfffef4a800eeb7a48b65d6991fb630aa53788d49e3abe8faa94d78b2c4f9bbb2769d9501e8c5303be66cb20046b5d82acbe1496501670b2e05439b70e57ac25fb3f018d4d37cb45bf7c42f62aa5e1e221c6b9b28407e6e79f9cf6d1b358d8461b9ffa992b0d40fbb18c5de6aab2aa76e3808fac00e780342c661ad75270afe59adf06d299d15461ef5e081cd4e32aff98ba8f7e200124bb361f1b0116e66e6595819e6eafba9af907db765da91d61dda9a00156948626da81e037589f371aab04fdbe959b4f1fe0d267b311dc59689b8ced5e175a1906f194b21712770f3b31c4ef87a826ae9515df000e88dac119c99004266fc18303621595fb33b04b0b8f6306103924ff5d26540b087aa20df6d04adbb9c265cfb6d23e1de3c43204f48533b6d6a5e7df1827e8f8152c75f7bad60c0c4d3deb6b3de5392798ba377cf6824017190849b04e2e14d774ad42480797d80817db91e36a5f26841809fc418d6695c867d0464db2d4390f4260b4f1bbdde97802cae777bb192f8b093b3ebba2a865458d262b1a1ee4d826bed829bfb52369e4a13307990bffc22269b41963c938b646935bf28b90ab1cb32fb8f5ea03229c8ec4610733b4b09eb5997aecad42b68e119bff37536d9c6fc0e240892d488c8f4e26757f640d94d07fd7a4b49c7042f7aef009a8495af1b9aabaa32b69bfb611c4bb6f53958ee3812cf95c091b0f55220cd3c6d8539e3682de051b36c348243bb6f5636ccb51d3bb4ffdf525e36ca342d7c45c5e112ac40b02af57da520e2ff87c06fd575aa8bd9a2128b9902fe131d9c39a9c7fbf496b50aed58cea85b516ecd60996ff961d073b42bb01ea4b14b6b8608ed3901a7f29302bd825fb74f5054bd1660ecc654e76eaffa4cd88fa28caf6256ec32ceb2c60bc50c1544c0fad34d0a51effc2ed614630e777d126164013d729701fffa0cebd3f6ae55644dc6a0798e2a068fae33840a03f6468b5b22b60db75c6faf8c97e0f069fcbf8fdb60c9cc5879357f0188b68376da4d6a0cdeca36e729a63e0ce5f59de37e3017deb575791c57e9620fb2de96a7d8f21be0a7301939ec61819b8ae52abc17fac40ad022fb06304f71a40d20d7784408a4cfb10636de17817ff6fd862d7ac0bb7c2b640b5751078c4885f4fc28b803ce31b20267443e1251f6f248e0607299a9d912e73a18dda523911c36f840c7fd7064a245478505d30994d090c2291627f44552ce0bbc8a37008de2a018a38a4c55ec085301b5dd89d51ef0981523d72f9697d8158d3d030a48ca9aae08ac397545e443675925f75cf51cda139d3cf07e73397fb8dc520884214c292b43d343258314c471f4068682a463877f12c8581681ae56116198752e6735176004d5934c99e2f84f9072ee8d9d153a340fe80906c95d55a8c9cecc6d502255823e95d971ded6d2d6a1cea2f0496c37e609195b0d0e500bc15228be89f59c4d5599a4c5bc19e816d4f6067aff643c5edafa203832bb50cb18980704e560ad70f57546496b34f2d535c779a2a51596e8c7855c05c0e7cd9a8b916782abc2430131ffc773837f1e26bb650ebb846377daa39324f298956c08ff5cf0fbdf2a3307ce0213b375696e2be34ded5835a6a2d73825f79c92e74add5ab94393066d3821526a7c720e83f80a44abf231a3222f0dc7a4538d2f9141f7d5ca2be517827943108279dbb22385046c5ee71ddf7ea41e16b077016028f0a18f000f821cd83ed20afb1638be0296efb9865c816e6292d4416e165d8f4974c87aa9a1f9a49620494694ffb742a5ebe486c5777243355ccc4d942ee5aa512d80452427b384eb5f8dbfb2a53814d19ac1bb310b8e47e243e615d68d9bb18f33b6c59e6ea4cc0bc61a2a24672f23d9b1430d8953f7be0dba7805714cd2984c13f8a7f55932ecfb1ba008738515170f305854a408f2f25b2780a915575309959024221d8d7d3501a3538b604d2472a73282228eb7ab5f1f23ace15cd85aa28581173b847650731cad92b488f04a9cf1bddb329051e1c411aaca34467f5d1c6105c5cfc059d78f33ea865c8f3787b531c0603bb1c6374ef72adc8106690f86de4806481b7a199ffff55106eadf8e6a2349d3025e9c4d6bacad5b6c569f519f2e85771d601c0014c28c570c17659b9ea605010700789703e086fa669d91ca726bab52998ec221c9bc9bdb144304adff22d3738dd7328b4c19f76c16be3f76833fab29afaa5b0c0b15135d7c3a80421a150c48fa4f65792d9ecd9e14e7cbf07530f0122f58a1159e1bebabdc375861850d77449bbeb5ecdcad20f2b6b6619bb9e57520d187f8eee371a0f01c784d1491746686ce3415520922ff10b49cc4aeabb185a9f41c449129b99c51658acd5ee7418027c7feb40ba420ebbfa2e759895257576d9adae4119ca5949d7ca113a18a1e7aaa4a0f5574b0128fda51ac7f91453424e4550ec0b7f3643fc4f7ac1900803085384deb4e016f21bccc1007cebd66d52ecd217adfcc785d857f162877d41016f197b4e2f916689bc7d4b205625c4d348165d917dbb981816180bc59afeca4184c842973693b6568f36e477a801a8b4e6d6c81710167cffd5929afb761c2101acbf754f7a08583f33dde4978af1af3510046f0db6756684ebe3e1401d81c00e20f3185a863e216efba675453b202d28c62e3491d6eb63c7d37aa10035c85a7517795a330b154c7cb2f6083c136e9fbb25c36e6fb192d8fd5d55c7d99f40dcc6518a419cbe4e4bc143aa301705733a263402ace984fb039ceae69907c022f7219788edf9c91d30281ea6026149c39e2c208d6337e76289c62d7febb1dd5101338d03c489b6adc2a94708a556c6b3558e49ac548eb29cb428c0b584cdbb554f3473f478d86a071e67cb2857ac6331c1a99c89537623d4ade22a5b8bb3f58c066cdd5a78245b54d1b46c5508e9aa5ca480d6c0197c30ef4ec078d86c7c72b9b43f53201f6bcd62b5ab8d7b67b01078e005fb58ddf52c091c11fc63a04db4d4f5ba97598ba81cf668ca917e6bf1b021779ac9acc81b2ff42fb06b2cefd491adb7d616bac7d314212a8966e5c79f95bedf02304968fbb040c76d423533b96402fe7407535ae831ae5cc893342eaa58a7052658c43ccdf677c5b9a0a729ce66716d1e0e7138fd5713c02d3d3aaeaaf2430543c12610caceb5e667c3eefb43e9c4dde55220ecaf3df2d3e55fc660fdfd6d8f4a399394c1fad386e3a30945c406ddb95cce3faa541aa011b4fceddf4f4fa5eb8491ad0598cb7f35dab27f8f5d0179ee5c3ff96d970c92dbd67826be8b92a1012207fd80ccf0df4f7663abe11e21717fb20a130a4b7cc3f2a4ad0909836f3255c844d43e9eec2e91a5683962f89c0b8c5c7818e376b0dad205bdcce83f18f207c2e7fc4ea3f106ce02ae803ceefd8611c8b708b335f8c2fd637200cb678123037135e0f237e6f9f18b04e30947bc0f0ca60895407b3e65dbb7720ab08f8fa46332dfd0e26a4dece89b67229f4a44ce1228e404b179442133e9a6cf90af982dc87c8495ed2f55e69c3641533bb5c644f8dcb161f8373a87f8d90984853151252daf616c94e0576a0df0d7d8c8ac2c6df90eb70af87ba0ce497d35a1b0b9941beaa5f6f17d3866a3bf3eba92347c56e7195483a6b66dc4d504da7b010674f4197340b44bb4cdd871c20502fd1caea9b820fcd47c828afa01021027e538b49239b9a990ef86730c82a4a9372e956c04a92b2ad355c1b423d487c3cbc112a990e72f755b721057880a4690a8d1f92099757ba174d7d887f1d9db36756d051ededd04c9b5b5020f15eeda6e02d5bea38696fc277177cca7dafadfb0184ed207ad0f840e0d27bfa626e48ade790a78f6f0cd5a127e283a93ada77af832706bc1a66d87f73f7f70b26859093f05ca7baa3432cafd5a42981ace66c4bcec1404856bef94b15c0af397bada8e30fed61f41681050cf98c9bafc5f6b94d8e9adc8551a31608eb43ff9754dc6d389eb6c7eec194c6234735aaeb5ed3740c5712e0a2c4d550bbbd3820d8353c12a80089856d01d1f559bb8c3d85d141e571c7351aa84001f802004f06e06e0ee4f9418253194a80cae1f68f3ea80186a35893eac6c32be4dfe0731b4322014d8b666a58081ba67c209afea223cf0750746672e268094cb4b1464c4b47a6b3c00476b645250105717a8ed7b42809e35ba86b264e7fac5d704493bde4bcbea7f7852649929b2eb3f1633f1f9fbf8d7a208dbc9b3ab3dfb9b2449c00afcd03ba03660811f9b6bda0d92003dcef87b32e1856e5d1cabe9568beb8ca647d0d32f9e2b040f0c30ae8ba71c02914658d6b47e31d620e7e85d4c6e32acaa125dce72acaf3c3af1770bf1ec9a2c88cf20ab6be60c9a44b0a092432f54e4d31abd701d5515cad6f30f9a62f20a5b983f39fbc3aa7997b9e60fae514f7ca3a18312f396ea699b7362b25e2132c34c1657adbeed960afbb0aac991742f204aaccd7f80432ad058ac4062b68d5d16e8ff8953dc32adc059dc572baa1b7495a0cab58ea3eb14e0103ad282a56b91ed5d43d6e0f18f175c98e02eda980b864ce32368c60381a9912a4494a376d874de059734e878e1fe264c61451161c4d303c98339c530d2a5329245ee2f081964883cfe76601fecbd0e9cb22033e74cadb3dc5857a37c64b5e01c1d6f809f810563b38d000c7557613475297eafb8e2587192fb9cb048869ac64a48737d4971363c80a054806df784cc5ef30e083e9ac6eb8c1701b08495a832340270a4b604a9f2deedeadbf50a16f12aa03dfb2d8009028f3e9baf68732fc24a95b65feb3fd0c25e7b52b021a50c85c02830f7dd0729bfcb440fa7a471cd5ed864487bd068a0a766b5e15305934d2ab6caa449ebee6c51869a064dcdd418306763257289ca32e0a7be9a93e866f388cbd85fadb7d68f55e346b6f7fd5837b3a71ac6e245b39c1f1bf48b0937dcc0045d32a2c8f9ce0f4a29deccffb65d35af6994a24b743137efda26c028afc0482ca9034ef0005a8ba5ec7c450f486b84c65deab89d00acbcaffd3191026b01017b56bad2969c35f79fab7d7e6e555015ea9872557a551cf7636fa579cbaa67e1867991c93db45ec52ed559819a3701d6daf9c104dff2647451dcbdd51ce1f837a86dce8a7e6708abce62b85fd8d8130c8834c7446c571139b3df6a375b97a55556f7199c74787303703de9ceafc1880179a61a075f80761836b98ae5502c1dc9d860a244328d1a33229c3fd7b61fea92b8bac334cd36b971071f38aa87670dd178417e4ef29bab34e4a22685f57e1cb12c899605bef84494cb058b1458fd683b86517dfc6e142c603e48c6cdfe3813a65b8c8fec9fe86a0a80a20deeca116178e5ae71cbf4226aadb7098aa9a87265437d62583528de7ffb1d26c887e855de6befacfa6ad6ba55b26dd1dd27c238589144a2080d8a1dfb3979aa1c8e0e1691ad3911ba66b1ff705856e0d451f8720d2b05964fc6a11509ca76b3060107cadcb45fa3785c418348321caf7470dd5e52f756d89ef4642e241e06cc8626af2d0db5da0d76ba074c59a0f8496f45a1d55b61dc9abe52e250a34f6ec79cf353998e712c62e9e7782c24b68676813113269263bd5a36801f88c39dde6f7dfef6ea4c3972c4958fb0fe63b268dff39f7b3df2481ea4acf1bb5db76fba5c4981b7eab77db2c23de2b11e2ead7db601cd1b6f5e86b5e6c37418763555bc8458eff7e802b18335c72ce12fff68ee581e3e230af6a56bc0c9dc99921ebcbd1674bee1b902237f9ab70edb6b655e82cd7cba88b8e2849e2f15dd206721ad142984f65ef13f3f143e5d95c25e37c4672f3efd4393c0f26b5280dc330e74a704fd6421505f65a923a4b21c40668102f7b15dcd0f82938fad13c4747c591a3ee84725634186877219dbdebbbcb83b98118a4640fe93305b571e7e912112e63e1aab96867e438c612ff5b32b828b09dddc147db76cffe1dc8b6542d388948222c1956118a203456e37ba6178300fbf711de38c758531b004a227f1fdab53a826adf3e6329dbc6cc72f3ae57e566c502fce9aaaf7d8bd42dcbbcded253e6478429bf846db7c0185e590d391a1da5eadfcadfec21aabbbe9c8e97706c6eced6f8b1960f41e6086baa9c2f4385195b124df5825dab2e57afce2ce59628ef6df2f5c644de08071db5a1ffb3d061c3ba083c4c874bd9d040c87dce6d7039550afd7ba98da24f7fd96a07f44040639452d1e8407272a137c28233a650706cd554d37c5f44466dde0777c801ca7af1b3e29d38e2b32321cdf8f26d269a8c1dac3f5e95f0393d2fd0c1911bfcce84da0112d556df7b06748c14c66b1b2910840991a75184b669b0a83bbd65a4267d8cd65400e4adc7ec4c706a478ed4d5a7923e8bf68941a6f397b914aa2137daaf543c73f8415329a5277aa90f6a632d1bb41ba4a9da1bf741b9e640dea902c906f510af80843fb59f17dc8dee8f27c4b255c0338ae75918311eab7100518f536fc3f1927bb56e3b186a9526748c61f7cd768fa1ad1e4376c6dd8ae91391a8a7671ec8b446b47d8d92a27ae5aca8d20368870a731aa411a2ae493fd133ddfb2a2ddcee5a8b6ac3665a6fee0c64124f07339b24d4ae9ddcf0f46ec28c636ac7fa209fa4c8cfac5c4c0171df05e4d8c69b8516816b0df2b05862471f65a7612da344c479270a78cbbb54d6f496a2333024b818b0d21910658e6aad69ab2c816a8d9af76b2576b1447f613039a5757d131b2bfc37351642e3ae6a2b8b262d4160225f937190bc7bd8b774edd8eb2d12108597a1e5cb05213fdb0cf0e1458f16c74c71105ad80a14ed1680dad776e6213c2f7a65cfdca20cb7517802c7d30d25ced7df83a0dbce5212f427989db4edad7622bd731d9d74b62a318858e0586547395d772f5f7d0ab376bd6839b9c15be9c111181d0d5c3cd460a0d1273bbb818d07bb0ed2a9dba9cb59b0e839bc040bed2809aca1b069a83dfe6da1b1b800bce62747dd66a3d270991335d0a80f1fc555a6c52b458369db029071183296ed98990f888ae7240bf8ba8609111b01f64dd4c7f9df805b81a58abb8ef49be421820093b54efa715f42dafa6e71a205c7252caf80b72d2ae51c0c017d40218932150304b2bd548e4bb009aa5a968d182f9d4702f4141208695d230ae6f4c8f7cc28698d3b0672acf0df2c36e57500429b460cc89eec2846e14ccbb2c2d569121dbd8fac0f8f291c02e152e0f51889b02e88b8469ef16e37354f3f63fd038696aeb8ae5574334845ee23ab2ec48cd066aabfee7ba85ce307242abf794d2128608510bc60a4774da2c9074ca44623460ed6da1c958aa10a88deba50b1df4d783618d2a30186845edb4d44a24cf3aee719f0db34cba41ad30430db935c2f30d276f11e35b47b6315e82534d07f8b1696cfba72581e5fa3cba2e7befa8c8350d68315c7f758d87da0ca0bae484b910babc2f0153255da145dee6546d8431fe487998facc1e8a18b4b2017c0f8a993b08a4f853d645cfdd7f12294f6e65057717656971d2bdaf8846350e6a7b4db5565bb91a6f13eb8421f1bcdaba61f5da99fef77b9b8b6ab5dfdb0a1fcbd2624146e6c54efe99002a7d1ccef3a6a049aa79b3ac7a082c9a9f6702df0e8f1fd1c3e0907d13ca2d5c9943be4b5465b0a5922f69f1514bea4cee8368afdb09264d20a92b4b0d54a917b8554efaf87062f2e7c1441b8a6a44eea9fb61fa5d28b2dd1fd20e88281f1ff52d248786693efa499ebd7464b3738aced1f499222af7caebdc4e21c5893461621afffc7edb52f2f928747875a10593dc114836349b219122553d8acb0eccbb105349265538ff196a8cfe7293dfa81ba58ca7b7979ee3300d90c5393ac4a82c6276c57f930346deb7721b993b1bae09e47cd6272867e5b236920ac3efb9b9d6b41e29ec033a586071e5e53cb11e1a8293e1b49673624225597c49a63755c2f53f95e7c5d0857afb31ad163362c4f8535e2b2df837d64c0b6adaf017851baa167877f63733b6715993e3105d6b1a8f6202388fd5d6ce021ed6bd30f7c2145977e786dbbe968e032ee5929e65bb5f1f17ecbba8a587c29d69fe430780d30434db3f205e13022675a75dbb582c0ec8bbf00b37e157934cd16864af98080ce4789b24c40dde2d45692e51726f42e5f5c406deaf27b33c2e268dc7ae03f8d466f5a6043b814fe0a23cc85b7f6e69b6750e3b9352b34e78471f628ddee680be61a2cb8b371d324451181e54b00468eb1edd149feb6bd8b65621b6908b9d90dd1d76da5d212bb6afd6094a2398b2c54f41650082aa65511cbc89f8dd6b8ba81a187e288d75f120fc6581583d6502bb0b22bfa99cd1ee45bf31a3b9039587081cf28a91496152901d9fc965c954cc71dba5c4dafee67f7c0b2b62a1d7616999b27bcea58bcbbd55d7956ba41793854e4d2c59b51d6a9114142edcbe9a6e95cd0a1733b4c2ef80dfbe56c5e92d516edc68646f89ef271cd3667e0c3278c8f968e8020bbe7f51b65fe82cba0ba3104c48716d03d3975ff1046e6644b528c89f10624c1f99b4cc2936f268cb7defa05d49f15d5a82946c98a634d9004a315d50364ad980915a758b35ce3e91962e96199ede91d2cddd212f2f3b1efa465e0ed0626a5fea7652b4fd2aaec1183db649ee9504d5cc415a0f92aeac9a4afc1288341d8cf74a711984beb31a82fb605cbe77599fac0c08ab17929c6367ac54c9c547385518ce3a20ac03f700d97b38167f15e8011d92526a9d6391a57e297222d6a00a9be584d59ee91449bea91c52a80087942c66ef1ac5bbe7f38a3060b444552cc58a6b92fe4dc679542f84061ab27264ede6aafbfcbfc1d506da2b43970db032dafc7056419c003e7614b154482077ca1ddc54a0a446a8116a70f0c6c241ce2b43567bd8416fd29471544ae581740ce95a52983ec0963aa073755b73f0e5c12d796b05c6a7542d9e4e4d092fb8ee0dc89a8f5465a43e0a92c927bb32d16bd6055d2e2abe860eb4bbd652ef090dfbc52ec9fb3e86a069ea63fe3390ffba165177cb3768e7bc5e45d0b86b0aac27d6660426af993da77b80794d1532c1e20d8c52e89fdc370f8f1b087ab689df216285ad668f1a39985fdb8dae8e226e54ad723ac96f8fc4a731e0c4116c93fb97c2857ee985a8f60bfadbd82bf2b1d97387c0cfaba64beac91e72d525beff87935115581ab9afd1812f1e61b46d99ab2e9016caa2b6b11a6959d1212e80aadc5c1210bfca8c00d8ed767012d4cf8101a2b4654e10cac7342fee7fd869e8fc83ab7ae0caf55189511f266375b4aa66227e9f3b1f0fd37cf9ec2cd64d27e4c4eab78490d0cbd03ff96237872959b6b64e2893c80512470794b1855e63b1077d40bf835c93b11675d24ad6396a5327321c19543d11bec71cbb802aabfc55b9d09c7d83fca03ee3af414fda88a4eeaccbb3f4717e9aa7d07a0d19f38bfb3ef445c3f6a5d0c1d9d89a2caf7812fc36d1b1e10bc5a3a5435af6e2087c34e770c1d73fabc8f0fa908aa4e487a8d2f11887952008622ab8b8d9db8d981829c54e1a5de3eb3766d0f5955ab74aa2486067cc75f11b74d400329c23c07210bb1bbc39204f83c445de9875f9dcf94e0415271b5925eb32813035122555500f78f0c4a108d7e0a1b119c278920e1f3ba344c1fe250e56a577710377b4d08dbd7dc3491f4c3414bb9fc995fcbd34d7b408f36f3b10d8af513d3a85a62428f949586babd70c15b0630afe1db956d05ec8fd7ee4d4250df08ddf254e1c27ca192accafad9bf4c9301b62b7fab614d0667351334c92a6bf8d2db855b9d2031d371059e1569b4e3df408b4e5613642a6ed26e65c7aec3c2a86cb2533e29e80c08a3d03d0e653c927032393602a02797119d62c678870a7a13b6420bda1889804c73e930f65179fe8023f3fb1661e64d9e5479e247f7c123e9666c19e89b634c322d4d1b3fcc45c61c4b4574822967601096a83d870ac9ef98e82cec79c008de2e0b9c7afc95e86b226dfa81932ba175268f0d7e390951e40af0b057beeeb756f7983496ddf18228bef4b3a8549f943e88946ba49381da02aa1bd67d0d737194cf1dfbb93e36b5ed54887dbf908a353b65092afdda2d4021b575f5ea1d4f9cdd6e968a96ac3dd6a442343d90b1a28ba19d955bcfe338f40f59e53812f5be502e2a082e501c3a356200b47e7f0575bea4bdae77a9e385ea9c2b71817fb942971cd659b2c3b0f80b0342c7c3bba06adc8d75caa5d44209a8bfc55000053d43868041d71065ca61939017c00d16f9398704c052eba7e4869d72369334f29fc432587c5608ddb47bf5e6c08c3ce58bb1257b12973a89b3640110accf4f26a7fd0ae57ac5db02b7709a27f811117bb33669f1139e2043ac9d1286f288cae9696a75522e8f4177ff0b7456f6170892c7865a92ad49af6a85d11ad4bf6cee3d3e80c7388eb3666ebf4997812fe14e795f7515979f5f1ba3de1592c79288408862985bfe5c33a360dc963397a809ebdb21c20d9b681dec0590f8d98ed8d959ef9fc95de6adf19ba01d9049128f3f9f0e087f4c68d201c36b8aea07a3c7577aab068f79f64cd709551beb2165a277d2a2dbf89e653e512f0f4d905c6a5ec25242e220cf838f5382262481b6b298e32438221effd31cf0a49688e574e65e8c081fbf6a680fef754cd9135a16a4f932d23b9524dcb4831b9fc01e52c454a451759a82e776faea3a6f81cfb8373859bef442ed3dea358bafea3501b6b72a0b2886ab83a210b5378bd9563a7908d4d33622dc3e026d79e58f16a22bb7d46adc2a982cede2fcf5ce5ce7c5ab567c4b60d646a762345473296141bf0833e797eefe35713af32669b1cf9617f75c785300e2a092645bb62f23887c13089796a40954bae6426e1898b3c683bf623cc6ccc138445c5c52d1166cec802b0b6b51d52163e6d0c55989cda9f8d68270f9924a52e197cd38c0bba515d2a69a2002162dafbb5258a61581e9cda65163040cf55f7aff0117d6c2587ff5b3fa9660d53cd50b8880ee0ed3153ae91c591e6cc5d16243c1e06d45e827b377e988ad5d617af7f3f2686acf249ec0e5790615d0079dec7f9339106d3fc44463cac394108fc86c83fba3b85fa4c78aadf5b4d9ac8eb78d0c7291239e65a784091e77eaae8ba450a0a17daebee902daf1d1e460c992f8e5624583c8c651a130c14c188c585cdde36c00442dc29f50e5d3e0e88f6729336366920956986592ffc25e42d4fdd76fa9ef2b8475ec56471226869ee8be0e6bb0624db6c7808647cc9bd88740bfa19d9cd43c061ba4139afb3e22d814d546f9e82d338119bb9875a19294c034e881ab51a072e2888fe8f7a911a0f5dcd830bf4d6edec76b0ae66524519092b7ebda85eb38b432247f3874bfc0023f6c0876dd1476d29ea17c71804a813e80544fd0a3755dc2e37e8d951c8cf95d65192fc80bd21441814bfc249bc4d8802e361d36b86184da2697f3856c3dc4f0b86f1fcb8a33ba285d0a3acef6a23b7074aed1ed15a967d94339086ecdf896a7318f7fb32b864631b18d5761e2fdb6c79a1fb5c043d70de28d5f0e69dd533afac3b3d2d9cfbcdebb309b46388d649d0ed32d30d3dfc918eda088fa39f84c5694b88b6655ece8980b654ec3d47c0a0ec7b7797c0614011f7cf57f9c46cd8d2e90d9125404f92b9dbb36bd3d9f6a3abe9edd2a62e0e595a2fee7a2f67a344090120056b3023ae6a6991d7d20ffb0f38d673498f4cc5cf022c7565a716845f054fbf1573a6a733f54c324376112fc507c329feb837c31f671bd5ef970c28519b66b9fe09e83a5110bc14c031cdfbd4e39ff38a552342f369220e9cdd623f4143b3a4caa2b2a87c499f3fee9744d5d2cc85171825d988dc5bac0b26d8e7f43c25378d8827053bd88b5f06efa3854b530963439d108d92d87088a853e0a63b9743b495fa2d4ef797dd9f2cc3e6c1641d40f112b2d020c13da59676a122afbf6b6d50355ba901ed3384d743202178c557deca94dd20aa16223155b93e7a59eaa0416b6dc4ac8cacb3d39d1c28bb6b73638628266a42753149e3c30ab7f33b01daecd2bbf566f8aaf5a35892c3c9de83f20b90284115ad4f46b9913d9985f1e76757abd9e9c288cf1e45364a6d2623c0a04d031ed2017393f9f34923d5e79a5714ad7cb7404e3fa0a90ac881ee08f39967e6a5da7866d6b2075c293eebe7f4fcfc80c22599d12bc15f574955d7f49e75234d2dfc0536849a19d6f419eafd336789679cb96fb57ac9a6698539694b197593403daae72c162baad2a1988df8343b146402ae6e2a5f30e544cf5511fcf075ae834741acf68cd298ab3a07e7d8b53f040c677542af1221e261de84cd62d6c0956db0d92ef7830ccdc7928124ed20488644300a99f7f0cbf41513a84178b710afd5b47102ca794a3b267a01623308ae01d60f124d88c8af3695bbe8637250fe46f53ebf359ab6e501aaea643d3d597babc437b243ad1bed7c096d2b6e2f0308708c0dead206f7d6092974f0c23d10966b4dc501a03dfe0e842dd0d2418d35dfa0b7237ec43698110e8329a6b2777711535eb53dc2677383c901724df564a01939bdd9456b93aca7c0eb6117341533a9335a10e2d587c11d9916d7c4890c1537a439fbee851b0824b1f523bbff93b580126677f6ce02a9a5034fc9341b8fdc790f9ca2a24820ecffdd7f6036e4cb06bc0301a0f264d46e84621649ad65c7f24917f6dfead5d9385362a829d54c14829e16d559547f288d5a59081f4c9c6f511af5e94804f10d1fa4690ace573b82f10726297953db7c7d38523658c9d4546548acea36cc8d11238a88d8501462131b9d0010cbe488048b0f83d203107bad3d777c587608b6173c8c1d58dc88dcd2069ecd981f87cd9498196c40940ddb85601c467ddda3cd0ff014c7f779cdea0f039f28d37821ce4db6669195cf5f28741341cfdd84718b4d573dc633c42030ff1e7b8d11837ef70b52fa62d2b3c6a8df64e0cbddd91e5ca87173c32a531eb6a6215f9ac61d48bfda398750ff039ce903561f62ee75e1410b8c884f889bfd4ead3621b1dca902637cf3b4d54800eb58155c8869b7a5e1ac823c3ac40a191c894253979d0a7140ecde4f6c412ae707fdf858ca6c6de95db80205d1946460242d8887b9219c6eb1d67d94589dae015e2cf4f4709b5c0317b9513044a389110d22f70840aca7c8c6fbc81846e2a486b27304e1504033e9805bc41194f1b04a56cddaac691f9d612a6c95ab3d2b7dc4f25df31f5aa9349fae70ce2226f121556872a1c1c6333ce81a47de02dc5adf68e2973399991810d14dbdc2fbc6c022921383df5c03ad371fbd00b9bbb7e1ca6c63bb9205aef492813f654c2fe128c1e98c3c2843400218efcd34adce90f64614e752556d77eca1c9232ed2d7cadb928e330c1ed0f88ed9834ad62de3bd00eadc32e5b79aae44e1331b15ac08356eedf0e8e6132e820b28990b837246cb03f54e073feeda6a8ec4f9ecdbdae07921c6f0b06edb399f77895b33c843d434a86d538e0e8e37700c88110fd54dc2fc82c686866cd1c29ed427050751b2966acb056818da3e79b84c4e37b1779da3a101f812af231f792285c789f087941431225bfaa2512af3f4121791b987a83c5c46d2cea321ae16813056e4ffb6c9c6c346d79f5e9b9a7fa70368af5a7ce4f6b3feafa57d1e61684634e07221012e4a03787c7f8f3da6d3107bcf03eeaa47fa8d6b09b2e7549644bad5974b374dcc1da11221f81c22f9343cd58e43f229a3b188163606d4a0fe1826f6eb66d1b6d8a3ecb8e3c434d419af53681c842521ef7f29a3660489543b66d80a1370600e2ad5316f7d3278d376ed39d377a076e01b9e95d65da55c2cadd3a2b6a3ff7d40a3cb14545d08550b967e48da7a903fa632b90b5667ce5048ecf42957ab53b8b712f0dd68004351e2c5d89bbfc2261bbf76795d1388b034514ad4a335a4dfbc17b9f736232a470d5d6b9957d9f7abafc020523c74bdafa9b82f2d48554d56db16a04d0b26938d2d3d13e34cc3a1dcd9a0f138f7471973e050bbe26f6813ae1fed03ef91daea1cab3490a37d432f1af4dfa4304d1131ff4f30cacf53153142f348f7b51a2fc83e58279f0e8603393321d86b97ffa7cf21c8a1d198bb9a8ee3b51c65e4a4e0ab69b62f084410f38d9039920556751fe3391bf6560e2acb3151700311331b02fa54e44bfd4ba103afe621cf8fd1fa83d8c30184a15f6ad48fa9c29059867fbd5caf143a40282e1d819bf3c371bf31f62df1d80d9fbbc5cfb4a18db255c51b6d55a912bb0465a175c291ab13f838789ba549214caca259192ea38bffe43c84a87e4cd5d6498ae94ee3a0f99656d3a825b7172e9bb28150ccedecb77aca715c441b45772fe2ce4e7635ee4c8258274f3eaa94c482d097232a66b7611c8efbd80e5fa315218ab857ff5ae03ff33976c4ff92f1c4cebe43e993f7a5a9b8b2a132e1fda7dec957b3b9e98d36911829909a284ed6ef1240e02171b323e922212c78cf84ccd2453b092e928c9a04c22f7825300f5345c3dce8e5967856b084b851921a6257a68d933b101b9cd135fb12a159c190dd0a212960e72c8a0fe64bbe958025dd845d296a509a760702692575aad8f0bcdcd9eeb7c83c5557b134d999cf01ad47c7c1cd1ac7406af0a44d5fbdb9eda198aef9c41e77061506445e4813239e41dee6cadccaa221fc66f6ad87cb421821fbc9172d04793c0c2e044ec1be5d81e006e2016ce7339022b7d52b37b36e1e648a02f4400902e9d8ca229565d9d3ac04c1dd6a8d4368f302b789915aef24b76d1859947b9a551be34ef9b4386ecd5cba2712d3f4a9afb50bd2f2575a8d98e75b065c8e29328d89a1fc74f2aa6174ddb527eeed80e5fe83475d9a78fa525901e582a05e88f8ffb558438e32d68a341de6e95e6944d10ff97abf89cc5c4d4abb6a55898b09a9c46810b54548556ba7296aa31a80e5c4e2cec5dc58b0c8edfef3e41541b79bb844ca925901533c7c0ab303f9ca371879cb68ed6fb9b900476dfc175be1803f14848ebd88d6af69bfe28be8d0da3896e07d8b8d89f40f348b5ebf010698e92d44d4c2976962d9b576fe6f9bff1ba382a4a3da6a85c7f087df812800e3939c26b4c44de3a2bb4d0d5e5e6c5c09d76524318c2116037afd338985499b26049e7eab7853d6a773c3ebea01f73d010159351c9a303e11c1d5bb9970f18c4ff54d4b690a7107664d73770cf628b8606d13ebd6e4fe80549fd336e5c6808033a8e60d693f5dd3a339fb38a39654188a539d984cbee76662ed9d5d28a5f1a9a28120487f888d825f7c3541851a6220a2eb06c7380cb6733978ea5e41f0ce2abed93029a376c66fa7eeefa056d6f2fa00f025be678e5b4a25ecbbbef826495f01101205991592a7fb231f5e0726c00a4b618206d9a14843f4c30473b4e091d92f41f05ecc1269559fe17fa2bd7b881791513551312b058be92b229f7454c153776162f92579b10ca2b35ef37dc95e504b6d92a235462325f312a95953174a3c4bf8a9599ed4f44f49dafb0fbc49a3b2330b5db7588a792ec00d68677addcebf77680831cc74302c40f2b0268144b5f1970ab4839cf8d466ab3ab00547a45e1eb272519ce0a613866863b69f3e5d9f7b79eb9313dc04a09462c354c2845fad52e5406cc412b77a32c071caac2c8032840a4dac3fd01a6b4133c16e438ecf28812432b51ba02a939892bc84c087b54be99705e77a344021f2b70964c2dd445120323c85b4a2a16334c682fcb0869ac0503cced5b51fbc5abba6b528ab0bf139685f9b09f313c0e9db38cb3955d49eb5d72885d694d8ddd9e42531c6f11297e1f15ee92be370a967092a09eac04759681d0eae33e5043cdf7d2d4129f9c9fbb227270c4ad69db3b3e119002a3726783f273bc1abbcd469278ada4c7ff8acbc5a839aa52a33a8223b3a03bc80eda648a6584a220e504d435a9c014f2ec135faf78cbc7f488b532a868baa0f4536bd4323e7e27c1951e72c65d2b8563c311b676f7c2f7c6eeefa176085a6f08b62e03a23c131739e87bb9dac05c0448093a22dcb491b8389fe4c6c962ff8843ad0e76baa23a6ad6aaf29048e3174d3f71b5e1109852cce9b92a8c0b34a065d5b761f9baa13b335e95e8927483c95c7ae2baf97f59dd50d397c6714e0a5f1e3cfe4544057ede6ee94bd4e21b483ea50917d1aee469701008d0baade1b55e707eab23e929cce9f730ec14831c9be24dc7e071839714ea095568881caa5dadd42a370032a289fc0094731ba4946d479788ecfaaee55b4cd3466a5b4b2446b04a30d5a5503e8523d958afbd1ed1fc70f487a579d11d0816073daeaeddcf85cdb54b54f177e1bf3ddec7075ca8ef32f9735cf82658a145586bcda4a06ae26d61b84a59a0baec5ac897dc5663c81b3b54976e73c92d07f26fc98c78c733eabafb9559e843598ad76cbea68336c70786cdd7e7e0d680e7d9e73caaabc8b4f8d35dc60a19dff7373017d59b4106c569a2839c7b7b274308711c58e658dfc9ca9756cdff2c1716010df4eca49e2d1c2c7fa17ea110a979d7d046788ff86f57ee164fa2491787dd64a5e13a745eb60638c20017e013e04f3572fcd247b0d71abbea295dc36134b4c238b963a08b00e1a690a8374bb12be81ab11026a27aaeb533d117223a35d4ae0467a7dbbd0d5830d6917290a5870e6dc46f9d9398b5173b4dfecaef3bf7ec096ac4253961925d592ed75d9579b574a129bd1025492c08aa835ae96cbb461271215ad48cf5b208816e7cd0c847473feecf1d419cb6bba5d77fa4225a20288f5274846ae94f5987bdced38d756bd8c396fb245a9e2b4c1326cce16a120d8c30d3b086a2e8e6245a358ffdee715c32baff63fa01a32659414a0e24f2db0e2afaec89365f7c45e22b662f31240e7969723e008876479cada45ae650743cb4411d80eb74ade9202275304e624eb0fb12fa93f1586f671633907e4b713d4c05b5f2b1e70454916e45d71ac2cd380764527240489901ee3a00cea6088faa2c5c9a799ba93adc666e41ca3ab4839a53321a33195854748128a1596b4982f223b41f48d514b6a484eb9bfa92d5af769bed16671f625442b5b0f289d39e8449cbd8bf01226429c5f4407af4a07e75618135067374d6e9a2b37e064ed786e6c7dc20cd45bb73b95b794250689e8a557168277439e4bba35c842c1ede78a1f7944d74f4ff9ae151b6051612891b53a3d9f224672f8744d6d09f81d5308fb7ff59654588084f44158214eca054eedab94d6930b15f1452c727c5868f14e02c9d9945ac048439c393af89ab61a422ba67e4d8c07326c463a2c5712ed5caf34420296a3749ebc694fbff47f69753195e2489d98261da76dab7831f5e660aa1e21961104954140165593b5b0b6ec9525a337ac3d0722d0252cb0b1c9b958a0edff3471ef0d509ecb6ad68d5e602a17b00ea99fc3057236d18676cbb8bc5b6988a8d213d1d31634f94a952510fb1ee1b66ea3117cf65463fa42b44b96d303829acfb26b791b30780b87c1c7cbca3afcb97f18adf3176b79f003933d671d5cd48d57f049d8759b5475a5805373d53b003bd004790bb1a6403ac35a6fde7e9aa250ac2dcbb0f9872181ca2f6f1c11070a53a37cb88e2c4ceef08b0dcead10ed26f90dc3594b7d2b1089c4caad77fb6c505c9a141dabac72e3ca17234e5567c08f86138fd871a104dcc34b0bbae329470851487f16acba4b6da1f4f19e239a6d68dd7c7819706a2aa67e77a778db72d911a77801c443b404e6e7a1e91664bbfce3ea8562cc8ffce7700244308983df19e007043dd66d86cebf257cba8227f0993ae355c4c6a1e0dbd5552350495524e5bf594fa653073ca5a38b4ad6e20d5e1f4a4b44d54b95582d74da101c06625259ffc2020662b1738dde95a6c67301f8d887c32793101f74408a92a83c199492de55223dfca478067406586faf309c2ac2a15c450fb60265b27fb83df96ced792663d61f8eebfbf827e939bd0031499083c8e5274b13e6ace4991cf85dbd35621fe46219477bc996b6dd7163c85cd84c8f05ae9c7604e19a8b2cda641afe1a20db79a5b2d2c937c9f31686694670805cbd7f4251f99568fc1b9afbc6ca0fa401221a5e3bab4365240d75b84f64be0195a44da6d2e0ffb1cfa8416ddd994e15307f86225c777d8257ae54bde5e6c5ff8b89ef5e225f4b6c7f4c3bb50851cda62154d0081d34b91344ac33d72b0faeb2605e8bcb69a9135cafade1a1c540ac9e10193e95de6d58591a202918c7044bbf0bc59186736553289cb3397189df8a1b09dcab9378de24dd0434d46b2261e76f2173112026dde1483186ef7268294e8b91e649b36e83f3c92570b334e662233c272b9284a6c9a0da34bb670ab02f519863a3b50f874eb95648b740397870bcdce75b0d66e7d9ab763b04ef06cf5434c1b02c54c51e83a41d7cb7a9d1d3c516cff1fd371737211128e46a2a865fe1ed3aac76d689d9cf22711e879b8d76f1b889f61aa1df3b03dae0c35d49ce3027182ed32ff993444c8f63e4f4a8065c91ab8b0944e24e74cd1f1a244a05068b5a43b1497df6ebcc3a59956cd10b903fa5620b949dae2a184dd589154ac609f1aa9ef3fd0c3e687556e6c943a1975df244d8786240c59a2e490d50aa785bb0eb33545ad00aef11fc1db7b1a674874b5f89dda6e307a6eaac1cbe471c6dc279745dba6e8a982ad94f5e26ee00542ac96cded164bbc9b3539e4343606f84d19a41f76a3ad681a343eb32f7a67978a496b15f4914625ae662a173d536ee6f8a7ba9347d1131d7b96a3caa44533f5038ea67e9993a874bae31966bfbc794a1f35b9efc249a6076e639bee04c1ae6234f66cc53342b9c5983ec68e165797054adb636ae71c6ab6973b63997012747b504ee426a46230710528245f271b0b4b120e46e731cb9f978abf4be721391d0915c46a302ddf7b61c23fe34e0b7988840c8b06b22ae586443a2623be6a79cc08940bf004ef733a5b7a559fc8128986c71170c5e461334b812d87dc9ef3c46bc0bd667a144bc0dd7c26522db94ff204d942a10408f3107b8d3478f51018d0d7afad1116121361260f785beb5185b3a4a91fccd66e982ca89b438865f0d60913eeeb9df77b36e3e79738ea1517c888b6dd26d8fdecd1153dc527187c9a98d984552102752e695bc2c5ae18fe5ce73dc0f050e0d2db7c69fcc8c30b878821a3d9df2a4214869075ad75c1f6e5e0ba980e07f91e53ce10a5e8c18fba754a722f28a369765561456974c0dca108bb1f420f833acf526301b018564d33e1aede0335b000757192324e7df4f80e4c11e5b8d806e2040425b926c26f9be6b1e0ef5dfc70bd993339bd39033abca0237dbe6b2073d7327f314883b052f3831052c2626ed92561d50b1be74c5c423ea7df697540c6ed4e6f2737870ad91d6c80554a17ad37ab9727dbdb821662bfd23a2f8c3e8687e299c8a7125a75db559d9b4518a2b1003186fcd9838303260186ab2b0e44b35de5c8354a68ea69d174b7c33c10f3879709c5fee8c1dc22f6b0c07527011b0cbf6c4352b391f162e8c7424be55e855b27d3ff613db56e85525af830dd0233d1312a63e52be6f8946afc365f9e6903b23bee323535c3321f4124a404496318f6a1f94230d8452456d53ed43f322d04928d02ac565e5d5481699de8b7efa0ff5d9718a89e64d14f05716e3819b67ff4bc5548cd8d8ea9a94c313cd733c803f15c1bd8ae962af3a4d5c491f590f2b3b0ba26c925e48b1b9bcf8e7ca281091b0f5d9ad2f45b655a2e5ae9739edb51658c7a7cc788fda2c833646811f9fcb2792b89de42156a3c34c07a808879bf0abbd9b08343b8e08adee2a3795d5f24196e719dee7b220dca49eac557a741b2bf9512b46e665ae7061f0c9f4421f8ef5d9ffd215ccbd837fa15ac05195b6ee4699740a5d835912aa1d8ca58246b465e9462ba9de0f9fd555288f8e61863697560a366fb0d694f1a03c78ec79130a2bed12f4deb851f40d4eb27fd5c69b885484e8243138a5279c4547084ca1d9f1c6b56ca0d4e4e3c0b616485bd8fe6e5b8c237f8676ece24102ae885238456e04d8cf72437ec20acc47b707dd0d1c8338ddccce6a67f1e135eacb57e4515deac7cb2705b1352a16bbc9de10c2a059f1ac7a2156ae841cb41f6f0ed1af73cd166daba0c5d5fa8382a8fc877b746478b2564aae4ce2a998b097bc527b44b00ee4bbfa0a14c7b807adb4d31f070594c494fe1404537c644290abf3174fae852800e6502c6c04a0d00cdecb84e291c225fa40ddffd53f28bbf2bde3015acc0a03b4e6636ade4f4ed88909ec9f51b2c1028dc74fe40664a989f69b774ed56388b6cf2d7a3f5b657dc816b08766bc3c21724284400931a7a1d8fce0fb947cb0935985338ae90ba30e407b2bd5f5e85751f6be259a01b3fe64bfac0f2f96e92898496c51af5580638e45890a8b17957278a474adaf90835c9bbca65c39d6a5677425eebcbbf7d32c5eecc1c495440f1abaf550ab0347431c9b24ddf0f50ce24a2af3d964039cf782a7bb6ab822b85d6587576596251728953d92f6843d14c207528386942df47109f9d0a405a392e427f1f34b93d83490048db38bb81766e35cdccf2fb903cef71e4c9228559dd1aac0de7fd7658409169c468d382eeb512f87d7bd8e50015f74f207b1044e89644b87db3e0097a7ce2436cf90de5f043157bc942683d0f66c535623ff162b3ce598af3943f27d1114f9e67a466c5a08bea0d97c2cda582aee94e3f8a7f7c4802b7df4fa798b0da5b8378b03cb1927acd376467d1e78b860096683a713e7d3cd8416fda734ece30b6dd376644f1ce3f4dc0f77eba11b913ffcd52335d61891c368ce76e63454937007b63a96ac57e330687ddd2ae8a9fcaa6014849e70e9c0f981447e28d08eebac4c3b5838af4a321a535911f6c539b109705c06b051edcf5c4203a3c628891e741ec7285163099f07f471b47588adf898aba0b7189b80f525841d9f3e1093824b4372fbe738316a43342829b7b1e7374978610bba6d961b3ba4a74d5a504284693bc9d1ebb69854370d0b3a8771bc71dc02077982b8bb03338f600a3d2ebd98a57bf3d46ee7225c618f7ca9071c6a958740202610ea0282252df5d2c62a6651640c83fa8e37691165b359a786ec6858480678b62b8ab6f3431fe743cb023d9b1b8223acd86b169a164e2a62e3626b780cefe4a4088432df4a244be431ae422f1d586faa7bd221433e88866ce7aa7b42a71cb263301a120691d4b5ffcdfb6b8e3209762b3edff6286823aebc5451670792aaff5247b313378042c427aa37816efa2a06a0424f27254ac85ce13a04cc641403b8da44ae5ffabd82e7dcc195fc8ca23cb085482957119db777e14c787d28f82d83b243518e0dbe28ffa5eef745405e37b4973bb43c563124854b494ef58af000c2c182fd76f58a8743bd360478432d4b0ee97ce1c581aa660ff111e65f390cdee20420d8fa4d8d692076167e6b2ef772695fde4c3fd420b94ec04761bb129598ee707397da0518c054ce178a646ce0e9db289fc301f2b432acf1e1cc9ef5eb56448f598c72586fbf008c08e07fb047bb70de34e85f5dfa9706bdace478a0be5a82420becef94a4f1d94263de507bd21dac40648c4a681dbf628f8707d2d2c6dd401904ee01680ebe823304928cb0239193076fcb5efca1cdeb12fb1e109e8491e5207322adf4a044037f4a02818fe52abd813bb931c2509640afb1aa2cbbf218b08f98472092cf7fe0842444e10df19061e34523bfb51038ef29cf29ed18fac3f290d2f211e228a219e0ac384d3ee01cb628b6e210a684ec13b15ee16ff5c9e7c51e1d83657f30d74951381a2cf0f8e4bc458290ba4b340d7e659294937c05ab75c5ae3aa4a38f4a4a0fe0dd2497877a83702c83724a24de7152d459239ef472afe5ea9ef091b66012237412cca772d7b391d89aa8512c21ae54d3dd91f2bcb46691dd9d955ab171df60d861860137a5a5dfdd6fb4780b2ded6017d0b663bd29a4010cab8fd38eec114a37d01aff11406605486fb8ebd155f275015e2e3d893ad5220178f97addcfe06dad81826225888604530d0a16571cceb45635fb0c69f60ede6ff091074722a3d749cc99eaf08c522433b2a75c12532437de9053666968d66dbbfa4d54683e1635404e12b975997243d9012bf523ae51be174232da9065ed45c4886165434e87a136943bd4ccfb9c5e62aa2bb41ec270296fb4a2eb76f1091f79a2af8729b675caea7774babeef5a5b1dcbd7b88c31d83847edadc280a4e02942a1419c4f8511fff75e4ea13d3d40737ed88ba62cde622fab19725a98e018b5d51281eae636a7b547ea4941c26a8b7b5916fb648e274040c6ae13c35fdddd2f49874ddacda922a0ea56eaccaf1a2170c18847246c8feece050b4a1511da13d151f30e331880db300d0d58cef821c90d02df1e817e68b9bad148242f4e016169eedcf00ed03054e24275de95f013ff591ceafbc27a9beadda8c0f1adc4106a00e37b9f8c1d2334f097b9ef6602cfcb10f8c1347717a563c92f2ccc44654df86a0a25d84d364da7ec0d2008f677fdce7e454211244da0baedf597cd5a641a82bab1e959d71eee131a0b05682917d427db195b42fe63b504cd1fa98b8011218f17891852788d1763abc05c7980a2d88f1102a42db1d38804c9d72d7bf4f909c1ff1dd4cb3d2aa543927385e0c89624aaa6c6399ac10f597c568b01612dcc3a981d10989c4042141611b5fa3c7fa67b70b2e8e8016c41abe720ab3eef1ce57c2723de3a48133ab87f047f894f2cec8b5e4c5ad1d0dca54a8315f4e82f1f2d0d7c0c5f60f5c51ebd70bc013ff448b596848de3c2bbe96a42941b86466d643978dfc82667b19df25b491ac04907d66cb73498242f88c54871da6d1c592eb8b9d6d7b3f83276cc4df65ea541ce82d7b84cf2bd3e6a62a8631e3c9c48488183639399ff3e7a980ca4a0fa9f41b6ab69923725f33603a0d8bde144a4a5cd10b8ac21344be6d7045e58b680fa5fe684f3199361f5dec7ac2a331327f4fca6615ec591818d8a8af43a8c92436c72d8a884f11b9e414298e191192cfb6641ba2cf6f1a5f494e5207e14137e16e6d1f78a2c38e6d1cb44e36a214e0587323816448068b04e22538c1f68e712c42311904426712dc5c50e89908ca93707a60126b6e79cc09ece4992cab2288e226656ee3c83530971ea6196aab06bf41e4ba08ab1423559e22b009c4238335a44f64e6f68281d98762c296c8f5c0813904243140db2a3db11d191432cefd034dfd335ece71dde2303a9446d9339ac36e59e4a31af53722e19a8ea36dc0c34dee2912a276f1658ad823e42aab286e1273a11d804aaaa3c4be2dc36e8e5fc2378c64d1edd9f26d245bb1c0f7d9e3413eabdd20e0b171275eb208c94307a5320a9604b32af250a38ed1c1c7d103ab0051d1c0e781888440b77d1af5d99c32ae8ff3418677b3dc7ce24327f9a934f8c02843181090123229bf2c463f75bfba55dbad63689cba2df98a203017c8a03da1e8a6e5920da15a903d9abd27f458ea7769d7c31cc9d5666cf13012eb38c2e4c5d4817d6c9680af1660be02e4427ed4b600ce01cd600702076e890f040c95d081e7d3bf0c3b271a7f28ca15b4b4222a8027941dc6def2df79652a69402d206c606e40623d80c9ff1a2a4c1f519df2f6962824dedc334da87b3ff89c940c791b8153e3e05916bc120a89953cbb7a09e6680a26779fb32c0202da8a7960641508752097452ac766fa01f10380871b9efa47077e53d6fcd65480a19af7d3cf849c67becf96466762dd44df0c5869e665c0e5c79ef3ab9a28cf244ca64109d4376219bc005394a981692149200512e71fd59240d98013d246cf4b22ed64a47739f59f8f33ea3588b5d064856404f829dadc9f290460c262b7c6245d7d171978e8e8e8eebb8cee7222a78d286bbf58a80cd521bb2da9881804bfb47a24e6e57e089629ea8999aadc93387cc23e66a2a993ab3c8f567c9cc2559ab944f230a2b6a2f47d0abdbf990f1392f36a26f7911588410a719dff2334432b04922e1924abed8885a5ef4a3a9e049c97ae6e34d230adbaf434a6004bdba3db4a6bd4c617d786eeb5e0629e78712b0f839c958dd9ea823660be965c6b7bc10a7fa5dc04f31bc88f46223fad18fc09cd18b5e889337832451a4171b979ff12ea0444998ef67bccb8f482f3632fce8650047e0cbf72ee0cb07eee0a7183e0650aa402dbeaf3526634cac48592c2f56fba25d79d65c8245a14260ec86fe7850b7012d131b70bf1f31d109a0d440766a29419354e28f188f9458f16f0bed6f037de8d5953ab012a808c5668809569ca86e990c2543c9503294f6a22b64133551ddd665c4609c73b240f30769fae91af3266886283373ce39c70bf8a987840192127203c60f128689cd2143eee0c8144c4345e7a84cb3bd8c0178200b143b234d4088f18425cc9546bba7e3eaf63d5bf50dc8f340b16dd53d9de366b58a75cf0dc8f34031ae9331f2c701f246de0887e7755cdd34dab205700956b67a70fdb9d3a4681c5ce7182acc47f86ebbb7043e5066451ec23210827f304d739288fbd2f4da4cb60a010f9c59955158bf75369bcd4a386a6c6a7b3ee0669e3c7bc6672882952fbeb681de337366d4629dacaaaaca65bcc2ea936aa44875d59eca9acdcc524ad7bb58ba4206b7608204ec94f36385253b7dffa3a508d7a90ba7e0aa629a15d3f068095724565c7f1a46ac58955c7f8fe723c2ca97cbc31e3f1a94b0defb007def49972b7485ae303564479d02099575fd4d9508c35415c7f8fb083d28641a661a174161e57bccdc1dc182eefc5e76083de879f0fefbd16b94a88d22286c836255d2a2bf4d3925d80357afd65ac11e82a017879b99b99b6a929341d0db83f6cdddddac854421c0fecaea09b2bb3b6ba129d65b591eb6a42bc4a7461df1fe03736a4769d2885362eb0adc99a982179a68e11a4f7ceac0235e71a4492e61187f9974a9aaaabe5c66565555555555555555516aa393cd5062eceeeeeeeed6f89b58e107a8536c14628930c1211858d0dbcf612134b9623ce5fc5881bdd7e81c7c7f4e3188abf56f93f492c3143bf6583640840cecce2311f1ea71fa00baa28b2802907f38a658973bc198115eb8fee5e072ebd7e47ae86dec5b30476af1841e273be37802fdcafb57635f23d9db24d6a20848ee46e26b493d4a18d44702033b03c2bb01283361cc4c99b97182157bdcb6d0460947e720293839729c1c512c2547ac82a8e48e4c713299176b99ccca703c742c2cd3f8f4004e8f3aa43be372de6b37a42947ee69a0426a82650f6d3cacf2c2c94cb0672f9cf721ef43a00fd07f209f38506c1f4e0621c994370ab115e4389415e528479709e226ef1df40a446f973f0938b39d1ed6670f3be5212705ecc2b287b54acb98a60ad370d30939cae44892a3cf26784029bc4e89b1e29b92a6940c076d6a9694dfbd1ca24dede27ed324101c348c1ca261bc03454985acc17599c4f5e7da88ebae2a71a049204cb3bd8c42d6402661c428a1f0d6624c09639b9aa6699a8d871330409bb86bdc03304cb3b111b817390b1a5101e3c8710d23a76a46cf8a56b5f95a47032b8eae7f7f5add3628e69cf5980e12616549ca4d1bd5c0e66c369b513aa56bdba9b5568ed5e7176ddc7e1a2014d45bc11078c8347c2587ce128707d3c80bfad58e0ef49fa67d0fea3ad07fdd7b3c80fe034b2e60f0f1bdb7f2a1d7b4eaf2848f2336a15f791f1ece4bf7f7d2200f3cac84409046c312b603bd9f76d48034baf1e7750ffa1c30c7035d442f6cdb01345260020e6ffa060bbc600710217ba53886022c2b712dc9706432994c86c3712b51586245a68a8c47c8d76b072baca7dfe1322f9d16e395e08b7cbef385f8a10b560c7b8734596b297592cbf526055d602d8bc5816dd1c76d5bc48ae10da5290786f187b2e347cef9e3bd58dddddddddd1a7b5d8963dc9320b650ec77c55207c57a572c953a87a39690da154ba551693492a65269541a953a28d6eb4ab26989c545370fdac443c2748eaac48b0a2f287891058d2456641f70fc72a84f3f1de697c3b6b5ab3492168a5de176668b039bf5846b48eba458012feb3ad0c7f7476c3e90c197e9e3653e9f3a1a9858ffce8ea4cdc20633f3a862c16ed788d1bf09863bd6a5f88ffb78e83eac924fc9673e33b39dfea261fcfb5be7755ee7e7013257ecd8f6bd063e17ae30852f2440ab44f791b9a2ab1e7045dfe19058d9627948c308cb2c27e22a1f1f1f1f1f1ff7711f4a6d4891125aef689675234ddc7332c90bdd3a311cfaded8a0092638874ddff0da840a7ce246e65070a64acfbc9182cc27e8262716ab321addc4b46dfb949873f2e439e79c737a366a74873d86f4a9128bb2a3720c6c62e53fc7bc5eafd78e275c2e53b581654c8561fc64fa77b519b6b05f415ec781c03ae76c1b7c474cc704c3f7d0e50b567ee7c0ea70b95c2e970e4aeb1394520aaba1d2b44d6a018ef1f7c14d1501579ab6efda4198ca6d928d4d0678e81bfe1b49233961abc84710d989059886effb0e1ce3308e03d65ca06fd8d0bef1b0524d2bdda0d6ca951bd6b18e553b44126fc4f51ddf683d0449221c7e2ccb1c33478d7eece29a63099f1d2178bda28462b59b03e9a43ca5e372d2446b088b476584fbf9f9690ee4714c41946a744a3baf683d10685d292edab4c30b870215ae37ca9398be8567e1499c0aeb38a85e83ebaf5d61454fc16029580af6ad48b1e00fc8c30e8aedeed63fb27fec0f140bbaa2ad3d52a0fee43df7d607568914de37cc0391c026e714c7b1384f718caf9048adb8221e4ed95cf4aa6157a86c20e7ac54ba87e826ae607d0304a5e01c70e863150ce33f04ac75450f58a9fe7151e9d98fa760ab15acbbbb57a9558a4ba552a91df8467f123ce5291c351c637323831593b55ab162517660465e4f5a3c158562d91512984a07ba4e225defe2fa92eb9d27a58c59e9ee4ce34b347163b8ac8512ad4b3f20fa5623ddd717a7914bf295af6444f9bada532b5c7f2986bb46a3781595693a762cbc07bee21831d8e453ace46bc54dae285f2bf95ac9d7eab5922ff95ac917378bccd554ada68a065484693628388764b24295a039c6ef064a9ed56baa54413c0832e64260182f5e1edb9cc0e4ab5153c5327649596513922402c748270ee3bc85273df5b56af1fe0b710faa3e05c738e854348c7fa0e85c5c7f0f149b0572c370a0e85b340c2849c334283a0fdab7a002e63275c534dd73a01b218b24207f5fc95713962fa6e1a0742191c079b5d65a3f0f9c71988ee11bfd376a709027c31352c662b5645294c47660515cee84a65229562ae52c16d3905a002f4bbf45f9e4fab33c6c79d87ec475e2933e85c19a34119dd5800684218924830c2c2e1343abc2ca9f48b0288be52c96a649901315a534caf86476840f95580c0683c118c635d2d4fd5fea1fd9339773f68c695cab2995c23006a3c104eb75a100ae07be50d0f75ee841341861c546813c1fdc7befa37bd088abb31aefb9f701faee6342b0f48680e831ee4b9022bce7be08d0772fc4f51c071cc3c2728e7020112f35dd5f804f1df8e5d0af69df0d25d0c097991a5e72a0e2cbe6328515676ca0c252c043972aacc8aff9e9606f835270df2869b2a222b1a8158c4a4d0b6d947c73fb82f6b17b44b1941cb10aa2da49496696b254b2121c8114c0915c9f0234763e722b608f122c7dad6218e92cf447a91ab97188d82ad625aed1d5ae518ee338fae823a5212d1c368e23eb937294b526b19386173616a341c48aeca2410496b5d6da0edc073dfa4ec3a0513b49ac5fb1562c7058859dcee1afd1b7f01d18a094b8cb437f6f314d7771794a8c0a1c240a2bfe0522040926c6518bc562b1586cdb3e2ade88840ee69c7394b2f267a9d65a6b85511a6cdbc61bd76aed68c4b6246bb576349261e871746adbb66ddbf64d60bd84c3a07e7ad997b5f6e572d2398cd008b8b3c72f9670fd6b04b1628ffd55607b50cc61db8090638cb1c9a003db9f433f10728c31a64b5932bd2c2c10d26bb05d1c9345dff0b79e85f5cb333995ed970b4c59970b4c76066b2da53c76e0ece0d14ce03009ad262499210a2bfdc331eebed2beab2e97cbe572b96a0d39c6c56264345d78508494ac9e73cab64cf30dd1a6b053a206334918c169bf7de55eba7b0725a4d324edfad73f728cff04c230cc800d06d75f93c1047bfc306261457e694e58314442b550c21da3fc5ae7f49e98218e391acdf9df7279083db0e28ae17c71e4ee4d50a9ab80cbaf99948a85bd21f4c51c51ea9a0b344dd364386de29ee7f34fa93d3f0b81c9cbe7f423e485cf890bfb86bf0c0654775a9a0d8648c2ad9f6ea00d35e4b421e461406986366861e89a0c67db4036d05ad358638fc5ae7c2c76f43e3e432c7b48a5f4402bf60b5970a5863e10e775dad4b8bad53ac339f7858e8eead553c4e52d77e22bdf9931f7c9e33293089b5a8700d7df554ce357c63b274df64587d1a0c28aae13facb2eaacb50a699b22575244a0a6153cb078d04c380c050b6c9681e92249d837bef76fffcb5a3d572994f6b47abf59ab5c637411554bf1aad1608342b28b45102b9cb16bc6913d464f496d3371c023e30d23afdf07666a7ae93d137ea26b51a7434806fbce66888c6d1c98139559b54677c05418d3a3339335f135e33a3191d978e8e8e8e8e4e8dcc93f2ffebd7afd555841498b0a95500609af6de821558e50425d07859b15dcde3aa6258da4bbade76e530720414a0508da7feee9fbd916c38a6c64350b4a06c5718566cd503c18aed5251c0c3510f8ef177cd5c3eee72b98b028d637bed29f8737e3e33357da8cc586c4ad122d31fa4053327d1a3eaa9e5f9991f80aa27d18bdc1589fa7b5e791d4e830afb329faf769a3e3486478931c72933442d2d2f12b55811c9cef8185e943f35325e87c7a0b049fec8dbf2f2478c1faf63a377f99834b98c4a2ea492e85b5e9425ede98f07913f31d0ad21c00d3d2af46a446143ef695cb062c76231f9c3f2f67fa68c22653226757cfa0649362161a18fa7482c6154521cc6bf3562ad5432406fa9b10473c728188bc5c299b2ce82c5c62ed7eba78a131f1e1915d893e972b19cbd8df64cd65a0150afb02f3bf8a9e7edd7130b4a62e9e778ffe4e9974b1cf5cbc562695f353027477bef2b98537fe33ee783e11f0eccd940ff32419b8fbe8fe7fec5c67b1f9587dcbe971db4dfde4603e76bcf270ada54f0067c9960cd69eeb4abd52c579425ede258bb38d62e8eb58b631c6b17c75c1c3332d359348c7f17302e9a6ce18a6d00ca288cd194d18d6bb2d060cea94d6dd643f6e8a17953aea1693dfc9b2013baa78734795f396f7605fb89c350c07b7c13ecd8f53138c6ff658c9bf3a20f35c6e8e798264c2ae8f9cb53430d38703ccf66cfdc0d4f9a617e369bcdb6ad34da18a8b657cfd66a6d206f03792330ece5d3886f9de252ba09d7bf91f413b197741324987a4818d8900b6040032c532a75c9927a48538d8419d239980e81d5004b804bd3488ee6aa860a27c45aadd3adadd699d010b899678ca5bcb8675afbb57e53fa4cf3b9e8c0b287b7bf1b660d13895aad9da174d5755dd76a750e6460f7ce816a6534912c79691ed8ad195d8189bb89d40b266559135a2a9f222b554b65237beac669df01fe0007543d5a35fba902a98fc044e0d0f6105d9715d184b1a5ea3a15f75dabd59ab1999921f96db53c2fb451c251637313c4689b9b3948376b5ead6fc009c3d22bfe126c0f4bb84c831081dc9e2bcfea8bec73e3a107403058917d4413338f1e48600296916f5d70fdf3e1d90d0d7a3ac56efe36ee15146be07a6afd826cdbb681402216bb12fa40228fa5b3dc4a0d7d54d3346ddbb66d037d9625b4c20256cbad84be0ee46d9bd771356439c161ccb0d878c4939e9f202d6b2923d1ed92d87abb24768eba2476e4a387fe4305c463c58685ba4ad7c934130e5552878763b8ea412a18561c09c089ed7fd1a18ddcee1b49c10a366c94a6aebed8bc67bab9f4a582363f9a1246aca3c1081721d896151b562a51d8f852c31246f6c460ad82e5400a969955b0a947bb8ab83d706db3cd25af381a81110557e708a5a9abe09a15a18511d63ec2465bedd980c49088f580cd601b0c06b37198a60283e1a8117501d3509a864ab57886b08e5829d1d15028ed09b11a56a56106564a6dc60cd804d130c47ad81c48c52e20d4a4848dda3698f7844c715c5754adda0c2ce781225c6f2de8a80247e17ec181a4d62899ca63e9152b2af460b3fe8b1ce143e4ec2ae75447b35c34daf6038b6528160ac51282041344505c2c168bc5623729ce2d9526a289182580c39134351305d0a1936f7eaac05f7d05418d3a23e76c1a680bd8cb07f0e33e5ec563b399599624ab540a435913aad4101c1e33b8420aa8d38f298428a7232f3a740fae33abd5dad1c86b50bba669db65e7256150723d8c22bae8557cbabb3f3d42830e9bf564fb555f355eff9476b7bf49e7eb8ad7742758b00e7b85a26f996911bd7cc5341bd3d02b7a57182d87c2f22e5e1c9fba24f67b1dee45bcfe1436318df73c3b5e8d5c77306c42dff22ca496b724d13749868ccf01fd8c0fbd88b4f220d207e67c2ffa1cd0b71cb111bd8cf7d102ce781f22d0876d7087d0b7fc4de85bc09c2336325ef4392c3f03bc59791198635f460b89e54524fb73b290f83449dd8b3caea8bd0fa3db4998d10d1de83f1c159702865771186fc2add611fd0ae23e6da45ff7670ac3f8bbcecfebe7355ffef297bf5e2f4a619dbb38d15ad358e3e6315f5b2101d1b70438b4461a898063fc7de0186718ff2a5be0c1857dd19e6f09da6df01d2e235fbb3c62d7885d231d34287169db569dd8b68d37d6d1d9b0e083c372c79126eebad23182c5e101019a3044804d38339d23878930298e157c28ce26936dda56ab27f3dcc7758a389594942e9b996bb52ad5ab54b2566bb5eb54ba4a9afce42ad548baaa8e8690a1320abfbeccff022e13c40557ecd4a80512d515bb894de4281ca5e7f3930d1031ab0047b9f3c9ede7516b10ef4917061e848007490bd5e3aeb7bbcc640b516eb77f9352cd063318e18b91e3d8fac6711cc78dd2b46975d3ea07e27134053b63c269391648b6eeebcc04b94edb368eab756686eb487cbbd5753536375cf0388ee338862c47ecfc9186a156ad473dd28bd78139317401060f4e393fbe24a723f47ff40f923875dfbdf47b1ffa482ffd20b05bd50097ca94202b021359ebf3beeb041d232684cc9692d075d09282f3465b5f0c2bc060b7baeb5958b1a90ed977a3608f1d845220429060626cb55aad568be588bd92e79c94523ac1be9225537a75b80f0971ccd1684ed115ec775166bb5361a43f2158ff2aa511b3d9b8da09a2d2318262aac39fd020866d596c8918aa7e384cb1f28a55d37a36c36d7626ae5b212e45d899f67db9569487de1c116c8361d858adf2ab42c7cc35a3b3d96c369b699a3785d6fec31a0fd8a8e1ea2971bfe64282b1251afe5326d8fffbb55afbbf6d4e34959479aa092925ca9c5276777f1886f839e5fc98a1c4ec14fa1f9c173af6a52c0c36f528933e4c334720a314639453aeff94b210cf9c734e1114566c253bdf0e7d0abd46aa170c825ed10442dceebdf73ee47954649f293b1db8a78f4347677f3754903ddc260f13366945c85432954c25234919c704e118bf230f1ddcb1752453c9502e336532994ccaa48c521baa101566e6f97acd58c591a639271039ba48008462a76d28dc0588331ab94cd7754d0242ad10002c7c0d52781d417bdaae57932d3a47659acd077c75bb374fdfa82feff55ce7813ccff32a28b4d1d203d555c0652db450e57a2b9452daff9765e877f7d73c48e2ce27acbf46a2b4524d2b694a24a574d229c7719423cb15e5a85d51b21cb1e28f9e102bf68b254b96a2ab821b720c33b934338a5b02bfe24b77d0093b8ee3467f0325d0af51272f0d3e3703db301211ecf793d2eec8d6db4637ca1a1de0824eeeb4bb9bfea6c3f348d20abbc35d94d00ed4d11be86803450f78a0f73c1f40d77b1d1e690711ebbdc82e1bc01d38a858fade83409482a8b7c47a339ebd1e0741c3191b58fa6209071c331dd75f6d14b62389f5fa50e36a4fa5699e4a330c050c0683c16a361b25263caec1cd5c7b7e9cf8548945a9d5ebea0652a954dae488a86cf7ebadf5946cd2d4e329b1f28acf63b52bfef5ba4f88edeaa655971efbc2bd1097a3a105db2abe53f5e2513529b26a7d31b0948617581f47fa7d74efbd8f9707da8040ae46ecd82caa28d2b19b580f7f504f471949f97e19f1d281deca75001af66262d943ee786c93b4ef6feb1cfcc8a5dfa3722c2d4a6538ac97794a29a5da87615d00b022c452f0653e0b71bbd520cf65b48edb36baa2a0495ff30f87bebda2a4ed7a3f60130e2887f7aec97432dcff0c21081d8676fbab8f53a7a0a26f386b27d55af56a4541d106e0a35960c20bb60409cfc85a511e826046ca04a081384cacd8abd65e003f92c1b2700e467abb4e8ef19c458939e7a4829d1e7ee1c4b6cdd9715b2761484ab05c00f017b06d9536cbb65adb9b42a552ad60fec4c8ab88ab87a544a51a8d46230e65a92459a552188e46fc725273c3329834f95879d0b6f9b0ef3912b7c2bef73cac3c2805969910197299896aa70897993c3185eb29573292a61a2961ae699ad63f05abc4271a66e02a8e718d44a43ead907a95d349f002aa75fa315b4a749195ab52aaed4557a9422f690a7244abbff2dbb63dfd2ca001b9f31bec41fbf99ed7a058128d443fdfba4cd7812f3bd8173d0f2bcf028a56de87e86d079244dc8f6ef7deacd665e66b2ba4976949deaf3c0fa067017dd807fd0ae8c3c7ca7bcf27fe74a0afad9034ed7b04a3db81228fcb813e8c6ec3be9df4388ccb4d6e727b52c3c3fb95d0adedf3335bad34a67195f3381157f5ca55bd72550d35e0c06163a55ab9cb086aa55aa95e2a954ae594da50712e0315b8d979641e7329fef21ead824fac8fcbd09722f4a28c22633b5ab7c33457700ea984964e4bc75b5d41d933f668d1df0183892540d6006d8709f4df7b9236f5f03a4792040ad71fe481a27331db62e65968ee45928a846936ff828b2d3c0b6fe9788b894ec78a2988709cb7bcd571a18d128e9f6f8ac7de0aa594524a295da976f480d087422f0ac0d42d8771d7102e9f28a5945a92e85948f657487d0a919eb8fe4e5c06f837164d84437f569f4224543d8942274bb2608e039c70c13aadbc10276f85c4e30709b342e2615f447a11813f802ffd166c70073f853e04f62861502e43b94c119c63fa4801430ade5728740ea6f95e7419cf2079ac7c917d388ee338707379a8846392f40d241cd3e2987602dff07f3510f8868bdd9a7139c61b089b7634bfa783d7921a74d139ba7796b72f826edf986003692101a2eba8648eb87456b2110100000001131500001808060583e190583c2e9c27d51e14000c61804084643c1a09a4410cc350c820638c610600620000000c0c91a8005bc4b75540a5a7c72b1deac50145f8dc4928dd364c074088a269ee6dfe486a1253dfae4a91eb83683c7be2abe30ad51f973c7c268c732e8ff712c14d2b6159b51439e66fbb7210af987b982a00826bcbf7e28eb27efa429df022e047c4271939921063dd42feddf0f2719645a76fc4a962a073a7af70baa8efb54d55a27d93719c641f8c33029f90d5e58d35719c62d7755351f582d2e269d3d628a6a751ed31a34f8240329c070e9648c5802a045db863d9cf40445b0c278df7d0fdf26edd62eb90caf0a8a0a1d69d84882dfb62ffad8faa54d3307de15dd3a4cade71fc11a4c9fe03c21e02fac399b2997cc8a7581f30db8a441934184df0eba87bfd4c734b0a3500e2cabe6d7e2587073cea4c712c021a900e439abe8a36df876321bd5e1dd189f53fdb99d07b13dd5be66c12e3107a6e1fb13d2e9aaaa80a707b64848797408927c17d4278565c732853861a9b5652083c50acb269abb8d77f5325231858e3bc3604e0cc020993c41205628091b626e07eb718fa43c37cb4e2d484f935d82269a29d0c2698a6213032ec325c24380ceeee5160a8f8307a02a297966fc2f63df573a80452eec54da143bfcdeeaee51ec6f06c1c04c9b27c675ce3ce96b1300961209fab8aae6c6968d96a2ef24ed067633fb5349caf52c366b82f5361003c7d5dc4f209b46aec54ceae2bc361ea71d77f6779559c9b30548c205520b84d0c6c00b953d273ccface5a88ff49f5320dc4cf82f7e966b2d97d82ea59e90de3eb2284f69e12fd4aa8b8f3b63a290a242f139a2bb71e7fdaa2dde223820750fbce770f88ce7ffa4963bbdccd1923811cb1a3310872841489428b57cd37e8bca7095840ec583dc08bcfe2a9259390a06bf59c1972f6db1ef75c123888d24db519f82c9223ec9311750ca9039825b68a01cd4888bd54a844d70eb0c32e7366dc4dc32fa794fe4ffcb78259a2e16d2c1397a38ba90c9bf56a2f4060c24048bfb2304d1612f8b233594f77fc494f62a29c14623721828a1e4b5264090272e3efb2145450631bba11192cc5da390cab66c8041590d50a9bb19390378271977000321aa13ec11b9c6b5ef849f56990610c2891094cc57ed207da0b58ff2630cd3030a2343b72fbaf7863d5c02ef0fcce269c574fb398d5f37922212a71037e680942eaeabafaca5f8d22e00672ccf690b3efb177ede1c8e0241ea5f6cce84181921802f9e88ac7db43133771e6ffe87c5078b9880fab08ef7f586d6c305f763c9753bdc537bc200d22a1b3552a06463d1c1ecbc7b1418fef7470020eca9b44e47dd34f56179f4d3979cfc99ae87c3d50a586b4e45b9f38162737f84268c7f031aeef6deac37571ab87ffec269b6622c4b8ebe1bd9bcca9ecfc587f01d74ae4205fa715b832ff7a18ccd52caa79ffe0bf8ba31fa94da79c386099d32273c4b492d095d0dfad08c5dda8ec265996925e12f3dc56165fde30179e24c75ebb34ad4d869ea5e7d04d122e6278686dd34d01192f098e5f11178f25da24ebc534943b0c54da911116a0225c41a7bc2b1ddc80969369c512d042a0983f92fc084a8ba29eeb386d4fb08afa396330a5009b14ab80775aea993744276dcfe0824b6c90a3c105ed2385304f95525c3c7316f5e508b3e4d48265a737cc2b2427e2d809572cf6190871215ddb9b526e68599f27ca8c7e9acf43f30f9180aee798c64a33295cd17b24a643b62ea6ae59d78f71369b67de7a77c0fe88eeba008439a19e32ef7b88b2095c2187ed8a5bba01de81222a89bf6167a78184d1e358988615b41bf88485c56ab78871c2f25a76443eb9efef0bcbaf66041011f07b8b71797d5d82c0d326c4edb90a633f4dae21cfe522bce3b749ae2a19ea31fe08ea8cce9ca9d4c17157ee00b22931e61f68d277b4ef9a623f4cd7ec43c2958fa53a43b50fd4a3fc47bfe7a05a39e5be281b6f58110248ac2606f7c1e7848cb2b5a0e3ed9875d048c9e8e69af173ea71ff6910b7d4dcf9fadbf1661c5db3115cb9cb1aed85079706255abdc40c69d0d2810a2a1ab821f4dc5d2a141f3c4a74ffb7dc1fa3337a8e53db2777235f1bd902d7165f482f30ef08313bc4d8e827f8abf1df92fb57482ad4f85ccb67ff6254990853988f8e34c1ff7c7c2cc1a8553ceb6f714dced694df8c12b789fc51c671a3d56e358cc4ed05c3c08be80b4322d7fbb964c450acd41f24390420649b61876ca9e84b4dae0b44ec88662bcbd6627f1f9cb43fb4406e7a4231e6686635002426c5c5cbdc10157e2e0d03896c2b2a85d91c7ea3a2388270c6de417c82f0296b6ee7ad0a33c5175fe4bcf5c0488d85c42924c9f66caaa4b7cb5c3c486ce6c1e4f736f27c42c10810ea7e52b86ca09826317c1f4e791ffa7f970d753bde5b1d8890e2110aae3e960ae47bb62b05c7dce68304d4478e444d0b0021a16dc5c09e560d108b55f9a83fe4ca4263c25bfd1ba7a8cac88314099149e8b8a3302525ad21e6e171c4857023c0d22425e956613687fb84caf0e1085f04a5dcebd05aa14149bc9000f40ae7d0a979eac196b3ea77cc1e900472d196d9dc10322a43a4b63824b1a73cfcef9544ad41a9f541500cdd601ccdcb55239616fe2cf20805af10064c9a2c103eab785fb5afcaa0288287402fb8881a11ce68d4acd689fc170f0dd4df4605deb214bf82b78db0c5dab8a95077a0c43e074b61820de2d5b9a3d319331124705fb27d4dcb192e0403cc241667f512595d84bd36f1fffa60f0455f9ac022e3402552c38da214794ab8f1f925952569403a2769c7dcc4290de6d76a71702b2d5b8c26662793abadf79337f21efd7293cb1d57f27c43e1643278f7014493a6eadebec9eadca9c8c8337e69fa88b81601253b10fad222b24f717d93155181b51cca11ba3a945fb686b5e81fd95feb5aae1d18036c9d58c781f997df3afd81d4c32b8fd02498cbaaf172d0ee81b76bd4d4e8d6f2edfdabf747de81b5f0a0ee42841b7f50dd2e6ca5f682e69211372f3bd5ed3101ad0c3415cf89f4fa0b43f7049528721df18c30e6bee31e41b7dbd12ab574ed3128f7bf85a1e0603cc1611690fa946e93cd34c0464626e8f1875a506b2264317cb3a1d54fbadbd5b0b2117bb166dacf872c6f910da40765a58474ec680cd3a095990db68c06cce2be4490b31c7c2e5c63a1a61a95f9a026ffed3669fd2ff1cd5b14cd2c97b97c05d12208576bbb3aaab596342dd5653ba3892f73943305d99ed76676ab49765defd56c6444a20d36059d73a3467917a7462baaf8c7f5864bcc84a436553d58061691eb013920b0ff338f4af469f67cd8fc77dc77b15a3cc7abf038185113104ba82059b8b47076ee02b7c3a8a02af80e0917107c765d0a9a602cb280d28b8a1f1e37e678b1d6d1dffd1347b2433322eb500ac5c669a3f595cefd6e21c7fb2cec274ae8e60854636543912d940011857b03cb3c9e40071656d41a7ffa2b2c27ba5e45e73e406acb1722fd0611a45d56117ab5793c0b41d7b8e0cf58a768ba160db3ae9670ad342aac065a4e48b12a8648c3b2b0c52498e3aeff2091cb30f630f9f360f533113f92ddc8d77f4c7184a3950b9960661865dc046af7fd502e451a2c1ef5d02ee69f95a2810789004dd525e386936d41afd48aefc038aad78adb8fd03b3b28580a296c543deb10f79af3a1cb06670df1cd083434d9e1baaa7105aa1b1d3c737064b21ba962fbdea89fbb4af8d4d1ca8045700b6411cda7b616d1b7a5269eea20001de27a1d306c87eeef553e34df3cd071d078ea81ef12f9b34ada1905a9bef9e589e60554abb265bb1315d20c238760207929536f6e2ba2769cba4c786d75f9f3475e1b14ea60bb0ff131d7599c205b8dbfd92acb7325ccc4b069d0563f30ab50c54812c66f0a7b0eb7555c3105677d10c2d6fa795b06c9a2b6e73c23be86dbb3ba01fa702162eaeb905cba71a18041a138899b7efff68b82245aa071c00a3f2af2cf5a4f01fafb2a3b6ae0202394cf177e37d1c739a6998d2d3ec9e60706782ff3ff22d4de1f2133e0b22c6c04eb6085217a07002426f234f7207ca3bb5afcb0cfd66c61c8770aa7ccc0608c53c43e753cb300cbe0d3a1c2319b96fb9c510afea4040e9285c320bab877d9d0af1580c3498e6a16fb58566dbe542cd0fa7d945d8194518520194d2f26278ba18b76b31a4a74088c9c3c35060c85d9007a4707b6ee0bed053c580d2efcf5911213e2300b0b510058f2d040c9ddc2ce13f8e26063b40f862245ad3920a320fa5012ae625435b878fe65e367265e5e35bee89b3f612ba3fa1465a463c141c99e6da0250c96a9c2ff6ea8871bcdb4ae49448a0f033d9ed696bf24981cf9efe568edfda34912c0e3ffa3df8fffda3b699910c4d5c183d98d05bd8129e1f3d1e0fe7fc0d5c813375dcd1b51e0f4f8ef2ce5234a35051cc4c0c93ee922e7645c121ac28e2c7728129633860f383211aeb1c8311f3b9633dc0e506ec87ab243dc6acc4f05ed9f2da9423f54791deb92ee12e698f3857b4b0f7afb5e33307655cee87cf1c5757db9c25cce8c40aa0a45331790844606dc4d40a696465c4bf79c7d10dcab3f7b8425cf62826480cf5e108686b6f85d1f626e12a8107026d1d48d56b2407b22b34d4807efe83e83782bc1468dd24ca44f1aaa2856140929b19a24885d06161de4802df2f01c2f932fe726068cbf3dad0baf78b193bd59c0923acc2590b53ae4f915fc0a22d3657d085139dd3d52c45feb687c9a03392cf530bf92095889bc942763396398baf7a754b0e2539a16db4cc63adcf983900d2f5cf077192ea85ce7c3f94b202f32648055b102a69b500501ba4cf025ba411714cfe7fda756d812543b31f7920efd20968bc0911faa7c23a24ad8ee628eeee220337093e246d31362a87d746bdadba15ea2625f769d93753775056fa3cbdd5bc36b1d4198e8984b67a31d8727720d3f1351916ec303c58efe0a0e0bf235296b3c8fda15d69f8270263d26de3ce55556cb61a3c2829c4241695c6874c0e6700334c567df1a25fd379579364e3d563ce9375ea227f13f027e6332152580f80a6dcdce6bc34e17331ad311e9d76f43a1dd64e1bf8402b6066e5f9bc2ff61cc4e27e1469e01f9c3cba70112ee9a4fbaf73a47445e9913963d3c6846c16d3307af07dfb56d9d416324d3e933bc4644b67a61d4a1e4e9dc3d66a002207672bc3b66b8cdcb0e09af3d3b97ca754019f934b61541cbe73d7c109f3f9535cb97a5f75d5c086fc2b4ea0cbcea4bd2284b609d4a5718201e069000ddcec080ca97f8f7fee1dbd005cc8527250d8a4bc1179ac1d74aac425093c162aff0f22605059b7994783f3232f4dd96c5bb1fb3fd522d2da87bc2a28d94e5ae2ddb2a6c6004f2a51dd7c0c3e79640de48147ef7a0f70c3272916d86e3939c8d83e88328bd11127d56b487089a977093b4e2b676cad27f44dc3f4d28139a4d6d81f5a91342974a1ae1b8634396d64c634708e28e48d39df050ec23d228cdb2d45ba753eae3f81b3282838d9c1ebea26a5d07deaf56f2fdef6d014b4d7621d7c2797c1532378df8d1815ef922536e52b1305979a9a64bd3544a486f45c39afe07a8d4201407dc16d2407cc31b247babe960952c56986ee75c5c1ba142facd46615372e9e88a360f0165fbe01e8ea572300c86cbf3e8fd1499d999163cd8f620e21433a520b80fd80e1557214b7a644f09f897091a362adaba63c5071896bebd27e1c9268f425239540699e6807a2c23136c082aafc4c29502628f4bfdf396e852a62522538c0780d812d3fcff8991528c5ecc10800607df981879205463d8e9e2bcd776c3db3ea0bbfae2b431f324fa3d1636b51e554f219273ece699f8f8088bd9757390e4dcf481fd97414486aecc9ced42c6db6c2d68303366e8d51194e7c443f5a8d62783c4b7b21db259b9b52b777db591cca8e2bab424ef7abea063244517d78ac424b1466e8cabacdae2d665388a6f811e69abd342e1e9c55516ffb7cc5924670db1c26c9932a7316a88a4b515fd8e2ffbc378d2465811f892c80d743e5c6206b1c0c5b6cc23f0bc020d695d64582781fec69c308f352e89d3fc132cf19f0951766d7875d656172dfded480a15532c3c5c741836c39f99ab258fc55774a35042a3dc04b5c1d89fda1f0da289f1296ed453795248dd9542bb27281048bcd6aa8f192f41bb39c9ed3fcfcb65a3c28b4f09ea79940efb07de19203573248c986c7746c95a1574a9eec60078c0f6dbe5a4b7611390671d38d5f3181facbe02a09e7a3f2bf1c276aa60be6d1fba3124c272ca8c67701db7168dfe3f3f5f7faca407b43cfdca7d442b390eb595404e51726c8733da3fe70154f7a671bfa23d03c286b8aba37efb31977c4d3a4d6405463e2b504a896cfd76ba0f754f3e801bfe5a18633422fd50ba93c24302eda7f820584210c54ee037d37db88b24cc733511d1711e5530b02101f3fe70cc297d1f2977103e3cc33f7f50c7b830bfd2e485d5645ef17fa1e98d5dd430a7c3fcab0f546238c6c6003c2c48af161ceab17973e96f58e256782d8deee55172021c039455d71af78f6f4a9b93e73d8e665b94e993710bb710854c20aebdd021e6964d1909a875df30fc3755fa9b61e29443157998c09c1fa8546cf1202d8c01520d3e9a63a1c538de76203d87ad2f673fe4d0ad34d90d04fe7d4ccb14759e339d1e886cbe9c59c05f73c478dc5d6d05d822fd26e9b137b42a97756507811d77b89daebf9b18e7c6bcf0e0f08e1c4152bbe7860af7515db364fc86436f315ec87215318ad64aa9751d0ed9286bb5a9f1ba25b42cfdc8d62a58655d82f200e27269f6a43c8eed9a7483e24ab1c62b45ca509e9cb0b0f84819cd8c7556ed2b8ec83faaac3949d56c3a2a197c9f53970f2c6c37af0272c8839b2017316b4d38ace2151e9f3f47893dee1c6d61c31d24449c1bbe9a5d667f0f70ac9159b9171bf2e221524b470c24ea40bc16341e0fc172b6d3172488ff911e9b5875a0b2626029b8419d76aca1031f60e323054b5eb0e0c350642731f88030ad1faf64a6a4076f1f40e9ced772881da70437f16168fa5c3fe4c36cb3245a04e56b0d195c6b8760308052cf8931f62fe34ff28210bb876abad9210731bcb1e40f6e126a82ef504461f14788de7870662695b53b2b0f75b58e7c20f6ffdc1fe66e78fcbf6390f5c76d10b89b7fff00d43cc1e0ca9167c82522cb7a5e1c3b0b052235d5e96fc6c87f58310fd0873bd2e551b8a5e198cb2a27600f5057b94a474fda69a6dd8f10837b6ba578f561e94f135aa25d0b508a58bf7afd30cfdbdfa5544192f6c7adc0055db1bbc95499e227fd40b1ce63c443fa438ea2b72d7ba454c6f6120de5f48a79049f4a4426c5253981a4e0d382a4a965d3d0fb769ef5a5d6d3d6bdd28577a3499ae518c3f3dcfafb4ae3b2011dfda41d042bdc10b643f1b231d11659e6d8cc8ac395bcd948932e81da32772c416ad932f0db8c4ee1aec87cb988c880a31167c56777e7851648a451d7690089a01ae253995c2511792f4adf9ed67b40e60bc179c7b8f2bd51afc0c80f7631628cd6a126fa6c5d1c66d568db8d32f7f6e39da066f5c62b9c49389d1c9ce6a70c6a41293dafeb7d726cf24bf0d9240b0231d628690802d50238fb5d01a1958150c601a9821fcce1c9aa2593fc3f5ec53ec007c1cf1c7bf2fee13bf71a34e04a4ded34dee000cdcc9f7b51166e4a9a640c97ebd2d4b287525fc226a5e1959851825639227f7948b6e1cf3cdbea9398373f86c8cae16429426c462331cbbef3a338a57375479af28b6078e1aea62909b4dc30fc2bbc50843dec6f7f28942283bce03c0ea1e7992ee34982e713d0c6b11ffd5e5ca23296f27e97ad7714c8fa414dd3bae9c205fab2d077e6349da1e40f620ac725f145565b231df862fc9405c58b2d507a2b699935287b860ec7da0150b3bb93092925c232729ccc1251a0737b6a272b82a21a65cdee1f15974490e8eb826a6a9b57f0940895824659a0fd44fe73be6101b7ca86aa235dd3984a65b72cdb6d801499f1f4e14fbeb22827f4eaaa5327e2af6d472faf5ebd9c9d672d221c251d89fe619951cded6cec9788680e5ea9b617f5e667670adc80ebc230f4bb9b1aa1e26a73fa787c3699b244dffc88053cae09c51622d0954d96ca725a7f1f196d7e7c5af4da93afb134c6336dc4d471fe287701d580986d5e2f9e7ab6413380dba9aaa6b469e4f86bc82affec94353ef1344244873851ef8ff96aa537a6cda05c3f9dc0faadd387c0dfe1c07fc775a0f32dde5c4bdbec0c6e454a172de29f596ca138aa27f77549b24a193707289be392fb54524394f158abfccbf0920ae379963689ef1a3819932ece9c585de74d697bf0b5757cce238c27f5aa7c015500fc27b751339eac4655158f8029a87ee2dd524fb7cf48371d437d7507a664e835ea064c0183bf90ed0d504f11952aeb149d4405f6bb08594b491c4b891adc52251c800a6631b2f458bd3e2fffb06ad5b7ab5739deeaf65f9ca59d8fe8a1d5ce5c62a378036d148ccea23351231951cbb37e52f153997274782f33a1bff0120698706e508348484cd6ade31e378ee644040cf4b1e94a062cd992696a782938ac494395e597356e521cdee2aefe7b2915e2168411d38dd3ac38c72f4aec8651b5faa50c5d0ea5417b75fc5a042a38c5b3306c7ca817f50fadf12602d0cc1b904e747fe73ee15ca4f31d0ab20911ee0fbd66c972844050aadb1ed586fb23b6beeaeb80353f31dbe00c9f654189568ab15beb542b692d4c60d17a8c01b1a4df9440e41abcd118d3c27b627b78192eb976effc09f3f911fd4d55c4e0296fdd250d4dde80ded3991d61704414efc5de9a403852b6c4c42c6f015c8e75a6fdf09bc45070e70d189d42eda5b20aa431a3dd036e894e60523c20091c0696aa367fde0fe6e8011381c49b84a0a050c3c200f997b00248f1ee8dbb7c26d7c0a0928128f3aa103d40d548bb5bddd4b873a1a799e942d4e4d4fe9080804574149f75ec757915984aa798b75522da221fff0e37269123ced35d12b78ca6782db74e630458df7f4942fa7b910ebacb38ab4f45b572cb43322d9305d409c737b6929d0cd6fc84469134c3f432dc1f420e092a2b1e613a948f502a5165f781d7cb447d97c82a9ef0a94e57d827e051ead65655265a167b8eb4ba198fa2372913af11f12b88db454dee48893c4be33b40347ad01a57e2b2345dd483e1871a34e6c57d36af4b4dd15651891bfb71450902334c1fcf33e97c749e07cde87cd8adfe233f02b5ca7cf9746660fce1b5c0f09653979fec34b3bdbb86e56df7663cceb82c65b75bc31233df99d32ab520f4ac9154a587ea42f7fadc824479061fc095476e384c73722962c88c394968af26b1189abf3724bc4bfa296f4245741f68ecb71ec5325171fcaf44cb1fff56ba063234ad465741a2a11e6e5ea1818898bdb7d37517f6f16da61623641a4e26bd1d5588ab6a9c6129d5ca3a4259b943d295427dfa0b9baf551f6a42618c906118511675b49378daedf12abd77de1975a091e6a8ce98a170a3205b749710175d879859b457ec988bd89f2100eed0a9c02e95a0ce7bea68d5a18dc223b08d0fcbdc4eea3438e9cb310f72464992be3f5fd45ec6b3cbcc3a282cb0455f91d6e350169ea9045aae6e0b8c5dc190511845507f105caecd0092e6430c512dcdad69d622a6af8373511dc027a65af7e8f3d3f52f6ed97416f8717938837aad82dc000b797f739bdbfefc1e0c740a49b2e53df5339af86aba1bf116d34094ee24db37a0cb16eb06f6edbd451c7a5122d1688702a56c18352d5ea017838d9e8df9f33d8e51e9c80e7cd84253991de7f31b5990e44c210199b5066ec89b61d12af912333a253f76615b7eb899b29c8df7b591740f7c9162b20038a6342796fe99a66ec397519e602f352dad809548bb3a70403101c069c3cce76b40a202af446ef9145de16e0d33c646e9e36258f9a4ffdde85c3155603e59c6a07296a3b93e0003e552f96a6734f6e42742cf55cc1d425ca2de539ec2c4c9c7e123a77e40791534e0697e3d4482716dbb5963a051ee7e6e381d443ef62e132092387350e3cff79c22e028cd4dbd70b150cceaa2cf7449caa20c679576d15135eb22bed8a36f893c6c1848d96b89fada8850c29640b639fe6368975bfcf863c5d27b59422b181ab0ac18e04c57a1bdb2a98a9653d16f6e651853137c7a1b546088cf06530e1f0e17c0fa75bcb8f2f4ab6c29fc3dd81e5dea0a4492573e6c0a29f8c090ee7cb10eee41c28c7f79dfac954d95b8e7ba9302d7fa57f2698b0a6c496c77b483767e423778200c2fbb5615ea53b751e20daaf9964bd37bc787f61374cc20dd36482840401de24097d9610e2cebc2273eb99c866134a25ad804b24152d751a8596914c2c01c5dd76bd388121d2171205614445f8166625ff79ed11b425bb4f50de399f3fbc3011c78da96439c0a85db5ead0dbc568fad5763c127c3be6b2a8c2f0ca463acb8969fe8480f289acac064b8ce5c024abe6abe476391f258a051486d35ca14ed4988a94ad0285dfb60772d62a2611a811fd30002cc86a296752d1dbb7bb4c6a88cdd9a5c90e99d02d6cbfc97c64dbcba749028e38fa7fc33030f7f6e21ae7e680600cf4b2a765fcc4b740ab6229776e1561eaf196adb281bedc3f8d10efd1df336468af4f04438d94987b88993cbdf7f143143dc6636a7efdcc838e65213a1dd11adaaa4fe2810ea161a1d2cc154c3c5c28d8898a7b8b70344edcb82ba762bc9c8b35cde31d785c59a2122860b117b3078339018d3c176b6f07c8a5b2b41fbda86c63a48f74cafc3d0d99819debd46a724e17656abfb21d20355cd0572a5f85612ec6f2b58486c5ba80811a90b9c69ccc90cd754844a53e49a3f507ccd51bd2d8952de78ca474df3543913422312024012c670e880450cb97a18033a464d5356d57d2f51f2bfcda01e5368d8db7c89916c773d4341f75c51a447d420089b5e6d23bd5eff3f439e7471418c0d8b68deedaded2d4ba2dda0d0c995856196d7766ac0a1473f5cfd9ef411ae7ddffe3fb2e76633c5d17d9eef36a420a236e6ab7159dc573b5156b91d4ac6687978703fe02861ab9b808f7aac5c5bbdb137e334e4a046f370c4ff51088ace0bac5c232a250bdd29ac26e8d7db9fa65f93a12203996726986cd1c0a1458aa42b16e43ac1321a4a31a3964e5e0486aace2bdf936f2bda43402b080b083eb1200b0894a64820c37b312138815e59abd319d121456276f22973290f406c61c489fa920d75dc084cfd5c1aaf7660f238f0329f8132369431b5e48eb67c612a3e336cec069afd52994048045ac69c7065c410d6278171e99e096a04e2bd23213532b970656c5a06b75906b73b52f51c277d5d63e70c7a2e8ecaf58c89ddaeaad68e40855ddf76e04d3f1edbc88e4093d84b3cd0fe67e88b983fe444bbcd88ccef64c2930e1b7aaa5be2cc90122816d0cbf48f0fae630ff71d621fda69d62042e006ad96a3bbd0588a19e65d1c8712ac8b587909209bbf5f009fbcd2e0935628a4e999635aa1deac96b4abf7272905cca58102d8aa9a8f80943d735ac52faf6b816aa35e868306b9d1fa2b56249fd644a23f49c73f10cd6f089bffaa859ebd3a1694b8b21cb5b0ae9f9adc17c23db222d00e04afeb2b980db309fa90700bea810a590d23f809b03eff7d30962bda5fc942057595f79e2879df7eba0df55ca77453e84a7115b1dc9427e9c6dcf20c99dec66e6cc34962dfb81a60498a40b84aa7b3cc04b973cd63b323ed1a16121d826c572db5bf4e7cd8a8dc5748741eda69685280d8c3c416cc87a983181a29a292b201e32f40ac3aa6d035c82543e2955ba01d0f1cd355b3035a18b72bcaa9a3ef6544de4a3729542ab11aa9590ff1d2f1895159cd3d46c008c608b0c940abc6f6492ae342c7e8c19072e896e93516d749b646de09cc355385753472a71310e4e5627d4bcd9455855c3ce353cc0efeefc5f318af3f731d0d26f7dfa9f308f0fa942c003c2fa7217dde59b746926d44e33031d1ecff9574d0b9e7f2e13537b0d167e903fd5dbe050e1da40618e7382a709666bff057b39b5373a96c1d6aff5a10546234cf6eb08289cbe8606cf75eb41eeca09184bbbbe27c334ee08f0401505812346546cb03b08fb6affb5378624228be5211f1904987d4c6376b8191e58634fe8294ae97ac9091dbc67018bbe695492668c02dfc01819d98a25e3b26be8c11891250211e19d80764f69c64d241c49a7f5b5700efb0e0218dbeae2ab0d41c6959ec1f7eddafb5c19221e0e57944a892b6580b8de6eda32c49fae0e944e8d7adf8bd841afa058aa9c69b1a44988ca0aa1f2e2a4804334c581c96274917e99f3098ec0cc8ec29ab4709aac9ea68a7e9a5cace3f1725010ff310979cb3cbfd06e3de92119c9f3831fae082e3879909c50c02c71dfb2e83233e1b6f43c0cadb38f62cee202963846ceaf67fb202cb1e9674b19abb2ee12a57e757bd8707f150350b4a52988de0ff06ecbd83561cac68454511ee69cad9b752aaa851cd63787db35e6ea54122436a4c3564c2058640dafdb67a0202c522dc68d26233e1f0702e8150cf955c7fc1557cc1e90fe3bc52a5750d85ca24f9f83a0576994a75a300aec370eb29877b107c8e656df2e7b990534b0c1292b3c4f5037f08d9a7e265fabb8c0296534b59b1b364f8e6203173d67ac9805d1011661750192f3907cd633db59a5673125d4f7c323590187c9b0e0f043a307e83fb9b22722334912263c16177a9bb3dcdedfed2bcdf53c5d4c32c8522d75f76d74208fac5f80259d1300bb2730c86b93a029db926ea0f0ce83f45347923ba25ff2727ae66971c9c2941ad5dc4025428db6afc1e7b72d7befcc6db16976584a2c66ae1ad676f6245334bf4712074155800dc048cd340c0dfdce0585128d1d53e0fae1d68229c6d70542413b1f4e5a4b9815be942c537ebf901d98158dc970a00ef63e77de541172f7da53678bda02c0aecf2c121a40bb9a91bde2e84442177e397264971689c0240adbdeb4e83aa18eb0b9cf6b3986c8a39865e6949231710c6e720cd05a5d7dcba28e2ed5f934069ee0b70bbdde8c7fce7d2ea26825bd40b5b3a04d3b62c8708898637e613a22e4e351377c95e0851ea25d85b9276850852e80b2c69ace512cd2463493a0eb80b91f2532cbfd3f910c1b2357a468dba2e7dac6414ce295f36b5bce993ea757d450f78950c1040ae921e1838a881fa99ddb27b8de1647364cb323cc77febac0c4d9d400313027c21d205b02820e85a0942e9e4047d65b9597dc26e14b95e3ea1586740e113e218772e28c21cb8042bb68fad17caa1536f8c7f54d816a02ece6e7b0bd09d1c487f32e55d7c200e0d036b473f45ace576a1de4007b639f3fe2d7e8d09e63e6c04a0bb682cb80ca0918b71ff16ae4e94bd4b2aa600975ba444477c55798d321a177506d5861c9617458a73d153b67857c541f84aafe698cced7e09c6600205f03ee14646461c63527d70843c690844eb7178b591122f849cf1a5fec5bc0f07275d5d102a440e5912f2f75b8ac5c11e65328970e9fd410e55cbf4ee0850daa696581b943869be35e431a472951d7c145b5d6df832c61e5f1fb95428764f2f1f1b13582570f19f7f16b1c275a33a04b370ff5e202e7755483fa0db6bc41b142a431a7ce87cd09d41154022c7e36581e3cdcfb81cc9c20aa2f6a6e362c766f4aead5719f2c3fa95ef972bd1fe7a500acce6c360455cc1535692a8d34f030aabd67b52ce855d67e3457b2089e8d12f3468c05403f414f580b41a0e302c1b8894a695b939564858c5c7b7b7425e1f8eab981acd58be6d2094cc98668ceba21168e6b6bc94ff870de594f041490ac3cc09e5fc80c818c95563361e5fc42656ec689cf182e15e4ce3fd8dee70c89afde7c072f5dce544652145e04c2c9f1e31c02299390224b68c4b44c3a1bb5342cb491900d0983b70594c132176b9dcaa69271799715a01ccfd72b9e058d9c991578fa81aa50f541a55db386a327fa6af400548ce9c2fbf495b9ba520b5df6b4fcb5369862a0d4f43464379c3fad7a6802f75782c5bcc9863c5354536f0a4c090951511415cb22d7d20e8152576efd513260582c2a1d8754d61515fd25b0d4e9ed72380b9e2683e62a3a92c5efe570b8995fcc9d620c46f2c1578f3c7bb5ca4805b3fb7984e87ebd06062b5b5a68fa3ab60a0dae27c1b5851e337d0f9e01a1f2d2eee0d74e092ab282bd7ebfe2bdbf0d419a8e61c615fb8a819ec759d4c0d114f17306584c9ef46b16f7761a1f0ad8973714897e3ff8632595af32aa4839d6d7901e103a5f1ea6a5153602d2d416128e927fd978eec93a40d438e5bf6bfd535dd8a13673f5b880a9f5ca5734526a4118b2b53fe96f8779ee452b36d3b98b08cddc18e2ff0fa1366003ea20ad894b4bfc2d6d3c73f7d4ecf32850085c4b6a0d97e17ec7e2fbe12269bb3de3d8c8d0d135de8e9f97a5ba007f91399e1b30457beb9e1ed01d2c9dd9903ca645f022d28b1c29c4c80bf65b404c16531f3ef30cf5297c8cc81e1907bbf29c463fbd4b997fce4a5c21aea9c78e732ec67c3f551734bcd1388ddf7a5a7bb1c10878359805e605fb4fa3bb28aac12ebf267927fa7e776656d325f74ba29da5c2bf3e97413234efabcdb51d309c362bae4cb685612ba04ee50e7e9fac94df9445490117765325d9d9cc2536f9576f79e0b607495e3e5a75285a0adee504b1a78e65edca0862f2852d1fafa4888d098df513802120c26800c93d2d729a0722ac8b1d43bbdc9c61b8b0d61551c6b3ba6d9c76844f1da1399d459cad53f660a5b08f37bd7b5c60f60a85597d7f9bca4a7928ffe83e1faed5b40776eb974403f42477c91c664ab12a5b8625cd0605719f1cc82b9d18a2f100b279901ab9f66eca211f23d9c51155bb0d67bf434fb9a5e52bdb13c148a4b4f5068124bbb1fe18d3efb69612cc1b021d7e7859da69f8af25084406f289bee11e19bce8fcda2beaa94e02b552dc890cbd8068f04d6d759d916c1048bdef77a5fc3f3c1df687a8592b0246f0b476c820d7a01546fe5a2f0fe1d450eb551a492b65eba8840174351856bc4b4b1af8062263f8685cb81ecfcf3adc661ca2f34dc6089d3d173092c634266b9df1a8650e8912545984129363f4db3caebdc130a758209dc38777ad5e759d4039ac2e68a3149b1fedf082deb1b436284a6c557a6ea1b0a3ac7a10206e4d477efeccbfc3004ae888dc3eaff9ee62b8248c68e66b66701c0da40151b2c41fb02b3a19dd0c40b30199bb13db63e566fd6af3e3812f469ed23341e3c0972cc6e1ac0868ce0043cee79f89922b14d4b9d40a7b4c5ce184f5850d4a91de0e6b0497598062604245d60b27a37a27eb37faf6e801a04e89b12b080f74925705cc9107f29085bae3a8c5d368ac4e1a76bffd6169eb1f314100acfc4923303f72a1425e9643ffba82c3da63b90ed822eb405711f21ae1915f8816051ea837bd335bc10c6a3aee24e0fa4c1323cbfee3062e1b00516f60e50ea2758f725fef3a27ad16fbf95d7958cdc20b5e81a44aec8935f4d17116ab8f59a24c74a55746075848b991017651d3d1a6b9e6185e591c0bc206856988f2f522d132cf7428c2b45b678aaa38ca5d2e99a80303b95381b8d51450ee7d40c4f18cf6428a07aebaf22533ff86f8c43c192df3e659320c71826e4060e945c449d008113db777a856e9c89050adc8a96765a74fb13ff8853936d1d60d98d764d2d07c0dab6f795719c8283d048424295effe0711e12214489a970351b55644541beffaefc7da8c1a86fdde7deb735ca5fe3123ee03034be9bccd4ff3df460a9e8f31be0dfb49116a5c3dde10d9c955479994d3fbbdf7051aa94da6ab5c7391dcfd2903cdb350e40a2bde5710bf582eeef32128e3dbedd2b20204bccfdf0b57754169b31d72825dcfe0493f17206e6b06103c3091bcf693e0868183eb34f80f00763e06f04e2e60abf92f5f8103e288ab431266ec594e0d80c68dba450c6ecbdf7a0a84d4dcbb9bc5b21866364e0cbb6426993cfe5dc03a5e61a6d62805d8c2d8cc44f04b4e07fe2b97f0f608bf43d47b1678e0ba9f5095e5340d492a795a0d9de9c398a79a9caf105763ad6f0c56d492989fa088729fc1d62b2a31070f3a3e7c7926761884194ef95076370ec4ed8bb2abe0fffd4d1e8fdc7bbff8a912e552d42e44e91bc82fdf8878098f5eaf1bdd0d8e3f4684e13a778d0c5fc33ed7f048ca2f9a82e9460767949f6c0ee7fef146590ecc664b28e28c21e309a0b004974d44447fd1ff477ed9403e08f27864e4d354aafe3bd8152a89610276fb71342a507220493e94da9266d2e0ee186e0a492695111dd17793594b90709daecf592826fa480300293785fab87ad630c430163dd2871eeb1ca218d6d84d52d58e8ddd4a6d510444b90db32b562d4a5e76a84c281630cd80a3c41468757100ddde4d28bbcf1282038984171203c268c697741218ba0bcabdcd5f82fd377a1eac1e09f9524ff0d72a8d43e5265767cb79ee7b25946abde2ce090bd38f907ab823cbb3ae3255e9c1bd27c8f4173cfcd6ce1136e908828d1199cd6553dcbaa45cdbbddfae2ae13270a5e15b11dcfd28c9f040b76e1d189879138b807a116b00abbd1850f56db94a9b5cdfa1c294ac24811992e510c463a31d8dba010494d8b77700b186677e94fae402bb9f69ce396320c1412f65641314b73280580872468d9671b0c546ddb8b585ff76210e0e028a98132a098d1127b4bfd7b3488a129bf3111144fe1ad63e085f9e63c6b6022b35a557a34cbe8f8d82c58d6f015ad29d46d4eb607fcb4bc102e3cc726d153d3c0657d4171dfc39f3ad31962629769fb432aa010e43a5c30b4e71c0d8ba124355c5b2a111280037569a63eac424322c432758f7a007f0962720ecf5915ccfe1c01eaeaa75969ec2fe588e808da49ce8135f7d4c51d58ccf37a9b8538576afe6218bc020731ffbbbfd76160d546f570d58bb2a9131090dd2c31967d66a471c1ff64f939e38dc7b4df8150bf4be18b58721ad96a177f577c3b5eae7a398e30dc8297b476aca74ca8234b076a5afdf339381200b8279e92e98bdb4cf4c0aa48af634ed738210497e6d000eb99cbf1ae704071a6c431c9abc8997c23749070d53fe4fd53838acb06aaaa79aa46af9c564305718235a758add978bc65d315bc0d01e5a2511b4bb03c3715973a4666b9cea3cd9b783e86ac224443eb948c2baec8c99d18300410cc1713b92202ca86f88a2f877128a81abd3b08057c7c25ea57f2a1f8d9bb974ac05c7ab0aa100df66600ffbd3330ce099be1dcc11f846ba69ec08b0c96b6649ad5fd96e11634260ddfccbffc49665abc458943444d0b339c4c445e16e114a3b6ac5c498107ffca4cf541b30c684729c16adaa0dc2460b8aea248bf7e19843503b9fec3bf7f1c6284944f6fc63016e6890f07fe630427eb0cb471f191e238a43f194941738a0d19930e8da9a553d3c681673a832e013911cf85407f0c8dea55c91b47c01179f94cafa55f19480ca240c7b5b1f372b6e405bae9495d32e36b698dc2ecc60353d114f89ccf724414c2d28fe8cc36308a5e6d4116da7f59aed50d38ba103fad4bbdd6f183ebef044732439fe0963305ea5485022c199eb4241ebc6f89dfce44bcae8f927d67ee80467dd20e4ce5955bd51f62dddcb617d399c43ce46621f6e5dd0a94c8c1ad655b532a43bd8cfbfb783eeba32618e662ab00c0b80952688a45423558401a1bf07c8f67ccba199db609c3c1d31db6879fb919e477ed6e940020665062a84ccada77f96af76587e404ef4bf562ffeafc45a14dc8b18a4129dbdde07655c940c27cdbfac313d04e80b032574a434c66bf19f9017e715220ee28f478f748c72190e61638fd5e763b5fef74318115a0d85c9264f6708e002a50fb158144a4cfc23658848771d8fcebc522942405345dfe00f9b6e8c19f387b13470d6ee6907606300300008382d4686ef3de62517c93837f2f60fa9347d211f5b166fe4d7e531c05c57210b88b29e56c1405cd6c9b153e3f1bb5c5703329037b2b254be23223e68746dab50bc1f25ea87020f2d95c818f21b63f386f41c0fb0dd8254155b81dee18cad39426ca90e4a535cb9e76a27a089b2c3ae6cf104e69ab3a99e937f4ae18940efae603b8817676e4d600c46d4e427dccbfc714dd5589f65b645eb9ff71c70f9c0374304ab21d76e386d628081d98f0b3ba608ede102340af0e9b9ef8226a8a72730635b0921a25b3a0578a813cd9db37dfae130e929edbd48b44d6453c29f2bea4c53dc358e8ec9a1fab04808ac103f8cb8fd59aa9992f8c241449b5efd1852f7bf1c9eaa003074815f9bba43fbef249973c30fcd29e5d0de69a4f6b6ec6cc12950ebc85d7ace1d0ce29d7095a3ca01db64cf02123814f82fc5bcd5dec1eb06582886a34249bfca144872ce269aaf50ea4b7e71ece906d7ebafa2a2bf81646f4b66a203e1c8b44f7dc48f2b90f5e7f728b3ae5fb89b6b4bfe90c0d3fac21ce81545abfc3f0d7bbe37e209b71310c9f53bbf4236ca4acc586a8a70341397f12344cc97bcd25f6c3ceee685eb9a35c0fad93837ca52af8ea92d03221df9eed6ef563b23941f87a4fcdca2dbba87a8c2b9cbd05a106cbbca20e16f93d3c26415e84d970bc54ffe830c866ab4549a12c23ff84645817219f91fdc101048256ece05958c0ef86eb38eca2b55a28e397904a0f8e0b9f94d39d49c689367610fed215e50d17a051fc26f14b07743aba98a218a1434f2ef82cbc168d72bd658550cb8c2acd8f3fb02ef70a9367ab085d91a51e8e5c4f2424ab56f0f25382d4c11903956da35da763f89e4da7bf91a9cdfc7a54ba3cda529b7c04ad2bd23410288075ef88b13a9cc07e5c8ff4cdd79d476666c049753515aea4c54fbd2bbf28020b6935e6b3b93a106d310cf407818ef8aa6b31df4d6d190dc20094924513cf488e1610899310ae60cf9946737833a074822250cde9288cbacaba54b3e124c00da42ec163955197ddb58e9375c0907220c93d4113ee729e8d98f6a34ef8c6713609972666b4f84e10c7f575742e1f6f8d641d99524446eba86e9b3e9ccc180ff0ec3cb40c8f2d8ef8e520e180c289d3c4ef298d6f86e257cfecadd1e4638fd72f611339af20bcc7b98b2d71b55a6c2c468412487946907f476278c10500512a6bd8386e0ef261d9b9d3f4010487bc45823b1f36ea63f71a06bb1a772f14a09d9b8c40d250b6b8ebe87d0c7292b8890da226011b96addfd8a75a04621a851d368a0a1879e22436408d11e66e984338db2662e48130ed18ab9670d824c80b189bbb74fe25b90258a03ac816cd00a59566ed2e7149ddd341bed866deb076fa4d0ddc32c0952815a633eada34deda23925d3949eefd2c296d2b2b801d502933445214d79399fc2df95b7d6a311add180500d0eb98a965cdad919edcfb2b456c832560370607c0ea605330a6a25c63a700760279cc1f650df6bc8b7f85776dc6ecdce55b4bc62eeca940663ec638412300d0fea94ca33064cb8f4e022a5fc8ff9b1a71f15227ebfd770a511be21f2aed815b9d27814f88f35cd51a197ee29273714c2ac5ad8f75a898bb44cd8571aab8f69cb2af4db6676db7b2f530e362b1c3bd0fb67caa48cf5df5607e56f78083e7137aa97bd7da13e3824bd3c5e292c81d26f7d1078a29935e05f7503659aa56271c5262391d6c8e2a08fff86c22f6bab3f3c1efebbfe42cebd00433f555e517ed822fdbd34de4240b79b5c2dff9aac290c3857463180f21591ac197e218244125fde54dfe404420bae25f8d781e28c9ea74a8c2f746d428ceb70243577eb03f8321ff9abd41e8e6e7a8ba6b4a3bdee9168d2ccfa499303d53df271a15245f58e0ba28b94377ad046138e287479d9ff58721587043af7c89b03210cc1e8249f3dc5f45cec07861b08d7f8ae5bc094b0a52c2dff86cb1bcce9644477114ee9b257e4446ec63de1b488b155a8bd9955425f6be3699c5d2be7ee10a4ad426d2a693d7e0ffc0e38d2623cab55f28f05c5557c1da59896b38c07f89f141a4336c304cee5c289e9a05581b0ef813fa1cab7026978b74413d261b75f6114aa1d5124e8cea8cc4dacf091128675bad07d6f2b6b55ba182d57cb5eaecec5a39c6479873e0e37587fccb6d07bb0544437e2aa8f2e89a548e87d3329626438df0f8f8becba8e0c41f45a1e4fb5a5444eadab86d8156b6319654cd1feebb1289a09664828afeb4adf9a5839d01c85a238ee5be9a24569d7146f5c5a9678908c3c4941c72b6666e42a3e6f4db434198645b9686ecafe52a100316169ef4fed55e036ccdc099afcf298d73bea505df608abc60225504566aae2b83d2a221de7657579748efccb0a7c70ba4a6d0837cab4d58e46f9a48a07756b53a1a5ea0f7635516b907bb64881c5731e8fff60097fe4335b275e56df9d80d97a7739606a23efe4fa7fb2dcde63ea992acb3491851c1f94bcb67a42ef5f7844d293388b315223cf205409cb9680103af2b223dcded5b2fadbd0d339c75bf63b19042aa77869f1ce4d54932f4e9b7a864a1ad8fe889077cc0c885ab105d6b4ea87eadc70793f21aea5e5418915951d3e7f59783e9a48007b1dd3ef033c6140a6b41ec4c64f715c6343507d05b88110e024350867ce3f6ed080e90e6d7f9a480556a5a70c5d17ae4ffef9011f769c763cb0941087965d3ce4b4cecfa81dc37f6359e4dd370bbebdb1cc895dd53a3b36fec10320f4b16bb39f2204210ab0ed1d5fc01cd489023914de7aca27c8891dd700cf07bd28c9278511f3fc2b9da833aef11cfc46f4b3cfa147b2977b99930c98f359eab14c71b750b8efeef8265c868c0d15d5175e1f77dd22ec47efb08c44930ce860d12497ea7b9ee5b6354be91e6d0cd85ac4110cf0d84e60855c5cf5c3a60bf42c1034209c8508d516a49e360014f62be407adb5165fe7e6d215f9a21ca0f1957a92d3bf40bc6687b37e8b90347d3e854fc3d06146acc42bc6e512bbcc7b90fa3fb627d5e5a70a3048dad8ac721f5f3e11112cbdcee5c1afd6d1a31d0a81c91ac1d6a50eeefb966737e3ba4728275dd0a300573c37a22470f859ff5db3a31ba6fdf2e5522b143ed2283e5e8d29ae429c6b6b81b843118e67509bdb87739b1527c63491df3cd2916c69c5f7e09c7a7e6cca493eea08c77144706ab7e5f3e1aa8525d3cbcf2ee1111ceef895f16818b06901c588cb4f71680c411c0a6e7a811ee6e71b0f5096304e6b2469cb131c4ab174fbfdb82d0d9755612428bdb0f78f85fb7dc4565580a61ab107fd4cc0b9ac381a859a8dac21d182c00efc11d842834289f2c3f487b761447d55fc6732427612a66dcfc6af7321812de5277a3c681f7200016c0574a107f1c133dd68d1ce966ca0a5d99fe1ea1a77e61b0aecccfa1273a46036a1563639926abd89d323eac27de61ce714c9b840849937535767dbc79925dece58c574bf4244707e91aa2fb9f26c01bad21602bdc064682a30e3f5e5a48c978d2c0faccef90cb904fd1e7ff7b13b67adcd221e6fa6ba7aa63d05190598dcc8e0a1b60cf58ba335aeda1d983b6ebedf045d4e77d11c2270ebb158c2655ef7fce3cc45f39c0a83f3d0e4104d0c88b71cc45dc235aabfcc9cfa71c115a9161fa08a8f946c2d205c023740cf063e0041d98a91684f080c5fdb00cf4defd83cf92a813f93ea01e1e91e33d8fc60769c8274b254dca39fbc8c2f2aaea89d0225eecad34d1886bde1d9066959e853474a71ac6fbb44714026c3b5af802c9b977aeb83338d5479c9d7ec01c86bd357d04c80e4eeed0564ede4b2444a99d9121b8a823934c270906b48ba2d1b35e0057ec2608338c70db90b3c77e5548a002d88fca8b68d07136a647de9d2b94a0dd8f2323c60ff2185237ba07efd8d49b4bd809bcd0b22a864ab8a279cef7cbdb22e0ecacd8cddeb6fc8fe24d94f2788d91eae144874a53abca9e1c019351654663f5ecf40e1b256d13a3012fff19af4c119a5d0a3d256c87e05dff323f3d89af38b8b6975abc69d3a5cfd70a78bda5488d353a97bb20805262c3884eec00c098c9472a9c17661c273e05d409c1d7dd569a25d0f8e85859751609e6805a8079169517dbb8cf82671034c8ccdaf73f8107d191a524d23bf0853acc1ebc400305425371bddbc230e35675770b0c5c27e0d59e294db4032b0fac21c83bb971c4a57242b40c14d088f9b0b3f6fd422a951da18b66a38752273df0419a74579e1d18a82bb8d21628ae1dfc1744deef83163062281099fba4840177acb4f68e4bc97c249f4a98c1e778eb63309528785e6ab1bbf9f48f1f155b0fa44a76e764e2b678c4e3282e9d386ee6d5e844981fc0d068ce827e092c66d7016f28260cae6966b6f343a2721489a3113fc9cb5a7b18044a2b3c883c4a076c01cdc6853036d4eec04ad9737bd327a350df1fbda99a86da8c321057903c15f54c82eb040daf29d310666013fc8c473b3242f8643d1fea179e1a3539d4bbbeec7579da5f2d0b4a0057639d682b1cfb7fca089c02b9ff52a68242802b71292926a7c2206572a1903acb4f705704de9f6be532ceac4a4b30014691d0a94c12096d7d4659a86061fb91228c073ea4b0ac2364351573000dd3ae49964dbbd915341d3c548430916af268b05883b15a0cc851bb7e755a0325a0b12fbe7b2c725484e50ee3087ff80c2ab5730b91b5e5e2bea2d2823a40a68745e75d0810cc1a5e9bb5b35c1c13af83ed9a1dd43984659e4acb80bac93f55b2efd6721635a0b3713048288f2a61c5082af585a61c621046c37133df6877d84e79f9d1fac2490de14c798440701c6d41a00ea2996e1288467cf08a7825e88ae82358fe05293ae71f91ab4ec498c3a157c01910a31cc017e27af57f926f1b4a11273342924f7a0d08a48b707560adb1ce9ae81fe0cbca97900b771bb5619a88b133157fb585ebcf264f26e0246a29126c18cb7692456abdfb48c1a102aa54ebfd5ba3ad107faac1bbe07c8ac8c4fd217e29bf142ae7d386cb0ab4e560a9db9bbc25effbcbfb8f35df51ab5e76fb81790176a6b84331800015895b09e8d8caaf5a2fcdfc518a2bf8a31ab50ca30fd6a28ab11f96ffd8a1be471c34613e29ec673cbe802e17373373d5b069f4d8a8531066ce2687f0c32e0056c1c5fdebdf3d163b32da327c74d45f97d1cb31e73596d0f18a3a0622914df5d2716788b3831cdc3bc4459bb9943150ef090bfdd1742ac89b472388cf746ce7c6e6115e31964d4d22849c1e50edc4c42fe91cc4d7f2ef3f0f66898183514e2b07b72b73ef9a63313466878209f0b51901ed12442924d60512bd10562b500965b18e8487c73564df6a393e1ee64099c13b880d3004e31cd1d3bf0043a9d2bc52f6875d7bb22efb00e01bd10256817ee8c7d02935cdfb4925868c2e556ff0a0252c6f80b41e3ae221a845b2e0d07188a6b1f22f533a02f2f13bf2fb06b317577764c40f057808b3138e21f7b430cb79f800f16f899372296268643d6c8aa884beef196ac118b2355181c687341856628a9fbda1222b327c99420912bf62b838599195d1763c1f7be40aec21581be1a12b2d7e267811a8dc4e0cc3242973a15308c24732306a05da8320926255fec276050ae29782f8eb2aa510f1d55d30682edef929e6ccb5d0342f4411187407021b5b11b61a4922ef93e94ad1abda2fe548c4a81b79c3ff4dca1db0984345ee5a064d070d09c51b7a89a423e97e198c75d99d0363112df24cc35c051bd577e3e6f1c4dd0b8d66a5ced9ab0648c8dc6ee700d445c3c3e5f0368168ffcb0a13e21202bfd678a94891c7be25fbc7f8b9645fe645c8e2de4060a0e496f2e1627673064fcef19ce19e313c1fb3384740fe77dd6155804e46fac78b905d906ea28b7771ddfe2cfaba204eb48d65c1c33e2c93830940ae44e5abf50e0c50e67c7b6500dc981f7831cc7d421a9cad4119787c1bee501df5b3e419006a21ab5cfaec44c6b28bf082ac31865784d732ad407974a6b9cb3fc788702400bb233c8250dd636e4cfa559e73dfdff531f7d151aba75b13c93d007702759d4a0d5c7053d3c1f84a46dfeab5f1782e766fcf738eaeb2bce8edee1a08431aa0a2c5743ed412a0d68208398d503d0104080c86bc3cb4901448a1224f9d4a57e49cc5b06a2357ca97f13fc3067a72dbb559af7f347983854a28597e0640619c0faefe4e306aca40c6c836b92aa3935154a7d2387994c9eb371374eaa0f64c651ca76eed4d2683286ec2a6c648e9e4b1f69aa91fac2c083824a1381c583f369b8069c1df44e799f0ea0af8fafadcc2c0804db33a7fcb5e324d55f4271a63d70ba7ad9ddbc59e440316f1ea85ec74e62d1d5a9200d965145f1480d93791ab88bdc71cffb508d587e6636dbd7c447f5416f087196abf41e65823eb988cb9341a9c84549ce4856d4d35545fb1936c8003f2a637751f408daef9dca9bc63121197e57c1133520e770a5c19795d9019c9668a1546f7a318b4ce74a0c49e0f6363ea597e60c77db1c54e20c758c58ca1e30c27a22e4304be0207c5d18d246253521d122c008222248bdae69217f5bed647a6b6df7b43ed3740c8f2cb7d8239e0b0f2fd82253956b92ef29f123b034040c8c841b013f1cd23f3bb0b2e595d5862b560d52fc24342b656393e7fd5ec1220d0b97ace46011d61c31b2cbdc87626858552362dead4bb43feef46d346d8133c72f9f09786356bef5354ae1d1720be9e0e382cccb9215f514d52783d63749d5bcaf56d9287cd287230339627380ea20a0850b5cdc3c4cb413dbfb493f34c827670404e281f5d34b80e1cc129f2e0c99c6f3bcd475a38c10e261d22460f6c68e59c50c328ebc3e069d1bc1860c69d3bc3f7682eae08874ce7f8a7022e130158eb8488c5af85590e35a53dd5fdf54d716e3e7713a331151b25386de025b0eba5362f4b8297d66ad5e6f152e9808c7e921145ec445cc0712379bc324936161c6f5cc4cd0c353c12683aa6a424a502f3d78c42cad6a5f4b7db57d0c364e32b3e8d8cad4d01c6472a33f002257cfd7585af45a41084f932c2dfe8acb5b8822b79861729ee055ba89b96fb025d7a6de8bd9e6297dd89fd206e4fcc209c29ea187d8e496333d2789a8a6dc5e20ad045363805188fd2d43aaaf9aa99d066429916e81e1227977e065a6ae7f3b85ca5069a59dba92d96ab00fd17203a110f5b9892251fa731b8a8494c2818734315e364e8366f66f69170672ed93283a445207fc617244e11ce338ebd22d5d7bbc5b4138e2b9075055f91b5a28741a71c22d857e07865504197f63c5c58d9b4556aa6b742fd0109fef09250c4c4cbd037a2cf9a96dd8f731ac821c863a5130bf5e0f86f498f5d22554bf1552200f753ec72111150b412f80e2f55aacb764a9234525c2410545c445efff46ce2f2fba6d58c3fec874e694563b8350820d4af9fbbe6ba6d14c983b3b6716b8f26cf73457fc576ed54206e8eba3ba6b25b9cecf347d9a06edd2a3dae8ce97035fc246050206568ec815dede61d503cff6e9b7753604cc70bcf80404082eaed037f629d3fbbec371e7a5a077ca0d9b50c9d38ba11bb4ae6f28032af931d3e183e4421c39c91acf01a99d6236755b914b8655d29fb86c0e543569ffa995eefe52d2342bd951147cb1a4bcb4cd4d69d9d080aa7bd07b57e15a0e0ffd8f96dddb49381bd0ed88defc964af041207569e67777a449d6934dbbd359bbc45a4b8d218a8e9e6729fcb26169f74204145ab9e2e67f9ac7569aa9e70471d0c367925e9932c564828a2ea5c91f7aab2415285edd2d224671d34e54961a5b1200a25754824a3fb596b699cf108b538040bf2f00d43e8e158f36ce6a77079cf78978d94735332300a5c663e441ca07c7415f7582d52cc565fe08186c0939a0a53e596b62a424cc454683919280a218f8e21d8fca2e0a0b609bb035413167006be16a1cb9eae2f76893444efe8fa26e0bde54e54cf682a6f91a0d2faf7c4f31d9567972467452d2524982c6706b242d35989285902e7503c14fabe5aa442fef51a200eb495490e6a397dbfc4d594ab7fae388774a3a775a3da383e650521fb5936b40b0beb12c1b87bc088328785b80981f3510da3114697643df3d280fb6608b84ef69a7a5904d489334ef150a74ceae6ee6d704ee2e9baa7f4281fcb16f4bf315774f49ebca369678186912d871e9cd21f8dcf28eed11284eec6be42140e551dd3ec59e9344758468dde9e9ad00caef1f03e4827aec27e46586a51de2d26fc2e17c470ea67463130669f0c6d34224acc32458e2747edb44ed167f33fc2984ae8d0e75019673cce3130e6d4f549055ae941a0c6c464519221f73c728bf376bf0ee4e680da75e910f0f618b0a3c599f425f67acf2c31f6fdb95b38206ff8eab309ef755f3c2c31965131f290fa771851352125e7a795c08159c6dce4894d046aa1b6a2af7c19d8e8431c5ebf29997fcc22b7841d2039e5ea8c01195103574b2800ea16fd15388780eb1bfb2bb052062be6adf61884f043f871f9179681b40f2edfb9ae04d4f09fc1df56daf2a5c651f6c1655666822177b1f6c27b3a2bc5d5bb46476eac65e2be24e6095e162c138b6d46112c54c97c18cddd5069b836aadd18c1112eafc6ba8a044e07fec0b57f67cdcdd9cfa478890ddf61ac7b04c5abb47bb8525cdac4776185a100e74d6e95b92c1e8872adb07a329c9a7442f5ce4895dd1cfede15d6898a54b063d8d87274fe88b3149274b56f75f5f6bf5a6ca9999611bfb2e114742f96c52600b11a4a4491b09f046f5dd3a3e546f39d177f561aa35d884e49af9c0e2edf900849213edba22e252d5767ce0404f8bcc4f6c8d974214efd982463a94e769bc95ca00bdc88a5f62f5257e62f2f5f9f5d2faf8af85073b11a176cadae0c413e57cfdd23803405502679c8ce929c3fa88cdc3e0db896d470480b1cb1b4b47be284049fb79e04ed2d7396e927fd383716a55d6a9a1443fad25ae320a87ae51c06ff44a683636ef354d841ce451b79e8b5e896684c22ac6e54bbe6f73a01c8613cc80d52437bace8c0ff8b7576550ad2043223bf59fa7a000983d56c3a9eaa428b73e498832606a1cb8f3f7fc3825548527004fa224cd934c06a8d82ab3809418f8adaa2892395419acd0338386b6d1f99754625ce03630924dc74575cb37ea3b4151951fa9b6c1d3ae4bf689489fed48e86078b3827d37421ae1d146c4e9569bb0274419b72661c39b43376b9814ca79f2fa7b28ed9e04a3d498529413af3b51373c16d0ce9450d6b74137e12043045b530713d5106fabc45b8767b30c11ec4c51aa224aa6baaebd9950afe32c82ea597765fc020b567f681c7247275e748ef440dcc1c3463105d35b2ff94c83e1a73d2ce7d1fa0246bd20bbe58a97835d2830278bb9406767c80d8db5d849a0fa73d95e06636009b583e7a712e7627a64cfe5866efe2176890413af4637fa870f6340b501b0393a8c5e4a71c4e71f22a594f6eff9c74f26393e865cde5313fcb432bc99f000f1c1bc69b32aaa99c3fe0f1113f83ecd5a65915bc41db9799eb6b1b03d0fad3c6be77919ab232e9b6947d02ca6e3350f57b46f4d0068c0e319de44b7823b5cafc24385408f55a95057109fe411d2d77421af97c490198168677da6e59d8c469ec699bf93040b851a50d8f57923a2b36b25c5024b84f7225fd6a9c4c76f389dca07c64fc1987d8ced0694e106d58ebe39a001e471f1552b831b5f050da9dc19fb44171265e8f0e1696166579104b09bbd4ae41efde8ce8cf49f4f0a987f9120962c6123d25008387c6383b252b2d89435dc002017675f5efc51b486213c6608dc104da9ba66fb31cc044229fe9ac5b3db9efd0de219e511893b408d3798bb57215137641565d5ffd5095841b7a3ba6c4502fcea53910159284c2ff910612f2fdd2802d1441b242a0fab9d74a3fce6137ba649677933de48ab67d9ac2ccd62a31844db8db2016fe6753f2708e37237d8a9beb85c71e2d981327c33823a8d4207df0b0121a4c38badcc72f8f650ad8a3f1c964d61410a553c7fd5350e43063a438adfff5fc929b5e6e1d0215fb11cda94fd962a69645bfb0397f2dfd9c1a2267a56cf6c14234184b7365e5b880c9ee6fbd5f5e300502344afef7ff8add0203ca4c7e021f0901f5b79f2c99745496a16dffaf962d4bfe02aa3b4fbde7af311ada018384652168fea2579738ba3daec9a2a614fc1bc6bf633c5e4b5e9c4c29437885f927690cc55887aff87bfb58dfbe18f087a0d0789d4a454be9c37e733f6a39b1a14ddf0acc8c2d4c1db96b3a42511a01b3ab80dc2c50265493cbeab9534c8fd878902b7846b72cfb4434a63b67bc3ceba0ff42bb8c552572a560c04e9c8b76cbda952e23031faa0c39db5b158833d958451a9a6e320729f0b40c69dac259afac3ecfc852d05dc22c71425d543951a6f592337fa9c4d51b0306ecda6d23c7a6086fb5d96564dc0f717cac82b7679fda27bedb4d79c118f66cf64873e374023a55e29389186a0e1b8f64e5baa7f0894646129fe468ea9e0b39ca15be2343988e5a85344edd1fab58be7d8add79eb726a5d0544c836029d6374dbc85f93636cdd0fe783485e42d708c13344d208a9eb57a0a2bf368f9f1978efb3fd57501e5818debc2d3281d176a029379b0ef90b29adeeda8249654530ab16f489d43a6f8b04fca74d48d42d44752e2206c64e5185b3f8ef31667ab347b0f4908c8e963fe49d5cb246904ec6bdd574d016e0034701acc1c75c86c1c0435b9306473cf8a413794fb46840fa559adf12dcd7c3e09f86b7b17c912afeb705c395eddf457d125bc23d745674d3b7be5ba4ce3b9464b93095ca11bdc6a65e3e3470f2c834caf76ebb588c3fc654af43cfde26a0e0ff79626de3cd93f5f8f3ba5fc462c6a9928914ab0f2ba7ccd50d14d4e567e2e9b4e1e50f60c8151d11f962ec175609bab069b70f93b158618d416064138b4eae630bade7ca82bbbff0f54180b654ccde3528a950eb43bcd0cd30d5bc488fd5123ddb8b5dec0f395d73e67ea618a501f0a3d9a31d04332b92e9af355373c1913dd5a98013cf8f2637beff06462c9c5ccbec42e3237bdd7347374d9b3b16940be20ff8ca6119368087edb207bdcd6b00cd245d9447f9e92e19548e9fcf72ea2a8a6e1ecfce44af6864a9758b5eccae389e33e742f235ca10007ac79942f4cfd1e200320af1c6c6938516268d3823bb20f53b8a0282c6ef2d9a5dc3f0c9926685c3ec93d6a488a6de61b2b57271f7b05a997c20a87b080fdd8c8980c4e600c37845a4db55de43b023e646074816fb68e431660bdb72db70c661cee0888a9db65fe98b8a1d574b7950b5e9e51b24146007a2afb9a1a7c8352a10edd1fed170c93753848c0f70e708c21b552fbd9255ce646b2ea69e1fed9110a015633d987ca8fb6b99fec50402a5dc40d8a349a4800272867b9ae501fe9a94fcec2e7e86a209210d9bc2aab338720f9e28612ba1ecddd5cefb91c7dd5902f24937365028a879e11c17a227b2b38cbc6d2f79794ad52eab5d1a98ef13aaa3e22eab5db0c753e1ed856349e3a07ce6389722be9fb40077ecae38bc3b619617e61450d276646e5879c70c1d9ee90206960e470fe5da9fe925e8adb5672f3a7526665807f031d960c749d6cbc73a0ee040252e87ffaf36703e1bd29e1d540a824631f2418e7ffc8f7dd35c9327d0fe1373d08755ba1f290771fb65ea28bfa1d1ce24551743ea2f5f9e4f2aae934d870afae0dd1273bef0c2d6e85de10d9b59b601d7e3d0b1933de33ae204da73b335c366dc9b5188eeb059f7a5c6eb2228d41903c0859b0ead3d901868274fa4068e3c813d00033741ea73c915dc548822d584e368c0afb9c8fff7d4650ae2c2051dc60ee3eacb4e37afa2d870529cadb159d725835f05dcd2e56e16c2a14855a8ab285d8cc94af527e35605952cb29ed045ce53ce96d3012d2b87cb5dc9c5940688b2ca999417e43f13d350ccf33f13a8c24599a177032b13fb0a9828bef842959b645bb4be9843ce7bacfd24360f686807e329afd84902dcc15c93da620e0216276e80ad7e32891c526510d878fb53da51ef66f25e457e971c56158744e306d30ded17ba8cc9703f94bc2c663ca5456c99988df30cba8a9cee778d8051fa62589b34b0a5bfed80a7ac5e9f8b8067c0676581436a7046a87e95aa70532b8a9e64899a4a1d79d4598b914dad5df0276cbf5a0c0e6bf643dd2fb9ef53ea8e356417cbe71d05b1b81a51ae3ddb78995c1490f492ead7046b19c5fa0ce2c89175d9010c59bf2695a926bcf96ae79d347fbbb8319e9c2adb28752a6b9c1fcadad91d8d95b286b34326808aa6903dbd806fe6e7f1c1e899571b0bb4e22296cfd7412783b127b1c84d762e11ce0ff1d7a75752e198641454cba8d94192cda93586a6988c8ef74d97f6d083ff746376eaeb14ec5a1d6dda6ef4f261a08acc46032a2bf9b970e7aa8f6a6c4d7857d1fd2290477ee669400ed6f746a3e5572b849367d029632653ab6106db9fd2e639531b9e1098218a4f53473e2bb3d165b365b04f09cfcff0ca8b42ad7dbc66e93900b90020d984e76b5260a7658d0826120c8087850a135f7fe5fd8a30b2ae7b8c3d9fbcff4558b267097dc8eba576a2270ce990030638b75b7d462729830b5b57fa46638c6c00d6dcab8381c768a80131ec9b059b39beb66a77973a406c9339b06c4f376df92b49ef6904e741bbd04417a93b388909ab029f1c5db8a19525995b328138b99748ea71456e7a413241b33241d030ac8dd5d5c4014163707b1cd0e9bc5f1b25d7fbb7c3b7ccc80b57226f47da9cd3aa090ce9aed9b97c99f4b96b177130434f5f044b6c3c5a68bca0835bcf0b8df831fbb12c7e6b41f4dc96f61b6636cd2d67b4a5f804ff482464b9b244922654a29bf05cb05c2056384cf83cb4f3f94103246cb4b5d903f84b0582e44878a344992244992d5e52095e2a2bc4ea7d3898ad39f2845013eddcb896047740d85c169fcd3f79c565229a8405788ce7890f1adf0991b0aa3846bf6fa243ae6f35be130df666a2714bf82f37a2b5e892b89a6b1bfe4a7782856f0a753105bc4901fac7be61d03d608a5ba1d90130cc33014eade7befbda11008a6bcde542873280cc3300cebb1d1aaa27d62fed80fe5f90976a821b06359bcf7db7e58adddba17bb376443947da7c5d5c2d9b4f628ccab04d134bbd429ddb44dbb30f6bc1cba3f346ddab4bb5bebeead9b366ddaddadddebcffa4157b0caa7e3b615acf2e938ae082c8a6cbeb24c4921c6b53056f988e83be8de2c5f9cdb40a390f320366299ea609867bfee7eddb59b356a35ab59cd6a5ab679b125d42efd9ae6477d352d13d9bc5cd1ddb4e9fdffd13b2a84ebbaaed369752ff5bc9c413014baaeebba7c34cdd7ce78c576180dc57ea2e9780ff1835df5a0c0758566d14f7ea233a09675cd3753500582601af4e4613860f04070030e5f5ae6b305b5744c0aafe0eb743a9dacfd0f183a6763a6f9add6b71690795afe7c26d3667295b7bee5262c302569134d9224fdd60a0fa6be050c3de33770d3fb81ca0b5306372440cbf400402652355e04920973349fb80933796e3299a6699ae6bd366e4c9527582854ea89142567cf2a8a8a8b8a429521efba2e123c9dd05ff6b9f8d59b0f9a977edbe72821b0d85c847f9120830d5b506e830a19a03df4aa4fa1de7c93d237e99b660875a25028140a55832bad8ef58c45e061be011df33561cbd0ee017bae39d3ec206ce489f59145318e23a9ec1142ea9c929488d47154a94a6e855dacb550f073b57a900b374de747b221af72d2b1dddc60bfe1bad15123d040086b0e1e3a22d034ae23819e711e1ae673d7f9a85a6185518676e27ed241142fc2ebb9ab1fe4018badd27185d7573f198ce3388ee3385e570d1528a59229c584086aa754723a7215e148bc896badf59215c287b8f9f1136ec4061a7a16fb8b8ed263033e680002dbaf827e72afdb0e158197c475a7c6832ac0a107ff93826b16c130003d2a5da552a9542a595b23f4b182529369753b462514ef755d2c2ca15333b78897e4f2b067b25c696a0b1fa92762a75eb2104ff53cb8036aea181e5c3f2f91c254c634454d2693a99e40d44a92e5ebb85bb783cb5ade9ecea853601d554ca1d28131de386d0a3c23145b955facc0627ec9c2c6831d8e500a8ba1971a60f1caf0b2048b311c80d6af069a3d50433b096faeb986fb7da09d84f55bc15361d1eb3e22f067838733c24c099c4307f4491e29a295003f797af0d64b02f2b390b72b14c81b9ddc2852a6e83c89e61ee7799224499224795d35700f1126241126b2bbb3ceb22ccbb24c0a07ba6bc2e17b9b841d8e8cd20f94153e9ee79ea184a29b5ab2acd600411908d10297f375bde0fe8944958a2442d14d36b250c846e0ea50c500080eb836290cdb68e0b1ca5bfe1da41b6e735296d910bd6063ae80715374a4d48ea4b247888e3dd924b66489849fa91d59cdda56f762ec7939836028f494d2cb0bd15014fdf0421e0b13d833cbcb711f98a8cc510e904d896ad4ef420e908da734e2c9329090115594463c58f644e3687f9891bd241adb22ec108b72c933f2f7a8568764c707ed4841375c21e602cae1d9b1b292735cf2ca97b3925b720e4b9651bd3acda1147ace096b761790e6dcf6e9724e0ecf0e973ce3cb99915d3e1a38f728c725d3c026954fcce1f4c901d57da20dc78386f64da0472ea01ecd9872b30cd4061ad6cf0606b8645f0be8078519594dd33444f40c2dcb233a0b7a648950a435605d526849672e130df3f9f244d1636b60c78eb9453aa67e57eb6299acd0eebc35d99114beafd81213987e383f6c18586cf3e6871d473a8ee368473b86f5a654bec5c465cce639cebe8481c57e02e4ad00e28811977dd019f046017bc6403cb8669b5da39a96fd014a53f46819759a8d701f298fb68f86e71e61370f9af77bd22cc0f75e1f3548911162f5125493f07307de65027f7ed087b756268c18b65ae5ce977b2f4bafe15c86e3388ee39274ccbb736e39950e24e2bcc6008d002e947580451f3fa1180a49ce43d770dce751b4cce71b8ea4c1ef3e97a26368a87d5e96b4c440f9ef5d89810b748d972e43c3e5cf16f09a2d7fa6a169b416ab9de01a2e53eab8da0758995d1e1db76929cfeeffae95e3f8abf1d3e273d9e6bb5ce3931d3bfed4f87c3a6ed340b563ee83dc83e30a40d45a315b310b002af08cfdec9b409b66c8b699e301d05371aeab063686b5f6b2172e71e05e620232c4b2e7a74df3ee8e5d1d0e232b39fe23f41bc21a7a156ab889562d485ce9f02af40097452c671983720b9feeea64c0fc13b90e33500ee1e59f58f3f6ddf061be40349c7b98cf5912d8e66be19b45d1a783a11fccb24face177307c7819592982455178896c3c0c58233472411882e3382ee7cf4745c64ade01c8387ac99d5d724bd6998157be729917508f3619a097fc0179cba7e3e35df8cc92678058be1ef28887cbbef21a11b4cc679719f9472f2b36bfad805eb20c900a885f5436caadf4c8c572d957befa924701957000298c4acee7c301c85683114f96731875c7ccf8d1c67d7806b843140f057a84734b969157f2966f68596d2e777b6e9101bab7e5e215efa2c16081d24858ad3c2e832151ce9d8d037444e066078fea590574298c73ff29dd2772b350bc95c9dff01f7a8696a4a6e9c65155852af543dc756ef62cd2abddb19a200ca267e8fbd03768e5618817f40dc2a6f1ec45150d856ed131d46c9a6adaf19a9ac4445b49764c74a6a292784d6de2325d9324e19fa087a84dde888ac52f51533fd22fefada82615559b5cd7a97bc61d46afd174681ace344410f4d4343f6ed1338fe4838ca7919ec60424000441a01452f8f154d69e9aaaa8d1666c4ad3383d62ecf3c7d17fc450972601a24b744c915a83f0082a3c8d271dc6204174580149891105a110405c25741883a800054200319ec6244e2f40d2848d0ba66a661cb78e11bd70aaa083b516afb0788deb0842a967169ec01f09bc0061d82a40c2046038c2e03ab88ceb8c54e772d2785d1876eb652d86a9986853ead4bbbbbb3f4702ee8cfbc3cf0a8f7cd499d6ca82ec89946cb56a619c1287cef4c595d65aff71b390c2a2af2ed18d274ca9b121464bd42d9e26e76a85d918f4f0d0d3c3c3e8299c9e6ef5e0ac56ab9567c3f3562b4ddbc14385094f7cd05a6b075e7c20c1627e5a6b39841449962b2749cc23aa26282524e9799ee7d119aab3e309c93478244a0025144956b4472b27d414249df1d6553eab758d17293c57d4ac2a3ad3de2354499e4ca5195a928eab91349246d2485a95ab7255ae4ad34fd2248f409e48484574828c438a189d8c41c62145ac56abd5494de7399a3facc6d509c6d8349d3a72498ebc7704d8cb28f8ca66a8cea7d0353448cbd0d01d466ff452892c91259205631ae487d2905211a5911c499324c91a42a10c8436e083070d3d42a150284492a927caeb254ae45484f49ef968d7f38f86f9ac7d62163e97826635ab594dd334da1d734ba552e95dc1cab2fbddeef77341462095600123e89a175c4648d35c3d3c55ae3b991052a74898f530cc285f28c153e04678145fc251a46b4631cd9b8186f92c468f934422e517722691346d070f179c4a77777777f7aede1ca5949abc887690144c24f426ed0799fbf943b52ccbb22caf4b8b5ad6b2a2ce28b5274935ab939aaa4c52a9542a954aa572ee546aa351c4094a52a32fe2c4893412c1100b5f60b1969563a10a7cb5b004ae496a595b50026399c6f5ff6421dcd6a2ad90b5907a98cf57fb52a48ff42454288a42b196f553dfe2add042287eaafc944d7d2af5292f371312944ca3ebab9ed37c7d34bad68f8528b85d86e690f3c341f4aba74e0b267c7d622d3b500e38a168f30d34cc58ca06a7b0c32e7767013c8ee3986b78d5fa7d8afb5ec9c37cd674c01555cb0759080277e832b496652dcbb2ac652d65144192e5ca4912f388aa094a094692368796e18ed13e5c75d0198c1f80379017587452c454872ac791cb95640c2d43438004e1cffca030ef425ce603ed76bb9f9bf513310c046088816878ae76c7e7a6af78d4ef668a1b5409b502149193c934dda04c138599a6699aa679af8d1b53860e7ad5cda3c70668e8a6d775b917b829752170a61fcd1887563ce86ab55aad78d47aba529038d01ff61867173dd0a104477eb0d65a104c65daf54e5afeb30603b30985301b1d5c8a7a201f6d1c8805284001c228078866c5c84d9e032a48ce491afe7d3e2f290c0cf7f9690c8c41e1ccf12948be388d72806c4c588dfa5d28401023ee5df80ce47918c268bb3ee0365d7cb5b68f9447da47c39a2c86ad5adb9349a8ce94a73bdb7d9bdfb66ddbb6bcdda6792c14efed981c83f79d7b3d3f315a5a71ba7165813fbb3cc1a2ef34cd969f07fc7da287bfe5a7b67d94480fa639e557f48d2cfa86155e6891c2c165ada67d626bd9d5b0ec6adfaf5ce673876a012d4183bfa24318117eeba4a413cfb2e8e797bfdabe5c6ddfafb45c7e6bcbb9d5e556abdad0228b89f9b39853df2a0974bed9b42ca3f289f77e3e11e3eee33e31b75a1c07d6e898908d9b8ed9c1e3069cfaf9171f4c96144b88c565064b904abd7492f4141c71c4e98b68bef32e84e5092c9fd862884159348bfd84e513fb0cc72c7379cb2fb0e4cf083080ca27e3dcd2322d9fd8397896ccf26d94a394858585858525b3b8cc7099f1c98d9f252443c60aa8c683a18eb121dac183860771721e7427722ae2a907959832be33a2d66aabbd31cd9badffa7c09e6f9ae69fc98366c7d4d4fc0c5a86e6b57833090ad5738305169dc6cdd987606b6cd3b80adc0c30962fe87234b016b4125e1f17e13379f0632c0ec2cfbf45cba85208038b7ebeea513553b106d488f5390163d96607c9086db6f92b963021e2a6693eabd7da0e862bd3c00f7e06b984b7090f839d5074d62545665d4e9e60dfd9d1988096b33c03368388c27c773842e7953dcfbccec3bc83713ae974d2e9a4d349a7934e279d7daef499fdc8e4fb890f8f74b9bb63185823e482c4464130c46303363616134ada41d0dddd6ff0d07bf0114f8e0ffdeb4f131004c15a59250a957a2245c9d9b38aa2e2426b8cbff4b07bf66299a6699af61d0e2c7f56bbcc65b15bee99cacd8cf33a508f34500db31e7da77d8ecaa080b32f14ca26ca35bfd84d09bb37a29f348d4816ba41a15028146adb68183b1b60ac29d87996251d3a9aa63b555452809df4b913bf441be91bb507e572a6046dd206ba59f4f30ec1dd24539c43601d55879f5ace3e1a375aa641811e693466c83ce20c00b0e234d241013aa91110da8339caf2075a4223d9870348619ef6608eb6ac65d1f3c126fac66e6c422ba1c15f3dc10b25241fc10ea7ea4b4c4cd5a952a2a4c7799ed8799ee779de7b73aed06064b15aa723534c52be54e4c717c2627dba4fd77517cbaac0a2b35827d64a7edc7d3eb9eb3e9f87f38ae7173d29fd0cf9e17c92c56ab1582d91889e8e3a4f2ae564b59a8613f2319a46628d45cf9375b2ce2d735974161774c5e4c1a74d5c8687929e22ab7f1485d1314d2a53ca4404f53bf74fceea4c2c16cbc462b1582cd655a38edbaf149165fe2b58e5d371db0a56f9749c870516a909cb70b295560aadeeee6b93650765d9b5f9db319fafc96432994c9a76a2678f55e7b8accd19e833c34d7df4394ef843d163a1891e9f50f44e9c448e1a7ae17b87492c7a5ae81e9d494015de0cbc2d3cd149abf644777787e82a1402c19cdbfd5d6afb1158f4540a0473f6ae86e323cd5d9645279908d08d1e0b23984b8c48b14003dc581c0109967b7a1eb4f91b7d39b67d46ba8fcb9a566d1c908d38fbbcc44ce025f0767531d40bac7181dfc5d00fd21c4225a1b761437ed5cf895d951281205523b50245adb56bfb05fab073dc0812518c2320da1045463c9e37202ea8afcb36713a91669323aa22292eca9e7b3a7912272fc36ac7dd8ed3a8f0b8ae0b39bf3714047a825fd0a61c271dfcf9860ff866b7375eb361b96e9f13d1beee98eb52b400bb0ccb1758ee220446084ae8c6bca75396ed18adb5d65a8b596b2db6c1808a2a701676a1e88516eb70703178775805d8731294babf2021438c9aa6691a160aa5f22766cffb7080bb58a5a0ca543e1df7659fdb5d16168c3d2f6710bcda6adb6a846c885eb0710087459bedde2d9ceeacd2dddd38c0526ec011515102a8e85bd7759f8822c5eade7bfb2f765d1fe63baff3c511a81110059cb45062b4b9d0e2240fd2329f7750e94174538ecbbc7773c4eedbb13bf7ee6022d1cd329ed389349b1c5115497151f69c4e2b1b9b3055390cc36c9aa63ba92801b2d1d3eb7ef423d2ab4c0394427802cbf7c222a27f813c9d5ab4568e0a6b4dd3344dd334e94c2804821e78c19013312851a31c200ad0190269c4e3194808053838473c5a1645d67e8f553162cff1bd9c7212e6eeee5cb6a00fb492d0039eb9bc7508702f412215f61224ca5026ec25488ce193e4c665ff9c84611223b9ce45b6c8d8ba2772022c3ee9650042dba3cb2d1fa8613cbb69e24fc5cd2fecbedc315e2a7925f16710be8b5baed7855d6e5a1b1bebeeeeee9fb5d7755dd7957178c92e19072fcfc88fe401a4977170c92f198719d9cba4fd8e86e7195eb24b9ec1cb335e5cf2f5edf0f20cda61cfe4cd57758c0a26f6e5931be80554432b096dcf0f7cb8c16867809e04b9cc7814280c7bc44bf2c12dba00038a49924f3ec992f1019062b3eeee16ffaabb6d60791865fd70d68f1387fe1d8e6a2ba537887af402ce0f51005a851911dd116a02d0ea23882602167fa2a1070fd66a87b53f4c2c168bc5fa11b2f1e1a1564abfd5067cd46bafa555cb5b7655bb691976dd5aedadf6baf7da22863ce6ee8e5dcc8235b831fcffde7b5d49ca2ccbb2b274f7a157d7d5ba4a4f728328fa0676c3d6ec701922f80f2e0dbab0fb6291893c51c64cc6fa86a57d03cb9e9b66a84a7778749e0daf2357b0539e1efef59fcb4d5c64714583249779d702085307a1cfb235e2943c4cd96a95996e19966559869ab68347c912c4da16ceea455d6932f03ea30116166d1b823ddb8cd3575f7d5191c5b0ac0a1004310631884bd6087a4813d137b24c81f01f7c6479211c08acc9215d7f307a66253fdda125238b0f454616df0832726733686615460d819587fc900a9272313e2b327056c99fccb29245af594dcea8edf0b18a505dcb5a11f075752c2cdb2643fb8cc8f872808cbabc8525217564393b060c7c84f0b38a11c2cf1f28210dd2cfa23b40216475cc93a592e82caf94eabe3f39f102d327e7833db0582c168b755d66ad6fadbd027fbc2458ec966a478808870b85df753c5b48bbce092c86b4f0e66f5c81b3f01ec1622806ec490cfebd3871d3c239b55aad560b27f582eeae5d5b2ab5f4a2f4ba905094124a92a5cd46391b6b6da8c03603010720ec254a9284b69b408f74ae6cb3d8ad1728e0ed72047001fe2e5aa1a396ece0e43d95dba8a0ff1f23def702fc9f93f02181c56ed510a769bc898ea9a23405141d128ca309383bea055224a2244992f43728176bca759ef8576e93fa5c8434112962e3505e08bd2e6e09ced12a702a7c65d246d3b4ce33d6c960f34b16d8412fa105d56e0277dd6bad09ca186a6e7930ec0e077e50088c57f0bc9bb13cc3fdb04c02338e89c88ba05bad6e75abd53af2048f154eeb3ccfd3da8eb91e93acadd553700267d75ed9fd687099bf9db59496e06cb55aad160e86854129a553f0f6ff5448ad6507b81a241403096fadfd2ec77605c6e1f770db82f3dcaec09e4bdcc39bf252447e9ee779f6b8ae2c0aa6b5d65a6badb5ed3838f7629c7316e1d0999c5bb9955bb9955bb975b3ad954195123aa71c209c12e48887cb40424490608d78b454a9d4342dd664537466465e59242bdb4412d65e3bd6644ba59bada6597b5df6ba2856b14aaf6bdbecc57da41691eb889ea12814132a1e1b2459b52c8acedc286090c242c5c406255bea9824d7674976b4452c59b2da05f9fdecc97e3ee29456ddaa944e415114652d2a8bac9106515e439f582788405116c5836dc1684b2b9bea9826e7ca96e8ca96ac2dd9922dd9922dd91286995e13ce28986952cfaf188f42dd7b31db11d1fd4cf4f32c014785f0ff47f03c8ce1192108660e1411423734b4dc619685e84cf9284eb4ccbce9cb0b9ffda8042e3b5ce9900000000001c31500001808088442a17048342295b7b23b14000d537442825e3e1b4a849124c9d114a30c328621028801408000c150892c2ddcd8ab999bd4543d9452a28be475855e6441efdf869a9c7eed04c8b24feead4d784bb5e98b0eb34645472f2c0aa6a5cb1e45c9525fbb94b0cb7f78143c9c394150da8d0fb07dd83214b014cbdbc732b77ac29132d9d931009fcd1a086ecfd58179be1a213dc83a3c45775a5bed482df17138484987626691f016730dcdd1047c6aaf9a6b54421a328c5e79562cbae5dd98150d7d18fea05a2d2282bd9da99e3b53515262afbb684310daadc2e33b5bc08160d9c1027a6e280a71d70e120f70c43c48f97d58de2761878cdd226f85980c9a9e93cd6f7ac287d8fa75c023f002e713c5b76ffd48b5ffd85062a200daaaf1e0711042b3a8126bc2c5640cf13778af074eaa29f81fd4e241a49165a50e9f539d751e5c906d684d935cf592db0d35020ed627c712ad834431c04ac64a13f7a72aebb6809974d250527c7c41f7f427597b5cab489f7c2631f34e88cf3ae4f42baf87af76ece5576c5bf0b49233e4484a6fcbc4d814942b2a9c99f313cd00d97a5482901a68aba5dcd569425b9da6c8512bda8a04f531448d64143806f621a0b7ea653ebb21fd1296bf63551cb58412662de6bc64232558eab703222b9166339d28217a538498d8c55f451fd8d1af76ed151e5d86b2ff932ffe56c4c59b4e0610aa12840804debdf5af4577aec948eb8fa239b7f47fc6f92f4f9f5753b41d7a0a1d653f6c4625c01e609eb15af69727ed58b9a14b2cf2b0ef42e4cfc1312b79cc6a86359867f18b96bee4cca441a7ba31888c4c3ca6784cd22a999a54e6700f6238f43715d7c03c7c9345e2eda3e80047325f9ecb2c8e083dc48427a206966e39142e75cc1cc5a3263331e9ca51639ae5996b82cc04e58f19ea44f3245cccf0ed4bf25b31ba3103ad980316cb264fe8bcc08934ceac860f64eefba4d5969aa5c18c1d7948e8424d9199def6ab0d9a1152cc7d11fc038e70364293e7f79e80d20d7d2f823710d1549f325459250e8157debd11b931e82c9662e4fd850176a1b6be3b6c7d3bdd29ac108fd47ef07dbf639aa9fb076792061d28b6dd82aa88d417f2c7bfd63498e3a1a9818731ccbb2b967def42f8bdac8fdd6c19703c113ab6ce9e2e2236205166a3a77f4f01d4239b635650920adc89154b0d635a23c631fe10436de96ce08af2ca3065bfa1789a704e79d6c8cde9cd1a1923d65fa01e373bf629356c1448bb36329877ad885d023c5b4dcac57a10659764699d3e2f7c2c3b128553b6913ac4f039d903de3a342227c0212916db8893c904313ff3b5a92336f6b21242afb37af5c72bfe908db124646186a3fb597694b6930f12dff4a139fbeebd09a57638f42aa3d5c33258f8565a29fa0915866561aa8e2da28c3761ad2884407cef8e13bbf490ecd17d5fb1be6bb9366b8fcf79418540bb930dae190e431c90dc9d81a97ff9f5328331a95eef4b243f6efc1e13c8af4d453ac47c1cad32f35a98afbdb4f5303d54434b73a45991f9ea0be154d7fe48a9634fc5f5104fba3e8209aa723ade8f9ca96ca9c2bb4515f1128312160e910cb9249ee7b93b105d91834d27c25afd9ec80ca7d056b381a4309e6d30d258f92cf6059eefefa98d76324424840a08b839113193246ca59d296b6819e6765a3480dd053fa0bfa54a876a85bb1bbe512c7c105c9499d51b7c7bffb46680060d06dfc18a9dd4b735a6366b41a07c84124ea9415ba8dbfc6fd31553f857b0423e67d215f3b52a113bf8348f4c407199978f5ceb1a625dfbbd65e570d5485b6eaf5a58597b2103a2b9092ac094289327835c09a18acdb282964aad6e6e65be42ab39e767c9349b9fc89f96a4599b857c6ccb6f70d3b8f260017f8b9bc50ffaaaf705bec76082e2d52cf42ce46832193772ed946c0d51f87d935ec9517a2a1dd450760926bd0cf24167426b79cab2e456a44583a3a89de85bada3cb5f48f567504b26db24e66c26e00e01529e90cb19c29375688e776d1f7397e4739dbe1ca563ad4db46de9be29db682dc5068e5d8b1f1c944094d5fbfc52d08e9886a38b2983efb848a4ba6dd9e4ab1a3c6b5bbb713cc4bb07a21f13f378c9546447b40b9d5c3764295d85368a96637e3cab8bdab6fbe0f8bec7eda54bc205bc2d75953d535cf8a21d3b812a47eb8c76f51bfea362c45f6c87640d79d2bdbe392530fd0d22233d802a058b8040a129f1b7f229457e0ed2aee6a385afdf7cb0fe457e1d320bb0a90068c6b9f39cddd8cb0c7740ce68d61e094cd3358ed99fd5293a661d13250147381caf90ac58f5bb87ef6cbb67aab2e7156537593eab8f1db81a2d33f5d87d3d1046075ac7858f336c9e4f54b03065585d57298ea3d6a206b5db8de10eaf2ea6159684182c1bd447c407aa4024149f67dc69612c511fe0413d63cafbe347419a88e88922a901567780a0174a07ed577dd760886414ad95eab06d2f1b01adc55728ba22793c45c155e69bd6a40fdec8068107cb9e9e97518ffaec2545a5c3074c384f3bf7e14c80a691c69f272ff146ad861432a21a8cda43a420e1f26bd1357e29e1bd50630cda39d6c6d58ae035c4ad6120430a39c3d2d08b882463e094073fab43fb2905a94cf4a50e6eca31c4b0493857b59174a84afff3f07af2e9371857c2c53c523a93d180eb59cfc3e1b56f35a5ae0e377840be332dcf11f26041cd29ca979a20e84c27b2ed612a9d4bc3f00f5c4fdd6e8fd801bfa3c0ebf2f7e28c4f406a5f472558a880c2568dc266fe86f51c9b9e22e62df55e1b0ed003f5ab3533641e6f0d7842bd1b0776a6cdd7d63b21185e4f96ef84ccff8611ee89aca01daff09e941101c89de345514507acf9635494e88e928b08ee93bd14951b00416b84d0eb61b10c1d2f73087724c45d8cdb374b85bb35c2dc3fecd85a230860b1093419bfd64dbf293284571adfb27bf951c70ac945e9a5f6b54e7917e025f16b1204595ea3fedae44f196ee001af608028511be53e9f613e9c844dda4741ef94333cdbef91f0f16ba810baa132ae82c70597166c28dcfe3f0d9f3bc01f78f62ea20a0d6358d00e15e32783a88277903fd06f672cfbd3acecf5d7f29bab88ea85b3498e12827d984e489f360583fbdaaecfa6a6714aa7d21c8f23334f281ba678af6733400fe9d11e5e25d0d1ad1497716a3587a749076624f81178015bf47cf0106e6818b828ba65a2a287ab12398b605e17f4e97576db31c709d88e8a5585b6a1bb512e628e73731fa8d754677cf6ccd9e9950874337f880ad364826df075a46ee444ec74cea06b678132e273041644d8966a8f6368390a121b8528966239f2ec58e798a9fa2b0a8b5e04d9488fce37bce285e27b803237a5c45d382ffafbb3a0be967a2b126917e219cb090a06de48a5adfd84f623b681742e860197dabc1f004109972f51651c495bb32c0c4a9b93eb99a331cfe8cfdcd4df2eb753ba9c34715886ea2f07814b2a7e633e0bf1fd49e6585e0e07e68dfd1051ac0d928acc8a21dfc91331f8472792227d6d9102c800f8f1fa35dacf9cf3a57122b5ccfb86489c049f2c6d27908adbdc1d3aaa36f1d4157d311ff0003f7c2baa78e4f4864161eef5ca101c97eee9caebae37532cbc6b034f320ee1780e3c626cab2df674bc978ddeb801cf5232133ff18bd52044ccd9ff0912177a1cb610924c1ba15a2d31a35b428223c89d55a2227e2dbcc2afe5c4f835d8e658dd92403a8730d87b9f851d70f8a6668efb1aa091b3ae5b9cb75b99173432730ce5e2e6ed66c972bd3085200b8bcfc257aa77cc964f483df88c311b89b2d19606fa6dc3b7953ecfdca90afcb81924870dfba42edeabda6b7898530583e060c6f27164cb67b094a2e3f60838c84afd8e95a5af628822719b919b1f0eca7a68046ae16bc17940aba218da2401ef4ae03d0ccd018e2808d15a6b5a0718b24e6d4014e303f3826ced880eff2f206ebfbaabfaf8588c3c2e623f2f51bf1cea41e7e4c7a13974921a5f42b346b01759346773c6e704e313999fc3e198dabd2bfc8935e5307991f1253156dc2a2c9c516f3b0d8e8871bac88740b3f477356c2160cdfa29863121b5d6dcb917415dd70bf50691224a16809f09b104b0ffaa0e0652c28484274c198be2d0e36a948f873f36c03133caf074bab48916619934d17319b20367ace9ced6e2505ceee5aacaba9241ac2fa4d5a228ce9a7192fa2b7b2de3581f858b11ee84746dc640b9d31403ccbc34194c1d59d2360cd937da21bf0e4267503cdb2e8872c9554f209116b6c60c7d0b15f0e2c2f854088734cf646a874709f241d82ca9c0e6c1ec9d90be5d7cfba4761d64520719a94ead7fed8f17e085c0dd17115862d334067be0b9b8e4242daf953f16b8c9cf1108a940b2788d7138ce0e281b20a4353b231744df56a1cb8c97af32eece387a3340096528af1d160b6bc4d2a1354adc74e520ccf3cac1841c0662c122b12ae26ace04351ca9657dffd66dbc59bc0434e5e4ea63b1a0a49fc7bc3034b8c780fe46a50c7f8c90dd1794df8c3233b61750f470c31005a899268ac887146ad8c11e16df532592c70cab5459eb768ac26a80808ad4d0e3711c2acfdb21a80982b5ee83354b2846450aa51cf16c798327094c5ffa98a28266571992ee3929c06432fe51fa14ef291452e77c8c32e18de83a195d1cedcb151281454849890fb730ab7642ea139bcd3c9a329a11fc002aef36f923ecb0c664112d8a557dfda6eb513d98fb5b6e2254d1364a788197055c422ca8fc1fc917d038c170dd88d7a7bd2d9a1909e1dff0695f854635fc37cf9f03a066a6f8674b48ec80253b1b33eee4cdbc32e8cf5c7663b06942f0103495ef4181f79c00b83240b5d7fb635d31a19db5ad1533d78ad5eb7f5031e779ffbfd13b46aa49088b8004b6d7ae3a15b8644931ba55e535998fc83cc252b1d1ae62eb713e6f94c492a2d9fd6103a2b9d77e78fa7588ca6c6b4c91b26a3ec974954fcdbd4d362ec644b2bd68a7bd4ac95343f73d898f26ee3c1c358fa5bc574b24ba47094304be79cb4da72e345b8f33678a04129f6652e3971ff22047e77706ed21b38e44113a1f8a347582dbc64bc4dcdab25067118a38c438ed952a323a9f83a3c375d5c5d75544f0432c7d416fa6d0919403ca69756272566d0fe9052e013dbc2b5287add033ac768518eeeadcb7faf3ec4b9abeb7538e2b836f5530a2fe436a1314ba486c41bbebebc2fe6ac95e0f6d7e9ad1065c1793100f255eafbc923186230c96ba9f2afe0f8555935a54a542bc54c457755002bd6c969ae0006003a0f2b73782b98681d45941b3c5d1f512126f253e1a1a03f249e0a9b59d8c169ba8ce5caf66cb16c74fec5e74c46097c3baf86302acaf298b6434926e9d337b30e5247364e981e2250fc4d6f2a4e5af3a59ebc51bd6382e86f35831ad7ca7ba4b6a95c1cfe746325ab5569f2561fe53156622ebf91d08a3c377fb6425bd6b710613937c0436c4ec796cc1c23c032cb9fd4d8ceaf6122abc18169e34e098331872e81a7caddb273a6af965b56efa1bed756313a8f8ee8647f24909599c4a2196542a0f96685b840e6daf1848b4b1fd9393409d76229d402340a325f6b1ce00297cc4680b79fbdad7c8bbd341cae7c95b92c1024ec2eb6f4976f669099f0a4177828589554a1e6dc8d9f47b9164aff79661a1e11fdd1e310d2933b224bb08ff5a86250b04c7f6653a0ab6ac9b1e93b9fea3ed7b3ac9c76112fc240ca3b78319fc140efdf24770d3f4306d6a33b1a49bba76db61c478be52fa4cf948fc51a6a587b9a27288a5ce44d857c3f047db005c13235bb79019d1fc894db43914083c9c90a2cbe950491fc22a5fee2805ca40da169e83fc1e6b82f5e459abb1dd35e1d6600c3b4d00f973c77325b9405b270ff2f55ebf047aacd26df7c2139698ec5bebb31c9037c183f299d70e35e8340072f4256dfa56d93a14b9c851f40e9b94b89790533a4a808beae3c3b83d08d105656073183c34f863b8f48768bebe057e55cb5be67a04f0e2d7ea5a99725de18ccb1477a74fc87ccba2915a16a593d49cc52687254b5ada3b15f61f9cb721bf1cf4bad678c2cc2b343893f9f0cdfb6566b0a14623f601185b809f957855b7a6f7a6a6544aa9456d3e85da043b47521f0b60e7505b0c335a73b5fe20d9301c668a083dcc442d65dedcd77386ef481be2c844d4ae8cda706627c9598a6854c3c77a6e04647e320dd7e887a1b8466f188c363fc31f9fc94170fe55b210d6b80741c1fc746c954dd99d836399066470e0fd938428a7e1780e1f4be40426d1f529d7626584d6934be930bb74393fe6801716ea34919cd327c5849e2da71ee143b1b134cfbf12ba1cb60ad5a49a9d80e72c4de474537bb21d27e0612532e872e90de18a426b08ead20b64bb0086325754a02e74b95cb9a45dba963f10b630d5a15a6e4c09581100aa30b33093c4098fa8214362fb676e06ea4cff1310b4d694b05b760519e5570fb1e522ff088cd2aa1cb3731797f6df1503a4bc0a7857f9086747f6de797278dc203b5f463c6b8133217dde9d1fa50e6cb98ae2b6902e727512fa332c0735b6dcefb3e6144c3756e2c69835c79b29fc05a15140271d86d973cbbd5005eaee72d9724048ca0b05bf6839488fa1e5002d715a943d2820a65f1a58e2352b55fb99f9b5f4e492a12e4c3b0ba06648350b0f240e0ac455abecb750644ec9064f7ce55073192d2ece691d217c3507705d6c7c61524719e9ca3222f1b8475912e4ee159ceb3b798abe032330945a539458135c6ab713e67c7184f0260702683d2a8e4c0b13ec223d61b9bd01823603a25724e2d174eb60681b8bde11de521de241c8dff470f782bf55abf5128ee0d3902cb002c74c5cae10e76271d6d81fd0475ecf48e551628ac9485143393589e85878c1374c6f24e2247285330b599a56670381222b54e57d3c1f38eb00e8dbe5e7046f808477978bf0ada4a7bb7be62b1c9aae02bb7934731c3be8c964805f3287b46a2ee216e66d914b916b130d063616a6eb1fa44d004bdabbe70860859c9675f89fd5978a6a7d601a8a0c6c1fae93419903aa3839e24ed43ecd44a80df420364e7ebe333a295f95328ae6f9a3fcd908345ad595069bd72be9058b281f33e45bf519c5f1714fd39b82e473a66ae4098982c6b7cbbfb7b30d949e94624affc426e449b924d16cb8827a640bc76e18b170fa8cb6548eba488d5fcd4de90ebf8437427ecb2906e65b061d303a29e66dc3fb44902e69ab1836a86207e35841309926d3dcf3a3e6b5908c1f1521f4fb9c34bcdc203d796a8b0be8a385b92addd0a36b247beeb210c0eb8ebc2f48770fd299055864fcc5fed0f37d0b0c8992b6c29d2c3af021779503ed1aa89ed2c3095c43e2860e50491439c463b290a7138035f51df94be4576dfed226544362c6aba12f8b37837952208bb260300e83525abbcba683344af6f7c164c19a472ebe85f68c54264fa30114a9f12395e88ef9966dd6f0ab5d1d3bfea1e8f8e36196769a885f841a27980dd7f47c0ccadf58434f82ca748728cb91a525f466290c34993462d9a71e7a47f0e5bc3b2303be19588d96e1b89b8ce24a114da4334ece8466647034c093855ac8539f141cfd72e89a0de523cd72f2cc65bc1ce9997dcb7291c4424ac7c4e6c2e1a5982d36c6279fc3cf437dd149b5971db863aa414fcd673c84b159828a1e9fc66412c90a70036c181425d6697b84515b11df40700f9d857f1026f711c71ee06e94e86c476ce1cc6cd1b81cb8c69ff05a416933e06d6d3cd18761cee8060dac5cbdde9d9f067b4d622f39e8d3f4c221f343f8c1ecaf2c6d5b9287ce4dd85e43a99148aadbcba7ad20fcbca2908c27a0742b821aa2fa84ba5df63795b17ab7a7598b87fb9b728bac19576f6d9a940b44b964924d82e765fa33ad33924e0db10393f5c19985a36f3c0faa42717072f9e2d9a34e048004167c9dd0ed4f679cc12158d91466e08be8b694994c934acd82e7d452a9cc2b4408b084341a74443863cb6713d2d378627414eeac776fbb3cd793d76ab71abfefdfca86eda324276ce779afd6bb02eb8a6a8f232c0452273f73bad5729877460ebdf9a663ccc4f27e7f559375d252d37a0519b1fff036b77863480d83f0a2b529506d045422c94951b18b221a269be1d92846dc607d0da70589fcbe88f9785c6e60c62f37a940f889d7875266054b07a596cab30915957ea5f201e44ac5595279d2cc7e1565572481f395b24b2bb880e722e3d738a166a4f213a06ba7dd128e1580a5893eab2614b3fbf6d6db963071358cd20bb2547aadf04537d228fc6d1a72baaf4ec38c905c04a770f0b236433df01584455731321862ca75d60ee4b5fd7f5ac9ed4380ac7d113bfda8f65de0d5918109bcf810a3b401340879b4f4e9571b2f5c1c9fb1a71fec99ee75747f6b6efe9a9460c001ecdd2a5ea819ac85a6e5dd8886937de53d55d81ee982bb5d682b3c0e921d8ddc94d7122499950407d112d03d8c9310e6cb3f58e7d31a90e47a6d7a729fbc425871ab26da749446f36b70c8838088a34c3dbf02748996daf5b45adcf85e57a88049c85b9e71f2147ca5dc3a8d2e6a1f84b68bea956fa149ecbd97b822d50913f41f6902d4c58823d9e3ffd03a911d04ea493690bd0d4065028fddd9c3088edd487b5887f8588cbf8b70d88a160cb90aa62536b6334c5dc5001b3e4485dfd4b8de407b1537299bcf6c36492d7b03762e3122d59d2fa0a610e8d4067a0bcb816417b52b34ef41807b65fbe7545ad51f11a82b4a395f498bd87b90915b19d7e1ecba217de937d3f68f85b0e23ca03438a623811b25505499286c3d6bce49b3bb4fc701d5f45d9cbe229b17ec6b901214eea6c5bc2b28e8695a111e9c8e25360b9dd536b29193ee9683ec8101c3d02276b85d7bedc25022a0ee8a5feebe209e568e868b66ab75febe44352b82e8b6155517c89c4442f265a25c38466a0fcba093ca29c4779b4a8886083a39ce39c6d6c836476ca3d497a43c7fc9621e5eee377f5b295b9aa40c0592f460388ba129eb18683a861b447f8085f42df80a4e58f068ed7df32af9078671d953e839581a456cca4d034aa923db9bd42b0723c46198a237c0d18cd6a6481e08edab6fa438b4743cb2474486e4b8035ad6fcc4530c03068da1c04d62c472b823f2f11d7a5e6007c84b2a93c9699e6696c29ae5d0a4937b17d0f4344053f481183087c2bab8fdc5b87fa62873cd53811d911e598ef194408376707b8946030aaf60689f790ee014b8de67dee1ddccfd149e469a9644a4a996b2f8a7a8d8ac4437209bc8df37ecf054c9fdcf2eb5c7cf87d2e477a9a540286e6d821e898f2ff22d5bf63bdf879db340f9dab9ddcf984a0d53f1bdae520ce76cbd19d5efcdf1ed36dfc1259aa6c202494bc4e02f60db1e8cac542162ad04efc1b77b4db45a73604514e3519e65224ac4ca4fcc4156680bc0a7804ba455c8f673070a4c3fe00b02d5ebf47598a635a18099c18da48e3c5fea6421b6711e9d211b437ac2ad60ada11d3968a7e729f6850e60a06c13cf2db1d17cbb4ffe5905a41f877bf454a24909238447cb2ff6f60497aec953c884b35fa82c4496896c765fecfce8a2e94f8d4fa7160d356a1538a0d87e80538f9f0185c38342c8e0b5a7553432ef4185b06dbde434887f6b2f9dee6d0e8bc59a458d226ed979d86a342b2b331133b72d4e89dcc152da2a6952ca3f67ca0b678d34b77dfca91654d5b45e3177b9f2888c8760ad99e99bf2a21a05dec8a82e574b1cb8aec136f8d9c58e1d921cbed385fd5ca04cd98b20440415916e30f2d38c211a2d4bb96e82191f7085c495f65fc599f30628ed0426078bb8fc2a81eb485213d6b9b8e3ef5ebe8d3dd2d2575a11597e50e26f7d32a4c50a9fc762a95f55d07b189f4039af12e4f3afb5d1bf642568007b70d96e9e93433b306dbf826f8340fe257444366729197fca98c1422e64943d46fa4f36db1e819c3096b59e9b24ac4e0e4940943f6599fabeefebdc6d14eb9165edb05f330ac5b6c0e27d17fa953c96a2fe53908b8d88c4cf76a18a8fac1641b9172768f611a7d3c904c7d0dd0a0f7f732dcf78983d1f7debefca4b0695f1c3955a3ea6bd61561a01286eaa89249ce4329ddcdb6bc11835d5b09b4072d14d2b1f75addb4a908b39fc3ba179c6c23d89688d4a374e8fc4a44bd846400cd0e57fe0ac52c3da024e82b94c3cdb084685e028256418cd8d57430617c9c14884bf877dd871c74ae9498bcbfb9173d38722f84602a18575e2f4185f5bdf44c44ae305019471ea44061d52c08564f9259d3d73d328a636ebe6132ccb7e8d6b6841c1aa00c93f177c4a270b52e3579bacb8c37d4badaaabfaa7758afdc594a2d09cdc02f66d89f03c780e3a001b8847aaa2831d97c6cffdefaff8eecde42659dce336870af544a12a0b1d58af12e5886ea048a275e4a25cc01c98d8b66f2fa2b5c774aa18528259788466897d323c54ad109d97f05763c8e2e1c2ccb7bf7fc0ce200cf596c6b8e28ba55666e0eab2e3fdfb6d5ad00dbd1ea6773fc56cea76d806a02ee0d8cdb632039137e56347d69e18b46715a5f4809f6200ebeeb8dff6f6838acfeb260657f58ecc0e0c5e6a6884bba4126c68485ba31f37343ac04e89e863c893f129f3e92a14acb844976f6175c01472b24c56d270116c7a72306c070b99b18822656006d40253b1a7428fc5b990b717c568bd05cc7b11f1c13b9c2907ce224bd32ec89aa9c891999dd2526d9addf0734c78465186b42accea6778b5f06dbc507b27886c515172a13e991a915e7c7f95d181b30d20a864f7b7c3d8614c6dda8e1475be097025355c8a49d671d9b46723200eb0a9658b803676ffd2d575841afd2336ebfc1f53ef211d4043bcb34fe88c06aa0c446706b8b3b2283671eb71f9568e39e1215ff4372088d534564fd3322fd25554710dc387b47f44bc4fab8e1b6c707e9980d9ff268ea72f0e2afb2f0bb70090cd1b0c94b3d61031d64e7d23110b6a846b26cec0b5560eba1d02c03e54320f19aecf6aac4aac952585b8601800acb40271a67fe84c7c317b3214d8ab36dc2728a8135a780278e48de7475467bb39e9b7343ec8f8d08ae9532e8800400c6089778d57e0a12a7cacd0a7dc5b5f880e7854073ff2109118c9dc04445ac2f0e7ff78b4a559008c6ee1b841a88c8d906b00ee5acf97466ec723495241af1ecaa9fe5b87a7427bb9356bf05137f80345092d3fc339b623a826e6d2f28213c83dd1b95032fe22bc7f2687b2c88380ac3ec67ef491b7dc6013b1ed877371b72028ab0a506ee4d36250438335c1f7f3cef52435f7f7ec7495431a1644f5863e4d1a4250d60aa2b5536cfaf7de04c51abd4de05ab98d7869d64df4242174ccda7d22ac7322379e4d19305697244e5124495030241406573cd425cc4ee9bd4d57c033f277ffaae35fa1096f3d96e4eaf36dd302bbcb80f64ea5c4a7978dcb8de06b1824c9cef5a7c72d741f6609c0c572b2a65953f24f71cd42bfc7d29a019767b7b5885e1485bc31a8ae30148020032cf944c79cfd3b100d76ff7c99ad6641b161f3432ca1d70c5db91064f52f86f977e71b5b5f489167e5ec635081fe9584180a5dd21855e35b95e53ad4f8d6b372ab4a9a39a6abfa482a2d19256d5f63b837c4f3188bad3785f4514d00a699850f37fcf53708d2a0c06915286d87adf1f5bf8d355063c7d605860e73e537f15f4806dc6bc08d1093b77a6025beb459624ed64e539ed31e95e8ca5ca440c5c5193455a43012b7885cad713249cb47ce2846c0283a0c490e6880c57beaeecdd5103e99851790f4011afa5f325e235877a5a0bfa96d38f535810f688019782d41a36f358e4265466a0468721eecd40f8193352c4f6aa20432475984255634430b6663022534997844970e1ef01bc69f4f63f2814369d2f745cd6dbb6089657f6eec3d081850cd36827b73b8fc911951ad2b761d81dad57462aedb1102365ad864f5b7559b924e0c086b05d425cf2bf8d36d99cb56add289899f8a7153e27c6a266128fbb88abbb8ee24c4f8f455645177cb1c9fafb5a549f95cfe69970c3f9771e732adce75ec10b16acb8b716e0f22481889b92b846525942a72ba408a11c751b59aa81c7504123e09a4162c554dfc0911ba01c62e4434b542c78fbc35f576520ec9d2115e4e4d5a7369eb72326276a29a5856c96ce2a86635025b70f0ae0d84f92d5a8442bd4d8c797b71d9f2df80ec33f2f8f36823d38a39bf37b77ad434e09704aab409291dfda2a8c01775820ab32aa38020b453c68d7bf2b9dca0401d51182d56bae2b78bfb411ec771ef526ed0323de1777690c47c9a20566f74d9e86f03b33a4613e80c45f1e0c341fa127e0e68d36d3a2846c5b4e944a2da195f784658acea1e9134be42dbea2206f4555bf142020aa876930b272764283095da7fe21ff07c27489516d9dd280c12ab7184c3c55df743977c669580e6703b0f98bf269730b4036ffd27bb32df59e6c8f996f539c046f880a99f85b2602917da7059fe718875de643ffce75a9400f7363574b9cbd3223d7d718cb7d2ec3f3e9fd3582dc4180ea186ede1831c07fe295a4c5288239fbae18ed1d11deab78d40c1217e6bb663fb742dbfd620eb36950a025045a1296f1c8cc58d69f6e99aa882101be12048017edc87860a4a9e53dfab05ab783ae6ea58b237d364f0e1e9c5871484c94ec394d6cbf4da1d54ddf72c08ddfb9f4f0ff393c5ad830534777bb1d4f4cde55f3659a8837f459e5d729ae3184105352b3e69d8fe44131ce64e0cec3808685f7ac4fcd40684646025b97caefd5464f295e8f4e682a74202773e3b15dc9c2cd7eee918a94fc7c454ec9b789291769d0d32ead9070df8284ecf81f0cf91b56f2e79871bb100839c550e1cae97a346dd6c62afdf4edd7e810bd910e48f717c159f6765a5bd2f3d601cf63427009544f0fa6abed4c316d45f10e50afdd501d33afa9e105a6e4a01e5d6c9dcdf274e015b7f9f008a259974f18b9e4d54aab50c16ad33831590e00c96f9d6af6e3c016f14a652b44a327787dbe7d3ac986e84da957cb4aff994b940a922e81ba2eac0b8f4be962e3ba8d554dff58e8b897ec40d0c8f4a680cb11a228bf3105e32617b096bf67b319b64cac1d4c2f74445371329a21c6d403f65529de61419a800c9b0247fcd3cd8f96dbbdcafd730657e651519359cc2bb5b08d98f819158ca983629e2239cc82d13e46631162cfbe46262b1c7dada16f2c36d9b0c520ba9059e92a496226f9736c94c39d266c98530f51b2ae9cc0f3a633011e2d730a6a22563b272306dc398d5e52ac580310883bb690595d3957542b4ed3a711dd780585f5982df60fa42d3aece90db5fadd375f12e988d65ee80b90083614da7298a8bc39ff1d9d918a65f16ddfe890ee74db420f8964ac240c120e59d942b0eff6f9271b56b23cba943efd4d439fc41da041294b8f263f3ecfc14298cce3b6b22fc6365067143721287443c2b33ecc42ac551b30a3f5f00a75410a94698a6f9a87829e8de2d9c6b2564e118ada4c223d8f44b0cbf3f934942d02a4d4d0511a99c530618cf69b5c9359f826644addd9270d0675e06fc5d1ec8bc2e480762caf181a47ab0dc13a95462d5cfb93c3150bce59c9231b7ed5034e647ef9d4b21b960d0d6a898bc528551ce0fc3a027ffbc48bb6de3167f2a0a4e9b34498774b8f03c032f46591f1e5b8e8900d1bc41b404b1b756afce3c3136dfda82d4cc1a5cd7b319a2b314c33790d4b9ac47c22083743da1428b803910891909bc200536fc5ce2b45df325e0facb0864356634716975bbaa784408a06219900948d87d54e7208ae128e29792e4ea8fd560097330308a7e8ef08225629fd84ca6f0a92e96c2178e5184aba21dcf7669ea49a2722e93145ea34e90816ca4306fbc759641a882854e50d0a4173a06cb1d40bbb4af82e278933a5030d220bbb944100b3824a05507ad6dae71861c8d38cd42d68c62c7ec37be50611861950bf32661865fba32df5c787b951a86f8d775ca81cf594534503a4d36b76e495251a8855801b0d734579b0f8bf4725a16508503bd16f46afbbfd8a31fad25ee017ce43b32651569f5b26d3bd9e4db1354910b8cf51e40040709681115b9a05d8c582ada63aa48b8ad53f186f716852eddd94ca08a40aaceefb10a4515d9930277a5f10a19cadad1eb3e9f5930cbcb2879ce29c67a6e08fffc77968e454646ceac21dfa2704590027552259af8edfbf5c4bba74853c5abea7f7b512872d2c338a0bed9bd85de5a6b982f51d10903e204afdd090ac23e4391db273bfa630750ce748308c5428873b92858a481e771b90ace55c5de1c6ecd36def60e73e43491c9f4c787889a619d90a82298e3b0969a88a03ac0cedc5344acbfae1d3d1b2313084a2da8f87ba1d6f82dc2de50c66cb43c0291c5c8cc0e7ec135534e3e26ed040915622d22c39f7dcc0a26f137b6daf65acb96aa95ff2b50a6c7ffe7f2ab0954ed6e923f1809f872857f44e54c264ed7732d28376d9d4a1a055007fa10fb923b28d259eafc47a89e9756ed4357708067e0f6de7c969dd6200818def3bf5c421dab786992512a3939f467494737d48d0c0d9c79a78b7af3c2252418475ee41573d6fc47c9a1801ec50ca36862b1fe984b313fc083b0d0f9be92476e760416115bbd4bd87da197e1cd83874cda87c0797136c5e0a578e55d7e71d8aab97ffaf2286a834db791270e217c0d9fd5f706db36e8f24d481e821f17ef33dd99797e3674fa560b28a1f38af89d1312020f17f146a36c1d23dad75c23992c613a9124d3e5545cfbd3051b91e55db54b1b40bd43a3f8fd9493dd1e3d5f6e48ed5a29bf429a614671f9bdf410479363bf5e4a7ffeb86d3e013628fcf8baba271c94e1bf6e1f16da3d772b39d75304b746201a950052c08f9e7d04828e86847d186aa1335601ad0204e836bd51adb0345e22508484b6cd3cdc9c0950916e318c33b0e74e7f0de57678c8e712b1c49ba01e7238a15686ecc70963a38636c5631ec7df0b59b85d593f2817ecd8a432bf6cc6caf9a9729d7ec93af35ea781b68ae94b550133c35b7da0c8e0f8f4b0b2ea4eea7dba7d39568f2acbf999916ef77f3d9de4ed73c38969bd3675a10c04c9c8902210671f88711973785f216f81b6be9043ca3144faa6767232edb5f6bfa7963ca3d1c9f3d5d81b28ae4d5cef5e22275433f5b4ad917a7f211bd0cb08b0ca7663a2153329423139edd4443597871300b00019ab45225fcc210cff1104660cf48339124969758af975e8a5e7cda4d37e4603270c6985d5facb53334a215b520a61802926db529552da0df2c0a1d2463628b36857e1e1d94813e212d98c984013b66246fff8bb094a59fe4bab6ae159bdc900ad4268d2cc7465d74fa49cbe73cf8261180d1c5b71f0ed938ae74eeba71cdc19a4a5dc0028ec16553fba0bedba34897f73a25aac2a8b7c79fe2a7e287395812d434c3bdbab6b0a81441d6495ff76dfbb55319af7c93cb4b6e9257b095d2c008844dacb0825f6022fde172b29b9cafb5e2b7e622c789d22eb73eb78461043a173e2b933e28fa50ab224578da1dbd6fba8d219dcb0fc7d15a2c1acefdc32a07dae30f0177b15265ec84bf153da268cc814640642cf9224341849e9cdae095a95328ca43743242924f9c1c61e924c9b38e117ad34c2d78e90c5fef223119947ffae2460a98ffda68add68482ef2a462689a320894dc1ca21505b993ede407aa849cda1d073298c966dcbfd935170382c4d38eb7a72f533645919c6a71a48628a91a831da57ec9c9b76225a00a47dd99ff7b93046e2f6240cddbba497e997091b103c0e144aa447641422b238adde70758c94311ed098c55ea92b407569cb365a8563e40474d7fa959dab10cf06a34392bab28821b43e00614fed85356c3a1aaa55bcf61260f3bb43e93d97394845a885e55a0be27988c2c48ae0737fd175fb38598c3463c62018ea43c5272098b73249ef7c4befe1448e86384c893accd48514f76da6e391d2a91e7cf669eeed8971b22cf808d0e20213299cff0f6f5860071ef14a431ca3c91dcbd96acf168933efaceee2b411c3a05215e3f23725e70a63ca02945f908726579ca97a85d468d75945e883d9106a53dd93265564431b5747abe0e48d0cf96782189dd99e06ae73e4fd26982f595c6ecb4dbf3507304c1a5511a345be9049f10fe5390c22dd52d2aacef0235a87d1c5cd7a8da2825b12d2e9bc54b91b6dd1857f9c7963d8b58f6c18e05c073a3224ca1d117885691f9458d3f292e54dc6fbe542aa982b9746f1788e8e0a318e7b0e24c458a7d2389646df1fa468e8a4f0c275e5949e5535237c57a8ba7699316ceb1d407f199ac0893679398916ef827ee280f3b6e8c027bc8029ae130d35de8f4ea640802cbb44baf51c8c9ad262720902dd02424ff5abf0ae738b83fc0df9eb46d4e17ea60b3b887a273aab899a30a0827ca0f79e0b8bc65829edfe9119cc504a7c2a691d102e74efc41000a039c7ffd13d6267262f82b4c85cd8986f274dee642e56e0009e97e887ca37137e0213be7c5c6d16f771ecd40f15f69e95ecfa5234cfee5a426aae4cacba826f1fd7bff17633cd826251768fb6b06f0dd44f50c599497a60015dee1f1ba9c3c16d5e3b7cdbed23ad6d7bac65004cf4f9613977563f6aca206135003781de7617aa53590432a14a841c10fa17d3b7009dd31b0150058d569b0d735430ca428c4a00e98d7fcda98d9afad85c07966b9d0374b0c38453bbc5c36c331a3337a0bbf23730783a31f860fd166eeec27db2eb80834f5b84625e345207427fc3d84633141c661b4489054fe0969d61408c6162f6f513c8160516b1aea89ed26516407d5605e6ecf9d77044c1da1e63ba72d49aa19b49f1e4844c70e0e212ff9467ea48b4a5d0760521d03af1081b83fb61ff05c664034c70e4a230ef8236b00ae89c80e62a7051c911d088c2abd88ec8033522a68fb87db47dbb1d03ea16cf1c1c9273d99ee14c80ed27da91d1d341b0c78d00e1e36723b956a09d4ee7f2eaf586707aa9b7e44ba615d7763ddc85fb3dea804fda11ffe45b0703aae2efd40b27e5fd01f7096f3dd9575d2325397c3e0e09bfc5308ac41b21ed448b10a32823f2614ec147dd003f97857224a761bfd7c87fc01271dbefd6b8b63831746132883b6c432b878881d462f8c64b907fe23e234ae8611747aac8dbed0dad83849d648f99cd6b6ea21ce5483bfa8c6a4504021b72de308264694001579647cb42e6a66a07277a56b8ee3a4c50e6cd4a65961d14a67a7b84fe0c7313e5fa2c4c43d738380d8ae5e23938b361a3eeb4d770fe657e9a198e0c4a623c17e337d63e9961024365682ca5634ae910e8e0d2d495300ef162c670b78368f3027a87398e2d36f36948c8313008f4e062b85f7bdc560c9a66e1c91ca9de004f7b1cb38ac571f9a81c587204b47bda16e60b7d644c7fee79f66f2eab53edcd93b3bcfeae6db6dbbb63c21704fb048c8723129d2c40539d862e6f37db337df49d1412695eaf3ed515111b2a4aa0fec3dd429d127b449eb60a25a9100f1466ddf30d9c76611a89e3672b56fffc605839890635541cfa5362da2ea532a34eba9b10c9629fa14ef1bc0be4dada92d00906f811ae3028297e1fd156f84fe4f0303bc77217be53897629b1142cd96c9601f57e6725472c0b3716c2110e1b20824cdce5ec02640fe2bedafaad274dad4bf6aa8d662b45ac47cacd2d74ba53d8bfcf92957966010e825a1826df349107d95feec3cff04a335d96639134e7dba1606dde82c2ae0dd9b81d1651c37ff369601587a6c53fd5cc8c38adadfa2ba43c934c129e653658372f6ddb0df3e33544caf26268642839cec97119ea1bf82efad609ffc42b8dd46d474136a7986eae95973f7acc1acb8195a70d0b3596d931c24857839abe40c452e390bcf33e975a4e4255d487f5f173e56bc05db85fb98a7c8069d4bae97a950ad51fa6cdd788a20e4d2afa788191c2303977955ba1939e5c8594670690a369f956d10cd266b1409f0ef1b30592a01fa2a6b777e25149d24de86446102c11584e61e26f9d37b09f735eeaf68607831bbb16075211d896c5d27cdba5f99482edd822f44042ae570fa249e19f50563e056e41cb4f019935c04ce1f478ad260569b721afe497856c61af92923c2edf16028cf65477fce56724b13ffc3d30991e89b29f101831d715e00ef4a304bcfa1a5277a94de16cddf5eae3c5fd9ff562312777e04f4ed4ea5243179fe5f44fa3e64f26df2d1df59d4f73bf14b82f2cde5bb9c5109faf9eef0893137224a2066a6f9aea3358f664f383d1b8b8cf3856f80334d3958283f2d7bd74902b28f1c888b74948448ca1be95efef9a2ad0a18c57fc9759c6fb907c41c89d2672f12fc26b90b376562288e5549e95aa1ca447a245d842f19fcd5197fc771bef00cdb6c4a56854b006f6448cddc84be01382325e85930ceb74c852ffe206421747bc45ec856dee7e67c952a78c255b9e6a0f2bf3248e97935a65cabbeda869884bc533a94c7dfad72406aa24c37c80c23419fee28364b0837c7d2156c3a50b051e2d1d49cef66b9d7152509b126bbc7d7801b27c515311175deaa8384a0ec2e3e715aaaac39ed95d7de7ad128ff1273bee0d7cb3fcee70f3819dbdaa1339b41e995efaeeb5a6a65e7015e6ba1becf7bdff67973b606b5c936b6245d26d0af47fc746b53a9b4fb3b30ee36fe48970febe382db3d734ece3f7d43d0c59299686871cec6cf7e09401317d21087284f384c9d9ce30092db0c5fff2bed078e0343c35b3011fd138de43dd35567822f7a422476a558a381c231bed794f72028b43eafe664ae5394d4db411e5203c5da6a32658a444b4fc0ef4f3c6f661e73f1cb09048b1557c8fe6fd5885c8b7122b8ab494329495597b1e504df7e399e50ab21de2ff8e0f6b6c60d792816273432c029b431e8b17a111a7a3c1e759903671cb8e1ab0d924d294be502495e23b5efc941ca720e1e0bbf2f56352ef8262f0a62f6ed87d4629e4fe09893b676221de295afca56bc3247eef64e262c9377cceafec2ca688dd873c4be3db2abdc246a28c7cba2de78675d7361d76c840a651eecc0a2db9ab4e2244c53ed942c3e2a3ac6910a710b39cddca4ea2e5c52b2bc660c2568a3c7583060b5a38bf4c7f3ea190ba8dbfd33db917b13c1bb45217b54019f53085be7e1de821d500a90c64173c43782a49adf5f5181c80dbb7f41c1f9c9e13468140635d8cad9f0486bd0a10b1ff21bbdae377caa8d3e764b8b2439b38708578e672382de17b17a20b7a7fbae90e62080a143073a48098fe0e26727a84741ecfc5bb473b59c71fdb84f3caf7b6d1ccd13c68f599f8fe40efe26871f641fd3c2ebda29736131809387d833420d65c2360541096242876668f6344351d469ddd307640f6d2f58d48586c90cfc69340d7758d3ce9a0d9f2775e0835a6781b6806871a5ab7151f2190168919d21b95ef3ae8bdfb28251d50d6650cb079bc6e248c427e34a7366e71cf048584a90a9f7d185180076d3325f4f2c30c1be23a48385e12c2b3af8196e47a183e085eb1f02237317a52f875576d062d2f0e9b0603350312819bb6bf690ceb789319728b7c045ceac783437796f38b75bda27b9a3d581a34c3c5d6f41b982b017a991b3147c019656e02af822f1b05843ba721b4ab531ac04c383c3385c0a76160c84901a579db7bf4604a20da31ba8ef88886a123fdcf95048fc3a184234c59a17da25ede799bfaf9fa3b7e6687dcd87048d5e92ff39a229655c0d55aac3bcc07fa3684e2a357854d0e4bb529d7af08128fab5def92e858b01e2dfe27552b3cfd03c25cff80c77490782cb0d657141537ce0da170c5315a42671bad21b472d2c6ecebf0deca0596b2af5111695b398143c4c717b1bebb7ecdffdb65c62a81d5af918cf6f0d58cbd655da5c82effdb54960ff63364658aace409f922f2671e66358953347a58481570d3c0edd9a9e0a52174873424555dc29ddf8b9a5594e1751004d016ca8570be745feb7ec6b0a47cb2cc79e63af02d06865af1ffe14576f562e536f7437cb70010b23ffe718649584d0507b4f63714be9047529e808aafb75de0441980c5035a980530c3e38886fe823c110e0b10f54a8cccbae674f1126abe51666a91d97814a6970a32d39ad5f76d83a3319d1865bd14fa2fae908edff19564b2f6d5632d9de0e7c0cd10471a0196629a5d61e99b09c4664f07a8320faba24164460e1fb4e263a4d2c8cc356f51a08189f95e2589db59ce086e884e30f5dd3e3902ef04d632fc530cc4479f8f166a3b8d6634c17c6684b2b1ee3a6c5b7eea07082fa4c2199d5279de8567161f48145f7de3af54e94f47ebf4c066ad4a57abcac1730896e23cad79aa8b5f8b57e4aca258fe438d6495649024f0e308b376744b5c662a6d1ee95c2bfdfff2197d486988608a2aba9efd1733342e704ec0c42c80ca78f4b6a4572106ead8947bcc8c01735d465d4c4b77ed1974cff9f3e28a04137b0144b52a7efbcd81192855b8c5f3b9ad29f195de871c4926d4a1aea5c176ebb4abc54bcbaf0563bdcc26bba15a58f9adf699d4e5d53c500d6f55aaff687dc70b78e0e3f762e240385cdd1521f13bf5c2d2ebcce37baf8b5118e905d15180be43f3d831c7c91ba7674ead6eaef5a18be999e09bd51f94156683f40afe48e87b1d1a77b02247268374ceef84bd1cbb8313c75d3819655e66fc6f8d522b94a518cf068e4c9f76d72ecd5910c8354f7d71bb194007723d16be13bf81c37961c4f67cfe9b853ca7d350806a6f1c758c47573fac9da52d46d6675e361f698d66588260358a4d918f59edc01488f30e8ac6ed7b5af8951aaa062771fd4dea41deca000c2eade0a404df79f19a2427905b1cde9fc72b0ada361dd9147a168e2fa1aa46304affa74a4e6cb3a68d3b9db3d248189a350a6735677869ca4783bd1ac7663545ce792b1dca963bca87db8578b52405837412154a84929027719f8f84c62a2933f452f0ea85131a970369b24df26211f74cbcf37f263ac32a22e128d80981151c435e4a24bda86b105873e3d8e660a8cc23e1698e8a146a5005f2054e9db911faa763fcbbc0205c86ddd23e47e91a76895bdf3f63192ce712ecf12c6d714cba02ad6b7c3810066ceac7da83c1ca30b34386e61e18797161fc774163e909b6252152b557bf6bc036f319dd7537f88b4358a241754aade0d866bf689c6749151dd9ebef34216107da9ae61a0ddeca5d3eba7ae18e4c9653d14865a645973e5546bb530b430039486bf4b420373355953677a5f0500acc856c816a874d831f3ed858e9c1e7d3e2a00f06b475f363a053e6b846945b6b53e8f0de71eb37a10d49252acf174a529d4298db602619e057e041044331ad64caadc7b737898a93849bcd1ddd96e9f81bc6d207dca8e6f1f187a0437101c8d9175d6ad37057a3fe6a7346500126370d06b8c1ec92aa651ea3b7cd17ec37912f542132d448c3024f53e8d6d47ea321e98914b0a7c394be700125276e155e7256f3c532c0fd5d1a10ac14401137a776be45ab08127d4b805f9c83506636f4bd64732f9875ff0bf5a69e0fd42935c062cbbb816107e9ec3ec6bd5688e4a9b414ce28fb04b31f0be7b5fc48b80d194ed333673a6b9a938a8260dbda2567726e1664fdf581fa5c24a0ac561909f5f2f03d204133b2a38548f56e1d750368dbd4dc1cf3dbe246384de6122e22e2e022202fc7b060ab5494bdd6a67f48383b21941f18d376fb4099998f7139dd6aa271573919b47466c16d0cad8580d00cbfbe55fcbe13a0efef82ecf1bec2592070cd366d9f721db3d9b48315ec9205aa262e35f2868c4e33b21a0f1dd016ca436160d6690116086294f17ac4c9e3f402dc04c940d509be40d54e10893d8e96a77eccd6ffe7a6b268d4a1a22a34d1d939fd67f525cb21b8d4c60a09a22470112fedfcaf8deed7e963597e885c8b099843db0a8bcb386dda43c9f9961da5e68b1582d985830e6bb5fc285a07c92c27c4a4c537983cf5d6e10c1dec23d657b5d612ef17650efa05711ef6c6f124bf152e856edd78b2a0f1f0a43c88f71e1f15f40102d9bde3a49a798fc85eb214e8a0f72cbd3b256d3b5180a832cd500359f97edc354cdb90466611ac6418ecc6e40c4f40df5eb56f5052e000346f7505e3fce4d5d18ee27e30114a96b17d02b1dac569fb06f4cb33b85f8352438b93d9d4116ac376a3d92d93ea66c69c5440945f74a43ee38cbc3a5c2dc35f2632d6ec78ef6479916d47f768b0fdf3715e402be01bb07b85e62bb1d8b466868a89e6a83a8f1bfaa8a2775453530e4122c9f16df2ef24f77b7a986ec2975ddda3678406e06d0ba7c525d6610e773c83d623979fe9cd23b00d67f9ce87f1cf2dabe327792bd225d9b3ee225fe9de7427f6c3651910958ffd13cde55eb05d90af8af11211745872a595e0ad787b6837055ff53b5881ffba8833a332ae57b13721815a47540549e03a9d38b6b89aa6a0071439a390c3414399cc49d0a27e33259696df06ad09fecf329718eae36f58219823d8f816a0764efde7542999aed9ece46319b876ec8219c4bc8a79750b6e87d02623e293a63b038c50656abf90098de7d1667f0569a36a5cb19f7f2baa481ea8f53570bb0d744bf5ec6716f07c0a00ee32d835a428ef30e3071c9b278fc19c4089c1fd1abda374c939dab7ef38083315b8ad9676fc40765a22c727640fb24635b86da0e5b9ee8faeaa1811c5152154195d1808354ad9da2a5ef80348786b0c482c7aa44d81f39781ac2e9e87616504ab229033de9bbd63ae5ae105b9f282ac1e82a3251e03b2955191efed4060db9455710c618f92f4f57f512e5eb8aed02d74d71bcb11c0ec2e9c4e299a8ca72c600954829c32ea7f67f7bd1e1e1f9a9844d9614cd8f5b78da4bc455638707a299050ccdab95ad4d2a91bd9f81288f09225871a358af4ae09ddee54edb7801bd51ee01350924555abd312590b106755314e86b4c6e4daf14fef4d4cc60e7f21827bb45d5612456206a2bc5059010ab52ba3ab568fe9a8e1ff303c4ad6a6ab38de4887af7107b9cd2408d83e154295cf57da5500f0beea88d89854d180389837902504e11ecb1f53270de9d5811ac4224c074463702917194b2c822b8149a4293c1f02c82a688b49a1eb55594927b0d051c06893720d4749e07a417403918c18c2becad3010a9badc01605b18c1e5e37b22c4f508af01ab719701eabc0a7489c5bdd0ad4e9e55a01bdfd295ad85128f288092325df61963020247e7816491842902553f9e4b05668a367639fc7cef98cc6afd0164891bdea9c9c25d386c084dfd13651c7ea16022db893f873e5072e599b55d627f513aa95bd8b1bea372c32893199219199753993a484ef18e8af7930c893b91c5206f254dbd28514a14ff14064365eb1449bfd23165e47cc87593a6a84134292963c87a0bbc8f3e0c12a3ea649bf499b87ec60845c44adea44009bdb273fc21d236ab7e01e0ddc267def96c6474096a8afe1a49f55a2da00a0f30a3fee65047db0d4da64ab1153a01b7c9f7943c0b8e30df564b149b7685a617388d5e2fe1564ab3733c899ab642e91da185d424122d84bf410f2e9e79064e70497869ef50fb9b9d8f463114c403296c93cdcef97415ce4c0a0c5a635d388547f47043c623f3abff46f9c14ab9b5f1c3357198c456d2019a69f448e52f532d8ed2dc474a96522ca1656f0a770f6626abb5384c437ee3857b212b3b88aad59e6b565d8d47b6b79543ad7e0716d3cab2907f512b9069d5c7de3785e068ce7b312d1cdab4765348d658fa6f539a5d8a7306517c8d37113868461bdad4b1f32a7919ad25eec686b1f8f84cea836856a94a07456a51ab56fc96a91be026c15dc5d9c07521a50582f99244e8750f9b6d575e83373dfc4e2605ab5812c920b9a643133ebb282cea0334f71e5437d98da1eddc0f50f36ee7cc78966c6aed662be312c8b1ea311f8ecbd349051c66e0229b54b499a77402f6a3a3f4149e629eb977c58ef0c0ff87f14c8a904ba219f297141efddad5617102021c61a5053ebae4d9c9e40123ca730744ca68a357114b0661da17092f2491aae12c8b9c8aa72d3327723554fa5f75c7a5be608e7a5674ff534e9e82607355abfed7b234eda1a6d6ab9ad3c35814553acb070dc85d0ceb806dcb0f69f71ceb8ce3878d708cc6b848e8319275b90b83a1a72790c117f7ccca65503c5ca178121a89eb47cbf575a7b7388b6143e8d551cf57c085590ad40f9ef56f84945457140875b882166d4a9d22e92a5779fc880595cdb47265f5ed1241bed76eeda69e00eb5d61b272bf792ca393bf73cf5b3a51646851fd5af9f3937981de9abfc75a7aee959e9e2eaebabb5dcd0316e0a7b13ec0a24e67e94cac4375acfccc01cc7496e80738c5d8f5fdc40381d05b8bda1e770541f9630ba1907cce783756c9803efd43f977c8903f59cddec74cd972bea9de860aa5c18db6e4b47e591b265d91ec7d476950bb3fdfd64c8022746c7366a060b451c0b502c9a9e3df5d74035bccfc9d16058f2ef1ec2f5c15c3f966850826cd7aef05814aa51a7918285702938a996dd0c643647b384d4f9bbfb85f70209d4bc1cb9a7b4100c31d220203b88d597acc1d6060e7b986c1b111f9d22a211640b5b8c0e4bb40482e09242ad3c80d6435d2445decffc44d03d8053028147f33ceab88dcab9b78592cf697893df46af231629a8c8b6436090e95ef88b66167b75c7b6fe7ee52edfe56fe2c97e78aaf11c57d9dde7d9c52627399313d27427df2885488164dbbd231b56761df171e81648c14f158de379333e83f9b7e1501e67ae5bdc9330f4d46fe320cb49d2b055d2a18ebbc4dcb008b9e41f1a72d54027cba7687e4419b658e4049b5726eb240e060cf599b58bc06966d5941c8ba904ff337ae8fbfe85fa838065b99e0a049a0b38d3bc5086095ee0d5a298d364eeddb1cd93fc380ae6764d2e8503201393b6284ad90ab557367dae61bd08b604d2bcf81979fd4a643b68764d4c387022799fc7be21083eedc7134f643312578f9fb2d2e6fb1598eca608ff3cf9a49ffd41ed1e525077a9b4f889692d4310515a4cf2c3b2379fd533fb12cd74ed248703ebd74bd544da6b8bfb83f97f39236b916760f5df44423479df36bc6c53c5d4f03c054ac0a85d9076444e85026ef7c4888c483b2c46c010350563f5381bc58b5af76f2698b0f52702a805f1a3cb9a7c5e423186f93532c686d54d9f39c0122c357dc5b01cf2b88b2eb8bc7e18576a30d46308c46075267bf043ad3aa4606f8ecdb15f860c69d4133c03e42c1775ee5ce4c748640e859a20502e97df08009733f5f1e93a8a8a959bacf20cd4b46ce47768cfb268248e00873d8e7e0ec1380948c087419910717c2a385fbe93b5e206d8106729c2b7e6e74896a472c953f9a2f80c82f2f285d1725c272ea735aa949244fc9f7005d2a43d23faac8e788dbe840436f21df1a5c0e11e16159ffeeeb6ecd8850d21ea0187c41cf27aec5783b2c379a04cb65a6c209337ecfcc5433d6df6ee600156b2043b2536eaf00aceb28ccd3a6b86ac0f73e8c9f407950221f1f77768339590766c967c617fc651e0ba92e2dd006d0818e1cd3df05a29d5cb5a5e5da07c69a3617f4bd035874718f4e7b437e20ed2904258405d2d3b1addd8f0c3e92507970281cff5b1618db7ad3a6405a868fa739c2969ea9864d8f1081d203b6628d50f6ceb2c26422fd5920974cb92dc8153227eb4e482bf12802fc626fba616b9cb30cf3f087ebec37f8033ab4bce2cd1e0c5e5886cbdf6fbff038784f9179ac2800608f0175a8ff5745361ba60d3835273e0d1eee2d1437e2f7f8fff57be2baf823d78bf19be36b1a485b84031c8075097e19a71e8ae80882dd92b507b67152011f2d3c737bda76db5d1d316f01efaf9e0ed0fa11738f5e8808e08adeca6ef235aad17838e0bd7cbf4b15c53ec793286025f6fff9fe46ec95637e1e095e5dbb8f8a115ca14baa15e373c5816d386c00acc88dd1a3e472e4692b1960d082ad5e8a062a953ae6d220529e4ca67f17df9bc69cc2903db8e41ee9d7ae41d63d56bc0dfe076790456f18bb160b7fce44df852d73d6067791eae69d6e9b06c0d8739433d988f0fc769f31e2c298b9ad0db0dfc0aff0a22f6b3c008d09c906b081c7131a886c5941c2d9e79c7db5303ec6e504c7b7e3cf24d28bfec4aa12247af47f3d5171d5d9dac0fec0387de709201f235138832da48a3432ed961ea72a140420a48a820c8676a9449b62e2cad85f63f64e779ae341898cb722d6b5242a1cbc49b43c43022c895d864a772881ac87423db7a94fff7df2d763957156e1b0dc2431f6545b9603ae4ab2838e0a5d7e42780ed6121e4548ff02959e8ac6581eb102060fc1bf5738c7321d4e5477cc73ca51388e1603e00fd6580b4064561c004a4796ce7c0f0d561e416a1a48ba26a5542456b4f46a38490c4cc5dc4f826fef82c8eeab2aee892b78dc7de1363c86b019d5d4817f067eb7a8722575ded07e5397b727081a1c00e90388dc9ba09c21fd16b23ff72a1fdaddb012e174579ea4290d4709511fe0572de5df6f1beba6054d3e8dddd03342e817ca82384b9c487db5ca88a4e1b73fdf500dcde5d47a419419212a025ed51b6e64cb18310994d6c36a95b7b8e1cdcfa4a27d917ac8f10247e40a03f56497894bc86cb3345863c7ff0dacc3f602c0275e46e4c58d126a59e171544622cdf587776645ce89df8007a086d9f1b786b7c50040e4bceab847c2d9fac05bea40a6848f6ffebee3fd053e30aa6803d0e9136b22639d1bca08785ae8fda927a81959ea3b13c84b7081afe73e1215c97bfee0458580d59453c853ccdab3447149d260a9f93f960aca9e5949f7a2ca6f7aeec4c8769a2f4738d79c632bcc2ea737ef4482cffd457f0658d4ca8874a7140ff6e76d9dc05616ca4ce82bd05b7402c3e18103f7e21b1db179a121a823043777d7ac698a8fda28be778df475629d4e64572b4ca5061656040ba3ba79cc3299c14aabe35baa2b457232c12d150a4e9e0d3b7a4fefea3e3815fe300a090e6c6be04e8fa511f7d9a65112d3a48e35fb97a03077500ca39f10dc249dfaa7ce67edd05501135aaf30cd2935eb06de6f204149e60d41099dc619a236b7d20634209c318138f3216a69a1c9770e4c3bc0999b33f23c2be1ac6cc98e1f48b4da194ca9106f257c8449dcbbdc525b7023261ba145fc4e616b1f0094559b7942176c7824f3969be8c09eba3fe4310ff76dd5ef39b018990db75217b3ed7577815e1b96ec5c271f1bb8d6ff53d859ea0c980335217e24324d4ac1fd5581b6483f199990c6dff014f0a6c7b46ffd0fdc1d035ab33d595930dad53607e5c8dc585e72aa45b8863fd60f0e78af06e43efed81b58131b6b27d4b4fbc55899a3031d56ec65d89c91a1060a27c1604690d718705a8e83f9457e7f9e6c1d0803e0fe7bf2e049fe9f8fd2464b9b249152ca94646205860574053e45755a29469c4cbd47d662f9567a29a59ebd3806eb9ab8f7d251278aab64431b924e4c8200b14aac6889946559966559965f7ef9e5975f3ecd975f7ef9e5975fbe17923165d08636b440acf811c9164869436bc3907c7d98ef67aa4aaee4743a9d4e65792a4fe5a93c95211b96655896362c4b1af35f9665f9e597effd7f59e2adafa0c39e96b021b640ca29eee28fe1644bb2a17b5d156c68c37074981a86a10d6d68c397ab34030c2349154e766fce7064dba8497cfed7a84d4eca904206bb94fdc514a394d20bf3b277af4ab9d9a3fb18dbae05c7fcf0eb303fdcd590922dfe8b81b2cf2ac8bf0b5444d3ba4e52fb730139ae6c67cf9bab0a5384385d40eb77398b4c8395bc3ce62ddc2bf71572104eee63c67ac4324692363732aca6871e3ae9c4c483003129119d084729c7711cb771383f080cfcd1673961ba143e7fd6e74a702cda86ff681adc4731c5077a0ffc89b6d1393c98a61a8073f5351318cd976841b37eb40d9f4247ac29dfe3f09e3db9f3e03931beb66aa7b40d1ad2144c01838ebc851df3cefd4ee5b40d6fa552ad9c0b7b8bd56a1b1ca6651bf66d4a350d7fae33a59c06d399985eb7ba065ef87c4c42071eb23c4aa93dd8ac1437e23ab57d380ab930f470348249c3075238bda0280f3dec74b84dcbb0e63167f4f0416524b9234a29a594524a299d18e7fcf9fc87a80ae35528346766df20d8a30898a04b8f7895af4d05640a2a910f2158562511f742784c2d51e76f673b140d8ad22d681628ea0485eae137fcf862b22ccb2e1a97c025a2a64b494b391d3a0c8d6a5d0b0fdadfd741cb287d8c7eefc0ec077af8eb073ebdd8fe3862c6d829a0e60a35572857425128cce650da36f8b9cea6c53eadb97ef02b07ca3f1c4551144551144551144551d4bda19110c2d0462770220bd4a3380c3a800043eebf66cb081530c678bb19085317f1da22d9f5393add17395618c3b21a343964e4755dd73499ae1d95da1db9acd4e693bfbd817df695ce15ad533401840483115a26922a884832917600294b20330048e43967dc073d938934994c26934966fb81c1efee340a72fab6ab967620d6e1f9f953dad54c8d408de3691545892a0999836a728de3d829cf7d918c580a96923d675b1ea198353899550c804963219988ef68d2c4a2f965d883e1513c67005a64fa9d8f233e4670a6625471f538f2e0466c15c2e73bda862b691ade4614610a57620425aa2528811c57230e57e24a708cd738625ca372857d52366181a1cab1a9944629f574321319ec548c4aff1472a5c9b142ad344dd33c1d4f87b1bdae9661d85e375585154d581bb76d1cdeb86de3f0c66d1b87b7546adb36ef25b4790c1bd0cb5ace89dc14881e33f84fc76b0ba2584a3d218212726a624a8245b1568cf1171983583948a886babc94fcda637d755d0dc5ba0ed234b80e420a1264073a08d28320a828c49448ae3872ce5967d5461a83c5b410af61ced42fb848824344c6a1f8ca552a8ce17f956a6555f831ecf157ac93a12efecd64013e84593d0a93cf875059b6e322759d7380ab542a95b52fab8d8806843585aa6e0200838cdd8729ba6e7713864c43eee59c73d79b5a2f16dcebe14904217e3deddbddb79b826677d3a7d76317c83eb6f4de7befe6850c7eea67738cfd3f14b04891bd2f640a81ac83c5f5ae8b8b32e79cd66698bd40c8321b17727d50a60273e5f3b7995d4c61b6ecf0813cec1235c3de5a6b6d6685ec9915727337441081ee8af495d1227fdb9b9a1f993e58e307ac0f9c2b1afcf3214992bcf7254496aebeae797154a4722453cdf615b95ab739b8901ebc5f6b9cf93db6eceb532f5d7fbb52069adb83738b1c201ea20e39508b38ec8b21438e5c6ee370d4dc9426ea9b3d67164eaaf03172a2078d691199fbcbe15199938cfa9426fea02e8c658a1013dc6863e17ae374fc9024cbb4d30fee614964ee734b877bfe3fb8e7bf83a344d091e70fc2f3f9c10683e32ce0f9dcd22a2a313a1ff957de07d7e5ce07d739c863f437b017f58ac6ac742ddac7985ad72201ee57de022a1fa30bc2a3d279ae9ba20e688a3ca029ea96c3b4683fc4a7817f611886611a913a52977aea247d726fac25ed63b8df3aedb5ecbb3522d5544b602d655ced50cb6853ac9a6a69eb8a700fd6d2a804aa715243b4711c4712d7d295611a892d79d552b6d512564b9ab6615ab66d9bb665dbb665188661d80f2e9381190c06ff055367b2a9c5bc625ad1812ec568b46dde8bbbd490c18126071ca81986d4596bd79e329ece26e3b99bcdba2b32fdb985429a0efed3fbb7d66b1c845a6bad1d155e593aacdd42097b10dc6a6152eb6412932426afebbaae2773c64a53355902164d7247c3224f56aba80da60daec89ce93cd7f512260d876927d3f3f7c6a2499324258720ddbb45b65ae410414c1b4d360de736ad5bd98f16d96a915ce7d2c1c241692b8c1285c17a7466bcd036b6566bed5cabd4225b64a9d52a795a2d4f89eb783cad96c78343c7699082b5d68a22c639ff6b1fcd8de7a8a190e7e5bef7da720b916ba9c1307cc21fc6e00cb75dc015007cce8217e459679d2dfdf88710cdcf067bfc36d8e3164c9ba29aadc51275c1c0206a218af7be84481d23cc39efbc5bb4966d91e99555f22c45d0319e0c2928c20b9fff006cd04ff17ded9b86c5b6cec7111f5b37b51d884ba6a0b4b71c8ef97518688b4ceb4f6e87ecc33bf4e31bb82ba239e77d5eeeb82ead7c42a7d3e9e42cc34a0c337c5e064b0c510534452b20950c6a510cdd8f23d8b3fc87a5e333c8685106b98805f42023842812e3697c72376a10f9597e05d4b2a2f247f011ed8710cd009aa24f86719b8e180ed01a484706c845193445db16e33d5088ca5017acab9d9597e163f818cf926198eb1ccc029a2dd218191eb33c986374169dc7d1438dcd8d0f397ed001844aee782787ec743a9dd99d4ea7d3c99f19c3097905bf4a1325a81edab74c974c6d24c98925460c31805838cee3a1c901877b3dd4d8b877d33fe800c2bdc65ea094524a29a594d29e349c93e5edd7183f6bf8a60058e0a35a648a669195b7b1a295ce8710a2958f010ab1688a3416509f20758396c89770210c51a4f9114c9c208a348a8223986089b47a04a9092d91664f80d30529d2ee14486a8012691793205c4125d230145054220d2b021454a148cb84ec201469dac602ea2751842b91b66d2ca036c2881ba4441ab7b180ba0826544889b44eee84c0f3d5074d26478c1889b4012cc94f54bee24c1bfea4690871184c9c3397e7b36a25cb790b3b4f2912d3e355b5c49c73deaeb6e68c2fe68c279f4a075622a52ac4fd49dba8389346eec0ca8433e173fb2bee7d6c2892413b6ab9401a4259d1987ca3380c062fcb8e62bc2562ce99edc5061a3a7634b16ca29e8ec807da519de29eab3a1d8b4bf2d90e94d9280d69d8aa3046476d10af87e1741ad2b08661188634b4f6e596d955be18eff5ec23ce0ec018a6d9bdb53692318f5266cccffe721ce013350b8f34d4c54e549da84a1b06398274a152428ebb5add253587aa0b25b0c6d5683bc085942f56f77a09d5f03c29c158ad30cef93fc7531ca190e7652e2efe8f13f185141c0018e48f98c15ead1ca673accd716f6e3169f48a0aab1386e9c8844194e3c175e05f57dd884bbe21efb460ce894321defa8155b9bac77814dfb0cd5952664c06006cafac7316f690738693e9e2bff2e273af24968f72fe7c7c544953e54bc8988b9e9488d9b91467b9776d6dc14d0dc3bf303d475123a68bbf14244aa22a70161593b88f95847125a9703e82290916c5b6d65a6e7bae7beae2e07f18ee66c2b611ad1e6dc3a604d75eab65afaa3db40e773219c6183f6e1b3a7a4c7c84c76ed6a6a6ea7a11258aa2288aa11a353659d45ae76ceca2fa824c5f730fab9cd18b0cce32026ee4ebef20d41b5399c1df8ee3388ee3bda1910bafebbae6e4ba0f253f9e4fae992e2e8009865c43155ef3e347f6d8ffd87ad42175116f6ac81a92478fa68bff689251c85f230ab98507017cfdb4fb40ff7f5dcb0eff5d8fb300041924d1852d82a08552047687795c2928a145175f37a7838c530627596373e303d7d1e2aa21a37531e7acb356ecf3c7d35a7b85464411a191a99a53b5aa610d925347505a1508ebaa54dddd1da2636fdb5328582ba20926910f219a481729d191d9796780e763541ea4513e5a2ad1122d8d4a9a66b79e344e04db69d756b56dabda76752ad59c69fab967ebfcf643883815ee8710691d100da94b8b4dfecee78e862d990a25659fb3ced3d11235512a326847d9db133dd9d169644fa3d3a87b85655bd6cd3963b37fb9fb58afb88d82f4823aaaac7553d5c861ee4a4557aa95ea5af14156a9ee6d194f5cd7cde5836a03d7755d97733756e4f999f63df86fa0ff5cef85643006d1e4e01e8e1e40a522c66661f39bd5d92ecf59af8b5bde139ff4095bdec4a1987ecac950fc496a625fd2232715e0d3beb62dd01b8dba4755f491f8d51a02716f840251263455494dc345da8d843811235ae7237519cd1944883ef2d168f4987a4569d6a2c874a6711e001dd3316811fc64568b22bb1645ee0ffc7c9f6cfbcc19ef743a38e2e7b3849a2a52f173823cb96e063d3a4b02eb01d7389c0e2bc8af850cce164e0cdac59190728044132d22c960e8a3223645418aa2288a62ad9d1f4c1ba0c8f33b5a9669dfb1d66e3ee6143e602214f9b85e080f293a72fb7998f6825a76b83f5da5bad7407ee0c7ba2258868b4075f48218d4757e1d9b0ef795abe97c77b8ac6e71f30495fdd168341addfb121a6952e8a9892909a694528a67eba3df4adc05479c2871a2c497cf3452d20ca5826b65328daa9c24a4911494131393c9f484c94d3e254ac95af156cbd432511c984c485a2d8bb24b9a4c319551587346e5e20a5df8dc3e685354455d4ca696a9656ab54c36c8df72fdfcaed4d5c42f158d59b99e78a916148fe9b28a19e3a4542a954a792e219fd4674fd4c55b4e52d99469cea04adc85e2c0549a4a53d932b5544b98584c399b4ca4c96432994cd70a0c20b40199265babaad86d0cc3b02539866f080df15f7f6d13a9a1e44dc6f2f939038446413748327d709236ee79dfc74fe96dadc66168cc0f3537b4cb51ae7a24ee28cbb2eceeeed6b29a39a736b5d63410f7f5c7075bde344dd3b4a7716d730fc7d542d74a69571965c6d7b5d61e31abfdda3d8d5f208caf8b3a6a9cac3975ec1089f0002214d262e9506121d77b6f8dc145fe0ffcd0f4efc075bf7ecdbd5173df723740e045188d829e73ceee401503584b336248dc7b2fbeeebdf7d2eb567bafb5b8de8de534978c4c4a46ec88030799d2c8ac7d77c39165a426c284c9e19ef5c04c5d92df3bfa7e942cfe74b807f381e9f9f370ef0324989e5b92ed20006814a0a8708232423a31b15fe9052253831ee10371f83a1a2c0f6f71407f1ef26bd9c1437efd1ef2ebaebf1607f4d7b2c34f2490beeeecf7a41225914824128944ba3744ea187177afdd3d8634a626c9c964c4f675f12b810411a2dd6ab28cb465abbf6f4eeedf98e47104e2030022b93ef83a34c78300be3a031872f6f87176cf823a3e903e109faf3e8d8fa036b9974b2cd94734943503b5d4faf9d86cdf22feb40de4b5d85246c6fbe914db2abb2bc5ad467bb04b353fb00efbabcbba161bfc6204feebd1bd5a06711797d265d865d865d865d865f8a2a2827d9354f6aac3322ccbb22c4b6b5fca184ca04e27146b0a9395125594d493d309632ce5ca329f33442efc099281c4b4f8449c928373c8669c7d76b91b7d5a32636a6af83e594c27a793a8042b419d5a6082214af04dd2de93b34e18630cabb141dd40ca1778d049e183dab60ddbb0ee31fe1504e6fe911a615b66b047d5da17952f68d6da69a7c51d1b5bd3384204492484d664145d3f2f900f7e4377b70f5b6be0e694c1900acc21b7f75e5c20bd7365ec7018eb27db699526398d27c8f56ac2ca8a528a1208655fc103d58884095648018491342a41c2c1109c71f45e42b4c385765d2fb9862d642b10d7556bbd735a4f167d5517c624d684d32a8a1255123207d5e48ea3aa474a2bbd51a96846158db9c944594959b8062bf2a42e2fc83a8fba786800a50cf6489be8aa010e64e0a655f6e80a3d5aad3b8ee3385e17e785cbc0b6dee762528fc6e76f593e9a61b08690b135c3bec4f45cc084a906a37164afeb3611482881d3a3ab464db9412142134f89d290bbd3a0b134e744067b341aed20f7e0e19edf7882f60ba533d4d3c57638c820a6251d6cdbb6b57a6cdbb66d1dcffbcf4a6470b63e70b2b2fd56aba58282eadce4a03a76c86053065b01711c4d0e387aa8b1b9f121c70f9ece6a73ec8566ad9d765ed8cf8bf1cda670041654221f42d0a0c24a1465ef43081a56c84288487b2166167250240aa2ad6fb801c4e1f3cfe14f83835540a72b420efd10419d3316490f69daadea97698c942fb81ba150180a3b0c851348c04d08019309d38a9950088970088e1234eebd84b073a75a6f46a50b46f7de1fe4fc00ca144d9053349102711f3781918c93e8fa16283214597c6837eeeea57a363e3428a24b850fc0f8c0a9f201111d50aedbc950971c2e0d122a3e70b27a3055d5da9266e4de712ccb1d9f4ff9293f234ea271eebdf7ca9052d3552c91b14506272902df8164361473890c2394423bc4aa6d35ddddf1a9187bf083e149624badb5f45a0ce49f18a3753cdcc5ffab3b505fcdb99da3c0052600030d683b546050426b5c8d754790107c11da71af2b546305061a8b00df9c12c5dd2f56b7680c0de70c28c6d7a45a0330258bd9635bafebba2e989c6f5c1de8e3bb78f8879f86ee91420a84843b0a7d5c3a4ce91e48451cdbcf4e87fbad0b627b6e7bae1b421404f79d0c743e3f7d95ce67117e5af2803a201ca2f6da6f8f3d2b88edb5b7400bee2ca0fdd65151744ca7d0162d411a8496301948e4e11fedeffa9a6538e6873b1ede3474984ab32830bfe811cd4a352bc5eae80f2125d13d275e16de161e0ed6c562b1582c16c65e8e62db5a6a69cb58eb323273a63ffc7692572783657e166152978f0a191742768cfd6554f6de1a342a5582d184c5643585848275a94bd376bd2297ba346738b144c74fcba7a2fd8794431f7dca074d29b207f1cdaec8a539d3ff83bbb80fee6203039386ff8c06e60c77ee060ff7ae07bb74030cec9b9c0e334aa67d373bae86325513bb8175ad2a92c12ea14aa55229c707f740aa9b39c33327d5cea6811f43a1b2ac860c0e3452604c92d9c74c4336b96d5c6419b68d66ce601f27e348c6e29250f03fee36f206c69d4291ddc6fd9cdd3daebfd129cd094992645ed180a13a94a8c5c0d62776d0597d630c04cfd71d0e3232d78533a4858316929648e2e93c264a85802924896173860c0ea4e6311821b5bb975d204e51d92d2832385b94bed8da897da23f421f6d3320cd39ebac5a5649b4da11574b29a55893b06fd29ce990c6ef0fac94c126913e0f88b130580eb30a50c06c8a0893c6942839547cce240559cbb08d524924128944b2f6a563857befbc531445ea7934a48d628be258924183eca1b73c9bf8b1ff74596eac2124113853b7033ff5ebae676022b78c26641f0d046708a70cb7484b5ad2520cdd7075a077832dcb39430cb2add124947a61e2a16c5032039939ef17e2de776df45b88d77879b1c1061a3eb16c510740684d42b69f13294d454585eb171d667ef4c39cc8ff953cc0f96cb0fff8b3b7d1402dfdddca402dddd574495dfc4b20ccdba1bbea5e0b71af4527f93ff1092a7ca08fa6286f5996652903671cc7d32a8a1255123207d5641ce99c18ff77163295a9e99691e971cefcf56559d6cf910cf6785d374a669fcaa8840e7a64c968040008405000831500001800068442a16040302094cdc37a14000d577a3e805e401c48644916c46008a2903186190288018000019299425500c62fcfd202af25a3cede476926b63f2a54c0fc9206d818fc040159cf0a4f6aefc8f07baa91e60ed749d43d2b2075d1742bcd3bb80fa7945c6b03d62f00a582e2d7e383ff660afdfb19659cc6015385c8a50af437bcd7837524f7e494b6b04eac50e64b6d2bfa44c81c8133c6b6b6e73ced05c1a6c24ed55d67c4e793a6a61b9a093193f59769678b8a9688a82c81b1de893b294755e589a146de29e630e9526c64172833fec060d2124d7fa25cf39990a45895a744f0967917d7c338afacc4d92b9f99e2f1427963fb6d07bbcace34e5bdacc0d7fa2d28aa0865e6ecdeb93f5f49cd395c52ea42f19c6a8e88b23f8427b54f294d5953230599815eff254d31dc54b89aec8180f0f077c75465fd946cec4cf1462a94c23935156412b78c13bc3b0c5dceab9ada90ac8ab60db5aefa194ea07c7797fe8537843952fd2c2fcfa626275d37e31da9e4ccf61327d44dabe18340429de298001def786b431a7ce3484191777928e9314ced8158c3ea8e836b83a3ac51886c4e8d470523b04b12c0e8dc2eeecde12a9cc60f7b6ebff74d1b80f0527e7c2677df060728f3455f7a41ec225d68c8fd8579603fa9d283b0b1c37a7e5568a19c1b3586e2830b848d02e99c4dddaca53fc844f1a25075c611859fc4e19206d7511e6e3c024201e88d02ca61076ff5210056b04017c2c22a71ee401e494bd4f7f985fefd0eaa0e459f1b64a5c723c562ea632c58793adabfded5ef5542a57da5716045e64bec5801589356b54dd105eae52abd44ac0d454f65a70cfcdc7553f8844295d833232334965459bcb2bb59dc359b221cc1e6541b33ba8bdd2994ec0e1b34f1aef368c5baf83d472599f6467bc44adc24ae290a6d0b8a8ac76bf3d42a0fc9f668b18bc958f481124b044e07f00618073b1925e58c15c162a9b830bd28f0e61c41b2629abac63472c652f087b0676e3b2d85f830ffd62ac5e22d87846f368b9a357c2249ce95e10fb9080af3a98176a217ff4d3d00a6e4bbc6cb81877c78e0356ccfb560260c3eac23fa2d9664fd88a11e08fdedd7cb6ec92ccd8b522a1d41008cc3c232bb64545679de519890597285d53b2671ffdbcb0dea41897c74d49caf1341b38640217cdb816821984cd168191389176c94cfeb9e17e068949687149e541f57a3f69ca67466f159c142a3af050b1549b8978345f8029501125fd07cc395a18741557f54496a191439f69def98e4ebd420bd64219404b58f3c91af362336cffa5c9eb0e42640bec22829b772c9eede40fd4903d2869df7778f7ecedd5774f4b100e746776a2fdde95ca10a3feb74a75ed01bccbd4516c332926999679fa8951155178a92b9c692a0ff1e3bb012689f538ffd11e70539114f90a13b0da116f6e3c87c8860ea453c91c4518a98921d5c6162d4972b74900ae45fcd8753cc61c5370c9d9e11ded5ad755fe3d0732817759f78221afb637ec7c57e3993e30fd67becbf4ae2db726811d0ddede8ec02734a435f2b192e4c8217c0ec681c956644890b25453d4b6bb720b1302676c43213334d24ad2b627409b327d1bec1ee3f06fcf0cf2811089ca9eb4326473277dc27d2523161c5617e954bca0df6c2a9654d1c3c4ac6719087917a382dc680231256c87b822c5a9e22c8c20d0035e542af3649632d6a533983ce8842a5e13b6482689a6641792c004890c1f19842737664dcdc43b4dc79fe6452dad542b3c48a7ddbf4fd26ec1b3b4be258c89f982de888620b28d7aefb09c469da0dda58e9282b58092d48f7e06fb59753701b436c87777b513159b43ce6aa785751a5b7a13fda5703f485c159a418ef0c1cb98b569e23eb32ad5bd151c5a4f75409c3e966de62d24c66c405825a5caf780d4868827bbb2efe6ef83e3543fada09ee8acd91b92a9b0a426799ed9a2b40bab7a9abc3c5db38cf3fe312c2424237a6ed5cd106d07b71e64f297a4626c30f4afbe78e2325258c0087b639dc9683ef76edc4dde00a1a83b73fcea0e18651830b82d60940785535eb302f5506faa736f3df332b86579a9a462e8880934aefc18270b8aa317628cbd245e60eadf848b366b064eceb7d199d023bf3f16100a7b4247af47512ca48b29a84359047501d7014628363ab2d0c0942d7f851b8cfc5375d3a63dad817a3b8aea4733952284530a9b16fab7827aa40cb3a437d74f5925b64dc5c9ea6ebba9a5c47bc79474b1cbaac42e3d8e96c8eac84225f706d16e113eed66a1b265f84ee753c6521a063f4b09ca749bb03cf7caa3a76c7f69e8b1f1fcfb99dcedbb67f5d3ad68d2390b39759ea25be59ba325308a46b3023a49c08630957c34f3ae33cb446b0b5c9b5e9526978bf55862dcc9afef56b072f2ead393efa23f8971793aca9c6213419acf51fad0cb2b6c17993ac0a27d94827d9e38e3a8725b527595ca7014cc4496c734fe964eddba4eec1b5bc25595712997d68405793ecb08b2cbaaf88c396dc02201d1baad3daa4ceaf59775714fa3cbd06802c95878d0f3431633bf964fe213e9cf56e1cbea79aff2313b56781c3b8dbf7e13aaa0849bfba71b82643208a9f129918a03d868e86987b589aa90fcfec0b7c3c4e4bb58691cb1b64593e2d5d923d4ad3175c5cc0f5173beb928e59f8bb6840abb9f8eafc30ed483b8fdd9d245afff0c2ae7cefa90b6d35de87e1e1ee29d862cd3885499143fb27d970e85722c5c52cbb3ebf78ad6d0e58a9cc5f238cb86d06ddc69ee718b9286c15cb7108c70aba2b3e70a0a23568e62a0943c745060c106e314443933b9a5e18adcfb1ad909891b11eb136071dc8c5507267982866d613a0ad7388ab6c2bc329d5ed826cfc012a76f19c9a3988218e8294067e7c5dbed236ceeb30619a490a95906d44546fb7fd59222729df91a7a510eebbdd71ac0972b124012f970c39b4159582f8f0850e028d6fb234f1244a00d7d4bc171e21ce81ca925d2e2afbd23d4a56eb6a5023d7193fb1546da43da033abc5fb0f2f2bc3f54290fa6d20c8bf6047381407fad8c58c7a92af6d5b0514ae1e97e74670e750a1d0d976830681fcc6e292f87305515ba69d0a87b0f01dd8436d5a65b0d7dddd1c1a4353ac00f33e38446398d9f5744f1deaeeb4e2e164462740eb0d351137a8b3e5d63c9362a538e21928fed3076071d05c96d070ceac4705076eed0a1f266c64a22826c8cd4769cee50b3a53303fc4a5bbd4e210c0d2645487d0fcbd224d63d8a5eb6be5ea590c1893c18a1f5a3c2c68d287343f743bd6d904ea00c0804893ecf34395237e5372b59889ba0c9d1fa2e302d13c2e94a021aa63df3faa3e80bf1eba8f27120e25845ae8358c62998a84a232c5b43d11a4f275bf5aea2ec8c1bab9842ea2614ec2ee030530a52ba9101eab409698f939c7e1206d1aa3199288e860906bf12451fb6a486c9a6c6bbf9bd75fc25246bb6136bbcf4719ebd4212226e7b97ec531c84c31f66904e631171ed4d55c2d0380c682eb5f7b8a837f3b0ccc8dca8ee36381b7f5cc9267ddc4051203afcde2315f9d4f4612538025cee70a924a19ca6620035decde70fbf2ccede068b1ddb27b9edb09e66d03ed5aece4938ac49a8edee848260b224bfd6e7962d97ee60f805d230c8d1dd279911c49c01ba0f7a87b04075784ed76de05730e121c45a9043a483b9a235152f0964b3a2878527cb45ebce69eac7dbb2ad2021d8d3e9178189e9f73a0b671b28a2384421a7aaad69ed778b30e8e077e63a7173e756f25240fbe40ad1e69156ef56843d75efa0742a11efea63ae4d076295fbe6fa481a0417f63b7b1e5eed1b5628f40e3c78686b2a31587c1be4a591bfa28626150f583d0bde714e8ab8c753552a4f6ab55f77010a542cba9d000980deb78a603befa003f74ba29b677d53a72da7eff92310c0428693d5ee7fbe99b32f5d4b6fe01c78a5563afef4336d82e1e2214e2db9389226a958270abe5b7264cf60315f5925058e87bef5637502b2313265f7a7d268c1bb5ada9008fd6c01da67c69980ee4761022d52020a4e2eea3a905fc41783f12068291f85803b834847ab62adc49313ed6f52c87ae37eb8f5204fdb9699cbcd6887dba04511866690ac16199ab8cc8c7b0827dd10608367e664cd177b3758d2d1d3a2bb8e7ae8e62175da57d71b007a244438b459b49ebd2aa139882d373b52acb6852b1bf4fe480a6e351d3a6847ecc255e889ab30701322702ac1f31cbfaa16fdf60526665a88cd1ba9414600720906d97969b2ec9cc8dbea16bb005cdd17ffaa4b2eca181e279fabd82e3734013b7c862760ce382162675d95269bc90612924f1fab6e883ac02697a89a58d4e89f567a4373ebd3bd0bbd279d5d20bde63ff24dc10cb2fe235f7a5c3735f09c3529571ca80b6c9dd9b078fa726bf31555992765c38c5c6480a32da180196656575e9bc1044b9758bce811411fcf7d2f79b2632ba4bb46e4f9c1a949e19f07684770459bc3546a743fc4daed6874e254238b7ec78120514ad4e40858343c960ac18ba84ba168b793da5daa2748615689ed5e1f8d6b3a669b61bb2c0755e472892b60e97f16e0e08557544c43e12ebeff854cdf4a867343e8c32c570b8549879b5f3e323d5efce881b44d5298a23f8d1ad7e026c2df0c58fdbad2a1d1f57286163fd8faf0414fbd9f38be581b686316684b50c2a5fa6a54e2b41462f21a7d503f3aac04aac67c142060662c32aa1273d0dc0f8fb4499947ea15c2d629b125694007e3aabaaad95c1c475def01edc2243c1529e16f86c6bee1cbbcb233b38414f8f800c2ed772f81ea9a89a67405e8db86dce67ac1e266818a31a1dae67ae4f0053697d01f3190302d1de03d40a878cd722ffaaa693647f36581f2b4427c7070a17948e194be98e3eee1b62663f5c03944cd88462c01711e99d943610a93f2351147d0e02f2633a9074efd3295c7f0fb9b3c6c1994c911950e2c2e8170e98f0c85656dcbf80bcda19af36be7951e1d634b7c154a5861e3df779586ad4ac54c34c42e00323b66e1c3f6ce7ae6688a4b7aea13d433bbc017a036ec43ceb13e264e04141a93ddb719f9b3c41cce03eccdadfb9e8ba4ab95dfbd3712054ee8c846cab5f936aab94c202c0a2949f90c9bbb9937ddca230fbdfb10a35fd5b6082487f18eadaa173926a8324017ccf81574eaad92f8ddc70d4585b75e34e82c643d70dae5a300e26ab120bebb5a83c12917324849b9b8f1c5bdf154af4ac99435cb445eb02128417149b91c116081bda59aaf18140ef2bc55207ae028835fa038ca06210bbfb11ac43c50a7657c687a24508b74ed3a693f1a174261006d245692616a5fa3618ef21138a308bc0b946efdd1d8fda64d15e9256b637ad0ef58f0bd7e7a0982f7ef138555a04b57c695924fbc242f4c9acb15afa8416d5284f21424517312199d119dde35c73bd8625e7a54d7d266eeedbadf38b837c9fee88fda35690429069b43fea9282e84d47117a465160878ac87ac67df5bbfa8345a3f86fee172bfff0c0a2184e9914a09b02dc3d5e5f9aca70c70c4db170e68cfa030975008de8a28e2e9b124792d0606fcce338d5e11dc1121afcb516011f4167a9f56430654665c78ce470fa902e53ae49807a477eb9e6fb4e03beea5c03eaa5423744e0ac17d1abc548ce8989854726e764ac4b1c109c490064d77c6ab5d3f9302370a9143a13824f53e13288f9d5b1da91cef3031d3074afd2dbb3cf4a6d7e9c13bae16a0e108297d07e69e248354e6d527f76d9a617475cb14085ac564085c80276dc57d4b6a41031a3feab429dc45e61b3d19abc7582622174e7f81d6337aa97ca672a64d5562679c80d9dccfcb8abb6397cd7f8527c7fbeb5af40ae8e64b4a278b23dfcd0bbb6030ae95940ed9d30f21281fb21abed9ee79ef14c78dceda006d7b6100514d9da46ca952809d4d42f8ae722c9dcbec8f9365eaf22820ac3b907dd7ccff00b164bb74fc3fb8e26ce70e49d8fbd5289cbc4e3198515d2e80ec75eb1f728a6cee7a557ac117f0cd8f189c55134ffe12cd95da9976b9dc750c1b48cbb805f6e6a0e8e928d4cb407eb2da462aa9deb1c0ea86a0a5fbdf9528b5af05241d8519c745ebf80d00271df256a2969e7c6a0be9c8ee8b8bba52ae4f9b12b2c1f7e1f6c6cce1241beec981d945d15d3557a61078c11cf3f229e81f670ab09f7aad3bbc055fb5d2d3d16912d8ab7013d1db96cfcea00e5d10f5c5201aea9dd38d4823f563839eb0e60c862e46d7f228f75acde2270c01685e8994854fe83ee3fbfe42350f4bec63245bdddc83de2640a841670c1e67965d181850347ce1118bc8e69f630e7036f374b6f382e7a6f5d065098bc505d3bf725c4128a4ef7e2a06facb1878d8d2db970ba5d807040a4a4e7d5ebfaf993092dc170719ebfe63cea2f025a64dba471b110192343732696ddef6f38e5fa7e8eac7115758fb971745998cf4e0736073a719a537b3e16d89e999ee0f0f244052adff6fdf2cb6a84b37b71ced93c9915bcaa99f23b01f674cea1600da4f57ed62664d4f120e8da4a1843612b108688b5938086ef15b7e460a15bbc0978e60c7a087725c212cdbb0a062b5d93e5d12792641c4f3bbcc128c8e6ed5ccc0851778ba5861aa36a35bc8fbc4caf891a2fbba244a7d76994c7e7fd1f2cf449613c71b72f16ba0029fb0191e93b45261e64a74832ae3c1ffd1982e5ecb7157024bafd75c1e5812ddc30591b09fd2e72e95fcf45b060c5a2ce914234cb65d1acf974629f98f274ed0903602a73a6391f4f6bf702b8cbd9a18a4ac92b075260403941e4fd136500848f702375294b3b47ef6e78e0499b33e4deb9cb658714d2219cbb93f422d78fa87f17553eba3224871548bf275b646056b6514009fb8a6032fc0e9409750f177df7f303987bdd75cccbab3789b56c794ec7f85e6fb232c4de00a4cd6e03d8ea308b25dc3dee58fa5762708185c82bf88278b96d8e305c9453c5b830103dcee14fd87d1f76da413cb7a8cd30f2e878fa02eae90bac34967f7120a7379d0e0f528db0382a694bfeec64f772e546346ff0170137718ec7d2a33bb4acf155a03f18eac426612784d1ef466f4a258081482589ad54204e5997f3e92c2c1b08190ac78fd80aff472a37ba9731cf50f6c9f56afe1109ad1af84d10bf5ce63ff9c609860912d3b6c06ee193d855de9ef3b41049b757f5ab942cdc0df858e16139267780795e100e04503cf320a1fe06e3a451719a441e40cb9d0e78dad4095f62094a27b7b437232895bc338f5ba0b4938f4cdc406942722940c851e5cfdfc4b93691bd718fd4eaddb71d050fb1c37cce18dc3617782509c7175bd3625fd4b0d9e89606eb7fb2b00a0ed54839804260142eb72a4477fa1c331734e13798affb63729d209edbf4a50c4ca900a98bb4a0f358291ab785632966ba14b57b92ad73e04fcb49e963d07fa266dd8a050cb1d6a95eaa7c18a8c225502e5cf8d4bcccf453f5998aa177e5a5a53130ebfce7c7d7e76ee4c6668412a52a044d6fc987dcc133df96880185254081c738184688e7dfa69fade9376b03d5929143d3e480eb9d3d79c42865384e3f24eca2294d5a8dd6947442cd3ee8c2400cf18127261846273c3362956c65b11a2ad147e658006d611c68fd564d557e73e988ed819ad84c9b5454455adb63458d31bb7d121ecbde3e5e98476d89485bf05aea48ac27112c4c6e1dc68435c69467617ef027f76b7f65ea0cbb34b5c44ca0d8096aeae18832b541f515cb59bb64f6a08f7d8b69314824368fd2f081db48c7ef890c3b7799afa9d2c18201ab1b2202f2e42dc8f672e13f0c9a2be755776c3772181490b98ebe09baaca3d6f4b3a64e93c74803dd2084e34369709fb7f5949c739727af81c1707ff4cdb8dadfc8c00814ae121090c48a9af2bc882e73eb046c1e26b042c46dc3143ad20a78110a0704374546e3884b8640a5b06b57ae60e9600b574d4838281571522703b89a54526930c68a26c3c23f53946535c1d93cb7dc2e21bc772fdb4ab067aa14da4b2719be6416b92c707a27622c55e204b34085a743f77148d6a88972d6c7c3d7b4ba2600a1f59f2b959927ced9917331e3b8e5cf5fb76bf1b2cb3108bee4ff0d0a7d01a882d87e30140c61af2d3212c971f7ce678084e8eef547e0bc65ca54431a0534cff6a4826982847f2b6a8662669b9e48064c6a7e7ae0cc52ae6655518ba5765a7d2c57f4a7c3850dbdb2e5b8f657820f72dc215e34dd75d49c42454afa42b118ba87e195d562e56c346d57d4c2da3f5b094fd492da6b96b41737a2e632500f8d0f67f53414132b3bbf1f17b861de0dbad2b0f1299f402e538ac08b200b901d054222e08f4828b6e9062094cb11f3578de02b4a15db227bd9a111416762043725c2d7a533a518608a0a00ed3608a1cef5b5b0cada9dd7f4474236a6561362710bf3350565a1d7dcef49c17775e161c3a720fdadeb4f45696ab530aad3fd4e190227d0cab95f0ef8553b98f6875b514696f119c0a18c7083336aa63912d980b351313ecc3f66c27a4e61462ee23a0a7303be455d81a6b5140fafcc1a71acb192b30a80b3dbb29d737b67a2238e9c7d8fe553028ebc9726f6391c81a88f33a83dc9e372dae6cfd756ac34336d1cec50485f887843086f90d11b187d6fe9e68062a59a86e14f646e01156911e652cf54cce7ec15d98bcb68b0402c29ef3f8b2ae24669698192896d29aea2beaed1fff9c63aab186ebd93b4557db92ba813bdc8edddcbec07112583da2333f62e6bb075bc12c88f7c87366230b7ee84a3351ffe7952f8c03a0affd90a56745a28dd8f3cabd53a33b7d0e5029fc6af0a8f8168b1fd4364b1c5e2ab7fc0a94a2b4bcc7904e3bb3f58d139c2dc8c5e92a334222ec27a10a1cee06c18a2bdefbde33645c916d10ecef3e38994ec8a8494c2aabe934a70cda2b8f31e1649082252aebc457394d42cbfd0983ff21625ae9a7004aea66aa6c3b6b70817d1bffa9e810ea5599461276c1afc51694fb9357da37fd556fd96de313731a7e92ae2446715380694f9f8f3a652b8f5cda16db33442f575c54c7f42ef0da60bbc456c8a5323a8c410d10b8a134a49954a0c1a6d7cbebe91463756f0a526aa7b369438a8a6f9c8110a68433f6c35097176ffa01fb59786f85ef4b2694518afa5813668c5222faffad826b97ec92c8b0739989096e970b366a2b2fefde632f3e199cf492833be9a54411d9d78c536022ce502ac1deeabbd86a49682275b51ba0e797c18fe92708457230ce35cac66d4701dd7ffcdeb316fe4522f27a3e099653808749ad7d87c7518fa02fee83c10e1067057961f5a4725127e11a210ff99d0f9065629632f4fc0e82ca94107886a2f40a37731c45cf22c160962f3d59129142d642263f280a9571fd1127679786cfc51b9ff4b9f25f0d3da7b2294c84f3024376cc0932069de82f3141823447403e555fa6e04d6511272cf0d2228c98a2749be9ccd2c0292d060e4f2012278271f012e2c32b652360bf6e4701fe2b84adce4a3078dcafc8cb8474215346293afe42439bf02cc3d0da7d92979283d6c8f1370c68f286441858c61fb266776eac6f8dcf2c36755a16f7801bdbc9bac2d4492e6ebf76efe88df38f0d3b87e8c4a3999236902fe525b2db33e36e666635380697508fb3aea391b8978c6aa6585a3b3201beed8a582167e97a90ac9dbc75a6513902f9cc9c80216ab400eaf1e7433c306129641faec246b2826fb711a2b0f5a0d7da4bf0a249e5c8ebdec98ba026563e0b81ee30ba846e42d01be1374026089fa1e58a7f3900c1d04e11d15307900b4c784a3fda73cc3bd8ea1eb81bb8b232613c6fe6344627336b5431e11041e9b5dcfca3955c858101333642a04fb71b99172035d8070b5315a918c639043305f214c083388abd9900203e62c52c9c8c3382c276492b971746b4427865414beca5f1e2610ed5a27e9aa4b453083c5652ef161cc04f1d49c3b6ff5f40444af49ebc71e15de033589e68c5b982e1beab107b85793864a084eb38182c94d0ca268cb4d59c54d93be162f6fa4025baf51eca72dade4d00684ccb84fdee4d5d6ee3e7c85cdf13bc1ec699dfa0018a6e3bced9868757a34e860bb38475586ccb3177fda5b6fdc859b5600580b531706db503f2bf55a7416289fed1c5e877baa0f37871be7c09c0d0ef7b7ceb1301920bd49902f834f0ffabaa2611f08230fb4d2e7fe6e075c0a1765e753b899b6bb6a5c5a779754369f7e4ed93ba8bb5bd4cf7194b9580d8ddb60ce85da4e0bfb63faccb5d4778750f2eedb84bf80c3616f1f8542bea8fdbc22eb978e4a030819d8d705c0c4aaf12ba3f1abe4ea7316bb8a3f94d0e694fce11cf6c935530474e099db288d3fe924b72e99f64aefc04314e637a57454e930b43060d314e992b58148d3fea48cf94663b07f71ab7f1255924d261158c472bf0dcc1630a642afbd931ab7d19d340c9344aa8f4daa86be9bb031a1ba52f730573028c50dd95fe8e7447d39832e3cc2d5aa740196573a802b4b9b70313b173f0d503bad24f0fbd689e06a401fb7771ef79d80d88dc4bd36bd243a4dc198646261176094746ad89fa779a74dbfd518c23d95335cc6b5299e0d6467788452cd09106a3bf62e537faca88892f228851266b1c6343248853388634e9a733005a145c6d46ce45f1921a120864c79a9e5c4ff0a26603e681341c3bb25bbc16fcce7fd242a904b81271a8b07c4c75da1fc39925d9baaaa8575286035fe5d24571ae28c0af6abb6c96171e6bfd9c4ab18527bb2d018c6efac2764855d70044cc800b9ede4b6b7ec38ef28738a21933bcaa25d105dedc687e8b8189650eec4f5d1db1dd32ff0ecaaabcd16caf445bf47d88261c2f869394c525e10a758e30999ea6eae752dc4917c6d1deec71265482f4626aff6845f47be3527caceb76c1153b235776be5e6d2a4a4ae63c21000d750c548477260fe0891eb1b9e9f1bff3bd9de9ad952f1b4fc3cb47d12d2dd4da2e585fa095755e56e2c9b6aa40573bfbbc6f1a0a34871e358454c5c9faa2908d4b50bb10f403f1e381b35c9ebb39d00aaf58374b4917498563dd488e341b7c0aea43de8f160de4cb5c2a2883998f6668a48e9e21d96d04f8f07311f34efa84c37040e92591d9feb84c23f32a7d7ec04f35872b51a8438a9753ce82171e73e0000f2d7beb6f236f2ccac0f548b1b06b4a254df3508dbf3e37aad35604118eb601c0f4a2296ed132268a9b805be5a5851cb76970ee3385bcffde98f07bd7a968552abe772ed5dcbd45946dcc5f6cd302ed6b8570a31f7d356e323f12f77e24141f7fe9c76d60dbaac3683013e17af1318282172ea45f93eda84fb338432f4cc5d488ccfaac24c6eb676c8be18f9a2ddad0c7c02bd7f118d7d49c669fad6fae566fca49f9d9adb279d4b1e6333ff0610e1e253d632e83437d359ecec21d3de502f2fe217923327761663d93a7c80ca6c2ce5993b71088ad7652650605e8d982beb012c9159c317839d61d64a9be669f10e85d98d582c2c36af66b5bdcadf66ea4de334682d559be1555348dfe01e8ca584793797476d32eba446061bc900a050bbd3676c3974934f974a10d3dafe8630fec658cb812e00bf7b81586474b0e25f3309bb501781506e676da8086f2924888cbb7ffbbbb9df2333ae069acbc92f069e56e916ba901b6e9d82067a262d6700f085dc5a802dbe0e99697723cccc2e77526c26f15b34efd455aa20374acc9b6114c6a64e36809af56de7f30e72e3c1b27f92f1ffa46ab97bd003f0ea39ee3e75263c072aa9b567572814d68a0671fe698c82ec6003f6dee5943232214b76d49e39151f3069e13c8a378baf3b4d1d08e0fcd63e09b8c333703669bb65250270f60642dcc63b0eb78bec38955cac4db336834fdda5a419e9352c371372cec4f59928b60ee5fa87080c7458df60f82162acd52c531970f0e3a8394d1fd6ad860397afc96c67c400ca3f73f869f892af4b1a046ee5ab321e1f65b650a76e2ab4ef6ad459b23600150b76b800d6d88d3b36ef11dbb710024165580b33fbc125f073b4e6462a4d2b1a58f4ac0315a3b5709f7624e63a3dd1ba468739dc167c3887b3a9ddbc456e12853aaf91cfc9e2a2259cacf0c5794b6ed9f3962840f5418c6b772cf0724b6d6e3c3da2ac764d404d5e308313cd56ee1f455c5f79738b885cd5da77ad4a3e8e2b33995aef7c456d0a7f5792f19c840e0fd9b67810e2f52d7f503870003c3cf4d7508d50e2b6c55e5b93849ec62b24bc929aa822e139c9b57a6df12b4818a15622cf075f32e9eb4952e6bb9510c109e4608ff6931025cd02bd96d534175587fc4d3e281ec845f68dc2aa060e94465c30bac79c2f8bab7cd2b096e3b2ba66c8f9b18ea34813e2e172bd55d47ef937194cef571262da86eb9ab5b32d1a317e196499a093181a8ffea317296b928df806c3f6b39d64ad6fb8fc8a78b16b1da3275f280f95b13021ea4740c91bc8dad97ad2fbb7b6b2787745aa5a46106c7edae4f062cf1254e8435b535f477dc9f150e5488c20d88f0473199146c83405bc8b5507814d8811dd049c4430bdffba1dc7727fd5a25d5cc547b4b36d52a4b4cb2354dce4100ccad5b59eeb53617671a9c6bedb62c6ebd901743dd9061a73286ca38b830deffa0166562a5b61fccbba29db1056722ee328bc16b77912e85b3d807c41b0d4956d295c6698e070645823240216abce102d212b3ce13a24ba87c5ddd6ccbcf6238743943edcecfd462828d7c2ebd3be4af91e738c60686a334beae5266079160d4aaea3cf278132342a6909cec0090eac12b2eb41bace7b602b7f4e23a7eef8ced7ce0996b3b9891bb51ad6f799985d6850c0225452228c159eec8056261ef2ad00d85bd12ae2b9c5e2642bb2606f092c714ee3c9cf04ae1e4af59d0e0213975ff9c2de2281884701a08c2806e3e876851db50256794bbe278afce23a36d95b7474a3dc80a0f7b6f64ba8d3e82f15fe2ed04432f147e9180561ee837ffec21a1a13bf5e304d39bfbcc6b0c4aaa71b315a4a0f7cd437b090cc280ec7d860fc7e6ee35315ebb906138ec05457f98b36530933e1d391c424943dec3701995ac57221b8a2fcc90063d8a8d12402561abfe833083b300c6bef70d9d53d1b79eef8ad7a91b95e7f1d810071fc6dc24d44f18e345bd4882f30d4d186a09aa3cc945293c33cdd60448b93432aaf85651dade7d436ba4f0e77a8bd038eddbabe862f7818be49d9816b3316eb08e47aaa6ad756fcda54138663c37475ef6184ac38125863b4066babe67e3759b7523fd551df3073cdaa10e6aac83c075303947d746e0bbe7c0d73ff5844b7d15a45e834601395651ff71c1fc2da244af3131809795685e3d11297b38f7b5ccb9b5663cc2aeea5664959d8d65bf9daddb1b2ddcdd87b2895b241a80e22b326d3563c80e56a769087346bbb94a9fd96c989f158fbe28377ea9f6b55684b4fbabbd525399ee01a086e08ff5483f33ecd062dc32b54220315d99098901ca28b3403e0f89a07a893d67278a02bd865366f915f1dda5a7b2c71227c5314a1bc59e8dfb2aafcf87e07433d25c54e9b95a526067e95fc40b6a6fe4bdfeb78f4606c5ac4ce2d1becc716dc2c987fb919d7cdc25d395f2b73d54c4cb6fae1351b928086be2694bbb87e244bfbfe15362386db0016d7ab02864a3ca2aacce0e98015cbefeb3a773e7ffeacc296df5c579b3d0f07052a1b9f48aee5f12ebda73f79b95031bd48f223c4b638f8d4eee87fb1ff9cfb295f2977cf8f269f9f93109573ff27ce7e99b8bb31d79d9ed602181829515d135df8744601e8179f043a86fd6cc057b06fef9af34ba30168e46e553c5b3e0fcdf9921db8a1a419f6c7babd0edad46408b9b270e863a32cf896b3a1ac7f25992fdde4579bf7e95ee1cb161aeaff8af849c32ef86009005829537f0a521ca54ca16886c3fba55476b23068d7a24bff95c6660dacea458e1006fcc4197d6b8bbd20b77f6b14bdfa37c5c495a6c5b0374f8bab7622b56039fdab072030eda1ce03d6a1330e0d33e0046d4a70667c273a5c61af4f0b193b896c5fb99a68b26f0a7b442001ab48c9e5fc04464eeb386d3947db3e14a2c38c7a25186e75330c5a816c210b3c65b43a6001f358bc0c6d8406832c32ad5a3002fc53b65f49ba405240e31b314f5aa1fa4dc9ee366fa7e0c4b4c5680672a4b709da37d2c9448ac1b8a317428590dc47429ae841e25d718682497dadc2044cdc57540a0c67e6c0f96033ad7ed71b48bc524a129c0a4e0735a397cf0e51e5765f56279c2a72d0dd1d59247f8abc64ca5d0519a691b710c8d5516f27b1cc6930e99243c1971c65d27414a9c34579269eb13b7ebc4e999ee7cdc39dcd3ba037af9eda42ddbcd9d882d2e816f85b6e7bea388e452b75b7841dd859f25219d08f479dde74cec802e86c81624cc7229137d0979b3ee3342fb7f949b9ae9fe467489b7b756bed08764e7221da1abec729c513bd42693470f36f84c8205b9e793515d70b8618bd0398b6ec7599ecd8c4995e481770d848d81b6a1d1384646521155f28833fba10cef0e603ab91a2ee3e0e0116b3a7685f474d41122cc947b33199d6262ad28b06047715a68ef2c94b329b38ce8d9e428e894c0197cc66e05ef783eaece0221a2437bf60084749f82e3fccf9e779e129c49f8ec1624134fae6852f8bebb967691ab790385e6c3aa4a35b88b9fb1c6d167b26a43e6d10c3ead4a79a5eaf8fb68903bfc5165311637b894a16a9c34eb438170f69ca781d6885d6a09bbf8bf0dab88a38a34f75d0f427d33b3d2a796156bc3929b30efbc1c1e06e226cebf61795a52104f5f95d470534bd0bc28bd19457a79a6649c7625820554d2ab695f80ca0c708f0cfd0e7d59515b81bfd9b0758fbd2b9d7bc1b59e764466416c7ac1cfa87320eafb891d73ac579d984a3a6d41d82e671ffff9221b7c57edcf2187bb0b2db16e0e445722a1dca40c78154dbcf7536cb2527d87f4d3b56604b63640b6b3978bd10af4ce70d0608c4c66c8d6260c8c802e26c4df85291528d6a0c5097424aa31a680df5ec9a41070144f342d30c5d8a4148283cfe5fd74a4a5be354baba5e725078d7d563fb4939b36681cba48a2ff5ba201ae93347547f696b5820b66e436c0c2731d895458878eda0d6d6e440d60ae1dd3a5d34e824b9cfa96dcd69e8329237df73cc6d8be2becee34b5d7edc53c9503a44138031a9be24f935b8e3defe95a8abb6540499a91385d55545dee69321fc1272d08e8ff0b8fe0a17e653f0254aa1f7fa368c6d4d5de4f29dfa8ff4eb976df7b8f554a571b34aa371be258ac0bd21078f044ab5154c9aa10ed56668627ce492905a42feedbcf234443820730740fb1ca9993869643364dbf4b4c6ff4d92bee72e44fcbeccb7f731f85d23195fe8015f0b5816b8290fb37505751b8868c5365152005b97705289c65e7315b5b69f76193c4f6dbb69fec77be5f305bf426917c0249982589d14a620c0685b22191c4a6365d17b8f92b7d3ca72c35f42ce9af50f627b0029ade625b103523a367a696014f20ded1862fe0e33ccb19092868b48ebb4ad43969951db46390c6940d8c8e80d74367915a7780044ac04df259b3db4c7dbeba6e6f56dc61edc215b69b283639aa5981de21d14b8a62599a0e59538442442b2235b090a1c5989d4687fcc93b9eb0c22ce8207fb6a0389ba0870738319a125d6326332756fe54bfd33f9973c0c35e91490469c317536ad3d848c878711dc1e52952ee89b32f939596fadcbd27145407313520dbb32e13c5229e35f9b857cd3d4604a8bbe63cd4cfe9838774a5d3a72063812d1b66e9fbf1591ea449964d4fd451e92f5daa1a5fd6e6e48a21a4814247ee3ed4e763511169e06f9c197fe00ab271b234f27f993c0c8011d1401b3c3db4754ce7a3ec6be141f91efc5a2de8ddbba7804f99987ac9cc8da33607dc479de58405843f2ae6ebc8533efd97282c32de3de3e835afa38d634d1aa87d76a9ebb0801e421959959cc34efa54b3cca73927fcf653b56de764a20564f4feea9a7a7c2603fb351a5934b33c0a278a49cf94a7822a52b35c4d70899e6d1a0e7b384553f4416387808b62bf3766ce0eedf077fa364347b031024044b52034989abc811bf4126830bd443ef833e5d92f47b1ba082a6232e46cd3ed6dde994c71ab76827e18550cee24921d0f157683a711cd58ef8afd3b27bca1f97afdec1eeb2ee009d895ea9dcbbc99c3657c7328ddb9258c1a347edf58200739425ab30d9c1ae1ff84bf291e616f5b16198da5f74ef9c1aaf881ab447b549e7ab1486cbefe1ca097e79ef0b868d7a501c64c178a7756f7547286aa0dedad17b2bf1c4d8608588dea2b765f6074d57e54dc95030e1a8601650ac749c9395b254de1a79833ee153339322bf006b01e7a43a4b15441857e808593d775c7a85587b56937194434a089469f741a236258cb04a3d5dfea4079e9fcb2711a1dfe68c3bc22d150fb499aaf431056d65079029454728b086999864e2e7fd1f968f72d37ce77601a727dd182715de56e0b79fbc661e66c289b0ad74037a5e536958fc95eaf2c36ea6504917550966164b5ebe2e668ce265135ac4b5c949f9fccaddee62f3d9e5905a91abf536bcc029b51dbd38f8e01cdd3c414975086a2124e23ccbb19818680b2d896a750999a9b34b826e45b95977c74981cd0fa9a64bda3fcd5ca96042f914493b8c8172f4e6558594275025dbc90509b84c5580809d22cbc017b9f923bd1c71b845a928bd91ebe31a50af6e3a9f38d24086e0f3d00688c88cf8b4ad315b6202ee7cb25674e5823ee5f269c7c281bcb207ac90438a56ec79a5cdbce21861819b798c98d326da3c06644a4870ed890150fa72fc24067cc40d02d856ce689b315b63d1c92a1619fbd9022bee6a94e88c25209fe68446a40b229005f70a4e45b509bc78fcabf4b0995ccd9e46d9058ee6e0acf26349a9dc36324903bfc6001880736541f402c5d40350d0e331b822d84ecf43295e28bc7ccebd75d1542a6b137bee79bf053816251ce6ce89883b1918e6f879f1a51324801c53b3edfeb759a41730f928ce53d70eb3a01608931723075b9030503eb38297d38f3b20a444952e7c4054a0971ba4cf911ccc8f3abfa0dff23fd170e0cf0ddab25f5ce308178be9678a6f7aaee4b1ff45bbffd4e1fd85d9fe92cbebb576bf28851cff3924e5ebff27c1fd184c37d64fe767f71f492abaaf7fc96ac23cb479ad16c5bdb4019f4c84fdf17fd2ef546278f4c27f937a7c1bf053772a53be0e7886572a930ba9a9cc55be9190a61a23b51486c4e6c901dc17a6eb4e7626fa93a7051e22163f8d34ff8cb2f151fe5879fc8ec3f09fffd50510b52cdad8cad8f5d317614a36048f3391ce800c49bd09bb91e90f47091f96fd59c1a5a7dbf47ef884e14bcc756f59815555016fa8cc0dc3fdf9de32af5f64ee14ff57aee0a26cefd51abfea360c8984add837d82b450da5cb2cea355f7fe47b63fb196b8bfec78be2756ce9eec2cae5802662eca7f98303388efdb864fd1640f6273d59cf1f32e1d81fcdfeb30e66b9cd800f5a33eb1f75849a41fe574d2c5f0d4e0cfbbbd35186c238f2a7f064367c10594038be2e51cc942037a7c5f2b1a6866239920277ba1a65e7a60c4a23912883c430c41a09d8e62aa53795cea2cfb61624c836fb879a9574ac9ef68bb7fd00b5f3ca7f94766e9c9a7e225502fab91b99e0b8ed631c1ceb84ddb012b8e93836fbf77fbd56001b1f8b18b61a43872df64e6a94bb90c13e32541878b96ffcad4a8ea41924ef319c0a65e6e068b7317be246a2d1744682bed142da46dfcf04fc1656829a733f092bec40124f0027eea838a5409fb4e1fc1b8e1fc245973fa6c53fb9a9661b0c0f9e1ff7536a92488d09ffa3c1b5a1f0a4cc7fe88ab0960d04b17b4d8f79bde38f0b2b24f1ddf30a3fd75b853651b4e73da1c840a1f0fee536fbabb213292ae7b1ed40dad312024338167b60528609f15457ae7b6941e8ab01302c72f6db288ce77f7161eb35dcf89bc84d70d36ee6cdd0ebf1c6ed077bf5caba58ea497aff1d9b3bc4cc9802a7b4ccf2f125482d6e0d1c6c4cd9b43fcae01f82c0562a8fc3be3fc2e534e939fcf2aeaf4aff5b0cb7aaea70a5c1480de76e00c2b35b3a205851ff1265490d126f0df0614250de7dd3bee49b0b39e673f2e4a62cbd0dea0e1f0421cc345f63afc80dbc51d1901135342f71aa1d2d5862118c869d050726d2ee09fef3e1384078a916accdbdc7fac1bc9e4042fa26fb9fd80551a75c67bc8b28c6db6072d070f54dbbfcf7bc826fd172fb42ca356cb4c4a9761107e0214e95cc482d756a342d66b4b6618d976349b25b263d2ec79b53c7d439cb1bbf8a68d0bb0ad484246f111a908c2be6adf43360fc50e093c311deeaec42e0c5818aafccc6c815d3244d88999daa4257510c34b43eeebb2a608b674e2b3bc4c38ccf2659fd923c0ebda89cb2d767b7eb9dc727a4899a605b7f5722bb8882b280ae252dfe0a925dd002ea5db098bdc349b2d9a57d21210eb44c4f9961c7f89d136fb095f9e0cf685788fed0e2202cf27780eeac7aedecbd2568d63627683ace9f5b6c69d8391a6a2b61d18c967a9c050ebc93950dbff161e59cd6f843de895d14f302161659c0018c49e36cb7bd39bb81a8eeabbc06540c5933db06a557a904a3f9c56d9d0786e4118e1b4b53eca846ae0212f930d863b8738af580067a3ee5b6c6ef1a64c1c27215324817ae8ae9edd62d0af33f031de707c06431e6e2de6f00edd47958444e5e7e7de3da0349f4670a6aa1f38ed2300ac7aa606d111080b2695042cc0f434870bd3bf710cb5255fb557f71ac6957f04684ad49ac63ae19987e04fd0981f4930dfafa236c39610edfc18040e8fbd7afe72dfe70a04597c197fb41d998c8449dfef34e650562586b6d09a1cf9610559311b157de674834e0b051f0faa74b196d14074e5d78b5ac6fb2286efa45a9a1d1189ed4573fec3323dd514af5d0f5de4e4affc147d2af527a69fce7b5376a90a4d86678ca62e56f5cb250fe3796fe02ae90c4865677b9874c40ace6bc288daf987dea8c841964cc37dabac6b5885e52234433dd6b00525f3dfea2beebc068bff9f6fba915231bc603b87d7a227dece951b89e2c2057babef5c57559efa59b2f7677e183d53e718e978ca1df9137daf4359a884937b40596392364a48fa217255d2180817fea2d3eee3352533e66b8c561aac40a0fb33c0044280c7059dc11cd783222a481a0cc3cd85d985b13ac204b790a357a845fd1502e9ff07ad4c1b51885e1a2a374748c00af687576219f57b49e8521f7e46055b6d1ca53111570d217560686c50c58615b78c04c1e217d69cf5d5966d6a6fc20a0b5ad2d5c541750704a9a072628af962b36de467b563026438d740341e4d359759609402c1935ad60eaf6f99d06b02f8781af16b0cd381e06f58745309c882490170d5f546aa9221348173440a0a8f755f335ddfb2680a1b6975d95fee57ae0990c4714abcf53f2bf79bd03e8a8e8b09489dc474a958b10e62c9992caa0a5e96853d7f2c490eff718273224720119c453ae3cf13bb8b151dae622a1406ec6d2b00913c26423f6d3ad5f16ea1f1940363aaae7c989742b8530d7ebfc07c6cbee8dfb1d7911c91f1b18e570dec5182dde7846af6ffd200231b46629dc0b791cc674c0568c9e4ea6b8f86fe1ec81ef7ce5dfd505b78d36764fbd5d17cc2e357f95e38e885c71d3c954f17dd6209ca7d83975b9fbeed37dfc13966708922ff9e13ceed8baf7881c543790cb87f5d2f80643703c35c84351cec52905dffe9d645f08bede8eac7b3377119700dcbecfe8850b0d07b1a710a90190b66965916bace8ed1d34855886ae2e0b0ec88e0f50f61730a87d8a062fcd810156c26a3611373454756110286255659fe2515023ac282c454b70f80fe0629c2a5353b1802d35e33e619e4e4c06ff81420ba10bb08d31ba1ba20e252ee90ae239cbeed027d4af5f06cb7482ccf30bc254b19ebcacad8b580c44206ed0ececa6682e8f7ad65e77a43c663103b3dc23cfdcda54e48de000473fe9d6cecec9bf20dcd05e7b32b3ac8b71d522029809e537f61b796e185dc8d63e700f03c07e997dda89672a6e4f6eaf9058f0fb884ad6a6d3b8bef13f6fb76da64c2c90233b4455769bb06b6f3b7a91dfd753c986ff6157f6a7e653d96fd135e32b39aadab067499268eb8650fec8dc0261412928500763aaab80224dd009827262106a2c900a6273845a42bd3d07c5cf9f21138a82eb3b7b2be3b7c264ce752edaa35d423eb374da021dc2b617f189aaec1a368202bf297fbb6011ff5c0157e65cda8750b7e3adf2536720b8cb94419bca4a4ac02de87fc9cc95c1f64df8f02ea3a05e8fc19f85d63cfda3c9257231064f9979553bf202ed6582d1dcf75d8ab168ecaa3860cbc08f1f188a72fc24754cbd51fb5fac4f5bda78107b25d034480fa370074ce14c2f98e31a6340372b6a85b2dd7d1c10b65872871a8c89bb5b6d6291f1ee8c83118fcf4c6876d2cf246139e3c829f00c64132065c272dd26f5ac72cece4568586c93564d70375fc7d510ddb0e60f86a1f0adf11ff636dc17f622a87faa8226278d1085022421aaee77122a234588227dc00dbbe8c6066c38cee9bda5a9e93c8593b917ca05a114fc24e03e5775ec6095f9036aadd1e386bb00e4272617657d12658342e3426bed1b2278c556ded8d22ac052084371a8558bc01933caa1188ad95843ae00892f1479aca1f8e0c1f94654fe6a8e966fb04ad38c19ae7398c83f0b65d8d28d656215ab5ec576a3b6082e9125ca956472edcd6a12502db97b0bba51b225cbfc2e490961f3f3fed7880fa08b59aa3175cb616083a360c89279efbf5166a5c151d8d7993aa16adc259eaaef8c919bb1881ac1a2c0896bcaa74d5b72bb06706a6ecabaf198a65b58b72209d2378b9bea7a78b779289c2ec7254d75c3544a945e6d79cb32f42bb8a4f0b00434151163a3a4d593cbbc6426d369380a067151dc55c3c44113fe7b1e8da9612806087161ec3c75d206ea41feefa987d925e7de71b401fa6bbade669e311a6bbcef828393d468030486ad9d006611fa4aabdbb8abe9ba4aaeb9847216303cda8076fbd851cb33055574b202204a0c3c2c487b8dcd06b37c294674a88fc99b45c6469ab17d8585d2d106407b08eda019babdd79f360aab765d93f407d2f46c367854779e40c571bb6e430fe9930201960b2bfc186d20616637db5bc8be8be444fb7c952140884398ca66b1e00319a88c4f6b36451b2c899e79d3f4a8c5d5eafd4156c28b2ea970200342957ad083f86c10fb690b3b74464bbdfee0b301fbe685ddd420971c29401349a7a5e61a7472f3e2e6d676ef9ebbe86ee1cb50fde19a33ea892cc59b4222cad73022a4a917b128a7bd6b60622979bb85b2556ad77a382574afbcf15e4265c35577811ee9148a5989c3870370ef610b364f21914145a5122ddeb6f87950dd87e3c3ab69dc869e68481ae43b4fd0b36868e06a391770e823e6ba442b8b8453d80d2c7088bd6aa039971a91da348582c4e51fa7eaaa558a09d72d0cb232b291826038f626a44e4d0463751c787c021f6f0ad2dae04ca9cd1aa4d2466026c8622499ef7346d7fccbe7490f2d9df3442051dac959c7d784330b081fd3736317d2cb69ccfaa5f43e554e348a07c7a095eb4101278aae78b6991289f71e3a2357e21c2fc2e0e793a206011848c528fb79c64f53f219d9a6c5b81a1650908ffaa9dc7e9d7ac07c647aa10b15a8fd9c31be18ce4aca22f00499341521cf195c24a79cd18a2afb1a332650ab7802d8d1fe5baf5f42471019d50091b5ff0592954c789db462c19ac469a16ee40393b308b58e6f35104913ac56f5bf340e7a4d0dbae945c56cb7e0e1d9566febe127029447e204513d76f5fdc4a470be7917d9e972f0e2afd2430052b0a9f4a2dd4669f739f8edf1917bcea9c4ed0079fc420fc25f83879e54cfe90781411004cc33676ef018a598ccd600acbe051a3e1093ea39ee4d1fef0718bf9540164a5be16a1d48fb887b09f902676f91636cc4d9ee83a4ce38032c88dfa74628a7b1251732d4ccee2cd4ccb1ccdd36111bcee342406ea787c79ce397508e5fb2503af2b040a824356724e30a502179bb8c6a336c3371d4fc658935d4181f5c1a793c8f89eb10cf53ba5385894efc739781f1cc15a12f910dd0cb5fe0430a9ad4ad9e4569ac71aef71079484e34082b2df19e760f2a821145f0f7048d6f4146aa939984803a547d77255fac21e1c2ac6665f153400335f81a60630f396225f3e2c7465cfd14e6760b20e9d6edaf1bc6705f4cc8cf575e2c511dcfb48c8297d7e946c67bdbdffa73a0207c97c0ab0e262cb5a7c0b733a4bd8f326439cd44a81de72989a25a3d10853f3fbfdd1650b725039e2c57eac1650f9b10cc4473dc3a04ae8f4c4dfbb087ea1c1308b2e0fd02625aa1b514395d709b3aecae19c0c31c5d4c0283126e959efa474bac198aec8a1a6c53052b04857520e8bdbce80c7f34beab607e660bca8bb97ff423e8d1dc7537b1ffb2fe2a115d15c5bdd556cb94fe4475856c94c9e296ec990a240a0d331fd0536d0722cebe172aac5afaf47f25e366b9718e26bf79987f9202a9c829c20745c35d6c2e852c984ab202a6d556dcbc04de62c74ea6ab2212241bafdce3345136362a721c1c5c2019b6718b0a7e736e5acc00333d014d7ad6a56d040afde47d361f19c93947b37c97e24d47655da3327a9f594e46c9f43c58991718232130a546c03cc0c81ac3b12e2361222ec87ae6b40b951a126ee409e849cf57c5d66555399ebe38e0b95e8b2020b79363c5fbdf73e0ddf2d0f86165ed56acad1c83ffb6a1192ce5941e28d3270113c5100fa50a1ce683430c4301531c6e7b1de339a102f4b0e6b6db4f23b16b3fae68f4426b151783312d294e22f330dcedba593582e6af622e1fa298f97de5d2f9be1593b7786e33ecdc2a6ea96b036d7e882fd37e39681fef2b7c0ca90f464bff5e2a1933be6d8547859e972b94957afd0d0695ed206fe0b75fab9f04cc21ec242fb26c8c09024949feba9f5daf4012e25b6deeb4f25ef105f223b0c7d71fbfca6d43f5663f25c5ccf86c15670b0434c33bd77cf31563bbc19106981a6557d2e29088d67c468b07edd397aa99b1a6424687092c6ae79045722b4215280d7ac5f07cb1180fa0c91404b1ffd0c0dfcf0b41d1dfbdb1dc6e2575ad61f401f1f71827f541f9cac859a20b6e699450c1813eea20903b01bb8c29c003e2a4fee05091ca637f9e1fad0ed0227512a2a36bd7e63aa3f66b388bb52611d2e246c9cb591142f0373b06edf2c9fd78b7978f6783a1a7f090bf18bc5fad13bccfdc237bbf7cf2512431cc7c5430f313f0fd7d4884598b9cb2f8632099dfa4836a4a99296f0b8a347754e78c3e08ca9216a0423366b4e3067e76da5298f5aca1827f1d4bad6f03fa2db26c1c2349f32c0ba210bbcf835823c8c420880a0c8ab1b4824158d21b1cccb65b6167bd85c21dda6e3e50bdbccd0888b10144041e8674e3036d6a178b31d18ec327ee9a943954383479c93fc21a8fb543065b21654a118c13cc0f2c34c7889a633f4904931d5ae0d2405b973605be9cd9fadd91536d990f5974d7970239065addd0db7ac20f966b58c0cdc9f814d94e6ad31580f27424b7189e1d3b7976e03d52238ff767396e1c4f92966747657b04611fd9d63fe2e0811485ce948c095fa66ae95417786cb8a647c6074dde996e4f96d5200fa995f495de60bbd321bfd2ae379cda28fc82506666f15e7672fcf57298bd7c4b90f62d4ff8c2c8ba5ff6d285714264c6a6821324f29d794f9c40a74abb0bad2045c327a35cac25c12a6f60f64e035be2b0b92fa2ba60f9e53e183229f99d0b399168174bee85f673526349e43440e568724b72eb475515c35feecc644627f181723da4c27aea1a9d9eac2474b71bd45675dc744506bfab468cf8a0dca0b2b01c517c37ccef474b744b3baf5cc8658444a1c87c849f550b08a2612abaacbfee646a1bfb6a41759b1a0b44c0de52b38311ac897d613c277d5efcd100404515274294d4e93d9c1da388c9def1ba4b5fb66c18451f11eff5a5e4b25f62257a84f12aca9a08de493aadde18408532f7646c6bc75071a17773b2963e8863a8ad04f10f1cbb87670858c9773ef6195aadc4062e7f996f310e0f8a4d4aec1a157e4fba89a2646b5ecd292a75c1106a549dd58f3835089d5b00e074a822f49b00a10753b5bfff2b12d574d4e31daa9faf8a9c348e65b610a61d3f22769962ab6d4a853f17c532a59a29e36f93ad5c9db2ecae4ecb64e59a838b57e599d04719246a41ccf12cd3995bc7766229488946189c972b15ce6cc5924798dd989f05db20731dd2d2cd1f20a94c1063bb75b9e4832d7e84d6a1a4de7573e5673f217bab3320e470ad88db461ef4a5d85e6f00d782b8db003be0c420cccb532a782b8608a898f451c96fb7b92f3129d7a458547f8a928e373db2134f70a36f491a42164b162ccf162496645d1d8d9c4158ff59da588825aede81c172a59ac534ddf4a873793b168c1aecc059d8b5dabe17a2b865b1d32d0dd6ff646195ce9e5f07f684ff2394ce5f6e7f449b19574bf66df92abb02ace7520c1a4444789ee12abb63d8116024c62c7abb87e640e79ef8f18d96462fb8dd631a940e300c2ca9ade500ba0aae6152183d96bb6403537878613454272ed7867e19cf02678358373aecf4b66571b0f83f850b5a7c652e674ec8269e56348e02be54ccb12db18cd69b23767e7269993eeb8d8c5279645ca11ccccd3d2fd1da18d5afcb718d96750f6bc590184d1854c8ed27ae2798207ab7c2a3ae29907e1eff4235f7ebe8040cb990a7051891757bbc9593d08699c76d50ea016a7aaad68870448f34eefd45660204fa03d463e1c6409860edebcc3a27cb4b508ae45cf2d2acfec0d91f51c4fbee0c1bfa261c1c47d152ea3a7aff3a8f065a3e6b192892faf85a03efc5b5d6336941fdf590607ef8acec096c22f39fba11a00f6672fb08ddd888788025d740039f11758817a72c055ec1889daaadd3e73baf9df1625a0891e750604b302069619fc0036ed6c53ee25bacf4ca31e1fadd68c77ae542f70dab8826b00ed10106a541f99b5f54a5fbabebd0d991ffaa927fa78d560add28fe08fbd66145349c2e2591ee4aeb1dc256fd4ab7352f44310240b89fd3bfdb9d289fc9d437379c36058bf256ac3a63483b4e20bef9252c8484766c03d68ae5acc436ba65662a80b8ccb08de04fdb449cae5ce49c4319e60f5ce8fb4972ab858ad2e602af963f92054348b38249379e1ffabb2df5b9c220cb702f92a7062177efe5bcab725c5e53943dfba69f310f71d429d497d96ce300ff1bb5f551f305fb3492fca17de04273f2bac0194baeb838bb000d2556aebe7d40c31255ac6536af19b34a8a3a040718dc58f167d3d16551c87a017f87647a27562ef4830a5c0430b673508dd90c55260248731939ebc4bdd7abbfe6e5e081fe0009e79371a580ddf7e0717cb251225f42b267a87b675ddad92aaa3753463bfd230b8ca0421a22e61f57bc33b0d0fa1a2524643ea262cf51251f016a331f29ddb3d8749606f57fb6584b77cf6b90f742b7c7b4bd0c0161db3b173bc0ba93a8f554e5f09caef6ac7e5139112a92528ea04e0be8099047c3e640f55db57bd8969c0b7b5a99feefff4d60fb8fad07eb142c21c519129a669825994fcd0acec5602c9d0bd3b59470f8b43d8c0b730eb4b5dfdef619b2c01729bf2d596bc9125db0774e08a742d1a6cbc53f436bc485b1ba429198ba7cb428f9bb216e6efd17b20676218157afef3f81ed0734e471f72d90250c17a8dd75614ed910756f64d01f59be57060ab23c484d8f196327c48346d1929ad0cea5c8ef4e918a2584c625ad33ceff46f8952f4d7607562ffeeeee633de6d7a2fa421ef27a980da427cff4d45f5962c1a70d6b89b8ad58852aab47af230092d01cd60c98321b4aeddf0027da7273549306515d914fbc4ce5cd25c43ccb5ed24379381801557f19e1d7d2e14ee0e256d89ab0a422915727d16cde6dd128d9d03d11b51d5c69d7135534ca6aeed8e5b05881fadbeadafa458af811c91757f29e1cff2a0c5e12ee76c5f5ad9e80c4d7798fea8bee7b8a3dca2e66e4ae3980c203378dcd52172416d9855a0d0038099755298a1ae0f0b86acc3392c5eaf17c71bde76a3e32f3963e470ae263c00438661afe371977a22442d9b837b99251b354b08784bfbc3e21cfc5134a2c68a94bfc1b8027819581db89aa3763b775864d27c978fdc8746b1ea82581d063026a2ca293561a8b1c0decf1076a18aa4fcbe73837f959b7ca8216874b03103fe1a43ec22340878ea697d5d770bb87ecabf7d56bace48c11aff6a9b08309cb341b7539e3c707fde42f72c2166a044824360e24638c31065ad1b82692c0521a8871ed51ac032dcce313f6510e0a4160ce97a3deaa8e68eb900d87b7c2726ef86962376a7e36186fb9175607a6aacd97b7c406c367e85bf8f9a6355da3e167b538bec7bd541f191b1d2a0176dc2c4832138bd293b54c93dededf8410af2f72e0e37c4e033f3f8980617a9e2f4341798a5ab15a798d1660d4028dee75adee4d0af74649470a228571e9d94b594981a70a84916add37da6026c110e9bfda93072314f35a18f956a49698bb5fd8d12cb481e51ae5dbef7b5e53222c570be1f9955b4fc03d825b4061e195b5ffb07b9eeb3a750f40e848b817fdf24694282d0e17fd0fb860811cbc7565c19fb4592545b8fd971aaaa25aa548479b6a5babdaab57ac836201179f129a1333f085388eb3986fefd370dc56b88265e303ed6c0c0c53fdf443d9502d28835768ec33cb110f7d9dd9ad3f01c39d6585f8cf0b5d2aafd279c421edad415dc82ca599c8ac29caf5d6435e8cc7f9a52ed4cf5ec25372c543812469789f28fd8d8d96072da1262fc9b892ca149acd93dc58f18fdcfdf45728238554a64821c356a1ec56461efa9926f4a5e509b7715c341f4eb15237c60eb4c7e2b41340a0450b4d1c0173e7dec2bf4c0a7248206192cc37916e860be965b151587766cdd785fa005d0b20b2357bf7717ef8e240c619e8aa01c627b16de979b3d56cb8191983cdddac1893911d6b4dddee1591f6a01126d65a492b11b074415e2c07590dc3f015c1182b92323d2ef456a1abe24fdcbc12cc4f17b7734be358be389844cb19537b0527a42cc7a685c4bef8e4fa2991f0bebb45d38ba4f3f44cb51b3cead60c764fb02760c51dee1e32a3bb671f67585322e23e86173630c0413383e7335d77df0a96d0ad6a6161aa14a4d4815a3d7f6cb74c4337da781761fa92a77e06934966e735eee1f9340410151d5de5f0247908ac95e60d67ecd78b9e0794afda2c47ccf319ba1389eddd974eb73c23cc763b884de374cefb9060dfa5ffd031ecee0b1119600ce1d2d069986bb1f099c0b036b1962c54a5ab693fe44675bd83850079da9fab5f3a073af9cbc2154779793ab22e7225a272f7dc599386f61ea1a2c148142d37150ace6786b2ce67caf2fb90ff46b99a616fe544088d99d43549b818211980f5e374d0aadc7b38ba7162aea7e785548cbda4ae85fffdbf7afbbba4384c634bdf9f97d2f1f5bd540689501364980a0e47b9e9985154f91ff9407dc2437901b9ae648fa30021fc638ec2af60846bf3123027f2bd07e508da449c3a90701a4536e0781313defe21cb11482933251afbc50b9164c01b75f9327e7ba850d458f7c5c27632f825c9c4585885ba9f735b8ba78c2b56740d6abd9460069c5d02aa71814c5e4010424e079c48509fbd9d87254ec77dc26891177202d14e2a3955c91b46bf28b6354fcc4f99f5ea70983f81cd73b51d11e662407fa4dede007b5248697cfc3e000c01690dfe98597fe37b1b3714289b67ac7dc86f7b77db724b99929429b704f104a80477766dec707148a66463078f7b677776efbd3317a14c9d973017b219ac07180960383c2d2ae2869033e9d3592ae188e082f2c4154c18d8d431ddba278a3c9564aa2ae6d9e83bf2672af98ee9c7dab1c88b8a6e2fbae8e26c36b3b163cb8cc717fa640bed2189fab0042d82c160303aa444049986408623f758866c48b52dd2e7ad20b1e5615e248aa2488b6614082ba5052a5a24d222f145175d74d1451769a92864a2289b55516294a468ca501351f48fc5542a95ab602caed2297acc251689f090cc61be63c23277e46c478e335a98f9656eb1b9154571c8771e3063642fcb2de2d0c762624c8c4df1b38781cdd0bfc83136c4846886bea585c5863445c533994c9c899fcca0cc4cac391363be3391c4c498288aa29128c3c58484a702134a2975efee9eb5d65a6b952d1a5488ff7f57ffcc1f49a3aa2bc4fa081b0c8e87367c17a539b42d2f586bdbb61582a769e34c6c7928d03b27744ff70a3f9a2a5dc75f69cbdaa75572b6eb68784ab8ee5adf29ae11030c8c90439c40ee20ab136c249bcc1df9d32f2cb37665eb8f9b95c8de9de04116a315118ac9623c82c631a8729c4c867f51fc9ab5be93a5a4f87f7f1434e0ac22ee50074ef0f6f696e0cd04df91220a5246ad76fb82c2ad0341e4d7a13e35a48c897bba19a48f7529a791283d294ad143a186784513bc6bed6b04293d51fcc21c9b0a10701cc7b54c06050f1ebe834307997ee5e13bd68e76a45f47aa82ab64085f69c4b2d609a5b4d24a7311f1f0f0601ef9f1d42aab9492561a004a29a53cdd0326b96bd624ed56332cb72ddf0e494e8e0b735a9f0b3826332546b20ad1134e26eb3b6b36c8646fefd4913b3566f774cd09b87ae2ca2cfdaae47e7e5923fa407804d594a83c0de2314390134ab2224231598c870cea710cca525a60c4590b8ad6de60b797b5d676b693373b4d34786a08811ea0943efd1e57e62a3105d2fd218b92d2ffff27219aa064d908c857a8f29ee5d7e56971dc45e9b04baa586d569bcd66b3d96c369a1a96bc49cfa3fc87abc96469562b666a561af8f1bcf6214d9d37ddf6530d431d3434185ce9a8c1290f955aa1c306a3b00dcb632b3e8cc23658e8c3365f0aa750df89357540d64b524cc3bd3c13cde42c57ebdb8fde99424cb57dffcb9891dbade5184b7932cb32c7fc566b6db5542adab79a41a81431f43385101942fce1808f98ec47ce600508db8f47a94f4a653fa5f724b11050f020f4336f3a1f23ab905c1784c8f94ad22709e9c3e15aa4c6aa8ff69161a45cda409eb8d29ab5dd51a5846f79625aa4a2294dd38fb5f7ce94e40d759bb7a1a10a0299705da247f754fc61be4bcb98d84bc798a69fd7bcbd8cb1623725a48c892b8845ca903f73e63b3f676f4428d631a69096f144f20ce336d80de6dc57a5acfa7f251ffa2e3ea890ffdbed769bb79c6ab3b1c1c3906e45c62f5fab1175cd03305d92268d0680182e872b8f2d1fc4b1a4945f721314aad631a495ae8d58c669abd97258695d6925b55cb45aad56abd57a28c116a19f0c988e1065fe020c068b113d293214246b2294e46130a2144e5c180e3da59340c81e2409ba2f1216ac1949605316a1425c6bffe9ffd75abf4787bd300c433725d9bbeab24dee2a56fd731c676bc51c0854bbd51213ee31752c36b1660fdf913f9d65e1e8b85c978d2f9c0dcae1ce22011934f0be1328e528e59842a5505c9696c6a5a571694ca152282e4b634d0a75023f8f86e6d6d0d0ccb05e1ac8174b9c425dd673014f2770e9f34ee0d2d2d228e5f875266b39eec32fb3349868e84629471a6818979696c6a551ca51ca71695c1a53a8148acbd2d29842a5505c96c6142a85e2b234a650291497a531854aa1b82c8d5746fb2914ed5228da9530b3657574e9c7142a855a1a1dd3cc9f203dddfde481cd719eed4cde079e64ee0c4d0dea53a9e04085940d7e1256b9111752a9542a582c52ccdb54e23a2bab54e645dc572b10a8c32b160b9b3b02949cb9f3e2967164b1484d2c361b0b162c6e5aa06646d3e8c511a9765373a52865b1c614681fc78202064ee81e19cc005be31cede346264c1daf7b4c4832d913a427376496127b0002cdac58b0bebf333317df197c71cd6a0e8140175c32651f8805fc64bc930dfc6c349b5846486ee44648b22732d993f9a4a8a8850b9a24e24c9e96a32f5e80408fa977b893f867d8b13a09674448e845786791196bd10204aad8c50743465e94aa03b9924996ed6028896c68064dd88b172fc2ee9e53b646463264b676db368b5c33cc0dc607e01750e9839c6fcb38e6c4f87c25b1cc70da6208c08454abc9c4298aa128abd0aa003819df0c10acab6b309e369231dec4681f37cae91e0efb282b5a2289aa11677d947d93f1998cb229b359abd59a0102673b292e91424c868666cc980142081505a51e4ab2888c8100020821d0a0b63361894b450821844063004ff3311c36680cc05fc9279938138b339c414e3880afbb71efeaecec804016ef002db15baea44fdfd626423718ebe880401dd6010f309be7abe1c9dd417e98e3cc3b753adcb58f8fb64da69b4df6954c9c297d1ec98bff0f7b0ef8f89db4f371a0e2effc8162ffda7bed94d96030189030317c12872d2e32cc185923e50e294676982c5b0ac9a59a8d1c6292a584c1602afc4813c84c79132365bf66912ca51c132583f8a70e8f0e08b3ece15e62c29a3a17e46e8988dc81e92a625ef85a9029b661bc84f1c0b54982041b488211207b2d7bdb9eb20ccaae8a8d62d692373f4431029bfcf8bd10f48061c10d6eb8410c90c01811213f9e3539263ffea993b22c14a16acdd60c144262160a304240226c322aacf049999d5a8879451481320c31898e636d20d2d13c2676ca6ce2346de2f494dac4e9fcba2a13b0400465488d881f375800a302e48614252b416644b622455b84dc18628c727362c80d22642a03c06e298068cd56b843162a4a64b1f242873b933b4a96248cc8d2c48b24ae4cd08b1bdc0bc307395c9a1b865c9413183029306e23123e8c4938398c4e44318a995d530b3831dc0fc90c1fb8dd8a830b19ee69042c48fac105946b734749a221d55e80b99f3b4a12521049361843dc2f7794a42c2ec4242fb0580e6aeac8562a779425885a4bb557acc8d1e10f733f2b28ae3ff247822b747c0a8e2dfe562958560a8f6b4dc04b695ae155c5dc63ffa16354faf3f3d8621d8f2d4b87e31af3a79f748c8a6b4caeca99d18aca95b439dd87f45e36b7784c3127574aa10a787dc34287fb0aadb53fdc0659426e63990f4ecab55163864bdc76f7fb7d79369e9826a960f1be6e60b8af36aae1ee3e6407dbf4e1f50d0b22aec4ed3f6e83aca1dbb8c674406a8c104c62c07de34d164bc96d2ca7c441e99dd6ce1e8e54a526b9a2f55818cf6a59ed58c2ccb087013e4bdca3d216441b524a2965ad392d5aa7848b2eca66559424299a32d464766777766777164700c8159f26122560820387d8d0223ffeec0e47bcd793c58911a70991217f8b204fe495ad159f6007140c65b9c188177e2af5916badb5d65aeb10b533042830a29fbfa3180c29c84e72e068f2eb60554858d48f2d41669828aaf9e1e57a31a2f92166888c6d26489153134a170621b00922991b867cb4930e413c116c126412bf22221d0e2f364f052d58946ac871da8816645758883511c3d145e9080814457028156d40c85864051c369821c1d104ed28880788e0606244e11544a31caad150b8d9b25feb2c094c98e4aa88b1706d6cb872051e82d89e1283a231bb700205930683c18e44d1a202203da50363a6307eb860ee285aa49440cb0b5c50b95cee285a6090e40a102d4ad0aee78ea265091b19b4b828cd224c6389e90ac79de30548dcb152e852d0414787254ee1c76311e6be46c8d415e4ad706cf10a67e998d8aed0f1987ad8b9cab231438a9d5563b278b82f55b70a5f61a68e5f2d17a5dcd13da92c318feee964171e93b58345140fa878078bc96dec49a1e93d4154eb110cf4e8b0ffb77c3c010d645abf8ae90a02f36b4fffc71d6b8489232d0f0eadf4516b25eaf6705f570292a7016d93ba8bdce188dc12db2c16af6fa4cf8ce57eefb4923f3468cc90051357e220b7cbafcf7d5af54f25e276585610d79faf62ae9a2a06575cfd5692c94a12cdb062d34a369961ed1d8e533b9b7cb2c4e7cf4be6563672a1262e4dee23159a6489714c706b721fa9600308ee4cee2315845ad0eecd7da4028c862bd325044209181db81f0c421e6e97fbc8470b4224d73b7231c68710889323372a37dc0f071832a8618ae8c3f5721ff958c104b7e63ef211a44596cbe53ef201a3b9a37499511bb8a74295c245a3e570d16834174d872b878b46a3f9d72e1a2d878b46a3b9683abe3f4551dfd5c7db88aa48d009aeb9e3a2d1683453cb90728a0aca08e1c4613b2146feb8bd132de68477174d872b872b29c9f522486fe58438e10c1180c879e9fd2d9ba391ed235bc68cc9d45d8a31ae5f07a8073febb2b56b1b756e34da08a12bfc2b8e42152b57925cef2e9a0e570e575be92b9df4d2c33027c4e9300c3f10fc4cb7939886735c2fbdd58a31001f12bfa40b395c345a0e178d4673d174b872b868341a0d575351f46decc499aa2f9c2a3c2fec7a2fbd7be68781a9232fd05d5e49ac42a680219f913c94deddfdffff9d524a29a50fb8930419ffd34b7777772ce54bf9ff4effab1e67b2de75d6c479edeeeff56b777fa7a07cc09ffeffc6656c58ab52d15a2b5d514a4998f7b3dc8dbbbb4b4ce9af7000e4631266f84e030306954c316d3c95f3a8fceaee6e4b6baabf97af1cbeb057ba12bfbefca29452fa2ffbcaa189dc8ca59452eaf8e5b793c194524b29a59452ea81df077a4aaf97e9a8dbeeb7335fb9ee6a739a46536b28eabdc8eefbfa724f2f956259777ac78425ab9b6567284daba69452fa1ed8e0e1779f3add3dfd294f6d7116f5594ae9d3cad98e524aebed0429d64c1d8952eae269e5a03ecbd9f99da9ffd27f7de03bd269becc75758cc63cad0f3cc9dc194a29d8dd327786a60675bf199aff477dcdff7f8f4acd7c3b5d4decdda2391da331a594524a2b4d0d8a529a9ad286e2d777b516d72a3357ffdf4bf1fd972b255dbd5ab955df2b85faff5e2bebaee28a1072ba7b6581edb66ece4963ce3973e6f4e9d3e7df64efeeeeeec972ef6a55f2bc39a7e339fd954657ed7dce9f52cee67467bde69c73ce39a75fd895787e375783faffff9cf596ad7f73fa4c25c5e0e7513c29ab398eda315f393a865677ec4febe931f8d9dbe3563a660cc5e17dead0ee6581ec983eeddaf5ed9873bc9646e7bd3e98d8c3691f1242fbf4c6f3f0347926fbada6d723db9b2debbb9084d0860b870e04341696bda9b9412c83db08374f4b75c3803bab9532bae72439cb8194b21e012d63e21bd646a57d35dbf8367aeac84a95bca3bf338060a6cad10c3c7490bf07c9165b9e34501d2141fa37412808216a803283211b55e194ffffc3c712875454ca01c8145b8aa4859b2e2f9e40e7883f715552c5c95083235fc28f5a95e106a2039951f10521b38420e28b1c3822dbbe8d1995109bdd2391680890a932c00c63d783aa735a29ad1fc470054a7e61a32b5492ae8c30aa5c8162063e821a1331519d1626ae787de3b5c91b00305c4e04dcea9e1499c33cddd399c31cc7610018b935b738dc608bbb2cf0e3e66648cb6a750cae95396bf220777409c575b524667f28e7ab1a8ec3e15fcd9793c3129ce1309e3a26dce18a2f873d0f3768b2d85911086fa898a24409b2ad768616638badef38b6f8face636bb15d7140826bb1c53756646c599cfde1b0b5788696e369cd90c3ab2188ec0e5ead153f9ee1062270936db7188fb0a0851147a0c0d8e182b98f8ef03074bfdc4747720899dccf7d7464098e0bae29f7d1111a5ccce0080b2e5e7069c2e080e0aab0d4702dd20b1a2ee782704603c2881035301244d1f5dc47465210c28c14d9c8600829bd69fa899a4f2557396a6f3a4085bee3d66788ec58eeffff2d27f32f4ff3ffffffffddddbfcf1de3ffffffdf29a51eedee6e53edb8eeb6ffffefee9cbbc9762050e37777f76aa25e77ffd7dd0efa9ffeffdf72efee52e6ffbfbbbbfddd5be604de53072e78b2bbbbbbbbbbbbdb57afeeb2ad34cf39a7bbcf5ebd26276d87e7ffeac5a2cf9a33ecd56b26b7cb4e8b27bbddddfd3bb7dddddd4d83a3ddeeee4ebbdf7ac773ff5957a652777759a9bbbbf707fa40ebfca4ac5fdf7274e94afcd57274cc3fada6af6368fda1e72a1dc3d9aecafaf5e95793f7b4f6f7e0385a9fe3f073958e01673f06fe7e4f9ececffda9d71e88b912d3ff80f5ffb49a68db5775d8a1b5d60567bbdad3e451295d5c29c1126696ac3779ef792b5f1779deac6eb735752bef0329066fc870ac578ffc2c1a13ca4df8815352d938373ff89dba6350fa2c21acb5f7fe0dc2ca580b42ae500d342ee46082792f147102222345e6c8080c34b2966bf04f1d1f138d23188e589c2c13832c834f2090cc494b11f80211ca046c054e6ae311413c61e445952317828e8488744cf95b1c872d132d20c95c01321d8283231686402ff2a53c62416c2d31edac90447eccc18d122b1ce5aaca15ab00816a132b5635638523f9710a10e8392b5768e48a6d40a07a332b12829d5c71aad66a73ad15dffa43ae18d72752a6a88043814095e21a2247e4a7921fd38040bf82232235cc1459f98b45e6a60643029938a8d4ec5de88e1136400013170000180c0886c3218118071339cebb0f14000f4c783e5c5c2ea48bc3a1481003290a63200662180620c410630c610632a8ea08003bb571b1b5d28e6ab92538f456f188d0a93bc2db4e411b91dfb7b4856b84d6e480282c8c87b213b860ecba34d473f9b735bbfbba91cb070e27583551eb3da938d2af070a9dea78e31d45ae15bdbc4b472bb0e231cad3c4b1669cb35b5de25156c939cf179ee56638e10ccfecb6a85f71ca3d35163060397332c2b945e7be8b899d412132c255c1f44537de41fec2f8aa318cf66b4d8990abdc9bc6ec35b76dde7ac80fdc36a53e9d587abf2f40e01e3970815631636c60ab0a1156e1d4f90f3bb46b4f06b1e5cd616eefa50cb268764122a6fa3d35d117befc737f84ea8b99db2c2b047e2f1df8604004e03229edcb7c70a7f661750314339dbff564fcc0e9c9a593a0df6f6882278635bc7ad7f242e6bc7fc8b650b4fe4b03d8bbb5a6a20cca8cfb705ff2d320d58f8250d4e15356a630b331527f21d78f0b09784f078618b31f88b506c5d3532bf9d045cc023420f54490e05374bdc7cf38d30032a38b8a40b693497c3e92b0198836f00edbe47f10128bc16a040f0755a466aa3360164d6d76a313e9451b5ccb67e7a33897cb09c30f710a3d73ad16548444cb207e87903444ee736dbef78077cd2f9adc6e9d6d3ed530e1a06a5634c4d4df1e24d7ea482951f4d033d2e2eddd15e64dead564dc9fccfab1fb39bc2e9c18b095510f64e817100070a66a3277ae0f11241a121fcb9dae7e9388d17891a97f1a180b4c38bd1126224e5b5f1888cf60c1c7c3f6c8dc5c77bfd82b912b1b53194cbb4a049af1ed9f20d4ed3bb4663028c538739f5839151ced87d66d92105c67058f6ac9c9f2c29ff0bdaeac1800e4455c7948ca6556a6abf7ff36e1a195a095bbf4daa9614e0733785d569c6900a7456c9b1520e50b3485d0470d4c4ffc09715281b1227c1a850f98634100e43b1cb279f1ef91e2a0a7458833734d31443a01cf2af6409bd49ccda11d47271ae8d5ea0e2b1df7e0d5b9e358ec19838921dcbd474a9b967b9494b4fd6918deead420956a79bbc567fa0f0f1736d0a0c00ab61bdd61fb4dae7c1c1dd7fc32c05bbc67e5e4884425336fc30b1fd3be75c93ed4f1222ea65960f253ca2846d2c0f4646142dee13f2dd0a4587877bb31b64186d40d1983b70503c40c61f9fc363133d3bacfb6e5a6d6eb386ba0c6d09ed88f1daf1222abdd5a1fc352bcd6c50ff4dc9dd38c2c09b5f1fe02413f3673684382a1dd44ecf827e7fcc956669913b75a0ae217bc764f8efb0a243667170f49b01417109bedef089cab7c89c627a9f7a7cd11493dd61ad6b4764e46300cc5ac8eb08f3b448148dd44a212f5437073bf71efff21b519d91fcd1729f4fc7684d2824d965102782691e37a21667a4a99c44e0950d4c7229be3e1faf9d1031a03029070b454a7e32543bef3069c915bac9b164dfd320658d64a7573dd8875b1376feb28e972e1266fee6bc5c75bfb808279c340a64e7c16e01d88954b8a5e38e6411fe04adcb71e5b9b20d20001d2c3b3489378b067930d9d171d2166ce7b6059692dbc6b14fdcd90ab2ada6cbdb63c0177a94aa6ddeb62a3139d49bfbca036d955ca5d145d29616274e6074620e8250891af575cbf83f6842ecb19b97a1e8c4e684d010dde9685cccdc21916e103fb0570e37e309a892693f9af27a698227b21cf152c854629ca0b34cc9a11a5b82278cab805ef2a2fb4aef2a3de8f203ab31848683d4360d87393e574bdef9e349ee0a42f7c1e13f0e620d005ee4364af3269467a237b46bda1e525da1d3df2495a4cea457a4b00acf0597da411502a56c7e9d3cc79a3f1d3096b2ee52a95aee1640880977a17450e8546d5ea6f0808b0c8f95c8815b50ab034236e2203c299503373d5acb9164df38d7cf932b14842ef4986b174a9b2e4b87f125d2a8ffd96d5517aecdc05c5158177925257489e9d90bc2cd2d0a534717bd0b2e8f6d4444f5464642f883294c9468ce820cab0c1d66012be6bdc7e47b871e7ee9bd53748e9f69a75a1895a1ead7aaf550686e75ceb529576945f464141c587a4cb3204891a18e16122232c485208b71c93edd5ec52daa140c96dd4f0b30dc7845f615e34a5a515e7cdbca068b8b1767bd0a3711205ba86ee9d3466d51622022cf2c34f7df617bf6e2ff800f9fe85e708b8417cc4e8943b75ab91e2f0117867ceb8c38142b34a2ceb90167101b8de441a66b77fd6e96f6f826d3006654bd33989cc79ed8582d574a764fff390e2e84a2aaecc89409f8dd638dbc1c3b482b9ef0f0c0505acaa620c53473345c9b22df075a3130245c7c962263f3b1911645aacfab545a1874317034359eccc515a07d2021d340647c1d7cb00555ec111cf988773c93042087c75c7cc67b354c5d2b3325c5cc260cf05280f81744499cb1bbf2556b89e3866e94f2fdcd9a112cffc07d51feccca81b3640ba1224109303432c4625229f5e8d87c620118894ce78261509d979c5a7b1285229d5c3cef4e688978c40558fd2b6350d0c15359c7e58d328a8326c6eca1802fce969b51ac6fea73488359b3c192ff8a0ad9862a79f2cc9463e5957bc0008058878fb6f122f4dbf4b649f0e61cfa6520f9df547ed9cece0d4cdfc2ca233347ec2337e9d0bb503c31b3c221c7080c828dd2b5439409105a0ebf1bfce1bc31032d85921c6443319c7b75c39cbd2729c9d510ddd074fcf1c422cd6adf9c80a7c3f4b091a699d1e5bec8e3bfab5201c630048b68043c31f3b66df91beae21889687aed006a7d745e82c50943cdbdeac4f3ebbb56b81c14922723d8f1e163ab24604b350a78632168fc3e30a1ff41d0073f52684cb9f089405181267286c475c016b33f306eda46ac0481d4fb529ed3c348860a38e373818b30e32f97b8bb124a366264276c5c5dd345b9b1fbede1ee200dcac8e02e2fee8dc9537f0c9e715fd6f6554e15ff007cbcee52bc1cc1e088283179a5adc121dc5e240b593518c8defdc1a41a12ab8ca33f19833ad77a39d0d80c2326f993ad123838a40757650782cd4660d175a2ec5195c84a008d94d24a6c4280f6eaee278807d2de44401291366e1ffb067dce109852b637b10695bd1226258241652a93be4959341cb5131f29e57c7ff4410f8551044860963b1130428e467c38a12858bd45a9504565d01f6ba0c901a2b90acd357d4e0094e1bc5e08ee580141088ea9d41bfd321ee81d8b055e759ea417e1ef71aa9f3eaa2a9d730b028a003cb997062e0cce01c6842ca64c94693d1a10ef3d0ced97afc87991acf5cff9fc785f2a13632caa1976a054221de0d73272465f2ca3eaf7f2be160f23a6a61b8a24b5b6b2283ea1ea3bf40f20c75d8de09753543dc80730bb09e6df2515280c52e3a4d0861da1ccf871f04f18a15cd8b00ed03fa5da1a527bf617a5d1e071bcb33e5f66559a8dd31801770a34e0acd35cc1882befbfb885f41bac8ce8e1bb42b18c16b5d28ac308b12d90a1c20f01c405c8e8f5c38a8e3b09bb614d92bfa3cd07b5f55ee47073e6601423ae0d1cf349a2eb1a6c3bd4043e8b156d764571a3b1eba08519a686bc0ba4ec4af54ade220078b463b1cfa3f5051854869fce246e841b834ec0683c589fb5bec071f3642bb2188dae89042bb2cae7c6f76cd42d1054316ae824c36750f883dd77d3341c56f9837ffa0c86500de8a297ab5621bc4162ac042093f2349de0dbabe6e93cc8a00978113b173012111db42b857dd4c08cadcf8a9f89443f87e9a8e5f46a5a5ea26e805729e8b8fd2053a2b84de1f9794b99dbc9c076c166d61b321b68ac2ebae1343e839d7436e9b27873c26988b3b56eed102b978223ede406d382c081d5458164edaab6c6da1407a417eb380dee5721459c8e641d68a30319bd2ab71c5487b42b07d183e763c98001f6d913e2f1a2aa269bbf0a462c8c10ac7825ded2b39c74d3e2f344cb2922bc3f61506bff128bbbab4e6a70257b0a5b5cfe7ca82c838bcdd291a078233da2638400e2b1a1a1e592ca09c584dcda74a0fd30ed18dc5121838921208750de5ebb6442a13e42127b3881d997329bc0223bcdfa30a29430c59b430f5731578275dc7a8b4e50e2e77d0838cf293122a9a680197c2e03cb49b35d70cccfc043cb5876e4176adb22f4905d8bdc2cef495263851d456c36deeb236c50b70cf770b28380ec20c2f6b9f9e4108759127261bf535613e42e2a3767e140bbbfc703f919427277591623c6141a4f50583eefd812f158edd7841af0d01316d1bc3e8631a501883b7328caf40244e9f005bf83c6a7512a4f51ee94de344602d96f05140fd769a3c351ed80d9bd7030dce6b9c0e913988a4f0b2db1dcc8feed0dd28253b91e57d19330738ee82f9cc5890617a47ad0bd3d229c701749d200d2eb8063867707fb3466ae9a72e7bec7df4e2baf69bf5f6ea0de4072a8c3280e008afe7617cf388fded2bc9411892cf9532963c4d4f0a888f743a98f44ecb7fffba61941e9989f0002fc604a06a4c00562c8462ae47d433040f0d1c90891ce0491294c4c5c985bca61919ba3127adfa366db86b6ef2433397c862ede49572217db7d3b21596af8996ab62446dd79eee7239097707ae3610d7deb6435c9bff8e6d565eb652904d46badbc1f11e393ad78ecd64033bb1594921301dc629dc529fa815df6601c1eb1fcd4439dd9a409a59c8bfba4990940a014137357311a94a5e73ee3ff18abe813048a9e0d483926f9bd68e3d9e5490b35140b0bb5e31ceba77ff8396bca321f38b385b902f493c3a5b5bf7e9afcbce86fa1e7cc3e297270f6a68952e9fabd6377b0e946901ad59895ef6c34dc4aa56a899aedf3fdc0d14d616fb08a5ecc89d2b333764c38a07faa87460d064f557512717902b37029eba00d92a44844a117b8374d5153c65346b3e22ebdfd1c20bcdf030ae244c1770ddeea3a86995bebcc219107f897339b5269ec8e7cd46c53fc1b0521b36f3d7c94db3e2675aa9ff644b4d8ec76b75d84f9f4ac72cde4a7c4e034b2107a7081866484a7da76656423629593a7ca81c1e9481d0d41967e3cfe00b44451936e111ce5ac1c2c64bffe56c05688cbd1a1be7a025db666b0d717ceac7e7f6dd15347ba1ea26f8d3221e68764904a5d1ac3792eec48b8d652a0e3fa21a4eb727717638d83d3043b3e7f4f32560439dd21b809d36ec81af37ed0b55d1b89a757f790d1a397846d84d5b46696a3bd6a6d12bd68ff7851486b0db7e628759e7e297239afcd881d99ed3234e4a13de9a74441b28c7691985d35ef3d06ea8b388adcfb0ceec20831ada9eb4e3f7e7e6dd1af5c29b9897ae57dba4e4714a3a5d391bb49c7672602934d403e6b483f49099910ee98983ab6eb252ba4267ebe742cd6cbde53de7b04cce4cfbb227c4dfe72f2d82c7d65eae4a7e3ec8cbe9afd0f97d1a2f56a1130635012ae1222b38d216204882ca83aa80131625dff0abc2feef24b82846646a9ea9ab2af577da7a720dec7a8afc11a70798c9fcd702503e217f133a1557a6aeaad46f3f2ddab59050e300515f8e4c9bb06a4644579f066dff9407293003862807bcb2caa5d618349f7bd81299fdfde77c1043f7777e7fd5a0ced70cadf7cbce5588020a266fc1fd8f6c8ecd0f50d3d056eced0e95c5e6c00d8b4dd0448adacaf0e69b5c067607177c61748bb37c4ad6f02eb6560146352417555edb29d5d1616a799ee5c9fd5c092ef97f9bc92646a9ccae6bd7324de5812d5d5ab96a29b07aaf86a66ff0b7e4dee6fc8d26a1e92e2e317991507a1bd22201fd552177d1e7addfcac2d686330095d4be520e15e94cd0903b5b9b1bbfa03edd82dc1871c9d12e8ca1d6a4e6fd337b3a64db7fe896f2bd2a525899bbd62b6770816c21cf0389502280194cd9f91c39083da68306f8567e6f70adfe37e4097225d8a57b8edafce75be8cc88dfb0c4118ddc5df05c32d406edc8777dd0e459e4995d5d1a5020e38fcc2c3047f134023aed8328e7293dd1658bee72a3771b40f9036cf06c8c644b5e5334dea15f3e991bcf92ed441ed4081e5a1c1fb9396dc9da999c6caa5bf237ad0468633090dadcd9b6eb53a635d3d92e8f572c9cedf4076e34601040c3797fd1b619c115b48003698612dd274322a0ba5e6385c499cdcd04d7d96aa41bcc5d958f03677d18e9e0c858c7925b4147a189c9909f24b62f1855db48278587d726238e474971208fd2f23102564415f1621c31b5ae7020799b151f659769a7e71f01baaed61567404a65dd1c2ea7adc9550aeffff50292fc1161f0b104cb161ea6a704aad0f460b244c109e476304daa3c2b3898c466e574bb6b08a5308e64c2e194f3d050d85b81ab4219fb074758b2bfb847047d8dd29fa7ae882752bc52570e8990732144fc371222dc249cc9acbcd1613cdba85355700d5243166ae8c798de09341d44041bfc8e87e8087af7ba75aa7d51eafb78e09bd1740d58138b81f0242c2cb2db38fa7da17951fa94523bdada8a641129395ab908721a50721ef5482c106fae070630c3e84126f2e7026e2cac916608e2c9cde19bd584076d4e58ebaf2fa0e416a30058348322c48336798a719bb8ef477d4d5a8106d437baca5adcfb22ef9486b7ed95a21fd11f5de0d52d56ef777b0f86faff9bd024772878758fe0ecd4b4906ba855af06d2cf03f74d715a82999b355edca070660d5f4ffc81d5cab272f1f3f803edb52dc222d207bef40e0751e28314f23996faf2f444c7ae53d6193bb016f9082fe5f724f903710fef65f740aebd792c13a7a45a1fa03e6da6f334c5258f63d4cc66950ff56003518be09529c1f3f94197486ea0ff39e67c4cac99904fc4d0baab43c29e2546c9c013d50cae6f2c49f67a528cf309083eb0c44671c5fe34541f08090dfbbc6544a650d1c8db8d30eca03e0eae5f27e2cacd570311733551af20eb8701fb885d50e9838f154f1daae4482deaa00119cfd741fa0953135681e38c633b0c35c4b419830863958d5e895f8f14616d5c7565d4fb6404727bc2606092825728b4865a8bbc548f55954552e1aa0a4f03930a48f64f8bbf242355c8c5f7a288b81d4ca01020f1799afa9cbd4f76d8d52651e10956d0aa1720528924bcad9e97446a1dcc2ecccd12493477e6994fcd031647126bcba93b6d09f80ef115d1b8f5652778a10ac4639454dfabc77057ac09f3d69b3e2998a63d0b5baa4fd16cb1d8cfb8f9f8fc496ed431aa7a5748605d6f74eb7c71aa5eac94662cd0a61da51a3eb3240a173821c467965f81154a185713cc1d94427a9284467750a918345fd158c7e1b30910b84dc5b65d2f8053252b006cc75785abd70b4263d62a80233ab8922ae393216a9d8a5674c12ba44111b3ccddf2a7b02e22f6ca7e5ac943ad686f0a4cd76c5a826fe61fc45a676c129b8383021bc4396917a802602b4271f407ab4978046c92c1ff39692fc6bee0e29c46987074c60de4820260195e75091838e8dec05f427593b0dac948a1d76c265f0489d4f68ceea602d18ce71506212d51f864e60c1ce9f77eda39433b7bbf1a0b2f280cd9d524392b4ff0222fe8a62acdd6b36c2c2a64c07b946ad2567cc2ced2d0d9e1e3d6a56184c10712988631762b92f137d3fced2037807fe6d21ec72827813d073f828a6c3b5bc573dd7a60d265e64dfb7476ccc961827600a891e58027bb7b8f044dc299d4bb0435902ef03b31fe65845581c192be887c17cbaf7e9ca897c250127141ba4c5f76c0a3c422999b39b7b52a923d0870078d55058891277ca6b3504582dafc146418a77c22c0dd1cf99741164506a70169f1855135760b3494832766a53947b33bb40d7f656b8caa6138c4e628ed40169c036c4e3e2386ee31e0ae55852b5a769c78a6e2a9f7dbb6141765b01f0502955608a78a7098ae16e75b19590c20a47359c6a144545628fc390d1c8596b8eef54ebf11ec2ed84b0fcf34e784a65d72f7a592c16cc4b693e6e14f0868417130192a5cf2323aae6c51d7cfe710678f8c87cd61d4e2be5c98af5311809b45be29f67eb5e30d6c9c6a02c5b5b6f09395b5510454600f6b673a21b2a9c50f177cafc02a20c63e23d06e898f8fab8fe0a693c8d3eeb800d390efedeed045a871110b5cdd158c8f0a0b82adc973fbf98096d0ac01dd8183ac7572251fbdf2f2c71a8306ecccba9b430027e74ad1f5eb755152d5bfbfd4ca1aed3e11d7b10e117f51da6662015f828b08a8c16f1168356d79a7a3d2611fe5bc0f0876129fa873f06c5dd54c6776ce2060883d41e41ca63c08141eae13a884e2059ff6a73ad63e01c127a0da3a4587e5b54ba8ba97465b216b997b6dc1bba316196c69d9352b10bdd0f94684bb6e95670ccaf6d5002d915ec185c8a6def1dd1194dbb7cf828ab5f0ac445b23a6a9e87e407069a6a5a8b06eb13084c5ba02448556f6680497be2e7fcac45743a4c492b69bf053a5aea7e28ca77b1cbb7a63c40ff29d5230f1470f22c315df38e99a6556ae4e8b6e8c39c366a8a96fb8bb7a8a264ba12d7e3d0bd689b4d5c3e2267adf52fed6ac145b50640ea6ce06b3e63245a4fe4cdba64454b0e182a5e640d50f39cfbe1e064a5e0d24fb759b7741350c8eedf6a4f64bfa7007bcec918f2b203c8dd2c7f4285f9a37b3e49a604ae703eaff2c1c59de380583e815a07585faa489448890bca0092ca8ac6fd9f9b93a9ce647b864f8213447ae2d045cef5568e5fe7c0229e33a56bff2d42bb75d1fd3acd9cf60ea464fa8aeacbcac788d094219caa9bdaa04904b148401fe2f010c0b5698a438ce50c7861b0096fca4aa3f871702dfae180c8249f25abacb8655612d1449efb10dc98bc1665c2fe33ee7f92500c2ddc59418083a4343a996525c044ee8edc0be298bd13f28be8561fa401dd0ad150530afd1108238889e9f5fa64f25a71bdb08e8d108e82888683d8ff8baf82b4f1709109e927612d95719e402c2ba0b1b9fcd1fc5bd9fd9cdb18600a626bbce6dcd9653a84b08eec2191420524f6678dcba412d422656b898eeedea9d2f2748d57c88b655cc3c31ed054a4dace0a71d7b4fd51bae7752b81311d65d42b7ede5e3c477845f7a06bffbca4b41e4305ae1e4c428ab7341e03af9a0b6ce8ee438b39ce09edf48025528c338b8c807b737080003a0884764b972dbac5fd8a1d196b480f6d5f1d9356a206a25ef7dd5504b46973418090c0265c30072b3ee3344a6f18d3d19cab8df175db8b3890d88d12cf097ea8e2f1543c1a0c06946f556b3c23781df1af9ac3fe2dbf781e09c614a10697c1096444f7e0da43015471de4d2bad04eae4493ca8a56f6cb8a4cb78c10fa4b138451702ef10394d19d2319a05412bb045efbe89a76e72b7dd9a4c0de56367ed8b2fd1605c9e5a4b7b5291a8cc992d2e2810246c8f747b0de7f7992395cf66dc180ea9e23cc14f5a55945c28e822cf1b58e4c7240b78b22e4e0973cd5726ce60fe5d20eba9fb791a036c29aeb8dfb13e22ea42418b06fbd28566c9746891fa8b388e8791c48c000b868181b06d06376ab1824ab776fc08c60a26c537d49d1f65d2d4f6830af29ef5b1672d0ef57c33f3fe19588efa84b41b71ebcdc6c474af7db3907f989235fe93297d39a50c528769dca711ea614a4f773951a3d3f6e1040ee7df39d6e922ccde0e0a8ca9aa25e29e03e8601a4956f4eb518588b727f21bae53405946812e8c89a32e8abbf7452a6697e78132994a47d69f6901f05dca76e278121f5dc4ab2f9228fa2865b47e93564094e39546ba2dcfa9920b84e2c40ce523f8f5dcfd91b25729b4fdae63ea89c7b241e1c596999fcfc03575cbd39fb0695d55d8e5152a58a1597eb72981311e4b9dfa368b8ca33c78977b54d9d3fb7525162866409962bd7ea34e201131f8f6c21e9a518e98fa4668f1dbe156cca4771886439bb43d4567ddfb34cb9dc318f3731c24f82df80305d1be941461806a6670859c3fbd984d197d53f253b32045021f40091dda44c0175408d80b235f82b40d708bf5420b6e1612c43bbc614c394a8056e818b82a0fb0645e94fc71411c6067aba2cb208c3b420e1cad140f112112a978947b8202353855158fca35bb8a2c201fa1ad233f64e8891cf0cdcf6a73b12da81546f188eab38bc602850d241a538514f839d01ca624d5a7b05496136a5a4a80fbf105a3303ded484e83f2e380605eb4162826e800fba03e24ee8082a33e003748787b10d426d980a89f21af41144c7d85cdb6af8d15a60a5819d31658226128875c0aed86a401109c64a37565b310a4306ba89614ad0d895cc682a52dbc0663ee9845e66e46c5ee09542140406e70a9c80b40bc92905961153b742fd27cc0358f9d22044411da85bc8dc264052b8d13e3be0bb9fff5be8dac7006c4165f30f349692ce70d6723161e0a716c2bdd6c29cfeac2468d3c8e81bec420dbc1f82849155b98a6500cb1db90c2a13fb8237578424368653da4bcde9f95bbae556858a874b739ae2ad6631a0955ca9247614b59e083784a6d777e5f555f9b1a0490f623a95dc651ff8f81ad093c29d208a832dd5def508bc040bb41d2775fc1bb80365efcc7c14911094c1865c6b9ebb71b58c02552149d21db10dc93f09043d9186996c0af98f3ad3a06713c45bc3abab2590e318aee9e0db39a807566fab1a0e17d8a0062d935d08d59882462120599e6eb945e714a131af453fa70f40584ae71d703197676c62b09afc5bec59786a72db2657265298f89d7f3d5d029461480913ed70caf81d9f31cae1495513ba0b39451a8591dfa0ceadb989d6036971f24c2f75d36ace8b8f298413dc459b9a7c74ec1f372833b21cf0f88500d4d61d930d0de98472abf6859082f9beab109e7b9aa24f80f67e2d273ff3660ac2ac265a037409cf83bb723840be1dd83a47b5946a12a07a3128448876cd0d456554e4a2c6d211009aceb63e86c0137ce21cbccc84c23d59131265004aade2336d2fedc26a1c2a9cc5aa272fe0cf5f33d27a067eba590e0b719e646292547faab164bd0c24d5a85bbeeae1d4ad72155f40cd2c72248bb0a10bcc284379c751a96a5acb54b027bdadb032b2ca0a54aca352b6b0921913fa0e7a0618c5602ebd6ccae333feb8fdc343f2d42f3aba3f411d69d26c3c5004bf99b3bf535877cb58f101d43d93daa296a94bbc8820a61569671d65e61979eac9f2a86a2ddaeb501fab41dd543c742da0e4527f04000a1c48feb4d10bccc079c4b36344416ea0948dd4bd7f0fdbd682094910ff468616913c01b2b07850e81eb873128683e889d785589c3c0dafbe61b2661f1415db244c18cfac9e30e86774b2b19e0508f3d687b4ca86613442315c42f1244817a7eb07aebadb654b3433e886534dd3839a6da9a58dda0e68b37dce520c9ee66b8fcb8ce6361c8bdf81d950821ff46cc7b40f97ea5d537e578859378357420f722a3420676ad204a8d619948677d93085936cf314a8f5bf93fe690c4740af777268f6ec35f0427b45f3cfa6da2374ca57a03ccf6df6b1103388cddb623884acdc4de051515d958878757e1125044ef03c9ae121ed95b353b00efcad93c6dde70bf12a077e7e227f01e2b5ebc00d0e0bb59617434cd40503490e9ac80f32265cfd297efbe64712357d5027a021f05a6c62081a890012bdad8a8b123b1a38ff706c0caaa50290c5bab95294c4c5c1731831ce932ee11a59f9ef712a080343d08c527263286cbc0975a4965e23d37c4b519cc4a05873e0376443fbfdb0e5d645fab842e6dfd6950389cd7cafb99818b709ba10eab352f3946bdfbf381cfa0e644df698a535ebbb98124d42d12d2b86dc702eb21902186cc0ff88688cbe46f1be0263ca1762029b85414ded2ff7010dfad105920f77cab0d7f4cda2c2630fda6d469ec3b904dd1ac5de0e623cf6a8cb46c709016d0dac2e5bebf3c0e458bd6203578dd9ee112a57b4915149866d828525105ba01ceb9f21da4d9c828f28eb8e0f5f877eb362c0bda0c6d117727344c2367b10ee3951aac6dd98d2759328f0ca6a99e7ac7d20f361fca569d8982d4044a028dce1d28bcf18d548cbccd50900298914726dd6b47200331cb7cc8b519061206db8b39a0ff8b8e6a261f9134f23cdd44adfa5e30b2c7fff9da6e6c6bcf86996a6535df054f3b58029f557e624d0d08bb1a8ddc1f195a23f4ec51c69cd7ff81d4257ee3d52abd59dbf4e6233611d14d001dd26cd1b077ee3c5f24f278b34e8fe201b830da21be340fcfa2d17f39924e569830e31f6d2239f7a09e3b9ee2990148656787baab78b42418742346653ee38dae9da3e2d363052ff6d704c7f667852f25862069e583fadbb1690df6e4be619764b1ae7202e9b583683ddec99b2fa1395e3271676b68df627c67d35d2774a0cbd91f65a021fa06aa6aa0059e3d9407e79ec8fa2941acaa6cf0ff4af99226a0dec8ebf9f3cdd36b099eebc434b9b235a519367d2d220fc2b96e065d4a348fea9e6cd2523c3a56c2721aaf8f51bc270345bae13c2da86b3838b8e2c7d708473d1f2729958c95aa65143a597c9d2e4b74eb82a6ed184147de7dc465c2e2a8a84ff5a0003d1e1fdf17d1458932a442ad009a2719a2bb145b3baf82c39858b5ec5ce8674599fff3828a48a3ceab0df7e9d86ff04d6fa7cb6e6bc031c2aca0b7310d090d812372faad95c09b55f28162f13835933c3b46a998600e87588ede951b513b77a1f43af5ffb1eef6801f4b93aa00e362310a02ba26d2dced2754a19156d7d7c246cbc939a6aca78ace58983c035390836758af77463f8f9fc349cfcc27964549dac7778a658361d84137ffa7d46c4518caa2dfbe738f7629abf505936121feb49babd1ac44ce3275a63fcba3c4c6b0d3fa99a5baa69dea226ee5b6d4fc5a92af6a5e52e97b135e54dc89b7cbb690a93b5dfe92df775bcceec12e88bd322e63e7200d213a0a9f3c4e92d950d63051b65ed3f42132fba7ccb62d39d5800f28158c2eed121b3a17fa7d1326584537390aeaae48f5d97cf95d3f584fa274acfbbae2a5ecfaf0ba6748afcfbedefc419b62b55e2efb49dbaa3770d25ff99d2aa31c67ddc7d5ecd8f38f42369502c3874e2d7beddc255163b98374571302598979ad8b2ff1524934dcd8f226717a37680e0765d434671d730f546be0b3f91a17a78e6f5c7c707297950a768ab7014d39b0986a31bb9feb2d403567f2fe252cfb926c1d6a20eb6f6e74ff8c11c7a06dc871c0fbae4c48bf59aab81557ea515661f236a4e8dbb07b38f824ffd068b786666002b7fb9b477d457a063a059f9a0e0110363897dac74d98adc34b3fd1d8621b28f992117bf00979eb09749c50e2774db1efe390935726f1a32da030e7f717da7b12b3c375490a6741e9edb81045d994a0a677bb87afaa66c4446bf55d68a1a11fa55249e671dcf97cd664ae851cef4552332eb1c76c1af25d796f495ea10cd49ca740a95dcc4e6e3b49e899053d542bc8ffb8441d335228fa17ed3b5251a8fc3590ce1fbdbe02135e831b30becb6438614d5fda70e74e730777331f43efc9a63348eb8fd7662b0d97386d002d8e06cac2354ce136bb82b5619ccc9f85df17f630c783912085bd1e259c69657249d72835db4005ce694427d4f0d5be59491c8ec4cf0112acdbb5b8b60da1ebafdb377af7097684703747f45f63db5f62e0c5403b497349d457a7dfc1f1d72dca54b40d38fc69f86c24f35f13891fee5b466f6821b4a0472dee3333a8c5d5ca5d1f0c18ade7cdb6932d9c75eb56ba342911760349dbcaf84a98dff196a9ddafc2b8ad6d784da52b1461198fcb2e318f71580bd217b628e8a119fba34b2219504d3b0ae0d39a41da448a85f2474f35462498f85321aee754e204d2e05bbc1e0d4fb167c85dd27583ac18f7ef81268bd220bf2b682b4e41fab524c55a78048aafc06934f9c83d641afa8c4e42ce80445762e5b3db843cc681229fe5b7330b50797105598237cac3a4235c397d81e0b6d22f4cb7c9c9cb341c1e7b494b9cd48a263b27f1cf1945ef0b44f4fc8c95ebe4fa0e6dbcf663b1693d8cb636dc7d2c4ad5ebef3c35b861db3d257c945e2ae536ac32de15ecd5369b8f1a254ebc5f18df7026cd7913706734a377ccf79617bf81b85f0e36776db11cb956dba76101a033d42e33945ad70fb7f1c6be0b9af58444c7f1943c54b3d485ea095feec24b208885e10dc260a5050c889fb21b68280aa67910063523b8ef200ffb1397296039e22b5c9b46cf1f48a88ee9c9200de0e1b98b8733922c72f7dc615f62d6456927a7517836f64c98143990bba0905980acd21df42b0658eef1e6b7c8602fb0ae65f72397c0b0b47f8474aa43fb564808c64df422d25e81d93bea0e04b646d644ff8161af25227172ae54ae674649a25f30a5ff42a92536c7c678a1df5e1ecc35700fda37599f7ac4afe7c2b81062b6a375f4e224d3764e1cb93812caf44508c5b4a2eb3eff02245f3803acc018e2ea94da9d17afe89b067f96b5195943c3392b8816f3b08e9e1c0b7ae7669409062000491bd344303f805133b314417c91969a181a339cda45a721404d16ded7dec0ae7e9bd9cd9ea9810c70a2ca6267fd602c27e4119779102d1e3cf98c9188111f8f60b4a85c14be980a14f31873567713f6821f3c5d52c5c9779472fbc0cf6374a3a5bc44d91f8ca6c85e8d6d7afb5f9bf7d65302460a01790d50f644db96bb809cac62b42952e0d7917983166df5396d739d6e871045e369403c518413586d8b27c3d7f350b24a83100c70dc3859455671e3679a5c9c092e15cba6012882170131a7022fcc1b739cd1051c018e1975274a46664e82583d57798dcd4183ee2fa6080dcc7de6f987979db612c6ff4cf1d89b76100b7abafa91a42d19151886ce07ffc557a49f9dc49229a889725da0bd10d60dd5246977b581e74772a33774b06ab9dc8e941efe114ed7581c616b66f0ba3a4dc05ddf48aa372d0cbb53c1c44596bcb14637f5e1121a48b14b569e6b86bca70bd01fb4a3a7277eeec368450d309fbe98ca9ff87b2c237d25d5a4149de38a5be1bb17e7fe666a068ff156d7b5b0cad2fef355fc14fce04e2496317f82db4727209120c0f3a2fd8be93e0775cc3c6a6761b8b75e37f99d4be23496e5708b92267735723443da89f0f96ce450360b9d31d1dfddf48055efd76941f07f9413e86d71c5d1df2e1324cd89dfe84028ff0c4be4a36d4b16eeb364f7efc2af51be8d1d7eb080bbe41c20a01be827d098f00f0bd1c52add0b82dee12b137753a71baaf8c30fd14ab81f33402690723e747e894b0f4a3c1d3b3050ef9f669c3d1da11215de238dcdc12381d8c65b2eddca014bea6d73dedbf0c232ec5e8ef5e4e786cb44a6d4631a99322d9ffe0c3495c196a35df44d56506448f1f1739d5dca53b8fccb3819e7f17f7673368c8b8048ecd4e3a6daa1072d75ed32d8bebc5c49199163c3394d926e24feb7106fdcfcea91599fefdef18d524e90337a92d9ad1586545c1dae1c3df6e040dce7f55a9f488e0011a36fe9460f8528fbb3e177127de898afd0beb6927c13fbb4dfaa78617b8ea234574b7b905bdb0f974feacf00be10cc7e0cc0f803c0e1e94031d30b37793cf72027675505ce053c3d537ce5b74c9b55aa9a2fade9faefd027c2c60d293d13ef0d7728680a70fc8f419041c9470b558396ecd2ceb572221bb3a7598339d2abcf1001bb59edba032a8446954d5f42db8fb5485f68c626c60feeb555da8df251182fd708ea05b834582f7de84012ceb40dd15bddf0ad3f86fe4de17585fdc5d952832b995316fc396fbaea639da06c606029311fd9251797a4ae870d137d329d2ee8f33bc59fa6c755f87be7e3382409c479c7889bbbb6760040889297f1a065469ebd96313e988aea3372293bd89b626fdd375a25b1fceecae324cdcd6a708b53ec4574252eda425044b255c78d5e21a3a1c29daeb68605c8be2fa4dee0a026d1f80ee24e01bda2eded0d8e1c07c0a3ee8e80784dc22b846d7be67f81b618a4ce7e186beb9f5fa6c8daefe87c2fdf58691319f0850ba2df97e62411f732b3e714a85c46dda776c869ac65caf1a74d493f55c7b1d8ee15f0be33e784fe7174b34ed3beeafd92026445b84eb7979050c0b2d16733cab7a2e6202459d61f9053746283a111294e593fa454c66749a7254c150bf507565f0ebea91417d6d20187ec42f5fb7ccd77290f46294acbfc67564d0242569c3090c90deb09200ec87d86ae83b83830960f96b5248e930bf753a9d5c19f59a135b686b42df5bcbe7ee9a9ef299b086c72ac82829e8ebbf5620d777324a5f94cb1cd57afcdb4fa9e3c3c4a1432aa1a3d826d92a3671cec4262104b8d070bb7e7a515061383133f906604a072141fc965bf98de1ff341069658013977dff786461b3b13621f27d4b181adde0072d163b1572d8ea08d1529612230a3b9d39a8c5d83ffafc6e30576b7796377da74a31a985dae10b0c7b4dc9954b3f7ec3313325c60ac4920dc5d19d93e5798189f7575938d7a4f2635e635e7220fbedf9f0356e053f4bb4866636ddab29d13b2eb767d71fa6115cc85b492ef5d7452ec4399c670f00f9b453dfac690d1ec00080b69305949de57acc2a1326e66a0078191fa68ea255b76a1357456f5a125187b6831afda8209ca31716a06d782e4ad4f3988e0dd2202ac6e31c3916edb999be0a17fd97a38e4e61c7348bdae9dc7102de2b788bbcaa36ba7221d3bf5a2d1afef867a39a1f64d59218628dcf9f8048c942aea766a318d86c902d31226baf33cfeef09248a0a4998054edb0e98c3a98b87d8f3abeac04db5751e6d1cb6ec93d4d36d65553700c782fbe25bf44f9dbfea94ac227ce586521aba6ade6c4a9c9be4b4f467ecd151f997c7c6255b09abb95098f0fc4f56233168f9a833ecfe0c7faa7aabfbd7573ca46f6c23d2d11dc0c51c61b56557cfbc10501d05e19c860f34f810ed214e774dc3c2be45e1a44f2c7e9538a622f821861c4c92fdf5281a7d0377a7e139d3cb9584b921176745999a5aa9a9e465fddec800fbc3e54c417d6402f525e9e157cfcdb6e864f83c8e0e96dbe54efb2ee0434485c96aa3d5fa1420cf0ad78ecd2943af11bf5f72269e5a64c879bd9c4f005dd5465c47dc4d13c66428042f9dfcfff61865a926a5032501cc4853f90b9a23ac75a23a943e7d85c51330a2585b43077489602a60a3fa82bd0edf6f46811adb5ae829102279f4b526ea99bf0796b48bc5902521da50b95aa89dd91b9288d9e00dfd2b804f6cdc9b08394273464b033bb8b2013b6cb7e47f8807f129bde855d2b7242c147e66dba936f735c1123a79efc6c44c03a0470310fc0497e2e17f857cc340802095bb10fb857ff1057868c6239c054f1d058889b50cee6fdcca11aae53a6f454c2d15ab7a16039702a2e43539b60ca68e562c13d4ecb565d95fae5c29e3e669565dfaea37b7c5b4b84de44580c17af18278e7a6d9b564c406857746e4d42560c0a1102d2eb069cdc01d2ef5330a2bed9bff252b9e887d284d57c89b52b6633969511723e48d627ecdf26279c93d6cf263bbe7370aad25d10db31d38beecc824152bfe11d6a713da9df7eab0f1b4c452e8d0e8a320efaa6d49947fd82dc34b389601d0f8aca9db686f6c8ac376f4445b705330038ab7efe3b3a9714812b6b242b2d6a22eb23bfe6e3a613f33d4ce3f3be2ee00e02662aad313031e3f790969fa4276d7329de32355f77a9ca9b50061391b232cf0782c946aa684b99c7170e367e1a72a3284ac33751d8c95f28a4081fee4c86a0d97a094c73947a6e435ccc81e3ec3d0e3498ea5ae586069f8193e63aeed1282f523b0bd5f0c93c7fe16aeb05f70100d4789a3fb2b036ed7f7f602abb478e5d63bd3381b612b61ef7fc1bfb3589f88bdf40dcbcc6bc95aafba8ed05296e40080ba6b79d4664630a21b62934cebac5fc73a197b0eab7b3976cc8d5674d457b5109bd70c71089cdbed50f0490628bd5c47bb45effb36341cb17bb19b7ba3986e3966b0207411479311b02189672e33c4148e5bb06593f37659d196eaf9b2142ca8dd5bba539dc77131e50dc29426f873db21e1f0e15c8e35fa2eefea8f6dc979c0e09cd9d7272c8ae678b90411c97e9d6b004e12a37adf668e349f52189c83554c356ba386542ab7ab81651ca45e6afb8c3453819b252625e595c5e317f2aeca3133081de114e370c3322baa1fed60877745f37d21382fa7a0f95641d60570eaf0f9930cd14ae03840c1caa08d3a07b4cf0a9a0d34770daa393c75bd769a76580d35d2e68fddc7404d4b65c3dda54a7b7e3854c1fa3fb9aa0b7eb14f9979e8aa4d0f7c1a16b1d6cff434f2c52382ba795289d40f41c3c2f31b977e86fae8310e71fb58672871e92bad782850aa25dbed375eebc901dd0bd9e9273c087d2de24a51434bdcc92629f2ae19aa69d0bce0fbdae98c03ee5e261950b4afd1c7215b119783a68bad0fd1dee23391f8dcb35394899a352832d2754275e99746677801ee5c2cf3329fe89f3123193ce52efd31056cb003d2743615bf3e7515b3013cef3f388569f47bbd5a0b6862bd3530ec34707f4fa14360337feae21899e100355deb735777fad88089ba3b921627a53d82ab89795e033ed0ef0e879598a3163d4229eb86145e8dba7db6b9e4e05069928cebc7cc49d2b02f4b2793d0a6da10c5945366e2aede6a1639678e3ed7f2a4ec1da5b8c26a78124960b70b461f82419ab75ec0703ac0286f14549c844e937920c94347d20e4582e45057d2b3e5baa3a51c9a8fc05407ebc2c5d420ff8823ee160f294323bd0005052d25ac938e05f4ec0eed7d3b4c9e087c834c02433fbb084f2531c414bac8920b45ea75f52a61698ce6e747bd2e018a7d3c1cd1b42f96f3dece717295958d84b46d8d75a4952ea4a176ee9a87696e369ecc53d7465e4d3c759aed2957f5303b0db25675c0d4b889ccfc4f9150b5d96eb16b49f61794aa2a97dfb397fd3b6662766a209ac593ed08b00d88eb0131bc97179612d911ef00fa49e646b6152a13ef69f3fdb0d424df27496b44cbc3dedc3ccc7e25c96d8aa710bdf2bc45e85182e202c5b0d23dd65820dd6a65506376152d389a5e282c8b898527b317256bdaa3be98da98527c510afd369920d9b616058b2377b9e361af7dd85bca3d35331dc9d373fce60bff7e704678fa1e3737c79383e8c19f8760554dbf43148110a6068817e9c8ac81272e3fd2acf50bc1e0320018bdecf258d48852e9ecad58cc3faee4befc393bbfa76b18d66c07621dadcc78002ef3a9180594bc2267664547444fbbceaf8a019d7c22080086c4748b5a020d90209b3acc2686b1fe14c1b02518bf891fec37823f95658a15cd83ccc8a023c71c5e8fb9021d9a3cce4aa48622bf9793f56e2b3f7f9a6dd006e803ff2d534bddefcc3b24b60f90a508330be8390941d8cac27a1ff39bdddb2dca07253eb8ff74d3db78837cc02e3d3faa41e01012153f2b15df2423cb48332bd4c7625ed2436a61d91f1a0389906dd6a74a40193f4d051fa7a61472c5e709eef74f16f307e42fae827197d22412ad6fb9c9a40d09a9c7d49495b5ce2836ae9f82ff8dd452bd35b004e658a2818f1c32e2bbc345f80ebc54afd32aeb33708444fd8fc6c9b43f312991b83a8c4c7d1189bbc83fa131559bbcb69c8415099c3b2a14737596183e465433ee60189fc42c772a1175990792aaf00c7cad7ce604002ecadc5f73c650910570eaa49a7d602c6ab799a87a256888310fa8ae2ece0fbe026a68c2ac6fb40bdeec8a921ed3dcd3d9af03528a866778a11da18b06f8f85a2596f2170f572a6f939559cadd9e7ed33c225c55e4ba9aef80072a550f0d85931ac021f68703657f73e8925f81cd779fdf4184bb4cccdf667bf03cf4eeea24c54f08f4d158faa2574ddbb9edee98cea195ab7460685eec506f6df97d14d5e5989c054ef428c2b462661433cc2c7be41a546b09c3636792310c300da66e4776a4848b3a3ea6ffa0ac9896aa4d0f77bcfc15eff57bbe5ea37a0981d1d07131ef6c333740e199a41d0e12ff0c49f0f7117b31c49ac91ee9d33b161bba92904026b665d63083c07905ee95d9ffb49b1df8e4f7ee3b92280ed13a3084bd324e3dc161787a73ad8b36eea42d90f332cd30c8d10c34e65790d59095946f013a3f630b81ada24c075bc00b0837c9c54bb275ccf57a2ec947789d0b1c6595bb7f79399f1e9dc68d804a486c19be164a450b431381d82331abccbcd0cafa1934206e502f76478904c492be848b6559c3e8b2fe65f947c2edd8f245bd6115afd0974873134f6730b0cc74f359f06047671ffc500f65432ead4bea9f1fa6ebd86604267d1e5b5766e3d77d3c526e3cc2ec9c21425b53390a0398d49fb9a3775f4b65039932a8a6d3673ac46ebe94706b4c004eadf4bc158309a55493ab94997836fa9ad91e698ae1372c7228d282db805765cd2d761d81debd680de4b9ec23d23381fc5fe2f6017c49a453a361590a574c1ef05349642d9d65a687eb19753a73634726d6c6b9f10b21bd984ecbdb70c2d0cfd0bff0b3f6032f4832df2bc5c22ca9f792d6543552d8bb86a6d1131a33c3f7f1dc5196c49f4381bac5505fb655f2f419221d6ca13758d257b20ab394964a711b8081c64bf7894e7446113c6a978ec29d3b19ba2299ae26d748d797a244489f2a42d5a94679c731e80c7bd899e2623571368557cd441d7a0af8936284ed163294cbb32201e8e38a45cafdd20e92c8955927b49ee222d6f56eafdcc7643b416d073f373d3c40dd0cd913893dafe9ba01b2b1a47e92d858f5047a12877ad75b38158c2c0b65c2b55f5a9db49557d2604fb5a0f6bf58c72dfe3c9df25942b568fd1a071c05c8fd5a0716cafd86b3d35d2ab520684a650d028aa0b88c419fb7ada13674eafa74bc41994d7d37aca449c49793dfd8933a8d7d3261a87ca1571a519712d1b34f683c69ee819eef518111a23922b17afc75a72f5f22c0b8c091de2d124b25167d80e723da6b31d4da07924ceacbcebb118cf27933ca317752d4b94eba7075a264d9dc6c1f2fa0b49ae3256fd9514672ea1ebe7899fd3a07b814dc1374790eb6554d4ca95e8df0594ebb54efdef01f38b85dcc3fcf73017f2a7606eaafb7d0e2b75531d4e0d913acc6f52877977188c63a4c33730bf18e71ee6387fcac2dcd4bdb7e56f4bd5a5c373f9c815cceb67d2ced52357a9771db6a96ba54a3eae5aee928a4172d5826512963128855baaea4d295526a91c72404a8734e381e9ba2c48aaea3defaf35283b3aca3cefef3a6b934a317e7e7e689665493229294b4a4a2a259592ea4fa9a816957e4a3fa59f52515151517dc62357f54866414212a6eb8e783cefef2c4f2614399b954f9d23d95913922bad2555f55b140d9d904d91ab1572ddae1081c6a3b53423882bd792ab3aa426916bab12b1db85b91615e5fa7ad4bd5e13925bc0745dd7e10f3a212857a05c3b5bbf6942b9a6d8934c922b6d8bc6d1597ac1d28de56a465da36e3d5255b52cb4aa5ec80b3a50f793ebe6936b85c2e681a7a1d322570d0bcec684371e93a954043724106f411b904c6a1cdbd1651a7a26d1383a5756b5495a4faeda0c727df58255c97832dbc18c27d7dbbb3511bdfad3dd80a2578f72b723770b8a5e7dcadd9044af1e7537a1e8d5abdc2d49d7a8cf82e44a631255f543b2242c916e893311942b52bd8bab194955fdcbd58e90e4aafe48557d96594b91727de947ae341ea9aaef4ea59f5c9f25c915e72355f54036a8133a51fdcae596e091ab0d8b56d5d77a14fc65f5167fd603b98e20d713fe626496bb1d758daa823fee27d7734cc499ce75abe79a88ab529254d5734b74492c92a423b9bee3366ec95614bd7a0d73ade8d59f56ae2f25d52ecbb623d376546f326d474f6c59fc9492eaa611895ed57aa257bf618d277af52f4ab09fc693ebb72ce20ca713673eee4ce2ccc9ebb7a3380373fd8614678eb6d8a2d892e2ccb77121d7d7ed9f6694eb2bd251d5c9b51ee57a4d6e2cb7ef8d24b9aaaf3ff0465ed15b1d912d25e55aa170dfd29d6ccb1fd3552e54d235e051f0291726814217228141f0db91cc326bbbeef73c996d3bcaf5a5a25a2acaf5a62b03af1387dcb8c18a7d7048a6b883121fe80452de8e51146c7300948323792b8294b7225b446f834582608ebe59165b5f6c31814724c9f0ddf83b62a7a79094b767f77bfe6011a0e86dd656275a52b5bdef44125d230bf6834ef01849e2d99ce0c9db9dd0525a0e84f2f6147cdcc95f4e90a64dc1246f5f53a19337888b00e56d4950be4e04925c4123494418c915f6ed441cc915fd56d2a610ca17fe9a8a9dbc61970823a9da0e8d24c915114852b57d7b864eece40d7f3d4552de9cd0c91bc5441c49d57623db59833b20cadbbf9ec2c8897fd9edbf0e3601245792b51d36112457a9d3210b07b250be1d1a218a33a56f4694e4ed42793bcab552b5fd74b72b5bfcd9bc39d1ca1beea2b71d1a6999f0971519e5ed2da191a3bcbd6336ec033a81a49de8641a59a963293c91a604c237c2f0235ee396586e0a0bf3b557ed55833c1fe409ca54889ef6348e93d3d31750251a473d7d71faac7519c995fca4cf6ed02b2d336233204091b32430394b22ce9c4e9ff1c41994d36744e24ccae9b39e6c8938833a55397dc644e358393db5226657d82cba2df2b6c3247a43323d6dc995d6d276d094073d633a3dfd41af5a4e4f85e4cac5e929915cbd9c9ec2a0bba90d323d9624579c516986e5dd3791ec0ed5f18aded1cf34f4449a498da33b3d768421c5192c08f3912bec545382cf5fd0a5c08ea0b3cb039916b58830a1be0ef31ed8535848ead853c72e04e6d79b958a4f3d8775dd54bcb98e3d1ec39ec238a963c781f9f51cd6062455dbafa0bc3d75b7c36cd7eabace0ec643afa41b34be974c5199a6be09c10ef3ed02362c8f5a7336da6ba2f6c286e5baf066458457645b1692730086533cb06387390cbeb9708ac7f5eba9a7369b882fb072202758019295fa0f9d5b7295d5d20e4cd7791e1090d692ab52c9f3feaeab317c7c7c7cb22c3b3a7a719b554292484825a4125245aa48b59515c995d6aa3ed5a7b68a327d6947ae342359020a92463b3b3b9ef7779db519cb679291dc82e46a23922aca41d12afa188513b82932e5ac68b2ed6c44db5644e4026f45529564bbe58ce4aa32d18670465a129c1167945ddcd45fae4b0b22b532bd6674fa2d081555f4305d672dfea0138c720065fa43a3db82327da32e391bed84324464a5b62c1a47e76c2bda582ed7ddada86b703c5245b72a5a451fe401fda7f3c994ebc95453421aae458745a65b1632e5764a2520d8526dcd23997240dc4fa6af8913a971d04f2d7a55ea6b080624579155da7822fe361764faea851717b24a3b59666d0793e33f98fc957632fde9724c448f1ee5723fd1a34fb95c1397038a1e3dea7247a247af72b9a0e8d1af5c0e49d7a02f01c9d5b64554d16f4cb22136898ec8b9254a4672b51d19657a17772b922afa97bb191dc9959665d61e65faea2357db4ed6551f94ea93e94b48f42d5bd419dd5b2921657a969b237af4db8e5c955a454fe92dfe32fad3b6f375cf317277b3ae4157e80b10673ad31f20ae2a9254d1d3d3e4e8aea0d47b6735ee8aca1d61ce287af4970afb71464831227596957a95654f6c3ed4e5f45b12d1a33cd1a3af78db891efd8b12ecb693e9b738637a8933dc29bd8d33df29fe3828ba38f37156c8f4b4fedb8a32bd762457f49a915cb55c6a49996a4699debe3790e48a266a3e72055b156fe415bdd511d98a94a912ee5bba93f5c974e542251712a1842012940b83e0912cb3b6eba4cc3e9a5c5b729565d6766d65fad295b9f9891e7c0a17e1728d883a436edc913756a44adfb8ff88adaf93bec8f3f2bd04630b26f9a0501e42b22e5c845461f9cb4af7061f58a49964753a9e7afaab8958ffeef3ae234a72fd1556d46f22d57fad848672d77e51aa1d20a7eeb4aa9ea7a7d24a3fe34fd7a89f9c022a4ed56f18d65bba76bfeb80c9254e074cae18967047a1954f7450628e1f151376cb3d04b404871f9be51e025242f412af99bd64d90b98652fb21798bd642fb2972c7b41b199bd64d98b245a96d1f6608430d2a04993096343d4b3ac258c11c6a15894936453f41941932200810a2ec880154190239011723c2ace7017908e8ece0e58f15d5c75cb1700e42f86c68daf93c896596cd14cb27c7f7088849192892920921bf9834994c025566401990c49a20a199790b1892311494cf2452553c85f5ce26345969734e0c97288065ac8f2afc110b2bc375483a3dc4336384296af714196078207135ac8f20c18628249962f020a59de88a11b504107073ad8c10119788a14a1c7a788157e868a8021cba11f21211ea2560e9214191d21dd20cbc3241da441e7063b3b60034f1347e85122cb1e3282f4e30411509010114f963dc483a32c1f731667be4d28cbc34d28b7d014497913da8c907dc82dce40a20cb7242cb825c9cdd9c4d2155d37e4a36404435f68f101419e9fddec253ea8424a9e73ce39b119f97a2791628a198c60ce20075d0a2613544d6610021990010c43621c010c2be8cce0838ef95aa8eb1c1d637a65a52ac295f686456e4455bc8c19ac4cd7d10091e55b75bd74bb7c1591e5bdabaf0d64e95d38124b298cb6157d4cb4020c482527d80069044d8fb410c1bdc71ccfa41fcc16d0132da0f1424b0648f9eba22cdf56c877f2323159ee2119b4e8921944accd3da4441bb2b027b987944022a2b50f52061209d1d09841a38b4ee491349a9877727970b62f8aca646ed0d050e5c8724ead7236d8c466092bcd8e863703001e958d9a7925bb2eecba2edaa815b9494faa68eebc24362f99f3a4f39a5794534e39a5fc94726612ce89ea1848e3ec0bc503adbbe17c9c53e2ec0abfb0e7f40ff62cf19ac8c3cd715baa240f7c81b9b806b9d3ed9cd23f8c2c78c9d95ca39b86e250a877af22ea5a09439e9724f6933c197ef630e529a89f6e6f0afe687c3437b9beca7a6f78cbfd6ec03f68e496dfdbfbdde4fb12f7433ce18f473edddecf3ee5f56a29d7e68616f615e67a697fc8a0ee77bacb4b9c8dc51d3d18bcfde28e5e0bee6ba50d5fd421d75d43dd0f66ad391d50e59eeef77cd2ecfda1b37dca9b4b4067abf2cbdaffd0d9e21b5a5815fcd5bb1c723aea5b6eba2aaf9129d74f56b939b906c1320a63d086cb6b644dcca2075d60df6398eb05e622c22c05c71f8b4ff01dccaced3aea792cff6458fed1d44896bbf2973b391b95a7ee4bf4506f7977bf9cdcb1e49614fce5e494dbfb5d057f30ab1cd67acf9391913c9247aae0abca57aea9ace0c0aafcebb2ca6ba2e491f0baaed35df0e9d8e926fc7557777b597e6a39ca9b1302f5165c6fe7eea2ce72bf6794157bb8726d4565e5d637a75281e8ac828360d93e7241c03469d26447ccf51980b9e21fa8af5c9827b74326a75ce5167f5008eafc24f920f51c411e2323a12322a496fdd745349efd2793abfd47a3723fd34f6f6e07e4c9292af88b4056b9bd9f4cb6aff77b9675d7fa1aa972835c59e5cdd9a86020327f30a3700564720afe78d87b7abd28879c0dca4fb723109d2d0e7205d181264d9ab4b209ff90c9278f3b72b5b5aa1ec6e4faac56fc6df8078ddec997e7933c196f71d5aca933800891e8d1ba71487b6534cb7ace47c80361e7c060c4e090d135e2bf1b06e0411bf1dff38c4cf4228acbcd43015d63e60d442f7f32594787862a80479228a3a5101262e180d8409c8155682f62a199340a3212ba060c401b2cbc7681c007a00d5647d7f824ccf276864d58e8c3920f9093e1a14fcb962c0c90abb74adecba48c5d7d5d04d334e4e7f5a169c09ad2101861bc380c6491bbade8259d64cbba3b2667de0b68b210ca0c4050a28b88a8c602b2bc5ac5e50b0359decba65c49d69793eb9039148221b9331c02c18ea9e5fdc6e98ed3f22a6a8e38c8954ddaf12100ca2fb987424064fefa25244bce46bab80c41cadf3cda8288792ec10940c81f3542434b6e2e2e93682a89392ac87e14c800f2a674c43cbf247a51069616d1d60c269e3f716662d1aaf8a905518e474747aaa0e17137d6c5c54546a665c4564427c3eeeaa0582d5707c5822b6fce86e535918888517ec94d44e40845355607ca53de33af93cde97dc234283b02731345afe584cab18b7abd29775ead6be5a812cab5e6b0cb9b8118c4f591a2c750ee970198a27807cae5738d440902e445c6404ea6c03cccb31586951c3434f9c80704a6264d9a346175d7b0ad7427d09d4dcc9fe8c5cec7757aac00353f727af2751ff39d2f98fb28a78460e5698b0201d1a0d40e7a79fa2eebb2dc51a0959be5a02a0e3081d8586ee7959b659cda51b37ccd12a78290f312a778dcb4a8d103666b12b576928841d18b4838ed2d1807e3f0d8812c97df3c858720e103cb05a7e40e64a5a4cb7ba4eee272212d4fe11e2e7ff90b16d2dd05a724e6f17297964b2002f448f42e6db95c5a44e5b4fd2146b9a7907b68c808326d512671c6f4f82c1b621f4fab50c9f1b4886a91291639d22ce47829ff6c892691bce48f59447d81fd2890c4418c381267604bc21389bff664689e9d1e3b6dc9a352504e6f59a76d207996154c5530968251f00957fc7979074dde2890c9740a34b31c2dae004dc6f00784e9a6933b91442f4a1ce40a424893264d88323689b6162acbbfe4eddf34ca4e232f4faa745c789e6e9f1fc53f68b2f60dcfa049247a1113faf901029a447312116597372bf566c9899d3ebbe6d2b9d6d27579777a7bb43c75ec0ed1f2141662e4c6e5dd85a4de22790c4961173c892065f9d91afa409119904a1b9d5402b59800922bdaa29802490a84bd33a53ea4c4a91d9ffd494c7fa80f6542ca679c8da42d7903135b391e43527739057249e13b7bee1c123df9895dacc17e3979ee64996d55bce46c36708420fc60c8a5933ab21f6d115d7174b493450f529cf926912de2cc377f72fce6901c5b4b620f2ed48a38f3fdf801eaf191ab26b2f3f95da7adc6e1e3c215b82e9168651a85c6d157e44f6e91618b1a5d17863c9047082ef77161d85272e991a872b9cd921253a02a02daa2401f355a82f6f4c096cb5b6e4abe59ddb1a3388321c955cbe3b124aa4377e4cac5e3290fedd1828d3ab9b38b7be94855fccb9d4952159fba13e9ce23a98a7771646dee2110a4217ff3c8e5c2ee9690000422f3088910bacbeea624a62dba641ec5792404ce884b0c3a310afbc122b8127df041073b20db927be80936e427bcf044d14f4b99a3dcba054e2a3430d04498c92e92ba89acf8c88a184708aba50a3b02464c0a24403188e1f3a29c72ce396717a44ca459a994d1186126e79c534a1b39e9906c49447461d817ae2fcc78c10848ac0470de0c6d2e51d367ad22a3226dbbce5a795df68ca7dcd825239c48d7135910b66801d0132420b2001e9f2764d08382a427828082999d4048aa3a7b228a152c00053a3a80b0a311bb30ec8261041b2377145d10438c28788105387cc1b2e48ec20b4e14c10b51743d48b62e22cecc13cef4dba355d76d77215f4ac0130e6e1a84105a6b6d2dc1ec1f4d861d764cabb2cfd4d8ededd10768b3961ac34abf6e91d28fcd2eb863348d3078cdeb9a9e91adb9878e78e10a360bf9fbbc47433b524516062928967be8881443ae9f9c88a717b439693721bd539e2c90a3ac79e2c800cdd81ba50239c6d32cdf37058165898174938c6118e711391ecec72c6e51d7755d5729f7d01126e4cf7ee640eb188de330d5fe936b13b91ee59a45f42a508c9f628b5c638c3046182352aeef187f72358254df874690ea8d8f317e12212455f1f144141101e39d58bb76ec12512455da8910922b228e2e2b9e42286b4652a5d5973eb803a1acfdeb298ab276680429b3b68d2065edb0891fb98a2c4d3bdc01529ce922ed2db5778cc61323cd82968a5a9cf893ff41e24b9992513e428886ec59ae509f90c77e599e2f8a6ce7963458e9237bb06338a2feb514ada20ca5100a6aa01f9f9d3c44d1bd018a1ef4bab33cbe6b39cae52b7749a9682a97e5a8fb37be69c2450a1d54d20a5286c75f4be1c828432914ada0e46c22c65e2335ecf60d2df02704e8f04280ae8bb3b988446fb6cb8d30d83eca31c60bd2a3e84d9a459eb185099bfde0cc277a970a3b1f77ae9e222bdfff681010504f0aeb89de757474a4f21ea9428332dd30d91367a60cf2bcf4996ad0e9c1ce90680434d48321ac83f29c8941974b0cf58027cf5324712615e7e74ff23cecb1fd8ede8ec9d9348ef826287a2a1772f488521a74a9fc3aba7cf2853f382b6f79c461b9cba3cbcf4fea86e5a9b33ce5027de42a75d31df5eea86bdd6de95a30cf9d4279c68e3a73fe221267523e3f8be40a7578048d60512b7fb2a7855a9ff168ca783f0a75a1905431498a1e44f28e1e3475324fe2ef47ec9c1cdf728593c3ea4caa7eba46aa8fbd71aa69d668d30873f744c513eea993933ae79c73ce39e7fc49e5b84f8e3b0fb99a5a51a61742a4492f26d19bd717a06a7e9221cfa9863c4faedd0c64393e1edd0b8bae31df42996af205b2a767c87eb2470ae105b5679d73ca25c823a0b460e1b116b6445bc1c2a2b460338de62963906da52c3be1cf5a3c4dcfb2ad44b169858db95e42d1ab6e1983691b0796a79c22cfd951fc93373092a704c2fcaccf354543d14e9ae998e9167f59663793e9d7e46caa50d64a375561adb5e22f55aa37dd1f4c2653ad37d592092b99ea4b2b7d714a3b764dbb66d26ebda95ec3b2c725639e0c8f7a8f05746f298058de52106917666ddb36ce86fe6272ed3a6a1c58f40a8b42abe667e93acaf39ad46e56deb9a0def21edd5db09095776fc1428cd40b5139eacdeade2a1d16d2bdfbca85a0aef2d4102a47fd46e5a8577cb3f2ee3571720a6816cb4d5514eadd6f50ef5edf756fc1382bef8ea302391b1e2c3db98347b10465f815a10caf72a5206299577951854df140bdf3d7513092e208a7490194e18b6047c1285f4771267efecae2428a3312338a1e93c696604558ab8fe2104552055f449cf95a8a534ebba6dd5a51b8130c046257748d79b1d6c5965cac08b3e2c87e368af81167e8e7a4415235b9cfedf3725e6e1167b417f5b4788876bea983b5bac6445dc594325d339d6ebad8d7a9d33b0b01caa6db37a7c3def49a78ba3f98ac35996e4d266b712a6551ac111a8a351d25eaa06b74b6a65b5392d5546852ca8961589bd2de9673ce0bc34e4bd74412e38c104278b718e3c4d98cd7fdb2aef15d2288914a794929e3c4536230cee092f18a18931ec4b0c65f863b5ed7bc660e8573083b646a88fb983300ff86cf9be1af8d72f6989b828f390ebfe1a68688390e4f41dc23e638a47adc7018bfe1301e00690a6cf6d835b128893d429484a0241c654882dc43486802094b202189dc4354d8dc43541cc9dcfd66e64e4caf91abd4498c13ec611cef2a5c93c9958753a51838558a8153252144259309008f817164ee6537ca30e336fe9d9c7236275807b762e3a6e065bc5933ae77d57bc4b80c2c44c663c8c0292e47c815d0ac4b55ec72581e4ec19b19f70eefd5780c8ce3bdc671627c460a4b46885291540ade06be078dabaec238399a164fbc9be262dc1477ee9e7715c6b171ef3800788cd410337ad4788af3aeba9018329ec3eaa1bacc65b0100f5fe0467519188706d748553c1052156be29b65037f4d44031b816f1600b0e44ede31b2779b756760bf4e7a76f29314134e0d112386eade853c06eee10951e14b95097bb8a5ea6ba19cce1a0e17c6ad81fb74b38cba7d1d9e0809477213292122520224747294fbc18c029fe12c86848a868ec024cbe41e12fac94976b60d951ae21e873be01e079c72003e8c18f77e13e31ec63172729c141703a7e05537321ee331304e8ac3a92166dc7b8f19f7b0102337315ee342bccfc03d6a7cc6676021315e03374b069671151662e466c655172203f7505dc6656021dc55b8a5ea44939c0da732e3a64c4fa5a49868524c29de4a0af7d44a8a938153284f7137329e4aa1c898b1825354b65b141977064ea53cb57273192bf886c655dc4da5527a7087d67ec6950144e66a514ad69eb0acfc2b87f98ba7522e9ef297a79e4ab9dc9452397794afd0a4c0bcc09f8c8b14cff47217930aa7b8d368c12915942fc8cc283fa9bc26e664538a3bb9a9d4cab9a71cfee4326e6a050f41e3aaa738dc8306567dc6653c95827bccb88ccfc0324e375d2032a79c64dc96aad355b7a5ca05d2dda4499336649413cae995b34139eafe885ebc4518c1c28cf21f7e1cc2c37b82bf994d87af917106e5b18838739a97717892c15dd51c96891ec763c82f55dc077540c8e16f66eed7e1551d3e3b39bceac2132c13bdb73d577ac3ebba258883cc2026c7711cc75d1cfe70327778af77b7ccf418387572d5735826ece1d4094e0de13dc66fbcc7f8c963601c2327f826c65518e75275f21827b89fc3aa91f0367781d0264d9a30d921b3c680dbac184064def007b38681c8128e000eb759306eb35ea260bf1f5d84b3ec628fb9cdbae136ab46cedb196313b78ecd81892fa630e79cf2f04a29a5d426ca35ed1aca0f9a0c3921b0b6fde446cee6243e27cbfb3d4720c39fee372f67da6e6f4e8637c8b55ddeef46deb8fb6d599b3ae8350c51d77e733e85c59cf3f31e0d19334fe25544eb984d1e420861a4810d3112610bc96b0def4723c39b60609b551f5f83c87c437e850afb6d25d4077f75ce68640cbf9382fd3cf983468e9797c9e2cc87cab285a609e0ef11ec0735001c28cfc3b8d6dc8e79183fb9dfc9eb8366a4e4ec7508c04bb502086c9251ac853fd6da1b376e683a04e03afc6ace2687d7c4d5ccea5773363ba04ea893a6556b6db53f9c6c3c8a1eacb54a1e0cbb2857351b7c92c706361ee5ebd5daa4dcde949b6e54123d28f385630bc79947f8d3456022ef50842345189277f80e45207245cee11fcca72da0489273780e876289c66dd8c9c9c93cb9e289cc41871c0e374e07cc395cb3a75faf185669d0e9302c2c29296f8e8525e584c36e6861535236cbd9d4aae3f4eeb5c26a391da7eff0eb62ab9f6ee7541030ef70987738ccfd72f20edf2108017c00ef68accc8e9765f6b7efe674c01ff071bc26621be5ea75b8343434a75c3dca8534a7f9e9d809e6155fd7f59caf9ee535b2068919f52d25057f39574acad53511b25cabbf2e7b5d36d6b68c8a5a45464618923b77468216b2c88d043128b1b9912006241ba783dec5bbeb020a26906c81040a22499664fa08c5904c1fa13852842d327d11aec8f4ddcda27797d45de28c193366cc10d23366cc98819343e35c0aa72cea299f05a203e6ec33628d15eb5cb81cc31f8d8cc538eb23516b0591282a6971f6cab37036b57e72db9bd38e72533a520ee328efcc72181e5eca711e5e13b59ae73c95c2373cbc06e3f4701e8ee3c3733c87d5dc3d0f37957a7eb372dc54aaa62663213d9c87d7f4e003e4ee9b7b711eee759d2e9657cc741a4f0162937d06d681e3dd4df7b3f93fdd171708ccdd258763ec4edffd59fddf1d1e77f45e70b76121e8bbcb7b81c03c00fc65c771940b738c9d0a6773e10f275f3511757a146743af410e08cc28f745cab19b8284c728d357242208657a8c08addc435464d1e51ea2624946a293e9afe48911830346a9e6c3cdf11e2e0f7f716146b930972ecc382ef67b61fc8147cf72dc87332007f6e10c38bd876bcd5d3cecadf7874cb6f774c19a68aff77ae5250f0e31317e612ef0310c8ea84b4e08fa8a534160c791a88b44b65a8b5142501f6e0e0bbb9d5fdcce289defeddcc3cd61e1fbe5644a2477eeac71a86b184cb9306f712665666b32bd394a4da68bcba2579f72ba66ef1724460e01f51988d9877dc7fdd0ddbe539e723acca89bb2efe13039ce728be4c029fb1ce7e1ddfd307cc2457ac0298b83d8e1399c073cc4880e01780e3cc4c8ea489c656426b56387e7f01d9ec335952d09b98790f864c8518cba30290b36559f9383d8e102b800b00fd4777867980a2287d757ec03f51cde7905f3950e872ff8fb75b82e8e934f98b529b76731d9145b537016bddabde2d3399b0be6a77b17f7833987a37678773f9cbc3abd1f4ed621871b24e61c0e7383c4bc03e4ecb31baf34cfe24c3dcd2f997ce3f6ded0c2d2fcb3f906cd339a67375ee284a04d9a3469922bcea277e3cde9a0c137be9ad921e8c6953a5c49240057e670e51237b01ffcc99a83c9723dfd84bf99ed3526ecb79ddeb9721c67632d863f1ccc9b433dce543c3b16da75428d03e61bb096aea32c375a8efd861baedf7043938b93afb7d88b0178fa0933a5e4a4d4c81b302cbbc7c0313860f853adc51fcc57095bfffff3bedb5e3140aa2aabd61b99a80651db80af7129b4c4ca4f39fe753cfcb331efb8f2e1313e6058d403e601b754c9e0962ad5ed8cba9d61b4beae0ffbd34fa7afac5cc3b69595affe74235ff57e1727db5f29c71abb3f6e4ec10180364eaf91315f077361c6a48fcab1a75c4d6e30299ccd75dd0f02d95ee56ad7c500cc11c8f55f677a733627db25194bb92b1a2a25db265945454545e55f17d9fb5d08e4facb9aae1f379b7000a00decf67e3a646c0543a213ee681a07ecf0977df52cf8eb360065fc05fe3299bbc0aadfc62127848d9fbc466600dc0f66188745366ee3326c5c067fd606fe7ed0c83030004ee3aad74800dcce32ee97a9eed7e51af79347c8f0312ef793f8078d3c4fe3defd6e320da824d2b81dbdfe2582fd32ad844f5698c8f525ab72ad7f78390bcb3597bb84fde2d191f77cdd775c1d2673c1b227c76500c49e823fef84bfabe0afc38a60dc895e123d70080b49f9e61ec2c292ecb3454fa6711817dac9306e3fb3761921a9878c4044fa40266c66b6ec277af51867637116bd8a82ae016fed0a13ec2751903f591467ba43974395c34b14340ed36947bc9049103077f466ae4fb95ffde99033611df51626058939eaa864e070cfb396d6fbf066e5780fefc1c37dc0427c380fef010b3172e3c379b8901e9ee3cd8ab906b7a813756024459d24265107e64f0dd1c373bc470f38a6870f98077c1ef9e3917fc8641818dcd13b86f119340e23c62d0ccfbbaad398110307d59bb39171a1920b7188f1c3e06f66986b37f9f47a0de35a6eba761e9ec3aa16a786c8711e7e93e33c601c23f638f526c779380ff039700ecbe2efd69eee07f329e5d5d6cd743f1ab962d36ba4e9dea7dccf7b7342c0b88df9e9de70c983533b6246ddc56b24ccc5e1302e048231f7cbf2fd2f0e312e447299d4e8a35e666badf5516f2d13ad96256a1129c100ccf65048e8542f54ffc12024156340668b81402660abc2d60b201344ad97291c11b95ca2be1e5efa1ce5b0208c98b75cc1bce52ae532390ebb28d79f52ea4d3030f04793eb636230c69e973fc92393e30e19e1486e79e9da4ffe82c48cba8b766df3af18ee9cae35077d603e1df6f02ff3e19fcdf65f97ed3f2fdb5fae78b87dcd6da972711f6e0fb7e50f997cfaaf9d2ef409900bf330fd29817a0c63c8266c0893b040c35aa3721ffa68783519da099aca18ae0bbbae09afa0417a45a88529b33c23af2967f462cf75daae9479e9631e3bdc6e68c1a68248f1318fca9d3b7f13a776a0327654c660cf77ce1d67e4f624547ca09480b00d4dc02e7a51ecca4209dc381ad6de9c19c811a3f89a1cc8f130cec8432886ace5a5564d9c6530c3160d34b863769baeac35ccdd3967420dccc8b25d2a6345d60c4347168c11b200e7ea406bb96261d89583102c56ce3c0246b80520682c0d6e57abe6c90296456fb3b0db2c0d76bc6eb396d0b03967841ed0e68457072694110e41c37266a075a9bd920660074e3ae7829009373c10d4829d12a020091f104187e107f69a584e11248c0cdda00966e831ba90a022092d4ef043a63bc3fe6e83fc793468aa60227f2dd44986aaa8414f14296862086a1882c492b28972cf1b720f1535c9a6dc434548f688d6cf826d2e421e493e45d306441b0eb48ef920cfbcaeebca2ad69bede6dcf29cef0b4462b7c8764d6e14723371a66aa5f78138409c89327af2317a387048f476a8dd400b11fbc9e46db2c06e7126420ce9135ac764119569e24a9b8176552a22ee207f4d09c87798d422077104b4b09f0c16f693c9376b15bde806f2754920aa906692269d60e155b4b0f0f29b110b85748dbe0a182c3c8c314231681d53935b080c36fe9a71c618048b54d0b41c67e39c0c71ebe8d93d67f7ecd9b3bbc140318c6254ca8961584b2963f2bca83c867b46b694f328e8c7a6402b652f3dbbc41fbc32eca39f5d83bd59edf89af304cbf097fda2b77ebb27d72ef7c9c38c524c7f7439fba4d8857f1421ef8f2ec74b25d06fdae18d2da4e672230c9b768880f8fe341c44faa83888ec472d621ffdc1893fd87de1ce4060ee5f37b5e37afdf5fad227f6d19fcfae5d3aebb33b2b9e1b86951e5f7a8d2c5d98afc38abfaa5dfaed66af77be5ed330bd2d61fc75af8f2032777fe384886fec235ed334fc553c4bf7a15dc336cf4db5cd73977ec22032633e801c41af8f2012bb3ee23b5f1708fce4769c726ae21df1fdb8a3cb5fd32a4a7d9230768650681d330fa1fc25040b1f2f2bb0e53819e9a8699a8f2247c8b08cfcba20b88edd4706642ec281eb9d254e0eeb7ae471e1ebf04e213a595e0f8194980611ade116b90f9108a069dd0ddf57b0dd4162ec9eda15ec372584337a57b0d9a78410c2ac218470369411e9ef8285ffbaecf22f71e66edddd36ebeedeb2190498bd0f2184597e9ba8f932e7dc8106000fc06bb0514353386ae5aeb1d316bd993b0a3028c95df41aff784772fccb148260458e570840a0d1488185ef4d87488370caee6e8bd45300e5eeee9e32c6c4c4995496b7eeee9630b08d7d3492fc804681902a78db51d84290b2a09021514da7e4869c0228ab846b5860371067e2e171e20c4df4e05519e64f468706f302da8364d9342746310cf380c019bdc982655858f089d82b04bb5261ad15ab87174837418a335be0479ef9b94d21996cc43c4bf70d7f7f07b18d9d8795e422205b44f4e6514e60e790a833758032c59148e4c178628c31c6083725b496f029f2018fbd11208d0862fb4e6cc27e91076a10a7b2c76738882d0e49d1cad8e3cc1cce66346275a2146c7cfd23ce00cc1f95d8b586339e60df6e77967f453a1669640552d0c91057405a0106223a39620dbb189cf9ab3ee283cc8c1dc38c88de3c8d94c2d94a944c1d29298c3a3b3c30893c672a08cc47846fae07cb3b8c8343852776585d77712012419041100bc7e5382fc7717178533b4acfb961b99188bb474e47841c8f96d36b5a844f5d23f4dbdd3175c4eb031ede5410a5c797bea3744af107e3212704c70096a7ae414e01cd6a79730e60790ae31c216f4094c44abd7b0660ce5e23e32d3dbba597ba8b0341c03385100bc7053ea2a7904410cb883cce0b3ee286198258296ca474177c04968424969193b7b038c1ce97ae4c5db973c89d3bd12b510cd57d6641e6cc6cef446f422b8c66963ac212267e8aec767b7a9a379623715647ab112caba8e8cd883f1a18362961bf78abc3be747abf0c578046f6615fbabd56baf1f4f06218a5cfb0434b33faef26c30ad0c8df4df69e9f3a53c7b4448c31e66843b1c89361fbed1661f9d54165b97de441a1c1da4f163c87b07c0e89de1cd29de52831c218233c1dde53778dc0b35c24ce32f2d2b19c8bdc351695b7ca63562a7dbb5f4ede340cfb0f9db1e76478bfe7084c085f57de5c94a5d39b93e30d72e5151c0068e3462ebd466eb7a3b7650ee51c8eaf9147dd6fe6146c44f47ed0c8273c77a6ce144a7189fad947457cde99608b4e9e7df6dcc4990b70df80c8d8558185cfb2d935127e592ec272ecfea0c93106b119fb01224d9cc93e9fa3c6932b16dcd1cb6663a16b58a16dcc6b175ad135e6e98557942e3cca227a33ab6d141fe329463f9a4c6113585932eca92c8bf391888b900e3e4b92f2bc4f134079c6a03ce77c4667a6ac429e3a7205ad88aaf979052c8ade8482fda68ecffc9ccd3242cb9167b24e0dd041823e72c5806cde8839fff2010bff02027b09a5441b628071f61704cb7d7923ebb79d114e4a31ce112cfa2b23555146aa6472c7c3932a1739b0f0510a1ce4f8971cb0e2e5fce7498f860b27d44352d0c9b1832c2329f0e4af5b9c8e148a90bfb6425eb38b332f71669281c6cb08905808641e73ef319fa20530b862152e256cc8c109ae147477cbeeee8edd0db1abb1eb6aec9a92045a1c4084534a29a794524a6d421bb023b431e5001ada90d25a137607703d8bd08694529a8080958680ad602963ec18e337f3978ad0463fe6993b69638ccc119ff2d76519638e97dd0def17f3c92c718cf29ab223c45840712e8c5ed725e31111bb9a482831d8a4dbc69cb31fe1bcb00bfb81c5ae26f3921884524278c2a08497d863298310c3221614e3a6e85637567adfa3efcee240b32ba6db867ca984bf23f2d5860cc32efafe840328c5b671c1d8309e408c4e194f5e34db221c006cfa2a4b598c56c26a29533cc4c2d7c489d9b8a49098e7b5d2f6755b561bc7d4b87b6a95fc76a53c59205fb133407326af439a4ba73b2c964b1848d79047e44b7275bb22044e402206186c29f7901236d0ec25bbae086722f4e0fb82d73c84104208af39bd6c622f110ee03ac5b2972c6799e72c4d6cd2db7962d9cb8bab94c15206e11bb3557cce2cc9946491bf4e52a4a40a29e418e42b265f57138e902f254ae4ebc615745032f97bc9c1841e26846109567ceacc107476094755c8df96278aa80479526188880b4b90420c2588c00a4ab8c2da2fcbb009f644470be2764a5089f800cfb682522b49ab415675404b4f604e10ca86884c70cdcc4e91822ea080080f04996147676768880d44e814a5d44026cac490813de58e420c6c802164b5dc518ce104558ce1055f18c30c66f4d82c771463c88137033ba99079ee28c850c5fcc001e2cc67a3a60040a0ae6ba27e20c08413af28818040a402851f9ca025a60d489aa8ec0401c8058c249028a11205105c40052888a09288a0029311b2eeeef6011172f7690ac0a33f1b675266314fb0f0fd3883e7212b7a727fbe5c97854b50824496f88978868e872965747663d735a38c538832c2d2a905c20b4613b412b029ffcd39273c651f6d62fd9a98d1eb98bcaed933a31836e7ecee19e48ad3057d2161e1e375cd6be294c472c4a2db66d9b265777777675052011e368700982057a4b4616268c30b754ddc3171e144cd84104a3803f003fb6519a8a58456286163bc1a9b33b330c88e3dc3b28cca2ca318c33d6397638c1d73288c4dc4d87dec7336f6c67e659916331a23ce6a60d1314a6cbbc61170ce6641291cc9f663c71c081f20e535e735fb03ddfd5386724af99a78c1fce564f9a923c2a3c81d68b2bb5bcaeeeeee8e51cad9b108730c5d843093ff72329c17964062d89c58b7a9d492177627463367dfae715d18c5e6293ebc2e2f6bd8d735fb7a4d2c7537be2044b141264f39a544a26577c309610732ece779fd82311a6918bb21ceb07c733912c227c42cce5ca62ccec0381ba722ee5cca16e83296d1f79db3c212cce095e1a71c81d4eaadf5b262b54a292fe7155a8c51da07d5a880200806913065f6f929bb67e4bff92cc64b39e79c73ceb89aac289b905168cef63c19191a1aa12c7dc83e64d3eeabbb9f050dbeb24bce970cd3c83db3d2bf790c675225e72f0c772b20a96ca8a46d15753d8d3a4533224000008314002030140c8804a3d1682ccc13416e3e14000e839a4878569cc9b32c88614a19630c30400400404000406466da00c0c436764055e2e393cb7f7b1169696b44dc3d53a14306f060f1015863a2d2a8e5843b9ffb1ffa8beda4fb023d1822bb81e7dbad20d60725548b59eca7d708e201e3b7810fef2df099633a29698dbd2f1ced3defba012367169b549e4d97c89dfa747367248fa832b38c5672abb70631dd62fb7c83312f247bb3001a6313212385d857242d53ca162676cccbb2253d5c5e75268c23f738cc0ed896aff9c3a49f7b4211fea5dd17ebcc4092a25af46e284d62ad80824a16614b6585ce602bf3971b0c8d51f74d0ae44034f3aea9ecf41d62ad7d8108397e3277bb31d0a1a1c8771c6c2e2776520bd4328b64ca5ef0d7aa8ffc40782d4e095f26371739baa153e4cfb722c8e14744f4cdca76cbb26eb4068f060f03935dc6e692010fe6aeb8bd090278383d7c603c47eaefa506271e63afa1838ed54ae28f32a6b9064e12c10b0b4488bc7adead5c92720472bc2420b75c37d19f2ffee648bed2445cf523c8b70c463f768135a76089b243a87348f645980f14e377a9cea930fc076a81638f0d0d90086e1d54713a8721f80ec81b7ef4c39bda043b160e3243110d5424069a3480936c7a4d954cd512e0642e15543b42337a6cbdbd8b8d281116e2510fd134f9c9f57848ecf632a45b81b40d5be89fc85854397205ee5d25fad1ae49424ceda8258c431a9d380e047c84615b261da9fd3d61af153243bf0aaeacf3c6b18225e8c690dcbe4416ffce18c230257e1d8cb20e0c3e1fe18fcd421986c2399fa401b3eca1ef13d0293c667ddf4869e7858bd67ef8bded878b01c03731c2ff9be456fff7694ddff5f69e73e8a185cc91e73b8fe6a044ca8a7ca55efd7ea8f8961e72e36431c4611d3fada9655befdc3426b1c299cb0487195a16511d77fe3b83ac56a9502e95d8a00ccdb971c23c1dd65823ac470d3418a6fba0523b28c099062a9e98893b143d5a8e1e9b0f2478495e81b84ac1722cf92302aa9269b36de546705a4bd228249def296ff7fad39edfa4317049cde183030ff9e1a30389330ed683ca5bf18a1f1c5d1c51b32529375d164e4ff80208ecc4ac8f2b3bb7c4420fe3904d931f937293c371d5466e0aa0e34b00d6acfb4e0c58f7f476a28e13f9884e0cdee4b5eb55c5564bcfcb3edad5367a6a5797caf0956978b41005a2bba3275d275c5d210e7f919a800383ae15989db5bb8c2f32433a440bc8ecf88a61e53b75b7ed8a01c2e4df9c4062b1c2b6fc48f701d70a8a87e34aa2014adbc13e7245a93bb0c2a6f41108779272ec56c733252b48e88ecfc0c57e7b989db3a5ccef273b165d5394961537143bd85c1bef0447647df647a9ddb3eccdf51f021bd69a5c4814db14a2df1b3986e44abc4dd8c2e9efc10bad6e0edc875bbff776c47ef0070354dec4310362cd23194b7037e939e3c6dcfda97aec58aeadeccc3afdc97f380e9a284383367c04da44e6f14a2f6f6046bf80c9598f35331f1a0e5113ba8603c2f863028743239e6fb643fff67e8948545b549626777658a5a50cc544b4e1639e4888859c598a9279f210a81dcaa528ceb010399ad36a9dcb4dbe86e2dfb9b1ba3c9169a3ca4ff1c4d288165573338e200b8e6140be97975c0a4a01d11b881ba1b0688513c657481b947a58c256a855e657015c8437fe54329753b0f14ca5dc2466031d3003d348ac380c969c5bb6fb579cc23582874b87202068b76b906831396ed9352a33632cb81dccef939a2960823a5a8714fcf13ef3f4521445ad7fa4d496d3dc4efb1c7837a2f9ce1089147a7b683113975e80d235164f2c02992f69340182eee9aea434f4c5b3f53f804bc98b2c1e60c6d0c98471c064e711a9cfcb5111fe990de1f10265f67d28cd21a74a4a6384d49e53e43b191a7e781f1d301129f523d964b37957d8e146ac0e673fcd126e69718fd540016b8314dee79fbe432bc35daa3f3078388aad066ec691bd0709840ed1d930e67738a2b355b4cfda2a494a9cfd26c6463e17aafcb5815b5b48ac8445e24d5f1cfda0b9ef3777c0f24a2f58cab0e4e63fade0cb9d2cb593caa285d84c4125bd80a1c6aa230d2c06e34a2c78fd74dac4733a1287122223f3ce7351cdb88d925b0edf02711ad3fa38f264d2f039299df95d04dcc0b17dcd11f1149f079538689e70eee6257ba8ba85532a9afb879e765bf9c64522a7f5aec4cbd9d8bfb1689f41dea405ad318c868aa5391754a78f8d35b47db53e8ecf87fec02ea293550fef24dc6e0cfc11e93b502d626c3afb2e1600409277155fd28a69bfbf18f2a09f67cdf609f61f8a3c890673951edb4f23d78920cdb9e08b157b1c168f45ad2f8cd73931a232c2b62d5c4cc108516dce83a4bb3260006e8848136064b63b69c5e8fcb9e3afbd61d9fc4623bd2487b5ab41c337246d643af851320faeae845109fdc4600f216fe429290eddaf6aeb6a8648754188c8b3ecd379e96ded7132c80288aec874cd785721725ca353b4903ba297d656f76292b5fa5f4f9be561c4de639a6aa0054f89af41cb7b338048ac33e7d8ba371515f93c4badaaa7d9222ab3d6dd2906da792a2769d17164a3ee090c88c545a3694bceecf4ab1e484acc4d232c63fcee98c29cb492f40352662cc0147d07b2580a19392e91a0dbe45ca52a0252f0d1fe4c976749a875e91a9824a4ad32df1acb490a2958b2b571c5061bb57b32665108f383c4a7d463fe69469322de535b6436ec0d31348b52283e2ac868bebdecc72e517c662ea1420e2ea0be47f8df233a9dac41e771df965e986cd3557f8ccfc73defadacb0c835c53fdd2f0fd4b802e585a67f29d292d08f49912853080132ccac600496561df98a1fdb943f1a53bbf403c907e392a3125bcba002b1581853775d46ad8a84d89b9d0c527f885ff7a1bed4a09bbae225512e8eaf4bac07d6eaf3db807dfa8edbe84036738d189bbb8e0b83da99150ec914475556ce094223ddfa764366ea61d81ccf668c9a81564ad7c843654ef76b2ed5bd8407d61621d86023f2d32b1d5b38784d4179f1db676e9f6f96f97882a70cd33e84d51da044ce43897a29e8010191dd76e3020d94cd3bd912696a4b2cbf873a099050f5050e1ed2443331784cd4da9d0dd116b5681b20de4ce509416829d191ad8f178d8b6a168a1a68f7a0a9d509b59d6cd9d732b57451ba7d59caa22d1c723552f4246b63fd06a5267695481dfad90f4a1646f68917cb45692155f4558c59cb9e6f1612902f88593d046c10915ce832aa5a74a0cf22c141fd5a75c91e608260d02db438b5ae0c2d453b39ad74716da369e58239773c59fabd7cd27ba89d90a52ffa0c3b4624ae55a9d99aa145307dc6f5675e79e3558f1f8cb09086e9e61f976c3f7f9de8331061585d02b49e0961dc181c4d8e048c0529375f4f8395255be020b88ef7e248a757fbddd76ee806ed79c8533fb2f1f8b00f0b42b8e62e22726a128239fbe2fe73ffad1d0478714e044a519fdaf4e4706b801dc16332d2184bc824e9041b6a6734ce7585cf52fdeaaa9498aa3fa449102819f0005b45b9f6667f4fdc400bdeb3c8d4f96a8144484ac9b8192bc7c2446cc3f370c42559c58fd2304f901cbc2cccd89bd5c4db98ccf407e05db64ab4c2176dc67ff2738b667f9706aaf55578e3980512f3c94e1c83fdfc096ca7b00ada08c4b9a7f2981dd8c3f3f323baa278672bc14f3d8d8db265e2b4c21815a78f7d19a500fc55762e262930f4b3128e2a7327b23dfb944c190fd25da2a7a6c2f28809f1e7390bb4a77614e8d9dd4d11a9c4412a6b06f6829beb8d73898743c877264b60ec764d5fda11561eb330f0fa6fc9e29f3c61444838a18f3b7b598987bf87f83cf8a0c707d900fdb815b7b5302e2e0a0eeb5c011cfe26a6475f8608b5ece79af3ea01222d31b9b3853f20b4569878eb9b01778bb180136b8917c6130551a2ff655fc189b32c56875b63e8277465b8259b2dc8a724bfdcb9645eecdb04da3c7ff11aabfe6a5f52026c4cf1978ef96c9f31a56c230882b9a2feeca8b39a187e28e1294e2f79aae36e05dd3865255b32214d4ec03e3f435724c100194febe1452bdf276310313add860c512a98e9de30fcd174571a482cbf73c78e5c08b4f9c49db2bd84bae61967dc7b7e7e807d9ebcf9af37e5c1af22459ebc14c8b2108d54b7fc92f0e415b25d293d9c98c921088d0726366e4762d5c16b62a72d3e058764ec60809aa67c49937576038955367aac259476368557b563c9b418ccb7055523bb40ce828e8ce4ae77d8b8e9acaf4cca4f081361b3b084f4f935099791bfd4b1751eec0aa0d1a604816ccb54923ba5798186c0690090ad100ccab762315eb4d0ee2fa776a9d09933c891169770441c83ec869ed7745f9ddb91d665069cce12176d12dbcca8b1048224a5119d499cd0082e0b24f74a6d6cc4640ef820b6ab6836cd6d374099f74421d39336dd554ac6c59a6328d5c4ebfddf7e5a1aa4db59b44912b25d2b1637e8a185ac0fbbb455a2cc51c3d06059d4d3bc9b72b419c3527e85cfd0ea43c1963f023d279efb094fa4a962a75a8812a24bf50fd36234b848566b364e135b53b81e8ac88f11e3898cccc3ce692e2bad8a36dde9b7d61a6aee17a0ad9ee49284a283424f4d9130023ed4858813e0347fb41d54f96f7986dfbf09875b67ab3ed2a2c0b4e485391f37334b7280ca971cc8638e572d60e46b5fe4ba501c40d5b777741f316c6fd5c56704405ea6bc294616ff95d3ebfbed3fdcb256d56946b6c04e058d732bdcbbf14c4b2b5465581d70a26202dc5d50b49f321dbb18bdfa69a0c0de8227873ee9b67647f8a3a7bf381295f219414cf7021d7b633b7f95b04f43857ce6998beab7ed66e02ce435f378ca9afc2d9c97267c9289dc9ab53f92b4fe7b2b506ce9f49b073d8bde4c82496ea32c16c043674bd820f5acb061b56b0edb407cfc93423bd161eebcc7be83b4127e1fd4609651aef10343abe834f1f164a3c949275cbd854ab9e294e231946bf9d5bf170a3ee72466d9a6562d7656d0525d3209ec8d839fa8834a3af685010b97a062ff3ae0c1a80a111424f8828620829497fef4953551fe52ee21f884a3fd53dee6fa17644471f1c59f7f7e01f228baeba95416b67d24cc975394a85685ec21e576c7446fbe1a4a701dea87f7381a10a929fe6a751e80f5d7a679b56dcd61db6553bd133de15a585c1cfc32babc38e429df36b9cb1b3e93c10911a0ac7665edbb2de33cfa3b101312a0c8b11e14b129197ff0eb9f121a617c44a805c17b44943f5cbcf4c288a5aa32ee2a5080ff8b943be8d6e0a68ab835a78f68c279e43712e350c34c502ccadbb24419da5c3bf22bad29696e0f3854772d50f7968b9ca069a2728d3905fa00329552a684e4e9e5f82d55121c1604db0ee006f1e0de516ab1d70bc0ea68472480b58334b11f2ad7a5ccb5a4032ba260cb212eaef0be6ddf4c95e11c346772740989e9faadc8f8c11876f861e512b894d47a39921ab4c6460c6e8bebc09354fc804cf9b59bdad3cb94ce9085005eac5cf49533945096844f8a1113b7b4af69ee9e75f7d0099d6e75bbdd39c240ebbd0213f73a4df4cbee7052df8dc2cc845f49324955886d000e51c89c8bd9a78c043fd1e48941fa253a1d8fdf06e00d28860ba268e24d049d96a813972283575024338d4c151e95c2a4510653434596a7d1d305581dfb7be6c5115b9a93152c70f647244f735a9298faddff763b70bbfa4d5901bea34bef9f4219f634fa35a93533000336dd0d99116e4d3a23880084464052a2ec469d321ece80db6bab330ab185b32a876637306004978b49bb01081d3a58ec5c3b2f9b3b5db17a1a4d2e9c9236631b8624cd2862fa1c324217ef737e0e46cd79c08f67b5f39db24580b8716bfb096bc790fe1b02ac658c8a3c33cf064d2ccb50905963826c6850e3a4117db24ee9b2bcd77171dab1bb4aaf63ca9847a0e70cdfdf3baeebb801c617eb6e7dee919eeebb194b238fc8fb64705eaf05ca0e8fc4f56510939759682aa7d5277b968c89e172ec3aeb851a16f05bc67c4a6715cd10a8db04dc5deb3457c757a65c8a3c667c5e3ba3c81ceb5036cc17bae2a9324c055af9e7234664c3a306f5450f3162a074bc5048b6fd7663501951c48015fc300a7a97dd7ceb05a8045ad549414d086536d6ba4fb877585d07e99f7106a36e009c422fb77d27df07a1e93137268b1bc8a23be72272f76ffb3a32bac5248c7ff8fc7ad3d146e27950700e3c2c59aa1f5c4a0d083d68187521a83e36b473cd5005f19b35e6edc23ccf897a4c3fb93f859dfcd1f0f26cc45a40859488c8c4a11ed9aad3d6cac4c0c156f8332cd24c01b1bde76017e945da6bd1e13db405e8aa020319a69b4826017a36a4afa4a00d51b3705cd4f3022e88353c8a5d0dd1fff6dfe234ac3abf1e9156411e34def8a982a74b9911909931e5338cedc5342f31e5e251b9739911c2954798b5140edcdbc72c2db3d9802807395a921921326292c6bbef0c4572a97bb5d7cdd5049a2294788648820a1fc9bf143429fb3379fd88c2ca5be114100b2711ae057f598cf75df8ef1c38865325177b55648a1d15b7a5252d04c2edfb49079b9a3b4046b1e1f87ce526545a018a071aeee55747c87919e11237180b5ec6e02e41a2e5f77de1d43155514b9942ebbbcb2ed59a8105e89fafcd38858f8ae336a7afce90c14e8eaa874e40b64c03afca87c1cdedb4261c9ee486e88f09527e4c24feb0924caaa40831326cb457a85856eb55d282780f5b939baf9264cedbcc435326cbbc3b661ee33848592d6acd4d983c34e06a7b5bbdb4af61f1caf746cca12648d9da68786846bbd6e645615496d98242df15a44904dbc2e4721600338967605d57fa23233cd0d4af629f0ec9e6ab90fd4a7412817a33467402b8be0161a62288bb95c135cd23402a11918fd250f3d6d0904f1569af6a54cbe389600542e2fe0b3707eba68556a9c522e8fdfbb31b6c46212d765977a0286045fafb3918d38c38267b0e3a972d811264401cdf3586844982dd59af7e0058031992c77450b0250bd7e5764320797d48a0f3f36030e45c1a21e8be1cf44814d080a7b15e267236f4740a927d028e4ed0c97bfecee88272bd827341c703b1d4c857cca9fbd3d10a96b3e6f9fb1421e1eeec91d1cb30cca8506c120dc7a6c616e370138a02f2ded6940db5c1e92941c416c2f2af7d50ae5381fa970c8a0a44edc0fabaafba29f38c902a34f9f523050d944688ac0dc001df3ae96a435fa621cd81a601965f2985b798ad3243c70765eb68f7f67e1584400b5d9e2729315e714ac75b0a0b32c194a75a3e9c0f0ee1acbdaedd40214324409db721cbff86ca6887b90b800e7860b9ada5e3cc499096a954134f4e765f6a58b33abc4dfa1e0221b46fdcd08adfe3953393f16a8a2a117cc52bf1d0f428209ba78b10481c55803e95cd3ec79099771ed3507e7b5f6551fad4b49f0f7a32c71a052187ee35c347df512ebc40bb7ae94a2389137dc510b694233b731af2a00bd1507e07c441d9c2f219b02e923ed5e5b7a1bd0b544e226474274ec8f35a85130468320076bc9ce0c26dd033b154356d9bb33d46c556988a5ec27b97de18f4915751cd18aba8dee4a73eb172742819871c40f9495d1121f4becdffbdb6617d1abc3152254489d6236309efce375519506ab2fb31c2448b9b32d91efeaf93b80251915292cfbd573dd5ad75726989e843cf9e3934eab3bbd7adc7087be75d787647cd70a5b69ca3337b327dfc7ad5569e23663ca5ee844b7480054b31fe72b96387aca843c0b59334d599441dd664685b56bb9f4db46997cd731d2da3b0089ff13c11b09f98e135666da5306a248611337788444c59ac0aa5c614035ff50f8272cf339acba389309006f8c477867590bf080bddf6bfa523027ab143c68498b11728afac88f684ccd8e04806c91d9312fe8411b6a4937d8102715a0bc838a49f1d0e0b9e27c047a1cbda06fefe380392fa1fbfedc21a0651d93b20c81a1111a7ed0c44cbcb8247cb703e575646a5241a663350e5ee0191bb9167a60cb71321cd7211ea634b735db159bb5b420b343d4073a333091046c703e45a5e43fb48b98fbfba7761d74205c68f733cc25bd16db1a4d633a9cc89d0cbcf3058f4b58e231da5fe8de53672689e03de0ea79afc6538a62d36d729c33c58ae66712493a44c9799d4016ca6e249e2dded55ee119f8d43ad1be5920f725668c8f96465db3a1c9ae67468b8fa006363d6d2fee85ed9eef9a113896a08d35bcf3783d121589757eee278b94e71e4e94e41bac9c0e7bb844740e3abcb211ad2060947948086da401d702af6dbdbbb18bee1375ac4b2f088909309677193aa468fc3125f3d6170a1afd7fb1e551afbbfde8f61d0b71d00ac1fe932c08d62382c1f97af39417f7cea6981b125f2f3b5f7369060f67adf4dfabd5ef3da7d1eaffc64e3178c0df4958c132b673b7e24dcff797937f72567034de94f3318ba0f66c241df9003c2f09f9f71b71f7974fcfb6e2459dafe8f2135090fc1cc1468b449dfc2e5b67d926c0af2be9a478da0005d53f3fe8fa8356d2470d01185b0e45067293aa82fae2ce8445117af79631f84375d7b4f9f4e7855a9457d3181c3d0a6c13dab0a1a41c8aac32bf5c41864cb436c97e7c739d749b124941dd404c9af42f60f4da322fa05dc5aac283f9fa612567b80a664763787b9f1761fa06ba811147deac1207d0c6ef943c33d29e9a031bc144b10b32e30cef6b7d5c7ee4a1762825590e05f6b3afd1212f95458bbc1a545cd66ba2adc3b9a55a2aa3557770c610c6d051239da83d277001dbbf035b77c7ce6da840f04d43030a3f065eb5f74a0f70b78f2bdc7bc9785c5b1369c9115d790cbbd8cad3d8a23d1efc6db23b8faeeec31c15489bee096ec7381f8729e6886be1837658b80a135c4ee7ffa6d06c6fa304994bf8ba9c4e7edc8f50836ce1e1c3d386a1c6edfb9ee95e5b1bb52dafa58f7be9ce5b0e882195125a53c4e33e795eefb3352da1c20872bec804997f96659f111ad109435b95773eb88bea1c124c4516ee559e7c581d9b1143ec5ee10f32c519e3227882d82c4e74250d429c23b044616e0a70cdfb63b616562f6231c37bb53a4e4206c21ff4d9d1c431a65963fdd765f068daaa97d009778b37dbe92fb13bb0e3ebab4821769b56b7347a32d1f0631672ecdadb753719d6a17949fade60ec0f1d942bf35eb5fdef580bbda9218bdde66519d8fadae2c4f36ff389b5e8bc79e67846aa4faaad24854e95a55e654cc4c4da3720feec8dca98950ba6598e9ccacaa09a404d52945f55248e082d366abd210594afaf5101cbda6b4ea4abf6e3efbece722946f79c2de62772118514a3e5dbff9af6a22b5ddd7b152eec6709d74341278a99637a94e297d4cfb40c8e954064fc3810ab0ea6e5a2b8d77f6fafbadcbf05385f82396fd07a0441b857f752c696a469414dc1f63fc4589df6a018d5cb6a54bdb3c59219ffb3570172b02fdd65bddba677814fb1dd29ae243a7f060bcb25b7725286bb3745eb7dd95be95bd7c47c1aac839153f2e480b0b1ff021e8f4a4cf3b34e5978093a48691fc83150f2e875c0cecbb37f6381de797e0ef00dc8b883d25f9dc24a2a034e05e45682bdd7fb3c865a501f63e52af077a3ba2501270af23b49502945e25c95c44e2a72753a338155f4aa2825b35ff71efd112e499212e3b7a81d00693c768c07a13e736bff9b4e35dc5accc57a344bdbb776326d4fc8e870aba582bb7f1ce91ec7993d40247a9e4491a9ef95a5853dd4551a860f1c5b5611e2d6adbc2aa5c6d152e5a546a87f6a3e5a5e0221b658e30cfdcd11b9d873690b833c345182c771b0a14f357ec53a0d611649b93af066f6ee3a460943cdb21f3724219771f1977b5f3846750f6424112a885cb10b10f48ae93756d470ee3ed54ed81ce8cae6c3877db6641b0643689973367125ef406f696eb58c67dac6f1c1767d4eaa82d0f4d35236c998b3c0bbec8301ef4871eac90dd66739b2c73936dd6eec169479eff6d8632302955ef3e01e20193c49115aa31773c625a1eab0d69c01fdbddcf56b6f6a5a799d34d86438af30624bee30d6aa1498514d436a73927182302d2d4fa426634492cdff758548690817c85aedda916b44073f881d0e1ce6aab2e7aeda4cbf24cc324c61569186dad962ec6de7bd095ff7b0c8d52f1b64c9686f70c73a2e3c6e0e29c283811b93e76f4579878bf19a1a65cac5cbf1dfbd53ce1621dcac6b4bf1b5143a90661d14ea2287de3c97d1066a4d405e76c20e8d9ce6a622ac9ee42d232c60d2ea1f672a24414458366e6e12abcdd3918c01d7e70aaf05ae487994a5b84fb97becabc2e6a564d1c0638516c384cb27f148d497f208142b358366adeaaaf229e360b28779999395849d5fafcd6d89d96b05267ada1ed91f9bfac8985d396d38f464407d46017dcb4867d7c5d1ec491d235a0d1c65233840b9f8bdbd237097aae9ada2618c883db74dffb7b2f6d0adb19c76492332b6e8c80d8f3aa6c582595464cc0ec84dbab790bfb1de86cb54bbe24e0ad25b19ea57cac39504a65daa8791c17b2d3479dd373ea8e9f0b7ae0388da35b29953c9d46cf08c263d24e66a91195dc748a67ab3ddc1d1b565acd2a55109b199c553d040501ec9c3c101470bcf49e45f9b40088dd22a0a40c2895f8e28d58871779e145562689e9ba8893931faad1ef3b13fbe728d11f0dbdab3d898ca387ad000b817166914a4dc89800c81c1b526ffc2901db2bfc615a645ea6d5d49ef7728900978c9ea1a02ff31545255ee28100e4ec7053a2631e946ea050df4559fdda37ba1b8ede8ceb446ee7e24ef41a7d0c7caf81b65b67262f7842ac705fe36f803b11032c3f4eabd191de8bbddecc64624c49bb0c098b73095799d5c69b0394f3f884c4be4bad81d892de9e56b8562be2ef4d20ef440d028a9b13a11cd8fa6fb9661524895dd322739c762bc7c13ab66d7912566709ab1f522c406dc6e3b54549b86a7b29fea9bc4604bde5d1b4330817d0d7647be40bfd5030cc6601df002854190fd186ec7ceb90976503dc76238653577055a4ad1034198b32d30302fc9bb6560af0705596ca06b4b6107c5003c225bccd708edb6cfb9e84defdef90357990be679485cb9f112cbbad0c9513d166aa8184818749807b2665e0a08234a81b8d6ae0558c251e684d3c0897d532f09a40b1eedf699639a1558f6c75e3761350465114369edecdb9e04f2304527a68183230327280e61d2ca7b0619efa07e98b133fa0b860a735a04619e2002e9e9a71732bc51bde299beb151d4d5b692711a827bbddd1e43592bfe844ef243065056e7f40ab7760504c6adb9d899c2a601eb2e44dbd635c1b051a8ffbfb1dd8e9029c9d15a4fea5b74c905cd615ad9f8643a9af046d59dd90121092022c0aabacf2a7dbcc82250f451e008646d51f0c655a6c86796016fd266ff7b2ce86f13fe6154a4665c7333fb049d6f7f9198ebfc7936e74340d74c3e745e6149eb31988b046f38e522b2422a6bd154ae0fe6e8beb7aa4c816bd11436a59956eb134426ec501ea9e631aca105dc86c151c0aefac881e0009149a496091be97713360f935337768040b217d9c407828882dd48091779884a834ca2999c031ff13681a1884d3a90819ede08e4b07c8fc5747144c598106e02d7064fe5207613864ab49276eb27a370b197348bd556d9881174626102866a2f862d6d6c10004f2ca0887d7f17f17343074c401d78ac8fd3f47ab55cb19f757a18b1e33b324dc8894f0307fae4575108d37cd7a08aa9c157df624a116a225a1aebb0fa04b38009a9cecdb28d20df2629a4346f2b48fca22bb65573bd28652d02e4709b663d7923586ff586f131a1c22f29f5303db8e5828011dab99bfeab744e816123123b66bc96e9e64e758f805bb202dfda12395c902566c5f506626f0e2cb038a9c7676817dc72e1bf196942893112c3468e306cfe1c0ed432497c921c6b7db911b823b7ccf7becaf0d1dfa618accec50ac6fcbf48b2e01bd3d781a7a8d21bdbe54c612ed8c8e433ca4b7f8a5328d1dd9098ccc63801d171a0f131db61dc46878a0923693c19f599dbb418fc85c7c73b7e04e3ccf5786dce0e06e084541d9e1db27adddf10bade7a791511e0481bcbf048da90aa09bc7bd019eeb51748644e9e6a923a363e1bf5c6b537775d5e722058fe6402a725e61fcc89a6ff6e379864cafcac0c03a844438d9aab5a97792ef193d7d5023d706b9a5b96c865dd4873b350e3322886d3a512bab9f27c9fa91b3b870e26647d52626ba26b332c17a22be9d4add760e3375d028fd10e7a6df2c416119c56830b8e0fc91c6235d39a162a047cb692e56eddf63d7138b0e26aa3fc693d7562be780c432dd54fdd8e18a57146bda6c30623b846f82737d685b2f42141c03edea0f4924e55a45bbbb07031c9778047e62463849dc3a2d25f5666a2b502a1d3593ff07f04bed875ce1105562492876d59193e79ca4135c387d005cc5e758faf234c8128f740c35ddb4903e5cbd69150b9e5e145019b7448c24b12aa0b60c1c0461fd0db1ba51eb4a1b81aced55864b569fe754dc6418de827663bffe0b38aab8cb0b75ffba296d84bb6ee7a90d16ff3ec936fe547877db655672288790f5b9290ed4f9285947453ee85522da2e033a6f5ccd52c828803d458c84647e09ca9e66c564d46b10c85666900bc5149bc5c6468341b3f737987aa0b7dddd2804e9f5d1f0318d910a14dfc9202141cfd79a95aed2fbe82631584c8a44af2584d8ffb2a56c90fc9f1d97abd66fb02bbe384d339fb7baa271dd04cd23f7ffb3faaa7bc34843f0f4353f21d3748eb401ce0e795831e0db60024f47884def0f5cc6054fd99906ef4c46fb872ddf55d3043f4e6c23b3ad847f8232f7555efc0fe5232d7dc7c5b3dac37be54f9781e030b2d2cc1f41ca1674b116127a7ddc50febe8eb00f1d14298791c65381eba2fb49474523e2ec5307a31bc65171ce3f098087a030a79a70cb844e88d1213cfa58e54904d86d2e0222075148152a7d1a2efa27041789aa4f8eabfcb5a43f2f905a6b01200967a61d15f0ab11cc558d388fd40ed4206662ee52f41930ecf87a0680223f8ee0b1f197e21e1666d19f6f4d5b871c07a92ffb8b8e90e30c16213d6a8d2a4367b5d207fbcebec1842e5dd7ce59a9a3f330ace7e29428cb660a06b3436b169ec66b92bff32f7368608a25a3ed7f16ec4ae410111a226c0194e7aa3a98e7fcd3ac238f6f34f5fa5711c37b6081281de0ab688ee667448fdad44ee54da9cf6a0f6f94cd0ed114f019b5bf2f9e6ed21622f3699a4437136159275c437736875adc7654931be3bb41d2e753407be0984e923fca1b4b086a5912c24b104e922c7ab58fbc374a12d75be1bd2a48285b00365bc3692314369eb1d71b85c42f09d747ee0054c0d9eece12f11596e86443013058c81843033b96f2031e8c2c39611d1f6fb4d384109fed2869b4f5313da0b9800b41ec60907fc9894170486fcdeb5835960ee31fe63a0d21e3f8b1539e938f775b1fed43ca09b0d6f9056384ce40d992008ab0bc44696cdcb99d24ab7bc031b40ef7ad59c7bc93c47bbdfcee8f5643c0504dfa659d794fe8f8643a0bc2f3ac9bb99091af3b0ae2784e23489f71d22f42a09e46b4de865befa2a346de0bc882642231c1f76cbf6094c23002be31429d12222de7450de501cd8b2af9202750593bd38b6c35e2cd25fe67819bd523ca87e5c24b7e517b746a23016f645ec988393a89f1122b62fe4862bceb1dea888c825bd5960d4029831af2b9aa1075c647291690fba5f82dfaf332ed2540c9bf3471b8744ff79882d22b5ae7d318d70192b5a12c4460d46cf1af641a69975b7ff07d41ef2a65ff1e51f36512af357c16c414055e5b3eef7b5268ad64650e4fd8c19f4f2fa3a842d1f2cdf0a49005f5d0350141f9490a5e2061dd03eda013346af81468b1855f1b9718020d0d158973a41b38b270e3ced6b50c4ff42bb78b4a3361b121ccfef2472d4c32592a2a3f4155dc202a8e784b661a1a28d224714853636900f10c37a31deb824732a3d56aa2daf861ed337d7cc89e54b648a78666279d903d475f7d0520561a4a2e1c25ca1a11ee59543d90ee4b80aefbd9d776187edf7bc35b3df1efd2f0c8410d5bca2536c75bbf08f976efdbebdef84cbcdc40916b9d38f1a13f32ce1f679fddd7c24f5f926c1a2c0a5ff8f7a657eb0bd21f1a10a0adf82e62abd75d057b0960a08773cdd04168a40ea6b9c8cb1bce3f101b1fd1fffa4dfcb610905f8279b9d2ab87f2db75757ec60c93937bba28a78d31753e536f04f9e84d6c7411adf693c26ded1a4451d08afb978bbbb2bc12591f520a5d2bbf1aefba606285c479ebe5acecba1f008bc9b4afb3503739bf1e6bec461d55dfda827fb3195dab61702d48c505b88925e2cea0fd0bc86eb7bafd2f480562bfed37fbc92b2e2e3904b07100f8da40494087a968425c85bc743e011b137129fedd7752a66f1dcbbd975e6fb14a047ebad528168f98d9491fa140717bc20dbeeda0c0aa4ee2d0498b2e017e21fcc06c5a8dd63dd56c7d93ac939832189bb20e7816c0e0b3d93e7dd3cd51c79cc27397565fc31cdb4ee34ef9365c2812c341c70e4d312e0076d0154dcee2682a1ae2aa9db1881acd181954a2e1743661cb7a3f524a855c6f05e4629578c357612aad2b23bf8b8e9151b14a008d4cdf7d5574d330706ef158b04f941249c139d7b2aea6e5bfa16d649055a7706e8b883c0d64a3331d08a65e56dac6fd367ea257f84ae464b3fcef0555aacfddd6f6fe9dc5a2c28f2b0382069deaf7cae4c14dde2a4af2540967ab8fed78d2d377d70084c2266d135b61410e1463f212360c290d1c7c4792f721b046033d6ed7acf193405b973818af0ec7e026c80d0a28b9fdc09ea73bfb0d0fecdc347d193d107513115d520c0739fd34ae7525dd795d0a4d6a8bd189042303c3944dc2c3bb913d40a918722ad5f08777bfa45e90125afe3160a9cbc067918fff1847147324879610249f643f88086295a6d7ef1b1ba0c6999f4fe41f2ff9b88d54445b94f58b066d56d405b452b3b38c8f51fea981f4a21da56426c1cbd71cba4dcf362e432481e4bcd317b5bd0a67db67b0a559dcc252b459ea1847dced7c8c8b153e3abe034f70e2b29f708783ac9c8dc073240f49a7609662801c9f89c48d55772ba037be420b47a473329e21e033021ae4da13729695a7bb563f6c277ced9bc63e305ea3bc2b1f9c0e7227099230376bbad2091e51edec9e4dbf0d2854f8e75aaadf13a5adb51a95bc19cf53f1d13716084390d1e765f3d4b296079700bfd7647086e9e01d4e35223a303b9a10fc061962bb29667f31261e7d6d00ab8b044ca292b91ddedfbe6877d260096660e23c6b8c41e883763b636c71d787c019b3eee8665c401178af18a6403dcba1c8b6fdbeec3a0fee6b2878bc03f30a82ea62d2cd60c46524e445205c68cce4a49f145e2aea07be1e7e38e41ccf7e091cddc2ab0f708b9d210c8bfc2af7b4d9b7ab67205b53667c8e7f9274e2eaa3c5e4cff1b6d637b802f189ab81b1528f912e0f398a6e9b6dcfbf2cf968822d95a69b1bb98f6bec02f8b2d4dd4e5ea78dd4648d4e9835c2c5d6ea6e57a633033fef44eb478a056a485c7523348583bfc549673c39768c9e0c51649f6792be29a213655f54ee2df44610776c42223ebf6eccc4fa6eb7f122fab17d82b85941859e556ec947e5af5ed293382485a5dd2e8fe0e34edb3e6a0804e92f23a4bf9892102abd65310a2d65b1fb7147d5a29155deae468fb8e470296c6a9c55f04b2dc6d42ebf8d65e6ceafbb42cdb526f7b1af844b7185234b687b6fdb64a530c5d63b60b062db1a9b2445b6d424f563f784e0ec58c70ccfc6c6ce04c70d2d7e48767ce7ac6989679918446171e50791dcaa69a6125c580e5dcc4ca1bce6eda84dc3539c95f658c37075b16f6843b3f5d306cbeacd5ee5c14906f58afd327cde5c43d5cbf7530ac0d510b206ff85da670d5ccd1b4c40365287bd48fd8ea07d33241f7da4b68fb0b4a4c55f481f24118143c7a52c5ffb219cfdab489303321cd0dda1232eea3ad777538a4a7ceefe8b01e7e10681d51bbb283ced841ed0d0df633d40fb174de1397c9b193c0e638828e82e2c9a20f59329ca4287d61feddd39fc3e476e4d5800cf9fe1f2ec61ee4313409af24d344c38c57c74b3ca3c0d0dab0ae4e8b91c5266605797626ebad7ab3238d4a7411d554c2c233d6c96f0cd15fff9c548cb6d38a7633359294a4c2d203297e0fe8dbb2392385632e915ae5d230d9eaa57ae5ab014b4519fa4aaa953795f9385ff9459b05b7f88f98cce6821e3532f27edf388d9d98fceb5b92c3276c4cd6567375a29dabb52a75da242b7a314809d267959b263df1e6f373b9c77d8861c95569c9e9797aa02b7883e0027637e1051995b20aa1e33db0bfa6a0c679088da269cde95258d64874164f02fe2a716bc6805bb2b5ae2e85f77508f28d09e5a493fc7c4b4ff811d0b205399221532c678a4fa0b95df74ac3c736a31654306a9dcb4e9465a15adc26c57442449a8c83319efdecf6d74592421c0860b68aaf60728912ece1ab8daa507e32caa501484fed83c9a5689c2de2ec0af973caf23d907b403a64b6b1f3c21c2e12fb07afb69b89aa6b81718dd20eb03e086e3cd27a9b64ae9b033b693fc4e1592387b1aaf070269e2f716cc694246582a7a7056c2ff46985a397770620a0b33c81ca8c908f889cefde81ab7830d7162800443649c13961076ba66bf3ceb306c45cd5848f8b6bcb6495f7013fd3e84baad8350d369f53c105739851238a9f0c3bf7e03cde451595445093100e63c376aff60a216a5d51c43ec80bf1fce647237a7f22bf19c83199388be072c3982af0259066fe01afaff41a285f6d990bf365f5546d455ef7ee8aa0c71fc95033068d0fb35e36278a00701525151b92729f20716ebca2a2a91aa73b8b3d7cf1095874df4b74ecbbc19523818c603877fec492228aaabcb49cb0c5f8256267b76647002d288a0d23591f620067e987c241bcd08ce276a073e21b3acf61331edbec6bd129c2e7ea3df45be5808109dde59d1baa6456912390779193ef5177f0ff4e977552ad603758a1373dd6b5094a626b55de0f336a058e390abd183a49cca8a965afc770cd8279be614b1ab9d1e3cf458490030411c2e1f2f04edaf1ff1a33d3e08961988b2ce49c2b0636a076cec93e6b2c90520cdedac14c4a87443ac5cdb189a42223ee196d21483486df2a64820c35ebd7b680b1b7f6a3d5dbb5756a7ae7d79a82ff82ff440b4ca9afcc1ed44dab63bffc93a3ec0d87697d2290374b472749fc19a42ea1db1dabfc41cd085fe6d52a1a557e8ba08e9d01c7db50515c2a32e3c5891a7ddae9223edb98edaedaa01915330d2b84e2e27a2b90ab1098c149a81b60b522e094923e158d9fee0f9b099a281d6ab3e9445ef4f4fd062624736cc9e620d256743c62c0d387c348c2fb60453d74f1a8a6164cc68b81077cb0d29d4d2846ae974afff20a6eb3df9e464f66c47b4bea18301c2eac14adcd9bc56eb6a12c7b6bf45c0acffab7a7b1fe70d69f6ae5093143d7dd900ca021ae1c97700ffd1b16617b151e8fcb7ed40af480580c9cb4a4c92c69b383cb88edf652feebd84bcf52b30df8dc58f485d0e74a8b2fc908bb69f2271a9412c9077331f537765b857be7d6ff48e0601b03755eaf7e5d2434077215131d55aa3a361ced31dd9f7d055e6cd589a5a48a2d43b0121f94b6a8bcb8353526b8c16ad83f7501a2df9bb237f25fd05bd8449b295775fbb8b6abe34f0ea66038f385c2451ea912db50134c77dd904a41ab0c54c1173434742c690ed384ad073ddc05144870c08ce31fdfb5b86ac5fee2f9e49a276613da33d682a862fa272236ec96c36015446e356d7adf5fdc197d757b7d7258eac95d90481973785b6471ac802f726e17dc824a5860dfd60f98f253aa6bc8376c71bbf88e14fcff5f1b0f473a03229308410fec36fd004946a8b6808219e95c75fc36e9dea6cc242d4d2f076e3c17bb0e7602a8012afe9450778acec6ecbe39d865b8e73ae85f9f3c448e0d7d5ca2bba4fadaed67cba29b985e22a2442daad690380f751dadc931ac9285a6054fd05e01a8ed801b0db90749644673383fb808a8adbdda51000bb08c522fc5768e8566b4280b0408c36d9a6d12ef4bc0a31095babf53c64793a3b794eac375708c3769ca46786bcc2d90d8b9e2f8dfe18453cd24f1a495fab30be5130fa2e4a5b1d22256f43176c4a58028ff12eaeec070eb35abc8cbb5beea7a0d3e390864b13ccf18d74debecb0f12e4db6b1b2608da8bcf3c4a6c85eef8db244b691d5732cf20f0d8aab1f5b8aedbf4777b4f4801a491f40ac7f5735ad60c42689138cb2d648ca60fd67548933c869d5f640aa29fc533c928911e99d375fd8a7ebe28309376500c48970cd28c020c7f3a338fe889e1766b276c6d175e090263edb794ac371a1a22b9adda656a7d3e3712cf20dd1413999b0ac37f0ffd3227c40d136a78c74592ad3d91e89becd842ab08a3d0b16d0ea230c5994ac0bc829477fc6e8891778006c50533b83a68542d30c36aa914408f9190ee72b73379b1ee6cdb9d8db26cb50233137ab3cbaacd0736f5ac3995804fe4949bc0dad0e1108f96f39c07e1b63081908ebbf9576235bfddb489460bfb94217d09d176947e8d50dbf4dca0fff975254a3b275b297b6930b2d04d9115e6865208cf1097a0cd1c41df0f8ab22434398a976fe8872c37d4171202fdd969cd66959ff487001c41dc62dbabef24b40a14e733f824bd4bc401cf0961aee662ce2c08e7e71dde9da5e7fcb0464ecd7c7b652403d712bb9200dc6c4b9dc80308b91101febeeb9d0ee049af0670d0205307a09d386e1016ff3e0247e563addfe562bf8f1b589a605cc713459c887111c1a6bded18b0a33eb3db58dec051796312261028fd66af69e9dfb822439c9a0274162d61a1a4c72cf0b2208404114838055e53ff0fdb86856d3c6e4a28365056c9d28b19ae8fcdbad74e631bfe053aad406170f9692583f09452b3f298dc7cf2158b4429cedcf38619e620dd60723a056213103904f39505fe4b956ac0e7e4b4ce3735d2db55e2400d27d5201fd2bc24cf45d2bd8878a0838383450e6d2826565c180a2cfc76cce131ca61a05bbb11fbdcb8bbd67e40d668ad90fd0a11ac827a5d07cfa0555d2b59b8f2f2b4f90e833ff119da56c87108581c2d9b5a7a03c70c39e1005f18f72845be647e7cb63c6bdd8d58bced3ed7df99f355492a32ebe824ffe90b33e8bf8eea189c64038f7870ef9bd1aa9fee79a43dfb806d11e55e24610dd3e0a635a2d039fc55e449d1b62f22c1662f619891f0ab0ea2ff76653c17985fd1b25881be516a66449f1832ee84562b63bf104f8d327b1e56bab6d6e14ee347a64b5bdcb23cf1695d7c85ea181e875c570ab971cdf2c80a15fb49758caf03da703063f19abdb6ce6e4356fd1c131efc9b2cf1d3dedf968608391ced7b96ee6d071c6a8e38ae76cafc922c3dd99b7eb5c25da32c8892435d119e8533fc3bf65ebd02015b7013b82996ec98d18793a6c43625f0ff004762ab4df9c04e83b4768ba6df27a8b407f5149907819b5344f0e4a76c433ef88880293866ff353ff4f4b5f35789694ea52008808e815026fa225f0cd3636f65846fed129935f410b495045dedc4e2a706cdc292203e0e4188a27690bea5f86f22b7b5a857cee935cafb9dd50ab51b32c6ab96a104271a12afacbd795976718602098b257abaed5d77d1eef63650f2db3e2f815b83a359f31a74486571335467c4640d5257d731515bb0ded783e589fb8559e3d7f17f455115860d679930fd5984411c39c2df51e320acfb8c2b8249f0f80501558bc9d97e4edc268de6f98b60905f169ead6517061521999f68d1e38c251ebca319e222f8e48f084eacc6ce695f847925a83d2db6b75ac221d6e092e7338a703e66f5ec3a3a4930e1ec40a7805b167b1256af10622fcf44b11dd191f4f145ec0ac5fec7c99845beed924138ae664b56fe112ca3ff0a2212a043651ad8b579f32710de1f11856dfc12c6be0f817fc81a0e9e22ebc75806103faf3bc26ab1854291ba3ac0649a8aadb04452e18456af98617a3fd3538f315e060fd875bef2fd0f58f8c2bc0d134e14f71637cf880c955edad8e8b611258b9d0895cf2304e46380b28b1c598043e82dd57e44ad06bc617f78ad02b205c9a0d292e0ccb903a834989365267713e54690647ea678a0e30f8545f43420a700b965204ef96330855644eee547351a9153ddae1175c5c3a49615261002a89a3c7d28061d6870254bbfcf8c4d3f232c3b458bbdf452b4ee34f22b3848515cbb8621ae96977019660a2a566dd107b2e69d8f88b8b63a3a3db4c384833cb5dec81772ed77ad64ba5d2f574c2cd0f344976ed58deba32a0351fd15b151547da3ee939f239e01c7243e77da80e84b77ec27a9ade9e837aece030d51662288da86781348da2cf9e4d91fb1cf94d77fa9d82927fd506624718b8cb4168d64f1be9d785abca0fae1fe967e8bece4a59e416fe8fcb06e2a6bf560d9025878d4ec80b8a1a000f3460ca67d4d0f389276b674c70b4222c1c22c5bfbde3e51faf73e1d4e1457d17d911bd02e2e9d96571a739353a1a39d22247711eb86f688155a2726035b1db07adfebdec94af9755e8a48273d18c61d81e6f03afe27cf96adcada8b8e2422475af05eacefd52e17a3dda8c655a41d9b8300f1e6f94d59a743ec7ba5245af0517981f8d9e6f8baf8b86a0c82fbff35b84fc993861b390bdae49f3c4c73768f4106be0437f20d00e5b95a3cf611821aafbafa8c73e48c18a7012c4d20f6cbe87e71f5c6fab6e44556e79f75b643915068073f7a1d94604f7226ad60633ed37bd4ab16e4415a7b80d7903b448f9031760807a180d55a7f1854579b5272b11957aaf1612d02750c1b0ed4a59f6a0260da01bdc294e39416814845ccda753801cba9e02968325471d550cc2b2ef8c1fa0fc8700126355ab49b98e12c2b160ad383e59a00692599dc3a35e8b9b4467ad4f78591a0b8fae470077f55f1cc14fa24a682c61762b12d9f60de3c89110c2408f3a83c4a2a9c87d0f3f111a71d5a3c35fcd49da62b08414d6d34a28878cb2b1a625dae9d88dbb12b6385b1ce48e25584b561963cc230d98d1c2b6e31505279a1f0bf4dd9f44a5b50108abce5b4903110cb5afcd61c89c91f2ac4be423f7de443819a9b38cef2b501ad2a42123a943856ca3e66f327b4030242bd9639c4901443a99f54c2c08d768bd4bf755ebeca478b2aeae56c936ac081d81c97b3081a4a48d49978870f31f7f774a63f0102348cd06621a8465bc756d11f7edafaee277d33e7f2c35ac543f025e1db35138430a298f796cb30bf208294ef18e18ed8286233e477bd1e21438a8088e5b88fc664bdfefad96158f5f8db305babc207f361aa787711edcd0040de5d2b60d38652981e2f1346fcb1af0412113ce3b1340489010c7f373f1b4218e146858c017ebd9305f3524de2fcaeccdaa814c7dc88b7202fcdf6aa417745bc1ed88fe3e2bbbffdfeae08fc3196641dbc86d76238e96d608cc0444359d7de34765505d899cc0d538bf10ebcdeb8d945abe5a1ce710b676394190b80a76b7f6aa56ba74f2a7c86a6157ce8890a5dfbe0a62ae28ae7347f0bd44d3b67461b7d85a6739215ee65c9f304f1d64d34baed53a40b135f1080c599e30fd504f462631e69f743e766f7a8514ded78feabb6ca781789b2eb83ebe056286d212175c9e08c0a5f1991b14825c501f3e7b8b59e242a11768ce43902711722b383c7e61e150d4eb1dc3d7b99dd14b1565b2f98f16e59e3f6d3506d1ae3c1e4f6b310da49462744bf307a6b1d361ab45835316aa96ba83fe8e2e5d5e2d0b836b396ea62de9b5f83e1f76cc1fb7adc9c30983ee0fed148a50489cbd1435bb0d69d2d8ee98754690fdec4ad02506ebc30f255bb96c281e1dad74ed2a0ac3a477f597d961b2c7bd0627a42fc11d00d04e5b59c950ca94d00b64bc0945fb3dc5e58241b4c3c13b846b61424c6c86c751c55749fbc48a2545b6375a0b09f5ad8927359de381f0c4b1294a50d8cc73ba487915775640afe2c3cc45a7f060cb1ae44b2931ac78a2e5539b3ba79184d775a5fae5df3d433e32c312df49171bb3c7ff1206a515562446b7a5a0b399d22247ef327a5487927fccb78aee4d40fa26f7c0757bccb233d8e2af61d588da5a51f5a00f32ca59af193844e11787f86d1fc968412c1af469bc8cccbfd775580dd646523d2fb63ba43e608908e372216bac21f61bf3a359da80ccc9fb3689d5fb058f793d2bbde05e6f1339677b48a606868818db2ed04fea2c00fc730f03586e116eba4642c404df12f6a09879ecd5d620c7af27ddd8e5b72a3790c48239ab4155e147d0c26085b1068686cf17b89e8f62156670e25f1d1b0234a2c8c2dd532606c3f2b8940066deadf66f56a922b8c9cf60da212194af4316cd4536a0de98198bfc9388cc1b7c5cbdeda337e1ba003451175a7b390a11d9e4040894ad34eadf3117b6b3861d7ce0de1be0a2404a40f7de0cad44410e0f892868a392ec0090cfa482ffe87de1dba5402550fa24fb045ed2efbc9461e05b52ae48b35f65185464cf6b462e063f4f2c6063dffeb4848b50b52a0a14105f89f0aad3dac2c35466ca7af93e8723ffdf0271dfc73506cdfdd8320a28137221b7fcd608d32ac486c2909c1ac125b05ae3f11281019adde1c1329cb3df59849f502c88f1bf3b9dbe218cad2299ee2b5cdb14715068dd52809b001e98740673798fcbb4569e6b557a9f6daf4cd90b4b55f6e151cc2fd4b9646e97136b108fde318263696076ee49074466211ef7c49c13ae075e9d83845ead3cc005304d81fb57cdfe489f2594235f94478622c8bf8383ff6074a8daa64024811500fc192f8c1a925a5db63022e2821d52dc8c53e41c5134433693b7f67e0429f6d0a93422a684846bfe3e797c3dab31cbd0e6dbe76f6788711d335c3bdc070c8ad0cb4ab20c22102d82989e9baed187e4e21df4b23ad043d91383869311668ebba68721586a097fa504823f94abf8bee2c60787b4e58ed29486b2290f005ea5b32ab0df41b648a4b8a214457f8d006b68db587d26a474d55acfe7bc8bb9a795e2c101aa468001dccf1271148b7818fd7728108d3e94ab8d42ce7ea4e38e1e8429e985c08a5b5e2112f514f35ba2f6efcbc52b672a1a6a1d8bb31a3353bbd89267469059d30207dde74a498105c20be18992bc0304053b1c45aecb1e82d652fd88a57e6d875f16ef84f3e627ec84d1179fa9cf46e212ecb9728c4938b398fa82b1517b33f1940bb31e13ee69adc6d9b1ac1c4de8c40caeb788364dc5bdef3805cb6e2ceef695627b21b443c45613a8bb2f2ed5a0f2efbfc2aa0d428179a308318c8c7e5daabbcc30e7849bfcc11c8db56ea1583f0de3d322cba806c9249c5542b2c9877ede25c23475ab5727d3543e7cb7a2037b9356ac95ce4e7ba518385a5bb1a752e9abc41d73b3f36286c2f0599d3e9f23895ad4c5c4b442811bb430c470e634d0751a5c5eb0b4eba30f482f35b67acb748c7a7df179c043f661a2a1531e30fa6a7ce50f9c2162097b0b3d168abbec56b36d2889ab4a8af033097c9aa15182f3f3baf6508bb669e14dc0fc26055f4699522b318cb6fed27025105446dd3c9e62d3d796934d0fca083ef3e54123992cd5be88cb6aa4acb41ef6c20e394e220d368258ebcac7cde12b2a3231441db814d82110e9a078cd9c3afa8e7cb06bbecff84ddaba5e21d0a20f66938dbe31edf9d6f0b28b8bb04167eca3b2ffe703a230e8ddbd4bcbe576903cb061a907e2d01feb3220be336bf9640965e64a2d71ab29ed35b0bbd0db739a0c3a686f44b2d3c4538836f9bd32c4921b8867036bf9e0df731b46458c0b24100ab9daba55026c39d8ea78eab8951f7248d77b119191f91efa5d7b698de7e209089d1b452f538762a8b6936a7da646460e43d49d78424a3848790bb9c2b9bf641b1dfcdd9ab695301333bec634e610165af8860cff21e80f301cc0053cb26351fb4160aca6e99fc9c1717d635396a8052fa97029219c6570642c519ca55d40883f1a49b1b94e42d44da967bd7983474dae43a0d9c106ab6957f7bd7e98f919cd87e29f46b4394ae40724246f783dde38bf5b286fdaeca31981fc047567e7f6e353833e548ba1ee51ecb2cc6f575737568f203bbd412c8642d36a14c10347b3843afe9079b67adf8bfbd888633c531ce524aa8c423e4c106a287a733c2dc49892493e29a394ca38c289136c34fc730d6400d66e56f5befb615a3cf83910b1a35f704e7aa114a843f0bcd23fad81276504b8f31298046e11e91332dca33890239c82d924439f258e00e3f4e621b6ea4a645fa1c451a0383913cf7b9f070861a92b4b935b6a513803dd7e65ccb44ae88611f7af66ec68ce1afc575f9241afb39943550afd4e8cb67ca4e6c5cecb86de427b290579a207cc7d8252b27062dffab384ba338d4cd6fc2573f02d4a0421a51ed218b19f2f0fe3d81eb819f81b4c6b735a31edbc59ebe5eba4b081cd151ea943052f72e036b76b07a70455ea383f291b6904f1f9eab6c793b645c73635108abf378a9571fa6a505de763ec58f9195c4264ba895c09c3be0bee4644b65b029d48f3c48c16859f04251fd2bc24d5d83fede56fb05d8ea311abfb620e56b13fba59fef5f22c98189d3a94cbed22b0bf73396d9ed71a986d07bb75e56f6eb4955ac218b1243c205ddc5b6085da66fec5fbc41953b27b7b151e7317c3e6f9fa9006f0f2f89cb53092486577244abfa99065e705a39e4ae5e2f9182626c9c67fb0c3c17870e6a3a9514a789e90dfdf977865d22ce65218a910214de41a7894766e9d41b80aed92573c0c12e1da0fd1592a78bcf60f9f4fb0c5fa1cdfbc792f78f9714ce6cdd692c76e05684158b827c2fa26f03a9dcace322b61a76180d8e91063a8807731bf46b5a4f05db19373b88d85e5ca06893277c57bf2c1d781aadafe2256b599f2103d19a9ebc7c75c42aba47e25e31883f138f7e5b214a3bd32ac84c41ea1c60dd43cf2aa7402729e7f6cd68bbd47e26426a839c8aac6faef6552267d0d7894bf5e95618a6d7bdffe5c5ede31515e1b4ed325f5f1550f8886138ca405ef357bdc79bc0115462404d615762d78913c8f9292bc007c9f9abde4ff78a6cb6f0d2640ad4407602afd3825f50af05fa65db34e8c8ebe1460f776ec01e512e4b64f62b81b3367c1572b7489416368859071baafbce97d325940304d6f58029294e354f9e03f4d03a42e4cd0e30b88c61d9399fa25f076f9bf896f4733a986d1d9a63d17e26705f1a681a36bf5b9452383fa018bc48d01a3f9d8344204c989ad191c1b6ab65993d57ffca0e9e931f34883821825e8378a74e824e48ac94607602f5f2659d35d41682c275c861afa189b898101bec6e1470a82a16ace3c95a03e878d8b76c6dad9578668fea2d0952778403f082a683c5df519c0a2580eb9dde228e0284cf84c2936d3777395d49a13dc50d38bacacdf6cf2003d309196c92c17983a179777451abc874331d342e02c115ea9147a565968cd52749918105793517e9ca35af49a18626843b6f1a63fb087e3b4133f55cf2ff79ad6b113f40e04420aa1cdc447c6b3700b6041acbc2a17fa81712445a07f070db66f4edb4408a8e499fa7cd821908bab367cdbe5f235e3023c588d872f3f415ffe0c461d2faec735a339303c63e74f57088cb89775dee600eaf9a53e6c9608dc9a8467d8bb5b4eebd69c2ed440927c45337184dbc906963f627a13f13185898faf4443dd558ba30fdcdc4a6144333206c945d7db4d5d1460596c31b2c00e435d6326e95e239394fd8e9bf411cdadcf6f9899195b0898ae37cc25720ad74042788885fd66da309c6b13a0d73bc0678f0afc6b0a71fd7414e880da125f5158d23fb53567db4a42141a121e7b2326c50d3ab3ba34bcd2032ebd41237c056575d26c85c426a8ffb575054ea3173f1c6833fe8582a10a269bbaca3d082ca1a52e5553c871f0f82522deb356c416e88538dad8e1b4b912c176413573507db238d1a725533db557c2285d9304e2b7d19ff4c4d24fdb48cbd9b6f19d9194ce5c3424431c0fdd583ab25305ae6cf6b25811edf0f01f7224df67873b293930dade3e3672055224dd0f9ed455cfdaf041268c8f49a7beb51de0aff27365b215a241d71f41174257eeaafa0a68beab5a9ddab171a9db0721ac17aaa90242b6943c394feda96730f8f85312d12c27a7a88e8049486f162b3ce5b02111db0fe360ca416d27796f25d9d2e78ed1e5ebbc0a20b4083120865fe96daf9125256bcc530a291541fe87c72eab57e15c9643d2a61e4db5cebaca8f52f9a85a0c78a40ecafd1526a927f18039af82075cf1bc0bba98f7a00402c1b803f4c574f6d40db76cee91506d0da21402298b2bef6187aee3b85f7e153386580b82914a4b3c69cecdbf1a108c70174d933c9db0f54bdf8f546b514fafbf0512de6d20d780a002bda80a5726055bf8a28603219d862fd92910297e4ed0227a3437e42ae3f78e8e6e22345dcd87ea404d0e29f6818bc82dd1da4109e030465210fca758bf462a474af16fab51128c5cdd66808b9e038eed7cc7ef9956a00bb082b1c4685bd314aa0ba2492cbd7d10bea7099d18d1d6a377bbf1ea4db13656f600611c12a84cbbed41d571aeb9934036ed40536fcf813125b2ebd953e25bbd2a45cb7a24ee5f6622e8ab37465619bd178175df9b7c95ac64367378c3cd0140069f1a771f53c1aee04e1f055038c566b91b95c7ca22655c860f06904f68b7e18261c129e2dc1066f3675361e66e7d2ab46b72a4c2a377378da04199aff21e80ab70b35db6770582ba46656d2137222a01a683821b72e589c8aa7f49217a74c628dd2017a48bdf83b2f3462487b2606f2f47b1eadd7abaa23616f5adebf77a39d3d323d14938ee88ceaeae23e1b4c9b3e3ce1f472632f5b5f39d76c946a67980a135458b3ccb1c9509dad37b522981d514b41b4c131642b50067fcc118d524317d9e9bb442ce396a86e5b428b6a40b0e6e9e857065be7c103a77ddd2532889c1354383e1f9c160afe5590bf756109964587b7c9f3d92666eb9783551511848096b8d8fd30f17c9642c58cee5c0d6de55c522906e7c45d0939454bb44fbb47348db92fb76d51b2e1d7b32abbbea0d179d49ee3913f8165dd8456d2ba61a5000ca6596b3b9f3723523e0a7d82bfd26912cdcd8870dafa7bdf5b480290a8a735d157012a965415686d529745418d21602241402b778291d72f7fc183896d77ee248d3fb8b61648c9c9a8e19492e106ae93b0cfc4306970a53bdf9059f151b3001eea9ef41e1eb894adaaf54a13bc734fa0e6f6112685be9f080717db0122d99faa1fe97e05fc1c57e6cc110280d9ab0dbd8ca86243f9fbcd6dc56ad9e77625902dcbfd7b5a172cda669cae253cbb95c3c97c18ec3584f70c4491f6d34a2c55bca6d25d7c99801f94e7661c0a03320031466d9e9adba4e1981b7261dd844d109016712db57388c1d35d1b999928634f84d5ca611cac5e53d2e2039b2d2c38a0d3ca438a9502964a21ed1ea5ed8c044b3e022a4aa02858f29d365559f77471675ef0755b25c5bf04c2f9f3b1f39d920e1b498a3f92020833c2755565baf15e96b2b266a118d40b39653c63033d31ba1db30d33b5f2e9237b2156a46bbb2c74619f06619a53ea93bd56ff1fe58669fe7511c7a990ecc1a5ed2bc9e6d45f87e5196d40abc44772e37ff7f101988e8a9ebb9ad25949d694f124c02153cc6970290d864c9fc72aeff8e522298c4cd489ce25e2789c1921c1422806bb805c617c8981f9af5fe0e4e9b95e6e60fa69beb19c5fca08a0bea187eed957d3893e77b59a91fc97d7290f6c23b4e17520f9430e3a898c7259cf76caa23d06ccf16d36e0c7900dcf3f1c0c6916d425e20f7bba9b45a1d09dd87e58bb85a621ba8d74406a767ab59f97334fb7bcfe113e966f57ea87b90f6ee7bf4ab3660f2436c764f87e32bd6a4a5f978fc6e9ca350260a4c1d4d1dcbcc7c059ff8de670c2a5faf08f5cea1d9ad4f931ad45fceaab8ca38719bf8ae152e302a7e03c453bb3338d02c226c1776fbe8e696def33cc9a8c9000c6b680a5d20055aeb5f01948480f2206be62f668247ddf0c7424ca4916f324aeea057e551b0629edc70cbb75059d714fa3f5d707c4602e27bae0361062da7c6e503e62ff3c30b0d6ea39534d6c23d2f89dc49d6488392305f499865b2e861f20775641888c38bac092a1338f422c4e159c1e1473ff24bd214cd639a5fbf5823bbf3537745755101814a4cde63c0db6511d4390fce353cfa12700aeef529f39da47d3d78b77d7ffc08871e5061d166580596586a33022568e0a95cf7736f611b39b315357615d4a3f6f86211409cb0cc64ffb35760123cffa28be2fd724596afd020fd0606d159ef9d5720fefe5273afe00cc8b7ed5865a5d488980d67ef2092d5bf331f2fe24071b68d51254e57c1881dbef8b4bcddfb4553081196965fffc1b05b39562a191b41e6ad1551f9afb575c21efbe8616e516d9092005a6084a09459996d80416e9ceed1877dec58fb910045aa73407dda5e58104366d3712aa903d766c352b84e78676f30cbfd99547d47ca08c2c8728e5f2ae3df8a8312186375af03aa99dba2af73c21f87ad675dd8798a7c997a65a3ae958d01b217cc4b98bb08a3abbcb77237092036d9bc43092367d4d0aaa905cc39e28e11a72a5045123d211ca54d98e669240dff4883fa2de45daf38c752977fa811c1b55609c8309b3550a367079c1f6fc8ed12bbe2dc4c9553470a59d54d323420762f84022764669e2bc16e67d0bfbf723c270ade8cbae829256ae252aae31387d096eeb18989067ff40ecf6d9be0342960df95780ef81a84951b907fcdbd61bb4d88492c590411462e5e1639a5fa251c03212ab94e4778ebcd48ad5df206b2fb4fc4033833b9034bd6ead0673578d551691020256fac43fb95aa6ae497134ca08e7d3518057f3261387cbddbc1bbffe402c25564a7f2af46154124ac783318364a6f22f293e3a82528bf3c284babc3d064f142758ea9d291de32f62ce0008ade2de0a150a61c86b011430a144588b7ddee8ac29f9fc767a89615593c7cef9a3e02db71efb96210ffc816057bdfab5fd9edfed807ffb3cd84a99ed564ecd5acbf159a7662b9e83f401c9489b65f88d28c97b3be308c3119a80eb23877cf281eb11a6be5e765cefa15ac4bcc8dacf47d8e483877609393d19f95c9a51932adea06a1ae4cb3c0ca4867dcd8dc487acf0cc0296852ec641da9d7c90adc81ef02981c82e33da89718949f34877cbe0787bd80b8a88a08b0d6c8e100a911a79aabc524e257890db7cb927f4305ab2683ec9d378019880afa570ae15f6a52e8e170567c9a91092fbc294a7bf71f5278c5f99b46b78713fcf3b9810f421acdb2b014059e9cc5627e96660bb8ceb2dd172f412e4f6c614bbded915c71ce29d7d6eea3da7cd166caf4ce413a5f66002edf6b1d496bde3823c26117940b9bf5f4949d6ec4df19310a57bc43a6ca03b020a28f1bebdeb251d164edd02169a57247af1122ca37431883469aa901e50aee0b69745fa977c45a9477c1f45acba96be8bf42a68e4a48ac6ea275dc87d5647e2e4bb616ba6f4586aa3a8fb3deaa7b8f082cc90e104a1611654166541f14826d253082135ead870a659606b596b8adf85934b0b079d1e7a348209359f8d168b15d0ef918bb3dafe822f91a9131008bf9bc199f3a422af1388d5291f23219001a3f3d5c5e109fc8d4ad62a06c63db3ec3d1f1c59bd61ca52b8e4f8c4840570a2e9e26665b3d8541ce32b34a5b12d9c425857fa1bec75d78721537a4ef452ddc253b79c087a28c5bf338978dc89be8f76cd64a252ef0e7d46944b1d89efa1889ca5c81d67d660f50610fbe71ad304d29f313fdfd898071a4e0562cc3b3a65c72a4341a59bfd92fe192d481032e53482eff4d94565562c8f75638a1ba60594a8156699ae300377c18afbfb4f302ea6b3963704a0410b565f7c971d249255883432743e5001523f663eed6660591eaf966200fc61e1b87911d4c7522d50ec5ec51c15578cf50f497b113e1da18444d50dc7e723f0363c352ed6ca3406f959e0f064827e72f9c80f923804a3555826927e11609a0eb522669404843073b098ae0603a2041c38a2f4214289217cef2c63ae05beaa00c4b77f7620750c01f1003331775706336f448ad32d03974ea0ed155c22e2c0b50284ac48930d58be043c9628b8faf8661d782ea9437cf7dc50820019faa5d8c33e845ac65b064d007cdf0aef93ccf25126d3827b7c60497cbfaccd4530e981976044008879c184324b2281f396bea0b15df5aef0a80ab4a74398e3110515c98a8de0caba4a43eb33607c9a1bd0776134292c039741b8e986de6cb8a66aac1ae7bb9472fd97d61c6d8b84070b1ff7096d4fdc52e66d17ea857ec064a1b77821eaba5c7cf25dfe8dd9188c7a70f327a4386953898c50515c5e07b0c8d6e20e0c40e749b414ca0dc4d78f302122a0d60d41c0d7fca4c5f851b06e55b183f78e629b3fd93c1677a707fec77251ee896bc52d6e13432c95e54ac7eedab5a6d4f4bf009343e6a283a80128dc03b60d32c47e69ffbe15c3cf1539a46079ebd954b9b07ca34564f3051b25957b3fd9c146a43835ec85a59bdbece417978db00e2d86ecd767eb9db491a3f74740fa159f871790ca84094bfe32f747885cd831b693d2e63e75e963254a313fd01e86d5d29436397bf7d69a7825a8084a5d17d7fa6f130b642e0e61f86b346e15fcbdc868f4409d046959b16662eb78ad806784ba3bd0f467acc909bef00a7acd467eadebe651ced6543c8d98538731381fd0a23cf0ee97170830e471309294933439d001954d21c72ce443210703b0805e073ab3bba107a02a78b87e77fc3c2384222163c35a4c46582b2448b3c808c48c862f1a2b4ccec42968704a2a951d320da2c846537b0fa1b5d854da779109d7dff4dc555ae775322a750112438bc976a3628945153369e17c1264478f227c0020a773c6437c7999e6764911aa5d8527567ff4cbdf0143e23842f5ad3c06050cd6c4de29450a9f2e0c9d248992872fcc9ed18dff47fc32527d0b6fe889e000d54e71ce5cee2188dbf37fc98f2e3d34873d09982e4011564bac12adb29f0e5790b47d2812800808aeb89821365525dcbf8bab4ff7737a89f634a93bc80acda41e358e611a024f02399520cdcd11d4486c0908e134c2f3c7c18f93a5bda9d6c5e54118598f93131d9bf4631b0cc424b11f043741ed6204a8c51808115b9e4b4dee2d50a31608f1414c3fc4de83a5c7f1687cea2eba3b92782603bfa73a54bc78fdcc752537c60b0f5f1fbfb4e05140588636e9918dad3f48d75ce931a02f39d4fe0b39a7d0eaa3e224ef825cb7d94d25380e1fb87fc36c760f3f6e6b62e2d52d4d1682f8e6684f49df629902262fd646ba2a011e70d14f3ac26fd3767c10709ee101153500b44e422a69cf21b5381c6f4b15f724317092d9fd7af23e6e97258ee7220020fde3f01c465d26bd888663966848540372608437fcb966a8d309a7d75858d131e72f173b6b85f1a27c80a88328a1577b68d201f1a77bd0dc113b061d544978f06dfb4fe840c2d8981148d625c85dd069744b55b65908bc32a4211568bbb20af3525d106d0ac97a0ec3f7f27349087e89dc5ed7d33f3bbfb5711904b085b6cb3e3346e0c901a641874a6de568564285939a19e317c7b4aef66b744d7ab0163911b1e911d7bd2f5ccefd9fb12a298240ef6a837f32714e3709c6e08ca9216c981c9b1a582984dcf0059310c09c55cda92ef77a329a8e86fcf0f744767a6c4616726bab748c5a6fc32f1a05e45a1d84bcd20c2f0275849aa97ad4d3f0451d0ce73a04a45016f760d36643afb9eba6d021ecb6e53b912cbef11d1f590bac099b3e98e8fecf332bc009c7ce15185796d3d2f8acdcbff84a3b11cc89eec9296df8fed6a231a8f41651a673f14540c1190baf6382354de66ea56ab686d7361281573ff327442f7a085429844b800364a662ebf996a6a3b21769b9cfcbaf41806d7cadc138b57b44a2abdc60a731d9c54a6c8323fcf279c2fa13c5c8e8b97896cf3c54be90ed130ec753757511ae6917b772dafe94f521461d63cedba8242e1105f28a261632a30db863d7e29e7835f3b71168cc8405ae199b538d9e3a5d89d16fcb1a87dada4f29fbb52b717efa0930a636924b530aa4958d20941a66ef0564d55ac8f667807bee96e083e2d6bdeff0d73807fb2e08a6df6154fdc05ebf09dd2603a9a387f5d6f0d146676f5274409f10e064f8d88f54a6cfffe2e69b994d5d69757d57c921983d16a7d0806cbef21ebad0b1f139466ad8b0c0cb8a54e53c3080c616b026149cf39c3acc29e759d0fd6b54dd428ccd182614944a9b71adcdfbd3e8a95944f79b1337050feed6ce72dcd4fc6b36bac51a05083d62406d0d4e83041632a9e84d3d0ac4ff393059f7224bf0ad5a4cfcffba0ae9660ae3f350354522aa3394da4ce1383faa6723b8063c93262a593a590d76d00f38c149e69925b9ce9ab15c3b5e88f94a3980050ba82eea1d90ff8530787e72564125ad5d6c9a2347d4d1b1bf6fb712fb96bcf2c20116c762b69449118546829be48b8d980e1e04712d4c90136832f2fc03bb9ace910446bde292d37e0ba2e228b80ab527406c460004db2e108a23374d737147b1cbc22532b8cac84b1bfa9a55ad8cf29fb11e04b18f9834763279aacc000b88650c893678a5d1f4ffd844f7ae79e04a33a1db7b89e7a4cded60883703d4c430ba44c7990f59b5e0e1537afb6caadc2d649b18b19c4b236314192e3ab8c5c62f007341ce35a86d809756859fa14afa6184296f65a4c262b14b9bfef9795860986eee85d52d25ce6ad99cd48be425b91d3b6a18236b5a6b327532a26d2c2d8387a338169fb882cf145b7e8434bcb7d829f22f5e954caa9e86a1d7bf1240feced94f80e00eef078feb402f008ff05ccb20eb1a74bd61089d92b519064ff5c2176cf5be544a2bfa705ba62bafda1c7b1551cb4460bf0cc233e2570b2068cad2dbcf92b112521ee8eec2d9703da3b49fc33fab217ffbe97573271b867b7e6649fcfeab4d359ac0e8b3d37b2eb1bdf4fc38e5a8e7734bc6e282b34fd6d292528a9d92740468988f9a2be8e47a838d538a0cb08b914e8dacb50c9e996e91cd9e63aa1a8df0533a60289ac23c577340e6bb490676a1f1c23fc8ca6f918049f05425f7d0d240f1562f8e05ab891bff85ce6fe67b7f265e1903d2e44d3c9a030cf1b61d62ac6cb6ea29283319b65cd3d1ed99ee9b00fa0bcef7f83076494857a1aabb73d8c8dab2bc97452e2a10a1d158fec1bd1babf8a836dbc0924759b67a1168ddea7ad06b73e05390e8c92b79703e6def143f28365b62e3c1e0416281da2b8f3c9b3adcc2398b0a7a4a75d9617a8fa5a27a5e9123056b1adf2fee36342c98329970c01b0e9271b4012653d4355ee0552f0809c288fc352b8b71bb2b2adfb224fe3c3fee3f6c9c236781fa8f452c1a3da1aa50fd8072aec2af1fc479ead2505224c0e7cdb00cf9712e282d964a6202fb6732c77bc425620b1a36a5f60bdcab24b99a5a453c5882783a1fd8aeaab85865842dd03ee87b3b4b7713b105ea4618ac3563234e2c2d2a249f7bc63e75ab93663b324ebca3775ce4bd3c11e40754d45fa24be8fecf73240d0208a446324c7f5e86c2a00a735a9c8e21dacfa4acc9673f33bdab6cd97cae66492989a4cd1f0a2431e58098515a1068a1bb703539672337e9b7b25ec0747737630c6e2b259967efd4b77d44d2a92621a25865b3900657cab83bd399557bbe6711c0fb0acadeb930f7a42feefb9e21efded7a2329fb1a00fb0288e463824882efc21cbcf93f671aa687e990f23191ce25f9a4d0d5f7eee8292bcd4fc031a1b9cbb0774cd2b8a792bb8d81fb55485873b875183e5f91ebfe9f1de1d8da605fa615e3b372b6d5dda3e70451c252c39d4605fed1b0f3bcd993005a2c398c6d0efb2ffb421cc4424563dfb530c7aef1292627ee24226c6bdfd1ace879a94f379bce15e2bc50071bda35c0beed005b269478aa892aa8f605c5556668fa685f7212ba0523881d261005b245b6301cbb132a45b636bc5c8d50876738073908aef2e92dbe881853e0b9785630679571d900bce84b8fb6459efe8c6d6227a2f5be9b8a0e274e6a57b143f3e52a8a3a1b36916575a00c0a35e238e3ff4bedd51fc1a80c7fb01e11d04d4898ca07fa9d641695cbfc0b7bb94595b05fe9fec182ab259ed771f4027a3a892bef38142c92eff302e5b4a3ac9c1a95d339ccc253766ebb29b6595d32d1190e23cebc5338cf91b4f4dd9c92bcc677d392690519712713cac72f3df2161f4e22e4c153ec8dee26b4918bf30b507460a93cc3d6cad0c40eadf6808ba37e80d93e31904f568edde2130984a123d19d58b59f02915942a54364e8540560fa6d9aa95025d3adcad447d05a09b665f02d8c2e319ed1f66f8b2e2b11392574e8d83405cff9a54b74fd2da9ed6e0497a530078d8d7832c59e37c813f6f4da8da2cabe89ed55647de9f912af9cad9100f4f1321cb856191e57051196aa9b54c0061c834be101a4d700ec16528155c16388913860ded7c62500b6098be0589ae1ceae8de53123dae708cbd9c8a88e96472e009737a1ec6464fcc28fe1983d8abc58f5fdd9353065bdc79ff750beee71b2cd45fdd3251b223a95403726ce4635c5fd20764ebee9e2b7e725afa457513bddae2d8468a907ebe1cddf204c831422bcb07c36d046cc0512e1861adfe67af02477513763bc8bb4de4f2ae3e04a201c9af37c4b8bed3e8200297795510a0f166b4bf301b8020615120a8ea242ee1da6ab60bc6373cb32da51fb3ce051013a7e20c519cf821b7d1c36ca1a0f9854d52f799b0454b5da006bf3b83c0853995887f6443a7e545b4c29495ee0ba8bb50f403ca75b35f61bfc0948c9e033afba4edbeb576322d49035e4cb60d113b40370cc87a35328e1f26f8dc18cd70cfbbe0abf6a81f1b0ec1760e683c2bdfcfa11bd40c2eca814f4b4195819a985203b41fbc98377f1a11fe498e21485ef200af052d2d8b7c40c87c8784e0799bbbdeab5de79328f8803f8d942a24e83e190ea1a0912fc950220ec17daf0d5928d2e8e2de07f2e076f778b1ff6a955f2d1602aa5cc1dfd30c3b70d0a7f74d2826c6792a6e211535bf946a4f50c684ffa188600acf10f00886014d881610f3c6b3df2c8a5a265dd2c45a7ff7482790ad62542af58fb8b339b82fdc171b28269acb4108e886842f7121ae47cc9fc472f4536506478e182201dc3e246496513c05920a3cdf6a8c3b47d794420671e592b93cc258b73e9a5d6901607523af77118d2b7e2294e2d6ab989cc80754359177bff28ea4341483e3b57779c4b80f5a041ff07ce5fcd9bb9a2ae1b624f6aa544e11c5c55f7dd8aaf1321fd9aa92e7640038545b24f0240d7257de4f2f4b45a08cb26eac54fbe52e2a0267256c1be98f6e7a6eaa3eaa5794d21e19b3c6341bab8871dcbaa5ad1b32916f152f7d5baea0c0a9feb50745a268ddd70a3c1f73e4bd7ff1362d55147c2a3926f92a4815db9c9eb1610fd357702d3e74cfa28889a6f3f38caa7962f5670a3fecaf725d0048036cc1b83b6f84aaaf44d5e9cf6ca300d393b03c517c4c08aef9924e26e7d02e9386fcef14c4ae018c91982f1944a7e5127acb6681bf4401d975fc666314642efbb7793b047d45b3dace5cbae92cf46b1e97428653ec23c06f208f1a4ef13cf8aab69e3bbd257e4e27dba671f5e128a4b47c1e876d192209c353f721ce48a55374b98a697036105457ce1e8ff732d5d74b10d1e68235647a86ad785262ecbeac5342b20025229dc4e2735552f37da064f36a573e0913993afbb98938dd4c7473cf71b0384a630c3d4ec85d486b69525095815f4797375f97a045fdefb535c683e5ad08cfe3c47a0b75792b35b6ad427f71e0106e2229a3d83aa9f22ae155bd75f84151f5e24a0c2352dab48a3d577cf0bdeda6d7cb8712e48a1d3e25b677ea3742f15953e39ab5621f869ea1896f6536c472d79b2369e70f98ceff2065cec129d1b389417b2deb536bfb04dcd088d04189d9765182e11e4354930af9a80361d397c6cf92f6d7427f2bff27f8ba94accfaa5e84384e45954d02ddec3a6504ef07a1c45f4268660d2645b258d2734d885acde6e204a8412f7d7fe25a0c3ae57bcaa747e6c8aa9225a71fecde5da8cb98ae17192df28ae7a6db30ba2bb1fa92bc051a1995e8d1c3d98c474af51a6ef010fc9ec1956400d1b6908a5c5dcd5c408d9b3e20807497ca37247f17e1cfdcb7d8e44556b32a898eb0d2782bfbb90d68e41147ba2170536329f531930daaecd543012cc48752177aaec84110dad6809c969a0ab6968e323e658b64538ff43c5af121e4f66399092acf200a25d932ff59a43dcd2da420c5ee72d4f52ec56e1904afdd7a87efe2431635a7ebd7d81ec5cb836eff8d4b22634ebf11d1438f91bee07fb1c30031d8da24c10b1f6b66d48c638d48e67af9887f7e59985698c2c1bfe48ef0281115a153d84c6e21bcff24231662374f7202c00ac6bff57307432222bcde5d86c73597deb83cdfd73bf2f3961308d2f4eb625b46d16b88ab83264a2861f3291a4929636885286d79bf9f45395462169ff6bd53e898f54509b38cf24570c6dd89601a5028cbe528a85639bf8ff0a53995cdbf18bb8fb9d9c9abf96699cdb4e7b067f82b8e34fbb7f095c98ffca8afd10c29b1b217a6d91e8417c1f5fba6725bbe3895db33948763429a69526454262779520cf05ffd78a07fa8a8997174a8d7b2fc34d6b39c6cafed1a6032546b2f1de727b0385932851a133acbf694ec0fc4ec9565958f480b698c81431924924c8075e56a52d00327c80ec2e2193cabcc2810b7bbf0b46e5bf39b1ddf653195a5aefa3ee4081a218e582349bec13c5b46ad910a7d036f0d2c608d9ac8feab9b1ce781818404bfba61f81394d4367bc8bc61157d70ec7d878e63982905418ab0692e4c5f7b3ab76fd588231ed030e1003665fce7c9c2440c421d28381098730341048d10df3dabf079eaa304eace1e3fe012408a8f29a844371f2546350d8787b435ccd2d014aca1c78bc6cbad243829972abe2acdcea7b9a88b50a90f0c9204ca3a3f9b54305e15251d2f4e10ee00105140cae798342b731c20e6cc34bb3318e4204cdc37d1219c52bc53e32e6bf45c1d6ef7bbe8e72ef9c5aedf5f175380a7e0a7b76ee2daf2633ffb1fb5d61a2184904df6de7b932de50e8b09f50879093a76447829c34abad4df71a1b6bdfbee7c3ce553cb49a485c4d6ac23a5dd58e7d27295dfa695d2c26b52db287b55a0c24b4ba11dd5d3c70a1cc147820fcf43e0a5edcdf3f8a95d5611f2d05a92c2c753e9b1d4e381b492f4159e02b9b582f156cddd0ade4a83cd3945c05f9af5a7813e699f4b2d3ed3a8c33c092df3e47aa6b33aad33061fe11a186637994da6042b5ad57ec587a7dae4c7f311ae41a789aad475d94d66b2b48d89dcf86815c12f55871612d5e5f391119c3a0fe91647e95ca93918ef7602eebeb614c00ba73b8fa8575a3ec233e28e9eb1dae384946766867c0821bcbbce92df380d65b80bb84e8b340839c2853cf2e31ae03a2dd2904492a4ddaa77fd94ff68521ef41ed2a4bc89963d1569b187b4ec65d8652d8d8692acb29b0cfcd46828c9aa8ddb0c15a9cd4458c729d650e41ee03a2dd600c59d9556dae2df774cd354a7572c4a7e529cbeea58ad187dadf49556a230abd66318f68a5ea66f6573bc5bbfe396aa53f7fcd6b7ec2c036f33e8cc269c52b1d38b321057a71bcbb4c7caf4ad761bc1cccdac4cdfead22c3be9938267503b49bb89b2963ca8b53a6b8297e9da5bdb6dd2b6acab8defecc79cc8f7d24a3974dc7877658e77a5fc7437b66f46c7d5c48dd79f0faeb1a9e05171b7fee38a7dd837c5ddfa327d9fcdf16e05dee1906dd3759795e9cb402e7cce909c1ed7c791325c2347a8b8f559d7d5707349d769a1869a4bc475b6aa26b95f5a084228d3577e93e9cb3a7c63bfbec9f46415518a76abe227c8ca742389ff1c141fd2b2a712edc4ac4cdfea17fc68eea97832bb595606deca6e3355738d845a276d899f145c637ad73bd98dff7ae2a0be67a18c7d302f2d3ce941b6bdbcbc88ee494d569a0e8fa8eec6777b52f00c2992e12c2cc2dde9687821bd6071fb431851069a961868a8b91de35e2e5b4f0a9e01df96b48e67c4ce69125b13908267f061ded4076ea82dc136431863a4674ae5bb80e82b5031c59cbe7022909997dff42d93d12a2290c9ee00dc0cd856c6ab38d3fa2e0878ed0f190c048ce816f8800b8580b77e93b9eb2e743193e670e640518afde1e6707f78404c11ea6762a445448e4a55ee0cf9012f2f0a50c0010e308001c48861125304f8aa995c3145a0947efa1543692da0ee021953044ae9d4640ca515614a51b9d6cfdc3a2b40a51501b7e4e670b2a29fa1b9d2222287b3b9d4258199cbf67240f44dec6572e9756bfdd3b6573f5dde1a44ad94b224105d19d17d175e5a674d60fa344331c4c1b932af00557eb25d4d32c249dba619c82a98a6699ace9adc80fbc31f62f8128a6086c69a8991f605326603ee0f31fc1c55f0f1509d132287fb0333f363d4f813ac9ad42298a1b9cc7f98b9932581bc3cf19df5f6304d30e7348114dce95369c9b315cfa14e878756470d2d24c12666fa4c8c8c26b1bb5bd6701241f79ecbf4cce384702217c4cb229b9ac47d4575ce654ed932f574df6ff52ad05da7e6e9f5e445b7b0186eaebb035527a33a2250b00ffec13554d00f3815fa1938157a47b121bb56e85486acef3c2fa106d9a5e71f4e08be94b570e9c656b8945a0c844b7dcc39abae4d75cb38c508e1d48c641068157a4a9b5ec80f1f4da2d7c09079c005419dceb52e4ccfd1b44960bfee62fa7152f641698f26d14fed0c593cd38be890517aec331f41cb8e20fc657514015a0d5cc7ac8ecbea704f65ce79aa59f3d59a16a5d6034d7a344ec79a34dd12a71dd1cb534a27ba750ffa48e50fe7b4b07bdcd114fb08d5c9d8200edf11f56a1e47e34c6a524da2f4f5d9da55280d1910da40b67fcb6cd3d849e99be6d1679405f254e8619a690cfd43424fb18bf89029b9747b492e3d1cf2bc30d22dd4693dbd4e4d4e29f54c5804de5c3ae9bbb9f4959a4f85fe69d953a1879ae8a9d09b6893ce3a7f69f31f8fe65e367f63de8b59866c13510ca3306ad679012fe478417331152cb954dd668a1c7ba5300c135d27041704355f313bb56da6c8a5aa3bab88eb54a5aeb345c465ad4d245ae9167a4ba3a7d194de3d7af7281de2d2b7109c10f323ea1555a94af5e9b3e7f24e2f7a2ef0f47f2ef1f44e06b5258863d5dc210f4a2ec24316830484281a31b5a007d388424c13f2a185ea64e4dc290bb91eefd655ef66f77d7242c0fb4ec47bef04702e0e36e03e06dc17c47dcfe43e00dc67d94d64a4b216c6bdf36f9959f408e77c56e0684632f89c17979f2bc3e5e7905cbf1e5f9048111ed2e35ed60ed1c2903dcb86121d7041bc1787bcf7624e6deb89ba392e989979729fd84ddccccc3c396747fdda3dd78e63cd9d5cbb5caf2ebbb3a364a2995a109a967d4b4269c85ae7e160d527cc364e9c7a629ce959b4dbeca94367c85c8c8b111dc62b08974018df45f4e36b8c81a3edb586302699a6254d4c44da857d94c18b57d32d930a215674a4792e289f40d773c13e659f4ea6e863127dbe9160684ca0d893394db2ccc2e920ede3d1324ccbd8c7ebee49e9e3b6acb6a69ad8497ac7b6ce4e770f19dff10238d954dd69c954d9b7d397b6a72aa38c30d65c33b3331dc08b9664d32184104238279c304208219c7114a58c324231c421977a9d46a0915330890b823adc91a7e4cea55eaca9e91ecf051a792ad4df42ec64390423b46f48b432a091e7f26c0bb13513031d136d87ce90bd9f5f0cf509c873a999a7ac8881c5a50e874cf7e1034845f5782a14f55aeb057074700c768e611733a9ed15b9d4331f59e50ae31ecf856b322ac9dd5e1697fa16e3526f0875f7843c15eaa3e995ad4ebde7ac5665555cc08943aa1d911db2fe4549447ee4f832ed443b32329ae071340e9c5ef7112adfc9d82e0136c943f63ee7cbdee31ed5c99833cb442492dd92b8eeeebe1cf05b13d79500c68ddf5c892fa59452da1cf1d0be491619b2bbdd5996adb339e0379e9fe0f9f33a37d9e688b68a79685d57ce4d2a6a0c1940844e15709de8ba3bcb9672d46f73babb140bde75ccc4bc4f1a0ade567dfe5944c8cbbff7ce6326e6591ef1d2da1cf5f3b4d2dcad135a27de794c3c9dc77be76179ccc41db0a110133f644c34f15c98a0a1a1a18979114e27b92625e14cfa906dcee630ce750faa33f143b6b91dd73aba855d66bfbfc88405f8466bd287ccc5af34c93d3a19d3734316930bd1104e854f9dc91eb2cdd9189102c3f770ced7a811b1125ff39f4d7d1238566eb4a51c2578b78a79772716c8eb9889919f1a0a24b449b0c0051c439d92f23c6662a4e5414f599bc31d6aeeba24aa90a7d23a213fe57c2a6e9e873c0fcbc3b91dd30cec6906dcb35b9a5b022679c8a66f434c5f70823a0f4a5178eaee53c678ea4eccf39053ca3f1727ea79cc57ea939eb24e886278501e4578a74e9d1664a8b9eea4151ad75d67053920e16e435cf739499fece49e6bd2fbbddbb19c991a3a4146172f8b5b6badd5a2281af593e607e3ffcb06e09515c02d0c158089dd4401b01f0b00eb9e8ac766189db46bd7ae15acb0768b6aadd5568b1ebe52971b393639363936d5fa5551d70d9753b1b0bc1f2c34301ae5480d75cb54bd4a2dbb5375486aad20842548d1ee18a7b690d8fa130d2bfebaec46e34ea7d1f2cacaca8a5cc12c16cac2ac4c7737cbb402a5bc68c83f4b5978c67c979597646141b2524f69b362e9ee66e996eea9592696ee696261a1c162b195841f4e55732be6ee943912102b9f78c6f4e97d0a22247ab5a294ba8bd2aa02d1ead4c5c235e8998256f56a2e33d50d1942082194333a569e15a5ab57b8465f3e2a5e0d0bd790f45bf56a6efc3b535b5919aa31335fd75ba33159d0b2406dc3a151978f26a14f771faef07b7cb565e1191264a93de1834ea8ddd8e2d6361ad5b23c9c5b2baaaa2aeab22c2bcfd2eaa726312d7b1af5e0a4b3e724bd748ba7b2ac58c896524ae9a5692c5ca3521c1a0e8d998f43a301594633099128cb58b06fd395daadbee1d0ee75eb553b66a75544f5d2559d890987c6c2352a16295fcda558409c5285ac8644f594361dd36af66aa5babb4bcf61dd1485d123161234ce4718db96a8bfc768ab943951e6449913658d3ddd58cf3955c6c6be31927a49cd292fd337cef909e7fc46cd39678cf36c23f5b6a32cc6c738e3678c51d6cc2a227bb4a5f83e96d58f8da00fe89ad70a8e6a8abf2a05e37d9abb549c2ea5c5f864acaf4eb5eb53939f346a8a320b75cbe4b9982d8651ec5b758f700de9b196aae766ca96e267e5395f238561169bf198465f2fe1bcccaaf5ebba6c7579dd3a52bd562ad218638c54468871c80f92758a846e57d2d2ba3e4a2995e9a795b049e97ba04b3ab1293d10fb7cda0f175981507ea319258910c9a244dd234261212917a136acc88d9752f2b425b8527d2845dbce0a60f26c41d28eb0538f171149e9067aa4de4da9ea7c85c9b7950bb2156832993604a2eac330cdddf71e469908fc68d63d1a251bc61378720506af8c5eb172e14bb5ad5c4a29ccf215977abc62e5621486612b37567cc5153ca3c8159f06d9fc6024cea2cfce9a7557df9cf3692549cdf9de8cefdd94e731921bef1a47d5f3ea9ed11161dc79cc3d5807c6c94868b41b23b91047157b8a71be15aaa3cc8bc798df8fe71e71ce0dd25b9667de5aa93a1ef4899e950944d98f87d2fe71eb93ef69dddcc33ad43ad3e8439ac9611e47abedf989ca62769b17cbdb52dffae4272c8eeace3ead4c7b3a97d0273ff1e8e1ff04d79887559502c5a58fd6ca86a3baf3950a14179e9fe02778063cbd9b2c222823b9b1bbbb9b9f704ea5415ed47e40b8755ce6f279153f6ba55af5eaacc167d7ab95ce39674b47cd4967654a62d562947e7b8fdf7bd396e8e51f333b66c7dc4a4ab33bc64e7237c8dd3af190b6e74d6f9a3d379eb302d2f617fde8a7cdae6e9e33b38aa87f9885446631bb351fe33a59cc6e1311f101b9954af9de7befc9091ff7ab43ed7d4e69f110be5bfabaaff4ade273d17359992bcf4e2cbb2d5755256de97d1e5a7093794d6de93d9ecf5c8138cdd9afaab375c49c56e6e153aa533844d36d954de66d0dc5859fd4a51193dda69b792a1211752e8557c62be77465b453934ec2c046ea145267855aa5966559f3b22c4ad9baae43eb0cfa654153c8e51a78e3704056dddabebbbbbb9b7ebea76a62a25b9e8c333afa6eeaf3247237cf77dc86efd04dd38ae6e79942e014d28e7294f51ebfc7eff17bfc1ebfc7efb1c5a798628a233333b3075a5df3de0512cd996522d14f72d3c6d6ac7704d7e8b365091172e555ea7ba07cd7bc3f51762be75c1ecdf6b242bac86e22510d8c5ff6358f40d5428206008f26867d34a314bb89ee0d18769ba2074fec76131bb2b05f1ef72fcac8ad1446dadd3d3d0cfb2c0ff3207f7336cfe5a4b81c0bb3a869514a29a59452b6045fa78d4c4c9c764d9b9999395e1a2b3373f3cacacb8b356796894494d23b1a798675782db9754d4ecd9b2e5a727be7e565658544fa45229b1a7ac578ad57913a7422086fe6cc3291e82791acc9a2afec4be419f1f24eca29e4f24b615b040f4f1a89f3c96c2871a35b26750fd5e6a9d4e2c3acf79e2c83f51e175c43deb2ae495e58cfca64175ce3559627f3489c0b99f93db6cf96ac1765195e5bf2467221bd90d68bf4d1923837de4d69a5945276216f2417f23d89433fa7e71df3c82e7806851e2a2f4b4a0fac26cdad966559f559d985e42274bdd2ea5bfbc81b97853b6597142e0b7c4ce329a595d6bb801b0e87830387c3d970f0bb56b4acec42be3e8ae14ed3651738ac57d5d25092c9bccbd6e329ae5bdc8d8a419b2e08cb6e382afb8feca25ad985bca1288973a9eca24172e8864b2abcb9151b028563a577ef9d53cf7f5a7d6b111412bd6b464723e9c3bc2e59eec15ffd0b5eb7b80696754f697d5ef0e6c250bbb08ff7deb39856dfeb7e481a7a51c2bee3c2aef53d245ce39d21172d6d0936f6076fe235e1cd8defeeee8df6d5dfe8db625c7e2a2d9e73378cf3b9b1270fbf7ddc9cd9f4ae5b7fdf3e13b0e0af3f6d93168376649d1fbf02f35c9800d96d9e844cde7b87dc5262c72c24aafbdefc09d9130bb26d652008e5256937b62c24aa176f621f5bd0c776651141e1925b2fcbd2dcbdaecbc2de2bccf368d4533494c3d044cf34ebafdee83757bac5b554a77ee34dd2c248278293c4aacbebba2e6c9bbfbe4d7b7d5155d7b7fa78c77cbd32b3a8522b032fd49933cbaeeb882a0f7f695beb5c6923136f92dbf578fa94cbcac06bbdfad63a5993ae8b50b46915515fb2ecc6d242a2bab555ae4fd1c774fd621f978cef2fb846a56c7fc133e2a9bb14de5c9652cafe62023500d45063bdfb55dd4d0821105d920de19ca0fcfc24c3b76d094aadebb3db34a3e3c94f0f08a6df711ff5b7756f93a16ca94f29d8ef51946b50b24fa98d3c039ee7a7f7fedee127aef13e515611d79fa557e419f3c15fd78476bb7cafb1e3a59abbad3ded96364f69f5308fe12b16ea96e90ece73ad9555bdb37cbc0c12d2469e5155761423d7909ff8f23719bed4e9ab0c4f94ddf84579fa39e37defef4d37421b79c6342bb676706e75e51b0890cb80ebb4c8c9b93936b7eadc8a91ba05bbdb2a4dc675cfe5130f92daa354422a0ff3a44cb756aadf21733c87b4b2a5ea155ea67abdce5bdf7a2bd6b9f0cc966fe5d2062d8d3301a4096ed7a195ff3c5db9efce3585bdedb6322d66335b6a8b9d5af6b273a26c891e7bc4a2b3327dafd3697339aeaad44ed465c1486f455885444d621d76d25c0ecc8370e6e2ea08960d25982eb163b343a90d256c2c6103f3a866d95882f9d948b6a1848d259ecddbb96c6309e78212ddce8d9bcb8930220d455bc2c689c634547d137a31e13c2efa862fb4f1369488dbb38194cd8d87d82314dd0b8675228b6233fb44300eba732e29f7c08f34f75234e754606822cd3914cd0a7dece6965c07e5e3355919081d7fbad1561978a91c78e797e01ad596a8c74b59c953b6c46c97e01953daedd95cf825780684f444e3188e71391386a6a16827f555279a8b715611f2c6a47ab495c4c99cf37f11908f274368517b79efbd373fedb3598287801ab486eaaa63c69899e185e4b2484c2df2138ca45b26f64bc3ecf604126624d331f313dd62c53be62835772d4dfebd62f05570c9a4e4ed7412bed142cb489a04374612cf4822c0976f51f17d6e59b6da9c4b76cbdae2c7ca2c1a4a32ca6e38aa63f4932ca2343f59eaeebab3d8af63f05ab6749d9a0065f9090b09689f885cd578a8c51810c2d09d8f318220744bf1f4f58134cfabb35be8734b93af22c300e89e3f90e6aa568920ed5611743275a94d6d0bddea52543c11dc7f8c849f58b13abbc29c3a538b43f8c89c9375260fe123131fe1217c44c431d6737933097c8475f888cc3c5acde465f62eb3bfc73a7c8412429f01c9fd755a980188b49b8e2b0fb5f8c8333339de9544c8770e6691982c22a2140fe63d8b88eb9876317f72374277e11f64cd4d47d4fbaa3c41111101e1291bd23806f4f164d6eb890fb2d23cbcef482e8cebb458c3cdad5db17504bc59b74c0babd0ab96c6a734ca5611f49174a389365b251e4513b54afc8926d2d88a003d4c8bb4ec28dae7279ae7261ae8ceb2d131a1c3f46348737385c6cb1059bf5d43cdc23c07e3676e9cecadae2d783ee29bc23361159655c73ec7b0eb309d61d9371010184d4e5044175f8472628279387461d7f99e0c7b523c299e1493a7e5116c460708f41110100602496c4405c8032b9383b42dbb333a3010f611100c34b2c204948140d64d4037b138039d848e594f9126d831cc9a3c115e9e5899be26761bc10cc86eecf9c763b70cb33e0a320a320a320a22bb90145a369bd1615d24fa645d348964f33bae1545a2ec5366d15b728a2815616589b42dbb333a325196890ef344d63d5ae9ba1361229147748fe5c13cbf2eca3c22eb338540d84766a27fa6d004fa605384817272d2cacb8591797e896c36a14c2793c9149a40d3679a98dd5ea8cb5f5ae419565529bbc5d339e374c2940b90f0e1f20caed3420d3ad4e62a7b7daa7f3e9f4ff5cfa7faa7b4e3560e7e3e55755dd54c223f339b62ad5ebdcfe792f968db435ac9fa609f4ff5d0e7a1ea0a1da631cbfac7e43af60df4ab7a8acc747d3e17945f36f4ead7517e7255199cbe5d329a5899be21bb8d6086b37b32bb615745f908cfa86c35817aa9dde0a71df5e564a54d77b7a7adf3118fa7c23cd83dec394c57fca9be65af144eef1a7af560a7af0f81348b89d48f87eb2dcb6e15d3f3113ec247f888a7631fde7bef82d2c4e4105af09649e419cfc48462138a4d2836a1d8e430cf84faa595aa4965627299fca2aeea323953186326c7ce33a35ec913c72106f1873d9c31c6159f5cafb71bf35d87401fbe2c1b6334615a85b6b9fdde7befa395765cceb24358c157d91c0539f53ecfaa2aabaaec302fa3fec9ac2ca3fec9fea1b8faf0abe715f594f8f9565596c2aa8fdd463093d9cdb215351f84675074daedd94cc2a036ec6eabab99032dcbb2ce3956b52cceb12ccbb2a6c9aaa6eb569d769379599c1b13c9344cb3a65b293ae3115166b504c37b5d4d3a51e9289da6191dce4d229452eaa615ce393ae77fcad2fe7f68c54e3c16c824bb2cfaf19c602093cca2a28732d18927f33cfbc75e009fd089282546004e3240010820630056d3ec05100000c418a5c010a19c9884401f4f865d96a2368ab2b72506ebbdf8de93efddb27bce49ca7e9772644589f608c89b2494721bbda845f958db6e4cad572debfddad7dbc29e61575b95a5941565184b25d5c9d8e4902b1fe37c71aa26a7e88c804c37cd382335aa99736e9bb555dddab4d3dd2625575e29491a4717e9faf74edb6e2949a6c72f489051107931c403849275a0942d25948f75ec1631ebd5f58fe6c91c13b12a2b33ddf8884c131fe1237c848fbc19aca118aa93e15c7c6e92da96f5ad264739237411c6cb4ff67db20bba6137ecd449e6a4ddac539b8fed198a1180ca6e2f77fb6d945025cf360fe65c7913bbb1911bb21b34c23817e7cad0419f76e301dcde39171937b9732e0438ca9d7329c061dc3917037c74e75c4807c09d7351b900b4ab68cea99034e7540ca039a752008d009a0c6d009a732a34d66af6767b11800d80dd56006063d88d34b229763b8c13bb65d26e32f186401fdbf3a2a124c36ca52c2b13af7ca5a56a29ea4dd196f897d9271b79c6cbd1baea4839c2a9463574e74eafee46b4cd0df5a699eaa9d4e254e465afaa5274aa8f8054232b4a9647a6e88c80700d792aee163aac3c9e438b3d20bb356466666666b615f4bc5b551c5951bd149d1190917cd53b8f82c05797e90ac05752db463537ba2ce6cc3291e834f2a50504692a7a0fad5292409af7f2b2b24222fd2251c35190471fa722293a232055b5c518d55c8ad1ed2585741439650c1b2ab194524a91ddfef8c44a28e508e7d6f7deabec28c808c8950c318ddea35d5bd36c538a4e671195d018d12d0e833459641195641acf4b69a594a320ef103eca51104ea9ee24f940e33215792ad3776e74725e8cace0dce91b691a05c1d145ba089592e4522c95f0744c8329f25c5e5e565648a4ffbd225de4cac72925c98d1f05e11ad528488a0e458d6a2e9552ca51109e11290c16c01ce86f301a2826d7096b17a5924a2aa9a4dba36207a554bee9bb3e293e94e2c6243f7b554aacda9275aa4abb4d333ae4e994a7534e17a573cae953b7eb74bea24c594a299595a5205ba51d51af9f522291234fa594a1cffaeba297b624dfb4d69005514aa90455b55237b75a1425a594525217a6657f9ae89386726872aacd7fb4ea308fe935a5e0cb96e4add75f405c29b8c6f478b2e702efb1f3b624e9abb4e4ab86843feb67c5d54528da89963d15eb269a7b139b8f508a7aebd53ba7fa641151d15bab9452fe52534e33577f70d059d41fb7625d31106fad9ab5a664a1d40a83a2a09cd45b2214eba2fa030546b5aab3a5faaea1ae3e205cfbe4dbfbf17edc780ba556ebd937bde94daf288e5267c16a5d1e26fbfcb81b8c1f0c639232ba07868d012346c5f5c634b2392976cb60882c4bd3b585ee81a45d920042870ff7e528e124348ce4e86c6ec7ed0c41e3c25c8065a016641e22783e63f880a8f02613a010e80f211316989c7caa38f9c4a3bc8080bc6051018145cb20d231ace8101513a572cf855ff88557483b4c8456906d2f1df8cb4530be906d6e679b2d5b63314563d144da8aa6e2c19051c6944f18b2cded4c266c5e919d9d9d1d6793813354d72d20e09a5b724dca0c10226d0c847b308d119c1b9b259d835f6c08c1a02c6c707ffa30a9f74932a4c87381e767c43c827a99b21092f38a02dc8c68ffe04351649b33f2e8f38820c988b647b819efcfbe7c608d2fa09b1797ac5578850ad214fce31a3152396803ca03a47f16869bf1a89d3da2c27d771f9d6c7337324dd818c1373733f4630a79136fe0cd0d0d7838a10d372419cc822ce00c8921babce3bdd7ec5ebcb6995b430b49b08999e11ddcac04fe64c1c60b1b0e831736d188112336e69c73259b73ce25d9e68c349c18e6b9c8bf1bf15ce2d4a47849e106373827cab83b50b58103b5d908597643348d72908958d0e366a11930b89febb4888318ee969dfd40732bd6f39660222db9a19384910a2fe0bcd8438f1d3b9c010b254062e00fee0a10ee26a2e26ea41fdcedc5077773373db89b335273210fe690e40863f0811a7e78010c7007406c01270a353c74e2202466c60a19c4600d72c8c210a2c08798feca737140164cb8828a9c1a306108317d98e7e2b2480213867421061af0200e31fd249e4b0370e690072c6001061e57c4f46f3c9713242982199450410728d82066016668c10ac0608517841c89699a1ab0a1f298020b7d40430de620071b0401ea8006150f78140951c105e6023f5c4970411772a0c8208410562c8021b0e10311f480033a08d98153bc81055317d04007287ee7c590374494ebb61892852147ac232c794ec417fc0b23a0ebb470c313575eb7c50ad0206326c0096e3e8639b8a49e89a20f3588c3139840042531dd5ce4478c3ba02e60430b824c3d842e4c95138e0061f0890f52204245c1092c48a18ae9c4c4872d64b006eaf270dfdb62055fd09b2d64a0c5c5aedb420660b8db23139c1093c7f3aafb1e1a7e6be59efddea3a6a99d13629a64047ed93a17c47b6bbf273778af708a3312018f609a3bc5799eb2ceca591096005238e9a4df22c7c8fc4967e4182b8cd2cd2b34855ae184fc4acfb175ee21a122a5749a788a16ceaef4add14fd3ca95f255ad1ee35df50d58d6bd95a90bd051d43c45e79dfb085ce8357c6fea8f60e6be379d9a93faa43ea94f869714457d4ed4e690f023988980a31cab505db760539fa51342462744844e08f89c10af9d101d3fd996e2dfe361bad497af5193324608a7e93d7e87dd7756e92398b96da72907b67b4208fbd49b7a85da564d337bf6ebdbbbccfede2fbd57e122c699e57869638c18dba955e62d6db38aa8eeb42e68bdad0850b768ada89de27c73be4f32c6279af46467154c4f359e29cd2eb5f2360601949055eeef2eda8f217bef34de9ce83451ca73b6caf44b736fabcf2c3b3569a23e69f212c6e8966a3759750b94d24ef2512b8114627ea377b3275875eca2ce3cb4e009363195b7d0831076626a7b010b3cecc4d477e30220f888a953d59a13030e919c980a6f728cc4d4a8e343484c95556bfc041688a013536790214284c4545ab5c641a6f0e326a65278d0c3196a626abd830c68626af5052700e126a65a794092b3862038e811533124b44127a6665a0cb1424e4cf564810b3631f553b5e6bcb8998226a6829c165f6c01276687b3f9820b45980d40d440c36f48034d4d4c3da95ae32d7440849d988a52b5e69a015b75793603f85554b5e6eca0879d9a980a0346ca1e84a0849a981dcc6f8b2f906c2949dc9ce634cda9e15ffca4c1c7865372dbd81c86c1e54c935d420c48e6bc1b433127cb4f0069244f0a32f01132b4ce9c93aad7ab463dad3e0b4cd32f7b91ea75bd08774bd7e3294b630ed9e888ebf157a5286de6520d87e8f69f83da4ce5ce030d29e504a6cf1731cddca76def0ddfe3cc7d7de13403998d70b4e69c73e64a6d939fe4ccb52c3ca30ff366203318a4e4ee9b514d93e4a8a649324e31c2a74c2949ea08488ace2808cf98a0803e608f2689609a373759f328c84dd60f2699baba4b5578aa82b7e0f3d139345e562aad52578081c015229c627c36a1132f25949406a9c944f808e49c0b2f2584d7263dd122eb4ffc28a1d40236dc82d4c403d224f98034493eca4ea2fae9956c244f8aa86dccfda2ad502756b0818140b7307c40ac90f5b739ab2cc2806ff0049b98429a24af9c429ac472c736032b1c3bdd542ada6d42f17c5e2bebceb998fcc2ee5c16f26837dee46c5e5e565648a45f14e5e434e6076f6c9a34591a4a3297a3c3c2c833a669c7754d3ad922eb6f2ee746073c70f5c443ce0322815427c34db74e2554f284099d9311c94af5b07aa5dea2d349ba05b6924afe5d1a914664196495a253ed280864db5e344e1b699cf6c2088744312e83d4469450a7510d16190e918c6f1612c5b80cd228c8888a0b3b67cb7a07270bdd8b6e89d148b2ce190599e01458c029eefb2848fdd64fe1ad73ee1b05494972273bc99caa868a846d86847aca66b148b68944a225504de8609ac82df154f6f7eecea8e9188b2615b1e1226cd32d946d4e90c09f70daf8848cde15814bc838068cd38a1bb94811510c1263d1840e915bc233a285d0081769e281de3645951136f2399f8b3cebe122f7c5ccf29b78d9465a42e592385d5a6861861e1701b7623b3144acd396641bcab22454d5215b4a9b4dc88cb879cf72f78aac240fef46ba150908ea43740b5579c0e9e0a828bee421314417c5385320090dd850e2c69350272718418124346043891b57647c8da040121ab0a1c40dd2151941011b3148403c7743e2233ce4c8345d73e2234ca4d6a16e40dc6a52cc7242f0090f323e5b19275d46b790ba25f2890fea542dc39f40218b775d9dd4647cdf7b7ffc77f73ec4fbdf65bc9055ada4ec66f654445374d2da39391bda11093f587eb0fc60f9c192fd6081d60f4a29b590702b8ee507d532c7f2c3ad38961f593896898bba0d7199c66516c9c233e02bbe86442864a2e2d5f4147ca75d99f6fdb83c979fd8677dcfe9a39068cec3d0685c886252cd53ebf3232d0586283bc9e2c287404d1dfc74ab2dd17a59c712cf52ab65b12cb52508a939f9d637ba0846ca484bd1606432226522f8dca3bb65dcd8dda218f7bdf7bae70f961f2c3f587eb0fc6031695018429f8f941f2ba5b41b12d30eac91b2a1e828a69dd0a5168a62da9976604d4781c1f816822de4ce77145d73e79d9bd36e32b0c77bc6ce06c87e3c8f6e240cb66082348f0fbd6452d2504c3b4d82dbb46355d5b403806f5900be4d013cda8dfa27c6e33633d03d02b0ae55b2bf56e918768e2c8c771a31bb85328c3ee512dd3997d14f465a8ae61c0ccd39156a1d907b75cdbd6e62b7ac85dc4b64e35d6d431fd1bdac876828c940f29ecb5eff7c3cf71105d7b82edb51cc40bb73a3e019f1991619098470aebcf08c2078b9a568b32a605437a25ba205e214689715d22f12c5ea155622238ad0b8c7c76e248f15b1c52eadded2a8b3cdebaaaad8f5155fe306c4b672e38b6dd3366dd336f3d166a20e35e93d74abb6b91baa19b96feedc28764e1a060ce0a4653370c22e5dce74cc22e1727c480d2ae16e748b3ccc8e69999439ef6e9a7ea35ba08f2b35c7d3b4d24b4cb6d25f58ad3393929d243ad38d0eae11a8a42d98643dc9d4880000800001011315000030100c07c482e18838d2242da40f1480108ca24c6e5219e86192e49032c6184200c00000008000a0499800d2c3730312345a41b15206bdacb84e2b1f029f9d8e502d16e8f9e56813233a05d7e6f9c8d82ba6c3e017cb304a39141e336b391e3ddd9753d16ac99b135d53d35460e5c9d4d87b49be59f3cf10ed73be8c02e28ca0009158e6ca59f306c35e552500df3a93e1c977f46aa097b1a5348ae8a5e15e4a59949d7195efba0dd2cb502fe35239603ae269b8975ed2594ab2ef2d008884cd6708c21b7349537e83bd1c95ea4ef8508c587121c40d06bda614777b35ece57c29eb573b2c5e39897c65f0be5698e40cf11f4ba729757a4f707b57fe60cc5f42ac8155b70a1bcd4f752e784364612e9dbd2ee8d85b85346723e0c502221ecd1a6545dcc4740916040c75e432cc1fa2a228b470daca363049e2b5eda6fe879a78d3d6a3fbc1f772b2e3fb96440008a3a1e05798919dfc836ec0dbf9099c5f7304ccd142332e09710fbe421ee299b6b2a787e60fe0b62745cd66ded1553cf41f83ead56b0085dc86fccbe95a63f976d03e45f5507290051ea7a0d17d6f510b7137c179850bcf9744392e16f609f4f113e7141b2825be0f6e829c0e67d2815a1fb71f4c3ee57ef1363fec21af9ee9d7a7b6d93a30e144dd6a10435c921a13e479a70816f50b96d948fbfdd0cad29629c63fbb808a064ddbdf5f285252857c0103cf4bee02e3e05b67950c87a2b964cfebb9679fe16ae67807ac185d35eb265023b73ee520530cd95a3631b4bd85714d8561ca9b12607418649635443037306056badf3fc80a1d5e3c3c0078ba0e3d15fd830d039a2fcbbf9e7d065dc1c5f025fbb4045110b3b2e64faf077a995daa30a2f52860410493caf1dcf1a4b24c0f2fd148402567e9d823f9f392cb5db961b7ba388d1db9ca20289d2acb5e88b4ca0a881d2991ae4af7049156f359edf613591c5a28c7bec4d3b288a4d61a952cf63fda3c8104abe4893c2ceb4fc686df7cb84eca5422aee0c8fa1c05d50f2fceab26e40f8b6377951a2cb9e685760ffde5b4acf2fe30e3b506f89273b1dfdb8b2cfc03ce8bca3411943aba21d2045e22d41b7e5aa0722241431ca49a19f0a838fe78f4e4f0bf36fcacb4c416a46d7dfde6f65da9eeda75dceb65207ac21f8f8bfa61fe3b77e0a7493eb84190b88db1c52d340a04e0e25ac283a97f2c1b7da38d628323c35b96800c3baebe1380615ee94a0fc25f33e4b11332a53a01cb821c571da192c18775f599c7ac55dc161352378efe0869e2e10cffa43352cd755a583d4dd4188519a1f0495b647eed4bc186d94c371dfa188a1eb1a270d48c9c74efb4d43c21abfd81c3e981af146730ad2f8cb3bed16782e0f6608bc291bf6e8a58f35953fff4a149032b1aabd3688b405e0e5c3fa4bf3eb96b82f11fdef11189bc4e1331c4feef2b1ef1f467307b6fe095ae9b2755e5699579148032accc1eace3054df08fb56ec6b645ca7969382e45667f8d4372954896f0597ea72e32fe50145e8e18510798543664576976520555ccf44354df9154622a337427fa80c5e87a45350a18341ab2c459d9ddc171639e7d8f68c5d270a4a383210ea2eba3920708022f04a45507e3ce61341110aa9f30bb3707b0574b77bd27ac4c45ebd2c8b61a3a38b619e9b341faf3aaf399c3a9f212d899f9b7e2f534d9add4469b2d4397f9fcc2df99f8d799f5fac7bf69492a66143b80fb9616bd314cba11f48afed0edba3232e68e8d2654e0df4516a7563708b9ebbd10d82c95c8c6fb9498461f3d2788b6c8ad74f0991dece840e90c8ca46a2b7ff8d68d1d677ba7b2a66d72254b86cb1a32085e0569978c770c00683ea85c39c16c55ee0a3515d9205d1235f2e3ba75020a4da072d90618259b4d7a1e890e422efb3347f49c5e8e8239361b2477cd28fdb5f587d166b5266edd8212a32799f223b098268f14b9b7200cb1a85daa48ac8a3a71b9a75bcdd01f440feb3e3782f5ce66033418ff16bac6d312e97451f4747c996334c916b367156090431c4b8c2b2fb195f87f1e6cdc62e9c61122cecea36d525a24918ca0b7343756ba003ed99fafb9fe3cbefef7e92577c8e7a8c85d4733942deaee85588154a31fab1ab585f3c21115af0370eccc6c6fc6e146ebfb2b1f9a5e4737741cf39488af3744a43f4195bd5f81751919f4f66e505253d3e04db13c7ff0d63c163f94ba0517bbb3e38763a508fb4cadb14016e28a617072b3ae29b6a9bccb0f60f24370d93b3a0b6ee37ccbc89e3cafe9d451b4c7e7605930f74fbadc11f612e7d37f5a0db49dce6412738859d31f05f8209661263e7e54025df2030ecee406a058066334f82125c5802d9205d7354af750c9c109bfa4dc64e19751268b37bf527bc1906bfe9bc3d06bf3d8b14bf785554b3e46d68062de684c403f4adb71fe0bd69a27507af91a600a1ec38dccfae80295a8f3bfe4f707e300e7885c37ece307b775ce7f38d6a42e998411f4422ab2b2bd8c39ea86368432b41ef1e6c3b0aa2a6442b76a8afea7ff39ec1c3cb3f81e24c3ee05b46c55850828a1a8e269139d5fcf2d0ee87eadb8cbcaa3e9c67218c33bd048a66c2a3cb318ad97befab4cc05f10ee07f709c54c9f8782aafe31c65ebc5e590c4437cedec9a31d59afcec40f02ccd9f9e29125d747ed2cb669d3d5ba2414e19583b4854aaed797e51e6a543ab7fc63cb80897c30c4961ff42ca5df99d769fb69106937cf32018654bb3d24a3a8e2671fa130fa8d3ea44ee706f2f85d1319f93a5f075510c5d11793b9c88596802c48532cccc51abc5db62f942d97a18f20428fb7dd7fc9b44f85f3e026beae560246c11571579f0cb7da5dece975c8bd20fba98bd6cea45ab3e31a6abf5fd59a4f3fbae4108c0720d99b3e6b399e42d3ac95e2e52eff661b8905a17c150ba6e1f359edc0b2b2ef6e98ce0b7808329e33797f4562ba2cb85f3424afa7a1be43903d96a54700df5880870ccd76b970c9b06ae137ad74e4156fd40b53aae42cf87e9b7b1365d510b5a0b735d151e08ec28ab9c30378235f119eb2437b09e932d4e016ab76908d933da0aec442c204e436a8d48ff3521fa9a2bf3021ca717e0b019ec7fad46b3207bffa64cee6d83064633ebd431ab94adf8b14717dc2086faaf831bb0e6f25c05c811e53d1087f85c97bf250422572a9efe9fae2a2af9b709db20eec9f498f344422a77bb7f2fd0595e966f64609892e1880d675f0a0ba59006d55eb64600bdae4e503ae2a45ca9a196806256def0213130050c4d15e5a8823b9b5bc4509cef0f39c2e74cdfb5a953038f3bff437e456f8119ac619d45af52abfd48fbfc27497c1c2d73feb9c7edba0173ab8e2b47cd9665cda557b0dfacebbc4ea7032f2bf57f69694c91d64d787dfd0991956ee2be1a645e5f0b4b30148b3b01bc406b8551784a18c2efb3dc86af943fa3b40f78e046a6cecf5e0355a4ebfb90fa7b14244316d28f43c3b3ba143123281a61f822a484f79769dcbd1bd6c76e1ac8f4b5d8e2d439528d707f395c1ecc1a7715a6b431a0f6fd89b8aa0285801ac875a99989f3e2e7630c6914e8b082b4233a3636039949dc5c6cb574d3c5847f4590c821897d207a116f7e4f5c14846aa8ff8f186e47bd9a49c3d44c43515eb3f34ddbfa99bf462ed95f17a3496673bd525367fa8b70bf479ebe4b8847c4af3c799001a4304c0eb826607120e46d61bc52f1275161e2cc84fe91f48bb50ee3dee807373d20fa3a6c5a5a4b755fcf8f031d34c5af19905c962426b0f99072ac3fcaffd9b390335e242adac4fe9f60981daa5f3921fb0c8761169d05782e3343b4ab290f4289ea918a6f512f9b020e804f3a64b13b4c64db384924f591d52b773d28ac046a4b81df9d24d3ca3a23cb7499db77b4e339174cbfc628b6b46ece7eda2b026adaae926031f03d30dd64b475fa820c29cebf8f4c75bb0d94a73b0c96f8c40d15247f7491a7be9162c0aade681b0f2675951e43f1e496cca6e8ce236e1eeb535a58fc1075a399e692e36eea60eed8880765871c2b78697a233f7aa17a975df36dcb7c5bab1e905893c32a41dad72b8f09152d65e20bab56584448164c2478015161904c0191d7cced300c98b438b6f5c857c2207e066a3f5fc04fa07aff49c18e77e59248211845faaccea9263f58edfefaa4b511f98d2ac3e502315d39d0d6d67f72ccbca371c88e5f429ca63ec39548e20325d98951df6eae992fa9adc8037347c20c2aecf5dfd0f06a1f653a3fa82e318e7760eef521a67816050212cc15852623b4964d531e1318c4d4411d2468aedea76da63ed7f4a1f7dcd03028917654f9edc46e39a778ebae52991488043cfff9b716e5ae7b0a0218a41fc1d4329bc5f32af06dd2ce15ec3f1c3e6f541139986693891042874d6ad25bf9525e41d2273b1006e84514238141b1074775a74b98abdc71490c0c96f0ce7e8a938a355502dc7c29f206ee7461b7c847a87e4b5b77d77d88d1e0828f312522104725f0f311b662f0c176668966fd7c82d3ac63cb53f82902e16d3a3195e8fe41337e651e58b285ba66ad358dc4ed77a68e2ce34a06b09875abb4be97c3ef01b0e5536b8648f90d6d0081614c4328a988772313eb8ff5612170f15480b0fd826f0723aa141902173dde1128721aa7cf33453a5cfbc6ed941cd8f0b5c5d7410d76ee17a8d5112bd03bef2bb716f59bf27374d171192df29fdc65ae70874c5df4adeb7fa87f625f569c996b84e04faee6c017b8e0d927b7bf127c728aa2a6060755cb5d0e930e4350dc0fc21408da19b7130075f2a5419b86dcebdd1b1382d89b4a943bd46f0640e8d17ab7d0168b277a3d3aaa453fc3aa47c7e31a92de240718a50670e3fb01824386c019a4a04684f448b01de0901da054a557027f3851d17924a53b73edc52ad55493505e017320f83e6e57eb514b2a72cdf470d0e8ee173875194acd0ed91d65770e2172c6312a4cd7d15b20a3eab600bd928077d55aaf086caca49a0dd68a6d5b2d564aa0c38dbdb28815c3402e313f96ac8f40316b28e9d428aad7c7e44807800269b2435f3da5ec446610ae5eb39051838018fb9a7e8ec0a74bb6381171fd99de482c8e8bb5e3edb65d8f157c01e2f2965cd70c164611664a6d01d43afd9b4a1b5469c90645ea739e132281ceb3308508b039ed6e2db4f9e7e97bbd36599010c313f36c18a1bd3518489fe8ae1e28b16e980a8f786260ea37dc95c889fb59f58230482a16d738cd50b009efe79ab0b5fc2212502000e8bad67b3fcdd3926a04ada27444ae69dbc4debeff9758405f25504dc685f2a69b28b6e0050b62e6667c0c114a18acd5e0d830f3493f35ea05fccb27b7cd8332be79d87868df6fe6d6ac5f255f3a69107ccb28143ec2f2213025fb087a74412df4024e4c2fe0901f01148d6d84d96a9d4b03fd8654db33bdb15d77236ebd135b254aa86f529fc3372977d447afaf24377da1134b8a58d8a6a52c69b20f7c2c2182fba4414587e05a7cd21cd26518a018a9f7ea2a78d789abdad06c7b9bcb2a845863b23bf39b82d4ffaf616022fc3ed961f46d62ff0a575f32a915ed9f7705c22b5227ced444d5d1758c7c52f870cb6e65dee78d959aa5aa40d87bb33abf9cbdf601aad9a8336b7e922e0c3dfad325ce257842ccba8f26dab31312ea462abb91594b73595ca7bca129d9958710a7ac3f3fd121a9cb53f69c913c4876fb3f2fe92f17addbe494252198f2fdf09767feb85353ebccb79f67ad39910fc6fbe93e0c7cb73ee5500a3c81db5f208430f95512820f053ac814f2cab2cf7aae262a89db970da58d807d0d5cf5a287cabc1d4b7f3769383c4cddb6a314b69ecc2be9f35d7d305a4bd94b887dfdd121abaa897616f7e5a537461ef11b979c2823349b10db0361c86c0d0ac92ea4489b2ccc7c1522dd42463179151fbeb184ad8263283acebecc87c8f58833c1ede47913be93583a57755fd16edc611a4075f16d029b7af9e4af2550022b33236145d0ecd5aaddd409a5097626aad88a2133bf1f3ef6272979fda28c3ceb9a14919e78d9028b79e444bf07b3f615309a7d4cac2406ca7daacb996461a54f06f959d153cc60c25e46d3d09170276baf4b39d37d9a18f092b8c1ab2f99cfe9dae28c4534d36eb1b953354bc992ef2c4b501ad0512c372a0b89d3382340043118f43e502913c247a3cf02982b2ad82d1876d31edcd3fa09f9905b283119a088f0ac4ba4a5b5fe53bfefc108693d132be8234385feebff6ed6bda88ef6d1a4a4710fb9a6798240d3e33f1b385c20a221ecd9edae3e407547d2181987e22587dc4e1f6a8a4d7cef68dcaf04b0b697fd8a1068bbe667c56d10e9141ee5974215e6a08c1083546377ba5f7228f6b5121e54b7862f9af677897cd92ba8de74677a39f26b6cc83a8479e39f644258a1f808fb8ba7aad54dc90eeaaf9cc9213cd13a6c09f443e83c19bc43e82c197443e83c191c331d30524d2bf03efb7937f4afea8216701096a422c5f4cd105e286bf982bfaf0a454f1755f80653392c82371c7ba7c163418f4616ca4fd7c8d2b5e0b8d5cfab4e83d27389b3651acb6766d21b20530166f91033bf316e71779152568b555c6c4a4d0a6aa75c9cd7dcc8bde3a8c09949d0b95c2849b6c13ed9a560c7f62e04456389952d5576bd5e11ed6609a8bd8f3ebf647e19f1fce29182be444f0dec69fcfa249a98338194d9f2d5f14aa70d6df21b9d74d01a3b1e11c71368282949ac53352cd82d2a43dd679e8694edd19b5b1b77940b9c9d0bb321b8ecc01a3768b365d814848465def84783350d6ec3a1073279a687e3a01a63e6933206489a3bfb9ec7326d28dbe684ada197e82d452a984ae58ca7eae62510f0508735743adafe18d4077144cfd6957f9176ff49d8023fcdfc2b28b14cede2c456cb06787f55ec16d74c3876cac91c13bab853545e13781d1fa4130e689905739b0becc649365f083e5cbe9bd255bc3ed4b005b17ff569d6ba7dada8bd8cc6ba005737e80f5df14c4a282d7757648a3b07e40af85c732cf4b3ab5b4a2ee2d5c46c74e06bddb50dfcf5be7de0133dc7e565b21d68e8e23560f59ceed05acec5735a5950adc4ecdfabb0b2b1d1f468aed0427ce672d3e0a5c6ae31c1329ca09e4e4e6b0c50ca2135a1f30e2d5083b96c20d74d77755e20cdb04b62fdc48ae20cd2bf7307ed21f7bdf0e9602ded2cc6899dcf376b526c40e159f60ad2109f435256876f564766bb38ac6dc0446e6fc5cf83e2ff6918286461c95aa67e7dabf5ba979ddfd96338af4e739c29a2be051a7b05991e25049c9c7d155318e9c421fcec1fac42d5f971767e8f6cc39fcbe5b00620136ef80f94511af7751eb228d2e00202856f4d2913df71c2abf2b02cbabaebbe4108a4da91f1ac506d9728768ff47c0a59a735c1afab2b85b4d6ffeb4d96eb6de8349c4848a83ee7a0eeda83c12f9a0e51a6d5955295552e0688c3e5655502162c54bcb685f156777a7f095f5b0ed9a5aba2e4966ec49b6ed9329c7dd1bd33adefc20ebb6d174d9ed86126aca5162e8861ea7f21b43a53cd64c12935286c1a6d3a0edf584b278e91165c2af27c4d5cfe13247cef088fa19ebb9b50ed04c225fddc2bafa4012e7a1e30530cd95ca51d52f6513d54ee1838a5069839b2625d84043f5649f3a6af7d8def5442e3f22a6f41c1d776ce8f259e206ae69d5327c537abd30eb971eb7479f3e754f42b0b31c2710e382856b6af1c9987e3caa24a75a08d8af8799ad2882e0931abde72cd90bf8f0d4eddb138e6ca4c0de55121e1da4eae8bb616ae1ad94dc3a00de1989e995d837d5d67b839b6a0bc13384460bd7c06b0a3eaa00030fa81d8d27b4d2b617068aa1291a557f7750b6e626459caec50c25ba8b9c96f5beecc4a30bd570029621e0bb26f52245b513efc320b1ede1ac634f2ae668b9a175cde54ebbe1209ddffe70ff52d1f9cb14290b645f21799ade1c7a018eebf2e330562a6726949a215d2a532bbf5b918b52ab648cce52337f403998e82438cd2040e92dc85f363d977e8dcf2c958b263bee7dd0fe6b3cd9728c423e79388aa498be4665a7256f2bb8323143ff55532a6e9073900daea1255a6ec75a12a3a072d8bb05b311dfccb10859eda8be5868e18340c3c3846dc6cce73215a131b95602d3c3a1a7fcdd0d9129a8a396657908bff311b4d940e36e603b18eae4733e61430aff35ce431e5000456d0da32073dbd3a5c5b9a402b9a515d99291b1843edc6cc49c9e8e6cd232b8242361dd65002f0941254297863bd19a8cf32e2035559444a3dd0838f8c6585f31eb0f67fd5cc9c0f7bdc0f264bda06ffa52e00c5345309fbc5065e26b3fe190a74f106886807dca3963c0d84da793e31d630c16cdbf49b53495f996dd68e5e5d11f2027b73ae3dc8cdd33b191786b9dd4b84e4471eb4fcae60b347a0ad9ff1ba45e3e02ba8301a445724e772d51e7d5459d2538650ae414561f0a6d1f8e5eaf03ef2bad5ab0d8566e45287f81fcd9fc78c065a27a8a05000224e2dea7515e42cd053402c2fa2ed74762cc48e02b2568f24ac15ab297f4a0f5fbb2580507678b903f571e2315b450626fe4f28795c2143739e7c61a54cdc714a9a82d5f4187ff3154612a522ca7bbcd2649d92723d1141d2ab115ea2f4492ac6210e05100d510c05a18507f983ffa91c8bbd63e898d70e87d5f7f97f90c44a345339f319d56df9611eb4e7e915c893a88af4295817fe6db3c8d33f4c327dacc2c08b8ec1b9cbd3c8ed079cf6388aa815d269dc144770194a4ac0f91a2eeb59ae1caad7033151ce527bc4ac6a28834283ed82dd8fcbcc656121bbcb6e1b5aeb92188ca9adb400ca769b23485c65545ed95a55bb81561d316c1eb9f6cc5315e935defe7ae12dc33fa1495d6c01cd52bfd77c78fc681b67613be429ce6d53116922bc3d0234328b792563a74b2a614fb2421f43f3c5ffa356963199ef295415cbdf9a2811d60e93c105ed23dd070420e4b6e667409a3184532b622d27ac28498080e418835a30b5479b8fb0de499b1fc80e3f42e4b54d0bf3fd1851ec1fe92ead42d50c6ab54e781de310568ed41399df2d478643c5aa11249371596d77a86b31124ac6c944dd0a9145cd2b67ec0cfdf8e3b69a7bfdcc66512ddb7e657df1683888331d44e65ab17fddafaf5cfbb3e0362cce8bc66dfbcab67eba0536e88d5a0abdb266d2347b029cfc273afb498cf8954bd3f210acbedaf9a21ebdf72103b52a7b7102504d52dd0d20cf7944082bca52a74ff4b55907c48927b79e1e5f38d70b9de48bf0181ec28ac1b95139a3cd13dc57faaacd3c18eb45598612ae8e36153699b1b528ac8c5665b3e397c84137afbf5b479dc22d6ae84770f1b67c6c3262596178cb709cc26667f1d2caac1608772b6930cd23c3e800e084f019ddbb0d8de12532b1bc08406077a32bc451f22406e59fb055cf7dc0a16861d9dc680db19d93ac1ac0d1c74272821a1a6a53cad80c6c8e223f45b2f1e09ea79bc24b2ba4b56c8a7ea8213e341884445b15c6bfcf7e8166684a94f80b0ebdb59dae8faa5222aa6812877da3c7f4790375901c5ed0d1b152f42422e581ee58ca20c0ffddcb60c7b3795d5c989e6c647983237cddfca4fbd6f5c94fe79ac2633d15c057018713766cc4e3dc64048fe79894a30b3c0221f92d95477994c32ab724a9e1c66fa68e73433a2a89e1d08c712d56da68ff1512b5e5a36dd0c2414dbb39750751c7ab3b59902dfdde7664544d0fdb8d02d002d4917b4c39a0ff0301b600f2e0d501ec6111a7be9a7ec61bfbd5af0b8a9e9e28ac8c3d508d174a21b74f80f24708a9ce52aa104caa2e4fa38827c09908589d607e2928d8716b9675f6ff2efa00eeb1ce04719a4e7d834dd37edc8709f84aecdfe374250a82d3b488273a633f390a38a0c51f1e7d5d515b04d8095d866b8ef06e96691cd690a6825ae92dcfdda05cd5354d49f2a01c6ea20e0f28dd50b4c118fb1cf2957e00608d7ea0839ba8c27fef304fb29f36ca40695c98defae48e8ae7467566a2233fab24ad5df834bae363d6bce1b4639b3abe7e984a9a687dcc63a7987ac4d0506a516f41b2cd84bbe7c66d942f650e936242f191d79ba72cab6c7e970524c73d63ee116fad4d8b1f8658c3c48871bbbaec31d1e4059be678d3f4c8b40ef9d0e3e17776068636b7a39dbec899ced2a8773a28e91210b236b4f2be6c5368a730c016eb8cf649561b694aa72bf5f58ae1c63c798027938e3dab525819e7f44c609e1c5fe0a32f6069ce9982c973e5224f921f25388760d4ca0d8ce0386266351ca0e3c4222db7e72ea55638ad22c74a57d53ce6ba3a5f5e1a46005932785d0851ea1a6f1e537d145eaa609d0ca03530981532fd0a04a6b4309b85281156c6e700e536682fb7daa26e40533394de5fb501527aa918671ce1e3a1227b975064bf41ee59a31bcdbc37082012d470e5ebf79d9586f6a2274acf5bf8b24ce15e78395740a66f87024500d82048beeb7e720f354cbcf8941be0cc2c609d510e0ad3157120ca590ebaa437218e8dc088c4a431911caf014226ed4ee2ae1836329a9c0905cf736a96e72532009a9e612dea2f3a501a9c2064d6e1ed02464a7382bea98ad208a8193a2360aa30fadb820fc416fcff7f4782dca64ce1ea177968d1c20d0276ee573dd98f8e2528b313efb26a0c05f7df49b4229ce9dca97766166abbc567ca1ff8c73a75c54dcc3f231ca8eb99049fedb3a21a9d00ca4dc0fac401105520cf6c3364a5e223e46f7343e8e27f8f8016607185a54d8e957af3a3732c018026fb0522dbd01913cef0f0c9cd6e0a53fb63e2417420d97210f664d205e212860b38e7c8d58a8bda31226d781812307822ed8546bdb7870333d9c2383a7d624b704f3ebac798e364dd5cfed960d770fd34088628fef15362ed32bfe6dbf53d62052300c9ab35b1d73fd6aa19888d212f6aa1012eef5624e31c69c387c6be3154fe218c5903586961eeaa296f170b295e23317a1503d4adfcf20348f2317c32469765476976644e05e2a9b63be363aeda872c73205c90b7a8d312dd8fa2439ad0c4c04c77239dfbbb5fa6f311327c6d241dbbd428bc707c72e41f77ad2907c2351fd02f47029f6eba31e737d182f8f46fee73aa2f7db0e6d130745d3dcc2576e6c8bd9c37eff853a285e36d41ec7dc7f7964311f80cebcb5266db0a48a9bf2e7632aecdc86e6a04124e890d03647c9b029fb3cf4a5fcffd2e4fd379a34bcc5e2cc52f392ea8a7620acd8f4c548ed52e5d9bbf4ab4794117c60c38a30022fe932861f62a3cc432d0cea07f8c5e2524a84d37a232e870a81cc3522f29df0b94de6c83547a34f7182069419fcc6e8c5b0718dba8d8e1eecba729f4b29b58d198854d8db401cfea8905fb30883efab5863cd17430d61c3807cf4e03cd75f5cc39705436e1139a0509401349ef7e2a3560a585d8e0fde8733fc16dd98163e834cf2b4e34f151dad2f09e25fcff4439469ae678e730f2c6402762e4d184804b07c88d7df017e47957423064aef54ce6a30d2577917cca79c116997f237c82e34c1c91f152cb25e6cd8dc38fed27922ef985ac604065c5ae5bd2dbbb0513ae2b6c80f001d71ab882d24e294f55abd4b4c4fd31c8960b97cf4226d1531baa897cc01584aabbb7a85c5ec55703922db3fdd7f5dae9480501d8b66ddf6c81bb8e81be69387c1c85d61221685b82db91822d8e8532b2c77bb4bad02760bca09a9ea341e8699b22c8d1986bf1813ee90c1029613c5bc3462e42a47102a7ebe14f4100c7815f4aa70290e683a88d9f4c1040ce706487ffdfa86210373d926256ccb3cc506d44b9bfaf77d0a81ec20f87c744691588ee7ef1c42f3bd44c755d4661369b6c45f7c2cf8812bca8e69aa0d7d3f817efe793e07bf904109af190f093bfffeaba66b6f0f3b51867ed1af86f649b7eec5fd7861e1acb9660b422d91bdad796afeb441837f9d7182c8b670c4b546031591220706ca905003592156d8afa63f8c1dc1fac676ba257bd55bd3212643bb95a1162f9143c9c436be3701ab6d8bc496e0fbb9dc94828c5885e8d045aeb3884cd08a1ef822224387d02a8960d33eb872668ff53e340d99ba243ebf8db5726dfa52f3b9521d1451daeaa2cef858c1a27b5c092c2f22ef74091d58ec1ffa1968b316d5b597cf909e5a5c9b1d9eab2aaae491ad87cbeabbabe42eeaef7a48a3762abe8f13d63867405ae6ff25d6f6ef0dd729be01391a8b52f16cdacd4a5d24e9f798a5db48eae76435583b5d7e44bee70b68eaa78631fb0cdf66e21e510721bf7918d8b85c944c4746b6b4688cda0da913201f1302df90623809ec4d2e64fd50d71124f4a04e420da47b44a02ed2e1d723c0f9c7a960426cbe15662b15219f88ef463b5359f0394580d1ad666442bcc4c69d3fad2939eae3bd6ec245157118d53c6c845caac80d328412355e1c33bb8f66e4b7dfb549773cb76a260f36505222af4d58cb58b3ac47295096a29d644526b538c819a148cf6464c5d3d54e2209e5b4b688f62a8fb3a0b3922e1d3b945a5eedb3369d76d731f536107d0402f9d5f60d11ae067bd0a6df04ed9f8f8d216cd290a7b23f43e2d6524f4d17e94f7bedf803c2497fa202ddfd76b2271e9ef3b791ba4a014330465f6d9be68b70560a3c4a5c7a19d45f8c2782d61a5cdfd738eb4fa202ef37737d0c1ec1ac51afbe203940c978aba6dec1832918074ac7289bec5573ab937697f42af6cf25065fc532d983f61034dcdc45b5543cf1345f472090e212ba49f2e82ffc54f442d2629f02eef88b44c48bf18702dd69fbc61621fea404615f888584f6f007afda443d564245029d55c8ec31f9409fad5a27c2c54e8666bf571209f3f532becabe16b7ca0fb34f48ef9c36ab7d5ca3a1ef4eb5abdbf41da1351d1b39b7d3f16807995a501eda3bf6b110a5bec5739615df0078663d3e53a73efec50a1519f015b315be005f9ae2474be305a4bb1d2eef89c83c4280d5b7aa87eff4c36459684c37a1bd4a66659a5da343dd9cd9dda9507b917c3b11ed9c4411d299675e9b27134570a92b9b68ebac8c3fa0f8f166dc68193da21f3780464fd6267b634982ca6da1513fe03021b4c6eb1237235489af974a600430d3706a45c3b0e34199961d209e5442c85ac62802b516d9734571ac34c5d6afc40db8a7b88f156c329647d4d0ea01ad1d4b166cdbc04fb8de59e43e4f25577c05b6fbd28cefcaef16dab5645fe08ac572f7068ad2359fc9c3bb51886b640782344e7921bad8f9922001cf0a751fe15f7caa441948b870e2ce9fd6d6c803ff7892bffabb0c0f48854287916cbb0ae71890aceb0d73cf0b1a03af6ce96363e9ec46959a53869cb954d2fc5d068a90359cfd7fdc86c278b1d574657e0ca4685661fa81d58744301358e60c3a228626c4ac8894569892d2a8f1c71cde57a94b2a8a88cb9a2c06822539e1aad35d062096f816e3384b92b5f5433af902a2bfd7f97b02c7733c8f8f8af1e5f8d773326fc20d775ce34e9047c4915a725607157aff08f514d1184ce6928abb6b0d39fb6b569d1391fb68c83ecab34a7ebb76438db59d2ff6e567a48af888f60c27b70c4067b20f75bc7a07b5cbd1655a768de92ee5b2f5476bdd815a9736158c7c757bf4618d1d18d2efc32fda7f3d083354ccef84b7a4d1c457e9c5e9ff01fc0c2e7cab690277c5cc5e72d4ba03bae321472a89d2c54ae3cda7195a51b6168718c23ee689d4cef1d765eae266bf5426386a6af8486e9ed0b79bd66577de2b69bcf3a6b7ba12fd672773a6b6986d7fed0724e3862ce34c2ff2239903a2498ebe2e652b172a2e8a6314608ab7d5ea9137fa3223efbe7c04a4f23f0cd36a6f0529952c25951c458a83ba0b9de9f4b178258286bca029108e013362bf2312ecaa5b12a5a5c3b6a1f1f774d3dd4e54072f2f65d0e5945ff792e05173e191624b230da7a20aaaa514f8e0df5c213766980d38ed5102568916a877417dd5041c950fc5c88ee898473a10a0a342f74fa4e832326caa2a8f16a200dabd671098a36a9091d5f269ea23c23cd26702cfeab76dd86335730682f54d146dfde1c2ae92cd4863e4301edc51afa9e8d7190e5fbca1580053e714542b7248f632153d4954d3aa1c597c923b4252aa841bc45d124dc4c8d54bb48e89f3d48c649d31a1a988146fa72f4cbd7253f081336d624b14fc2b62b9cde8696bf36d480e1cf62a30424946c06aa51d93d0953aaaf543db15766020e4888014e6aed9eb87084cf80596cd3aeaaa910baf60ff55cb086c1a1a5ee91961627cc45889c3990fa842c6c08c76dcb2b9115bf0dd4c34f420ef6d927f971df43817d7dfaa2a75679756ab9a990e22f7054d1915b6ace483c12ae09b4e09964cb7724e92c928c988ceb063b1c6da6ca599e3aa1c064a6f00d6c3f39d6837e5b787400ed8fae4067552115681e3ed505d4c7fec01b0cc4aac186c962d010ba1a5c972e7c57430a228a4487497f6759152bcac87570e4644657bb559898d272fb04c9cd314c8700ad6c4917290cb58d34ba989896b5164291dba324f5af2339d7d9b825f4748446e6680f0db4e3a7d83f3175ee6a077c94801272c3452e7c679b2bc9e28a87560ed884f349675409aec70d5c53fec3f980bba6dc8e681d8d05b8c42ccae51a204e7b7cd8cf38542abe43fcd733cbc172a0473edf11aebf7be106b8c0f9e5bf52f14ff80f83a164a677c2cfb016ac30ae28eb4fc8a7a5b2401a50ac882b223f300e0b22f5fed4d99b887805e581814265d7e730bf1e57f41d3865bf842b4ae80632e004b1b8a21bde42c776efe64be3ac68d5aa043283e1390b21aa759d57d89e817e7454f95ed76bebbad9426114963eb162c92344b3041bf729bdbdcacac07e714d16b775d8839cb432bd9541e6873ee7236e47ee27bf6dd0c43cd01b40703b0b03bb243323aa34df40d213a0c3fa8caf5fbb6d3d04bec6e5ed2f1b2754e5be961b5e98c658fdea053561f7358a5367fc9f73f93161d0d49807b20100dca7da6ddde64a9e0f15e92b523f687a8745b8f11ece51d37dbd11a094008ef235c8326c7bf09e262759ce755f7936878ed6b82fa57367a53e243977509a0602b59b14786bd0f2ee2b1c909cd7bbf1f597e9fd55a8d5b6d87f07b8602006c55dc2cb3c3c03c1ada255117dadf5064f43401ece3c8c2eb69684aaf34914793ee5dbe7bf3a5875349daa6264b55f9e3f88ccfe567b68d3220942e3e3d54327fbc9329de1bde43c4f4fda2f5045f51ae7528ea79fc7be871c32a01da368e929bf31b7756ca174b7203fffbdc1cc0fa5eb7ff71f066530c5b8154af1960e66db0514d0cc0734bc5e7ff0d94ce19b97f4441d793e9eb496f480c4b29d7d2e4efb862c5ef4d877e6795e77cc39e6314a42e160ef51d3f16e90f75a9648c8a4e075135e78eb9de38db2fbff5cd203ffd4ae2304fd3777117fd4154d618579dfd2955f5c88beae3f5c26b892f6bdfd811c974c7210b4dc83260a5d4fea4566b5d6371b1fc2fea5a15c801a16fdf275e17014ba65113c77d79f7ca0ec170507da136006220a24dbc23949bd644c8a1b7d26fd40c507a0a328d8454b55596046ed3305bfc22f81ed4bc3cd88fe8b0c00265f7d2d83979bba4f33be987f2af6e6d2201521a06d3e805e1c7147237b309d9eb7ac0e9e93f0b833146d6798f3c8f2c5ec742b43a2413de78b9051f8aa22b1608f247d979663670a3e2ca54d187ece2734413d79c79e2e74bdaa9dfedfe2b9304bf46d5d3830a99edb9f9ef76a086cb06816d66abbe79bf711dff5bdb72d2fd4dd7dc2de0fe88b06dcbfb614d035904d50cc3ad799f7ddde0a75c7e081c8165c29b608d816840a5ff49e66aeb68a6f482b429358a8e00ead8364a78a441074e3183a9da92466674210cf93093c7ae62a175530abe7337c0cc21b152b199ff471071dbc1fe31d150089ff7338206fd9954711fcdfaeffdb37242fa757fbb192430e1559069b8f39dcab3945eb75b5cafc46c88fdb865366efe5fa516581bdf7301817f3f55e68c47ffa60a4ab336aa57e114bfb83d2e6fbddc5a1d9dc9e67f16a2fa66886cfb6a1b5ebb5ae8abd8a1e6824b08b3a98f9e9f8f2c2c20c8264f0a24334cf3380909082e4e9df7df4f387f4137cad1aefa28da7f78bcfe3964005225450bc522464aa646cb295ec863c1b06645cf590de5b344612639d96b73c30250e6ad691eb214b07b5859f253456c9fe757bc9f38b6d63a7d5341774dffc1d004359e88987ece05989ee9ec2b33dbd732a7ad35a267fecec16de07d321e16241ded0ba67d34b99a11bcafc577cb49ecc3d241f57eff58ee8059e57afeecfd766232a2c18cb06cf22d5323ad3708c77bc7fcabaeaf94a2ab3ef4f58d7626dd513931f69379479b74f081543ffbed38db4a61bca6c9c1cab30e5e6c07833f8067b3c92e216c23318d7cf677662da646b1ec91e9459d7367c03a59ca7f5abf317cdb67840fbb78ae39ea6920d49aa93449568a431686c9c8028ce29489ef977c7b90fd78fc58f09b7403f4c0430075998a41b7aa7d18dd335c3ca0a47d74f109bb9524aab6a57cc019ccc563bdbdc5d00ca097cda449f2e92f0459271939484aee83fd1d51f6a7519fc03945818aaf835a1ab726faed994b6b223a8341ef1d09085513872a2055b86d2eb9d20e986cc9a2724309838967271942bc78c68c6fcdb55953fd9da2e6c97d3791d3c1942967fd82424b6f3fd4a8db88c4f948f385fcc69934d1a195091a518b0c7e8fb35c60ced3fcc545edc9929c1a8ca165f59cfffd509ca85ee81d6aa3ecfda056b69b9defd0a19795dfd83c0498831763c29c8316912a55e45495cfd1d2118a2b6efc117b744ee1f29711a1c754660e570429c1829a5f8869344634a9d6b05b6c9644b61aa8e94985ea5ef59ef5a67b54f60a4c450b850a1b22391df37626ba5c8e2c0f2e9ffa14055513b47266fcbc83b94153b366864662646f9068d32575fdd73bf699ae90a7b20723672180492b2ea3525861ca0e6014cf98a8c9040a470aece911cf3192737d042ec851c9665b7f8bcd830040162c594b354234f1a1604ddf8c3105712f4703310f4bf5efed90af739c85e4bb8f55328f4cef5f9fc3bd2c11b6a751bdc96705af171f228c473e2bed244103ebc02682c633b3188389cf8b8896f0c847b2e3e460dc3aa4ca80f52812517fd9375231178dc73c78a44ba8873b038d030154c9faaecebd50f1da10f1eb7f69729554025e88dfe9c1cbd137ca9e1ea4aba164863ae4b34dce136292abb78c072ad94a57dc5beed0dd8d6401f7b527722b7175316165f47b75c0b072f16ccd768e90c8c45278e3a91000192abcffb4d21e8189852f8a3f949282b618cb34ad5253d7342799692c3daa5ad070bc006508fe1af4b74ae7bdeb856141f93e514cabc3c834c5ca1b8755e0b7d5ce1c6ad6b07df4c2a0e8982fe91c5c2a67643c3c3dd2549a573bc14c6b22f87631dc01d4d3a049bb68de86f5a04339d5a7c9b8ccd68c7013629a2f850cecfeecdda5f4ea36449785c0c2a5bf95b437e873a5ee7fe6eba6436eca1ae50c1b03f47d49325d2dc40efe8592cddb7b3e1b45e3026aed7aaf5e48da524b0ecc9ae23bdaf29edb767f5a26a331bbff04ddb492f8a64e2a83836d9ce136910aa436c85b94161d95e43e1658323f45ee2229960d7e7dbcdb3c42ca206850f93c62a62295a7c638900b107c37de0811c8840042eb0a412ebf9ddcd37589a3303a31c373e45d79aea6dc1f39aa54dea88066f3fc6dd96fdbfb359b780441d6cc55042f562ca2bfae51fc854271595351e4b8f33ff5676e362a6125ae6948933698b9b1a720353fa6efb4b1b62b3edf9da12240a9a401b47de63744d0c05f070c83f0246c98b92ba58facce6bdc873f1e23817988da1232887cb26115f65fdf03f32a551faae98d1beb2bcff64390b57d82b671887820715b043cf87728889ea8040e0cbc17f8e1f03d6c2eac5d8c1de7ef8d98e645d383be6c835f03bb300d58f102d629c47a85f8777999ce2c34da9fbeefd3659993b93fca6d8013323d4b37ef0934e7a53bed3251e78b36af1fc4d48fe3b09f6747c1cb5d60336e998aa2fc593a0a9041593b79d419f394d8eaeb4cc6981c2c7d80660134120b7091decfa710bc3ba99cb92b8f0a090e39aedfbdfd6ddef42ac24c5027b50a1c4a8c2720a8e51ef90518832ed4de913b6375c3306b80a7c065e1844f8faecb5ea5f55ff1e08977741f0e9e2fde7be3c0108e5afa93a3c70ad72163d4ea97027c3ff2aea2f120837f41f616b48473b79df8cdd0eb8892adc2f1b17f37980e326e1ddd21085693bde25b9a3ddedc0c0551af368b0b88f98893468708738500c1b15f5ace015796b38cba948e7f533bf719c3ae414f95c39a3841e5430f93524c3e38f2996fbe93ade8dee9fefe89b8e1e2576d135137f33e5d669ee9a56b9c61e05e97e61da3db18ae7bdf239fa96c8b4e114b97f02f430d02f87ff370f51fb3890ce9ffc9a58242d990a93e9584d2e98e2d9a473ea70b91fe43818552c6c2cc5c1a2b02ea354b27cf2f990ab36b0da8b51076e7c3b1639c7e81852c255b705b96df329941dc49ab8fd475f2549125ed27d70f306edd9a4eff8b79109506d9ba3709bea94fd03fa4b7924dfe3399aa09bc7342eae1109cbb5bbe4002ce11e2b38fad73f2abc6c86a7c521a1ee8cea929789d39ef76624e300ccbf422325fe99b69efb38c3fd420881c02eb3e4d43d3ccd6814721fbfdcd914a02f2de106320e7ada640e9668a54b5e32480f1a9da13411272aafcf202d6f3c96578c111cd4acc894319b27b94ae244d70ac21740f12432251071ffde208ba19e4986e01066f70ea7f67d8c8cc78c34f0378884362379fd124ce5d979152fc22b2cf4aa630d5bec3020204574dc975f7a1df3fbd243b0e934c6e535231434304ac4a291f5a2f4e725b0648b40ba8d9843cbd87c4f471980dcd35b18bf4e09c9e21852be7de289303183e7575f38444f058ecc4cc6a491cbb3bc0c2b875da9c8c05d66ddb09e4c2d8b5cf6efb1dd3dfef0768ebed33a9c4bc832b2239d0f10062cda84041b8882da16a23d1237cd4f70288638cd85330e97aaa90800b84f05eda706f012cc442f3dc3beaf8088b1f3145ab54c3f9a9558b23bd2f1ea4883bb64e8ee5f38cd25f566ff570988b7fedcf25c69701b1f48c7d96c2518754996f0fee2ea6f9971363fcf3cb7378add722801b5fb731e0a197e04203720dff274eb5ae75a8b91be936d5c2e0d1d78acc6c16dca9174097a85ec3108a03f1034f1aa45e0022651d678d0cd18a04a84d43d068ee2566f452325662d274c2e67900a85ecc0476f1f052f9fb2913a393f3f2c0a6118939084c9b9936134881acf77de67f3cc4b41210d4c984aaa7c0b5384c8ed97d9e61be5ad2df0e889c072f84ce64a5b875e32a7ee0403d843dd2f56613555f9919d3078cbad61f059770655b5644dfe3c05bbaab56b21c2a20bd15dc85fa56e6517bd343097f6bef4bf8e710adeeef020051eeeba7c10983d8e82d474774b052cc0484504a1a831a1a9888c3f7128251b95363f4b4c07d5a7e89ee555e1bf2b1c4e9c9b030715e849369e8c3956d9c654779ac06f07c1ec3879fc76a401a7f8aead108521dea63a252fc0a453387c2b2e8a5d9c267c538ace8fb66dfa9b21c6dcfce0f9cad69f2f56c2e15c35ada0937078fa86d689bf132f599c3ca34e4256875ce3745cc8bc7434581f9e66683e999369f5c75930980e367d99dc0340184c6771f4d0e5a3f9c7fa2d382716d2298c3e6029208c50b3e73b32dd4a0af8dc71ae9e85fa03c8ec81c56cf369eeb60faf7f9c04f8a053511dc943332018372729fd368840b925e73777a7f177018ae09ca095ac19eb84cc52153fb4a61384cc11059f62a2728a827c5ce390b280cce72ced14df6eb3bf2edd9892b42a384dab92a9e47f84ada74a2588d73a0e0d645885a81a08881bc6da7b89c48a16f042e18b07c12069ac97be7bd49740a5e61e918843d7ccdb41b41073670b798a61e7ec5126b60bf443b768dec77cea7f0ee89f921f4e20807f58037d0a9bacda27c10c385889bac0a0838a6ee245f69be64b956a368963d4ee034bae244579a5023b7f34a1c9eb63416204ea38a52d240a0d89d6e9ecfe38661209181a88109daf73e3e0d1107921c9f235e0c34f12db0134e090bb0b7c3f579e3e05caf931f31d3ce2b905ecb39131737f3facf5b26f4fe7e6b8c04c84a014864cac690f9189fcfd25db6f85b133717b483263b4d36e59f34b3a3d9103922c5cea5349db183e881c3ba97d0e5091b27a9eea32c62ff8bde0d526c633fd08dfe2a581d9f764ea896c77acdf4e0790d942b9aa8993ddb8e923e2d6f5c4109361aa00579472ddada7bb82390c0b8eb651ff5b1bd2604fdfe5acb6c4767ed8e057c01f34ae6772e8e8b23fab3cfc661474624fe477f4960cfeb884fa353983725b2b2b4e94af1a2c939f8f24ab8ee7ff36adcaf33b46eaeb29427c57c49ee3431a027b635433ee893538a2054db5641063858146a0f7f1ef039f70c0ecff47e31ffc53da337a302aec793ec52a2c510cbd57f2521645fb87a4fde6ec2af2958d13d462747a9a5a86fa9fa0b99fef00f829820fb3a38f2a23c4e38a468be9683ea87429b9abadc38c4427cbeff6b5ce6db791fb633f888a2ce1501360d121a3529f1e5e54070a837c9ca44efdf4667d6a7f2f235001345ca372c6eae26857ebe89973aff7b17edaa29d05af280ef3bc3bcd378f90d5cf7ada6955dc5ea75070af06b4b788d39f9b05668e3413db5eb15073d03f8afbf43871f6e0214f9b525d374b9f72c3bdeb6266c88c5c92779b2a27397014158985ccaa84069a064347df1c1846fac4d170318f5be1e5eb56cc61985bf5243c3885e1cc1449ab69f31c9c261a61dd8a2f0559c7bcf9fad0cb5ec185b3c944aeba2a9dd3b8cd83d838d3ac641599a72c89034ed58d113348ab64adb0d26554cfdd40986c7bf7e1f8ba2db85d7d5d3cdc49ac9e2f989ed13136a3f01a7ae460786347a082a347a9454141c718000c458a4c5febaa45a8ee4bc9eac82f31602a47c8c13d94be9e9cd3e741c71a6e2a90687082ff2ab3fbb5cfb09d95ed954fc2b02dbfe41ea90b06cac6a69dc218ce6c6193eabe4af365c0271ebde7746d47474c385541a698baff630a7e91322a6e425241a5686d6f0a21333fe0a7e87e1dcae29fac9545859b7e91c23ad042df0ffec48b03290a4f78f080e59e3011f13c1325dcb1af514eb19cf4159741b4befe620486377f5f8b0994d19991199a327825d5ffa319f852522c45e21683e32bae8e1304b46964562f0944755d64b45b8e8ada1ae86993fc95d9aa179bef28e74c30e2983628a85a36f4796315f514894bc0fa33971c25bc3fdef25ce4c605d72fce41993991b62f35b74d2c6c9d91c3463a35b3f384a57b6468f05c63e06b711cb34ce621d7e989ed212026c83a9d71d8fe6a211d7205f428ec50ae048e60651cb8b776b75a160b2ec371b34fca664348b5151b1b52a8fcb352f4dd2c264aa13c0f973c62a28d39e031ca875c1f0413cb27369a495baf622b519082946dd111f3256a5a4b316768a9d8da1b9e6606e279436b4db6781f676e2e51f0035944b83b796c4f4150cbd94664161873cfe8a8be4d6443f0aa7e048a08ce2f736e23df47550245c63c91bf0c590b3832c9acab6dae5ee7bf3f210175e4c9461f75c4ab93d425fc63387697c7d70ee5d9a38abbe986a676bed2fe4d2750fec5607418ebd0cd82e36d93108b9a8e55c6ae0fe34dc6bda482e31799fc2b095e332279b7dae068c8af9b01069cc3d1bcd928c1e3c815fe98e4077aefb810e66aa40c471f68375e60f8a496ba81edb5692b8575d7abc8c0b5a955dbe6ed69c7781343a891a59671f48287f466ec02e3bfdf9527290d00b46bdd9f84dbf3b703e55b97b9f72bde3b1dae0f419fa40c0468fb727e090600ed503a0162b711f23daab2d8027c75801e12355686594cb943441b088dce43c582f53177a4f119e97c02e9a3e6155204199c80832fef00b046fafc8b1bf4f56088ee6077f6e73981ad5a235adc22d79ca70b5bb6c3918956e8d27aa39cfa1876680302a58584627516896c36a2666db867f12074276f985ba1267a696603ab7aa25b2920b204c621ae740d77a143b0a95a6d264aacc87014a0610c1e92a695daedc44192b7c893b4c16aacbbb9e12c9c3f3e722d617f70f4a5af6df88003aa8f037645b70c9ad9802e788223153dbc3b115ef5ebc6eb1f2536bc8c9fc190fd565150ef4b2f46b79c4ff7aa256d8943c626631a738fa1eb6e7327a281b7a4bbb53fc340ffd8ab47298b52547a04aaee5d1106c81a9e9fb1b8ffc16d8a40d0bc83650e42485daeccdf108f363a983322a55c7a5133483af8609d56860e1ef5c78fb75e05636a90a3641366dfa081d836a88e440416cef8875504a3c5147ce98cbe05528a1e8e229b611e3bb1a28341e47a196931ae1fbdbba9a92ceca542caf4db7ad4a7dc99a58ab8aa0d24bc1429162bccdeb9cb30530b9e5cd3ad4d1618cb29fe3ac0726c71ffd4b19cbf61e1c8e3d0867340e6ba57340502207589c7dc237a0409bf1b1fc6520b372e4e6965bd5def18342a8e8c907d2abffe08e5860ba01de9a2edfed52cf2432975a3eff07bf3679b34e872138993a4e5310a2b1fe5bd48bdcc481a8bb4143389bd73a7e7816290b33b9b609301ea29380fe44ce498a671954ee342e55ddaddf8d2cb15c4a3ed82ba5c5165854dac4f7fc82f82c37cd77022438a517fd01628f515e4c872ae25d8af1d07310ae848c36651d834fe4d1fb8f68fdcd2acc2bb2fdc9bead38713e9668b520900f531cdfd272ccbbb1b72e6e677aa66bd538c4f82eb3a1d5d349febd312dc577458ff8d397c3d4883e21c8f6a30cc0918db0f457900cd49523b067973d599de240ec2cc72c0b7ecf83c1ec4e1daeae01773b839fbfa7a38d521d75e18d08799eb645917a6aa95e548e0d19e0fc516b1f962da368b9dc33585f4c6243334d721d31ec8e8066cc924152fb52297aa3099da70d27aea79f482559c47d273d07673e0be0178d90800bd57e979095688ce5380d063713cbdbcc91afd044aa169e49483034fa0b83effb162071b9575b18da5aa792310210cacd5f06b5431d8392813aaeff41b4b52c0d1b8a0fea18b84e0ef542aee8dcb2272744eb6d44849e0a1724120f39c9ce3f5e92ce72f78cd9ded2eb0368dd331e215a619e55ba41ba651779ad324bd55b3eec020df8b3c5bb073854edc765d2cb7b8626506cdec7ceaa61338df51e137d69575a91e9d3f9a3a1bec997cea751080ca195b19483ebe8ed1ecfc2c7af3ac0b33693f105a12def795cfe64f0adaf2c2a8cc04194d6c88351fe077f0d10c8af5cbe57d912203632bdbce89cba418dfe6a2876b287bc5fa8dbb21ea4bc167b19c92973eca612694972d2f9321ab8b50269c3ebef7b3310204942ab828a2087744b445c042eb69383b451454232fca11d333426ee9d234af604529e7899048f6a2490ed8a78faae832d20ce3f3b31cd1c08eb816c8654822aa6a7e53bae05db4ce2894667a07189ece585c684b0d66ea7f3ee24a565012eb132af3686c9cd777fc9deae96c5347e292e239509e9a0943ee7e2a677d0bede172fa9ecc2f940e8038c7e04583c1887021f6a8910b9bd40bc557f6c729dc6df6b170075f0e2df1a62225ee0ea55fcad3aefe7c68a56f73408fc718f0d5a28aa3ddb8252e50fbd6986788d8015e365dedb90db8873317fc472f6530aac84d869974a0cc69be77959a3529836ab2cd5ad13be0b7b99949ccdbc320cc3b07df37f784c5e57f4a1fe5f38e3758cde0743e07c7e419d97a26c9f2d0503eb98aba575e723ab0c22f97c7320c950f9f2ca8af1208814f391d1beb29463fa68e3e5fbfd035b745477ec012c51cc8269d638689392a2ba7e658bc84c5bc8d0a0841843e79795bd323fbf68259b0fdda0c5c952736c6f6ac133f5ae4d5472c9e3893ff81473ba53904506a34640e3f6b5cf32719923eb8200607aacbb821d97fc6bc2abe0956773d1f6c6713ae40cc0a806360e838d5bd9d515ad6424a6ff3fd04618fe36bbe06ff8ea461fa7589abaff81ee8d4507eb1abbaeb771043d2989acebad62c6be310eba069e57f0269b5dae895e26498b4b14bae39fab4625f31739611f7b6024a43316c223fb158db6b13b87b21166b7d5e6f7606c61a433d7d64a173c696a39ee79f5b3b777e20ee67e9f01fd73e2ce587bf0f6d52c77e4ec22b69481134d07dbd952217d3e835dd220d595cfa7c24768dd74c8a79e63391d055e1aa9e8ef04d0291fc594d8cbaa596df39fceb4bed1ea6a474f4550e15e377f9c21a6eb31a97c682377ecaa5882fee86de1b854dca73b0d9233923796d3364fc3c743ff62d94201cf0f30c5cd2370a7454d73489db1c13c76c5c0ba8d18984cc1515e005d13aa83f23a670fb62650a576f4c9c298357085dd8d321660a689aaef300024440ed6206be6c034dd1b63f2bfd5e192e592d1793308e2d64096bc57736e9b4433424fcea1120f7b0f90cc1c30d507e6215a81913301e22eb1cea93af7fee4621a287a00c2588208ec024d5196ad82f34a8317457292fda110b7fa235a7525e758365f56738fd180d5e1b48a784203e0554f30521a834e837f2bbf44a7db6b275be2e2d185d9dc7ed7cde7478ea523ec1b987edacea7de36a9728a8642729adaa35c093f22ea7aee4427e7afaefdbc27487d06fb836ca7c7944ee6d0041cfbfc9634ab6e2ade2c13a823cf00d603569a3d0c8d8b251688860e9e225e300ee3b5699d0fc69afd6e6a95292304ac4152311359429853824dc5703824eb29309d5781aba626ed73337dbe189629248a99f28482f4157be885429c89292ba5ab7b718c098b47bbd57928c8c0a1261602ea3e866d3113354b00127b2d4d123dba66bbc728f7902440a3d89e9c4a0ce39b2aadf6df50dca410d5ef42e3c19fba01650c2b1c3be5c5ada3aacaa78f06c4f06d6b4bb887818dba24ef35e48df618b74d70cd5f32216b07d68eb88c621a148fca0df027b9234fd6a8dfdd5c31ad44d622353730af211761c518058c379ee52fe5e48250e885ae5d70175d768f9b13e40e4067bd75632c2ac3dded4587d9575b98bca7506061b4d270827ac7fd859cb75b3ace21890ba35a4d0a69e4738beb255d10192f64bc13ca2042393fba8398b28c59ef80245036699da8fb95228e29f682fa549c4637b8f2276250e923faa944e10f947d7a4a821be89943fb9f1911fdc38b430a3f3077a4bbf5a8617e34f2299886a9441466cb2af85765f404c837861ddacaca14c32e31e5e5bdcaefa9186fd774bba26863fb2b8becf7253ab7ba019541520c81b154fc9fadbda940f61cf42169cb27ce500d9f0edb6f3dd8217e0af71b662e4426d2b3b0d7f37e935a94d17b8a4186ed544d6879ed22edabf946bc3a5f4535807f7670c007d52bd4f466468d947138ed1a847187adeec84108a1ece2b01e184840a2a24b07fe60cb0de83dc76a4cf99e3f4fa5b4a34b340fe9312bf305363bb8d97ed4973302585c773d97e4374d0e0d5fbf208d716a77d44d31497f5e80893fc2d044d48f91821264968f2d9f6f19a2a3be8421f4acaf6459b455e5d76610e443ca66f9fcc659b4304133d5414a8bb875452984ebbc5e703328864bea78478a5ed3897a296b0037d90d151db3f79c19c64f14adfe8539a5463e2548236085075002cfdc6a543719dcab52f9c71a67015aa0a0a295e5838965a109e79b2975158e2567c0cfd11e51fa9d3ae9aadf2e1f9bfc76a0d4968ae2ca1a2f90fcea9689578b8db443086fc17ac09e411eb0c25aca4ea9c58fbe81ae7c62763d02026f1c53048fae4135e7c500b5ebee3e599e29a735abcf5e8ae43be4878be066f9c37f96c727c65f7d525ddd273555e0abdaad4a84dde0f3c27ef099b872421b1dd1dc53879270dadb699adf06ad37c533aba059963a73dba4ac9517ee9e526a47282ce14e9de4fb2195fcdbafd5cd7be8fc008c198ea2f2c02536cbfa0c7d9a80280ac6fdf6743a28956477bdd874a1ab2ddc4a6b850ae75d5eb9a10a5a891562f62eb6d888b38cfe879a45efce135cf1397d004fc36a1a1809255c85c55140a610900de2a9898dc490df6e01c189d5dcf7338e2851455dbab25d94fe88def9aabef3334ee4a1abef1bd011b49c733da7bf1cb1111038889c82039cacea16ce858002eeed57ab682055cb78a514846c29a8387c863e49e31bc7c0aa4e1b83e52e1e40de5e3eb52fa43d61756022e82b26091c2c5171746ff28b227f119080392384a55764e35f50f1518384cdde3844d90da4b99eb4541679e6d063eebd9b7d75885fa6d73442a94be876ff3c8c45e67a70e9947993a756a445589a46a3e06bad3434a89519f71d3ea63c8694c583420b4d498e899637102b137e0e30f6c2ee779584a9655a31bbfb3838ed5f0184bcc8e1d74282245bf4eeca888ed708ecd35316a74bb29979996000f90a6e2e68d6bc75d689453be5b9d13ee6d87bc647f52fe98c51c1950dbbc015e70be8b4f80bcc82da7d5bd0dd9d29f4726a793bd6735c9e56c7f3b233e490325c5ee23a66441abc2bf3968f4e712f115a154576090055a53250d52f0d16536cedeb34e389112a25b1a0cdd0cde0eb101a37dec22546157704f411a7ed00175555aead7f0da932532adf7e8512a3dd3f5bd911eec74a1a2acf8fc699c43cbe7c54490b88d3ec4f4cfd08759d58c27b380d05f28b6d215afdc7f79a745dbe3553145e300bb017dd2f0a1d8bca99b2a939229c68cae867de88d8a17dc0d26ffd6440fb183516b384fcfdbacf27e2d0e6fd05822c886f872764ede37ac1005405f918b590dcc916089fbdbfe3266f7d0e8c453fb74308a736ca14e46e04e1645ada74309ea90cdf9e45fcc2b6b80fc9e420dc8cb90ab4f4f83655345fee478cd8b020f500be19eaa8ee3e741fadc57a06f81caa08204d5f98356eb94bfe786eec711683f89a047d04a6ea3217566f3f25efc9ffc39362e0dd5e37260139f13dceb699153cb33a16bb246ae99c2cc2ff6223b309ce204384bb946a06ff82c4ecdcf5b5ab0e8cef268af51d8d4b9a1a46565785c5095071e48fafa3875e2c297a01b04b6b8e2bb56a7bde31d60462e1e4e28e4dd360b762b694e17c96ea150339b417c6dc70166bca55cc2639a71105366537b56d93a81d1594215b46fd0d13c12b099813f5a176849660b686f5464995050581da69763eae0871cee2dd0576b62808af46b46120d2d572d049c2cc2cb90cad13860adc57c5160bf3c1265ec28f1741a5631ade49c354cb05fb8bcc2bda74e625c93a4e5a35d52f48de12b4475bd4da1e824207d520942d1a684f4ed9e6ae958faac307fcc16013c9075bdc351d7daab10d728efef4dd1675b94c4d0aab920afcf7b86461da940a8856be0485a6dc2ea3d33e246d8003948d2f0a5d439b7a8727988d3471fe89616c69bdd9ed831eb19ed9a95be1d2d77d6970ced3557cc0ccb5a0def14171f84d2e50cbd4d6c0f36782089041fbe7af430408d1579ee94a443aed3cc782a96dd1e8e6c6460b261026f4d41bba4f93a14a18af6ffe9830f2cfc341330626685c17b10c592e7e4df47027db918bfbfebbbfacccce51177392acc77ff964e1698a88166408d18600a6220f3b47a97665e2d451a2e6a65eefb6826fe9fe88d7585177357aa4cc9e27d7791bd1763f26ca6db1fb0d1b837a3304ab5965ecb647f706d71f6272977bcb7ceb8e2354db9ed5bdde25f2ae531848fd707f8f0ba7adf7f099c7a454dee7f856ea1c31b06d606ff97d6e2454cd366cd78bf04c6f22c8b29e440f9017c2d9181253d76ad9017c0c7c9f233f404c97081e913b8310e937c9eafa57d53b85d07447a81866fb17855c8ab2b8781466df59733d46a4cdb4472d77cc675bd2f074d9dc80d7b06319f14f4462c48cb6ae27dc625ea8f2e8ec99e9fa95c14a7b0619f82a1da97092b2b1527b77aaa7bf222358e4012f0cf65def2a460ce3213e77513c405587614418f68e66e824874803311df3f999ab7f404f03c9230cbb6773e8c8c4cac9ca0c603ad1c453633f902161170f784ba0f3313e311d89620cfd1fe5c73967012b81de8d1860266bc739139895e911f38ad04664f7ced96d4394630d4d28d23e40a6acfad442ef3044ea219504bf1380b1202b044e85027ba2f150b832165e90958ca59940ccd552aa7a092cc85eedf8077c908482494faa30d0da37ba05d8f12d69a0e0d1da25a451dd4720f0d25ac863a3d486be908a1d5a17e35a8aa0c89a0903af060da1efa8ec99c4065d726a22766620feebe9e9e74d7fb2ff917a279ab3e45ba2f5906f8d55d518fc00370f112a370edbf3f8713fae71fb2b2621786c335d14a49f338e75b99d6e514616244ec244a66d9e25dc3794f4b5bb52f92e42a309af3aab04ee66987a8391e746df02c286aa1005ffc7c1371e1cafc120eff56494869567b6502166b0293b089f3066603b042679cf92fffae2ac317fe16bf4b87841b23a1767558bc9ccc70c8d050ec6ddded14b9683fd28a783198366175befd99302c25a4e886b5f2de63122df975a704e1bfbf5b97696f6905cdd1b2b2035814663c59039b23ad60a8788b6816a7891e68bf12f2e299deb4b401d151425bbb06b4005d4f8c6d187399adf053163131fbd744851aa9deb41bf1b199cb9db9051d13350d9f75daf35e52bcd8a79fe505fafc960f09e54f554b3c2c55f68eeee845e9c28506c543c7fdbd95211e55300f1aa41c2f45dfbf337b2167c36313e879aa8ba21ea14e38da60284fb37e68eb58fd5b57a2ac205976344fb91e0bcf15d446bb32d85f4f70dbb6df52428289a5172134c28f8cadebe84984a4a6c82017f34a780611531e3e1a491fea603c54cac59924069ef6cfb800d201266c45eccd40e93adca972449c8a6672337b2c254f6e1e1adb857845b4d3322c6376406da41e0c174a002a13a5f0738123ea8218a1ca670d87f1658d0ac263764c48e23c3065d564619e05a68632052688c552a6f15e77cfc9f0652cd214f9c0044463460fd4b562031d842da2e40f58584614e896d0cedec8a69f4021aab53b942b259b39e8c42ee3782165f4dc43acb1332fc580fa39df89b55ea0f931238a557c5b6d88ec93291ef0eb721ac7d7bb33c74443644606699822e74b32c1de3fdf2530cf44cf1d12cdf76460be0cf8877a50c075648b7303eb9d911e959511b026ef40f213b1cf5f56fb3bdc44b66a49e4d627ce35e7e52704db1a19fac9350fdaf64c6acfde2c9b0633e8ae8b6be2ff36b27ac43cac1cb2515220e5a87738972f325824fd22e6b7f8885c69e3042b7191d61b004364d89ed3ea65a1ae340944628a3e6f90c4aa194bb33730354d7711b16ac8cd7fc94c1b6589b151e3e0d00d25346654c9103b9de31166288828e105e0ee7b56dd7121542ec7c0345e9014309f9e5f86dcf932b7892805d856171551ab8840559f3e7f0d24c63d900163cce1f65a5873bdcc6546902a1957a68bc1407b7e52e90cf120ca87e05d41831339834858ef80db09fac0f7ac672761bc048554d8f1f9d4a03020d27b1af27e3b2b2f981af778ed674edc8165745239177d9613f72d6e5d65875ad5085121fa920b6769a6824485b8a73352f602ebb4ba36c452beb37c52f0f6a8d9fef3778f531d8ca712100bd19d36bf71ba14dcf2c63060af9c3d73e58dd67da15029d97a6cbbc746a84e8600913b1320f4c86dcbf278dde947f9052c4a865af96426c0ab3629ea190de96cddf59552e86e151a200c5ce043535fe10adaee7a537a9cb3ebfeefcd0befee356719664f43f6fce44de17865fa44b430739caea90d49129b841e6b9840faaf7bf319c6b0ae631c28764c719196f3454a2619ff5db129616ccd6ea684491e83e2ecaf26d1a0c00203de21af9cef4509b79961b0c3836889ffaaa7eba7fe8588d691276461612240477e115add24f036438bbfa9d2aea987000cde69bb6a72fb2dadf4aa66ebe3892cd88c34840f1e11f6d92a55d90306dc44d5f2fa5810f5f76c848d2d07ad793b66137a1a9026e338aa0c29d87e1efa095773fc58f4324c506bcad8c3401bffab14a606f67dc5bcebe14af28a5d94c2cc2a112a4ff156a2a901394fed2889d0b1f2474792900dc0ce619cb9fc681d01065484a8e21402476a1cbb48ba9e7ff611d969f839b9259aad21b3cf08f6522a2a72fe6e246a9c41bb2c6a20f28341712ac448b9ff69a352bf0331921932c4be73e90d063f543644a96f76724abb6fc1c6ccb2a141a03b506fcb8ac4cf929ed51c084ef662903b9704100540b55a488356dc7f082e1f0975556658e008b1b15f165c7619778e5c9d8b582468fbedf8b4473b4b4f175aa128ac47f7ed8b81530b81123820f09c5524d56b03ac7826fa3df532f89b110c4fd818382b1dc74dfb5421dc351e03231a3ae21aa500a68583a769dc4c29e6254e13616fbb41c9315f02c13eaece9710cef714357ae4ae8ea14a27adb6332847ac19a906a97fe12f91d367911a4c470d6c7ab1e4778b3d915a93454a7e4e59bedee0e5e5a14dfff5a3cb6208798fe22ae54a128867ac81f9a4f452808111459881a02789f266b838cc1fe7be3ce8569d2d8385fa19449c9884342249dc2d6985199a74dfeded4ba3ad0724308d5bded47e74ddf8cb78c1d4ef631c1fb143cc168d1df724e697bb7da3b8bd3afd3dceaa3cb29d1c2aeaaea024ae9b9f529628010f8afc4130f8e3287688b8d9f2a823af8a18cdb4819bff816ed0fa95048cb5c6ea13fe848b468883c41a09f17e37cd1d018437d1df080f507c0c9822cec49734568e78bdd684bef6b8df10cde6d803aa8e45593e8bec39a1e80127a239975046f1b19c6c6702a0e8070eae103cfbd5515faca38f097102d22b09525c7a8aff0054f77eebf5fce9ba00a226cff44384d256d2cbf646760b0a421ecc25aa96d1647649435ce747df8fe1933272f44139f2d2f37cc721e013015885add011d0208d0795c3607bba3fe1127e3a603539c272d62708d52d2f37d880e3726b0ac55b7406c1aca5038d450eaffcb31c88b71e91104bfe90190e03c50dc485131f160bcf75811115f3f57a3c12c12fbcad9a25685004f81b3e4e422a6101282afc7c3028b86197dd7dea1a61b5cf1575e243dca003a50930cbc517e7d8538606233c32ba37f7d8928aeeb5d7320c237255054409c105c2f75c3c60a36d7cb7a1632b3353cfdab53d43d73773e9c36c5efc847e0a819f2a340fc9e49907797d535e31c8a651ba480af015c98600346e04a2a97aaddcc2aa47af70d8f828b86f11e1cd4712dc4c46edaada701d62dd9924d7bccdef6d304be2a85656e12e175b76a6f353d8f4c6b0a941f2351f619c5e5740e5d9aa1dccf99a2b68c5d50f3ba8d167840e3faaf3b1dc4d0ff979d8e2b090ec916845229d18725b06f597b2f2359fd06593c9057f1e8a8cc475c0e4a3fe745919b721ccca99b888e444423c3a1494559e9345a2a901ed7096db378b5127447a31c518acb7fccb20ea53b613575a3b078b9b5eaf24b045f4ab110d996eeda9ec15d1b7bf89f4d548347849549ef480ef0ce0bf7ccab20411531220a20d3d77d876e105e02cebf2f129e906106912fa1be7f020c99e30d35fcba4a8b5ad342a228531d257ee47b67bc45398437b6826913abd58048399c490e033b07a917075800359e6f8949060e180a35b7d82574152a1e9e7998391f6ddb5b157003f17ad50c40d580ae3fd5a320b30da6a9d5213ecae2fe8215f7d0a26acb85f0c772d5603438a9d0edc7cf420c67bdac978d75ae132a08e518c77315800db2fa4c52871450a2f44eb94d70eb3eba47c7a28e910077db28a2ce404a29a9130c61bdd24cfa06ab6df2d688d7bf5a5a8859098313a4f057165e8dfb73fb9abe802cc8690a9141a6e5dffb2f508720ba006915f471ec2acdce5aaac040438f094b0ac947786e4360e5135cd229fe811520863d45128bccb41413d17d32f97689a1189964a009e0caedd78e264a2341b0481e5ac9414665501bc386e657c79b371a736205b770a67ef25174176893a0c9f2709e14363252a92ec2e10918a8bdda5dd8db433e0241a3cf1062f064b534a8c2668dd5b7dd4b2c1878a9f9c510b55d2c990f819d43e438d8e03c75ad39ddab498ca308bada6d51537826ca755870444b49bda83c51b4edf6283850d3465a46b7a5918f296c0b5040934dd76874f376a83ac3bb74860ba07ac7a00b267edf2638dbb85cf293a281fe73d058af830aef9d87c0170fa790c7bec95eee2595f64471993171aba06dc0180a89a2e29ddb6674d1054186e82d20d4f8164e164b078ed49772b78080cd5b955ae49f7bcdae20e45320a4be59874e7f591a37b46303563e99274777271316c9006d44737d20811ad68ff462d7cab94318d33e936fa4cb07d1a5c3d490c72e7e411e18f0647400decf95bc540b27702313aaa60c21c28c608930ebf40d629b7608a4fdd962fe78017f0fb0bd367ff2b258af13bc4d1e0b7d625c90d0213cfeaa9331ca72a1bc70c910deb150c0f5574d10324b6c5b09156eca40582bec81027ca271e4b21d1af2a4585b337042a3ca8b8cc7da9d808051db1ee8aa1c938894e54e2d9e2563d4a59d467e2a8a357293884617148c947c58a7464ccc57470228e7deef8e70146530069aa49fa23975f9055aa6b735a27ce4bdb0783afa24a4adfa493e1543ce6a567aff2226ff3b6541860ca091171a33b7ca9f4df459e8903ff845a9fa4d87243810d57d7ffada6bb8f24d247cbb36db877df7bda28ead8721b3ddfe147185140a8e9980631625bcfd8e55893d103a32e0adbc6877e28a3aac50bc0e86c65378cd44e0d240f4b78566d92f83eb0992e984cbc4f286aaacca4d6dfae22dfbc0f543425fbc903478dbab3343fdff9a94336f154c06127f43db2c87d3b0aa52e3b20639132b56bf01d871ef98df05966afe3cb60c99d0b4c785c53480e5c6d5bd3ed563525cab0e6ef924a158f2eff7a27323fe8def7763762a41d9b92c8f5eece23cb596efb5683a44bd490cabeed49e87ffac64e245a3e310e50547fa21a2922e67ea2dcbb9df44828a9af319771338945b16816bc0cc70a2d8ebc166d4ede75ed2028af56841e943da9e4d0d5dbc7520bae4c0de828773fb53cfa4ac80d920e1ef9db2216fbe7dfd15777833e24c35e9f8a8d13bf9e11e8427e5d2c791662e4c930a6f22f54e68538cb310bf2f85de14b76f7d2072a4af3fb17c5f4d2184ab904ffaf6353615e06ecf0c4c83efa8fbf4bcc6e40328abaf1403c7885a5dab800f2083f4e7a0d415bcb8101e82050a2f3329c82a3ea96e98888330d5e9dad3926189c03e8cea2f5283ef6a17c8dd2e40c8b328a12981b867596143b095abb6203141e85c623d48a67ca8107ddb7b3278d4aa0d9e2618f7d9edcfebc594d5c8045e8e49668895f1b1f54feb519a6d3d2cccc4e8238bdc354c92db4078995de9c5ce02d49f608516c7c4b4537a2986db55369f12b72b4a5114139829fcbf10f08b777b494fbe7b5fc6c8c11f4758cec291b9905d25ed3863514fc80470f0f82f129bfe88c28fcec4333686526f389f26cea3a525fe887cea7cd5d4a70d44d076711067639138539097b5af5161f67cde416e75ce085285474e485d1d59e2d003bd3c778a78b023c7b1387097dfdbcfd6625f16e435748c521ea2a4f452de0dcc18bde63533bb837fd213265c38f953ff8fdee911abbbfdaef2df8f5de6bd9f76f56fd72f1f2398b9aecac4e32e2f79541ffdef3105fd5b296705b925af93376a68972bd882ee81e3f4ffbf60c1aeca6743664f0ee5133fb38472a6c39f6317835e28ace65e7474e99465bc0c235819ab61ae6445fffd0159f2bf11da187ed9c9cc87fe10b67319fa6bfdf630602860985ad4784a18c9a36ff3f52a61ae28b21c9feb6a81e05085eee3d8c6cb9cf893636e5d1fc44664b55f1005f35b4eb9ec3ab93c4a6c01926c85899d17a437b7c7bd745fa2d36775c80597d43845884747f52720bbd4d9ab2129b120fb5d222908af7c17c68453bef0544646bc9b52492b6d7851837ddb1982d42c6a8a0a735b8a6ad9ee4e346bec0143619dfc1194860ad9861a8d5a477558952781b84481085e6be1765160240e26137f9fc3ab7fa7f745cbd8e9f97561953a9c02f9fc2d6a3c264e2096479106d956a69088c54d11655246cd93e12d4b810c33d930d9524926309874200a913b1c2755119f3461b39fdafd86d726887a8b0218c84cd78b716a55e10ff5764990d0870a58df4a8ac99ce847e9d9b5a61d1eace785f2280f460481a9501aff644c28660c685ed057d65f7465504273d4eaa5b3864439f23b1cad7489e5dff0cd567244eb0e49c23141047e6336dd1046bef4ff17e949168a21df1453a62a2101b179e2fa1acbd5474548fab837d4704d8328ac181b4b37f4e491b9d6c6821578fab7807c8d78642eb09535ddf778dbf7e3c1a8174a7fd3c86f90547da5004f371dc794a1f6cbae88effca0a6dc590d4c3f4b31c245e40e4d401aeb20609b41528bb8af929ba5bc4003972594b65571548e264a9af1f6eeb5c8722654d6d81b4a61aca5af2c42d5db597b8126a1276dc860342662f8228c1a0cd2f13c0709c6b8ec68e46f894ef28c775ee049d4daa253d8c78c2c2f77adaa869f68bf5c2b83826c181ae59b73954f131f4c3651d7ed0bb09d51f5893565574741a1c9e64394510d9c233b5128a06a76382daca3e18b778f8be8b2febfe94ed782f5baf445c41acb8a73a65ea98d8820823beac0a50afd1252a8641fcb8800c2e0694e185069929b9f8366450920591506b440b95ff6d931b818f6c8539c125a3032e493343c194fd5a506e7de9717fe8b43888d657d63bdfcee3bd19c3d021238c803899fa60d24e33b5c8263c434c44336a63a5b11713e9d748be5db1de927c7603757e127e912abd8fd42d3f9b6ddcb4ad2327462d1964cca8bbaa28ebc296a5de7746bdf516e82bf3065dc0c165457d3845258a6d819350495b2d3e3c303961eb8ff2460d9794845e5494f731c49940134a64fd5dd0a92958eb91ca13814d0c4ed78ec0004a581231438b66aa117291228abe2f585ccbf634e63516db435671f803ac3157005de9908284cf932fe373d18a8f0e0277312d5c806b4ab5f665153399fa7e1278f3d5a8eea451ed8c5d7d85fd4da9d70af5762b763caf15a1c0e7dae15779c285ceda55081391b4e35e224862593d219ec2d1835022a713958b709ccebbef3bd89e9d6111c6fe3a2e5c8d04e9485227396fe34fbacc317cb738451562f292a12ae42b106f7cccc1369990b95e5a84dad998e1c953177a40076759502d224128c2b9ea43c984ed1dfc09b6693dc2b4f1b8e399cb3dc1ceac3dbfad642a883023cea85913966618ae1648a35d4f4b292833e63449e42401fde88ccfb66100d462c9cee7ff211da2c09d26e453b499919936ee3493627ad430b2d9667016a6e94a65cc4c46a7d90235cf4a585bd552abcc841925b3b8b30b46e3cb7649c738f38228efd0747e7ebac029992b97c52654b26fd0cccae9e896c936025c1ccb9c4005ad5213ad1afcb13e97a60681bc50c0519bcf70a1c1dd77590a2b86788459a47f16a97909f78dc73770ae5de15a8364bcbc3e35b84a64e5e26d857daf71dbdfb5a55985579027e7a793593e393a33e22aa6959641305eb1227f43937b592886c52abd4eb294dfd22475b98e3a5b431ac678a2bb10f9967a02625250431087e5d13e4333f6c00add16799dd0f2943a1a68b032e7804d4ba4cdca1c2df58d927e122987c62091c633e33f5b133dda892b25ce8bfbfbb7520e77b4b6205a5cb0e79342f928f65420329477b4eb85c1d876368726573bd84d7d16c08351f793f935eb6fcc615d6d4472e7f6285f9d1727c6ef889301f3839c179a7da1159cf1ad7d3d4d576215e8152ec6fba631113dc69c03dcb95e9f8a06ea97f596dc9ce39658803a35eeda7880deda2eca4d81560dc0b80f943842fa54e81d78b2eb8285ee472368c3908e6c29a822421d6e434c8dac773a62e8237d5a99d2dff0fb1a805a08bc23bf9c737d53199a02e7f9ab6728433720fdefef05a79659f9798e8436fc634998a6bf77a0921268dec01a29e0ad821600066705cda322b0942b6a5fde571a61e0678d80ebd0908230757f6142129ac318509f59d04041249c505055e7d62698c7006d610f7572f6cb1a025124cff694152481f4a062a7435eb76759c4c8c60b0906bb8230e1addc5c45fa645e1b0543e1711ffbbec4468b207ac1ab1a20b54ff0e79a9412044469ed2fb5e1179d92e24be3dca770398f794f6f5ede03d79a7108771b1d886fa7a997b41cfddf52237610ebe1c029a8f89bb211554a488387298a3c21fb0d40c96909558920b2d0339e9ba249019ae390ffeb99b7cdab6d33a392de967400f7f024888ecbf1115b3033c948c52663a79e840bcb3cfbb1d20d631fd4ff50db0f3a745bf8a98c6edf330c72eae6f61b93ac97b93d6f55359ddaf76d3eda3906ae0e6ce2465a0818cb55ef155389602bc8e4757075e18b7269a264b321c00ef58f274f599a77127041754133c5891c58ca66c9e671e7f465a4bf7c027dd1f34182d9fb153816570f6f40e602cb2250039e5999424c738698471cde073df46a8173569c6db0076323ee137b5164db77c1a7acc560d77c9177401520fafa9413bac9e23154b274c6023399fcb301cf901099bfe0dda78f8fc8db75765d3a857e4bfc5cb79295cb13a7a8c654250f9d6cdbc7a326bc416eca002cbceb30f4529d9dc36d7ca90788174e5ff26af9a45764c0a9655f8d8dc8458c4b2af0a92d75f33a511554ad465cb3ecdfbd45eb2a5e91a2b74f51cd9983bf92bc2d32b3d4e034bab0479304e559e908305fa7add04b986404372cb39033d9a164695ddcabc884f72108b6d30239d4f8434e53527a7aa8a0c6536b86029bffb9228473df97462d41de9d5838d02f364d2240f2ff5046d4c611860c8bffecc35ba2550a2c447d14185bc09ae28bd59f2cd1969ae4d8ae010feab22a71f5dc4d3cdc5d424ef1393799ed5ba1f23e33cc93cece99bea6fb93f950b377abee6c80505f0cfd23acbaf5117fd54e5634e5bfa0a1f1208eee8dcd096706ac748005d7c64ae940dc7d72fcb849f142ca3fe936e72c84d4d521aea97dcbba3a74a099a8a8cffe0f45b52b09391413883eb161da7c38efe86989974d059c9f842a7b144f0e168349fc571ec2553d549f0de50ff478fe5ea0a24a0f106700e8f56ce22daeed89574087f7fa6b634673eb54980022c68aed03209c423a4cb53a81baec9e4b44f91bdae3006fcf61c9d661e4d9b342cb5a614a10a2d8fefd473c3ad56da07179083be44aca65bd15d999173aa933c1daa50258991f1cab2efa04cbaaa273c5584b6113f6016b8bdf79b8ce3e62fd28d540fcee28bdc640725b7ca1448d8fcb7571e30e91f5a6ba0b23fdded28858400f370178722f5fb70538ccf202e6beb26d81293227c3b651650ba9d8f2f3d61acade1fea2463b38971bae63298a6cb2ef4e84d9c8f21b2680d495cf2dae338cfcebcb3150ca238e2fa34173d5c6409bacf91eae00dc8c4a906e06f86a41ba571961e79634d0ddf4887f9f96d291e3da9aeac649266762213a347c88db941d3519249f661915bc24e82fcb0faabb0bb5ac30f83ca7f1e826e9828e7cc1bf480e710d66cdaf124e1bf8a214556ee67518131e4e7bd54527d50c3e1535cfc449e8f5a45768845093c60e9b9628c233c92bfc01747eb181a64d165776d0b22ee13418fbb1a172986b3a20a24dbe1165a637ad3e990f32a50ca8818493c062e1eb4c40a562ace5e5657cbe31424ec248815330ea675cc0a291ccdca40fcb5831a5b7fe5f2af6a52bad90ec2113d19569fdcc3ab1f045427462610610cc211b83e8cc62a3274dda7c07faecfe5a94a41686afca89513f265207470495e741b9aeae82690ea82c3c57d854766f0b825037652e87902eb676a0cff77cce229bbf0f5f9fed23aad95b55c13677ded6cf1be087137880e06bd0cf71b8ed39ea289a2329a98f48bc4c44d4c54061da9f21dbcb5776ae3bb7a4b7c0baae9ec94ece7ec8a7a8b80a19afea7da117b641964c94b9667717175754ac80d26002f3736e1482db3fc840a5da348cffe13308c22a43f4a11dcb9d0800af0b7c20d4640ec0b6cc2342af6490cf3017a6e518a198f1f2290b11ec50db7512961467c6fa9ec01e841a5b84fd1ae0abfa5e6992eff181899e142a1662e529f7a4b96c2aa121b97540aba5ef9cdd14346ad3c166c7bd18946a2fd8a2e6feea7e5238a2821dc0059b6078120b2f8cc6dfb65de819224593a4dd40cfa811a210f8073836ae4e1da694e72e342718e7dd355256323c11ba386bacc59ca502e401e3257f9c2e060ae047dcc4ab0325a6088708a6433a7fc00e2f0beb063b7578b381001a8a711a98a05dd2b591ecb05b464a073482db1fa11b49d2c68cf71825668a3ad87e2521673128cb306a815548d5e1ecbe66c0f74e426c55e1ecb0e12b48ad5e5b1a44b4280f10aea59d290e27059595e92088cd523fa2db62275624fff44773993fcd116cbde923274c58b0ab45e32c1546c034a158e6a5b30145ea503da7996d0e7ad34be5c6d5bb8cb595a4b27a6ce13003b19ce0bd01fe258834645ce122ae22511c5161d628bdcf0f801e33eb7bbde4ff37afda35e0ad72ffe8f269670e1bee17d834a7ffce22d3bc8de64cbbda54c29a5cd0683068306346421ef166a21168a21c68f6b70842ab696953f9439628c514a295329a47260be0ec373c498715877c55239b8fa67a91cecbf37dbdc5870dc8cb9c17f3e5755d908abfdb6b586bca687e8526ef69c150041507e45a66d69c2f9f29fdc04bed56ab558469eb59b80f06b3748e56b3fd3600ac71c2a9a48434b46488db33538f252fbe79459651a354e3885a8475388adc110f08f5262526ea80f3b15b4dfde533b50bf7d9cdae19f6ac76c55ffd9aafefd981fff07aa92406307744a6e668750ca47fde6eebb6973325bb1ea550c72a8e1004328575709872f0870021cb2f0828315e011c5ea2ae1d0831516ae6931238cc023acfc35e933c3a44fac4a9f137b29a7c4a4f499c9a86931238cc02b50c6cb74333191b24c37f33134326464cfbf71291c8ce2994c866518f3fa67c2180e4de09fd96233d8a20eafd96e2fc60c931ebb3119dbdd1d6bd9b1bbbdbb1ba63bef86114497c8ed5162324ab92b252633e93353aec6a1c2f82ea5e4dc93acb56024c7c86566d8cc30cf231789612d774a96f24377f795bbcdf5203d62188661f10a0cc364c4aec062160cc33029b12f24e65fb29c207ac430b98aa9ebc36b5ac76b5631468c433df699e3ac0ef73634d98732aa8e4dfe7ecaeb788b07c4f3693048bbc03630b02768ed058bfc30293b66e6f828c6e9be7df8f00192c2e19f0f12d02984da3239ce2eb2931455c8b0218a183728e151d49095e090430d798897542e7ac9e0f0030350a81728dde0440d99b5a2640316a6a2c5450e95f9aad790c3912d9d53dd38eb423ba523575653829c4471648601c81083f8d188961aa7a89186276a0cdaa1a3e1ec2a73d5abc94436654a1c894804612938e245415eb34a35b4acdcf080238c948ce0e086071021a186b0ea55cd902a90f88113c8c30fb6a042b3ba493ff052032b66c8c28a1c9470c08245d27ca6a25543a6a255b51857a8ff8186f3851c5c23d001ae1c1274d21a657cda3851a671c08fdfa790a08cfa55fd313f7bd487ab1b9c4a617ef6d9e4388e7bcfe9e7487051ae598eece79c9aa6693eab99fdcc661735962dd89666052e622b9b73c3c9d628616b74cd987b394aedd63e7b02c2809a00cdd7be0423ba757e3f4d7ae6633f7f9a842a28a002592cf505ffe2a5fac854f91a90f50522a06e7ed38b64585307f303bbc5c2d23ef38f88e6a9fce5664212babdf64a4680e021b2ad2781f918ca53f9d7333f95fcf9cbc23e55f62c60d9639f4a3ef6cb6221fbf9f3fbc1c01030f0e243abc5ca3e955c96f6bdd7f8d70196401419b1921c3c3d0a68c8454c1e1134ec22958bee927f0c8df3d3386110f971510a09aac373baaee1efd81917a7d59d3776c7766e5eed0760c188d3eddedcedd47d77fb6777f7c605c70884b8bbb179cec8cc3122f18845cfc89c25c6e8ede8e87883ab78459432fa17af702eb6a5a9dba0968d3916a4ec97de8e8ed7fc40c71b5cc5ff188966dcd238f1080c74a87119290284225b106088224e45b21079d2220376a40b1aaca06c60ca860021635ad18e6e51036ab5c56be3820a27451732c0be90a2b58ae08ea4b80a2353617e4f5061607e12a930325ca9300f238503a62b402af51bced4144d4d7d4c7d11414da5beb86a4aa9e5434dfdae004449b16d3475b3a9dbc7eda79724eaf67448ddbedbbc58aadb838db3495f0c31c56e4e0c153930e20b220b787531c4c58bae4ccd9ea8d9cf8c0b126c7183c5f12e1543610b2432cb22801a54fff954c593106d26af0ac39c161796640386618cdd4036d920a59472092c5a920829a1c54b1750aca0b224d960050d590d65862c0d01ac494fad17528d3f6fc4f5828b11473380410e929c205a22882d3ecf2cae1ae4e83a0d72185feaac68e8344eccbe307e3a4cb5205269542f6848690c61894ee188af56ab55e428c9155c38f1e2cac11169440a58b0558c5695115de934ceb2fc38c3801ad2744982290b23598a6accc2881a93862003e84ee6933927457129129465d1b8e0500336b9f81024776c119471118286a804e362c411d762cb0e2dba48cae504397486147772692207def1d4e4353bb9b84068c7109c3a224e4a337c914a32801758d440802050545da519ba0ce0896e759566d0a244b5ba4a3334e598814969062230f0efcf565d6f6babaea7daefbad5c398e83ed7908584d846ccaf8c671e388732f3f22fe77c42f40b79a96e128c2fe4275c2ca5eaf093da8c04887d3c8277016d905543a061ece91ccec2d33898098e3cb1836e6d79c2b21fa76c19f6d987e9c4784171c207c21996a19ef63bbd2bd49199b7f21ac6da6582262ac60082d228652c21b1262645998c22d98c61034f4e46f2d46234d1260a45050d5d028409456d44201ddd8004885ed24c9c4a07b93fb953739566299aaf30169723b99117c98d932104c4d0122a538e9870a9182ba80161f63c0df2c8fefb917d3c7aaef037ab071acefa537ff007e9d8c91a769e4a61fe8e6facc5afa381b6a22520e2487b47b96b8ff25ef02f3a2f1470a0d03930dfbfc5878109b30f39f662e488607edbfcd9f3ce87931f11a5edccac82f13ffcb587e1af3dc752f3b28f44f40b7a16cc47157fdd4cd7f46b2ba09d1419541745426713db3eaf4725102f3e225ea1eb6d6d6173767936085a4c4822b3f79af92808ec6f0efe52330cc3b22fdcefc06f7ce9c110eb8ed8bf2c22d4af07a3baa7ea9fb5bf393d100790e62b4b284ab08c208a96111c69ea8fd9dfb93144897bf8de434b69410d57df030dbb97122d980d70659a8ef10f7908480fb53044c92eaf0024862f08d78486eb14841fc837d72de58361c762a93868832cd4eaba2a46432ca12449c9fd8341dad81bfe06ec092ff8172f3bba55e5d780bde1da5e07ba4a4f05fff2e5cb97da5f03168c2ab8cb4f676f646dd6a921585986d2b0d3b0659f61588c40acd1b1280463be61e9004850595789071c146009edba4a3cdca0c30250578987293c18d5f07b8ba416282dedb3e4ea4a1e1ed7d5de4041c36deae17352da750f32ce32b8cfcfcf21013a122833aaf23659a0c7d688cf41a8dd3132a7a47b60d82cb4649bf99918638c3ed1fda36ec4b634616caaf2b7ce3e9084adc19f01fa518bd2b2d758d3b44c7bceb0d8621b581c32c5e2f45377b1a07c192f624af582f2851a477bf911091071282e699cf9dd854ccbf862c47c5e44bf229814d71f7b0b68b8efad103d1d373c14741a94361290e0cc1cf584f9974dcd999cc9005b835f3ec83632b7c1179996b49961a856a2cdec51dacc50dacc309436330cb54ccb0ff3a9df1ec59307745d4f4f4f4f4f4f4f99cc27e38bf18594c27ca1cdc77ddb3741d000314954326d8d661b315a557e7cb23596ee8dcb9f93d2ae7bf94bd953f9924a83724a95ccbb9bcdcfbc179c911a1c82ae8dec896d645f346a2eb6067ff1c9de7c91696fe44b25745a098c14c6bd029aa0303fe3e5c72316274eb1a07c39e38b465acc17dad0afd5cd2902a500e8ba19f12bcc179960d080c6f7efcf8be44fda715e94050909090909098983268a6addfc4c3ec641937e554013348c46ad2a3f1a21b9965e4c325b63a590b115e4394258f2a390e74496fca8240e7d2c8a4d362858edc7dffd5412908f3d0b8e7d404d7a16c85f7eaafd88b25f96fc653dfb11ed9837a605195e0bfa91f7145846c0c2753ab51ba10723f480668b369a9d95820842d0d09f78dcc96b4ad8010dbb656f1844a914e60ed8c5485cb4af255751d1f217c3021abad04e7b933b6571269dd76aa99b406f2667a55ec8012b21d085804cda096d8dd49c9476dd3fd8af55bffa1583d7c407e235d1998aa6a061bfac6c4e347a6d0dfe4e0ba5c2688a1a7f33f21c9a45a3ae24ac3cc799bc26fe9c9476dd3f08ae564c948a100410cfe9d7cbc90926323de938adb2803abfea406aa30353e3529eb3d8a1a01da0159b6c036324f6263e17f109ce4a7ddc44ddc87368c450a1fe5da917a35517fbe411f5efcf3e9992c0b252bf291eee1909fb908b7060518a28d3aa5cb492de6bf7b51d0150824d6e1ba7fa63f4f7e132fe7cb84ac21094fbc17ddcc17d5c887dfc2020e5730a07c7d40a42eac6defc622a05d48ed3e9612e770648ccc004b57db8da334002864bf5a76385d7c2b362df2f5f074f8fd4549ae6c3473e906725bc447e10b94d44aa0c2212878e704b57ba90daccbc165a537056290456aafc1b8db33ea8f25dd8c1098b949ec2812282c68a83bd0c8e2ca502f6330d764464fe3958056eb509c12a69c815133190f27584a046d91648849478108251015d25212521185816ba94e2b81e68ff2a0931a9d8af6f18c6428da3d2fe3114e771d8dca67c2e224a3db37e98c5bd4c0ac7fc28edbec33e1b50b56a50feb2745637b06f6713e1075a7fa0d8739dcf2d240d2a69500a3528352bf46bc8462b603a66a6d0551212aad86fbcc92859888d3c466a50be00aa501551ea97c53dcae3e9d1625640e3b1044d793dbc463ee7f98842c36daa12ca12757e412410277655f9233f062168b84ffb1d7d7808fb9529283666a6d99b1eb21f7d4e4add6d36a45bb338dcddbf0f40b32bd95a93d2676262626abd8c3c92e80ae1fcffff9f3c74f0c0e44f791a696664907037604c1d9fe051860e51c60892cd33e3d91926a349a49991e1646a68e641c9b0e2bb86a780523495d93c681f3a7662f849229c4f413334b403ddb523c4483bce42317ef3056f194e345c97cf8ecbe572b9a490cf8da741973b0d6e41c3e9e2a01df6666f76d9fc4960760d13dbb922ac18f4536d1f4f8ca7458f025ac40202e35371d1def4c3c0dc97d0033ae39391c105c5d88a3e1e0eaa28d58e50fbed53ede0df9e5f48155277baeba672506fcbc2c9c582f196a5793cd4200a6c834bb027f433d1fcb888461ba59a4341d3aa54f854fecc04658287ca5f68233343433a8310ff1ef9df4f93fd7afce3f7f32384a948912d32d4a7715a1c0edebdc0daa06117b64610ae2964ebc2deecd3b08d0bec09fbfb855bc57ef1eb582816317fa78f7eaacf1f3e5ba54a75ff1117ebae52e5a8ca67cfbe3b85a3b32cee0fecb97e347aae8ee8578e4a49daf863588f9f3f9583ab0f4c642a476318b61206dd1b8975330deeeeeeee763b4de7d90467409b06411bcf46468ee338ce9b7783a1eae158f2632592df0f0858d46b38994a01e3662a076bac699a37350fb5715b2a7aa738b5198cf0054fe3540ecea3810395ca81550e47f584ea0ed55d9f7dbdbe70a91c5db9bd49e5f0caed8d4771c0487130606052746fd893c1d1e58895c66c31a8989898182d26262666c6c46431588c8c311ed3311c7302bfd8c50cf38446514336e2a1d496cd07206088edb3623cab8028a80ba7a7713819266e18b8f2689c6f4229527f884151a4d07c94204f9e2821c5b69cb9a0092b4840b97b70c5513061b27df49db3bbce93a06d65a3fb1d25879928534cf041fb2c15666ef6d2ddfbab06757a1ba73b7e389d7a7737b66f9ba0057dbd48e04e9d3a75ead4977a0f9c301a5a52d42038a345431eda6716d72747c4a7c9556471c2a589cb15c58997902926f880fa2c158ef254c3a74bd35788c0fbeb4a297d77e3faee7e3dfb294a09ba27ed966977386b0e58e065e7c60c1d68b82e1d3a74789d0e28ee2e82b8bbbbbb5f5ca675ce3f7ae156d9dd940b3c4629dbc4141d9d0f596989a61a3e85120528dddddd1d73772cce06fdf7c6bb2c8d954d83fbdd206f3bb3733132d6e43b8e8a7083b92ba0fc73ce39a70735f161cb8a4667db2fbf95ced3689075a46c273c8912585c477614bfbb45a8abe4a40b126c9c34dc3e3831738f06f97d70f5f1e17e0f1f3e5cd0d91b7eae09ede183db6edab4695d274772024ce5e70f003f9290cd86ab2c450a17b91e9888a0438cbcb8ffc18ccf04e59e8d836dd7e5f4fef7864a7bd8a250d73d46667e0c8b8286ab1d5f89c2737431f624185058517612d0fdd5f2036b4728818222e2729520690853e4c95a8aa281aeb866239818824a08945c69024915282aa65eb3cfde8c42775775f7bb068ba06b43164e51fc553d9fe09947d2753c14c5a1788009e7c46c2b3498f1a8c094ca39ee72a171f6092447955f5d7a340eadccad2a4f20d95243bea18519ba204de1691c6e41e5dff53929f51b0d12cd5fc5b430c405f2573ea2418dd3534087a2108edc5d623724e6ee2ee5638ca57030f67247e28e64ce22a8ff7f838d6152a83f867dc488e66373ce1857f06a7a31755d47b4f1f4c47f148ac79c3c3c5e3d0db644794124cfc67ddb1666af6def1e797ad9164476332fc398962512ebe1c2d7e8f9e8ae9bf3eb71a3c5850665d6c37d9cab2138d3a0fc3ace5eca28d4ff553bfcb3cf9a48fbe8691a57d983cb85246bec065b92b610996982020a8dd31f3d09e5e6666460cd38a9410d6d666823115aad5641336040436e794f31826469fe6ab55aedcdaaae68cc0f5ce980ab07e90c82814fc4cb781a3df6b71f44dd403f05ada599a56e0a0dbb89441123468e8a1c0d79e9ffd93ec8d6e0efe7c0720ed0a2096d203e9e0f8fc70edbe8a0da3bd9cf148e2835ef9be1ec695a8a086ac842362d90866090bd41816d70604fe86f4d0b7a544316a2c12d579cdc9091274f505f3c61c26408131f5e0d2ecc0be8d72a3289155ee136c5cdc1beae03f766569bc69993c77baffb81c61ccf1e11f68bbd7fcd7a57b520e857285f549957a50d7612342b92e4430d509200a19ad0cb01326308fd979ca67d7326314b46d33c63b5d7467be34e360b1115435328b122d4519efc3d07e6b51ffddb6bbfed0dba7dabd0bf793d1af427a18924a954654b65a52a5dbad544b0df9e7a305ebb521e6aa2e69ca86ddb8c3a339a935277327ad0c948a7ce18427b66764e7376dd3f08ae56298f480af56d3427a55df7afad3414aa7bd25ce9289bb398b795ea0d45f57602c6f64e1fc6c873603c877eeb35309e4e08528db37d1e6e40088c944783609bf6dded2814aa67f6bd4429c95dbaa687e74c963b35e8de46d597696ffadd488605fdfcdb8c21df0f9056cb63f3c72bbc6373de6b74f0146b65bef6bc537fec07c16ac45e9b3888b26d93d8172e5663cc767fdf3518d03ae3ea5cd1073dcca3c10e2af47ba401bf0f08743ffcb8bfa908ec77e353edf874b8c2d54cbc22290906f47f65a48c0da5734257980ebf12164b4cc2201ec64fa741ef874c413ea603f641bc4af9d9476fbf5583197ff9f2e54b10af1c0601f9e964afe3ada47f343a67fe8d95ce8e4605c90674ca84fcdd395b4d7ff71678b6c68ceacf23dc205477ff95e76c1f2b995f94b287c7c7f341a1fd27a8d28b51a5b74b489654e96d7553bb37b2ab52feacf263ca5ddce3c6dcf3afb6c68ccaafb33524144e705f0cdbb75e83fa580814a2a4fee8f7d98c6be6bf59669dab95484a438ab817b2f5fc0889939b3b78da41465da52737d84149294992ec411ba4f7424370b9719669869716297a9c148df3ae55f73abc867f7d76097c2574a7174e15fc4b5d50872ff9cb2964ca2ed5ddddf1812f35fc69d5fdb80abae8d75daa1493d1578809932f5f5adedddddd9ff6a8466d956e8f8d5a4dfbeeb92f1eca300c23e6a373c2501a44560d45436b9e0685a0daf7a980a23e5c0939aa3fb42851da2729d79e5909b51feb2fd4deb5cdb25578f36db291826a2d8b14b8fa2f14285d52529ea4a43cd12289249ee8d2c4d2d258c9501aee2bba0e349c759bb33f206ba571c23929dd710ffc81f21361cfafcad1771f6c20e857a41454f9cde840c30eabc293199c407a6bcca8b1f6f311b5e75c7d50fa7df40616e7c7829da385ac038a66a95dcd7c41ff8e42b9621f0cf10b7d364b8dcf9a4fa4b1eb86b74383d0b75016640213c8c8ec1eb19732945232b38c531e716c7759d37380809a00654f81eca380fcaa3032fae7de70f4ecb47f2b30b30068a0fb11e8df0f05546a0876529c862a55765f3c7834b83c1adce769707757fe569b06b7f31aafd9d75e40bfbf705d2b2846825acccc2c9955df2da9115d59798286da5f1bb1f7d0f323a4e74748ef7e1c04ef0a614dec8b086145212cd5673df1e5f7133beff66e2a5c5b2af69bc4e54a9dbfbf836b2583515ad92589b667ec53fdf601a558d83ef5a90f889b5fa722807d60830cce5feda7170aa9a1f6a86deaeaeeee0b3f2108e67ae033f13fb29fff237b08ec6826557e33a9f2db3ef3683a677b17ba66f6d042c37dcd6c57270e7a784a32425d2514e4b0bcdb02ca7533b804e599066bd720af409edf1f00196cc006a7084f34039bd3c2fad81a5cf931b038d10651962455dea6ba5d2a7f0536c747f658d095e734c19e2bf77eac2d53d897419ca05ca5122ace2dd719f639b22f7bc9adfcdc23f27cba867b40df091535d4910197989d6de1bdd2c44e287f051a87824ddc6ecb8f908406a8fda1571b209f90f168b0f7b5e2b1e113da3d1a0dead8b08d04ec09fd08c09e5731a0a83a27a5fc3d8f5461bfac9edec67e56ece3b9c1b59253583e494a8202a5698b1042114350ba326504fdbbbbaca40b13264aaa50a7d6feb033298defef1f90d7ac8a05195f7ecbda9517d2ee419d9d16dd8dceb4caa2a32d550175a13852523718fe905570a4a4822e5e18cc0b6630fe19ce9959b675f78f20723d7cecb7e6b01f52ca7010ab7f22848c0f50647c80a2a4944489a5244bfe5c8f80c2748416a10a0ae84f038b653f9ffd1f3e8ba5fafbecfba781c552fb53450985727f74f78695800285092682824aa8abb484117fc1822d4f9858efa44b19dd37c77f7fd0cdd05ed6c90cea1ae999f891e5ade195df8ddce539f15f04959f1da9b22fb514d82f5569d506d45daa61a8ee60e4853f7b8b880921a0404dfa81e2cf0f9bc90b1afafcecbde51ee439254041819af4641f1f0828eb57f64c2a16a26abf9f263dd8c7e79ef8fdfc3451f1c49fc0b2a2b601c58f5bcf3df60179150bfef1e30784bdefa77e59d293f1531fd0fc38bf75a075e2b2f1901050931eedb1073202d23e36f21a1ed201ea63232ed8a7da4f4581f9d8f764af7d3f4df6b517c2eaaf67fea878522f84c57d13150f50931ed473a5c04f10b3b09f8159d803a154fbc1d0335ffb7e7a780dff0496e5e3e535ec427db84da9cfc96bb2af5b5e93cd07dabe16c21ea5f1872d5419fb80fce7a7daeccb1e7b1632ec81e4671f0b1890d7ecd74b610fa528e0ef4abc865b3ee42da45ef29ceea55e1687def21a969605fd1a7aab72f7521f35c84b6dd420ff26a49b0a4d71bd76f77f47c78d0697bf30e2a8fa57c6f622e8462d647e75ec34b87fa5f2f7f2224992224746a4808179b98290b06dc9d6d86609d6060a3bbf79a8a75e5f714531c462c2a47154dc6fddfe432ec291eacd9be12f64241aff16c2c9698855a4c4941a32d2875cc4b193cd0940d3efa618bf947ecca7da3ee637a0dba8440ff6243154340300000aa314000020100c064422b150389e29d2247b14000a73864c805234944643591224318c428818420c308400600c101a1ada2600cfb45151019851a3f4ca9642e3cbc9e9e230c410bddca5922151eb6290133dc8040710390dfa9d5f2ee64468b80d7bbbf9b50c6a5f8db9db7bc1bcdb5b99a8ab1417d21efb8839dd7eef530afce31d0b0d48aba7fd31c98afc201dd4ad87cf68586ae87da0b73c0051f036bce1c9f10bb9d9ca75d0a548cfc2f04b21e143bb30cbabc158702965b9984b789d054b0fe099a6802f25f61e62abbcaea765bbdc3e6cbcc26b135de1d173f2bf57e8fc0fd30dfe28c902297d465cd2c6071cc1711a58b54da2af8dcd35eff98c8983a40eba74339db4b835795e46ed6de5bf7680a20161c46f356cd46ec6ace0e307005ee094ef35939c959e05e7502ed346a00d948eb664b84ea0fd76602d2c4df7c0c0e85432409a2e4ff07d3efac79862deae4ae6633d0f8980bedf9e1d6d4f3f185b9bec6e75b0a20ac2292149b94301ff592d1152560019f0896466a9bc403f9a3a599624420d5414ebcbb4642be8297680a4394efa251dbb909bfb856a465519e302c1d58c73c26f1cd072508acb8e4f6c0de5976b654bc022c0bf059154ec50115f6a43a7fe5d5c351cc885a1c8a568492fc6688f56678ff62d926b0cd78a9db13e0437b320f81ae1533d5d9f233600ba074ebb18800db48727f031e718641a090c8c3051827e9e649f29567b897d1d03dbb5b1bda355624c9becb19a793a07af76844b36b903f3eed7d13bc65189837eb28f5a6ff06a5ae00af533206d9a0b10e636db6ea0df0585da3706480490c8821838ff5b65cac4af862f75ab69fb17df951268f7ace8eca935978cab224883c18b96d60c48f77c51cbd60b0d162becee62040fe7e8f281813cd569aee986fa4a2abdcd66322ea8891ed04b10f5ace5e7bdad198ddafd2634dac9fcbd12c25e01de377a1280ad60b6d78717668c492518025b6363f5666e28537bc547ce8f0b61814684452c48ad1b77e60a60f81578d9710730185fcd868486b2977a5b38bab058db322207ff6c23a064ce0472356f9fb72e5d0769ce2d49b3690636f2adb9e9937e03fbeef0207049a13003c28153d0762e5eb25e380af784f8966daf63e9870d52d2787c02fac858b4c47d6105379ae144801d963e187d1cddfca6730e8bdc4a816e28752552286f7d182c57429cfdc376ef3d673a9e8e43080a275dba9512541f6c2c8bdb9bc08e030479e366609660917d9dc516f60c1694faba7be3b49eed38f89322139d6bbf14204b46ed3c8c0477000be3d3e3a8529c1983019e5b87b7362baee849a4e7bc9e5798c2979f3909288113db26d78ad91258c30585b7fd390efa1a9ae0ca5af938e648e1a06021a961ea51a796e5c29a0eda16a72c8b298aad7af5badfb3dba5fd94f5da8ee00ea751e8675a6180e552e03d9f01cd087876a7bcaa3266fc40f652ff305dc5cb87b22b7f6f32c7d0a69ed5d56baf6924935c72733ec42e7a5342072a5e0c7977645060151b4ebf484ef608807c17baae0cce493f20bd65f20f3d00cd5857f5584a05863760897937d0b04f8ea5d85cf263fe26341e0d0896fcd69d58dbb6ff00514d4cb0ad7cdeaa005bde134efe0862e7ae15dfab73e63d81905206e6363ba1a3475e15bc721bc90e92568481d88b641266488435d6d3dde216eed4fdf199359e04c5ae0dbdf5c3a50de72f2f452cba382b003b584abaab53659757b51f6ccebe345a9ee57ac148f806c0f7a4b386e32a765651a45d14b7405708a8d8c7114db2b1e13cca7e9ed21d465256c6c1a6d0143bbdb3600287fac95b9d13b4cc504ab3e4e5d97d5fd028ae8a92557592f2012afe7990db1b9ee1bca96ede4d3c4bbdec8c979ce08569112729833c93d108d91b7e0212ff9f2e484f03d297edf234fbb4f1833a5628b9a1add0ce938bf5b50b1399b8341c17ef00520c6a10bcdb878826bac303a286e00be168961dcc83115f5d1eff3521c85569ea590cb4da5eff5c2ccff80546487f15e8d6dedf2a81c60aa8e103466dc75bf52c691f731dbbeb9044ffe12da857b36d23007136e7b24f1d3db28db579c0470ca200692ac2a3bbb79abf16aa53d97c3d4b2dcff097bf68563d9dd21be546e641da3c60689db8417fa5fc6aead8d4484fea1c55ab3a2b24b851752fcd4e74ce7473d036ef03a3df503c2947de0983e82648e7c9685b37f8d246ec786157689df0362f91b6887737efb7f4acea4707cae198add6e9e176aae46c956fd416bdf44e8d4ef0c1415bd8e305e8c3b52603186061dac74f078d86f0cefad81b6524dc9e89cde71bcf73ad0db24c805349958a17922452adefce8cdddaa0eb1f553b006e6d8825a41760241c8f45e6805cf5aebb45000187fc99f2c91879aedafd7a8eaeab9db19ae57a65fb9ace508b8253a279d96fdd3dfdcc9ddfa85e0a7fb57112417d9e741625f337ce2a6569362e8f87e159952ccf799783c830d5199443e66c30e0fc95acb1b431a30ae451a56c94e98039899d9f2ea24598cc7b3f6d363a5b6248425be3c213165574a24b8c867a3dc4b43643410a826568a0e1891131b22f42006136368ad666e5d429a28e46473f157e98374559d29223b4a5314c4072e1a8b0080c1c1073a484f09504e8f30264ab5c5c1edc05d8e2f9fbcd4b86be5b6774dbf3bf3c10c51705cde0ccfe45f19c056288801e5768da31fb4d112fb4a0a827164d33526bad5c4a38d966731f36d792f3636c50267a092c5f52150b665896f1941f2d2a6aea15033805ea2465fafdfa94d2450d4acfb45e6c91bc48c2807b50da164cca7d848e8211656ab39d15febff3678c214ae11201b4beb9ae8b5f075b4e17a0b08f1ecef2dc53624743e20eaf33da156f216532f64a4dfda7e2f98be5241c96426e9a4dfc500dce2f202e276d59ed82002528555407d9a8b216d7db0e4c79621cc76579e6cc7ac2e8ddbdf2c1aaf8f263f0002b0410a50cdda8eaee3fe413c1d5ff6c8b55666e6de9947c21b952d650f112abb16af715c9b3525a59415724ac4fd808fdef64de05d91f43a10a36da60d2e847e3694f82686c174a00c84de0207f9ba02d20b1e73dd60fd645372245041c0be35f37a46cc77b83240f882950a6912e1be9de86b355c99d87d880cbeea3426c06ec937927c65f4edf5ed52dc224a3d280714ecb67490569c92db668bb78c7ce42e41e16f28089611362e5ae459d1f105d11947dee239fcc91350de0e42946e0f202308a80445749decebaa4a7c13f634acf318b3b0a74327ef2f7890a40162969c29ed09152804966498ada0e7cc6c2d3c6345647c6f8ec41093c7e30b0022ae3111e80efeae238fd5eb426c3c2cf35f81fcf370fb93155754fe8763d7d32880ce330beefeacc904feb219491e1845e96a950e2523a9e6f5229aa90132d071b8b1e9cba1e29d56fdaca15c0b940731a31176ffcf6f9c3ace50877b5f3e2eead764a2b447442af776799df1092c83f7bf9b561783321e18ff9c82fa043b7067a06a1a7cbeb3a534bf9424a8cd89ebfd375ddab26c0a932800dd0000d53d4ccafc649d8ebcce4a54fad78fbed1f4616ca5b16100def77b8107b14ab05fcfac65f23d81abd3e9a2ce180e3c10bf60352d6b1b460857c52c3210baee9715b94b39ecd3c97e95f5e3dd2d7babb1e6c4eec7fed7c6fa55d5c8b5d615314ef9e36c6c34427e5a7e8fafbc99343030489ba20af84c7c3fae2cff247a234afa1f9592ded8203578b1f80eff5c3a07be6d3c0a94131fb4c10571c8379d0d422eb743a993848abd36accd3ed0629e262279b3950f20061cf3d99d8afb7c0918cf1a045cbb793b1608205c52ab32cb6a89361319f3bbd6b1fb330595552ae19954b7fca5433bc9e413ef398e41ac00e08c220f8b58eea709e4b90f8829b4287a2c770dedff1278a6ec97d1900e3c3e84e35db91841e11c3693f44e867f51c2188968a1a79d24aa8e41ea4ec0b9e6c9080922e1b75d8d3f00dd21cb468cc23204180659cfe07812fa7b171800367e00fae60590120ffba117dbaff94556f5f7dbdf5fd126e3cb1fef00c8893c4f60138f6863fc4278f089e247add297f86dcf4aa5fb0156196639901e183074eda75efe1c40b5a87f289f2e6a21c6213a8083369a1f835b74d6c8741eff024e7f1852c0ed554881327236c7b04e18d495a8e99cb22289207518d8d36e1b0f98522f4b376f0b30cdb1bb326f77ebd949bf354d052a1e52dabb3d0846d2f12ec85e44b32afdc50b8ef43e4661ee4f8189009517b98033f8fba3e58155fa77605fef0a0a04d5ae9224236d0c5228c695a48a67eb09d0c5a998bd281da0115c50d438f19331b42e51210506418e64064d11d10700c5bf87aed1e270e2b65052e98ddb6caa101c20b1a9f57c880435a6cf0a3ffea5c83694f2bdf6caf32e183a2b344ed92d9a54fbbc2d605a78edbc3bfa02b57da010fd9725b69f3863d0a28fa9f17ae66acfe5240d072e48bef1426f375c6d6875d0ce3c044eec0daf61dcab54aa04cd44f97fba40d4d88f30ccd08f26d24db57050c640687a9a199ccb1c2fe058325a4b9b43b3860c6abb49a6f85d4f6751f25fde8eef2241c31844c4bc36a2fa1f3e5867929f37684c1d14abf247ff53b1edc8507c0ff76464b68db3c12c3b5889fcfec2a47d0a35185a9615f8c8be63c95a7aff06f8f3318e5a2141746d8d41363251c386f09f4daa7a391f2e4c1a82583f4cbc73e9d5de5271786e73b2e277bb63d4a27633c902c7810eca6c2db134463b2ef38b21749c708e2d949157d97a645b792db50f23e0969064bba67dcb2ceb7d5aae4dbd60aa3097d979d361341146a7d343b42e51dbbebaa4eadbc21ce0f2815097cb0508c9e3ed6d8fb692d466bfc1edf1b2758e11f00acb397041d9f910aa401c476738145d8e2da15821c87acc3d95589fd293beca5bb9fcd1eea4cbec0db7de335e5fb5249b89a1688d9c40dd884bda315a1e55bfcc5bfb9370a17476765596d25dda2f889b8bc66868d209fc8638e415f0cada750ea232c6a793aa64e38c0d49a7412fe9948f31f867a0e98c026ba719eecd328b73c1f954f0b63085971cc1823be1ef9148c41c38777fa21b1ed374064aac6778a8a9e3dab4755928af5025237ff98b89661366bd702e2f70be7d67a4608828d86154271f9349b02751e0030a4711abdb4799d80bc9b34527baa6a58de8a1bff5e7fcbb71c505560c6e70bcf5c58642045794b7e85fccf924caf469f2e83dbd4dce90588ead3606c12afd46c1b6587ac8aecef66136370eaac6fbf9142d344448c9fa7f29a44320d8f3655847c06feef6d65a2a26bdc25cb2081eb7f98bb3f9feab89c6bee2c457c315e5d4b0c80c5e94b94ce295a31990d6a18b9b4fa550c82f1490a437ce3c90f3ddaca51e892411f7a4eb3648cd332b2f81a68b7a60a87879997d748887d5dd3a6a6578a98e8bc3eeb78b9e40544a4dfbbe2903ec7bc879f51b00e33e5b59defa5adc3aa39e668aadfc08b42daa5209dab4b9dba5d98c6a3f12e00a3c5b455d1506e110050a15f135e06790fb49cc5259a9eb616e600c4d27a279d6ec272f4b73b5a4f8165c2350523a1e0aa69ffff57e54147216c7ee780a0072513c430a29a1ec5ca7cf4ebb8e4595162380a0f77861316828ca47374cd61e3393b36e40f7c9e5111ac710ccf0bd6b0815061820adee301768752f0a759cb219343416fabc042357fd143dda81774a865dba41904349eda712121c5ded7ef5fcd131952c3d016775cb5b61593625aba23d041568d31cc7d4132f8fd644770a4a5fc9deb28d073f225a8ee7534701ba3d240c7a6605cbfd8155b27fc6799a4e1239e29cf110db55ce5e20b38c33b3adb49987dac8a5b877f7d067cbf721d7073879347270a528733971e87ef318d3386de7a77a87a212648f2fd6778de2988508bd9f4f2d99ef9a3f461229aa1d3aeb46581ec0f2ffe2ceb08878dd9c599a5b25fd13a57e698c332135f3707b5b9d64a0da08eae159bc9d605b683f6802bcfef7fab771cad584cae63fdbf9521db0e066432d8e7f17685e5f6fe92abe10fdde2151d0d2321c2a8148d10ff4138f63fb9b1c862c5f2afa6221472d14db06f9770028c9007c426e18658c24f6f4cbd06fbd1a5182c920c6cc4a2a2631fa4ddabd21e786ccb3215e87f24dc2c3159c693afca6416cb3168fb200029b728a23549635c8a8943b69ea89a113f57a448ac548c1dfbc747c8b75d888451a660a47e1c9278fbc5dbab6e843918d788c66ec634af895925d9522e9a060463197d5d80613841827bcc22d714c8643ddd12991da40d766314511d420743b59187815e1b06e63caacb6f673a944b781ae9d95cce0a684611d70e86428c421fa6134e00efab882b4e6e468b2018f6d59be986a198225ad01d20ae21a42d6006f5cd7ae06f67edd443201c274e99e0099bbc47c022ba01c6d8969872a5183c58397558e008ada6ee4ea3e4b80d9285eb390111fbd2a773d5e487d08a0748b5848240edae13de2db1dd3f0a7d01d8a962217a92003db2046e706ad27962f9f8fbc141aef1caaad7de40778b8b757bca3c4d340befdd50aed43b7ac2e1613bb337982884b47f75ba9ea8fdcb1968f939b2ab90f8ddedbbe17d3f345dca2921695425eba9d61b48702f17395e32d24263299ea9a35de8c49fd6796ce5342f1a2d26300d90dc789e3679f4109e7d0fa9963be5cb048786ff5559c5596e040290f1eb6ad1f4df3f93a01dbcf4855514919c2cfb174cc4f03a1aa3dc2a1dede485b16ac3a9749b9420761dd2d70ceaf04f92daff4be6f03834cc0eff37b38177a171804000d5573e2b4ce5998fb296070879f9f4571e61c2ed78598559c5b217c3c7866ce52e5998655c679f43ecfbcd055ac48a81af2ba7d151d295eeb933caa58c9f508c9f86ed675ba20b5cc9e7352208f939a103ca2f164e658dd01fcca7524e5e963ec9ae2517be1f69ba3ccbe8df1f65e565197ff9552f1428b0ee1445f01177f28af03ca6f3434c120f04154990a0f91f1090e9a323f0bae498b91dca3f14eeca78f210d96303343ef4235037418a9f7fdd72cccfe850a6e4c47ca23e4eeb9b6cee1f83647781cce9277b4f41dc6b7793e2b27c4c8c186688da8d4ee1f81f44245a10577440406ed496edfb96ca23c636f75489334a81ea58c438270d60dc8b61b5fa2f0dc756fe9593e623bfcb8ccd5516c906f9672c51cd31cc452606ac662ac1fe2d65c18798f40895d1016b98bad17745099d8645c16016153c11673d1cc2d05d083b08061e66a5a25ca6c07bf782200aa82f36d6e282f4d6bb036938e819df0247060f27a08e80b0fb048c7aea39ef25874af96b7cca606731d2315ef4ffae78280016124b092bf0e00c6d94c98ffc9a9ee11b02bfa403c2a9896375a501464eefe342d519541cb33d807b0ac8036d5f6ccf85f09cd8f79ade7570b7bce9641edd35654c38c3cec3b67022c40152d6d00e8d340025f95bd64b0132ab2925c7929cc692b5fec458a2fdc3817b24876958cfcac8cd4d3afcf79de99652ae9719763e3c4ca6947711581a25062f8bab47dfc0b20c171db507f67df9a22f28ac5ef24552535891fe7fbea4ef15242b2c4ef31df3494dcd720c088bd2cca466198a44f03c2f4dcd9a782b3434cb044e5aaa0f7512ef3dd32d9537e098b55dd33c18de4f24f73f7af927bba3c7915e1fc93a38a5b9f9e993c1c9a17b257b86bf3077a547bdc40fc9474384b0b50d912523add5ecb54ab1fc1e48b7154a381f5203b700616d3a34796103d0c49eaa2864ec9e4b7203bb0a3a100bba733d18e1155619b09619ce756db14e6384d23c2b4764a401285b2cf1bfb32888a1077d0de9f047a9cad26f6fdda22c65b947c521f247367586ba46ce3a5c1ca6091c677e56a5e0b9af919179a6cf9366722dc779ad4458d5adf40f6f0671a3f78d54a2631a6abaa489f9603a82f4b31bf70738f1e64bace59ceae66640f46b6e3f25dc051177594cddb84063883d6c6e3ab2aa3e2f5bddb894a16b25c95970a630e6f2fe42b5c1f11901273876310693ca6e19ed77602a3842f1b2069c01bcb13b16ed80d0342bf3de0b05662dcd10da1f5092a38c5894639a0db6a0e62058b00c53abd56811f7cecf3927fbaac1804853a478ee0d1b52121110e52ab8f2ba79771c864de8a3526f5430ba4ee8decdb81d60bdea0181b56d91a6ffbbb4bf0442f1926b3e8e1e15e71005e8f1a20e27e35ea76cc162497604dfd9d0ed3b542ba8ead33dcd7b830e3ce1b12fd1f0353f1f45eea6d62a423502b9b364ffa6b92dc05bfd3ab1e0deaa79a2e42ecffc9d57647f1f3e01ff4a3a7499f8d863ec7a0593a0ea4d94efdfc5fbc38c996df201f174f0b32ff6e8af22446eb9c2002d4a7b30ac8c6c5d77052bba7ca078af639a39f8a470870e57bacdf51018363cff4233633e5490930d98ae9471750e915d0a456e7f60a3f6c646933333c5eec11aa345457c8517bbd13acadd4bc2773c03ec7652e80425c68e8ab97a357ee35312ed0474bdb5a1539cb22d8e10a87c70eefd8b9f26994e8b3a14fadf39450459e4ad2136e58c5bdd44a861db1d8892c10e1523774f8321dca50264f6fb5fc4578418546975e68332dc42d884e5965be52bc45272020dde40fa65a0f67add422dd70d25d3ed54a14c5618b7ad30beaeaf6d54b9cc6631ba176a3e7ae4c6d4f70a8e92f2b40493da63b7c37a98861d90f29a462a30f5e2c4a7ab9699b0d104b1aa8279e87831e51ee3bfafc1d3358cb9ea7e3694269954ec3e8705d42703d664722059c47c1bf837894ed15e247e23dd745e3d8397cb728204482bdb5c614de4692adef7110af2958dde7144e0d5fa696fed12354895d931765794e2e4c16eb89b5b2265444bd152914f62cea7c9330dcb37f9a0e32aa0a9ff651562924fee39bc24eef1e5189f7bf3efb3fa6ff27c0009890f2db33c298a22c0cf419e576a058afefc0a8fb3f9078cf344c58f8b063a683f833d2d2fbb057f0982b88a87d2b3155cc32223d1893dda8a207f46777e33bae1f58b6973325fb613fe57e8001bff08f219cdb20a9314de5bbea6225b1e781aaf796cef47c3e826c414ca71f0f85da08b7fdce7fcd7613823103f6a17f4a38a87e144163fd8aa5bfb6230ee684210bd70f3867ee4154505b74f00c62aba397d81e42bb492dbbe697de556dd1d33df7de63ad51e02ef888121854a850f93d9a222629591e19ffe309bdb1b9b9fd3eb25dc1df0e8491c19cd6ff40f2b2da332896c368eaaf581c83e8bffbe8416c86c6a6c34de30966865e927895d4b46b931f826cc11b94828737435dafa4f9558dd97b6fb0dbdeb7b71397c106de0b04edc022cf3dafde623e9f5481a6b7502697268fd49fbaa4fdce873991b553d36616614ad0a0ed37805522e4af6a952c397cb54294f4480fd3a06655c15d88f1f8c2612bc696f874a128f4ff25468d726ece0a80468e08a2bb16f9ec681365690b7461db8ffb4445adddfe973b19bad28fef28d812069e3c9a07c36698ac665c9a4f77c57fb7670f9279a8b6fb030739b53fadd4622d9323fe0254f06bb74c23982b0e2525db8b8d0a370cbb062570a2aa64c15210ba0bf5a19052dcb86ec6cd2936e927a013a45fb6914a3318c59041ef1d5ac6aa08b39c0d5bfb5cbc28ac0e7da844b0ccf03db957900f1952c60ccb413f53d801c15bec5d7678fc9f496bbf36cd20cd8068dba111307d93428b1ce410b3e2cdfdf5493d43a0b3a6881b0ee411a0b16e3a4e65350cdbbec972903ef25d18c8470b3b594044766593d887b211aebff1cfe9e2f022a56ec4fd6573a04938c9cc554569f3e8e8d391a8defc44bb3098a63dcc9595f43d73da9e0f41554fc9d7ddc23f1ca6bdfc60cd411ba7d8bc2c4ad05beb66e6eac530df71d59287b7ab247e52d74d27a61ce98a4aed40ade9eaafdc282a8e967e24043f299b5ef2705b5ca5c1b34707c75976d2b0a18b785b3388f8b6ca340a7d3d8a5f7ca1e40e7a370d48066eb8a0a36ec4fd854aabe6bdc8f7431bf22cf31fdc79192a4003ef0bf40c2c3f4bea46609293d7b0e3eb8065a5d3cef62c4dcf053f12c1a857e65bd9458605bbaf99a93b9d987accd003841a32cb60351735979967cfade3c2a8a69aea7e9a0788b2e779272ce4e359d2e5359086f79aa56417b722f375b3477af4d2fa2df811a15ca84e2a2bb0445a452e70df980a8746d658a442415ade9985ee34159d30fbe95817cd58b9b27c87a077b011e5e8b68602533556d20e4d9d057a46a697d79882911c99949fb1d659f521dc3263bcf4453dab3ff94c7d8b12bd81d17e22a144ddfa6b250d6efd11fc906b511fb5541083bff7c71929575ecd4d830a8eebf03a136ece40351c6b89c2ad14dd6413031c7ec8c5407604f4c3821b032b280914ee9be88a57ca953ba77e3c83884e912425ad2d8a15a73b8307a72e696634bfc6b74c8da6498bc9153e8aa15383694d045f325b0765c1ab48ee88558366e18d46010a3bfd5d7595f9944e2e0f39b2e02a2190069f3396bc04d66ea8ee1aa719047a175048150cc4ed6b8745d147f1b6dd266e896c5ea1e93b357087837864f3e88fdc98d4ece64b14a19736483e664f945cb0e38eaf0cb50af122620833064ff7fb307b6f06a494eb6056b4ab3ab84dd8698672deb25c390b0171d19ee6623e4f47b0a9e64b8e36fb3b1abc2210fdba6f3c94138f66720a85be5e025eeacfcb80d75eaa9918bbebd914f998b9c3ef581b465445cec8541b96ec4d9299156730a0bca221fb38421ad31a90bdee4b4a215fe8171f531900830a7209a245b3a6b8d02854410b06289263718fc6d08a492ee5b6a506985ed8138b7e00000c6f4b7ded35e6fcea4f614b8916161a588355a063061c242c0a5cac779cf927a3f88ded44efd55f142eb8be316649e3b7fdb029a23d638abb0f68358877423c6caed110e57a76a051c287f51b87000acad0344270991de63991ab3ade4738ecdf6bbf48eac914086397b7032f61f483d83f535ec19a4e4a5eb3bf6dcd1efc4ac50de291e9a8d2d3f99f6b812b855ef641ad9ac86a9ac6336929de869c9ca0b6e2bbccd1204dbcdbc8dfa470f4742d783a92513f4a0cfd22731ef3b0afd14fbf05b5329be949ee4e3fd5d76c59b5804127cc1ef2c7ddeba106b33858f2f62305dc5b75951c395f3bf0f1cd4d54251db70a39fc6b631065f70d83454f6b5517ea49055b491cb0ca561b16d0ad241057f02007426e8148d9d4669cc47f38e1948816e8457152d3b59a74b315772f5a11ae842ecd978b150c20f336f6226bf0367513ac98201ba2465b9e4745740f3e46a920a75cc052b69d0d41a42c46695c76210d748f57e889dd77c0706ccb7d629a946a12c7c21d560b273618333411114ac4e933bae43c063e86672463710b8b57b155f96b2a8fe0b7614e0f6cc8bc9d76a268328a94b5afdfd134d42c35e6e35c506cf7fecd518e311063c929cee93f701844925b80503fd58513058e7308ba981b98fe5e23ded26918d81137923b5dda76430e5eb6e7cbf53161a160770f28601873fc0c73dd7b843142ca56ea388d8673a8ce160f4908c60ef0b49d2489f225c84f3c208c0a8e719e201801c19205156fbcf6926a8d60cf69d1bd28f65f80893a0535b4023c25d713ce9be17e4c839505320c18c2835237fdb6cc5e124c766e659a17637c6dad1bac49ad6919c8b7a1318c687513f876386da7e77a99c001be4499642d9922ebd3a302cbaee4cf7f5a9bd322e5c5ac58ab0fd250d4ce4987bb213ab5c3e75f07fe0d540b6ebaa8b0f92bc6d84770def2ce2c1c905e4e545118fd15383b8c7ace311869db2e6d3ea488509ac157328547c8cd2e50c88fccc0340c00948899be0306ee576999e31c0607ce173cea4853fb765f444a0d753e47f63d7ea6be648c1bfcc60308abe7d862c68a1a90a87bec1b8b15ebe16128d346b6dfb03a1a7ba90477a3d81a3bf434a4790a5137e1c7ed64304d75e026467be2423121e955a87dfe82fedce59aa263baa83a1da5f83c2dcb51292e5fad1cf24a93472c58160964f139e3242db3f75ffe4eda4825c1bde6ebd7aa2b503bbaad18072ef1aee2932cb7c7d854b2f4499ecac1a921e40c8ffb8e6fff2450d2e3430eb9018f8c69f2dc707513cf522d5734d2acb91f150a9ea542e5daed3449809f8e76723154e3d0c76ee4a656d07df3bb452bfd872a270db53e5439706fb6ff2dd88c435bb113ca57f2ffe70d9fdcfdc41340ad89803bbaec959dfe9a32d8138f176793b6040cd4c54aea0a34525f18efc6523faa6b3ec7e4b39eb491441f6ca53e69613d3418002d92f9ece907b50f1a8e3fe1c77368d05887293770bc692b02640d9e6f36d47c00217f4d199fadf75066f2fac4bd3a836de016d9b669cbb31c41d05a5c8a00b9d69dd8d1c94ac1092b891b7aaaf62c2e7d22766841a3bebdf390fa669791f24559dedff72c32fcc9c97bb9b8b13445a2d4f76c6971daa55c2284c41851629b88fb113f138a6a5ff521b34a845eed5b2904e8f5ee2a2fffa07007ad637fa7519ca5a315b536c909aced28a720d6f2ad62ea4c7b48399d27a32a20bce288e8ea3228ce97967043e7e1e06295159ab85d7d805e01e86f312834bbdffa02a5ff2601a7b2459ea9f030eff49df6d3962580917863f2c89e32c66d68b940c424f894113aeebb6d3e857c71540ae5c9a0dd96c491c43295946ad467902f196103d54a33523529cbabb8b82c04a875546749a7a975320d0c201ee704dcb30e91890573fe6348a0d0f37f79badebef3cd1306fc4dbb7db1744aa045eceb66fa66bb2e171efacb4e1f0758fc77b6aadc819b1a7d94d389600384b3eb4946870b5f9680c28e6734d8111ab4dcab7e56511d375aec6001fa7dcea48c3236dbbb80836ab9b6b5b75f4ec4eebe3d2e8d64c5ead9e6c0e6d98c89f911de90ff118bb6e2039f0dbb55bc820fbf9b436071ae80ae64edf5d8cb85fdb7b7a0e21f02d24df941da8c5010b5a27db34681e704391d3b4d771d7ccb471a303a258955cf4cca0146459c903d21854a91373d06101419ee3b52976496710448db0ed5f4b557f670ed2cf5a763b790e18ee88a8e2aa86e03a07d564a394ca4d8c98bcb2f2c48b9903d9344c4432a9dca485a15277155bd38a0aa3dd34f3b5ec24580b8cea5c45b2469ab8ba6cfefe3e7e639082aec95ca0ecd616ab9774b83a099c0632b4fdc2a23210486dd1b6889c4825e3285e0672f88f93a3481ed4e0545b85fc4ca31a2c584a2b4b0fc27dafdc337ef604c5dccebf69acfd0763c6d1b26c665c0616dee4dee5d2d7b80cd332cf84586382824072d7c3a9a71cf02f3406b7f11cc2004822701108c4636aebf80d2f07e55b38331b4e496fc05eb00ae9370d33720da213a1dde48dc65c94eab29da2268a1eee83c5d6801fbf24152fec6033c4fc55bd14b56223d5c48da0e78559c6f6bb31bd2fed400bfd6da3311e96839a62a3527a9e1f616124751451bf8e77561693f0da1f0bd30dc005aadeec77d4070778f469ea4ba277d38c871a2b8312f4100bdc2dd7831bff46ad639741fb1eeb69bd2130c3a20afc0ea4867f04c80d112909834799749b25333a238a434fe1b9a947110d260bcbd01e80b69dfd408101180aa984e0a5f99f2f6e240e3e8584ab53766170d13100b7c95960d0cd37ba3c85cf48055414c57ff8f94df64caa0d624d36eac6d059f11ef76cff51755531ae9dc235fe0b3a55e3a852e73481159dfb1471ef6ea06f97cdbf859045ff4dd7a89c2014b4d4925b96179739f0724fcb445bc3296afdb13024f9eb54be0712671d94acbddd88a4d27850b90c1ac76a4c255a2aa611ca2d16c58a383f73f86c62b61ef2be35864f9bcaf1a08b9b89a7605b93e6edd011875e7ca6587ef6cd2305199a5c4030c6341e559ff7d4cc87a87085e69dc70c230ca46327e718189dcdee089f7f72581b61e314c3b376c3072d8e75de464420a86f7d64d8245916e3d71fa7b1021f1bb1815baf4f4ceb1eb87a8dc136f17a8130228f559f4637a94295e9d951f1e3ac48c1a9cdd9c26bd407b6ca7efb78206285b7b76eaf6518d2decee7d6895b3d28e6e2873a896b0bdb5b18aa822e68aa9d91f1f5a70c489d5e3b7dd6815adb6482a3e8861cfc9610c1569f967607e0b4685861e6cab162d4ccc78072c72fc86e6325a66168442461eb5dabe01979f07bfaf80db00b0109274506f0476588f7c150d3c6a377c2aff2e08a7b316efc89ddde2b8bbdf26ed0876f478fe224aaf9ff74e094834deb59bcd3bea1e64c7bffd439d85ba11a930c5d53843701821a772254eca30a85cd43052341e72d19c7ce1a6fb91ca23fd3001ab526c1b9c0ed518857d18bbc1e2caa0b0b3a35e6a7853ef283f2ae9a2572d1ceca57b3169313aab34cd6a8d920c2625458cac4d57df04e48bfc16f8b974e178909535e26b965ae2ca251c881a995c6fb6206cee30a49dfb6e91ef822780527430c5ade57c0572e37f43d6a86d6a62211061c1b27cfd824320963cea0bfdc0e6123ef780afe27f4c0b5a3472cae09a9d1bfd5855ca6c6b0e214f2a2dd0104b027b518356adfb12dbfda7772f26ce6f9c98f0e9d8ef19fa4ff34677a3d233c41c0fa424bfa7e34261c39156d7b7328100db7fd1f3242db62172e3371b2735ca7d4e67d2f3b98e04a0fd74b9fc3f555e3ccbd3d024bb482758fd9acf44c8d88bf73105031e162bdb9ef7c2f9c08ae7f771c32bd945a0550e17c00f8c66835e9d7970f9850eafd31107efc955143254bcc9a67ba36013176080185504228c705d0a4e6c7c8f2c1792c79163206efa5deab2ab97b2986c4d8248e0b1368ef585981b11045edb837d014d0110c64d9eb5d79cde7192ad70d86c1460063f80abbd69c944ec1ac1758e2bd239bc49429300054f4bb0368d0cb30213b36d14c4386892fe4d10f19d30e075074f12a507714a853bbadf4f633ee90dfe85fd7939185afc14ce7621cc87e178ac6b9622e61fc09d29554bb5186f23447d8a35e9d36f64b2a0390381677a4dabc577b6dfcd942772eec29d51e1ff351e4cb792a234694da0a8fa4804d0892f4ef24cfadcb93c767484cb52b912a7d4eb8417e19406fa99414cdb410836a53841fe26ef0fc68933af2a73170c7fed35108f01157df71dd1156ccaf6f7540613e8af39196dda838705d60f1ed1a1bd8ad7178cdfe6e9ddbafc2e61650aaec18fcec6193ef860ba31bc6af99761f5dcde3972e45ac3efb17952a1d7be1792b06dc11928f60b54d856538f41ddb6d57e24f53c19983b8518c97e321720cbacda5702f6cb194e83d0a5a3d2342d262767bb78535b96134196546d064c927bb91b50e7e708f01948ba39158744333d441b68cbcb14416788596ce5a2307638d3b4ee925298dfac9d96475727a8e26a7b950ca53242e88bef7dc34be4461c703953cc3c2fece071e8d8bd5a74ede4b271735394725c28f45a3671dfc136fbbd19b37e834663a272b8421fbfc15fbcef3d18a2cc8bb4e9d9e8cad0f9cc75450148377a698bb949a43fa5067270e6c3f55a5f79da08b0c4a9d0fe4445f82b37497837ead2dece261244d4535e765c6f9ba336fdecbd48c75966d0ebd207289dd62fbd4f0e531fa24bfc4791d8ed5174367a2e16a43840c6aad41e3b93e09691f9923283d1115a2b451efe8a527e8f89b1401dde5161eb0a87f676894ba5145f7bc8b2a2a08e69b940d3b9ddafa9659ff272874f1562a2619bd04f93fde11c9648779c592dea291be88ae8da90c6cba989d911d0ab05250118e56e56395f634c2e4d45bd78d936dbd70100252e56966554caa6e51021d605bd76edffd8f61fcd03606f2318f9a408d03a2605117e2591a326f317dff9872b30104391a0a4ad3f54cfa769f4974168cba0f82ba17041a8135633708a68b665e357e0ad0cd7b1caf45e84ab0f1736336d08a7808109210fc5ad9814c1796bd82db351a3e704b5f123fe9f8f9d30d5685d16f01ea9ad21ca79c214d0bccc97cd9556e2e8d94295bee1131524afcd01346b482f17e3be3be5a9d02c7d4dd9b9fbfd6edd86f65da6905c3f45425b8582ae89049297d46363b7f0a544f80f14905fb306bc7fee6ac69ae40e1b24d9811f9661cec821e7df5ef5110f88d312ac5339a50a1c4e35251d94e0befb8967fa2b906744b832845ece13c1f8e630e1c281789b60ef09e9c5fcdef4e543f042d3c058b5a066772b240b5d1506d45adb3e8293d7b247ef76b1372fcb1ae35a16e24884204d62882f78d7bff054301027a5c6bf0cede50987f0b8e7b1fd76fcf72a8055e76bc52bc814310eb2c9f999e1aedb3766178cb05e81ca38dec64576cc80228e00f1422688ae1e7f56c4f6718692f1d7309f99cb2215b997012bed94b2f08d6a9f4b47e77452d50f50557b6e63d4f524439d35f7a054332857595f77b1ef290b42d4c31c1d2d039c69592b8c671bf57275e5bd72fdb56129954bd5fffedbd64402d9cf0e23060656f70b0d0a31e8ffaed2aa6c2a1482662c8f46b11d682a1835811d0095f85b0f3d30bac7b6784c122056d0058ef4406852339d8141a44eb7a01e4b50240b0b16812758d7e2ebf621afd8508bf8f427f4deb467574e1e9faea1cfb38ad45f19932eea0d97cfe312ba4295a37efdd62152ac47677754d0fd71ca9f355274246f366a1e88cbca7970d74e65d9b7ab5c1aa2ee4e950486a4f71ef0f992546bd326236bd1ef11a692f364788936bbd5a039b8e11df8b082a80737d102d88a92b79a8a151c155a0ca04d2baecdc0102699bb10e6b6d978714ad7d07e092e3a5768598071c76e04e187e285c6fc08caf8563864e91b4cfc884e532966049efb50323ebc8984d8a1170f37ff312af579f545ead37cc8eef25a52796100ada781da94c7b4d5a0a8bfdc1d6f7d0abebf4af09c70a1f9e22c4953a05fcfde3b16e7394e2a0ceca462ced744272ebf47d16d6063e87f730a673312fe1f10412eeb2a74f33410c6302bb4c1b86c2ff362fec2ba113538167cef340bf120a35ca65f74bb98ccc92f6e60efaaadd78fd5ac41432769266e7d7591269e4da2aec889a4a51cfb69ed5f66dab4d38ce39d8b380f7d09d17aaf2d36f0b264225e733581848528bd415474cf066a03503ce3e72bdacd10bb94a5ca304b455c1f0317c3fdb9ef75d7857cc4797b1b37cb05a32d05b4a75bf579ff595025390933fba4df0c9c4e6f3e9aaa423a7233167d7d7037cdab0f6a872c4cca02e35669bb252485dc0fc066d5d13b038ea9a4eab91cc5cd1db21615d00ff7f742a6b8a0df1712a3a74eeb38da4dea4a9104f95f3fe8291e355ac9f4355d4426fa57ac340ec7860043d027ce62a152d54d94e5ed143590344f664f1c0dbdc7b9ad532c277d76fabd94ff85b7f5feecfc3ff9fbcc84c294b073903ed3d098c2cdff1b0f2ee17f474af20bbca5084ddfe2301f0b7152df30e6ed3d7f2bd1c49bb320050c40f7c4edf9666fa385b458bf0a6a55b34d45f03fef9f72c2dfba39890428084c51a675c2507dbd760ac82d69119bda9fb7a35d321ee3bf12c589ec01ed324e05f8fb22f0271660972e363313a355f469b380e495de7dd510fc099ad40ebb169dc1a2112be88a0693cf86dbf47e9b81d2444dd845ebcd236e35e9833c08ea364c4c96456e44108264cba85fed342afc882eec2a273e9b83c65c97a8bba1f51ee2f4aef6f07a96c79933ca373ad08592b8f3f8fae7dc427b363bd8974e287cfc41c8aa62f666bb993d92da350fc1a0284524364fec375f98b9a757959ec0934a34bcedac2181d2ce390f79635b6fe0d3a2f65e471f65e1a99a702a5572b3ed3bb71cccea078c5aa020ca489d505e833c853dd155989f9dbd5619f621c579412d7641ebee51c2c548886a8a9ad18a9b4d4eb102e780effe4f8c28ee094a08a60fe4b35be16eb9c17dddfa30c24e98124429bdc06a4ed71919ffecdec856cba0ab2130739d9ae3267be008f4189a38a1d5370496e39c27d8ba01e975b55e9cc7518654c1867193d074a24b9416df456504780acafaf9a033ead10aa18bbc673d4a562199d32c08f0932fec0c81b941d8dbca840abe1babc68698ca2456953b45abbf823aa18a85a35e66eb7307c9cd4f29c29c4ca55f7f9588a885b963415adb22d0f033fb980398171b15afd2c52a8aab933c2805e32837eef01dba94012a18901e9ab0bdcca10eec7da348bd220fdafd8f35ff27f4a41deb57d04cf8b7fc12b4492f401b96724808ac44f263c40bdd650e945862a2ee90f556bfdfc540c4d43e49581460b48ec146ee9676156feda2a23390a03ec5afc990409e48bde24d00e1167e04f8a2c204211599d378c41cf0dcab8364ea75885520ab190cff3b324c7deaf16b367c17862338a1a4955f87da0a1b5da4ec1cb545d060458dd60fce281012f13e719dbc4dac4ca7f052881123ad6d4136d22e2a4225d85bb8333e9d1d124eb6b15870f57f63664961bb2ec86cc7967940f8c92d04191f2f9ea3ec4f963038bb4c36245e089815874517aa53cb20c050d6cbe57380a65d74b3ed83778602f3e53190c7b21819cb1f2168aaf869a5c57a997d9d7cb2b4df98b2cdba73d1d7742bcecb5beb234b00b6a79415ac596378e61a5953c801c87f467669b355b31bd347aadd7f4f1984ddf9d1de95bab69f2393dc4526db9d8feb911a9dfa805b462cdd825a8eb15864bed323e516fa2581880094463fca5e5f43467cbf4102874c0f228bcd3009dd05c77860c34767e7b038b35034bd705967ea781efa816e9aa97c7e93b4bc933ae9d418ceae0cf2cf42e9ca82b4a8b87045d11dd2c244d9eac00ad4897b9b83cbffaf46f91ee00092e0e6cc7cb533ff384374e05609e9192176f7665f938007fefa9750ecc4ec186d6fbb355a974dda7d9d97d1e9d7ae666b5020951f2d56f9885b9cdffb2f1b59d39743aca9ca6cf1988369e5aa6a0f065b1b7b9a1a81e4f0b77c88a87d709f94af9f15ee23b1c25a28cfc944f4b3dbab1f336883d86380bceef246126f0228e6ea8aa1be83992b91d59e2188a3c0ff1ea6a68b0b12480bd52720e6f2e681cae1ad9b98fcd03eb5d2eeac5888d50a71aee9f0387e09b1467ac24b69ff0364f3ee7e531d0f846cf37a4e36d98e1a7b608feaadce873cb6ef24852cb88043934c3bcf28c6488edee100de2c38af1f8b795f207a57fc5be0f8f81bb0326b8c3f738bed181126f103f20dc8c0f4a7a796fe89858e1da184e7676a2a38f639eddfb9b628e8cca1eb313b10946cd78b4c102aeef53e503119cd142093924846a51e32adf82e51019d4b27598c28b9fad71e743d7d2356dc984a544a7e32a79f4664a7a367933fcc25e818369f672734d7083dc68c3ce667afc8f179fc3876d49948142ce28a279a32a48241ee59ef957c14ddb92d327130f14c315945690c21021db1b571411cd8ae6ae61b042c046020301e89080f673ee0eaf721152d4386ec1de5f08ff8893f0b6bf3a665050703231bbbb9e516f057b56040e1e68e139d38c7c00321b648ee97ea8cd62c2263cef0f4da533140f399631fe3b8b081252414d8a7af9ee09989d1845f4c719c0f031a18f96ec086c1b0383b143e7336a910ca8183b112cca18f2f0e35da8d8382f89ef22a47070cf204c7a981b4288f697d4be99e7e6658652ea6ce4d0f91b2827e0ef18fa6531fb66ed5991218f0fae7fc27967abef1868c4aba354227d4cd408b1fa01921f6650983ea133ebe354c19e694450ae93f9b2ca7297bb4e736d8fc3b50868eaef9bd86ee2ef58ccee62917978b3d4d00dda33a215dfba9328c029b31f5f4e8df522ad3cc211e7e0a988c803ffbc812ea5f0173a2a4f907742e408498191b5a6c767cb377870df4755281d5a3ff99ecac9841baf88b09b45ed6ce5c976e4ef7c7f56c162b9098620b922a20c464d1cbe20d34e637f8624deb2269184e9bcd345b88c40dfa5918a5e4798206cb82739e0b1c4e9cb4106039e3b1017129288eb15a09aa50cc0375c12e31fe941cb6918121a2a1fa188ee45caa997066e256c02c333b3edaaac90b8199ce11c06dc62f18a3a51042957146f2cdeb179c8171f73f41a2694d6e65a79c41a2333e3686486137b1906099395164c3d845c06a30d2d3ea12eff1a6da440f7dd34ff895753bccf3130122cfd22873a4daeeb90732cb568ef8771f321d1c6086049765efe875f10bb7839d43b7dc974a4e3ea6b063d171a9128e4e983633dd20f04e2cd64584654b45e938d7ea7f08e527e2bf0f0a5b462db45d89adb7fc61c553ace880d2ca49fd869164402117ac28dc87c5868bab71fc203b84f8210798e72de57ea7de9585ee7f910f4e9ad053bde203cf43640496f3c73443fe4a8915d2196053ac175500e940f8e8dd487e84b5bd9e107b8ab4ad30ef8d69632cdf039e433032622b0c835fefafa45d4f0c41b2233e474107d20b50485da81339fbd20911d59cc7d9dd4bc2e0b47f3b1b3ad42374c0ad08d40626c076a1ab66491377d3627a17b984ac04d13aeab1bd4e43040060903d391c4fef60a458438d7c2fe63ae70b38fb8840c2329f2fa43aa03e562df0e1629abe281f63cc7c2d8a5ac7b075a3c2f162aeb086d9e54b0c5ef6134a5b4db468dc77fc1103a92570c44e648ed4131cc630c4f03e4b2f9b7511420cb4c00a0689964a070dfde5cf9a82357cd17fd6f574e4a26db6d8d8a78142fd45b5575a21447925d7a6256415202a0ccec04bac5a174a843b202522cbaf25dd125310a691bf6c04f83ae6c306b34e697b8337761eb6eff4347c62e9d035e1aa30be9b033ba311bf85cb1494fb70c6f23fe780f72db9c6c8b4f8c8093c516fb6ccb982db2eef75239e5579868dd55643c2ebe773d84b4c3b53feecd86b8ae70ed562cd9e7b4339fda497f2dd35cc8c30014654864a1f5c7568bb31f1c20ed38c947d63a1b34706d01dca23543b96eecd5038aec014d893afdb0179a73e5d7ce0287213013b71d6a2b2d3d3329482c9903bfb397f17d6b511895c0311840c6a055b445ea38c1154184fc64d8596a1db590d56b5b888fb9ddff83c083977a57560821c66414ec6de11f15a98a0b3d853df49d1c8a56026226e7e1e9bb3c3b716dfb864773c06cbd39c5009d5abaf5509955651b9f246d50f64f422887de398f92aa79f5428d4be9006bca81856210b7781ae9bc5ac9cf2de3a22b4197e57a2fe3619569283b606b446cf0422d314058f148917e9dad43265a326e590a0451a8a35dd9443269d858a0666f34150da644c64d8e4745211d013009fe4f04dfecfd7447e695f12454ef5b7c9f3350ff8ed0761ad73cb4871e2d22e6e749ceedd5321ce6012cb316ebaa05c9dbf9d5234a75315ed5df280c1ca916e121cdc236871361097716fa3b35a660fd5729bedbd139ce34db8ab29c177fc656fcff5af6d21c7c4995cbe4e99c75a567332bd842c339971b63faca21959943f7d2ce2e374286bb8d06a5582151850c71fcb441b50bbd256f34a23fa2283909e6f34559605293d39015f52c82df23ed39f8c37e6c15c94554f3a5e7d4c593e806aea1ebbcdd266584dd9148645c521261dd70a108b051d936a9207bb082cad684bcf30d9f36355c13169c3c38a279e2e257dce65d7f8c60ea11daedbbec5ef894adf4044260f15a2a9e4a725805d866121f171f384e666ac0169d0e0d5afa616e58f48c693263559aabfe6ab7dcd9632b481c40770b702346b6148b74b6324cad32b362398b7dafbdbc8633364186bdc20d0881ad338f73b1644a663a7f3c290a1f93f7e0adfeaa1ffb3efcc3c20006b3a4b31cd1f5c3c01db6d2ad1f418e6e78a400cc1e7b2cca06f8a391b1dd1d9bd35de692a06888d1dfab601c37808991d79a6cc5e87bf936bfc090865ec7afd4dd335e745523f8803abb9623d54a3a666d00d9b0353910b30f8afcb836ff7c5ec5247425984460b62f64caa234755d85970bed17782fc7c089a19a544a880b1eebc14c363ee50a9114844eb83cbc19fa662c39d58ef1bd82f1ac7ec5b29feaa1ccd3fcf197647048c8c9791f38d39c58d454cd7b694fe84eb67c3357336af946ea23b48f154c5512c21b227e63bcfeaaa04ae87e6027a380a5b706a22cf853a51cee12fe72e7ca7ec50de09676fd36926998d16d33f539dc1fb59e43a824411497b2ceecd1aef0615a597ccf57709ed27e7ae885e49a9ae992c9b5aa05165db4b1315bb997b4906519bddf1c8976ecfa6af7c9b7895272c2c0972203eb4d96247568634aaa85fa93e304e375341dad0e19d94eba0e1774f4095f3fd82a187049ed8a52ab1ad9422dbf3d9b6a70ff0dc527b19dce49b7ec49a0b0ccdee5d529a4062de19ee1bbd980e6adf3122d599344ee2371b4d7f15435a527b09d4ea3a1f8ac5d5b2df9a01390486a5df421a7405f806e4de1de8f46cc9e137a1b0b7c83ac53e4205ce2e7206cc2bdf39b2164c3734dadcbf2b669fc5b15bdcf4ddba31871963fe457857ddbb8ff884d7b0399ef0c604df356decc4cd68717bc29fb78fc66a11b367c1efdbca11f4bae259a1da674f5be6580650ed7b5455aa49f3ff325f9b370acd31bd359165fdbeaa13f31a64340ae631efcad27eda700bb479aada4654d2a88d7884547ed4fdb5849e2e5974fd7a768d6a740140efb3b52115675ed730c5f8110a6ddb6b884370eff78261cf9ff8ea048b47e2765d21126777f38f549c67b10e06cd870b4475aa9394c50913435a7bbde803d26413ba908cec5550b3f0e1d341e7bc88c15eb715925e66b3840b8d2dfa65045699c60b7c4265fcfe59e7868e6958174d90177620f6e7429744d95f4310320332dde683bc5576d9917c72a4441db07827895c9a80f83b5c9bcdddf1529cad3d7b6d385da6ced6ca54c41058c45fd624ca45acea8d4e8d397a9a743ec6b38943659431c2204d7d180684136a4a3d61b446400d9de162ad632f6cd01b48ee56e0e3b8043fc1a37f38115268ec2e3712c7a263e27853b6bcf28006b4b2f05d8e945242de1f9ac69dc96b5ecb6a9b6cce2cb9e61f4647f9065079f8eeb26b1842f4f26ff31aec8c9d601e2f3d42346b2e39ea550ac438a2292fc4b852f1ae43c67b25e30f101f8baf9b6004e0604e3dd88f067c0fc3f2f39d960f1f20ed173674409b6597102a9f6e14363f963d7ba694e21e574b397d501c89d7cdc1f17017300a9605e662759916c8c513243f786bdc6c5204578db07ca09f7a6e7ddb5418a5838a4d07a3f3b98d9a127cb75865edced017030ccf23633533455c63ca68b6dc2b046797c117199f4e8bcb78bf24c970e1d95f25bb29436478e14b1d6f353603f5a1c09302dc040ec7051fd5d2b67b6cd6a2ce3404f7c8cbb61b1a4a4fb27722638ac0de2f52f20839cd40b3de6c194cfda7bd0927c9e03beaf13d8912f0ebd7323831102f814646ae0df83f72b5f92ca8b0a7d021975bba41e1a6d6aed817e976c5c7f1409fff3f569fd91be85c415e1233be46844f648ade9e60a445b7c6d9819d9272ba4547a88299e87fc0ca23f61050bfabc553cab042091b71d813459328534bdea20cf55de19499be78a1febd20ca5220d90ba80724205c2c79ed0648b31e4cb357f3083fa2d40baba705261d07e24f0bd49c01862379b867cab68c5e68189aca39acaa01de8a864375e2b4d643b1dd73f92a55d94232e36b7525cd921f989896137314a742c402658590ca1f0a0e8233745b5e90ce628aa07c5a839a1ea6cf5dcc0191129022a06384e9852b5d289094baad6e35af4bc7a79237e26b34095e11491c9dae86468baaeb2026433efa38bb1f884db536bfb337e3fb9c42bbf53653fd3fabb9a3a1192f0ddfb08c1dc13283062428c3a3acd7921d1bfe0b6f3680bbd727feea3a06b1d00fbfd81df8670de150805510ccee254adaddb9eeec820375158e95d349fcdb57d77e37e4bf8f220cc7789e8532f33a24195e72af28cb4dfcdc7f96ae906317410faa957a77335271f67a11f06c64853ae19f0eeffd284e11a3f514a12ba681028b22825913816cdf8eb59b488ef06bcb118444a79a668ec6d396171eb9ef03adc121b9cd3436c92c4334e4d811fa59e2882eee1264f48c86a20db05fe693b61a38a0f410cef60bee734978f2bf38972c021f04e14b240ac9fde60399aa406a1245f39b5ebdf993fb3bb137f2c3941327e7b91b54d9ed6b1c59c95eb0d8dbb473b1442af4afa8689b7c958dc4579ecb2cf36253635fac682f28801f37312373147c8e7779b52d9f63bbb70ba58372cbe43411137285a3e783f150ed9b68ad4ecca9123cdb5c1e59551637ef484616d76ddc85151c5a912a0bbfe7e7c98e98b0293f86c5b4709fd1db455d6afd9aaf89c8b1fee09ccfea4daa25df9816a3a06ce1f80a24bfd1eb9f039112771467575622a342819afa2460a1b0d6f80d6ec42ca711d76cefea5fedef7727f85ccc09486a58b542f52e823ac2f34922bcb3135cae97bf69cda06853935ad638d55046894c0dad57c8f44807ea144a074e2fea4a0b8c8cc2dd3ebaf9f4fb863c1de4cb0dd7203adfab18cda6e65c0da14d9b9d0e1b0e6b7e483c19aae9ebdc9caced6937cebd1e2e512479c062a11acf774e7bb8a379535eb9505f4b5e16e2ada1ce92a2e8927067448e958180bc76652dcd4975ed48bb37d425d0811d8f41b25fa6ea00c45dddd20db14b7cf3c0d10b38a6ffcfa429bde32419a6bb69fbcb70fe5f800ed529241314479b428dd0549fafdf3a55ddce521ec03939955a18cb8cda2f3550b4f3d9b53d8e8a9c22150335973beb48fd8d26a367290cabee0094be097d3410a44fb28c9a21b164bad8ebfc8045bd09eec244d3ca8e49cf60f0d8a9e8d05811d07b2cffd7533e5e0e8f2c4631802dd9cdcee2736a142c7198337cb6e919eaf5b8337efc1449a1266d3369992436fb8ab8225c76594dd5e5ebdb0b5962bd9ef4f9e3718ecc1cdeb9f53b494b5497188efd2aadd2dd8fb192bc5bf14b1de22dc4341ad54312fb0eed0f902fce205d55055fefa45cdff123d7e2bade04c8853db7f4195c8c10804eb691d704b96dc6cb93259a23ae23e1c5f1a76ae9fa9de69996040c94646b9c9579f414b935d84d6bc0f70ff037780dbf987c23faa0535b898b4642d5145ae1b472ed5b9f57ed04ad3bdbceb2665a8a3fe6bd527d34913685aa5640361f52e00364de62be7c500b1adcaa92310b880306f5c376d7ae82f1b050342f28a2b54e28e491142604a43c98ab360ff070e6f457e51a37de4537e097b0e3ea2ac501a63f8cf97f3d6db198f673c10e29d21c688c2898b4488903c6f5ac3c4737b1d5004d137a86bb15c0fcd090ba5e42219d026f8d8f2848d31d0f90dac423cb75ba7ecd3700d6065c7b81d237c277d8062459df83d1eab50ba865b15c117983f8e9c40212d6de1e76b189b0ee108691d763d20229c0051247c30dddbdb3a14e4d69e09f914384fd5550b55de90a502db8f81df3d0bf33e8148e0a265373f93b1af792de3b69363f11912d170b07665bc849aba574dafeaed60a471255597ea544f6d5172aa43d3333d9f1bb68f9d8eedad3b741a2bd21f0ce6ab06e6c947b91a090b85c764231a898e7c315a9e1768b9eca83827b92aae43a771b7d1d66c8e844d36540d67adb50e19a89c9184ce7c7ecf955e7caf1f454d75044957d54d498daeeb0dcaa3ab0a5e6f103f6027b0c8e21e30b7279f06c19cc071b98746b8d2c0e149461372b430b0d3286262156154ed6916f0c8a4820dc8562399e971d4a12e89690dab4c8d28b30be170f9c8a534cd91d4277492fa45996083b9333e9078508c3ccb690c3fd423d7fe2bf594c8489e44fc929831bc199a219406885ed5f00b362aa15cc7604a17a38e85dc3dfd092c68038516f208fc452fb4fa88c9176d2af8557dd242c7682faa8da1e730168afdfcce77760de5780615726b025590d92da3051193d013699a5203571153e4be4ef16717c6367b61fba8014a301210526258d14ed6b73d60a365c5338bc60486c92a44ce103f55260c9896a069dcbfeb0e3834e41e494cc4870481e025d732e05faf0936884af1e69632bc16adc7ab70a7f955f7f82adccdf3e84e4249cb3559a1ea8dab4f732a3ead954279720de66a152dd7e6ac718381f84c28b42e64625a040b6de681fa543084d732d64a774653e33588cc9c8e92788725bc928bf4a90d122c4fda2046def513f6aed96d24c363b31deeaa2cd0bbc2167315301aea8a320778ac59a6a9a866a0638f6b2c8192d2d19a5d957bf8cf51036553ac474634416e14bd66324d9e6db380c7b057ba5813acc65b48ce8abcbff74ad0e233938cfcab854af10e0873a8710a5924ba4bcd07b5f1b90a7f8608608215062251e48cdd1f3eddcbb7280ee1bbb873418a12688109dd342dca4a07739e5999988e8883d13f5fc8d3b1dd2203092a449ba500cb1e25a554558d81b0393fc46d260452ee645fdd18eb3c7b0c68dbb87034c38feb61d85b762e9f87362208afec3748291114f64d3fe7a06b7608a0668c95249a704ce32d88c3886c76b025e4e3b11aafc2c40fabe81eeaa142cbfc79506bf292848d26c5e3b8c034e9af8980fe60761cba49c8d53c8c5f3d691a35178c40929a58c0d32889ad674f36d3234154e44f33907290c90e67076c4e8ca7e7dd1250c9e2e1eb010840bd276c6ee25e3da6eae7d8e1910a4ac7a42841ac1545b3d5c144488e3277f99fc201f129bd3aae73bd3c85c32a327f013e3b6ce40ade0819eb831147800b5745047a04b2cb07ea5e461e95d7dae88c499aed0488a1e563fab5da784f92fb4751da51349df5320a9b459125efa30e5ebe0efa55e7152583ab3dfee44685da5a8cc04cb91cb817cf3ee65e22762dbb152cf4dac949c56d4857616d74877b790f203f576995f85e31eb8c94910113758fb0bf671002fff176e06c4a3e2a58bcadb903932b727ab31e3482a386a774d6af6b778b552e07c6d9660d3b416e1c9134f9441b6e1b43a30ccf40a611b868808bb9c5447720081ed9a43df1485b5182e9071175e05cd65352936e2eb53ed2267e83b7e964d6eabeeec399c6432f30104b1e09bfee48ca514cb383164318ef063c8b881b35921c0135a310ca4f22284b9d0aeae16b1c9ee16094eb5e5e827442296f7c533e65235b1e511b31dda7646a4fd2cc1d1b67aa716c32bd896979f4d1fac53426d34d45a756ca25c1b518fda847a511fc3c9ecb3a9b42e2eadacc210eb8599e19f4f7b71e05d21e576a73ab0fdb4b829ea4a3853ccbcaa897b277cb0bca209963dd77517e430be48aaf020228cbc70d6c42e926bc850bd313ba0f424619ec67d990cb5442a7a206aabad19580e64ae12a219e0ca366872c991e41b408d628ef858c208d6796989061538f736ea05dd600ef095cb8007e170176a6e3edb78b7df27f077cfaf778e219d27712610e2151542d873817cf377b25d266fd765de3b05891f83808c194bad871ff5d45514c4fa0db8cc5d87d5c6402e4c2c163e2709475783a8056e3182549847f899c41c6ff5f3d442a536488b12f76e84bfcd1ec95405c08a73c7183189d17a1f125915473b3a9998480d7256d0298de110854bdc8a498258f9a03fba0c802ca2ba1e8e3501c871c4a4a950314006d923ab12a39c5178bc049f02283dd1035382e900d8adc81581cfbe1b4dfb75853c010a30c3257eae070c0979180961061806d0918cf31643ec2d77a29679caaef3ea9854ea33fd34426e8abde615240e4cc01a3e8d4800837f290f31def003304643b8642447915c5a66adc13263b727f2a8b82eb516d0a4f4d16cc305648d9cdaba7e3a5a1d3e9a96e5bad58275cd3bf81d1f91f8c35bc1813e8a94531dfb3aef671bc5624212697c1d25ead2da6e586968fcbf5b9d7fb3337a9cee9400a5732ab2e353e42438e4a44e818b7c48891aad87199c76e57b38213e1739a0d46ee5987504810d96eb5a42a589e717cf832e2a675aa776471aa3e4d6625c12affdb37eeb0711babcceef5a72e38f4848e6b650e7eb20dbe6197bd18eb2def3e16d0ceeb0bdca7cefe194f6884e907172b2f1eac18ac62970b06f62d56a2e169cf025c13ca1c27dbbd109cb2f0862b9394a981ea112c46d054a8ac48587dd59b92c145da9d122203ee412871598332254ce4300794d219981f13db341aef8c36167da1fb862583088ed70d89e03c38e4e65fb44ebd12046ba4e5df539b5c887801f22c47e611b477d61c55b2ddd94557ec9fc865137c2b0fa1959d6e2ad0cfe4213932858a6cc4941509f2f20193f7a940768f59e400f4231657471762e4217a1253a47bb7ba45e0859c082553995305ea5937d36047e1040e5be54c21c578315b553fb39729932c57ec87abb44a538dd2e9a14229a96f0c866eba8a520e0c84ed6cfa1e57e8f81a8db4a70b4bdaa495dfa1c976e8b5c92f2e59ed30d0bcf266809abc7857e795951c06d80deec776d4067d1553fbb6a4c696e46ef9b54b54bde4e9bf90bb68a952c89d99cc7cfcb00b050be0c9a476993c2c49e4ae5a54505ac4c3104e6fb995cdaa591658c4ce02b5921d121247224a14591598328279848a05daefc1a5290e0741df15efeca455b86bd5e615f233006b94086960c088b3c70bd6f972c89f3bc2e79fb93368a3e7579bb074880d0b51cba2a4658cf83c6a6fdd6d3fd54974297738b2d58be18c9e120174661d656a45fc2ef974def5c93a7b2db5e24481fb46771bdb1b8c1e1d858b84bbd984ac13cab19dd8846c14c643a83721093c112dacbaf87a74ab723909423cbff584dc07fbad16f981dd60d81178bd76d23566bbf766e77518cdd350a0199ebb6bc32dfc695e379843f0dd301d3d046e35a51fd7ed9ba4fe1e9b9bb5689899ebff137120af01a2d1dc68e08bf4e179c9418883ab82112a553cd506e339a1b48782c8891071796755dc713eea0c20a3855a69a2cd55aeb93ef5d442b139f8e69dd1f2dc78a4ceee2b0c9cf0df3ae1e9bb61ec21ffaa567fcb8d50dc174e343eb0ca3718312bf16888edd414a3ddb1d644087ed395d10767031ed792e0cd591a55028828a257d4abc7656ca2fe3ea0dc6ac609176ceb92fd629c28ee0179723ab8d174c821cda48a91a6c317e178626e53f16fb20b2742b8dd73800df074756eadda83af3009abcc19eff36b80488a527ae8bf5719a12c3b0bd4e5a98b5dfc04ccc31c23df32888ec1fc197d26f2e484c5519114dee59529425b481906e0cf3239858a986c0d9e93cbf28773a4e1f133444ca12b9b934ba6515239551f4dca89652285c2993d0f4360547b30f20e64548a4ebf2ca44dc0b481faeb59ea5a6111907b4ed2d1fe84148189c8b1a8d84a4cee667e06b1e2d2ff677de30e70923ef554f175e9011a373be6e99d8a8299c13db923e3f2f234d8477eacd8ac47a9c56b97478431c0f7993065177a1a1522cfb1c88c1e47b9a0d8b4eea8b9a75d35432957c5fc4f9a5b15d6b68d0af483c50d3e97809f782f9bdfc025c575ad7759546656dd39357d050de280852c6a4d3f57e037866f9838ae595f637d4bb5fed90a38fee1c4fc12baf6db24e83f6b11756a203904db334b6df046451ff267de3bf2138b61bdc5269b538a7e9895e59411a84bf147ae9e98cfd0cd221f1c40e9fa7383372a6f3ca5f88d43eba34290879dc7a9f69cfe3cc2459b819b61c627243bf58aa5c6a7267ac78cf042f46853d9b06c963057574fc01a8db60a3dd886596705cd280d543274e3b8f8e96623c1ac5c866ee533667f6497c312ad9ea725ab6f53478579fd871235a96181e1193637de84e80dbfc105e7572cee58b0188d7f1f6ef51f24e8dbcacc0232833af1324339273ae3eec10f8b0cde8cdeffc02c572ec49010786319d463ef2513f320146103ba3b82745c308eba9a0ea58266fa7dc08955740b5c605360b57c5f66d484a679b773ec9080c49501be08c87ebe00cd3cc310ec0ae14caa4340134e3a5eef9b4c21c36e17e94fcf1adce9e476981795bd72a191e668c416d2f6eeb6e59652a62465070740072e07dc0bd93a300572e1e675c7820a9d5bdeadd42b485ba43cdd82ee47b89784eea7d7fdf723755048f7938988119095cc0947cf74aae15538971cd6420eeb7b2794d3ef9813d40cf8a98b8a5cd9d6a71df5baec791c28a43eed7674617361f251c3c6b2a4c54e9a2e29b0ea59df48848afc5bb693c3dac9c9a9072ff221284f5072e64bba27a8b09d5af4204a1d095585448c88a8fed5bd9cadbe71f8ea42229a9733ecb416815aac34208f1f0e7b5195eaf10761fd2afc593deb71c8fa9fd56af5abb0c8ccaf1e874054cf0a8918adc21f11bf2a0c419553b0e3708ad11ef49d195d56a864e2985505c6de6254ff2510cb8d64b26e92a6d3ac67b319d5e32d79227dface5c25c03b64c6913bf325173c36d2152cc1489f1476c8dc60e44e3f09f43da99346bb81bda5b33ff6960fec2d43e099bd1f7b4be88386df8e077c3b663e410acc7ad58f8dd43497a8dd36afbf11bc67f2d175a9cf7e273bcff3b13d15f2fd043b157a4beef7b8e46e2cb9bf91c03413ad7f0a5d216f2473cea80b55d4471794b885d39e9528da09a8ad74522389c136a42e22f0d8484923914ab57aeba386af1f8d444b809b16cea816bbdffe8065142bc98f51921f230f4722d60799628c688236fb2912b29e1516f99945b4223faa67fdcccf204da4a22b27122ba4edc17cfcab1f659415385ce118831d366b4d4b93c98fbcc621817d24d67e8eb65a92a4cff6d652912d14965a1acea4a31a064f30004699fd14c8811df772468374cf853f463ff73b4ecefc7e2a1cef0d2507ba30806176286228b8be9cd95a6e6ad16e16c98643e05196152061f6adb5d6edbfdc9398f80226db2ddb9f5062748fcd91fdb9c5beb4d6328151629dca23fb938afd293f13e48e0d9f6a9db485912dd26802bfe8b3dec88c035fd47bfa9ef7ac9008ebbdf0e7fbd41399f93ef53faa13f2ffb4de7b16f8d33debbb1939e03a0626a2f91fef67be051a01e99ef53cbc87267cf92b9933a3d77d2034effdf673d6fe3fadeffe8608f09ee681784ff3fe3f461e02e9bef53fded3fc8fd116026985f77f68ae7d1a5ab017befc573ff3ddccea675e4030eba9ea59e05773813a2ad44c1fc7182c6746f4f3fee52110eebdd4e3f881c493c91cd61cf8833a288158f6a7e028ba9864b2679e91ad2b145d4b29e58b0a9e7276695a7eb100a7e020a5e38c1aea9e9f4535e35c629ab59e13706ebeca27305db8508a23539dce01ff7ff53466cc7819353443381c314e38ba38d77fe128aac21a8e327f854953fa1196118eef5f138e622b1c63b5a69921d6100e41f07e27794f083812e64f461613bb7c275d1b7a0e0040d9b4ec34da2686aebb4d7bb282c060b87bf794ee02edee6edadd9476373872b9a7cf321f8539d9d32d09dc6b4b8f05842be12f5dadeeb59dbadcab7d4aeb04ed579a6f485d2d23309db2c55a3f2d787e8e9672a72f0d3fe70d2cc051eb53aef56f0872ad4a3674c9f5ab7cc09b7190476f8a1a92100293e96fb8a3a8354a84926ca5b243aade106292e9d35aab8e1836685143982a5c706156eb0fb9d62f5799ab0cb629d36f117ed46a24268628a2706109125866b516e54ac549ae55860f4383951c198431e7c40cb6e97aa93db208da9466004388f67042b24c5a70a62a044393a002212a65c9dcbe6cf9c2a54eab4403112f6c36c460c06022d7748928c05e9659b278829100e36499258ba83c62f10ba727b4e5cab20516368f3fa5dca19fa3ed14789c436456b42642f6bceabb4f2993974c2514322d273c00859fe0cca950f6e7a3e33ef5db4b0fb73c9ceaa1bba2543887b660224666aa4fed806b1e9f0b7fa8c2c0e31ca20d557082a13a4818ad4d010593964c8fc8f4471911f4e7049a4095fe03ba47cab7639280c9c2e9697ecef5ad222929bb97dd6f985ce9095276e9495b949e38653adbc79c20384cf2a0603b09da4cbe6829207bf27c7f14b05fcfc969d1715accd101d71f71b2879fd3a23f8665ff6d0478944e3eba7e8c752e830a5dfea20c4a64f7d9b783c69716dbdb3e2549292500b2a5d6565ba96f1b121dc8a38b07198490ed1e065078c4221358059afb45e802dcefcfe19fe2c8602f13ebedaf17bba1a45f0fbad1c740fba04438ff948729d057e1e62977eaf75824fbb70d652cf4b721d1fd5a6b7783a0088f3733d92a53a6d054c184a60a2636d890840d33ccf032a74ed1841f1434814e2174ce06cc16a5218ec5feb5041e63fff37380346cfe30014ea5607c4808f12121440baa0d50903aca1160a2d86dabb556bbd99e5270dd68583efd1b06aee1ab7fe60e63e10d392738f64474cace19043583dc45e089007beae7e7108147093f80cc94edbad40c21070f1083ad0dc4116d282be18710f865503850ae6c99504a41c19f9b5639a7a4f425f09dcb90c8becde958770cbb2b05430d47fc426db7dd22d28be12f29ed6ed99422e1eea8975d38b4c56e2a84a951151b266fc3e4cbbe9b531a7ad98244f75e4b3d69690949949f63ca29a7cc3165eb88f6e30d30bfeed4dda5b4a981c17db395baa49c51c3454e96b5c67a6d6d12d34b73299de15adea52cdcd195a7faa8089f8a8ae0addcdd6ba5b5d64a3b9c929293f24ab939b53555069d73f21081ce10bd6d72a6f794524a29a5f2f502e1480d1b192175e10eb9dcefdee1f8fa1173987c569eb456bbdd71ec57e5afcb0e4af9d4e5e3ebe6da79524a29274d4a19a502a594524aa9d7b5524a29a5d4fb542b3cf37d18a86cac5c18a75836683c0ef42eee928b044770aca19452997f83b97524a594524aed6d5fdde01aacd68c67696ad4dc8a5975061c5399db6a64cc70d9bc6478121c0130c3456dbaecdfdd6c90fd3b9c9ef18d5073879edc49659f8181cb868deb06a76ce4fe8e86c7b97eec1feb3bed9ae9775d336db029a5e1b5b9a95123fb77e1cdcdab064e8b8667737f0700ef29695455cd8df355708ac320a536b36bbe8865595d4d4777772ef07c1fa59452ca9aeab5e54949b3497a299da192b2384aa9ace102bb7baae54eb5dbbdabcdd6ceabb4aabcefb374deacc32465e7eea56ef348c9b1ee8c47371a8f4a4a6dabd64cf95eb3943b94565aa90c8f4aea140a6af4dae5dde6a975ba3ba6b9bb53bfb91100986aab9d9133f65f5f0f6c29ad332d1a302d9a992ff6267405405691810c6a6bdd2a4e8d960694564ab3b0f645ed97d60be31b3b43ab9db9c27ea9f7d28e56cb62b1baae7bd985b24c9932b6be36d059bd6e7476543796565ba68cad3602b8e1d9dc8875ee9303ae034a847670894c892385060e0f2c0d1c0f78aaad0183f3e2e9a1d5bfbe2c0daf96563b64da4a3ff09922c5cde3a4fb767476a7d56e38346eb27c7a656d819c84d940a062cefaf007c3968c97326a70c277587f4d173c7ffc57e80a4000bcdb354d19c8c820834f47fd1a35d4abb5bfd91a2d0dea8b34d4bab442e3d3e12ab0228c7e58b45e18c33cd8a7637b1b1b78392d977f5eac4c242c66789b6c6021a12934a9e0a821f349cd04d54766470644f4be173f1daa176ddcc0deeabf1e7d801956d779988ad7f94af50d994fbcce0415c8c88070a9af0d7456af1b9d1dd58d8ea7a323bb4957d66e98306f34ce104e269b4835cfa46945c804a1c9ad5e304436b9e4709c5b643602b8e1d9dc8875310e3a0eb80e3af0a4f4b9dd003c297d068063436a1107081a383cb034703ce0a9b6c609e7c5e3d1ec49ad25266ff5822ac5faea9161b9483497c93e1df46545b2cb200cd9b639adb488a58f9037fa93903bf5034f4a1f1f4f4a9f248c5d5eeb8dcfeb66a63978824e0eb23f75f798f489c91d9f14088cf1c54e0bb3c316960d3c44d1f4d0d492e202950f543a1fb2b84b5d23aa218fddd460f21cfb293799281fb8c8aca7cd63e38a79f5d28725eeeb28f900743be83a294de48e0c2e410f2f5c2994789062edd74f8725c00e284852da61092d1b614daf88be3a8871b5e8a04408997e875d2efa2e7a058728a40ce145174e66f4c5e6a9405cb152e562af66091e4516f20eb976453a28c1c9f4ef3645173599fe96938229327d6a37a5211e32a55fb9e4e420e50465327ddafda083031513e4e042a6ef395ea26891691352e0f18a3a50d8cc8cc04d578c1607585b68a0c4e0021e9a8122f4c28a5e160f4c544d2c612a4e3e033411b5520af29c545328e94690f44141810ba9273c2859b8c07550bab80618c1500a4a18306c475c1420254c51624862002786a2387161a916258a0b062041541422036ca145a1c2845e2e3480134b51987819c53aa6650b316cb8803924b028304cc1ad2cb33cf9a08114d826cb2c4f48884cf08c2cb33c49914197272d32e0e2290ae604af90d4a8823f2736ca60d6908d21f08a080d76c038a9c613be4c3570c03335510b5e6599258c164c61c0a8410553174416b08d013606e69e9c00df285b4809e307518c510d1bb097651631546a1c65119374a41613b3c5d6a493392924302bcbaf5f18065f292fe82370bf510a5aa048ee14787bfbeaf7d519039d4722790b715a746f5197c5c4609fc205c4eda2058a5db885f108c214b1618c714be90616dcf09447fcb48ad32d98eb965d0577376f5c33601fa9c733a6e011a7bebf9b9e6cd93e02cdfea927f8738e965212a9beb08884a285312420a168610c5af6fb94e3387ffad465a8c54240e58e87f52be55e8242dc3bd9bd48909ffa1da9972ab8a42f4122cf41dfee0d456858e7f841ca0f600b12794f411cdde37d7f2ce6b21c6070151ef2289b7498b8269d2b0afcae16a58bc0c3257379cffd9bb70db4a0dc3102cb5047eec8afdd5feacd5d0098b08ef4997912f1a72111fa5eb885dfe22482df3f4ad5a9c019e5b04afb81c4b1c3eae3f7503aacfaff784f7f23a13ff5fd2922aaf0e77bff2dcc6971ae5ef58f55ac577d10d6ab56ff839f151209b2fa51fd785618fb9574588ed81830f4ab53a039a32c14a1e14f051c169ee0b0eafd98d7f6347c6d21fd1ffc1ed2573da534a4d1b0c8cf1c72587dffafbe9c85627b30df7b2b68ad8f630c7d7f2449e87b9fc4ffa3ef3d10ffef5b416daaf0b5d5d716fec0db130caec0090536cd61f53f1003e5fa9c18dc42f5c330b8fe6c9a4935e9db42da6227bfaefb0de43e9532d21f391b7881c7f76a10264196c9aa26ecca4d690946269d4128773f16c99386eb8144e40b8018439b11790551153902055ea2663fdeab422233cb0e3800cd8a7020050c41b38e6a0ffae5ac88e442862a42332fec0f9433d79125a425ba24c70b4573b2d2626f791d61e9deed515e774322ef91bcc76ba4f99130f34c016d246107da88c2374273e98ffb7602c3a979c6761abdc8a19a67742427538b1a3b6a49f38ccd25b7182ec678ffd5c3bff63bd27b91910374a11f8563913cbfa1644079826d942f28c3d85244cb0e1a41e28129cae40df49745cd33bfc7b778911fcdcde57228177605d1bc47ce80f2903bbd8ed80277c2118b39798f87c31ffc1f0e5ff3677e5e53f541583346e16bb258af7a396b16e84e0ee5b0ef3d509643d603112322ac377afdf03e0172a6fa9aa74335e0091f58019e54cdab7e944d56d0680eebd5ff1801c1ef7dff83c339e4b0a079e4b0315ff89a0b50bdf740beaf098918f9f41088eabdf766dec88c45f35f8df747e6ccfb1f9a703239ac5f334ce187745802e4cc0487f51fa9be6936318da999504d5fcdffb0bcc7615007d15ef3ab79ef83d4d484aff935ac67853fdf7be16b862f04785ff341bcaf097f8c80cc7ccdffbcfc695eb23e48cd4cf872ef83cc3ccd4cf8f29ff19ee669bcd6d3d474d00254bea505ba934371636067f2a5169de64beee454d4475d94db432ceed44950ee1464f5a3fad53b943b2d60155220a73477f2aa38aacd3ea7e9984b290f94339af43ad2d1dc21e9eebed7e5925e28a5f5012dbabbb7839fc3eea639e48efc98ecc529bb3bec965da48d7877347436c7032692e6a18f3f2665b247ce205ad417292515593e0a0e90208490a70e52ac40210cd5202ba58aec3fa5587fea604576b17e92303ec78657c8b54c762bddddaa6e7882dca92fbde46a240716f8a3c97348183dfac0989412e63547f697b0fa29b0eb8fecdd7fc20b914db7392f40261ab4e840c68b306ea8412cb14d7aa82f7ece5b31b48527bc58b550c33cc1b48277d1c2e54038c3ad6d58704ba48262b663b3d25a690d16f097a59210458c21c4942d4244b13428e91c2658760068be27440bb93eed5ae9bf8e00aa1845193d512962d43f2f9411982deef9a51941e132bb7928eddcfd7a97a500168a64f76e760a159986f386e3ddc2117b8bbea82c042656b64d22348f540a6229cf20bce45492d29424733ad7c4a9e3155869bd7a3dfabfb3877bf94f2499c8ad9e5ee656cfd4864cee06b2c78625348c3e0d65c3c601f08c2040691ecf80a4995640fa804e7d053a54c20f1e4bc6abc210155aa443c20a04812f7d2f2e2a32a514082fd1a73fc42954ade17e377b7bf9e9f0d1dbc66ba7bd96c6451e71be933623df9f136886938684472fdfd4bd9f0af1a4f590835d54ffd6d0fefd8e227de41d7bc98ffdc40b7b68389f72bd3fadf4fd09a57f7669f55d5cb66071519953eea7eed3200273299003abc0f38fa84dbe3f6fdfa121fcf23bf768173cb7344f33d5ecbd6f5fcb3ce21291efbd6f8ff09422af0b04d8887b276dfbbbddedd29f9f2c5f51facc21b973ffbe0264cf8442c29898b46891573ef8401441d0c686c5baf77edf7b7f9cb4fcd7730d6dddb5928142fa90c3a40fcd15cc60aeb5d65a9fbb628bc0435ee7dd6ae55ef0e762c04745cde3ea82bd86a5fe0643f64c2aa496fa4c4c5ab4c82b1f7c208a20686353b93c674deed4af453e44471f9252e4ceec41faf4d76642dea85f8b724861ca9d8aa536538bf53beca5166b95d4932e0bba1916a64c64cf0974932dcd5b30ff205b876cbb06dc2b8041a579f05bd6db6f26b2c785ba903ddee430e943b34dd9af35acfe3e0b9c605ab48f417b05db22b037794f7dfb2e54e59d496a81d2619b17712f7031e0f9d43c76c4f387a25412b875381572c73a90f441923e7e8473c081b43890088236360e2404044e026f368923913bf6534dc224789c4dfdf3de24202bdb5a3b9de40e7d9aef4f02a3e030fbf762ecae1702ead30f529f86488064b3995772672d18c038bfc8f6bbc8f683d0a709914c27c9817d25773613a2e0d65a2640b98588b2fdb63fc14481ddc99b869ab2c5d247faf474923bf6b3ece91a562061f69998b468b922af7cf0812882a08d0d8b85b36dfb6058fb36083c7ad9be0365fbd6eb99a00cae0041d320041843d90801f6c068f0846590400c836fa8d0f0430f5e7e1012bbf80106b10abc7a0116633420c236592a159d40dc01d764a954c484175434d001b3b2542ae2c1865091932745405ac4d8a0c953161867a944d4e5044426d8801605080606930649b863a286126c97304289e8034c4440d8d082b72c958878f0614eff6eab57473a6520696459abc9f293e5947f6c88dcc98084f573b1828c269cbdae7379333a9547af87adfd6ca5ab16f67ce5ad4a2ddeb6b0042379ba2a75f9f43a4ecea7a33e6bce1c8b43591c48a704e1d69aa0a6bc413d29592d55cd274ef73c2a6578d2a3299b1befbe365b43c16d9b7f73f391306987636978423a413940381d9d8e3f59432303261e0600e87e8f36a98c192e9b9b215907fe8694fef0b1e6914a4a185dc9743f980274c515474041c152a58244169dd36ab7f196b0b91893f993c78e7443cafbde5bc311d370e6de5bfc28b7f42479073ef83043972fb490c169e61ea81285cdeeee2d031e316e9c7657f3c8dcb31ebabd79db7bd2f3878c6a356d4e9f41d3c1f1a64079f8903d43648f321b903d3c96e691251a1275df605765e50196d0b0f9dc93710ee540bda039e49ec354c90c85f69caf21dcca5269862a799c41b98416271641997beefdab7fb7c999021d227de66637ba6ddb6fdbc681258077ca56cda0a01fd913812119909e0464cf1087bd181ce571b3d611ab40f9b5825c0a747a9dfb5bc2b7433e51f70d689ed8090d6891c70c2b37067fc63a416207d528d149efe92b5f94116a7532bbbabb7177775f8735a6d9eb6eefeeeef65abcdeddded6058da4694de48efc9512980cd49353d214ea204a29add45b4a995c1aa294e21a9e2f7f8eb329cba7b44b8bf273b4982b78caaf1183e5d734a5d49b524a699d492df250f711e0299b5221f49fe60ddb2f3b245264e645ba6750e041b55aedffbf56abd5fe3f6989e9ffbf56abfdff77d004a189f4b964ba073b3d413575116e72393d54510bcdf0ffff1f4c172e5b269625115ca97708171dfd44ba40ddd3b55aade8a8a8a88b7e740d045dab0975a935d56ab55aad56abd56a35ef367501438518649eaaa8d56ab55aad56ab79d01fe9ec745aed76b9546767f267e77d95e33e15bd57b5f26da3ab5837f32cd9e4a2d39680986a28788f283a2c0578662061f55960fd16f22ad21b8a0cc8f6eb513beccda709824b9ffbf26717f9134b6c224d2bcdc3bdfc7ea6a79b9ac9752fc62ed72ff912153ca548ce225a4fa12cb97f9c4eb2fcc9448230b1cc1bfd92e674c57c856aaadb50ba85baa4165241518193502fa95a28053912d63d0b94123697963a550bf92a945d03f2fd2976affa7a7c4e85aacf87ab64119e3fd4505aeceea1bb86b6e22aea1bb078ae610bf50bf5ea1b81fa1337fc277b0f9617f39e6d06b56a0cb0102247510b5ce00596284f3851c4154e30e960adb5b6061f5cf08219c22ca104083ac9cb096e1212a37ac55092263b34f1a4cb17274e6c5189b842cabdc208870eb2b8e00b185b64698111f5083741e1c15eb1c24cd312375ce1845382c3115a94184af08014461d02045c962748ee155090d45a6b2d81184b0606ebe58a1a85972c668a349822040690c00287114c11a6c9163329a7796e9e33c9262182cad01412601ebae01b9e10a203415d82a3329f3d8284e65176c90e45a61ae571d226d05c32859c8825398fd34af6a67214953d004d8628ba72e5ca0c2cccfc633c4e9072e4055f4039e1441033ff19348b3cc9aa8e58248bad73e0459dd8d6850a76d8c24b91951cb4f8a18bebc08154134a6e70128515485e70e1160890baf9f385807bbbe97dbf79de77537f5f08d86c98fa1b522e05e688b5d31008f75dd87e432e1c63a1c3a6ffcf7dfbc3fd06e4be0d8170bf85f8b3c02c937f8ce8ffd84ffd6cdfbd7cff5e08b09f7a20f653a10864fb2e7c8771e06bfe1b995d30f5f7132067ae90080e2be46cfbf153b65333fbdbd726a6a47207676fc0097247be6784e7c75a942f71748fe01987dc915fbfc0217da8b4b96a0007e562381a70824c862079b6cfb593390c662061dcadc9a59e2c3dc81c09997ad0352a1a19302053ee3db04648a63f45ee7b0399faf07cbfbf03784e4d231407acc608ee4d11ab570f87f4a13e3bd596872cb616ac68e10bfd23a4ca6502b422b43801921034e952a72c81258621ea0b2e822f5c1430d45a6b350192db4215a0285a40e22f7c0ece52e9a8288f1fbb5e0800093cbefccf1175ac064af866a97434248e81b72c958e6a68131c31b9329924b11c1df132c6568778ca5d964a4378916189b5d6da301f688d59d244eb8b314b527004e83b526bad958b0e1c145c8078a116610598302ab8428c099284f1c3064518474a66b8ae219686b052a543681e2ee575aa6f05f290b0fb52ca5b94650f7658d3af3209bb72c9089228e3910273ae091cf852bc2fbf1ed4f3f6f8debb59db63ae902b5117b61ad65a74a28eccfed441c47aa7bf43e6eda6783856ddbece3cae3ccf48f6c231a65219c92a8cf11bc9d88570bf92592564f51cf72bafae563be4abbe7d16a8d330fb1514b9d48b62f35831d63cdc5bee6e7fef9c77daaeed169dfd252592f288979440ca7666bd68cac9f62f879f7e3a2c70819953bf43666ebbb5077f5c0a9c92b2147024a9a3af7a5538aa8c641a8e3ade774672178eb1affbcf48fe7aacc6ef57a191bc0a475927a4be4a0a517d55a55eb5a382ae56ef90d95efbd95a6b3710079939ef9d3766a1aab413cf5a67752ab3ba2783a58023b516a50bc7f2c764217c9db34e20e89c73fad359ebac4dab774e3178fc1ca7230e32b5d6d818f27ee02bc834ba3fdf2bad94d254caa6524f53a930265bede05d1f62caa72395024900755cf04542cd1ee851fb77bbee479c5a4cfdbdf47e4e419939b0befcb617f5177d9a690c31269c20bc796013d162313451327b05f929229d88528299117d2f7c059929303935cde67b2ee6a6eb240a542a0bdccaf2bbf995febf101aa02fa8b46df844b5643403000010042315000028100c87442271402498e8c22a7b14000b778e3e76582c1a089324c7511404418c318618400820001162184254441c0020516c50695ce0c5a843790fb716cc6ea340f88e8727bec67ff44a591a7d4a03d016515bb9882701a944cf604088a9ac816dfba7aebf6559b1951f11acd87833f99578132e8b05894b0396bc3c14fda0d81c251ae4becb11b87d6df5b3b22abcb0321eda997ccf0553aecfa2271e5203fbbb049c307d2ddd77ffdd1754039b8b1d2194851b34e639d94b16d7181c34417a142328fc0043766f574ed165c011b932275e5aa5044c2139dae091585a8e578a2d1336986dcef41d8a343a2909289e66c6fb733806b46ba64a4123c90e2d87cd49fc6e03bb9a0322f89e04b7144b6a4664b0e235b373cc9dbcc5d5e9d5fdb4c8ed074022da12347a37f75f2637d809ff5aaa49c1207e4dc0ff36febd6f733da9323a466254a02390fdc1ab8de241832d2227f81dc8894000d566a6afda11e08d31ac4a34960b097c22b653a056ec1c9659af2a2c92d5f952168d6d5986da6a861728ed695f7c6c98bcca5dc585b20d0518e6d7556507c6ccb4a8aa2567ab12d6b5f718f3e062835b4ed068940d137ff25650e8471bd865f927fa139ddf988d7bf7af073e58f322439d70bf6c7bf81e675361d6008a9efe03c9fedd952df8c548de5ae9927cff1c0ede0e57e01cc7b5c0299081af12e7d99a239d46af049179cd0789f2245cb38d45bf2015786f07f8e1a444d1c025635f92dbaa09a50a1de1fdeaf02ea3ad1850150a7045f6e050e9a2af0c47432503e80f843ffd477f8bce44b7a47a9ec4daced89ff4d5e0b1d45d5fc0c678f68eacf4b061d677700538d4a1cf10b87e09d69bf802f9217aecc4edf23d0ace0ceaaac108501a41eb2d5ddc178b53990499e3bd7b804cf315ddc373618138c396eb1b57f2049a2483ff4f90f0322dd830fd256ff00c58a483c6fca47dc0dd3bae6e76f484a42bfe1f7a8d396f725d1c9a65527795a846f3d77abd5516e4b1c1648c87d555170d21316494f28c21cc8b32eba08697c5b3e01b72b4be9a80c61682a1861b4266e0a026a09947b0c78eed58bd7b674232d34f3ee7f09b099ec69e57efc7cd1c6a0907d1d0b3299df18240ac9ed79905926e52d70c2b08e8326c3dfcc503b8f21d7e589eb1260be009d1fce33223a67972f8dac80c55953eb04bfdd6b53088b008f77a3471df79b12c164b189474cf3efd82833d3db6ed2baccfd79e45b364011f2ad740de9a8407745e2a8d7de6218527b48a82ad9e5979aadf0ad542059db4e4eb07f06d3b5a0f0311f719d8e85d7f1080d21523f8b68c310950d4300d1814d8d7b32127e42d4b5553eac0874ad205acbfd234958e4a54458423f57cba213eea0326806bfd7a5852a4fbbad310b100e89ac16834a27c0019f7406e91b94b91acd056b1e086f0326a5e1fb51a64bbeaa56bafaed72b597588ecc825c9f9f1d18b473276ebdea571e43284a417ffad8d58c788d207cdded3c885732d27e8ba41f2c5a5d03f1765913064f5e9dbd73d28da823dbdf12dc756b1106e6793d369c239adfb7dd33f786536e4189798ec9f9ca3cc61a638e4a5ca04083d6548ef7bb3e1bab03d208abb117d6662c2e16ed826661bd35e3aae3426342d13bb8e7c569d7d719931ec6d173374fb16bcecf9b05870168fe1508c6eda0ae5867260ed3cbeaa26c4815302c657c4915a5af1328cdcde240804e073031cba83425810c6b8013a379c53b30b17e3527a427b35937213b184d4132e9948f5438601f71afc250e2c874f691eafb9a1a88252063870888bc49ccd9e60c85ba3651afc0b875d9e0f69f5910d01be54d96a5bc92d9dbe7c20450de810987c49b1ec4a39c71e988f3981762514d65a19446c0ed02a648abf4b43e7910c4ee677dba24382c020ccfe9f8c90c81c12fb4c9a675a66fe31cda40caf4f4698734d3d8d1041ab89e910b5c700634d049f665aeb12d6fe1c771995dd38518b11a01f0fa0a3ebd4437b8733e2628aff07aca3fa00d3b69c9fbcd178bae094903a04265bbc15b8b67701065c920096c17a21aa166da90b79884decf2d5da173f54201b7919997b71bb9ab38089fdfebe4cf5c88ad97802c2ca559d966c49b1caa2065e3bd18cc909659a7da867a78ab4566445521db5e200f5698186f40151831a1404ba072a1cdf1ba4319e93458fa4db89c9679a2b4bbd895ba381cf36372b3dc9bb3500e6dd863033007b6874ab93f0e2d795e650d0d768e9eb827b654bc44a5cd6b404ad7d646d3ca8917eb37868c8174fff3eb4372d147d9d1ff188e24667fa9ee0968a7366c10e2c4cbef1adc26085982e28947bbb1c907cbf8363e5a3c4a5daddcf20f8e96edd4c5060ce4b4d5102f4dbe2cfdc6b523f559a4b7b4df7592db24bb0fe1038d4813adcaa8b42055120979520b5ca66ce2dfb229f4be442cd08941a1591ad89622a79db854716fe4a94c5faf8e129cf94de03152c15338c9c68a0790bde558927e4fb6f28b26fd68c55a61a1a8906bd6302deedc17b2b996b196186e54a13cd3d7c2c407a9e284ec8dc8add9b6fd1049892eaa0451f25be43898ef8d567697653862cc6bc1628fa5672906520457d2bc90a4df8c8ba0d041aad13904562a33b797b1bf06b63a33bb5d9602cab57fa57b4c9c729ec3691d09be1f09415dad8cf364190135a7898d270a88c1c200671b8e1c767971b892a02dca774301a69c277232c08c7739d1a0ea04b05e44f67a84c08d1900afa40c3b704c9b44bbef45b57eec3fe374b339c86451ce7300f0d58c0c92cfc22850e9c33d3806099e4dea1b02589b7d8a2713799084703ca7f4e5ac476d70fdc7a6979f264d810747871fca9237808392b5bb4ca721f4c99a7a82070c65e7794c4f35bc4bd1aa66fe42e76a6de91544f5e6a63d7d77c9e190d0f5c00c91a5bfe856dd3770c5e8b44cc5a6b145eb348b578e9e2c74c6b9abf4e4c67c473c8e91b57f595d54aa527c8cf69020f5c195dc4f3cb351a8ff6c5aa761bc46aa706c7a7d915363791a760476223edf30a6ce021b82aa8a7c3aa20603d009d37640a3d91e0e26b0c0eac4d5165ac679aa2884cec34761f38dbdd1dd2ec38dc3a31b4fb88812546426777cd3f8d24dd4840b301bd1f0f7945cdc8efbe6fbaf30fcb3f6033def57b0520255f1126e4605fb55d2544a1d3df0f77c64eef6a49dc46d89373c6989547b44d06925186815edd9cfb0197be2352f67b36f602d480af3c620ed5a206320a36b1529ce2d9b5038061bf04e5de27b0eda846f6623c4a221fd76652cd83572c9f2391b4600e92d9e3729e0c005af50d79013f851d7c98144ec7d9733a329861b046ae76e4d228129d8d46fcfeeea1580586971509264008285f2bf81c6dff8e9b3efba76dfd97bfa8fa2400e1b00a77a75e2278d42852a52d3037e8897d437e1afad513ba13b24821b0f604640821f003706f93e6f1936c0802995ec54d54ed25b18e5a9e4877c72b7e3f9b2e61f8041f3cdbdb019f7f89a0e1af3fbbf76140ce2bd03b89e16b36e0d52b1704d020a129bb7339b01ac4398c614162c0be8b55792b8cba87f93bb602ef2ae0f499b9191132c82edaf336c43a81e142947d037e217cbd06c9256fb496e75d4cb0a48cedd2cd3ce05691a418996e99ef4734b59626ff43a8677616ff544f830985dc9ff8e4668a5ccda95efe497fce8b890172f6ed0d254119ae31f69affe67fe8251055c84bcc7c1cefdfc6a007dc9049518ae28c4e559c733f96acb5e5ce305cff268f0e234be81045a5e9ec4530f2ebd060c813ccc892bf88d395782fcbbea4ecf2f9e95f91d090f47b2c9d1ca48058de4fdcf60ce8ade0916b2cfe757f6feb9d2bbd9f2f66990ff89d46eb16f31827665765909e4c5d2dc21d2706cc273b9e69fca00db21273ed7c06effd3a3de8ebe8506f5c5626f40927f7b3061172ea62c176c449fcbd5c9f41e30c4f8818017b9ef54531cf731415c7e875f283e601d9d3234f4fec46018ab325e6e9fb0dd8bd58f741a7f7832f8bdb81eff1b8e30bb2d955ac7c7643ea6d1a99779963d6a4d811629cc1975b20f9af9eac32c67eb9b67ee3e18d48ba7c6d8cf7ffdfeee7fba579caf0ccaa756587dd14e6aa8e49e8d79062aefa82e723228a2aac0da806056f60346e1502c376fbc55e1c7223245e9af5b09312f819981dacfbc1105996e88f27b6d2a260f2b6ab12d9b3386f80d78b0951874f8cf63133dc63bb2ebbcd76fc2e8805d8592c5685ca52edbd920df6a4b53718ed2d791f9005e00d1ef679edcd3ebf1719f808bc9c700ec06ace9efbc31d32fe3d033560c3a88cef583e0e2ca13b574c13fb9b297b9d74effd5a4640313abc947bcb48235e330b49da7720cf9fcccd159616af63ab41f5bd0478a8a602d9bc9345c76a1f2c768d0070bc2df3b9762e401c97e8bb2f1d1c6d19058897f729c16fc1cd33a788d110cef8c3e94e29b425e7496b49b33c89321d1774aed8e672925c966d7903d63a11b64323fd284267a03a1d5fa3925e58e785e51b5fd4f6fdad90eb72e7815b31d30f266b8c2f81da0d6983ab8c9e22618eadae426de7031deda7ca17804ef99e46544911d6a769f6ac7b23e441bc96319da1c8323726704782029267afd29635a373c2f97ff12136392efd0528bd44f635503d2b6a7aa3dcb7de011973d9547c7339209d46e40af776701ef86499c7628ba36146d1e12433b552fe630ac42bbe30669a6e871ef3d47e93023ee883ff5300c865707eec9ee9a041f818cd4188046798c741828b83c06ba351ac3a22b6c5d6e905d38ae6e37c40f0eab05871c69e0fcd2a190eb4311cc53219b458caef1b33cf7a71a8e80fba422cc9bf201ee431f7a0b6e77f411ca25b0cb22cdec8c9042bf84d26ef4de0256ec37278ac8722e894c203f5feb8ca2797a02f9d3845afbc130b3d9ec75f427cdd27f7d0449b07dd2a95f73c79ce9038fb03d2af94f4745114b63693ed184d4443adc1c26e7d5f5dc574b4ad1ef626146834229e5c9ed63185b7ee020c950d1ca715589b0a95cb61a2637b8bda10120a0335f616e821e4c2882b6a2bd8fa25bfa88924d14d7e2292e54eb4f7233ace3da17fa6f32ecdf3bf3a4794438f3b9f832e73723d0d393d5596eb48501bfcd3280e11c7b70a73b08927a43c4f28ae722771f07780a46e16bab5c3c937e23d8b55397514cb3a5cce89459f55b72b4088b91caab967ce8fb007747b3f38a3377c599d1fbfda1d4a7ae65002face8fdaca2b083553e87de3f5896e02805156e0d71ee5944fcc450d3938016013a8d0d709d97fa9948ef9207cf2e620eb3f2bedb7529e3901a75719cc88517f5102c4614d6253d2bd9d7f3ef1a96687742503a0360a71dc85094c76be8cda0590c17f0f5856b6c8e9c04d9816f8fa53b6c8394a6c2933e093dfc453042707d7f22f6aa79bc4e0d6fe2cdb17eef233ebdeb8570bbf30a952a69d90df002c1a0480005cb8a6a12713e7de42142ff5848b3fb7ca268e3e2a3b68876b6393064d894b7326f428824b0042c324be77ff4145704f90978a4a6277695ee7ac18805e2ed13220491286fd1039bf11f3b1610a83beb79f175b014af4ffe380c305f36abd6dad40e8e3339f4190bad78145bff7d0ab424c4e3724da2d3e20512c82eeb3075a5f26fed40f12974b1644aafa62b1e97558fc072255533367b0746defebbaf63cd091f31e5b1f0a80e5c22c4c34e1ad68eb0da9b6e09e9df2e4b0e440f8f10812b210395bc14e20474f06d54d54ad78ff27565432b1ac53dd1d64e3d7e9ab7f50875a3c330e759e76a60d351619070e8a1437715316f07157f0333351c899deb20820ea568cb675b71c669325247b479216461feabc23f2797848c42651ab3f4976d9de701e71d5df03180524ae6cb38a5c900f8924638d9271e1d4aee733217a2220062ef1ac5a6bbc00a09b7bcef4cb41146fd734fe0021f35c9287fadb76cde9ecbf00a4f8639982f1e20e837f12e970b55d1111850b10aa575306cc6c88937e41ec789a0f81da85df593a2c7ee0d7185a37efc0d726ef8a8daaa73a9f1b88eda2da7a2624a503349499692a1686c99990affad100801a63f31e2500cb32ed3edd8d85746625b5d94d4225971d6647cdbe4bd87d8bee7d788c2e16218e7a432810dcd67bc6a09266c149f3522282231aa885afc0dc742dbf2a0a645f40e10621d709016b6dc03aa38218ff47f8449dac78300e3abdc899cc161122be8f82e7d86395571c8db99ddfd8a92c2efcd3c0e9c084420cc8b2aa7d4846800d08002259b3ac371590cf50b80d50abae4dadc004c6fc387daf60d0f73e51a4ebbdebd725381e06c13d8afaad461d4bdac6dfb347e95fed32dd84707d07f32ca6244b938a2df10461f6158af9b71d3a2c966fd4e73dea272950b851a9846c02d36ca02d0b4c621e92e8d7300e05c198977b57e34aa1f504a2cca1f7609b776c55828c90c35a604d1f1af9e1e7815fd1dc88852026cd817d3d94a7aae6155ff30f6903703fc50f9ff9eb9f32fe84aae19c40179be7c0e0d927fcceee2312394cab7500696461cd20543469c71922e4c15f3a2840d5407946cb9c13cca6667b9bba34ef5563a2fd26b26adcee9eaad40c506deb068c87c28a25ce4ac7193fb1981c7e03c56ccd12bf8caafe96371002092766ba901f13c105ddae20b71281e304e62c78ef5ff360869eb60b84e979baf76ded16721e89990fef9757c959cf270fdc9007a92d0fe5860f744b21dede2b55f9f9facbed30acb4f27b4623add5a6a1bd44b4074fd531a3e8219129ecc41d81e185dc3b0467fb2b3193cbf141a8f30baccbd51f155ca065344ce171ace7d4a80585a11a6c073a9e3282a338de6fd909d7a9acd2c9685806d11f6b7a7ec843690d08de4758ca4c016eba7dc9475158dd36f00990189bd5b07a54f0256b2b59f1f41a361447127df7aa29af93fbbb1ca757b2b221c4ff0b4c464656ba560250a491a1fddf9344815e6eb19820539aeb0d3aa57ad05424a6be231b5624c67f5a3d28fc18442dd08512d909714dc8874a1c284a204882677679e184128b933d9e96c3a196bc83fc902ed313405ad257de8eaf0c1ef734314afa34d22b70319cdc419cebc698275ad5a7e0f7d0e3ea6634d65714e8183f24c12e8eed247cc5246843acba50287daac8dca394037d93e7e675890364fade86dcf4d2f603b7ed025608e698181ade8fe74a183a460f203a03301d1b6d687b5cd9af18f1266299f29bbebd3d393958679948eff17f5d158dd1457c15827d625e69fb0d0994f255bec67998c9ed902f3154110514b6f2984cf68f5cb7832b6808238148056ba51412fb86afb38d65140d111bf3e1a0d6b5febb1cf09dee7ff98f06b893b65b05a6871d696b1708848668c8621a0858a0aea2316c3a20e1e9346114f45f2c7ab3ba6529b167b7dcbb1f478316de045103127f2830ecd763d92e2372dc5be9d1daba5e0b5dbec18763e8256adcd88c32cf1623a6f54e8bcb99bad1a52ad75c164fdde84c114f6257022b386c038193941422130a3cfdfeb95c416c53b25ebe54777de417e7a79865af4a207329b3f84f366d0a115a3919490b917ef14941df2c6f27cd04f0aa8106e628e92c76b386abf9a35580c325f239808d13633d2359c95f935634f16862110ff3dbb64eda2e78e8b3408b41df9a142ab8e066798910c42a2e2c86f778a7c4c39fe0536876d398fb901f780516ee6f9ef91c001a22391747873aa6dd654e70d66690494da4be7e5a218b911f7c3464ffff6ab5c1ab906105991e9bedc147b01a25e2358f3e3eaa9f7e2cc1d9d06870495f6b00a236a19e17dc205baece553bc2f94b87286bdb113a4d907e11fb802b7fe0dc3748c6ec3ad468e4b3ed691b59714e2f8d78834f7b986706e245d9c5cb9c345d7bb1f6a1137232585459feff0a33b540bbe0f55bb801b70a63ee3423c03db16171fb19821ea326dfe2b6b058de401699069f75d3126a97a81111305bd5b336deb48c95a6c1d60130176523c1a6c1cc658912e047c54912e0da4c0514ba39f9e0cc0d06cb97dd6c367b37d6e4b20fd160b7ab8bf4bdd8fd4ac9920bc6742307d7814a0d64e44f9b0270d492111e8cfc43606b7f509b96ef2e9b1afea5e5b380a4cdbac54b35c5d77e0a53649601884b4e9dcc7265c8e498f944bd43268364c9c57306939b6bc52edec8054d740555c151c6b366a55014353356c4151efe858e441b2afb29f095e4aeeca0a9ac9c91e50b5616c75e515fb0bf67b528f3938124b02d10729b82cb0f88bec6836f3e3548a278eaaf5e6adce52bb018bc2404dcdbe27e4ffbebb16e9d44cbeeddea399ee4662674a28a2ed795576d3dcabc62044de2618792823058d130f0f1509dba8dc43108731970f7dbd05fa5ff17b93b6ce01e5141f63c36b34d11cc29939564804b9cf98fa249f296e16bbef9e1a791500b98c12d3713c4ac9a4cc2366519616a1fa155cd1146e33d8d35c111406c1e900cdfeda1e2bda1602fdb3479910d1254cce02482bdac45fe2188feecdf23492ab460f7765237debf4fa8f7440004671866716f439c3939aee079ae57790828fa349bb9d263a6fc53de1aa65f7c8343b6522fc59a19dea1efc54fd92e99485c3eaa8bc392d5adbe0d2c742cc64d08d007bdd0274dfbd7e4e16846dd8fbc017e984929526eda1fe97c23e71d8381d45648df37bf40dc991d9685a022fcb2430f73a8d1b755e18dc7a335c21f25552c127023ff180623d74fb8dd498c7c0c53986b17384ca4e0b1a67b96217030aa7a24d6c39dc41cb2103491bc06e0cbf638e0967e4d8961d5c5371bf354eb9a6a7529db08ae3ecd5bf60a94215cac55d92a107263f92e2aa3d2f82b120e70737471560f7b132f5d6195b82ceb476ec9a9f86afcdde12742402a5c9b227e582e934e83f8e04cc31d5072c195b491a00ec454738a82b297e36e1b334539516d6f86356708a0ad91bd17a3e2861af30ca145f18c7c98b646ad40de9478993f9918c256e14240ec424ff2200c2c2e9ee77c057e3cedbc9139e2b92032df6e4764cfc00cb65aae672077e2949452beb6341536ef657f79690eaac86aa564a4ee53279d7d0d1bed754bcbc7a245f24a7af98b0d3441b6a1916bf360ebf583cb3968289a564e3bee2055ff209388f81058b852e52243c1c49d7bb9553d1a7b649ce25e6c4a9c335932c39808f37026ea32410be16d7f918bf9d65221268f8996c39bfde4374b02342db7ac237feef2f9ce33994f69f633361f40cd70a9e6550e6c6c6336706df0950c26c55525a9f44bab34ea4a8afd1217c9e9d685badc00a47e5b009e6b15417f3c4591815b1640ce00f2774ba163c94449cef009505adc4ba48b53c434ba1431f1f818916286484b6ccdeb4f76c9259676a760d0f2e9c4695fecdbcd208b0e41e48ed125ea7a28d9be7c7e9565f5e8c921f2bce7c1fd8b03702d2831c039864015159fe7ea8654fde8f5fbce48815bf8955762b616da05f0e0887f2bb9f543611ccf635d94c3a751da38183f71316d079c35b84d7a9e628466c05a04bdc88d3979fdc3fd67c08e578541e6bade0e3161a7a8670a9d294c18f38dff319506a02f9bc8ad80b10d6cce1fb2e68f083b03d83cc02ed8640bd439808fa0e902e9b1bdb51c9db84a41534b246d4e5c3ca981264787129b1164a8d6456cd57d4187f155311b785b7f2de477dd1147a6c114e445221a6ce380101048e1501d44f5898136505f6841ce181730c0e68bda980f9804f9de6be6d8c04235a470124c35c3275b6b78017d61b3f6b8d436161f09091c9ae7db61feec1a27c02bbef8b141dfb41c8e1e268841a225e1fdc6237f6fc61461c18aa4161d06920ffe6744c87bb25d75a6308343d378e13eb44ee71f45f81b16a12a7f16725efc8cb585028e814547180d708f0a2c98d102e0f5a93cd99ac08949ecfc28accfe672a8b9dc0b44fcbad8fd1d461c76a4785d57f3b04ad5f994c4f8a3f60829484df216ec4399961eedee8111bb59b041e9232cb2e5993bd508f2dd3f02caedecf428c0189316ba87f4fa5819c0a9da6a8396dcf9874c9bc4455af3a5263274cea2697faf1f10784c703a3a8079ccc0f26eba12497080e1e73aeb9a8f995a63cfe5a93ead4e1d7ed9921c0c21b78af7ed9d9d516ac8d00726dc9d5c7922829ff2654d64ac3df22dc3e9f27f78b38f3f6a80d63e1ddfeeb59c42768c893168edc5435f85e6a135ca7173c5eb892df138fe7099c7c8829fe128ef49ab75ebc582d3fec530e87b688670d2b3f51a59b437289555cd744da04f10a7100f8080d8d13915d5029a6771b63da6340bc2c2b6cf1e7d87b1df146480e60fd6c53be531c02d7f31a4c50820e5319c61b4931c81b57f89064d8a1f5351c85386f431286892426ea9e95c099215f68c23817d38315e580e39936975036569855f2024f0f339652b4c51e85c75740ae3d9fcb882437dcec022489ba24b4e6993678fd4c85cb6493e69b4ac192fd4f77afdd3e09c51749d9b93a75d90c5ece0c6bd9eaa3a37a5612c74ba301f3eff94add6417bd2204c220f90dfd1c927d606604f87ca2dea73556214ddea13d917414d96099315a11c3d302b2b70961aa432ee50dc165bbba49cf4481907e71258e3e5a0734d19c2f008206abe48c8ba99067c19fadaae9a0899c96abd2ba3ab69162c91a215d5da5881e614f751c69a74c5d8ec0541a44321a03bf1bd64ee391915cd5038d361e37ab2792ac553080363067d2aca54e2722fc544d63423332d8bf308cc08e3d08c33f425ce8e346d51f7e7d94c3cc1d1b7fa20bc3b0b457824f69f89454ab1e1384c73e0e64fd7801919cef697dd5c24df6385aa71062d7e3a04952949e71af3804bd0b3d400cd8cf99a4d4460f3a05c4942d15477e4143f86439ee2be46286be9d90229b1d7881036e0aa80270a7e47164d5b8fea73ffa9d7657d06ce2b364414c833e08604ae54943f49c1c4f7c89eb0bad3a643f4a7bbbd4814726d02b7bc29f6731ed9445a2060d0938178914b0beae8f7e099838356247ea574a3f9f003858424155aa5ec5f318ac715bd218531d2626e1eae94eb99eeb1660916db862ed52f8fbcb132f1c00e3c1376729e78b6e1d22f022392c56cb67974b5fb413a1cb33ca5dad651c35be0ac24951fbaf1c6a8b0e93eb9714428b36af1a3c5f6995523ff86ca18ada0e1b6cff976b0cbbdae3162c284d0474c76219d3142c86f1a0f83351ba91fc487d863d747aaf3b0da2d72cec230043712e2913822629c2d91c62a5338c173fd7228d4769866bf789bc1e85307bc81fa78b8c26c24921b415ef83f2ab4875353c289c387a9e613003ceca0ce96edc0430c8f7db88a81a27067ae909a2b2cd2c8b292459df237653802698c8097552afb80ca8ce6c782812248c4bba259aed93063395176eba28cc17072f5e74c42e4ea9081ee104b169026353b9b976470f4c72e6fddd8f1e26616b5677e805d3d2ac71d51f895544efb86f0793ff0c8b699ea4626fbb2336039e2fc34ca11fbf1aea1ff22461fd60bf7d86bcd6f8f9ae30059de7583b8205e240f05a6f43b61d1a23545c3d531801e60f5c0794345072ea829a7f5084003caa1404b90c9ed84876b9c9a7499308a3e0241a4715f779a33cd5f302756b22df7357fb1a26bab7bf02d2aeea1db427a784fe1a9d878806a85b1fa13fb44416ebdd04746a4245ac7b06423ad9b21e193d5bb0ebd73db5fe8db522014398110173f5bb90341e0d9d38ac4f0990d553be5215d6da88cc15fb5145562bd38466a40dc320aa757493a26e4bd8cc12c5200f4c601ec99795c9210c916bb8941452bfca5eab46cfa7f1f174f4044db3d25c38b3349c5675e004c4d29afccbaf0a363e9610678b55dff82947071db794d94d186aedb80f6ae695c2194f3c7cae24d635670899d996977f0b4e3d4ef54190f2e9eabecb611d8e7836551dbc35009415cbba97e50b5a864094a55b5f20bb49b14d7e15f64cdb496bd219f8267b205aa024299fc8a5df6a7f3f7e94a12bb25854e64b6e281aa943854dc3c31a41a6450c3e1207acf8af9259f792fa99350769d58b6df6dbd1522e7596b6677b66a3f76be6f030e06acecf5f68d8a40c61d20a2bb01c22d8006f467573cc7b600f9bf859aadcf1efbaf2efe1590c3541f316428d05647046be359a52d6328fecd3f17c93f8f6847b2314e552497b4d47dfa1d5c91966a806d1636ae7df95be10bb5dc3d0c5b3aa1157770cd26017947593dd2910fbee83996c68d2ae693c959c7a732c8f3d5e9298123b66665c4cc6e24cf14022179dca80aa8292124653762758480566c448f9079840b2df1d0b4a2b50f644264db1291326804cd95baa7bd0cfa24e649777d366b895cafd16a72b0208812025fa3752c8e5bc6818f5c8ebda7fdd367d7bcf3558e3c7e05de9430f1e5672e579c507279ade88a4b255c3e593f410732bdacd11f0d6ee8464b71c0023ef79ea2a7a406dd5e1be32e97c074e302f73b5d99661b0c36efeb5c721d8297b8b55f92ffe75640d633ccd3a44a2c29f639a6361e462db691cf6b32444d6fbb6c88dc21d63b8db2cda2f012b7b46bbe2b253f4a63e8d0f5c2f637fad48f901167ef8aed89c56b4e7bd5f515c605b809ff0f41fa93b1eb003b85f02ae24deb775aff054ae1a8ef034aded829c7a1f7ccb718d58ff522da9f9393dbd1f130bb1dd5cdb6ee61ac3822826f9f61a678d6f207f3edf9538b5b9014848674b5071b07307b715b5b6f93c871ff56b835457f63366df690e1f806609675b9b6db0af3571b0f04420ca7bff53cb0fb062a0c609fc715ebcad55fcd9497e4e898693c690d7153509f252df84b7e9df9533c8d022876f93c39e017aaf07be45c268241c50b613a830b550dd77e7c9180ee43bdaa5916cd223c1566e96044b96e8053556bcdbe2a5c3b903eea33055eb817d7c36aae87d795f168247f29f19c195617b2e40cd6179ec4bbc577f86cd74d46fc1dea01a4f31f0cf07a7851a87fe99d472bf65330d376ea7cd3a0fe1071380d19a87dfe20e16e7399a10ef84f1560b71b9edc08d4e2d22a6f78a89e383b1edec4140b84191317eeb39055ebe31782fec44a591466b45583cec81642b3a89a6c32881be04c743bd5483b7d9757e0cbc73c3eea1d1155f35bef6af62a5a15b48e58589cf7502dc6432c0da755dbb264a596e9ff0ea95e14e0b0562b6367b27442107acd36a6b2ada732efbb8346349a3cc2b148f8e5894cddd2dd0fa54087e800e8bcb067228008870660f41e9614fc98335cbaf334c659e3fc72b442c32f9f9e23840b860f11fa5bdc2bc99beeecb108f33be8fc359cfb807a56b5b661fa08b1cfd2ad182b3eb3d0f32cf68dc0ba23bff5e92fbcb72b133c1497be6a76886014ef1fdd09dcdd1d58094a7ca599d2c0fd99e351d9695d3dc6462e97fce7b823665d7c94140b893c51efc054de99e2fbd28fdd14b80515a91c98254199a9724b94c61a4d07c3cb19c8ebabe8e3d1fe79488b4652dfe9c0a491f67094c6b0602ac27d3e8e59a6bae0f71147c1d6da1bdbf6cb046d5f7d33d07d225e9cde1d3c43c479ec8428192e2563bee28ff769ab87badaea5a9cb2478527cca698fae8bbf59ac49fb63b13e712d1bc2591f2ab0abdaa9d3e11d44521deb07cd5705d453de9339dc37128e7ed3a52a8e8f8ae270ff56b3e9aa27b596aad85546b9f393cd7e05cf82d89f46848855f0d46a375b08c35fa8b37023f32bb39202bc853543d2b26be7e00dc077438d16d4adb5ca5d8cc13ebc0edabedeaab6fb9229a9cb80e6a4ca9af6df21142f93cd4773821d122a916530cc504f05a0e789dc6b5c4d45c0c3c587944c4178e3685b2c496e4f523d2499a8ae5741501b48646f4bc853c7d6ea48356c717311763a3b16e1e8119f78e78835681cfcc4a1d88308e58659ced19cdcaf467c6383ed4f522cd1292b6d920e4a3e8890df8d0a0beb3729cb54ff02580747172ed7e1a816d35123e32e336c26cb58e608705a78c6346d54f105dd93b8849f1a13da4733d8a46a65b54d2af3399994de7fdd3a6f05446c6a8ddc0e9908c15dc15cacfe11061ac56d0501bd066dd121a212dbc5dc880b641977c325fdfc57cc020f8ca1555e45de688208b5d3533425e706c52bed8dc4a47d5dd7c4bdab9348f25d3cc78f00d0dd9dcc4eba2c731b3f2a7f822858930eb8f8a5b24c8ae664f3b736fa65a9d7cb44e9d7f287492555acfd877544a9b8e83dfd1c2c53a7eb1f48fdb7adf90333a803b247492f5212cb69552b7c4e185fe58c45a12eeb2975309a4cebbad6fdcbe1b25d57aefe23ac25cf7464591e8abb495b4a31bb4ba73d06e290a70055cbda55a452ad41dd15add8b1ce9f8b1158bbf5a5d183bd5280393ccd0e3a42d1779d5113d01cb1539dad3aa061b9e30093babc42a2127fe57d97063f7798610b747f02c495b55f1f4a03a38c706466cdaf789eebf82cca093071bea8499e16fa2c9b57c964415419fa240267b33a50031f358b83de58360e209e0bfb43fc69979a47a799f8a5ba91165129a9f4f59e2d30d61fd6787640ae1cead847455f7d5bc35eb7f29ca7441ad3964ea300e5ef3ebba2bac00ad87d1886c8cc178bf4a13493b29332a54fd01f60405551afc63ec6f9fdff2b4a75c95d80d8d12210192192c6ba568b2d93069b8a8956c10b867d5e442e179426a2b88b213bba8cc037687aa499e0aece384522a29388718309f40d5f82942e2a0f337296f3328f75551eb46ae97225411cba07b7e4892d3331b9a570f154ee6cd99293d4e7d8525187915f47af3c6b395a6270a009b0b258fe00cb0dad6f668d1b71a335a551ec3530321c3ab8a04085574af56c120880866cb76a6587993ef5350a9642e810d2f4f32cd927575943b6834ea1785424080958a12a918d49d2a6be5c1a84d987a5fb3aaf54d8c51aa439b29aeb7d901c9d0107f42bfd1833a87713aaa22570a4f5f96103419c0771f667c33e5c4d444c38406c5562f7b2c145ef83ed86bf8913f5f070f3e0d047c5fd9106249524af2ce9f384926023a33fdf978a4c6df9a03533b524166c5c83334bf89bf4937ff87a76981b750070583c7919014c5835284a422a9cb317cc2fd629746718f3726df44b1c9198542d805a578327e6f1fd548ec43063922866ab83303c1ff9275319f10729824c1fc63a4a9d9b0c89040c238079202a7d0ffb2b69250761152e280c439a2248a70ea2cf3a5a03139a7509e1e3f7f59b602039686a616b4f5f9205e13084a0715fc243b0b8f36239c78bcb3f5fa7867569fc3fdf250e8246dfd16d9601105480788348641dbda7250e6dd392e8bace96ae0ec21c21ed4497eea5da02408dc13a9481db8e0f166cf55f9f01bdea053be32c85d1fa2fe860ee6aa0b9eebb58d8812cff4b624c8a3c1dd43d41e7dae38e94ff6df8298a7fc060102b0fc378415461f26c79721b8faa27f2bffc059f603501228034c3430c865ca3def301c5462462777aaaecb279418d7a7b7d688cc9574cc3ca50094ce3e4393100c51ba8d026eb1888cc988c6d6cf36d056b4e181798d92b630d43b25cf3f02195aa0d4883828a997c9616601e8cceecbff89af12881a496fce5ca5c218c76cd7511add428eba094f587f0fd928198e559c1583e3cff159b1f98af8d2851ee7191ed3bcbabf45348451c26d16910c2932fed577670a07b4308c53ea14ccda7d415d5498c8ace6a6460bad15ac5dcf1967edd2f14610e57630a089742f8a9b13e549ede8ec60dcc72d5360c1dcb25d3ebca23e3467b8830cb08ebfdc9d125fa27c2e588d08f20d2a06632d94224626f56c524e9368bac3a26b52c9a6855d47d72bf04ec0044f52131a431468949f7251b3589fc7549a89b931e9df73ca42375802ee658763eeb567e0698187ebe5f7c15843b7ef6c2f9b375341ef43cf77afd621ba74be86555d996fe834d8c11c1c753d0789ba37669a0996e68b59e35ddf31edf2b04c571cf2433c5727a0b32b1d159f77c60e29e556bb81bdfa3b6b3346f88a0d55a532364d5fecba74da018e715d91c9128acae6558a70269fc85e1d904b20b0aef87fb5b1566f1123053c9dbe3db0d4933a239d53170007ee0119558b90cf63d961f5c15c6992ef22c95b022134317106c7d0c56a1036ac8e167b40d2a44a4c62cdadd5d3c77b74a513b7401f98c682b8b020215be21cd5111ef0ae699946c75f7bd5577ae152761ad8ba03fc9f2f097e265a379b954e2fca6575a2e60391e2e84fd160447724e743ba2571b85126a1c76fe514a1c3de9a781b2da681954eb25662ac8715f2e5069ee3752e78185ef019f9cdd6da7c7dc8a6723ec04ff8f543f441d2661d9a808dd914b8cf7530e1d6de2d74c6a9de31cc5036250388ee29851f0e85112066f01a04fe1ee405592049484b0793105390ab6a5dc7168210d89269914eca8fbfea500c077f28a69ce1a366a38fad2093d0cb276f721ffe4c59c1ba6126fa8ee071af515b3de22bc96b8dcf6a4ade847a01d7e4135292718a2d2e0add0384d7a79d3e56cfd25428d885e55ffae1f5556d0ee2f5587346c220e8003bf1a7916dc3ca915a4c8e71b2bc18b5edb5e934e8625bd7c7c29189d842c36baca0a7c06b4c1ba8f1a3579306f4caf559f016df8a5c5ae96a902a7c040f91e3c5fb9848df1702bf09e365c663061b02fd199f3d162d24164533affc4c8f6f8bd8bdf3b6c901e2178e43a27301a1c5902a1eaf1fb4f85e50cb5a2c85b4c02d20a4a5bb47b118072765f140e32963e40f5557b9222666ce8641b8bba8e5c592efdf3d38c801c5aaeba71183ee74c05d48de3da28b21bf531eac910008b6a7c3baba9e60560f036c32c16e6bfd7deb9d16896f5369d2579dea22aa2186a3869be52b3f636f34ce97c0de6d9601f8bc195c59288260b8228852f382aee59d7b668a1b763ddc3134f99113ba7afaeeefaf674025afb1db183dce84c915782a9228ca94834e4cc1f265b5fedb66504aa60d1cd82d548a830e8dea02aca52ec47fed7cd5d296e693c9f7ecfc67a80cb721aa7419db0ecdc2c08d6ec1401428972bdccc593043a5aac9bf824b70ca074d7f63aacf9ba6e72c9a248f78753b509971f0aaf4e79f386e7c1811e8699d46217d87a31d101becc98f8f8c757e510dcf7826f05b43f969dc401b814051845c36cff8c00fd1331ef31efb95bfa324c0cca391282cf75258585e3346cd91b21fe5da95ab2caf814a6784396b7469f4acbcb3603d5af5bcfb15c84f3bf4c6754d404feae786d2f176fe7783effc714a0f7910cba6f00bf6bc4ca2da359ed3734c5f28aa257b84e3a0776281ce2d7902a65c96457c311c89041abf41fc61ecf7647f0712bed908daa0021b0700b1b0c68bd720bef443c118f0baf120fe7c5fa213b5d23c017cff4692b9dd95df857295628c29cdad5c08cba7ce5ba53514834d74a4b660f9f1fbccca1e83e10e89ec0578c0959668fb436e51189053dc331d42a1607c679e4090c6017192103872cfb02f300d47343d7ea10117fea905532dd6b61630d189c501325e06b64d53602cad5aa31e1fbc82c2c8682fa16dc798b0c73216b402a849b564a524e27e620e0855102f3b91be8434700030511c12e84a21d75dd77f95f2f05e1de40da2578d4875106cc53a0864cd573bdac96f65b36950b00ab1cb04bb2e6edeb1f6c4ba90ee0cf09bc347dd955379566a24c742f3ce626edf6fb38ef185be73ece603ca1d3466676a39d692c74f04436c495d269b866c09281724f914bfcf6d0d5be93159e8abc18a72206403c0b50e5f271d7d66a047584f1039157516e222941ec506620025c6981f4a6585424d87751a7eb762dce3a2ea1207608e229a3c72abdfeb845a2660b28ad6393c294f5bdd3ba0527022580a06847c71c7d98f16454a88799e90a43006d69ddcbafdc6a5eca74524bff1002a2ca910682fcf5d991e3173ef3fe1fdbbdde64fe6b2a70ceacfccfde4aae81e146ae88426669d7a754ef29fb52315b25c48e2d84d65d9bc3109bf3c852af1a87189891c9e3260989ce8920dec1fcc835c959d088fa1b5483dec5a5fb397cd273d77942f7389a656c00fec3284ca0fddedb3ad337e8476c8b0eddcef591187079ba00a7a14e1405ffce9f50580e6aae652b7f12c1fc4d514c239bf2a95559663cc0fc85be6c58b023bac754404064b778205e52d894c70d6b31377ad734e5081d885060aca23e4dccd3403c9d535b8557279fed82c690aa12818c3edbb64742ad8f092b6046be6148ccaf2e0363c7d85330eee4afa7237802a6820221863e51e3fd6f9f5c3989db6ebebad5017e3490e1b5a9cba19b40dc91b49f9e914a4ee728e6a3213f33e1c94be3eaa61781603e32ba41ad8a4c5afd5cb9a9f3579e4eccb60e4f8a7739b1432a81a63fc3b5258f0e791d65c7cc97c94bbece688256fe0bfcca66596bc717d75338d89925da126fc4b43e28b0c02d6999af0c197f7ad3d15c4738aba0092ae1952f60891813147fc45c8589f74aecbba9a0827c72bf14fc06253b1971f276c75eb4c1536cc634eb220177d8035cca3cab29519b34cb2d55100f7498bc1f79da8533100e7cb7e9a87b35b5099955e5b47300d6a5fbc880aa020b7096a66bfd34ec19ac5467fdb43552b501ff4a4de5548a9385aa40b3edbcddd0c6fe3702c6137d40cc2dc28974692ea53048e60ba53e777e7ef3f4ab010c57b996431925994d498b6d43c15960162296a1ccd0a4499506644b98dec60f25e7e3ddf029ff067f1b499d4537ee4627537e3b3adc02a3f46cb0588341f116ab5d428cfcd860aa4c1e0d8ab668e0e01471d9597e7e0c7674e242dff7bf02a161d79303d0267d6ffe279dae4e8d0a9be9d9e6c057c8678b79b8afa40e9ea24387e2a217f6c2c4a1e94933567a43242d3a9856c3eb5a175d445abc9a8d09a7b5c586b22d8d0f535a88b6c64b46b4c2f7206ae474fe843962056d41c58a70fa86dbc83c875a6ec6f9cd9a879084ed19a3999aff795a996c9c084b75b33e88f5f374fa92e1e03193c6e45a02ffac065d5ae1bd7d62232c4dca862914b2aeb724f14f498f11c528cdb68b16bc46482c5e5b3d13634d3ec8e67c3e552b4664fbc3cfc123082dab5e560c1aff0aebcb9f4b6ec8dcf5b1b231baa59c32b5578ccc54b109e43e7160ea7207805dd334c63cf758e04362c69d093c1b68c6ac2de3bd707cfcd8da8066765ea5bdea941139c0db092dfffea54808cef8a232694177ab17d7f5c97289389347b83cb33dc72ef157b298766295c4111f8ff25f8f1b38ba00af6074eaee86b17e192db2932c3165eddaa1ee46d355232ee844456497ba8e103a5f6e611e7fe72f900798b31747a88eb6800d09bbf09d34bad628dc7a1b00e1f81ad874619b5f1a8852aa0aef05fbb5b5990e672ab6332d7a0fa638c14a0a0ee024549459dad99a125d15af537c977802974e4944d1000633b8fb48cff0945154ee69047c5c1050e0aac8a581f89c3447aa458d114fb42239cfbd132abdffb87b08e1e15f3354e4944f12f4e85037394897ca3d0a512183ffca8cbf1092e98d3abcff28f118a3a72a0c4f6ee83db674a0647e513684846c39db1c6d4f061eb3b6a147be006d31a3eae30bd86082595a0f136d6993e0cc071c81c9b9112528383107648ce3aaddb6e7be075ba1f4012c601a514368008dd85b2ea506d8719b805112227ff171b2a6c4aeb290d42437939b2442592cdfe67a48ea5227388026a0b21283a8f870281d2fe97973738efb8c499aaf3ded77fb2819a82efade8eba95330e93e2405fb3b11cb012bbbe3a2197220eb55d9de7d63af674dbc1064eb63ea6facc21cb214a1fdf9d8e96f05c7946005ff67294a825168fc654335ba99bb381fcc4216b76da9ecf19989e7097df11dd7e6a4915717d7f8b2d924c35506e02318ee603c74061c9fcc813ca58c1af09d21c4ba754f020bc4609b728edcf2d7c2e4a3248dd5405719c9e98df80bbb63c40c8e8bb99c233688a6dda36e873189e228c9574d37099dbe2dbb8f318b86af32aae615e67e46d290b256fd26a398d4fca71691f8ca390b9c7af221f079b2e02e1072bea6b05be4bcf656704ff2a980bef27498ebccfe51e289a86fb44a365419be647ebd08c180e2d256aadab69c3080a499f9030dd9b96f0779117d964c0c8d0936c88f132cfeee15365592e46daa6f1f5c884264af51f876c169010a69dae6fbc3382f048de9bf61338b73f4ab5f02d2ca32f84f91c45a7ef25a34a9d4daf98d36a26a1592cfc366999369f75d1fda2262695fff49a071a14afa7bbbe72385e9be60a9b21df9e09f435e88c09b615185c564375cb2d1433dda29d0a9cd5eca59376dbe4ee6b4f467e2296a18aa4f81ac02213296990b283a1d36c579e8dfb8f846e4330d139c598fd94cfa777f3081f2bfca1cda029e63da1b946f213f9da70cc6e29afe479444673a73ba945a1802fd87f7f299165abd1499c79da2684f26c901677ea1e453cf7a39e774b128905eee31cc996dbcc17c040c9359a9f1bac8dd063436c783b225e722f0312bf93730a1f5cfe16de425ed030b6065e85f8fdd6d7734ec1981d52205fffe8daf6d5224b8137bc05981ea3109d4fca1be0c810e99307cfb8a4e131f1ab357b785ae0425e8868d71724b79f5a71cfe61b8cfdd9327de5a1431b1bc77fdc804339982b96e026d4ce8ad1f53cc98001121e2f5225b4fb84a22469deab4fd2780d8e76b3703d467a465634aa08f79f01e34000bcf3f011b009c28b42c75a45111ca824441c147a89a7cdde1b242cac3e6443f8c2dbe8a20151f4962d6f62364420d65fff06d5f034d2da4b2746818b286b09ea7bed83fc13b256318e407c81384a7063382ca1f8bf6bc4e48517fe08c6297b06d0cbd6019414690a29fd30cd9c4342854e4b67f347c861beedf4b02b3d424cc0ac0a4b78410952cf11b4f2166f90f053cbf38fd104af7161ee364fefd5211423bbab5449cc5e7f035f2a2b1bbb313e110d0ee4d1b6b58d44c1c3de90c0fd0beb54ad1dc064b6b787c8ecce420137a3ed3417039de9765813397e3cd8bdb4d0ff0a2b7d9a6ca0031f1950fd96f9012f35f4973175c656443217d9fc8dabcbb458d9f112ec68a7987a40ca812b17fc5bd67f6ca70d89df2fd88d6cbe9f44f2f924f355860541ae6f936a94a6fc65b636c0516b10c5029573b44d9a529926d1ee84abaf68daacb8d4af046de4cb1747fb7a8b9d23052118b534a81f5bf6078bac85b7666cdd3e3f5294c198a43cf0e9edc3279d288bbafca0caa7ba44c50d432ffa00869c0d3e1a859c73bef7c9142888e02a6188e5aef0f762b117949480a72aef49fd642f2a7a2bcccd4a20a0080b249aa1608392fdcb81c6249d32d21e83c2d04c65f5542243e052756976bf7243471efcbace1a614f4ea7ed4de64a7ccf7a5900212a51db03b34be2f41b563ddd989fd079a732d01569dbf802727ab65aec2fcac2df7a1b7cfd05749930a77644d4d55c136fe5aa47a2dee5d9004a373c0136c9e2385c666fd415dc1a4e4d3f0061d313db364f6294f60f2f0ee974bb3662bf87ed336634c4531f8b3d051a9fce19790eb924b833ebe8c045ad312ee7825df5b41d45516708d2f9ed2831f2ca1739cdccffa17a318e66b94011c975c1721d8b63593596450b23d0e9b6cfcbb9ea1c1285abb561b1cfbb96417c8b4f922f6ab7f2b0ebd44b9c3ea59178d252b384387f44bbe22e05b00ca713dc5e67367f98fb8cea641c7e803d7493737022d1ac1da6b41f48839342eabb19687401211ce6f77d45871e878f9d2c18b1b837d4611640dba82e3fcb827ea1bbc432541546c2bda81a01879bb2fcff748711895c0ce8d47338c150faec01c85fd8f7b8707f37707474b9fc378479f3f5b93e593102acce44de8a84fb2c62c350716904f1ebe596ff6874ce5cc800a16f6af99dde74494af689128fa7b4b0ea2d2b986504cdc4f64ee8a74462ac3b51824b59751aa3191bbb0e70af3a16a865604df4356e8b3157aa03b55f192b45f72d95fc552c96e033a827c6f5937da44d6b16c78c5d43824603f495ce7d309ac420e9061dab768eafa78c0f7bc4cf3e57ef391bfdbf7e74aaeabaa204e8152e0061a6c2a71be0e8aefa0fc6aade9e994bb5439b7ba8de53456d61a84d1d59c867e50ea969df1cebd011d801e9a3139ed3bc2d0524f99c2234461e22545a408d539650b381defaa4f9a35106aaf89c038acce3623a0e9d0eeb3d3471246e03720a60b6c748f3368de922502319eb716bd260d74cd03a364c97f76bcb97c70018dfe9e26f6982703eb3e3ce831deb0a2dacc92b5d8576e358da850fb49e084a202fdf5d97f57dd4d145e48068c85a0fa46ab1836e560827aa32802c61544700fb0e0a97206ee0dfbd650645e99c0a686fc7b5f2d9fd95f693ff61dd34ff208cd4f3c26eed4a6267dbf574c3f60e4aa680e741271bdc522d21eaa5ac46fdce781b6c9a380766e3ec3372c75f2c57014a42735d20ebdc007bc41dcbcc3a808ddbdd24f99af727c1e42b24d9d9505b3973164e6068ffdd8d172f8b1204a558a34d38a743e5cb88797a53bc4de440feec468754caf0e2c341679e6840dcb677103d87f343db996a5996a20e60af6355c6392af3b5c90ab0fb180c9a20960d0e07efe1df80c242382306ef787514f4c186bdb9a514f76cb587dd556e793f36878c9c6e725db870ec5e7c5d06244cc3e4e6d1c64bde84779756cddd44f66391dd7077618d51985ca45cb8010681b75d7112f4e423a217bbc403c3e4432225afb5356ab59f57109fb3ebdcc919dba08b8e073123a789de7669b91a50dbdbc5b866b23c783198f4ba3b555c71f2ec457c5974f358a687724f111532c3d9ecf3c947ba5c1476720ff0fcea5ee031a0f282ef3e319450b873705f0a12d108442166e4494f4d82f2d89c3288c7b7ac5177037682bf9d0e0f404071f1f2dd1848fc8df11f88a1f5be4b4fc098161b2233d17c92acb861e5e78b83d2add5c58dfe591193fcf52413ef7bc7fc3102feb4c87d8f0ccdf64177626125f357470ee2766f9f806e8ca4bd79e2311136ccc045bad10ab2d691de1cc6399433e4b1f77b2eb47f3f39d32a98f2c96a93b0303c96fd8a2d8ac0a37825f07da91a8d6a7a270f0d43717402620713050032c60267abfd294e53a0a9150eb65445455e32e6ed4dbbae7858be4d8841e28ae254101843e3f887e369e7668ac383c38924ea08a1eea05051ac7d754e87324c60e805bc12766e826a6c7082d65a9e4be20c7ebb4511f6a642345129e55156d5d57442846aa5c83387d82cbcd64664cb737a171cb1b6ce97b174e37166aaded1ef2358695be1c94ccdb91495f6692e1114ea21bc920e6380fd997057788767c30cfbef53b81a9f2289eca0a4804b048f7150b844cc93e49c3911e6257f9a3ac2ffbd669a9064ff28556c04215c11ee35d110c7b555b0ddddf12078f2ec44d6d95e3d0686098a6848f3c6a78b55845443ba6b16ddfeef16f8c6015328ed8d5c29ec088ecca5dea9d0cd9b68fa4200671e553c2955620e651ed6fb4efef1846a70878639ca22622116f5fb8b7617b348dd54b60fe3901027444abc18337eec0936a3a880b01a74cd97ee2be11d8972df3af7b2f2d384b22fc6ff64264f698a3d0ead5aa4e63d913c93f13bedb0ba8a5f7af021e9db01fc76c5e4fe944ab6b7964baeebdb6dd3c056e20b70615296a5061126ee1c6f4947ce69e08c4b99c4aeaed95e91b99aa0336c2ead865cd1e507aba16d2f88fc695a47ddf946fe0c19f511602d98ffe48b51ffd11f3353dcd139bedd76969ce674cc201d681c2ebb7fc5ca21e4bc53864de4ef0f96c8c1513cd01e26982aea0bec34c8791f0677bad5ef617643321e164506ee4c16cea4a2070bf64b42002c34866ab19360ddc3557576f9add31d6feff031b49eb6e490922dca732e7a368e6b131910092f574b5573760ec0cf788a16a40dcb9bcb91e2e1bf455e3e310563d0fc8997bf67b76f03b109e46e862bc27da116018ca32887896bda74a05ea5c111daee99100b11665670fa740cddd8278ca3f9eaa110385b60f11db22479dc7c6cc85421681278dd2200b23cbfa8fe618d275137688d335111b2823082cb66c37f76104be175c918f9fdcd86cfc34cd8065524ddc8e741195f7a9785b8b791d996dde34e1ca109887ee18def52ecfb4df4b759483442f4d0112a357e35321dd1f325e5e30eb3c97d8230d1e84c5ac2295f54f12608c78391ae7a69f18c647cafbc20832684d3c06f12e8443291b8072c4c99e1b8cfc1720bd5e19beaff324ae5f874cd0af84ce694d00dd84bf894122bf6a53199d2ea8057db37e14e9a057be7a7dc82a36a8b50bb9243e9c61b9843cb8867c50ef273781088640da142595f80997db8b485275eae9ca772ded5f9fd685ff701d2ed3314de89634274ffb921639ae2b3b2e6dffd395ba0d77c0722060bd2d94ca323b937e2b8056ac6dcf2afa5ff00be75fb102e9e7c947066001e80c7a519c3503a727a3df72ca339f8db338a7a6e2b974d68b5e4a2f75cd283571ed90916b2c619b09e3c9f4102e74fc9b479171f05676c35ee8b2dcac462c8c223fa371d7b3c1fdbe4b04d20ec20075bf13ce68a7d1fe73526ea8cd829f32d79e0b1eea0ec7b7afa64fc135f9c8cc002d2e2a90351102231ec9a2962fb96d8d8f4891e2246ff9130197047cad5adca757c74437d21bc9c805a837a4b62636b5149e15c02e26ebf6ac42383ca48cb489a5c08820deb1bf9a309e0111b3d42ea3cdf09b581346ea12c69a80cf47e7b427fe0d5c641ed1e23538b315cd23d267931875064a8f537965db436f47269a60d6b6e1464596d9179e3c82ef4851c9738c34062613ded7d4cb8298c60c9f7a96f4b109bd75dbb9e2620a1a9e8954c3c68034ff67fedb3adcea225a5d96a5e03dbc81934f53406b997f454af585772711a7b3cc9d3535f66c80d2c12cc3e3d1813975321fde4493058b784769d137e9ce2a4a66e511f2c327e93334e40cc3ea1fc6f03c2aea330ceb0dc3e340073948f5d991cbdb0d2715dde35a11949f013bbf3d4d90749db3b2849907eb584edf1cbd951787be304de7989053b9e384ef79278f749267ab4c62c946a260eb9e66fa223992b44e564ec5c45edc0355c3c0370a9524e4429ed68c90cc30d123bf40994bd14c25a754510940cf2ee9c14630de2b52efb7a3b8c7781f2ec77c2193a8a0941e37eca682b2fd337c74a4bb12a0f1477758d9759f3f07424488568e1ae9c706c6b08ba1b8b868a9146b9667f85e41b9b7664fb433d04d67ff32bcc966df0d2044ffe35ef26bc05ce25917c1b492822e9d4de0064696d9df6bd8b280e1dfb7610715349ed3ff83da7639edb2896ddb0ac3be364a6369e6449a0ec7fa322a11b6d66a83c205378391d746bf7e12bbb1c7aa988fe8c08be9a0d793ef08a8f3ba56f32589d7a2303d665c4568616a7e477a2975a1fecc8ae785e61ef148056da1dcbaae4f2bdb96d37bbe87894292dde0eec39c426a342190168a17698ca7ad319cee9ee5f26a0c174174588ba1b61959206ed371367f505759d6481572db2376a285d09ad2f92378797e10881072dc8463f4a2e00d85778c46642a0895f65b071b1803995420fbc871ad2a698552a936d99e7ee844b306c450cb021fd073532159225a4ce29179c47c506b9429cb28dca138eed324291084cbabc2c4b3c724d1977d463dcfdd439435132eff08401140358b5e7abcf00decccd5df4012ac2530a2990c6455664eb910c589bd951c91a8c30c7eeddd785993d835d1000f87fa1f046c26fe7a034b14f9beb1b1e89d68662092e629c149e423a359f7659696f27457496e3e2289c1d84321e371dcad42e5ea4cef279ab217b78dd2df8eaa6586f08b01a9ac77b200206e079f6ce107464f3568d586e9375f2d383a182132f99ac15ed8c2d15b75cc4e6c8c3148e6e3699c12251a83eea859cbb988ae03ddadcbce8b49d04372a319a446eefa6ee2da51c6342519363918aa982b18bc5700a4a5f8a5c1a77f38bdfc67fdb089df5380de99ad73fd168234569e22957c80e214b52f698cc912a0fa817c4ac45cf732251e4ac8180c015ddf2728f271a0bb63b40ede29c23487e5dd5d7f3b75836693ac86ce070aa6def697a6b13062f5e6d6a0822a5143a14b28e60ad60ac30236ef71e96dcde405d68b3071941b79c0f70cae1905a78e7ef9c73c4c167743621afff5112adb2488ab866e35af5acbd6bb9e0fd2f8174feb0e3e3dca055ba9429705d6c668d8ed95c88561c50b84e8fe5c69720d7eed3a83237963f461e8627a0b1ff92d492842afb7a14eb436686ce71e43df5b7fbe7c4948ceefd6dda4509c836d46d619f25690c2b8cc1f2a69a20456607c8da030ae6f9508d85508c22eebec9e79505504022674a2a9ffa6bb1e54724326aa91d41883c53648b077be2e9e5864a4d5b5bf29bbb283db8a055020c877aa42b08a957206b8b547f34b5b692aeed043340a3332b229d6824575088f84851072afbb648f8a0ed3ab031f3134107ca614880eab57acb8ff718a2d23b6b9b0354f76a1479fe00fc676a4659bbb04e03bebc62c60ad9f56b6d4b5e4c959e430947d35a1f75638c200c71644cb4485941e2756dc00f9df4ea80f8ab3f86af5a7eba9481116bca9b7d24b74cebae16955fd8ec94c1d3a2d957684188824674aada8da4f87a5d10683a8860a50e1e9834c6ff5544dae0ab7be4280a713ace8cf28b405f8ec4269767a74649e12ef07b5a19050d218c530d6c29ea1b18d2133cdab7f0fa43661851b6da737116e2dbc401d208b2453be61488c657218efc64e520466f1c21892710ebad3dd9b8983ae22c92ab7004ecfbd06933ad5d31d3094b0131825b10499aac357cf4908b374efd10c81b5fc939b6c5a3107a2ad3b5f4084ba4cdc24d13e43c57e2ede44e60a3bab70e71f709c4c0a8dabd805adc12c73a9b01e9ba9f4aebbfb478677b6f6460bb135297dce487435f47bea5e4532e3182be4d2ddd3f2f06440a93005e4abd6009eaf521242c6fdcd1f2eebb3d5dc853f591835907b414ad9b16287f084e8fb174dc7a696d70fcf195d4a511c921dc79e00659595b6550edff40083121a4c8ab8ab7875be3813e1c34e63877092b656882cc976f995a34cf117cc30e30844707e4164eb91bdff4c166e262b7dc128b2e87620fe26d3fca32a9bad41a95d1df3ce2881bf832416b5d6692a128c3dfa0a1b31136f669b4dee3ecd1a7363749172cffe0787cb6870a47e700f2259d43515406836181ad5776a8ff3cf5915910f586ad919cf875cfc3d35a3f814e21c9f4d921956a29a1ecbcb9033b54a817eb0725fb3931db55a027a8fadd840dd7e0e0c691a67e4c1adb61efacca5ce07ea28bfcfe5112d0e6c896e5687b236ae1f0c949f0c89ed968f07fe49297b2680fe27428de7411d3932f50a040d2dd4bd89d172d49ff3fbf993857eb30d0e19763662ee4f6add3b37e273ce65ca70b2693b88e508b53031ac7e5290d114abdd77432c2f8a7636ea85a2061337365374d623ce9812dea8d0fafc9a660aed715a386562846ed94a55f3868e0a151c186032f68fe65d038118f1b94e1f8fc3ce80f73af3ea65834d8556f459e9929086e65b19a44cd97081fd46071e82c841a3dcf2d76c1b23160f54ab5cd0912bfa3a23af989069580d7429db033ccbd7d5a3f4fb66f258b8dfabf16d52cbf992472b16cb8a193456e3c322d5f736984f7daa2fd5b0e63d3c191796954326321b8e94766e9644a5f79b3ca394bc1801a8abbf45241e6a3b0c36dc59030af7e385591bff1a54e6b622f888d034051a56c7c3d650ae8431f405021ab8949c8e750bfcfed5b3f1bf58e174e9e43f295198121a2fafe3eef746207baa44d77e3eac97d47a901e7cdb769e9144942a282cb7682351a744af2b8ed865d21ac51a3c331b63ea5ea00b35610ca36a66e9cfaa87dcb546d6e31684bf197221d16141a81455d64e628a8677efd0479cc0c47ba845def81d7e79d86864652099ac6b02ea28c40d10aa366aec23a5326b71b5e1fd66d78b813324008538efe2fff289e51c461a7cb218a7c80f1ba0869f89334564c112251219d7d849c944d57614ae5bb442268e24c9bc069058122b911e703b2c24c3e24dd65bc8bb350eaa8aadfeada52920d779f13e11b2687d73ab80044965e09268789a6c090969da3b0cada66c38bbf1995368660b35a83d7ae06a7b843ce2bece287ff51a02abdc6b378b9d65199ef0a72d20219495fad061224d241165a544a7d7df22322786e74f59199b682bb014a98c170b1a39e52e9ee645184637613838b0bcee7f792d0e03dbf492390f1790c107a2174864ccc009e34995b029074e0da5cb58f52282adbb03e9028c0abd48f6d5b7c9f01f98617ada1e93d0d45a79a2718f3630cb1e3c51846d0612e8c08560b304fcf4031ae96694572056b24a07159d088bb37ab4d38d0835da51aa8c37e30f5a145d4c1f95f6dc3df41cdc7f89ef4d0f2b5a280998d1ba9eb8412d2862063671b8617458bcf0b2f0f1ec2812f7f2761e7dfffffffd4ff6265bee2d654a29052f0909092809ce0c050a43f9ccf8d1c44ddcf4352971539307e1f0516742ac3d6a5dbd42724b7dd9fc3ca8fbeffba17383d983d887bd51c70d75eab85023759a5d17e2f0e1e0416ce54aa7ea1eb041aa30871d390e0a6a3f053d67ffcb2891992425e1cde6264dd3b4ef4971d4cb90a3529b73e0d8337e4ca0107165e241dd771772538bad43863772541f018ddcc568d62eb1ee9ba29a9aa2a2fa888df6a14bd045f40aa494b2e3af518110203cedf9c9987f64f899305e3d5445e1ad90c4a9cb4c9849163281ea611f1c877084a96cd42d1ac2b6d57449ed1f4965186973936ef5373b912d6cd01622691af600e23853bc71998a780884890e15deb8501cf3e9130927c0a30f5b1c72802465044a9850b932f11828bc02ff0e063434a82b266aefa0f6e43250672797b75f9ed05f000b51a52376c09efe3eea3e2266ef9fb94e0cade383c7beb277cfe33a23d5afff0e9d11eb80e13430e71b9c4c46dc83ad48791ba31fbd1a43e37c37bffbe272409de73136a845b01d436aa2d322d890b29d76f2203e8a2151a49c6e9edff9ca2a223b5fa444f3f0ecfc0fcfb42cdbf99dffd1debefa1d2794f27213c2d884decb6f0731d3afbff7dc04695e32135be11edc85d9c94a759b1f3d1e48ddc426ec02d6bc0b1b74816df917e9d80eac2316557301998f79ffde52cb473794783c3ff2110f0fe223a46ec23d3ac63aba466a529d06dc15c720d6b907af8e7ef758cb239a221ec4aabdfd349ff0003ecf67df4478be48892cdc164130ccbec33103b59f871ef96ad7d91d3ee1e19fc7860f79c2a29eff4109d80b75e67b106aa05977f5fbde2a88664f5bf43e87178a586887e71b7cc2f319f8c4033c3c3c3cdfe11310f0b0f33c08ad6a084f58d4423b3fb3aa31e11111c3802fe048a3e24153537c446b67db59366512de8a65124edf18b1947e32cc69f2be7e75de56bf9cfd59fb6ff8851e73ee5e1385c73e4516575cb982a972303844fce910c77149781c87f38437e79cf3bd07daf371e1ae8be33ec5fdc671e17844acdc770dc4f5d4719d3490882b8d3571dded5f778f66d6b1dddd9e725f9d205efbbd7638f650a9171cd7dd3dbbbbbbbb7fdcdd6def6e6fdeedac05dc7577777757ce4ca3a9996974cb34ba750bd26dbec875edb7c1d1aca7af48a5964d2a25d5b2d9867b1bee6db8b7118458d6d3e7ba66f681d9febb1b11397f58477f90ae1b4d6faba3b5acb8f087cae933ebfef17136862e071151e1bbe1e9f413e9d40bb4ce6696cd9612bc5977c90a2c5450c192153c5802133db0024a18fe194b4e9bee54ae7a93744529cfa49487aee88af2d015a53c5c4ab2945366736bee91fdbae473727e952bf0ef6b85ea95ab0ca0ca5f06d23ced3dee91bd7c0d7cb1454dd334eda56a487b5074e2699ffd1845f65ef5e4d4fe47b714c3355442fa7f34ab8064ffeb929f8121eb604de1f5e414eb90bf2579628b5286485e5213545ac1e447e218c21be9d10976000589082780810410d60b2a595260858923a27cb1031e1891a9209531690172d5a985b15a9af2059309aad49e9e7c8a55952750a8f2fbc91be9aaab02085594f09c78fc19674870ce3a42c2ca61d3ce5e526609ca30c489976551781e645dfefead0d2a00b7fc671886ef0faa3f0c3cfe1838d411c22f9f439db9350b695a74cf62e08d2c030c91610daf9f25a5f8f9fea19c3635ad8a25740828a92a8c84d08670da88c888d0429b9060c6b42a6210845400115332294700e19222796b992081028a60f2a2601a9c24555125081a58f0e4ada50ff3c34fffb444e07575ab40614104d4173e8881020ea0b4a0700694127c48c38725218c98c263eed147abf6be1d3e2cd981ded7a2949ffd942c9d78f2b746e1c9ae6357bbe31eeb7d2357395d7ede1a9ef410c90c8e81100294cabf2f50d58f2ac74ea344a5cb4a6e97fe3a92fde55355551f1d5413eb9c90a830421dc594142a3fd4714775679f3ae006f81085038fdd3d03def2e7a4e598f66662726a402ca5c494b4af557b47b5796ef1cbbbcccbbbee2f594a29a53fbbcbe94bf8944b48ba03954ae876ce5156ded1d7dd7d6ed7ed673ea1a2f639e62d89f1111bcd1a780cfeb64422146a9af1f33da97ec8321f7461fc90c4053318021b48b0f1c4162ef025234820fc208d0dc30a2c54502e62204608360c2a94e820a2a80111413461c51629e613543cc992bc20aac9921c3861841c2009c9d45da2e2045418415997ec52aeaffb0fbbfbe24ccdc9a5e694bed3478b3b7d939967ef99d30f86393316acf4f9b548a9d47c6a99bb53f7fc05e27f546366667a84d37eaa25993d70f70b7082f0f8a1b668f16056ee53cdd9c185bd9d7c7f22d520c1db976afcd775b787fc662224b23e89e92c8085e6b3d00c8f3aa1f93a4160aa3f4cf5704c529f7c6086d45beeee04b1723034cbb22ca39452174cf1831a34955fa3495514c10a57f9b31774107e90aafc13092a5e9040c2a0326f7142e5a5f27753073989caef7d4a4cb85229156b4e9516540e42f570fc9a9fd54032955fb008c112a1a5e2a3eed2882bdd3d0c222485a12eb8a89d85d3c3f1abac22bcad445cc765ea2534163ff6c5aafc3204d9170aebe2e7df262a767fc0b053f97128eaa0258201c870aa2cb20462142af38e0dc76d5a29a1b0af7d16703b65f33c4de129970bed7aa8bd7358973fcbe51ea52c5072994b1135449f2975dc2ce28e9fce615ffcfe1c730846731e86d7bf54c695daaa20371e185eff4ef94d4260d2fd532e9722597cab8ff53378fde1f91cfe04d90d77f8ec87496818d2a2ff0c59a101dc86212d36ebb4dca1c8779ae8209ea45dca12abeeee51aaf7cb65225c8a649101240da4e3d3891cd471b354c7411d774bf528ef70e4a3f61f4a0668a0558281d2376178232321212121f506161529215f7e92da034c93d0f65c4759ddacdab1fa4383194461243662a7f6b3d20a414a93d52285c6af528e924003a1f954cb32b044a7a713b51f072ee30ac99be1c849d38974007054e0c9dfd1416c44b776ecf0f161b1562b24a4f1e767859eb61a74eb679b81f7c3492218346852e43b25fa026fa49e5786a7d33a5078d5078f1778238fca38108166566c70813ea7d2c7f3993eddd215e73b28579cd3bb5d91f967bef2ce8afcddb6f85795c70fc2aabf6ae367086e7f59e342559875f9b30e73577f1fa52ed5ff874850007649698b231dc5a4388247f5e75e985e411d3b987ded7bdf60e99ccbcc54db750791cc5dba31f306aeb7e6fc49837431b8658d3f9472f85e1adeaf385948f0ba21b4940fb2094b5a1c5551a3cb4c428225253021e1042dda50c284c2092d2fe20c1b6981b0c61426a2a8c0093880811a501c21460649218f5220b865ddb4c06b4e22c47df645a9df3e891038c45beea4d39fd2e94f7d12a1a26d2bcab62442dbe72d29bc19c6accbe927e4de7b19702a9e0c9d0af94984f8a5b7fc930811f156f69fb7fc95b0818b94b0617e1616cd90c32cd4b1613eff0c89784b4847fefc2a3cf0c75b2ea512549f413f713390992a85711b55d5811ca8937d12213ff256160e31ea286fd14f228484236909a698d00a29c14f7f8557c286feedc322ef3bea578876a863c3f6fd423a94071dbd6a8067ba4c7e5405a5a19199c42d7370e3c3dfeff6d53bdfbcaf9d97cf6a480fd3d81e9cc43ae4b7e49dffd13796ec8093665b37b887f6f2c66fa0b7e28d1b52c78d1bcf205df1c68760b7e28d1b3f321255bebcf1db3be8db167e6f7f23e4a31691963012d3be364a299ddbb67d2f1fe6c79eeafe3d4339ccaf6b1f78836907eccaf2c6cbf0e5f7dc06eebce83fc6e0f871ab39defd7380384016c89f55bef1db86cfe0b8559877d5d08d23620dbf55423c90c5194c2085cf71770394350c290cd34ef4f1ce55439de893fd8f097ec4e1286dce29a17ce328979a1af33b6683c6872aa79cd27307bddef847b51d1e77779e2b4c13e4df9161864fa337f0805ba90c2e77c04feb181cc51df0d33cb06b71d5373031adfe7b8e763facba626228bf116e9449fc49c2d37e14abfc61256cd00c0bc5c43d6e60daca5032dcc03d90b00ef9854c4c5ac73c2a21abffe8af7e5534d0ff543330c8460cf5c37a16615ee4466b78e34679686407362ada818d36b063207701398a8bfc22483c1b703ceb7f3497c4f484373253124331ed0b2ccaf13afcac67a1acbb01f67c08fe6f20f845907096653e335343f33b7f464ce13371fc80be1fbfc7ce8fac9aa5006edbf2df0177758caeeaffb5aa8b200aa0d370870682edd0ff5441e8f3f71f1ba578c0aeeef473be2807eb7960d1ff582c168bc562e560e5c0f139fc7b5efe4bf0250f0c4ec334790dfcf9687a402f07b8dee209e98a86b09d704c5257211bb528657e5d270cc7233caa7f4ec838e11716edd0a227026f6428661e3e70f0f8f1791f8e276fe48e7117495ff33c1c373734a43720f736e098a3662111d780e357679e061cbfce844c0c9594c450ab4ff4f91199f5e327036f6c26947a1eeba9b34050a6004419b2775d53aa5c2c90b048da97d6473eb4230dcf816c6c5f3eb89192edc147ac43be6cb922d3d03de297c2470e76c7806ce5a4265a9453fee769cf494ef695bdfc1e9c6f633ceba16a39384cbf37fb1f9e038e3d95be0d387e5b48c4ffa37b3ea9276435a7a38537a5140f62b54f95b3d2df2143d1fd354d63f99016ddb5a11d2dca9faeb9bb873f5be53bd287513d3a3b365fd26cd3380c9a492dd39848c76ab93e4052feffac06daf9d5cbf769209d97dbd39ac7f9554991b23ae44f1b2d6782f46dc0ec73b80de4ca03eee2e01c58ad9353d37eaa86e6c3681c27b32c530dd1988c66dc38e0c8aa33f593079cbfaa4dc3c18356dd62a9fd9864f5dca986769e53694f44fe88e3959f06e7573c5b0f76621d47583943783684445a944f1f07dc791e50e7370e6c8b9df8e504ae727670f1564fe5ea6f562b1cd8487e28b32ccbb44cd3f833d6f8358d5552ee93012a0fa932540efd351b671bed1d84edaa866cfe47f37378e4a7fa3bc80fa312e2cf6f03f2fb88dfc762411d83693f323bf1b8789a114e72a285fc1ba83dceaf6a933a60afc0de01fba88d5a94eb922fd286ff9ee7a438e1f4c0e3183bedcb5f7e0fd8f32cb474c594aa42dda5154851b9addb01717e05faeb8039dc64555936e7bbf365b2cf62f3733ef54c56cee7fce855999c9f116bced36cdbca79991cd8cd4b1b4e4543f60cdafcaa82646ff33f5a03190a47d1ba09a640afad0292fab9deca09c7ef8bc0d7e12f4a22d4f33cf43c0b656fd3036adf420c0ad13e87172a7fcf73cf3bf8c4033d3d3d3dcf604f58d442e0ab6af8079f9be0290d84f3f2198a9ced2585e12a6f8f6d75f07b9f037e20b860e76d215d1787e31766fc37515a942f6d42761272528bf23d203cd6d802aa1afe8bacec9798bf87bfba813776ac911a481ef991d956edc11ab0e61d1c8754c93d0d38f654999f01c7afca844e440c038e34f5a563dc3b0c3f5a943fa481fc191c7f5b4d49234be5a74758425653d230a332cb9a00af0784e28d0dc55b3f2dca90478b92478bf25755030bf5bc149ddea1c435cf6c0cdef632b353daa66c383938211b754e185bc22276c596ca2a205d659ea1b8ff088e58aafeebb4c9cc99f7fe6ba06d669b993321cf99f7dfb6779006fc544333cfcd8032328fa45dc667405957b56d1f64fef632a091e9acc463a175550ca9f79e9b41e6b7e75a45c3cccb84d1a5cafccc732fdd107dc9fe12a4f9560991f9992a622ca937ea56f1a24b65150d313133e10e560dd53cf7a3e5fcf6b481669e478b3099df3126a93ed4f0c69f6a0426138e49aacc1bf991097db4e8dcecb6f7a09c9cf047ba8536e07c4ef8ab67214ed6e0502465e35024bbe4c436b0e655aa20335ff332a08f167f1a0816c3ccd73ce772e7737e2392b3b393f3ae1ada5435c83af3379f6364e66b5e82453aaf63130a89f91c5ea8db1725115a3d0fab3066cbf92de765c0271ec8c9c9c9f94d27272cc2791d24b26e7f13fe34d04c081b3949a68aa126dcf1f38337728c97c87cccc77ccdc7bc3fd79c7fdf8facbaad827e7ce647afdbd374d00f6ff96fbf3d6f0f1c5887ff168e5e8bdfe69f8dcd8dccff6822fe3fef8f03ccfbab54bfc950c65f158587f3dc736c5f32ef3ddf0703859301b932946d731970ebb675db16ea6c32bf2dfe688ec96ca11099f0090f398ff31b119c2f52629bf99c9c997094f96d7b9c4d666395ccacab4200ceefb66270de655ee61b88261cb91ad95edac8af79ce8dd8fcf7d90e329ffd28f3313fee506dfe03479bcf6a6ade553170ddb6c604a9091db0dec27919d026ac0147991f699d792eeb6a40f93423d79b99979151e2c1e3e74746e6c7af9bcc8f5fdddcabf9ec6dfe47df803a78bd9101475a657edbfe876b5566bf81317f038e3bd49ab789a9b951d1c01ced6ac0ad34b44e70e498ffe13bd418702b0ee88123ad5be8fd0f9fdac3c4469a3a3214aa316d3101de7a8f92670403f2bf6eb8aa21bbad9543926d1a94825b16b7a5a0042f539c52cffb3ef932e54ab7e422b74899e5eb0ca5d3944e9eb73a54cd19c6d055a98e1fe52d8b7d71d9987642e08d1b535454038d2f53b234d0f86969a07163aa3d76571a287b62f251c4a819aa8de8981326df82249bd857ffec0bcac95bfd947adef7fd8fe2d6a5c5dea2dadbd868a1eef3e8a0d4c684d5d1bf5bd4133ce9d44057f665d4405b7770f124d4cf23f7a02dca5bfd0fe54bf2984c244a3deffbfe9d6a3fb7eafe76344de8b180fc37c5bf0522bc19760eb620024f470759b587c1544d8ba241be16eac0d57584f0ccc0a548b8ca306aebe2a481b693500dd42e7582c8ea2fab87230f955f9e6c946852a71195e792cad3a8b2ec52f925970ef22950b349f5291ea4925d5cc988698937d59e46ccde5289246d4a9bbcd5b4c9839e9a9a68136daa4dab872a25dad48637f2539353652b4e3c51a88164f7d41bdf206da5b3ca999fa90a4a5b825b964ef6fe498424a89365ae436937dfb351aaf245529d3fb27cd449b5ec4a9d2f756ae8976f43bf0c8b9490df9f8536f06f61913f7fd315ae5ff66c9dce699cfefaa66dbaa6bb1ba669beb3de3ad55c77adea97e6df51dba7368bbf797e67e6fb69ea841dc30947efe36791b986959861f8a90bc78f0bc74f85a398312b51de58d2ea8423ddcf09470f271cbffd2f1cff261cc51fa7ba5f53d4e2fe0ca8e44f1ee4635b1b138e9e172ac184235585e3b79f0a9fb670e45179763c6969387e9b71d4e7ad56d5aed439e182b4a7bf7150aa53bfaa2156b7b4dfc06596377abd55b603c1f9737dc415c5d868a4557214b7bb9ee4634be14029a17400bc99a4c2913a73a92c95a5b2549651aa75777777a7f8658adbb66da3f9946af324ea4d5a8c62448b1eb6931671a078631f31a9de40485bab9e38e19653e0ad15509c547f19c340befa56d92d10e13943e1b6527fee2e4005b8adce5e554f5587ee45d60eaac2b4aa838caa7b8191b158e5cd6181e7deb5db17112b551db2ca441cabb0172ad3e0c52a7f17846395b35851c6165354e134c594de6f75ccf046f1f3544e58562d761005a255baf2c21bc5da3cc43a859452765048291bc8a594325c4e825b393993383314fe2c41b946b8ed9b167838bb5c6a531651a0c8236994e549090a6fe24ca2b858699212a597f491962c549438899b7489aaeb5477fcf0f30e6d28a9d4556a719f1966c7cfba606ab4f0ba37088e1a2dbcfda902c2e14ae9d239ced65b9bfcb232548bfb315ab89549b2499728272b4d4871245fb2450b1315279dd4b12e579ca634c1463012d491cd42061c33bc6d91856386275b5cf6177e0e351970db6266f9d2259581d7ff5503b9bae4cf26540cbefa28a954964aa354aa4fbc9c107851bc7eaef25bdc178cab873eab7e1fe22a5fd65042cda50b78231542142a8b5027242317eafabd1ed491a6f60f03e1858bc39d91b4e2806cdd17d755128208f56b71eb2a095184fac1248cdba83bd7c5ebe290430242d65d1a820f940d982d57aa4a8bd1db252d4cf503de2e699952f7bdee929626aa6a5ffb75a3b1e2cfebeeee761590cca0d2dedd2e8174b8b29a823e5a641e73abd7f3b36d7bf6766f21799bb144b62a866c6edbf6ccdffdd9d63c5ae4267125b81567055e566f3450fbd75715e466e4d4151ce3e12d5ecac3a5cf9e3b3f6564c183673b319596c9679095131b4827487728d6fd4f12fa78a27d87eff3f2c9d127a43d4df7ff4085b4e7ae8f635d387a14d6c7d18f90f6fce00e407b6625d57d1819fde009bdb000e077615be0ffe11352c2c31f2db6774b2e8389b68294272ddf500401aaf2b3b80ca4ca3e95df3d26f73625b8e94ae4b2ac331f16173ed78c460b3d18161b48cc5695b3a7bf0dd45ef7aa81565e85611fd5a3f9eaaeb81f9f25d6293baa1ae232eeb79c4c35a48519a53506ae0dd31da65823c193a31f5cc8074d48891c64edd8910f42b481bcbbb329a56caedcdd9bfdc0c1ecacb265f6655916ee77077252ba37e7a3d56ce53ebbfdb33a5d35b47582dad66db3f74bcf54190fa6bed4ee70eb56372584558b528aedc3ca2ab7fb6ae7491b48ae9cd23d7bd726336bd9d7dd8d18522ed7ace1f1eec32491695cf71b854152a5675a8aeb568479f985d9a1c2bcbc84635195a9aeadeac027319c16e92fa970d795fa1457e9ceaa2031af814f62429a6eb1af74b986cfcc27959abb160f975da35a66c8eb9a5f7d672699596acb9ae653669a9639e179443eb9be2b3aa774399dd022ad780c6e2baa72c8b60ef0949ad4b215674a07b0579c9916b2104443f2533b32cd69449f9fde8d61607efb1770577c81d9647d79f9ed25942d6ee1762ad949e66457aebb751aa4924abd279ec6592853d02e8986fce7d3ba99f4a9fbacee4e93bdee2fdbff684d0b97abd3cee2f187da04b9669dacfb72594e4a29cd6896895e5716b981e68622abefa3ccda4b3976ab59e972911b5a24227be0655cb783ebc6d5cb8f3430d91371a7f09f488b383fc8324ddb3939aacd15a57ce75f51be0682caef330bbb06da90dae0fab90685c00ced48c36306c2758802631ca1e145e5f746fab4051043489a4ab324e5fbf134ead9ccb299c2104f4d68e1d2930b6a963dcdb3b2503c42cc5b9b83079e5677e989c9138fd65d7a427a3afaa8189c94babf340426754324fdb520ad90a1c4b63e4aeb05174d57f895eacb65471db70b0b7564231e3275e4265a38195577271b388d01060bc05063290c2a6218218695165c811a03690c294b6364c182022c3ec0f224d9f8f934279c0f599665d90a7c985d202105d2873356f0124402b6d8c1144b68d962898dd9832ed030a2ebe20c1904f1a403277cc185ca954bc8c1199feb8b20787c51459defb3088d104fa4c106133c28411421c9832526b2a480f036005ec0a0cef9d40ba73abd061a797ecbc593359c40a50d17b0e08a286e708457c45bfced130b31d3acbaf081a6caa75e0aaafcaf8b23bcb6041e1f7fd44a0e9614a1c9833cf6ac5071842c82948c045e84a869e58a10bd058a9c568850e7e4a57286940851bab54d50283c2a5f166fa55b5b47b16a44b8d2add57858e16202056c69e298f8f85341044870e2815753b70a12889043081e4ddd2a4868238527783275ab4015b1c5f3ea56814a4205243c9bba55a09c48c251168e36d0ee4eb99276f777f713ac245169beb06e953482f018143985952080becaf9ca853ab27cc61d3ebc1b9b65b700403a2f6123b46052fd084b5a3061c907598c60698b2b517680c552d3117c588ad20265898b2e4b3f687a028436765f9303759f7a0e7e021bae00c2084f0841064ba060022107180801064f28d9c11231777767ef27ea589cb999b9a04e46537706132a68a209f729f5f424babb3bbf3b3716777777ee31a4bbbbbb73636131199e497777777632ba63edeeeece3f72952419eeeeeecefd947999bbbbbbb337167777e777e726a3c570f666777777eedaa18e907ef9cd8e458ed14c6e021f00d14c58b25041d1b4250b2c47685a38220b348ed020d1a8e623e6880a0c8ef8b842fd8a91f6d405c9080b946c09131b40c1b263c6c90766ecb822fbcacfcf2b9c94317184169c2406d44684932ba0b04829a744c2fc058371449447c42f852e66e0c591ef8a966dcb931b68c142fd4877a4f3b94182cb123e57322fbb728575e8a93924e12da8c00041451954904c0ef2138cb043243d91f4184c2f4da62481090b1289448ef15333832e68f073659d382e74c0649db0f0a05e83c838b1a2081e481c898fb16259414412ab7d67e993f3baf63cc2922112e62b417e0ae9e124dc9ff3eeb7ba5b802b929e01d7aa96cf2a24bebe2a863252eaee5ab7ad92322cafc1254a149410c75d837c4512672409ed165cb4408a10e74a9a100613a11e609a8a580444f08249a8879ea4c98458194a423d30b310dc72309d8163513582a4ab94a10e5d8d64e1760db8658dac04a9f6732fa04fb73e160aab56fd4b0f1cabe3a543d104de56191aa13c84b755d0b852fd99634cb1260fe21897e618972eefda208e3df9a0b168f4732c8d6d6d9555352cd30f269efc6d823128a02835d2902a20502b14e1414dfe4c6e4a8e9a5889518ca981baef29b6f34fe6a7b1ca1c638a516951c95127c18561e49852ed576a208d4a03f9c7a05a037d939c83f3e52526a67350a3a99c0de7600ac7c14ec74155652d1ccbd262c782b0313354313cf1782f61b8dd8aea493918199b1c1e8e3d79100cdc77dd4f57a7027df625bf5f876b7b541874e8f87170fbf96129030c04e851a7eca01fdeea1ce4aafb9299191a9a2536526c6c6e6e8e7096c0c1c9c901627583d5cece8e6a28e5cf4d9e4c535982fcf3532ee5d6e01f0487b891831b2c160b05265010455185292a743e5a3ca8475d1d66703e9d8f6a48ea00e2ef9896da9307937442878e9f9f12b0a003163a1654433eb1206c10c7a0bcf5145bc22e618376ebb65a50d2826a8895ac88f0465612eb3a72ec8963593a8895c4941cc5b6d46625310f3aaafd635d4d04c1108e5d1d57c92b22a80b520d718c4b8b354835432a1c532f3ff32d16c531a8a6e71897ee59462584fbee635441e677e1287f863a466648b7452da8a35ab64ab1a8065a185aecef5440becad0a6053eba3ae3820bfbdaea23e48dab34e4070c36c4a0fa09a87d71c7a55e542f324625c47fbe2743ca4a90b8f6d105c7ffb5b8a4c509f3b79e9c224afdbae0bc1b5329ed53dfa9972afa23f7dbcf7129493f05d2163b74da1d1a91df8554be67dbcb37229fa6a47cfa0deaa0d5961ae552dd214db19462b917eea6b6712a9898999aa6a01ab685648716611f0e4131fce392bf2135ec36e5e8403118a98eeb86e873373743eccbbb2fc78a1ac87f6a6fa4a808c9b64313c996524a0f2606a42faa0e4c894016c80631605b41439c01433c08b62d1cc6f0a0dc45a08c064e4c7184ca7fa31ae2a5eeb9a8a3e361705ab75a655a7c299e9d8eeb7878523ed85628a26763aafece5907ad76b4c52692d57f2553d9fdbf00814603c1182e641686345fccafbb71e3c68b239dd4e958ac1c2b48da71e0d869121bec720c29c263ff1cacc5c3e15540629cbc71a1c623ab9a3d677cb4c41f899452ce0e0520bc8eb1f68cc4466ccc190d278aaaa199f14b0ec7917f59cb40e92ffd0325bb8208542891dee7d1789e2b498c2580a18329a260d22cc836c0860b90886289255af083904b41a35377498b1234b8c815aca0026ffcea2fec0bf6420cef3f807dc10600c3fbbbb02f980b42efef635f301f3fdebfc7be603d06f0feaf7dc15e3ede5f00fb8209e005f4f283f6050b5a97ff8ef707da170c685dfe2cbc7f00f6050bc0bafc7fde7fc7be603bd6e5bfc20bd682cffbb3b02f180b29bc3f00f6050380389ff5f375ec0ba6635dfee1fbafb02fd80aebf2fff777ed0be65a973fcffbfbec0be6b32effd5fbabb02f980aebf2cf79ff14f6054b615dfedffbb7f6056bedbab49779ed51d8170c8575f97bef9f635fb01cebf27f797f1cfb82e158977ff7feac7dc158ebfa1bfb82dd58973f7dff705fb0705dfed9fb83fb8281ebf2eff7ff7dc19e58e02bf016086770fc0c7af9821101e97dc18864f8ecf705230af2f4f705232ac0a77e7bc188847cf7dcfb67fb821119e05f7e5f30a219de7b98178c88e6b77dc1880ef0365ff3fea97dc18868f8ef6f5e30a2219ff338efdfed0b4654c3af5e07468480e7f99df77fd9178c2801ffdff3fe30fb8211d9f0e183efefed0b4694e3597fe3fd63f6052352c08b8fc2fbcbec0b46b4804fe15bef3fb32f181103dee755787f9a7dc18888fc0aef7aff9a7dc1881af03fafe3fd6df6052372c0b3f00078ff9b7dc1881ef03bbe0518118f07fa00bc3fcebe604437fceb05f0fe39fb821141e07d7c8ff7d7d9178c28023f8077e1fd57fb821149e07ffc0befbfb32f18519117fafafe3cfb82114de0617802bc7fcfbe604414f8187ee861bf2e7ea20a843f2800f6ac8b7f0220cfbaf88b803bebe29700180150675dfc100073d6c57f0388b32efe078037ebe2770068b32efe068035ebe22702d2ac8b9f01e0ccbaf81700caac8b5f0160ccbaf86d0061d6c59f00f0655dfc080055ebe2af011c0272ebe2a7014cad8bff00e0b62efe19406d5dfc0600b375f10b010bf041405f17bf0c60af8b1f08180319957fe885ca0f0396ca4f8001547ea1312a7f75a1f2ffb852f95f18801895df851e95df471895bfc7abf2bfc0a8fc021040e5e701eeba824220a7ca1f0070d7b5036c21a8f2b3e045e5070050e5ffe9a2f2eb00775d2b80bb2e17b8ebf2015500f953f841e56fb150f9452e2a3f0ae0ae2b07b8ebc2118e9eeb06b8eb0ac15d1708be0f2a7f0fc8cfa345e5df59e9e46051f971c0ef8aca7f9342e5b7b1a2f2d7b4765d33618cb7c4ff52a5f2ab72ecba381c1b48a9a8fcda8dca9f4dc1df2b0558d1c8525b485ba95c79090d2a756bff04fae5e98c2c6a4edda53396a8bce1d45709e9a91c7e8ff3e4350b96089113cb51f2a4d440dafbacfe924a3765e164e5e94af54d4b6d0f37264a3def7b9ffe3e4aa78731f4fcaf4b675ca9feefc4240a977538aa746a71eba26d51393b24f8be2d6a6e514d9452598ea234715c9840d13d1941c9625f502f46e0d07fa1b28b67f4ed6f514c4c4c4c4c01a3daa884cdf66441ec10d1080000004100c3140020200c0a084422a16028186ac2b07d14000b869e4876589889c32088519431061942080284106008010081a99a1a00f9eefc6488e4606f630c03b257007b312e2ae872714fe80b28e7b11eb8ee7de9fb51e6850079288c27a492b5b8cc4e0ca9bb0b089bf9989a40cb37aedd12c2b831f3c51c25944241c49080b87349c3b3196f2756f4dcb3d198e2ca92cdcb0142ec2e6d9a85122e32f3b3add43d7208e66a346218d43b459036438066a326c6bac0197ec1a6520c2e8177586b9871c38a360c139b33ce1da8864f61120b5b3b2150ee3873c08193f2949d54853ac1095ba41d9b08498ec8f5c1727ac9b53ed393922d0d19372d94e093d1a003614dee8426b5a2ee7a151f27bbd18d3abe4f18e3775fdab7e6c3dc5ab68d610427098dfca8290f6bf87df1fcb8c19f3f5470c50ab5092b3b91e26fa60887da360a52be693d1415a9a9b4578876e59f20d6152da1bb68e17b847b02ea233e1e05fc33147ad4899561697016d0ae5421736d6450c4788038dbb671df1df7d0d45864706ea12ba9637766a89a6a626c072680ae5847f7d2207541c40690e54b32c3cc0b56d824ac5852bb0c6dd0736b673ff1903c942b182afb33ac6d1d7227518eaec7d4f2b6ab2111680e17dbaf76c521d58dc44ed52898414bc34162d8b886d5c17be1d1913a10845f76c69d02de0d37eaddc0b966968e51ece602eb2b6e5dbff1c89d1626cbc02416219ac459e80dff86eeb4ea4f6f02732c4450bb31ad8aa620a833d6f18fc5c2978f15c36c5d7352b7a285ca6c824933d01bdbc28bafe835b5eaee12535a7d930c75ec6812c69bad96de61e4e0e1b876a6dc03d3df6eca4951ba959ebc6004dbdd9e79529d42d151f3ea4da13185da3ededf38b31a153b2c55a8484415f44dea024194b51e77933876df34bd09b06f0266e5f9cd888db8d8d18c699f7cef8b5f12a243ab83e1628118d96012cbac3b7782f5f40b66e9ce58a3252305acb9042a757bac77fcb6d75c5614eebb15e9259538483d592525bd64ca04f641689c43cfe2d1bf972a108a94a555e3fce690c34696ead7ea767bcd61f08ca4236318919832d3828f02b1e4949dfab3a0afaff772198230a1883356505b8c45802ffe1a54d5ec1362a726f07c98c54585572940f8c54fec247823cea4e16379e0e25f19ac40c7eb86c431d1572332914274e5def29ca91e70cbfd20513ca6683ad34c2ab64ada6bc3620a8784f67158cb47fc9a3f3aecc7bfdb47d4d2c5644e5225f7222dedf70bae09f1c2fc1432f051c83cc8c3dfad0f45f5387988768efa311aa88f10c9fc5a2ef726851c20bc7d2e4405d39d057c3428967017d04d98284bb7992f1d85ca071555b65112092d52c7015e4ea5d53aa95f27498b5e20bc9be0d88f82633bbe908aab84ec82d91f496ca4ab16bcd68b6f144e1c46158a7a2d738b6dd9b98489e7b655454444b1f9b044b46977e7d1ad5f477e067e20dd9a6c3d0e364303e33c65a092e9b6f6ebec860a55f0f9de0ce7ad3c54d0f9513bbc754574b23e9f157b04780733720161060a77eef886c4380d5a3f33540ecc2dec2015f41035ce00ceef0460bacb043f6b0f7c27b84403513f0761dab0b0231a8b42dc3889983274a0b525c4c89a73b6982dc600d5be0f354aee607f9493b4f784887eae02474533726db297d12ea77290102158c9c490613faf2a861e75309ed024bbe9b9c708a79da204ef695ff0df6a74b70c0871ffd65672ac0b7eb68920e9c031a3f461bb613aba7b1a2fa8b41d178002e5b3ccedca14dd865f281f9078b7f50a41029688ea389303ba059932d58a0663e663b275a8e13b1df3f734a14bb94ba7c33799d75beaca92a1d490897e38b2cfd64b4c0b788475362577926fe0921033a0949b9a22bd037894db162657dae80072abbe851d93bfc3e781b07cbc2a50271165bfc27848db09f3f223c43227d07a412d214578360a672b0f9b31c2d5ff4f74c88baa2ab6f141d1521525f4e08e9bbfa201c89bbcdaf1495af381bf3069f145271671a8191b17422b12292a9a961087402df67bf614660199c9896d6f5775e7c567213d4c8ae730cc42221055ff0f402c902a7e6c875859e566414a9f56b5a1745a81122f0dc94265205b401c0ad2b8ecbe818f4854ef8ab42a0b53f3cdb4a84f755b75126cad72242d20e5c6337928e939902c24af9872da09704a499f320f751f0b2fbd832427214c3cc2118de8bc28425fe1f2d1690077c6a9a7f59ca0a2bf3172667840627f53dfea699579ff59f7928f3cb946c22cea9afbb0032008baa6b79ff8a00c3667ccbd3fa1c8282c180202ae064f858e3156109c5c79c3778102f78806289ae434d4485e0b5f18a4f82bfb40c60191411f01d0631d3dc190ece090fae56035c442ead1f6edd0803ee7b953be3077b134dd02c65c163b7cfabe11b0569d68b37dcfe6a7e7699d667d91793561df202c12728d18db0161e2bcf0e4dbdc8ad74542cd6c3f0811f2b1a6f2a40ff9c8073ef5299ff98cf1b1b468aa088745c1f8ce38da69915dd4134eefef453338ede853eef7f2941f48609b454c5cfbef3eaf2ea21db2db879d8f3c39f2b4c2cde497c9b1e84f28535a747aad42ebb249aa31c0cf213141734a510a31e002355e1d03902fae08c22ec0859df5a90c8073145ce05762c85fc8c7cde1aa96b76eb26fd81eb773abd2523acb6dfce923ec8f9bd96a727931cdb5b724e6266825226795d48c2d19d543270c2ce777f91524644dc32433de2f6153f60fcde82e95c01c379056fd61f34ca02cffa4a67381aa0f09d244b816e08168f404fc930f2c1f9783abf0d22a948bdeb9b8376189f24e6331993837c1b232eb140589a9429fa5e4928e627a964c2c97ef85d6d8a3dba18156d06b42cf0345ee8e120062bbe6888c552adce5bd291efc0618875532201727df082ca2faa11dd46262c9a2070ee5de89189b5fa9a6d55bdad20d79369f620b1da05ccb366b3a37aa27dedf55a4b4c6b25305015b29b0323438fa08b07666eff1ce21d398e0e83e00cd09196ccd0ee46de74a5f1cb01059ac03a3c9a4a082b65a3c8988b9eda1108ec9403b9c5de265d8efcf13a387866484fac43407a92385077f9b643d9a386149b17b7a477750ba42c7c2a9a77b3e4b79e61569902ed7d4173cdfe2b54a31dd6b819805667954e5a4751965ac08bf9e713af8aa85f2d6f8ac1b78bb0b1ba07cd5bf08527f1a4d294733337e618f0bb259f96bd7f2ee4a32a4e4295146287d4664c82e39a09588b403a7178b9aa8b91e14ba3511707660c2c703e306c29d199f0d9d953e5ff625c53fc03eda24dc81d0b30d537178b1908e52b171b9009f3652a26dafc8a5cad5ef8a7f1be640c8037b92294ce3a51dee1eba66188313b5ce45d8c357697b607e24e153a4d91788afda8fcbc09c134498c4e589928bec3770c5a6ecdfdb99bc73cdf0a911f4ecb0e75e5338b93557f2f16b1987ac160e414943238aafd7bfd936b1792adb65449ad6ac6bac2bd8fd289a0211dd0b4ad78ce3258a55d24560973b48cf55e5051b32432411b9d0d4b0e67e4ed9f9937aff6861c7d2d0352edd2cdd760ccabce0e70198442eca8df812948d8481bc978264c5aa9f26f5c01f5aac7d9cc563c09d4e1b70bce7c3b1dd66e1c26163b609890aa0f800ee322bc22f85875be551597deb6eb7094ec0a4eeb1945136be237bd1e009d463c8ee43488352c73cdd96773a7dac0f8bea55cba42d0794b64a73d2e980816cfbaed781c6aa06b51f659dae1c81ed85d36e153b57da9885a525ee9120489b23c276bea0e895b697f72c31ed88575475858a9e42afa2afa1d7d053e8d442676106e7c8ce4888eeb66149ed97d5def5d62b09c077714ab6dfacad816f1a1af166b6b2014583d5bd93f5339524035472d1d75871a9e68b6a83a67598284b1a2d176ccd7d9f5456268e12e4a6adc6789792ca3b01f29e3dc857202a600d6d55de5c07273a86788e8ee1edf582cb9fbde07caa546e9005ac7f1c9138edd6cde523194bb7fe258c6fd7f4a6ea0d409ddf62d6a53ff0b4c264b89dd520ebb6dcb16594959b863d38ae118b060b7cf4c1e62949e437cfc78e46c6ef89393f728459fa8ae08e4acbe62651f2c31c513b49db553df2185d9f12e23d6127341507a0a3dfe6e74889c072681955c5cbd2e4b0ea8e0430ba57e159d157ed6a156f3ea0d2edbbb2ad3181b4dcdbaddc3870acb39f0cd9c57024c4870ce01f883ca9b2315b980860476fd4dd4cdc5284bec02e60e95ac48fbd56ba5e71c16b9364bab8ff688f16d61625e28b77db4f7f17612f7b76e3798f95c03e7fdb8a4cad466a36e2f0a3f52cd2251e51432f6a69521846afa678f18f0b8e9b6923b4bb1188d79885401e82fa8090cd7d53d2a6144687172a51e6572f10cd5d1b0a13c8b9e2be11aed72f650471983eba2f1535dc0b3d3841947673bebc42caf1a57723072c3f0a6fb4e8ca8ead49941efa7f452b5128c1d8a4bd58be2174a2349c0b0d4811bc5c51b1898b932ec9d5e91f43e6be20130cdd2a1a675084e75c10e0ab6b8c2c1f6320bed5bc0ca2ae320472303e345f7d0639511a2df7f264cbe7d245bcbc99f16ba304817cb57daeaf0d8508a4e8f431f7b351465902aa68fa5c8c919d158e6a1410bcc3cc8ff50773182a89cf92e5dad4bd7ef09b1b875d11bd1dcff16f2c3b5907dc0918b1a86e341d3cbd05ee0ada485d2cae7e3a288b879e77c1db3cd04210bb2c88f55864b6304f44879f79473446bfcbdb62ecf68020e12d51b7e2398502e8f3f006454534f913778b33cfb280ff6af11da4a0190a74ff92c27e8a93da8379e5c5c9a0b9c617aa27d7590946cef564bffffd3df3daf8689e29810456a6243810e2f2421cf3c708223711eb42710fbdad89b38cf2ebdc78dc3d188c833fe8b4626611c9c373a4b3c08bbc0b51e2bc13a76047a8f26bee0332f72d3889a34d1969809c242d351106c2b97b1b23cc816693fbff5e52b49ddbe2abc5793a96f369318ac083a04b383fa7148e83e71a0fe972a368d910649f01642683b900a7d4abb50013c72ac97b46d3611471f6a87d3ed7b7204c68729557d883469f62a96e911e89752c798a0f2853ea596b982b4ae8dd6d92cf90ad3cfc796d05965b52a91f2e65a1167079043ea34ee9ddd40a19d7e7dfdef008e5a3b0745bbe6439af15b14b07872aed34d68bad17eb2c3f4fe27223222870c5f48a7f0066cbf9136387d53d7f6ce32b8afe50e4fad9a09c812ab3f0770e1e01fd465b212956ad9325abdcf3278a81633b8fdef3841db66daa5d6eb4a26a418697355f3cc448bbe0bb88c6d37b2c31f0aeae963eb307395c065d7321c459dc167b20b9882f47e5c56b8b84f6a8659c993b13b5a5c0bf7cf641ebdfe3a0fafbbc07bc76636ea1c0579078bb17eec81cf79402e009d68279e7506d4d13dc0556c98dfb0ccf3c855cf16ac55626658f47055e77125a488234a347f862ac785f936de0c2b22459cf21cb8b26d8da80ab62aebbaeffa78a291f15562c46bcf813fd75ec18f7a7db6044e4f70b4eb3707de20844f64408e98b385adb9a131800987ecda89bcecaa57ce810c9e6aad1575fc8296bab0e82e36b5ce272f8a36288a8b36603e951befa3c4578390ba6dedc086f83a2fd7181c8c3b3f17384b050b49a0ee78f606c83280616e6a0e7d01e8ed0d48312662f6a6933e2ff3bf89b2d7fb194ee0f1c374ab69334e65ef795d9d483ae21a57115084892259cfaa7a995e7ce72d8869667ca217b9399047bee81d797f5f5b4d657372620d8ea2f08460e0c1f57c4c78c182b517e6ac1fca82f6f5e736feae807622129a7f861df57a09c9b5bcd35a866bf7ba81f2080f8db1456d397d0ece0d0cd29825a5c344ca7ae9436abd65e2f0c290580ffde2ac9a7339faef3a930fa94703e1df9b91f4708eb086f1e44fdef492ea567e4f360596f88547a110caf8be7614b347c9f11a1b503794bb29ba52cf13e4094075ab0609e0922a7a35540baf0fc774517278eb801e7616336123d375bc427dca20a6673344a030dad468aae6260323a6ba75065b192d897c8049da355bae2c6e72a98c6d6a637c26009113c63a9390fd61cec4f583d2141a9654b2f176a6c257885d3a3d0044db333eb8f8a5f60f680fdce7e72e702ac750ce9b221047c73de797910218ca882e3a21c5b78fdbf7254d489a291d089a001e171d6e1fbc2897b33f193e3463ccbfef423bbc8cc2156d37e6fc46577a1132a1bc2147c55d8b320fb3c9093a92af11a55370945e2168345c6173c748868676e4f359c901e68214bb43c883d94cd7e793cabf9469c024c5ce585c0085f6734adc0eac894f07303377bf4a1fb731db83346691a8e100eaae3ff91a7862f5805ec70a94f268f6c4b4b942e933ecbf6406988f7acb525320cbb83f08dd27df781403de7095d192e9833f77f49ef347b4e57d79862a600c790a5ee528edb0dcd28be1b930e9aa98a96e3527adf0afbcaf029dd8d9909650ffff17a6ed426861c53d0901ca0f56fd995fc04008a7eb5a290c5e235a4de9f5cc5a7767743eaebc0b36cec8ccb52c71ef68625c43253dfd6cd2a12170cca252f22b3ea541cb23bddf0db0065a3fbf3527d97e009a4d3f4693b3e5afeca161e0b8dca863691ac7364ff9bdbef4820134278bdb1287da0da96987f3028e000bd93145b071a3582fb980d2d11b57b5a7f063523dc6dc418188916a990f023b01ec20d1ab4d1a31d2be8c791276c027eebaebfc6e8c83154e4e34618e63e71bf851bd8091b8e20f6aacbf9031069ea5ba6e9fb3574ab74a3c760d72340d2004040516f60e1c4fe96b7b61dc0a665013c2259e69954130e24a600814d502fccf0656d7d697d818afd17ab08558deeb858a242f58851649c3644b12144d55cd3cbec6a5cf4a6098aefcdbcd0bb6df5252a9a5e5faf3e9695d7cebf410327438924e63f3670631bdd0e432434e0959037c2f8a085447e563b3bc141bfc14b3d95f66cc0cf1ac0f1d7658426e743742504d482462496d63d8c567a5ca3473b1ae488ac243d002540ca44d1c8817fd53b41231731fbd8f1c36eca96727aa78b6c256dc5182638b420e7787dbc626d2b03493a9d27ff280718d0f376bbf4ac6e576101885938487dd9a3be01d7b92e1559aa9e2c2d53f02f91cbfa691a0009618a2297326c819b2c350636d6938ef01404a53c90b4a13d05a548a402c87d8b4d4aeed19f0405989cadf35f52538fb08f31e29f30a1f2e17a226628b4c57a0fcece4bb0caca823db2ea24306f25a54cb41831502f5d94c510dfb8c1313ba0063b85282bc10edbb50401ddc3b3a3b78799412f20d3af55ff7e300c06d37a8469944c8c79f4187411f24dae4ea3736ce0ce41049476a877264d28e853add467063c518011a45e89baa3d09ebb847059b9a0c68148071253fd7a0844b3bc830f27b3a937e3ac187cd8e8f3d9b3fc559d6105d540dacfd4c69bdce8180a8ef7211e3c2731cf0a6ea0d29f3df8ce2089551465a32a1fec8e9724caf9f6b5960f9729b56d51c26c0e3e64321589bd428e8c7338b346e4ac22bb360fcb9b89cca0be226ba870e6c32146304991433a06a222bba8e49882772dfe9541997fcfaff30468faadef75533e3845f7cdc7970e458855567e68bbd289b5349ab79cd19567fc0baa93894b2d18c4188e445c66d1d323de802cb1a11a251acd0d9498e2dd446fc4d0c3032b15ff8c1301fa474c37f7a646c9fb12883b3450af86a2132bc6de7f53fb7c01f90797ee618ec40642e1386c2a33ae710d2ed616c613b77393be485e45a6bd065a55ba4b0bd7febacafa65477fafc0855ce0cb18124666cae0b747b40243f07f6c4b6b26e82563d7528a60fb4158d90d82cb7f13fa94e5c4c7a7f3fbf7ee5ca1bb43f4aefae641446f00a160fe3a54671802e122e632010f52208b5529271b60780c328eaa1e11dcba426f9abef358139aadad7193bcbaf2216e9a8679489d75c6ccb5766e7355a5144c388eeb661d3a1b138623075a7ee66800709e73bbcb430d2ba48830cd610c225f002e4bba40621c78b67dbce47bb925eb7d9258d548bb593c4a2cb1d0d1034e53d4e79f0979b90b795defe507eaf8a6c6f9347a97a86c1fa5035042ac1abacba4341db92d34b8b80cd509ad49feb9c9bd6e4bab7db0086288d704be611d42ec8b1db752cb0b84fcb012f0080f68cbd8b8fd6c008c7aaab58195b592725b2bdf0faa4fec9a63ba0bd26d171deac847696d21ebfab550aca17c8c3b5f64982c980c5cb230a0ffa18bd6e545e63dbe763b1f8a748a9676e61565b1e0870538a29d9a8bfa545879e246441969c4b8935e6614b1bdbf9b2d45e388413cfaea829489c4b3c8b83462c5c2e2b6d4d35aa9e8bc5baa7436fa5e8a9e88637e4022c06f06bc5106e48834a5f8b07400c5ebbec14d4817d86add15679174dc482a01463ad6387765bc3b23d5dac8b73578e6f88714638316d26c6c540c8eee972d4a22acd04483ed7d9ece3c62fb5b26596004fda624c29ea860bb85ebc04677dd4b37b3e9befb1c8bad691081b349b2695c2d6ccf483824651b259604bebfebaef1b5710226c97dcf9e0803fcec037709fd757545eef2ebc770698043b3bb7fb08b120876bb88e4cd6d678dafb77e31f606a0dec0b4d71635500deb1650f55eca1baac3961b0a85cb556d80466369c2952ab1d9af45676986df38c404ab0304d4950f0e7469758ea3f4ecae494704e07f55ee1c0e5f74ed884d1a6020efddf5ada633448315490f69801958faffd25bc17e1d8e00702d1909e01b6e929a79626b5e0f25d62b3b4a41ecaace592cd78b07d17c818d903e64d50ff820dcf75528e8773b7f77c27c2feb6fd4937be255664ed8e79cdc1e4d50de3ad3a456356b6b550d66c17bf9a01a5cc836b08dd355efd7914c136a56b960754f56021268a710b282c072a260f5cc2c506b3d223465acaf051036f1962ca6ecd3b769c40233ea1388c8e27e6fbff44390389a7af60c7c71f252f993f11aab8b1e74818753eff1c0966c55a6fcf94ac237d3469258e753b08f6de14361d6ce50e58d27634ed840f71496cea0793b80a128414c4fbbfdde27ffa2897c94d63edf2fff9d097c4cb3bddeb5ef7bccff66824fd3b6d7fbe6ff34d9f83038ed2b5c8e81d8156c1687d78e18db2f055087f08043287082b4b061b5bd211d224a1d4eedd93f867b88c25fff88dccf87bdc74cc690d08fa162d9b86ab650cd8a6ae295561a750aa2a13070de131b7a55913ec3dff0f4188bf5748954bea5c7e4eacf81bc17a6a184ac632bea9420901a2d108d1a380d6cbfae33d0342e108d1928512e9f7469a0695c20180df06dcf58d73d1080327a3e3291d77ed418a963466fabe6b6d758370e63f6fe3dec28ad829ebac279bd8c6d838de95e91f98e020ecee5719a5246ba97b8f7572dae58fd0b6993affcdd6a43e983f20c54533237d132dc12ee4f8c8838502e70080346b24d697d433ef0b55d11624f2e4cb651eab2c1fc2896ef6ec0010ba55a8e820383439e3c5f42c6a43dd4362c87a3cf1e50bd6bcb3e9194e6f164c1642129d684a497584ad71ba09d1dd0635a7260ee724078c2b558bc5be82d2b4fbd86175717a993dd06fd12db08085ed7467c0bcd872cdadab301ff6e27b9101f2a6ff4d8ba8704312e2095f504569e87822476261e61e809778629cdb5dc55219a2946ea6374db0376b3f2904cc5dd2b501d07ab80087841334518dfc75f985c4a834ba4dd6e863e4345e3ed98341e5fa42f858b3294dcb80bad954b8aa8c0fe13c8c8f704239f5d4df293ea6c28240240bc637b9070d9bc2d7d02e32cd697d1d8521d3d2e34ce46e7003c6ab88e7a6af2a4021ee0c984c62ed3b927ffbfb26e8c8d6971193d2f1c5c01adc17e631cb359c73015735a3eae6f2c519198ad9f42f9a1217a964898cf6f7ce9c45534497db944d5e99358580c2d5b566e2cec050a3c48bbb12c1a8ca3e9235e13d1444a80031b9d362b287a3143e6c86eeff4eebf207160a949dfbf273bb6a794cc701077326da9c3e2fbc208d63348daea79e08a8a040b10d38cc7da4ac492b6e893325bc6b0d534dcc3a4a6188c6eb580b53f505fdd798893acffd0b1deab8767c53cda342641ebf82986382ab531eeb875fac03c1e8f4418d170eeaa7df3247727f04c7c3dfb3598a3c33e50ded0bfeeda9c0b0f87a0bf7d06ef03c474ba2048c0a2353b7c85b00ea7937bfc48d442c7b85f3e65037fcf2415c7d38d447983fde0323c115b45020b2800c2f1b14df26f9f93c250f0fee7c367c9fa13984509933d653f685a040d3ebbd8f0f91e6ab89c003b579254c758270fb2e7984c0d1c0239059a8e74dfadef16ef2864d250b6d7e33c902b11491d77ca0ae35b33e0a07762ad06037a1244103429a3c19c023c42c5c0412101076d6988d04ae24d6129fc7301cb7021fda98d6733f9d6d968d4ef1c53554ed63959b5c0dbbc4f4430a9a1a288bfd6a98319824ea338414b42bebb84a2a42dedba3793234f828336d83c8c991d386084a60598a4ef671d412e5343367a5daadbf539272c0c67f323e6aab78d833b378144ccce6264d4ba0f5f65343588ad626f51f6360087e93cc8e82986456f20173ab4fe75cfe6ee70c9178ed24c21561a7415c89cecbf6e3d16a51063a45aef0cf534dc7ce32ac8de356cc528a5aa0fb6ee16542842adb549669c141a50ab2d4008777827f1cb8a4c106e3e4a37eac07689cc40192e910d71d5d96b911abb75033b6b91a8ad824ce7c6331af35805076d3fb0aeb20da0432deaa61779b3fa0d5eada633e1ab410bc4e8ac05a809e4e4b90f3005ac1fc6e0d34e9154ebb6bfa300022b28ed9be72e3105bc3640b19595810076f3aab0314817979526feb6eebf7868aca4ad49b1649a85f228a1a7804f22551fe9da5510095888600f7d6abc7303420398f1682242ce20f2b7dfbffd5eb6c215bafa7ba553f71866b0eb4e47d257a1810166960450917f769c6582443126c0241185f7372e1cdb77ee061c6c2ac43a0344b65f6387e83084712137e20fc2a233360ddb18b0cfd10acbcd5ad41080985d9b5cab7965c2ab27a3f0529d9dd6d07c1d6bf0d0be707b5d69c683b6eeb6e6a9e8515e42a6efb75a62fab2361f235fde9080fc7d07895a7d65edf77d9f1fe52ce12c9de1a0570ad7716088da90b9fe7a8527999325dc9bfaa9078197efa95af252bd39ef924e96d1ca8e0fe7cff1d12270d396d09d1b160e9560181973cc70561c65eb6cf8ffe3ad236ee7061c4f02cc90089e10906300fe4c173cca890436a8ae6899cb0eeaa6c99a0fab25716e367ea814df9f2ab2ca5abadf652d70cc591416564165e9860da457d370fbe2f69d219ba14f6d74e2c4cb42892c0853e1dbb028cb49694f4f633eebfc65a14fd4374d5a34733e288e3ab314e922e33104f9bce6d137edf119de8ad5fe4bfcc22b3dbe2d78f515b9f098a768d2c032bb5041026579e46e422dd6640d27d802f2b92bc125b9df5b2bb9fa36a640290f1d4caf2fac484cc06236dd14edc48ae1c028f7a0513cb8c233a0b153021607eaca4c94290d816884008f728fa85c6a321b595b8b4fee7701465e0a887b34ce401ba93d93866cd9ba41c12c99b1ad32d7919df403ee2cd9e4d40491a4c55eefaf5108299b0ccba5c24e16eff6cd88c545eb8166c8374c73588d8104aef40806354900dbbf26c25ab866665f424995a0fd5cc1b83ea7ed4b9c24426875f90e66e8763a71a01e15c60261a70648579dc3bc55228bc8c31903350a34c1fb31e389824bdde9e6fd45e876931f54e988aadb434e8553a6fec51d1d14df848f5b39525bbffeb45ff408293a6fe090607702248804fb3b8400f2ea2ca89af7211fcae41bf2676c57a254770fc9db0cfdb4551fd382cc2628738f898aca16996fbcc76380bfa17438fc9bbe21123c81d5e0fef80c11398cf91c94905d6a8a2a1ded801294f22383fff60e2556c549845dd1848b96539a212f87941a02d6e15c16f6ebf063f91ba840c4372152220b171057ca18ac6e01805915087965ec6c621196193a9a1e285012e516de7da1591166c516f4d79e720d1fb2578fcf25941304843cec79647009dfafdcd3be4d29b1b2ea47c4b8181d8a641f01297f052c66c56f9dc7a0ae8a8547dd9efbf6ad1c9f356986143b7ed6504582b7010423805e114f7142bf1351a616184518425104a67591dc9a5b04de73d42d29021b34230f542f38442d10a1fd4b8b9c080290bb801f7a4689d90cd6d851aebd95457c39e807a13caf6ded826a85a815ddbec8100fc9228e3ee8588126510eaf84bad0015083c719c3956636e2d921b4f2df56f48b029de0b48ac5b236228fe083e031fe0f925b77bd26c6a6053d0077be8c6658728823a3c2b925ad82a628f658fa5f44b3ef8b478b8d51c85152c9e2587ac7f9a7be4b101a953900cbe45b246b0e34cb082187843a752793cb002710253fb2f7aa45e8da27edcb3ddb313f7b094c9f54055d2b61f501351a5ab2aadb0b61cc80ef314ff4ab783a0ae16ec626265eadf8c5d71f89a7b2a936209dd8a3e5779903480b159f6ab0451580983fd2e747f12d1c00943483d09296da2690cd5bc545f152fbcc022861901a4da55b5c74bf25bb09feea946bb3bf94c7b7a96c5e554963638e40e088649163bd41b05988490131af951b80ac287f9aec86ca7a8faaaf0e88ee6ae090972ab5d8b3134aed521416ff4fd5d64871494439f1009b53c67e7f9181dbd68d047b05e64c0b5a89446eb7471a00abc6c6db9c0cd4f8c10b8d1fe93c5da0d2f0c9a59ce4f5bacb0a6840fa2a669ce1425d6b7f3577b6fdbdf667a98581e89de94c9cac8139eda2ef1d769421fc202d869e6edfbe74a0629158034f404437731a2144f4e03293122851c5941a96f9da3a57e59aaada82cf5ae4e13266b0db0b2704ce674a03cc99b0829bd35d88577db9ffa83b2d461955140624d8cee3723c44ec857eafce821e9d5585f6c414d0f90103cd1aac26e5b0b08c69d0068e5b59df96efb50fe27f9ea3aaf8ef4366f8c884d573b9e7dc819239dafc88a3911cd3294966490a404cfea21b803953fa5398b60796bbd86a070dbf95b2b32b75d43485c8c0b8e7cc67cc4d6ba6cc4ff5989701e00d5968a4856bcac825b8b51e9533d53f583990c3ebdbc70f0404a5c05fc604ab73b245eefc092023d94a49998255c4c165313985e2651f1d8cd9789b77cd9ec772ff2e047c46aa9819c5ab461cb052f1e04f5e8764b08dc882b70d2c90241527f53de8520f1b451df0a5de2b1ac3fc70d58d9de121a887ed0be9f4181363c6ed3d346a863cc3faec6b19e476d29e134b7485430c7bbec1949173d0dc1500c2c8df96c029a073ffbc2e9654b9785beb439d203f0b96abd44a63c551a581acc088cf3d18d8e010e72c18a0a8a238a865b74fd47940afeb524338775c8ad9f0bc41c15d5fc473d6331dc94462db9443c20eada804fa2dc046ab03c1d8a7472e72574f924b621099fcd72407464f46100c1aaf40ef39ae23eb92ce237d2ec071ae441c2c7f43e8cf9dc4cdfa1b16336c57a53d474cffb718e75941df08670953fbeb05dddf38fcc6432f2dff5ac80f736077746014b75f77f1188a117bc5c42a69d59b33f76761e6bd636ac5467b723eaddae97917767a9b4764afd5ae239f9d65e9a5ce982e6357564dc40fae15b92764b568aca946ec6685957f99140b098d067c8149877d329fed61511c444c684c67664ff362fa85b76b99fa97cd155e3e94e0ebcf8b22805e28cbdd8b3c8da2d47106e2cda75a6fae759f71e6b6c33dbae16a6f3c947123311dfa6717883eb2e38f24867825917cc6aab32c8a65881e22c628a0d51d2f6aa66897b70e4afa400389ad59c31c530f7153e5a69a6fe296117d8d9d60775020f4234d1be5f5fb11ad42fd944ada0be201e1c1f9d32d42c4c9c496f5d3e10afc540f02913590433038fff6f909f74ef61af49719e4e273a0cfed51127490d9c8831cf2e251ae621c9b3cc53e8192f969047d187e9225b439058ef584b3ec937d948644022d099179b862fcacdbf88cb4c385baec8d5470ae8a43e8b2d04f843cb829c759f153ff2f2962ce4b48d0ca6f8c3187436daaac1f8e763b3acb93c5d36b28ed82571a1dc23e18d28a75fbbd163c5ae51e9ab74736fede2b11c86ea792d4b8efef8d806ed0723ba9b9471a527a34ab574044a22ae4e5e23d36a213f221ae8f0f7c3993b5c3999c2b7b859e0386e4065195d9a1816ad0905950254be89e7b597604c60b385e1d40832e8b90d5782d6bd600de17050476f1492aaad58c33d5c34686b9fc297aef57d8d7a29affcd6801e8539980ab61dfc8cd6474e18ac0123c6794459210dc763d8d939564974fdc4e1e48de9e6a72059717bfdf76939bc52c2ce104d519e4be91691e8377f29ef45c7d4ffe8edd2d9673cb86eb25619bbc9e40df2d2dd678427283b4e69b4c43ac9c8905b8ba26113031ff381999cd07eef14b27e39cdb7c614bb39a7e1e2a7e831f4af16da5dd432424bf35aad0a28da8de7039738c735a39c71f0d3a02a754b3501563311d701d5224692fb40fd43466b81d53748a6f55ae58cd1165ae2016523d31a5a7242e8ed5a11f162ae0ebd0f94940eee4a909620d4154121c507b01d38a9093cbfc3d1324407c5eb5927f4b349ace513f906fa2af708d88f9dff4ce2e78e4fbd4a9d7ec3e2510e63eaa1227e220f6b9ecf112188bd95d213b5e19e6d9fdf6be208c62a989a31dce9c06cfe66e2db644597fca6763d424ee4896f7d69772295ce5413d14525c0b9929e7f8c39b3c742f8d2bc5796080dce4187661fbe67215c35a0a610fb03da8374b0ee051102b9a3b72ec66798750f3c7bd6c874da0eeb750085235baf4a645800c479a2347ac2db015a27e236485496027de882f1a8b8a32150bcc60280231d6522e1d20651d591f0d4cc1c0ce23bb0194a414f4186120d5bc6de6d8140c1e2a8b297624fe124c18056b02c346988291be19e089615a37e2a1b21b1ca01e6c1694345f49196f3dde3785cfd9876f8bd8b5566bf0dc185cd26a5b1faaa41d8e248cf76aa3ab737bd5d1d83182d7456b747cbead6c4494aaaf93848c4d7a80695d5ef46ce766a58fc5ab40b44f5ed5d46d83a280a243f1a93bd0938acb7c0a5b2d1e26770c65bfd2e2a149c30e4fed0ae649fc5fbe306a77fb243e2b01a399639eaa23922e23ea13990daa8922522c6c3e94ac880d8707606971fccdd7aff6bc30fec947b141df86c838c9c2392b68d30ac6d8d3bb8e0a86b319d0d2502ba6832efcc8a5600cd1586d31bcba10ee66080482abd4fb46ea4d3678279c018a7399db99f81233c39e5f0723cd8897ccf467c89260c326b9c41e77136af26a3b972cc61874bf8c4fa6cf02c11df424022a0f00776400c49c1b0ff8c630361b9e3067239549e250dad5be14361bc20242bc0c7886190eddaf7e3e3a9d63ce6734457035d02ca859beb04cd0841361c4b39a754a9d33376287d90647e625951b1eac1c5e64b520509b9dac34e5fd657322142fa119fe1e7eaa9dac1a44e9daf93cfee98e6398c1f4366f82c4899f97c3d4f1b8b627244bcf13c62399a1387a8bdb82c350258edcb5509b7db00ef35082bc9c1cebfcba4d5aa3ef6c79442b4ba809915b16bd346708c16a02a95b220dea6abd819ef265d0e83cef9ecfca8e5b6a6467c9b167d18524e2bbd37ae05fb700aeb5a7f74f5d9bda2f1d686b3a54a254926db7b17427f85de99e442425fd723a0d5f8359d604533f0bbf99a0762767fd89941ddd922539469150aa4753110acd9bd52c35672de04d291c1dd17a0c4d01086ac0afd947be46c289eb8480c0f9ce12f16b9ee07b50d135fb404270aab9db50cb3a73bbbc1df7f4b29db6b432dcb6e3c1b1d261f091e5eb83ad5fa6703565567b9143a2d0fcb79a1835801ca29764144a769da946381d69d642d555e26c064ece57ecd1d6c11f049a8215fe35545e453868bfb9158f693c03f737840bda1e72d66fbbababfc4a3b0280634c47279a531fed08030e50186f01b0d37590781ac41eedf8c50ed160954606e26334f8bb34f8afb3e953390b213b55e6c436f557667f7e87d0e53f09d0a51a2efe167df0b362f9ecf0b4587864b594739c805c61428054fc40127b4a89661979808036c7a8794548fcf7ba76c9d6dea1990fcc159177ce34ce0fa9ec2b6598cfbb2c8325a2c49321714be67ace643539e70efa3998992c2f235c4de5c6e6be17dc873345f5ab9f75d6891de7dea3e3c7d89dd2d13d6d03ddf6ee1fd6763cb8a4014623ca256af7e7f9dcaecaa487e82cf163191d5d54322ac0673119351ca4380ea6d909dcdc5e6953246b0bcdae7a38a2ccb5ecba7521fc310656e6359d155cd6d976689036dad860a40a57f2be2c6e1928871182acb859667c3edc337d3a1a25ffb5f5f0a732c4a2f0adeded62abe871816273726c26d89226a3fe4c612ba633c329a9f491ca92faacfbe3d5a5d399a7e0dbc03af97d0408725fe74458e2a2db05d05c96b03e33d064ee358ba03e3df399962640acb927cfdeffe993716d7e125269755ab1bf500ae9624dd1c881bd8b74bf0b0c49959460af1adc7da2206d70dd8dfdac74415e3fd1011d9dae8b89ff0e04ff1344b303aad860aa2d248b78749548d467b78509e4f92c3e61a2480a36486c41fc9c3491cf10418d6fc9e82c97ea2e9819bd63c79b0614c82a4c1ff79746ceb4b65fea2baa6f7686a7b9389dd0ec2647332a50de73ac11c459aea451b949579cef6fe9af50ff37c36fc8f61ab484d6907c34fb994e3f918e54264e03064761fa1e317abd33d2b74684a310fa876e97630a6667f9e23ea211e4b1c6a494d5a74aee9a7bba607d657d74f96b735e3b0f5e21f920bbffe78866833c079e538ed7f96624d4bf98b94a9c9b549321ebf313e745555bb4d53b4e7cb48fee313b72e64b6acd240d2277fa2e695b538e76ce6cfbcddd61ffec232977ccbabe80df1c229ce2189856afee5741cd37dc6b6df01599f1ae6fb789f14e9ea2b3871271f96141b69cf7aa061dcc0d2b46eb76eb46e71980f9f0d53484a1fe71f77dbc9a09476abec4e3ca089196f10850298cb63502ae7878718503bb50bac7ce8586a7ce6e712e63f225a52cb6e6012da9a3aa43b4c30ad819c30d789abcb9177a902bc9a40c9c079ce4db71c2dc429f3196468a3a7f13570ac5b7e7d63cb1992d602c7822ce274d23c17de3656245b06c6e4733f265ed5f361a9431d276f45f8dfa79953be544377398733a8b3e8f2904452a6b159cc54082a3907786326d1eb864b0bc618e5ba79ea8df84e37a42ca9aaad10ee11249b1a759817247da7351d3c9c7b640560c619f23b30ff08e68b9b18ae2d94053f5e9309478f00a222c973ec9279ab53c7bdc16eecb89f53e3aa9cb38444403ef52d35c69be5a828417190d2fc315e30299b6991193736754659db25f16763ed5e8c37b0c0ceff456c5570a2a578741565b825d17486694306f2b6848069c7f3c19ffae0ae87664bb0bc9c22c23257741b33c5b8186fa8a03125861777e034ddb2e8b2424f73cc9725b118dcfb0065ab64f47061b7d7f45323b8d55aaf60e193cce5c104249b33513480b0f65bb87803a4131f839917c738295de37cfa3b1548e584f4198c055ecf23b2c837321d9c861d1ec439d0a0b9b85d8a268251248f1c329dccbc1c2f0272abc01f145e784d1ac05c1461688a5e2ca8a14ae494fbd187f847c62446fa52a20c97be9415c4beaa69a7b8d17f145fceb25db941fa401173bf618cfa47366b00249b193202eab9f1e80339d2159859333634f1c1a667265a6653b75356c8cb6f4400a6b884e60ec1dafb7aaa79f09320b3053e8d3559b0d68e7cc4d785febb8c0cf02eb979aac9e07f12566fcc2a9cc8423c1bb77f95c4af60bb1fe945222d1207a64a44c07bf8561c7122faf80dc0c12d1dcd9d99beb7b2cf80dce237424df2f13e63f1671430d224003877c21cc7b4e25e5501c36fa1d11056b5b866a958f3b9e20b43f03d5047c11547958962f6e96447e5d1308d720fa774ff67314f8cf7c973667e5c673fa08f6960d3f243d74f777ad2036253e2d492ade5322851df4407180a00189368b1b858417c7207a728befefdae6bed13226e41506232d28e1bfceeefa4949b4dadb720cc85424259ad5e858d8f267c43c23c660fdfe4566745b6addb15be8c03240ccf353dcf0fabf7b7947200e9a52dd02fec5a454a152f00b10e24aa89810ea6707ee057d41c883a5893dc933a704e1134cfdb2768f3131234582a2a0975357c0e1a5c058a6114e0ae5b06ae7c1267ec5da3da86ff8ac861ccc7791ae7cd5fba1fea287c2137456a51030fd60f62db750358c84bb708195afb69116ed09ae13f963bccda18a2dbc52403ee6fd48f4f3403619a30305de273ee783dcf033d69b5d2daa58fb56832d3f28ac9d869357489602e0e52dc5804bc5dc684abd43efd682e71759858a0020c05c8b5188538817cba910d721867af7dde666e9a1b6209a54fb5d8c3f4656a96c96ae3830ef2a2c41b8da17e75e60a8745f52bc5934eeff30685508be9ac185c7d9c4979de4b33cfb266993eb579f21eaa0018725473368a422f0272d8f090c677c8099493c16915ab8f45e7f88370afa20bc714c21b6d028e51b34b3607ebbb00005c5d4157a7b1f4908a9487937e2de75b33805eeb6817b144d4c3b9626f313cacff3f7971a439a41df490b29e3ecb84461b3b8fed352aef0880cb1b16cafd3d618d5e63fa4f09e7cab2f5399cdabadaee92e29e144bb0b62416b958cc0ac4dfa72dfcac18c97cbb75069d0f38149f81a7be1a98a713ab792b4eaacdbc7d6ecfd19d6f722386246f1e08d84b97fe53724865afd5408f2248b721480a9663fa88a55418b77df3e1cf26d4f9cc126fbc937992084745797e5a44d326d393dae0e221bb09a19c4aa23cf8a30a8d30b54e4fdf678cb82df834773af527fdeaa13df84fa2308fd1196985623f755911e1e0853ea2d9abd7d469d82a8cb63836592715f5d8520755b9832430a508fb476aca2d9da8c1bb0c30fa3981b39e7834a456e13de0f19d37c91a241125f35a34077f4b328638098294d7303092435529df441595886c160ff2f558b5e0c342b514f32736a6079c11eaec23e986f50ec9ac4d70f91a71c5587758089e17ca857412b5832f899641d6aedf3209cba44b3082a7ed574b3a5dfbf5369ba002554fdcdffc5b1f1507e686fe3d06d6271f780781a386f472400fdd5abbe9ba9747e9322c562b18333406326806f2dd31636407a19246d2f219e56435c7a72bd52d4ce3aef8002f82e000e5ba7694a17744ace5c107913036adfe8237d697354714d5519b848ef6e39b13a9886f333fc674d44ca5f130d57c2798dd83a30c5f3336d995cfeb58a4af7570a735fea9d66e846693ea2c75a102b63a0ae7b953c51cadb05fcabdf84d4520b692a74b840d10b099f327fd283559775c30cdb82fa93f2762f95ab04584ed72f7d829971a3cb955de0a06046020828b9d32d6de7130ba5068031eb9f055ecb91fee8c58eed8e9f9cb88356450c620ae8eda543c53666c267d839389c32b7caf1e9dff661cd3b842b6e8b64af819de752954e643369b669861a0d29bc5d8242a9caa64d9ffe1bea94687fb2169b6d3a82219d95652f8e78f95ac2b41a57b2c9a5512e7322b526640345b9200ee8f54ea0a91278ab849e943ebb390e30b95f1c6ab3f0c3a9eb7df16b3d6d570e1f99c7e10ec65fb2edf08a97cfe6acfdf911ce92127d0eb97d7050100cbc2a853b91281f56da2a38b8ea14f4f9fc3439ede7d2c1dfec4cc9e5320c4ef15aa351b02bdca1831248d2042bff9656cd2dcd4e619fd11a66586a88d9fc3447f437094efaba76577e1eab4e17c4a56860c9f989925b8d6e052f294a2c8e4a0d4bb535b82aaebd60e5f55279a1d314ad4b18d9b10387bc3694eba406d60f2085258c387575991f709dfba278ec8db674d2e9ea12fc2bd0c30d742977bfbee9920c24e452f4d45169ad7996779d2b2a956a3caa932b94452f3894a59da1c15c3bcf77ec6353ca6e3381eb121492cabe9156b8586d8b5582b33bc53b03c8c6821626f0185873fbc58bbdfb31072a9e4f410fe1dd8d542f735eadd3981eaf29d6ac3dd1323010c1b94e258d27c215c088933f81352bac5decdbafeb3abb243100f18c609e140d776682e93b57efc5db13c1df64417fe89c6b7704b08fb51eeaaf66830c823e02938845456ec538a1c0ebf8f91e6fb31596c57c49140c6370d7c153563b69f935d05ac705b60ffac7108d45f33ba436f4beb6f436563d80341fcfc3cac5e266cf8d564b9a1d1c897947115b09968a23d4e30b707d0f195c3060d6b71d4b367bfb7656258a767185f9f7f69d5bd825384d7132cb5b87fbfe28bffae397fe5c4ef46051e00dd07a9b72cd06f573dacc0b426b42981049a287dd7bd0b1d41988cc027699e6ab550e8fcb445759a09890773e4fc8541236f1bdeedcc7932b8944e19235aa3c65956fbcc78ec85c6b0fafc92d61fab74eb0b2d2ddce333f4289e91791a55070cb537a64b55f53cd558af5dcce24ae30b68b73e6429842836f4b35f9eec1f0df48beeb6fdf5ff79508e830683c8007c230a51dcbce0ce2c22291080850ae5a9a1349436b0ee3ecfea689bd1b3c16993fafe59a850a2c034f02a9a71f66873529b74ca318c8834986125f6795bff498e8a91e726fff3ef0aa3ef3b5fd028d23ccbf3e07a125f8537812b694e828edfd95878b0606db73339a4979422b5d64f42a01a68e1b8a16641203f01443b33fbac2a062a9f0b65270cb3e106c84f502b823cbaec2dc26ed0a8b698afb39c685ecea60e51c35794af2092ef085c1df74ccc3cfe188c4466b7a37e0f1d310e1b438e10b2c7eac248594d3a8adf9c1a68796375ce682d452d32f7091dbdad105a5581c8364013d542e0b3a0e528987c3c8d1d8fdb4693f216eb4ffd5db84e4be09f79b95f1d6bf87b529fbeb3d1327ee4560823ff7fa6c4b1202ba1e4e4794ec472e7bac40a610c451814a77b2d950146816617410804133272a09902bdc75aca7378202e100fe28eedcf19d1d13477206a85dec5cb72b95bea22189ce04608a39f02a6b45dfd3e68b8532076d7e7f6a90de6fbb242999b890612b057398dc0271a9d0be9c0ef2c88129d0fdfaecaa383f197bd731ba37ea5738ced3abe820f9e804b1b588368dbed309e1a62c0a5a3c71af07cc2039b7f183fe40351d6d82a0785e085ad31593ef885a53358b990c4cc2c650462a05a3e963a63ff2b5decd164022e07046205611a485f3704ad821078410afa13af1205963767094a23233c585473f1002b79e8c1f22d12f241c48078826c36a492b0438a81c414541668aabc1c3066eb36da4a77bf7234336dddc5402a03bf0fe3503de1faacbbedc358ce719212712d5dae67c294508a4cf7092648e738be41a9c4a48eda2e4f386c187c851255390630029e21a92caad7d54c9cf048138355a38408d1397e6eb4e35e259c95e271b815d682e7f2afe741052d1b70c0876809277e067c62211a0f3a2921b2312e4bcf4f7aa44d0b57ec3e1c8fdad372e13a94aa9366747c52554bf7427f72c586b8191145480a7cbafa2c47862783a41a0fb2ccb1f0036d0e9faf5e5631a35668beab75c36fd5d6e827f05a6a1e5c714f3c493870194d35993218a55790d5af757520d484c97bd9640bd7422bb1d42cb2bbace5c6f5fda69840d95b4d4e097e657fcded22a9d297fd92507d8c0ec7cd9371b704133acd1db8bc6c3e1ab79f15e985a12349ed035bd02ea14fb539fe51233565156a9bd6df98626cedfbc934b9257554472cb75e6b35c986a20b89d41e4039d0f2615345015fd335187337d48d43a2b32094087f2466356aa54b0099104f0a95f92591cae96be5761dacc8c28909ea7b0296ee4dd651d9557177c6fbac2b549f9904303f652d8e808b85051b3078e68c524dcb64f4b61805f697948f24076667af59af26696e0e4cb59581497f9828fe61a48e547c60f782a4fc67e84fc9ac9784d42beb0881345060d544fe5fc3cb0d2846e732b3240caffcc60ea17429cfc9277e6515170afc4b9ac4b4f9c93f81b8e556af197bd5bb16186b690bc9f1cba7d2a683ea5deab15d10ba4d09c66fbea91a03c2242a4e1a0733c2e029695a8fd10b18ae74ef255c72a1a9ee9fd161d3677f3bc4a2ce9afb6233e0b9f9aa8b98325776be92498eebf9b2e4e443bca3af48c4c57ec280a68872e52edc9e76caffbc2d55b7033161617880cebb31241eeac80211643066b0cc04e1724e48dbb60d545db168a55e778f902971ec6de93db1eb56600532ac31f28fe4133ee902d2a88c2947907d036080d4da0d35ec811ea84148a98645f7ff9716672dae14c0c0561d895b5c17f13ca97eb0120987c4c9dc08d0e10bc86194f71e7ff8b5df8b82253d08de99f58bde72b765908d4ba5cf493dc15783cc46e435e4bd14a02de3bb1425861674c903a3e884e8d703294f68ed54e7e3ea95038b2cde679e91d7b25c33007a41acaf75ea2f0dd5f75ff8393fdfde6bbe300d66a95618ee036f975ac47e8c9f4313544e0f3d2a4287b82b1473368304d21d1914f5a92e2a94a3382fb9d29008950c7f70a5106f36c910d7d2acda31404a656d92f8186f27fea35910a43e22fb2377254bef888ad473091d7b51150ac99efba4b1b6c0c7889c86c27c9cead524481344710a20e5beb252cc380479677690bd9d633141a8dcb3b9285304f43d390b62e37018900e3b512871303f60e8d9cd1fb6c054b902417934e01f3660b0cc8886ceeba4d13cd7b6bc7951553ae520068b110bc1cce3711aeb01750c8c1f31de6ac7280320135f0fb5197c40f603a46648e7325d45e3df7e21cfda9d63226d3d5cc2d810556150fcd89d32747e1913d0237eafa57ab7646a15e1d0f7e928f19cdabaf10c089226bf661f41da524553c29379b763949f8585561392d604de93a0194701a7ad4824779aab316b452c3d61245832b28f67b7116d684d5ee495a49b4676028abb3cd18a0d1a44946aa0764ab0d592f2967c8090f4c7b3ea737598e7771a59d6fb5527eede2bbccab8231304b8eece0870966648aae87450c12a457ca021e76a7c0419551e9a6da4b6cb07fa53cebfab1d381b577207849e829fc85b26aef139d3f02ff6a55276b53ff6826125340c15fddf869757b7585e72b217e43af610c81729876da5020a81615e65d4b392e02228d2d498c301d7be3350919efc6283a51ec580136abd7373844676835c2acb575b4de25ea6cbc245bb31f394a93e39cb53c4cb9312431f58c4b12cf24b3e399844f02935c1b5cf0747ef74256084628427e5dacd6a29898b1d746b20bdb7e6cbd32a00d5f02139d3b679195c22f74a63dae4774b4def34752af12978848b33aa92f47632375db472f05732adfbb2ae4520e6246081dc2c79275daee00d32d8bb1176d7ddff20700b2ce913e8df552e4c8610ccaf03bcc734c04bc3888264fddad1985a9cf389d56df72e3335e08b265773dbb273742697d6ca04f3c1e7411aebe8d56b428ef06e3324026ef17147e11dc17f68635cde19596806996c501f4b60b3f6fcdf898db9086ccbcc8e37d87040534d3ce3276956c96184a04f2026327c26ac9b083ad4fa37749affce8c434f65de20c83ef62926750628674c9c2d8d32fc49e3bb0461f0486580582636ca890fa84f202e097926584d4e496a7f3da8f5a34dfa565df0236b5a8aaa117f773d2dc3899d9382e9bf5cf07c429431fc1392ff3460ea28353cf8b53ae210911b72b0f70ae623fcfda213b4d5ec7de833dd1b9c8af60948a422b7a9c1ced2a3151c3a4ecf657f91ecf41bf5a825611c50f691d1ad49444dc6a8496de21b2568062f6dc6f7dc9662eb9d3302d316282b22483012d595be867f40f69feb582b32339b2b97590a509722cee918e409e8daa367d5851d12e23264d3f6d073d81c25bca2c2f94993046b571b3a636ca93cee0db21a27a90836831d103b22f772a06ff5b61e4e074f00c0cfb8fb15f108585960cff591eb750f91365622f60a6788b460b253117e2a5055228272f06c436e470d56ba961789dbd2ace13c127e3ab9e600728ed4acc51c0e04ac2dce67312a7cc8903b5c0eb3da16b12a7f1dc40d53f6242491a940f0990cf035cf4113c12edeaa9533426627fa8207a78af9751f09e4c9c6fd8bb039bff2382a027b890b7ca3dae0ed1755c202088e88e1ce8384a66e6a9a4b46261e0de6f02b91e7e38a373aad6ec7dc9b08cd31b0bca184963eccfdc0f5f321c9a6760b933a73cc00cd59c16ef1b35506899fe830f02f00a2894948c36f934d6a7ce046558d0fc992182c9ef8322cf96d38da0e2cb9561306a7b8c48ac0f55a54d48aca0ef32a8dfbde94b278398bc645e2379dd76ac6981b2a4dcbb994c313d167d6468a27a8aec462031529d543d7be62aac314d036c2dc252b905344a8e278ee4ee181f3097f7edc64d289b148e67b3e3593ba59eb2adb7ed728d464a9cd06de9a410c2d2fc9bf31dd4897ebc9ead42ae4a8d201cbb50d207a7429acfa30347616bca4f497715a2523bbe2f1cc1ec0631885ee1352fd4e5885a511f85674a423598de4df2edc6b9e956f1ed77426b83825d444e461ec128b58d25176648b07f82e6269aade0b346da6781fde324a19c029e543fdc5382f8557046ec60be8e9fce64b36d20f9180f1ffb07bd2878f522628e6fe996ebd7cae35a713813d0b2a6e49b4b0d2fada5f9a6645342ac876b2aca5ea064fd13d9652b007a365370ff13f0bbbe7dd010fd7b294d091ef0de48e30193faf6d0c55e54d3b9adc1310ca826e64261755e4d5034e56a1f0d1aa13fe38c5af61105430fb29a09188e6bd23ab2b66819a5c20155f7d1fa011de8d6240e76808a8888ceac6e5bd67035e9711a26a117d67c5c14762f3f94c1e0ded36adadf680b3a5b28325331c9ffde477699d0f03dfb813176b8c4e7627959d1d877e474a738993f46137ba1a297b2534e75e4f908256ceb87792aff2a1f11ffe99ec0eff0e2aa0e4262715de4b79833d3eaf5226abc5846bd6cf061bfd9583b216cf248abaf1fd6070913a3f707ebb26ab86cb0b130871b2f616e8f5141378eaee594765b8cf649f80af3fab7be17aeeb753aa64ef8ec49cd32fc20dd5d1dd96c27d3cdbb581712da6fce8f987986f0deb441f3ee751339d439cfefff96560b11842f861d5354ef28079106adf7eb8088560e4a6b22074a849a588d5c75042203972e32b2da77bac9585fb23d7db17d42a57bc60b7d08054d953e64554de39a04b9c24d7945ef22d7cad9ddb5856b03aa400feed5aabf09d1bd60d06f089516383c311f7f78ac4c6acdb68c419e039a6150bec2e09046c2e4995f5bce65dd36209c3f4e2cc8054292f9f009e5f2288da554c560d8d024430d22d8b762a16d92cc457243442adf25d219a0fc89b78a293fdefeccc77ebd918629a947aceb601de8258fd35ac83b5fe228a0f328dad21b3e75efaade1081ec3b5a89e615f2489d72261356f43faeb0c0e02484623fae1d293cf55210752c0ddc40265ec0bf90613c142577b0c4e5faac573d715287bd2c21454401ceecb45722f1c144530374ea460de1e6fe0c3c3f2b3c9af1ecae2f2cbc3f5ecc10060a080a26bbeb23e1aed0ddea806df98cfb8fca05e9257e1139cbe7210e427d6af98b5ff0494bd4edffa01ce8d848efc1e34498b8a9e38e8c0d05e87fdecd368ef87d9845d2b0b34706cbd67c2331d22548aa410e88f2a7596d4e2df9d59d165b2bf4fa973386d8a6a7d15144cccc38a436554e0399a74a854e375d2faae9c987d99cb436e7da3ba0bba64821e390098571d8c2fa65af64681e570432bcee2003ca1c0b2d0115e87648948fd30b6ec6edc1c05bceb6d4154fca13da8b4df9208be4c1f33933efb2556f88715ff7facd00044defd8cb25a65c1abbeeb4656146fab35f054ce56ec50f1ba0c512c52aa02e5688c5069e12fd97d802895d459cdfa4c06c71552f75c1fef78f1b2e5911ec819a004ce2ad3c5548b49d52e09e9dba0907351bc4ba62911eff30bd56a95358cd3fa08f3e9201e85069855657eaf5834d5d52544248e08d387d6f75c58d4c02e2c021044fdacbe06eb5750c4fa1d18631af2d6ed49d79098774d4f6ce2a6e44d3d27709e05331b8de89c57a76cc1c0336b35a70cc4ccf58047d204dc7a456bfba0041eaa8e35992ece03f2982f97fd0c5d640d1c550c4f8b8ca071dab771364b32407a967741b9ad744972005361f29fad3d36a36e7b7f476bb8b6a6db48e02beba9fd4b2415b71216ce091ec825515da0251456ca44f4a2cfbc00edd6507a2f44890ddfa91d96c234117f87014388b171ada3bbec39e8109a96cb0a1bbd6c9e2bb6223b64762e0be0961b7e1805e82993ff9dd181f5d13e5ecf52d67a763cea9859603f27b97bc54ce62abdd9d1e18a107147be07c8b53ef2488c208ba23abd504c51ee8796b24ccda856bcdc24cd2a82524bf032d74b502d14588dd3b4ff3b7e1bba334393ed6984406714eb0a67192dbee2ba5783f6b2c20ccc7f4d0f6651059c548f99e65287da537d0a7ef056d5be81031ccc2229290053dd106232a517d40013143ed9c40a191dd8dcacdbcd7a85c0ff0342ec32f8e2f65a8ad45ae53bbe4500cb9ff783cee8bef7060d1c202354082fc8ef0e8fda0b09f29144210ab08386d30d85872c603442a19fcea13d58b25af1abc43e1440c2c1671eaee9c9b8fdfcfe78e896a0d3a08917826db2d815eaf9751caee6230466f25fe00ec3f7aa2ea033698f68b830e702c170068b51c3b80270ed68831eafe352a5bc4d5f0608808bf2300d4517f620976234e846852c629bf5c1f0e836280f836d336e0e674de2d8e953ca58ec744fa4ce0f6166a6519d8881c37d3ad4babda1f1f06dc81746a0ba281d85ff7815c1d35d417fc7a2997f8120d1df0ef67dd5ad22ad6668aec5ad5a2d240254a74faf79d9f90ddec61d0f426bb1828868af387edf13a3e87e0409092e6564f80370591b80a078a2479aa6024a7223417141dfe94ac6b0ba87632773762db9676db70b390f0a2df2f63501c39195c3ac463f1aaeb0e3c05111217505fe3d4077b33904d06fdf348aabef16d160fe25bec9db8b6501ae4cd50fc9d038904b932fba76e68eac89a9e675226da5bf35e16426a86ba2398cdb5df39730c6697d5b0062cc12f256bd78e83b295be22181ec09280621f256113204f8e34c49acb713f850b5649eeb55d9580aca660db1ce28743ca196f7b26afc5b7b6b6a67ed140e4713c37b3197010166d05a53d27f5ad16b86491753d3e2f391a48359c400a1fb9a7403735323392e539aaca2e5cebb545a5a32017433245e5de1248a1d6955e09edd3114a9a459482f356280aa2bb98fae329aa57f85ab969fc55c11798291d3cf59b994dc555557b5795c9b32ca1b9442d99c19210aeec001daa39d94893d6a1e29a831f34a613c8da73600255999931d4c7390e64ad457f9b602e980400572e39cd1b88e5c9f052fd930db7b13e5016718384b370cf7edd755ea75a73c736436a19d03215fca359f663c7af0f16818115b9033cecb7072ea4560f21de6d44a0ec1abd6d9f3af81404a78d6bb666b5912105d921fc65febcc9f272db2d30002b616d477eb18e714866b6e41890aee1f3b4061dfe4b3d23905a67a98a882833acf6261ae426d0b4344795e1748248bc3e89ad48af708e13caba08cdee3d3b94dbdface923b309005973861868e7c9295c34521e0906ad854e2a1419a4e5b10278da3345fe65ee728c81a61dd348e2e3604680285d2402085b52009a98e1d4e61f75e17eef53aaf407bff9bed5b07b891a7030d7eec01a3c3289d749a6adec6f78b930b702fbd3a8bb0c081cb2e11cefa88c0c0c3e7bf036aaa59cfe626990dfd3e85ecff37a0786e25060b91933a266451ca90d03c73b174c7f00641e2999a7034344cee08fa7d44043dc7db3676a00a5dd586c4e6fddaaef302db3694e511aaf3302ab443525587ead793bf474c7d3b6e4a3192351e83275319fa6cd042f962cf82aadfded240c0aa2dd9da2a41d60c8ae75441575a7d1e638a797aa512c20ec2acd380c3e77d321660ef8eacfa32a4514a28fb601e8f87f357eb7d82cd167c45c4969a3af2a0b6055d046d866c5d9ad8920eb90e64d7a2d4734713c0915f12444d9782e768aadebabe43373fc139fbd605c4dcc64ed934c2e1130b2ee25bba24fcdb1d1f5559a55543bec4c60fa68ca079ddc53e9dd7e4f447052dcefc61ac20f8c0da7de6dffd62328740522d9e5e7e8cfb119f86009c0a0c72dec3a757ca64c64495d9d16a1550a3d74bfac7aab8221bfb6163d45b0a53009fba81f259d09fcff4a9ee3f30b4303afd87a23789bf1a63ecaae08578d09190ba5f68de5efe8c920a922c40373c139ad601506b2f4bc60e2129b78826b17ac5d954de1ac14f899a603bcfa2ca18742b3d84a66e23da145b4a3c42ff5c773a62226c8d6a8caeb50a208908222b2f601ef3c37599a48fd505bab6b90436c5cb2189641dc542603de80c1bee938e68a0c28b48e6857c5daa05ce25c4c84b589b3137b280c1df8adb5f4417a497947f05217dc888f684f6873793d12caf19dbed38cc967e408b900d239694a982ec62b7abccaefeed39feeab13aff90550e70e6e5b97c2f664e8b09d49df95b3729ac67ae5086f03261c99ce9893e7b7c1972822bb50a06395a4319405ec18a632b53ba958dc67ede821bb0ab7d7b36afc78a9722eb3cf92ce6619701f55333e845b22969d4a896b8fc739ff61ab78b66242f3041400e8045eabfbc66ef5c4082b2c0990b31073c1332480aad092714d30d082c5ca6a74b9128c413c873726cd010ca3ad4dccd442fb8551afc2fae2ddb82a5622677245814dd6c37342af69c895da809f94c4db3ebe4232ee2198ff218b17b8fb9cfb36747aafddcc32a02d91ce5baac5fec92107d7f2a891baa738867a0987a92f8c2407c8f54d74a05e5310a2da05643be465f374e90f8324638d86e7aad04f8e78e58532eb0b1baa849183849482f33c2660a9de2f5e50b245b417ba2ea706a8ce83c55543fecfaa8816301d98f187670088c9d9566cacc2941a490b470867085ee2161786d1177d07f673e2c0a8651d868a4ba2b976e0f2f8dd06f2281c2291b6a92844ac498f929687965d36d896adb294ce9c643d0435c05979d56d159ada4a441f6101b69b8bdbc114102f63bac7ab7ae99d62f3237d4fc4fefa46e8e44b0f64c847cde1ccd209f135b8c391c4a441bd2c2813888f62b903e46e6d6ea1f835818cbef94196323d420f5a89ba871b54982115415735db870d14297cf51d844e6c059e8fe85d6edeb533217611da6b19487b3aa91d41a006447654a4eac0a0f286982eaa3f11d1ef4c4309ab532bdd7202a4fe76543a2c481d450055fceb279621e445a4324b4a30cb73bdc817d6e160dcd84ce914226b992d106e291267e4824eee77c0a9d465bcc8caddcacc50b1b2642c8448e5a8a0f826ee8300e2e0890ba7c84500c22a0380a81c759852983bc24683ab87be4814ef38e2ed55a3e00400c3b505dd96238d178af20e18b40a622bf6974d7a3a95c01157dff989f8d2e2c9e75312064cbb8963ef7f34ecc400730d482c3e4a9aea1ba95ac8dfd0a264c43694b03542e04e9034f85736c5a14a6741115453c244c33d87d9829f102fd9f2db3546e166b3fdb1ac0d4e7f49e0e7cdc3e97e9b0a9d2b968ebc04edb20bfba1da7b56e33d8a51345864119e91be84653069dd51201cf312abf895271e2a37311dfb3a9d16df93f669992c6dc4b208a62254e84a5b65377632bf89ff7083db0ff0c332e9064eaa61b39512645774d0e229333b48aa845b4f4eb8f93b8e69b360db8639100db2b50ea1d4b0c76b8b33c4b620cb528162665dbb716581c7759d6c9d2cd8d631b594a474a9e21bc65c048c9f6716cd4b9aaae4472329f49a7b9bf8c5b7dabb606cf6e47930f0df472f604a2a62e03118d07ddc31746b9aed06d79387de62e286343f00bb5fd56bb02373d25c62eb8b9cd082689b50bcd40aae1b9782406b789695b073c271d4ee38b94de5c7d178b8ffeff91d46eea483089603f37804bf83962e656543c2324689a71d63423f88fc2dca29e319045b90c6050f19b74da2b9845723bbf2924208d8b65874a13aab6805db757a398497e9a31ce5f011d3076e49c6a271ae7dd147418b061602753ca51e6a2f7f4e366c2ff4b992719d174bf3c21dc1b286800a6724b51b1097d1912d3ca829da55ea9850e2fc19aab11bd571fb743fed9285790b98402741110da9e3899321f0647c243d5cc2c7605286a4475108446b0d46c2aa985409b083117aaec0fad22d080401735358cd4554decc2d09f7640b8ca7a719db6b129f72d298b6381d24f5ec83e4e9e861300fb2d6c00f34fd4d78b619383106c3aa5093274bebdfc230b8255bf44c49c6952e1414594f66af4361cf24e1734a3e36553297e296496af7d8db57c5af27243b959d51f20c7eb4654a0ea2593852adb900b5c90c17d03aa8bd8e6b9954ed47653882157d694853eea42c8cf59535e1a81f7c0567c45441d5a9b4fdd7bcc2ffee32106a88bf1921d66970313ee34652c7b2db0c41fdeae14d3c0b93832d497bb572bc004cbccbbbe704d10f2c7018fbc2aa4b7ff151e6eebd78d87c010c88c11c2e799e9273ecebcd3b2b4d7eb3be350bc15a8ee8d648cc49115a99c775ad63349caca8e261316b716a94b99dcc9b00a72dcb9cd8448e470cf5d90e9c5a6883390eaa4bdd84baa353b949145c98e6ec8b979ae700ebb7c70b0a2f9a86cd3d94bc6188fe4719afcd7394afae850b8b8a57c1ed6ae883a520084b317667408b69296bf68a92c51e0b00910f11c1a066361ab7cc40d01d83cdcfbad8efa6400c7b2b7df9cb84b6049808a74d860d18fa8f347274977067aac57790114c6ab32bc74e8039b06ef158cc5ab529e8b57b9147575f9885846d0b365ebd0e54b3d60171f0bfe7ffc2445f5c610b8d00cbce00e62b43e14dc55d2a32d63f795746c0d9c84a09d19b0720b6522e490447cb42b4619c3fc12d125e0484836180364b16ef6dea3403c74d9f92d93028102134dbfecc0f17c46a4d6317c5cfa69ff395aa84bef9d4ca8e4a81fe5b9e387e8663083d098f69e666294620842b804e0b10d7e5f0fdb2c30e7b19c5d7ce9b0bd54f5f5c4ef25fd8e83d22dd6201cf5008a0957ef1610e8868eff4b34382ffd76a5ad167718a0970451fba13a108728a21e040e8ddb9159e2a4d66990f6de00e9f4a49da729bc994f32fd21ad4379c602b13edc5ece29cd88c161fb53e7b5bf221fbfd1544b408cdfb9b69738c0f444c38af947f04eef7224ae440e85ce81132ed20fd6a08b7e7c7a22d5d731145bc1af3cba061f15d7ae04e76aa435bbf6d5a20cd051450cb00d054926f86e832992c800f82a449879454bf11d111e40907e146d6827956a0d0b635c054e844b43b8b8155af0a47b7c1b92f9c177f588afa6a15e7f2c318bea4268bbc11af70604ec9be9f6165d827ad68d513cfdeb919beebfa6f2b92d8692d4abd2c7e1c109e6c2513504cbbb6cadb2dd4f45504b77f8fa26581d6a7f5d18250f8289d705dc1d8bc2d46c8c8b56a3b6ec5ba60bfe37b8cfdab5e744706f4fadc4814ebcca050dce2a784d8fcc6c994d4854f977394212aaa46f915d9825b331f921ec956e6e5a679d0b0e4a4a8e3b80ba385d93016fcb835f415f4ae21fa8685c8df21ccd8c4ad0d20dc4cebad442240f415d6839c597d10f8117d059e0533017288bd86258f90a03710924b1558970333af678dce4bf782cddc68e6c849612a8cf84d7ee199579676266a383fa729b69c1bb3fcc99e42506f55293193accfea1ca602199655b13b20cea5849144a48da0d2bb7bee180f0043134c7496603a65a4863ee49c0d77b724096229b309eb6101274202e2accda05f0c0c3b034b533330c6ce3b3149bec663e2ff0ae78e2264739ed3f79bd4c06cfc0f54cd25f655cc5b857b92be8cc846f037fc398a656843de93789529a672d354ef5053ca722c71a628119cdbc89539adbc011256f4ef4013751bf94622331b18755b188e32079e0059158dbf2fca29fa918ef5096a93e27ea1f9e7b9586fb0db0e4ce103fa71927c5a30523a4a1b557ba611d5181049f87b5d3578efeb15ed62555c45c95e739dc48d5d89b1a19346eee9649720ce20be71ddf7cecec471e3790bac553678cbb848f0a2321d57063ac65bad11fd0fea13d44d12222989482291bd690760084e07b0073203ca3f72503621eac4f840c0f5af379d7e867b4ecfa8437fe6d613874d1a6b4a8fcc7d55fa56383125ac63d7755dd5d0dbaf32f63663d6630880bbbaf247949a2e65159675adb56fb19bdc7f89497bcdbe0848763d92f65fe7eeb57addae6bd332eb177fd8d192f0b2d30b76e207f8e362e211f4b1711fe311d1043bc62b95abdcd33c8d5ee2499df89c0d2c184a1d4b7b9e3427b566fea491a86661463b9256423ac16234e0e803a683e455310fd8ea0f9fa828ca96ef590587e2cfeaa3ac2af0a5a2c71b04499ae9ef859d197961cbaf681bb1b634e92f866dfa6d03024aa53e6f67db7fbfb36ddb7e1b4a42b76cda4c992933fdd7ed4c675baddb5002bcaa3c0b226902acb7d62f86bdb5d6643299be6867d96fdbdffc75fb9a724f19f8b587d956b4b79c846e0dfb2cdffc25d998cdd56399fe35bf7e90846e5d61e79c55aa6acecf3dbab027dc39d20eb955b9cf97347b8e30aebbb95ba77c2eb54a1527f6c42e480487e4c79f28a0860c410d77ce96b342183d9797c72eacdcf4da2aab8fd10cb3f7fbea150e81e14f5da137037d78402f7e0761849ed72a6bf4aa2a75304429c03ef62d60df02b744ca92eb97d4c72e0da50e108c5eaa8a1504160a61bb7d485eeae89fba62c04203e0eda6674c8c7388e34044fa56ab351d0825c4e8b3aa755befd65b5e1c41ce96357abfb3054bfd59f875cb4737d473c884518694f51656cbb2f4071f47f4e1d5e73edcc1e8b6657dc51b96bb68647d9dd6b2acafea4c22ddc15495e538ea43fdc1b774a53f77aaa30a28a594d2ea734faf023a84d0e974a702858218ba6c8f12dfa330c07a9475fa8c925616ad547644e05aa5cec49565d518e3ccb9d785510cc32686490cc3302c6298631886c11a42955583449905b99910d72a8d6adad4344d46d7340de20bc3988d0eaf0b5bb7d6420cb3f6664259a669dbb64d6bc7971046cf9ac3abf9b6c19979c41056964bd5d0b48728c8cf77fc32b05d6f189b4c27df3dddcc8c27b42324ee1cc8d309e108899b833cf06b788c31c618b5bbfc19a7749f4b61be54b992f4c481982fb0d003949a77ce2b39135ed9baeb6c6c6c6c6ca2436d03521fbb00906a3acddc1e39a7ac8935355e032fed83e1749a99e1381a9a1a35f0c6aa689de130e73457484d07d40175b1734a4353a3464d4dd779363637372854aa67e762685574deb821a35f35375046ef6cf00dbe12dab0216dd88836bcda6442379910148ee3407983729c6843dec09104ae40638ef9835be24ef5ecd41c570e1682bd317f292171dbab23f3349d6d07e6c163c29b96f15c1e8b5d3c3cd5e27158a37d45fb5e871107077338703e5b08b5ce9183f32204f403c210421041870ecfe33a211d6ec70e1e3bdbcece8eb6b3b3b3b363632313ba2184c3a3f615ddb89109898f234772dfc91ca1fc5c177de7e0703964f41c392aed33a7391c73721cd29cf5a633a11c5cce0de17a16e48a0075441dae83e66428cc9d5474284f803d4f4767c70e1e3b3f42266421beaa954a553435654c792a958226ed2bd2e1e9e87411da910989bb0708f2b83c78ec509e29a3f3c0aa7d4b3c2f13e256277ed43a3b78ecf08c20a343c8b343661d3dc6e831422b7ff59bd0dda7363f222866f3d8b163270bc22313a23c3221d72828f8bb0e631129401581e107459e11a4ec4164fbc748d4790a0001c884049009c11eefa9da5734c2087284e8b0070a85d4beb1a3fe260081262c8c6e44c6996c77aa69a414d248e98c926a0de91473ce49941373a0110906d260a7f657043f3772a31d03f6f73d938804c03be0f8dfc78813638c313a86151cb2ed1923b7a5ac01f5e855abf5b562dc75305715dd441ec444d8092184dc7dea5cdcaa28a5d4a97b2c62d239e5c3af43f2ab6ac99773da9b1e2f289d93cea9ef3c83fec420c5bf0ef94f2d44df7277cb5d4f49abdc3306ab307f5214a8be728931a4958ba4f690fc1bebc72b095b0f777c5a7754e2db7591d4aef4d07c9737d88ffe0d135809dd951ea25aeaa1f83ec3d2972caa940942861bb24c1720e1e1080e2e3e40022f5d0081cb126362161d30e388279acc3082262418244a62e0a5035998a84103369c71045a31a241135f9e30592209337e904598264884e942c90c2906121b4c0cd185164590994195320a10850c252652c2fcd0c5bc922305195e6c20081f34d1032ae6480f61c0600b285ad0031371cb912d3e948004484835f8820c19908104298d1ea028230c2c494954073598628a256a80d2039931908821a3054300010aa32f35d030530922c8a032c4132c64446024c34042811684e940131fc22c9d012684230f0021cb18198ac082e6e0c8ac02c9092ef0618b3159a0e10130a81847ca78312687107421811552fcc0831eca50d9e28b333e3066098914400105151a7ca1e18b1c03893efa000f9618d3449829611cb1028e61860e70b86203165ba8902408c3064e0091a481249070010e8a8408c1126472c032441857c0e8c10f860801164258018510f308119668a207625809410c6e9853e091a9a50b078a30438a1f68918418f40bdc12850cb4b84203661c81c313934a1a5794a0063878f24412497c8104822993c609c68ce0cb1667502fb48031c313204ce0050751ba4092c2165d6cd081862852ac50a5235420819409242d30b1850a25c48069a265a6801a01c41622e822461844d01b1c992f80687c6982e54910aabc400772043f88c00654b4c00a0e5ba2e002890c63c268228827be58c2872d907c51c20834c290c18a3368a05e60900ca2f040822bccc0e1055a403252762042074fdca0c50cb309241698e2041fd042891b82b0c2060f38e38805629630a3075e680d669214e3e3012caa4841175e84d1046a11812aaca46183204ee00507ba1c296201106980b105193a5cc981d200491454ac30da010f1ae08013740631d00004305ca0000733a2805e661648341bcc20450b30a688810697b802314a3ce921cc0d42d02d47240f31474c3027619eecf81188f8e323c6075a01e365c7773137a72c29fa7895e84379b0e3fb951c36ddc1beb82cd378043525c09f2bf952f46ef08071fc3ff635f237778d370229c6ecbbebe6ed7e6642366f6176f3a7fca5f6e96f7296bf157676cadd679928b5b38f9910f69f27d5f8a4d3d1c912f87327950cb8c6bf67416abec607c90aa3973d8ef74eff383e6234faab1be37e467f7e0c247f6ee898e1682875362db5335dbddf6c31a569ab54e9d93769ff883ab08a8d118b91d43f5ec7bf7127db7abfb9827dc79bea3f586503f9d20fff127d28fd1ca3edc41dc7cc97c2c09f4cf912944792ab9faa554b4a86061a68f0bfe63412e44646bea05de92fc85a7de7db9e31188707f8835a64f6e3ba6ac5b8ebfe33b8af8d999023f1439628367d0c6a195221f14396a44d6b75749d4201eae931e14dcb2e10166310474675fb58f153138cdb6b6fb529b0efeddefb4375fb6aefb5d785b3bd32cc6a1b5c98fe946127d3fd7ab7ec3bc3aa1635acfd479fa86947f7de7befbc990d2e2c135a68616484e52f67635fa3cf497f7557bc4df0f49346e3199a65cf68d9333371e6bf222af42b38a33fece929fb36e5df387f38f6fd4dcb593ee2a9093108adb5461b5fa6ea4e297dabb2acaa48ce105007faa81fdfc6c6042f6c19718e990026ed6cdbf3e3c76967d3b2aba4b28ab01859b08108b344f73697aac9356832cc33d955057d4929a592beeb9ee8590f923a99f0965d8b51ea4facfcf564dde34fa24f7d8933b5397fecd9137f8252330aa5d78362a27814291d8a01dad388cbf9fe010155203cf9032552f4a9a46c229bc826724acf8532f341d18b3ef2639229e22cd0d81f8dae2a897434f6855536d4017fd5dbc7feabd087c7587f75d39aceb47fb00aa55a89dcf46da5844aecf38954cece0edeb4eca6a20d49db6e94e6bb1b98053f2adf649bef724d9e791aeeb5c76ff115b072fac32793ddeae55996657fbb1aefbad310d6e81aba66dbe38f3f61968d31bc7dbf313621faf8e3a4fdf2a7fef7fb7b47bad8b24a4846f5dd49f4e2e32ff873244792187c17945c3fd951cc4cbc5d2cccb9aeeba29452eb9a3e57a67f5dd7755d9665ed58182db263557fe5b96bbe95b66103feeac4138a65f1a665106e1d1d1cdda6bf0eebecf8f6b2177677f6ad738b9d1ccfc39b96edd8186d88db9b18d9d37f75c67f382fc1f4f4b993def8b7b75b166d599f3fddb608ecb2bfa2287b28fb216b6b96bdbdaeebd22eec56edf433f1badfeb2f7bfb417263d7ea0f76b96e3fbcdf4bf06d6b6233b7aca75996595d62972e996bf9da7a5d6da30b2875826203287655a16f3f888691b5828454a7acb08e38dbb9ed9d9bde5d7f443b1bff7d7b73c5827d63ec462f76545bfbd6d3fc153931e9aa318d556ce6b4693965d921eb33df9b56e464574af5e6dc78fde7f4f70259a0ce71883afe34436aed3b86d94c04bb14814a50c9a1d276a0ee081503fcb90f108d1d7d9cd817e4cf49fe489de851fa0d903f3fe857ab8ad3afc3315be2aad6f710faf5c3080c922a92dadf0ad8dbafd25fead2f067ef5bce74fe746cacba2e4d94b3aba34d8ba436d54377a691fd4d5dde4e4eb5d65afb35887dec83e2951fab3999f6d95c4e4311100c981e860c98be060762d24b1c88e9fd6bc41bccde94ddca4bdb2d7fddf79f8e1dbf7e50bc377b98ddec7abfd7fb755defba48ce1eb2bad3385a89dc4355d71b3d9ca26558014365432b631ced6e432b6178b095c43d4497ecfa18e68e25895b49c5f2f5156696c6dfc470ccc61ec3bece8de9fa7e6928a7d4fa44a20fce1ce74ddbb7b6be045e637c35a6ab43d7f9f0671ff5634d4718c40509680fa5cecf20cb940122e5f31fe265caec21a222ae89fca1c0102475744aeac82aedf7dc00266d7a85942c530648a6c542f7a3eba856bde97b0f8aa345c5b3735b6b71b6cdc9d976d3b2ebcd222cfa0e8a78d82da59f43297efa3350fe70dc9f3ecb50d9cf3c0472d24b5099462960db6666def4309cf457f73dfdf60d98d1a687d9111666fea497c02a75502b68da3b10fca8161c087e07f2612d053564c8fed5307a1d04a2d5e8ddaff9734ef4b0d4a9aaf937ce237eecf40001459d1f55918df10808298c5fa94fe833dfbfca775da55f5c8ae042c49e1f87442e457079b267915b5d8e31613552814dbfd60af557814df557813d047fd2eb3fa81dd312de2118e052041727732b997beaa8efe5520a5ba38f125a2bfdfdf6b1d0a36f037d6af4a27dfa1df4713d7d6bb3fc18f6f13be8436eecafdc411e0c67571fa1577dfc0cea602c75aabf740779aaf9357fdcd657578da315ee64dbcddbf53fe2d88ef9176dd75f7d0a03ecfb8ab8225225e697ce96f988efcf8fe60f196387434d9dcda638e83bfc0972273b48fed4a50fe370ff00d4891f97e24ffd751b092edd80392a9f1f595d58e8357f3dbbdebb2fb72fcebe39fbeeecfbd04b80dee36a9b4d99c6efd94353c61868918d3108ea55911d2058d29e32fbaa7ddc5cfb8b3dcdfe16524a7736f6f52bac6aec87b2afb6b705c06f59c11e33219f655b5dcf8454ffed6c0f8abe594b29a5d4dddd35f6d907492dfba699fe7636fdc135fee0bfd4c24cc80ef601d285ca9a73caf8517a9c310a71c2aededddd7166c09f57e9cf4a0404747a82458716649f69ee37cbde5ffe9c2a9abfd4dea6eb6ffbfb35b9060dd6327ab5ab65d909706b7a9e4cb46e5a6541e4cf24d5964f935465ca94a95ba45160d93ef6f7d29b7d633e5950fd97fa56d8b362d8c2ae6a55f267554d19b140daf32bfbf153a832feb9422985a8953f98a4e5e200891fb69450e290b976717dd79f7cfa36cbd7d72cf74df6dadb2b13d22eedf2781dd92ef616dbaedd58f6f5c8d5b2b77f3d561fbb6c9642d1ce78e2ae1f5f72ee9c007ec88203cd2ba41894b6f555cf18eceed42184103e9c4257fe9ec89db8932ddd0996f9d39a724a6e4ba93f4b3ef6d8755ddcf5f2edcc84a4f4cafa2a3e5137777443767029824b94524cd70594caf17672e4ad79a6653ae5ae6fe5c5393b2998049403276e3bef964d6ffaed31beb2148ab6696b307ad7d34a7bc8331fee9f3fafbd30fa571577974f63956d0352749154b1d839abdcaeb1733bcb72db78b1b86fb2bfd7da6bb32cfbbe70df6cafefb7d033a1cb923f6fb8bb7c1a7386e05029e38b0a0afd59299d4bd38bd8bcdc9f385d010da3870202fee6290575fc973adc45cb6e129654df924f89e694ef50cca5c3132cf214e914f1e33b3440922d9fce4dbf4ef74ca88a2f33d1dd3152ea35fac49f918a20ec0ef4240584b7c3e3e04c20993157aa16dc450a47f33635ffe10db91f1f38ffbd0f8eff727c6efce7f9d8f0f15f6a93f01fd01f798f12508ff2d13dd41f4dbe79541ec0771967d764283e5fc3fee4018c1166cb975c0daacb10cbb6e1aedb6578c5e608cc4a972115b562dc75ff51ee141809fcd5db6558a52607e049c841de4716f2353200fe270b3d4e4efd08f9c6f7641c2f808cfa2e432936978f709fa4ee1e6f6fe4111e47ee795416001553173813a2b12e244319244779030000a1548690077a3d2cea863702576f97e10b6480058d11f8abf8d264eebb0ca3e09ee66d6cb8e7381bee761926e54cc1dfecb20178e872016cba7499009c179adbe51fdb5e81bfd9e5126ac5b8ebbedf9e974a755efc6420df651fbb264339c0d3fc7c8d03bc09f9e7ed4f36e10f90a3bc0700d2d5f0b0cb24d828e3f4f183628c31c6184f32292949fb1a244934c4f8f8a2143d2f38d9bb401e2d5227cb95ec4e64a70279b4d871e6e3cc7f914b0277f9a72607d4edb20f764597078071d1e59eec5f5023f3fc4fde8f93771e95773c8eacf35d16c0b6c947509fa46e1e6f3d5e2e43086b32843b43b8c3c3eab143271f8190c7480c465be7adbc34b9a6e66dd4bc083535b3cb01202133f1307100f149f857c2dfec3200382df876394526ea24e16feadbe51e9c14396e974718d3651e202575e37cd0c3e8e1b88142039b508f7a9ae7dea9a03ebebd910971a8f7501c0ad3649bdce51d9312feaa08b7cb3c1e6254f6c9f931972eefb071464dd6f135b2f73f39e8bbacb3ad4d969b8b3128bba703d3641b32b5cbdeded2c58bd29718268e893a34206335c1dfdc71bbac236b419745e87208d6043cb7cb395b086a72085f23e7fc4f2ec0e3e41c7f23e74765111e47d60f9409f05dceb1b90cc5000678287f88483fc238e9e8e82893f025641f06c84c7ebe8607f2a3a5c02772f44bd857a91c513942bdcd8b40f3dc5b2f13b2d129146d08211a9506f60821e7e402641873e89c6d641f99840ca30e01725cea94701712f28ff7914b781bf9df06d5657d9552b7cbb9ea80bf0a80dbe5d7b2a58b8f4c4206ca2ec665b07bc40f923f36cca872254bd4898f83237b97e879c9aed4651c1b33a2cb37503de8b95db6b19fcb507c7c7e7072cf002e0e6a7b54ced91598f3b95d46d964a75293bd4af42a19e06f76f96673198acfd7644fca5e253b8d8fa692e2fec6e6f43701f93354e213aff245208e4c2327b3e35f2f351379141fcb1f66d4a926f2285be2e003d296a7a29ea8821166694ce1a5ac17766528d80f134e889ec49e524a31aa6d76c01fc678d04257b042ca0b51ca082c44ba1c5ea864a4e3f0822c2ebc07c2d09903936de32f5982e1143938b1bfbba39414fa70337607b168f8ef5f1915c4fef5715f9f659402f0df4761ba05540bdbbfb5305b80c6850cae040474420a2c044d89492bafcca4262fa015b000da3ffe05f9037f85e853450cfa1416b629d1c7faf8275c81572ad00f79cd8b5ed575bd705d4a1ba752de77152e2d0002712a4878bbf4bd9db0c5f8180f49f71ee194c14058941fa720825dd522123dba2fe56cc72943e528c658f557d5917429ef9d4424104fa6e094c147181416bacf0b6b8555b6a29765458b69d9a11069d179a5624aa6a495722c4e2eb6edb2b0edb3b7d9b6592793c5f055ad4bd334ad5a18ce9f3fc9b4ecca6a666536bb19ceb62ccbb2ccd2d6c3fa4b6dfe24ea443762c7d732a49457bbced2d5aa1615d2487fbe67fec6dbf64b6dfb0169f64d883f2e7cd5277bfb37b20d1c8ee66d7297617d5b6766ac9a1a341cde5c309994f0df87d643ed743a65990e7aabeb8e968e8e96e2d1921b19c9997884d5ac565c6b05dab5d628d68575524a5f51ae2cde188f8ee2516675448a4947b5bad157603086611886bab1e930a3a5a4384d3e20a57af294d5ac2e549fbfddc88d6a8862845305555512f6769c28874a49a717c9d94352d7eb2e830d4af287685403e6a287f990b2f43fbc292a7fc6915ffefcd31e3b7a07218ebf6f3f3b8e6cca1e7573e2a287bab9c16167ef4a5fc6ec48b323102612c986a92a33cd859d6938af945856e997bc6a8555b6cd43f2e7e7568c16b6ac9a1f7af531a62f3d87c86da94091c4c0202c9fbe3771a320729bc0ba419c49b5a6c41f0752ab13d1a3bec5b7446f8a11d047dc4044ef6807ccd5ffb0172f4b4a5e941cc90b4e5735aa732324952b55934ac2a95143662643af8c3f85d4a0017620f3514ea267e56ac99c713a207a2c78730758e6d0e03ed4d0e2f5442fce1d60a951190b90e7caf6db4490092bd4f0823fa8e4829c3ef4ff5fce6a42f4cac0df4bcf8464cc9965e01863ec2612d6d34bb8fe8b615bab3fab8a12bc8f5c9f046fe83dbef70b277afed8855595aed14b5082f711ff24d84bf0aff9bd878c1173c1f2adafe40c5275c35bd66412d630849694f2f3f0756537d72a3a05014e10f0e747f15f70ab7a3742637f750355f94a4a5dba402db54a596b4de29bbe53aa5128e8214b13d144d1f34ff544cfdf03d890f9c5b0e5c3f0dd0f03177861cbff70f67cf9f2cadff5f5ad4f6eebb3b6f51f8e6519b176d543d6e70f495165af28f0bd37a386dcecefc38dfd25effd7bfd7529662de6ee1935c4fffa4b0f5dae3fd410b92f6d7da67fd56b7d51b9ed3f5fc2e8535541719b3b16e176d17477f23bc659ab1860df9dd481690499b3aa26c8137fa681e15bb9304cd74b88dcf5bfd63a2bc9559dc6950a70bc4c948e3ccf842b4c9ec0401bfb947b54b06f1b23d0864040de8ed6dfff07bb482995e613f80baf9eb63f99b2c72eec8d0a78e5aa441e992d5fd62c5a556cd2c2209b69ff75d8572630aa7ed1ae4bb0ab2a1c24ed6f2b2f1d117affabfaea11df56ad2c9d84eeaad2a82173573f77a551d517ed4a9aa8c636f08728eac80f6242068e91df754bd004a5c90ae2334e8d023ff6d2eaa21731fb1447c88d5e9cd782f46de5740aa13f67177db069adfe7ca3866c77ecad22387b08c782546afa714e3b5fc87ca1ca55747ab155f96bfcd7c33b495984bac936b9abc10eb05d7f5516d837edb1e7d7d05f0f0e68467fdda95613ceaec5a84bd9337f3ec6b5fde7799ef6f171601830b6d01e422bb6a6e1145ad52c4dd31e4aed09007f807e401ffe9aa601c91f1f03ea646000fde748408e84bbee3d0f2905b4c3401e1b4db0fc48136d0c7270c54a1949fb53fa7120622cd5d002fff5d6d78f5fef95b1871b7ec4aca1f9f3ba3c436168be1cf26c5af353520790528efef75fb73b1b9a69b4faad0aecbbb24c58cbaec5ae8a54c99f52dbb6ec2d8b94dbb66d407b4b6d58fef89498923f15f0b2457eb0e2aed3df7b29280668cb16ec5db4681460ff20e9ef4a385e680cf9c79f6f59b7aa1c8582fc0f921615e3c4b6d9d08a182d56651109817b88481691f38a9842d42e54a99e05384c7221b53dd79e9f702935addf58ef4f5d000442c48958fda0777d1b46ee6e79162fc1dd5d471b46d4a9ae286d1245208417e12cf01e368cac1feac3a969fa23c2b099da1ff6433a1b811afb548a2815c4faaaf5148498fe52d0339dec9fb2b7699e55d70ad999a960952953a68b3a7115020ba10f9a65fb4b27b6bf10b7f24892fa4aac4f808c53d704500d210fa5b9fa2b53c15f3e66c4dad588b52f25c3cb7677f9f43d53c13315dc359e720bf74be812eb2d4705630f3314b09dc1c03d0462ca309c9e72798994164e6ffad44e459f4ca36af4a2ebfa033b03957ddf042e34157d3ea20b81cc3c0ca6e79e9e7ee6e90ba9fe7a9aaf8710d2ba29b5374c600ceb88ecac8361060629dbc3c0bd897bd3b3c069d36f9a85199d653bef299bae7d135054a72e30f884a01c3a60cc5941c41bebadeabcbc04140ab24c19e9310cd6706e8771155777568fd07b58d1670583af84e0b437e2eed6ebbaae58aff40266072f607630da514341b1b0952923b7f5371b71abadb9bd4e6d0c2c25be5bbf7080ba14e7e1bf1dbeac2afb002a239611e99e87c059b763d1726256915f6613e93edfca34c3cc1a328dc8c801998618dba4628819620b104cb144c548ee6049054488913421bc4288a5a32962f4306f589268c0a008b7d86cbde3b0fde368e5555565966559395525bbeaa165d5b7189df5a77f16a4c26e5996cc558e87392bc3ac5b68699f910f87cb84dc5dad2bf3b72324a4da15f2f8756596f541715a9635bfaa2a2d334f4fc86642e49e9047e6af0add29f3778570853c75b31bb66ddb766ddbb6d56db3b66aa373935bdc7ceba12589515828a79c724a09a3124cacc0ee417624ac2884b0a3049a907ad47a208f9d99901f417c4ba9a1f65279d4244621843da7860a42bfb9e1a441023838314e4a679269c54208218410429f16662d66ede4ec09fd5a95fb5b1e71a2ac2aab56abaa2a286755559555ab5511e14c5ab9af555b4eab5955ab56abf20a7ea5616559b55e17d600cfbb989d93e60f0bd19cd13c2177ed866ddbd44429eba729ee13ce39a7432ef037b53cb21ea594525ed100cf23d275d67e73cf39bdf2ceb2e6acaa5a41f841b128494cbab88b5d183666f81ca574469c1c58777777d71046f85083b156021b67430821c4d9fe9002a6d40fd8e3eda43e1d5c08db2bae77c7d66cb14ce796dbdbe9e142a8a263621633995278f372204ffd4c77367794dbca9b6977c7dfdeacbdf6f7b34c639a96f9be7342c8536145afc82b433420a89431b32102a4e2a8f44e164435656648002000000043140000200c08868442c168381c1266557714800b7e8a4280661fc99328885118a48c31c6184200000000006064a6888300b99eb317ce9b79d38f19cad04833b1c8ff42131b0f32e2999964f16c2d046d4001a38a3cc705b6129d10be10723156099b1938d7682629f39bb180e7a4e2d2c460f8679ab9eb21c7e75aa9be2a3f29444e4abc12c4357b7388ca019d6f0536016a4a6b6a2df0c952d5a04727c83bca2fd4a46791d9583fc0bef459748f5aad60cbd08f630ecd1bf3e78deb71fdb9b88a488d7e56a2c31190e808912d857b89b2e5e7d88d13b607671d0055a047d0112ab65471546478f726fce304b44115771db376c2d161300de24a17c947635f8a08372eea69f7d63874235ba36f11928c8102e2d83a0b319f9605352a11ff330506663565ea2b0683e34b8480c03cc22410f2d752dffdc6a6e75f2e6f0acaa709710f641e7ac302d9b58d64e7809009f169525f499a0da11d9b2ebb1ed9804287635a3f1c7fd481be2d9f546e5f1eeed2beb031d6df1e17c534c4397884520f796cefa41de72489ac8634ded1b5de383636fb96fdb0e943039b398741ec865e9bab63873014c78a6c603fdca883ac74969aa6a9d9aa8ecc840eb18fc64f4cf1ca82469952bc2518cb80b12c5570c69b39e85843c18d4e585596eed365c90fe498579799d9993620c0be9121b5367b38a0d0c3cb5acd341f42a2ac1ce50681c68b60529cea113c53de7244aa31abf5f90f9768e2fee773a0046135783a1854059838adfb0205d481ef69461b784496b4b469c571a4a847451729075da4a38519b77ef07792f65f062481d79fcd0e6703ef3f37c09551b96d0539db6e832cb1a875d2e681078783515811b70ad77d8d1c89cf7c22937c662279d179915282dfd73d2a3b7cf2202943bbb2cb2d4b13f2c5c28ea5780ec033a514246f39863c5c889e1318a98d2dafadfde32a76da48dc84f0bcc13cb4493feb4847a22f2efba30b6cc1a396d9d191460f314011d98a13f76eeff5602776c6f393fe2e448e64b5a75daf31342dc435ad5cf831aedcc2d644f924464787187b896bf375023fc83fde3f1ac645db2f41ffbf09793fb3cfa13b42e9ab0613846b824c7fe87e11b8dc976e4e808d1f310cb5cc9e4bd099dc2dd6c06940dc3c1135fe64fd42cc3d414af1711f4c34796904ed35fbdcfa61bfc93bfea10bfce4db3894c6441230c26656b60c249f3234bae73084f2544aa2db933c51a9e337513258dfa1885f5b5bed36ffbbc3a1a7e7016dcbddc085219ad490efb794af754e34e9ad505975b89d5fac7fdd887ab1b4f8c858c755db5901678ca35840a0b4119e2298d90d5393773172fbb46fd5a961e0d688d0cec930db2eca6a999b6e071aff0beb04c9ee8c0c95f3c12e13583607e022c73030038396d0e61a889e38bd82727b4a2abf82ac1534fa47d426f855a50ec8e4e2f12a1be4f82ce814035c0d9b00139bb218e4da797e182b160f42a3f7fb8c20078fba474de297aace375ceb374e32a84ac996179336d731afd90a967f98c835f1e143de1950dd86014171af2ede66eca02362cc1ea2846a090c39b9403360a76b24283074e9a305f78815c42882e18fe63cd3603647af0bcc5c1e49ce8af8cf5e9cc29fb524a9fb6e77d5ad42601d58caeee6a8a032ce33af7fc2af9e3ff3aad83fbeec2a253ae6dd00c5a444f39b125891f9f81be0596e0ca29a5e9e95435912a4390fc43289bf5c651cc768ebcac84453f2e569ce56dca979aa0c914f794878f3a62793b09037c8f0658015a81bdbd83e4578e37efbf969f1f71b770750dbb8f8b92c23d1226c15ce474955c8a92c7717c31513180820ecd1ec0d0ab7877d414dea391fa0aa6571ddb028d2725bdbc5958877aa48b31983b30f7d51d3057e84db622004103688962f0acebc063ea55b806c152345e113a8fd096f542a52b1960f9c9f573a08aa1d73c2656778a9c46df9ef4924c5241a6f9575a5929fa0c09dce942cc689dd8712d33a3dcecd4a6294e70a0b718872d5d055c893ace9e74008cc0ed83dfb78020b32bec9ef40f9312bc424b0cd0772891755d5a5f789cfa31d18a39210624270c0857d85b2d561c35eced9e04186a19499dca5c2f7cee1b4ce2c1aa34269bb43f8872143c18010635beec9acb090f30051de30754d3f0e70bda9b70e090dbf10d02a1c7f87089890d07b41056c2e479760010c25e9d9e62725b9cbd0dce946b56b63a577e44c0c64f7206fdc814cea47594d266ab37e84946bf68585542299070162c63e4509677e0c98a657df302f302e024c32be17f36483ff47a3c53f933550398108b945cc74b75abaa3cbf72c5a99a5a29c1d57a49246667e07d462b05820099f7d848fa7df70dfb4ef5a8f4a5a3dfdeeb72041b424d620f94a2146e79f187527959348c3c09d41d7521253eb3ccdf8b1a7fd8197393eb51e5d3ac04c6f35a66a584b3a33edb06bb365e1d271761049e28a04105ba24588ee70c2501b55507d45dd9361ed1cd26738746092115dbc9e52783e22590543ef18ab2b15ba1038bb0da8329f99b7f505a6ca8c99f0774f1ed00ad4a120a05295abd4408bab8c22a04956d845c58de8fcb3e42d46657d10a96026dee86c581157c78ce6fe1af30ccc2c4209d449ca8ed025b0b2a8828a945d3b900da61609c544e00af4a0bc2fd827862831347c7983c0b6acb92d0a1a6badf0ed93b7fb35a9a54c916bac9767a5bb71088229472fef590d51dcf300154363d3e6f33a833838d8c0c5e05866571441ba315915654d5a51374998c18d2ded47066e692b6ec8aa9c6226f6b9effe8709b402ef81f9251552bc7f7d59498d17df6c8642fa5422ef28569e8909afc4484b1ee3c83149ffc643cf156f24e1662a998da5dbd83b63a15ff86e8dae5e0785f67c39c0daf205cbcbdab1ee3ad37ae23eb915083bcb36e4ab4add7f87fbd8b71946f600a6d4c15037a06bbf43c00b6813888eaf5af34d9372e6578394ba6a64ea6bef3f9acabd656a7ca6f238775e2895965412c414f7b75fc8790ab7a9f3ed5a2c8945523b866653396dcec6bced98392eedef3e3cd05bdec2b655577d1c431e6061be6cf25fa43591aed0a4db74db8fce72deeb19d48a7d12eaf49db8f5f983d23369a8fa23a3231fd638dc21f2d2fe3ec882b6a660085d3bf9810e5573212b061a03d0dd510882336cf1c57474cb50d0b29e912cf67edf09817affeba1cf1349cd885e5bebea78c52b8fabdb94173621213cd04802a45466a12d5c880f21365115fa914a46d68ecbe500aa537b818d82ba52567b1693ff9af1e5e152645a3131b42bbe5bb9eddba2dbcb67c62df50caa35210c1946c439ba983a79b2a947d5481b646ac4e25ffbdf552f94a9a67d78d9012e7c2489e89d861a81362ce9832a7315f1c17cc2154816d4c606d58538f178d0f528d3f70c47c9654b586895304d42c6d77a800d2e0734b0b9d184b89328d207056a4aa52828b35f72b626fe6e626331b166665148dcea3e85f6721e9206d083212db6773841ca4fb34a442cae70e4927d3053187a3761842005ece952c91b224f74399dc3895b2e7cc32079b63a73d256b987a4001df2606a269115481a06b8286947efe218a7940cf896e017c2c8eca100f805dbe6afb6962205fbc03ed798c61f8a42f0d423bf2145f8c70f32b3bae9e46735e195a4327cfd05712b6221138d9cf86a76bae042b4a5960e389bede0d80d5341f6c129fc9318b13308a012c77fc6ad0f0d95853e0a77b262c970e43631ba11465658b176e0e6450d70a08754bbd8b4c17396aa1f0d25ec1fa5d591a37d72fd9eca151a8d4b8801c78ac45912942d8c9e5a4b46f030f055fde15f343d7d1e6fe103e639254b342ecba69e5048ab0d605b88f7d32df24ef3869de4cb0268a0e4fc9b544e651846934d8703235f9d604e4cdfd15e6b4552e15f44265cf4229449ca9430523fd125da087ebbacfce07959863acb9a9f946c4f5b91106167cb1f4aed74661a4d46c48d5da407058b6b02e64568fe1cc45433f51a7a74615a83ca4ff58e4f070796cb4ce4c553b88a59205c1517d1c72e607e47e09a4d009ad335a5bb846d843e41ea5c4f0cb9f1c36de3dad3c67b9fc335a37e9a711222997e0d20c6e13b19f04a08718b8bb8c77da05e25088d777661c588beebaa10ebbf6e49807b008215a6aee5031f8613a160f99f6310140c9b29794b6b8ce91b8d4cff4ade7a970193267470b55853777f6fdd953d74ecff7d8a001f26bca7761041c83f35ce36697f865811ac6b5aca776b035307a75432d9a3b72a17fafe854d44aba7fd5243203faea55ad071e492b27403a554d725bcf3aaa2905dcb9d1bef3cf64685d80fce310de97b92be5bc2c3d55a51d4973fd60e5e9c3600f6cae970c2f58830511fd5ceb40ba50a0e270286e6067a65d21e7638e193afe5b3a99b59f42a9546245ae2dc99773b291b7d85fc537bdc3ccb8c9ce9825ad4f8a18c2eccf386f476d9702e623ba28083251ef712fa083ed3598b4c90182d71612d14465182f8b0fd49048a27a5e091747e47682cd8e6197fe0366e25378ff345d531e34ea3b761aa39b545cab93d7d040c2a1e254e1d9e3a68906140dc237eca1aeba020c6ab7ead9295ba8509164571b5ffb10c1fb6e3aa333140f870f647125b07c5d17a18e801c8aa3d6044ebe3718f2c41daed1568968ca540a3d78733678246244a2b841949669e0d2751322adda0e6a0ab14785bbccd4151e89dc61111695fbd254b1d5a33b146c9742f811e2e30ae5e63b370ac12a2f51aea517b17c23adfd0b20c0bf6911b6dfc23b3709d2f3a59c59f1b6dbf40920d05432013844032d413c07543425033e30ee4551583b62f611913e2e1de56c4cf1f6ed9f5aef7bfe7bbdfff3d3b25de134d3e1bf7e79df8433831ca605975b997e295c38692004043d0c0fda08e9269abd52aad7ae03256eb66053fee125cfabb04131bc56aa00ebe350d23629807ab4e9e93e5afcb42fcb72f5c0c545e2935ef17d650ddca3b1719cc9118fcfd62dfac7664cdfb0dfcf43403b69de86320102014c4fb0391134d6463c8045df4c8f118411a308a2fb4fcb97190a35d6a83c199195ee22dfa342ba317817db3e4c6595828065c4c700e9e3d37fcfc888d7ad85a30108e776347a70386a9281160f82c1faaecabd40d6c02a81b2345c122dc7644cadbc3cf8a23114216312da2e0a3a3274f0d942a73e553cef868a0dab8a4cb1795d54ad5aeea151b603f65af270c2ce2dfba6725056b667f2e2745661415e6a5a26b69037f9527bf9e5da708e688c5be8a6cece7e94ae555095ea2dad49c0f30628ff1c6edc840b1c5a4b3f857b8a573e35de19717efc83796a945825b099d376eac2cb9dcf76a4c687396ad4fe18d260db60a976ab88ef6080b33941433723fb3d94971571a61804115efae603ae575b619e005e72f04722f589b30c64777dcf4d79763fe9c06500464a26aedefd2075f0c007e64fd8b3200c634b369cd22a3dc916e7f2ee4791474a33106c0c8fca1b4d70fa81e42ff989e520362f7b0ea08bc9a0ac1f420e0ed93f06b2a99efaee2893e45452fdb27d1c8df09ae6daf40936a894bd4880d933b9648ddc14084b5a4b3c3845c1b9381b831329ef1445e1b13bf46df20888263197b88666f2c0443e08aa31ef3289e3764efa6ffd91ccfb9abb5e4ceac0a71ff0637368a71e6d315c7260f435dead76b200ee3db34d02c05a8c01a231d4833b4800748787a364938383374a19c602ebffe0e4c8d497e682708440d0c114aa444f93c83e03b2a3ddb3d387319482fc62a35bb93242726aea90882c53aebf01fe8191d93280eb6ca556aa07b20e088b78a880c24bafede68da0b3f9da7e5e91b32f19b32d839d2036f1373512b90e7d20384f1300c8d23835382d70ab7a1b49b048f96c62fce14e5caba34df71d8591580454c4931acc9e1019b6f512848ba03fac040fa15eb0fb372369828e71b5e5763dc6921b32904060ae63f7c2032d783465e2c1ce4d013c10d5c4ca996033c374527560dc0981bf81a2688abda9421d62e30c371a99871544cd46fbb822c2c444b5f10a8096e92f74d12bc56c28eec9fa581c4e97062e0de451bd807edfd68f5b234f880a90b46841b08fc2cc4924204e8eeb1015df476961d99cc607b1cb1271f2c55f1c3d22208306cf99f3bbbdf8c29cf04e3c57cb047346c9273645e07e726be99d0f7206bca2a0ba926f227573628e295b2dbb725d939932429412b5d9868c73579eb1f24e3da71b8a47baa6cff968723b0c330ec95019cf7c1268c658d2975af238653650ca84f80dc5c86969ce1fce802c5f84e63158ce087ac4053b31d11374fccdbcfc6b0a4693293693908683faf26ee7f000ba79551fdcb208adb2be718f16ea802b1845462cadc7be00c8905a4cbdf8b07f2a8b900e0b9807660e760b25fbaf890b772cca97150b3b518616ccb0d02361d86341226fc53a51787348aa1d75771a7de437cca05c38f75608b73c71f1112d81e90b457a3b61544d7a928310091871ba15ce31815084dd0e590bd1d192b1a29bc187623768576eac95178635e9ebe757c92518a368fe143d9bb6920278dc3360568a352359977ccd59112072c3a91857464c4952a885f30ad5cae12a4100173cb1600b552a63dc0883f5422e26cd4ac6bd044d1e63b1ca9c6d1471c60bc40040771e74fb11a4b23f2d4988069c9bd276e7773b437f4f69fdeefae14a5a9924e28a063d97b42fd843e81ae8c34557a988ec6a210719cf8ffdb5a9f9e918d6694e64fccdb915fcf98b62af8b40b79c6cbc2bdaaa6e4fb1c8a957c0efc09c61ba19093b07a1516a96e858fba65a05e7cf16a70f117cb6487704a865c6bf6edd606cb5eb6344be7f72a2ccfe9fae24ec93b1b3e5810146af75e0653b343b2a8897fd398041c9eb9f2f537a96e27446ce9efe98e1bd72439299cfc46d5da6bd520aecb4bbae01212b0c7672a600ea6295f4db58a5b9c363d3ff7349a0317f5986a70e9bc52f0edfadc2a0f61c0596d3c50413f50f56c4e4c51849ef403496a1f22c474d0812a73b586921840095c093351bfd29d4bdaaa840c94052670729b7b40064a28609ce26f3362c4b603d6360be79ec1b67847b69510db70378f9230d845b106f5550753ec23b87c8591766494d8fb0552a5e4a437bc62cea06ad937d72aed82a790a9d03a589ced49829fa30dab9a35e96e6ad6fa1e9f8f9f021fc7ccb921ea6ee43700092038f24a1e337dba370d90b869ff2ae9d307f92d1fb7be35ba88efb60f0bc7b32986fae188ae5c990c747092ac447850645950ff40acf7b93f4210d0090f33b9e946821a1d5c3fa50f20d2e443d8933ba42b6be7d9b8a6d3858467c05e47570f207ffe1546bb581f7fb3e790d838adca144639bbed26a8e629ba878ced081b9aca610b25a2f001626ebc0eef8823620ef356405cb6ef2dda04dcbb9968dfde6a8d82d50ae1b6d153c28bd3d4580ee532e802c3ff26f42013bad61da5c54ab3ba5a6d42ca5e482813c52473c6913d35f3e376ec87015947394d749c4b9c952ec50a00d13668b62656a7cf703b2a5ed0e628dc196e80e35b317e8d1b07edf7cc1f17f6403319c6115b3a28e01c6757dd4509495c6d60b61d83fe3e921ba351caf987b34bbdc5eddadc457f8dc06de9f2a19f8971bb7517f2459166947dcc8d516e5897956f5bb0b02d13686d46bc44459cd770a20d7e7c120ef074212e6a1b6d41d62af94aeb428f4f4659960c88ecabe4ce91cc9744b8caa596e6808e89c9264577dedc235dfc2e66b8ded6c14aac8e166e0a37ecfd4b9b83b12a52256a4322b04359070c7b87ec62bbf0153ae810ff32777f3e6fc552af48fe6da06b8ab2ec8370322dcd5bfced48497122a8462e0d97c7d401267cc8fa43df07e3c35bd7d7db9afe734bae24029ee0f27a69cc7dd5b41dd0904c73dd33898f49ce93ce0985b73cc1db77e66f112ac2db6c3cca9b49dbeb188fbf2c66ce01665839d984c87793e28c1199f2ce136b82f3af6e4de777e1e3600ee06ef1b56497220ecd0edf2ee279fc5bf24ec9dc835c4d55adbac878ad7485e442dc44776bb797ad79ff97aa0b763a72cd57f766af9ff69ebff227ef453661417b9d33c53f39f7265c8db667a99ce3c5bfb46e3df1fc0bf70b88cf2fdb59950ecd9eb1b7d0043be8a7d956d175e6116aed345f9ed2ca638f9d27bf2558aa7d8a7b840ad65f87d4d5c0481553dc9f81ba16ed72fbd7d053a7b5897a6f46d1f94e27a675be71ebd5635f1962c2a6027a97c44fc68488a1c14dc378bd1cc3d1b43757f4ae40b2c9bb5853f0a0efacb75b13c8aa0400672655c46f05012db3faeebfd2e088db1b738af8d0bf1fffeb628fc38a694b0fcb91cc544b7c32a4f60e024dc5540bbfb81024ef48f48392ad571e17da4eb69201c47cf5c37b87df77f9865eabdcb2d44c70049b4faf25d220b5eb80ec617041750e855f4e6687628bcfbb9e2d741d68b61ec99b0101206dbaac3821073092c0e1e00ddc3457048335214471d16b07da708ccd965efd74ae15c5135d172c4d36f9b1be0c47b9698abfe904614cf3a451c92d1ae2b0d5a405c8a86f2ffc54b82689b2b0bc7f06df474055da040295a87235304419a86fc42f93c77d8fa26f1913df8d8885a5ccda66f2a322958d80fea2a472f6a333c8ab66761b5e7d776527224c0185361e0ff97d92a8c89641190a0d6e2bf100e1d733154fefc33f8e0ceb84d06c8d5388c831a512508c03593a29fc360c5332222cb47d3f76395a54c96585b46014d66816d6302c31f03888f08e6fef60e99c347083d686c53e66014b2d7f3aa6a40faa7066cb0941e9fb0fc1e45105d6661cff1df877487dd0405b62e07650c704de170a2c4350780848148270b78d4ee5dbaccfb8a3239655fc7b1f97c5e4d79314af7156063ed6abd8eb567db3d7bc64e0efecb94ee6bd6a8da21c8824d6a8199b6c3d3043b27e8322ccf665126cf77e56be0f99b3e618cc69211fe20144a515b5f5aa9f992b7ffb08b36fd95e7aa3948024d7d424042529062b4fa592370b355b3a743591f9916b06aab3c03760093de1c6d4aa12e17cbded4f4ad9969d1eac0f06d09fb04e4c3868323b3d3b247a144d795a936f5a9fd5ef8e0cdce71d4b68891fe4ae046f192f3a241aaaf4ac6a8c16624679701a439ccd1c58a24fb31045d3f84914bc5aed122851dc2ec9874e6d3c0f0ce4a1a4bc05a9b532161dffb13fe440406735406507259db663d2d1fbed42a564a445eacf62a7cbebe791c0723e718177c0eba5d032e1e7a681ef1293f6f9f9f9fb9e74bbbc24eb88a70576d1a05913d5606564a3214d94198050946bb09dfb8657a872c2274d67b2b9446c74a6e9932d4f91a1ae45108d83d450ee37037e0413f360a6660bfb34fbc11f74b4cb2c08007cb5f64975889cdd83df3af1c046ca98eeee5a6d61757272902b513c50c2660b4522956a22c7ca859b1f2f19563ebcca604d34ca5a279fe6fb14338d2cebaa445b95c36a16132f750a5b38c7119fa504d877dc61f228076e56deb965cd3c1e0a119211cd4046c72f6467375d0697a549ca60617b29d60f5f5492e6d24b1dfc7659ac44e24f69f49758507994ee1cd5c3203c2ef441026c3e04a4e54c4bd04c8b18c8f294d41142f20a1372e27e07c48897ec7b87c69ad28608c46eab274141075611c9d38140c4c60f4567a4a086028eb46c3780ae886344e649a076edea083c1ea3f66a7a9bdb8e21aaeba4947bd3cbc2dde0764b28a744d622873cda3f88b65a454288633935a1addb590eda51d04548d0cfe976f2a8bab00c66f16775034b13ed9e9aa509a3ab4524c5fb58b305782cd345a4eaebd31076fb6fdace4916229def1c7cb8029da8eb939d63f4fad2000152b351edf71249f0b2d17eaa263f137a89ad82c5a94a9a388441bbf20f4f2a40694d54b500853cfb16d1982e2c94ba1e7b2e1c0365cf71c696b4d6c848b5e3240fb7a071f52a9ed934c56d2479fe0abd077eacd60bd4dbf16d451b6842411c9fdd3374184ea5215e4ad16c20da9cff2a005f3036617eeb33b50718bbccb46648ba5e2f6a16914d6f9ad2867f612b81d50cb9e5d63acc04891900a0e311ca91a9ea5d606838622777f96688a41a97c7fd095d36030ea05c5840a13ac48c9a6d45dcea7a1af0349f8981ac4b6e17c616e70d19f8a5e73454c56f498c8f2a29552c826c0066228a5008ad43bcf2395da2980ab23dcd8b49732ffbc7773004e1466c8b189040c3e7f24bcdf8ab8452df50699f1457bd4988ce941aa1e09d2cc8d30c99d8cf6ac6554f2a53f00842131021c14ba6ad314ddd5c912f12d7173401e16f04c0580875b3e2f45851d03f7296ca22ac7a4aefe6e919b5ae5c49f7c0d394b66b17f73ef2ca732b269e4c17324fad68ce4e6d4cf5339f92c9ec33a61afc76a573073b9c661845a32b661e746474c17fa574f194da3a76733f944acb529b7d0255ca7ae62d01b9b7405cf08e6d87f48277b60830e4fc70f893a247a080211ebe3f12e8e3465f4970f8a25adfd4531368b847d81a59200693ab4bf6bba2157ea81f2fa4a4aa8b672282035ff49e7511867a59b150da0cdd51e9ff4f52d4efbfd24b85086ef4994d6f0a495c1493bf36e8bc3a1a818f0cfdee61b623c248884acbfdf6c4500c074121a98e1682b0f7a1b366a72e5ba45101bbe0175e32e8b134bc5ed847435a7d06ce14023d7dcd0bbf2cb716b88404a286476b8419e888ee6beb0df853519b89ca7ff6c0366936caf064b1c5f1b2f8c09457d92ae1a8146142001bc60dfc05023f9127aba0f7a2b8dfe5e64ee53f29c31e3893a12ada442423e190911514cd040f2493563837a0aba541012651739564d2cc57b86a75661aac4a202eda38991f8e126cf74099a4222ed67d22b3e8a06baaac3b294d91379deb6fb5ec77c179b72631cd62460902ac8f34eaff4c40c199c0f6e75e68638724bded50f8aecd1183f4ff6d92455a4009857d2b41778faea65b53a570489eecf07d94b68013c3b296a59ccc39d12e420e02668a4873157e32de3645bfcd77663916e80bb8c92e8751f4a03a071f14efa11c01e42332838c8bd8d3c3aa7f10fa705f2ed537867f7101c6f82257a0b7552da28b4473ce54408706adc18fbbf7049ca5b4b511f4d1bd43438c1d6abb963db66cc378caad73431b1e2de595eda73bcaf5e2ff872fa6313c2bf673621b85ea366e315ca38520d318445b05b7c4585f40dd4beda6ff7847d50b6cc0b575d391bf8f083c291d288568bbccc0da89a001d5038900a4ca35f3978b4dfd4e064cc0945b2532c3e799ce52e36b46ee4cbd6f36b1a1a6da315d56a3b8948e87b6340333117ba62e80db55389517e5eff846210f3b77159c687b3f68bceb817181695fd23fe7470d719566c0c62e5cd69141c97c4f538d56420bda604900f48525179c7d4cd514206515d5722697c14c80674af95f37f6acffa2317ac376533e787db1009c49bb48f6acee3ac2370b2780630aa56862cec984b12d12abff05637521266f7da6ff97781e1c869f7298e320c31c30b296c064aeb5356b6d7d5ffec855bf7eea41e4bf1936b5de845e2975dd16a0dbfd44d16e8354ec76341f35ed6d7f795e4739b9eb7c8a8864d390286deedb7ebf8f97fa790713599f9890a2034044a77dbed0aa84b375589e644650632983e7a4e5d035c56ff29f2ce79181ef32bb67c888c23d85c9c360328cf5126c309aaa97f041f04bdd4c3be3efce04eba510afd55f7e9c2293300cbcf32d1d082dfbb7953b114517b3d2d16fb6f3a4b31295a96fef3606c1468a376fe36ec12cd93771112feb1a81588e040faced0ce8f08f3b3931211b40556d5e4b279831a0c0db6d3f612cb82e252c0487c6a115aa42983a06b41c2e8d05c44b5943163e80b2cfe5e70fbba3aa8633cdf268bc435cc422be60673819c46d75897712e1bf83ae2fe7c282eabc82e3a3588ff984eb3ee7afd448e789758a6f6776c4a27eb335c529d164741b4cd6a2a4c669fb64b7be6a7b83684be167ce376914fbeccbcc322577810241b0aae424b64580d86e1632be5d05d3a6b7ddecf61649b06b3ca4e44b0126fd6d1b87882acc47b88a7f95748efa7480c80c0a2f11a03d19d5e34b9d4aa29e482164df30021f1e272f7972b44aadaf7b9297af02f96a4eaf303a743829c675c4b71d777f6f0f4632914e31edef7a3226fc32af38816dd7e971f5c4a32170517f4941d766176a1014161807efc3a8a23e5e42a1d6eb8b1714835eed4de404eeca1349e3f077e09da66f80edfa9d8b82b15acc897ca200ec1d68948387bfbdc01e44b4e13a768dbb7e3102b7aaf6369f5f280a2d45e14bc35638d994c44c7c71b0006ab9097a1db7ce419150debfe9798ba93364c2dcfb0f909f71855f232360e6be38bc597790cda887e00278f5792fb53cc61773040782e728d0be49021ff68ba4b69f574b9d7d4c6184564d08850dc2788a90d14755538412278b9fc8b340a11ca64ab3edb14d95701c206ae1ee36d5d621e744d4394a99eb0002bc498d67e81faed6dc91c69f8f5089a68c8b01551edd80acf0437a7e2b6936387179b38e1fcc1d4ea94515abe0d3fded7b171ba5a72fea1fe1a1201947383f525cd41639ef787c5bcd22bff0982949d6ea7c152a990b94ba60c4fa0ea054102d1ebcae1d0da2af52b94424e229e2a69ccef43a11ce71ce7f8b19e05eeb1e03438afff407d122c93d430d8d15a5dc3c8d269fe104ffa09d0c7d6a1640ffd7aadcba9e5897d966f91efd580ee2a3757ea53955a5509b3d65bae22210e0c0bf9520f11295a53a4f573197218f5cb167b5cbc71b8ea2a3c3e3103dea21c81f6c0237150b7b75db481321fa39c116886ef957f7b328ae5f74bbddca7b6f5344fd09b1db1c69f820d503f49e6a7cb8810ea6ad87ff290511670a4738b6a0203b9eecdb116d4d80646f747c8d97ba311c0764581fdf98ac28c76210d4593d81b3d23be4a37ddbddee67e5470bacff2761551f00ef5d47aca184cbcecf6296137e0e37df8b38bb9187a6345336572a1cc34096771ae6a8698a68e5d18ae3d965cb178f347f606939b260e2acede0644bbee10189ef89abe5b0d7fca0d4020ee4dc8338d09b4d6e17ed2aa611683e6f5420f1da711cc5f5c9c86423e28253eda9832dd8db6233bd6e4e7c468f6cd7c1c03f8d53889e816f44629373553a1cdab5fdc48851c0d0b5c778784fa7e5c85a3e7e72d91815f6ae51423bb985ba596b1dd28ea32d9a9d344300bf54e75bd76bcc1d3762b57bd9ea6b90afc445764abd8fa4f3adeac6a892ccc91b7ae8b56ef599b0df8bb4e384470be7ca10f866194b55b90d12451406af1d447b14c8762f36b13e5ed937500a9463462e16ee2be628df16d1ff7855a8274010fc8e577c65a7e8cd6f2b66a4a2c848b5b6ef99ca7967ad81ebbb46ac16fffb7b235b008b1f89e20e396955e050c60086021833c3fce2d4e36b95a4d8faa574d76c6fd147a1e04702d3da269938fbc92185de559ee53dd0db0fb96eac950f01b39454317cf454fbc75ebd1d7190f5bdb394bf997386fe177aabb6f60b4d9a5b99d464f8c8b10fadd7fd029483e1562dd22da7874694d392103f92dd7ddbd4d89e804e6133495d48b0a240c97b9978362fcdb18ceeb8f39c64d4bfe4c58e6f7c7b69d73ca406102966e160743cd8be15649d6408e4aef42162eac6fffc0de44425cf5debe7de5534a3154e50e3a6a789d965242217c8b464480a4ac41050e96404913441f9b13611192773423fafdbaf6885252aa3b019bf35f325d3a5ee30295fa524e52ceb100b5df4bdc087e6ee439b2b2186581e0c7049abbd701e89fe00bda5c7c2795d30026b24a464b5e654bdb507e9c9c482a6654e759c998c8206b71f0a9627f59b0344f532792b55cb50f4f796c2b345b33940be328a27e1bccd1298d3ea569848652542a314acd926cc951e4229d1ddc4b2f728c58248f6258b153986ab68417fb008fd6d3a58e3a8d47249d5b055cac118afd30adba1a9e04107d04b5534c5cb77565ae04958ad52a709af8af0cff5ee8b715ce97c08f821627b17537d6008684f31de2a6c09c05655ed87d315a36394669f10dfb07d09f1008fd87721af0aaec924d82c8d246d20ef3f158aea12687d5c5f4d6cc1e4ecfab57b42e610cf870a9433781468f94fe50171b35da3fa1cf93e5a3ab3e8faebddfb1d566becaa841e0980581981fa32c9f8e6db4dd169d66052cb9d4925373727953a7fb8f19b14d0bbe703c93588e3ff35054398b27302b087d03fae6d92bcd29596840ce942a8edab1fcf4be58f3e3db8b52d91b243a8620390ae971908242bf7fbd5360faeb19c70baca3e96f3a8497acc08cf6df4992888edc6c67244a065169c118df4dcc6be1d44068c39e26693fb64f8df61f56c6c079e551f4ba93fe60842be5f61e015a21e43884f6caee37f962d3540c8d0bba43112d012f6d567f98d9fccdf602d123a249270ce2f59eae36b2a1f6bfcfbca9d9f7f44b13f70612366125fd13472b1a63708cd7477e3eea693d7e4eab06f3b971e2e519b2220189c406680668f9e4be10558ff819b58bc65fdc7587de86440f1623c3bc5baee3efed42207283b67a2e2f0f4f705de34ffdcff4fc5903d9aa358c3af4ded11743fbe071db7bd98bb9ce40f9d18300be2af0bc2341437e4b240728bfc42d66fea9e9ca77024c2bb671dd142047885293192ff78f48fa582763f3428cab6d6fe9770e90833b1480c914f88d0d77ed73aa3cabd85e101a9d2e8f109ef134893b4c840c15c06298c97d590831b28be4cf20710f89d3bbb012ac1459616d50b2b4c221b7f363283ddaecc9690e66a419c52fd5e84c228681300844ba7925655bf98d010006feb986361864ac1cbedc63a4139ad3a031f8181a0981e6a182dc7ab6cff79496b8aa4aaecb2b209f2ade21197413dbe7c7fb9a5eff83807657af64416300935704677b44408a6415d523fd027dcdee8a19bf969c0cebb8a776348c7bb627022a84d873bda054c5a23c1ecf3224ab2719fbb9740e6fda9626cf229d4ee323809d66c30e1fc9a3bb683c0494ef7f95fb2b060258a7218056d589be600bd8fe28a151581751915c782674e6ffb623294023b30bfe1d5f9ed3ea15c0d94fe2527148a4b1fc5458522480363b82d0aa9334a239eaebffa5eee83c0175c09fadf69180ebbda91cfb6d3c67effd3a7db74d6f53fac42699e8ed4024b1e85e3ec528ce53c772d9e483b249c64757696a3a389ab7562028a671ec60ec8329305ec4a2456d9eed294f0146aece6a59b79713c3db73ea49bcf0722ff33eb034147ffc5a175387e5032a4451d9947ed8652fc01f44e7f967de58c7c94f525712e92286d57397a9b19f63419089c836b68ae9e0004c2eda55dd4c82c4859d3ece3e6ade01a78b614ac3fa4ce12fefb52a0f552221b57a08184f021f71456ce7cb3371d6d94cb69e04f2ade483c7091360807caeff8e204a482e4181d2011410c78ebbeff126703844f5ad32e4aeca8b4eb4e3f305b8106bda8bc873773b81e7941168834604a42571596ea245852fab2bb293819247f52353bd9ab2450510f710eb540cfee3b50952eac8f0ccd3ded4089d4e2603691e8658832932946beb7c4a02d4db161cb8752858a2ef236c78f807a5cebc38b05435b6b3c5616304469a9c9fd245612bdd066308232e09a94485708497472ef2498e0e875d6707a68e35ab7f4a22633cd4b8f69f1128ffdca5c0624375e6e8003c0191e48d08f0cb659b0d08f7ab0950aa1e20c897c561a85630a3e2b18f8d37bb1f2a756ff8c927198d2d24584099fbbdaabfaac20274306087bc629269af20666dd7f3524c1bdfb8a1e49541d1df30b53459ce64e6cff92050837fd4fd93cab47c80e3b431b941267eb4cec6720534528d3628a6360f53144610fc4aed0fe1f931a7ecc9a39c2cb7ca603651d14c1c2aca9bf0c61069486d708ae2882f931f39ce619a5e70cc87e6368cf38ed97131c1145c8492ddef5676bd56a0cf659716638c7e7e8df1f1ea5047a45f8e5bb1b6045085504f13f518d410c7892e1a36909c9034fbaf63db1e0896337418c11c686d71d142bf4b445ceea2daaa91fc95fa69610f6a1950f02ac5db4582b9e472fc78f5eb896880b4a74e762342b0145927d6b5f9a6e43c6683226958b02e0fbbec4f0f3c96353da961fcfd1c39f9c368c2b0cc4797cca794037f9bc06da7db7bac34d203a9c06788649db16d1bff2077ecc6220bca84de9b2c183159f0ee2b5280ba525bfff3df986157965284d1890b3287ddbc664736a5ca7eb25e2afee50a940fb7e3a882586f6677914fa48ed865154753c7c524d63b785d374d4f53bac436b9c1760f55723be6d3f9d46604cdf32bf76160427b338587d8c0f46e06d367530f2ab4bf0b2e69b446f177bc75da7185d47f5dcf6ddee7350275e65fe0d8470bc5623a3ad6a0d0902bc21b06dd8e2a3abf905cd410de32925bc716a3d86267c4c04115a21a0d20dbaa7d3e96df04d8c7598f0e8fa15d2b742657e1b6fcd4fe14d2fc39f9aa6219ded46e4d3fd876e02e4aa7e41f148cb7181b6168123b44401b1188c7ebe7271d44ecf7c42c8b6eb529970e9557c202b4a553411367ddc656f85a06cb8214a4b20f7e934128af6dba4fcb8c23dd2a5bb15385262aee30602d13390e5f7af58d0bdb01366b3675cdde503164b9a75975b1d96addf1bf02bf2be712c259b7f3c498e77cf011663fe9e65bc98eed0a458490d2e621fe1cd87008a190b09c2f50e68e5167de078331734608aa5a3efe994d0b832370f99bf3e3a67a894707f98a2faec0dd8cd48a24d98f059a23774f793bd33bb9f79972a0059bb340a6489185a0db6c74e76dfc0e08e0621e56143b0e0f1a6c2298c1d76a3114510528f2e08d901b68d07772067170a05718fde10d2476743bc06d8e34a317ab2f4bfa927a1507e1ea18ac89de1e33d2c3f6da054d2c3ffe0291dda8851f1019d864128ced7bada9239d9f0afcd9b753e2c442eca4bd223bdcc490b42dee88b6f63edf4c94a4505bf8da54c080402746b217832c831e3d587e0256be3a82a3a9c2906f22298e1e395d5cb4131c5ba91657135918464e1e18386f3cac20591d5f9b8d1f0e89904fd163f3fcb631a1cd77bc082e6599a3f2a4f4c8e26954c7600a3c504fc05f7d167290b1774faaf86c05394b553805b7c4d70865c09230a43aafecfb1272fd4284419521b5319b03a598629a005e26c8fae3a9eeea510c3d761b0f53cfe1b4061d42431f48c474b70475b4abff4b99820163596fb38a4d8af197ba6832b606c1c939608cf1db118e3cea5670e4d1e0fb2471cdae58a626f4038a684686c68ae64a9f2bd74759f0f6f91ae0add030864421f0afc8def56f58f3131ebb02e99bd18327ceb0c3e7ca22c08296a5318ba31a0868a3e80bd4ef9ef8f5a63f2951efc71bce656b1f891b766f0adf619698aff31d5d11f02ce4e93022296c7abba33da3e83aecd24d791d24642ce0f88fb6e8c8286ffb887d22452b4fc262d5a6e915c72cd94c424cc98771194ba74587d8984f42dd0f5d2cc1a7e4b32d7ab0893de63ba3a20e54b266352b800dc2de80fbdf33598a68cb54ab9f38722c78ae0b425ea6ff031fd51e7fd0b27dab233ebe41e1b892f606ceabe49ba1cbc6edc9d2fb98f7b57e78297d3d6e086af4466bedacb4ca09776a12ec2b6949265a49bd4b6ddce37d9bb20aaf44b7e1284f9c4f5276ff8aacb3453fc2d2ba51c9a8e0c50e4fdc278ea5d839140e527de30726e8089e3c0c5c9f7d4b3887ecc5618b53da00b078a5e2bcb0c50884356eeb5594a1c595c8f74fcce6632446fab8dbd306c6d2aa59f99a01a35126919bcae6cd7a825a2cda0b3c2e542f41155747998f13e54c38f75d9e281205c4796e2ed31a08154c99653bafaf9d7502c69dbd0d3c3a740f3ddcd3b3e5f2786ce0c42f10d8e951c2d6e255c02157a94093cf4c4619b6651c44f3046cd0a2bd31ce0bd40f8cb2151dab3e13ff7acf1d2c3b82198abfbb861422461d3066cafbfe77cc489a52d3981f62a5c766ff6c2e29f3349c48c1c0ce748e2255e85d70c4161cad2c8acd3528889158ca05248b5e30d933badb774cc585c0a187a4b5424c9b15a322e0c5a6320ddd445eab8881fc7e34a7d751bf20a0a4f8fa6c05b55ac0e7eba2cfea298f5b3939383c24ead1a2c83bb5346958a5fce57c0e299b4fa4fa5601c06b96cba86185dd0bc115e215c7c7c9fc1d78d242f5cba099283619e7cf8aff8ee5f82ddcbbca6d33b869528fa4e3e598ca5d14b6251ae4ee0dfdab080d825abd6d08b91c28cc34cad010a3e6867c87c0cd14d00f2546d75e027765f88ac9e3dbde2858920ec6c6575ea103006f19955c3ac3cb5a8d41d33b8475bf17f05853d1b8c09a1b25784a66307fe7289388ab84bc438a46262f1aece39e3ca57bb1b2abf550d063334a1546812ea9d6c8a205e0e45b6ed2f6e115819a419c9578b1f2d1afe888c4b79b666937ec56d2b3144bd26adf100e41172bdaa1eedb2df12ad8006a66659574c006c344702e24b54fe09a3fd7d2a8a87ee3c55161467c80e26554455d2a0f0e4a4910c4bdecca2485707658734a6fd64483de1a901caa2984be1d108d66a9b5d04f6c2326b6cf8511ffd7a049959e3383604068a3e375f950850e356f5d2573e5f77a4ba2c04d04ea1b20eda36b88ea044f3706abbd37840b5f3787ef14094179129b54c283393fac80db3fd317a2b8f553f6459a7419d8b158589f04c5c70260255a1425be6a2de5dacd88961fd5ce8f49f278627b4831eeb3a6d735688b7a34124f935e03c60714db3ae3fcfdad8c8dc6ba4ac3cb206fbb7c4cd9310bfc0786f1b5e815b5360c49ee7e8d26f933823f05675343d7b9d53e90602b2aac9034a94c55c2e3210a6a9b6344e6d2ee78dc77e31fe38ce639f862654488cf0bb548eb32fc4be9631583c6440edc3327843cd80c96d27cca7cce4094cb60e3a701f845b02e9c91fd189dd9ea29c9e1e832d15084b59fb9bb9b213a02b70cd81c4328748b9a8893cd0bb1f845845ee25b9c1854f0166512cad266bf874687e298b8f42785c2ea1014d25e3b6565a9116941be22b8cf919327970bd956cdcd3dfd226c80e573079116ca1b223adca1264ab3962ddb96d0693942c0f33dedb2c9a662b9e3d0577c2f5b220892cf439be7c91b9fc89c270bd4f781bda9c1b97a8d5e650afa681abd0bbbd8c4c49641c0912a1a558a51243ff8a13fd7a1e7d0090ecca7eca19726b082de1cbf65a747b14a77889e1e998d769fa068f6341dfc433f85a41a086898f67007a9579ba3c29b5a899892221078faae6fcea923cf067a7d4484c1e2a412fd7ca898cb1eac519c3e00cbd8721b4ebb99dee40857a36c4db9ca470f830d13b5893788356ad0da70be61b0cee21197c6e74555fb5dfda90320a4284ab13daf28b1517552f50773421aaea469b2233b54bb2e7a78f526cfcc56c4d6040394b9ff8fdd1640d3b2bdfa797e66c22d2b29a155a2c25037ca0961dde875ee5f547602c66c609e8f6e53138cf986d80c78d0a5e8117ac743617797dd99970920daf81ab550f6e0a4f1caa0fbe1ac3f52733169a8c3a4bb8d684958a8c5029be4e821443a8f4145a04993ac4e20948642a2f35b6bd54d477f704a8ff3c7417b142b2b2e8591a6c0cec5c2de996ccb2c042d81e137e5b8c945e4cc536e678b11cd5c32be80e86d2f1ef04c897dca657ab54e4e4defdc425742c0dfef9383cb34c07b4ee36c5bdbeea8b84b0d25f58a3593b61d9a80eac846d89e50d9518ceec09ebfe11ac102547149125790c512d72ad759a36de382e7843f62758ea980317358daccb191184678632b5b5f1bac28e31ba1ac35605bdecbd9940ef1c7f252e73736057c43dc3cf543f284a4252f5fec770561443c5da8fe24e2481dca7fd0d38770cdc8299ea63a3066033626d8ad96b5393541a5b873aab6b5d53f8e911d02469ffa36e8c19df658716d0bf2500f3513811b7613eeb49488d02bb490858e2e017b17c4156be46083bb2b4e77d57cd1a716d0c249cc14ee368cc830c5698020ba66d958a59d0c1ace285f2072852158d12a856e9f31df085ba114c9a721e81447a0e2b93744e94117352b29283f8b541a1bd92f38221b339b3cefe0855819315b104d4cce7cc5881ba176991c26f5b3fb845416b30e7a3b2bdc139da18904c0161c42ee339cddaed9e88933bbf4c101925da4cad0ff333ee312e0decd57242d5f2e6655aa4b6afbe36b2ac9914e7bec2dbe0f8cc107113b5576f3c8a4ff7431110e59b26352e81c378118fbd9f70c1da569b62c64c8c1fe47da2deb45d10192a234d5089fc44406ad98596d915e87864573f2ff3f8484888c8fc5bda034b998a2b71450891b70c2257aff1a81f5ccc61aed5099702ec7b60f12985228763492c18322534ab3afb11105febb0a3f394a5b1e19540ec401127a76b16707273e39e80888231e373ec35a71c711626beb21d2bb07e413926454ad3d4cd8dc9381fff122a73fdb05d54b0b02e4aacf22321e2ff19a7e6bb9015f6293708a953d7c16b245a55e17c946cf08476fe4a0899f6dab3c14f7a6b284cea90375b9f3b7724dc781498297a398cbe274eebb29077002e863af2cba0c82e31562ac05ad5dc2c86331251ed000a1c830984e3c777df04c6dc178ad935e7683a4ad43294d01f6edb9e1797fa15c9191f88f6185992dec6ba7ff961be0c6400014790b17d50850406bcb019b0d0eb628f40a3b4366d68d7fb4d0cc4aa706bfc3c8f4030915b645af3957f1b469189de2cecb86f5236e225db0696937b7d3d56216548358530a994fa7fdf2276ecbebdcc42493b4fcd2fa5c71d9d6f166aa0b225b37e8031f67da4fc222164e2ba52deba42aba3566fe4a6105214376d70d1751f284ca131d213cd879792fd7ff1f2e9b1aa9f896b8924ef7a8e45dcd8fd97b9e92032850cbc3ff76d330dc40b45d46bb3543bf69f051c598e303b568a0e1e53a2c5542e8ca32f4336011e36a9805ea5fd446744a4e5ea5f55bb7a773899e43ea13aaedc9b53bc1a1073c3fa01dd01da8830228726146c8de594f386a4c920009602807bce027bbab820c95335269406bf82e703fac04638089b38fb446ea734d1d178fde7f1c4e940d2b52a8e68145445cc38fd55968e9fa3d8feb9b676d080750fa7b698947971088f12aad99ddcf41f1a5c93ab9ac679edfe8850c6ea425ac39c72ce2b5b814bb3adfb2f347c3e54fe9adccb4411f083338eddfde64ba2012d45a5058ff1255163dd71e4fa4ae4da46faaba14297ea9efd2e6baa41a1edb9508e3b67e3bc6e8975c0a29a2fb28fba630cad14773154d2b1abba50cbf7ea2108d8e0a8ed1593cb19c506dcb42ee260114e6bdf8821146933cf7f5e3272b13dafda40c0169a98218d85eb79672bb1b2e1cd0853262e944ebd01d21602514a05e342248d4b08e22eb43f8546b4dc430cf8a8450393ecb1a31b9d0dd8a2a61da570f94897f5beba7a462c9f5367805e043f235782e7e537c70eb4531f3d3c3f1a39be4fdaed6ead26b1ed761e539c2230655b14eebc7541b234a14370994e7d6c78af4d41ba467807ce2218c4d82fc1087a332d35d99b1176ef3696835e2e40cb4c6b7ebe60edb414cc331e8be095a3ded7e6bf81c5d0dcedda76d04c2aa7a1a0688db4fa6aa98f3c45d61210d974c0046fcb5d11904094c6700b73d1c48cc20eef16ca8dbbc0181e88d532d18ce1a2f74b5296c1c58ce32491535290fe453d41413d9449d0cc5fcaa79b88d8423569cccfbafa3f502d44b056b689911612580699422ccc95022fd7ab5919c285284bfecbff3a04e50b7614d971b542b4c4dff36a5de5de251090899c8a99b8b2ae10121dc2224a5ae9e0e84338545802c060681e0ce5893465ee1d2f38a883f85865d4b43c2a240dde6857ed476803c60dbf578d8dd1fd2f32172a9d02b3f94c95ae5f2cdf2b065452615b8d343d91a915516b930730a58147428dfa48064e4a99fe91d550bdd03812a92333e4b3a78649d1f69b484fcca9a5371c6367682e864194a4ca01d90eb79ceb9a35e34e9a58adbc528268d2e1580fc197a89b6b03086588fd187cc073898f437bbc669cb128e7b7cdfff8544cf517f2b833cbe1233a9aedc78a7b9f446d3530d1decceb6e3c1e8f5d6419cf025d289d75badd0f3e18987558f50b526cafbaf35a6d913aea65b16db180a0cde4c0ba6b463730267efd591483f515730fdd8c224950870f1049d3a0e0f1a4c4d2efc3f125466c1b318c394d0f134d919c289fb21801438fb85ee4eac5a561d20cddb2c176733a4b502370d1ea802202948f44349da347a7280f466c96c5242756b710a85d2e88f0251ef70031e3e85342a0a960badb1a693dedda6da76e02d2c0993235a9367a14e38902903663f6b3bc7033108de9c170f68418c40a3f3b9c90254f7f4372858715776d3905f7e2cc4db9dc83f2c9242f4d73e5cca68273ea8a5e9048cfb50091944f7987974b0d8d9a89fa6c8e81456c4f5e1240e889f36a26f526b753ff549a7b483c486407d719eee4855cf8e3d6da9b7c4ad92e2cac7612ef1ff41f5264711a8a797d6d424921319638aa1652a77a4c109a607182f9a0b22b2baff5bde75c20b990697cd60068bedf5463181ca2f820fba50599e12eaa09f97cea7f7768f1526c4dd39c5158167182c1fe9b82373865a29ae35e1d76956ba68ee21428da18121c268ddc9d38a2364d695a13250d139ac47f5619fb8afcf04fda0ad034cd5971e1d06038e18f431e4c07c3953f792d40e26c10cdfa523be712bbb263cf089c353df708a60d1e13ca5ad964ddc07e979b15b208471676a0bccce2238b2d5e6710a175d31eec4688a80c66056ff03fcd10fc64244551556fc2059a7c5058d4124fd39a2cb493a13309f1e49d3200f6e0436e0fca00fab147443b7fde8158bff75a24eb7c0acfb4cd047acbab1735b61a0eb6d61fd81f9e606a0cbf94a624f30649adacf1c742fafc048c25c8e1c08543b105bd7f576b6d38834673d34abd69007f76c311c4e902bf80464f914ae5acea4a4fdf20c1a67a41e6153e3c87ce422ad85c3595663c108bbac3323f791d275387bcfab21666c357078436d9a9f9ed2208320f0cb6322c32125ea1673579a3eaa76a8f0e726f9bf2c0bea7abf25aeef491fe22e674ecbce9a7831453771a1614cb67187d419a1ecbf8ffb5c108b085d29867d7e9846d4eb6653d4d99dffe46352533ea85e793fd39386e312ce8fb5cfda468903db37e52c3f3281d889acd0f2df8afcd19bc29b4d8aec5f156941432d679804700c38d9c07941fd17d5b43139f192effe95247eba61647b77caac4fa21584ef124b0bc24dbcac1adb18bbbe264dabaf339650dfd09f5c0f647915c15be98b165a8007e345274b0ae5a72883141e56722762750415c47d6f36ce0b0da24ceb7274ca6e1be5ce260322b2a698ba737bf7050fbebabf344a09f1cbdce722e7f566af567dccb030fcd51c9f667ce744f900b22ff84fbd3e87dac73e0035517eb2668a14726758cbd9710c944b9d51502442be1db150591dbe1b078e3d7dc020030b32feeb27c281600c928b3a36fb04ed2d077d4dab56e97e9c2707a14553b158d1692640ee8345c3fb2fea77d25e4a10ff8c2cf10df133e888d6e9f23f14d0aaa2bb7731cd578bc5bf541232736022dd9d0c7530b13059465556cdd0e5a4fcbf2bb92021e21ce9f4da86dc3a93f3eaca39dec791e11a7e6ca4f37594f36b1619221e90b7df84ddc509b920a610b61095788677c95f09b4867f988e7e3b10405f19ec6f21aa120c26cba98f05faa090a50d14288d5c6542fedc914db46f093dd0df6c61bdcfc5dea94ec72e647af7951e8e884701024296417074d71daf1f269bb7f6f077f76a3bd82f272c6849719cf20ef8b0bf9bbf56f7ce92ca2c17f0a217082387668bcfb0cf272312155d8a28a45d3fc9edd1e733fdfe1168a96657cce44b4f891be357f75dc98f826b4d4590925efaac589ded1edde8a25c4021928b612cbfd7c1bf46a7ac8f8813818112eee90017cd8a2d46436b6ff39e169a8869f69773f653ecc2032f57f0725745c9b986ee452a7f064284628f32599d3a88c429bd34edd4a489b5334f1f4dcfea84badfdf5311ed0cfb48d2bf4a9535b3c4a5b648e8085896783845bcd0f53bb3eee625082e383883a4d0ea9b3912c088eebde91def124e4cc76f808787156a62fd041cccd82c79c2d1ba2401661d22787125542e19655782b635b1a6f99cf2503d7f5fda5ea6e2a73b6bd5d291fd5e916418aa11fa78c2c68cb6036805224e562df0ac5ea32d3972450f5bddde9f68b7087328f846fb8b6f81b2ffc41fa3e1ff6e3e52a2ba4fc56eb8904b832a4dd51a31799e4aed56acde29f080e65f6388dafc04e0929ef018234fe9183c41b0d41694070ee547e18e77758a574b98518e1b5fc037d11a307ffc2af06c03dd84d68cafd7129c1dc855b0d829fc163d15bfa82fb13a929e3223e52b0a8b46e29e0a57618064d62d5bb301258ff190132728490fbb4aa5a45e741eead75352ad2bce7dcce531e20b9e5cd2c3390f1d2517139fff5d6b422e383ce9457571c8a1732fc160e02aa97816230adae105acac57345bb50959dc3f1635194c467068c4c05d4aee649594727181f8d8492e73862f5cd477f5e1823532ea548c301e85d372a72c968620546494e902e25d7922ba2029b7177cb8296b58e8dfcd16662e0d878c5b33c769df460822a6dc6e9a63612c2d439aee9bcb48bd332f99d1df7314a01f25e35cde0d85e89150e2039b0ad69fda9642c5095cc09f7d8ed98bd01caaac4bdbdb18e4c8deb0ad1b632198053546057cacdeee19b503e455d424c111852c65b1cd87dc726b9c5e6218ce5340d446150fd3e2317479120f978ee9bf60420033c040dc3d667e92885c6ddf33763c4dd15164c7803158194ce2194e88e94be3548225ddc1bf29625cc0eaf498d97ea822cf1dd7e31e67ba4d51a94dc327d85c4cfbf17340b8d99b73248d3c3cdc82442b338271a0fa01897b4489cc5a2defc5b8bcc00842c9cb252a60a03588e1294016b3da55fe866df3509cc94dccf0a410ce99e40afa883971bef29944c619217975196ac4a78166343d899bc0e76f87842695320178999c0ebd8a241f39fefafc583f2255973ce4c27776c36dd1bd7d78d1105686950561e9dca5d172ef96908c6ad7ec6f563fe314eead35309ccc54f983a0b06aa39f68ff588a982c3e1b23b03d4a7732a8324e2ee50ff43f98b3158373e9b470794c9b9bc1704340c05ed490fd03050e0a1f91a2d4831d4db04ae16db5b0117f6e5d81a463f52230ff8bf52e6797281089b4015a381fcdf019783c291b55965fee711f1437089a28d338722e070e8e3e71909b1196ace829e45fad7365dd8270f4d4e6a327725a1635b33b8c4a6734da08322cd7397cc6749342883c7ff136f0932286e41a5120fb12c2d1d18b23500c608bda0029e41bc0d6a038452a12d34641c28c6d42193ba12bebea464eb1fc5a00ba6df921f415ada821f2c65d87a254dda1f4a0fb3c9448e3e8fc4fa2e8f39ad8d20a91f7bb65f7c4ef62417feb761913fd68860b20978da8e4133a3ceb95e2388ad1a5bd10388a795d9ae8ed3cb979763f42b912a411cbaf22842607bd27417fb7a200e9f61133d1b4402183267f99bc0369f42580d9e90819d762e5d5b5ad0182cc1acd4f243f5fa1de20bcb921d5845667c453ad3649be0316e54d17adc98bea1bd4fc46a303c2ad18d1a81f721512be64fbadd6ae367c52d6c91f663cbc41ff79aef786ca552ba820e01280617a83059db9430f2cf0e9550dbc890f0af1309cead5e0f209b0a329b5f315a0c8df0408780d40f1c876dd6d7d973ad67818a0734da102ac34aea624e3bd6a54815e895cfe6f32a9f460d07b186c59cbe7b0ffa7b91aad31ba977733b4f2fc3bdb758fcb9c31eda20f69c346368bf1713100dad1932d0cbea5cd8ec141e68b5dd5e8c5d1205eb830dc4a78fabc0b80ab1698ce5fbc7e96abbb2a629b74db6488ff4559050c79b54da564e5305e21b10f799cf54b5e347b432ac60021ba63e53d0ada9e384dc2cac71afc203e2f180773c5a510030765143a7319a2bcd86513238227c10ab23ad11fa8f5628e27a555d548309017f61a685ba17ea7f5add012607a1e9ba3ce8f4999a6f12526628f7ae8ce0e709867e7c550d026ba9728a9d71a31cc110cc202d9dd4a61f091cb7852730fcb24b491e079198a4913b26c2b0f32deba055cbaba8b184b8f4f5a90900e8942e464ae1e00b52ac29f3e40b7704d9d074ed8dc368e08d46954a53ce64e0f3d99daeecf4af88acbfccb9a7441958494d18cd0e3f3f2bb704815b1c595937852a7a26c058665297d195f41b1cf3fa17a3e7f66213741450116e043025b6a56c1fb837c641b00cfc259b17f47b367be1fb6949582a0a0f8631f2bb1fa63f3b6f089b3fae8acf289451ec8bc2f7c832b5c29e415efe905d3aa3527b5761b4473b480e00e244d990100e3e88632491ee5d7bbdfcd69adc481a15098e42cf36694f5efe0882b005c5a41903f0f7f905296c1d3787e00282f164c2aaab966a788770263f095adfb748fc416d63043e45fe3aebf159352364de4c8e6275039b1d6a2e124280a03f5e6d26529d855f7aec10f8ce40afa49054606028dc465c9af853b3145dd61d875a0958a521a18a55f6d286e60d160b83f2cdc27b4235e650714ad9c7d00e0c347e8071a1927b880596e745354b28e82ffacfffc3a59a006e236586cbc74f1fe1d3cbece560e7ed8fd1fbf98f0313d3c1c0d9d34115e38d07e831a8f87f01b695cfa39ec8c3ca4908de6abad71b9e3b9c9c24e05358589708d413934ab1bac654ed9e05c96f3ee89b8070c022d6d61a6f7c55592e8c7565323c1bb0fc3e30781b485090d0757decc9ac2b3d09a1894aa213b74d18b588cf2f935528e8053a94f940fed7a03042a109eb702513fd9b57d467c1a27f27d9586d09c337e34fff214cd8cdc6449dc220d581ae25e2990d8e407a66026338b64a1842d57c292d466e305ecbb87580584136b28b3b8b95f573e723498e2a4b4313e0fc3754fc9b31bdbe7e1237f30aba8b6c72b66f3cd4bcbe2e01ed602c88bf20da00410fee28c37def869f5d06563cb232bd8d245f06db57deed11d1f59849f6b2ec8cb075e4b9c76c48b8ed47a1818884d306f2734aa8389c5cd28fa0dde97c13cec3c18cfad30cccb11ed9e213c79b95124ff1297b308cde9ab4ca097a0fad72e480b95d06784e572752ec1d31e0297326dad5725a8c0de32ccb4ba5d6f2af6f0e0aad26e0df52a25eb01b054c8e62e68081bb606633821f73d84c2d02df1dbbe98a22d453113448873f34e875d329e502a743acdd0e6f3f492f5874dab25d3c9a13b9237ffcaafbed1e071443c3b9eaee983586663964538018b2e12053a147584fb5fdbf5e51bea540c912f75cc332acb2884c1a3cd192b5026abe19e01724d8c9429b6450c14f4dbe59556c33d4e324345c14af86cf84c17bc26d1971752687f1f535065cdca38b7ca3a9b9ff6986b4f4335f0d1bdcaf6bba96482bb56384b727f5ea82b01ab96f86ce556012c03f06e4fac0e551a417dd43e9488869d55929df97404c29da98ac4c1d4952b0b25294a3ad89faad5438026399620ce36103497885a595b3bd4a0d526a04480dddcb233f07464ccd0b1e362a01365516deecde5ee9e28b329e2179504515b1930b6107a437a3d65a866f206708c879d88682c74b673f2f1dd99d24908c68604ffd81056a82a2b315b8abdc828a735b3e5a6e3dfe66e1917a628017a0f2856fe3002574b3c5d46d5f5b48a971a9063f1ae592d4f456f7411544c103d578b3d82be3a40c90fabead4c326b2e359ef86d07bcb7fa31ffa43b6bc96dc750aa05c4e7b3b4a4448457d806f9c8df1a5b0f53833425ae384e48bf565ebb45d119414456350dc8bf033dcc31663b2e0fdf523d8406bafa2010b2002b82823f15af74a3ad7c4c3e87fa4e03b63ba54465d5af2ee74988cbb32ee29365ff2083e21d85da37efc84024e6b51b541f8103a3f4eab92172f527d12360c74691acd3e77f1106849b51ff7f19a932900b531201875b719acc448b6b792741020ab055262581e78213a028d13c3d901123aa2c8ab098271374096ce0cd3ce108ee55f5e145c1f2a60157851359b7e5308ef576f08e3e9227233e868220ccfdf6ede96b6344f3541a141d1044791d8f08c30773a50df496cd3c4ef93e014870475091b88e36373e984e89994c5641430ba57bd7553582bc42ab21b88e179354b733c2e6ccac454b283ef2f350e02b0cd887fcb8bd9e8cdc70ccbe8024598fc03ead9a6019e866a41590211ea6a1efedbb79433e6020d83d6f690624e7ed401d6e90384a1e85d993cea9f83c199e16e462be0f383150186cb789dbe08f7999985d028b0b328708fb49bac9309f99266a1977b450abf80e5e59990f0690ebe02916cb5b2817982e40bb403afa0cba3a58f81ec7827f61484fdcf27d1169e597f2252c2188ddb984c8f4f0e8514f1fd90aff02e878401efe45b92dfb6ad4a317454776067fba0ed215a01e9238790280f33bc782272746de898dcdd85436a30814318ea9410618f35cc4877c7cad245548eee207d8225919594a024b8afba397e6d689bf4c15e87501e923e810d234799b415bc869a13fe4b1fa4deb99234ac7f561894783a90e447654df6faf1d98a9877f61a148aa1b2ba37d2624babcc86cd63497393681e70c67bcc959407ccc0600dc1f20f8770953a4f87a539206941ca30f24cb7e9d6062f8ebac08d840688818dc5ca9f98054a25af61310817e05765198eeb76e7c86487bca056f582fd1a39671f70657f1f59ba5622000e5443f6a3c442eb4315b6787451321f0e5efca5d19bdf9d0897b2e71d4c2a7095c2a13bd7591e1f55e7614d9deda69170ed7d1111f2c6216d41e8ed050bee96c7cfdac1318086c2915b955bec2821441269a2ed0cb5b114a82a416a5e61e2a3aac6a16af8a4854c242cde70c27ac553f4e939288e5e85c7a1ff319e5ad040750a69ecd917cc87418fea409359f757f46a28160fa2b457e99fdfdfa8ea7070adfac3eb5edd733c55e929ac8e364470da2ce336b8db6f55f3276d9da172c8a1f397bf59640307c2679060b7a183a6c1f4f1a5ecd19bc74c82cb7883ac9baad7a4c11cae903186766c33632bd780681f34bc6991c0233310b9e8ef70f6a946bd1186ad330b1668bebdd19cf5861fb06f4078f5fdc8df7d4893f208ed8be7a0050a5fd52f76337581ad61b9a967105e5cea8336efb52cdb3127e0d3152d4d1df52a94cf12a23076da06c5f63c9e725a5c23fdbced24fc4c8af680a56196dac59d8f2095124c0ee825b54ffc3348b5587e075a6fd6aad72b19a40aee821deb17be888fb4c0b3eedc467dc76481e01a506422bc1f2d977a98160923d3a75300934132e2184b80ba5d93b93fa5fac96db9eb4e43057bed1654203c2f3f2baf095fd335e970772e52e69418d363974d82829674ba0a3c064fa407695fcf82f1e691b6297df41d5312b8e67adbf4b2404e9b66e747cd3aa25abb9243111ee1f82fe560dbb4bbce29d9689f5f6da7e59f96dc046a7f7d85633b7210e684a767bfadc5ccd200f5649d0985229296971d5acad8fffdc2c1afe5b8627a8437e16f754dcda395d1f49ab7189988e3bd9fd26618659a50ac43b1bae60fc304e0c02ae1868cf7834bdaee9a5c7fd0cc6096eea06d17e85ec997dab35352eb77af98236451ca72018a5aab42ae11b02fe99ed0bab03222c82022e1bc0b2b0267f7572e3f8c4f6038e82642b023feafb046d7fd3c116be8fd7da587881c0ffc5ee8796613ddf4f82df91398587a629961ffd65da28963ed2eb25fe33962bb4b86b97849f434d415a21b473e6f0c9257ece9bd99ccc9cbc2c04da63a093a1cd6840617407ee5ad5a84dd4296d09ed2c52ac376e4de4303a4e3bc4aed34aa1aab836386f7a6658c3494b9f2dced9d9a96186b89c889d20a985266bb8aeed13de92a03e903cf33d54597003e49fb427172f988ce4aefff334f84f213eb76a2ca398b8c1135fa2d70f74f5e52a695f9d974c3dd69f8c473f5094dad7fc92e092cb212374182639e71cf99ad2fd4c9b97dacfe3e367ac6c5438de6169c7cd4dec5551bfb1e06be18cfa45b146b08bd3f47a6f105e54496f5301cc358aebb03d6ea5f7919a293cc41fa6c4305a75379eeee9080c2b402cfdeded5802e1c7d0e3dae484279350e1fadb6206e12b8c2be0041666ccfa3a927bc0267371cc849cacefc73b5ad89295708113ec15cf83efc0e76ee14d252ce68b2072b25b8814c2533c9b387e344dbaa3aed98fa6e886061ba3afaa42c566ea84e61d7ee0a9e1c3dc5eb74a5d818ac0356675715d48b9492ea2f7f18be5317227d7e0bd8163eb2cd7cf018379712ba3e23d47afb61c270c7c4cd25321da3669df270526dcff1a489fe1db9f313f8abf0e3dec5e7ebf5b01693499b011fa95eee93e3b471506597d4f4ff37e0d2bc9f1dcfe9b259baacc350f4d6ed4bf7b891f6d5500441bb3aa3a9fe7c8ba49faece7be1489c463664797ce8e279a4464162c22706888345828fe810774e4f6b38885810a1146e84e845bdac08a3eb5f35fb9916c73b0b1ef4e3e4f4948d3272169977558048fd795f11c6519b8b63e2d05d354d24fed29f7be3fe302cda5e24c7a52ea7d27b4f7988375d48b66d4dd0fa5da3efc27b562ac95d895ce51ffa7715566af1cd69f7336572ba4a7c5280a15f3373635aae65f5201b6b676c86dc124d85f164dc759da2d5fa4efbbbc5dd1c4f91413854a15876e3f748d2715f98068581421b25f8ae29ad78c69c4416895bdca8c46e03aca97be88e2ae480449c2640df963708162b07b6200297c07c29f051de67d817d3988db1a879ac6167ddadc78b4e61b831095e4e309a7082784d6afff3ea16ae3f35cfd7ff1288067ebfcb284b4f07c61e6feb52750c79a069a27398f4759838e6117290eb37fdce596cce00814bdf6fbdcce3af8466de3fb9da66b9d2cf9e09bc2983c0071f28ce3c67513f8ce561ac395ae40a1d7740c6545c667f94ab2301b361dd6925445b4c558d02a2b7503d6b185a5026001f7ea6fcde53a88e6f9be701b5280b5fa57a98abbc6578cbbbbfe9183ffa71d3de546698ff0a3dd8c85e19de7ec210443d5e84c0f774fb699c25ee8c20210c51c28f001037289f6d27f312f5f45fea8006b110f44c100fed60034a299e4b9b35f216d905418041a35b26140e196fd72a06c77f61cfce704164598b54f27b9959723aba4b8b2205a086141877b223f1cdbaf25f172565ff9b7cf077cad9163b10a1b68809ffa3fde074fe796546bdd39fd8138c5c8ebb503d69595cd968995113450f87beac4c6fe2b66251029a43adc74ccb5d5fe21993315e3434ed13f2d8e81ed7dd60e76fe52f347feb704f036470c720c28b965fc656808c2393c0b6a1b517977d54d17dadf34befb4fa25ea6c7cc0a12a4cc00aae7a174b443e483ea686f414049286f627a3aca5589e935fee235c3518f8f0c7c20d2319e8667dabdac051178d4a4cbfe77ae67cd2ab45aee7dd200ea90920efd30717f8bc367b01ffaa0a6bd3c0d8b8bf8550dd81ecd80ab3d1f4a248d2a527386223317471fca78cf6b619ce7e36f052882ec1dcd68b212727de8dbf39bc9c3ed0226a910bbc6ffe5097b28a229220a6382841d653707fbe69e03f6bbf280dc353d887b88a093c403629fbebf695022c720887bfa65772233ba09f782c8942a90cb1dfbd635c59390297111e4e646334a669c5e573f2d1ea120eceadc5da012b584acd9237927a702ea2f97d172d4f8fd0f900e6a1874800bed1ddfd771d644e99ee54c58c5e32b500b8787e6fde59eca28b8c114d14f834c74a1f8546fc3d3bc745ab9b423b369353d0b73a2b9c9c1ba3839b3b91a557fa7173fd8ee029698c59f0de3bfdd4fe0f70714aad4d743b6657f1ef7fe7f1e794d2b33d068a89a04d8051c858f90b14f647c5b1214e25ee8b68ebc1ca8edb6e386dd18ce9b45fae10e1111317114aebf4051acc57b53fb8812c68a8d00deb63f130f05896aaa38bbcf6f563aae9004a3eacf21874f74a4120aee8380ad2e459c28a3ada04ca520391d832e2d83e5de943b110679f3a096407dd3de0ddf802b0d98d3c1d82ddfbff4e7f3dfaf23a888e3b917ec717028395ce7372a8f05382201ba57d1fdc37126be791e2f22feb0777d4663a940561a2c457d575fa57cd5596c99abb3825d187dcc7e42cce4e7f2f644b6636cefb479f7f9012b7f0622ce5fc033c7fe846f076808a11918afb3e4355d223abb820c741f03375303b94613a16f926beb660ff832f46db3677982ac8967af136b65a8f5dad46a506485e3cf24ba69791961704161eed3413c376975940a190d2152e5b7f3cc7660bd0667adb8063a90d72da36ea8017647547bf07ae857f5b36d55e23656493ce74b4059a409a71b054a8bed97acc3966334cac1f98706240204f14b433e3d261a7b1d08a6d73309bc9fae4a3451991395ba6e565816f8ce4e752c7072d440a41fe121295398de1760865b178e10515e3cc3608139eb711df2fc9543a2287791342a4ee66ce97d4967d1b200f549fdb3a43479195541896cb4bf5aee709e8116c93d40eb0ff3b53519bdd9818bdecf69e7ce0013a4115715ea341b746a4c0260d3faedca6b0b89a3a55c7080054764d4e7147c5193e900b7400735e040c24e0f2023266b9f33d4d9d4a037b742a07ed223ff4640d512125c2484caf71e5439097ec2555377a3780e788f266d9058c33919017843aec43710e98f204fceafa42f6c1d528df1e2ce2084958060c6f078a4db164b9a4eb7c3e2ca2bb35ffdf49b0df7740f21f0c80e5ec59367c2d524524d09f32529eb4d3af8dc0f08e65b2277c3f2fabe23f3d347d8e3598a110d1c66860b2147e1e851a07270c4b052460c32cf4a3381f13e79b39ffe91962da126af94c9bff80196f0fef0a525eb4ec9f2b63b76bc2ebd3df1e4a3467fc88c12cdb62a24ff01b80eed8303564a02463c0989b52f669f70c37045823d470b8602fad1a40681e7b23effc6241df80b61be2369bf1580f260a414b5c87343b26e8c16fd510187904bf8fad3f5b1bc2ce905416e0aee0f64988f6269250882cf9dc832ef83b4cd21e035f7ed89c11d351c9a2971f5517c515e88eefa5aa76d65b90c5752550bf9bdfd0e3ba634129c3c5af487f11fcd480d82db932caf0fe43defa070a5a4a099ee2ee033054002cf5a4cfa7c97ee8eb9afddfc0dcbefe3a8f56a9ca3027669060524e79a6ba13c3eedc87cfb051346b8146fda85329ff6765a983fe848ddeae3048aa8911f322580e5a7dc36fec224d47f15a324e43fd4a091c691c28f79828c20461c14040ad48a9059305816a503f2460d49daa6f7c11696a91b2ace1fdec5ca0e4acd0c517debf1827a4a560c79d233ee01188823eb83f6e31fbf2120e805054e012fb5b9acd453c1ec3e0a9eb42c2fd3a71e37b3d6882464efbdb7dc524a99520a8b082f0924096ce3f2fc31b04de9b7ff0e70f90bc03f7adcd45c8699a91835a697edb1593aed47abe99f085a208c03472317d2f3921b3f15395a4d0f84505115284d8458b2fabc6b6a22c4922ba4be4b57eada51f1539ef76f32d5486986d5ee5372499fe3ee84d25a4da67fcf4947619af8a4e824eb2d7f01763cc4ee6b14dcf859eb8b17b232277cd1aca2254a04ab387b6444a21b185525ba0437c227c2aa91c58151d3464ebb1fb7286732a83097871899263e864512f5e3160fdd4d24953f3b69647b0bb0ca83a898c528dcf848fa870f3407c6f1c18403e3c88f5f01b6a11fff48ffd070ae8f6f3da83a0263e81f9aa5ed237299fdb88b25da48025e82bdf8f448fc4863afe0466ec59f338051a7d5712fc608551bd3f931c79d71fef5eccd39d342340c596760589504a2f8474ffb4892823dda477c2c7ef4e6523c299aeaab3577592d05553d3c444444695c807dc48f11034c13ffe32624619a780315d5488f7bf157c840cd3ec5d33f7ada477c9389bbe809e34699e44d5a4e44a41425da673dd9fb50b9381ecdcacfdeb9202de9921d4c7630e91d4baabfe60e37e8313a6c814629c76fe6523691e88d3e3f66dac7052ea55fdac1a4b27b2ef6f3b9f4b5b8757d7dc7924a5feba6ef14c228e3c31bede773c568dd7a2f97872e9699a664bf24977eff88c1ab24fbd5113733837b300693bbf7fd70778037da1c6d54fe90cc5c223272965984069fe5535aab49723ef25316f56b2b577e3de54a2b526c2f91d85bfaeda5cbcbef2aa5ce887bf2b7aea7bb0148922c27b9674e015c6c270de49efc1b3ba8d98fbe81b6e81e67d93dadc76db8bff131ff5118d5cb5fcc46476d2fb76deb71373bbfeb46b40d712eb9d0d8f60ff9b1c42a0a51f1a9cdbb17fbfd42ec42edc267c906e055fff0cbb4bb18e5d1f81ee338d3f4e7a1d806e2a061fe75d94fba8feb2fdb3ea4c52105a5683cc331fe57af9cec45469960a49561e662988d8e9a636818e39c6aa8cf3d03483ffafed6ba5652259d6a7079ee8bc0fce874aac1e5b9e781f9d1f3fdb970dbece95443e9b9e789f9d1dbc02b2641949efb20627ed45c90530da577f922257bdabe74d28ac4d8d3668b909494eabf3c4ffd17eb43457b1f97afaf591e5289b91d262ed6870a8fcb97de06ae2fcf3e80eb5dbef4fe3563b8d8afdf6342e8676fe4eb217e3d3414961196e632073d7a7818bd26f486a2853806b7213dbfce0c6e537a664e7d8c35f22fcf8d9cd47594daf5144a6bcdf8923aee8ede2c7bbea2b615292addec575df8650d5cc76dfae9477b3ad5b03df745467f03b3ff6e341eb7f93ed3b4ec6f80c0cfe93182047e0faeba2114037c1d0dcb201c753f2bee7f5640dc8395079eed39bbd9c02b1db8d91c1f007c5e610e2d1595dda3d67fba64cca5131a1fa065646ea497c43ecbaeebea2e4a4d1ea40db1c3184e5b2adbf90c2fef27949ea394de5c8a7d89d48d3a4dcbb22cf34dcbbe3b2dc3fec22c4b8f269899f9e740154a6b894f4eea4e3e7a9ed1e85fac0fcc8fdee7e549ffb3d26a77f25277727f97fa31d607e6ebfbbc7ce98847edec8e1849a24e08388126a1ee94591e785e1ee679b081573cd8007f87ec6de095cbc3581f9f9f950e1456cd66f918cb2b98b7a71d983f65d6065ec1d8d4cac57ed7e7c08924759dbe5f3ebdd4f1aa76bc2219711b6ae3cf41c85e45738a452a85d16b4af786c20a2b806c5a86d16b426f247c8c1bcbc8fc78771037373032333d6a6a328c5e53baf715db651b8625faa70ca334cba80ccc81af33037c1ef833f0bd0ca3b445c506ee132efccdaf0c5719d79ff20cd72c62422b92a71d86fea477f9d38ecb9f6ce855e94f455625fb3fab51fd6a3fd2e8e75e2fb3a4d27f7e8c310c7b86b0ca0863f04415517c981bcb9847be6919f642ae2d5bb6b461c31f39055c9ba9d248230e3448c37d1b3532a1c243df1d601bac2bf935eea8fd66bebfac0bed3c11f981757ba0173e7f462e7cc242725e14cb8000c9b0ebc7bdc1000244757343afd93df03c39af99197a4d197fdc3b8ad643d492c633d767d9c32c756fe0f82ccb328f8bd13c26bdc6dce8bb23d92fb5731996f83f6ff4fdf57af8a774a07f8fc949cdcda8f99db94392bab687a8eb2b0ba1761bb98ca2d55c9e7fa9a82a7bff1e32c398dd8b3fc81fe87dc557493f320e7c5a03d9356b3e1b172e818728855dfd7ab8d1e7c69883da3f82bf74bbaedf5ca575596cfb23a8d35205f81a1ae754524ba7bb41a51fd4b1419dc1a57db40f7f26ea217aa21d9d19dca6a18ef6e1ef704bce0d4ced238afafdf7a0dec0f3c1ee3bbb8da8c76d3ec67283c9543dc6de41c9ad37c4a836fe31b84d9b4c2c1d45d4af9a58cbb2c630da5996cdcf4e32649f39d76599f6cc651af69d61df18f69de6f33dc1e73bbf7f7e6f9bd6652719605b1ffc9da35b859164c4fe90c48e59ea4efba56e64c991be1b6354fc517c2ec6974c13396b993ac22b47fa909b3b8e2285a8332ea4d18778e10ffe23bd8928d643ac228a262e57a106d1355dae420da1abcd8d8aad52b799736a327e47db9f034f50a532cb94aa3019a6653d1cd146a4116544ac1e5f613a355373a660ed69222d510888a2101951374ac9d0b40c4208bfd4d58e348241240bf58854fffa7e97eeeb9503b9209ac6715cf771cc6d9ab669ad75d3ab75f7f5fb302f0e3ecc8bc3f51a65ce24e3dee6d20b8eefdb2503b45f920b3fd2adc298e6d53db7e95cbfd60da7c5410608c60584fa994c8f6ddd551847f56bf412aa9af6d95fdda7b19643ea6acfdca5659ed1ab65dd977d0ea98b437c987539a4e86557517825a8661442088f5c11218cdf18c42086c53859e8daaea750c5fdf526a822fd75913a18ca6d5e8d4bd858857d9c5807e328f818db4a837a59ca2b2c5169d462a4f3e1351f9e88f80cfca2664f214c72a1fde80ce0d7f06f866118b6759122b9f39b5252f4895009245ae7cba9e5f2155f984194032713b58c101a11bdce06f5bbb9fe566aaabbbb7b8ada2374990bf2566ebc1ed7ad855951112c9229698b8c7c84ddd9a0fa5ba9fe1f17b5cdf7503c0f591f640955a1d5242474bf2b0b64614ea06ab2202a42b9110b9a72b5645e7c980b6efcefcab2a36981a80883fa4d4dcb8d3f599355194ed68dbf234ac52edfc089d01d627141f108dd3ca8a87ff9d2c0f7cfcb57d608e2c6e7314585cf438a28acd13dd078e693555a1746eea018d48f85fa892a04b1b4206c412bb55fc0838aca97af44410dac9abcd48dac0285a75c58c19310b0d0a47a603e6149994058e124f017ac2c454d60c284279a587914ae7f8de222faa9824514222d2d289cb8c2440635c0019117b3ce14c040e3410aaa002209fa53646967a235c512ba5e6e4d31c6c52eb7a638632ee1964401cae2074638e2889567e00b368a5a555650831c1011456bb68c52469413aabcdc12a2410b51849c702688105b422a9861e880460f5cc084222ba2285d6e0941112a020241ce979fb4d5e553f9358b269c70a5fc198f16492a09130d88e81a0c31c485156674b9e58328acc009723425891478a1c5d009b24c2088b450e2074b10f14bb2c052ad27435c78b9f5a404330373085f620330890c942e7c53ca035888f0f324063e40620c278e085263b25670834b0bf9de9c5860190209126230c61a5b8c20011663e0e00acb77b0022e8eb82e27818b9607d0b8dae5561223b8dfa7a4179ab713ef543a33ec2469263ced7ce3369f0a08dc72bf4dc53852de7a250a625c1cb77a97ddee76e8eb4c033f36a1ea406666da1d8bb40bcb5ef38dcab95ddedc15aa5cb4bf6ee6d2c138ea9ad736394d9bdc77525cdea53341d4f59adc3431aa76dd8cb445bddc26fbeb395bddbbae87a155e15ff1da6a37ca344d7bcda52bfda8ab245bca3ea3ddd7d787783f1dae666d0ff1cacf58e8d22b73c9a28114d757dcc69d57d362db42125d8fb7ba0d13d10008d7b3d0d80b26975b5d10e072ab0b2b3709f44117f785cb2d1f44b9def6d98cc63b2e8344bd5e931886595ae5c605e1614acba8f32737445eec35312a256dc184228e0b82618df110ef11243dbc9ef934db360c8b379bd0b351f6b48cfad55c49ad8431044693fbe3728b4807d7c3b2e36661e53211164358586935717d5c6ef580755b5f64b9dcd222a8a585932bc513222b54b4b0b4a6bc6cda18350ca1fbc2e556184eee4d182c30b4c46ced3736a216308a89a2a0445554a22b626eefb8deed002304444caec96db8d583347a6006902cba3352ccffa2890b80cbad2f987891c665e172cb0b2d2ebb4d0a5b771fc52e04eec428655a7344cd6e6efa0271ef86c76fb0ed65b820482ec65650d3e5bacb7a7c3b172b3d89e3b867ae318c7bf7b8cff127759fcc2565309051b1efdf3ccfbd1e34602f93511257847d003e54faa998d83d17b82018666a1c9c69078b5aff8b97f437489f034725faa4cced4d7f4f8f7b2cc3dd998c2646cd300c4686de7284edb84d66638744cd7ec4da9e3ef6c17041280b580f0cc7eef180e168c85e875b3d381a6e68b820a4ef3b391ab2b7372f7041483fbb9fcb6e43b296723464efbd4cfb7976db60ed788897c3be2dcf65a6c1be2fb533f0509da7dcc51e062c286b815ddc90ecdb520cc37e623c37dc10eceed434e99e59f36c2b526e3c2da37e3757cec76c534a7fa326f784f808a1769895916f4fa0d27bfd8672f98bcb2d2eaab804b8182764be96795e4d0dd6a3e6eb713d0ec37e731b18c69118751bd2f76f15a62717a473903ad2b7979e392f35fd18a71f439b922aa97e8d89e962ca9db9dce24204976296ed377aca29a0ca50a737eb4edcf315261405d1ec4906ece963f6c4bd3d8d9eef0e90f41a471fa3db69f4a3cf3a24a30eb39799863ed67d29ecfb3199d49d76c6bd1bdde584c56245b1cababe64308acda069d42dd63031f9268ce2abc3c51346f1fd523a5c848069f83601aed61aa715f5b071d7a02f5fab8fd9cfbb18d0165d5c9acbad212d9752a1e532110d9e98d6b032a58563ebcea75926c72c05d2217194fcee8eb8279f0764c02b81189151b8f275a070bfed7e3c04733f1ef28e6ef176908cfe00714fbee7d5d4f4a87949d57817e769cdcdefb6c0b443e2cdecc634da0f89b7ed28fbfeaf9b1bb245f7346d76231b8d44b20f8485961c0dfdec5e4c74d3cc8ccc0ccccf984c2d34c60d696cbbb98921062031b8e4c47013b99b1e82ddccc29045fd642ec66dabca588692b80db786547025bf9becf4e830ce842ac85e3ee16adaa6a3c3c3f333f04851fb4bcfdc901dcbe39eff484ec7bdc805e9b1359765432c3704dee6283b8e4c4c83bd10ee694cf7c120e9993d86eddcfee6b9d9f76b5927432404e532d11466dc7a99688a1f5cc62244e6621b0c523037a4da9feb0f611827db8128f9dd3b5095044ec93458866118cfed1bae7342faa74c872475373bd37ddb4bf7f5f880dcbc97bac9d1d951f18ab254cc758ee55e8d769ecb9739a2cadcdeb62d320efb371df9b8a75ddb75514a63865858a8c609d13ef3ba947bf27574a0b6b4a9aede6064324ee9fd4d2c73b7d7816930f5291629a5305968a42f94d2178a75497cba6b56a963a6d9dc2ba27e48646ea5dab6e1c802d4dcce713a9c2c09e2b849c905e976db4cdc93929503ca57596e531b4afb111d90b88d3b71c20549c283ea0f01b7d97a6e30e2dbb68dbe63b8197e6ee7b8cde8e5c7e03693dbb01386b59452a68a6c6580e8ca211fb7e116104eae7c20a8dcaf9bf8fac9958fb5c7dbf2c1930bc3e5561845578b1c91fad4a9b3cbb847b226a6c9b2ecb70e89877141bacb76ae7fc605f1a75dbc3cd63b24a9cb29ba318e0fc72a258c922fdb7e321c1723ff8b49e29efcce89ea2f547207cc40cb1642b707781b0890107045a5b2986480b52a314e015a6700310d544df93e3ff0184e3061ade2fbfc302d15f83e3fec006a22c54a5a2afe3f9c90e0240aab68a9f4ff00bba7bbbbbb9bbb25d3305b33d0284263e85ebe8246153097afa041e52a216a30714a64326e702ff6304dfc1e8269e23ccd06729b18372b56b86a004f3aca57a144acb287b8f163931bb5dc6fbb3d04e3cc797ba02ad54050c580f9f282ed610c685517d1a8f8b451f1dbfbacd5a1c3e57e0de4d240d9fd98a853b8299864ab6a1c151f4866858b8a1df5e9b86dc3eed9fbd11437451d5a82151d2c97c8029b3aba74a3971df71adc5c84b809aabc99fe3143fb881fdd541fa6bc51c9ce10493656fbf9e5712fba1ced304d7c6e8afaf2a4d7a24296444a4d6a924f44462f474f6464a52881f997973d2fef43455a986abfd14bfb1d692ec8e8e50b67bf929c82c0ca932f6af6f1055a7c0d08e3909e5f875f98e8729c139e7bf0fb53504260c6174330e2076aace07f12f5a331a298c62f147d9900d195f642dcaca85ccfa50845bdfea3345c598681a88078afeb3dcb32bfae8797e501cbb21f825c9d0f7e31c62c8c9b7b1d8ca3b668cd6235fb88b3df79c8fc877b79f7d34b86a88078331ffc660c337b2f8e645cc805d9a1b708f99f7b7549ee9675356754aa79ffdcee7a80dde44b72e35f5434fefe1d30a8dcddcfedab76221dff41a02a56b447f85b33619c7e93cc9bd6e034cc30fda076c15ad498f821c0aa9fe123ee39048c98a0f6efc06afc68e0be76b5fbe8b23a308d3c03890b8d647152effc9ca2a09f73e67c966b8822212834212673ce391909ac1b4ca9c22ac210583810ac882d253cb04407a49452b2e042621221a594920821823099fc1586c604a65d6e2da16289152d084153de4c1ce932839bab73d30e4302872e5fc07ae372134b5b7ad069b55a2d1aa79cf26504f5e316141d776fb54c5e8eec3c881a39a1b5d3cbe436476f416186f0d84eafe8b4af1ea259d0dec1851f04a1402743bd03cd6196805e58e1f5c743bd1399a81f0f0545c9d181aaeb31acbbb9baa11eeaa1dee954efd01d541fdf990981cc936ec26468c883a8388b70b0019310a310810842601d6c00160d018628832068af92f04fd22ff767ff588beb115a71dd9db280b852807e35ad8ca3dcb4c5c4ee43d0428b085fe8dbbf75ed4c4878c1002ffc0a9a8fb84b957697339c5e466e1eb033840bffc3b94270e749c5d2156239c2de11a8a233720eaa2a1ed94280050b96200e64a1290e409287c1e9bb3c2149bbcb091c1a01bd2f6aa47fb4b310ee13d158a224d1f2b11653d5125f9878423e8d523fd6f24510be0c909a9afbb1961b8ce4403a618cd02e1731b61e333230148608cce5089cc9d832f68b0e3e2ebaf0a111f814c6ce2463cbd84d90b15fa8162ddc6be92088824f9b35a596244ed4efdf29a5f0af7f9d2450e55df65dac549ac4b3e2a5303d519bd0a2458b162d579a802549171742f8b109beac8d10cd43a935fd27a07f6054a856415a523fd306eaaa53b7673810b921f4d239a590decd795d7f79b2ebe109cd34a99fc908f5335d77db6148d4bf9f77eb90c4620713a66a6194f34a82d218e5bc28966914ab584629866159a66d1bc78d46a49ac154227db58d1bf568b4916238eeb71189546ba9e4e2f2f2020313c3059111a2a670828a0387c9044d2693a9965c60626e4478c36fdce81ba5928bcbcb0b0c4ccc8d1b26538e6b4aea5293ea1b3f986e4c381c070c4c4ccc8d1b3870984c3972e8d0b163c78d1c384c394c39749cfa9443c74966470a9d5d6106002cb4e0a15ce0d1a3c7d643cbb01e3d7a6c3aea0623733ac9ec484185ffaeb3768515666600c0020b2db4e07928940b2ef020f1e0c163c483070f1e3c78c8ec4861c78e1454f8ef3a0bbdad9d2315989dd9f9bfeb989979054e86a8020b2d78330480112c1851ddb6d082e7a1502ef0e841e303a3970f1f53fa88d07db40f1f3e5868c1f35028175c7081078f1eb2478f165af03c940b3c7ad0a0e49cd2615c30419927d5ad0b1c91be3d54b0525fa83406a18931c2b8bd20534475eb23150001c0d030d0d0d0f464a1a57604d0c44e53ea2f4e48b576f0f3217c1d05b043085d4c103d14fbb8ac89c7b46cda0183eaf282faf1d0ced0d0d05016cda1472882ee7403bc4cd47ccf347acdb75150cc8d989f4153b02a49146c23ffc6cbcf1903f3da283ee98b8c1e3e09be125237e1dec9dfad40d4dcf120889a2e7467cfefc4a8cdf1475f04fe8b55427af823ab840a0fc9d257c2308524ea07d52fbd074155a985588539d1f532ae1a9182b05041198c93cd3bdfb340d5280860f0c0abf028a8b7c0b55c9aa983e3a70e5425390255386c433171769b1ed3311c754d0451f349dd7cd9589ce5ded472a73371d4f4a02677ce6c0605050505ddb933fa2015044d79a9228a4934499fe32f5d5771b1429a329af34b9dd441fd3cc8a3b8cd97bae236e1361f5fa9122528ca6a742364481097c6c3863e83e80d44314ae97f24034c21dcdda1b7684d027ff83b3d146015cc04d826fe02d440b1d70fb91a78355f8b3fa80b80377e0ff6a633b88ce8232957bcaccfcfea212a7632399dcc41a5514606be3ff48f1f87a40fe66b0f5f4a7dcd1d0c5631f7847f869771e79c139226e9739c3422b19063c1e17090a036fc18db4ec76243afea9b60ec72523b5055faf93f02aa71554f9973d6e0ab6a5b0b44cdce594f1c08aabcca8c325f9b92cd06a276e55560155877ea8477be5b619c22a88a6fe241c5825671a7c6927d24a53404898afcacba055156b8379f347fd4cd975bd4cfabdc6e5d2b6ef3e1b8f3e7d756dcf9f3bd8a3fb7c324cec7c13393bad684c65544612da6ba4d216610f793b935f08a096ac70b2adff95feac6eb239f986f7c24442e50a2b8aa003db46125b2da38c2fdda89e6644b116df3c16c3d4666701b6825063789fbc9780aaa4ca6f89aa9b6a03244c123d0623fffea4e6e79307bf213cff51462d863cf2b2a4fa8ee04edce1188e215c686ecc4a81db12098213333d727b5bb9b075a4e0c53d2bf28d54107a8468d393ab80d5f2918041c85d99c2c4e90a81bbdd839295e161887e03e10830b4c8c1f18218740c500aa720835a057d890c17db97c850d297774f90a1b4a18418b9bec4c321d17449d7115fd7adcf8f165fe8377dac89e64f624c3bb83cf9d94ba0d845235339e4926422168d7f5542c503108e96bbfbd4eab590db400d6d095fa555335fdbbfdbc5a83c6f0bb9b7b98377b0cc3be31cf7e0713f54b5d8ca35c71ef9cf5f961c57d8e675d0f06395035ceea78a0726bda689d00d1d9d318994da5eb73520b600da5628c99fde0cbd3c8fa6ccdd1906d4fe9e8475d6454fc4c067a3f9f9b3d5b0fc69a5e4a0b0002e6e3a108bbcc651513ae818529a7f90f4fcb8fefe3a7d89dda9e6a80ef5f24beb44aac1225fed002271afa29e9a1dd81a8f927cdbb93664f0c900f5fd3ac0f0bfe0ff195a4a43d69f37f569b3d6996071ef9dbfc9fd5cf8acad0cb27fd977a5e916c0e0e2719fae989483ffdb6bc92160d2a27227de9f7a5f644447bfad4e2405fb35709159ef8a45772d2de2a89f674fd4923d9d365315b44c6f7374285f6c045d7536b011f08e143fbc3e8e147ab0344cd6738e1977d0ff05e492ef673aa21f28c3ebeb4cd8a3edba44ada096cdb411035e7d7a021834ef4e5a9066a79e49f78e25fb6ab448e75bf168aa27e9095e33a6a8450b975f97e70680a54f52a0668c40e75997250bfd8795abc15523cb1c216bb16b819cc6cb16301005bec00a095a07e94852d7633a4245ad862b74266a57e3176b6f542282b958b6e527f1b680713ea4763a782f6248a4381414d1cd58437c1638bdd8e2b3b29177d618b9d8c1604510d3482fa511f5bec4edd35907b4fdc6b92da62a7e3ceae9d74fdc45103a0976d2088f214aeb4295cc805811c6f95d413d032cd4308614321681042c834d43d18a78410324fe9ef90f414fecd5950598a00ca08a10cf54233cac0fae95fe1cd1ea39cd7d636878e085c18c39ecc21810bbf3df93206870bbf2b506fec16a31c07cc3108eb978fd3598860ea7672351216da404848a1ad0d40b91f674983d7b8bddd0b060927eef5f17a0ac4bd9c105da6a93a228b4d76a3e988a10bb3d48f7d84509531704be2800563a8e1a40652ca78c14a422c57c600ca957fd9082f74d03ae204373ebd62239ab1e2c65cf9b4827165cb881604910f85145bdbcc98429314dcf8728bfad53bd345577e943b50a144171f8001129240c51cc2054f5c90c78d50dc184d26d642064a6c37625f98da848171c42cc2093542965611683c2122cb101ae04887208a39d064060d40d1c0086628424803538c98818829401b116f6ad305e594725e39c38b39e7dc1202477114da84a3e496275cba90e58c222967248104356bc2fd6a3555982b50d0407d31a668c1779b1391f9e3c49dcf949a482e9f753a5c10051fcb16edf7e180848beecbe700affc972e076c2bba97d5b1a4c2fbc5e81c14a8327dcc8dff2a0e1badd501deecbf1b1c94dea875c441b9f061daa81f5774e18f9ec3c238d9c3e7cc701b9787cf157164b88d6ba5aebe465f7244b08ff2230dd84986f8d8c7c7e1e5a37cb12719220ef24b2f5febad748a5648e9e5cba7f44b5db51f0feea8e3a12f673fbad9af9ab6a2cb5a6f10420cc67252380a72562e8c10890a3f76f386b6606e6ae5b2501ac08c4a9d97e7cb37995e4e8c820f63fc669c1e1a4aa9fe1fe58860d76d756bea72300d7cd9e948d598dca66e9c05f5fbd44d0e8cd2f6d0d9f5cf201bb186eec052fd53eeeeee5f5cf525821604868a6a6aa3eae0bfa30815a3d79411fa476b819fab83ef284265efafd4abc0a1bf01f601ff45d32e3f64557740882ea264546a5ffe6b630cbb54aa948c6114fc43328e0a17c20ba1055282cbead800023f16b2018a0f3fe38244185a2be300c13832e3867037da8c4a85973929d9cbeb7229d910fa57f7f98df2e3d55bb48b034c03bfb92119957a5d08c4ae99465a23eec5ef537c5e65ef2ca86e84280650b2930cf179e2cf3dfd4cc3256a0ee318b98171e2c36f00ff507259f500154ca6528961b43e4c036b9ca480b88d3b61038cbae3dfe3957d270b1620687606b59f4f1e1f5a254a564aa215b2e255bf9351bb655ba8e3a2b2ad1d79a87340c6500ef291c02d5baeb4523cb2582b0821dcb265e55bb6a8608d1ca4c86732ae14fe359aebe118e0459ac96032c84083e4af792785452507ffa692833fbb3d11e9ebfdec3fdd16883aa51b5f23c9e719165c22e5b4532d7d7ada81d60451713eb5a79db9a24fbf57d4e12ba1d683a808df2f7b0351d1e1f717f16739e40eab10c10c6a53aa5258f2990196158b48cb8af6546415fbfbfbe10f90f084751b0a1ad30cd1a8db44d88d80160eb2dc1c97afb0c1ba4360528426975b4320e372d1e5161945b74504a13b4b77be469acf3ebda2fed12dad19a36234da229ee7d8bb5dd2abeca36522c40156d803f52a7b13f6d967ba41035a1d889ad9d78c7105d9a11f29fc48bf5f89126a7b6ac66022fafe45a875ab258916fad7f350eb4385c7bfffb2ed478022d03750901decb52c5a9f5e65dc8e0645a3cfd9688b5809a201f58abe6619a278a0f56122c40156f4817a757db44b7a757d0d1995fef5f1a137478fa31ddabbd5a27fd9d30eed55967daf32eb43c5065e3151424549665b6360581a0b44c167ff22bd62615da06e50e7e5161144440c0115911842689d9999bd2111124a184550462a0b8d67be54b4ff10de80c6348a20d283a296106d04418408c804d41aa24882c0d426178470c6d0d51982e8679ec0c48d975b432cb9dfa7588fb385c6333836f84acbae8ecbb0e6d0f12e36bbbd020f6a578710be91d9f5ecb8c745468ada4a670f59da9caf75bde209ffe32e43adf3558a21b7a062d6870a8ff6d9fb68f2a177d2c8e415e43c2baa7dbfd8d14752b677ae48af36ebf3c34ab3b36b2b3d05a2e0639d110aa9b568d4af592c0a37eb2c6d0438b6ff622ebffc41ff9b5c4b9bbd69cde2308dffe7c275fe991856997ef20fb9b10d86b33d7f896db4cc740056298027c09effd55120870ab00f7f78861ad79f70dbfb180ad75f07721bd75b88eb708b3567d4ecd93d6e48f6dab5c50ede03f00eaeeb34ca3921432e4ec80e8d456e988d8614512087f6e17f791a5a9e70fd75988debef5bb2e06b00ce0895c2fdeca400d115f7b2930254571ceb466b290bea47a9e6970d349ee12e8fa3e27677e20a4854f8adc58f85e4e7b88c3d76c73d2e6af721349ef99ca734b3ec295da59b7094f7138ef215a8807d785b7fbe5c109bebdbe569e116f5f3a12952aef721efc26da277e143dd41f01f541e5a87fee14a149181eebef19477468eb837c56de077fcfe243a40d5cc525d4d5a0a520a1da6aab8d7c409fecf8516f62a767de7f714f7fa79056d80ab695700aa2d5d8ad1ec2b01b48a95c8821b072251e5f54fa42083fab5909523f0fd752000a7e00d3318eef90d91bed31eb9611a2f2280d70057974d419415586ab75a0868470e2a7f771087304608234c615829478e48c1a85f4f99d21e1dbe13582ea0ae7b8eeb5fe93a659c78994bdcd59c91011e3a08104ce3ef4c7383f3fd9b4c371815f5bbbb3bfe8fec2b0dcd538c43baf33dc639ed29cae799ab537c25d7f34b5b43ff7c1e2554a2e5e1bf5e49ffbc94cc1d58d47e36991c06acb5e646a0ea9a454a8c1cb9809309b08a7610377e43a14d8b2660e4889306e2099742f1208a7d84d11c88da99445ad48f8b8cb8cd478f40c06dba280235bfe61bc7385ff64def97fd67d967178bf1bd0dc6a4c5987dcc3629a1d45ed3ec69085fcdd69c51a9f63f37a319ed7a80f7b25d8415282cb8b204145ba4b18a9e8a25d0e0ddfa87774b54e9efb90725848e43fc1901bca07aeec1a4b5a834ae9574410c15d1000000004314000020100a86c421b1602c1e95cbc2de0114000a8ba0447e529849a32008529842c610600c2080803100032033325b05e52e2b6ac05478bf273b1cc876a547901d81ba146452eef7bc0a948c6ed2dea62f4c9784d52eed030910924114fa59e0de1db03f7be46813a14b0483308478a33da0abdd88f57483bd0929767d894aa9d6a74997a1d1efdf20adb8322ff4b9f2db32957ea26f2727881446ec4a0366981f409e52a16cba27c834a97f45c2e8d2266ddfe35961756aafff73427e714d0be498bc34156c2712b34a8c19376272f61ccbb04846d1069abe353cffe41950d37bd97b971f906e73df893077e4af3278a08a15d69543ee8a40d25557e39c1447ae6f27d6fa8623ded381c5db8e2645ed5362123465a0da19a66d735cd0901b33250d21d3a40c601e869e3a9b7e400274800cf624a71aa248b5af2ddda3104e8262d332a7d4534f1d695510b5435dfecd623eec499ca60a19a64b673854e7e8b8351a8c1ecb49f3ec57b9cfcf6218b3142dc652067ee3018ee3f99e4bef8a6bd3149fd698085d9b26191563177429c4204ba735ae485996d66c534f02d8bea5a5f99ebf4df263bed1a7ea3db6ddcb779e5035886f68f9ad01e7e6a411591c11a285e9d386e9b95fe3849b3b131296689b60c7047fd6af67300e35afd4afdc8b1af0cc57d479aaa5bcc3b0495a6ebb1a4dee9fbba915a5e6b9a7b7a83e7ca942115f6a4c7636452c6cce9b2d3121d0873852869c1acea97138132297234ad9f71a7036ed93dce4a3d06876107bdddea8a2497b7a103032e60360b535ed44e2f434a3f286c8db3040a7724415e7855431fd9d2550691537de0b6b9ac00cf6060fe1dd1914837aff900d09e14cbf9b34ce17ad80f44f4cc1c7bfecd97eb4ccf1e734863287b6749e0a597b3217d375eea163f35075453223b0ad0463ef194305c5e3ae9d5d9bfb431a0b34fc277c567413af7ad0516f20f7526b81b41c14f0285746e9244f91818bdf417f1fd299aaa46dce45ec861de8b6ecc22c1f9bb604676a3429910131b10bb7fb15b3b27f806bcdd4dc9918ab7e5c3bcc653d35625686ca8a00dae6407f0e3abf8444079703b0dc69b0aebec2138ed0e46f218f23ed8fe9337ccc1d3174d3f22d25120b373ebfb55aaa7927d9e457a984be67937bd4400b158c16a7582a3285187737220644d1674744542e2491a3f12e3e2c208b0c3e6a31cdfdb8db67d6d421b0db3c3561a3deaa9b3300382a6375739025324c9f99e14007fa8255f8a775a6cd7b7ba1ed1430fd3e025ffae9914960d95dc21732ccbe6af91a7d969d7422103823d92b876a54989366723d29155b1b652a4d0713868417e99da2230a84b62b9ffa95df646bf920c6f5a5a209df264518f62e82fd04b877ec21c699d05a8fedd529a529a45777e211905de71d67dad532308ec29c450f9704cfef7205cc1d5b01fabdb8235f93c6b229c1b0ecd0316a9a37c2b468962deb93a00266bd779b973fb622e9455b014f10e126fde906222f62ed50787f916944f8b3c326ebb16f97c21ef00c3a881b683c196137cd1dd2181a9b61d00cade4d67256ab6c36811520dc8e8f598eac6b96bfa24807d0a526715456ad9dd5392e45d278fa52db44729ca53d27f8c746fdd628e7680b1ac639c0b4479ea1832dddffe9310f7cafcde26b1ce83ac0aba9fefde4f20bdd4a697e5ad76b4658292129e9aa3cf3a3c5e64808cd35d65d1ff1831043dfbf4e30da8f62e853e320e2ebaf6b4074bdadb306c5de1c6450baf472f59d1f579acf9cb60c940737e52f9529d9d54980e634f15b3732c56dc00204014a399d294e26a748e514f939650c25c9e4833f71bd3294c0602053a530d90abefd540f85f5e707211f476e865f51315c05ff6706376ac6b493cfbca1cd613bb8704c1c043003fc100f0b0c98d6ebde89a300ac9ff3cb4d9e179da4e307e3564725bfa5470c94d164049b5828ff385689b94f3f892c0f8a4de70594968634ea62f95b603392e10f934458131cc2829fb71b91d5ab7cc5ba8fdb090bcd6462d6d6b7112c209022d00c703b61ca3f70769d25dd7ec93c91aa1a3aa08b1fc2618dcf4bfcc7614dd6968549b6da939444e589d17260dca0d9defb984bd573771752bbdcbdeb245fa129d25aabf4e755a6d2ffe4a6070ead45120df5eb2ecee3b1116a37fd61d0bde355392efaed4f917cc8029f80aca4a44bab6f04824e7de31648a6a7f1bf33665d0fc8547a8d0cd6d5ce61e82974da717122f615cef89cda9cd04100a3f4fa2fc88e870b2d10d7a4ae535e15adaf48b6941a754789547fa6a793c16fcf49acc54866c396dd637c756f06d458caaf97b08192b89a957564ace6fff982c7a17a2e31c0e4393eaa2db87b007be308595948fcc286d4990731ef073d9cb7a3785dc08ee79f883b352a2f98d000978449cf4f78fd59966e09315f00af3fc7f9b408bbfd74fc03ae091c8e1ac83859f9efa1d1f78f1e10db9accba489de6a94231165a627439d5e81455eb98cfd404f86fe605e103c650133029087cbd2aef653dce4d82f41264787f5bc94d02006231e10dfb31802e9d52fb3d96277c0add8219480b9ec5f6b7a21d674f51b46d88d0354a802d758d6d430bdc4d9050da6b49b7f4b30ac0b552c13985651d3339aa0c309281050b4ac8cfea394236cc0da609e7e904b2159195e69959fe560b265d7682d212ed3065409136028c1381a0a6296e0b1c7c812f55d46b07b0fea6a3c346c3c451c03b24b260f8fef63aa97325c0246fd5ef1209533ef63d32cfcb5606d063cbed33632929786041d91eb23c1b6ce4f8538f013c0cd045ac3a21e793ff965ec171bd0a0537e42b9642b34c221238dac2a9bb72073ef45cf5f82a757abd14608ea9922b491ad78ba3bb9fc7405c6077e5c40193d65d9d5ff7e750ee19d2e361655c4e5dcdc4e5f09357e400891556e5ecb61c11823acb329a7ae7e864e5c6c8c23d75f74b9b5ab47844fd31d2aa0307b2dbee95a1d4c53cd2df7de0159c3283ed866c9232018ee686577dd0adadac3724742074a9a5f37a41fab171400a989cfd0c878270414f62927f78d20875e2028ce5acd0a66db899a666ba5aa361de96b9da3f26c5baa4cecb276a4e5b79978f005b3c25b44f3cb2edaca9b53fb08fc9e1084eab2d037ceca42956fec090a18a154383bed00d6a7d03ccde11317107e09c2351e99af5eea103af304365ec0f94b65a30f7d228c5bf72a36afd4c24c1efc99419f3a0c0fe5db33dd2358f60f78a87c52402324e1dac9722d94b5dc62f7543d5a09e03dc74cb3ddabe0228c297a720f54a740a663202a68d0e04d1367602598a391c92ff047c8d34f4446f95dc3bb60e0e5b86a49ce615ff5df72bb576a04f11d13b706aac6f23f4c81e540d31e5c0cbed861ed42e1b2a948a2111fe46a8535d1f168f9de235ca0c1807d8cc2dd870b0705520a0fc511a2fe5d442972e5d88a1ff98e7965ac31ca22d3ad1ab59b99b12703389017d6c1ccfe2df1abfa3da2c94e9e106b9bd9b64d112e9a703b389c8b3c9170ffd7ba022d5255ba58b040b37b066a79a934e97b8c14e99cc02c64d5de8051d715edc14114f4821039c4a7103750fab7d994471a32b9934018ed0c73b1637cbdbfa5ac8276e26179f5a8826018534ef1b93aaf04b00ea485c9d93accbeb24b6854fa6703077bfafdc655c67cc7565c94a39ce94922c5d64e5ba933bbdc1727df3818fda7d1cca32445f04abcf1be64a10f3d70a47026c02201fa35cec8c5692b88ea2ebcb178a51568d406e51b3a418c592a246fad460028ac0519be451405a592bdd065125d37818f459c1679adefb20963759cda88b6f52afdc628c9f1bdda3471d5b02344d492da4a48a83befa10ef1b8944782701b3c16360662ebbdaa6564130847ac848941251c5b41301c42a43d12e0c6f3defb328aaf8287fc051846758c866c5420f50325ce3a81b8c038780f6f81f11b83250b1ed750f0d2732f332abab1f854f780c34ec4af3db42b048ad3377828785e680d43e4da611d579e97de4b8b2c7c7f8e4caefea89e321b5fe868c617e68dc3ad178bacdac9c04a71a9f4f6e0005d1755752d04bb84a239b5ff2cd50865596899ca1cf3e5fe2238ad0d87e60f9316e150c8d873b08f7a08cc86576b2c79d5acc09b8adb4009c6528a54041815ad12a0042d1a7f5e3dda474554576152339e9ad1faf866494b9dadb37ced17c7c4d0ed7c8ada71d3202246697637015ce7c71d3bd6f1325abf119eaf2fef79e2c15c9fa7325a1a638fbd5028136684fc7e76092aa31c3f3550255fc22c9f1c89817236b743bfb573262098a462b22a4596de23e096f79956d744e9026aecdd18fe05af37ca753c6136534ab3de739f19054798923a4bedc1984f5e92e18a090ade04e7c8e8d41171e32d38e41514000bf47d3b57a52a07405eda8a9ae0bb5f2f329467fb89c10164176e2df92ac84c578c384f9bed282e0b07e3e5a46505e2d0f8e6ef0afda3d054e7e86908b1be913253285f1115b4e9931aa0f7c11823936d2cac2d05857e0b4bc0f558f2523a93f02dca963fb21a3eac080c54cda404946b72f727cc8fc6990d624b86f2d92ebc50d73eff95e6f3d6b9774a943e9c42f027669b6198a80fac4bcbb12b6df2fa333fa408dcbaef4016c3860b18274903728e23079b04d026968e5a3a07282190b052f0fcfc130e0d433a8eb485c318bf20e6d88ab6205521991bbe3adb22fe3c67eb88676c5fad8b9b3eb4a4fd405bdeade12df9fe364edc2114449d2620257ae4c46d534e2a41e5d09707e814995c550c7038d47c7249db13c408c308f782bf85f55d97f897e37a61e813f28e73824720d7517e9a17cd5320f8edb31ed5980ce787d3bc4c490b1067caf6c20448176731f37f323cc8a1457c04f7f26043a3f9d1b8d814e3c62b7c454b36d158da504addd16639b109602714fa48cbd1059970e4b7a2d4cd4e07ea37dfdf7373e1a18fc6a9d5b31497adb38cdf641a8837ae31fa397d79a303731f4ead154cc48aca45f0bffcd6d64684dd7dbaf5c7b87b6a04aaf049400d48c1a297bdf2621252653aa9e6638a24d39c06fbcf75ec2f87d72b15614142d422db44cfeeb8a15c73890a5b597664220c451cb0524579543bff334149951337c918623c4bd5a4b4f2327843ce48cfd78e24b716f18e2dea98361256ef990714f5db2f767dc5343ffb88ebe8f7861d07c9bbcdb843b66bc696174c421a27bb6e98b1b114fb515bec98854ac57d9040de57e57130816135731b67295d3923796e16aad075132da0947464dd314b4b2646d4e2ff48089b4fea90f0461d6b4cbfd8100e64523a02773ce0a3fab64e6955b2dc76ed4eb52e7231cb328c714bbe4ffc9caec215593343167eca95d80de326b113b0f1352add7b31d634103b7100469be7264a03e31a9e18a44eb0432510b6ebc53bad80323f531a8108c7accc67da2c573fce609ee4bd78cce03f17c6e24a31f37f2594b5d1ba0d4b573b1a4341635da765363f2840c748850c44c5abe535e0cafafa284cdd83facf9ea77ab4312dcfbe7079430c314c669efc11fa9730d3cafdb5a700bf5c1dc58443b76d2f1ef700f9935a57321f382e44e6b92c3b700ccfa43e6b9c4caafe48b19672062a126e26f3092168983a888cceb61799fdcf46b207075d13fdce31ac66a0905b6bc7fe3626d19a51b461b3a6887be4c55ef37f25a431daaedbdba49a0b14e9bc0ce4314c2dde4a2f7e8db506d6655a851ee2f2c350a78a5046b25dbfc326643802370ece24a4e445d7deb158c71a9bcbb02e6e180c00fb9eb3859c676d9bfb5e6415e93505454adaed082eb2810f364a619b37a69daad3431e0cc185d5fd28294b4e01ceda81d819f527f032771e97324cc8c94387aa6b67617ad4cfacf611eca215866d6355b14a6013cb2dea0c203d685bb19a6ee84517863e21c9c4ffbe2eada1ddad0430cffc8b49a6f118ebc3cf73bf846dca495129d3be32f45be73d2b126c500fd6e4fac65e5f9c7ae21d922970e43fdb2c32d507c99e60b2d67a5efcc1125302bf2dfc6217123bfe65005d9055ca9659c0fe162ac480015502b28d1fa26fa605e6a1c409096c70e0027cd9d214c8d5c82b8ebcb06cc80c05ad7e8e18cef5974e9f07032f889f8656e7a8187146f73911058b549f4d673f378e07be6dcf456db0f6168fd51fb2916d6081703634833e860f601737315c6ba830b14a3212b7e30d3b7d9b7dd7ab340037b2a9a60715e175acd103c6067dce1cb6e65127357410a9f6bc4dab2980c3bb30a911623d193d1be1162243e4447ad47455db0e3eb7e036f1ee08bc825ff2f43deed1791a4c9484525e3f4feeb73cf85a3cab289544c588f452e74beb10ab51bde1d8cdf162cbe246fd0a4958dd75713cccb3ccf6027f71144df0263c46fd652f25a15c81fec0739798a593dcdddd56db573a0aebc1556b45da8f826de5bcbf40b3760f6c8ae86c870c034fd72dc27333da0c62e04b858c1b0bc2e04896a7edb1bc9716f065f681e97724d7b653f8952b3ef9dab0fcdc95709064aa66041c19153ddb10183132ef5700c1068ec7669da674b56f3ee2111fb33e8d02ee44f8fa49353011cb0ecb865e52d0116480b9673d063f9ca93d33cc429259b33dc6ceac1d09e8bd113e80957871b327b9da37c9f1a6eb120b46ff416836669400c587eb62c3762c35744c22494c6c97c0447ca67b6e60c7ce7aa7444046e40849b290bc8b37208c395251a26e843977eb2fdf64a9cff1aad991be60d5a17d1f74248813c77863f37420065dc4886ff338bd69cdb46346e2d5107b014f6ab990e7169760cb9b9aa42a19f6428ec8fc640a8978b1564427dfae96f63602dd2646a14efb2b1bc191d364bb0c8ef68f1301de8e2edd98260a2a98034a2606dc383fb36e208524e19d799c18a913ab05ddce6e89915e29a26df4be867b87379d22af9b0b60d54a7799782ca38a1f390f5da577087def7a70b9b501729ca66a08e7770fa695aa0e0789415d7e6dc901ca6b75d769a52a86bb42d8de711fb3b83c4931f07638bccbc113c2b5de1126a45d0ef455427a22d79c5c22876cec885b88e80e40f6dbe3cb852057e0610bee421d5b02ff0f956a1a027ce331d581190187118a7988e594c16429df372c76704bd81951bcbc5e109fc56336b71d4caf960808092b06d3bf7301b4839954998e16f5924996e79cb5290c81b96a34d6e067f894cadafcbd2e2ca672cf96352e6064ab72cd3c7be6aaf35a9896b76ce81ec1afa927a30c2562bf7982aae4fde3ee893ae1b137d9c01cf19621788ceda0073592ea93b9dbcd4eb9f8697bd6716c6b3a9cb9efe994f1924f8306c34680f71042b0804f4dc0f600721efdea709803520bb08bea44d79e0aae25534d2e58ab3e564ed356b5a7c4bae03fb3e8683e0e507b37f7e9f1008ff0384017ea1ff45f2d46b725c10ac1b457e8c0dbc245d3b630eeaa26e7177c92c0d3b02c7a364e3ff33bb0db938f51de7e8e5933ad8ccb64613246d12899651599b2d35dda96e99a179bb4b15acb1a3508d1f7b556408691c5f169123abd9c66237443d96f9d4d148bf5c199cf283b5db45b0e7183e884c43865c7f3567d2f7e937198ef87a6266697e3daee88a68e2d374eb7b4636acc77b9e7a8f3cdb7a42fb43b1d531b2011d8aab383c5ed3def1059c01245a681efb10486e94570191376bdc20d663188519153dd063dfab66bbd551373c0672a3d9487d029634cabc5876413b4c7785c51e8ae70dc11f050e3b1a64d02a683094124bf966628b8e068390a815f7f79358729a59ce44697a9c11d2a43a5cf1572287d3835614391608cbefedccfcc730b17c489ce03c5d9954f2f7a24a11236a346feb1d3f3250204fa0eed4e8e8f45bc8e8ba9b10aaf9cb8c086137a75589328d3657bcd94055b85de9971b430508f1f824e7b8fd1e969caa6acc22aa23fb2e904044239d1779a0bccc0f6525acb21e760b624ffe5a645388865b7c5db599d6096723f1e0a11a8109a734ee1f21e84058bce70a939426bee69a1026111c802593595c890746b195c18cd42acf43986405f82389520df7eb85605b81c3d5b4516d771f22a6a89824fb651eba0a60b624c77ccd50a1249b6ad692183f25917c96e447cb60122b5b911c774692130347d8deddf74d9281a088b929047ffd07fddc94f6f59c8a249a7d0137f038bc0c7ddb825a6351636ab377a54217c148ea145fc2545f779b4181b8403fa22a92389685c9a8542682534c26bf4a1847962bfddd31fabba703c94619ad48e4c982d5e71643cef7e1259a7109d9e5a7d281a0ebc4347120a4244192985f3a5ca245e0f8ae86700ed946f00a02599e9bdd1d5dd3be72c471b0f3074a15461616ad8f8048508354b727220b2959104d84b80185b159302858c7a139d2b17d0a32c9594f4207ade5b51ca0e30eb67400cc8e85b50a5f28feef9b5be983bb277e40c09fa40520957205cbd7f3e993383b518d2eac89c107aa03299086ab82c94002590122d423526b08d0e6fdae4b4b2c7ed2b83da3428fcd8984030eb5bfa2a093a9203b6954ea25cc151d73c182564d38022c89a43f236e86995f82b923dc5ebdb0402826c969d42fca782b95fe01ed3379a50239446922317e67563af0033351bf28416815746cebc787ba436d66ba23a3d0308a2346ee384b94bb48ba865127928b9d220b48c97efdca93fae75e1433df6f9802bcd50becb760302e69177285054448c61ee5f76b9d570f9066220534a11d86deeb35f7ee18b9d82a82e06721c1dff1fe039cf0faad120edb8aeddaae051777bf11aa57be06d74615d0772cd1783234d8fdadb3743057f6422e6ad6125ed2292834d149219f63e05f7cf258f0c8f5e5148409116ab83d7f731cf02a553f81887b3903eb4fab00aeebeca8cd29366ecb3c91580ea15adb83aa02e02e07184df61ef5f15985e1ac6db9d976616ac85673fb471c2eab814a2d23c4f83549c1ce7c0d8dfbe67789fa2b0b09ddbb01ec673e709059306244e9db32a7cd0f4f9f2cd4658c68a1fdd8e6010e1d026bce66ab451045e18f861c0735c3a60d6f2bb220111e90223f5125166e66282b72db65c4f4f581eaaa7f2b79fa23e0a33bfb27f561346031fb0812a2a1c6155af99e406a80c33baaff903441c69d96f0a3904c56c7e35ea3901fe440d13c6716121fa25d7e49448a88157eba6f650d50e02ad89d0e8dc02ab765488e049a1e701afb1061de9b4390aa12428020f21bd9a0a23f1b73bcd8de32a4d076c4ed6d0edc60c52fbc1cb0c4cc7850f1d10755faed489edc0b925868d0981540afbe5ba5487bc28d6ded347b0d0a0137d4732e5cf996161685018e3c7d2b900330f2667e9a82bbd074b4ce64bb85e6f2f3e28785e6b0e2b99a4785c3bf403eca880bc787965b5079e63f5025e4c4b3cb3ca4d7dd53b4c30c0322b1370ce06fcf188aa477bdda064c09cd63ccca775558d45c9d127542f3b63134b80f82a53b75091b826dd0d446feaf9e97eafbdff7b7eabd33366b5310103c652141d439f577892f5d0eb154eecc3ade4eb8ad9c26eb314d8ea205e12d17077b752e21292bd69a9e3a5ba9b2a786956328eac0d35432dcab5b009d03d35f7a34fe39c42fa9e49d5763a734e8b0d3f9539d1bd0c3288bd6c26c4d6a7c202286ccf43145d921d206c7206234557603067703d32c5257bef912083ccfbaac09bb3846417adb8dd823a047e19bb001633d6591ff6565caea25db2121e10ab7a7b25ce6b28b05b821eb41b5d1ad819fe036fa53e8817df628b4b7681810fa8dd9f2eeb6197ee37f12dabe44791c2063ce607c874e79683fd441243d54144fd2a40475b772154dbb2be2330df1fff6db04ffb82c39c8bce50ccead992c56c6f09dc36197221b7fef7ea2bea65b7206237d32430578188a4ca203f7b1ba94b012d16bcb1485d754912f53749c8d760aecc70fd7f8a35b346a6efb530aca2d1a7bfafc3404170650429b07f09f72140ae078798680edd8071c8995d0cb9796a691907975b6ba8168d7e9973c287397dfa401e8ad47bade0eeab76fa47a102e707c147d960aa870f99f494c4143e571ccbdf32f79cf6134187b3170f5618ce44d5be290d31d9a19738319a00e66d451987c1acb5bf2445fb02b5771193aecdcb086e1281e6c15c8c13c7f8b9bddf936d8ba73c41335b3807f493a4e581e8b7f8b066c6405e0562d0f9737014be10faf2b3f36dd0fac95ff0022083e00425cb96bef9b6477dca946fe1466c367662aac4e83c2708b9ebc283e4de28d92316d62d335ea005fd531c96dc34d10e36af8e8b3d8b6a7912a30377c8ef8d0b7fa914b95ade0855ef8457a313ad35bac31ad48059abda2ffb4895598d1ebc2bf805627f193a4b2bc61f2280fb75aa655b0e427a14a0e79abd5ff2344c24478885eedfffd461216c5627c268089e8b5a16a0e5a41027543e0fa31480c212ec46cda9dd4797edad82c9fbf385825214d9331362824742a45970dfe90b3a21d9ea124ec478f86011689493cfec428f9e78477c42340c207ccfd9088861f9897815185850117b8fa94e9ca4b8684746816948d47485dd40708bba1c218e0da74801c05b190e0412c20eded8216d4871d6a4b869e65a1ae2462f1ff983a71b757c8c42a8dd375130c6a32121d22bda395dceadca9d2bbbf0677efb43fa0ded84bb0f40aba920317f0436b35f96c0d76ac9be17bb87886d4c745cfd416c4e1b10aa370ee30174a760ea796a2d265af60eae5f6a6245bf28a8c3be279d4a1781e7e1893158f133ebf1d0d7460817f465765a0e545c8d61b0d2547cc023e62ad2ee741798cdaa218bd753b6595c6076c8d1f0da89589ec7b07f3671d098a0479b70040fbf3437cbbb81b60433434f2795328a0e15f58aa42a61654e29332cfe10d6f25efc1b5d40c0520b94344d9e463a501b9393e6cec1fef15a55807dc181bd0b75faf9d0324c9c216ff41813fd617de51c93583ec0123982bf6c1749db84152357d2ea545087d48b89a033f4f54a8372d4ab56ce3b1ac450d81f69053ef372d379a1c7a0540ac7a24114711e08f85ead3870bd92d92db746df7cd7ba24bc6ac19eb8e1a08caffdeca19502f4c90337077113f211db1055bc0dde8fbd8d5be02aed29fc06962e91aac9dd3d8858374f40dc06db90f9a9e588e6f6fd90e20b9063e57183cb544e726ec5a94a02839308859f2cc3a609639647c80e81b0ce86376bb8b1085080f705295010f1d3e3912634f6b603d158acba7abf7a9f815e919988e16aa9020e927da69bd4adeea9afc705d5735e81e5adbf47643e88f9629a46b3971299bedbf2e05d1c0ec7d4e7c3219b256500df450d9042c2b2db7fbcaca9fbf282514d673b03514b03c706504d281c1fb9af02419aae94e1dae558341596867ad56a2e0d3a98169499b61e9c095be1ca01b09be153adc014935b2ad29b40ccb45f52c2aa089d9288f5409038acb2094078045267b96bc6596e498ff730a34f6a4fa6e2c3828de795c649a2866029e009382fec8a0d92e90da0cda6c2b84992ff75dc7be6b8e5f39be7c1ad5c4fd4ac5704bde5a2a0ed77edb3cc47779770ff44ac4f7be53e739bd0799a420f46217d1e6a9fcf876111c796708b2a508b37088aaa3975ca087a05ae7c259fcec9d83c3153d1f8f5eea9f17a8d6412950c45c04e91c8738793e8e21832d7a2a2b52755452dd17b53b1520d6868a7119f94b56ec3bf9ec27754e1f8ec30ee56eca4bdc4009a60f05d3618ebec78d266e4da293bbec28b05999fa9cbc8abf8c2a95634d1996c1745d8654e0580d41d48765eef94679790861f22f428872c64180283038dc0c741573e28686907140df7d5e299e6c5b8a2ef05ac1ffd1950ec858bf4780ccca2bdf06b42c20c51df415976a08fdb1dedb0fd7d021e3e1c4b2dcc5d5b5d77a24e671260a4237b29981e0a5c43558a1b56e636f97ff5169966a2ef2282a1ee075b6e00431a936e130e9a820a8d9ae34191240e7102eb753c8263f83afcfe1624b4065d3cdebf60c476c1b852155f6f8fcc3b2bafc64d9382d1cbd11d6e59c36f1272adc52ce743aa3c3d9c96b99be2f071e2704b32291bd74a80c2ca9ea9a26e25475cd658f864678efffe1ff456d9276370dc58315333e6096c1f3ffc30a1c4159a64c8591a4b997c24c3a32ce7c1bdfe84eaec3a07d0b7b6fbb8e374864cb49bfc3ade10d9babc5fafe88279ba5ddb805325d88d7bda0e4f229cf694e2a2187f894df0fe1465bfa997d8e10c66a35ccac58dedf0d3a0010b24e6a2c12867e83edcad13cf7663ce119bb8d48c0c977e3319fce73a6d3fb6e9b10a7fd9893e3d5d236c9cb03b0b0ed3680404075212903fbb664189ab5b9d3c5489349dd64a81dba502dffb2f9ffe2e171b36f98eabe52934f7d58d4a893da075e9cfb61d7f80d53668f764bbdbb2a4b0822df2df6beb583810601d36bc0c180e3683e3cbee52cb4ded0e4587c4e86d9237709c9e2c93c93e133136c4e3188bf25b8665368e489bd87c0e407faf38ed0f8f526d25d073aee60fd01071defb843bc933eaa99d4c1a5bff5a650ec5143ecd050a360f9e75cddb7f711fbba8ffbd2df4e509f0d2614d0ef85602262ee633725de6d102101ef6d8080c0fcbea500ea1fee0f981b53ffd6f77b735b2a5522b212d201f8a7fbd79081ce748a4f95779db0aef77eedc3afe6fba12fe1a6414c2f0ee5133726827bd1dd2b788f759cddf5b215878a2cb3aad2d420a6574352d733d389c02d19788e4bb9958bde5cb86dfcad33c24d195d56728b15614ea4a4553e290606bc8f0103ff3eef8b7dabbf1cdeb0db1273f37de761261bd966393628017534dccc4f3204588bfbc37760dc4a263944fc2b35a787acc4f6c6e912c458a08ce238ca2e104b6f8d7e7d43dc03bf26e3ace8ea7170e18a55256cd694ab3f32a3d838351ec47add1443284f26f0f13656efdeb73ebb211cb726b28c5f1c6519193212b8dbc8042873525d136da06596a3f4cfed931766ee502e6a1968b5ad5fae3e23f41aa4eb59ddbdaf57b75606eac5d2d8cc14adc5be57b75738d49248e2e611e8e5d88034b2aff775df9f7d36f132dc2cd385089ac4e61c331d30d995144211ff08eb37b85f8aba618c6d3102971f07c0dda6646de24e3f92fa323a029611f0b4f9a5ccd6e14c1429e4e10948eeae99f1b40e460a17e29cad00a11d88f1a4fe7055e0131a7b2091cebd4d2cf1e0c08264fe128cfa2f95a2910b37d4ac2c86ea313e45e02bd49226c3ca7c0e8e3573b788deb087f94337b62c134b12a3291de3d35848974f950ec4d77822c8d0fbacfb3f814104fae5c3c46bdf0907617a07deb27bafb0cf0e82f2a103c0daa6897e9e017d988b103842dd3c258b4b5e7a99f77ce3da4985507132212e56558983ea53e23c52ddb4fb149daf24cdee054df3e3f3863e40450f2ff1d892306f934d98e029fa929fbc799010883e7f5968d932bae83613f008043a3abee220b67315e0bb8c6a89941de6d4b90e1664d88cbbf4c9a78eabe9ee1809fcd8b87cd61e8caa50b663e6b308921fe509f29bde6deeabf577cff906883ec57eddca4d29d5bc4ac010ac5ce2a14ece0fb834e5e18b7b26ac6bd475119cf9f0421625071817b146c5a0e751b952fac022192f78050370ea198513055291067c37b37dc3b51042815482f41dd007a5b7c80fff57c941e1d7b1f01f0b196257e536541f3a29a0723e718a19a188aabe6a20d630a466cac365d1f95be9484035d100b48b29e141afa16df78d8e3f0f1c9e534489be19d2ee6389811e86207e601fe5afa1824d730b7665c0ba55958d68f7af6a7eab9ed802cbc32163a2418fef7276d2eed8210729d0829d63b1e5a5222f55dd2b392a8da58b34754f3606cc2b723a5a3ece8f6389baf21c95d91d4743e1666643ccc15969fd5141714b30a9a73d647f7dd4b4b6ea2380b9b2a33cfe202e2ce94f615782dfe4f4a61c0868be12d6debaf37318f32d3c59812542576e32ce58b4aab773f2d24ea282acd03fed7e727bb407b2da611f8c1f59ab4ac8cb515a1cd96a39871e5bf0cd7237665f2b6e7e3a805839e3bbf2aac6808e8b0434eea516d7255366e13754cd3cb6439b6dd03a5d1f62aec269ac1cf670d4bfcbc297d4418e823e8d63f2a256a142a31c327f3e6ee40368f465e07255484f8068a1a46f5401c78a17b8a4c0c39402de3cbd71cb294f91c5a3d578fbed0207a363d35a8bf7fd5ebee5f7f3f5737adcd4c7d390e04a24b87137b36a74dd91ec62d197570a677cb4bf4b626056b51ac28632302761c27f6e8f4814ba7f88ff15fabd97bb8a4f9872cacc1e970f12b118f235aabd43fa8d5a5fcd509abb03d46c26b300ad24488c9291aa43a086e0180947840f0f5775e8c9b4e5af33e4897857875e22c35de80b0d249c0faa929f73ab4541fffa518549d436de8caf339b1f3a6456b35eb199cb6a05c82fa9e96b09a68f930e635e204ee9038e280094a783348feba6158fd8b41e3f8c66ea32e071e066c0b9d048caeccf5be097367484985fc5a843d5b0f001cec072df05745d47957a68a1121b0a7f94ff3d732f865b7789400641ff9a545f2cff2a750601a287c880f6b7276af38c4c7582acf5f41461df3fd5d2295e864e97a1533bd725654f94291737eeab7629ba4750f9118e8b131fd0682a253097fd78fe4267b9662cd7acbeebc82318abb7886688a835b18fc85b4ec91ab0207a4afa13f6ad192c09808fa5ceda217b17b0c8d5e7e20ccc7088ded78678f66300a2a982ea80f0534290694b16ca53e9b8e389480e7c2e2d733dc9e8a2378b7a3157a0bae8233885003ad7ebbd501fc96aa7cfdc08fe688c06dd261dac840704b43542b9e5389422846d5d27d1950c6a40e800f03b07900fd9c6564cd312480bc880d428ba8fe4812475a41c3f301b4af8f19ac43d371687a11cda8fdc87d4868f43c9991e94a9b53c51fd67b82d559c24451933eb22e9dede2e0946d9c61cebf2bfe09d94eee6f6e410c595d2e770fab529b2a2f9607b9b2280e320d7d6b5ca1cd6dcf9850aa300c5714f4dfcb6320332552bb45667b9aaad4118faad946cb3bfa1c3daee34b99756c7eb681d116e418fc697e0eda2d872b2962701caba7942467c097f3bba2068860181e3f935d04292c19816a4d46bb1dbeccede72b1b00474b1de160731dbb3029763efaf1dc8c5c6a2ea43e15118896686563705eb7c364d9d800912f1447dbe0a5ffd5fd92234eeb1e312132d7f1c7cbc80065252137e7f842598d870d800fe2c540285449058c09ed2f1b7f5171e8ad80d18000caf9840ed78eef4e07914efc0b3829fac53f21ce40d17bbd8c2ffc9ace978909d5dc244d55fe03bdc9e1844696b4f4d801ae426b0ce8a86ad3e16ad7fb324039be10bd8162d933b09ae8d9520be283a500dc9353fe8898b70bde56d449fc091389ae4cbe96d2c5ca8aa791f838d40dcce19b56ef6c92d88d79b0c9e7ae87de26d47cb540487b80ec513c7793d904038891068f0cf1698819376fa8b352ce56adbec09293568bdb4e099a58c716ae617b69c78c731a7038166a43fca05c2eaef19caa4c425053f957a47826175372a125220fdd58ab6f0d02b12da8b56926e04ec4a8edfe9fed0321aadbdd501a94019c2bb96fdea3ba2645d1197841b2add2fc5d5c837b3334714ebfdd60ea9b6d021fe7fd468cf58edd8c6ed1a90222c9874f3de69a26b74d322bbc8942abdd1fa622934526a0746b69b2483032bc7a789fb33bc94d826ae63769222b50a0a67be7f804ed819eb556fb35bd260cb2857a50cef32164bc6c414a78a1504bf3bd08059109cf57e9611f55934e1179387266f1ec47477506e326f7dab99261d568f659379fbee0cf38ae81c0cf988e250466cd033a70de8dcfbefa0c58c2ef707448cf1aef0b7be9415b08e1df101fcbe2b49d1ba5e1c22db2983ed9aae7a6502af143a479cad1c3221750fe03ebc24057c111f856b36dcc3b01f127bc283c69a54ea4b423767d06d7a535f4c51d648eaaf655343005c03e4713733f39715467c129436c627b526306527dc8d965421ee4921310441ebcf07dcee60d92a87e0f3c11f1d436681e176f8e81a56f78b20e07608a114653800c8241194c14217bedb270d0a85e61eb993a29576cf77cdaa2c79a4c9b5026e1172d0a30a9c57bd3236a770190846d0be519b60d058300a18481c07cc0d342691179e2ca010aead2ea8dabbb103a2a14b3fc8aea0f9944f75cc2bc48cecbcd0d254f89fd473f2f19ba1c40cd0e2d26a1b6d98fc92e3d585aab68d2b38ff988f7a16c9064f9bc968137ed1c73452c009a228b8ac0d224352ca052617734cd24c610cb1492250854adcf81469a4701f8d0d02efc3e944dff76e86efeedb3d8c8e9124b42fe6c81a946841abc3490341ba4ddebc39dde83466e3918398f393d66f256664bd89cb8b57eb423e425035bcbb8486a8715445c80fcd6c8dbd335465fd4530abb41f6105525ab9d83cfe30324fece74f59123eee3fef4f25fb25a9189124b55256fabe9365ef435e16b48bb78e1b75fa6a0ee1e4c383514446b4d72e95c2e36555a3cad7001210e4fe7a67c36cd58cde12a657b1402ead77dcc32db34c1dd34a3628c9b518e5c2695c437d9d3e60792960a7ed673411feaa3cd07209dde7e6c0156283eef6dda6bb9aad4c57dd05c1792c6b607825ab0b47e4a9e0c267748328477920056abde478941f12b0a8a38fe9bb5f695b84b82e80f24a74f13e96b1a8e0b255022170b2eafe70d3ce53f65c9afc4fb8348b90598a9617b66591634b525657e3e24b08710c06c5969bfc6ce0d24ade764b4c2d857ef0db3e50b5196f1c5f1a827ceb5c7cfbce58ab28d37ab1dc9ef3a0c8ecf252b806c684fd4f75b18279bf812e51e4350b4069c9e2ae22dd8f181cad06258a8c4543d88f35bcb540c95e13347d560a0ab67a5a1c135ccc23c490c7fa3c3e934020ab6b3652fb1c6b5c819c514b582ad5a66c4194ee2a5f4edde7d824fb48e8371ca629667b84219cc30b0fff6759aac367349d83ef960ab6865acb24a6a7cc7eca1e8452012f01dd20d2b467ad84f033c7881c262fbdf4e60c071c112a9962102c8002d3aee0bf2378ca56f129da8bbc9c049330010936b92dc63e9f5a21b998630eb5882e2b8bd01517c0daaea8af9aa2b2e54dfb53ad7852c95c3b32a3a46cfb7cae9fd5340afb0171f63ae53744da451796bc30f3aba41f2bb99bcca0099fad28ab7a813f54677c639b4bc962b5a9b77b24e0852a29e4a0b720a926bae75202b9f2a44d811e7c823b77d8219fab97015e10d8e549aec085aa7927df32b558c02fc4db9c5c7b81f5f3d9a29663c3cdaac81f0f1c167405ef2e8e2abba60a463ddf80d1337c55d133038429ab6217a81908f5b9b9b23517b964a37fe090ef1efec62ea9bf2a14fc7e18ef3165dedd63d3f1bb2c64b925b6bbf51fadd04de5836e74ceb5cd57e2cc8a741b6d6e24145e159d1a852235366816b938492f085d98bedfa8a955d58c7cd73d9ae548a7e5ce6d0c8b7291548280e3263408800231299049872da1e42116a7bfb7afe14097301e2d0926116728eef9db938d209d888921b8aaa12993f6570e728081aeb50bda2c6ffb5fe9e9d98e33bc7df9d952a43e140d6a3b06e76220b769733d9b81bc6c2c7b74e81c33fa1b31e0dede5df22b7c189e1848f704dc7051eb83334187b2112a43bc0628f802356719b0186d1caf84238b2af6cf719e61a27f640b3ecb06d33611f929f6145050c43ef8718cb099ee9ce4ce008bdfaeac68b59ebf36024393e5cf679ed5271f8d53539eb40c316ede5009962324cb1fd7a8beefc1ed507d97174cd7e7cc5a839f133dc90d0fb171a8200c3fb463651dd033dab012b34415ed13a3afcfc25ddaa462d1420c6a86410be35776359938bf3ba99cd195eaaef4709754cd6000c7f0e0ab62f49a92117f2ba9c603ea143f24ddf45069b263db0fdfa2f09697ecdcb2da448f9d53e0c029e068e539b8c2dfaf76d382f9ea8d95304f57c5f0171224e85262052032ea7c2f1a0083bc4822480eb55e2e09b504a5a8bff361e3378c38fe8c20151cc774a8af9558cfcde866f858e6459fd3608b1e13db70ad36cce5298769b27a8bbece2c99dc99f91089a506e36e42d6baa71d396735f3cb2abb0b3d6250b83c0528c2b412ba00be3c95ce0c83e50ef944f05dcb454bbf7c60ab8ecc2ae452d0beb89693385bda25e7f87e19a0cade78ebc2ccc1416076092a42edc1b52ad8f1bfeea5ffc8f91a245cfba7bc607184bdfee0033361d118fe7371b061395de9c712bcc649b4a95dbec8a29ed3339f83d5418484730916d243f7a3237476e588dc8a5f6c72e2d4aa88b29159d5fef08291ef07444d588221a63af7992fac83ca35409e09c5bc23a72ad641221eaaa098c90cf6383dd0219c6fa8a6efc24cead13fe4999642619c61f7858b484264fa17ae8da2ad05e86f1a50b537f1fc47ed14579342f1db00b1b85d2cb9cb5b53590a0878cd7423866961ad5b776c6828fb819d78f5a2ff62792a53e8ce6d2ecc94a3a1cfa635b8bf9a5a3fb9e61888299662ae648047151c46e303264c517b5447c3a095479edcb64c65b76cc7c5d98b6d191797d9e9605b5b4606f379761fc669ecb196aa76c9165a8e80e2c021b36605729d9243c2b6f0419fb9ee1a905cf82adee5bf298d297156f1e6d943dc70a3fc40c0e07c59e9a9866f6b3119c7549b05bfc0c1bd3e652f4751b8d56cdd52060976b4db19fa827e895efb7698ecabbd038c7456e29de81e1e061f65075f4c8244b8d4c004943b266402deab8b2921e55c63c5fd751782cd0201c78070b68a5ae6a2b21d9fcfe3ec6ed896f4f3386c4365fefde1b6de95fd9c185238b206ef6e10ea6dbeb4e1f9ec4686d6c5270dbcdef08ed73bd33053e2f84df5ce6bbe5d4678c07df817f9e0f9a9baf629483209dfda20577bc5192c09c89238e8c98437e22a4b46692f003028a86f8fbd06f251d6ffc0e9207daa01de51c1563843888744a73d8b61a505fc576d26265e4c5b5d232b2308676189173f20d26127276e98d40b9a3ede0050b2d7c381b7c157555bb16cb36a9498630a6aea33564bb99bee57596f0a92de5f3da3f8801801161375ac220c96acd41537540fc6397098681da7fc45d7b1cb940959f229320d70ac517ead4c59077e46e9abc8acb386008f2474e8adfc9162cce5f7375c3e001e84f69498b4c7b67b64e62996e033e9ab04d7b439a04e8ede2510431b08729ece639c07ec3c9e5d7dc4ec82668e08e1b7f5d6489bd065e8fba125f505301951b0a985c7f66cff44cb49c7b62346c0301fad1a61c6db6f5b09ef16ecabb60a83a24398412f43843ca833f1f363f847155d5daa59c17728f8146b315d12ca8c238eed165b0fb01141b9bd65f0e6730a32b3b6aef82aeb4be9f14b993e7041b327fe9f6142ac7fd3654c271005873a6a41d4a404bfbe05b77c3d94abb1003e7a9daa5f6e52bbdba3eadc26aaa4fa43be755a6634d5cbbc6bcc87668b4245d8076af5defee1593d2e71e0ae0b269b18ce6051a6758669b4eb5a6276d280d7f870245c3b185c92166d43d6f026050714332d109fac8ffd3ea3ca511740b6d1d0e4d47ca048761a79946aaf5177c8335c3a622133500d192f412973a8160e464548a00e3261c8ab390fb2474ea18dd716bd9b062261e7e8f6e99249642e9aa618289a3fd9f6d1b925067b0580ef27587ef3fb9f23db0bd91b3c166d1be5e962b9320261cdb07a8f9df29fc698078a46b9c200ad9cfa94077537d8b1aba332f3c361bd0f8fed83762cec4838dfb2d861f48f1dc41636994641975336f0a5e667964951c40aa070a4812bf1fdbb01d8d0b73b37c3886837a06522a61d8f396e4509eeb0d238bfacf05ee7afec6b713a22be268a8944d7f0f0a44e3480e922bc0dadf40caa44542c5a2759e4331a975ab10f9094f1b56bf23cbf8d15386ff9d0c5c47c6e0cae4ffe5046c4da0ed542ebd3f8869fc872b1b71a866add2f050d7eab7d293eca5a86b072db2db7283091c218eb969220fd5a3f3d18253a23c0852fba7520593d00fbb7b03a783bbfacfea0b50c41d4549a5c3582f0299f0d5bfd0f8724f06fee71eaacc90724271b09b482a3ac4ab3f14b5c4b356a0b87bb83c55bb812130ac77fff131eed246bbb5575c355c241787232eb2c85c09079d01d20f1dc3f04f58df90becabe2ae8e4dcbb450b3e207d64be969a4fd136a2f8a051240f38a6f65210a14e3ce9eb575fb0774b838a8341fe90959a29a80a892f5e86a819bcc41120162f2248a13da26ef90785f240bd398039063e7d748fd124885cd07ba3536280ba47baff810a84a828e146b5219bfd08dd867ac61d67a3a85ae181f3be78e15d4eb74737bf7f79c168cd836de2c8bfb2e21d4fcb049bfcc594607c425de3ac4bb1459e07dc1e28f1e02e547007825fa1328034e7c2e18d03be8b713b4f21a24cd132e14ed7cce02537fcfe7696eb7b95b8ae96c0b6a8e003c9948517fb617be3ea21f5678336078c62c68b460a88541e235890a90b7282ebeac89c44b700d3f1513da84e1c9b8fa5819f5e6dc916acca2723db81fb1557659c8ccbe2b9e35b997347c4b5dd168d0ef4113a60c1e1216114d7d60585ad20f651c76abaf908d6da96c20017f26f6702ae133d2cc70bc65c43bf1e65f697d2e916007cc0c68de275055c71b0b4a35dfd21fb7d64633a04db23f49d20bc194fa4f72c4a5e08be701d0f325a0b1340e3ace5c979606571cfe042cffa80ca1eb922d362d1b968f8750f1b95d200c45e9ddf396b9f5563d7b47a1f1fe7db27d31bb6f415b9de9f32950ff0b443e35bb8d974d1fbe2029657c4334db586e8c440021b1119a8c87a3430e6e8d05978a21ffbb56347c176834fb1eec0da0a6807743e814e575f3a1173d6e11409af62e7ed7d160ea76499b3849dd551ba9ebab0a1e4f7e89da279e443c112569c9ef0848e9b88ff4b72ffef58c9eebbf0073fa80e4f38892c6fddf1e9ed68a44ec631e06fbc12cc8106d7ce3c89172f5fc37e65608550fbee699a7e788cb95e0fae5c8a36ac4f47a6207fd557fdaf3cf465ddf79da157652a67562f66683668990200c75138a4a210e439aa8a249e804423807e69890ac91c33febcbb36a947dd85a2106f22361e9d93bdf7a259a9c8f9b4e0818e432ebf4ff1290b31e282237ccf5cb17f42b8cc57b9e2d73db46c8d8175dcac384283f3d841c802af8ab43051b9c9ffac2148e8da667ca6a2b10ba1ff67ee4062bfc5fa66ae5d7a542dc197bd3bac25055683d719bbec07689aaa7099c3c00558745e7c1cfa938e05ceba3d5ee9cf2e0b7048750045011b9133d8d63ab2fcc076c41fa26bce3caabfcb5949af058951d9ac53c22c838d68a4221c28b3180d38f1c8b46f3cd4d9f3eac2b941dc718d40916f8311380703518ed721c1f042d7d18268f6e2239166001ad003339fbea7c3fe9c9a203a50e3433c8fe633879918975a8cc8a5774411bd959f69d573b791a2360bdb8c1ec23f7d5e0427b7e6780199c81530dc8d21c12f14a024f03e220a49b4204c88012c48397306736c16394d090c096fc0d75f5f1347e128077abdc0002016900d5fd6ff70e360b6ffcc1f2bf3c03b6d5e1496cc58e8ad0d6e162847c1eb282b5909620187e6800a636038096b4d4cd9f097b8d2903e531bf674e9fb159e34b1b1050521639f9d50f083fa5128c1ea11cff78f022f2b9c6729a1732e93258cab6f88502f6d7a222ca9ff41cb81703726a7f250193ce455ca70f3f918388562e19ae35e374d6aebd4763d226caa9bb28915577eafecde1ba5f28b47caeff0fa4ac42608066a6ecf646ea4231001d0386743d6462769f81f71967deba1117282c90958d42bc335215a451f3fda094e5c6a927a10c10312188944cf17a4706c05ed4e344c37d3f3e0b50e6f3abf3138f3b5e2401c84e10de31f09754988793241dbc580e656837604d156e3d5abd96dbd549e9d31c04b4ec33de7418904545294910ed2f60c70d3aaf74325f38e853b9a4beb41ee442ba49525fee31c2d4e4f2acd9913a7d584a13e6d793818b80202ed4571a626e7bc3e4e9fdcd3f44521049f63bad551b6c733f37545abb4dc07668a2f51e99f35d4338de4638588c64d0a17619c96f6920884441bf7d563c744681108fa96223862ae7bdc4dbf46eb1c4adaa31a40ec489ebed66921e3d51de1a31dc6d9aab594dcf94eedee1ec71ca4196edc8a7674ec33129bd56a616339bb502113e16c4e888b5ea4aba1c5520051dba1b438f691deacf598c3c9151c28df5961fb637feea239dd576582a441787b5f364c864fca9c4aa1679fef747ae3f488fc032921a30be9ec244585a2564eb7065fc6150d1b621b4026013e5abf5d057b53190f08bf10723373487a637355cecb13dfb6e29313157f248c62d3dc2308daf3f254f06f3f70238e671e7d9440d80e6a8da5ab67db447d51c519121fa412fa23d011afff5f8c5c0be0fab2b2da751d0d16adaa32cad97e7b753a7ba0111ce340114b38145c66af14b10f34d600a5782e15790f72b7abe4b214d040f843e9472679fdc9df40679c7da2177a6b9cbd087dac25433e9e7e549df68eda3221fea3f30d081914b7c9a204986c846db6ee2941661e60874f8b752afa147b6440c53965c1aa75d3dd457c9afd7dc687829e85c384efce6a6b0988789320372eddad3e957c20b7c03ea4e777219d0b636442f2477f060dd6385946d2df75bb47cf4f7afaeecf1e57b74ed179e9aa025a29e435fe1e7f7b7c3e8aad1e88c6d608bbb49bf0c07457f9820d8c9efde01ef6e8e72a8441f6f4b98e02c9a527ba270bb0f922788b11bfdf93fae5645dac0a6352bf39ef36729244a0245acf3ebedaa4089bef9a624ab56d18f03e602f773d8e6280ba3635f55db76e6a00fe2bf95e564bd954f1403dd3be0cd9ec81f185298d9ca704de1ea97f7694a973b1f5899bd67f12efe210fdc0a670cd4689cd43ed8e56383b01b84074205f22f47b8933f5954018ac8d98e61c6573372978f177938c1e446a80284e0c28d23103adfaff4b27d24329d1d685ad791b957dbfb0fdce9d208adeb927d9874aef367c0004c13ae0a86fc3fa18497c5fd8ef2d92efc176feb21ddddb02510e9888070ae8a517ddbc7742bee4b3a1a03a03caffdea17fb3c886de783adbd0750e388d207babb1e7de82bd80ce0bed9e949fae977dabbfe6614a4e881d0a51289672a5ead9a75dd32238660e11b59c81e48df6a45407582d593f8b3f34f79fe26aa040c5ce6849287c31384326c94edbb2744472929b3412b4b084b996b987afcb18c24b8ae4e0550b5c0eda1110111a011ea270c18852e70fbc38b29722e43fb0db79bd7736b1f0fc519e3ce6da2acb6f297bf610f9a7bdc60bc318ca762af290043af03e799962b1018f497b132476b87515dbebb7eb14cb1c28e587c58cbce3d33d66e9c90ed6b768795c83542308246582d4333971824364a40ec7c3990e73bc0b9f5d4ae59145dec0809fadc3e0160475703aeca8a9088530bb7c95d4aff4b6ed6c9d421240b7b815248c823f03397c85e2a41c29a94eb3eae0232027c3d82c9265dc480afa612fd78159eff068e81da3acd5a3aecc341431e9d86a610f2bb8e056707cb3b9f044aea4178e78bc7f0d062b51a77b41e6932f133d11075b4861ec78b9c2ed8994e2921597a07a488468ce35fa15ee4a5115a5197f62a66329a7aed8962d0e4fca1e4e3e7f92286fb70cc29f96fe414f43975e9f1379323f2cdabd545c5e6b6391afd1f2b30ea39c5affb62ee9f89ef15277f7dfa2ad35921f0b3d2b7b87df6922f8dc7c4524ed7bf955a554bd5ab27b7e761078daed1dc56bff2b50643c44ee6a54dfb705469fcc90078438e330365e89996268fa47d9792841c7b09f9df2ec14074af02cb26b708c85943cd94364167e06231e4ba6c31e46213787ccb67e6fe47cc5e3b6bdae95d6741660898ca966bfdc8b434b673385ee702dc321c93e04563cf5cf29e95e190411f7f1519b0a3ce6339759d0753b56028f702dd83be8c7db0893ab19dd503967060607b7425838271edb2cd2dc74dc530760483186771ffd0c9bec7bb086c4f420bed030b5424c1f781f3f9582156f54cd54a8eea0371bf2a39fbb647a9be623314c706390d2f1cf636b883c543c08ac7ba16aa77ad9a4667b93cbd15769a0cea2c7e92d600cce287f8b73c11497ae1f04b54a482e9a7573cf022c468a2a8b5b02a714cff14ac4c7bbf127c0fcfd47f23f367226806faaf7682b73b178e13429154edb5e544c88fe63f4305ff4baf5e7b95d0e53c4885053be32053ae00db3f4f052d4a30b05486a1dba7c1ae2aab3bf215078dc9a632442f09d8b08e9b7f5106eb72db85f72d7c493624505abd09c32e6cd49689cd0273510ff736057bb1d80471be62c7fc1507c11ffe57ee1147eb8d3e2cc2dfb8a3b6006d9fdf8bf67270535d3ea01fbc055c7c3640ffdce3a9cf878b0b057517d7fa73ce7f752a731676979663b6321f93e6c32cb615ef3c3b2892e16a83b1dc250f8902d28ff9163647a1b2531d843be84368ddd9ae942aa1e1a912462172cca85e91c173703a90ac2d0a65266a1828639a47313bc239eabe79412b44e96743a004299cc418c7a733d5c1d5940475d0898c96274632f5811cdcefdf03ec5b1b852b89a350eee2b0eba0ba749e872bcee48b8991781ed4cc5cdc4c5c7942ff8429f3cb818307b3e9e359cd3dadcc8dbcb3e0de0dc05b0bb814d065ceda06f2d07149510131107202279bdc7e3bd2677d51211f5865da3c003ba4948e5160db9404d879ef3d19f6b420c1613f10a2dd068d0424b18b7dcc36535aebf215aba4ec8246fb4c833dce17c83a06d4a1d00960bb1c51af5d1c57e5fe237a8d665197b2e42c956f8a1b262871ca2e791d1a93918ac3450284f2b143197a36e303a9bf624a6d445384457a4cd8bcbecc86e83af04a31bc05723f1e6cc7728360f2905e2586fe02952dc6489e33859abb869df56b6d6a46ed518a7bc9d221e58ee918444c0168e74ba8ea96415cd1390a56837a2b41a6a975af0c830bfca70a4f25c644a5c83016fc3b945f40b67c40d4328fba9aa4e6b26acfb27bc3c9ebcd8efa820d133cfb260101ea5b83ae634200bec90366eab172bb63cf01838b26d2004aee5829c1fcc1269863bf9ac7836d1f74f9e9ec631a9513d2012752c610043966be300618ed5aaae82b05e2ab33c1e0297fec247169bce5b62ffac3614721f4818abd7943eb6e6064fe2eddaf09c2f31572e26ae93bb008b7ae3518346548de1db3676bacd119f3c2d2c9d35e3794bc0d95d788b785627f69534b48c82b073d39ec9621821f0221cfb998d3fd1329e0586fa1909553da42c83af706365a35db5cffaad4e830bb5c71f77ce9920a4c7029a406f6bc022fd1a3faf7784e6987b8927d4e5e382254cb38320fc2b8f2a7491b29a5f33eca1e84fc073936b6b53356a808934396c738ba00034b8786e6a8868512d614efe9b33c8682ae3e56efc4832a1b4cdc178b0f865e3eba0e0721ce80209ee56f076ea7b622c39981a0243e5cd7e378d8832637f13891a76ab7fe9d8a5774e5bae530dc96bb60eb81ca340177e51a562a3657b6d51286eaf050dffa9845889ec3a9bed78fae9c0dca40e52b31e04cd752aa97c6779f0990afc40e679fa3d10ede239c3203bf17464b0366172fcc7647c72ac7097f79a822194c0e52fec351e9664096ab892be59ef697786a5d9e1d91c768037d13b4a289767bd53f241c499a13f13baed4b7a09f44ae5b8f2d4c74f1e259f9fcfb987e33772e1f0424e9d0470486df547e10617e8a08f1fdc641a83eb4aedbff2a2f9f4aadf9f6d1503719b862958c42b4f1218674b47929b136aaf84cff9de88cd10954e2ef9481715f941bc38a8db262635971e359a3b1acdd6856d148d63696151bcdaa1bc39a8d67e546b0cac659531b07b152091549c06cac0213b78e07aef383d4f5e0753e409d1e5cd783d6f9c07572d0ba1fbc0e7cc05be707af7bf8ecd479e30e1231514c69cada36dbfd902c8f19a6143d8bea66a014fd10a01debdd63e222e0f2b33930c137ba7be763440d00c7b83d756c89cc02a6060450c696804245d50ea43794cf10b03db03f21ea3c7a1b122e464cadf9ff1400fdbcdf1c9e4f7f043b4da142a898c56af9454af79d857782f7636e58b4c8b5d41536c325002a5be2f4f864bfccf4ca293b152b5c1a72cc1344e64996d167ff1cd4d774134e2176a01ea4f9f678f3e5ccbd83e3343782d9f1c87dd193828aca06ad874e712f65d9629f929ca9d8fbb16ef6b4d4cf2b12e84e91ba20281cc94adfe7db2bbd21509e6e482e004853fbe03f5a0e422173e95133eaca3d979fa0336f0477d478651a9a9011f48aa8b053e1a00a1cb6cade011b03225cee9cc0227675e31d3e16e0fa102c2568f577d0a1613cc4643c24d0417a7e0b52f1d038a361f0722c10271326eebcde6236144bd1f5518c3dea46eedc3869e90942de91ca9bc2ed7ff2428c6e79380a3b1abfeae5dc9a358887f90cb10188e164e4148d8b97594a01b85f6815e2a483f19577335e4d91bf6f784e9e0ed0d97dad7bcd7f0ea53afb6be6717f8e79b6e86161245a8be2811a339dfcac83db3d8e4720baff9e0d5936b79c75713ce2c68b5ef389cfe8fd9d683dc112fbfeb2fa5415c74e265e4e9fee8663093eb4b48bd4f681800a6d6191d17351c52af7ffc8d2164001a9c4b20d9be4781ccfcb0a8ef2a54725d3b9e00568bc4a818cd38dd5005abf2ddc3ea2b79378aa0f48424ad9e0e7a09c8064d2a20c111afa95d31ba7113aaccc9067e6c8549d640dd307d79c53727e6e1ba9b854a3204901ec76db04eee47e17540c092c4eb500ad60e228b8a0c6d5c8c0ee9b59526b2128e1c33253624181c06b51f0a09fad74efdba1c2121eea0239cc40e9130028bedc45ec61d975ec288fd0e7d2eb5af9274a0d6f91227d9b1ccab9d0154845b639b524ee5b5a91b2eaedfba29c82af83a616b9d31e6d8efc9dfa4d2513e8ded4da8b17248e2e08687ba6189f3a96ad847a26de7f3659b89c77fb972868e1fb547e080edb9c42edbbec1f422f7d46eab45d1ab5713b516ad95a22875906ee8c2857806c4ee33823fefcd92df0cb8658ebd950de6b58be2a1cf4fe9aa827f06622307924c1bb4b1b3b59e7b8d5ddfec7322387820884cfd860174813567db4bd4027a91a49a7801504782f37806426f0e19f74a4f59c2004627c1df0ee635b2fa6b20f3a82dd761ebad1272e58cb1d82f7965c320a0306b3d767ece37077d5cbba293078d32f357f0eb0b78ed9cdcd921b5346ed56fbc43e18918e8c772875ac17d3b30658a5c90c0621b22d2e4ae82b8648c146bcf836673f5eea9ba5896051416d84268f7c3a5f941d615f3107d763a26d914c1b6f04e59fd8b3e88967ad9f94fd6f455cb8b571ef473f5ac9a1e44b760e4f1ff15ad2ade6ee0104a53a98af813119d4aac13624fd6a466195bf6505f6941f25d7730bcc2e08bd0c15343665c2fb2fbcefedeb848994b6b0a927819873583a27c61a18cf353aadd06d2426825469a1b4c5fa3851e66d82aaa6783efd75b88738e2ca7156e209f8d75355572d5a65dcc617122f112493ed94f263033ca4e908ae38046c3d8f2bcce0ff1ae2c1b26db62f4db4e2dfe08cfde841dfd2ded1a96b6c15ba2ddd00ec5f49d6ae60496bb8b36806469ed07a2391d2d692bf3bafe08aaa1b2a5053eddd499dcdc9b323ce93997db5123135a8bde95285883f3e3d0c5ed3856a52fb79ef0cdd06914d52fc9c1c00bfc16a9e9248b2ee7f85ef7a1c1775a02010043139f828239b722178474a97876c431302dd573bc85f357eedbe6d71a89c2d07ff155c62688582d18cd591e351b3faa04b17b142f16ade4a93bc6c1f01c2b542baa8d92b59e11a88d34d0b6f47a7665e9174f7bce57e62ef90f7c939f2a87266f01b400788defaffd5aa46631ef391bcfa234ed8179a9a4b8a74d19bfbfb87a122abee14fc047e65700e2a3c0c3c3185edcbe20c65318278bc1b90824ab1de9a32e1f805afb2c00c0a156c5fed2dc98601534e145903518c896071d02e65a9f7e9453e39d1914a78d11dc2ff8390272e0225a32f75dfc239f938ca5ca29e568e99ab18a301071436ed07f672e29ea893fc1aa78368964a99b69a4820fa1ecd2b5e983c4b1685dce83d01b301c3a146ba672a763dcaacc96bc7be4ee0d54dbb35bb0c4a23f5be655dbc8e61ab15f9cce82e750673df208d78ac87fe3a149802951309f5e7b247ac1eae45d263e8905bba61a51ab771d43c2d23ffc00bb0a4fe9a8b39083b31dae12da68c408b61a00328687fa847cd8afb8eacd465fbf054acb2c674c2c244ad50b4af5afc9c1f666eb836545297a7060bfa7da8bb58300e76e4d31e5224361e4b5e45ea3b3ea172586f46a95901462ee15ba77bbcaa867aebb39b656523f6ddeaa9b6a9dcff8c12433380fa617996c1774ee499986c7e6b141e37f1d095f2e102cbdc4b06b655d5e03de7990250d3f478879ed20eaf74d9285be921c1f3472befd87120eb9a968e5c6c3bb772ec329a369376795351a89aa0d294f16eebf4bb50418448a7156dc385a5d5f5f8abdbea74f13ab2681ad49d4a7bb4d4d406c0f2fc3f0993b498cefd1991b1f75c0858f96c2e49d0124aa0e2ddbfd5b0c5995db19e23d02a222db6978cd045304c266c623fb5e4311df671f70dbacc03fa16ba58007701f6374fce0ca1d8772065779e287442a30ee2bad4e088c503d85d2a4e71d2d666d170dfeaa851a38188c399344ff04fc168f902e9bb9237e159d3b48b5c5f609f147826967f05526b550f06d5c2cdb200126a350ea6b54c84bb185876399602e85fe9a3124f04dedc454e2e8ffdac819505c6d02ac0949ef4f739ddc36733a6f7520846d4dd4aa8e618977a2343b2253d0f7e617bddc79f12b0404b6f6ff839bfcb00498ba49afc0b3f7c4001da0e7556418c0bb4d5cb3771c88573a6a4c8457abfeccec09215eea152c4831c1a024f20897660fad3ea0d2f678e9dd897f73fe8ce398babf8a87a00650a148de1e07dd59ca1433c15ce95cc18e65dd55a26f0776e51225ab8584abf80752f44ee6e67c046a10e37360e196fede0fe1038b5d2b6d1243d8a5a6a5b8168deeb0204172cd553ff26861d5187dd0b1848a192f7efc1e73453ba348e7f788f76449696fba56f674bf9d59818f58251325a4c5f10aa2812544c2fc806a14b370b9c446abf86adc2c98dd83ece888a78a8ec7407895cdd33d8cea1b9cae92e7f9f4e8fec81232064bb7ad8c37f6258d6dfd0a760ea4f4a695d734fb841b760789b1ad3c8e7934e5b36cca5bdd53dfacd927a3abad36fd7122722d0c614e4d282b711281a1ea444275157265c6b7714f6276876c5d34c8ff3ee5243f800eef3a1132cd46067b39caffaea48409536fdf4b09acc148472185d6ce77904be2a7f25e24f500527b43beb0f0efa1a4bfacc3c92bfc63a8b3f9c06759b2fca2297b65984dfd4ea47c62db8a08395a99193686375e2f4ab81257828e1069e95f4fa12261ae6dfe55896bf1c4321eb401a6945c98e234b312fddbc527e367ec353fa9facefaa4af46d8d4eb4376dcb97dbb74f90efdac7656938555eb49b47ee78eb81456501ca11d6df07c29f19acf71c75d9868d3f6a346642aee4d1701963eefec5ca446370d11d7eccdc098220779e359418cde4527a0115c1b0b9d3d22800da87bca60184d04a21ca40015b01a21813115420377200e3284805600befbbf0506e61c9408ecac7873d75c36d222463fed21a0935694e159c31293b6adac5e28375b6e8d8f8ddfdd317467251da698b8429c019584e7e1e3c7b62b590d1ef9396658ea5ce3080697b2d0352da18366454938e8e7b6967489d75e70628bf7e02cc134956693a4e575156549ba2d2607108bb34fe78186fe4723941d11132a799e7b6a6e3042dbd6070a80ee9d048e7ddaf19ac4bccc37984909e4801772b7cd1491def5bbbe905e4424bd8e6bcc19a2d7e7cedb793d75efdf173b0b17ab4944fd7cd7143fb786b67a3d1cf298177c0cb21e82c95fd0ed039786c5240eb9f2b504e5262eac612f9872fd781eab41004a72efe87ea9dd45fdc17085569afdae8fa4fdd1cecb5e8685b544831171aa89cdfe478ecf517f6e464fde1987cb019fa3ef4e83f6a9909f7f879723085aea16a374a2f0ffac47c5980711b12f8676fea2e752ae33252f626df3419e7e358a62054335d447329bc43860836af0f8b7154d2c5dc0ad05d2af46092d0959208cdb6d5bd24554fb94bc2a9dc4960d70bdd673d6e03d6d1d4964735fec078158822b7cfe44e99ff5e8249854b11a047c18971a49cce6b061069b02de621dd49060e9d8ef2749dfbc1a3d10ae775dc7d9ace45612950fff995d29b26de8c6bf1196d4bb52e9126201d4878155131f45d15c2d58207387d6fa28ab1772a5aed866f4bb46bc1f16894589191d423379b27b37a5ab4f389a49a72f728264c92eefd8c04afa85e8d1ceca4eebd7a1664b48ba68ae99cf01ad4b861cc533b83bf6d4d679bf2e113030fb2be0079832fcd115a8324bd1a7fc6a9b45723520371f3595b21c95c067040465a69e7387bf96265d710d6cdb4e089e35add86284b09d46b6f3a5d4f7c7aca86ec6913dac00b17b00975ad8b34c07a2deba83bd630542f280b22d768e9fcf7c2a4a3a8b86da35da3e3836a0b71281fb687de0e6abb54440b77b599e58f4eb163433985b5543dc9dd784d428a667a5787a3f0a11c931011e137c607dc3fa9f04ad95f6279ba63957cd576add37bb27cc52c0c127e25f7ad67ea4db2bd43fa52ac3582e159d726c0d432201ddee8e36eee44a53ffac797a95d683a9b42488f2c1896a773af7aed21c287b678045a99f16f724b3dcbbed1ea075726b40069a31a8bccf178e12cdb11dc3aa47f494ec00015095e3b0c586b79c46f0ad7ce1dc362f518d8ec4c628270417c565b6d3f996acb7fbfad6f81739681280f7d3f2e1ab93fad83c74e070dc4e099c6db654e9a0f7811ffbac96e853990481c833092b788cc624b0ecc0557a529b771573f664216a4462a5af7e7fe9f904ea42112e75f4fbab958a2439ae0b624141d1eb5a4e5cee7a38934fc4b9483c8a1adbe2bb51933a21adc42b1b0245cb42825fb5c6000574f7d0f86d41695d05aec3f6308fbd3b3de47f17e23446f2914cb83c462437a373c8522be3422a96532bb254e3fb80dc74cfa5f5af7075db85e8868f85b72e5a9c114e8bcc5af3d9680992312a0cb90fef5e29c0faa58fc72c973c56e8e24169171399cee3359587e7ca71a225d0932131587174f4419ad995d433e24abb8b156eeb38de9515448ca6a820aa9beca337b53cd666b6503e5b01b08925dae3d91ed9f878895ec6097885c2e795acb11913d93a80ad2ac4e2fa2a3ca209197db4887a4909664feddd79f97454ed22c4a02d9ce0181c4d466acb828b794773819e80f5837f6fb957202ab6410559a32a97643e40b927981b7578af8f4799f19178353ed0a3b41067743e46ce76ce3befb6bee86c7d80f32595c76e7ea33d4ec87d8b19c6fa9b1a2d3f69858db9490e2400ccb71d7fa66cff7c1e669711abb1bdfde74c14fac9d04a126caf9bb5ab5a84110d5ae16007d46b15fcdb46c0046a1cd50048dbed5effe502b5858fce71fb8d55686e6e59ae21f0477f687e6f33a4df7e6805a1e4176049bc7f297544ea8aa4915b5a6730e8b2c3b2d200ff0b2054baa6d26cb46cf87ddae15aaab8cadd5c1e2d835adc7c0fcd81e42a6a72698d10d889395e4d6deba38a0bc77ff9442122033e0e247bfdb225b825f2e1891dc57b958e57a83b61083da7d1829d235e5983cdb253ae86b32bc4998c9b00a664e471163d80cd352c8066528ff34c1943a4a07322bc8176b3a9946988d3f494fe5769b9d97ebb447a4b5f60ca80073ddb6e324b8fc73c959131f1b5823bfbb85c27c4ec7a25e4f846b7e09afc532386c77ef36a5ec108e9a999c0c768acb0b653be3451f989dc2b83e0dff812bb86fcdd4050be19bf70b5ea9553e10b134f642f1b6ef2fc1ef0aae8dd16782ccec29588fb37b4fcc3c58b6ca06a948dcd88198ded0ad67cb45410e06554f9856e51880f1911bf3abe0c4c27663c7f8480754587990f23e01ff25920c8996177d652a2b8900a8c28d61f7ec89caadbd843d1ba7792b878a7dd119ecf37845ec9267988c0f3947af2ff6e118355ec3aa62bf6878c5bb41015b3491e361c151fe2bd4ba6162b93872f4cbacc439507509a418f1fd05a9aa2e77d5fecab00554874638061349471f2a0b9bf4058dadf5fdc8aa236e62641a90c2e5ee315c377f9f52d83811a97721bda5ea6a326d397cdbd17be3a81e4371ab8e59dcadbbc9ac94da1c50e4b605d5431338ce34ed9aefe851cf15f8e029c702dc1ba355f5deb0068dba91eb2c3054b42ded2ac2ba15bdb3baa42259ee1cc50844f020022deb1c72c3e7233dae06c19eb4dc0623c3b9fc9b05e6c4cb1f4cdaa33bfd033fd46904275c5bb873064f6cee7a422bc8569699f39adb506341c6f0fee328f35d9a966e9320e4ecdecb3045ad2ae246714b103951e55031a610bd89be241bd8921cec4307d29da4e6e03e89087a28d7af8a104ec1c0795db59ed657c459ad73a005ef9759977a213b95ccf20959895148d969c988825a75e0da30e990573797d1a16adbc6372ba1ea149dd10078a1cf817db91b32639e9b7e4e0d3d8080818c1dc44ac37572aa5308ebbbb9f804c85136290c71bbb7c17123bd4e8c8922294f4a664ab15241ca9dbc1fb0e06850c7d4208f48d1b3b3baef8bc2a6cab91ee60a7a8e9424968532d1af40e6c872afcc7ab75fc08e27784f13dd4f729502566a138a723137cf026ccf275cbd4c05bd7f5ec14e24ea7fc0679e5acaa1d7b01a783325b9b1c5cdc12e30045a1c4a8b5328376b252d93c700544bf93c224d4a29661e074e05b80c997ccc3f869b27287a575ff300205abf720dda05442179b15cc62f4c1e7099b664b095743ac5d4e0953298ff7526950c1a3c728750fb93a77abf94e66defd6d214ae0bdb7a0fd7085bfb850bee5407f3c9dc1a973cd8a0607edc5e042939c59c49009bd84e2e5886427c7b26864e1e51e53b7a2be111be3855370a067c22f7a65af10c5c7307db899944755676ea0fc52a3511c8c302bf6c2342369bef5b265b11fec35b850233673cd70a0491b91a777a3ef3d634db61532158695964da4958c9b01b66e08b0dd44eb26c744535939c9865445c80b2f6421efe5d75299afd016c8bc60aa1783bfc0a356ac17477b2a85da4622d3cbbd496feb5089a7ec7b81db171f97277dc24ba4fd3fc464d603c1f49ec032d08e742accd7542671d5914c163af8208d1aabc614d264623ee8ca4c44359921a77f9ba92928d607815b8c6461f983db426d1d0616b5b333ae1dcd392977ecf181d5258d5550d4b6b39bfdf14596b19bb7b6d77283fcae385eb5f1e2363cd66987f2774e6a3daa64230328d1a8ad6a8accc6095110dc05d4a52b4cf7d8d6aa7e849c51ba043e0a823f57295f66caf769555c3e24df49850f388912941b94648012d5be687e576d3f5bb586c56654f748b48b26195e3f52f18088fb0beb82affb87d7aa0df53fa49ca086edaa16b4614b543d3d6652bfec05f654725d0b9124c03d278efbee4e6ecb80875e511a58ecdfd7128ce61744963c6e8f07ac783cea320dadf749066dbcc391fac9a9bdb651ff26838c9747b7cd4876ee717610ee7865ffb4f6cc853bbb5f6db5fc7f0b89d4af15500f2db06518de6939a10af925da60cd3b235f128bd1aab5e070d1b7643cc7e2b885be673d3c39ef359c6bac70c3104a3b5f03f3121537c78fd7a8aa6a4cb3fa77af704301b0c87f2fa5224f87711772e62e2e9747e52b7edbed1d8849e03facdde91592090ba9216032cb8aa12f76621d24bcbe42f40247e91562ede15ca60e0e73cf36e34eeec7d0b972db486382914e00c06b540a96a4a1a15754213f8e9aeafbf78ae17fca807ffbad584ce691ddd116db74608a126b4b2bb7b07280925093009878f64c89faf29e986c70870a36f874d293c75f83515bdc9e1e9000e7f0570780e85c363130e2fc4e4f0480270f82543874761c9e189821c8270d8a1cf811c5e861f87aff201d209494a9492f0806489c861cf7d1c7af097971e58f038fcfce8613db487df083f720880f31c3ea6913f5fbe3efc76aee3d0bbcee12597095485c69c1c5ecbd20978890471e4a60568a5c75a784e6e5280bec94d50b4d2634f7e23372140b372d301b4d2632a7c959b0aa0b9dc64a4951e23facd4d457a2be0262ce040501e04010f3ac08914e0468c7e24173d96b50d4977412731403bb9f4177b082edc85ddc48501e80fc8052231fd0de0db85105cb811222e0429e0420b88b5a0939c72dc8fc845d82100fdedc75010daa1a9e0a024a7adbf1d990206a03f146e08f73bbef7d69f0917da424f7242417fae8b1082fe727e11427892d30efded0bc004fd091d85c75c3872895c2341416e420b408f692a5c0b26c472dc480b381ed482b621c9e94f720aa23f13de447fb10fe024402181059d9400edd4d2dffd072c18394c53b92c10799213131602a03f120ec402d01116989c080b1f0480c883b0a0bf20076ae1421040c2139de484a33fd881682af73bf2c308d049582204c87fe0273f9ee404a43f58d6c2d07f682a9789fe7edc25b0030101e92fe84234150e48c8939c86f4d7fa124d05ffd0df8d7fa0a9e01f1f007d48c8979c04168280e80ff600682af7c87d0284c89320fa0b3a094f8290f0242798fe700ee4c9cd8d3c810179921311fd053913fd91f0007cc80186aca0930ca09db0feeec7e33e3495bbc29127399db082fe863c4853e1562012e463051efae37e64051e4a8e9cc80afa23f2a027ff29c010157492938dfe4ef85ed74712fd057d08921f1f9a0a7ee9cfc77b682af8f524a720fd21c99ef4d0542ea7bf1e370992070505fd04fde027e9a1bfd579f4e0f1242724fa0b7a929f23f990158c9c707d5c252a10d19f910f5181c89027399da03f9b2b51c187fe587fa9e0e3f524a723fa23f213f437e44a5e82510929e8240268274d7ff73a9acadd4d295c9e148ca460444b21058d3ba2a96429e8efc88da8f022994ab69b8a4a20d29fbe0e4de5f2e828c11629c2a3a960ad3f9eebd054b036a2bf9aa97075ae692ad7d61bd1543823468a1829f224271d3afabbb73a749ee454f567e4b5c8ed4bd054b2dd9402bd3c97a3c21dd11f7d099a0a77a4842739a9f4a73a47c4a33fee5a53c1db8624271efd24a7a9bf239ffa2be1f442b3c90004800293000c2d394149122426e4111ecb247c67a00b65213f9247780999841bc9402f92859c481ee14332095af2205ff0411948c3ff64215a02215ff041f2085a2ac917bc0879e72164efb00c0290ec13634efe23effc83ecdd47ee79650f64ccc97be49df3c8de79320074ce5566cc894e72ba863bb47422efe826a2eb648f4877398ebcdd9553cfc9d97172f7d46fe48c95b7e39cfa2a6757e50ecba6a5969466cab4dc225fd066bb021ab648b36bce48a0c4022936cd330b0d5034d833db1d408006061269861b2b0390fa059b1095741312923f14683bec0bbab7d6c3251f30952f68067fd08c9671eade9b5f73f6744d3f037fd04c14970b6321f9032bb53686242fc8577dde00a65f50845d1152cceaba6378010afc052dc52520848290148989813c3546f8bdb0a504a955fe1092af0d52f943deec801ffb87760ff5845b9b457bcacc9eca1e94e5a0fa2053b21d81b9a98439828881bfd4a68f6bb6fc96af6ce71e10d1ec18e26e9ac0b65dca6ddb9036ddb659bfd42715e035e814358928d6180a5f767d9124b33f986606f8bb512aa828a5690618459f484a67a500d296b3d62921851b9452eb5c00471d0586cfb2419ecf428966d494d97996edc44bc9a4e4de235fe9710f7a1ceeec42d2831ee7b81e3d1ef34e8f2cdbe9d123fb0ef723eea8c175e7316731c6b8f3e57ce736eeec1c764a72ce390046edcf4a972d25e731ea2931c61863ddf9dc3bfaab42b9d89d9093f3c5ed8212235f59b7f32c6f3b99ae54c897dca94b70c8ce65a6eb17f9c2227f2a14cf79e83800bcebe438941cbeea3bba3e411f8946be7ee0b2736c789e9d9d9d9d9d9d9dd73452e0fdd5331b03816f7cdffa3bfeb9f60ede3bf9dfdd3bfad3baaa4103f757d15435f2e78cfc992ad04e908a334e789eebb8771c5dec7b2ef00936fa3b9975a83594af9defe84a867cc119a94a3fc121fa3baf3c348ffe5c00d03af487f74a477f7773ab1c38f42757aae3ad755dca75eb82bf8894f445fe7c53693fc91ff8e40509b67c85923fdff2144afee0b83c15237f762e4fa326508fcb53a50924cbdcdcb8f987f78d9b9bdfc854e97a87fe5cad7f5309c7639764e7b0a34ad04747850257285d01b0843f59e6c975f91e19caec3b5996c1b98efe2ece3dfd619ce728f345de8bb1cbf5bf5e30d817b423ec7068fde5dcba32dc391fc5c91fbd915a608837b2120c9407d7a78f93576518625797b8fdd5a5a56f9a994a53c96acda30bfea81255923f4b6ab63c851b045ac86c18bb376960798bc42375aec02f36ba2ecd6a96d5d71398db10ca026178d8c00221d8df6f012b78883ca899b7c0123d7c07353c3019ac70c8384f63e424a464245314d04d0c7e8b2d180c16020c0683c160416021c0603098bc71ef4ddd7befbd5ca4f04e209b9818f8a548908bb1fcf9512395d3470a31126675030c03fd91baf7a6eebdf75eeea6eebdf7b2388ec25b44ead01d1e3e71fe7407f2f011a2037de25d96c3ab584b1583e7689c18771004304c1783d3255f31062790168313281583f7d4c01d776f90345832cd73624ccdb4ffba344e182c082c04181c026130d85dd96b56579140aceaa81d63d448afb592dea803d35257e75e1daf6b5ecccad5f8aaf47256522ee3a0bea01fb0204499e783abf38ce7d2ecf5c5f3ea51af65b97368b7f66a2909fba0c72bfbd537bbbeb4529adddfab8704cdd4eba5c15ef5be226dddea7a65daccd125a95aa5b5d2d77dbd347d656e9787069db2fe7eb384d43f1d7c09947d2645ed6618a31986d938a29860a8992a023c85fd9285a065032d6e9cc0dfcd1004db4b93e1533ed205914bc041261ba1b9c88aa399881accd13c643765d764d37da6f458762d27ddf058a6951ebbba6a164733097bc7061996c803f4d1b265cb1c76803ef2ad2a7006caf121ff08c1e1c6bc82ec1c8ee61176d0c01fcd22d01c420e8e66187ef2389a4168858066203b8dcf179b067f540747f30f56991d1ccd1f442e5aced1ece30648981182b504d30d24da28022bd910a1b45a228a85c40d2a2598f0129d1250ab2d565880e34246b505aa025b5354b7050515d09ad0705bc4e021c504d4b685064b978bb6a58d1e889a404a82071fca1041c46529892474205ac24c1250e84094849a24ae50524a02044a444c984922cc0f444d5c72d0783f2c1de3964b2703d2019e293c2df98a3aa49981926ad75a5b2e18b561176994f100e9062f2c69d6e841039cddd0a305b8ab800722c02c0cf808036b4df4e0a00a2270b621183442e0031a5bd88059649090907e40a38c1eec5cdab08b36c6ecd71768a4410234d668c9c10e5128a17936c4062184104208218410420821841042324284f1a201df15f830836dc07c8044163d5650851558db100a8926a640c28331f0dd100a09227ac4e06c43282480f0629352ca29a58c5766526ee84329fda69c73d25aa994724a29ad94126fb9240a4a4965a694ca2ba794320535958b0a0c2184104269ed9c41a6a5f605a370a296ffece79cf39bb79452fa694b27a573ce7fd99cb37ed63ae7dc2a47d3e06c2aa7def47b0d01ebfee69c733e421ff8cd39a79caf5965a5130758d21aebbdf495c4a5524e6ae9cd6c5d73e9a51ad2bbe6d24b335bcfd09bd9bac6d6ec525bb333d5da9aada1d7d635975e7ae60cbd6b2ebd34b3f50cbd99ad6b6e5cc9ae94935abc532f6c5a6d16630d5b461abbd45a6d4699905e88823489b42012e88b16a01fb01e286f8f84e5095165d2c2c46491b0543da318242c99ec329753a9a65f28e87649ee6f778284d9ddeea2180245a6881441905ad3bd1913d2182631910b8d484abc540ba1cfbc4d9a8b71b4914b47648184d2768408761602117e80f6c7ed6a64d7236e30220c1641881140ec29718c1016f4579669b892704a08e12319f8c988a495b5d6c2664f7cace2880d5ce18123a8382266add2b6d65a6b6d50d06b7f2da62c76e02f36e5590113103d6bf0878384d9456c20db6a8004f3bb94527a420c3050031a41d040882e4a88c97410812f6c43c51a5bdbf2fc8837ec2f4811f8655b11ec0f8eb19ab59dfd6177aca5d6c62d2dd8918a6db394d9568b6d7fb1eb2f180cb67d90d01222226eb0ed9f403962db4779c1896d2f0306ae40d262859219db42282268c0a4650c9722b874b9b22d84ca0017f6622f62b6b50fb2d65a6b7b64e1c0bd9d076012a679f1210363260566071ba6cbf562881a0629c352460e148bc572831fe6089e6a96a40bc826504f7488206213305db238819b8c008d7429fd8075288049d8186a18e1011835baa8a106163d30c0aa0dc1a8d1850f23f0b6211835c078f980ef8660d4308303141217c8d9100c1b5b94b0fd6bc5bb6950a2440d0b54755cc76198109109a2cc182595627e3b929b3eca5e77b6b4cdf96d9bd56e75d65a6bfdab6e72665de04fa7428922034483f47a990934ed0f50505faa8e1ff0847042a8a5c45077f698c2b4f6846b179a98ce16a4b2473e35c67ce268ac8184a54b9d99cd7296d15c245f2ca4745c8a4af0009882aa81e16397c472306315a0062ffa090cb56f179217f38040ad0c7fec06c47d7e3e19c357e5bed12f587be27927962e775838252ff504f89387eae2cb9697f67572437461c134a286e002239a2070902a03268d96c833bb21b9ab974a5d0e490b16c102a1845862df6cb92447d8f2d5a60ea14fe5eeb32cd24aebebddb093ef5e9044c70f986e4be40fd556432d44f312263045a26b75419f3a035c796409f3f5d556faeb512d1443227bea5363e827b00b0ef194c46d2b19ae0e6838d82e1b0eb5d65a71b85d34e104c5e102693629a5843e74d2092f6574c176e50f84b0a0bf30b51267905286b1d18927d0937618a38f59529b669a3e92f747f38b503bc618e352f67b6917a3d0de69aa539a462c942e118d80116ac9eca187b14d6608a554c9cec84a4ce84911282fd4280c0485444949f7d99388b6db0c6348287dead2141b78098cc92529ef0b6212c6e6375967ada78f59c4e244c6a6ebb387c296b4826c7d1ae36a4d2a8416586ed8794eece78de636bfcd6f9e91fc7699394f49dc5edc72c3edc566f6e2535e6ccb5ebcd985a49682cd9eec3113ddec37cb32884642b1411e2fc2a889ea679452a289346c90e766cf3aedc5ec475ed41e91ea29c098eadd8faa38191d6557fdc8a9283beabaa77495edddab7057dd4a0cc660ec1ec6b6d82591303c8049dc148624f644a90bc978b3176b517ee23951a9b25ffb5de9a3ecde8bda48fbf58c52d9bbd76d4bcdab5c5a50c6068e422505c1a691524a29ad144a144a29a5dacca44501a5748b0d0689b4a1b673d8c01149860914af1ad883da73729f7ad17d4a577182af72e474a43a3db2bf87faa83ef5953e9a3b5be0d5aba84e6f57ba4ad59e13d5e9bd4d17a9b4b73dd1d7a752afaa2b94fad41ebc7609460536f8f0840e19f822765f349f7dce5bed44b347fb4b0d342640230c24ccd02296a9741558ff647595a96151474e45a9cf1fd17b2d2a0663993e4a69cf89fdbd077591fd7d51fdfc07d33ebb14622c3b9c324e95071f4351f6d4bbc77db3077fe4b4fd28f5ec474e9d2ea2bf3fca9efacc1ed41ea73df84d17ddd31f51ed412d03d2ecd17428616ff336ed39493dbb51ea993efa117dea463706b5a6ec4252bbd7525a5cb249d4ad84edda29942812804bb5ca5a291492b5d6babdd65a5fb3a7ea084d69eb6b985a19207f3eefcbf142945a6bbd078740b873c021f465e8195bd40287c82a1026f100a39658041c120f213c03a11816ece18bc0a86311d0876660533172cc025f458cb1650c228b0cb6bc05e08b7e0661c6968f715f1d97a00fb5400db67c84102ecdb02712d22c6385495a3a2595b27e61938254920542e3820637a8ae6c61c5997a450d2ee98cae0733d6e4d0829a43adb5561dd81c542c11a8ba484d81820c18d134031bd460072796a05e10517be0806a731b4205f1441a323d5833704825692b488091c314293893431850c82eaeb85c9c01020b986146cd813e08a61fa99b1d90b698316306f26c6e674ebeb07cb9cac03c32e6e00d4d087da2a69312d9aefc81504a2965bdf9fbb561841d84a2505c00cdea05a00b019248427290fcf9a07c8970f856ecf0ae7d781da1c3bf051e067c012f177e2800f6c307d97148857cc18770f822120eff04e8f02c08393c94270c48c0a144913f5f130b4f1d3621e0d961910f3924f2a0c320ff6152618b017e806f874d2b3c75f83515e0d9e157a484c34732f2e723a2e5927cc11b397cfc42fe7c418a1c3611bd0bb596912f49867cd517409f7a9d31f017a3caecfa28a64c7d952f1813c9c817c021364731d58ab59672d9edb35b2dc3feee69d7823e57c7a5ae49a6a5dcdb674357dbfbec6aef664deceff1afc6f28573fce14f71ed7b3b2538f8114b37021438fb1797602a95c588c56adae52e6ec121705b6db16427e4ec387f566f5b8ae3ba221ccfa1ab38d9c3fd45d9df1457a577ca989a65bc21fb794d4a8fe178130e3d0395426892147243adec35529ccd53cde56c9e69e4eb862ad51b7942654185c6d96dfbc23d51a8ce091597d516ccc4d26283e50610ada51b1e709472925c9ccd1509c71a39d4786974bcec50a1a3cb0e343f93cd6832005086e70b1e647a8cf120ea25a6078b0f9ca05c7e9cf1e16c9e6640d802630a418b085846e06ca64004e16c9e68e4ebe69b10cee6f9245f37f7d10dd93cfb06c4470f10204080bc80dcb46ed8701b10203e3e5aea0201726f06044896d90a8290114408418810988f8f8f90880195a6bfc9ad9c314b6391af8a5bae1db18c9005c3583d527d646aed2cbb37cb62a09bde52aca97c6dd9cd0f80adadfa223457f4aac8d55b6a7596c5b8713b460d73b4e02f46c52f7ef922ab8f59764fafbecf3ebba1d68e5f84dd907d2a73406b47fd4dd9574f69ed98e9f845fe7cb41b8a5fa895765a0a63a6fa64d0da3bfad1fd4531bbe6c8f214d8bef1cb06a486fa4a757d9623d1ce6e65c36e5edd85eae805880f187f3a9773bd76762ecb2df9aacf9104cefe71bb56224bb2f80241807b491623803e707f5b48de7b513856ca6eefe918357beaeb925e8a51f255731481618cd5323beacfb5a18f1af88b513baa4645b5a40757789c00771b42618145191f5c808a170a7085c203344d6460c134051630b0580a8389ef2d9376564a2b9d954a2979a49411afe6953f334a29a994f272369093569b5ff313c279b3219c509b32c29b26ab66361a279a29291a0821a438986dc468a6d2362a3d234633319aa9b48d4acfa06a6cb322118295ceee55ede479e6b287e59bbb2648d7b8eebd37621a35b95811850ffb834f104a0c0a9ca298d00006d03cc1c36cf292e68a2536231ac8ac5146cd0d67ac985cae5043857ca0a905300853060c282618b7032ce056adbde280167b75ba5a750087bdbaaa4bb282647457acb1bb735d920e7eb9820a1d5a3069a82b7088612079e1e588e8851559d02ff78c0d60993744696ddc0d285dc08b316b54c181304e40c5ec54625b0e6cb16d6a5b6badad628b12363de5a1034f154d6c7b2d151cb0d65a6be9611535dcab04864958e67401cac53e09319d18a14622c91eb8bf8ba948c1929323a27898c1131531d062861717164a2a8049188f1164a0870bae1b82d98193193b90c247961d6851811d98000736c2e031c271411457ccac59139b37aab7d393a79e8c41d86403c71c5faf18c5e002671b424df18507434031850a5c504a0821a432d628bb9871ce99d93a29a5349b76d639699c73427875d8a69c137eca0c3999e79748e78c311ecacb28c116e99c93b26084c1e61ad8a54c770a241ec86092228d1cc6589a820725319ea600a20230589ac2081ec6809ac2e90632a26a193268c0e4400d17186f08260d1df6771cd2c08018692cb1031ce016b918bb18a59c52c6edf5028128683e79f5f888446e76fd5dd3734a2112ba604bf92412612182208fef16391a6f2bc7c2b3a8c50d053b5c601965193c378c0c782106195e908f686478216628398a9297d4a7f6b844b36060cfc33875f001dfc727e910e2834f332249b821d004726965308d724e55d376d919c9d8762dc7a739b9cc1c9880f69cb71b45b24408004a48d769bba9018ea773de9c118b04c9d79c954a092f9c3d70aad9828a405953546ed5d4da2a9b3ec218dbb2d67cec7a043cb6ba2b48fe84005fa99ccaf52134c15be60440583369a780ba014e6d0825451a3e8690e28c1460ec6e432829a2aeb665f4a9d4a65d0c8120dc5259769ba57eb56b7a48ee2f6e6fbb67543f9f42d5d333aaa74fa16a7b6f964d2b76862967187b6b96e1cc663c5b4afc7876566bfd3785a7d6ecf6fe8b99f6ae1e82f2f54de1d936d6db5cab151ba70e5bab556374b58838216a2bf5dda44024983e9e9eba4610a3f6b25bed65ba08ce9e59290f4f4f4f7018f18293524a338dab9e93ca182319b576a952d62e55c71438be4a69350c744f3d05b6e52c82ca1b1b3480e1c3e0cb426b0d1c2fa7f0ec18e3149e3dcf13a714f16903f7e9be60eb42afb843b463522960e9b63293598aabf976d92929678c12069b3adff13cf2e7b6648fdc1c2e93590d60f9ec35f37cc600d77f98eeda35a148481084792a9b64b2ce6d730432ae7602d011bee6ab6c4277f6fbabb1968f99eeb867e4991ab73c805fd76d60082505d37e9a3fd58b33a4e8210db659e3c504c6673e4872c1fefec396367cd0805b5b6489c2cb52144cecef4544e103de36848a62a9e5a262a622a5f44a09e79c73ce39e79494d26cd23969add44e29e5945266f2be6094c6ef7b5dae9b35b0f8e037ac5f26ad36bba9596bb5f225ef8f311827ca7fb5555fabdef5663745b53937eebe6ed00666760c7233b17bea267bfaddd45aebeb9ba7347f5987ba5258bbd93247a98b7694d65af5a5db96c6255f50c5adba24f05072f3aa99bfc9755be0c8d9dca8ad16a594bb9956df0843d549c9cd0be16d3229dc340a21b4787230c0f1355575f637e7cce8cdaebdf207de4a7180a5a473ceade3b0d8b009f8e5527265e008e19cab2cd35524105b21b1c6524b2b0dd4d635965a5a69a0b6ae5943abad960c5bd7d0325450c69a32ce9401633c53c6cc4119136a4d171c37395a5bb5569bdda036752e417e7435501d2c9ab05bb2cbe2a214a4c496ff766cf81d48246e8920c821104875a82ec378263b60e7248ba57494d9338613714b4c8a4848a94deb5210c5002865b48debd2f2a203c5a170bb255b077b71af1712a15be7352d15bb244d97e7aa150eee82b9588129dcb0eebee068c375e1c2850b17c8850b9c40383155c76d5a54266f78c117632c9960192424a41b9aa0816b820ce73406eb092b5450a4e0c6179dc4b277ec8fdbdd6119bb3bedba64815b74832203504f8800a7f9b89db556e044164e423441868b04504d54e00699a14698113c098162424c1c038a1928818118bc98c0024b21934503496819620359d81c3c80a4451f3a5cd26c7afabb04984d8f97b0c1a63c6c8051118c0ecfa64d6b36e5e2b4e95d9fafcd8383314a9c804c53139b5eea005320586bd3245ab029941248b82e165603aee86a0527581981034427040e2f749cb1c9a085458e0dba2daea441a3b855dc242db57ad84a80a30dac04ce96ae0d17746d58e1eac1b526cbb6869a6e0d3170769093a56bc30cbb83141b2758ad41828b46b5668bba0136d4746bba986bd4c099a00d1b562658b3858574c5f502098acc0b1acae03594e8aee83ac688d41536c4d8aea051c65e69b9726c08e5010f4499800607f07737f528de7e105949795c3b50603829fe04d20e537fb2e93fd134edddbfdea5bdab6f2c51460aae6042aae2a4e9abedb38bb9632e45027be8efdd6c96dd669aa76a29b019b5411e3c81644c27661ef9caced26480716c18e80e627d09910bbf68d3de3dbd8c3ff29c5c6de419d9cf6b8fba48fb165347927b11eb9cb6124be922ed5d113ed71dffeaa26df39cb05e5fc47ad5de2dd2eeddec292df0b32cfbcd32d6b58d9b167792ce98bd5eead888754d7b29dd2435fe91bdda357d548fb5778db6b3b41f79f746dab973fa086bef6a8f88c5fa1136d2479c3ed2ced2de2d621deb2a4ef7ea22acd266cabbe7aef69cb058f89c3eda8eb7eddebd11fe9177b551f7edddb7145665a20c65f664d7f20bac55f62ecb328c6941b3278b58e42b68674b4c536a4d1be4d956abcbaf3a1b1b9bd56ae5c47b77239823078e635d25e7385ec57b8e5b8949d8c91f79efa0777ca39cab728e737ed4ddf3debdc87b77a98b72367c2bab17b5be7afceac6b1ae62f31bafd2bd752b31a9d25558c7afb2baca4a0c77c72fea8e2f8f6daed255726ef32adebb5b896115cc717c231c57e9a39ce3c8398e1f79cf7118935d124f7b91ebaa17e9b46ef491cd6f9ca5bbb7eea55e74f3d58bd4c70c7a4ca27dbcbf70cb6faae7dc087f471fe91c3f47e7f847aeab72b2c77de730e6658fd39e13d7736ea4f31d9de7e8fc4875d7a63d4d3b715d7503b8b4a7dd4aec06d0d19e86bde39cbbeed2559c8a5cf77415a873e81ced11b9726238349e3d32277b9a2b7b5afcedbf6718cb89da8b5bd7dd888573d63b9cb37e74e369ddcdbb1be1b08ef38e759c1fad7e93d24e6ebeba016eb497ba95d50d80a359bfd15560dd9c1e91cdbda2ee30c624de7eebb2973a8cd9642f05e4053d4ef51f8c2a923d267adb2cc53ebf90a1e46c639927ba70810e9e32ed31a1b7b75a4ad534c6b2a2c9951a2222e882572f3902cf675789dcf544f2e7a2205ff0dbf69b67fe22929ddbf6cd6e5151db3fd8e6dab66ddb52598bb0bd7d9e955d13c8357bb61c047decef9c73cb36752d9522ca02a77e9ba4e007a1b8772b9b1cb77803db1cdf86e3baaee362ace3ce3a8c6d94734d208eebba23d6b9c318c775b7d968c7499b89595fddc8c6e62b7de4347fb4ba11be8d66d91cff88f5d5eaac17adcefad445f8361792b24b01c66e646f7e35e75cadceba951b87bf916d329c3dacbca93a4e952f9e3d54c70af0fcf743bfbbc10e4ac2a8e9a106259a6a30c40e492d08030653982fa830636fb03a2d68c286304a6394400aab0318558c1b5610b5c54c0d586ae982dbc2cb952bb6060f2805f50086085090051a25184115b11578e0863ddf72cdc3a0b2508305582e13e6e2ea722faf27a8a079844e912ff839e18c9762ec72fd305850107d3a3229a5b4a5c33329a57386286f1adbd4b822f88b4bccc7bcbe809171e67e3a1066308319dc6aadb5d65a2d7de40e63174e7f3344cd3066b395da0f8aa182c6d7b64f368535b395521d635652334869b3c43441676064bcbef818971809effa8179a0b4caa0517391b09274c5a5a02818547c8a5d2297c804d1ecbab4e76193d8658628a6e8c40c63b643910f0a92d0ce9066cf25f055efc248544c970be309e565cf29e1ebc99e8f51863d9fb62836388120661d679bbc719f6bab609324ffa26cd5b56c73b86995feb46df3450922e7375025e0b259cff1b2332a809be7bce626dc59df62d62eb3bd0e13e09bef759800cfdb6b9afeac703902d31b8ad175d80920eaefe611a05b4a8edbfbcb62e521eddc6db04d86d0475bb1ec6a65594aa46c36e3d8617baa57aced3677dc37eedd6137b45dcbdf0c43da59f66a18ae24d25c71336c284aa4ac0eb7262db4812f6c7889a4bfbb39dd1d4b24782eaf20d02449ebddeaac434fc926a5dedac36f96bd4dc45ad4f4070314a41d03dd10b0f138373404ac705e8e81f5ce1b92c27dbbd552585f5d062dcb2d7f43aac3a8bf21d576a1b9cdb0a36c2599d35f448236f90171d35f44da753b772119f12a07cd9774c1107713d5211c426f1f5065775f6596a6b79a9eb03a2b4b4969ebc5572fde3ea5691886b6738f7a6875d6ed3f2b48dbea08d06df5d097b6d552bac32ee7782a47a4cdda3547a42de5e639cfa199b09e73d90ddd3ca789eada6dd6f2eab06372f39c9c9c7d31d055f68658bf39eb25c002c505991d332e764d6e76d4526c0452dde0ec7532de2a8abfc16e88fbea36774d589f8da68756d71a2b472fb3dee5cff5c9b0216641c882c75c406d94bbc9ac1bfd459b3f6ce1d6c9707299953f2b4838ee23d2bc4b37c9defde6f84ede6e471638daa7e2eebac76fac5fad752931d0ddfa77e3f0f6563f40eeb8d29fdcab6f5cfea06c2e8a2a43f1b27795cd0b5bbbbd97a1fc91e190b5ba71564b47206e9ae48b9bdbdc856412ee5df6ecf190ea9e3debabcf72df70b657e5d50ae7eeaa5577782e7fac7faa73d7b2c7d24338f7549e6a75f89caf3cd5f16d6eb377e3ddedb79c7c739cdc3ac769f9e639593bce8da6a9f4d0cd3d8ebbea387b9c1e627d75789ce377d95bbd3bf7cd266fc7695d95bfb8556f1d276fbfb1d19f95bd1d6e57e5ef861eb2b9b7fa567a8875acfad665acca71af6e337e97ed6d32ebb01b6261fd5959e91828d7e5edb06312c28e31c429735b1d01b9777400efba430b1c0fe7032c7c96e385663774b3e373e40e33738bdcfe5a0f889b76f837e32ea5303563fc1253293d3f9d9de97ba189e92facdcec4ed8ae6961da94ac54a7dd085d707c2a03c2f12c098eacc304584a03b27fc39de9b8458b7c55fa6d76f84d38eeb5c7b93d0ece715c38872e1d97628775131c1db1e4fc669c692109378e2cc9903d395a96e1e814570bfa581d976aa10ea894ec98a972182a44230000000000d315002018100c09450271300e26b2aae90e14000e7796406c5099cc634990c4300a82206300208600630820840064942aa20301946a70aa9e4126bc9c963159da9b7e6a1782514880c1f32f774369bf5052c700b13e82cb399fa52af277b9f0d0be18b0876bd0d1747de2522fd6b50b1a412694da9fa8f606ba690ea60c289d1859eb9757a711b4702dc182bd32a8bf5bd29f58d408607197163c02efa19be661da82597e4de90c15f52dd204b4dccbb155ba44abc55220889d5250d440e75fd6a27da565ef7305e2b31502c2c19f7d8e10781857526cbfaac8d603e3898e6577258a12a014bf51ec1e95ca69561c00a6ddc5a608be431d301860c8ed0e9787ed2406c2825bd58d10a623630f58985a1801676ad2893ee0aa3da594a1d5b4b63cb02e826708cd6cc5497ba94dd1aca2a9dd5dc3dd3ebba452329d7322174473a262d4a6f510c7818802106581ca7f830da512e18d059778e5591a15aaba37ea057c195b8ab37314dfd9e7993adb4ab593cd51fa3c57d402a5b839d5d9a2492cc4404247883acc4420601484f3c3e32509d7f4d2c15b8db31be32fde779d62291ad12f7c08e24d5c84601ac8688684c6819f30fa0b6392a7619a5db3e8078d97710c0c3f517aaa1510eb405bf551329e288bc2ff9056fa88ca11fb7dab724506fdd8fe764cae53dbd5447e6898da82e3324e87191b76b3fc09ad65d42f271fab29f0b484c439502f24c003fc647a0bcd03911591df42bd02406a38b8924d50c05a00f190840ea00711de30518268952e84556ec3413eb6469482923289a966e568a7dc7aeeefdf159baad3f4b8d5e50bde370db8674310eb77e59379d9a708bb8de482ce0fe90e0eb41e9f366bb18a15b55730320d591aada7180f4708bae3668f6e0678307549de09f455d8c0b6cf12b9aef5a36b5c8e461425e7cbc1261836083b22a328e9ccd70fe11aa5da44b57014ebf535d503372bfe085f122aa26f168e462e048cae005da3d801e6ecdc0fb443e894dad8b204ee41b52f491bf611459364f61598c5ed6f56646f12232159dd37a3f51e093754c77ff125fb62f8a9a21c86073ed636a8306528554bca2a25db1278d603e83e8a7aec0f352028a6792710d15705a2807129821033548d75ec52cbbf0c7ccb466dd056e40db05d28c9066c9710da27c56ab21b26747771cb5fd6ec1d4afd5824a310322a27c516079ad0322ba7f33d30d6d017b8c47e0c635085a7904eef619e2333c063995a1f648d4af8bfed8937aadd61cfc061820cffc6434bb763c34a9469f74464d9b11014c0d82b88f6c3275a18af3fa2b053eccbc81f34f059cf05e5fa10286f6b4eb64fc53d442c55ac87a72a648b153e835fb66d132b61ad1adae757066402db534052afde3751c88106a10cadcb854350d5eb2d0a31d335feffcc303e46f324740124ff816f40f4aa2d945578ddda388c22a4bde6fe2942a09285cfac04877883264e0de93c8f505097a28be9c0ff28e7fc4ac6c8de4b23292e46474a3888090fa88f0a431e962ca8fc4829dff3d90755f0dba504acb0ff256e4643d7c8a090b63591f5d81e4bfd6b04b0041be29c93317113bbcfbb55815384933a3291b2f08297ed41297e88123c8732329ddbfc545915e56a7550fe97e658ced39b28d4099f935b00b0f5e443b20b0a2cc3f68fb1b4e3f42936b35be4836c0877ab9486a0f5081f347c59d72f0940ec17b1deb8107098a7392149972c8dacab1655b33e7f99a6adb094374b432c0d9298a45e82d9906443b380d9063ac1eb9a80363b5814adcbca7232f47d5cc19b98fc726f8ae8f807244683456a59b43994f645e2bd28e0f4ad7926517f646f4998c70d332c7a56300922c1a5e3797e0729fb9d1f8aff46695713a835c773c1451123e07a2a04b04f943c88c9ee0b687c1d6aeef18e71e4a3338505bf8109201099ad46bbf7c2837dda08a6ab02508bf0b3d5a1ae930a8ef2c208a23340ed3ad630e46967a73cb17c45e148f5c1c9a9cf4065f9ec912ac3f9ee6d11830f61eef026e2365957a02f820415dafe6ae30738c188b31204a109a36d95b03b2215fab322183f36f5934ba754137d1b0ef3c4afa1758f90fde37819d434b84c74011bf0d6f5883406a5742946e507d3c0e5bf204f09860bd9d2f2ce7326f982be1383b0d8438443745c9eaf514c7ac95db1d521151327b6c8d50063ba8a5882fc7372186824a45a886b788000e2db420d801a31c8fa1d76bdf45f84ed82478a347920e89bf93e1e4fd84ae03e90aa43c32a7c4da37295fdb19269b69b50c0fd179dfbb1f403f33e297b3bb1df44318c470ba591bb154592d76eef54e5b91e54aca063f1505188fefac26c045bd6d53a82b32c5d48e6995950a0a5161dc71ae261c9772400637b1f6bd1d3a8c2c58516d98523e787c62e072c7f421e206552147ba2a8286f120fc768f8504ddd869b109e1929ce61a2c7315011398dc6b07cf5f9f80647806d0d56fc90fcbd6967940dee1e67a841c703847d26dfc27babc58244805092230346d4b6c81c9086625d49577f793a64fda86db5fabc144d5e47de5513b60eeccdee0159c5786939a7224193acaebdcdb915b3ee50f2c71720b3158c7fd940343018f99931b24577086451b9856323104308868701b0ea87945cba099cb6e789a1fe861cb7a2336cef279581d2e13c1b889714b908074e2028857e04be0ba074e77f7edfc0d4022476e3c2034199af049d206ea9da807521d3741495685d4d77ce4dea8ce1854cfa64592bbce8da72af921d075f4fae73a15beb57742f29773af7c84e298ce4496ff7ad524ad47b96d3d46057b4db5d3de2bdcfae76123ad6456fe4feff92161ec38e7d4374d572448732fdc518acc302e148ce9b98951f47d092036369e59f3264b60ee3423cdba8bd1c846425ba95cbeea80b7e3e296b0badd524bb8dc4152fc7fa8e9f95434e31c54367177a2960930e2259e490e9b3b03298787912c0303d3b43585bd119e2686ab6899081d3b6bfcf5bd4d23a10d760879f7d574848956e50e411c831b2e5e698828b9b6171471dbbcc1f9f03ab5c84d9d5f7760b13797d82e5755b71f7017e7d60118f914b1926e8ef11c59286b602ac20fadb597cd132fc4c40c4594d3b7acc7e809402db5066463e7e5d48c3d8bc678e8519807a0a8bce6ad127a1e24d452d4ca096b373390265b2954b8ccc8d4b974fc361668f8b47580d2ea00c879dc83e700c917592d8b91167bb59981a29817f69b9ee6a806ff97ca8c821180d09468c0106221275b05042773577f7eb8fef0f3fbf7d489b68645de51e027a1a9b1c9ccf2616f613e654ecc0082bc844467a52a42f2c00c1ca99479ca6fc297dc4a235140cf204ed843676cac14cc7e770000d6fdc65404f03142fc37d715e945950341ad1c755fbbbff3702e311cb9450f23aef20dcedde5e52e6f02e4bd2fbe7fb0c6882ae633e0626e0f7838fee265aba10dae4817d1eb425c0d77b1a57846c2cb6c15bc93833a7cc250ee94debe58db9a8c0a6d83a014bac2555eef64801b548eb46f7ba60d2993688d86fa79cabecaa0721be4eb4f521df625cf7fc864c188afe2baafcd7e99e3e17730515795485e99253cb35f7b10075c878086ea5b58931bc33e6260535fcf1cea904697353ee7a66969854768685b721c4c67e97f950891cf6631f34016c8004ffa45ff2561350747fec1604d219e3b26e26de4a9882b55494af9706cad4a88f73e1f9574cfcb85db1e183137ccafa14d378701222c9be12f621639bc9480cdea0707a13208a91ac6b208c9d1f20981a3163c3da617b87db3a526af0625acd3331a73e0960c6110ac8fa81d80baa82b6b5480ca1353523f79f5f314ea0a8334e2814371860230a1ed33d3a98efb10b4a7211e67aa1c5b9908ba1ca54c57c877c42d66992ca5e601bb3ad8c34c9d8305b6554552cf3de2f6f15a1ade069c88f83355cf4a839a04d83c11e395888b6275f71518ff1a0679768233cf483ddb2bb3d3e326e6166defd884c6c16b208ed2eeb989469529213ce01b111826905af023fb7fd6146df1277b309dc28e102203045ce2080d9cd81677fe30b1731997effb4fe988f0b34f96c8920c117e18485cd32eaaa74c1c1f84dbeea2cf5096d66ab9cfde0e65cb24c82554e9165476e9d4b935570cb0adf7fe7c15951bc03c26e12295d8da204220424782647902575b6560e172535669f034f5664e8d9389e9d93f58bfeb290c4b5d39084f924bdb2456a75b7dd6a568be9531f0a69d372011842c20567a6f1ac496c63ae4f9b48bb1d285a412afc67284a350d5bfe18eb049f43268b998e6980155e8f231c49a5bd4e8d4e8aea4b2ea83d252c156b08c973bffc8b4498bc9ab33bd5b0fdd317e160b031bc5753b6950367b082867da2d11a5d34c5355dd642993c54b5feacc3b1448cc72f0ad4df1159ea12335115e7bafb71bb0d76af44c9bedc2070fcbbfb36fcb88ab86684929e1053925736ad2e88011c731b293e0fa73c202fab60adec36dae4cbf0252d6c46ea76cbf8d2f59122ba5c01057595955ae2d9acc87ab821c423460fb5be1034fe9aeec9561adc80d95387d82b0e924c6ac4af58f31a20541537ea762b2fab57422b684ca95204188d823d2f7c9c900e0ea445863343847e43520938bab887d81538e8eb936bc4aae9b8a9be5f18cec1ad2cf1a767b2030d5f1d85bdcfce8bb6d21806c9e7f0b9f77b86be6f633d91ae2ece2e826ac4c4e31b875e25e476b2ea89894b6805d349bb99d41c1108cc84af010bea728dc5768a9dc8a3d8f977299e0f76b3ee3bb3d4bd727c569fbd855e410b93475dab51d61e42a40753011e3190d58b53e4f93b6d64fc384e2ecd106f16fc0afcdfdd70849d953a037b60e9eafaed1768446fb468287d11f4bb42601f8e3e41841ac58826c6189acda3fd0a70c9d7792f368791418c8e39e4e26eefadf0ed092784ceef4799be02370b075032c3179aa66558db0a2397d5c8a87b50ac49661d149e32ebeda5b0edc419afa4c63ba19e6f71eb3a1c2d2b41d5a4e357eca4c3974bf00fd300ff66722210ebaa53fc0bbb239ebc3b778e603c36337ef5deba04ca0c9d388a917907ef7539abd1cc32f9cc4f364449ba01e3b7c11dec29590ead6254c078bc35cc368b88a9074775575c4b084718b99af999e57599e1c1f619a740200aa6caadff73508544da8729054cda08f6c93ec723ef55e7a737fc8d35c10d6d8ba7930755c01014d1a930faf638b151c41a4d93a982645264c9c6d1a5dbe08b4d937bb900e7acb4ed2560731fe6bda0f946cadcbf4708fc2e0a2b097b0f259ccbe97460416baf5dae28bce08d04050bfa6cf886cd577e3604a42af3c3507587519e0ba5dc98eae3c1e5e95925a5de75320d65ddf7163de8d203d00d12cb197c4e1093638564893641620fb3bffdefc88119cb59b7a4790a5cfaa07e76f1d71716da62bd8c250e082ea9470df3d462259532917fc00b5fa8d9f9eefc917de2483cdf2fb5f6a34c0fcc3bd0030b7fb0661486fb452f6c508376b55ea3c0512aabe3cd9e37676dad4f1119aa4cb12574eaddb5ab31a4f0caa7bb268493cbdaa9e4ccca2e1082565e55b6a3d7cb33282a6a14e64b95a7c4272c5a6e43b1213e360e6ed236d447082d97eafa04a58645371a6990a78a2fda40f12ad972e1e5d6aa9f0cd3498b93096ac25c89594dd6f262e006f185e3a0e811ce53433dc0cdfb887b3856044e7f3e105b0f046f564fb1c9cd8820c381dc287e714e0cf0e14289fa7db38944ac40bb9a15b285aff73643e5a83edceb5cbeda46b44503638bd7fdced406e75a00f1012f6742c4395dbb78d0b62073c117525475de6c41a9979a659ff6062790c6cc20101e43f59026320631cc26855fdd56bcfb43692f9e85e9390b9e10d720b74c523304a049f6d5a25595cbf820c52a41c5b683af0081a627181712e3597b6d002a123d6a054bfa532eaddaa1f9c2fa43297d1db09da529ba77277c7fec848d095121bcc1fe0ea2e4d71b7804deeb1194f65b3a3defbdeb6ba0e8d7be27454f985105883d9f19c009c25ed2f558c8552055d4fc4e7beb8673e5feb4354df06238859f31b5cd5ca2c1985e9d7dfd6ea5e4cc78b32783196a30052813c453d402707c9dd481d22d66a6c454cd65959d106b3961c1fc04838219b66f3a9c0d745895f849a2d68e8bdd2768ab90099289e4ff875b174dd9d0aab3844220aed91f4ce8c8165a5cdf54cdd40ff0b4b683708b18ea4264ec849a159cf2500a62320c49be9d0908afc423d8ccf40f6f16927c7c9e029ca1e27ca8963c20a8f15eb27cdc542102bde92dc18bcab89fd3cd6689f698741cb659681d73beef9a44d50cabcd6ebdb92a88f164b6352d93b05d236848089ee5f1a07598f33279907e2c1b9fc55bb73df30945321dad79a141916b23296d07b9d2170dddccf9fa146534333a9985739dd620fb3bb3c88c2822f7bf4133e9fcb6cb960605fcc06cde5e5b94186d045bdccd248845f7298358e49832b4a3ce2c0238747aca0e883ae39af6f4963ab029ef3d78814e6dff8220f5ba41be765470fecd3209ba44955d00eccd9fb924ac175967c264c6a445f8fc5ef76651d571fc7e4ff731f0a564b408835144d87b883d7aa3f24750404c06d78c9f065b57a7033331883a26fa1d3de69aa65f453f6f732b623b23a21d6cf1fd9a35ed77b144ccc2cb0ae39a7b744f8eb4856303818e5c82d2018bf22a3cf078e359753930dea267f48e4e9d3db1d5002706c724e494e462ad471f7eccc734b7dd02a384c4f402b662ff33c35be93c06889897d57657e7977dfce32a0f6d02ce3adc77b34af9f22263ab404f88d1d9573e6a1f1b1607927e81fd79a4d1e8ddbf3a2c8e1a92f8141a22c1a22554bc88ba5be93af5a54ab608d1fd8cf2ef04404b5f8aff50c82779c3e0e68150535ce4e04bd97aa28541bee0e214e14a204708356bc113cda25fee0b1e50b9c00645de6cf6ae8c113225a3274a6303b34aa7408b8e5c5e35c5cc80f10f24cdaa6c87f18b4774405a24e301b712408287d9e48a72daa726d863790fb46dc3543c8b7cb7a3a1394b70afe84867141a6594d2d36040908abb65d6eb539929de81e27217e49450411fba87c8a175df0beb3f81c64559f45532bae17626adfa837056872bc8f51628726817274d0c17b6703aa0c559397133aed1a7b12bb1d6029112b79cf5a26529069098aef22f0331c814159d4bae0cc91db603c5bb0e3481b479f951c67a06f075937d19a4e2d4cfc7fc2e604f59c383a88f1775fbae93a4c22c529a4581a0ceec498a782cd6bc6991f4c08133f7b14a866a7b13861ca448d738ab9a8e60a2015dbc2db192097bb1d87df887f85cfc2d462cb6e1c54ca4090374bb12e91d331c83da119cc96c8dabdd859546c3c69be55a6dd44924ddc6941e219f2880595749d9d70f9ead23a6838d09a5c48cfb800aefa1d9978105d344d13eab180a0e578018e103145a6445950fa86728cdc7c59ad19a7030f34b25f27f7fa0651f8b667db49140dc1596c6fb969a6fd2b99d1ca04e3b380172b77aa7262d428127937d0d8dee9f40ca82450a11a197bf7c4b5db0b1bac56f7f28d629cde4694893d7ae88b29a01bd2a2944a8afd05fbc0adcd3c32e58047433ac6449c48f360bd922d28f180b8c88629b92a95bb77501769136a98b3f2a12eeee8e53804cd74351a6b2264c2444a240b25c9330580d820ef0cbd726f6e1749f6faf279e37d1663976312a4b485f1e18abe117d2ecdf162a1d116b18975bc27b6e806df24cbc0618574485beab41b8dabcfa9e0530fe93d20147ea837038e13072a496be7c23ef60a074574888d979b6a690a4cdd5b0f67921f20177ad9b782d86ac95c2b4acd297fd34d84e81be44750f0503ae406e6d909e9d0f46a9009484942124af377600b4a3037f68948f14240406a38f501aa1257f4936d3a0736288938b80a2110c6a2ad1ffe29445959a62ccfa95f719235e4cd94c83a863f75098cfee97cf6c7d5b0dad3759b35db5ed8128cd0322919e2fab0b7d08ecc302708b99df12232d1c824344fe3670a0c21534f89e0bdd2f7740dc2ec794de2728657cf141e0456cbe33026be29b8e544f6a4e655bc6506cf9e9540d80a3b92bfc78729e5523c8f06d4a942d72fb1bf7cd3451a01c0904e7980ee45956d23cfae32144941d336cd397e37d509e6124216742ec8548210b9a6c9cece18671639c6d704f63bb6565f7690f7678721a690af9fc2987d0548595fe30dcecabf6192d83c78f8189260caee6bb691d9e5e1c388a1a4089baf06861450ecbcfb02efdf7cbf0a8ceca30eb394388959f2f2375cf46470a9dd6671e306563d697e89c7b427bfa7897273292062565a4b0a3f85fe76a015cf2ed6e4e33417aec98284e41dd54f517c69324cd5892b9cf478a8440b876e37d2b6bdf2d6833e91cc56071aff6dd82038f0a88bc643f7a64bc074518f8e200719813b7a096f4e435f632ac612c6657a4ebe74d23aadc5b5134dd160a474a1a0034352b1daedddd909917d152ceb277cfa11a74973f15c2803abc6d71fe45cf1a879adc8824246f99a8c3e00db7b29c5e1b3058b7878fa9db805fe1da0f2aab3e50f687b5aac7023f69c779d41110cdfb54beaad3db9b7e139be161eb7b381debd203c96d3b71dd5820e229067e67bc44cee6f5416fe2043f70a46a9ce7a88a4a41b037f501374cb9968144aa8606ab69096c65d3b6a6d6d9f9bc845e2d09011a0961b64011f35a737b46b4679b68599013b56e54b5e277eaa384b819ffdebce902a64b8d002c094124e91e1f17d4b2bc8c20d23510b6c9817e45ba782a94284683fd4dc18e474dbb636981adead3251354106dfa25c1ce77da0c0130ad39f1977d592629e1125846d6a56336a105d8fb58d1ceb641ae013772cd3ecaf0b48acbc4bd3ff9b70565709f5989960397a587c4812e8cee5d01e27ece34f5b16bc86c37312ef8cd7307aef4e6b6b66ba1fed527dfd5ae2d9c77f3ae61c6378422f422e9ccc85541904d391dc4fb7a0153baf24700fb94965adf575e1596c694a3d3a381c6d2db755f630c490017e9a4ddbc505b0bae695a6d42dd2a492782cb59c5d5bf5922af9b5f3202120c53b3eea8c9f2021b0dcc3c943e1ddd0e843a7d9a8ee0ced8dc87a668f6deebfa164db991e1b032fb462585933b6751032b651960d0f2d026eaf07565ffa40cb8b25ed15fe84544923eb111e29d2efaffdbabfee193a5dcbcc5c30def70bd7f585d37cadf6f2a8897b0a5ace33f8302b64b284f547a59ea976592065a23280b35f2780231becc3198b035913e200e6e78f38a3ef9ae646877463bb09c326537937639be1320652dbbc72cf2b645055171bc9601cbdcbaa70eadbf64c54fde5f78c42f17d03351f529b2f3cc55b1bb9466889013c6074210694ba8c3944ddfa8722929e668ab163625f7cf03d3a61078fa779879d71879d9f35c1829c26e55e83adf9cb255ff4bb0ff7fa237899ddbeb2b71fdf93fe59de5f6418793464477730cf1faeff90781cd1ae17df7ed625dc71e3b4256547fd8586a819b0f26dc7f49adbe7f09fd7260259d5845b50c43071a2b2346410b054df91ca0b1ef371adba99a9d556be71a95ad49980d26185a8c6ae7808a999a34bb9375b423557648d6ec92d1a68e8aeb3152257fd3573477ef62471562ccc4474707c056d612e2f1863fffd44a0685990876b1a7c1a6c68fe27a1127102413b432700ea794187c6f042718ff6f6c0d5a532514fb5c83aeae80856d64f0d5c169e4119e56cff1e2f878855bf37df1a5fc22cc0c6c98a933efb111054a7538bc1c32976eaff63040876a34e60eb67e442f4c126442abdbc764ca1673e9a8a45a766e22c30224a2c41bc9a86b10d6d741837914eadb275ada129bf185b0b9c46eb35afaa91f133d5428d1fc0d251ea7e8e1e9db869301e22078810d9a459a8974cb822724f588298a4b0b25c69fd6888c80b94df1086714c726af358b756f1fc6360b469571aea4556fd16e8a2760a2507d92a05d2eb7f6e35e9ff1ded52175d7b163de694a05307c59ab70071fc791c81f0b8ff979e164e3d0e1bd3fae6d44677e4024273174119f23bc87abf1189d5a34ce780d754415e295301f711fdb51c80dac45cbb17f40095220a97a113c50aea2e979e044aa17161b2ae9289f408cea251fc0a36f84174c70dac9d7d4aadc4c3ed722e7c2ab3362e7e02751cc9f7145af7821fa032d5b3aba9e7fc3fa4e358501eda77ef6138ae9ff0e0d1cf1bfa184a350a85b5fe1e75293357819acdd3afd62137e1ff59077f0301d32eb45ce0f98d46a4d46727b091a64f9a798093b97b92eab9c249b00ad3674e842c58fa9329f1378297a8a75f1f41961ba3d9ebaa2ac65354d92af723edb1140eeb2b557117f04bff12fee3807f9545998edb4cd24ae37ffddda6a15eb750be48630bf0147a7c0f44ed909d96bddf04658fe009600344284124d14327f0724732cd16d26d9c4271653faf0646318bd4c9198fd8a7014341a0a8bb02aca93268aac4b99da82c7e5587e2cd51c45214cb7229cf9b43ebd20c72bfb14f73978d1a42c23e4a19434d1052cfadd44c3b45122ae519d2023d8bc19f61fed2f1cae851b94ee122aed9c09884b283524967ef9e0f80fda203827de0562e198c2e1f0936a1d0dc14c53e4a64e2de08e5cd384e32caf568e4954579c32a2fc83b6aad4adaa702b0e8d64ff2ba18973ee6d49a35f3c805393b71a1c8a3429d2ffdb623b166801409c82f00374482053462dd309db084a50b73f5ee42de462c1d4faa12d3fac9ea167dcc4b7803e2315bcca7a75154f5fe1802291b5eeb94647c580b297d485e8cf17d47b74dc55632fe149cc098dafa4a8c577c0d713db689610726ef5bb95f3e4ab1efff63516dd143f51ae6766f91c826df31f9a80e75b5ee97bea1e04d80677ea5ab55e08fe736d5854746185d1adc0ad50f3867058a3439d6d38618d85018251831d37007818056263c73993f21dad787ed20e203e3673dff800071902fdcc2089529557c86a5b842e7ef5c7f84022a1149122a8e17a059c551802f07cc64bfb93b69b116c247f26b3e6bc5107af75af33383b87313d3ebe6753b6d0682f12a4ad0b79b4e23a8760a8bf7d03fb4cc6e65c954fd578471313115ce7e2d22898892ea363828f9f1a5980509bc78ce5d32e048a0d86533c881edb05847e2e922fb12283e738f69c17d79229f848e923062247ab94b8d17ed6012d258695917cbcdd64a1913aace0b10a61c6c947798f42ec81d84f2860390d48ae9bcc269998f2c79e66ec5bea917a849283c3c705851b90043dc9c784b8e5762c99b03c4696258c194991e64ea43ae20dc996f1f86f9db8e670e56054d126a679c15eb911fc048700299b6ef609c9719e946381850d8129079a058ceb6252aa2322b2dc797415e196663f7cd40c5edb42583769dd8a547a4a6cf0a1d7f169796506bb6cc9eb1e6ab4badeb91d4335e6a9f680cdc4060b9e2fbdb87fe950ccb19928ca1742f99aacbb63c2c0a64d7698f654745d34155ccfa44c18c3a841390b6d38c97c0c2cd0510582ecc6bc3ad17b26ca34a2fb215b1a6e112ed79508be134e09ecf97a84ea5fd9eea2c610e4aa977da1cd9011207630af99bc0ebfb13da475e51a8b92bd80ca80017c1adb0b53d66d009cf97e8598139cc072c423441a75501f6f45ad4c1afdc6b7c18ede322a5adecca571632a7ca23e259d0b3aa7f207305f23a17e45d4a20deb6e684c9dde60ed83b6e121ce158c704ac6ee642644befb05667a4b5fc4c01dd37e4d476adfb6ebaa138e93648f17f90c963a989aae13e793d29e1488050d44ad528692c5ef8444193c4687d984ea17efedf49cd452264ff6916c5c33a5306323adc1f4859fc30df9c4a09dff6eae7240a7ed4d6885fcb63ee56e975eb90915dbe883501308aa36b0eaefed2da7d5f5e7f10e37c544df6f643a7611c9947346b59d71cc60c46a1d5d6c41d450dbb410cbf79f17e202c43788d89b275d838352962450fad12b2348404315c347c994688b95544b9f85be0cb3ebea3d961b99681a5b9bd13c329aa23d0a6d2ca80551323394e1fc76ef27787d0eb4b89606161cdb68e5f538a41c7528bd9b525624db2efa1dd18be7f14e7e858cab45b2306e726789d1776b30347fe90d023495b923b74d674739702c9b9901cbcb9a4e7d3fbde930d6ef6c1775597df630baaf859171dc51d1d93fad28e8a452ff234801a9ed7d2cc2b1684453bb99527263b9a8c11d654ebaa5c4d098099e49332a29dfb6113293932dc50d822bd19af295c1fa8265262dfa0a5973e750e33ecd037f8c76538ad373ad9f63b9e40e4dff4b85e67f79660e27ed1e45d10d710ff4b92e0e0a887bc72c915e5fdbe6a5f2648ac95f163a8edd061bad1be3234b27308c611b91043d99acb0f64ef6f6ad04d56bbc4e779248775e1bc128fe0118e33d3d6a44c0efa759e7d857a77b3436f6f03d455a29286c20e6d9162cab9a5a0d24d1c31fc7db8964be9f4fb6d7435a0f2d165ba0f50010af81e0527a6170e738ac0d3f3c1ffc77b2cd750627a768cd1200c86597fc8d7671a41f1fe151ea7437534874612c25cbe5a29bf7192c5670b807de735659a91990d10938e0cb80e9a3ec6d5f53401f3670b9f3c2cc31ed0e6cc1311a0eea6989f92c9e8ce89ae97073a0e84194827076ed2e7e2e540485e5c5cd3c68ba16aab9b28346116a97cf101c815257cb0012250658c798a256a8e8144d3eb0da89423721cb0a25132217968207a076f8e0d40dc0607358a35963e6e74ca502187012cd8405efe5070064d9f403f79cf56f66a0c0225a7c7a1fa97d0ef6563bb6a42564e43539fc60006a717829a05547a3b5af02c43cfbd40f196ccd5c9e4f037042c46439e805dbeffaa7ad0b5d3018f2f3dc72ec8521e1c5fb974b90503d5c76b1a80404695f710028f69e1f87d34deda7b7b28058a70ad53a5f74eb429c44a52f046500f5fc9eba780256c6961d14835dfaab413b21fde04a2800dfe89096bbc878648bb6880680d9047479687fceb201b1d57c0fba429aa967c96bef8e6f0ad7136670656078e3ee3fbb4d65cb0af1d4f2a0a1b85fe8e0862267f748390d8d45eb1d16e0fa3631fbe0933de0894d3c9697e5ada267cb8c050bf80906ee0cf5fafe4517cb801a1951b17088ec2512afa0f4be5ace3ae61c343c627f78e354bb97cd0629d1a6e924571008a63440fad7d5f69cb6378a2f3f456d2ec4f617f5e8ba8504dd783b650c988e5b49585048602970a1b5642a00089405d71ca4f7b40f617bbf36185784fe04ec4d9b5a83ec0fc96e1c76868e8ffae0e7532d6b7402e5864dc77eadbe9275e403bbea8ada205f2550c50880e9b0342851c5c53007b7d8520847fa489c60b3541aa4c35a7856af6496392486cb14bf83a271a3b693f742bf102c2635b03c601cd23efa33646f5fd9b46fa5e44204727ccbb221934309c111ff8758719693b6ba2e89d12a3ab6dbc7b243f4bf6c8cbbb5d257d00e40f3e1fa92a9b8e9e46493256de71d1c9163922ab0b2a7d0a9f5cc9a8ae335d000918099ca029229a66de2aa651815c8428bfa1b94782f799057549f606fb8ad3d58cf1a37065da603094eea4653bc593ba402fbd7b20a3366c246981378dd291aa7b44442e78bfc2084ffdf38ee82b8d612c7f020babeac14ce5e3ba1fb707dc997652417564188382db5c25be645a6d41b16e817488c1a5120fd866885048788d075226599c81c1df626c59c5add1e5fc1962baf239237f6430c0fcbf97ca33111ab99144d798e18e664d5f8e852eb48d85396620b0f19cbfd12e0d867aec51d53cb01a81382e184fe12b8e90f7ba568dde8721f7abfc30ff322cf097b48b8eb1ebfd004fa5aa9600184ba35118a8cad1620626be68c7bb9592970a2785759d6e86b80a0d39ba9ae6823d4c810a286bc913df00452d023c6e0eb2f04453fd514b413683505c662c005bfdd9be192be185add7af4524807145492000d2ba8426b0bfd8f5de09834e0ea1f36cc59e79388f0c9b695fc273858ae101d3bfd2464bb53854f9a82418dc01f374dbdfbc5655b938c3da8dd6a0a0ef05a0bdf496a7d24a919181709c5ea58313e4f5aa1c1cdfcc38d146b4d784bc92e95c47a132b7023b613795646873fdbce42803e05d0cd01a9456a3144b18020e76e185d232c6edac45aa67b135c050526101ef051fbfca73b21c0a02cc5a9516dd0e04ea10ba00e3fa2e674c251450122b9f63a24cd1f262344f9350647719dd8fa4c24eccbaef7c4768a043cae22a5bf7a659198f14ad7cb7533818cac48bb6fab60a25723aae79572e14d3ce7bb56f96c38ccd7074a86c5743ee6ce79036e66c7dcf7e119d5cb789e85bb10dcab84b35900e4d40d66c1c34c4f2f821968b3923fd314bdeb55be17aca04245380daf4d6624866311133b40e4993951ab5630f9940e8ae0502f8d62678ed5278773c3faf6fdf7721aa02af6bd7a7f8cf2f71adf29087aa8b6b77715765826b9f7cfa73934d1c16c50e8f9101de132a073a7b3fdb97ba216314bef4a53bb8dd17bb72050d5e4a7951a176a57d6a9b4eb16bf4aa854210b7496ab3a461c29ca6bed739e81f59e071b53447c40be7ac99bb6d166de1f99e073f392a193bdaa7eba1ef3f7f5bbe1c9e92e063a8a816e8ea3f3ff2e70ae67c4dedde7c332d6b01fa00b3e8c7b168791d82b8be9a15d6118cee92786ac1743914515100db77d168a298b3034ea20e4a4d5d024a470048598a83695829585f56d995eaf536ee0dd0089fb9c28184563dc83f1436837b83d7cc3729c3e9e10f26fab415d501835712bc23eda7a28c49a63a5d07d202aa2f6fdb1da32dc38bd24110eb63c8102e11d5ed1280b7ec3f741b7da61e7eddd1b044a973750132aee7b96c2d839e0d3d41d506bc4e2cac0d001170cfab6e2aa593b166b19b9140a4f472f02a51d0b38e31165294dc7a274ea029eec584048b2332d551be042a60c59cc91149f59b46162de580a2dd2e2e7d225f60a215f7b96b89968390c1496c075d1015fd598842b8612607d07212a77294fcb0a3ff122eff95e06a5a208bfd4a6a91622d34518b43f5c869335d82009033422fa0383c9a47c21a2f00a80dd96aa3545e1928fc0e47935e2305da3e61e48ca4d281fbb197c0b91c43cc1696ad70d51197847dad972cf9238f10ae36552ea649d176f99f987554654a6b24eeb74515a2e909a2718594f4a3b47b385aadc00ea8c6ea49e2c2f67233f66e14014592f92cb2851836052b393df3df7690ff668a34144b2fe60917fd8ac04d177c3669d12cff0be796aec9e94ccac0f0e024803def499f42c8edcca491055984141164ad60c442a9e344b62ed9d559095745ba141602fad45d1b0562d185e6bb8421ea34106620010d574da18ccfae55d55f6a596afff2b474b8ad57793be1d888fe579e4eb6047f7356e68ee30c442403bba346bcb94d66620b8d24ab0382e818fc5de51b503c6f8485959aef311a511dccb861f546a9f074dc0ed2028b02a44805efd094051c4a1e01d221b7bbac524a60cac58667888073bf6c4803e037cacbd4736bb1759db6fe3ba8d48298e8adee76750e04a2a4cc2c3bb2292f3122468a9b4774e4e91d088fb524ebfd01d29e094cde2009fc7ad0ea755dc1048f53dedb49bcb3d8a128f61c8f6ee56d8ec2355bc5af5e0672a9a0f41349dc3a8abea87c0d9deb8693180736adcdd35e07e75c98941db24d6fcf50bfa9a76055313fd48a8b6f5e2ff3312b9c492c18ce7a02f6cae990e7705512441fd1ce32c511127be3b5c6041b76d3bdb196affeb68a85dd6ae813cfc7ffdd8488ca98227914a2bfd21edd4e80e091bc8c3258540f3a9055edc0321476f940732778d9108ed69971c0c79a603cc46a5530199d638aacf3edd41c8d3714e6d4489f31aaabf52fa0a0d64743e87ee2e5d8f9b1b56365dda61731c39f528f477c2d232d62c25ea7bca7eff94333e9cc22a9c127b9d5e46fda01fe421fe41d7fa742c5a847bd351e9681830a2cfc31ef7dfda2d8583bfa70189164754ed51e284893471c2c27277a98016d5a330930fa3247ceddd90474f273a09f331eb38d09bd3152b1c44f5fba780c90be1682f4315836691597fb9f43e8b3b35240b80bee139034eaf42672b3b19014954e1f04ce9552d915dff0a9492a37f6f5337d4df34fe112d808bdf25ebc349c6f39ecc1cb74af5d09c193d11b3c798f07254258fa60231e6994b609c0a8688d707ed82bbc1f2c86ccfe380785bab3864d9de6eecb703f2119491ac75ece3b445323b0eb24c81b6890d5212664a8eebf31639d2250ba96994685805762541f83e458e8f92d603c08ca8c17ed410f4807b06a68ca6243052dba3d3e6a6e4d7ac1160f9e83a6c4a9653e718fd8a0d5d0200db4f5695ed3ce9fe5d74f104b509e917a9f537191e36ed33b7b42100bf2eea794d8289967b95e7e37d79be102ad82ae718160f1afa88c76ae2b6a617f7e93bc7db88e16793d2ae0b400860a8fc6eda1952c21931799da4d7475828ac4e29daef9c261d69c4e04aecb4340959db8705445ec0069dec6130f1d18a097102dab338325abc82800d14818e9924d351f44f95773d04f1646dbffc889a88bcd28467d6eff739443b8823d9a4cfee693a96fdc15da5a0c17566ff6dd7400ef44e48088d52ffca79ce68e2e23d73458f65bf9467956c74bd504377b207b4e605bbda5c8e6750d7b5d7dff79339e0895e314a3b7bf063d8aed54dbac394b6efdaf477768559e5241082529a7a1208e2fd5ba55d85e992ce90d1c5e44a2b47a97ee4887b4ca778d408fe721d0f9354bd53cf17c969f398a76e721a2f92e0b68e4fb10891dcf060102b484532149295345eefbd4759c0db7d8cf3dc88c6fc34e8193e93abba1622f89840f2d21f72ba4ca447e0b6f73222a32e56b5193ae4f2d2771120d0228072d7218ce77ee8197fc01397ed084346eac458ede2413e411fbc95b91e78da772091de8592d8b4356d43e81d1aa8651e463c219a120e154abab04ae4568b463f104b57296a9bfb39100d49c28cf1c719806fe0d79ee3d5e32619b9fb41c510fe83ec729f218884e7bd181eea68f415fa688c4bb37316878ac5c4c0d666a5d8135a3d6c827a00e2b9433325ceb6d7c0696d8feb1c950fb150ed54a0dda88a563a84df2b5e37ea0b678cab460c84411f1538d0dd65a3ec5de4cf0c3ca8b487da1445c6e1a02b97982a719828c486b34c59ec0c16f140e44813e2c38e1da7f54dcc7c878281ab1492167021ffe40a9b5c56715f051bf525becc89bd97e543a5120f916aed56d69019d8c1d703d1a19ae38f1791c4da632f9d0632d000ebae327488bf46391d0abc3c1e98131e95823c083dae1a30860761062cd2d3cb9c60463cbcb67953f019077f52419e385f410119636220194d6d1c48cdbb04d933a1e591ee8f3df70d33a92841a57383610298606a421e121aec7e35f1222585328614fadf7674414e635b36459bac721c5660a70d9293f4fd64d9ab6265e7a4de49c205353c8f20327dfc910d531231da5a562a7e28ae1192545238bfad2e616d6892532dbc09034984b5905956b2f2794bbeedfc3678764ec104f8507feffc79df90c00d614914a394954f45575f67fe4d6a2f823bd476d5ce8d252b55175f698d725bada9424d08b47413abf077ec37c03dcb1da1303b8d97e9f1a1c227a51101f6d75921294074fd37370a0d65541fb9fa4977de1d542b98d94742d08211b97a483ff63e4976a36f51ddd197a4e865ec7c3bece84d88fb3659873e5a2cb75a18288204276614bf7b516fefc2300761dbf29007e1dd84db6a51d5d02dd5ffe26010f2ccf569eef88e331d4d6e9b1b6d3be695215ab6540b5335691721decb8bc1301c0e4eb547d008dfb916c49debf5e3d5c77a5b97cf756459c5bcde33af75a1c9f5b432ee3a79e77d36bc140971d256e6a211d5fa17644a06cbd00e7ab791aeb804920d8410b5b79b4e90cb72a6b29aca3cef5576e268f812d75bc973f604e2b6b4e5327194ce84fb7b284d560589a67898df7d06f950f1300de90fd34dc1d247abc374610ae63c971482350d986ce88f111571a4165661b91800b72be620aad9fefc82310034053811a08f0f0aed56a4d8f9206f11514d1f0ac16db842515c04fc15be54b047ff9dcad7be144dc765ff566908f0044293ae69f991733cbe38652dc66fcc9413af71f4924e36add19a907756c38b3b5b801a561953994a3befbc082d13941a26ccd8e97b8fbe9d9edc7f1e827b0ae786657d97e9fd106d8f91e6897ce945c81932437b85ad516698b6b1447bd8a5298cb87cbe8616e69017a2314f53ba2af6c6ecc00fcf9a0da605a1dd220f483d14593ff533bb2e92cee4746b4a833330c9cd3bc648982e176d41d0e965ec1318ea6809e1c64c63417f87983714d25950d26e0e56fdbb8550baade8448fa485cb2d804b12016be1d9af962fc6f715af9cd141fc0b58f3912f599ee1f8de42053688b0274cfdc207c413296a3a768088e1f4e0bf6e45a89133932e978dbf5e3a42f71781a845be8b484f40114be285a63da57b6e9815bfb9062dd707f8e1716f7b527550b807bf6285b2707e9df9de14134906eaa0e7409bf4043f20671926abfc3d6b417d748df1cc1be5c688fcc91349a224196e9421aaeea1bc67845c58843e1a92e37fc903ef76e52f1b59018f1e4b1178ca28170a622bad08664350191cf3f90500244dd754327407f8ed1b3629dc3e8c7a2ef525899a8ce551972cb290ce4b0006b9d45e44375039b0c194d1ae29381500e3e8c51d3fa971bf48daf18c8e8b9d0763b8f141961e80aa2f1ca4ea20fafba97909c669fa4fa9db27cece60092e3ac5c7349985d925baf86db82c86295973d183cea0611eb57b4f9170d6a4a8f066230dbbe15ef97d14f22308496b62b16423af6c4e3d32d97539c01735a25548d0ddb49119a6989196bc81f372e2ede51187d0f1d1c7789f744de4a87de6d0112206268057e7fb982681acdeb6511bf2da70ec3a391f1542228c3a23b9025c158b83e00f03da1bb9e3ec6c2fe0989c519a9e9e21b4f0d8e07d2367d1d5aedafb38e87be4f808da21ff13417f8be908181af67ab3b51c8c121e8174e13af04fe85b93d4651f541f6db745b3718883726a25cf9a0d9283d1e1e8d598d121859e8b509da3e64aa798ad086e29028806c2de4438d3775a060943d0af375bab9284e3c3a131d981c8cc3785faeae24622e5f87b06fc83119f3f728400fc7d790e70572dfe909d11013218ec3e5ba52884bed9803797f11496292f73d795ee0206ed23225b5af1a9e8c722cb081cbc97a68a450d455e382fd2755aff05da5bab498c90abba44b3f03fe9257a4cbbee1291429d986f105d3d8aa736bdc624444740e3c744576994fbdbc7a1bf949ba99eb113cb3d90ecada91d6b758fbf07fe79c56ced06962a3d51181d8e47ff0a66bea5d4fa7f3d4d9a7681b99b497e57af3c437def6360a44f3ab9c8b7d3ba0f21d73eb093336846324a120e47f6537f532a8e7a328f53a9a8be269318f31ceaa25304a0c4db6e0ceda2d2dbc504cd174ba6f864510e628557f13643afd593c2e382339ce3c6fa24c00221250cf1a9e441a35af53ea6de4d014e37a7cf5484ac45156453a4c5565e74369115fd505e2ff7fe00a296712612d3e9714a6a38dc4bef3c308f0a62f5095588d2957f362fe5f440d820d94040e628174b28450f781771ab234b03a282a0b93b325fb5ab4456a32e071ed83b539efc35413e5734fb527a73e4e094407fb8e1dfe2cb5d7e6e1e4335291f5fce22afd1661185211a5fb0f6497f331f7ae3b061313dc274763de4ed1e7b9feee9adc1d319fb2874ac162d99cb4ca56852017cdff765021a388689ce8ac35b771b5acedc6f12e8d377a3fb10c126e1277a503af594d6976c6d010158ab9d8023ad011742b7e035bf9c29d113912b514ac01eef3d90a27845a4094ccf63c8cce7c3abd5aea13aa45a18bdc4aeb6fb72e489b2285cb736f556e712a6e1088f977bd27c953385a4f1db7cb1a9dfe14774f3b4dde20bae242d388c90b4ea63fd515330ada29a4b0968873d14cd98d0cc88d20a67f0444dd8e9486b0a957cad909885705deb791089b40e5e8dc4f21d830e9aac746c093d2f1923db53ee725f22da3ed90e0121ccd0a42e169586e0fca06c3e4e9fe7dea2c232496c625f6011b3b6bf8e21d2bb61aaf28f7fa3afc03b7e15e5bc40f858d723d1367e65871d8b25b8b917d8009084e69032c0a618e7b5b218928b01027b4cc8786dd2f4d6a846cd8e22f585d985e0b8300710396beeaad4cf252a27576f1459bbc3e4eb7c5f48cc44c1d5c1adc721c538c18a432293a310e9eaea5a1d0736bef4bb64c6dec56fcc2a0d75ea141722fd2f8f9ef1e15b70ba4d678fdb167356613e4e264181fef776b60a605a39629ba7c8675c456fcb211203b34ea72deba70129d399bc749c0411c7722cffaf43359c113454c07c5dbfe846660e374bdf84f022919ac66f9b73c3defb6db5849235548dbd857cea9e3005a31a13ec81c7a08e14398ee23f54beff73d8a8eaa0d7a658ea1142b219033070b373bfab879f5e5ee9a9dbdee9060d68f5e04742a65365c23685db4d5ada6785ccf70c96c185eaa177e407236e27bb4d29b011a76be2f323601103524a6678d4f88df32e5855b3fbe59f0b24ec285e85576fc6538a7e9cc75534e70816766729c05198fddb6e9d6c248d4cbb5492f10f8df502029027823f808dbe6b42df07953648d789633607a5f1d9eb5e97c54abb1c8f74f1fc14279eedf9fa96a2090083751e866af3c9ee394fbc464bb5a5922e65722ab1523502c0e88077f7700861148da0410fabbaf00ada3c88eec1de7667cf5be321f77838ba587be1414e9ff540ee4b1829d38d06930369fe3b3cb206157aacdbc26e446bc21a14d49034627bb476c9b620091431ea590dda99280725277e81532655e7f1e910470eb26b33373e3ea08d0c76b4424ecb0d79d78734df5934b548574b5944310697556b7bac23071ad838482192c44f7cf829c1a449d4d4661ca3a6862350ba1078e63619c5198378cc83fc1df7168f3d4b775a923c1287dccb4b8dd6280c5294ba3e59dc04adb14f461c1e5b7de9ea9aecd4550b85b681b66c6b637d8a607142f2d69ed1c25d6ae0c5525b48a63a13ad597303b451be63ba66eedc75ccccd40765fd9fa853a81e63e83292c2de8c6d6f415d8e6bb7d6c4bc070eb9a456a2cb5a6f59c532aab890a2f9dba868a1125817231eaff7e59268376eb51a2dc920d182d176897d5847b49c217f0322e22c0aa6ce63d67110bd3944a982125e1216505da7bd61cf036a548197034a7cc58612ea387a6a9dc9fbe14908908f40c06775da13e384ac2ad72e404435b387fe52237082e8e708d87f29def0e6f44f89e9eb85f3560d5661139281699a8f970408881320c1402bff78c3569c9484e13398030a464d8d764f6f70d137c341d5fd111397a9cc0deb4fff2a253a6148fe01ee9676ff1ad3db52c073537e72b869c4d247ee53461987b433d50c176b1b26bf032b8384944290d5fd8f6c7e9c1e90b91b1c15bda0eaec5dd6aa08b9ec32852c60ad47c4a7c846d6954e88da3586bcc26f1271e90888266f54b54e3bfe31c02a88a50aecdca378cd81c02189c8d46436ebb4cc9695347d33536bacb80d6666b0cef3f3a3a16a4b631d197ba1212aa92164d61aaf3bfafa3bf7e691dc2363f121db81e95c49c8f84ba8e26f54ebb543bc7fcc78bfd3e83d550b30b7e55f90b1864aea21c4babebeb3a09013c37a02b193d15697104f8bc56fe431f655eff81170712f0f269812600215c68cc1ea446548186c3c86c43504cbec79a8a53aece6c9d683f5de3c5fd588ae52096e3d9c1efab578fa0aa902257546d73420bf6b84954d7b8d9997e9f204279dca44742bdbe9e2ec542e69ea41927bea276dc091dc6409ce3dbcc514944961ca08e5be73918f6431acbedbbe3ee1443345a5142eac0cd457fa51671150092f3f9137f83866abe5e8a28079b36e8cf042c122d723f56d7808ecf26b1e2c3ac53a12c3247b13a13d5c0790baaa883e8e696b799b23ba58ead308890676b35c466106442e3201418618589c805b7fc2fc2a6b023d8471dcd6c083c3627c90964ef5313771e414cf48cf4afe6b6508a99202bc95eae717769e52ed24452c267b6a789329e351aade4756027b14949a248aedc23aebc17afea089924e913c6830cceff3a670460ba0fd0d1cc6b96e0cb33ea64ceb5b3ade67303547b7330c0d9ceeb6b2f71e6d60cdb2081982483567da1a1a7f0a413b4c6e720035550eaf902f34594addac78826b09b7196952eb72d924782296790d6734e0e3c29b414224564ecf307fbc8466b70ff638238977e6b2b1bd0b60dd0f1949adbaedce51d778e3a92296f96cbc047007c457de78093d0c6072d4e61430cc89167fc073d2dec81923acec6e5a896ece6307b7c4a62c542b4995f3e16a81c6fcc70b58c596c3e1879fed05c1e3639ae61504c48ecaea18e2f255ff09ce0568f1ad9ed298022b27980fa9da7b5d2a84e4be56dbc6f3813bb443892bfb698da902a9d7b3f85a86b9e6f34172e6be038704ad825e8636cf341e9a5b1c34d53b7636be62e2cc3168fdcf99c6d84544fc280918134a5a6b35fc3b817da4dd28711ccba44864cc4f74445278c841be91d4f8f8a6594a5104199e97575938dfe086bfa4616b742409f06f7df7da00ca54b986fbd20bed4bc881050d7b5c62a9633a778d15ff959b2832aa5c5565a55c5d456193ff6befde5f7be58d0054210fd9579ca64ab835cb1784ef6028df3a65c236c56ab5e960e1d8b1c7f2503f5cc5ac4b25e58ad55b452917a9f62d98e94d1fd58e2eb2a52f9269c14826cfd2e983657f83c1536b25cffe5e5c753aaf6a6ceea7c94302949ed7fdaee5feacc2f5d4a5659dd673d9fb45b948e8c36a65b1aa1f2b90c94a973938bc185a87d8563f9a9b3beceef98d3b4013b31f4fd9c92c6cb61bc65617aaecd4f5ad3dbd49bf93520a77cd506e41c28226aa6dc16f4c25bacd16bc889161b9ec39446b1e88e9d65b1dec8d575c568511d748d1b2e3e977b3fc91f2fc1190f0473601628284d2814dd681197b9a5244f379ef286722203997978cf5f830391ad1acaca6b910b28a3a894f807d02b30bdbc8a2bfa649b1a0b10956c055311facdd3d5ade6339834c085543ca553d7008103f43b58cc96a4211f35f0de33033d0e73d8c490e83334d4e7c8b0a8dd8bf686f4cd26e79d191a6675ed85f72c52b4a86ebda19cd6ed01692fa9263ae453462e331961b2a862ddb0b79a3341cc727fa27d4202a0bc98cbbe698848b58a0ea195ebcbcd2b58df7e628b69615ccde5aaa14f8eb9869769614c64e55355e7a64fccd48cedfa2076831a0c0420d736ad59ed31a65e55e15255729e2eacf88ec62f0cb69476ecec16a814f705452c5ad6902f72f8e3559a838fafb4acf35d5edb502b9e5f2c5c1517b616a1eb76c0f9d6240b76bdc5ebb0ea3b40145eae000fa9d42412fd3788d9e7817185b930a6eef4895c61c37fe7cc2e3f8c71e5575cd44662e08381f314e3251e35a24a680b97af984818d3eb8871967ff84c0409c89a1c70511bc3455379204aa6f2764eef76652335ad9a6d1632d782d3b955081dc72f9e2e0a8bdc2a42c95954d9f7935d0598f104aac431b09d73b58cac47e2a36e4e207fab3773390cd83e50fd37c0bcfb587ac99b6f30375e980a840260b203b79a7afa81823cf02287609d4fcfa146e6ac642b4158149f7a4cca0557a69d3ff5f733edf3e06849a0845742e0e11432d494b6bd65f3689b2a67d531ab7c5e82fb70ad2340e30f2c49a264496d0759224323f63a1895a43fa3c44c83073d943648fd414b3f74f10e46f770adb19f5470b7da00abf5ced32b191e3decac62d7a97463ca5244b40f915955df7fb20f662431676038156331062ee94e1347c5ca0f181a65049218917bc12405e33cd2fe3ee1f468e0726b0c409af029bf214d61dc0c0cdc26955765397c77a12336224854e61959e735b0be7b501e4271f0f19b2d6b570a8cfed4093062293ec7c2c18e22c7cadfb4e2fd62f5179b32e60a376cab08319b6a348108d2a9deabbfc07b9526d75a32ad05085d9c3a9b9f47e6e0410948793a11c96bfad2820c6dbf540a60620bc0efc338dc9522be3e8574c422f7b0f4bc128fcd30dc95fda6a4a73a5c2887620e5192a54339703d79b369117d603c9e1a83d924215c7aa3eb12bed2a3bab202ec14067168507376f9fa2dc4cd435fe57559a934d0d50e8574f5b811ea881ab579de04b4d46a55539326847741eb13dc4b400b5cdc55367a0dbd46060ace696a280f638c7956480fda1a8bd91dc95607f2bc00c2247b9a5eaf478eca8d1d8bbb312f9de172b5b6f120ff914c48eb7de349a497f4461a02f9b5e5eb43457bd2240ba523ca04570121b817d007aeeba11c17e756ddf3364bff5da359806c705dbdf8cee8b7e48dd417426de632d27fd140a53aeaa62293c5dccc2d8b6f4a9ac9b0734216294d209a58a788fa18c75ebfdee7a92268f108b12f4c1b83c9d5be8fa4e346877075b41d51a7c6c5e9c548b83740995a87fca255ee89ace12a6493c9486eb7dccc9b02d67f53b846bb05afc56b1a064d86080258d6175492516995a19a634c37707721209125d6362cdd600adfea90bad40b0eb3ec7f8d9eae2488f5a86915a29d3447e7597478530a2f086ceb2d4f582cd676467804fe98e280c381dcb2932889578ce6a8990d57710ad256a6c8398ee412649c14fc7fdd1a0f3a848d482d2e3b770e00d5eed8f26a12f044b8e57578687d4c93bfb88df125fc104de081b3a5b801e26e2edfb4da4e3257fd7d10515a2ef164ff78c627ba5380f704c3bc0c093d9b32cf024487e491f4d2beb110b8aeb8ce70db4006c240088f4d1a60e414a84d851501418b21eb542bee74d24fd3a6b7524b19491ca8724ecee9ba9b96b3f26d3e4776ffb93148c45d493a789d83de6bebee24461de41e017039d1980b67eca5c8489f14a4a75d2221bdb6d479b6bc9814e5b312d2aa485700190a83e0df213fafff6e158e50cb05c570f29026ad700ab9508df1c1c10abd505952ca0e6c0c6bfe4ae3b9ad7d5110f11325650a41cc050c28e90ce815c0ef7fb4b1e327a5cc2fe24afdf46e4db41517350372b77381c69b8d00a98b4ccc451814feefa516035f0b2a91bde09db77ca8057d4266b2951775955dd0541cb34d74a4db39d35de5f9291f4655c29a7babac2dacdad8cd37033b9cae554f05da38a321b205ec0a0805b85edf40966b9acf362ebb585c58bf467e4d5025f30dc1d52b997acaf80358711f41c4ee3da5c7df582e4d87029229471c5d06ac69cb5f138558ad1a91b2c7e5d5308856642827eb4799233ac8a58048dd2ee3a254a5a13250328a35ad75c505aa6ed342d53d0ae11b2e91b32f97aab90b0318a6be6742987eae3fda663b44812b8c924db6c539a63e74c1573b22b4b52dbb1d3a6e64c2a07248e0af5c7f446470615049e9f6cfadb2989eca66c4bd6877cdc4286f4d0eee92ec82a8185af5203ee8368730dbb0b9257afeca0a34aeed888672ca74b2900ff8204b8cad939d07df4c215732b11d4fddbf0fcecd2f41bc3028674bad903e4b0e2e362dbfbcbe471771de895363937a63cb5086678e3594e7c09cc29ae4bfaf2137e086d5d4c28a20aff0e24777f5c5aa0587a5a3e82fc009a9a873a1f3a06fba77772716228f1c7c5abd2a1cf38de455ae8bc2c5b08e9fd2e469c4ed41bc27de3caa3f82ce00d8f2d76089ba66d4f00d13d0c5c57287aa6b9fa1f758f8b76caa09b662964fbd719488ef500197caff04c751384a5a83e4efc7693bc727862c04231f9d1ae15b38e70cc710ce6d4521bf6e4e7b89c0b369aeb0c8c6afe240b22d814b5738936b6495f33b5f5cd4327e264a1acc9f7d2080038694af34dfeb4a69146e8b872917c6b5ad755e4338b3a191fd6ab53f465e571d18f5e8cc22f4633afb92d01a8408247e5449f3a41eb66c959bbb9ef416a0a790503f534801a95e41dcf8284b2ed1d91f2a4bf174d264a33ac7d82b188006c8510b0e394fe60b84f352c8f67029bdd15829bb65413f0a650ce13170c7a52d61ce26cb36679ddcecbfd34ca9a934bc5a801ffaa8b62f78a2add22ce17015ad01b06cfbd1c5c1c00ee4b7129ed0a142394784535ebb24f2028d9632d3743c63429e5aa5ec2f0bf5939632a569cc31faec9c0f962678c64615f7eede107911a7feec98884f94160e2527541c728e620f708b647d54d96e3c4e55e85807783df46bf7b5a9640f71c8ca1b7f35d369817625ec824efb6f64aaeb98a11f3d5197ceaf3f2129720536761d3ef4e0aa6e9cd6201b5393e55ea6570849cef792461ea65303edd41e202d279555107e2a8a81e135be8acef324c421d19335d1f63f7b612623b46a182a1d38e9f8e0475800e010f586ced1dc8dbb49751023ba70c27e4a7ac8c6cfc045b65fe54d7842b9eec6768d024670413c49eda57d780e3a745bf8fed7490fe974737a943cdbb9a1c7e309fc31148f1bd0aab135e5adf6e856af3383e1d7113491751638caf37f2ea9de3917e680c77fd255c9d938a0080bc9560bd889ffdecaaaffe432e4bc8adf53b0f99015756ce4c5e435094c5742e751526a59c212e9042967502a53cac0e541ac50fef424e7b19bdfde79c4d13d53e467892c91edf86c69446a5940ce242a0bdb726ca17945544e3979aa8591a090c27534cffe9a5aae4bf50b39ce66468bdfc7601e2ef9d47ea32f63e3a91c22fa4960332565401c977c98674d675c281ad91842aade990dd7325360aba6a77b60ccdf76beea285c15a22233906ce039b524d730af213b3c5139355e8572ec045d2392c05f0a1c82440b3df97b515d912de448646f8bc63a710dd7c05481eae14e120a25ce9490f7000d134fa9cf3e5904c7203137e5c6b7999d073950166a931c06454014f521c3c5280395cdf99786d0877f51f800b92774853c0f30059c8423771ea84e06bfba1610257ca8c989aa7ecd5e73def82b538d2986bacb6b0f458c067934cd29ad551ea422742c3e12924a7fbcf1165beaaa039cb5fbf55eb05c819ce95f3f4ec4b11d2c3655b856b53e106607f9e9c8cdefdcc88cece54b01c5f81b46146cd146b7826c7d9ad93fb9c186cb46bb7e258e5e83a905348171b0b0824e7aa121c53384844e542dbca334b7310436c0fe4d1365a2301e78f79c900881e124fe20130319dbce3d4c68b73290677495eedba5caa53f8ce246a400412f5f1f4be8b6f13f6e575c1571d5ff6c274a8064591eec224ca81146ad772d3603b10db186d22c6839597d89e6436fb28c4d8677010e7458a65651f928567d4dad0d28e1c4728f056dcdf30cea688d929f439986247e173c685394b07bf4b8d26e916874af3e0a6e650a39e2a3fe4a9816016d5aef84e3cd99ce6c1e93d7d56238f53ad78dc0f4c386a5c21d45b243902607a9cf730e4183518bd2d968ac6ca82b2fb67dfb2f46bde8478e5c10a5cd7167221e392f8478ffac9787408f35c64a3009e904186b1179b94d571a5e01d790dc684eec09828914f9c05facc660b003d1b98b9301d722f6198d040377f0b3e8000081676ccc0add35383e5b2adf3d3f8a461109e678e97697666712eac072090eb94511f3f97e905186cd32eaae0e6f196db5c1123437884480b2ccdbb95694bdc0feaf1f2391f020c9457b02d1939c83b386759c47316d2cdbe8c765f2e25df05995f8a3eae348d3c5609642417015d966aa991974ea66ff3176d08d00849d88808a21028a8b6ea396daa24d99330cd1d3f390db7ca46c0b810be0420ac4957a0e14a453225320501ca580345cb71b3b567b3e487cd764cf441fec6246e89b129004182b374ea4df53bdd15f4227dc88ae00c8216c184d75ea8aa4a5d604b0c4403ef80f42c7152bff9ba9a22d30e34487bf0033c21a29d6407154ad64e87e13cd4e2c0c6d0ee0d59421f678252840cc19723ab54803f1adb66eb9aa56465c079887d09101e62b23c4e513242dba9994dbeb241ca16fa8888617b6cac2258d507a4bbd8e428dbb8ec71d341c186257cc8c0a657392a239c9e2c15771d14e83fb8818757704d07e07887e106b37587cdf9dc269a007a31d5fab398ccd4a09549ab9718156a892aa82a26327347da40a065ea5838f4b208fcaa462f29f718d981253f769071ded21064702f49697ecee70965466d56f6c4e961b2317f379f657ef561a6d86b05535726e79cb89a6582ba228f29402913164dea1580003ea5c17e0bcf44a26d21dc189f1b5996351ebe9a9ba9eb08675d167208e1f7b8f3c655b05a67468ea6c7d8612ba0b7a7cdbcecf735568394b404c0266f480d1800e7935342272d346405ed2077d4b16529302cf50be2c4150a112bf770068914ed6ee2cb73b4ce68c80e087a31dcf01f53857ee3f04bd3d6385bb3fe4eb47aa682a9633f299ab45504fa30bba25a20181ea50365fee81889443650d29450a0329046b6fd2852c97fd42a8d6288a74733fb5daa8a5734901a1e8b0e40602a430d721efe6d486786ce9b85da93d80e8c0c12dcc87f72017ed466d1482344eebdb72444ee2da54c3205c10a8a091d0a1308cba1b64dc68eb0d714614bf5ab5e0e1d6dc5835a870e09fab0e97dfbee9de3d9e45bc132489ce3d1114e7ff1e30f3cbf6f228fe7348ed55471ba8b0716decca75e101c250c8f1d613e9bf0c40b7a03968518443cc142842221b0603efca00584161fb21bb020818926c876c08204ce5dd4576ee07e61b1015bdcaf971280d00de1d323134b99ea51a7582855d0475d3ae9bb4164e7c60e2ca3b1ffe43ff91f6a471dbd02d4e69c6d4347af002f4ee3a04038effb86fee6e104b1aa94ac815299e4df8c73f6c0b1c8e284216459c214ed20adcaa6ac3d928512848a7670430dbe60507c5005113ae860adb5292f70b6b8b1e8a2c5931f9e40825112580f561c618c0c0c1d72d87a10460cb8f8c1890d37f01026c9078717d20b0b24271886611804a6c082071f2051f485123e8412b0c801ab825a11461068b0c10b0f7c40a58b2864c000dbc1042fa31f54f811f358688ac30eb04ad3a04783fb25c50e1842083d5ea14165ce89655224ad70bfa4d062d24aa552c954a158cf81af570babfc8395d3b66d474cc22affe2b61991b84b8da37fdb5880f13b8f368ebe24b0fd7a15d5c0fd7a49c14f8750bd94e2c704710047588afb2545ab251936e84816fc19c5129cec203d4631466683fb15450fa2c892443d5284a31d18010544c85206abb528acb8200b31b4a0610c1aa81811a910e560ce395357c06c81c208cbb75108a9748840c83be79499084dc909657b944c53652050d1875e06fbe1959e11986300810ae718700f7c7989a832c5aec1fbf4522b36abf2e71bd65885e3c5994e5e3a70b53419a3d795a42cda0ca0d71357b61cbd9ef882014df11b29425ec54aabd5e1e4e81568e9538161bb10c202a0e8af4087e025136ec0b1044b107e94525a81a7115172f4e6681cf355c0b3051c6dfa663ee7cd1c3f5234d5e444707cf8cd99b95e20220752be1062092928c0747882f900290618866158bca1e70d3ef002888d0745d002872776488253ce2909a0c3133e5a580cf7cb892710c087971361d897135f946007a9c54910aa1356387105899a52428c51ba7faa7eea2e31eca252cf11720501fdc4169824a4a32d46af22a221215710d08fb7c024211d6d317a15110d09b982807e602b499118601812a407cf0ecef72a4be30d6d9f2224c51525080ad0931f9fd90a03e64b9217a42e475cb66831caf2ba526485a8cad0142129ae284150809ec81fe9235b6130982f495e90ba1ce1c8c5bf2d5a8cb2bcae442b18be4cac2273641cf20f36a055a9e7c0c7b056a95494cec7eed481339940972b68d950f6370ea861d80fb3a8ab2ab61fd288f147e3801826bf3bdfc02adbdd0dbd3b5651a9e774e350bbe9dd6982edf78657409fc6d1bf42c2c6306cfc9294f26569963efb5aea52e931997d2c956ec81c52874ddff44b69a5c280b319638c47266e2fc678638c5147e3d0c2c647c2aeaad8f89d819f4ffdc78170673103b2f1e96331fbf9547ed693bd7c2a367751cc30ece6ecbd2ccbaebb32170aea9bbe34c677ea39100ad1385429f78edd1da571c0d9ded0c334170cdfc6dbf48dce417333f5af1b626424f12fb61552cae8d0217c6c4305dc10e78831c6d88ee35f3f0d42ad34424f7637f41a6608a3c396d808c4f16626d82f74e853d8c611e3f412c4be144208a97cf83146195d89fa594a8fa671cc19259533f60d7a851b8d634e2d621fb10845504d1822125eb1ddf276479af50eeef9a7083d6b658c56222cd5186354417728638cd325ab0eee170f5e30f5dec6bdf8589884e49f8dbb5f292a65b15008ba7ed502d4bef49ce784fb2ecbb86f4c9534617141b8cb7de699ae474d5ce9b94c268bf52007f227d8ff86e14ffcc77390fc5d2e21fef96b5e10ff6acd1238ceb3d38b306dfd80f1561218a4a4a38c3e7dfaddf46b2398443d4aa9c948c42068235cbab9c91026d246f46256544158f82ecd4d3ba8f33bde28638c32668865308319cc604e49cc331235ffba6191c7de4e187032e45f3b0cfe3915eb5ce94df533cee6f937717f1edba1e4246e9e38afbc99480a639e39a9fd6da3b54b395b7677cbee38e38c33ce39e7752fa2e085ad31d41b05a41217f221d991e5ae78033f85969d0f1f7ef11c5984096a7002777f1912496929ff2004821204e4aef81e04545d5268201272f9073f432ad65d10097ae9241c5da631e2cca49765524a8a69190644624d85b9749ffdc5a750662944c77cc8d938e263790458becbc611fd739904991cdc638cd15d42f7ee6e82c148c559d3e590869e02f78b065ce0eaf0ab77a418ca17f2414b4a8fbdbc13a09fbd054a8ffd122a42b02ffd92ece92fb9b01597d09ba16083758c29814ce800c40f2bfb2aa9bfcf9f71f698b3747bbc9218af0a089b2110108540f1e6aa58603304a28fbdd35f82fd5c42450866fa55fc25f4aee21582bde9b1a75fba4bec53ec210a4eb858a5a75fa262601727de380b99a784092c3a4a428845456585092c42c207894505aa9480503c080bbd4277bd826b627705e75dc1f916c03e7b0bcca793e54a661006146fbc95c4bfde02817a2b02b56861f8ace935cb814c4bb877b7673de7a440d8ecda60118a63d21b8391a3fe61de0e367f37b20da689db8e4c857d8ac2ed471388336c8ada36d555f686e794aae9bbe3f4ad058861961dd91eb44ac76d9af7e8b0e96df60d91fdd1f7cc945d29318d086dc77322c690a27cdf7c4079537e63a39277020725580d840314d6b6040e9660d5504103ab9e208955e32809563f4ed4a971031a585dc50962c0eae7893a359a3062d598020c568d2935b0fa87449d1a47f8b0da280545ac0a861358fd45a2ce0c0e5ab07a0c560f01074fb03a0b568b210410c2b0fae11735b01a0e5181c2ea87425147c715376cc16aec0a56aad503ab1f16451d069c008a17ac6e2e4760351080c06ae824071eb4b01640469820b0ba817004563f4c8a3adb1090b8c2ea8760a2ce0c2bac2d095b7c60f5fb4fd4b1f185d50cd0a18b1eb0bab9d081d5efaea8d34f6869620b963ff1a18b18b01a5e8185cb15ac7e278a3afdc4d018276075562507ac7e7f459d28041a7c7e585dc760758d82d5375a2005ab511083d5ef495127e78814b0fa1d4cd4a1b185d5363becf06383430c58fd3128ea94acb04e5a94f8c26acd05464060592b395ec1dd6ad5d062e598c5b672d412434551abd58223b072ec82f918b5688062c4cad1cb5cc2a8d5e202042bc72f9468a8d54a4207568e61729c50d46ab5845859fa401a865a3e43706165f964fad06ab55e50042b4b2825318c5a2d22a22cc1a8d5ba8207569652a018b2610b2c7260653905cb51ab25e50656965588306ab55e70042b4b2b520747add6105958595e916206ac2cb35001d46a4d798295a5162cad566b4a1656965c8060d46a4d9982956517295cadd6942fac2cbd4cd751ab65840f2bcb2f9507ad56ab0824585986d14ad06ab582d0032b4f9f1db45aad2d64b0f27c5284abd532e28795271428865a2d2a62b0f28c82671449ad16951e58794ac15d049ce794c8c59b121105064ab8683084137e68a1e086ee07a024474a10a3862dc2d0a2450e48c440e1435f09e20b134e98f8011440604f4a0003ac8a124cb181e27e31618299c54998cc09866118564312a4644e5c590d4a603e3870e2653a6902f37182c5886c87ac86221f319ca8c009941a56e083854fd0124e843003ccc70a4c8ae924cb747202d30ab61ab0d87c98e0848b520d5e309f273024d42838273d30dd60d2a20626947cbe2825ed207d8c40392182fa184d2758780d48d2490d309f32680d5a322735d48004adc2e704196a092c2b4a90c29ad86ea0e2414703550fba329ea072123334c1dd2ae6e177f7f5bbdb737aedebed89790ecb486c68da69d358d0fe64e266688257a8efb1df3dc779317772777eccf7982e1288ebd7fa266f65bfbe49061f9a0fee63bed63aa36e35dee4c1168ed15a78f3f29199af41e36df733347e06024d5adb68fccccc8c47bf763450dbf7a3be7e4dea6b6f3dba4a205dcc57cd43691705adcd3694d679784b79a798467d95b79bdc6bfdf579220daf717b9ef5aa97a1501268bcd2ea6bf5b91b33540e50a8dafde9f439a6c66bd7decb4570e5acbdb948cd6ff6e65ae365319f9d22865dd73dcab35ce5b6cf9eabd63eea3b7b5731319d8dd96e8fc6797b24367077572894e5663c279379ab1e8d536f3fe6372f23b181eb5d71cfd53ae3ae667cf6b5a3a152a95434ee6a46ad3277d575d90ad5dce937191999e7644ed9766580486c60ae7bae7b8ecb2bd423b1814fbfea90d8c0a9bbdab2df32eeb355f7dc67dff6ae50b747e355ea7b621ef5a998477d4ccca3503116d5bfdd1e8d4fd77e67bf7b6bbfb3dde59ef372132b57546ee308198d1da9ccb22c9b32fbeac9995189bdc96b20d208c43e661018f612a9c2cd07166594df110806047b1963bcd9b1863bf8c1f027180c1f8b3ee6bb40b38b4120d35b09e978e3f21e8138462410c326d4593ff328eef0b67137f372924c71a642666e8d6c7bcdeb18176e5ea279a8d7bc7e2de6ceb83083aa713bde7030cb31cca83f83665e04647ec6631e90eeb7afd0ab368a4a6fa3c8bfd69b9b208998fee6ad7cdc9e52c43d343e2b7de5beeb7adbb29ff1ead665decc0cdd4cf79907b9ef381fdd73d9e28c898ffa5a7df8dbc60477db37ae5f2fc775377fb769db6b703b3dfc158faec77ee32311c2c6a1799ce7318ec5dc9c3df7ad3dfc2c4391163e126b66840946b1e038f38c408ccab8ef47fd8c77243e5cf9b83ddc779fdd1eedb7245d9793601822f5aebb5948d73d4fecbc0c5bd87ef5320cb82d77336cd9af50832dcbd16c07ea65f5f2aba2f5ecb79b5da8f1db6f31a713fccdd3eefc2ce2d376a7e6f59c2e1288b35fa14ede0af5d99fbe5e197c74cf3deafad85efb2cbb4822ceec0fce6e0ffc7ed8c21a677b647eab3f63860b333366cc98e1d1cf4af565bed2e7b22cbb19e2da5e861477ab9ff92cfb1a5e6f40b6ea75f576bf09e12ae4bcecfb67b84a5da8b1c9788d6be94b5fc38b1b10fadc975ca871b99bc84526b2373d8f73dcc3af35e67b8e445ce37af5b2ee6b78b546eddf8a6054cc968f64db8eed396f957d97f1787685d4d8be765ec6715cee3ea37efbeaad3ad40af5fd32df7d7dce5b718ffa98cfbcd5e9ed675f65bcd4b6552ff5325e4dd5cc6ddb738ff2561beafb538f7a6b7ffb1ae3699ff2627ee5cda43c2d06e5c9004f57c8ea57ddd7f899cfdd1552e36736eb75bff2666a78339f79dd5b2feb4d488deee6263337dbb4ed884724e2ec22716c4309ac09eb0fdf48f64fb1d62a4ae501bff4b5e4d54e48295b21f6d27853aa9f6d6ff2b8bb7d7ccdeb29bde94f57156f4cda735ef6dc9b5cb0b7238d3726edf6946af7b5a4752e9cdebee6753727c10f79e2f6d27ee769dfdd476d092e7d73df516e2e9c6ec79b8ebb99892dddedf4ad952a8f92e7037ec97a27ea82fd936f3c4a3f6b12acbdbda5ef2fd19c04e7fe23910eb14bb0212a0ff826887de6955694529e689ade95b4a7268ee39ef332cd4df0f63909debc9ef9be65bf651a7dd373f44d4f4ddac5b6db33bf6eb908cef47b66dbb671a026d99163c0d8e72218bb997e73df83bde9b96bfa8e01675fbf1d7bb941a0095e75a6ef4ccf5d53fbb7dd9b99e04bc4e9a58e3d5d7afb21967510f7b6a374794cf8990ff8f3963c8857a65ff9b8d8c49e2d51b7a75f79401ff4e13b2e79f9c31a863f4d25ada4693717f91efaf135edb5dbfed5eea10fff74fa7af2b20a9fe8d7a89dbc06d2bdfd9277bab9082e55d5e312f7f2e310acbdfdb8eda8df7d8c77ba9989bd72f3e19876d7f431a51ae371f5e2ca83be0ff854f3aac903a27dcd9007fd69fa7ab3e91e91a5928f1e4cf001302feeeedeb50df6ad7910620d279401e2f852cacffec88633d99836bf62a68961d83542b33b03f63360d894917a0c43a876dd104a2803c4fef1b13fb2612cd29f5e9c7f8d6417890772130c679833cc4772c2f3ce00ffc826af1107c3c33ef6d682ec913e9f05bf0d53c8472046e23fbd8629e0e8829a24a043f718a59c13c3324a4bfe512ad15dde4ca394d11d4aad524a391ffacc4d5a18c2f70f2787841f3ddec0813b50d4b699c1ca145c7ab9054a165cfad209c3557c8927865b32188768290e15c5a1a11987e250f63568b08da314fffca97fdefed92d72cb9d9fe116eca85780d86112eec691a11658bef4f6a48704627a73fba77dd98d4798946a8306b604553318d2b6adca703fd5fc53f506e5b7bb175092a8e76834bd83fb5337b04fffc3c154985723088bfdbc99f6883a4d55f87495746f6f4b2e36f76b02bd820c1070fc20bd02f522bea3e0c5f2f817ff42b1f187449d8e415e9166c8e67e0d7905c1b4927743a757a08ec10d48f6f2d634c1e62638cb6872608564d96d9b1e4651d5793bb17ae9e75f5954c1a67f6c2ad53719cd943e9f4aa58770276e3b7947339db49d9d5ec171e95f88c173e2973e01ad43e34de96d13a552a9542addf0aff4d0abf793a7496347ed665aa2115e161e9bea4308e3f6a3093679d2bf4ea202de6067bc7400d4ada3d34d5c83de0f65613f3d21de6261df5e66821b89c4f3573ea00b4f29c4b2b039e52502c3bc8e37f1a64b8c3addf166d88addb171b401ac804f98e8934e13db13bf33ee221d8630c49006dcb73d24b2850ef767f92b1f262caf912b300ece5d06ceb1210bacabc0426323b00cdc6d44766f2c50ed8533cd6b074838ab6854dac9f60a2aff3aa8de48c10e58c01becc45db443165f149c35ec7d053eb1f0e59d510bc0c58d1e0a40040bbfb5da36392bc231c26d488e4038027928f0f78490d2c60f16c3cfaa9fa803595a8df30a8e39d8c679fecca9ddf9439b5a193f3e1d22a9a492528993c373b2a7b452fa254c353b7fe68fcd8ab227f03d258000d0c5ca79058531ec7c41f8f13dc720a04f02277e4ae5396129009ed8f70fca1f2fc31ffb36b039fec420cff1279e13dfdf15853c67e58de1ff60f8ffe339fefd8a51081a57d81efdaf69349988afa5accd9b70b08fbb0847881a7c7181e784dde9d18f43a343759fc63fcf47bc4a1370de91b2fd5f08ebb9ecbcaf9ac2e66f35bf1ff03b6e780eec07ecdf63becb2fdaf9f58d63c9e2c252088c8b0984e5f4a1819d3f77b600f0c4629fa7f7640a24dc2f2c493970bfb02881bd28ea74f424cff9e239d8536aad4af59f7dc99330c6f82c60eed1344deef14449e341b192c6e873ba43b1be333d27fbb983f30c4df24ee6e520b2133774d8c05624e227bd817d9c77200b6cb6d8230f2a9511a4607f9a96299bf96d039bba0afe190faa3f4d0a435e09c8a6704bf1830d70c0f862849f1d0ca8c7173b3a3a0b3684fd69686cbadbc6a87245a11f8233b0425f7441cc2dc1660c0828eac496c4801a03c2802612306582c568c0fed15f13a971fc7847d88c8393031ba24540571c1afa420bf64f55e9621176e872211f7215fcbd1b6c76210b7d0862e853a80c611f5a41c83f77a1298dc387a20f6c8e4371c8e3908d2245684a169b5bb168b6aa0f95f9363c0bfbb611b28408c75fc5c07a44fc359fc8c23b44deffc1c691cd2aa3e789371907e70b2bd83f878a46472aeae0dcffc1661cac81f7c17616341ae8151a0f11e239f05a213635a968a9c0b8b0bf121ff9363c8b3e0621ccd8c4300cc3ee4ce22a804912755a9c183653087443f5b1e16790abe02fbde97215fceb0d6c76232ec95aac1575e43bd21637b253c8735e5f68f11c0f8a32c5b93061734cc2fed5b760376a1cfe52e6f862e1169cdd08c98de4c55aa61cd86c53d95114b66dca46f3a1225f95020c6cee97e5c2661ba5b0d94ee1fd1042082184dd72f6ecd9b33b1e51c28521e7c3a3961747d83f55e408f491574629a38c52ce38b18a6118065d49112fc93dd247b08beb7ceba936212da24256db7047b0340cce30c8837e9e508d0642894285f5f716ce306805bfbf0a2f84b03fcf8e0bfbebf0e207b3dc85c0b9afc8ff6c3a1fd82d7ed34714c926a97a00e65b7ed33c55fcf80d069c80f19c24f8e0238e6790b874c2400d40b5f2c40a352712c28d31d0b2e2397d8597271870f2c573561870f225eaa0be7bd95ff2eb8eac8b78a20e8e6f363552d8fc7f6505406c38be6f3e6a188c79c4255fb00e143086cd4712c2fd42e27271bf9088f0c72094e765e9674b64e1e72560b07fe45183b1db8d63debc2409e725449888bfe21005fc3a0d540034c2a25aa9c23305431d104ac110429d4fde07f0d44461db891b965094420bb500c718a54c410a9e7640eba85a075509f46bb0bc9988bf70bcb4461296c61b252c8da276d47126e8c0e5d55852f033c452d2647c91c31616930d08b6a0f809623181b003b56d4cc0840c8e581546814511ab8d78a084114b053c60e16209c065049722569d5ddc40882156c54cb04412ab662ae04110ab9b8002c688d542b0c16788d55f04e1082256ad5af4025084a41b92584a04d022a208442c260bf029c20fabb1f0c20623d6f7050a767f1bcfa1c1fed45ff3af2d27e5552202564361042d7e586de3d1871a1920060f492c252a5811c6118b09aab5c5ae8448251e049630462c29fd8bb025bc42861118575094167c253d7a83a10130a4b67130411404ce1667095f46081d32a1b60d2d515a8247248636efe0ece8f01f9e03b1a79023855ec133d3f7a75cb31ff4e4767568b7fdc6e10374f88d27a015d0381e4feb04ec65af5083fbb71da58f1efd92e7a3e1675007bc3ba723acebf09b1d1a50b025d4b6f96edadd6472ffee99be898ffb73e933897dfaac61449f4253e9a6fc939a855f189ba9dfc08fa988fdaa1a47b4c266faddf0bfb468e2a07ae907ce340e7fb8b1007deb4ef9d7051715f42256b547d7a9ef697ed3ad00c8650c9c1d6741f8b0858ba3219c298e9716a17295ab5ce54fe3153aec57173dc0ac975b64caed11f6039d8a4aa148e44352e89314abe1353affef31f9ec43ef51a9f9f69c9a87b0a606974a5a95534c2e29bd42728a7f9e9442fec1cb43c2d2974a39353fdf8f681d2ba7749caa79a5506e304afc9b9fc4bf195f06c1d02b34d6817d53f3b34b566a3ea7bce6b367993e64e3fd08147eba3fbd816d024f14bae0599ace05db76d8a8f16abeb71d36fed53cf4e4973c16e04b1ef03188829721aeb936fed53c8fd7ac6116b96e1c352fb51a221f721b5658d3ffc0ade636163ff38691c34ed6c6dbf879e239415127c99c70e298b88753382821b5ee39350fe1eae1b683e6874005603fdf850c748ee9e767ea7db618d5f0516ff2627ff0318f0686ff1d84355e8e2f74d212c6e3317daac18d855a9a621a1212f2a12a442f37f22d6ec5b3b8162f9a9e93b10fe2dfec998209492121cc83b8cbc67536de8643b75274c58750f81a358ff6d8781920aef9209e93e10fcfa1475a2ad745f1cf6a5306c9201b33b0335ef5331f5f0a094921cfc15ec7fbf9b268d69f2fab78ce7605cfcf320b9e443d1febac149242728a1c62c1b124a2c9a7f1d987e8cb8b04d2fbc33f1b354f1040838d5d3cc7c6cf8f4851e73f3718e9aa79d37ccf931b0268b05906f504f16ffe11887ff4c8284151c75d320837f42af3a14729b1e9e62518fb98e4dffcf7e217bf99d9e7f6dcf322cfadf837df5d13859b29ae71570d2f435ce3b18d4786b11bc348b1f0572ff333de87b46cf19c159793ed52cfe334980fcda743f2ae543ff3b9c1dc0008d702f73e047f760b1c1288e5cdda97bed478c653d1f088f89fe1c9789e0c30c6cb5ae643783eca93211b1267d723eafc9ddca659f8df377de502c8416d1b79b2fe4de95311b083cd90c8debe90c8b30f3de939ab7879c4b76f79649915a845eb582f30169180319965df798d136fb0a7168b5f33af6b11cdf4321eec9bf8292fc683561a75ca2ea47a94274f39822296619909c7bfcce413630cb55608f405679969ca2eaf2c528be422bb74af2b451c07adbd48208fcc73b02dba544aab86f2a015ffb0c77995ca62367c605ffbcc7f8eecc582fc27eac43cf60ec573a2788efcec841d798e7dd4634018f3208c611fe36547d4b60c83b3f7417a82b39f5070f676fbd104a3ecad5de7446cf0ca08c4a74722717c231d8ea887017591407cba19da7bc3bf18fcc39e03fe61db860027367b286ce5348c728d655f3b9e7c3c27d3bab6297af705ffb0a71a3d71dfafa32f3843220989b85849ca6d74c57330ac888655cc84758fa5fc9b10a848d4517552c47060c0bef4190da1b044cbaaba5ff58924f19cf8f57dd4afb5d65ac3e0fa4d1fd6d7d115dc5e70bfb2d8822bdce6170c3f460d7a595ec1b008e248875863187d2638bb32a9be464fa9571657f0fc1dcf51f1788e7ffd1e5555359aaa5458efe15fedbe81945ef93d6afdb6a9b707b6b0252e300327607051c51554848912813862055bbad8628b11c48041104198c11170f02148881daaf051c1ccc28814203184215cc9d283186300318f3065052a3f4f4822cc183208c2420339ace04b0f2508eaa10a96021370f92268e04cb1e822bfd287d269d432460361c4a8ff0c4db089b5d05af0bcab161cf3386e8241cf72e79c73ce3c21c5f36146fbaee4cb246cc00afb3766d89c73ce09348e7e991c6c8c3d5b7ad1b7146d79d11d5e5b68c1bd4516dc2d01937c93d79b04a8cc62fc58a2b494655966929b04fc8bab52896634e062bcaa69b6b5afdad7faa79b93606fab45f0f6f6330ff59d1773aa7faa9f699bb6755e6e125304f7ccd3e87e86c6cf68cf3df184c6411a35be964a5f4fbf51ede6ed2bd7695fbdda6d0fe16b5f3da871a7aafd8909e65ef37c701f03bfbb99d6705caddc37d6b6ef3cce9ba1098ef99819dcc77c6f5a0ff68dbf4298bfc678272fd73fc9a03a542a95abed6eae1f83656ca5b1b57e198665d8845de68427e88261199c451815a51a9e0076d12ab53f60aa2382e1cdf32b0438ede38cf7d4335ed75d8d4b693210aa64361a3366d7fd065f06de4c24055393d31ece7ad2b4874422707af8dc77deeaf4f5bb6fd7b4d5e9725fbf3e470477b0a630f7f0747bb6ef52b8bb4452d86e3eb6db2a1a57ce9832a914d4b40e7615c22e057f42a85d6ec26e42082184282f13c1288a632c8e89f91a73baa70ff51c17f3a76fcad9989f93a6f0bc99480ae56522a98efb69396ea6344efbe9715caac3f3bbc97199480a6b29f88021449a0834006207a926020d80a08208462919341428385ec16928500e10a1409161a0a86cae58e9bfa3809e9ed669321675b279a1fbc8c5a44cf6a22e774f73ce79bbdae1a8a2a15aea53aa97b1aa4f69dfbda6c99c7ed6ee352436b47a35cd7efdd879b9ebba17509db742fde93b4a354d5ba16efdd39fbe3ef7272fbff0029e9afdaebb446cb8db23a379446cba4bc4065b1999542ad5a53aad6adfa53aadaafe55afa2e9ba17e87ff5476783e21ef539aa5da5ba99ce90b9a993bdf99ffb19af370834e11ede6c83b99b89d8745df7bd751de7e5176c1e431a0c6930f7f6db7354d86bff50a9d4ccc39f79eba1663e26e6a2ec678feaba1770ccc7c8e7bc8c7acdcb2f74977be8698ff24e27cfb166d3a3bd041a732fd8f080386b3df51df7d6a3b14d2662038548f53b48e0e265b383042ea4a0368bcddff78551a1e70fdba1cc44d052e7b7077fe51f83707c611eaf3202e1f6a3f8ddb862db8e9ed3ddfdca7ee9d0fd219c4d6210c4ad1939b09926486e2d10a778800a683ca1d7dc10ac651b9a54d6f0b77f98b3f67f088637737f02623f88d6533ffec7496562a6bdfd55894ff1e5576dc710863fc385e1cb7cad70d6c80186cd45f0f63602333ef5aab740e055f5d4b75f3dece373430061ee51588668e1f9337cc4fcecde7e05f290831ce42007b99f0fb98ff172fd917aed2377737cb1f36bb511e87ebef6a7b7945abbeaae8fd3d56e1e82e773f5b31e10a7b2fd989be38be5b8db937aedf6a09e7b1eafdef4b2bd443e9c7a5444cd78f8dccd7d258d7b2462998733785cc6cb4cf0b4d23f0e73af453c2390ebdbe7aef4efe625986adbb6c3f44022de2260aff48ffb7ab59be11f893be66b0fad7fde839dd087faa64fc2404c587beb0dc1311fb71da6b6c11c4d4e61eedb5f7a2af5b6dbe9db3d4f4c7d90edff69a0642490d46dffe03545c0f4d56463eccb08944c9ec5e202171ce1fa36428ff3f210cc7d47934c8cea3feaccd030c9a86e7eccd1b83350375b999b8ab9f99f279e3c2410c73ce765d467eff6ebd7efcd879579ce47cabe7c6e0886da43eff4315ef78e4f5e465d5a737dedf49c37c487c675cf133b2f33c1f56a57fe87b7979b29fee4264343b0840800220b128edf48208e3e64acb0f99f86d34082111536f70bfe8e0e1e8feeaf84a3ce6df1bbd83d957aebedae92be4d58a62bb59b8fc4a01804c4bb441e2250e4e19b51a21882168c833b8a214809426afb90d5316f9f55a800ee4d5b3ee2700b6c6bc184bbede7c642f7f4e186e439d86f2fb71d5b103679361fe79c318495dc4ff9dbb7a4bf3ddc1e6e011500f1b67ddc766c4d7694baae7b16fcbbcdabcf794db0c435cb3cacfa54a27e663fc76664b1b4c78f209e331fbe0e16f59aeb344b7a2688e49f8ccf04671e12962859706309a20b5e006e2c41bc009f1e7af9886f9edc76188165e0550bf1edb310dfcaac04fb5b8ffbdebc0976ef8863eec22d600a5a15ac3d4fdcfc88ac127fde8629cc9743fe491f700b9882fcb943b5b63d932acdbe09ae52cb3e635a9db89a30186b0eff6edc10e0868773d338fc336f003005ff8a6d3c20748f374e4f320cfb52c55a0bf1b3cf10630fe3bde11f8df76b1c3c7c45b388aa695aadb53ed5a6cc5efb1a3dcd93d9c758327daeaf51fab546198e64b8745be832307d235d06ceb2c46e8271082c3070cdd77cb09f0f1f43081bba3c1b9e05855e76c8c6095df1ca30f11109b1d80c5d2f03c42e1d58f80cf879d67cfff7b781d3e61bba54345909be242fd8ff864dd9e4584db12f9b2d24427e5e6343a737a85654060e4e5216ec9f2388902e3aea9bde2524e47209b9a440178ecbe58a49415651d8243c858868ad120c12f2cf8d8ca04ba607d005849424c465250616167e4c7a127bbc7afc78c0d10fd5878af419b5ee1e416c606310608f30ba60ff1f3f640f56f3cfa6781e8025684a1ff578ede8c83255a881cd36017de34f593b8dc38da4c80115acc900230e6ca62d486db05118f44d5f4d1e863ffefdfc98624d0aac114fbc811f05fb13ec57608741a28e6d1fb48ee91d628161d185ad7ec1332c77c9a8a5fa968c116cc1a4cc08368ca01bd9435711ccb3e159548a24b1f1163902049b3ba9086c9e8f3aa55799262cd18bdd8e37f9db51a4099a8b0a55183e54a3a13bfe2561338d5b6cf7079f8c2a5d38fb910c024202fdd01f22ea47447e9421911ff99117ecef5ddc0b9574c88f2891fcf123223ff2a3272da5ab8bfa72c7e3c934efb8c7d71be1fc38f39ab08ab2ec2ae97893a3500c6ac28a40334dd878e54b62c1ae2c8a3744576cde21a23f06e5080494654747961865099b77e27b32409c77faeb5ec2365204f2276ca6389a3472c7be4082a14a10215d62908b0ceb4f630516c628d115831ac74c1376826142e3f0998414dd592e5bf18a85374b2224dc464141f3c8bf56bffc7bfcc05a3d5430ae42eb09d6679eb0f0711cccab83b0bfc4c971251e6d61f3e73f5bd5874abf0dcf2abde69f7b3c5e0f256ca6168a221838c00323f6b1deff82fc117cb0bf0dcf03b4dc20826a7ea38ab7fba879e2d314451f30700073ec042d4ac148c2fe5acb070a1582dda14f6c862df8b303ed1476b6eabbe969bd41a2e9be406fbb7fd65f94f0cc9dbb53bbb0721a1164084c0f2ed8ff07929730ad658b43a65716a424239b61bcc2e608b47df7a7ec43d14571910a84bd077424ec434343eefae2d50822253dc6c1acb77e1cc883a0f52050bc29e2b697ab8bcd146b911221e43f2fa129561c0a7c1b9e657a77a1a12c363798f8039bfd487beeb3bfb68fe1155f18c78289ade8f0667be1960c07c38144b6e1e6258937fe9a67823ff1860b9b29a65a12f58c09306058e9a29ce8f57062b7c4de1277b06048699982fec91dd8577545f6937039d0904b4a15a3e8452b6c7697bba45004fac1591205cd90416404042a8c3081135b8001f4431345c020c51006fb13f9b2a323862265d84cb514582f5d5aa6a0f4b420db02a42d43bcbcb0ff0b54a3e932c43f57c11f853036d3a8c5669ad48497216fad228c9708ec9b35b10d88ee8e2a15fc197498e7f3b90afe363c8b4a868fe3dfd71e4e7ffefae2dcc0f95c857e1eafd16b6bbd0461ff94a4f24694c1c1e6ef7e9fc5e68ff6f7e9b8b9af7cd8480b0fca947ec1fe5a9047f129290bbff2d830f66a1cfe364a80b9a20e46146fdca3640f92ed4921a2a82387a4101196539e0c2baf0c722914848786a43c9248f4775446b082fd69bea688a894ad7585452d11d10c0000003314000020140c094422c168241a536565fb14000c93a248745418894990c32084900100100208000400000088c8dccc00bcbdf5763e6c71bb01c0cee3087158de58af47fafc668d52d7008b50c11dcace6ef541765362c9b20775709e16b79d1e2c8ca5fd113d585aec72495f95a9b562d016689e6e6d922c58f60627a7e5170064bc88a92bc017595dde71fa0805c6b5fb5338e888b1ce8242a363b4dae59a0cfe25656837fa81860b6dd383116b0544ae81af24ce2a5bafdc4a8308f5741483cc46319365a504c6be0e5bc65d12d3daf2fef471af7f1d91f59de9ef45639e56ab34d38417e9494cb508995c9744f9449a6a3909af86e09a94982a0690e6e8c28aecbde3bebd5e8a9f54cf5e83dd01c61ec3403c0ffb3dd6b1f750f5ee416ece557ddd8b94243f0ce583c9acad7be96f3249ed9cde7e4707c222cec723d0bb89738586c6904206add0bd82ba833c64027d57388382da5eaa8340c150adb0b3b07b53699df40684ea7d299eabbe986c4f7d87a0c0d05cfd008b8dfd5d85f6025c6f6ceec522e21b48633100332bdbe1040cc59c693db8a589a7dde0c756affd0bc1a6fe293560497f05b6f2870427302c2298b9c9dff58a90c1563f85691b21146af1fb6b6c2f7efd8b5ffc321fdbef62171035ff6cc51c694ac1af619b8a96c0c9d84000fe920376504d4acee79413ba024f8d9cb34fbcf2da288c33154ff8e28d18176376dd4c91a0c3e4969c85ceb9476e2574164263d7395f3a9fa3a7686eb5a79cada1dfdb82fffc84143d670e47677262eaff857ff6532badcede4f8f3ebc0f8aff899d6f4b46d11c8a819d0b96ed2a7898ad8b98a6f6965b06fe988f04efaa17a1520d020ef7cd69d983ee35621a4ae0d0f997742e366d3ec9c6179193ee51c54aff24ad0479472076105a47773dce41488748fb927472b8eeb82ceb988796236ab76dd152ce500cf95dd060a41556d6e03ff9323729cca2f563c671790b4c4335e868ba18d520c042d23214509e5718dd5e9a6a6b566be52c1852624b4e9a721df7cf094106ed7919aff9f1f071f06bc886188a6388081bdeec4f752ebeb2879cff93dc511e1fc92ad38a3511a483f971918cde9ce732846bc7cfb927631b868a5571f61539dbb0e13f71470ae4ccf9b0769b06edf3311b561bd0f337c9982c39a77680f6fd7483b10eaf55a387369f519d6ea5769b0fa9a5b6b0216d737e565404e89a7a8625a9343e25f753b87941f2bf64f38148b0bc512cafd94440e136ff4c6901e8a8ee9e1fa149503e02fb40d9b1476046497a64fea740bf5c9bffb48fa9756d1e32328ccf4af0be8cae66c24fe16e3ec865fc28df801d155298633e82815a526e2f779ffa687a0ee25a9f2f15c9ac3c0e7a65266f3467a6292e638f1ed0745895ba109b088a6074749acffad589c30ac95b854add954e3dd31e384c874ce359f09ea159a19feac963e71c660c392a1873510eea586f5504ccbb0b53fa2c2ab43d3cfd85a7aaeeab5785cf7715c6534b1c23af9b221e53910aa53b475a07810bb32476b1e6001b5817cb5c9b17c719a6736118962623323c10e32a486a24fb9cffd444c3397fca3a52cd70f0bea66e38cd39b1fbb6e22acfabcc9ba169e7e45f97be0e9711d0337f89ef6340cd72ab1e21e29e81a0feeda5064feb16dfb9bd6b128c405ac79fa01c6955df03f79cfea36f52f7079ee5b4d1ec9d50f149f1c0f6dd86658f832d60e088d234e3860a66423b3b9be9cb60d3d3a2451371c8bcbd32bde333731b619d906a8d341f009362dab908ec4980607b93d3a94001305c7d0bd5822e959bbcd2868fb30ff3b0dc88b74dc559a8f328fec37a1f39bbd06da88a34b31fb030b1e5cffe26e22af74b5d1e45a689c9811d4c58aec15de935c61d40463f52c8bf9b1330fd0eac0cdcb096a69c0766b745a810a546f79e91cb3ec8fcdebc8985e2f7bd05cfd34ffa1b62dd312df30fdaebddefe3d495d032dfc4496398498b61ae80bc23e89e1fcb58aee1052ad20d5aa1cbd0993abb70fb21fbb735605ade496bc58b80d1963aa41803105e44a49e782b48602fb8a26697874799b3c4a71bcd2988d8187643241c341a6166f07156f5b41303f713d488e69abe29b2d413bf940df1e7f56c14a7959dacb56df8c9b85dfd5e4b14cee8cf8a565d3f9fa11d3bb9457a3a782f12227d3ecec7b87b706c9135bad7415c47a48bfc682326992b439349301585ac1023033cbaf14586a7dffa9d1d17bdb975cd7517aa8c37410cde23c208f28783a0972997a22f00fea8051609f5ad58e1d8b47ad8ddfe1c64ecd3a6a119e75e2a1004b24f15a613991bf90411eb3461a34ee642dd4a4b9ed255e4ba05c64ae9c8368c2ab8c2c39bc6c44bca8aade4cce4235c2391de27b35db5d113c27251a382e4336fe64804d8ad5b13f161233d29a034d2257cea0ea8664e0d4b7662530a2d4a582a7de90239e8486faf5dd8453ef9911ba36eaad8631a5131319769c4b0473e57bb92252b6490c1cac908bb23adc8a9e830e91abf3a24576d7ebe5d8213d8ff942ac1c5c074a675942782b2ddaa1cd08605b3952af210c2069706d119893499d79bcdf9018dc59d72754d0e398e86f3015909e70d13423543ef2782ac923817c9059df621323f33ea39e7e5b3c4c1f614dceb990ca6ba30722ad6a7e183dff41f72ada08cb49426c0531f8c37a211b13d1b5ce424212267ab333a4fd7c9819b40bcda9d15516624df0a46ad4ce98e0e5eb5c8dc636fd0d2d58ca86c3ed73cae0d307d72b8d703922c848148d41040c6e4e7a1f48192f34f5ae45f79215c30df061682a07c3fe089f2b3b6754cf4635c5d0cc6c70501098278e8de5d29c8f0c6381827bdca12bbf22d84217eff3f7404ba81ae8afdcb818c64d9bcdcadd521281e284adbf2cfd9904696189b8e11a370e9c2fcdec7b08287d4a26ebb8f0b349121f2b9165ab0602a2a0ddd4bea3ba918c5381042bbba75d0cab849d66b1851677f2d80ec9ddb9d3ea4980451ca5baf77e003fb8a0177d2a4505e439f5cafd53ff5dd2073e1150bbf84366d79bde689588fee9ac52ce67a67446aadf09bc379cb106d1ad60b902956fbcdf3537e9309dab6be41b135e86034955f0a108bc753fdb584fbe2dc2fda70029cada1a8dea300b986ab35f26a03ca6853829c84cc864ca023c3d26752c1a2db0ad89a52ad9e3932a3f0a7bcfb5faf5c7b9a7772b708dbc86b2f6a66e626975a836d85f676f12e4c2227ed68311f29d812191224f0517526739bbd30cbef7de5570093dded20bfa76daef648e194abccde1b8f0eeb6ca48371f62f25929023190d0981f7dfa946767405ac0cd840bef0dff841cbfec4fbee1913b65405b751e6c103957595c9b2024437de8685632aefd073825c6127d4bfabebb3fd24dd3337302a9e1d7e48a7968fefa6b015bea15f37216868eccb46c37faa5b790bcad875b6c98d3dbd9fea891a711a50f77f2399c0d73ec528490bc1894b0eef3582d5f9f12c76f80e10ace64b4fb189b09d1f3f8b397d0ba0dcdad2f84c257ebe2313d3b7e9b9d2e98cb80ab06d8a60738f2ac258a52747b5fd0050167f5efb745223e512fa089e6d2736205c34939f8592a478e94feeddae146de36c96159713b85f8fe6eb75611f3a376884071362c27414d16bce21c536c7b2d54e2cb5d5c94401091f497d088d88202bf9409590b3f67545145e7816932e7e7afe262efa42c874d4c136b94fd46ec2d565ca8acea621ed3843e4d59bc831c4d1d554254fcd417ea6d0224f7ae40fc02d4fa587f37bfc605eccd990f8d1f80e95a4f83a15f4d466f92c87b1372befcf7ff9bc278038f2aa00aef575bd28045660ed57fa98d93bada5a14562397179cbbb048769f7bf888d8a8b7fc6266551d8c396b35b82a09c8514edb8854076b8b7c82f29a46b59812da87560ea2b934f9cb062b0390be579df51869a11aed68f06cf40fefb0d1e9db875a9edf413178213c8e717a8967780e5fad8be9c27926ad3438e85bf8d98780fbdb35937a0b571d0b755f010c483c97a16fa67730cff49e55b38bd615560da418c0c73fde0cd06657b1b78e2b86ac45efe18ac892bfe01d0b2829039f75b80f66c172ed913235c221dd7b2ce73546a9adbad89667b466603168f529acb08d2b6b12bef714af6437797072a58277e402ea2c9eb7a64c4ae5912053ecde75f5497957eb98f90a0fde91251e4dcc12f089d4366610ceb8178baa6ed38ee129f83955949ff37ea7dae43456ae2d875a9b26a37ee2f69a4c97c3fd42873c5ab026d9dac78af3337a77ea0b9a094913b0ebb9c840379795e061cd88b5ad0229745c40b9cd824967801d4b75f53b1c6574b57fddee2d9209c9646391f643c939b48fc4c2ed03753fae15da873183239cc943d60dd7e61e1446f4b66b653b7cff29f481b0398b82c434e919aab04f2fd21f67c097f71fc3651b5cf772545614f3860ef8251b76da66e435a68c1a913b511d39a9c2f141d4c9f44dade3c4f0cfd2c4bba2443248d45bf242836440dace00c92c106c5597cede299364e5248cda8a02c2179dfe03365ece914bb80090b7e3367a80c1b9452014cf7dc5a1171cc0af17df33f618557aeb01ef14a7d529cf190da28fddd1270d7f1bc4773cfe665b1f1d9020c4a35e32c55df1d934b98c8879ac9d51943632a67b0b84c77791f813833f906deabee4894c1793655dda5fdb72ff2778aa0828ffad5c6b2d03eab0210fc18f385bd319d0b8a4df5d6af1907a2030e497c9e104110740d0423410c5c126983222aee559ca093b5063894843abf799b46d943b2018431edf113a6e6b9d47c30aab91e2760ef7be455040c9596e9637a9d061dc1bef7ac06a4bf5c0c05155a5bc5532863557ba890bdd350f3b81406a042de67f8b320cfd50d4a1f6e1c478ec2ddfe7e48f3e1f222d4ca2313b09b39b4cc57256056d8e760bee7cab961b9f4ca7fcb20148cd7dc0e39a87e6169ccfab6b10537702ecd7e60c503edaf671d5796319db236c3b9432b92b621053912bf51fae699800d6045c8a5c0569c5664c6959a02cd172dc55e5e0a7c29fcdb450d10658528b28e9089972695584dee4c89f1602616bc765c57aae40662de3f6a216e8218678c9c6f90718cbfb40625b2f377c262e862a71af1afb431405ffee10f17d790b14c686fde64bca4455eb755a360353a81c1c3f3700b7c40bcea213a0a2aadad071fe16a37ad5e8aa28295b4aeaac4891f26fb2d1f2266da1f73181df6ad8cd76c2d89512e12cd2a498dfb0539f8146072f58376138006177472f901a3a5e885b5da22c7798e0f82b50fc3ecf53486e84f3a499d3444211220ddf027e64418f8b1d603227ab351e564a486f436cfc6e5f4ca98c73670dacea3042df1a217343a6d97d8693a6b115b9a7810af3b4432b8b167804a005135895d1bbace946ba8bbc199f6b0dc2c333ecd2e054db3b4bccb5f0a380a776c05ca1dfd8bcf55984a9785581c2bfd0ea79666325038ad436b5a627dac2281defd6a352ea7bf1848033b59653e9986eeb4b173e72edaf015fe94d1406bed8af9b3185a865c34005460c67463b42ba4143181da0d584219a0fb6d0c2b44d3a469deb7e3e45793663c837ab29514723eed0c88d734ed1f3960a04536a3b023b5021db3f3b05acc76b3194242a157414c37920258153cc9aa3cb1a9209224ae19f7d222015d37313c76662a8ded9bbfcdd564ded0c693d2b7f637ec601481ab1bd8a30158782528c3ee190db110d5244089ea11d5b34e3fb196a644ec97acf61598ff7e57dbae3ad27c79be08f85e0b4add6e2d845863c3a4e5e361ce03f3f60b32d08d97d19efb6f12aa4b6608aa2bde3353591ea0e855429ce829d50d9fe7dd02c5d4544472976b9db3b89073241d899236e1c7f021f2a31f5b1bb927d6097b502c62ddbe9f438f32302f572774ecdcf25a5e62bb7f72762781c8e28f32d056642de8fe2168be17e77b96c26bb44da5088487794177ec8fd1e3fb03ae797705db034ddaa6c421e090be3f82f805f5a721520e54922cfc4584c2da675761f0b26c800dce8528ef89ab60d8e6c962edc2e8ad3b455051ac350795f55b49e896243569540e38620f58ae9318c82513425a4e5a0b00c880c8df865bdcdabec578c65d31a7766013a319adcd5e08a7c393744c04124ec55506e093e8a10bc81a1022c500660c2b6e11372a852aaa75eec54f694ca101136df74a591fd3076d63eb7068186711e3fa62100f8cd583044dff7717b4382a46fa60ec84ebd6de0e5ab58759a5dae8e6dd82be47991b72e33195b76a49ce5549be04329ce0a5edb4f4a441f481a1fb6630befcddb44646bc7ceeb49e0c1051c04fbf9d1afa108e789b22ab61284549c6d3b43fc8abdb64d5ebdfd64b1e2239513ffbe136deea5e41cb046ce5bcceb09d949d60cb224562673e000e60f28f86ff0f64a4eddcce9b1a63e58a0d2dcb24f89df13202f5baadf62964d6fa3a6bd092b9b516efc9c2361d403355beb7a7e7606420f968f991fb279cf536cdab4310324fe01685f5cddf0882e10a6b5d463668a61ab986bf8d5cd9876a11f6f290dea7f2980ce94485ab250dabe997c02a473e399000cfabe4ae5eff783f6d281e4f57e909983c250cd3d1722b0d6c915d326b4ad57744ab6fa07adb81b578de5fb8d3cbaefaa4525a8e84a9900f2ee7a4ac2f2fea36137964de3ef2a524a30aea830f4680ac29618ec860567873e82c30bb54cda869e676758b27a360bfc99bba472b505dacae2a0c2b882413f8d737fc882b57f46e09950adec77578cbfc8c4a9facc280644d60b5d49be8ffe70479d610f50422f813aff62050c56b53f3dd860dc6ee6d37aca382b673f09aacb9a195ff80ccf6fabf93b6ea79212a0dc37c4c7db5cf95978d429977b152adf80ca9956d07cf80fd6fd3a69762ae4fd39d382e540e837d5d019ce8299178db971b7dbadf2b5a39fa342607eee133fd1ed9dd0414efe3c47acadee50ba6205f69ef82524c4cbe793cd73bfc6628b010a9344d626f85076b62e41afa88b7811101f6bc02d89171c79145ed83bc87328ae8886ef772a31fa4270d487c97f6290dce582056b4e3da0b60e666a9f9251ae843591c79cf7f4d519e76baf6b7171a90326ded473e6465785bb40eaec41834773adfc90ce8ae00d76ab1da3f16433b84799c26d1b9090e65ec19bc7dfae3d403b1a8f3592b02196102399580887b4117cf8a324fcc894e4fa4adbb83737a66e5157d0e130254fc2c0d673bc48b34fe46af4cfcd35f8ea6f8981a7afc32f3c592dd2a37cb879a89a1b5a54d112b29fa26e5ebc95d10bf443a691e3c1d91040fb3e5477f8a8559acd64c14d970bb17bf02b04184d426a068df17a5e31605307bdd85f1542510732b20ff8dcf39427563d9bd147c5b2e0acb2e8535a6ffeb11680671d62126e5baf9784993ad0f50d23f98aa56755585898e16d2623230f584acee1b1ce551b3e32e007a2124c4afca4970c48f646725aa770f7976c07d0a817a2d7d778fc4f5261374483b5cb6eb46ce340b68cbed4ad9ad300a86d5ae59da4132340a3514911f7deb56f4fcbfc88c940eae3893ddac04d0990c616f49d262b7bee75c2269121d9ff9bed49af63703d6238d4263f59163e2fdac8cf598e628f80b320517ed7ef93036e27b3526daa65530063bb707cb7eb5a018f28151b090f053804486272ac002764ca34e2a907dd091755b4823136a525b5c78e90f95b171cf8890524394912bcf068447ad868f0d4444d1474e4e3bcae03968dbd503c16797d0542aafcbdfc5201e26465560c2bdcebd33d0eff34536670327786342855c6c64e7d224eb00091a5fe8f9631c4f575754657f51eb2a4ef2ee780a0c2ffb13400af9484d3b86642649d00740a26fd0c0ad8d9c26f56f9b83bafa44f4fb7e0f6d93bd4b7d034f95636ca01566e60fd584c4fd6676afb592e8cc86f6c016c4b6d2c31ebb4d99a524dd063a7791de64f796854799a825ebeb537c10c91b49023c77594625d2d36d3e06365977e2863f29f8f1e6254879550f54a9b90a64650716bebadc514d06e3384380c9003b5290e42989d4f28ccb4bd733a0e5dd88e08edaf1aabb02aa09ad3ac24835b8043bc7c580bb9d061971e4fb334402ac542b17b54a641c47696988f3ebcf9c33980bb39c73d005b3b78619454ff35e1ca763443958441a1153820de26035086c0c012e787e797f40351738703850a22f1cc198a37ecb3a07e2b310ae52b57db03ee03fb27602d6530dcc1955b696b2ff0c27646af7e21fdcc14589c2f3caadfc98b273c9574b1931991549cff4dc5b657a51419e2b19135b07caba82a574c092313188015574fe605c3e05a275603f3ad7a0d50955e3e29df7ad8d91a28372297fa11a1f45249fd7e173d467f7fed9aa699621c1509875e2096c5ba815507c32d33a99ed598f5a14830fb4d4ab9fc1392cf97043e6ee82adc5a8eaa91af973b7dd19381a2fa81957b4f921144d9ddd6bd61cc4f18f432e932fff65d4088f85827cb1c5e2d34ba0267f52593aba9deb026229772971d928ca843aa407f027137dff4b13eba0ebedd147e23ba8a02c03eb65a3dada1bb84205450a7a9aa25d92ef5854d54e783fc2fc445dbd04c1fcb8bc73c85579c12bb271be3861fe027c39fe5b1cf080a4d79cc7c5eac2e896aca823fd8eb09e6b0704c1a086b54d9f463540e0191e000b74442d695a1799a4e3b955ebabca6b3034eca7b6c2b3bec138022a5b25c8011c6f5646c81c3fa844b9891597dc6539987ee13ba184238f0f2857348218eb79455fbdd88e500d5ddd53a9ba62c881504abe4cae3303daf32d9113bdd196a02077b24c919c2015beaab82960ec3b37578aa4de809a62bf3e8f7c63ba898bf0c9f3cc26914bfa0479830785cd17578ddf70306b4422bdc151047fa90386e8089386adb24b6b8d15572c7fbf01026c5af2de7eb0c2b5adb36c25b9c74dcdbb061b131e38e0bef894f90c3a36634e02851212fbbbf8ec840a06893e00d5fecd986cb7f6fd24c5c473fe7f5f66fe582c52e2b7f23935f19bd81dd0961016839db5f21991a58d70f893517121404f8a5622d4c0a074c7bf6f150d3b373626a8c88f27d5308e6d48b7594147a1f16f88f3c8f173a5c8e4390190d6cbeadac1e8cacf980becd5e9ba39d3568cd8381cecfab96dfa91b10b7b58bc89da82659afc7990b1e3e97f1e035e92449c97c5f6e7acbde920b652f89f785207e0b56b92c8db69d80064817bf5ba94a32227b959755ed526e7e05e98581bf23b9e3a8368b03508ca034e49005c802cd4490aeffa99db98a33bb15fbe8f836ef5752b14eb7078a1c43225c3d2fff9882b6895c4a3bab235804e6cde26d6bc41bcc6bf0cd72d33aabf709645b3829428d9a39512b1e76570af0822f8d8f878203b8346174a61638943c54c4a2ead1b40e4320211ab1d5bf0a0868346d582dac8986ca3b9011243c7f85a851a72cefc6d019c5a82893f5b84222c512f5763c73473ff3577a9274791eb64f101b1953e0c22ee1e30b918d815690c3836e779d011d1bce269ba653c4985b5b3e2ef479d2418b081064647d19b84aae48b889e39c943316fbfcf47ae349b2417dcc27eefc2be900cdf9719d693be3695664a53771fef8654bdcea05cc41004c378fa12a2cddf50ac98f43265e3e29328cd8a2222dedd8cb2d0a96563ba029b66468c7b8a56c1f02579af90519a0d2ba936922a254094ca8edd7ca4a7ea9f0807a074ad8dd9aa03098d469fb5df074d6da54fb92968572c024cb923006c87a22fd81fa59c499a3d0e773b4e68bebcc2455756380fe895e78b014f0545d3af69778e40ae15ddd4532fd3460808262ac9d30ea1994c422785cca3e629e9867ecc1855d80d799056ec73326366399e8656c693811c8ce653f1c07756c8ef1097d3b9496f1196e0a00eb7924743b2b8152a4953d11e42ad9abfd39499f4be64a833dd70daddab9d88e0ea1d46c50d83da768497574e74563eca8bf5777be0ac635f584cd65b9e9cdd064778df888e18d70f92a1574a904ba7209a61ec8e9ea2db350b2b764bbb78114e8c4c40d7828399a097ceda9615b2177c239981cc333a1eb5e75b14eee591eb486f87e41559658fbc9f3a83840a72f79dc19c5f30544c80212c36cd7c633c6064d527e3144907f87083da6c76fef47c49d85837bf7872fb5a3fb68ffce50649e11ff3632f2130de24fcd2029101c40a517b8de2ad59ac9dc7b5e85b514e8b47b281ee310278a5a4085633c5b16905ddea50fdbc8009913260e8065655320de44257f6bb86c6424acbbac0fe8839895d4fafaac62234d33125b83082864c40749d805fe81e70d4e9f6b67c1574e82d0ae40a8a829adfbe0100cf122ab347a56239a0052a5d1c1734141c1667fe9ec8817d2f6d7c62db5e3b1726eb44de3624e9d25907093d8080c56b1dc81858b6a36d8fe49cbba0291713b03cf99ee70030e00f3468eb2a1231d51f18abea950ded7b3a59c28714476b38e7f8507281315cced5d2130ed5ce20b5bd82004b3836f98b6e3172d971ffc5ea0b3276e6ca3bf135c9dcf49da0fa7336b68ba399708c3bb89836b104fb69aab8a9e3c431f21453c013b37a21d25ed2f3aade04b71e1133b36184bafe1d4c119642d280d81677c5867ac4d418fe2358ba8296ee4a8f0f2cfc9e9226823c2a5b36b1558fa19723d5f3723dd3cb2a57ac4cf185e93a7d91bfc4d4833c9b0cef64222965c9577134b3f5399c2e4bf5a6d3b74143bb20a04530371fa8612cc16e2c26a279553eb061504b860e838d85807a4fe685fb0b8ebf112014bee891d7786eed29ae0d6ce127cda968be7faab74a86761d727fbbbfe483630b54e1771a59fcfe7076762c00f27475f9d9bccd1456e65f64c9f7952f3b8cf5a61025961ab9c2f28f9322e95daf5de131c27f026755bee9f136230595c0e9302a85d1115ac6a8e785b4db2cc06b5e55282b81c720ccd3a5c6a4aa2a7c3661de3428b94782e36cf5e2dfee4b58777f38496da8ffa05483c22cc126d4c74af752cb35d22981a3147767685e515267b275320877ab5d69c66c8240274233c04771b59d4a9faf952ffd8b48a894e59087d8609285a738dd3faa752c2ac53a195dccddc5e6d4c9089507e2a2bcce59310c2b7ca15aad2e35b2f302936a0207ccf1da58143e4705601ee50c6919e430d6b039d4d79805614ee1db5ac9f2e5e0efc603a3e9b17fe90b60f11a781038b1eba91949c04bd49e4ac62d60a8fd374d287c649abe7780482399d05147a29113b7fe23bd5d3f9723fcd6adf25d5771480b111e7cdc95e4f538d7d6b66a95fd994256aa795bdd59e7f3d59990a36392c19baa6b0f77280f13c45eb0d73dcf1da213e1883256b7c71a00e8480605c0241f5e8065ce15200203d55bd87f360ad5b640e84aa34120614a0a5e456fa942aadab667848337d5cc9a117f10897d8cff7164300889796776de4267586dc7f647be27308af6aaa74147b31955c9ed5d6d528db089511ee643ee422b8c68ba8daa06c463f175a3639439fea3f1eb5a9422d6da4430b93bc9ccfd78c1868216c745cc6a865a148185d86a13040cf8f4029e99fe8511e69d52d974ced5d8737f24b5410529c3de2ef4221231098eb8fd4f42dc92ab85b027a300803647f805bd1838a707658a76f8955a7300dcd55539970dac5466345b9b697397dfe73dd8a9c33b6ddc8d7c5a0e74c6964fd7bfca9ecf1da92efeae0fc0c31f741c1ee1771a9ffd78f0c66d009e1e0e7260029fad0b242cb3417ddb607f20b204b8b8396f25249e18c6839e4e9a76d36fecbc7f813ade0ac4b68074a615c0c2d47d98bf12b1824e6187dd0a27bef1b0ba43e257624aed64c7ebb66f6539246cde441526fbcea52afa6485049cdb7901db46aabb57e6862af9bc93c51a4e104384a9e8f41c5b49dd40afbdda07daf023f8fd1dcc294bbbb709b8a42dfb07e46a6696e7f6cfcbff343aa54e471e2ebbac8a2144f74fc6b1e3cc56a71f2f34c48193d6c9fdb8d6b1f21c27ca74adfb502a81c0916ac79861090cf068b4a77cc07dafd7b65d18973d3b414b658d644a66ceeb914b1502de40dbc9e8d4fec7f214c11a8bc0c940fb79fb2b3bec90e0bd644d0b0510df7e7c26e759e8e867d657bdddc42a5b3b713154b64b94e0037a05f18e46afc587760a6c5bdd26b50d74253749ca59afbaf37c90bb74a37bf2ea46b37a9b0418f7bdead514d04fef50eb1159b99dc9e881869e071350f4fc21ab915a0da775ae5f61d4c7e2c5b3bd94cd5d39678b511b3c546af275cbf2691c692c7d48fc04ea632842c16549e632d3f907199d84f9caaad40bca46b809f3482870ffbea262fdac543f19d0fb176238dd863018a7a4ba2bb6b025eda03a8561e7b3f54ef0520ab683e32ed13c4e085d00845bc5580747a032c29db7e65d5e65dee425cbfa1a170810b5d1b0bd6b21ec90bb9f60c6b2e1653dc07df8b1205419eb7d174dc09d8b0a76111db1d50996385d3605e85885d6464ce1a0136eab729452b5adebae5addf0e1aa1a8bd61388ebf57a69f3a1d59fd4a2305cef3d814beb1dfc705656c003a0fba8b0ccb9e49e5bc2ce10dd2c0289b9509bc925e431229628ac0f26e2a95f59aaa7e188a2ab64b8a4114a8212c8caa7032220c07f5ea13a4e4870f92f2f35083443bacc68ee1c94b5f9f0ce784b5b2b6673be54a913ef889be364e1e2313464cab6738f7a797714894c3f48a1374212714a6ba2cef2251871ddae1abc1196146178b10a6eeb7fcd5a0186cd9475960133ec2e0e235c485ccf1672f6b4d0c9869979a50bd02574c77e36da2eb2c85cce22f3a4cd6eb00d1191c93b3c1c0af0be5965158e153c873ff8086b5a05a2d06a3a59502a2b98b7f7f12025e72fe85cc511f0396fef2053f9875a4752e429c7a11097edb0c56e0b0cf8eeca88ca796bb13311fc6cdf3a198697e5aabe7192e1f666cc86c08cfdaec702a506d8c46e03ee9f3513c9a8002f3786cb5b4fa83234bf2671c32b65745007c99c02a8827da804deaabc33ff29c39a25aaf6e7ce24510e7c0522cf222ecf793d018e19b4aa639e930b9df07879c1b9891306daf1eacd6b0eb9164df44d6e2e033de5e70173815c310626679f2b20bba7f03d0f1830856d970acc922a04f4147456881ca0116703379429663df745db1ec3c4bf370390bb00a9d8df5317f1f0dbf458629d0ae7ebd3c1632f39fde2ac412eda147d296acbf6f681de73b78c47ccd037090f51511208eb6d026e499af8196f6467ab17c0ede3c3f50b8e01f1d626d49e354c5e4d8ff9ee839061b92079a77b9d6f0372be558dc652c0f9e6a788591f64aa93abb59cbc014459c423250e06835f90e624b73f5f5d1a1e84c37852edb3c26c1f4abd664981f2d5852c9e377039bf01de7918687c8d901eb3a1ce1984db8f968303ee066b6a912c51c046fa7832df2b660ab588bba9737dd33d6c15a9bb5da75246c86520a8a0490148e078ce25f25b674cc05fdd1514ba073408252f414eb4d3c791845aec4424770b5a4513cac9d416a67be8e075b3dc5925ce50d663e6108c4eba29144adc2b08eba0becd5a3d2f5e36683e7aac4f453150863669c5072472bd230db33d06bcbe0e6a8eb602257c4f10cfe03e3f712c238125c587ab72bcab0cba1f21a2ece27431d3eb12c760eeddca04f41bc741179c3f211619fccd0ae50379275b4cbfc4ba6570262bdd8ba3face03a6e65d2fc6bd9c1fc4856a279de8a0c5e2ea58304b7af1b95a5ba6c2098a0debe67315acf99def2bd16adf079cc9532fe3f50be04123445ad2cf72e855eb36ee3ee3af5c958ea6d4436f397bf106727bb8dacaa0a0a044cb31f456a3eaa7e2c96800a3c59b6c3255ee8326545d956c9119c2a0a697168e06acf621abc8f4b81b49d40f25a1df010bbb1c423a37e0425cad5b2012ca5d4e3a0a33809535c4a730221ab583f478be52edc5f740adda94558c02a05cb0b56c88690e729bc549b94abcd6c2c8625ad95f31bcb22ecbcc88543bec00ab75aa7dcb1060bbb0577317bd8cdfd0a967d2654543e5eaa9f33aae3e901b2e4f1a97f7d374918f86ed083bd42c5a4b996d2739b7b038bdb46bcacaaf79bec7578ab39d64ad25f73f65773e859e2256f225d23fd74ee4ba350e12455b79330890dca9b7f42e8415bcf418991255b2df27434257b5f79831b7f2c19d930405c1f06b5e75a503e0e68398b1b0023e21f1923b34a75a1abc787cab4f2f71cef7d63915d4f5603d508159e12379ec711291f68b16399504dd2b1467a97397febe16770c0f2be84e1070bd7fe1e8e1e5ed91ad8d01ff3d9fda9380a4549d1ff03ee8e7199adaa900de48ba7e9716dbc5037dfe3dfcdf8287e58d41ba0b0974b342d201c991870db7aa1025987f13d1684998c2349877e37d0870fe0afc7187a0cfd23a91313c4e80ca78d029708da936e8b639735f06ff3dfa3dd4c0b88b836295347dbfe18db44f88f48083edcb1bf8d9b6e631c8c024199ec4a742276a570b12d7f6d9817a641605708c51d556f44f2410425b799f17c9d0e5598c89c75c86465e1a7c2fa137e45e7eead8a23058afcbe34ae1faa1797524ea3d5ba8cff0d807ddd6186280c5d452a60ba9286dafaac4d5462a6ce0accb9c7f2d9a2dff6f8e655d24213e46593ae40cbf59ba930203b0494d8590ceb027611ec73cb4af2da26f59d3158d51b921011e0513376b951babe06657128980117b3236b8a07e1b6339518c4bcf802621f2935e2541ea1510604ed5568a79db93029ed547322b7f491d814cc97b3dd98e957eb595f210c2a6291a01afd7f7322ca4547445fdbf605986ebdf5c1737dac4e0a070ba15efcddb901c24df73ee1cabaec7fdabbea8dbb7a21962ba70d042eb7eaec4d3d6a4b2c4ee8f17a12b7ae6057ae1d8b7f5bc74eec9501c25193300e1281f59df0099b98d44595c0d89e54c7ca284127fd416fabe89988564e4b669135d83f9ffc5c8b83049e2f0e8bbc813640e5953558df94f3dc627e1da26a1230f6caa37681bf48c951748b61e686c7fe2737a89680c6356ea4ab9fe392bcebd71d6439764467b3cb33758bdb38ed7e5dcd9d5ec9826a81febe0f5160696ee01bd105f2d693e5b3607a3e60b370fc8213065ff51080ab42c1bde746d3be6cf51ff385a9cc6b6a5ebc25eb4f82265ad6debfa04af85cc0433e6bd81dc9b841c618844604312de794c2c35a40b00d44f295f7fefc42d6245c853c9700dfccabaa12921e732e3bdc3316ae6d2288b5229ab0994ae45208d8106fc81be67429b16e51b58c2526a201e87b0c3b592b449df3c577d71f8a04539b6db1bfadd365e8e1ea1f857b310a7269f8ffca013ce0040e0a94402d721d2dcb7144842230d8ae5ba6096a0ef0e385442a06cc3a4fc189cb29ba7c73f01bcbe4578f2220fa8e9d8eaf2b3b30e44bd345fec1f4465cd4174d36df8286691f7de610c68036a1da277f4f4b6f0dbb9af096e28143741fab33a66dd42986d0325d7db58f8f3f1aec37532b5fe98f4f6712b05132edbd7a267ed2b61497fc5326fba562c135c5e3a7cf6e69b5c79d986fdeb5b5cc4dbd2f2feb682ffaf7b3db72c769a910c38a84479df4e6f44c7d965313fdfec9d38de5ab865afc6bc2f54d61391c793408189158dfa73e1326506638c269a3432c8a6a5e419617a7703406c8ecfd28090fa106b6fcd4aa0b694e2fbd71660f3c158f1ed1a71dc6308ce5e20e554460b5b6aa556be16f32fe045605dad9f9284a2bed96c0b38a5d4e3dbfe65669253d5ab09fe7c3f11499a8fa8946ecd4a614920d903daf0240cc858b286627860772bca0fe65cebf983a77b7e30b505f9f441a956f3a6dcdcff57d8185c2a02b625ac154d9a0c6bff61ae24d1e922c4356b5ee11a261034ab120f1c0d57b0e0ff17637de91264cbe05dd5bfba08aa52305499d3d066024c992e30ead93c16a2518dfa4021fb0642e0840e5b278d7b83130246640a831e05218332971a8f3a54f534eb50d421b7d53b055a6bd8278b46dfe7e5815cdeb6246eed85dd5fd7f696b988dd8e956345175dd20d87a952fa740653813bf5d6b61fe75d4f22cf02fe8b6f174f40e3fc6f5bffb2c390a69b8d8d4c2b57eceb9ff0cd485ef96ba1806728d714ecfaea3ae799b20a9005f3097fc71a5a35e225b8ac8732a79ccf701472f36e3f4e4eea47516d88cc64c1392908e19247c44fb364024b8d423a8f38c2fe59c47dfa238253a0e6d79301d9d776320b921936acfba6ca962596d9dd78b0988a802556666f5433b3e2f6eac21af4ca7913798aca6e28fc208aa14527d3073a77d12624deb7b20815ab75e1813c3519c1c5c37520a20b6aca1725d068671cb5ad166759d49905853a92e6c2490f2178feb5e8e7a215abdd4c4bffc239804416b105be934b40e1541934858416ea4cdddfa126f4038608496fe05cc14880c9686f4cd2e5c720282f44893c8b1ce3d65a78dc57b40bdaaaa452873b9cfdf65f872bc031a2c0c70191469a362e29b856639a90f17f131393ffeaed7f7d5e60bc82c8f7b1aee3fb798511eabb05e370cace1a987e43fda50243f5f5e7af26244a28e05f3d530fe25feb942c82d3d846b453a21f02f8003ea688a09eb4cda85f5db4a84b92a203adb2b91fcc1e838beeda0a61bd634bb4d7f3e07d81e70ae5ec0bc7e19f46d14da93fc3aac6270c213b42de1dfcc2214826946a151df09f67e61465d77b315040663a254059eaa2b2f7442217898c44e916ff6930ae8632d576d72680681391edc4aa1070d28a6984ffdb07fae5fe720a84e655682fccca14b3b95fe45e3534d2dfc9a8c33af0f85e9efbeea970d7ea6cd67615b3cbd1ae6fa268b3e944a1b257542308ecb256693482c425a72058f851080a90de600d140c17db9529c5f1ebf25624bcc4fdf21632702463ad80557089eb12bb31f885231372294c6b89be502b9fb67970b0e1342eec0f2e79a978e3ece3da45e3710375d4574a7d37b7ea180012f55c028287d3f196292b8f15cc730148c01b945c159079253081b0469f3f173969d10373e8fa3e1551be375b6c7130257dd0f0c64454faae33038fc283da2728131ddf19092ed4cca205bf64b58efde89a5f2588c80813b57c5eb62935436ab33317d14326d6d1a8ea568fdc2b6ed08ac46ac01a7c6947b5bf12d025d82b0d09a51d51b3706b8029b2db32204e8c14c5419f7277aa22177da15b9548ef6a1a1021c546c0a7ac5a55624793ba578bd21dc25a704f71dfbb7e00f0bd3a4d66f2052810cc522e9e6e2fd1fba9b82b60aee239697fb49c3c5d70552d7f5d19bea8bfabc0fc2b0ddfc9af698f200d9eb9c36c24743ffa456f09b23e9e5ed53aad1d7fd0580d173ec03e6ffc819e846c1b48e11ab6f5affda2359252d08c1d6e85e3b1ad4d54b987a3972609006169090f3a2ecd76e36025e1a63e586f9e7e3ac7056dee318a69c14d43dc3e8d10b3979b0a1ea2d5d295e1158f018553ae51bfdc0dce2773b4b5b40dccc626ecfa4315d5ceff2a04fc9bc5cd17155260dbbfb6aa4d8464d7290cc72a8b6dcbedff33af42ced74343d79ea8b0ccceb708278046f390b0e4de0174542c8b348f49e974dcc7fd668a3b60584681de095c4bb2459a0b4137e64a3c14254d453902b02a538db34632bfe1b01ce2aa901669e666a5a729a3418750525523195c1a880397813006ad911821c16b8a8036775d650b3b4171eeab7e2bb31cab766b05f649c881a2ed1e7c75c14f31b14128c4612a88809e212672cebd6e33722be749fc0802a2327d7cc5754ca6c4ae7da09a891c1f0fe58f9b454bd4e0a51af5e2ecef75f772b497423c4c649c12251070f9ca16cfa0738aa38968f569de57e21d23ca41e19f2575b819719b570ba228fd43bdef991de75303c8ba5293209598e9ff6b0f526ef6fa43060f12746dc9a07c8b2a5280506d2d499218a00488ce0e065ad8863dfed034bec077bfafc3161ae11163f774c9ec139cb2d5645518a76590f1bce60bbdac2d1cc4fda17e58ddb79968b07490841ff343cedf3ac1a30457350b99fdbc68e947c76eb6f11f1a6e0a5b5ae848e1bffe2dd4089d334657116ca14ffe2eb60d124ad10c009a9bb07005b3bf789ff688a22326909cefa80538a43198460683a9e4471b1a53bbd8866e349b387703335543677d9a4a54b02491062ca06643ad4a2f7f24b43dff7cf10b6143ad67cb1b94057efa53d0176317d56de1f6e281d8f69de842ac03dabc5548a7c980f8c8a21f6b3078814fee14aefba6045c5be1901993d17487fc98217755fbb946c6c411329b65a23f1beaa30c486814c43435bb9c359369b3f51b18f1a93f5dda68888037f42830fad7cd6950c6a76caa3eb0aa1553ec0154a844d5500273429f0f5099cf157084e086401591b370bbb965798bbedcf959deb54a07e91ed9a85943f7859369dedd6d94f3d6544386eebbd81189de3d5d7e804ecb2743fc9e2b1f55d390ecbf8923ef407b8891b187cad86a4859bbad945a5bd79d6a2c3dc5ea744dfea26af63501160e57cdb707b757c2b6f7aacad8fa76e36279837d4b118865a31125bf98e4772b2bbb74a397d1cd0ff53edfd81498facdab178efc1abe1d446f8d81074f6ed8e0e4011c36de9f15ea607049fe08e1a3d5e9edc7474ad2407c1d239ff4b0bc3678446e9122070ce4adeac8f87b5959189db3099b04c8eae02728c87591119273e30f7a02d5666093552ff32f35887b66daf533ab82c2988d4c1c6a5beea8a25a66d08982e842b471793713aa60b48e69c0a2a0e8e3d844e287e928afad1e0182897b98cd191355c60525231682082aec10d9edbf30243d076d89a3a9b10b9852f603b6d3bf65bddfc6dc7a9759f11715cca376b9d9d5e6fcc3b32da6b6e8e06ee65eca0102b82ff39f059c6891caab193a428729acd9d4bfc23b7c215c7358ca0f72994cad2a3636f244bd555399c8fc738cd689127fc465ae80fb0c14a23cffe05e490e4b2a671236d64b7f8bff6dc556664665174097238b61ba621725dfd58a6fa1c5b75df1d7ae3a10174c558603399f5c3ae3c0f5bf15a307d5c0cda1fee964db22b8f89768254c97efc8142d324820a856b1a00ab6aa4cea9bf90a75c5fd2f4e896c198a65b3b502722d5f5f333c066deeaf55da4814831026585a4bc27922c3f4b2b3c3ebad9fee018d5c454a7f491b09093edc15283e58d3f1f864030d00374f745f38ddfe4c28dca9943c9f5b9c3c368f8cfefd411a186a12862e4cc28f79b594c44b30f5b3dc42bfda773ee74147176acf1a2b1589a03243cda07a9508a02c9fa7d1b3b9b79c96b5c9f2d3f5ca7f88896a7f1f652eb43708d58a65b5b9db09456f17639dda832f0996f46c15450a8c404dad293f53a5b51b5201d72fd818bb8cd000d4da8c724eedbe4c84fa14f136676a679252d945d2c7e3f3349f7a94f9beea5afb334d341079e415b691620f70f04e0dd33a974800f6a81b68fec66b060fb7b80f2a6be16d0c484d78c2c88a129cb2caa3d7324d82d42a70328bf8262d72271a79dbdca2c1827292b4bf4c19cac9dd90b150d1179c4299c13a65226bf94e2a25cb5e0a44f2739f49c932539721a425806efac7923b20e85931eb52ebe109ff57261b7e026e0ed79eb54fba47504a94089da386ee0975c206cd5335497ded0352ee7b17aabefd6c059277c127397212d0a2619d6a3ac15409bf529a1bd7708ac51218b7ba7a4385c83bef7c2e2c74c0d823e220c930507d243a2b9a5c2bb944ce17ea5a0bac841d96af901769472de5ceb2dcea0230b7cdb19d76207f06815eaf8a6e9cb98ff004b23bd05db6ccebb87bcce47052c18104589be143e2523e7c3231874ab8ebe862ef4aa39405b87d512e4a113588aa315e72a3ca3ff692951a38e7532738c4f7de9f903bcf4b49ec12115caa2bbc765a706b32d9c3a7fda899315ac053a1b9f0882519ae659be9325bcbdcb0a5e8f781b88442d7cf0515fd7350887d2243e28e51352adac496b8d3f80a11d5de5f029b6c847d5929c985d20ba849ec6b29ff50af08b7f8936806281d2142383a45c1193efeb21f025b3581d5c3e2c2a025cb32e862812469bbe785cc8f4c9f5f33e0bf19827380f193fa5b4149fd2cd0c3da989d7130f4090fdb16813f460681c915ddec339f0ba91b75e50556fec47a8f3ff98d20132a371b23747458c783c76b3cbb991d5b0d65124b21711f927a5ad4ec04092a709b53c5057dc5d2996b50ec75a134e08ea11372f79ff577607c973cc4f8ae6a659d700b81d517a2e4c8ae86ae58e270cfd8730007945a36e2a961a9ad62e910a2f49302f72e37b5da2b96509ed24e34108def9699c60d764a048f4b15bd8c6dc5929832bbc255281f0d1b565b3437d8d5f79c38daa64e202f1e2486b6a225d84b6fc8cd10c6a1cfda57615c56b56493c513528e1db1f698336880c37dc6f28f003734293ec044363692ae938aacb95063b6e836df1a150ae99e4b620500ffc6f02d3c2c5ab76eca4e4f5f49be4b62b9d8429f7b119dbbe8f5eaf32378c6c974d08dfc816a3adebea48ef26c87f6a5a31ef4baa4ad2c5711bd842fc4f35b5b6bef928bc034772e29d7d12fd3b3b61cc39288ce02fa2aac3f5384d7795d09e161981bdd706ac5975169f5564fcde8730c8e9e333aac2f6b34c82a265896aa1f0cffa2c3922661c287dc70d38775a6102b0362580cf630bead344a7151c89a78b38b32e14e69e7e9225651d4d5e029c1e3ca3dcf644d57ba33a68bfeaa1a0774624230c57310576a5763e20461afe83d0aa7633b40abe05035e1227f91f23e20b2d2fb35738ee96a9b25cc1f2b4d5fe9e0b721c03c2658362cced80d794c73fe4987831793fe54fd9e8ceec69cc7f42d1ce401f9ff3ffc46a6b4a3def35dde3169f11afe2f511bd129bd3b98cb50a044d759978ccf24a5b2c36735f4a8d1ee949d3a7d2b2e6fa6e04c773cd9a9095188c777ba2faf365212be1a127917c8890e51b967bffb5d795ea2530742b83ebcaef03f0583b5a4b25dacaa5b0ec576bc8c8d130cb625a00fbdb9280863228a6175d163175dc7bfdad5c8e0f0d3bbda73b69623b29362c63783b428f3d7922a5199dde691332522cc5aef067f2f08f5a50081e761c4f2913036f95efd24994adbcbcfcc7b67f2e954c773e824d3d95f8aca04cf5e52bc671387778f56ceb445f671dd88f421e7c434b4977ab40ee5f5608f9b7ea08b23f2d870dc6266c3605194e09a9d6b9501d488008e1395ded04f2c8d0d744e23bfa87052621fedd6fbaaaca5ae1b386dcd2261468c7f76b2c289ea6e72743e3fb43f8019dbdf0b4504878d7b69528f44718ae4cc75d8038a4c2327acdeb3c6a6c59245c59c82f2120b46149093f23a21709d6c33e8c9df6fd25c110e7e4e248f7e96b1f914a6a53c431b0aee78db8ee06874dd6367473594005f6165249a87e8d5393cc1e1ea229a97170b82a5690513ded5b63712d0ce5d205d0024198f17a228d8f22bcec62a047a6fcbda1963d5d21832ed074457f62a30bd8f21aa1aad4284515117ff9607538eb51d51cc531d0fcf88ca9900bd28a07ef11551a114a2e691d76822e62a6c6274c8a57a33513f4f08d815fa6d6c4e69cb8c0fab17a8f8ddfe12c19a92aa13223213437ab2c1a8d60f4445a4017f2939598dd3a66ec29b695e89d79a5856594134095eca45f19823022a4c667b5791d28359c317c523090091f4f931db7c78421370ea8a7db22efe62cf1d571faad191899379ede566f02ca7d0c66215a9af4e8d8eaee682e4107545233283eb5fce62ce0149a554abaaf182ce649a4127df77911efb59e15b5ae5a98f481bb0ef1c99a95952def60ed376b73996903c459aaccae7f91011a30d6f7012136000dab754e0069367732339d2facc095341c57c88862ad0834fe7ac044dadd64adac246ff99569a120d11ade2f87666c8f801278075d0789038a7f70966c77d3e2eca2ddfb93524ba5b7b7fcfe082e6f3d6886b3b42137225509d7239e61520e98c0231562b6c1a48bfaa595b97eae369d9fb867b9d2b518b5ad89d95010aa1603afb5131a64f2c77524ef052659fb2d28398a995494ced22d049a22e76ea742391895acdd52ad57392c0b5295ea0f3188329614e748262de426f468b782a8be5fb653de30e49a986083863d93a004bce83179b28551d2d637f9ac90c28eeb637138b582491f55ebae4caf8fb76fc4614bfa141f62bb84b3e2ebef9aa8cd8b3479500e4b8c90ee94c49e8568d48f70a97f810b3f92a302e475bd530d5287bed51551d208922e93ae7dff3826546786d01ed0187a239ec9b8ad563622c4d849a7e5f74b7e1f2d1d13eecc1f5eab5ec6931d34ae1cf0649b4cf3086e85c48e6af65d3a2c97ce4b90c21c1048dbd9f76d47f3d77303a7d4d4228ed7329207655185cbd133a401dd27d6dd8936dae049bc6fb4a43a661700d94cd8ff9fd2a72a5a1037d5388662543abbf6855c2bcce3ff48a120208fa26491d12899d0c65882f715ee6e93f28bed2679a5aa7559b3ff172a82a96b1282f642d40fe5ed612e91680c93aad62000baf15bde39069cea3150173aef8acdd9c97784c6adcf93b5dfff574021eea110f85e88b446ac170a5293dd211ab2b12ed2aaec3114f309c2b4c13e883d91327ff45e8421ea22af943ddb9c214dc95a94a7624dc40faa378d1ec3c755e25c30329de3398ebe0327ee892ceff16b5adee16afc3806f8b6bd25739f23907521c06e90320bee22d3f754551f31555653323a9220070efa5242b183fb3365a7d8fdfbf8a95a3138cc71673b2432bb2b54ff07c12656c1bc10066a6a0120fd437e91ded602f30e13510dc192d657d4e6244189caeba892edda033d490732f8fd562c1f85dbe9310cd7df7b12cec8c21cdd4c9995de536055cabe1913b4d1d991e154b977a19512cdd7427b68c9d53bb59be4fca63a8b4d4fe9ea2714ca07cebbe733bf3550b1a9f62105ed08e7e1b329fb0a9c4cb7ff26a9470a29cbfb283543aef326aae261555569bc0efac348f9677f67df59455ac5755720b9d611d1b571db4b1086d59b8ca443fd1eda4197616bc8657e180ac710c3d8f21ba56cbecdbdfc4336755fc215f552fd1693e37cced71a8f242d3328456d0ad64f2ced4c33dcb08fe1dfb71fac591a99c151c8fc9017b175a21a04aea05ce380dcf14aab1ecf42e4487a57329b73f176c9b87ec17108fecd0480ede99343ca5caad7826f11d8903cf63b10a1b5c2b917ce04001eee1a7fe8aea78e1c32d0cee443b16e6d785111ea8813960469687e1eddc4d8b979be86295df22e6918045cf3e533e9f93a100ac582e3bab559e8bec866405f9d55369ed8768448232a148336d1253f6d3debffa81da1069eb1de59a8d955f8e00ea8168ea8658c16fd9ed04892e7af2f523cefff25de209e56e9c3b4c448e7e32afb5718778d306a9bcf61e6677aadfd604f15d433a567671d63f43019e94204a550f4b356273e5133f0aa468623bd8944236aab1c5e19c449aeee9c620bd057218a9c6cab1e1bf80d0e8a6ebe48a0eb35204d2e951bb9c752c71acc3259d5567c8f82babdeff387965e59caf39c86c53ef1f400480067edb79b70f388417f09ee989d306f35f8297908629f13459d2094d4c45f252fe6eb9212cb8d77960191d71191c03fdd7aad5d5aa7afa696e89c99d120179732aa8a3e6ac933abfae0606fa0e078f761c1f09f6b0cc64f0f8e167545bb22232e773fd268bf9695837f8ff3fc90e0741b4fa71a50cff68d9e460e851089ca1cf66640038782fd8c80738ec6dc1855f74d0cccabb4d84e5f2af83a98a44f2075759b5c23745d0e33b730cebb73ab9ed8c8c6e0bdeb4996982b13694d66d6bd341074e5b7e56a1466e559807ba23c1a2e2373b6540f3facc01aba690805205a8f11bfc74d4b2701688baabf495d5b87938f0baa45fbac3736f024880386b85009edba18285e07a8b46d7355d246a1bf846934a464a611e3a230512fff853999127e3ef347f88b0c563627502fc3de9b11a4a80e01e14fa6f1673c824eefc0b7d3f1aa1a8549365a63a95ce8bf166b8c8ad282a1d9a5b06f0132059517569a5a8a2f7b534f822c7315536b0a88a930a3137892a6a06c86d2522e013a4eac9832fa08ac24e462417e40a005208eb86b691d58f4c8bc82b1b75fc6d07b48f56854db1fe061ea5617dc1cdf3417179056abf928eef12563a60360d563c9daf969cb9737a525cd4d974592f16594a4375480c2eb41978b41e03fb48a88c0f2daecb9376ef900d4d47a7dbf7d1e3f7e917f889a3b2b4710e595d386b1e1a0680de56021a9487e3f9c613075d839febf48c5c3744ec44fe6552b11a6fd6fc485290145bd831a9497570557013b7067486df6ac1862cdca39fef15d500b7e28c2595923735bcf4e3ab95509bd45e52a4bc3b9ffc38d25d3e27854a3ca8e4e26a4866eed9c6e3604fba0db65a6c91029707e0067163fb52f72abf86deda90c7de18237fd17660ba92fc427806ed598d4a3359729750abf70645f8d3cdc5634d60eb338bc2281bd3710fbccab1247cd3eb7963c9c46820da15cf66e1fd5cefd9ff7f562f4a72aaa15abda7be8dfda8435662052e36ce1d1f4fef6c1111650267f682402ef3f9b97737c5af86db8c0c246ac0fc99c43995eb8cb5b4353079463af2a90b865c2041a111916ce0830b195f0a00874912f3b771f39631836bd29057b5ad4dc71ab517c396cad82e9d31d86a691e82afabab71340dfdab0b2677ae437ce823723902a3015b00edd6639b1d36f669c67934554ed04e7beacdb6372fcccea641ca77779ebebdd308ef4c764ab61f71b27caf467fdcadb2d36bee49f103c4df75571b4257c2cea459c15a2bd52f2c2bd7df629ae20c9ab853f25890be9dae831087d2161291cccc48d6bfd4143d19bad2922a20ac0316f29b277dac55017002327b050ba836131257ab0db76aad90d2a17183901b325c6cab9861d6b593aa447dd3ca07ad9e4658af4c51d782308b1f83e892b04c749ecfae959d68f12150cf309f90e8247eaa7234b68025fa40728422af00ce7d27ae78c646ddb0083eff09f72450b0cafac998427f618cd1715ff8c18ce3205cc47652c2c993568a40345f5eb72779b0004fd86eb2c1764525afe3d44d1e5ef3add97eb3ace00e9347afae4cd5f9511c33f807362e6f855098d3aa38bd3d26128dbd8df44bd80fd95ebc643f328a62e1a2f2421642a0c95a7eac4e85ebc41002fa5cfd2f7b40de7aac2c749dc7b65400625748c463add68c337ea116fe396e13ee1ab6ca65108bc8427dc1ee73983942f75538651245b4b6ec931413bb4c13a6bd514943fd65dbd27171183f6aa2127c8449369d30b6f87c8142f7be3fbcf1ead38ddf0c6157b0df3f852c1172663c8de5823db9b351429a6b176687428203e0315bfde28dec6596b15ed03be9c8b32fa4616dc8424a332aa680f9b53a1502df5ddb13bee822c83ae4fcc2f332e1d3a57fd18a5892b6d5b8639bb5f1813560d19240c3b4810faa1d8bcabeae02916d83b83474920a261d51bb09a8b871359647d173a61cecc81336c525edb5dc713e8d37046da3dc58687a93811c13bc4c0ebaedc5868ae89f85b59da4b02d751af3e7986556a75119e41753d10ba14a1116a127c62bb841a668642b763eaf92c03386436e1be91e3d10e6f83106a446e96a338e2ea698738bf6b8b34349e56c0dbd9d4994f4633ba2962f0cafa978140ad480dd24c8a521004c373f3797faeb90e1e9ca4b3e4b5c470a39ceff250c59248714e0d0d6e8381986fce4c510c3008725e6c1e6b04fa9dfcf572e5f1a120721472dc512c74d2ae082a4942fcb8dca9d6b3ee1764a0f3c4c212a8e30260f3d098575b04fae84a67f97e5fe89ea784a0279fe26f784848a2e4212b492bd6e24bd4cd5c14d0cc2a3616202fadbc1622e94bdd5d7c85f9b88c9a0e8ad273f0591c67ed80e626bb1e9135e137a0a49ecf77ff6cd310973c6500ff9bad5b5787b15e49179987fa88f077fd12e32e9c04cc217b587fbec7ec833d02a131e705868ae52eaa64d83aab95dd497c681b0d2c7e502d371e776cb27038fa7b094286daafbadb96429dea74f4d8e8f8e3df30e72dc6120509f172383d77d235c20373565d566be43eb966f8121fe23cfa3824e1ced9bb1091631be68f79f7a0670446479b462817c02eb3c32172d057557dc3172b12dd868099eebafcea2e6e738d213108a4faa0a7c30d39f5e9552e42477fc0704b9314b14cfdfdbfd6854d00c2d4b08cf33c52caea7c264433c68c41c6e80c51911c70e93f9c6d338f50d19965bbbb6e6a37167c0d70f2669d5d2feb413f7245f90ab387378d8bee0dc4a55fcb5760f235d0687b51b9e2a66cdb9a2b76520dadc3b58b101da6092bdefd940ede63791edcdd93bc71e82ba79c579e631e0760cba65f32417d977cd339660b4ad3698cba07bf385b0235fe192739f05167bc26f23b33cb891db00ab20dda7aae49d8eafb080829705033f324db6eeed74e327b98c736e8d91ee9c98ada6c686ac3e406771b287264a3d0e53095b835c723a4dade439d8e51682676ff8860b94499e1407dc1d523e8640b7751b2a0fd376cc50730cdb65551bd5f64dec28f7179538337346787c68e0ee50a240d563758714b06ec483e2486885d943d65ed65292434b69ad965271caf1f97d62380345602075bc3a41419cfebd0d88a681c4342b9b7753a3634fc19d561ec449598621227c032591e40ca818edcc5dfb3aa86450c4416c3c92a20f48bfd1421a9b208f56ca8cf8e58278c6077a3f10ba37413eb63783aaa089b217e755692f1b0d1e6d7bc4455153b60d3e8bb420968181183967b4b942fe0db86b1de6a7c1ac63dc9c4227a5ce1001950b6bd1c65cc8ad1e67e3d664a06bdbcf820e3b473cb09567a9d6f93bd24be0880165ecfbe206fcc5fa3e2affa5b682337a7c16c377e9c65500a7119f621220c68d46d55e57975a25b5ed45184d7c6e1cd95432db77667cf31cc57f6f2600494c1fe51be80184222db904ed2861a59e36fb1ace1ae02c068250ef9f4e51c2c235fb2f94b3b00f7f1802f962578723dcede3ef035980bccb6d38133c7936b2e3eb49ce18c9f2c0965ea153260e59136ab627c154b84c9403d45cc58e882e1cddc92add480a26ce86b8372848c3ac8aaa2e1c320220b52a8eb08eae20ae68aac994e2a88824a5eb791afe1447d443447c15852a16dac0f102f6ec6cc8832924983f4070cd22551e7ebee86646707b7e3b1d7fb08b816a7f77a68d9e28ff43d3264efe0497057676198446de33f15baecce729ccf3cbc77415a5d64af8d3a0dfac6d0c042ec1c811d7ec4e973049dc6a0eb9e0b04c91ad08fc7e0f4c08df76e33986c8da0c7a97eabb891fd996ff3f02e104b5dbdf9b7831c0326b8c48956b200d8b95ea7fb30d3f345a0447c39a3a5db56a664420fbd6e4896346f4888653f7d72e813cf8174b385feb65679c62f0f95d0fd3f88c4601165cc71f47d43f3b801a4ead5876e08903b2f523ac97733e25e5f5e74b757406165397a0045ee3b3eccf8513ad704a08c732c921aa775c7e36c469d20e97947026abd1778493790367dae22b9d70e04cc6ccb76b5faca3e5d6844e0bc50b7c2c910c53cc872cc5c010874379875a83cf0abfc92e2c4a57b644fa0ab02ee43c7e8cc328c8ef1cdc04bba8a29c0ead76d08963d5d089c0dc31aa4968d634f6dc803b7f7ca42fe10656ecbfef6f7f98faf7024a6d5f5049d3d16a97e23f366243806c58119d2b20188d0a9a209512ecde8fb4d6a1cc3b3c12ea4980a19eb3ccb7b53ad52209856cb5ccf01b73e420ec7e213f24e47bd9198f4509f9548ed496250749f49dad347e4043f6dce0b9735826d4a554fc043be7dd4d722b61aa64c7ecb3fca0eb59da5ebec9664b5c3dc4755d2647e4d41aaa9aebe9753804e38b5028096f964fed9a5c86c68c642a3b04a10df45d79cdc1a4641170e84b07d7067b07efd713c11c3c08bf401cb185ac46b4d4f50d69c5426f180f5ea342d7cc38e214d112c21a5b2affcaab8970480308cd3289c468b83a4f5b8ed822e2c2bdadb072aa5e8e3c1f399ca90d1de3f4cd9a00d474ac42e05295c43e51cf4320db89f78a8a59caef7f688d9a20f42d20065d9a19d3db3c9555da4680ae3562a7e2b612b7d7df47d5e447ba40e166d365a9a4b61cadbf99f16c3b75793b43751df1fd5547fe2fe44ee3824e85a54f30d0fc0f0fbaabd656a87a197625e1724737c18017109960a68f042148cf554615361fb46909140dd9ba5e0165279211b909a8d0eae444f9a099751d0cd60cdfe4b604c26a05850d247587165af630eb2688a9bb0e86a23aa7370408c4fe739bae2f1a63ac329eb81d076a8ea3f57c124d6355b44f35a2875cf390cf4f62a8bd1ddc14b825e4bb18a4fa236a949cd991efbd6651885f9b0caccf96c8e504be8cd53c722ab890870816744bd8ba37b25b59503a92ea64c13b296168c9d25de7104601d726e6559e9eb466d1777e1f79945b63eabf6ea511694d22d915b4313b9fdcb34ad9c2d9d5d450fcccbf82d1431bd991f9dfc05cd95d4fd877473e8b5614859ece1d79584ee30ded1e5676c76802679b69fd6cf9c9413feeeec8fff29c5b3dda9972977bd7c096cfc83ea76475790f04a3de4657ae229b7c225facc13ff83a6599aac01e25a8697d487febba0df9bff4339440462996045cff0245aa5c7d69b0dd04af41d0e238f92be64bfb4624970907077d2029330b864ea99315d9811858d58ab58a404bbf5485161a1612bc47e6a0676e451fbd209cfd024146d456f39139b50cb5f7df726be05da8b039bb246307542316fdea80fd80ceea02d0657ce2028021626f9abe05757bc020cd009a7a764ae70e82a917ad45cd24a193cb048c8d14be9445b63b7dd5f2fc084f309d1bd9b19d093e7b09b5cc927894594ab1a683e0d2ff510e7c414e30036c95d308c5a04f88036606ade109e013e48019612b30097e425c282368b5db048b031f201798095b0193f00be24099410b7002fe0638206686e358edf16bec1afd8d4ee3b7f16df4373a8dddc66ee3dfd869f48dbe46af1adb0dfa763665178128689b75b0dde187220af485a14dd085f09939e78cc17a9c3c7e66ce21635a4e93d39722d798395b0f13e3e7c89d330d967372fa9cb863c6d1324f18be47ee9861b60c13e677e2983246cb71d2fc19b8c6ccd162e6e4287d2e73206724d8f2a17f52f89a38c6ccd1629e18fee1e0486e091b4853770f65f1f97be0ce8c9375aa895121d573ef05cd9e76df3799ba14a82dfc5053b97d38009eacdad67af1c8c53e1d92883a5ffad380b420cbf229f56115f427e85bc3d2c87f7d1f293b507bbccd5667587ee23b807c1d60933f0325954c18f2ef11e725acc54a522370da8206f7435630a88d778e2b60aab653263f866d7211eb82031e018b8231098cdc8962bf5d82a539c7ddaf7494f2972a24d1c04eb3012101a0f3043e2959d42764987ee2f5d1e11afa4ed1dece78d48118c83b8991810f822692371e713fe66b6b2912e3e04a4fadeb90544590d3e7d18581f773e1e56f61641acc0573de12d6af6a0d78a59f4037767d25e33606496cdad5a83d215993fc27270dd6d22ba7927499afe0f3aa77af935be6fa7680965757c7cbc57c42cee0ae6c7833cc01d6b72eaaae5180aa3e852b02c973a85c017094b6d0f05bea797a0247fefa4cc50a5dce370471b0d9f6d465b6d002af78089e6aaba1dd5c56279b79c0357350f8a2eee06d2084140c4b1d805eb670f6d3bc43f1e54d8b391898aae102146e2d10e5e1cea833c895fff409fab2b184d9802e5cee2483544d2aa06975b483180a0f4fcb2928ee5ab0c1c775182f8ba15a882bed8c18f54483fac31f9bfd65d67c7d3c56f49194a88e742f9a92bb641c829a6608558975106ddbb6dda87a00ac68a70d12e5e061d2ee0674031d836b29db95eaf35676312dae63eab2f5d48c9ab1840e06969e395d80ab766927e3475ee314249585a80749d980c51c2e0f1d74d63b9e6835859f47ede59bb2c80814173d427d94d84741945cbb4f7d1a2a3bfd01fa4b512d40e1e36dd8c0c05554378ca76f78865f39458902a6f3071bb5fdbe7cd5f86e2511f5b77b2efe85eff72f5f65ac020091516dd31002f052b539222fa2f84127c6ad675d7b505b1621173952d648942805f969d7e4a3f8bd9cdf338b5f42f5f39a80e50345f3dc5504707b78ba7328379374be3c4344101f7b24e78ca78f6002977546776606c0e46db31b84757f95e10959184830e28ce5ab43250401e3b022f7340dda7db83bbd4d4e81456f6f82d1240da1cb35d077cc185d141b1c7ceb204581407cc6a52c813b618a04c7f806caa8df3d09b04a1d1ba57154867fe95318446e12aafb1b0d77cdc0236af234f7724a65454ab80c144f3775c92cc15006975936124b1c7cd40cd6c4ee3013195452dfa1341cb50228cfae44bd87812e15a0e514f5ca09eaef397dbcb84a35220d686f59b634be8810cc306c03170223c95054b99b8f33c1b14b20233cb3df430a868cb390c1ec34d3644fbd6bdfaa555697d7cb5cb24726dee2f5ada3c4da530ee15a693ed31aea1bf3a5e937adcfb1d68ee301ef9e76773c0674bad3d45a00adafc360214523581fecdf8464a40481cb22d541abd2e40b8ef0c6b2c64f2bd60ac3953522a148321ec7ff786a5cbdda9b39a791e09dce1fdcefbc08bd787c5aaaa79ca9602cd6e0f78b959163bef69198ac99e8cd7f9a8db0ac46df5df67960829408e2fd72ab370d786214cd223374d57cddaa898df01f7dcab64767004b9bc907a697cf090f10447c46b41506910d18ba78b4920dc3924dceff96b412bf23688150348a0d51cffd1d413b1aca1f142394e3afcb46b02a8682fdc88b15ac753d5b6f2163a9e5b1c492861478723700fab7aef7f9c3c7859627491a888feef4943067df6c42040a9ba8c93acdbde4bd03921b6278d39fa69e13dad6ecba0b7464c6b70ec34b93451b05f4c4600098e8b600b4681109a2c7340ebed12e62b301a936349fb7dbf7b0e4e7cd1ba284a71797a4dec830c731b37cb65adfc25e8fe8b27221b9debbc7084b026a1d9f53b0cdfa5fbc066d5d2d97311b27c8ae715085a4cd42080cee17c742163be37a9c00495978f9124df0075a2d8d77b3b575c96568a64a454c20c733bdaa3108d771c809e8d4a577d566f6e071f2e68ce086978f01af5eb88f80c990bd1154f98c607d6944bf6ca5984a8f4298491569d55942a62734836f07b17303723ceb98880cd87f3e0a82094cab9e73f7973ce217cff33510839860ea318856af9d58f16ad101c2a22d722e456f77c5b5dd27c5e22230a384496832e095297502587130b11645065f821443d336a74f310b4add2b779c18afe515f513abb14f1aef373d4f20532f612bce97183c56da0fddb77ece6313092d8fa1fc45bed5fdef6f0dd3b68b82024aaf760625dcff38a9a49c8c74d0cf8e1e574ec4e614a12a01905863b599398275b16f12e3d997c5049550196a893bb4a2ec5f5b6eff2bdea83b986d1e7a94145cc256979b5f956bcd9767498fa281c368248c8ec512a762d76aaef4ce388c4527d7c7b7fef2f5ca4de219be1f66189ec17409a0818efec1e3b1dd77c15a05bc63d0031041439487a46bd48e9d05a352734f3ba923d262d0af8a69ba2b4c1cc58055932742516311aba55c8b8196837e8622e1fabcf89002496e234019ed7deb3440a910209f8917e2ed152aaa86ed67618de87795fbfa3cc32e15aef20c1c46cd599cff0b030dabd2daef1df37ad186a75e2ce2addce2ae876876c3c0b823b30515f434243ce88baa3b9b881a669ab4a75630a774227a03a866ecd04f178be1122d2e99b5e00d5e0d343620347ad070e341209ea49d52914ce47111c809b802aacb43b88bfbb9a568211df44629f642ab2401623ba348d3ca60ed8e619005e1b9290b08e04b2ac7213aa7440a30e903847d6eecd39f7580eda3ee9dce0ec220c05fb2c51dd34725acc8ce054226c6426e942f7f53f24efc8b1a4605fb4e6b86cb4d6adcaa8bf53a68512b1814773b77557d8f6f32caa4370198910a00f99e9382967342e214d981edbdd03d83b91513fdf576152a2e7e70500c63f1ee95962dfded85fa3047526fd03398c5abcf3a3e1f02dcee7dd60d1d2d0884dd6631de69037414374dc5667e1180790e46449e10b637610e78e4600cfcfd6c7e1207300b0e1dd01c7a1923269269c866f8b6f075f3d5ac56904516f9ee9c5937a2002e66a0ff7c9c4c18bc9950c9a489974581e781d2779628435592d6f4b6b998259e910b67df459514a19f9445601155232449e94d723a6f9b92ab9d6727430c99c6282bc79944a43f2aa476efabe79332e9baff489d26676a4ef05f07964008361b60cfb10114efd31a910886d93d72ec3605762f722b55f26eb894e91db206d060ee4ea8e9238b974c465cea1c14a6fb06543629ee1165a34ce39bb1ebb617e96d80219105c3d35e3ddd246e2357a1c893e4f660cea2398632d567c28883d2e87d99baba04af7bf04542c24b2058ce767cc05232b48ab9d61eece5868b05533401dc2ec8bd7682de66ab711e89848bad04f56732803b2c3fd76080f299e7224e05b0a9fad8fc250c608b29be452ed8d8b6306556acf9f389a1270836a04413609a1d1ab6e1dd5d9d235057235390fad6faf8e21fa6fa9fabaff3fe86ae8e16ede74fbbaa32f73ad664d9c495ac98eea0e279ae266b9be1be102fd47c6f91570a91938ee7d3b926e76de3f3d7ac2ace80d4cb2d12a735769c2113368f28b44ffce9649faedaa6b98b7469a2fd3b5664608d66d6154ce85e4330bbcf3abf9d513c40d3d9da9801482019abb7fcef4e749ca616b0978a982d3e9c866bc8dd77f93f510422bbf4a5d47502761436d0d6e951822e396c3ea2f8e02b8c2b14d00bbae9f9cfb97c9d4492166458be0e3ca2e31a663b048bafc4cab50015039f67ffc3ebab48fd1ad68fc7106b4f36dd6f69e6b75264fc11c5b0c791de3ce77f9ba2b7239feaf4a87f7afc0bcced94842ff29d82192cf7daf49dcb93c2028b56ca886177fd293591807e18384558ddb900316b04ec3d623754250071fb8b6af2a4d87d18fedfdffb807cd408cc80f380030762e57a05d375b465a73f5fc798c68f54b4e809a4cc519618f7af1a468e126ba73d1a07906addcbfac2296f0d03de079189249d13c7377b9968a38ee2e0a2f6413a0c8df57327b2ba920f7595cafdb8fa79b58ec9a0ab4f5604d95ad1f697ff02e33c5f76e615fe588546fe0645ba6d1af5b6ca803184912f778b0db503c8e9b44ab8f98089b7294ef0ac01a60a4f1187a34fe4262909f561fde3d3ed1e6a5283c15b9964b198444d106e50998092d80a547d492e12f41a0c023fdc80ee111c946dc629081a3cda10a3b1e85c424ad107a4f6dcb99cd9811e6b225721990f41add00ea8b35b85387e09132f7e05e3a0ac49c9362a2a56b63d10f7c511b4c20250e9cde6d876114608e5d05eef5fef43caa203487dc81f6b805f97c80a0569e57b159e399600614a1ecb84c013930e49a7f4a9294f5c0b51e682cdb43676ce46f299b344ff2a8ec0b8dea68df35a3b10d5a5498a561a9f73f8679c7ad9fbf213321144d11ce971fdb9001581a8274a7003bb88259a7079903779b33dfc77dd5e2c4e247448261498158c4a6e2cb858a29cffdf2449b5f66584447d9a0381680f490accacac57bcf6c0ea0815357ef47bf7427a59d0de069675a8c7772d4ca9b6f6489b1efec5849c33ab7fc125cb50656e7ebecf740ba9ce542581c42a27bb853517d283e0160e445096a44577905f4b75056f4f86ee24e71e7a26fcd67309053f7a27cfd25d5e25cb7e152b2593e52db08390b96e867ab683cb6bdd64de1fe0f3d226486d5260e21c98a3c1fdecc460aa4589c9c7e2fe5c773c307d0a126c0ac11a4eb59e36214f7d9cf588b5da94fb963e3ac5e1690bfb9e794fa207e2a37bb1c92da3e0c611e02c73c9800c8abb6e3e96e9914e449d4ef6a1f531cb9c04b8bb0254dc6b99b33726e85d243dbe6afe96bddbb7364db8f90ddc2c55c56b7a8787cec8f99c2fb3016637cce6cd02d4c8edc45dab90e92470757516ab626ba967a81fd753c543e85630b70d7af61653abef4c880877201e7686d60c24773bc15c9a8fd5b4a2539bf3570ed1794069d31a044eaf39408a99bed0502aa6de4356809527399936eb60edc68b1be4921f5bbbd45c5ed17540886310de573e9024bcd290724386bf95602391dbf5c2a3b3c232d9d38a67422c80dd2a46f04b2baacd4b89c52986a90a5bb3a5e41740331f57e28f4acf81b60769c1e4302319c427dd1856f10704a8457ea09a50d7dad41ea1b7cbfbd428f3c7c2baffe07804800bcf8aa33785bcc42c8c910bb16217f466c237eeb8c9650d606240dd641329c2c4a641807a5cf4af5c070b261e4e3b3db17af687e2f946db01cef665837df1cb5ae982815b0e072ccc5eb6ea4820a553460be7344177a439c41d4eff30d84d8c69b360cf1dcc3c571b4b37b685ad6af7e7f30a7cdd4bedbac884bbd3b2d6eb4dc4d68779abbd387eba064596bba0c1765171b336d0e6c69a4be90223d0bb6f287b517b76b7e1ab65690b6e9cb6c2a71722ee3be095a78b3d4187e205c97e13b2f9212549ad7ff06a72ff5d0c7755feefe737097489ec6006b38a3414c8a8993f9f10bf5a5a0e9904edfc24584a06992e6de2c6738370cce0ee463df57aa4b77a59aff5ac9ed54fe137e5c6bd996ee8e6546481d5baf16fce1b74e3bdb6f7ee656f0aba21de6b1c017d88b85367f14f656a5b0bffda996dd180b98fd1d16854290a47847a04939bc1f9f6081828da7351104faf120eb2338274de14f873d7a7a969857b31957f1e323c82184b50b6abafc0b446889e2712db8579f42dbc752eec51e7a1bec5de6a4b7a27f678dceb3128d7b4a897e49e75b84352cf4e3d9374aba3be893def7c9f20fddde25ec7a05edd92f6b385b3eee562c585c2df2cdf2f41fed0d2abe7c2e2fab2e297e15907cbc50aa3f4e3d27d89c21f593eae1bf0acf657c5ab7a710dc14a736771e5cdaf90c060a5ce37dc5c518c66dec5952957538a577ba599cfd2cc4bb43206654af16aacd442b19a798b2bb9a8a614efed95373ea3999768259a942dc5bbb1727b60cd0e45375756db89b7f24a54fcbff2e8e8028d9f433f905edb8b0363fd5fffb90dddfe47466656dcf036f171a95ec15a377913e0e325eb8a5517b4dfeb54330b3c9e039aa3aa855b3052aa9a74ea14ae59b46ba470d6de23dbb6e9045638eb56919daa4b16edde55cadd2669b5a2c429a0621a8c1a841fc2100400529608e28a8c5c5e1ea20781e27fafd7eef55e12c6bc4fe8b1caae37b3b6d612a2d636217b6fb977e508e4071a08d3d5c93063a6f70428304134ade323c3ab90c4aa726154ac90fd26ee31c4ca02051e68c07c56a746a353a650a1d2f05a5792fd581347f922b613726c3134193e653493647590c28e0c9f2309f6abadec35b9d845c49f179b712d57aab7c34b21c37755ccc8d0c464f8ed03351226c3a334f003a10e0a199e7b7951c67824938ee24ffc9155bef803039213421d9ce10f6764bf0afbf1726e86af49d8afaa60049d3c8112447342863745f9a123c3bbd6b0e172d4ab65b75981ab11486402f6e8d33bd12cdbddc0cad938f1c795e1332e70b82a71e28fd59125fe1870f3848f8ee943391ec77aa932f48c92c68606f6822a00e00a226fb644596baae596ba6a3031352bc4d4acd082878367430cac5981082d980183e3f52b9b34934930482f47469c0d334a22986143110e36dc60030c830866942237ff2cacd79ea4b36389b2560abb59aa5a666a1f1d4c6c73de4c2980f6726d75777777b79431a3b3bb71f79d73c6ee8ec51e514a306c7c3f4208514db8bdadd37bbc72856d430c55518ecfa109413e44987ca802473ccaf111c9a7a5813a56ee5e72779883dcbdeb7e1022773f80e1451047b0c1858f4f8cdb5879dba8e46dbb0d236f3ea4206f3e4d70d00417b090b5c336d0c828ed912965824fa64cb041a66d84e00a0ebc9a1fb478811442190abde4243cc9f2564a964b4862038d2ce5490a1940b104a38d04d5b26125890c18174c36583093e784a922724ae8000e9450865d2204f2473a401cea92e59328813ab03f293e225ff211952f0db046fe88c421007cc93560f2d540470d24a5b5ad96ecb70e2c0cac819747f2104e2c7b0b14d8efc740a687e99b4803b38940e4696d8f1e666eb6daa3ad4ce7040206eac82f85dcba17038170b1c7bc95f1e6c09a590f03759460a58c929bff4e799e7042ab65ed5773e2ec0e869929868135b1f4ec26f172b64d579c2c5cd77ca90d3b7f8900b9d820cc566126550b2c0e7d13719ba065467b1ece0c4f3ce95c99613fd86bb5b6d592b03c3529365894bf24b0cab550a7b521ad8a7603ad8a5625571f6d48aba255f1628311484720df92675865fed9dbfb0f8349b0b6d24674a8854025a5437428d3a436a24374482bc106fb86cea6d995f436195ac928d7734a49a59452ca7e46339a6536349b369d4d2af31349da858c8c12d205ec66dfd992ba9c4497a3f6baeb4f292b97cd3eec322a3749adc8ee6e39a7fcbc72ba9e645795bcd3f2ba1c7541a6eb8926a59cb3bd98156d104688124883d50f5e6dfd633769ab924e94ecd47c581626d8278cd504ec8985524694230e803a992764e8c29ae8cd63aa0242424242a236dc0013e20398902a3f5202a56f909090909022ac616541ac0c3c071c5720f08aa214a1a13caf0cb1c168a9a252b56aba9d97e23830fd8a515830b231a2318ab245571e08a2427a91e50d07884068769a8e3d22cd545f1401348f4304d234d3b2c841ab2a14d4920cbc52d5aa66da81fda051a402eacca01ca240b1816ed92dbb65b76c198dae1a72c2e0c0e0ab6f61366258179113904498bf885d432ebd7bde943833d6dd46466b7777d3ae5bb7d464679dcdaa6514d367df289d31993541d5ea49fcd25efc8095313c0476ce395bad5ae984dddcc056fbe6dd314653de24d7a5bc4d4e526ec21a9ae54de3b2ca69336f25aecabc99b8d2c699386eeb60e84f53a96ea7086be067d10661a6076b20aedac4301bcdfe699aa6497a654728259bb3c8890decc0892644232072e287a8893432972191134300b52a154750031809694058102106900d8608030968074700418a15238080046486116140e9170c324018525a5fb4b42108815404243c1a08f10321bc60d2da322412628bb90358cb22592003322db0801416f0895181dd32240a228d9717b6cb902888a3208c0e932bb89665190f8ca094d23190fa05c748aa3efd823ffd82325158ae06444dc0c0082b55e4cb5b020bae341124234413506cab89272e2840c05a9adc618433a0384a810704bbca70e88c19c83439a307af32ce08e3c76e190e9d518433d238425249ea17f4f9017232001b3ca12f1f9200449524606087164970923d20609905329a65b406233489126589295714418a200769e4e00a1499cd3ab0840c5c800552e4600b1870f144e3828b2856605944404de45386444045e4cf7e8600a21184d08f1292f82162090330f1092288688827800c1044510928853434308411c4f8c072190ea521254a1a53764c61b30c87d2c8c11a6914e5c0b41ae3bd980426d7971a6918e1215c202221a55f5068a84a919101c038a23979280d339a20c1450f9080381a52034a9e191201c144fe9e63d6c46b85268d6a9a0788d08630541a011199107caa0a8aa05682b42b8698568a321a1021855045be604dd2c18f5012183f0308824f52108418c0109eb4981cb1321c4ae3072220903a0ed4564ece6896d11d32b02c19121921450b234600c508275e51ac29432223909899c2d60c898c18228527b6942191113e438a48aa7d038980e0402bc321352c906986444c9068b083ec8b21542a08c328096900d10408d90b8260d37082524a29f5a10645449c0f42d0807641240411911055e45586444240c9c0061be76bd958637422e67863582d43a21f1f3c614b39466984221aa29f2d887e84b2cd90e82708099d26c020065460618231b6b002762101318020c6154a88220650aae813642ea0598d28d410418449b135c321353a60a5e529cc73d639e9a42d3bc3f0cacf4b7b764398bb7be291a452ca86f204310a6a6db568b4c9df12aa840f980fa9048da22961e3db4a53ebc369b610c6186b8510c28cd65a82b07ea74bf7eb2157ac69a734f6a8a7771a654a9f4d082b841aaeb7f488187494db89510c3a3a12231e5589c10e9c32d4ca964a14231e9dec91ccc596b5167f47e8e930ebd262eded6157e4845b495aadc3c0e9dd5bdd3bddfe74b256d5a24552743b9db6abeec7ad4edf4eaadbedf6ba52e75028570a0f3992ed37fc1dc991db56aa956d657bc2495a79d5b276b3276b397bb2f69e77ef301175d90531ad5e254e8bea36a53aac3dfad445fd645d4e27a96ab5be242d7b249fbe42a14ef4747a94cac4fae9aeceba4356ad2399a6ae32e1242d4a8f504a69abd59242c3913c7f4f4669e960043a20410ebe324116ade4562283f84bc2e5c943f6194f5e6997b48361e2af475e6d6e938bf2ae3e6f5744c5624d6b97b4ecbcfac7d2e4ed3798b5c7169c211e8b1aebdca7655d6a3bcad5e567afaaf638777ade263a224a86441e18ca5ff421f2405046d939ef1019a1c6d98b8a1135c48b11e3af872c53af29db4b7872fd112526539b5a08cc8d75e0c94b622e9d967209efe4d4c07ef028d325ddf23e7d9276a1e5f44794f0b0b9b0d8b05fcd137a347449cb9123fb459fe8d2e28297b476a54a9c167c8408fb4558e4431bdb108158ad830748d954aaa1d6fa392b2cbd5edbd0b0255c85fd603089e3daaee5489caae10a68e7b473d8b51d265fa68a2319b0c6749369337da7ab15ebe1b767fae5c242261cd668d8e9d4116ce9dbe72b761160bedeb56123f334ccbb4c97788a02c0189379790ee7c897e93058637a16b604435ac24876d305c2f4cd74984dcf3293e9f14a1384d2643242c34ddba0098394601f83ba54a511cf8305b5621739d6b05f0705b9b8b05f0cb22252d12e98b029c3a69214b2aec0d22089bf28f412d4d2500029cd32186986a70eb209547b2624871cd8c6a15a39270b8311c2881f10a3917cc9d2e3c53da55f42edc94fb902cba47fe44b66b87ddab30200f892bf425a6e47ca1848338c0e2437f87a81a82fc5580f733d84b53edeac529afd19968f6cd8cf47218993235ff252ca8db2b0618d5a48ee0c657767a8a83d9823cb1af68b463627e7cb89460be897bcec97b4f25808b6d7b0972b38326219adc07eb625676715daa8264cc861613f2e77e9f51c9c0a308a9beab36f56577d536587dc94df917d6b3abdda7b755557a6306c0f6733645f222f12ed11ef40b3499b37562b1c93a53a0baa57f2f3f26ed9252b6a3ad4bcc34b86404fd62e85c0ace1782a6fbab2934175d3a5c49bfdbc29752d85e54d513b2755df698be52546a2ba09236149bc446615ebf5dd11c95818ce4b16d4ea73b58a744523356997a7ab29f134e16fd219e349c618a3f693fcbc277b59f1d7d3b7f6a68baacd5a5d1586556ada94f3b0a39485e55feaf5a6b7ee57b36bda670c167f3d64fb1bf47e4a3255f19055acc3c669b1f0973afdeaadab24abf08704667b61961d0c31b3e01d2646328964d7aeb14e57afa7f67e3c6493bce9daab6eaa3e753b6b37c99bba260cafd99fbe25d2528c7a4569d9e3915ccfdd8f875c67d681874c7db2e9d9e9ac37ddd2dd81568c645ec21bbd7a02deb8c2de6897da391b141081c01ca3ea281c2916d1135572e9b36bd7ab7a765195e5d46ae138b1a42a4b6618c95ccd194a574d24594eaedf2267fa2667e3c0588643eb829c2e0fbb19703cdedc48bd85e5b55e53ffc63c0ed527fe9278a8cf241eea15856754c9d093f56c62d7eaf328d5b3ba425d7595eaa2eab74e6567611b346c868ba48ec2486ebc9378291c6f1029ddc02d38585866df49eb1b3559e6e3a90b72fa9ca8393f3360513f1d09d667f774d6955d90d33728a5f4b2d56a7559575d5befa26ae16869c1d1ab54b7565917ee7476d865a5a350cf6cc8cdc27acbadc471b93cb1d81676d9e17ea96f6f8c2423523a0a6543669d85bf245e5f55cd70afaeaa73bd5f0a73a89f90d4a3bad6faac7ad945827ae7c6daed4e579851f7f452a705d990b598a9e6d26737a41a3520a7744bae971cf339ee4b75f984e4093d221460828a10a0e4d96f400e8e6ef96122216501e3d1e4c05e2cab8f40caf4ce6d6b1df6e7e4e453a491461a69a43021763ba158261c2d2d2d1c374c2cac154a754ae570ddd01423aba5595690f59de6b8b3dc387545b673f61c8d34d24823a5f6f4598e7e3b6d1cc77d5ea69c7d8a3e753f2179bbbd9f907cb2dc763f7a14b641c352ccb19c4b92f3519c2427af72b8961ba7e75a386e64f6593764ce701a2267e04ef614638ca79310976ef58d863de72454876c9556d1234eddbea45870b4b80ea5cb057fb505e3b8815930cbf330ea2f3939a7d3e92424c7c60606a3a1f13c1898974c5329fcb5562f2f17b645a55eae4afd2585ba769b3a9d8464d555f84b92934f9fa7f77e51084d5d6b734e54488ea739a79c534ea6393d14010911410e0c511221c892e505dd7769d71064e8eeb6e96e9a39a5940d9bedcdf92d838778d2b477f9c93cbbbba59415ce43082184b0b1b0f15edf05c3cc9d638edddd52ca150864a073ce49e3e1acad496e42fc13b249a79c3383c910692279341952da40e69473ce09e19c734ee9cd39672c452a71b43e73ce6932ad86a8539bb46693d60c0b4d8cacd6ac0d3a6bd6c69c342b514a33adce4cab6d64339b5ae50e4b39d59229a514cf9969b50d9ad579941dd92c7bbc966571ceda4696c11e95873933b9711c47b336b6d66446a306bd5a67d775259ab55192198d1995117758946a7d9c8f5aa4996cc3e462b29964367358b0df4c6c3dda68464a6fd9c41efdee121482d58ce4c4d2cc5a3768d846ce49b312a534d36a96d1c09bec309842f7ade3b49c1cac65da2cc5eea62cd8a314a7a6695d106d562a618fd852cbb21964ce88c879ad0b5232c98de3b8ada78cad96a6698f734ec945d3a4997c74c969c51efdd3a90b92fd3425ee6460e3b78823ac291d962e21ac29cd5caa9ac45940df007bf47510d0b2a1c8b4997c5c6c6cd94b86bff0a646afff132b371b6736246a398116db0c7e3a289c0c32ece0940c5b9e6d6db0f863b9521619ce3bb3ec5ad66d935ca9656545412c323c4b140875e0155d90599a32058532540520c3774d562e4c6929b2df64e9b490210bbc01c4494b0cfb554d27c7aaed08800c9fc30cfbd5b354605d707060c07593e1cb0a554c3fc86153e558c0bef999f4c7cca6f853653287f98e0bbb212fece1af872cf3ff5b22730a7fcc85d94b017f3d5906c73ce6dec3dc2f49fe51b81f0ff99f401267c624fe4e6f18dfcb7b7859f2c539173604fb4da01374c49e03c809bdaec7ae4b629a14a357fad52f2161a7933b86cdfe4da01a76dec265574300ee32e2c2f333e6891828238a50cc85f7c476e4cb85b9850b63aedb933f28d4ba9f975db838e251cb40c3e2a359dd8fa5fab4271348ca513cfab8fcc5a389c50368fe68527f60ca03a894dffa7ad2480b6d5c402816007c172e8cb57061acb5b0df4b3e19a2d003d703a45f58e2b90f757ae4fcfd55582925cc95dc3832347d03899c90c102bcf92a111368e43e0b5e041998729321511257f2869af09008102726c199675c02c4c185fd9a8ceda6331d8d3c3d2aed75dffee263589c21911256e4cdf428c4952ec5e50a4bcf4deed18af6e6e9277b6dd0b0d9b9974ea58e08fd40760de17014eac9aaabcd60061f108aad2e8cd13c69c8d917d608eaf4c82854de2e045ff35ba954aa37a7944da1de57ec65b5e74a61183aa7acf4913f4aacf0a489932c63f3a97b031068dc1b7ca4dc1b7cac189aae2954faa6bbe89b2c0bdbbdd59948891f64d8d1c0e43a3460fbaa734176dee83edf4e248eca9a7092770343c982f1178b2e5ff47da13cb5d0679b08590e91e74e9f2ebbec27eec6a1f66646e9bbcacc0a2091124ff2cc3f4646454748502091123e793e5e699c199b2c325857a816167633c8dc425c5724fa904df1ca7663924b8cafbf7081f5fa2f096c521c457fd13730cf2efa665af1a34a1256a41c8a55da9b309b88058c859cf626dea13312fbeef371a86fece72395be41f53773f7ee1bdc9a333d93c25dee54a8bd69cf5dfb93b53826a16ebcd2836c833a3023319dfbec21cfdce1ac339dbe9ba1c3a58b8496cec52f2ea1444edd3324f45c9472b3675be4b8c89db647a510d93e01a3bc3d0bb97604b0c66422c385c0a13cdfa44a864419a0424786444d8272ed23230b54f90132f1404a224a1bcdd9423e453f5434d013560bf58d8b0623edcd33c9f3f0eb22f2bc227f2ff98b4938cc17cd204b398b57fac5a47f7a3b71d95dd4549a79bead50c9f33d7718f9f8f8f8008990b022e94a9e9ffcc9f3891a59e44f2a416f2a6531a96fbe5894e75d70664279beae31b90d76a54b848abec97a32ddaced8264575dd9d1771d91e893296e9f7825265161a54fdf449f3c332b4d46dfc8f94eea9b2c0679beaf40ae0b925123f8ea8250a23272868d1660cac1a8e298c48124141fa9c2da2e86ce3ac4256425b0665e754b5ff0f0d0de844935f47970a804c10ba1580f2a2d84388a4d91447b16a970451f1f2aa21441e30fa7ba5b1a484231d8d1eff4eac258a4a26f287629311b294f3aa393f6e6a3933cfb531e8711c2f089b5d1eb0914d4c9269d51e66b03e3d1c06ce8945067c6676159edc5576d6641676c1b9d53ceee081f4307598cd0dded75c37477b794db0fdb766d64f2e7f23e578d5b6c9b9492b694b3bb2184d0e64e09d31ebc9452ce9b29e74d7777378b1933c6d8ddd9c60454d671db35a5a8a9b4954cdbc695b614544d2ab1a026163060177a3108c8b22cbb1a8dc0d4b030418ffef480d2cd4c3b64f938e98dd09b593725b69c34d36ac984ca3a6ecbc1d40d39caa6a8a9b4954cdbc699784add90996ab5d412947153c1958eb449b5504a0f4367162fa66cd8700ef98a93cd9291c5524bd544e965e9565abb212518fb5431a52c5a76ba32bdeede012b7f704a6b0651b4a1812a489841132bb17eeddb1f7253a2223090e5a7a4d99338ad28899092270df294b80cfbb5e2df3712a7c2e25b0bdb928d484404144ae1b4b48b4c7f8fa8064e64d99c19064174812c88886022cf4b0ba02053fa6eb528a5525079decce844885ad9204c865289f8eef21b0a36b0dde3eb86c21636c3b300e35ea49cf234f9949d7e3a9d8ef4cd119a4ef58f85b3faaabbb0bdee50da0c7f47724881adffea4dff2250ed2b9111488c3f59266529e31131b4296fb0a87d72761c72b0a1872f720f4639fb7a28ca59b7d3ed451fedddd50195d39d7d3be12fbba6e57acd27d767328ad4eb5d40e3a4b425fd2acd9c83c499b1aaa484848d4eee18361e0730723f8d1f2107e1d45bd256354dabb5d67af85a6bad75d62adf46d0d7d80a81e54037c9357badf3d5f45a7acd6a56b39a55ad6ab5e5663a91984b47b0116eb29eca6aba34d55a6bbdec82546bbaa9be845bedd563262c4ccdc0d0b22c05b046fb27a59c00f6d00e1b6a34b0466b6523ed69dfe917d92f067511500766ed3d05d499d71ead0415c52fa25133c9da95aca19135326ab536d33ad6ab430c30974e24e61aa98841b046bbe90856e62f0611a9efbeae7e4fee21f55ddf93af4bf3b2a6bd6a1046c3483a886eb141984f46d3112c15ed49813a11eab4f27c4ba9711e28fe54b15f0775901179be89140ee4393b0479ce22604d0e1bd8f8af6310ac99e768e267add606750e1227fecc39e747137fe6eb5733fc593a23eea22b869d8f41918ac681735a213527991af66bb5e47560fb72f6105bced6b8cb69ca696fe65285cdcc46515f7e1ac9043ca49f33c2181ff19c734a29613361d30eafd596f059649b854b1a47083d7d292332893fdae96dc0a16ff2b6c939bb66edb65cd23b3932c86e4913994c91357cdf896ac27e1d254e429327a641c80de050922349bcf6280d0f4f90c6dfe4c951f69671a5ef745f54910cc7d64aaf9f37498b7cf759fa2cdadd8dbf1b3fd21569ccca6296eab3342e229f1599d73eb34f9361f5794de2c8c5db1fcf0ca8f75177a1f010ab952c863cb95fe5b56f99bc0adba061255ed2a60c23493deb159e384bb57cd62d9bd5b1e3e4ba23ab2fb9ee2c4efcc943daada4edbb7fa4af927e92f6e83b3db26b181b84b19fcc9f39334a5bbe4f46c8cb1b833cfdb431c3fe30899bd5b2b5c4818e4a803929aab0cedbb9ca93ce3927b637d0c70b0ff207f3923f1a14963841a66f7d8c4c899cb8608923583c60bf7a030d00654a89342094e9bb05b1408a52831f2b404145d91414f06056cbe5d01c019b1865589eb9c670c6457c10d30ea14f64d84e296c1499cfcf1623955fcd0da5644d395bc258fb2666b03dd93489ad5619bbb9da77e609a314aadf44ba34e37433510961686c5e28945f6cf4924a29a59cb2b1946163d19523c8404198ad8b36f1944a7db04e75ab92f1b46948d8fa79170cac2aa652e7696197a7700bf3a45218d2ae95da5c6e4fac757b622e41628ed7aab575f26a0efc822d8cb52e8c9d7e52dd0f16a9345cbd7e49a011068a98f205ebdc65bdf6cde95bbc2c1dfe7aa06caad4bd9cfa25cedf72ed0ac75d375c5c386e6017015a7f790d2ecf812bd07297bfe00a4c61a4e52eaf80ebade85dbe4e77b956be4e6fb956be526fddd6679363927853a943a39cc22cf5f67eb08b7c8268a4bed35beaaa3ebb20aa14fe6656d9afaeebf4d5a395eb3adde52f6f5dd7e9ade7b8ebba4e775dc75baeeb8461e051866df9098f462f9f393e1fab481c1d9fad4f97d5a7eab3e5fafc093a72bcdc54aae59eee725bf7e3c9dde95d27bb225a0ad7f6ba4fd995ce42dde20f1a65fb6d83028bf2e9f5d6bbbc27d6faea56e2b854980626aeb7bc75971b69a9cee3c2aeee3d312117ccd3825ddd7c4f2c5691afd9c29607106c8ebffc84f3205ff3e799c288cb5d7739cf144674bc75285f2d98670a232d3f01f3b4dc8579a630e27a0be639825d304f118f10f99ad7818f84fec12328a70bb6f2650f632d2acde578e9c9b09c041659d4d5eae95b6cb53cde8a0c893cf0247f3143220f00e59e58cbbcebb6bcf59e584fcce5f6c4b6e65cb727d6727b622e37c65a2db885e3c9f4ee96be23bfea1a1291588dc3044c78518426a18c13e209e50d7cae0fd7cac9adcbe43241800f251f175a38fc76f9eac462219cbc850b633344171197eb30bb9eb9767cde35249b3962279c4a29a594524a4c23941c3972e4b8cc711d394eaf0e281ddf6989c216f69b4a344eec32c05c73d8ed38cd611784c7bb570c8cca9c1e7917c9eb3043188cb91f4da6df646ee797fb45a21f2b59c7656afa08befab5f6511fa150a878b4d91c7641fe83dbd1d65a9965be513222520c71f3ae87e311ac690e8af63428da13584393b2271914f40ad499aad3a45bbb6dcf41c57eda2aa35264bd7bf8f3be09e4e32426665d0c32cb7ca35b0e1bd8d3e351f7f2ed41b01f4d0282afbecd5b2d2929a4d0accbdc06aa3505e1514ac66ea35c03f50d8c3906b79356a2bd0934a5f44d6645df08411deffd7905d489691c9f4050a7f51f38fe1d078e7f15c7eb61c4a142f2d527cfe5e3f92ddc85ebf2811f50c3ce33761969c1c7835c88cb078e22860be02f3cbf2796b1eb0139a74236f807feeab1900bc3bdab09c19a7eccd5ae006279e1c2f018ee0b177235ef76197605e8580c587bf2c2d5a0c070352903fbd52a4faa6d5581817d92dbc763de9f494420548dd803ea7c22017500a09d51b54308849e71d8d5b07397911682e0d9c27b62d06524ff85bf8079048067c62ecf054304c0231b30108a452658098af5c4a6d88f266dde8579fb71e58f1f3e6e43711bca1be7eb5a46284ffda4f336b95f16eee30279ccd5b97763a645126702c9d71911084da26a4420da13ed45b4e88cdcdf00c0c2ed27b0a60fe43614edf575f2044aea6b4f2290ee40ecd11a4d6a0ec09a06c085f9476fa081daeb9e026b1abbbce7bb30f3a556f40afd88a9942dec179de0098499b03782e0a4f0afa270085bf986cbbf13f28df714a813f3be975957e15f0bb30efb887cf559ef22fac6c7bdb7cdfb50e7c76ffed9dc7d857f35775d8f7f9d4f873918763504e02e1862f69ecfb34d198a65ecc289793e0f2c0c1c14c5f25d784fcce64ed81eec5bbe3cf18735520014eba19e119be2df7e7d7c8b3f5a602294f3a54b10e113f37161daa38771fda211c80d5e017f35f7c03117079c041c913834fda277a187c1f4f42908d15f8c8f54c05fabf56da3dc0b7f31bfa4e7c93cc7635744c765300c33af8bc47bcc3bb286e63cbcdb93775c9867ee47e3c275d510801674f02314e371e13db06640149b42e29c980b329f919efcc743963bbc1999dfefb4f43c997fe6c2bce3fe97b95f4fbebfdf2287a5bc0f791e314efa464a1e972a7c02f9b8845d7eda5ce2efc72790c4d389777aefe27bcf3b4cde07cde58ecbd3ae08bd5764e63318c21a19f997779a5f7632d47ce6927aafe3d79534a7f7bcd72576edb8bccce975edf8cce90e3c44e6339f91c1de77a4773f99a3e0d57ca729cdf13d8ca4e6331809ecde775ae62e91d9bbbc5f0d7ec1fe7747e4de7bec86c03054012f91d9c7e93dfcd97c3ff01299799cfae0c1437a7f7d7b5def255f3352e6de5f3ce469cca5f45e9799c11f95afe9c48977893f27f2530999c71c097aa737862686493e8f6fb18361067f3d7966077ee11d352c9acfdc14bcef348ffbd5fc7afdf5172eec155ecf778a9ac3ae480d7efd15f37b1849cc656264be2369ee4e7ba7a7f9eb13eaecf8ebf599d35cd8deccebf51e3dfef1f83ff31d77c29a99d7ef7d7b5d24b07b19995318fe7ac8b0abf099fbd93c739afb29c934df71d83731f7b1037f4bf28ebf5e7321ac79e18f27bf7ce04f490c0ff975d8373f6e73087562eec3067f3ce41daff98f0bdbabc19f92fcf2813f9ebc037f3c4ef39ac75c086b6af0b724bff0c7e333df9134f757a1e630c37ae01d62e621e36124f432f732f432ff8efbc55c739afbf19067bccf5c9ad7dc1d34f7df71fb93b907bb22afcfdcbb1f0fd9fbeb4258e37de6e55d99ef38cc01a13ba8846d979435eb149140000000000315000020100a064462a140249808bbae7614000e7a9c466a509c0bc44112c328ca20640c308410020800c6001821a21901b02068fa44c7b603af965f4e0776b3e92439e6ee0df3f9043d0ba2916888a315e6157695466e2f4a16c7177c6a1cc7c508d3950d20e02481be892c2660f0d4ef419fdcc044cbfececdc2511a38f95a2efe2825a2e2ed5e42266650b9a123184c883a5985dc84eabce2305f065d9498a27bbbecd7322f50b349a2c92f2e591998dae67ebbb9fb5a98498346369818f17daa06af4ea3b9e2e3ee3d1b2f9240adec3664146f8bd6d5695ba63485d14ca530f552cb4c6fd15505d5be01c3bc03cfcb9d94e9788e729dc460dc8fa174560f28a237f4f44b96f716055e376589a1544f00059fc8abca1c349aba8ee5ec02610197c6f217aa1735a350b00aaec080e719a366ddabdaa7ae547d03a1419b5dbbe2c0c01dbe09070e1549ecf5f3cb5f819cfee76ae6d199e2757e38286671c5e0f6022810b3f32a86e6c3fc6a4e144ec95162ec4bb6bf2f85ef10518b454c17488d565d4221ff5f65c52cacfc016970e7b3140ee3e25f4865c7613e5397cdeb5c4db0ada37f9bc309934cb518f52ed3ff0146e557ae35776bd7e3deb7018a63c34eb7b4c1ac7d263d249e85fd60c762948d33bbcb8ce8946607312a51685b29f83b344c73b300da18ef91478956b4fd6377205d8c0a72dfca52cdc7fe47a5e80415542a9c802c4f94d679a9716dc78ae3f102c1653b2adea0e183061f3752ed685a1d88e2bc25dcdd565f0f2a1b81964c5adaeb4266dbe492c2269614ed8c80b0fae7642654bd006fefae302f749c2c96a2d873b9cc1786fc2e482c6326fd0c2e36e18618dda6b4aca0597a408a3f78815d2e9a00590a481de70484cb6f8d6ba4d0023d6b0c22a14d5876ee92f73c7b703c28d6ba62c4a9beeee1ec4a3e06d529de1c31e19c342dd879ccda2ff965a389b5c5ca79d834cb5fff56df25967095f1ff54a70d53b8983f5dd55de7cadaa146e8916d286eb4833f1d1a123bf24e39e5db4936262573fc28fad5369a46bc26dec02a0621ee02b1e13f7fa5896ecf3609c4c8ca5fa93695324f7e2d138916cf3f7d57d070ff0a99d71ada9e80ac8b9cb366cc399dbf0b8ceab1f55c7befb385a686eec46363e992967f1ea8416963410bf4f09ca5601112f1a0fa208e779d3f869a4493b048be70835bd1f6d6480cdbf0f75a27dfd58dc3f32ada23a9bd1c5b1ef15fa442cf400bedf203dd468bcb41c911a33837d941f71a418a2a96d3daa7e235fd29e71ed169f77381e86b1b2a5cd05fdc0896966360e1c621ea85e291ed2810410e98916b25f054327e2d7a5ed50d5fe8f5f3b5a93e52d6a6ae004b79c272918756ecef181daeb60355d748f975a7bad227bcb252f700e5cfaf9ecdb6d44b17144c155e2ef25f6eefd6fa166ab5fbec9900b17b4a9ac4313f0ef70c1dbe26a7469db161806c76f41e4f67550a101151da22ceac33fdfacc80fa9db3da808ad6479a05af102851e1e1b840c572ebee8f06eae4a6fc0eb4ac65f7c93144d98fec669b216d1b140b1f974ab36eac82fd0e1247b03bf2492b7237e6b7412b64f566d79c3ea4ddcd0e41013ee3a51d10af92f9a2771245d1d39a4c4a1b8858dbd38402f77427f1fdaeec5575d6dd6c5fca8f9a092f760863dd6e2b4af47e5f8e6050396de8972cd01d24d2bf9aaf82f4b1f9b9df5f217a21f4a22244b7f4f0745a3d5250e36ba70c5a592832e39960c15793debebce9dbd577826d60755aad603239865e8e4cf58851cc09ba5c8e6a2581ae77dfc27739f94d0cefd8e5c96bc4e10c3b253c4881138c0f4baf9f441e5c16a46130a90125618ecbb923494a6c27ad25e0d7c683706c3b9fb186370fb4c813e580ab3da85243d3b67d57b34da8f1b473b214806209dd225ecb78840b1c15cc7bffc78cdaaa108af8ed90e48e9fd1c7e6184bd1d328bc8153ca03bdbf3c2de2c50b60b5d06ec36080295bdf9c1c01fba71ffc84c06f67102f109780e0aa37f88b7c4e105db150b328c4fb0daaad6fad8368cc0b38a96dec46ec059bafcf0c56faf5d683a41226754a5ea094c6e05dd889b59bbd0a39aa8f870af1af6c19575a83f98d013097e00f1dd8c1745a6588e4b5c8fe8cda2b5d1e092a7923c62308bb7b14e8c8de31908216d89caf7a5524a030100143944549212aef0b9a0dfbbd7503f78003bde88f82d2ab8b55c555989d7efbf6b3ffbeeb98e8cb23644c0b5b9bcd2baddf06f1798d07b484cc6a6ea7f38099f162393b6867c91dc844cf7ab68e200dda96fa22b835aee20a135a349fc91522e4939b0a2248fff9b982f7720d0c4a1ba5a004eafa3c4f48776cb6027ad64715d879259c02660d2cc768cc4157d78e33a7c460b270cc8e5f372459b094dd6f9e36dd99101d1a3ad0370806813ea517d860dbd89995a2ef3aabafcaebcb0b56e293ced9d4aeddeec9d84856c52779acc58e39ee0d223debf7141e440ea059713e20bccb8e292bc0f0b51252ec61ca8663581f1280f81c245ec1cc7977418b4216fc57e90596fd21f8ea9c76d72921bf110a570a7d5aeeca8678de1425c72a6fefc3c7d526a557aec32801de6effab5d326c49950e16a56915182b2bb77ae37a2995ba27d7a5e7dc4cebf07804ca590e512e6f0497cbc8bddf992f8351c5013befde93cf3ce1ec75530b77946a453ba6882e26f13fd280c6d2c2a9b941e8ece17a4150f12d0a7861796e4461283eb77ceccfff0c3e4119dedc9785e19bb5b232c3f750967d825c20509f3090bd2b8d5592d298de1bcaba35a86998f366f484e85c9f790aa64e1161b65e314c551255ee1cc975f91cce014173bf4f6393e67b681cfee8571c3c82fbe7287665489203ede7879c856ac0ff738e169c68c47ae597811fc1a97fdc31c8ecbe470604d8c944003875809ad1f07001d117d4bf41857a92e9257b229b5f0e3318f1ec45b2ac903f3a4572d2136d37d2e0ba93bed7949f719b95d5fc55e45163092bd1fb729e78a9157299862fccb460d12b24c9edd78512a725aaafaeac63dec0cb282bd0e7fac500d7a9d9357058482800c6f5de20d0034bcb860b7e178165ecd39d90e1765bb39e3f82694a29ea30589469ee19a8a3af6d06a1edcdb574b8238b7d1b60a1ee3b0b02a37db4bd5f068d36cb2bc070cba265c377010af6c8669addee3d1d16a836e666a2a1e439307d036be7ed505033db9dbb60918a99360b296529bf9fff472ff87dd20283145cb3452e47d540833cb244291429029c3e71855ee3cbce409e16553e1baed26a875957b7270910a90ec1e021015e6b8836af1e01bcf6db986d23800d2c0b5edd2f9467b2e5fee8fbfc4393f15b763e8d2d9b0d1c5d9d9223cbdf06ca6dfaba08dfae1b9bda5d35eef451dd920383a6190570c17d03d64a1362ade067b8e975165d3825983264cca8a17eaba7dddc8a3b0b63bf1cd0cfd4e28f2b275a0ca6650d1f999e4bd822715c4148cbec4da862377a0679ecc77bb38b5ca3082c4446d5af019ad54a74526c3de0b0d1d637f3ea900bd0f1e776e66b57f97a80a3eff39d57c45393bd6a2ced250544e518cf086299b6b5f296d4130c9d9e80b9ec55a27cbc8680cf4eb0b55512489908ad637368b41bcf4ca700ee22c84696a5b73ab419913e9b3b64d6ec5603fa793f7fb4d24cbc5ada6f707b029f8e87f8f574cd1590b0880296d27446cbd45a38f532e4abb51621b40aefe864adc4ca0be1ec84581f2b0aaaa036e86ca1876bba5a30556e50981cc483375721f0149ca674291607e98ef668094e200ac068fa3bad6e6d046d1ea357ff37f743fbd16408c3e68d238162ad19d0b4273742a2c842520815cc3954bb9b2e0eee5ec8ff8a2eb86463dff758d25182754e764cbac00124b950667135b4e9a5f1b66eccf693dc8e3cc8ba6709a8ff8c5668af6bd15ad455dfb8b1cdcd295c4ca9937db9b1215cc07faf0660a4d0e9ab56fc481a6482e17492508167ca0041b812cd62b4eb015061120f2f775a1fca969af74d37da81a5bae7b8a318a6260329924495bc617cab2942392823ef4bfecb5de493a6162049225133400d3c10c815a0824a8b937de7fe7e836878d9a13bc5cce7a15dd2228e04148aae1b38382cfd7fe21a922fbf24e79515d01fedc6d677c81caf82c76976e8a55cdc40054dec6a240019cb5180393b207e357076f05cde25057d3fffb7181a273dc280cbc4260b7cc1356b76e249b759197ef93f1e3638f7488af8b46adf11bcc19887e8fddf322673de1c7bec2eedf12f31b9ad0a3003836452c572b3202562c8e82cde5071ce422396c10ebb4a6168742ac850a430f8affab0182c4130484d95e7d199a629c8c8cd73062c2661c4d143bd218c32e2cfe99f07923d6adced813c0afb41d836ef6d6e6acc09d375a63a1607f0340feaee97def24ed69acacfecde6dedae6eaed93b15677143ae87da89da0792582d9437a7c23be25ffdcaab5985ae65e26fdc262683c3c0fb892519ac27549a32d5271919e4676313224ac2755b6132e280956ccf6c6d6a6ebf2072cde802a3b5b0008372c4b6edd349408e74106f5b222d6136f5d6add4cab9350698107c1e026f8ffba6c4e75f070fa84cdc2ddb1bfcefe156932bddcda48abb79370f3b92079d35c9c4fa50d24a344705b227ff5a50d2e83c26088526e5f36745e30d1200a407a0147b889d7f05cf5825fcfb53c4c60e3388327a471fe42f91dc4441349dbe205e76e9c993feffc43864c591212b019558eac49692fb46949e6242d63bc8cd57b5e14d0170c27c569abd1cf025bf65a62b86f5a6340b4f03e265fe14ea937e51715f4314ab830239220c504c15615a643da015781eee3cea4a943c7f57b05a409245b93a1985ba856c0b50ec4779fb3e55425d4fa3defd0c5bddac73977a50543c5913b672ee039fc54e3dea3524caf3b7373dd9a4aabb657a603293b800b6e87d7b38dfabb00eeff5f6b28af5907621c89e5d82b6401403aef75a7de21a7538cd39dbb3c69b81cd452e8bb1e510025d04e7358296edad4e258137a2146c36a58731a9a9bfffaa915b4cf3cd06329012428317524330812978d47acfdc3359eb2400a5898668ce2807413fc3ee2570359c260d4c487debdd38bf9f07174f7206f49e23dbf6fd5a8490f8bb90ebb97af23ba7373ca85e8fe1ef1c3ea5b5df1b44952b850b67d9f68b83fbfc760b40357cd3eec28f634b25ab5c358176170cbb1c00bf74d4bd3f7f3e1ddee2417c77bcb0267d55db500e398c3cf6a05407ef0d03c9b04243cae235c4d319a76cb26e007aa40bf2122abe7e70c1a1d3c308a2c523a7fb4d1a351664e9106cc2674255f7df56e8256ce2dfb03e8079dd127b5c9c36502a9562f163dc76840d594785978433128b9b3eb835c2992650d156763670139fcc2768e9c2cc7056c7cdc09d8928f7b26ce7904024cd3a34c558df59368c563f7c917235182931c448d523f278dda44f0a3712a8a5ddb87809d2d72478bf5d1b466ae39f83c648959e191173d04e6f42705d6a281a6bfaba156598f58034359d6746261e1439e3865130eb07452cf218b39cc5334857ceb5bbd33c2e35e7090149de3bfa9c5340b9b646e817ed0c5bcd0f36a3cf1650b2490ffe9ac2ff05cacd54208e80ad08e9dec17358093dc7eed1192173e62b593286525b865a646b09266633336c06bcc7ca48504094d935cbb6290e1436ef075fa26db2902265f3d46b92937d2c7e1474cc8a4b5771279cc7a595153baf967ea9a8b50c84b2eb41e30e1dc1d4d99da4a5a8ad4c1caaebcd144ccb6b3846a04079b56e73e02e8b15d7d334d8f40a4aceade42e3333d32de4a2310b14f1a3b91cc6007b42f46b25a11f4839db46db88075cf5c01dae1af370580c601577ba06bdca77e43b2059a15269ab2c48f70d7d137361cdfaa5fa53c8e6292006722b63822fa0ca3b6be7dadf4b1d3600c70a77fbd24867202940b735c04813dbee21bb1b94d696eff9d7b9bf0168938580eabd7b2ad8911de8949511bd92071db1d0dd4c80f95b09e78f637f06d112a11ec9fae82a42150d667b55a4c03d8d61cca31ec1899993ae5a66bde19ed685e210fbdadfabde97ff5e01991a81661a227ba94641bf9da21095867aa1579a468f3fc187dc2c7023a7074548ac090f68cd1926d27aaad2ba709d2ecaf13d015787526ca3e474016e9aae3c5950c2d581805a1202cf5ff54e16a601d422065c4baba8ded193d825f3e9ed84230d7643e5b94505a732336ca7756ad47549f7cd06185dbf17312c0a285cc36d290c8e545dd9f63d9a7ee87b7f3d761b781cdb58abae61ddc99c5202d804353ba22c53cfb79066e2b4efa603fa5edce43bb5f4beafd3f0469f996ba161a78c893b2c28f5da804f84c0fd615941028714f3133c6692220fef1436ce0fce5d98a6aa38c16cc18a850f2680326aee68ba3f8d9d53b6cbd69167b98b7bd35e992d88e27813980f32218a3a66a0ecbcbc959db9661bb004c98596bfb91a61358d87a099b3aed0c4551a5cb42041149f101aa2e471818f793feef44f1174d7555b69179b7571af375ab28ac8f8f1a33e31c41335a8a18d8cfee8373c7845d5cdd3975e7350c6224ccebd87c3e70a81ddcc184c8ad6114159be29ce518285bdeb5808fde507751b31807335727d4fe4cd95cdfc384f6a4d002ec60278dd209405be92d4259a7e38229f3d50980c40e8e9141d44e2592c092d11d63f0360fc83232b6c074b7fafa265ea498d337ae6ff9349807e688668b5399d690292931c86fa51e33ca3202a9a77d68a9cb326945c967376a97c3d3938ddeb0952a492eb3b16652d2d473af01a4b0027858bcf837a424f989081634bbf7a11b2aac11f86eb03d31526ffac2b82dce9352e8b5ba1f26aa6d477b641a59ae62d7af011feb251191a627382a4c3e2ae2d8c05c1279439ec1793e4081db183ff46569500a9157f3970f642a37dc79bef4ad142533d43a0a24d75ebf7fca1d8ea65b1438dac006a74e6d7a8b238c64e000e846e63f7bd08eeb1f1d3e4ed812c710205c106fbf6a7e2d29d03ee7cbfbbbf11415fa5430fcddc99a95bb947153dfb373db0c0723c299d7cb3673fc7db6e4ce7a3d0076f7044b6c39667bf435dc5cc346d94bcbb05960045cb5ecd32d12a29dc4f984ab8c199ab97e51f77203b22bec7795071792321d3603af129574be29994e96186e7df2f5c57c9cf9d4cafa34e47054261e2bcc6069f094e5c1e1b1e2cde17e780ba90d113b305d8d9bb5913f7f3e489c0ba1d9868f3b816b835bf242ae9be4818099c2c8e6dc6b17e31235949ca12b9242b1a05323da125b2816710255280f0cfa6b768463bc4017b82305bb6815095324ccf5750c2d829552d0c38527c00874bbb6d6a6a4ddc8a65392d3bfb1eb6418be3c7ef0b464bb3d42bd982cefba7cbef003e4cb4c0e1ee01cdda7a0298854012a826b4c9b61cd1d4d0351a0415a8d810ac275c3e365563d8004ee64455b13e044e1c8951f8b3d8f37b0fd057da759ecfbac0a724e6abe63d01c662df91d42b8d1ca2bebc0b9b601fbc0194f49a7ad2fe5fe1a9136b0abc104bf2a2056b15ac89bfa2ad91e0ea53b116dadc4b4467d3b6bfbeca01e9172618f2654c615f4c61523f7e0a7ef9ac5b0430cec126d63c7af3ef0e0173d0c333437380175f68f096ede2f42b81672d3fe4156ee26a6c8dd4f241eae5b2f2a2f7cd8e544cde8813cf45fb96031970ce7632bd0820f2bc77deb00477a490eb47e2701d83456b2a08c4cf3158c455c8e217301ad11101fca9c80a1ae0da80ce68928b70d70a6caf878bdad5736d36a9793d0c8f605101aa4818caeb61806dc6ccae7bfef71affe90c02583e6873a1e1ea05319952a6561f8631750ba03c55f83698dce94ae5a8c7cadc299fac95d54e738e22b0e88ce40a330619c44a720c1ba2a844a07d6655dbe62e5f40fac450ec50d9f22404c3b624275373288065db41ee54921d27e4be57e1c0d8bb01471d7149a452a8d0d5a731ad11eaa1c37652203c88d2bb84f393f3f59898e48518f0ef98d9d6e260fcc29323efacd3cd5c17d137939c20b20040f1328dd98e33579f201d04339ff4017c95d243df3aef5e566f25224311cc6cb073d92f584e4ed94d0265b53a1e0208a6a4c996a3b8fea42134c42a6bbe74b4545c31142fc9ff13a08b0c0535486eb5928b4681b92482015c14ee9ff7d10791b55cb8725a024ae8c38d0f449205d38a198195d0fe63bd72f6f408b626126c93dc5353752e1a3c5c591e9efcd33efc937b4f128f48f9228457932695c3cd7f27004fab7508d0b2d3d539684e268f4f5906eb96337fb7aed9a89eb2c1537f7471053b9bc4a0bfcbe488d6f75fea79d30dd1793b00480d8e8c3da3e32acb1269a1c0f7930e89043dff22ce348f45a3d783b239c8e22967a544f998fc0b06275fdd92a0ea1a06e1f21bcdb68dd1f2f782f8db3df79af89214f2aaf20ac040f0f7cd3389357ed953df2767015479284956ff6900536feb77524a738ff418aea4c04cab2bd0d7ee14d356ebbc9ec07f2a7dd0a7e1ab7a65bc64d1bb2b0863835b08420669ea0407c0e3d37ce99d460e0030475e0ba4a470a07903d82981787ed991c565652e4c4ed6c156852f305a749e46c241e848fcde89608f68b823d08013dfb81342acf7ddba874dcc144c10d8257d24a3bcc8d2a936d7978bf89f6efc4db972e6321b9060a8a59c671348d3d9a2fb6b1a6a7da31c5a58bf38e01245e297108d0db23e060e19538eaeafdaaf8cee62f1acde682e041baad57d55b2f4f10773af3bc098c0772e45f4e15f8f4aa3a7714cc5c6b3ab22fb5bbaa1b16c11549421803cbd486009e5bc2734f3059c39479b6e7a9cee54d42fa56b67af70513dc55fd823c2b29111ac96247c4b531478a82d7102555114ad92185ac0b1cced4b084bcb20c5cb8f27bf85738d7d99ec2da8f5596cb5f5c5d250148adbc8634a17e68fef426b25f9797a85c2c6d9e175e96258af56656bff9e820110769060218a383f7f02a9cb56a5200b0b11893dac17a4d84dd2de42143ed0807201cc328d97c1645d4a0c6ea9ab7b8f7e9c09d3f13b00ea9c812a860af5fa1641b171e032aff3c8755b956a38a8f074a79a3d3571a1dcf10450f997c4c3a46c4485dfc52ab59b1216b5428e5322824b24012066cf2c857f044744156537ee79ed3fc9a2f94a8b18b1e160bab61e43df306368d30594f25867e4b220ea4640e11a64fad3fc3f94b537fd1dfc1ce268d1ebc5be5762a03de9a10058c137f913ace1121e1d11de1c1139693aff947e1fe9d734244b0459dfa2efc19e1fdae752d6c53c2fbb945cee06b882210c5db15c132d2f1f619bab4a734b56319aaaa1ff10bc0821d6634c969b0b29fa06432f2422d1dfd82edb74e482df624d0721a88b846d28d9296402eab19d0ad6f0a9ddedba7221dad00c84c33f1d16715f9842b007c8dd7231cf75310cabd2ce5d3dfda69daa7ffa79ca9f23c1a64eb1b66c070b6f1c7b9a909d4cb830c9582c6169dc100b188f1fbae69450c80a319533d4f2efa2e1803250bfbc6ffa61216af8dda157763ea727ef9b7a5173e8a884f39ed250ffb64153316130021725882b3752a37169df64b16c88ffa1b9cf1b784302eff90f006f02beb80e0bbd760fca8a2cd6a235d85d9dae54e384484f1220ae12851b8514e69d9e6bf1a475a8adca139b8fd7443aeec2dfab20ff7c1aee889e572817ded39fdc9229e66cddd4fa8cff1c7bdc5e58c43f37f9b6b7ccc79831451c53b3e7a17a810a42d1b8322da0bd8df1aa3e12ef8f305b1dbf8fc5a4c54c7b360b3de04785e97f1e9202b361949b3c8aefb3f1da0ed894a45e254bf20d0fe716ad321ef782fd02bdbebf3f25b27b1a66fcaae62683f6c8cb951222c03274dfa0736ed5a7e117b321e3fe16a034c40517aa4386d4e1898d8b725f298a99cc4eac79074bc99c1ec31a638c52eeb8ac6f48ccfb245831c612e81b733585c6c0cca2be6507d9f05e52e7087c64e004a065c845a7d724e786a5f7528abd56808b91b04f644d54aa09e1e5970ccbc44a36616af429b902b2c0e3e461a6cd492c69f0367446c9da40c3b09370b00f9c72048bae54d2b5300c5753c87389a2b65f81d636b5f9836751b7e34be400bc29df146bf35e8f78be6ef5219699d05886a315acd0c828cc63de998ca30c6fcdb285d05322c03e7d7f7a2a33ac2d7f53d2f063ab9a360511e721d47aec7e6ecd3ca3ffe28ed76bc7ddb89e0a64d3be9073b22654564acd9f9505e75c2728533a9671a127113cc9256b1557a26b7173d614d5144f6f66157bc2ec287672b10b1d3122f1f028a79bf6d4e74c7d426d2dca4e086de05401b0a9c8ad7f15202132b1761682ec6ab4a0264ad49e5c74146d40d4b92880173d9576243f578c641d63289eeeb22eb9e12eea32552d3ec026e0e7d89035155b8d5e47d7b607eb2fb2bfca7fea2c81ec52f1182cb1421d057a9079a420ea274a93c7b6fafdd1d7dcc886e4c8c3479515faf485a07082d5780992f524a3a674ff01523ac6010c453978eeb06417df9c72f486cfe88e826ff24ba2738c39d218b395ee884b772e14aef9bd615bee5cc1e9e8cfa7b4b627367733e755c44ed69e2321107fb97c68b39bbd40e54bced37b16655271c9a6d575e433156ab80f9e2be2d1d1f55ad959d87dd4bbb1c33140088f927382363dfa681710517d850a1171589da3b5df4b691404f733070420c7e9bce730cedbec68f032d352d868a815ed7ac43ee5b26e0189f62aa67989423d8c0bb8240398fef46469b9d016e3642f6a976ebacc63a2b6de541638d8ee5ee16777f78a7b62ceee5e71277752faf85a78c82f9b38a0274678964e9f056eb843e9bd5b06c50c8236c71f19ee0dccb07b2cd311affb8b83b2e4bd9a8ca6385a1494726986aaa51c2959e791f1720263a2e3e1fa9b26be238ebcd524fef1443a5874a3bf36369b7dca90f3969d70b869a6bd68374844880e5fb849704073d16c0877b35539f94e6cde74b351828d87eb4ad8dcda85cb84bdf3d8623fc6f8ec2a623c2df5025c666ef5c637f70b8ea471bad36d909d54676cfe99e56e500bd3c984463082ce1c58dc80aa7e577ec9ca3f9c73a0582f13ab5a86cef34fadd02fe0935667515a2a17bd6146f0fe878faf163c0172ff17f46eecc87192d23e961fb4b711da473a2166ffb21d49cb647a42bcb09d98cad42f628f4bddd12d09fc8731322b9f45c7700ca2897761e81f98d03823e4344bae104143574ca3ecef34f0d048f48ccf5889e0898df0527f9032b0a4d62c094f23fe38c78c9d0b9ff6a31c6a73cbb06f09e16d81b28e34703d869cd234532a4f90a91968560edf633de1ef7edfdc02157632debf0c71108713b30e143dac30d5ba72a55027b9721b7b04818d46dbacd8c6c9b2c53e3ab73f1fb2232118f5e5e35353bcf59647de5e41347aa9da68356a6df0ea20a50f236bbafc3eeb0421e2832e6de699a4287569517aab185b5dfa1502a5ddf6324e3428c90e97cc5c69f8ada10252c49671b277a116af7666f6c649570e6933f58211d8d7f50b91fbcdc36b0b84c89f42a7e47d68d612920c454053d4b48bea5f94481fe43476c61add25f8ea9ac634726360dba16e49f002fa64b70db2232dff0e020c940c441e659b9eaca5478fbe3345b2afc961b1418f01f84c61c24fff478abc556c8cf9182e7421ed7d5ba3e353770f60fe5d15c4839f671ed2c816194d64a588a24871a59e6a168a314b9d714db9310d6f99573a27c7a17be654ac317ecc9fd6ef11cf828a71c7b4e7f62d3398a759ea00f9dd82d94928da72cb5fab68da11c2d21e64d23f96d1834e0d0ce8f97aea3f24cd735903bbeae0cbc36d66e3ea96e7f028d066361c306aa914119015c316ab6617c0f932d881a518cc22c708cdb77157b96dea6e8935dd7243c271045fbee044ff88336d1059092067ea51342678ba9ad0c285de1165632fda90d50e1b7209c69d3c275404d3ba2177f6eb63e3fd5daa5fee0a7bc8ee9a1a54ba4d7eb2358a2048f8019c16bcd7578bbfa48488b59b8b87a188a0ced4358bcec8d86599d973899c02c7e16357dcee2d54f7aeeedef295685a3d2aa2bdd8dbb4eb3293755c3f02b6f76166dfa9d94157874a8c48243785c590303d3334a8841abb29f287841b2fa7cbc9ba280de3883246a91ddedd47c67b9d013424a055c0c24f28cfe6cdcaeccd56c5c744b812cc1ca50a6c27086ca610830def270da47468cbfb4c4d1f4260f208d36324787cdbf27a666009f760f4d36de1d9466dfec6052f80508e3fd17981a349b40e06ef05400250df235f6a9134a257937875bc11bd55f52dea1ccd927c51489ed4e8948ca5b86a8315e913a95b2492e725a029d69a13cb646b044006c93233672c9a586a803109b6d0d208cbf8def49d2897b03ed20428c4e2b803fa0cfa37d435d31aecb57737e76e4bb76679e4c7435d2302f77eac817650f735f069730d6cf2cc64c052ece401cd22eb4e24f2f122a6f0c16f56b95802d516a68a017cfe9d50d00fe396885d529006ccb32864d1a8b3041c149d3514a1800609f430caa7e3775e45f629b8a8b882a0a627b9a791ddd3376b499bc5edd20c2f73b3963876665434767afa375e1535699096bd9b63b31e43a846fccc5a99446c9259ae26cd2ab6d046f1b40f136ad4c9085c20323959c775c575ff12a1a7f3ea338f991e65822458955ac38f9bba68e34235e02db4c68dc73a70ccf4cff33636b02f34ac21025084bf42048332e1641a4c6b4b11caf4187808d510174c997261fdd06a5a8a0443051edcfa0428f94c32db3e7f89fb140aaaec66e2d2af45d4f7ef224d488cc488d17a16615d986c76682840f6b08bc44e66c60e8b0c75e4710ac75354783c554631a8a3e0607e090157e3a476069d920ce3440351e175b960f5d542362d11cc6f10be071d1b4ea4de1bc554402dd9c9af70e7265479ddee7aa94c8b97b7c424e666ce5235b519c478fb450819519c2f1f1054351eaf23edb19092dc5b96b674fe8ea22622481730f3d955183b5b66d663753c19d3182b72cb8344e63ddf0d4da719d3cbe513d6f13ca766982648ac48b669072157753abd61ff11ccaca0922c0fb28790db39378143cde2983d44479fb9c2fe50e87e83f11078ddd623f0694bd13708784bbfbfc46b46c17e0b5fe87c210bf3034dc3d1a9439ce9004019c138be7d6f8ec5bc010b4aa7cf01ecadcde2477964810d87c52c609a25bcc1001c0af10525f9654138dbdaf25b24a58a22219bcb2640f26cc4a507aa8024ab04de3a07f34032307e1b8d11224080724be7bf4cf855ae2a95e5a6701ad534149e920bff64a31043b415cbfa7470091a8105091065a4af8c7dcbe489b2de24858aaa9245d8b287309ef17f86b1e570cdcfb01c7ec82a2f61767d1c94e47c5f0bb2c7510063b63298a1e8457e5ac23ba3726d85015ae83ecbd60b1415e9c94dc46db990325e022cca6de063ea9215a053389d7b49b35276a49325269d0f94e96862821ca4c655977251fcd7fdf6ba895842c782c2c89addc2f89a5026bdbb9f48e23d942273621210fc2d5046a07c156120e6b04926d83b593e53469c61cb736e6259f95fc6576fc78722a05a1382c7be2df1fbc8bbf7f7237d0c775af540046d53ec7247c0de200c70150f7e7fd5127390442da085bf0367af3ee2f89142a561ea05d4775c4463d821d92ddcf3bdbe60cc776d97339e25dee77bbed116f4da22da6a26e30bdfaf36318b528263d71a2d07f1db31e18421c5d6a1f02c6ae4c4ee723489cee042e21ceae0c3b1da6acf9b2d3298ddb0335d2f75bd9593006f22131c6fcd30f57411c00f4fb95a6665edf27979c6e911387be4322767c88844b431f1120b5fcc595fcff81e5c92a3d1f8a1a64df3e82722c2530a8f817d481d231590ffacd4420607df6ca37fad9196846ea5b51d62f8a9637c40ad852b5eabc1aaabe12a23988161c0ff30bb25851089d8641f11efd7e8e7146030800a750badb7e4ae18910b9c796c1039d656c806fb38b0a3477da4940519c800c473b1dabf5a9957cf236f97eee1fdc002700779783379cb577c7cb3b030cb9e56dc00fb7e7c265317d7e96533ba78c01b4544c1e7171b9758e2a465950559ac6e902574571b553e8c0033933e7750bab6e785ad66290e0699cecd744f86cc1e3a28a2a3f6e6abb557cec7613cc49c33ff13a82b127e2865005563a44dce0a2a114d523f24f03f4b372ca2c40f5203f5858a9d3bc6e97b31600ec94898bd3bbc39d76dc8ee513aa7588ee3b152790822963a341285685c9c8cd095020c74ff3d1378ff9ec6e52d80947f723b438012d01590c2d897dfd5cb778ee793dc5ca7d7e6e44da4c0d9eb2f5a5d6f376081cff9ba45175677dab13255a6c0498c3320b53353ad4c9a4e18972ab2831e9ad7b4608657b1add140a8aafa3d4c923c04558e1e30e362219faa771a5592e01c68b0aa4149cd86873a8805a38f69008f1747e6ca3b6589d5ca524ae4ab40971520ad293c96e01ef592188f2ab977f674cd1917d30e911411ef7aeddd3732fe53c5bc49b72d90cbc09f3fd116e11438e061500c0abf121c5926f3b7f209d86f4dea6553c5692fa0b903074b9829b1ba0d1261ce7a7bd9fbcfe69521f1208d3d313130b21bb95cd5965dbbf549d39079973a237cc393218359cac66a14eb71c414d47587a4d8ee6930bdad911a3a2e72beba01293ae3781f4fa442d440edaf36a75999aa8373e565d65488e42e2f536031caf9e90a05aff63a621e4ae4e7c41aa42561db13cc50b353bc08d8b1625d33e46e6325b3da2058a3b98eee5e0566518a793842f2665cac31f32e523728a45c62cd19012c11b8877d84a0a6cdb0e74dafb450ae330a2317d174bfccfeae03fd09aa4e264f31df64d28dda21578ca331bf8738682faea06b7d45fc36bad03f6d4f0dbfd44d0697933e5577d1ba6e4537a7e6b7a89979c155b01bd8dce5867e287c4c988ea7d748e11df60c9c40e5bca48794f546268fa8ed0b068b197badd674c75db7d335694736869e557a6591859039cf1bcdb35a2f3239c29c3818457d8308a623260e56370861c5d1f91b7cffb07648ed4b3b5d51c3115e4771725986c33512f16735a5d6da85a040cacb2e84147c8af0e3c800fc722864991ad49259432d75e0d729a9587a681ef98d242b4db20bd95df1f3c079d4c98c05958f809cb3fe9d9e487c68edece4c489b6f2aa1887976fade781c44236e1d71de5cf59a64bc8f483384264f9ca1697dc5454c027811d29ae28618af915b62b2ac280d8ae5705d879103afbf99e0a86bf24f0ce7798d61d7efe5ec7a26cc95d0264e6f24300c491c89cbb52b144d873072fa34270c1aa25d3d7b4e2c4520587d9ed06126198fbe09fc6d32ff3f786ad29a4094c015270f10fb78cd4c4646cf851f903162e8608b69dad535a02040e933b1676c64d675c64f21e70428cbe12c06be37838bca025caf060850b217c46efc0f86c9a8478af759f71cd7ec9d5b51060d755c63e8e1761fc1feeff4ef3c93108d3666900ca89856d0c8170045850dda988b1122a50e50e5dd94cf39a98d28dc133457a230414d86c91824a4423498512fa1e9dbfb1dd1467eafcee2078e5189c4c2c131d3c7046eb1777f574ca7660a84a895625edcd856bf7adc61de7ee5806d28a399d54310f33a8acfd6ffcaa719fe13949f2b2af71f2df36043920a3abe327558193ae4022f196e26dd89ba84ca78d7b29e2487bed123cf01f32e9b392731cd0af8bc7735e481f670ee52c263362a687f60ec00dcf561020bc3fccb073de519e08e5c297242d6bf7f9ee3fa434ed0269f7ebab64e0a69c72e693e48204ff1f3e55ad59cacaa88f7cbd226fe11796217ea9eeceb06205cce67c2d12bb05ca7c6eb97d46c743d4a6bb44e4b891c5c32144610dff67612ead7ba95aa5e9f25d5b32b3c55197abb85bae026bf2a252ac28b79eecfe6096b08acf263def8fae9e39902b6412e5bcb3d5026d78d6c28a9823fea6f3b4c30f3b862c6c9ff50686b06c23d6f72f17a17d3735a0a602976856b086f53ca34353ae9e4bb0cc4e4a153e318ff55ca27c7219f7ac44db6f2906d88f3fdc382f4711c6f40dcf25a4e4dac4d6f6b1c809546c234352bd805bd5cb222e031824e07913aadccfb5737630d89c8c78d0ff87abdca010fa12ef0bfb431563d8f582bcb6c3a809af0d6f8a492e84056787288dc7f5f1c3e50b0ed1847cb7ae2ac003027e04d88047720076c46f32e11259137838f68bfc98c55637617a6f6b4aa570c0f182852f01be59242f525a1eb54f922e38695a99fef75a40c7f1140b6eb9665d30c3dff2a948882ac700c83669d8c2cfea21fda7fc2582829ebe923a810a8627b7cc7962eacb7048f2051344e2e656e357d4992d095e60ea0a52e7b4039e535bece44a7b42830b45468752db46c0ffc7250a71b8c26581bc3c89f9f4ede2b8843847a8e64e504352f117f026a5561340765a7901a71221d02bb3fd4c64a65c6200c408ae71e751b924bb92d5482375264e8ef531ae536cffc09c4d2fb3bdd1a2d727e8aa5c428ff47f69eeeb22b65820d1980ea8acf7b479e20747cb207c2a3b64ee49982346200461b8280b5bd1b0f9510214348582ad93b821f6dd69451c41356c323e9b75ea2b891071e1a858beb05e6e7658101b743013801297888ff787758c0adf91a5c3b4767ae292d5673c75a418c07ad272457b4f4740e103e9778bd15bd741511526fe62e28f6e0965b50a829bda3d69a6d4bdf318987a8fa66c76cd228d2e540dd5c4741a095d5b02a417fb22d7ca4292f544243fea08c42567772c28485b514a16c2077a4b9c81df7a8c57497e01cc5291fe29e05f2a640a03262920b5f2870432dde660c4d99f10a2f94b640c972c8c5cf27d4053062884958f496638de088513398203964fe12b51a08ead32600d9e02e4f50b177073b25152e53c876add683812f6ba6cc44c87807939f048baa221d200735c02acdd02c58579a01e5e3bef97306c4b79bc58eab3cb12b513791822ef92b84211318c1566f553f41fd7108b495d87a9eac0817ab9a34f3fd7f1bf94f14ee0a834d0c01340af85086367af9b47d4f0b0c8a784edf9dd8de2e697a7363d4d925402b43ad4ab08a619f6317e666d504fe06a2622f3fe449cb6cff387e49f59c641d7aae56cd5025246d896958951e4ff1ac80e83f35623d37ed0c517612be47d96f1005b21e4b680a6d6dd17492587add0c634f0e67488e10c5edb30abf2eb7015daa3fbccb94d8d81973174ff86760dd78b47bfc3a957977c3a7b39ce558e2353183a50bf9eb72802f3de1c06a7504608a4cdc8f8bedc3291ec6152cbb71603d0155684e29a02d218925086c97ea100e5c280458e9193dd949230f5d4d081fac95e9d0d62a7916e8e271dca11e41485e6aead38da1b65766d3d312fdceeb28c6fcda1142a1f7025697f436fe71919bc47b9e6e91723b6096b4833510431143cabbbc579500ac15ac664ab0d6cf3b43ca2a8d4c086d50b9ac8ba65b5caa0300aa23851c8498471038afa8eed0f78acc1dcae0ff851e530ae22cd32580d46c1d26a3e09deb6ec72aef402e643f63fe0e6054d0c8f413c9ba1a209ce7cac41a742244785f58f30f40edc3180cd98d8136d3e816aa4209d2d46d9edaf44736f1bee359fc8ad2f47913fa4c76dbe689f5d301211b528c0e8b364a790039c228828df3eb460a982b5093f1f47e5f4090a0dd1150440a2f26b63562c8da0f0dfaf186c8b7f7868189726584eb56f0171e1d4556d209b84360e97fd7240caf04885e2746215c7a09b157a0cc8cee307bd4db08ddb649dc1e8f27e3b81bf5d42865ff07fe31f1f4230c11f4d1bd065f1f9f2de940594cebae04412500906897d400312b36f1145f372e23175646693bfede6891f9816c10c2cc122219fa35877b28bf9b92db5f4d77f1639cd12fe69dab78f3b7c52b83b6131daddbf204978b220001590833aa0744408b3b1092c12aec207b35fb49b5dd9eab616093d709a4280510b3bd5b3eb02d8b5d5d75507a33d981cee236ded3df00a67e0bb2b56512b5e0e8b848a81e34547675a0bc88bde54bacd38062981339358f5d3b43e02a5e6bc004813b2c5baedf4449b2f7ccaa56c40889d1656f214b62d79feb3638b936315857dc31aeb6f794a93765dbe470179e4f1e17f0f452540dff1538b0409bdfa08197c51a92418c91c86c097f50b3b4981e293893b82a8fcd4c1e3a693c057f480f40ebbb8e0e5bbe72e07cf8d70d1966672560c79b9362312ac623b859f7c7e6fc3c680808d344c82946e1390c3f94d234451a936954db84095cad206d7a781a89c8fd6b49dba45fc32e09d5705717a8d1970f22cf3b772f4e87bcf483af6f25200a0b6e6bb250ccff9fc4c03aba70351910fd5b42dd293e999c0d3d514a698b27fbd689a62411a68d10255931f0bf940fbb62746ff45ee238a300d02fb11e2b85266122237119c0c4b37f18021f015eb2d6fbd6e58cd3de1ad5d8156c4692fd01132389a3df001b6200eee64b43dadb077fc8b0f8ce3d714cc26a764f8b7a3d8c30ea04bef18ab8f6189687f6e589ecab22b9f0349a61ff695555571a8de1eb2cc07ee3729e393f83c4171030d7321b65e80ea3cf71a1c7740b20400ba51c1ad3b3f122a4f83cbb1021d1846ca5c059477d89feb81d55dc74d389b4b7abd76d56cae32a9506c1198a8fe2a168ce27069d16a0105b19b226404ca39010dfa5da48e4b2ee27545c288d96ed643118a6b0916e459889d14a2105bd6ee75c65dc7c80b072f989e913ee159625eb230b2b30bdcf153092654f06693475ff7bb51d5906b3f9ecb74cc67f46047f98baa8b44a7542ddf776988762a6d66abfbc8dbeff6c3314eaeb9ac9d12971d92a689d58e8fdb0f93b395008433ffc876fa4ab638b874e8d404867da41955b068b59f990f265bfce2466899584d147bb16b96aa568e3ff2efec3ca73a8d27db14142d66577e4a0cf79dd634281bdbc9199e303b374ec928beae8d162c9c81ee96ddd9e5ac6ab35f88c46fb0753e7658b17253ad62039c6f843b0dad17eccc6b7bdbe6e7b8e5ed9a717b9c8c673e9370d21903f4921b85e982afe49396e5bc35686eb499d99cedb4becbfab9442baa14d200f6e8e7977a6db458b86eb143a55772a9a13856371a73b8fc846622ddd61d4cb4fb18d4546665692c91697b9719f22e9ee7d08119f76dd3267b8b9337e836e31894a07bc41ff9a84739a00f8cf91b51504ce4d6e538a214566a8ff2dfd355433fb7f1732c358a4409d01441dca68362e22a257ba5d723f7cd04669c09b47633c8b25ba49d3bb5f0b8f233ebb875999759aa1908368a33d068415394fa2e3481119c00506dd26e8b4e1c6d3177e4c3e75e14193bf933887d798a02219676bd71429bc1d10e176765f71cadd8e0fa549daab12193139a263aba7f24beb642d7b1002c13a759c30840978c4ba097c62331d61b281db82f2eeb29b92c0992cab28bfa9be1d52ce87ec06ef848f6943b6d2b7f872d19753adfbbbe95037d2d4d057872be6993884a612d24eac7fd854ea7e87548e05b595085942e0281cde4194c39d88d7f681dab247acf6d412885346f4707ccf2c5dcdf7bedf5dd002c03001d3bb957538db3ea7fbc793ba2cd37482bbbc3466aaf1344226fa3799515777dc0225e1fbb54e22d921ec33654102ac1e8a2db9b7bb4f745c317ea8bb296889d75e19692f86b76ee90bb266d89a2c09fb02520a1c581378226878b1474f50660f78c3eeaf3c260a4b3f30c2c23f38a1ae8a8ac7ca9222b417a796a021582890c817ef97ab63fbe5466255a0c3f1b684f8fccc7e6eb3c47a435fb8d1cc817421557bd5331a2862134aa7dabdf5e72c4f595aaba36d8447ba617722ec28f9484738ce3f3ff8c3543c9df0120c37f9d303181550530b6d36cd7ba0b719dc0eb47ad0c4c9f2cbfc1aef7b96e80d215f4426b34f6b2ffe33bc2a1ec878d5cedbca4060e06db58c129fb3798ca7ee07dee4914667374f93813afff3f772b6249bd649b781d2941f049832e3771fda8c5fe1d0c891c991778f63a7747cb88b3e05b8b884828885440f2cb7ab021d330bc4d4d0d96ba6e470bf7318e6e6157e1b3addeb2eab7e6b2299743fad1cfcf03fdf026213ce48fac7f91693d229e64f103702f3b1b62a033a274b08c765d8c3791dd4db8f04022f28f57ef4cd9bc71616db93d1d07d7207d3cfa3c83a873491095ba3acbe5da1a05d3cc29f254508ceb6476a4a1bdceeff6ae9f9f31450afa97f31667e1004329f9a9666ede9e806caa4ca1efb2351f7a1af6b378ba37507111c56c2e4d76b5aedcf944b9b6bb6fb793aeb088513836d475a20fc2ef361a1280e1079d5747027a5efc5d623941d4fd8d3579cb17dc42f13e538f5645608cf85ee5895c195325e247e5824e31ec5f83fd6d5b868036bcbf4f2c24be4100cde8178eaa66a034a357c9a1920bc1d70b238ed62e33cf0e37f42a49b8b2f9752433711d94a3e6ecf9dcea9b7c8d4ddb7a7c0058ae04bc61bfbf7a05bc7acfc1823d559be4dd06428cae8cd392eacb5896f2a6a4100b3012a8ae9f4f400cd1c88a02c68eb916021891d882afe5e623dc27fe1abd55d1c30f901e40019d65bc9325c10ada4dfddf4b59dc19731f2a0aae1385ac302c8f5f65aa73bf7a4582881b3d27b467d367ca2530b40864f471b57d13809a7dbeee4461033bc99819a926a084b735c70369f9e61dd347c97a931fa5167c3d51700d7bd79ad25681cf152ab9668dc982309076927a1f85e08e6f551a3f89c10add3602bb2f5e19a12321a0f204f7bb8d8ac5a3be4eabaf01cee1f687a29b7fe33e84436926005e4dc311ab8a44e581cef9c88638d5fb11274d8b1ef1e6e9064f409ac0b992d31e99d324031e09a1cd0f82855921d2d2881f0f5a4207748d10a403a04d465c008856251c91b0f3af112b6afba0332f621c6d25934a273234057948019dad33947af6d962e226857644bba37e0c03151cd3aa38293aa3ace9e2a9bdd16469e5634a4fd987f30612ae45d6a067edf7e51e56f10016a4752208096722e8fe6dcac78f34a975250869359c87ca8eca7d230b01e659769afe11d4fcbe4c964269734cd7da3598e3fa6f42303b19c450f983d1b973ecf774aff043864df2a2d2b31d160b93824443e4907bd8ca5c3f07c7912101510bf13b734a58d86887ea95b5b9baa27c38c487151b07d3381db4c56fe65b49abc9cc76db119fca588c8ece62a6aa28b00273867918bffb8796bcf3f0884287d8d7830e4c3662ac45c1823f34c4e5bfe6a98184e378fa9153b1665be9e9f0fbc610e34754aaf5c86a9f03798e2487d0c61a53413e0dc849a0080dce9ec665a04b63152adf34737d9d3e6d4c582d593dfe9c2d3ace9634555f339d3ee17ae4e295224c6f1643bd99d04eb33ac7416d041e9a496491c241ea668a806534e925a33f199a5cbf83392f4deffa37239ca8e07c7f171358415640ea4683fb80cfde05c6f30f3e8f9d2f15b8c3a0e0ca3b73f95bda3705858bcb4947686fc51c2fae87bee5726642c8b1a8154990961250b6cee87f9eb1a32b3657cb5ceff8048d9bfdd0a502ca5271c0c56e3b237a782496ba620809eb15efa34e0afe524a1a0b56db7c58d066974df6c1dd24a23b4a0a48bff6a10592abc339644316129611fe9c49c0f751c44f88195fff0353d69731c0a444e4aa0f7ee350e1fa18f12e575978e25beee04c2b042a0ea206ef51fbf0cc707e40a904a83e2a19c8904d3d8bea774934f138f720bd88871ced7fe8a1811a68d8df742a608849aab7fd90b95eb8a6970698430a3c720e05a2fd3b174cb6345ccbff282d7da3356d364ea437f859c959b9d10639221c6133c94dd357d45080d9645b1e804ac5fc24e751e624dd233eafd9a4bd46e45faac314e108ec77b940bca00be9caad4671107c91883dc79078ed9d242214bd5696484d8786fa7bb4b303263b8953a8686a2c1f07f9e306d844a4afe6c245fac954f8d667a09b1026cd8d67af985fbc8f969efa19f0b666fca97553a335a06e12df3b583f21b8583a9a79e8372e1a40c805c70fa402573beb132faae42ca492d80fc1257952c24ff524025716a9dd5461c89af73c9bbcec7ecdb7b990a85489c9d9960c7bccd8e745b880cc709e7687027cbf02702dab7260000df6df86ca3314693964a7147de667560bb3db2656ccb2cd1b7493220a9488305617330ccad252db6eb094b581c2a69c06cd773c3c611a33ce5bfbda061378a657d1f6c31a2bd1f6092ee403156ffbb3334cd49a67e47a5ac9b8b751f2592ebe512c3da705d99840d246dae7bce7d8154c2f35f9483d0e0939d1b4ced99b6a47afbd99a0d3c4a6036e7af1de05b4f4d2d1b32cb7c45d198aad21d3fc484e2c0307b89b8628dee366ba2e96b0c2a1f580a38255c17192792aba80badf7e978e30e42b346e8cc93474df35e2d0319199c0200e2f0c168ad9803aa83408ffd9c458802d226956c41913c17490fc5003e00e67925de798b0cda8d5eed7431f7535d0f1d0f052c5841f13396998c49a48a37dd00a4dd03a4d29561f9b311f436fa1e5740ec6ba106f1631d0e652278cac462e6afe78082a2d18d0109b926633c410153e54eb9beb1a1ad23cf6f1e577ac8f1b3546bea0c6d0d01cdb98cde4e356ca1cc2d0d0f897978c6d1a91fd319ed55d914169d32c343406945bf228ba2ffe2c0c7ca5f888b19f9742435946d01731c45944dc6d2c665625f0d6587ad2de39716aa244fccb73369412bcad4ccec3237ad9d0aa63009eee0c9b5a0f334eb31d73e415be6455d70917d28b6dd632fa973a1a9c63df2d45ecf2c4a921ffbd9b4235e441a568c8abe79927889bcf7e7ee417b2f23d3c98eaf770ea9cae755ab006cfada004af056026f401e18ab5b5937f0034641c92b417f59c627ccf2539f2bf5c4064767ab39ed6c01dcdf8594085856064481b430f8b2cc1c3d167ec61f22cbba8890d5f17baf63bcbdc505776797c635953dfb126624cc7a9ddffd784963de0f4f3b300ae5728085a8e8f2c2ef9618598eeb1b8daf5b31e6eb67eaa46f1521e250257b1e3188758b78a21f7f1144943b7e4aee978bfb1dc28a95ea03b6321a0a0e6b5f53cd1d10527d4176cf93525085e97427478cb5ee6abb5d6238462df3a2041b9aec01d99f20219a8f00b011409ca22a7909f239b1da1580b6edf8571af32ef8874c0a3780302b83c41f7ed57e30c5828bcf4bd04b8d9b293a31cbdf05516803134eecbc0df37d697382baaf8c66f9cb06621c23da3ccd14edd41428af45302d0a0ca353fd16f30f8f318c0fce43a6bdfee2c330f8ff0a80b91f3273e37b6484baf67a1a3945a394b944f3d165931ea5a4858c560800af2eedd82e9c3812977377c6c6339bad9351e3877cb5864743b44befb2a1a98708016247f8174b1413d82efe76f887630f660ac3039f4101458cd25b5c6a05e7bf31024c78d36f3ca53b5c91f672a964956960c775e80228c81e73171e5ca34c2cfb15d98f78b270a93b82191a0ac5482d882884c4eab21ee7f5a3f3158fcf6df191a93ce10bab165b5cd33eef7b3675ff2b2262ac5f2fc9dfaa9f5846e0a1c8eb23ffda8e459860426f1ee2c49a5f4d14b62d80d48d6400e6a42fef3c77862148924258fdb7fa4b0be1dffcf25cc8ba475c7d3a78f051c20350c4be802608ca1d4fe8afa390bf45e03bb94846786e42e03ccc7b7f842cca21545df417eba1e7469273ae38c4e2117f81f772d1acb24c4acf0c707a600654b21d96f9ee1cd82577d650c46b2fc243fc8a92e9c4377f25c8256b981afc17281a2d977578fd6e7e5ad2d5567b2464996508dea7544578541efe250c95fddbf958a373b80c57eb1d04fcb13b14cfb3b5b8bdf76e83713d1a4c320406af41fff1ee23e906deaa6c0041f1d9adf5fb1bb56237f607866b7345c6557bc119774f7dddd676aa0b1efa4a5ba8f10d7b6741c67311991d239e2318db93651af27e587d3f5604f5a0675d24b71e931b531c7245fe27d248d5d5ae8a9a64d62b341b039f90ad395a99f7f014a3daf22f6b0d24c1a38686a055dcf94b2d8572cf6d382444cd31ea8af32c1bb011a98b8b69df8cd243511310e481bfdffdf59dc9b4013ce32b72a29497f527c0be9b2393813e7b55cc0f5a1d3f9037950fbc53af8b0c185c411f5f880e0deaa51287a719fa18b82bfec6be3c1af461ac16f981cfe7ca86c60f8110e3ea286fc0da5dcf294058f73e5e3620cf552eb074a766e2b054493d12341c299afac1e4037213af44a8eb785b2b4bcf3e081c49b9685d3e7e0c0b7d9f4bb50861e4e97a83216cd1ead54f12f894667136d05abcaf09dbab318ff0904bc0368e3805ac82d7df57b57a76ad048f8a5c11c11c23048cb810c0515f63d8e3b960a64fc4d09f8a491301f0eab4cfcc505a86df794c892c095af8148d84b48d4635bf7405dd5ae9f35fba1de27fc18209f8b924e0d9be53e172ae94aca3bb26dc07f650c12614c479b1163dda2d08625c1881272be2a36c6e63b6412a67d85d9452e5a126c1f46d699b1b1753ea684cdc30a4777a4e520ff0610cfc484ff24f4d8c29219f33f660737182befa6e623963890ff53ca1e3689e9a0509311ac7ad383a17f95a6343234573f5c62970c9c3fb948fea27f995fffc4e162b55896ed0526e9fe392c077da2082c68fef00e433168ae3ae8fb6109908f0ac9b6fcd409d415e45375f0e6213e16533d626911fb7b5360c10e328c04423a2ab6c106f94ae59e35bea3903e235a29f4f10cd642ba33b09bc7a88e4903ab6157cac5b255e161c43f252ea6d26453128a18f4cfdf3b68e8e7cd61abba085f7c9d99c20f4b9116992f3eb36331f599f6845c4a8825e3d8002c33164799075bc1f9f3373ff49771179ab89fc7aa56cc60af0d474390761114c38d71870fed3fb9462bd63c736966c78b45263d7d26e17981df2e1baaba9dda2b24d2bd5591fcf2892f9984d128084fca1475467d2d1da996848948c52f8e7de949b9e03cc46612ed03d1dae1c704d17998771ce7af4ef8fd1188882497323dae7136732c6332217bea2bf2481ea3b4e8a7cc0596333c5a5a274e3f9e29096d3ab72b3fa231d8415b2d65cf362ea20bf43e3141e62f7c3312b119d79d365a93cde83494ef914afe180b7178864592e3fb6dfbeec3fac5b8bf680ab6edf411335a55e939597d0692c0bee89402384896516361ed06470a3e325e9d9a4279a1cfaf0652067a2d413f0471c4220c5cf8e8291fe8369f6ec633c9f7d9477b07aa6a7a10bd1da89565df506f25718716080a2a123678bd00e1557fce34d72793f8d1885c05f00ced1cea309cc8f0c69e8003675230a0ff32a552f8270cf5dc81afbb35ecb5274655790030677e8dc96474a0ba38e6661b573a873f4b0d7d4f75b9cca52cf29005222cc8211e194710899691afbc33017e9d5948c1cad5592f100ef1c603d7aab6c80e486f191795922c5cd3ba61dfe254adb74e76fff95c03f6d2e423a9c62298941ba8c1a2a42a1411005f574783983b6fb1ec8758318f35588fa83e8dcb112ad1558838ee0693c06bcbb1a7ee5461f882c292bc6f415ef068a64a889c1802f195fb3db1526494436142a5d3d894e606c4c33917721928001a5ec743fd55714cd366a71774b0df8211fde296c86eb9d174b1347cd51ed7fa73309e72edd4a93e3502cf31b1bd00a71e6a0af65dc8e4030e7d4a6ee469a0c67a9bcb2e24873e972ddbea021d65ee11a67cd296a4e365a0fd13e1ded90f219181ad20ea7d3ee2b6e773fee709439beefd52efff063776bf24e57f1cb9e92edb54a8bf904b46f70efacf844c4415ecc7413bf5711a41c1e12f9044b6a882f900facd184f0abae86dfd84de4169f4c508162492d16d858ffee2df7f7c4bc6ab0b45874c700c4636e706a283db902128d610e55e1dd3c41c694bdc988cdbb592f6445495c64cff52e3e37235c3de85204f6775c82a0810f39b0968993e4b7b70480754cccf08ce92770d60062cd4fd68c0dda4472beaf89fb2cbae928892146d4643b8fa367f503ccbc0301a83c190aca98f5c878fac41bd25c9149e0cb4c2b6247dcf99f859d307ed7bd2af9f3988b1079b751967558c42ef424eeeee43e5439a00d16aa98f9a727c699f033a7cb2618be02738c043186eea545597050865c060f5b0a154e494974daaaf0daa8ac4c2cfe1dda1074565c41412902e8546d9e752d4c352a0b4b5d1f4ac3292b687153ad9fcc93b2c3035532c26a96b2a7e69c5f982dbfdc2655cb3cd1f889a2a08bbf883980fc41b454b33572fdbd6d9ef24cb080a03f8bb92a150f9a53c12f4b393051e0516cf233cb9583abe0d26385acbd5bc1e9c67755112a739b9534f4c00c9a55c6aef0621824767528b11e3c066c9adb185efe676fb347c2a860ebe8e58af54d300a9b304d17b38fa486ba36bb7b61cdd655091451bf55d2143e1ec897cb62a5d4a3456361824e428517f5af97a77f69e580dfe6b82842fb89d0c49bd3c5f36922ea7c890c55de4faf2e7c02282c159d5734bdc4c45a84f292c721f2f36461b9d5ef6c107663cf30426d4d1f3160d3f86e101dc7f1642b7b092e4c2ad91c7b8408935282197bf974c975d201e95b79634e5c33864eb958273f781cbc5c6a11fccbd9a306e048c6d425338965f9728ef992a969720747325af16b48884f3a87aaf8d438ac9bd906e97b82954ace7e2ba378db35179f949bb09854e7705fa1fda630ce122e880b457c68670172050ea4ca02f2be8743135c77d9e740bd26194ea78885476dd6ee42125b30eea87102aeb10c3841073436a7d1402c69206f4f0802f9baa8bd67f39d0c27de9db3a5089818a9d2fddb2c348a2232dbf7daab43bf5cfe4d2f73f32a2ed5c5fd29e4a36a25c8eb6d07421c6de2a7f485b98f9baa861050cd7ccbb541368f73668e93208312138a528bb2336d5671a429747517c712e452e0cac4c18d9503b5718c8d97d6eb3a5b8e5923ba106039bf4dde3ebf2a01879ee3b668d9e11ca3851ae06bbcc74802c2393c0c7996907342b4ef20606cb52a39cf591b3fe72d67a34fb3f681de528ed701f8a40e0359db72be58f12c337f8bc7135ad3f3f15385a6148d2255d7a1e5af3c5387d494c6b97772bc9a7b974c46576719db46d5e8ba12e6c15fb3e4294428170d9e4866331eca07f2872ae69ecccc33456ac6855200a7173fb0aa4fa828066652ac1827ea4810e6d5daa94aa30e134cb9c841e6d85d961c2d86c38019dac91487936f77e5658c3234b54addab6502b8870e91df3b38a00b3e41417f55f49b9a956ebc265b5722dd684eeadb3ba279d0222b78964d9e685846ea4a80ef7d10f575c8ce21b51a29e81aed1a935341ad84cf4ea799281e035fb2f6e81ea599950509d224b8ff372d1997cef86eae563bb0a3d887a737045930675553f9200e48c9dac89d21c1a154bbbf54cb9703f29899032d6516e9dcaaca79c75d2dc761816fbb6875ab6c22fb79b9917451dd6bf9ebf0ca8ed822489056a3befa110cd8f5c95225395cbf0157bead8683939f48131e5e76ee3528a20d8323ae619288b8d77dea8b9964b1c1b92d2c49c459614ad50190616339b8281391a5b6bee82f2f8d098c9bbbcd9947caf711366e345c126f6a2ed9852eea45175ce0c0c07d089e70b7d8ccd3fba09f3363311ed55904aeeddef3f00dc3352bd18e24c433ec658dbd02f3a013893885adf7b96b4e1d899bcc91e0806790dd4978d8c59db5d075f40e5744f576255bd7816d8217cfb58c35e4a16f4b1018d528fb3468b5f4163969c78f45a0d2d5a32a281fe9c492870eea5cbc3d9d5f151380e46a383add0c5cf1ea679fd026ee68f42dbbc53d973cdcd530cb381aaa910daee7822e423564a6a757f0160745033b92854ed4133523be8d1683d369b6d980fc590606b3ec3a3b201e6fa64b4b1e02d3d2097291e0f54b4a059519a7b1a4347a3cb4e288f8125d357dae726638b95d4136e5222ed1cfd3fd5c62329f48a0fea5a1553a2b14cba21f55dc969ad86f1d28246d2945c719acf5c590412df332ee4e4fa1dbf6075c46b058f1cd5d873c67333c12c91662062fe879d6aa0e4fe330ef1ed06c92e7a9ed6f74d8d704b79fd37f9343e76962267ce9b014d51604557c3cf429fb43690f4891801fbb738a2901c86a64fbbb08825c7986052786786dd5d414c32861f2ae4ec2e0d0438c6a146764632a3dd25e4e3791f9b3d1e35ae7f4ad6cd17f0e004475781549a9c971954390f3ef0b7d310ded069e6896381ee5dd8183f9d69adce7f222380d918fd70435e5088df77150ac73d820c7d353b6a9f9a8d2a53793063242643a17385555e0eb9163b147fc9be7e208fbed7406b155c4336afc7dcc7a671a89b7daebb6a8574a95e3af8d73b7ddd688df10d0c284a0afe6a64299ffca6beda704ccbd12b24b6176eb888cecf2219c7b0c04b495b334cbb7fb2d82648229856f71419bc62f494d51b6dc9937caa690394fe598f3182d11fbb527e12b1a8017aa004f64ad4dd2f9721d88a2493abf35f94b65d025107d0d1c7a466a08e90ceac13eabee18337a8869507fd1146680ae5c66162aaf64134957c7592c485eec09a15fb31a56a6ce48c54daaf542b2878383b7687b2e63a7f411eb805d1700bfc56d072c9a651448073615590c70eaacdfe158067512cc79e6e3261eb13d55663b82b65b18282c8508dadc1b36776b196890e47cda38bd521ef61fbcaf201f432218df35bbdca3be2280dca04fbc575b5fec3bfb4e45505e6f4e03dc5a2295f2cfdd929619c3a80a92d3ca9e799cdcc6ddc2bba412c43c568aefe0909857824b6176f8728627b898e99b1683b124c65c82bed4cf8e5f177a87ad263861a0ace1efa56d171ec5c5bab5a7d70b4b1e609e70733ff1a72eaf1516202ebbb2517c1ca2a5c44f9f7e72282127882a977cf64faec89a235592698c73bf6dd6afda36cc6f5a9f31220518e956b3d3ced3f35157854c4925006d22bb394e17ac656609acf1f69b0e8c6ca12d63b580cf1336f733e34ce992a713ecfa3184e506c80be221e500c383112008750e509a883d70e0875aefb2029db9689a9048ab9bd9a1cf5955682669f85e164ece85ea1b3296e62edd4f22654fb26bb4758339b66f242faf49621dbb644b5a6399ca344099d9fa48e17aa0bbabc6f9f2c6dd1147dbfc777f53df961eed49ddf126583585efe9023743f14232b1347a183dd76f3a45c5b0afd89896bb12d5b702ebd31061572c10f894cde200b654171027b610c193ebd95e82565b5538bc00f69769f409b40709f969a6530d984e5ea22e0f689912b09cd6f796954e15e4e91fe09a862fb2d35fc38a34dbaa978511e74d0a26011b121c07ff2dc1172a23ddbb6303233f2ab7cd7749f54ff2723673d173225d4daaa092af0b4158830397061b2b27565e1ea7fe2dd456994f32f5690afee26390ebdf8dd67776d0b53b4634bf81e2fe734580efaf1b8e96d5dfcfc51862e12273270167a2c6a8ddf808f4f8459eeb8c0dabf70f39e347a38a943e073375aa435a8b6e69bfbee85320a82952e32d3839f56d31d647bde2c52422dbbcafd0d416c3a80956b1a946dee704085f4266b0a1ba43d043a1a1f9a5a305c15351d9981a263f758ddd46dd4f5f7dad545b35ba6d52a844a7eed36a439734fa8ac5fbd02c2071e99211c00030b60ca0084d1bdee9c330ad85c00f4001e6d6bf884261f632ffa08f661bf35db96969a889051237bcbbd777309f508dd0914239d623b3a15fde41487a563d4bbbd77637b775defcdfd60c3180cb3d664fa51287aaf77d7bb1b932fd5c5342a7805bf53d74d267b8750f94ad783e8dbe5556f5dfeba3eba4eba56377bbb6b92e3e17615c3ac35997e14eabadbbbed9aecee8750c117c7a651c138f6e7d5d464abf295df2136bc826d64fb9b7cddb03b664366d1adf683e817ee21fa867b8c7ebdbb3e62f2752ac2a347f96b4423a625d2e57997bd2eefca7e5d5e67afeb9862ec2a81bdbe1bdac8df65c3dc1f3f44895e5f595c9c9edecaf920f27e9663ef2af8266fdfede554e075f1a86511fd3159723ea8264ab668717c1aec42e52d4ec3f2abb46039b6d1295a5bb438cdca555ae0d8a92156b00a8ee91475717f69bcbe2a6f7ae9d977baa961ee53b2c6a12a571c62217682435b42e17bbded1db9fbb7b82c5fb9f82ad7050f5c02eacaf18750b98b3777cab1727c1a95bb68f17b9a16bf2dee7f4fc3f216bf1f82a5850b7c67963ec48902c22e30feca695c541bfe62081bf00b5c6f8bdfe4ebe2aa1cdf95c764adebb29925d75d931c0faa99f9af7c0896ab5c72a71cffca698e574ec382af72161617c72c180fe102636c3b557f9323e7ddff342dce72f1f1102d70c4bfc9337366aea8dcc7c8d0468ec72ca52da9948f3e28d38629603fd891ac795506512a67c823396229bbf664a98a41a9a44962cbc21695d4c28ecc17f9932f4b620a841ab139383ed6c7e463c24c39312726873227f644ccc7fed4253144512cc2d86861478290c8217246fd15521b65117246edc6b2882145f4758f75aa5fdc920c6c1879ec44a15e8c883076a6e2651147f0a1961563376e1cfab8f9aa17e56a5cafdd5267bef4adeb32311cf3b22ade262a66091c8da1666248bba34b84b13145fb6e188e9457cf7c8142cea0aff5f2c93ee8a504ebbf7e4171f9cc970b27d72b93e0e8d4fcb513031b4a9e70e664b90509836921ca5c4a228c4a7ece0de4190653155450c8533221cfcf9c1a8f1d003aa6145812c8224c66b060c8510b39c6cb0d48184c6a000231d65c3df345093e3972b561244f8ee461e1c99949266a5e20b64c0c3420a6e6656a0a24301561e506e6bc0c19b173c74513368463a7a475b16da2304f368526b5276b9e4dbdac96b4256d29a93c6273e1505a7d35166874935c6f0f36543860202f8bc82132070859e3001ea6c6b14d727cfc04b2a625130bb547faf03411190a9b086661d60ed9b2e843968caa92216710892a18a88e3d2e35b0d1464b53c5228df1891d72bc8b0c1adabc0559289040598749fbd8a64c122986c35196d8ba381eb24ce32dae064663a634d6fbe2a519d85035b34d548c14065bc91c311f1a04ad5eabd7b5ee9e3cf29440a84b72d7b48f8d3eefe8e3a3ca99528b3e78a6009d74e80f5d45ff4c54979460c3b884dcc74153f3c3290575c91591bb7265b3edb4ab8b4c14bdbcb1f796bb2524d8f0cafdf71160e3b2648dfa0dcf5ba169337368d533a07553c919d9eb89e4199fc81816976057765d5886165556bd33131533511876591aa31ad81e206a7834cc77611bf3a5071c9fbdb65374eef0d2325ce24be8b3ba648c7b56ef4dce64c81821cdbae488645765a2228d5844cd5bf333da8ae1409bf8bbd7b78b75915c37ec93899cf1913e1fd2d19641d2bff9e678c832094f2cd4209d7b64428166e9922e0ac644d1e310e110f349c0cca523368c3d618c0d1c34350ee01181eddee9b7399a30a589053943e659ba71a6b267573681bc11e95abce88626f0d68899043e720ba8f524d2eb4938147dfb453a463a7612965c0244b71fdd2f8b6eb2f5b66fdc76356d6241a289f96419a536537b943342df5ef1862d19437be56af4e9294743db4626194389ac6a9a96b56b59bd1addb6ed35e837bc4d99b357ad46f6d0bdc9968c512d2a35496f1039ecd3c890af44af9b8659c7cea4f36e44f6b0d570e863b368bc62be2293f9729d0b5dd355f944d5dce1512ed1c0d277cc0e13e67b3daa5e1527cc37fb56c819327296e87eefac6bd866e4bbe876e02b26422126f23562f6f0c9be07760f63b7b7b8b83d729c8f2d6f585a2163843eaff8a25e28f039e964cddb7028a42787dbad87b887369abb6fe7ba6fddf6cad5e87e3d05e85444ce88b9eacc977a9f1cba538a89a2efeef49928ea44a697c3514262c319c47ddbeef6942be6cbfcf614a0f912f3f6530ae40c99b7538ec66671b766d775af31dfede4add3e6c6d5d8cedd9bec63eee40c9f522063580fdd30e58a6c552443e89e2c57b161ac6a6dde2bc6236f8fa21bfec81b0ebd87a4b6d96fdebf7ffde1d0a6e6efdeb4d8fbbc57aec6e71d7be7c8193163de2947c3ebc9db75514dd4f579fbd25b6fec920dacf53a7f5d47c06579de64e27d2ef1de24f0bc7b21fbd0354dfbbeef35e6bfdf84cf1ef7cea6660e6fa11a44262e59f34298bc4acea00fa9f6cc85661a96216364af9d3bcb4e391a19932caf092b31f19c3d7b942167c89cb964a793f220afbd86ccb2d06916bac936335f58868c41e911edba76dd38b1df647ac3f3c8b15e77562c63a63b4ed98436fb864172bce24d8eb74920634c26b9df37979439a031a714b0886152461f9b2c420e298249e3585da04523489c884a62f013951811224f6c3373054cd9c694b3bc917202bf028d2db438b5162da24c8b162c2c518685656525caacaca8a844191595d329ca9c4e2929512625050525caa0a0984c51c6643a3989322727a55294299548a42843228d4623108c32202812451991e8fb3e6ba38cb59e17653cafeba24cd7715c94e1b8d8b26db165ca685a9645992c0b85a24c28145b30ecbaa2cc75595694b1ac5aa34cad94764799ee39a3cc9cb145467e5ede486909c104e8a70a287c789e48b2736489247472884821b26c92c515414b9848f12325ce1563d12bd30341a91461bce28a44b04215991e063d55ec9e2aadd78609c33353071a4329c5e982166d3062c3f853310cc37eb09f8e91e590962c8324905c226be426251356e630027b2387c8481f1313132fb52ceb9a40b5704c471965bcf53246a5ca22d7371614f3d496b1ce6add1c88b0b5946d620e43582343b055080707e41a56a1cf4c17d4bf19b1218dd9b558b3cc14c7999219111acd71c26c745249295529820d9f290a063da57f31bd2813e7fc8dd6f5a17b93fbdad48c61193246fdbc8dcd46422ddaaa181e949cd5a2966559169667a439d0faf29a942b298388af51e6ccce224f6b725f0338808359b81034777a16d19158c43c859846e44924cf2b7c4cd49c3c988e649922c655cb25661892a3e4287e01e3666640cec9040b47004a120435ec4451038b0832d87440822c18c18a220b491822054cb010638cb2bb37dad87c99b13b7637a594524a29a5ddb17b069452ee1b1762f63eceabf21095efbd76ef09bd61e9cd25a0fb09c342144d0e4bf701239f4e3b03418ce9ef3d39dd996949890a9ec8f5f4c5fbe4f4c43be9520b96d2574a573979a9f4caed78711baed9303f14141b504c9fe92b5d7b71633295dc0fd4647aca0d6f72cab5de5ea484348b5cc0604fdebdc9f4dad47cc232640cd3eb0d5db2e9338d82e3448d6ebadf090e61e412e9c689d2bed1b649ee878d3b0fa1dc9de3be594b0303857af1827a1e087ae1e87b41a905bd172f6e9c29cf761a0d8c9b0dd7d36b2fb237fcf0c5855c476fefa581a59f3032f7d0bd4b031bfa80912b07235399b78d865b16343747727cc46e2002d01460dc4004202964f93b6d3802f7892c49c581a3ac54ca48230b8a3e8d52cef328776f87ca4f1aa651c19ee6554e3bc7d1c44e698f9daa9a17d6ea795ead9ee9a4e4795da779ef3c4eeb3c1c59f4d1e93c3a55ff712a1de90453b92715fbbaee386155a72a27e26ab5a2d368441ad9fa5315590e3c5591e5b8d355c141a3824fafb59eab1d47e34315444db3548612c98aa84a011d38ca4e4e4a99157db5d6d1886447b556558761d69a4c3f0ab579efea3f6b2b0571d0cdf36a15e1eddfbfaf6a15f7b0b5b31da992ba3a1a8d46231044a12794aabe4ff483eaeea24f54323d364c4a8aa9d4892cc5a12a77e0c88a4ea3118ac99e946c6647d64a1c22eb6d9b8a7b941908c2714284aef34cf5dc8e2ef33653ceb28c4412812392c7ed40b9a97298060577f7c07b60e76d998769baaeeb700ff01e281a91482452d7913acfb3342654d7ed309d8b3b4c184b795e77af13bd870dcda277dde8ddb59ee79148249287c3eff624d2f72e7e64459fe9a298ce75dbbbebdd5e2e9ecb36d3fd4183824d9c0da5d96a48f32b83165f70a2ce3ee3911b87d9bdec72cf3e10147d190e4dd144b1567bab918636b0db87ad4ba4087e66a6b86061b32cfb68a3413c5b20e5a1e5ded9ad9769efd7d6b2eeee5dcbb2cc46f4ce3dd3a8956937d432dc63c4d1daa36c949548e006825a9659dc0dea43c85d7b86411f344cbdacaf69a73c3051df1eb8043c466c27e7dd4d33ddb3a311062d16711d531c87439baa51aa510f8737dcbd1ab0dcdb02325b9f5a9665f778e4d6de97bbb5a91aa59a46b9db542eb4a959c371cba1909ce1117978641b7a808b92c06176a2b089e298f0de81af4cd64e940ef41e078410e00d6d3278d1fbd8d75bee3a3777cab2efa60b66a2ce70e33851deb6813eb64d2385b4921dcd9ef49d466f9525adb7eed4022d32053cef74020fe2eddfd6ed7d8fe0d69d4de313f813f8ed21963f7c02b18d981dcc0e3ec3e8f7ed8636fd6dddf67e05718fd2777d6cb97bdfd062afd495e8bb114923913a52e77d218fd49fd733f4ee3b9d2fa47fdf356aff99b87bdb4874b2ef814dddb9ab8936d2a5fdafffbdf187c1cdebbc5028cb361105414a3abde1e85696652f1da4b7fb4e0f7e7be9f6f840cabdbba29344371c611f5bceb230fbbe7df47636d93b78698f0ed35b1f9ba5f7e8bd631f9b8fad1d00848d9cc1143370828f2d5b40ce608a194c71b0061a8eac659444414ae9290ebb6f9556db3d76c39470889146f560b5f5ab187b2aaf44aa28f444d64fbb77dabee3f495ef60b94a47e9874f1b5ec1342cf766da0bb7c74feb28d52a3e59ed9eecbf6b9dc9844f169f729cbe729a130d8eace1d0541fee2152a9448f128552cff3a84769ad59adb56ef68638b2cd40100c5119040f5ef35431df907f1cf81e7d2822d2e9f41da313dea182a3cf36adb7793872d7fd2405e524238128267b52b299c892ac5da17693f1047e74d2cabfbb912ecde923f0e65059b122ec43a5cdaddb56aeca4f9765bb3954f0cabd4bc382e35576e52aa759c12a98e684bdae533e545127c7f88855953c8f69a284e0bb2190fc715c08a4e32cb5f6d64e6d3be9edb449a7a5531c8a9a36f77a8ee34eda28e57ef8fe59ee5e73f6961702c99cd55eefa9c3373e0d73d7b8ca719d394cb9136cd35c49b471b7d72c672d77bb71da6739daf566efbacce4c9effb6e770bea903d72a14dc665dfd7894c9dac36fc914db7131c3de68ee3344dcbce5dd2b37b83c4ddeb6e3df07e3814619bf6ba73b7bb373ecc7157f36c9ac33e7e009196069ab76d17512cdbcff4774578b30dfe7b87b189a216f7681bd2bc61edde64f086417253d228c3dad4186b1c961e47f4deadb2ebd63fd87ff8068edea3f5bebd36959c0fdb1b9fb4f749c3372cb5d76ebbcff2287e05efe11ee06ddf90721ee79d50d268e4f5d6dbd6ed7d1bf5d6bd511c1beb9e7dc320b96d08247b07ad873b7a20f9fb4c77789b280f7cf70f6313e5dd7bf779d47adf4bd2edfb3cba7db4f33c9499eebede28d5b6cdebee9dd2eddaefdeb0946a1dd5a6b6d13e958f2d1f6fc1d0df39cd0b92696d8be93bea7d97dcbd5b9a17cf8536f3f346948eecebedb52e37ca9d62fa10f743fda9fb0e949fbe43e529b7f76e48b377eaf0a7f23d05d7efd486dde3f70bb4debd4b6b101fbc537cea4ecfbdd60e9f72a0fc741a144ca375df431a3dd605c9b5b35564b75b7ac38aed462da5d45afa7978d451da7d1ea51ca59bd5a4773311a5d7d2c7a3ece88f6ed6729f9974fbe928df7142d9918225f8a8a23693bb386b6d7c7d77b96bf6ca0e7ff5745b7fba33fd598cbbaddeb54fedc41dfcc87e23909bd67ea6439b69efccc2bba1c69dba7fb728f7f41a84e68463a3fcbbddcd91627f7a6bd7c65d8dcbc20c64edf494d39c3c1a149c929e6ac319b50182591a24bf344fa8d0dcd5b0de369bfd13b5bd5eee9e69db7ec8b09da82d7236d43b098d28c64a1ae91193747bf60377efd96bd753876f70d8c391defb7743eef16ddf1eaeb7eaf71f3ed4537cb2a7f7bedd933df72db3f806777a79db876da8e5e11ea25bdca3f4ed3393bb9496b651a4a40a8259b6d18df39e7d0343d9768fc361dd6a287ba8de1f39d4358cc966fa0478b8628ab9eef7ae7613b5a139f49885425b88f36e2fc7891eefdd74b14e79f8a10dcd75bbc6dd1ee063ce32108719c8e049f76e77431eb9b321eea6100e79944e4a38fc91edbf874c3814dd8b273547ebb32c3bf8ed8a0ede1ba21fd9e3eed9789b6d34ecb7cbfdb8c16d59e761198e1385c30cd02c7328c3a1cf4c798ae3478e8f41fcb0a4f949f1d988c9d7f7e9d58ae5f0d73729babeebf2baaeeb3c7c5dc44d527a123d985db71dd2932befdde34a7ea661bccbdb6818ee339d92ef6e4da77870d8466c628a4159ca08b4e19015b6626ca27866628c266dd22ba48dd094c5b044aed6afc6a185758e8480340c860384a988cde9db68982cd8503ee1c08ee1207285fd66c523ca707986308f4ecd03e9d4bc69e60cb1c252175fb0615cd2d6112bc051a2042272e844d949a58ff53a64be504bbb8f9462be08315fb29989f326a6200b64976098b526535c92b5deb488fd0822c2480f84423f3a4513c0c5a01f5186cbf4fa44a04e94b1995e2a1165ae402f8970090399864c1fca3164fa5076215329852ca74842a65c963ac814479fa892a9f5b09deb126fd7bc3f36943a2af43b3586c416fafb043b846297f499424829268afee8a09a3cc844a9a53a211d580b63132575e4a9951b1882944c21043948304308da27b70fd044054d54c7051b4aa06eaeaf4929e62402a353856c222ccd3e5186abc2a2204e27664e9461c9fdd93d6530719d3913d55fc9819539081334dcb507d98e8368b72692b9c444293175e6763bae260f620b1aacfcb952d83851f28a896a30581994fb73620924a1882d7d202020a03ec6e44661dbe78a4109a494b25b36edee96e10e748724ace1880db15c84d6311912369446480dc417cb23c8f4024654c7c49656c2368e4e755eb9810d634c0d13638d189638606b20a22e53080af632c1cae7d0215afc0e98e4013be325cfcf2000888619000160dca0ba005a1ee3383cf5500eb18e43df7ed8f8882d3387088a066c3873a65c71df68e623ca649f8fc9e1f34088ac8cb758394bca63343d4610dfc5637f8fb1616450a772b827ed3a3cae64dc93864f3964dce53a72b80e39dc25870bb1e1321e5777795c692ff029870e77b90e1deee2722101b80e38764ac33a5caec375c0425077390521b3f65006659f993208c705c6f8c696f95f20266a3e07193776aa050e51319d9a2c388c91658c1cca1d142a0587bf099770682d883fdce1cc0396c31b96475c1061b55010190efb584e177ca8b0c72bb30a071c7050a954383cae04704f9dbaa7c6a71ca994000420800bb1e1a947ec12464b4b0b0cd461a00ee34202f096c7d50df7249fc3e32ac63d497cca11e332aee386e7808500e0375c0616c2040d007ec385d8f0183711a0c88c1d260a35800be3dae8d4fc0d57755b6e8c8bc3cd38dcb852ddb88a71e3ea861b572d37ae60dcb8ba6ecc03a83153b7621bc6c400f4c53200ae0dd7c5ec7a9eb042cf135638810f0c0cc330152a8cb1d1c34f8c12248001a358ec819d748a9e3040a6101335491e2801b69a31cadcc0fb94353632c6943f0d037e8a5aca020cf96a7b289bc8f31207d200db470fe5111964c5555d49ae069781c4969969c17af77bbd46c05bd7c8106c057ebb427440b5fa3ec4aec003a1848a9f6c3373c5272c6f39c87ca9a71cdbed4fa1930e4ff4791e0d730a611ddbedb7db875227f450e684b045c2d67b8b74f7547fb3e2eea9e209d07057756abec34150d8e3805cc38a09eb71b53d443d5b6df71e9aac0d441932e4c981f842447cc9260b268e9c6123a708220c378fc8b3a661e28a1447b2c995a27bade65db9d3a91bc496f9eb4a2457267165114964a2e63c42c3b29133e4084a105b72e8ca5c8361d95a12a2c2528cc3c6445d2558f9309b1a0c8a80c4bbf6ffdc4a7c7a1082247890a80286945236866158cba6dd2d553ba07aa28ffccf44c5989999989923e4e4d0443125f24420030e7549b17a58d775cd5f3c72c7eb560f375986cfd20b368c3e34354772297354a2842a72d330810d314a4513ba20a2020c83a80917801f20428250980daaa0e9a805d49452411c74c5c1c1c189a886b1d13895cab91a89c086126789d9b4e79c162a478e20c6e80b4b1c598279491c216cf8bf982d67cf77b71665a62414d8a9c4199ee059459410d8b9842a46a0b3924300421474565189108ec0596975a3777ae0034728b2babaf0269f6e5839cc40c630264a7e07497a70566d25923f471ffa5b3fc1d573f55cb5d65a6bad97cfce5cd26dcd25b5a7f6486176b7a58a735e2eb55eb556975a65b89c40c7d2c9eda3840db71c755a4746ebb44ef5913b5902c9242a974deec82676e4ce04ca5d8449c4c2049a4016106850ae3ad3886d64a241330434880659249e39ada83ca8a1cd933ba886a7791ed03ccd9306ec48c67ea8851db17ab6755380381ab3bbad6e7aeb5eef3bdb6a2b05a84522c8735a279d2b03d9c2575b97b6e0a433516dd5478aa38c98b47a685c92650e8fb8e4013c2a0f2be877af29b6cc6b328a177cc0a7872592f8acb4ee001337f05969549ec00849f05969b5e7a70547569ae5042c663064a55d5bcf112772561ab60149c1b3d2b0adde134d0d129940e4089e55454d948cd911988004243b44622044d5348a61d8abc51e0a65c65e6f45f7fb41cb189edb7ca83ececc8a6d990b43f7369bd1639ac5a4155c8dcad19076648a17ddce46928c5d912790b442c6980f61184603bbee0eac0402ca92abd41a4111180cc13ccc091802e8ad6953656b94a996dd588f6d974e1486d5502814ba7693af4b2e4e1476b2b01d65d942a0efeef3406fccd7e79b9614b8ac895dd69453f6b02c7cbaf1d97362cbb22c8c7aa19a2fd3b22ccb0aaf8ba27f81cd2dcfda018cca4a9bd2534a69a5b23695b9be6fadb5ce1ad82badb4d25a2b0cb6a2d9a78956276dd95d67d3ee39273eddb8c2be2c8cfe4d9b36a530daaa1f9bca6682165f8419a5216d02413fe9a7920833833a456fd109058c760eae4b42b752a0dc9f411d6d6d7a051b5e38b92b9389eaba24b6583d9dea3fd7ead3934319106c587d8e4c597daa143f5950cb8699ab89335f84c064bd62a6ba02a9c0ca26dd6448ee954ca9414d727f0275aa59a2b0a16c02947b7234b02c9bcc972c70e68bfcb5a467db208727d8303619126402992ff4dd6f988a598093a392152891c3d81395a8e08a091357f3a1b5d1b9c646c300d17303096c189bf467a6cc01d23038ab6e15489181f851d3ef1f551d42a8923a3c35353535353535353a74e8d0515353535353a343870e1d3a746056a5d9d1a91361d69af00e150cc334b15335db6aad12c73376fb7d1688873db1a7fba14caa4e81a3930eb2a87ce5a39b43e58461262ae4a715dee4ec212b6485db0f1277214da35aadb5fe264b59bf6119f2862ed946c3ad6eb20cccd95e10dd90268baec53967ca34cddb9626839fe91f7b4513a5eb94bf5e1a581819c60c7dc0f0ace63616154a555cb0bc45fccc2469dcb56ea41c05ff403ab7e3bb218cfc7ddff77ddc51fe5d7b7139eb9e4e180573971edf1e46b724fadda2f42b2cd7acedbb28f8a44bce87ef28f8548f727bd23dd57b2761584a4a4acaa9621a1bfe22936e714893519e82439a9c72edc5a9742747a3f4931394d3afd3c9c9bbaee34eb89393128e13757f724d076fc82393aec9cd0613a613755fdcb89ae97b4f9484618c4e718fd12deeb18272c38a7dc0f856e88a0b96d7d3b75061c1a1cc2a57b1d7ac8ab5a00f16ab60dc8df644a09d74eb0257fd66e572c36962fc86cbdf80c3553808ea383c48001ee3372b19f7242fe337ab1c6e8e1bae3acd0d575d5ea5ba0c1c0400573d880dbfe13738a860c4b8a1c58a2013c523771afb25777cb082dc30bfcafb53672a315fb61e1934711ae6f44e61d189325c6619819d79f495539ffebd61b0563daade84ca4c54131657465ae982275dd19da09b8e8e4e5ca5c4d549461d2327df3c651fddf4947bcab08ed14d271d2b4ff9ca532eef094bee58197c7a2ec98e53ee12ecfc699fb9a46156c209c40903e28a470d5e7918814ee4e36af430fed8187de561ecc98d250f228c5e4294913bb12507730711e6e43d97903170d00521c288c087272b57f248cec8c953ae3c5d693252fae476581c9c21fd8e28ebbf574c599749b4f46918d23b943ff2d3a7979033641216b7b85e4c5967b12e77a24c8bd8622d911b473c7ba6ce9da73b713ad54fb9132574d3a87f72a576a513dd133b05fad0c82e87b49cd149e4feaa74e38a74e36a74e30abc713564a56558eec49639244485c5b0c4012277e2e6dd78d343a2c51761c5e9e6e9d69945bc775c983af3257a98c5a2a9105b0a39c345c628437c41437ce9236223117b07b17d109f105f342a2219e48cedfd1e4394e1de2d3a0bd974c58b1332cb3b0849e40c1a19830511a6a65344fa501841471379896cc402b1a53fd7106180c89cb9634413816147c4549f67e6d24397f4eb82b7aee8d45ef2ecec441996fce5fe7c22a50925a223cad01314f9294293d026624b9feea89cbb31b69cde82e5ca23220c7d424c519f4e5135649ac54579764dff9158fcfc5891a3613ab9d65ba649148c541a5deb596777727a826e42a49b944824d98488dc44a0373a6dc22b92441699454091682659913c512672356acfd979a73b0d439774aa0a3983662163ace02574872ed9c9134f21f7357be71222aaffdd898488f291319634cc8c22a65a362137cd625291db9b40b1a53f9f0841c1ca1e9eef4b1a66a3594cda853c0aa91ae47da88fcc51395d79651228a66b335140666a1ee7e7e4fa285d1ca4db0316728604628cd9303444be9025164d64938804223662cb3c7861c8ef456c51cdd4fc8c99491a8bd8d2e76e8f21b6f4b7db6490319e1051fdec3615b1a910532e72464bf1e284dcef20c4543f0ba62b4c468022a67710db07b19188a8be75fb8888eaeb6822d3c8199d8405d146ce6822b7409f202ff1851cce1d34c4598688eab7b8f3e72ec9730d3175c41772bf81763ad56f2372bf89c8fd9d9db91345c5595983145738d13384123d4284a1064e044d9c23e008e28c789f997693b10a9ad812438018bb042b63da0c7194fbbac194410b42ad71b307c7449d64287778b7a7e9fe5dfef3b0e9662531695d550c8aa14924cf1c2c3bc2863268c917ecc4456822163f57f830a9a24891bec4b00c8aab89716856c8162a08c68499420499a4496654c3c8d5270e0cbc3083b4287a767777239948827690c8254c41f2874221c2483004fd04fdfc502c836415f45dfb72466155da54042919423e620a9f385f26206f83e509d8d82c7d105bfa920731c684913b9bcd0f28acf56a447bc368414131413287f1c746187d76421782854e8f248b7c801c95d820284b4e869e5d8876ec4242cf4e7368c7ae23f4ec9403bb761dd835eda1ec210d9be46dc8277cc427b2fc4c1256eed022cb5f3631280605d13c658eb56a1017689d97143a4a7c8ee8d66182c57efdc77cc18c881a4684636a9a0830b84294a1292da74882fc81d40167a36144efc7663981053fba10d149affff9a9a9694084912d883f3a37b042981042bae8f5a7799ad1c1d3902e7ae44e13e718611007618206bce83a48d8060e0262535c31a1cdcc17d90f0390e56d8833a40a628c3e6647a4cbbf8832f4f2a4fec804da9823d8981d6acc6067cd34733eb4c8da8fb78ef4a4adb15d5e9e6e5ce217b1e593f235629638a4f9b352fbd4dedd6f363314ea50167746091595914e8e99b19161a973d56031ac424dd4d502454d1d6f762fc8c15982176ee0830023da6d4c549f6a60c3c86363c665c26857990608f20307a771e41ef33e54f9d2b02f582c54354723b47d08eeb153563643eb4395352c6b59166ca4481c59e28989ead9d34f744ff360938707db393251488e44196ed607f1aa77337faad66bc534df411ce47b909b5588cad67462727227b6f4e3ec79e4889c3187e496526b91687411e95e0983251c4464799774633ad5a3eb7913d38c46d6da8b623ef06a7434127d640a32ba27bf5b9ff634e02df80f07b1074728d14d28d3e88ab0195baae4ce13d4fd79c57ce18932a1dcda73b6b68d63aa8285827c820aa89f9bb9e9c3710f4598c9d3a966429e3b1665b673aaccf950a5f05899b54f80f61139033322cf6f9916ac7422893cbf5db3b6d8309e05bfef8237766f573e617907af63748b858c22f81dbc8eef2016c2040de9e085c44e7d3ac07fffb01012963dab4943ca9f3cb17c42c3fa137d9f083cf7378c45babd90d2c15ba4dbd3906e71e920b60d630fdea29cc803ef8db090efa35b17f54b570eb10dde3b0de85d748969be8fb010fb9177d169bc8b70ec14f8efa11c228b8097c6298777f034de413c318dfd085f744ff3403ad51360405c7d380810f866f5b8b28f40a25be3ddcad8192957ce876885acb5d44f9e7a2ae4fe09a70f0ff3dcb7abcd356459a3bb7c8dce872a6fdbb34b6dd2d0b013b7cb5f903b3b4d828096fcf8c81596f1e4892d54d81096488e4c54b73c92fb579ddb4ce9014e963b71623151f44d66d0bc42c76727f3c1ce8e8f4f94b93f55e820622193cc9c91800a9c30740089945276cba6ddddd285ba58392af14952440335c6ce52e4f0b109108ddd48f639e79c73ce89a53c92e7e90d6dae4c7ffdba82f0ba2f735e71e412ec2573a80ce51902a28930f597e71ab2c441c835e41313d8d02501d488f6992977e6cbd430dd7246392a392f68864fb28fd91158ab4a9e248c01a358b52eed9a9846bb8957d42bb6a0601cb1e13699ac0d7d62d544c584aaec32511d635355a1abc246faaa186ddb3ab3b6b7296742b034dfd0acd6758955666aab1709565e073c2d833e7264a29640f54347e20c2901349b0911466aa18166048a2d68b0611fc97d7aa49768249d2476f7916f8fab1cddb7ebe8be5d88761d9c90ed9926638c38fc68ecec9eb28796cb30131ba23cd61128a04082fe749289a2bd83a491ec20a1d612b1859a7e620b7d88084b7f58320dbd4c2189f4ed2c456ca1a71963622d1c62cd23c40ca080a20a3aa0a2044248a1831c244890f8f4b060618dd0914148924c89058e13990faccca14492f9c0ce1c4a2448649034431259be590645999bfb210f6820f73128260a934155d8cbe201425225164d8276ac8462a2ba39196465108c9e257a7a7a7a321250613be7f280165f348f5944eacc588247a684953953c26648d896417c8999a8b89a1151fdda84c7090b6c189b0c6131c1ac41c87a6b96481aeb03e9543f74b1192d83886aab890ad5c407045fa062b0d288c61796437070e490a6e8a8740d97b4450b158d0000000083140000180c0a874342b170409ce7e2201f14000d8ba64a7e4c18c9a32087510819440c21860000000019001860b48d00628607bdae1afb40ffb997e327352707c5c08a31b0c6489061496de9c085263ce1ee420974353c2c846dddaa2970138d3b18366d0fbc58a44e6f2755c2a99ec67717316a3968f5c2933e9d4a07a9509afff7b4d8c0072a1b06556ee68ca99b16357f77514715f4bfcec3981594865e7c74ef684e03124c027f2215aada7ad1c71c1d48158e77b03cd4fc2c5f47fca94f3a3b503a6f068dc3a14d770f61384a75e19e8350a5c96202734b3c1e23cd2563cc4858b4615c368ac40e99074db6073aff19db91e526668a4a7072c223bd6307be64872dc40879a83d1ef899ce4bfb6b618c07a9be7434516b19268ca6a26f768c7541a9fac9b1395b16992975874c8297f399d93b2bc8546075c5dbb88b3094877b48c6ce5ebea85d175ac86f32b60086657cb4dcd95ba2c0381608813623b9345baa6bd30eb626d18c83cbb42ec939fb0fc90d535306a2a58205c5c511a1a5091ca9ab75e852704458f038fae6d9bf35f610fee3ae4ea846008f79f9c09d96d92200c10fc09486385854f58036b3fb8e650b2e1ed5cad70fd2614b82dbc82c225195a5c037425d75298ec532e34b3dac180fb07c17d37d9907ced04282a239fb43ab9e2727a1fd3026154f51b048ac9ef95c035f76782d4c597402d3a9d849ae540749b0f83a42a8d6d90c57e6d61464600f2a1f95574651e19dcef569e2995595c1efee95463d23adb4e1dc57d1a2de6e3917041a4677841e0d66b28ba49bc5175b51c8543c4b9f85fe166ed878dea8ab12655e8557bcb1afac9ea702558d69e64262721add1b9c861405efbf33ff7f7cd13d4cfeb2c795ac646914ad58a8ccfb8d15c581c7a7d40f073cfec2318cba85327ba13f730c068da5b202a9aaedfd3268591242487227c417d30b10c7591f0ac52c27b329bf3c217d124c148ae91b67433e3bc51c1ed8744d2289ab68817f53249a9e0e9ac40a71fd9266f51df2eee8a13697d6c8a226179a17e5640b9319b345329d930945838988a6d2b1c567ec232cec72f6ac0c7b9341589517e5ae624c635207b53de01dee30683cff6824f9fd8cb44cc91d345bed990a0c8dc0dd2545aece2162ac058f5990a5906c64d92d397ac8303eb0409117a34282b1c09f12035caa5027c31cfcc875681038f0e955ea9954fa93db312722d52529df8292fbf3ffac215e7c5615f635306ccabe11c97c65045162946e63c9057a3898b4e1b6782efa7c93a4ec95be695438ab73b740398d623f8d223a59820819336974526c021c28877a57bd7797f39353d1fff4350d8e1cae2164946f6acf09304d23b83869f0d0486503b7be90e812aecb82af5ca668363cd0a569900275cfce2ab009d49336b63c6a101e24932b70b82e239e16bfb2795cf7261e54dc7b53e49cced8d0e171a252640fcef3768e04be57755ddf9627e0143dcf5d536e1254271380209a0b18a602e8cf3f9c4d1efe12272acd42c954ed60825dca15a191e53d4a3a7385ba96ff26766a173d0794cc660df0fe26156fc029fab5ccb1262bedae6bde670e071cc74896c7f38fac9d5682547ace9172d764fed0504e834d9629ca27d0201d5c920e42c882c6485eba7d9224c6940e44220959dabb4a007a6eafea42f4b7b83cbf27bfc8705919388248198133531ffadcdcbcd56f9abc1822647196122029a7be49bc44c70f27d12df41546118e97af53939bf11e1cebe8340b1782d65e3b5875633abf152357bd10787073e6740d6ec3974ff5b4e4dc5fbab4a08ad7b963ee6b44f8f9e2fab6e2a120ac1ee66b8079d50d8bbeecea329d7f8f4cb4abcc816d77d9a3a407f0c786f636303394212d41cb90aab2a242cbebac4f6fb8b68f862c64f8995485fb4d4c566c09c6c928cbf6f4f4f775522e4f0671122003f418dfadeb5849d0ce0d775d16b852b500ceea511325f59d408aac02c3eaa75fdcd034ee001821539ffc9d73c79918ed6f981176616bd19494521bdc5834977e4466b16a8493e390eb3dfc251ff5ba78d2f1fed70467b114f50dfeb7969c8561238d03f4af733406d58a33b385cdba9062060e76790c65d4e4a652e92536c0249c3bbdf6cf9bcfbeb8a2317257cf0f0bf72bf651548189d29d586198623adbdb8329db4b4102da44fc92c9101fa8d40734f338817a3873031052d18e4e31cc6ed614822e4ee1fd7330e85259e1f6bbc3a49d534e4ab8b95882641385884e24e4cbf0f57a1551935c6c313910e4d24d957e54cd17522035c54238519f022732cf265b1fdbba166561e8f75912cc26d2389e762fc476b5eba6aaefb2cc6d87fb7742ab16807a8024882462a0b81f5f003e853a8af3760165530ca366954ac30601bb138321b6091c7ab1771b82736818a41113157ac72e446cdc877a21884d9e049dcf0a1c8ec227d75518a4baf78bfe9c60c8a51da32312b2bd00247b101c3a0c83b8677373f1b5cb4c527dce9df333139d690971ba4d263c570d21d7e14e22f70ad95a12d3710215d0c4ee0bcd3f475c2aa0550934d93feafd5052ab294d3885f34e0a33c1aff9f8442fcde8b8288da1144f2dc59cbd148f0ec47199e49684cc99fbf0f9d34cb47e86d0b42124188a2a9608fc1412ea4dfdcaad5a170a62428036542499f762a7368ea7b4ef9929636000e27ab13cde83b4c686b35f60d700d9b92b8c81684a068730b64dc00007587f7651d9316341b6707be0d78ca87c031bc46f60ff0a6a3feb8fb1b15d0a8b3024a0c20cfa818ffd458f5f386dd84e71df6b8561f86bfa9162384394a0fa5191dad7fa402ceb7eaee813d7e708a166012100651a13c761f4fa95355414d5b00e99116730ed2ec688d398b195c8691212905c3604e4b3fc171aa9098f86281bb1f2fcc8b79bbeb33a876a292bd1615ffe92f6875e6bd4e92e30350bdb859a6a6c30ed5ba14932b74540e29e3393735ca1805634b22e24f749396948c614e402f7221eb8341db72904d642b8e90f9d81b4c19e7dc8c6b9044f37755eaf65836cb796b7d5b2f7a57e79e95bbf458694503e43010ecb7e15194e2e5e8abc69d410e9bdeb47da050e3cfebed7bb28d6a0eda9dab852211e3f1c8aa61d4a6b87ecc2c0cc3d96200e086cb06a057355030262593a3aa3aaf06dcc05c091e4115da068d87211e456e48e8670f61537cffda54792aaa078bdb8a58f804948875811c155f0c5c6bf021162b14b78f017ac709d942374e81675084201990bc04711fa700eae9bb4139622beb02511e0368077aeed34718113eebaf255c0cd9e84897a0216f8f0d80439c42ce08b641eb4609550c1a8dc839c583a72b46c259c364135cbf95519ba2e6c07bb1126cdebd02c29e35c413bc09f3d2ab7192bd49dd8322d8c41e4246273c63db828c8c4a871590115d0c47233742654423fc0565dd3f745f59ad2800020eba82f74049a69fbd2ae31f4719b8744594a360c7053e621819262fee971119ecaee6417c5a2e40c984f8ba0511ce55283841a48ffdadde6034f69a0481da5356d607128adf1239e86c8060ae2ff24a230a3cf6869e0c7a1dacf47a5d7b523542d17349c9f5512b4ed8d9273d23684e6c953651c35a4aec9ad9d232fb29ec33f26213e242950131f49b21870cf5d13e943f498db245856e3e20631ef9e438027d07f35b8f216871591b2498410ff4cc5c2a49fd6cf44928ecd20a970d1716e4e060066dbe4465c5475512cac110eaa9ccaee36bcce727f7571b18b702ffcbf630e2d839008d363dbbb8c04113077513cfb21d616b9e8a57975615e217b90194a05f6e20959125dcc43562ac889ef8f15d87f61d35acbce8484a008f1b3addbec08bafcf7c5252c390ea0102a4d8ad9286f1c33b23890c77628a1f1ede59e88e41df705e8c7800435e2a33026f0c481eb8fe318112365407d4361c47c2fbc6afc9ff2a0eab5312528a3a090eb894341c9e9a56c496620f617703bd1dcd92d05b2eafc65caabc42ce362a121fd3c8fbe59c3263abf8dd979c0a25ae772e1bfb55a153566093f4dede7ecceeb347b07d90ffa5c990a1226ef0398666faea318efe3bed2be149e85db476684276718c4247e04f7970af61adecefbf5d971c639af891e5e079eb98e8e3eb27a8d1f540e37fb815a27205661236db8425d2c749e1a7fb1edad2cd9a9ce07ef05633e0be4c8018196f2f738e1f1db99e8a3f21655858e9309016c50007f9f38593bb32b81286d4ee4771a64bbc1b59e259b467a845383acd5d51a285d68e63e56ad0c58c1819459aca1af798c53cf05bf7bbea429fb01759ecf44521394c9f69b1c1edab754c8f752eb80942976c1f2ab15ba9f956d347d036d9fe6b1674dadfdf48c127bb2807d227612c209d8c370eb07c5297abfb93d671c7969004f132f4c01a378483b45fbe74bc9dede740bbc3a04be43c19e2f6baa03f662661e28360803f26592a234abb6c8852f19dbb10db288c75f89ced5494a66da9eb9e44d4bfde85244d64702f1182a9b867d22b0cd8690b37ecc1ea0532650ffcc3a03556e49cb0ebd03d5851b10fa199244231dff624088c4a9f6d8f622b14646a672e4c6fba9ea28bb27e6734922b49398f15d37ec9b6ef7f94916abb4df63e5c802d0ef67289a5d157aab46832c5f281bebba26b1228b94baf9bf8f8240c3088c86c6f089da104c7106f78a3d13aa6918e5811cc74508c82ee0b472d6e55421d64ac22350535c4465ee37cb3d1d062ad3bd5e960ccfd89905b62684f9f063c239536c8f370964f866e7715ad2dde7f03729dfb203a4849d3320dfe406bada3363f2fe0e9de3d9a1928d06932471682d598db0abd0e28bff96ffa41b966c8b162e335c1ffafe241bedbdcaceee3f695c9bfe9381f35cac15b0c38a578a0da2760fbf93f4eabd2d1ed969caa04709f57dc274de1b35120e30cc68825660a31e2a5134f749b2c25fa4273d21a51c7a8aec8987a9780c1a4c69440a37745bf360220bd646fd06a710c3f9be977b793ed9a10a89372cfcbca3175001505b4f2dfdb4dd6c00fdfc623299202b95e1492935e4eef5241c75919cbe1d62ef7d49dcd22beda0da22c26db1a98c3250207254f40e2ca469788abe28e60541c6219357e7cb6058521b352756f68d28c883f70310fd94e01178ca2925848cc952f7b55fe3f5b2e00592b4a3e900032d46d1bbd40262c05a78ba3619e26aed24bc4b681ff97e0515e909e26fbb8270a4c9d97829df39d22f1036834d31a7b06a9a398f6018cca5a04df981a30ebc332ee016527a101bf9f537ac8ef50cb5bdf83d409fb1a96d72608da24b9993687560c33879029266a53b397bd6621856e510280ae19da8dffb1da775a51857979aee9c1b2812f7287873e8fe6b8fb3f95dbb15d233a1f3ed0a818ff671c3a395ffd9f954674800c3af45f2d94b8443dcc1f3104766083b71082aeef22f40e8abab5208af1f79ebcc19fb841b0f3c0ebe5ca636a3edf111e79404ff15cdb62c9cfc5a3d39d76d5f8297a13fc11d8da2e40ddacdb6f4ec0b52bcf098d0b544405b1b243131c23c0d48e9fc7e7c5febaa2a2875a8e5c421045d6dadf5b904944468f5a0fa93a71b5c41dad3fe19fda92723bb4dbd86e4f7f3429e66fb326470daa4d047c3eb23c1abdeb3bf91a16b67e0fe3ec023f76fc99c329c2ba05d75812b313250beb0c05a049c04dd74f9222db0bc29c14a2fddf76a60012114f913498285289cf7f96149c1e66bf8ec66201a80ba7b479d478ac6fe18aeaeb96a692bf36547c78ba32e97f59eb52fdcdc7f1cbfcd9677cb896fac05b718cdd3492336468dac9da2705b63d08ebb5cc8a9e52983358621c5c3ab6701d80e7480fb10966b6a3624d1a1bf94f7862477df7abf62af5965f984398216d8f4930e3c6160c0b9c9bbb771c5306be56a5a10b07973207dbb42afdca03c045241077a37151104085067f980f54cc70544b16187d45231a718018fc8131182f3c429908e426e7b8ead2439d1d4761b4d516dc89a71b6cee25ca89b3083944b19268bb4b51a2c3d49c020d9b1d1592297553a38cca8644e2231983fc526bd7f9a15cb36888f5f08a6a8e21df4c959b1f6b6784d8dbf7479821c47c27917dd804b79cfc96986ec1df61b8bd04d7637ab6b39469a773acce47ac4d34f072c54466c978692a1e3c85a7975f90fbba33cc38b257638f1069cca3b47ca15406fba6af7e8ed127de7f3074331f232fdb18f12a86e29e7f86ed692c710c6ff74e07ee390268572264eb0df42e504801827821136c2c20b0cd670e9e92b5fb730ecf6c6abe183253916875f1c37c40f035befa1050afda8adb3fc28458aa113810f2922229e229f08c299d4a8a8ce0ce1866d1a0dcfe7bb27f21acf24c43033d295ea8fa097b94c83f3816eb19045e6b1b39ea906d251993d53d55480db661563b1ec6b0cb36d03e55a016cdb89292da34e08e179e2eb28818d95ef5b881cd035c3dc559934b9d8bafe4bde69b865cbd9be2ad4ca7fb234274d95a2b7325618d106e54d8b4ee736132f0e0854727c15be2794b37c0414a54d89e60cda5c7189f213a28025646c555f2640759771a6526538db1c2a41c3f95e6e231ec59e6e0c64a3f9d590bd703af29e7546f8c8a4d680e8bc4a756e0557bd719aa0a885a4583d9b1653f6e01fc9e65b225c12333a3709809e431f8327cca9efb862253c64ca2683773eb78eaacfc1c07bbf07cb0b987f0bd82f2ae3ed7ccd3493b4151d7748fb640b8998478008edc8ea9c746ffa54703f235349a9f040e6866b1989113d064d0bafea15a88625ea7d09c923a8940b74944c73bbbdc9ca18a3ce4ca53102436e24a8bdbcbf7e2b9ebe3a9db201bacfee7a7fc532af8e73a1d7f5917f63b52bf9c36cb5da2c5f4c8d90218b390ad98579f7f661c2afc818015eefd707c9386629e8f4147ceef50e4a4a9de77a574980947bd891146c0f88fb6636c1025c3491ad48395fc1104b4f819124354c26347a5b03230cf0c0eaf54269bfbfbc7cf3ec23480a6a9909c1727db3c0392993c332c9efef8565624840dfcdfef80681c5d803009cd2abc50e0d33a5c120ef1b93ae73756945ecc203967f25598a90c845c2049f5fb8da3bb952187946c820faaa7bdd84f24bcf7d6b3cb630d2302aaf334651025875b762363f3f0d896c0fa43bca885c1725411b32619c47927d7cbecd6e16e4bc216bb0c6e8fd85fcbd9786abfa4fad9f0803ec11dada9a971a319c17e5f4266ac96251ee9a30beb28ce8d6cdfbf7c25596a48ed12112499580306b3425989eb52ac3439b96916467af337b6d6831de854af6e81884c80e187b9975ae6ad9cb9779fb310ffe17c9b2efdca7a835cc3532883e36c444b9909910108a65e033abbb7b050431f5ce27049108b97f4a3d8b5efe5e2fdaaf340429b8e4c548468f1bb312b12832c1b8dae39db1a438b51bb4ef492594664aee7e694c278b8a7b77de51fabd9fd938265dd22289ad49c5d340939f9e950a7e0d14473c7448eb6bc8ad2131223cdce37689592259ed4e6dd0e32e8a6344f88928ff66a1f5136c9c4b980693be0de0af7fa5cb0919523d55078a17eb8efe8f6b5b1965d35f5ef237eb8e46e2336cd437c57c892393259f241705b7bee0dca7b7a80cd073ae8aaea5d8a6dc89dde5109be94a2ed11b35b4d8cda6f8d61c055492e92517aaaec534ed527c0fefb482c8a2288de0330d6ea5094ad2838aede9c554859fa0c22623d18fd120166e49ecf970e63a1357ef70a7c830a8ca64cba4009d94639b29e6c95e3925f522bcac6b91b4d5ca75ed383f4dfb5063cb3bef9ca551454c044d29f618100a7ec1a78ab22582ee6472829230fbfde79cd54fbe284d893b5e5e2742b60f43b91528f91a1da137d64a4a9585be30b30e8f77eb1be799d8097a8990c6ec04c9d6f7f1f99e8678cc4f21a26f519aa3c3a16091fb9470f882a95957ef828c85c6415925cdb80b4b08b706e25dfacac1748d2cf3d77f96db445be5aacfd4ca5e755606e2601f042c45787794452f91d7a91bb4f4c5e42861d542b75ec6a10017436a247dcaaffaf751cc0389bbe19a40991c3c33ae166f0617d0ee1a013c49d5c4159f1f068f1456acbf894413f8330b027bc5845d93c84a5666e2943cd39b0f4dca5e87e38cbc53aa5e904d6ef70bb21f0b6b2b3244161b990d808a66826d04eb60f50da8d071d7f47e4a5c3fd2d9f7b4e1e0d8c0bf8a96dd7bf4b0d6c10ec1fd0aa18f524d97939b2749e4be3edd4a603afbd8be4312467102d1c5ef0f2107d514bfe681f5d5b64702bf0d4aa00643d1e13b30512ab8e61400949639ce12063e6dd402666e3ec437a24aae3e864835d4fc6fb38542625f60d5ab26bda6d1806e4b70f85b872819906c3a43f5a23c084962958adfdc1eb9a84ac70d4ad690306ac0c33ca56a76d1bad5bae88feec72256ce13578550e1a6b895ad964073ea0c2d571aced296e48c92e1fb358af3f810656a0da77c47a681eabe1c36069b4c7b0299b0faef33ff828eb1761f7f75e2a9cfe921d882ee73d262050d383335e924e0588ec6265f1b380b7b3957ef0c9ba0af2a51729a0d16484c9263d7c2a8e960707416ace6a1f31450c8263c3531beb2ceade9f05737180cc2723685368ae1302cd054111ad9e82bfb0ac0054c1946e81c720c8f83345d749d29562debdc520d595dff094aecaa3b71307017e3665c50f5044747a4116feeb6af777ac391d60735d04739d6b6ffe42fe970f01aedf0d308d965cd4bcae1083d6b1fe7428e8fe6e6003702571e299da69044f30f6547cc7565be556c517e9680ad87fbd339b48bdd93afa66873ca2f0e3355801d64d7659a050b7704fe37acbb43a237bafa8f573facad95cd93aeb74e850ef383f866db75ea8672014e23d2a1f217e984d2e8c1ccf85dfcd9837ad3143d3931867fd56d91f118d5888c04267a79cc408890d8739bafd490bc3021d5738497ebb59952fb28d18627692b51125a36858dd7f121ba7b8e2533fc70e9959c0188057b24c853c5597cbc484fcc741d16d30d35a69abf55471ec44cef6a7c28e04134105488fa66a503d20253310828d89aedd00137d1c24a6b311603104696dfce1ab0d69729d676acc8613b8c2e718e601debcec66092ee4727784e94355b6701d42de6e0605d90a983c6635a74dd9027bc5f57b969863efc1f6328fbbb1c8f2f1237382bdf13c01b1a68729fddb928b73a23e579b9d60d9f6f6a13348218f7bd20819e9a9293ff7c2489e4a69f98f77b12eea61bb57df466960334794f41589fc96261f28e7cb3c807808f18adf09c4fd3e6dde7500590712400b0d3cdf905a24b1c5bcf9a63134aeb1827d71debd7cc6dab84187c7e3c379847de41a796567144b00893d94b39df68efb733746b0f8028fa83640f158ed8b40bda609cb7f53436cd55f9499a6daf7662cdcad645e721b0813e3f4bdcb57fbeee427ae10ad2e9ac1e852588cc261603e8b984f5e4e94f3e97f9d8b4f6bb44d2b0ff7e9f93468a8612a24f0da13b94874f1a0096eb23763961a99116ce80cd3cd1ffcefc8ca8b33100cdca2f4b0091a4c05800a4a60914debae28d5707451154a325447d4cdfd6eebb9488225ec69cdc962f93b7e1f952ef5c6ae8f8326df8e362d6c1ea2efffd7579681734c23b637824883943b588a757eef5de1181081c07495c7c3ac01092c0baf4d648a54adf7ae347ff9c6359c213b49a81a795f64a14400b5a8fbdca5333b80122195d96709f8c9e3042c2063c8587e3ce9fcd1c3ad0527144b2d99c95cb1966b8c2648c9c11c1a30ad7c5bc46dd168aca9d4527466b2862991613f10fc96b8b225b8bf5a0c941e0a7a47ac3b19fa0f02b888ae93c6afb0729b52c1a3bb038a8daa25b73695d8ca4a960331a65267c0c13ccfa0f234134ae8696bc7846e37c744859718411a7658fecebf6c371d1ba114dc6d7e19e92e2bc772bbcf076fefa78ed5bf916c7431490e0c49801d2eeacf3d8e9f6bbbd2673c7836c4db574eaa25fa0626b82085ebeb8721e98dada40716b49bc47c77ceb46a40c6ed8e575e75c3f96c3fc186e328050d687e57fea9586bdefb1f29b32fba775fd5f7b2bff3f5f109d243b5f45516ea67de051c45719003d14b7940c4f5ae016faeaa00e7d9cf900309370f48f76973a6d41817cee190c4377c18e37639673936e865ca289b498a64f1457e8ad064151e87ddbea0268786fb15624ff1b5027fcedb9a1c7919856653a2fcd76f5286965c6b5c284691e94edbc98fd19cb81d92b1f11f9202464084cd3a645814e0d0568396e02ca72e64709c0fe891678b2a280d78ec435b5e65cf80faf27b67b31ac960098bc9f1539f5ddd76829adc8c84f529230d97a601ff8831dadf23a927826b169b4fa450678ae6876a81b05168381c21ead4a65a8475b657e12fed4eb040ce8e4358621e61cbfd79762478f948c4c98d90867d244b10dd3dd917c844f111f683a39922a2ed0c5665b1f40c17c21c4f5e34d4ec1202892fd68cdc390336fc7635f067121eeff5894d696bb22615b9ba04b08aaae208e70056b5cfb3c7f037176951f0b42719a1871ae12635ec3faa2740cdf1022a6c7597d0d09f243a19b2320c4e4d94d6e1bde4af0e310ec4796b178af415b80ba4780f045db65a3b8484f65556d88be28624466a675d6ed55844afc335a9b6a35c14d5218257b5bdb2bb28f481e5055307a4792da78ebfa5e5bb1b8aa77c55aeb27c515ce57739dd690ed3b77348150467808aeb64dc2252d8a8cd83222b599a173363ae9f40c1a48ec84e93c0009f2acad20fbf9295d03cc597e28ccb27022f861b8e0d895b28d597ead89ad120a269cfcf71567f984c1e29071bd6e4a46f00bf793a16770f899f2c5080287495df92945972b825897c96237b2d42beffe64621e9068ea3d83d6b75930d57d40ea0fc88dd22e5d0571ad8c181ebc05d0ffd8c7aaea29eadd323c57b405ca2c5045ff53aa3b12870b42ad5af5c69376ed4c128213ae66dbd9ec3d4444fad85a7075513bd444e0f8a7250dc0a3741f2b4af687ca3251e9acea3a5687e4748f00a06e4e490e088e40ce20b732a3e7ebeafec9a6711db1fcec9333660171aab313aabd25696dbdc6443e820a5f1ae43a3a9f411b321e0ce47ed072aed688ba36cc6052fc231427974a93e83d91d25ae8d9322abfbec95a875df97fcf56bc679ac7f062584d3f244d6e28bfaaecdd78c8674e88b55c2c97730906c3ed27d1cb97a1566b9f0f00ebdaec9019df914719de311e1a98010012b04db445539417487928dda744d5a72daa1986921f625d0282e94fb8e671d8bcb76380a8d475df23d3d60e7bc83e2361d860be83427592e15864c454eafee81397d5a601ec49a5fb5e79ba18722bdfd556f7978c0afc7bd15d0b01b2c0bea72af2383dafdb9f2729b2d976b71f28e8ba86b8c6e0bac7febf26b6e2550aa2810f2efb39781981ce990dcae355caef5f80f62824cf324f901c8011b404c708997a1ae19864e3f11e050959ec6b15aca471b17fd62a46ea7625f4e1b01cbe02b3a511a185960a715306f3b6658e3fb2fec74a1da54ae2a8132977bcf40759617e3094457ad059f36a2446e1f4745ca015cec3ad6f1af4c7c899d258af398b07c484b9040e249e0ec07d0b7cc1a4a405824a1e440cec3814da7af763aa0c42854161e3979b5d74de5a4449886ff8c36e22859072351901993ca87422fe7ffe4193164b185346dd82b89a2f7ccf60237c3bc52241cf475fa2c073fd639869f07a89406f75bf97f1d6a2726f1f6e065e382f700c4b13977b02e26542bf9608668310175ed9f69ef3004ab41a3994319a9fceb397b3eded87c3942df923a102e913e92d9ade92d6e39c7a95b3de92eb6192d5d3e2a9e81df30a9b807a51a4ee4e89afef2438bd146341b5b0c21b863b821b0a6ef4c36d104ea08f9d294e93059400bc9e9fa5387ec31f9f1b81a21e331fa0b96054e9c554f867dc40223af5cba662018930334467196fa3ff599e0dab1522c9beacf43387b0cc8b34f033627e81439d3f8fa5ee3729c3f57ff6e937d0952150ef75c728b3e6d67bd9843482cf48f9aa1d004c24977b56aa024f7518ec7d283e83ba8f7e511f9c0f50baf1368d791f805f52e6b8822f98d9bf91bee8832ec104233cc007700b6cd8d8852a9efcc9ff5bc8fef8d4041207a7795af176472fb0da6aa9a85f8502b70b41c2fb70ea286a1424e1c84537da386753c3c2a96666c521defd8be2082768e90f1109e677c4c836819cc88d2ae85cf5431a0872ecba05c421d0c3ab473c0e2c0f7c63a9fc55839a70b0b93e8e51c25432ef1032f8eac30e43e3aeb7df872e8a87feb378637f7104746ba3b77e1a6b3304ce5aa88ba42d8532bf064a911589b8eb8436b988a4bcf4174a2066e714d105a6cc8ece993df3a6d91551d858603c853e88fe1ad59cb64540e0ff0cf53da6258c87e5862b8d8edd13fc1e4713fd16f2aba3bbd356af62574d3c0139fc55559a6066d908551a34bbc576e5cb688cbff6acd00cf49cbe1adb5c4397335d40b0071e247c903eacc0e4a68ca3afb62e4c4a650d775fd5e4a4dab5ee27883ddaab2a1c0b5dd7d1998270e37ffed63f220eb1c6d9915a78c5cd2b3954c3bf0bfae030874e8fa17b5bb59c141046e4c724c2e20daef4c82e1306484923990bf7185a4bb8c2ec5595accc2e99605b865ba8dd15e0891b57da8264a71ab3fc267e1a32d2054d1817993d6b596656c65eb635a8cd0c2bd255b381dd6ca1d73753f20b59178cd1bda4d6a612fa15fa6f62419f5ca5947a5f666d32d790e8d60cd064373654ad147a47f401cc37d800311dbbd2ae7dcfddd1f2f8d95de384d6efdefc55e3dfff87a111195be01a1b59166d8016ac40695e8b50e30e34f1ab02338901ae5f101f011bea97f90386dffbef87a6de33b64b6a6db42cdb134d1505cea1aba117bff7927b6d32c4d5720c8182f699c1d3cd073a68e6ceeac122c96d1eff180ece1303b0ed8c254501da78a1c2f1abebf8e9124fe81bfb08c84469c200b715eef0d7ffc7871ef4ead83eaeb961d9602769c104f6d37284f4a7a5a9cf13596bb34fde37151e8df0f21970a3be913f52fcf9fffed0943e4fc59275d2291a87cbf3e71738b359d5b7230754b68a4ce85709ebcdc98f4e6f52e66a02f01daaf1d512a416a375982d138696206c89f31568c8fad663078d804bd53f657de6c7287effff7de84aa063fbb8e646cb808da45d12384e6b84d0adef87febcf70c9891195d08d4e6bf58d1a21ae983a01ff8a0c4b1a59970aa892722f4976139dd51304fd15b291e05178d4a63ac3655845f23bcce9e1ed9eec8026ec74da1fc3cc12fdf59df342160e1829fe90286226758fdf284e4d6e286b1201e2161c1a7534bfee7885062c1960d390de077d0ac3d5895d8b43af33c4287b34e5fa7841ba73722972d566db4d9fd28276ae28c3bef3236fcb4c6c7466057fcbb73ab9b2ff250df546101e259bef6b91b9bf6fe354b45660c5b05c36bf9e78c7a9c7269cd1ffc7648b285d729240b1c183bfe36c9dd348def7b44bceaff1f1b43ba1e94878722fd1744e24097a2bd67a760ecb8f31b1d506085028f63562b716581ccce300ed36f9b87d78498bce9cc63ad17c58cc6da32bda4a63132ea3cec0de5534c770c4facdccfb73f97245a2700929129aa3e774656b18ce47f44f5ab4a89ca086265493e1f45abdce1cb727cbdfe9dcf90da5484788a7b330c3d97d01c7bb8d4e051b6a87159079599b4f04b15e7f08ca4bc7cb2128d018c2ef5ddf4517ae5f35f05bfee049eff138a9bb8a717997c62ceb77d91cb9b1f517c0a5aee084af9f7e22b586e210597d33a5d392217f97e95cbf30337dba09ff5555631668a87ece94740ed49f475b82647209a400fba51baa9e12efa475ad5a456359be11f2f9e7180a61dc9943d5ca236b5f9b4cbf7fae8be445cb1d189c310ae8275e6b24696d1ba5a9b2c12ea22bb10d80438bc79af361c4066492b3d4ee12ae3b1d03dad55f78803a395e30573ccaa678c54cc6aa92cceb5d90d5a90d4063f7794f3d111c8a413178bbe4bdec5937e668268f2b3dc8fd5065313795b6a25167e3aec9de7c9bd1d1b10b817bc2c34c375fc71f479d3051bf6b562e013f9b0f99c2f67a2278e4cb75a7d2be0c2075fc8b5f33857a54ff423922f4acd89f8ce79e3ba4fdceed7719ab91fc361b647b79dd671175dac08b2e50f0968619bac5659c591e35c8f6d3e9a935b8ab8d5d82e0f57bdf9fef91b9fd6c0ed88a20571c619c9e5eaeb955db03e94eb2b1a435876d38f8f767c4d0366ffe8963e8154ab042fc94f4001a5397150b12e169d154930ca42980c41945b31025369fc40b839c275517cf4268e84104cbb83a5e85478d22181537209e56d0d37fe4af4d162ae371aaf6f63991f8233d77dd2a9d2d66c9391cf7f2af6f972b82237780303ff0acd31be0bd5eb1f37711868d430f000d4a338330d917ddbc8f059abdb0581005e13fb645f1af29088ddb3457d2259898c1fc54c83b94bf2faeec7ccb34f40df3511c88549703c0b361a7b0c3261dadd19f960e093f01abc235983152a9e14ca00e06d9cd19220170d90b8fad7e87b68a6b64611dce2ecf05d54ad871dd4684cb57330e5c0a8b0350e1610fbc593125a338fe97949ab427fb3ae97f33d08e12e4d3b74302481691c06fdd3ef1ea631b3cd7ad9ea1dc2689081e4f609959359d9c5c4ce268ec23f967cb2ef53af6f9d04029f05f7fda2d4a22646cc26cdafe5c0892012fa0a6753407fd671c1a59d73890f6481300c04121e5ab354448bb34d9870c1dc3d69c75abe124010becf4b456b444d0921ce64463ab12e933c971a930ccfa1678c86b9f7ed2eec857214f463b43989008a5c165b0c24cdfeb7e1860990b7135fb8319a7ccfd9a1104ff3ad6b5d1aa3ad51a734781d1e33dfa5cdd0bdbee9b26999a3f776fac94cd39ae19914e0aaa0744eb422e9b98d84ad5fc7b47da148c88926c916331a1d51c616352cd4111ba3f3d77949347b844432210af0d53efeb1ffa78d30b3820a08ec9913c171207c56a86a4e3ff364a4e8774fcb1c30c85fcab65f4ee540469e1e85b4f03a167940cb6099cbcd566e6197dd6f7110bf087ba164479c5fc203fd6c4661836b4dec8808a7597d8ccd43dc086d3c0fc87885546b21b1c58df4b1409267f82b4c196d93924b4bc5885fcd17d97b2b751791fe64fa21c1044c9b905737769917efcaf510a2b257a2ed5d197f536a009bebfd82c5a3c754fa5f365daf2a075875d92c9df63dad3f2c8dd977803a46c7363eb45dffeeedd59bd2fab8dea7a949aec59f3fcdb58610d1ea35957e249b3ffcf39491e4cf50b9fcb75815cfa3a6d7b6eebfc61e8b226b054f1347bff07d3c681fda6709ebb1f54b5a2eaa087c7a48ae7bacdd8a6012b8e866ad8e25b5d271d11a369462582a686938b79162ca33b8581242c40f8e623d274b6b030808daddf556787808c28148457a3f4195d5bdd4c60d8ab9d2add4fb49c1d5ee8630813ddd8d4ccac2bcb5d479db2f8d0756acac1e4b84db705d3fc54d0f78c16d343ea84d8e4f6dbfe64bd6ef6982dc2814e19dea1e8b442784e86bccf37118343ae302e95a26005381d43b4846e5873e1c815c18f456270f1c5ea4fb9601d01bffe4718745561397f3e132f14df213d42bae99ed8b13c4bea4fdbe026ab82c345d19429aaae2c00f78dafa8a9799486c4faf4f487c91b1f4f0de324b9f580989d0631f4f74cf6d63f9dd727a94a94db30029a06770f11be353ff5e71d3635d47592fdfb1bed6d1cb940eebca73c01c0ae17d7b9b803c7f9ed8b1e333aa6deb53a72b804843a31d10fb74375d378843ede6186da44ee83be5e8de78db31e58a1180f0f7957d4e21e9c7e5ef046f6e2bb291205ca674ea22915aa36ce9faf73a856b63e010be1d8e9f5924f6668d2f144c3f3f35614dc808101c0793877b3f53a7f8b96c29d2c7281f45450c27a3b6f62ff30bc51d3667f1aaccd18179dabeff0746117c47247a905a4b564c4bd5d1e5cfd2b9667fe657498026ac77dfc22df02398351d82f4982f7741a6fc9fc790bd3116b210c020d7941f7404a4733e950453dd04a8e9bbe48f3c2eb3ed7def4be2f172fc69eb551431ab0e9b530c4eefa7b5d5e42f7f26c7973f3eee7dd5c65becfe7387d9b2ee3f6fa907d19c2df3ec01401debfecb1d266eec8283ab30401d17d462a667df3e920ffe9af30e2259ed8967a65921988c96850e4786da3f083449086d50c02b9593441bb72ba7c1b66455dfeecaa1c79f021e3ec84c1b580d928a2e3901fcc05c2f43eca28fbc12c3c8a33a0ab94ea3e53f52e270c024494b9010c2fc945c5e11b3641c7112420be99459fdc2cc9fdb7336bd5e13882d6c2954819a04a05861710c4eef55992a978acbef0e040a0408c836dbdbe4061a366c36fc6068e8bfd9c7ec889af00e72a81109b0482ccf257b660ee7b5d20f85fa8abc3333ad29e1a70f8d2221f6989fed0a4951e3d663374e388ce0dff6fe171507e53cf8a8fd3c85db761ed251fb599d7d7515a657a0e2400f20497fe7f51fbd8ff9b1b8c67c145738ca58c57b2cf38506a243370a3c71fa9d5637a337855a8b78cf610613c94c419447526ffe84d9226c102d2f29daba57a780f1831d10264baac003bf984b3f47f18e37c37cd455781d7b3a6de687af9dcf18ba8086f1228f9c49dd73818793ff97715ba3dc67693fde399a8c6f0ba498ba420cf2420135214cfdd89011f710fdd80af0f288f4061b62dd24175967fc9045203f01e7ef298092ee97d64b8db07fbc335acde38ea0e201f83185a3efa0d87aece6dc907365070ee5dc5e0e7c5034e9fea5a804ef7eece687d6f088e7adee2275b2b888bcf0d510b3ca98d550fcfb7811306d8c9bacdbe6109c66355965bcf819a678996009a8e8a10b41176a1e368bbef54ff0a128b2e8c2d4a52b31243704101d71beac519ac3f10aead0e9ec6a5e4550fad8c54151f35e5e4b5bba53fcb20abc57c413a2607db266d6b5be8511dd1ee54bf7c83313acfa2c606305f0c701fafd50b58188ffbe11c71f50875c5e9201f520aa7f0b6a9dada402fbf6dc3548b15317fed91cbea69c8fa3a1f426e206c5bbb3f7506002824bbc2b834f28bbbc6689fedb14d6e14ecafa532d10b8f328a1cecb28402affe93b5664f5302a76bd085d124d656b6ccab8b85d1ba21c287d68a1284777de096be4ca8f89e98e4ed65404f5293f966d179300708f97c7c2ab961d5e1202afb389445add2318ae66b554b8d91332a782e4e49e6a473fb79e8466b34e16d8f3e4864a31e53b98840a65cb50c01c8030c7952966618d8a530cfbeb29764056f2c168efc00774512338169e582347617ba91bebdf60ac71b8371066e1b3f5573d3c5df5641f25b57fcd4b572f8a5a9c9b5fcc57ba58778653173d5fdf71aa87e8a8e7e8a4baa0002246c176efbc41d425ba12db094b8e64c706865931268c3330fad6effc93ae9e662d2b99ce5b51c1fa265005f25f15346528ba902fd30a0e3066b24608d677a850a14373b904e1c38412ac7fe332266b245e166301a26db75baff4a675aacfea15b9c64cb9add13b2ceb5b588cb3e7732a8546d53321002a384013319da24ae808d02b761033a6ee1fc57d430c54b4a0f8689c344e9ee9e5a383a832c54ae5e65dab3a16fc56f200970aef5687587c055e35a41d4af49dca9425950c7b03fa04eb8a665c34c1802e257ef3df5b002ee01a709584ce6e7c230ddade4691b50622da9d0f65cb4bcaba29b902a2da60eae7a467a9e71ce51632795416d279872e267b26bbe98396b9ea6760459fe23eb1af443f024f4b47fa5a0b4ec2766ba9e5ac8701ab033b536335917aa21024947d324c04057eb812753f8b77fcb0b0d490cbdd5c487ff0c1b916fb1620e4d6353873bc7775b755626f827352dd3dfcca7057d05e3db356f8519708239e63ed51035742498451878dc444eccd3ab5775b6450cda8742de5f380548f5e769fdab294ab3b4356fd91fbf0a8bc10c2e7ad3e2e55c92156d046af0571d9da3b28d460074e35478c0df8d7902e12012f8c61454b8399232538206deefedf20b0ef564a4eb504bc379ff4fbf80e38d5fd03f37a8cfc3b853f7546c879aaa6d21c99c9962555dddca49cb2715cc86f28fc868ee023dfc724bc89f075d7af1d81ee88bf4fada419e2e6c016fcc5073369c186f4427417e150e2879c86112c13f61bcb9a97368832af2a9e06f182ad3556bd93b434f03e8bc507dd231d7d56de8a0de4474318f9b7a613ddb4357ee4b37be0333d0f2c8d747ec185dfe7f69b9084d5b6b53910b01a74caedcddf79bffd3f035cb1d900a38739d7f45b29e9f7418fa07353f7a3ff07025d3fbdba2621b6c7fa0569e0a74292fa6d792af2b25f804176651387b73b181ef324aae94168a8f4f81d318f06f9ffd617de22821bd28d1b9017c6e7bdf0ececfbf18fdfd7bcffaf2bbadb522714c3d67e7aa12bd20299c20507abc7e2867ca6b39d0c253ab94ad8ccc02688fc7a887f802fe5f5a8c284a3be640362fa8af2c55a9ab38e923c4246603c39521a751d04930b043ad947b5022617dd64ffd8982c3dc153abce2937d5c544994cd69a2d54302e69e97a99e9f42ee2003dee33c67545c6b4e57b6284fff0344c7dea9bad1f014b335d7d39e2a240b6183e17dc9a0db7c17ba5cdfce15eb1f0733d059251e390353211db06071e909907af6ffec9e52e02eba2def6e40e340cdd5cf4dbdb1aa9c3c257cb22930936376b16ef0507963a54570e8f02c7e0525e83430889f33ecfb024ac44cca9937a9bb746a8ccf279e5d7f748d8558a774aa7e3f2803f86b0715d49345fb36724d06de20f8b0606a18451c662bd35601dce441b86ef1907022ae11a7c87341f62d063e5dfd6be5dd1225101f5412d340003248945c9fb9df7fa265e84679e600a1abb15c0dfbf45c050331f43675d8ba296ff00530754fe991a46137c216298df5706588bfa80fb779ba20a3f1f94c14f5832e6ee1afe190a1708c773796878f9cfd4b5a6f6ef531a31ce784f5d531c9ae1cee7c6b611d17f328e69953199c48cf902f5a206865b5ebff55090c66710084e8f0372f80c51419a77d12b388c00cc840428809a6b83050a2a660e3e5367badc8572db4ee333beeedb0139d72e103c9d9a03ed7bbdca9d9a06f9a17d4eb714cee7ed62df778772e8a81896454a1cc8f58c34e3fb74a60b19691bbfa238691c624279862ce434b8ac9e786734e2fcdd8acfc085860cf992eef37b5def6085accdf6f284a824984cfa1600ea710114949735afee0951e9fde04f09761c5a8a6e9064ab8f69bbeebecc5ceb070af858e9837c0747e4511542e21cdfc99556051ac94fa44ec01cb2e14b5641e5e33a229dc858246dce5339f74ec46d44a5e1dc8b45cb5b51e075c6b40d395126c5883bb87a4c62cb13c2b7d9a25a47afd0de4122c6d15cb4578539fa51a43f1cf6721c770f8fa4e41db134df9fd1af59a4b74cadc5c3420aadf2e02024780ddd1e320a1af632b002aac3635e75000feaf41b5758cf62eba81783bb7a3dae55af842964ef46d1747390d3f1c80e774e42f53fc760e7da7f097fc231942e06a91deaa8b8d18316e7d610a1aa27a73a58cd04381e30222c033c3205769b4be4de8545371a9fc4b2626b4b165fa08a7d0262ef024a1724e06077f1b54c6c4ee5dd9dc6f3e6a22b17df717326f689cd014fbf1e14800f14e1d4b04225288265d303ad3a167951599b43ae2d0b0a111cbebefd654926a4774eec0d3b97288167f6bb27e0b96a0f82faa8b2e13d0d4b8301b16aada9478cb8539d3da5797ecd60206f6295dac05a809b266ee39965116d346fc8aa4e2ea0964d18336412a14d1fefc763590d972acfd70e39900602942324b7ffb2142a1abc461dd50717125d06b953373f88bb64c6f72c4d5ba14a740d68733a11c9a22f386979ceeed2653c5d5b13b61b8fb3c67560a0a187b443e4fe5aadf7dd9dac47390c4437569894e779df2b5a7f57d6a4ba449ffd8ac9438e11fd3c88bd327378b4dc410fd3c2358455f1a9bec3241dae84b3ad5b6e847c370b47fe2d82feb88387887595ed99bbc1ce21dea7b189e98eee403315b48fdc1dbbeae94f72c9cce4d8a6bcf420c57bcc13265fdc9ab4954f52aedab343de063298f3ae6d2cdfb5ddba3ea6e27dfbc07cd807f2f2b817e6cea1f9be30dc53ed779730973c903925c69df96ee75ad45c9e01bebddd27b72995eaf50f70be3c6eaa85dfaa490ec1aed418531475c64231c2eb5fbb9b070da55a27191703502c632eff3fb6e8fdea0fbd0866568105b609b9806587af021b0e1f2f827354369587d78b5e7a7db95e2146887f4d4ce1022c670f269a2abead3b17199fbaf0ceed703e06d6e56891d6ab642782e7708917fc252d0aa663a8c3e63d8b5deb91f1b548e56c0aa7192e82826544aba0bc698e10cb4e9d1c0eaf9bbdea40ceef248bf896f25b40c7fa8b762d7572d197f4ee686e018bbd064f29f2dbffa32ed90726d183e05cfd02a84767336a1fd7c23663815093f2ead7620cb68f0760f0c2d736c9fa79322dd66f5068770fd7eaff4da3a96c887ab32f2d00454efd616e464a4f3518491fc0c24d2dbe0acca9aed5fdec2becd6910dde915dd61956685374929a46573a2dc0beeb81cf90f799a1adcd1324f547d5650978a904bc17270f8dfe584f6d3e8c67a959eb2ab7b952bab14511e45922a05547d128d1ec686145c53c3ddeea28a36bf219e18a95800f6231f833e113c0c832e21bd480e6a906eae3cfa060f8831e3856be25caacc7f8e24f9d68a18cc001d85722fa9463ac83eb58945d778c474bc1713df6a0b7a00877ca660ce3842b31f2540288ecd9f263d6d4c5d7739a968edb4aa81f7b945079434c09050ccfb2052492239d0e509590c731dc1ed1596780c94cbce128954f3ed4b5f2f16a280d1c5a0ed3ef01dd9ca46cd0d9930076c4a36f95d15e4734f7473e9918935b63e9529d79562f4fd9876127d95bb6c3400fa97d2b756856e6ca37a645c25da54aa1d785afad3c78f5763e4af2e1b038c02e3e62dfa549d230206f6db499367703bd96645701b1b82f2dfbb5fedad839168767f3ccde49841f8d901be51c2369ffc9b86a7b57b58ea47aae7996c80ac16beb51ec75a8fbe390a5f1d566c03947540a3ab66f7c0578ab3c5cb3d1b599cdc572d6e425665c1122b3cb52f82073c679d6f8ba987c3c56c3aa3d9258e10eb988f595fadaf7a8fb714486cc032fb53824922ec3d72f13613dec139e19c86297f5b1b80066a3e7c6b3d875ce6bdd0a5e4f59512ae4fb5a830971e8ac84609f2ebb0a9ac0c1dfd7d7e475497d42c11a7040ecb5b9e4f9087bcdf643fadce4ed61e6c17aca59ea785bd7f4f6f9dc3eb675bda3269cbffc212d62b0920a4a947815ba31b22a7068032609208024fd1420b86fe928dcfc91cdd7b306f70a6c75397da793aa2eb240ac0499aaba8ed640acf6ca08ba70110fda1c68839b2796014ca340555d0ea0bff51a555d06b2453cecfd1c3fe040457be16ebc0d967fcd158437846a4e39a6d094294b018a2e3ac7d59e105ce86035f05c938f245ee1d730298cdbd17c55a4213fa39ea93efaaf8e0212750ebd525b97b5eb24dbaee862cc7de73d9020c85bc78cacd74e6aaf500ccbb657a9aeeee9819824ef74f6558fb850570dba49f38a33510ed58d40eb5ed181a347e8815abf4e7caf5707b9257554d49f0f950c76b047664e448687285da13d0eb8850b5fde767208872ab4b66770be68a5594929f497c64a65d2658f007b70c17ad8e28ca3949400a8b369b57b595bd78a5a56e12c58fe22ab7b8a15bfbc2cb33c4fc03beb67cf206bd86809d09b7d98e669c3eb26ba485f8d5f794d0046fc360aa4bfab02a50c129b7b390b56414eea376526659e01b9f1b923965c25b1404c98bec2b654576aa70b30214b4c6070acb71ff7e8dbf145b0a912a829940c6ce1cb2e8da003060d50118ba6de5946039661342c445000c91f4bdaa7a343befae0498e685e8c4be658eea3c939322d3177452eb0c1c2b39a13045d07f336216b33435c79aba815469009191840ffb406c6fb583434b3643d5d921c4fc5408de8e16430590a4e6681532cc1690ca642ddfc79104b053e859b4645a9f9a1fe4b27c7f07532d8588b512e0124326405eecd1c5377b22619c6e24f29877f6f36a0fcac1a7a3f8eca614067a55ef421497d32506443d5b1052f479eb164e908172796206286dd576049671a6ace25607663c262a0a2c06cc0246b4a1853f26e53f00c5ee4e3cbf2940560545c9ffdfb9c60f2daa22d0b2ac7977676e6ce159411b00147a51a42c7f7b4c9e12cb0109921cac212b9ccabb2e7b10e17f570e5f2b2d95a9e511a246461eea60dd847b70645d1eb8536d01bc0816dfbe3317f74785ced5409624fbd81c53c49520c4f0ac13555498f97c38c1eeea51ebd20fb2c126875911478662a22565d50071a8b85e560781b0b50a49783212c8c65af3650693129bafbab400a3790e71d65a16d62a00cb3e64cc0b36f22d665a666f73e28f8accc080cb490b026795f3ac4a49995f6f364a2c1c8e4d2ab97c1d2faf12f4ab92d8e6b6e35e2512f70c67ea236a05c55a67ce2e34ba708f324a21ef50609567d910cf2d0079b6418a758138f755a1e848d198b9c1a763f244436aa7305272fc5a708df17fd982ea707dc08045b9a2cbbf2a8a9f3adad3bae3046e42ac0654b468366e2e88943cf33a363f29e51c17639f5cfecd9916623415abfc58928428978cfcdffac16600477796885a2e3eb75ede17cbd1ee4d2923df5be3e94dea46e47261ff987827c74050368e6acd15aeaf17b8301f60905ecbf50274d27dcfd40cec0fd189d9ec6fbc1c61d593ca8701bc32de304eea365189ad683195fb42b7c62562c4391b33eb960df11aacd957d11955671a741af1fcd1834ba832506110a51453387c7d68f049905550120684db6093fc2e376ab92726e944272f92c54ed9f108de09ee8b8fc8762bb926c04e459b476d88fb4b9304216b5c2f738def7589368849250026f14ba30e2073c2b83d8f75f702318a42ee8aff18fc6306c6f73e39f63671bdba214045c8c508936db83d8ef349b7b12aff222a08295618f1222b40a2f30b3626fb3930ec2c8445f902d689761d7b71bf445006e3c723c1a40a505198e6285807898478a5d12763015ba061bea3341ab38faf0fabc9b8b1232c2ac4c5a37da047491907e910ff3d82c66e3320283ade7b87a0fe48aca078952b4af222fa48e8a59577c7a9d49e0a814ea0b82d1db792e2a218c9a7dd92f69d556eac2a221d430443c53dfb9e766a07821edd4bb66400be005511986dc2ded50aa9fa4f5a4c466ed5ab0ae34a944f40a6c06d4862b848df4b893deabd4920a8f9a0dd99345a665923bf33790b35ce07b64b2e8f3f6d2aba5f7e75345fec4630164643cdc5f41fdbfeef62384947023cc67375febb2cc75e5c83c21424a5fe24a15b511f98f2981306628ee197baf77d7830c298e7df2744913a80056b9d040aff9af96896fdaa437b7bb82f64e0ce61aa06c4b6634c180a6b0da2d68caf2c1e633ee9cf704655f48721eaf962494d7cae0e7fe1cb00eb4d298c873bc6d761568e661fee4fa06638fc86d5cf25a607ed1d53a40109cfad398325e70afdc48ce9bbb6f093890f3967cc2f6d9b111b4689651dc209879d00e4e68538da47a9f067d0a11f1a0ea353cb93a4d182e363d673b0d3a59ef13ec08ab6c4898f8496a8a09f49e9cb728284b1844df4629c47d09c90991d20069dedf75f889fba4704c0963e27c7f9a4f6a7d06162dc6ac10cbc07f4fd0e0200f34cf26bc24d782d0a026e0e30e8445e9390da239ff4f00486f162c45b86da762ba40fa36896bd03b190a50a06b04d0a05ecc379014f4937e6c98429938084b45ef3bd2efe03d19879148692429ee40dc9bb4e476511231e930bf054e5474032daef52d61adde609f9a84973890783277862188dbb69a8613969f551f6228e2714fdc8df000ec92a988d1882d865c8ccf1ec69b034d2cef704ec510890e845d099d999060f0e96b5a10e88d556060745c338533eb7d0b838116e555818cf009735b56cbaa26ee2cf2b4a897de93cbdb0d1453af75f5abd20e2619e15369dee064b555ea1113a1e28c6e516ef465823c781c9b073600539376c9db1a829b1b0e4db98fea241a1d81857194f9f0e6e52a1b9b09c49f46c8b08623865ac8042a58eb62ad996032f86fa38c95a5951aaa39674f83f82cdae16468429e2c3282c63ddac98c38666b076d704dcb4bb72bbdaed64356a8c56000b5453fc80ad84021dea26fbc9483b0bbb0f993408918de67402877a453224672508dd36972c00a78adb2004df56ecef3139d80ea9c2c4099563738dc152b7eede3413f938d53a7c22acd1db359070d4795498c8cb2330a5ae21e56ec9d6d66dc590ff49c0441879826cdf5d3f5d89c8e8710f178e135bc1ac8cb24de7fd23d350c2eda84b01a6214a746efcf0dae462686219c3805ff66494ec4d69cfeb7e608d87619f9f3d5ccbf019e5d228c6a1d9a15d902b60dd4a6d72ebd7a0c0eb6710e5ab013f0613faa090afa930898c25cc09528b44030d2af60de0c8834a51370f849cfded966dbaa61bf04d1b1d4fe485f1122b3e6252513bddbbc5a3b5264c759a49941f7d7e214586ca401cc9d4d4dd1bfaaf32350fc6486bb0d22d0e8851afa22dcd0dba8f3d0aa60190169b0980216f34252187a5bad08b7b19e2a2f8e59233f69cdbe925a2e8bbfa635071575e30fffd6d2ad0dfc864ee86d9bb14513cc8202aaad7f82120d525b00626a906b7d852c41a6df1c17bf1073e109232e30f3db957d7e7566b7de694d0c673754298e8765a9d97976f44cb0773e0566740a1e0489d405219a1ba19fc5cc9f8abef8b7423862d2779b8e9abb19b109dec7b5079a253609afbbaba7879a03da8612221f0c8a2c4c3d204cc7ab3a8f1965374388a9f7a94c1f2cf022b3fb5cff8c0a35d7ff0a51d2f902a295714621d819aa7fa60c1ed787dea6ccb3961541a26769039be9e9ee6b7c0f1469ed8030f9d64f63094c4ef0502b20f1fa9c513e65e66829b1e7936b18e9eb9f7c180c80b025c96d49c22feae016a16650a5b099f2c0ce4db4bf5b86c97467cd37345403060825cd333909978d93e57a066ad6899acd09c5c517565202812342cda186889f80391cd41a0799d657388749462d9ce25138161b505fee4938ba17770d04c3b689eecd51159dc0c02d0962a71e14e0426f04eef5ff5b22d4d1cb5546b1a58b26c0e2c2b5bfdbe0992c51cbd7767600fbad66e6c5dd182681fe9c613d68f31fc00bb00b39c681e411b2396d125b852c2e0adc29c04541354499feedd46329229b3ffd412ebc37646075fae66368eba2e237ba646c61e11b8e14e1fcf9abb1495bb614d1d45390ae4414ccc2c991e6b0a1c6fc20eb4e2c3dce8db1998ceeb607321183e4ddab3ec49bd2e94de4965f43aa0de3b6eb7632f8ec3d8ccfeaa33a502f7a015d0b79681ca9caaba5ad6d182d27101bf14b5b0786cca9a3ba025ef9e5ff4df7598d0462ed92cd46a0bab22793148cca27b85b1ccb470b05261f0c3a39c4406de6fef7f6386116ff5b0b5b56b752fc8ef18194ec4d799fcd0c0c6f61ba22ebb374a01783dee533df1095cb6e91d775bf1442c8ad7ac447768f39eafd2058ab8e91e2604e0bf82e4405b386e92bff7bbc11f1dcfeccb2ba3470ee5fb8b9ef2f550dec104b991c325075686ae4284589c69a07ff948f9d9e4ca544022a7f6279ccb2ed352ad4bae9e6e65e9bf34e6de1941209e93bd3507acfdab285d961d473b7b16d9d76fa0a5adb04373962582c83098551d512a6baddfd23ea4181e401647b799c38dbb9604072d617edb9601cd7bfb6dc912f96f8f19de6a01e4f61806d986737a7983be290e3b417a45dbabc81dd355f38084812ee0e2fb66159fa67aa63efbbf157044ea181062b9a85d29d26de6301ede0d1c096a9ac16141850e834bc6905c6ce17e12c0096a28514463fc576be070ac037da5e30454d24369620b5dbd3b4ed6829d3060bd02b5a9fbe10b18e49eb926d1f2f6cbc714cf49c2a0046c6da30713d62f44dd7d71e53bd98a6a86e1f446c325bcbe1290d598476aa1a3426b62a7e248559bfa573d03268f9d2a8fda8138efdf7b7276ec25a51ed1567265414af8631dca963e38631e93df9e6a5be373a672760ac6cc6d5f30662dd7de7dc7a75784fc02bb9fb157bc3b76d9027bdd5e195905163149d795bbe36538c00287f67406191a462c6db3b3d62740d181fb6a7697ddce33c50bbe574df0c624085791db6a8fc3a482f651fb613f562eae59d23f3dab0dd2cca8ceae4cdfead67e6bd9b05a2c82b832e1bfd75c1cad825e7d2550b274276740889b18e5819529a98047cf3e73cced1232151afda058c6cfe5bdbcd6a230c3ec0a63b332769a30124806b1ab73b7945091b308a3c8c7c452a6ee2526d2d1d043518282cd1dece5b1a778d978ae3a1eab2b96352fb124704ff7a6e20f3da9a1a6123f4e984d33e9517949eb17da46825c5a83e4215446dae239a015512a7851632a3a202f0ea8f8b186f4356c6bfbdd05a87e0e67e78f713334998990ddedf2000d18093088372202e96f22ce482ac68c11d239c5076952be9548dfe642824905b24ceb58d49995ae0214b655630b44473c0db8b6f4f15160d936cb6179b43ddf380acaef00875f0de106c747a3c88d419fba00135e3dd579a71346f4ce33cc2d7a9dc1f1c88d2d585d74a98a63945003fc6f9ff471db7ca582098327f2217c099843bf4ad2f82e12542fd4b2900289a3aadf1e81c745db4f50aea27a196057d68c0e7d450f4ff72a460a512ca60a06bfbb4ebfd1d844c5a9c1c5180177d86d40efd6ffdb47310cd96230babd22ba62e5fcb879e39193a1abfafbab906f6b0c14fe2ed9f2f15e76bd84d2e078da2b61cb13023e941725d6ca63446eb370ef99098d3ebc9c6b2e5605a3aa24434ba202be22bfc9c10ab01f110e0c7dec7ee0673a087703cda24e68b33df6592c62b3aa55013a49306423b269b8db14ea2ed051c839ac3c5b57bd01d717cc04aadee10dd53e30040728e723185b9bc9c9b813fca7b9d8f0e06b665d1add0390f369e31f0034e6b7f93746407abddd81e54e05c8167e6ee2c21a5751680d6d64ce0925647a50ae00c9434c80bc34224273bd40722b3680fe26ed73a990f20bdfadd20612340a0f8dec82262bdd910175c53c457f4534a14351a4134c213965c8c5fbe9e776fc1abb9c9072af9616d2e934928cc6b4d46ce86f6bfeeeaf059e3c6c67b726f3ec960a74dea364ef2e607e276bc10512b6add49da43e47de84f6a1686cae93442a740109a251e70463d79bff20f6a8eb31238b7ad0fcb0f425a1bcbe6a83e1afd11173e365ab8b9191c1b70eb3fb979fe8a4f0c959993c44e68789a89f52b2bd3cf4d5a19bf85575a9c97f5f66adcdd24416185ee936c340738f68e3b4cf3b06ffa69a74a4d62b966b18387311fb786d6361b53a2d4ecb7e759011afa0b6ee86103548f48017d5d3028df992e21bd264b033edbb0a1f2f70f6323eca4a85fc15e5fac1d3d047fc5e762490255ebd8c0683976a6f2e6451325d6e08bbb8340a3cb871b26693c6796e268d926e5d54fa1a8ed277989e1fd86b892e152a106b2d6417e4566540040ab1ed099818015dcee788d7ffa55610d63a31507e66397adddcc35d9f9a82ba9ba4b5b1e0731d63fb1126b521fa7d758c329226f029ef6df9ea5ef787b25ffd3843cebec7b7111714e06501f4740d5ca2e61a24ea7f7b42d9ea8b1b38a8e001d706326a6015e3dd6f77604c0a19c532661406c4905a5cd5d616c483c7d1363dcbc505463f97652e08ba17326a1e807e3055e7b2d1ec775d54f668799a9523cdf8d2590f9bfeea4de6c2cf8c3a17334da1891d57a9c42d8185e425343f41a0ba3b98ab9a4d003e5d0a4f0109c5f04c6dc48a289cd85078539ef429297428f5061c65325528335a7b20c867f0ff38dc455b583bf1f4d83815e2a96eb34c966af1677e36d9bd6dc5ffa9314df9a1c9e5963ff85f431f4734ce22d3a8be55e9ac810016573ac31dee82810be687d8c0d45d439ff32c7eee9c34a55f6f20d116701b08a3d48aa2b99feb410a90abcfb328ee655b6f6f2de5335e95069c10613c8bdd392d08e77f629cf6d068b19e4146e5d443b48153285d633f9d1f1484c2dc75e62c4923b74f392afe401f215d81d285dc9aa5b8bfb6f43eb2633613a4539e1e5dccab933bd410f11c14853c60d2f73537a9821d230d7ea0c52f75ec64ce11d51cd4f19a5509c462d18f153d5a56a8f9d867827d80eceb02e7d439177a5d3071049762228f7d6d6af60f1ed7b4829a2d053e1e683cb2ba12ab57227f894ead70204618ebe08d246c52d11cb70f15e698302ef7b87ce31c5aad0a9090aad6589160caaceb93e8299f27e5715459967f98e577a20052c2bc96f5e5a4df606b05dbe961d90a68a71a55c31d8903d489d7078f8a9c683ed70d4352430478fc095c57ef58fb322560a1501ad71b809046a763b8c70a43cb983ff2a7a1415c6b07e991cbbc1a7445e0798aa6859735428ef049363016f4d988105cd61e3c9908c4676badc587b6bd1a26105057fdbd1e699b9a9b1f2b12c526c2ee279ca7dacaa990049e7ad63f0c53a9914b010164382c2f9687fef7b7af337077beb9d640a1c9d9cade1a972b1ab129efcb9fc912a52078d03f98cf330c7afb64cadfab2b93477788b52f3184fdb6bb6f712f86982c7c1eb2803a4362f3cd218e2a7ee80c7633ddb64b087092351ae700b38b5465a057e2e8efdddfd47a2e367af903a313d9a8df4dfe203169e7c0df1f881c4ad6ffe63d2a1610ab2b147b47bb9af58d3deac4771d64a9eb6e89e0b2cf20e683958653a18e49dcd69c16b36cd39034700d28eae67b15f05356c3f3d701ba69e71bbd9ce66395f1915f92039c0135790dcd492719bde78cfaecde9c6a93803e4116c52c67bae250e605796c7b9cb141cdbb8c85aea434e8388f9a84357182de00297eb62e88917fe1b4b5bab71fd839918ef48d6022a5cecbb706b92b56e1c9fbe49b9405a88a2584340c594bdc492908ba41e7479c479df6d3f6b75ff88a4b86ea6976868d66378587596ce93faa25c66a837795c27511c4cb3f6fde6091614f4cd567bab274c4993448de70f80044f008c76ce7174d4f85625fb4dea6f5b45a28eee96122f2d3fcc4ab02663687036bc3d9608e9ccbdb0773dade8cf4e911884d9f1572870cb913caa319ab42c45804a468414f3d40113d1bb04950bbe93bf4ad809274c76ca502b3c0e5db2172b3e172e239b5d163c60f578dd934100b62fbf009bc3d78bb31b4673d7213a46da687271ecac2d04d388653094dad14c81c147f4a49ee060f38b5173b4128b3474eb3a81bfb1f5846c48801ac068f0e3225a38184c1cba33f91a0a09c61160974ed849622312589a5c7da85de78be4768e1363ed1fe5218a26ba0905f6dd7fc7b111f050e9408adf80bd00f8deafae2bac60f19ea04b664fdfd9a24b9ffeadb0ce78db4a043b8f05a8f178adb10ba2232e30bd5d7cd80999be2cdb89ae1b18450a5a40a13373c2f232e3774c9166dca8eeff625504c8d4d5458d2da0db043a5cb190829cf5d090b3a5262a181075bd071610f1a3febc70b38e6858714508a25c712b8ca430709e191e5605c79c82abe3f5dcd156b99dfd7c53c0da886e979373e141cf8977ef2fd280df6c977a83838d08558e78546c3d0a93c57338aeac138c06c26172fc4fe4b38497eec5f834caa65fe4d5145b3048fec4f812c0f66b37ea11d201dd0029783b900fb21c0327cdd166a1e1c307c84364d012ee39fe04059112dde1ddf05454a7871238e45e69645dd649bdc921f060a2de7b68a8d7015350333450a3e5cd57187e5228cc9b7de5ca5d428bd61c9fe64abcf1b43bc9e335a76f3885a0ad906476904b1dac781fa9db05a3d1391be2daaad449cabdc483a79350e909847990eca042c538c4c83b74ea1063a47112b6af25ecc3add7cc6dfa563adbbadfc63e619d9b063a8098a819cdc45194f70bfbdf7901696fc0daf5e407784c158506d370564b1a814a4a7182e2509ea139beac8e44beaccfbde739b6cb3ecc6019af8ac6d115095cb56f039bc2202868f644755abc9c21e60cf48b503e853d535f417c9171757d716ebfc30520cb4648437f9ca3963b04c7da77e5fbf4f7b63ebe14bd113afee73dad00557547482ba7a5e0c46efd5af86e44ddc5332bb1403684b537f1ad9d7da06d00ce803b1934548378d1d06cec777b0befe9257e14d327260ff3201fafdc7444f5b15c546e9d55363a75302ef6b184358c678c7f6afea592d017abff6a67ae1df8083e75667a423cf2033b83678f2051d98edd63f56d3c5953351871486e5bca5df552b7f888f53e2d087ef1457f5813ee8529386587a762adf2c802f0767cda402916ed9586f5f8bceee5f433adfe7ac1119f656aa0ccc4cb046a18348c61471f7986b2e84af3353c60215037d5b1386b6cd95c5ab37d215353bdd321fda85c6637626f86294838f21b3bcd6bab439a592784fb83247345c51894b8fc83f39b5db053107132ee40090799cdc41900f577d627062243fb0f6ac2fdd021a828b48402c46ecf090dd94978fe11bde4d40d0f00405340280df5cde43f1ed2a025657a744e71c22d25e04bc201ddd20beb8eaf32b30f690d6fa9a1a02cc626704e8b32138ddbda631c9e9620d70a3a3e83280dfb1487bcb16c3ce81a810e1611dbe675f6555d123ae87217a27095f18b47b8cb58dd44e551eb4b54623c4282a69b88d54fc6e04e0a13d51dc9461a938f931f7fde18031bef785aa16e3278e13cf3dcb712a447432570cd78707ac98661033c6fb22fd44e6adce7fe30a1e308020506c5c73d25e0fe75814dd831155cd7dde542a6a4f1287dbf9e1ea79ea3dea1e78fc8d4f20c79ba0747d187d5a132024535fe86334aa388f762eca0e4ce498d978576f0307419e74c45998ae3e73ddefb84de251dd37bcfebb579b95ce8664d7056260f5bca0e3768d01b607c11321a2cf2187c2ee4f318c7ccf4dcde900b3c659727747d2ec528f3c9c13e76208f4020778d0a3c0c51e16dbe653346ec71d8cee71630ed69b4097b9f78cbabd0bb05581b8956dc853cb9a3707edc49227656060c34fe3f60b994f6e487e1b1047f105487e8898b30f3ea1cc2bc8e78922f2ae82126b7d7af5596316c4180f1e0a1bedcda9be7e82dec06e8db6f148030b832239c6b5c629afa53225ef50b4f02cd8bc965270fc814b67f08b76dccac8d8f2650da286d6845e603a608a455455ce66a02919faa01612c9f7535ba7fef713309fad078f2e157740116d02f17f14be0f4677fc5931c5d9de49b251811fa03ddcc4c5165136e41bae56a1d3ffe83bfc800a263dc6082fe2ecfe15ef5353567a824dc3703a6afa96dd0fa395758603a064dcfc72d8c4149eded1841efe314a01e9914faec47084272cade2bcefb0ef7b4d30ea927be12b1551d2849b4664d955a381db40757e530d7b4a3f6f86d33073ba4333bdb907fa2a3a63568b217bcd641b8fe6ced657055b31fb9f037f706094d1df567f60f39850a936d0ca4c81aa4532e987c72d30f9e59ba57406f7dcd1b84017affe2f9af56ceeb8fd45a3d9bbc98545a65bbe48712be9fe960c63a25ab6a6999b54bbac29e8f1f6315dc302541a060a3715bb2f91a949cb510e48ea8bcf4cc1c21768bd3d2a12d40d01489c910140c869bb9897594601820ed3f3feccd57b7b3c503c0d930f1182b1b1a38aefe13ac206cf910035ee7e4df6755cd09454b5b642d3a21a09040d6a0c42cb6721cd91a8c894b148c232ac224a41f697940ecb4aa220f73b001efddeacbb642d4f56053e67b2e4c560e7377047809fb85ac622c794c212b85f435ad6c4884e132f22c474768b73fa5ca69d763c78ae74192ab88f7c8f67f8df8ae381ced2769d67e23f6ed00d86473c003609de6d07a3d884a32f9ccf8684652eabb3dc08e0b99f7e7f5b31b83d2aadc707f536eb9e97f682e46509262337d1e5e17c627f8ded0148b15a6764708b00601e4615de3027212e4321abfa73c622d85317c88e5d9584614f4cf23680892c1c506c11a0908e7e6b793ca49191ac00038a7775e6ef0cd5f3e3c7314ebb16ea6698dba5e947cc808b48b300d7462956f6a3aa1a49db126d2a612b3022592ca24638010569d2e69d43843621e8ab09f4cbbb66b8734fe2d8df62807f20e17b21502f9052a101e44c87e5263a40021faf533bfbe313974b7661dc2598055c55c0c83a660f9b1417aeafd372fed6a202344e15e4c8e87fb0cca3869165ef0f36ad7170f57c09cfe824b671be17166e360dd040317fa65b6bbba50083b3d782d8eb48692d646700f431793e29d38ae8df0238a4f5625113e79b98e672130b4b8a0196464627e1edfda6146ec714f906083b54bfdecccd65223ccbd07fd86870cb4656acb541007021a7bea23027c6be2f6e0d4f91d98766f042fef26998b50f52a2674205d22396a59eaf2b8c71649a8e056189c0deebcc5f405355333ae3419941c74c0561774b0b14007ba9079ff9f40c4df4d788a094bac77f5fadb24aab7074d76622e47f28370887aea4c6d1dc87d523b365252d9efb86fc16fa321900616046ad41515e26c6f49d3dd3f560ccf85aefc5c48a04320019bb596fb3c901c766bfc86757f4725176382b301b2d360d9d120c16180ec60b07436b371757f4e824d53132653417600e15775de6f1c8e6f36dd5f1e21f71d0f50dd116a059edb803cb789d03c7b431c0b003ee483bcaaeb971b072382b703b2d761d9d331c1d67a3577078b18789a7b940f17a643429b7192d3c649b89951286f1275db9475d55cd21a6796a68ecb0fb5776e0e1eaf9f2a76d808360ef6b3c51f76bf1d768c7e56df7d677018c76ff10aaec414d58fd882dda02c230ea249ae1e0d1b886cf1cd93d5318c4d7607b577164c8b95a819e4487e99da2763e6a6d55f4159f66f186092d80f93a8dd4e9d8022f075cc01b56d424518bf05fed964fd8423cae7dc25478968f5ae8448bf6134b1d89731a69c3ba730d505987a8fae1ee1759272f6c5fd112b33a4ebca4e122ff67475f659e562a66c84ef9a6de37436a4acd1aeb5725f8c6831416cabcf8c4ca3aaf2814fb5a7a10e6f94a77789d01d2b71fc9396b3b6d38003be261f7290be1ca2c1018f432c0951a0f1f2a9e1208558e4563227be3c332da12d26bdac7ce02edc29c34da7344600448b04c3ba059dddacf0be424eab0ef2cab9e4800eddd247571cb18ff6d07d1d4a2c01363d6a8d19872d748e29cf9f26b3800310769dda6ac68319c5263ab0711c9a0fbba4d271334baa9739e4ce4450e38b4517d572498585b54613a9b5ff94ddc35c1ce11d13f3eb60332962022318de3141c39d000b03d84039d9c00ba60b676d997d99223eaeb3fda3f2ff36f3e0df25c58e4976536b8b3771073a59215f4aba9c2e3e1713bf6a659c9a06ae6220794de25fde6555341e00aadbc806e442260faac721d9bacdd710e887402d99dde28284ac60dc583f0d36f1fb2aa43b8dba23581ddcda33e26dc5ae09ad356da98940681fe519bcec25aef6132e54087f437ab9d941695d9c92adf9d8d904e15246bf2d9cca2146a29b7738f71bbbaf0f9a44aa8564d0e717afefe421fae29a841dd9b1b7f6baf1c1e688d7ed23f47c0c8ce5189acdef3422ce7c58b01177494da04dd31ce7ad3ccb9f78ee1e125d2db4414f5d15c7f09ef036ef9f2e94a0f80c402f0264d44fd9226a56f229ca6c576e2ff71cb86441f1c689b06b8ceb0dd7caf85b82e3a9efbafacf34591dd73d689fec463a1f11f2a85349c7294bc99a6585c1032db728cc08691d99dc5888f081601243ef02484e938af4ed38bbd6bf0d349e425800a2e424b602088d67c8a9970b158dadbbd2779026fe1e877e036eeef79ed82f258ad63cfe5006174ec9da4fe9d22c0883be069b9d20eb127308d31a363b7844aa5c3c3e405bfa6ac2dc5ffa74be0c58ed62f1650208b0cde362cb9708578904628c80315bb0d521f79dcbafd177527cc690c702d9a16a193d0b655f8c3ab92bb22843650dc74167205404713f6ea64fa2d0b70e8a0098af23d6ede4dbe26fd38a02189654ed8c523fb3d12bcd3665345a071c6159594a84044726ca62012d9547fd9c5be115c85b1b8984ce0713415773c0a51b8e135aa4dfa95568959eddaa3266dacbd5fd106935e285a894a9d7d0a9e5ac28d63aa3a4ab7470b29b6e1cadb0a3111127f96ded162420edb795c13991dcbd3971ada597a0a4f0e895dfe518776e1e9b61939fddb0123ba5d75501ba1983b5711894ad4a4ed17edcf5fa9a442930c2630f23d80068ef6645b7724e9c3b0f1318a0ae8bc3a7c02672281edc9b16d630fd4b1d84de422a783b7ffcd758d0b04c684b4854a09b2f0a39470f2555c858ad088f6d57cd03a9e676896510c15cbb44f2aed2ac5138c3522b54cba4dd5a53bd5a02f34d40d61f254723b05557b0e291faae9aa6fc056b6473601f8a882a261567979df3b08421dffb10ca6296e84fea9f1c5bd3ec6d011bbb6f4924a73f39c3ad1cdb011847ae3e9b9842aa654f4edcdff8a63e17280597e2b2aa5ffc7a0d8ba7b45c68dff41ecc6fd99c4a75f56b616d9109c7b86978b11ac9d8c1a4e4ae280b9712024aabab8b22f5f56304ea6ab78e6a3b029d5c0a2e61234463fe89506b44a4af04fa3874c86f6ebd0ca96fabb25ad8fa0311906e00fdc65c0785d9e9a3bd053c9952e5a34ffcc5d298a35cec3cb9562123a026e8f1e4e0c3839cb042afd09d35ecfb25c61f332521359aa7f6c9240f9cf03e82d731f9f5f487c6352aac0314d3021adc555f5d30522a9b0ef1e28426524ca8ab663d160dba674e3ce9ae2b07ef3299aa251505685066cfd96aac86c2e88aebf742986220d1c260a817bd5a040af1300a49a1878ac3a36ee8c6b98ea1cfd6ec45363dc2c3881006697befbdf79629a514f205ec05b305bcc1aa6f321d9658d2df45ec244bd23699d3b4134d6c46b5ed88924d4868a64454341372f992679b6c33da8e6c421b0c969c6626d995bf139e127a45f589e44e9cc9694e482152cb9d546772a6ea3f7da6cc6936b02bff15c3f3292bb72935e47b20a7acfa2f973306ed4f6304a095181512d28c9413261f274c4cfe32605e5c5a586241b11382fc6867fca9e850f00d7f15d19fd819234b125144900aaa3f92ea7f1a8d6a5852044be2b02bff203e1dc6ae8010fa41142f96e462497f1fee7994a652ff2c9a5ab650a5a9e536096911c36215344755152ad86847a5763763a2ad7e63d0d94d6b9f20744b4edcbd930e688082c61c6b7287059e1d9511d485c9c3d3625848335f3e561f17cc916e8ed067128428c8d177baf9afb95bdce11102ed6f74706c1e4f3c7ade77ba59c0d25800696767fc4b7e17d072a1b8ff8e1dde9722eed0817a17e6a7fc875ae1e32aef8cb747d5c3538b5bed10d4b7f1503c3d288ebb33de7fe20b5c5346158d0951a211954f51e93fb15869a7917d5040594dfae7657ff81e3e2bfc920c59dd0a47f73c4a6b18ee0afcf04330f47ed206cbc349b2bc479c26fd6f9af45edaf116bad5dedddd9ca404a9cafcd73e511f9c73776fef2697d58ac024454535a31e5a8c2c94b6265ca9d53c218618328218b80bde82c80b3943414008f1d9284dd6090e2d6029bd89113257152aa8cf76581097299c4d66a276c9486c1f765de735c88a60f275953b13a9b00d3336628193daeda4b6f3a6b03577cae4c632c54293debec6a063f7919055a8a0fdfb251b19ed380dbf7896aacc7369ce1d168e2a3f4fb7542a03d134bc03ad856e6dd211231fbe823f5ad2911ad42621a63a7b5ddcca335fb10de81ed5ad658afff58d41474fa401dd2f3d5a0c18f5ccdcf4fd295dd0929b18caacc9229f752b759310e8696fbeff6e44108340552b8c0c60dfe6994273543e4785a69df1dfc6f042cef33cefdbd7f721d8034e15f0555a54a15248814853535393d89432a2787ae2a94997265331bf339f128e5fa94923b1318d59bd99a8de43781f48d44bda08e56d14f6964975eeb899c29c4fb8ac03dda4a127d5b9981e4dce9f58932a1650fe79b58ca4d2f78b240ecdefdffa8790eacfea968f9e4769ec4b560a9e47e79093ba4944c84ea89b34645439e6349e47692af54fd24a52c7d6f4cf3f000fa9738917069dd58529764cf56b117b8ee4bc8c2edfd3f2348a501dd7e1f710ec979f2c3465748a1a9f54c00a1d17957548175dbe4c81638f60046d7997f7173ba6ba89fdfcf21268f99751022ebfbeea98eacbdbb467e4e56d34cdcb4f16d2ab493a6be46efc948b4aa37e98e73c75ddc19973ce39e79c5d4bd7c9a5630a99f3873961384ea3e226a7a2f2a8ef49993eb5e5e72e94da32ba5646fe11631c63ffc6719a14d88523c37666e280f3e7fc9df96541b7295a4165a6d71c0d7474c7409949e8349acd8ececef8cb0826b0d32c74eb7bcfa18367a88e584644cd41d5391acdc66667fcc313db6c0daa04c28279192fe3431aa2ea05044710550fa8f1345ef532f2a8f134543cfe47f8df9d5919550b68797e7e525fe8ba81ae726056fe960752b728288bbd33a597e2400a1be0cad230ff29fa80c9e543661a7f5ffe357e5ffd32aa1ef05fe379fcd7a8f13d22fcd7f8ff1f7b667c8dadf1e2f3f81fc71ed5ff8b63cf911cd5ffd813f335c67df1c85166c840cb55a25e8aa6c02e28aa964b5bf958f8de4029632c4fd1b2352c5ff2104e78e28c0354dd405751dfa807bba0a7ca309f82498daa1552fff22aa4c66d52060ccc7bfff240eaf730e2e732f234b9b38526b75a001c3bd37f125d402cc460e0892181681d4ebaffd00474541ae2be4610f71523ee4bf579b5db978e163398a63fe1cab8b8870c031428309cbeffb3719ae7fe24daf8f046da7b11d2041b279430734300374455f8ac07f21280a80a6f7c8e00fec6877fe3c6b36ea0f040588fc2e7b01e85f1c71199ff71c2b364c61cd6a3f0288c3fc86701b9210001bc0922eb4f106f3c29a2f0366666666cbc09e30ff26dfc8f137ee68198f0404af89cd597f0fe2500e04d187f98f000f81f25fcea81bcc22e4124c09b200ee04f10713c2916e00b20aa38a44d0735e941429b6c9b55ffada85ba51fcdba45f4bd1f756bcaa6d256444b9739cc5d4602ba7de92815168a0afb44856dd2fb243b653dc6e6e019ec0d7f0fdfbfa3fcb04b363be34db6a66b939d014717ab9e8630b963d89533d9b08e01f1a7a880d5324505cc886398f7d33086a1612a1eafc2f97124e75ba972def3bcb1c7cb540dc0717df58d2e5f398f8b391e4beea1fa566bb8bdcb33a5eca9dcc8403be33f846e23ce78d3e4d65b1647449894c44ec0036cc9107c9061a526fe61d09295941aa502d7fd2a003c9abc05ac96bc05ac763e36af79881562613db4ccc51b610d1bb94993fecb83eacff15619a5c29c356c14f79d08564f754c0bb5ec09a526bd95fa951c1c42a78f4749c29559d7d1a36b7be609db85fe685ee84f6ca157fe9c98819df1f7440cec0d1783765defa679c2eff9fef43de02f9367e4ebf7449d1ebdf2f0f4dff784a7ff9e47f8fde9797c7f3a7d189efa1576037a5c5512b45c261e4ea77b50605b0758d27fd4b133fe9b8b72bd35e91f9c1c96252519aaaeba494900a102cb8e81205210c3d49834e121d03b2684fbc42488ea34c94c63e11a93a6a1cf29292a2a2caf32aafa577e5f3d2e9f32aabae579a47ccbcaab7c4fcba7742ce3ae8cb4855d46d95c79069ffdb949b7fc9be55bbee507cb188295f108f840640da482a3a3de1f48ff27d3e4c3ac44600625163908d5e2096419d3f1855ef17b3bbe62cec72783944f797e1ce620670939978ce4a4b20e8bc5c2c961d96091a806a3bc4e932c43b8bea27aa139ae7d7aa9c7acf2ebec740ba6f2c340e303d68c80a23207618450e5e7e1b6f6a1f2f3ac80b29af4b1355bb97befbd6edc1718841a89fdabfb7e1b4dd37127f6e895b7d3640fd761b58d6e7d651f652eb8011353122d60814cc935a51a55e2d7f62f5f4197669064ca508ffc31095ab23c2f06ceccecceeeeeccccececec3f4d9ef8c1120c8911c90d03bcd9d9bddb1b8b203e3423f18a27962cf919829f109205121a9ccc40d4440a2366109a2205480cad00c80a211560b14b8ea2348164288a228de44807283baa7852e4480bb890a17a90c44fcd071b92340144d4440e4ba408c202206a53d8c086fe6a30248aa1708a2234253f0005315bf2e467c8cf2c92439325419014418208dd6700ad0ea9adf833ede73add15ad6eec93d965504f3407da64044db5251d74380ac2c2892896242931028a2555bc000914330025d54cb08276e2892f7a7bb777bbb7677bf7328e6ea5e65094a41cfcd0474562dbdbbbbddbbdddddbbbbdbbb35318a6c3e0b850c507a77b4df6cbfa3cd26de6c37dddac6f279e38dc51bb6d971c3db363b37f34df3f6f6762729a9010fa1fc2bc3738c7065ca19e379a9909190883890ff78fe333dd2c53db72ef315f820f8a7ef091fd503fe49f56d2dda6256dd8af1c7798977b12b7f1e5487e24cdc97ce44c55951b36e0d6d6b386762695a881d52ab25252d13063000498ae28c192b2bfec38d2de33e3128d7909a74ee3bd4f729323561df09c249b757211cc1ef1b4bf0bdd1d5a40df8a50b649b19edefe19272cf7395bf837ade7bef5ef7fffda2bb54f7dee55a66eeef7b15b67e63f879cfdf89464eefd234a7e79ebacb5bd79237c30a8ca458b2e1081b64d58b8a8a8a3847c7b89bba514ea44612edbe8845ff6920224affd91a21b666bb695f9b118d8b84d0b29b98748be35105ee69547d5fe2201d107eb79db8686b9886add815c91dbb2b716d0c42b92fb9569980231379230d328fe6b1c744b4d3149a327e9616626139da1a2eb6e5c5b638116cebabc1c8b652dedf89587f626b54dedfa1e01cf4fdbd880dc261dd8773e4185547a2820a040f41aa7f87d151fa07953573691167fc27a69e13617e135f9e672d24d4b3ad49a9eecf21a12b5f6e34baf2e55caa48ec846f30f9ca7ffaf00d26a698524c89c608ad168b3565b2297317b896dbb4c9362396d191c21431e651a2ea19899db0f44c8414a1991251d14c28e64b9ecd52336488f0cec4d433522966f2e11bfe2c4c3ea713cf58624eb3c9b4d81c9b11cb268bc5e60c605e5e3ad641ddf4662e2d2cbf4b61be9a49aaff36c36e22d84d86b186a5d964be82718ecd886ff8a302375f10a8d731d833099529e6e8ecd6a07e64e2d6a854ffee616bb83fd6e4b83bd3429a746ff6a91ca549e6906833b1c307f2f2e7ffbe0fc71fdd7f3fc0f776290a98042cf749d79f9f213fddf7ec13efc1b11b7f80db0528dbe709a862f04fcf237cd4d8e385370c68d7bebc574ee7ec8c3f4369928beaf705dd4616e99afdd5e0ce35aeb112d7d6a64316d25ce3a52e7f546ee4d919ff79946a22a209e7740bf8fe5493ffdc6ca265ea26f5a38afbd2b5286e544057766d0d379ebe24ba8d3adea6d3f188a3d3e9743a4de634e93839364dbab7747af8f42ec8118de3d435a2a0dd77834968d7349bad112b5d9f5f14fc83782f7f478d3a76e6fb8276638a8e59501f62b6851cc303cafd4682ef32ddeacacd61836ff89f3e9c4d22c0726d8db73cd82e7c7d5d8532154b20d57b70c7b9abea6f8373acf646006ad7502453314dcae040b9ed8659d8db5077aed2d5bc28540a503420f1135b33674a093e12c40e218bdfebe8967faab7a6605229a430bbcbc36c9ee3f2309ff3f2a95f9787791e2e0f33aa1ae665bc7c6a54f5ef4b064c932c1fb67c384fa78d85d296959516951696efb422d2d08517683d3d7f8f2728941304ec8c3f8b07d81b2fe28dab6b580f964e53fc0441c50e3f4d3c7952cbf4459d7329e5f5c8d3e4e4f131392e683fe9abb94caf81e5d91a5ae7b7b035f3a7d75d6f403dbf471e2ca83fe934fb9aaedaa3aa7ef5b301e5c61f996c3184a157feac49a2a29e3957f967673ac811184d5b88f301d1b32e6a1943018202e463c856bed334bfb8891d08317bbd66b32e6a23f07fb6860b4f10083f3c8da2e72b70f4888a7ad69dc0cee76ce65238773559d433577fd9b36de49f9db9b1a9cd3c31361c20f8295ed0a288ac269bec221a6d224d21f307e6d3640a3893b6046d9395dea4f96a095a4ed884398d7bde37c392aa3fe581bc548d5219fba76ca31a34977a3661d2644d9cb48954fd5fcc1535bbe8710a9593c6cfbf094d19bf50b7d8f368bb029f859a94cda029e38d43a5c0db269b42e537e9a22f35e94bdd2a276c0a75ab74da1c72a739ad5b4bb37103fda269a949f70eb717e107da2f739a09e3718eb359396130d50ae1cf9f4d544e581b9934186dc2605ddd7fc07ca1c6d904035afa12adbad3684bb425da52f5e762b4745a1735e9bf421335d9335a1bd168b4179a2bb139788cbde17f7a7f37da1a5e62094eb21d25cace84e015d33b5117b05998000a190cdaed395bc35da38c9c9e51356c666666661e4b162ac1064110fcd0719af410f652056511fc0ec3adb9707442b25b5d99b9bb9b6178a1f3b156734078cae9953f07e27c238b6cb21b6348b7626b38eecb0e22e18ca3d3834611fabdf7fdd327f4f91ec461f38bc27c4f0ce2bdbc07c520decb27c8bf7c82d01b042867eafcdd0294ab98ebe58de2aee602c6948ff499d0d92dc5e41ca8baefeebe49cb5630123ca33d763847dbe0c2f6dd871cc74d1f581141dcdcedc4af9ab3dddd45207377779fcd9b37770af72278639962eab123b2d0a47f221d83065a0c4124690a307c50aa0205330cc1233aeb3e0f5fdd75980ff90816b63531b1ad99df0b09e14043aa7b91128e6d0dd7fd37c28c72dd976a1b550ff01e7c1ede83e1e63d0f301c55db6824e5f7857af067b5cd27e6b0263b51b571ddf6df7be1d8037aafdac69c6f546d1f760f82dda8da461cd49f3ce63029e8fcd261dd7ffd4593ee305fc5be316837313549035af64c24a2a5c3981cd6ad6d8288a0ea5dfd55a40d87910e837143ecca1f89fe61a2a9899734a9c32322adaf4e25082ac776c67f08e5d1c685e49afdc1a07bb7fbe60d04b76d034fa80de4f0b481fc1bd8830a4f1f828f7a1ee0a3c653f827149fb6499511dd9ef3d8fbf80b41af1b59a4cb0b9237293e1cdf0a9acc24740393d0fe44564fd9944da139d4db9753c6c44253c6513e1aa8ff2e69d26bfe7dcfa32379edfb5ab7befdbe5df9f721287aad919a5ce2481f7f1c92d71ca95bb56e95dbac2ee99697be4b886aea085aa66ec881fa6fdd7ea8032c00aaccac270d9b51032d1bd6b186354109429747fe1f304292c5308ed6675d9e688114a5f881996b35a41d983908a9492d46c3a0297ada2f29cecfdd5d13d0fd263a8201121c363b6e6ca80eb45c9a0dcb85c4ee76b1a9269ba363aac95e124ed0316c32202de1e8baaeeb7e7b9bf6bc6e75dec6799bd76ddce62c1da5efaf29d5f28774ccccbfd3e4bfd840cb55e57fb18167078784176c8d8778f8197a9be69a060e9479773218364d34238872111045b3a259110c4533a2d98ca8685624039a01cd8488848a8c8478a1fc30d18edab9e4ff264926654eef6f83ecd6d25411ba35cd02e367cf903fb5710cf364a2fbada496293545f4f62be02a2a189ffcd80e0aca485d32d2f6cc48ed791cdb5533d2116db78924c4b4a36ef5126666e6187b50d8083f0943b48f5033d0466ada8f44747fc4f184d6401032d2cea800a41af1cfd95e3efe08c1cbe5aba01951cf84d0b2675dd4b396b5d00d347eb2240041f702e1ab66f469aa49268e8a08b978d3e4eeee6e775721039224e1323bb7cf8deb3ce5846e935bf3e6ed9f8668ca555325fc50c20f5984ac9202ea620141f73dcf474f8905eaa72eebbd238e4e4d87524a757056cca9f5eb34b7e1e8f8ceea0f4b70bbbb2c8fba76b89c481d22bf9c39915f8baaf9208a154504a55c43d4c7225e607676677766676676afb150e369a106456c8a2390581f77a03d7a23120b78109e7f1e8f3c9367a7c9de259eff7f1e5fda6181679b3b7ec33bcdd3c26c6b1ff3a9d41441d496b400fa82871f9808a5bea281f2c840b3f907887fd88128a514e88789fc004d77ff719afe2939c63ecc3eb13f516f7e6143bb45a98bb5a36f5650a9dcbbf8a09df84d6e2e624c933d95e09fbf7371b04df7418fdece30b703fdcbf4b82bc474ebd4a44d7b0cc29529d746b7b6da58afd5bf2fd336627ab5a586a0278f8996d45bd24fb57ca1ceb9a47f7b759630d4fe90674bddfee6474656b7df19cd48a86eaebad18c92d4cd6773fb6fefd2adf9dbafcc06841b76288285926b89134860f1ecb25ed014093950fe0ee830ab22072fe020ddddcccdcceb62c540ad20e2c4122d6214394110314c6f6b31e0d06464440f458ab868a2429644142a9210516406126858f213daa0ee7b1c6b1e19c6318eb14f73cd6db1e6d9692a22abc74393a7d960fe556c51cb57826e1ee7799dd771dbb6b9bb4fe6cda793208313473b14b5348184431bbe4e23d34bee73415dac19ebc00721eeeeccce1b4f66f776253da91d014612417c3cd07dcf4ba57e64f0191181388c37784ec42b8a9408519188a00454f480c81731081a628914454a569820091a9e7c5794a0464407198d99d99d7dbabb7378c40a21b57caf1ee1dbf438cfebbc8edbb66d7edfdc260f68b948373898210521995008a1b933cfc9734e9f93594da8b8412d7fb21b75ed535a9951f76f7cd53a9aec6e1860e4d3344ecbe9d636418488466d76f473bd719a6daf69a71a8711ef594f4bc5a880f21351e0088d2882848e5e30272087a39a0d6666f73ccf73f6e9ee9b3405915aa650e09344b4248908a8d5b56c752d5b2dce61b444cc0aa35aa66642c4c2f6be267a33bdfbbbd605922ddc87de6cc9bd8f364d36c77936dd363b96f3fe9bee5f990e4258eb13ed0889d6b414122d6c9e328aa0f375b68679bb14de4057b98b421c3d7030b033fe2a4ae8f6b3396cf20183073eb035cba1c0564bcaf3a8bcd3dffa79bf4223639b9a7cc8f89e948c6779fe1e984f7d8f8c7f7916984f7d0ecc987a1e735ed8c5260533aef7b7fc0b035bd39e4baa49199514d1d5e46260c579a2a48d20d06d3261b174f7245c19274c4b5b33756bbde7b8aedbbca02ed70a3a4d2ccc1d1a45481a8dc6756291d3eccbc325a7f17cc543cb223cedd74bbdb494fa9c7bdd9d4be19e6b7323f3cfcec0bc1bb613ed0889464b21d174b6c6bddfddb1fb1c705c5fa57ce5cb5b4a1982da8ddce6b51729c272eef771db6cd431f55b3be543433ea55c4019b56c847bda743f25e81c3d1fb706749f3584ced5a4ab28a1deced20f1ffefe3b3c5b73aafe18d89aad66becbd4251c4d93d35b4d3f2a45a69629d269fee43852622d656a7f7f9abca8142e3745b9746846020000d3140000180c06058321915840281c2d7a7c14000d77984c724c98c9c37112e3484a29638821860000000000002a008188010df3fbc11416fc68e1939ba6d428385c039439c70c73e9987a22a438b8b27cbd3f0ec0bd2f1f22d8870c8ec036211322c125d046ffcdb2a9682ecfd7848c359941eb62eef31ea41a0e9b0f22ecc16e6be837be6b49fb4794791d7be959424e05a7ff7975cca5eda5be88d77d379a1029b74aa3b986c2e6ab6052ce5e6d389b260c3852d523674af5e37e735140f685ce331425c46ef50458db95b84efe0fd76345e183d6e036bb9725c2e9d85b0a114569fb336e135508a236340e3d4f9a84c68fbdd4043d39cba62339f6697f30b53d7440adc6af45b42a9ef1c7c420053c20e4b87035ae92f842a1980ca84a01b4146da423fa5704e52259f53c57affb6d941f5ca24f58482a051301dc8b753579501af73808271fa9c0c101de25bb1341a86e21ba0df56907a5f7602ee0ca6f61158c2e1171b889bbbf67d5decbf929e574fd363e6f34f6f033bbe9d0ce6ae59df543f4b5ad0f5cd38eacd8882e9400b8ca96134338d0060ed4598b28d11be4b90407759965c2031640a104adb086765c590900c830007eaff2eb4dc9aeebf581a4dffdbfdee4d2df10eac3c7f2dfd6ff44e8faa60729746b02a1964910da4b533abb72d90939ff7afb5f288cbc1bb2c8744846e69967ea7750d08d87093ea4586b234ac576fb484b9a2b67f5000dc66bcd8d11629fbb0868d2861964711ed1c7088495f57397de8d4a309629a1d60c37c9111f46aaa07df2f60a789a99d601eb52b2b87eaf928d464531cc7e616f056b63c4425681df837349e18ffe0665ae9fb253da2fd7f7ebedaa7053793adc4433f30d94d30558bcc756befd89445c16753f59b64fa10fed62d23c4cbcca728eb1fe505c37a1dc8238ce0b6547026e71310fe90e73d0c730e421eabe4ca58f290e85bfc7207c840ef50cf28491560f6d9d8b4b19799f6d4d1cbf5296b7227dec1b4af47bf42b52f3b52852821db91d977c65dbb011e82fbb65e80d1b6b753668d8185d961abc42463504faf64a8ccd40d40da7a643e0f953cf77738fae3b8450dc3f88744e504222eaa0c036d13661f55d427d44c2b46cbcc2279e9fe2d9e92494a6bbe651ccd1d5af1906c83f25a542fbbecf013867219334dfd11a35417be63b4c2bf85e68ec4c21eacfdefc7902456f12be23e185e177779c3f78d9a0803cfbd8dcace043d3c748d10c6cd1fd9f34b0f55003326deb343fe8dae37e632b0803713f5b0473dcfe09f2d421053924c2eb654f1ef0897079a1909bec637fee543fec201de7c8caa3ee2046af66d309015204a001c4ea0f83865337b95722c98f149e227d09154853184e3657e2f15662ebeb3477047081690e22c62b91c12207ffbd4acc6a948974686815598c5a787fb28dac43ee0d361bbb0d3e945ac7c283e46ad40634900dc1350ff6f9fac9c285b9595ad7f4c281831772578369256fdbae12c7c01f0a86554d72faead2dc2d584589a82fd6b3739ae140685a093398e39ab6da2d3aef3bdac73a219bce352b3ed8a71a64741e8d500f011dd18ea3b2a211737d0d6b9ceeec07f7f58ab2a8bfd17484cf7484d9f9edc399df64d1d8329e6ee816adedde4596aa0ed2ce129ee8ddda18fd757f64023078535d1c109bf4eace3aba2b11e824656104e1bbbc0ad1c7206f3255041dcac6317b8cb230a81ad5ad58c196afa96b160506dc04acec05d3350029c34483d9b8990c9d32aa309adc08f7b491adcf3e47a45ad764f6024d1ec84dc78dfcf17038cd800167c74bd155f586ee9a626db3ec90c8a89cc5695601388dc52059cdb936c6c1281642042e301eb352ddb5d6a7af88ca9bd6fe37567816108c9eab58f80525ddec093759e7e9ed9d5f14954a5b9ff4cb93ecea763485445cd3ea8ca0ae5853ba7ef3fef741627d1fde17d3ebdcbf5f48bf031a2b2f27bd360a4b536e4efe4ddae0ee84e3b314c11f98ae123c429195f4fdede52e9e6a7f7c0d867ae158eeda51c704bb242a5548f92743812c2124edcae58c59b47cb3a6eb33ae1aa8f309153c7bfdc3c07f5f9129f16ecca4e9616d0ae86298611aaf0939b63e3e16cc5811e971dd290654c5506ea473c3c5a1a21434f1e1dd52a42951a9923228637f30edce85fb6e42209967c60848484b5e8db2a00c53ab31863cece850edf8ca16109583c72b0dab416c0f9bda585e091ca3829c40c0b9432203828fc4b3c3db08ff4093bc61e8b02a22a75de6e7e51fe8a4ebc88b6217ca056c90ba61ac70fa9372bfad57a9b937d3aa3fd8088df73cc272f4bd6b96fc5aaa1dbe4a61720dc781225d90b673814afa0ce53140d51ef58cdf15e7533dac44f8d8388fa25a89b94f235a44935f5e75ab342908252fe5c5c0ce5700a8009cb8061de7a99d0d6a56df6dc767e725ef29978d1e62294b940a6fe088b1b9f29f3097127957996fdc654a89a6e4bfbcd04593f2ff565b9e794030d3d9d95ed54703e7a0e4762f4a05f10174f4889fe5126645622b1e311eeef268d62ed3555e1c38529359b29cde014619720c59c0d2e8f7a17493a140ac916335708ba24eaaddf103ad728f2e7a10b77b5c9a737b76026b17acfe11e6f6779852dbf661d56762db623cbf2b8050ffa974d53dad7aaf9566b919b7774c0efb0212a41dfa65e84c27bd2b5ca9ae31ad02a34c7a00db57b5b2d81f113350a10b5fbe747f8a51f74e02ab8b3a6238e47a8b877c9c63a66219e6b0e440e35ef9379467501042493ab185098993d052fb57bc502c01e9f2110c4618c72c4678947ffaf2022cc0d86cc64634f68bbefd1b0fe8a74ebadeb1013db6b19a730a24f0409a85c80e5759d0f8d225288e0430afb41c6f48c8d9bcc1d6acee1673388346128589a3eb01e6be135d13eb4c042ad5b1fee5fc7b8407ad6a8ac11778a785105e0da8ccf8b86155908791f15f11c93e4dfc2c9617e4a0b246a3cdaf7d7c8e31800d588090eaaabc54490705670e4f726ad1caacb41120cf8062cbf3e00433aa2855a9cd4c72aaaaf9d85c6f015d7001194346ce6a9411a74fc147068890c2715d6fcd06e5d36cdb157f6e206062edce0499fc2468dad53d73bce1016f06a5d534cb4b9b227ef86445db74de10271c7a88a014c344e6911240ee78b4c1621e1b1f7a87964034a6f5bb9a7b5e8d3a7931a1f53a748209e099b771964db42dfa653315290639f3503b06347def8d35d579c9e0a6fbb0978615f728d1eeae36e6da27f945cc05c8b29d2b0752b68c04880232cef1f964e66818f6d1a2a044030d23928af467772af42de8023e2f503a37bc2972e2ebbe8cbabb05f130a2f4db22b6f4452ba201ea3c16d9737a898de8413056b292d1e93e18b393624f1b6af4982db65dc955ed442d92fb2d4c44295480a50f4a6763c960f656ab6d82737c5b4764317905846e2967fd1fa144fe84e828ef904740b2d3509a15568fce0733469a0af51749040467c9d8abdf3ec86678da489a86c51ccdf20d9bba9c9a10a21493acefb89f4124a01ae9b5c36f2a21321b192b18c7910a134bbcb8a326d3a6ce1a65a4385aaf1b0b5c1a8130b925c92fdf42c98eacce4d8930dfd0459bac17a15c2275d1f0e214bb9edd2b674fb403bc41598286f41ec868fb086ebf84341617d1c820cd5301caa7eaa34906278e4d4f4011aff783948690480b6e30b670a58955b24a82f8e8a940a2cb59dd548066e16a04ba71cb36f78394bfcd1453f49415dc2855ecfdb4f42d28849ed44c9f51e23a53a25ee003a6d933cd0781ef91d7573db0f63ccf87cf0ca26be8495eb1e06d104eea5a87fab87cd974c1e626a745ef4685de7261b4496e5a49462d3b67568ca821d8f2f65c9577f6fd594ef10a414bcfaab2d96d556a4f8fffd00cf0b3fe662de8b9d178203e0c6d861d95f4c70e8913a75b38f60ab00e3abb0aaf7b5de3629a8d448297982a21e20a019fac1db5e10a33ba3c00cc301a40af6cc506deaccb982b981ffb64f97a769b91b4de11acc8ffd8694e505899da04900f87f65d37986004c1222a81ef06be634aef422a700bf783c7b3500b2398d3ebd6024a70cd67e3ed21f1c2c27668981d293d9b0ad3c9b59fa1a2b38b32c5e18ce0e5b9ea9491807c5caf9b7405f5e6a292ab53334be0f03f8d750f7f82848de80519b34628e62fbdd9585c772fc459802705df60fe0831dc399ac70db73c6a3e542e320c9fcbb80dc4a3e29a010ba6b5bf5f4cebccc06ac54f1c33407e39a45507e2cfb3bd5dc2e451e36d7e1b5950cc3640840e89bc45c0174c59fe31a22486cf2b62dec2fe1a9ac65ee04c82ae9c3946d6ddac1a8053ec01a19a5cfab8afca6f3e0a7f9bfdc03c568a5f12d166e503659993e619d3b145f11c7254b8497961848cc62c47714d43cf7f7b84e643dd1c2c363b73383393b10324bad722fc410b60c6d38b44f009ac425500636acf2d180b34acb4c72b3b0a31f2be2eada2c785284742f21b81938ca1a52f7e3dd27412434d316947f9c2457ba69b9c5ac75cbb81ced1dbd0fa701a19c76d3942fa5e381f2c0c4f274cec4458c4987c3d8903458e47314903657956fa29af88a22cc49cc08ac33a9678c5f318d4074689d12b56c90daa79cb65e40025946822e6103e18c8e9b8910e7a59fd788c31fc30d51a9734eab0f25e9090e6a26eecbe8da317d7d8a8b99a60e2dbf698ef4bb406d391976a69f7478027dd3d5db0ca93dfcddee1b8892a4ec8eb8ec66fcfee2593efa570ee13fa7d26b7d7b6145899bb7c0ee822460ab2aeda0b219cbe3d678f6e3de043e3d76d1fd1d233497dabeaf31cc47d48591677c3033e7b0fde8047fcfd1d12415b3dee8d6f06199ec55c04904dee665234f66f59ebf7ba840220fe5cbab3637f4ffa9e8a9c59da675b25001136619807f7a5acd1319ff2ce814bcbb01c3928bbc425c40caa166eafb78278b116879c98756018b8bc8a94922f4a8eeddcc4c5c9c3de741deb995dcd50da11232bf78e242916cba97ea1fcb7ef479d55209e6c48913ad83c8f110446f7a1166c44bf180f1bbaaa104158ebbad2ea2a4236f44e658f9821884ff8f90cfee783d4a161c9a0d12386d3e27fd98a27448748ec9612ba99a66258300558863ae49d1ee342b9be15b06d4a4de1246d8adebb57ab312861647ed5ba9034fd49c4971346cddb1b47501dca38fd799ac04c0cf62a765cf339815d62915197eba18fc5959dba18e731419e55eb081613cb29db10f4769ed8c796a4fa5a2f6df7708aa7ad6b831efadc91b9013ad3c4c976ac2c3894096a117aba338b63d1c61ab4e049606b054989c751eb89c4bbff00a5aff4339b6c29e421e330014253f3358bc34926ada2b54bd483e12a9800e9297e91bff59abe75cf90fa2c53779cb012fd061b25e5ce26370ea529c42a5ee0bb88961a61f4d3dfeefee4c03480c6870bcc18e42830b5bf7028eaca7d9f6c3d50378d47c0f7b354ddd9a260e9ea118e411b644082e9a92994e94e665bca2d0670db440672c70b0027a8ac42ac6437f400cd99dccb6c74089f382f314dc486a2f5e3af36915360642600f87070e3bba4c06c6840b2179d1a1003ee9842fecaabe753511835db8df110998418100b370cb6921e37949d9771b3111c2dc74a86fe276d68619a752f332201ecbf315138f377eef90c7761d78c6e268ac2b2b9a9299ca316065f6a1b75defab79ff4aaa3d1722a406b0fae6686b6ba8ec1a621f58644ac702182bf5d9b274b863c83c7c608df188a437eb6823b2049135837851a590c1c728e5b745788eb0f4b5808975b31701f4941b40ec6e8133b80ee02a69e14e7bfc1149fdfd10a62a70fed82cce1e707e32ac6a11f59ba9ded4e25796024b1c729b0e9eb1a9e5f28f7e29ea2a7f2c37474df742470a44ddf75e180414b8a10290cfde0d97237c67395e942d233be269c6410554e2dcc5ab313af66b608c2aeb861556b383ae4629ce308778595f389b974b24f5dfb9cb8ac9019650f80ed15f94c67dd048a858f6ebbfd8551b393bbfd275495eaf6c4229bdc9bc885bad1a13312a8c6e73cfb003b18d924c02af490f4e6c86d3b8cc83b8f493a2f89a22380a5d9dea0e47a68d950b697ea7bb8f1a69878b6d870f14b99c446cc67265c2c78152dd674e4ad9ecb4c76b62b77c0d0f58655eb1b1a0144150a7926bad4a49c39b6ef8af0218c05affa96b0e31ef895f9ea0a684c072c18cdb7c3a6d833230eb9a91712fee75167242de473aa6e5b35e6782982ab068a5984aa944c7e9c85bb1ed8cbb05e5d140e0736fe3b4b774fb72428d714a7dadcc9b5779e9b7ac2c22d0e35471af7d2a3ec91bc49b5b58ed3c85e415407df96cf8fb67634b8b35901f299d421f8d7da1041f09580b2babb23fb6e8c93b16c1ce6eae2c60720211843db7a5f857c7b1ac0a4a00515a138934bbf88774314ade4b2beb1ed3f14dbbe19792a026dadd2c3451881689e228cd57800950e378647520f372b9d0b866d953312e1b8e9248cc12951b4cfe3e32940a3911efe1773dc191f220a154fef99848803cb8784cb8d8c882c8bc7c15244251553d13167e196446b554053df7da43d06042e5ccb7a30b12a6e9eaa6a988c2f6748dadea5c6ee8313657fe6ec84d5567cce4b24ccd760fe080f4f465aad8147d8fe1a317803c6d2aaa841f9e8e85983d9dd9ef13ea14b104248559a6d4a790ec178f57fbbeb14601983daeaef49c06b9658d34599b596b548d7d161482392eec030769aea81d1efc9b2a77fe0ce54394775e9b9fd4aafbd44db4cc79e8787c862e9e8b3c794e9200521abc41c4952d3ce651949685340ffa65219bfdb6d9801c26f58c9eb53353e5d4d085720e2d445b17d90551572648b6941544171101571e88216b74b077384a465568801c5e6ff331bdb352f2e97a7539c446949560dd1516b092caa3603a946218a40b8d9fe36957196de6869564abf3f47aa19e833ef78e90ab46e1590a113ee67c415576651f3e91e76481e1919c35b12d2a56755b8e5a44127162cc2abddb09e09052529cc6cdeb3e58cc03cd0e14fab33d0afa33a93e170c6a0466fa51114a1f5f3768c1f23e4815cec692d8662a0bcf136a623067a60f1c9093d6ef8cec51d4b3f65217b9a9b6f8a5ae6598004943279803464c95fcad3a3a000fc1f9fbf002f3d26873b4406d6224c261085d7fc4c1ba9088031e5b0e5f1f483d7a1a4ea80da9083a8d0bd1e397ac591886f855b2de7c375f0703b5398e0b0a3440b19f3cbfae6e09f492f4328067205035224b6a4fbc44233d78f18cb43a13970949f5834c4f40b1495b8e548efa78bfaf29955bdf5746e76aca1ac9f4b15e4184ecff0a35fede4c1649c6993bb28136b88929f0dc17260419ded7ec09d8d1e19b4037e48f57d2de6ca730eef147de7ee11336b3594356a2ab2657f2b1e720e69663d3fe36882c5ce9daa39a988880b0d1ad0fb73f660e15f6ee0e6cabbf6624669964f2d1207bbca2bedc8997697472588cfb9bf14f993adec19cd118909c29f31416200e89b843e74d79d0df5c610ac3c5f6ee48889c7e1fb01490cb1a8256ff117f837ed28fc761e81049eea7c45f6d130b29c52a065645100c4b000bd424249490a1d37b6443dd88601288d22f39b894501d4c1c8b64495c2df3d39d7efb21540f646cd9be060fc7c389e023752955d64bf53cf5da8b7fdf5552194bde3925aec7d23d1b46b814bd0ab50e82da3e777a1d6b278b71ae994a0ab2e140e14b0659979a56c2d45149dc04231f9b1dfd1942fc36a95864d4fd4da580e187c3b36e400fa8a70f193fdf727ffad0d95248bc1e2ce03ec11d5d8d3e1e32f331c047cbcf737da00bc35460330e473ef7166fbfc75dbcf387be533b00e9615d86a430fba7663af55690463d2f715a8715333b1ef6aa2e0170c4d2e3e912df3221e861128efbc10eea160079bd593ec5bf4af22eb648c8b45bee1b2da6796d50512177a8bf1025f1a4da4a144a5d8341bc40d4d8837327f36fed53eb1eb9e690396539f699cf9ac483cecec692175d619371b974e3ae5de58e2dc082219fcf1f033664986f15bfdf4941b48686c549143012e42f6123f4d8be8c19c510f3b506a1b68c1eb5437dba20277c11d94bd94a671b2f0f071c5b43c3c1dc2005007022e4c1b5c45564005f5bbf67b8a09eb06ef25b36b38945730f1d903fa8445295c71b9a706212cd02cc04c9a7ba73025dfcab49faa1776fd64cc2419501071d20d37c7b001b5b0a4b21955be26d966eb4a731ad37a0b9c8cddc0cc27def34a06a00cc8edc2d982c4eed931cc894cbb3f4cff3933b7151b71dd7f132a195ab05f9e420f3f6ee5a6bd2a189231887b9bd3b46f3a7b8864df31537c50ca7500f13692fd427ddb1453dbf872dc35c36a7f88bb69668d8672b9b48c3bef9e99e9a5e1e4d2101ae32bd079e144039325070725f0609aef3c552d03e5fa17041e3825db33711064a59eb06c2f9b7e36834bc715a4dde151641832f11efee1219db1419c1000fd6f221b4ba9f31cbad579905c6ea7dbf142c9da8950065a69819f99dc4862146bd2ce2d48c2a83d5ce0b1ba64d7baac7fc7a87254fd1ee0f762e0aa608338393eec2424f6fc169a6a6969a6a682f07a08006a03c797c0ec2392813cf6e75fda81bf6c3c93e844b61747a1c5d72b3bcc9982ef8af861e5299fca2ad589ec227ca8b1030b63a8e83e4bfdecc7abcd1864be4b3b45267731dcbe4e8d9752413689f2e1c50f009f438fb9ceb0e39296c816c124d44caa09bd2161db0f8911a094c1b487471575d552dbe1272e996a0660d2daa49fb03dff9b1a1252ecaa70971217b4533a0e7e59d8f07871c69f8ffc3399cd04af434440a8c30ffade43a287eb3117bc9116626f4c1005652d28f5468ffbf4f4a3f17290e27b06c1a0f4a37760122d4c283be28dcb9febd4b063c1a5343f134177e152e99bfda3fa150d25c15b6a18c69b8a46c953026731f4721853fceac236415266e898b105db0a3121b4d682d90f44770eee7901096b539863155e3e28b8fe235e5d474b4b0529f0611f060379a3e4f37d8e0eb397c932a01ed678d9018242fe6eb4b5d36be482b957c0d11e7ac0cd842261417289430d12c5d081227d207facc291cf02d22a75087ec0d9cbce192600c32fc62c5ed331a8fc5e463dba0d4a0711a1545b4a50acb31a43f95991d9b746d162c099f7fd8f1221224a8c416fb84a589056def4002369655ae7708909b982b4e7487b6d6089d9d0a9f7bf113468af5364ff749831a6c407cf782f2f99927150d93ca91b8587ef3223f2693fcba2074ac93fcdcadb7e89ac564c4d16a83975526e813790aef8851ac4b6adff1e1c41f84ba7bdfafa026da3e291802810610d78c34329825710724dd9a5367515d5813ed59b5c8959392ed4c462537da136ee3695e2495a737e5ebb0508d569ef820045d693719f549346aa410975f73a1b2f062bdb21da90df7b420a55a0b5948b63133ca6bc586d5c4117d8f1877f3f13832b0ed040127ab0873a05d20fc06e857fd5d43400a8e6623e5253e0a8ef4d85087bde4fd177122448e6abcf6803832ea731aa1c95fdc574f60328eee7304754f625f27681a37264897c84df8cdcdff3eccaeb95051646187ef0b716d64b5043189928a3710ff9e2763b91841ce42b10489414382b319a65ceb0a66571213ca6d2f546df4fe7d8668188389035e5b435d5d719a83d8c44079dfabd196f61fc60c26fddf345c7214cb6cdc80050a7a1212e9cf3032be97285421af45af006c4a28bf674e487d13653d141eaec1b729fc085faf2d6c6f3dd8769078bbe3aa86fb8b4258f6a344a2cec17070dfc698413a5db57ab9ed6ae9850e6b8e460b6d6c08853d287950af928d296fe4bdc7ef793f811a326f74a23eee7166fdb83971e174f140f2d243c9f98a33cb8edbc18faf98fe2637196898be92a3c94aed3de3b5a30d233ff5b4a22600a5b91174c649e5e956cf66becf2f9b741132ee7f8391ca5ef43d3f45f96f64a00b50b9e087589e5c15c2f42d57e0a95e1ccfb449a032b6f75a196323eaddcc37f24cb75a1060dffbec358a00b0fcecea97d04d09a50a578f14c92c71ae60ea816c4b8daa0e43a61c9ecb19c2b557b2637445416e91b1ac0d7c6bedf4cf8298e1d57dbbeb25a25e3321c2af5803a4d1a14e3921e4dd681ce948d9ac27b82a43f6f23119b0de4ba31108cf02ec93c53038a7163f2539588f0262eaee92e66ed030cf299fa03dd74a3f0571c66b5e76f95ba204de9d3b955354f53bc7509dad7f8e7169de94c534c0cbc3bca43e853482439b71d5c67a01bd0d036d65d76e5fe1854d0e923985cc151abed7e4ae614cb4f20aa988924f0b0bd7ec597629640001583632bd388419db9e27947ba6e93427fc3082de2dd24a2546cf3b7024f9eed1b42df7a56b588c888e88816a1dcd43df2b0793856693bcf97abd227ed703653ece68694f8d2c07495ec490c722d02331b960d59c9c0fc7ae2b55c4da7ed976918924dbef442795c2cc922f031c995bdc79173a291c0e13663f964288efb98d839289a615f8ca700101a22c7ba52934bec4f54fac46b11f955469bc14bed644e40184d12a353945c624a4c04f2f8ec36ba18b1024f4b01698c1e5f644983216ce2e3af9a85e2206a5c683c013c1e9c06ef95eff5ae4180e3c9c923eaeb40e7b57180702cefb6d368de9b81f2f6cea761bc7a4f55fa60eacb19229e5026e68e0892a7dff4183db1ba46ce0bcc19e0fb994accd11e87915984c1a508e2c3487fcf240e721b0cf35b1439a51757118b1c1481c0014e1c9d78d7303623d9ee86291ff9589d9a82c7e2d28b14955a7e526b096a8b96df6bd71e7dfdbe6a0968bd9d283bc7b347c39854eff2d18407e77e6d4365230ae1fe5e3e35ed5f49ee1e0b8465004dc2d0a3a559615b511ecb0c0d88487908ad1b29f9969cbe2935093c030dfebaca2454ee37322224fde714d23e4262e08f87f0e063a0bc9fb98fc9e2aae10812e2202da38311851983a9d9c901408159b6ddd435b87e4d29698496557762d9e16bef2b71260ea3d507a08db74187c1e8270dcda32bd8a543a47b1705df594dc0d1cff4e0e3146a0fc3b0778d912e4c8e34b56ce63e880558e2fe6263a4f5a80e963e5b0ddabd64c5bb73a6cdfac1bc260447d243aeada03a64d8dd5f094a2636bf62421f8c25d20b4b26d913508c9591420143211f55929e5b539882047029dd47d7fecd7809fc434b1c3fb8a4a940e9115d2081023f38bc76faf1dcfa48b46b1e20e6915c18ebf4328ca5f54858fc2f4816df280569903e81e6f68db31796c12d24223487aa2a178297a14e4ea390fe483bb8660f24e962dcf05687402390042d30a2c35818fa9de9316b3c79627400688daccb7d23d96e6fff42d7f63dc560675861cc35f5260f6236c922dad351e69ccc0756f8ad67b6e323a13faed0408200a0fbc0dc3780b22e7677cd3b232237aac64f862f33f64084ae221348546aa298c789a0d17c1caf968d3a262a08ee9bdd7653747dcdedddc3dfbd79be29c625f919f786811dd8ea280a060b0631b69941e50b0085f1dedd87ba954b097f5cf7304b2cf63160351c78fa4ad3396b4e58de021136df7c042e51440bf92556677cd630be115e14070e272fa0ae6a6f9fec24bca37cda4a40ddc37c9c204abfa6af193787b6718eaff64c0ebe362171dceaaddc6cdb3b88d92613cecb7c832ab7ce503aee2a0a64ded8c213b91ef35556b84f542792f9b5321002197392f180ee9a78cd21cd98333c305eb1f53372745721af6deb742a1aa622e7dc1964e377dbb9d319ce33e94d11a5d211964bfccaa969003e1d533537ea2e52d46f98bf8917f57247a4fea49c91f6711361f04bcbb320dcc97ccc81c84eccf956111de122cf40fed5e855841a1b4546af842fcf0a4d1645c3fb9505e887ccaa61389e4825dbb23ba77335633c895b41279e46279e02b18e96f566753825a7fe98c2c62fb9527edde51e43ae85263a1ba44096ee8135f2030c7efaf90720e8a7cf44a58953d3d6903d7390dd5dabd20ee242877b680de21fb206a75bf68834759d4a87d31dc2719b513ef806da4519b6271411bfe9afc5b8f7b1b6a0cb0ff02895ef908066ef2609a9730be939a87ce91cbb273e7c442f724593e24b06a9ed26d1ab4a009e67cb218ca5798f35c26ca5b71a2b065c7f52070d5f5f6ce7389f3654b49e888bc081df70334bf20e2c7b2276c07dfc2dd78e0fe6f260f2205c60f882f14180ff33400f5b9badac39d18f13ae12cb7654028ba0d88209d560d02dece6ca161f31249b7282b149b84d973de88b45044d236c23861fd6bc3884989f8a667dd7226a65b7419a1be57b9f50d40c73006ea32745945deaa4a7cd2cbbcddfe101ca46c72129a295db4c91f21895fd63dd4bb9cdaabecd500475633b252144fc64b93ccd6815bbfa47e73833511ac69fd38559a9a08fe6bf67e6197f2fffe35d51b0dca43059e8e54d206b7ff5fed050e71462428f233764f9cd883067ff7477984140b0acdcabc8ed97b6c001a6bb506571f5989e750145cd7182f8217b1e786469987e171b8dfb6007d39873a0c2088b278a1957d20d06073cf723b09c01008c52f118d5886749f0625dd612e5681f8ffe209a0124e6d0df07a9aca39029feb3de5840e3e61754e319a7628628ecc7312b19ab64cba12aa665c25348be574315432a751907eee057ccb1655b97718795713db1a76ae05bbeccb77395c9318e8fb539bc6790098a7190775ebfeec78ad4fca06954db4a18275fda419023f85bfd0a2fa705d335333ade35d661170fc0898a8f0759d3b2bd097a2080119db3d99493a626e3d0c5e23e797225824442b5935c28e2223020639764006eef088eb8f57a9d129859025f2e1d5cf16ecb8a6bc6141866192d813765ec3c215f2cad6c0de3cf190d94da301551af1847db2e0796aad32049ac830c25a10fe15fabe4fc74af39f9285fc19d6be8a76e55b190609581c8d070d0f708b8230bd269ea6c1f2d7e9681009511c0c9d4394a90b6548963b35399633bbb9b054a6b36c44f28cbb1860b1fcf65998b991c981b528b27147e7000001ef66a784360cf301a1bea9274bd7ca70baa9ecd245bf84fc825de6e579c629aee8f7ec0e867b30f742cdc2e45a9edc8c890b5075a8bb4e7c2df6c7e4a4159c989d941d59451bb67695a00dc60474134656936efaeaff697739af4a57f9272a9a6aeb2507b4b536be4643ec2189681bde910fe99dca4479c6681937a77e4f1432261a064efdde8819d950b5b00a4bcb1a4eb5b1a696ea43aca006ae917eb0ff5922430eb1f772f6b97ca30a578b4ec97585ba188025fa12ada180e563e3387a2e2d875e6db425555f31b79dccb1475a24fed96d52316aaf6a5cd932f85cb107c7f9824835859b396ce9302b104951c9c736befb0704ce8f5947894f4bd204065d4faa47f212dedf21149a602d261954d7cc52a896e81d7b578b381f9c0bd7694ccc7bbe1806537cd04354c002680976308d4f637af2d4d988beee962611a905c8319e3d360445f3741e7977eda96c0678465a7e08f367be9924f75bfbdafcf078b89221532a0bf145e6b5b9454498d4b35c2f993a346b39bfe603c57969a17083a49d724b09b6e2b92adf050c6e40aa8f90d38b5bfe7a3385764c05096cec3adb24e6e29fed5199b2966911bb70dfd6801ba3288ad9728f00ebc8aa431ee24fcde9f0457780e88a57a7872734befd65c282c5385c13cf1b7e20dea9f92ea843e015f2553c27a8697e0de286f011d7de2e5f185bba452553ee65bf820a04309bd75dcfd79eae5366060f09a9836a0723c4e9beaafd9f59ef4c2adcafaf8d0446cb7f84699a7efff1d32411d807e771e2e36b7156613f36246b20cc94ab67013d613b6b38cc7799445b435f1f8c0ad3e8d2a051575de7f44e10f00f320e664aeff8d9fc5f4ef2eac3b64a6db536b18d5e135d0dcd30746fd57fbbfd3c5c26fd1062e76e9594cb2dcc424cc8145025b79eff727ddfc86b24e3bce3161eb5a3471a1a60a12333c7c49496ea072ebee09659f78f7ad3dcc29bb7dabd0b1a4233f623519f32b6604c9feb7391181b2f6d304024dab983b833dccafd795e83f1817a87d00618d12008456ff77f440214ba82fc88143e5ff403c07a82a3fb39ddc2544d7d45ed2ffc267034b3a60291be53480a266152a8a30c16789d4f90217a19f7e5b4fcbbed992bc6b064bf494888e01b2b91d04d362478b4f6a653f4b7bba916655cbbebc8bac47745b9a16e34e4c709b8b05ecc39eadb585c847a02bcc593d964e63c423e414ead3113cada04b6fd6db9fec86f951f3a7b51193ffd63c8f81dc27106535c05c26c0efa52303114f43ac43a16f757a8a9e67f4d85f1f5cddbc190dc4f58f6f6333e0fc847ae275addf512e75c638f9bbef4461a0be4eece9566d315e9aca6265c8ae288fdfcf474c3e4fe3023cf1d4fb04e1222aabb1920cc118b7f489da1a1994649d644482b00764d04064ba7d23f054957b666d8012eae22e413485bc2a8d3ee75fe0a8bb80582f50ddd3f5d6751d44c63f76344f6d220aa133df4de18d86b5df2fe00c6a2fdd0233b1849b5a644dd3fd3b3d137f1a4597402c6faa9fac072a9f9c55106cfa8f4a36d3be334585445be77da1e8c072b20d8da1d464ec5053cd0b562f183cc8d8f1a1363aac40acef5dac70985f2842507870bf9dda91dced1a5c2c9a74eb0be67ae46e4ef49945208933da97b2a177ba5525859524f4c394295cf25fde937e1b4c02441d128a4345dfc4eab765004af4a97e88343dfd3e93521815972bacb25ca5b7226feaa98986cb2a1d4fa6634f04232adfc92cebb9f66b7bd5373c4a37c323f3301fd88708c52a01201ea30e6194ff2109128b318dae1af48bf420f4afa8e5b18236acd8717fbb265a7a72bfe1c631906c4b794e707b5ba2f94d243709a599da6e28724bf5a080b193315f9bb3f268f3f0a2980aadeceb715d091d83b5f048556b8c65adebea09ce19c6a526c00f44f18cd92a7ddb288bde3c681a513c099031b9af5da8f94388e36d31097f1dd3c128b3a88d941841c5afeb9cd295752766d3e85353ca02e3fada6f6c785d63f715bbc51cf480b4861a3feb90280b8b1276aab953290e8c30654f6fd3d11a6dcd1891dc51e6a51e5859a49c7e1fff56aa0fe80d9eb4d97cfca6490ba583f388702a3a41b23787d1b4d6aa81546e6eff9cb013a3fcbcb115e3fe7e068d8b21c420dd364283e4f1a36bc68e9139476546dfda5982cf3aa138181aaeb04f7d2b2c49276e90ed4d438214bd8d471df05f61c706ceae72ce548023919a98f7fa3169d0d467f982154a0f714c1f7eb547a58e98b57f43c4c5f33f6ca381024499232988d1b58b565ab2435e6cb9c35f25b1209669968f2f587d4a73aad5eb9144dcce87c224f6e78cc906b9525cb50775048c6a36263452d3af46260b8f72a15036431a1e6830fec2f8393935609f21f119798baa429fc4a201fd789dbc597fdc1691e8114849d2451cf3772b9178fe2712b59c9745ea4b8cb103924d3b7db400e3d9ca1bfb912daa478008c21c2345ef9aface9f66000388bfadf97ac2bdd523d7da6f48f88e828bd30a5bf9e5751a096e5de821a194d30a48c430c34da648eaa5bcd34ea197d40854be0e927de87d5e3a93a8519f5b56e7a978271d207eca08f90e0197bff84adb1db5c48c1c899540f2066795462ab2d86a01870eebea1f67cf280b03ba5ba14b0ef7cc42ee7083aa1f373386abc9160c50262d10f93556daca5a180bd1213564d6bac95973d0c9519c0d8559b38a2b334645a554f2d563069e7b72e3d3bb89a89ddda15b31c30c07c373e39b5e674863b72ee4e1fdb42265febc6c16a9df5f2f8819fbf7666f967007effc78408f46fe50f619187349984d3f59c7ed3b46f27bce1d9711ce83e43a6f657d05a47f3f5f4ca39da20a6a947ebeae524270ef6fa44fa952dce8f527eb6bc8818319e73b05a063723d673108e2820b30285d8f83eb689e2eccf6ebcf2ddd63e313bcfb3e9497f814993a251420e79efef3004cd65f44cd16ee16c4777dd44abd9eb8301342b3d53ff223973471d2ec5d2720810eb5e1da51ff9d583e1deac8d97aa84da47e315f31942480d10b8e3f7aecbd0b160a11084df7b12259a0d99ddb6e606f1439551202b33c5bec2016815ed70de6b3009901855c7a3e90c515a8662bdf4827a25ee665ca178c151ab0ef90f464e42b9cfc00fe404e2629087cdb0b57210d77238fbba36f7d53bf5d302580c34805f77a32ffaaa06df248fcd36edf08567e5c99286b0ada10138bb8db9ec1e7917e5303eac1d3b7165aac99d97095718f43d1e1e21f961c8604360639657878cb8d2a988cc6fe14b4838471e93d9b5f4000d6bd16096b047656f0a3c4a6fca24b4ecfc37a1e300fa3b13b437eb3db4112ae99913a82eb91ef2dcebc719aaefc0e0301a1d18c76b31ac25d20d8837c504df01834f6a7a03d248e4bef6deb4e409a82fdbf2cc780073f4c748503d9a881cec4005eac9951d46c53b792d3c6c732168496899510370765aaa9ab611210a35bd7bfe0938d4a685ed62e1ac8a09346973a91a5a8c939eb7243388edb0db00673a351b1733beaef82776b4b567812666fe0114ee0617e2340b0d4f0d4358080c7a09a961f25cfdcc539ef61621ad90036cc9e15c009aeb6b252452f3e5d3f5d3094ef5c23e793a22fe130e3898f7632c0278ad9cf005ac99510a95d48a03afdc33be9ff03cc32c40af01b2832ea1f51d181c14b186f5d155afefd093e31f94be008be92bc005260751aa4d83009b20357749053ec65d5aaf98f595c1f185807ea0ef0ae10572e683284cf7f4dbd88b4def0249eb4f946a578153bd4866ff0ffd085d7d6768c37c65732b9355e67356034f17a9079541f243c462b031951cae285944be967cb6148781a62b03fa70a7d4dbc7a1a755c2b4d1e90b0d47d97c14c3272af5edfa3a6fa87f3c0a80879883c2a4cdc96c406b3e461c7281a6c26a1ea040428e70d2e74caa11eebbac4639f8decc0edcb82ce7b68c590a9b4dda57744bde3d7cdc9e3c274ec5b73db9642d10e3f47cccb4614017154daaa39991191e2f27352180cb10faf3cceab4dcfb10e5234038d9f61c4e06106ec690af1cec6921170f0c623e4e04337a7be0ef7a0ee1230da2734211c5da6a171237cee84686c0ce14fc6553531cacd0e40bf13ab6a12841f6833d39481fde961702522b84588f44be52b874fe68e5fbb461d716d7a9b49a923f02208ab0f55920afcede5c53f3ee39e083c9e01b997d9a6e0f04021e8678dc8f6a3648f8783e7734c6cdc9b8d7dd10a4e79435b3fe402733bdbd137db27667a7266538da8747be52d6c9909721f9b9a13bbeae1c7b014423a14f18913403b0b1bbd2ec02f1485641a9286ebafd37018471432318e0871b29d78683042d07c6bac0a083c06014dee087606b92c2e9219759d7bf85673c7a398e72682dcf681f29cb410db429081be670285e91eb4ac28c70d5a9504eb9a502f6382b9f6f77c250808b97d1f5071b1015d55002acf2f9f3a09681050c58f9b70deefb7addfc0d6b02057f60426e21f6236cedf3d9f54eba4a743f5e29d1139ea8ab6681c02bc728848c03e290bbca49dd959b82ad7defebb7c9d789696dc215215cd533684f108c8d24b2016cf0f39e0636645258475393cad28f784371b83c5c3f7772a4a9f7dab0d241694cafde3a086230b668b27391220a6af86bd93c4264d9a1b676c320626ab14187f51caf9a374a9961ad5064400834365d01f6f43405128d12353200506d6d3c3bcbc184c7defe8346c67f45a8fb83b1b679cec59a613f762c992583b577be8082fca01b3b230b4546301e02e3b389326ca9eac9abcec968451540b68171a2ec2b6751f8218e2063df99b88ef45c76447dc1c6a6bdc886ee0fb7322578d10acb78ed89f2a9a06890b80ad54e0b48a6dc8ac41c04c35019f06a57bda24a7866e461ccf5055832ca556880bd87a418065eabbd111f1f6006dce20aa55efcda4387ba4ab633d31679eed833ea693f82c6c6fb7a9b826fea1b3d3d1655b442cc4fc08eed39567688d5a10178a766d115b21a1f2e59dd32e0f7c6a0d7c4f06de1659aa683b09962e31a863dc582b2946a1de2fbf5c5aa4d01df379e4a7b78ada380cdd52ada2fd737e043546c941d1407e156953a217cf7f7711aee380bf4a8c6bdd176efec9010a614074131beec2b52718696f623212a6c01d18ed0e23c6b8bbd3fd63e531999baf804e971e1de1e4dbb439446c59f9da1b097a2a95ee30bd0b2c7bde9a7d03c46d8e6ab01d7a59e5267704fe8d4668b5c82fac7192d91a60d547b123dc8a8255ab43672412f15b0f1db95f0479fc2297017f4336fcbd9faf54bc5495a22de5b0d359c6c33e872ce0fac226d0a1fd042d0c6448282955b92cbefe9844d7cca12b4a19167461109b20552387d25d3a7ade56ebb79441d50497b923651be1551c5eac20100e88492a54bbcf211861b0e41204c5336671b5123d2317e45489b45abc79fe55e0b5b9972d21f0199994d979e8111caf33ae07d13a15853f88aee26a0460522a3f9615954e35aa7a3d9fd064951b960a9a15914e2965286d56639043f5d4dd29a364dd73414d0643a9550dbdc940e351ede8c5bb304db3158c28dec2445cb016896227985d7588fb225afad8707771f0d78967d2eb09f6efe21c8c648cc8867914ce68e5590d396c74bfdfd20fe8aa53cffa8b14b3091d466139a97c82b6caefc0ff078818a18f8ec208c20c84fb214b2fae3a80d2ca189b181d6f2a9850b5d79920069086930a0298df90a71ab052d52fb2507164f3c1b7518c71fbaf4ed5e12d4dfdbee5b0199f4b7d0cf1e237352891439c9aab3852ddd268f52ce00464f03b6443aa40e4fef5838f2f5e90f3dc05d52d8a9e2d7d279615e5eb321260fd19105023763005ca06728d2bbb5620abdd05a5cf0cc8c0c24d8ff86d5ad0223b3b243bb50ca3fab25bcdc39760c04d8f2a0bf814f19c68119b5c8f0fdaa0bf7aa75274cfc30b1672c1810a7c42a0f9ecb7c8db58786ee6a34b91f792ae2f7a19085890aa653f182c844819aeb445b387341bfeb21129731307fafed2e5177b3664611e9b805e242207a2090498f8d3b41f7b4f03083e21dcb35713fc0759fa9ff6f67319c2f6377a7a95895e2fa699737cc390bf02d15be435e2ef4eb4678aec76e69264b880090eb241c04488c94ee9beaaa43e3f6c40d6a8d637a048477170818d598394c88540d07c155a3b1baed30fd878edf0828862e5dfc9147aebb178beaedc8e3919e2b33e5493cfb79f8c39267c8a8ed757a6bbdf93bd0d2ba6e643d076fe1fbb5746bdbe755cb2a665cdfad65fc150f7058cb38e7190095fa859f9d51abddc858cd2c86330b585d53f80d717af937454e00f735ecadfc0ceff89c2a0d9e196ce794d25e8d72a55f18bdde7fc8ce1943b08721bf63789929805d48a3ab52276c320006f6ac1e0db86b8703ba61986ee8950a2ed1be38a44defb2db55393de7aa1486a1e02cfacec5d1465a63007fffc92c5af01fab2c09451eee72fdea689806842475a2a518a982df3aa8fe691cab893add33330d7e8a17e1f3223a4b0c414303b7415d90fcad51693565eb4b3fe26812a25befeef5f5b73fbdfe182f12bd73c77061949c82517d30cc1e22a49dc6198c4211af38838ea5b622e5515568b297eb1eeb2639e09582b1a3704b2d636335d85e916e08a53b1f8f175155a098cc6330e6307c7466f8e790833be31ad2bda23d935b7fa5f68d74062a8f1a18c9fb7b0f80392ad1f78cb5b40f61a7220fb79caf4b80eee42b0f6c17df375e0b4fc9a7100af0c9c976cd33a37189c9ae39d853e4e9603537be8c69a6eeff1522f4238208c0beb20ff3d474a47196b0433ff0bbe60ec47e1157bda2b753de0dd8e0784761f146a80949dd0bbf526b87879ad9320635b3bd9df280018b3dc1c65f7c848dde78b2eb20e7981a9ae7ff7a91f2a8f5ba347680408afa6b659749bb26c9c48f72665d097445d2e7e4dff201c0ff010f48fdc207837713eea25af7f158f73eb610e53462024c2c9fbe75ccea90d13bc7f1e448c4b36cfdea86c11641f7e1922d00f2f9e1d4864c91d40607c97ac8e2d8031ebc7f5ba288f5e1337dfcfeaf0d3d5a12019c0fe4c76371811ca54069801aba595d32d7538ae73707f3612655ff26c88d4cb4d8831d5afc0833563d4ac2039d2ea97363434801717a8769013c11ac0ed6ae54b034d4eb059503c60106a7e21fc60c36b599fc90ef24603d84dafd0c4176e38c3ce392f7fc0060960cda47953c2990e57ae671ee8378368294ee13b3d59439897668c106385d9decae81d59278fad64d85ca62f08228ceecdb38bdb70f3f1197f809e9a9a30a6234447e6526f07bb7d535471cc348e7012623b308df1ac4816a19b529cc81bbba2c438872b0da2afca4d3496a304c56ad403a6070ffbad1d02dca4c3b05d90f54f1d82f20c09a1e05c7bb094bbe282e06ff6fb91bd5801229eaba3c1d71676d787b026f485785e9c17993d7ee3a27d53736e86c814a754cd144ffe2283c1359bdbb09422b45c6d29f592cb46da5285927d6546b4554da13cc65ee1fa22740161bdfedea00c7466b2643f0c3005eaa968856b49ad193fdd639bfa7d1e3674c91c92b9aac2bb01bb26b0a6225e6da9ee4f4ba6dd4d75d593ce761abf0998d6bd6cd2d9d54eaced69b7423d572862cb204970875912faaf2350f53e0a0d36e159c77a6f91603a4902b2519dd0d93b259571604dbf3d55765335dc752fc94b23599b08b050c2ae0b5448f0f97dba61425e89fe7d4f692c3e57d0838fca8777e9b514e9af1ea5b4e804608a616539000d469c7d6b33ae34f0f729c360f204f912944639c82ad312c4f31eedbfee0e00b7834297eed56e23388fe37b328d8ae927b4a8efe216611d8d97d8b835619f899c9581c2e427ec6915b2d2a4ebcfeeb0bfe9f9801f4c0275d10144548d8bd19c13e712d93349e3141c881a715d76259441ce4a2195ef70f99707f86991fe35b0a36561d9b11ca3fc497f68c613581ac83b8cdcc3dd9d1bc6eeffe13dddf0f6b95c135c8fbae10b46ba6fd8b91b427cbf79dce92b382b5142dc4469d28a65ec97e83913bea81ead74abf065ad254eb6d3bebeef60a89f5a25cf5d00bbd09ad583fdd17e7a6f186f8179df9d91919469b5c82e9045c8dcc59aca244253ace5f99963aa04ec1b91588041aa28566a89a220a3da54eeaeb5f889d87c1d75796bd00f5437b901c80da7cceefa3254802e8e2d62050984cf78fad896c8178049d84be4b4e1d6a1960795bec6df3e9be32b2c7ae6d80041627b398600d9eb6b7d3a25f718d40b5f18f5384d27782b4de90bc418b5c232b1614e4520b9fa6b47f5700806530b95a170921e1a53c4fdcba30f9aad59ac8b28710208d5860a529e1a1ae1208dac52ccc0dacdba22230d71b63b32c857fb1ebfe939d5fad572ae0828836a8d9fbfee7b880cd3a4278e5a3463b394849e731c6ddc8387ab43e443f6beac6971730dc49f700632d089cdc7e00deb0593caf0ec76d05df7b192f73f23184d42b4f7ecff851adc419d75c077eeac863014de8a58f9fb325ca546421fbad6c62aeebb8959f51e7a1ac9d29b9910ada085c85d5f1837e1b57ae24b4b93f5df9997cc73e04aa36d6a07e0d550ae270cdb3be37da01e4af63c3931343b912cb7debbabadb7b522d5541c335ef0a5d0c712d1e5d38de53f40df5585322467df7845f810c68c76dda9da9fb5a6b7d92fd5b00e9019dd88f5579c552ff95aa491df6dd2fc09cad9ee085f17ec652a4a385ee91732c0557620bde0b8b1a71d7e6103a8e90330d7f82aa9872d9202a630e76ae9c1737d1b658b124a124bb19e866afe9ccc25ee99b0e00a8214fc37ddd4600b27354bb58b332c9d6d78e690052955f4abb8cd7492714c59e1f1a848db44fc601834a812196c18189c36c1fa60299c464e1b246264be61436c4dbe08be8f782c1d1383b32b84e6fdcb922d348c2f6273c4c8ee0524989d1646388fabdbdc56fda910ed365a5cc8694d6bb314956ae4b39dbf999381cd7623de15b9becbede367f99c1db1d373769d30db38909b162e4339603e18e8fbb08d1b416463454ba419d9045a350749ce859abc5cfa94364b688a6939f88b325fb96301319cdaf405354b9cd62f8dd2c2fb9b90189a60bf9ab11f3108cdb9bf0fb5d7537f67aeead166028662ca07aac57fb86704e0d83217d64bd7fad12acf24dfecd197e25ac6bf9cbf0cc65c9bf148ec0cf7fbfd71dd6ab89358a7510a4f014879568fbc7aa6c6391c19f026879578348a59c7d35786fccac19f0bcc5a7d790080459e0b63d50606a551bce726cbcae2c01949aa3d35d47a5aa461d5301fd0b5069c03439c8304e5e76258283ffaa5b01f32505105f740db868ff561dbb0a45b2e2b72362250481d05083b10862da728fb926bb0b8ddc35de8cf87d4169562febd1a524e9b533ad75b41e59e1c8a7c1cba1c9fdcd16eada51cd5d86769b9073a9c442e7acff625a7dd10ade5c05fd17f1079c86334459d97ef4ba29007a5b4a64d804ce84b38bdcd8e02c61d1f793d50c60c7578cdcef582ae4dcca74625ab6eba6a2828937c2f9e6ea9a56ada503ae4d900b0d4ff84f7b01c51972891285f8676c659227ae3861b0efac63ca07668524c3264ca2d3ae502a0a342f60856bdc840d4a0d81f4018378b36c0cf7805f6b52405f25a29b75417622f25eff1ea2337f286acbae0bfe368d0c4580b941eb97328ad4623d743de60613f6cc48f248905479e7467abc63b1d0d232c3cbdd3cc0b05a7d93b49cb47e1bc20b05e4be2c807df9dcc11ce60e8f85c6d8b2cad1e9fd424b5e65078c778c41de4972bb1136dd8acd57fcc7f5f62d57585eb39d43d807705ddf6e0b25bbbf0ad35e417c713aaa90d1e75a3e9e411b583137f019b9453bf00d948ec7e9b88bf6e193e0dd3f8286bec8f32ef8ac2c8588858bab1c984295b7a44a0f43be0a3bdd44cca25f2c6e344304047e94ca94bef7d4567f71e1cf7660284223276374c01ac173b543217e095f77ed05cacff9b88752b540c300f6ab1612f8c8009e470f8e2b7f3853244fe9342640b5705949f58279d57d5a41e2b73ed2942981cbd13e6aaedcb0cb56dfdac427700bfabe36698f757af72b8ad9ba5a25eed143c1bfddaf0f0a1ad613d3857212e6a152a0bd13934a7f9fd567a5230516468f2deb78fac82a90909ce81073f2ec935291c3f09b3279609283f490fc758819e09d92de5f3ebce545a35d564e576f67f45158da1d4646f8701bca2063db25cb02a087817da464a2a48102e3877e02aeea535fd4da1651a1dd565618dbda9c8de4c4fd77c41818a9050688b2578ccfd1b4e23c17de61ac40ed2d61167afcbae548a807fb67c010eb26b9fbb4ce3791f228e70e06b48e8bb44086dc5f4072352bdcd1456582f206bb3c078d09787ab047ef547eb688f07e30c7dc30870156bbe07a2cb6f716758274632606f0089d4ecf3d73658cb392a0528a80f19779e538d600323ecab97a0e33e9a25d1817902306e131759c315b6857453287c0c46930b4e80f0a7fe4ee082359b21a222a1bc1d4566762e9dec8f5dae24eec8ce4ae9b51d492a20e4f923aeec1b74660d4b5afa370eeadd288e63943c6c25806f60a77137546ffba9091b0ccaf2093b6ea353abbb5cd03c56ca06b08a4743232cebe01817d8f75aba377972b0c7386814b35c940b5b1243e75dbe67d8f434ec204223092f4630adc1ebce4f276c2604c0b9785106138d63df3fe69681d790d1a054d1c18d4ecc2583cf7fcb087d5311404e5a8a51613f932174ff93e1bce5580b80abc9a025281091d46340a90c63a0ae926344f531487a6dcd78a6df4dd7fb8b419a6c9d2ca3031aa8c28b5d30ccba9a0ec5922617dcc1ebb501475a21a6bc70491b98de1303dedf668a235f05dc25451a34654439ef38be72d3c3d1e6cea9a2f3a7aa3040a48afb45665745254483e64dd3bf0f21a021ef8af767beef6fd2dade7b6fb9b794324919670867084508159ce241391f8a15cce82573d99e4721215b0e69f32116492f872d7b82b1e7130e23ec1d8a6c5761cfa71cc4d0c721fdf555917376396f38e47c05a91b08220404bba6b0ebcd3b8edbf88d0d39a72b67a753994e4d3913131393eaad16325f2b538dd5e9baf47495313131c9549ccd76739bdf820809827f88030df156557df97d9021df97f3f6e921425c3349fa97ced70f5299aa4e22e71f80ccd720383f3ecda87134b665dbbfdb6c1accd7f82017e69036af43dedc5811799099f7b75a8c968b5aa53a3950c5189732ba36d197ffcca9413a362f833ada88be74727490ea2269527551261a5d8e32bac4b54a91677454ce5fd6589783973dc3ecf944a508ce133991d3245a8489ced3292f60a638207b782bcc2115e044b3ba847e7e5aadff71ccb97e2ee70d290781726f8abb6a1512fa11125acaf4b9a319cf01e3e75a2232d7653ae21163cc43a61b7f0d32027feaefbcc7737e9f66e1b0ff8d7bead2e777d8b1483211bfc683c4af9f45b2c75d78f44e63f14642f0e78526267470ba56561a0511b267ed7ee62df339dd6920d3b6e72cf2965bcd04ffc45fe441d8b1952157ad80f1ea3ce6398e35dc98c70935720005f53eb814972e5251f2a42f4f33c98125792b47d3189d51fd64cf9f547bcbee40d2d122cd9921cb38214f5697e9aa22fe39ef794e0aeef0f01dcd2ae2f99de7016f686e6e6e685c2c0ae1b5f3532ce2f91d6dc4d22c9adf791e2328453ccf7a239da74639cfa3270d196408c9d344a6bb88e76368232834cf13e38f5e34ba88f53bbfa3ffe8455af03b3f027ded3c110bf45797b3a6ce4011eb6368a30de60b5797ebdc6258f05acfea22f5cfbfe6d14444a014fdf3b09ec86b9e8fa17d54d78e26b2f33c12d8d19345b2a69e3734f3e666ded0cc247b3e157948223188fc5bc062c578124a510ccda32d2089b0b4479f8764d17c8c9faf1d9245a3591aec3ceb79f07c0ccdd2af2745f67cfa379466521a1a4a3b3a6f665ee88d66d2190d79c81d92488c67e9fcce4b20e7799ec863901a5717cdb348223abfa369e88d2e799e88cec77831e7795e7422a6b5e753932e36bdd5a0185fb67462b030d68941d2a51f37dd79fa19c88393a44b3436714c2239cffa1d92f544747ee7a994148ed40d95da8941ea3c0f99f3536469a0f33bcf43e777348f9c67fda4d134a665c89c8369ce5325a7b11c927271973f5905cce2d0db796fb5bc2585e3230da494c65458d08fd14af3294c1b3594066b01be699ea563ee3987687e262fd190b5c8f4a15f436dd414260dfa744697350434d3a7359cc77ffab331975c75d618095c69a8a555afb5d65a6bad4cc250e7ea129fc5037cf1411edf8f19c4efb94ed0ddedc67a02196f501a9235dc55b1cba02293d60aa91a214170e74136220265e6dd841944542f3083beba6acab905de4e65a02eac204e2f5e359ab56386e6c397919973cefcf44b9a65e67c99cf794e994c43ffc7ff0f22c4c8c78cd498a5b254760e09aa770c31761e78cf3d11d5ab5eb45b728e4934876ab63f03e690b7c73999f0a5cd73439e7bbe549ab5237c9f2a529470c4fc11e44021777b4fc1a713739cc8fd383a753a6e6f15f520f248407ec99c95166a6cde62e17f244b0310d4b3ba42fdbdf72c1edf7bffe9210ca82ec7f97ecfe25ef5472f4fb32e0f56f7e37bd5177dafc29d2e12fffb4f1b893a08a82f77b923a77dc31d44e5ac95dcd37d1fecc8f287d57d24abd33c42cdc21f3eab7bf18f5e1e8b8766618d9fd5e9a2f0456d04a57ba30ed447af8f7ef0b3af2e77f4e81de09da20ed6dcf66a16fd72d6e8d482fecfa169abd17e708cb9734f054a5d8f53e720f27c23a55b7da54c1f865cce5a8f1e07b0f9b2c70e4bb78dced555675ceefb9cc39f9a6c2197bf417f7fa10c727e19199907694d4d4d4dcd1fed1a7286863cdaf4ee194d004a23d778aba7ccf8f14f31973d1867f0bd05eaef896a06d2336d8fbbfcfd26230579bed338e7654ed81caa2d6ff5a81c9e400298600c24597cd5ff84b5a6227790020075eba706f9f8eabcfdfcfcd4e3fc580522c6d179297871dc79a794cd49085b4af0e18a06e8a65fedfb73d0cd2f69be317dfc9843d5fd68535dd20c4c1acd8714752a66d55bf365a871a0f11de87bef6b70e06e0f480edc8d835f4562ee31891f879c791539f3204896cf7a500764913a640e39a74b66becdd3901eccb77970d2d8d0d0d0dc7d43f33536244d8d98f34a8be2ab4abcc3f99ffe911cc99ed68c1a42b46cab8c29b91cc739c739de382e019c3f7b621ea3b573a649ce9ded4fbb4c707eaffb3c4f5928b6dd976ad26cc81cf222ef3feff1732c0dc0ff5e02a09680a785b86f85dce99f96c692e7972d1c5626cb0586a6249854d75a16955cfefc30115fd4f993a2b69ad0aa7c9a55b40d0ed9355c7df82a92a5c1eac3950e593c444a021977ad1f8c1bd4e58e0d64dc5de7e9ec2debdb3748c351fcbeea12c8b824cf5de6397acbdb75531aa30375da03efe9db0781fcd8ded34969800f9640c6fd7df71fdda08f93d2a8ef7df7def4967f4c545fe341aaef6ab8cbe61a845ff6c7834106152239bd14402e5d6c5ba06a332c539c644f9230c59468d294182f37292e5136da6ccf396d92284e2f66d25470d3443c6923793e408a0c14e61bc9656b0aa1e5219583214186ccdb10212121a1214184dc820819626b90213ecac965bb73e9600a5187c900ce9eee098b11d410eae004f9870f4c6f4a18e7dc026343cd98261f64c4f063e70e358c7bbed39eb40c310224ea8fa48f15b9be9d35deca795e1921c8f4e73741f10ceafe665fe5eaa2df91a3eb31d32c3cc9db3be77c3badb5f6ae6ec77d3727be42ba7d6fc79153dc2f338932c05bb5ce5ae7acf34e3be79c13055b6bcdd95b638db7eaf8f3738d07e15725725d9b75d639c588961662a081d6724d87f1e8f3bb3927ee640c81a95bd1b39221b79eb4e2c7176cc894882cc3c8c4fe018de145a64bb116688c2679e09772d9836589d326632b4c1a2cd86c537559186c069b59d8ccc26616366b22d3a99bb764907053ed404377bd12b99cb01ed56dfb615b9876a5f6a9f745f7056e194d7269c19e2419e791abd5a095e6a654535c4d9ce26ae11457fba6b8da9411d989da2e51b9be6572a0259b85b1a5551f32dd5cbc55bb484d9fca79315dd56a6e0a964beb54dbdcd4ae5c6d3b3950978a85ab511bb689d2a8514c1b1d501af5837e385057a5e610f7775251a718b7e428efc2843113a5b3aa5845f705fedc4cc06d39240e26666afad8bc55bf036ae37a3169d4af5bdc755740c5ae17cce865d7e7b22b4db25daaab3ebdddacd3cd3addacd3cd3add5ce64cd68969774c9cf8476fad2e52a95e0cc53ff2de282c0a8f9ea8c2c96892cb7a67170bd4add52099b7b65ddf3a554bab41aa9fd9da76a95b0dfabeb6987e698ce524298c731ec77f0ec95bb5e438981279979cffd1e66033651e3919b5b134673427cb7a756ddcb57132991179cee6d75dd65b9d554e565df53137e33e094e46c1e92d3b9bb1e8ab9e65ad18beea45ad7a2222c521cbfb30b47615eaf9b29a45f59c3ef44b9f85abaff9c51aab41add68f63ceadd6ff38ca623333dae803afef3fbae5ce2e964b232f945f6bcba49591d689b4b4a66d6dbd55579daa4cada58f8d49bb3e0ce39cc7f16b9d7948642a65f3960c156c5cadf39514f58605164eb3d96c369b952e639a61ecb719bdcde8cd6b22d74a4295aa37f0e7f392e99e52f5bb881b8cb01a3366cc181ef665b5d1075eb53e91db29de72a95d7acd69d5e518e73c8e4bbee42191ad936df296bf0c156c939d551a387b26b561bf14aa957e65a25f659b665b6bd3a60f54ad2e511a54575d0a3975ea692157cfa272d6d65a39ae723adb8c33ce18678ec6808ceb679cbdf5b80616ca00d32c0d6f418328eae1ada794524a73b05f605c6606549c39cb71d776ff5383ba9f5151c85f98c277b2eb2182a00782df78f366f8148681873bfa8f45b6df3d7d20de83e39ceb541ffe286c485211a50e7e08f93c1c9233dcf579b88b6cfd430e7c70e01fd698607ad8aebbbb5f5b0f9bb5e500ce1e5b6f489caf64f717e4549d4af5e148a9be8eeb4221e28d215ef27df1c3f70fe242fcc12eab9e95f3ea698c6e0cb627f1f126c47f08927f5ea998e03ce87ddd6c776fb5c01dfcea5578ab5ea5cb957ebd77e28dcee66b74996b3eab9e136fa85636dd156f745e87f3385ff3e5940b7a5651ceeb60b104ccec959375f6911cc9eff90d828f7d71c89f19def2bf194c1f7f2297e55b3b20eef27a83780b4847d627aa371e791dd7dae5c774f95b5bf30c360fda58a82120f84bb9fb297aff1b74a321b025d9932948494aa0f55fcadc7758b2f7436ebee36ede717e14ed88f3f6e7fc71fb569348320e79430e7120f0e983460e3491863890ccd33772a0fcf4296cf5d4ea00bfe671805fa3774de99f679ee68866c65b2b585efd78ab355d572586de83159c02998c86d050197d42a750249a4495c0ea59b0bdcf14e73c8e38eff842c89e0d91db904614667443da10551b4cf66c8e9c1a3284088aef518daf9cc0492bb520644a0477bb373724ce0be15485c1781b57c8be3343e2663dd7e49d913aab1625a34dac69a9537aef0d0a83cb65655df5bfbdb07bcaaa7f854f5f2b4bf3d5caeb05b32390ea8bfeca3aad766ddf03b5c5813820de739ef5dccee37c0f9d1f9fc82f4b039ccf791ee3b334119d1f3f47138152a4f3a376223b8fa367d5e58ebd7a276985cda119384f593c5fe218ef896f693528869ea00ec9b279d61fbd7648968d6669b0f3395fb4f3396f63a38b749ea58d705ee78dc6dff9a3978d4c4d6263e3394c55a66b4f4a28bd0c8dcd8ddd25072a2f9102aed24d427fd6d97c5961369a01f4d26a9095c9b0954d1ffa443e3ece4f7107d2f8384f6b8ca624b0d826270762fdd4a035879f0c84223082e390d7e62f17072aadcc81eca67fa11c683e1d9164d3bf3507cae9726f5436fd3b75c5781012387b3ac2894d9f43f2200b6637ca81e653d4d4a67f6d35887bd1a7b1b19c549303952ec6c9814abb64e640e58dd1689c9403b176143d7120aeb669cd61534e0b962807e28ad8f471988ca903eaf6bf4b3568d4383fab0b07e779d02f548680e16818cee3e80fb09e48901fb50f0dc57ece8f5f4e2928464a694eb39ae7894c7ffc9c37c27919231aab2efaf9f3e3905df2ac2e1afd95ca1c9279fa76c981689efe172b6f2c77311b2edea22fc5066fac065d8cc7f1ffc67c767963565f30a60fd78593f2168da64f38313b2b12c86772c76d2ca7ef359ce791f3e3f3c0799636ba800c45886961d444a014e16896e76896eb1d398ff3b24f72c891ac49d5451f87f4c0c8b6c9ca2a8c3e7943f6a79756832617382449a18b2d7ca952993e14ca8322df9a7e21e72faf8d78634647fed5e3c8bffaa36d146e9ab7214bba6d7e454e9fa2dbd4c8bc2569c8b267cb4cd7add9ba4f9f1317d0da20186dd583dd8ab55a55195285d5a4ca549ba6d42ab5484db2b2dea9de82adda5161d5b54556ddfc7d7b4356a4ebb72679ab223d0e79539d36fd90bc01c91268979706e4d1c7974683705d6115e6f75eec15565dd32515c67947362e002720931927f1cf880f6230dea6cc271bc46cfbf84bbaa452894856eae9862a9b520c367dea54836848e0cd061836c5917a9a12934da1af12718c2fd972308740a03bffe775b853ad38ac9736fe6d2d7e2297799aa791c9e48aecd103f45820f87d0ffa3528cda6bfc34707f48178902a03fa440da00f7e5ec5f11b8421db3e91ab2cd8f38efe434bb69a49d2bf66de897c86ac71ab500d2b43de0c6a58fde32d2a02ede77afda9d57fc22f403c5b38f006c1687b886badb5d65a23300218a72a3e052cc24c728f1d38640ce8272b70a9a21e357aece851eb9173ce3d7614d57614f5b876470f216fd11d0ed48383a639a3d4a9d42541869111b8121a62d304304c774ab3830e5ee825a4160cc8c129a54e67b0369b0d2ac80bb974a6ed4c381f26a4b0810a909cb0c194131352174b4b92a49e9cb04198272b389cb04117b35188bbe7930964bbcc2f83821fff01402dcfecf954430e4872def3a9862700ec90ed9e4f3530d16252c30930b89271f67caa610a0cb8c8377b3ed5f005064932b7e753939809983e882376d9da4118f1f3d4e4896df77c0a22cb2effc72211c2fe8d6e416f357e684de6533f326a432693c96432994c269b426cfb348a6ec102de2aeab8dc17725c48e61a2e871c076ad61742d1eebd31bac51cba975cedcff3eea55b68b227f7094b8a9555d9cf8fec3ec634aaa3356a1b41d4dfafb26bf316a63525b9fcd9f6e7caa2b2f7fe6595714f3c8846d9264ed31ad6b449466bd40ba5516b5fac179096a907f8c1efc41cf8efddab2c32f7fed88696cb9ffd8910d0811ffc4f977401f8131d007e1962f2febda4ebf89e7b1c9fd6e57d0ed08d3f141fff10f086d8032f28d6f01f070aeb1377d9fd5383ec4bacb24f844c65a0906f8da38597546dcfd21a9555998ccb94d04daac3b4265bf27e6e8cb36c2cab7d8c7f7e644b41e66d6aea66696dde682d28e7f5bd87dfc3182fc59498c61d5a1bdf5bf6b7a53177d55fc232d90f77d5bfe1f903ab3f4e5e1559a65ee89615d4cae742d16899e63d7eec698ae57b0c7edf7bdf73ef69968efd7d9a45e49f8f92ec3dfe3cefaff7f83d7ddfbb98c5d95a17f97e496b58bc55033ffa6546a35e6acd05067df095a0bbdc4235c87b8abb77a1246a63ca31c65dcedc385eed49d3870a2565406dcca7424d55897d1afad21cca40d51cc7dd0feac05df62decde3fda97e671a636a6aeb6193d6748dc7f1f57bf7a5939be520412fc05e5fe07f7ce9996dabea44f92cc913c4f644ee7b195efbd77ca5bd6ae7e7a6f6b49dd9747ae7e5457fd624e306bbdc7d883e9a0df7d9df2d6b4b86e6135551bfeb2da7c78ec8703d9c718df171f3f381590c59fa28efb62102bd47c78cb86399bb6e9be242bc7fdeeaf76240c2359de6dbc7b64c873a685a9fe7b5f6dd8615ee891d5b38fbfa55c4e29cf61db83d5a095d6512191579fdfbfac369b03ddb78e64ab5230aca914b539aca43fdcc81ca298f3481c7acb72da6132b070da5e68f394a907f7bfefc41cf7f183dfd1ac412b30c4a2f844fe7da28ec9e56e100c6d9e72a981a3fdbd0881fbf8a9a8e33ed6e2026e0e6ecbbca72120fef7a07843f51e693748c57b498f043db2a45946836086035446fc4b8a1f79ffc7c6ef91e5b83d2aaab4e7912009641499e417c9efc03359b7b8cb3ede3e6a107e85d5e642f6245d4596b97924b8b915595f1ea9da5ecbc95671b54d1ffb9f44c67fdf6e9b44436de88420b5648bcd1f35e847a806e159fe1ab3dfb5843cfbfd2f91ab6ddb47807d960eeef1c330fe74b5551bd374d9c738e7d1be85652772e96050cecb3e2659dfe3cb912cee3bf10698b3bdc061298b124eb25011c5cbcea72a4fb6ad71e40f3773577d1aae65dbe8f597dc559f09cb72d3e8447ad9f57b68c81ea334be8d1d40c5ecea91de86c1e61006495ec4811c68d33fda251583e9944c88c3ede202e866e5c07fff6a0a06a4625e3dd645f9655e461be53f7aad7e54d74c4bd39ee20d16d644afd5e7bf1ac80cf3020a609b95c36efc7663cdd241a996dabe02fb2939932b301e2b8703e87b9a95833bdaa0b8017dfdd08dddc8f4194012d89edebada6394467d0b033d00571ce6489e54679ee4451ce6b0fb778b035d2ae5405cbcd6a25d5a752ad77f3a356d2dda6ad1a9d61cb25ce89649a5f6dc6293e026f0290d0acbcd974c706ebeefb857fdd7618efbef31c73ddd9c7deebf27a737ad0762fc16bff79da8c33ed656b3ec7bbf7aef891c7b7777f0c3813e6ff5f777d4a05c5d36e5b4edfb7bda68511a57e61be040f9ef9713887dff670ef9ecfb42431910cda1f0a7456dcca8d1337cd34c99e11bffcccbc8e819a51fa6192b34cd4aa1cdc29739343708923e4a72f8f8c507c3f0c110fc50b374ec30fc4007a859e0afb417053e7e9508be07fe07824f37087a9e66853f37793189c36421fde3adabbbc8dc7f24ad79ab7b16dd5ed73dc61df54269d06f927151497775e8fa56037463fae007a0d8179f7b20d6f34992bd0faa4f926c27deb9e3c8f34466d9b7f9a317cedb7c11cedb682328f68d6c6eb4d1cd8fac1cb583a37df7557220d5dff1ef5359cddf2f2993cd25aa2e990761dae821c481c4eeef1b7d39b9d818ecfb3fe690b53113640e797f7f86f418a5e1e37ed09c5b5cc5c53dd277d7819c7843fc2b36e0886e8fa43ba434fa3e6a1c94f4874d5f6a5fbf403cb12f9d4d1fea4630893fe78f5e2c5c84f339361ae7b12e1a6ff4f8472f1cfd63247fd8903e4a32cf13f95fadeabadd83fa4afefbde5ba129b92626eae0bec43177900f381fdeb24fa5541e328194feec1e634d044a91c703130175d6ef1d49ceeab2d406f63ecffbc00982a27e0f5561a87aac33febe7b173ff171f7de73f841a29f5951f75e0b3f58ce19f73d66e9a2efb1ce2208740c8bfbf74816a73350e4fde769efe70b7b9df6e93345d007d0079606dd7bcff2c7f8e3f19e03651d8a1070cdcae16fdf6e513adaac1d451cf4b01ab841a78f156ff8f4b15fc5397dacb621fd942c9313cda93ab5e122581da6ab5aa71ea65c72b53974041735c5944b677272a6ebe4f489495cc935683aae39bcb7de516881426f81d3a77ed9ed59bfbc78bbb73440434f674b52f04aee3607e806627549b707f641a863c64c4ac3f334b65ef747bbd3737bdace21ea85d38ec95032379dd2b0356ec67536fc219716466f30ff0a951f67cd894bf7062edddb126c093687a610484df5a32a54857258ccdf22b92d525d04a424d8f4a9e1835f86f75683426d911cd4585bd86d5b98087259a796a6e6d017d446ddc22d714b4a21207912ae23389dd93974c31e11e492dee88dda006361b0593dfc341310cc5d7299bc75932c29792b367d02fe2ab29b2ddffe73d2f007a56a10385dfe17cc8266fbe3f8dd89053092bbf7bfa26692f42f03fcfd02a0904b260678efbda73a039656010510720e4a5597006c752a80ab0a352b87dde1db1dea92c89ef2d6fd21d2c5b8ebfee7449dbc75df0024ade2aefbb8bbe0ad063d2875bf8252fbeeaa2b92b7eed7f70fc37a54c369094b407f70b5e78d1a5bcc9e9e16a5e0ea468d2db2f59608d62099caa4b6cba0613a08e298f3fd0390867bcea8135c89392ed8ab8a63ce39e7cc60cf05503de7a474ce39ab1017b470410b75bb2e8d4400674f896f168c07e125eef2b762ac1824a4224536bd4a5769d3db2eeb33b164cf2b7b3ed9a43678410bb509492e31d4f6c7500e549b1c33d5251f6e870ab515e32d5f926d937bc923b67a1e554a4df8be7e5fbfafa0934cbf76b5ab5df7714fff821af205dfbbaeebba0f042b58a93bfeeebdeefbeec16f00bb7bf0ebc00ffcbefff48c06e85abf0026f4743c20d9b2c17724501b7c47e26583efcf3de824d39f18e76c671096c9d9b30024e4fb17d490edf7e0b76a1087f3c61bfc48b2bcdec23fb14c8fb7bee79eee398740a0377fd101fee0ddf4afce7101cde10f3e48410a6a0ed00dea06685b0013aaeee1ee131c0c91448230823852041058182145f45b1533850eb31d5e68f2058a2ec9085937ed0e6f29ed700205296870d2430f598410a22b2106ef488f274640a2c5114d767842c2b64f63bac0965841142f4628cd89050c2b4788e08624685c3a101851041fb1e285d203591246872637dca0e48a0ea966457ea56cff61c8fe5697970b058630010f5d58a01dd1a41ba126e5dd0bc05050124b0285a8147422d46c58cbec06a428aec49a88a10ba196053c62830d2928a288305844d0a183d576a0a1476a0f15a69890984a32c6c68da94de198e4a815ac0842052b5d48490aa31685b3b956259a8070fbe2851794623a7814b518564990a00b1451b4c46ee0c0f0e891da0bb7c9044249102980e1e94b1556c4d490d85a922a27a93e4e8044851121d030821b56501be132a9553bc50aaec4906a21c4f0851630d65afb46f28eb1ba8ce45aa9d0ca83521213145844b0a289175abe702e7b1b8a5411831329a418a946b4508195b4446103432e47ccc930048e0d159640291155c44a186e4acbecbb4942a0a549971f6eb089208c161cbe7b24532d33d0e4249e444b0ba1529416116c8ae06265e566518497ceb3057ab86551c11547c2e8418a1364594060c20aa618020bd74511537858977e6b0a9e84cd051b0951bc38c20ba78222b6747ea4c90b51b531379cb083162338304520e1719574627b62427241072e382e94ace005081f76f832858a6fe96e96215172052d0460a2102326054530e52bf32506206e43d41053b205e74b59e856d17a1223c4174d285061845b1125a86ef55202272a2588218c089c1663b02b390b3cf4c0c50909214449ca62e64802bef80085890995159c705fa400b9903282929426b65ca14316599210a960295964b952801e9414e1f4830a9880e15464a1225ac942823c44eb10173c48d990c20f27c8e2258b920c9309446df1c4c6b43404150e6a0c9e4018148288d5848872e3ae80020372d34a1434ae64950081ec3df244834c0aa72b2a4ca9370c111ea1800e26e410a50a132454b1026aca4a890424a258c941845b9410705da0986aee110a85e403b27e641a51220cd314314f5e64a9022ac67147fede7baf9523271494e0e10729da123a380aa0eebd7763d764cdf4f1b7b73c87ae8bf92c3f846003942861603b7054101106c621635cab942423584871e10a264b8480438117d78fd401200166892c4e8cc0040e5c88d862ccd3c7c6841a5875a18b2b218922060726aaf8a2045db829a0f08e14e96207134819610a14332998e8c00c332c524ed084165d4411757d3a81029715580821ea85239c1411b4d06a21e20a771d8718931980b08202a530382888a8c2390d242c9488e24452d416dc13449400ac4cb630c97828e10712e08965b6f260d10483ad8a2a49ccc09d40866dddda975f212289c68a063688a0092648c022b6026e0b11307ca9fb8c0bf188148d5b6a654631d101d97be413620431b0c005942c60a858640939772b26e894acb5d6e71347381183a2e9052a489c280178a402575491c2298523312e4d2c11876841c458487001092e464040e3981822d6b9d2bdf37ebe3fdeff5b45b02f09dfbdf7823268c073885e24c0ccb09e5c266b7d66a1457d7757cade840acfe7e47499afb676de5c75b02a7cc102172938114105596c4fe0287984791de167937a6489ceda24e53273bf4302b660e2842b5d84601ab344ad6b22e2e7a8290c122eac70c10a09342580105725c83e5f2da8d5cc5aa11a84adb5b26de8c49624820f25f060c5cb72496cfbd4c3b65fc381eeb6ba0432330bb9c4e37629e0cc1864e1436b86002c11802f0090426b842727d70bd99312002926188491710c00a892710b4764156a7882b9a2a4208a36050094c8aa3d9f68494cd17ab8e04bb6d9f38956c3055eb2b7e7138d89b62484ecaab0f29f3dd9b7df696387d2a0efd5bebfbfcf397d7be9e307d874cef93bd4460694067d9ae9fc0ce8d379c3891c4fdd8e727eabb575fe4cbc13a3d571f7bd960e28dee8eecd1cd97117efe018db6d0f95ecf70904573dac7a08c1cfc3d539bfe00ff7feb8add53bceddbde3bcd65abdd66a2bb5ee6ea79d6228aa9c521a1c9deeee95d269c15a6badd6ef9c40f54bbc7184506a963cdddd67786b3e56d27577da8eebf0c59ef5be0a86d37edf773f50bc4f2c8ded8fc505d8aa050c7113f3fbf9de5d3a5b5dc6a1f50f745eede52e77b9ce76b8ce983fc36e5a71f8f8b10801bb3d2ff41e04c3190ee4aeba4419e41aa48090da30402b4a559d70b57abb7aa562ae4106982e7f4fa62b69585d6b9986331ca8c39d9d1ef550208e16dfde67163fa420b3fdc71f9670cec7ec72e5cb9e60268df98c12c1fd73eab4e79411255d3869f20313a957d41662d3a84d8308c116df3a90d0161f146f882a104cdae18be2e73065faa26a47fc4fbcb152893a0376871ac89cdaa01e91f87e9635fbbb32667fdf13104aec0f0b94fd3d166f7ce3f6be136f7806c0f80a958da5367e4ebc8127d00092c00cf083086a96d96c5b5cf36dafa8b7432b0a12c25851e40606edd2d0848f4000c60e2e3c4d75310b02091fb6503a6bcab3f594a504b1fbc41bdd986d1f639ff2230863892b6ea0e104501c314495afc3d16996945cfeb7ae053b3ac4b6fd6c9f7c90b22dce6073dce7a80d04051412dca0786284941767c4e6fec781b8afc1bd02e6e68e0ccddd75dba78722db5a2156d7ca0c3be9e8e704166d267c2a98855114f1ba9802b338018371fac29410ab12c6065cdc02a103a8942df6553d0b11d90800000023150000201008054462a160349846caae7614000c7f9e487c54968ac324c861148490310410420801000000034668688a036d8f710c200871e6e8a3c2fd99197feb07902cce524cafefd92f2272bcd65401e29fd44a851cbb690287d35105a34ced90c269de87d3e0be909d91bb5fa76f679e3117fbba73089e70420eb9c6e748c104ff861eb8ca2b4f51f3746c329ef600837f76a8b554fa6763110b7f4471eb75b4a8843c73b2372d6fdd865942867896a2d7345abc89abcce20d52a29b6128bcd81db8c86442338ec234cbcb83b6365398fedf854fbe56c2e36f1919cbee65ed49651a84b2d2021950d80245c84933fb059f494e33b854c2b17733857119ffdc11fbc0a82805171c16ef79e67f9e508bcab21dab9bd39fdd34e89117ceffcda36a55d60a51af47ead2570ff91d6970548457d049f538d49fe984f55a7448217630bbba23ee863dafa605f916929aa8c9556831477fd2d67fdf87a78a645e24d71f83fecb1ac1c4fba479b8a441b2ac63d25686ba86877030a0368225201cc865e5de05230a1a5068326f85ae1db86da83a1b84dd5ac66478224ce7c46b31354232fc493dd4a20283fbc2611d6b827ceac5992aaec1f014a6f3c4fac1a279c44aa76864b811808fe53ba7669060cb5a591fdaa5d1593f25a4afaa50e077acc90d1386c54e71e81d4c865a2e3e2766196e6a177c2e6d2aaf5f70402d7349561510db41f2151cf10e2a10b00f33e25c212184dd76d121bf4b8884e12590f16df0aefe8a6304f006d9693b9f6a73f5e80ae38a013717e144eefb77d3705dc29d984dc27a6cec0ee48796056bfceaedec36043ca5fb045d17d472061b98c4feb21138944c98a089c2cbababfa11c4827a16999e6a3b28b1b1342e0f87680392c503abef768825b451e818765757622b81ab5e217f49e4da8db92182f14121fd66bca5ac8726f3ef89b8b271097bb930e24d9eef729921c195378342661f36e92d849eecd130e7c7bc327653beaeae6f6845db752730f65a72a78fc49768ce0112f6225a100578128f489e79d1885b9f7bb00c1b0dd565cc633936e97440197f426c243ffb76c482e9826d733c0e3646f34fc6c67222cd93bfca368aac23def846c5728ec3b129774bec3e2e4d0b649c49368dda9644eb1b9b48bab135c1de477c18ee7221620335ab8a53350ca6867735764d98a5c238056f043fb133de1817074fa4834fa1297161212ad602aa122bd622b67531cce05f4db869de9249d103eff160a216b67be296351a73c72c2a1db5fd7291fd89b5a4b3db780b28a22dd354c8dd48c5db792cd964413b400e6d521bedb08fa8aaa006b988ed2eeb0ce3d13c48f88270cdf57794d4a4a5b0d35288332432c4e6de9dd37e9323f52637ea01d43b4b4eb213b224211288d915d5192c82341d15eb23c94591665a3b6007d41f901e3af918fd4be2e548e833b5c30ab5d456b8b90d58a1b11e01e170cbf870024d1e774975734acc1670c4f50496653161b7488c5c799244005f420b4e0585e7466a0e51aa980f59e468eb3f42eb36006b50aa93726482f5569b95312cd5489087d340e3b00d339839f8f88fdad053e7ea13d8c9031b388dc5256f34874541a37b04672d2944331b4eb190e0f665ffe24aba897b774ab1170dd37eb49c12b83ebee61887d905bca2fee42a7b5dd869d9725bc5f8cb96d3af5258c4e73e9759806f80bfeb254a4e61cac8551876fba88335ab9cac5c2ff0bf3d0910cb132763f313fe432b2d06c76b958cc9398e9a4694c911cb32c6168567e2874c415115d534da8e3d836bf9cfd92f7521fbe09297a3dea4465612352a76cbabc51d4e78925eda8a98a86291416b539ad401209a7864744a5a3013003c65e2ff738b6528d7b8c404ff0637ab0bb45f3b8a9e4cc9f0593981256370007c416025a8ca3f3a329754d015ea4ddc946922488b0ad28efa94a8f453a8f6657241b86640952350a862d412d01c35369833306f0889643f44a46a468659483a5d84ef7f2aa297eb72a8aa46c5f7b63215e395ed2948e3d05cd5e3f2a5ef6bc28208d2186b29fe9fd4dc77494f40476dfa33314401025e02da5111fe31baf7155acc08219680ddb1a54409f1b2510cc6ee9d202e3322841bf706824106fd43652eb3dcb47c204d3ec8b905d7b1b2f2031b13439eb7f887acf40d21a70fb149fa59c93cdf295a897643186806b32be00f7cf31ce2bc369c9d4f35356bb187f51c289e4b6474b5e2062c6114f8d95e69919c89b352f09514d282bc828404c2ca8e753cc7b705dc7b2471c693b62e9420a6b981402c1aba62eaf8b115d1f53d468bfafb6d517d1d9d6a2501e571d509a3eff881e11de5b7463775a0002d7093b55b24ca71acdc3be4b8f474a6fa64bd24b98a5aaf99027aec3e0ef6c4b7833c81ab30b7edea79ecc071c2ea37038870a228971b9311b9ea2ee7910f26f5bcf29655e4b85e89031b5f81381fb279dcaf80242a0bee71db5506125d5285062f242725ef1e2c30c78abdd8e7ee8b2d374a91e0243d59c7acd54f46d2be44c0b7b27cdf1ac684158ab40c58e6df6a2a3ead8469e3163be4178ecfbb53a6a43b7a4c895246d9109f0e0e58dbb7e596217ab5804742e86c292728964f7de04dacde186db7f09d2522751f7e021596fb0d4f8da8e5df75449f170178618fb34b60a24c43586d6217183e275d9325f509aa248e94c9cdfd6c1c2bd2cd3ed692ff0da7f923146fdb2b39ed7a835aa9d174a672adec0d8936cd7222935e0cf19db4465f0c99efc30418fe5b15f8eaee5f9021154af5e8e330ee0c2983fb1c0d811c7a2bf6f744ba0d54b9108a13630dac02bab1af867a87a5d53402da985c12b9dc7c25b8eb96024a864b3988bd2f87b917d19737f8f2a2ef98a492d7085fcb34a90e9e09657061d901522b85e4c391ed0c8f083c7774841bf96ef6b9fbd4aa248e42c3b4cc206d5d55040124989029dfa364c8432141044e462f9f74329e06031bc263f792c4d88203bb0841ddbe2c6815fe09d01c2ddc6de133771c4a536bb97abc1efe29c7b970dbeb30e7e6d6a9d2a88b8419afa7c9d33be8092e32fbe897cb11a2308360a465724d24b35cb3e7cc167193fd0383b9144214092eb5964e8ab220d5c4385d6a15620befc840c3f1b6035aba29d32d11e33a14a7dff61bb931429c3931f29a994b444999a4e25a0114ae58f5e406f947acf1e494796846c1c816dda64d6729874de08856120e43a2db6120af832ead6bc970323e358fa5358b5cd50e8f194f9e7af149fa7be620ed466a74607c66621292f0adfe88aa038abad0086538bc9038ac66c41fd1fa31be8901988b219a5bbe18615a36fd6940097221161d7a7175c87f99b85e48026aa096c8454404da8972d8bacc0ca388c5d64e5ebfc9d16b448c68be0e1d2ba9ba2e3080a23f41623edfe3af551659af70b9524380efdce306a16f46e3c409195f195e23ed018fada946f30f6e871461c0b732d16f356898f072022ead6b864ec4b721944d809c6ad3728e469e0f375b4ebe0d1ac2e1f8b82f02de4f023fb37ca2466ebb0a0c5c7da2603bb893e566dfd6dfdc1d79dc6d2f4e07e197703dc5501e476e68ce57bf2a323faf2f08a6f86933d638ade6fd8b8b7e6e78b81f78169ed0ce8a3578a6676e518006674c169481a8b30be9c541519ae1972961e2bd8b729810dcafab18b580cccde253f6bf5386fc86c44e95071b47f632f19fda19f2e805858b8973bb426539dabc414195394169b693549c9c2074ac903f0245e0da0ccbe553bf07821208bd1f823940bb08e175d42a68ab2e4faa8588291332694c31cd210ee6e3a96ddd2c4d5ab7384009e6ad5a6c93ac577593037626fa88e7cf92672d52d324c5d6c96088c37a6f5fb5bf00b9543cbcced90e4f84904da2de0d46f60ed4415fcd54b8fdcd0435a8d16d5d4010808fafaf9cccbb657014bdfd651e5adc7c5cd75d514c1ef36529c6844ae9b31ccf9a7c4b6efb3670e11f2b53307f0923963de024dd8fb8180deead008069c27b10d299a84d9ed1be6d545e560681688a0bfa8a030a1995f838ad76724519024bb1c4a5f9af344f037cc6f48859c9c2f44d5925e65f0d48aadede6812dd5f3b77e6f90d6a38c5fd0cf474da55c7b768a6b0673454eb32731f17f4f8140ca2846a640c6d2855876d4fcf9b4df27197b167e251837b7e175aeb37d945980bcbcfbb3ab07b350ee533fa234d0c4bb22ba140fd9458b1fb63029c5ea1f7a37416250e553d6b7eac8f53d4c79154134c91088c5c19ea7276df25e519326bcbcff9c10e93a2a7ae5d11b3d7a2bfed0ab03cbd130a10391f87b1e8562519ef4f5a46be5e5f2ec1af93ecd8ec786104230bf4db371927ab3b0323c7cc853adbdd7bdc025f08887230ad5144f855e8afa121cf0a919b6ed61a1ca4d66ee6ad03a9374ae0b46a0d7932b700191a815394efcebea5e5ab7b783845ed7a72fd88c9d95d35b9fecb0080d36a5f92c8102a6182c0380aa1d61f3d956818174caf9f764c8d22b1e5039bf27844b9d4ae4d8a808e08a984a384dd3c99ab9a21b4bb9ca29dbd2fb3aefaf0ed3e4117221cb8d9a42c72da1640e6a6667c0195d92b54d14b802c961e4f31e7b3138245b85f9872d36624cc29f254d617616ffb5dc348850184f162305622343c7b1061ca69db8baaba312471aa376df5d78327dc650704987df93577c0fe832e32dd2a6cd5b60208433173a7d41bfc98947a727c0c726d2d70278b9899ca3be51271d4a9eea132d2b7be91693bf8d17347ca2a34ce481958b9c06589e7329b3192160634a420ae91a14d62b01c01622994da47ac829b4159762d5a45c456d9f5984fe08070a2136323d20831b3f76c492176975158148989f1064b25d2e6c660a7f8d6fc1c8d2cf8986483a2963671cf3b628752e265acbd42669eecbb6217dc5acc344920aeae4ebcaf63252835efca55c6054d883699aab499087d42c14f46c96f0f94825e0519e47aa38d7816db244346fd4cff28e9ddf5fcdd81cb525e7457deb5f4de4af15bf410d113111ac6b87b493ea43948c2422d4417143680a5f56073cec1b177d12aef3381a84079785f35c8b02da768ef2673233a18baf719a00f6b6049e897a377604f01b510a3d668df8e7ee6952464396a451223ca0429eaf7efa3d25e267ca04e83dcf350563cac94046e59a8e3679fab9f16b02813ae0d4e98d5f65743389611621f6051afdec4f697f6fae3367c7fdce313fa19100c6d596c33937d06ad2a875b2a60d3bcc90433ee06e44162ac5ac41c02f6f96e2ca1e12958893104793125b10c0d891577ff0c18c6c4a21573dc159cb788c67d8862f73604cb5d50e75421a14a4147d62f6e2f0f92bf7051aa4721a58e208e31c49037979472d1557514b7483534a21550498bcc95d88d3f813d5127d82d786263e77939904e550d76f72e8b74aab3607942d9eed3e7317b1e98e5ab5cc178e1f1d01757f49bc3c20cb1ebc546d66004f303a981333ab505889b7320a029cc63fc3a337750a876c65bac26e82976778493a943deec4bc73c1ebec2c284e57a6ac0cddfa6c3c5ea55ac1c7dfcce9b7a5780e535be8331b323dd7286d8ee090ba4c6c9cde7d2996a38a0698cfe9813f3cab6610d4f974c964e41d85233a6c8b8c05b673fe67eb04fc31f19fb36f503d51f3679933c137fa0d0290590c18b32620155b1023c388808b9de48df91d1dd87780b6c70426da691d7834550a2016158e3256354f58a082b0afa78671a0423808744059d32990555fa91b6b6cb80be5d9a7b599c764450ac90a4608ab145f80308809adf3dbec8c2d6146286d9c7dcbaf1b07da8e11384f603eba4859326d156ff6ece92da8c6e406bd3456bfb315eeb386146708298679951248c8caa31dc0370559407c32e899673b52922a7dce31d52d7d35f0291768461d326722c9074c9b64618b4f26f1c57f17bc0a5607e0294850ce26dad78e7820a866f2973e5852f79bf3cc5d1449a39beba67408b5a42c50c91d054e8ac9df40b01e2d20e212a97d4259f0a88808cd0defa879ef11c3e4ec28e9acdf3667fdb86658a08cd11da9e81610f86ec02125e81c733a6b3491dbc0eae111b6050e594da4dc28310bc0875902ec4e1b692ad73e984bbe83a601910115b6cb3a4ac1dcd080d3951b941d55914e9293b33aa02730b2c232694da072e341105a699575cf523ab14044927cc8c714c0e0c26da6352e627c76670cb35b876cdb04c24ab7584d07cf6041830cd0578f380df3d9e0e0586d2fa8a1c029703d6429317e6cf0dd08ebba8cf243c9646fb3b6969c97a233816686b72088732ab2044209b1550a309dce7722289f3bf8aef8a248de09c7fbacc20e7fb775ec535b86bc58565426e5df5ecefd09d29564aa41a5f707f28be0d1531fa17c41e87dbe76a74b2ce9627eb190a5a8a62f6bc2c3aedb778378f18b5593477a45942b6da568eb2615c47f417cd0a954b3bcd884f680e96754dd20e0b0577dbdf039682875c0c6ebe801c5821a776197d26f9f5337b4a9c217155afe6708ac80d55f9c155915b68ab8730983025824f3d712fb8d787780d6b4f7219c21b77e2e5e32579e63026066d29e68d3baf8e919e54e1800edbcd8e104662f69437f217d768c58e7d09e35a09c23748251392646e1b56183cedf2b3a44ed73d74c160e6f473f2f002757b0d4a79527641cf89fac7b4202e9c9b4ef1f1e0cfc59b3ce9d87cb3fddb6c8be1ee52c5b2166d063fa64b8913abe39e4e27288cece83d183dd9fc8a1c6150dc0045f2eef76a206b60c154580e39f4c5ae5bed93c282a60795905a2aab3c9fad55e4960a30db96ab82d4d91c3f93a36168d8b5c703c2abfc37c69a455de463d2c31596cdbd768bab16d060810665c9df288da236319d763910b5cbc549f4a88e04ba39041d55be33d1490bec296e9bd74f3d27f90f8c8a7e595693367a8ab7cd19bafa03a9e0b1b1072df9014ff2d91874516160e8035439da747e4e3a1de180509e3660d077dba87dfc185a2a0d8d4b01d84ffc279123ee7fd619cd553baeb6348341f391c6431515367cbfba8a4f9abfe1d345a283880dd26cc29bfb4e76e2fa68c3eca4518f1d4594a1e6d2edd7c8245ca90735dfac80dbacf99f58d063a23f884913f47516a157106a122cc9de5d63460ecf0f6565380e9610da6117378590ac4ae726d276a69beaf2fde81b8b0c2326492769a6fa57af0a62ab5105bdbe3a765b8dfdde93f5f89c762a933463b412497cb0c4659c673050e12bbea44ddc5e50432b690c37801dba76c973f096484723726ea2c1d3e1730f2ce7a06631a4b0f7083a5261888fc691d3843f29f631781f6d4e475490e8111fa08a3c28963a52ced91484441c16a5a5c1e1abd0a7254b621fc7c7c847e975947de3318d52667add960d7c1a659e347eddcf6d36a3c27edc22a853d734311198959d471b20d6ac00148c48828c90ea6cd7142b83a520e522fb7f72c89722581cc1de63af0b058ff6dcb86ee09f0237fffd486cdbd1e4ee818f93c1f8c99b44632beb11f998a9d16e79930cba43d691729bee0379dbaa8058d4dbcf45eb7500e267dd3e88bc696bbfb1e2feb6c60a022a1d7826ed24ea77de0038578e82809238578e88b5a93720dca22235a9134919e0ea949a0f3db03283b7b0bd468f07b143f56f1e0073ea7fdba5d85088ba210db497ab80fd7c68dbe409c4c1853467d0acbb5cc21a442d49cfd634d1118a251884becd7c27f63b002b979b1939cd9ca0937248ca431020190e2fe7b3d10090ec1a88b3117c7a1b0ea28bb3a391fd641c980ca5d0fe5c4c90ad02a7915a9758d28d42538e3fccbe117adc740e3acad8caeba6a4a6d3414a39850c749b4d2703bc6b244b5d830c4ac647e4b6ad74d7a785acc28ae0d5d85e1e90d589e64755ba6b9c6ede53ab4a89b84b358cb82a794bc2f8faed871e0a7685e059ecf1618de400afa4526b43ed5de41d767c6b827cca2792d3112f5b5481cf86527919ff69b064935feede3e023882b2361c2548e8a9c66ba34e0975bbdf2a5285366762239fc725335b4cbc2412d1018e336c0a484834e7598d1eb147cd7c46257178b34012aa80f1a9c306c6d63d4ab613357f47090fd42844e596a824340b3680489457bf366085cae375733d30b61e4c64f4ec6d833d1050e120badd0259df9f1154de9865955b733738c8996aaa1cbe091966e68cbf13be8d9ca71ce17606a9738bffebd651c38ba6b23410425d1bb2b8eb91db957a96409c33729636345d9281c1b320651f8427e4a8a97282cdc9d57a2d5ad34e1e579622e9e48504aced3c1bb9c804e5d513cceebf69c67b6e6efb63c9ab0bde412b46a6e884a53f98cc2d817215302c7f5e804bbb9d7434f551f287c419635faec5497de2bb7fd319265ea31cf8bcac5f4b9fc52d5c4c60dbac2cc244045cad802b64d0310881ae4b811c7d70e70a167a31275e12185fb901f18dd254b79863a352ed85dc4a1dada9c7143b189710bf845c32f5685f872cc34921775abfb74f17a32f85fa7ad99a78e0d9f502dc5b479043d531d84060c454ee33697f3fb87785225091e6460b48997a89bde974e202e57caf7a6e4d84b555de206508655deaecb02956bc52a50b9dbd102b73a2818ce8d5b24fe28e77c10969539505d5c5a9571139882a2d2b9697496914335120c26fc917c3ccbdb1d4fa08a19f9755be20e44409fd7fa6a699198aae6314c2be68c8d17bfcd156043347c335804541a288e0ed573177f9fe336755b2394de9bd9a6046ad8fffc825de8b6507774001fa222dc46ca404ee0f9ee05b032bd900183d587158c4aa81c80c5be47099911e36dd6e1ff21e6cb36c258895fd616744426461f9c441e03bc8920a1df2034eff5de2a8f6b554c61a437f4cdb552a04d6f62b2672f23dfec82c71e57c5c2ac5d60812d353b92df92b41877bc289423a6485b3cfdad755210248ab7324ecffae6f0a30feb9b26d0a4f1749dbe10464de05c20fe8e58861585010b50c6ef69d84438265a80005aa960ea610d425c433f4fe86dafa281860e27b5921346eef35596eed0a3372324e98a3620e684096b49b32cfddddd03423b14ec50847c12480153070b4923fedebe2e9e74e29af29fab189b643ddd67b3af9915286c13e69bd5c8da852425db90ef02af3eff628d3513b8b90203de9c28b7e4a2f191b4bfafc65efa0db26fe78dc60ed5a95403f28f231fb05006b75ceac5f1cdde6d47c73058480bb8dd6ea5d0527854994cb35d99842b634249b01e9360aad971fb54123f267a2cb78c90bc9394f516543d0fe79d5bcb447dee6d13ceee72470dff088ec66e67981b40b50bd90f499452480d9be1220c53d80eae6d5b1c362f4bb8e3efcfecedb5fd621671e7c32dadc987abc3a51eeeff0b86c8097eedc06210d4177a959c6aabaf0ade1332c7abc33e267d1f9cdf0af150d87347b4804e15fee3bde26bb4760f58f5efd6733b47b7e21b781886eda52f2d20914c871bc9aed6842218a47ecaad0932cdc6f4a71a44166db01f873b5db97ec511448ae13d7a18bea9c14ba4a004400d9b9f4bcd59110ed1b8ce6c0ecd195dab4ec9fa98da84adc0c37dcd0ed9cf2f82625d90449a78d34d09bc7346f579e981ba7d21c29aa748f7815a5aa8c7ff6a16fd90ea4169237690982119dffdc63bc501fa4095650e8f6590e6c34fdded79eabf797beaa983ad183515369235cae4312ca01e3920db2a510c17c298fee689afb94f7f54fd79f05a8a46f8ff3364549f1a21af4224c9bad5faee050c4fbcccb16b4c832243f7a493e8a71c5c26e910bfe08dd322572a85ea26b5efa2d630fcabc8b54bbe817a72fc6981e0ba285f55524ba2113cb19a009b68905cfbcd6757fb75f569f14f297cb6ead4c7402c301262282a644081a97b35e0305febc42eb70e132c9c7e2c6e9fe1db2865f796e8c4fab8062c16a3e8ac69a2749359f68c465a1a42dd3de2de2af20e473c0d85f6df729b69cda455f6784f4eeda12e1f8008b436405e5877b2d2b2cc2f71e1822049cd117660f86032783d892b040bc52111dee68b8fd05950adb710b8dacf4b0f3a732622a22d18eb841f0df15a70365c4242142dd0670cf257db043cd878cfb6898d3a49bc27fe859db052d47840f8e4f406bd7ecc599a93533928910dbcd45f871475cf839fc643b470fc8b1c89805e226b100ac2fa986710e1720266d7148d2a55bdc0e70f8a2f10c19320f05a9ece04d13631599749bd954b9813ab11960385a9e55e04090c57b4a4a0e4318aed26a947aeee94e360a72ed4eecee06e7b04b24722d5c4808e647bc6e8e1dbeb3d5c5b7a4d842c4b7c2e0ec7ebe99137fb0c238238fd34aee8b21c45a280055da9204c670a5df10901c8fb228b38ec71427dabc1e54c8b2601ca0d9e4fb6198b08385011c97e4f74d6f9811b17237cf0d2db135a188c99ad81736fbcfffccfefe6771f2a60e98ee426292b92543abb636b1a2a8244106f2ad7721fcd19ca66171c6ed70322bf162a705ce8eb7a95a2d0494881ce5907cc328df0a155cfc453c0057f405c10240ed393e898e8e507e2e443f663fb4508a9679e70984d6dc598c4f1d603b1e5e8605d70a05849059e6dd6caeedcd5dbb051008a81fac4513f74891331e5bb94150bd0dc55a87e6d5f33f7740e051604109564b8b49c4b9c518b726aa45f460c9aa33efc2335ac8573edeb3ddceab85a4a604684ea15248d4ac273359b83f45032c7ebfc7d0d568557d261ac2ff01a42f0f3467583837a6011a62634323b59b107957daf7f68fe3fe947fa2ce34e591dd3491890c1ee75aebb9ba3d90c1674814bf8a5af169e4bf4e00f1e732a78c9b0cbe05bd01b8a704d76777bee7c267219ecc7b5affe90b02bc7e09dac7f4d1975c9a8e7f6e66351112cd80bf16e44ba13011d2a0f5d011badb03789366574cc8f0e60d29ad93cc40f58360eaaf619adb6df42c4d4e0e6639b429647c9f0c4672a5ddcf7c7204dbb1b0d568e08ca0dee4b5acf3ad746a0a13f6f1600d64216c34e69a920616891de81e515d884b80f49f9f44aca97859e79b42d3535a1f2007e83cb70d247be91eb3aab89ca9b357b0ee84f90c9fe3717480185bfb7da6c27256c1fef6607b6346257df31eb705155d27bd341647421e26667dc98482ecaa88ec4c50c84451a0e4952df50c7c540a09bb490ed13b0fd6686bc1e92833c1806c67007f1fba87f10c49a20604eb996cf479a8543bb003111baf87b8c4316620f360d492dc26f11c4101cc274653dc155cb045f9f9bb90f17b9bdc54aa84ede78f9837e4816ba654c213634e5c55b8e5a0538baa4a51584f98b4b14186a70563ae4965a812a6d290fe2d6b02b933d012e6e06d53a259777a86a5c8d40c496c8b6851db7a7be7505d74193d4e86cfde7b5b4b147634eacbd96f0ecf8373e702119357b6dbe10e43a51887a52d75007cf1ac203c162f802f77465d6ff9257339231577b7e4388390b6a2bcd42aa2a7b27d1462df3dffd00f92cb372ee8592cde9fc4db6ab044308a4709dd38d85bf319b090fb53011ddea6dd4d703322f8014f7dfd7c9e42de6a98490dc36919be84b09625ff99593a81607a21ff99d80ac5de1086828d5e10a45d500f5de27d91c041e03dd348c7adeb04aa11efa968eebae1012c79cea5ea6de996c4f8b2038dd579f4afc71873c4fd9dc4302854a26e5557b5e2cbc0047f9249f269fdfae83388af2e5909f79b1b2df13b2f104f998009dd206140519f8267f284c80fb535634f289f81a81d49e7c2713afdbbc5ecee769c2e26919a5142cee8669879c467d6fee0089960d84af82489f0878742b61a9ecf9de3201609bf453f482a6171d10d7516f0e4c93aa75d629435b71a352f47e9f08e2d6c29838e9e23ffcae87cd3b70886581210558242de111134bb7584a2ab3f9d168f18af167059eb2a2af2a461f300c7518b33c56159d0d978a51a1a096389fda3df65dfaf59488c862d2be5762e1a34bbd652ef43a7355b50fa7e47f5b306c6c6816d98fe1b0f0c6f2e12f981850268419ed92ae5ef29308c7377ebb7d1c9ccc2cac28edd3cebed585c3fdffaad14f085b43e78ec5b1274e910dd72e11720a054e4c117d8c4954d120703aab5f42ec2c8fa5ae455e170f61d2e59e288d21721822ba9a6d0684f015e36a60cdf80ec50d28b6dde4d572dcc6263cdf015e40d50374952f8f8adcb41e8760b9de7213825123db2978483f9d22c1106894c9e850c4759a8dd4d592cf8e3d2b964b1ae1a2caf9571701cc2eac65e1130bea9d9dabec0c4498f4300c721491b3aaf95f3d54cd2a2342750c8beb5c35c289d96e61ecdf84d482237a4c233eb4c9bdc5005b92afd41fe9d2bbf6fafbf3b38cce7250f592fbc52c90adfedd5fc4a2ad5d734c3858a0a06d553a0de4f8586b8655321dd980652a9bfb8f1586fa61d3332d3948e1b5738ec7a2a73542aeb36efd8ce806025c2a29fc21db88138ab40109526f1514ff1ab0d35d9f323265f4bb09d59769acaa6288da21b3f188e0c62f4c7307ab466a6daa1518cf375a9b037de6743700142c23d9f1f11a01a78ed735104ce10a45f78ded08cee6d4e0cfe7d5d8af32e258b43c82de6ec22cb43aaf3ec33ba4b19752d4f8e5c04245623e415e17b55149b63f5db00889d8a451e158ba3e867290d6816f33ea5f10d54bbfdce0a6cef939db5c694646f85b0752aa6428a2d05d2ed8395e3d3d476692809a7b044f0d4fc417fa741c5f837c609934722c0bdf518599a7509ca75b4ab4539c6cafe484a9e9610bcaee2d9c17fb872aa0c23d26b1fce5c043a0d174a5c90c33e3e50fcbc34438f15fe7c3b95b637922d2cd4448680ba54a3407d3827765301f7a00b8b15280a3a4fe5327a6579c31b81c737b192c0d0eed19486bbdf532d4adc63d10e6e79683d98583213522c0c08c1528b88f51dc9529eaa5fc2e1959a28385a5d6a48d25e891d8b033f378695c0eb15523f02267cdd728b3fd08bb42fa3d8f07df9cb5aefceca2cdd1a106ec25185b75891e00761a78160dddbe03e88d7597fe0613a6e3486c341343f789d68f7f2e372aa7688e9bae12136183f6f7a92bdeb67e881bcc38582ae26fac4f8a9329fd751e93331d5fec6c7ac725098341daaf34b37480f8e9cec1f59c9095d9fd1354461578aaccf2843249973c4c9ddc9bafb33ce3e0c4d098bd079ea8861a7f15a019aebe7c62b0d4e242679592eafc949b84f04d7e16b89b3da40c83d607c218d2c374e74023a7f44bea6810e14126926710e5929b84f8cac7fd6b59fe2c936915d7f633cab9d400fe0cb3d2a1b57a5b34e332395453172e9e05708d5e5b5bcc39c1321df7f071236380fde011dd26270500aa519b2731c398a384696c81d06a3022a6293b5f7587d5ef3112ecd748bb950237f4937be3b3eb206aff085485e5dba38446925ef4ba835a196b0cc0126f1aabd4b4c07823a12ce845452d334582f6bfcb6a1ba5ba612b9175990eef9606d6f47ae4661e97868a89b4c845f1bf950d4f98fbb51b1ce3305a5f893dffb315c4cf95900a0c2567a19913708405c0042e8dff254dfa600fd76c4a242dbdfd08cc06eee27fc3a2f10048996755b18b67ff419c1fdc04abe3c3341c06922e83da7997058857f7e79cc50b16018f309056fb7118caf53fa5061bffd8bfb35e9dc2ee93e73f235c1ed48742350619c3e99fe321c4f96731288234f801a076e7ad65a7944519f70dd3d4314b5a5c41c1113889da04f23db4c87915e0124e066ff9ece35104f7217cd2ae131abd9d335ee583b9abd66b0b56719e0bfc242c98ce6cb8ec78bbea43f6a8667b20ec84037fc787dfadc9c0d986f8d9c4d4339d0ed4bf86fe7e543297569c08a71e928705bee168d2412a016dad6c2b5345a51df60f9288080b07b844ffd9cd41998a9c7c7ee05d5e44d0807880acab4b39cfaa44157fac4a0e6ed29938a01fc586b3cb3a32de53117aaf55b650441a8b4bc2eb179fcc87e1f50105c177cacd33b9751a96315a4869ea779257f4cc9a4865b53ae60249db0242ac9d83e408940675e22347357426d14a74b68d1a18c788e30f35c0706a322bda97f2069b571e51f28e3c3c59588d3dd24a8de4c11af3a939e9a0e60248eb9b323fd064f08e88cec5647d2b14dbf99473c914cf2952982388d60b3dec2124b78d2119210d326fae7e2e4988ee40ea7f138925e3e3ae884849fa290f00b62965ae31db3c2bf13d05daf792a7f51302da1e2719613bee873331678720367c6ef152b7b34243a406848074f16ec6a3eb40a7588a6c8e1f4de399b899eb807402fcda1fff38b1580eed0f5fc0b47da9d526e8a4031939f4801d10a3ae242a67e66c24116065849233e116d74c9d8033354908aae13a73cf137c6ec0b40fe464836345c17628dd7f586bdb45a4d6c2c86e67286234e548e46628595d2e87ea12ede97cf2c652e54d99da85b20c150309211c38717f31e3517a0ed4f294d9055bd3459e755e2bd1bbc1cc462fe1198a287a27165ba3c6c10a59050f91b319454f80e72f39cde84183979a6102333f9c403b698f9d3fc01c2449bc8a46d3a469210553b227898ae1036e5ce814b4cc73c8a0d6b412a79d769b31f7a1fc869570f75c4212e5dbb6be6b4dee99c5b4b656376f925d079fcb70605cb936096d0beb93639e115ee4810b271ca59cd55edd4737e761eaa7ed90a1118621542011abbd9e36ff4a9964eee76ce62b6b17f7b1dff4eec31a7bbcb40c497ec175a81dce25e7008932facbd713030ce1f75030ddf17db37a56af37c0ff28ca8c1503f526384ee4a2e04fb1081efa6fa34d1586de26c6d6f43a99b08e0737523f9d47a0bbe20070cb23cf04eff3294f8c88df955c18ea2cc91b263a9fc7026c568a586b4c1ae78e6482ee154d1d10c95170db63f19dae95cf08871d959dc56f2837cfa66a9c8b1d61f012480822d831165960c4ff9b9681c566472bc60f5fa520199de14d2bdedb624cca0a9c8d24ea21c26832b9353a48729affc205c5fe039b9b1ef52f305038bd97bd4b13cd7b3a247be40148927f1ed4c194408965c0927b7a2966d17a4a178459b16c01ebfc4fd4ae043cf7754bba6a131c080c9a2151799a1870da1b79da09a2583f4b3147255ee66c6e23ff9454b20ea6726b97f6614c139a376a49cb8fee32ed2441c0b4154da16ad885eeb4e2631b5da6c40d44ad475baeac7f2ace1e7901f2c465957f8fd929f2df134c6ec3b0b7e953e5d0ca45a1a2a43480033b8811c3bee2f2b29f62ba5f36f4c293299c9bedf24fde4b11b4ea9e83001976ddf4b760a07f4097bebe0a562f666018eecc31bf67823dce1c02d7ac28096283a0d6342a8f4a237a3e154bc52d98c381082ebe1fc17aa6169ebe3af05d0aa35b2cfb4efbc6a88c006471847dd72bc4c3057498b1c79f5da2db6386586ea2451bcd500983385aa7233440fb126f352068b06e1b50b477579e7e81743a56f2398a65494fbfe15409f4bdb829b69e255c26102675c3ddb8c3d1cf0805ce6f86251602252c366eb4d3397767b4a0a2279118b4a1e9b34336dd679666ae3ad9f98ce959b3ee4180904ee9a40c511b808025b18f71c55d43457b8340358e3e8aeaf2a28093633020d404780d89b28eb12bb999098cd4091f2cc2dca0bbc39e5bb07be190c7bb2889264dba7bd013601dca77ed76debcb6039a9be329c2257d709fa004095c8666ba67aafc0e63f8e0f0efea3718ce2a1c7255f20f8e4bbb7459f480e4b1c9e7e910f99625da242c64180a8a3c153519882b1b836ba19244e1170eb94c5b3145507bbef996412b10a206c648b716e1fe9c085d9f7e660f2e21b1d1fb58ecdf8721cc9bb318067f9468a91efaeed88462584c340ccfbd9608ff46fe2ce7f6b39030bb6ab2f1ed2dd3fb61794d48131a17e09b664753e3f60bfe441597d0125773e75ebcde6f526b98c0e0ec3d59a406d51da3d1222ddb3940f674c98bece6fc8d38531f23f876e598b65307b66eb3fc1d23f21eaf406b6467dedc07dfd10ff36d0849b4262dbb95a172c39251b2c00ba2d109e0e603eb0addaa1a21dcbec670d05917ebb2ac95195d35d0008fffbbc0047fdf8cec334e9df575d3ce6cda5ead503da56e489d90255e0e872d8b0db0635adec800fbcef58138c39c353144012007337fc63f38dfe4e82723ed0b09287ea2ba6bedbe05ddd4257429aa3304fd764c3b47282fe00bdcadf3f37b730193c343da06c80b9015536be084d3e341ce2b225e037c9a0bea2ddb76ef97d57cec9d7f2601802571fcf5b4143aa35183cab80c6b7ce62fa25c557e61009e72ce9fa5898c6578572fbbeb6591cdf5de9bbbd48ce89f1d0389d5ae22d465b6759d17258453577aeaafb9c6750bc155a29f144b6cb68d014c39ec1e4099d201726271e95ef2e811eb047bb971c1688fa4e8d6eae1350c50dd60c3e296c1a2287e4aa14e3de4c5de840284a9638806f3d0206871856b14f8bd48747bf1ebb7cd5283b09c94208b37a71c4cd38144230744ff9d15054e5484f795c05c7d25774bcc89fee821d095070db7592ddf18a84aded3b59169696daf60c997a2a8ad2847cf72bbdbd0232f73882f8ccabe44aa102d2fc61efda093fd21e7b57180796032d3c35e0d684fa1b1e0bf83fe84eab8d3f865ca56b54128c8328f77cc936bcb65cef8ae279fa62085d34877578e0c5837b374dd106fbfa35f955c40bb5a5f87ac93d3c1ede77b8ed85368e9c14ada827a898b2b900ccb1c7876884e3d3f5186c5f31ddb8d2e9393e277034bff8a0f91dccdb00047d80aa1feacccf1e1749e5940c5c99f85eb4ac1c0256abbfb4264d07a77bb1f7f3d7ec6a6883b937fdee1f027cbaeb4220d814e06b66373768c580f988796132ff93b7e9f2f318133d286e78773f058d0a8d5b46fab4ce94720adc581fde2927fe0ce443577c50a7aedf8fe75e21d98eeed93567833bf8c878b5b088131128a7456b593c21c7f0b8c80dd0012cd65dbbcf6d3f132e097081f1cb04c9385e1444cdd836e2f019702fc856a3ed1ad0188af8637f830320670f0b331342fead9091f1edc33c5128bd259d9a8ba89b95afd984e6411f7a2ff19440657edf17c8fd071a119901de9faccd44b07bc9197b5e8d72bf587a583cbcfc096054f0f78f0f43686ff9e7e95457fded4ae03359cf0db5a98844e7a5b563096f92f0c96c463209a51cde59c5ad4e3180628b7a2912e50362801433629dea3d3a9e41438301fecdb9150bed31b03751d5861f604f33697378c396867988f925953a2994b93cad955f42f8f07048a81f58d47f3ed931cdccd80ae8ad54d063ea0a0c5d3d19edfc72d777276cb652d90b307f2d1021edf9212542e54b1dd7c3d2efd90f81831d8801b68850b3471536298481492ed68d2940a140f8a2b4796cf91d151eef277e2eb0302c64212eba6fa5c0b38a1570f309a2f79e4372d09dff4ca193339f9686c635a7cac4929764d1fbd1a1d09b29416b72a7d3bd0e82567842730562cdc7e6ea759d79eed85b0ef9591761af20ca076700e276985e25fb12ec662f0db86c6e801504857202d6b50facb149a6f445449ce14f62480ae455eafac6bd218873b10daaf77fedf387a71751418bd7a9df80501829ebf41b4edbac835a7a602b1cb334798d0bc7f30eff00acd3502fbf153a91bd66e37a372ed3e58ba073d2a06dd1fb539cffa98ba07cfeee901e1ec28e121069922a5152793c5cf9fc180804a0e726a8a308167989cc9654b3805762c194a693acf66c3c0e34e7dbad11850f1bb6fe1d408364c4cb10f4f3760b686adabb460bf486844bd2e67eb69a10eeed5599f1bfe41e11a59110451a1e914d6dd4e0832ccada086a36bf620eecec50993f63be23304cf04a0cbe725a35afd39abc971d049b65e0c4fb18f285d382256260eccfe056b839b8fdd70b2237f7b060b32932aecfa2600452425b2009bcff687be3814dfee877b012bafcd10b851a9e44fc1fb135408e9b1f9f3a910bd0c1dd88c9496b45fad4dfdd97bc51e86265d863cbc328b8ed8c18e511264f894d4c668d178b5d86811e6bb726677296265f5e494fa9a15fe058628c06f87eaf3bf88e0c2036eac63e0c91ef34f50b0595bbf4072f7224f83664695867ae1bb678015bab4035e2e109b949ecc6d66a341839dc7a25d8fc84bd3c739b90a1be9e3ff519571d624952e46bafff3ef676debc25ecaf377055694cacbfe9acfa7703c946da7a0383ea2eea88cef330c855f7dd8a107b31e45619a4a9c5b15cdadfdd01a5891c289b70372b6837a44517e56066bfaa205928739260e66cd3fa8e6925b1b1fbce097d3e0aa33eab0b7c5ea4c07e422449081da0cf1771b30515bc63cdbe82635e3025713ffc0f56d6d1900748c3244887d7c68d9b94da5cea781599621673046ff43f8ecbb14e53ea300921b16e5b03deec222193f52b3b325dd9ad631c6e933cb147d83cbb355ced395242260f66e87059cb03568922dd0c4d4b20ddd90f3594e823af705800bc4b4ca4b46ed4544e9f3ec5dd01fcf74e28426042237b53c373fb7ab2ba08d7784b2ee8dd6548c3a4f1234ae6b8e3d630b52e61ab4f8b031c349f124caea74ad91ba16e1ce341bda6abde7b1ddddcbad2762666762cca329da72292876967ee170366736cda2a40e9e3c2b3cb523d29a7c4bdab1b8e130d5b493ec3d7dea6a920dbbeb0e51a5c55a6605b7125c8d0ce45db87ed89582803e338efff9c748e30ba310384fcfe1af1f7268c5fc5f7d3cc280d6c903cfeed9d66110a02af41a2661128815f02498b1d48b0d8a9eea79a54ddea152b552b4e566889b5003f6069e273e49ae9437ae5d59ec71ec0cb865a135693202bc8c646a88256a0cf712a8b1d3bd57345b148cd4e53171af122dcda5d0af1529621a0edb20baad2accbde7b45ed1f02433195802c0af09bd866e6fa8fdf9e2ad2690dac35c5dda13f24f37e2b91a3b890bb53814b40e32a963771978f5264235dc7f63fa82be5645ec084dfd211f57c5693ddd32ef309ce0526e2d226a56f498962c4b7bbc054e8170d8f8855dcff4ac4245d64811a2e580dd662575bb33a2d72973736a41bf55830ad71148335787eec433525e068093e8cfb2bafc5b9691c3ce2397dec4b1402682a8103b420be13475ad71ba9f8a9aed8d94f7f7f5061dcf987eb2d3c592253378fc14d0a3aa0d10ca2cbc59fc1345ede6b5e8b9aec74194974712a33a46c853cdb52d61c6343c784ac5e6f77be5263de5ee219e9bc670346edf8677756635c386ab22913393c9fc2ee7916b130897a55e2b9d322a1185212556c16b92e45ca748e0eb0b0422e27503822524a7c9d23db635a49ddca2b07864f2ab00c0cc0c97e212e2d35db65102fb97fbfbf135a6cd391078f7fb81c85cf2b7f7c9e36b0d39161ce7f4b5ec9a63392126d2f3b1085a10500c2cc860c8b24ab5c14b996467aa3c1a45cb8f48e3d9935ec51df6973fbbeae3ff0bd2bd1f2d42386d183c2ae4d966796a6773e4da07b73b34881c627ecac67a7bf3ed229ed927582558d1c75fbe91588ab00b2c160de0a456df45981f73dc98e95be68899d8d13c7acf6017f02802fcb034e168560d1404c5ff9eec40adcd935180b9c33ffce7eadbf6e571d741dfd3c0e92403a109ff6ec9b7f70535c6df2c1e60537fb3fafe6c99ca6c8b0acd6c2b6756b410630d3b060b3a58d0937a9b042b6daace8bc39a0f87d122c38209d96553ca6c745d74c6ea889b7dfc20508033b81c9aa083a0c93874038905878fbd84463427651a32acda86d16cd58f92e2bdd0d97a46866ebd28cf428accd2463049144cff229dbf3368a6867c3c2b90efd2dd5199fa10f547bbbe1e50e0951c1bfd086d5947976d04c2fe4977fe644319cfea2112622176327f4e129714d5dbe33cf8bcb95237a7e510e1668fb7f5c51023ae3db2b8ba49ddf9f0eca1efec402cda3c2d054fd682187693578281022468b3a6a604adfcb66b6a718344fd0d5a1ae03173449ab78a1cc829980e0f6dc5d91f8a07d1ea32c31b1ad785205e776638523f788c314347c11957bbbd80b374ef397e5d3a31a105daf920493b9bb3beb701ac738bf906b4fd03ccdbe4b09f923e5551f7241f43381cb5a27602af570624c14db3774dbf9747fd800249c192e67e9e63aac9cac9e48057fdf155a577fc35bf9134317099b64b85a8a5744ba9b440872ef8e6d7abf35acbd04861c2d59b53496632119b0007a89312cfb97cff6d4f57b2fe35793677261abe12b459edeb996f74c30650a0792119ef9700adf973c00b3537aaafe3c9b448707c100b30a24d3f012d414f36cc291b6af2ff94cdb0f76cb6ea6b129f466b702ccad0fd6d8b99835ed8e6cb3b481426c2bb11e57e117fe590091c4229924c34ef030c1144dacab32ef4fa807afda534eafe958be8892b6e843f0deeba39d2f711851a4aa693feea33fc437744459e105712a2160bc5eb054c35c35b424fe6c8760c4bc8f925ff452b7913b4e416749ee48386d36e3e6e9af29d9feafe3ccf9cf42194b2d24774e9da182a59e14268bc9eb81cc2dc0cfc232d5362afd0da1862d12b0264a62c0a9ccce61648967759e0359ca7f0ddc99e25682de13876c551f23cf4336f5d88716008f9526af3f14a99e1514872ca14569d290c9d9f36f655040820b1255fa0e97b3f80e17417959aac383f8ff197638a47624a058f704e1439c13fdab94e900836fa3911a13328a2347507b0cb4ff63c686a122e23b8ba0ee8cc21966aa22db1b92d58c913aa876ca8a9dd60853a4dcfb760ccc9e50e710b4339eb01bdd9344f2a30cefa95317b017965bf447100b703a07451085657c8df483679788121d675c2820ae1070248b46284036925edb7a06132ce2a943e111b585123be604d8ecc0b1777af93a540bc5f9e1e7cdc5799c65d7423fc518a862fdc698c5be32bac20fbb1d0f2dc41d011d034319fe02c2154e064cbd204fc0860cfed60aae55a8ba9230780f31f8a9631c9acf94ee20730242f7b695fca20b002086a4e04a300166947cb6d7812f754e5a83d5c76faff07a0072b7500c7b125e2e2ef15f6bf2498f4b7812d2e83149ea24a50185e09ffe5078f9da944a60a391365c0ffa96e6055388fdcda03eba851ac03e5d736651ade4aa54529d0612cbadc5c4351d28a5b7dcdd890d0dcaeb5ad2d8b048e1cc8a4466c149b577aaed0a357792bb1c26419fc750c681e2b5024b1392ddbbc84b1c501fa5c622ca68a4ecbd62740e5f96c65387846bee10b14382e177af167c12bbd6756a15e64826bcd3df531406022af9e179ac496343dbedd3cb7532cd23c6f3f429a5ed1d0400f42eafddcd34a6776372416486b5009cba5ff45a70c3104aa7eb6a54d66ac272bb83c786e4e3364e1e786f57083013d89721fa7e3a192e1b8633c40cdde621615498ff3c5f1793b704a27bc6f36580e6a2a5c1799ecf3b2fb1c6a516ac4a12c45c7ef87f19bfc750cfffea3b64c34e9d7fa75c8b7219b70d92c6cab6c13311850d18eefceae8df35d00642f3a7f79a8de06605c93fc23a9ac45a419e4308a89382675c9e79aa7833d9f52f895b26b0309938a7af24520e061c984d3276a136b5d094532d36d452537325942e7e7ff4c6ceaafa25ffebdcfe1b5b0cd7e1fa084ab3d18713cc8295edb83c64abe890725728f5459c01f9d46595013c41fa752db2c6aa6653bdcd0552384ccf118ab95d9d232c06df5ef249132161791026c1500853755faf0fa6caaf099d90526e7859863de08dcca5a5139b1ee568ae9d9e7f0093971d883122b9900b382b612094d05ab9746b332212b5aa40d02003f66694b1a77f52af97420a43f2df22bb29a4111a4912bac8fc8bbc4251de925f96561df87e38875e6b9fe69c1053c7c3019993f1ee0ee11504cc0f19810b0a43ab4fc2b76e71bd1fac498cec8a12509e856d6011e9881304cb23cbae4f84b5aab03de24141a7fea7da0389e61e37497a878addc42b5c8dfff061727bf557c580472b3351ace57e162b1d731f1125c5ffef82e93bf7bf6b7b4de5491f39cf1de74aae13d6e1f1fe30235a49080046aef913925db858efa3012f9244bac90106393713e26cb871b5f27171c1dea719074323faa6a5d900409e28500b0f057a3b576d045196118a634446f23802d29acb8dba93922543e846f905a3e5b1470d30c9d95b808c913a6ae0178d0cf0d8481e2cc478250ca4b44e333e3d6c0dfd7bb8cdbf49be5833198708041afa67e2bab4ab2779fe9c34c4b5f5f3be759a5eb9d9ba8d50671bb81231317858daf82ded9663245d1dfcb4164ce8d738f02ac146cc7d008c1fdb7f54c0f4803a0dbe5f8c3e605f2c547b89fe3339864ed1b2da0bd991ced317c40376c5f2a354e4627881315db417eb20a85c08d1bd5c4c6955273084307a62b9e42af0f55262e54c5981a6e110df34e8e1fa0b9904628adecf83e4fbb2866f491c85f8106aa1030aa96146296543ec21e02945003fba134e46f6e25f393dd0a6612aa102cc58965e9550e48c389c1c04a326470cebedb427e442f8b848df82a8c5d55eed0d1446c6e5d6e0ccdfa2d219019ad3d400fde350d690cf04d083844adefe5069c7066b0ea24854ef3f5853328d7bb2ea735b370eccec5f0f777a467c98f040c423fc4c3df237ee8b1e9cee6c859c860c0297667809ffc0b73af9815b01384834fcb56d3e782ce11ac9124345a3d34fc22ff7e0c3149d66f7bc8feb9743bb54405ea88902011cfd4ed07ee19c6b8e6de6dcb08e2e86427e5e675dff052652af14d7af936f032bbbe508c54fd4dfbd16921e7b1c1471e96f3a521b911e32a5888b5a4083be97a3ab843a1dacc19e60f161fd84c10fe94c9952829da6979a83ff25faea14df6f6d5c876f3103a8a93deb51a3834c9da185355a8b189585f7c71ca082295ba29e326e60b9d08ec5386deca533a03b903541380cdf616135e348c6b09a5cd4a074d7c2e3d794e44a0c4ab8537f3f53b12ad2c2a996c5ec0a1b6d9a25d920a782bbf2120262a71f816a66ffdfedf5e5dbb868d37517607e880d697720a0119077b19df4e9e8709a177bd25508b00c6c79d4b1c1ca7f607aa7b18e6f93e40c8ac9d8705bd9deec9626cd4aa06491416430f1e204177b62d1bd18e9fefa0da4d6e032f785851dcfdd3e2a2058b1811aaa976c30a067d9accbe4504abb7c2a39492889fe518dc529cfb481320dc05a785cdac3fd225936716b149620ce252d079b0f14a947bd7efa17868935b6483516f7653fe108e5c1da91db5a58a3aaf920ecfacdaec9cb997d80860e966fbc4c2cdc52f41fd3dcf8bfd70fc4a28f99128b1b5e0d412c91fd59a9deea1d9b5170e92e1ba12064847d72f9ed9a58874ce906252c6679851b735cdd5f3f17e35e0ec6117e83b9718e85bcfb608428bf03df02e2950a07e80844403f21b8b0e6ce349c5ca2c260aaa780949050d2d9fb90f890e0d33b4a8263b0f3ff72d06ad34072f3567c85a6e301d5b374d9a78a94e5a3523735e3f9c2db0734aa7c7c5787879687b485f1fce35966c742b896aee8f0361d98ff221b58f0746a0bb4ff1443b1f21eb26e1503187f52903a842a278d3cccffe3328876cada9acb5f109f1679265c39ff58a2f5f63162117f63556389d00b7ddb9cfe0346c62344ac0c9f130294d0178425920cf8c5623e09bd387d8f1d1bc4a7df18f8f38f20680ce2734505fccf2d7e13a0fa68ae5f7f949346bce6896c992cff605197740913534fc38ab50d679c92bdd04e6682ffb8581c3de476b13bed9e72cc7807e6ae6a0f0fca5cd9a03086c1a5971991a7e0a074c128727a4fb8e63240df8d4e87ba2077b50ca0c1de5ca6b4a09fd2d16022aad1342b0dfcdf706d13d433db3f592bb467f911fdd09969d1fcb4fbe4ac156a4227dfba8999642bbb7239cc6bc02d4e1cc5ffa47642171b9807bc2e62027befda4cf5d0b994e36b110580f40ae0b8505bac989738219bc3deefb4fb85037482687f8f196ceed78ef556907987d952b042016046c57e36e47e9d5e4c71d5fb7bd2327809e4663d75a402c9b6d89857d2d07375273e3142dbfbd1c4c658fc64e2436ad5d8a714d9a626b8c6a26c3ca5cd8b7bc75162e5ea63a1644e4365ed6b16107b8462e7186586b0b2c43f526f0656c544b70f5e59e809462b1e00853cae8bb57e39c55abe0e2435c53bf68c0dd39e3bcf6da3250f4ad1d47f1e9813b22b109c9f2ca6b06b362f8a0c11774cd90321561ea5633ae94828698a5b87a338a0a1ee58aa9e3759a68ebce835ab5bffab1cb564a704c220e8f451d02ca511d3a61071e59d7a638c6eba218fd186a9abe7144e21dc862d71cc14fbe19898710ec7321917cb26df10994c2d4980eae0c9c512cfaa4068fed52d0c57c9dc3fe75b51f333210839a37ff90e8508bbe215d7fd50cc4c90daa00e10194fb660fb38b9a85be80afd5232edba10ab7c98dd8e5ca4eaa6fb7828b529711682b92e5c980bc877a83b9d7f0b848181110e370bee7ad434463f90c954705032d56c0b86305b83f61642daec190941c8b687f46d70c0c0cb4d627c0af930844189d3df40c1ac2c5e0f19e598bea0d6405cbb41e35fd850f26bec7aae8873c883ba0fe69c268839681796ad11c090e891f6cedb944fb4118092d8b4397dce87fb4755b1ac74217d12597496c41370c4653df24c3df308c2c9605efcaa3e8fb55250eef97ba85bac046d6aa82d249fdd348bae7b1f6e658b8072a2aae3dc22920e419e656810cf8f80398bd4dbabc4df89b4b46328524ca43edc03677156dc05a215d2c504db8b28e876a1797ae0b57de85f634151a8bde6002948ae1f540fe4d5f53186fd979992d4bd95c2fffdaa0d02596e17b439ab392ae0f50e6bec0af1ca9668890801d5dd1c9fa69c06ef9fb04b9b0260e8279bf93f1fb0de27d60b0c0d07329f986aa78e6660a8d0785903e7bd71fa74fa1ad87a952a22ca0c215d035817ef038624b5445a326d84ca96a7486058add15801596906b1d78381b9092f504db0008628d32fbca6471359d445a248c0019ff3b8f6157b7b45c14c76ef673a927ac5e425c0a2cb71cabda5b2f323aa037543ffe1c84c1833ac61c016bbcda50b219bca8b2d210914e2e6aaf5483c943fd4e7c68228b26bf751cb466667a66529cc4c19812a8306a25776f5ceb24a601baca327cbaf470a61955474f3d9ae0aa8fedef83fd62d1d1e843a835c3b993a00f09faeadf015cb28d01b01fe5ca49864b667ba0cf0ceea8439d39cb2a9ce71f7b3a5a9b2774141bfd68baacae775d48ba40cfdeb1d1018f77ec090a44ca5f4672f8a1b6110421edbf5014dac6469e980d3e207f43e25353c1a7d4d010974e145a7cb8a5e05d7d79c7f4eeaacd410dab582adff9b9ef8ffadda3682651dbd8ee69d60464070908bec020c622cc00cee15aed981698ca7d413b83b78fc1a2e6c85bc11787374342b243093d26301476c94e671d7008c7f076dfc7d5ea5d765cc4e82b0fc85ffc8c6637909142f4f3fc943170002ee6e4ffb8a3807970aad74a2aa0faa7a3bdfe4c925757497aee9bd3c1ed174e3aa9ef62d6c8df963d0272545e3a19aca824d7ebb9e22d1818f67e98d5dc3e1b3c45fbbaf8a5e053db3fa77af51d975a22ab70321bfc40af2e3828542f4236adb4755552c9437ce84d39332588d33eae8fe5119eccca99d74962a3c9f09ee67eea15f24e58fdeb5536db348f335c67ddcf19dfe848cb1bf5f2be87f5641032816376f9dd3a983822463898a9ac4fa1c88294747715251561bed2933c08be3c006f05a7b3fce71c179e9fc1bb1de53392ba96d0080179c058c441b9e370714526fe5a01dd1ceb43fdbd75efa6324d799955a4cf9441f50c25e456c6436f95fb183851782552a4e3ba51d2597225b8f2b84dbd01ab4bebb18a49712ea84e86297c4be4e394a3d88646bc8da23d09373a2534fdec05540253bb9435ce0f9c1ee444de9557f880d3bc81ae16dee47085dec4022057b0d3cba15569f542939f58609cdacadf9d5055a9b123be4fdde7985a8a4eee0d37032769527587fa1e09cc7122c8323d1c7ca23a98dd63e970031d8545288d6224c9cc034e60731a9212a89fc6704e67f4ff3638366168abe7c5300fa1dc6b95f56e079cc9b97595750031d8d346244a5619031e924c5eaa8ab82200032737621f4e5684fa19c40de1ac18cc6d416ca42dc59e52b07e1a69f3dca3ce63ba55a4c1a3cc761148f83808c62b840b9252ec3fbb2060b9e7c75f6d94891722056d24771bdc8806d3c5124153b2e07ccbb16b02987c0e0ad70a29b48ddba6a3201ed15f4c055ce2b9e3feb5a7ff082215587c9d891c9c02c2eae1c5efd8625c6535ec57be13465f5d4b5acff1945f0a7a11b0e41546b1e8f3a3ae85fff4ec1c89c2dd44398d04e7689464ce2c631929b4652c9e7645684a0857d6c2cbbe2363496c88a5d05050fc76d488ba7f953959cccb5ce8e062c203df001a542cd5e3ec4fe97eb15619a9149022c9ad71b9de36a3a5d257a0d3ccca684666a703ded560df69a53ba546dbade63093831c306d04bf0ab91ef00f96e22edc0e9745ee374693ea38e7c9a66f766d395be678036af3520d65e817f05c7a9e4b5ee15decfdd2c40e6a75789c112a2cd02da7e7aaa27b57b50626a8f989630b47550d39efbdf17d08da5e066039e2be80c51a0221853d0d840fea4e5d0a818de468b455d1a99b98b69ba89c118ff0bdcb250fbfaef760e3eb3098b92512e0cbf2cd32052281727ce17a1d55824fe953029190dab087eb179c5981c1e785a2400bcacfb5fd63025983d3841b2123e21b529bcae8f9162068db42e1280053dae8de583b3b713f2f78738df67188b7a01f40f0918fa1e51ddf85757ce251e903bb996d87ae4c845a420e6333e0a3c292521190d1318d4840446166d1241f4a837b47179ea554e144991857037225cbcb44e782a9c08d58f166da0e7dddd3b05ff2f7cb5ca53e445a3e6c06a1e3e03c7912619a8418606b4b5a6d8df274ce2aad313d5ac4305024352e9219046a0ec8ff68f6d7ce075490b9bd41fc9940f8a73fadf6577a4742f08d0524f72500d944e950ec1a7b45d2bdd46df4bedae251dbfd53c97a4d3c746de80214c46675522ca77fcbb13500597ad629d5625f9c2ea4c38d1334225b00ec20b9127dc4a15d65f129f4f95668768b51b02341df16c8430c163878ea13ed24b683b993732cc35b987c78e2bd25f1fc6ee4e152bd489baebe997a247076d380c092acecb79c91213a29ab370776cd2c3b3871204cd156e2ce3ff091fd31b65cfb824f14f400f6d9bea7894b8e2744e60b68cc0c05084c024e1cf64867a132f7429c9411fd0c9e225f4828bd9f523bdf3f5a8c21b09dbb8f4770bde3a488928ebdf0ff3d2c300bf6f4eccc94c5b1e4551ef25d144cdf78fbab3fbf37f01160ecaf91b153e6a9322575c082c4eefcfcb41f606eacbc87e9ad7022a0916ca782ba8a2bf4f408d135a1605c85ba1e211a78747ffbd1ba7c36589bb7cd801166efcf55a8e2e9e24bc6cbcfbf1ede191a777fb4a6a67a39bb92498b8d06b287882c859d668a7757716572334aa19f4624fbd7dfb3cd42a34f6f12da60c850a21a2e9998bf4256b961200e57621dff71ff89860ab8f1388b889e6836fd22f120d9f42e08f4999454c0523038e056404d989a3dbee88cb59a57efd7c5bd3827bc85a0bc8c02953ed0d7dcaa108c115a48ebe00c19ac6a0b7daac1b1468d6d8252e93f061bc381523fbea0f248d4de1945c704fd01510d54aceebfe791ff1a44852613dbeddecf2e7fdff1e981cfad3c615f65ec413546c787497f2dadcb2022a6a2aa463bdef07ce1f303b06c8413357261f8d662a71d344737504ba69b8be1ea8252e6838ca8936dcd7041dfd6a646d1cc0b12436f3c89a7feaf8f57fcd34f860017798b1cfb22395d2f2836dd02988ac37178f82e5c543a98b8982e59a0729168c866526ce53173da0b9300e6c17ce85a74032f052a82142b290911a0edb93bade04baa6e061678107143823fbfdbf3c06c0dd0de671ab6567cc3ee3a657e7ecf6d10acfe4ecb89f9698307623643468e0ecb86d9d9b18db9ebd3272d674b43d42784367f2454b3759ca6bfdb30a9001d8b0ec48ed1378d40a33524c3a81de9f331833c8a3e9cee970f651dbfce88b26ed8f6a4240fa2907529e11a44d4b35483310d25e3c006f2d7d51432acc216d43a4de48db275262f925ac1669a7e6e9317fac48f5a8c60620767062e78bc4d93c3fbd5dd47a332512d2fda7447f76a7badc77f862f290ee4b89804280f591a6badc290d3e128c46b681e69d71c3ed2a3b6cc4c530e0479309d6287b692e08529de31d830126afb4a4652a8aeb3303d3547d00b93b661edc1b226d6d79a7761fd1e43264a090a0d8e9cca3454ff74b8257714e299ed3c6f5b6648b9c26bc78ff09121b9a485282e4c5c2b240129ac0819c8532b0b9cca4472c180836f7285d09386581375779cb546d4c8ac6043b3255ab1035c1d6e07647f453130bbe2aaf04e5b7bf49d0cd6474c25a75c67901a23870ae77c32e61af3ffea207f8749100649c3cc054c36691d4127bfc7ad18e1f018ed75f0609001dd83e41d6e2ac66964c248eccb2802c378c9252146c8674ac23b81fc13b0089add0152a1141a6472370df94ae57e54ab1c3a26c55f24a1dd0ccd360e794f0a63987a08d50ffb84a76d3689ac1211ea5d8917dedd6abf81476dd0ac1c7017aee6abc9ee1a41e6f5edd0b89b9d99983857dc32914abc1e20c29c2c2882c21923c947c980e43393500716ba97ec56ce33fd4d01240988636baaf5aca649f87fe606606fecb888b6a7c62dc99688774d648982ce1cbaaa3282467050963b31d95c29f55d427d4166b142f767a695ee5be116bfc9455f405c12a1c3e7dbb14564f94c73dc0a7af0aba2b89c172b2fe5f9c059c0a51fa792481ba1fb6f97faed51fa1e1857eafa818290875f34d876e2a17e5adcc7bebc7b01b941b9934c2e4942e9064d836f976444ebff2dd6c52f44fd9132f4a4a0ab659f052f5b80e6696d217568dea33b7a90302d011384961f7809b0238ed7e26a28492676e4368ee5548a3f5be6b7c3f4342ade03db48e82bb247dc95b52638fc38802881d0c2691f2801d0be3a66700ca06e22070d3987ff4d44db8f952832f0a74e43f77b7874bb68fa67435fffb3a5d98b034ae7766999e8c9563366a70d86110deff01dc7cfae0391be8ebad2fe2d816a06daa82ad16587e43c91dcad74b672541420d12c50f82f737de005ad7235436f404e87ae5b3ac732a92a34bfa3c20f267fd4c7ab07947232044ed716b52a0eee6bbd8388d7e4d15c904a4ac17bc8a7c57032a9e8e8a5c30ceba4a078e335cf0db5a938e3233d9e16a503d741755da53cb2b848c86c25199e1245000f93043ed0b8ca80200a4d1cd64118869789d5e90f2b393c38faf9492f91051c29563e737b8d7c5c704dd199696ecbdf796524a299394015b080f081b083dddfbbb0e92e54cac171d082fc24500c43d3192e533573280171d8acfb0e33fc3cc2ba48f17e79700bc38bdd079718ab17b78f8e26c5abd38b570f0e2740200fef30889f313080d369831481685caef5a062fcea0a9e47b518a91645422baa2362f4ad98e17e5171e456408b2077fcd8b52a900dbc50e7436cd8b9f6366bba86dff1cc9aa4168760028e60680a22e0104c59bad251901c5cc0050d40b004700c51b8d480450cc0a00455dc4a5116dfa2180e2cdce50208062fe0014b50730a84d3f01a078b3f3880050cc4440516f10146f68363a0028660380a22e402b1b6dfa4240f106cf7c4031f780a226c06bb6e9077961261628661e50d41d30316dfa406694857f80621e00286a01f88cfe8ecf70cb0728e60080a2d631c2ad4dbf87d175ba30baa20f0050cc1c80a25e81a2ca69d30fc7bc012866ad0128ea1c5054c1367d1c50bcb92ebaa26f3300c51b15088a2afd81a2a6ff44f90614b3e6018a7a0798b46d40f16657998cb26c0d28dea87480a24ae70045adaa59e300e9cd162d28de6c51dbe055ba1615499d99a40227a67136b3e19bd31a5112b09766d4d42475269426457369ad198cc2742a8f5dc49c9868100d923ad9680924d86ba63edf5c37cb3564a1ecca2d2525a9c314862ce6e4464652c777b7e1177e022761240c0b1386c32d5c05136121ec72fa7c6f4e6540c96257264c8a3109690ae5ebba3f5ca32b044605a9336363665032398620757cdfcf375791ac601a93449c2d933a54db5c446c2fbccc10238707fbf9ae9f6f4d4657f445215949636df91d8d4d8fa40eb67c20b2c73f67b1ba7b752315f46e7bce0eda5fb6a9267b2d49007b326dad71b66912d4a63ff67c516362e747142005d8b283098a40f6fc1f76fec654c294404ca94bd3d6db9f7ef69c2a5a7a983d147776a84a2582ccf6f7917252ea5cabe420875486568656665b9e200fb1b0b267ce13a6e7d3393fb9bb3d6d0e91aef9405461026da74892ec49bd6c31f7b03939e80955ab5beab9d30f7e53eae1299cc4113ba16def4bf92738cb47bf50d65aa5fa705321fa725aedc559dbb8ce4bc9e899ba6bd2e66cd0dcc081812a878e1a9b1d3c6efec3ff9bcba0cbc02b92b327160f2d0e4e475f3467ad73cc3407e3ae38a741e7f3714c74e57405e6a17d24586ca645cec5b99c27c8593e6f61b287522ec63ddd7baf067f2f0777f5f7de7bc3bf37c8fdbff7de7bf3f7b22ef8f7de7bbfbf97e7dafcbdf7de9abfb783cbe3efbdf7eef87b815cd5df7befc5e0effd7175fcbdf7de1c7fef002ecddf7befb5f1f70ae0e2f87befbd37fede9d5be3efbdf76e7faf8ffbf3cabd7706e0de7befd5b95368e6affe7befbd3deebdf75eeeeffd1000f7de8b736feaefbdf73e8de7c1cd206783202c9e0e80fc188000767c0440a7070034c0d10087831b2b1dc20d34c8c1c9c0c6df70cfdd703540efdbb8edb79b8d9bb1e96ab66db3d96ab64df3e0766cdb66b3d56c9b8c6ac360db3ea523874c25c340e6d1641be3138d8d0e870e372e8d8d17a7c376d452b9361db455c964797399ccc7a7f18e3e6ee08ca6b5f6cbe59a1dd49f6f0ee394cdeedd14f7b6e7eddf896526f9d898eca1201c398bd26a85d62b58b687f3de572ad2a702ad5eac55b6f7b548f684ef7d6d39ab6697e76d6086f4a9473c2f5234b677f35e7dbd9e5e605e514ecec3a30ae953953a78915ad1247b3e2467d5714c1ac791e98af37c11d2a73e0179911a01933d35ef3d1d725695c968d191f754c87974bcf7148af4b1403f5ea452b6b703ca59d6356b79ef609cc7e6bd772fa48f3d7ad1c1d81e064bceb2af57d3cbcbeb69741e1c4e481fab248017fd0925d993e3e52c3b8eb011c953bdf7ae83f4b14f3b2f3a0fdbb3f19e9579900f156d2fbff7538cf4b940d3879d63c2c89e1b31675d974be68272cdb6477385f4b94701f0debbafd7547a2dbd9ab647dffb7984f4b94ad387d5797126b1bd1aeffd2472d61dc76934bebc991e2fce29dbbb4fb23000785186b1bdcf80f4c140f3bddf80f36cefbd0ab207bb64ae984882b3b0cbfb22d2071f4d1ff6a5922702d9de6b04e7d1defb10644f7def43e749bd062f6eb0bd773c7ae08b747b9f237db0128eec71161ee9cabee7fd943ef869fab0ef79af81e78197b4ab8bb2b8eaca711d4d1fce0acf1165715cd5ae97d2f4e15e1d286dbbc964a36c94d5a7e9c30101a94fdb7e9551d6368e553656d9586540d3677bfa01e4a2acedf572bd5c2fd7d1f4d9940670f4a2accdf57abd94a6cf762400a56d35996c948db2a7e9b301edd8a76ddfca284b1b472b1bad6cb432a0e9a33df900725196f67ab95eae97eb68fa684a01387a5196e67abd5e4ad3473bd2511a292bcb64a36c948ddbfe7d9a3e1a508ffbb4ed5f1965e571bcb2f1cac62b039a3ef90900402ecacaaf97ebe57ab98ea64f56e2e0e84559d9e57abdb2ebb5ed63a5e9938fa6064a948573d65886c76d1fe7e39e9ea64f069a3e641508c8b7889ff653d9531995ad40fb3494d98083715634c801713200410ec659d9f6736e523c38ee75f3dc6bdbc7f9bc97714037321e321907b4ed6750d3e9189f6a461de3f8b4ed833b389beda554b3bd746c2fa56dffc360c3b1b9b6230c36178ecde56daeed68dbff1c9a4ab6016120c321f3641bd0b67f6323e7f1c9c6e88d797cdaf679dcc034da4ba96ba954faa5b4edefb8976aae23cda5b934d7d1b66f53c3ce649906d4b564b22cd380b6fd1a239dc7a73c8ee3530d9ed68b872fa5acc197d2b6cf693a2a9d4cbeb3ebc8b52d78b4eda738a11c3e95641968fa6c2328aa545a63d9ce40db2ae98f7b926de3f4e1be481ff66d4bc5c5b4903a761bb77d95f7816f1930a78aae9b6cbb93f3881369c79c47ecfcf3ef590478fb53698e7329ecaa8baeecbb5c1f3817fbb8274ee6a22c0e8cafec87d996737151dbbab898d4b13ba78a1637d9b6bfc99c07cc06c5c168ce5a4b0ec90d50b995742e666dd6aae7643e2ac3e2dc323f559a0c78019c1054903deeeeeebec3f3c0531f0a1e62145cd91c6c990505aecde974f373ceba757fcf885377b73216dbf5f3a79d6ea79b1e50fb1944e1c62b32c116e6b6e005a48cba165fb88eb65402e8aa3fc5acd0b10279c57568e31ab4f15331d2474a1fdbe3a761644ff7acc9346663c7130a8cea098bb429f519ff6cd2a09851e0e1d2fbe0c88f15ea7419e5219612fcd1cd8fee681af7daa6713bb6d7669ba79b1fcd5aab7e0cf7dfdc600acae7e119a9ef3b3c112a131393b7349d4c934903b9209d134dcc06e3c73b4c745535d734cdb70f3450771ee6fc6108c4cbc60fa429c706cd01e92efe1adffcaa5d8105bd2b2075f05340fac05545592af80abf93e8318fd9e0094e210cbc22149c4473c83d83f7834c1fb9e3e1bcdbf4a9efb258de728c93e1f08a5cb07a78856cb3baedfa2777cd5da76d910034dcf950f594898eae83c81eb977360d695efc1b3830f091db878ebec2ab1b9a46e5ab95d672784634217494d19ebe9812e9c8b4f1774f71784552600b73cb8062eabbd75ee519d1de035b981ef3108b1e63fad1ea400decb4ea7d0b75e74722b3f3dfe764073e7d8e7e3a609a82f0f45e58464270b8f3a1ca5b9476ef19a1413ce4412226991327041584ae38cd30464a2e0b8235d1592daae17970f347e319c9e01c0245ff4964348de88bf7690b48c82b72535c900e7ff8af52693de60ca1ef4feeb989bf7b7102b16b7846f2fbcf18394f77f49af144c8294febf09b4393a8a3e338e6ef5e14f2c022fe4da26f0ee550c18f82d4c1eeae4e88b350a02bac04b524674d58ca1fc0182d4e214b97a40e7efad151882f31fc9f23c7cc0c550167d7b450b73f1299edf9b387ce231ae1c04ef4d745b6f7231c38893238877c0a4d21222e7bceb30905ffa43c6a26a78c02a5ed15f1dec116e607f953ef9e7f4e7d2ccced81297846dd0764fbc40eb60bf18cbc4f9c401c89418c266c638c9fc39db79c07c85d1a7822e4f7bf224773d65a2ce4be14e877812d878aa64b7404e188068f70e0053cc4cfc2dc1b98c28f17f0a3e03cdb63cca47ddcf6e579c5c6184856d24baa9f4c94557de5df650d631ce2e778ecd3af7e8d4f888c64eefc3b94e54fbec20f66e3a8240fb33106daf88336fe1f4fb4e87f57a8fee4f8bd22146c61ee0c6ab0fb68cd15c6390b37701247ac42bbfefd797fbed350d09eef5836fd1c22cd45a9e09df781ddf9a5f529377c737cd022654d222faa26bd9484ecc9811e217dbce88acf5c70e127e8338a44dff31630ffda22f3535e91f917949bc23aafc8b49bca7bc11e1e52b08e30412959142657f591b4a45de98823750059813ee2ffbb3ae82fe93fc41dcc41e8191235729ea35a93f66d39cc75643ed2f695fbfaee84ece9be7e37df03c5e9b2bd790b98bf7945e63b9483f1996c86690c6afa741a8bf5a0459fedd8b3524f531f7df21585499a7a5f39d59aaae87f28f34b1ff19887f55998dbbd7828ba93c3809c4774a75dab4bf6c8fa4960c6a830bbfe0f18b4e84eeee43c1e73e9d291a8bb23d125aa44b160f19c4daf7858fdb9499f3cac150884e915c8c34a6352a7be10fa087d16a62355094495c89eedb9dfb6bf9fc881e274d9e6b0e8ef3207e361fd9c1e747d975587c252a9087675905e79ba3f63333663dda657a897c7b111298cc2fcc859da8d5ce25abffead4857a44ea558bc68fad023a48ffa957af926d592a64a49489dfaa2e7b0eb733f5c5aa43198f388f4efd72fb2c78f50ff90c8587fa7a1a23ddf7d3ea5e01cba9da8556eae503757bd4e596d8a7a719e1e3416be4ad39f4f9f648fa493562ed5f99e9e8775856a77f6d01271a0ed3b149c3c48ee0fd164687c04c9058f50f07ead427f86eab306ab874c3879438b9656cb3af3429cc77e0c170ce11b2104e7a9b1e007b66efb41926d2b0d61841c9f5c51f76ad4ae4f6badb2d65a6b7561df2c575cd9a21ce5df0fc179ee8fa0a239abaefc6ab0fe21839e2d0fa5644a638271cf33342e4a29e5e74c8f3e2769473f107ce30fa2895cad0e4a991227845215826c0d04d96208fb88fc4e0c617bd769da431b5fe34f903df9ad9e2f93f26eec39ffbe8d1a9fd42627f3a53e51a5f70557989f0a415436dc092dd0b267befdd944f638cf7dfb53c8ce2b2205c50f6c79c54e20e731c1431baa54f2e7bb6690ec9992fbb7765224e9c3bea863b59c55f3d321849e20d878686d9289f4f22d9d394fed0312a5f3d39f4f73e6e867bf15ac7d77495fcd7befbdf7de9ad4791ff8bef7de7b6ff579e9bda9fb61ce5a7b185e9bc569698ba1d427482badb4f2f39772b6b4f33895f1192dd55a6babadb5d61c1974adb5d65aadad44b22db35811dbf6a5d7df62be9fdcd509cb96599cae6cf7a6b8ed59634f1d53f64c4daeecdb6cc73c45db97dbbf8ad98413ee0ff10bde90e9743138b9e5146999c50a2b5b66b1e26873dea9bce8a6a524d1a7a391d9bc907c2041640f1a6364687fe44abcb1e9933da93742d40ccac3a54d43038af5b52bd0ae11db63173127262c5b6b50a4443bca630a4316734aa540d199f6eb8924249895dd75a0e8aeed5406942cf6b461528c4948dbc6e1d89819942c67242b98c6a42b9bb625dad93b5b4be36850dba62f725bbe4f9e3ee8ac51482964382b1572456b8c8c8a85d64d4f0149f6bd56a98e7bd22dbd9a4445b28238e0c5da43035eac4294f0623d8204aff1fed40cc942c1c88bf50506bc589b2ce0c51ac3086ea30ac99a2e115ea42950c08b748b222f521684e0ba08c99a30105ea422f8e0456a020f5ea45912f02285512892359d10f0229d81c88b94ca7e91f630c4535e4896b70ef0a28b618017dd8c02bc485f1022e38464f9cbe745d7d2f3a2574180173d05415ef42725193209c7599208be3a68d0f225b883657b9c33d775dc10cfa2de19c43f846e1e601ad504a7f6947e62b735aa499f6e339d765ad5d1e049aba6b1d91857156caad56854a1a6654da3d99a06567b6f9d9fa837e6b4ac69793e0627c6396bda764268a9bdd652fa73ce3927a53f2db5d75a6bafb5d7da69a7b5d65ad05f033bfb48926ed68871d2d68a55e8c40e23a163bad79b820e4ed061462bd44de3e10d2d7a6aa973bf86ff2a95be5ef40929489d8b8287f77384d0a2def763f7fe910d50d6101530207d24307ddcbf7f5fcf21b13dafd8f367128b9b4ff82183963d74df9f462fd0dfee6f1c0625dd91308d9fa6e0f7526b41fc9c6704532a653b9b42e5e94634d28b1bdb8dcfc627e5782754eeb49c2ad5dc4013385054a924b881db089a90672c386b8cb2868c4e20fd46e0e40f710a66106824db390f96c9f9358953923d9e13b22725f3a91428cefaf2b8fa929d95ef7747cd987bb31b38db665af5219ded189d51564542ca39d248cee37bfe48c791ce2315e6e1b45291ea8bce26fe5918a82807b3e7ff8041d797f36cf4079a1fe22c1af071e813f5329b3c9c4b37b468fa1cfd56a8938629da602df270cea4ce3c729f85b96945aa583aea3cb282a92c903d5eeabdedbd979f98023d707b2a6e4f917eeefb5cf7fdc61487c1b2ed3737fe56f02d526a86ec997b3e3d63b26a8caee6cb6098d5c99e55863d5bf8452057f34db0e767d9136a4f2e629dedf99c5791a4cefc9c299a22c5f6fcf91628569f8a64aeb9fde63c582e6da24e1e4eca654fba14c659f3e9cc79f03f8eca662676f3e992cfa7239d383634b469be3365cf033ac58abf89e59b41334916c6de2966e447328ac8cac67fb7ed3e12996d04ff055b98437cfb8ed0df6610c8c29c51b2a788b3985a8ae9a455fe10a775d3bf20dd860ce930eec08b69e8af02de2dd01e73ccaef4936e7ff6f0d07bbafdfc193567d307c8f4d1e56c247828e5061bbf9633b246eee654fd9c01458d6303c59f3efa3529545f8e5c6dafa596bd3d069f137b7b1c05d8dbdfe8607b379201c59c02b78de6dbecdbf87e6c3ccd097b1349d81b68e3e5a64988d8b06103c4913a1b48f372d31f9a772109119ab79686e6b7ef7aa0b5294d0992880d319c2158c1eefb8979cb9ff4ab88b3e55b210090b187b0fce9729e2b7fb65c30611b412a09d9b549ea95c8a46472a8294b6b194957a9d4cb4c29864bcf820553f5c019811f28394ad1b4ebcb3ae794b5f370669a5b3fda39f6c22581edfa72f7d8f291d81739b03d10891cb37fb0f162fdfca1f31cf13ef450a652a9542a053ee8396947322b985f4ad943aca037f39904afbef74368fdf29e013d1089f6168362b69e0732bf713232325aa60192c8e55effc63da765b4d6325afb8ef33eb1f380842593c88dbff1338f648ed95ab6f748e698a5ed3da62fa33f2d23da2da3c1f7d0f33c24f6c5d4b740f70f1dc0f172d71a8fe3fb99791792903003fe2469251909b9806078a145e4c7850f8c59420561948186983144665e49122233a0129abf910291d8f7b81f66de7e343640570e22336093999f81ed0cce7c3333df05e8ca312801a9e3afe399408b322684fd99b742ea27765063066ca222a264e66b804d32112599aee42b513203bab055d1e1081b6658220a23221f904e2f314a9a9eaa4843082292aee42ba9f14a667e03945503d47425df41155dc997719926ae8a2a3bdd25655df79a4384ae4fc2f431926082ac596bf7604a1d9f2931498d8273ed39b779f9dccd6bda8df69b767301674d28bac23f299eb3e6757c8e573d063c387edea0791b357ece6821431210c20824384f9680b3fee7a7e03c746aee19d1344d48065050380370c240700a7da0e6f1353cbea6be6351b4555b66c1026873b5dbf1dd3cfdb4ffeffbfafdf0f6ef979ffbee771ff7ded77dead3fa6bd4781a9ac7f1dd507d187c8e4ff53abe1cef9f8eaff9fc6d3eb96f7e884f580db6d9f1e1afde0778dffc64a2fff8e70ed0a6061473ed6abe9b9f3b87082d4ea809f5a263d9f8455762e3175d48083fb7e39b9b47cddb7cf58cf0f89aa73cbee639ef7688c0e36b7e88efa8f95a987bc7cfa8300e14f443fcc6774dfd0bc8953f940cc5d9b2e1f1edf8b2873b3ebb6d3e0fb4afc1afe39b613cc49fe3f39687f8559f0379881f83cf5d9f077988ffc6e79fdbf89cc88b3ed79fcb7cfec2ef7d0ef32b8e743fc792e44a1e8efff9927b53f61975721eed77fdaeee5aed27b5cd1e11623577affed683ec5aa767a4babbdb26772ffee4b328143c6d99a5cb95dde5685b6b6f68d1d803c1e737a3b0bfcf3c0cc63b34e7bc71536e5cbf9a9c358c71ee7276d0339d87136a688a21595a9ab131c638632fc8e59e833b7586fb09e53cf9797c267bccf846b0a0c433aa89640322d84c318de5f01d408420a58a27050900e931e29e160eb0852440f2e0dfbc6eeff0fb9187dc73dcbddeb4b7f7b6efb64f4db1b2e4bd8cf6a7d3fbd4adb53a6ded3ded53e3ce4fff62b132b494df6508b33508abe831d163a2c75a942ed5d73b897414a2ae1e3836236da21e1803c18c93e331ee7307e278453658d5caa55efcce73ca4459381ed3590d6d882a1ca03f81220d0a6f809906f428edab0ef41507e617f3c679de7beab74d6fdb96da5e664b6daa6ddb3ec8b66ddbb66ddb96e319d9ba6ddb64b6ef3aaf03c189e319d9c0143cc45ffe21ce851dfdb66f6e0dcc86e99c4c9db75c4dbed7a14a148baf9cbe90ee47a9481ff8c8431c16491dfcda4789fcc96555360633141415a39449f6d0ad514da323dd9af653fad071fac0afbd967a24323bf5be395013b2a54880edfd8e8cf7da93f1bcd17b21cec3bde7b3bd2780f43e88ece9def33ccf7bcff3641ef48c78329ee7698fcd3c967951bfcc8d5764060cad56eb094d4113aebce5091213bef6de7b2f045c509a26fbb95694ac3c011440464b3c26d65a6b9178f295041365021261804c482208ef689a1a3f4b96905ba8c0b0d87105587111490912ca4c7ea680090a98c8518a1f7cedbdf7de8b63df7befd52266b6efbd59b4e82c29a8416ef1824836114608cacb154ecc96f0e0f262975c5faacca62934686826f304370dc99e5cb9f7de19165f49a5a526ed01332f610d1dc0884571c117504d88dc1df67dfd65df961833049530c43873d7f5a2a8cac507345cd5015c185da24a45174552b80294305151f282285230a94c38456152b493f1c516638ccf10a22b99f3cf0d32dae414443023308808dab6018c600c125f9c44b0022074706d3238e9321be221bee00756748318980f485ca1a105dc1623c238d9a10902a8254304c929c080c26310e957d1146ce402261915d43003bef6de7baf962186f6bdf706cd24b0d8333a202bc5ce40492042a889097624c3740415453a218b714eb0b04e8860ad566b0a26da320a588bc849511dfaf071feef903bd18c4411bb4e6890c517638c3186a2096a639cc31014add2345adf5087cea801430e5880d1058a9f31c65011c20816dc07ec300baaa207275c15474f3efc4802821611484cbc10b1c5cf84c2618c1fba128ee0a18624ae1841144ae6932e320419618c711090af649091a021adea7e5250c49210c8926a80a24395a11b4034f9f071fea160cce42e859f31c61896e42b393239d905c062a110205c3c18e1258b2b58680f5d8af0ba94c0a5559a46eba5314362965c308c31660213b431eea1cb82461951b41f262e6ac03180382f78428b2d404c61e50b26921859c0822c323198145d2c90c08c20ca920ce30e328da32516482d58985c18635ce5c3c7f9b7415aba5cb10d6d0da0220811784d00e921a78d68cc9596eb0b580e38074b74022a122a87555e2b4843a9e80730309528f785289632e00a59138ca5d8bb64ee501c7c1e91341fe7c3c7f9af42450bed89b5d63e31f2957c6598465225fd183ee009d34e102fb90aa127202a85dd42d3b8269a2685144d4dbeb811205e55a986a46ee9873a8009d7bdf732f1d68e945454996d8cb355420b0d8c1d722ca850c2894b8a6108638c9d6839c00917187ff2f4848a1374618124c61833f9f0713ea84b0a0aa32219c688fa82a50c5c44654c92a6699af653e42b7964e50a16a5127e9670184230f1e104569c0cc1840c430a1745d65abb84155fc92b198b56522dbd91259ac29d2ad689fe9a74efbd5a64f0b2ef3dc2044a206901c58c9f228c83982c9a946c0892df5a6bc388f94acaa08a84316bb98a4009e12064c87eb44ad3688d6fd0966d015ddc34848238e8d1c245d40ba2a2c002862e36fc28a1699aa66521e42b4964f482212519c9624ceac249ebe2cb931fe20e5cc64c7162cc099e98627471e24a54f5408c28ad20664c5c60a96734a518d074efbdef23048d9a664ad012941d6ed0678c3176f94a0a11d9225b18fd1845c8b0a488a84b1337bc649210d22a4da3f505bf20995165a8082943d8862dc61a59b640810e5f77982e8b2f166ab55a31608c31aeb131c618bbb6dc2283d0c6d8b593c060a225017df83817e3ba25cb0d395ca37ad444ca3d62ce643269c8702706891d8b2fc618638c316e32c2cac6d80a4d0ba4705ca0c829622fbc6028081fc4bc8892b840c92243030e5aa4f03065054a44f105d7d02445152f0a0d5cb23c63a4186717bcc08698983fc6788c2669204dbc61fb846b63998d31187a581b20c62593f029484c1c146f26c5698b202fb27851a362c0d7de7bef55c0102d4dd3d2c3089a3811c2e8c7059806241f2a52102e269911cc7849914c235dc96cbb9c819dcc2636bc144394b404132a4ba4ac00cb11627cc1642597a525268c317e828bf6908d1248100514315aa0d81002a3218c5a60b92c1947284a10dba161009391d5b20570400206298a20818bc98aa19264c91353d3981fbe98155130b6502e387cf838ff4d59c420858849c489549c1882660b4b2d529c5ab70a30568c2a3b425b6a88a2822f4870c49319943c29f1a24a9221588b0a0e60ca408a61280bce0b4d0372460f49d0e0c44a165e10c153367e5db497e8a00417b2041e8ceebd178acc86dc321446b68778b652f45333a8035e18b5ec4d4fb49c8a1f2daec75c98e84ae6265aa569b4963286a6699a56e42b7964e50a16a5a5052cd19414dbf7feb8039a8062b2538788f94a0e21cb4340e921662a225a4f842bf42efb4ef184114245f98bcc842f505a0b0b70d0863e7c9c7f210fdf7bef76b7eb5234dd1054a150b282a12a6ff1c518638ca950a2b531c63570d1fd6895a6d11a1301652230553af8c08f1645428c71c4c513938c222b5eb884a317141c143f0049e1d2c36c630c055f7b535130ba925bbb4b2d8021480a1aed892c964cd932cbe2880722a2789112810a2334ae931ff287f7091a829aa2e81283c18910d5034baf2d34887105891db00c398c51daa116162be2e1c3c7f9bf181812a30727c0b852051522b7a6b12f0e44eec5185b0d4fa182102c696202511469e143154fb4cc10021aa6e4f0650fedc841e34806335e512ef8c20823820033b524b19480a21ec000d3da320b8356d1524516a9a0d1e28b855aad56138c31c63936c618e32d474c1be36cc7259a949d291cb64f348d8a29464f90f8ac598c313ec3e52b299489f403ce3052bd6be609eed2e2a29950303ea93c542e4442331d232ccab862044c284144858b0e2e4e8a1aa880e2046bb55a4fae6482b2e2c485c9101eea92a4699a06f395444a1a999c620f1843e62bb9c52049617297178a6820818c66354dd3b4fb9ab7354dd3b42366be922d971091d16d00122f8ac3fdd162888240f518638c957c2597624dbe9256ab2110415aa569b4c68106dc84039525fa6b0c3a1830851394fd7b31de72451a1bdf8dc128c4c4ec96518a14a37ad444886dcb134948f91d7c826af1c594a9d56a51c118638c319eb22d9bc288da188b2562d8b62d4cd0821ae38b26a204e1189ad208639bc64499819e41b110143f685439da4952e4840f3f28e170839527a6174c70d102a858abd58a6225153324410521021fa298587c31c61863df18638cb36c1ac18f56691a4d0375103e4041b1a40b204d9f08f239676cadcdf9adb5d6da28a85c42d4ace51222ca259061a47d9a267fce5a105cd62a1a560933d8943a672e64bc76cef96d9ca7dbf91f27eb336625a0d17a2c72b6399909d56ab5a4dc2bb534d1b4ef6c37b9768d2c6440fd7815a3195e4489bd60c51437c81dc408e386fb2f7b780e60c6921b6078418b491573563486071b3235b2e4a22b99996427185ba9513c11e48442b9f77eb7afdf7b6b2d4307269e68594195344a40e46229fb76a1b20315306b5dc539bfdbb8fe9481914559ed7b1cbff2c5108d0e3f186f50687124b3c86634bc38bf7d7db981bf2ffe8ca1f8e2858d9f461546c9c66fe3aca0c5a864cc184a7b9aa1a90100000000c3160000380c0a064442599ea6499cf5f614800e6596526c50369d86b224485214c510a3000000000000208800829073b4a3001789589a955a9b67b75d52f2f90cb9b4157bcdd2c16ce3e00a990a31292226c739bbbd9835c20adcc6afa81012339a8037382fdd96c7f08b065c974661e27fbe4b6b2600cee951ed6d1c1c96205aba8556c83643ff8511e10c604d7a368661f77c56de01b4617dc87331da1eb9a09829d58134a28a237f74e4ca32aae8855cf3505a7cdce072f6b98838a5d6a375f2bcd63d2c995f60756cdabdf3d30f62ae806482f2e47fd2d0745d633cb442a43114e0ec4bcc81e0860d4f474b978ff8c71f480d3364e88b3bd2e3bab5e32faf69da18b2cec5c44bcde9d49c5e95099b68a5a701e4e6baa1272bbd14fd1e7692dd4b3bc99b8fba5a9c3c8ef5ec7a01abc045be1013800ec5369816f763a72e882d5cfc32bef807ff526d70d39601b99b926465357582a9a4acccd80c1d7c0992d1a68bfeae692239d12300edae46f6ab7ca0bb8d1ee94cc9925dc131abc92cd9dec37e20944b2766e17a123882e69f99e7e34aec1c67275835854084012c2b051d2f3360ef867c98be957e8668364aea0a8a4054494ac64b56fa0f73e6a633ffda7d13a6344c142b028d257aab535d8cb8d4842da4457587a87159ef481344ed96963c519c67e13addafd15397b633a8a08a34b8f0ee2193806ba69aa9f7974550bfd34c867623b14251abaf7165845690ee8d4aafecc1a9c3d4cd2b5efef7c82a8e9adb37d6935613b7d97c1ec4c8d7f0a486aca200fb12e3a03bdf243d0cdf6b57e274dfbed096f8dcbef9150e58292f0d7dbc28fd5854239db3400c10d241b4e16e47881bf28b7815201a36e38c706f89ee09557e7df2edca497860a1da903fe008c478d59a620c59a6ba01f05cdb7e18c0433643bd3feed737260631c9e07d006b5bf63808adbc7b45b7ef99aa0e5083a693e85183120e430db11e3e40907ea4618c467097b8074336ebf41d69d1874b8927312a54df0b10ad126090f2f62175a70ecad31d6ac2c30535e3e16a8ddc8948978012eaa875417b41318f703dd749607b67573e026a9e06665b282c4fcf8e299fcdc5c45993af3108d9f7046db141719d84240fcfdd6f09f3a1a9efe7603bb0744354e9c20019d4e9f5e7bbd596b9fc885e9e5e36f9fc8a9ab77be6c6a20d05a692df0b1253154b6dd6d245696b2afc72accb89cbd07d6ff1f4797a35be9f69ef5debc61b848a4c37341738aa729631219d35f0b839edb3b0d2e07523ea99bcfbd208cffd0ea2b9bbc9596451aa0dfebd42dc888495b4cf1db9a9ad6a0e38963ac28bc74e88861bd68a7ff8fdefaa4de013b5af3d5f2a02ba7e43255b2022065fa05515dbfce106f54db4f28bb7552e39881a4cd65865cf8fb0c5a1b38338633248e159842ba32e12268214f8a898b87fe3865ee5ce60ae80503f560080caf3abfc94ba346cc56d73435b2a66abcc7a44d1a1cead361b9838097d26b0ae0d8c8740f7ee85655c34356d631faccad21663422484ed4a4f5fde07582a2273f61178228dcaaca68055963f8e756ca37296d4b64cd06f6f05d172a7ed8de872a3081d11de94aa91798c980f1db1d6cada53246d0cfb194a6f62a0241bc0ed903f193288c7ca587c734b5be99d57619649cbe0f4c3333ece7b34b58c9b4e27f03f5b974ab95e9c89218d10b1ec4939bd4884953396d851d368ddfb7f13f340bf227dfd1741bb8fe5af4f3ff34e5bc49884ab6eabc5254af84399184029c3e5f463426b2c7c695e5542f3876a1597d79e0ffdff15a0a423cfd07b6eaa2756eb4bff2e7696b6fcd01092b9f5ecfa9e43cfed87ea1b0cacaf0b63910f719b5b5424e60ef026281698ffadf90c95bd336d7509676ee0250887152e543fdf4d0ce9b2835c2d8cd087e5b6e6f6c4aec81e1da1d356a58ede46d3f906226a0e856db6ae22c73f686e3f4bef09d476619aa291edf112a6db9eee92f22dd96cbfd36e35c315f161f0b46d324b0f879bcf98adfd8eafdeedccf22c164249ad8ac917983e181f9f3915ee441bfb6ad680c9b45468589bec364fc56c0eba51a864602bb0cc7161784c4224ae9089b7914eac4ac63d78e58190f1d462b80638e0bda7f4b5021af785c2d7805526776e6f60c979ce3d52ab4432dd815e35e4a0c4f94a25c16741d6911b6896fa3168042e74e8193560fbee3803a5716ef90d40c94fa423e994f9704d4563e9c484af9c5410bd89c4d94e3b1fb3f4e0493d562533e9b8a33f7032a42b646c56afb7b85d5e98267d4435a07e53b1f84a77321bca95925b94017437c005b39a486aa3415ab3194553288c478e017678604c213751d05da19359bc4f7ace368bbda50b60392e5b505e63b35aa39bd0d7fb811f2ee6a0c232cabdff2f178969e5c7fb3bcc63d0a5266cc2af47b925b1fb997088f34e21bfdd7ad8fbe7c0d518a52d68a54158b8e57d8d853c9d7b41062a71f60a10af8796db6cf4f0a7be6c8f36d4c199cdead3c01f747b2f2b830947dd087a8940e63b820f4ce65f5fc8b2e2d0bee4bdf30ab550cee9425a937136018405d5ff245d7ad8c077f4018cddfffab03b49e78750b570a49f50eafc38f9a12d526bcc88b46059a4c234ad28fdc13291b2e6cc106f6b4f5aaab4a50201a6842fb2bb6ded57dd6ee06b5567a8dcec04917816a71c1be608e44bc836ebe3958ce016c3f9857777952765a778f18874585ff4b64e6cd430e319939db0887f30c11ff5528158b08e1792ea4cca196046a792fddd925973b6012e7c3441355007fdabc21890579fc706e18737901ff960b62c22d05b65ccaba1d3d969ead8a4af0cb4bf12d6815562c66d6f3e13f2c54fb4b6ed0eb74c3e5a099abf3f3833b79d176563c9530bb040f2cc04db2c351e6f998d0e69b4396c79639d498a5b2dd351e306d8dc62280b9547fb6615e3cd399f5be9f2f5b9f7dacaa9699a7068a0361a48466a4c4cb17476da2f5f47ea44a089e4849c94e3d0d3597d7afce5193179f4ebbbb45296fb3e1e059b747c7340866b8e310673e1d5fb4ba63b2911115dbfdc595574b2fe99dd5e26680acdceb8e799a95c836ab0d95ad4b2b908c03427d96985045c49a4cab93d0f609765b4210d4aac2933e935c8d6fdefbff8a8f753c03b457ea60173cf748bafc448e1b4ebc7fd64d839dd7e7d5143dd05c1b32ee9e004b6c6aa99d00dab977667a1bbfb1ea856257b7c49ebf00824f1aaaabdf5c31433ff30f503f9635521c3bb9f506bac5431512b0520d378e0aaf4d90fd8022f72d806b13fb283189e59191a3e6c091c75543cd6cc87466b42842c45c1c1e8d0e71e93536a3fdb4d1b8b998dba6df603ce243cf117eeb6817d587d830e262b6721cd541856c8a0347fd4edc940436c308b33634fb4e99ac15d2d5f6931fd3c1c26026f0389838850355c373e04e41188ef2f9f49cbb6951ebca41ed52f8cccb902750158c937424795facc0867281b3268eea29f3f3addad0ebbc8840512141a9eeead73452003ab6759f4d68225221076ec90ec1668c69650907f7fd8ee3af136ebf9e2b6681b7dc42191c1b33dc6e669eaff2a3ed0897a3808ae34541d35f771594ed5b8ee6fb618a21cd6c3ea4006d6783b9f9a58fe76802bc45df94f7f5b16767e193a3a9af43cd6f0968d75e8a554bc605cb00399ff6365158bfead1b489b280ebcd5ed20869684e1de3128354aea070461f9c7c2c9634ce70001e97bce1f355eaf9948ac0330701751cbe76efb18859098b1b79ed39d974a016a58dde34f0e0c39ddf12b8ecbf8d7b40d7697e1a5424b94d7f062f46e184889e7d4be6b0fcf064bceb37c45909a679d3826a0cb8936ac8b26a0e45bfb0a4d22689f3ba237fdc72e41bfa32b6346ee399f6e9bc1350b6a9ab827f80fd3cb6f2004a13f6e02d567ced5c13344306bbdc43686c24447436d390603ebdac40a0a44c8f375e1f30a5d02be287f97b02fddc2aaf64b879c398ed31eac6f900ba8ab2528816cc480fb4799602d3fdd8caad6684898ecd63211cbee13733b51ce5fa9c21b97bcbf4ab59b7497cc855e666d904deab169136a81c1b34a455218a8a74388eaa106eb05050d23cd599c0b1b91e4e39464527a120f8fe91a612f693794c90321131a6bd42e4f0c08955e7f4d9a2db9112b83faa8317cd39fac2cb94910b282f74cb23dce4143925841abad3ca5f1dfc098e2165c3b5abd46d07339e8b1737cd4f7ab84d3250058e04982db947a6231d2ba7698b342020aac7fae284ddbffd43d9e816a87a3de6dcd0aff6ce0db0546392b5fa8b0e9542b6e5fd3c944ef5eb794f6aaa5a3589b13d059de1d2c71b6ac6cf0c0c5d72449d795f81883f62dd32c97bd8ee704a7d4367a014b589bed95bab6110b91a8cf39d23635d994c7c8780437ffbd4de259f678358f3e0e2738adeb753e3396dafd4ae5a3b16f2f30894027dff081cbe640300bf93240ec925b0bf86a6efac326311762adb8167f316cc358293a39821bfe952bbd81b4b6c2dbb51619cd0d6106261c7323a41ca0dd5667c1d9c7f535caab2da27f06787de384f4ecfba96b6fdf15f4ab0e08eac7fa3f6cc713b323c7361bac2e96280bec301cea58518c880e4db1cb61e9ab1488abf04ca7c0920c8aa3bd7984ce1587e6660f2b0dfa42bb0c5fb48eb78037d22bf0aece3dbd3f15c8e073605e04e427f4de09dea961ea93b2a98966c2607436d0a554619bc09bd9de262669ced06e1a2b0cc061ee782dd2e0f851c74df6467246127020c73703a1ea980fef963cbb9048867fd464892f49cec9a1f5ff783117af870030c73c4c37f5d99daae862c3cfa322734c74e760c8ee0c65b4ea7fa5e74934166754317c63ea0746c6d434b585eebf15dc4697ed53f178dbdc65a672853f4a6ac12e7745b94e53429f3bfae444d989a450304f4a46ebc9c491fe7c812dd6c941342b3196dc54fdcc9385e2939da9fd842a90cdd0fbd9348eece2503f9592ab468a8f864f6d41ef735e0380ac00e84e11d9ffc7ccbb16b35a83b6cf030a042873c97dea4a22394a1ea657ccff9d20b2515e133c75741df6091256d2c206b8510ac14ede483a066513e26213128eb84d4a4ca4d9442134063bdfeb22e64e774ed8f77b9be1d70e9bf37454037eeb53ad91c6bc1df58342348ce0ded737d76df5a3976edf231b2df75e38dd26e397f2634bd9acec8cad7dfdb84fe4ba971430111f13619fcc9344e55fcd7619dcfb4b427a1da24e10cab86da1785560eb19d8fee95ea9766f3e71c0b87c4b20ecc1f8e572973cb560d5d3920b951670218f17694b82b30506aa73890abcc8b7300384bf6b258932d1f9205c1494e44d981b7922db02a1742397cd3d8f66379bca28a990a2f9e387fb25e16daebe96fed5a79e729851c9eec0ddb79f4b673b6a9f4ad2239a17ffb39897185b4c266d39778f7bfd4d4ca694d5c2c3b4fc2dad44465aea4297525e633446c6a57e5f781983ee1021776ae690926950c4d6095ab7620b78ebc894d4f8a1339f109a79956ea64caa05acfddfd52c5b2af1488ecdcb0b9982297219c97846e9c14f7c6b2d561059da05febffc313935ab09b6e3d3e6fa69bfd06cb36ca4add2df7e66cd8d5bcb0a6f1801d39b5eae9b1bb218558193518f763a38c698a702df231f8ead8bc9d6ac55cb495488b18386c6ae39b58433ab9114de31ff5d1f4b7a727aa9979e19c75de1cd68f2e01e3e4f3f3fcc104e5361fb654c0c2c0aae4c202f308f370da17e580750c075e1c2cbcaf86101a7eeb99380aca3a15c0465b9375b20b912bf46c4ce9dc691f34cb057d28f458be7b3b25956b8b0669d234d2497ed1122ec3cb84aca600a4111ddd0d13073647b901ffa5becb4a8e354435a900668c127176ca3d40301cfbef411a268e7218f7cf23e50af1e0e4e3a2b2c323d3a4312265cae7a124d426a09dfc6099eb50a25099703c7da69b261dea18cbb6455e2a6cb76d283ddaab5328afa244588b52ad98df7ae3200e1558b00b1cc95fe3fd5ea8b94ac8b1f98ddc17581c780394bd45db415e705914c22efecce660f107bdb2ddbe618168781ddd0142890026c3ce6f55278c0c5911d3e6f9a371e5332f3c5d8c707217a9529d742266b51f8cf069f3471b78feb66cd8cd56ad1e78a873e44ebacae533e0ebbdd7e118d785a67286133ca6023264953a19ad6a215bb961b7b1350058e43a35e6b22619893a16e45c8e0575ecc3cdc1aff031900e37c9b8fca8b1265fe15bddfdeaca365ace8cf540189f30de1ac62cf4688007a52a0ca3199eb76b6180ec718053d6cf00b116c20b9203de1ad8cec04d0b8dffd63b28aa32f945bf6703b0140272cf50939a40f93d342d2cf143c3c1d38d573d0599cf963fafafbe1672d7587ab6cd9b7ee641f038dd12cb9b93f94cf7541290d1ddb0258159ec7105697facfea65202212d3f4c6549731712c6186ddd32888562aae5a3aabc151fdb64ca73b84b9180b1a753e9da5ae2eec31adc1440d814ac76b75d0510f7251a633234d0801f812dfb00b73bf1608c6471e0a127edb5fd6cc403d0c30cccb13f2a7918a6428428e11f40c90b3bd7121d717a5032e5791c714fa966e258c99c8c529489ff5606aa729cbd7f865836680a8edcd0ff887766e65ebaf81f215009b466ca1295afd3626468d7bddff5af49e8840da54e7901691308b91e6619afbac60f621595c6c7ac3ec7ddb00343c1e4824653b9c6aab38b30c052236b0a39910517957c391bc801fbbd8505b9294fc0c9682c53537112b056537dbf7bf2e6d752d349a679f0a021585863183dc88d5f02faed84cfeeda1fcbbe2899e2cb38098b5d815d408bb03d3b8b5a6052841f0eac59b9914e783ad42ca8577caed35c3eb485be09b41c43d08fe53acc92b763a1fed1f8a453de2556860c3b521adf769252364068ed6b730789fa7a0a66fdc475a61e1a93c0b8046e4b6bd11aa54726faa50ad02f00936eea76063a81c2a22e2350dea6d6d595fa30916d7f1e80ab7fe82c21336cbc289e3c5e08a6c3f2e0d7426ab58e2b6b953040a60bd8376710b639f5408dcbcdd1ecdb3501a3564ff3beee3a5d7ba0a6758bca2dc81231e0233217306e6283071a93875903b49955ecead296480b233d18fd9e90dc1c06dc621c1e1e37c8f6d7bea717f5a48cebeec09a7cf974ad3eebdf259f9731ffcfc732855afe4217b9190d7473185ec11bcb2e56a42cf4d57932b7a5fbe4fe0900e4e1c0afd7ddd3886e4564d801d9bc023ac63181ee9f913a0c6e013c317474340e8fce98d6e10837a197e636f782fed760c1d21bcbc473f8a18e12243a15aa9bc69124080c97095f74544a121e55fcf38c4de25e97d7f9ac047f3927910d770dcf00d0df614e5d3aa0537dc4b695525805eb702025228c0cadd5f7bec55e0aa4b6b64d4ab14c6e41ed9771f07b6fa135764ab2585988bcee7ff00f6d4451ff7f4ea4578244f5a848d496cd4ee1dc9d14d4b6109be34551b7d781d92058c43b8f700ce53611df569fcc1f615479b6b31dac4a62899897dbd3d066095a32aefaea928bbd9ba5e367406dd8359b9ed0c1a8c15ace934c229b0e8f0281671b316184261549211124506650e851c03036b1ea8c858c428de10ae205115a1cee0a593d4e37ef14eef1582caf7a8a96c52291772ba28a51b5df6ed897527aa45ee514a6641fd3afeb29a390247d9ff9a3b79599ec9b38301b50ca505f8e5bc9db5a69397e36a663db6524bfe555e9ee726bffce6352a8877ee90a17ed44da4f4028892ddb5b9ac9073635a79c7a04a62ba8d3a196654e07ee37fecd2d94a4bcc10c81923b420d8bb30aa0cab28f384d2e4433214219d123c72474c1e8cf8203d9ae303a22a5d0c7c8a29cccd9e357e8711dce9d01628d59a5f1019a24c518c02865ae754996d5877c66ee5b9b8128314485706ce39a8a59f62198088ff674c9db5304feadefddc6a53ff5753855e1743124bae4215dc1df5786896e80330cd8205ba3921a1f7800b16049dd546ba937b7b1b06e0d92f4e496c2e5cfe16eb2de57032cdaa0c92840d04e98c5c58a05821d4d29b6370000bc76c7bc9a303d4aa336b6798b0dd11480d6916f8c164502c38a598bec0a4560a6b7ed4dd5fe37343951320dced3e2af9c44665ab358d9dd4466d9abc90e06b32119e3ef818a82536be931c2c1bee502b4ec8d0293c78c5e78707d370b2495f52c60149a5de65c05897e1db3aa52fae888a47bea337539644803957c5ecc7969473270fe7ca7022678b75e6447e7753b296166e8c0c0288aa5dcbae9718ef1003f5b850bc0e09af26ace3b98d6c94e5e6c3b31724f87091d8f9ff2d1892afdcf6f28f44b0a4fb1cb96e8f9671c840c20a00eabf249c1b2e4719f03d3ff9216616e617eee4eeea27dad466666b181fbd87a26a0b9acfb943b803a80ca30125506721cabfe288e8defa16688228a8e977273afbeb419d400ce206614c5052b257976b522809d31aad04771a44ef1235c3eb4022135ba7393fb944ee74f767f899b392605a93a7b2c1d6ed32ab85699afa22194e6c840b680acd09170a72357f7716cd9ea73dfe565a6146de9384834c24d60a176df7ff0e7b1fd2a2d7272a7bbb47936f108cf377e0c157eb8ae1a27278d613ae701dca901e1a567bbf152845744d0c5df4e370013e3dff3c91aa8d91088d25a3adff19d341e0423d33117bacd8ac2d3b7c5ec8576c8e6008227ca1bc9c645bfb190970d69b54b11993041dfefeaaba69ef6f988e71f4512502626b07201d364c84d56c90fc3f619a9b24b00f2d19eef175fb6c7c9db3703019e000c10c5ea0be93c3699fc5b94a283ba89e13f2b5a8afb2a3af5853d5070ffe843a1e9caabd8f2e3509da9316711ce0d398dcc19c3ad271ad5cc3475b5c11107f739ef604550391d957d662fe4a50e34726a73fbe47120a1e247b545e8def59e39976046985750e79abf9b4c5477cd508286e1011c309539850ba6c9520bc109b265b6302a0b170a0bc35f4f59ac0244cd82370abafd888d4ec14f56e502d53ef24c03f30793c010daaada864dc5aa204bd4a30b7b243ff1152533a945bc4836f89cf813e10fef31c07b5b7d0dacd43ccbea61880c8bc35c5f0b4f5e59630a8f1aeb822febd9320285119d72f15ffbaeb11a4324331e2ce0a9347af1e9101209f680e00fabaa0b4645a4e04ceab5e373e54acaff45d57717d929c69cc0c14fa55abbbe0312b563e829e464aaf3d6635ca1cd3b2d2de4a39e79efe3f55b847fd947c36a13447afd162213f1edc32e61caed08ba90a20b5e6da074b74a2621a0eb29e6541db16ab48534b772cad16738898bdfd3e842b890a6369c79b399f730a6507b4087d1c5eaffa76078fa59623b9aa813db321c290032deab6718561743f2eeb1853ed0315344a00ab4a423c8cecd8d146b1535ed25c0a9ac2d15cc31142e7ed4cb4151a6dee7a89c36cdc3dda901a771b5d23654f2fb767d2819d72d20c37795e493fbef4f9add9c6aaaf9103a6c179633a0c10d7b176b265ad039a53e0e4cc37057a2aec74f6061e2b3ec963f18aa9b0c74327c9c80a1afbf5cc133c2e890ade8ec574fe1001752d77b49e83ae1982e88f0516961b742e0d5044a4aa62db5eee43b47da06be9839efbb397d0bdd8a174e4ddd364e5a42d54b15dab354199c7058f06817686f30a907385fbb0ae55d72e44564ae994bf3d9782d1483d2180633772d4bc2d742488b5eaaa7fba0027c3460ad5b487be964988395d633cc33a7f3f94eeefb22db89413618f0502b875abe51a563b8950aefb3f57c4bd270ef316d762b7d7ab329e93a19a5dfd506ec63d200ae5a63d6e02d985611481c64ba2613238deddfe28f1eb0b2956934395b06c5a61c1bdfeb857736a3fefab01756d581a4cd30b136f763f6cdf2569456f4e04439f20fe90c1485031132a9552fcad82a3899445923a5edee0307867e96ec2e7541d3b5897b0de141b01703a312e0c2a543d9e50df7434fde4857117dd54a436845d57a7ead81f89e54ed113903277db3bdc2a233deda93ad255f118748b2ff4c9b8e190aeec224a0b0ec9c8e3aca01beca1f3435584fcb9dc421c808410f17601c3c4622cc40e481dcbedd3a18f464794159791bfd98168fcf5e7c9a2fe2a88cd955f853d0a690e4b53095c1b83fe1f72d918431b218f9f94f900bc624bf65f6e2a5180f95bc259802aabbf352c83a2a2cf586b3d4cd2a5282cbc2c96aa5f402954d7db7224c611a442429c39d33b0b6c4f57f077afb388b46d666d8a9290cddf9df890856b65c71ef967e03d316ba7301edeb98276a745b202e45e1eecc6ca12e68804626431a4de55328eae00dc317887a8d28a234beb74a7cd19650fd06da3ae4d006c0e850f09eec6d2d5549e46f0180a21e6ce0c8d997e327787723caf2e3e346b23a9d309f0f16e370ff47e43580429d0888ba247ea44a034f1a7a9588982170130c0c03edc250f928f669734fb7c1e90bebab943662ee26c2344357632e7aacd0cfa5d47c512edbdfb70cdd173aac1e70427c81f74970889e79110b91d80c3d6440f49bae8b98afa20a27ca8fefa46baa837ff42a94f952f15342798e8ff3f9fc773899dc29a00336144d71bf7854ba10142ee4060303af38e77a3e5d3b0832ee792228e2c707b03edb572382678c336979426834a5d1b55298f91296e9cdec3e6cefecd6c0f43d9308b54ab9c5719fc0d9062eca721844d4f6eb6fea7e959d720a06d48100c4620a3274615178b1b4a4d7b53d713f0139b51a02cb46c1488b587051cbcd70cad1674047382e9234828ff8b460d5e15e194498abe6e51143f6516eb11859e6c8e8e8dbee3c976ec28e408d81c9a5d390a75e5a5e2b06fbfee77d4d380ece5015ff9e0d4b9154d3160f627fe2bd847fd1298ec42eefb6d029e91cd7f2060f08270a56b6c04bcac807ea68e3537b2c4d0f1d4ae41d0370089554c840b586e59cadc9594dfe893119d0acaf1bfc1f65b83392ccdf8f1b847644c04b4d6ad7fd5d4ce17989dac28253b6e2f3232883f2d8ccc30581a68a5c21c1b10bb1c93a8936a55fbea790fb8aa7a1b8a5f31c1e39e040d2c5b457b67c3bf7e4870f4677f4a19c58fdd3a6c82da9929b4ad5484d34d8219db0c9a4cbf5a606232c40a137fb50e0c2c85488b1430c5b39f72674c12276e356a270cdfbec9fa705fa874653a611ed8e245c7ccf69f9d1454faa1c3dd1d6a94397de4c79d2f0902f3a5262a16274edffcc87b631b3948cd4cc2947542cae2104d86ac5f896115c782a00ee4a89177da304ea6ee50ba0aad21c80c5c34f787ca23e1003fba884d2625b3a4bee767a0f10b2747ca10dc81777d797312079718ec227476d6550449152b3daa840d252f6f5b10e82f25bc9c17ed61e1bce605eb46ce8758abe9f0dd3911b66b212f1390d0506d2c11857bab27525b5272a5a4b95a0357ae5f0d2c4a8350b2e8042d740519fbc09de395c010ee6b4e22755e694ad5df71b09b033b765aa3b22d527eecec48cfb47e39097770a09141e36e45d12736344e32ad630361134448d3b126e990337d485f2279f0fca461c0fad128f530fc15f8b923ce006407785fdfe2a06d5f4194e016d6f3c57cd5ac661ec10a9a6a8f7ed9f69272d136376b182fdf60abc24f497116f4d572a1b636f9eb7e026ef184484e35a07eab254173a83fbe147312c6106a646d9ece9d448e440045e1def6f90b74466721029b409240a849e98ae9646342e3ad809641e74ff6c92eab02023255043d1f0e0e67168acb766272c1506bc14e2164b4ca7101ca09d33b6c3361ce6c2592526bd50990ee93235853096f573040e6daa11fe543f02558e453fee17af8c669890778e7b2c887b3ca9af3f419347050bdd07088063703ba12c100239ed2e9d56c1ee7d00a832a0b5713e5c0f2f45fd227757aafdd15938fde3bc5b417880b7e49c89eeb35a46a68d94468f7249077eb55d1b9a39db78d86de774aed3e3e7b574e61363daffb5bbfcc7dbb1f049b3aa9e1949dd566bf9d31c9ebfecf8b1c2fd5a66253f62d554c874cddf04a4e879f30f0428b6b9990b36d68f1314dbf3d1070c1ea71745330e60fbeb19ce7f9583de72b7cbb76d79b00991072505162a4c4eb6d70444ca030b88416de653057f9f1c6e1df800e13ef3d456c6ce9eaf825faaad51d7031f2a06f51d23f475e89a6621ed9c2d6a9c38998ac10d1fe344e90a106e41843d1176883a62d35dd119102fc7428eb9baccfe4a786dc0364c5920501a97e176d7316969f876f6739c4cbfab26e1251cf021cb1dc48bfaebc7c2a1661e27221c05315d1f41220f8c2835dd4bcc4b78567bea10c8ba4090021bc650db5232ac295337e7d40d43896e5d733f5fd8d95117c707a8d5c662681f4f3bb9bfc143d06a2d248108fef9506536d4cd3980881ca12035c8604f2f32161027ce85c4f7507f0873e2e7ae53bef9467828504d4e3675b22909502c79bc87394d48cb7bb209d60dfa89234ebd8eb3772631f80f01c85790db234ef58808313f398ae307c6f045a3f1ebab74bc9d09339e7770b569e744937bc2763cc4d6636d3bc682573ef2b996d96fd699dc7cda1c7c6ee590c6366666636cca774c5156e6813420e5816906a7a41701fa0dca1419b42d543b2695d649ff95f67ba61807f370200635939b47dd3c23f4ce54b1e5c2e155e9496418e240f31c7b2462efbb7579e897432e4a1664e357374a246216ab4426f97827616306dff2c7153692b3a8f433e40dd47ac317836e98ab48158b0daf241273c5b1998eff9c2728ba6575a8de0d4e5506ed77fa35c0cb61e4f899c3888eb247b615ef28ad104820a97474f8d5b2c430c2560f68b9e27b8411fe0fb85496d3c5b508c7828d3c3a536412607372ee4ff630671c31047b250640e72ed825d012aacabc7950998774a54156f78dafe42781fb9a8ba666fb8c4ae8a4f6de0e43508321dbb0e0a243669528246c8cfe34f41c9e1f11295c46ed444e1825b8a076b0ef8376b6d321ae0bae95d83ee51f95336304fe008fd93f82b58b36cbd5f822dff0c78d63cf1eb2d40e9d4aa7f365aa688f6072bb28f2643fa25816012b3d328a1f24e638e4c016f43e31856744d88586d60ab2c6072f897fdc64f9f3bb1850bf400f4a378dc6bc46833dc661b1e586a0a869c826b54d5dfb1d7c2c9f2a21bdc44792ae0dbfd8ac8095f69b919d4f58060a2e88f988ab14871c0cd63f0efd42403d717cdac51f26443a69e1933386744ec296d79562831dddbcfa541b5726ce8eb1b64cf3ad9b35cce735e90ee36865fd75c97e4abe6aec350fd9e043835ab4b026857d392d8b09cb41d5a4cc9a35346f52abd1d989a9bb0d62829e6cc4ae43ad77095de51a73fdb46afae55203c86bc182cf1e1f22981e93851ee4e88e1b9a7ca2ca8d1faf6a9576bf6547b6e63d40f188b1c52c48ac51d7c215ba3fc77c5070790c41a409a2541979493c9320b851a44767df89a11912e661a85acc95f226283ae522b6ae63592fb868b6b74a622d80e80e96d4d9663eb78ed2a40b2d824a4acd9540db9a81c3831b0a06aaef679994d5f2e10c4d71264b7d41e3d9c67035789034f91c479d5410df09ac25deab0238987124a67770e26ce4a54e42352334fb10c9ccf3a7d0b00c34f3a2e75fcf1e00e52678fc3210c6228fb8e510a0318075a6c0082fa8b8ce72ed2a54fd8904734f199c77ec18d217a34d1a225c2e8c682a60599f0aa0af2649974306992da04e251559a4e7382f1fd3d8a4ac6370e46c20abaf6099d2d84016e9f2e7ad6b5cff332fbf7abeed81798cfefdf44f2cc700e6f62ccd5a2006922ff8461dd0d892630f3709aae03f3b36daa95e53b4b196ceb21ad33f81ef200c2e57b83664e44279bc9f4fdfeb5e6fc92f408298ebfc144551ef4304019ba7b583111f9c30ec66082de8bc081b90ac28d273857f285e61aa311ee13b676c4961a28d3f102b41be004d188ebbd6ff37feafa90bec272ceb2e1ec33a0099770c744416d9e5341c1ccfc1a588b6a8ed54fa65e78466ec6995df8db07a0d1e44a801adf1a85fb14b19d30befa0cd0bda14357ce81536c29445604f3775831e43504717de0ae52972832c8820d74611b1a2bf0ea6483dcad463f2d0adb56d6a45b6c4281e32c715e9709edbfa7089629dc2dcf70b4949632ef32dd77f1245a60c9c48b161fad4c855ede1c7ac0604324da651c362a776bde28fabcdbd30c5108855420f776d40b10c9d5dae25c1ba3889f8cdcd54dac626df8064bdf56e765519d82faf2bd9124f804a58b2fb0fec80bda3bc0ec798848dae2621a1339a1bc2802a628f5259cf00ac225f6ab086b6786278532562970502f380d49b3954da170581d96b3bd1f79d34afe3886eb49d9ff2287f1b5f94691089d46fa9587799e8718ee1789515ea918f42f8b11bbed6a10451ebda1d12be87cc40b3582971c9596df7827b1a32fd45f3d479967ddc34d3370f8e12b0c43f5e6d49a87b2596c20a6f47a4612bee31ac43da2f96ec073ac1da3bc56b731fd774d3f822008ed3969df670b48d7223108c3451d193ff1dfc9de0cb000642a8f188b5550118ea17c95b21f68507e705d6d125a078929fbccef65f63d16e3516e1cbc4e80aa894dd00c2afd388199ab9de1d1e7352d889c8b6d3a637453d0ed844ee3a01ba52fa16a147783217a2029cbe4680d14fa0b5ed0d8058073c18ae9851a603d9fd02b8912ccee92526e75f0c42d89309de25c7a3dcf6c3801de6550e908c58537a9e41864310661c61e94672375efcee09389dcdc5f66717c86c744ee8d50940f54c85f2fc9a8ee2824d22b362c507ca4e9b7dbaeb0c80864c58a0d3358310b769153eb580d47913127db0287d75c1e84dda7f1e8adb3c457e010231e23be631a2b806724ca20ed9581920fd857b32ecaeb0a1006774e1816b983bbb29cd0351c6d1373aa10e8923ae9fc94ed108a52fabc4b0c5f1544c59c2e0d4447e50e5db7d8d07024d204d597e0e7ff9a4fc7a9e5b64c171939c21005819fd344ed80529addbcd97083213b8783a0d35328a51954c085bd1fb7416e21e4ec2218a2423634bdcd969cf5a593beb36ce4cb7b0354c6c42d0e4a870332fb0a4b6da29f5fc4bb5ff2a6c355ba6825addfeb60bc0c287e97e6c951cb19be1371a419e5bac0b9bfc3f28690afc62aefd0e9f18b04dfad528291efee35fb8b4c66fb9bf954b9118f2ce1e1276385855ae0a2267e9f8e665b2c6cee23a5d7b4b9a7d82409c1b1cd2fb1af8f0ca03442e0761c8f4e3ea25e86a46174ee1ebbe84613534f50e4e1ad2b01645d9122082cf84d589198c717c228fff447c95be7b5e558a85e52a2e94c55eea20ead7fb64e565d32b50b7c110bf4b8505bc2f1e07d76b363472db05391359fb902cb97dc265c6cd52727704e6134297bcd346f58d4218dda55f9da213796d347867a569c5105a40ec6f7ccf046aee230a361082874e115264bc25a270cfde7a198052a3c24a6e8e4f40cdfa66e9cc0abc9410fe492b4cf60af66437d5897896d8e5592e86cfc651ba058f8c87d90d4cbf6270f1e46aeeb1c4a3e77847b169b27c339a87b91d66507156f3e87a6331ad5e4e22bc89e3b6416739dff4813680a8d0fd9bf9ff9b52191dd985754f271d4cd9f21becb512408d8531304d380c80da54ab02291326d27c6defc6aa9ed1cbdc51c05cce30238fe112e2f3cc326877d6aeb472b3bea01b9909edf4fc2c16a54d9bde746590652bc643185dc07f3f15347bb2acda8dfe1cae8b9c914d4a3c8e767840c7ffbf0381df9c55ede8ab9298aa18428d5feb46410f388b846ab63da3c946309471f5b0a982686a5988502d6e8f1dc74c08e7ff1bd320bb46e1780776109c2208eb1417dffb95a487597740497726180bbda7dbb831979ea8a51b44d70800022a8b4223fc942327e7c5754739388a7f76d4c397805dd72887c8738756ad7ee74939376a8d49d7cacf858bf0a08a5aa64ca0caf348114b309066c67a6868255465d31554efb2bc42748dd9e69484573a032d9a0c880a90e3e12ad2dcef8ad970d8b04e3eb8bd48e347a658a892c73dca1c9748488ad029173fb7d58b753ba7dc33005f4e8d3e5f3e9e442da81be733bebc9733b95d55ece240f71e891c79a64bb23a8647f0778a845858ff85ea61aa4a926cd5bbbb9d924e76017843c0e35186f0aeb8ae12098c4caf06b2a5331d83006b47d39f6bb84f5add049e7b46c744ead670ffd58a2ccf22a618671783c387bb810662f1957d4e079e2de68f1c421a6ee779019008a2e39814b144a6578d579e121819799201ae4679499b01213c686037a6c28c35d5a1b686f1a623c89191a19358ec71bef62f6a04c4fb52b9e1399aeca00d993a5677e3d460200cc2372ef0dfb911543e44165453f1f23f6b787dd77772c9734a80443aee6a300da711e271c9d70960df3ba5f5817321da3d434d6c1313365f709340946ebd6b458a061b6eb73eb91459b00ffdc300bcbca89a16068d22d3e910624543c395fa9b28416518f4acb060ecf8cda51427c5f15b8a63f1c0262cee1e8a7ed95d7264b5f43170ada9ef062fa6a3f3bbe428ac9b42bab5bb8c6fdff66310611422fb262f6c5e1c9bea9a2b3a45c6b1dd8ebaab36ccca1a99d75f82fe1d1bce7c1c283ccc3db84842ccaa34245d895d7f67fb379cfd6613226ee557a368cd37974f8eed68e8be29321ec737d5b524c1e73a25f64f1589679b2ad1318d6dd2d825d27e5abf1dfb89b8587bc288d5015315f5a54e28041e73749d522a92db017d75e1475979b91da947d821b21723f3db9295671fae647e0309611ebea3620bb31d7f0aebd4655df43ac39515daa521dc14f926a59a5177e338b6f2a38a4459581af11b73f58b9cb2e7b05797343ed813bab7d56b4576d41f3bde6e27f6b9ebcbad079f650b66dda0518f4b2c86db180d81e8b5eaac61da76509846def8b79d8b64b12a4e735c16af521cec3ad27b15cf44e82c46012ead88bf4485c5b60fa94110f14b54f12c21c3ad3e7114782a589e79025562d2ef3a5d33cdaf40ced8c094d900824663e18ae84263c07840536c220a17d5c43a6e85fd2cc1462bf1bc690f48c273bb01b4505a8da50464523e594c34734edd07e31e8f93163955c7ca056a1f223d174272c59725bf2a6ca33084abbb765355a19f9839c3d6d87f7ff2acc55a79552b52211d1acc5017429875516336307e3fa8fbbe2cee7a817f2c1aae411eeef09ac0a4ef27b4ffa4cf3a58ddf9037fe984af5d78ada657a779e3eb3ee20aa910e1ab38681b03e1ec76e7613af7ef9ba47350265158fb494687f2cc55bb6a2d67e0b53a334bf585243e13af5c2452c5e0d2eb6aea38cd91c4275ac567f8ac729d47c61335cdb6bbc4317e9679436e5bba709654e49d96763063ffc58282a4fe1883e4a7046913bd508344e2e4a2bf6f6b62f6ab44c099d8948988d3c214179389f9bf2d43a42c5ac20ebba0d56865a292f1ff3c93d178df2ad6b311021af1c2d871aeaf2ea40b1768c0ff3cab3da038b08a45e1019ff77699096470c044a48d727bcb7182193401574558fe58b61b56c7ba3585a3f4400c4720206ab3b0570e881637a0ecb05885458c5cfd7929e13ca5a14951b18982e92945e1579a6ae36884547c38e0ce353195ec03e374e07f65dbde85b2e8f174a0603a579e2132496c52466d1125b30e68afe2d96b546135cfedb8adf98e8e882f2d5245939ca446df3985394ef080dc324ab9eb061d30873734f572e922d3abb2faa370f4fa27d59b1362fe09a9494d1c1f015120e0219a610c8a582b160178c142eda3d49e2f3e44eda428ffdb546b7af3b13aae2e80822c3752c041a3932aa0bf2e94492939a6cf95961328a6450beae94aa1bf0b5effb754c98cc1cf492edca4859c5f4b26fea5cabc9692c8dab6308091691426542c378737db809e28da8cc34a699b75427a76e2f2e6493c1958a35fb75665b9efa57297b107468c987c12031b34fd6b47084b59f553e9833bd42c957faa1125fd1981e644fb2e738d30dad10c473949dcbfe1d3855c3f0a32a2268b990c7443ce0c3817ffe1d0df8c74428ef154f0f904af5799954bcf60d85137fccf076e31124610f80cfc1131cf42225945f469c878573509c0702920cbd0e1ee56ea69a7d490580e0aee677ef78eb05020282e97c7b2548856e825c67f0c35fb6185c23da3777acc48636401519f28c93c93b875e8c09ca28d092315189624c1deebe190746df0fe88082551b308c6303a3417ed682c9f1716b94adc72b80787f0697a4062e6f891b0701a7a1ea5e5bd66c9baeac354de33ac65e0d995e98d91fc98d79c350e29659dd93c7c1ffaa83c0dd5e70312da0137d228abc1f074fdc606caea84071a0d1cb0869d705137135746e68c05260471ee501b31bdb490e6cb7d6a170a87274cf30003d1262642c2372fde55b048486d2dcacaecf8cb280fcb530a3074bfba8b8e823ba41600428cf91605641879aa3d1622b5be95b98751166a27011f6debb0803dda2305dc5c3120986da95839ed014d2fbbbc92466991ab207ffea54f17231cb2fac40d9682c2e1df2f48417e11feb2679f20465b474202cba751a60afe8651da7f84d118e50b4d38f275aecdf2ef7fd89022e3968074dbd00d14e23ac3c533a82c1daeec2ad0a729c0ab65c5c0375c0234fa9d0cfe4b4a89c8e3e20cc522b18c73c56d62638b19cbc7f3a0b5d03b108fd1b912e0c5458b14f3cb6bc49cf6158a035a77cd38af323618f5c08311d77298ea4324f08266a6c561c0a0188136c4f47b16ea3603648432f45764eec0b090b0ba6fe03bdb057e1474e6cb369fa78a2ee484a13aa2bcb88452d7977b4fdca0d28829ed07f09d3177fba494240d11bf0433cbaded6ace02fd2d0e7303f0634a00ed92a6377e48b14a0483d560bb94ab55a4adaf5a34e2338483cb14440e9f8c9b172d52d59f31aee3f7b73f1f714048fe511e496c8550e06a700ade3b983a0b426d5cf4f6e29746893c8717946c88f5249005a271637ead003df1b2cd41f41b08dae54c00d2d4d8f42a3b100aed136485b260844d9927126265f7a1f05d301499df38d4a003d27a22e4ab0f382b559f66a87624ded8aa84e7e623730f26da39f20075f6231852f8f1004b1cc032395bfc362aa9c067209ff305ef02d2c6644579a9664781a903c2a45621d8ed70839ab84f3e9a952293fa5e82915dabf83f07de1ce2652e0b5506cfb20f1d0648ea33180f477c69e451a7b58856312409bea0f6e2274e65dae8420d8bdc060adceb745251edc9fa068ae23006276eb161b7098a5432fc9d81e81b0ca498b24820e5b53704462a4a655c0146540ca16009db6b9c5af9b52d23b05752d548596c60834878fe92e070fbb5daac7ada19a6564d4fcde160b013f20ab5786d29ccb5d05ec4d1a10368c2ca362b935d5b2aeb19ca10120f34403efbf78b6f425070ecfe16ddbb993dcb5519adc999da7da9a7e3dde8c2cb9dea2fe843377c538dac473e6c06f812ec5314376ce44fd69b872ce849ae27273c392a5965a03674da7580a229b73263d4b7f48bbff652cbb78b6e69cf9e0ccc71363af5a23a084c6effd28e59ed35dd98ecca00e2c3f866a7a692665d3f89899d95e8ec7657a7955f4498dc06e62a4687655cd99c119b468e804b0307ac311e44aa3b007e680098e1f1f24d4c8dd9fafb3676a45212d7986a5e2cd3310c09ec7daaccac3590c8a3677ce9c10e20801d47294dc0d74da03b6fc0bf6bc22e6cf576d1ce6d25c9cff9c2369dcbc99732c72dfbeb7fe361fbfe4b2c4a11f8fc51ff74f4e4cb51c428c0133020a005bc4e94807c27f921a0c8e82b8154fb2df29c56aa6ced8abfa6439b8d02d55d3fb5b4f381eba5f3f536573c7060849301f96ab71dd6cb24f59ee5103ecb2c426803595d3ede6979f9161a9d7c2aee61463857b7f79da891926eda4b73b87d794c9c6be9f449ff19141cf65b29d4e93b39c77cd4358dbc4cf6b4d517cc52b61382f91ab660195aa7a87a4a28926b3237ac437c7b9502c91e17bcde2a847e4d19b0a63f603da66dbd57ac7c11c74ae130db409f89e336cc4d86bfcb63bb3f062b255c54cd7d6356656dbb3c77997c32b36b126343eebcf0ebe2762ddcbfa9ed03166a55144d630970207dbacdc3d072172b9feac02046e8ee44ad24d3caccd7fe2491cf998c16061c78819e45952a040e1d1a17e56e8661cdd292a7b6ca1c27a475d1e0850512388f29063d46ac41f2347ad28ca1f4129104685b2703c07dbe18553a8225655971bf1fa2185b414fd12ab568ea40af9831639ac47532a31c62e9f2c967eeb4290c44de9ceb868fac83a15e4b8e5125163c4bcf6fb7ef57554d65dac7da1c15a03a4a981c476086c201919aadb3931f35609cafd067ca20fbf98879713a0c87fcb299d710060c274cd3da7f0a4f16611cfd6873c429e504474b25c65cee202c2779de260b7c42d202609125f4a9b6ffff35b97f2c3c21fc08ad1523dbdf64bbf65a937ae8729371c039b59a97c0ece0c438c2efecfcfaa941f96e0802a464ab1f4fa931d03ce0c07040e0c03f33da93132116f6ecc5dfb9fdf9a94272ce8802a9414324f47e6c14617fea724e5cad009c310fa03073f5e46c3d218a9c7cd5f5c94adf2d12f26023c70f70131e2c2be3e2a3b8f73a62123ff1f9871f9e7be742747d5f8825d5c29868c6a5745ba28a55d7aba30fe2caab02f4ab7638107e4cd629aca00a87abe0b5b81a86ee00b7f5d577a38b2581b1ef34ab46c47e3c62a4fef2cc02977549bb691b55619ea0d80c6ec46814a159aae992d400ad34ca3f5d719ce9b97f61a0186be9ac02700494bf4e0acb11ab2cb4d833b76060475e49600c3a30df85d221107f8c3ab0e485e02f41907a1be6cc627e90974060c54c7928dc3b5b07c040823864549c52d100acd95263c0f78405389802256be0f66d36d0a78a608d909b4236a5f59ff1382fbd2b7fd5c5bb6d1586dd9399ec46b415f6330b2bd9b83c2ee55dc045759223f394a1974dcca9bf72ce36ab44f7f0671f894c47b836c4819b6fc47916d9d20de9a727d8342682d80d22e2ec2ef56afef612ccd31eaff59cb6c451c5c2985c50e836b65d1e22e05513bcf83be4f9d9cb44fa54859d38007174068f305513f2e00d43cab5abfb108c16e39c41f6cd19d2ac91970867433db8e17be369ee72671a052ae556f8466aae55ae132d5b939b7c2848a6c884fc50cba5ff01a7e942355f825d8340bf000b202c2be17de0cf0bebac8b3f6dedd69c0640a7a8118a823210440739526302cb9c47706f50dce50934dcf4e5cff93c5e8b9043c6d9d9c18ee15e8431b4f12753f2557882fa29fb4e80d72d8db86877e4e17bb135f62fbb3fcf9539b0307ba32d1fdb14d561a464dde926e626261c9c63608303157b68143136213dbb413fb2d347e396f2f048c2be045b059c60dbb255171dce29e764bf8e961d12c4efd4d83365eeee69ca83635d7bdf185ca86af01fe972df4ee0ebf7fe2c84a98cd2d52994131ffbd34b39d8e5beb60312312743946e10dbfbd44c0aec1412fe265fd0a65743c52366c4989bdde2dba576777ce939bd132a6128cba211076a45c070b5f918942b7d5e0b9cfec2695eb6f8ef4cb36f98ffc4faef6a661a64787d9a9f2299d0f4003d375a29d527259a539292337adf7e389415ba9f73135e8416c589ce0477dd9bc5bfa92d3808fb5bcef1284ee3082c53efd4b3bfd2feeb99817637b8857f14a80dab7840ed30ab4584c087887806940d1e3d8e86201e9e97112cc9c7c110ccfda590bd825742733f437b9888f068a70fc23efbdb950930ab81f9992c341c47b73638827e0ee4cece8e3a1ad1a63414e0e854143102ea69dfd75ca1741496ef2bc9408541e1ad6f6e58b93217a3ca8541dbf4585e282b4b277e7154b9b805c43b33bee0468a650914f324feffca65063107d770b5f3e87fc931550b2918af665cc91d180b2f51910b969b2ac50562c16996c9fa0a160c22a19ad734759747afe6cce98b9ce9807b07601fd8fb05c51f4c55f46f2fc31bff122e712e51f4d5e25cf58b52d07e6a9e51cf1c1c28803d4a330bbc883a08d3840fbedbad55a1f0e4a89c25f42cdc8cf3a4a862eda5c0cdea2ba741e00c31f218c94231c64d475ff24038b85a09dbab0692342cb30685a5618a3eb5fa322e613b896aa3b90c9a57ac0ed2adcf4ac64a71132223222e5904a8cb391f1e1f297da3287cc276a054a4fa0cb2e24a1166f2be2ead1d03a55b84e49dd283c387f91c0528166dacc5231263173c48c6ddadc01f0e8aaa79dd00a2ac9c05ba432c2057ca72b9d51fda11038fbaf546d558ef17465bd32fa4dc1484e63006ae48b113c60c6a5f0a440af934349506a7b57e6c002493214713ef762b9b0c4dbe15f63115aaef3af893abb55591063996f41fce58167b74a303b0d5df7780d12d558ddd0ea7696b8bcb509b78e1bd8fa9302a5ba3943fa28d9ed46234e8c621174829e22c835e3fd34515e5e55d2b65a4075235543d58028c4c74a64f28491cb38ee45617fee85984c42776829f537c0be85b234974f6a3e8e7d613c0015b817eabf2ba2fdb93262bcd16f443c0ede0078550b362e849f31c4d7a3fe6420b6182177634c1dd57f3aa998a01651bfe33b0b81fc7a18c48515870c1a1ae88b4158b41b5244f89dd9b5159237a8123be905a36e8b40e5a1705ce35fb74df9f8919e1132b2fcef2458f05171082a0327818affad2fa20d0bce082b0305728a008c03a5990a1ba9b6bcea0792889c1d62c2890f4042330bc71a81c19be930b9faae1356287928f2351867c811ec40c82fcfe44ab8e5f94901edab3889cdeea6c9aeecfd5506af9e849d2f79cc765952fd6cbe79d9588ae3bb33b1ad6df653e0e9086d6a3dcb84fb6f2dc9a8637996684518f43e2672995b6424c0936a95b3e3dde2669353de7a2d140923018a452efc8e2f4c1fb4b6bfbea0150c701788c07600cc1442f73586dda14054a97bc2fa5b881d9014d8aa4971fa487da281e617020c0b68d4e2c48bb381965b63c5e0a695d5c58d0671cc496e430c787104e6fba2fe6f29d34f3b1fde236579f52ff44ce57f7149d8bdb7ed3f7870428ada5055c921dbb3b466adb907ec6a1b6a990aab0d7ac04e6e6ce6df49eabdaf7ca43b7b1913ca94e8dd1b9401205aa90c4b36822b391329320c9539478c1e071d77e8d011071c3becd8a10e1c39e668393038d7adef08be63c71d39748443c71d3be8808372e0d6a1fc3bccf22a388987f307072ede4a5f8e4df8e2cf5ee527baad4a855f9b59b98f7a82d4cf1756ae2955f16756096d056c75e1f012c1cb93e7d6e271044171d4e2a96d09c04545d23084a3152c267480532930ccaeac78766da09b0aa9159733ed4c092e7bc4e6c2054a1d9f2aca981eee39afa134596875af74774bb8d4ce720b594e5a73d6ac07eeca4a08adcd9a61915b49bb949519663cf0165b85b26ad61963ccd6d451d69d31cb8cbbb1325a2bb366bae456d22e656586190fbcc556a1ac9a75c618b33575947567cc32e36eac8cd6caac992eb95525a83c1a7048b33a1bcc50f975c53ea2710484f4fac26b5b69d5943d2a3f105ecc467fb9e913c3669e39254a7be09664257a951e954720ca3c00de277ae9b976411645e567df59ff5acd045eda356aacd8969bedb64b6c9a756dc5b4ee968bb56cd1ac552bd6fa719451d959f12542f0dae8d7a73b4ae59b87b22701e66a075f90242c2ec653ae791a9d224235fa72ca738273ee7261339b12c2afd6d63092bc9806aee44e00356d86b3772f6569b2e05219310f0872115a38928b10d4dae0e17ef053494dc4c5886c94901ec8213a50ba90a0b39afb1aca722edb1c801b9daa513fce47ab708f90c2aed1380f51b362a19c408cef9e9874b45376036ec1a2f11288c07ebde8948b57a4d2de8c5c019e18db290e1cd28e50123eb0fc2364b962b8745071da645ccc002b69a070c48e080d49601f1cefeff5fac933fcef1073cbb7b33b9a77ed0a83d1eaa8b6316622d4bde0cb1f03153adb0b1f4cf6cfc55d3e9c019112e55b38ac7e79ad21a95f930bcb651c0bbb24528c474aeb49eb00b2ec22fa981d676968a07b14c55cb54728d31e6d130142b838df9ffe0773354ea5816e40c96f5bddb6d0eacab6daa465ec3e911d378ef8d33a746ba2439badbf72dc0dfd020e980ef23496df2a0345b899921f73fe8cd7604be6751d89ece9a2f97bc57929c985633c7c3203f1b5fa81a056f8b952d0cfa80fb73c93a50e626335b61c70c40fc813ac5c1b1b8e68552e05e2e974b36c32add18447b2d2e177b1d14f05f3ed31042e8eb8dd186027b4ac3e2e4edf0d7bb2b2b84f45a5b51d9d1b0f0511bdecb33a88fca40ccf9bd601d2772319555e43858ae9794786a41c85f1ace26db60e4a73da45eca6d70ec50188855603818ee005100c3cef92308b8db5b70f11eb1e0f0ca0dc758992a783c8119affe8b87871040649c5902be2e2e4c860ff47b3f0e1e63bd38d9c40720139bcde1ded593f2bff48333edd8895abc437d7825be87b1976c0d15a813d4f22055293035db3e895038c1c31e143361404714eb59e27aa7813d3d2085f61e18c174c2260689f317ab3d912e5f0dda6e9bbd8985d3401a4059e4e5ba0f496c36008773ef3e4d3e2d298947882372b6b5cba7ee2a2709ee1b1a3672fb4a5a1bb124d4240fc64afbaaca3f0365acc1f8b03ffb723ddf4431bf3e7430b97092c2f7dc31876c101f114c3abc90f4d2f6252ce98149ecc5ed8acd140defa71dd636ca1455be13cb5e9cababc4def79878e231e33ff1d7fa33cdf18befab12f3191839a49dc568e4f3883ebf7b90d9b0b1d63a8b95c5b5b20afb6fa3b0cec9e160773cad9030412343bfb00b5ef33206a03e5d03b661e7ed88613431b2040eed0aefc126997e7336ee124fcdc86cd858e31d45caeadd590575bfd5d0b764fcb8839e56c0c02099a9dcdc16e83f6c40b35061946a6290149643b4578388b4ecfcba63701696bd947ea762ee6861bde1a765ad8f5272463887f756cb8b3e67dd97a5715df29a0e0c5d339a223f3d9d26af0b3b6bdfc5cf5be095eba5a84dd27928140ca026cfdb1065040138038fcc890b0cfb159dff8d76385cef2e880b7091d06da2810da3b9d68e30f4be18b8deb236b5d16918c458422d83c68bd878e9410a2fe3a4a76ca4709e7c62febdd8608748864c5e6a8c87f49e25193061881e7701527d99d4083633f1749b4a6d86baa84ce8bb79a48577b58b8f866b283c566230a3840b26a7150ace4181b8320e06c07bfc1b181cc8439aa33ab0cb9a890238d60a96bab9e0a1d157a152a09f17e4ea331a96ed1e031046450025809b16a26ec3c780a4eb9485aee49549e7a9d2bc505cd06de08b3dd0ee7d9a474bbead9791b69b68b64d0a23dde3b17d9a16bacf56ba96d857b561310c53ac43dae331958f2b2476ba0e0428ce6f3417c19b8258a512175b58fe9c75f79909bbd4ecbf0033479461f63dd19fe943dc395a0d6e5ca99c2b98f5ce3ce4f9f3a60da3ac0696bc84f04634c159501c5515f4eb2b7ec8b0e3091a739a0b8259673959de6cced29d11c561575e34588dba84c7a76665f90decdbc1f9d8d841705ff4a688e0d231ad4ecd6a1e8466744b1b4240a1c2f1fc4cb86e19a0ee2943d448a0a297ea7b27a9e96da16edb608246a4d5d3c1fc8a7a5349aa46163423eb0e15fa8554454d60846a3cf767a340fcd2f0b35b456c44282894150461685fea1cef0ea0f316fdadb6373b7e882e835b7025a236544b84e753d6a8c1abf1a60940dbf970be16f8cf7b5a67139d8adec08bf3dc1d4afdcce654b21a3ddc8fc4a9741cf9c29322507b176991554ef53a71ba7c6068f1acad74da87a6a47856174631ed7e5a20bb122055ba38eaf43fd69856bbe98d2fba8cb8cf45e649a08c3f767101cc014c46aceb07561c4c04a67a4017995aba4c3790325af2b52cddb4fd990aed8464981ccbe9c4483ffc9f121c579047ae82c9282ab67f83394ca0b2b013c5d010af4dc355770ce61750acc7240ae50e5c6eed0e64552951712ddec19e28f9907ee30612477136af386f61118d7dfb570de7c4c681f1a17cbcbe442e5640ae7627934cce10ecae6a60ee50db66f3adb8ae077af16e826774a726fff1d310353034603bbd91abffc38f9013491ad3faddd27ebb42e0a815ab25104e6c8c69b1841e3436badaf84d45b4a84c494f20daea8dca3b05a62389b43522d3ea7e8c72edbeceeee454bf596369d4f280845d13751c939e77c216eb5eb2cdcbae49c732e06d55b3a241a8fc8f7504cfeeb160114632a525e623a322358a5206f51e99218d7dbbfd8b1ddb54dab893df7fe5ddbb45a4b654282836539f671ec9680792cbb1a42d13ccf6ac2076868beef8e919022393c2e4f366b46f1e60d14026e7c26b97d77f7a757bda5c121d108e2e9f84074adebb60994b4ee09aead75dbaf623173aa4ac22c2feb68df5f4d0a526fa9101152fe208959b2b4c64d388e3c5e3d40215b8df242415b3846476f06a7d06050573713ac8cdad0ca2006f3ffbf4b918434501865e6bddb3e0b93c403bb9510dd21c32b47a7a9882964f4a5e4a4fa78d7366def7ffd9b2ddf61fcd4bebfceffff1fa0cd9cdb2521c396bd01f5c13313beaa6214a198f8ca5131817ccfeeee6e347c71eebcb603b1a123693161a59c734671aab7f409fd0f28d1dc1bfc0f29c3e4c7bc20cbf250396041e15ddbb4bd8bf07b767777a42c249c7b4fe7eebe33a1213a24472867e3c50b628e0b0a510dbe6727e672391c77777777f7202e45a2f1c4b907714076e7f9406f79efd96b3877770722aab7d4a839001db5f6271c9c3bace52ac6d58f7a25963688745f6cd88d301d399ad1e5ee633f50398ee4cca880445afa1191437d91c15ddbb4bd995eb6e9459a59bbd62517311185a42a2c9f2a1f8f9755c60739b2e433f4734b5c9beb2ae97a9a58aca666347d718506a31f2490e5a91f8447166fd9658097845112381fedd004dd4d582da26b83dd12d7e6ba0e5cd15a6b2049f5962a974de7f30408d42b70cf2f7067edc0427304deb54ddbfb573282918f530b41bc1c434b30a6b2dcfcfeffffcc1d1edc7fd631710861884168bdce05efdaa6edbdc232a237e3e07b76b5c5dddddddd3d884b959ac4e02f75bab2345592daad2e40b28ebc5ddbb49deeffbc5c89b95c4e664d9734904b66d48b5fce90231f4515d8e8124b2fbb62964400843a939503ab36b304cd8a22b49195861d58402c79027ee1220691e97892e1f3b58b8699392504b24d5b62ef481ccdf07bee6469ebdaa22accc2ad8fdd1a6e11b78c5bc72de456d24ddc8133eeee24c434ce4ee3c01a27d6383425232e30d6955b3ac4c6c7552583a9b5d33484daf9704319c673e7fdb825aecd759943ddcb4fadb5f6edd45b0ac734451e10bea09c73ce334cf5964a5165759dcc889dd0ec5ae5114f1844e697ecc17a1159660c3073d0d3c00a9c94183c3830ef4e366ab1b5c23291c31eafdfb3bbbb3ff5732765815dd05299624083d05411244c4d5490cce869986293dfffffff6f2cc5b890915b41d972c29b8246997fe55aa429168b3cc5a0a25091a88854646a560928eb55aa9135dbd1b0f1003272411f71244e73ec4312791ec1c4258466bc51878ff7eceeee4c285e9c7bf03dbbbbbbd18c13e7ce33519fef7a4bdb15b7c4b5b9ee9531c32c1c81abec98e80549015271e532637be0947307823005757757712084ef7d72090af311c3062a2689e297fdff3fb9ded20c9c7573ce43e0213bdffb493e7c21592e930b38764ca86b6b63e085e6d18326b2851d764b5c9beb12d9620f98bec1f596b659a78265310192e20aa9eae7ad1a3e65bc8899c96514a2ac788ebef0aa6924516e4c315b286dc9744f392ec664f411926819ffabbef5c4c9b80e69261ed30a0cd06ddf3f5725d55baa5c660e554dd7b9e00c9390fd40babbf3dc6cb5536f291ceb132b1aad81447cc35313fefff7b9998318d0dcfef37c81102dc6863a44468071d9d440aeb04a61ec040f32c566e728c4696cd8d5530ca291330386870ab6e20945e5e55f07f724393c1e8ec35ff332a5ab088bd34d915a109d56bf3361c38eac6b6bc788ebbfecdf2d716d25399bb43d77f7a41a1a9c3b2cab81758ddc32153b7ef944249d6822a1313d323306486fa6f4815f1519083da22dd39d791585553c4392a8de5263e6903cd60280ea322cd3911bea04800a0bf2518304588f1d3771115186020d4ec0e44a70d960690153ae40116080686c5ac134d9fc40be2c19309bd1110ad205f463e1844b8b1b0818f05a19723c423da990fd789249326aad354b53bda5ce27d4034b34e701f8aeed0666d2bdf5e9a6640a366af6fbffefad37c6a06cd8cd1ab6407ae4e55cf9cdb8d0ca11c118cd84181ab934c1a69c463f6c58cb2b513d97ee3f7548f4dd5f49885c386106754b9cedf45a1ea9c771a8b523f366b311ddc731eb04a3f9822175aa01cf02459c197ebb756678d7366d6fd7efd95b9d5b92ea2d55b61d5a96bb16c248840550aa0b860dd205fe2970fe42585860435081e637b10e25730f28c011fc6cd7a312523e7777f7b8c697c117ad91c5c1f596b62f3976b76b9bb61d8ed16affff4f51aab774d9747e90f2f4921b37d3188b6ac75a66c2ac20502df4cceccc3499c68c18728c6e896b735d1d31b3fcffbf2a12a45e51ad183b6ac4dc58a135c3bc514fa6920afc98a4bcb4442075df33d5e399a6ac66b4d65af7bcde13f49ea1f710bdc7e83d47ef417a4f32c984738f73ebeefe434abda554595d1d7e88ed3a54c15fc10a6cddf663fdcb56eb0bf4c05ddbb4bd31ac00b0ccf994002061c7468526a08f538c98b8c5c56d75feff0fa2516f699127731014e4debc0ea9e248584700f4065207e44a41e8e05ddbb4bde1155c7777e5abded2e0507fa0246a1d858348486444c72b16d1b2820aa8a753cc8a698d94a8962bbbb6697bc7231d4c0c77aa663a1440129dd24e13834ec693526f29555617089e18887717ab42761d08817db4708a95814b24b0495334e9da7819feb9b2a45c87a477fb1e4e617f20dd3cd98e3094268aac64ec70295dd860b1462c60a5bb3b8f8010402eaa601848979ca1e342e28576f4d3f56c555fee9085d46dfea924274bc6ffff1ed3d38e16ce3de21bbbdefbff07aecc2fa432e92b6c967da0146559d98b09d22763cf2f6719e6d3028d4c0c7725aa9bb66b9b5693edfd2b091203014530203a3e2b462ec213575f31173cd08d207aabb0686c5878666830069deeeeb323142b091316954284104aa68965450015cdf32034eeee4094989669c8e9be6bdf1febc50a6ea74eb3ac36dca25f1a172e71906a5e1362553f532b869e47096a6473584efcff2fd930e2fe338fe5a9649885d906a7d74bc3221ca524c1403183a973f4a29725fbffb96877241ca872ea0f1ff9c99261bd8481129f2d0f832e25a70b9c17e371a5015de6b480493acbd199cbe55ed4232e352221750c03ba25aecd75571ebc382ebe50311383d34c8704616c0af0a0e9d803babb2fed1071eebed4a38cdbf7d7f9ff7fb9ded256657bff40adb536a2516f6991274808841191bb3bef3dbbbb7b8ee77a4b5bf6cbab60a092fb3c1c5945474bae1b37b61e05ebdc1ded162c2a63d3966dd7a089caa45c6f01adbb7b902cf596767d0822b683e30c7e84e4eb5d5b12a77b5cdfa3891584172873f88efc766dd3f6ce3f150709a2a88c651485081d9c98c705ef02f72fc40264bde00b3c7ce01da11a3122d6236b66246548887ae755ed150b295750e7b925aecd7575bcff7f9f32c33107e36628e377241bf13462e7844c0ac2c5b8c2ed8861924437a42899c2ffff41f70e46a83becb2cb215459c3eeb8c6cc96505fce395329d55bba6c3a9fd00da8a239126954acec11ab2073a28627a6451126299e8f4ccc8acc8e64d218f62ca2a43453d48f180e50345b9ed25b2533072be5762e38c32939e79c6984d45b4a84c494a2cada40d38562b66b9bb6b78f75e69fce9945a2e085988ddde9ce5b89ab556ec5d7dbb54ddb7b85317410b582cc9325684515c49a31a26cd95d31c3da646d7a01bbb65d5e6979b1c97b4871746df091c8c26e896b737d85b58e987a4b77704c53f413238fbb5e79afd65ab740546fa9f1884c9eb4a074770756d07ece39db20a9b794294595d505828dd8575044f8ffaf9273ce5f39f596bec121d178f4f08564c36e9e96d4647c75199e81f550656042dac84e988830861eeba64caf67be20d9a35733f6a3455cabd81234bbb6697b8f2d6742d7bfde0ebe829bc54ce8738189e853b3719622f524d51d0a115b2a502d18797e85d602ebad0fa452503174f0f8111183215b412648cc1fb690d1e77f001b2e7d252f7cceaba98feeeebe96242aa6ded21ddc012cceee6e8d3578f0d414ba2619a880089d1c3b7ec2c246a4d0a79b212c95f79edddd1deb897307aaaf6b6389818ac26f23e9aea991109adc340d64793430674eef6c802e6bccffbf12972a091571ff4a9c056a9bb36fd7366d6f1a361e324052d21328b97b81ba7e5804edc080250cd103244aa80495a36a840a6631035385d09d64ace4ae6351d82e8851c70fa8488015b7c4b5b9ee53f0c52d716d6ed4f94e09470c39edfc8f58002f5b6eba444cc6bbb6697b67e07b76777727a025cebdc689c84aa70ed912aa3ac4a54ba1e7cf4ce5bde02a0b6c05a99899a13fc2c8604442a849e83e29022c5feecacbab97e37d6c6624651b881cddf3d1901808804a1e42b2b0cc6617785cbf614909b7bef7ecad9635b5866bd820789221634a450c142c1b303f6a52b462ffff19dec761e2d803b61d8ca2be357d6a0d7b5390f2a8342d9e46c5009d00331a041c41c3401cca12b9a6031480070d8890bc7888d02c1286c6c180480c0086024100180c0602018140202c8a817096ca62b805e646dbf3bd2e64f64fe4f004eb23ff0e699e3247d24b954b5088a40ecaa685d8258c2a3eb4ecfe165df5168aaf83b3641af522ff11f7da40c0a2cca02c46d2efcdcc6a1175a1daa9d70e2a750166303407f0b645b3fc83a82b1e4899184fb508d9357cefb368f6496662150a6f7e785018b411225e0e15f5890e2d8d344d1149d7f438da024305fadde9c440f6f31737f3568755bb2fe44eb98682b9ed86ba66f98ab4db8a862750ed262b4417862278d552ef5a1ee7874ac9ff53c3143d4951a8845e4981874b338fdb6644167f70da9070c9695afbc2886b3fb9fd8c545bb6e2da3c96ac914c53d3127a343d6fafc05c2dd69c4ce918a410957a367bd3c9241d7c1218cba1ccb4637b47115544336634360960ff0568b26be93a44a1a2d9f59b24d4d66695674084fdbd875a244b6e018a06c2095e2dd4ab8dc170c6fe37ba6bdbdbc1e8b152458909ab6d0d8a7ecbca1261aef5c8f04b1c3068a2b35b45a74db7b089e3dd78d2b48c6259262ccc5d1dad46da316394643eedd95a6410cd1e4fcd54fca74e1f6da5b8bb3250970d8d5cf4a4a195d4643556a2188b7bfd5559311193eef6871797c02bc2de8bc8834292b0731e924411129b9ca537a6ceae2e270dec2c56a22b96e463f562dd90156539a401cfda7ebb33e130c2b32ef4653f2413e0940f5b53b2c237b31677e5fd1a5ba367da9a8f52f3ba211cd0a86acd14aa4534574928ada454c5c91726a7a4cca5c9e68a194a25bdd2e1ff64f5ce58c21b4eaffe332f7dd0630929ead5abf96f88b98f4712bb4d25861070fa396f6c3f228aa769d1bef21e9e5f3ddee813d442ae61f6e8103da1331e1fa9e78d1736369bc1bb1251fb2176cbdf28b32e55ade7e471266c81a4dd06282c44d1aff58c1627dfb68302d90a51f44d311893b313a8307cd6fb1475788acc3457c7b4fd399f0880683d5c650b11cd9d249aff68132935cc4ed966f320996adad48ae4546194780947df9a4e180080b6741118468028346c2867ff5c8cb30a14e029c09e75d282ea573c268928293a1f81872649162790292cfc5167a458b89fc6f0fd6686b2a058e8390076939b60b212624324df61daca31cfee89ab31cb4570f2e01b2296c28f8a721385c653b853610477395dfa84c8bd4a47210579b988cb39a3a2c755a18cc1bd73f346275a053857a265e82b441021e8be4a6224d4d03359ca241f3d7c14887a47646ca2c411139ff02fd8d3318ad02125e321b6237dee5811d423c8a9a8510786e2f6c731a10a01da3d9a5796898a7ca49222908098242196da2adf276c85713d91c840af479be33dd44a5eb0e00c6ea0f66ace750ee1db88d1ed6f050d177a8d4d6c6088a44ce2b2a490949a94b4b2a527de01514f2f3a3301a46b8f2609de770961ca6bc649fd8aa25cdac6883f60893904bfeddb91fe918bdfef655f3c8e517069c457ef5e66a650f89c7757ddf4bd252eb8bdd1c0613bdade3b21caf239f0030c93d7aa99a04305b4a17589908f2b2fac28b7981b3ae9e762258d3f881e1aec599b58884cf5cc63bdb190a6736247b98d5cb9fcd2610614e180a3298dde507fbebd8deb27dc403ec12cd41cf3fd70695f9192f71dfbf654235c6e90353490315fd6c832bde9802d0853ba985356e9db8af0566a27858c95138b2db3035d7c7a3a75dba3b647d4c995ce53d2c5b4d91dc8ada94cac2660ae2d76e22ba90317ed99b94c64fd6e32287beb800bfca12f1d2a2218ad7d1db5ca5d3b15a28269a39f7cad6b19a4b66f7e239af7f89607a8a796e0afd971daf7767d82898e207218b3bc828092d7b227d770933e0ce683636435391513bab68dad1389cd709cfd3c40e78d02454f3c51050c97d335cb8a9278364abbbcaba81e076ad8261218b934eccc8c43dff240fab4aabaa8d5c6efdba7c461f7be65bb39cdccadab8549a5b52571d0cb81fd05257f52bc54670ca95a3f890155712e5ed711a3a30a6ddb7ff721dc7d60c33917ccde9916c22a0b4b04d0af2cf4d33c4e6e10b9e3dce44cc35e553ab56df458700e79afb0220d95858da2acac25d9fec14943b4a5a1fff0bfb26a4dd03fd1d0b18b36fe593955a56e6c0b044fb29e7ae1b62415fe0edb3738f03ddadf16285f195300a2f2ee76deb793c71105df2539ba939f5340d31ede2c94a4d025862142884f01f8b598b61adddd5408ab29283531086f384921340b5dd1eb61b37b68394340723ded2dae6516f96f14f7a417ab1907ef8f3d8d002807e59119c18490349de164614cf2a4d018c482df8a54fadff007d1eb27bd59e53fb0f0af55089995afded158869ab33264e0d9ec7bf7a2abfb5b2d0686615895ea0b03f339048da25177b97eb715f87d1b76e542097067eb609b821735cd01863e577b6046e6f6ab46eeb5e81bd192f6d9586dbe510289c53f0e68887b0360b42f22b057fc969c9d4526900a413ef5d1d03f08bfb46d36078b080c9db4de95ca92f557d53820708327b4cadc8b2892f67e0abd2f158e8c14f38877a6bc6b9c4f3276af85a56859bc1a55a67fd2bec14f8b438d341d5082006a530ba240c0df3f9c5422ddddca3933d61c22138dde9184ceb36a9cbf6fb9b5fef5e3ad28aea8c716ac000560b91113db931cc3057892624067762b3a6a9b0941a5a9c4c7ef8dc2f56ac24df912b4161ccd44b5ed0e896a88f89219c826ce8f87bde318ea29d098ca286bce340d0a3ea2b03a4dc786543814d0d7e91bbd61729a3651746d1fa26c0c61c4f34605d342b5c3ac9f66ac3c78bad3d11a88b7ddb2cd19c17b8dce701d600e729e31978ed283e17bd13975471a3cc41380f61b06e6398572c969e0a97c8f0e0e1ffc1e75de3e8ad321dc86edf9aa0ae222941c5ad99472e7b497fce170223b142e1d9d710f84883ec8f038cf50403ac8bfa5be213df902c8c309038fd2b8b108378a2f35bfbd9111e646f33569271d6b03fb15ccd2e646434a6bd7d12267fb3cff5d27d2e98334a71d985bcbabddebd1423a96cd10e7887b26343f81de4cabc0c072afa62e8c7cb05c6aeed6bd1769bf89179a93f1a6cc33976e5b49095f86a79dc57f7cd358d583071d03968b122cb8d09a05fc47adec2af778011f7c542ec21fc2ac4299c316b9b112b064e15331e6cac305901a167eefdd1defcaf6816b685ba73f8b3cbecee1f82bdd2b89654323073de92f0279361ddc40b851462f2bef68bf7c6c788e0b05565c089e13c681f12679ab7ef9ba9ff896d673ef47529ac26095eec0fe4123407ab6faa661484aebaa842b7201eb6dfb528c06d760a637fbae62f1d3bc14d90c54b814df5806b6921652d24ab8e6143eada637b0cd72fa85511925f5d25b5019bc983960a35c72aef5d1235a162eea205db3afa039ad0d2e604bf6e5f0aa5b5d8b602d54635bd41d408a472636a64855314e8282d9b4bbf573350423b6d42693728633f2df5fdea4fc962764d5f80192fe48a89bfd148273cb239add4821e82f9643abd542ec7632e379c8cea7bebd05e38fb9e072b7da4c52bf436734d31fba1ec750e77db919b597124bdfa5214b2c8ecdf37ee72fc8b79da76f87306ec947a989a549238b1e6af86b9577b39aa4d7f14d3acf0d74b922082611b0eba19c2f31d3580b2505c2c15283ef06b9132264df40f716c2c541561bac5bf141f24d724920545cceede2df3f42b39d5aa37946d4b5ed98f05e1fb0e30bee5a504e93f4498f0e111d342b496ad2f4e1f4ff849c982949182dbad8a5fa4c9801369e0f9fc5680685ac05030ad4c4241faf9eb0a0e17b0b25f92004ccf3f3f5ac6bc5d61ab9e36c80a5b3397a18d538253934ee2c38bc13353534c1106bfafb9dd6d6cb96c74f050444df427c6c0ae8fd0b2952172f5f981c4cd6d23cbd4789c704e0d6f09bc12e080065c7516174ac9d4a35b5035767f959234c16fa345d631204cd16fc04323b557bc95c8ccc5953e3abab2b23c449f7f2660da91a9d322a49ce4fb65751590f6623eef1398865d64680c9156e7910a949b7f4048c7010441292de7129ce5036b030541da3d701c3fce1c711ef2e44b0e8046bca4094dea630ed38264db66adaafdbbaa81a47cc44616ce544e1419ac089e82c1be936dd76769eece46f515713c1f02649320b810a4062230def881095b3f4937fe3b0e8c6dbe3ca7818253db8ed10c6d2eedaeeb1e1ab8f3be1ff8f77209a1a6e5c21860d572e8f0300173fc6c2a2347e456ba045efc66b1abf12b2d76760aba0ec363e19c1a04e44733a3ea7bc8ad605d8e9725d0d49fc0c25d494e0344c50b616f398b342edb8a1894229c75ecd67eb20a2d7687cae4c330d13435ee91c21c74aa81054cfd8170ac3306e3fb097327717c6a0cbdc5de3d921fd7ef7a56c2e839d01a4b883fe558446cf79df45115ae624eb16c1960813dd326f3cbf8594aa969d497a53f2030e1964eae09908068ffb047e7ffa76a9d4564c424e87b4d7e412f2dad17699342f204022683428ec9295c3ca27e0ddb0c2f6e11701e9cd20969fd2f6c41a10902704f0ac8769bd1a50d1832c23d4aa888bf3c5d6bcda86761f92709fcb0c60c26f20e1ab9a0955c7a446dc5a28e9e1e371b81126b7c9588b349d0642927c3c733ce462d4b41fa86eddb5f655e5ae883ce7799b4156466c33b15f4e0f4cdd142eae599fabe121b1cd09c5fbf759726074cb015a22dc7dd33f7e1dd1ee44b9b9999cf6b7afe8b95e1331cbc12822a14a6b76411b37f65ffbff06f45ad9a19d4f7b3dc8c2ab945aed68f4d6a80bdddb98040e8fabf9ea2e33939ed1f67f68f7711d1ba6b4090d8e1ad131584f88aa1b87b0d1794ae4e9eeffae272335d065c65885e150a41a0983350131a91f648dd8ed9750e39c62b72e532def6ea17e0bffd88aaa70451cede72200c471d3a5002c5e0f6fa24180d1471824492dbdde688bfa41fb4029e138da56dfeb755a3dc949d459cbbc5a31c0aaebfade577cb36c49acf1af887f6679dee08e0e36bfa2d64938bd418cebe8c1067b011ea30f7dbd88d884d65e340493895c03c835bc0ba48e1c402839721a7e20a414691b12ef4ca1ba04fa31f71ea6a357967a29919bc7e7fe5edb61ba0eb613ccec12d7779d4cf61a6380d3dec324e84529b72deeb6bf2ae9b31323744956ab86e8d7bc0a41493c245c0ca0ad88cfea98bf6a97582645ff908de9a238ceb9c1415b68eadeb2f8ab10624f72c6559612ba7fc1323dfeb15bea4a857a0f56ec1353ced24deb1172eefe871e56575a0bc12c3d50b90bca175f125b9a3da0bf442cd46a68e06a86a547ffe5c17cfa11b977d968e4a02fbd41d07ff9e4d54d866965af5736f497b826c02f6d9d3e1e9cbd13fab1286ad5c4965502d99cf32622d97a200ac8f446cd0a477a938c0c13c9703a4dd57eecbcbc742fa1944608a93744ce7051996ee05a4239cfda769080fa6744df4ff541f1d08e784b07876778caeb692bb9e788673d9b17bf49fc5dac918d70377f1c6c587b8ba233cc12320a303b55b31d2b34a115e96a5eafc5da000152a60c3294c4817b3077df6cf4f3b60db39983e05f13e7c66e084105d287db7ba5328224be105f81cf482361c6d34632366b58484e8d25ec257da93ff08871708b6dd9ea121730964a1b8ca3e88d1063efb192853e840942130a0669a653da7d2df75522648aa574bd3a29257594a111c53b7421b60b088916063356ccf5d84fd6432eebe295c3552803800da55593b9f378fc8ffe76e2371bd072d3193c91b24adf9ec7b751630309762c578eec13a747e353128e64daa4a423933ef1e90a451973330c923cdfee5d7712d0ac9426173e69ed3e21c4b2cbc82d5fda3292b2d9a5799380030ab75cc9f823bcabdfd466e66a4f8ef611c1c7583d93470ed5c1d64217769222423cf278a34bffe5e1c513f0fcd84146f85880f415c520cab65967690184994116c5216fc10793b5c5c415896083570e317e7d7ddeb3719e333f36ca82805985976c9e4b50f355f9f194840ac79abd232f7d7d32f9a6efbedbc36b661bb782ecabbfd9ce877b745b38e77ce3e681d601763490bacf0a99d8c177aee097ed7eec233aea98077c7ac2b979e385d474805fab5aa88bcd8a964ecd4957841b07361c04408e03909bdb6cf698070725ba56209131b194cb54404694c68f6c36a071ecc559dc54e5b87c7c05264aa022c965107a3ae4cb2f0c72bd56eb113534f7590d4dcfb928264ebfa28f548becd638e42fdd4cd72429abde6d3bf20c95220a5c6a481da5ea48ed54da96b1e8577c332d98bc5a6b6d73267ca80bce40cd021d4447ae98300aa46b93c2d31a2d2246d8c45411993f7cf9215b7624817d8779a3c2db8328d10db2204bbc787500fdbc5ebc9bcd71e28038a7da15324eedd453fb6a54e921c908e3694405019695788ecca1f3b46b20bf381b859732ddd868edd1a7237ade96a05a5cf12e093438f1ef7f3b33b5cc7436835a6db765cbb14643b682b0ff9dcd4e4ef8dbf1af4097881b93880b6456dad962ab116944774b732b3f1c45a0520ab8514a0e5700cf36510c31584b061f1836b699c521ffdce1e99c0e89b5dcfea76c532f34f0f92d811440128a9bdfe03e2f4d24683d7fe8f183977ea8f2d944bf544358e0918041d55223dc07b43685381e118c6a3ba1a4fa713d1c2a4a3a97839c994f20c3013ebdddb59b65bb0011f6051f586c24eaf547bac67197cbfb47e939d5e9b7dcde3c5d4ea20b1f7c060741c76b732e4bda7ff60d96ed4821e2b971b86bba909b6939b71f8608eb662e62914c0d4b538c147a086beee2d3dafe979001300568cf821027573870356c330c6e036badeb53df3d357b97f1c7f9d7d370119e77913b12bcd79dd62c0785216292327e3a6880af7b6d7807929cd3342eba9283427020456e980d1d643f21d73522a0cb0ad4482931688409d813baeeb6ee34f654c2cf8cbe81eab8dfbae134ec60deb1b3ead5e5eecfc8cf8c804c49a988d5bffa77054d3b6fbe58bd941948de3e200e1fc316a70edbb85925d469c5e2897465d7c3e5c010646c36e09f1593e3f51735adc6bee6f9fa557169481a8695dbadd30c6f2dee99e6513c54376ede961d573c1f3cb16db9bb8185c3b908e91bb54be0225aa6d51efe24857de5891a7709bc9eee680c756461af9753bbfb475daf342e6ebcc6fb748536c58fd5b7dae3d2d8abdae2af7f8a116bdad5cb00d4a8215a349bd917ff1d450cae6d3b975f40630270d820fb983a30d602c66dad4f0c1cad0ec3e58a3315bfe59bba5018e46b956bbba8c77281aa25360bc431f499e549e8f928ba59527ac5cdcf39c07d3042e86e39d6a6ae8ef0f70a08d1fde3f7ec1bf6f66b9dad0cf8ae90428b8444168a90c0580156220318e5bf2e8b5e70e2bc6ece9cb04fa0bbfae26f607b804aa5736168509658c609c86a0cce70ae5daa08b14feab81e48c9bb3c59c1b0f62ddf690d91db364ea3286cf219e29f0f005579897d1bd9a8a1c97a41b800825c44be6c736fe3bd7047d0a2bf3124d921b7254bfb9d5993a440c0954d4c6ec53301b96e1735344e1c425a189ef90c7293dca0312772189f5c57ca07e950dd954a766d5779a191922e19966174075facb6308c5726174b9510075770f7915f3b06f658ce2a5c7b60d86ebd88574fc55cc1c02b4ac3b4320748eeea6132dca3dc6f5ac179fe71d6bec523be767cd55a9f31f6289966041c98313d957871d67fd236e24cb549ee258f7fe3171f1b09ce4b8f4d696fea15fcd087c75248bc919c76e974643797a90056c9b6398a340bacebab26a790fac76ceec942170938318fd9cc51d85817315db8580f5e34d1a00c1af6d05a5cf14e76f8e84477425ec910a3dac1e6c098c1f147c127e95b3f4bad2e01dec8c35931dce2c7bee53598b6bde7973071a0a6955d9cb9972566a80cec26f0e8ed81e7951a4efbb575ad6610a864e58422045f40d1f252564ec548b5546695e831bfa1fde8b6c5f919eeb6c8ac9e52753d0a6c678609984a35f7b19cad9d965d343a2b71f34dc84040834cc3d4e2fcce21788c995a6662684ed2a4be0e04f9acac09651a0754727b7dbd694d2a53536b13af58c89bc8f73397012d16edaf370a3bdcf4a5328e898a1626611c9f10af07b53c1deda04033e1b81101daadf8ff6df92ee534e5c8c3bbaa20b44253fabea55b28d22d2391346911816d0d8cc248a2140fbfcd8f2d0fe273d0e462acfff6244408d2c5b54e63afe35b07bf388cf2d7daa7fdc18785549b578d659486d0fb1a18d1809526af40485a1a19d2139346285d54edaf80860de4d4ccaf17529a48a69c4e4122edc0994dcfb1a90fc88ee511332d5337d4508933a67a95d0dd4a23250ba18c0c1235783de853b9011daf25daaafb7eb80b34e1f5a26cc4d3512b453fa11825a5bebc5a20d0910fe038ad381bcfdd14243566610fb1b5a3352cfa6b5be72c1704e45c9c956ee598be33456ae20458f125abc95b84b80240f89842a3138b5ccc9822bf3179799844872390fb597743cd1aa9d2b44d4759fd48e2d162ed7fb41c0bc62122f892364cd6b72927fc6061d4cf26958e1ce168a1919b6d894173dc8d85412268b0d379eba4528ce085e30955786f12d57962fe451c2d523d51cb9baca878322bb7e297b4bd87e43b7f6801cc12245a7bb8d7cfd9ac8ccc44795035eed38ad0ed080afb4c3c5485a52ee4f5e620ba11240addda1868e97c3bdcd8a83282330f2597b97030d425ff6092396afb002591b82fd07892c47c68bf3f62e4081783b7a4d67486693a735b34f2eee3b1746714ed4125aceacc82d19c9b343f54535b23619509c2cd0420c1cb025183376bac82afa30eea09ab0c9ed51a644b4ae5e5a863a63f7654adb046b295240b0e88616e53cf40aa602bb033d908a5444e5a8b78adc19930591c01946db369fc3f6850c874119197ed6d45624fb2a56890498be906d1ce405ab12ff4ac82ce1e23002c7a366128a2f758c59bb3d6bd306e7f4e8efbbd3d244b555c0a5192564390d69a9711fafb7b379ee72889f1f74cf58806bdfde655bc93d6b07831bf75cb4c71033198f2e8058f188a297a486a32835104968cf14f3d755d9bdecec0f94035c8679618a245f22d81a0461ad0e024054dbe3016f1fcf2a879ac891fd5106608ffbdcf3d11f45ccee091dda2cb13f2aa44f20f1ab83914b7b0aa2ba97b88d928a4b8cc0290f25af77e643422aae968415e4bce91a313487745c8d3c0505cef3be10c1f036a336c9eecdb3d4a6cc3d0e51cc8d0cd274f0e7242fe5f3139b383ff3f9515d9c97c000128f1522679070c725ee9fc00736a3c7441915bbe9c3c6ea7bc38e42b1d2d6f17717519c1b81961ffe69773e700549e494b90ff1e010340a9d813f2eb6df8887acda12fb90000e0e505db744670a3208f4c0e7e920f7ce35834657f4ab8c0184cab5bf9f0232a88ac0051e5798174988806eeea46858b5ed68cae539ea970199c98b3207671c4c270452761cfdc2c7119139629d19215776be4531642195195a6abfe50b50abe36bd26ac4e9b72536890598f4ccea5b5bb026c21ba3eef3f14875f10b37d783f7120bfae425dce01f2323a04515a6c9ee957f91dea4811d11b7f188ff5a272d89bc507bc2eee213e03917cd2c8c8fc27cf6ac5fc6c89dd8b629ece1f6a754feb15d595bf71bd6efc3947040427ae02fdada3d6579900ad5d668c16804ea9309ec56a54bd70502cd7a8a787833923604a3565d7b5fe2ff4e17e53cae04ec8f7a783b4fff7744826a42f38d87fc31c88239e828ea71d96cec115c0fd62a611daf325c5b310ee38c6d306358bfd6c1c6943b37aa6463083c843acf5a56c29e8ad8a2b92972d33d2ad507858986e49f9d4b578d2d02bfd5bdf320bb32fca19adcfdf3a1ceb49f3b1066b5af0165e8d449fe64a3e206270fbea7495ee99a4abc3eed2d591e4067a1a5a47655eadf13388bdf7305abf9385585130b1136a61b853b6e18118905c18629862ef04ce1f9139aeec31c2b763aacea6371067789a8f58c305fef29f4f6f8cdc789e5d7755120169e858363d8ea82ed17da2381a03ba9a4d94a8ec3bad452f278bfffb40a2879205aef144deaaebe4bcf2ca13d15911cc682f0a0cbe43c023f742dad5ea478ab83d98aeb6ec983b57c0011f22db7a8cb99f2782e7d055ec5ee8288f62d240627c95521277bfe3d2e121ceb296baed42a2fbc8819e343492a39730a110977e7d1d8054f6fad40ed6dac8c31eddda1205b087243335b323b969591237811282f7e83e6639672f9ad9fc553c37d93d946de542851b058b3020664141533e76557d75ca8fc5b0ef810ec596079e81d1460f3091bbda7a7c1efa3aed6003185ca144617f87e3a7ede9f743e6e977786f6fe53b4fea9a3619261d783f946a13c3fb9114856aa06f18b8c3be73ed7e2866370ab06f7979a58c16f7af20ed76d2d6f91b0af738cc5264d6f2c6a786aafc1c01d598bb8fa84f6a7e454d0348b8bcd41f3ae1f7b028337faf664209272fc7ec0611a8172dcc269acd9f607e26acfa24ff16d8e772dfda4283a63a73a372ef55226ad58d19144a526ecbc8419646485e042106076b482d87c9648963d2368ade1b834caa97552b417043cb900136df1c242e3f7eb56d79ebaf56bdeb6e235090f971905b7f2e182548929e025697e2edb295f3bc57b63a16f9efa707c277dccbe9ba94087596c46f533dbbd05ce3a6d605f37f1d3358776ffa50d7228d4a5237d2ed02d77a834fcfa7fc44c1102aad4e244a6cf26724aeb15dda5981cf8177623f249b8b763ba4edad621d119c4b017ada842f58708e25a503f6a3b75858eda21f429f7aa0d80f9444ec0bf5ab0cac03d0c682caa3257748598db2963fb767ee8393d7c5f631bbd4b858b236b4ce4599c576b9d8801cc9dff2af3ee5d67be05e4a5137c263b04d64f6278490f802c202f70230305157835e2d6174702ea87ecc213b267e7070ca091e77e6726d5951d6937555e6f6ff3bb8c59c9f73ce990712a59949a5071e4b9b07a42e674ae95cb0544f6722bdc59c1e8e471d4986c04cced04526e48825672ccb4430a78fffff4d2ebe953f97b541d6065a98a7aaaaaaaaed8ffaaaae1106d0e6eb05aa295befc88f891210a6745865536c5cac54244229692549abb2964c2477944a301972b960cdb411c2216c8a563645f5c99868533389a46555d814b635eae3ff3f972e83e0eaad3f9a6be0040fae9a96872786232aa3a3af1ac618bfb428cd7c717a8084bad60e4d702bca7ab2ae555b582d0d8d20451897f91ad2605eee91f9d329019cf1d8da8367b0bbbb3dd1bec88a61e179c191fa6c01ecf88211c312e300ab0cc74156db5b51d693751dfbd1fdf021d5c2939c2140d61b74621372a222a25122e1c2ebe3c6a6a6f6bbbbbb3ba010629cfea829943526f115326b5dd30865d5b2a2ac27ebfab076002a143a70eb122f898b369b6dc5995c318b5043c9169d5bd489546fac0a9bc2b2972003ab13461ea28c32ae13c8140d63580153dddd352bca7ab2aeed29b5b505c4465c3f13292ea09e8fe3865b7777d48aa42e2b63570dae271ab8da08a9c4058e4b77b7cb6229182d3696dc9278dceec32e5ab66c5ddbffbb2af84ed830fd9284c0d29a5e52841d2fe5ad47940f175dd45392f4c678ac7954ddeef64c8110774337f6ffb18e28cd44263d60298b584b9c333fb843b537e79d4bce39b6d6387d0504f3ce30012e3039f4aa0ce994450301de8ab29eac2b0f2de608012128bbaaa1a94645950c4de4d443b49112e0032a9d4bb76b8ac061bb9935c3929715653d5957fc12d6c7ffff9e77e57fa744f0007d88ab592308930ddf970d163234323864f87f14c39c7d5a5c162e276fd99aa41bcc38b6c0a2cd669b494da72041e0180faebbdb4ddf0c052676400b30785cb07462109da8ce14c12dafeeee0f3d1dc61b5a93b6ff33862494663e19ad368861eb1f72b1f2e7bc588c802220b960ed9011290a6a1933b8009821769ab090d8de7f96ccb53bac509ab9d5e56187d82c67360d4d76dddd6d18aa4c69a6fabf10d562fbff4c4294660e3308a662ce6fc953b2f7df4ca621b6a47a6b8d6cb8f16289dd97354f0e8ec063d0e45804b3a2ac27ebca7b9b73ce594594661e91496587aca5ad8396eea58fffff3860702bbf0e1b2d8b8cd40c59fa4b793897125d379272c920998f1b215217f15694f5645d77217cb6a6b6e4a5bbbbc99029cd549f32fd60e175bfacf8733ea91411e3f0ff8150261ac4feff0dc00986d588592e07dd750c09142f70090d21239a351853b06c77f7900fa5993f6088a160568f6aae45edbe6aa4436966cff7fb6004bc0ac618639c5bbabbd95a46a1f63be3ee6e2b94666ee10e325d286ce35815368565310c4ecdb1350cb41a5be3bbb229dffd4a5ab56555d81496c5ed77523d9f6d5d328258b2c26b7ef9ffe70280e9f6ec51eeb8c4136d58fdffcbb91473d3b7b19aff1fcb86d24c5d4f032cdf8f76769e865c923bd2610fb2fb6079fbf8ff0f2534b4f2b7b8d6ddad944c69a69abee4803cb37703c09b84ec171b390caf16c22ba89996a797946606cf30ee8131c637cabe59368ead71748dd36b1c5fe3fc1a0728ecf7ee09fc727158f7d41dc7b52a97aed89d7b61cf20dd7ad2cbba36f310b6a42d8ec8e7f032e7bf55f3ff2be9509ad9f3fd3c5002fe3f6f841a5b6245239c747c332335f5cffdff3d6c28cdd4f57cbf103d805db37a8b31c61877dbf296addd880132ba8e242ec618d718a234b378442695226a2c557c9382e2c17b51067892b62bca7ab2aebc921b43160c94d01325b613b2947104caf7bb3141614609163bac5e7e3ace760ad8fbea1b3b4598c7aab0292c5b03005e77378ec40b39dc4995245b7c97430a9cab1897c5fdeeee6ea916dd4a37c61d6731631fbe106be707a29e9a33bb73e6f1ed8992b1f4f1ff9f461289e4089b9e8eb6d7474b12a511bba99c730e16519a794426952182cb1aa7deeec52da705590b8104494f46ab7bf06efd3d4f91c32c901b784f8b218e9a8c68a05c0cd13a8f3b7eb83a154c62329634f4248f43ad087684305ce398f0f471146488cd022bc8f811923b2292c3e3a846850efbff6f3184d24ce1f0438be2ff322b9ab44769113c76e1fcffc16a5cdc92654a33d5d95bb25c4f36e89eeabc227470569fab730855da6cb69a99596c912872dd66deff77e8c043aaeb5f1e6753532f898a2bc8c66206f9b1e85249810848d68b209e196228fa884ecc540437f0d2d5e9e888712372bb3efeff5f97338e8cad29221a6c36ba860d163d97a5006ecc38ba526c94f08731cf3d41f410b6d8a4694811efc61e308dfc5a862472445a384ee494d0f755c345219b825d5cd50659dc11917839a71042af8e28cd4482b84afe38ae942b3760e5baf45dced852300f0613cd6870bb181508993671ec97ec7e79250930206408955717d111e70c4eb930f2faffaa224a338f1eaa9039dc345ce668055f1ebeb12a6c0acb0a91f4b4d7dad16f7a8325af407a5891347700cdaaa189d1825a6e93156528cdc4b52f4e4f0816406d8117071a8c31c638aa09001a7528aba5458f251c48bd4444aa5154342d3ad478a4fd7f18d44be97be9eec6f86d0b3f2576ba96c8ae545c8105d970c09df8cd7a5cb09afbff9584509a5994f464eca0648577aaaaaaaa8a337bdf5a95daff1f86446966324cb9862d51c46cac984e45ac57b3402522449e488f9501820792373d2db723c1125a472d406ee648ea5815368565956adb4ef0eed4d0b8015b21c319b60454b26abfbbbb7b92509af96414d16385c2b6dd3e3b2990a2ce8ab29eac6b1490b21cd54562e66c81a7d301f3824caba8c914d21b3143c0d6d4955113d412a8e753c4cb811398b2b46010f278f05801416163fe08fe3fcf645194c143bedc691221bbe15b427edd30b6d2afd8c7477d39c77004df6e47621cb16952ca51559574238a2498d24cf56f4dafa4f9012a996b915d581536856571cbaab029ecdb4c5d6663d1c7ffff1cb61c22872e6723e4520c1d442f1518bc69acdc7835e49d36ec9e2716d030a88fffff01ef8fcecc06d23d4368853c3e4470158cbb0257e002a6c88b5b8fedc724e34176cd7a39d7c7ffffa82572e5ffdbffff3bf5509ae9fb013308a7a0caff12e0e4c379f14ceec9399b90455ecbaab029acfae69cb38f10a59943b5b81e51902c083e49959a8bae2ca6254b6e68d316f5e043974b956a50ef58153685655b75c74077edbcf08562c44c52d4901f27b058b28bc2b12a6c0acbe217dd993986b86555d814961debd66505807a594f742bca7ab29a6bdb8404d4ddad43820bb025b29b2043390da51563657adf740b57c3d5fad121ca41e4f6c562654a33d5decdff5fc48d62ce3fbefdbf4c12a5994a0f64966f115343195239bcd8755dbabbdd54f9b7c45bb0375bc21155228eea85ffffff15302436214a3387c52332790f6cca9fe4869f7ae07e1cd0bcf58aff8c4ca78fffffc5b0b295ffdd4035030fd44c6f85f24d81f5758e7530b662d724fd09d6201fe3a2635a35e6fc254df00e05feae0257316163238af8308a0103ceab86fa529aa97eb744db59dbc7ff7f61cea80957336e37398ad408eaa7e12e9733054d3e2762f070a167c609d70425263c7182f39bf5b8bcb5d4f8432cd5b5efb74f27889baf1baf28ebc9bace786b075e60415c42e38e19352a88cbb3bb73a8cb8b0b7c90a674c4909161a49b8080b93881bf9b09d9ef37c36abf33eeeefe4262115fc995ac8acc07b79393d14cfd55d653dec0dadb060e54b5fdff1fb72c0df81e9596924f3227118d12274a4b48079f8527231f1c28ca48109934f460d0c1579ffbff91921ae9a9918c8d64d5485b8dd4d548628d54968998ec54555555754bdda563099408c20092540449662868464cc786d5ddff3f0a08a5994220a28a5694af92165e50f514b946388854a72ea6c80cfa04b595ba6ef75b53fb9d7177b71630a599eadbeeee96b7cfee99931cc298d8e8b101b4aa6deb1a65a4ca5bce2df43ae59c734e12a599ca10394b9baee7fbff16530a08885b1c331bb639e79c5f21946616059020a8946ddee6c40079131a68040d0371248cd31863001400070c6a94b4787808311687c5c1a0480c0484026130180c040040a140182c0a82d068aeaad17800a9362d9b755087dcf8d252e1468564365bc5a23186ea284aae53a43daa469d13895e5178dc5b2b30f6db8c5b8ee015ec4a8f461befdb5090b46549080152a5f5c6c1719314fdc262e01b2f7cb846499bac1e5a5c8b5520cd8497002e3e611b62c8d6356057eee490bdaea48a573a2d93e28830caef4f278d631235b561e51fce0ed32674e53f5140a552cb7c0d081c6388e0e53a5effafcadb1e9bb7b2e6da0865e6d8d3fa48fdd8523785e51f71ea1a27128cee1c5d7b313a04ba1da2b55f9be41aedc5ca165f290751cf0590cd0d4fda27e79761ae35b87b26687011cf31c28ad9d213cb6344da3e3f74b2b3537c3c235bd069f7683ed20d21d4b088ed678cb5fa2a8b5490f1b7bf61818323e03ed030f223019ad1775bb4d2eb1c7b0de8168040063925f1d163b92332dc60a11e8fa243ab93c61fa4c3ddd46864a2d2308e8fc72fba05207a5cff261d3ce57fd7f153a8add024690786bf3c69bd9e960280f148bfdd347b2c4e8917a4c69317fbdbe47b65fe1897ca90aaf0343c7295c6066ae25db25a775eb1efc34f746a1c8bcbd876ca1a2cda61554b1aa040360a9311f60f9eb859eb6db7cc115a2a1a8a6941cbebcaf6f168f51d1ad31f04589a44a940b87979d0107e60ec29246a8ccc420d8fcb4e3ea5c9ad027bd880c3948e6b7159b4a8a37f4cd55e4911a95427b5d31f4d2e256e27bced380dd8d246cc8829b585e8f429a07f12dd81c90e4aef2cc53877cd856996c1478ea4231f03dbb9cde6d8de7297ec59b50b45e032049ebd53d24e41279dbfbc974d67b9938564044581bd86a8ef7d6cdc08a29870510420372809173a9fafcedcec4568d34eab4f895b5024e18176a716b453bba8d17c4aa98641e0ade052f9272f7b879a028af2df79c3a056ba73b0dcc0ab1dbfbb3ecf2a45e574a9214208b332241ef642a9b3a700c8f059c4882a07b51c53c0c4c948530ddf491f68f199e39d885c90506d27e3097393314eaf300cd5dc2bdd5d2f3e57a48999a80f83cbf9c362786b75587cc2c110b6df4957d4e698db840b57f3990871489c67d1bb9709db69cb1d53706044b9c4beb1b1adb6a704c44f90b01ba8672f30afb5ce0a199edd47bcb8e111e93344e453b4d2244f262a824b6193cf528a7639103ac8b8f2a9bf48c2343523120f50b2cd953e8adc09dcbbc14975bd51999a584ada2ca8feb61edad30207495f2dceb01a900e462e6039dc910c907c662c6d15f58cd2e8df6e596b650c42f533dd0d81d1c710855ed25db4128e89420b34545bcd5aa3e8d1c07cf9370547599d25c9fc3535068d70d49bf3178596ab1957e640d3c1c9ec30ab08cf814acf3bb05ca64ff945703c097977487372036f25de21d993cf004ee36e30c75fe07c8e237a9a01dbb35788df885ddc18fa956f48bfe02d9850367135038276ad7ac5cfdd5aeaa97facc69751b681d13c3fcf0f0452f8018b861cc8eb837bdb995d8d04681627cc7ad38588b3024e671d9ad1941ac2b52ff4a94ff9ec9119c77e26f4f16b2da84947bae7c04807e6d7896a4eb000169b8967d635e87bccbb421fdf28d726084833494e7f3dd1f6aa5243fb3ac63ed839d08a4bcdc162b3595e9d5ebf4459d602799f8bfbd5586690b47ed354eab043c80b429f3b4ca1c0e42edb66179c066fac66bde8536217815d0c77fee1a07f688191d7f3b54a0584cb0b21db23e415fe7ad635084a5e405de7c966d880a6746f69be38a57145cbc3f38f131b5b21e5bdf0498a9e2bb907d5aa73183bbd5e33089b4311958b675a65fc285b577710993c27a5231644a4e96ae90a487ee4b5f25548fd8b6d66f546e5ebf31b5b22d90630e8e9505e9479a09a0b589aeb9267946fb14fe12e4b5bf927e8662b339ca794bcebe7924a432b6b215078fc811dd261095648c9f765445061abd52791a68bd1ae7496b0272b2185476bc1989a6dba82cd1e6595ba632c3c2539e2cc4490fddc1983701b68a2790f7ff8a7b6f3504497669a34a6b5df26ac7103b1be2d273be43d06cfe8503da2511ac3b9093abf2e5a23c034eb8629158e83605bf704cea275cba29d285a1868e5d6848115adca25851956892766d702a8f8df05f238a80c2a402072804596d9116cd5da5f2fe3f834001ac6bb2609735f829a9729c75aace0d836b8065dbf5c8df4e036076bdbc0eec5596eb839aa9f283ab945c837d4e89aec18423f40e74d8cf50c31ff70db8457a528c77a3e540551713c65e776e3272224a12720a9b9e434ddd663f81bf7a6ee289d5fc5c00297698a96aba2e380fea4cb7fcbfc438db3b037c9112df4f081eff2c5bf86c1c8ca5e279d4970ce10ac5b53260a9c2fefd849d37021d84db480268086fe18e2e5b029c72a3852341224da2635397b4231b8fbd5efb58bf18e9920bae9463a4980e06a20cf274249c6005bbcfe7ce8dd18c24732cdb4ac1bf83d11b657c55bf551d7b85cc81352d7a7c53e89bb842e069f8b2c124a6af601f9b69bcef5e6740a0ce981c6c7714b376ac1ed6ca411b2609a0d4efddf50162a9a18c4213803c0ed22e26c04dce7b9032a2229a2c083b04df26a7f4c657e471792b80fb7e08dcdd5298ea718e1805344b41e197f95e6edea21c20a06b24c5f28922d3d784a3db550c565354db5df30631d0935751bcf76da87e0e9a011f121f4da51412404c9d533ea8f1b47c2a766ba97b8751079d3abc46d9e1afb396038767c27d5737cd76cfd19027c2517ace2a75d1f2d7da2387c4a568d9c5904311c9fef21808ab53b5830728ccff0c1a15829d66e8dc39a93d514b76b89e25e9d555cb043cb9d3a0e67a77c8ef637ae9e59c1be788c702cc609d62950454a5d9c578b09ceda25e6bf646822edea84c8e59816c400a69df0178f8bda50a373bfb87b442a100764cf27fa86762ddb6f1c5aa225543fb481039a155063cef8bb3ff2e592becc16f12b8f93d10ca7bd85a644beaf8ce26b7b20a3ca57a6780188e2f69f9d7eab8449aa11e447e81c35a2a2c7771cdb03c1d4f793c81db60088efa7525a972757d5d2eb1776feba731f8830be46903f5f1411464cfc60e10d96c79d2503bd6befe426afa55f50d91c298ecb41f2cc0f06dd7fb4a868b05a8a9ef77b074e8fba84274b104ce035f24e70b17b13a5dddc4b3ae4afb24ae106e84657b1ff6c49fa936154f1752f996f6ea52be089cb271a71c6f783c5997e91a0552fac57f96413a7df75af1f4f8a66abe2e4135ccbc3d8d8d6fca963f9f533e50307e01cc56d5bdf4feacc7a481144a30d3c7c55c6ab2a5c9ac38d13b0cb04ecc556f816d52db834b498546e7824764d532fc61e67023e4d178d2707147b0092326e06550ccb01985b2a541513973be2ddf77c2c98099f8990cf5b973b5286c9544566989fb38bc5247f2d5a1236d6beb0cb0f494e67b19d4dac0e73700df4781b55eaba76e47bf70066d446295b25417f50d0814e4b3530c7024fddb0944d737fced13c0d7468f2a1cae92ba079f3a212f1c0875d95c9f86399f8bc530c36c8a3da191668369fd1b569cb210f73b09820cf233bbe24d37d370caad446009b2e668b8ebf147e6fee3cac7025d0a2ead12c4e9e4d048658313f79ad5a630264c542096ffffcafc920a94d3ded10ef4a19a576f6e80444ec71712de5894aaf9d467b4a712365766e2347beb00c4b98017a2fd4955a3ab7285639dd392b77110c9c1c1b2d12b20a6db882c00473798ffe2d7b3ab67acdf9581ac9484a5000817f0b57a48b9ece8473f75d62ed4be91653391c90280e4be7b125992693464a0a244222174232851f3db684db69d822b1b8c75f36af99cd6babc646e9796a2a2e1551f9862c5df57abbcc8b6873a900b24ce7abea3c9078941bc4807f073d624a9514c8b2146fb8ed92221633ea1b5444cd927035792ae8e2c22a206cac941f7da4616aa0e32cb533bcfc704b421a5a676a2e93b0505c95b550d4c544e00267dbb6f72c08576e2350e1f469f3e98483749111862081de8772d4b56e7a49e96a234abe8eeea3e116b5c24746bdaef6b7d3493275a86ddaff53e254618fb4a19fb07b06e30ae735850e508df75c9f19de0ef29821309f3215956c124129bf0e4098b807229ce8086074b272accd3281655a57a501733a1da0399981da2ec635447792f9e548724a19f09c3fdbb2b78e747385b38d78a995c203d80254b4994420fdd4e01a32d812921ecc8b9c7d183ddad7d23d1f49477977a961f6ed52ee658fc49db2bead3b00d4445d8cb97b6af667936aac950647d04f7dec399d5bb2afa1d386b5c29a41583892242fac073acee0c7740470225faea9d56a87c6215b60c2c7ca9734afe6bf501ef2b16a25b8c64276475862d9a795aa5e5e334442f9a253d1aa5a930b88a83970585559b7ee75ca8a2fe119d85d7b8249c9ca40a079b1b873568e1b5551ca752b629be3e06ff7eb0faa4b490e11f169d15fc97c4dfa13f10fa031ae24e8080137e5b3690ed6ab8a7ecf87c7577fc2d8ad055c8214e103cc8920ec43fadb5e332b4e05261adaa0a2413b37b1ff24c2b81ef63b9bdad754cd1737d28904bb5670779d624f5bc1068cd0801e6001b8f0306d27a5957f15f60d1f3b443ec1b2d9802710178009518133e01a4fa23257e2302ff1ddff9750f6fc024a837c6af43b46a17aecf7bcc0a5d980bf7e91c36b631cab928e7652a3e5395289179e82399b02c978398c4e4796c2efa5a6cf4fd704ede56334970e33d447d6146bdbcdfeef36d319c0d40d3cadfe267a4bc688acbc30c9fc52689aaf22b132504da6328d3d259c692c8614c6f114c2136c651b2849ed57681cbce5d7ec868975d13f3b22e2bcb18c369a150158f43c588f848518a1c3503f525491444e881a8696f16b519af71ccdd9780c76e973e452fa293057a143030a0b4e6bd895823cf05a6dc82cb945740fa2e2e85dd61fcea1f0fa746c15674086a9839964f7382b9a0ffe83fa03816808fe035a21d6a7ca3675d7b1bb7c16eadd24b159d2d42ac8cfdc552389d1980bfda9ecf64ea08426a51851b7d24f05511f813af01fb2d15ec806d423e72ed88249a22b5c3428e0e51b9d1d6b3b180430513c2b90157403a533edc59300a243854217afd93138c291a9d91c861a66597f1c0a75708ce831bfe516e8a23f9eead92a0086d518d7da90b5e096652efffb956a443fa022a07dfd5aca652255b4bbfa4d6e7bb38778a0ecf9441718c9fd6e352c12b38112bb9575bfd5bafbfcc2bee0b8d36cbdaf4d8a279fb2f2c4688d7900602553a9d939afb7bded4c3c37a5d2fb7bd02ea964bd9a69a5c263234759936adf5f51f07cd2cdaeb75dd5ff76b4902adfc34dfa2ba87d1eb5bf0bb7d3aa9ea8308dc0156b5ee68c85c67cb39352aa13391e126a2308ca6a4d75e5110b0e9ae17cb0c50de55f41dc61f0cd5ca6e79715841d7bc10692cd9881858bc51c94e9229bf1992361e2e2bf02015ba3a9b1cb2f04f2ec93a44956c4af931d28f597f0c6ca20278ea4d5888d53971a147aea2cfa9aba84a0e82fed663cc3f65ee777e3e125eddc757ae872a6b7dc2560d07201882badc1fd2affe4b7775ef80d45ff2feb7cb12a9121ddd54807c1587bea92c8ec3bb40d154828071b6e417fbd5511957577aacf68db03863d4776bac2cafffeb84b7b9182131aabddc536355432bcf0f696a9aa126619489e1c2f837e56090a568740e2d036e1ad58ddc669f3eaeb25d781b0ca4a2309e5ffb034be64faccff6797b8a4fc845ba4f183033f1ab983220670ffc2231999ae83ffadb834c048dbb4d7fa5ccc3bd941084927cabb0c7ae5e10f7fdcd441232723b42a53c91c716cfd60bd1371d858f58b717353649911cd818916db570b2c071169ebb7653c9c590d438783eaab595ea2702f0ce7b618fb342fd2e44324ab75a30a4e6d5d41dd8d926328e96f99d871e4a368dbdd0b747bb8532b48be47f39a153c69b843532a8e93d7af5d643312d8e5b5a0c4a25f42219acb58f2a70185476e6e08384c5c6f49b77819579789c11ad80cc72568b6c9e9ca2dce874dabd6bba4de1b94886a49fec7cc5493534bee914bb968949d4e9831174104147cb09ecb22bc02aa12f5f38d0b5f26f0053046901c43f244c279943ba89b11e1f1c79b935d56d06f6bef29bb9aceaebb31884f5044cf3a013a91e663af156b02a26eb6f83c8cfabb0ba9646523a610d6fc98009973a394195fe11da460de87f866fe5573402d801d4f263ff9965a7280e28bbac1fb3a91532b116666f1014580a361bcd554368c3ca907f8255487d14c049ee329f36d1c965f0fb871c65390ce44bb2842a5678922df7aadef656b933226b0e5f49f1a87934e662483344f5b90192273be59a78d50521104002e0bb4d70665d566e48f7448cc15fea67bc89905dd64d560c9edc3772d7fd0fe79f04e1e16e153b4c198788d4958a48c5bf6907e77553abddebc4d936111042d296b4a8cc2094514829e441437056cd6627d8e24d3402595c750e0d6bdaccf61142b9eb40d792fc1263427c75c4804ff7a085386eb563553020d5a2d91f2b938c451d0e1e46a5e477f6fdf6230c4eafbddeb1e129692601de45a6c59a2902133e5f6a230745579e1ee33275b7949954beb877d6213b8f9e936bb6029697b62096eca3b90903a67767f7171721fad61db7398a629fc90e9e847224950390feb0d01424edb4a4e35b638e838aa595cb525d25225e5b021ec60f55019655ea536c72983be55d13bd4e96587c7ed40f3b4f505f0768d27f3233e3826a779b6da96ea128905ab30ae2dd9a9274f0d2b6d99e1d25bba5b08dce4414451e17b3fa4c6859ba8c4afc647dbedc69b6fc8b76d45f0224eba4fd5c40dba0b542bf719df330757f504b21a1aad7f1d401e2a5f83d2c6d2def10155855e5956be4409a483234b7c34f32756ffc36f090c50992fe760a384fe8b8b759e16c0e65b8ce2469aad7cc75aa3126b186eb7be7f494dac0d612e66872435f5ae50ab6971f21e6e8e22a4029135a61b7984c9f5f7c4e18a0410c3badf31e95fac7cfa3d154312c3a4682813c11462febbe9dab5402b434a4f05e49f052ff85a0d4f45bb7192106f45466f5b20c3c70847587331ac70b6d0f4bb56230fa6e66c50038cfb4624fac635162f6fb87cc1cec3726c00722b670a1efea68938df478446285c70505ffceb73aa508ecd914b96c4918556a269d38f495a8251b2b0be5adb91bfec46f849b060967363139e2d45f127b22b0f8439cea55ae51766bb3b92cfca3f4180bc8a1ef7f548bd86c4cc348b8544cb3db6ee5cffaf1929356d9288cb80407e847082711ea1d233184ae64a78a6a46ae59a4510ca760ab19d7d4e0ca3059ec005c0e864e5589b654150b015d2d314b519eafcc0b80c768df4e54836a95ea3ba878b035b0a05ac8826c5306e3659bd8126f5a261dae5b3851472b3cb8e118dab83603a556232584de2ab5d5cfac6d967120e469e0a249c2a84e7c2aa22391db067a3a275dc2a092b81d30f0fdcbc34faaf08bda5adca3346ec6454a80d366e899c2f7cadb8f4033ef6801f4ce7505fb9f5e9297932d4b73ff34b69074d344473edea2d1c4925f5c2b53c8436839466313c99b431c4a191275219dcca464842fd4a8352f4bc28ca6816e5564428a218d1396eb5f4fb77fd978bb38af36fb6e95a205e34cd60cfdc31d8d3139427e3707d7c278e09dc9b8a779e465269b1a008776d0858f259f86cb188578370b958c4bb8b76a169daeffc32533e6dd1c2de30d379e0bfb66a448b0f3060859cf1e061ee028af35bf19db4166d67846564c600ee1b32ed8ce2f2804d5646aad46f6f8777af521c4dd6a0bb77abcdb88c74ed3e9aa987517d220108b1a922ebe9bdd0598967c5d22003d678dfb92172a40a02c641e9346e75e2312cd96e7ac7691062d74ed5b2011007f14b9d6efae4e95b3ac039efac873f07191ce29a3a77aac664ae8246c66268b102f78c60330563d7a56c026214a8af6f2dab6207bcfa4f7edba740107d51fc2eb52afa264c2ddfe1827d1a1d7748cb4445b2f45b4bf953239bf7e60864399f74f5d24c1561c1176b8b564bfe086fe44fe158da0ec3a66ebcda0345bf73b5dc84a4698bc1c3b5bf5181f49cf3c818972d1d5b58802a4b7314b83be9d99ec89bb4015c386d96e87e99b3ced7eee25b9a7a22986e0843d77aef9caca912b5d0c88f55061380ea1529cdf84a222eff2e5864596c8cd9124646384f0cff8ce257aa2eee2dea3c3845c968e7b1c794963ab7e0908141a0d262886a99bb5fb9cc2ecd67c5574ffb4e7cef3e257c8aacc503f343ca9f02380b6e2726d982d1591818417dfa0ecca45fde0ed31a94b84e858415e52e22f5b9766a6daa8ec656da88c25c5c79700a6b9a107647fbfc45bd95232a2bdf60db1fb6bdf309bdb0ccccad1f11efb5dc1711d7cc3edc0caf0ca1909cc8283cf2a0042aec2a386cf7460c95d20944ab34213b702d777f31df7d266c3b12e63de1627802154a13eca949db37729d8d5ea9638b3e2706bcfdc5f20f2f822940ccc657083040464a9f93aba30924406880913b6f50cc7c28ca331d8d1d02f0e1def8a485517c0419fc11c39e23914fad2699e57923472d7145fd0f06afc16b379d8bb8a69cd0273254d470cf70030ce3fa02f1baa7213f2c34953515ac2e0ec98348f36fca03d91e8697cfd74614cfccd74c7e4798cb3d28bfc961136e2ac71ea2aebacb81bbb0829a0c07f672be14b67c03d8d9f31f0e2f079bc71de86b8b96a0d04e057fda6d35a7bdb49db820fd89817a7a9a28a5521eaa2d59858b96cb65a380b589ad04836f715661cd76a7eb5fa6c9f6d0a2d59634a960fc11538d24812af0cd6afc0d4b093f1801b6d001c24ce443e21590c524d303000805b45bdbb0e03447da1360ac21ad213a6027bc06c3e10587b4e26967b33564b96b530a58e6a5a8051ca179fbb5547e2e57a0d43287cd018565b6b75ee05ae07b8016948de2c4ca919a920991e025149b093a8c2fdc9ff78c7cc9406c25da988d7193b2bbe45cd379fed3a6ca7c322b05e4bbe017f1f2fdd3b2dff9d641e99a3d566d6134550196467e4326a20f8d1b090b8009c3633d80e776b2179d52854d461e1a8929d1e5096dc8743cdd1cfe7ca31ae14ad046ca127e58a3097e81c1dc164bf8e17d4829cd8de665a551a0b1de6c4d5e094ea71ee568863068de987841de2327e4b70d7b87d846fc1e05d1939bca72c93146344659f71332aa2166e1ff3417077cb28429b10d1c22da1a2ffe7c673ce6ce8fa1e66f22b1e28fbe63a915a507b095a8aab9bd16244cd369d39451dbb5db4145a583f48c2d2a7365424c4e77ad4999163905a029b4ae74f9a8720f310a7d4012a44aec6af7f92c71f53f5e9a9d92bb8329157068338468af607b2e87c5e3a455459dc62ecd7a00fc3a18cfc04b5e46c352bd863720b26a9369ca080274574e2766041555b8cc21515907e700c78a89e0f619a757e999b034773ba04951e3f7b70ddb668d91c8c0698815e16abb03d03ca9813aabf069f6ea2a1583eb4ef5288d43257e704ae86f80404db7822f605e894c5997382d6adf78ad1d86fec29589e76e887142ca7caf53df09fd1390b84365b0ba89bebaa1aca0fc5510538954961b137296bcfa152db73535223a74a4ebbf9d25eb30c726e450229ec2bf5a7d06026856c6281c0a62e534a486ea8f80fd2ccf5356a8e50f54fd2677db304d5220fbfcd29548d41b91a9971e84594ee5bef6577bec7127915eb0d24ac0c82b0d207e565d5b130d4bf2f1b50230b381934c79ef5cea9f8ec62c7344b17c91b3fbbf0f85753f70ebdd44d7629623304549ba870cb87bac1b9343d114855e38c4d9ada3d145541990aeb857eab77e2f70e400ff1a8bb12a429b3647749339e20a044d26bd685974d10be43e38266dc96e9c543670040e9443eda9b180d4a8a7d95f7d05ead92a4ac3d23723de7658e57e3d5693a945dac2d5962852c65fe9eb597ea9b06b3395f5d1132bc756c03a1b5da16d1e87705053bd9ce85a9d73412ee9aab365298c5cc7b0dc456282424934ed9746e084c088c62ce9467c5b0b06338b6dd9215b763372b481fafbabba955234d57fb24d9e93bd9e06afca8855a6b057f998b3e58f3d5902dd95cca4b81591a7bd3c8ce56b2915d27dcd51679cf75d43925efb841a040bf357f0d0cc86abcafe2456937483f7d5b58ddd0dac538fa3fe2342ae65669f760a288f9f523bbfd1e24dbc76b196aa82164a287a63a2970b881454a346aaa0dec14f963cc01bf266e801828d44584e73d3b94320fcaa79691c947539aca8a24bf6d9c9c693876e5f9cf7cc807051bb4d4c21b53bd5da722bf7f58a36b964d03786e4f165e04faf96b68a74e0f09a628f297cd9c348275c32d1dfe014aedbd76714faef4d670835d13d71bc14a868a5249d5c94c8f9a698afdca73b3a0b8808c4ed165f9a5552a9774963112457136bc5be16f2c70510dacccbe8a8dae3b917518f6af4a772d573e18b947a8af60a601823eb85ca0d83d429d7ef7cd186b6f555203a9729c067e422178ac293c12158962c6c03842f021ac12960562090d1930e50943f6b202ede345de177ed4ed3b36f485cc931ca5eb7bb0efe1be5bfa857a41381c089f7c31ab085328e55aaff6455cd76bdf74cec0ad2a706c47222ff2aaa7de08e034f88fdb6c9265b4a29a59452060f064f05e8056fe9929f4ff23cb951a8526506cdb77ea32d50a8e2350d30dfd61da62ebc4e6eb2a432f6d8715dc1376b49e5eba796c7d66bcfadaed88e55d08d22ac42d349a0c736271980c342bbea6cad5334dfac3fef37eb37fdeb60db21ea53fca9befb767e4c807dfa1011ccc62113037aede8fa0875db05e091c8f49f3a6680e9c8fa10127c18e2c310128c48301f307d82286c1c8eeed8b4b3761405c2911d7958a2322a53b59487274e4960c4a06f735d8ad7a4d2086b243e3b0ce86bff94e8db98f08baaa331e85f578200d37ba309f37712d276eb49d5f1f873c276eb2e36055d40a03abee3766fbe0c76bbddf62bc6a027d0d7fee3f9f5f99e6f9f3fde68c2f6ebb5ea288c18291ee79194c18cbf30e6d66ef7495777dd5eaf1e23e98e3f4a736b0783578192086b6b558cf17d0d773a9fafa3752c924915063d12104186e973249201a62318d62740ffdb19323d86b5adb5adddee2b1d79b0c9a0153fcd39270913ac3e4511767392f0ed38518281528abf5efdc784f9b583bd734ad5ed18e38e247debdfce6ece4942f50e6e9500d46f55013c6ab09b9384e954ed2f65e1ef18c3c4d7516b521b7c2c4c9f63d57427a4d2d26eb77bd2a25d8f419fc4fea3a4a9ff589faf02d3579faf441f8fa41d2140abbd38574defaedbbba1edbb51706e551d7a77ea2675e10d476ce709c9b945e2276047d269cfdcc20ea356af7834c13a75183a9f9f801d61d09fec30ee6e97f4934713b05787f143fdb6dbed7e97f809e01146dded766fc71feab8dd6ef7e16eb7fb3a9223d8ed76afa34ffed011c9d365afab4f479d12fd3b924c33fec77a0c134f3da9baf730ee6eb75b7bdd8f1d91ee6e8e2aa04e794cb79a3e7d822e9474da6eb77b3a6a65ea79a14a7053880b7bc2f0525532bc33be513c69664aa03ca7f9d9c0565a6b6dc38dbe23377e7829a648c1a1e6879427301a3b8ae8e0338315192bb12d3562778ee7799e1785a40a4d1db4a2744520ea4bc8961874e4889385871a58a21c3132b342738351394dd92f1b5821f6c2b2318354a13903121c7632c49adb9c1ee004e3032d8d0b61d6c4a0e5c0522bd346cc6c5d34ba72be72846c25192a6709c207f69ef09495f6d219e79c73c6b203c9e76c85735416d09c78a05f727659da861cb6160491fa9a210c980db46e121b1ee440eed54a6b1cd3ca87d5102bac2dc46bba57ceb060396d3569af1abb26298a95f31496016d870796730e2ffbb53515f62009db4c59e51ea2c072ce5987a5b185c5c985fc14e2c29e708642e4d01e58df7703dfd05c36ec9448648e95225934cc98c1e2a4c79490106c8cf1d8820108a719dcbc91e2c3cd072288e3a508950f1fd28cdca0851b865c2a62419a3cc881dca93cc881bccae9172cb2b04748539c1c3abc6e13d61286858700a283e389d5cd063872ce19890ecfcb996a4e7d4d894d8d4d954d9d4da5e170ca0ab03a6269c8c25b6bad776455a1b9c585e5c50eb01c84f7de7bef1d984ae692cab173e50712ec39799003b9df9cd6749855c656396e6c9db5d65aeb2f3055689299e10c7ca179d72d87f94e799ee7a1d1aa42334ad797d818129ab29c6f50ac0de5fb0a2cecd13da692d868c0f2c2ce9a929c73b6a17b6435e51db308980f6b15e2c29e30d4509e3170669f51f3a4425cd813864fb58a191f39e79c438be79c330e1daad0d48ae2bdc0d1e520543583f2eaaaf185c52c3b612a32990a4f210085302d64de10b1b1a6254d142968b059ce535e235a588295c52a889919179048299b52662fa4d0bc6c28d953daa3d20526c4ca856bb5ad9688588098f51045446dcdeac992303435ed2b2aecb1c156b69293af88e11757c6c23651c07ec0e94aeb41447b29e1f182f274b5d65aefc0aad004436676811d5a0ec218638cb1a8d010c5a13144091324374c512f4faed8b8e0799e6725aa0a4d1d3e866029c9ca19b0b2b51583b132ca0e0d8d0894a3acaf7cc656b87a54b3a979430e0f7220c7e15b67adb5d63e7455a1f9855ff820860b71614f185a5d1e39e73cc40acd9d33946faf365f61cf5c43c32c076160a69cb9b141a8a992b3508554716ab86b1ae7d9b5eb8aead2f1f365ea862e555e806839d124376429bb6d74641bb6daf03ccff3920ca942134b49d6169705926091e2f9408b0c8e140e4da684d1209f3d0ce41d75f5ef08f28497f0eff2b8bf8bb3847ff4e6e23cba5f0924eb493dbe9d82483dbe470bbe5081e98d88befd13fd8ea4ad033109e7b89194f1382fe15714a3fc48bc263cca8f4437218e4b23584186fbac215c17dde623d82b562775fc7a093149c9fe2091257cc745d1667331898fff884a1d8ce4895157bfc7af9b709b97487ee867a965f7624fdfc7c7250fdcdd472499dec74571e90317dd821d9081c293f8b8530a177d042b8a4f7ee45e41f71e9164fa1eff7c4423a2bbb8820c0f5c1c771eb8e8e2e89404b799dec5a524db93e0760a1fbf8e134d8ce4f5126f93d1236adf587cf2230fc62437e711939464bc55a2494936075d474c02475dd55510c484369f7f9de66c5e08a4aede4692c9366d22dee24cb28ee9cbc84cb8aad3e6b3bba7064d1ffa219c4fde7e7efed56fd4d5cf9f4f1029467decd99132fe3ce72ae2cff3a8ab3bfee9781ec9251df1c98f76becc32bd9e5d0b923ff1b3fcd2f2dffc6c37193b62f6273f5a41860374c61de83ba3d3ac21507ff2a31d9f479febaaf6efbbe988f3288b641593643d2e25a5907dfb1e5d909d8e3094ac2efca414b26bd7a30bb2ef11468cf0a92e7c3a82a54bffadade9eacf1a34f7d6596bd1a2e0a6aec1f036ab8a15412b705668c807ea4655450e22fa6e5a67d7d1c93fd6ab1d9a12e2b04854837c070d4109f5a894e2b5ef3197dd8eb80d4d09adcd37ef8f7e2ac8a3cd75f5ef6d86b7f91fcfed5655648cb348a9125dfbc93e9f29b7b5bbd8a31e993e8be4d267d72299fdf6e59b8bebd86d48b7ce4db36f6dc2fc3cdee8cf1984abcfb086b5d65a6b69a5420ce5a0eabed65df53beae8db71522f59ca1e849f6596acf7448d5d5749ecd5f55d7a6facd61393741583fe2dd9e6f644281156f0a044b0ad306b089e7b62f5db6f9deff883649dcaa84cbbd6b16fd4d5ab49fa4e3576edd397e8d2d31208aea75e7dfbd6d37c5bd259cf2fd0e9acdb3c46f53ccae0698ceab6915cca696f73bc455db535ebea6b9cd3da27282655a78e41a48ce9d674c4baaac017d709d66cc23c81aedda7a01e93aae7d18278d7a01f3cce5183f926d0f4eb79c612b02f62d4c7a3b52246ca4bd8b5679164fa3c7f89f41c8fba6ab361512242e8ddee0f21f6bb2f98cb9ec5189e5f18d975da2df644a5f95a544af176d4d5af172ca12255c7e30573d9b32761d7d5cfe3985d571ffb1ec9ea7be9eb579c382425ac0ebea83d385bebf883547dfcc17e6fd97707209ce59b45cf27b8f1c6f72798a95ff10af200f8595ea97aadb7f92dbd90bcf5ebdfce0ffd10da2add493afbd775f5c9eda0ef7182255ca4ebb691b479f5adab6ff36f484a9874c78b048a4950d8595b5b5bc339bb4dc4f7e623ec55242fb9f4365b92aeeaea83180841ffaa67723bde23597fbb57a3fc0824ef7f1ee547d701e0b8346b08365f9a3584ea37af3e82ad22769b98dd139564bc9d3f95c4a9777cd30066429bd5818b5e502e2d67470146418e0b6fd43eb2d38d58bfe3dd7fefbd3731d6628c2fa698e28bf1a423a65c18638c31c634bfd9b1d65a6b6dc5855f3dc6feea2754b7e35093903ecf4f33326d8ad0a8b1153c61da396647d2da91720de120fc7e9657a27e3a53a5b71cbe09e4d488d953aeb20a98a75c4fd1beb4a2e4c96dc5aca472f6d689e8eeff05e5fae9942ad13525a0a74e9d9e5ed15987b2c2595ad1a4a6547ebaf59b751c96b78ec2ab8a59768179eb406fb73c9559a4442d28012ae5afd73bd67a6bf5112a9d32595c914e9945601d95f653b7930575ccc23781b8688b4a43389d1a992c54a04e4f8dcca2e92c54a05366d1747a5576ed9e725d3de59a2c5498b3684af93b2a5d9172cda239d4249ccfc34565b2983f47af348474050a55b24c21aa02852a5c66d07cb2443f4b32459e0ca7e0286e4d787f966488fc0b7808cdfd2213e47159645ad0f2659f40b4524b2bad14db4aebc5bbde6a2badd4d24a2bfd284833ddd4a3975e5ae9a596567aa9a5955a5a69a5d8565a2fdef5aee096c5695500e66c0ac0dc5cc19caf259c787bcbb9bd53800230972911270073db04604e8f71a19edb24a802fded2498b3360198f35a94a08e718d4004604ed7b1253c2200735e084ebc70020463521f70d3e38131617a3ae0c5c381314e466c80c4cf72cc11129ea701132898f8598eb132918131347830b07381bdd366a72ab7b0402de1a54405c05c1633a5870245ec1056e5cd981a54da1ccd29b4ab5e7c5759c504ae18279f04c05cae62b04a44404c90db096272801e04c09cb63c7378906e6b6e1e3601cc691f311f17602ed7305478aa4ac881396db5741e400298cb340c92f0280c91efc3f4b079de083a57228491d2a9724003be2b068039af0518c209ab588039afc502324f199e2a05b0b02bb6f7c5236d2ac09ca76d08604e7bde170f84045c30595870002330a72f98ad112c30402d401198cb3e477c88866e7845000d064810cf95e709008c140fa90390d33784131e01c008e6740827bc126d0827243da7c9f4785ed61f8039ed0198cb148c44f103e6b415a2cab6b967f34e8039af0af1e46301e8f916e96b1325c09cae42e0f020096a16b807869e9e1c2484d8f1d8353b79841d03c32f60b71d9d9fe5172a3a399d45ca93c57305f2fc2cbf64f1dc2e7804ac9a5305b6d9b6ed67f98588cdfba263c4fe3263a785ae56cd56a9c837a3e52b15f866b47c47941961c190a0ae6739fc4892033956a094399a5368d35ba5955a5a6da5957e14a4996eead14b2fadf4524b2bbdb4e8467b80436442ec57af303ac28e9b2cf06ba2a220be7a5151d50f2222fdb3f4d2f57a0f81391d6a855a679de990171bb6b641606e5b2f572ee8bda900c0dca640800ca06616f20bdad620fbd9f8de3aad12a2ebd7165e6ab8c06f9de2aa21604ed32d04e6b4cf522c2dbff53a03055dd41643d54bf3be14b616f583efbbddbecf368bf22cca0e7af0ad9847da5180df9a2fff5c151de4b107abe63ec102b7efd58fbdb5ceb3487b9e45791669c7b328cfa2ec9e0952bf76b7534509d0451e730394313f67d0fde1d303e6b405261b1cb85c59d2a6c6d8d9d19c42db00604eff6774805b058180b9ed731655d0057d17d6d6eab9972fb5950073b69c776f60b75b09f8a9d7122d7c6ac8155ef580b94d02cce9902be41971afc29cb61f0f5fd501c19caea012f08ade28a8048401cccda2ecf7bb4734053df75e679db5cf599447bbb5beaab3287b9d457a1665a7b328fb9c457ab4d9abb61f90efa330dcc03c6e16dd3cfecf52ccc757c73f4bb12a1a0474819f7a16e70b600e8435e1ed672906f533df9eba531f6bbe17d605eda12092756c2faeb859441d378ba6634ad388cd781223e769ff2cc3da8461664d62c29cc48499691213d6252c882c61c2a4a6be84b130f5258c888d2f6147a4bedc301e5e07a91b0bb69f651891c79561476a7801ea92c5a52bec8bd70416c407e6a50bd7ee82a509acece2e6757e965dca3ce946f889cb962d624358b0167bbc25eda98aa5a23df8597249c24506babf608489ddb834e9b02a3a5c747e965c5830c285446e7b5c452969e28252a48b930b45ea7a9003b933c1ee41976aa77af47ba9950b632ebca1f1264d7339a27180727707b23f4b2e3c9e74231c85b9e8a0c1858a06d63f4b2e505a3603669415fba8dc5256966a4358f0254be811e40895314ca444d16052394790148c703831c61ed2788c4bb0a7c74d47f88e55762ec1d6bcf7b30423b36686accc6d8354e0b2f9da7bed9b28cbc6a986383acb9e565c7aefed962599bf77a82b9ca11df3cecfb22cdff6b32cbb7096212a5f52004291b5660c884a0a463e346839928291d84d6bbf9e97b35d6d133ded83745d7b76d6a09bf6fc529c8fe3dcc7e636dbbdf4ba09b789267c489be3fc2ee96a7d1f138e73138e53e1a3a5ebe95f2d5baec7b7b82392f7775c4724975ec74391a42a489453412848823ce15e0e020c10609ff6db7bb494bdcd7b2ee882e9716e13afcf6bc9d0b7dbdc8adfc5b93b6e0cd96755412fd5d9b75e7dee7105ed19037a9c56c80a51eab75e2919ec2d3390d82d631f080a7806ec50ef06fa8e488fbe0956a082db77443aadd075901e55318b7e459be79b45ed37f18a3de3d4592c5b763e2470bf7c73c6b85c732ac0569a53bbd3715352ae613d39c5f0b55bc7dbbf4058fdbb4048ddfaa66ef6d55c830098945d19fb414a199b1c46787864d4a2e6b8409416465504d60f31305c3655a9e6e3ef258a23809fa5da1335264ee4c08173f3195182e7629c091d520f4ee40e7676b5811fa4f8f974ac93f0504c5b7b6830a76a3787aac6d69c1d95cba91116e1b4d3ce9aae579a9a1a358d0cca2b2dcceb428b2a02088e0808341f3888aecc1e7eccc131258e952c376c1c695d706940e0f8a8d1dc1ac104fc00132210e44035688407a469a5657d0e923c693425f4668892064395b42a1fa8421ca449ed90e694b5c624ce12375c663a1041c31054c2d42096c3161c80e8c1ca13ae1bf8a0c4890d9868e98065c30d34fc10e222368478089220497c34b1dad2c1c3d4912828729ca4c8d975a53d6944e4240edacf6aadb571cede5a3b9f9c5b2b6e1dbd1de28c11051152a15cf587195fa3ccf8ea1fbe5dbf275010c484d6ad6b3047b30e9b3c59648c9da4d41bafabc0f4d7317d4ae10c29e3383db9b3d0b6beda6aadcef4aa6489b2d8fc6d60cedb1ef69c8e6412f6ebf9d314c479dcb388fabcde2c7a018b152b40568cea0aac2535d850264c0d607b6ac43d6dbd600398dd0b6bcedce00104b5e3e7aa488d16d09c9419b3c58685001421bcdcdc20062e3548dd70e81143181c9c68b88216150000881b6ac7d5e981c90e438c64e192b59f7a44e07186eccc17133332ec1aba0612235fa4685185d94e24ce3491e18c5a94263a84d84d3ce8931f3eb2667003856ac8a6915d20a64717acb118ca7cd93376806ca95135264a8d72ef78ec10e04401b91a0325e4c99a138979099b51840d5f566a1e600992034c4790afb1393c3e48116707355b7478128395b41461b45a984104d85a0c7276a000f2c4860f1d48ba1479128707cfd65690355a3b9098ed008747070d086288ac356072680305ad040a2e4dc2d8a80147899c227cde802468c264cc4a0e6590b81971f6a19064ca922142e03809d2c684561a1498304b98e4c06687b766876d6681c34406316084f8f2658699587821082a24438ad090a5e644106b80f08222c30d333748c3234cd3c30b674d5ac072068d0e9117998eb4af1b67dea8e932a22b4195cbd75a271065b26d88737c31c645583dbe3d38b28a7111548f2fc618bbc9222a52c4eebe41b3d68d9bc73f4b37664f863e2767a218c29c513833f33c22ced0c0d24d0d1c4432e833448c8800c10043d566ce72d04424c428c4b90715a0c9bd2900110539d33ad3218a5e7b56c313d190eb40672c9cdd78d28d6adc13fe555ab3ac01332b239a5aa39bf4106bc8f29a34529b524aa9d2b54e73e02caa3e8baa4fb1cdee6910ce928dd9d7323f59cc59e267c926cbe38a588326c566061b29363b9ed8f48022b2c126091b18b2d7b7066dc6962ad9ecd03f4b363d2e9ee19b75d61e280be41ac1b71cbe9f659b27f98631c6e2cc5d2bb6016b436593f859b621a36de46c9d1fa4fdd6ebdb919cc1dfa68fa8ca66d1c5b4379e9f659a1920ee6799a64a47fc59a639b293a6eb71651a227c843f4b35509ee7d93e355b267e966ab04010d4d9517306809fa51a2c5fcf8d8afeb334737adc8d8a297e966633f4dc48902041a2c7a73413c34d16277e96663e3cce6ff3fbdebe1d4915be7a6abe59777e6e21b3f138141f02ba6e10451901114519a1f1a25243d3c44a0d8d112b35ff59a2817af0675916a70c08b5322a6a6550d4ca70a05686835a190d6a65576a287e966536ca769ad2595429d2dded763b8cabcd741a00dfb7f43f7cbb31ea67a46b2bb53adaf588ddd65a9f1819ed8c88661035116146040d22a7b5126564b839738ce600cda13866bec8ccc0b9beefbdf7cd073fcb3354fefe2ccffcc0e5242fc1676a88ba6ece5c455937e31918a2dc9c6921cacd191e4e6e7269268d99312b381c1aae88331ceeececccec86eb41650ee4d8882dc847960324ab01e776ef55632b23d3579aeebd60ca64b995f172a30c9781722b73a5ac24f3fafcb3249bf2a41b8140d839555427edb573ce592b8cfabafab5c5bdf5ad935557bf7eb55043656988208208a3216ae08166082238d00c71e3bf9fe5103b3321ca6895917143e68ccc1632568e944132c496d9c5f7de2f7fc9b4fede92cc87bf40d59691d1e17702949ba8c4eb9a2a6a1022c50810000000c3170000200c0608244194244110835cf8011400095a924e543228a10444a130140c8581280a621808821004621004a3108603599e4379006f08f625a52f948835d9a91cf4e87e805b4d6f4df601d52d4ec33bcf3d2d3cb2ef4fa9b91f13e453a7286cfd7e8fdac537da566343a7491b1cc373e4b609d88932d64caf92684f9c1034e1d0a249b244afb01cd0faaf5e890543d89466a24a107bf452882f2f7655c21e63184f5a1211b5b7854fde71975188f7dfe82e7626de93b73ab7205a3e88db850b9ed2700fe052e8227d43892d0f9e0a890df5a8292dfcdd9c319a368becad0b221fe3d33c420a543c767b20ddfe5c764e092255a42feed35312f4bf3144d892cb770951a74d32648585e0da50e8ab43760ca2e7ce409b4da4706f4b8b06731862c939f45b5a5aa71b3e8867c6f5ac641db00cd6ce4e1b222e12dfebf302f45ee3e2d9ac0cc6ad6d7d4ab823b4b06a5fdef9ad22c8adee66d72d36d8ad786c782661414b245898c148db51440d011450f010ee8398131faff942ec5208f7e5ef2d1ccc21a262a20cb37a500841a3031097ad9f31483a2882124a7d18101198160045036a53e505710e7a3168e594c5dd7f64d1398afcdb0fdc23f5ba786357702997c9c5ddcd6d5dcffdded81ddeca7bbaf9bbbd6df7bfdf1bbb83b7724f377f376eeb7ef77b63eef0566e626a3f0e16c337fbaf1ffa39f18cee60f6c5246bbd2b22f01f85bfecebee5079eafebd571fff9aad298321a14848d670ec65890022d8cf7d4f62be8c0b3618661945fbb2a405c71d2c938fe25d95ba286e9d4f2331374906c68f5be2daa789e8528d054e053941107c14d5c678e05c3ead5a18ec07b3ec040230766313faa8069b20c3fa51d5e9eb27931cdba7796860e2f58cbbe8ecf560470f7310e3cdeb508a3d87de9a87aeca0e102834ab3e11b9296e0a3a9b298010e095f65f4ba53c2c2cf8600b69d2458dc159b07a96aba364a935308e1d0268d2e6f9bf189eb43cb4d61926a1c0073c3823cb6b7d376abd199cb3532de9876240c4c7401d9f8193c9b93ddd927f3807637c0cb07eb8e2639ddfd99c5bd22df986b29663626a20a30ec9ce7826e278953010f7f2300f5556f619473fcf97638470f9d64532c1b2e142876991e660667e5105037cfacab5670b835c418e009bd1fea3aadbc60b0118995b0b90fcd06d804e1eaa2005c4baa5e0ec0a7ea697e289f063f44252ae61e92d5069a44c3f3c0f2c192f8fa8edb0c10b20be72a73b5ef8c765af2c9941fc0a8db7d2d321d8214fe2c548ba653ec3cf7c25dba3ce1155eb54748f790bec9e87d2d11f41e83414c1a35d1a17c99e47ac3bac0a1b3757a0258a3aad9b1f0551b16ddf8498b0eb2715daee53d45e4772fb3dd9fee4368de2ea00fd45bf955bd2b4dca24bbd71975b113df686187fad43635358bf0fe976cb36f3cf86a3de28fc03cc35f141da38c9e6450a1f4081578f3f04301d68b7d5a2800960bb15471668714417bdb2039d7b2d2789f11ef588a2381ec7f122d7eebb1c3157087cf1e884ef48f14b7a032a4e607fb04706330273e0dabb033e68fa6725ebf0962426a4d04df6f55eab0db04f1c406dfefe849aba0c61ea22ffb307c79d75940ece2f8cea004b9826b80a72533d1a795a3244c3fcfe326120233d650a87a3b4900d8ee18e7b59a8f7ad35e513acafcdf96cc1a5283cea440c46a326f85bc4d489b05d0de1db35b54b76e4b31bc76b159c3f7ff51e1660e9e326cfea4e88e5e376b2152df47b7386967e694e57f1775a680f416f8bb63f83ae6219b423a1f5739e91e0f645fb4b84a2fba1039459fea0e70a618044bd52f66be2a7c6b2e2f8b9adf6b2a3fe8a3f2f3a7ed93d59eb3fa9eb137a246f69f18415f05ff76397fecb955367a248a54519099e6bbd81a0b21fa5270b0b85ff6e7d993e6f75b7f67aabd8f9ed41485f237278ade530d445bff18c75b85ff7fc2f9de27be68f78e665fae71601be0dccdb7ee91117f18fc46ee142690239f18177ad42eb53847210a930bff3a0d56d72547cd9fc03a30dbfb49dabf82fc7bed842ea0f92e9d0f90d41b320c2e329d4690cf682e8ae47866d63c0c00bcb07237ebe1a216ed20cd2e9570d3efa86ff968e2f962fa923e2b15671157ab70c8fdbaf07bb229e33c2d132922d035f529dfe292dfb8956c26c632bbc66fcb21e435e7409d3d27da04ed2aa043ab300a267fedcf7a96ee874bdf6ab1125ef22a33c8a36cdfaee5bc0305c94604e52f2a4da592a6a59c1f4ca2c583f0c87459c07c344b4a48de1dcfd77d0f08c464f42ae4e62002637cf83a0eccf104d644ec545c9582047d19b027738d00f2ed5510b93c27be604146f3d95e207f8dca8eed6cee43786779a57831fd86de207a99c683182ee11bb6e1acff97e521abdf913497f063ca2e616dddb6a2bfac013dc1a982ee576bf4565af01f4cefe7412c19ad9dd912fe737913110040c4de2d85ab80db42ccab34779d582a09e8522a70104c8d88d12751c020224d481dc7651f0bec65e745638835c539c06a90165d6def00526e1a641277fe3d17aad37c3229f345c2deee09107fd449ff066d17201a95e194cfcbed970359ecbd949f8a39a83fcebfc10b75d046603bbf8b83f6dade6e002116f63d82f71f9c3784abc1c3f2a252faeff43631d7818bfc486e057c117587713b4b5b11c6989e10ae4f565520ef49d5811721a5e2dc8033c90f31299b78b83721a3a39dff6dd94a441374635b66b3ca41fa23fc105447415c0e561e45bc2755ea714402b7e2e1bb4dd55a6866781b6dcf21d705221bc764621fdc95844111d660191010ae80eb3170c3a47aefae9de817d421010892f9af0af0086fe30884891fce2f9f14f4f8cea0edc00bc96bf4a3e32704131b6aba03055e1135c25687890a19cca4b8b63f20e7842048daa4534863b80e3d39a73c03d12f49e8f265262a256f36651730e8c4872ff782a1200097d92203e24e1156ff35937922443dfac89d4b6ec80164959c4373830417aaf5db1ad5df4b2561695b89b5dae157857c1f0b69635107800919e869959546152853edc074579282773d03043e8f9ae5d1e5f4163700e5441bb6fe4c9de9a663dd70d03e7b0915db4a6fa5c582c71db6b0a0948c4ab3b4bdf01d249a5cb5b38dec3da6f88c9e2186f95c3ad0425ffece3e04e380fcc166865285e67d20f4c6e4c4addf7c05fc1061f13841a2982ea494a8354d27827790d5589d111516ae393bd6087192577c8d57dc9969cb9825debdfdb12fe70b5134ea01b85b7f14ac0bdacc11adfefd5baa661de989898fc06e6592c00e29700e0b32ed9bde950fc166dda832ad7ba4331239a281e25a61337fd5feb61900e036470920aca9e2d67c2aad8cf4727f4e613dd3f02c7f802c19318df719d543fe6d3517ac181a6a347b4ebb2f9507367149ff3895d96740aedadbdbd2f44066c564a8036f731457f571b4c0fc706b476c29b772ab2aba1e8f62f9d43a716fc497b602f17cb4708555721f80ca5a46a001f17dde0fdb01c7b771e1f02d3cb73b833f601f8d5d108c43fc9479017dcf36f242a7c4ff8639b13585c9cff49e3d24fab2e47253d7f39cc9a57ad2546d5c53fc6f9516a2b14f1c31f832dee4196f1edc98d6402c949e3a1e7cee8bde2880bce3a582f209ff609c7f1e285ba2c60c6886b82d9b8558c6120451aeb7bc254adc7afa8ea87ac48a52f2b949173130f1eb32d208a10671872194d3cfd8d79fec66015f1ac3f384426c6396eb9eef3144e459c539b68e9fe79d8f0295c504e78d58a5e0377d513000b0d28dc92b67c765a906168544ce77bcdc3b5ccf06758c27c1641103c5b86f0f5483424d44cf614894a71e02801eb2fa757bbd5c0a661d40047c8752ad9087c3aa2e42ea5990d41a63efe3f40e15f44b2258e3adca0c7beb74b35873a70395eebb7b138ceef7e8c02f9e26536f1c4ee7234bf51034ce338f65c04fdc1c57f08f0a72a884b225e09833430f5d2565566edbf0f28f8d7a16097e31711f9859e7c9815c63f17e6f5e4c8b3ba1ffa74e64f602ce27fd408967b8d11264c8b0f283fbcaf3a4751981e45d2ede514808974f1599df6516e71ad2c8a0ede32a0350d1abdd6d238d537594124f384f6dc7bad8172ea026a376b5d4ce47b144f6b861249c80af9949c9807850ac769d6c7d57bb00960185c899fb79acd3dcd896756d5842fbd2937c437d3413d517f06d79df13d9d0a82a310577f76115cb7ce8f183a0488c29acfbb2270c5dbb873d63e651fc08a0a2ea50b9300430fa204f4d527c93bc13a78f8b181254304aec9919c15a1b27cf16e80fb954c301857b01e7f438effe7bd7d9f1d9b77dc9d3fe6ff58269d59e5df21f3bcf57f2cdbc4cc43bba61feaec9b6e5e360ecd3baec94f689ca7ff694bae5b1042127e91897e3842438bfb517b16cb48c9194b7d7785cd6354bc336d879323a2355751bf1d66eff21d7393752a040f2103d5635c1a8ae0c790ac8de30878b64ef22a5bbdc5fe652e9668de6c7744b258d21e2e7e9bcd199effd4858c2956fb182175e66c579809dc0b0abeac765d1b637818b6f4f32510c672220788b7a25b4e2bdd2e430f69d893881d4ca51d274e36514a3550436939f2a9c0bd90ec3c53fc63664a4c3038714a5ef0667cbf5b318b15ca28eca3c3c5cf206da3273f211cbf2e9f8dbf5bfc651ef5021145594a72cda05965ba0d5800692a8b220f104db55839af75c0ceaf16f4d499025f029762a8276271c3413a21ced80f784aed850c286ed166c69744c0bec04b0088202dd3f3cbe6a7ddab11bd9e4919eb08510d48d32638a3c97d01eccf7aff0d902d7935616a35392fd9ff1ff6c3d0b05bc362c63d466f0f087015abe01b838d07bb5ccda1a6c653a6d3d912098b8414c63a9bc263260a889259724a895f4623008181bee3bb060e97fb40e9a1c45f92876d28281e855352949800f2f41410638338aed668bff597401d05a4b7132d88b4494adea600b8e511fa8103bc62143fffc39ba50b69a32f1811fd4f05c3fb3f45e312e8aa374494acbdd5ebed202d3e5ad841e35568e081091c1ecca26a4fe73c74c644301117a3faf662b3dd8dd49055d05b1691958eef1a7cb3e95455d8712745743d274070b67654a0f242ba1e3c5b7d94333aeb1886256290e8b0383326fac8cf4d4f6855316046979c9c705c4f6d8f85dcae983952f8a5a37466220985a8db6c9c79c81308fb1603f8afa5f631d01bb6b1ed0910498fe369f44cfad48fa7338dbecfff4aacf5b4af05bb3ab2bd779c46c139175c39b00d03844580f37bbd0c3974170a42ff3a77781003b754ffcd2c21e82f7461f0522396e0d3592ed83ab75a7ddabd88ed66f08e5b48c6124963897a829c8792771e13b8ae9eb53f7d2d3b05188705678a5f4a432cb55a7674f5cf23d34994b377aea71cb9c5b570cdb2c60fd22103c79908875410eda70aa732f0b9f997feb18761c70c9362f0d8ba5294b580f534d3925f35b0e7d3d9a1250d7f05830894ef2e45d06db64355b1fe17b0a388429ad61e864c93b72a1ee94bb5c48c02941a578ef17a81c0c965375f333dce1d7af1b58a1899265dfd8d866268ed80ddb500f320475d38a06459d4879be976e8fda7f657846a8e822293dedb4e89a93c7a965e48e21b58df6d4f019480120112204db01082eadea8d3587279845f21e9fca1ff6ce0425adda94afe106f2b3089ef95e088eff329b3d69b1e68ae5c78836af78e2af38f7bf3cebbffc7ec138bb4cba69fb5fc3354438a394d721b5b2bb9218d98409ca79adeb7a8ad271abdc95e036a34de06410d5187e480ef7719a17902fdcc970e27903b58d10171efdb31067d98f72605021ca9ba6fe8316d59588e410edc4e21a5fd58687113823b94f49b6f8e67d06391640dde45ece52890794aeef96927d9c6f826c584b880d8b25c0702b888558a8896dbad6135035c70c2826bdce0f8aaee34beba7df23a229628c9487c9b814fbb34384bc14e0f9d1a8b25519c376017ea0522201a9002ec2f0ba8b1d98903c7ce8387106e0485fc0bf9a25dc0c3028ee35e65d53e7a0348892393e599761292b3b4589d231998ce01d7d70813711dd4e8543bdd9c631aa84d51462dd4c85dece81a6baf4791c0f0c74fd7673827b6e8068f4313b96f4006b7061fbd7e7bba679b3c6cf1a3984d9d318b2faeadc4db92dbda621a0f8fec3b8887fb4332ab5dc64aac7d0e9521cd3a3370c6867b3cc5846a21a1649a76734af2ba22a2852ce15b0ab53b6022d3f6f5c2c5d52f6d20299302e737ab6aa4f788b785c19fdf6284ab9bdec3d55ca22c9039e83a809b2cae9ca098013dbf489fc3b7e8a3fd68ad92a2a47ba26e478d49f9c55c0427a9e2bc970e8c80465b30ae794be41c338289ab6102a4d108059e03500fc88a65b5307f4efff528134fc3bf3ed0b3f6dda14faa9a5218e194d6d2beeef229795c8534313b9be8a29e56f3d0363cef8814a31a13b873615f56cc4c4ca0cca8013ea56a1632e52de396aa9dab565b15538221aeabdd3094e22f9554fb6d84e3e2d39fbefd30adc835b8d0b9b7b96ac0ae194b4e2612a466f1078bcc59e50bf17330882382284735daf404e55a5e710cb2f92e8e21269efacbfc9171798ed1a39ad5bc23a59613ede5be283750d64b3eb62cc2b49e8201a62a2a3f255668d4f75585913144c832becdccf64a1dba7494d94716e6f695e73185f0529457e7c967493cfa6fb365c50df115c33aef0eee52c07ffe50384a208a9662347cce083e28c48bd4ba36a9f185f4ef91a3bd85fbf97b6e1c96b10f9f59ce03468035899bd61f9753503a4d74105935ea8c2cbd206ddb97d5a1fc1f4d4558041f427a0c8219aef47a1e05109dceb79e3eccf4090d4520f599ed31346247c5aee8e09fcfdf8b4d84cbce98bf32def5a5c2c455c672ce30c1f31f2d3fdc21e5be3bd85555052d991f125e4509826ab9ff190ed51c7b959d636456f20111a569fa29075d44c58df552227a5bc2815abbca36f535b5ef380d14ac95826688542774e5b7bdd7f8675e6a0e4e9ba85368164a4f508023811c835df08c85fdf908c4f5f5c099ea6225c7a1380914a33c65c5287e392993afc3eab4a91baf82c4947ce631d09648998f534f2d2780d4f4e8b2464cdabdc7a5ad5995735a44b080ab6b82ddab0f4f36466665929a9ff34565ff06159becd0f696d7ac246c750e36d7a6f7854b9df58ca295dad97a2066af1ca4c706b341b8cd5d90c5c5dd3f85042707b66e47405c19ec9a37a7e9fce015207a761c932f11cc6aad441341f29dd6b6833d490d4c6437cd36947fabf40cf55ca5888498d774033adab5d92e766807896948cb1dd4029d3278370a24e8e28c8884117195254238d531f6ddf04d634f8239745707938c581eb95658582266563928be82482a1f22c86c4994a14c3c12a01d70d827703e090b0caabe13f34cee6e1bf6ce3747ed3835589e7b1a0e4d0207e3bf03baee1a4f88b1cd9b9f229ba0f47be70e85258a6759d36da31e27c1f017480295217f2a5f6af7b026246696c99a7f8bf49122ceaed3c258514ee00fba085f6a2bee10d69f2574c27be352b5389b1f7e1232c055d8fc5ecba40e36785dba784f59696f39dfaeb18fe6e738f2896b3849a3122cf36292fb9ffa108ee0a140b0a5ed177c06939de4ef1db3b6708707d16b094ef7ec3059a454d8d443da37d1ab0fee2bf4c0cd2c31cc6a667840df26d690dc65c78e14d956605ba29beef803b87e2bd550e101b0706cacf77832b56674d5bc429d5b9fea85a919e12f74d64ab2851f54821b9f84789b187dafcd813a4d73f9bb7a869ae048d031eacb48bee13485b910d88268bf068d753ed9b9bf62d2d2bbe9229186e82b3a24a3aa10cdf4045484ba4fd0b0c96119535c5835fbe17d821fa3e76e016d5a67755f9cf9d98010b50c95ebda505f2754c3ee2d7b38bc398dfa81e9d4b0dbb3a38c0cf2659db4ac786a216fabb604639ca7833e7d39011c742a12c7dee8cc14a3faf8b43d2a29a69c6bc3e1eeba9ac3469e4dc672b360dab155c84db6df08ef16b263f2ef264bc56092583431252e1bcd0c7e4b8b689535d6cfebadd0eb04998ab505d93e3c2713d4f74ba7fa12f429b674c3f3fd2b11369df79667840c09d0c53259edb1b9e99ed7c9da418b9ce3346b03b80d8d5ed68d36745c12339eb03bfa0f9f47581dcc67393091525429b08842a16d53c57211e606cfc9d2c64923932bb2560885f8ed8149b09ffc2837ac7f654ea49ea2a03fc457fa3c98e78cb4113763aa6cf85a6559f4842269fa96b19026a33e0a93f7fc4f42405eaae74f2f9b3de7582af42db3ad747c5ee6a72b28e36ad50bdb5ce98d2f9043b6e42de9954e15c8f4f1686ee2652273b9ec7527b800e4b2279dc242d4c653b7b8934d6bad3cb56fedfe5ff560f2328160d4ea4f30704026f3974125939392d595cc7624476ae9f66ee1997cf0d3e395e67d5baa43af7dbf596bb3380341314081a3d82a0726006ccc1f4c5ab85f70585d7eb402f2a13535776807fde8cec59141882cb347633c198cd31e6a60664c4e749f18443fcfcdbedd0e52c4d1276440c47d8ab9dfba245bce3681f83f552db95d4e9e95883d007032b2638ac1cc972e6a796f4852c5f3b69b7eaa6ebb26ca62b54bb181533fd6ee5ad331cdb711227589ad63b43254284f79fe478acdef813cd26b0f86b3b093325f2412e1bf68589c401080d833fb97113e741d0e427dda0af9721742e2ee89badd512d9effdb9cf8bbccc1db77103974f07ac4512ff07e39473de93d8593be55cdf78c88fc91575aca8e387dd5c46f152ea3fd14ca040e65e1d7e48e74716ec3a4df6ea7604b5dba0eabf15017cf221eb846a7e9545953906e3d868f366017f08f76d53dbdc550363c6ac6f57e19cb34d19acaa6e8adf510967a1ecfcfc00bfa2667a78103d3be1fccef7d0a61a66ebe4294c7563633f99eb50c38c4dee1f1fb9558e67478e072efbc257a454a716cb1fb7bb1b9905c2c55a9ce7e0f0110fd853793a1c8082feed4e65462e3b9e49eec511e0da82171b0baec5ec8073600c5abec0d3e1d482a71f73c42cfafa8f1dd0d63fa3ed483dc1b8a87698eee95e6b9323dbdb1f2bbde05f48d0d9c7e4e596e30da07422f458b3cdb8827b41d9c9d3089bd1cf1e9dcfa429c6dd5c2f8fe5f20d151761a73267e07ae3df15aa6ec951b0f65d69db94139fb9c76ac6ca00db0893dc880b8fe81e8e1f900787f90596aa97dd72acdcb00ef67438046e38096398c53349fb95a6919efac8d03d14c41b183205d5568cf86f7e36ad2ae17ebdd3abe6ddb00ab775047d3cc8807c21cff016025ff9f145ea3b2352e975cddd8bae00f08a0c123ec9cf2f31ac75f45d30ffcf9b5d65d7e7e338ff5f400e80b71ba45eda3f60be08d71c484c8268b26ebeef92ffb3baeccbbdbe0355bd5fab1220f29c08eaa40c96a8aeb53fcdf4ac84585dc372e95eb1e6060ab8c6730b4ec04d05690966679167e79862304a8fb717f4d05432a9ab6082f7d35e8646cdb3eb69a31bba7868870b7871ed44826d4fe400f1c5c43537f80173a49a1088f8abdbf171f16e41368d3dfbb8c7b1cce0a85232440e33dbae5f61fd7ddd17ebaafef2e5e06617880c0054e000b2030fbb5ba4a02073aca13eab276c1e874c376e2a2b76dc7d4923d6905b65245297165d41a55e95c30e623c0b2d8815b5c9986bcd801706f6b9261fa9b0d26c1ccdb8e283639600a9d283cc8e4bbc4b9564ef7df332bc4f9905797a26e05e5cd7af38fd655260c32ff83a26ef1746433d23dc61259ec835af1322767f06703f2e6548d858321e4ac4939f8c2c77bba97c91677b3607b231d0c774fcaeb9394dfdf96c9a899341421c90f4e14758c8a9a048d125aff20669fed7b0d474bd44caf74b52a336a671c493db06c7c92a8c1f379fbe2a8382bfac44d244fec0e84cc0d61a7c30798093b78c538158017f884aa3347092aa17ea04a0e3151fc40fa48543b01e00b85d8a71f6aefba7a299a49827fbe147f9ade3a0f052cec21a0b5de196599f4fda1f050e6633fbf267be3c63d997e12c00f9c84e322d22c6b94a226a31dff4823267a748cc81eb9ed25589685e524f629c5c69ea8a3fde99e60f68bc92739b5c6e76c6dc1adb3bbd7ecab4897e753241a8098f1c2b97dba8bdb0adca96f9ea5e608509c4d44dfcb60eb73f40254aa577c1bcec7eb270f9d07b4e5dde04b9cfb41df49120dac2efeddf431725c44bcabc887a98bc5d5bfb7e873e442bb1dee089a00b955970bcec608d2851637fa5d0c11c88b5727c11fd2becd04cbd493c666b77eef24949390b5df72ce0fadc30eccd3027f67a2363fecbd4285becabbba57688e361fc1822ab6d1046d67ec5c44ee785a1eeac309296fcfe39b33c275e7e502372bea67d7e4b8899a573198e0194ff835b19bdfc91ed42687dff87fcce6997338d735b1c019194e72f9efc8aa4a2141f45371790d2a6a4c9b5b9dfddd693f556cf28ebf758ea235268d712fd9a9f1ee0e7efbc51f7ea49e15ff3cc3a138c00ddd0559e6c9d93f649937516b4d630667a2fdc345c1bb1c1d218e5bb96f924271bfc2c359e6089f136c68330eec2d46c3afdea2ef18aaf9c35f5b12281635f88c8a6ba24b62dba60682027f826b3117365b3ac7b37da680a707a9f955f98fa417fdb1589e36a471c4b7c7f66f9cf73a619885618466a4db06782bacf095a564ee030959ea4a0c4e18f861e0a61c657c2afa8ee3a97b98e67bcca8bff16d76769cfddc16d37d163f74691e65e79b790ba4d3624cd1f3afa601b50cd72a52067077d31a24145638b9269ffae4ff9564d2388d3f63f917a95d3407850b3cc464737060a4bc6bd79937ce2498fc21a0f56963bcc95b34e578621b9246604a6eab683367bde78ecb4edb56aff1e3f11b71cc3d5bc75279babf9bf726c96ee469eb290793d075066e2142fe4d03c09f9e4da606077404f91b0382baebe1513a7c9e78fbdc9fe4d53bdd50ba2e3d8e2ad7039e61d23928247b29ed788c7fbbbf2748197c4dd173c5576c6443d630ba44f702429924ff2751666fe2d34e266eb3234fe3e9714c66aa2bfc16cd54bf02b827a6f16e41a67bb87c8a87ffe9233faaf8c79274eb1ba74fe85fbeb8c2619975e415e60df508bfe7e8c8f4cc26e34f0367aa1070505f414fd9897f828378f7993f380e0f7b2d672dd2fc5df4cf200607f63d5a4b0caf05a001a9932a53b00a8370802fa03830a95e4ce2578f304746103c5d9b605f0d6bc60793165b214dc65e507c31dee160af1f207ca541d98cc67776368152f50ca6fb84ab326283d00f220a93e7c931e615feff41bdc56f73a73be4ee12531407f25887fbe693b0a4b6aab279ee25858e139838c1ab0404cd9407597d45c833aefaa2771760946c16f1e3879a9b4f29dd8c95d8e713f11a3a49406bbd7d6d828e0bfc98bd62cf1d1bf8e36c4725fe19941dc9937e89e32f0cdba3b8946c7da54063260ed9df879c827c92a529796c412ab0c889999c50729d28f042e0112978e7811e2a5c42fffec9c68668d577d89fb78229fdd5d97238cb33259b33c700f8ca52a25209ec3e10c742618e219105eb9bb6735cf6f1fddbab1bfd0c8b05c6e9484ce5599a819779a6b81c386730a87e39ff12023df3427bb02522f80456bb8e2c7bb6d948b8810d8a80acba3a34ccfeff4e31bd1c2671b0e555abbe6b498deb0a0d7d07ea096fef8ce84e4986eb8b7004141642c85faae28193616c2fe7b76b9de48db86600b8981c5f6ef747df083382c2f47aef577cb4346547b7f43ac0f41a7372332f2f3234289daea64c95c769769895c7340c38596cc9f5e31bdb5526d9bb24917b5ce6d354c4186632a9d6299e0c8618b5a2fe36eec5e37f2801fd6d84e7ca462385a1ac58f486fc1c9d1832ebbbadc41a3fd0f82503eccf798388548c348210cf69f4dabcb6f3e70c332acdf7a5b54a022e98a81fadca535bc7440f4a6e2aa361d68e3cfc733f679cfb2120f07f63cdadf67f5bf748a71d19d664e555f76a3c7e4614c97555f232439625ab73c0d8feab4f534fa91354acc90dccfa886b3e71e3454a0ad183c0a486c219122dad0c7488d17c88f88f53d65ceab9834eaf8166a982539b69b8bb82bf0c3b30e9a2e61ca91202752277e207319a35691a4f347bf1d6fc56190a3e43cb59e447c41e2aaa2054d3fffcff323a42789e3f6218a4c4162bd1e574121b69294acb375c5da3b70b8b010bd8a629ae64054ed83d63802813bc8af9782146efca9565d7d32ef466cce972964afc1b6e1190708292ed48ba12085844f6b3a9d5a31b0b2641271378b5e5d216568db0e19c735932d15ddf7ec63e91a59de4e3797dcc628ddbbffa20af29563e64e78313e4f2656c6f57ac414730df464ff451e603e5bd2d2b8bc6ba62eb3b2e1e710f20faf2a0c232f4f4c2053dafdb14bd6e4fac6b212e81d23f510a4755e8dab7e8f543303a1494be1ed505b366f28eb0a93c476f02605e0ca082c928a91057112c11d02a602c7a37623cbd4d599da03434f1884fba8701b9323c642f0dcf983e39b5f682e014eca3ab06d1734aeb415a714dca15188dd88b473b5b06c985cc481f4e96ffc4d54f1774d75ffa9a7d58fa7bc53d5bc7fc4e465a9d8e105900ad074a46ad711521a3d4d5bf278acea9a887ef789d962b17d91dc082783d0314f67e4952dc5e0cd507af0d98cc92ad91f6e2d1b14b395c70f22494713ae3cb38ed9e6028e859bb379fddde512295d8220cd7d16968dc3d7db1e81f6575a7a63988839cca6ad3857f1198b2054c4a775f756d2c3fd60b922ab2b34fd3065cb487ca5b0f19a0ec198a45fb2b4b9efaf8dc82a260a741c148f22acb2aa7b6ef0909eed5f7292bdba20195ed81014e2582511b88c7c30b7a0334216555d712149fa73c7cf034a6363c3fe1e18687ccc22fa64160ea2165933a4a7a09033a2a4f71945ac18e70aa68be25493f37e19d9e2adbda64a9b3db6314c47461ef63c69d024d5d1c9bf5ed32a350ef6787b722bd483e131a1eee097f49508e45fc519b2c0780bc95f0caab77379de21097aeab9e2cfc5720f47fca642370e17de94b0830632b1ad3a28c98c76776a019d3708d0a6cf276777330385716cc014e04894fdf4c0b52cee7d30bda21a1dd22d4756847447b57975ad120205f30ccc1900a5a0b9b439e46428b168c2c05350ee1c4061e7c4de9284aaca9b0e2ad5f19fa3314c26ee93a79b560a91645ed7a6774a2af802865dcd6eb6ed4621f96ede841c6434803764c3bcd27cbf92ff7ea5b76d77a40246c274cd83f37d7f3ed70481a387e1fd6deb790004dea14dcb062f3f5975943ea801e12887f364a76a8a0ece689b2c1d589ad60fbf6b1e3105bcf3b111cbfa39f6b01af73e4cc51f2162631e79202452c805423938ff5c1685e26ba5e0882f6d9e1eff0c465a5f571f3a181a20dcaacb49078dfdb9bc9aaf63d25d46c9cc683c352e40d1e19a929bccdc4a6b5125d2a7929477d57756cbdc1e9a3e72655b5029aede61c395a29f566ee33bbe66b0217b04c2597e4cd0218b436abbbe6d024238d08e4cecda778d6e3e50a5754689d3bb4aa8668f1bfa0a101dcec9edbeb730c6dbc1e83264ab96b6ee75f7ca748c876f72e3bb75f053c879497bde09092dd653237a79515b4d856563482a13e969ccc9d37a8627d7227fa78a7f8a17939bf92574aede9e7658a80dae2439228f95b2e3e2d26e29583da6b80d3cdd3d23f025729a2322dcea557d531583ba9112dc0e061bda12a9dc07b420d6f7d9ed44e0f2eb8eef8fe34a96180e4ff7a3d51a365a2cdf8add5a7569f0e01a2398c1413d3bce43134b0a43db1dc09133ca6b7b4813b7bbe553aee80265f375a0e8b0219bc710255e9c52199b9de6547aa4da874aea2d5ed1552e3cd13102ec625861fd9c0d25c9b7908440c582613b4a061d8b19611b0b25eb7f1623a2584ee9f5a64fb9165047756f7edfdefb841b41844546f918e694e2c46b278f30801e370da56434239909ede42d6f5b61276759949c9f9ba347ac972de480de83d49d55b2c10749f41da528f1750508b263a956a5d3d3b35417881bd9044a97dbca8c956d3719e38f34a9767082a2eb3a299381ee90cb65485f76c76848bf3f47ba156fb9f9f2f0c869f163b54f84583fc84e74c1df5f0e5c708afaf324d24dc20ab3f8d0516f30df92f869c4a4100e318abba7540d5ca3bac2424cca56c053f0a5837810712f9462fa8ae765a5139f4005d0b460f318aabff72a651fd6b4700946804265eac12461b7703386c04fc3e4904925df87d8d7e35e9bebd192d8fc1c04854d81f9b94d4c3d2196e4498f85067fb1f97fe7030262991fbefd912909e6041cb7def18c7e8ae85aece40418ccee42cb1f1843327d60f1ff419316584a2a67771480e89334cbd1a6b33fafe419f10d55dc34c597003f2ba75043be6a725f83aed41ca91c8d709fe780145f4201a76a54bda0cbd22030350e89a3116da16a6a6ea7b763eee767206d057dd10216c39bc1a51dba4d007b23dbf2cd6325c8ad3aa82d6cae6a5287806447dc143273f500998b85400cc27b350c27c262e0e38f0a50033e5e4a9cc95587d6098fb1d2bcc104df3f1f5e8989c8dae1a48540532045e742987591e2bad48df05036d30f35ef3aee01c10d983dbeaa944ce5f3406a141ed59d5fcb1561397129c48323a965dcabd89127ee444b01ecc83aef5a2466dd2fdc4b59a5ca3abe50477f42bd881bb9abef562a7761f9eab54c04f6af33eeef4bf240d158b0488c4c19376ddad59c4c01e8d59bb022824539e7a00c67a8ebc97a3aa9f582c3ddfede0fb47db07f297a6340f0a8e9651bf416fd3ccabfc12f69ffa81ab0cb04817cb566ea7c6f2e98109d278cc6552492bbc8b6aa67b885e9f38694f970f7504cc35091f20a97ec324b8e912aa3af3d03701c0137826aac74c548dd55a05c75323a0f950efd6d29717d2ee7414725c5da0660791248fee222cd0b0c02dfb61597e0ee9e51b809586e01c1390c60564554f1b9d0f1ac86a74fa59834d0ccbf386a0cc6cf644fd97b4e795990e53a5cca75f7a86dff1ef33b8deb8be9290a7da49805921d3ad50db89d1a7b3ad1c7ae03e2ce9642f69993c144cd8e5965c9ada5c5360098dcb008d84bfb33e10002b73616e34cfc076ec826d8cc02879b42f6fc94e501723797dbb816627ad5c48f7e352794feda0cf77fc1c65e4dd6e4010efa061c09d56e7ed6e8e114676b50a14abbad14cf2a664127b9199d42c543e5ef4692b9ff5821da9f9b6891bc74880d07a0953d504ea3b5d27fcf6d062d1ecd58f495a60458a4061ee440dfb8713b34cb5065eb18392851c69c52420a5b0615ec80c0ad1e54b7297504273aae6a4c434b2b83ebca82f80870862959315e11292a5a8414c99d6b1bdbc7ae66ac0468a39ac90342357159307b1580b2883b6ff98b4e0caf6f8816f94e94a0390493629de113ee80cc56670866aba0ff70c43057b0921eaaa3a313cd090d8862b60ac688c16f2731051c1844eaa168335b6e884fbe093f1ddc0c707b714d750aa4909a91523a8cd9504a2e3a20c0bbffb753ba4212cbd3c3e0e0ebdb6a6be818a149e114c5fbaa9831ed830d80196a00c4be9ab8d4e2f3c75266288936cfd0b27fe1adfcf500f4d2cd736165e80b765598297a57f28ae75e54480c96d3b4a39206f9f900f993909c28697b553601a150d33fd921d36425483618e00d07b953ca7a5eec7b9e0cbf187b6be811a159d0d30bf94e3e03f209d3066dabc90a71c92ab37bf6c8b1726ebf32adaa58b8a9ec1ae9d3b0d5df3a504f2df55f72c2c4c7d24405b55f81430a339b74e40e4ba5adb599ac60b1934a785ddd2b7a8140896571ad23c2038464c8f087d4d3c81902a14b282695f3027ca72add8388c5d21b8257243d666eee44ddb1b36afb76c05361bbba9087ec58f3a9f5a993fe467d2b8fd674a66cf05264c09a52ed99342145c9615b3b6e2eb85a6e2ef96fbff37f0286fe2189325627e8d9338f4805d089edf52626d7be864964406fbd39ac2ba5e3125592a7a338d4a5808e9b3961de474701222ed554ad18bea31b4286b9d2f2f2a19e34f0f71ce6136cfa5849f05032660014660e830cd012dc1445ffe19ff4c158de1216496446ded1793c296578baebe6c4d2e07faf117cb0a52250589914f2da356311186b53bb6bc2a36f2e43cdbec8114489f9e1e128f0eaeed7b59a531fd45e91f423b7a26e3960ce64cdff14e48898f806366b1ffb6a00468e6095034103464d86b589ff2bca59d92467f245fdfc69b034df08ef5f56445abd9f50cbdc19e80f0e55c6dcfc6d19ac5bb598e5183ec69d7767f5666599eb295c1ac3bdf2e735d86f094955746592928aad4b2ef59cf815107248a3cb00d62141aaae8f9c3a84322e25f1802030ad5114f6b4c7f20ae4d70e1ca57b2725e2ea060e5a49fca82bad1a209e6508bbfe56607cd1ea35ceba58d02c45c036ab4ae8e5710400b398d01e149323e741ce94282775c1cbe664cd0cf78bc3d3e3038041707c220e96dc40f08e2196ce00e3a9c734bb965461c169cfc91795d7063c9ad56944c24484b530c129166c027bda4edbdf7de7b4b29a59401be0976083808ac9353cd9e9740ed11037f37087ed23e38a1f688859f341d4faa3d62e2ef1663e2276d76729eb1573e727cdea8f6b0f7d159a07a778e3c69201557b7b97570cbac0320ffb02ecb3f9975200bde9083fcf31d1dd6330e1c30182c76e3062c0683e1c071a29a33396e1c7ae7ac4c26dd9df31da24a61e10db7cf5d2e3dabcc759ac970bb7c5cb7d9e7f52a16b9ceba158b62076db893797ec5a29d83532c729da8c6ec9c7356ba52d9f890509c89e26c0bc5ccfa4c0c75e48c0306c3913fc5a29c43aa830bc3ccba8ed0d20c7e9073ce3860301c19fc3399e40330b3fe41fef9160efe65d669fe60b00ff67ddf7798e5e0cbac73907f7e7078457b9bb778f0d3e79c33ec200c070c8623e74c2679107a99750fb2d65cb805688bec9e58c4fd070cc5a22d003828166dffb1c71d2091615907aa1067d63bc0f63f99836fc9b1bacdb1caace7c85ae726a918ece02a1c6b0f1c27ed66c57cceb3a393734a4feb653528ca681f168002a954e32880cdadb3f278904e4ac18f7aad95ea8626996c1bda27cf99e78c757bbef29c2e9d3d653cf94746ea107aed613faeb85015ce5d69f5e34f0d975e6350e0ac330093a513b0b4e795bccc4f9a5417327016c648bffa9cb3e452250a971780a85d239aea140e58a26d57e2eec46927416c192597a62d658ce145470f863e51b1b0ac3d4b2c2eb858cec04e9b0cdc0e9d6a082f54e28b022c431688aa3d4b1cc850b5b09a325e61853eb488c81197d031b353f278d153e61003570e3678814eb0a8180d3e586cf070830b8e4d887360f297847e224727c50f7705076b3ad8ba0000f8464606101a1ee810e703271d51661b0c415c0d3bbe1c84b804a0fb22002ecc00c6f0d89e00c14c8f2a7c64f183734300170c6d6200c16414603bc30059d608c1298814224e866d032dcb01b61f10e079293242842d09214c8c5066081509e0b020c28502362f16805fc0806d8c226518d9c106475c20817bd28028231a1cb0617980c743095d906c4440e00813c444800909909980190aa0a9c01516d0e2026d30f045065ea0013cc606c8e0001a1de021ce094e1e8842c2705443920d870ff48002e60202292525588204d298149e4832130215a8508a60e362052f580869ee61043d8841821ed4e8818cae5645ca55f2a20564e28416319b3e5c4ac3e446dcb3d402a7052d3770e173d2c483a1e9b3c1c9d3f224e5c40828259e744f4091224a29650553c0a062c60b3eac11e504860f86186e90c1d352456a06303424514315ae89ce4a1457bc2a6cd8e2062fb0747b963f8081c30f64e4f0031a3a401967a9c5cd9ee50f37e8b2dc273b6c5378d8828593a187eb458b962a5f36a53ed8227eb8466ca94870b967800869a64fc6596e11b3c970d72d68367d1844b9e58a2e21cd5bd4d02e34080a04e542b7d01fa80f540bed81f24077a059a80e34078a03c5426fa036d02bd40aad81d24067a055a80c34060a038da22f502a740a9542a35028f40985a24ee81375a24db4097581b64099969828d5483002165610810a21484a0169891210a0f0812447a4074ee8000736a0810c60e00216a800052620810898000124253cc001460d20e18891220c588002882460c80842442842c001689b284808062800902102fcf0d103041e03104000847604cd747ce001908c7ae1e1059c75f686da4a3fc51e33d35d457a2a7a818728b168993f188b0ba071e88efa5b430a640b412eecb20a75c80debcc8bf16e3224aa219e43ddab8cdcce11118990606fc799c443ee3eda6e0f762156a1ee6e88bdd4aa30d64becee463bd61280d4623dafee7acc5927903a91e81eaaefe69c75d634f0efbd07f1ad9a5cdad75e9188266dfd148be6d0b5b4d2004e2a83fd5662a9b2377c70ac3db66bbf7dd364bd1e527f74496ae935d3e6c7062a6e6c90e2829b2b6b5ca141b7512d464bc616639581b5026705576220b45d79c10ee32fe3eaf1c5f89663b86779858b2cae5841668a1d5dae33ee4721acd4cba8ac041ab88ce5952c54289c999a2b51b212ae4071569e5869e25aa8426f996ddb368ee3b819a2700933581967e08267909a82c50c59f00c3e34c1a2099e5d51420d6f3a2c35c0296ba001951916698466694a19d29431b86056451a5f182a2aba1b64f8029732bc6046c5ce9e659518ca2a4d68b629a680e14dd40da228226c6226862e3786219a988941871007331886336270010733314811c312294881d099281bb80045d40c9e405146a9894243e687bc67f608c65946899965d4112fa0a1d2c5940b9a28f1829b5bbef0c54c89d59e651497282d4d4b44e5f0b4448e3dcb176cb0c73dcb17c0a863c488f91123342ba2a4c2460b9b4549c58a8dca1927a0d4134ebe259c7861ba22382fdb0f984a96a74bc586272a559ea85079a2d2c2940e0d318a31a24c61c113a9295c40494db1028a14b76739e54c9d22834ba3a9062e70cad2a40627dc7456baf8c270b20418181833c41a6160d0c50c42d4104319058fb809d700d54df9d24319a58c32ca9319988e8627700aa6e012b426103540e9f095529e3c990921658d2dee594ea161fb01bc1dbdb7c746ea78fa88fb778bf591fd7634bf4ca4de9b9b7ea9a3f489d9974a67523321b66a032f332f5e84bc04f113a5890da0b0186f9cbc3650d438e902a58aa72e50cc38e952425162df3d4b284868f9d12234fb014a540950ac64114b285252663ef4f024ea095409e504ca05a129a2c062b6eb02ca666bc289a7c56dc249699b70c255819b70e2546736a431830e0a0264bc18a18316694c896206275f6ca5131840cd6ed061fcf62c9d14b1c96719597b964e76d8e438db611cf72c9dc0d093c6c66620b15a40fdbcaec92c90fdb474d746210b641f8b19e14ec2a43560d2b8739ac802d96fd6dace02cd1891796d2fa5df178469f12908f668fede7655f6c5fd7473e380f6a5145cf66bcfd2ccd49c7a0b1313a918fd3c08f3415f8c731fdd237a3c841eeb9008fdd535b479fbbcdeb269265228cc4b5da1d8fcdcb121b7f4a1ae22117a1bda9c635b6246dbe79ea209760d18555aa06d5a69b440f3320b546f81de8c732bb92cd06c02aa8fc58c6c2761d236dd8049dbbee96981e683da4c9a1bdce68ad0951fa1d1f5cbf0b57736c30c66348c76cff22906fff9f62c9f58507d289fb4944e47ccaadcfb11cc0ed33483a17c9262877b964f4ccc62289fc438cd6098c9308bfa89aa325b69207419bef85219b93d4ba72f9bfc65253871f9716ab2f19e65d31a9bbcd0396e0665e4b8321568a229a149cd78abbce9a87432b8b965d3174db328a3d093262eb4000b16512e3811830b61a4b890830d38f62c5b88b3557b962dc8c00550dc38712a5b58d33473ead9b36ce189eded59b6204605b3a69f0a52f108f7edf786650b58c0883922617ba76bdd9ca25d1dadeb1ed3bad7365a775288a375277f4cd188a3795bb6dbbc853b087ebab644fbdee51aed4e8d7cba0947eb6a4e4b340e09f77a63f2aa71c47326db66d26efc4ae90de396b137af88771dee1b99549f54ad97c9ba79e0ec8d966ec62ca60a764ece324a28c7594c0fd2a9a9da23e73c94a3534aee47b0d336932fede9efdc3724d6078d7a3da6c91e982647f1ae1ead8647df05e05b4d0ec1c7b714883dd59eb524ec1bf73a1ed9f37c251609373ee5a2c6bf34d9b3d2a2ee71e9284bef82e915be4a14427fe469f122c523eef44bdbbb7af48ada8b21ceb2c1106fa1b5cff67787d9de7e3c6108c1675d27733959759ab7d71efb23aac7bb73a86bbd63fd870d7f58efc7eed9e48fa8f0944671e948a1ed79da1bb577f26e6f0c0a8414dab85672bae101c27888814f4feb022e3dbe97c9a4290b747b7ac6118ef72d098f1d9e4cc2638f5f9d14da5c7832a9b2b26bcee83b5148f8a35193747b07cf8945c21dbe262d816ebd3cb6f79516f51d8302093599c2d2f60e7e78db1d0b1b1f9cb4623c04dc9cbe63d01d9b5e72d17341c20b12511b5c81734271c76f1229081e6311c4182b31d97e1f625dfb8e7f2f88cfc4fbbde045503f714a4cbe5fcdf43d7ca89b9eb8dfc7eca1ba8334226bb311fc2f7bb9c9aac39f342e370942c3bf796efa096b16ee2d65f2d11a46100e73da16f62ca90ebfa1b3377416c71c42c281e3c61c42ba71c3c61c42b261c3670e21f9f8c4e610522c069b434830d86b0e21bd5eae39abef9943483d3d3c73088967ce26d2ce8ece1c42d299b339849493d39a4348ad166b0e21b190c639ab5fcd21a4d54a358790542a710e218962388790c2212410fce610d2f7797308c9f3ba39abdfcecd21248edbe610d2b6e1398484e76c22dd399b48d6d6398454e7acbeced91c42a273ceeab7d85b3d972c135a2f1990f6501adbb40c23a53c224b50963065182c5041584a1388d977cff2082c6ae89a103b6dca54bb9174ed490b9f73257c235a6dfb146b58d76ad3027137028fb7df1b8ddffe4d7d17f5953252bde36e24fe1ee37f376a1d1ffcb273f0463adf3e6a1ae57d3c4b8fbab675bac6b9f97eefc11b71bf1775cd5e4aa5299a9a94d178d55bbac6b4bdf51d4dbfe0e7e85a4bd754ba268affde690bd4a48cba83e7748dbbea2c4db35820fb51ff7ea56baa4fd76a9f91dab4405246dd435d0375add3a3127b0bc46481acb54016ce54944bc8cd97f11d1a8e66d9e074a3cb0da74734347c995a4bb4764d5c3f46a130b2ae9b6166ad79c86d7aa2d56eba6bb69bc8d24cf72b3709427b95814dc50e956fc38656a25fda75b777b0c87b2b9374b7be4cae003ba973925a391232b7f7bbc57b393956ef02e77e8864f4c76ea4e32f5d938addc675bc6643d79ad0383429fc987efdfb0d55dfe1519de7b121aa87573d3c19d3aebb32a94335c904c9e8f51b37fa5f52484636fefaf5d44a2f5d7bdd86a66a5e474b82ec7c09dd54c78680e739781eddfaf89dbc84b28680d7d1b24dc5a2159c39be79e99abd05b24216c88e87d16c82a6af9b60e33cda8c9306804f1accd69e4e833df65786caf1d89b6c5091083d08c66207ab88a4c9462cf69812130e0efb8d14f05eda266042f2d2359fbf0ecbb5251aec20169134bdcea483c360afacc4c4e730cde4f31bbfa19b9e72fcf598911c87fa39ec93168bdd464c3fe5386c72f0bbab26b98b26e8e72cd1a658046faa49d53d4d2f8e5a05bb49d93eaa43b62dfe836cc402d97b909158207ba06c010b642fcb2758207b00acb0c90e72931507fa29c7f57f72932034a51c9a05ad270dcc643da23ac96eee5527596ac58a15fa653fe5c75eb7b0db5328ebe3c6ed6fafcae48d5cbbf1a77c92aad9b406fb537eedf5a77c1baf0cf5bacf6119ea751bbf91a15e875dcc47cf50af4f0bf43c693e36b2a7c9240bd32a6c9bfe95a5ae5e1264537dd47d4e6daac6fa88b9b946d0a8b0ed7ab049109acf6d1c6bf0b0dff807e5a39570fce1b43e9e9a04a1e1b88f37e79c739ae08c09ae6cf086b73e9458a0d1fed833688791a46194582ce46e4f937649907dfd84e3361e821aa9eefa271c879df44e52355b3fe1f8eb9f263d9d6477d52a6cbbd35b7068166e5c93dde8d22a6ce44403b393898d87607da48fb6c07eb7bc8ef1abbe2ad3066f9e531b9659989985d7412a1a79e94e24616a4fb1c8c84b57a65d7596782a2c0a905ee602b3eb7dd4d8f53f3a8ed8f561ddc048bab6cb045e76bd8fcc882abb5ec79d4dc0596957e3f515895dbf6202d273f182a67a7963a5a0ae141a2c55c6568513d309f1c6abf20d21a682437c117e613262d75fcca22ab3fa0267acc222224ccb4d0e1167e858d929228c104f11687a8a28c38505cccb8912c08ad8f58f95e04c47c4aebf4f09c2a835f4e9421b3f6a0f72b442c75a6537ca6c602465bb04f366d7eba8a51729bbe6791e26b8d689ea14774e547b6253f43951c5b1e553b1e8a7a27ef7916635f9b32b185234c1449b4cfbf5a0a89174fdbcdee6f8eb53467afb23fbf0a7f6f8d1640e9d446853fd7ad594295f8b5a8d4d93aaacca6ed8c011e28073239f60238c18cce7f3d1590255460fcb6ebcfdfa2b1bf5f0b83a179a9e3c02cf199d9c1d6e47ebe49ccc1a5b5b4b68e4a1125778a563d31f51067ee10d35fd7c3aceb3455e38e293f786db8eb3cb41555e8461776b10942028425a64e0ac207532762fb08b19651735e6ec83336fc410420f82b5522b82dd5593b2a2dae96b6fc539a76d0a620d4ae9bd58b62ad65a8bf1ec02a68b178a8f29bddd5c24e8e244e57400679d73d24fd102f1660d1067765dc2da0fcc998228c38c2f3679d7ec3341a02008306a04a125082c4148d9358816bc33d000c128206e00820b07486a054a0a65a24db5246befbdae15949cc0711cd759dbdd7bb9241aa8b2eedafbce765df729165924dd08f75a6befbd5cc6c70aa8b28a801f171299cc474703fbfa24f1193b34ac74a3eb32a11f96c88e60c422b11a489254abb4494a558d098261245dbbf688e1df8df127ad8393e3f6bb37009cf4d931ee7773dc274d567bc4badfdd019de4b163deeff6bc4f9a071fa1f6887dbffbfb3e691c042a9fd5b1988f5c958d7cf46bf57195c4354e98365a693289cbba88f6bc975e3af2d49c12a441900983cc1764d69464d4b852261921c818b15d5546a689edaa32b1c85a7b2f1932656243ec26992ccdaff1043ece4beea990797baa91867c46363ed212da66e38b30db10d96a4fd28d978cd9b0bda4c3be22cc36334c2e3d41c6cbd681e76da6db6791abc95a4c84f94d54afb8648526175a60fad1bcd54b6a9bb47bda1e829c18a3904481c1519b4e61242b6c1c45a144d1a8bb46a98413a5182e3c6e18bbde314a3258ca27a22e1c7a4b409b435caaf0eb36a702d44981602057870c757e18bd93a110581098f1de2704a8d36a08f5aeeff8e0b66d0fa8174f42bda897b6973fef987ba7667b79d6183cc1b4b977f4c87e567104a23d750a74177520f8caf6ae6c9f936fde41b3b9c788dc73bf9af41e3b5704e3e9ba91bcf79c80b3b95b27dcecf017f69b7b6ef34a2ce285178570dfb99777deca4721197e7c4e0cf6b95d1deb5d8ec1fefa3c7830c788848f3d7c4cc7605a84a5adf31891d7592cfbed3ef73cefafac7357d6794f2655f7ce938f5a9fdc773419de7b8efef169e523eff9cb3fc2107bfa7b9753a0db1efcee0782ffe07c48df93b60dbaf9bc10b87692eb66701ba3c3fb262ea03b772b825095ddcfa9ee0a38c1dfed6e9be5acb55673f4cecae3c7be97ead4dfe625d4356773da30f15d749b4353cabbb5dafbf42ac5f976d786f0dde25ff6203123f93d29f528f5b890e46e3f02026a8feef63aacb5a30b88917e7a5d9559fb201fc6b9ef9c33341c131a384ab0eec2a9156a0f4ad636f7a9497b255c469a5465f5e1deb24e95e12b49f2a1da5565415323793457034ea2f10b51982f15e3cd23d41e56d7eef3642b1079199520203c3d39d11059fb638739d4138dcb5569d78dae5fb68530bef435c90f5a65ceea83881875aaac5231922ed797129cf48571962880736febb69dfb100410cd213a87e8a6dc11d7e31289454b689ceb537be053fced604eeede7ab77db1f16344ba6fd779eb5b26bb93db5597ecbed3d444191b0c37b1a8f52e8ff7597d3b9d7346ce59158b6c45c0779a5c0a7f445184a5cdba4fed71bbdf1355f137c75acff9d4f94efe740e5e47c75a8f11112fd2a0e60c00d9dd9e2727b3deca222c6dd6988f56faaa7c24ea4d35a867956ddbc34dc7865c2626bbbb734328d3eee8c6224c279898c02e2fa17190964c384c4c3ba9b5bfdba4707f4a7687b424c84edab687e43d692b6281dd1dc792209b8a0958d2c16972bbdd0e7ae208447b4e1de417525184edf76ee19cd15f1e73ce48d52e1a3267f44ce8924eed986e410f0c2d78ee734f8fbcf7265dfc39758380b43a317e155e0cedb55693dcf157994719e3eade571f3fc5d57857f7aeaeaa0b37f86111b8d77349b8d6a515b55c942870a3ea3ad5491d7cef05bf5d95799431aa1e923faaab4ab27baaf4e78c3eecf2b418d3d1b600ac32da755dd7755cd775f73ecf3b97bd9fcd6df73c6fdbb67b9bee964cf0cb28fce08cc24fd0970dcacf4f10f7feb85c5d5c231365302106136b9a687ae1327166cb6a8f0e0926c4f8a8341b54c558c97ba918708a609c251352f62ca7b26c01ec598e19635b4003dd2d0aaa629c5546492a72b4e6a02de3fded829a18f161468c6a8f4b373ebd32268c7d5f05382b7ee7bd83733749adb5f66a926a926e22916f7376ee3bc7b845b4cb0a1861eb98b36a64e69187919c6fc8a9a6ebc6f122b993562a543fef18368b9a33f6f72c91107382375b68cff20447ec316bf6077b964ba0d92092da63e277dd3924f748a2ba3c7af7529d1e46fa2934d74c09d41e36ebd833828cab7707df913e36fe23d341f270ed1177e1a827d7a9ee6a65ad95816098b9306fdbc3fbb56dde0eebc422efa0e775a0d779777361b661ae9b2a1106d9a031e3fdc765cfda5a67fd06054f2541bd7d77c73a3cdd778e431d34c448ca36d639c639cf39fe8f90475fb14887874727e11dde8a444810274e1c347bdcc93af9ee9cf0adf0ac1c7ecc2178fb2ed424f80d1cab6cb4e1528bda34c0ef344f3a3339dd6cfab3a9fdbe8368d22c99710eea2f1f71ef4e43f2d3a4d0feeaf45d587d8c3e58b2fa31cfbcaa3a1eea805f69f23b47bac60dea2fcf4d392d748500ed838c18c77b9ff60ad9b9432b1689a08eeb6777dbb98fe3b88dd3dd9220e3eebafcd34d9ab78d9261789ac9ef902e0972ebbd7462d5f689d0ed4de669f267671f8ed3a40edde8ddbe713f8fef62c662d1d6d11fe4ea0ebf1fd60785a25142412818e7c711bad1e5e2b237c5bbe81673901023495baff5ad30d41d9875aa6cc35e4ee2dadb7de80873733ae9120912274e9ced537bdc5d6b5556c7aeca683767219971aca2111c0d1262acf73e394c8ff8d1d212850c3f5c497eb424e19b8483b4586a6d9b5b83b4586a2bbddba7a236b80255d9674feba3155ec79539906afbed765b47df6da758f2d177269b66d2ee0da476bb1dbb23d0de6f47e03f91ac7583a326936ad781dbbdf86a122fd536ba6d14cb26f1bb7c64cf64df7c91d07724adb249bc7145c8baadcef656e049efdba6491a3541bd6992d3db266ef6dda59bce57c786d0df22f4f74828140572bf697b49d6712764fb15b7eeb2f4d86d611e3539d708e93eb1c803c13cf7ddc07cafddc11db72ee67095bd1359ba21494aaa6412ed3e7d74c9ac43a15020780d39d71cdd6fa7dfde515c414a528dbbe3cf7b2b4f0b744cce351b7f03bb7fc7502810aac9ef9eb7e1cd6df7debbb94d53287407be4ce892aa8e2640b3c34d4f8fb388b1b241d8b34cc24d125fb66ccf3209a89dc4d4067778fa338758dc75f66c82b067013a0ea60ff0cbf5f54862309705c1d0f33c2fcc47dfec3c2f0c5fa75f62f751f8af087da7c9babf8727aa96ce2cacb53f569aee8fb4567bfa2824bd935693176f4b35262b6cbc052c30e24c9318b65c41850aa2a8ae6c19d326aa0d531a4be8a06123031b19b059019b2deebd3b76c0dacc0e1a54e082cb1316fc0046091a3a2a90ec1a356bdc4cb1a9114cdc7174d924467aed9a3454054e382976c884146c9a9cac0973860b35d600b1c11cf6bc55765411da820b7c31be343466b0823245b0f1024a67868d102d3653556ce0650d2d35f0618935d6e852c0e6068e0d0f52ba30b808830ba61d3e44c1268d931d336cb1c69a1748b005182da0d831650b279aec88d2dab3dcc2cc1650ec90b203ca0e2818632c05638ca1f0ec596a41841634dc90051a38642186942cd66481e60325c66ffa510b5b4ab1e73f5862ac65137bfe0331e5127b7e0e81dc86b76ddbb66ddbb66d4bb3831b1a7cd12587285eca8889aa200c4e64740146142d5aa03853c375bcb8811733dabc81c1541764ca266219258506db0a153da8c1e50657b0a07b028b3328166840b14135c801c6932e6caca81203369d1358783143100d9ac61a039d2d60d8d1640cf72cd350b1c3290d133b9ed29c200d1120ad61677de0d1de90ce3bbbe9cd29ce1f0f4ca0fa273218b6d0aef5549f80c6483fc27d9d3540cc780e11374e614f7b2bb52a72697f01ebd7b4b36799064b53cf9e651a2718c400c60e4e51bcf083161460d1c5c3020cd4fd7f8ebb26ac7c3c3ce1eeb550601175b1a8d2744518ab2b6c3083156058b105973328b5e18a356964a046898506563c61c598d91560e4809ced79f2677b9003888ceea827b3d783f4117f58a07a12ef793a8118a13bea4998b38a4fde15c8790653b7da24655a9190c3364281502cdd28f3e06eb25b6d72b4fa225183825bbac5943161a140e814dd515fdba841ad78a18939ab27690ebb0a608d917e09bd00d61845a05e689b393465b95aeb69166b7b90581f9f40f6554d0f8ea9c3fee620538725daf653db32794d6698f16346694596b20a2382c8b0e2cb0b3228abb0a18a2a33801304a78a261ce26af18558bdb43359497a7f846f871c71f7fee17f07bf4ce3eced1fdd2038456b6b772ea9ba6ad326d58da92882e0e7ed4f18aa549fafaa9cc71849a14d647d048931f250a9c2f0f334488cff541f736aae3e7e3eac218c9ff3a178f04eaad811f1e08d446da4a2713658c322234da29126279553a8418dc6ab1d0cc02ff6f6895590666fc74b58c80d0fce1ac2ea24f74d2cb27d92f6e2b7af32d4694b35b216c24ad76aab33991584fa5941507de299c32e5bf1f75ec81d4caa966e5cee5ec5a2ee134f1d23b22f96520565ec1558ef9e3cca18aba55badf5081fbfca2024c4a6eb84c04e889b29352bbaea446e953b0be4ddb31b05d7de7412d70ec573a73a488b91fcc1719947191dd771b6be8a4482bcb12a166b6419b13ebe356aaa5b44c273b1d811d77b1ee3deddf66425969411eb3a571a5f93325a5d47d75a5fbd9673d57b726c7b4f6cd3b123e3ed1fc07a8f566a29f5dc7ed2d46cf19c5256ea79ec48cec79bd0eac95259c9953b0be4fde6696f6cb2a302873dbb14c447815ca8d2b5255a4d8aae9668abe9810ef62cd164d968ca6c3176c47ebc093d67bdb33e4656cc84d65937caf99863d43a4bd728ad4524dc44234daaaf94d493747347ec5937a1e7741cb7d7723e6a23d6afaeb5ced25624121ad9f9dc463cd7e9b119dfb36e643f3e288b31545a29f55ce52adaa4c0abb292ea3b42c4779abc9be3b873bb23855c737a625e42396f87ef9680d968751dae735920bc6d22110fae08e20a9ee7c87890314e1a8f96aadfd14a5246aaafae94f3d675b492eaab9332234d4e393ad6b5748c7352e9d8f758a78d8c629f3ec2fa65fdc61e30de7ebc655d95c757d15b8dbac611d9952ae9824b5e650d31c5384193b7674945952e69446931861a4c6a58d03101a6c9146fa6704393b2076b56aa9f349b4948816eac5370c0a435717772128456cf9da8727702c598fdf6bd1a71ffea3d13ea3d5da3b4dad43d8c1df13414a5c58e78ba064569debb1b7d6288892cd07d988dcc32e211a11ad4867b585f754d2a76a49ebb513da76b52f635ababeef4b440429b6bca75db0dd27a410c8149030f52bc55cede493b9513fd6afd1ac0e518be9320340feb23f49e56a29fb42526daa7d8804933526feb9644c5720488c65a29a6aa684489c93df7cdbaf0d138cd74bfbd8e31fa983edaa69598e0dfd18ed955335d3d2d90c5126693e3cd6ca9519aa7c4a4bbf70028136a5094d6bd09a57577a13b372f53a7a5ee39cd8426556b914d934b8e92e0578d023ebd127c7a229b56825f7f330a98da59af6a098d8302be1a85fa7a2676c9d6aa86d01938e0f77df105f7867b33a788b271e61451db942cdb942c47490cd034b5efed99333a4abe8d82019aa6b635f3e628c9ed42aa33b366571a7669146e17524c5b8893c14c83022e87a926db9ea51456ca28b49465c204855146b1840b416bca3371ce9c31069c3f9df5517f4fba40fa39c1b97acd3529a31004b591ea56d7a858f538f220e3fed34d55d7a48c787acef3daceeb29fdbd11fdbda7f7b491eb56d7ec5dda8805e24e754dc802713cba46a46bb740dc7534f855a86b52de6be1bf7bda687515f7d5e9a90e754d8905aaba46413d2d10ada7f5352923faaa6b4c54d72cf0da78d6d428c4faa44d375ceb9346395ab8cac9352923f02d5da334f0abb3b252f8ef635692320a35cd6295c2f368b3d29a7eb1403cc818b5524d8a8449c3df3e699f56c237d2544f53c0250553fb0fa0344c9b3fdc6ac9560e88a02dd86cb185150f82f7de7befbda0787aef1559e238de0b8aa2a8fa15c14f111441711445d678a20a8ee3388ee338b258add63bebe3f5d6c156265da35095b56eebf82f5d65e32852718e5a3cce2c16164f1031c6d8a51297c2f054960f2af1b67e652bacc9d541bccae291ead4b5319e26c05658a54ae2529565b8ecfb9db28c15d74ed8c3b3dae8576519a8bd7a584271c6bedf61a9be8a81ab71c43ac6d23150c7b491cf61f778cca408ae34fec6fa8db10eae56ac1b815ad4e409fb7e458ae756392a955e81fa28fcea44555cfd86e1d5a46ba7876747b55aa956ab202edebc11bf3a61b36e3beb03f6f1e098b15ea9ce3acea1e8da57f599335bfaa56577257189b48442cd06bf7a3de7ad1c4d8e2f55a71abf164bcce40946ad7c04a65de3a793b8c4d545708a4531f1ac079cf4a8542cb7953d4d32a56844000080048315002028140c88c40181482c4dc32c647e14800c8b904c6244154a22418ee32088814806a1184388318600630840082169ca46001418201158a2d577ecb846043cf14c7c438620918a066b84dc99b810adb5b4fd522608dab7562a9c3434482543684e2ae184f7720053e0fa25bbb099c630e86ea9e253d24e22cf2a5520fb06205a3b3072bea38bdff101383d761ce609962d3c15cb319fbe29163cfd34a72b841244ec1567e48281e58e78dedd6962e25c31f5d174f9984e107ef44b6d9597dfa579430bb81e119fd5e5ca611fb0048bdd20c01136cd6520cd1d5d2f7680965d00fc0dfb2ea7be4641e0fde1537a128c00e5a801cf37a823355a3366cfdfa1373c326ca6440f74b9ecdb7a7fa4cff0adf64c808f8d8e820dea28595f6a786a5019bdef8f85b0dd0b91d8ad6f2c15b117104d2e9800f1e4f54331d4ee7fb973f5dc16bb608988c721082dcb6c09157725a4d5ada288a1613cfad6864e2b49e5e6d61884974da39bb45d670f293140fde30e14e353c9c228dc34b30adb9e86469172b7108f28f01d92d6ad27832cf6c4bd1e7f026f380318cfa1f1ea6857111a25e84f96a5eb799640d1836f89bda1c3b99c4b4a188072fd52e4225eb2eebb54dba0bb4e5771a738717151e011e3e7822503212650da0f504e75b55b6d0672bf9b9e38684aa5d5780923fc4ffda11e942e141755b0d4c3db57c73aff42cbf65bddf4d9ea6226e14a93d5401862af123730a1d581ab5ab4540e6fa0a46e2ba4cf3e1ae5568aef82369a1505e04df7939b6f3a3a9ddcf5bba07370867aabb44bf228e799f37739456c8c5472c455441d03e73192f4679c9155d22dbad5bdc11690208bc3a31a55c2672d0bda8157957f8dbb8e178c961c6e803e4b1fa72f35a52243dfba9e6142873785c9643631bd9acd931d0598658d2f025e1ae4e36e6c6bf4afe3e3c0b4654e3361da24632834b6c04764095429bbad47d91ab1e92b163266d15577fb439948d46f0e6b55dce9a6c32dcde79c6521aed209409fe2bcdefc98b4cbdbc5b23c4cdadc6d1c3b8faa7ba3e387c6b1bf7f1193d675f9479417aca3d35c84145139815c5943950309f8b5767069cf5a6c828a2cfe29f5dec48261ed07d416bbb18931b4a70c3b98aa20924623461b92225dc71330e809ec9e420a6cc45abab3d36c9055b31d17ce2e59a1ec4f3fef3fdcddfbe8e784dc7a03318a3bc16f6965cebcabadc0f45734ba6c0a7828239a31d0d5e29b2c83ca48cbdf03a5c1c0dcc573cb47f073baec4a8579203466d78788264cdb333e353061ef40b0976bcf502fc2a95a18cd877b695c574000df50501315e9905e2a0e0d0eea9d868795231005a79b337d7e4c7bfc50de8315579b2ef2cf93c9feea000cf22632f0a3bdd2f7e7db25ac11a9f2b9520e7561eb6794217968bd43d754cae53266c9ba7a84cbe3e823e2d4ef9df0afa1d6b7fc9dc719a6933bc89a3ea6075dd69131473f3a15c54f8a59726ac4cd86ab6833b4c77f4a57ddd59ccacd97f8e81f52dae0a6feb685684bd4f798dd99eb0b492d364b22304da8f2fd6a6f342a3ee8cf2ce8959f6078cc9615537dae85888671579d11596cd552a32ee40982e86110cdbbd534333e5b4b0d4dd821d83fdb99434342e0d6a4220a5d991cd6ed3f1bd32355552cf0455d48161ec5eca4394e0d91c76b41c0f5e86cc5cc808471854f70a0e83bbc80176579824aaa1c05a121d56bbc80abfd80d42829f246270492f334d6590c0213fc29e1630bb7ae9d2169dca6a4e62624281c0c7cf88ab8d0c95b4e12ddcf76474c59a4cd54918fd262a38a67a4ff30278d39a4cc396b0773f2845a70d8dc884a7a4e94ab1f1699e044458b466b8f7926b6762e5cd44647bc7977d9600407386f4764cdd8d3fc5a6141246a6c1916c75713d117a8088d5c0911d5589e13a9f905d9691728878f3716430500992e97c55ecf3aaf48426eadf3816bd7015f66d469fc836fa6dbc8bc9763f9b34929ee790370359082575303bedae2ef7100ea15307c9124af2b487f4c36988dce6dc4c1110ff6cae36a44dfab582f39bae77ed0bffda5875a43d70b39df6e266c190b6664732cd8a59dd5cf99af8d22c50550ded7e01e467aec7174e46f0eb511706ec5bbc1dda545b963ae2be154d4867522a3ff6c4bde7ef707051ab4777b96d2e3796cc529c578f57007023492e112defce4105e17836e5dd9faf2392c9e152b364d24f29196bb3eadb04e26c8b120eb458e02d5570e745c8989a860cf2bae2d7c527fcd78fffa2a0ae4a0cbcc3e5dd689b4b15e4395bc90a990fe72c06c49d8d57a74a838c16f50a422c023201350c8e2eac4c65ee0b6ea579a611859be6da66b3a8ebe99366857c2cac83d6303b83a1beb989b578e79c505a0896315688a114a406c372fd4a36d40ad32c24d29f665b90db211a8b7311484049be543d6035c27f10754b1bfe2ef3dcc57923dab2819ce3c2de0002208ccce3a89c81f3ee8d88645bc2c3bfaefddb1c286269d6aaba2966de2f305a97b90c64bb67ac0e0933cc4cdd861d27f8c54df2e4d775d8d5ab7e48b825ac5aed491819c0a74168230109b7220a1ce231a59dc2c77149997806544932a2f59d4eeaeb15bbb1d4f064949f863e4ee640babec0d969ed3c9f51a1721015759d104e9b6f83bdd3f2f4eb557ccb8e9ed8afa8e211a48defde0c42e55bc44ad102611e5104370eca4a2b28bd1216debc0a0bb659fe6a8d4b40f2813c9aea27cf7c006386f049395bd50c77a0a83fcafbfc79600953a9626dd3ddf0e30ae36e7827ce8aa93aec9a146e04ce289177cb2acd8d38aa80d2e7da2f6e6bc688c46ff53b5494260bc9ac10ae3b9ad4bbdc0c2ee156e737dbead3861741e58f12b03402c1bda38ac4b9ae58b312b468cf7e03e7a3d0769724fd7a24c2b6c37026158e80ff0fcb65a31cb1031f471dce4f2719bd4cb56773b013326b18cc40e1b982a374ecf29673c75364da7445a747e6e2bdf2428c8e7137bc5ee923c60526eaac1d7d89e77c983a9469a43299272fa4662f8786957720f988e1e49071002f79c4536547ab25f50cd969ff643cb502b64b0a7e70668926d1b86d0193416498134febbeb97d571d89e79fcaf044908a129f82e9b0e8911ec39bb08061abe4e224f8487ff0394b22f2f46de9619bcb45042bdcd3396b0be0d337dfd1433444775e6c17be52892cd9d65428db381c5879bbcd9699cc0f16190c1ecdf217d3761136ca413878bb2a874f2c5a5ede8c4c1940aaa66946eac4789163c02dfa94e3245aad9b124897c8a9098e444e66e1aa93990f1437d62b2d95c62fbaca8615e7c0ee5ac76887f2eb9865b3dd9b837adf70c69bc516efa27db985e04bfc04944d5f1d81d6b270ad73cd80b2a72c4f96c243ad7c57014fced287e3055560118a88f8c4f07c266528686030f458f58dad06d2e6e5040b411213eaccd3a820bf7d82fb109b8af28b7b86361445f0488940b6f7ca48fb0fe93c716b6c3eb253888830e42681674514552f80242fb5d08dd0752374e9eae6ac68387d7296c62ad4340909c900f0c25bc84b6fa74884b502787256d75a6a74d780ea423fe456ae079f0da730ab43b0970d0e55514f9acadb6596ce46841effc8a0494421cd83d84da3d50952ddb4e9f3dd2cd4f7d13def6a6960b3948dfad36577137c589cf2240a95f60928676ac26b6f03c1a0771839728595c2bcd42e0c4b0d205f38d120e534a69e4dc4df04eab0a3160a6b81b598f620b8313bd4c660ca0480f4a5313b02c324a169b45a5bbf506fbd36b269bccfca182c9edd56139f1bb574c15569ffee7097b54de6cd526308db0392cdb9dcbe6586a013d4d54b0d800c1143cda812d4014206724322e23089c2cbb3dae362557b0d5fbe0db21a4b8cd069a6bb435313c514b6cf1bc984758b9054a5b741be6a67da1e3f13d3b2657633b216297ee20db866a7ca34ad6c9a011286b180d5e89d450854d21e6e26f06008ed6b486bd635e50f6a71a04467871806996965195405b05586ca45337cc5245210597b0770d6c9fb087f0841c896650604d4a5be54db55b682d726e0045e34888c6cb3f44ed21b78e5b7583dfabcf1ebc46138f6b59a30f816ce2ec9288f7d129591f422e1264018696828b2e5498d2738403ed8f280b071c74dafeb0ab27a5bc22b70c1214301cd0abe059225c572581aebe581c7b71ecf2cc7481f0acbdcd3e8ca0f02c829f2a9312c5bbf4573783cdee6df8aa512db5e418c11b9840b975859a9ac3bb962c74f92abac648af97556b435159b6f83a4cd98651fcf45633b749aaefe26ad15ba565d3b922c927538524f2e0686e6be7e3879f6a88436a4b798bdebaf461c335563335d7ec4d4ef810b524d4c883cddd8c1656fe480be8f63bb03569ddddfaf0c2880dc1d17530d9a832a5bef9ff729aa5cbe59c75372846a79ba3102d47cba719215c25652ee3ac264fc1b496ae668d85cb7083d4ddd77c79280f4f5cbc19c5c1dd39b1f92d3acb8d83d865927e873aea288941e04f51946ccce313c62eee9cfc26130ee18bfcc5a02f4ea19eb3c0f2f4f740366abb1fc199d0a603c90fef13c3b3ede3d4422b714dbc150ca278f50a2f7132e0b6c3d68dabcb3af5e2bd93ddd8c013ccb24e3e36cb483ab1f5fad65ae8a24a135aeb4516cc29349de02b2334fc42e92ad9e106674ce3d4d0287d80293b2897382b954f8f040e67279e4c1f116b6b5b777b51e2a0bc80438dd2406c2da00cb04dbaa2c3e9ea9cb7315022fe5bb03025fc85e4b853e5fd49f7ae0f83f83addf427630dafd03c5ab391734f255510e166c3adec2325989a51810d715e031979de12e289ec574c04536aa56cac1a1bbab7de94b918738cf103b427c5751e95da33b2a760d41148c411674cf6a0542954a44307ebd4bdc65a653af4f80165e60df92850dec7a84588959b929f99fc9432ea48df5a593fce625d3e2ef433243ece4230cc3d015d578b41f183e8d07f1e999aa09e8beaf6827df7cd003e430b11a8a89b2097b84662b77b1a24840537f1906c183a34f7e997689597db11e924fbe94c22e443fafcdf2050040fad4d9d8ff043643a136fadb908f8edede1bd265b7cfbd621eb9676d934917726cbad248a53a33caa5bcbede8cc2901136bcd575940e08b076b0ce328b516f9d496a21ec416c93249275e8db92d267eddf462c26b36caff620ec9ca86b48fdb624a6fa65c2b86b59345be98ef171ddc0927b6c6e009c42d0a32b06721b798e82b8ae916435f93fd95bcee28a8b64cbf8602d11f48bb5bf78f10e331701629ec2117bf278912667d8c628fbde47f0ded3068d6a5c4c575e7b581e920ab8341bd7c0d6c424059a490321185c70336757bdfe1df9c4ff85f4e2d9cc6dcd82c54375667da9f20bac3464386d65da88e5a709231f7115be4eec5059ae911adb158b5084448aa5fe3426e4a2e492af50ab050a146e7b89ded71c1d5938fe3fef170b84c08ddf2648905bd214df6dd94398980d2c6ef7ca0e8f35a3b4d2c78dd6b95fa31a7d9fabb35f215dfadcdef395905b1389aa782d163e49626fcbb8b8187ad981b3800d331f2a384198b98d4c6e095db5e76c31e0949667014c98efdc882d184551cc1af8f608d2c18aab8063491f0aa27206ddc796aa0891218c583e67588164e6ab23f3c18160c143ff67638d85bdfca873ea2b7a95262648cdb8a3b2cf64c0db22fb8c848d455c6f575d2e9af63795b44b10eb773e293757b14c4ed552517f9baacfe780932df19c18251201ef67d5a56666e4fe7e06c3d622fcf2c6331fbbe5790353ad622191c3145436e43e8b33b8c45c09db93f80b77b23ec31f25f6148c466f41e4d270b04d4c0beba7f6a7788f79c9e7f1b4ebcb06634dbdb20ca283ca8a8596b28053e56bdd4723943562e542c2c88d73689e50b096d78c74f04390e3eb10f54097a91ec29928a9207902b73b037408594195ae0b9658f3cac217002e5ab71e5b448a32175e4cd164e355f11ccd26441964dbc3db7eccfb27bbb65679789a10ec109edbc60a2e8793c842d7b0c0a2219ec550c8d9d04381a431a41e1d4e5c7f9f9f192be4b2f188a223bf0f9f109396eaf57f0c55a5e063b34114cc9df22d8ae2ddb49e0c360079a10bcbe59624c96bb6202a50bf6428c4363d516ca8b33e750614ca58e1bb72717060220fa2d2cf3a2d4e72de9173a9eab61f8f464a1e56edc1e1d0280a2f7594edd1abe3c6ee2c8ed41938d4feb4d50574d49b1168e2bff7d74d76e790016faba103c30900278d58d5ec2327bd980dca03c7211585f13d78f06df3a7f54beac95a8fed34d49db5a080ef5d4242236ef2208d0fa9e731b29c10e500972d776aa751db54ed50a79e232b253bc4652656eb74386e08c5931e016adbb3d46d735d1172eeec6ce23b15a4de1c318861f5621cefd514f798118b52766f7245f93bf269f7a6eb501837f38134c470a4fc591c54d0fcaad7984f767351bafcf222cc1916d1dec2bfa0f188b2e62586309ee71268d6e4a2c8307f44485419bd5e3e36a4737425d4ffa2078ec0366bc60bfa4e0d5179b05de949651af3ff17f593a07442d2f407353f0dea9154f620deb7927b5854cacb40566bf67c592d5896012f2b8395ee4cee2f65a723ed0c776a90c2c24ca457be678511ec67cd7a19410112c472848eac9d020e5bf6c0d88b2606806722dafcb323325703efb9b44ce6045132c3a5cf93b355d1d4762dd8cfb590df85e192b8d675d8e54b99446e915ab480321634036277003cbe49fe2606f5366955787a23ab085a59306b1f3d3aff61b5ea80a2095ba25936e8b6822253b0155ae797262ebbbf49253568035cf625925c07087d8494088f983d8a3b5ce31749d8e42ea0a01b4892c48a6224a17904ca21798c4ccb9f12b3cc39b9d8f756701c0d66aba6c60043a012b81f6bfe850ed993211a5df900b6a8f473d762b778680b7a049ff91ab97d520cf4924d5b01d6bb42c4466d4d2c63725f83ade648f3bea9aab74f96b58812ba31876f8d054f32d07ceb63c4127955087ed1b53b5f6b4d753d274d1790d3795b994a860002f97f369ce6042a8c434111caf0ec191b8b171e505abe32883419ca136ed99d77e3429cab897d5b2a46f77dddcf15e81e4c292fb8130e094a1b13158b4d315fac1cb56784f8bfa8cc4bac21793adfeaf43e3b72f3b458d8d81066fd9d636d490f4b733ef160cadc8d890592727e5fa6a393977b0c57696511bcb776ebd7f976f322db442186ce6fdded6097697a686535d09cd98c0f6a95f6885d761fc7f1f105d377f85584261f750591f1f94249139367836d1387dd25ec235c1d700ecfe4fadf44e911faf1df6bc5e12eae2961050a609f99fa4c3f66239bb980a2a492b5a64eae164324b5d7761b49aea69c8adb37d832e7032d0a041d402201e718e29fbfe3eb633185995e1e848da250b7686500c132733b40c41605077dece7c5fcebf10c1b83976f9dc912cba624a08b64cecf20df211a3490bed2f093edde5fc6d7e4957d9c74f09dc88626a6136bc3cc55f607909a1e9c5af38d4d9ef16ed6d92e2600ee55d130872db418fcbbe23a8d37bd4bac0e688f2d669858b4f5c258a5af97b26e5440b13f7ce517a9eedb4d6ad897403979644596a1d306f02a277e1c9c76d89e9353c1d7045ab90ab6197a0647a433a6c21218795b57bd0d2427962d057c1b013c2b03772ed100242fe40818444c4398293ffd87422fa2c9f83548d9169e9e7b578569a05c89b245e22f59f4c55758e942fee57c42db33d874993d496263fdd146162674343e5852e65136b23b98a46ab0c7a907e3c8d175e76fadf384bc60993bdd784fe919f585f6d105c39b299b80f39cf4a4b44decc421371c1db23d7cc5ba70043f73b4501a47e6e43e9cdd6853c182e69d57b657a370a80ce30ec4d81dba877bf005bade09d84f4e4ce24c3d47d180b4a1551b4eadab3ca8c0bcd111501c5ef9ffceb915adf368f364c0f4abc48e0e32325eda3e139b904a2b01293a88c8bf8da8b50b2bfe4da64433c66b50a7ba47d56882b81ebb733b8a4aa5d16ae8de623485ada78d5c87b2e001c783b8b84cb4b0c2b8964e985f04e0218c4e8da8fd5576ad25735fe70371e065101982f061e9197b75a5fb87bcf7871479166c1eb420f96985aec42e9f56c01acb10d7c091a188caaa7758449fef068c420ab9fa7299618899fc4d3a0dcd00b8d7537f400839e8e28408d55f9a99fe6d0050a5de6dcba337544c108e2ae71e883e3aee780b812f88edddf472073c377c5452969952a537e5de6372da1c2689c18fe038a472ab5e742ad61c7d4606b30d98d7ed0843d7ad4690f489d901fc333a893a3e8fa676dfb51494a94665d6e2f3f213b8c04f516704a216dd47c6cf2162085dacf9c06376fe60f9e688d35e4c97c8d20386185cc48f556f1cd395c7f3a492cc2e136959a4f05cb0be84708ac56e1aba75129f1456d874b74f1788db8c8d1da72183a5b24519d0264eb7a8ea863d96b2603c76e592c25a71cc0d22b7d0c142d047a867e43d4fe21b39216dd2a2d4ca4c8cba9f5a6bffb1799bcfbe3e6e5e41dab005d285e6a744d39e0425250b4528244b80eda2ddc4d2686dcdf4120d9027b14bb70ea2e03c32a68d71cb586feb421fb806ff089b90a9eb5a809b96ad9aa8ece3166c7f415c2dad714fa14c6f344155b567ebfeba835b82bbb06578a17959ec13189e44807354fd6eac811dc674ac748c28b3b6b20eec3a97d42d948f8456814512f440eb16344d79c5dacc02f9e5859afe90e051e8cfaca03218c6695845968181991f5869fd9d57fe7ecd53f5cb2c7141dd5ce9d9646954306d07efea29fce502535de8953d5ed681b1872241eb7589ca5c79f0d42ceb08794c56b7ddb869f75fcc8a28245ce3198d4875b4739b02ad28384c65b8c2740e43914d591d6eb064ce622f95feb007592082472c02a5b44ac2da580f5a4ca73485803f4e814ce40b65b71586231de1829694535980c02ba85566b9e54bfc34a81277f0bbef96e4df60546382f8a1dad379549136133da853646684e36bd9993cb6692668313700ebdedd683a65babf356e9436bcc67e513221dcafe34a092d113bb55223644eca266129da8990c3140bae2af9f6a452e28b04298d988139225646683112c64be939c2f7e5335eb328e265744103723aa3f30c0c4e1e1c929a6c96290177cd4e06d2b44a671c0d8b45357cd1134d57d81acd39bd0ebf62f3765038bf621448d10b0bdbd858b1073cab64a6c1bf7c39ed10ec1ad36c946bb09c71a66fae7a9fb5a013aa2f45e4c18d3a3e76d9ca9c381eac3325ec67f2eaadff6c01ce2fc0ee08744a34d447fd0a52467a8382d2ec745f8bc75cc57ccf53196000aa4f6da565cd8faa726d0f6dee6264bbe46400bdfd2f6ec23f1972ecdafe860d76f397bd135d3a74349767d5d7155dba54c409c15e6e3c71212225a1b0f2039acbaf8883a7d6bc0e09903a2b2bf518ea391e897e4426c454dc570946fa7440bb3ccb62e9225eed0ba25b35508f137627d46114fe3afb1091d85f7e5c1a2d50ea3d4993aeaeee101d7289e74b8b40716756b27ae4c9aa5e3519d059e303878a9cf7054222af30afdbe743ad99f53058152c24586b06133f836c6e16c0cadcb9ef41fe50ad84f7829f216e08a0aa25a3828c992d92da3c72a1eac348f9a136935711fc83913dbef91e4121f4037749868819045d4c97e9c8df1b348e8ad724dc0f160f7e9ac50b7546b45fe6d72cd91b88b1180b80e7e87b261c17cb4c3fd172dbf078f71cf1cd60114342dae02810f2c390f9cb920451438b811c93b68fb0d8dc2878833930d27172ab53ed1f6176e1bb20513727b5ae557f3adc57edf1b7800238aa988699de524570809d18397ba7ce4b30944a91490846d550d0ae8a762cdce2df65f7915191bd2f275245026867150a18a51223585513afafcf13481921fb3f61dddc35b4e5454d6d11762f2306e4c7e0838f05542207a1254bba376137115c24bb7a4399ee50e2f7dcc668fb888ae82f37e2d594ed567387abdaf284d7ae0e4e1c56fd75d8f5b24eadd3a94f107b02f02d37c226f679348cf3d3c0d7a42491d21d3f98171e75e0c208a47ab4b4a32050c3317757a4cca29fd0d8c7c672e94eb02c85696f8d985d79c8b21f624c31febab3153aabe275b1729248435e6438b9f7a8e2e424d5754d69b44fc73afa6b1d23a7f19617c1b5a7130a902a267740a5f7e5da973969ca48afa4516e34ce2e1ad9b4f52a6ef197030bf27663a34d673fa6ced37fc82a044af5f214149c2dcf99b10834866512b16db42ea2f93ed44376f88b0844583791ca04057545e66cbad13d2384b5ee738c47546b64c9c765ac6cbb626e52401da95f315a172a284a8e4eca5aaab700d9fbe90101144068ca09940837a1a5ab9f3f494801776bf5a9750230c98be899d98b6d8587f7e5e2915a161287170c9689b7da15d99a01a9a3eee6422deaefdc265cd65504531114fd30d800225efd3311195d0975b448cbf4928931ff70f1fc1fbfffb33f8937e2c85c0a241868329d434182959e123b420dc5004580d120fcd3c8eda29a1e98ce03e780881d06124c559fe0ba64058d82ebb831732dca707e54ee41bedf0d2f02823877d015d998818a3a63cc845f6afc6c82023ed95d8b90925c6f7a18edd906da0a5cab62c85ae9c04c209225948b3c4bcc5c53ebbd872fb3bf281e5b00721f9dd2344f0c0b5a344f0916d02e4ed0ce40a38e6af79f156083b35e1116223d5eadc98ccc9b3816b88257e6187a0372709f26f9f2256fe744b7a49885e41b434e0264b441aa1a98f0e4d915d89856d1af9179298a7654851da3b642d9cc4131c9a52efba9e1683e772a793e4d2edea95b20eeb2883d212fa42b4795be85e1580f71ee2eff8458e3ff2a1b49fcc1a0b4da76e04ea6ca9b90507104d5bcbcf62318b2877c62c24cc11eda5c1dc9c1179412a4054b4f2028193a67096d2095256e9589791fbe1edd128ecb805beb82a37639c6b0c243b351f93b0fb0a892061eeaace2fc0256c84ef0032e3a8951d27d1550897b07a21f5e2ed31e671fa198c76d5bf12ce1ff6f109c79cc48f8015af107f77f2b862a9a3a12e48e4a6b4bcb74968be534688958bf6cbf2f694aba2c0e50068d2dbc9978acaf21e33c2534a48ed044735b1a57fb75a2abc68a317f0beb8e799e3aecccc5198f7b39cfc1f330c66583ffa7c3f66122d40c11cdbe53818a97856daa051e6e2b03d221f9fec210822bc8705fe26e20c0433a41ea1082d8dcd79e0adb1b623c78257aeeb6c79abdfa428b436ed940c64f0e40ce61e20dcf14895f1c0cdd80a7ee22a09d3fa91316219b1ac3725c7559b18873be6c730d65e7e2ac1c2ea6c228920531adcd85e66daa411384fc76f780ed06837b331607c8d0d1e18d6363e6e5075eeba2212e985b6af168ecd439794c183d38cfa6b4142e04a877886f80a578642a1a55ee1573d5ffd61d682ab2cc57dbfeb234915dcd13bd5ed6a2d50a8022a2eabfb118135086a627c27016b1ca17475ec31fab5c73188e67bd9c1b540984bd4a70e46a62917a4500f0b5d058c995c74d5ff2676f897d837e0cfc11fa8a408061feac5a8724dce74cc41c91eab62a48e2be25195d66a7f841ab135a56a5bc9e64ce161c3c156cd9bf707055bde6cb889c28afab349a93832303c08b6f82b7a7572d80a0c0efb6edf9123a3c5a9513b53b13eebc8bfa5da07b2a5a72f7391849e472820bae446d0808d5bbe4613d4d8b1c98adc4e6206d90840ee460170a9cd28ebf41cc126b54227adda5dd26adba8fd874dde316852a6f27d7441a2a3221fe46ebd5f780f21d77abe0916a086e4968c964efa937f2f2486e014c3094dfaf186054babc7864af938623ed3c0be3602dd20e37b11bf5ec588c1e1e82707d9bdc922baab90d8ba78c96e0e45556a40425d639e3e4550ef3c0698e541046c47b85917b521ebc18c8398516c0da2ad35f0ffda6fb9abaf0b8b6f5ff2636e5b5086537a6f512a2137c5b209bb94f7b092102067e52426d02d87622c3a86d81fdcaa9b571fae25c5f50aa7f2111859b9bb6b200f838fe36486b935eaf20611f27381665a97afa43920ce3013b62f0160dbb52e64dc9bd31675567b4c8b97419fbcc1bbd80e342847de462911897583dc57898ddf4fe3f9d2fe6fb75187b1021ac35c2c10e4dcb3a5cc2b15911e1812b921d79b3e9d1f39d5833c9de929d0d06ac6c9b71bb0caea6ba90cec9f5b3977d83fcd0412289c800703161cf40b7c89740f7fe1f03e226d97a30474f851d402a88cbad3e16de4079f22e0baef28003cd11a8a82b8f489fd9df0c9c713fbc348202e48f3e24bfd4e8094701159a97f35d378c4f926f535a11c251c7372b0bc6b527fded5c4f3de11d6a120bc44f0525858d99ee036aa3062ef140ab6355000098c37c14e167713f485c28ed1be2e35df98fccc84805f15b74c262beb35c9c148656086a540e2b027f491b6e08ba409b070ca0386940c1cace44f2b4e4a81e4d38b404506adc094402b6beb329c24e578844e0b0913398bfa3741f64e371abf3bc30b737e6cdf1da88eae298f859b5d5937d55cd680bda55811f9f24731b4997168de5e896c1dc83032712044ce90294a54a5d703d40ba73523021214e29292fe4217c53ef313c286c0861ad0b424b76606c183cbfb0af1cfe945b0d117e58ad30bde837887171dd11801ec082574f8331e29ca3bd752582cf4e6559644af3808580304f0c2fd5343b69c9807705fc98db600d52c9cee43af5de176495ac7ee9abb7886f31a1ec5ee60321c4096bd7fa513d82d4de573ad6d91fb1dc8a57ca4d24509d20997618879a585f0a06ee639ca66ffa8a78e5fabed09cfc2042f5ab71e2960df79936d1346a4a1631ce44993bcc6fb53bd2efd5770853b081dfa6944879d822abc8984a6bf1d8b4b190663a001dfbb4dbd2379ec5c21a0b1309713c0a63ce8e0db91079c46525d0f27434e3be2dd52b9dbac8d9dbc5a0dd613d5a3fbf8bd279679fb019ba519fc7704766bc44d997eb98efce58bf02a2481eb83ddd23259b14a9a92bcfa0af23e4739264df77238e2c25a0a26c3fb564b2a6aafdbb514917559c7376c07c62c5aa3da013b9a001b7f19b0db3e6d8fc0727cfcd26be6929f721f204e40dbddfa2ffa45797b08f870f6a3f0ca2738507d98be8a80c2ffe0b8a07cfd80dabbb48b9b9ff9b7eb8ef113973307e8e2c5a50f261097d54c0e435f6418148c733281cc31bfc9ea53484ead400d4462927cc812c5bf2aa664bee315ee6b409900cc7e71baa640079768b7aeed6f41f22efed0792493dba054f7e43088ee9332c1887af7d4e2f5edb9511294f70c4a1f4ff82e3b5fdd0bb3666d92fb93b65590c7b068cfa378dfe5e653f8be329e0f86d60775bbe4fb665c6a20be4d0c995f0e1fa060d1328802fb0846baaaa88fc736bc6d73986c94f9234ec521ddf2fd9fc32aa851b38adcb575cca8b61bede1e81bc531ef2f194972bd712e8a3b807bda5175799b2f9693261316525a824f99b7b0bb95483213ad8c153ed0da04c353399c26f23cf90aaa2c0da4db07c1272c4db047acb8e39636a9dc0d61e5d2bb3b4ce8321146e823a6692c3609fc0b23ad060024c7c8301d99a05f7c418fd2202aeb1724ad969fa5ac66761b1a4e0dc0bdca8d5133f2a5275c4f6fa6362f428a18149a8e551fd49a90263665d82c88363c201e451f79906f5047ecdd1409f959c288f19a5170cd15a8265ae0e43a8c27f52811da31f5a4292ae01acb9e990e333976597e3324061ae3c258069a8bc1696b102014b27dc607222621c7c2c37d3a0185c555903dfcd69c12cf7768ca6643a59887417ff0cd9bf90fe8d3cdf14ae074e56cec4eabc51e723c51a35008124d0a4234a4240003701b3ea2d9639847f2b468a3324650f5a537071f70f05c3ade0bb071beb12c6cb7ca73b24bf4d5e6f4910a8225e62eafe155730cede643cd362247d42b5a200e23f7b6fe46492f911b01f910c05456c0b210c0e697e4a4ad432094599e1268a7088cc5ba9a6ef48b039e418ae512d86e96e86e7e50608d3bda774984e2faa22e2703fb2d1991c2a48c4da7b80dc28d722d83c3369a57ebd8a96c5d88deb65e40812872d43cdbc2707d0f70c67063f06c878010e11b7bb58f863cf545b81818dcb14d6171edb7e4a2f48ebc81d9d1113d95ac78be7aa964b53b0630e680307c42bc2c1fefe16b8e0e748685d9719368dd1b7ae53774e14bc11cb22e6152ceff88ec343e56462344d79785e60bad0a081ff058caac14814e8596b977c7f924260b502170e58d0a3c387b50861e4c615735f69da69301e48159cc60fb238ee2b378e51c2537781bc32d492a0f57aed8e12f296e20da5a001e9094b0e312dec8d0bcba0a60a0efe6044ad3a94553266559d86c1a3a8e4b451fc065aa24995ae40c5ee381ed82a580d983d865d83b9997bdd02c570f0a9879d1158ec059c0010569831e78eb3c482a77f2c1c8fcf227f0d7128a0ac460fa1c634e4e1d84cea337ae915392ca23d252d320cb611511d0c9febd06795c54e744f2c00227959a67029f340f8e8bc51837478f2c4aa5503a03774e03926419530cc3c372fb8249a7a2e5370b22cef2110712c2ba151dd6279a91a8386cbb435bd9392f22c508304b79fc0ee10b5497b4a28594bb697f01c4caedb62fc3f3be271b1c092dab0a4b8a3d9ef890bae7284a0a562b115c5ae8d86bb508878059ab170ac245ac291c1406a79c1edc7d233d20298fba9837868a42848540f6ebd8a06b04a1e91b07f4900a619d8012c4d1145edad88f1c07d49214dc5b75b516aff81fb237d2849890b5b3a711bc7c661e9635d44cb550ea8b883289ae737bcdc871e76dce438d2c415080d4eb8841c9ea3d72ba0d5a493f81574e256bffa7ae6848ac0e75aa0e0248ff4a28af4b49396290600a29a8dc88f4f47ebe2cfe06a2e2049a02f4e45dc4bb1801dc005347cb83ee469e32bd301f2144978a5a9018a0b6494e7cb6bc4918437cc82fdbde1139989cf7856ffa11e400901b009f45d150d020f5e74c15a2fd1a4f830e650225c31604b74afe17d662a568173590ba710edf45edd4769a5f42a709901a0d9132789c77a19069ae3f5e19aa37ab47cb5ee3a3047a6c36059a88e5012621737dd004639218ebb134c45bcf09da211e6dd592972bf3f44894be9ce4607014e4536dfb343898762436cc712947905cd7e8e725151bad273cc7e134bb53544855bd903e19b4e200cfbe4527594d5733937b02e171e311b2e2cdb5bc0989af370095f9cd03221dd0bbbc9933ac862f377dda023ebbe4d1e940875814da93074d84437018cad2abc1a484a26a187d5c126c2fdfe460b46c89976b02857e086aea2e61fba5eed0e4c4c0f1e843524aad3723f5d55180701bb94b87229e9753fee6d56b03e8966697e69b605b941574ecf0a733941d86861c16cf935a2a514f88ef40a870088789e811a43462a81e5c85208021086f6ca5fda9837051ecf0a337cb68ea3c136762b654279c8c54e590041f968e371b802038e36d8c5df3570141671b5cfeadbaffd7fb269b428db56d31174064b119508b971e7917ce6fb5497195a05ce5ac8975bdc266732b280638fe83968a65c7e88e62e97e0a9a17fa728824ca35084c55d88da80d7872caa71d091774707b2a8d3e93a2292db0151f5734402f0008db4a08b7c2d8be43859c006a62f0e7fb6537f6ac8fc43d09b88f122d7c5432d06460b30c2001e340fbb4a0f323c02b8b412a447181a116844e1e24e11887971cfba6638ed6d1bb13062e85f8623e6f6936415eea6fd264d9a8e3551712ef325d48560567a96c6ffe962d00f5a059d7bf33da7fe2279eeebde8433b00ad5f810d7fb625e6b8ff205ecc732434406f51a5b86a62a33b3c35a974df0d0e128f47e5d49c0d2b856718bc9a30451d148c5f51e77425fd6a1c37b0d797cd6cc029a8ddedc020518f7c2c102a34a8b416dd85aa7bfeeea400ec3eb47405c0d611547925780f6a67cf6ec26464b70d8927a20d1078cdc01909d1be1d52a77707355b61ade20b1177861d8ccd01c435d3910b85906c78e6879c02288d5921ee560d7906f18223ac797160110207082dbf5ba5faa0203332d3eac7534ef46162a25742a440b13a882838b091e2ef1eaa0ec1c6286eb15f18c57b346dcb058d93a085ca04d7b24460d148395efeb08993bb5a67c800752d4f2067a00798f67453a921e5672101ac6f0b3dcc15e6cbd97f3dbfefbe76e5e2768d2272ce7782ed67188bb5158f769771b323e4fe838e566a508e3f8bdc84d1475b449da6266a665c098e195ed38c7d54408c954e59b78ae1c0f2528d779380f6a502cac503f89c02f5d1f46a8c56867e5526b0e604dbc1a2195c980d61831ff9831b8647e20130c5f3c900259e15d1da5695fc89aa2a0b1f3302c3adb87f068f868465af72d2c264a28dea23538cbfdacae66038d525c9e6f5b4b1dcae87ae93635308431adb0f887b8494c650b89f5b33d25ce5f5604dcd87cfc4448ec077ce6a152d0c954489c8be4909575b0052fd516c5305cdd9e01d9294878a4e01ed1cc185dcd43f318c79cbce8d09f47e57e1da7fb1741035de0dd0e2f4fe8dcc184da5b4977dcb84f94bf6e3c5c1ad2850e413d075c1f59b376cb0bf9c3ba1aad0fb4870945c70a4f376f67e24b04a640d0c4504fe5f13a292a32e54df1e396046768c641766cd5bff9ba508fec52e54ae1b05a46090004a69995b01d1a754d3c2e4a5b686f413b5a92e2b62130f37f1dff12d29e9861366a1d379a08bcafe3b7665457c56508e642bce2c202256dcf200cd7488f3348fddfd88529b0ab754fa9dc12a5b545355fbfbc65dd206635f5f44009a1a6a4bfb99b0d5990f33dd67207c2f14b220012cebec72616ae02f60420ca6a6b861e9613d4413977f618590e4f5849a82a09657ecb51477076b1826a6861c21755b9e25111417c13aff1d109f3611102f514487b92700d19115c9d0a24593dea658c53a061cdebcc2f93445565d83a1eb2d8fb8e5a300a98af15b30618237416ea8f41902f6f9b496d31e8d6c24cd8f5e9e305e0141dba80c835802e8fd4a86ce0517b2b90ead1103ddf455a75e664aa3c13046eb53eae20d1f0ec2171e531245e571c25da123dc77e1b06063bc2d890c870fb227839556505a418331498820de7f84d0a7eadfc689f63095fcd0a9b96d80e20a96e04d79f109f59daa0dc831b4f31667a84feca68d2c9bcd0ec2df902f0232e05dfd8f80668f0d8863105171586d83e878d3ae9e87562e2e0be0df4a7540bb1f62d22b28975dcb143384c9ffb7051a7377fa848816a1a6165216f299ac9f0eb3c13379a9a65a37c29a08f7b5ca60e703388040ab2e0f9f9edecac72f4450fa95024c13532a6b7679e1444e62fff8a9f4382d198aa1c0e4e7d0913fd01dcaaeacec8411fe98e9772d2690ea211e8733b68e596295fe0bd30851e067f3d5df139d10e04f95182923dbc7a04d6c17de6a5f6c18103cb4ba19d0a5262f85faba3e9aca6cb5fd9b4d3ffb29ab2b45afad0a6d0124b57629d0c0b1e2b71e859fe745e9254dc898a282beed28c409adc68705812561e10ff93b62177f3a71620b2aebec38c32ef21cc0a76591b5d1a22674d002a87203ea46e237119404ed6ce8ae1b39b961bb33f6eea42d498ace063f1a1f2bc32a123d865c1ba36d0234e472b9a5f7bc7d37d40cd10b08742de7d0923ddad89ea3a503b838009acc9561881044293aae5cbbd4a19190f23c064e97eed720669da61f7c0752ac2a2cc7886e6ab17453299409a888059330ee742b6322734b89791f550bb40bb6cd9998ad51508bf2f47e660dc2b3f922d45e58b98c0528ede4515d416b711c7f4a12d30532aab07aed285075441aca0b029060f93b363fdd34e704ff392c5d88ebbdd9c93f34a06842252d65b63b1ec5ae10c3b6d76c35bd25596fe83515d2423c979cb01c199d2c657ffa60acd52b6dbbb5b5cd6a560155c79efee534d6b158c0a41811e292878cb2f01e257b200730a05c943054e2ae1726ab063ea6780f3838782f41d8cae302566cfe669a47ee88af71320e551e06332a6bd73038e08f24f55b0a01425b1a2ef917f3217846ef50b2dfc6ebfbd9f105c66568c5e5c7551da47065e5d659cd92415b739257a668c958701491ec3bb4266a9061dfbe8be448852f25d525debec0316cba2cb325d1fe09dadcbed33122953fed9b0fed4bf6319f810f45f6b1f58a5ab2dee38b6e777161af5b8ea60008d75154d7d7354ecbbb6b7d4de39877797def1affd8b7ed4d9f0fbf43e43c7bfb116b76ac33932fc27d4107fbc987e42fb8597d8c4bf8cb26af6418f2102cb245a9792760bbdecab359e43905034e646a4affada4f844e4536d3c411e9623ab415aee61f215922b004d98c18e71b74ec2cd92d58433287efbb9700ad523cf24aece6b30d8965c4aef6cc41972859d0be6473f5ed05f476295ee252b5ce5fceb6c932d3e2bf695ba16716b8507a87db37545359747b77426a969d7f10f2ca4d06fbc73bd752949be25b6a56f1829087827b2d715ae272b90d5bc20adf6475fe1aaec9cd74790df01e540f8fd3e93ed9441a09eaeb52c73dff7b71b3849b84ff893a0391c9f0085702b11f16aaba8ff0e3604fb50835b140af2a742b352179c89bfc0d4e013a98bc0d816f7d9c93f37b40b68d3b12835b3d1a759f50c8fece6258b5b11e2bf0bd0f9cf160c5d162b51755ee79d26218120c03909aee1633c3757a3eb91cb3a401a387ff8b24c18f6d31f6c92abff1b7969bbc4ad2d5b7d45c2cea1cfa1e622935c00539f6475204b12173b017887401e4be0ae67061c874d90b05495e68ea178adfcd1328ff7c08f01d61e4c389f1efbb1b462ff8e205bfe74f3c75362fdb5626e9f389455ae4caf39b00088fed13b1c3d43644eeb04f070d57e6b620a6c7cfebb6016c0897f4bd7568dc50cf105fbc9311391ed6bc3f9a93467a151c353986e030228e5d69068b9111dec876a91f4afc5c1c13ad3b90537f38bd235e915eb0b85168199f58b4c6474504bc562771f0833b41a632658b5bee28f371ca848f1636b73fd8dbe0fa1bcd66814b7843ed042d6743ebdd707dcdcd39bcb330774a616614f698a01f2617d236e2c8891d4860373f1917d3d4de40dbaa2076d69394033d8dfdb6caf37d1f53a030955cec1be6fc131cbe153cae0df6cc8646e5cf289d96c4e7f07bf035d10702e39742cb724f55299ab3509009c42934188929030682a837e984135e84bb8b08a481a948e63016477d93a377adc2a804cb3278fac40387bd6677205f9b3221b2ae8cbbd43ea3965b58c78be4f09c71ebaffc76e524aff609021074ef9b09a274b7ba62d601d05a50c31869fb23315d6c5d195aeee1171e15d20454eb4da390970222290fe81b0c9c795ab15a48da09ec80edf7067dcd1e488677b3546db280fac43a7d1cf00af8e7ba02538e711329d1623d925bff89b63829990a1e878c38994d687d46700e2417f18d087ea7ea9698c432e3101b16a0a4377a356ff10838e9c358a38ffae21e36865b199a215b9b2332bd7c920603e27367724c6c2df1292a9b13160282cfdda2518838b1098ab036b4f3b0b1a2fedb939fb6f3e4e5f01317da779f0e780538334fca2ea1bac5821f8385ec1f2ec32b19140c1c6b02860fdde082e5e446c2c08060bda3223c2e8b8d5d2648744dc435d2287c97e31d4ecc088fc2ce16bf4c05a8acd1d59071494793b80ee41d44432de6b8480b664df153a8020e6c140d182561b8dff0edae34acd750c18336bf9edbabff981c2ab4ef9b67d6e16ec5975b93575221e1a8054c811da5dda424dcb9a37c873d6d48c7b3c885fb395892390fb84e3a38fa142fe24f0ac0d434ab14c25072d2de9cad4943718fe1b228592bdd69964c789abf7390c69c1842ae08ec325b6422017d5d23bc69484b70815219f3077b966253dcf87cb17250b4ef00c621b25e1f5cd123c30f04a99516a831e3ade53cb3f224cefcb900d5207e26797d4a44844451c0d9b067485f68ac6fcc03db623dc99bd6395cde143f0d2a3744eeb1597435ff1ad5bd2b50e8a5ed591b170b35415414ce271129aabfe8fa9558876ee508f92e94eabcd2d755986d5793dbe36ef83b1117a7264cc4d741aa6135894c5f5cf751d4965fd55e3b2e17060d33f45a91583d9f08278e4adb71e0e26e864e4e079a064d3583d96871cb60053f611c0284eea9bbaae7202df7cb3bb10e8565aa827c05b307209c890f73dcb4ea156dce923d578fa16fd5db779597454264772701fe9e9f858758750102f7da75791a8a1294e206e0658efd6c26e8965652d4892b7514c70ac83f0b998d7024ea34d515ab93f85c82ee17e43d01f5b7c48cb13b687d1ca54b1640141200800a2f56911a8b8aa82853069ddaf66012cc3f6c1f8a340bff67ecccf45bfd6a9f031f6f37f87d6d963e7f2e93c557fd3f7b3b28f4a672c4ea00829584abfacc4efc1c1ff78574e5b02a8bf9ff229bf1e50bcdde0603e3cafdddb374f19a5dbf4cdc7ec994745951d71ef4f39946dedf04b483c4e8d9e39da357bfef40ee0914dafe5369b2ebef0cf18d4535cf0ee296ee3bfc6bbe9040f71cc361bb368b68e1f3b38a5d0f35b357d1f3e7a54792d9b1af5a84f94d3616e5b9c577d42072adf36e96d8ce1f56151f7845991e93cd2a5f023c42e254cad1be990a36396d0200a21116a7afbf10c308dcb202fe115a264f12084b31b32e1988e892556aa14b68c83d657cb9fd74d80fac6266c19b17aeccd579c48551421065f59f90b0eed6e51a8d381e3ebd2a5fac1e93edcc52ba959fe687dd0bf15a62d271691236bfa5614a2d4bd80a91900b91bce59b227ef8b8fbc2bb3c221b1c9d4afe1926d7fcb90a5193671d2c0bc7f0f9fade4a8c742d8e9a8252056f937a771d53cc75ae83824c404fdefb0dd6dd4ba93acb1c6fcce3b7e0770705d6cbf30c9cdd9a02a6158afa4d92043ac6a2b05dae97856fd0008e417d6345036829d8cd37be6322a20bca1cff5ae6fd08c525c8fda31a151fb1661080cdea5858a99f3a5e25552b194d025048441370bfd12bd187aea4f08d8d340512e61a7823723b48770c7fda02cd45101b1c276799180bc375a6910383f93b60e62789c3407e587322ff0258d8c25b5ca3800a59d5d61655c919dc3ec1d2cc3de6da90a483b23c0587dd8060f586c72d02525b67f6d3857eae8e80ff881660026376734314003ea52e3a3654ea6b3c8b0877266d6239421926fbd2d53dd87ab40df0c19e466c623534acfcdd593eb5f72af43b400712ab7799aadb6f6da7e95c97310aa43d9451097f077dd6cb601b6a4724410864696511d90ae181b71b23af5bb7a2d0129da6d43ab643a93748c6768b5f5e91128106a363e5e020342a7661e8455dacf528d5b876b59a711597cd26110a0175b8daecfc4c646b395342debe32b4028e4567b4d7533b4a5bd22a7eb48187b1257b53e49356e85058dbe0f02a1d4fd1508319bf588ad3e4bc77a04565a3e27353784a3469f0752ed1bc76b49bae667e9d6edc955c53ddca6e9bae21e56dd0f4128f38ce76875ebe3238044eb5668d0e0f730a5b9e1bc2ea5d57e226dba3dbbaedd866cb4ae57aec32633d5fd150cb1ddb84aa5b77d4a686f0a071abf1ea6b5b74e579274ed0fcf408150d359f55be735298df6b3274069c3edd1752e7d732bad8f8f808110b3d94fe1aae62789d6edc95522bdede3293020746ab6eef674ad7219d6738b9e31a7cfe01564f314eda535a6bd02c2d161d4a8d18df93344becfbec845f89fd4a3acb91f32e5f7ebdc5e2709f29f0cadf0bc7dfc0759f5707a7bf03fd90a0cd1dfdef8db5bcfff255bd090fee84dd827c9da6ed737f704e010c4e42ec41f7b77e82f320b1ea2d33fc92a70487f7ba7fff4be1f8028cdbe30b103431fbaa0ab7fbd88c6004fb9fd4af5e0c1be917cc85d73fc4163f909542ba244883507167566c96021699e0754e8d9fc0f5edac2c2d4046b4a192a2681e1430b18d11d2454965df7dbebe52e9c90fa5e0de7efa61f5576fc316a36a17166d84f674080348781eae1d840772156751734d28d90cfd8bdc2cc791f874dfd7afcb572f7bfa39b94fefa9aacbeb2e6d8b11fed667f56b07329463e306c5efff263ac4fe08deb47c963970032bb1160c1d422119b9ad2497ed8a37e040fb983ff5af2b1fb7f80bfabed6dc251e13015dd984f99769bbaed1ec83c941d7e880834c29eee585be12f8bab6978e8f5ee0ea216f27e9daff5079901da399756d327c192f6a48365d869880322e18c572370fe3a0f724bf22fb7abc157fefada15473cf55fca1653a56a0464150784821d6fba4b0b0cad77b38815423bde72eaa24b5eb38a67eb1549061309d134405e7b9fd1d8a27af697beebc6dd580c624a21d7acc42a5624a22ce972f16a4a7c9c401b73501a611e07f285f42747c157ae801b8a2de289924794f86779ce4725a62d91aead5948dccbdd752219682119b45bba2d0c6854b04919639c40074ab1907f894662c258b4c6268f2ce49acc42c9cd23a5c674591dcb8bf0476481d205f8dcc8e8d0f3c89f0c2b5fd1619be27f8accff0745c3f9525a6865b10885b359a4d42f1ad2ad821a1a64818cd3109047398d50be4a96e37b6f5e9262853ee67371d1f8fbfa4e4d0ea4c31cfe6bc85dee47fc7439fa2b78ce2803172d9c5b5962665b162b28422cb943cf1b5b9e78b5baef3a517a9a7dfb372b6a7b8685c5ef8fbfbb21e8000d7be14c738ccb66a631ef7584aaaf4860d0740bfe0fc21dde115d4374e8d5da5d58e96d319179a91168d93c79f1d621bae6d1b792bd9f90812053ca4ed4a90502cc2536cb80008f171fddf736df8a7a62986899c8fd7cad17028b0ba10d08dab614602261ae2b98f31d3f4c47d68de2abc3eb6a4656437eca6b205bea11d53e8142ae95be95b3da8cd18ef76ddec7cb851b7622d506a87aee324bf452277d932e4b7f795e41d434ef7058459d3d0eb7ec64ee8d4954ea0c4ac23a448a20d5794dc2c380d9bb3cd28561104a0bffa92c15436b516a7d459e265472d9540c1c849657fea4b25db5f08d377f8b0a1dda891a8f582d5a585bac33aef7026b17b73e43d8e1f540d990ebb9fdaa4399a9aa65fd4b406bef88025aa7a191dd2554c88ab39a93b696307d3656fa01474cdaa63fa00e04ef19ca1d428e60e2daaafec19b7b505fef43dc6731a6c9e3b8bde6953f40b7678c6970b825e62efd77987ac940706b21f5bc8b4e69a19b717a4bfc659f88d2579cf97781dbb9134bb82dd5ff48752606c331234c1a71bf3adb953b59c563fc752e0fb1e3982f83d01845e654fca040e700e69b193ec82fe3e38eb87f456078e88d5390f0b20cdee94b3ec55c343ff114e57efe2fc35ef73a7d62848ff7dd405f6c6b769349df166b12aea1338054674c358903cf8d8b48bf737394b7f744544d2feac34c37e72c9f5a59bc2d557d23962623bc62fd3efb72b6140e3abf81fb865ca7368ed6d46a7a85f224ee5e9f6884aa0d9164302b3f80510360bf169168ec1a5d8b38bcf19e32d84fcea3be09d1bfc7d701b3fb9ed1d0fd27d9286928501bfca543ef61ed20a1d4bb7631c925b9ac320c5830d2cd81df5f8e8e0bedbcee622a6ffd305a70de82a53b876859b3abebc5c901de69fea666d7e609a0891b7ff40f467483b87bd967f0c6cdab30795e5d715d559c9fb8fd95b789651ab5318a1b92cdd0db88b63736c3f12e009631799c125d08ea60d12ea03e806a438a3557d2fecc8dd28524555f863638676a8df56ec46e602e7122d517ab4cc876155f1fd07a70f50f71cf09a230f5c8864f3f8cd2325a822734953e5bd85aa3ed48d4772516d543e691a7c759ffbbc39d0375e4972e4a8173d7edb990a66e54fc1212888ba79c1581d7bd47e255084917dbf56f8d26058f929534ffb48ac8c558bfa9a8b9db2722c52df3085e1ac2a87660af55c4d5685d8c849c8634ea0cffda4d91ee1674e2018cab89a554a6f8a7d974ecb45ac30513631651af6660f9f45c7b1919bdcbe29fe62980ea659c28e58ef0f6440d2a59b764c30901cbf4afa9d72b9ed69d275310f02fecc99548619ba50de5d1252ceae54035be7437774dbeb7799901171b54ad0d6540098b1667e450fff2ab2e125998ee843e44e9a6ccbaf69aa42a7108ca0ad3db02fd1ce0ee376ed3d0300b7fcb421f11af3330032b4d9a7f22415f3cfc5761776e880566d7ebb32956d0d9a33534d1c3e326b9faa744da12c1a491fcaa50fb5271250a65ea70eb7a5d67523797dc0ac05b7593602a46634c29781b6325e36949c508e8af3e76d84f534a897ab4ec3c124abaa0e367cdf1d06b97780efac5528e477e88ba1b87ff8cc8901babf44e0b19d6f2f0e551212d12a7c995638ed8f86457e555586b1d89ded3506731853815a27fe195ab9dd25788de93121aeed1eb4bf8172ee91990d8b7c9b3dcc48e6ae6456b68386e3c91761d6bd0d43371515b4134bd8a59886633ffac12576c5f3a09d7424de3ffbbbf4793efc90446aaf3684ce09a50e73430aab60a5e6b588c99da6fbe825c7c9ff45449df600b20bf77ee9d039497d61e2d8ab6ed6ba045828635d4907ec5c7f580701c3049b80284817bcca4506eb12cc7b54e97e483c21ebacd67e2ca1b565e119d49c6e84813ffe9da21faddc3c4099a151cbc04f76f22472703e6ec03f218c3e5722c66d3e0988b2f49108a13f32f5445de7e68b10373eba433ddda86816c6bf2acdd40bc07d9cc31f4fb93e4f2c4c0c41d57daaa55b40b8eda685bfa3be43ef755d875e4150870f48268eeffa84e9f725ac38360fe6c036d711cd0d67cbf85522a2c3788fa84d802e485ecf7b241858c48097f055432227d19ad9b1d8a0046ff16f668c50a9961e4d69fe24f2eb0f0d8a215c99e104c785c4f26970e14a788c8ae84f3b3cf111f016610b17805e6bfc7509dbe5111a3f69f7281235e1e91ec8acd47d273ceb0b05740cde61c2c8120f0f110808bd24ac59d11dc3821aca83849cbf868118bf0d7d3f98633f4a407cc4ed7a43d3ead57bdaff4eb2e5bfeb932fba6af2f7bdd0bd4c60deb887a738fcc0dca647b4959d1ec76ed97f1e0b72edd5a63924e0119a1e0bda7706e1122d0d72c3b7e0802876cfca8714a0dd5fde04bdc655a8b8a984e063bb256ea33c6caf8017a2d3b6193a868f6494b506c944c51740c6e1fbc69be9c859daf3f16d2584e374f35fe6b8521828f6023f939c68842198291ec47d82d13c9355a837cb49d75475a6af0c81b1bdeb81c42ddd4b186ccea18a89ee699bf8c0bf77c626501dadd9e59c4ed5aa4d9b03b8e89121bc67dd8dd84ba0f3c18014b75d6a7d5f0eb0981546063bceb4fce36e1d4a869a4d35e10d9cf3b03a7ffce7e8dd94c45f83688e1fe1a4f8f0b3712865e2ebf17064cdc3dec5709d3a1a1b2b2426f4846fe4c19e7791b9b3116a2cdc3cd84cafc528a3bdd167a63b372f9721a46aef15663c7e7615d6023ec6f3a368c1c24661a128d0fb5f5ef0a34fb7a68339d0ad5a78bd3a1fcf0561291ada4fd1269709e02076abe9eb848fffce711b73ddd557f01aab18e773dd45825174035165107bdaba788abae04bd3b2bd56fe1b4107deff3e2e1eea6bfbbfac25e1a277c02d4eaa3f9788a02750468e6b09a77083a6a047e7945c50f979a82f21c49b4c537359682549599251ce618b011554411cfb1b244d6980da2a69a45ef3d1c0a708003e96e4de7e4796bc52ab1ea4a2104a50955d5cb989469db0f2d83230a7024c2be5108e72a04fdeefeddf883ebd6abbd52f757d6d7f25e51b7bf181ed348a838d86c4a54d208a2944326018cbb01fa3b254459404c31930e92f708f42ca7254892a7b48a3d650cda9c609b016bd8103ecf350f35795247f6966aa65ff1929d68ec07e65df15ee9a609331e46676e78508e2bf29a6564abb910a462d88c01fb43d329d436d964efbda59432c9e20370049f04f603021aca40426d32bede257ec8f48ab60a81aa4157d2ccdd0d10cb4ceff566b5e6b9905716cad83dc0e0d21ad9839858a2bf436640a637cf6a0d93600bf996dbeb02ac4405742d234975e5402412c50464504480cc5a6b2d50ad592f7119888307d50e90fb8e186480ec430681206dc82fa0404005f88024401e12db5af08548ab2e0d13bae60908b556fd839229dfe8960a7c7001103ac0554bca21df9c3dafcec16bb797dd25d28a446b06b6edec1b570f6cb01561db85a264ebe11066b6b62052a135b97a259feab4d43c2500fec1ed5e85cc64ece02c6b00aaf7822ea2d60a921c3292946f690ae2fa976908fae1af59e2065204c1592e69e41bf8a0830efa0c04414b53d15e10ec85e400f2e74852d8735fb200638c31c618037170dbf75a7b814a24510014cc8081174a5a59df2f94958562c837bfcdca0ae2b6c13718d61e5435e811fdb7a1efa5ea1544b523093b8ec837f06df50ac2da0dd5a94e6bf7f42fcdda06e1738c3fecded841f7f97dd8bf8afdd6b63e0bafab9318804c6f05d885dc640d35087f4023e4a96e8bea3178aadb92915dc8f549be799341ac576f1200f9067ead20da0b05d666da4276a8d6acd76acd0a69c9e550adb5bbde0cb97a45412cd19f33fdc412fd3fd95620529f8c2485c9183e02a86660cba50c456c2e324f7568bc7ee8a90e0dd5d3f184f74563165169108d8038d3695175104559a64e3d3104aad72b8ba73d05b22003183ef5b61d54b7ee8d2558fcf55bab5bc763071b209ff644d7eb4ff5c1edd55adbc482f6f5c8ca245f5a85aaf20c8492db6fa05fcf17935c2298e905bfc51f13f4afd3a00dd7e96f28d17fc90bbe4978d0cafdb70bbec1bf8086d000742f19e47311155ffb915f4692aa640c1f416b0637f0bb56514abdec81d8b5efaed59a50967cabd5a8b5f65e8bb3d50bf16624297b9d00e2aca621f25497060a83270106d5da750e252e3b10870aa2faad59c1187b4c53d1df1ec473ab1848ba3456df34aae3f27a3a5692b41949aa5a37d1dfe51ef770a5b49a91a4aec7f01152d891a4c09a81e79e974b39c8a3217646926a135da29f66fa095d095d39096146bfa4f0252a84995013dc2b70184c82de0a21279e8cb434835e07fefab58d2ff83cd208ff256f69895c8b73a5dd80fedeea1863bf98620dbe1066d62a5fb71a84e2e4b6d6f6f5be77f6445f3fb982f06eb55ab93a7decb5d6ea4454441a7433dc5a9b0999c94f240a29c9ed336befe7e16bab9610bf21e857129156db7d868b16d2ebce84fd6df6f5ccd6d75ab5745a37bc445aa5f840d2e5caaa2b57c78b935c560a4ecef4c89a5241770296d41a158ebc11d3e58c1126a9ac5c162e86317cabdd2ed06d696eadc5350bb0a4990293142142c40319c4636a6510ac54e30585cb26c34c149d39c296d284174a2d28a6aeea6f6e53a273e46f6559eae810512acb058cd1a93107690e4ec69c11c2847861533170d812dc0d9382b3615c706594b892c2bc4018be5e589a7d61cd10bfccc890993ab2b9954b1232ee4165c303abb284bd345d1b52eeac031b9351c360e0c8b026187276883aaef7f585f565c65a7bf157d8979a6fe6799ef7816036c090c2300c65229810b01e198c0aac0a98979f9f9f9f9cc1bcc0d0808dc1d0a04183860a464adb86e9086b12755f3f92bea270412878aafb52c266cd1bdb13dc8604dc068f0fdc26076e03f5c2060449f925c3502e99626392e304cb41222748154521ded49299941997b032615c1efeb4441b95af1f5f510f546b12f8baf1851bfb1b18f65427078d9c3272ba7cfbac922410c3e8cc419a830b81ad6a8a4d08d5234629cf17374ecc4c098788e001cdd5e71b449f398b111b3e18dd8782e0504dd0af510f35eaa1c120d9c7212888839d7d08b3f73c030db924914762cba5ab0a98fc817cab0501790909faf1d5f38826623fbdb42bab6bd745064806441b946c6b926f05b8304010e95714ba2e23d6b69567344457ab37f26c9c2ffade888271f6edb55b7c5104dec8fb69916948445addaf83f5da10883626b97d66abb61f41a5add65a35bcf55aed07272c6a42d040c66b3d14eb060b55cee6d14d74535a67ae0d9493ba99727572907b01038f4a8e474e890c3b27d8f9e5ac9c2470b016c02a1255c74a8f330e948f25a7184e30e70372755e9c7abaebca19811c97ad3337766e39c99cb95c97b37339b293f8e4a29c5f7250289e3a6387c971a08d0b4d6294f92145eca90d1593932cd725b40e387dd4545184349533399aa74d2873684ecac6022f098a4e812125e5f4713a97b301b90cb9761246bfb8fa044aa795a8988db38d20c06a03a60db927670b66fa85b3079133b73586926918b4502f37627a085503e6dc71622585c8751634e700725761de50aede42d784625f504c60319090ece82221e754e46c3a676ec9d94072d4ca996b1c58ce3267063406addd99cb79d13bfd8467860a678e3e69ab14ec60da0585734c379d39386067aeb3c6ce386797e91044a95c600024272dcc7d9d09c869c9d19d9cce33078637540addd3317427fdd24b754c8f8c335752acb042a72e1b3bba8a9e51e3e53c72fe6893739c233820c849bb7214a4f172774e30c7845ea15927f5b2878d99d30590294cce496cce49ab206970d234f77e3afe63932729cca163e3d52442209783a2d12ed66439c3a8983387651627eacc39e1ce38556270985c4c9933c2c3f19ee73645de9b31c2db21a7458d156c4128141b9053a4ae9433945983f554b726ca8f4adaaf9a286974e50d3b1998e2844c580dd6a8e60c53995b03e4c7a7ba354ed5b6ad55e55936954d69aadcbb01351580dd76c0c2097df29708e3ae569e7a74f0a07a49f5d587a27c78fe8d627d6dcf6f50ad559f40b68e1b9344d7f189ebd80357670f63a9b57660bdbaadb492ade5d75dbcddd7fb3a514731c1370dc4175f4cded103f286ffda296289fef60c3654d043105c41677fbdd28a0278b4c88ee8e08c5b688a02ee9ab01cd1d9d938c106d49c393638f8032fbabaec50129ba366840d97bcdd7a20fb74c794f5796a58d1c082038569c9c834e5851bcc0404000e2822c606cc489a1f7242aaa75b421213d3d10c0b4e06a61647f7de3434dc5c11588d45dd71fa121287ea6a6c097735c2d0b0b9710fda3181799fa73ba62a7ff35274022956a8844a035a98e244513903c74992375e5ebba5b1dd52938d4d8804a703e378e06c06e2ca1a720e8fe07078876b4ab271ed70562f80a73bdc1010bced374afd5a15d501df5ffdf12561bb9ba4fd2c6e5737698ea041a3956fb91a5df022b0d0a0dbc988b3938164cb1af2435503638cf1ed70ea94f1c0b5f8763392703632bb195ffee7e96ec694a4322cd8c6d8c6ec94bcc031afafcea12d50e37e754aeb0fdfda1fa291ad1be991d65a6dd0c7ba881abe25e9102e5bbb530af3e2d39d52162b0fa8c96262430718205be10a6d90feb651f29eee94aadceeeeeeeeeea63a6a8d3e25bbd80a6206d415a8167d6fbd679f375a073fafe14802246bed4d4713f5ad8bdfccd2ec539b01032e7a3cdd291d79513692189293c3d184b54e7a60146cf28215db7bdb12b5c57e6ba7b576f3a8607baddd293d398db0d65a6bed968c9fee9470947894722b28c9f091f7fcc5bb24342f7bba4b129382dbb2dc005b0ecaa15d1294b74f77494efe56ba90e46fa5ed04a932861f729ecca35c799524c3b694d4428d18d51b130757a9848c102fb61956d23ce14155fa50a19c03048a470a37cc183196cc3c315e64b1c3244e0a6aca2e664a295faeb0983daeecb460735ac1dc09f92ac17684a3ac8241030e0ca43978ca3a5f43d8985c593274e52e0b10296617931f53259714be4c305fd0b10389a9dc428a619a90472aac44a16b4c2b29cc912d245009d3c47603898985c8181fb67387c9e6a849c99152a9678f39858e0dca4d0b68ca27634aac2e495e306f58915162a351c47c8342c906aadc72be98612be1858b72471d17e0b84893a38c090396c9c295f20428659e25a610236282bc4082798e50da71812bb5b838ba72078a9c2f6bcca918cc2c30b61830d8784429a5aa4c24165018d2a3470c39b0d43099762d605c19b3f5009b6a23e74c29b6339b6831974c797281c891b284a812cc092f9c6cb83d364cab3d493ef4849993c5ab44b265961163eee11255a58472528a49a2470acc0fb127734dce84a1474639a6a785ad8598e9e4cd132e3364a47809b3624679526651c551c13403a424c3c336c20d332acf525925cf0b5b0e3b5de2984e6a82982959f8f294432c5e7278651aa932674c955ea24a273e969e909c34c696cc2263472ae0090266f2e82acf6cd99ec6bcf0a2bb6233e1aa6c5255de99ba1365d2f16112792a879c65f02cd5c073545ae1319bc06c4d5d65922daf315abc9463ae985e57260955361c53e59e28b3ca8789e7a954e1b4b9b8b364cbdd392aade03901ccacd2d5c25679648cb98217dc9512cd559baa335368a24c2c1f2d9e6c36ce387696ca37768ecc1c1e9b0e302a5d495b25d718938917b3ce95d2cd559b2a38536ba24c2b3ecaaea71a67589d251b8c3a475478cc12c04c2e5d2590ad126c8c69c38ba974a5c85549a76aca1495a812061f604fa69bd34c23b654fe103b3212ed9e5bdae798835aabe5bf0736509d12580d3a005aa7510fd5ab530fd53fccc822ec065f39f8aa0297b556bbc90e94be1d010d61bd7a394443d0c7b7471b4c82bcbae184e71774a72d4f773ad63c039eee743071acf7a7bb1d475ebc333be219fe661eed5e0ad0f71cf44b43d06f4f71ab8ba8200e7aef44fdea462060f1f445d4149e57cfbda741f6e2f0edba672f066b2de8b1cc2fedfb482b0b41ecd73dff2ee897e679d05f32c85aaa3abbbf5eabfcf5ddd31a11cf9a7641152b8a3eeb4645df5b3ca2c0d6abd75eff76704c7167753c71ab4822530fedf4b675f2b9f7f50718d93a55cad741bfde3444e8177c9987b4a29f6fda4d067afd79f8b6980e281db86ff7c6beddf37afa2c76fcf8023cdded40fa158d45b0bd968d24ba7be620f8854dde46bf79ee5303123978947a18fda3c93c9016f41f088e34702cd16e5d846d1c1a5ddc0dfa6d44e1b9d7f5236ab7fe91e2877b3cd1ee919e75fa91e8d0e4adc353a71f60e4a29f6feaa1dbc11c93173d0791a72f6281c23d7d1c632ff3d0739079d143bff9f82d8721a9211465b4998fa1e8216de6e38c06bdcc43da8d05d8e1cdfb79a3fb335f711f03cd380061fc83431f1f692038a290b948fed06e78863d4f45d1087e74a3eb9ee823f369998ba3e8230d4d84a4e83ea2288e331765b4cf7de8480b7a198dbacf38862842b0d6c21926c70e2e7bc1040791a7cfe28b3ace53fc2376a03416df23099ae74d54bdfd03699edfebb74a3159d46f9d08457bb56c70407d88a7bb11b27ee714e694f51d3aa8e8dbe79ed7cfbb794ec7122568d1a2858bf7c8d9075ceea7ee7d14d3a0ef403d50f77639afbf4ec35aefb8c147269bb94fb563079ecf3ae4b16d588915fd9f7f7091653ec296ff5c7683cc5ff1861ddc121b464a650ecedce83ea52e8e764421238dfa3b45ff8cbcb5254bb47b200d6560fd3c046927bc15fdb3b65cd7ed05afcfb07b8e6d4561dd5e9a11ee6641b463ef89e0f5d89b4c1396af1e3279bb3b897cf5d0c51fd0fb1b4d84dd32df50d44fdde87e7bd1cf37e9e2471a759346fd94bc591abd61577122bf08d543ff42af5eff0b7d457fe8962422896827784abb854e43af2e86e058f4f32250eae1665358f2d63145f5108734a3fefa3d82e486131f1149547d453f2eeabf41441a74fdc3f5757077425d10cc65592b55dcbf95290ef04d0e0de0c38d6cade592df62aa00a7d4baf776f616c4758f8487e997a2c5ea15df4a5e3a14f68d1eb0f803807e1d743c9e188bdaa81a358aea449804bd2c22ad208aaedf0bfe54500687d935cdb94d5d1f3edd35698979156a674349d3111b53029023a804cc983162e8146d800093160000180c08060422912446a250dba90f1480076ba22a604026a74a0261280a83180662188461000040300060100041188ac11854fc696ae111e10cd10d4adfbc73855d6c5157cacdaeffab8fd83d5225acdcdc68de077071832af5d2cdfabc90ca8e2f7f8c1279d154a6e33d9d7558cb590c132fc61a6a10901aa598ce0cc1f20c0ccb2640a9b6728ea42ba70bcbbf03fe651d285140cc105c091dacb07029941d5b2f1e33e25c8b669a1dfc76c6e6ac9840555cf00274f7292556e0b781ee185bca54e5e5559c2475ee2120161b6c648dd381deb760b75ee8d7b9eb6ad3e9a0d46f6f4b2f1cdee79429846ae5f5beaf9532df5bc74d7d3181fd89326ed2c0238d99ba2300cf3b1c8729d8563f61c925b8630918259a2b756a1069717ea2177a486599dad36d5b4743f8d45b02eccf814f269d4916990b8615c0150c1805a6a9cbe9367557b336dc615b3773ee07ec408d282987cdd98a249f89508a3bed15e2d030f1b7c65196289326d671f83f4c878ac08855dd3d15145450e449dcc2e46af93e83280e881ac1020d2cc3a45c96ef1714c1c9b4ce3e988238eb9141308294b8486afc40e39761217f810a6ce77e0eb6bd62d73bb0bb5e9de13343551cfaf0293203fc8ed9a3d3179c0fceae403a7d1ed6aba382889dd9c365da81c119667005bb2a6264678abb08f9c4f86c8377f47c0c10759f5adbf434f2d7a12ac4ba24b2c88528832468a6dd6d7603127a32bc643541a8053100f150193110540072110aa43d4d604e40eb86f280a677056eea8d98a8091b66bf68ac3d5bbfce958c2bc68ddf448399cb0e2736b27cbf2c090e7c3447f81609b8fa5236dd012b3b2e7092ec10984d1d100d3e4cbdfacc0a81f6b55b82fa622ad9fc8283971daacc47ac8a602cd2167804472ce35b200b78f860d56d07c8bf43cc5c36226dfe2e8603a3e007e1fd3ddf6f00b8a51595b6d6bcc8f6586c39f7f950014c6acf1d7ee5dfc5b21e7639f2faca85c490d85232a757185e1379443f4766b451b3978dcf28afe121259f5a428cfb9b8a05fd9dfa241b6f91df05bff4a848e24d692ed71484f1d701dbb6240c88174a71a434aad0b97aa508af2a69839902773466c15aa40a7e8ca38ec26fb4e9a88d3ef3543582d0950342440f1d07de537c36772a18692039a61e08724eca09b2e20a6bfe040f4c0cd8cc82f0e68cb5b8cb10f300857a0de483f3e358fafb7ca02f03c68657034be02aaf97dc25cbe11021142143908d6ff1517bbb0380726303058f17ea7a30baba110dafee98c9a78d0289b6ab0c425e5b131539ea8010898a0ccfda467de2acc708de1b9305bed8fee4859cc9b998872d7c3d40427dc96ccc69cd5f37ea15ab0c19ba41203c47439b7dca07b3e5849fd63221580870aa7f1b82d297dd3be103b97117fe3305da99aaa26500d855c84a1bd93cf9264cf7434dea47152942bc4684482632cc0d2a8da1d03804eb8638036b6985d590f6dc058877b64e9487a434499188dbbc8fcb1a8e226da167e70e075fbdf7c048916f998a9f18a96f32da0bf692e218396ae83dc27fa11a79077bb774e01c0526fdeb10ac2d3c9d01d230d23de224ab256f81d95cae2704eb805268241aef58b49834cfce937034b68750c284ef428d3655ebf60466ff44253edeae876ef04a7308533c65f3a2191604fe675815ef8ad254ae12403751020103a396798a16f409de6c177c113fb874b652893761f5aa8c06d4372431fc9c64b4394024a02263f7e842c4a28b36ec22ea43c877f561526c6d4223e0ccaaf6eab4b6d5a12e11af82674ebcdb3e5889b5ee4eb65b828ceb40c77c219825f6613dcff4ea2a0e0d16d1664db8be1aac149300db70f56bd3b7d8406a156b11107e30d626d10ad5fbb75bcca7bcd41f140fb3421d85e5103ea54945bd62d5749a7a8423c7360205160497a5d01cf00bbbb96cf0a03812aefa0931a6d6917321ea4591dd0b0511ecbff0c3d2f7b4c230ffb2ffff626608b94c6fa52a698bdb39feb55787a42fef2ae9f537adb7d501c308a5bdb9b989a9fe6b57f3b49ae23be0e1cf1cb01ddfce3921218a2dc91280dbd7b89357640a411a0b9f52a181364e7790298afa9213bde4ea2c53f71d4bec974d3e234dc72a791404ec71b1136e8c7613bdad0a6905f138d70b201d85633374c3f9731ef882e7a96f0939c5238d25c881cd8050ea74cf1a34c6df452c976e59fd4e40d99066c1ae90d6dd1352bc401759f0e42a8abf4adf5b6a0631ad27b030c6507a22a05c8971705026832d817aac4ea137775eebf5199d576358929b989bd6673f3287903d8509ff64299b3ef273ef634a9e55c20e7dc0bc7199779071513d208746ea4342d61b51297f052a79c589f141f6b48fb5885a62609d4de4aba808de60b2bea5497b2599df07bd949890766321d1fd058489cf8c6007b19694f57d25fcdb1a1742cb12875d87a381db63700d6f236b9dc7a2cee5c5e7f93ff13bb92852ce48c39ae53f3c1440ce67f81a7744082950d5d7e2a51a26fc946437189e0e40de978a6ab75ee422d02036efbb1b301b35b071867907547f39288f674ea7a324062ae8cd21a2f510d52a46d6ffa945b3991c109be2ec2d87bf52471c8f25b4c44964ac3864e66c12b6cc4b21198f8ddf31b33da55434e883a41ac67fa30a872049cd9cd3d8845b4de12aa4f25ff08c414f9e142d4bf7ccb32ec6b4830a392ee26f58b33cfd46426017271918797bed8d8f4bdd09569ce95cd8224c843345b67e4d1bc6643d39e1813bfeb1d249249c56e445d599ba67895a07c43fa7164723078dd1d15c1e9a6bdb2759666c06d0a48b9cd36ebcc7aaf844dbe2783cbcbaf3826f36b7bd63331829a9e5a261044adf67f1cc81a01331cc06ee82b106540203e234cc3e20d36c6c69d5ac98c930b87f633efcf8945b08d4a0c9a8a43c37d30eb00a4dbd7b61a925a5ac77bd835c4cd7e3ed79bf85bafc44ec9d609af201db1c6bccc60ce906ad489d9e9674a526cab6d1c23321b4c097054f62f65244e6c0c7b559d85a45a8030ea72505a4fdb5ad856177eaa9005d99a8b42a9885af4d202eb0bd029488a5019b0f31abac32b9376389d784f8d4375dec91a61cba3fda995a65e3d32adacb5ad33e1819f843c288e2cbc0dda463c69b0653cd530da60a1c59792b1ecf899bfa7a9d8fedbca79893e047a31e925855e70ef875be3d1eb4294eefcc6d1b38b092d854eb75036bc24bb5475a066ae517b0c869eb91caa8a24442f68899ac572c3a81c16eb4921d276afb4ce383f741f8086f2210e3f8797928702898b743a53c5b4d59d8141c420e221db033f651634ecf23cd438eddd1b3d9517f1ad3301b7d514b68d7876e6fb230092a1b5eab1f8c9dc942364eee66e1732b188514d13dfde661ae15713916075a818e245c694e46fbad8a73e80f074caee4ec23398a30f83b0e76731f2524a8e1893fbbb38cee05a0f159ff844817bb5e22801c6eb222bdd7b528476a6c1920008cdabace58c39f5035be4f5afcd1a294a801a6f74d42b20aea1440aad492cfe492a60c503f4eff54473b9a1bc1aededc5249cdc72c7d5bfa1440ab67ca8f334ea48c93f7616a9d4b9514357a2e55b32c4f63e698d22d754b10bfb81c97966f138222445ae6959923db6693ccd474dfa64767cdc863f20f2cd1682b1a82f03e652a9c5f080e660ff75e4549610143e1e35dfa75d5bdb1c1bd982873057734dbb6530894b52e6c9912c8b9d45182d89d03208974d0b8749a1099cd4a3c3317a5c8bed30eebaedb7dac9ef639f070642bd6013df7b5cd1e3b71685bb1297cc5853610912173779da50f3f5dc400d1b30f55208ef98e7e401fc5044421fefff76913d8779e11e93bfa38059a96cb755ef7878214bfa9d04526be9866ec0d1c136fdad2da0d20b60e4d5c5d73f35dd8684354afb2b4a44994f63846f3a0d3b5222caa64010772638ce33f271a7f03b649bd8ae339b5a2c18fa4f87398839c87ec7cb41dcda1fece1a80ef23c340593706486b07b1e18d80f827ceda83351477e8ed76d2375135df7626abda085130034f22880e054d6f84f18528d81c5adb32cd85275d11758c30ae049c7225ee1e0311d04db57dd4af396edd1bbd36be9ed649f12c82e1065393afe5f314c8db69cc2b4f8811ca4e63115843018ebdd64a6879c86fd4db45b5e452dd8c3b58490081cd7b08c9d02482c9c20c3d9bcdd15723bdef419732b5c417dbb7f9f63d471a287a80b8563e2c19692e596e5038abe631affae8b8866e02085530f33dc65ef6031ba69c318ee631cbc0515c723d82113835ef1d998c264b4909698caf265a53630897a2a495c5c716d5d8c542e4233ad5d542eb18eb04f0d00791e082b988b574bc3f128f9704ead41cd77a9426844103a98167d44d97ace544a52243e87c04e2d94d18cb89f0754e6b9a69b19b7c7bf4c58b3a37589bae0e8c8ac3e927a4b25190d030b0bed72c0ba734409e3b68097504ae3b1f8a48ae31e323b0fe4e2a4d7027d0ac60acda63a2df71d58b61c418ba08b0ae987e774c204c8ec405126d35e30b300a838fb01444b75f7fda0e2838a3c749c6b9c8cf04dd644420a278bd85a41d38b81376fd08300f263e09622509dde9e1d751835efe0d7d56559986d160d432021dd8df83f3e41e32a9058c54e60994f8cb24978289123316b9679a738c056994a4ca0b0aef3fac7013f7057a4bcedc14765d0ef7dc85013dec130b174e3c13e266cfe592d74496f1decd8598c8db4763abcf863c878c6cf804f4642f306171163a8ee22ac2d1ccbc1474467f20f508bdd7098f732c60c8f41b303fc6113cc74afdb0d8a8af79ca06ded9c1497f6b439bef2e08d0d36a6a03fc0888bd6574017c5c9bb845aa2723878d0857f7ad68bb4a9695c7ad8f94695d6d7e4a38e520ac37b7c7c1862419144a37df5c014bf1a6af88d38b2293b0b2792c52a82f7c90081a0dc47cb1760521b1e52259aa8452a46de052d92140987b1349d1c58dd979e0254d7f54ce0c772c3dc9f5364f3fdb2c89de47b390fe3c268438b06a516647b3aba8e9959401ed982bb16b901f496afa453e5d6b32bf9171c93f48cbb3a2acb7c85c2ff7989c71b011db0e9b6d61b62acf96b3f08619e84fb1a0a5cc13ce9aac1bbddef4f8ce4f285c1b975271cb9c422f93cd869019817d34a5eaa920faf2d4b24df84e4a0bfa8670911c6f3a2c42d6d46c198a021dbbde9d046e1451c5dd60c5b5bd27344f4a80799f54c7526c7f4b2746ce44bd45cbeeac757c26fb9660a3587353c0aad0633aee0e4964d08e25def8072bfe54b420b050d282a0c3aa32fb2b721e96d09bd1f9c48d66cf325de169cda579b32f3ce64c525c773d0f79d54b7e17e0b17eeb4ab505d72114f250d61c5645b96e7f612524deeeab54c6a0bd71bd661864fb08baa6e2a078df09d9c683f13249f2655f4d018a83bdf4562e57874e1e34323d47a49e67cfd546deda6ff61d1130b1da5694c65723f416081d3b6d89f2a7cfb4b0adcb46f6e4fff19877ae73cad32226ed0458479ac746d41a3c22b45f1dd622856eb457ea1e4a0d283276fa9d91131b4e4e02072a17cf9c2b6e5d4953de16e98e34052b61c3edc5efdd4a22989aef84692c3eec2171efac1a43d46c4804b506a4cc3f20efd2e1a8383cd313bdecb2840899b0c49d74f753eacd82fc3f1cb1ee71cc385a84837be940b9a5b16da816af903ffcece73d13f6e993c40d7e9b9190d917046adddec151a39315bc2f9550c75f0c34d67d42321da1b751fcdac4c4de99b907358a19584069f280ed63ae55f3dc88eb41bc1a75abc9490c5a8227dbd6a79ee2d481c4fdc1989d3c4f751a0ae5e14b9dbf4ed15de08ef136c73e517c36a28ff34f6b5e3a4c940e6f5c07990eaab578b23c8faf347eb4acc01177534c20596a8792fa5661ee71b96d0dc71419a2fa94b71f0641058859fc6273452ecaaae827f53be886484806f7d5764fe0c38ced1bec1763a8c6390b2563ab10bd05a245b66c9af386e6ca65d23ca45d8f8ace2fd12423e62e9152fee9079d7cae11ee0c46404c63f16ba36d3269c5da10f215e23e5cc3bb1bc26bedc6c97e77903caa6f4933c07629f00943aa6f11a79c443bef83a0bb521de7439a2e061cc09ba5d8739a15a5196e7d58c9a45f178c59dd9162efa08e0837dd0d3ffdb3f8dc0755158a8ebd9e7d482e1221b461966a1536855eb9333e1abc4a5ad08e5771fbab8389c10e5d13fe08f5502abc93735d579031df138cfd4655067855640cd072c7ac4b62673cfed9288feaa01a539c6e1c2d0783946eae08666b6efcf5ec235a83213855303ca62777f8a70dbd9588bd7b2c55f4702e113a1442f600ebf58410a41a685c4d8a99dcf81693aeb1d7fe9647aac1cc74fcd4f9d3a40047c4d99f562a720041283d6325943605fd7c171ddfa2bc8c82cb737beeb172c02b4ceb2bc618e63a86bd1c3d95cfc93ace95110ba10286d1830410fd85efc91f18a9cad9363b419e3a28f62fbedd09c648f5bd30095a7ac99ec7fe4e9ff83502a40a6581eedcf45a2d591bb0bfdba27f6b2f27486ce5a095102841bca9e1c09043f23b71d2aaec20dff05c63c222536acb6efa65c672062b23fb3f3f334108f6d36e2ec5fe0df601ebc87ec3a22a4944b6e0f34256bd081cb00673e0c6fbb9f47ef25965bb915629560cad0a42028f607b5905aff98c05a7e2ae8f57249a5040da96205f343ce035a89809c780b81e47aa17243d11083460aef2f99e399fca13aca616b53b2f895e37aa65efbf75a30277b8834fc5e873149fd7c666d2a6fa281806736265093ef5ee44c3ac18a198bd0e7b582d253388ec7a630ec1ee924b60721f0b48eec1851c2826900b68815eda050274b4f6dcc7c6dfd4f1e0cea735a12bddbab9a9b3d977907889782200a117f75b1b8778b816075e543571dbe5c96d11384bce3f971772bab81c616dbee9f29a78acfa3c5848b5837bad7bf192660a403dc88ac997c4e941c812dd4889402a349e02ee3f56ad1108e8c824c58f2b8ec01582ec8239e720f0ad16f10b5e14249364631e181e626ab5b04dfba6caec86a3f05f5027171c62acf2e1c2246e4487d39655f218faf1519a4b6aac9eeb5a2b1de13c2a8591c234a89fe2e04891ede138eb07296704451920370205497dab2db1055167210c6345eee3aef8045d2997921ef2a240d9fa8540b8c183c1ca36f44d5e8dee48a79a20a5a314609e767159808b47a4c2e2c0389ac983be28ada68a5be3db009d2e233058a0e9eb887203061f5b0b1a567ae91bebb30cd7a3dcc9b86782b838fc2509ad9ad6cec539bacb0970f19ee0d66d95ff0a3e7de0ac74037b8f9e73046e59f95bdb146499a176687bbc6f582dcfa49013d47a66a0a1a393c10cc2efe68854a1e66d3a25c4cf8854409dac16c0d82a44de006faf8133b9c1bf2ac77aacc6809707416b037a94ace98895a81e7f3b815a2d03bf08f6be3cb2a5799fe1d46fea7c61dbf9f74fd86549e24c686199fef9275c49ecae94726cc59238b2ada8beca99b882ed9c6b0b6ae9829ff8401b8d28edc4d3996bb17f209fb07f446e0821b00f1dd3b00c78c214c09d2aa3d769ee8539a846b1dce63d83e93ff6ef37b4e932b9fbdf5c5c807d02bb9f9e26ce61c44a3184f2754d61a5e791cf609813e68d498541ccac3e5a4fdc134e8fd5062fc075cecfead1b846be30f65e15a95619fdd85a11fff33eb5866150176209bb004aa0070190cb867409e6b01e969569b10aa9d9846f32209423de08368ec038fdd46d29217c11b408c08b003499c526c21eb776ae72370830e2c7ca05178141f819de12234413218bdf0fb2ede2e903ee0610af440143f41b30411f18e7609abf9dcdbec32dfaeed8cced654efe54bb2e828a2330709f3d3816703eab66bd880b27ac724df5108de342f9d13936c40a84de311a120854373bc648049c15579f3dbaf3e13ebcd62e703e6de78f8816e64f1a9712e2fd08ca699f1a6a17899f9a438b78ef5b01c1672e762ef253aa0e43f7332c07ade707610e2808fd8b66c29c115f81fa6a47418e0effaef627bf0e43fc33b5250594d6bb759fdde53eab960702882158e43f747456e07faedc73417faeedeadde2fcc039822196112f840888310501c1a7b97370d11fc372d02e458c7c2ca89bdd92d667b0bd25e8020d2ef19e789ff5ad0f4231021f041b44244255841e842322c5113f0df3cf9a2d0dcad266854014e4f35e0e63f629ddce20d4053a8ebb6875e9afbafbb2959bb2deb13039ee79d52811bb11e088c0207c76e05820f8d49aa54400fd7f5cdb2e9e3e076b2c849fa4db59c43bc4388269884d107f10e940203e0283fdd96c592128a09a7411a6407022d409c102e1134327b4f8437351237e1055bb5e7e6a49ebd6880b7d29979b870bdf02cbe7c78d22744238431c8b3081d08cf823d485c00f016c0486c8cf789d15621f89a344ac4e88a0cf4f7b4b4704a04f3e436f17a84f96ab4680475c422884f808210e61265c248dcfbf8b17741c250cc048264bd21dc6c2874edbf6574b3446a74892fd915f8731fa99de9e0262d16d5c68ffb88f352df89f8a70319da245d6c7f706a31118bacf263a16909f55e383501881f808b598fd17ec2673f70e2de957be63c06e932b281f8c5383c010e88a37ed6c8422e21191e35f3721fce4c2816a7fbeb462207420441719e14054a1502c84b70d32a2c5c347e39e42d4e9074dc999136707f904ba154658f14aff68b140cbb5ef2bfcd06e2915d1e2ff09b6abe2f919b7092116205e208e20cc204c1b01d4f7c96afb84a0c2f4415a3739ea936d6d1174b1baabd20bfbc7eb680c4a1f49bb5b5fe573afc98b70401446e023b622a0405040ec8350cf8816a34fcc5608840294d4900db0df68a55fbafc8c65cc02f5e43cc54d5b118213f14e0446d18706ce0a854fad43477c10aa362268fe73e0e221c48df093f823b841019416a6b9e1c4533e99561501200816970f953a6a9d3e15d92e923f2bd70da13804e0d715c924b9f94598223623a6b7be0844f976408d98a1dd828db8618c9cdfd743e1db1d73004ead119cc5fad16eac880ac4dd0807083128be19027a4b71258e1ff68759f0d66c994b3d18a323dcd18cd3fd406a67b04d11f9a6ba33f81fe1004676014597d65c88155df8aa582d9ccbe104f904bbc208e5106e448a44b460fad41c6a08f17db5444ceec813217e562e078218818f48d60f8a7db20ea351f273e5ba1157fc73551fef001839445f18f8bcd0e4a3d14d5431848ef013f80fd7883081ce1ad144b06810c67adc093bca4985829345bda9710f90e7d9e0b721cb61c9668aeb3366c6c2656071dfc0de396942d496aa8534524d91816a37785ea7b69e1632d42c2a8082f6c12f6023922e74ba70508c6c3d8dad4b0feabbd3855e720de3e7c033df67e219269e088187828f76292525dba9f2f02273c4fa3e72acaeb1f17d5d06ac51f942519e752883cc8c104a31ca6dbfb0d0ad27056cce2c74281dbabf04b164849eea78bb0d563a40e03af63efddf22790ec5ae19baeae5f51c9ac1cae8a9668937d4fa622593724a7cb20ba44965d7a2e73f0a75174dc61806c13c60756e02f90537bc085b4b5bc2f02329b9850037f6e4f22f9af210dde652fa91af1d5f35a972d2c2f29b3ff152ca6208cd670a662f7f9ce18c40877aab9f5a23f04a4b4e3013263b42d0be41490b6735c105bb62f59e221a3f7835e5a12cf6781d742643e8c94c4581d6ed1df6022d46aa8a570c44372f61d8473c759e464480cca582c34cab1a7341215aa45f418e9bd52486a3e347a6ead63944e7dac11010cc17783a52b2d843d0c56cc17d75cbf045e3773eb550c54a4d7b3ce7ca5f0c3b308e821abed32e312b104f1977cb2ae372e25ac8bb2bab65c1bfb128b14497321398e3de11c120044641a31b42fef43dff86cfe76fd9cebd7f39cb4d455496019d4b289f5da96e04d061397a11243a1cef3080f5e1a9c1e15da744691101c4795341f017cbe057837d3978085c2387a53d0c06528895e1e428fbea0f59518a7c0d26fb2674c41453445fe7e7beff06ea43a92e791cf61584c5adecaae6922ff22125a0eefe3fd6b102809473f59ee10b63178a7b177b358d86db064f65b867ca6e8bb5002a921841ead9742607aa4d03f7a8aa58b66c18066cb0e22572294f6ee02d45289e277b0ec81e36d3d36863c9566473e18689a202f15a576003f8ac00f240d1b0fdb6bcd0857a6e7b86eaa8d277b99e50c9399fd48a1cdaa10b63c57506a039eef84e4e922c267376159c66abaaffdbb186b6d4f691e88e01096f081af7add35a6ab5d5bd259549e9672d48f7b1c8be26f6de0cd6fd3eba1220dac1b416752d3a4b46ac7713fa55b3ee3f300c2df0f08eb5992ed682098e77128e86de69978032b80a0f26b909b04c3b546eef6e727836a12daea981ff85d0f6d3e385c7668be1d2e422a859ec0e921e7dd6bccf144ec4fa805fdd037905708732b7f5560810661d6678496bbdc706201ecd62c2b1a02302605dad60517727a20679aadc708d1023db52dac037851174654d5aee99c8c1c633e150c39a0cf06aa4dc5e2cb630f4d492616b288f3ba90cb38dbae6ccbdf9e038dee09d196ee63df81b309f644277cac67154cf54da4eb71fcd3c1f5789e73a8f9eb08d579e2b5bef842f0330ccaf29662ffa74787ce4fd8f1e29dc46133088960ec5cc62528f4dd0109f5720d5fb88d13a3415c1be9241085cc1bbb6c5e7e13cbcc1d5e340e91037b99f62001dc4288ca577e6586e5fc4861e3290fbc9baf51d78ef7f46720e16bd840c451e99ddcf172f27a7b35c6fef2e3c82535c9aa6f9d92384ecd130a49f6454c16060525529f68ee21c439ea9b1193f8a5cf7af1d0a09f4516a905b138283c05ec1c03aa4ed05d274155bbf5d5b7fad5b1ad1218788d6646543b7cf5d2b85cd366c53ce0e4fd7287047c7b2bf1d2a79e956f0af1d99ae73c92dbdee061f71e4f661646b1c8003c4cb356b5f25524ea1fe5ea07196b40c2221dd2abc4158059b9122be16b618c64d05a763106bc07882ddd768ce7bc0650ae0baacdb227a7514bffb8336b7783c048603927abc8201cc87214e24a7b0cffba678726b8d4dbbd590124811b1427c05fc205d37730a9914140ddf0cbf8573b05753da8b48dff27b6f7c7dd5679db2f1dddae9c7af267c218c62fb9a7729c846e2cf29a0f11140ecd658b5ac6e36b8ae8490ddb84a07214e22824bc1da031cb9fe4549ea348434b81c43c153a70ce1cbd08a8bab1c8cfe4b0c052d17ea21f209e1118525c287ae01a8dda41e658d16e8f4c015ba3fe94002a376311e901a18d15a199ab6e16c874089284775ce7594970a56836ca23ce68963c9fec58e96590a81b41b37f17486065e0e3f472549d33683d2ed59d6f968e08e311ed075b19590760400b20c23aca3d19ce1aeb9e844a68602b4515855e5f1b24ecb1c2d9aba5dae071fe50b4863e3e9723be9fcdcb60da082c68f3d7758b48333eff20fa89bc0aa46db3fe58df6a19f7d1d46ed781522c7cc0abfeed35736572dbb640fdb980e604b4ae5c6aedd02051adae4d77c9e3ee6985cd7542c50bed2aa89658e9f3522d7f47baa55e9f13ef23cd98b79447f27f1192ef038aa2bd2cbb70ff4c05e27dd8c645dea92bd070675cda7d7ad8bc0c2e3ce6193428815ebd698c6700de565f4ce8adb9812373582755924d124f5a8dcb9d81b2f44eb2acbb6d73c2b272bf310bb9e67acbdc84f8a6c260a85344ae80e3850c9a0cd28d2225f0bee6bb3023adf19fe1c224c16d3ad0c238b5472fe0cd50963c0140e592e9a25ae7489ac89c109492c885595f80b538264b2b04b96e74b57b9fade342c1c9b6b18c9149665edd7698c8e446493459060e618d80a9b8d6619a0b3c8b2d621f75c598de46004895960b53f09fa9d8cfc9d3d110f0deb8ec5521d51953ef6f5be2b1a2dcda9a5c4cd3452bf3f13190916eb4a5e1d104f1506bdc8e8cf770ae7a2bc2d6ac5b79eacbf4c6c05c45bae4f447058d4e1fc6e79769f0624ce03b8d267841ac2d2fa3bc7c7c62e1a634660ca15eacf306932c5462a6005e08aaacdb4fa24818b911629ce0294f3d5026c1f53a640ce2ecf177011235d0b119c3f957e07f1b41189a265c89d11c904ea69bf9c3ca62ad86a17d9ca1adac34d2da70756712e90dad7a4a66fd6bebd694088b53e77b6ac51a9396af2356a77c5e67a6c53abec0a6f8a0526332dd61942a4cad5bf7a9a8ab88aa5e5fdd9bec59f9a216d90162e1d64b5742ecff9ec71695a1ce4067978eecdfbe9e02a47137370bf21b931963b21002dcd74eb6d227419154b8ef69a70eaf013eeda25eae5e2137cb7e56337b32615bea5c5745d20da9013f264ee084af59f841b34cd65228fd7226611f2827be14ed1b0f5c84c56f3af448be1e6facb0a9dbfe1dd1c8160d56824dc12f5177861c7496cf06868e4106d7e14eedad125f216b6712818fe4ce48606fcb79d6f31a56606384d57d5429394dcde3da5c62259d35262b5c5e6f89c7694e03dff1adbd75687d829a46809679488135536786406d6dc269d4c0734f04f1478fbb1cf39facdc42bf87cb10450acd1c9fed1f5a10e56be65eeb4ccb19f4036de83023047dcc2de521a38ab690c6499c113c0751a8b09c73539c16030e9689d52bdbd0cd8c4e96cef17b8b7fbfed1f6bcbf61f9384aa415394febcc05b1522051710e4647fc027e8be625a2133c691e48a309e6f03fd81af657d13a0b243f5a37715b31d9af8d0e45d98122c0d1cc3f5371bcf25ab655a3ba0aafe770f0ea8d463f18220a522b0827f52685695ffb9d470335e896d8501313ed174b78bf98b3ca6bf0a0f1bd34a814c4153ecbc4db6f4835aa1302b2e41f15cf1d5604b730cc687f502f73dd15a84d490b298c8e9d77cf0d3e78199f63084760959e1ec7fe0158ce978e22e99714840f1f425ca2e3fadcd58b268eba294b89f5a6e799b71dc4a42b47376527678ec25558a98ce88fa1d0db7341bfcfcbb94e1c520e5c608e6417a4ac1dd03d6c6143097460de87e9c5a3d880b770a294140ccd9b4fd4ab73b3b4b31833a4350974b438378614420676ed08f09d0db01b8360f6d51a721ceb74d91bbadccd14c122612c3388942f7272515262179a08aa4d9ce0353c46ea7aa09c4609b7d4704106941a5687148bba795e1ffb2cf3e922ac1f3fcc448131cf3f9cb21b157d88fd6bdb633b8e216e4b3f3e6680d689f11124a8fdf78506f78682978c367354e234dc8dba6ac475e7ee6fb3c9878e62f9bf09bed28b7899423c99758fa49ef322b0851fbe24ebfd2314095c9ef755895b25439a5f7db90a99521d1e7947db30efe84c51b5983329e62f99dfac60327fea0790031d69e1f3fcbbd2b0598b9c6f2d318f26476e15627e26b0d6b27ad027a50a832a892f1abb7cf21d4bf9a6fcfa05a62fd4da6aad5ded61ddddf405196a55fc552a782d2ed840a065d0a925a1b626cc83f3d737e9d09f6af0f678609f301efd750755af7efdf383003f0d10df0322547aaa1cd2c0c19598951da7d35d1abeb3ad4b720f1dac250075b6fa5010573fb8efd79ce826e9c97cd73d78f088f4a13efca13751095d35d816235ac5ec0a324277032bc9034422e354cfb62c12218546c9896316b456f2473f0647aeb29aed0463389d1d98c92518d3081c49116005ed6d9011d45049c448fd8bcb6fdcdf94545df8683984a5c762654b391d629b68ab236b62d1c3a00e42eb673a2ffb48b0b36bba70dd2b1789431130b0bf3837e302d1dcc45c5bab0aac1204fa193ba45410380b4d3a958292b819245d14f8bac8c1917fc8f55059c341d6c367a511eee873a983b4bf2a3ed17923ad32d6439de64465637772e31287f89281863798f56d40659be0800f7dd3d79b10b9e5de726f296592329909670ac40937dba261d3d9a871dbdaf463fa7ed51fb5404a80e39c9a0a95e63eca79fa33cb856439389ee6e070a19c108643c7d400c7c775e792b0bf5973a1d152ed32d7856e48ef175e172d154887a8a492baaaeb615a6e1ced3beb51c93796f6c1b723576553ae0acd48f92dc65866abef77a16743997db9c71fe21be771f4bcd13734a8c72633aeca0bfff74fcb3876b1ab5cf66ef7d5a6a676f797d3b2ee3babf1d55ed85d3b2ae1b2749c032fb0fcec72bdcc433c39dd75e5b58069f4fa4e00ef9c57ca4efeb679dfcdb0e3244fd7fd94fa765dd8fda5434a1d97e4f518d49cbe2e7aafa79267be9cdfcddf5b379299aba352959f8bdecbdc79b7bbf7c7bb3fdfb230b54a2ec27200e923c92453503b842d6b59d66cec1fb54ab6b72114fb5b28af8b339425a994f2503a36896dfaf82505cc7621ce7b99658a6b997d0eb69549d9f7bd135bd68e58b3b3d0b6fc62cb9a14135b695f7de9f75866297dc251dc7648f7f73f5d44bfb189b8dddd9dda9724fa729571cfbd7beeee491c4f8b85116be6951bf1d453a5d0b55472e4fae34de2deea3185238a084ae26e085a0d8b02fd79eccfc3f982d18e76958523a02240ae6ee0b6dbc6e3658c87de997d12e028ad8aa82b1c7fb6cb8ff8228791fc9c1cdf2d6d8cf3321fc14ec04fea66521f078efbdee3f81aeaf891d2211e5248cf04627300ed6b0f6bdf56ac4039394d71266772da9a356ace9c3143864cd69831565bb64c59b102e5e43465324da64953523ac104139628519204638c43115ca445d2470810fc187e8b35d00fe06b6323aecd0487a00892c867cf2417381bdfb81096443e42a08b509268680ab94c336b9a914478d31d379bfe5ce342f8a9cfa6ef4c2e347bfa3e85be4349229c4d71a8f3de4b99d6f94ee31d7aa6af8b5d8ed7d1b2c739f04bb13e0f7d25cf9440ead7d7d1b3e994da5f28a54ff534ce773ae7b117a4c726df0f0e7e9806f1fbe3e8cf458cb5f7327bb77ab5de2d7313d7b6619023c0515a1d7121efe90dcceb91eb73817af4a94dffa547579edea6672e6e3a08c8082af777e40757bc53eb48c2c65ff147edc45f7bb0be17e4a005506e22225025bb3e09bb86586afcd3d34d7ef6fd9824badbb669201dc0ad7abf69ece9b1674cb26baddb05e201dc9eabffd551c9c63e5b126ddb5699cf86c02f7fc7f8af27a1c0b93d97f52bcd37942ee2f00ea15dbcafe0ed019c7b0e000fe0bb726f38d2edddafc3b3da1b5ec18fc318e5a143d208080bb83dbd1fb5c2dddb755dd775f75eaeebbadbddaeab33ee76dde5e4b66db7ebae54aab5c9acca29a59cdf757a84edae0b9dd039b76ddb6ed7dd6dab72e3b83be6a36e0451f472c582e50ea516fb47abb848ab1938366a6b9b61cbbbc3964584d9f793b90817e2efb3fab571feac9e3a838da9576aeb66b9ed726fa7784526c6e9c938c40fe7f85c39477ef0f1ec9bde6f3bdfd41fd6f9808800a5e8e6429ede42a4ba9dcc36738a0daff4f164432892f77263f19b1a96419e6fead92b16f3f14dbdf33c3f32d2f7d5c551a9aed9536fb0373dd6bdbd72527e309481cfc4beeb651bf77c5617b1a16ce328f97472d1a56fe4a31c7a6175d1f33104785dfcf14d1d04fbc13ff473f2910d83f4641b4e282b59407f11007065cb9c645db4e19c62c322cffbedc73905cc36248239f8a65602802418c8373509f9c88623d44c70912e01ba027a930c3030b5d28e137000bea9a1b8487f837c64c314c40db0074c216d0a7df4779aae80738f730aeef931978e8436f87c88b988ef219eef878f259f7ca423c88faf271ff5841ce8f80048073f40be00007d2b74908bf806e1e7f3f2277dbcc701f8bc2ccb49de6fa1ccfb9c2d807ce4e120200fbe39c585f2910df1feac96b522cad838d90bab6be3a16f4e11ca453ca33cc4f7379fe81be5232f9c4f2ed6a2a6eca9736c1ce483b2c7a27c64c3f9f461cff3ba7cefbd2e6eb337ea0d0e85e1f01c311d3ab2f9c18ed9ec0339a55c5b28a54f372a39256d3f43d9f6397be72967cb8ca4fbcfc52bb95bef379d7400e586dd0db65724833d36996d5b6d682483edf5f3e873ba0bc79fb16773494625db86b231ec579bc1a65af6499ffab216b5c496fbb5a996b5a82eb675b18636c97e8eac1151266733813fafdbbfbafe74004309e0323b8ab69d8816ec9752ddf5939c86b2ed9fb3e9d109e1092ed207c12631919ef084e65f7e1550ca70e3a8d4512ff67ece106807d0e5d2b15d86e30cd39ce459eff364cedbdfb8017e4cfadc07f5cbf5f77efaf3eccbbc05491f294baf69d57cdf7d1bbfc077bf7428632a298fddb8db79f8cbae1778e30607862327474c878e6cb6a3c7eb10003b1f978106df75218efbc73df9e8761f11b9bbf0473632dbb46953e41e4fdd7803f1e3348f8f1fdfa6710f8fb8810619ec0020d4dfd3c36d3db6d29e1e9fb2a7a703977db9c61e93a4fc15e692e75d15419c01222a0832fb67cb5a10426c22b0f68f2d6b4358ed4aa368a896a5965a6aa9a569aca5340dd572217a75110896ba58b508404080a3acb9bb13b9aa56abeac90ad3f660cb9a1058423c6d71cb5a106bb610521bef4f6be317de91b01b2fbfc78774bc0b71372fed4bbb727264fa755dd7510976ddf7e1f8d98121930fa46946f052ad3ddf8ef2ea7b6b434b6d38564aada59b7dca86e65f615b6ae948d5d8d1777e3a522dcefbd1c30f36a433431a8e124be7836c33e7b7e1927b414bd350ab471c618e5c84bea568a6106badd61e73502dfb99fee4be28165a5d2b1ca19ddde7e40871507a63c9a537cc09c710c78d90a6a94fd65a6badb539a4692690ede96fda7e1185e91b389a7bfbb582e04534cd8759a25813699a2c5114459aa6880e2da13cf563348d28ce5c9caf43bff32c916662a2199a86a6a15a340d0ed7314505c22116fb99b9bb3b9d651ce642561508876a95ea17f5b19444cf66cf9768b6dcb20675b5e57355f6ac01d1b4e78fdcf7c409b767524e09640338fedeef42236c4774a17dbf3a827ae4be43c23df732042592a64a6f3b241989fc2d23a13fff0b6b0d61341fc90956fbd3e624fa3017a23f5f3cef3bcffb8e8aca0a4b92d9f275bacb5926dd7b45bad0b3dd7f437c6fdbb99fb9c8e52e0ef7b9396673dbe6c2a03520f76e2b13ee6f112ebca18ccb479c6f6ba3ecdf2a5137d0e770b8dadcdf1a7dfb03d5b6bfe16cddd6c1703a9c9b0a62b910dd32270f99569b0bc7efd6fb7e7383c97dfb37b2915ce4de2bb77411fbfef417dbf901818892254d52609af214e5bb3ece61f317f5753776df9fc97dceb7ff26960bd56c64d67ea8dd5ce4825f918d7a9d925ad7b47a5599f2016acb5a0f637aa8b2ab13285c9b366dd66c7f2272bb162ceb102c1dcdf61f97760f4ddbff89cd7623f2e73be1b6943e54c909b7bbcd3db513c9f61e72db943f7fc2c07bb276ae7cabba03399807529a10a6cdc659898d4327af36fbca073dded21ff57b68199e5f0ffddfa34708f5df8308fde043207abc0cc77ad41e3ab1f04b1554b024152ba2bcb2658a45318abdcc0890463a51ae0bb1904a4ec223c849d8564145159f638d2063abf3bb15d8aff81c8b4cc2ec672f33093b7e470826ff949c646dc8491667e160430d5938d54083163748f7e123d320a50454a4f80c4ea6ea471650ba0ffbf6addea26ac76730339a9492006168b31f4880b39f99843034991f10022d480d58440218275537f0f8d9f3d060709e879ee160d72f6daecd0eed248dc81dbfe3f10e4d250c4d4a0250e1f13ba8ecf8998f2410e677682a3c2210829492003cc21b763c952aa49404a062444a49801da14ccaec67dfc6c63cf4ec77e85908267361b513fb1d58da198cfd6a3f87b222b2cd76fd93d1dbf997b62b63133871bd077a6cfb733a11c196d7f0678c35dda2d1b0c676db77854fb0abc853a0d16834fb3a44dc477d223323b28d8d671a8cb5386cec0a9fe4d8f604d73de882a33c3e831732cc204399186488e18ba6189ac080a10986305e80e105332ebce082184c2e30e5246cf318519cc9a3d88c8216d044692127657c06c7340bd3d34c775dd179aceb8e6969a413429946ce42b664d0622f298fb3e0b49c9471194bb1d7797b060296684b46b12f721dac6b2ccc4ecbd8a66085366da05161b6c1861950d8d84a23823342a005822d47432a85ad355c05521f58430d5f81d4133562e06aa43c100336ce022925363068810b3048c3054c69bc604d9417acb1f90527a8b1066317e4a46c711aaecf2ecd819b972e6e4d778d73dfe04c1758db829c84b385c1065c9fed962bbc925b7057c06ca43490df6e99915258dad98575dd32e7f08aa43c210b7252b63929631b831524e5c9af66056aa8b00215ac01c31bbdf04650548086ddca001b18f0362e205d44c3db54000d2d9a05fe7b54e0c31ea1a43fb472923d232759cc0205ce48d3820969cc8852821968982620e98ffc92fe40930217249082325ef8644b76fcec6558864309ec0867a1741f2e970be1327292252327590c0304c838d314813328888104148c21c303a4fbc82fddc71862cce00031cc48698099306818210c306a6000185fd8b0802fca4c5140192f46a0c48b2ea824a08b13dc808013d49c0e20290fe5a99900872492f2982087241370a18301b8d8a20a922dc890e0089912ec60a4045af050002db2782a9245560f44b2b0f001098b2b7e18225d0cafb0c24261399a5600414410578488b212d3d583ec635ac410f6b1cb155abdb4b17f33898b5c4ee262953792b8583f3f969e8b888bf57318640338b3c84778661181e509b847daa6cdb67f84cc45f0cc9a581c1185c511565c215584155255606131a20a24b0b2646b8ff86a7051918f6eb25c4d8184540d381f7531b3f1e3e029e4141629a6a28022892c502431e6092590b84f28e18418a025c0515e0de990479ccc540d60ddae2b464b2e62df158eaeb7a1554eca3fdfa56b189cbc25090fc2e423bb05cc124a80c94776892f390967259af8c2449516aaaa26bce4249ca996e8c00b972e3929632e4cfc74e9c2252765cc0490172ef9e8a60b5513df9d01a832c02472640ae926101da101260d47c9c5ae9ffde64e2154f9e8c64b133909e72a2e1d34f185899c9431123924529efa92a80322457d44fad4072285a414698844f2d42e57fecc3dde2b8998c049782e919332ee126609305bbc7860b5258c962aca23e6d69f5aac94f8e2123de8eb111b1209a201ac5b9c4a88c945ece770cc8f13ce2472120693434cc37c3a74acc8330637ae7141b3658dcbcf96352e519b880bd95dff48123a54d5d068b42b46b54af2c831170b242379e4bec20bc923f7d863d39f4ae423bac19619ebf81cfa4a8c0b9badc196352a339b4b95edd4a963225ba2327d22d3c79aa34bf9a955c66fb5efa598c662635aca5e17f3c774900f4486985319091124f21056b224b1fc9d452227d9c7e1a8c2c63fb34c2c5336768242f1053d05fd008ee2ae37378f6f6ebec8a16c8c839e408bb5d537373fd68d83c3e69ddf7600a9ee1c7ed207f64875db10c7fe9c19c97503f637b42ce7717cce37a166ef6c596b628a7d5d283fd012201d123de7cfd13623c1be1f2fd6370bcee320995bae8b593e9f8b29d68735ed410178e3c3cdd7b7f928e79b89251f49e558943dc2da27827c005f145db48fc371ee6f1e9191e0178dc8491c11172a221fe530c4633eabed7e72f71756176995d207052570d3ef2410fad3888cc4ed22425991fcf4732829a51308293eab7d06f181fa4aec5fb1cf3199b18ee9ab6ca372127e1b32718d4bdb85e9148fafe424fc396492dffe242227616bb3ae547c56fb967428f6ddc7f2db70d6a8a030cdfab0e6f6cc45ece330874cb6d436912d59bbfe91fa236c41b3b7ffbe9f511909fd2f1c71759ac5949b9d572af519e552aa45946a7b39bd7d150a5581ae50976075ae20065886a1dab2f6456b6f59fb5266d620a0a67489d6aacaec9b2d6b5557bb56455535a5a5caf6a3a5cd05cbd98ec82389ec960db1db7fe3426b61dbfbab412fa007023501facf5bb70fc93c8c19e1b7fafb5c8cb9582b8db65ddf4ecd8b43eefbdd9eb761e15e8a73595db57b8abda7f4066dfaa6b0c7ed95e81eb9f7be53a2bbf33617c445a0312067eff6e4f442ee6efaeb026a27773f99edab9da4b0bde7f413babdedfd7571ebac68b4cde94ba3ed4ddffd4387ae91bd4c8e65e3fe93443226f37dcf876d39cebacd761b4b1fefaaae9bfede76a48f2d22bb33dc913e1ee4a27fa7f78f2b70bcdd7cfaf631ddec36b739e76c739e73dd7bd76dd37a0145b5767d92e1d844d4a25a55d48698aa597112291a9aa6a6a5a996c416d5a25a5ab82ca022c0ed81b4803a404180e38c7dcee7bc0e3438723cfdb94676adec1817ea1e470eec6b3ef26ecd431cf6f6efbdcf7d3afefe876327e771fc38db76ecd9361cbde7381d1d9d7abf3ed2fd1a5a3dd6d9cb8c64ff5bda9e92ef998ea635176948cbb8e8e1c08123680d98f3f5bb2e27279cdbd373e7a836775716def8aa618fb7afd356eb6c998ddc8761acc70aa4051c41a70ac79f8df3e07f2106bf778c3d1fe5d70b17d1ac713cd6399f8b1f0dc7d9867d125a5354ec211374100c5f5f445f300b1ba2f3301b8ebfeda8e4f53daf8eb36d4358ce17b98e7d986b79ff3dd6361f61dc853223dc778fc47df74bfb8af9f3b7bfaf7adcc11ac77ff5084966d55c04847deda7759ac0b685ed1b8e4db6cd099bc070be623ba630e2502a0e6c00c759b3db47abaaa8a4a4a29e9eaa5029540a6ddada62a3a585a64c991a16d6555515959454d4d3531597e252bc696b8b8d96169a32d686b34c6de642937b202be0c855e1aa38f7e442e0d3e7a05ce8f5f4392b2e14c549f9d08ea7cf6d71aeca85acb8312e247bfadc1587e5423a4fffdeb7d6eb3acf52ab54b74c532c2b058d8bb4aaa96bea194f5b9a65b2525ca48fa3ed14eba46d156d9fb485d2d68ab65156ca4e511e5ab35476ca46d9a91b3b65a5ac0e930b8df639269db1fb6dcb458ec907d07ef73a9e4917724cb4b9e51c937352c66c66e88666d35243e96f6c249113a5592e44b35cb45496ca5a55b9500efbf629968b54774fb35cc866bde895d534cb458a44b13ab9eda5575859b6b3d862706ab9d06d92443852aaf8539453f995a37136be459ba8942af48946512a498463775c0ca0ff5d402d0c3261a009238c23aa6a5848dd1a16524e566a5838cd1c2cb91ba08b332b5844050d415f5a3b6b5830edda021a3a0c7c7a16f5c349a3dffd5e6e8519acac8dadadf2256baed7ebf57aab9dd03b34b73b739ab5da61ae2d9c5b538d9a352019e7a91fc6983d4edafdda69b1c3a8daf527533e723dc2c0dd645ba7ae5f7fb5cb0b5fa112359cf6a68a4fd87604f3169e3102c7993545d6aeb0b287a851a5bb3e91aa242ed465b1eb2b39c1ae3fcd58b9c806f4e6a472201880f42f1d22522489fcc798f8b3a590696602a93f694276f8ba726d210ec71f3353881751858cb1ebbbf628e953a79a1f57388aff0a69369c520ebd201a45996d8cb070415580726fdc1a1c7e21d32b1c63e36fe12882e1f853db4cb5a16a63d5e6ca6ad74b27d977e9fb8552896e1cd2bba51ac923ad607369924736491ee9ffb968b9ac8dc071aa715aad6d31edfa738d0fb9118dc9df3fc7d992726a8f5bd6b0ac6c9d1080b286e5b41d8b861a16d38e6d55b165cbda14517b0cb2eb1455f608ee3973af428bc27adc6546eccfa5cf6b54646d599b226b0aaa8d5fdf77b511388a9bca5a154f43d4883e08b4d61a7e77cbedefb63d2ce643f7b77fdfd95617b9589fe621419840b9e70701c185ec66b939e75f0bfe136c848282762af5f7e2a12cc0192c1d6389a574f7395f4ae91ece2c5f414fe058eb9cd405c614b425352cab3b9d56bb71f7ebe494f73a4d9973765d54b54229a59e67a9acb516e3acefe3388efbbe8d8bfc755dd7e56ccbb83e8c3176b9ae18af2fe79c5fafda9519afd70b046b5756b5ab346ee7f2170bae685bd6a4b032b4652d0aad8d5ff2af5700ac4541668f5f83c114ef9cd86e345f7e10bb85a00dafd89f3a0853d31bd970c779fc03c179fc7d0c326100e957bda38348008e4182b87b6d02120314e6fbc25550068dac7966bbd33403f40538cea63d2ad15d5fbefb9979668c33f30c972a141403388a206c2db0cf19fe7d5bb775e307acd8b4eb2cedbe7694d6bdc56d928edaabc5dabc7da79bdea8fb4d2fe0d5c58a28cd493a7bb56cfa553bf1dd81a57da5690046f73b2da3f7a3bcda307a611add67ba51b8f04b9ba512b828befaf241d8cc797e5c4cb3ebff0405b9d2f446f7cafd2d518c19b3062881ac00679248a604bc4f7feefbfe600dc7d8f62dc4740efdfc70027c62b713dac6cc9e396c10e6b37eb1988d7d92886e0973ebb9c8cc61d7a7da89ef273c7607969ee4d8f49d706ddab4b195e6a68f42a561559b072cbdcc24cc9fef5b14dc753da514767fdbb6bad5eae0cc1d080b1cc59f2049c4fdac2ff6d46a7d73f73bf7fcd86ff6b9cce51acaea2f6da4397fec21449440e68f3baa3f28615b76bfbe33f1eeca9a5f5e6e47fa6c9bbd57ec09b29bb538a410bfe36b6ff7b7c7d4e3aaacbb6a99fdedeb6452dff7116cd372dbdfd76df58ef4d9dccbbc50d43d4175c666dfcf07619228ffec7e736baf75ab5d2e5babb4dea7e7acc6661e7e0745d49834dbfb3eff700204bd2f3ba0d2c097f9e8fa3bf7d51f77daead82ff2a3ee6dd697bb1bf7f6feacefdfe9edafcecfe9fbdee7eebdef5d7bf937ddbdebfa786edbf6485ce8bf415142ba9ff3ff1803e6f979168b6dddcfffe12eb75dfc713636abb7ded8ec9f009df4d8575e7fa5c91abdbee7c7a9f72f50cb94bcfe755f19ca12a3d7cf4c41ad02f85830205dcc21942546e0cfec7f5d1a757afcc2d07bcf3dbf9e87c1ba3b5d77d01aef7bbff7f3ffb6cafdccfe557a2d0a2b1bdcb20605d5c6fe79cc4519c39b8fdf96b1ed5560100b402547ba1eba9c471658ee602969bd2ed211047dfb21e667d69d0f7fceeb2e0491793fb7bd3f2ee49bf7d4eb3acfebbcce9b92a86e32fc7333b1ef9f93b9f187d508feedc96b7f8939d7f7957c63efbbcf7fe622fe4b7b7ad37f8c01f1df4fd7a357de5e7e9288e32a955523db738fb47d0d47285fb5b908c65daef5b1add4529713baeb7363de4e5d36fca4cffc4ffa383ed38d9956b3d2799f60da9452f167df1e637b661b561ab0dca9d1f98db5c89da87242ca2e722149eba54377da5cebf4af19c9d29ebae62217fdc56c51316b36a55fca88d932375be9f41eae710321dd02cb2ac64a90f9b9e3ce29a55dd7751ded3a988b414f200a75dbcf5ad84be8c7c5faf25f624cccd39cbbfecc56ead405ba58ab0c226b566a86dca8fe111772d0b6b1c3ecf1ab5f3f4912dce5234abd7c4429ce479466bc6d5c7e24b97328733d931cc402902eed51696357e7d1a58d75936f7be11c832949fd0ffb7da2b6bdd6c07cb1a75fdac5bb74a1944efaa4c7eec0d2ddf32f165de817b098569a26e8f2055017d8bc617bfa056bd33bdee77ebc746f5eaf745456570da7d432f9db1f3901de97db6545c227a3127d3752e48677055fdadcc9c0f8e5e3a01ec0b1eeca84993d6bd8b2b685cdde9ed2bff47195d6c68fe3ea9edea7f46fa6d8d3f9257e9c70ecc01275590abed2ddafc79c4fc9ad808293d9667faf74f78dc7292022bd2ac80c084686f3f6f38391e184b58c04c80d7f0952011846963ff63a1f46e7eb62ffc2b139e76c6dce16678cb1cd365b6bede36cbd4c11e369cb9a99293355b6179a1a8b93858333b6cab8cbd4d660cb5a97a68d7f83dd54fb22b5ede32f4fdb7e96b2edbbd850d176065bd69ab0b263574e4ca8d9221a34b52f5b1bcb28282d5adbd2aaad9da9b2367efba5ca6ae3cf531bbfc501bb954f63fc1e95876cfb3106f595181157a28a30c28b741f477491e222290f16aa2c4d4817916042d21f534b24b145521e25b4685142bac8c316aa2a2e5c7838420a4b961f9000337dca9503ebd20587892e436cce63ea60e4a4d585f3765b2d613739385ebcb876c8593e243e15745e1a61397d4ae743269da598c69ec467b502965cef3e6424dff9259e5f7e25745c3ada6aba16595db0776b5d39195655758343e501972e60c48409e3250c145658803dac26d0e36f70aa5cd92a1f59d88d0d9580b09d93f3312ddd0358cc9f90d3ab0be775b434b25ac26e7270c488717db9e9dec5e423d71739d6d13257a8048412d32ac87eba4c014b46b247802c64922ded9856c092512cacee817d9a91dcf390b9f3c7ea7477e96c9996ee8195696984a54b31abac2ed74b23aced0e02421de18804172b4c1f49a295489ffa405bee85015d01ceb0deb6cc0f98dde0389820128459920990463a0a582241152e545c3eef522527611d7212b631adf3ee057bd5e75f72093dfeffc3303ab8870ee33ae4e0841039e0f0441038388d0142d21f3fb2d30d5040f90d4e258a0f7e4c8192fe90e2ff6325488944f645fe2309b0c7cf5c421835324f20043541628045b2843051be00a1b5d63d5ee6231d5991bf0e424a22f4837fa8306af43f54086a663eaa40987f0da5ff5f66134230a343203e94edd0e37b7c91b761a4a3230b7bfcebab305162efc29291ce13a11f40219d90244aec75429912ae8d91ec9ba064239d5f3292329d708afc61d404fe1e8e75bb7b38e7f436f0fc9f17631fbb41412e607777f79d9e0f8c92b57b827e071673ecee2478232c71f1e8494a915b6badb5d6a7136d322961c0c5265068d4cc336e45e4c80ee0085e38ceb6f759793e9a735a2f66f3519d765aaf42d1683423b46a5a66b4d00819414b8d04729565b1f5e1c393d9291380df0c7b5b5a4ea0d6534c8b494b4a9bfb094d2c52f4979edda6d068b422d068010d19d0a04234021a3b481fb94751ab055a6a481eb9399e3d33cff65c25a536d3b96d8865e7b6e196e88564382bcee30e05e55330169ee246bc9f4ebe23d2cf0a8fd70eb97ebc9e8fd9a69d52f9c80b4f00facc50f4846ba7f62b1fe3ad61e546bc87e2a27b3e6545a1fa6ccc7d77737ee5629a315b5e6d5933c3873464368f2d6b66d036fe3e97669a3fb5008d3389ed3fb148b712f233ac7462dc6fe68f227948e83fa19b89fd8c94df4ece1bbf90fb201d402617b0ff5bda198e998100fec044cff3685704841446d8534f2bd1ed791b80ed26b0ddbdd5f94bb3c6a6d9b26730d93362c860db4f73c6a6d1923cd2676357d46bcf252490d7e77aeb0a7d0ae509a758a1e16e755535c6cc1ebfed55533e45737733cdd2c52d33aa064a1771b76409a766842556b5ed242c51c3850e5506e8fdfc51a281ca5ce8563e46cb6ace3d4e2d2b9f34b5340a75e70f77958e4a3292b5f6b367ea0e2561560922c58726564f0f0dcdd0dc02bb7704c31915f533f18e985f31900235e5d12268115e28a5cfe7539268066d012671d15fa96a2ef4e69c33045d7a4a398ffb7bd46ef2cd4d697b3fe73767c6a15bb9e86fe4542e84b587dcc87dbb4f8d0ee5504d5c68eec7e1940b4df7749369bd30888b6eed2cd2b6ce992409c544927c01bd1fe5d591efb116c5fc9ee7fd8b5380dedf1dd145ff3078c10f9ccd84c6ebc16658a0f75d6ce66fa3820459017aef85452e42d9f6c799883dabe9ecf909fa71d1843ddf5a1be4a2f778fa0407aa021ce7cf2817921a251a6b59b027d6533799f9d4389c9eae7b84fdcf1e61890b49179241c41fe95947326c596accd4d04c810ad22148871a1a5a2d055653413904e11054058a4a5a535881f3524bc194329acaa8613f399dc97232d85032d46c4a51b0b5291952bbfed46345e228a594ba4615b6529d61a5563018e953ca29ba65ad0c2c9bb3e252ce329c8ef02d6b655839ad428e81e5639469e26063bad96f62ac2579e49a2bc616c814932279e4185434d8755a33341a2d8b917c9b8f26077bf470b4ef36dcdcbe2f06bccfc43ecd48740d9540a1fa371bf1df68341acde650060b4b8951b5b777a92d6b669a6c186cb4dca37fe6be0ea003c1796c102d37b2db7eec8d4017b228a8b2ed1ff1a16a44b7fd98b51f34b3f63d23b9e1f6b022efffb9906ff14f6efb757ff5eb827800ef57ed142b5502c980f49164fd5bad24b25512552a89a84b22aff5c8927c77a79bc317c6188763936f672028c0b933d52f7757f8737bf5c35f6c02f1ffbeef8b4d21b319def63b0912e19a91e8c63fbb8ee7f7481f7fa035c0ed69917b7abc3edb9fd317e62edfb66cdba6e461918f1ede6aa5a5096c4d1318f6a7be54270a58eecc2fe809b41873e198c2fe0b8e31eb2485cd8d2bece984dbdcb67163fd5a819e00e757f965297db52bce34f92e8dd66ddbb6edb73265f6b66dffdb6f1fb4d5f6c664fc1932b15f5fd8c9acf4058fbbde538ee3386e72f3bfc97d94523ddf6afad16f7ebb8eb0c96d8ee3b86ddb40342ca5da7e2b18d097f6f69b06b29a77537d7bc0f3fd3fd8fc7009969503e36ad39f4d341a7403385429f79de6ae7451d226b00f89d79cbeb052466b8b6d6cbfea4274e24e02d938fab8bae4b63d92dc8ad89f219322f3392ebc2bec51896e2e8d335bd6d638eded83b6aca531b5a50bc9dfe8f66c48916c3849369e646cab4d60347db1820d5650c8c64e2551ec2deea4101d1248fd106c01942e521ffa55fa50243982520a906e7a933e4b9b7e5b248fac926324962423cbc82fce482934c217670c7153341acd8b9114b265b6954a81c1a80206141851604c491ec964fecc74d2bf014ba01580b2e6c5d31ec52dfa9549840f41ad54216c101b101cd4fda1f3c1eb013f7d3ce41d5c2478550175b891c30d0e384eb01b7050c919418e29311b74d4a043834cca6c861d32f088a147d3c3a05f085d0000d34e940c5ad060b2b0c1a4896d78daf0c1c68fad9e357cd4e0200640d8fcc0a0833402f002a035412ef0a005422c18521364051fa880080d215a209c21803403302304344529d865189141803322a0e0688c2162209921124611300af085913247bc40d285014e90544b6282037081802d124046490914a0c502b26040d6085834e00a0758f1002c12aa80001511984202574ba49840142540418131263c5101272c802f6085811032308051004c4068224403441bf88003414e1872228482071d085202f240009e74f0819f14808080835d1f87c067d7c722e881f243051fbbfe0f5e816749dcb40d360b1ab49041941d2600b810bea061f8a61e31f09061c70c3329321a746ad061436c4a8e11e450c17103cc0907879b1c6ee800567991c06577701ebeb99f640fd9872f88cab77fc0501e107606918fb60f62012cb28209f105d1bedeb007a80d38deda15185bd6b8300387a53976fd118888ef471275df105d6c15c5ba58b3ebf704a92f42ad9dc069d75aaf50fbf381da502fa4587ae5036aa3678b3d3f364a04da026908c406387f02bd001cc51e203640a02d10280d50ea88202a178b67a9486c53d7fb6c46a2405be07c117ce886d579b65742895a6dcb176c59db62cdc69e91eaa661934fa422901ae0267d828c00fdcca7e59b5abebb059979b5658d8c947de9508fbbf291e8a2ddf26d81f948144ba02575d8b2a605995d14debac45767be5214a108680d90fb1da02cc051dc3bd37ead61b5e18e0b855a8cd9b2a6c5963db5d8b2966566772085dc90407a7e2491c51bef0f943e1f13f9888614480d900958133954312e3a5d66db66a9171e55559f8f6c28f6c400b4f38bf82504b353c36860258af1e144cf131c8cf9812200510449217415640a222a40a86200584556185d21021643b2886451002d8e94c00064926c8180cb8512132ca036c2091cd00509d38b08dc324bbe28010c13c2b080190c88318ed104051b387302192894a1948227685230230469a09cb182160d8d1654c0b48217d434b14086164871410d6ba6bc804a1a4e30c8814d9518eca0c6d31a3e6c41b111441b56661b2268512c18d18254942c4c532e28f1c216189868a28aa18b0c5533809162458313358cb1218a295723a0820ad60d573865e1a0450e6474e0a24a8d045dec508607309eccf430860f677e28030a0d106982d012420556d40cd10222d65c49238a4d116a18b175c46c438a86a5852c4c48bc30d594840c4a48d152c396294b5061c2a9891ca8aa70d9a1cb93171faaa0be0401c64a1822aca2c418e184d41359c64c41a144145ba460e28a6a8a2e5454550106cbca0a27ae1883451459575950a1055609ae2093b585165c90e9e1221fd1508c02e93bad76e36ee7e12fbb5ee08d1b1c188e9cd90e1e3d5e8700d8c940830d441e1f3f7a7c3800f2d3410080823c101a0af201911010043080108ab6110144381a8244a448018c1c416280a42407404002942860010c18a1010e78000910888004964ca0040a9850010b5c000319189934d1c00638708213143aa0e481271f480104211001141556589ab4c9c26c6146994cd385f9c2846136cd18a60c73862965d2306b9836cc29730493cabc613a4d1c660e538759659260ee3079984fb387e9c3fc61424d206610538869650e3189985766d42c621a21e71153cae5c40719fb0b03f2024a3046a9ad3e04969f9535b140b3e79c73ca39017caf5b05a4eca854ecd8e992562a9a110000001a5315000020140c088542a1509806622ee61e14800d86963e6644950844511aa3389261209a310600838c013023403052c200e2bc81b72899f9e7cd6fd94238a6202ef7316b79e56720c2df59f15d4193a3422d7f5c7fd6e72626066d5eae68c65d70846f165ad570db2644f984d2952ba1f4e0e586ca8c371cdb51c4f6f77d77b6616085a60f624cdc9e0dc6c06f929dc35e5b3213203a3748268a061ebb5924a00487d941f763060fc7d3ba613e0a555fbdfda1f2bd8633d15304cf0398122568d56bd3afce8293915f1dd891b9ec8eb639b13be4a9e945db66fa17a9b3bf4a9e6e04f2513a4d8b368716b6dc3fe600652f29387dbfab43bdd8c698d5a0cb29b303139af69d500d30ed69d5a0f3cc21a78306b43c8ee9eb42301d35d3f111b422b84340c03e52ce0800c03c5d1aadd1103ca840326ad89d14edae928aeddf06655fd8054580bf7fab038a354b85f296a9918481b5f28945d9dffa1c53f85bee953d5863a4601803ee49643661d45e041ff98531af7f5613b878f8d5d52e46a3e2865da20efa1102ca37fa4a4e02cec7d743f9475a8dcaf0e14e6fc3f4db09727d561b4b742c5a77bbacda1dc07866b5a3a32988de12b71c0b9b48dea7830b802e65f00dfc029ad1f82f5f7feda24371e01287d1db568c0255e39d00983baff1e7269ddd2618c5bb79c63a748679a82debd2c32c79b9ac3f2f755277b8fc2ef4a11311a5c8c0e2a0560a138217524d607c503ee1a4d9efd70ebc87c96655eb7040837e8ab04919e28a6c623b96b0b54313a53227d26357a8ceeaf5450a9699dc13a7d5bc691205c0716e5b6d42ba580d86ab6232670c5c8d1a06b48a0d346af5be24a4a5440b3e93278e1f1e152bdd4b198efd6f8cf45f53ad1aa69852b31c8d4881c38146c0b028b21603bf50a8f0cab564026c09f369ab3b91f7c962e517675f7c23f9f3c44b7c1574b2e6799a58d462330eab8c25dc34d6a9b2698575f9c379eccea95d9b3ee5c14cc0d3cdc078604a30c0aa075d0437c5c5d3c50504ef991ea190c5ee833435e538c176c606662cd193aacf527ee6cf4fe6a2852ff3d025d218a75801f149a5484cc8d703f25ccad9a19947fc4b56dc33cc3a60a2d88f42a0375cb49e7f4a18c5f6ddcde3c3b479fb9832bbde149554f6f0d7f1ebe1f3a32f3d722c90bfbfc9f25d95ee9fae61af2f68cf847731a078558e5f9858d84fc4628356dab389a8d38cb6d26c8fcf6311a43a8de227c46dba0d34b1daec67cb564618ecf124c93eff025b4955a2d3f738915c805796a65e3a6e0a7674ea6a89bcadd5a89b3be58fcd3d69de8f59370814fb7ea02cf7f1b00694e9b31fd00fa807b07d10fa4e9f0447df7e93033f2e0c3c36365993e1da49fba9173ab4eec947c54e6f0f2c184d855e9725ebf48be60afa19053011a43a0353fabd99c4b43676c5610a55ea1bfa35ba5325a750f315f2f13d06b113cc67a18a0d547a5e85b02a76b01b1da7c35eb0871af840d7b91f2c60b1ad80e5351a6a526f49115c3726f0ede861559fc900d65b5c675bd0e548220760d68d41e127c26a11e1aebe2c9628fb2735676dcd6e423d1303d46a2bcee761964ca712c3ef1b58f8b12b74fe0bbec74da5bfeef9416f90c34d028ddbef4c31a6a5a39e36fc311c9eebc68dc756398c1eac625070c1acfa8dfbd737ca4d600064b03ade029a51040f6d7efb1ad94241d662dca5776f80f9518c19b154c8b064b1b87fba8981f0bb3ba40fae8dd4c0c74c2c4c2baccd0d9c97446dc773b4d53cc9a60d72383a78acc78d4e598702bccc80dbe41e740e60ade3c209b57cfcee2a097d661a57f9788353118e2e6944f81a68a750c34635025b81047c3433d011b8ff9a7c262bc1f383761486ba3ad7cee4ffbac6ce04e405e454e9695045dcf28706c5fbfca4e6948cf41cb353b9d15b983130a1099f708e693f8e1add347df153023559984cee54ec537866262c8088731f39283370ef6c9cc245d2e4962e3f09646518c53bc3b61188f5c044e45e91260fcf9b7bcf6a06df0c35902601bbbcba0a0da24986afbd612de7f7720a8f1cd5145cc91358ddb0bef95df19f6dbeb02135836a1f405dcf40b85aa04e6ed39e907429dec5e1cdea3472e0b7ce4938b47012a8d0755857b8e80ad7632944e3f322ab2a7fb2d56160a9f3e1358f8584c399bdd8b103afc04ef958704f4eb73bc1ff53b89a2782dcf13efebe0ca17bf3957df2466148761880605472c82f24f3dc662575c9cd8dca3e65f68a713321d67177de77e55a965644712ee600d17a760e724c5da0da5d41a5a799449b9370c1281ff496e14dde1f5069be1799405be2554b72d4bbb836a9e5b06d31288b464ebc5a6c76569269ff06e52a409b6dca59a37fc7a102e8d9c359d447614a880409e8c5fbc5bc7c3c46536103e650ea0e0856a5aac4a5e1147c4fa46e9d7eec862e76ba00664cd79aa1944130162196065f914d019bcd1b55a00d5cc12efc0b9f1fbcbf48790ecd4c5ac4ebe89ad469c4bfa4479794b8114f1cd04db45ac61aece26bd43c51e1156b4c3c499faecec5349a97c9304edb9dfb44140dce5b07cbdfa8abe5fa7869ff93e38e09b24467a9970d43c77e62aa7d2020c6e613183d3ef7a630ef56446851267735e272af9fee95ec17c39b3e589b41ae20461847f342c8d22c4b3c28d6d1d723fc7d3c8d9ea04365266ca2f6dfaeeba9662e91c82d820bc157e222f70abe265dd3ffbb236990c8fe485e66860d81286a402ab310950e700f60b1f4ac262a068b292b3e3cd558bdf128a0643590b7aee983c538408edc7dccb1a8ca5791f9ba5212e63b6a3bf20e51151184497ada94a07f3c1c2b4d0aaa2422b4217cc9e1cf4eaa66a8bce14cd267bd6e60d13fc343f221852206855b9f71d7428936b37c0411d29eb12fe61da96cc93b5c4bfee701c875e6e79f4629f42ed817c38abfdeb87d6be6d82af3a342e3ed8b8b341776b23c5edc42fc1e9db4de12ce3d93c9159b9f6b6465e2de74a3d496662d0290d8d11efbc0a94a7da4b84d63838671389ae4aee356740782152d9565383ea3a22288649ef2b7045c9c5db760e1b05e9e112b6e4b50e0e9fdfa2cb9e79d7204a42778af7b0fbc061e16aa4ff9ec28dd39a248feb2d4dea6e84cb2b5c6d4ce19a453c1dc51d0f40c3065f7913f7323b0e79122243e8f6e481cc5058fbcaad7960870327cf722ff0947a260c8e5f71c7f72670f7883d64ec1a2fc45c88a2199f84e7c5f49be80d1c1392259b7580268f38fd5c41b06d0202454ba5e79d5f6a98bb412b6639ff57020da4b30d7a13a7b6d0d86685a55a629e10c940a8d2f58ba06403abafdb4e916c697dec40ad9b6c2c336a1676e88c0f00c65e445ba53614c3064658fe9c261781e36afccd7884808c97604bf4d485be8198d19e4ba3134092864bcaeb80f29cea2973c17e3d7873cdbfe54dd48ad7d311002e1c9365e0cd7bf4ed9d94620f6528c4c2cf3ffdc6dc82efc1a9a1cedcdfc230ca473f5fd7e83ff62834d36791115cba1e96a503af9d223eeca1c8ecc9f830348963098ab221fadf84c87c2a765a45570d4eb50d7f830a65ba0157e842a23a8f9abd0c9ff73348735d3ec253cac949a5eb40bb5ff23568191d0b6c02e2c8925eb976758de3e6fa4d73c2b409207bdcd096c1f76a6e06b30217eb22772b8ad39bcc819f97f91124240384ed84733141a4b54d5b96759bc4e90b3312c9b7771e8f535c8986d931a0a9b365b101920956af64c19f449ebcd678bcc7efc5c73a92197f5fa5629227d883c4dced4b2fbeb1ae49de71f6d6ff052c815d537f8b087b7c6b0cdd914b88cc104a10355ac69f383d3e3d0456c1cb22d3772a750b3c1626011eb3e36191baf8de2c459599cefecf5b8602917f15c8eb3596847b2f1f21b58b882995023a5e7cac2767dce1a8f9f16a5e8d95b8445b4e949ba84932f0b90cd15320fe3d237dfde415e6ab17d9f3a3afce9cca17b5ae3a2e706c0faecee3750f125cc104d5e95a16e6e481da1c7991cb9127801e43c3e0ee0280ed0e1f276d93da76783df2d360f54962d0ca421812e4269b2fe3b43f86debc6bbda8179326201011e62e6fc5fcf48ff268e83ec4cb3b1f44a6e0e4080bb7c3f1bea8720e7620f45f87cf35dd3e05e80f357f87f70db8b095b917b38df685a4bcf59a4686a3847828a571d019550116edcb2812f7e9a04f0d6267380542503804048a6ffd2b3b8f38c05db4ae9f462cc0da1a963ba847b0df8a0ec775f7817b3a7a24b86c7e57a0a4a10f19d9509415089557846623d1ddf938e1d72242743114aeb0e4c23afe0d7e56638747dea688a4431ae834284bda82f6cd161c620f6601ddff296d6c65c4a754e09f5ca02692d57705c944924b46aef351ee4bc2ca11bfae85e06c1dc4c59de534875e42a14c499a5a0a55f213adf2d4da62c1ecd55e0dafe9756133e86b3a038b7ecd0db0f32de7e3af94eeaa0d57653adf62e131b085c757585a7e0ba0be4a25a8a23df3de50d8dad786cef7142b2bdfb24d4b1fc205f8a450ed9e858d3f8240ae1972f3e906080f852a926bf25315031950d0f1f66720499f819ff31da02143f676a5318a04470038a9f3288bbadff3e00e028cbc9d1077b201bbe547be96ff810736205ce889171f2749ad182003d0ec8c8ee2a82b395a41b3e8c90b48a937605a0d90a3b8da2b575fc5496e2a24e04a4c2c8465d34c99ee11cd1c7d09b3b97dc65837547222c25eb5f8a9b87095da22870a2b1475c9306f7134a6a23e3893a42f69249cbdd3bbf97a0cd4bda7b64a8366971b6c215494d6fb841a4116a5b0f9c7c68cea28f1c973ff276566544fef557c389b13846d89d572094f8786e6d19858c4538697eed2dd0be18d2a14d581137ac04a21fef59a7697c6b37abdfd733a1c7f5c9aaa69d9e1e69b6b494ed95eb4f1a577683e94b9bb1631cb101284c2c4c9bc394824e1c3354a8215b9f512147e5bfdb71c723a7bdc60361c0aa41c676d00a2b7db66e93eaedc344839167dcbae76bb076d3d1beb383d8b5406233dcf0439af87f7e86bd73d42bd63bd86d47c2c4d8c7eb223f86c400b902ec0d55e3bb744eb2fbf8da782a49dced8137292f34623b034ed6c9da3588b1ec938cdd0b894407e1f811d5ad5d61b84ce5f9bdb8007cfb3520d857f9765f62d8ddda5f0973a9ac2cd0839190a434e5a62c7f67ac52560c47e2a2edbe56f6fa0660d8652691841966f69d88856ac048b93d1538e7ec7012eaf9d3af9cb716a1c13c9e20caf1c152ca5465a1be6df36b7b05d738c009f4dd60d720526d772375b058457cee3825413b021663aeb17fcc26b7759bd0f5e1f1022d7623bc47ef50c86ea07c5453cc44fb9452deb8c11ee8c535b52901513b031101c28efa7dd0fe62b3d53bb53f5a6a8a5ed680413c2e722bea9e935c6919fdbda6d5ed4bb8f9b891f8f045b60e77ad31dce4fd096011ec46a95f1ac1b7ffcf39184ddd4eb7bd82e49af45c054f568bc5f22626c512e397ddc93e023e7379d357ceb73a6447e5bea952f206553409643bc7bf357ff60860de76e6716306127e580df9e25ce2524115b0681bb4344bbeb76f49f7591f842b1ed698e26b480a78f6f0c5eee593ff2c5a8114018755abcfc5bbd4f11b3bbc5590882f8cb82c1e00f614db9e6b7773ffe1cb84d0141a6fcb85cd7101dddf7c211de38c05756ebd0b378884e28de1ee3101cf398010e5242a1f2d58fc81bdb937e76c28689e0c743ed976bf23de71ecdd6f501adf74ba9f0e4f00849b98371b3e330e49506bc13a37c5520a5bd2c3b78c3c9ff1ece4dbb7c87c99747627de3941dd0703a1c4c19c42503ecf6edabe189d8f2ba864fa9f052585fbd82fb9d863217421de006d2200b4377880232a199ba26e7c39627cb2fd2d1e16c81f96a5b044878a8319ec215b2182df011612e3bd1e3283997fd82725181bad0e48d7867d3ebf3312aaffc0fc9b8d48f61afbb590b197aec69df6c0968b90ccd11e45a560ec4aec522bd5440cd43d3542b37aac71db94355e8cea6583edeb465684b99178d30e2de6de19a45224584c49cd531e2d81d3bb95fa97569d2a56c39e38c9e89e46ce130e6de1867ffb2e5803f9e8805734a705a699666bcc0ade326b6236cbbb056289950494bdd34f0d2f6ec26f88ad67fcfe028954557a8a939c42484bfde452b644e63fd2dd404e6e172088810431525f89f7026e8f6bea92a27af34032955d78060083fd40e44bdd507c011c4e68eecf9a13ff40031b102d60a7abee8bba18a57076e3a3c9b070b03a6ca59684ef810ade6638bde1bb863bedc0a1da6a8278429f41e138a6766ae122f2ff014864d3d6ca0e17293d5baf400209a633227e9e824737576cace05089c6daba68a0600d23d4d72150bcedd66a158e2265a85445830b5532a67e9f000436edf6ec90a8d2a3554a1426c38ffc750418dcdcb5db40c1241bab2a1181c2b5cc243f4740e146aba55d3856f2a44a050928486596fa3f0a0ed9b058b242e1a54eab6b910102148cc87f67d0d0ed55ab050444d2bcae8e142a58c948f07100176f5bdb5a8522250e2aead060c1744689df83c0c0369b9d351c5ae2b0b212092344638cbedfe67840e0551151c5ee111b76faca9262327e697e398f59fe54fe1c3e196f39bf24df2cef2cff0c9f14bf9ca7bcf0c709e9d4a03d30f960487ac69389d2e20bb9cb21c9f288f2346fc273096c34f946438d861c0d3f183e26cc20b47168e390034347c38f84180a371c6e18e260f8d8f0815046a18d430d861c0d7f53031fbb670c01afa0760822d2aae28824b125904b23b04874faa18979ddf2aa5a31b7b392c7c9f1d406517e9ed0ca538ed43bd82b53a4e23010c6a8ed15ac7b5abdd874b0f7fa61cf9a1d267dc9025c633c5bc5855a93cb13c5bfbed84e9eb51c0ebb85fcb41ba980c40457629d764d09904b9800ddd7060ec6456c11384b3c06f4d4da0a22b942d551fabc8ebb6e6d0e7accd4168b6449114bfcab358eecdb0c0ab0a07af0e4c840a755152d8af1cc9fa9fafbe5040d191a1d04ee13664c132867aa8f079898dcfdc1db1e0f60d73aa542b75e860d72dc2df1020cd8652a6ec310cb6f143ee63b848df5ab40b254ffad4f3f2a33bfe7d88a3251630d93be51cb333c6ddf6edcc6a862c3e450da8ac972a306e23b74e8275117fad9d89b00420337c66ad01104f15bbb5824a4c4c608089730b4b0c9228075365139fcd0b9bedb38704fe1c7c28c4e80c7965d3751e6746038fc9409cbf32ee2f0d3fc911bc6da33ed04c7155800a800929c3763ea3f2deed7fc97fdd3f61686b14126a995f074949e622156fca4c88333ae414d1fc8e6b0ef9b1cafa978458d0174dadb79805743ad61ae0c068c5d1e7ed40f1767232ed7067f004ea14575b20ca0f04898a73b789e1301394b4b8b91989f38d36f6bf33725890bae0ee3994de5f87c60b6b68fc5df2999055468af7e00003c1a99682e2bf05b6ebb6815f67f27ad51976159dadeb8de690cf2635a9f8ea67d5ce848369a1941e00e2f815c8bc6199effc3c70b000b79917fb1a6107ee7e2489cf11d8446fa1ce223eb29698b484d47468e3f4a828ef49aa9277dbde84b6f0fe436f6d95bffaf40d592a58887b1c746a660df8a694d0ac050a9d01e1b38cc73e80b7ddf7aceac7c0139de9883ffbd9ed2ed57bcd4b91e6f24b0aaf15a6dc124b271a91371c862575ab3fe10f4b963211fbe877e7f6f09ee3d72fc000ee43370d138c5291ed3cbe4c73a4c3acb9c75145916cc3fa9ae775443c177584949c0c7940090525dda2343e937ddda34467563d703d0e30d8ee3a0b80e8af320380c80d360dc0dc671a0b8078a7b001c0cc06d70dc06e274509c07c539001c06e16e304e03e33a50dc03e2a807556c9ee940dead9fbb2b051206fc950220a85b2067c91b5b9d3e5fd100384de83a9aab7509608f2a5b54479e5d0aa28d47495720adc03482d00844151c5da0b402290aa6100c45306ac1a805a4149032055cf4c2921dab2f2af9fb202f833649ceaa9749ff7cc89351331927b5c5e4bf3df264a899d079cd12a97f8fb655fd42c9ff4ff9996849e4a8ba90f4e7b3fcac9a9338525924f9eb915f56ed449dab2c90fcf4c88b5d6b52c7b58b257e3ce0c5d42ed969d565a9bf0f7860684aeeacbea8ecef87bc0c342438575f26fdf7515e468d091cd42d93fff6cc2ba306d20a26e0a4b298fcb7679e0c35933aaf5920f5ef313fa686099deb2e4bfcf2c41b5b534287b5cb657f1fe1c3a42dd1a1ea52b9ff0f79b36892e4a87291fcdfa7bc4cb51371525948faef395f46cd491dd72c90f8f5cc1f5b63a2ce5597b5b487f05f3957a2e2bc3a19115fb4094434904e5513d1fcc07e9720f58bce8c56f56f9a127a3291a103a03fa19da6a481d1b667639227cb94274dcc3f9200ff85a5f316e5e2547fc8d7a281cadb2300401732b8b42a4f28d77d30731258b5b647e1639700835fd4683b59d99a50a28e5a8506e2133753073b8654689ed0dddd208f95f159f51caf8abda5cbad49180528bb7ff87bbe4df882a563ce084310b3b3e8b85d559ae817785064dfb9bee6ccc6f8b3965aac4f4fc5ffacc6b04bf82d5949d24ddc836a211d4a8bc5d6aefb50f9e3c058a910a429a5a5ebee014e60014fd62ca0e52b2657c051464d83270715eff06f62ed35be36f0d5b534eea3217368f4729b88ab505f70d821e26754b37f5e46241b30bceed67a401bacd48bbb2eab814d5601040e0123b3b23009e84f17a6931a59688cc6b20992d08210e88561646c34968f540c471894321444c60e53ff66f4caee184ed262684ae6ecb0bb45065b056c77c16eba925a13b11b582562521fbf94873d619eeab70531e24714acbe94356bb91915c0fac77c542a93b488724726e8d6fd9e1a49216a7631e54a89d4da83b200cc283bd4d5731180441606e3d7cc53ed285a6580eb22dc7c814bb801b0fd45c3a95f1d881aeb23c85cbb818bdc1267304b300fa1931a04c97265ced83100e11f14e58db4695f7c1c8f9154906181106d9835d501370c59e9948660ad847152050f176cf790761b770943a707586b658461134187b090bc5d141d0b490e01861f715c3c5723190abfe31685d8a2f60e098b82359419927ef08cfa9f1257c6a0c43e8a1e375b7a460c2084c5c8c69dc9315dc12a80a46e5eafe083b67a826015c0ad9d26a66fbdbc2035ae9cfb0c37387c1bf329c9827c7fe557029b6add91d76d70298e123ac84fcb22ea6ba6504c237bb872d875024238bcaffdc7da628e79d15d5b93620315093de0b9da45ab349c77125e0025d3e14192ffdddbd78c992ea16c449f177c70db36dc6ba90540e44ad7eaec08310b4eed30a3df91ac1d72625c5f80f1e1c68b700c63bc1472d7fac01e7b1e1e1d5cab15ea14c89bb6cd3f14a7e2074df41270dad480aecb3004e0041681fd598297d441085ee3104b634c22c2b123744afdcc0a9ad4e782f5e7edf042f138c6300dbcac674bcb1c1aea0445cdeaf7af129f5d9a11807c3999068be878336933957d889cd239c8a5d84869ac317676cb639f552d1ce6872a78a7c307e1282e4992e07d906961041e389fb11d767dc59235451f269a33781a175ca40d697112c4019f772636dbc157e396be82e5d36fd8ce34036fc3d0e34f1824c5206f6c0f7ad4623cff513d1ae8b997598678ee300ce48f30125de34e5ec7ffe71ad0a71b18c0b9a297fe0db5c3cd66c66b940823ca88e66194138a1c93d979f5c5497187c71a826d3789886a1e6723ba6f82a1c11cef5893ca3373868fe4625ca454c482d179f2d961b4724a0d372e84e8e47f24c2c08c32569dc1d69dc6e9f000d4939d93d25b814ed3b709af4f6e2132bbf7ee55157c27c9fe51f9bc8efea51a8bb93aec27ab903a9c277db20b8dde60a96d149e539fade01961f450c9521889251468649401d99e3538308dcd721a4092ff426d1dc4e52de7a05a902bb29c8e6cb4c6b400021a4be749c5117954894d4bc38d041c2e025eb89df769703c125d2fb449d3b9f825e20e0aa4cf309d77cbdef8d99d7d19fc8be3c44b942beab9e2dacc55fe5dcaa3cbe4402a6a29edeb54433a59c542172be559018c2b2cb972441f3078cf0f478c4b3ea98573cc54b9d39c7a69c7eb702ecd5ba52deaa59da39c4e6db914b92693c743facf9cab8481815aac13f7d9bd8cd655aaccf55654a1fa188a5167a1dd5c7da4214970dd09aeb67dbd7e6de7b9cc72a491c6d0e443f655c03fb3c9d27585162f326ca2bea75cba0676aaa1f7ec5661c3f898862cba4d0d6390992b98d475930ad4219128f516753fdec5e9f9a3261f88c3d61bf3ad11795fa5fd8d13bbed798f3ae5c2ab572aade07c861c7199fe5de3e246d6bcd7685c0c16cbee624bf8358efe934a0443d68be4c9be174e730b76c0261e92439a23dd8562f1e627c3a72067ace8fcc744fa54ffcf29a98ac765225a52e5c64f165bd3171e2256103ea07815e661cafc66621aafb037eb88be171d14db7b3fbf322f2ee8ccfc69e40cbb637fa6716fa5601922da82231017411fd955f291ff5b60f9e6aca056464fbc8ec546f582eca333af1de4f8be44004f5f49e37d8629824a304d5736822ee25d045c4a955c42cc154e267ae73830f73fb4400ca8662a96ccac90561a3651a6c19723c0b279ec9a6b10c600ffcf6f08802846d2358ec19624f369fe6c05a4f5c5fc70f1737911e444edfa7d1b5c79630f852ee8593381c1572ce2a01bfcca1b7d0d2760d39e25463f917a216217f95b7480f8c35d1ea78fcf2399c6e8cc74486bd29a4ec7aab838a5ddd2da8336f85dcdca54ef3e71ad737f8dfb02eb7cd92a0bd07e861bf766d8a1f898cfba50b5f9da3215224b78b2073b94e35e81557b6a420bec86ac754f18d25a279c6753a20e9cd8619cec2ed7c5e40f3fd0d91deb6d5b695c30839cef5afe5694ee893bd8c98ee16837e97ff8619d76678fae59038a343171f6e48881a14ded0777b8f31d467ddf88c7396e3c28b5a0c0b1130bdd357d4f57543cd76bce087367ddb90aac059bb9f7ad5b7b7864e05dcc0912e5e001fbb32cdae097e6f7dcb8f8ee8abc40d111d336e43d78600ceb1654c6ee7a2cf58a117111ee599ca301f8e51d390694c6852b1258436e3b04ae4dc61b19948414e7769919d74d76466c0c5f085272b4aa891b5615a2158fe04e2c0bcf9947c9d22d1e7c08a194ed6516285f5b22743f1b3219755b0ef53d2de56c62207b9865319c97aa71205eb1a538f1dcc31bf7d1acd549d4316199187d44f553d8f4ca4b7b37148ab57383e182e2fb1df4660fc5acf0218b81df436baee404be7a864e0456bec5e71e16de4a6da1e46a3db9692ae2cf9b3eef3be15c99c5d270273c2822b3fa32a769a55b1bcfe708df6e2bbf6b0da0711953c2b8f0c994d21a2b6a0141ecbdb3461eed3f8ec0d40fc4cd5f41728ed510676822062f80bd7b6b3303fc0b6abd4c540ebe99cbf3cae1c2406285d4d2d8e196fe5e32471e96ad92874b4617179ffb70175fc3faab89ba677b890e7b54eecd7b940de69829815257d0d18828705ecee8d1e1ada10e3c4ca96662d1987e879c69c5fa8ea3006da4a3acc9ad13b02cf6c9d79cb094ebcfd47826f4afcdbc443e6cba6e952acd52dcb85b5600fed6f06139ad32680b4552d272c4125d6f87e8d6a10aa2aeaaf64b83f21fbd4bf11b7135ae9e7160db71e7c092d171641ddd2210aeb44428167e1b1f474942481d646991391424788d606f8a12e0544bb11edf5e53413b556bda8acf173b43bf0a80d59a65678c5435a356746fe56990bdab94a57142e3d472623cfc1d71cbf21da931ac49dc89c53c667928155a945770d529bf1335a7869bc80588461ff00e7a4b7be008851b841f29c2050a0aed7bf5d9c8fafcc42baa72df290ad1460150a57c55699ea612977c7200c375657df1acdef3a79437858f541ac3d2dc8702ede5f19fab9913ab0983f77e0f4c5c0a7842fe316c6094f303cc84707f018ddb5fab080a201762fe80d824b7be5e314a8c0d071e20ea23f470162765fb29875637c24725d919eb3c9748025432e9d100f2ff89c44757c2511ec3fa40c4f2fd3f78bb6640696eddff515e7e79e9d2d2877505dc676e6d8f20375f7c126739b5d634082f53d68a29b1929f526bf701604dca66981f86a23af3e80e264f2750cb38731807453791178c54456fca431418662feddc54784cc29a18e5942485f609b4250c7a439553b91b4ac79397712b8c711e8dce38a6243495c741de7f4ee93b3022dd89e03c0ea25463854c1c6c11c6be59a07833e5b21d671838420c4a23d66dec9149024d0425e86718e431fa799261669ae56685a03c2b8c21199162637f1effbd81bc538df7cb13e204bd2470b042f2371b542231ff1db1437efbb1a7fa53dcb25a1213c96ce28db42568cca10984c75a1a8a2c27176572da05cf340fff011c729c307ce33bfdbde6d7b315393024c2282bc5ddfc46814a12d41760ec5f96df39c397d54adac182132eb666aa8766ae9f5f680128105f99410ec7f50859c95f61c5269a63cde2bdd02361958a9f1ba3bbdbe5197113579560252aff0a57119a638af448cdc2ea2fb021e9dd586c6b519b73d974044fc3d1619f30f3e28219e3efa78f54990ab470b95bb035c8e01a31421766157e5544f5c5d615890fa801adda41379d19b1c5a3cfcbe92128644abd19ba41779d93590e6492c8e906e7454805da0cd2679ebeaff1f941a278e3e34cd2cb76918dd238faf48b943d4eec898381394a41bc3328518124d8b3a954089d52c9088ae045065fd54058d9bb60516b11a76bc3c24389a0901f80747210278c631e381384edd8308b1c7f866b30852a49bcb74411cf8fb2c1901729206b55b077c3ea573a6ff8d26e6c808942ccb88c0222670bf09b3df601cd76e344a20d53feb9f016cd34d9394412dabbd1bd7fecc750dc6aef2a40230633318f76019b0e4c89b19a17d3c63b6c73b3ef5532f67942bb4a7f4a16c16a0d60c412b311501d0d51f3a5a0aa8d692539b87eceaded56ac132e2acf2d9738ec4944a45a44c40a1eabf38f1149be81277190664186be65eb12f61b027c3d3a0c842819830d212ab7635d58c976c14784e414aae792c9d283302a792809b2c02e5db13afd385c2e6625d9f79c07d58f6093bb4653d3d0c172a51c94a49c0756a9b7f8533499bbf3384a925b153d06169c6e02367f8d4ae0facbc659ffd89c3121efbee219445f61dd6eb9a057e199a973627288034013206dafa58b194eaf76090d801219e77cd01df6a1504d5f57ea58d351fdc20be8a9ad5ed4f2ec78320c47a754ee8b0ec4617a3935ac5139d188a575c3fc01f52334350e14d65891dfdd2615658da107bb3b5ef1bd177828c96c3d9df2cafd10487eca304507ef4ef022b157d4e2830eaab088f6e5151082f7f43b0dd0a983acd8d50862058db0c3fcc3fd5863bd0c7578144eb4e42431c2c4d6f435ce6f795adf34e919c367bae02b5241a32e451c8db62e7a1bf275780b85e7e0b8996a0127d920398a6ba60531d7ce9cab62e3d12c634f9cfb015cf027364827718d40891abec56e83e4ab53bcdd1da577583d8b2ead4380bba0ac41e8b817b310254a56957e14255320257693c97fa87266b1aaca70d561cb397bfda00dee61f0488c7e01295375aec4fa7483532aef4c6d1750f8b9e2f56d1816fb3aa83ec428485c02f2170249b52d0c24bd5854c8e3a46a92ba5410b709952e55c3673f58c7d166d5bc0bd547b7a17347ae9cae38e121b5c4f182a955e286be5ffec09f1032a063c7d48784518df844fbf46cda52aa51b1591514f4ebc0e1260219c372d5cde8c922ef99c5e5f5517c62d73d0591626287b34cd1ccaa6d35159c0ffa71b16e8eb13bc702168e33ba90185c946dde7a7a08c46f79d731d7a6a0ed0c1201094fba0f53faa6155be8053aa1b1a7dd85cf350332a20084b86c4482af597e17e3b3920fa2cce942185c9721636dec466f6f93660b7464c04f861d9aeea848617792ccaa7c5d520381bb1d360d38b2794b1ec9d9aaa44094ca90593e9ef3d7f15a0601477cb852a8294bcd4545727e98fa5d138ecf05f86c6f8723e886985c09fa9d6491975fa00577529f7b638f6d086ad051e3d952f215771cb4abab01758fa1711ee5313270165c8bcfdeb63c8317068d9268b0f7f6f22108a16bf38f02697b873309489b038c6c40280bd28bbaca0486a5adfc90dd0017ae736ab3bb0bdd306b8003c5d413fa2809168bc451b6b61c310af53f64b4d784bb43c532ee440d5409dd25c0303b4402ed7b67b94231a0a1d86afbf5398a48a2c024ce33238e93e27673f3526e87da6bcf9a16e991ad0d13c81611f4d5650d77366a17de0462de76d02b82db9357e23171c269c65dc92b215864b5b4e91ae6dc23e0bc3643a90103b06dc0c450083bf1767b2875fa0c7c3e264b91e3a5c0bd58727282493c2f87f4af126172e39992b8c331ed13e5048e8fb5eaa3efb74032fdd44e007273274d3662ab306bf8bebdff987815ab0156a6b8ffa0da1c7b79b86ab5192fd30972b1c2032eb2db38e0809c44c76538fe910e1cd1a4e785ac2f5150a0752d584b2bc658c8a01b524d339a4bb970bb5b6ed43e82e986a1fc048f9e2a491cd9bf2c78b08ef486aa02e3917217c8b671c7b45f8c8ba700299ed127c3d0fd3f12e8bffb7c03647876fa96552241c9eed3782df6315a43252a4508f12aa200cc080c7e3bb8ee8b8810b8def132f395fecee287250f6e7bef415ff10119afcbfa5ecd1be4add1ab234fa30b8fe5350c13d8c17908e6728bae1ba4fc1e1c072b8c94f42faf58efbbee59de4348271fac73e1dfe7d33ee46b7558f5c4d20bdfbcee3e82cb9f1618256d501a2e0e9a81b8d8f0d23c04dd23fb6990c884b9e026590f985b7b1d31d6cad366394c811a88fc52544147dafcf8a57bc068a26949fc0c26256b9fbc7c3f503fb9630a2dad9f2802495eb3b898cdc6aaf95c1c70bf3630edd9352a5faafdd8b59c78aa4de6a33af874ed960854ddad1495940564679810673f13cae7f9cf014664823e5d40ffd8fd6cf0f053f6d4fdb8a938c9b6784c72659ae660422036e822910a608c50087de16aa0243f3dc44511681a42bb82d9d608ec7b59f56da555af749f0f1a524d28e4610ecc15817b9f4da8370a5f98e3ae3911b0fb12bb3fb1ceb70323214537a74f0516aa8726468636e5302645dbec7b1fbec1f0006efc71af65f4c54d84bcf7b33f71ce6e233ee13c743f169279595000270ca94757f4f6a3f2f23f636b40bd317fecec2243fbad6db8ffb3dbf1a50eaba69872cfe5c2e5eeb6c29d2637faaf37aed8639fd19f8bdc51f9b1341b98ea34baeab3ea9689dbb02572dcfefea6efe9eba3ef0eee9d9c569472deca19cd46b1040753a4967e43b4e22243ace19a2c03e5d295f28df8435253d1f85abfd4dee5736a31ab10e155d39544596d82845fdf3aff5fd01e9a4ab2d3409ee730406192df3f389f53caed958614f1bc1e69361012689030b0ee149b52d508ffd7c21905d1a9050709f6efb9c53884318428c4858d1e84bfd64d10f1d6a601f320ef75dc27ef429e329a90884e58fba1f772fc0f5dd7c210f3bbdc3ef860851841fb59f2a26d249150129dffdcc5ba1fefeb7fa19dbc64b08bd8e4410b456ddc15b59862bfec4086dcafdf66f97f538585d9ade8b4735f8d084c9407525491555cc01a798c5cfd8d6915b653ba1421e095f9f36d36d9d54314e842dfd3e4845af1670a8b444320281f2100b47dcaa3cd6e88f414716585a23bcabe91afdc83aa9fbb4d781f7cf4a93931f424cf7ad41d3f7e9f84dc064ce7c3166bee18272e8d234196161b5f3700aa67c2cfc2473bf94adbbaca9a9a5e6d2768fa521fb6359db929bbe74eff0906b27e5654c0aa82ce381dfde34df49cb993be982fd633df33106db0ea409144e9d8af5099a657d6b3e7048111ef0a8856b7028255e375a118f55aa4c75ac2b912aa09fc79e8ffc4b9ec686b2b7c5022ba457fb392bab81e9ddf9cf7919a07dbda1f41c7ee671f4473deafdcfb01f24ec3d74992d38883508a31784d8eb87d995275d791bf8975626935584fb06f55c3fee2769115e970228f6b7f4d1c2c6428dcdee9083a82026346f49d6f21927895cdea9b7d85d8e79b9e044d38d72e1c925f6e1fbd26958299c4a6c2c84205cbd03a12a57526383052cc0c24c90f62dbacbcad10c44de686572c99702552f8b1b37a9bee72d7f2e7e20aecdd73046c95c818e66b66e6142a8523679822434c4221076fb208746202dc2f8abe131d096881c366668de033d150164ad7ba27ba1a3ae5eaaff0b994323413ab7198536fcbedf2ff627a7cac37bc1dbf624eae3f8b7e8a8805fd163144ff5b9356c87e379eec00102d365a4fe0fbfa650f0708340a39020d484505342dddb0f04658d637f106642c9b55fc6f26933468a51049b8ad3e59b05efe56c047357d553e9f428c4b44dac044f4485e5c85f42a394f96532c795071021e297290f51724e578b741882ca0d4832bbb48dc05ff6f542601d9414462538b97e3df592c901a4e754b7e4a4a76ffce0dfefcff0d54264302a83fff43d7ebade7d0930f5fb038945503c360d5bc206ff5ee18369bc7aed8c57d61fd12f04fe29c8a97c14bf6b434223105a7694cc71d795c315f3e37c936a20cfcc42600d05e0d0b936a2059ad9eab76815c6a938bba286fad6544e463b660065cf476d600ff0fe641cf3e1ecab36ab16e30892ee8ad8c18a724b8759a7b718ce9ae94728b2dbdad7198cc3ad36fbd4eeb8a1855e14d989888b6d65b34be223d6a152d3757723621886ba44e380f2ed0082086126310996e82ec742d3d52045bea78dbd8dc37c5303e583f18db09f8e075586237f08860662393fadc0fbc06afc49a57ad50a7fe9e7e9163566ff93850b988f75a1294bc1ac150be1f449883bc9590124193dd51410463aa68afe6c1b29f4509c660f86e75dffdaacb14f93188543f695f0ac49d11380853c84e2edf88bd83ed99dbf9012f91cc251a6856a240eabc5755dedbb71e30b8330b80b41a75f5c40bbf3929b7e99a8ed341cbe01bc1f824b8c0701e3c00795581cfc9bfd4b5f7de1ce533f9e60106009a1748f5e1798be5b3184dfd696dbd4249aa32e6846cb5817da8280d221e03288b93eadeafd768f4b0d2055ef2a32369e6f71eff7d8db951a88c2c2cec294842de1a62ac0a7c47ecc6f3c1f9eb1337935dab2fbb8e63637cfe067084ef586d862e2e9a48d1875f9b2df6bafa846d10810d6ed6422d8e3f3115f8168597f6f0d7d87bdbc378da3db6a32d2d162502a0f9eb7940ddcf532ab6182f57b7bb62317ec7cdb6ec463d6c802747482951a55bb7842247aa2e847af215ea81e93afb1095cd315b839e4073a97f717f9cf251374fc192ac190390c66451f1769f2b895a63fe6092ef8f8d9ec09a793857ac85684e0df92bfcb6a8fe11b69577b23b0addf2a6cb3806c7c643397de7228e16ff1b4fd8f3722d5450027b652fc7c48804c71ed239b773c48b72594db00576172d345b50f287abc1284ab52c28b818b1906429594439344c6a4e5585a229b40c51565751d52e659851fa1ab908d237e649808be24ea99b0405e8ababe1ca765307343531db4187335b096c689d668d582edac7047878825840ed90a00f8ef6681dd759f34462992265498c09e99f4f779829895e02041b45d43b525bcafaf8e600b33fa5b4f8012059284992b1bc86bbbea350597a498abdf3effd8d31ec6852fed4bde085665bef81ba98b8c9777450c473bc033efc8b7ce275868d1ab9517abbd105b9fc2504db4476eb44203a62aa451ff06f8c38697b7aebc416cf000bf6c17772f27122ab280afed2a2a81705c7fa12754d087973f7011c960e17fa3cf4df062a10882a923b035edc3893ba9d2a77126bf1ceab18b383c53e3f0f81b0caca25b0ec797312a8d57c1e02c096979b40d9e7e625a06c2b6884f990776698c2a391b8cdc50feb8773050fe4c8112f919d25b08647e972010000d2fe751f230b254e1c2e7162f552154ee96b0376523227ae1e8f3602405e3d0d0769043b35c76ec6ca95d9603ba2f8214038b98df3d3e65502f5f3105616d003b5d22e35a91563fd0b2630fbe67a14cc1c130240859c88d04e194c0db43c3cf40cb408ac76ee7e8a761c38c3e90272c712d1254a4f63d9dbb663c7e4b6b7c6ddcb6f9b45779f73fb6b748f1469e55c5970d2fe586e601b75ade37bebdae9fcde5cff7ed381d00f5c40d1876f5b79051c8c040aca7324ca7f83646348f48c1467e15e19cc18e4470b2d4c73acf9d72df9e3c8a329b951ae0da3d18da13229b40197f94e5aac6a58577c7be682b66955bec4f2a0c8aafa07ddf5efcdaec4f35b793f17395d791780630cbf6fc5fa5f1e5d15bc7baacac304111f49b7140c2733d98166e027945feae464ab690e085f60a729981d8975e68c2cdd5fec1ce27e964d8f7b5d8a0a9c23eea98c323b36287297a4bf55a67a6133a7ca4dfdb90d42c8b54f4a11f9e76e4ab3858a3828a9bddcdaa6552b7b64c2571f0464898c05b6f6a6b747b4b5d30c156e5abf1f956f6e26914dd8bb0f42cd8eee6e9c5f2529d9e66e27a61d76e4e0ed4a0196af29ba99ea099453bc7f5529d9676ed2d80f9f270feffd5505c99fbb99627f78de6cf8f75728257fd66d9ab2878c7c52597a1a983d52152027aabe702fde2ee6f65f1539d9e5b7a5da9dabb705fe7c1489e497bf9568f7bc9e1d78f3a12493bffc4652fb734d6fd84d8111480a44b634bf8ba2c214061c08c5c742db378beef95f8636321fff326c5b249c0efa1d682aff0dd9557bfac0739484e920afce4f1c01147ed3661e81413e6fc4c584a48ac7a54e9d3986cc87a81ae2edde442ea4632ce4d0a6929f5856a6af0f56eddbcd9ae7b8a668129fcd2d23a8c9bb8da47d4d16ae987099d1db582c719f7b87d02c20cce0ee19113ca715f61e08b0510174da6ff7d18f7956db67fb09d7987d98aad837189535117a8637c0f15d67009477cb2d6ae2c22e01c5d8d892456885dd30340a6e327eb032138d28c4fe50594e6c164419638a1d74c7afd4132b53b7772d8aeea61ce16159c97867544ace78921f2c1b4168eaf6506cd9514622a98eed4cd1ed3ad55269e2382448742a1c7689484db4c011bafad42dc73d5d64f93b03097a0f9ae5886745283616a789d2f1e5e0d88852acdfbb920581066f3d28336ba02dd0887a79f7ef3b2b055f9bada3d5541f4fc7cb708a3a03c112c19c3d868c525e4f9063946c7740195b7ca0a9e2ae213f4d720ea413b9a2e3abaae397ab33b06eaace27b8c3dadd840cbf5ba6d0dd6f19d8038ca627b818e3fb9d4951c7da80ed3bcfbc046910776a87389f367dfcf3b24c0c1312f8973796161ee298349cd2b5175cbab35f89372a179fcf2ddb5b798ec6f9f4f6f389c69bfe99a1394020321916afa277a4bbdf2486bd5f17d1babf8ebd59f4f2f8bb3bb7719ea973d7edf2d2871e6c796df39fa54cb17aa50e6a6872d4eb9eb8e8e8be4a6a24cb590ab1c5e517c7b18625a022387c174d22b6618d2f582ba289852224c9fc69cc3207ea084305cf5fc1301672e2a809331fa7ffefa04523a67b6fc43bd5b5319c4ec73d10cf44d74efacaf7939a755aa0a683a1aa5db6388174242194fb1bbc69602a23241a81cfe574e5245c556dbda03eac64ece5a5b19461225e3006aed1ea401a5137c07a50dde03604889e7880917cd7da84df57e9e70b41bb5e2007180489fa8bc11e4e8b5a407ed72ae35b15c0df7a0d3ae4a532504696e61ba6f9bda0166b2b8d7fa49ffdde1eb2414418e1df07ccba396dca45d2cbdcfd72ad66c54a74f9c87d2d8fa006e1ced177a8645d7b171f1ca95789a8413de4536d70eaa16e1c24cb1066947de1f78a3bc61c60d43a7a259c3fac2c88ab1acd05b89d7fca604c872103ecd34120ade48c48ec79b0f934c07e47b167163ea3fd0e07587cac6b01923b6ab899ad380eef4221f5b25d736e590f5e6754b8b526b3f3ef2b0f3607c3ff3e8ce465b32826e98132d27039d605b9dd9879f12692667763020c2f10976797c03cd1d17181f0966b1c28e3ecc02f21e5ed3c5e06af70544eb89ad87c4528a41142a17f64ebf53c37b596fe249c24c05a82089e627cfd0833878b6f0e42fa30154bad0e8e60d86d917d300a5813967eede2371672ac81cecfedb7fb665c905b4b82749747712bae563e28afd0464039f17d232d581f42e2d11d6fbb86ecd97e88c260eed466455c4509de45dff9b147036af7b13f2224bc02d95d399279ac5e4be329a76bbef6cacf5135988aad925d772a87af5a5edb0b4afd1250ad4a816ddfb33502d620cdf8af3cd12a99bac594440b70b449a5b9cc554a2d346a41f6a66573fddd506da59e98bcda9f3fdfa4f2e0f296c427f320db8f664ea695a14c39e5fc6ac557e06d6082f62a185e6b46028ca4cd3f5bfead0113ad9f5c5481ded52605c2253d698e7ea006260b63377ee59c46c62e8f88c628c09bbe306fe2d2976946b51eb0c6ff710e08db721f1385101ac163a52149970892eea45666c2b78e941ee62e6ec7d9a66828620fe053b607fb5bb1634a5f4a4890028f14b8b4a835ab988ccf2159ce73eea956810dcc221f6c88cc43f70a8724c6c748123940cc95ab39ad8d70e47aed04d303f3aa07d87e83528fa008618157ef03ed4dda648927cadc3ffcc0407f0b8d66c80a6b158115659586a5ecd8b68814d246a9fc4674578da4299a27eb1618fdb5bd4fa8d188b84116d4e4df7fad24b449f54d696d5344f4a3230b29e5db91af1d6f2c6249146b1f09444db30add7f8e88ff56644e834ca313fb7cb25e394af3bce32102f9b362d73aaa16b9cde0d4357fb3e5161b0b4ddb7c351321cd904626be85561da98739397c20339ec68289b5e58b83e0467a0ce8274e6832eb6e43650224bd2974c867ffcdad9440dca8c9fddbdc8b6fa701206ae776e55908691fd9a2842dd136482f139e1afbb4272de27e0b43df896a91e0fe088a4b2c2bf2d33f11c30c68a19e196cd3ca97331f742249d85e8a35c6fd685f28fa3e66afd842b8e28865035e071ccb12f62dc7100ef6952c032e1178f8db0958fd2b20fdce1b5ad8c04d65410646bef32a6b28709b5d8166e302a6e8e97742e158b353e26b0e9adbd6c951dcb4fb6155f24c93f5eccc17bf9f20b8751ada81f2a1d1d2489ecc3df5e8bb7c288fe91be75c22d6a4b3a33e58de84f6bc2b01a637ce05cab51484ed0a166bb966cc23ee56431200c1366c6f18f4fe64a382aeb357c7c9647c9340881f6ad95b6fb66b2d3e33e6aa1cb041ae66024b0e03ddb2fb17ee287be38977d06c267ec9025bdfcf9f347bb9f1490f2e492c788910cbf486a1b5e87588f4b4d6c31d4f140be49b8d0c689adb3adee6a82e89e9ef1b96b3f00a4b3a81853186140aa4cc599f61882a55ab5cb8a818acdb15a6e6037f85eb0e411a85ab26da0f994c16cacddbd562dd5d9c11b64e4d297bc70cf39c32c39e5b514f30442637573a2d5d5bc45367c74168e68a45e830e72b165b66288af8e19d8d2465a255c7d966a3ae693f92f20269ca9588f4ee5130c91f8cdb4820d022723fdf40b916b2d1c06cb2c9e5708e35c726644dfa2b90fe627befbb83b30a5a59cb119d0f6c663d7b69dd5b4bc410ce5050685387610f70f983f45e5d798b0bc6845c6998d7888412bf77967103b6e399099a41feb3166a887ae81b1b4e649341c9c9e51e6d6108f3bf4ad754598ff0821673ab777f87f861a09fa27096be0ee0b098377719fc331bce8bbfe02ce9e2b24f767a56402ab456f37e0eb21200575135286288306fc9c9dd4a10ef4572a7341cbeabf61d6d5ddaad70eaee1a23ddab6ef09b9c4d1d61807439282c37c798894d692030d16e8e98b9e18e1e7a28934b626b4d105e22494ce31642600badea37e18b34866762aba2c8f9dc4fe641e99c38045b426d6e40069e08378cdeb32d0abdaebe8851edf018661d4da4f875ba70ca42fe75b48cb0edb58e8952f04d181e5ab76413902e26fd1a0e93382b2e87da7a5aa1402b94ff02cc9d2a13d9b56b65feca5f5089f74598e42a5c91869c25c432482fa14f218b60dabb5f6bdfdec9cd2df10ad2d750570728fb69e244ef6734612630215ea29ae0c0c02fade927e1fd177ef2892b95fe9392f13550ffbe0900c9a6f7603e2cb13a77f70ff1fed2b4f4efc2396cd00dcc344809d8ac9f9b0517ef6b9839430a1ee307687a72e588fe8a926da4aff893636ca2f8ce337c7d8e30e7650868e440edf1e1f1a0efa9810626673372228e1350ab8179ea03b9dfa94e9995b3a3b6121418b48af77a4a2c087fdb014601fe736ae80cc26181978f466b221967a2ef7351d60c7878c2353c8141a334c6ce5521b8efc5a15a0b31e6152ebffb9dd5c3ccd35a5cc4d39979a1db6c296a171b5b4e62a97000ddc05b6f0a9e93590eaf8d09468900a2ba254a9dc21c8579009c427b485e96406b5ec6fe0d6ddfb165eb5714aa64036b1d99db667b8e66cc196c64827d6d967c693c8bbc9015506b93b05b317b76ec0eed64889fe618dff9aecbda004915fe88aaea7d9d06b4332245e660571f4fafe4da9e84d32261fb3216bf3c2355cfb18396844186eb8f55827beec0530812aed470a68ab3fb9442c9de9ef26b3a405bca2ad5e97e4c352b7c45cb32e890c498bf870804eb68013a0b3f8ee810182e4aad47d1d65213d3ce905b966726392ce69cf3955198bada521cdaebd77d538b3659c6ea428ad96d7918ee5b3d5d50289add16e33378f28653fda087a527ea08f33e8a1b7241a3e6770f32f0d9b78acab098f8eb1529553e88daa6d68619337a1651ec27659ee9683f36db19086fa73be70e04548dc10235a9a29c18c0fa48d6c04dc134dede492089619a1824587f1a9526397483f13dabae8f2b2172496b66b8c5d860d940216313742f3323a9e3c2b03e59dc7ececc679c49407b056d6c3806b9c8d0123913b6510314e2de36953533ae63e76a5d125dea4da9c5ea42e9f3a9e25599d958b216c2e035c13f04b2615aec119dcc812a6b17b1ee4a09340acb1846521fd056a366c9c7479b49c20731f886a56c21e0796d5ee19c0b6fa4547fd89d653c56e0cb5f3847c15b29eb1b9863982d94f20be6507823e57ac3e92ce3b10a5f7ec1398200a1fb9555ac267625f9868d5301a25969ae2a8d7bc0d19fe4fd8730eb7923e30c06e8fdacf345d2bfda7adfa2cc5652b8abd4ebef29f3190c3dc36f85248876fa2a3387d544ff00f64df30534458aa0381028baed1fda57a5b329ca2a628a30e834c6f7e09af9178fa2eaf2fc49348dceed4f9417717142be3019b94ea5a9feb4b2fd082e1b099ff8350ccbb653b8370b4f9ea4ee77cc01a4c9f4894453645944cd7019e4a09f647024e843e4a0a06f1b639470944c3e9b5f40e28d49858f86dbebc5db762bea9cddafd721e09b8762adbc1eb3f8c0a026636e1a943874b406804ade017f5fdf223a380321c5c98618afb3364209ac28d130f3471e4628473d2a3b23d6329bb11e2da10068d1d6b8374bb4f740919bd7f8cfd9a5de82236dd38332acc8e4440060f8be477c7209a745a4665b8bef4d7629a18813d7bd24ccbfdfed9021c0227a7fd1ac755f644eb46bc9d18c8ee4da56d2abe4595594fa68b54c09502fd59694cbae8dd33929c59fdf546020954bc63472b26f28b3e321f306c91256be8c02a7cdc99e6b43d350fba9d24df29fc8a93030f93776590a357e49ae0d03c40b5b300e499e90a2022cb8743b9e1af3834b633c8a8a6320f34c5d9ca0f298c6a17738ced89c2b4a1f826a3aaa76fa93303a979e3a04250ae7b211cebd2d262fb4533c9796e56d465e1a4f4db56c5027ecfec255186b21e31b5991f615164b2682d3706374d6caa680423159fea37b475770ec849f0534c9a516922989aeb2e61bd965ded4210a2b28e7fb21effe49ce119ac426e181f848bdf3fe6435bcdc9e114b5a6b0576adc87231ba064798107f311f292bde1e62a0f6f79c33bc7f61820d90d4ad01180a4a7096845f8ac9c2dd09c941843688cf3168216ea6e8bd5203853f6f6b5ab978950258a90b2bcb637ec844f9a96e8a0dc4ef08e4327e8e4a2ad493e1560b2da6645792b08d316c40bcc6c2f442727679eefd8fad4c19adb18e07f8bd74537f06eb9530330c0b992a91e0d95d6e62b3acb7be3bfa50ea9d83ad1d00a0b594a813ff505bd01f55381d386c0978bc589cb4028ecd7519d91144ca24b8b7e699c1975c5d5193d697d0240a382051943c2444c1a58f5867f364cb8927cb55b475c0b445f5a91821b175456bad3a4617d4e09ef4ef756179c06611eb4a49cdc0be82efeaaf5cdac56d3fa1507e285155d40212bb8af207b8bfde03c4956795f187a121cef8ae1750865d4e1914bca7710927441933b80c68ed16cd388ec6c8a132573a1e7abba1ad17e9f8e0b9a93c9d0db11e406c7983c42e394f500bf20bed9cfd781c9d57c2c3798e3b52722cbf8e603cd82c3b7692b38a02f42ad838a2ff4930ca63b8fe6cf37a56d9a48cf5878d23ef04178bab4855283bde449035a147bb4d108017f1aa777a72272aa7c389fc5a8db2170fd820991d8c5070834a17edf818828da398614b6aafc9629e4bab6c1547801a826dccdb79f78ccb38b8eec2872c5bc7d6a605831bb2c67a8c8052a65a19eb049a63606a0c1c2b67d82685dbfa6a9b3ab76dacf611c516c62fcfc8de84825393a6fb9d42ee38d3fc3c53da8557769b5a98c6528c5a50146c61927cea5089e9c4d596b529e74ddd3d9d13cee41bb744db68b753894486c6e897c2f5392e1baf303290dd72a530b8192e81c25c66cce8dbb0ba02196aa855bab08ab92774f8cd8262c3ef04f0658f30bf56142999d0f75997a18ace4045b5d1da4716ec64a3b3725e6f252df4134b2e405b41a06d669ed010ad204fb250861bddffe08f5486b81a01d95c5e5dbb01022cb05094c981e73a5c9cb5e9e5d03df8d04cb8129731b93d2f8f9916c2303010f75a17ba8f54f05a5508380159ff21084cda8d5a55e31ea9784b666c4306e82a2115d19f9ed4979b3774acdabfe5bfaff6874fb5c24e1053b42fd5892a9bffe38901c8ba110319cfeb39a03f769b67aca52710c7e88fd75738e1aaf37ed04b2b295326cadaaa6dd7346e530ef88484b1bfa769f50f672b3b82feb7d11e946dbe8c050cecb6ae9a441109ea7a17d7ca98694e4dd149d1e292123e28b31055f320b0f4dfee8d3e6e2520ff74245e1bfe344a8572c5b441172adc12a8f33b393bbeed8c0f7e2624b7bcb57b7da8a1f53fa5c8b599b7778bd85cb1e8b90cd987dea1170cc900c5e80db6450acc99fa4c8dabb159ceb1140a9d2aac75468400494e733781294e93b38273324cd3b9260fc7053b0ba0c69d78bcd230467a9a4ddc5d8c06fba4da7e2e4983aa63498dd69c04a5feae7a93f49c8d25bf83205a2cc0f6fd176d32656387f33c83ce4eb96275f532358b9e45bf6a2acfedf0147f17a310f8549884c3bfd80eb110ec8ce29cf41272220fe960ab2c59964e20a9d4d2186b84b560c40167412c0758c51503fd0ba4d3ba864308742c75b05dde782ef0432ac37deb30add13dac0e6021705649e82d2cb8e30b23143e04c643738ac69cdda9cd97f97cbfa1baae2b076fa78c3feccd32962bf2e9339893301b94f30fcb31e8564afb067320608bf2fc177624ceb4a1612a5ded969beec3a10e00b84db5e8180579da0abd40dcace57de8705d80ba468a365ccd0c8c29397fc10a58101a0b71c4524f8b8e3e85d6b720f08507542e71b29501daea58601a2f8c9ec9971cd07b38a18f3f2bc68ff3b6c7532d9de6c7f0a9a69637f427f2bc787eb8ff8e40bdcc9bf18ffad53c3610eba57a53abff388e44db0da5db1367e80b51fa709a30323c59ea2e0c4bb7c9b4ab335648d49149bd827e9d13fc7e7c977aa5d38dda79c7b9cb600b73a115989527e80f9759ce975fc544bf5e00454763bdbe29c47f2cc7d97aea1368fc44c3fc5d9115372a9e429188985911900c62fb737308e290cec5dd26a37a1d835414d620f17167cd15dfaf2c91c911c26ad604b79195bf96023745a32cff21320bd862cd4b8c382d92e8d1bd75e120e27905ee7e1748507fcd0fbd8cc395c46c641b4d881e1f4a7380a7abf9d64528ae1a0bd256c41baab928948172a5ea1c50862454782b70148575c771211488a495cc77e969c74b4fafe09711c6d7093ce993e1f190e4bc9645352354517c34bb8ca173ac6b7f6e91e56d16a6ed899020cdf524af9e93dd333b09b48764117ce6eceafa4a4a13702538e667f8b04e99ada0b28902161f7edd4f0aa5d13be4582d4553e409425091f71ea261820277a1f3b392e5e7bf6857c3aa5ea07f07211f31203572012654e67223fa74f351475492bfca950119b4a456c0d9a1938a56181b6ece68e5cb76509a6ff4ed0a797d5b55536190baab4be3855014104c153e9e00853e9596f5ba6e5fb6ba70a6c279c878609faa35744aeffcbcf3e230a0f945db6c042ca2fec4ba59e8eec387f50a2dbf815c10a229a659ec44b63b3f866979d17c97ab4d34f0e0819ae8f627bc5a03216b7c1738513aa8905c8763ea82fbf15d4a5b2e543a30a913880f81702e8531d9f9e3ba5a2aba1cc21a1c1201f9d6d3984d6be271c24567791a708e638ec311843eaa32c93b89971d0d0b948d414899597b7808d7360cd5cb10eac20be53dbfa3ccf25984240e3accb26ef25a55a3d4e40f3f83b978032d24a33a07c78b3973eb5ef8f7dd4c63c8c2fcad8cead4589323cdd8ad1a4ad21b9d087f2154d954c959ecf3377c2e3665e9adda15310fc12d38cc20ab519f7ae365737c9b6ff33512a8f82efc44c9b171fa73f85b7fb8241ad0a4d545ddd6c606cc18e70006e4e0d534815d66d7911161ba83add966935550e28e1d90841a64e494143b21c5ce32e664a6487df95e2aa585fc49fb8cbf32bc2be86957dab37855bd4c99c45799a1d39835a02f47f4bacb97aaaf3b6f19a82816636a2f80bea9e4942e18087dbe52b1ec92a8663ac03fecb21747e7b0d2da2cd2e9bb80cb5840c0c27960a577b4cda60e26dd948b112d9ae621d81e2a56f2ee0aae1a270146179a6593246baad2a5fe5e65d097c66e90eef4d04a0c2d4ca9f9863fcc54ac54d9065758b8609d958a5c65b7c49de60847170dce5e6edd6590943189853c27ea5d049dbb21ec523d46b5e0d14a8f528ad5c750ce35580c3a61b4a6e6ff68a6326b9677178fa67e84c60b15998e339492af73ad20005e7b0ae34c7e1146d7ecaf4874fa4ce97dc541b26aac593349b32020a8a6ba57cf188cf3607170fb101f86b4310221b0c20fa290d96e9c42111a286e64490c3dc45f2e8dbe1546fbede92aef6a51fa8480fa5b21785f59571792ad4ca1d7d6b3a5117b5d20c728eaf627ddaa20034a08e10b6538096375847427270c646ea1a797ba6880a0dd36e5d00490904022f9643f0b8fffb53ccc01546726428cfde3313d66d98468914c75230fbd51e112d38cc50a9c27e6da079282c651f9eacf760e907890bdd26f1838a9ff1915e20fd357008b0a166934f8bc4f83d8a71adb96ec23c6c25d95812a28d8924e8981bad767ae1e8e426b1af0dcb24f7306a4617d25598e3188525caef981c4dada077696cb01c2d3edaa301844ab3270a22addf3e2a8b59927e4faefe39db21ea7c8973ffe32ccfa1a245895c513d8f329c6a5d25126eb5e215f53554dfe601e5032be3b7725907d4c5b9c3f96995f5970c6a2e353535626c7e3d8a60b4f402efd6183a6cfee9139c5724dfe2bd5ea8e9c70c3f52b2e91a23bdea04675ff7651c06dcbc35215e797ab1df2a2ca2fd6f0c9aeed0700e01f5127578e807c3cc1d86d41f79f355b0124e0af71bef97f0b3bcbd17cb0078548b656eee0daa5cff37c2298827e7bd3b03050798b2517c069ca36c644bc8816d6c0875cab47d22fe0549d0bf73fbcfc44bd25020e502b0ddd32022b065a4b9f7daf4964d86fd3d8584856001e6c480cbb400da434149dc4b71f6b0d234497f840b36ff8c1da4638dad478c276773ce83ec65074ffc67ff750c22b449b4c40c040cb4966e9b7e56456f3cff643a34a5a135f976773473fdc3e159be69b6b87604e4b04385f9abe759f4b7a5859ce79531880c78018b2277113bec70c9fe48693c53402fd4c1f8cb8c4a371be0c46cb074312b2a2a1f601608bc56d09eb47c9010a0a0cb428865d521ff17b757f6c9cd25a9cfb45d0cd751bb4676869d73aced65105a1606d94c9a023731cf4c01e9dcfabb27a059678697ffd48937d81dad0bfa98590f977e248b39d17aa2d9fe2edabf51a2283f8583e17bdb0241992fd89a9007f0a923ba675320a45daf41b7f0b00490a107115362aa16f1570b9acefbf06645a41a3c868774c7249ae2b77375c94e93c4e9e2a29d8c43a60af2c1f9c3dfaa6a234810105db3795ede906dfc19b7e9eda26225e4eed4ce43e4a4e9d41a71556f507e78b55c018e6a6f6997e3051bda142d4b84c530181b93920c8e258c4991ecbcc8a06eea8408184b88def4fa906f59d2eb096532ea2ebac20f4cb79efae1814086516486f35de3459bdeeb8d9f12d5e95a08141638128c063bf2b52d044773427ef5dee7360270b4a507bc36d37c8881f5a86a99ef3abf51594c9bf079f391b59464c96fc2319644a5be30a1c009ef9c205b86ac903c21c11092daba944714d2d997e18b2e3502a7ab56661501c4c7cd210678f42b6ede3005168d7b55e3c5e70f8770243f9e1be5d489b090f30d9ec24a31eba25be0524fbe5b710306395bb930f7bd3ed4ffe0e2091be6495f4a40ed063bb2bd5ee21193836273069e9a82744d37c9d31b8d10d8b9eb4a87d6c8fa47b579519c85ff500f592df69984d18d40ecf2f3f593aae4493f84c69a6f3b6f09b4dd9bd81d3ea079234cf6ee08281cb5de7c6f1894c5d35757d598535a83aacf5352f447abbb3ed109c1d3601122ef7f6645bee1426f1039aebefb95737363a73999fde4655c093872dbfded9053c4752d364edc0a1be8668eb8278004bc7fada6e1f286512219da67f59ed3ee4562b4c3ebeed8c9522d32db4374feeb79dd4f9256ab82104d13267d0d5d05ad4de6c21ee569f310158116189063624cf8f687d8da80d2ecfcfb5390b568c8c941bd30b7d7d2ff1899dd792138601cda5046576ce52b82a112745d6948cde41b28493571dfa3b80b0ee792468bb009e9c9ea63c6397242dce0cc71666c25deb59e1b4f54ce16c610670b4343bdc5acf74c36b32b5a06f3e6cee020e8493935cadda985761b567cd3b394ea7a1a9c19cc3aa64fcf817e4a96a7e7fb7c81f6860d66213cf187bbc0dcacb429deaafdda5757a41d02918a122103cdaf0aa6558747fa4c32569e9ae490913828e10be0e6956c7e1317ce5e46823f9df6f275cd7eddde90f2ecc1ad638928e4f89d38beb5d7d661d44c3c099e22d5af1cacb7ceb3584d095a579600af5e8dcbe0aa166024377debdf49cc82cf03e2b786fea659f3e58c55917ee649b530caa93a3dc78abca9d0addce4d17bf5e74f34719e58249863107751ab8e964acc9749b568e811bc71c35d67faa6e904397d57165c09491ffb2bc69f7394c9923e83cd39337bdf7982a9ddb7adc1603da7e9b98b91a98d0f960386fe0dee54f01f3e8ff3af17690af8728ecbf7ad2baff247d9c9cedb8e07e04c7663cebdfe8f47d200e119d7a1b43d2e482ea8d9425f27fa32746a3a5cdf86fdb034d182e5ed8d6de535a8a16f27f361ffc852287fc1f8ea312737d35a0dac8ffbdd4b044ca5b84f3299c900854576290dbc266c830baa9966ae14b4f81260163ca8e9d0020bae9b32ee93aa93fbbb7a628e23782bc002c1846b87ccee32199a208c6bd33bc004c92a42a56640fafb6ddd2f34567dc5d606f117c5a6895aaa5708cc2909a761bf988c6e033be00accc897f2f0000c5a326d0771ec4008c649b4f25501305f7e2e6312c142ee4b47615bbd649479bc2be7d8572f091acf1358309109d61e47651738a4ff4d5d619cf0e6ae30989833ef2377ef907159caf89663eff8703c112fe00f10e93fcfe834addce21061a032aee988c762ecf6cc2a1014b9bdda2f7739425e0bc25a0818b2860b16ea7377aef064ad52e85f7ea3398ab808374d3e4efd9028028085ab7be4002b38a09266691bd868718505c36c11e13478ddc35c7b5691b09300c92ba25368fbe11030a2bb832adc916840d5069d92514c3cf50ca1b6083100c88e92b7cbf84051a7877033a754c4391a4d0316dc0f41308a79af4606db8bfa7aa8b00ee274b2b149cae04722bb7e0c701a088bff2d44399191901c69a394b2988f32b7e0e20fd1d0fa8c3772ea557c39c9e8fb553327e8bda430fa2aa3be8334156dbdddf01ad0ea21eb0b9a107e84070f1be01080394058be145811efe5a5d1502fd37c9082b369c40dccae3244282c08241d092872f204ae3aaf7b21fec48530f7b981f29875cf7d4a0ad91ed091ccd8266c4e45b93acfc37d34e81965d356ed50aa22bc7de55b26f49642248bdb744605deb38162d30fc2a0b24502df0c95d031fb3455f60964987088fc992d80bcc52f55c66421d3603ff9eb1555ee0e9ca4117ebff8adea3c2959c1ced5f0cb049613168fedb8aeead139b57284a1e5a62b56fa88ccdc54ca34fe7675d0bafb6831fac4f96869a717b688fe82f71f4117b846d1fd80eb692cff378cd599ddd4a3445fb898502a00abca687187461f2d34d8fc08ab5449785e395947e2ea5d6a817860afba6cfbf0723d100163adac3282cbbddde96d95cfeff4e85da9b4b6965bccdc1ce203c10f64a5fe6dc33a09439cbc5eafaf7d104c26d36912fbe55a7eb02aa0f260e9dd0f763d44753836033309bff29aab095be0fc70d944f494f170621abf4184f908d78fd945d44df28171fe43d50bbfc9cbfe7a7b45478e3d8c0712c9e6f8e509a5610cda471e6dbc1ebda75aa44ba0821262b16f9fe71f2a616940556b7d116ec7c0bbcb560be6c24add594b559094e0234e9302a6cfe8e38954615a3195ea7cdea8b36929506b793e50df0d3b98a89a6d823d0ea8123815e8f297250d33ac85ce0df2e55f01c338c547450abd85542382cec31a165241a29098ddae78129196488981e1b5e9995df3699f264e3470feab7656598ca52ae1ea71c6cd1c3f60491026bc4dc2bab9bd929fa5bfd00c1c893f6b7b4f04bcdcd808a619776144c89e308fd88681cfb309bd2dd7203da1ddeb6c08abdc051ad34e3adfc86539bee35d5a423ae301396736da34189d96982adbad2b031ece7ce3939af8dc4de689fd2aeb2e8a9ac6a2230034d6bacac920588eaad65a4ec5eb0e39891bec00a59b7cb957a0a49cfd0e2cb21fa43bf2ed23174592a41d33667ef5ddef028e86f899cbcd5b78873cfa6cf27c1a918cde36ff40d0ddf646c9f7d339e1a0ac0040ec096e5a64adad5b347fe40038bfcdf95d9a99d003dd8eb5185e0d9a7b31dd4decc53af4d2856649e62ea74e2f2ef373aee9d7cc15889473d724d809b2bbd45f7ae7a179ff682f29aafee556925d1c3080bb65f3db3388195d04958d674fef3b5528284231c95991735aa5d1b64f9300c8980c749d1cab0dee9f89b621299be67cc407da1e058d21e7df217ac41e2a559de995930b10342bcac95d02c7c2f981011cf505592aa2f9f4bcd1cb3028d1b2a82a79215daef167014ca99949638b3ca5903dc073ea50f486c695a35b43b98b6600a7cea88aa6ead88248013b7a48320c1bb1fbaadf40177dbfa50d2f32ac8f04bb85c2942e50f9a6a0e43d208616f32c26b98bed6a34ed8da24071facf8e199ca173602a6c233a40268bf9c9b4db9ac16d0580789f42cbd13331945f54bfb092aa2279e4f032e92cfabd04805a670ba89eb29349e015f36d34d3c9aff267f90f45db44489d070f39fc787de66dda5e6c32f371451af3c6a68417f6de7a4ff622ab3367dc64acf039266559628ea6a73935560b439d2750418678b18588647ec1c7a3cc4307c32f55ebf73480f7b5c43fb56d8c49871374d85a4f38c0fa2df8234b5056efb854814551030ed6a3a0c581bee38d40832fccd155c40f303b5048c0ca7d3e988fb81d36345d58afe29c46e29194d64174fa891b4bb45f88b4f249bce8df5e3f3b0b70b13abdff33aa42b5203fbcd31b4fd40c2ba096db2770a1216e814f9125e91b7f27c3c1b2fc7f3bc27de05dfcdcae5bd40eff33c98e7b52cf87a78e0e7b140cfc987e3adbe0bbcd5eafbc00ff49c7c9f17e4bbf16cbc17f8799e07f3887c37ae9507be40cff38aa8f703c90bca6a0396b7f26c3cf087676303c3f922e402af08e87d5feb73bd1756308463c5f33eeff33c2fc85d9ef30fc8786abca8e1d44b0f6778e185870c1174a96328b1458c303c8a47030ed5c3041eaa4ac09f7aa04287271e9c454b0f61d43855a229587ab8a00456ea9021273dfc107252751c5124868e91229e1baf89181e0a9accd6ecd084a6c0c7991c1704cd88f880c2100203d121241bf000b40606339a8301f5b1e33cf000e333560c4ec132bec17d5386b72c77ca8c6a7b8bbb23f98b9b1e87a1741eebaea5ac65e626832daa5c362e1b50c7ab89cb66452427ca84a69e974febe66504e6ecf0c09c960cd4ad74562298a6cc0d552d1d9fcb0604d22162a444d50d979c1204d261c2472484b505f45a50185015054b9258e6036f402c3f27a802c10948bc30c163c1440ca698f081415641398f470a6b832faa5a2d0c9ccc54b0e30885551513005005c4a64b4e8f9c1e2250a920f7d2376e5441d936556632842e9b950e4b0a54a105135ea08e16116fc71213ccf0c106c905ccbcde18808e0f873545743901affc17264ee0c1f2b9a172a3410b041089cbc90952f450e504235eb0201c32a3436259e18a2a9cb38643191d253b3c2e43564f5c409a9870e372d2ba79e958152d555911b9a1e246d58d6b4907ea65458812951b1b2b3950251429aa7c80404d6e5a301e3aad1b1ca59e1084a8ba7959b980c642156b15b2bc9696d60deb490b8994239cd3e6c8cb4aebc6054427c9c608d864e3a3c7100d825880e4b5c195270d4cb8798dae253a4b8a969c5c39a02b080bb66a6293031ea1535c36ae1b50887505349ae2b184ac7858160cd9bcc89513a5273f5e3716d8149980d48443f4f2018d80465a465421d10126b136605d6063041cb223c98ac80955a390b7aaad82c0156b849e10046005be4b28e1051a269630028815c89040a5a56a4fce4200e1030fb86c8172c2d2811598d1121f0d322842412c1cb0660d1198c181940c7a820071f110012e8610428b1207302215e4e0b4aea0220149103104103ff4c0830e5b7c8e088d38dc1005b5660e13d03e58430d05c8b028c30bb626e5c98d8b88186028b2c9409a2288803969e2a307cecdcb35440802a000e1cb2c4d1d2c5151da21002a0060270c26552ca1841164ba70296af2a30738012f4ac0454a942636ae56132924c0091f6a10000b231460871d5ec8d224e5c9911c4f8e551cdf1ba01aaac6770668c627062b0c4f031f06be0bd87c9163816f029f043e2abe26564b7c526018cf8887c18b086b880e90cfc75781d743e4c1daf9442f04757c38ac9bcfe6f5fa5c2ed6077a2bcf6bb9ce8e9590951555a00b5520961612eab9da302114a28ac5ca7169a00113c01e92803e728038a2b5421588c5c6829b213fca54d978013f585d80b35b392f2a2fa3d6cdeac98f1bd61655af28aa7a8060824dd14a073672c0a862ada962e504b94055ceeeb1a2cae6878ecff58425c49ae14c053840067002d842d50e9e1d3cab2051e8f5435c73026b8397910bca6ac70aca0b88aa155312a1d64d0b89aa154e2b0808849364e5813920d00d15d6062e2fad20ad9b56989c1e393d6c7ed858e0f2b242c109ad202b264e60655195411810476519100161393b5a22e8ad825648a0538e8fd6e7eae212e26a6255a0c36be1ac5860ce6ab5fa56aed56b657333045cb9b6b8767638dd88ae96cb5bb940225008f45e4056424cb0c1807544950e244c105ba09057d209201827f4c8a8af498119194833012f2090c569838a0106a5230ea214e1bb861a4247c21d2fd7970fb234ade9c20214c0e085211b0630e50630302081072800014b0c21346a50c3b95fd0b90d12a8e1c0171670c001c8941002081f7890a5a90a150c2ef061011553905942891248901119822f063ac0f080185cd59a149cc00d10bef8b040c4c003b0588002100045132f04400559085eba64695a9240175844a00a1bac6c4003127880031460851040b080421912a8c1c0170ab0820a27cc547db9a424eaa829830c3020e0802912f0441131b8f0a52c0410be7459527a02fb117524d0050474c02106335f86d0c11215a527301d3aa097418604bad0028b2912f0441345c8100033603a588af204564494e46747047d4d196478400b0860e1802912d0441132c4100017cc8c210303020742e31c7260b9b243470786c0d0020b1e7419f2c10516765449d8ac59a5e043014b8e2f8ed711a0115f11df109e922fc96ac81b7182561baca805187c433c21ae202b20de0fd08767810d8f9d9d5508eec8d111ea04c9018233e446b471bd5aaeafd562b1569e0771bf09739870779dc73769755f9b73425f62d2de9388bbe7ca31e32d0f73b884394d618ecf0ff5a1f44babafa5dad26de9935daeb9de485a2dc57103878d10870cf719b55dfb371dfda151a0509f2850e8b5b6a7e13c11e214e13ea3354cb5a57b4703338ee397252bad2043eeac273dac23ee8e818738465ce7f1e6dfbbe684f20641100457abefdbc0431b316cb8b876eb2f29ddf852fdb8a43f3e4fe613ebd046091b1bbcbcbf2bd5a1873654e5fdd0868a0d1135690d539a712dd7ade9db6ecd371b50e731df48dce3849eb4a6b639c1dd2f70b719e185e6b5596b7fe61f77f771f7235e194e92502934e79344e2c489919322274d9c307142e4648913254e92381972e2c4c8c8a8c8a88911132322a325464a8c92180d193929322a2a2a6a52c4a488a868499192a2244543454e9a1835296ad2a4099326444d963451d2244993a1264e9818312962d284091326444c963051c224099321264e888c888a889a10312122225a42a4842809d110919325464b8a963459c26409d192254b942c49b26468891325464a8a943451c244099192254a942849a2644889932446498a923449c2240951922549942449926428899321a3a1a2a126434c868886960c29194a323434441ba21a7a7717e2a10b059d47dc798536aef6199360dc5d03f0cb0d90cf8d0f0994043a02a54037403723504a2975f70cdcdd88bb17717790c7354461ae9c1908c29606b27077201eb69698cd28ec066836a3b05d7b93d29bd9cfbed96ca674d7def4995158f9a6ad355da34489c2a3ff46ee8aebe1095b3b2a0a74e408dd95962f45da5b732d2777582bc8dda9872d1da7daee9346a9b67fdbfb64d2e19cf151c83ac37d1cbb70779787ac07b072f01f0a050a4de243ff34eb149dfdc54d335ae9c574f6e393ab59774f18ec62bb735966b47cd3ac240cee3e86e01cac9355bafff8e4b735bbef974b9bfc30b42c0270f72e1e8273b8cd82977bf9b88c6b66c5d1a4a52c45ee2ee4ee50dcdd030fc1289d474de6ea641c0a2a2d0edafa62d2dd7b90b9923966b3471847913966a424c9eb7ae4ee3cdccd7a6eb296bfc9cf51296d6bb349b76dbb8f45933976b39df82a6ddcb47192ed5ad3d61cb5db399cd2cdb2317eda5f65dfdfdaea8bc9bbe4ee629871ce4a9ff1862a7fe7ce9c3192fea9fa584a6bd6a9bb9431951ac6d9e97e95ecee501eae80e83cd2acb933a65577dfe1ee3a3cc7dd71dcfdc693c1ddb778f899e177fb16e0ee14a6cb7b621aad61ba4f4cf196e93c0e8d49c62441faf78e26b4448911f94e68a513274a9a90e42709c26172a49db76d6dbbbcb5b57d16c2b65cc951a84a89a02d4ee871f82644a340a1fe7a1955e0e1477d5b33a7e96cd7d98e879e09dccd1a840f0fbd27dcbd87871e0f1e25bfbed6dd75dc5963bcadf358629c10f953a1e7c191bb5be0a107e4eef74d0a853e8d96e6896f9afe506d7d28d597d7d29fc2b8cfb25cd56977b771ff4a77ffe1a107ea3c6e5cade5ee9e679cf3d35b69f9379ffb33bdd8eebaefe3decce12cddb6e64d6dd7ee5d7119d768fd5aee3ec443a77277d1439fc1dd75d8ace59fc274b72d597395d479247f4aa6ab5988cc5a88c4a6598576b9669a35dd9db502ddfde3c0cc17073840151b1f6890f8410004c63875c08aa89a0488d0c831957c784060e4050fdd6b8cc3061134992a006163d4f35380245ef000b2c2b8cae924231c843983c20faf0a00a98a02c7d15455c57c05c48c0d38384467bcfc4b013473c6a3291085600d2b72de3e622c1ac63525c5a25e071e134355d5b3955a3d521db4284b0a4b6b4bb5a817fb5c3ddb8bd9ec10426506779c1d3478d4eb99c1a3cef3ad78563c5b8a45bd954dec6bf56c2f06ae89b1c01e2a7c7bb1af870a6f35021c213492080defcc19907ed4e3317306ec49420c07522b2ac6d174c159519c55cf151c5f8959992f332798e07df403bd038020084a7dd4061c33f55156cf5e51d62ae6d1970be49162f5881913b3e9916a51d69415eba32fa957cf981808ae562b70058220b85a510ff43ceaac2270dcf3bc559817b5b1a1ceca1ba4ada98fb6280be411f32326f5f578cce31163c58bbdc4ac3cda23664cccd52305d28fb65a3d62563129a71ea3ae7365471538424000234408e9f5c011a265b5e3078f7a3d3e780a30b3a26652203a62d13154ad332dea3a5bfc8845cb90a9aa02573cad9e174f1488b3c307779ccfd3f1c0a945573cad568be2b8ce961665f5ac7870583a4e2e123ebaead2a2df9702092dea1d7d2e176db97a52c869b5563c600a24b0a87704521c9c1565f18c2173c43a5af5a4907304d2291f4bc989453d58d1564f0aded18e35472cb0a70aef49c13bfa7aaaf04a687d200e38ab2216d107429042c1a1be2ad2e1f9705639383cded1475f3d551ff5e88bc78f7272a88deb06a4371ffdcc8034877a3c24d850efb3d1a17e94c343a6aaaa8a27050e8e56f486c7cc19ef684553e0e008a4ae23440b487568d4ea0887474787dee0d033ded10df5e88bc74c0ec5f17848b8a19e8d4749c0a15f4ec8a323848a8bb6a45c3d43ec3edaea1962b7a21cbccce0d033d48c0e4d811edd504fa7a76a453deaf59859d19b9e2a3329d0231dbad2f940878784125614a7a76a4575b4e844ade877c363c373c63bb2a1383c6652e0e00887e27c3c3a2b1d25215a40aa433f58d11cfae23163d385cc914e0f0994841b4a020eebc686278524c470106b51ef88888d508caf89b57aa486d87d74889d102d20fd68d48a7af4e5b4a274f5b5a4c0214a23fca84789ca086d70848000867aaf55d19831257c74454bf02848c72411e5a22d3ac6cc197a14654359b48417bda13e26057ac4ea1953428bdef49ca1472b6ad353c2ab87455d3d25b43ccaea29d3f26e06aa8858c3c31a1b5060460df0f33ed002de1c4f78ab700e1318f17e2001fe00636172629f8ff7792b2f470e325e46af550370d05cc941220e35719cc1c6cf8e385a8863863872880388389088e309c7f158211c73b88ee741ab1d8671a461f580ab1c560e1c5a787050c08343031e1c6378dee781ac9507470e7000010712703c010715703000fc5a28a0f15eafd70f9082a0d11b676220f8860dde8a7e3a5756d4a3204501e7fbc21ef405d27ae0f84794055116a0e7795e16edad413dd08d39dc308197e6042dc4da30b3a24f629ea6046956ab96c33cf6a238613eeaf2c0d8176bf57c445d84ad9694778515868c7f06d820063aac0d11ecf8d183c562adbc1ed08d1871d88f188b4533f0271e63d1230ef3d80cfee36de4f06a0388b00d247eb4f1046d638a232c26aaaaaa8e38720aea286d10c3017df5e908332616c67b85f9562c23282cb0e5020816b96898bd22dac24c122b6a26057ad4ea49e33908e6803daf2f8ad6ebd57ab53c25cf080a96b0c7aac56ab58c5a2ed7b76ad196165e822c3e1c56192008b672a07c3facb0022c232deab2f96c40b0f5d2c971b9e84b47e7f4540163383d2c0f02691530e6eab90163208e0dbde159c16c28ebd371b128c8638487d2d0c5fa7c86582c106c5110a42d90b66e22f0b2f93e9beffba80d0fd0f7b32a8aad98b810ebfbc0d647592da0cf670512f9a409d18055d8785ecf8fefb55af5f8b4284be7f54d59794e73404f07a43d3c90b27ae440f3796872c0f93e96fbc4b4cbf5ad58ac6fc5ea01f2201608aebef0c2c603592005592c10044116c862816a8a7c7c7c5e2478c3f5234c8f21b1154841230e6319b91c06d2211f209f17359263c40b968d0dcb8605d2cf676504054b0fb0e56ab568185713578b7a8cc562fde09902335005c3ca87e903af7c14a42c5087e5e2a161fcf359c57af8be8f8705027d31acbcd56a459b4cf97c5661c80611abd54b07908d19b13044b195b7c3615e0f140f5a515087c3be1ea75032107ab18fbedef83e8ac3e209c3a11378432c4a8d7846565febd3f97ac2901a617d4394d230fcc162b1a6f8a0184531f2fdb0582c168b0d13c4582c8ae5e5c35a7d3e465f8fd1e7c3a25f0fb562c4a250b084445f93152513db1ff5629f7b01c6c7a24ebf8f05ae562003beeff3becffb28a53f28b85a7dabefbb22c4f1becf410aead06a79200be4a2f5b558dff7b1be6fd5fabeaff57d9f1cacef6bb1582c568b25c4cae359ad56463cf40182e2b55a2d6aa4b55ab5807c82a8cfe7e3d35ac901ba3e10044110044190822008822005bfeffb7ad0ac84f0224aa91b3c0c7d4386b0f156dfe7f91a3455aed60742f1a0d52a8afb185d11be62af1e9607b97a7a8c7c3ee12aa4d4c8ea034d80b302f220162bc87d5854c7a31e0f088a7a7c3f2cca3a0ac3f8c45814e88302bebcd52a67f5d1950b9ee785a18a85d92b4fe7079c149c112312f33428382386f3e540f97e563a4a203562a4275c03430812690152d0e7c7eaeb6179d0e7638445874e80650804b1d547575f48519066e5a373586fe01039200c12c359812b6781617c629ed7628134e61ae2412bfa83e54d88b8cf7745e831d0d56a40f8d12ff662391112e147411e9607b128cecb49c00409a220011a17f298072420c27f5ce90b12033d88f5d9bc1810b25e37397ef4830436c45674489832622b8a839383b3001d1c34e1ab47478e8e520ece0e1d0a087758118a6115e18e4845c863678a1e3c1250410f292ca8208ad0870508087ff870203f5e41807c3150489055ec3544089121de054430b8c0631fc580877a3d3c457a3e234532300245e8c5400d32008f68f0f239f2c5c01f9f55ec85e4c7db0089c73ea00dbc20a06f0c3a40e8c5c098d0f8443824648030c9902b49e22d51f2112d71225c31216aa20993a22646454e8c604e9ec0a03c8902454a140ea4f8140e9a884d398a211d252129255151aa42c54a95252b1d2c79573ac07285094b13539626a72c9f16a7272d504f51505ba2b86c61225c75e1e241172f1e7ce0e5cb07207c01034208606421cc647546ab24ad24bfacbdad76b3b9bd85b152619630a570e6c5e19bc36272598cce5b9f7bead44d51e9765422ecbc114418330209634a20814c0955644ca83ac18432279829838299145000400a6700f0a9706605155858a105165c6821002ebc10802560782106186488410032cc20001a66a8810625c2d5006af06c1800016cf86e20000e37ac72c041871c7c071d0ab0c3c743017ae0c1871e7ef0c181f82108203c2182580d210411437811441851847784112b248ef0d89704125e6ca544125fcc975022897015f3623945433e6f091d252442228e083feac57c3e9f1f5f8f9107093124844e15108cb55820cb83be1e222342cf0b42e7eb212a22043d26dcf38cf08ef090f092f09af098f868921a38fe799fe7b570c6f3bcef5b83873572f82e80e31f0e0f26741a6081173b40b0461b62190b66f011f3346a8c50b3001e70887e48a3c61b3e9e6d0905c230ce819847b178e1feada07c3e1e1aa02120cf89ce84de43c641f0cbf11ea0c762008ee779dff7b97b40e0e0b80750f0267f8ad69f9bae5660b028baa3d1f2f77dfd39f7d98792368737adf4feebf6d3a8edda5cae32d1716b6bd299942828331cce358afbdba6da34edd6f42f7e1cd6f47525e9b574eb334c0d07d9e8c6970a1fd1719731ee7141d7d2b7e56a562ed8897e356bd7d2d75697ffb63149f712cdf46934ffd45ffa19d73eff6d97b7d27b526d29eeb78529456569a263f925d574a4589b95026dfd369b44c7dcecf7493ed5cfe88e46f743d1b17cad9fc439476dd73e8dfe6c4bf1d64774aee27c68ddb5a49a8efaf1a63a579980f2dff6dbf0a6fbcc99f547ffded1e8b52399716de3283a262de56a9ea4ddb9e668bd96ee7b6292acd434cf1afd5b147d5c6d223f07f5ba7e26ef128ed2e57f1395128e7a1c46dae6596b9f7471d3be2746aafd13ceffc1c54da6a5629a158965dd1d8b874dd870f7809cb9e97a7b7d52bc29fd1237a13005d3665398a64c99e264cad0142153804cf9e1394c7f32f0a1302a447f32a01428030acb610a9401f5a1140644c17cf912931c8c117290c58f4f95c1a8b62deac98baf0c06d3175b2dfb8c492d2b7feb33ef7bca7027ce5e8b334ffd7947deb7e5c7bd6cbfde16473bb5145969a6596b325b5050d0eb7acbc9ec364f9c4c26cb057d142ca25c41f1a67f96b4527a4f4a0d308002a8a1608a7c09a354b9e3bb7b29ba7b29d9a6fa1b46c1e2ee3f40bb97f259dd70d3d5ca0d06236dfefbb6fc657d2bdaeabf5f85fc1cd49317375d6c757e2e545152e4df90b4bb7ff1d06805771f8f9268ad96a5fc8cb73e738e7eaef4a7bcd527ffbd16484bd5cf694c5e4c526d6f9bfe131393fe9bae56e8f8e3f3b72d82d574dfcff944a2e3c6f8893e3131d1ad7f572cb4525d6f95eef24f298d74eba7d1bfedfcdaca68f9a59dbab6dec86be9d37de4e6bf45651c6eb4a3c6fdb61953fd53f5d26ba9ae375ac3389bb8aaadac56dfa465593fef5e4af6b65b6f24cee69c2cd737495892bbfff01006e44e6174574af1a6bb975aade1c4012ec3597cca82aeadfb9e1817f4a6547e5cc6e1642b94c18510c5c3221e34ce2f02b55dbb332fa6657d93e24df5b634baef5bd2d66aa7a6e5ef9abd69af8bbb971e36190a8baa0c2d094109bdf5b6a9d66fee6ea5fa71b9ea13dba9cf4ebb3e6de7fa379d475a509322dc71145f8a420e6348795cbd34474f283a8fe49231c9b82488fc1293413f65779db2f94b99aea65965baca6ee4ae34d99319d77010ce864cc6b853d89798a46fd2ea8dac9fef49cbcfbfef5398596ffe7dad69da9a7e5bcdc972f56fb2fd5a4b917f2365fbc45f6272bfa6b2b5cf3999695aa97d7fea65b76d7532a9ec01c0ddab42a14c0aee1e0965aaaacca040c68cbb37a68cbb7782bb47668c092578644a70f748f0c6d8b48a0cb183851934eeee1d8800cb147fd99866452a2de692df342bd2b5369bb3ecfb534a2f55b7be5bb6ae26762a5fead6276d62ec84c34d17db8d999ebcd59a666c6b6bfeb6b72eb66b37e662a72e4692ca15f74fb5bc9fbff64fa5696f4836cbf43647fdae1b6a6b8b25ffc6a7187bb76cd356d9e5df1b63c93826ad73364abfddf7c44736abdf5671f6b3537ef32cff4642d9b8fcd36ebf2531d46ee7ac49e5a74c8ca4f55f1c2e6f7d322b6933deda5ad14fdeafd5b2ecf24f6152dba4ddb67fad79b3e096707942e94dd6bc2f46dae553d7cf513557de9aab3c0df74cfa7f6f8bc361a41bf951a625ef89917664cd24c67d92dde6c94415b55febd8be8fdb55a728ad9fb4e55dcad99bcef8b6cf580e57b7a6d5a3ddb6a6dd5ba05aee1e0b74f756eedee7ee9ebbb7668e14b83b0ae658b366cd9a356bd6ac51e3811d41d07490f3317a18a2e6cb1743fec5131e8a5c98809167c1030748d8a20a0f9c8a2b2e807326e70c6f22072a649600c37d882132f8788115ba0e4faab0010d32ee0250535ac00010b0e22c2469428a32f3e0279c004a04d504463e8213aa31608059c0b59a2b72222079c271162c6dc1ba800baffd60860d178dfa4c86a812c86069c13fe04009ba0000f9866f21a10d1548f0a83be5a4e87abcb8c2af2ce14060e072e15598406181230120e1484e85788c0039073750a0044172e44f9caa8457c4c086177571802a3868428d139da06404272035e0496c38a091a901f27184391e20440a667c032a5e90522543e93f1a4041e29e1eae0102e698a3042430c28d5c1eab2f4178c07ba86c81238384294ea704e141024202fc020fc439c2a8220a1fd2c2075cfe00250fc281344e24b1011138102a1ec482a478c07d3c008c27b528a15b30fb3e1d01c2f00a74c24c816abe701e5d5c4089129070f8ce0f3e2230fb32858b2a8469962815e021990330a143180df88e146e74745140e83a70a0330001c305ae630510358cbcc0798e1a45e028536081aa1c243b6f728348154e0e618e38be38c36f1ca0c119392d3e54ddf400f5883aaa729b33150880074b44f8eb0d165a0841115ff82ba705193d607155b94810a2f000244bd0b8a83ee019c00808d0b85c5ef870ca41cd94960e26151376e4d0b49c3cd933709929ac0d14e172058f31ce3a018513725ab8d0b0848c24d1c1ce195560184dc810430b4f54813588a1c38e1826d0805a2e0f4e4a48e26068010d60304064ca8a0238802047192e61ac6c6040991fb43853b5a26db9917a5a4357421828e9e18703f44b811a2c3ab88d876f0237a87066800c0f9f106c48e0cc000c345f095ec430c48c32fcf3a2230401d040c1ec6392c20f09b373f6f5f8f184c36ecd14cf04407851c314aaf23090e3816c2799e24d41b48117b10d26bc1ebc0f5c5314a8f2ce7c30479014270c79627e7cd08d71a5cafbd265ca122c47428f8a042cf000a80683b784840278f174c6cce3712ae10c1a95175ed8442a031c68000f9e636004cc8d4995ab910304264dc8aa7c0c2a940082891639ff620b0c0930a2829167214512d59305d4a9d800174e78651879134d883184a7a5ca87180241075128e0e43a3479000910350b9fe1234de004151f67e18887324cdcc08497711d893064051e7c042b535ea43ce1e33a056084b89d271c572400739041430e5e63c283924106239fedc0438d15de08fd83333c2a2a6aa2f02d67beac41abf0c29d44708df0050b16f02b5130a9c1880788bc8a94595e8304261ce9450501243471c63910cdc05de08a0e7fd2a584264c200081177d41c68925e220c389ced470e4869b1c3c096e07270b8ce1858f2600f1443411c2375880181d3cd57082ff6c808010c4f18305ae01154e5c51039a13dc4836c1cc65c108efe9c00d0fa080c790d3a4d66e882e0bbfe00b03dc2813a5880f81010423527c013d481844620fe8d1c0812c4981104769ba0f2d1ae04511111db78096002f661b08f10a76c4c143842058701e13e08085a33796f84e1020284981dd719105256bbc1a21f0d0040490b141d7c37700600425eca0a1e33a7230233785180db88e021c608610379e3c670d288268c30584e76c500230644fe538ba015356d834f11b2ca6b2448004a5df14b111b1c11983dba83087084a700002fe82c30711e05c89c25f622680a68808d6b88b0d170604504214eeda6df1441ab013b8eb75844d50ad89b776805541f24410de82f58862c464c7591bc8c0136b5838c1596592fc80033480b384b0c0608ae6c241319676590c2b1c1c404e052b601839a8a50d204168910107431a84a4b921f45505766e5d2c5184af08a0040514e078e02b9a15b80700b1c65742277c51f2a307ffd630d930841948f8370136b42461060eff8650b23519f1c23f3217541942c60dfe79e172850f4e49f8c7448b36c41cac7f3dbce814c1f1807b2610634a097e28710f034a413ca00136f7a6085341014258e25e0f443d7007d8c1bd332b40a14651927b62b8ac50822139ee7d31c104213ca8dca3e20606d248d9b9b7e407d7132ad8dce3d14ca0f161cabdb08b0a42ca18c33d9782c50c104bdc49f00309317a38701f230d921305d871ff029b2957f0e29ec5049608634607ee54b08145911cda706fe20164f0e8c47d0825286e7c2b771d685ef8a2729fa1c72b19e1e1ce02540c60b2acdccbf85072021408e13e4297d3070514e1be73e4b0dd10c51d37f40517ae22dc6b54907152821ddc674558808b5c18f70f4a108ad0e4343194c6b9a66fe6ee4e1e1e4912439f949f4f9bad5d4c525ae94fd51bd594d58618fe73f34aa0e1f6e4062ddc2b4107a327554adcbc12361005ec880b508fcc4f1a2713f821c22303001b8ce038c0cd2333471646432870c6ab72c1a9484a4f149e09517e349931208d77828f344cc8a489c22bc34345c4030ad47866ac0d4bd07031f25090438d1230aca01e00cea049d6fcf0f25688319184522b9e0b47c218e240c9140f06285e42217441e3d1b0c3692c41270bef865a55900eb8303c1ed8b00244c5088c3c22e60863030ee8f0c273228d131239a060f0ac20c11b4882e03cf022a0059a1f27ba2a0f8c149ce1e3010f67786e6c21e288ce89303eb10a2b1ad470459a6fc9076832388006a2f840a02167c4026fdcbe17901051c4043aac7c1170322bc2834e5901f142448f122546ab290578c1a305ca6c8506541a9aa372063cc930c2e0052726583d51682e50e28334ac36c4f048a09aa2777fe562abf543d9f2ac17e3ecd32aedd66cb35d2b75f34fe12af96bfad61c7571d3eec6a4aed5f76fe4b6529fdb45eda87076fa421f23ee9ee3ee373e3d7c42164280c14f664139c2dd3d0f244001267e80f1450ceefe79c93d1df1458f352570f78f081f8a70e231451645eeee0dc101047a7a9082e2e6ee1e07327cc902830a3a50e1ee1e0356642ad0810544b8b9fb0780223d0af0810cb4d8c2dd3d032841731d2a84f0e1eeab3646108213483880002370f70f8b120765b070848513b8fbaa8217bc50630036504101776fdd40c31b9e05602998e2ee1e196dc430668e017ca0c8dd411c662e02dcb6080386fb97f8067d89afbbbb77640677271281f727376871b331ce3a8f34a12ff115ba96e6ee42a8c119552fafaaca84aa9b2af7aa2affaa7c55e52a54390b2cb8dfb88dbb9f715fa1ca6daaaa4ca8aa62a1cabdaa6a85aa133c03203cf0bcd048933baedda52f6bb6e5b66c5db1d86def9208d6acd75251da99b95c4cd79b53d4932ca71f57ef266b0e87916030f24b4c4e2959724a91e5cf51559c14894d5a36ebc65b4655715415475a7d6dde542f7b5d6952942c39a1e477a2aa387ca3703d61f23b69184c8ac4e69194f273399bb786e174d541c9e2218f936ff273c624ddf86a4a6b96526de9dfa2e893992c63d9acfc9bb6d7d668fed2b4e791cea3de16674ddc6fbd73f79e7c6bec846b776997f1aee5ad4c66cd9fcb62565cc64de5ae3ae9f7829b16e0ee57dc1decc06d75531b8662d179dcd7e2dc9271282809f9608ce813a3f38b14287a579dfe6b32bdab39adab89742377cd699ba47535c92efb66b3afabc2dd3ff010031a4c7bd2928c49462541b8766dd09b95d4d766b5beedeaa4f36856b382e0e105398ce37864bf09b4eb671bddb8898e9a9ab59a27695692deb6d551dbb5e53de9e74abf0bccfca9376555df9a374ce7f1a6ebeda6eb8dc81bee3be39ba618ef9bae370a7b9d7fea33752f7f2abffea7ff4c85d4160783e9fb5278c3605a9fbb6ea8276f35ebd1c556e7e702e5ee4b56623c5eb9b4df34ab130e43fdc54d51ee4ea99090d0ef9ab7a69d5a88bc3b1d94cb5517b4ffbea5e1b008414c868476dbe69a2bffa6ebed9e30d8ce38973bb5ec7135d7de5633de1a067b9cddf7cce1101e9cee4a7fd7ada9bb2be94479380448e7b1bcbfa9fe89bb87e0a1102afcb7fe2bcbbfad0c87734d467e4e0b913f25b4847c1a49d6222325342743b4a2225a7d2323263f4454abfdd00f91b526444e6aff4542e4d6671612c283bbc7dc5d5f6c37f9a692c6b926779fc241fed24ee1ec54774d72f72858e8f772f7206b0441836ac8c756a39a624a58b264397a52aaa214d5b4b47454a569e9290a8a4629452165c182654bd393d21295a5a826a5a4251a85a4d4c151162c31a5a724a5a8d89312d3962625232a515b94909a94b66851828a5282226d7edcd9e4c424b6f4381b8514b5e57136aa7c11ac59f3dfaff226cd6acbc5766dde504e4c47417ab8fb17da9465292a86b484c5c92906e40cf72f146989ca12929213545094074a514d59908044e08af23779e69fb2dbe26cce012102481021901cdcfdc78782f94295a2625c969e9c1e67a37ed7242af74dd97d53f6bfdfcce1307997cc4ada8b6f252f6e622a6d16772f2a2d2e6d16dbb5f9cb9c653f5496fc5359f297f59fbec44cb61af534dcd964ab51eedee4dd9dc9ef1dedeaf095ba5b6c35ca76edb515f7d9dd85ca2f31f965ddd5dd898c6a7b8bbb8fb6baff342b17775f72b1dd56e39cbb2b49e2eee5b5523f427717bab8c9ddc7a0c761285f4d0940081b511039c8c5b54309a50deec2401537ac983272af0cbe19c0121470971b3c2c8d300a59e36b44e0ac1a58285aa2c600f7a810d70ea008ff704f96e860e7e3ac1a560d58a20113677d6044d20898a8fb8f0b090b1b487197e2428b2d6a80e15e03c8c0e044cb8cbb801c81450f736471d0660133c81630e5ae14b280018438d6784b0b4e8d92c51a7757fd36151ef817022b63970a38714781115560a6a4c1a24dba18038a35ee728205c90394299c65860f330fcd8f7b44f83ca9e056e12b262d7878a1fac1bf29381d1c805be32dddc203a6ec74be9240129a55d593af9c9ca6907440046fe13083064e90c08b7f5128b102ce41c45d28d0204415961ddcb546083954913373ff2288395ef8a183b7841ce940070f4c38d0b559b3be0856ef13ef2a160ec29dedaea66ae62e9ccb4107a378eee2c12b59a2e7f21d1ecb024f87f7520216f96a06f002d7f77ab1c095e7b98f6ff4cf3d2d20079ebb9eb07c47cb73cff3582ca20fe773cff3569f15cf73799fe7ad5a227cdee7b93e0b9e3cafe5b9fcf374c6d5d76af9dc500ffc3e10060ff4bcefc66be3f36c9ce581dfea3d2fcce779df6bcb27e4f3be16f87921f83caff5795a3c1f9eb7fa5e0d60ad5c3a3c0b3caf82d7cad3c1fbbcd6e779df4ae67de08d0dd197e34979792c23ab289eebfbc024ab9beff37e7634f1460093e05059397d0efa178407ae7c40d6e7ad9c45833786e79f8761e89e7ba0f7796a78af0f89e77dacef5b79de124fc87b7939dff77d2d24efc8f7819f37b41a7180bc34f07476827c03f0581f100ff4569e7f4e1fbdf140ff6ccbe9cc7361e53c0df07c0a16dfca6b79a0cbd3f156367cdf0bb6f28c56def781f4cbb1f1f1589ee71a02936030e47d37add7e7f23c98f77d1b58b53c9b0f5c4d793ddfe979ab20cf06e7f35e2eef9bf25df05df01159f9cabd1d5eebfb3c1d305c811f90effbbc9607d63c1b231e0eebf3589e8e2221df920bc7e6f368af1cd7e769f15e9eb7fa3cd0b3e211f99c7c433e9ccff5b1bc95f7791fcee702bd156be50543421f3a3a3d425146868bb212b8285be3e26c878bb31f2ece885c9c39b9389bb938d3b9380b808bb302b83863c2c5191a1767127071c60117676a5c9ca5c0c56a818bb5888b55898b758a8bf58a8bb58b8b9574b16a176b0a2ed6195cac44b8589970b1a2213244489070274890ef0499e23b41b804a9b9fbcb46c78d8e17d0452f392e7af9e1a297222e7a0172d10bcc452f4a2e7a6972d18b072e7aa9b9e885ca452f29b8e8e50517bd10c0452f45b8e8050acfd90152e53b4074be03a405df013283ef00e9c1778024e1ee3a383b3b7038e3210e34788803101ee280000f7170000e5e7888431a0f7108818739b88739ec789843110f7320f230072477b7e0a54347c7cd6b473cc377c414f8ce8e10dfd929e23b3b3fbeb353e43b3b567c67678befecd07c67e7face4e09beb3d382efece0e03b3b41f8cece12beb32385efec2cc077762010eee84143141ed2e0000f69c88087348ce1210d6b7848031c1ed6c0f2b0061e1ed650c4c31a843cace1098e0d8f9d1c23dfc9a9e23b394fbe93637d2727fb4e8e19dfc91980efe420b1c3fdc78d0e1e54f4e10a226a4972510b948b5a4c17b59871518b005cd4a2838b5a9a70518b025cd4420117b594e1a296375c7ceae1e213918b4f4a2e3e7171f1e9baf884828b4f33b8f834848b4f50b8f874858b4f5db8f8f4858b4f1e70f129042e42b180fca88085325c64210e175bd871b105212eb630e4ee366278d3bac9e942878b5dfc70b18b222e7641e46217555ceca28b8b5d8071b10b9b8b5d8871b18b115cece28c8b5d04c0c52e04e062173ab8d8c5102e76f1848b5d38c0dd71c257053b3b3a628e4e8886150fd180f2100dd24334b68768a0e0211a347888c60e1ea2818487683ce1211a5a788806181ea231020fd158e3611a403c4c63030fd328f2308d240fd370f2308d99876988f1300d321ea6c1828769d8e0611a41789846123737e08e1cf10411b87842095c3c01052e9671b95886878b658ab85826c8c532442e963172b10c928b659e5c2c535d2c835d2ca373b14c1917cbb4e0621902b858c687968f17a8f0f0050778f8c2161ebe90c6c317d670771d3d6e76585e7c8765f31d96f61d16007c872583efb076f01d16112f177a78e802110f5df0f1d085200f5d60e212b7b8e2e216d5c52d762e6e11838b5bd8e0e21641b8b845133a3737ad1c7104352e8e00878b633e17c7ec70718c0f17c7f0b83806c8c5314d5c1c93e4e2982617c740b938c68b8b63662e8e315d1c73bae3d8bc76a060e03b5090f80e1426be0325e63b503af01d285b7c070a18df81f2ee9ec3c383c4a07818b3e261ac8b87b1301ec600e061ac079b1cb101402e3680898b0d90e26203aab8d8002d2e36008cbbbf5eee363a44295070510a175c9462002e4a510017a510c245299670518a2a5c94620b77efe13f2a403dac00918715e8c0c30ad05e2b8400063a81266a8490a8d2dc3059c08f9a963339f8f0717777cd016483bbfb8e009039e3ee3e840511d2ac59f317ffd7644a5e15544c910029bc6789300ad77934cd271100841705029e78e2092928b2701b28c078d0dbbc83b874a1a3edce92b22c3d2939c994aac49eb24441c9a2b06c8951514a82c1727a0645df56a5ee792369f974dcd12815a48d9bcad7fdfda7ba6bd2efba93cadfb8a98673c58271d4a6fa7d3152598f5c8c15039c711f67abf9960bd25e020c50827b5036cd7a84136fb048276208aa4eff547070e215549af646864d04e167d0d6b5f6fba4d9bc77accab479e8ee3226d494f8dec0040c486552f91b731162d49a56690d676ca7eaed69f4379eda3a67fe6dfcd9d17cca5c6b146baae968bb16db2ea6e34dd75b8c8eb7df980bc6517a772b1314b08912403ce58b60931841120a4802091f7f7ce88f0fd57d936f20092cf507210f930091c000121170172a4205891328d535a764c9d2eb5a0ddb5e23f1b27da6478441614fd69c3ec201eef4c17ca1528228982ff4733bbce9085ccd1141c4d027f74d992c4a141a8587de376532234e30a274f73781a8b6541bf1b9eb46fd9a6a7be2923eade633661bffbea675679a95ea53dfbfaff18da4f9c45ee8a8f5b96baeb95c4582a4eafe888e9a8a036d8b10f1fa4244263384156f8c33caef04429c719caeba7de456a41b1d6d9646f1aeb67c1cce527de44d5a8dca475493d8bc5f969696718d6a4bafc566ad7c3deafcfb7135d71cdddd8ad35b6c43667dadaf7d7dca64667d0dd31ac774e44869beadd1bf6d5cc6356d561a366db47c6d29dd991796c3597a71d67d6eb7ebc5b7f699ea2bdd6133f7a5ae369dc7cf35f7390783e9f0b087325f62a4f16963a67f23a9e829e69f70ed2ee174d5c1606f9e2566c2e9dac5490b1e8c0c50001378a9c10ca7ae9fb7b7410188dc33093b5c2067964a36ab754f5599469df1262b95aa6449794f9a3f77a464c9eea5663f3f148802f9f8d4f006944867d6b2acf4568ac9f29bb45963b849f754308eca5fe62cb52cfbcca2df66bceb52fef23e958d9b1e67a374180bc6510b88000e2f57c2d96a22c51e57c93f0af34fbba5376d0d0349e58abb91f78fe898df29a9ee9a34669cb33b7fee5a264a55cdaa318e665cabb4fc769c5d3ba3aa4c33fd3a6ce6cfe54e6a566cbf466d75df27f3e7e8ae4ed726e56878d35dae96b4b5bf4fc3367f8eeeaa3992d534fff6b7a829c6f2cbdfd18d6f4977369374fcb2e234dd35d1ec74972ed6f59fee16a47f7a2a4e4e9fcf5d719f9d76d54ae9706c9a066848a26599818c7a8ae12242d10c4453ae8305dcbd04016cffa41040e841210313ee3a94e18cbb8fe6b87ba90de8ac5cfa2b33fab7dd4b5d1dae7a26bb78762373fd6bf5a92dad371d2d77eea57e4aef5e4a1fd15d5e53dbadb79bdda4c5e18bc937f3974bbfab25b1d631dcb4fb2b7af75770d391f085ecb69b6f32a7e285efbe08f83315aa2fef520070eeeec2085c9861bc27ce9d52189bf46f51b18d9bf25f5d968d9b5e6fb94b1b37edfbb7e2f23bf5f0705a00c2dd6b184f27ca9701c0177a9f4f28d3ac485a7f2ecb98cbe1b3f37d2e2fa80a095fc28211cf8a15b058817a73783f4c48e107ef042e0498c0a4822f881745dc9dc943326276e009cfa8f11d15ceb91d6766d079a491e0eebbbf62cbb12b4e001881cee3eea58478f67ddcc50e819cced92d02a0072e4fed1545e1a6b5091d200510dc69d50be241e122582d82d594fe94dd41543b482827a3da55a6fbfb39056688c0e9aa23c778688647ccc657f7170663b2b979f2b4f1cdb3c43819add63ee746f2a97eeabe8c6a07bd2dd71b12aedd258d9d6edb76c93867a5ac24954529eae97fe3a9d2c432b36a5bca64af710ee7dc3d339695b9eaea2edb1cd5cb76b2d28410689bd54964b25c95e92a339fbc95a495517e69a768eefec3dde570f72cee1dc0ddbdf2e9cebc5d4ba38672756b9cddbb97ca670e67ab49fee75afeda8bf09f6bdae284486d7125249570848434db0b220c770aa871b754ee4454b80709c15d47c8033d9c2f4410a3830d170fc7784182061437e93c925fe26bf3f642afc7aec434fd4487cda751d9b57a6b6c45ffb53b87fb6b83e89fd7ee8b49fa64b773b820bacbfb3ecd616cd28bddc930c3dd87689428b403236cd179cc7fef99938c433058fefd391725ca58335fbb7b30fc7801f40260d2ea3e71ee9e0b345a4b0884225819afcd591d9a703747a5b82a76402cb14b9231fdfc53621c257d28addc36eb38e04e3ca4327f9f544b5419bc08f65a9c2e8cddb6a6d54de1ee473cd4cd4033aee9a0cf3937743aa478380543fe6b71e114964c472ae114f8fbcce130199e599c30c0f699dbe76ddbf0c41285d2b1fc6c4f3164a5b5b367cf41cb3769f53ea53b8c4dc5487321ec5b19f43947a376583fb35208676148c9994217a1612029108549a114262b479ba5e9253da4fc325752db9202510e804c327320cc298cb66b6fba9a9a0295f7c435aaf3088389a180bb0f7928c6875dcde69fa278973785c9caf277ae1bca842abf0c736ae8d717e7f4677a6d7e27aaca14f526ad72b15daaca346afa5275eff6b5414f5e0ca4f7f91b4f51dbddbba0fc4e6599abee88eaa7af51f356fb7c5e5b6d957ea678c360b32ff4fe943e546f186cf685d69668d55495a96add5fa02cbabf663dc53ccd585baaef53d9d6274e464fbc3be98977b4b644476db505ba4b74d457874baa3759f359526d6fa5c553555345e5bf96e969d44772b8dffb75ae9a4f3513ba757db33e0e88c99b395ca5aa7f8b2a4d7cd39f6f514723544ffebd9fd64375bdb6f6e514ce395c7d5d6f495f947136a3d54ed1fd1a898e6fd2acae5f2be9d36cddfbc891fc37f235dd996625ed2d57b30defdc2e93b4ee23f7c926bf56ab3463bac9cfe19b5f9f41789f95de5cc5ed5e0af61b5f4a85755174bcf8a4b66bdfb4371d9de959141df5dd42c75d29ce34cb5bc35f31b9ab398a3f1f79dd6f7b8ad15074ac7457d376ada6f5efec5a3a9b7d9efd0001f9cc806274fcfcb7b2fed677898e3a6c6a9bab4c3aff14a6dbeeaae9cecce1acde96026d5d73f4c97e4dcbaf541fd9f5b681663f3ef7cd71465f9ffb48173a0e01dd2c74dcf5c949abb634f7a4b65d8bc39b3e8de24df5e53df1d3ec0bd5968299cdbee89d79b3bc2dd75d7eb6fa934cb392b4bc95a4e3c5b9f3fc530c05ca1848cf28ae7ede3a77d25be9aeff64263f3f8eb45be36babb6a4362013e34d6b65d097e6597b7de65fa23b3357a52eb68bb354fd2e9f9d4cf3a4f2e79f5a9276d569e37b2b92d67fb7ed72234f268ca3a06a56b25d9cbb986645d2911bdf74ae5e28dbb55a5b268ba39de5ebb069c6366e32cd4a6586048ed27d9502c0c26cc954107931ed6ec9556762ec443ba1f643e5306eca65d16fe2271363a7fcf72e99183b955fe6aafba7ff4ca5bcf82848489b18e7645756c4dd7375e3ab7154b9a4dfc64c249d5faa6e285db352b984a3cad7b5cf4eba66a55a96adef92be18a966a5bb74d3d584cab896e5499b9d70bf9732a6a243305f5c6b96f54b0a547ea61bd3fc5219ebb014894da120770ff2108c096688decf61301f086c80c001770aabbb96753f8e0251204f05af052077cf04ad71eeca721aea6302fb86dcdd8b8720d8b8eb208d735748ef70b833a944dafd95fdfa9f742e577550faa9fcb2fc1975cd5220f2b9d0f281cafad98c6ddca4f56fcc0587f7ad3727d94fe92a1ba01ce10708f88008779fe2432fb696eed8aec4347acf1a0dbab8c9abc20f2c70f29e3526e3505090c5e9aafbf1d9ed1cee65da8e5264dde3a62af5e36a9396959fe57118aac4b88a69c6ca9fb24ffe53e885ee6836363637e5d32ff46f5136363637509cb68c5a9b39a08c6bdb6aac6b19db9c8b518fc9582bd578974b5c6652a432d6ed6f2abfbc273e82f2a7989acb923f97abb9cb8ce27ddb676c46cb5bebeb2850c654e858e9eb59fe5d8bcd3e9f24599fa65fe3dba6ba52a0197eda54df34fb5d7176eba75a7fb6e19cab74bf8de24d4d5b6bb4a4ed72d5fac98d2fcdbfab49ffb6819e3c4b9c73b6ea28ad5fdad22c4b8bdb9937db896ba7d5f47537b2daaebdd7da3e46475aded7146f2a85a93eb22dbd91f6a6a3f9776df757ac94bf2b69cddc9984e361d400a27451d89dc27c288551dbb54f140c857d110a1acb2fff2f7d1add55dcd66798b2d2181defeea5e8678cd3b66b6fae5dbec44d4bb67a0475a604a81c42dda066545bdd5f0a446d9546f1be96525a3e982f3487180aa0868271f75a70f758f054f0ce3ccde1ee545b2cda568fe8135ba595b6746f044f51dc7d2c5f0c1d6d954677556756baf589bb3f656d5b5baaff12d37490b6559ab6260cb6b53565da5669b2500b07dcb4b5b4f8a6a395da2e696dd8a4ee4ee5a11610f49f5adb1bf99beefababe99a34fee3fedf33965f5fdda97b4326182d5d21264ccb852a730ac1494131a77ff1a7d6262ca389c530e7ed3678e3e313189c185061e308ef93535eb7971497514e3306ed76ca92dd04c8ad109857c2e359cb1a69feb0e67b159ebef9a1f775e253a6e6c6afa38bb6979ad548c8e7a679cfbbc7b29aacb8cc9cf949626bee593ee72c5d99cb35d6bd66a1836654f310f7b5aa555006480bb931e4a796ac279c8e484dbd8d8dc8c363636373f423a484893b80cbab6e284b01d474de2524808a6737bdf7cc0e82f1487b73e916c6c6c6e64b251976f9a1569772b13c6519576ea5dce2c31ce44da412643132770318be2b5a23796c0506584a2260f9dc8b0883263de00983061019fa6ffbc946f9af68aee9bcadfb5cc6df9122369fd2479425dc9c07dec000519e7acb4e4610740b8fbb8a3d1a7d15b499a3f47f7ad36d729fa1723996645723262020535da4ab754c551bc69fe32637aed896995eaf095da965eaceb3fd191fc9cae26f925ddedfc399c73b467575cc6548c9868dd435633f7595b6ac4040a8a96bfebb559fde5a88fecaf426949e34be1a96be9ad24d575d712df74b5b275b6b5adbf34b10fcdfd4be128131d7127ce5255dca8b5ae340ad31ad02b7ca4175bfab7d9e7dbc6b5bb14dbf8d29aa53fa50f7d6d562a749c295972cea8b67436a3bbde36c59a96678ea263f9f773b97aa3e7d6b586e96c369b7dc61b8a8e5b63933e0d47f579db369bcd9b3e8d9aa6d5515bb31b5f8aa9feee8bc99abd7fdb74f6faa4afa3354b5f9f957c1a9dfd507d79978060b0289f19fddc6ed37adbfaf36f6bdec8fdb51ac6694b6dd74a9135efb77953fdb6fb536f5a930cda379b35a9d661d3ac54db5b141df17d129bf46d95b45bdb6b71f9f797a6190b578765b8fa5bb65fcb642fc3e5a9c5ec828725b744312110438628a614f3843940613f35a5bf335e1f10718ebb2ba1484a13e72a798af95246fe9490f65ef8bce4bc38e2fe49e02ab96f8b532a31d2d23be17e5b3a56303318ac66fe43d1516b4bf749a3d79eb65cb1e05dee44a8e498b3b129af54cd6fbb18cbb63636f8a62b6f2d1f77dad0efa269362a574ab1aeafabcddbb4b5963bf5b6f6da6de96c47abd1ad31d216b6eadd54fddb94121dcb92ea4a6b56a73f8916d1389395de1387c364d54d615aa51b5f3a96bb343fef4c2b423569f9fbcdba2b2d2fd171091de9a8848e48744c4261356c4d13933f4f5e7c295069653e375d6f96becd9b522448487bf1c617e39020a1556fa01d8dfe6d9bf55a9bb555b35631cd8a83aad5cea37de66e3bf749a65962a42f31924e2aa3f69bf6d625632afbccdd25a827d2e67094d2b5f586849b4cf3a4929431d25d2aa38ca84431d94eda27956fef273d796bdef7cf7aa352da1667b1ecfc53ff7497c6a0cf3224d76314121a4537a0982ee1ad31be91b4ac345a4fa09d69c713ef6805dae7111d3d8831c1604d929cf5f3b64d929c545b1caed666651d957c316eaba9d051ef74c6f93fd0549569e3a6376975e7f26fe4894dd36ea81d15cee52795d7e20e76a619d37d13aedc0ff5e6f9a4fba62e11e8c2c4c58d25d3ac485495699c5155a6d99b38e7cf69aaca649ab111cbd3165aa919baba6bb6d18bafc6fd97678ddedf516aa3f8a6fbdc6ee39deddff47d1cddddfae689f74f05fdc5d4acb67e50fedcb9f357f26be69969d2121285a2e2b4b4dfcbc64d3bd37cb25d5b2ad55d7395ab63e56f6db16cdca471bf97ccbcc5767f5b4dfb2ee58dedaa99d336a9c4b84a979bae56dea455bc9fcbc64db17a64bbf6fe94adb27153d393ce4f83884e1470c2c2c90ad1e9004e41884e40388d426140b4e695e194e41fbeaec99f326d4def6b6b5632eb59da29bba54cfa7878728011b35bf29e98fee2268c9f9c3c3756529e54053c046207aba52786942859a2ab4fe512d59757ebc72200bcdf5e5bde4ad3b67cf3dcf771b7caaec56176a65965bfebd49bffa4ddf8caf67d9ceca7acedb3dd52a4952acb2ad32736cfdc99497dcfb26233777e8949d3aca4aee5ef1b79e2299cade50b097959f0c690103b7811820086b20c93c8c8156478f192c6dd573a579c33775f5d40e5f396086854a102549859d02447142d2531a85a491c54dd88415e8460c498c921012bb45c85850e0cee5e1099fb1702980f0423d18a189d472128f2a764e5c3609f3129cb69a95c10ee06d5f29458850cf7efcb0b5e9a0fbc78f075f9b8b8fbce7a678854ae70779dc71c2e7285ea8b4d133b5524291263d9d6cc4195b996b76ea8df780a069371d992a4757512937444241744a4a224aaca34eeee9333faaff3efccfc5398de4a81b0366374acd5b08931d2182445d61cb575a5328e3b73df273fd37aa3d5762d05caddaac36128bc2feec4587e632ea369ebbe4f75b6625e5ff3ac690d54c33be3dbd36af8b18c6535ebcfaee17d1fb7c97a95c68a4dbcabfaa7ccd7b8bfed29bccdbdad492b7ddad20446f3d4a6b9edcfb63e7a8ae21cce4e4e331a4433a64f6633255dbb945b572c331a4461fb7158b775f97febb67fd3edcc52b7b3d570c6a4d604a81a233f7931b9b48fdc99121d69f7a4f71655ab54a540f43fd7be56f5eea528d0d7ea54141def163afef8e830962326282bb8a97cbc9f0beefc8b9b366ec24ddf943f97db62bb387779d24ea5d04b551a853d65797a52a2484b55b260d1e57d9ba938e1b5c0840c77a7957a669830e1f92032a1721f77884ca08ca5a5e9884473e0fcb9dc8fb8484445d21a221094b84844dd475bcee0640cdee2c5c50d606711387c8002359ec64712fb16a21206f82c6a466b67eee24e5d6ad3d6fd49356f2a25b39a6f052a3feed41723e576aff5934acf830ae28fa954774dc2b51b8583192949a2c3d72693ddf6cbf096555d92ffb6aaf5e364b693f6a59192244a5eaa9a34a94a922fd584891299927ad3b29baeb7276f95edd732bc652ffb8bb7a6e1f0d6e1f2b36cd7de94e96afbafc9f096ed9bcdbeae6299b632d9d5e19bae3799b6d9acaff799bbf677ddd56ed3ac3625667d9dc4acab28442053e7f149f9629ee81367b2e2e80cccd47dd99722b39b9cfe9d619f7341bb52b6db7667cc24139150e12fdb6d9b71988a93c9b6ae35b3de8cf74fe1cedfd5f6e697f7d45b5b538aac264de6791f8ffbb883e0e29137968c4a928c4341578733eda6ebcd027b3582149aaba44cf7d71b722f26664085bb5746ce4a337a8f84a399eb538ca340206ac085fb78b1d5a7495ebb6ded4247ba2bdd57d4c0080d78a074a741d5b559adc1cc5dd4c0c8dd450d76dc8dc62441e44f9966c569318359064614c8dd5b2e66e043cc20c7c81cee0e44a94a0ba39534e3702e178d84e114a6716f7ef95f9ad8caae8fcb8fcb1fa5fb262e195f9bee9e99aa32514d475cfea8f14b4caf05c2f94530cd9a7ba99adba273a76cc4fbc7a7bcf8c876edc65c46fd1b4f9176df6ab3365a77b4ba77ddd5f2e223a47147ea237f73a73e127480714675a54a546250b9f33449aaa740e5c5e443d1b1e24ead2bdd99db92f76f2533a6650efa916dfd3459c5b92d74fcd9da874add9a736790a634466177898ee5ffc65c70d3ee5626fd1b73d1612cd509476dc9475b9f4cb92d4f4875d7a4df98cbb54fe2902cc4214cb88f60be50994c1c8254fe99b740fd99a5b4d5a9441282852b45e97ded587e06434eee9b95866daef7494da1e89804a6ab619db18e3ead029d5a5bd95012ba35c6d1bd8792e0bda3d53069f7e36edbe659fe9959f5adb3fb393ca3b7da5d7310de417a2c2d3d62620c4ad9f2a76cfeb2b4d45a4b8fc44cb3e69f52a29d9afe8d02d5dc89b38ddec8aa44c7dc897395af3d0e9354dbfa64cdbafc396cea2fcf7b8e26c63d8fab3629dd436bf8cc659c4d8c73380cde26363176c251da76b1f9473bd33ca9ec6e0c1f4969fbb471d3c64db66b77386ffd49394bdeb8e97e2ecbc64d5a5355a6b7dd7a2bd24f552b1b37e9c7494a493b53eb37f33b55bb7375422abf2c632355652233fe146e5756243a8e74e3a6b734729ce9f09dcd92d00da89e0599f54baa93222b8db630eaba504d9d5edf6cd60ac651e597a749be49de2d4f92a73e731aa8fcfc3977d7f1c8f880eb74eeaee4ee11f1395ac3f4f5e7b28cd9ae2d317995caa5fcef4413738c728af889ffe29c9576db9af5d4a2c3587ed7a412e32a5787ef953769758b8e5155266d2bcf0ea82ad3c576d7a76d71164b69bea50283ed70ed2e5dc0bde8b1637f3ee428815781cf480aa23802538457c3cd8a1e2b7820031e2b42308128f643957fe57629bffc9c549a59ca2f6d75aa59497c69e1ee321955c56da1aa4cf9a576b72ad1f1a7ea0dcc175a67b66b67d91ac95ffba4fb53dbde13d37d62a09d59b37488e20db4a3d15d6ff868fc9a95f23be951876f9ace76eeccb42ab35d4b9ee5e719fd4a9f6649a819f95cca9ffd6c9631ae6adbadfdbe35d7d336bbeddc97b2202a85cec61f97aaf9e54ccbca1ff3dbcac70235a34033aa2fcdba7194ded7c2664034887e99594c858e3b7aed98f1e7988c3f3324549569e6437f664832a632f3a1fabeeeefd03834164d69bbefefcc7a2bb5edda7246e2fbd987eadca969add5309899ee2f0c96df566f6522ef4ed36b75a59d9896b6e66ee489d3959ae6ebea4d3fd151df9ad374ac396ffd379bbdd5fc407a06863e91d9ae7dd9971985697d32d18262f59e3f3e54e34e325bb2ccb8ee68b4ea6ebaceccf2d65b26f363a6a1a1da121d1f97bb7de4d6ac54f3436121fba3675787674d3e74d4d966697496df29e3a81998d9ec4b352dce6a3ae6af2d95745baa976efabef92595324f1ad561d3dcd12ad53847a544c719989a95806810ad59e9cb8ce6ff817dcd4f6756a29c9492645e9eb244412d59998d60661a067bb2d6f2ef2ff9e9583e59f3e7ba2d05ca785b0da5c337a09a9f966fd6fc3b303318cc342bd2eccbce2c7f77ebcedcba62a1637e5cc6545b186c46afc59f31131d731547b59dfdf88c3f3e7af75230d8cc9a399ceeb30dfa4c77401bdf5aed4b4ccb16e86737dbbd946c36f536efcfda666b3fd75c5a3033aafab76dd26ad0c537577137bd3381b22df76b8bc3e4c89cfb795abdb7ea7cae74a16399abed33c5b56b7be84ff9a70fbe14a8b65471b61587c3e4d32ea6e99e1e5abe6956bdff6efda4cd5b7fa6f9c4359d0f35eb8d3e79f3e77ea7ebd3cf47767fdb9a92cf65898e527467d22c494bbdbb313ae2ecc524d5fbd69c1d6fba6ea88d9b8eb2ad4e171fe9cf98093749ddf386244562f36ec14d547054cd4ab52ce58d416ddc74dbb94fdae95b7350b66b97be1e95f5c834ed0d496ba41da2c13ae38d6b29d57f061a7a4655d6569f0175869433a09861821faa2d50f93ef43735a30a3372a035bf19db8c29666c60061133723405d259e3dca5b4fc0d822940d082ebf0a59a4661b319bd5689cb1254931215a5a4b17e2e57631778088271acf9a16a7ed96b58195a5051861265cc8037fda1d7d26b6906e60f0fcb3075191c543347a3902187b364cc408600dc69143214400d05f3e5068b6fc903bed50616a020021068a08a3044f02b7a946002d896d21381980fc75c838b18b450830b2118101ae2bd207073772c4b3bb2da1e8bf6606e029dc7a0a08b4d0fc5f02f314e3ffed24e6d2757e3815b7805b4d8c0e3e113f0882ef00037c3cbc019303ace4330a090dd6ae66460fc70778f7a4b55996a98aa32d1c7d9a8f167b773b8af9bce481a4493cc7ce88c9cd16dbfd27476cae66d5a5aa5e1a7291dc58eea789652a4cd34ac292e631ae776e6d6d5047a9cdd77fc793d9b51bc4fbcf301ba38bf083b6d6f7f6aa1e3c5f4d637cb5b6bdef7b7a53a6c858eb9936e7c81a4347dda8d7cf25a283afee84cc378d3abebf8a3f5a1e553d91ad5554777399cf73531ee326b4a12d434a33b13a87c2dbb78f69a6afb43e5890bad741fb9b8f431cd1cdde55a5e4cbea65abf794ffaa479e6708e3e4ddbfb9f3f476b96ce1e87a16654ffec72cd3887fb283aeeaa14b6fdbeb6cea066411e64e91245c7d9d08ce27dab69d68bf5dfc8faf966a1e3cc4a549526252cb2a82625a62a4a50b2a62c4b51485b9ea2a09ab220c99e94929ab6e44e5ac3d706e52fefd9656b5babe1a02f6bdeb4d297aab88b2d6d22eb7daaad3573b94a475dbea9c3572ae85a4c06557a234f4df56b9ccb676e97abce3f55566d2b694dda99a3fa27e862fadabced97b2a60fd5f6b3aed476b1997fea75f84681b48949bc71ced16bbdc49870f937dd19dfb43eb125ad5971b492f74fb376aded5a9386ab369a712d2a4b138d82dac274920f458bd01109926cda7d4f3a54feced479d7abcbf2c5f01d61e9cc34add48c664c672f55f7ec46e29cd24780717fadea9bae99a4444d4e5ab3f4c95f4cd4e4bc9138f72ba92caa9800cf6c637363535fa5a7d5239d475aa5790165bc56e8d20c6e0850e1ae67d44966bb7647d6d296b792b227ef89efe729d997b25bdf24711859696526c639d9ef3771969517d3eac5b4f24f99aee6f2b6adeeff7f5773b2fd78bfb63299aef965f8ea376935ff35cfa96b65fbb5ace697e9fecacacff96b5fcaca8b699f6fba6e2dcbd5cf52a495d2329969da1b89c3a4ec5a9c6c67e672350246221024022fba7ba9f2a730131721e0228b17c1227151e5eeb66bafc597c2fe9e19c685c94554adbe49f16ee2a2888b0cdc9dee5e6a579aeb9b483a8f19870bb798dac26e11e5f4a6eb4db6efe79aa354e31c85edd7b98a93d9aebd67ce651caeac32fd26794fd97e9dc5e97ea58d33677c60c226c783591a16a248410a6e3e8454d0c3bae361a51ed6261e56260f2b081e56ec612de36125808795080feb023cac1c0022a651e4621a486980e0621a615c4c63bbfb4db86347f8c4ccc327c278f804091e3e0183874f14c0c3278cf0f0890478f8c21a1e3e8185874f7ce1e1136578f884093c3c802706c1710de1808b43d47071c81a1789ec7091088f8b4490b84824c945224f2e1209c14522d8452227b848c4051789e4e02211215c249200178960e1229108ecd0218e61c6c5316470718c1c5c1c430817d30071710c03b83846152e8e81c5cb25fee02efef072f1071e2efed0e3e20f485cfca1c8c51facb8f8c316177fa8fd70baf80309eeae73a4021dae1c20e2ceccc51d9c8b3b542eee14c0c51d225cdca9c2c51d0ab8b8f301177748e0e20e1c2ef270177954e0220f1e17798c2ef280b9c8e38a8b3c40709107ce451e23b8c86306177900e1220f285ce491051031bce262287331a472771d56887cc7ca91ef5861f21d2b5c7cc74ae93b56c4b8bb8ef08b91875fa878f8258bbbf31095d81e2a01000f95b8c143258cf05009273c54e20a0f959880874a6cc04325d2f0500939dcfd95138a3aca7051c7085cdce1b9b843c7c51d405cdca1818b3b9ab8bb053f441cb68b38ace0220e3bb88803142ee2e0007767f9d849dabe93b4f39d24169272707642f0c07742a8be1302ce7742d0f94e0825f84e082af84e0835f84e083cf84e0840f84e0848f84e0850dcd8bc5ca22836b9808b4dca70b189085c6c22878b45372e16edb85854c4c5a220178b602e165d71b10804178b6e2e16e55c2c1ac1c5a2165c2c22808b453fb858a4848b450a70b188022e167dc0c522365c34f27604a8c4a804f06da5999a744c213333321009000000931200304024180bc70312c16c9e86ab0314800372a67290521d8aa32849415219c20c0100000000000020981a02a5295a29c7c8d19282f33e01009b2b0265b1c6599152c7f19b177053c43555c0be14b1bf9c5fad8f1a6dea9b6020874aa802915f6811ad2cc131fe698eb2978a280d50a1ef92c4c70a46efe9525d1ac4e81034e235d5337003df3edf50b9ecdfb7fc52a17fd7f4086af45247e6af2f529cfe8e3149cd0db26bd903b6e488f4226b19e01250a3e9a2110a17132954b2729741f1642cb47251420a7add4522169a8e46a998080f4d3c70dbf53a0f36dd9ed1c8f0df14b9ebe397d2791b889d13924dd5ccfa3023e766edd6e5f676fa397900b4def30b070fc2477525eed178d3873c083c285cff25a8309d66ea8a70a0cda27360f908165e7a25aea728e39205ebc3182a9f66d740cdc774053a8fc169e04bd9730ba7ae045646414bb46fa4aab1c482844d99f544e36a4259f867339763fe05898bb9a20a5658329e25a8d15c75f9d01add8f8653879714a8aad6362c8b67c86edf38147d9b817573d83271a1192d830a836cba0e6fdba0230b64a236790111a66f81a5c10025160bf3b1c71baafe84642c27f24d5aa5b18e4a0d42349f848a78a8c5202d01ccbbc8193300d990b5dc5ef3a30dc7d2f8c94a8fb15806e435a5310fe768b2f226898bc334e1510b7a2d8832e01c3ad6a8577600183ffc3dc1aea0c6f80a6ea843ac6c2739af045a022eb631c4714cee200558fa4f71291f4ddc0f7c327e2b8899b4e1cdb3329b898df6cd3ab645eba7a92d95ec51ede37df57e99b801ed5c31978614f484bdf085cf2f9379c6af1120197c6cb5b66bd50fa4cc28e8bc48e48d19411a1545469298215a4902f6e8280b71a16f6ca743e3034371caff99d6ba142902ea7ea1086f52c049b0fc08ee310b25951c59f3b14f485ccc16fa5ff90fd808deeb3a1a08e59eac455db4ab051a1e400c887887a0bfb39a36a4e01da402a3c3a68f6a2efb681b4cecb44ec43a9ebffccc0595e83e47958328886dd0ee15aacd5d04cdba3deaab3a039a5dc52f0f519ce93515b2dc2513e911cc68f85a50fbc8fbb01215320a1f629f5a82146128b840010e72d8235bf803c66df8c2769a9b6728b807c3c830ccbce0954bc0b7a6c81a5479db1e6b6a1c1ab2054f8ddc9786ef7c608c6aac64feca2dc8299441eac3ec4006dee5b87a887605520c18f44abb9208536d5ff3a004775f8087e46a35398e9c9bd99239b8dd985493b305d7bc1dfc36a84680bb83712ea93ac6e77dc19b02843dc5658d2a48c3656cdee3e633a8652e69e51d218c104c913ba5229253f3b5f86fe348a62ac219d79ee8eb07221073e3671eb8a0e38b5b1be86b644f52ea8aede9db96da275c18687ce2625a8eaca81e37b2c1ea06d007a0eb32feb6e9ee7fa8ca87d8a12286ba76c42793dcb7842e72b0161d36b22fad1f79c893a5cfee9a3e5bdf39de13c96632e5a4dfa92d310fe400b42884e1bf8bc7d66877da31a00477e4e039009220603780f1dde98ee7f890819d0022e88a8ae4203cc01a21c1e19541288e058e01e7a016e78c7dd60600bce0e888096c3a436ff7ebe513b3f3a7cb90bd6b244751329e56b5e45f5930781b959a41239a2796118cb91708a260dafb8158d5bc416e3d8ad1a2e8eb9a4695851d5583db437d32eea0098e4efff1c8538d7b75b7b179ec8909901f5c4bd627463240404c14ac09ebb49dfa20f840094e90038886fcde1a7fcc3dc8ba721a727db6f1d62f32803a81673d13991381179cc736790a9155f57f35e2266486d9f7b1bca38de118a5c8eb9098f3c9de038e6af2da766307d48efae1b6e13f86d6ab2585d86dc3276cc781c28cf08a2ec7501620d10b0e2bd1bda1f7c9ec93531806e46d096a4521a3ef7fb00b084a6549150e5f2463db5db0e6da1a1c2d439b35f1c7b7062be2c5a844adeace61be787c05ebca890a291224cf00fbb807edcb6cb25f99ee38d82d40af621a3611f1685c7b2af18bb111591b4158ef6f0f334cb1e205439a8a88f00483b1421695df54f7fe4cb310dbc651faf56b3c6089113f87bc71e8011b0eb24cfeaa13e71c87319ac45469861e8ef0c66dd44eba1cdf368ef2a4a7fb53fee63260d5f839034786a9388b3d635b10174966d94df2d14686954b5e877c1bc53e2f96db90f8712979933cd632179ffc90b229d0bea9c5472297da974a00976f8de68b1da90c550fa7f98ae401e0ad26dfc0612ffaa83cd97de3432c98f8e8840dacedcd49d146b2de82944d8bb8ba11a581bc28573335f946148b0fd5aa7bb9162d183911dadefa20fdbb894b5578203e7524ca6d1869e0296931f0cce558f1431c54de2ce131f31149e4445db510120612a2a2ff227d3811547ca8f1aa21936d55b39b3ce73b42347802869f2287c36e9bd5e58c0b13e5473b2f08361a2e82357501170d42d7b3ad97a92ccde36342c70b4b442b8d351931650afa7340eb4088a34907604de457bc0bd4e77e585d152591cf9b366dc3dd46ba6b64777e2fdfc3e35e71e1b7cecf0730156c9c5c9ab70412c47c1be40be0da9e5dd53f4e357538d3d62570ada641da09a5f071f27c4aa9ee8f295d61b1aa2025a69a62468270ceb18b6def77924bdd6e97ee68d29cddea60a01cf9f529e77fa3498499ccc9dc7059a0bfa99d54fbb93fd9316266891df4f2429432624cb5530787f41792c433c1f2100fa8165b49d4ae8fe60fde9ed641140538a16078310cd2bfc96f5447273741d92b0eba157fccc94a8c22483acc34d222f5df2324e2dea7fb0367e354e8d76565969d2cb84dc91aee3a58d28ecdba617dddd6fe34f64deb4455192ec92b02fc8d757f90caed2538567840a37ab042fd0f91d221e0c22ee41025aa123f5a0a6703855edf03e4ec821f2a06ad04872b03046f0edc776d0035040448dcc7f29277cbb9ad186731b0ef6556859b9da7b5ae7651af672ec568a241597883a16f9a553d031a5426d87534edd71fc0d8c1de4be2c5630cb4781a1f40c770a345bc2e9d3cd23cc154028cf0f34efb0e84beebae9ff904d60ef88098bb49138caf8d30e15e2e8cbf035939a9ca1c1607bb793ad8efb3221f86c5a0e80f85e9ce1b5b36f69acfcb5890cee7b7043de4cd954f378b5c218a1a5cbd28585f7f7b527d303f92c92a5e2b7ca3496ff9cd2fa7fe91b3db65acdcc4df634e483fd35507818e0848bf0c69dde68d580e176f59aa23de20f1021f2eede580327e2963e955e0b57ee1b1bdf42cd74bba8149927cc17d43a69e12d0ae8ae63b550780397835ddaa317434d1eb604918909ad781231636d1140c1b3cfa67530fe761ef9b2a98ea0cde1c51f1769845824feccf0f9fd54f12871cfd878f0780fbf1d60f4ef606df7e0d4e16a36d6439c62a20a8a5cd7014a828e69af6a1800089a0671460b23438acd3796f99864be1b682eb30f5d50e90922a99a35049934a92238c8dce91cff51de3dfd934b783d8ccd7be13bd319551841047369a7d41671cedac2ff1c6da4b0f8922d4a394d442de5fa35c64cc6f8fcd322245a92cfe6a7b5b7fb10e81ef4e587994876fc98b3a2fb7c02863ec020dcd82ecde9650599cf0ff767e152b40d0b1cfd91b5007911aa8834467ab8048eae88771918c100245fb8d2c3a0e110169673a9b96c3fde2ffb930d2019db13224023e8a27f168e14d59166c8183710ead7229bc7a3e6b3f780111488e81897b0aae6c6116883ffc1192c84e6890a92148352b2c5d35466abe150e5bae7c34ccf91726ca13cb2e3f1e1c13af06f3aa7260736b08ef9fec83988549592c14a872ec98e69e05c11ef3e9564a6d90516ad899bd304b88d8b75a480ccd2e1c7a1cfaddc05a3f5ae3427d6079b01ffe349e67495e128abcf630ba66324532bacd578adb9cd99086dc15994f4d1f79a4bd85eb9359e6b0df118198f55d99d841e54f7fca270b7f48e927acf9a7daf36a5cac2ea0974045d4811f97e21a61c4d30177074876aad26316a95eaa476beaad9678bb64a326752da93c346c878c071edbd15f39636dc7da9621a8a6ca71973297c94afa2e5580bb27f5a3e5794f6be7c5dfa2a1f71477a0c5b8da0461d4183de6800c3724a4f023fbdfd1c70b9b7acee58d28cc2ec9c81996e13ad4e09c771ed94503fbe24b97f30215c7f1cc25315cc01b6d1e7bb2b28b8c6994561c4ba5fa605b35f358a0518b14159140c06934cfe69cbf0b86730630812fa559818e81608a55a02af318528ae8fe3d5c405708c9329bd78c36b00e3a2b45b31c4982513dedd629875a026822fc2e54697ac53b636ddb016519463e1924ba9640b02c1e42eace837c8b3892a7c0200d97d54de3ea9cf1c38d6e8b5695142abdafca574dce53086fdaaeb4bbf67690fe105df6319a1aa8d3acacf51c58a8b279faa6e7688613f822b87717733da453eb9ca6b52861d13699bc35d3a4de762515c1f0098218d6b8c82793f899343cde6823fa06f12a2bafe42185f8897a7b8e0f944cd0e510f3486504eb821cebbc22068640a3160d34c41f0976cbb3e710bf957012a322cf32e4e8ce574d1e4a2a404484d2f3ab355d144a703781422113c92238adfef0f48c356e9017455a77464921212c1cf496a528c66333d3c7804435da3d4b6fd8dc197fdb3b2f43908700d5f619ed33ae395a9925361f82a7df1bd1e8b154139c61cd3e8651d57b2cc48ea71a1411f29084c65ca89fff7661d0d2ad61a6de140e82448ca7997c066fec0eaa7b58387d7108a8c1bfafbf54e8bd1299e2608764891abf95f6eb6f7d5c31bff1a49c216b7ce8aa00773547cb592c57ed96ef8320ea846810ca8a5ef45e64ce028663af4fb2586f22cd354a86750cd9bee1b345ecb213e36ca183b3b538b928a54cddf5484742e46e920ccc42438580f71cb8cc9410e884c1e95191796b0ff55f07024941630d6ed2450a90c5cb8d3dbfc41b8e38126148635e3460901c2e9d2e3dcf22f3029c1b01a6fa8305524dbc8b9f52c3a87ceaeb3ed09a74221ecbd19fcc6e4c21d92855e936a902aa6a724cc817c08e5668ac0c7c10c2bc4278d8e57ab0c28094ba3ac20bb5692f4b7fb35c30aad25a952ebac0fd084cdc29a499d1b74dc2472f23089ea343465a12094566a9ae347fd5f38a78b31b62ad89ead323a884983d1bcd97328fc3d08081662bcbf0c021e7594624140058de19c854f9fc248aa069123e25218884fa4905dc1018f523c8e05c9ccc241f143a17b214d4a7099d7cd4b381c603b9cc94895d58970422c182626dc44197544388cd6b92a9b0612f683084a53b114c91094b2e5dedb992f2bf4de0005bf6deb0f0bdc143b9757f720778c692b474cb985d1022d2d5e7c9b639911bec47134fb36a3160449ff29823dec41d34c035476cc4406363d480de3e12220242b653421a15a5ed521f3d89e95da810e47e87a356a9c0837f19d72c092b2912b33a7bbfef0c6064828675706d9994ab3ae7dc235d9cafb852356300e951c8b662b1719382a78dd900856fb9d6b6a59557f38f7516ad15465e469e3ebb1707c97bfb060e48e71b39e2f5173985b27242d4c12a00d755a50f7336bd665bc125e8a756faede236086949c3d5ec911ea6a0b6dfd16e4fb2e4050686c38764a35275a0506f65a920254c173243675610d5b5e36404ec005e93e43a3482972e500fc9ffe124a0133690f08182e830069ca1310c66bf2dd407e8160034ec5098caab0c84a1297dd45d59d388093e9710b6fef01ec03556c745ebb103c72a805f058bad4de22772743a34a6d4c4d3b8a1116c7d4c06229ff4a5fb9d7e28dae5b4915c2268c0b9e8632a5bbe78913f569325ad9b329b6410a3cac52b8927548bdc64d00652796ede21570f3f2fc5c0cee8c0a2c2a3f90b051a11d7812b1d30b1bf8d544e381978b903f008cdbf3a0d13008bd1d80b0bc40cca00ee27d2fdf56a677b1bb9e757483e09a2df3de737c18286dd7813efba4d9525309b54d313ca9fc01779acf153291250225212a284eb69e5b521a11fa2ac38458338725ba40ba2dd9d7b7ecaf0efedeed42c03007458ca80f6185db70bf1d59b0faf906fd07a821fdddd4189a1cd360cf76fe4d8a46823d16726e2715b68c6c74f826cbec7b893f2ea5f48abf73109c2dd111cedb1816510885154d17d0935d62bde262898d45c5c1265a7bca14ac19d5d1a5ea251592828a246d17f9d90cb99ab4626480cc614a8812004f88ebe8849a830f6c29d754bfa2c732f14f3557f4060c2a4308b93536304d19626656af1622784cf0e78ee96bef16c465465c3d315e9055dfd49497c12f6228da394f56d95bc0f0644260eabdc14bf0a7ea4142b713113541880880405656484c378b00ea9bce23bfe17c4116ac23c0d8be3ae81138d83a533d45f311d0a10f8df7813dd3ddedae798d7243deb938ff57541e3625036effd654d855f8e459b31b83bcd6b08a6f3946899e113c9bd1f119318063906d6e2f0b3ae2bc9246e436073a20b3061e223cba9c51d8d7f7ef76e02e01e14faed7d77e2cc5652496d850520e96f86ccd3df7a03a946416e15e72de9fd83dc605516721de3767af2f9e518067105f4f87bb4572a7bf328fd390f1ed2b3ee51894deddc090188a1bcc2f363b2bb2f3d307254c0d8243056c789c395dcb1562c8b4addb53942970d4da5fae223045644c5fc6dd31697d648f048362059b5da8dfc6f652754ada18af960e30de9ca989bbd83c97d301256b37c92ee23bec863d9a7f9b07e28fc754c189a50bada349e56f95e326d75066dde76b855e16f792ed8c0178aa992cbbf7d0b14494d7e85ee60e9d05615d92c0e4b16f6ec8d9afdf610bf311c0a31f23db028c46296de47355db2653b57562f35a8e905c19c9e126a43a0e07adf810a5d66a12c9623ebec70a1d69a5ece3edab920b6360099a9df2f2088a1dbd2c8e0dcc9d0fd5e5949ad024d0d82c402a506ab8fc4d25290c5f20548818bf6683d12761d566adc07b26a6231f39ec1c5b1e26af7d594b17313101fa188fe718b009677dae0c8d53ae3e04142da5f6d3bd4076c54f3775c792d073cd84da7d7025903c5b908cac3456dc8c4a7c60a16af90159fd6ea02f0744b2bc702f1ea05646683a67648c7981da39354f4d258abc3aaee0abb458e39352c0e449282c57033d189305ab766fe04f79c35e02dba19dfb56fc3e6a75b3315c59430baa303324c0ccd8317482ca5842d23251bcbff6fe5b585b8762c5b906cbd60b16e0ca0ad2a837b7fdd86047b63e1b239fe2267bd4b61eddd6bd0da6d5c830a82d1035d1a30d9fe73cac1120e86f1fe8948764b9e73985de4b542c8ba75b98b275ca4878ca9025d8a3b40299849f41b7f01dd3f456c11fc919721b9c06c0dde4b6d9a22ad7abd2da1e99729bb383bef075e74ee91e41f76695a467f1596ca92900b6d3064edd5d3f33a7805935c02d98ea99efc922966d0d2d7bd6bf87fda18937316d5e5b7c73ef4978c34e4ad41b96fd4beba2507296ead3a778bfef7e1b4e1be6dc856dc3d9102304dfe139a2fa8680e5de887d3cac6418ab65f51f03b3e7c47f57320e3ea2a16d5b660270189cd275fea9d6386a7d5bf491c161bc28ec2f3663446fd0e4601e832257b976a08b631a4df8c9c4e6278c44038ab781e02ab1a43a91bfc2e6760464cea889a51f1970bbc07588a9908a7af5807963306ad4a57cbe6864d5d85e2598b9c8e5223e1ca1a1522f338edd78842ebc824699e8697f1f708252b028dfc4c7165e8a56b0f31da73ab71eb160569f8a5b71d8c101e79754d5d26230d80ab5d7a005ecdfdcca1c203b7f977dac8744901efc6069cb10674d2884baf10111157f76a10c3f623bff044a0d7f271b4d4e12c3590628806a43f3c2a88a87f84e9949369ccdbaf68a879740cf6f38e18b8e5247558f734a9ac52ae94d6fa159bcf5a3d193898c4349298146b8ade3cee785f7691027815cfa0690f7751e856517e1ad27ecb6fc44c4f48ccb1e6fe45b00b556f1f8170afddc15f31bca3cf78a23d8569ec74f8b2022f0700f7a62328a11945163121b79decdc5156ddb05e50e01c3aef189b61d1157386d4049098b5b94f04cb4046038145a6ac3fc1d144bf9877d9da82955461304ef72d9cc75ed5d81013f92461907c8979e11cb2f301250e0d1a05dbd317312b6711f344571ec461a3f7455af61413600390b751107c90c1f1affb88c68d3481071dec063cbca549223b6d34a1631fe1d2ee644cde5af17a06352bfe0fde4d7b2da0e3daf5ee2fa07f196c15974897bff81d61e435d489b27d2af986be6e297564e520c167617d323e94d1c6de1e859962a4b32074a63d8c8046fba8e3eccbde89c8c65a8fce93abf3db8bf2dd82a68f38744cd98c663a6c1e643b47b8ced4e8382f4f9232ef24801e6f0be047252cda4abb5d78bbba4145b2c6dd810fba1ebdd891ac38ecb7441ef62625bc5c86ef723965af821210f2ac7783e20ccff44fc0d60b258be4f3078499040b033918504eccfd647ca4f410a1c7eddc080e3421f4711933928d5af62f489dc09087393bdff1431ae54943b3d88a8882e9b1292ccbc506384b963915fc1610a1ecd41d36504b7cb8a14cd5ddbcedc487fc7600ee88249eea728ac6b8b78fe187aa05e8ed8216f9d107452a1cc0f05c0483074c5ff949301f9fe3c3942b6b80cd55ae5e1c7e18401809a5ce6b1ff47737540aadb96f106f7691e931709ebda44839852ef403659d1583f5390e5cf83280e0be6ee837d6b7566c919c95696ad77aeb91301587bab76b564f3088cea47caa69794445f5c2f74e4d1a034c3661a32ec8270d2d45b7d9bccc53204e57eb8874b932d0c4933535106e0e10593c95e13bbf42342209fe73ada9948470098aedf8ed810e607adfa7a7b37a25a17ec5dacf3fa4525d3f1a029b7ac08b64068cbcded6d7266ee2a550e8df04a1561e3ea2b1d9c0e7f1782f3838bb49441119ed74bfa7702e54a88354999ddd77af9325e073465fd0628a627dc0159a7391da9c322a6b15d802af107069d5ef217338767259adb17310c4cdaf9913d82d395dc7e827fcd0d27c493887247a9cc9a157c373f8ad9d76adfb503c03e44a795f499b823f7ff69b9c479c23a7f11f776436915cf735b96f07b2d63a52d7bc834f581db62c36a43346d7d4218025550935872da447019bc06232b34c1f710005988010cdec2eea65df145025e2c6b55c50b77a467b91901ad36056b203372be10fc682d64d7bc7fef30cfc0c0f9d20dbc14aef366739e3f9677c6e3c00c371de4e70dfff9369a230c530db6293c4fdfabd16895bfd64b44f703e9eefd42f8d3f165140316b529244787d0f11e321e4d840af54b0e2de66df5ed6eeff61b9825894d7dab9e9ef31b2a5b3afdbbd81e9ea7517154725317107ae2b530838061a34f0c546a1325cda3658f00fd7858e0c3a476796434d16f057d1188cc3dcc9b0341b253a19a2e8965e3f06f61ca9d3e8c9ee6c084ff5180536f3052eb38543076843e08fee0d3f62bb2d7bd3baeb27528bda8f39c927b2b2bfffcb9df83c96302ed5e82c4342e42cd9f734b8318aa69be2e9e201d47d78779840c179c8ec37a76d750e09dfe7093674021b4f55b708cff85a11388254d88830d4e6d1e8f63ac43b2610f483ad4bf95309d47e3583825bd10104a1ba3b5ce830e8c5808930ea274284c0941304ab6509c64e90f9aa8d8382d3c3bdc88ea2fd9486e38c93772665d353d2426e32e69778abbe50a342174d4b25ec58bfe550f375ca786e6c8f3d5661a1339ad41c227f8ca18f476bc457257d6ad6b6a9fcc564c6dd50aab81b2962ff5e3d034e1447059d00c4fa5d4936ca004aedec2fa03259317e05daa1e5d04b1f77063a4b314a937c0d04426cd991dc05f68dc37f99f151c6cd4ff7fab42ada690df2332724dc168ce9c5d33b6ef201b358b764b37c51f6ffaf884695caca94f556087d26e82fff1ba2434af893b9052aea6fd1d37f9cc490268535e6064f07b7682dc8f709b5bbab8867e940df8fadd940a8865de41ed839a63290e35dd577dc2a89ac58824e8cb9ce37a64243fe5447b68ec3a56a96202232e77196bee9f3a8db17f7b3854dcb871440b43855bce9d6e1fdc9485f59b2b33f8a8e1f8a8706aba83fc199317b8fbacb1f8b278c6a92558ab7b3c005a71c22fcdc766d71416c50e7e5905a02b4b90ed6350f22cd012007738df16b0d473c31b4676dc1f4a837d15993193be17cded6e673922f043bd2b455ce4807ee8e2ad64cbc45693182239433a83d44a8648120c66247c7a530c23b4c478600878b14c74686193f5382e921ed7c1d5b97d1bda96c1e2e852b5be654df1ff2a3ea0a84efee9c70b20909697a2e2a6ebb2200de5e82e8600b5b39261e9ac22b41706a02b0d371c344ed7e665bcf55dbfba1a78df805f1431059b499fcc9bbe0d835470bcc224458a89bdaefb2592531535f31b61ae10904f533be9890e0995d93590fbb4cf5dad08d3c16cf2a8c5b3eaf51b19e3b66331f55a2321e1158f985955991b794ce182d52a4fc450bf54ef735eb7c7d84f256979b6cb24b527877cc01ed758ae28850e3c514fbd9848f15135ae7feb59470336d008348c7b7f293611f6d3c439060297ae29016f12085057487388e8dc333b500d59a0cff3f2f3cf5ebcd07ab7414cabdf15406dd99e22c629cea505742622f121a21d679a40b559143edd23041c6866d33df1a1460b79853ee318666455ca8abe60c2a606b3a13f3be46d15d59ccbe4db48fbcd19ba517b3e9dec272fa6b200154117274da09a43d9ccc93730626ef9a6a40b89449660c03f8285bd03f16652884116e02b876ed62e183f5789a580763efd60fa8feb4aa6ada391b93c868089b4658c8a795fca8e4df7c20a5ec6bce3e63953df8a0a5b2593690d0f061fb9b0e8a13d4626ba5ce5f5a2a5a120c4e9f601762068c31295ac0c2206e6090f3758f163171fef3f1842c8e48ad21118ed83fca30a53388987fd77bfbf0461ca7be92fe4c77ddd27d3e381a87a8b3f93258be15e43481f43975df687af40b743d6c5e87766cec57a0d946a6f46fe9118f6cdeb68fd1650bc74948325fdb5de23901345b6d7958747c262e79249b88b3c423d5eabf767a3fcd6ed80060c1759707d24323f41fab51405edac29ed4ee103bf90c494c6ea381954a2f0c268f69aa394808472e0f5c64bccdecc7b87e8fc34a6cb81ea685140ace3d0eb36cb8f4692786da468aa84572b06655b1d5d488f4c35c958def19a31f7a3aea1fe5e3376f8238b79656b54a668808c7f043e42d4209f85a9d95029702e5ddc9f5ec38e4b09f8baa002809855e6c21c15883c8da6b95acbb99023ed0276975052022109844d216872252b3bf3a2dbac0b2d46deb08fad4fbde0d980c740147fa22b8dc88c8ac26ea98bae55e6215caad98a84646105982c15b879c83c5b6b6a8faaa4010f0e11244c8125e10aa0d6aa80d2b0c5bed83b554f813bf95ed2e54e6fd845ac6106b32c1921e06274280897936a262bf86f8634b023982f166a00a54fb4c3a23609327e2c02c00021fc19350fed96e111fa48912fb2a250b2f0f6c850fd698ef14c7ee9e764451e50ffdf2e17cf86cb1d4bfd56929639387e1459e3f3e4dcf0c2e0f7af233b0c90ce49f0a3d8b26b8ae43c4e2ddc4e59e3f9f27c759afc68c58956d3172c0967a3413a231430834807f85f734459b8552b33b45096803bcad2a1e04079fff6984667d0581ba0221032500c173da12f621606b564b00e5f5f57fa64cf0ed0c350b1357aacff45c35925f29476bb652b8fb606104c07245fa575a5fd00801a03361673721af9f2a0031cc4510a6488b910d985fe560062a65f8833277ecd0a9baeddec616cc5dd8334fd1778dcf4f9b66e71e69c96510f3cf0ee848dbd73d327092640187220e451df2da4c531a1022848296cedf69fcd50f6bab042bab36c68ddd0843d2612ee7c92fb517ac3b1ab37fb99c57d4bcc02d743d985380921cd4d8b0a78063026c720af59e05192c973d36463a5561db939423df2fc5999e89e863538df06fdd8a42fba346be291ba10b16b35a14ca539db0b4a0317a9527aafc05c147bf80f0f39387bd40b950c6b94e84216867f98e2c59e5b53e8c42141a0eb32016e1cb866a25451a0e33444f390a87babfbbc1784f54092a41685c0e78eb9d8413eacc21ffda28365bab4dc0023aa64e725a35d1698995aab2f268dc0f870650701717151bd860b4f962273e50936f6f2bc733a8091e4583d93da75b194b724b78146057eacac9c35f93df546c7e14bf3dde6464f85859d046faa98a437e8a136e10d0df5b95365939fe61038ca788038162c12053a60223e8cec033d986c11e02b17a56e5ed2d9cd7e6d0b45fefefe86a21af0a9f0e50e7afc8ecbafbf25c53f88264ceb4650790abc7b6a5f7cfdc8ed53643e16586f4125ca3cf7af1c88a9acc19e2951c78d72f2af47020c5b600cd8fac92f8a22cf9a270caadc88d1663a63e3289f304f3dffc26f1ee79af36ee4d6d5a5f05fe6d75ff65473d26386727715ca204da7eecc2453a25101afc33901258cea2a825223368c13db01a4135105899ee2a4a0c0b41b70cf2e4cc974c380401f49c30ea7b270aa0d922db7c72ef27ffd4c8bf2a10c9958422f7cbc2a7b94d0439d6a17157284c1e6725a338d38c1ffa4f6ceaba03c1774dbe7a3e0bc283c9b2e44c94ca1d16f1b7ed85cb1abb280b6bd82efb3020671b682e071e8cff8f38afdc68ed8470712fea2b908eab5433159f53314f28869f8751afb970bee9bb769db23d8f3b06a392e7bf5050adcf841c8ac1f702fe0ffc97e3a8ea77879e991765c2a20d19628dc69f6782c1d23ccd5f75ce1c8d81b4694894d56f30613ede0cb37262ffd109043945b9e6facc2238a5cc47f61ffa5ccd73988fa83629c6cac00cc7fb35728253405745c91a11380e476bd01618540e8443c3301ce825ee418ddcef67f09d70bc24f44b826f41db1c6698cfd4b8a046bea4450f0891565ec3b7efc550d01cbc8f300cd2dd9ce388b43a3fe94b0e85816c4b92f8c33f2b762a8521d962dece5df34e99a3ae686aea1f168d201c65c5cd273962ef517ad83c8cf6ea259c75b28299f3d9e9088847dd365240d0c0734b6bd91231d00b3f5776475ce9265a86ca4c13d747597ccc9dd0da897b14a3c5e46227d697a7ec1597d018b325e8fc93e14d1a2de9f4ff22066d7ebb8318713e3f4fd977f9ffe94b8c5305c8a2014fa309fa3f7e410d48b954e88fcff301ae85e1ba3e855458789d3b197495d069dcbe936324c46a5cf12507e2bebfcb98329c3f8f941bd2d8878f47438c00d5f879db370569e0f13740d3e1d798fde52a9a633af5e5168ffc88013dd2af1d397cc8408672a1ada8905a9d0d8f43412eff5a893fdb6a653d768199ff98020dda889ee9081c043db59e09e789622ac08b99c87d03407fa4bb6de3a7579a5d756014a710d591b516df34501135fa3195bcc6d6b198c86e44f54ba4738af34003c85ea49be5f70bc3f1c95296b6e049b8b88b7650b11665de106ceb6fb48ba77e81f07e0bd69a1a30f4d12278900db6d4cbed0a950addbfed611966407a91e0b7461c88332bb0225c2905ea7d2552b2727ac332268ad8038afd2d9685fa15bc6257f25c9423e3aa1c4b4b05db0f7b122599f2d4aa430957accbbe8a243246c78082da2211fa9073155e6e3e1bbd688058941d131c0e71cca84b24d41a9ce4476a2e290b02bb835e86f4cebe786a56429d71619dee7a0c04930af14e4bc4bf45dbb8b19e0a057e0d17469b566f450afb6dad06ad08cde0dd414c67b49bdd490925af05e1d5c08ca5d518957ce39354cfe2975a2803b6e949bd61ab16cd77db6a76c1579dac5e7a0c17165f7641277bf11b86ed5705bb66f1d53b2f40fbce1f4b3e55f8b0817c7125e4618c93b9469e8609fa82ae220e50c32b4322f0ace8bc800167498234a4633da9a717111f984f0719b405b6fe8a3ea66b181591baf4e6dd4187ee0555fddb0100484252ea8c8711728073c74dd47b45748edd9c0cb6ba028f79cab38d5c97d478745e73ee64b9a52c52ab1657a56c75cd312a9df548e5fb084b7db3585e0f0756415cae17b10c3060eb91889d66d84eb365c658c16d856991a33b2d26cae66a0e1367528297d40c93e77ec10425463c878289141df2661ad374005698e2544870302e0655a32f45007fa69cb3499964240c02658fe3735d4907a8cbfd17daa80e3afd991cad35748cd248ed4a973d3c74e716215833df7f4d130283269a48c9e662669c56e964be558c0d2d7bdddbd4734880e341acc2a2a2fc26f1bff619414ece0b6c247799d31bc6ad8cd7af42013d99eaf4cf7341580c909502559ebeed4463233df5606c6e8e169c3edf2a5410cbb0d13b5ebf02ddb823d7abf05e932e93dbee65c6aebef06db71442b8c1c4b0f1ac6098d32d017a05d3cdd837f7ffb335020fe2db8d0fd4073af82a3e40213b5421f9700fa50f747603a8e5fb7f82da1ed61cdf3d6a57bf1efe4e01f40ced79ba5426ce7ab5bd84aa783ff5623453afbf19028615c9610b09e4813b39bc662dde8d5f5f504cf7cf2b459a7f30c2ac81272904cd1ebe600ab92c0bd12b2883eb7164b4d505b2f27838b1d66398d9a10eeb9bd212736d555abae41bb441885f7a070a6ec6b68a951b37bc7f63eada6ffe696e460ced8d05e2bd6ec8a8186409e63b762c2f236e9e9c2b717e319d33a5c6c172d0e36b2baf0c677b868039bef68558d0ea381006215d09174a586def6f309a5d7d209f3ffe1685938043bcc2ca972ec7d4a1e418e706da36a1dbafdd4cbbc0b187b936af694f44962c38d8ffb3a8386dd50b44ac7dc2c7298cbf2219d94cd18019df32477eeb8f7b62dfe99f268b8616e7e7577db0c83b93f2771025280e86ecdd9ac94e940e99141778a53deeef584b99a7eda0e0def498a4bb9670fe149a97305e9c804055025720ca0821082141bec4589030148c093200d5ccd98e49409ce910b29b1821af64a1d473c42e17fa713576cb7a620ee32b3fdcfe3c3bb38c93090c77370547a5e330f368bcbe8d46e54918085506bd7c6ec03db423a7d60fe0db740796d211ecb51d640aaf1da43a753c7ba4d14666da9bdccee1b4379881776473bd994f762fcb4f211d0af5a3599f657408536ffafe15f666b3a4db544744e70f22fd63f446d3a375a77782aa2fae9c93db612bbf508e0212dc1025fd5b93f5865bdfb7fc48b7193399ce21dc97e1b3e839f39cb72d824337b1c926643e87ce835b1cff22dceb4a87874dc790df12b5bbd334f5a471b3ed70c9d44fc673156b727256c3ee0b961977936f068878fde313fb0e1e54bce3085ce62ab3cb4037bb3d57f51def027acc4c8ec5a2863d1fcededb5b38b2d94c322176edb135fbbc966f13fe2aa3e4eb4497df8684f75affc4765eb386969828de234775d3d9f203c60f81829f41cd66a1f1e523f53c702a5fe2e4d9ca33d022fd2bc09d2a517772cf978f3edb8b107ce37a00cd5fa31b67e7bc7a6a6fc1cf48fed7470b5d70d4c68fe4dde08dd4533bbfbc28bd725c3176663e1319e90792078e6b7b6672cf569f8bcd5603749053dec3b0c60ba9861f38cef523974018f38c52f7d7c3e2fae39151f5eedc5efc1b78916ff651cff13cce3da58b657774e2408ee20a74431bcd75ada8c51236e86e0c89f600d62fc1c0d81e6b983b8147fb5592c3401f0ec6a17be3969ba705785e6890c735dda9791b9d3115ebdbb77e13f13e5cd81345aed5d5d9a75ddf41ee8e17c48f9ef3c7e98c8ea57e24983283b868b6d44683ca8bc3bb347f4f6964887dbaf1aad183f2038ea4f6972ef2db371a470c8f40700ba284ed93dc75b7541c299694cdc976beab9b422a9b147a1cdeb716a26bead34ffaa7655379532637ce0aa6ef5905f9a5b229947a10c60d5efe6b51c0a5913cd40376036200da732f84f50952d1b507adbbfa489f58d49275e084cc165a62d3e3f7753a1dd2baab16536116cf8d9a73be3957498c471f407656b3e80a730a3ce280b2fe5f88242cf636e176dab073e0fae4e3e0eff8cc41b097b8225706a2ed68b355626c1c26f2f16bee2dd8f55080fdbfcab60d43d0a5683984e2d05eb88a773ec27d18bdaf3606f1d6eb9bfaf4ed973b40ce05236283cc90e50c98f0f94ce62675f0bef5d522441e03c0633a3e59aa681778b8c14672e7714886313a55ffd32dd99f9b9e7155d99a052b48b7441117581af151929d5c380ae0fa916596c716889514e6925ca2c2d739df4d4d8186d4daefef2d5add409eb980ff670166d286ffbcedff087ef85a2971f3bbf96ba315f9d50bac0c7fee089107e0cfa54abcfd8bd2092baff6ed93b621204b8edf9f3b39adde28cfca3bdcf40b2d06de1b1efe726a4d878171acd11f96c5f4d46ab9da20ec2040fc42a6d3d8ed1a7fe9821dedf2929e3c10f5590510699a2328a046d545c71d1b8aa9a953c046a8bca0115c3daf4707caaaede9c552515ecfb40e7690a7bcd10d70b435545248b87b957a74d8c4f1320c7bfdba0453ee320ad832b2a9b3d9da7215b584ad709469a89ad272663efb4b54c9b1ede8cd8977e7d9e3f581caac677e4189f441ea59f96bea003f8f7a5b22838e38786d7fab8b2a40c8ea29801637f7915ee6731535eee47acf4a88646274d3280edbb8e27706b9c92550e848662ec0daff0b1c5b274765223d376061f2328c817b6bc51c1115e809ed41e1edcd1e63c2c2a14dade148688a15b881ce83df9b4ab7d0149a3c8e2305f02fa4f8ef2e1b5492a8f97a0f82728a0c7bbf0cbfa8dcb4882658b950fda246fd78f77bbe7f1e626492f60ab6da1a02192bd4c814121cdf169af1247bcb0e4eb57280993ffad34213398eef69e547ce6a5fbb643fc658b618eabf3898b37d7a729168068c786049b9ababbbd4d964eb22adc3db0c78c514eb6360402687ac02ad42644b14d07da89f1d07f101f3a42ef5f5e02025ee41e4bbf0031ef283323d2257b3ef8eb6ab03c2eac79a2387126d5b9f4b1c8448131c169cbf3d9f814e5881991d6981750d7dbb5df57ed15da96d5b333a8a1f44d56b0b4325556c44f56111a95e193b7c713f21de7bf791cd82f09e0118b0d22132ff9a6ab406a27c82afc57678c33f41a36c019c952e4a8e0696a769bc0416667b7a839d7501864fa622639e645c764a1b9609f371cb2e18e59fbcbfe1f94b2c1dd66e62038a4188247a2d3d999fc99414b307c83d8121a80364597fb125187484e676fd793e69f9b9f93b480353b8335d7f7d8d3af8319e5ec694568e83799b2ffa553f2b8dd2ba1606a53bbab07a16b2d99431355320e81004f18c73d851504a19764c0fb9e00d860ef5ba38051f6cf9c5e3a9155b5e5fd240463cec544eeaa23f5a3b033faf9c05f2efe42f78ca17c3d63ee769c74b0dbcc8cbb10b199d4b250dcb15e1a6aa0f0772da15690f08097ef239b7492d8a1f698debb94e03cdb3c28369afa037149f8ef4bbba748bf3c47542a97cc6bee1f9182dc959e4a1d1f6cad492c8ea5a8509a0360984b01ccdd6650f8e56328c6b3ffc0c0da123e321fa79e017fd1ed75d84c446df576aa241e70dfaf73dcf8708e62bfb84ae18661daad9d9689e9c2aaf5c341b8a861072cd961f8024576615767c78f70bc63139d4f19f86e7adc0ec0c2339821441b74b9af4de5c1a93056140e5c3bac990e692a75b941b36a33404a069ef2a30db953041beed4c08f4da8046696574d7e16ec20792e87c885034ebc1c272bf7f70b5b3dbf0b6f4aec9b742f9ff569765300c9489192f01a9236798e51abeac7c5cc7aaccf4cfd142ccfdfb37ee800330ab03fe8e5df92b2c2ebf768a463040f8d234759f75f0f96b6555e161be384229cd65450961bcbc5f3ba0196283b1a2b7bc33312d396ef2466b515fdd3ae713bc7a5ea1a7b3f7e8657112109210fec788e5fd705799f8fa0b286c401ac754392d14e3eada14edf87ec881d5fc1e90e3b097a272a56001773c1b111003232aa31d44491e80d1424dc182998d79c3387b1d98e63fb804d8ac59a41b97261b2ca373ca784ab9186e9ac0cb6cffef6e283384d810e68afa646a1d528ded0da549e686940755a125b2f6488ef2a3a1d16628a31ba48a9d2788c519956598e695a983fc583011f136f64794719e7e11407e40d0c7362048550f8f2c49e4130373a2016ebda8eade3804f73c874fcd4d53a686ac7e2545c803340477034d120ef7b369b245221e924194d7f587bf62db6767f45df9613ff3363510db929f8aad83befc91e50335bb13dc8c3bc3baed84e10eed5e8d20c8d099ea33e7a79819e237ea46cb6c090cb120e8c62a59a9bafc45c69843d3f0e7cd6e22779455f2fef10f2a367abc72631e57084d20956a8217c0e0a97792105d830b85038883b0ed2d4886650afa0582e16b677c4267ba46bc3571ed7491a2ccb28621892af552c4425ad933d443e878ceaa7d1b70e16e0ddb0c78c10c63602d804ca208e3b348a987e44d36aae5f02c0a4a505ee5ca9d8c8bd5c631ba0ef37f4383aac774b6031d0fc0baac33b83e95b1854fdd261e0c45cf297ad9c931e4c04100a25b4289dc5959fd48ccbd4f426e0f8f7abbe16d32399f0a1c6325d3b6cda2ce53c73bb7f641542b0ef8bd7cbcb39c4c81831c987d7ab380b40e91813c83c561f098c6fcf7f0e97614476c763f0950a7448324e155e76d4c6f4b685583befd23575fb8684434e26c0edc04eedbfe6a8bf2e9a3b1307f29230005559742689b1aa1d6414d5b422e0c86332a9c5a857c6f1a8c5b911c85018d6b36ec6b5c83aa75f9a90c6c7c025e88d7081adceca07ab1613cb4611869e1d622f3b33d0a5d166fc4c3b4f7b42ec46b76c1e34305359f33268d43b3db5ff2800889d8f43b90380b22f19c07c7c38f199d859f41e470d4501c5e29c51dc9153b76964a2cf7c054d360e472260a363f5dc859ef68eddd7e9ec5c1cb127396a517be0b18370ee509558817a622035347efdb1935ea02cb9e654e1c1ecb08eafa78e2287c60c9f4a946be43f7d14adf8c303315983a86d7f4e4c1588a48064eb030cc05c2b66eaa3af6aa51b8f32e92f2e6b5fc55a2ead9fa72138e2c547cc18ab96ddf1794fd0bfe13306123fe54476b906d5423cd05f0dd72b90841afaa149861801cd2cfc0895d1bf2d0a2e65453a2d2ced8682e78e3d8a76255da354846227be9eb18a98b346ad7266fad0b70c9a1f7cca00484c79cbc383ae39c3c4aa1ea7992ae0e40b0c94718b95171c0c9c00273eaa24f81aa11a341e6210048bcaccb07b8c73b735ee8dbd0796706df803e2a5bb8b825991cc2dd4da543c110b6ddce16dcd2b81411f4f1a3b5f5dd1e5f7e8613e14dccdb32c215230d72a949b41e5eed74c1e2f330bc812cdb81211a5bc16b02d97a547bb3d5dc3b1521f1c308cc071144d6d6195c460c0080c54f561fdf70a5607f8a7090edab11e2dbdc60dad6d8ba940bd975438dbc1b6c0b595d1538ebae52b3860f569ea786b75cb7e4067754b2479d1ccbf9886dc2da6cfa6080d14efa3dd4a952d6fef83643ec807b383a9d65540e7f0252f8456e1095527ce440565152fdc2bae1bf1da201a4d2905021e33ac0692e300ce5acdc4cd316cf9296506fc0c3d1d9d1d0c9f936d9c0bbe7515309ce20411ef4ab77dfad988c38d96c74b1f0efab33fcabf7eba317c929b71704171e13a108714b4f45e09cc02406f961697747667d5db00adf870a115ad4366c96bd72bd009f6a1a194d205efe8adabda68d96a526d1d242856f28d6ba70b9fb7142f2a15ca1201ba572d6f61da6836c2071535accc9ffbbff37b71e5ee5e5edee8c941ec8482ce04f4c7fdafab9978fd0763d32888e9803641e18e78dafc0f89791dd08f4764140ddd6cf2855cd408c6dbbff117ecd2e82c05444805e57f703ac8222720321cbb4743efe56a76ccecfc226e4b287f75a0e58209f974a5da6a4e5d0eac8c74957dac09960ebb102b2b05ed6738adb4c24c14b24ecc2da436df960103bdc5d2d39e5d032fe162d205b7761cd49e966b83118f74bbf010cef8286790db3396ee24ade17720f2e2670b2083e1a069941b48de58a1872ab0116929b5bf1fcc9cbdfcb1d61f22a0634d91f48c056184f9c99a92d47c840469d32dca7c0bae9572c9d082604c761f0af30c1a45689de4dd4482653162324454e0d226407e1b8ec08d57ea9abe7eb3af3d5768c1967e091af01da1edb98c8ee581a6a2d3434328b5aecb9c66bff89b60d988ff9fbc9488e514e828fa6fcf1cf219f3d49ccf2805c09be8fe3a3da368f5319d4d16725733f812ee8b187621449b8a1ddacd7039d180022692aa95ada864c78994f97fc7220eb1ee1c762dc9e4910859c5d5fe7e133bab771740a063f9f71ac03d32c138b13d2872d569b58393b6cc5734201ca4a6820739df66ff041944444f4bee59ac051a33610f49f9ec1e857b61eea2ef39eb73425aaa73a69ff871be0d795f9efa9d52b7a8d40dd1cb2609f1e3b718c531f416de2d142ebede5edeedf53586e907aef3a54b333579c6b677ee1f6ea111aa616ac05d6892c9234c4f348de55abe4633f1ffd9fe1b55b59599d2f0eadef785cb0d419779b2e652d1ed6bdef3a9d57e2f4b98672ad88a3583a936e38580fc2dcd0ef8311f79ebf607c8d611d9554674dad6c27e3c05d8d318a1ce1f73188d9d327b10fce1a709c2368b6e1049d0bed51e2913dbc2de7d348a777449a5256cd1158d40ffbdbacd222073591f572df5f1ef1239254b17e50f0b7b0e88fef73a091f732733cc95d69d319241a70422e1a6525239ec872f0bf670b7337f5f785c8efad9636a666cc0046902eae8eb0e95d6e40f2c023d5a405726a77d1a7ad3ee9d6344ab4b48c2bd441c1b83410bcbf7da3a89fe3a26bdb079c9199a4067c9616c411af9cd97309b7122ef1e1fc7590268bda4837bff7b4e4d9a403b0cf78bd09ea63d5ae74df5954ea57d6d403cde7415d33cf365f921354f7243645b9de900480f177f983df3e6949b79668679552d1870c5968ab79bf751b1337c6eae8089ba8262367c4867d8ebcbfc3dc470f673408da133b67ea51bb93ea11abccd5f9e7735312454f604c2a692578ad619e8ba324dc5e849a3c8ab93c8466f0ff22caf67bb8b03f743af0e5830747c67be40c9c28ea584d52f69a869dc0dc14516a9a2b679244b5b70c1f186443f3257b6d146be78958decf68aa1b9d2de88bc908746c2d65a31a02dfa4ce02af64e38a295d83ecc49834e2f22df173c107213cd41f95e3e0453a6d536599b52f11941ef547b181e6136390ea8e8d4824321dac7fe143211af79e4903846767ee2f2d6a78433fb2af5ae29c8c930d2f16616d569d7824dbec08bb7108e9c621d364af3dd3f56bc7afaa03ecc232c0371532dc033fdda996a5d51069875623798dc94b4273ce6192e3a60bedbb3c0c7f2d487656edde1a2cad5a8ff7d34b27dfc579c8de7448bd2621ee1e47ac6d82d6b8eb90576477c209541c4f6067e7a0aafc1ac90035032d82dafe55f29264b4863ca5ccfd383357acc6b9a4c69792b4e14e30aa08f03854509e9040e5b1fc12e42ac6fa66c32324352195138f0880d86dd83d12b0852c75b5249b91bc339a5ed86f98330d064e11b449be44439a0529b556b76ad7c3405388971cbb083eeadd1b07b67c9fc660e852260e7c6bb686a2c095cd023a630a5bcf38a51cc86ac7920d3adbaf9c99a44b61033fb25e53366c67f1856aa6bd5c574c1b55f43f0df311df44b9e567a0350bc32fd8699f1ec5d2fc03600a2dce51917278f94f71e429fa273662ab5fc250af96b6854d99075458e225c1cc0d2fd5435e2126fca7aa6ba7ebf8e1a74f628ef71b98487bc11d4a3810492a14f09a113e6d191630d1eb4d44ba4d8380844e851e4881f208d21176c3d91509148958c6b5187b140afe3a8ce1380ad66c40f17b1b82a876c7d71cccf2b04b588de6fda296e84a71bad0c228d08ddd778a89bf075ed3326795343d7e0c046479c779d8013d217e559709f2d51a02024be9d861ef1bb072e973c62274c02aa6b6a49502537e90913c0e17c504fd6e6a586209b0452e6fb48ba97ff8cb162aade0f0d8542de017ad79d37979ca42e03c8ae5bc556faf2510661216cd6338e474481656d039c04d48eab98a09f7ab2c479718bbb6624236832defbe44cc122f5c36c1a178c1245b09c7bbe06ac468f18b085fd9fe21ab917d72c92f31e4a5be48bd2490750084eb4ed06a9a9d07ec6bcb4e34a903f013e7f429f25f71451659edd2f975ad0de32e05ae3364bc0979a6aafcba2692a36c79ea44041ec40d0059d5cf73466e174610de40335c9ad48167a0f7512d97a2b6cb335ee992d83b639c01d9a8fb01a9cb9598629172829f8989f70a365bddbb97d44aa990c5947a9ac07e671eefe3c8682017850d75f460afda209e387084ad8e11ed5cac5ec3eea25bd24443ae1869b030d6f41a6ff573048a19f45c463c7d122ec16bd7e32631af79e16359464da9380e800373dd4e5e844a5634bfa129e015663540ddfd8b4da3c5b9ca7f01131e151dba39a208cc56adad9cc70182205ceb56b9046ace1e2d6a244d548cfac5aece3a0077990b9915d3778b7f2441380f9509fcd89f0af3dfe54d44d05a31198716265637d75b4c5088be49930b08333469253f64dc15ccb9b995e15433d0087eb869b9e8d4dedd2bde5d1bb4eecea9b20c740f8c190f076dfafea718a3667afd9d8d9e2b2ce668ff6d346685a307d44584684982ba84cc3e8a213e005922b7777c50d8d3720fcc5649d9219d065e98d212ed5e989d10f96a7aa5921a5ca3f362c30c89d805e81f96922686377e4bcc5435b82ca75f3587758440af27687a408a0b6a15625424a9ed21c1ef58c7162d7a703bf5e36c061111adfee4c099351537b5d2a355cf4be00cb17832a03893de4543931d1f6d3ebcef84ef61f5f609ff7fb9f85d2793a787df83604b88b2ff7c6ad2f6598abd4d39596271b930005e23f602d042e4fdfbcef9174fe0c2b061f35472db3e97f10ab09a1f4dc3565231b48d39e51e002e5cd644a08e18db7a3be901b6f52571dfea13e6c7cfe179b52f8ef6423e3919905bd5e04daf08827c9bd13f6e1488cd0a04cfcd850443d5389c4ba251a3c06365e48cdc1ea5c2af27d262eab393745d1592c211b8dac952a930c3a2e24707537033da6f8d6c2e8fb07f3b0b0e6caf8aea09c8a105a8b99c2575ad3a1a4d7667e7344c1e6bc1d247c65f8e9770fe0c7a9951b645167c9cd1604abce2fcfb9b30dc15cd9993d5ece2203dc7a0a8666ce3dfe87c2ac8a6fa67a684e012f0a9bcc5ff25cb334f4fa9a76ad3514ff5114664557a32bc55643851f21ef644b0992d4f28e533b3ca43f8758cb88ea7f989d96dd91b965ef639ba60f14b892ab6de99bfba5c437dee44a6b5c485be7cc82d4a8ca08bb0de5c7987122a566589bc661e62792fdfc168c0fcbdacee2add9789f2e5ebc0ae92d0a235ecc7873ce1b40bcd74d1c3b6d5598aa0ed5b5f5007e293e395f2c2921a6e7f446a836155e4cafd075b2f3cfc60ea07893ef8eb40b9d59309b0601e3df57c2909340ce8089e9ed2325deffa7b310cab43ece4e4d0d27c773c10075228ab59e7f8182965abd0dcb6b652050b2d365e7b1d05f649b19ce7b62f47ff95a31d052ad4ee397b2cca64e292c6cb37dacb1aeb0f547ef44c998b4b1d7980441e01b7446e164fc643aee74afe9a6c5a8e69a0a34f1829750167641f1749da69f44809109a2a4c5d0312929049f38f9929fb7191ad69eb2da3e357757973d86362bc6c9511a347ce88106bce57e35c4dfe9a33d5d76a1a6d7cb74766356456b7a15a66b7d2e483647cb594768c48402704e09206985cd644a3e61a51bdf1c1f451a55910932e37e1d11e7e3d60929d96a29f93c7c382870d29deaf4666f9c6498becb1dca7a0f03a63998377b82d587aead568928700b483b71483f53a2543c1eed3b9b4bafaf2d45e10ff99da3943aa77ee5c2e1a84a6f0578654ed576171308d00096ab25c93f244ba3104662f94298bcb6a7fc1bbd7f3bcac219b574146ef64bcf0cd1feac4b74bc276102781f62ca04eb2c6d085012e0d06a2c2412ab1be32698f304d73b0a533c64920d8b33530b65e16fce14b4d615f1bfb236fab226c9c90b9448490db19bfe5d529963885ff0938a175e112d72c6c4327cef3f44702cdd7f83ba63ddea8565b001d6a23fe51eef3471f828f5568faed064ab3e2390c86882b5a6ee8782f0ec6c37d98acf968e5bd613da46c36bbcf9f9f0707590a19c28a509b27a8bfbdfb730032a64bbba14471ebea2c398a506612b785922597ee76139034cee2ff3e74a4d1eeb471cdd7f43068bad806a26c8d86412362793c7823e1e500fc4495399b0011a6988eb76f3be8047a849951eb253ab9bc2767db88e5cad1100b1fe331b68968198a2e033211de0c804009f95c409a4e13210a30cf12d725bae62b6f6ca513b8e7d9ca8eb0cb9b646bb178847fbd01b44b4fe1e6b15b0ab7c2962874d5fdf70a455f03d2e4454163e89b20e6a1d8033870e1e177cc6d856457c3624dd76227bf6b5d4f0c2243dadbc11235dd58a95a272903af1ee6671b636d8f47e90bc36d5c6e070d9067e7d81d504f566d040c3f193aee5b48195fc5910ecc4926d1ebb121c2d451d3e99a2386a69104bb5c15171ddad5caf8e09d7a051b33c1db342cc4ec3d81e59ff6f19983a44ca609a48d86a053d635ea49fd90b0bbe55be786c28205cbdaee73e6ed957f8e93b8f2a9209555609d3346a1b044750221bf76b3d1c10504ab8aabb28c0aeb89fbacce4dbc40afc27e0b3b9e86a3913cbcc9bdd343045e0ce24e72c6f52b6852683fd9a61533e5994c107ca65a0d81d4ee5322c0f7168e4c2b32eba8a7fd783eec9ef68d7f20950595988bf1f857bbd3e184aca1ee2e7f5f71fd30a1075e59ef1103345a8835806dfc6a8a246dd79b7551c26a9b16a7628dc65ea8c930abfc7a7cf04f1e475664e1373cfe6ca0396d4c750d114081f22d33d7981eb536e60ed2d3ea5fa72cd046c5fb110fddfb14466f0d8c35b2658eb69742505e7d1d4161f1d4c1b9af6e373fc984baa35f81392bbfb56c201ae31e2b6fe2a22680802d51d9ef98e7ea830eefa07667879bc93921d4bf4f117fe0d328d1586ad150b58685eaaf61e704a2fc6ec854d19ac27a9d236d88a1fc310c23255187c88a5e2f7684a02098fa671d68a592e2096466c5b87191efc3163193123feeaaac57b4fbb7d78352b01f5ddf29563946a45c325c74c70e2af45167619af91d10088f0699695decdea4b41d43be14e0b0fc95c150e122d56dcb90ced5efa1ec926bcb5eb55287c855f215bf7dd0159a7cfffab8b8f897ecef49764928f3792c5e100c8a3fa3044361276a2b987f57624a509b2a119c12a678d25791101d182af43f1d44749055116496fd0ad78598cfd78bb185d0a5b02fa302f3559a5f952b9ca6e639da088792470e04ce9d76c431d94f0633b7c9893c3a72e01289b8a7573e60cec814bd2e2a553eb1728a9f629cc9324f93f7e440a11a39a437bf3ed1ed4ae684904cdc4fa3546e583adcd55d48a8d0ad228e4eca534dfa0cfe35dddc7b817f9a01d9da79ea45cc49915a2935d6226b7e0b99417c55e29c070eca6c394f3994026fdffe5382a05ef7e348dfa260c790b9549d5ee560c7a83c1ef7f413a46885df2a15f14d81d83d4fa51c709d5ddd62a34b6a8d531e04c48920e525e98875cf188e8c800876a3186d081472c3e3c5180eb3f8b1dfe1b2bd18f271262211601f7b0a7ed0620c5dfdfcb981ba7a33b8b10af6995bf36b19889b9938a460659e2454ab63e1e0d423ad0d984d4d3c0874aba21623d301d12f606fc3296c427dd4aa1bd6dce71c0f8b31b1c2be774382b8db3f518ffa883b97da0dadd6dfee0a647ffaf1e89515ca8a6adeee729e35a3a3b43cbd4826397b4b7b627e41ca18eede322eada538090e4b924104dfa67909d1a4d4941ac4448d911e21c6068c8d094fe3359bc8a26ed66962bf618c6c93f9177d5f93527789b89ba3d68a9e1b467d3616e26af40dcf7e8e71e6fd1b88aa1340ebea1c0e8ed4400f13904be8e90cb4af01bb7be6b8843da9f878948cd705f2db20ff131ed1cfa4695d6352b78a2d9bee47e45f19a30cbfeeb561853cbb0ccd307a5c95c9824001f9e74ca4cbe5ea9448f3ad32cba1087603c3627ec1c11ce2d2a8692240d650735dd67199fcf92bfac80b38d535d4c40063632bb63ce185a3c5aa992b7a28b761f0683010d3a3c058a07d8dfcdf7e9714c9c639cfb4de8a8ee7bf4efff8c5fa8ded4d8d5bf9e00efe6edc2ffc87b886a071b6e65465192361c76ef37897f7eeb2d13fc3ed6fb02bf2b9b7dc973d4a5239cef90bf5e60fbf5d6fe601963d3d39fc92451d5fccfe61d8873bb2ec8e386d2752f7d3d64f3f01b90f6a8b13ec9fdef7842f7d7efeabb2e6dc7a2279860fb434b71fb32eb73f0f199ed35e4832a03f1409b38eb0b76df9f885aa7d741f777b24feac604b4dee56aa9412461c5784182c78129ade4459596463f7f53eac7e8eb8b15c2747a3dd1a848c6a5ce7974a54d6ded7b739ada83925ab0a1c7cf2cd2a1871513c77fc80f8ac1c8b12ee425bbbeaad522e8670902a42a597f04db17ce3394e0a1423ec869dc9de9f790da539d84cdf51c4b98c5803a02c6141d1b42c2fd896e4cdc9b9fc2854f5d67da69304f70bc3c4dbafa5354a0b896c60de031a0fceb8d8c1c2bebb7ebf1feb0d549dcaac1ed75ab7e4e6ca0842ba63a95fb17ec222dc836f37171981b6b15f6680a67bbead684b46ab654d35843f036b0a51c24a73d0ad34104b473c59cd7f6083cf94079024b5f18d50b9515dcfb63b4440189659718bd1e288348ecc7df7d80a9e8f65a8611049fd9d8ce67e831283a524fa8893c9d0d907c05fb8ea777c015a1b707008dc17fd1c2646fe9e85df960eb1e8c00e6dec6603ad15190860e1f1cf1f61a332f2df442b7a48e59fb5914ac307fcccd938ab4eceafd708bf0fde6d8017ac1d2e00cdc3c240978173f357d0f80847edc43d1498c1368e8251fe4ad885606a0078415e17dd3dd3ffd23d1385c5a02fea1688941bd1dd7e547001ae785bed2b7d02b117b4b665ce3306a37af2017009b41e56ea7b23e8a7c0f8ec0766a690f0d8dfb105156ef8042413af70ae21d1e75bbc6cf8df1017a144d736241c745774935344ee98b7c964c2e522ef4d2f71f7560704a505b14fb90e5b1fabe63b43a17c3c242dd49c46135d9cc8e1e118d401b64410fdb89d04b851870846e68db8351733ae52d52bac06fdb52efc13c8ff37187a755dabfc3018f6efc4fa1fd06aaf544f0f2333083af3dc6f335a957824187d3988ba57e605e43f68deca71724add64be8cfb852099ef7382343ffc9fd367e881f3b0aaf60f7c4d7d5c7b38f687be5027a7d675b827e4aab8856986bf77858fb039a83dc9cc4b10d281a01b026aa81cfd5ba674039c9cc6301ea3a7f32a4f28bfb059bc530d5ffaf4192a0a9eb0fd1137380a195ee1f3ffe308843862a6bf97e4a071f00791d7e7ad63f83ec2b22e3ddf41437fe96f1f32068481d3108e6b47849641eb7dc8e969a596fa374e1919517129d9d0d6d78056508c39e0df6b9eeb2982c2d98033193aeea3ebb47d7ca0663caddb4dcbd63fa8f6fe4e64427bf2ffdafdf4b89bc2625f4e9fb31e01e894321a337e3cd977aa1dc8fc5fe3fba2d504dff188d77e898ab92cf566377ff837fb106b8bf986c903053ec44f263acd65661423d30c33821061f32e594110ff80588f33315b06f6bb1893c25fc0a031cd0cbd3370f532c5572e06dd70ce7f3e9a1f0595c6ec10f5de3b2de433dd9c99e5cf1c6ee3762f30dca011f14be2629f56322724fb5f885e3785914a1bcbd017bef734471916ea0fc99cf8fe21fd6120ba7fcc1466ed1d7d570ae0e4e5dbc7602331de15d9ecdc821d65d79da065a8744cd47f37eec88287f9a1f3e8db1fcc7c88913afafdc66298b6f126fd1bee2fc3b0735baaaba2a324d607ba179b396e830e238d8d884e8d7bc018e1d731170dd447bca53a2b5a7bbaa8fbcee62bfaac97eaa96156d67395cd5140e54c2d2a2af27a7e2441758528d65e5ec7de319fcdab11ed2500de72962e81ea3d297683045dfcd54856393162bd9fd2a25313003e10d822011f3d30df0994a752c692c6233f60b2c8b3c0529bfcc878685bdfd1aeb6028971a0b16b86dfd40f6f34943cb19d1230e2ee8be4b346748377b4dab8de3a2456c22e06e0c0c72a54207fb0896fd02538d305e53d20b0ec8b7c8d506cfbace3c43a778f9e60b076ee3f6769cb070ddb077bce84044b24d69a8bdfd91738f48b62d1cdac43f20f7f56ec55794515eed0367dbac7d45f2afb47c04491455d41c5be1b78c410bdf11d4ad2a53b4c854f9b111babb072697727aa0ce0fb907f1d500f8436b57fae4511fb63eb9f84bb327cbdc939476cc577c11e6b4fb6c02f5c122e541003e2feef34b763424b3f66b9600dccd931e38d2475b0edb929f1288515b644abc3327e2136944d835814498caf7553c3f724d4c102922a772db3536562766d0b06b8453ad78d139d426ea5f882d11d24bdd728e1432ed77c77f3fd55b740c29187dd6f2a12d94a1a9f096f5cdbd00d754f24a23efa621338ff70c9aca84e4c8673e6c20c630d3e315c223fdf15ec03d1968a67b7593d1fd6676c5b586a40352270eef173badbc307a6be314255c84414134650469a960f0978dd09b711ad5d1dfedadfe916503e9c7d2b31b170012a7192916e54d541ac5ca57a4571c5aecdb0894084d0b95fd4673c630f7b5d55681174526928b8a9159fecd90c6d8e50c5f2285c1a10de52e5a3b8d273e075bdf8eeaceb75da6ad8120a90e252d9880271d9b61469d08c8fa02b4ce64a3379c1bbfe1fba817488ae9373e425e0f1974a9147efa9ead2d4105662eda3737edea4c9a63d17a8e567aac50897a0ecd72906c28dfc2e41a5df5dd61c17d7f6a60604fad402c8cab492d26f551585c095ce39c17e0fc598a3140f34aaeb6e486b2ac5d458a2f1cd1c54b503d34623dee4b93c9dc02fcfbab72f621cb0e90256ad537da4a4afdb38ef218922723d1551b8bd581027ac79c5578695975b096d0200d48b0ff1aa6548badd57fadbc6b60648a4f8f4ac2699d98343e7dd3d0632c2a0cf7a6b3813a0e21e8eccab9cda6a91dc71c3c42f3c2f564d9a998b107b93211ba01ef7abe7bd8e991bb15daa16745427db628ce4cb393599bde748c1731260609985c0e1b3dfa512a42f051a7510dc3e26a387ecdf236569ea6cb1b469a72336489fa5e9576c3d93fbb9d7e4b44216865aa75afd9c27c3fa497910acb90d1e36d3e958fad04fc2a4f33e25148ae183579c210fa8bed9aed5661943f52dbb362e25b036aee90ea2a23918228e466e645d878670c81e4b1f2669c1cacb0585afb9db3b64b7ca2f948a48d8204fbfdb2994e1e87a7d2a8a7bc49e553f844b86cefb2a414972f2a95b6b7dd650b18298de4122a258414464a5df39e162e4cd4d4de5aa5340605813ebe403367d7f157a93793f595f53aca8e2a4d7ee4074012a02cb5323a417d8eeb494eb0cc17033de1d08d65c4a4f9ddde4cbf28698699cc94163a910f1de124935da8a45019f05898fd4fc183863573b1f0d67572e29f8b97d6f2472f8b711b7cf173ad7f50d3a810e506a2ff93e270281a5ef40dde744ca6ca4b71e811c76d801457935455bdcd5f855c3d29d2a7d3b9d78b5c48b88df16362af28d795643c440b4be67229f7ba80c4bb4881cd168195b3a196bf2e5531c60d60dc6793fcf3866d691cf8cae131be330ac3c01830c027ccb88d1527d6425fc37f48b27e8afc958e277c4113910103c7d274b61f22b4a04f7b0c975385979fb794c20dc9b2ca5f8cd90be81aafc8448fe77ab128f429740b51918408ce4b4f3c05423e52a0347bf44ef670812a7a9c1a9bb93ad9854f1a5af49d0bff294229004042f513808a35fdc15d07533ec9f551ab32623d2dbfbe12029110a141e179e4d2efbbbd6e4212fa114b78ee6ad47d68534d195204d625040354bcfc573e98073d8bdf549a6d3485c382716bcfe1ac369898258ab299ab2c1d1ec2f3d79482903038841b46663e68ca4d6a4789f0ba25598530bdafd0783c2bbcff336a54a995f8f67d092546acc1150fcdc49b036bda364c1042cd0a88a19b9aa890001178a8b63edc7b773707e26ffca4bebd34c8cde6362a4afdf31eefb46bd79db3f49ade0b7a5a9e134ec2c5d0104d3848607b04818f2d42c7f07749c4d571d550c5023442af41bbb78512eab19f8f7674a126fd20467509033cd228564d178596f90d0c55260a20e153a6f5c6da7e1cdcdbc5a192200bfb1715311b7ce8f379c802673459710d3d2682b1ace45be05d605fed6552f7f77a6de7f6eeab7da6e7ce8f78a69d67a3fc478bfe9d7fece3df9f8a13e95e0cd73cbd49b3e371230cde67bf52a34799f978baf0b5ab12e5ffe67c2f027a8cb8d59e610e749a61eafd76f165cfc1649ef71f48647b7061e1669de833b89d8b5cf95e3384ec121a1b741b13b7430ed13e5307ac34fa1fdde82ed4f34bb3164292f40a57dba8d8a34fb76816e746a2c1b85197dc3081273fa7d23c6d296ab2218b76353f59388064cca506d4d95e486ebadab684e182f53a84d851e0facac28a7863c485c039e862ef22a152e74c17b250a9a10db26196755c0938a193ffbcc80e62d93468ea1998481dc5062a3d89ec69a2ebd7e3cc9d739145bad5a421896eb7db228eba4d5869885a212a382dec9184fb2bb12f43d4a175414e6eaf22f5c77ddb3488e539a920284462ead356142bcf3041cddcbeb22cf6a8f9c5261f769f22b5cee8f77b3a0580b44a8f0a72ffdf1251abc5ed4926ffc98851e150de81ff441238c21a8bae46611d933c3fbb94fc198502fc0d639b45bb04137fee531b1cf9ea4898b52fe3ac9f0ef9004831cd34490ba5b957070f302c8fcb117076f67ae27d846de2ebf9bd1ac7aba319d39f3b362c774a666225f58652f7dbede7de62e5d5d0858dbd5c90be6aa5dda51889584019af8a9ffdf3023f686ce85acf977a6e2cae426bfbc516c432f6cfe1bcaae638808e992e1bb47b3fcab9b00c75a8173c74f589730f38f4d6087b5440f413f12ca5612e095125ac4b300e424008c16f6fe99898d129bf596bd25b17060ffb061b3b00d5c43454bb21f063c7b03d062cbcd6be4ea4a86b8deab28c7bfeb87be73c8a8959890216864a6e34a58ee9ce02d5999ffc9decef9cfffefba7afaf3d92b490efd4a83c3483591a2748b66228cbdd1e7420fd46f1d26b0d8dbd83601e15a5d76087b89fddd684d211da4fc42a611ddac22dcb3cf6d6fea51dfc20f0cd3c3eba248ea9967fd84c248ef6b434b16e0b50447329e1ed4ad799b1a0e1e89dd434cecae57d6949670520c67c9398ec2220a77efa2e1893420bfd9afb9d50b2d8e5173236941285a45670292538054ee4fdc9effbad56206d54a78ff9d12916ea0f1a44f8169e209a0a3ee0fa71fa1153ab5ac683770a1d48e59da4ff59a8feb9c364f7a99d25aa57cbfa45b76a010cede3ec6219965f0550bc1443f8c6010a8298339343a0da30712d740cbc81d24fd937674451a1993bbd75aea251f0b43e76a4333aff96ac2b34df28ec2a9fcba1d5a87884ee61645558b3074812f4f53b0884ec568f5d8517cd01cade1e903f784c6e78869bce9e2093253f6407452ec3ecd9657efd68191d648124c2392f0597022c91ff866a946a2a1fe2cf37d61b99ec177a85efc6cda315b1b3050bd70186123a8d1695e5d927ac39733d84024910da51c09a72aaf082471980db826fa885d6aafad98aa269a65cab6b0b2f992940c0fc6fc1fb6ba1e1d79ca2bb15c0580bff044d6076722dcf7f8cf5fba79411e6319ac2686fa8d19298074af70b8bf8a241076ce88b093cdc27699b66127a3031be25b6d82f0543a5006033d02d5678a3870635f651351448ad649e90092cbbca12fa80262b42a9c2903454e30d56a1aa586d20f2494347a5738cbb5aecca0d6b226a7be8a595337738b70ffbf523f47c815732b0c02682e417c3bd3f3d5984cc04daee30c98b5d497234c12f598c79040054874b3ea8e01d91b50080a498c2025cb49d590dd207a6ccc7fe26321814095f28518458d7016925b4b39413882ea1fb1b2580e58fa7e69bd549e1b0a1648440ede71cca2d68f0fba44283f498c3c5acbbd885a187888050677f87728a62493270134ee7ab158ea1da10e82f243908e25e8908885a2746b8e448d3a02c9c3d0026f36780c81cf052efd83b1c9ffff815fad11688a308ce38e52c632eb9e4cb59c26e22e8a01d8cba3148c1f7af3ba17597cd95a3c9b78865fdff3ad553d340782be52f929d83f6f4d6044ae82731e51ddc9ef43bab1e4ae9a22bdae4e98c7bd3de47efaf2dfb54719408e404da99e5c834b5f3b8183fa553fefccb5f2bfaca3a4e5338a7810b4fc1d0f97a13403c7599a607bc7bd121beb627c83fd37283487df756ea7d38b8db9fe57ba7f9ebcc6cab3ecc7d70127a0f0e80a111b4309ee7a6118085cd548e8b797bfe2c4570a9ebdbfc2c44cc8852f45d3f7a7e6778b553f42a24c6c299b5fd959a111cb9c97b73c23a13dd7e22b980c645e40cdbe23d0ed56dbc18b95d03ae0e698162182c9f6ba881a4849681c3ada9fb6c906e7eecfa39e3d43780852e42121622f84235255fb3f7db690db4c3d1fb8d86e8b8c4eed38e05864fac37d926c0a29c4aaee6f316e37bdedaf8eb1fd3d957b9d0a24197a3539bc9bc76bb314bcff9e84db94bfded0c195e28254e6042e6a563e8bd12793134a919d48d012fce325c9ba590aaef758e70bd43757a60dc65a6a9138987008bc14718be687ba42bdb10654a00bc4a644f65e00a61238e892a70ee5d56d89b1345789a6f7e5000c82e5f9763385e62e1cb0864e1a2e89a7be3073adf92c4e8854a1b336c8c5414a768f3ab4a9eba29eeaefc1f221ef954297e597ba3615d3e3792a332ac892a0899fb259039fba984484cd435c1d8bb01d4bd3e63581dc277440eb28be7f1966315312ed1500e9b07a39ba5e6ad63ffc146f1fcda7aecb8645d2a29a7a4128243041bc1bef1618de2f9746160f47c28f6852e466e2558ec0f27607e9ace220347b6ee85d443c8865c1c782c88f2cee8556f6d37b7a1de249d3a3c52ad60b4c7fc83fb3124a6c7da2a1ecc2e9a1f0a17a5568287e0404c60c9b108cb381325606fc88043352579b5e3c11e84478e8ee72d9cd989e4ff6e3aa1234f7d01b6cdc03fc7c7e1ce17bee16878301c8d2de0f64de9bedddfa953e85570aabc00df6c5e8844c4ae92b82b2001c16a60d582f960e73514e19a1d7d97fb1cc82ebeb0acac2c1960c8144a571076c28caaed6cbf89f803a96254ee3588fb6c5169025046de87a04460be98b2f22da176a460464229239549091ff904654dac96fee466eccb16247b4bf75b0e4fd1feac1a67548d055705e75f82921562f76c5d3fe9823c76702c33a8b0dde91b4e9de9541882b6dccb1d4bc1fc8bca7d7bbf5e930f94caca5a7d455be1ff3a05b3d3b61d6c5736b9ee8451623d443bf977f558f425bd6b9ffd58cabef15e5f6e491df483d4e1fa493d5415ddfe79e1de7b0a0030038ce77a30822d93ff8605625319f6d363f81d237836a2ea2eef526c53c92d7a43100f0184195fe42e0636c0d9e7dcba9f69d905094cf23510a63003a30d874f7aa670566d89ecfadfd4622987d5e4ba5223828cbb662ec7c2fbc881f427c354261d028688879378dd18a404fd82784e63b983968f3a8af2d76ac10c66f8c8cf336bcb4292ae1bcf565d0ac5760f324bf0a78084515c034b32c8d71fa53f670d0cd479c43f16aabce9febb19edab9b60eed8de41cd5989a2ffbb5bbf1e32936f805e0e3845abeadb68c05ab6b8205c860b73f76572c45da3cccf247d89249ba60d3c72cde0ab3ff9ee1b025b3948adbc6e02179905eb6365be80ee3954ef3a69bdebee464ad0f1a49584dbc88c496ce703b18436259bee9eeba3596a13ffbdc222103788ab1d322749016a8879f4840f52841f018f87f09efa5dcecd0e34932d73fb92ba4b9580261d82c63eca0c56b0f1a6d25d01b70f661fc0f7d7ddc84f14d0addddb46d8cda3aaf5c2a47152135280cdc9bc45dcaccd52714e209f848bf84d1a43c37b8fdf9f834334f65e4ffd1f6f18bd3a0479d008bd179c9ef18c8baca0a2dd1e4d79d85858304dd3b61aa7d5a69b3910780cb355f8d01f33e13f4335a95a21a6729857bf1b2397d9e2ad270739354cf8c06a3137d6fb74b872ec25ed45534881cd5818e044ebf5b540210913abd90a0b29c28b69d1856f01e01eaea889ac3f67e058ea8d83d5395e3ca98a89da33eec58ef9ae016956c3c913a647632e87bc54810966d85442c0050325cc681b9122a2fc5b842860491fec9eb277a0dd3ad7958d2ecf91bca76bc0374bea8a1caef412040258e846f2ae86aae6edf2c96c7f6df29b9bbf1fe39249cc791304b4b8a886adcf68af96bf853c6df5a1c3d48289ea36041113896880178dcfaf39f10422de08a79af3272a95621dbe26231e5e5e9101d632291231d127fcc4481f6238640038bd525ba5dc0e18b57661569bee11712711cd0bc4a70394f55207e7464c7caad5888e680baffcb2810c7d1e95314e322b2dea7e024132565c788b293162ed4b586cf327b7c1f3684161d21186f0e3b87f160517884e9f2c9340a8f485ffef92129024c15cfc82226102e74560bd567fe2559b679526acf95f6b8a75a0601b81a91dc6382f59f912bb40211609d5d8cc201b177e7695dd2a8b5bc5fa7c19cd92c024107dce6a004d031f217d68d86fe4685c850abc2fd0f34a6b6bcc654317b0b125be78b863494ddbf6519b245f927a4673869f7213c1458717c6fda6b884862e74b6523de7af15634197513fa2b4706da848ab6bf8280de1fcf7dca7d7b127075bea38de190a33d7812ad6bb09f05dd500f75fa9a1d3eb76a31262f690d359d82e437d4b752c4c904872144c847f0c7cec02ceef18bbcffea4f7b79a966c6b566bd0d5278d48ba69a2e8e286422d8df8647a78755e743e06bbc19cec962033237b3134de52fbdb470be8c6f2de7fbcb0619fd679b4cffd9c6f830bf0f2fbe19fbedf0d8f9ce85187fe26d90b3af33de3c6b7d269c1a6b474088596834cedd819c29566442d925481809a5c6b4177062179634d4c22ae52cf659f28ce0b52d79ead2b242e74c2d7e4e30ed7839639a4222cd41b90e166592ca0659449e6a6634cdd459b24487757dd2c21c77f6df3ec3bf3ec2e2d387b0f9f7115e3e834e4b58fb3143e564a689acb3926e42062ad3d4a4e6b0a455dd81427059aeb8977ce9f16e3f1b51cca924d96924abacd385d081cc1435d724ac695957a0094ad3d1b2ab3ee3d0bace40117453a2998db18a357bca834bb394230b9b63192b760725a0399956ba348d452cd889640fe592d9a7794a91810db18c25bb831c109c4c539ac94ad6e92454a033859a6b0c2b5ad725d004d954b4540293ccf7109555739550b61be7fe4f4eba0919a84c53939ac3925675070a4137194d6c8e9558b333a880e69434a791acb24e17424750e3bc1aae00be0f86ccf0699a5264b349ac63c9ba5aa0074dcd764f39ded9f7248184fbc73575917b750977d619b7d44d6eaa8722a0a8ad3148bbdcdf5cafebdcab4bb8b3ceb8a56e7253dde1ca2a742c21ee650c6ecc1c6e9299b89629b83393887f64ade69b7fd83bc9e214912771c7ffc63f1eafe0086b5bc28f082e5ec50dff10d7e8bc8fdbfd092eb178074f585b126e05b0b615f7fe437ca3f33aeefb27e147a3e5a5f873c6c4fbb8ed5ff089897770cb7fe10743dee166c6ecd51490eddb390e4ace73c4fc1f6b8b8cf9827d49277cf18a93cdd959fde0010f925ded112bd606cf3044294d4948489649e5bb3486bd5ab11fa6877828302ed88ef0f3ea1012a9c89bf504ec3ac41e20554768931d9f4d430457f5ee328c897c4a044650281a3c60d1a0effd447f59460569a605c6fde96aa58ba462391e6281c55872fa8c1e5ea89deb10c3b21e8a41a09d52a1cb95c9bbc2b30fef0a0cde320669cee13566186bed2ec1385ac7208d6cdfebe27d0fee09dfa9e73bd6594a84a343f41b6369736d6285a7da9cb5c97bd1a77b56ddfeea0293658c6a7ab8a822d0d928237b5376fcb37fbec6101e2be50f2ce0dc4e9a390a62ec6793e8a3ddb5a52f6a04e5a24611d3526c86af495d23553a16564e4c47e0896825eff448b00616d7d47323d4cd928b92ca942754a2e3fa3e0025dc855e2cf29b51aba72f549d44c1f737bb9c2c5594a073c1673a9dc41777b3bea2e5b7e01f8cffc4dc2344dd65b5ee655a95a741f750c53c74b722e582528b03d3637f78f320a84c0eea6dfabc1b095776570d3546aa9f695138ee05aaac3ef8427320ea2d225e279fd407b68ba4e017de3b4957a877b1080c2f051a1c6ba5551048cb481dc419bc348900023f1a70d2ce4fdf84b8eb9df6510e60c22b079c4043120119812f49dc52926d915c2b2169114b646ed29e0609211eccead0076a416c002b2fa01770a7fa0615ac3aaa63748516f17f0adb09130a980a3838aeca18bc5dd77954a53e9a51be0a3df0aebace697fbfda8fe68b65ccbacddefdcf601da65de797beb5423e9a2f5d12d2757eed2c530fbcf9ffcc5b2bd4986cf0458d243576d4f8d11da57ddc9ae961c6872e70edd264ac65ecb3df0c2b8d308d6fbcb75b9155cc26b355893443a58b31a7f3a75599fb99e50db65579976c55da23a4afb6a85a6aab12098d1b62d2194d74b7b3a60b86c12a366798babdd9ea9756b42a9192eec3eeed06fbf0bdddcca042c50c0194e18332c69421a68c31baa3cfac4b57e1f06dfed9ec3ebf024ae424d10f61cf6bcd6a7f6cd17b20d2acf6a7525b43a544d622fdb5b224a5f740a42246943c8c2fd1bf50cefdbf507873ad94087bb652229c2dcad67befa3f7655f53de2532fb2db942352c3dfae3ca9268a88665139c9344951261fc9277c9d1e37fa1cfe10fbd4747f86d32fac2e13b9917dba39cfba29cfba2f09de0fc4993626c33d89add274a193fce0edd3fb22f2cef926cbd24fc7368ca6f72add03c4ac2e13bc9b92fc24119cb218cbf7e964393063d96b5a30c1acdbfd1bf59223bab2e9b4c5e5aa593ca3e4868565d299b31a234be343dc2bcd336627889a1274615e3bb6f6ee8cdf5fde6c669955aa14fe9055e3aea2cc16c86e52c4d01d304992e3bc4a0bd048004448aa040aed140fb73fbecca9f245bf993e623e54fba7d76c5f09dc4f06dd70a11a28ab7cfb7cfaed8c2dfbf13bf471eebf44be7579cc5940747acb2455569be4d6687f287def7dd3ebb3c9974abfc921e83eefaa4ee3d5ca64386b8cfac0bc98f85e0a77456892b4539ee1ebcb9f3786d4c4d95272b8d6294b31c83f2e806e247aad62659fb82b1f0537ce34cdaa4200d13001105036cd077809d04e80691d66b2608d513021d700446741b33ad0292259e4075d37ce145172a480117345b74d3a0a09b468b6e9a2c684e1047b5b30faa61d9048661f6fe1518be478ac49c556cce07fae8eba32fdc17b93efa8a2f843ffa8a1fcd9686b3f3a3af88ef7f1fcdbef4b42693f53f2b3f5ca9a4b53cca2c27bef199f7387bb1f7bf5dcad670ae4275f39344f8a32fffe86b562a44530023badba34cb24799cc479af4e768d21f2c148045cda4b14963b02b76982efa933dca247b9489962068a2e0497f729228d664927a3497feb119efe370a6b59fb53cdad9ec2988f112ae56a852a248672beb37f9615b338dc63e866996f28abd334cbdb791c6eced66675428769dad46422e2197f8c8eb0fe524518cb7af9428563b9b579542799486278d75391daed6c3980a7761ecda8c3f0fbdc7577ed867f6976492c7db673af384132350a17193fe5cfae596645bf4f466d86799edfdb2bdfdf43cfbc13e10663328619e857d36cb608fedfd037cf46fb5b7cf343f9616e67d1f8865f47eb0fc2118bb59fc38f9d10cfb8bfb0afb68fe6886658fd29e1863bee7655b675eb0712237be11e360ef8fc49cd50d4bdc8a0600432278234b1a5d9233b11fb8af3d941450a7a8544a7c94782a37292acf7e88c5ba4679f643eeee754a023c3729cc0727c0a287133a28f199bdd7c3014a7a9c086c7ad64b05783c691f61643c651713f9f06841135dfaa7ad364de41e22a0e32b25f169f38148691b1080b9e1e5026a1db580bcc7739336089e0d088874cb1b0e1675b4f083046614e008160d267cd122c7e647005f0837365b70c084b0e504590a5bba1b8709299070d1dd3925a460730c2055595c701b264ac0305aa5b78ba6b100cd966e1a22ba692ad0365e9eb0f1d28566886e1a217ed050a0bb939e38f9e40df67f73ec9344fff7f533dfc6cb0f9a0948404b10516880c8d29386668a8d07c8687ce377cbc9dbcdc603583acaa4cc03f3fe9267f1916e1b0ff858628d25ccb0b7bf36cb2a78b3ab70ae7f731a5fc2a73d4fcaf08d5dc2609b2e46d41061d3c547171edd3518982140960b588002361d38e24193a569f5d2257abf9f1fbe6dca58b6d5d2283163eae59957ad27417bffcaaadafa184bcf28ff0d53fe244182eeeed136493c914406922022891cba553e74f4721f7af272157695d2276f3e7fda6e9a1fba697ce8a6e981c70e56a620510211708056e5e5d1f11586f114a1cd87cdef217600432e3cd02aad34276f2e7f89cef8e89623061b24b2c81fd84356c59cd4d0028d378de7d96c4cba6964d348a16e9a8ea6a3194233e48e3b66ea98a923d2c0984b4bf3a4774b867e5a4d805a4b908a94b098a167ae68a1674a3053848117bef131b06383012246f4002f790a158d80626344ca8801747b9e04a2c99beb3d2a976455f23c095495b22dc22e4f0281718110ba3d49b34f4fb3c0025eb28d05ac74871ead66d95f1a14e463b3050536450c4002a12e79fe937830c5f773efb323f452eab1d9d2753b2be64be6d36832f648f7eb7ea8f32ca15099ff4ecf7e2aec2e7894e577954e11558e8e5feb39ee954a8cd155465c55c4553a523ac73b478a449dd0cbe5e4142982e9928d5d70becce7774790384dc63c2f85ca4f63b1304dfeac1ccb661da6c9d80a77f73fef6bb6ae4be938919cbcc5146c885341b912254e45c789b84d4a8755f865f4e6bfd9a7b9ccb79b95fd7579b514c85df06871b95a8bc32ae5833c5d94165152e7337bffa3defdafca5c65be5f6e89bbe091266319fcfad96796055bd1db6398df57cda75e71a6f826674c93d42b8d5641b779ba3068e9954b8f1dc3e2cc7b8fca8c3b9afce96832469331a79e57fad3d616ce49222966b2348bf58a81b8a6052e4d0071c40608158008a1fb87357e28e3872b9c855fe52c95b3f04c1126f460b32442f704faa186279512c5ae739bbd028e8b704e12e516ce0ee57e5617bec92b8f28ac064c0f45b8c70e363c84a184fba2595d93c6aa92cd606bd29f1a356c32571750c436991dca49a218b1e3ccfa5f52fce8ebfe0cf2585f56a98dde9c52c96b515e2d0dfa4993622871d7ca68fede869dfefc5969cc257e3a6325ced4c7424984729f955f9f954b998a27e6d743cfe3a4313086278da9306ad298e39b9c7bdcf288dd7966754c3df0b63c1e4df993946d912d9af68856e9a43fd916dd97df24dba21e3c39393aee13c3ed630a9a7b1f533cadbee7c99aac7da030df8af3dc3e671eac4489cfacebc4af16e623063ea414c9968c295048531540492fbb5628683e4ed65ef36ff25ff3ff8218bb80b0007145cfc66e21bec91a715f73046de8367b9c2fa34b5caa0a72f9b5b90b65337b7f26a3332afb0f4fcfd6bc3ace0e29d5bf62af90bd7f004ab4642f0dc2b6a85ef0677aa085a204ca0844402a105298a94112e166670e9b8f88951e423e5cf727bfc62ac015dc2cf2c4be9ea8c8128bb50a4960135e0943c77110c98300c346038a40e3072c68f01044b541b865279834e90493725fe494e86e3bc1242c617682303b416c27886d722f2cdd17d809da092675c4b15902c35953fed03c66a15736d9d780b08cfd9d5958aef6ce6095c232f8d1d8a4b10a56f0b35d9a15fcfc6110c39e36c12a39992bbdd50bc696a82761dfbf0d276b19276b394676565d33a3991146ba5608e36ae9fd59959e26f1cce893447866942b7efc1403fd3dc232cba099d1acd449f8836b5836c1ffa13cb2b1d6edd259b541322664ab980bbafb15b127976e577aad385f56d0339551efcb2df1886f3878cabf1ff83689cb5582367806eddfe82be2c7587e61ac52da0eb1cbc91b8bd5e1ce67f3bd866593297f3c0f149af2c706d9972daa4a3c623550f090000f20a850d12828b589ca2b7cdb6781800089b406fa570b622c73ef3b3a0e8379cc347604c9ec2f52473149c1d2f8c6088038df558332e078d5ba4d37a0d1dd9efde48dc562b16ef0a1bbc3b7b13e4b0f577973f7096e40e1da283ef8f4ec105170ba6f368946abfc759e1c0cd66082e2a5bb3114af4d5088f4943f4d4f74e81e8a0003e2928d659ccfa7343dd8bca691297de9e6a1bb7fd4ecd0d77e4a44aaa5d8a3b61b58270cf6d59a5e4768495ce01b33786b05212347072963420729734337120bdd311060862071e4749038987490388ae8207184d141e2f0410721a342072103d441c8c43a0899b08390e1d241c8c0e0841d4e50e60520657c20c34577f78905091c7577cfac208709a94b371bdd3c4052f57c7af38f0d5658ca03e887470f8f1d1e383c5ae0d1c3061e4348613ad28126073caa697c230e903146471adfd83e42cf65cd50778d931a665e5034c50d13d11bbdfa51d3240662d8877fe65f7bef1213518d690807d350adbbdb5947aaeebd9965ac1e7a354c3f21b92664e66bf8a1060538eb6f569641eb2a9f954aba8469f78c0b78504dbc709171d5c01586fdfbb96a7ecfa4a08689104f7525b9869ce50ad2a48d2667b8ca95a8f09b9a2ca0490e98fafd0f66330ccbfbb6080826466c214573400b031020f4c5fd25a3d09b42551a87358a889f1e59729b91c85064f57364c97d566e6429dab01cf258adcf8f859eb13caa2e5bf4483533f0aed29323a69878a2e8eec7e050d1ec322c18acc8c89584b4e4098cb56488204c3c4033409a0ed30c3998173cfa015b70b48ed841d2d5b06cd2b9aa4a243afe8519e59df4bafa1bcd4f73339b42c5ffc20cebaecd3229d4d1e80cacbdbceb7c663d3a69d30c5cba632a7c1bcac39cbca96cf689abd2ac4a33ef936c110c06833d71721f6662195d0a7ef56f13c66306043128306104129c2146890148e8ee26a10914ec8c5087aaf66303b2813811471620345657c1e5fc280304c48d12ccd8c93b2fdb4ece4e096d4aa2834e12268915d9da0bbbb71b976e8cdf839992f81026c9dda624af243da624deddb0ff599210baedac5258994ea3c3f49b9064e179d24b7723d9d2f829121dbcee4672d4b09acc7e4876ba1b89b70c74846f83c9904577c3bc744faaa5730d93618a0c418d6132a01acb4042f791326d3a32e648982360ba1b049a235b1a85361df1da6d9ef2a77b660440aebdd787139311312623b51e130c5a4c4654353324311999b2d35d93a4bb064977cd901a196a33b12504a2bbe6484e4ebebf54adecfb3a10ae9874dec03762d8fd0f859a15e8fc2fe4e972f2f682f7782a276f2fe0584179f4658ee356ba2f3362ac718236e56409ab94535a2ff43c82d276d718e9ae2952b30202681c60abcd1a0659acf91567f4d3167552d65da3d35d9353b3020d269c283d2606b18c68648a44daffb332ec1566938f930f85860634ab15cc8c11868a0a26a0d04256c159a6339f71c244a4892e6284fa1a3338009165a6015f835313bbbbeb98d4c033dffb98f45a33249850748861425d81da407763eaff85d883504add5d429b502d136ac7934b30130a05d3cd0f6ec62ce9ae5975d7a84c37b91a22606682689a134c336e74175d9051230210244c3144c9d7621a23189248a1ba6b8644dbb5b3b6810986ee5ead5635a91d7f9cab5ae1948f849348dd3528a1992a6880e8aeb999b688c55a329b19d51f2c6b4add9dff8ec3e057de7cfe632c7576925c480db1751454d44262626ac1089bc9c3e8d6c00c2a7423a04d0ed44d5cb7cfaef7645509bb8432b64df21d3c985800405b9af464ba323d2a6a12667a41138da9b1a4cdb4615ac1d5b44a6158d2ee2f59cfb348b95ef08756a9490535babb67f4e8a9a4d1bfbfa4bae04fbc602c85fa2b3f7c14b1ff1205f151b4c9646c7efebee5319625cecfb628d779a3fe5ece8f3178c516cdb7d9a5478a8149f395804ca09da5d32a55455a7c57e56e3949e431e7bf791ae1b8acc7209757e93d8d4fef7fab188823c6a0f739ad3732398b81385219c5f247ca6287531e9555d0ca3c59cb56455b1eebcdcce538532131100bf186c082863b31b299e66c8b5ec816853619cd493130e85a21a4a934b11dca180c9a8fb3b32e71e52451adff592d8a14799c55aa92bcae73f993e2ce31add2d9cc76dd0d0a70f7f1e9915906b9ca553e3d3d375a4bfa5c89bb7b029cc5727f8f7e372bb3b5eb3ac7995610574b1f29cc7452d00afd25eab5be7f27b44ae50761dba6005c117f263118fbd05501f0e96e619bcc0eb9db6432cb20a41e21f868757748e7675b27fda9c940fba4522793fef43099806820aec29bdd6b62e8ae81a1bb7fd4bcd05de342778d90a7f73e36fd48c3f4434c37f1e79c248aa177a9b4510ff765fb6149636e3d70da5b4d8637e36237a31eca6aff71e7f829feeb441eefcd4c1db9ab1ce5d1654d76c14fc96375cd9f7549c69e87e9129df2e6821936c4d4800e1edd261e6faab181a9264b4fe08c3156b0032d32d0404031470a4c8ce916c8d1ad563830d8473ffaaaff199966b484d79a663ad34c4e77e70fdd3523c2aca09ddd6861f3e7fcd8ed592cd887733636ab343592a96d30750ddd5d73c95af2a62680a97fd8dc5183ee2cbfbf77c880ba03053bcab4b3e67dcb627df8654a76987ae98232d0ae6677a9d2d5ec2e09213da961d94408e9c9acffe5c79e2761303a96ba8215fc8109dd1736a78c81ffb0fc55603110c3e694b1fa3110c33205adc84147cfc7a00b06ebaef1ee1a166a56e8eea0dab291e34877c7db67174c8e0c0bc118f63c09837d36db94a1dddd3d58404607dd99e2ccd01ca9834c945e7a2f16a320ac200e3a6ce2e002840d1c62e048011c5c781873ef32818e0247149b37c6d8bce145775fa11856c359c3d94d33821ace6e9a1674370f1a30fab3d9bede4801cba1ee4ed9b80fbc9ca8b3cad1dbea671247a08bb638d2dd5fa957a91b5984a159018f14ca0d2c1550c2c68d26ce7a18cc0d1368957ef1af6ca34c1b61b8bd6d08c10adf066b0347168bd5060bed4a3c7c1becb3d9bfef41998edf835c0fbebbdb59e13bc9580ed9d7910dcb97cd608b8d31366c4051f36a69fda1f09de424910f8eecbb2b499756ab95151c9c9b95457a85de98cc15276b38e270382124331c41e22c6751e956ce7a59d491c103a5c47469cad5fd259b3d59ff734ffeede6674f36e95c7a3e458e20d1d1c1e97156b543808e907c88bf52e851ea819fe5ac9f69ec7e92a8a893429318fc2bab367cdb12a2169290db5cde689cefd8560cda5a845d46b3bc59f7d9cd6db6f869357c2753fe446c33fea84ccac775df0d8cb9ca2679ccf5b1771fcdb8eb3ae74911711e1fe244fc7f0643b912ff6886793ca98f6694cc93329812cfef05b2e658d65a37a875772833fe25ba74418cbb01aa5b0d31dd1dd5006352234babd175c720d74b8d02d8000536f8bae36ae63db66e031ad22813d3e09246678bd2d8498384ee1abca03b66fc93c57a4d178bf59a140d2bd028020d20344ae8e28c069cd1a4fb263fe31be954761ec6fe2f36430733aa98d113432fa9a8e8f3ecbd32ae28434b370dc6a08107688044031766d0c50c8e98419319b4c860838c1b9021c4adb34a79a3cd64182143003220a33b7615c459cf6bc94028063fe81203a518dcc480070cbec0e00a0ca674c72e7f52b53486de4dd6ce57f1bd4bd5f762fc9bac281fe244fc314b7ae0edda99981b88d932eb1864c6d0c018750c14b410c38a5183182fbc00062ff0d21df14f1cc69818861017d8e18211b800e602a216906941981674a005575ad0d3dd75b250de640dd358579562e881a10318303062981c84f1120601617aba3bce2cadd24a6fb95222167cc10213b0a0b6c3821f2f1bab5bb522be76b602225680c30a4e5f50f1c5952fba2f72ba6705595dbd600c96a5175478a14377ec028e2e9ee822d645933854a0c4ec3a0f63f86bf95a9f5915ac5240c7ac52958214c890821e5c8ce1820a131755b828c0166d6c91832db66c81650b225bc8ce579d12c79dafba148e2b8f187f55e2b2ce572ce944fc73222e9335cf37e9995679f31bce411b82b3cffb9acb0367df85f86bd9ad2c625a05673eb3d251d04201102da2d0226b21d3c294451d597c208b2759d49c004c77c7d0fb259cc398bd559c8dff379bbf0fcf5c33eb5dbe16e75d8797c47ce5b7ba3f3b410a587081851558502c6cae40e38a1eae306245195680b1225b81002b7e7477e4e1f9190dbd5ca3516f5639b35765894c5001135013d06002ef8eddfc2bdf9385b55502232588a18a31aa6041153854714345185460a142670a1a4ce1c4143e4c219b42680aefee88333ff7a95ac6d94b7bcf6619b4c4abc4602dbfac93996669bd18abc39fcc94ba32066f61959daf705f3b5fddce579dd792628a9b36492184149f143048f123768f71dff92a1a01918008cc1d603e00468299218a39a24041146114a88eab0378c6f6f318fcef91f3ac32b647cec23f2d51f6308d753ff826bcd91bfbf953fe6cfd60896716090a16406105144140f103858f66c58ece269db4f3afe5fc18cb59c10bce1cd3a0fb572abd557a9b128669e8d303c3f46fb2ee80d893372afbe9c957adef7da55e75cd87fd05bf6b9f10d3fd04982770e82cc312f704932748e858cbb8af2d27c2b49ce812e67c4ee951aec526277e447c932b6d89c0daacf23c1164114127829d10a4417b8f2ed12b65f83d09e4c362bd90e8809e040a4100be60f1654b47fcc5a6892f9ac02156fb8519d6ddafb6891540c00508bc74c77ac1f94ca0c104154cd4989031410213ed65092f4a5e927c208d0f68f9c0079078604cab5498e68f41f198315805b4a177f706b4a12b794c752c5606bbbf494c5561eebdd92f61fbb5fb3356c37f672ebde2e497e481214b9cb1c40596b86189205dbce8027639d279f2afdb7a1fcb9faef3997d7545d1debff2d11aae76fe2cfe0533385bc90e88a0036007541c0883035dbafb63b055942914be3435511c686103606c4089fe9f3ea361ac2a2951a6af28d17a43031dd000150d0809230908242193084006ecc88017549b32a083acfd05bfdb79540ae5bef355adf3d52ba793208dc66e12d3e9f3bddbf92ae20b7e5d18f358e990213163ebd9d69021ce6252e42a426a418917fce487b9c4c1e5082e52b81c718981cb09486cd11d59ab18e66432f749ceea609dafa2c73a8a298cc2b1eb280da5f7352c6b9efc6b67d585c40e1226f4116558dd1161aad1115f3e893b02cb6c1d71a46593ca28988401336618d0a11d031d064830c2099311b9eeba6b8196c4dc1bb113bb9fbf7cc2b7791e8ddd3f9a5616be932348409f77d223fb271790e2025cbabb94ce055edf4dae7fabf6d2a5d8ed316ec51e8a05e6b0c0062cd000a13659a0c723b6b30815148183a9889dee8ea197a3e1db6220063d0f193264487c1bdeb2c496275b86b6f46c4161cb08dd6d439b88a882082b2622a274f4bc1bde0cc6727d1abb1410caa873d94f2bd3f1554cfd12c595c5b214f6e10ee55d2a49c7575d95b2cebba4eea795012539110742194d2b23e2c7ac550133ba3b7a1e755281fc49157040a6b7bf6f93444b7c5e8f65edc3f8de252cd62b8336acc13e9a8730a3bb7b882fdd1d6d6b88af3b0e41430f4142377e1a0dc42d21c07816220bceaca09d499c10b58f662148c0996fa280151d3f9a294081ee6e1f97ab6a58d62630c50488304de0278044026848c0879b1b9f59a44abbae8bf597b494400b125a685a9e680940104f04d10501640a0208103e00c20820baee9066b686e4eeac95cf6c87e4441ce9a379fe95ade21092d26a6725f45272e93c1fcd3e5d75edcc57b1be4d667c63abf3e0befadf2c931f3cf003961f8e7ca0c387287ce0a28afe61eb01f52066043d2ca0075b0f4d786883071af000040f3c3cf0d8e14b775d90afdcbb944e902ba6ba6c6b18fb68065d915669b7fa68f66b69961964b9c294e5872c48225046048488404f0472202006021a80c01104801ea0830708f180dc035ed0a14c77f833bd506241beeab08a85a77ca45890af62a7b37a75917a38d3eea3af2af35c255375afce67b6eb522f9451e7acd057b2ced67095f6368a3ffad12057d77d20ad6159eb7c15f363ef64a5511ca40314930e26981c40c6015238408b036c1dbb178bf5ea3c097aec5e9d7bec96c48c1fc4b8c562bd3a49143f9a5755d6b06ce283fa68f6ac8df9e0994f0f6c7ab6015da84c9132c5a3cdda56038e7832c5612a53eedb09622953fc6baf06c4d0dd3e2c960fcdb1f4574f4fcefe789e9455068460c262069621b034e978bd550c6dfe5aced622e9b46901255840071640846901411d73727254393a4ec493b2cea1f82aa6507eb3b7eb72c0410e3030e570450e52e4f0c59483027208731082d3e32efc04f957235f455fc5940ecac8573e3dee4284c1c2b7d909a63adcd70ee5b996c1d674bd600ad0a2805a6d29c08454f6280de513871e74475c0b073034f6c2414b96d3438943cd16e1e009a0a39b4902b848008d558ab39e5b9b31f5982901347cb5a62b7774479f57cfcca88811f04a92e98a90e98a4d38453833852818e47ac8f5e44ce88ea99cbca1a848c12b9a8b5da7137f62597339fe3ac7d9a3b43a3df4268df14c1aabd4840b010e02381bae8437565de7333be94a4ed312104b499608005e017a31af62f628cd56e9ade1eca53da67e671ec154764186c274f304bace57b1abf4365b5d5ccdacdb1a8e564bf3f568ae14b472ff684c0b6fe9ee9609d3206bcb8483442aafcdb92ff2f161b15e3d336b7b72f6a767d6b258af6b80394c564670adcc4c565c307d68983e2e114b5a938138d5a13c530fbd6ae3f43c8aa357be4f2bb321a6379c307f55be124cd60a4b3bcada376d2dff4d16258dcebaae5aff9877e473bf47f64f303662b1eeb5f72e995557c6f6a392536452296224f7b39aea923beea0a9b2a68a88dfb5428d89c796377c10be0dd642cd1d4a4b92d400d15df3c38f0661e8dafbd3d6f8d05dd3c30e5e6c65ba25ee8b90b051f1c4649bb1d5335376305549e3892a5d5a70531559054a15a52a475568f09945b9a9ca0f13f582461163a62dd8ea59fbd5d430d558505b8195dfb54238578a69f227633a24677d5a6b6684636052f8d1179e19e17fa1fa776674ff0393aafcae15c26096d70ad95975cd02b10afacc118fe9e98158e2686de12fddd486bb8c2f99abc4fd3aaa4229e912c694ca149594291e5b7707532ff2fbc38a98eef82d2b56b0745bc9e9c6d40a09dd31ffed6693be32f10b135ddf97eef881b64c77fc9bc5368b68bb3e591ababbadc7a46a46fd124ff5ab4e6e6522a6556a8b3730b1bb69e9be4589d35d372f4c4789ab96b63c2f318fc86687ad4b77bc56565b29980a63d6b6d45502cdfe7e458c803e3e3e9e47633e3d30d80dacf4a32fd4d0a8fd5073d57e9c685bd0be8ef16fde7558ba2a762c56a5d403679947e2c752f68a5e77adc7229176518765eb32066747713c6fa6c40cca2c8607e3c33732679065c6a60859c812203b8a5385bdcffee73659c436c7f94b3c761e3f36b33e640828cbc9592d0c56e9adf321d1b152ec8cd817f914c786ba5b4e40da709249240c9d19dd0aba06743bf16b39e71a8de29ae4a924949187d54eb759e2d0c3f8c30a23a33baa42ef334c0758d7ed081083001f2a6c5031e244c501548ca880709a42c51423a604650c4ec7d2f3d31e3683c1baff507edfa11c5bdc4fd0dfdacb5791a8eb62a68ee3ccfa077a0dfbeb24650a293e48497280340e20e60058ba63175699aa602765561b4351e966b5b14e8ad2077673b66e98e30631372871bac1deb0a372168eaba1d410ca08e9069b28248852eb686b38e950ea800206142f1eb5b9cd2ea3352cbd2416eb0514fd890e9ec8e0c9104f983c01a234859255a2e1c5c6ab03afdaeb3f2976b453d54fcd28956a531dea97ecad73cf935ffd512c963c253520099624c209490d24213a7bb6aac0d47cd9b5286fb9bc6fc318365c4002363cc08604d87073b281c7f48c705fa472564a07657474e5c87674c4480d232e464418796d8b7c151fcb5c88a1f799568afb7a8b70d10aa7a21188a42092111960684888a125a7a11f273f383961c3c91627312721505183d7ddf1710d37a337cfb6e2fb9fe36a7f2af5d5575bc39e9337efbce54358d7c80e61e5bfe1cef3680dbfadf2ab0d61d662f9d5d0f1da2c9333294b723dd11d5d374dd4e86e277d6a72812651dcfef82aa670b514e52f17916b88c56a6599cc52962a42659abb89f86d762d9838c164034c8c60626322c4440421129c847c6867392b7c9b1773b5d22848bbf26775f92aa630c558a23cf452ab47422d096249cf92108272109446d0114114089205bd10040290088066402afc74f19325623b31c5adee7ff26b47ee3185f2bfd253b44a510e942a4219396bbaaf52a8228c3262dde8cb5771465d55a58ca7d6c9fbdd953815be56deff501efd985a55b47e68b14e34a841030db918daecf8bb1139cbd62b71ab866596f7bd9f451a086080384e06f0a2bb23954e26c56c2dd24feaf2a1f2be8f8f8f0fae96e2f91f88e55d5229cc47f64f7c70765298cfbc4aca9c947451f275b712a39e32dded3d61bae74bf76cf57c7dffb6ea53cf4e0f093c5cdc2ccf96ce8fa94cc9c99b94293c94a784ee8ee04d4d965bac2d5897d259a507b91cdfbc268db1765077b6582674f70c635a3370d19156e90c5c66f8669801b553a63b565a74dad9d9a911edd0b0e3dd3149991693248916ac94e48bf3948486a64bd5d6561215e2949f93b78f666cbf8be408121264104386214e3230408624477870440547b074a78c3e85a967bb1667248d93112f46964e466a30c2a373f29693b7979111124ca7969344119f8ad08a149d8ac4a0b3860e17295fcd54ad3772aa38e53020474999138e08706e3845701cbf07ded96a76dfca5ac6740ac524e203a2778a1f495849715a6d49e95cd00ae1292deef5d57ab5b39bf29b74b56c631e58eb4995864a081592eae644040d22491099272241447a9c8684b1be9ad56dc67578d29faec3f6fb4963d77a0e7f2ebd4306302675c40e29a0532ac829d5a82650b7136aa85340734a2020a0506256f7f91483173160200629a7184e80410630100183100c51062f2c717a819e5e18800b57b8705d4841081742721d23b61983acbf85a00d6bb8d847f387b3074e6ab3ad97d230665b48727239dc8c938fe15abc8a13b90a2cb880852a58c8e1c402664185130b21ac208315905881ae50e4a44299930a635410e2a482014e2af038a510c529052c93c67c858d7c15696c0524023911ff4101d9225fbd8a948c806041ae1f589416d18ce2e0dc6f347f96651464f44279ea076584fb4a8432024afda08cdcf3242b0534692b56c1ce278d5589420e28c8503889713ac18b13ae9c4e507242905301d028c00f0590a7020831010c139030a1869309dda99f1f6cc46d264aa11ca3dc71a655fa9eb5316ff9cabbb04a15add2e92aa992b44a63b5140fa088d3001230801f804e10344e415e700ad24310a5ee1ea14f41989c4a80a3041594a0815309b8127c4e25fc3865713a8de0a4c3c97512c134839309042713ccc46363039b246c8a4e36454e2490712241cb4fac208dfdf8ca5771e20c5a8bcb11488a28d6f26330dbef6b407c15511e4595c293c67eae5d79b77258b514c368d2d2669593c66a93c662fe389aabfedad9941d15c0152701e4208029027861041d9c465062040498fa34c2d0083f4e22e440042544304284a153087474a7a238113f72224e44b39e1371229451ea0865e4310acac8a3e749998ee7c9d4518ac869d6431911a18c5247ae4a619413392b7c2711678ac336e34c6f3e3db3525b085d8a42c062429f42e86208a8b645a7008411becd6f96a8f74e70005800401a27004cd1dd51fa0400d909003e27206b9c8050e004c4e7042484c6ff85299d94a7308892d19b20975f2b3f96547f84a71f379c7ee89c4088e3044218107c388110e50402cac719271f5dba5993fae79dabba99d1745d8bc293c2c2b7b158387c2791669b6387c3b775298c0adf96947b1f47f9b1e7a1ea635b3bf9e858ebd4434c0bf34f3db8749f7ae45ee8538f26ddddaf530f7ae251a61b9f787ce9eea6a0bde1c4034b6ec9fec9a9a6cca9a689534ded54f34204fa19cdf2963fe9447381eeb6a14f34359c66e838cdbc4089cef2874439eb0f8919bcd663759d0f8956362476b74e9f664e38351ba7fec0a96ba7ee4ebdc21d34b8838a076de8aa2cfbfcd3edcb3d8a551f9db922ce14cb1a823f77cc3b64b0238eeeaee0fd3c7365f9df5f3bc0d881a5630ae51fe8f3df8e9d2057cb8e3ac2d4d1a58e1a4e1d293a78e8a8f9c11a3fc8c00ff00f52c8f5e947657f577f319da3ce3134470b73f890e38b1c5de488d2bdaab64a582d0b95b1658a9489a1cc0f3260c848323b644088e38b3872dd9d42a95878e56e957c1559dd6757b63aabc37d6af51705cbd622dd4c2f18bb51ef6b705c01c703e0288203d5ddb9cbfdacd2dfc06f746fbcdee87963006f88e0031df860091fbcdca8c30d319dc28e33e523b98eff04f92a56231df0f619676bebff0ab9c1a5adc56eb11b51badd50a10d32ba636afe12f5da48a20d0474c7d412f550f331283fcf37f5faf8b8aa86650f8ae881941eacc00619dd5fcbcec6b371840767f0c0071eecece08c1d04b183243a2843075a3a666b6f8d783aee2b6c66fcb10ef7b5bee761a69fe57de5e4e4e8d895ecda9f495ca3d1da4b9b5d95a53f6d4a9a7f2d873e3d19d3a1d0a7681665099b486428d2440724748fe99883ae65ca010362a5d6e69bbdb31cece4e0c71a62566b6869adf175afd1e4263fdfd648a12785753878a34b9cbfd461896be1e02885c201ea961913a67b4c97a431b93eeaee380635e6479c4937b0a23baf79a8e413d7fba0756a4600002028931000003020140bc62332b16c3ee9fd14800162b856b05ea1cae33cc821648c21c400000000000000461b004c9b09795e5624098c79f82d8f62a2db4da8cb9481beb753c7d4fbcc0011a86a0442ea728843db6e9ea28405b06369186c3adf84313ee780fc84c70dd954eafb8e16a8e4389d4f1da75f9f31a087b47002345f0c1bbfd168222388e873103723ea63ca1e609a996a569696e0a3f60d3a08c7bed33fe313dbb6cab83436bbd4b8b9952d20984220b5d43340e31c519134d91a32b30f0eb627444280abb4106955136c0a1596c7216f454370f684804fcbee4ac7a7682ffe0d3458cc1405c2943dbd27b3325f10f50d2f5aaea27f2d3b72e4adc5bd847ac9a6dfdc7c27041afe45d39257f942171e1a335331236d26797a7863c63e830af8a3e51cb410fa0ac629fd6f4a50cbcc48f437a1c08bf086cf3f58163f9cb40e3945e635adbc8350628b3b7b34966a4b2e01bf64ec1854e4a8e051e4bfe512fcdcced905a14b317ac6a40f5b2cbc00f80c190bd944b6bb630ba7f03118c8a4273cbd22cc8f9e6087bddb30ebf7a6b6ffc12d590f83dab58de83b9a3782789ca57a4e0fcc97bf2ede6fe54c018879a7dbac20827cd0cd8d97e935d4be20f409bf7581c2daa8bb29a1107bf20d7880db2d0f844e075c715f4eb36a621ebe4123aa00c065e400bfb096963198a776e239c4eb1efe551a5c82b0586a3f708b58a917a50281ed99a5f7e1e5e2939348ff6fafd01272f01f80fb315c175e3f219e0aa4f88ee3094e8e263e282c9b577ecb4e8a2d9d0496310523ed58a01061e5acee370cf5a07ae2c32029e430d5fa0cccd63b5089984902d232b511ff0eaf841fa90869876aab058e62c0870d821609caac5541eabbb8e42da37086971958920080bab497b46cb2b4b68a49260ff7573c5c9d89804227f2851aecad918ffea473d6ccc8985ab2d3797b4b868f9e5d6af03906a6027d77b8d71126b606831de9d2036ef4ddb4d2f4ffb2f3f5b5226bc027741a26d284f4251ada6b49e69f9378b523f9c12ad2b5288de3218940d0866c2fdf16cc6fae6b6c14deb20bab4735188e10b5dd66fba11123e901c016571bc6568980c9d96d06a1d3181a3a6ccff54eb129946118158fd231f2becaa3123e968f6fdf47ba0de7d2268d9c0903346c1cfa6df49ba212a7a520e919f5ba354cdf68a17b40caccfa6e7e030248d47b152b4c69a91594906cfc4e562844088dc11cdc1e242e82275d6da4b42adad609c6b36451a54abf7dcaf966c0c7a723f476e66e78f61e497f9bc700caf7dba1933ad0f604b6da4287284346d1e129fabafdbdd33bbb7a329a50bd8a029ca7472185f82b83e1e5e16d4a754b7fa3b3ce5f9761c0c7563518d204319a113d57f10c8c30d5714727695f60e7b8e66bf57a61b0b7b0f366c1791d5fbf3ee4fff9cb26c000aff73799c37f20ff7f192b7afd4edf03f814d57e358a5c53422421669ca69ce5550840b8475b1044c1d1c204a61b61af3ea82cf487e90bb4684b045599e9afb1bd551b2f6f1571255d2bea727d2cdeb2bc96045e717d3c866a2afe57b57e43f018e35c37a231220d8c2e3b74a2fd2bae8cc5cdf5f295a3ed21bbdb415af746739cd5a5afc47932751450118c85348455d352f8d61138536c4f6eac0829a3d7c85ae1dce77e8477a2180176e6dff21007ec543ba808a8ee9014fcc8953ae3228ded0297b856cb8babf4bccbcc238e5646c06c88061f154331648b9e51a5db10e04805b189393d592bf228a6764f3fc123a1f6bcb6a5c7a0b6aa078491fd3a65b78381de1687be99254ec0937347f9568980e70652b0fef6901549db3442fda73af177c3e07d5a6beee297f16a4fd0f942a58447b84fd2f8c1d8f721c126c6815bc626cb88eb2d44e92f2cb828aeb9b5f82120e6f7c5ac12ca49461ae18b69806e75305cddd443ebc832826b65fcbbc911366466fd5b8621399cadf3f5e59c04d0bb89475b7ef43ff753e0867516c47ccd4881d1921591c9c102a82371eec375745867e51916fa99dc2ef666257c8d665e05d9098a59788388babe2adf32103ec6661d728f40c7aecc52defd20a2a640107d9963c0abfe1497f9ddebf50b0fb74a79d9f683d5b094760ca50883e0b9f6ac473e7b17535ffd1b6f0e1991841f89a8253278c4953d68994ffff131bc4d17f5f3db01e74df94e0bbb7a21b7821b5d8ab51ce288be1a8cb9a6b6943d252bdc6535a151e6693030f5faecccc008e18042b78f14b4b082db325c21f58a5c85e18248ea611059641e32f41414727278122948112a198d05d14091e53d46074dc24c7ff3b3e3ef8246c8067eb55505655ce1ed4c27ba980a17d52fb6f41352802a9bb3c69248706bbc8f96cc7b5fa03c1686a9b24f82ca13a9491cb727baa70f123f5fe141e90cedd2b2e3c112cf6c86699d24c829ab3ccbe3a4d93b891e8bb57e3dab70076e508882aba4b2e0a0235922f89926e5a59bd352b65343e8c3e2682fab57b36cc73b18141ad8d69ac1149820456831eabc3dd96f787b163b4c5c1e7c5c4e4219c14760a74eddce611a3a7be33fd005236b1242c368becff57eaee707e31740bd999bc1afeabf6508294894d57b3eb7aac9f5222ab1b1b314731cbc2b38a914c266d9ac507850da4109eae721ae79ee1b2c222c20306ab08e04d7af322ee1382f3520da815a522ba98b7a3b82eb643363bfbbb2d4492da5980923f37153be92be0074007448856a67883d0044b52c135dd7ec6804f2777ab7eb848773adafab7f2eb8b143ea30cc60c772ed3d6c97f38ac89cecf23fc41b975080550e7b8bcfb0937643968804a77d67a1757e6d004bf122554b31cfae2e3e7afcd5226e5487be980deeb679523c47f5b715ff96c69ec96f56c5cf357b06ba36c2afc30df38c1f57417ec03ed40913d6c490e4cc3f70e21b20913007c888aa63a7b39bd732ca1be9c8482b151b7c2ccd78c1db6c7483d6c10f7bff1dfe091db70b4b1903695e0f56dcbadf44e072d3dd6262732ab6d0f75264f3d6c7e05533f3988b9599cbe3c4638ff120ee6d0859ad23d1295689043680d7892691fd6444ccea62717e8e11849571c493b2dab75e7b62c3cab656430ec5b6bdbc1363b7a5cefa14ce5a4abc73a2ba451b333158e906ce1129bd9bcdd1e5b524a8d35d43c6f44c633564bd7a2ec710cbe008e89f9baaf3cdd27b83306d68ff1f85598f4139212a1daf97a94d0c12b4d0a4fdfffdcb86cb3a4dfdc78911fdf2d661057422739c62781c2d0985d66a70e40df538c2566ad29af2c75c90aab6aa4f1b2244e2bd1ac5f9f17f857f34fa692e8a921e8bd5762c74db758e23555ffcd8c17acb49e3f6fa41d3ed2bc42b8b2711fc59d0f4b787416f30f18b05db9edd3faad4db22f21e400818c6ac4ff389c9acbf67242b0da4652ac9968d101d96e2a158fcfb819c7d6a0a44607448150a16d1b5a7c3d4f53b09f2174d7f1978512d3f7b1bbb8d3d73c28d627108b76cc98403cf6e52374c0b976c54001eb770d821c59586c4c3829a9bdc765c410316401df09282195f8e2cfa066a3bd912201e8423121ce11b38fcd9853d39991269b63d2d0920cbc629603b68639c8175808f3244162b5fbce135e046104264f16a336f290bf9b339e6ea99f0e9176d0c3eeb11635cab78bb81d04db82ccf3ceef2fc97ddefb3b8ea30bcff557f003c8a464687bac1ed9e4d251cdea62dfd71a2151bca4a6bad751afd2e36fb60d4f8f69409acb329b5e58a8418242130bcc76cd4ef2eca071dd23d1c053a50a6594057e1567f4ada5be2ada1f1e206c39f7b7f80402e3da83c594d87ccce9f0fb74a39f900aaf5d8c2db75db186d4a3f6a4394f80193d7139710b50a59bf463d213963afcdb5058605e454f6891ba1d6c6a3e1d1046b47b83537a0c44f3405e81cada1bd7dace161a3ed676abcfc717ce3ea444b70c194899ccc8d3854d2d2f9445f1b2d4b0aa98da0b0c6236c8a88d1e7b0d38222057aa45e223f3927064629209da4cea3e7c5c1478817588b20202c5d1bed513a0af75aab15e24d40c8ade1cc8c066517a460d5c65d137eedfca6f9a86449a200ec12cd4ca441a724e24eed47e21c414093faae6a9c8b6ad50eb7f297d646637a810cf7f92c0d3f2cf7e8a0df0b1aa7bf03aed13bae12fe6a58bf1947ece4c780918b3b7a926125b1610b56ffa57dca835baf1b3f54c82f33aebdb9f1f0c9840c83e52b87304bda75842a3f11007bef835e8c4fa3358910e54d7c1208fc2c750bdad7e36d0bb3d2a8d60a5defedfee6fa28ccf95d430085705e03f890b5b2aa871387b1e1ec19123a6fdb1e0d3c319625fb7829b804d957a0fbb5f7f926de6ac6ba994a8e857e5e8cadc3885a4a0f57d32e040511fc3dbd86a160765cc251aa9188b267a5225cf23b20ab391cf41a126d70b0867016a3122e3f971308aa40eb913be0750d3522f03e6f0642f503202a4706f973392abeb9f161b5da47a2d82eb47ba57f4110ff5fe78366feeec71fc9fb21195d8ff39228cf55f4c0c2fafc778e1ed5e6151ca79d71ef52ae0a87f77015615658d9f4915d35a5f28d2778bf43ced6c6415981bdaae586ad182137c92b1b65ddfc9cc0ca2fcce039fa81e6e5c9adaa7dee49f4996d696204042871355126cf3d6c6cbda28c33d91fc311d9b870b6ebacca7a96d6d9467e0d4b366a03c535c1b76c11418917969af3d5040807b4588f90868a4b018feeaf743cccf0e72001013396fd42102340639c8353a9381b9a2797224dc589ab87e6d184386814651341e8aa616742e8972eb20194156d2c6a0001100648761083c26fd712a3c8e0a9167a70c6b8da4bb00f1b7ec03d352d2a3ef1399cd5cf3e9d24f970f773aab39edd1e9f6f572203d272b2a361977c81856a0291e106a298399c6b6c342f1d661690a3fd7a4bb6d46c180a99ef183c254330c2e1b0398110e7f797ff868dc323c632afd0924f195c86965285315e907e92c7603535db1ef2a7ebbe6b31266df92478a7d9547246af57067757511f6340dc8e2819414add8970566ef7b231e9a860fece979579836775f3f27af5b0a106eed61c579fe37cf4e40fe09e5d1b3b9dc9dd8a344b3baf93b51b6622b4b94309f6710c0fa7a756a2aa4d90102e4cb31b21b89e5a24a8bc4a5b73bec3a56bdfb82101f80263a25b70f83068dd8d1e64cc98e63b3aeeccb78d6c9e3878b62a9c41abda9f32e3164453e971e6acdf7f29f55818e7dc5cf8d5c1a7bdb1896fba395692a30dee4dfdc509a42c658e854c1bdba8dddd1aec59e43b8a2c0a6d0fb8865c98d269cd04b978eefcf844f76d99251a999e2df85daa8352343c13bb49a0d681ea4c513829e8131c939ffa81a34aec3aae07773adadb9660b79ee1f063b8783e5f4a833a405deb1f5a7991f87d0bd131d8f8168600ddbd0058c3eb0017b83c1b05588996f8ca7ce0562878a9a8266d889a03b5cf0f2fb63be78735f9544ab4cec7ac59c16dda5e488b185b62bd528e9e19ffd4a52e5530df56d0f0a407be88f4de93a16986c0ed4e3e6433a8158e71c20d23c0bbfc107c79526e4557e05e681754b0571f8e8a5f7b03bdcad40d29fffbd6ea56a614b41cea3942dd73d6ba7c347ea9471caa6ebf7d7ab348fcb822b808929cf9dad5741f9556a6c73af196d4bf904222325a45a9e906976e93fe647b8d8adf09e5861e510a821b54adc469d9d3eac678229742a0312da848336eb6db59955c445d3f376f6874057af80d7dec8bcd18ccf140fd6b0831148c775656fd9fdea9c539f62adbfb21f3bd978e3926f4e64fdfc806779260b650e6d6cd0a0d534449e428a18620c98e070876f9a3daa5e5c5c8363ef1b6f4bacd049ae85b09707c1a5eccb2b26e5deb424523ca53d307b01855b4b62f416e2513eb84ef45f6a4f2f4d6d03edbbba4b05b8501561907c58cf8b106d6e2ef3b4bc1605a2ab601c36be51116a617b2c2eeed06e44027bc7b1f4cb023e3aa5de92803782256b75c5a0c7e9e30ae6c0812ece56e00b160d1a47562fbfd22db64204ea2657f713ff995cfec26972b056dd41671e17bd693c81feafbad81f73022d5f5e955f13a1de1a6b2f4fc4b975d0b1b21b4a213e4c67850abd75569df51a3c516d11577f2ba23d320b1b2e852469f02d762ef1684d514a8de7c7c7c4068f2475c52d2058964a6fe272491712c254e183cc293667605b9afe4c7151d6b79d3c4eb2f493e2fcb1afe4753e212fea6daf32293597b00035c4a0d08268ed71fb9deb84b5e5dceb2680026cedff5902994a259c44373cf7b15ec29e0893994772278f74280f5068023a0ee7b7b03393f0ef95f6acf13b6f4f3d3543124c867e5ea070a4fd85fdb7ff604b8ed13bc6a747abb9843f55de90478b66a21861d86efae0a8e53d0fb17fa9d055afe7a9e2c8c3f007c874fb6814077fc863f66f4141a48600ff7236b7602666a599ada2d22e6e0a968c803153acc98959906c20e6aab31be32554f4719a89b1a2680d12e9dbec0255699f3ea87214c999ce0c86fb1a23d7dd6d40c225bd449265bf500f6d6a01d7b50883eb7e4d32e0e657b50e39e36e1118274435dbbd6b30ce624509cd7894cb910836478f7fb2a15611ca792178d57f78984459496e97894409337b6fba4fa1d807f21a1d930801ec10608091e3fd4768f5f4b513906c11c750b15e72d4e6c55ecc9f87ce9f4100a29ed52fc29d936356e72a82f24966ea33213db9ed55439f90e7fc720c516a68e6a740d0c08cbc83f5aca4259cba5b2adce4b1fb689ebfab5ac149ca9957a6c801dd93b64fc75b4fa8f9ac3930145710c63f3e78ca0fbffd058d447b941815fc38ae182c1ae539b253bdf1d3b43829bce332157d12743c76e2a30826cb9de44a8415097f876b6822c22d094d35618045444bc515aa0ca28f3f14c24f0fdc1e2d3e0f6d1410f37c88e1057c35d679908e8f50e40c91e350472d468d34590ebd05a11b88587b8da6c8a2be46370a9bef2b2d42cb30e87904b5f6e345d335336bdac3f37781f8abfe29f85b9a4cb8d450a78cdda1be4a18b3f31908f2ce85805a0365dc7677793ab8d68b8c7af6438afbd211ff9109f0d322ed630f462f2f954b63d2408c0b2847113a23af6d434d0e746ff24299f9eeb1647e1fa4da63849f01379673dcec6875d470d284a24f9db9ff890a47b1fe0b55755fa998a6b32b88102dbc84f4c5796e7fd2334b6f15335baced92ff0a4cf253a6676c71983cf893eaabd3e93cfefadf56fa4da19a0bedcc46fc5b479fa7180307071475cc03d73cb686f2de4c9fcfb87d14d1cc2bf4d99fcca7b2a3127d1d0738579b8651cc32e3778afd3c698c10c4c1bf2d64a1e41fd4445b1cd10ad427cfd91d0630578aeab84ab548d00ad4a03d85d04edc9f4e8def432ad47ec3ef7ac9d20a44623a4aa3b87cc3a07b14fb0c07d313d02d1bfc704e01999139813ef1586549aabc0c1f984d3cf7df11b3e19ce06f67e36d4093110303fbf0f4668d8dce7a512ad94bc7f6008c98c3b6c036a0c7cb68d983a3c39a7e0d0d63c8a0ee75c70da24dd1d3484904804ad6e1755c92148c51b8d9e90cb9289cfad2180275a015408d83bc7ce12207bc48a61d1b9519839e081390850d51319855e220c5df296c52f1fdb01e25db2d048866b58de962590ce337cf77f986eac751857f1392a64f79707a3ad42bf6f1186414c7514cc5a5e2394c4ce8ecafa598f4f0740b7e06c982da5f7f6c866e4f12b07db104ff3f264504643826048cf83355b0323765b9330293837056746fa9cfbfc423e7eb7e96d0b784e53679e557bd2e24199f122a1c849de09a72aac58c58a18d1f44e116fa914c129b325f1c2e01cd00a4462d68f2d5765cd794064c37e278b90f351057fc2beec202c946bab29efd3693ca8fc6904c81a8ef85de40e3c3811ac6442ded8051ec73b2c8660982b8b271145b8d68477764362962880474e9765358c39295a8fbbfaa0c74cc2a2081888d02b6f094f9d72a9f722fb1ed0731a00ae9d41937ce9a420b850066b515d6a96e209c03433857fce0c51bed1a1cc8e8aadb4a60c999b8a894e7e351f5d470c74a5ce15c1617dacf4cd5ad97d738365df496fcabcf37998b52604ac87304a0ad52b5ed19b720b66216f59c48e8ecf3dbe906b1b271826f2c5872c55778ba6cd9a6ea1a42fab8ab515d39f6c23ad107179594ed09078d4ba3c8c7e104adc9881fce03190c68cad30b398d88c24f4f801f46252b6f12343084f844ada05d13e1b33c220904e913a2dc63d3dee26f15c4cf27533a8fa7f8e30d3da3950f93229f4da06748b773c07c24bd0d59a0ea502741418a980389a52ae296a3380219457e9493b46400291732e3fe7ca259a25e8c58aa173ef66abf170eeb4bf1f2e591b4952182315a9860a117c97c3ea7fce33a1a9334d1b7d7862fefdff14f68c0f1606f2c51524bfec7d4297fcb2d3100d1a7aedae7e05333a16448d3a7f0b4829c60b330e672dcb38c356804b8790c478ef74f61fb96e3c90cd01c19f0ae0a6094b7c3089c6e1cc396573d8c0783d561b072a6a3bac71d8a391e69be35442737055691335886d5bf2b264b7771892920140ab9c1ba4d7fd81c6f561e8e1344662c1769566d87101806eb9e1b9e5eb21a7b92c2e5ddc85d98b758e8935a37dc86dfb6ec9f460f80feb6ec7c2c5b929fd6faa2d7d692377f3b8e4bb33c898942c2c23e3a332f2796e88e22f720af86f8650e7710ecaccdc5879bad1d5e46c41ff96ede80bc0b69e64d3dd167915d149ae8e7c3bf8cb5fb0911f2794ce0bc68237a881231990eb324cbddb9b575f86cda0678d39c0aa054a20b2521396f363198fd1acffcff81585cc255115c2fbff2e3bc218afc2b4da254ae2d337c4e1faefb532ee53d8065161495441ac587cfd391717979bfc274924a39e4dcd2554ba1533a888da1cb52a47ea8e082b4a18b86e48cfe3acc54d2f4c64c82d22429eba88b1e9e663304b95df3e22509666551bf971dd3cb5fc054a82b2e0212600e549b476e726010037c6615cab92849bd247046008e9dca88207ddc5cc36310cc88bb284d0836a66cd231340f36f3ff6fce1e5bbd74991ae4364442d04635e6a9d8fcfa52a4425ae7c82df238a8be7e63217ffd6ac3104c988e2894caf1a12450da86b29599c4fb17097e4f9a8e7ee167d164d1990ad117a08469aedaabac3c919c301b5babc1fef4e135382f3849deb3aba67a045319c5b2d61d8427f138d741b8179bd8f6d36e73e4baabfef963e208ff419e65143c7a028394e227c53502eec93591522dae8726ecc0d5baa77e73f5ac39707c27fb1004ae16bf10fc565d31d4eb381c6cbeaea0e4f3b99ab9f6e30cb455a017996c0fa7ae1eace7dd644f8f6ed2e9d9171461403977559dea507539d8157e52a698a82dc88ff53678c3d0af010a441bb0107dfbdf19ba403412bb3a41bfb7468b6258a77f2d1e18434b97e09385bb74e90b03abf7a9a029d780ba2cf0efa68700a99343152dfa6adad5123f70c3d9eb4c85e3ecff798e54045b3dfe0fffe428bf31c611ab08257d3a75b296d2da6d7b94c2af28ebe1fa78b4cfa6a24762cee53b29b85cf10f3c42b401846fa1d800e6e549afc70e9884237f520da7a68a0bbf765872b57f26bf29425e10c0770dd192a94944d50d6a0654bd62e3513bcfa1648e339abcda083f8a522e3ddb0b4113c5b8e955f267a5065b64eed0c24c983cedf3a36e101afa0ddec9e7a2c607abab235b13f794d2bbe88e585dcd959693a93cb0118f8392a649b26f16ef1f93232a1fd95c522c740393310ec318d5a37dc382fc3ad1fe3fdb64cf44a71053f0ee0cb60b57efb47a683eec6ef4abff5fd41d8b055abc79364e2b960376d26ac7300ee4ea583dbfad6f2784362e8a9489aef24c4ab262b63df667dda2ae6d9c3eed0ff5a445d4f031369dabc861db4a74b0c5124f082e864e3531d483c780c009c2a66de1d0be999ad2deaa746500c2ba2e4c797ed4f57376ab2d2ba017af1ccdc1ff343105e4450dc9172bcaf03966a065669982f443f3cc572154758637eb7b02f3c396249699b59a461a74df339b3f967b1269d1f5551e78c8a40bcea004cd0fd216664868867f29524eb75efd9bb71e0f08f9f21314803697c583e9384ff5da01b7692606cb6c51356ab399e3a41130e782422102cfc5a095c3a918b06b1e2869730590f408d5d478367f5721e368d54e75d727594a778ac4a3e188a44305f0c611cf1c7ba90b0f284f52a245ac0e5667b3bfe9bfa32d077124189fca04c8fb7fecdb48c99d96d497c1fff7945c48c2a13a9c4ff0885a25d5fb843e7f80e21b7234335141d008ea78c3df60959c8467398beb19c997128ed67b122def88facf5c52f86f7aa1c65ef017ee387344a35c6e2bafccd256f35d5ca195cc43e88deec202bce1fcde419fd59d3abf12067be1d67d06c07adc87eff05ef3ebed3fa5b9621f0f3cba6b19d26009952968f7596f313dcdcc0ca6a423578720a1d430582ac2908a7bd295c8992353bb14a092dbddc4a2b9c6264a4dfcbf26f0e8fa4bd8d64e97081c7d1477365f97f79f950df70e9aae1224462120cb029c635b8cfb39b3653f13f795e3f2094937cfeffca4ccc8c09b8334ffaa1ae8750024ad9fb89fdded472fbc6ab425f20e96dd2aea6acb4f2d15830889a0531cf9dde2bcd713eacc09648bb7609be257521d59f2532de6198ee98cdecefde9a1751916c76494ad36020b95c6b8e0a83680eb4f44297ce15fdb21c6be70a170f6b3813f63e1eb0ddf1b239e80e95c1fc49f25672cfc0d90f849fdde9c3bf090e6da84e30e999500ee7337e691d71eff4df09e30c3bb222a55c1850df266e1f74c2af02c69bfc06c2f46d8656ab10151600a57737588e18e3ddaf228643cbcbe77487e3b9b5f14d4c8464e7e980d406efb926d465f5cd51d1c1dbbf12fc3d8cd4e43cc8eb91bb477679b47d7288e8f0c3ecbc2e52df50d882682b8911f6c5a05b27bae01988015d59ce3c3e032ba4ef2d7c2d9514318021404a9cb6475c559344fb1450b148bd8de464b2ac2e2b89cbb4b7ef079424a5b4705817ec876363262181dda41d8001a071411987a54eee566b1608ba445bad5ea61eb6fcfbb219dbc2c5ddb90a2c502cc9370288ac84e3e6d54ed60c690f1198778c213f9466fe8dfd7037a13744da90bca11633cb1e4c23776b90383b5ec52abac49558aa2e7c74d1bdbfc58e39531fb0c312705d4ead7e6f1ecf709a7173a8ab4e97cfe5ebf2644cd4738a9dba58f948316fc4dfa301186144c8a801ca7f889ef6091c811d108ddb5721b4684acad063fbf0a28c1a1b467ead6d45d7077af719219078843f3885a8e711b4be17123ace7a5f845b8fcb4da74ae5c847ca4dd3e49b65eb28877f1c89731902bef392605724ae61300a5f573f53a74f6bd9ee47ba098e2656df384a4a1a1d9b04df1d000a89ab229448d7bc6e62f9a399e30c89476593f5116b67484c6396dbfa9c863342f2af43cb0ed016852c07a1a6e94290fd82a901d2f25d0940a4df13a90a82d156a0c6db95e7ac70e622b829da16f6aa1e3d6d50d491d735a308de22af118d610934a3aa71189c5c3579f7d256755cc6379cabc02e5941225aa76a406fd3bfff7040381c01ba0fdd52395cc6567860ae2c47b31d62e9637471072611c886201253897644fbafbeee42b7512381d3bcb76d63bb465cf8b52c0bb3138ec68f3da34ef533edee7fd38877fe1dab45308da756d0a0d4dcf636d6cd5c09c61114a4cc28548121e9775b72e9fbc6ea6baf2ebf2e11a650ace454382e9ee75185a79e4e1e8cccb83f9987b3ffd946391d1724dee56532b60fc5e9c304dcffc8fd6d7c2638e87b8e0c89f227f28962fa9aba2ec7daeb5fc9a309d00ab4e8e0c4ab70bef20077f5d47794cef872f463a70f1c2cd99f50c6a176febcc741c9c1751e9892c73bf40be3b5471fb7d01fcb22397aae5dc2eb5f86bfb5d1ae5c85a384c362d1f9e58ad5840321e911bee8c449bd489bd07ff9c7442defde6ab9827fe8b20c4b105750d5be9fef585193b761faffb2a82ce4b535f8fe30c77b2ebf178dde7f0e484a4be4231e00a31dd514806505c1c46b3e6882fc31305073cf71b490a1e6eca614fee30c70485a97d470e1711e7759fedae6a25efc99d7a2c7dffe2fc7ffcd17be07d5ed178b2611152c82c69181fc751cf77d3b7fe8a93c7a9c04df6d7f1dd3d3e7fb2da6077bc637cf9b7c880e21e1cca517f0817da785997eb97c99bc08adccfa5610b78653c20a12888404470bfc896d4d03d2d9cf6396434126dd326a97733998f11e82ba88c456a1a897bf512aad9fca3500dcb2528128101a395e63b5bc6ffd24c069b8f5efc7de3710f5f458f48e279e9daf8011b60936c982df8733c5c275fec22222a7101f5c22c985ad1b890ba73a82fbaa697952833745d871d710b49bc5730a4189c90c14dbdcc1a0a49c3535a6cba9d394480ab004d2eed7acac25ec33c0eb3cecd59e98d8db11a1d84c15b03779ec0bcaabfbe04939211e48fc40244dd0499c3e075753e6159e0df8b6cdcdf595fde2531b193e435fe0fea9aec993d7f0b6d492c656904fc509f847516510e3109bef7f93e5c441845250ab4cb3b3d2cafb7c0d1ddc6990f33f94abd402c1755ea57a2996e1b774e5ab144b454742140c7243f8fbcaac21a2308baaf947f5971ded9372e0203b26b53c379d6fcc30e86de854320554b32e889bac7396b40561e7276de5c79d3c871f33878f984af500d76cc73229b39f2f6604cd5035d96dc396174d9d854461042fd80edd7ba511eb84f5bce64f05efebe22d3d274f4947b5a12a2002174ca5ccdcfbfff1064f612a49116e17d06b2332b310899e8e04c2ebc55e15523d411f7bc3249eab2d3d0ebb311dd86f9fcc5fe81ea109f8bdd57aa0030de1cfb89eb916cf9bd81e786e29bf627709d335a20bdfcb332a7bac7b5bed134b90e9e094ab1c2c654c7898a5ead3c352b313095b55ec91cde6aec6ba0d4643a65266cb22668dd9b8cd8bb333c8765ecad3a86bca291deeca48a15d7b24ebfa96954f699d41d1b624b03f55322c605b0d3f8f3066b79e53d2c43315e5cd14b0d8411a5378a7afc745c5974799a74e13c5500e2831a0e7353d91b0fb64a2e4f7cc3ca6d29f06f489827243b0299d19665a3fbc1e1a4e3922a7b83177e5cf012601c6c4bc460676ef8dbcc47ce367e4dcb2efd596f0ba98d688e198fdcf488c94f6fef27d368a419684b3aa1024f7c7c0d884aeae60f66996b998fa8b29dd71e46d7a2c6944426dcba89e9447d30afe444f69924c9cbf9986577d0b9929710928da1cff9a8b85cefdb79c1b21bb12c513119bf9694884c8eaefba81dd4893c93e0d97bb8b70ab0843e0d36a24d17747a7e7dc26db9bb61316f94113af354b21e46b608e7d6a57b3aaadb3402f68b8151cc740aa0eb10ee8da1e3003bfb004cf0132ed0289fe784d7c8af65ebce7d86ce1e12d438219b85389e7c67d727c9be6683a12871975e3785ed7ea43f3275a3b78b08c8ff8bd2cf4c2d3dbec2f39544dc726493ab3ef2536f313e6a77bb6d623d8e8e1b925035b53a66b429ef77111b22d3f9db082c9e24d5953a28d818bd47ff27b602ff680bf42f98461e12166a841f4e1227f83a97d0ba85f057257243dfec59ff6e8a16238188228f8d416be52ed655cb0f5b8d7ac508023a981cf238d385a66eb102647e6e2185bae0c4568c1efb09af0cea464cc2673eb0dd5263e473529a6b66e643a68bcbd5a15a0d817ca9a10997debfbc8bcd4bd0ccece7fed8b3d5ef0492dfe676c7bfbea2b52e792204566c96c39154b4a62f2c031cd0761a21ac84a8a9c694d53251b544315675a40e9b407f4807b8dcb229be9a54fdb4eb0a8e58ef6e83f64e60c5397ff2e62448ca933009c111b85c53b247456a8e0cfeb56f9f0f31db62cfddcb24cf35a54951a7724a5dea6139df116a6102239d2d6b2734e0b9762b3e0d11cbdb7ecdf3ddc8262504ac39e0fc33de223abea3e3bffff553220fd7c449afe7c0d88a5218d28b0ae7c597da4638503d427903917faaf9df0df0b526bbef8ca7427706644f8fa3e83610206378234a5605d68ab44f7549f7bc04bd3786f33948b60d25225c619da3fad7b76b38cde5bb24ffbc6f36eee4d57117037851707b10fd5b2345c786340c2156fb785fd1a24277bfb9a82f52be0c448104281cdf1dd4fc44bbc0ea535b918cebccba708f78637e2fc23e67849ca2da7055977fa38c8fbf2420b3d68df73d47f10afa87dcbe4315d8fca16bc62ec365f7ef8584d43be3cbadba65bbd11889596c90d8765e5f632487329acfd2192b74c4bbce73869f68da7e364b1d87cdeccc48547ee376fd39bfed6791e9df7fb7618b71342c74d4cf9706f9a4cc4c7daf4c59e5159eabde73f4db0c164ad5b5986d614bf8263ac728375e2a722c1db8ea82cb74aa312b5d85b66ea1fdf6bf2a6c8e781303f51d0d89995364e86d46b70f72baff39b3e822933376bfd511ff4fbd877ded65a629cb433e8cb1b313333bc0336ea17069d8c460c9dd54fbe16ecb198563e4aca3f98ed055befe295a58bfe05018819cb973a327ddc44c0536c1a8aa511ca8694549dcce404661bdbd14f915df2c6ebe782e73ef988a31b96a025608d021882b68244c841ef86217ed97146e3d59e84dbc61290cb312d4c20271f55f2a8931a4b1491113401ab6cbbb94e8a0151282eaf34eb423b31bff23745a752e1aed2fc57568ce222b8efec217ab499146b3741eb9433107137326b8c5d3411ce467fcb4fbad9971f5cab0334025f33a6d5eac4baf8caa953fd20418f3a08296ed1e9c69ad84f9f726c98465cfc0c440a3ea6b57fc0f8daf160dc557219709cab043432a9dc01de9f8bf4f551a1ab22d802d66793c887da0c079b3a2daf731cbaeb58cb648c6e350b3118bcb80b5be4fd7f2dee182271e7935c0466aad2d31a12f339c0d52029b5108d0702b9ee9aad2c1d0cda345408f90cdd2d60ae9bccceff4f921a8a323d3d5ac6af26e61db8cf7e8a0d8f00c907cedd730ed13a3182ed2871c1c9a2e49d40f5454eb101e9cd94b7a805120bd0e948d34bacac14f96d8e3dc6a262f3278cf3fdcb0e460618db29ce2df78e39e83d9c7773b3ee3f8e24f4e985e78ba3e307972d9fc277b0687365208ea4c1d38285bf1b1ebd6c386055c20145d8e6060d297c67962d049aca38828fcfe5bc8786c74cc5c2c21c0424839984708b7170cb78577aed3690e62041bd03748448f749d169cac92db3e24de44a5bf5f108c379599d42cd898235c907357437c2367167ca841ca4652ef32556f590475586821270b2cbded67fc0786905064d14c580608bce0255d33f21d2949fcf1de07eeb63ac3ecf8b9e8d632fe5baa3997d7c2233a9c37bce1c3052990fe6ec4f1a84fb037fb17a2f0ff6e90efdb52eaf07a0aedb8f3facda4d59fc12611e01a90f71f3657abdc33b0f7d3d02e772f32cc8037ee3935d6b32935830d69c034a1877bb73da3844a5e4a9f5fc6cc12692ba6eecae7c89bccdb462dc7c81edb0a65a97ab965777f8dd6bbed9d734cb36d2493d64012589bd6f529b157c893c866343f17bc87021110dac1ccdc560f257483b5a9f42ce5645f4b773fa84462d7227c85334834764c2e65d0c410a134b5c82e0aa4b35ebcd80987d907ed47ddc5fc9a3552e80bd0ab51a1201e2468e1455f3e7b1ca9b63c6f2dc1641065dfbfbda817b65e6553d74a42479739426c495dd81ad0ece43abd657f564f1ad5360222c8da00d1da0abd66c88176dd4e9ccfa113630606d7817883765665dd308e3ffb5a44a99f0561c2842e3b4e0cefb64b6b01a23f18e5f6b55c04d5b2202091eb47bf66bf19093e0392c6b0c16868cb8e698554ea7683c516a9e6ca7848de0018b77e31d86dd3f06256d0dac0312ab5bdcda836ab8e7cf663a01a2a1a2fd0cb7d5c5f1a8e462519e58642d1f4ceeb9afb76f59f7635fb051e116f555b1378a4432a0633ecf57368b993ffd94e14407e35f9711aa62fef293e824035ddfc3cd5354e21fc9576326ea79121ddd05e12a268064e07d0e023828f16fdb72920c5749765a32afe788067d0a16f8d9c09ae624b065d6cef8e79bcc44c02675fe54964a8236fce226ff020aa951bd64826571ea289017e424a53997be347341abfd865baab5c76fd44475f885329fc7457d2cd24c4bef6163c0b0d294905ca9f3569945a2bf191f72519a05948d7a60937c73628493b0afcb56e30bc0cb43a7eaf02f564dcc00b87a6f18d3372cf3d795b5082e9151e0854d067ecb439a02b17b352ec0374c31177da92308e8a294a00f2b70876d962f6fa30472e909aa6ca540627c651e453e8a3dc8be31fc86b78a76d527596768d9dc328ab584ba9c3a838b71683ccf914184f02c9b86595b556edc67e27d003ece8525105a4497b75b2afa1729b6b3cc5fbe8f03bc7adf08bea68d4f1d1f0691b3dccbc1dc52b44e9247326ac61ad3034e66d3cf1f648d0e1cb3cd89df5fa1dd0d1703be6c78093da98bad0c6f1a5632415cadb8ee7e146804d37f48136a81efe221432bde0a79a0b524c56db635c5dfe6220524a5e2028cd055397a26f85545c7eca12b78ca10faa0b2d88717032d7e816bfea16f0f16b589770f19b8fc850cd2e4e84f8717dfe2433fd774ff40c53f428eb7b89e4d52010334c1f9d27944070c42c64b59251c2eb6117f574bab20ae84404836b346d8391b25bf4236dad98b1b63a7e68ec0aef40502d4f8fc7261d7f63444b7622a10816899e8b8c770db00027133d1cf56716172b3f639b59a701b37af34dc76a7de4776ca77cf504ced0257c27a57e77f274532f4b217177aa9cf28b6bb5523adaea03985391a34f67f06edb10f13e83e7a38279b893db6647c8845a4c0259883577a83e4d3e1c945f044f3d1cf1e687369c3ad036ddddca3b6eeb42dab8ee7b9b81ac8f13750324d9583a1b8b5322b47cd4a040cc5d9f823fc517cc2e3e405aea619c281d02727987a7b134a15de2ff0b560c1d0791daf024011b7340df5da612c44e5eed676debec01f2080390883290a1ca257e103f15a8288c2db9e230f0b004600f6fcbc0b1755ceb073cafe3745497d4f8867d2d109856a73e8d16ed037e07fdeee6e3ab7c67e6a59713e8197ba7a7e8282b82e7a0f9d5ddb34e82c20a3bca7d42a3386c233825b5ecae0800d821066169f955c3effc34f0badefaca5cb16723644d00e4c3e3c564ee266c9c53a66a9d9c05dc2106b15f0e4876d42e342641401e4b8730f323aefc626b4af118df949e027c187f312f8240545fe6f7f14f15fb70388da8805f16d27abfae51cdc10071cbb678b26f6f4299ac1fc26a500c0e9c5827c737070880462100695918d3560ef30a3a41df5f9b433da349de06762e0507e14ddbbd0962c245dcc2b9a060bddd3f41aea6824e2a160b4ce4983e04ff88a1e524c56677d71305ebbea4387e46b28dcffbc20fc7db41a85ecb305fd5f204320f0182fe34bc02ff9100ffbac7e0a6a969b621b1486b9787d4e4ad0543bda6c5e43debc84408268df2b1828d14d0bcfcdab1bf52051ae32df0baef37ea77a0e311b0dc817146643c1b5eeffbe85ad49c757291895b08b65ddb39dae54bb1e0639fdc948440e1a792e7d12cc48bdc7f5bca4cc98f8ebf778de000e92bc5e805a709cd9cae0f9830be3597d545561d3ec418e3a8122188d250cccc578600b39b542ea3e1059c2b563486c897842a89b5196a1c35c480847eaea307fc1ea0ec38d904cb0224d2cb8f5d53afd32b917a4c7fea376030e6da56750540dcf6cb23d760149f7c16344a42f7607e097a3cd985e2b35fd77afe22e04fdc5b0f1c2e483e6b7a05b675c9f6035e29723934d60f050c43d381d328247a17829cf025431b8e7c803561508ebb35091b790b72fa5539927a21ad090e2df510662b897307a424cd380cd252f3f231326bcef276adb13f3d52e461ecfefa94ee89fb3473afbb62b0969f73ffb99d67b21444b644e207839278c6598a96dd5fbc1a185e1abb6395ff4927d14b707a2f1d3faf58f85ddf6ecf5329d8561f814c51de8f6c1f19e07f32bf9323ac5fe6f5bace5b476c4ae403085110bd2ad0585b891208a40b54c1fcb84d33d8cc3d9c47cdce5ae1595c4f80007cf4b1df3b644a123076d9adfe65f2d6a1b22393e3d01733a7185b04cc5f8b6204973269affa3494a963efb2dd603e7950d6056610685079e5d95db507a5c935cd306f02398d1564103613cfafc2a0ecdf7f793f0c21113d2686b6362a6e40f22773b24009ab6e91ab26964612cda4a36bd20cc1e9615cd0f73422a2148ab3116537ecb468e4371b3b65c2042d5b8778946d00c8ed0f8ec2bf70e329b66bf0fd1679d88e35d1c72361e3a30495efc0ee9712edfc27f0b6d6fe539bdecd1d2ed3f40e74792e74ef74ee3c8704ca4347af6e0f44d7a622aa6c1bba98f4d14643754156300cb84fff44f40b36835090dd16e719fc99e694b982988d8f24e9c3a8dcc088d95a7862d863c426fa48724bb0b90f8f78096b59735d7ffd708754e825fe405d3a71c2dc42eebd6099e514dccbdc75ac613c194ac9f0602280a83f98a7563bdb7ac498ea6d024d28719dc3ba132f4a5087a1b8d5d0dfb10d837a17150d1877b87eb3689fb6bd60d373111ddfc6a434983b6a5c0533ad4195359510df316f64046c7117e19b31685e6c60d4d875ce1f216280b00a546b19307ad0e381d007783e58b793a3b5b0e6406c992d0801d0df6c99ea6d6d771d9256ef949b507887a923bde54b2eef110861d33c1558870321d30100af179b872abb3c207d311b7759c32ad6d06daeef3280264afd14814569eb10fa9a18a25b78ef0e2aabfe2660403075a0c9a1c6fe3cf9fe82d8dad96ffd3f407cebc7ed4704c8092e5a8d95cc2e438cc606ac1e092d6ef72758c2d60017803caf0ad413bebd45eda701de08717c768da7b440b433d42d04dd0f6f973df16506a246b2032cf24e01e0826a0262da609b87914d4368bb16ab0c35c16c8cfe3a3cc738ef4e3a56a810c8c62cdc40bb121da1aae6c911907e75f42cd5e0a756212135650e0ead81f63ac5f8c521e522d86f0ce45eb8485f9281bb138b93430395f5e5e7db556b46dabfd0b15a9a47f75d65264f5123ab95422c8e5f8ccfbb55d481f8532eeacedc4f45d86da88a31ae93a0230cd3e45ea2e91624eaa5bc3b63d74f868be2fdedd83c1fdcd24f5c9407e7eecf780c5bc74701b792c788a146dd1107348c8f4cb69a39a93081361854d99546261afa9f2e7cdcea7e3e361063ec8f54e47bfb5cb382690b5036d20e8127437e17053ae7dd9ef5f302e3ac9dadcc197e37a346b3845d95e50e2f023fb184c9948a2bd441d02d840b3baa551082bc50f6c2f5591eb2f94ccf04e2e92aa970d2a53ec382f09c3841f15452f331062e3a5041d89eaca6464d24171c394f3f568962cb119a292da9d6d0ebc0836bc6a791260feedd878947863fc2f30bdb908a479091a50f70cb363740add9b19a26056101634e84226c971caab804dda3fc9475774245ba63453bfc01d3a1ea4771003fbac56a7d9ed25c1032ad0a72d71490e9c0f1eb888c04ca2446af89f6debaa211f1cba467c66f9b6a7f4f541587414fa11df2593eaec07e4ff0702e3716b723e172a41a4e58738019e2c0c22bb8b0daa92370a6c2533899dcda7685b4878e452d22c3a679a60e4e8be9e9c57eacd51d914a3dcd28aacc2b79b2e19173d3bfbc47347ad9f79b704e82b4bb1790546763ebcc0e79965aa6b207b86922d1b24279c28ba44742bee3892b74bad562fef0477547190f8af031c33a1a2a32dc4de3cbd3ba7fa0141ec0d55fe0ddc5f23d423488e13811d9b7b03356a9ee70d1e919252d542f4534ad0836817c53a76ed9dc4d45980654952305b73a36ee7964e7f94c7f33c22ae2e9d385505ea0b89fde8015c7a687840029af9eda6b109a4890a5a8ee18842210ba13602811fbaed726eea2d95cdd7834bc9df1db190db964d058b1f985ceb10b50f94fe1a7e65747bbd457b9dff8f80eb00539a7336d2b681619eedf33a09e5f4f96ed3fe12c6e93a7e259386865e6bb8d0778ede5c08c95939e6958adc40eafd8189cfffb2c65f99f4c9344bd7b29e470f32c874fd102b3dccd6bcca3e9c191ba38e3d2c91a0801a2032907f7c2c920085ba8a71b7b9939a0961dc9f796c0187cdbd07919eee538f47a6bddc982cd49c4ffd129e76933de8e158f44e1353c704c26e42891897f58cc8b2349a67859289c30e9852c974c4030d398932ff5a1cda80abaabba6ce93ef20d8d8392d4a0a3e6c7121c9cc24190ab68dcc762df4015eef827acccf11f554ceb6594ac7c2cb6e51ec7c03c3e163b942a750bfc7f4f1539c33073c142f0b1be9a69965399411dd3f6c4df9f5d9912eb3ed09e1191e3093dc1496e88ecd03654e65bc1ecb14ed14a60ebbc913cef32bff7f8f063f43a242e4b3402afca766719d56fd5325b3f1788d49b7fa3742d5e3d1b0c8c7a1ad9ef0100035f7d10a50ae442e4d2d9c6c8417fdd3cb3919b9a2bed815238e33b1161a69aec9ca393a875fd823e8ce9221a276e2b6c13b3427167c99f768b31db70f8f56648071e73e257eaed4756bcf9ef34286b3661a23f93f41eaff6e00b6070257eb736ef34aca3e06002ff8ebfe27ef0f3d65411087707822f40139e3223cc1cad7af9dd21afc0a6632e0e87e838fc3c112a695e1634eccf67dea9e761fcb4c24f0a7ffdf576b1b1c1d5c6734a50b3621a1768330275714d8ee24e91dc05f7e6871fbf2a20b1a7346fbcffb614e251bfd8fef687dfff77d06dea4d1e09ef2fcdbeebe6ffd56f4f9c84ea71e97255f819a5ce34d406435f24d75a1e1f2454410768a5a780d6cda24647a5f968b418c5739aea413e21c8739680824e1cb4f2e23feb5c30abe397e0e0da979fe79918f4bbecee5ebde3df7ec169ff1001f6c8a8410eb5c146d2caa3d36e11c7ae20a651ff4c49999c0c76e19991ef4ebb247fe84970837c9fef1752cf4da64df791adee734ccd1703b1967cda82c63dac5979609062423bac67a1707e7dee077330c40e557b5dfedcc785a3621cc2fd423cce8928a314575b0e3c4765335e778be730f55decab94424099b482cfc29def59c8a7dd88d6799a77390c2fa3af9a6d7d60461a26be36525d32ea93333af46bcd989f50878685f61081e87d42ef12d8c8572eac67ec459d29fdcb1c19ce4429163f726b4d86de1cea274d0084dad4b33d7b1c09541fc568b5444593207912ee3023feffecf97234473aba21b7232e6a497f003be931e5542ab8932dbb9450515ce2daee75b64cdc541981cc18baf1dfeedb6d3c76b00d84f9aaefab307b02334e24f24124432ba8ca8d32b6a51e62bcdaf707689bf170571f2e647c8e020d5a7b0584127a37f91bd0577dee6cd8ce19ca30d65a629937811977d423b849c5be4b3871194d13d1c0030bffd4091944b0a488022c9de8898e1aef743643b1f9913d2c2ab610e470fc6bb314b7a80763ed6ee8f8a585721fb1405f6d0c6472c96c81ed766bd466729178dbd1808002445f9ada8057f9a205ff6d03c2abc99b34f9afec32d14342f6343a02656981d58fb747a3b75b15ad7eb40ddf5d366e548869d231f900e85fd774feafe173e23977d2211692c3a9b67112808758cb1c5a6003548a0d1dfca9781e5a9086e9c53be47ae49a18d2bd0ca12306c2ace63d73dc5b9c2948992d06b900df6206930ba312049a632877b351eb4d9846f5de4c543aea061be8bc207885324a38547e7f3d59349d1ec99162d72b78372230daf2a88bd5458272240a729c737d4da7e4779e26221f1b77df5a7cec0b8b205dbff86f71732eab9423b990f2900a7f1d7420bcc7ad82fed3c1b131fac61c6aff72897c9d01cbc8e3e298a00e480e129cc344a236a38bc6e2616df6abae7c1523bc294e4853441792d57728aa18e234c195082b140f8b73d751f18e209a04b2d246df6e50e78c19e752146d54174a780414bfcd8ac2722d1b642df67df3126720a5e47f9f3749f790db51967dd570d05a50559f8f2308532720ed24d2da0840cdf964b575daf006cb5ed43f0f4d53c03f0962c7ee926d6dc18308d79b6956489fa64f7ecf84e123eeecd35f91fe55b3d8a62828db98ac44a27d72186deeee284d268d951fb1a5413bba5d9885737b54b19fb039a29b2e493bd6177cb8b8b6cffb5d130b4c9653f1ee3046de38b05db5966be41298d0179713bd666bdc720a4892d6656f8abf3d8b0f072d070649f09080f687f63c1ed34b7384c3e6b0bf6c18807109f1cf2fa67f3bef9d16c1ea1c6bff3498f6492b1267170f56c789b957ae4561f3d123af3600beafe857d945e7c8433463dc1e965b03ae85109ce253d331dfa4e3332bbf5d443c29d1936e7fd37c0bf41226c40c0d4c3f8d923f16cb9c57db5f1ebdcefcade110f8b40406d8e4f63d89b86ef0a199d8e21b224d3394322833c95ce1c12c20c08dfe018b4c1e5dd42c29f953a1f6734af19240f4632d01bd12c897ab7af67a58e7f75430a8a4fe6ecab10b4e8bf556e4c82f1bbfbf875fb5986293f516c9fecc4cec5bc439ebfd7e16eb935f111e5eb20012fd5b9f0f9033421c1b6836560065d44084758f3bebf9a3db94e3922fd9a1e4d3fe7f334225864bb23f7b9a8597bc0e627669a8e7a748c09b83ee7b26b630eebf43485b984f6fd7865ce6359f7623d119bf6e645d34e58e2fc7dfc1c1d4baf8c543a57ead500ce6d6a38657585975d34cdd9bfea4ea6b2b46243545f914f8f08d8c1e1e15d3b0a6884813e0947ce2a3a53c628b9fe87e509a0150f32cbe9d2e8b056c2429538326e4bfb499ddc79dbc203f1fff4492d53b02eeb9320ef3195dd7994e1f8c1f293c23a76a3fb13fce83dab58ec091e667b16cc1c557abfba1adbc852abdb1960476099d3b01adadcb883c1023492aae49404338730b75e4834e12c3a3573219da09d93a296ae4f6b7f5b127dcd245cf2549c714a24ba6f411373e1ed0be7516296514a96c6ee3c3ef0a4de11b38ba7c6cf9af282cc9c45b69803e45252a35c5c4cc950bdb4b1764a371a103a0454c7d43a1f60a2ae90b246f9023a2b642382bed9b0c17342974c85778f0fc67fe577bf8d1f944fb70d7fdbc589547c5ca4221772a83e7636c87e29b9445d1186e9b8ad585f1df53b2c92f788251689fe36e5564806ee450c36f1280720d6147c027f2fcc715ebc7ddacd1a016730b03f637d519b31a17d691d0470eae8bd36f944f21317e1bd2cf1c27a8b00bd7b9040b88341dcab28c085564b7a37b6f9e9faa9416db9d1e45f25056c49b8f81520f0382ba1ff8b564f2b0163221e13b54bbdb745c8081cbf9d5a6d94961862696e973f84a009a309e5b6c4dde339dca1df35a2d7d09273e32b59fab9863c03685cbd98454817f395cb899b8e4a0650990d3bd7585807853f12c26e50e1d04168efe08843b49fe8331c15fcb0b7df197be691182aab05bd0de73f9b45fe874654213e93079b68b5515a7db956066df092ecbdb50856aa976e3434e7e0c6f93b478202574555744ad7a67412f8205e6fb1fa7001d2b8a78fdfd01455303b797b450d895829a4d5a2ba62b02a1699a8853e8ceff64576084917b0b9bd90a708d8c22a469a245c03c9c4e8b4d608535eec1c0a8d28c9d379f8908c7a87c2e3792c55a697ceaa1530f66e05aacb55abd2c5e8c4ece658bcbc22a63e6378c3b129887dca929ae39155d9d2a9085ecd049f5514f8eaee2a50215fd10ad34070b4698b316dc88a65f651acaa023288aaf4644f456c886a896ad93a369334ca22e6370f1ed929d48417e0aad3612bc022e0ffb52a21d1fde6602e1f59da088ee4558519551150a59fb4baa4c05bc67222bea465a8cda8e81f897d27dd35dc091c96972e69f0e0744932bfa36816796d83262378ba47ceb4e25915c68eb21d1d56840d6fccc3c681035d0a16d31e1581e10ac338f0db408aa5b29fd4b0ad1b31536c5a0995a976bb165d6ac0f90be033ba95716b36a7482315a9cc79e97827b1abc28dd232c2156f70c4d1a3f1e7b18b5ed02ebffaf7073bb015020725a9e26fd291d43a3a18f2800f2e61b1f38e9b76f9f062a093674dc951eea14732d2d2ac93fe0ebbf79f5882a7aca7ba57e0290a1ff0a15c5a1cacaa78d6b2a56bae3b79a1becf7f837d8e4cf9ab559e08fd3c8ec1f34e48ff4376525defefbf46a85f2325c913adedc433e2e7a4078bc5e2fe9d90b6f62f781a914127744444b7ba0bd67e38b03f38eb4c50fd659e75f6c0983368ffece99a2392fc42e23e8f3b173d7922ef3c1eace06bb8748c0aa13adfc19b2953e196aab2b7834dfdd04f0520c03550bcf6df4ff5bdfb7ce30adbb27adfa0ccd0e1d6895745a21682d5fbe0ad39f5689ececa7d1bdfc8c1b1adb9286a6f0e9793671841244b76e723e94216e9a4ee6f8d2f42843eadcddf36912504bde40e683a38cbf970af2d4183f1c78f49d92b364324dc35b0c75c8cc00bcd02b8f818ec91e1f89df735f933e4ff81fd7c2cdbafdbdfefcb6d2467b0b5910aaa84a051780cbddf3d5fd52910d31be47256e5be39e40fbac5965af40d199210a9f1b7e81ce6c47a4f3b6427ded880db6007a2bedcf66b1ba6a7710dfcd079f5176a00fccc25b12c2a66c371a271710c3dc70cef254c0c341daccc062dc7800570be1c12b082bd63d4c1f2ad7cdb1f08b5a30e1b8973ff18040cbf1320f0d0e95b564fcc94dd68d97a455e464e69c1062b85679623266e3183c94e06eabfc4332d634e727a0038e59109ba347ddee28c068d74134992420d2caacc2c1bb8cf0d8f14dcf8c930d851b08ef59fd13e3ca3c2466cd912a0091d2bceae98f102f065a8566b5068b2b1f5da2edc7406d58ef240f780b45448d432d8c780d68f6d3e0b11a2c07fd6859804c8e28ad5342c666102510082c025e0238991920be52b21a3356aca954bd6eb9e39318701395325c5930271206a7b6871de2a5c37037e45e07ad5c55624f14416063c160012a0817da1134829299e3e370e3181a17c6054ffc56ccf902c36a8dae8d5c0fb6e9ce87d395963012805995e43275268ea440accf2617620e7f14573de637b27ecfd117cc1e1541bc859cbab0158238c5b54da9561aaba7d1875a62264b7650de83b32e588c3f0d0716acb3a1ce6e6cae2a080bbbd4b3e5b3609234c41de6681ccf7f04eef61c9030cb22f65473feb7fc878a5f7fd83475dd2f4b3ed77815ac595867cdcf9a9060b71672024ae3609cadd62d5cdc24483325c58e1ad90f42f012adeb74eacdc1e8021c7470fbf122618bad4c88876ecabe808d531a85de449a8271581be4de728f73f02db9adc53e64d674b90ad61994a4dc4eb16d5e3eb8c20e997247413a366156a7a4edafe662c3c3c0801fca05799c4f878301ab0e9c9fa6cd40b3e092b26788189c625e59e2f69273501502c1a886cb454180812a93f269addf13657a67e282b59e06c27a0618c129497386c99379edd48c6b8a8a8ffbe982ed66f201184e1fa0d8141168211ef4568c4c4720404c893fffe02f92879edc8ceca3bcc7fb6bd62cc4368fd2aeeee7f88f248694e8e7afc4a5c0f5bf8d61625ed227a1b1a0b9e9358b1dcf92f2138fd483127ea5046888b389201555cee98439f08df19745a69e9792057a21b1f4e75e447569916d1301505644f0a8510e970fcf3427cf22ce6f28471d88cd6bce768ca7f4d0d449316b9581221ba501aa5d9fb58fe4d84bb068c8f5f20af2e6fe3c0a3046199a5ec2ef5d6486d7355a76cb5f8790b3415c0931ca7b32ca065e36174280a6ce2ddc919951a7464ac6a4db61ff61de1f8e6c89eb23ded61bf7ddcd32a4fc7db45d0d9891684cb414f759961ad5a41ad3bb14186261fced6feda0479b05bd99a78d639a3066df1f5b08dbeb0c9c27da8f7744e3d98b9d4082b17b10a5f0593119e0cc63c3cb48e253636ee70b3a84faf0876ef0b387670e641b5fd2577fe838c920e2e9b9cb98ac698c832c9fd54f5fef3fff77c06c41cd73346751d4a7c70fe5a4e41a05cbf9bf8fa4edebe16a52c4c11b2416d30537691bfeac03b28c85341cff57c7fdb21bb1858d14aea4e4a0ebd69f1df88770e2dcfa40450ecf8fa3951eebbfec871d043295c0173ce751af4e0650e9842a69f58b0a1a0a1e795cace27e05a821cf4dcef531d31d0ad20f14c75352f6c4e1af3d57ad52fd4f57d52992e2ca6bedf1a7d7a8e97ce59fccfc40976264c844f881b0cfa9c107f351ef2968e53f8c84ec5db6e40adce48a63ea09bcdced80cdd57427f643e15e8f862bb02adf726031fa2653ddfa1a30f9af08abff25da4b45bb8a122dd3cde29cdbe1f6b0c24b32a94fe483420c91e8c130fffcef401fe8f9ef0451036638f6650a337da5bf11d1237f8216be2b09f3c233672c1f87a57ee27fbccd3e828b72172c5f2872dc487665538c96e1dd72ff394598f69e5896dd3b81946ccbd295032d9815f83a0d026cab3c541a1594bdd3e7818b743047817e7dc11d50b0d01751be0525324fe270d7e917acb042f3a35ccdcf27b9497a9a4218908c3ba264e88b02cd43e6b8938f3c13f03b02047125f5f327d0c6e2125eef895aa3d7e66013556a4c56cf3494f20a5a6160048de5ff8e33f605367c062c23f17ce7f489e6d517ece617e1883cac7730f69baba2760b71484a2723a5cf6aedbe68a33ddc3ef7791279d16b785e094d6ffbedb998f54fc060699a373c7dedaeccbaff5c696ee854b6556e04505bfa761079b2c0cad0ab2cafbac49774a7050348adce7584e07df446ee95aa46ef26a6138641b099895f97c90120d3320d098259e62c2ece5025322272071f92a95161fccba3b73d18f0485d3ac91bec90df3b30dbfa6410bf50aa7e74364bc4f71797cfbc681886eaa0621159c0707262a705c8f42cbbd165fe83d4aa3ef8686dc3a603e7c4d192587fa809a7c19cedf30cb51ee58875b508918bc411dc98ff163c9d7ab2f12403f440f876fc5d14ae2cb624a2e7f11c15fa9f49105af3694bc88fe1b3e49997df81e58fb997d339fbbad324e626a583282279cdb5daf409bbeccbc080f91cfb4c576722fed3bf574d918f7846d857245fc73457e6532a1cf991f0c9a41429c3cd33696396a092f4f5aa84ee710d89e9020cc064c670ec4186b427f2c1e6cb6555d4822578236e48d70ac0ac04ef7bdd330ace409a38843ea2e4ace31979df7eba9fc74c35c149c7c6a88b357b92c1b75d59d512013741b45969c54bfefb89f7cff1c35d858f0f1c2a2519b46e33937f56263f6b9ea349760dadf7993966e557cde75b29ee0cfba9d3d7bdc41aa9cf9541695808b3c7833d3aab16352fd8b749e9bd5c457edbac0f92d4cf71a8d96b47682a78edaa0d467ebb9f355e6ba5e65f9c7ae668e30b29dd089ded68f6b2df10fbbe472617596fdda6c8e00e664348a25d8ae7cc4af4c7fb7ff7368f3b1ec0cce33201ad74a300c39067802f3a7669db71d875bc3afe73d429f74eb2cde3d2029fc82e867610dcb487ad1df03d3a876e38c496bed99c4bfb9eb321ee7ca7c8590839b66fc3a4ec78c335bd79153afc23b0a0978f052beb25d714aa11caacf44d80d0b8b97741b5bb84406b7a69c8d57acb06f0f064f9aecc4de8a2c2b95f1d8b8b508e9da3ef637028582f5baa7411be43cd8b143887693c4d2b0c7ca28b3efbf27bcbdcf19be83a27921ad519a6e411e9970957d04374d9d60f8f65774d1a760a9c1eef61ae07a425e66ca735c7cd0ba663982e23600c8f8e287586cd41f1a886d5c21b03a283976332da9781a3ff87885cd539b0077701406a6d62e6515da9e2a048491f05c48a49f0d0436c6a10b36708bcfe0e2df91f851d7343b05ead9dcceefab81dc74432b84687ffcade5b3a5d3ba8744fa58d2fdcb4a366191ad292ae840b9a71855db2c1c3fc2a88ca0cffbcf11cc12ff71192b37b5ac15cb02a1b8247516c52ec9e7e1a0bb82aea480619518057c8ac85799c60c7ac8fd8ec3eb611a467c273ecd9108a56d6029db0420107618de084edc93d09c83b6232f5434949898ae9f826433eb3fbbed52b1509bb48cc084c5acad143b0d62c03953bb0f0a17b7e5f7e7c63e538cb505172b98fff2e166ceb5fcc525a9866879c87dae3be5ab65e3d8d5779da23cabe64ccdeec47d382475412552e0541d460bb19a65a2356f27acc394d441341416ffbf8572018183ac46cd1280022115bb1d51b776c61e005559738821c67226b73beccbdd4b6ef9eaa10df43f76d1d4489c59eac32c2c6977ef2157f84ff7a1d719fb681090cac6702e9d914d36aa8d6b5f0cd2e6378bd83d943bbe8376575b3cd78a7ff63b4424e9a1f7ae415048ecb6202aeb020011108fbebde7cf001c03300ca0135a56044f35a84502ad4e68082de90e6006ef0f5e8f0d1e6480d4025696375cc8dc4e9fed3799e21edd5138d627152ccf01e411dca1f8a83deac5df4ae736aedeb315b8cff43add3ebc97408300ef9c59d20277f77a5b023b79f6979c1f13f8090f613de7b6869cf0366d9cc7fa621b1ea57a83fd090ef76c3daea76c43dea3c9f91b78f84da99882f6db30dc984856055eabcc486a2a92919bf9c9e261a2ae020f53d35c8397e8b5d7fc5d3534f5aa68ce4de91dc068d8fee3898c95bf568b4eb06445d9e806805570ddf189d08211827e90559cb7d4d2dd2b9ed79a2363cc42c151f3077a339b3e2b5512316f6f3e4a30921af1d37ef4c42e1b9888b700fba6ebd4c7483dcbd6ff67fd50fecce49f1158149a069dbf459618efb2d401fa8109bc8a305dae68341ecd47146d2345df8f70dade6e8ac94f78d7b746e660a1f93fc6bd68b288970c507fec3cf080a66f8b7e45ce19bb579a6cd4ecbf97976770074c45be6f7b3c9fd32caff7bca21d921ea418cf19fecfd45d2ec28f8dd8bf4a4485e4e16f07635cc1ff84a0a0baf69aff2f6df0e27aaa28e13add852b72f69979171b47ecc62669807c24689ef34caa5e960c56b802be3338cd6f81b781918f17d670d4ed66358fcc0bf4341f8ac9327f340e67e400886ef9ba03330546d586b71068bcd17241d7270886caecdd8db48b953c1a2a9d4e25bc696684801413a57993883018f478c4838160f4b193bbb62b401cc4f9b35e8388aace39f82be8a9cd704033a7c68c657bb1034802ec60969e1c3f11963c37473c68a6eff74dbddb4e5bcd8bcd8b00f8b0f0e4b8feacbcf7b51bc5ab13675e636dfaacd39606b38f1c24cae8765a027b26dd44da7ef872c20bd0d36e8559f372c6dce3ad666c805258f92336b79cbd96340710e6b1916d0f391804c9846b8860eace1a39cde73784533ccddc1be5700c608f21165eff24fcafe7069f08fdaa371fa84508bc1ce1d89c1c2beeed807e77603e7716dd0cc9824d07c00c829d82eb0da413666f2e1b0eca2ec4ae1a36c2dc6672f0b2ef442e5c0b18ffaa917fdc17d56ceb3512cca352d659dbf9b8629d292cc1a7a630c2648b0998e1b3c3b9bc169a521a614138d89f579f4e7c2714a4f57f57e38730707ef9516f753130d44403af3a277cf413dc3f762aeadb0c918fb1896acfb4c189cec9c36b4671d8803c5be4f1cc12d1c6983e95d8f10509c1f9a61b491ae689195987e856931eb384db3e9688029d3229f7fdb2f27e092a098805cb6e1a2323a63ff6c58f370fbcaac70a1daaadde1c5bc1eb3feb0fd6e68e44fa0280a9897cda9798235bc188622bddeaa401af18f60e2e9525250db8c7e56dc54cf00f4abdbb9a71e00cec93505a1285fdbbc5187567f5acfd81e5cf8173532db56da124a29938b7a60aff8fed7f4bdff67148cb38c6ce416e21c36d0398a1455cd037f537fcae49fa79de829905732728bb1ce510cefc1cd6cb389fb3e35627ad3767e89c03bd2ab8da14c69f08d76e7ce7bb97d941dfdef5061746b857d9993f835f9e96075ef911d65d05cd3cd09419c0f2efb7d9f05ee94528b1cf6006f30158e70a751bac1fc0e9c60c03c231ca8f8f24e438d3a3f3e2b39e6795a452b6d870c0b1f114ed9f5c61c267c4a377600b301b50cd29d29c585b386f9f7439b375e6876d44814710c1e2961aea3e2d23f6bee6077d02b6494e67003cde03953666a98f259340f20c7bbda9d183eca7e0eccba974474b59f00fda4dc586bdf7c3f330fa1a60464adcf296a057e58d090a406253483762ffc07996fb9ac58672030d46deea411067d60afa0aa30082949d64497def516a58d0e490c5cbc86f11d3042938f47f85cbc7ab6fbdffb418fef709f5e52a25cd0ebc5552b1ee1fbc81d0dc764b3f87d06b02e49043395e7ce3fd95393038f3334b41dc55e0ccd7cbcd4d9af5932f58ca0c3ef9d34a670956596bfc06fa066b0a1f2514c4d2f8c228a17c7ae2001c967b200d1ad2dd1f96cffa2edd21836bb2d4a7effba7c99557e14e589f79d6679eca9682f1ad1d2a502b85e6a682f3baaf030bc79814dd5cfb23a65a6cf76895f992fbd935f4d3832a668799d9c55ff087c8f07cb4faa8446f164ba5868164d647f95818287bc120077f3704d6a92257ab6947f809c13bf407ea1f26423f41dd980630610e391b6463c8076c1474e267688f1dd068b5a8563bf7b465d39d8ec1ff8f3a04e0ffdb4fe1612ade3cf00abd10010af1570a6c690eefbfaf256ee7fe32d5c6489f9796bdc46ef0d5cbe7728e204a234d273060f61c74b0219cbe5f3d8da244412230276db2585e4839d71f58c2d0ae270c02b9503a1ddd54aded0afb711f866c0f46a4e62f184104eafa95e47872f3b482b3d35beb1f62fb1a83d35440b05395d0bed173b63fbe4b554f8ae7dedfaf9b0c4a415520446e8a6d93b55ec9c418a45dcc9ac5850b2105d813b8cb335e6419e2b2e1b70cb20c928cafe61c73da6d28ac82316c43db0cb004c52a833b51e6fac2a23c4f88ec53fbe0a4ad71e6e6729aad5070fdc393ed6058b627b4b42f407c07ecf72ab91c237b6345136849661a57ae89b3ca933c68dcb8c5bd0a549ed900c49c0086bd60c3ab7f5379ff5df1148f98e64ae1ad1c24cf0e6fae5ffd9eb852a718df05ee56dac13c675092d7c664d98641c83d45c39c913f9b063670b5dcc9c5adda2103bca43e3b2e36db3d3034056e672c5fd5325e193acd69dc82c58b366769484d6fc2efefa31733418de6b12c725d15277a975623540f84d409405441ceb02a3f84108e8b17712871e22c16243300b42462384f391027f3e03955f4cfd2dcdbad39464a647a90755dcca10644858434f2a12fba3855200a6d8ddee54fe960e70195f3b20f5107e4a1be91eb88f996167dc6e232031b7bcbc85aea537d5907c2c2ac0fb13037b96baae283f6e3577dec72e23adf2de724ac59f52d44ecddc1b6fdac900cfa7528c8371e88296364d2a02c585638f1c759d942493072717e875bd3accd7c5b431045a9ea9900b9db2f06d2a04bda0088f73817ed04b7be29370439d2da35708e2898bc5d1e8434a8b4b012d971087269393e6fd0945ba1ebcd4c687c8ca50eed0767707f7c8b979ec26d2eb1f05620381cc40c537248f49b2785f133cb86d397b8257640dffc276e9462cfd1dd4233f7a95cf01293460543bbb6342ae6c798b95c94838a0bf01ea961453bb899edb63f59e6aaccaadcd2bc98bc9fb30166786921e809f45be7fdded8f031efaf70caa77b06b6882868ae0474c4ffdf190f3b364e3ac4a6fd9f9c1bc2274bd7232c10e004bc03247390412130923c92e5c3dbbd13cd8f8d4598ea616448e8dd4f8195027c241ad34a23ce720e740fd702af0cab783832304b91f2c2ddd14d68cb07c56eb1384768cdf40fc68b55a8eda7e4c05d89475419402b1c3faa212fcb3dcaf9705f55717b88629d5bc7dc7ec3b4b82a734fb62eae974ea7ec1e939372d3fd6843bf3ae60c6fddcc7953a769f7c28766dd1a9039caa2b6fbc75d40b75d87c5c1fb91bbdb8db5000978ce03f7c78aea767600cdc74ea6ae8bb8899979a6b513ef5add17b2c4aef417bf8ef80527fb0cccfd8173f562c66603f99857a2d572bf5b38b7615900ff334b8c9f717c05a30a041b31bfacb9008957f44679bdf2e8de7a12c28739e0114fd40ba21db041860f5686f40a2817b86984f6095d4c63e513550fe0610ea3be5880c43d8c48740ec34b0389a0aa9507f10c7c5640a1e85c852ee202a3dc9546ea9531e90b25c14e3e0b16709497e9ecf5888ca573b30f9f4e5a4f4405fd47fd3a6cfe3410ce724d1baf3117a5b6c8ccee50aa282b8e1b745dfa940e07fc8a8af4d2107f3d808309822774a502a8c774d0ae71b19a077bd704211756babcda608e0d080da536d642428221ed66d949b4d390b44eecb73a7ddb30c66a11f7717f70800fbd11bda5db75cffd68c001d2e7b14fcbae6475142fb33ed76a699ae0c5c2ae54f8c2b25a125d1936e9d707b0c24dfbd62579750d0d1d3c0a92c991892c88caf91ee918e458fb27e1e2fe6b462c873d84e37983fb810cd76204e8d328759a1327456b38336c22e0f34b468807ca5fc79946337fafcb87b06ae8dd93f44bd37771d3eb805d997e9e66cffad20ec9390d31c7d9335c652fb9c195d8f7708b7d3c0f394f828e25f5a653f6ef00d3eac410f65523a9448c30b9f7c8a7752a078ea248be98036769a119fc97909180385d6dd0b431add4d463816ffbc5b72cc680d2b859491499cc680474ad490b7e030ad92e20bfa2003d6f2e5614304cbd4acff73a3565a6afc5e832f9c654a53c645eb08a7ef13a635d5402fc780ac0dc541f1c593a3ce01e5b09cf93d664215400d3fa3f153c44f47e50ef988c73b4abde12e46d3b7b9197b6353204f19d91a309444a528c9937361dbf0f4df64a1e2fbd65ee327cdf5a9bec94996d30700aa5ffb25d664569f736d85cedff8d52c01f623a3f08b6160a3c6ae77734a1a098aee24e2741c28e010788f0042dec0653dadf42e945ae4ad1a18a5b44eb0335deaab18c19d04060dc417ce632aec07f8c665d8c7f40cb0398b2ad685483051c50fd7c580003130af0f687528f83cad622f55ee82d20de0f0121d0eef55d3cf194d91c074fce47e1e9395e4741021b2218996ac9ff71d463a0f083d3a013d61fcc7eb3efb5f915caf4e7af380fa968448f2f00841d904ef2422db4794771c33aae3105f6c9c4176480313f6083cc9357d424af6e74cc213b8186314a3c6020ad52a825ce16027342e446f59e58c7055633d468e1c6d4d578af479390d9c4bb7707ff4cefe279125a3613fed160f8dcff7aa44776fcc6d3323e38842910ea3497af7e54884712f4fecdc356f63752ecb27aa6be4a6ec6380a2e659be18d4f68d4d9fed9e5a8789413c52171b4512be72c62b9d7ecffce452a63ce3dbb6ffe7274b4ac0732cd900e281cdcd95b5410f126a3f6b0bf1fac1661da073b5d55c5423b6f855ff562ce88c0e48b523dcae35f47ec573b5f4d9a168bd469eb9c5eacf9f6b05743ffc6d643082cccf52cc3a94a793a844fe40da8a768c240b82f78310b1a03c5bbf230ffe3646378690d4687e4f30fc06f5310a1027e570be311b8669987c9257ef5eb7e7bc6850fe0295315275e6a37aafa8b1e2e5f93dfb46dd10b43f4bbf9141b116275f01556668f6c3000d3456f49cec0d7fe65a1e113d5893f0848b0da91b3f1208608d0452362081c5dce062d3e7c303b0b40b26c67c1a64304e8e56e1b921f7557650bad38e59faa5c9d741ae8e1fbf504c067f8b1a4071169c77a23e610dee5d87e52e3f7f2cdc9889b928ef06e4e2a78a1785ce1c3d4fae09febdec70c1fde4bc45c1530a4d106cf83b7c7b31d8b7e1f318520ffab2d78b3a68d7f0d28721c373606be86b8ed81b8e7b0dc0b3d5e51bd3b9a10f1947e31ce1514c95753893f7dff997e8f1087993118763012ee3fbca81edb1d72c413a856f65eb13d7613b2be67efd60bee9022b52cbef3bfcfa3539c987d7232770f142df7bfc557b977dfc157cc3be421948cbd6c91fbff204404172481d9d8837f127e7b7da2eda72fb9fbc224b3f841aa948e2d07989b3035c12451be793239f192bd7718137cf4a065c5e3603687393704326dd4abce59986f9c74c59aa6524f6fb490549e8e9e9dec42894d4e5d7ec5de75a538d320461be86979a201264f33f251c39ed65ffa74c57f7bdc803f0fd7b09250c61be7796b41c5e17231fdd706fc5adab8eaca494cc5f06b205c105ea8fe923273db5bbdfea62c3babffe72e5f49b7939be7a9910c55c8e32dc7987ceaad2c40001d5d458728e6a3d676a4aef296d7c3c255ed79a7e56ac50e9c0a376210be388a8676e121a7bb7da61d5ef0c6fab88afed2bf02e33854c43e8f14f1b7811021777bef2cd3f5d965979040b6e09d9fe5501c1612892933f30d23d529de17ff9d4b4718b645eae623f96833ed5452c8ed039a50779bcc665439e7db8f59fbd1325b36fa741d0079c431c1c1db25530e8cba3a7ce0e1bf48776260e1425014cf9a86ae30fe6c5a3fd0144817d8066da3b393514d49d025afca0c356f3e2bebbf8599632b4df74e8e8c52350edc41cd72687ef939269764f6c45a45a3fdd73483778f22053a1d9fd82fcf549d308a201d8dd126347e405a63851cf5554dd6459b412b3e0abd19f9fc9bb42614f1ef7d328e919991d3dcbc8c62bf7971ac9c82ee101a7eaec4e40398b264f35109cab8514d18ec1add6e04f127ecbdb0e8f34014ea340b18302538d95b8a95566678bdfd03213b0138676c67693367012f0b520bb3113645b62502929a944445cb53b08d1915a850e0b18a2d05679cc5c2c80e6274b638d80bee3f1c67572ac9d4b3e6c6ea95606d4c3bb83ba1e4945c240f5a1913ec683e8e9cb4209e3108ebe46ad5b055274bba1752fc606c2bac2b0c6128ca910499571d3a0b6e4800e42404b5d8ce49128d14f5d402f7a25bf298bd6ded4f8cc1d17bbae658bb05a8b69d3fabc7ccf20e173e5b5fe41d3b55dee8ddccb15e65b40126fe786f84eb4b036acfb74311f884548179b0d88dd246306ee42df5ea5913dbac269594b8fe1a0d8f0c4a39cc402846ce941393a7e4e45b0e2173dc1495cbea2913c46467068f06516dafbc78653be054e8d772793582e80e5573e00339041e4788185530b4fa7747d1b236c25581ab3462a235f4c7ada43f5c032e1d63651a3c81bb45f3c7fdf2311e56fd6f2b2f5eba59daf453d338ef5024141ea92b94ae2e79043088880a099a45209e52dd812415c90debe3f1eaa2a3ee8accfd405b0c06c7057ac396f2f92381b338893405fd2b4be98a37a1a9d89c5df54c54e3e049c2b1f8a42af8a58f0cbc272d887e89816b21fbaf5898b8e2dddc58f0974c68f3248ed9f7bd30b566b478d5a96f127eee13c13b787673953e0713a76005fcaf35ea7d3da343da225496a3634f65c6b6a4c8b8a393c9425af20fed69df27f6650ceb5040cff7d997c3d7e722792722472af730b8f55791ee78de29414a1deeea4462be62f9022771d1c61d30739f6db1bd0ef78f0aba2db2131d4714f7f1760a5193b1ea823aba146ebbd1f88d43f90471e5278526966f79bf03a676a11839f4a83cd80eee6c2604723eeb1b4d4b95538c6fa0067993d4bf8d0e6168c414112698bd7b3a35ec98144f245a99aa827d9121c92745ed7ae8b61475f5dcf69bd21ca4bc90c0038b53d5d2bcac6dc8225a182c671c7a3efec9b7e1387aa14f56bc9561feb09a804797f08a42dee6dbb652e90878330701cab614b1efecc9a69204ab859be2826aacd9a27d579634ab888333cfd319354c7f58c6856b583c536a5f09638506b864146241246f2dcc884cb61fe0463229d78f6f0af3857d09c022a59f30b4beeaecccc0bff4f6663a0e48d7dedcc8ead42ec383557f91d86f1e08b3d42fe10605b22e0c7280c69c4ae670eb61c3cc5e7f6f15c5f9f03a07a71ae2511c7cbe54675926f6b96c06b1f8aed70724122b720203d6b18c6af7442ac29f87d33b666743521c1bf3fd36b5d0ff730aea22e5d664280116832f8e16fd4096f24ff6624571cce426066098d5af78d06da04050bca5b4a060faa42e0bd156557f1600ad9978f52c3cd8e4a879910e7c320b971e61b755a2b930f2f150d9f548377769808a5afee0b2051a677b8b0d4d0daec9bbb78cdbc4d623bee1e224585077c7eeb458aceb118ce1bd49e43c2c578c11e2d0c6421f57380d496442893077cc7f0db3b5421d784c86c45f4ade46ff8a008467e4681126f6e4c912778e0d10f9b7dc4bbc4bbe4a0674b1dd0fc83705171cbd12a9f6467806d10a03b7c887c943237333891c99b03d6eeb0466d608ddc9ba7792cfcdf5062f06be7b6191a6572e1a8195aa1bea7abb550969534f05b369a4e882898b79accf58443d5e62c476898c2dcb768f4f348d6cb36b9aacef65658d2aa0a1297b734990108d0ff144c06ea1e9d3a7a79ed58fa3e1745da88a00b4adf3da41ed247e8d61dd98dff68352a157fae7efa20c175eec2344b088a00e030cd14225b4a4c4fee992c1fa7c64647977ae93e2474945178c9765a649f8f8549305e0196068661061032a37093f304c80e11d44eff503e3473bb1ced4d820253f109972ea4794bd0c6bc76410c1be9429d62d360b8ca2b525bb573c591988ca65452ba3b249a03c7d5199ebcc3ba3f79f0306841bdccc34623b5ec71737d06ae1ad642ec13ee393f4741a33a667dab704be3c037fd20a512b11862a897a33813738693e7920a2484f0294ec43eeda8812b5af0b4418387c53144cdc4d9198b803e933dbf23f6355e9d372589108e12f4e6c3c32155469f5eb601fe8537a67dbff3b3a24155ec66c103aa2979cd852421ecd6da2468c03729fe06b587d949835d7a8d5020d62144657cbe1e8db1162206f1790d898a8946f5535820074afc2ae6d3e81c7c7de63ab55ce460c56c2fd3bd29a366f3979e4c6c1910e9d9c9e4931240f6e8873a63c786aea91d678cd96e2d2400d72dab983c2da1170bdeda68bd359dc2f098479a449a62ac3799fdfc188afd96f8cb74f4edc6ee227c0152dae700c436082842c265fdbe48dd5d43f0e99e8b0ac4c6ac640ff3b931a5db2705a3a1f4ba6efb1a15c649eac8230930abae799eb8e2044df54f474a6165c47953d5e9a0dbdec4aba69671f15c776902794dc8557fa7513a33751b3dfb4499342edea0e97d422d196afac73e35e03dc38e2652961dc4dd1d46273574ca5c4b3d00f5b4c71ff7471e4626673f8cb59a27b9c6c8292c5606f7333a539b7eeca3a7ef2a938220315bfa5bb8f5b882723fb7ccfc19250b8391d431f4d1778dadfa3666e65db2bc5deae4a2e02e28f07aad2764d272efe0a6fdc3c0a3cf3808810eeffb207bbac00b5c0870a07283065e6fbdffd7f7fae1ef12cc9fc1eabbef49f286c28cb2cbb3025e866de0448b8454b7e744648750ca065e95579cc1ba156891bd3cd3e8059d2b861f9485e25c186263956337ce10619aaf48aec5e20a5a43524d1971b6200718c18f9a73b25e56ef73f3fceeaea66a0d3c22260f4886714feea12b51e23995dbdde924e184f8d5544a613e2bf43b1ee263a594f70ca88b33059a1d04df485e573b6f37bce6f62adae609afba7c489b67436e5cf91b6936cfe350441439e074e6a7acb27fcf33bb7bece54650d601d3f3f7fe6637504e5ea989001eeede4d6bb988ae749aebab31a933df7bcf6fe32f450b11b76813c2785ca84399329697a06aba3a4d5c69ce27d3985ed318e51908dec231aa343afca754caa305b714f8df450381e2e9ef5d8a11329228775d7cfa59c5b065f36fb4cbad2c0e7282e0db0891ff35367f512b39308b5d25f4804487e40dd9a00cfd71d9c3bccd5597287ec39405dead1d50d6904ee96629b0a3756f30af27d9ecaa8c937f99a1d70391834e10317d8e00e6cc09b4a253eca8fe42e68e1098d4ec9eca411e015aff630791ba73035858b2d043246f0139fe535fb1baf51180d553939dcc56ff930e39c2bcf6abe5ed7cb15b4c6a13fc95b0475ce69896fe20c6ad987d89e5562804f1abb452f2d9dcd16b5b7a87eaf54411ee2c48058d08073a67b21a935840adaf02496c1ca2c3b618c2432f4ae1bbd3e66b47a516281cba014abd6f58cdb590238beb88544b8c21c8b6b6a0cbccb34715fc85cda581604ac8822a1ed680ba9a5f922850f12b2a6e51ec2da7d557e14d729322db62739129624d114ea15c16027bd9248cd706d73b984cc59be405b25677b91f60d61c3aab7867078390c6a0c7165e6cf1cae47f9a68046ec85d10748fe4cacc3662f60397e856042c68f391de94d02cf0b62b2af4eff67bcef61dbfe0b62f061dfaf74ac383ac6713b4c1657abcdf52467fc4bb1b8bfdc25af84f6286864e1f695fc433d2d40d7adf5fe5f55572304c16a20eac4aa45ed8dc1410f65464b82d20b8587e0eb023324cc7709cd39bfef1f9458ce0a4127fb441ae3a7dcadb5c41e834e2c50b49297bab7df75aa39a17ae37d7441915c82783ad0d8fed51ff672f2c54e77b0da6200ed46cd4bf377248a505066426a17eac38ccafbbd40603a88e4a48bc596858dca7631d4aaa02fcc964f60c46a72e9a9f649e90926a4738292fd77f27696de0eece6ea6e89075843613fd5c5d2a413795c6b646eb9ad866303c9e953a89712ec529a41abd9d105cb0e77fd951a7257d5f668546204b2f128799dc7e662c73138deda8e5dc53358a67044e256092a5445f23be2e7c9dfd856439861cdbfc25c1993d861cc0aa05a2bd1e1a924407d85fbdac9d6eab266aa4082a751bcab26887d146e5ed381fae7f7cea4eef8c619138d470dc2c6faff92a762bc1d3465f041e1ff32e1611b303b2f4e49ebdb04744f8c96793e69ae0d27a915a4d966e7977d33af21b425132ad6743f6657d4cd6a786a7b902bfa01c038af536dbb3b7f0e5dd210b29b3b0d3364d57446d131de5510c0fad9987c8d6e0e1d81ed2a46128d778eca411b49539eb548024a13e7477d9a6f1a6cc3dd879f3cb2c89211594b0645fab966b05188b2d34a5319682b1dfe544a9453dbf4d31f6cdf9c4c2ecc27ffadba746cc892f7d2d2080ed858629abce0ef50d4771b8570b79ac764a3ba03b81436a25f4ff4a9b8bc928855c63fed5cd8679a68268751cddfd823cb78f65d74373b2a70334760bee2748c3d55a0a683e00f7f263924afb67dad80156710d28527310609baccd156f6c99629ebd3006aa8559f63448908188386caf629a05306aad3a0fdfc5135858413a3b296a1f1a75a70e1873618bb23f639d267a00c0363046d1d0f6391499d4d8f03503c4debc0e6225a40f20747ce70d8f2b00ce6cb04bec57233433ac958a570759f7c43842bd0c8ba9fa4e798d373331108f074f319f2b5f2771cea7907e9b5a8d4469b9f8966c2b803b47f080fcb5318abe4a0050d08941f0fbf5e0a20ca4cf4731f7263a1a8b7ed32281303242694f007e9846c5fb368421272e06a4af0da5c452f21f9c10acff627e0f106cf1328030aee69789010b87f1db4796e57f69118c9e062d80ad3f06d65c1b6729f6eef17017521956af10e77d6cd26985e5c00ddd29db6cafbb6669199dafb158af4e34b1a46736994323c3e2c09ae7f9340f955494e2758e5e1098967b15cbd9f46058f3ada060ee40d7191ff0930371c6c8d9fa95d593f07f1c5fe1612cb11d00d4b26d343b5fc63548d41007f961f1434dcbb0b6b9562e67deb7b13e40cfe5f2df99c26f7ea7882cf71bbd092c9022231e52feca39781e50e03c8e08e760ff9d9a8efd41f82637e7f93dcf41ffaa7276dc09a91f4ff23c0fe2c1ed4bb5b387ec18809fe5908b283064db48a392f60e03b7eea7f0e12a6dcb5c38689a8b24fcb7eea8407b8aa97afd455cc1a4b9ddfd30dde064cf35ccfef77e8034d494847b305d9598337baf0a386c909e182e67f75bc9f57c58398201a794c4817d3837b580fd4101767ab197e8484e8875ced2d2373bfc30c1a1081cfb74b6dc68046d9cd784d688894cc8d5113b9d1196afa6cb8a28df82361c53300a003000a001600d000202a00800316e91e0f0a564ffd00da939301c9295966a752d0822ff881f14a664ac5b74fdd6f1ad272e38b9576c0b4bcb3f4fa1715eb7f21ef2e4bd77cc0ec89d302fde0a587e1ff9cd07a11de95afdb1b9acdfccce99f743c7765aaad2061437e72fec1559fbf84997b9d05a31708f52d674c775fc479f78485597be3d64d87668f771ea4f2ea9ed6e36783b110b3134f1e12c4bee6e186aaddd9509c5ae859f7affc40c4161df2678c50a5f8a3b43b5586aaea1200dff9e224c42442a9edd96b1302e7ea5f1284ba70357eb185c25963fa94823fc17609e66266a5707ae96df9025570d34c88cc0fcaf6abaef588bded6f29d3f22e03b579db8e1aa0bb317896db3c237893a0323d9c7d69d6f232e807bff04590be0a8fbd74486dd8be2468966ef68ae1117ae4003cff53facbea2eb97aed4c0dcf57b225ed0c3356be957983021d41c14bba73a785a8ca7ab3fe8f0c3889fb2c7a1c96cddced5e6040f2bedcfe41e98442a4683cd01550f49939b4048b432009d36ae8b4997b2bc783546bbc569d8ce64c761937b151fac08ca1a091da6e21a3ea69940c891facb6d6e7ecde2b55a439a56290e2efe33ad89a10dfc97197486f74e900861d0caa6e747a47f9224d33b9d6492d87f4bc42ffd9759247add2f39080e72e8e01ec567dbf83b708d59a351ebec73433a1a19b79e3f3662f3b8ba729afc4a57007e80f044bc4349a880616e71f1c16002b6eb08f9f01a61793b8c133e1f72f1195f30a8a7db4c037cdd850fa1f5014edbb0331863d1692d65bb4039d29d812373d4896f70420bc6a3744cb43d0aa2d5f4f643997ad4fd98cf81081545c2cbfbe90635dae8e75eef2b695d77578390b350fa1fa4b64f226b4be7c54b066db735e4bb027b6e95900091be946d33e0f37ce0337a01e0b001e202d80c8e6bd3d47d89f7585f0b668d5fcdb66a48c0ec63a76ed0766d576f695e1aa12725a40ba549b1bca02a5a9db5038407ecbfa2f05aa8e62f37bbec4ba2c60b43b29d5c3fed2c8ed617cd6165afb60f3696f04baa98647eed8efbb8687523deb0abbb48a85fc20047d12f629d84826dae0a30c7bbcb3bf3787d186d86d9c518718dfcb49cba91be9ce48fda10fec5a78d40037fc7078a23c59e32c8f5cdea85e02e24d989370ff2070ca087a1617fc81867bf855c986b26163deca5bc745f4a25295a061db6d4819d8047cd5545dc66e67ecc24af55fd00deca200ff46dd0c43aa9383ca05e924dff743af420182621c34a3b465cb7b5557d3cef8caa1a8827b1795c1267ada3f2f37a0ec884daccdeb1ee61d61edeb3677d2ebe59f502e99ce9ae652883786c1fe657887824aed13fa852c1e0ee5c4706d583a0d884b1b2ee26a030eb44e9863b5375823f4c12b980dae77dd7c448a0228aea726f4e5a8e11759554f8e6f72e7592acd47a1620dc3883d4af230ca975ca87f03ea13a7569f4aa63687eac28d6dcf83966a546487797c452aaf7d9915a649d01f690bafd8d8558566bad9abfed313e293023d1490207ce971d6d85742566568e1f08a802d70f4f2070acd5e2e8f691b955fce22b59fe94d49bf9817a29c58c74b91a16c5ee50ce7bcff5dd5be05bf250698626f290b9d943fe319d563bdfc712fab57ea2aac38ad57236ccfedc378eae9046b09527d02b5aa5ce8ea38b6b3586e6efa2d7224ab0de5b2f36cdc05d3bf5e6f9ad6921d1671918b8653033828fea71a9bdd92a4175f42c9f634055cc4a89d950e6809350dfe8940b137b3c832672ad4e5664f9ce7213e3848e3f7d5ee88be2e9fc17aed09feda48a3a3a1dc94c9ca45ba0e500f9dbe231e90bec78f91b89336eaf70a90adcca493b67b44c37f8fd6a7f21afd06d6164c8e8af28c726460fd46ef795727b8fb030e5230ba72312dd9abf5ffa5099c1d3d156e1ff43ee649857417fd628c53ee78aa6b8f7fe23fba21da1bebaeaf183803f4dbc7e4cbd9ac0f34a9fc1aa37ea20bf8e78348beadc665d08a469d3d40ed5c307a17140c418ece6fcfb70aa1e43feec6a49762c3504c7769f27679e5fc682a5ecc6749acc043fda3674956f67f1eedaf65b29da8bc899db6d48decb44278c3c0fe17de1b663f4dec396d5d5d1fd352ffdd5426bd2cfd4fe38a026c32314c11deaad8548ab284a6c20abc53952dff633f99fc6163e15778f72314984d5417106034b0a671ceca2ce9a2dba12559014c2039c19c399cc55a4849ab99c565b14b74c0564d2c49f04b910054af2c500516ec8f22538f1456e06a3f88e7ad5f3675bd422fefc03405d594171ed4f9684958f092a8d16c987c84c3862b900a46b92444dfcc108ea44e249a6568dd0b4567ea70f375a5d98c25f4b9ed900bd76eccaebd9c376ea35bd0e073ffb2b7260509f3fbdaa26dfc1c1ca92c0b6f581078d86ada9f1a539a5f36e7f587534fd73078eef37bcc1baa69253fc724d6336c7e261369ba076b2930f708615e32e6e52ee8258a0390d242506cb011c85766f1111b00eeb07a6900b9c6b44f1eed594386cc0301d223a919cec928f18de709dc7906cc6cd4ddda0bafc40e6147381413d96932e97f607c9067754bf0ba9578bb21363e445626ded6c67766f33deae67cdcdc97571deb4eaf1901deeb8f8460ce4e1830b6bd58035c1869862e5e3a55ae10387e61541eaea8d4d6b861e3d4d4b8aadaff30ced160074544f941648e41b72c165d3160538113e7d031de33d89c4aac68c714c13b32c5ac1a8673028090762cc6bb893853f5e2c5dfa13e9ecdd6cf990fad7067c60194b585a11a5e68a767bc8e2c0f0da692d2703e6bf1044a329210dc9335291db43d619a9f94589665dfaf5b59adfefe88004575dc67276a00cd40574ce6c608f0b963d53801030f0323bbef84767988951bf0075d5ae995f86c8affe0bc9898e33bf4496d10e00528e30d669095d0c0bb68ce281ff04fb968bdb2263e8458ed215dc3bb682c916b70531fc9c1e0c157859f4f8bfe18d65ca7676299d2a06a3aeb1e9829a67c904902eca0183f5aaacb1a14ee40898651aab968ef6b3a3a94a6b3e86b8ba60318c08721993225d72840d7e651f5f014d87d6d96e3817a3f9cf899a8a6f40fb39287c8802825df1d0e0cee488399646f1f78a266c8226a73111a6d60b32de2cbf0cba142a640496f90a72b44df20bb41a179ad6011af9bfad62f4f5681104eb31393280558fed38752617d6d43eb2b7a02eb3f50261f4262225a1c49b4bf6ff3f6ebd6abf3457862c8369ed1506f1715d2a901c633af4cf378f757747ed57ddf2c17c445b910d7f6cbf789cb609754c21beedc871aa5ded75ab19f994949d93d06b880788353d908854c21f7607480384b0878fe0d2d4bccfb9ac9d7f65d318f71d4524aa5adc74b49306d200cea4952d60af73b817151bb5119effb0c3bf9429b77c11b19087e89165a951b743e7a9688a7c5a04d813d414c90c78dbdc0425c0bfe9f1293052ae88df1b9a60bab5f7b883ba0c312e234eb026fc0c9869898d982a3ffb2a98da8be4b5308e94e1cf72938a5a7ca0034cf14833731a4959cd18aabb95177cf4c8a092609044b4dd5ccbd49760b6aac03edb8379d53283e0e47e5719b7596db74f6d946d72a6b2b523ad5162aab117132d50ba338c69be3ef4a1f62f50702c18eb62971b8fe5a746beec7b0582c8c127ae69b07f7e6a1f8f4621fb8c1b43b0d157d47f948c1a7b1250c776649ccc9b3310f26110ace85c76a04db80604b6dd06e40000bb691e6a3890966dc50301df01ef9b2c3d2fc4f419f7d72d711bfb9d68963a972859b7972e1a0db3e392b576ca6e23147a232284ecd9494a75bd0e3cdccf63bfc7bec32404e22524557ac751b2dc6aa33cc3929397ec75a8d290c2e0a82527eac5b62c43e3b384ce3eb5dfebeaf86b55fd457161df2004d4c8419a4b3d24becc1f17aa2e288db63b55a96b3416d4a3b2bfc9a6c6bb8c7c1f1cc0a94273161888d07a91227387c33d240b17fb27c8a8071ade1f11b4073e6e869efe27347e52aef54cd3d482767a30b846f6863c0ce6d6c026d835300db594635392134032552511f85b82150d57ab3ceb49c803916248c1ac1cff59c1cc29504c1017d1d7b6789eb8858c545c2f43f8493a4bfd3d9ee9894a5d6cf8e5400f8f97a69414e680891cb32823e8113adb154ad77f02ec3174456121aeb04d15046018c376791155f2e45f02f1c3aedcdb5dc9d3582a3487ccd9a4cc71ed0e22b41079b1b70cc380e5f47cd0d2e627368287346d0efc433084183be92fef49e0cfea93d7ad341f119dd2feec3d19156250b7a31133e812511f34dd00019c5205934c22527f2ada2e0f99d875e3a90a0ca489fa42ccbd732aa3c99939183dc541223fd1839c6601ef004f51495ce73e86b17cd991086d7969f2b2768c1bd5d72c79476d491067443438ec60548737cf538081a99ca9338353b5600db9d4a3ec8b9d0c568965908e8d44f3467aaf654f592c9b10ed32b65e690172fe34828afe285e994f115291396530f30c82e8c283dd8a8f1b60427a928fa3a756c19a676a519c079f0a573d58551edc3dcd2fe69c78cb735dab07decb3b2781e6c41feb573e1f823ee2c13dae7e46444e892cc49ab1808c3867bbd6ca0746be316138a0b7ce661a87d183b083b75b922006caa161c5c08dabc0da06a64a4edc96c4ebd47545f378e40831468b4dc659a272ea6ad15b7e891c090933ef3371d9166b7dd71b0c4281671ae24bce535ddfdb13e43d64d500b1c1ca476a362e189d34ac6ba856c5e6832fd003e6783fed439026c0d2eed3e0df85fed9bc6a4b7f1647f30047706e58dfeadae31d0ba81d5db7c2354bdb3dd4f4dc8c6448a9c3a054a93268f4e1010f08a3ae782dc87c35491ce8f784e11da89c83a80c5d90e3aa1a20cd9e38d46ecdefebd25838864d442d26409117168fc07a14d71813ca0313502a8f3f9935d3c0017e56a77edbd19147296020709ba08fc083f94c955b36539bb7bacb187167b80792442496a923d747b00fdbfa5bb9d3b7bd5e38b1e4ef45092071a792891072e8fa20f96ba8cfb69f2ed636eede3227367a7585b8bc7173c4cc0c3c42368cb8ead345bc02da557cf3d585e7ecf2b9deaec73d19e8414940321241588fa5026fa438788866a0734a6776672d5cc0cec3d5f2edb3b9d65747cc99cd0b1778e4d3303cdf2f27099c3c0325f1f9615e9cc7f1cf378e6ce5c46c7d7352f121daf79915c0900faff7a479cff577247d6d21d64eeb863c97fbd77d0ff9ae560fdbf1c2fff55ced4ffefe424fd57b2cb11b297ecd0c20eabff5bb5a3ea2b931dbf7f3b68a6ba3a12f0f55647ae0e10eac8311bc5af0fd37155e938a2038239103047d57fed73fcc431234e135f75712c90030f39ccc831460edbff5f5d1c69c471260eb2da0b871a38bafce01082838237aa78c3ea1fef468c7778c7bbba07b41456f91e73d58d2c37a6dcd0a00d30da30a18d0dd810830d16d8386283c87f25733f9dc6bc5c6692e293dcdae7eb3db4e7f25549dccfdcedd945eb14cfc0fd3b6919cc6d1228cf3d074d1d058e01e05c8143548d7047b27e6252ef9c797127896bc2916b94fff5b5c61035b27e4113d79d1a55bfa3064e0d9dbe4b6a9e9bea91a601e783b9591a61ea2b0daa3480bebefa0536bdd9fa7f73555fdb74d1a6375c7e466f92fe0d7d34e2fc1f41e38aa28146d2ffde261a05fcffe3805863cc773820d667d470c6ec8c0ecc78f335783985555377a798986165860a5f6fb51a53c5ba9c1913b8d17243839b10dc7c196dbe5a736f6e69cfd645310f962f6b5df456a332b294b15406080878a30e297d66afd2982f9b1b78e0c185b26420800c27c858818c236db4da00d1864a1b2063dc31069c31c08c011c2303366cd818c18604362f31ecf8af3e6c8444b7aed1a8e005c2f4595eb39f48b1d8cd325dbd63b1255deb144669b02471faea7031a64aa7348dc26ad944352eaf2e9b99eb74e5dbda915b2b064e0c08b4cad0eaa245b4c6cd9aab355cd64cad317280ac034c1da0270c337e08a5d5ec3c1b199dd0173eb9e9a22f17ce5d1d1d69595e1cacd67307c7cb474b751f3b0e97b94ba3741b0ac63b5dcf3e8cf92e5896b7e3feffc9ef8401465613ba4d30ac4a30a66660b8bed8fae2ea79367b5fd88efb1117ed5f50f3dc6ad0d06825d550a971a901e285d6bf17545e3cfdd71d2f78febf6661bdce9b84acaaac5e9652175b5f499ca37c971878bbb8aab60baa97eb76d105fdca05b9378f7281f55c503d142e92ec6c01e7ff2bd98d6c81f5ff556a8baaef37975b24556bb7e0f94f03e7d360a569e1abb532998c56b4ab15e9b053afdf1e59d68265794f4ee6232da6ba163c5968fda6ac3d77308b25b2b05f75a6dbe4bc2c807c182361610725710e8b3075ebe0a51a0baaaf583cfdff6f2c8ca071534ddca55434366041834343bfd64ef2bb737ad3717685d68cee4a7c8597285d7e7245ef8a0bac00e3bf623ca356dc6085b642c87f1d476b2d76aa028c2aa8fe2bdff49298ac42c97fede4ace451aaf8af5055a854a17a4685182a6cfaacba29d89822ccff578ec9dcf53ed2f593da296c53e85ce04c0a3752c4f0bf779a16852e8a09b0f2c052022b0b16396ba2e3d010144d401100282e140a3cd1e68584fa130738a184134027ac13449a98a309ad87a242c76ac926e8993767ae3843c3192c678aec1860ebffe9489b68ac7724744442ea2b65800898d062020526624cb8aec6b8c2ba0ae2aab6441f4b44b1b384124be09608a2841925a0fe5f08f338fea12f9779713566855e38a11ae47a9a29591ab34a3d738f98a7338f635fb7424196ee68fa1c7137a374bbecf962a9ab53827b26a9f1d8318f6325252a78592c762b9ada4637895c1240ae7e717ba769b1d8cd8c16334264202103124596a4658931797d348b7ba6be74ece9cc1b553b62ea88a32388bcf93b79df298059000facdeec58dd600582d50e01b42040553d3a72d52ceed72816bbbf608ef69e7b3717ad7c739d5dd4c6a8b975b9b9cfb74d23dc30228d115346d022ba28224c114f8a08abc5fd5aa1201f1b2f771b840b72535fe0b983e70e565cb38bee1eecd22eaf06f5264fdc7f9ad4b8a9e30ec4ba4c56193265a6ca2c512a83001158b59b3b445461222c113a4368e9f41056bf330497ff1f62082021dcfc5fed08c1e5ab105688255508325aff64ccfc3f991ac824fd7fbdc11c19d74e105a40bc1404d54e1049fe7f4c9cffdfe7183463c8e43154ff558f791ae31a03e4ff81c8faaf647680a07a2034c6393176ece0d4f5c962b11b8ec4411c259391b458ec46d27cd8a4c562371f36f300fe872d7e70e107a31f787e681047b94cdce4030b3e3cf940c364852153751800f4c0460f34f470f64079d88287137818daa18d1da8f87ffbca26ad1a197d3a20ee75cc77dd8773b02cc9cb31df1466764cf28e9976180213074c1260b28041327193ee0bdff982bf4ca043153ae8a0c3eddf87cd0cc47a27073239ec7278e500e49f6ed3d2a0e9c5031cf6c081091c64c041041cc627cf5cf0cce932effddae80d40dc3075c3941b10b0818d0d3fecd8e042b52f17f6ed8eebb9027db8675a8bb3e1470d65d400a686df7fb5380a47f14d69808306313450d150c00c59cce065062019f2e842063132ec6428ba3f5d2673ce52580d9e395cde7e06cf1cdd669510552d544955415545a90a12039a188c88414a0c406f7d96c2acb61416f3d11faa712e667bc71a0643171892bce0e685245ed02f8c6fed6e53174c178ab4a0a6053228b430a585a11682b0f086ef1d16645de2e8f244972532f89d2e5e9ecb175cb47009dae14264cb165bacfebb111f36f316ba821d2b58b1020b2b7cb002102d2c6861d2e2da518105159a54e84923052f290420052b296880821d2850f15f2d7f5d9792de0d0507042080140420446507950f54552a8969d5874d9c3b61eb8434279c7042d25f18660a809a9d009c09802e000fec98b08709624cb0b5f2d2ad29edf9eef26ed39789bb8b9ab8290b145978960c4a18a3041e4a482aa1032c6760c1fa7ccdab71b9db5876825004b30461c121536d4c113175c314d554d15712e782d707abbaeec3666ca6c4fab0992dc53025b0d8ee08a8052c03840262f0ff3158b5b6779c0f9b198731dfc9e898e49499e7c691f9fe2ec73829a0ffff73ebf4f2ffffeafd8c72fe2b812931b199f55f7914f36be4668e316d5f03663007c41a87cd608ea4e1cc6f64c6e1cccd7e4da86242583335b3c091254c35739991b29cd546963b4b922c40be92b8842d96c212aa4a48fa2f81ab81c5eaff93b0f0d059504d904bb0289cdafaaf98df5e96d77769309c9af2f23f65a78404734031802c84c0df3fd055cbf2fa3adddba4d966525a7c2b498579a9258ffb792475c05712632cb949e7738b93eabf9e40d59cc2d96cb3dba1994d093a9cb093397b972a77c7fc5696e7ae93df25e07038d6bb5bfef45f494c7b374eaff4ccac6d57b45c09fab9c9a56e9b94c4e5ee7aebb6e6b34a86bf2a0ed35bf378b7dc456d29fd4bf235092c5bca3b73bf7047b17f9df274e69b735c37d04c6bd59da69ae9f17d6c7c29f8824a389803758eaa1dd998e8cd5294ef5e3bc7529787250fe5d37f2d79f6521496e5dd7217d54394ad5abacd282015eb4d827944c209ffff34db8c9ae5ed32fc0bde623159bf49b25b51afdf244ceea3dc940be839d19ba147ebf1f0e4e0e9c0a3c20bdac5f9d1e2acb975596e3df21ca9716ef4a9758647a51d98ffdf25c16ce01db00e47109259ffbdeb8bb38f0fb526dff5ab336de4944e8ace486e8d9c0d39107249ee19d789f05eb943f787edc262b11ce0ce0871070871617022e08258d9c38a15cc0677f98399fcfa6ea71877fe7cb7d77b758cf57e6985b27ae3283466cdf276e0e554679f4ad22324e6714b7d6abf3c9ea53e40ec4387d47dea3649833a1fa94f235aa1ec0f85b2b7d7793a5b91b242046a0d9497af3f6cfab02e77a8a1ff7f4b75de65cc7f18a94a5905032a5c5099a24205c99433a6bc306584294323c019a1cc085446d879d2aa50169fdcf45d12fbf0ad665c4d9de92eeb4b2994d5653316b354f0e9828ac52c151d27b7a9bb519e76788222a58fffeaa27c5639d6c0ddb30fc9d7b30c93fb88c453b7c44c25e65b174ab1752914f0947a86e224c67f9d39dd9c8e38f544c9238a9830cacff24b61bb5cdb6d4ad238b6349334da8d707c7323bc8d71eb12de8cc29baca98da61a6aa7dceabddb556fbd7937172c390e9663c799efdba33d9316c7bb39730a6b29cc7fb1d88dbcb857e66bbe9ae8e8e42269a43e374fe291678ee3b2be92215398df6da6a9af4c400fdc5a0ad37f15818cc63f8ea5b69226119644789a8900544500f2a1cd46c35732e36c08d4d8d4ac086b586a4098ded3b684c412d5925e02fa587f0529bd51a2416904a520509480c2a5c248de84e39d6db216eb274b3cd13d59e0ff13f8f0c9014ece70428493149c3439095ea0595eba7b79c78a6b1e6dcf2151589fd919ee86b41e6859425aa6edfc7f0c86ebbb4cba4a7a4ad2811202560821b83e98e3bbc95613344daa824d9af03071f353d7c7c40bf63149fa0f320182e4e6bf6a1cb5790ec9cb77a4a719920e3dd23afaf2ff7db7cdbecb232323378cc2184d31d2998151cf1da43498d39bc463e79bc4313258f6d059389332a3397797785912b524b6040310b4fe6b4f4fcfad5663022129048101d91ab21e42991559051f50f1726d4ac30f46f80082a233455bc2a2a8a29ea2204a7aceb775bbb414d6d343af92590c8f308615cb12c66e1506f3000b0f82a107503c3820c913611215ea8be2dcc5598a73b90ee074504407be0e8088d80889b2422217be9eba7bea3ae6d61acd3808830314420ea6381832b4c5d0008644181a82440d922d2192a0ffeffdfe28ce71939e3b6871bb8d1b427da8b5f487da20ae772138a110d6bf9097ff1a0a3d09b978fc066585415e8292aed9cd73cf80f8d81a076f2800c180747e041e39e2083f82a4ee51771b977c9bd7d21ded0ceb0b35090cced7cef386e9de83fac25008614d962ecd926eb4898912ed469930d594e8528d22318102657644991835d1924899109293a7334fe711ebffe48d5575b43fd2ff89f3b5bf30df3e170deafb1366b77f7a0fc4bbf087672f853e702ae953f53ff3b17df5e1f97f655d20c7e42c7c51e5a8694467aa8486afa7af7c53a1dbebff9f977bcd850574bd50cd9e4b59d1d4f515d152c4a988920dead8a08c7003321b3411e183c812447e4490febfe3123635654a595efa439bec58e6a89a0db223ee6714dde39dfb0e29c09030e110010c5132a4811e37c21e227aaa843d409ef6b3b4514a8fa6d01f3ac555ab18766948efa057140c2d814285148130833032a0fa7f4a474b61c172f3607ad311030f3058e002362e18407881ed8208849021c4082150421c1823b4404d688196d002a6d0820bc20ab0082be8153c5500840224420ac6841448a180011e2e7882b3232a31ea437ff02e97b49b3956edaba9a976a4c9ba8a58ababb4c955b3e3d854962e9a7b367f2f17ed14c6b7edb69fe58f8ed6065118b5bb7cf99e1569dc03ea7c7de1046e3e9cc08bc98d7c38416f827e811f7c28419cff0f253042825e28c14cdc0ac5abffff99c8e57f168abf2ada44a09ba813c609432d8c9b8464be29b4ffe3a74eb7c390e73fa82fad4ae1ced6ffbf041fee68853b56e14ed5d71d9beb77be2902381170f155262b9ada463257eeecb9b343f0e667101ca0f326d429a383756ea18e90ce030fe8f1c098f0812af505d38d30cb64e469a781588fa10354a103b6d0010dc206daf87f007cd8401a0d50d1400b0d9cd04053d8001006900819a8aa2f1bc451b8586c577335bd6c94beba111285d50e8391e5a6d66673d55e40ac5db41b099a3d77769be33cdea541dd1788024cb840090b38850b1c102a7044a80009a102b250019d8741d9bdd3342ae4f599b6dac2203b0c32250c127ac0411092da010e81680981140199204c008e300123c204aa9ec952582e4c20294c80e7bfd69e3b7b8880508840901001044200688500480300600800a010003e0784718055b52f26fa439f5c354b71101dedab89c95a8bf1aed697cbc4bcfa72f5186c9be7a53897ef0fe3dd2ef3bd9bddd0003d20f8d080364203aa080d20131ad0141a208605c829404c580094f0c71e5f7b13fd9d662c76b33e6b4baac4c992fa863f7ae18f26e18f22e10f0ac28f23fc1dc2ef127e511f73fa78f34fbc3e7afaf83957735298639bb3644e057320e0e3007c70a99dfed0266b852c85551826b70e669f6024bfbd9e3b3bb54da40bc62d138c52db4403fcfae868fb2cce56128d8305d3671ca93849ffb5cab1f535cb81f5726cf9c7c921c611a7963b0e20e29012c70f38848083eaabe5b1d8367376b769af3c0783e5b9437a63cd1b27bce17a230337b2dc38c18d1f371668c34c1bbb366e6cf4c1061998f34c831948ea4b06e99847dfa8738977b4dab9c6baa7cb3b1aad5b6fbbcd5186b1e4a658ec46c7974c26bb15f1749eba4ae62e9bcc5d768ec98b7b38d90b4ed6c3a98263fbafc00ebcc1f935b4fed7a046746d8daaa5dfaf71fb7ff2aad1871a6dfe5f8dad46086af0fc63a9edfb5d60532c7623c96bd338401a574f92b358ec66e2591ab4341a78a3554d7dcd29bc4d9b0de228fabbc03755e11ba537ae8e0619684c8186feafb6fb2cedddc45b771c44c3e88c38ff729dd1cff0c08c2d1c745d9ece52179739ea3203cb0cfb66e8287193e5c6ea9fcc6e7a5fbbedbb7db91b9b797d3d2bb90152fb2ed19441a68c5e19495f06fd100173fc63c90878820010c868830c2c3254f851a23c9d6d647c1b356d826883dbdc360d8c71660c2fff97e6ce265a6f6cccb0d1c286890d0562a0214612627431686234a0e546cb072d520b8916903575ac19c01a14d620bd92d1aed63f60aa313149bad198c48c90826ccff66585e80732a1207d79eec5f7cb0ad122eaa2353c009230f608638e30be84f114c61130f800c30a306000e30a1844d27c31c517515f846a9a08d574351a7841871761bc7812666d3d45027bd9209b750951a35dcdba68474261f4655f41364b47fb52a231eba25d88c2846c76b7836c19ef603d93678d846cf48706d11f6ac44f3b443ff880be5cb1d86ee376e7b1d8cd5294d69ffa53492c952f90e29cee76bd33e6b9cb37a96f173c74a1d445045d24c005125cbc10858b0bb808c2c56fb1660b14b6b8a59993c68e304d99344f698ed21cd1420c2d7cd0c2a605d0ff636dad92ab666db6bc9472a099b9ab66e9685f4a945a1b106b6a97ac925da23fd4a6041b5279575f5fcfcc409d0e7613f3ca7387f9d541d96ea95033e39ec9bbdad2213558624ebbb6487a5792e29c35c546f4977b1d4b658143165ab258ca22812c7e6041c4ffaed669cca7fbf4a9ebb3d95c351af3a1584ce98cc592ffaf4634163c51d0c4f90fd160fda321533b1a9d06628dc656fb4e86e68a2bf20a2ef55783ed25aae48a5e7805fdaf405c2c760bada8590142156b54f1a58a5d154e55204085175464a18257ad893b8ee3f245a3ae198b59badb2e5a5f354bb3c1dc1dc912fb7254bfb7a87e4d199410122a781eeba6d8fa29acc229aa483c4592ff1bd5bb146ebe02b18eead794428aaaaf522491590a200fd35b875184717f19fbee5254bf375914bfbf611421d60b2b0b8bcc7f25b1a8b096604960a9d0a8ee0beaad6732ecbb4b396866992c16d365287e2114c127e0fcbf9ec07aa2ea770f183ef1abb42792c462b7279cb8aa79e704d557276c5f9d7055276e1356df9bf8fdd7739b4d2cf926787a3e03a7d228ddd2992b7e86ea4cd21903a0b906e08275ee66802524135b4c50e193d1e8c8040357695ca1f9aff6cabcfae08a678937d5363d29cbdc97a05aa20325e850828750092c4a24a94a5e58eff2528e8178079c254146125e92302109a1248a98c93223e6ab6dc2516b668a191090d8fa4ade1aad7d4b9133247a40a206246648547044968fe9887dc4ee88080ad04601c014e0cafed19ee9ad1b89d2f96cb2978bdff2cacaf21ef528dde5264e675911f6e59b6ca4a302231d473a8e244d26e36637bb912226dfbfdfd9713afb703afba4f879a4b38fa7b38fcb64b7225cfece5b910e3b9134dc35228ede4658fdcc88a96a499a35e2a9067194b9978c20229b6231d9ef37eb9792b422cc22ac14a153268d32539479a10c07968ea31d6db794c911264f9eb86ab632a92e6a7b103fb14f98d01ffac455b3380546d998e4ec5846c724671199711ce31fc744e8f4c221dcfcff0f613544d5104f43f07c0d85d8aa24e6098146882a2184709181f35fc9585532543adc69bf3d324f644232f4fa82082308aaaf63994d7de61ec4d3fff374ee4100d97a0c1add49eabdf518aaaf24dfbbdd1d637f0c2d331070f0145e02e2ea4320aa2a1053ff0fc4d3ff3b01e17a3170423157525ec4f4fe5f2726898ad991117120945496f7680a939af6dbdc3680cac60f667ea8e187da0faeaf967c59ebf281071f62f001c90707c2b8e1d4e9e5e472da2676da26760aa31406d6431ba49b73301896d23cb8e101061ea2f4b183103b60d9e1680720601000060d982b606c602cf8d2e6cbd5971cbe00bf98ff3e3e58aa0c5edfe5586ac3603152df1d4ddf5ab1b9a5b636cbb3c328df74dcd1be00d5ae83153a78d161b799e84b9b394891430e403958e0058d971fbc287929000702843854f5dbbb4cb72da56467bee948626b39c661c80d5aff7fc3ee06211be8b0c1cd5b5c2c26bb15c5629d7e407fbfd0869c0d3a358c514398b0862e350c551286f90f47031b210d6668508186dfff101a1a98018b19bacc50e5eb8839efd25e5ecdcb4d333020835628830ea10c31c850f4d5be8236d0d4550d5195a5ca15c318313011432e860d609803862560c0c1c0c0e5bb499020e5ed3d9ece96eece1cd69bc4658e5f1d0c162c83e50b48bc90e505272f087121cbdc3bbacf2b5bc9c6c18bebb962734bd9ede482052dc4d1c20d2d3461610e16c2b050020b1bb000a44b01c22e2774f1e1d2e675366229ac1bb13dd3b4a7a5e696c2fd2e792468660da3946faa2487b90b898b932d7a6c59638b9a2d02d8e264853a56c0aabbcc7167b2244fdf6a07ee1586b4bcd1c2464b172d4fb4e8a870c70f2a2c852a8090421cf54561fade9ee9a2f6f573d52cced158497176ec7987b9e5e97ca9de3b5a95c2e6b9353fcd8e83b707afc6e6760a96e535352eaf997f578724ebd8dc4eae221d7632b7d491ec6a1cbcb25b51efb25bd10e67f6dd1b22ca587267e7616ce24e5c96389eeb3e5cea868832df53434439c84d8d8590e4b31c22cafdf4613e44943970731edf4344d9d4badffe0d11e5ce7326ee57f01051c65a9bbc21a2dc4fb31c22ca389eeb9c24ef10513e8788f2ef72a010923c44944ddc71a5b9f91051c662ea8688f22e0fe1424872278788868832ae3c7d4344b93ca5323944944fdeeb4344b963de105136310f87f5ee976796b7e338fe01b7c6e1a86be27c9bd49793e5c63cde71e5d56133981bc27197eb2c15cc54a16c2c86cdcb75960ae5beb393fa52286ba990d804ce64b7a2a87e6f51fd9abf6dca8af4ce26c6923bc692bb4c96a4f3d89535aee47025caeff71be10764a3b165d84ab41b567a048d812fce9b66e6408ea536b6b493c1d2de0b84b2b15854bf375f50dfdc2fb0d3f166caf73571184be636aadfdbedb8c7cb308c77b01d895d514633e35c39a375ebdac4c489765b6272b444a32330cd6e4c966a4ab4b6d4ed91af26fa8a945c94c1b2272aceff88cb5fd6e9cc7fbb97f7776a5add3d58eadd336d6c46ab99e92f47f5cb6fcfccc09c33a770bf3a9d9b4499f9a8a7a82424504102d557acf78c840c721699cb07f57d41599b92a5e2a21c2be5a7cfaeef6d7deda1f9ef55fd7ab6b35f1dce057baedef3f8cdfa7f1e99caa3faffcab3ff95b7e4bf8a3c9dff17776f7ed7b41b773d580d9e0143f90a041494548d90783ae736ff515a7905527eb1ce5076bb475f2e2b927890498864183289fcff6a84448325cedcecd9c5dba58f1ebba575ea2ad99ec72051e7842e8c4ed44d904b53cddb67d602b1ee3adf7acdbb73622ace776adfa9c5dbe526b93f360c6b8275e1bec059e19e7042ac6461e58c951e30bfa8505a6969de71d439868456116a0050b52a7d8855e254d1a14a09558a50f182ca1154aa7cddbcebebb4badb8db8974ce8c94d6cc79e477d72ccad796e71ca11e21415c42948532818018dbeb8d4970c8eb080f894c49395a71f296048a9bf0e8542599cf93be98e4999f91e8fe0deed37ab525e4e7a38b989e2459420a230450921ca04e2ad0af12680db78b340bc01694aa2c98ad85484290b97386c6e1c2e868496a54f4aed3cfbf8dc6a4b3e3e4386d40d3429edb9ee97ab48879d38362fee4c404498238255b9f9a637dfdd4c04aaff1ad4358940e4ff83b960cebcb8d3992d8eed8bcd494d4e4dccd79e9981dbc49ad43bb779335aef14a6789b1788758d4b2d49b5966fba1467a9ccd20baa0a952a2e1fc7becd77afbdb4c4f3d55a7a2989315752bafaffaaf4fbda332731b72d51d2f9af50b2a090f99f9308a50765498502646b2d7d323d21f364ea959e24119fd0cab1b99da2f4e54eacb6e8848b139f131e7b2f2ea948eb342f2fd27e220db869409292acfe6b52af2cf72f842842582184104200a1091c4da2109bb8f05f5ffa02b18bdad7d4f5b96a96d298bd348a4da6262f2672884cb4b699b7be3491c91626529814bda2f4e5389d7d4858482820e99018f8af51faf2bc39c612a5af7991c423258eaa8eecefb652946874c68804233a93f3ff412fcea818ed2b88627ee998631607afa5b05b734a1d072f0ef39b9bd987aa32ee1e904a153ae35982f55f73bf4becff9913972cd9b6253a48342a82c0e6ff65b2de6f7924db42d68228db1fc08ade145151e4138b9a8afed25e9677ecf82a794154b24509d0ffd77d448c85896931e6daa2075b3c30c1830d92b4e1bb031fc40e70073a446210392112e54054428ea8894804fbdfbfda2d7596c26a59ee18a9effed5b2dc3f3af67bc4d3481c407971688c212e434890e481240b24412444840e206445ebf5e532854ea10cc4a03541565f839a7a262dcf6210d5ff2cc8f6ff391168ebdf5e8ead080444f55fe91581aa1c89e3089afffad219783919e4d7d467b9a5ee91a96d1e713a52b134ce2d8995cb57a0ad1689b03e6056db0ceaeb824dfdd77e05935784b96ab97754cf9c8ae31a2394ceb3d11c5db573acdbe2cfd6bf5c74f663f5ffe20f95167f6cfd3cf2e3f249f37a5d26a20f113e4fff7afb344f8b3e406ff3f9e7fbf562f28a4074a1a93c4d45579877f5a0acc65044174f2d6f9f1981639a7bf75f0d887591208a9c453610379043dca0890db46c30f424d67993a0f1af168b592a3e35d31f4a49736bead371cf14897041248b480436248c2154ffb5a7a7e3a82e45af7939e517d75766aab9781687040d59a027eb2b25b3a53ebb6dc92cf61cd1404b832fa20651a20656340842dff8ffba4dfac2e11c6e9bb8a89c897d9857a1b1dcfb578362d8bca645caa04d062f881910612007063a88184c61b0c3a047c4c0820bacf8ff0f5ebca0cb05572ea0a2103942d87411b2a3512c79dc3bf6c2bd3ca4f2285d8ea2243633def1bdbbd8d7bb49a3b51bb14214b0c08c68410dffb5dc9b52d102a50af0a8c0870a441029d8a35a8b710772dccf600efb76a74714740a9c8814bc441e3e78c21079b2441eaa0a65b1addcfbd7cbbd6d531737757d306aeecd34c19c09d64ca0459c60e8ffcbd24742594b652483b8b7f53612253842022ba20440a2688688a5b099cf2b9d16659769751cc7308e182a218655621882b8a3c70e13e24e0ce2ce0a3b48c41d0d2248f32486e1da35597d8ee890fa1a39d6510e411f22044188105481800251e78da86346d4b1a2ce4dd4f9213e50467cc0870754b0b81fae64d4b40a65a94f858ac52c15da7daaef42a13ebbd3dd7de810f10110c4079644076a70a0141db0406ca08fff11caf672ef1f2df7fe755c2779bfa54c762bba9c49cfcc527ab965b7a2cb316e6b8e4b1e6f9b38736f2e2b2a37c7e6353bc7220329880cc082b911e31dcd7626932d90c5f3e20256e20253ffe20274b6801515b8caa2025bea2d881931c896204d82182002c1128178f9aab798801e62024d245042024e0944202220c78c8840504420c97f0fd5992cd28f68de4bf580350e10e200de01444403f830e08c015844034ad100971a05882940271640452c80e7ff672ffe58f3238cf843ff18c57f437c23c4078acf81f83a5f3766d273fd9dc192674aea2b85f671c11c3ce6383107cb9c2a73329813f2a1c587152af061850f217b68fdbf6e6c528bd03eda6c2dbfb406617b04d1830c3d5808f540410f233d84e441471e0408f3a8210fa63c20c0830d1e5ff050c19cc23d3ddba419caeab214ce45a96327f5b9e34568b0dc5ab395668bcb5693ad5702da4840990470a9346629df774c71c70d77ac7007d21d3f42397bc8b9928345ce939c0be4e8d8f1851d63fe6bd05218ed99f5d06de619ad3db3a7278a6f60b6ed7293a0295360a4632c265ba2635291ec725c47b00ed7ffd77be940d32fc7744c753a9efee9006e4dc93a879939707324fd575a350eb135a8349545d458aa19000000500053100000181c24140dc8a462c1644cde3e14000051b47468dd9836d1649d54c81863600600004000400002775171a3e24156cadb10d96309df5fbd43f80c71507817fd707ca2c8e3c1d2c485cc87081f139026bb817ed313d887db583c563a9ebaeb5bb7465f92774d263f8d759f1c612a3d75c6e395969eef524e684d403039fded06032b9b8b89b1ad7039aab78d2d2f47692ba1e789b1137e6601a9be07bc8d895542b0971e36218b2f75be69489b84c1fe475eb70f9ee2f68d428f3f249d366b89df4583a6d4774b7559d03c9bdb48ed737f74ed6c625826a0006c7c21caf0724b86ad3fb229fceec5e1ccf3fd0df78cdd3e6eee6eedee483f8216b7e4a2dd6eeaaed2f7bd3bebe526a482e5357980d1cfe321c504e645716361f4761349d1818a174b657cc657a067877a3280ac2c82cf37b81a2e08cc74e7f20c4ebb55bda8aa05e39fb1f2864b60b424dfe96a000b7f94d84597095048a0101dd28cf37f4742b1717e4d0aa7bb14e47820446962155d27e3b9561af6014400add1ce74c2806852823a07782bd282522c52989188714c5fb60f17be64700c3be4e71ad3e92bd352738e569f5248fde93fbd02fbb45553ea760903b68a5da9b11740df2c9d7b33225a60b18279bc82351f7f7f974a1683920d4c981b42fe32395ec054b2949f6a39a3ace33cd21b2e356352a0a25343403a9037cc39166fedfce56c18b2b50eb9f6b8dbda5265a0e0bf4ce92e6aa0aa908736a8a57602b8a15f037d8171cc42a87db3094f7166539737a90b43a84344dc96d1377cfbc4f181761ebf30d4837fed1d28f2f0b81a23b59bce23fb8fa34a3fc048d61b171cf93ca840a4c69395ac7b4fad4e17b519e9ef94c1f3936f56fdff8441122b00ac6e16696e10909e7aa894156852d1bb91404fde7f1cd93c394617050641433236c309b9e31659f93dbaf9c143e3626036d248dc84a010620012796412a8d6661c6ca4a8a81a74b82e95e32a80f3d7694369ece556fe2148be8bcb1f3e2d4ee2f78501e83e229e331eae567489bfc48ead1b6133be1b837cc62c0e0de3a38a284ae8509a241e0ea0ca3d65b2d287c6e38d0ff6c5cfcba3375cd7cfc2f82f6f26596c900524ef851710d66d278b03d4903f76b00ddaa26ef7fcb507a889d598e915baa8ed2bd0fc63e68aa2cc46d96b8fb92625caa608a42be71154f9808222a06d62f4941b4907235e5e0cb6fc428297fa84e3914fcb8aa21f35eb1f4e3efa48d33287e4b1c525426070d5ecbf09e71ddd2051dd77b7b0d7dedda1b2cbcbb55ab504970ea21c04635b7f6d536c203f3d8a4cbead514548e382222dfd9723479271b35cf7887374495ba6a099ee386472ff770698215588c601b4dba6a8c981967ffbda66cc348bb3639bb1bc38bc1bdd7048808057c1bf480403ad0644329cec5701f92c861dc4ceae7755e8b3596465cfcc913fdfda9e5c348a921d980833cb0aabf0d0af2d233ac23c7f743e86033314c91709ba6756b364ed92bdc9d52003e54953eb85354500b251666f971fad0521fd20812e405fccd99035add92a61782ae43bb93141232aad6cfd8ad71087158ccae296b54447278c839e8536f0e86a55e2ad13e7c86df20524abe12cdccd9d45b144ef69afb4d6b1e0d50b99ddbd7187b808395f77aeb60e6f042c8fd21e501147273969bc6b4abc81744d90005d96c48a4b57bf18b91fe7c1d7a5258fa78b2879d15b9c6491b336d8b5b549573ee5c65930f4049f751bb77edb9bbf836980e34317c2314a1abcec9b11beb4209ee15943d8bff61b0b6ade42d640bd7ebe44ad29394855fc3fe6b19ac91b4d55002d62887bfe83fc7f431fbc3b5354f67e420a455fae7b4f572cd23e2d8a22cdce13765a36c309f4356977becf04e0cd9ebe9644c939131b62502b0676e4b20201db11e5fa8758c84a2f739c6ac1da4462c11ea5d729b9e3a3109166e6da97a247816fd0dfbc9a49a4f8996cb12f007c272c1dfe870ed836a4bf793e00ec2728fc7f1ed814d35f9384dbb6fcad0cb8eb2adfcc713b22b5b6f167a81ec187402bdb1ba080fe264942221a2b9067714f6e71dc0067b42e36b36ca7fb45cccb6739f75c0773b45bfcc395d0435eb8f8a125d7f1cdd1897982fb7c2b5a18919b3ee6e490276fcfee9631ed40c5ce0d822c663d996d823da258e0405d234af66b570e482f394e9590dc7a45afaff02e5bb4531429ab89aff67d69a376a83b935a9ca5b8157b7549994e1a09b8ab34bc5f63f2414f08829a599f4578deee8e044d68354970f442b13b9614a4ae3b7781411e13ad77fd496a91b72490e754019a7c78aa39782a073d3cb5efefa9d2f2d5905dc7873499e343c3e61aed628795593bbb4facec798bc7a4496508809e61e024b2b314f4fb35136312fad3a05e615c1b9eb706361f10d2bd919d7f1ba457288068e3db68386d44569b480dea4d8cb86702440cef39b136f09491398c313d2d8696d268582cadc5ad2df883eaec5d9a6c72eecac5fa2358745988923db4f7d585aec6ecafd99015b41fd0c2e393d81f081665b89158d5f39410969ae340685babfbfc2049d2fae3a3e76fcad774217616dc9d659dd46ea19b43661991db2d885eeca836e411f7ff34c034102160019910e831b48f54bc834c59e19962e952f6fc48077fcedcd2695dd280a687bfd30200ee1aa37c8448a0c56592691e48d459834139723e0c74c8bcb420a655a3e8d01f27b54ca76e627b8df283d809da70153c5483cb63e9801cad5057d7d1e846b512f6efcf1fd9b8a00210dd8cfb2af26287610d0e7096d6229e759c87545c77429723e4b9b1cdba6d30f74b67e46d8d73ecb0640e483c4007b1cca60ce7618a8bcfd7ca907090b16dd427fcfc114f471bfa1d20c8faa9c1d37bc9d01bc9e746a58ea6304698e5c5cc9faaefdb5e0af3de64831f63bf00451cc1bc4b68fcabfe1c62e029ccf3f9d82edafed7b461a2adfd28594cdc9a18e47af01d18fc6c6154cbf9acecec1d4d94be7769cc7f00cb771f49cf6463ce00169763628784172b58858c64f2ae55561ac55372d9c8ed559df71f0d0449495c81f12b77fb3391c31cc647d091c59c437387d3e0c54b4a1d3cc93572d6f4b942e41c83f67f8ef69f30fbf3216acf155facbed553df092374dd21211adf1331561c033774120c487b4f8880993e186ceb209eb0f2ac68b47612e1b83851d7c0ce61f90e669b2e3e364659c236871ff0ff5ac45d51904d0bb8515b40d6cd2c2f9acd54917957ac0dfbe845c9e9c915a753c5c33ce3b6ca9297faf3d6c8f896c91c1a58492b36934b3ad9d0e29898e4353a958e67a98c8c5a5d29c5db1f9f28ad797380010600a83d13176b3800a36f1776b94916e4d9b2b86448587a40c896b1e266c4648e2ba99176ba86e42b251df4d19ac48921d7283c834d02be558bf76b9c06ea22fcfaf6a8f7a3540c46f73a7c2d19dbde919c49c1f6f5ffb217fa421fe838393009cda0d358f2bc242293f1c0268eb2cc6a534196bdcee5c5358662e5ab1db400c9441768d050bd24ecbaa0f426f437e03b94ace7124ac2d667106dc9df2e05923249cd50e949efa52ce557ad99edef7ddc48831be8926dbb9d63299e09a350d4acdcf7034745fb19310180b52485c68306ef97d896f010ddc39012ed162bc5c07e5b47d2fa307974227a5cd3ea77b1351e0913563034fea7429e3f0aafe13a349e4ea1412db71df8200fd5fb4db617c34b842bc1b500a60c53153893bc8c74039ba79115da275b0d949c9f4c90521b9337972eaccc7b2c007aa5416e163665b51d3b22c405e61bbeb2465196277331caef2092e6f155e8b4ca1a8fcab8415f3d73096f305cc4502bbab3503cd0e90acebbffee6f1b5d5cb12c8c37cabe37e2ed497a4c9ca3475bb2a4c285638979b04adc41ea3405475cbfd9afb140bd7f899c855547b425dee813824694dde1038c6f22ab98cf4ae5923ec5709428eb27eaa863dbe40fc4ff665edfad82effbb1e811a7fd2141a9c46849f63063689aae5ade2d51bcdda66e335856cce2e66b1385d372393463290cc4e9a9490bf7843ab38953d2ff9437eb9d27690c0cc955b9ba451ca57a628ccf47709ae496133c905cd751494ee9a4e68ac14618c51c11cb1e6e0b83a90547542073e137bffb261c59008a99f9ed693070adebacb8409c5c4bdbd3d27303f4477e9e2f4a1cd4671b03836165a42d5a18b7855600ce7183eababb78327e1b097d06df400a421d9cb6afc5d5c9766e943f4f2c867d4761d840f4b4e09d6cbd0ee7ff11a93d81a7b4103dbcb8639c4e2bbc198667a3af4413f0fecf1b029d757b60d9da83476a2ae7d4a688b5c1b249e3b0ac94f3b97d71b690398ee64a46bda2edcb2981d1dcd227cf429693721c9efa560e9fea303ae39671d1df9132ad776aabecfb7866319c38cc495ae9568c30100ec09e02cc67353e868ae452f3f8683fb73a630ab79ae08dabb7ff4f65b683e4423ba5fa1abd67126c0346e2c80c77f0f634ac16539f8a994cce7ea77e7f3d21cf518b871277fe1923105b6bb9191e50595aa81c0604eb3c57bc109927363ee99f2c4db9ddb7af2e2bb166aeacd4857962b18ec4e1af6c5398b7e2c97edcd1853dd1798e86900a7406967194318f950c7115b2277443e2daa6d1c028af35fb91d7268857122687b0fe6a8b21c962fb1e371d6406b390313748dffac8394ef2be8e7a8a5409de1790880aba4d90b33f9974800c05cda41e21d43ac572d5d9dc1d3d301064d20acf204e6d44d8a6217b63a8c7b095cfb5088f12e2821d6d61719d13a82374022551b8f6bcc56c1b502b84eb9fa0deb0814eedc76308e83c3d2e493c2cbe96d7ebde5269f457f3511e7efe6aba1db8e6b1a106ef1f64c5845d9d7cf099e5872bfae2c9fb752a057057997ca3a0a203e12308d67fbfd4ae34dd9bd03c9fbc1184e3e866f7101569c4357808242985f5d793e9ad5cf91b69be5817c2f2d4c8f01757861d62f4bbef7bdd043f8f8fe9ee1fa8477ac2d2da62ee0cad16e9aa10ea8a989c909c7c5e48dfd7d5e500721d07a527f4f860ea3c92b3a65223646357bde4d1d111ac009c065ff50e68d6974e32227193e0c0dedad1e35853ef3761b1e029babd9cca9af399e0061643c11a65c42af84f2f8e3f38aa69d045a7f38cb18302b5817eabe5248a8b8a0d5d8a3950abe3ff237c4de42d16d2c614fafe6f3007bdca9ec0d2e57a4e82870a06bb56bbf3c1329535beb2c1773e0f347607daf93c2771108fe77073d8abf04379c17bdd89f3fa896df8890853ead950a3b40b1d200d72ae57b999796a75e3aea310c8a78e7533ce3b9467b9b0ccdef0c506464d5d1c46b7ea7a4d48d721375d5eb1b055dcd6c676562305f499efe83791985f600f54dc91ea511b0a93baa7e73b856ed206e6321a3df0386b1367e058292818868e4bea19f844bd6f6eaf38896e568190de16a487086bf3ac279e482b0913d5a2b4c7d0641bc48ce918d1ba6bb1c7e9c0d58a0eabad985efa2cfe7b04bb23f5d800d0de0ffa4c6c5e5061c192d4673fb5dcbee650739aecc817c64792f6ed9a97705d75d475b0a908aade2948910662f85acba260d617191717bd2f8326d92fb1728e93198d130b6006c25fda320d32351f912f832869a9a6c31af5d04a038160b194a0480f692195dd948f07b848ff42b3c378898d22b7e33d4f8e8f29a083ba70a5ba7be9372ae7acf753e42f5ab88762d25e0810f847d7b84e5f73506562bb5c6d815c74b84de897e8989dfef4330a7c0d06ab5a52fa8fad16913d2df9cea779553a35c2e7f41c6177108fb31fb5bf953128530674d1d37c8ad88b7c60a051af84d8437a9491fc8ca0311e78646af93fd18521f3e609387b117d4c0207c35d0efcdea697cc0ef4c96bc7cd639c9fd21619209f11cf635a92e17fe39df11cd2a0f68d87eacd8967e5a0feda6e7a7b18ebeebbd82e5521f98aa9f50763b981c3551b22762ae161805a1223a55c5e919f2f36b4272c0bc229fe64781a91a46e0e96256754f077e090855b316b7c336060cdea31c33433a5b1c6ca7fb66a2ed8ab44a8c6e5196458403d36aa07d1c7f0d678c632fa7993b20b0880d58e611b801154ded240fe3e649f264bfb04bf377d89d5da43e14b07e113b3770fbe69a3ffcc863133f826537c62f555f0ce22ffc9d84326de3592ff116399453711b6978da7dfa4105a5c2e7518740990d91f297002b88718ec311988a157922a7407476925ff325bffea886fe94e54bf5a993d0d9ea1c02c81682ee1d388a08579d75de603b53f57e78d5d53bf0c5927ad7891c9921482b5bf6892c995e6810109197b42db6f3e2e72f8563c989a865370f050b332209c40aa0b273d0c923bc440dd7c1708ddb98e1f1a3174e25ca082a96607728e86c97b666696c4e776430f37f5a754ea6f5a73648f2462bebaa5167c23ba80065d244cdb18b10fef334d91d1969d8ca27721b25e90b1233e8b44b8e4894912bb698b6d680d5f77dd81c4c02065586147f1be5384c36824d550cce5194cbf1c42d3925fd0cd2e816ea209b06bccbfa55dac3e78ca5a4be0e3f33181e3c6fd9300d9031608c73927e06285bb8075bd946a51785dd4a9c6d5d7e7e32768070797707b9a70d45d5d2c74f1f708d0a69eb50c231a501c6702639cca7f5c09da976f8d914230ab5c5ff788fc1e4a39481a49d737408d115a534c344c763d94b459879174a05bc8240b439153b372f0d516f89da1a804df2b65a78611da9d1ff922afccab36b82f6eb30e6f850998fd335afb9d29e4ece7709b55c7f7bf8f5413a0cd236e3edd0187dbcdc9455eb35bf0bc69d785d5141e92c219ca33d09d64b4c14ed0d58d9f02233dd4ced9a379993c0c8541c35c79c1af4e6c60982dd8cb55899a787534a69c72c00822bd0df36734805a65419fa87c7103fad03264e11307d06e614c1a34aa0884ad300dd5e5308000caa68e812df133ca6f14a8abaa185ede3ebb59041f6c566af611c46d5fb7d2b24b1e0b92d9ac577007b8489e6f41927a38fbd5b8690328c73b8a4e65b65c3c01c205eabdc3207c167e07b08b88a2b7b26b01fd1725cff7774df0920f5b76275d8fa2e0d9272494260db19a2304c01aa9ecbf699a21e7c3f6532cbd6ce926fbd4ba2c3a58be347304dc97f99783cd174f42e53eb8a9e2fee9dd2a995ba554d7d4e8ea475725390888cbb95119d9012b2eeb8e64f749d9783c902ea548d2bb17160b0e9c34ed05e1af04ae9403d7cba9588b0f8eb7684796e4b04883fb5580f6142338d970303248f4af43fcefeaa420f86b4630fcda9d6bef478c15dfc0fb2e733f16cc0848d3660bffc3443543c2c15ddd13e7202260bf07e6070f035cf4de1bc80a33ac174f870f8c009c64a57c4d4e34a3a62f5af16289c8a69550c1bbc7ece2631cac9a2001bc1400549b4138a051ce3c0f654e360fd2c0dabcd50b0b7da3bdc421fd7434b0f43cacc242138f5486a040a41b465cdee75ee1b27733260234e164e529d10e187ab413793dbc35b3a1979ecaf13528bc6e65e358dcb53c725de6e3d370aa58e04f6993298b87adb167187715659b2e85f755dd0648a3f3f5f009cffd81647764e134f8f32cbafdd79b00764ec24b02dc02c582b23fad89c39ac54d531bece98929bbfbce8c08f4adfc8ebc0911c5988cb0df10d8feb99ae89fa8f77e0fad3a8228d2299db807a695632a047f8457efb1e535990aeac15be2d6573cdaf0f0cea54c7f0baf0d5280815c605470119add45f0ba2cfe6af5c18ac63c75377891f458381eb3a14cb4ba9ccc397c67584e41a7ec17ee2207d48dfff7060125a1006fb1a2096e20e94d75eaaa0771c567ce85aec684b405ce200cf429c702508b899c74eecdc95ee08005d0fe2feee3b15b07728535421f9ca401a27336aec80bfceb6872f72865b07b0f343909ee7457d4a96142dceeb161a727d23811c0b71b986bcd54d17977f1996eb6b293b896232303aa8200c3f277cc5a79a465e127647e49134bd2b47b7c6fd1e2ff863dcd29d77363deb15f098ba98d8ab34060ee7b3ee1e16edb09f83953dc9d3202763e673a0653aae4a5006e39edc963045ecdbab1495c2e44b36dcab62694f35b99f3552ad5d3af077dc0f040ad48206eaaaaf22020dce7f33153a31f1f1e2cd3d6a85973b15f320ea047616cf67d2007e6d0e8b924fb660fef00f2451bcedaf860e5389474abdd8f06e40c1a7ffdeb8dc6c189c1fb6c74ee7a0c726b4f86cbc39ff1cdb88584be247c17e4bee8a1baeb82fff42c1fccc3efc857047e721870338954cc167473ecec22a7552e3b16b7d7da5b82189fdff58b3598b892907ffb496f919a471590b04106454b22e490a7027e449ae3379193e4670891575e9dc661796a7063ff789883ffe7b9962bb92f4ed55520a14acdfe49ee9c563fcb1cbc006097f2a2da17edc7a04e07d17137f3e483d29f0ea420143c9c43ed173f52a292aa941c611f9f579e0282501e701c5fdee386bfa7e5b12ed140bd15be54913c94d358d95405402762f0c4eab6e2f2c21baba3bb722887ef0ad7eb5157ff07b865ee2525f27263101adcfd8e7c9369304c8c2bfb4de777bff0387e31361c5e28a65ebd86ab835e89b22c67afab7c76e7be5fa8cc787e40348607c3e0b3cc394e1453d098fb14c9e8973f5501d72077cb3aa1f82178b461a087430fc62f06163ff6411eabd8d7dd19f4c6ba6c274b1b1b016edad5c87f6fd16ed7267d70777ef19b19d8d40ad560d5e1739eab8cae4792a7b5d89812ad88e7c475a8459d69262be10ec1f91c3af1d67fe77a6fbf7f0d4ebe6ef0bd166de7dee03761812e2b1858fb944d7cd5a22edb8fa5ff83fa1be9c5ba8b8e549cec2505023d195758713388d22c7035dcd4354d7aa33767aebb2a2c587b7f42f70e337791afd9547af8fc8c4bbb3f80d2f36a96502ed3e965fdcb566fea2c8a2253690b9f5a3801996887af6e44c10340469a7e4149407de51ee2e9eab83fc854b5612c13d0140c2e4d01afa309a353d007e0442283e07ad6fbbdf2507d9cf056ab1de56c919c71823a43ad718a1e45221dc2ebc43873db969d036e0950df683d9d3273c08647089cabac97e551e043fc87ee82edca133daf03c00070603a4fa91280d6c0366f347795597334fb68ea882d87ee1f87f4d1a9f638429c3a75637d78262143b10903ac4123bb1e8e36a56473c15d490fa19066d17e9c45aac5c838cf4c8ec5ca20208553c672184ab065802d4c959d3c778ab4c5d1bd93f5fab5fb0e5cd2d12dd21cffa1c1bee77e29327577669c64f005ef8fd06d8c3a44e0f032b233c7fa3fecc6bf2ecaaf87948e82476a97ff2ed5a830af9df585ce74a097dbf04e306ddda7926c2217eea6c8daaa92a33f95799daace88acc0b9aebf0f85cde627d9a58c003821ceaaa52245c59670bf8de4190600af0283af4d86cfe59a8c7f90edddfbd9ae15ea04021f3c0b8bf9259f6cb9a454847708755e370094511e715aea178c5d3ce2fb3afeb3456f891cebce1ea3e768a49afc4a7f6828d8036513cd1bbb5d07a327af24af4c7d8daa816a3c1a9be94ed60f70235f30ae3f3df0e469eddcce81bd2c8473c1f8d3ef02ee93f93367e53ecd005cf440cabf0203c08b06cc135c0e892ea47e571af10615223522013ea483b35137b6c8eb492810c6fc6d2c2dede45c22ffde58a3902cc5be61cd95100c3ac9ccebce100a3ec1c315640abbddae20eecdcb04ffbc9c58b7be1c60a40ddb15cd640b1b048b6cb462bb1c0b055d29a27d1391f7edb4264bcf52c7c9a9d4ee00e8da32a0b6876e82b11f41430552363e3eae4c4435218d95a09deb2f576df0efd71b34410df5a81ab656d6508814cb4702e1b0ede6fd08c03d1f1499ad31e046632a0472d03297d86444c3c6bfda8a4b8bdb748c683edd71551b1e28135637e064f00dd2720206e471813d9908fc5303d37916a54fe4509790419baebc00d33afa6aa037eee719b95f8eafe38f0f1267393fe60c9c8a1ed911a1443522edef65e21a9f4d90068a878b7855c1d50fad3ad9881bfc14ca70c4602352e27fc991ece95b7be797939d6f2e79e94c41bb70c2cc7e7433d907dd7ef882f38ceec0a43e648b072b19efafb84e60be3f5ee478c235385ee3fa59a1d6a324781a1b39fc67c9d1a956163e20c2fb873e057ca0703f6e1dde9acb60bcd2668b9b4a21763feac09557918ffc4f4eea0a4f0d9cc44eed83429381337c8712718eb9a927ce6cc0293bf836cae45d535a45159196d4839700f6cc604f3d2d8c584c0155e30cda8c8c01717fa0c7e5d9984c4c14856f7767a6f730538e669de833de781c1b271fb9a232d15700145b955f363550b57452a63da8dcbe91e46a1216106cbd184e90eee6ff0d15acc2b25ec79a74aa4f71d6b3a5005fedac263db7ec10f5071ab64bca6b59eeab8e7e035c4ee68396e79c28f6cd911798ed0d31fe99f342178078322a49077089b0b03864874150a5c689190c20ff20d2022679d1fa1c6d34f62e26ce115cdf2599e9cee7c1793f4dff71a43a40a56effee4d863233d7a6241d1fa82146042cca02ea20d2d1602c6eae8f158c5a0a60be1360dcfee05a38f682a99749ef3ddbacad74a9d813a1248a4bfca18e199e164b58a4e919862a287aa91a63fc07f7a07e88d0bee25109f496f98955ca29a89738fb5b3c33a96f1d3ad6b2ee027dc4170a339cc9b6e0713b9bd628f098fbbfbcb1a3ddb9436628998e592f72548ca331cc564ef923f4d834cccecf4595071a8c235c1fde16ed8e6823b9824be2b7f030fbe256b0dc35f76eabea2e804fee81c82dc47e262610a7697e2a5a4bce754320d4d44c30859d1f49b848b0403ac81841b9c660718ca144d3a039da6e17c39375be90011f2099cefaa288f46623856d77f6587688b8e38a1a8f5c204ae9c2d88ad622e89ba77061484eb283625d18aee09a88d852db82dec238b5803ba6a9309297e2a37ec457b29273b2be5218752f5f77c2b86e755a05613055ea2625b407018b5d088328b92e49408263f8bc8fe4ff2ac70b06d4006baf4c7afb1f389453574bd72162b12cc8e7f173226d165af8735e024371b730f4674135335e63f0b25d131294b529d9db250a9fb84b16c7373a116b8c16efc1ef63525e89a9063e09d8547781d7a24126d23bf138049d621daed9bf5b70e522760cf5816f23b2031adadd6ed6378beb1d596f3f7b6c509eb57dec36c6f78decc1c7b4c1eec68941ecf57ea3d5881ceb14220d00d948b310348ffdc03557fb6184df31324ff5504c56f22f8c056410f922c32bc1990d1ada45aea152e8a52aa58d591da4c0562c8aee15182408f5172f8f5a35675a6776610ea051930b52b39d65da2d341b02fbcd7e84508cfd7e0dcbb5b4054b936d41c91948b89c00194ac8f23d087ecdb4a508ac1265422edfdaae7bd768cc67fd19fe75b43f70a8bbd913895cd59899e4f020a1c64ef2ac2cbe46064637873425782790c2e5ced53bbe8e83ac5f56f15de66ece8a748f15402bb7d32bd70246106f97f728e36baeba596034846168b81921bf21f90e3ade509bf411c9576281979e61851f85e5afbb1b5f591b0269582223dd51b073ae5106852a4dfac27e953fbb4fb873668aa015113c7613d56bc3524fcf02918f95fbba16661198676028f3a0229a68883a6ac6c8d8c77e878f73fbf84f54c5ec37bfb9f25ff0aa00f76f9a96217d21a23a3d627edeff01e39000f644e6bfffd25fd1cee1f1bdc3de6bfd0010708781f28d2bb777de718c22a6c5e4c6189a11719d2f24a18b55fbd02b3db45270d4488aec686b5f6a7afdc2d132832f6b947cb6250a0e82204d31e3933ea780b8e90b4238a3ceb483b0ffe4760b0abb85931f74f3211c33cf486ad7c7b8cd71d6662479c8487b6b92bcbd9c81b3236b497911f132d8566d0a07de0f8e6cb0ee0c80bbce90dd211bd0439d123506de95391bdf26379c641d8e577281d7719aea805e5a0661576ab69740fdb5b5f578eb5ffa614b586c7bbacd7269afa70ee2abeb92ba1587c5c923aac7b87512589eb92d1bb1404c9d1bd2b4c20da610242f4043a7628c21827249f6ad51ec799c2018f0a6c3c0b501008f14ee6942152f843569b1ed03d866d0945e3b9fb819e4438006513695915a3035e1158dda51a6393f7be1ad08ef88673315be260c55a88e24a89dda96c308afa221e0a10d08d933006272088972d2dda687f27a873311c30a3de6573ae3561e996e4b0b688e29e6f40b32f9481d70fc4074c975633cfc71a966f0eae175e2e74e3026fe4c9bdb1ad0734061de6d7e0c52af17648faff0b7b861f19a8c50e6fee04514f4e4d2095157f5366ab71a00495ac353a5ac6f6b0b0c56baf80080356e16786042c5e72dd5e29da871dec73e6a1f68148c7117a84bf6cd00116143fc865b4d431edd449b5a2963e9748e6d88908f7909318cd48fbaa201dc64b87d518596ec00372cd3638f7fc326b623a1922db1a59d77be8148428281aeb063b60dc8e0a91df3f2a49d2304575a5f6d9c2cb8e7baaecbf6f5961d3117436a829a43620b859a8ac4de1f2e79f72e30d08122fd0ae2e3447e3ce626d4c71f1a7a7c126a4f55ad6fd380ba9e99cca42a759bae5304d26f4cf1b53d88cb112269b547d035d482990125688a3082401a8f1ce8e3d20ebc5517888c4d180d44c5108ab013f55106fe1c8eeb4f4ad70964ae6dcae3b82c73fcbddefe80dd4280ee3818bd4ae4bde751b8a3a0747d921577ad0f7936019f23378bf850a6501e50b19344e7734cbc462e0f492c2d36343c13785988e617429b96166108c12920791a3ef18b7f5e252631831a9bb7664391a998455aa7d742fa6b49fc52c7c759d63e36152ca18c6ab846148dcb351b07606333ad7668a6ed69f1d6acc9a6ecfaa8515845469a426d64dc7483d4d90b1e35e14386036d680bca3632e9403f385c2b463dca9799a3e57cc31fe40b633744bf5f7cb818c5af7a8f27c9a4d88b7daea99ba1db01bba02002d2bec3075796991db30ec1dc2f98929c0ef031b7446206c9454ad111226f19614f391eccad26ca805f039f6d3a4d712528a00408045172bf502b5a5c90488c4f2c6356061f01ef33fc04763c086600e37b65f581bd24a27c9b39a7f0c71b9cea5430e36e091998b19afed0741a66bc5c06089689e8111aefcece76e8a5c3ae27d1913ded3d60f17c989d019146871c37bfe619287d227453baae9b2020f46910b821c276fe3266707a64679050650a22e2133aa7a0f16b34345144c4ae87134dacd0e1ce3abfeab8a55a7f9827b2d0892a369d4051bb0c3cbac10d04f254f0215cd1cb4438293c497cd186130cf701ab42e94ff165ffc43310fcdcbbbe5fc60a25a8546e4274199d30d213708a60f739f2cad37ee467e370a3d517bd96ff405cfe44406081334a00ac618c80a681892d6c77852a57ea8ea3a0184b8891f25277d80e941b4fad9b3959fd37e1b4af560bc46c08c868fad56c0d58baf73e6466d959e7fa4047aac032ef09550d0c748b045fd1799dd0d5a3274c272c7291af54c621c1d35379f8b17b5ee8ccfbbe94e88ce136c3d990b9c0e2e7b2372080532e836a6340f730e95dfe9d74f031fde53835a19943bce7b52baeba50b8a2111fa65be1e97b5b46c3c0f2d16105a191dbb0ee22cd5820c28e8020bdc2cc92b0021f5bbb78e8d5b1045b43c482107b6cdf2d0dbf8f9ba124e761136e84a1ce9b0094d484fa620957fee615abcf8441348e477fcc64bb493316b0984de66e4d773e620a22dc8919621606c78ffe63b4d3db468688a05d2c5060305e203ce78059c49118577d4548c462680702fb76910eaff70e27419cdfc7b1054d1da93677efd4ca53a0becfea6f2d33880c4c117e2d057e322a7608f7ae3323eff09622bbe1430ae4eb25f090470ed5684ad9d119235ebcdb3e3c2724f2acb589d57fd55feb38c51f5ec2343e1305a75e0660c875c17f820675af3a382e2c3e47e5347f4172610855131b863296a1f0b887fea519a57bc76aa6df23d7fa723d3a749679d5f599c76d130c9f97a66f8d83313ee7c0083fdf5caa5fd459a72ccd671c3d54cdc681cc82f6982ae84989e663caa45ae7346adeb36bb7abcc2736b763c7d827a97c2f701992f11b90791307ea793daf7b20d0b57aee07b39270aa754d980a0b600946fda80db8432f6dd1b420ac08242ca0196960d12c2a00719c1ae439b94d43082d2624046a2fcdb36a93826956b827e1c2e6ee8aef4a5c5c2d5442252e5fded5a2fdb1715943b656dc2e84643bbd1d7e85a66d55d6678c1314461a71ec7635e8f94acf22c15f903c2fe3df71203d07a2bcb2b58f76d9b74f5ee302abd2a0cac12ae0abb0ad118db49ee5632a6e3afae38cb07831e5fd6243aba101d532e58c70c5f5c4e6f9a30a7600e75254ffd463fe55f947ca6d2af283cb5f3c4e7cf1afff93c707c4d037723a2be99b4bc39e9940d1247c9f48752772e23344cba813cc76b9ef7dadf50b7f51e76744be74741017857c9357cd9c09910f34ac55caa1b5a768163a6ebe8b289e315c090769dff8c983ec2d66e65a8b3131cc81812d8336c5170671867990015d7d66d12ef26c17c48d40d686fdd8bc8c7f07e87d4dbc7583a7c3fc85ad396adedb961bce0d497c2384fc8432ef0ae40df9b45d5b09e811a1aa5152035b26d4f396c54cfa6661389b37ec2a48711c33dc258a1f53ae0281633a98083bb118a7508d114fd003156cfab92284225f7c9f2c46db167386f730d7ed1e99508baa14c300e337013a6633fea98b4a52602153186d869acc0b44461b8face84c3be8e1856d51b71f38908bb1e57b09aabadc53ea2445fdca47913840bfcaf2d2854a0f6a18adcfdf0167d4ccf450e4a891e3485f6c58837e983a25d310392a5ba70acf99ad481f1f830a3b256ccbaee8b8227a35e8a58b28dc0d1da29a6be70ff16734d580b26606c1bdf3afbc7d2bc21ffa79928e43bbfe1ed7fb481db9d1b1cf91c7d7abda83ff750db30fc7e8bec7cbfb369cb36fa021e943b6b47ca28c9c56765e9f7c61e5d5110d898b05918bc778c726a64ccf68a60a4d446e104a32af659fe3eab134fbb3193f83b3a9fd39ccb32f2e2dea2da23cf9abbdc8f15f224983506056f87469511bff2f01b18f25c9228f152fc2310529a28c5553eb71a7a6801aab79a472f5800c4608be08b59f9e7152e3687309383a2d174abc57ba9e7267c834e657d741e73709fd77f76c0289d568a7adce14331bfad9a0f33a4ca976804efe23db5ced0182e968224ce30c924bcd082e995de57faf2573d4fda0ed66eb3ae0d759865d4b7741dedd3c69981fa17dcf3b8ba773bfbf75cd2445f642225fce3203d24f965ddda233fa41d66710b6f154cd4958f3a32a819881fc2ff1ca757d3386d408db447a20b68774b0820074fb97481611ec3bf3e264b01481fd107025c770081994c532457386e1dde683397b8f28d8307af81e240eacf4ca8a513044dee4ab9ae80e89c23cddde6ad871345553c3cf5a80cb29106d71839d1085a4b710fbdc5bc82c37f033d2be65661c56f33cb905bf0c12b4bd18c8e6f786430357e35daa5693099d67aa69c036416c37519b933c37ffd02a5f63e7090771abcd90f7d9e01bb9a3ec919a7cfa5fe38c82a80a59f5ad1ada62613959a2c1f3a7a0b7dcc2e5a2a32fee6e3a8f58eacd2d840b624199f7d1c640bacbf639708e3c9025d19c9bfc6794b5c0bd33aea9a67d79897e8c0e48f2854e44a3f0f6a9928c3ae400e01afc26acbd75282f76e5024b7af66fbd3097f6081cc020d62773e03438bf0d1dcff01f272f36ce1de013cd8e10b1279a375dcfc95bdb1fc8361cbe102636390cea7808793be4b2a13744110a504731e6dd06f0b740d556ef5891368763ffa4126389fcc256ab8cb9fe69d47493a615559a3cfbb059f7eb8e1d77859acee4b6c48a401b60123d4ef0296a888fb67afacb9cc5da7f09a912beca4a62b023f10b3b64bf9e28138d9c01f87c3757cc8b3cfbaac6358feb11cf8fcea8515b6268c34f672a3e83de3ddef7f2c5b5488546d26108b28e01074f50f180133bf2ab757ce0aaed3793727f2e987fca522f29e8ca35ae335544a7b9cde7b8013cb9992d660560b5e3a603f48907773a405e70f56685b9c36504e30181c096a0386a98a03aec70705033154efa3aace2c4f39474751e3d34b084f692fe2b0069179f0446d012fa9ad591608cd8da48a7d9c3eb06721fdd00e020618ca20c2e9ac66c59777c38088cd9ede70eec1ecf8ceda63d73edc792cd4414360d684bf57241b5d2dc6b81b5ee4956a6313fdbd41ad6d5e8edd070a21e755d6528af5865961676dd9f5940749f36c41fb8fd8e51b83e8af26d88358526b2ca4e1a2e1bdb7f9d361e6b33dc095d18ed43be423d466d004be044083623d22633eec7af79711f9bf9b8b18b47c4924fa9aed721ce2663a7dfa4bb13f9138e28f91c9d05cd88c698a00e34a80d0cbc402a7abd1f00457f2807404e5fea8e51103140ae88a2fa49d76bd4f72d6152104376652bbda6fa30dbab2c25a0e3417f61c985d7c90af74313fd1da67ce86adcee4955ff4fc502d24b0bc33cbce06ce002b7e5b367d9de5ad44f6b676cf27db35901071670afe22d54c9b1233db73836c4e6ac1cac0090b5c3a7f4b51db9de5d1734c631f49c18ded45dc2652548a659f19baa99a63d62f5cd9608b8661cf7fc88ec0ade0d13568d8cc4091e07c7d9d8544b4b521e616ef141187ddcb9f4caaec7be8d90cb66ec8ac2f78a19c48f7d18b55d596b7e6aeec7c3ec1222fad3d5bea16033b6ea9ff30f94e97d661e922ed23bfb9557fb1742bc36dca6b202f9218b2ff870b64c7aff4acd74513fcb8b1d456c917adcc57a88b77c978093edbdf8a5d4cbca0319f731c8b61253a77077ac2d575cc29c65290174ab6bf04860b8168737dfc9102903df24368f1f7b2e178eb3a0867537fbf301dd75b00070e5715cbbbef5f1164c30a0acaf78ea75b958af893f4cf76def228bc6ab77bb89d7977d26dd07a957c35321ebeeeb8e8b784947a4c5c44c85ee3dfbbcf8cd429f2cdc161c5203aab4b572b63f2e40759197311856661a94e1cc9cd9aca266af0489cfcbdd653a6ca84cd1b70175bd6ce932840f5f9dfba39dcca3b15b8bcc9d7a077cf38b4e43c2d0579de4186a7db488367c2afd8cc8732d7b3dde96a334335804c0bba48fd0465286160129e4481274a79aa46b54e93c2e6b557fb2d2e72de5f0f92079de6b46cbe80af70ddc05dbf944d01ef405129b75cfae13b113425d8444715edfb667ef8228415d7cecb2402405401583d9a714aaa3b8afb9b9b1626e82f85bd8d23c1677f9be212935ca19d341b726495f50d178a17db767ee7b105b922361938e6ef2420cf5572ab2cde3a05894170bb10df9a35a2e5a0d9d5a9078f169825924259a9ddd8cf0b7284105c4ac8453aea54056c6ace84413998ee6af9e2d8cdfe06af335164e90275613a357765f1c55c718d037941820d837b766264d093bbfdc7b703e589a9db324df79612fcef727e912acd2fbc12c395e98c7d8b1278d5a3facfb2093ba0a2cda2da673c300c8747da11574389142f859a588005ddb716964efe42cab10f97dd4a04a3260a5a6026825e1129294e92e7f63388d2923e31d8fc74a34a0a42857e41f811d3c74131ab73ceeba63417c3b902d4b962a476d8c8323527f6af03dd7aa2add82d9e5d21d4bd3b63f8d5508cc8ccd55c07a3e10328ba0c51bcbb616b001141ad6ccff3f3a52ae6bd1fd4ca26c6d2c219c7bf9e79d7a2e3c7ba9257c7b5092002ecd22082564eb9dc786681fe513752b2064882ce7dd52c19c32984ee445399c00e09bd31682a5f0d7b8268c65436ba0d4356018998a8dc55b108c85c25e42587866757b4341222cb7008dfdcfb23e80fe0352dff5687b3b98ef8289650de50556b045ccd304befccdb98564b82a096291f8cdf2760984f3a5290a44e3871e8295d4ce30812799d74142d12bd245dcf315f4b211384f454e489e87a80855f5edc06f7ba2ebd1219103f1ae4c0ece8e9e7b86b196566358b05cc4df733a2ca3e5cab2fdc14807f1aee61f8988252b09f975d591c82c0db757b294e16594f050824badd4fdc72bda7cc0988fd65817435a9cfc5ecf0ae843a427087ab7c2fe99ff5d4f65861a8bb8355a059593c638fecbf1e3a826ecba88b6706a738c63869960964139c3d0270f6aeb4a99ebbb0167d39f4efcbc8d84c7b0935899900a22b627eb81ea21dabe8162c59ef159e27d7df1fc13d46305e063c08e38fa1a2f902cf4a1ef9a9283f950a2b9ce2ef5120a77f313e7e5b123c64f0262a11e2327d243d216cc9c58fb1ef7b3994793308c3bd16c10a0d18170e663db168a09583b91ff6e79fed89629b3d856c6602382e5409d99925aa9c119ed429896044003f6012d99094afd538de684beba6b7652791a8a5cf3cc39ca1b042183b72a4339e9ae4c3196da559cc8660297bf7c499e329fb91e7279aa905c9257458f8b6d393ccb510c8b509b941841e1961a04bd5ae7bdad1b7132039f8d7582d268021d3a9ed91be2b17950d7a099dfe963834521e13ec9a009ef037c908b8fd40e854dd14a69eb2352ff34b3fc44cdd4cfdc9b2068c69794998649b60252d9ec53ce26c30323a7be0a1d9d2e8dcc9241d66c4f8baa1878a66b4c3d20318f7cb8119a5a146e839291b1a2dfb1c458b63f01f802ebb396276b7631605d285d631b0245bbb3efd7c7e23feb5c8456d6cee8430299591b9e3b0aafeae5fb0349ee5408ea192cbb605ca9957d1edeb73c077b7f08c421c4156c966017978faa5301bfeb8174e71731e1e08101ae94f23449880823d054c3666ee2df0d44641641d218e3c297868bb7b60d9d0a92abf6f012d403850546b74f4f85c1a0b4216084a12aee858dcb42edffbac874d5913fc4c19c893c06c9afb179fea443106df3a19bee90a03da1acb91ce8bb69102d4fa1c5c32eb3bbc478b459ab40428ea0d9c4381b988e037b5714621a2c733015a3240eb88844075a1807ab8be0318244ee29076f71d9f8a70c88e30f36c992efc24cf97666adf3d19bea51ee0ec446856ea36020bab08b7a543c33ac54794be993443b9eb60dfd9e55a112f64bd2ea993a220a46dca03c0d79634f6c63396940b1e7b052747d1651306971e7ef68338af2c5dddbcb20bab86bba3c2b43348c31284d9b759c7a62251a47203ade31ce59a9ad379f21f9b8279d35140f3b8c1b02a0fb61d1c10f7f5f8cf8fd72dbf29fe5c51026a557d536d2eeb105b53aea8897aa7a6f0670429f948c44e550a0d914072b73a8014b2010a6188e915f83981895bd3f5a0a3493aa1dc054fbd7f9d990dbefee196519f2ca6883d1118b85ebf42c4c50b655a7201d13516671a134d50284bff0ad0bdb09a642f3c149d889eb587d73424b1a32debfac2e237cc88176630518141aa95eff800710bbe87ba9ddfbb24defd95f2b706d96acb173bdb27c42d9b5a0198b2eabbc80641676ba36470a070db368460d3923af702771e00ec74270081b3a0bd4e043147b9479bab7ffc6c287bb0f5995a3a23f49393ee0dc99d4f9c6368b10a22322cc73741c13e90ad22260bb6e01ca9849e002338e225d1603c0f31949bc406f8a9f5594225739d39227158c362c3708b0ae5132b2224e2d300ee728f9917ced6901cac10590fedea57360968d08e0134e50abe98d3a12acfd393e93a526b6d6cdd88673aabfe7bdec8abd88bd6d07db79c2025e19661fbf91cfaf830f763b38f52a7448f1398926105ba8e4df2ec3e8b5089a60e6be3b649181c949eb2f9852670ad6ab8a9b538aa4b69d0ef48b3b10b06dbc8723b837ccb1d522a7ae506a04b72f50cfa0d8029744da6d3633f95df991d2dfe04842c66a06639cd166f741b5d9d5c794fe3761022f13ccda325af6e7a574a012bc766bd3f88ff20248afee366c2787572fd475d9f2a9ece7994603213016e52f93b13429d82d26d13b2bc0b584a4b19a5a664cc0bc5772d40f77cb956666e67125ffa396f8927a77bd2512bfec6ce210515b81ed8f56b4be8b677895b7e98d3ce2eb7959aceeb05926b0b2cf7c47c32c93cdd464445b4983eaab69ced1c1e33e60aebf28cec6e2f957aa635516e881ee6ef78862e828859161a6f2cedba7422d1f6b35d7c0e6be66e29510698b73d202c52dd1e043800fc32ef58e5b08312f240765450dec88fec10d5131b04d83cad60f921ebd85b7379cc879a4f33ff23ccedbc7787005f55e0cf19c39af55315289af8ae296630e85ffb7b3df5583ef8616a39011bf9e3008e02148d589c904ab567674b2c46ab30be054f9ae23201323e58848f789ee48d6d5f335941c3bc54de838887327dbd702d2bf7fa861dc1421bf8e76bbb4adf1207a43a155ed98cfbcee1cd6cebaf351d124c1bc1179d3eadcfde0f22a88c8989aa9db91cb79d54171d796877822c3bc2e1562a2443edb6ab0a2a7f37a14e76b028a6590d4eb80c30ccfb5bc114b4c4153b94e122fe565db7be43655d8b88053aec5eb9e2f65bdb00574971e4b59cfbe40db65204821fc04df783278f6e99e77e3888ea5591bbce12810546d759d278f5c90ff46e33d3f2ca3651533e0122c5e4135590d486ba75d4c6c8013cbeae0786b06c4aac200f828c8a6961c6cd8b538a82717996fe49da94f8233ad294faf9c3b24ac6737ac755b44be07c2fc96f6b688663dde191507238f2bceac46760f726fae51697c06e7ed9b5ce2cdb499388067a40388f59f7d87e37cb9053921ca5a26ac03b1f533367da375c4a86d21d7249a66257a9f6bfe3ddc0c35af0d945d7863fef070007f71c151e1e22bdfd4494841a7f405a87fe6214276c71bac5a6f959e7439650973e4072467a063cd51174a4373ee278e1eedc3b0525b8ba74abbe0a51bd950ee7a0b7f58503537e2931561179fd81f6620d96d05a1ce12a9588bd09bcbd0adba6a3b836432dd3950c29c582df42872e21225f9ac6c24cc0cc81add0518f518b0745207957b9fd8d4f974dbf1367bdfe6a757b33d6a5507c9ae0bd8483e4a5333d164d88fb4bba5d5280b4fed5edaeefcb198ff614ce7a3cb765dfd6a339b1d1a97f9a3e030d8c540eb64322bdfd77ab8493c5b1804716a94e973faa764e88fc59f9557ff259c8cdcebc62c6630904b0baab372ed174ebc92128aa5f1a316defeeb9768d8953f195a8a08e29185c56dd5624f975ba1c500d9e21e82ba46343579b241998baecd1d9d840bd48f094573a6064612bb4cf730c76199051b14fa2d882af6c2bccfc70d068deb1c24dc1fc5ced0c4f967b5b58408d1e0475d7cfec7395c6db77ef08abb88f7bf2aba975dd7f733362a3b61a1dd84d0af2fc069d688b404d460a4661767b7c6e6ba056ab141ffd59e5a39bb96a6adb350989016f8c6d3dbcabffc3958cd035aeedafbb0f1e6976eaf42cbd8110a3dd8b6871779a9b4d39618158b0876567b3306c12a1027ef9a5c4cf74f486c6e4d4f808d4656625e7c05754a54b499ff679b9a9e37d376f67b15f10001fe2faf3fd9f89a8df44ac7bfa64a7901fefc5a4232201eaf8d61ffd33814e7012e51a7bb1847a35849f522a00889dfb618038d4a35bca21f6a1292a921e0e7c6b87b77a73d00585df2a559aa3061a851f40c4d2d9af5e398a792f09bdd8b72dc03b4f648cd2b31ddc8610fda382040e8a8262ef3100d158888fbb2aca235482c1fd05fbf5f15ed8ee0e39bd643f3fd0963e77669a72f86f04157134a56a59404fccb4f288cdb5dd6182523db42524102b46662d011f34240237a017dfa56f857e732c8071e6ed4d9abf67ecee7a78162ad46393da94945bb9e91291b15d63871848a79122f652cd1311b5fb1d6e0d80b47c27e9179e7fc00651a8a4573a71ec348fa120d90f27041cfac1a3c3df5ca7fadd77b0c1f64f6bc62af40f5e47eabe93e4cbe0e25442b0043e3f55b12fbbef210827b03518f8401cf9f7d2090fe9c889bacf0c3b35bdcdda4e22a0c098a72fe06fada48220109f57d30a56a498c6b5060629f5c0859d98a5a6735067cca06c44e9351d531a26362006264bfc8c1bceec9111b157d582abcef55cb9be5241628dd22bbb92931ab09409f9d5e04f90250f9b4f16c648781d4abdc988716255429a068798c64497d20b22d0e380afe29ba2ffe570c9f2509c434964869e4800366b89bbd3950233276fb561e940276338d5f485953b494c32509e14b7b584002c889fc6cc68a92f262498fe9ec3288d2eea7a4288377af78e6f29a8e2f68501a57d0d9cdb246eaf32240cea76f93145b24a11289e0a143346f4f09285e8cb6d64799a83b307f8ff50d83c2de70e4d73ec80fa8bd6f689e53e57a6f6e5dad847d0c0a1168eaa546215fc45ecc8662427a15e44c356809791542719226eb21977f46c680c0bdef68f167b67af47b7d8bc8128e0d5b1a28e854d252f5b20b081af2a86369a710518a754092d1a3330205341c31279a96fe04a60c9abe2b97d9b953978cc7a12f30d2a0226f8898f7807285da2268f78cab075cba6b367af136caf5024d717a5cbd15f99e441c3afeed3c6f92130c2960ba487250a1538e7e1aeff17ae4451a27d51bc6943a6b1f56f41b27a56c8914944ea48cab098496f35ea1b8d44aa81615db4328fd9aafd9488c5fee59d2046401312dd60b3efebfd18f8f156168025c9a1bd64bd79303716913f754b8f8ed156f617c0bb6c28e83998f2414b0a0daee0f4ee3b0ca936616c638f3022ca543508ab108d4bbd342cc4845def43cb89beea0106eb8d748b6cf4c95c017e4c4a3ac25d17df8f525dcf903650e8eddf931554b6de7544e8f751ed159c2e2f5b82ac46240f60867cf508df4a693813f89ca9d0dc54851e27491527c16f83e5249e4b3f22c2433080ef379b5bcfdd5cbf44648dd9559b52a95dbf395aaec5ab17a56f213c2c69c2bed246f161dc1cda431d606573ddd67de005b2c9dd71c9d1a8f2da9bb7d928d76431b95f3e60fffc6c8a52f4c534489db616f207aef8ace4b05e8267287cc63357e603e2c377b98e2470a7f23c7fe7e86e80df2c4768e64ea4952c696606c15cb24cbc32a69866c524166c55d0f81e3e46fca39bd4e5651eb01c90935ab000ffad5d6735e85005b80a4cd24214a5d6018ea4b858a2e745c7552d999ee40dee0df7ef9a01208c0094b1794871dfb90ae984ab469038802991a76687e68800a764ff3123b3f0da7a4fca4540b379c45a779a0aa9f935336a453f87ec801d8b00063867ba8be5487ba668bc881a6a704154756625499248912dd347e642bfc949f7e801b158a3444cd9f06473cdc06faa139a002c3551667f22136dde5ea14fd273509d0ea69e2a14712b6f151357c87d1c558c75586f548c7b871d780a425c14ef869e8816993695663e226573700d9006aa4f4535aa75505f2a144e2ed4134376485125184b1f73a9da58a34b12226c12265a0ee0b4ccf682c1b3779af32bae8be28c10822e4a027948ac60f2b20d974c32afcafe314563a939ad2d1a6bdd1553685e0ea359defa12224e5eac09504edc2f99e3290860633f9e4b63bd8f6e6aadc1ef4cba681aaf996ec242c3519e4a2fd64d78c9c8de488e96853f347dbe9ccd45899765898c7b2e59ad29ce60d2b43c5309fb2a70446e1c0e13ce58bd58ec20a69911d7655e984ae43f120684b0f702d870c6a92c349d949e9b39fde5c9b62978d4eb8a43f6bd41a996b60af63218ae4403cf764210cbef154efdcf6df34debd58f1b66ea750079f0a97b9368e0a360d92df70e09365714acf2114971e912dd5777d1ccbf2d2a83d5c038001846bb18837b74ce525150e30bc0b079a353eb1b27183372b1ac0be01fa3e7cabd34f92318d3fb5d33e6e8936787da645c29c41fb3cc03a235a85dc4bcfd6b4e98073ba2d51f14a70b65f5e62bc007e76d90b3eb086e91b6bde38fdbe70fde2dde1272cc665b4677ff6f5b6da432aa221ae4217aa11be315f9391895f8c17ffacef7630d64537896d79abe4731db3dc2af978b478f43bc7bae44e06b61f9a528035598837062f7807e51108822fce16e1727566768a157565b7369c6151113804459f7495c46648bcebab6d8e187149d98a2e3360a0ecbfc0b607ac48160418bbcc1864f2845f26712844c931945e73fd3c819ddb145163bc851ce598770d4fc1f1f298d2f32d76709df7142bf3f29c5697e7c421b0baa043de67baa9e14043062b53ac425091b395a975447678fd136746f08f592427478487c1e99e52e9c75c2d362938bb478333b6a3a60d518f8f15222cc17690396145d0d6f8cff859aeb94371b12cbc0dbafe8e7be138020143c1444d0211f3aea1f861ef1922d8a15380ba9b46e141255c15e9e4aa08238d9039812855e3ac7bc5e9bb84dbd3016c94430de1a0d53ca5ce8c135db3fffe2a53e44e1b0f29b629bb4f52fea7c0ad3dcb59a72b569a43bfa804e05d07c20b7813f1902fd2b07983cf9a13fa8655fcfd937344779f21d62651b891d95ec9520a409d2eac6d3d22466c8be96b65512de6fa4f6bc0b50b6e6c48394bfbc4362d3334812f328ab4fb6b372949f6a89a23f8b2cf6a1e5447f9e9a8854f462853215981056e5ac11ad9384ee58cc6e3b0c79b72c800288a01ec4a0172092cba8cdf5df0787ebbb0830296ceb513f491f2cee7e01c5744800d66a7436f01106966c5d9ae21142efa1c065c260d18fafb302f3d46fd7a010c6c546318021e1ea4167b89c43689bb7ecd0e6f6cab5fc5fdc489233b6ca24a210eca212d9245d1edb0b80df7ea805d6564a3ba0271283dc611e72cabadc61848cbbedacfc66a08d84716c35080f97988d217223aca933289717ac1cb605a80f7e692225504f8951b3bb4bd4cb2a7f62459bf2b7c976f4044fcce3a76ac1f7d4bdc5bb0b6c5c2976fc84b5e1047cc41ba48093ccd7b6b23b43ab8812d90dad273891877f558444037165d04f67b00027340f337e0ffd68836ef72be029b6b089f8ac86f46f9403b40cc267b7edc5e2ddb7815bb72bc220bb09cf91bd00828a0c3cb79d11b50e9dfed861d15e38b6341957f32f5f19222a18435d9d02bd3eea26b622a74bea261164a8130d977000d9f7b855c4ac05f6d50d43b79336d5bf7ebccbc5fc42f9d5049035f92e095fef308da00045dd39c8ff63005e488b29f6f7683210412896e631445f1d7fced33075cd402215a67d31767fb5c0eb2edf1df30dfdf6b73c85b3ce93cab4ca9be8c67d9214073e821d9ba578f059ea87c4f921e4fb7e69110ecad840ea011e9bef87ad8de6eea178256ba846b0916e1eb12b724e04014598780899cad7fadd7505c3e55d10919c0e0613af22f526e42ffe9b8d149ed9b1b003587d2f46038100cb3f93b4f2eb618df9f49af6e4f322183db85644a1bd13f333c94d7b4a05745cbdd8ca45a613c6f6708a0d7d0ed603b03f98e95f33a923d2909804c77dbce2aad0e329603fb034ae7ecca9e006104d4650b3cd5f81886f219344af5d823712042a726a88b301d5784d40c67f20f8b1b2a8e4c93dfd5496581505204cb7fabc772f393bb4c25117b5f322247d585cad46044c9c3069904cf25f91af792840dc898a0e8c83df7039bb17c433d929a5919a80b974c4b1823d9140094c82cdc17a800ab6c1c85127f9b7b9accab494194f216763c21c1e1297dacf22fc8f2f8154a9acbb2f662d032964aad0c98de9320da00a936efcba3c934657f2903ba410718864d78d13fc9014307a74d05cdd6d77ca055831f94905073b51dcf0b571360728311f78ea3cdd3ac35dcbe453e28906f9dea726dc6181ef81eb513c993ac531138935a3c10856c9418accfb0314997413689337e22407cd0a4a188778d25a5b557e141cfd5cbd13f5d9dd114be4df070bb01dd30377ef16675defaa5b2634d0f9f97987d9a33c5167e3cf8226c9c2f57baa730d3ea8b3be75ff9c7f51929643a770c87150365b7a15bdad94f72a526ead36c52e26fff75dbb967b9eaa1161746e80c62192cec76a7d5538b65f15af7580513134284d11eaebc2c83f319e5475980b605d152f8b5c0a34be43317ef664f4f00841135a93f1336bc9240fe752d4564ab1d83bdb21aa396d925df00975963088900745b080a8f6ac7217839cc4c8bd65e9e862160a12dc36bed1a7e0191399839c92099c85cc943a8474c0e4f0bf8ea04a10b36bb9e65460cd9306dd48258cd62805136a6dd0b5cbb9def29852689e3b7aaccb20cc32d14225f67be7ec94a1b739ea941455cf04b96931dd1d410387b557f9949b18da4ca7531d311c75b5551b744f20181513e250034d67b528ef99023d58a2431a8e0ac195c3b38c6731b279eab0bda61e37c29974c14ef036c25629c674eededc587df5bbd40529f3ef9b98b7f889ff056904943b07b805479bb1c6714dc8fa83c87a16091107cc1f4a3cb187f15c074e071d96b3f5fac79af477aa3b8b1a8691cfce9784a0bd73eb8bbf9d8b881e44fcf9e8a86f1167a97bc54d2a7f7b447398e33be97fd2ece3f8ced7c835f2aa344dd2a74f6ec88b2b6e177875c74562ab6567182bfa4abeac052b6afd7ab7bdd2fc8d364a87afb6efefd2d7eb26227de664942bb6b6f0191c4df8ed93d3e5d5c1932b08f6234e3a62e1ed49ff07ab498e3417b7920e17eaddf159a7417e6ff63cb6f39eff3d4ff5ca89a21120611c5677c2c0efa2b78ed6b35a444797dcaae8539c45a2c83c843dcfc35f833f10091418bced14e3eb7fe4c7d2baec7ade52b2ea1ed93f351bfe02d4389f51ffede91f5c33f66eb2693d0e98bb59581da7cbe951747105682d232e78f46f578303436c2c6c078afcab31957af13d60c4c31155cc97894273366230e0bedf8963a423d48313e250b80270d828ffa5cc9b50a708a4be5bc2f0318b80d5fb5de2d8425d5de2dd5b90eb5127a8c2c9956388391387954b1047aa056b6c94b13bffced9075ab059ee96ab4614bdf341e80abd4efc7d122f28787ca53ccec0011deaaa704ccd2c4215347cc34da525b4f937188dbdd137df599754d246648e0bc791d0cb215ed9e88f70246779b7db2985270a09812a0c40d4fb92522b8b2155ef3f5fd4678bbd58767fb7d7a5a7b39bbbc7be735d04f61887bdda5492d3a9d645ad176b47cea41a26b120bf9e2c9f79c5d0faa7a164d383852d3fb7ae5171d8eb4f77898f1c82d1a244a3e2aedf7932d4588f267d9b10b85fa06dcc4473a8ddf1614b88445a2aca1cf7e9e9706bd5aeb9b000a0434fc835404421a97a938dd017a82c1826410b590f457b284bc1fe4de550c692b20a31223dcaf1447f70528630b14a19b85d4fb48458f75ca34b478435fb83e13edd79c1eec1de17313c867bf4e00b61b56f633540552c6f0b9ed45230eeccc4921719c470768c45e48c209bc6fb6bd4c38afad91fdbe308fdb24a5df4b28d739902a4a7094286fc968438657e99b1d7b621f0c7affddaf1c1938f18db5ab59907114e60c06a24b861be315bd0d15f5292d0d9ef43215a895f00bdb1caef75b614839221d5445966ac0d030d9a4233b4156d8f0e83aa7860ac7967e167b21bbd7586e4965ac9e6a4e650b0d9aedb944d9862afffc270b5c6792c84761ff155047291402ebfb7d26b906b65c371e07a4a065cca6f8bb7f1d4183244c0c606bdc9ce633cded1cceb6347b3670433a942f2c18a877c536f775072677e25ba9cb2dfe0642d7cf8a9db7d628a69e15d4c15a28e034c8a3f734046b3d09c57e364b0ec4b2ad7bc36dda91f0ae51b0545a1a8efc67d5c13936358bfa6971c14239db16d21aef2944785371bf53c47669fa39a30ab98865b0b007c6eb1095dbedc267a820ba9e56cc3b9ef24f7a440ea970e0899b57ea5258c43b2b4dc02ae620ff65f0c48cf0c044bd330fe86e80089976599c3d91aca0a6a08f5f33df86c8e10abd7ecc1850b3e7fb7946f2dc763d6fb362db58a970cb7dd82e9aa6b81f0fc2f873a204bd35b6d1fb8bd43cb79cce8c6590e1c19e14154b2becb426cb685a6b0b98ef9e56167374979120fc4493a4275863c52bc41033175cf4e94aaa6944722114712cf0f6a571e31cd8144866aa2602879659a307b675f0e5793877b32b6d6db7a2db3058b1471cd270fd99ac88cfc09996f18dda4f9bd73d08cc72d39d8e54bbef4509a2f758cff232611f0474e336a6c42ef9779de2adf6c8361048a39cff98ac3eb37ffddfff2e68d8f1387678d839be716c4af8abc66012702f504edd87b227dfcd4dad71c1edc236beb3308d4a237c990697e194a0aed0f8ec71c140e90540bada5e1c19629d76126b2c858ab6370914598e68c71b026865df9d6043d2c591a2fafa927212b69666cf539a47b3906747d9feac5fc6e91621454b08c0fdb43ed0c0899268e16597986216fc83c79e1b266cad42b32d324a0fbfcd501ec044b6fd181f3e7142969996d0b7f93e6149955e0b9309fbc3f0a4d70a1ae6389c6688453b4c4f2a85e85bd0130ffc169b8583d694d565e58330d125b22d0d961c8638919991084f6d9e96fad1cd844977596160083fe7814ea6d4456389982b24a0ce6a39e5df2c53d1f7162c93d8335bad25b36898ead329848e9b6c5325d4a8583bb3ff00495d4f138f7733816b208edbcabf7a5543fa1764a27995129494895d02de29a10f12db1a7c950de8d31c2a86149c1e0396430a1658ca220a6755333f9178b21af295fcc8f5474e081d83e47975d77374b325f68d8e276672783ef168238e7683c8222e1aa601108ac7edf415980faa1e9f9820dba28d4403e2d78767564a3231241206ca6d12496f30314253b19a1a477e314a16dc8c0223b60ed823606d2a0638b19178a8ae690bdae60c403c76e46d8c97b1e010a485c9f062f0cc4b88deaeacde714e84306296eb837140a8785f9dc6acbb879de001f2517801d7e0ece131774fbb692932c2c92be824928adf23c24a68e7240bad554aa12a44fd5d4efed2d96b4766b4902bb57ec0afe0fab1a2ee770b191efe87395fee284ed376ca7aab68ab2370a6b52e49e10614dea151465a99fd761f89f31392da2d55ee5675918b0c1b0493a83970e6238965149d3bf6d3c16bc093863db6e293f31678f18073938584531608ed6e5a1b11c3b00228af7def4593494e9b00bdb3390c955554a6874267852b4b3d5eb5547fea55f2f77f868bae4ff4b505913147da4f4aa125540f128f9cc9b2e557583e0b1511cd3d8d1a96ad4b6c5d90629780f618e6503356159ea1121702eacddf6094079bef8e1c792cf95fa2822cc46909bc4e6c2c70d4c0b1075e4d9aeaca18d2422c1bc5033c84a2f2911dd956b7298c26f1f17f41b0ec0ffdfa1b8dbde474d647b59ea60903f00c33b44a6d190f388bea577c344c753b47766327b9f7bcdb80bbdfd5b309ec5ae66917998478a3c116f60c389e00b380f9b6a80ba3ab5982be8ccef39e30c396517050890d877c72f816e541d00a7d7c070bdda59408ffd23875ec2a0ab036e8bb7090b7c7e08e83d32924d33d4ead57010e4024df5fe4b02961ca44117c246cb442071c95f664ce7692e4be280d625adc9d3ff73b846a6bd0c8f73ae0a417ee7204433b5f92bda4c93902e46d6349945a86ce54c2b3b96f3ece4d505d971c0d73bae610f82c6f3d7d61a3fb468b8386299edf0f5c7ff3bd3766bcbbc8ab09195a66ec34c41c251ebe3460aa3c1eda404d33d5e910ca065b363b8e5de961ba3ba00d74dd0d5943f23b1c55d2a45e657e9c63833c2ac3e5e80591770503957c9e2ecf8dea6bd3d2c56515a273ec8994cfea9b2a9cc8c27b764d3d230c9af37f03d5ab0a57fec6cf4913418d66a8a92629d34183be83f700749106a22c193416030072c9cd52656c8a15dce2bd12ad638d1d9148861aa9df8aa1b57996af1bd945e52379a333d1702b3ee9bd5e73e993ea99ca998aef496b4b1d2297d329490ad0773e89f5ab38c9f31ebd7d136ddc87f4183374e182d6dc633f9f28de847ba364213c905f323dc221ee8f060e99fb33be1d767afdaf25b084b012850a0c6117e2ad7dc803806a5d2a983bbd3b2a23c0199cca25af2b66dd9f4780f617aed3e8fd8f1b9d73ac8f59415db5e97f14c204f710ca44e42139bd39eb3971e13e9de3f48772220b2f1cc517abe155643f8ddce3bf437dbd5184655cd8f737047e88301ce1587d069dd7f0521e476f29a9856def84c282c3f87103e0a51b9dc997cda9e24890a496869e1c444626470ddef2dadc6a5a2bada4ad2b7d2cfaa7d539c6c738ccf82df2b1627c28e9d729e49ab071459e1fdc2cff09cf47bb8a77c2d7375ba2ca98aac738f18a55b372b122eb19dc42d29aa356fe18e0ece19ad052083ead5f1a17e996a40ecad1a68e683fc9b419b27d8c00439a1448d8482e1029e6302b525070b7b67b4e7aaf3cc6b9ce703c04671c52c98689b35ffeba2aefbb6d6279cd0b6dcc88b9180d2a8e0a663e451ce733850a38dbb278ba4fe9482b2508d9eb164fd37ef25964e9ea7fbc8446b6c4346d51eb234b08cc5fb4e57d49f737b9b6119e051c1b0ba3d6c19c40ce64b68ac04fc9f8a97ef972ebaa0ccf017399af2e0815d518b8ecb4d19ed7db30e99dd62064b136f2d96e66edfc55fa20f1cb3cb70a12868ee1e5c17722654c15e74da7641728005b2a138e9f4b930668ab5163d05081f18290e766d24a4e34609d8b235a4d420dd1b54bb58d90e3b8f4682250b8f4f66c1ddd8dad6cd992f6bf1854a8bfc3a72207c95dcdaccbd2a971d28ff0cf690387235f7203a1ed4febc7e8a69e4e73b58bb264b7c010139df84c80f6c8b63dd277d0ecbcfd8ff93d66d66583d29f778b81aed1c11092868a1bc72e4634889b65040830362cd2773fd2efc38bc9457c8c75bbd110a079130f38d0057fba390e750dbdcaa18ab8fcc679664cfb0345eeda3b2f90f2655e8592b95426e1a91c2a00b1e91e1478d618c3a75343489e00789b311aafd4989291a0f95b05b6c642e42eceb6be82e3df95e1b1725db9c3dc5d4206686cf390f1875bcca454b5118277196222cdf04c5d8cb1c8a23f35844aa329ac10753d02dda2ec5f2b0b6283c4c91125f2b64c9ccc000ed29f756128551caf52368aeca6465afa203550640fad21c79714a3d0704a13e2bec7a89efb63c57664343a3192d43caa2f04e49ee2022e85bce5bd810358fbf90487e8d4011227c199a9c483066e4fb317dd8af46c6187e55b70762e63bdae226802d20f3ba3f6055e197465aefa6537acd2c0dc78c0aebbdb2d4e8b34ff00070e12ffca9748dfc6764482b1f0937080e4111de8b9a400e03590c3ba718e1fb7568d627b16bb52603751f80af05a79024ffeadcb24879fa013d7210ec6b5985e63ece346c5e7ce9713fc40bba189d7cff44e5e228a01952785593b31469b3269f483e48a30f1d0ef2ca75aa2fc2b4ccf56fbc90df8ea4cde65494e49aa01748521a6763926ac71b1ec8c26f66b06fbda6e8b43e43bb8368588bc61ed09c5efa72b309ba37076c0a0a4e1b04ae2fa4c2140eebbf19953639284b67cfe6ee3e0ef1c82f154431071650620dfef846d2bad030e6624b8392fb2e55cb192c43d2f0e373f7c694d1416a3350ad63f58858e5935823efb44ec484c5db24c452080a90cb24c7bc9ec20851b4c1ab90edee04e973809be5f748cef2f0758cf95ba89a71ba13d27f13f2f1db1885a56447fb79e260c56b8131905e9cc36ca676df6b4f7ed31b0f3f7413da720b83161994d5137459b0a6d6f2193ef3717cd14bd349f8c9c873fd594e7c03543139071053086089904502e0e9a41eb1f7f5daea68212ea0d6e9e42e04c0542ec969c7631ba49f3e443aa5c7ea96c40c60bc2b175abbed4e0ceca35945210f22d773b15009d9f5a616dd92946eda518b4ea9094c22157bbe71d4b0371c88e8e9dc0a79fcd14e4ca484f1eb7521c0aee2053d83f0b47864252ee1e983dc92bf798490fb7f2149d5733ce3db3fea3c905ceda983833cc07f319e20eadc69351407965adeb381ba45d80d414d21fdef32d062233d4b1cea905ce29676e99cc79dcc002e70d380e60f388d51acad0c5f778107c23e500d47371c9ca5e596ecd715ec4baf0d630a23a4153af80891a4e3b4cea2342969a125457135710796961fbec09a93075171ca2a98ce2391f02d5c4bbecb530930aa5671ff732d6d330d42eb82dba70d7bd5799b888026d53c5ab0a5d63c97ebe2ee2ac6a7bf3d85c8bb84d481306364d7401f76ed5e040500b462780616bfeb441ede9055bab0e410d2f676e68d346a4e5297b8d3ed0d239ab155728d5e67fe5d722154bc1cdc60f8597d7799987c0b1021a4c82c9f826b7a7e0586079f36d3c184be6796956aeeeafc66a0e99fedf0b6fb5de52c42de6fdc1e6d5c013a43ed71be613ff6fcfbb2164dd16d0c0765cfa9319d7fd0382792d3eaa2f2fe778e949d62a8a1c9aecdfdee82baaffa125b5522a0ed833d06b20aaed71f446628125747db601d03c7314140f8aa2005e64314f522ac6d7c82e36f2a6265467827e2935ed017e610229c13b575f42b2866658a6c36374b975135a37e9fbe7db4404ebf810ef7066f7c62ac1cd8c8ff3c15805370bf3510f2fbc87b34b4c557b11db1804422f332fccbecf0c39fe8571a2be6f35692121d960c8d8bd8b76e2b2430c9990b4f818fdd60b00337ca18d4138dabc61a40d575ef55510215882ab47bcaa44d5a993a16da446173d044a06e9511c83c2dcb63fe08db0127759b4cdb011cf1cc5d68f902cad88424948ab067009ac9bc3ebb62151e3b9a5ef92c99243f1d795d8407f7de18354da2b8c9b7349cda0487e7118927ff53b2dcc54a776222d502092cf93c12ca50910cae16bc8d57bd42b489d87865961a7f769bd325c4a068c36be9505e65500e453d827ec9b6effe16901479d78b74a816df89abc9ca93ce477c3af117fb5975bb11deaf0fec06cef16b86b68ca3f13f7a60b1e4929178d35f5e645def10791c560c8f064e3b8c3bc01ca74bd809ea5b74dc685b42cd0bc8b3994778cd912511cd0850069afa8d23162dc8609c82743ffcec06969408df0452437deb35614db518556999ffdaa311586cf7173c55ab77db58570168c273b829072819ba2c2ae355484aa6fbcdf5a553bcaaf183d194fd8c6ce51df58e0e7746272561ab3478b01145c5dd6a3746551e69a5cb75361dbd184a6fe3b65f92bbba6988cacf130407e37c99c6d57fc276eff14c40b3045862e63e63b5b9fe81f583f58d03d02ea1ba19c849d429aa79787a56ce6e7a86322535aff634a644d359889f0475f8e6b79800471304cbab32f0f3ebb733b325f5edb8da95df78ef6ceed92377486a88ec81b0c37257ca3cd9fc769f23088c3ba4cd3605f77ba308e97f7fa6766dd4603c7738c356e1d7b36f56d41f3c25a083e72dfd969a852fc190891a74214349fb69562ffb68b36aa231915512658c3ac9f2a2c1377712b50cbcbfe52403268c1f401a565a0641c7bb1ced2b6fdc09e4cc722ad83a687eb995598f8af59720d3fa01bc85b4833563f096a0caa683741f4cbfde885dd89fb7b20aa2d7024987bd188e5416825301d86123bc0ef39135c7a3f0e28dad8de98f4e02f0240554d25b5ca6bd76bb6225fa5a08e49244dc9988be5d1965fbef9e94495a6747298d7f33b9b8a84e2a4c9ef6af4b802acac18526987619e09ce86e900b64e83d96ddc3ff6cd375ffdc58c9f346cfe26d2f7b48563c37796df6593b274ffa3dc35a4dba545f20ecd6b2e4874bc55bcda23ef12f39c2d1e7ae8015193df44460618157465b60f6c1c2c0fa5046920504bdc10ed654508c4bee9e00bbd325f6d5deed02c32a53f3296e5654372cee007721f13b916e43657b06bfa66ea1eec0e2afdbe0707a064bb731f5e5802ce3900d8c0603d1eb5ca11bebcafa0bdfd3ce04ddae776707f916b27e8224557f806e17745ae9df26b413d83013ca511e96027fec11412de148d4b673ceb0c5df0d8812c13890d2e3cb10ebd460f9c620e1a354d58a36fa9dd6218ed939b02cb23cc04b087a7d4aa6d601d36f2e6e1a03e5f497c969e1744af136b51761eb3423f91c20b35b9f02bfe6d0fc2af37f68aa7a494d86118295b40236dddfa892dae337cdd2bf1cb1e085deee0d256d723d979fc74fbb7bfd8eb2a2eb4364ce95c63f5b742fb20ff7992cef6f2a22defb1f747959718a0269faea870ab64408df838c4c3edc618e18af691445f64fc382f84bee2f8b46b6285669de8a5178fcbeae44cde5affd52197f54c8ccfcc8468a53f1d66024a870b6c71664584f600e83029839cb8284bb774019a173665ed29f11cebaa0b387c074d6803c6e52bf083a5d2a0715f7f2d370baff7b35de4f753582daf8c247962b1c85ffad6c891ad7d2d0e22daea491500a4cd5a0cb525ac656598dc4c18f8e27eb90f719f8c3f6e7844d2a477767f7b869ff1045f0e6e938810d02a1bc4103d7d8cc204e075e65c47881b10398a570b50961b4cfdac2769c6ac3d388ed4cfacfe9587e5c4e209549684760b9f7d78afd8fcf98ec27b63885ffd7bd74a329919a57a104109562df538d05bdc067cb4ba46ea178ecef47babf30677fbf34d273537726702d37a0f97fae6d17443908af94a4ea457002e89d9d1888a254bba1eb5b364f4c80da30050484b15bb7935a06056143f32895225ac77119d25b735c1cf6d71a71f101a0e0856443170c834b344c18ddf5323e305d9db55f7ec5939c711334dce1d64f44787aac03a04cdbb0156729b40b64ee7e3e570a709b175cc5b8a7078bdf6257a4d434fc332df57ae191e7239899fd77cd598ec0fdf31460d4b49885a68c97a1933aede95cca5614d5e34c4cbd26c372d82f883ae3cea8a31789941f696edfbd6c7525db9858e0f82de4d019ab06c2c7d89a52db13867b6723966029b6dccc12ecdba90843093845bfd5b4a5d859788fd1d7ce6e28cbe9a5b40a8c3d508cccf6361512f47878637af8a7810fe61f306dbcfbf6bb88ea8d7f16d2ed48133c8600660207f4525fa236fd107983127afc36dc24bec5649912fe65fec13941415b07ec3ad859b05a695e7b2791caef5e49d0f508bcfe4783cc251d8e1af023c236c10456058439025a342962b3ea7e763610cdfc6b3a7c96a2b945cf1ff2cd2c835485bff97672439f2a9fcedfced9f106c32b09b59bc60703f6470087f62dac55e77ef457b53cf326127491e571f026c2f8cde2d3604c52e2a45832eb7647a5e2039d0d1f509834ec6e9d60e26ec5f37a2f7053fa29f1de51e47d130e5169de4fd461cfb4b76b8f8595c36b7bfaa07a0896a5b6f466a79f6c5b4974750c7762a8c2213ec2176ecf59ab0cc2effa63b113caf753d405f610b415435aaa3da48d75b2da2bc2d1dc3dc3c7e9a63e3cd6375da722ac5a73c4dbb05ae8fb602e85c67ae8d393b3ef70b5f8eda7eb93ae4aa0f824d540de5e91a2fbc4d25bd07d721e5e629084f71a04f1d67416b7d7185c53fe39dd436ceef9d01241b4cca952c3cb46bc2e88744d153f34c0b591fece10640a87211a2785892114c0f1daa26e722b7ee39cdcfc1c147f76efa76a07a855f3c3f0955ff9cd65fce8e24e9c973db5887632ae7afec037a50e17b02a799f2bff9685c3f5ffeee702e99c4dfc984bb58f51d1658103acee5873bf82cc3bd516e2e85dfd7d3d755988223f79699b9eb3125c3fa95ff5fed1500ed2b8b0cad571dde47fd5feac1b9f776d5c9414ed8d26ec04b2651e1e1f0b10e48119f9d59ce38dac16b6b3a80fed6fee2cc7e474400abc0e5875da4d4c40277101ff9cb3d6564ca8f6f6b5d4dbc93eb17f586283a6c2c33f036bbeae61e8008c62e7fadd92d151a50697c1f23c697d7a8ef38a1809ce5a69f39ba69f017272e7d34e2ad7b7620fa1baaa9e764079928bfcecd5c4af617d4ce317d562ea232a23b1b19d479d083cd57e87f55053c4120317557b4ccda8e3b19f815b119226dfd7865bd680644aaf2cf33a47da526a0e81c78c20910fcb669efe452401c53b57356afd1229afccbb99c9331148439c93c643d72b861838efc8adf50006e88cc8be415b64739d55786d83f641c97b685426640deb180c454e1372228c6fc6167e80e01777b975a22e3c48356b74ccbb399994a6f8e4fc32bd91d26d8f0e78c91d4c853c6b6ff35c18ed93a3b40b71789d0b045299b29f37828daf43d3d1ae705526f0c3d3b42083e847471f66de3cb018c3f50489aed65ea2dda7f8e2511eb6aa12388fe80b68d897db7277644888d8f7e84e39ff78e03bed918b727ad35269335e68555d822eab7c7b38639a4139645f8205fe88349326c8faf2e7737b74c5d60de2aebffbccbcbacbb58df7a5a74cdcbb5ef90aaf1eaafd862cc67f42dab73855011c043c78873f3af0216ce1b2b8032b5c23b0a43e3160f9f0e6e3e8cdc07457c6fa3628dd72b5a150cf3fead105bbe9b841bd72c9d801227a29e7fcb7288f12289c730bc2a1ee4a6878e56c9f4bdf2516239026b88d4a5ab0817411aed08b12dfadbc76e53ddbea7b615b9d87a4cfba4f9ce62f594aff1a30721dc374c2299f390fd4e3e9108bdc4281f85f068b8a832fa9bd64e712544b2315b42d81c3e335f8e5759ca5865a1b45ea466a2a7efa82d7f4d421960fa6c53b11215839e20d65ac47468cfb7fb1f333b25292d54f7842290e8ab22c8363d3212f0b0a165237294ab91c6f58bfc88300d1b0baecea2cf5babc3b6ef0f973a234ec80a7a2f5b559b7d91c99f82e45252e7a7b63f69cb0d278269bc523e16ef2d7dec10883f6a2220b1c849dc731d13abb920d59fa4bfdbb18d8a9abe71e2a31f3ee7175388785d1e44a69fee27a820e5e7785031a05333878183a4168480256406890125fed87ca77a1fab4ef6583b4cbecf1e7b2ff2b604e3860bb679a11e2ddec7f993abf2905e2ffd5ecd9b5711f0ee042f22240af2101b5e29e62985b1a2ac0c51c7cef44b62476410e3976b326db1fae13c4ab4b5f5fa6bc1e20d14d2c83943386dfc4040db1bec83fdf3e7ba7e1840ba74738355ef57a8aaa2712822247c9e3aff77bf59425458445e4a0a92d6992a7d0c22b97564f83ee6ca33931389186f759faa395b644086654bb9affa5301604f708e5f0af2441b269131eaa518572a2272d148d9ad32f56b5ace8dc96093c4def4d2a91c33998e0b18e09cdb1c2a228946655f69277224fbffe10881dc344261664ab005d0224308ad77b84c5e9e7ee7b71cc40cabc7a201086572bdbdb6d7a5b60fd90e4daf25778c7da75408336e93e00dd5f206a2e2de0c24284fc1b0a5ffebb36b766c8298ce231601677bd04476a86efe144fe6e580f904020ac9d228061f22136a093a343c3cd442a54428f0e345849345af104f6c0a83cb44f1bf76dda9ec758a4623a120612097c74aead060778dd39629b6c4d772116b48bbc5c7ed4986eec15465201aff25ec63332beaefbf9235e2162e9cccd5c9ad9a08e58c96d4075488d5e383086d58f1c2dc002ca94e09339fb901c3fd6cb747486cb37fe1f20041f9c6b2ee6cc746d28590a2bcd01fe04a3a801f081d6d00769255e584d7af5b1a043e4d700b7560d405557c3af67f1838427c01648847cb29d05c1693d5ea04f4ec3bffcd8fa938cd6de857a49193dea3a1050ecf5a0bb94213abce7934f31bf644900e9465cf865868edffa4ef92bdba5a16dfd48a997cc6c4b2b6c4d616b4d074c74e166dec166c9a4af99ed5692aa419485cd3d7953e18698e139ec7307b74d8b84c9f94d86fac73a5dcf407a2b6456f4a7a111001d3a48b06a881e15f171e6f7eaf519c813a9264a86dc2a7d7d45c702101366752bf26ac066cd33a337c65c76c93f4e1ad7fc9bb0f0ca43a83ed7cf35fe9ad932d7bbfd79340c3fd8d61f84b8ad4c2cb605086ed891c5fc3da0381183866a179fc955b0cf88f1460e620b492de69d53a151c8d44e35c3d65bdc527f1855f13b07d45bc49a48362a2d64512432c362492671ab74b91337fa6590b739483e3a3484a2c8eeffca75b0461628471c25da07ccd4db3909b85e5a20df09d85ac01fb545625dc9cbdf78806796b5a38e21b812851dbbecd92e3b3594c4bd8f39e59085cc642e6b5a1b2356ae15f4a00ff9cba9e7c3ec742e760e0e4520d9c3c014b677cf5aac74c1c9500b94b02a98a106d0e8357ecc2f2ab363ae0d8c270c9a543bb257f33469b02384bf1a4843890ab329943bb10c43aae35e5d358f97d5a2a8f2ab8c36b86dba276f9fa4e607b04afdcc308850fff9c3eb46bde66026c08c89dedc7b6d96e91bf5fb3eb550182b39d5c89ac7554bb8fda0037d29f89f9392a2fb35c35b50efac2064f9f540fa8b78307c3d7db0a0d292c602f23f873220bbc5a34c2d3b6dad603b50b0934c05a6db27e46c0f85ce7493d98bb7ac56b24c54e94675d5517a5c73616e178eb40d5833d1f021fa8baa4e86160f1bdc8ce0d0ca102dc2e36008b27493dc0436c97d6e2976212f229713a2d33ccbd13921ce0decc6adc61bd398c989b4b37208cca4d57c9e524bb6976d7042811595439f4d58a85d98a36dad3f4112aa44b13601d13e0e97de50d4922c7d6f3508147c93e620cccd4225c750a539c3e482707112e5f8a79a89980a3ac6f993f7926f7ea959970a7c94d8a3b11e52658019ca09c0e7d8a0aadc2f322cff6707a65bae011430323053e7d3807a01f0cf0a1dfe6b2641a0d3e2e63111e29805f95cc3475ef3115dde93d3b0933b2de91a73d8df686730cebc7942549476e81a42bbad9c89a9e21a23c975f09d64bbf2f92fa5db19f2945f723c5e6d825ddbbd6ad9b96dfd7d510f3092755dfc7b759d08f8c37aeb1ab8bd445af960d8296961397e063418a41c36275670e65e10332b7a43088218bd836d5d3b702575a052f31d340034f64a2941f261e537a311c2c56ef4fd539915c0068d7f1ad0145acb88af7daf1c6ff510b76a405644c84babd7931bf1c09855705f2985beab880d6a30bc9e29317e3321726d4e10220cc70747369c4cf71a2fb6fe4c4c8efae276959a4ab33cb909a1ab307e6639cc65641a55badf6eb734199213c440289a37a1d936d0ec9c870e7514c6eb1cc3130ac659382816f6dbfdcda1bacb3b0799a61feae3be4ee21dded12048e4d5766a3ad9237d2aa62cc636a761a28868d1be495206466d1a99266bf9ba226ece9e8484b8c5676f1e1cc2986284aebb60c94b19c531931e2d0c23f09a471755ea49d3d53c4e3e4125db8cfdd7a8a09ee1ef9a7b61db2fe122cdcdfa9b750dedc7c2f329b574ff42d0934dd58db76f6796fe59b7312545fad99b929f4e29f4adf3f5c68827b446a87e28398789b9c98125baecbfbfac1b74a0103bae63d9ada8bd72c8291c22432db0935301e7cc2cecde1ca47b27e80f8677238210fc86a624c34042b68e1589c71df730c42a3bdfe2ac27d7ea7d15ab1249d07c6829bd2a9bfe710f3df6a8621675d990677b2f3381fe1bb132cf352a36b557b608bbb0bc13adaa04eb7c196393fc09f5339afbdc647e8b6de66672fcf9a9983191de3ba96133dc3bc2cdfe9c73e3e8c8cf133f7f46e7c3f2adb80197dc272ec44f95176580b6eabf159b6cf45776244f3e96c8c64825a6eadbd29e3851ee3ae106dfb0ea304b973cd4a136ccbd70dec7a5a6234fba70b1ed1b5a676b78fa5e187d8ffdcdbf9ef083fbf5f0d1e07028fc955efee2d7d1fb0f94716cada0a610c98e68ccf903a4ef5ac467173e8e0771d39e1a2267898171d47365f2c2000e6d93930dcade2c56d3cbfc620cdc2fa9fd29b960c2aca0295fb176b1618cc8352a9b6f160f80d29dc29a3c1a5138d39c97c36c9f0b59a1a5769ca450cbc24067dd65000898b6ff3dc41b19bb9a17548f2c9cfe2b30e4c8b2a1eda017e22f884e5697aa8d89640f0ce10dabb4132c001baf860f070dd2581e1b286c89fa8eb84563483ce08372c6cf1310218027c28e2272e927f46be9c444dbf78e27846f97bece201152380c2bf774aaf6d50f68721f1044f3e7837d864233c4db90b40163171986b574b2b258070b6e8b1284763613d792c257a12f5ccba391b6e26d06e7c5ca7009ec4837cc0f98192a9875cde1ac1d229e59a765260e8fa4807629311d01c4fb0316ba857fe05f70ebf8e0f260177d9168c8c03ba732f4214178f0f8df92a3f0fa73962e6ed2525dcb49768f51dbb442768824163d6fc7ffb059a75f8b8ca49eaab4a2aa3e03bf66f4ffd91307d75c6f1b09b53b29f2f2773c4641e4323296414a83d773913d15f593cc07c0c1bc4abe486aec3a48c1de23164f2e229ecc48a24cf20581ec64dccef38491511f79c852ac2d5457bf003e89662a48cb5dd23871aefe21f155fc9ed8bf6fffb6c9e613f7289c68b3dca1b0ba294ff6b0b1aebfbb05fdd8a65424cbcab8e11736776ca3b3aabd27044f949b970509b732cdfd4c9419e22f18c266172026148d51f6cba006608e035fa1b5cd74ad4666e463c87ffd0d58c173d02c2c9da43bd751415925df6cc2ba6f68d1894cd38e44d079e7f596d3a42d135b5f700188dbefb8e25dd83441e75d385006d239978968ee3c0d183bf9a60efee98fb78d1a50347d084674944f78781216ce77ea4f52a0cf0aa6c264507f34cfc54517b4e07a13197e3c6438a96d76571c93f0e040591e4d1ffed0f1c2807d2138269246da0cfde522f38edf7b370e03fe1885db5d3539aeb0444a6176f4f24f9e4c482aae8fc4546870b12f1b9e418abb48c41e71528a4474f881496cfa32d968522ac9acfbf35d9104338a2b2ac0387d6f44677dcd5d3453f318d89ae0abf4c88a724eb73a803aad84b3dbb4a355ddd1eca51e3968df81ac779318bfa61585f3c38c30c026a08e033c06955f1e4b743b38466b6b7200f8c9252de85ca491888fb5d8195e7d11d8596e4b583a4e63b576443f446b9f46d8f5bb4949c756164730496240a54f85e416a5552c9a93f38b5929706e2903f52604077f9623bc7927081cb9722a66b81389462b8acd7781e10a9880b41a3882060036acc5a371ee26f7e29f71857d73a257ae7b90c09ededd1044da2dbb2576052ab6a51dc44f00a6982a7b38a061c59ffd588498bdcba05853faa5d50cf4d03960c9344be7fdf68b44b56f65328e90972c10f748a35251b4812bc1b904d68e9d055a6d913860a1e2ab4a0e87cdf0bb89c67893cb8203784e2771183a3da68a319a39e15347b13af0b8d0392dbce9dcb6903a4f25b359131cd9e956c935b0494966438932bbbcaed34b374730e0050b5ca3f1dd82e8db25ae72db57d744c1741f18b7377e17c6e9186b6c71a9d46313fcfaa0026b0fb62b601f708e860742e567df188f44c1597ad8ea2fb0060346cebbcd0387c1f17b4711abb03f3ae1afaf0f59df867a4fb5767efd9f8cfa9259dd29f5bbc90cd7873cc076ec1f6c3540bfeb9d723929c4aeefc02f265d40f2ab9c35692d6cb3ad954cc7021cdc2cf875084e3dc548db3a0c774dbeb2315f3a9aa3221c33923fbad00b692bb984f67a437dcc4802d6e93a801442f5a13234f487b20bc40c5edb0d280878305bfb8370dbd5b170adfbc6392bc396106b3920bec0d3a63e2c2033c9fc41cd79282087d46019bd0bb17bee52c833d998db6b18100a551887b080b3ed9442ba30af4382a5406abd472328602b9f5bfdb65ddc37b6eb419bea9d9d3756f8d384820af18ffa02e32de964e0a5d3b1b75fd048da067390b5fdffed94e5a53099495c3d5d728d05cff30658ab80eb752a323b4b3d1f06677e858183d0a433c031451d9401a9afbb0bfa563ecf11cd2922513b52f79f0852a07daa5fe6941863a300160bbe07cfc5ea23d438fad2e4aef262ff687dfc376e850290e472ff55ee8107d4e8466d68c8654c9b9fa35e1fbf31e1865c5d1a5ed887d13b32076d49b83099286c420ab69043b9db3ed1810d97d372869ccb53d4e0458170aa6376c4126be983e4f3211e049619299c475e2852ac42daf960112153a46dab256f426463c17629a436362b00088a953ce04566d900a2a0cb62634d9bc22a05c84791fe1af05493bfe59243d8024ca91d7b0be5440343dca336a71fe205e02b3ca39b5efa0979f162addf292e995229142f627437e5882d92fb9d541538fdf9cf9f5ca790272e12f691da14ff1c3b5a63d44f8e3bc9c693e68c0cde53ebcb17b9e30fe44f4866f60e23632bdc692ee9cd6a8e4e0a00db836e89acc0e44aee9197261569cbb3766c6c619d376df36fec7a77f083e6343de3121c4276efed0c43340559604083e7e68d21b07f1349483918cb0e8c651e1711406e492e567cbc09e3b8ff7eb25de7f14cd2e20d1aa2ed42eccf34610a64d2fe3fe11b723a8e36e3a95036bbbd5b8ca76bf44764f657add728d678a598299e53ca7736ab1c1a39fca0b72c3f40fd74c6739f5caabfa60afa45f463d5ed7fe4b88fd92bb5a411de657efa3312b001f2edff252677969e19f3b19fc41eaf9951efff7144160968b7334f93241b6074ca902f16d780a143c294ecf0017b86d03a9bca96822c93b9dd085038196fb82e81bb4393c175cb2a559c92545c48d346b5974816a67c3017688439f9c1c6d1263b7481eb83ac581a88005559d73ccf6f68382cc7800ebfb65fb879b4b0334235195ad3e7c9c3c7f45bec6d044c54b3cd50e8512ca2bf71c10888baf14f4223d7455ee945b431e23b01ae22af99b58422731fe1cc4dbfe75a36da9b44c0cd1082e941580fcc7b6df20cea445ec9d5c8ff0f318f03c0506fd330d5db6cfbba23c73d296a4e49ed8b9226b631b7e5d8fed080cf5139a1f8842d25c35c5a5c23e34329fee4e64a12d79ad01697ae68596979b1016bd13d6cd40803c147a5224d2cbffda67902751a154ea2dc10ebc20df068d429472e697b60b67ac023d8ce6723f457c78e93ef87be2421df03fcb841f8d2ad5a5bb9e2ccf9d3032537fc9db16e1b27df119aa30713ea5962850213164d32c4175e934c56c5a00613488375c4e39ae1176606bf79e1733750fcd8aff65983642ac60d1271a9c4365af7d48b59bdc1e062eabf4904e181646d49eaca52d071d65c4bc436d00a7b94237404953b8b444933c3c5ee9b4d0e18de4813b507a58ae86a037aa94e81f4e02b6b5e01972ee68d6a711c85dca653a5799247a10471d5b0fb48dffd0f3caf5c90201262df96240f0848c02f5ce82dea42eacaf96882c58dcb4999c35753b733d6009ac80e9e49f00cbe633b7f4249e947bfd5618130e150d292b12e36c6b3b3fe8a0b8159cb5a2f160e3ea9ec271daf9d3ce3f82055384b3bfa081b78486cb6846601341db24867505cebc9a508214e07167bcf6877ea901102ff99b0a21f58c92aab856ee4e5bd579a34b026cdc24d09807177580afc0f5d5c210ed795707c6101d119c5e7ca334b4b3d7e7cf664464994f7d44e74ebd8d1d6e0166e75cf61df8a3bfeb605b059bccc8b0ca65a20a6cd62f9c9017e62a24bbc887753fab15f5198b1318c4318b57ff4f6ef39f8c622fd3491829350fd765e3268684d40510eaf26bf68b3e1da64e26e60dc1f402dac64f6e3517ef51b37073c321db4fb956c14adcd5f5620d565dd8e7ec916dd14ba60cb51ce861c55b7d31892a79a8e0c42ca9c32e0bb82a239ec55ed3113aaecf5172492f65d26c135b977a4f5c3bb396c4a2c33355918da88d80b852c39614db94a9a3b95d4d7b16c813911f5710c38fafb709966baa9ab6b2da64b8e83ca4dffb33ef12e818405686cbf32597c04e114191fea64c5b398c0901a17d0d540cdb23df83ce0d94cb8d2c1f3a24df6af2d18776114d16cd48a60bb674fafc53bab6ba2f75e1325f3148ac83c0c91d02d02bf81f86fc01ce554e7126966a937cc7597ce63f86ec46cecedc21f1e08d3f7992d834505bd0f1f9ef2c2e03b063feac80bb57da9b4650ba5eff7759df73f074a0a5f3b54630b080448845e4a90df898c4ff53d3c02b91e5dfa4d67acf9f589cfba25d377407b79b49cf7c787da3caa93f42cba758a78a42797f387394a118f87d9efccf2c19be11653275633fa849eba096c8886c845fe5f922a2001add80ac2d6bf306b55a8b15db4d0c1b1c39ff25ee7b8407aef21772e783e3bff3f20be2f7441c6e1bf1dc012cae1873f57389863dd240c335372605a187f05f0b51dd69678d452714e151eeb2dce75c330186ea3e0c9eaa87c632218457c4cd1cf2316e70717d81cf5df97421f6d3a41cff1916b89dc4f50668c665ff0e873254b417eef95a88066b2b0a1f1a2801890b5a78e117d3ae1450981454ae09c7c8b8fbfd1c8f92f839bbfa2f89d816ac57d12c97a677d8dbdacb261310099b5c319b00c49ca4d73afae45c12e30dc4d9dd39f0e5c5c7aecb3df1b9db88a07577d01ef7cd9ba172eb0bbe82cc97b1dfafc8d216984c7e24c3bd6ff2eaa7f3003b4abb3b689b43c81d423a1d80468ce64115487d9fb35098cfc4fc6547664a582bfe94a28a0b97c97a839b7f49f4fa3aba2e6adf8e38de90e46a7ae1f7a791cbdb318777264646f27cce7f8fe9c0c73bbef402bfc7234238dee234bb1d1119828359a5665cc715b511f9aad8d3810a925fff520615a6f687d68e20a7bf56cade375f389b700adc6ded373abc4a979fd23f54663213c91026245d1d814a9bd63888e3c78d0a44d00f6fcd0837f651e3cb3760ba021e151cf9825bb0608a637bc47663e06bf29bc3cdcfcd8b0f1ddef13f684cb859cd9af580b17b0c4485e82202d43e92cf8ad3116ac168562507a57c0d5789e525dc108160f8f20c43bae08fdae24594b8351f0705162d86ab3ae44d511eb11052db378c42b1df8c22ba92315d217cbfb95188d58bccdd13d62deeab55def673caae5271cbe55f020fb7993320054d2b4d27ac59334efd384de0c953f08be8d05d437a831aeaeadb1cfd02d49371000a8af56253f53877b1b353163a020c3f84a68218cbb6c23150b6bdd57da061720e3b70d26efa31884a5b627aec0fed84cbeae4ef97cde04cb5a207a96b6dd9c7fdc06e54ffaa9f737306dc943173f3d601c58fbf0f6d49152e4a6f346b67487bf6665c3104efa6ef4830ac353a9ae0bd9bc3f38e96cb60dccc99ef8efa64d43418736e5a54304b9f54eaef8c625cd8f5d46dca98fa81178cbd12eb52a2b74f4c9993bcaca369af876fdf36f64c717b0fb0364f27f3fefec4d9e44fa666209d5e21f24bb1bea1ff16d4d776fb35f9b731d8a5a981f0cd0a413ca41fb8f77479faa48d542889368251969951ba302a8883b511d3b5e37dbf8d713e579e4dc836781d3b9ef11f707b708e7839720fbb0b96d48b57fae034fdc875bc5f6682fee2cb87cda41c214b60ee573e9240071bd34b6817729c7ece5122ed824131b1c5b3f25a879c3aaed700addccbba69b3cc1c830462733d7e2f489d511766038c2a30b982c46676153b1d7d6e2470c8b7e90748f9fec97379f5b4e37f9bd3444f7e9565246f3ebf72e2cc45166ec2b4afa3b94fbe0edbae7e6cc19c5eb13112f864a28da29760e7831779b4af8c9f0e44d6dbec2368c3d1e3fb6a7cb31e3c3246fca7a6671080f355fa489f2b7a1e9c9e9e9ef17b909b3b7573e3c089bfcfe43395f5e35ceb1bd5e99a1c7226db1edb4ab89e450c49a29ce64707b2edf45123baa59ca9f9f95988bc289e3b8f549617321f055105a6d94f6faaf2164517b99c001dc9a1504aee55acfacfe4848951e81af6adb30bcf3d80aadaf1f17337df4aba7560f0787fcbf823c9bf9bb8b761f16df481d6a36e574c28a5786c7acc41ad994eb74584188f57290d01c1db457e4f49ffdf56acec90fb95737722fdc70cbf6e286b37c985f63e04bc1786f2793a929fe4ba9b7344cd1f47a61bfe4b8419884a42084c2bc6adac46ffe216ea2cc2b487ecec9c9caa2c4cb35b5dbc3b29882886452736b6536e9e973ef4d4bfce1ea3229f9442034d148be8b1d00099b505b74cec877a6d39082da9a35b96982d5d2d894388b42d4ecd0cc66bb03daddef08ecdfe4fe53eda98d70ae0a236c2038ff39e4bbef85a79fd1a75dc4aec1527484d31abc09829951d01876d9c777abce7dba14e04df89b3da386516e674b95bbedc8a48b6276476dcdce623da8fffa36dc95bb6d22b621f017d544404265c8a9d81912a6ace036db7d5ec43347005beb8097a434662f5f56aef1a6c717a9d98fd0d4ff958a8bb2ec7517b715901d4a9e22c66b150451682f3f1f52743eed71290ad60b41daccec84abfad4971c5a0a91b2d39ffdd199cc32f16161ba7978f447360257ed3fa6f01fb61836dcf9ddefebaebf003890d54173a07a2dd1d9d28d1a8fe2fbb1936e63687ed46a6cceb1610cc57006e48b58db5ca9d1e6df1259098702b692f7bc04b1e357f78920405a181f95f726e017849b17939a7ec6f494f288fd003ac2f430612e4fe0fa86cdf358228fc0c9cef4cd07759a54721c673c14fc220aa51a3ef9943422c88e7919580f75b6eb4dad912cda9781cc3f549caecb61c387d2cbacbc842c13a8a6a3cfa8f16c86cbecd3fe9a238992301a8c42024690b88ab85da58a1d5ac5861a7d7bfe786f3b8c190b202c3893c2a1f8d53606984964fa073d6731a241e7729d37bf301b063674fde91b5007dabe42e897041081184c4026feec0313873514d6a218d6df6c6f09356ac950f237a65bbf48c47d73a038f210a1f15ef1214f4accc5fdbc8bf1449c390697b12a9e3d9b99db6621a356ea273d833057ac2c58ae0ded3678c378eba5e4885b4266441fe9f82e3c119ad0118bb940082701f7dc057ebd9385a42cf58cda71d1266ddfae9a1d2e185274c7cc8c006ab160a9cc5d8a77e263bd8d98703daa52ec1080cf71251f70cd91efb74ed4c439721d8d7b0504ce0e221f2c98f6bd60e3d5a3f002f91c7588b5d20aa8d9f7f6fe25680c3563279d903ac8a27f69de517bd162a07ea64dc775940d1594c7fb642f8e258c62eb9ab176a8760c1511e67df24267084f1165c137aca9150b5adb093275d9a5978904f79eb638219568df090c4167dd67cabadc2a432625d5032648b2d7a225dd36a031612326cd45cad626255d2e6b66dcaa4204f8521b54ff25a91d29e5b64bf1400fe25f98fdf1476e1275ca024f811947886ba212108f63403151e4f5e6484c3230868390c45833821890c36432197a253c51918d26e4a3af8659abe29b807034a2fea248ee37db7dc064ba3295e4b626021fa79a16f124e16affa3be43d057ff8042da38d59258e50db158bc553707ddef8fd270a0d8fb431992203e768a174c81b58f96c9a61cf8eab72544ba42bfb0be70b8e93c0ef131315b12d0893d3982dfef0df5e80ec8c231546eb1c066a830840c7237097f307b3bafc85cc1a4fc92491f601af9eb9c3ed07d767b92c98ec53ee9f0f0e15698c05d985d06d3c022ff0a8a8f17a9b14747da009c1838901b2ca8aa4938baa8c8b037e6644150d4410a0b5491bc3300c268688858a0aa6e8608e02b668392d8b1f5b631b8d9a8da5db4aae6ceb002fa27907dfba4d782bbe000f8aecdeb4339254de1dbac0bbbdfc5687fd24eb0f9e0cf40b27b08d139806494279d00c8aad3a5c9c401e9c402128d5e4fc4099aaea6bf5f12112f31eb922faac502f1a3834831084a8a2b63011e232e19c70e288609ffa2071299274d2d438695438693a3871429c38cb89af13f62389ed54d01f585c1c0d93054ffa0b4f883ad6c409fbe184c120a1301038065c86c704d3b448304d2440a1003b610938d69a9ba1288f50441c8250c3f2801ffcb0871611c5a2a1c415419024141e705ce1c58b66103d7898cf0c555b68261045753279608200ca8ce763c5264eac70e3c40a2a7cde43c50e1ef645d5858d2124e1a48a227cf1a3d0cb5dd9802811e599a128204a745205c70d921bd5733fb40849b2c4668a0cb02469faf0c614202a64bf9811816250088045057a51e5630a4754a1e9640a3948523592240d1f2449e3461b7b58430f92468d3c744213094a4c07e573324514275340713285025078509101314e9e473a799474f242d2c91b4992c60e92a4a983544d219d48b106a90627526c7122451927527c21492c28410a20e210070d1d2449330749d2c8210e1faa23d2c0419224cd1b4033f422499a34dc20aaa82d4e30c0058d1b346d90240d1b2449b3068d1a502a7081345688b2271710802445218828d488020c2751f4800349664c9219731285e8240a21ede1c0c49e1c1440f9745072447182b206499242a00f553f1d29c78989154e50c43841f1e2048a1440bcc1861a7690431a6b38031a50cc2a34d5cf48e53d749e40f14ea0d88024492b404149018a67164922d1605f860a8528fa441c9e08c2133778c206663c918227a82772fc139a930a2441b20f060a16d5dce20b97203980f00372949828c2119a3224a20f6a98d0c1640e6e300943124ca660c203144c000092244d5fd8cf7f811213fa509dd9f2269c1309404992649c44401392f41272c14904825085a659759470128129aa1308b4a00a4d473e238ee8c867347d94884e1eb0054962142b8ed455f93839e18124893e584c4e12dbd9545888a88f2864ff379bca332b556931252b40312314847c3c68e6658a4fd5794bb180a80f16270db0815485a62433e68ad057f652568846d40903129172c2800e9c28208d0cfc60499258208303b420018628590423dc2841a3840c2709f080a4714333831304a821499f190d19d080a20331384180002449bac401ec19064822499a31942000094728421124c90c498a410c66408624955146a8c7013a1d901a450a94cf7bda09013c484a1620090e5042ba42152e70841f42c8010ea42152910e50e064001ac9ce0fb91b09400492d448363c78542702c81180499c04000e2a50785c8a0a7d4c47b4b91fdaf122430101557054bf48d501f9a83aa0e901c5740010872405917a9c00a0049274292af4c412de529f138d0f4e341e49a2b6902aeb99eff2a12133f43c78d4ce0cc9d65a6badb9bbbbbbbb33c618638c31d6ddddddddcdccccccccbc7af5ead5ab57af5ebd7a758c31c618638c104208218410bef7de7befbde79c73ce39e75c6badb5d65a6beeeeeeeeee8c31c618638c757777777733333333afb5d65a6badc531c618638c31420821841042f8de7befbdf79e73ce39e79c73adb5d65a6badb9bbbbbbbb33c618638c31d6ddddddddcdcccccccc8b237cae396be62266451a01269a2049d20cfd15b5633f44a8d01b99f9a105c5224379fe878609a1e78844d4e7a3c1424b45b1549a2b4892c60a92a4a98267cad0cf4c21148b2469a820499a29485290a459d92a2515a0cfca8746a2d1ed4c8a220a7528caf4f18caaa9fa0a0b4aec9024cd1992a4818224699e20e9a084e40449d2304192344b508224699220491a244892e60846308134b2e2b2d1426ad1051016b969e9a2a5456ea410225a74c1c5c60b1f5cf8f08c2cc5051cf58879d10a0ce5e901472bffe9c07c241049b44092248d0f7a603731a3ea3d33121c2a764892541201a9e40c48a8a00a4d3374535513a49141621f0c142c449ff9e9c4744231a3cf3f220d49b222029a91e4197926b505cca7230a51d407ca147a84171a2f44204992a429a221f2224992678aa68a23b4901a8105fba11e709445fd2226f0e69c113ad0c1082f6c872ab2f220a8cdb8a84494a772375a841792f474fe506929623f3e66423386f2c82402119224c95c217ff8f8214af2a32e3e2b2a2d459ece1f9588f2b8d8a7c2dd08a50a77a31df552d40d21516929b2b92124a1078d2a44b8808ba8b414516929f2e94ccf10974a543dcc10106856a3ea7308151068f2e0b1015552891f2428c40089219214620cb09988008c20499209241d847843920a1137f693746e10e2708424491e8f6322a11fc283c7065411c223499214253ae288e30d499274c43102a90b38dad0a1b079535d5143d515b523fa1836723c8223d83c723772d781636510660091248d073a20499e5048564d0f0ef0a7f2418940332120a24f871a8281900f04310641481a0ae808440fa27080243d118427cc084403a44a93058fd04bd20c208af007454892540249072056159a38a209ba62468485864715fa4e0b0a473441281e8f0f1e3c74fc21057e8843871f5c241d6fbc21bd91224992157cc8826bbd850034259274828d1b3d9024c944d2c1072aa4246b4dcdd3b2c20ae7064842e181d2c5152b6e0c91dc409124e93d9d3b61664c1b9a9024e943a40d38d440d1b186019ad0860aa436bc90daf000cc075aa1f242c48a0fc582d286244928f6d339c286212410c5c61924141e5c8409483ad84832a4191b3b24c91dca870d014892f459d983225078d88e1c244972d1b18726ec218924edd88310499276a07cdd438a24ed40d1b1870668828a1d6bb081c223f4301d6ac5435923079224893e6b8024141e6b7821556baccaae610022920e3dbc21e9d0c31f241d7a1084a4430f71d4cf4865e6e38362599124cd8e25499a2ba4c98a07cdbc4892a60a49d240f11e3ac3e854df22499a0d5492a4d140cc7bfe41332f92a4a16214b3a93a92a4d93185243d6846f4a099299a97925334b5d0a1468a068a0c4892a491423445530b22208a054451422449937257bef248fb91a11f7725f443923418780f9d2fa11f9fd04824aa1f0251212d5c8288dec5332b25e4ff25886752ca1344f42e2a2a2e10ba40e842c4b10b9166765242dcada8a8c0662bd0b1bb15cd05242e64a8501049d24481b222491a2844d547923416a88024aac20043365b7916214244414441840869b6e242e483345b09030ce96ee5598408110511051122c4dd8a0b910fe26e050cd94c4524a4998a2848339517d24ce58334530143ba5311e24e4514c49dca0b71a7f241dca984e101d2ac59b39595951517222b2e4462ecc747b3955017cd56429417cd563c2ecd563ccd56c2f00071b712860888bb9521ee565656565c88acb81089b11f1fee56425db85b09515eb85bf1b81009715cdcad784222aac5dd4a457d346bd6ac994ab366cd9a356bd6ac59457db85381f1741e883b9510457954dca9a888aa0fcd6771a7220a81e1e24ec55a1fee54e8c8c59d8a67c4853b15241d2ddca97c3a5cb8534932b970a7f281e9543320d00c89a059339715222e2a445cdca910a99f51e8c5dd8a8a16cd549aadb8ac107171b74204c810772acd5456dca9ac346ba6e26e45f421d0b7b85301b284396041b21398c3169224e99803cf410159a0a0f0f80284c24556111ff6635eb412a2427280220e3fe320461cd6e4c0a18283186cb3111c5400872924a99a28554c33ffe30d492469d38353cd2d50aa8992451a37e022312fea4892460211903e8c4e15f3a24eb3d187d1a9dc504992c4bc38c2e79ab3221f1fffa1649e45a5ba1f1ae2a1286abf873b2af4617ca8cf045513e4c28621fc70598321d63004697a149967594305663649dcadd84fd2510951a23aafa53aa1ca7efed38179eae97c0d5194e77244309f0f813af55b5ee4121a0199992c3fe3230d6974a1230d4310511e978fe9bcd84f0704f6d339928646431c68d041094494a7aac27e3a47485082890a2beca7736487fd748e5c6ac60382cfcad70972b1ff79501792a46180660167c8e20c28d2190a80c22326c60c1f141e9beac87cd006049a3c78446ead435519a620bda8806086783a33468aa84e0b7d117826cc0b7911757eb8d64766ad0f02d77a725c5c6b4ae6a599cc6c6126335b1693992db165660b6c99d9f25a66b6b896992dad65668bb7cc6c612d335bba6566cb6a99d9125966b64096992d8f65668b6399d9d25866b638cbcc16c632b3a55966b630cbcc9628335ba0cc6c7932b3c5c9cc9626335b5c66b63099d9d232b3856566cb929946c8e0802a34a181051d687840071a5248d218a820d98f1955a339a4fa8e8e31144092c4700669b262d8c124aa3a42445f8961b2341b8188e488e34554910f513294108a7aa97218a21092247dba683602c30a2429471c3e3e44e0a83e3464109294431081908e544a8865f91025aa428fc443b9f0e0f13c4413a5d90845542728e66d17782049d28b2824ae39eb242ce43f140b17c2f080debe67f36174aaea61266853553d9a8d389b23758ab6108298da114d198f6756fb9bcd666dd6a68baccdda7091ea5b3c1e1fb5ea70f1af22aa3a9ed07790c0cc1f1f335d3e2b228a85a5d9880a7d7079b11d205c641569c6a92687534d4e911e3da0cba2191177a3b754eda1630a389024984f67c6e3f141b550a224a5240a0a40a0128ad8c2195638a20a4d1faa138514e83843ea3863c8342945015285263aaa2469650a1d5090c3ed702a8903137540c1495568ba42f4e98c603a54f4e9c074a81531a34f35d7c44850b8d0c113b220bda07c3592410e9327c427a048f6613e2820aa330249059c8d740227882449ea694d8c44fee8a2e5c5e58b12a9e48c922a343da542a2aaadf8743ca18f59430f00804d384392a42fde43911ce984ac98f9238f279f9615309427871a9294230f9294030f928e2688710749929078286a088b085a26912042beaa7c803a2f9d992454a80865472e40aa17899ece1f445cb208514078f02080ed504578f0d86c389b0e686e4055d58335379bf6139a1155dc3df8916c1c3333f3e2089f6bce9ab5c86233b3983fb2783a29f5928252cd2c8aa05401820d920f81cab084244d2865a0a1a38c468624c870021949282af428a03ac880128a8e17c02149d214eabca0063a5e9044aa4414cba4e3053b2617a4f1a1444f47d7053990241d2ef8a2ba940be01896f850a11f238d313e44cd9719832349938e31c650c0141fdb411103109224e910430b301f2a242302205d7c18a11e3d7af4e8228b2c92503f363233546d92cc98169ca0058f0570b0e0062c60010ba658011e56f082158460053b2469a258a62355473402cd78aa98993228339f593b9f09f2783a321fd3114d199499cf7c99a8a876a06840031ad08087a240339ece8ce7fe87faa8600d1590a1024b89503ed6043c787c353943be2001ca4b0a38a1230569e8484111244a3483f29c2f5270002fe808630961804047180f987184247d159b8dcb0c0f663a90a410497ea023892889053e9d19125d41a1cc7c6638a2102523aa461765a68a992f3ef6333955f8c8a272a95ca8f8fc40a9c2435174478f1e2f59802811109922320298bef8e20b2aaa0051a21d4190b071a49a2324399024c98a1085c40b898241b29084466c48f3c7080cd38fd18f0020ea822846644575081d151a3c78d8f6565e2e4ee765bbf282992f5d94b8415af66e2fd6eae8fd67bf0d92e3747ce3a48fba4b091b9e2ffa6ebb3e1f7df72d1494ac414edb8eb60b19fab58e3afbe98000aa213216a35b2e3277ee3984ce756cb7b9da1546cb6ea64136aeac513bafc7dbde9a25689077756dbc286d4a2b7d7b06591fba7a6ba3fed331ea7ca5c40c3246e896ede6aa776dff6590933ebba6d768db65bf22192475d335b3e5a8bbf442ca7930f3659a60a6689a426f210b89406848469fad85cf698d77353a06c990c51bdfd106a97b3dc52097d7ee56effae6ebdf711e83f11b516d292f4152c0901fd37999a6f788e8a89aa669822c4636a39230c4e55c8bafdd5b33d36b9bf2b2b539eec7791ca2904ccfddc0743c9e779da4040cf241cadcf47adb85d0310a5d48c917647d4799473a632fbab8398fdfae1620912991e843a2aa138a2f255e90eddafa59bf1bc736db7bbec3f248a8d09069e2caf3968ad9346fa2a40b925dbfdd26b79f9cc7d64e6b7d7c3ad41039d97f420917e4b3f6b167df5e6f8c31dc826cef3d76ee55e8d6c6398a619e1117d304f150a205d92ab5f1d5d78feb43879cc7475a8602b52c48b7de366ef4beea4d9f711e77362130aa9ea67783122cc8cb6ea9f37a70c549a95322c8cd239d04255790cbdb9db596ddc62eab97f3787137e86ec4dcf3a2c40a72b6af715a5b5fb3ed68398f8fd409f2364dd3e46e344d9ed9097d354df6f347eaa4d3e4af648c922a48f8d5c6d870d6f88c4de63c7671a1e999b57247de33ed23098daa6316239b1e255490f1ba696f2fd666b3ed6f0ab2b276bfa953c6d7be8342a6490af2d2bb608d6f756bebc209af88484854b96331b231414914e4ebafb459c7d67dcbb4e40c16978d913176b4a785c2bc7632abed1032af469f10695bf79cb9eb6ea55de204595d43b69e9b9fb6d6604913a4dfc996564ae9b3bcde723762825cf37fbdb858ec5fffbe53b20439e17458bfbfceebbeee4809d22d8495ff45b7d6b976dc664912bee37af146e670f1bd8ff3d8dd03c574181224c7492b638f526699d796e4b708bd0c25a44f507204d99885d727bd9479d53a61e747094a8c2027bbed59c7f9f3fe6a91c8344d53cce8e3588c6c684911e45bfd1fd9b6ae0d3ad8bc8408d2b9e172d4dac7b859ee583204e9b8b1061f5dd5edba0d398f65fec342ef1212b930bf90a862254290d7d5fa2bae7819df662fe731bca251ac60485431561204c9ec91ef751c2be5c83c66f379cfe31910559b6da3949714da4629b1bf0408727d5df4daf92cbdb1236d404a7e20fb56a66d5fa41432ffd91e28f181bc77ce06a9e3c990d1c8af07f25f84cdb117df9a3c5db49ff71f253c90f72d7d1effc5d0260629d981ac4fd9eb59613773bbfc79cfa69b16253a90be7c460a99df3d2f6e939303c9d6d25ae9bd1cdd2e4a398f1d8744150ea4c3e8d0b6bab8365a5be3bc4dd5698e253790ce46c673c567c8ec98721ebb8ff9c6cd6fa9daf98cde074a6c2029f5eacbb1b3175a873124aacc90bf9cd6d6e0bbccbdd8d44351748b921a48e75864af51fad1b1edd53490aed93aed5ccb456b9b35b72e99818ccdadb9536e0ed7bc8bf3986d363023fad6b50c24bb9fd45b5cafad5d6c82d854120339db71f7e2777456e8cd79dc2a2530906fc61b9fc2f916b56b3dcee38ab2ce2d24aa5c4919d25a16abab75fd5defee9221636d7d2d6d2cd2551fbf921748c7b5f65ab0a3b3b3d92e71819cf6db3facf6ff17f7978c21ef7b5debfdcb1c63daae084ac490b741d89aba836f396cc779ec992198177d3a1b3b41cda1174551cc65b005eeb11dadbe2a33ea9cf318368f36a2980b250b2a8bcb276d934d7addfc7436ee461be798d18709598163754eafecf69d3777cee3e6a202e91c8cccdd9eb35ddb6a5d2990acadcfe82cf79b963dc679dc5c98a128e6b22cc2907efd51fbaca3fdda99398fed6f9c5d8b3392521629dbd6377ab3d4f9b073c83455143a16231b9824325af85c7de83ad6c9e064ec3e44d59691357e7bee2de60b23a32e3616231b2f9044760eeb7af4d535db659b91640fe16af5c5791bf2f5888548c6e5ffdc8496357bec17e77105b9923ca17b6cebf5ca666dcf79bc61dc42f2fdc256237deb9cd1c89cc7ad0a3024f7a3b76f8490b9b6064110bae7acdab5ea4706d9a4a4f78c7f67846ed95bb582623a8c7e248c77bdbf8c3efe5be9c7c8e6f7da2ef66f6aafb7158f7431b2b5b05d643c672fea7e566ae733874cd36331b2b9472473ccbafb4e069945c6603e9d2371a140b63867b7566db4b42ba48c29d71df93d59c3aebf5cfcd79a3916239b1270e4336ef7b95557a3d72d384d1ecfd769fa108c74b6eb55f6eb32e89e3ae7b1ed6c1e34237a1f1fd334f3998cc5c8465ee97445ff45ddd1e66c9df3b889626e065e72858f3257e383d3195bcd5609acacf7fa7adc7ad2ebd3b2247605e6335ba6e9612a10b5e1c76264632b7b6c113ad8cd1d8b8cdb6f33cbef4e4ae36ce6cb79fc222425f4a29569fa109069b2df0151759aaad08b40d3cea9178744a0122550099fd97b778deef176fd50f1eba78b8f8a831588e231253f7b93a17b945d74479d6331b2d97cc19c37165fec059941e8fe9c57637451e775b1a61fd98c3b8b914ddd480b1985cfc2a60e42fb28e7f14c4804ab1af2e1550d4d8f2c46367e02c79039e6e6cd7163e6a037c3d8683b1bf95deaed1c13c86fabbbfda573f27a7e4b20ff3d3285b63d7576d049201bd7faec3ae8aab769dd76a88d6331b2198111f9e89cacad5a997afbdb11c8f8b6314abb1d737a1715e285f479eb57766f74ccb4af08e4aaf7c5c87e9bb1d58ebdb4b318d904292299766cecececb3aebd4d53880a857e9adc6331b2e91071ad57ece7e05b8b6133638fddebf2e833c2c7cc3072de344d93f3900884821779a3d3396375adc6089d398fab23f3411bd1c344b7d9bce748e86336f4486dcd626403c4455ac8de7270dd672b6cdb388f31d022adc717fd3686cfb5785d0824e3d5b6a1bdb4bae7f035f3907f0f176d96d77cf53b86a00bdb5e7cddacae56af375b4bb5b02c06eb738b42beacc245570b1792553759b3fe8f596ad9e43c4ef5d80979104e7eeb7174cbc276efa113c4ed0202796773b4f536befdde6d9cc7202a64797d405e861fbb317e0621dfc979fc1fca5337cdbc22df3adae2bbfcdef557e63c863fb6801c39bef5da41f61673b39b6290783c9364bb38cee66efddddb9585d1a94621ea7a40319d6e31a30f13c55c9920b2ae8efcacdde9566bffeea53651888a7c11bac3d791c2f51cab52327b993a870dc6bf6d4db7a285b4d32b64ebae5b61b376711e6f18b3e3fa48581740e46448adbdbed8f3d3d99cc79b66278ab9ccfd903e9f8b753ddb45db5f1585a0077cc8666f3df36963a4efadc579bc79d003d21d3ebbfedad93e1d759cc7905f072483b3ced5ebde1827e4c9792c438560b87bc837eb73cbe6536eb0c5cb791c12551c90ebbbf56dcdb173cc59e43c16c5dc48240b79dd5cded0b98eedfa659cc71bfb991bca72bf116021a7d7472b37eb687b66c879cca946a04d88ba1be7230548ca4bca8b9094fa45ea23d9c8ccd06b2c46364278c87fb345c8a8e5efb72ce43c0e4d4eddac491473a7e9435415816814b3598dc5c846045142b771d186937a3be793f3e02845a52525e54548cae6d3791d1281d887a8ea2c46361c80b23e6be37d675ef9bab9388f43ff79922e08e7746fb5c5ed59ca795cd9ff6a237a98c6292f41aa99b27a94e2324d33e54548cac6238b914d890c5c6ba0d9d780f3142c02dd14159200531a5812b8c2025304aca04015bc6303ddb91f025d400313a082023ba498428a0c5c408a2b1aa5f0e6391b0a60c05d052e9084921159200a0ba040e15a5b80613307a502cce3e91c5914986202f3433b2430f347aa88c01410d850f10051688aa638690ce880e954513880ab993fb2d9d1002918d03154dd6cf8886b0daa5fbd056c7628000309d86ca440c026c98c81e20030946703f3e9c0c0509e081820c60205e0cd87ee2644892605083000dec44c118a00a80880fdaf36170040ca13950666478e8dfdcc8d9bf0460325bca93a9b8d28c96340f249b0195028f998f9d1b0197d304001a4365ee0081fd20e7490031cdcc00666d480063390410c605006192f70c11862b480052b50410ac298495285c000519f18cf1114743830f76da5f38bcd094c500212181981a4a30966483a9aa0891c602880d4861860f02179200090e8801d24a96a44079248928402820e3c213d128a7aa8da630d3d9a207a981e64f4b05af448e9e1000e48e2840376c082c4811c70400c69118a901c6892cce2115920e2d3a158baf359c902491643b2a0408924652161f1862461e1052ccec02208120a0f2c7220cd7c7c4892261188a82e92260c27583880872624942a78acc1c30c28222a08ca34adf048398421a4dae1804254cc8c87026d409468f347664c54c34934038507caa72324824ea2094ea2072449a26207ca099aa2a2024ea02002af979d8bcdb7f84d19c8da8b5a56d946763dd218c8c9f8dde7bd60b35f87815cad39cea6abf172ccbe0c19977bfc98838d23fc66c9901de17d089d6defb5f802c9eebbceefcdf68db2ea02492b6c18977d7863f71c4376743a2b74d4325ff7e51043daf6bede8790a3b3d16b27a475b4c2656f9bbcba3527248bf1cec88d2dbe90996e42b2c5fe99efbba76fba2664e4ebe65cb523a3f4ae9909c9973e65b7b7c18e7e3121ddaf576b74d3c2d96d5e423ef7cbfdb3eff64dee6809c9ff0c5a0717f51befad847c37ce76935aafedce2125249d8e272fea209b4cdf2464d759f9dfa22daefa4d1292f6578ed6c5b6bf6024e45d8db2e59a29bbafad07095923bceece603b65661f21a765cf7fbeb8e0a5d61192d5be7fd9e4c9b339d808f92cb3f1da767667d76b8c90d1bd3dda8f7b3d48d91721fd397be7cf672b5f5a1521dd178dabf93367b3c144c8cacdaeb5ec22651e9b2142b69bb536b798ad6ca33d8464af56dbcc3c9b568786906d1d5aefe6f6d9dbba101246d6737e74e8cd1242b2c81ddfe30b59838b3b0ef9b87937bef7d1d5ecc22163bc4ddfed7d2f3e1d846cc8b7c5b6e074ccad1784a4cf5ebfceceedeae61c0819db9b2c5e7ee88dad0a0849ed83af419e75c23be31f24f3361f7f74b4b9c86d711ea7bc04892c46362c30f1839cedb2f5b1ad7b591fa4c74b1bad9332b6be46ee37e46d9451f73042e66ed15a01f11d98f0c1dfd1775a1983f4d5673898b821979b96dee66e7d5f5d534f790992c20d0993362adf5ad9fe7dea1a3664c3ba76ddb9afbb6e03fb0c267b90ec8cd558638bd0aba56bc89f8b3e9cf3d2ba685d1c4df420dbc15f347a9bafad852f4a1335e465bcaaebc7deadea6e1cd20224c5ae4cd3102129ce358b918dc919267990af59e85875f6dea06d95f3382482292f4152aa0f202922aac8e763545a5266422faca182091e24eb55fbf1a4eed141fa9cc77e0749996de62284ce1ca59529133b48bed4ad66f0ef7ae89cd641ceaecc7e2f76fb68ad7490ef6e4f7e6ea616421add03267390fd60843edf84d6a77b4b0ed2a34fe66b9f3d52bf1e0709d74fdadc2f16ffd566e120e36cc6ccdab61a69ac363233b4ba0b9337488f90b6f8e6ab2f360b997f98a421edacbce663c691d947a90b17dd5b98b841faabd1328b3e277bf33658039336c858a3ffa38dcdd896b187619b206c901056c8bcdc5b5edb83eb6e8ed4190292029b47292f42a6a95a839cd5a37dcf986b0fdbbd1640305183e479eb6c0f2bb5d6d1c7d2209bbad66ebb471a29f5478364d5e37acc395a5985ebb9c919e4740cb6eb7a5adbbaf96e4ccc205fa5b6b93fc75665ee1e91212665903c394e37a9b3962f7ded8c98904132c71afb572dfcf518da24d48f69b29f84a2f0814cd0e0dbeeaf1fd20b6f739cc7ac81613206d7fcd88b8d357d7ecc793c93840a8136949da6bbb1764e5367865e9849224cc4305fb5b45f5bac3de77d6854519e3a4d53e83d9e182aa4b21e17c2240cef3a5e70ae581fb4d13d189c7d733ab53d2b6cfef00b72b1757d7673fd66a5de9cc72ee525488aa7a33245c1c40bdc5c65cdd256a985b1b92e3c1bdbd23abd4dca1ce33c4eb16f9412d3e154139214fa4629cb45265cf8371facb71db37651cb792c1ac540d1888b8f4adb026c6ef56aedb9c6dd1a64fce69bd746e79abb4e3d9e59fda3d22030d1826ccb1a3ac8fc9f7d6fb61504932c4867eae6643a2b6d079b731eb766662c46362e265890cdba069d4dcbcf98f6e43c66579071c2bb38be7bef627f3d04132bc8ffa737fae4e8f7f97cce635705f911367ae15f375d7beeaad935c82c46362a26549073567693f2c3087f7af4782610b8e13805792dc765dd84cdcd27749cc76b39becdb118d9a4984801f2eaf62284efc1d51a3bf77dcf2d8fb53637635b6d1205e96e8b7771bfb7cbac3e108b918d8cc91972b1e5a08dfe1e3e9bd78251b90f1328c8cb3f5b651446fec93a4ea59f201d65dc3d2f53187d42a6448e7a6113274886f6e73bfb8cb5fa2ae53c8636860aa938c1a40992bdcba67dac27b747df5db498a669f2314dffe9dc3b231bc184097245a78b31857cdfb4fe388f3715ce783cf34e936b7d642d41da67b638ce18e37cd52fe7b112a43b07aff3ba2abc0bc69504e93f9fddc5fc39caacd6161324c8f962534b5dacd4f9b109f31f47c4e408b24e678f56efbecdb6d08701999a1841b2b35add63336be6fa721e7f189de8854911e49dbf9a6bcfd1c5a87d8b08d2fdb2d141fa66753152e63ceec7ae932cde5c5eec5a1f7116231b6b3204e9bc5ccfe9edf2377bbd0c132148e766ff73778cf673b03d4803932048369fb2d71c8b6d326ceeabc919f2363c630204f99cbdaf6db40d726bb5b24cd334b118d9844c7e20abfbaf7eb698e3846f721e3b2f9a890fa45b3a9973ae9741d87f7b205b7cd545fb2e65d6c1f64c30e181b4363ed61ada7676f19dc90ee47aba28eb782174d7ec7520dd9dd3b665cf368ff152931c48777b2783eb31bb22e3e7e2c28184ce5f63ef39dbeab3fb8603931b48fad839d28ebe9ef5d9e00e4c6c20eb8c2ebef9dcc15ae77aedb118d9704ccc90efbeb7dada0bdfe4781b6e4c6a20df3167a753da9c451b8398d04052d88cddd2599ff31856cdae99c5c80688c90c6074ce9c6b7f10765cabad685babf1aee5fe276b9cc7d3544d5343622203596f7d75dd8ff73d378c233089819c7f9bf9c6c9e8746c2d0c644fc60ee374ad52669d97d1984318dd45778e5f5bcc316ef1cdf687acb137a7bb266448baeec3ba38b63ae37bd85108262f901c63cfc50dd6875cdda10f4c5c202f75edbbe7bafda86537fec0640c392b6dd4b67737da7cb69939649a360c6d6022863be7b55c73ed357c9039b8daba8d5aa72f42cee3fa5564b5a413322ee7b35576ca9abdbf9c57411e259c90ce36666e578d1f9aa3209e394dd32446c926243f1a1bf2b51f1dfb47ab91688aa6695abce15a7562dc394d48ea169deeba7b4e48d933212fbdb1cec66e7d7ed15ac79890942dac7fffc218ed9b7665c3979014d2e50e2ea74e7b5d670969af853e9d9dcdbe52d69590df78be77a947cbeebc8b12f2c50b639d8bd955198d91eb570d48ca8b9094990701e4c59bda11813a1ecffb24e4ac8bbd236b6c424948e7e9ecff47d79e832ffe480192e223e545488a5b33288984ecf6565df48ece7dba2889f4e1a20510394dd3344d90c5c8268c1248c855175cb0dd9ef436b695f338446d440fe30c1fe347445f0df9f973065fb7b51c33c7d5f4428ed4fab5f03942ae76b7e79ad3679bac9df398ba9fc842d983665e5e63414923248db0b1fb63f3dd1779aec0c808591b65f4d9e95eb7858e721ec7182aa4521fe4b2796c11b2d969335bb718b5cfa822646cebd9fbcf5bf516991b414922e465cf1d72bf35bf794f4448f7e5fc6f63361947f74a0eb19c47e8abf98aaef16bcc1e650cd665dfbdfd9ffe40506208f9d37943d86075866f7e2124acec99bfc5bad967e12384847f1dfeab1edb743ae390f317736eb96773f6b21eea8628d154490192b292f222240534b99826d08ce9324ae090fdeee9a3cb32c83aaee83fa41907258390fe587baf7d9dcc7fc21b75502208c93f21b4f7576366cee683665e88501208c95ffd7f51870d99afc8bca9420920249c175a667eaef7f99b4c09257f90b5698dceaeed175f73c779fc1eca42d4104af45999a699d0342d1794f841be65b66e9b8fceda16bb73913ec8ca13de1559a3b732636f2624fa4817672a94bc215d64fdf74e36d763cb66737c908de965efda581d8cad35b8dc90b5fa7dbfdab1c6ff1c4e9333926962deb03312e656286943ce0a61bfbf8bcd7e3d1925fa6c28d1a7232a61433eba383a6646e9622fd23dc8dad6dfadaf1f46d8ba398f535e82a480a89016d304a242769aaa69aa8f6495ac21efe2ff77bfac46dace2ede70e56644bd84123dc8051775d6ef5ecabed52f324dd334239aa6b678c3a2cf9b1135753f9d2794a8216d63f1babecc2a3f742b461894e441de6bd9a3ff36ceaef7effd16519dcb8c123cc8562be5fae0ba6e417fb889d3b4d9cc696290c5c80649c91d2483d646da5f27eb1669b483bc953ebfeb75ba66b7da3a48171964b8ae57ea3532ff50d304598c6cc028a1434718577bee45065d2f876f45c6b6319dccbd2ea8d292c24222d01c64335fac358badeb7cb0c941aec8d7c26e8bcde96f31ce6318070929bb93f6b4bc22abfd70906dd6196d8bebbdbeb0716331b20941c91ba4a55eb9b11aebbc0c574d43062f4252364d038d23649ddf3e46c7ae1fda081b21a3ede9bcfd2dbb191a46c8c8eea3b4c50b2df5e7e822a4ab8e99f7b20e6173c740a3084967b5fdeeb17395e1738990eeba375dadad5dbbd5102161eb0bafed09b9aec9da2124ff7dd3f5c7387dd96a08e922e5b7babeb5dc72ad0b21ad63466f7b3769a5712d186808e1bdea8bdcdc1ce1f78cc3c5d68dc1c8adb1e7eeb56efad6a5ee3dd8e87c4e82060ee9ea5bec5a7737725bf7721e6faa8dfd7cd556a019847c666dc1e7bebecd5717e7f1a713f3a4a011847c3376376bb0d90addb46ff10d348190ec56fabe3d63ffd673721e57b5534dda0c9da0018484b75ad7ec6c43e6f15dcee3c647429408182f012841f307f9f8adf8a2c3469dcfc63e0fa2366f0a1a3f48db9a2db7dceb56576bd5e480b81d15347d90adb2e50aadff7d96b5c9dd469a37e48b7ff9b6bbfe3d5d35721e579bc62548d0f081a7a57143bef59e1bb4f645ce63c647d0b4215bc3778fb6ab76cef63c76e5d3c5345547288ae3adb5d6dcdddddddd19638c31c618ebeeeeeeee66666666e6089f6bce9a81a4acf780462f294384a42c6631b211800e346c48f7f6359bf0d9e9cfd5f620e3e2bfcfd56b3d46ebb8d9e84dcd1a92ad2fee3a6f63ad3646f520ad3b9f163e74ecae7b5ba3c6f2e570b1079b7384f1c566462773eaaea3f63e7e1102aaf8bd409307d9d3be6e3cd9ecea98313c48c69eb7fb6bf6838e69c71f9a3bc837db337e34fea26ddd0eb23a735e8fe9a477cdf60e68ea20ed73cfc566975d66f05a3ac8fa3ddd5747e6bfdeb47390f15e66d4c27add5bfea61c66f3652cbaa6d4c541def637c2e53436beed3138c89eec208cb3ddf6e3c741346f906cfb7eecf726cfc830529f4d1af2b5b61c6cf3ad7aafabd70dd2adffd7cd93da36c87f7d216dcc3247a78b970d32b668a79bf4bed77adb5d8384cf2efbfcded76c9dedaa4146660bf6856cb548df6f1ae45d0c23a4ccbae69af58b06f996bb95ae696b3357d73d83a4b4f65b77c1cbf0f6bf19a4c7199b7de7e5e674fa6590917d652dda66f6b9854f06f96ebd75dac9dcc70ae1a3212b5cdffcf15d47eefe31c8f90e63abebc1d8dcdf8a4142eabca67f43ead1551b06d95c5c3fdfa37ea1756ac120affde6da8d6fbe38e9d72fc84b678c76c667de62acd50b923ecbb4f2ec1b99fd58bb206d6d8cb5eacb7573ec552ec88e76b1b5d3f67df55ddd82ac8f29336fac6a41b265c8bee9ab1f6d8c340b92cee83ef247cb20a38e6241ba1aa15738bf3d63cbd12b48f7e2bdf0557bd77b736a0549ed62a6edec73dbdecf2a4846db32ebd6b3d7cc7d5241be5358df7c5fac7ae3390519d775eea96b8fe9ec35a5209fadd459bcd4b5e7ed4641cef91d6775bde0d7f6ce9035fa85f0d508e1bbd7452848c8ce27bb6af92db72d3e41c6b710d6bf3dffb2d8a213a4bbcc42a6def4459e2b3641da47e97ad0ae09978b8f09d2eb8490f56d0f2e415a7f73ad1721bbf3de0695202fe409d9196de7983b4c82646eb3ce7ed6dfcfcb201264b3f9bcd9fa864790d1c5b68d56462773fd4690ce1bbbf894de7efab408d2dfb608e3c70799ad4904d9b53edbaaa5add9f8e21064b53ee76b8ed54b2f83429097b63b57d7b7af36c320c816ad5bfd2e7f9bec1d10e4ac90f9b6b37bcc20fb81bc6e3d325ff7e9a48bf94032e89ec1f72e75ffdc3d90f52bafb69c756c35ca8f07d2b5f6eeceb7dd4819bf1dc8f64ddf23adf6efbcebe9404ec636c6c9de0bfebd3990b679edba66a50d69b338900debb2eead577703d9ee3eb76d5a6add84cfd940fabb5f6ffd67f75b73ce8cda6fd1afd0b9d740c29fb0b27a978dec6f391ac8f6ae5f9fbf9beed29f81a4f02b6bcfb1177b95817c7ddfd7357945b89c8d8174cbd8ec4921bfad0e0319ebfc6f6fc50927645a86f4b71c4f47a3c775a92343fe5fbaa24f1a6d6d97db0b6465cdda36cbfc2d57ad0b248dee35bcfdcc3563c8bbd8aaae27ab1ce784ae1143fa5ddc225bff1af4e8bc13f231d6e072d6debcce35e7847cede8dbda70bd5ed57d1312b6ed78617f378cd35d1332b6d7ec3ad8d5bd789967423e6be3ebf6d31b42cb1c13f21d73f5fbcef64bc86967bd7e2f83cc685f4b4867e17ff7476baddf5a09f9f7bdbeeb21656e394a09b9dc3abd0e7a7bc70a27216f3fdb9a316ffd6d1f9384642e3a73cae6eafb5cb348c8fbb73e67f359e7e6650609e9bafb3aeb1f6b3767f608f9fffd6ddd9d73b62de608d9dc3f658d6ffb657b1b212d85ebed5a333257fa8c9090619dff6b45d61eed22e4735b8b5abecc5fe354846cfada6d77e337a77176222465eb229df0355eb3672342ae49ab6dd0a77de65cec43c8c5abf6834d27fbc9b00d215f5bd6d969d95b685f77212474b4ba181fe3f5e6432684b46db6dff65ab3f5b28f43d246dbbdccad166be387433eb62c9b0e5aff87d10e42366dad5d6bad20e473eef2f4e8de318d3110f2efdbaf8fa3f5c72820e48c6eba7f0b36cb6dc23fc876aeedaacd9b3af3e60759e16567ecf274f7f0f39efa48369173f441322f8f6ebab518f305b90b39de9073725f9eab3666bb32c879cc2c0d39f8209f3d5ede7aaee777bdc779bcfa0b39dc9097327bed2edb7541db57c8d1867c2eda6efc6fcd79a333a79a5b8462b828401672b021d7b42ed6d77cb97563b59cc7cc43c8b107e97f9fe1b4eded5ad5ddb5de629aaa14205ca4ea6ecc626463801de458433ea73f2bbbcfcf1b7cce79dcfc1239f4206bd7e598ffdb4ba9c3c979ccbac83475403e9ecea7936eeaeb3672a821e18dee28ad2bde08b945cee3694a22da7cfdfaa13e33a24e10d1344d53354d4080cc70e1a323aaaa8f21326d804cd334d5ce34b9223f3621ea6e3cf5ed34857ec30800478e3c48e71832ff1bdfbc8e617540c88107196df51a1f8b34b267ebba83b4de0e3aeaac33c86b393bc8e5ee9dbb8bd55e16610721471de4bc17d267635cfcdcbf4a07e9ef5683973d5cd6798b73905c9f33b57e7fdd385ddf20871c64ac77ddff07637d74d6fb221172c441fe6cb7cfaf9baf3ebf8ef378f3e01839e020ed8ab3e19dac2b85eb43a056418e3748d7adcddb207ddc2b726f380db95ae40bd7a4d429576b398fe1e3400e37c8656b75932f5dd4c55579866eba3f44a6c9c275841c6d9097c1fb1c63af45ebd41fe7c9e460836c7575f3e8b1b24a1b6d1bd1c33c167d9098630db2f1737e6b756bcec5feaa417eabefebfb6c0e7fd99b06b9a83b5ae3a37da1adeea241526e7459fe37fffff93d83e4659fa374da7663f4f56690cdb3f931b33ce7b3d396415a0bab63abebaa707a5b32485ef3dbd5699fa50ed9a221eb9ad3ad6d95f6dbbe750c92b5f77c7dde39fd2dad6290b12fdb7fb4b938b9d21a0669179bcb2984ccd6d6af8241ae3aadc73add3bceeaf50bd2b2ef091757e610ba55bd20ed74d4b2f7ac1bb37e6917a483b6ce7f2dde8e943ee582b45da3ffe2c5fafeb2740b32aec8625cf6368dd629d582b4afed6b5a5f73cbb549b320a38bfe91f2adac9f6b140bd27eeb369f3b579f2da35790fd2d7a5dde627c0b32b5825c6bba8eafddd51cfd45ab20179bb53e66deef61a4930a9299bf76e7699db519e714246d6daec6fe4ed6e6d32805b95e83d456d74ffd7bc628481a1d5b67bd315cb1bd78866cf76c2d7ece277db52314e43f87d7adc77139641c9f2027d308fbbd06676d6b4527488793c6f7decd9fa50f9b20e743f8d8f3e89c65944226483b6765cff432537e0f2e414ef7165f7b87b335e7500992bddeeb7132d88bdb7d49909399478e70fa74bdfa2141be175d656c99df11a4d3a68b3238e9f5690469d7a2ad394bfbc6d56811648c8c3a868d3173ab3a11243386cc9e5617d7a3ed86202fadd0b6a5d3df53674d0832bae560bb752dc3176310a48ddc6bc1bf0f3a770804d996a3cc2ba476adc6dc7f20fdf662d3ef5bee6f6b1fc8fbccd66b117275372ed6037919474bb93a7b7651ca03795f73436bdde78b0d7b07b21973e5c8e2ac1e2bd581846c9b356df3bde5eb9c0319efbd8e3fb275f7d98a0309e1f467b13d7803e993ffd6cbae8dbf9e17e7f1c7cc8faf20870de474c7663fb61665d3a319b2df556be7d7e991d25703f9dec5c9fc60b3fb5cbb349090adfa1de15fe89abd33901e9788a864f0aa959196a22086310010425949150063130030302c1e8d86a3f178a2287af203140004597e6a9a422e124983c1500ca3208a82180662100008208410628cf14a116e00c03ef6a440347b8ef61d6168e8db8d0df74bf5611d510b68ad2dc4e0fd4d8a705a5d0d20b5810f42cc59fd9f4544d406b19c83a5727210ac88d8bc7a22b7f22c74413e376766d43f788a5fac2fdf055a20aaed78093242b7db8e7c7791f20bbdc6d4e1d1c0af715c1647479b78593ce764b6f93fdf909a5f5470cd7fea27029f280eab52b3137df15661e3323b8ff7015830f651a7273da49283635c46bc941e5f330b5c53695aa4c414c740ac11cc8cf434f43e3b88e4e300cbcf1b5855b61443e3b7cf3ae2f58cbe3a857309bbf341814fac97189f5c7dbbd563afe96028de3f4d559c637775ef79a3917c321f061cf708f244ab71818e38d3693729bbadf51eb454afaaa0d78a3f4d96679d2e21ac2a4724c040e4260cf2b64988d8840a4f118c18df8bb57c4b12d0f1378c3da0aaf7845d991ff3d2e20506a60f0aa374a0c8efa7fca2a0a21527897b47f660b144cda256ae37b42d3e55cd014e24343b0245cc00d7683431844a4d024634b43b04256600d928b43186524d014344b43a0635a600ad515aa79145472ba4a62af3940685bac813d562c2a15454487a9b188e64b508086641d025fc6b50cfeb6ff590124f46d0febcbdae95a0e40be251b52f6d3c1b83e9328941be548d995566b1a4bacbc4fb17900195418442a82bab0fe602070a2030b4eed4f5c941dd598cb823f387efd4d4632b82e965e5d48ddeaf1cb73606e2728a1388010a05ff86fe03848fab7cf105a2e4006f4b5c860909ce6cb43b4223b61ad1179b067e396222d21b4b2fb206a21d49117b35622ed207421dbb22a26e4e92315b2af3bd8e0d743812230636e22eb60c9c3ab2a2440bdbb494cb10a390de587a252ed413d3d1fe6ff0381dd8e5b83a72928c8a309d4fe6985bc7bfc47c0397c5f1dbe276fa2f2b5ff4b24dac5c183104e9264bedc585d4cb8a6f1d058ca38db8ce6e276d68cbd03a55b24bd0f5d2245eb95cd7fc4bcf0aad93978332a153c81bf241fd5a11d38da48bbd066e1cb1474aeaa8c08413c8ccb8a5ff1bcd97b5b4daf0a490ab1173b17d4c28bf2cb7e87f9bb272156230d209961ab214a29b2415dbcb2d9a5f38cb4feb8525bd6b510ddf74b7417f656659966b0d9b666a9e068e85db46721620ba2f4a001204182f961cef46f5396b295ef6f0725dcc37df84e951d1da2c706a31db74f290f1fde9e2a18c31dc6c1ca3fd8cd71ea7da9dbbdcddb6d970c5a861734295122e6558f85afbaa0ced3d0e494ddca948262bb01a15bd7ba69d12db681ba49b30cbdb7d19f28eb2710b7b85237b6b0e9d4bde82f1c80913ca03e9e787d9c605cec4ea6c6783853117b6c7ce70855075dd0ab7eca674514177509eea1601f155d06c868f7e9ac0a2bb4a93744b2c62e552a7df82c7c80e9410c6568f1a106f5926ebb53c43f68cca8287dd6264cde7ba3e28ed5506c217ce7c270e662b2b5907a87fe8cbf965efb3b7b4b5c7729ea531371476482df40841102bfaf61c052b0f0f36752491b2b48b4d352190a2dbc7847ac805d697dac9d4db56be954d37ef10cef6614f290e60e834e594ac79483a807ecc9167e8b4e7fc17e64d6a7197a7ffb60324d2c0f265701d05829a8c5336af89c889c2e384a5052572bc0366cc4b3f92f636866a4a0ba2bb4e41041b08b68d12286dc13911d2ed884c9befd5c8c24c76df134c28b0aefdbe99986f8071a010630bccc416981aba14c7171b16bdf4baa4b93303585488bca03c33f1fe37cec4ed5e7db1cd7835346c12ffd18a84c2146237de06cdcdc199f64778ebcd2534020bf1c675f868d73e0457b31e2ec063f3fb0a85487dd6f5fb2fd7689e767eed5744420be03cd8cc05d25fc961271803032f9c728593fcde6332a54317018b5a471ad5e0677b35288e62d90ee373d126c2e93a29f3d340ac41f68f323ae6e2f80e81b27bcb68aada9e470c4716f437ef848369151d5cf6d460e9a38c27532573379c0dfc3517c428f52d4c94ae18c3bc42254650002d2c6493ba240c163a89265f3d0fe4f44eb282f3933c701949a201f1c217b46b28d8f5f9340f6559debd6f3a3d304a6926664c1c7740d4ebe62c7e155015dcba450bd716f65abdc3fadd02458bd856f5b550c362b9c58c56695bf06b51864573ab2e5ad8b6b8d7e28755e416315ae8b650d7ea1a16d32d68b4e06db55c8b362c9c5bd868f5b6c55f0b342ca25b55475d0368f1440ef9b59d3bde22f31d0369abd85d6897557dec455c4cc6a0f8559e314a7dd11cc36957b5cb6c70c7015b75b281a61ea2d4062f8d92666d82865b3a2cbf715deb6b0cd46144d7a1ffad2adf582b639a0c6ab5f23da3b046c3335cbed52e8d6b32de6aa03d6be437b4d3509f63115927af415d07ff1a85606d26c3d91b16695c36eb171bc86dc4df0d3dbdaa93b17e8d9977d0a5959b8c626fd8908db0ce78dfdc349ff6e9ba2abdbc22ab74781919c3ce111c1ef12dfe652bec7b42cb849dc1fa7340d3d0f77f6d6337f7df82cc9804a31b7468715d4016c709787d4f16e4065c7fdb19eaa279bfa83073765a6739bf1351e54f40e22a2ed8f7640d0d477fa262f489c1ae543fa3dad1213ec7a51a841cd666717e315c756d879077f10f392723212f29cee423df9a0c0bc3faca117b65bf562bac05247f0d95d89e1da5722ffc705194fa79afadfc08b0004faca5e3497d63ae05195f38e2262756700962671bde531c050685e24b445c7a0a995f26d17990d010f188d9b926e1d70e778b0f1e1411ccbe087cbf73c6a8274169ba76a8ed86ea20f28f3d7f27e94f2ec26f5cc5086c13f48d54e9f2bb5f0e7aac40cdc85e5c5522d0d07c8f135a0d67d9ef80b87cb7c8ef882c1dfd379e4b1ca17ff286936d98fb4fcbfd43a428c3b888510f14cef3f8a1228446e62f3ebfbf801a18e91203712601f84ebdd7b4c8d53ee143988c3ba2e7cf07f0de2e122141d06a40c9bdaea3c5d667edada6624e0edd34b520922ba36ff7db796b15cd379c03b7eb0cb5923ea410a9d47b0e2f223fa4fbd6e450354e7f2504f4df5cf4e1ac89b8eb197ca51d44e6c78fe0d066e627ec8ba4549b6f0a72cd04ebbfe59cf1eebb1e294fc75bedce8f02c3c5ce6769e661f1af1366453ffaea09e3e2c3dfb8dcfbb9def19990f05124a4d3bd87cfa9959ca9249122ee17e94c077ba424750a2a93e1fbaeada94959aab5b77616f436a9c6f788db4ad2b58c1a6d0e684530461ea6ec69e43b661f939b7b3cb02792844409aee219971f726fc7e7d87c8991a18a7adac404bb843238f551c28e41c55f69e772ac4eb54eb212708e75e70f176c0addba40d31567ed46f177816bc26d2282a95b7ef80148e8d3b689cc47ce52f679a1435fca2503b85ef17607876b7f92923f06f74b9908c0cc0730b031422c631b3e7a26ad511bbebfe0a908d334737b839333df9933a4b779edcf934dc68fd7432a623579ebe5cd3188f5d1aab6bf1ce093dd198020139c92dba6a4850e0596c1f317978aa487884803257c71fb8e8bbfcb2566fc88572d71082992bff27a380da0e51382d7f438f4070dd56fa239e89f7e4888d5c9ed7685e2290dcdf23aa6a8c02fde2cd94903d347eb7033a77246c998f064b19f922b17855903e69d553d04a0f6713a78de139d6d1ceb4694ce727a5c27ea06a3249a2e2a559a6da78357142b20e0089356cc31a9083ae55380fa68403147bd78ece1123224cc9f5dbfa4b07e09f8bd21a114249896b4df49dae845a4cb3cbecef597936000d8be25cd19e5b88bef4a557c398606e21965771450f4a5aa10597598a6fd4bf570190c308bc353d738c6f7891c4f12ca7b93a81fbc00505211291fffb4fef73b01f66eaac5a1bd1756c0818ea8abdee109d333e504cfa007d240142d0039dc1dfde81437d3e7add96ce88716644aaa3e275acd46d28fd9dc73f345f6b3f66ab40446a8c05e06ddd0845d07bc27f6b7cad87d00408eae632c5022bc42de5f160def1dc433bb5fe55d7b31e80aaa249219f58926c5970b2ab480bb6f8faf43ca4d833d97708dd997e0897c4ffe2efcb8f305b23c2015a9f70502c42bc0e5242403c3c90272dba7f8fd2538604a5e6221148eba4566f9af324ef844bee428366f32b279beabe6d0ab7e9c63c7dfc2e59e9281e8305eb71f0391a8aab77a1fb73db179e58d100ad2b09be65dddae58f344dca000f71200e27b63e0e7f9563481aa3dd2143e80d118a5aca32c02782db66e6439c9cd38c4fba064de9bc0de147522bc701f2e00f04212ef34ed702e017b623e53f9e48fd659da91e073b3ae75d2861cb3b41a77770d3627fb83aa75a2e88907482fd8586f69c8acce86d35a3b515a06c59c3e1e16c5944bf4e1718d6261d46e2fec908b569dbee34e195b6d751e188d3c60822849889cde55ad4c92d74111e0ac2b65a50683789c797e0d99f3b8b9398b744d2cc17c366868104f1b9f9db742325431149ff2546b7a51514829021be68331d8dd47b31d3799476ea3020419016cdb2c37e6a0a96dd19bc7e99a554f2a2ca1227f5db47b7e749526c9d65fee40e3fa2d6c0a6311e014c430a0f3220de787861ea4478eae17993b2ed31ec8fdd1ca7884d399f2e31fc8c9fe12c6c38890fd6b190bfa1341e63dd6f167abe9986a0853e59c434b30c1582a5385524445e2d7beb7176add1b8ff3d1a26b790c03697bc14646b4429f71eb20ae4db9a8e6b2d5d05e33fdb4e71caa9d35f692746242f49b6ccf5d44df5fd1011df591a66e3b9ce474156ac66113d8332499af1a49a1bea188fed2952c70de93d1b7779edbcb4c5e51b5c3816a728bf0308616e637cef76fa6d26ce824c5930dcb0dc1782df32613e8c29dd89461967585c0073f204507682b1cfee09e7cd246e0259b780afbf3fb8e297b2df2898245b5ff37a816a148cb1c185a76798c4209ea1a6cb3bb71fedf267553e622a49767e724aa594ffe57652577ca2036b1429cc9e7a528185d4302b9dd17fb3ef69c66a59620a9ead454d36ba99a88a8b94b1ed22a5677ae3fba95d37a179571f3d4ff693c1de9a1a36bba217ac15f026aca5ec0e28188eaf2cc243f89bb9591c44da6b52e9d773d17112fd1eb4b9df655206a6b87a074a0c55fdf375e319590e62e4969c93b0e254a792ee253a25c9dcff4d506ed53961066aaa304f2b18d2b4f965137a6f668f9e2914cb8b78f8590d852023ef7afb80f030d5659ea1613b2dbecb41277da0def3deba0051b1f5e71c93259b7dedb64d844c61cedd5a8c377739bcf408afc50546cab65551eb3d8615e6f1a500fa5bad569a772507b12a557abbfef016b4e869298811cee56683b7be466088f2050cfbed4cd922dc70c3753a04dc841acbf06d11da42057d57e45f57fc304edf0d22a84a55d982864e8c754e09c40aa1fc9e134d83b965702b8a48bd9075ee7108fe36a68d18034e3f5bf1997d1bf273880807d32fcd6487bac28315d286ed401814f921de50198bc57604ef4674175d442492f921d0630d261ab364cb8057aaae69a6b334aa85d99754146b59264b6cf27be1b87cf894fa7fec72f3d4be3dba0344647c0dcd4fad9a0dae4e20a12947f02c2f33c9ee5110e8a83a04871538980d9dca4b797ecdc32a735a53528123741455be5d05e27968fdfdd2cb8f81e75d2d902be426a9ce9e718a14bf41134e6e93b4e3e0ae32dd9e1bd8cc355dc6c58095a4e90d8b3169fb0ca5cf2c76dd4b0cc5bc19b54665370d63e51191cf0c7863d68ebbc1f22335fbd4247b004a43ff3e5e398e32b2b5b00fe91668af55a94639d340bb836564cc5503e18b7423fbeb9204554b9b41987bbcd82afff1362d666b76baaa3beebd58451579bfe256c66c5291132383fe50a489c041394b6fa2501b98b8d9ad5cfdc79a3a7172817c0be07f91154af6125638cdfa772e5390a4014952440686d30e572d1242c68d4fa8e1e4c381e1c461badaeb023523944d8d49a3599240faa8fa8462137b89c17a6117f2b3a9114421b9a1df747148b22681bbe9617c0a6647584499be813f8474cb31fbcdca8572c269770c1fb721ed75c3be1d0bf36bccc99d533b007ba7f80ea2035f5c5587f28bc08da9185a7e80d62ae65e90440ea2df604b2fd2b747feb45eee25eeedff5ff7228f4823e108e7506d4b0b8a864065686a2fda4f6b056480ad750c41e436abef1444eb1201061109633e14a99f081d0df7ae3ed84a69f8ff8095191e9f35e7a936588e3bb6e518b1c8dd5520ad87c6662381c920a44b1368709cc922e0763574ad0f8a5e106b4ddf2cf90331013318ce0698922771336c3e778b6f92f8298132ed5519b82bc9354544ccc3d8413997b4e641973c296e87ace7f9d26cd58a13461fe902626f4972106d7c1d4b87e6d33ef76f8a840572bd0762a0273f4beb07e74e48e481c7d61f3c6c54e758dab93d8525966583625153c95e472d537b64b9a4f532a830b43043700aaa39c8a7f6e54bb1f3185200f12e9e24e31a827493a4bd3e44849844d0a617b77304829c986729ec4b6c0b0fd58e2703e6fe4d990328d6c30f0ca073a0c8da671939601005ce50221ba2c4a5375e525649a12d86d8d6b67dd4dae83d82f2d4e519410a4b7285480feb5919d995fe3bd95752841aad49190b4d809316bc0b658fc75b9979931c9eae19279e5eb6fdfca417fb9a9f6ea5efe4ef1a370e67c68f2e98a3695be1d099f8731f5aa5f5a14b534368a4c2b4c7b5b6b542709b4becfcafbb8e73e6ce0f7e61edaeed2dd28736ebedf03e8132c3cb8f3c917e0f95cb08c28b3c93fa4e1a468a4e967e8058ed173fff9bc1135503c50e7f6aa0b6a80cf1941a4bb1216db06d8a5d9387c8451f889420a5b9d78485512e496d262e2c170c11a5fb88abfe294daae3615c6234a3b443ce6b7ccf98abe848e7cde138095329f9bf2f591a577b1954dd07d5a278048dc3eb1a1ede406bb26b7b8def94b67fa1e91a49291c11225936b163cb38a1b24b1b2504ae35ed4afd2010d96493f0a2e8c791a596fad4dba977ade6be75e6b32d8592363b0936cd8f9e47c9e3a6addcfa17fce0df7b885d27a64dfd6d8b2ab779470afb259403799c9e50a4e2024d09b92b43ce18776002c5799925932a561ea3512179400436170d10ef6866a5f2cc22b97c81cb495ee77379ab21e4c2c4b5d150fe7c5327dd6bb1ddb9275bd95cbfbd760462a798f00a2787c4366d2942fa8c2a779441dfa3a40387e1b5831698a9b4148380d157dc25f9186455146cd767dbbf4b858576b03dae235e5e9bd54039e34f55a7e26c60b1ce8a51b4de9c0d82fc766a2d032de07011ea0732a90431bac4dd5abed3e11979e3ec6614d12041bdfbcbe16e01f370e9e2c3887385e0ea7f50cbc3cf6e4f2dad01c243cb7bc6267e100b6c01ab62b2f0f0367287fee581ccde8adf52ef81fa2a5eadebbdbc21888550bbbf25b110b3e8f17720570f2421e5ccb58b3c687f050a20eb9f853c9d23bc9e2a2c6a79994de238040d1dc7a0f266158d08a800eacef02346932bc301f712801f068d24a095192310014fb0d1723eff46c802169607eb100908fc48247546758569e9f109b1ef79c5c4a72cce6c4e8c841a88e3b278426c307c76872285f3a058df5271786c874c2afb1b2f8b1fc73bf7d72d1b341c6585f8f9fade1b6e5d6bdf442ae84a7de9d14c82a49bcaa16aa217dd2a1b625812c352cc0ad60a958382702c2f6903eba36872d22582cffec8d4885a1f7ea2a8c21083effbad3cf83d14b75e746c67a69c74fbe61d8c6be7e5455a24f92c671b98117011c1ac04dd9afb756cf440606a1ac349509f3bdc171f51fd526b06fa21d41a74176fc92029899cbdd311876cb419644facd1d5765fe24e06926bf1c2a3c5549383c287d49bb9340eafd09642634eef18504e04ddf0ccf62b06bfc0455f1c52e2978cbc105507d43c5d391fd6e60e243005886e9082a488c80f09564067f9329d546ce0b47435484e53bfb8a3010bdd463c8d4901bee7d2d21222f618e5714580eacbffe81fbef2739c0713a880e8ba7111650da432a158a6ce78f77644c1ecba2cf34915f50ce62d35dbc9103e0aede0442700e43935d1732f89e9816ddf920a10589d0502ff690d3e25663d2e84f49ed758909865c01fc44c568d0b8bba6e1f9bf59e56a146f1dcdf4e4d458e841d5836a6a57c2ae2e04f2f195093c09372dadf73ec1ef940daa4603f770d4ac65338e0f90cd03d758184879c4d17767de5108b0d4f22db99048f10f46f0d321284058a158a716c077093ca5215b380644d1d922e1145a7dddf716015dfd7499a381be17f4ab2ab9fae43d5db30973aaafcc5223883940d0d3b0a7833903c90904293c4b7b88c7e6a8fd734f5428f0a29c4648c418a6e0357f2ee9c883daa3135e28eca0a75e06b18b51f8081c452114027f1b64006c59047e96c200505405f048f82d108130e593f0190a0241d0178123e0b64200c7a9f2fb40a87ccf1755ebcbb25c509d595394aaae116e3932d53b538c88877f023f9863bf09f61898f179bc670cc5efec43c1f319c1ec5d8d737aac1a2286c1787242140145936f5397db79dc31f8626dfedff3101993725363c3246bbb538d2c454bd0a25cdb69cffb77f6130391dc204e6d7f6fd2bd7aaf37f649bcb48f6ebfb5533becf4bef2e5e4530a49a088f88fb1581d153fb0200621229d9f3b6f87b6d007c589f3e4b8241b5549fdeca443fbf6fdb5f3ca34f45abf8368f47e269ce28e1091d392f91a755e647abcedaf931fc270206837028b605727b0649f35f92ff79edfef7f31971628892ded4412ffe68702577d8c0a008cca2b21dbbdf19ab264a423fe5105c80880bfefb1b04635a45ceed05040a342edb74ab7298c817ec3a69fce4c638ef407b43a4c022839aa1542ef34c57aaa6f86ed755e9199adc08ec0cca900b9f9055148b23d931eb70a9594e72389e1e639be4641befb49b6283b53a6fa2b48a27bbc90dce3cb532319a6fbfbb9c132e1ed0e52ebd1d627472098d895c0fa10cebf8d7f3a3911e0e5def01884ceed6d2bd854ab07808e83942d3b37b0feeaef0f36f0a87abde0620696634cbc1466917b0d2ed67e70bfe1e5e0512cfcb27c80e8d7537cda2a9d93649fa61e2fc705df0b6ad3f520bd8faa12140f6b52398b8b0c503f11a6eda3977e60cbcbb8fa55b389668d5f6e258d8123608a591d9cd52dc24a7f7f8debf662dfe958de04526bd4a9c8c37b8c44b1b7ca7bbfff6357afdf6edf047f13988dbc4cb4641bb9003658e1c763c8fd206b96821d1281d2fee0be074c3b4b56a48850e09a8eb9c165631d805d85f6d238b847a676428dc9b04b3b742021d7dd890972be0a32abbc913558a4f417fbfcfb396dd189dde5623fecf9af4dda686518cbd2db55081fe335ad8081db398c83421cdcf230ffd96721e7d8d921092d617cac5a8bf4dc3380c0d83ae6f739318fe3936f4f021b45bf1a112c9167a48a04079b8422ab4e70bece405eed0cc0626fc4bb1e5a1cfedd31c74abfc41b64ec5b6a9419a002fd88959e72a605ed59206ae936b79ec0a9743f981e128e05f709a83521d048c3fc2fd7f9607042476c06ef5fabc2332c583f68de3c4bd884da90996ff53012dbd7e66ed4ae4ca24c7e5461b4221fc0e77752678ee914ec852658452bac7c7320bcd5c11f32b09bdcfa49f714cacb9a2076eaed96c46b1b95806c65e154516a08832d769fea12ed0504340d1f8799d77757b00f3a568fc137fd06346bde0d06ae1f50856b6c0d79c1ae930ae85c9b9ce4d3d83f6bed66187a6a6703346b27bfd6bbcb0daa3801ea1cec5af7b85a76c7ba94a3752ff3d6083e5f4ced826068453092c869d74847ed76ff96f6b8258b2f752d1041431af1d6847f51ad9911ced22d2c5ba38aa970f63c7bc28aa647caacf1c0db3a612a35d5fa9b74efc917b9cd8d727ecda576f0fcd0f92fe45e0be1fbcdeebf68f460d09511647b6448a2a791fe7dd2a392defcb3d7e461f68b0b42ad999d645549e2411ffba6f120fbac7af9c24e72d818e96a8884a75b72eff36d0e081ae6b030de0c3037d1fa22e8a99b29616cc7924b0319346d756f3ce9eb78f62d9fb0a6319845546cff6f395d16e19e0f370241eabb1cc453170fdeafbe019f0130e28814890900510e15cc9d3bf124b28bd4eb0018a8aad49acc320cf08d58f7d32f486ca56ffaa2c83b4b394cd1d5d9e39cb303ea2de75b2a3f5c7e3261a345f2a3919d2ebb0e1a873e9a76d568bcf8eee7649b5973acf71bfea9e1be04c6e36f387bdbcfb65e5efe2d1a73c70e79c9569724cc3fcbd7ced46ca039b2140a46307f86a172b558eac56da7922d72378db41c14ba8b0d02f70c436c623a01828d724342d000c5d6dc9e70f40013035e4d1c9a5559ef39bea42c5cdc001c6e735390bb9370ec05e99fd364b6b5068be035e66edbaa08b38db961fa35dbd2ab754f1f8dae74c8d07cd36520447eb6d52e78981a22dde389761af78e72d7bfa7ede68cc5cd4f175b5b6817119e9db4c71f2d4298bcd5223f37d85d72e5dedd8466ce5c0679e85ec930bc8da509be3654062107f0dbd5789fed93a1e2ff2398ad48317786135b7b10d3b8081bf62b3bf4e26f338bc7a38b8727e083d4ab3839bf8427135efd0d82895bbc9f9e5397b117beabcbdd403fc0c9f13006e2a699819352b73a9627ece9df07df6b4e93e8f8a3bb9ed5baff4915f9987dacf7a409549f77ba0f8e58b5354921994b0bf061a32ed41e3dfcf4d534caac4356eccae07c98a338af9245ae7e1addd5dd6c0c534431875f09cb334c344966eb19066d6b150b8198f40a6d66afe827fcf8cef3f3c3b2f3a31c992e11fc1fab3f4d802e4071ff7f1dda64cf41867347a4d25d98fd5557a34bfd07b77efd1796d92ffbf28bcdfbd3b8ebb38ae393879a8c44d60b8de1095c7462fdf67077bacc80117e78ad2c4cc86081f24fcfd1238d23d1d018e194e50f287ed4bcbc51aa836cff51729b9a019fba6ebdf979dfb7656ac33a5ebf12f9524af9d68ee00f30a1500ab688edcf2e495afaf7504a8e340e5bd8f9de33878933691f04c72feced32bbe92e301d7550b2217708cffbbe632094beb5a9bf23cfdbf5aff71d9d8556ecfefbd326ded2d331e1ad67f25f966e604c89445dd307500817c9c5f9d5fab86d44fa7ed2737c43d3782e759da40ad9e8418cbcfe50cf36ce4de3e479a4ac5e23c690b73b69f0d27c5983ba79f37d4d97ac3dcca5ed0dfcf65f11b6a7862decce17ed67689dda38a4df71563a9329991b1db0887b720a30f28a74ece4e1a96ccac07988f462854e67f9380c242ef09a8efe95a6be4c02706f8a767765b67a7bad4e8bb479482e163264db6521dbaf70ed6bff9820e3c1f850a06e9b37b2eb3ef95956ca3677c0c84ff827c61cd492197eb3d2e0f8910ffc73639e9fcc2978aacdbf453d307f5788445cd48e339a0bcd69e4693bbb078598b3370fc9a99ebcf8217dcbaf1e6df993c58d2450c4747bc637db8d7d6fda1a3beccc7b28ebc28e5638da8f94a997f6aae02aee6953dac94fe83a89800394ca57f00c68c63dadfc0476428cd7ae79ae796f362a21dacbeafe232d827ea9b47b8d88cb18f9ce661148c2dcb03e7aa80730bbf4b12c9b38e77db696593c1b9916ef633bd1bf164a9e70353d5d73bf6d4ba405b24700917aaa4076f11d10e9ef21268077620b0c9fd4075feb4d4c298bd85913b18d854e909371b241a2b4cb7b6bade9fb7fbc8dcb67f631955134197d30f13b7a8fae12b7307426f55ffe6c477d4bf90aa352da52402608ad4e91f14d414b0fda2cb9567643c8f6994a6a0d1704e7bbb38e9007cb4c52748e7b575960bd572b1cd338a900d8dc2f4b95a2029c99579767e666e17b98f2ae3e438f99c46a420404039b0d0cc2f151fd5359a1ce6290169a330b9f5c73b7fc705ec9831fe2b949869b74ec5e83adc3101a7a6886a72fe89a748eee48d4f270dd00f1e982fbe3da37c00062b8bccfef710dc6a81764d66f5d05906166d02da05b041e7fd4e890bd5fb63d717f5e03f6f8271f8e32fa46e753c073c878a0fc3d2041f4b1233e3f077e6e22b99265becd40641939794df96b46c6c78810fc45949b6054245f53ca2f71e2dc14f97b32007710852f07930f0b2cd3403c85cfb83e58e073719f05728cedd3bb2b3d194f96d3f0bdaac5fc67f3d782be3c84c7fba177c6ca61f307addeaf3931510fc45d31b9504ecb6baa7c2dcfe637eebd6d6203863f3fe95d91a5010dae7950ff0b6c14675dd77f8e2bd9b37f727af36be013e00dfcec11044c80db44288f783507e69878ce26e0a9c6e29ad5c8e0a181ee9ed023824f12035680596bb80758461dd835597f05605ef5756d2edfb8f1ede05351ffbc2752e1f3b016ad321a362abcd28e251fcbb663d246d1402f1e10990faf604733ddf1ecae3a66649f9dd3a1b9ffbd132d4bb1af11ccc174106ba9df3dff558c03489ec2446776e2e52190492e3677fbc865a4dec930d5a14d185ab7bc0284581a4b32fae82e1b384cce3317d7e8409fcc7201be49c10488e2288694d029070641f57a0f8142b559a5622366c4f91f8f41f315b905711d18a3fb5b310107d5d000dcd57a641e325a7aaa283301becbaee001fd693f2626aed0ddd517d39048fc4abb656841ed2e669be012e160271bb44479cd8dfc83ab08427e845060c849ad94db01bd5156a8de42c76f236cf1920e56b8f7798c61d1fef9a4588147b4dad0d3ddff7afc5bb02f4157ca808cfff53b0dd86a760db56cac048ee18e3b6d0887aec975dcf9c1aed39ba265ed82ae74101403e46784fc96f9a7af9444a96897f7a73e2d8718abfd497ec01215e841d0055022443f0d9ad14a05e097e12380a508e89c760496aa059c03ef8104419aa3f0292f801b06e1fe6c81832d45054316c108901d5428463b35885f8a87009726a1b3da1078ea367016ac071a0c6b8ec45154b369f48538087e65089ea88a4147eed153813ae0dca8722812429f1ac56f4503e04bf3d041650468761b3a8b56ab3bec12c0960d73d3631b9cb6c664d30b1b886b0d58535a0d22d42a2890e4319a7e519017c1c320f662000729470184aac04f835c000b8bd09f0518a0141500be123e0562210c7c927e0640a012f420f00ab85408c571e0097a9900c0cba003402be2d02329c68025ea6107c2780a84746a541044e419b9839fe63a538285e0e1ce0686965d0606c5e0fa05f9317632c0ec2a7f75871c9b7ff2569e640323df9a8af16a107e6382da6bfc5e59533c6f14cf03a726b0ff07358e2aa814a3fc686a78aef0fcaed790115fa9eb3264d024e82abd80d0f7a74acc55c46a8cdb3c593cf95fd08a08b6a659bf02883543418f71d2607bae5fed5207952f5efb13ee73cf597cb8c58306bb16d4c7f59d25c23ced72a6bd04b0ed87e2534233e2aaacdb04e9c0c77ff20235d952b1d9e69c8c7abbcad49ee595ead1070fbc4a5938bc1bb1b4ed431185dcd7b92dfb8d04d4fd0ebfc0aff2f17faee4309abdd8b1e6f2a995208112a5ba83d4fda2cd1491bc9e199bdca4223522bb30dbe198844c06cac52414a4b7f46c8bb4e74c9d4fc90483b53c348ffcf9ed89ff800ac23b2957a711031638dd9b21751184fb3b7c3924499647a200cf88888c0ecda7d14584a7eb5dbc02d64bcfc80eaa3d826c087a67e6c4885939f74f23cd37808172a3ae9b79134c040da756d6da5372617d339c8b5fcece04e71cd32cf605d7cb84fd98a3f5e10c6c844207c88f2ed27e838d0d243af92d9e7aae63909863d5493ce0e0ef45560a0eb9ae0243cbc74da16d171fdd1bee46a23f07c300cb726c60dfc23e271b623f185f69049fcd4921e50defe37c4ca777bccc8174fe80797015468743fa65c57f7937ed54214694d69028287e7c7552e976a23bd5c7c46f7f52d1b3473333e136048abd60f26d47fb65d7ed16814a7eeec98e44274b5229637ab96295fe0a579da178f26631d94cb012e0e1fa37facc309a51be243292a89d42412680d2329ec4b901747be18fbbb520f9a4f6e6c181881ddc5bd3f773658c9a160475b9b520a8cc5fc6c470c55e364bfe6263a07d44c8a7ed0a045456992116ba411c0caca952377d9b58b27d6758c597cc89ee5835f0848af387dbc8de13765e2dadce1fc03fec394a6d5b747e8040e08010ecb31ca4db31c7d985e7d054823549a65cee90d3d9afd64ff61b97eb7c079fc453a55c4d97379bc2bea3b92c6496a265b012a3d3f35ab0fb09ba21d3422896065612374eaa805ccc417c6c2f8673b9c33c8b5717b042d9e0db14b067ca06c4ad2f42c00ca7ee9faf87c7b6ec446f8243a85f218f4fbf77410c8d741d3b0463046684fb8e1af3991fa593d1693ac60d1ad5ab4e6b0982a20abb6796f9acd62ddc323d76d24f03bd37cec28fbda6430494361afd74eb3dac0c9bb227509b51b0cd5e4a4303844c641e091976e1bdf707114ecfcf919b0688038a73a1cfa39c050a4a4fe8c1403fefde5d778714353f6dc412f727c54a2c4a9180944588883af17b55f6644e906f7c5de55da56464604c647175a2e28a290ce1b284090410b8f990650c1da1771adf39d831f2cede93121b745fcb95b8a20d428103ff73d7578cd646f65c869b86b44f0b2be734b387fcb464ba2c3fc7b59f8cb0eff2c6e92e05f6cf5dcb173df2c5084ee3ca5606abf07222b057178d722d3fbe2e4f20e277b6f9fb3b4de253680b48adb05a8bde23242d1270b66989e17f365d2d3cbf7c22a1b11b52d023f1ea4119fb2aeefebe5bf7b7d949e8abd0e57048dee8979fa8f9a923689f5399e2691e91dfda84737a3957358218f174566e5a07857b28656c36f624bf23d917ecdb60b68fa859d0b0fcaf511b0deb591e137131542ccb16436dbbf1a3aacd7008e7237e8d58f9d026932331668169d0ddf7ab3a9c8d73c1fd305e7513bc7f12f2182f9b58bfdc36a56c6a6679f3ad8875b493b2c5bec3aa380788a6d35c4ce754139e74f2627efcba8b838ac86085f3ef65b12df9145656a71bef88ecca6ee97a02b79e2691e0e9036be9d6a3b10441186b426bd7338ce79e806733087a7b8f37e22bfb3247ba09399f6d696c85bea41b139e723c22f918fab56ac96075961f4b787ac1d0a70bee3736d882b95246ed29075db870b758b8e07e7e87e6c4852e3d9b45ead8383c59a08ac2851b403557dbc3b2237556e211e8f50affd7bd30c6203da89b9f022e4b267c037bbd31ca665aed9eb1ac7dc62769928695cf1556b17d16ed57ecf342bd483fff7f4e80db65973fda918844498c6fd469154941a01bb734d950e6b590129eb34626b0e3b2f6079ab3c41d6ce99f330d782e76499e23e6fdc18535eb0889759789ddd6b3a7af0a74a96a5fb37bd9a3c6c040ab2441f66a4d0ed1f14d1dedfc59af3f68d8fc3c98596a859033d7bd3c167e4313fb2d12dfbcc7067cd2308f02e73bbed98e412059b129f5a73fc6f8785c1708654789d09d28b46c747021d65f592833b9a7768bf3e2df0a397128f9f090b3011f5b5eedf548c04acca020192319d4c3f77d95bfd5f82ef1b2f96b37471c2fa0dc4a5a7c1cfa211e378e223b495d0f9cab91d85a2614bd1d6614dee8a37d496ab68538f788d73d28c9cc3cb1eed4a5b76b0f335c9fca8e68f37ea8d85783e7a935248f05bea224f1522797347a3ce77445a3434d5dde8e119f4fda400cbb37d91e6fd6bdbb6cbd441afaa21c1149b5fd04fedc83bcd6caf7b9421462761a29187c126ec80c68bf04de83339e9ab521fa28750d5bd8add669ba83d2fdec9a1e0cd0823f263e7fa25a3ae301731c4aa98bdea0d95bd4eae0e0630b73f315007b71ef4ef344d7ad62ff171abaaef55dfc82abf1d53f136cb859108cfab933036d3372c1e5b90d022737efe30c27f2e1c833fa655ee2ad5fa0cbfcf895e60dab807e3fcd3861b0467e3fb6f007658af778aa47a66a5b18ef77897989756c0c99461874aea86bce804951f47f86cc8e33da5f59f5565806f18066aff4ceeeccadb52e530849838132516863e7c44c6138f4f428cefd85952202805b7df9cff2fc7a9d502ffa304763b8ff578efc5ab580dc98b4b99fe5f090ec1c58983e340075253120916f10e6e496142b1f4d6627434094f714a40fcf3f8524de0ad21584b982bc3d74b3982e3c0647d59b471906934a7820f8e65a48214948b4b3f818b5af0b451b610cfac76ca0c2d301aa7eb92000a894793a057eb8020883764718075e0e2761cb025eb0b91f5387eb73c44c800038c182604cc096949dd392206804592ece1bf5ce6f195d83aeff758142cb7a8d19bccc43b4366ab5834638b1db7c2ba783db2722bc811b1ca4c61d0b14deb70fc48d8ab896aa50a18581f37c38dd83254d6510694daa145052c84b78a53020b2117168deaf9663b72d18e6adc5306662f1005a338e0a04020598bdf848894e1687f356fad082532d63e4fda3f5c796c836a1f2441b498767a52cae94b92207349714b4a7d3693e8b6f0bf7fab665db7ddb0fdab158c4141a7781c8a4c672f57838789925b812de7aee0f053ca88232ad582e98af92bac36f3943110cf07f96c288d3df98d8c515a29777ecc10c7aa2b976b2490df83365a5ddbf1994991e9ce856958325024411c9f7f78d02b50bfd9e73038af47bb1480d10c2729cea20cf4df1979f3535f3ba04f0b63c352d62230ee4e14c7032078026815295d3f8014b0bd366f2bbf5f91101fb2388f7217b072e05b41f270739d5bef78bb8a304265a9f32b153feb9dbf16be6046a15c917445ee7eb310b12b2871e156e0fc5d0c9c26b6e571caf9618b819e42c33a82b583fbb44c150ff333737b1439479f12b51352983688060b7c29cc260962432318a955ef92b2e811b2e89f6e75f20e1708b2022414f8aa5995ea3a15b13c25c6d4fe327aa2654b2798670ea8752c07fb5a47c6592fc2bf5a9a52487afcf7a2051d3bd53ff175527a0015553335aca6c03c55c177d9f94c88dbcfd3efee47bee84d36bb7c282354c7c0f84716084b9e754c3ebee02f4d027df4b08131311d05504f5c426d961a24e72e3b8bc0d717f6c3dd9a3991bfa53f4f2c448a18701cef19701eef285d252a85edbdb9b502b196ea77c5a95567de216097a34ceae75aef3c1360a84a8244381cdf0edfa73b0fc76958cbc2394c54c11417bf479dd86577dd4a8cf4bb52848bb9997263cca7bc9dd599ccee7d0aec1adfad55aae38cd38c5eb40dec8ae2518f48851129d3d7e38bd9d767b43158c59e3bdceec2fb327857ca6780227ff3937d393272989a76592999db2ac03af9261a0ae45b6627872a0e528b6ce6921c0e974678d446887821ae38a8798bcba3706348f6f0ab780b6c77f50f2dfb0ffdd2874a30b7a3ea6cfe38b75105bb34a7fbf39b482e9fb1eeeb700bd1a9316f6acdcd3ebaf6349460924e130856920974aa020d9c6295f11a6b1ed8dedfade8653233aebe4e2c0399aeef49169b6da154cc2471694a613ef60bf7cfbfd636dd1da0b5bb05b259715543710af6126a5242a6f7d4d7e324887a08578eaea5c8938cab7c5e3e4317122e7d08aade36614c01a1f5d36a54ba51abb90a433add9247384874e7d2e001d86c6600b85b2343b0f690e310b825873f91141921d9ca266afe4c63a244023150a57accce96947b3bcd3ac39125d4ee472e75bc831becc3c7c651aba627976598f72bb75834ab83ec878012c8355abe7ad876a2ef96c630fad84c96f710c1ae2f59613d3c52d38f054667c0d2a9259ba576ca828c9fd632178973386afb6e845c8a2e1e3194de0af1a16a4b04349c9d154a4ca39a3f8d8c4f138249e41d77179a99da09f9e4a73b64041ac16073472fdfa89d1ce7c15946595f0db3f9972484f290a9a91fdffbc3c114eeea4106dd91b89bb5f5f99d01323385ed83d1b5693733a5140b06d832977036e2d03721c7002425845bdff156c3f519d064e1df2873fe72a8375a50c6d5bf290249fa7a4dea6b840f0a6fd5a8536ab3238eea474bf74ced4771158a8c7ba1f32401cb8481bb0fe5d259a16abffea8f8ff1d15b0542122741c32088b7a705e96178daf28379ee9bc3df3ebf3e624962493f6750cf6e82009636c24f15cfdaa8620dbd945875664ce01688cbf318c2500003e9246495a6cbe91a0e0a41399b4d9d6c26509ace35442075ccf188d29dae494da195ae388e3a6c8bb29a1dba574a1130845468714d97f91b879ee28d2768960740bd49d43c94b0c002e93a52e3d07e0a447b26193ebffe2a10ebe0cd518d0221a2b118b3f6c170b0f185780880d7a2f324ae4e207539dbeb167b6b840281de93191ddc5d9afd9ea50838d8c3c64671047c4fad289d5b887889ab42e50731d16cdc1e630742bb263bffa6a56cd445766b26d1f7640f296a4bbac8404307cca0176f0a51f0d8983a0a7560f38095ae39b4f588d0de5ab01f419454c424064854ca8845cd36464300e277180bc74933ff8b15e0d4d47344e9dac182d686a1b4390bbb68b10ad57394f83cd480c4c50510e3c9038f56bd4d061e82b60681ee5fcf9a1c722a4e39c7c01d7ace184b9f2c38c8bfd5bd99682ffe893650c6c0f83178d0064a1bc2ee449e3ef2e71490b473eb80ec1efb95d5c3ccbf35fc755932528351aa6c50b38c9ae5eb58e8fa009b47be9279b5c3fd1bad68b95960841197d52ae062e0c4c865701f26f59ffb419571fc3c056cc86dc3607e4caf2406fd5154c064118a3482dca517d7dc6f6aca2acbeca999a3e5ad0df9cde74b1e9e728791ac3180d9fbe230c5ce73ebc309d457532e1d519a20b491f3c8282cfe2ca6765117c4c92de8c08ff9fd11abd2e5e1b186dcec0372c8ef3d1542a7cfc6a5344b15a56d13b06fbbcf2a8f9d416c98ddfe04d96a5d9f90d8c8e9e575d51b772302c41b3b16b9bc2ee9f198863f8f5ba4cd7603135dbc961cebfb34b473ed4a367666adf2b07e44ab1fcb10d4217441fbabea1eb428bc7045f6f1ea9e8aff9db94971de26ff960e4226aa964e21b8804d5536cdb05ba46acf8689183624aa0ef0465c2b963d1ee809379cbfd6a98831af3dd9d6629e3de56a084277f132b67c17717f385cda1566f9dd9a1daa4def780d35d5827dc0f6ac2639ab78f7f08a480cf18bef0e69e34ffe825884ea2a015fa5c5ad34d1f623f0822e9a15450cc367dd8078bd75b71002969a06734dbc47bf613a4c744006e8aa37e01eae1070041b5a119fc7e0d822e04660b21a16af8c077c59ec97d98f75350bcdbeaa548c3006da4ef08918ab26f16e1f8bb5bb88638a899514e0009573196ffbf510dd0981f02c61c569aafba7f025602aaaf5cbe2c517cef47a219feb00eb44119ba8b2df1109b655f1eeba3c4e84b80acbb2c7b5df040c303f311758e22928fa2ade189f1eb232d4940ac1361d17645ddee7fd893a1095d866e0d461201c08d3562b32ec556b2bbc2fb01db08c671fd1ff9a64d33d082889a0ad53af4d7ac0f02e01fc703a1baa7145e2e9123f903c5a185fe094233cf3bf18521960b11932b412bde418e556843bab311212ae173b6f0c1e11e2192d86b89ebe484df2f7c56215151f96afee4eef2eb1f225af644dc578821727cb4f28e19046c0a0d1be5c1bfa490fccb8ae8478d2bc424df6d34d6dc9ed8387d41702720df1c382c0d44bc3fd423cd4be54281e88a6da4192870c43c1f2eb7fa711fa4442a66543ac4f81e90483fc3b1bc5351c11557552732ebb7ef0f4022ac4d17ad720b3975029daf394684242fe4a03e94421608fecd0e51a0ecaa5d6e82e08485352503305ac470adc8bc90cae9820008abd270a8368871721f487a6c518603b7a5adf1d1111b2fb34196d35286003d19dd652f979e137d79ac4932d541ab2a0fc05855515bf0a132f6d5b1a3d2a21bdba1e6732c65f9d5304853839942e90184c5993db5c4a4a22a86cd323a89becb26a4a6de39b09ee77b798957db5a105c1212514d3470fe412d64979222d99c49e6114b1b7bbcf2a2531f5cded156292d56923e7e673d475040bdfc54c4b6b95bbeff75c686dc8f57d2cb7d496686e896635a38627e83c8de3abc2787f0b4e801ffbfbcf33628e816baed975bf2c60987ea3c6babc4c723c0f9c8cb91514deee9e6947246f573e4c7d773901e0ef79f91796abd65e0d5e732a3dff06a842fb4d2c9d8b8a7629190936c3fcf779fcf36f1451d55ca24194ce40fb5472cfb10cd51c69dd9a17dbb6ea4e1ed34f668e20ddb50a1142bfe01bba81df274a3855aaac96101f9ca0ddff95549483c6ff9abf6960f94b206c1caca4d548acd3f97588806bbf432f73147ea954bbd07f457292bca089de8040a0e69277e07e69a1cc9af124c1ec0318372cb8045ec7a52953c346eb8728acb1e2117f7c85401f322834281cfb982f24af2431b447f5f27ee579185f6e7c6e34579bb27d13f53b894f9fd9933ed8d1318bb06ccda1221af2236f9ef573e7ad68d6309f988a028ff863c275386c425812a24e18a80b07df91b9a316228a92e2da39a3e9f48213cadf61dc25647a16a2141a996a69d755cc458c321aba0c748f666112400d473d4c11617e70765e82832b0869b98528a33ef8ace312d96f3f4d25be8f2c1c66d07dbebfede4169174be0153cbfd9568eaac4f9ba065095786a87e5004f07fc71c085e2f5740698113dcef8f07738ebfed0dd736530d3931dccadcb8b772f68be37aac959a3ce9dff6180941f5ce55665c13324a037185720764f3737eb0030294b91ce519c05f3467e76f8164cb9dbd287e034b6b012f93816d221ad8f9cd68a03c2e3a8ca14bd40d79bdb1842e52e7cd094c7f329efe79e02981def22f01d1117b0650b0e04a2be79ff942c6bc751309fe40f7b7fbade6585f772c617e3c890c2ec07f980b16027a68b46c926bc8f205613c4f1acd35dc9158a4a6b136f745cda0901ea9624cfec022b8f034c55ce20a3b1a3badaefdd5e2602731221807a2ef05c68dfca3c88caeaeced8f973ea59828fc9b50b997d27caab83936ffac0de02e87b25b9e1133f12a90341c7df3917d21fa7ad18eb89f7b300c75f10fd712e6fb217bf36d3be4d8cab614ea644c026ec29e7f087a1e93e19bfd371fc035c519289a1004ba914541b5ff63d786680f7da09139a6397226c705bc6279239afba6c7f53a6416556abe8680eefddefe3795158054039e9c1095d23da86022bc49b07d2abfd97a94574d6626026768b21148068095d7669e8031e242a81582f8597aaf31325312bc2b8c975020743d0e22c9c47846e3c42d65d4bc26580d1ce392f629568d11d74456aa8609ddb3af0d9f72be147300a636c97b0aff027282e449361fb3c3d5f8f26978d09eaddcfd37327684eedda2970b8bc13608a547a473fefa09a2b242cfe106b75ce3c64e6c34cf1c6ca183c19e4fb92e146f50496a4764c443b8e7b2365b7a912454b50b02015d7244a0f66c5bbaa9a50377524a0b11e4a349f3720c2f4ad2e64a749d66aa9ba0eda7194e4bcd391ebc9977855fe2c9cdf41bc630180861a18f308727dcbd0d39b976d37a1dfdf904f77a6a40ed06dcd94738374389027d9018b1943c5b713325dc8b5de53e34db7cf819a55ea2fa52b11b05b2f06f31084fc2a47a1f72d6098df6e66181ceb8d40135120f055587a63e793dc731c3439b83d9ad34d6c234c11b5e368983e17679ed558a5ea7a3ad33d5b9ebe300778ef8b8f578f6e30d7363c82cd9f03e1d780087c4c182d72e0319acec822f2de2a32f24733f57413f6d2e693c7de3ded77e48fed03176d03e7629c68662b9410a68580f98cd4c0ade2e5d113f8d72379e78ac6038525b81ef549b934f85e4714425e6990805ea4f011f7e62088d86b11de93ae990135dfda335ba4d6899d2cecc2c7cd8497f5226b3c59af0264c537de2ee237fdaa594788747be37d35c4755475ddb9647ceb63b2066cd4ffd3500d1c8e023e5a04220b3760b46439330f0f0f0f0f0f0f0f6f4337426a6b9f908494a454aa976679010b644a29c99492d81dbc0b9c99f87466e2d31546ea6e34e301030b400bd30a89305b754ea153cc4f17311a1a68000d2d6854c0c3c3c3c38bbc0c801a6220c214d28388d6a39e7fa625c4388441e5edce5e2284ea63058d011b39ba7880214c3a9430d9298b440b63214c21c78b914df249fe104218b465c813f91f15620cc21871e5d6434b9e902208e3440b19a91e545479a2102310264f59952647c8881a157284188030a5e777f438191b6b016084187f30968e74f988efb9a75363edc3c647c12d4b31fc6076b7083243e465059386161e1e5588d1077357fef6f47137b6f3c1246eb35ebf9237ddefa26b68c06fd898c0923d186de28afa0e1d3d18e5524823aa3a7f3a711ecc5f174b955267a972120f8697a4b4aca5548086062440e3430b1ced12c891000b2851438c3b986ad27c74ad38f91b362002e50a31ec60be0c7df524667bb5af83792dced6c4fa09da6e3a986e5baf64752ef5e139183ce54ccb19a24a29530e26a13e57b8a89e9519d6588b83f14a456cb56ec2292538184ef6d8c9d0918488a637e8337975ebd52f23c70d068ba6bba5847e25f3b4c1782a629b087a7ad5c26c3089f59c82129d3c8851d7b09af89d69d3fbfb5d0dc6d1f62762470e252d4d83316757528ea8f360123418f542e3924e6a44fcc81990e79e7592d8f0dd88194c9fafebc329b7951896c134e23e23f4d998fa6430bd560e39a29ab0a4d9180cf2246987284292490cc69ff9d4ad94264cbe6aac1962848131b7d9ae20536c3430587a3cfe09791771fc4272a23de2880929cfc70bac96e87069d927e98241e9d349674cdc0575e242a272ac3d2f919152bd05decf52e447e9f4c1d58229e72454dae4f24ad5c982c94212972fe88d05632491b3d1174a4551b942fa4b5e9f1a1d4f3c620593aafcdb1dea296787ab7067cb13dbd46a6255a86052e6de267ddd4444740c31a660c48e14d192429784670d0f69267f4761d7125365924b5ff250307b2425df15c2ab3e9e438c2798cebc4dc6e52427182d8f7c87f2fc155d9b9078710fa1cc4c2618c4b6044942924b583ca565c7d2217fca9460b6317defb0d57f214930f68dca496adb87f00e09c6f8ddf3aaba54b61ec1d319b135ce74881ac1b8af27c1be6e2c9f72885104e34a34a14f45869e1e11c1f41971d72dd4ef538660505921e5e715e517662198aeb346eaa80ad2471b0483e855f79c4a6dafac4030999950b9206db573f20786f7efec4e7af744f6d00d317c9068a6965ddd0373b6c41c939397fb82789007af3e53a24f9c24edc024277c56ba206f92b6bbd8a26f241d982aabd675f47091d29203c385e7eb087bed220eec0992b642527cd9788353fc38ba446f820ef2183630ba6e8b6e0fdb298aceb521460d887f49f4d7280f950662d0c02ce6e13cae598ae4a1b121c60c8c5e3aa5a81246eeb8be8618323069cefde76f856889c5ba9f53d8cfb8d2aec1c254276ef73aebe597e91546fdb4edca31b57923572073ca9369bf4a2b0ce7a3d4bdc8c6fdafac30dba7baec905ff2bd5d85c1e444e5e6fcc83cb9c69aab1960a8a2ce761792852429684f2accf196653997fa4d1f15261d523855d7317e3a790a5418cd4ea2744c5863ad057e820fbe1b3672743185b13b6591f11c23966534b4a0d1821c5ea0c07451011a5ab4e0867f71011a5ad0f02fb8680ed0d082c69db5c02340430b1a76c39d8bf3850d2df3a251f05186c3bd68418e2c85414f7a0f8b2426297b5218d56cd4a8f4f1f6b98fc26c71d2cf88c5eed35714c6d1e965fdc36fe49ba130cfbc8f288f7b8b2c0185617f3b4be7fe2cefdf270c2e4946d0155a3ea25d066078c2a04694e5ed59d7fabf138614f22c56a8958afbd4d80d745181b3829c30870d911e72e6dfb29cb809e39c271d99a142de4713c60a7af1223444ae8533611049c5fbe69e4bae0f26cc79c5de7b74ec10a2a55cc214b45c4d9f92aa22644b98d46595136182ead866f2004625d491cfcfbb1682caa2008312e6a0ad2797ee5b93e1f8c8f3008c49186553c4055d59e46449560086244c1529ec8e55d808ebdcb8617608302261aaca9ef8b521b2eef187106040c21ce36e73278b47109700c6234c6d415f0e42bba9578405301c61d8b7aa2ecfb7b0145463edc373d8e8e24e05301a81d0191e3e6444790306238c713f62d1e43efdeb35d63e10522f602cc2544ae26e9b84a4425a6aacdd5084a954764cf86c3fe67101231126b566592e665c46b4cb4c000311066d912da851fe41a4d3210c7f61db43caa5b9681bc29ce467e498a51121a51026e5392e9f449810061d134a790ae141982508f5385721447a2c087329ebef2f5526e60f8439ce6ea464656af2640161b69446be8d8a21e4db3f987d62593c6bedec52fac164f7df69fb631f4c29ee6e65adff50b3f1c16049eb6666df8331458ed029b2249f5735d672b4e0468eb5ced10bf0e223c905400c30f460bcb4f1faa542ce53aac6da471d0d0d34600b30f2600a6982a4b82e5539b45c808107f3e81e93b318dec1a4646858588a4e96658db5b230ec608e26579b3ee26bfe5263ed830d07a30047af200130ea60103bc23f8556eef5c3737c617e18061dcca924a54fd2f75ba489e760d64939b722bf65cfa68f3b030c399844d8a9a0ff63df851e0783a58689a7541bfe4170308e507955fa6358f5fd06931033ea6bb47583f1d37376b8d5aff8691b0c1adace3e87f8b922369882fa4cf652daf4e49035183f2d98fb051d6f92d460887339fc7327b17f8d8b56810d143806baa8000d2d380dc6d02222d553f5ee99ae00030da60cfbf57af7703eca3318b7be26ee8752224c806106f359678b37eea9457b30ca60f2cad24946844f8da700830c067517ed83b4fe1ba53406e35ad871cbd7e3b29be50186188c5a5b37bbb67d9d3d6130a7883fda42ae99f6d100030ca6b3b00b914275ea60d6ad01c6174c9d5444af9b8100c30b86f43b97bffd9e7459140230ba60ead4157ac7cc264b8ad987a11c6070c16cdd162752f27a1bf9ecc3181030b6609049317a1e52d809920f3336c0d08229291d26ce8fc9979033fb30b5d2038c2c98f7e2f3558a8afee75830a8591ecb3d59bd3aba82f9564b7b5cefaaf3b582e9b7a3e413d23e29bd55c1f4c9b28856bb5890142a9854e764a53fbedbea3b05534d2c7d77aae2e7775230a9a06137d2ac24465214cc7d1a298d2c75d9520e0a062d93b297d095ad84fb0473cdbfa5abb658eed209c6d5b4504ae57cf6779a601a6d61ff45878ffa2513cc6992b07fff8ba054b40453ec0bd3d6ad3fd7394a30789add480bffd22d4a8239e8a860fb5fc94bad483089bb9f117942749b0fc6114c49d99a488bb011cc11840a2a87d1cfdeba08e6ad6c6a3f4b53438f4430682f11b211f3b22f3f028c21984bece28afc8a259df6f0281f8607430826ed4eb1743e136f97140473bea978d6ecd68d05046377f5886b7a7779f903c3488ab964a13a9f181d0e183e30d75d075d6e32ebb33d30a8b9a43d7479903d2e0fcc155ad41d988358499ae02af945d68131e4c73ebb49c2c4e57360743b717eee57a16aa3a1c58729da62cb60e0c03c16225cccc98c8ad40dcc1f44880525f46f5ad60626fd172d47dc9aeceed6c0702a3e8a4eb942be80410393b4483fc2d7e4251d9d81712b23a7bbd58fd41d18323005a97dff932a8ec9321646d3f2380f23a2bb25b0305df06afbbbecc9f4fb0ac39f4732f3d167b1a72b4c62a284dc5e893551d28286161690000d6d81005a6148fadada644c92159b5ab10b08801546133af5abd492d72cf00f1b393ef05620805598c2da6ee7d3a810376320005518e4e7be3ecd5f68130502488529ed2911adb40987aba09d8b0f1514c31b282801a0c294ee84ae4bcb97eb2fd2028f403985c9c427ff298b98c26057396e9696ecd1430194c2204566e6ff7bc8be202408801426f7bc6769a476d2e6e8628b1a450b0f8f519852f8879265f7a62ca6111e672887243dfc2e5f7c7461833b8ad0610643d075973fa67a8f9a40e828c32a2a3ce928a24e7e51e82003ee5f5e9d25954612133ac65072bb2f31cdd0b30b5c4287188ebb9611cf7f346ec1f9280b833945131efaf24608dae90083214938713af79c599a5f3086e917ada2aae7c4e4dbb9282fe8f082e15bc4bd54e42e186f74ce695ebac73fc905d3e4169973514af6f45174d0b105939294f522df4d9cc65a3098ce2945c991d4a0230ba634f12a4b92e4ce6663c114f428a56c47f44b7e35d6cc6868a0010ea0a10109d0f0f09041c7158c3a493c699153b357a264830225d9e8a2eca4a500083e0cd0610573a4ac9491a89d26710f0f5e0a80e003004ee8a8824175ca972e6fc99354d5584bbbe139fc861766aa800e2a18640979f398e421775330a470175b17b4e335cd8f0e29184777ac185636f3f9d482060768584002343aa260f41c6f25c5fd8ad599066868416303342c20011a1d502874864861fccc3f5d634d058e010f0f15f80db41b39bcc043c7138cdf5f51527f36d52d7e31812e18e0e1e1e18163071d4e309c502297969610c4af8e269844926a0f777e6a7eac4da18309e6642a590ea1b53721a9c6dadbf8e0251872a86441f95a12d26a724a30ce4fda14f14f27d54c82797420c1f82bea25071d9f4ec5fad071044350cf11092a4a90df8d604ed1a5478f96fbe6a4a308a6ce26259d8aa076f5c2367410c1e861c4e517216774ea5e740cc11442cea3152d76ca2d4bd02104934a95e6d564769c488d0e1d4130c7121533b2e59ce3b36573e80082b12ac6071ff57ac2439258213a7e608a9d8492d9fe8a7caad436b8f0f020f6611b880e1f18d447f47fc7fa5356730f0ce2a942a57c499bafc63c3047c822c67284a9b2c80ecc29fbe46025569e832e9fd0a103b3e7fc1232faa774e7e4c01cf793f3466a383084dcc93a25f5ff0df50d4ca9ca7476dc49133a6c60b29bd1f7afb14b538aa1a306660f22f9626db8458e7ea18306e6206b92a3ed857ee5ac858e1918420a7bd723c553493a6460d0f5c1f452ca1efb7d2c0cefb13be446fc8bc8c2c214b73d6ae7707e2987bcc27841ee5225a929617b579872aa3d15272e88e7a915e6d6cf9654e58ffb5cb3c21037437755ffa2e4945598ca3ebf8f885615a6cd946839e59c0f6aa258c82215a6cbbcb99c13ef0a59a0c274ebf6e154485b3e39a730c7ca4a4a23ec1b3958604c61f0109552ca1f254afea5308ff04ff18d70fe1eaab19611c88214a6109479ce3e7d7a71bf1b4116a330e58e7b1a4134925b4a8d355118c54f951eb57f2af13d01b2c1c586c270e2262d9bb4acd0528db58f0485215e4acac38ea8c6da65208b4f18546d3dcd495acff2d558bb40169e3065ae97764f1225bcacb1c614c8a21346fd9113ec52a6fd7d1865c1095359fc4fe2d69ddb6235d69c8bd37622c86213a65431d789fb6ec9ae1aab09e3ed44f5b62dd3fba61a6ba90b1ba78b2f361326bf8a1f275d5f5ca45a70234762c26041a50b2b571344446aacb5e0460eb2812c2e61fa9c3e2e2ad5d60879324b98455987b058c23ec4a2812c2a6108b2697fa6b273ccd696035950c22074ec7394093126ea933086850bd1ba6a24ae92306beaa591266143422261bcb738a2539daac41224cca2428c70df0f6a52e711a6ab18177cf257bec91106d331e4771aedf183dd0893f214e18410c16cd28c30e78f9dae5f21f5b96511e65329fb9cc9274f9e2ac238ee3da3edb7f2fc441862a7a0ec65e554658908c366cdac8dc9da499243982cce9ccd07194bdd19c2b0ef49cbe6c2e4d9ad1006d51ac22d564ce6a93c3c70b8172dc8714701107c0400085910c214a367e4d6764b8a21b40fbb2c0661bc783d31fa395996bc200c49de09f123b1cc4e0d8461ce65948e8a1ff40f0863a898dc172d79c59559fcc1fc1366accc52fe3c310b3f185fd2986f044bd9c9f7c1105b2f2595a4d3635e0f0f3164c107b3af873455d11e4c41c8d1f1e446bf4bab078369dddffd8fe855963c184eb52b5be8feed13c18361bbf3fa95f60ee6ca932d9cecb0371766610753aa121242aace33f70c1059d4c1d439e88837fbe5a9743a1826c6554ab24d5cead11c8c6f66a3abd255e4242407d39aa5aca7a7d42774e2605c0f7796173a7030ae99d9870bf274c4ce1b4c25cbb446abf55da5dd602c714b4145a9ba384b1b0c1bdb299dc50a1bcced3b22ffd55e94145d83b14ee48aa74feab35435183f452a593339c8b7d360cc095ff91192a48b241a4cf9447eca10e6198c6ddaaf636c9abf04cd608aee22eb352c9a50aa2a64510693ba1b212f7e4f0653ccb17062d26ca6c8c76036212df34b2589c17429a87e1ded15742585c190d3d6efa4ead494243098b33e77309bcf174cd9c4a28a27715e757bc190824a3255933f7ba574c1ec7f9def42902729cb5c30968e6f2642b21ecf780b86a81f2584b0ea13e3d582694dad72fcceaa77370b463951a5f379b29b5ab1601cd5599613a24d4af30aa6b0fd59478d6905934cf68f3b4a8ee79454c1b835794d7627557d122a98ceab3f2b9a369192640aa63d75bd5f4ac63d77523056866817f92267b68bc2b1c32585d1eba0603cad94ee53e8cc0bb227183e4e9e30fa932cf79813b4b2cf394284ad09c66d131e572a74d29d09269d3e2c89c6e5d32fc1b027df4dbd64cd1229c12446477f3ea1524c4b12cca9a76a5fb3c2642498365436cbda826b5716904216473075e990f354e794e36a239846082d22d4cbcd7f8a60d056ada0e324f5e7b03040430b1a75011a1690000d2ebc40c1166a4430afa7d8b6cfebaa1492c30607ee3e90c5108c3732d64dc7ee3295f5f01082498e65af74a3ab1e4e48c82208c68cd1d9a16a9ea51d0f0f0058210b2018eed273ec4bf331e12106b2f881219ad6aca4e2f4f42a3e30778970abafb6d037d758c3f1e1c517391cc771163d3077deceb58dce4ab68d1c669b050f4ce13f7f6d9b8b0ed9da813925fd6b5e39393e6f4ac84207a6246e23f3126543c63930e851973c6f527d4bd60b59e0c064f5a542b05c69a7a31b18b4424f87da883a216f210b1b98438e962bfa05a5b4493c90450dccdf9d45c4cef7d1b28d42163430880ba7d353d6f0ad9c8442163330c44b5de92da84f56a2608b1b5e98690bb2908131c3b5d4d743462ad5be102316a620d1935cb45426b65b2ec480854925c7d3f5ab6b4ac5f415860b2a26bab64711f95d61cacd4a4a08f1126df256182396f8925e49cd66b816831506959c4e091d4ebfa4508d3557c1163752a22ebe78d2858d2db640018e5e0189b10ab3255dd3adf5d5afcb3eec0f315461ba3c2b39ba92f2a7570b1a34b4a0a1050d2d68380a9a021e1e681f568718a930867c864ef19239f10dff40157cd8c8f171e3867f78d12858bb618018a8307f2775dac6235e7ec8294ca2d627a414e6bd448708314c618813d383e4b7fc214f928518a530a88dacc84ff13c7c0e298ceb4195cf8fdd859895e9284cfea984509d5fc4a5105198a49afe05a11e4e3ccf408c50985c4b948c999d94da9a82c21c44d0cad974fc42d0ca270cda542cff7896212fa29e30c514d33457b7c61a0bbee80f1c5be017313a71c8a6ad478f87306d08313861cc104965dc566aacbd9f0b000e626cc23cbaaccf36de1aeb802e2ae0e161ae88a10963eca7c8eecec494adc69a2f51c19503c4c88429eb7b4ae1930af3c13a25c4c084b13be7e87ac1930c317b78e4c0b105171e1e1f312e61d4f6bb0a8babae33046258c2786f229ef77fc66a8f5109b39a9a4e5ac3ccbc932861d0e72762446848b10b8e2d100bdc930d0a4cc210627f98999af02177bab0b1c547310ec4908461562b89bc7d593ad901312261300db38ed725499bb68504562161160f13df7212de1344ec1e508256805a0e1c5b70413a10e311a6bc2345655bc8b11c2a00f010c311c61f75df31ae5de72a1f311a6150dfeb104ae9deab1703311861fe523e267f2b4a387b11a6ee7c29fdc65c6dcd0f1c5b281b6228c2a49f133f8450d7d93e0163b06b542449d1830c311823a41c429a2d7d1f2936920d1961309d460e22d7c608e1078e2dccc820030ce6141d11f4b94ef81a71f105938c116df11452e507820c2f18fbeed674f67f4f3b5d156474c138f21e724bbbc3f7cc05639cf7288b2d5241c6164c414372f658bb5acb6ac1706739548a3769cb436464c1b43d49697dcfb7a17a1958308f34ede929ea46907105e39c1c5da645a78ecd56307c96be28afff6cc184b6c8d1393290041955c827b5d5cdfc766190410563ffc80e1d65259ca59ce046a3c06f988c2998d74cf252302421dac3bccf838a7714cc637fb1f6c2733e8f0d20030a86744a6a990433e1697f8239ccc5eb15a1ca3b742798723aa19d3dcb92ce5213cc7d715c46a911b1549860b48ab5adeb4b1eb46709c6ff5db7121f3c5ebc4a30e7d332d5ac78398ff20b2f92606ecf2d39c6073569511948309e8e246549e49bbf1a20e308a68b37799b2ef2846f04e36f4bfe2c7f8b6711ccffb13e92ea49189d08269d3121f2c63f04839c5d8a13a24230574e9ffbd485ad6406c1a0276a9927395a8940306d9747f8c85eeafc812927a1b4cec49095d8fbc06413a4a48b1727e1ef81219dcd5dbe9ede34f1c0785abd25f72ca47c7660d8fdfe55af9589b60e0c96a735442cadbf951c18e4ab465c9771604a29172e37b981a9cf45b72d5be77236305a4842a5ebce6b60aabbb3b3f78ff697cba081e9f63c47ca5f19e272193330859a9d9e58c182da65c8c06842627c7e512c0a69a74aecd30916862065724e69a7571873d5b63582d29bbf2b8cabd7a9b5a6e4b8a91506a5ea2fc590eb131756989359a7ca4dd6d3d9559824971e95f2f9a4e0aac294525a8b7ab721ac4d8551542f5c695d2935418539dae81021a354c7083a85c9545a5c9e780c292253985b2624a16c4f98cea15298f2670f2aa69228f9218571ad757f3b72eedca3309f49cb232f8bc2581d3af2e321556c4361bed355ca666ebfce939fc87e9e13b3f309c3856cb933e2d7f9c713a620d16f27db9d30f78ccae1479eb4b339611c3f933549ba095376bf2d9de029775213a648e17c6e24ebca9809b3cc5c7a8753553a870973d4eaa4bb737d0973c8a7ce5a2679b4ad2d61ce96ee44c5889c9b75254c7b41b99d122bb25953829cd47d98e92761cafe9096462d4f58256110d671a2e935ad279648182bc951dbda175b59818441ebe8d121afe7cbfe11e638aa6639976fbec511e6942645e5c4c8e26a238c9246a5b1b29326228c305f2e616245a87b087911865827743eed5811e68bebd039f57d3e281106af78ed517911612e4bfd126631b6c73d8439480c15a1d22d4eb88630453c3121d9a38414dc42984c77c87b77a5d7c32584a9e4984ad162e5e4dc0ec2143a65975feb69782b08e3e7efa7916d0361cad0102994a97aef0161d0b19444134a5abdfe07e3cec4cb0e29723ec90f66391d7eef7592eeba0fc60b25d5bc2f760a5a3e187e2e74a5e0374a64750f6611a52d29554e4f52d583c1c7bc52ce97e6c16012827e7d13d5764a3c18fd4556843e1d3f72f20ee61aa5ef2ccd6907e3e98513b93baad696753097ee7ca53da659793a18b4a50a573274b2d8cfc1ac716159576ff1477230d7249b5119119205c5c168a64ca8fcb1a363070e86fbb871153335b6bec1f8c1e3578a923b65d50da65c7a674ae9ae0a4ad20643caf993bd7472b6246c30ad5bb8e59b4ee126640de69a942729495e0de65441271db75fe43f9206530e42a913d16bdb7244835135d3eb3ad8095bf10c8637a1bbbd3da2f58666309bb4d116452b8341a8532989d1cb7e2a2483c1cbd446b8f14aed8fc1bcd75eb27ff296c4c560d24baea5544da91c0a83b92be8d23679bd94c0601ad393e2cdb466eb2f9845ad83c872ab1cd50be62de91ff183e75eba601053ad8b13b96098a0a4e54bb9db82415bdcee24cf23f93a2d18f5ec27dd5e9705d3e44fada15d39873c164c5db2464e5e8d35f915cc296f217dac3d9492158cfa15b154073597ee2a98e6d449b5f8ad242e5430b7685321f2650a06bd9552ca69a1cf220573300f3337d9a260b0f568d95c8382d962786544b9f330da134c41c48f7d2a6d04cb9913ccde25545b5049c653d60443d637cfbf9ebd6f6782c97eb4ab5eec4e3f5982e9edcb7427794ac98812cc27d62992b44f72912418336d6fd5ec73f61009261521a84d2b1dc13c5acc549424a22719c16ca67eafcbdd4254044390977366d224c98c08061d41ac7efcda11a91a8239e6c4ea24a2e71195178221659985e510776196060c2008e6fdcea346628dfd2801c15c39e4fa32747ed07d095d42dfd828aff8c0246fe16ff969db43ac0703e8814196840927c663a97d82ce417630001eb8225a3d5ef54d773430801d68413582ba3ef5531778662e18800ecc152c7f0ab2b4f7d44bc630801c1854687c9e5c153d49968401e0c060276458fefd907be1220ce006a5a553594e8c906766060660039365b913ff3c9e44258930801a18238e4cb83c5e0106400383b6163f378b1eb4245be011c0f5a251d00511c2006660f814b157d953ae08fb00646098d892b3e85d64b13716e652da7c929cbd4ab1030b738510c2bbea5252b3fc6f91f6bae315e6385b11827b52f1f3b7f3b000d0a0c315469dd176399c9599b66ed8c0f131015c0f74b4c2a04ce850b245e67b973a58619e1ba533f12ec9885b598549479f12c24e52d05176a14315a66842c768951f9dac4d854962a90baf734ad829e585a10315e42c3eda6ada276d5c1a10011a5ad0708087470bfc0486868e5318d2861a5f516df9c46f0a73e84fe91e762d8579cf65ec53ae3c499f5ce8208561a4f5a5edbc7aa98238bcd822070e2fb6c8310ab3e9edeb1055e31f3f36d217386ca42f7088c2f09f3b848e3bcac1c51625c8c1c516250885d9b3529061a7ce521a14a65425b98298c849253f61dcb1742aa9cb4a2192c40a1d9e30ae6556d76aa5147fd40953ecee70499b862ccb55a18313a64b6da9fb713d04d111063c3cd00d12746cc22827a731c2df83ce1a0f0fe42cf0227468c2149a963aeced99484c18ae3ae4ab8aa2924aacb1f6710963f5966ecd975029a325cca6e47ad2a66b47e95f09730cd36952ca497815d558434a943aaec4728667cb4551cb4fea63b44e5de77f564e051d93309879b614725ee949649230e812b2fa431821b1bb8c844977c88927c47dd01ff6a00312c611b1b3b7a542627798071d5af8cd9fb7c311c6399d45ed9aaf97bd1d8d30fb8cc821653f31c290e298bc93ba16473bad60e8588421a94b48563271f72b1d8a30c7b3fc20b612ce4247228c1d45f4e6a868a3bbef408471648a3839d96bd9e24a42c7210c3f5252929b9763fa39011a5a78785c87210c9ee22eff25154eda1d8530bf5e24ed22272f84141a5a94a183100629a3a346ec5bcad5a20047afc0c30305387a056410c69c18395cfecaa7a60bc22841b74cfef4d1d080046804c2ace2b936449dd5870410a6ce1dd15ab1c6d5f407d3c8fe68932bc70fe61479da4542fa60ec0fdda253ed7c307827a184b49c4e5edb7b30c90cdd2e916b7e62ebc174f9913b87388d3cca3c184fdcc9951362c2e50c0fe6dc503a6cab750753a40bea2145b285f8d9c1ec21ea46f588141d3b753005a9262aa2891d7430d8c955cea542e660d4d3d972b59a6e179283219e69b7bf98f99cd7389827ce5d7b4a952d7fdc0107a3f587d0e9fbeb7883d15484f82f67ca725248e87083a9b3b9c90921049316521d6d306b4891756a724e1c42071b8c23f4b9a4fecdfd0ad0b10673be7b48296adea7c4c343081d6a30da450e56b9fbc34b5a63cd16e0e19106537ebdcf16561ae72b1acc957209f510cf3f6ed6582b868b2f7038063c024320c0118c1dce577eb535ac7335d60a4d312010c008e6740bd1907d93f6322305018a70acdf9b134135d66a060420827962c65c14496241da359653172671f1858d1a19f0f050f3d3c7120438a4d1129773dcf25e40002130d97ce7b2778a1408100453c4c9aaa7957b963c35d63e706c0104536ddaa6c80b277bb25c70f1c59fa96941801f3cfa6dd573f09c6404475a00f5cb81003e58b4859121ba3dc90e6d81a38b2d6e786a77400e82003d30083d96a654fdae530a1608c003e3a57e1aa154ce65fadf81c94d52c8d949d781396c7c85b86f93accd81d192d01b42c6a4981207c648f941282182b211961b18dd2dc6842023cdc93420800dcc791d22972c754ab849011e1e384a170850037396c7fbe42b42bf9b6860b0da89faa193e9f119025120c00c8cd9a7eb525b3dbe3402c8c09456d2c5504ad5079dcd8885416b4cb58734a977e219b028686f31939fa4bbaf4862c7965ac4b4f60a2965862b4c25f94cac3a74098b7e71c38b3b2d683c400b0f8f1b284001eb0f66b4c2f82571acebc4f6c7ae3061062bcc15752429d5a37b3f5aab30e5709e52b2bce7742f0933546130ad8ff73948b7a4c244c28c5498f75dc38490ab919e438419a830887deed02927a475afc6da47b261a3041f38ba066f91805232cc3885299b8821c26e5e3efd1a6be8c3b9485d740db4a1811c5b24bfa18587070540f0118055cc3085b94d564e720a95752a2508334a61906b5a5a1f7e56749881308314062df1bf54e5745d4af72fb8680e8cc2e0b1bb4327468a284cf1f65772b04fa1e357426150e2f4e99fb662300314a63065a1174f277ebe19f88451c6434fcd44519d843c61566f730d99e3cee884a93c5aa4582a48eaf2ac31274c17c73fd207314956ca26cc9dc27c5d8eb6260c3f6e41e57abd9f0433615a7f397539ed56ce1f264ca523a83c9d439f50e94b9854c6b8664d48726fb18429a730e51bebae61d14a183e68d16e71d348caabb1f6c10517fdb11f357278e18905332861b034361e33cf547d28d38c4918c485e420fcd4b6fe481286b5fa8c74fa481845a724f14cc84bd69119903049ed097f2ab47a9a6bc6238c59fa51aebb43f423331c611e376634228dab8f90bd749fb6c61ad96206238e9e949794d1293fc48b22331661d2f0d1c82ade9e29a24b6a62673b2dcab22bcc48844124c49b0da12d9de820c224fa41c49ed8ea0ef321cc21c4eab54a13dc3f8630c4cbfec82ba33aa46c214c6ace62d5fb87ff132184494e777bc8f191a3c8660cc210d4098f587922fea28d98210853e8f5f8c17357ce1c91dbc38c4098b48ce714237eefc68285198030e77fd3d5bc325d769236ccf883e95a457c7ffc770b397e30a62761f1473c7f64990d33fa60d6dd970f337a3e98c7a45c9e442d0d33f66010aea53c6bdbde776f01175e78d1650333f4606e13af1fff5973d619c18c3c9c2b54e9cb18dfc030030fa694ee1e543813415dbc83b1b453e70e9f676a5a543b98e5834417651e4f82e4f20e33ea609891d5ad20f3437b8c0ec64fe95325516225a56c0ea69ce3277a2521621e948339bcf7a99b7822c8ea92e461461c8cfefb123cd672bfc739cc80834967ad9cbbbbc68bf4e30c33de6090ba1ecdde34bb196e30674b2929a5f4a53af56a6983c1e44d8f7eaf173d6283a9e3e547ec3416ee396b30f5e82aaf48a5238d5a0d268b1fd352750d6d350d06b127d4d5040d0d660fb338a9973f652d04cc38c30c3318923e09162b46cee69d32185b82969482d0ea53693298743cb9fa57650ce6d8ad11f546e66973c56050ad7c51e24388d96130a5759ff0b62518f0ed9359f51232e30be6f7d98a97e45dde0fa9c20c2f98438ee36d2945081eda195d309a1097c9e15752fde68249bc24b595976405af6cc130b952c5113bd24ab45d70266668c160a2257e4e938967264f624616cc9b577e73dab31f52f81133b060b6d2f37e21be2e9a0d1b37881633ae7045b2deaaad9067d5580fd7c2bf7174b1013531ccb082d9459e4ade39fe96622412985105c3d749f556b1e449785430078b71b361af12664cc160da258267b887ba902fcc90825154e5d55139a419a5ce8882e146aa8d6da90e95d70c2898f7edf4c7c64497bf673cc174419fe9a0ea7f37c6194e308c9ae751e1cc53ec74130ceb26f6d7a2a9347799607ed32df12f397ef2dc8c2598cf530e167b7a12523843090613d367128c3aea3c7f98f03f2b418229ce4d90f5249a71046368b5af390bd2427f8c60ace4d9a9ae7253f45904f38f989f50a7afa31f36127f31830886e855317b524b3afd0fc1204baa8948faa6d46f2118a4e4594f25bb73c26843051f36d2e69811049376f80f6159cbb72540306957123331e5a5c4f603c38b49d28bab3835a98fd445670e66f8c028294e6be59ce6b39e7a60d059462387d1f4d12e0f0cd73a314bed8a4e4ed948773698b103f39f8e45d62b91b4bd3a3049d9bdd0c9ddea7fcd81415d794ed73d75ea331c184e828c982af777756f6010bb11271baa849cd00606f3db53e9f35ba5e86aac7dd8486506336a60320b0f6926b95a142d0d4c6aae22da08f5fce799310383eeb0ac9c77a13b5f3364601259fd2c87285af9cc5818bc732e1fd7de6ef5790d3260610e336184901ecb40c62b4cb51a6af53f25774bb36980d440862bcce1d923495e6798c4c8b6c2f4162dc952ff64a6a2066e68218315a6decbf5679ea6626833a0058d08d4c0d10ee0f3a25180850220f878808c5518649f24990f931a6bfa0719aa307eb07c75a227e1625f63ad0aa981a36b905418dcde372ec70e16b373c3c6ef7d51010f8f1a38da013570740d09f8163734208174c3e3865742062acca2557a45c9ca2c55d758ebc286c93885d9920841a514bf7462de43c830852958b63f616b6ed9ef52987bb393474ba9d4682e831406e9177ca2ac6d895491310a43eaa0b46acd9808f9230219a23028eb683149e8b32482a130dfc5ea4f3c29aab2ffa10419a030041b4941ded7d3e4e41326eded53ffd6371bb9278c92fd846a9b14d13ea9138611caca7276b9cb71e38449e4544984d39d4d94d3bd7388b264d5adba0c4d182fe4c497efece51241cd8439f6e9a03bdba6cb24e5c9c084b92ce7afec98923c65370d322e61f034d244551239794e3901f21a5ae04186250c415b2bcb8b76391369250c7a4f9ed74bb4d0e651c298a15ea2a85c8892a449983bdeaafd841589b949c2a4567e31c5437b1991309fc895b311ae23d117820c48184b5cc9d1e6e31e43081f619c147bbb43a538c21467fc83887b712bc55690d108a3e58ab6f9113a5e486284a93a8c2ab91c3ac8b86f0a321661c86ef292ac07f3b858086428c2242c94fc7c0a41fd53321261b820395775fa3071224106228c1727e976bcec9e2dafb156ba90710893c5d0115e2d5d3ccb8d761c1f072d20c310c64e592f7a59b6c46cb990510873c81d2689d029abc70961f8339dd5889eab84103918c81884b1439cd50fe5b1c2bd9a2a9021088396edcbba957e3ccc390619813029b1772d3934d34c650908a3e8ac9dd35a589c5f760b32fe604a26f258a7dbfc60aa0f594aff6ca873530b32fa60c8dad1d2980ef3c1202c8eea76d0f649d92bc8d883e1e36513225c8a5631f221430f26257f2e6c6e555b8c0332f260cef693e38308614cecd9041978305ed6f3964b09a2fdc30419773029bbbf102c9a0aca4576300839313546e6a9520b7274f1059aae40461d4c215a58cde94ff16cd3c12444ecadea8fde1964ccc1a0bba154a7c98a8fca0153461ccc167496cfeddde229d37c830c38987b25560ad59fb3dcf806e3b9beaec7d3718351444e7a4433de93966d30d74f7a75ef9c9316b1c041061bcca2f4baa9f5f7e764ca32c858833174e4cfe78e3ce2924e95c544728f3a4a83597d3f9dbd550e6a3b1a8c9a753a9728ff0cbdcf600a71d1d76fa10bc8308339766ad3dff1fdf288cb601a3917226ad4ba332383e1e4255987ec1faedf1a6b1f3612a640468d87a8449165d2581c0a8542a130280c8360f97514c3130000000c1e144763f1589e29bbb20114000442343056343c1a261e141c180d04e3703014068403623028100883c1a04028748ea6700c8b0f2515e935d557e99e1353aeb200d9fcc6754ce80c44c8119e6eca14f2955f0f1c331dc4d506d130fd1664da9c86913a19b432400ec18bb911457805b235891c4adeb651768091eab5d77e70eb293d81c4e3c2663444d433d431c64abd4c5e2ac4d1c74d6a65fd83cc3375796e80d929b7b27a360695d2efaa2e71a4927e3b85bf4b25079595fbd2e12d5ce34315756e9604bdbcf2447447949e31e3d015327d4ce6ff8eec4b19a3a68e3a2824240fec1a0c4a29cd8fb6e60e69df702c238fdf5a221c2e4854653009cfbb492309094f03eaf9fe9a44aef6c32dd154193276cd51fd88a713bc8bbb72614d62280f0dcb61821b33646137b0ed5c93179a1cec5d49039ba3d9b0fda804b3e9f375fff67495c531f413d2479b2969aceb4e308b44c3595f73e813bb039d68c5d33d15d074468af96cdc2007853353c5e872a516d2328d89ebea6ff34492bfb54746e9263e4f46a88595c6eb656166e4b4ff48995183760f133699db9bd3f91713e84bb02dc6f0280d3e028b4cb443aae45f1c59f868e386af9883444a0c3313163316ca65789f5ea051f15275dba98b19f039901ed51a26979dcee3cc0057f7ce0115f98c7c50561c4c70dd3a131d688e4dc0c8dbf95b9318d566b8c1a7f13a1820aad3e997bddc246f0501819d6dbe2124d360abe4e6f8b9d368b0e6c9650340fa75193d3f6165c390a5645f63a4630ccf23d0e988b646e2c50832237d45d706f09fd133460c2820c85317b4b310e3f2236f200911d6195baf9b946e95aec8046f4bc1f070cb369f9d994f47d747526de2682ce100b47127ff8a3d2a827fdb6947e9232edde09dc9d118655613024789b870a8c4c4a9023cfda92f006b7e5c2e9d26fce8d3531917d86936c09666eeb5d85105f5d96a1285d0cdc6088b5a9ce6545550fc62a55a82a94c5285fea0553886d36acb8394807da585bc695904589de91399533c582c41d09282f086e43284ed66f127a2d58407d58c66b9c3921c44d3fcd24a15ae568a5ebe6f550257005784a41641645c8feea284388cb28047a9670165e2f8fb11a03a18ace39a114bd716a330bd6276af016d6933466fd716a0dcb83e56b4553be0fa08563cc701c9322b365491d6fe6e067f4ba7832e5027bb66a42fbf982ccc6768fc7dc748ef8e74372037cd9c2e33969a5a8ba4340cca6fee1aac57efee90f26fbc8d5fed521609bde34a2c38edbe02fea1995c710f46cd8926f3ee054665cdef666013642696a1346dce3d9b935fa5dd876d522b5059bc58d8f7019d0b133494c18577e1ade092c4b7e1b12250b93e882fcc097e2ae27503b3d2c0545f0c15adc5328f93e951e631230d6579f7ee5aa358ed8e6ebb9f50ef288a543c45723ff414f08891a6362b4a7c585477a951373813a589b3513eb6ddff4d1dc76fbea8e4b03563d4f4bf6943bedc84aeb862c66254a72fc70a4f997d631840619285488e43d4e4b0618555bf6ff7993cd9c8e83d4507d42df8ac79ecbe7cf2cd1c8d51ef005c319d1b591c3dcaedeee1909129f14831e8e934bd575423155c6daca0b333ac0a6288eff7190aa94d26df0fdcf706f610be82a7eb81c69d36165f0f97435d6808c0b1cb38c91ef6680f65f2e8219ef2f12c2412c80db41909203cb5da2bf76d21f0a6edf92ef1be0a0dc7415ae763989a43686280f82c90a64bafda406d829e67911fbce7e50f8c9d9e4886e2a7f0ae954326d3c32b98d18ea3780d645642a76850a5eb633d09e8062181b846d2463553631a11bde2cb0b24489d5c41f0e67fb1e1e37159e99ea2a66f93fdec382ed9b60121641223d50946ac1edcf085e577a3607d2305510bc6127b38b6ce897021a09a554ad83c3d3d47a05f281ba95037af91c7229f145b624c8e36600b5adef16bcfb3e1760774c91ec83d9675d492ff9d7f424f813ec8f343d935f6c7aa7cfc9c9ad4a26408f147452bee24bf1154bc1421e669da917700f30d08c8414dc3d346bba0a73dd70d13a03c2c17d109ed09a71b79f24fdb04b7e9f589a33452ea6200b3c60c75e108fb01d33f2326022f2babacee5cdd3a9dcd48a8142f5dbb74c2bae7f146779f26c070527dadc04e5142a12d06ac44d69c68bf20ab902b3411ca990c250ab4a8295f5cc92e01c46c6f8313e0730889f94103c04a271a1a9668810665cbd920688daa2ab0ac9089d20193eca01b8c49e910e2df46f68e6512ad5385b1363d016da0c30f6def5453d35149ea2f30c5454043b06f36702f4f07841ed2c652a2d80f84f250e051e9685d1b9bf4710af4ddd3b1d58fa546fbb26549d5cff4339a3fe2537e46cd1a727a1f3f31cace2767cf447b6a6c2b2cd19c2803d01efa9f731c22a779f5235b4e70027e715161c209e23408ee15fe61c60367185730afa1e881b4be630e3034af70f8f12a7a902977fa47676b95d68889364acb145d639177c06c402624e91f0de01b5dc7d81f6f3157d71c7eaa54ed09b7247420260af12fa8d1892c80b00edbbf50cff96ad8f070f160ba02ccb6cdc5422419fe282f4a314fc05b20ce8d96f4f17d56882b6ebf66059e8d107135521051db202c099b7307e57c67fdc9b27b44e03c49d1c0c37b7104c0a645017d4c3bbf39d81951e3fd03ba90de3ac1ec34e460461009e16a010e9b2fbf61e8843fea3b97269bd44ddcfcef2e4f50978aede1bcb4735261489dcb44ede40c69ab926d5ab441563a5cb5cd513c0f480d8247ae1b730a9ca315ebd32be660f6efd4c762259ef8d71dd7b3c4ccd7b401479be91147834f9d154b8f4bfd1783a4174d4dbe951736a5e4549c86cf4313a4b6b52a8645720a692995df1f2ddafc3fca341e4ef76ba08b57f15a397087c02db6ab1caa3c75426fd433828c9d4dff765c57a22196fac2487ea9d1ec49c876ce273a353ff85278af8ab87510bd80ccd5a2a3672c6a1cb965cc4b0ace8757a1d06370430b48829dc1d645c47c30e91d02628f193ebaaaeedfc51f1bda6474eadade3e208cee33da6295565679256c4d188b64fd6f31b0614a508f9efe35e025317eac65e6f1b12ff2ace24a92b0a39e8e280de735f5e47a8ea2a9cd582c7c9f913def21a62c0d9708ac19216f7f90ec15018c5730f95e1f3b416bff1787514842ab6e6242c89073f69b261dd381c169785b0928962393eb211141e728da5a1147b02fdc6cf000f60b8adde605862ca16e03b1bf6e64e4f14ce7584274415967a248abb91498aad5e26818ae60c8a3985822946614154bf53ec087e4a9f42de02d4853b0b5020a2650ef0c9a8866091ddb41163b0f292e0dfa48426251b06f839e40f4b681606e5e4991057489c916c23a1a10f111120ab4a0eea4af2f70dddbfec18ac75d8058ad40d59ef704ab045c8e0506e67794163844b9efd8016364da9804ac9febbadd75aff27748af82661223f915301a21dcc370238d0a602024bd1fd430247b53534b3682fc35b9613ebe0830be262ba420825ba247918cb8c481a0ee359042660b38e7d2380f61c534dd182473045b738b3bd88d0f7cee823bf926103a40ecf63ea4bd14bba392e0725d3e2de186a6ed7d2dd18c0184147882d7d74f20a07f02b5e7c63e49b7d6586fc4b740f60a502dc94fd264c5691ed44e71655069eaa4c6a162a7f9d272abc898c52f2ad1c7f8a443fa2a18d66d8e95035cab372cb177a34618be41c976fec7648352223915586f21a5d968298ae628298b34cc729542169ad6216c156184b117d152582cd571ac306c5c6660a165f72e05a864c8b45e53dd71d6e8f2ead82e65944f5b7e0a3d16f1b608bb280a4b308d129e041a9c05d1260d01661bba70b3bd1596006a0c0e61dce18377031308211085a10ce0fff7f2d175e34669d839a773b2ee70f4e5ac544f1096d2479c1c3d1e8a42363e4511da8a34528dcd5a5986636ac1f1e55b5597d2fb1c7e13d4884e80a663246dba34bad54f32c81aa4d1a664651e8ab850c73c754189b59218b021d5a99db2c9cfd4eda91acac26cab18ad5c587f90ea981b8b1105e91d4b568ba85fbeee8fa609f2542566d22726436032c6f448b381725f00d7f6da63a51e2e5bb3f2080587eb64acd05a38f7b5faa830ccf81e6d83f6050098080b0a6e49c80709e02b988b6e97c2361c40a28eb5bc1f3cc321f7b2dcfd0d10510144060a3d04a1375e0e0825c87bfc2fc3cad2be668e87590abb907db333a2fc263766775c14e4c38ac3f41d5effc1410dcf315b1eece3416c9780ee738e6d0855aeffe1097e9329fc55d3e9ca9087c6df6b80a17e541c786e827099ce4b58a149e602dc906d8922365610ddb843ae98151c14a236db415ee677135d1b7075275f7097a2c7db3723e3d758d21e5462c54bf262b17e835eb50eb854909cddb05de2a3a42e75a28776ce6f754706652b4c3cefe11a91deb97fe26dd998a738d10a1fcfa3090139df3e1792db3d3792fa1a799d5734fe19a0ed81c15a46af7498e80f9e7f4dc8631d6f358b4fb7ce6d8ef496d391fab6b460156a256ac6030b05a1b43bfa89002589276a70e0e265de40dc84a84e5c84865a088ac1bee1ec06abf228b313a4ebfbbf9dcf8943699c0804b3d9fd09db19451f95616d378139a8d9e406c494208525791223aeb81cf08efd360eae8862706d403ae2817bbfe4490fc935d1bb4936a7d0c9544246d4d18beb20606739bb92e84044a44f27a1510d425446305293c1ae2b314d6feffc1b34a3638c94be379af27d12542d4045a5dfb6c7b559947740d5a75e6c831d8220cd4cf8a7e00e3812dd86d3fffdd6d5fe91cdcc08177ebd8e7c15948781be697d412d29e519ede69afd26dbe7d7d40ab6ba565eea80e62448f634b9b4d3ec6d36086214007381ce5e45158e66f6c7617970635580749fbe6003ee96cc3aa74de57ea131aca128ed9258365d8c49e1ee9bebad8baea4ea045a1dd445eb9aa551bff1f35282303aaab55f3159c040cf6999ccc99b2c93d965f3a952315162c2efaeb5d8ba5ab5142e77a35ed59e91f440cfe965d6baa7c729cf219e87ddcea44aab19f5662da7aea85642e55cae1cac810e8ce49c94c99ccc2dc588be5b20033a670bad09ea292df6aed65a28001fb8419a0bfa913f9782bba69d9c96ee5889373a889929155af5a87cd6e6dc1f13309c0064880edea01dda712c0691a2bcdc7a8dd32fd9d35ca9da2a44f5592f67f7b44a519e663a2d9c5b17032bd5cdbeaa0d0a7d36e035512c2eb62b309c35cd4b9408d1eb36395c47f42b69baa83781988d9f9af68c9693d0a2cfb19685467f9358aec464b1a400e3e90b4d15b63f6c618fb20b0e7bfca8b3d223538cbe49551a50f524d8696eaa54bdecccda325b59721ad7040b6dbd9576c28307109f07c6a45f02ada4021f4c27c70ad3fdd457f540fcd71ed041b90b96e85629e021e26b91fb357836a29e1b315ff8a662ceaa88cbc2dae08ab4cab5781264a89cf863656dd54a781afef003aff17b00b649223c61b3fc4ed93210d4083df7f2054ad5f8916a11250776bb474afcde8070a03ac3ab4642a82fd0d8b21d44f9e76c5f7b4306a0afba43828c8f86006948b2a39793e2c5fb67cd36e357a3ffaa4b5257f13d519c84c7e16c014db804ae7b16153b2ab5159a22ee0a8e47d2fcdc0c58a6f5bf55b235a4d367064e0e4dc820982ec17c53e9e09d18cea18a9b89ed4cc921459958cc60da9cd53225ff0e63ed03076fc4a041e6dc7b4e4a14fac99986f362dd8951d8eb7b95d7a28611de36663c2ebd3653358ca005f881c3d9897f0a16e74072eacd5f118d9b2a5efdb9b7b9e891cc2303021a86e3a6c8a1e43f0838d29c226cf57ff04dec33e016d6a36252c36ea35849c8b21a9763f5cfa7921011dab0f91be0ad109e2b39683674bf07674f3dad160c776503f680490ccbce93eb4cfde05655613ba1a611f364a06e2c4a0adef6d9cb79d12ba577a44d7295a8af828c9cc08b0db413592262d83227468524b572695a32bb50bb6910c25f221d1e459e6ed04a760fa838d2590b68433940f58691bdd1f17e25022389e0ea0ca70c8f94b603dae629bccf5a3dd7fafa071d093a0b6d97fc204a4c3ff45e90b1cab00874ad7d756880c480951be64e1ebaca40f0d107a5da0f1d81d059d59379131bb2288c1dcc769827490f4395a5248b4d40e0a1738c6c7df960866c8818bf2f167307a65a474d0e4e7f121d42dae258bd8e368c5f2520a4508a530495d3ac908ef6073ff0c535069c532deb887e8605b2867889a39b28730467b1df045fe000e47e3989990ba1981973806ad4085165a4bc1593924bf2b67ee49a022238f35b57b614c78c50f3931289fbcca9cdcb914d25302c994c1975870e2564a21ce049701d4afadc798e713ade09bd7411a40a316586aa3726e33c138cac22a532ee7c0a93fc9aff14bd712bc8ac13544d8efdfef2e7843779aae61ce72de0f97e7088bb782d4c6e9896a9a7632a536222338323a231b66e690cf92f64e8bbb466abee417ee2713178169814ce3f3cab878fa7828da4eb68c204976587778f0215358ff93d86c9f1da7f5c1a562049cc6a3435ba8543f69b84b781a58a98b04a45c9bf1f81e90db6a5a88153d7df27f23b4aa50662c433b04c5b20103079344120d91c52b119c1bb22f9100ef26cc7d746f92798e276ff8e7ca09fd068f4be423fbf992c0f99d10f7766b89b22c683c64dc34cc33b35d65871eb3f821d063403ed749c9bc0d400fea5c9ac30075cf431c69a462b1a7b219f68ba782255c7e683e988dea42343b4deada812efc2515b95025b3c5dfbd1e36217cb6fd280f0ea49fc22e81368b2a4fc6950ca1ead6c41c756b5cae6fda17481f4cd02a363b2c0518ccb650065be36a855cfb91c4d72196970e151c9429e25dae3d601bcbdea7a8468b85b3b2dfcd06e1a4d8f62a5f9ba3c8de9dd1429530265b37467ac74b3bd920d6b3e86f06b758f4fdc869a213da35b2971ae65609c05d6d6084e0d06e1c838a1dfeb6e0e9981011a7c0e427f88380cc0c2cacdd5752df7ad611a0f182d975ce17712a9cc292b30aa502c2ee3732fa41b2645d9eb76b7d081b0a24508b99c398440d7745229514a28e27a06002167b822982287535039c5f900163da00abc06453a610cbc71752de78db24f47e2841492a81119999032364964a5acf9aec81ee548df6ab3843717447163c286d6a084cfcd2b9f4dc1449111b2b9368afbc09e623171271f8f9ae165710844a9f0f6990e8a43c38f90d9b11560ca380ffe0eb9b59b411e0f65e1c8c6e28f2a1e8049692e181536899aa314129127804e3cbcbb56df21fd5be2c03c036039669bb355c3162a2d55eb00a0c9ee55fdc4e397f151504888d76721fb5d70e156d8a1258c6b39e6bf19bfb5130b57122f4b3b31b9d227e542b7e08768b3ddfc906067efb8909062ae0341bb0bad6e9bba5ed97ed8236beb408a1c2934f37a12f3feb891a1600f14ce07c2e6a83553293ff1441a2ad5e526a9a1cc1bfaa2e0a0097797cc20903967660c36109c602819029fc977350b10d505799971085720cb2c3d0cbb9cd37ba15ebeed57a3444fb18a2c4a10f80bd3b80240124d00086ba8f8576700a84c17239c5732c7a5725b5a22133aa23f7a9d9de905924c9c82c19adb4ea2c5575e61bc497c11f0c04cc23a32fa9a003cecc551d9ea042384a5f201ad5cadcae108a6f41aa960b032dbbaa1a7911ac62da0d819b7e744fa4ae22652b694bcd044772a323281d90205c5d5ee210a6b82251577c6ae0d70c99148ada5170d36751954b0bca23d7de4e8d8a033919278656d6e21f25c700041b0d6296e629f5bb8405c4ff6710ee00e56c1f7a4763b50ca5f061362ceef80e1904b2c69529064cc6b7c5c548fb3b64f259dacf03b36d9ddf5429993ae44100a51d35c2596505a5c040501a0f17751d00d8588369aac0cb8094d3e8b7ae995e87a88d9a3154c393762ef11323a406759431b868e3836867b8756c5dfefc509d8b75ba9614bb62e242becc15a7e25a13b623c0906d6a7a563835424a72c5f0f24e9e428b113c6901459832a3faa68543122575a27282e598e4acb2094be296b260f68461de88f59a22f600c0d4faaef59df66ba38876544c45fbcba2a6fca748dea1c57eb3c297f76d2004cd7a6d2b1001d19559189f29df22407539e9d4a396221bde703d8a83f2aa3c7650da8986bf9018711c782343210861750e0a1ba40ff641ee85635ca4642a6950fe3542eaa1fe3fd05ebee38f56d829c4bb9774623c4aaa54368ddc6509a01ed3334701e80e6774965fd7ab1199de4f99261b602e0d6549df6895d56053b1a492eefe45a0f23c9e58b5eb4af03fa7d6d9ef477a23754125a9b0a8e48f0253de535443e94eb0d9603118d0079697ab395ca1f16c9160c73600dc4bce18130aa31073abbcc1853ebabd656e8d6b432b42cd0597b70f674ca63111b6a2ce57ce8a60fe24597b02aa58fed7bdb80f5343cdfc92a225e8b02fb39eab7c6ef4e5f3cfbbef25b67bf053f58fa5fdab7c4ef565f2c7d4ffaa6a45f91a57df278f53447bbd75979c211925976126a1b251a27ffafa7fb836955d0e6f734b63f4ee894414c595b994e62f69f5dfc09093d7a5a1b410e66c398bc6f4b47a5a07eb14f0cef5a8ecc660f3f7dbc9226d7409b5368f9eff0b0b0c6bc9ccccb0347cf5c992bb49e631458b127ef44c6eb62acd7b203d62621f2d79834a481646816d50cf5669330dbb8d911dff6730373b8ff0674dbd82b6d95485bbf93ae338754ac7d72adc3897e2c41f29bc42a124704c92725e30bc7044937127d24963712a3a2929a8442e22bc9d625924d8c4625518955ca5383447c24aa2bed158073893be9c9b8b4a6a3edb07970af3dde535c082d078f661e3eeec771f892a7c89c475d1e2d3d08f5f8eb61d543aa87411eee95c77615349bc7c523a687821e1e3decf410cee3fd75b7ab207afcec71d68fed4d21c73a7b1fcb800ced88ae215601f185c8a9718ca8e8fea2304402136852e773ef5cc6dc38154709d11ba8328f2ef69ba23cd8f38e0917f7fa4d3b17ab02d6d936067d42722c0d223844530d6951c4dbaf4996653eef3684b379659624809d510afd6d024c57b6b4c4f39aa96ab5c3f991a6838adcf05bd98c7e00db019324c72d133e925ecab8105380e606e7c17f6d8a48295206ef1a84518b7de68e2e209810874e1c2343320a40f1b4dbc21222d3592f062ed80ae8c9a5e8611c534ddf0bacc3d815371278144dc15602ca81bca77d12b599654bb48d3530dfa0894c2a0cec0a33f31ce4b295491e9a716dd2b44043f846b544cc29aa5b420353b830475b0ad4b1d921f2742b8475a9a468637eb2c9724e430dd83247386e389c7a2d01701a0b6127b160a955e938c289cf05c7b3e2973a37ce871adbbdce2e1ab2114a9165a43179437663c6b010db77abcc2786499a1254e337a76a58360c54210ac9fc503d6965dd62437cf0db39b438b5e38219f22413635d0cd2dad7ebb4f8f680eafc362daa48e534991ee59ff25e409cc2097a5bccfdbdd82d9a0af8053c796d80d2482e28b3e47db119aaf2e005942160600ade7379ecacbb61b786d23e501ce9966c9715392a9d0c443b8730c07e787bab84968c58414d7026386141914f631fdbf871078f5baf3e6d6c3d48e16f255407b8e434084640a7c4716e1215323c2666ff88b68b6bd9b11a482cec660cb8586519420036266ed50e4a46870e6a49be064bb1b2fe617a189964cc13a7b6f55350c9e47a48efd563925ba6b746bf34499f85b1ff15f89f6e9148fd39c4839b8f5635a0226184a7aa63ee8d26ee9b4522bf0612846a6fa71cf5a4e7e95cb70bb944e8f0a2083ceed422ca8bf291d12eadd76a283194730311534b83d63c31940547b61049726078751186f9f6808515936e46c375436d78272173d80a20eb96efe242572ba38394724d3b7affe1894e34c4a46804be6ae3a2ab85007f400f4d00ab092d0c802ee0f9f1936b154aa37814cfa7de1542c0e2e67328d7387b3b7615ac044b68e4871e358000f4eeb2736a2abbb01501f26812c729f5cfc034b281e89c10709c5000e29e3ac5c4e65a59f09e34a7257560d1493dc1669ed86e005e7c7c2eed258ffa9cca61f7ae1d1cdb600b5bdb86d501c78206f056b279093c4bf34f53a9f7b40f8065ac623c7389285355f30ae06b429715bbe542a81fb1db278e316c68bd5818da16cd9d2ef063ba5026008fe0acc34c156710c480da7fb0e34668e5876c504a10e8fb7c4e6f07238189ee2d273f5b785ef929d876f94422645f08290457f9b1233676e2b6d51c6525448b06c9988d009923c72398bf297d971300f41a14f2951fdb95a06c4961c8ada0df257e68371bd16c010e43fdc3789c5f671e770f36a86440c45758b44034ff1b16454adf482ba65c0f93c26af075296796c02ff744904ef533db4090cd329522b2053bc24489a4ce527f9c783c227482d9110368caf03081ed464811e98626af381b718793196e6a3439e036c48d52360bec0432f046263ca3e706345dd7c283151ac431b06a5d9bb21278077bb5be32ad756c55b166646b427c3b6a6adad3b7dd5225b3b9af5a103a7d6e99d328fa5b986427b6484f5c5b1a92390a2607ae0a540a68a1f5e8d9193a4fd969267aa04b919c53642753ffe937704d27d1237467a8bb68d66c881de86f74dab694b0cc64ca809fe4a20bb3b4433a4e6be4a3e31d41d3fcac39078512da528f71927d7dc0494c51c15a490fdb2b8eb667cf9e5898d82f57384295f5aa0d761a55f0915048f53ada6d1515c04f93a579fa1d761a47a3639708c398914f465a8e4c3061367ad1368a6cb4da48f46070460b041ff58eb43d232355da918aeb9cc26f9cab1ccee9352a83eafc84869b782abf711c145aff6ce44d10b77ec1ef51193420ced8dfc141387e2c201fda4046f30455b2ab0ddb4036c4541a4a690e27247c29e9e5bd67e90c1627d3e7302ada05801bc118252935b9d6fd729c58552b9d376586f1308bfcccef22092febbd8ed82b390135e3154ea3e7e0fae5fb6a088f70c5c0f2f1d711ed60598fb8e9f5bd388644d7b493591821bcda8165c9ca8d95185676b71ace0a438e9585b482291764a89f3a65e8d499d080b48c851b94e44a410f8d8c0407daa6485209474185cb1711ee3a1cf3ea0dfc4645478157512e0433e4256a180698ce52c6e88255648aff76ee29943c60257aed1187b9a5be03a71ad645440c5c22a8a4542ea834f2f1362820b55135788acba4ba50956084a7ef114a81f87eea84e022f79cb9e30175a4804c444969a55df25710177434ea8a4fb48337c90f0dd289c71f3d0f00214229f0e9a381ce1d38bdef8056cd6e2a67e19850308a02b5743f285e818c56861ea407b2313bf1e9cdf8ab7193622de702fa0e09ee882b84e3c2c085d42f326fc4c423f783fb2a93b223540823bdf4f3762589803485210cdc40243ca219683c6a0a372b6b32ad5fcc174375c931adb1a6d58574d697e45a66fb79181559c8b71f816a90eaad50be42f3f741fdc7057f5e9544c8b8e4d94acda85b543398d3038c13f3de1697219b3407b3519b8d266024ecbcca858d4c3d2788c22b0ddb80641b18ed807b5081df10982f55b10c4cc49ea976c3cff91c73449f665d5134702930e091782ff2f88d7e5ad6582a0d0492edc0f9c3a52f57c00fb20f08e607104f2d0b7b96e92f97211632e90998c85d0fe722d2adb6524728f97f6802c85ea002f3b884379fdf4f23f8dadf5c0582ddce2ef23de637d3bcf6fe6e7b6b495e266b758f847d9d83dd179e38705a9ab87fd8fefb850bb4038a460987e2e52746597357b121ba6ece14ad9c14dcc082aa3d8a5320ec01bca340dc06cd1269c3bbf151efff71bd48901bed4d84905f411f3baf9166d0ab7cd4fb7fd40b20f4cac7bdf161bda88f355d7706d8eb7d4ceff8b8f11a2fb87a852037dce3d5c5bb25d156d5c92020d886c6b87290b213a4308548b3ba0cf6de6190751fc72032ad26acdd500fc1a720eaa4a762a274048c70c3b8cc2c3ed7b7deeeeffd78ffca3dbeb3f8ab9ab7579653a85aac3ff87e421a62fb19b6d99adf42cf146c9967a0e52381cd40bc2d0b75b7098c37d644725581eb609e8cc5c044ec81dd044c49389bf0a85165ff8a24e593f4fff04477fc0c5bb2de8c423ea20969dfc5d95a4db48b8a18bdcb601bc2a6d66c0700d63790155d884e9b4fbad5242e16906233635d2d8d453fef428faffac90deeb00840d88de0dc270024710739a621fc6ac206054925b84a81d3e89f10961b21482f37482a0fe20d0842ef222aca9c29825469a7d5bdf6bff881e13124dc0c6e5402750450015da19672fcc76340c634d8037cccb65a58caedaf501b047c3c69b794a256b5857c0881648784ef3e1517033a6d15e33111774898956608481597398027af7cab65075a5ea87f8909b13ee98a0cf1a40c443a51fa3c0bdb119a11815c7ca9f7ef86f13a1c6fb4c8038c7961c2320aeeb4e758895cab3cddece684873ad1cba72cd9aa3a40283c117722a0d197dfc71833ba3b1bb164a52f4fc7a1266b8a840937a33eb338f33360d475859b1d0dfff8dc3f88190fc4a014cb31b55748203c6ab6fca35a1b1e64c1a3eb2217454abf630c48495fadcf049f13e3306f652bfd225de84581b01bbee778bec44af16e551a87014bf6a1037c61f558233492dd320cabd87ea73802b3237cc792d2e520fd46380fc17e089cab21a84e3aec1e561646071b01731ed38f298e59c784c6a4625ac65c1123505716eb5e22e8ce81d03a7019465d22849273208a9b5b722f77bd37353bb48349da92b91bae90a610fa435d58f7b4ada1e16909c43de3fc97e094c3de8843355c5c101c60a0767679c823b7d6b3b7bde87ac1f262c0196de7c755e705b049e05096ca9a6cdeb141029844fe645fe976a0553c32ece269c82370576322f4ab1d4d8858dcdbef59f6e2ec0370d2ba9f39b8ae1e30766c2cae199eefd86c44759c75f43a2eeafc5fa4092f909c967278f689a8384cf8b0dd3e040fe03c2598811955d1301ebf2c6985e70ed978b83e131afa13c6af2b5cc25ec6e97733292be305b9a537430c2a6ccffcee4904c813933dfa228373af89f71aa0d6d216dc6d2ffff748a2bc0c527ddf106149a52584fbf05a780b8f179782300377280716d916ac67813ac52964e22bf1f453b7595487f3fc078e24c4f35cfac6c27ad708ccdab1bf84a8969bcb8243482399106f3b0a3d280e4187136b8e65811cf974eb94ab2fcd433aac47ddcb36e61d4c0f79f2cf17269290f1f3159e2f75b1f0dee813eca4021e89848e0b3660b46439330f0f0f0f0f0f0f0f8f3121b5b54f48424a524a4aabd75247e420a524a54c2989b7483b7a3a33f129a6c9de6498f8040402c20bc70b970ba529194ac5532a28a5c7a80127ee5f214f5a8e783a3168c07a4a297878ca32d5b663164c8ed729a9f85bf27ae3396c6c60c60ccf614305336698a143166c66448d9d4468e4d7c4823fedaff9a34760c189ee1077731c9d745baf489ecac9cdb74757703a42ca15730a19947dad605f82662425ace3dbc70acecdc3d44790ef216dabe0934a4a664a4e1e3cffaae0a444492b62a954b09a76a742aca8bd6799252a785bcb1d59a994498c769c82ffa484d211377595af29f83af9a33f9b8f1252540a6ee2a65df797284953527016f4925c3f4fdb3419052f2612c54f6645c1f9c5dc94dbaf34e8e0e1e80805abab13420e25bede9b147480824d136356ebd99fe0d4fd57f637992df6da800b68514ed0e1095ebb2477ddc43bc1c41c925f98162dbe419c603d922e696b494d66cf2698e469a1e67e5737d2046fcaf467d7f6c7c8e94c70494fd9e40ea57dbfc504aba5c77b83ada714d24b30392c55292d1ef27f8a25f8ad0c169e1daa76639560547559b885790a756180c60942072598bc41529c1c3ad4e23e6346c724b8b5f8e31b31eb3eac1a6934eaa6d021094ef848c8e1679d69523f414f60c60c2f3a22c1d786082a9a6b4ec999ea80049783526d2288fe11bc8ed021c7ecd31bb2c8118cd60ccbef49d4434f7e8398024e021d8de034e4dff43da943ca0d6211e86004abc12b8bcceb9e47c72c82efec5082418722d8efec7927294b29c9b023119cea94dd4bc6122ef22e0e175d74d1ef051765800e44f01526d3c4cfd095cf6c41c721ceebcba2eb4e372ae83004fb1ad2b43f3c2479ea1bdc51082e67e57491a5ec20042ba23db5ad8e490a5dc0050e1a9e6c98391737726cc720f00b49a530e5a2a26e0c3a04c1994ab595f54d67aadf11085627e5b2720b992de21d8060628d797b55a9945448c71f38a1ffa305b788ada1593fb06fb62629546366d3fbc05fafb7794bb0ccb4f9c07e8c6cb2d4b4072eaa78aa4efa3cbd5c3d30da79a2e7f4f595369a072ebf267597206944060f5c063d12ef2f596a767760b4268d3177ec16f5abc30e33e8a8c349765042c7545a0ac90e3af03958c88a215f4ea2b21d73b0191d72603fc9d131258fef9713904003a0868e38701b2c8d5c1711b225b57ff1451b1278c1c50d0a748e66c0052420811933686400ced00107f672f2159d624cea94ae60a1e30d8caba958a752c8775d631b3adcc0d7c7e049d3db36f023838aa0a116717b3674b081754b225685a05e035b6eaf6ea2a63ffda506d663cea1be7e3f8f9b062684a42fee6890adf92fde810636e7e5a4824cb3b45981a0e30cecae8ae6bd3bbfb69c02860e337071623ecd1c3aa59c45eb858e32707f994d591695e4c46fd0485e943b420719b84b4dc143b2181c5c181f748c814d31668b90f24bed88e4b0a182d221063ef2fa8dd96ec4be48018d30b041481229e4244fe434707071050c5c98fa4d41a62b499e44838e2fb09147d4d94775f111aa91c44a0076d0e10526ad28d15841684613e902a7b5b784a4bb50a1830b8cb6eefc93906369e8d802a74bea5f67ffeef4592d30aafbb3d783e7deb4d0d09105ce72d04188125a648c3916b811faaf6a21bd4d4cf10aec5a0c1dc945a9521347d46105365db2fe0ec2bf62765805f6ddf4e7385eeb163aa8c0bf7d324b093a22f7d33105c6826e0da9e33987d0b09156061d52e0af920ceaed453fa64a0abe880257a36e528aa8a3aff324b0fb4107143ccf5fb5fa136dd0501e743c81f7495a993a7a9ac72cdde81518740263df1aa4c5b1bca63d4d60438f6bf64d4a3d05bf461adea083099c1cfba469540c9a7a61435b80bca0000ae00e1d4b6092d6e49a827e97b549097cad779654913faba808858e24702ad47b2d54590ee16f193a90c0e71044c8bdb1f65dcd11b864392d57cc15b91742860e23f0b529c4226e4811f8c937713787e7583a18860e2270c94a9d48d14e770c818d1fb1b5e4256971371a2dd00f740881fb4fc24e488aa03cfb0e7404815359a966f235d79368aed001045e34770a399ba44e3a2b56e8f80117fc3d04b52153238d469d0e3a7cc076a4944a074fdd7b658db416acf5800d21966bcc53513dc303fe92f6ca1b32d4b10326e6a6354f162fa7d420a043077c090922ea256f8624e580af983daee4b30bcf260eb8bca8a34fc449bd7f75dc805352d3fe7609ad4ad7068c52e33b4144936be91b1d35e03c09fd697f6b9dc65423cd4632d322030ec841070d18b7affeffb190aacf8213622a88adbe27adb194051bb7bf2bc62ad3696e0660c4824d69539e64ab1efd9297b0e0bdd7df630c39e60418afe043bcb451ff25e84b2379d1e45cc16669ab6822061932556d048c56f0371e36415465d18c16197080b10183158c655325a3dadd5b560b2360ac821dbd92ae2fa7a42a7acf8dee95ed2e239b0418a96054a4c9c9f2078931a660a082d5089e9d95a2ed22458b2db4d8420bf30818a7e093d2eb2d49957809cd14bc4f4e5bfae40499925a0abe45e69d2521318690cad17e72dc80410a368b7efd90745809114f41c01805ebd9eb7df1828aba9fc11005fbaf41dfeb4b67356d8d2c2c1a80110a2ec4fbced39b2b928ae2e8030c50f0ad31c7d4aaaf9553e4e200e3137caea67753be9a2fe8a400c31368cf76b24dda453db5000010303a91a7eeed0ac13c5e3f80c109f6433669e5c1e2a9bce826b86c3a98ca21f754a4cf8dbe40299a6033fe691f9591f2f51f061899e0da6fbf52abe4fbab6082d3bfa395426b525a62b904ef19724c97a24e12ffa025f810b47defc40ede2eaa042754c794bc36e9a98a53820932fe645162b973266b128cf726a96ff142352b0926ae7ebeedbcf4b596014624f85361a75b7df6714220c1a5b6f4a4b324791e458f60f3ed72cc19b9bf73c411e40fc1bd73f746b0a63ba3a6902445513a23d82a4b5dea679d37ca4570327da9a4529922d8a094f64f113dc97037115c5e6f48c132e76bf8886025e62b7dd63985db7b08ae93e98ca9534ba5983704db9382f9067d39f7ad8560ef93daf2b28d105c3013135372b389b006c187875022b778cafb7bc31004bf195ff3dd0895589a0ec0080497f306cf3c75a1f29a040b3000c1e48ea5cc2649f78ca32bc0f803fb9927e9896b69681f0330fcc06898876c17327ddabc0f9ca5b6564ca67225e52f1060f0810b9195d734e7db905335d26ca4f4018c3df0b962e6deca9962d10327a964f2daf423b7926aa4a5d4346c24d30318796062aac98a936e6cadad9176c34990bc0bd4010c3cd89ff95fb91e52793968b4e0468e25598071076e82d4d518d592aeb809fa0476605c84ceb7119279bc8fe100461dd8d2a419aa555474a7d448ab1bc0a0032b1a24a49cb2eaea8e36ca66ccc0d145172968c0161478038c39f071640ae197b264f2a01a69280032c090c3b61be32565eabb730088028c3870494d44dfa4a275f90b07f6b3a62447ff7f48ad1a09da8b968041018801c61bb8f83d312ff807bd34ddb08132100b186ee0b754a760992f681c2260b481d32f4fb596db647c370301830de5a997875f673c598db4b741e3d0c05803a7329e92372a4e022fb830247f80a1063ec4cfb94d6ee6268ba681ab89f599a496d22112c3051868e0feb285b28d24e35ab600e30c9c45aad211a692d000c30c8cfd071962d41ad174712307a2d18243a30cfc7b99672b4d3949ca910c30c8c0e6fb243379cebf51df301b03373ad2bd2e26494a4462e044040f7d15d1a46a65038c30f09541c8b6104769a81b0c7c753279426e48a9319906185f60fb5fbc62975a47fc6b24046078e11113c9fef9ffaa3287d105b6d428d51f5754d0ae6aa4599a4ee003341200830b8c48d7a98269ee18ca13dcb8a10005cc98817c035d74d127c0c08c195be03d87de9e28e1e96987a105f64cc7d041ec3e30c0c802e721079545971a4d8f1d16d81c796326216f185740e74c1db28bfd56e02a66f68a0ec96973ea0930aac06bce6221a6f206993354e0aa468b0aadf89a9d62028c297039a4d32a414bff27111a0f6048814b49640ed31b31e8e93900230a9c087a2fc4d39ca43d9f000c28f06a6a44ccc94d5d502a3304184fe02ba69096f49350e67921c070022342321d794253232d078c2630f9c72af37ba8a568aca1000613187915d4af36a95cf5daf8c2d1043096c08e96fa9873df35d26ac050029faf3fad093d31a5bbd448c3190148f068059bf52d66ef901923bf1eace06aaf764210b9c72a188f9ff4c5948c9a6378e0a10ac62a77084a4491f719d3399a0137f04805e321b2c6b0efaed31954b06dea962789a6b47c993123070e270117094fc16a8af92586a89a6448c1c0c3144cce7275f3a8ae79548f52f06ada31a4d51f7539b413f8000d16789082bffd0e3dd31e09ccf01805eb39da26ed639d5b4913f8008d2f3c44c1a68bf729df42279d6a90808b1b34be7037c1bd4728f8ecde762a4ba06072e61a75f22d9fe0f45bea88dc9954d248199e073c3cc165ab77d027833c61f94eb0773a832cab0921c939c1b8baa88852f24df0b9e2080daa214df0216c7754b724ef0c658293a63ab2a6ce23f53e98e04ab9e48b1ad44ab29c4bb02151c342ecd38b765b82c9a92a497ecaa2c6dd4a30394d7e68087aeddba504374a2d26097253fc5d27c17f8dd08ea0a5e67f4a82cfa8adf7613196dc4d24b88ffeff9699ef7e3190e0e4782c31cf1174102a8f60d7f3a71ba5c4930c298e6035d46628651db61d6c04971db7da649fe7df8e119c4a4149b3d32f82ff68317ca32711324811dc774e7921672d119c8e57e90c4ac8eab210c1a9a484d4f862a534bc1a695e3c0dcfd13772e038880bf03804aba1f7c1c79432dd202f52d080b3f430041b736f8e9c4699f6da0bc1e656cb1d25d64ab6122118f91d6f7d62e6cfb11e04eb112be9d19f20b80c49738f504b1de225106c929982b0af511b6904045f7921f7e9789327e80f8c6adb68c7eab7d1cec30fbc67045922aa059dd85d7af4e13cf8e0b1079b31060f3d9c7aa33fa5e47469c005b420c7068f3c9c071e583d3df244526d2a6f907fe1450abe01382640812db4d8a2015a64200236328064021fa021804a78dc81bf0d6e5b25a2259196871dd8fdd7f50e0f41e3df1e7560cb5377ba9c3f5552e2c276e0410746e926d55deabf23a95c0088e03107ded42c4ecc7d3284ea75f09003ab6a31d364c7a0db937160d399507949b5396c64408b2de0c05bcee94ba998ea2f21273cdec0e7ce23fc94d64d88f90624e1e1063eb5e670ef5c9a438ab581bd931f6a4c4653a173b4d8821cc2830d5c9a103fe4f4e59f7d6468f0580397b32521c57cf2070f35b0d92e53f576877c927273f048039323270d41b99fb7bf72f04003939406952f23581eef68b4c1e30cbc66cb6baa63c94b9d3703139210adf71d595a82cac0ae07e193840613912032f09d95425afd6360f2e4cd21aae7564c550c9c309df933b7835fb084810bb5b2d21002031b9a2f495745be53ff17d8531aa4b5e6eceb96e405ee5255b6d6dcd0340f011e5de0367b68470f1616e20227d2eddc37d85b6074eedc9c72b25a60ec46d5e999ba9c72cd0223ccf46de5a6e9742616f80f5a91b3d66fced75c811f11f57e5267d660b202a355edfd29248f6d972a7059416d95ec8c1a3c4205ced6f2b628d3794c810f3993f6bc9162324f57800a1e52e04b480b3d5513a4f5ed110576f3e514c735a45d4e99c0030a7c861063984930eb9026e4c2e3099c9b4e22688eceaafa3b81dba429a7984a9dab83155080210ef36802579b635df44d954ce916e1c1043ea46c9aa563e6b10446dfaaa6bf4a15aca246f050023b4282dede5df90725d982471258f7fe2816af3ddd5624703bdea7bfedf4678c68c1e3089cd064fb7d2d2286c9088c29c91a52d4eb0a1e45e0236e6886c7495a821c041e4460834c49176c73fe7beb31044ea60a91738a71250979088111312747b5adcc23084c122aa44cf22a0f20f02121c7b6cf4954f7a6465a0b6ee45063c3e307ec7dda34fe39a66e30053ee0dd83728baf21dd644b8db413a4007909bce0225be0d1035e350615834e212c49be465a5981070f98aca24b34da6ae51e3be07a5dff4ab958238d460b6ee428393c74c0bd8f10aab27257ea9f032e5db598a794e57a4133669475c10307bcc6fe2e3d6ec07e5433559bf2353da7461a0d1b393c6cc0267d6f955c9e46b68b9c056e47c3a306dc45ec51a5ac2d66b088c08306fcf7a6a74ee9e324b8d135d02c181d3529ffa859324991460e1c292841eaca400c59b0f9a2b3a59be853da353162c1c64cd66964ff38a41003169c46ba9c41ad826e88f10a2627156a375fd4158cf4aaec20820ac973e7857371a3015a6cd182193368588c56c46005e36b1152455256a95b05d7d93dfb3e6570f71055704aa64bb13685f869cc18a960c7dc3666f7a9fd9ca382dd08c94e6737113b055f6661f984c590738818c314b9aa55e52c8dd1d42ca34ed618d26dd6766aa499c0868d1a34ba485cdce1214629b8bebc3751ea79498514c4f4be979a6246c19b50eaf52b8735d2708b1a39b8e0008e2eba5080165b68a1c5165a68b1851618d0220311d0824999ab808b220a46a407b5cba6a2878c8682cf2721265332573140c1e51845e5ec4d9a945e7d88f10946342519ef3bd4b37ec4137c0ac9b736d6a89887189de064ce75fa3ce48f5613ac430c4eb07e9e3668d9654e21493818b07088b1093ed3636a11a62e52e50a1b626882d7789692a9a568b14506228003c71a62648295e456ee27caf276d4628b2e1a139caa84549a218f5ec9b900a315625c828d25d4a5b78cf55a1e4b1435a9d363414670e4701c38ba125cb692b13b6f55de2053236d8d023128c176fab84954526692a449b0976152d46411de16920497432af9313b4511033122c1a9bb2074eea0b682ed376cd0b03b400c4870d952ac8b56e3997edc0208311ec1a70f96a643e893f96b4770324cae5725a9d9444412a3114c6c537aad47a6f4d931825127db2f4af61c82ed050d37bb8bb10836e91c159328fd0e221e85188a60cc738a693fe2798960f74d88a4d01ef48b880836289d79b2e8e468216bc1a1c145dd03ee109c8a95b7c4daab9166086e4da84ea9757c73eac210a310dca53549323b48fa3d1182f114abb64f445cd42fc41804af6bde71b437444e108c972a59225e786bcc6ba4adc0861781e0be53d49ecaa2e91ebf91022fc40004bb9e556ff1b56bf207fec2bbd2c8bdb30c215088e1074e864ed0aa8c90009f10a30f5caab547d172ad97748d5c420c3e303a6811e11b74759a7a0facb85568868c9ea3c50fc4d003a3217bd6504d4b22796083f0902e3f2fe95c1762e081dfd35c53c29412ca3bf09691ded36f8e88fad8e18b22aa73fdf31a69756077e455363b9d0e5c5fd4117aae29a84cb939f0f6197244cfb9dc532907ee2a6dc516370b1762c48133f5a733f7a4706064ceafb42b421be30ddcc4cefe65b981bbe0be9e326d884fbe0d7c1c25b24ab610830d7cee0a524f6de7b57e6aa4ad81fffbecff4ce376e5500397634bae1d93c68d1b9e062e9d4efa13cfa0611349f7ca83e40c7c9410724e976fd4c5941a696660e4e94b2252ccad0c6cbcbe9c734ceb924a9aa3b9487e821b9ea39c200619585189227d6d53236d0c671e59694a2d0656638ab9c9ae114134b00431c2c089b098f64352cc3e18f88f16169479ab4d8e91408c2f302aef87d2ccb92d6e9404de8517f80aa9dee3b9f1235d606c94e609e5f5e29ae4029b73cd6d4cd828114f13630bdca9f10c95a216626881510b651d923784329d2cb0164310125c628658e0748a3997a8a0235ffd735760b29fda6ef2743926252b701f2aed2c998a355e57818da59134354becd1392a303a07d3f9da3b2429b11a6953e0c2c7ff3a6a6ecaa954234d0a9c950c49a7ccbc4446a2c0059d114385b4af13d51a696b218801052ed365ccb81e47984fe0b2b86aba31218244538e14d810410c27703a66a769319926b0a33d3f54d289099c6b6b277dea2cc325303176895e9126253022b609ed96df22799e04fe235b4e503b2652be91c0a5da65151162e63ca523f0f6499d5263954da79206621881cd74559335bc7b3f5223cdb010a3086c5ace7fb7691a3452fb8d3b33821844e04352a9e933aa246b085c4a7731e9979043525c084cfed1e29152a74d9fad915670e4c061e30c023182c06afddff5be8554c2d222030ec84004baf8e2040f68c08c19ef89860abc701578c176851840e02387b5c6d5fed1efb161e302c609317ec0a59b6c95b4e9bc9bef183ee0eabff7278d27460f38d339692d57a8a044bb80183ce04d73e59113a4694b290d2b7a88b103463d3b2fc92b0fbb910ef84c32e68831b988a63a07fc6bce5477fb49e4d662e080338f9c5493f73760e409adced33f1862d880039c08cf9b25e97bec3e158cecf15477f5a5af4605233f6ad67442648af6145c060dd994b6ce501353b01edbc264d2e9631d96825196ddad4a65fff6470a3e68d2ae4e3712832419551b05ef31d7c79052ca8f1aab91562307172b30d645a30c5170a9628c1d42893a335d8db44caa38b6033242c1574a224529710d3223a0e03ca449572363b02ffd27f810ddd5d77c927d9072514c8b0c38c0bbf8220519b8fb820c4fb0994b748a87529f773a199d6092f0fba821d489dcd5066470821beda5bdffe287fd65a12063138cfab497fd2fc752d76568824d21fd6eb5780e299a8c4cb041bbc44bb2490626f8bf20e4e4d23b694bc4041997e0fc3b8752d7cfb5ce58a212ec45d7915ae973ccdfcba0047b27c4d742f2c89804fbaa27d126e73224c17f8dbd28cfcf2163908c48305a2a5f8f4e823e2a03125cacf348224ddc2ec87804bb7efb5927e9e4b9ef0826fa9b66cbbe89a7f346706bd9e79a274670275f456d1cb9d79d5d04f717ab4aa915c16529a5cc3b79ca5ad944f049e93a11dbdc537244f05555715b63a52c113d04679f4fd4784ac92b260dc19e7a89ff1d3b3db68560624413797dc44ea247083e272539550461f69a41702129e5a9b7b1bf4e10bc650a2a684fd5039c2023105c7894689faaad363f37640082af3e15f33af687468e147c91e60f6cd75a249d5367b3f2981fb8cc1941c4d5f4411fa5566b5bf36b5c1c4f34bef01b5fe05824c8e0039f2b55ae05197b40aded84f25e53da480603197a60edc5f4b49d87a4cf3379487b9bb4ef3c92aea3810c3c305a53e4a9ac216e6db0469a17ed5d2075818c3bf096d3856429febb586d59906107f66a74529d3585a424c70b1975e03ce4f3b428f21a8932e8c0765f2a33515a3f9ad648f3c2067216b8c998039719d6d9e46a726074f342551c292a6e70780964c48153aa72678e1fd93c66ec0a32e0c09a0875a5335310163926e374c173bdafe3062e89147c9372977c226d603de22515c911e375cf062ec8f83942eef1d0a0b30626f88e760941d6e566d5c09d4649232ff4594cc934f05d2aa297ba0822f468e05cd2441749f2abd233b0e9af36f456e4aa57ccc0e7a9feab495f414e481978d33962b628f53e3224039b33e62c495a8b0ce518380d316ed5e8ee754a254186183820230cec6d8b16111fa920030c9cd20d79a695a1fd5f20c8f80217f2b95712ea933686d0f0027b1a3e3182b264e0ae0b8c12215510dae45c60359dc817af94b6c0e8a79c1bb5d4f77aa405de5cdb74446ada484159e0765fc732af57e70e6181bbfb492b5a934e10cf15d8d4ea262ae5ea50aab502174be68d21a8282ae25a054e0615d5be4f757fe7cc9821830a7ca84fc1c44598104a3a05b65b35f6a4cea14d4c2970e3253b8ddb8b484a13053642b45819dc4424cb4081dfcc1e2a8ebb2425234fb82f67ee04eead83762a4fd9bc824d6024e75869344529e5392694efb3658d29a42c81db10aa4fb608b5053294c0d6ededa72f51d1b93256909104fe5350a1a35208a9420709ac67b869485abaceeb2338d691d35ea669047ed4ffc9319d9c31e32c0e328ac0b85f36ddd490085c7f705bdfdd5279913104fee45e0e35bdb0b31b0d3284c069845c55d922230849ad749dec723287175c68e0466f607b200308ecc4aca53f758a3925f90363704b63e6dd1753b620c30736c368c8e841c9e0017bf162d555b56ffea406942063079c576b281d7453788f3366b4e0460e2f3c083274c06a66cc3984a0e1a6fa1164e4a0dc7e3175ff8e051938b0b345634e704d31fb1b6c29659b670649deaeb962c84f8b20c49b820c1bf09ab531638990242765041935e0b209194b8aa56c70c181e43366e0281cc8a001972a7808edaca79de41fb3e084243522869cee8490f990056b23729b50e1971c7cc482512958127d13359b5748830f58a0ef6a820aaa57d493b49a3ccb1e4d57b062a7720a3ab5db0a45957a48c242061964057b3a66cc1fdfa4986a6f7cc102fec286aee224355228212fbeaf0a540a75de49fb099954e03f298f28212accb415c93ae8ebd66e9080d8ad59093e4ec1a78ed0a31282d0112153707b766934c54e29188f144b7e1c99b4a73429b80dcb2958688ba697320a46e9fc60f92a9ed3591fa2e094c79f9433fb72d3130a56744e4a59e6a0d1e20414dc79a83e0fda8f4f1462b28db1fcdbdaac91863a840f4fdcd9ad734d35937a1df8e8c47d7082ed3ed11925d5fbbbffb10956c5f24788e62e2ab626d89cda749490d68f4cf031a78da619417aeeeb295070021fa021801b7c6082d3a172723b9d3ab1342e6ed820c11962fab804671da3c6eca492363dd6489b3163c68c0e68b1851612c08002dc1b90fc4af161092e5432f5ddd6a07f3c3492175cbcb1c0d3096cdc6840f2828b06ac81e2a3124c3aaf9843997f8e9bfda0046ff6edfaabd19304f524f8714dfde9dd2aa693241811c5837787de3d8f44824d31b9566ae7cfbaf003126c2ea5520ee54978883e8271cf9e2cd3bf594efa8723b832fff8fed9f4d108f6745a8d765c8b91941f8ce07227b73f09f93a7ef063119c8668ca4c89a24ead0f45b031f55b5626a5f9d6fc48041b64c829e59cb4acaf43b6f0810846e555d08fa1ea53c80fc16e4e272187e8c3106cade68e8a26f4c4d41f85e0b3a6ca9244559b90dd072158cd49f976f613fa921f8360b527dae9d54b3db9fa1004db16d4494c8baffdf98f40f0e1c9e4269deb0720186dadbd1d524c117ddb2f3efec0a80d322c5e103d513f303e29650e1d7699bcac83c1471fb8b8d7975797e927311a7ea38fe10337d69de4988a8468e11e78afa0df752ff8a107ae23951069554bfde9e0f8c8036f1f2b92f094f4c64e1b5d9032047ce081efca6b394dcfc23bfd710756cb4d6f527f69418ee6c30e5c52634adde8e8764ca903636d52cf723a912fda0f3af0312499f39afe1f7360443a2d3f21ed36c6fc871cf8afa064b2ace79dcef2110776829d483929992a09990f38302a26a1e3e8c9b13ac67cbc8151dd793ae712a279ff0f37f021ae96c689e2973c79818f36b062ff914c722af92967cb123ed8c0fe27fd1b542acb7c9f123ed6c0c9d8a984d20c491c5cac171f6ae0fa4d997e0abdcf7da6c166d4f840032f9a9521585ac82dffe30cdcc99824050fd10f33701e296f44cdf6471958eda02455068f9653f0830caca4d8c9d5c61f037e8881099af268efcd787dfb4718d89c967b9f2fb5ed8a3ec0c0e7a0524a8a9b4654ce7d7c81cfec761df32e5161faf0026feafea22eb21f5d60cc3f075315838841eb35d2f04a0d3eb890a6a45649e70d8eae912ff8d802efef9a4ce87e2c65f91a6938b8282df8d00267e95e35d384605b1678ddcb11fa29c898597917366ed0c002ab959b4b42eeed3ca181830bc2828f2b7039989652d32935d2f0c30a8cb0cbfadb552724c96ba4e1e81af751052e26f389969ade23bd393ea8c0a99c838be7f4a9c24a16828f295c7d4881539ffe63786f28f01105c6b5cefb92e9943bfe8002e7aba669924ccbf59c65c2c713780972926f50c92685c8096ca520d4468914dc6296081f4de0ececedcc474a0e8f0be183097ce50b3afd268b153f3880f0b1044e54b99907e996dbb4317c288153f25ce28d6b08258307868f24f01394298d6216eb24db850f24704974344fc1f25d2afbe3089c9d7b56a8a7f248b9113849933798e5ca471118a51db47eae8e296e0c143e88c0462e2d42771aad1ffd6bc2c7103895835d8ed61b5397324008fcf7557592a3a2dc844a193e82c0e8ed52f23d8af85b3a0c1f40606f54cec1e266d3d3e7fd80310f26477f1041552f1f70935f538af8d9470f88de1953cd552cab32b6c7f01c644a2aad91f67ee3cee40a3e78c0beb678a50ea6c55fb4032e551295830c2a4a2cb50ed8108fa2b565c9d19e02143803906f60c68c1933707861e32307bc85a45719f69124c4940b1f386063d6179d379fcc6a9d0ca4143e6ec0fa96fe98a23fb796f861035ea4a80fe22afaa8011f16aae3ba994c42947af8a0011b928520ae51fc63d299055fe7aa5e2a043bb1943b78c88211a637c87a3b8b6beaf400128b42a98d31e8178f153c60c177e8535afe1921063d7905a752b44eca21befe8ece156c0e52fbce621c25540c034660b246ea4d3ddfd6eb8bc0d9e438923de514ab9e08dc55bceb9359a6213f04467b7fc8dcf974d0bb10124a973e08bcd65f32ede974aa4060358a12aad631acfc01db5bd9da366cb3877cc0dd081935633c1573ba075c44d752625a76223c60bbdb2bfba885d276c0be08116c475d94d4ea8037e91fff4348b12d25079c1275e341e898f7c5019baafdb5d2ed4e94dc80094a8688faa7367fd006fc8e8b0879a38abed48051a35bd9399632b402d080514987fc591b29f7b3e072c71169b34f845616acd768659094c782334d4987da0e0bde4d4f92a04fc96bd32bd8db20fb3a23858b5cc1c65115720e21d3d256306e4944922521c81c6205ff12ad5acf4c4d735661b2e0aaa9fe2655f09e7f6df487a454b0112fa994dd3c882c49a86054cc1e32675db749d22998ece1a7b326b72c319982f5b8a9a28fe54bafa352302a640549dbe2dd3a22053fcaf49b0a32e42073340aced33f9b3ca5ee4b098982b3e0b14a864877a38442c149d09031e974b92642a0e0c736c5fc63a15f1ff409eed426a6679ac674234f70597db5bcfb62451a3bc185a8ee649ba29e082758f3ee64ff7b3a68bd092ee55431b5e8e4f94d4db019fdd3645e6a4f4d2638f59758ba2ca9fd10136c0e6e962aa86a3ad9253879273f830a5132a7902538b7aae41f9a45f44ab09f16646fc85322bd9634b7ae3e097ee3faebe9cffb133f9260527e3a2d6a234acc23c175d61c2dcfb4165a487015761f43c8a052c4a047f0174476915b11a3ba8e6037e6760d2286598c368293f43ee249533a9711ac9e5a456c11a96d2e82ff4a4205957e2ad75404a74ac6dd74ffa85f2682913104d1a33aa2990c22f8daa04ee792f9c6c2738833ea7bc7102891b1f772af5308c6ef53e9484944ca09c1760c4aa8d1f126c02018a55df42475775abd092008cee4673a61fe23e4a809100836bf490d299dd4baa0260020b83eef0d162d2c784e13e00f9c68eec578e9cb33dd04f00313f226dfa46356fa7a1d40803e70fdaae555793d8a960f7ca89c83c8a7ddbfee1ed8533a2664ff27c9ab1e182b8d225cbf4d4c9a07269e59b020647b87140f8c502a478a3596fdd33bb0218ae6ffdcf4aba71df87fdb10849e75607469124ae7ad9c7d3af0a92798a64f4977690e5cd0294ab6502b21c6c8811bdb507a648d3e691cf851b5a3e3a83c2584032333d3a95fe40d6c599239ed836ee054ccf27b450c53b10d8c46cfa4bb535e8e1f1bf8f4c9a37e1b9244afd7c0ad5e4e509e1af8b48dbdbb9252779706ae425c2de88b896b8d06fef365c59c381e72aacfc086dc78d994a87863b51958fd98eb4fbf5344be0c9c9b4e4fe6fd92813753e331df6fde7d770c8ce7a9241649589eec8a81c99fe65a22dd30f07e2295debed62475c1c07632f97f7fba5d93fb052e6e9eaea02c45af5c2f70be25bf53ba0ddd97ed026fa6f7d2225ab0bb2c17b8b4e69daa73251d25bb0526b59b97855467fead16b8cccc9723699294b4cd02af31fa885930192fb558e073e8eb9ca87fbafd15b8ac29079dc5ad2e7b2b30229e43b036e9fdf12af0df1dec6490ac224a546033849482f9a46c6a4a3d8d9b72ab921478d39bb3461b09ea465160db4fd53ed8a649395060b37c54f0c8392ba69fc089144aec4bc809ecba68f8abfdff649bc09d90e857f1e4df4799c0a88adfbde5934a2f4be0fc42e5de88d257224a606cd773b0d34147962481cb4f2aa2aa4dc5844860f4a5dff020fcb67447e0f45a963693a4533d3502e7172632fb7cb3e6b4084cd0542d2aaffba54d89f07b4abca0623f0436598aa2eb34a488bb10b8917ac1f4aa53043d089c85a85dc27320b0eb5b17cd6bb3b9e807ecaaa94b0cdeff29f201df22a3c9c8d9267fa807bc5e92d57f5726f38707ac8a4e9a4209ff08393be0f488a42dd557c8bf75c004616aa7195295da39e0324b1635ca2cb969098003d6c6a4e8e9ec66eb12e0066c90b4b6b6173b882c016cc056b0983ea5a8854509500376cc2f5945ca909f24000df824c382e6537b92ca59709ddfa53b424a7e1759b076a6b641c60c522bb160537373b5a5dab44ac28271ef60b28469935992af602bfa75bafd75c82d5dc19767325532877c3995ade064a41cfa3cd5534a252bd82832e56e92af828ff77f27732d784852056726fdad3e948e3f4a05639bf756648aa71ea182cde5162258c58b203a059f47f209a5644a326f53b057693de7c71cdee952b041e5181e942865272505ab19644753fb9c951c05ab9e7b629be40e188028f813e969292d9a90985070f9b369b3112aba33a0605df3080de9ad82b27c820d9ea2acbcc4ed2a9ee044e3998a1576824ba52767df585fae71823b4def29a538b6fb26386df17b4f838d95ca6882179d420a3287ce142d93894e49ddf7cd31c18810fd4bfee8a5892ec14634f330f75882d5887942eeb7128c58048fda796b2f4b09d64b42889663b77b26c1f6ada5e7ae24f5488251da368904275cafa4e45ff59c16487035bad56b928f607f37a7183db9a4be388213b2bbc472d48c498de0f2ef5a2df3525c0923389d2ac4f4b499b4bd4570a579d3798cd1f46e8ae0bf2fc6cfd024a94f04134f5d4cc92cf305218249e199cba2e6113987e0437f4fcadbcf905531047f52624816c5358d5e08c69274fdcf55999a44083e95a70f593364af67105ce6da82e0b296ce9cd492403021e8da8b360920d820f9435dfa482195e40fac961a651994702d11e2076e74aa3269e5153b47fac08a12cacf54be897d113e70faea6a748708d1f13d70da293394e4e49a263d70d9572b4d06397ea53cf0ba397a7b42dea04a78e0255be5a6e5fd7fe80e4c7c5f4d13f3b8396407fef692a759882d1eaa03ab55c2237be8c046fdfb1c648890b4670e5cfaece6e37127e7550e5c921d446853d58b6b1cb8c929489cb89722513870912708cd19a2e4ade01bf894e9bfb265ee0626a8a50b12b462d0126c03972a752911dcad830ed9c0af7f3c0f31e5f59ce11ab8ec987b29c343c8ba1a38fdb739bf47358ba932810fd020c100d2c09659ba9037d9b77fd0c0a88c1c84ec4dc163e70c6cbacba944e47676d70c4cfcfc94acc192d4b60c5cbccdf849cc92a62819d8bdec185449ddbb730c6c4a691e1273c8184d31704a2b881034ab4ac78481ddea949426ffd5b380810b1e3d8bc48e6842f805be4b822a617b810d6d3a5a43e78917ec029bd449cd1e6348ae8f0b6cc564a62fb40546a50b6943c94f0b40184016d858395c6428a1165387055eaf45555cd7d45777052697c7ee4f1983bb6f0546a89b8a14325ee8be0a5c341d4beaca2df26e546034d9d88754973aee53e0b54308b9a69b774752e03c6ccbe2e6f5e09e28f0d1ca74a6fa483a7aa0603372004fe0b3ed56d079438a41ea047e937abcba4e96f45e9ac04f2e254547caa55e6502e7d9efd746dbac93b6047e4350358f9272168b2981c9196a2f51f34a12b124dc5929a8a44c6848602c990613f61ad2373b029fafd6f92a42cc296404f63b6e124ae494497e8ac05f87b2e021a6a63d4418c0106c86090620044647b030192369d6741058fb1e151d2d6e9206022f4a74fc983b6e08fb078c48e2f53d9a6f93d6075cfe911ab3d268d5b607bc9a0c5db595079caa0afe41f6968cef809131bcdd2c7e854cea80ed986e25541c5d269303de2f8ffe18623a6d161cb039fde37a5ad0a32637e0f7b73f834a9d43fa6cc0c9f7cd394ac6b425ab01b79b7a5574a6d8e901d08011ebb4ff2131df320b269d5abf0c9a6a4177a11690210b26554822a5309142751f0bb6ededaa72c5b0711d169cdf7755f06841a8ca79057ba2927e4ac2e30a3e7de6f2fe2b916de956b063aa6962bcb4b7cab082f532939e2d5d7bcaaf82932cc1335a44ffdb8a2a028daea8b4b065e2481c0e0643c150300c86e193d305f31308001838268e4582c188a0c9c27c140005462c344e3c2c121c2222101a87832261181c08048461302818080302c140201c0c0fcb0a3d0f70ba8f5f491016d864f976f89f9f6cc6117429941c168278c0b9b07d0815e404de0c45821520e670e1e5139aceb8b6510afd64fcfb39e4ce9fbb2013ec291e18f7c24987cb2b154ec964de2daae97b54239ed0ad7351dc81fbde55ba856e92bb72ffbb4b17c79a275646910142c82f341eaa41b97b68e27ac682828f1c8ed83a29f60620933f7c98077ff8c5c23660953125fc191e84fbe020fecf5a5be93f0b2486d02df86a78cc77b6b8e483bdd94b2bd69876c18ea9c3e9b8bfba31ecae906f3034c80c7a060782f402fb1d7c662be5a09df06fa80eac0bcd3aae9906d46562c1d45d0c3f2365681b6c0181b3efa37c48116e0115b0e65eb8022fc6863fe4a0d763f8b5de50f777e8caca8096f7719c8de7cc137b751e9237f21e3cb55f4d48255409658606a28d3c6a5412880d5143821c3e4bbafbc486aec342c3dd306a78126e0943c014bfdf2fd9ffbc768945ee80761076b837d7b9864e17dc05fc42e2a17a082bb419ea09417942cfc88b78ac3db41025e402cd790bef83b7f570dd4f45ca0b35c1c20e81b9503d647a987a15f4198c099742e804a3b7063ce5b68c772b397239073d8303417a81d3ce2f0b9484a6c08f50cbb5f9557c4a2e5edb70cee08a250e1e1d374c4933347bc6402890220472ac522af9fdd060527b71f1474ca16e3143847d0023a34a28333400f989c245b4c8f72f13320909325cc1b101a820efbc43c2d5a4655adf62fdfc53d0f5b676af1c79cfd00bfe584299a141e82fa41eaa87cc1aeccf08436b9da1e03067d8273c02a7287f9a631cf4bf3f725e3cf5cfc5a076eaac93f035292c16b610ca441f2f119c84a661ab00cc102774121209354308a15dc876c2bf01dc48c5f7512f285ee09a81af08882f2eb120a570cf3f5ac4e9a94703e96d4c5ff2c32cec270550797e4294904b8893a0065426c1af2b1c83ec1fb8460349ff27e0a12b72a9f95304a5fbc2d961f4a20629415cc068e654e214fdb546c9c891cee1cca69d54c4a07118669813ce09e1de0915941c0ce00fc382eba0d3a06cb01a44014e82766a5c03693bfcd7112c0272d12f62eea86ff4ba7b6fbec6b15e309a31356a6562f1ae8badfb56acadcd8aacd5cc747f2f97081490c712fa1c5f8a39ee7d7220591a2265feb4b715eb5f0e2ab1021add3c48f29fa4b4f451ff77bb3c8e8c08701c73b9772e720a97b8b690712a86b69c3875324825807cf72b681be8888ad73b25e053ec152aa72a4f20447dd9e25f5c4f910f5f588d9d391373a491bd0f4807514725378a640fb1cd88b9917cf0329a302a1ba8b535dba013232201cf5a5b87e2974edb1eed80a2aad8f699e8aee1773c94cf5df2063acc00c022b9b900db54fb2fb96be32f8bc82d66c77e572182a8c777095db6e84879f0c1c4b91fe6443a4ad5e4722d66fce13534d8d5ca091de539a65b59985e316c2a8cae81fbcd2ab326f80100310aafd155cb3bdcb99ad4ed9a9cc445b593f849c592be9de4ad3ae91a3ce030e74ad4a5e55c39d6b5faf9597614b79322e58f91828ee657da92d9531ffd93648bbd4a812cbfe527ba142e6b4ed819d968642400a1d9e8150b031e7653e983d2209e94f8ca91f889e33ff6f624ae3989c830eeed45ef2dba9d90422194841513e6a2d06942a515724111cab1d812ff6057560d02cf3f4a90b1ec6bb134bf5bd0732520061c29e3113b1bc40f61607a7a08c1848c4aa153b27c708c8aba0d9dbc9f713e81d7ca9032d8af3396d032ac59ec61a1340280c58d192117ea89176d1b7b498168928e093ce7eba743e3ddbadb95acadfb5ed98da9af6ef7a3db279ce88a6a7e6af10cc06cdd5f2c32456c144ece54c0cc9190028d80926471a24623796b91389ed04f6c6f566d0e16ddcc8959a5fe8e509032ed539b38d83c9c803d6dd24db586f08fa8f2eafdacc79eae9d06860c42e295e0d05bae40b3e46b314daf094539bf80180c0ba573ba1835ce2964cac961a85e3c580c5feda6dbcaa94b5ef2850c357302fc11dcffec3860800fca504e407b72fd923b7cb1da25148ac503fc90d4b3b4e0464ff9ea0dcfd58dce9ee043c6f49b1ee0c1e9239c8c5a547805f3d4504601493944bcf9307907d60182d40802b9a1feb9638a14165650c081d046848e0811270465a18a423908f9115236217d0a9cde4f16ff327c68710f33dcbbd31c94af58edd4686cefffe637aefe4b6a405483c7499cc2e07035820a26473d083cee6b561c953d1a211529e8d3ebe7407ad73fd316328e48918d144de870ac3221ba37b63165834b3125ffeef762e3434340140c7273b808311b62dd835191475fcf0f3aa7c5aef663dbf6b955b3308e298e85e3acea2ec7bd46a2f949d805b6492bfc63818d05a83342614185ae81061a9a299a2851a5aa490088d80cae64deaffe05217fe3b47893f8664bb16c2835e803e8e9d1f3927aa60a5aae012d3c5751a50295019481192141219ca4ae09b6469bcb85f67ade63210000e10b4c56ad48c66aec4a5b1575b37196a23dceccd8811d41571ec328ae81eca57a7dabe1a4f635b5a10905ac8b32611af6ec7c027d574a090559633b95de2ece656234bf422f2f9621e535a6e3940b322791f5f99c4ada6ea2e1ec3e5b4e715a660a646a68faf9cdb92f5b36dd7d602bcbe6cf4390bd87626a1618c7d9751a3f40a926835c23d525905d5d5be3b9ad2c6d8d02256d755f6692f0f710c054064598e0df5d47e94192eda34b7c1603c8732d6deeed3e9efc0ffbaea61e78ecfd22a2214e25ce8150096d90ca5296849ab31629926554339c101dd6f88160be726314416170260887ee0f4834dd18684c104d2fdaaa53e351d64c034a730af7c3d3c8ba64a11d6c121aaab4919fa90994ae1d7443dc4b69dbd7daa9054592532b53c10e36207650e0630c1776d9fde6ed60a97a248e40f4a42ee555341d860e64a3d13955da00c5b9eb23d732a908474ad49d80f2b0d767f813add37042b30ce9dcf8eaac7d7f82f1100cbc123cc06206fd97e78d155decae172ae58a8f6decc3103587d4d0cdbc87722ad7f9129bb66ba0954f4649f4e224c362b9e31fa9f88538d8c39d3051d2b68475da531fc0094ebd60c52ac2e38170526fc4464d64cd387fcbd677f3ad0cf71031c179b0a5a1ca049b86bdfc1b55b8d926340e1e42c7e6d3f9c345f84ea7e75d7f9247f8e116d9099db5cb9d53ad727af78fe0347643149152c5e665b8b402a76cb87ece60107201bcccfea7e5df35d6ae7f075186a3531c667295af6ed3fad1e528325c56f5dab99cbb470d78c502bc7c43a63199b0b8c573ba3a3b6669dd25074bfd4e3e6b6241135cf710f0a496b9d9fa1f89d68504cf65da483262183aa10a9080a7f95c62ab7743b55754495ca2361141f35b27d13b898d4fe498819789574301584fff2be37d434f7dbe30ab11d8f603c4648e2a1c5e36ba86d0252a504ce2408cba2e9338bf0791b6d2c2a9af4da5d051c906d5b2f9e86cfe91abdb7ff281adf8f188dc48c15624d70f908f33d9d7e288797b41b5846f0dafa65b4bc8d81653346ebfa19f3cfec6e3c743c8306255eb6b4addecd55feb25392f55597f20db544e1dfd3260d71cb5d44563c657a365e580bf8df1f9fb3383ff4d1923012272d67427be0d275922c2da74581c7ca846600397a2e58ac1548343cb0b75d07a946ce2ca9f2cd5fcb7d3c642b1bbc4a9890a6e16093d3cc641443b7464584612baf3bc824341458ad8e02dab48a833d4b6bc32822a4c17e03ed5c4b0fc9cbb95968acadf06880ac2c6b14492faefa1769b704c89b202b27f93d3d2c675951c6f32f07d9f96718d55285f25be7973aa2adc73aa46587cd51353b1f17b3f2f5279aa86210b5a9c3b18bd4fc878020f0d2ded14f6011188453b857bff2161ba5a6c73040350dcac56f6a0611917619bd9ad03a4ab53ac8e737b327a2fcb86e38ada87f115058f64b4fcf2798fc10e690bdb636c2adcf0355b28b9b09110c19455d8aa6d7121b28d76797d2cc6ea797dab4b87c376127b7167d51d2dea67d7f288b4d10442a9a817140106ae9e3ad25041c94e40cabd467172548b8e5190b67346aaae4ab45253f2aa68cf3104d3982c2912e086d4681bc55984be9b8d2e578e69a8b2364dc8c56a038cc7d7783b5f67493afa521eaea6092d4b764854f9946100ddf67b775b42cc84245dfd1152893d2d11a3a28c42d52a72fcb1a833654a8a548d5854e725d4c09611b9f77b0356fbf4cd4aabe061134a0247667b231855219b21d394e66a3a8fc3b8d330aa1c60fab3379f1a93d3c2323c2369da8493e746af60547391ad642ca084c4cf179cadf35ea3495c2694ddb220395bfda006f6e31119c7e02d0d66cada4dade822b09ee8601c3a8d0867b09b7a3155749df05fa874d12ce557e3c9f9fb2518c31a1e86686e597e20a72b5a3931883fe62671244b3ebba5f291dbefb72fc9190ccb37016c40dcb635ceb0587a3758a6a3cd6543d5182f1982f0347fc3da6c69bde2b636f27cea1a4fe6d8cca77e0a54e961bb4a01164223862dd4181010e353d3ac76c414c3d2ba574f8a12e4d0da148bc0fbdf07f41f85b2cb699ea24c5ce5e8e9d0ec10cdcefae347e3c4f2dc7e1d36e182f5c3539a68c01c94a2d2616c626236b221ff9280f9840b299b1dbddfce77080029fccecdc0ca27826ecf4a2d2463ba44f33e3ab6069f4420ef133784a51e4c966cc107274824dd62d0caccb80b936b01dc483035a216c6c4a3c88274d5a2179f93c3c06b42c1a44249a90c60de23bc4314f3b316a0b0fa55568f668a8aecf609d501e29e9277aec0df93c809f9638c40d766a7efa69528bc9d140d52a9b453c939f6571c095113098ac0f2001c41968da1529510d14f915c25bb1a416e5de4fc818d5769f94a55746ce3b499e2199309f965543ea3a25cc87d35d8aa2e8528e878f0ab7bf9eb488947eb87551dee5515f45554a98d2edca78186a4127ff35ffe5b4650e75d940c2efa3f9da2572afac1bd884f1a87a6ca08cef4d44a065392a0264612ff45c229b3818c49a86d28f9ed3acc37400a2aa010450f186d58b103029dfc21d456be086c0f4d8aa5c8f75d79209c419c3a92dba7af37604205779f82885c043791c7ab58cfc4e5686fe831e62cc821d84a7a992d3dfd1f5528c0be028cc66a8d13b58b59a959639e428cf79b244e13b0143ca6c568e55000a3eab6220ae32552799f898ba569dafbfca371507e0799f2a873f1b8590dbfe9104d72f481b53e1264eaf7d617691560a823feb120806f0c38bd6f81d6b029e9fb0fcf1be4c6e8cb494f8ee4894ae4de48857a17a64ef09a06160b6a3cfd373f8b0564f6e364625a9f698e29c4770d7e58aca888c1d351af4496ecfb33ce83a385656ab9cfd8250d6171474f91b92a3a9f57312493ee2f895f6d2b591cb849ca9c4ddd2ea73e29dfc7a3cd7e70a9b08a601ca7f4efc11b1ee83965cfd819e3323459c45ee23bfb0914bf361928412b0956a130d3faff8a0a135eb985c1f0c2847f1a0dc1160072b506076f8c347a7381852e0083ae2989217dc6b735946d5e6bc029041e780d9d72b757e506cd4e08f5c7640c65c997ff331ca9a0585f63b76c38715f5dd4f15c82ad2e68e1e450d5ce7ac2df7d175fc65a0158dcd02dff4565d8ac24ceeaf885458782c7cdbe78407d742c099b77d4c3a3405b58223959807db53f9a3e62d9c1ecbe31fad605cfdd4778bddf4a4a8cc8eb5b4bfcd18880d8407bc56ed43367b6e37332ec8b9b293d5abd92aed8ecb341c526874dfb6d3ada44b409caa6924df96d72daa46893cfa61d9b3cec66cc096d72e42e2721e7ccc2ab7d88e336333af546f03374c357f152153c391abc353c518c94055d0fa1c072bc965cefc95e1c6471578def335f1a371d63f62217f7423ffa45e36d678c97c265598ee00701a19636308103c6bfb6bd220e5d7b71bcf61d3e83f1efc7cf9169ba9330c7a6330cfdc88404af186a05be6e90e38524a116786b4585acbd4026c64ccd092acdcad81640469df7fb0c38d690a107e1cf7a305e41fbfda779e4aa5a3cf11d3f0cf208d4a2d4676e2d123be85a9b62dfc6205ee359cc382ab5dde4ed6dc08fd39666181df734747610c207b2d71158fe8e75b64ac8de9528ef107d27ee5bdb83d88d6c328de948c0d92b9949b6c8e4b0ddd6662041da419b333240515dd66718226336a9728fb205414515bacda8e0e8888833465108b42a7da409b4faa1f4da78b611c31ea4d42fcb76736363e651c0ec1a097d47561b581ac3f580378ac39db31f9eb50cc7978e8a95c76dc702a4f83032a80f3721119e1a5c15aaac7379272073e52cc7079aa5638e3b0eb673c46c6031a58323be060cc195b388f0e45b1afc45e0df96f3ea6e2a955d97a47343e62ad193f6391301541db3ba6301b3faa16466351582d9444e695a5d178ce842a6bd6f7a92507c2f9243a3425df218082be8ec18f288384d2e073ecb93a87212bcacc7f4bd470f2ff7a4aa70597f52b4812cdb4ce79298246b2a6ac9b1114db1674b65f44012c6e204b51476eeb1879683190667d6e73a00158102033024595516da4def680cc36dda08f18113e6abf6124ca84915a7a810125d4bd0b78316ce44c95200b0f154699820411dcaf534c49b214ba6a218b991be40ab3b5e383db51972fa382deb818902d46f16ccaa034dbd26601fc97e33b5b536570db41eb00dea66509be6dbf65fddccb36194bf20b4cc371e0a080969f0fd65060bf0e64ffa3928e36ef5fd246cbce35539384836efd3d5ca23c473ebcdae16a36878f3cb06abe378975d565e0390c76bb50065d890dbd386d07a044f6354f9272812b4eca08bd9365b47b1be49de0e3b3886f16cf314641ffc15fc508f46efa923a094f3a8bc375bef412450298879b4d748677208e45769e5c8992e75a1f5642b2aad4d544bf02a72efd5d55e7ddd022f8b0909962a9b16600607cb0edfdbaa4b005b6a2468d51549d2cc3ae5764747baf8fa223eefb5e73fb886bb6b4137f7368b34a78fd16ac34eea55d574c339c0b9b48e37acb522f50dd37859a2573afffdd9664864ad496e8bdba7da1b36bfc3b626c5d212210360872760727ef30da783335fe8b1737c41017bb00ee45401ca59b5cc4eb9e92153326314b4469b3556eab840fd0c21e8ed94afc1585c2b84d973d007ac707ccfa198b0e02a4f1858a10a54a08fe0c67c9d61c280cb6a0b72649f15b6ba258e1b2ca093042dea9c5f46394541633b2ec86a17014d230bc6ecd105b753cbb8cbee3c07b59bb7c800fc0ebaa46f9dc0335ab5c13546de116806b87a2bddac8e24c609c0b6f5f9304197a0db82d6a3a4eb675212685b89d1a64972b656dc9c6b691f30713708628147ecddefc1a18aa860a8adae579c01463f9a362976d069aba9ef7580866639c7481b9ca9933445abfcdc445678839157645b6f9949b0dbedf07447f3b78b9352915dcbdf74ad882ef2c6054bf4d017e90383a1817fe7c9c5bbeb3c7a1976b22874570436d64332500b67a511d6308ccf9f1230493dfd1cd4cd03d3a6cc3ac93e14145b7e368d87ad4fa8b21436071b910215b571658a16647bc7b64e2758ac084821ed9f00122b45dcf4bac0039020299be99987d90443e68be7def628975479732951dcc4ad6b315e19519b3f7eeb329adb56f0af64168e669a8d7ffbf51d49a5e20c3a1abd676e73ea6c0ea9ac04f7cbe3efbc8007f219f69d05deb114d617d0ad815833ba716b12c16467222189bd1102ff13ffc759ead670b5b18868dbdac8a85750fde785e1a23def49794d5621f06f9826b78c9de596cacbffa02fc41a3e0797a160bcac175a710e61ef9e5fa8e3df44590bb2951fe048140cc9afc38a1db64005f3c8bf8006694eb8abaaea883a72ec2b002eb82d5d394c87e29754bd29403913b45c39169d5817400a1f924614cf8573904e5185fb575d2f4ced6d452fb7e8d5086676cb48efac17063a740666f0a2993ae9a816535792355a989eeb3265a1c62dc22de1a4a7648672edff76dac6724b005471ab3f62cb282f46b975eb4097ec61a16b15491a77c17fbd01163f5f219c1df6b953e4ea807edfb3813c1fb4ce69caaebd4693e26089392e6ba5b6ce4c8173220bdb8762ca36d53170f2f1ebc4cea5e71a82a1ae95f4ad34e81d1b01d1484fc24f4e9df436d0c73a204297ec1f716922e77e7d8769c61e94cf51c2ec5da082290d98c83304fb0060bbf7b33abc96cab0ab3117b1bf6b125671e7bf5a6bdcc532752be94c66d0c0090750151f90bdeb24ee63c26f540fe6020cdfc12fe2f9eae2af22a68d70b15ebdc4fe626a6a0de792d8a375e826f45a848181888b855b1b73b213ee52e0843550179e1c0a68c6b44b0ff3c07f309406e75fbe33d904d2c3c940c24281a6a46aced01dff8ff905128a46165688380e0c2d209a4a109b1bda1614a5fe380d4101eaa14780a43602c14358b6567ad16b58007a1a23d433124b0d888c6ca6fb8fb083f403010f3911c06a034c033b82162f797a4f99b7ea3b6a41c00053b4df0b803d0d99132ca704882dd4d20ee014e0de7e708f83e974657f0f6da0f8c8adc6455792fd900e69ecb115f9185c626d200a45851c6ee269deef68858dc0f5309ca795fd5806d6aa533e1d03383b27e1d6b300040f2be852349237d1ac4fe182cd00eb1a5c73155c35ee949e4846f8d95a89c7d556d082427b686b4fa1e5ee01da1a961ea52b7588836b10e6101145db80d327d0584393592bff00c37d0c7b0f6cd9805d1ce70bbdaaaf68c1753477dc7a175ae0a0254471ea334755e8f07104d2733614802d63b2772c7727e22a3d2e369b53f5a8eaff865a68f90844a65f474e0ffed6b9848286a93331f8b57a515b1aac94f4b1c4b75e99a7c5140efdfb2e82d2a4a08adc40b01779ccdedda1a5fe6a4727829a79a5d082742a0771ec88b82813559635d0e758ffe82c80991473f724bc61ab29665c8480e53e4d4bb24ec1da62984b4b7799a3c10a2c9bab4d2be89bd0b971d8af469aacd0673280eab61fef85d8119337f68795f02571822c5606e764a197534e24140636ee8299a2c66b4bc1f019f9aef0a91619cf8258f972182f4f0032c9dbf71834c41905879c655c06dbdc0b4f166f62b38f711c86952943947da12603096f5c51573db48947358515143519087ba37c1c07d6be56312e29414379b8c4e1882f82fc2da19e509e400167febf68daf17409795f045f1b7aa9a09a5c25f7f21e0074921f1fd0d0f7a35dcb91a0e1640aac10c004c131175f4e93fe877897378ee476b417b1d9a682edb8b454f803d681e7df350bf4bd9e082b48ad60e02a032df1586a11a4b4916e19803ac6a0e9b2f2ec24a1e0010f0b3e12d8cc7a97ac360c586bfda0b4487e1ac1f08601acffbc4f291016d0f510368a51eba8b8574ec2184e4eec92c311c486bc1188fce8027434708a46c2c3f21e23c47e5d5a49e9c20448ffe258c98258ca7895d89905580a01ab089161b1942121c3d2d154492e6500c30032b7f1f0734b2f007f97e089e18f657d045c830b8c63b159a62c0e2360a3081bf0668c8ad6004dd9ace0c15601571b14e954c64e65133f07cc87497d7548b2f2f0e484e2e7f795cd067c464686548668f8d81723b8427d8cf85d74ade7e3a1a36cc6d140f73cfba4fa88c2c7df0548762eca7ec398889d69e9440bfd278419e7bf81350c4ccf000f2e83a5e069e2839a6fae4f8faf1f1f24be217e5438456928a1835a9f5d02df7973421512e1c3a6f7712b583ebaf2c02764d7faab2971645037b17731bb2f3d408e4cbe348a730714c7942f01ea9e8187ac4b320e20c24199ed9b549900952562fbd7434579645c1788b96ee5ed4be32339a3135f52b209c90ec0fff9e1e26a908642c74a17b79081190970517153859d2029c148c457c04fe99d3dd1bac1961faf4316f2f30c221a26846cd1b0486802e63df3143f6144555c09349abe3b8521638cc37993c48555ea5f60de1f857bc366d711f17f6890ca5a22fd6ac4f332cbb5ff5ca6a9c1e77c98c06741a34499f44d8c6ae074715a0909283a28637c1f24f5e7381a1293fa8e753d36ed198e9ea70023c3cb8be0e7f7046382b1d38d61b4bbade954f907d3c420066a9cc37c5906bc702693d6f7e9d0666e00cf7d66aaa58d5097c1b63b20e192e11214076b048b7b23c765f3b379a00b0471a5a260aab879057cd630cf0acdaac222a53a9866da61c97841ea67050addf463d95efb1b46b06a21c717624864a23aa2c512c1087530c60549623a53df694afa694df24e9ad93fb6a2b5637a187d9bea30ea90cc0a245215d26bf8cce53497bd00441e1970918924562eaf68b547b0ab63d760205927ba5451acd96d80c51edfc163247c3f0d7fe939c793bcc06601dfa1ddb2274448c3a6279076df8b779753685122d2794a99a2598b14bf2c65b7a1645aaa157a8d002eb3304a59e0412cf8d3f8a08c283ffd9ed82409897e26f5c4828772659ab347e22d7e921a3237b51b16ea134909f332474f7cbb3658a9f57bd4f5e45812aa9767b7683102993db0616192740fab0809566d6fbeec361733b792e475d96b7b26bd2553d603da20f78400fcdb5965fd0505473174ef239cf39407c7fabae2f6662ac2e3ed5f07184584dd223bc8fe908a4ef10182ed367f32da45153e78851d45175cd954598b5263540bc9bc4dd2c14ff169b1d5aab148f0d0777c1c321776f0d5dea17437a111371e9e61bad0aac889c7a93f09693fb519c96b452a7e486fe9184ea4e906a35619ac5fa45ec82e07870f7090cc049ecc624f37516cd9107920635d45641b65b45b4a1ef581807774a49f31104e6971d4c71413156b29b14f39d5fac2180d2e6de38004296f63410232d95ca1c11dc9f5b546423f6e9dd8c6e4bb659b254bcc2482ad9328d1c44384237390af69c2b65413d703c9c9e78d588adc82415b55933a0d42d1dc4e4232039f2d369bb16ab214b2869ef1ff231d7f26ce8456fde1e559af494db7d3df30e3beeca0eee54c180e6c9397894c6afe93330ba25821e23aa9edb29aa939cf10eca3754da50d4c6038edb04adbc05d7638680318f5183cbed609baaf7e3c5bed654fb335ecfd76482a56b98005c10206fd665ab4407a525087a29b3d42e122a45c9e3f743ba6ceedc466a3e86305a39808ca56c04cae69a7a205ee907b72092d4fd889c33e105ed56e485e14bea958ba6f6cecc7cee673cbc84bccddc662c2bdd334752d9d5b1f0ecd19f8e3a01e69f44a27a7ea05e16ca234905d243840303498212a83f9615a984abb1309bc07eb64ca98943818b9de52ecdba481e46d4b64f61d471af7e0c7b0e054be389a8b1b7635c284000085d81684e831b977f0a18532dec98d1883d7561293bb43949408d057815d420fa1462d3b16f417dbd0d94474016c3187d406a14dd9cf2700f21ce0c4dc7d44e8ba2d66c911484b059e29392c845c795f5e319ae10bd6fe2815d6f15787f08118fd6047ce993441f85648e3e44fb802848429e33eb08096d46aaab8807f48ef8e3f79d602445b4c5816b9942fd7075b7336709e2232cda8415e9e224dd891441bf4849f9678362744983b0e2348669bda4206986721d6649afb7817dcc1f6a50f7a411a2241984425887dcc03b83ae5f7ee320f4844dbab088553f4058b2771226037ce7faf4073f0f6800ef4a8d69f73256cb707b152bba4e470d57ce9c142d9f288fecb1e41418f2ddcd5e9e5e4d3bab4a23833d5086bcb4d97e6b549e465cf603643e3a523b48e83b7ea2f3a2d1fa015f2779fe271c6e7efd34ff100048dd842571ab924add6256e142d5ff9f192349151ad215129946e8ac62263165f27cb58d0fce9771b92fac71305d48e56a627c91dd530e6dd2d8dcd4c2a8ce0ffdb1038e75d33e7cfaf85ee3fe31e21ccd5789d53c9c9c8ac0e58456e81ef08203088b04656a2f6c1772158a21602fb5ea06f5b9a85e3d033d9e616343ce928487d5fbb87aacebc0323bcac3b41faadb610aec92a3777686a4f7e9b72d358e7c388055975afdf31f59935d8f17d9019d41cd52a4da3755bcd07dee3829ad370808726e96a7689b34f59f2b93b0331bb068990770b5b7a74abcf79241788ae04de0a3b1225763ceb094535841f5e22a9f26efe845601e7f0fedf8c0fc8c4dcaba9c98a06b8369132df4254de30e5e641ba45ea43acf7c410001e92a8dd1017c4ce3bc09fc4f7ac11769b14e0a86626c7106ec6c498ea7bf3e975eb3d090bea00ea65dd7c91808b0af15221fe364a398b81bc02c4fa6c5976088717eb70603163870be2e2010359a1b18472194128c47782a80255c8b1eb3486a8122aa1a2c80a870b1d24842ed7367245a1177a0a670dc2e9195354056fce67b608ac6dcd930e007c873bd9a3b950b9cb0b634b7fd8ebf2027fbb1e8eece5b82580edc5fe1fb5be43fad4d1c4c235f6b8376124423c2b2ada5cbc80b0a23a3f571d6e9f1dc132c3a6f0c5bf03c5be074ca18c266c9ebcc9da170bbcdbeab38ae09d061c7060f1886d5c6fd292ab2ff6b0724683b17211393e8832ba08d6544a4094ddabffd05cae4206813246f5c6c20d134680dd3a46285810fde053033d8eec23708a709b17218338e15af105d5dc938c2d4c52bcdd903815630bd56ab09e79a1c0b437343d4dab09e282a56f8ca297a8fb409e3eb22c561ca4b9a30e5aa490f90811c5b2718c290d9b4f040df8a3d01e70d4d8a0581103cb713db0d670efbe41ae8dacb2408d2d1987938651a2c2e850f523a642df26a789abe881ae21d07fb17059c355cb0a945840866309e783c5b7590829ebb1363f7d38d0cee8f05c27e102e268d47c7b52f737e0a8f942846c1f1abc1a9ef4a099dc2893f1ca01a0458735765c8c3f08970e59a4a33c3f41b870d23d9d772956e00aac8276152022d503d578927b9a4d0618425d3de94bb6ff87601e68630b21ac07eef95c708b0ce07d90a80dfca2ddf3c7213140cc1568a30596d1bb093fc64f85ee6e68ea7292d435e11ee041e13407c11015a6a07386ff668ef2bc26a7af9467f672845016982dbf37d55f368487ec60853ae288ec3037bbde789fd0102a4b25d120210fee66d60370fa2c5cb6b03832094ca8b7c5db58695a0f55a0e8b80dd9cf61ad05abe543af922d094e8f9bbace9a66b18e8185a2717ba8f94cb303dced1e55cd0ce2740a822a44a71fb5625ed980872cd5af1f126f16f7dee4d591b142ecfc77ee26d8f89b7aa5eb9794dc1b98c7e3e473a04ca094ddc8f92abf9147b9dfc9939a32441ddb816c551eff16163beb5ac283990d0eaede71a5b27803c4e21a3fa87c633242ec80af7d21883296180f29751338d08a21072cf812ad73e699ec72b1f5d7e2c62d44ebd65a7540a0da1c514da27e5ac6d3cf13ff5499c161d86876f49659e7c90043b2324730db637430337939a52f5fc28fa2b870066e3b1053fcc6b80dea7b5a179233b810443514a2bf0b5eeb1f533ce1c9c3397cee5b0f5a3cde27d6db953bdf87a7c99d10d165ebe381fe6829f61f2c60890eb7956218a0d0d6922033f802638d5076bb9489a376b6aa8ac67f25c4280922dcad9819583756eb7714b40b86bb8adfc21bc4268a4f8a1cdf12708080b7b98456eea30a55a6ff8bc5097b9e586382c47db412e438de5bfad90266ee2639c3dc2bedb3a94f9a84dc0b8859014486015382105ae040fc2514ec7802fe4044df0a3760b46439330f0f0f0f0f0f0f0f6f706ba4b6d6368024a49424a9adf153f8ee9029a594648a8433d417ce4cdc86362184d1863fda080d02010bf40ac50ac9f499f2b5ab325cc1873eb19c2fda07c868051b529a92123cf3a59820b00219ac6064bd6b472a993a476d6ce001362820011b5bd880c0183256c1a43e4f3166e855c1c61acb9f53da53c19f680d31c8fc7ef9265430f92ce750ff21afa77b0a268e8a96c73bd8b6ada6e07a77f46be99c25eb2d059362481a6aea99de1e29b8ed9027e4cadd28f8205a9265d09e29658b28f88faf7fb6d9d3a67c2818d3f8666a440c146ceee8b952b0de0b1df904bf25748af61bd2a8c83dc1260b59c53f923e25f24ef0f9647a8db69fa4fecd093ed8a866ad64294a3a6d825162c9dfe228799a9334c197902c5a24277bf55226b88a215a44537f25e208136ce4d0f71f73e275e55c82495a21e85e907973722cc1badec678997542094d25d81d913975ca5ea276a504b739a9c99e96d6f58293e034b7492b957eefc59304a373d25ff59e48f06d25421242de9f881448705192529f839074df23189521287d9e2a6d8a992378492a85a44935b6ed8d606c5c536806d5604284119c34d3bd2d79a47fde8be0840a26b2e45c5322a22a824f1354aede4ba52e272611ec560a22654919e97b47049b738a0abefb15aed14370c13268bbff6032a225c3109c14d1993d665536e11582cfcb9f9d2ea7641082dd2cfa73cca064705707c155f610e99a5434b5a80c41302a7b6be39f84a4ab77b1c3e8588055faa2053bee003202c1081193fbf9aa3db72203106cfa9317539ac4913193f107ee4a4726c30f4c12eb517a55374ef4f481534ae8535dcf49883ac4088380a12351061fbe14f5141a5e3a4765ece1f275d3b496255af0764d20430f2729fa2495b6cf6a870e301cf0001c376e84c1011d1798808dcb01cc41461e4e061e4c9b335a1aef0e8c48cbaf1284251d499b63c781c0160c68c08d1ba87164f941861d72edba183a090bfabd066edcd8a1038c3176dcb8b163c78d1b3a5c0c2efc04376e7419c3860d6263d84036c6172d6807e0d0e16274c18518a70b07dcb8f1858b21c6e9e24b11400c32eac06fd22554acab15931ecf72d482430162635879e15e14d70146ea800c3a3041dae44f8d7539863e073ed6c64b6152f3c80fc981f59c444c1b458e4c37f9e313e8a28b311c1007d6439d44cf312c37e370e0369ed2759d296508a63770c2bf4f3cb6ae471cc97003b7f77f9db263ee48a78c36b0c17c63f9a70f2d1dae2081a12090c1067662b59f8c41d449f30332d6c026e9d95c443019fd35db21430d69cdc135a5e995430b87abe0ec28c5011969606c4dfb6e64730c32d0c05d4a2633a325b520e30c8c9af2717dcde61b649881cb9644fd5f1acbc0c9143f5bfecccb5d2237c820039beede4698f24befa731f039a434e919ba83369535c81003e3be9e3f8fba06adc130f07d26ec5e82fbc43791db820c30f0d69fb55792f294542c878c2ff0232baff6f208870c2f30c1d4b485f4503131c8e802bb49a8532143e9a867c220830b5cf4283107a53c684b627761811b374c05376ee028db838c2df0d9f71b3d564add6b818f29f7c40a53da3cd959e0e249cd8c604158d0278b50be279e2bb0fa95449f2e09c9feb50297525636f7f414f42a70f1541236ba1a29c5a9c0aea9905e9ffadd53700a8cf29ca2c4b558c890023f4a5f27939f4d57d089b1838b09686087efe080b9848c28705e22483b9d37275a1e0aac5b9ff6e54cda4dc99fc0e62611c72d74c6de9dc087bc632da2e926b0aa96eb25242526302a3285ab9bcee8c9b40446869434428852c93fa4045652c81bed6d97174349e02b67b4b43e993de206097cbc48e3e621e608fc85749aa2c734b333023978deb6089c58a848a9b359f24e128111a6eec992a8f5dcfd10f820737da759c960260aa1282a276da7c552818c2070f6616363397dcc07029b2b22ed86d2b92ffb03c6f622e5ec5bdd26293ee0c23f72fc1b0f41a67bc0e7f8554a1649a23b3ce04df379695bab8f15db01373af39bdde4a4a242142043074b126f2d99262707bcfb6637355183034e729217e468ac0e326ec06b72b7aab497954d9561032ea5bc9a9625dd0695caa841b6412b92d438914103aec7473b0b4e7eedc8d49bf290052bde954f23668dec522c18bffc94549f62400a1eb0e0a44790f69af335ad690b1bc40236b6b0412a60630b1b840236b6b0412660630b1b4402362e30011b71f078059354c8316b4816cb84af06011eae60bcb5caf2ae294f9e6d05a739ad24d3525975b783218616f560c517e25b5269d15d8f55f02571729694d23278a8825dcf6717d306a5673b20031db871a30b47810e1d607c9123edb871e375a800061ea9e082ce6f2a29e615edcc0e555470ff1949b54474d4a46a233c4ec1abee6866f28e872918ebd4fbf020ed8292799482bf0a0dba5ba204bdfc48c1c90e161a3125798c82cfd5a33e652d3d9aa31ea2e0f562a5fa1c52a964268f507032db574590b955bdf40005a78334117358baefec797c820d795355ec8b1e4ac9c313ec8590d247f1d31325280f101e9d605490da994da8bcb93225ede0c109369552d1941d3d356463f0d804bb492413dbfc1f3bed9a6025d9e59dd8a273867960f0c804eb6bc18205d1a14665c5e081095427a9f157c97e31868e9580c725f88c3e22c326059d7181c723e47d06cb4be5183a2af15bd8bd9f679b128c8d92b9baae3777d4bf1843076ac063127c0e91458a5bbfee3872ec18230cc22848470c0d6c2567815f053c24c1061f69226ccd4830ae39a4a037dc8404a3e2263565ccce27fcfd82c7231889c1435bef7604b71f6a6b6ff75386c9a3119c4efdaefba57a30820beeda9b97443ce0b108268888a87f168c828722d8a4f4c42da12af7c41c143c12c17d9b56e9b859a445cb0311ac046d77cfdf158eca83c721b890f2cba2ffb628bffa0d1e86e0a4d999f87757082e87c6ce924e242f21941e8460d5d3a59844dac9fb111b049ba2c6cf79d46c33d382e094509bc54ac4f2897904824f4127a154f4e7c8db01c1d7a63a9d628e1172c5a6e0f1072e0909aef9727f52e843e0e107ae3704d11b5f1bf5ad471fd8a0db69d48be9b4343df8c04b0ed3bccb252478ec81cd173be8d254e5d0c2d17d881d142430bab00b00103cf4c0468e6629b45f27ab5efce09107fe93c633bb94c9e2c8f0c0597253bfd1be6c7d2167048f3bf0716d2d2d640e4916ca2d78d881cf509d2ce5300d95d781d321655656cb972548b4e04107ce7474bd749df4e50dcd811f75dde65532d6b8eb21073eaf280bb2627c8fe92e81471cb8bc9e665f59d4697239e001073ebf9a8e1435291e6fe06356341942f28d091e6ee05bbd72fe0db24c9989a305270c331978b481cb394951cfbfb1aa325f78183bc6d871e5c10626c9ec5e4a94aa1ceabec0630d8ca757f430b563297335f03149fb8e96df64d27f0b113cd2c0f765fecffb3d61d2c62c78a081c9299a9e2382d23a4967606db227a146d89ec528163cccc0b82921e26e2c9f1cdb32b0c92f467190819139e93791e4e7381a2a24f018039b338410d67b31256d1bf01003fbaa498a5d503a3b84b6048f3070a66c930c1d47b55f0a0cc7943456d25d2bc1e30b6cdde8cde9b1cb74ee385aa0430cbd828717380f6a7dbfcad3877ebbc085d7a9884c4a7bd0e102a3694925e854b7c0f9980e52e2297f53d10a1e5ac0721e0d2ae446aae091053e6fa8648d1d1ad444565df0c08297aa479859fc0abc84a851cb46895edb0a7c90dfde2e32fea9a90adc066d7df24ab8fa54e03e43f57966bacb4e81f7493172aacc4ba18ba5722995321f055e3325896aa5172bf350e04db3f376d929a1db7f02a73a7947c545855cdf09ac5eea076dcda263f49bc004cf5144aaccd39f3e133855f12c4b0aa1f2cc5f0223dcf472c9cddf48be12b8142237affe78d6f093c0968e65bdc89b62d23d1238b9e329c935f99ef547603f256bf650933ea57e47a5c949d34a70e71d84ca9643095633b86bc8ec24f88c9a63e79f940497512d491db7d4798491e083ccd9d245de8ed53e0d4864aade848aa351748f821d670336091a8f60848c5b413c54e7c71dc195345de7666a04bbaee7495e75868a0a23f8d0ab20624417c1e7a9ba20661d73f614c1e54d0db6b9f636b49208b6d2e9688f31b6f588d84c6434134a7608c6538a489fc97208779b8b2d0c0d43f0d9b549ff540aca275508464e4a8e11062118cf214cc5d1bdafef0f824fbdfb510b7241b01e96dd3546dc1f650a04772a846c49f99eb6090204ebc14699aa49273de9fc81f3bd1391ef3c7ee07774e3d5fb875cbbe9032f31644a9bc6bccc357ce0fd5753cb93660f5cec8951ebdf54e8bb7ae0aba2a8542a836ef6681e8cdc12cfd7e28907ce92103d31787ee91eefc0c6ad1c4c5abed8818b39cc3e3de705cfd78157cf9f8489c6b4392b3af04175ca7819a4258d990397530a49454c264a47090b68c8819598c13e84150736554a4ab27a8d5b88c3814daf9cfbe1f71bb84b4ae78edcddc089decda0cbbaf74edd0636a6ca2fbe9577da64d8c075ea5222d89fda5e740dacc8f6d49b37a806de7f84083958c839669706ae2496d03946fe247434f09b4262d299fb5eac7206ae84f6cf6f1e4a249399810f22e554d9eb32b06e19926d940e19f8902c54ee8da977947a0cac78796bce9253a5b41818bb3ae175a623e78ce068810e31c2c0ae47fbcd29497eb01218b8cd67a9fd93f70556f32af57684c5909917d83ae59d25a9c9415845031a5d602ba5a6cf6a4ae988991d6870818f9c45e8df36dd10475e70b181a5b105ce6dd369519a94e8a4a3052ee5e7fdd5dc1d92a259603746caa0eea7e244110b9c5b6acfea96bf026312526aaa7117216334acc048099ef267a5142f48a30a5ca5bfdbafbdf5b594a5025fb16c83690795ad73f431ba382ac017d098c2e291228aa8a454d19002b71f4443d787a8161b1b78c016c50b34a2c0a9260bd1b41e9e46690c1b1798800d30d08002175fad339b526a39b883c613381135bff42e7a8aa71750aa8481861358df4f0bdaf55354d57194c181461318b5cde7fe1a732c956101183ac240030d2670da83c48c6e4a62eab30c3496c029ef13eaa9367b4990d15002a7dff25f3bd2e4895d0e2d1c6178914a79b145175f58804612b8d4eb4a492b8a042e289534ea0633a55febe31928a510a071043676964ef622358268530a348cc0adc44b7a22e6b459544da051044e5409cf215b9e38a944042ec35a74d774567c1110680c81afca49bf52c4abcc7aa9020d217039ba74090b324fe62a08ec290926c1454408518106109890e495e89646aaa0fe80afd69c534b8714ffb328d0f001574aa594f4ea95e9b422a0d103ae57af92a6d2ec3b960cd0e001db63a3b761c98249d61c81c60e78136197ee62e80fa937020d1d70e2ff3175ac0b3adf99432b0c2ec45893018d1c70390691d73dd3f512061762e0d811061762744103078cf63bcdba1464a040e3068c77648d314516c976db804f4b216b9b29dfb7c91368d480dfb6d23ebf4d3d7dd1a0011fa459fc6c153263169cdd9bb6dadf376139b2e0a4de8e48f2cf34cc8805ffaa9236d7f2657fdb033360c1495131534fa65598f18a728b4dcad2d9aec00c57b063dfa52b2c58cc21cb21cc68059be49769d0bfe725439615ac66b4ccd851447432550366ac824f5971efb23e6dda76862ab8a483074bd974275d71093352c1be86fa4dffb9fd928f0a46435747e750b9b5834ec16d52da1d4d57bcccd514769e1434799fc508334ac189ec7699b71bc2724a0ade54667c932034e576678c82db6891fed385cc1005a73972758a9332a599a8302314dcc8bc4d2a5eefa5e08282179dd926a9ef6b62ceccf80497530eb641095d5a3ff7049784befc38d2e4a77d3ac15f5bf747b335c78e0381d3199ce0b46565fe379dbced83a3ca143163137c648dfc9eb7ffda6a08d8d8c2c603b6b0c136b6b0d1802d34c1675226f72f7dbe3023135cda10845ee650113bba0516666082b56c11746307675c820b41648af9f653841cb28019966062daaeafa0aeda2cb4b1c5186654824f7192501339c434da86125ccaf190439b9981044617ae6312dc067da6a794d6955f39b4ba0b303e083324c196de0d495e3a1b21ea48b0935da2e64c419060b2281d31974ee2a6848f6025fe577a9852e121770413728aa5f8e9d35a4b663482d31bd916538f8e3083117c74cdd74e593daa25bdf02202691b8043cc58045bd1ef2aa9529e79438ae03557f2aec816edb42711fc5a0ed9d6e2410463216ed01f2166d6c839041f84c4cc546117ed5a43703e7a3a53e45821b8d0e3993cab4fd54d08ae8450bde412f39f84e81003479587d1820d2462c62098a4b1d2d5f34316e90b82abd49bd9ed8329b33b10dcdf6e0ebab29724150182fd78edede611f278f40f8c69ab3f75b671d32a40c1e62366f881f5ebeb11d2ea2c5abe0ffc55c7cafece5515743eb0669182f0f4901df2b3072ee5a818214e1296ffd3039b4c3f72929a5ef3a57268a9000538fe781738ae3a2001731580e185eb08402066e481d39a1154d2a022a6d5f1c05d06559363d21a9edf81ffdb20313ceae474db0e7c2cf1d7b2cb1dbda375e03705b5187445f5e9920e6cbabe9873fbd69412e7c0279945e65dcf4cc927a6fd8b15580000aa98210776426e491294478ec98f0327b2e385507582039bd386beab3db7d1ef1b1855c942afc8f7b6f204ed08c60c37f0b59752c5bcb95deb6f0393763d5f48b55945c6b0819359b2fea8fd2079b26b60b744e8babaae8d9b570372848c41e8e86f1a1899befdf2539e986488063ef6e556aefc9693b2cfc08714da64c87631490d320397829222476b4f2caa6560944ad31084480c79f46460cdabb35e8292a5427e0c6cfb65a618835c0c8c25193a657dc8b1b31e0636a7dad0621a4212afc1c09eeddda8d2a72ff079eaa3a36e4a2add78814d7709a61642aebaa60bbc78784efda6e102a37394741fbf32627e0b6c0c4942c98c76fad1d50223536df69f8e27c966814fea937ecd251618cd88a9be976f17b91c5a27f8828b1d3ac648ae03479da0991414665c81314f2999e5106b7df3de0596cfb002a736a7ca88a12be860e238c1175ca0209d40877b5186821955e0728e223d847ecf2552ba382ec60e1c28e8620c946563030f6080316f30beb89f41056e83dc8865a332ef1de98b8303477f7170b0808baff2850e0bfcf109883106056edcd0e128d071bc281670f10503c0831953e04678091169d3bfa2648614b8b4416dc40b966d6b93436bfbc60d0e9828b0af395993ccd2983a0a057e948aa62a3fbf3c98f1044e099154b9b27437955608339cc0bbea086d79a46e507130a3095c08491e6b27fead884ce0a3ed77e7cededb9212011da7033798b1042645ae98aa4c6707515202e79f747d103a1dcc48023b69b494bedc9954f410099c52724379d01dcaab37338ec086c474ee1743974660527a8a418847af084c5caffe4a3146df9815e30b2e3870e346210263fd357a3b9dffc5b0cc60c61038916b4cc4d19f35e9940b6608818b7d2e4a853ecf82c0a6aafa87851ac78e436ac7026a3003086c28c949691fd359321983193fe03e65f41cfc7447440f0b66f880519372fabc37cd49e66c1166f4804fca247aba8a179ec61d3ce0c7bba36fe48ad88e2f8e0e318a0161c60e184f6a21aaae9f04e1660e66984eaa246da9949e03be72c774e1a9ce269970c097dd56ff58325def8a0d66dc80112965b1a0aeed554b1b705a7931e36a8ec9d3ad01e76a75f913626d0ce50c1ab09ade5a33a485560b0319b3b0c3b36f5398c9dac5f8e2a4d3012bb2d08245b5bb78569b2423167cde18740e1a3b5870a79dbf6486e0173b5d84e185eb0b64bc828fb12f0184e025c5531a565223bac6c60626604307c1ba9f106db59932725210e64caa83d0fb2924ff77081f81e053df5396a067396777820f40f0f9bde6e33105b533b1e1e30f9c773495f75250093efcc0c7902fa5595bd9c79429193efac0a7d7575aabe8aea0c307c6fddc4a3d85e41e58d3b4906741add6d71f7ae0cc3a06f724624a4247ff9107c6266ba747dcc9a22d1f78604c44fecf154d738595430b8cff820ba2838f3b70aaeee65e5ffa473d36b610400e3eecf0f9a638d16dc4b31c5a2b383a70b8bfd58193c147a452f1e4093dd1814d2e6abb746ce7c0244d49f7a27b7268e506bc0b14e8700a9c073ee4c0a8512f21670b922cf42ffc04a6031f71e084ce6bff4da1b36f0a072e2328ab0a96477aec38f0f1066efbdbdb424e11512c6ee0bddb46787814d16fdcb831838f36f0e6c9d2fac95117526e470e1d384e7050290a6480021420a6c30b2f8a083ed8c0e68a14a93dfff4d28f3570b5d9be59faa5e5fb871ab8d6f02c916b64d221fa9106bef7bf9392b42f42d51f6860474566919474d37bf6e30cbc89a6cc6a29a6f4261f666063652d4d32bd9652df4719d8a4845f977a503a499e434b4df041065efbcc1c03dfab66427e4e36494d7268a1e08ba303c78718d84b217ed9b985d8df8ae1230c6c6b2e4fc1c3b4cfd361f80003b7a75f728ed61633828f2f90f369ce21626e8ba60221c0d11f5ee02bac56c453e66f497268e1c8808d2dc84717b8d2bd110b1d65ee1d2e702a9ab698d47e47af6c0c1f5be0a2a5b8a9152adfb82106185decd80f2df07ea3465e8be6230b6ca51c44b4ba5ae4a4fdc0022337d3b78eaedaef908f2bf0315f658ba57b52d2b815f809b2cb3dfbf85105c63ce43abbbdd2967e50810b5a2c988f58f89e3ea6c075468f9e3a434a7c488193626a9d7a2df2c75013cf131f51f880427e31eea952761727c761e0e309fcf9dba64ebaf7e39999171f4e602d87aadcdf4a11d9a2253e9ac0240b21656b089120a41f4ce04784452dd31c423c1502bb858f3bc894d2561c9d600ce48de304607461f0001f4ae0aea35958974aba52b4c24712dc16d3bb112a6e60023992188701376e4ce103094cd011a39a7dae12253f026b2e4994c80db5592123f09573cab896828e6b8ac0a9acf02836e61584ba880f22f06d2a78d6d05be1ba6b213e86c08798be1f2a3c4d16c78381c330c013172ad0e11a2895237d7174a0cc0d7c08c13d7d6abef7dba1a4021d636c91868f20703ab3b957a94060af445bd03b293d7d82838f1f305a216d52952e59d5ee0336a88a646eb71d64090350838f1ef0f93de7dcc9d6d5d7c4032604f53cff705bf1b1032e8390a20e387d4164c93622fb8765630b1b5bd8e8557ce4809718ed3bb73c53c50f1c70c2f4a4511d947e52495ff8b8019354445f93b89fab83884de0c306ac4d7a2d21847077cd7ed480fd125943ca8bf9e18306dce8186a84ccd8c13212851ab3e0a2272931c82c416551d240b1430d59702986d6abfcf70c41e9c51874a8110b4e459219a9d75cf72758a8010b6e75344c52a6e41eabc62b38e1f527b45e7ccb9e0b430d5770414da9c896bf2b06b7157c6f1659fa9e55f28face0e257084144ea5bf09c55b03569432c846de88b2ab8eca0294216eba81b4a051b64c648769a6dfc34d77109811aa8e0f5b44e8ac1cff2f9478c8370eca9710a7645c6cd8ba233342e7c8c1494aa610a3e7752dee57c8b399dc610354ac1e6502a8927350bcac73cd42005df159a6388aea87aba35d41805efaeea2198f47cf92d68a8210a26ed56a5e5e46d691dd60805e3aaa6f9d53e3540c166f178d27cdcdda2c62798bce973507ad74ba9c7136c9e7cd283dcd4e804e71233aa44bfd0a12ca8c109fe6d3c27fdfb20121cc46a6c828de6f76d3aed4454870b1d61580d4db07dffb9419b094e78d69ea9742931b939b42a063530c17a301df3c70fea4daf4bb021d8764848a633420d4b70aaae9e63142537422cb750a312bca8f98ba81af364419460ac430ea62fae5aa831092ea4cb9433955fccadd790047b4ae8f04832640bc2ab1109c673ed8b9ca06cd4cf1c5acb831a90e0afbb228f0e41dd9258e311bcd9b8aa988b0993780d47f0d94386beccd22c4ad70836dc4f07651d32a10623b8fc20ef42d59563c721e6801a8be03ae7c5494a868fba48166a2882cdcf5a9b58969e16fc070347f72916811a89602c2421d2d4acaf236e705003115cd22023c70c22631138e3a2c621f8ce7b4994d68a212b65085e23778f2cddd933a61405d42884f9cd27082183493381d15b83108cdc284ae4f4bb210779d526a0c62018c929df7e754a923e6b420d41f029c2bef2b90969a5d608049b3428a549281b108c5ac664b5ead6f803dfa731dbe990fbc1ec5e55bb27cb1a7de0b49bee7ade4e1042abc10746b48894d56a4165f76aec81b37613ab7f6b7d8d1c126ae881ad4a6f13cfa6b684d40535f2c0a778a523a2f7d608ef0635f0c0ad69932631ff8d3af91dd8eecc3156d96d07264b0eddcfd014a1461dd8607282bc92acf59dcba1656450830e7cd6c5a45d42e4dc9e9f0397eb94ac499e9d9bcb814b9b344aee7890691407b6ec4dd7f78dfa2c7138b051d34949195266c4dfc095e63d91e2686d44ddc06778528d1ce936f8b731d69a8f121bd86a1d393a5f7bbd92d6c049c8912bc4a44d7c4b6ae0e32569a93508a1cb4a6960359d8bf6efe7cb104203b7eb163347d252223f67602c47d2bfdb1c3330e66e5b1dd275828897812b2522932599f44b78c8c0776513ca3f6dfc0d9931b0daf9b2978f0eb14e2306565f5d6f57fc523313064e2591d7bf3ed7791c0c9ccabbe165ba52b4e80b4cfc1b61315a1ce99ff50297d466536eb92ef0a7dff6c13ec7acd4728193d183f9a515a13f64b7c086eda5c62879d2a6b5c0698aa2524fa259e0b76b6d62c8799983140b6c348f9f4765afc07af6fc31c7d3a52cb4029fd3f44893a0a24d50abc004212ca7ec954ac94da9c0bec88d39a81016c934054e66bc1249e74b152229f0e51a4183c8a54382320aac9b8514445fb9a832a1c06da860aa2c9d89d69fc09932adaba43b81df51ba62cce1e9d3a8097c85901acd6702a3a642be3caafde359021b2fc6603906d9b7a612f811b58ff9fa25940476336af85eccff202430a24c9608d9edb45a47606d2f7e0eeaa1e349d008dca60da57ff222b0317f478e9913811f573f9554fa29350e813555710f293c21307a27679f9c267b8c5d1058d5ca9072b4030267ef218b12964564d00fd898e29d2afb33a7d0075c6ecf65b2ca2fa3567ac0e9602a7fe2a4f080c9a93b9a49ba3c95db0ef818546dd7064df144a603c6bec2444595d4ebb11cb095cb4a72f6ce66711c7041cf7c736faddda56bdc805327b2a434211bf09fa7314f87906fda1ab0935b47ecd574f4b4060d38f513aa2f79c5b59c053b6a21efddc9a8db952c180f12e26de6c7b87e2c1811d2858a9be9939081052f31497c2f9d4235f90a36bbb3baafe94a52bd2bd8a0932e765d48a14c6b059393ca9a83b5ac60fd4cbd0a3e4b08376d49a7cca2a30a4ec5dc935372489b924d055b7d49988e39890a36861092734eedac693c051ba92208d19ef89f33145c0b6898820fd26209095ae3dbc74bc1fee668427207d34c2229f8d2f9d1cc64879c9a8d8253dd88792354be4314fc6810c9724d3779c943c18b44fd4e32dea0e0a2c5db20ba235d2bfd092e7708393c8614c26ae409763be4ce58163a69e67482ab144bef7258999887138c6a93d9e4ae4896acd9049b2fa6ee3e32a5c78c26f85839ebb3c61e69419960a4efe51482f4d2d7c18449249172df622ec1c9143cb3a6a5aaac5a821149a925510a82e07d726b5ef2afa0f94070266408f393f963ed80e02f89a0a1f4d286eefc819164eba15ba134c8f88109f69e3a338d7eae7de0542da7de562b9129c6074eb4a63d95bb228910db03233fc7de4fdaf4938e1eb84c5a73c84fefa0993cb02ad613634af1c069c72da59eb9acbf3bb0f97c82767fc60eec06491b5ca3d8491201831675e03a8a75e79c2157254d07c63206a5936c9115f4670e8ca7ca206388460eecd686cc263c64d17be3c0dfa8e6e63af9164385031b24e80f2a47c9667dbe81b549b9574fd44c65ee88e106f3fb6fe7f70b2e8e18ae23dbc06ae44c3ea2d3a7feb46003934efb95fefabf3f79166bb1063e8b07f3ed77b38fab811321e58a1213d1917e1a98e42243772cb9a7bfa381b7092149db889a75e93370417bd0d4694f3b7333b041a8bc1a2f8bd44b3965e064875b2acd8999364306fe4ec99222bdbbbcdb31f0b931ad7c6442a08518388f563fc294302d790d037b22af629b0c4174a7e4d04a2dc0905a7c818d18a225a8e4926397fa85165ec01468d1852b560c92cb2aa5985482a50517d2a5ca936184716e145a6c814dba6b9fbe628f086e0e2d1c8866630313b0b1636c60021cb05068a185d3220ba605160a2981165760b466cfdaeaea6b8bb50019066861054ed6d85dee5e5125ea2ab0de952e89f85a323df4002da8c0569508caebf2efd42b052da6c0ebfb69a5dfd96b74a5c008b541837e8f16b4a951e0b3e429b5dd5947d4f5042da0c0572af51aba792d9ec009a54330a1326f94667368556d2079181ab891650c5a3881b1caeda7164f4de49bc07a0c399e3909372162029bdd2445123a889ae812b8512926124f25707d2bb12cc34f021b39078bb1d4048fda2381efcf9e11d7fa2370595a7a1f9407f5593702ffaf49e974bf6b99ee2270359aca6dbcb75a6b22f0515f84a5ec8b7eff10f8d29f6ba38a84c0c6b21d592f9a93dc04812b619bd12a757e3281c09d4c3a7b24d30f98a0397ff04a412b7dc9077c8e7977cf54520fb8f748f5fd67a1829e079c1e57b318f1be436807fc4911ef5c121d305a2cde955273c06e0a1952c896d702075cf95edc4b934ce710a4c50df8ab7c93b694bc95dcd1c2065cfef71ffd8a17f276b4a80193269824cd7ac9bb375ad0800bc1268594de654a6d66c107ab7849c8989105dfd1ba946c9360e9df587097b935686adefebdb0604f8b8b77d03b4f7b5fc1267da3b39ff0cb5b5a57b01a74db238af58ad0b682cda3fa94d0e21f27baac60b3630e65c164ac28d255b0e1a643f2dc54f1185505576ba7b3aa8d7e8d9a0a36e29dae1ed724ed525470273db55fe490ad969e82b118628c94276a0a2ead56cfbb735ff452701e528a112dc7cbf9430a2e4dd4d39eb37b8898a3e02a2fe535756ab52b290a2ea58f299d122ae2d6a1e0ae4774c49c82f60c0205234a63f013fc089946a8969e94a3e8095682870ca242ec049b3f2775a2e3a7d61c7282cb7173b668fa4e63ea36c1778908955384741e2f9a50d2c84efe37964cf06b9d930c15b1eaf498e0db43ec4b37e61fb376093e76c8912442fccaad5982d1c8ba5582df929a9ac3cc7d45a3042742c42cd974c658a29a04a34aa62043ed2da8b52451b220e3a75e5224b8d6984bcb74a9535a48f059e47be8603e828f29b2950cd13cfae8087e35457d75e27b758de0933c53afdd63ed298c60a4879c91b2bc736364116cac521a74288b7944882238cf9932af3289cade26825395af6a3bc9a415728a08ce377656804330c9e42695f431c5c43704972ea69cbadb7527e71482136b112253660eb23d842863b0b89a9b6206c146755d13a1a729a95410fce994d74d9d8e869d81e08465aee6d1699f441010ac59778cf92b850afdfec07936d7bffb2a15acf30393d44573d3362de84b1f3899f4f5f8ed5e755af8c0b5bad5e40bd97e54ca1e38bfd431b5edb607ade881310bd3e6eb77af21250f7cda969cf8e9747a53e181abde9cce844a4d975377e06ceb742b857765b4ecc09a4850d1939cd4b2aa0337d1dd4a3bdd4a448a0e6cb699aefd909a03a327eb5637269996037feda6e63147f41ac5817135dfcd6295f47be0c009fd953d6955eccbbe814f4a081f0b4ae77817379823c970cbd136f01d5b37828a101014800dbc29fd418479148976af81b111af0a3ae389f4d4c08a0c7da79a9a543594063ef44ee6cd29b134b268e0f55465ce9ef9b7ef33b03af2ba479decae1833b0d53157363dd2b72b65e02b68d357593793c4c8c07846091e54ea1bbf740c5c9fea335da23fec1403a7424ffe5c4a448b2ac3c046cd1959ccfe4566c0c068d0567b4104bfc07586e0f182bcc02599428a88f9eb02bf751593d2f47181b3a4fbb2ea2d85e5650b5c65fd20d3a4ef85a4a205bee295d41331bb4c2959e083e5f62fb10d8b55c102232c8ba5ce26bb0227b3d4fdd52651619a15384d1fcbdcb2d9e8d1aac08d4833952fc92a591915d8da167df7a4a64c3d054e7f571231674b0afcb6bd8898c98927ad28f0f9233306f118a3490b0a9c485c09b9d3e94bb39ec0f5c79c325dccf3f5ca09ec579b664b3781b5d12d66723386f299c0a9f79026ba2a33be043ef8a4281a456c728e12b898ff944e891f1e9249e0a3889853c7cb413f8804b637447e5fff09ea1d813b5da739067d79296604764c453ce6a0725e844ca000456037d4c9899e2775d7446093d0bdf5214534290e8191e32124a4f6244d6542e0b373d404d3d0be292e70b818a71e508020a0955a52ca2ac1c3ddd328fdace06b4105000277a2471c42017ec096674ada92bf55aed1d1a0003ee04e64d0a1f35e6efd0d0705e801e7a22663c7f1b8800b0dbca0003c602cc80c936f1253e5ba450e0ab0034e9dc64b29b5c69c357643074cbc8b41df69ddf353b7a00039e02e549b524205c001ff1d430711537c741670e1050e34c60e6501175ee0f03f0628c00db88b1eb3fb4325e8e5779c85c059060a6003ee227e964eeb9492fd05a8011be2e94f5a2359f20d0b4003aead455e8a36d3eb3139b494371815b8fd9805db29e6383abd6e0ed5f9172b00030718626091057cc8828b933d66f4ca3e69f7c1b1e3c610e368a0051fb1b0ac7478081e3432f880051f4b6b8a93ce7292267a059f49a72821c6f6c3157ca5c66c6923ed06f9b582bf2b1d2a241f3f58c1e6a86f4274b86afed22af88f3c42574cf1c775f4a10afefa46a78e54f57ffb2315ecb95d7896d2ec6b3f2a18ddac9b60ca7d349a4e510ea6378a6ade146ca90f1643bacd91d4a8146c5b881ba6695dba37a4e026b5f9dec56e14fc8d9dcedd561105973ce8cce9db534c950a056f6a5f5782bec9a0ef0728182147fe5f0eea4f70797793fc623e3fa1798289924d4bc7ddceecaa13dc7a2475f31141098f7c7082cd223429996983d2b13e36f1a109bca13a3e32513e30c1c5a08386c4bc5832dac5c725b864ba7372fb6b89d1cba159a47c5882bbfa90548a64f5163f8756a9faa8045721b46b497dfba0e91c5aa4b6bcc1f8e21af04109ce638c28d174ee9849e863129cde04914d968e24d88a112346bf10178f5d043e22c1eaa411adb316f7ff3e20c195da7595eca08f47f0df1b838cf963b6baa00f47b031e45831a51311a34a1bc1bafb687dbc5c9bc6c2850f46b0934c5dbca4758c41868be02ce4adb4bd493fdfae08fe43ab55501ac2e123119ce6fc1ad48990d32d09116c12c1f7538d8cd4f71e828dd949dbfd53cc0e1f86e0b4585a2abb0d19ca367c1482495ebebe6fbba5806fdc08c38b84868f8c7da8a4f024e25824100883a1703810808102e603e3130000000c201486429160248db465fc1480034b2824443e2c16281c2014161a8744c24028140608038160180c0884c2e15048201ccf84bcfc23fccdd9b69cdbc999e79ce7382bda9ccdcd90cd990f73c6dcce96250f9f0356c899d94abb0c693383abc7709596ce29ca2e9d82b9731b616f895c47837bfccc3d8f7b0ed169fade7f1c99303dde814deb1166c45d17335dcd2866080662750208a22d4acfbd8604ee0af7cbdeac53946a23355256678910c3f65c9854a1168be89b326a1661224fd6afd2d834fa7f6ba163cc780669085c05be215e24f785c3c2091c82a5b011009d7eb9d6810d19965687ffc01b79050cb0f5b5b7672bd90d49735ed176c4c29d8d26ff6656b1e3c5e68d6ccf32d42c88053d878cb4d89b356121c6e908fcc0d1bd5cad382fb3b985f4189e1093ff24a0eae6b9fdfaa5c7a996959b0743986eb3e77bfe4605f12f85557bcef57a853fb8c2e504163bad26ee3c3ea29dc52ec3ff66161d54e2d4b1c5b3e2b1d8a8fa2dc1c74d655e42884f4d4810f3bc45686720a124b49317bc4b00dd21d03b6a1336613f500a90229a4311fc3d17d50eb0280a5da010519193d28dfbc28a775be808433e704c21984d39b0c669aad8aca0c5806e182d8d867bbadb9df3cc3f86b525e4119e3efb0c8d706a78dfc143abb1fe5c0be0c2c521203af53ca677c9ba39e3cbeca9f2bebc27be75013e16e90f2092a199c3f5820ba5d5bac5913d05fd3d76a36e59f99f62c3158687dd53c9fd0d0f09e2b431be040f1436264a3ab96e5837d71dee86d59bb134156ffae571f766bcf11e8cf7cbbbf24c79a93c40de9537d1bdcf1cfd78a3c48f9d5008e8e819fc591a6ada7061db859d298fb06cbd5afe4de88881a8bb791ade8ab79f6fc28c1d2a15f31502527a13e44de07ae7b742f73c0bb357ef11f662e12d4432e6e2d6e105279c8059942ec486ca86b68539070ff4f306dbbcfb8c7f6469779a9ad6d6e460e0f52feb163274ec32f5c5b8c9815381b6604c5444de1d710bba30f9860b3a6929b90bcd9de75673efdc656e3f37b43bd4ad706fdde56e6f37843bc48d7add0ade9271a6ee3e7ea8e28d8a169d272a257e744752c67b9c5f0aee9cdb39a6a5d6a90aa9876c593a757dfb6dfecde67b6c4b5627db17d51a7852e9d76d7a612591324a962f1a4ac820d435cb2b47c6a3885148b1210d1152344927471f21a5202279479bd1ecae196a8e968b5c85bba4161d4103d0b8457b982332b1d19553c8189acb7927775e74317ac0cea48f51a9c552f9a8b1e799c1364f4e29153cc4d252a0a897a4a537a33a6f15869f05fb91614864694b76b2e641ce1cb30551477508c0e4932148e488940265835ca018c424be145e26d16c32e43082fb265165683c125a0171f9de345d0d14722bf73ccf4b5eef8122d7d0dd48bb5130da3845b20b0ce1fa21a9263f386e59ae48006dbd0dd2fb4101030163b313ad0e806b7b9135c8d4e8b36d2784b8b4ecba2f7e6fbcccb7bc7e71d0cb1288cf4d76b2f0555c40df0435082727b1ed7296cd0a83ba6c4df8d4210763e4ffece9e133f723b60a90efc57503079ee3f01ea559081746cad4dca70c00ea7d8b58dd8bb06ee401d05e25a05eb73dd78d934ea15db7a1745097603af90d5070b4aea9f052948fb361c7552134e496f19f0c34dbb77ce8c0d557251e7cf83215a122f935e5bc50db6d668269bcaab06e8297114998b432c92ce1d823e6783c1aae200af5ef57218fa4fdbf9dcbb015d3dec5fa2e8ab104889334ca906cf1b43a385ea9c07b2c09dfba501a262c88e36d4460cf7c4c3d4c0552c389c1010e92b78295a6b1e5d9495c0afa9a342b588eddf8989866462f8b5b2440cd9061b5c69132b7c48b483c7767d28780369438019d780586ca75b854e7d910baa21e6ba3e173eea11140c9b570b904fd41ecc560a217958c710becbd45d5389aded202876af974244a67c73952ad23619c2359f59b6dcfe3bf27b20851dad1a8b476a1b437443670d596c9630e547ff648a3749d2e00722ef2c6299394c8e993409bcd1d51553acfe093925723dea2900c7a55f6702e5f1f0a5cb3a2e8c8da7eaf2b330320861109db08ddc8add9f8b2359bb21ad000cf634ac2f598b19572b5d7708f19919632f6ae6ee4c0193252aba1ef3f8d4c441fb35297b165a611137747194e85e0883819076371a71099cc6adf9bdf4987f02ef182fae849bcddee61fa210009f1bcf999142eb03226982cee916ab5b02d44c8638000b246e30d3df95dbfa1be68858ae49e3fd0867190ea866edc860df2691ead54994a8555a2810f9e03a87b8adb40b4b81bb791cf86d3baad762f010aeed10190c80f89f19d2021873ef935831249264f3377a1dc9c5696c5c95484ec51fae7c0ed7a521bd037d182153ddbb0943d6f5440c1bd0ceca4fa4256974d0162b8b551462b1798ef7f3d5d5f44ca9d8686cc723e80a2c24496afa0f1d15133b6cc24fe824cfcb0e117cfea3abf962e31cb05af36e1be6dda2c07ec38d240c0761465fa1274c1a449b078c7b17401a5866d7a3468687e756852de462442d1c01cffab5d7f9e8b21c98e0b29fb214d56d44b4e6d41485d8d840ea2496a5dd51c30814c6f83c87ada6c8dd6980db039807197050b388d3433f6c9168949cd2d6bd8e0a70f29b7535694a600fee9b95fe98d8f1a6058cf8907852b3ef7ce25afaf81217188683c5459a21db11b15543cfeb47038fe752987062bd70956d0fa79660bfe538c4d10506ce825ca1ec9f18ecfa36c6a13045040410b2442bd5599307717502e0e697eb016517d8b090b497808392dc5c5a9bc8bb9d83fbe2f26606ab7520f9aa8cab5345cef62ea4796f45b325e6350c351528a86e3341311be125464182f4c566fbee8a3685c6452dec82941eb71c65412a74d56baadff13ab9b36d9c4a1ee4ab0575c83e8b488d15d9d3da1728f98bf1c840d621ffefdc294422da4424ba5e55013bcca5d07a3841724605c56df971d060567a16871405fcd63ae10619c3b8a9cc4f2eb4f6cd9182de961267e1278c9d59e06d00f5ad3a38fc3f19846635b4ac57707981c1b374094bb306cd73a02b7ed97a5d36822429e2c784579fda9809789b0e06ae0114ffd2da224e36f20126057b42f015905e4e28c09a4c915f4e2cd73f5ae06e0c45fe7bfd04b68f4267c235863e814c442c77631c9f9a34274e0b1655836d63fd7febf448e5ecb4e9aa1f103b0aa1bd456b3727e60278f5587faeec1aef32fe58362324bd29f6e4d061b7a9535998d0965b54089746c243fc63d7214d999f9a7f864c94e08ad517a298a654263eca4912262adee08a1b85a85cee0b35e8b67ab9c8e60216e5a5b67aef7004410477468d6126bbc8a81240518a7332a8a205f5dada0225f270174a03284325868ff7e2e03d05ba1b6f23533bf0a2aa8b73ed36dcc197ef27d2842010caa5538c60eaa81338aa1a559043f5658963ee5da999ab2847181ec470666b9ddc796797f29e3ab2270833f833991556e4b030611163d0ec60baac74a6faa4fcc27c226b87b2700c9e5a6cb4379bd3aa6b8cc9254b43eddb05e61c43ee4a91a1311891fe33f358e8da3178d6b49eed1ce3ca810fc8f4675039a7e6af4340a0e8440a270e14efdde9276a19776a26df890ee0ae41030858a7bbb4db02d4ea274cd846b7151ba7449874a4c410dfd89112d21f9cd127049c80c59dbdc98e8a95e8d72bfed25cac77c01ffb338001e970f2beb1e1a1c812977ff27238001b4d8522051521641e1e23e3480896fcfe198f6855ba8f995bf1a80e8bad7f4adc6143967bb1806abcf8e590abf26801b2244ed42b22fc25a3f248712961bece57c951a7e6485e4e4553c6ca8e61dabaf409bab6bb65cccf867e69054d0f621b84066e0f219d3f34702d9aa420139d0e421509e577c275e59fcf874c6acdbe1a741a6102e9f9464c478da4f748e9e83c6c3853edbcddaadc405b6e3a0bb8cc7f1d1dea915fc142bb8868bd9366b852fd7918f263e359a32d118704358481daf2149749c8e0003034d731cc498f0963b52301352e8d97f3528518e120c98f967812fdb5e7f95c63f57ee74bcf85af6a46e4d019e8a4b4318db5023c221cc603934afb720f8d4dd6fb2ed54700339a87fdf43379ddb237eb207ae32695bfdd68bfbc8fddec44cb117b95a286d37e49eb5ae809417641b0e7ca3fcfe6c6eb8ff424da114e99c39f4674c7c55376e0864a7e7ed14fec299d727f223e655b7caec63ab0535a3d14e349cd31247c70b4f472f4577851691f627052e77b25932965753d54abbb43e051ee0082c9026c74c450ae42203b2b47bd9c6880c284a0530edba2796dc8962b62155ad3dd2d6f16cd0e7036dbf80976396180a58f54e25c63a46b57cea14db74d96ab12d3c5e754a7e3991a0f3081a5105e3ded0cc4f3e83e9522a11daf3d8876f3b1eb4da137463fac6b2858bdfc14b1dcb80d0cc2dc3ea1e6c4c21fb0db448df5116580b6e05c40590d9240cf3521a4e8c2352f837302892e1a94c834369f51057c6bd385d786d3c97cfa524254632d407bf81cab69648308f9bb6c81c8b1daffecdcbc1a04c040d53b12e167491343c9244bd10ff11e5f2049c6a3621a5dae536c88de633c4556d5253f9d170516d98e0d5b654e72527d520aa0f16ad7903bfd25a5b1837c20d7ee24bb6e640e5cf09d0f98883787fb0cae54ca35f87d3bceb2f08857d634e990ff8b2a32daff820fda3a9423459f74c0e662ec0ec29b68fd39ea8c840160a94ce98cf1dcb405cceccea4317f8c473c0ea007198e6880ed9a8fcf4a83c2fab7ebc7be473aa0136eec07269d701849a0563825409352a3b0104a167275254581b92f503b8c2ea8518f386c8b19623ac78d146d58447b1d32fc08a355c93a9e77e16e99a9ccbff2593a2afcd7911958e9c2a3aee748522a3927e5e8712f11214ee84a11aa37e3a19365e9fe1746c86a377a96207a4615932a55eb100ef6ecde046f73e6a2a5b309e53ddcef26ebc6eff80d1e1935d93590974c0f1464dadf78ac48c95ed67f996f064bb784496ccc348cbf448aa313222be76bf78f292e4b81c1759dce6bb36adc3548e6825e20dee8fa622b0991e17915b8f8c1fdac02257dccc73dd8f002ad3061af9497b795b4d80b0084f9db04fe7247c9c0ffa97804feea0a05bd04ef0a0d7a6287c003033e40aab411300e60405b63ce460cbb452481bbc0e7c4461c193649fcab96ccb365aec8185e03c7c7cd79c094ca87856ea12ddc224fe4a8652c8a4b7126d55c0a6b7d70d25dd3b9e0711489252245dc9bda42d29c1290e7d5744b9225d4b01246aa98074f3b4c08a8adad3d23eae3cb180425d25d24e5ba7fa1392e3c45e92c7298e5a96ca3a719510ea523a78bab45a4c5d484f9ce679f5c7e26339f24ab053759973a37cce2bfecacb5361c0c0bd66a9fd3105b61f8e6837a87f8a2254a290ea10a9fe2d1aa7f228595dd2fe6f670b2389c9baea04359da53f024271ef25fb93fa9aa5be2662a96fff3e7696a2686435b2fa4a152f89a0e49a7cada4b30ad8c48fb003fc8158cfe90d24b314a0efee034d51f831a85f8c61e2a596954d4d70803ab3f3ec1b4d73a4bf8e55ceff43120e5c184d88d16054f6790590ff38ebf95f2201ec106305819f1beec2b43288995be639f3cd3cdcece819ead019ed9c7ef93eb51cd0d6f8f755420932c72769ce1c4fe8f14356b5973fc67714335cb4f3ec88ec299de90970f5dd73418865d253dada3aed3f96b829bf2284bc8cebe52c673a8f426b1888e493ff4cca36103a1009f3ee2c537e14fbb89d81313347fe8370035d514c86d40bcd159683b6053302ff9c96d679a30d68f33e669c78a1dccb4f0320df894e9a9b54f462d27ec08834efe3e400d221869df9cd1c220c1d7e235636327b4cdcc1d085beaf1c2113c30cd4e495f32e2bc5cc99d1bc637da41ebacdb543a2660bc70f20e9df33a1ad3566dd64a21b5475efa082e88b0bdf3721601ecee0025e3dc4deb67907de0c53efef0de38b020d7a42e71d4c8898673d0e1125f36859e1f51c1c6c185c7eca1c289c5848350a435c048cafb790486545e2c1e61d0c5e7071b13e7363184aba2434849911e806b327f01c4b58117ad9a256c56112184b25ff1187f54210d93ce74256f0f48ef5393044dfafb6751e71d80bd8822b506472b54caa1199a8817f15dcb0165e31a1a9039a00f9797536944cfbffb99801671d38f2e91e39a4efd422a11d0d8715c17562f42613a7461f90e6c42f9a74d86309d63c1c4e4877bf145f5a7a25256d64268cedbaf2c7661ff060d8207405e31db6c642717a6316b8cc16c27e944218dfabdcff02df4ebe2e7e7165934937e983215e16314a0a8d79cdcc05286cb6cb894de0d24c0069a9d852e14bcbffc6077234a2366823ffecb7f598eeb98c6ee7039c5a890baab20df2a49e4b2a59766d26480ac8330726356198778953cdd4b3eabb5400e8ba341271c30578f3f7a18a7a7d6dc6837beb0659bbf598dc4109112b7251148c97a06ec0dc844dc50f234e5258b828d78a6f364ac3261e2d2a60ba478c32af82743548901490f42eead5dd515a1f97d7a11704265f15fb8b7af19608aa9fe8509069d66c172e09f8291af272c3effcbcab6ab9fca97076e60628f93afe921a0b7e52b3748f14d5e1e3491281a5621d096f04a066f9fc2e306481aa260acdbf4067db93ca7a3f06be8e6a61deb5a681befc1d310b60a86c2c443a03c720aae06a260ab51bae780a53bd0222ba3cb4f927769fc084178f13aef04b12f5d1f74e43c118a49a0d519508a115f5541c00fc904813f3300135cb35c21c806ae3ee9111634d7f9d8f3c5750c4f84a06b5f3c9e8744444e590137f527afc65c7a02750d0a08028c3321594737515e0235dc67f10339f949467c24a7c3d7e21eb99a524dc37867bfc1af616ae3613652010d5cd4d05b67e0b2165a472b8e07e0f35a4914234747f81c67fb88684cd24e66ef858f545da8249b63525d37ffa641c20c5d6bc0c7b14e0d3155cb7ac6c0c5bd7955de2430101f3daed09c603d7350df9f4c09a813579cf234f9feb00117b9507bffa46135451bd260b384aef457b1bfc377943099bf87753ba518e0a2795d583b017f217ad58e18ab08ef3c2757d81348959b1630a97cac9c233790d84ddcbd94a404001295a34115cd63ee9b6201c79d720014110c08f40664d240566c2bda1b5c7bfd148953a56a4f16fe1fad1a26eae501b49962a50157555bcced0460fe98e3ec22c20ad98b7c8aeee7c284df811bd5e36d021a8defa91af1177e25391ebd5e27a6946184ecb8845aaa2951f2370586cd6cfa5fb55a6b6f9539fec900388af9224beda6a9c2c8bd12d56f7431dbf5a701948eee12f1a36fee9997f7d1067ef4accef88a92088a254f5a39287927a0af24c43f9d9d54bd043c404182d8a7eb26a7d6c5406cb700b7b47ee9d0f21d5bb3fea7dabd72a92a41f5b877318f729aac74abe9160a25d123c13af47541a53479e17158cbccdab65970878ced3a0ec1bea7c997ba7e9f174d73bede04133368b3719b3da7b199f52df3696e6f7498992c79b6561aef1ca30198f2338862f1df0a60a61c10156025dc54297d3ce78d848d3209c8f49b24dd8a036f7e6f96b1755a8a19802e735a6fcac53c7fb899137b083b22e5edfcf46521b0e6530995ee7ae497010c462ac6d2ebb119a04487be53dba42083180fea1454b32bf2dc165dd439301729c7d0761e49dea2717f64673411f439057300b270c39fb61596b13d0c10ac48a4cbaad4a80c7ce6e4f80ecfb72a8504071bff29f75dba42709c43424583f4f57a6390c7ff28c4dd06b91eda67e497bfe01a8edce4f93f612149436c2368c82bdf9b7426716ac4fa1cc5e176126f9a76516720f119d6637f51bf27e1efe978aee0b513920d151fa2928031df16644c42b622dd6158f8274e2512872bbfd6feec1e0f4215e0995db5c179d4924bd25543a7bf9906fca12504fa3a394d413a56ea2c47a4d492c343f1e5b2f90241e66455d70d44a01b214061f6f862689c75bf0d80b1ed54b150fd5be1ef1757fddffc72716ba1fcce9a4f62872cbda99d3a80cb7f213ca5356ee6f36c016c52259fffd302f28b13cb23173f0aa0030abd1412f6d972ff5590f8d67e45fc7bdbb6ef9850e9b93b40caffdf968b97165dcf725c360df884d2810084e85584c8374c4b5c6f59b75c4362bd01d2ce02d2e8c9d662b640b0c0bf76641ea4d0b637b0a97b2e958f0160bdb7b17062151805156602f7013067b7541e85119467240c9124e239861246fc75108cc77596c5d5e63b143916f5e221175ee1295ceda8ba483f321bc5c275aed647182b655a0311b7fc4da579f939bb29e154340e7468adc46f198c96c64ba9e3914954704dfd6f831cdc13da1f1281a46879db31a3a5a9afcd38ab73d52521ed4a191a7df8d845c3b2b4fbc06585c322c4e4e0a2c48fe3833cdc6818b6f02ea9cadb61619c8525302055b594db7de4db4ded5b1e8442bdbe73a756c65d56d089c9535301867813d5c8efce87f78eb745981415a0963208730d204e2b912d1627c7a48e4163aec994d160e678a7bdaa9ea4e8659b924114cc5d9270d57a6e4ed1f34dc5889846260fb2b16420688ecd0408268014ebe2600eab0f03a790612183687b195f9f6975fec47c3146a7f816d1d1b23dd610a23acbbdf419c90f19c8f7028fb0f3b1c9a64a25cc2a7944d9bfd29f76aa05473cdb075de04f6a1ef2b809d816080d885c6036c25f7d26f9e903e1c18d9a2c690f2648d8bb050da8c4a2e310a61b3e61f9cb08f7fc46528ee248d68174c490fe837129014ca4e0ec3506b9f0efbdc38cd5b39be743d4a8e65d5063c1a880685899f465b4784a730b496863443775f0351153267d71300d5c79013346b800889fba4d8ee1512c6f92b317e50d753d76e4c373c4cc2e10cca8ea7c2c120471e93a32de5842ed50479e062816ac6769f781a2a47fd5d25b9dd7fed580f473052298b8770e50d566d2f9c0c8ff2aa036f7d6a48a1a538a6258e581a5f0e2cbd3fa9a0249c8d6122b60b6aebc811d2797b44cb80ff27825e2120ceb43e045140449c346dceedfd4f5ccfbc488d65ed8e282522b6b2946f00fb59979609db58ea6d03c2569ef1a1340719cf51190368b557ba40fe7e21711349b696b1dc0012241c428b9420b7c8811f71c35648c9da23ae92f952f8226a848ed611deeb90a5e209ec843d614df82dbc0a3fc2acf05fb8164e0837c2c21ba24cad43042d08b6824f43da41fe44ce9a6bd66a111c7ecc8a84100c0990f481cfb0b0754382a2fee9bdae163e7f2c24072fa4ce9450782f33fa58c63eb75bf7e2c420476291243c88091a2908a405e1bb17f54f675d08ba7c96204fb097dc26bae259b41ae333a5ecb4be0415020b24eaa09301498f69898642326b1d2aec9755f26846ee8cd210e5bd491d26f8cd808656e44eca690ae33e9b6882188fb299327dc88753a326de4eec2913dc8e5095d7dcd963872dd4e95cd56468a83bf42586b56803cb0063cef42b41c5c863e691d22102acb329ea2d47f5018fff59caf96ef219e525abd6a29599aec65dc650b04c327c1f454af352beda3a5e22ba32eb0fd7e44d34fd07b5d2b311def030f7caeede5acc3eb5536a2242406faa2ef235099680394da385e27887c3265959f760f80980c611fd3a9566627a32ebbe6a165d2c00d84aba57944f1ea4cef4d592179623fad97d2880e600e635311233b973952902bb62b658a7c5184a9b21b370b8fe60d56c3236b2a00327f4dc556746a4323b0d17559d6fa49878230f58eb4d01f3faf44d67e5009c7f33dc416c018a58c551848797444988cfc275a8bd2da85a363b0a366d9a52086722cfec3b418f8d4702f636938caaa574259fea6148382440c79c528fc09190b0edbb0b9cd02c8dec1fa66797405aba8d05a58328e3ce3b37804b24300a9f3b875a2d8345be2d0c30d9e2e40a55a5e0760de9f02a66299116412797f21adc770ee9c3e5edea62d19306284a0b9fb72c65f5c1d14b54ec9cfc9a5080a5c162be5c52eb15930cb3faae303323fdc3ed1780bab1721fa05c9b72dc1e01a1c55dc7bf16a804b31c75b800dd1c6df8ca914b40022f0b26130c1dd8083c79fc546fd6f8eec49113e4ace29fe1dd1b40a255c412c0986827e8ead4a25d0b36f993f9e187574e9167adc002ccb28fdbf0f1643a3a91621fdfc0d7e7de909600e8d9cea1b92abde5460f34b0d313c219a13d62137338ce96cf2c3dd6c07601270d178d1d95e15d042d8ac35a5f2f0aa294aecf4c2a681fcd1e92da2e6b5081f766f281bfc4d27af3152b82f1b1427a608da3dd2751b35b1c6f9ec44bd57036974ca64ea777ca0e7c14fcdb91942455d7dd46300c973166ce03631fe6bc8cb7b801a0a171ea0c086b474bf6786d7462ce501a4161b1cfec274839c29599c99eb10b2542a10f52fbecb082e9ad4b52657afdd8670043a599568836db4903b1f1b225dac8686c7fcaec5c47dfdbacf94954e506fb6013f8decf2620b111829b3902b0b1b5035b2d77c3d79ec9661378b51b25d8016c670a4cd0e68813d9933f8d024e4d4eec4ea895fdd6966ab3817a726cbaadd321f029015a4f65bf482190de98a213feb9815a65caec141e687189d56712608243c6982c7eb0109894967865003a63b1f83f84f39fb1031a1662b3dcee42e2162940d082a25bd3b3513a31b20c2530e9477a4fe9c056a49f9f5ef36461daaa946f289485470061560fc4b7bc110253332e90621105bca9d8d9b386a7ad1a675b15206daaa00a2887a7558d5e9e3656bbe83bf25e8964558dbdd2344a0d7c7ac3ce03750bd054a46fc29e8bc11d97c13cc71aae8cf9fcd03d8c784aaf62f39f438689035ef0f96ff406b4e4b98473cce6b9579eb16ec327bca6bfbb6499da22364a10312ca2bdc5b08344e0e1838797d282b8043aefdf2611f84e3d717e06bbe1f6a6357fa453852d4a6407f4f52ddd4537c6982a9e2af7c5901d2c43b1092f0b3819ef564f37a6a04a8d4d81a1fa7a346187a5ce904d719ffc6efb74deea9ff6106e4907577022cb1868ee833b23c5cb608cd7b0fd308f207e4b9491538069991c3d1e00861801efa834f6a89de69b647fcb9e648c231ae80cc31147fadb619e1b480dcdcb43b58c1cdd65e0f8a25cb4e25cea6123bd5ca4b60eca7b0a56a92c4bce58463ce48223e21de84747f308097df3686e91605f7971e1e108eb7b974b29e48a93d903d65bfca9557523a3140b35d7e12bb234064d7dd704e9e6df68785545f580356d1cbc54e2e53ada37445e24b173370a360ade6dd16cb994b1cc358c9eae0e1a2b26361b66ca45216dd374f8f9d13f6b8f871bdbb9de2445afb3b04104b479fad1779449a092b9f154d4302cdc0b02ac5f660fde041baa3162988bdbcc002de380e0bedc3323d07050045dd3c6beb68208850196fa08e75719335321bef6d8bd7a22b784f4e1712167cee0e471223c23a5c776ddc9249a5bcf4a71090dd04e188f7949481e21f33ef96cbc8c2b96db23b55f6f6358347108e185d2e4f93f0f1120aaaad6664dc4079e945f02553df450e07a40e5f8ce3ddca2ac00b6fef4e44e6a805d241a167ec797b702a0880220491597fff8dc17b098f00bbd13516c9469b39182610e92e02899852cbff53c19325697d34d573cfc48c76771155b178a3cc8e56de086fdb830923674d9707a3186b617b29e04466c919a8e40dff20c41baf878c79bb1b11c7ad855de0864a0d5b7200fddc769a6364a32d9c922c56242609419430db85a12518c273ae4f42d96cde2c90d7ce90f47b92d44821743f443ebcda91c62048588b59c67db69e7d45355e3727cf0e42ee7a87382c09f94631427b910681c5330aa82c01cdc0767ae4c9cfae5467371bdd3aeb85b2ad2ce4f864a9db95ce6d71ce22d22188cbe5b4132374ff52f40495c1e914d66e03ab65cf49f79dae419102e5c47305c04e98ca4da7c03ad1adc0ef4e3f841068dc861f24aeddb62b85bb83884f1aae70fa0d6100b6a087a25ae0098821562d46db8bac21b4c62a9d093abeaa546543429f02ef404f1a7d32a343cf94f468bc9798a594756c889aaa314beeff83a9a44de5efcf9ec528b738c7ff559be327244aadb8b67bf8868ea7a808a9767929634c99556563cbf7a72813e570ddcca3b8b6ae791702e38d793270b2426dabf358627e4d78f777969adbe8af345a845d211b3a44fb070cd139ca575ddf27f2d25f23b67d48444357ff888f60008015f90336a8d59969c005e0cbff7686203a95207121f3ec5f691dae75e29a5fb83a82d9fce81cc6e1f641d445380deb97657089c741218ddaf56d3b1c91493041bd1aa3386feef390d8f724f0c070da501787f361ea0be9914f7b08de820ce6d645199cd232cfdfd5df43f76d37ded55b4c512dead744f18755f300aa1676cf627a08ebb10e0b5645493d57ff93381ee7efa7eabca6410d49666e884f89ddb65ce67eae91725133a9cba5ccae5f4ff8c3ddd9374e14e9be46e510c54cd9abe842384b8973010117474ea30c673f0e0d6928b5ab803de511a18d851dfe4253c6ba6182d9398c2443fd5d26954fc1c60ef59aac3f7b9ba9bab19796e229b00dd517d61ba51a1ec230af124a97fd046ab2e9282a8d14915145020663b0634bb8f8b29c0a0e86c23145514597781bea48cf03f300daa13dc0c5256806f8beb40b65fa3f8503a59af32ba7fe79939ecbc315fce4f73ae7d539fc51df5c81f208094012c89023e1bc4920a3150b46439fcffffffffffffffc2836884b6196b5f2699a4d43fb65e9f93292599524aea8a507fdb7bb1adce6bb700705002370ab70a2a0b6783f633402006064ec07808a3a48a09795f762b7b3b7018c25829438599f9948102331e8d11b081a310e628ae57faf7251fe28430560a3955f2e8312999580d1c8330b9a85c29994ed23e98046112426bde9d754e218a0261d07d7969a132cd4407104693e521f7d357d7e40fe60ba2e53fb473d4b2f8c1a0f7df345674b793d70763e86041041737efed2c1f0c6bd97abda71bd6e93d184497ae9efc5c8c9f9881430f063993f263296112dd1603471e100d0e3c1872492a49b12d6b2a5d068e3b20871d8c132f3b826ea7856a1403001638ea6078ad98aedfd9a225a7834955a4eb9a373122c77d1b9cbe2570ccc12c794be95eb864acd982430e5d8bfa49b2f3ccf19a0c573150b0813478607860666046197130fe7552e3a1974fdfaf070e389842ee11d52945d7f7eb0e1c6f306e8dbe9896f466a204898101316c6c1b38dc60125f5ab6e106071bcc7d7593ef53487a13101070acc1bc9ae57741d7a5d21b047567dc020e3598d5c45354f6e3ed48c958ab71e36f50461a36520d1b67a41a957fa38c1dbc7f192420f63ab091032788230de61093bb64954b86771a69f49a064ca08292010e3498b387c52461225f83be41195380e30c061dfe9e2fa4b012a5b4c1e9b7810dfa0635920d1db0251b3ac0097098c17055f24d25a70b950f9571018e3218ff928509db5056bb93c13022fe95bca4c492c818cca9bbb2b7544c072c050e3198a3e536e1f14708cb3a0c869c336554cd4704638ca154e00083e16db4d5271d9f274f38be60f894945f9dd6923eb91a26070e2f985267c7e40f2a2718630ce50347170cbbebefa72b574fff655c000b1c5c3057906a7f41733150000213ac81630b465739bf1b09deb5d7c0cf000187160c2178fac64d9e4923e1c8827135ecc297b84ce0c082c12ec7df8591db298538ae604a5a44856eed2748638c31ac803c930bf1c55392048e2a18c73e575e388d3d1351c1246fb174ef6939a6604a634244106627cb13a0148c56aa74a9724f0d237044c16416f1da547fc4fd13148c21737f36436f434d4f3007a1baa7f3236278de09c6ebeba4d7e72618f29d0863ea7cc276ce04d35dfce533a14e657909a67abdaf0f2b17613d4a302515d45e5e11d2c328098657fb71fb2072b86023c1d43eb69eb49e490e3a828d911c46e02882f9b292522907217663250229824ee710cce152cbbe49eef0d86e091c423059ecfb750ed7dd49b5040504c3a419174f9d4812820c0cc35f28ebd2ff22ed41c55cd0fac258226fe4dd30f5c2242b2cee93887861eaf91369e3ad257476615041d72bf2a90b53c8ad203ba48d94839d0bb27857c8d6a6ed1e63d973f4c5195b3109e38db791831a4b06a100bc26cc7b5d8d7c0b835249453ce7d71686fc513c4c8749a6c5ad85717f84cc979b1626d9ff9d90d35c3ca9b33059c8b8f0105516c6f8adc94959c82657120b73b00ea33fe8242c0c3ff163c40e93d542f015a60e5a34b55baebfe40a536e919ebf9f43c9cab5c260c9266dc6dd5cd28a025861d0cabe52d12ec53dab30a8d9114ac7fe51492e551844a6bd455c3f1559292d3fe975428521dfa7a97e855c21994e610a23fb22a27fa776c9146657b3acbb5ca6564ba530a5ad0cd1331e24a94f0a43f851ba4cedcd24ef4761f2944d5d52e5a5f14561cab75a290579288c7212dd84b8bd8bb183c2e435c2528c2c132be29f30bdec7dee2f1d2996ee09d37e6f558ca4d309e3a5668d50677db23c9c30c7a9d23fcf3e56a9b30993d25b39450a61f683ad09739a8a093a6974084225135ad70861c23023f1b2043ba9e1954b98c56554f6c92c215ac268651523e71257c20c5921e694982961708965563a65ad09f224cc7e966c7410af2a2749984f6915356b3d267a244c324ab456f81bbfc842c22897bccff28ac7fff61166d1eea0ac3ea7a4e408e3248addd908437e4f759e57216c4698e4979658f2751127a1bc3c8408524598724a1059eceee74b4d84513f449c7017f4e85111611eb9172e589ce8f9218730cebd5d9e53223f7c8821ea1b359284b4904298e25fd8ab6f5d8e242184d145dac5f828a195e7208c25f47da49935152a8230d998aa88b6a022693110a6549e4ad47f29b32002c21841cc6bffff07c3ae78ab5ebeaf1ff9a130eda7f4b3de0793e88fd65fdac34b870fc6d221f7e2a9f76048fe313c62877f5b4f0fa65879a62f25793089ffb7d3e21659abc38321d7e4ce509d456e7f07838ef2cc0e66754f2289b7eb60f4a03da4b42cdd4ae12328800ea6ec10dffad91ead3207b387d6940fa2a5c4dca2003998fbf24452c943e26048dedba17f3412a4a100381872342de35b6fb9737a83f9822ef5f0e979544e6e30ac6ec9a888ccf5d1b7c1a443bcefbd9899be3e1b0c56c235363cc6f885d660c8b9f9e94ca538b1e36a308d4895eb2fea6930aee47cf1a9ffd3480e1a4c419c9ff9aa256db13e83d9a468c93035aa92d56630ccc752132929cb099532982607bb6b13e299a3420663878430a6372a5a5dc660f4dc29463c93c560f211b978fd881bb286c1385b51422a3d35b925188ea12a1b694f5f3077aa7fb76a7fc88f17cc4976bd85a958296dec82b992fab64acf3f9ec305a35795aa0bf5313ebd05e38d57e70fb95c49755a305e3a799eb3ea3afd62331490057387e4b69792d2e94fc282b1ce3ac9f8f824e2e8af609219aaa532defcceb702e2773c96fe1155c17013f594d4ff3c21712a9884d6c4b4d27fe94b5330e80af627642b05937cedd25e9d4c27d95130bb752cb3ef0a14be74332f215ee509865b8f717146b632632798f774cc12fd9eac83b609667935ed977a32c12cd721844b30b5b2e112cce925d6de3a68195109061d52e6bcd905e1d725c170fed1c727f9aa9690604ad53152f8ed9e9c1752c01130533119c170a942d07d9db37d9e8a6048c27a72ca257be3f40a208241a28ca88a91ec29e7153004a3a96895537f4a59880284604a9e7a3ec5d472134ac13088a50b297e47c0305d4af2c182d07809fe2f0cd739d4e979331dfefac224b353a530b7f6c278313232744f5e9842faecc5d83995f3db85715de5e6f279498c5917866c15c53a56f8503a940b53ef4e8aee2192880be2c214645e97e81423a8945b983dd6fb920ed726c01606196d73f772511e24a016c66eddbae461e634946861f0cefb984bf75039cdc2a04c58ce963c5bca7564611cabfa4c11722c0c631fe729fc75953861619411ca530435aff6ed1506f9f3a554541235b62bcc2dc122a41ccd3071b5c290a3479a5821ebfb618549fddbdd53bb7fd87e1506cdb8930f2a5bfa5d15c64c4d0941881cfa74a93045319d5efc42a830e9b85fa9273f8541f25cc85cd85870dd14a618e1d44ebf530a8350572e661b290cd1f6dd763dcde8708fc2144edc4589708bfdb6284c7a31bba183426190dfa1e6d2749e561914e9c4cbded922fc09935dce8e16b395728a3d614efd6a3bf2e2f5aed2099356779ccbe179d3b39c3049d4ce92266fc298b7d6313ff5cb6435618aa73aaf6d24874f66c294a447b1d4b09c53b5983025b30ed94a5bf457f412c6dc52625da3a3a65ac2e09f442e91c4f38e48254c395da570e96927344209e37dd09fb2e53909e34bfe78a6e22909d32789332af983a57889846946470d4f199e119c10f7d596c118caf4f2ba875fa64a06c3ac794839e1ef434cc760fe9338b23ea204f5a71850296c961695c530983774de5fe5c748f20383d1d2b8cee7ff0be62496e339a8a4eb6e73720ae2b36c85e5d105a3c950932ea9d86c2b3db860b6d149c731d3cdf46f0bd97552ab164cb26eaa652b5ee66264aca14fc306b2db814716d0f1f3224c23076714d3838207164c65256e94e7b42d3cae602e65639ea2468ab896580d53567858c194f74a4df8ab2c964c457854c1f8d1ffe2ab04ddce122a98cbd2c80efba78318a76010b2ffca76c7837b09111e52307e89119b76f9fcab838228182325fd9b955216f0808239c78b9e9f72f48f952798e5ddb479d0179961999d8387130c3329cae51cd63bc96f341924f06842422fcf621c030f26982485cacf7b48a3a3843c96607a5753b31234069f87124c51547c3cddbc637cc85813030362dce06d604c108210f095f64882073c9060be8e707b3a3df668c97dc1e308c6fc7cdb17ebb81c3f848711ccd142463df582ae24d2078f2218dcf334846bac6f8ef2e0410453e7aa4a975b1a824988bb4e6ff11082e1a4ee894a21f4c54e308c7dbb9643b9db48f081618a37b12e59857e61cc53162d5b12b71c725f186b3ed552c3fc92e5bc0614111dbd30ca8b0e49bd041d7288f0c2fcb7b26f21780a964cbb30d90911b4a4a02da8ef7591e75cd92b9872a1e5647fb612c7854105b311b9c27912b2dfa21c31f2a70eb3a0c316e6be9c5417fc24574a1203033d18630c5344472dcc9d35dbce9456684f6961d02968a8b78549299a85c15625260b53ce49a7d873652c4c3ae5ca93ccbaed14c2c2e069da74ce64e5f4b98e5718bbdacf7792fe77571dae30699af4371d2a3ce7dad10a434cffb8dc69647f7d32f6d3384304638cd1c10ad3f864356bdb5c0997d3b10aa3e5fba0eea49e19e85085e174e8f939c041a331023c0f74a4c2e4329f7b2c8ad0b1827fe84085a923567708ba7c63c5e544c7290c9ee6f24254ccc841aa91c68d33c8404d7498c29436fa417c45aacf3db071c6096eec253a4a614ec173e62d78e578925d1f3a4861eebf35f959234ffe2cd101d1c1758cc2a4c39d48e695547aa92c0af328e195b2495d0c1da130689c27bbcff2f711ae403b40610a955eecf3488aa1b78e4f1824071d545937de0639b041b6c3132695b835264f85d1a771e34590fa848e4e985e23453f51fe196798e0d4071d9c305dcbaec7db0f196bc4522a2303d9b10983f6a94b8a569d674732d68e8d336e9cd6343e043b681390232de8d08439f27ff220642713863989f712a29fd26562c2f4c94eb2dae9507fed1206dd79424a8f9c3aaab584aa23e62b4db850072a61d2da2ed692844cd94dad83128618579683b02c49e19540c7244c62419c4823e37fca27634d67604619356ef40cce6a7448c224af575db2bb3fde8f84e1841ed562112b749f206188233ebea894479867c4430425b28e30c6964e12b2cc8d3027dd2108310bf3fa3123cc5d2b41ae04a1e5aa2dc2a4de2ddc27e6841cd48a30b6c77f92e93a237212619ee41255b54584b94aa5646f7934d0061d87304dfe9027e6892779ad210cca2f0511b9301b3b29842959ff7e8ed157f33c210c9ee3e792131984399a668c87b06d7d16411864e4a598b33810a653eff944673e7c5e0161bc4e3aac94bef422437f30be75886a79b0cde81bd4b071460d2074f8c13cd79ff695ef1d731f4c3a7ae3734c5d7c9b3af8601eb153224da7875adfd0b10793698951e93f7e435ec618a30c1d7a30bb8952ba9245ca65e7c110d79385c8e94e2733e1c1bcf93d16376542cc10093aee602eab8a15254f7630e959f96c48899192b6a30e86a0b23fc71ef5cb693a982559306de95547a890be3107d365f5f021e7b782fa7230460e21fff563bca6280ea6b9601eb7930eda3c380231306028820e3898fbb44d77fa88625f7983b9e3267c7b753adc604aeaed6404a196efe28e3618741cf16f3a5eacc975b0c15c322a5b6a0f95f8411d6b305d57c8cbc147fb5dd5a106534e1777429851c971471acc29b376245af09c67d4810693b89265f1e2d67106731e0f3ab23aad7b3a7598a1a30ce6da8e961ef9e62fcf64302755af9274cb8ba5948e319894a5d457d9573d9a5087184ca6e25e59f2bebeb07784c17cc97b84ea297580c1dc9e6309d9d1449e24ecf8823154dab0681ee75e6387170c42f99ce890e30a7474c12caa62c988ab7570c16ce15497752a756cc124776fbc453fc2850e2d18af5ef74d05fb3897ecc882d9c4086175fa43b0bc93b156b2091d583078593ce541e92041d664dc681bdc48cb29745cc120b664bd8fb0a07492c6df60247458c1249e9752be824856e111dbbe362263ed460dfc8c8b4207154c4ae7f34a7491ef9b2103c10180091d5330c9deee284b21edd26a850e2998d2547ab31ca794fe3f0a86ddf2c841c72c31f291a1030a26a12a28efef70161d4f30d6571e7d227a6adc103a9c60f6d4a347848409b9e464ac1513424713ccee275e4b54aa850992b176b68b0e26984daaff4eb0cba3bb97e139406f63cd3a96607cf5908210da11a14309e692ffd68cdd8f5a0d6446d748c3df868d331c2f0523400108c6188334a22309df46d01e420551714400f0840e249842fc3ec9ed18255f54888e2398c37b12570949449f91fdd0610493d23616ef2f8fd277923d7414c194ac2e2bfdd9b67ae8120f1d44308b4851b27c5e8e4a7a1d3a8660f8d7c8edd194086b4f87108c592167f4ffb94bce81812318c6eb30c2e2538255489bc0010c773e8ee46f512612387e61b60a539dd86eca26cbe10b47cb9caab16ad4c0cb40a30c397a61baadf06217c6a485928c355e9894f6961c612732d65e0767d84083ecc2fc966cb764f9cea582347270460f1a0417c8c097610305638c91460e6e705217e6fd78b23d89989eefb3326ca060066694a183336c90a0ae56c0910bb3e849cbeef87061f25c953c67d3e9d3ad5b98635bf0cbbfda41cdcd610ba3951ed39da487ad7a6a610acbf38e60e1bb744c0bf3b55e165521b48fa924143866610ec26b525239fd39aae39085d9de544bf4b2da4a411cb130e8b855faf6179f4212072ccc398654911b59626285e315a612ad4ed656b6256b0e5798f4a7f411b4b3f5c511472b0c2ff973be37915cf671b0c26c2f42eca8a45444876315e66d13fa626dd35694f4c68d37430f8d326c906abc0eca4011b8a0060018c1a10ad3b6c9a7f6df6eddd2e04885f127d68358c5b67d97a83064b94f9f2646d0959392e31486590f49e280c314e6f46b4a59104ff1692e85397ad22108f70bf9107c3446200606cc18811818e8c018637090c2f8f964a8a8898ec214d4d57a5f885887958619efa2c83cd6fe509834b6d4723c670f7080c2587ad243d076291f1232d6d0b6031c9f307b780c612d2f7a47ed9e30a5bb1c1fbd7119a70c393a618e3197191ec2bde3be64a0208b15383861ba60e931c7b38854934d18437877140fe1ff276263e0d084b9e4e64f503365c2144786b22bd3bfc08109c32753b1d2449aabc0710963aa9ff097fc1de32e352c6132a1449f0877f996304725cc5f9574ce7f2ea38451ee2eb6fb6dd44426b1fa9998ee08faf693b1468ac02109e388ddd115f73f1a9130868cb8723a1f27fdcd0109a3e9f0ccfa0d353a35ce40c6f10843d2ce12ea16ff53ce7a60e3735002fc0087238cf1d9b2875ce2137034c27c65daa5df7eeafcba4119c8c1089350a224690ba14347ed171c8b30c8336d51fab4894990220c23f52585ca3825a3cd011ac57024c274255b95c389c958eb341a751a9d81b3438439c4d39c471fc958db47b7349694868d336ed80dc26883594250dbe1c43ae80f1b4c6147aa4593abf1c1b20653f64b951f5613c7623518bee3dce28abc9d531a4c924288cad0a2c198163d480b5b9fc12022e6b283f97d4a9ac110abd2fd7bd3329854dda4d86d12321852f27ca3151e4f98c6600e537fcdcf5a621783b9de47fe23c9ffcd1806f37cfe9f705142550583d1de4b46f768651208e30ba6204743ab68ef05c3c758b270739bbf6417b0ce26d404317a4789b96012c9ea2b56ae101e4f1b67e409630be6533284058fe4215ed1824988faf82d162b744a66c11027cb4e106e95ddf5c0461a663c89411858305e5b95eafa3afbabac208c2b983a3c5e88e65ba1d5b182f1f397d896ac963ba5aa60aa160b299274cba57c2a1854851439cfc147dd3305d3dd7b1493659182f9530a2e63428d82e9f4d9aa7cdfc51625148cb17f925372fb1df5134cbdd96155c24b92f085e104539ae7f5b0939d208c2618648616e126526ecb1e0cc26002f6de273bff787f7210c612b09453c4f7ca49fd26c377108612cc7d236e7e157ebc2c1784910493fca9d3eb9d173f289d9186191d20411848205dd6da35753a0c8871c836d240037b10c611380c23a8f9e93a240f855104d34e6e65ec056da4814618443098dac9a93a23faff52e36d80c60dca40038d36e30c33126da481068631041286104c31a2f5f3920e1f3a45c69a06c6182318a6687d6e23929c6c42fc018c740827dc7d2f4670f0f10b435061ed93529523a4f6c317c6f413c9d94ea6ff5b7a61ceb7f0218f5e0f0b3f2fcc25ce639998eff0b6efc25421897cdd7186c3872e4cb32729ffc80e2f415d7261f6eb38aa53e592f4d4bee10317862826afec736b753bb730974549410715a4a6986c61aad634fdf079265abcd4c2ec914ad6a79fe546190b820f5a9874d8b8dc7df92c0c2a7fbf1fe7e9e2c8edf0210bf37cd995ca444b2cccb61e210513172c4c25b994b6607dbcc2b415f9b5a4e7ae305ef0fce941eb34444a2b8c559b16174197a710b3c21455a26bcf9fac45c9c72a8cb2f19fb2a8bea99c25636d35f0a10a735f9a9790162d7a0eb1c0472a0ceed9f49da77b8d7f64a4518619638c199851061d3e5061a7305d4e397448994fe2ae0f5318258e38f9a92b87b7df818f52900f529852860a9d6db370d9761406d7d1511db449a9f0210a539e3d95f2b89e1825e64728cc215c298b1eb2a030b75558fb089553840a0d1f9f30ad87917849a924af2f9e309b6993eda4e2de32a265f8e884794543355efb635cee8313660f3e3a8470f98f4d98ba93c8ac905532d66a70a3d3a8516ae34313261d43cbeba578e1b3f6e02313e63d19c1d2363624e8c607264cba7d9dc289741f3e87c6c7254c29e5cb49930ddecde81b669c618605c618037530c618a800c0c587250cf249a9eb590f495755ad84c96425bba4bf38418614111f9430ede8a5511d2d859c3a0e1f933024cf8ff6f24149bc21b14f99928cad8183bf71fc1109d3c70f22debb95c6dfb861010c70400c0c8821821168a007e4111f903048cf8e2621761e611295b91a164e7bb54a8b0f4718ed3bd88e078f7a154d679c6183046cbbf868842145f21073f11da45a186110f727721e7b89f7e5224c4129ad7f31354518feab5a23774c909927c2a4cbe646cfafb347bef081088367f7202c99de05391dc2982ad142fe4ba4da785cf830c47d14c2a4a56321f444de9e9d091f84307fae3c158bba222ae4c2f0310853b84bb5753da7eaf282308a7653e13c53d72a1bc147204c2d9e1fc94b8aecf00c3e00610a6d12dc428c94feb7910334ce061f7f30ab8974fa6247c6a9948cb51ef0a08c5484061f7e3045494269fe763efa60922c626fe9bc2284341fccaaa6246509eb88f51e0c1f64549c9fb01ecc67b222f2e7c98339c99e252d953db6bc2a7ce0c174f59323c7506175d28f3b98b3a5eb10dba10f3b1896e245855d4cc6da1563c1471d8c15cf4c7c96243a986c52994d1a1532d66e2033fa0c4f061f73302595836f9c0e231ac21ea45106213ee4600eae5931b392ce103a7571c074459cffb87e95ac81c68d3a7cc0e1f5eb9873667d51926f3042ce7c3593967a4fe30469860f376479e27ba54c64d369433733f14f48bc78c992870f3620ff392c8d1cf93da99e1a3ed690b2a85a97730a4a203ed4905645f0f865aa19c23490beb6f78325870f34a0426cbce362e9ec1952a1ef74e912bd916f0d1f6628ccb9fccb778847e7f0518666b7829ad193c2a8c4c08018221003052010030377f82043aa6a219e923de1630ce82efdb394b23664031b29e0c387183c73dd0b27bb33d20b43aa2f1792b42fbe3330986639463b2baa46cc8ad9ed21044be1e1e30b065162559e23e9875fcaf80037e1c30b0695b3e4eaca5df615ea8239a8357517a16142ee5c307ae9f270a65aa9287c6cc19cba2d651bedf92ab5160c9264f68d05350be63c31dfca7a7bed2c5830298df89aee6123c6750573be8e2ea2a276df3d2b186c4bad2aac5527cf84955f86f041059350495dcea65bef43ff988229e74a9db746968241626b8a897a11d1520b10a2828f28782962425a8da806cc28a36d6440a16008ba744cbace4eec0b0a1f4f309dae382295b897f0e104939abd0c611e84c930d9f86882c707136ef4e06b50238c8f2530e0430908f84842033e9090808f23dce00602f830c28d1b6f038e8f2214e08308370881013e86501f42b0810d1a0310f00886033c8051a30c342c40820f8f5ff8e2d1195e2307bd3880072f6c6083f60178ec82c3431765a06181303c72413c702186c72d08e0618b5a24c08316350ce0318b1a65a061811b3638e30c122cc043160ef088057bc0a2461a08f078c58d2fa30c342cb0810e0f57d428030d0bd8f81ad83863056178b402fd0c66d0288880072b6eace2c3431509f048450d0578a062001ea73080872908e0518a007890c21c2ce6e7be2c29d6ef0a048f51182f646ea5e4c87fe692b1766383e0210ac34910d533b146e68743612efd1a4943e5010a939795bea825f4f8842188fd91952304356a2a62a06003c80c0b8ca145f0f08441447a4bdd0a69545f88e0d10973ed6b856fcf17365f74c605dc8c1c68608c1f7870c29055b4e38ea4cf61271e9b30d7759ce84e5ae5c08d31c6f0d084a95b2e4fe4f4f1eb7c076760608c3170e0910983b25d55cb63c00313864b52dc7c3b889f1cbe81c7250c49dec48a914535f0b08431aec4884e1da37b66b5107854c298a5433db59f2861aa39cfa5b233099387081e1f4aa83cc2968479c4c4c68275f49461240ce7f9644e529ed35307097358f12e91bbec3995c7234c62f27eec43ac7a3db081027f1d98230cf9449a96f9eed108c35c3c7d532fad6e71469894322daa1ed4a5057711a6bb0fbeef29238ff03c1461b2e8e2315f65e75d7924c2b4399ea59727951ccd0311e6e46e2a4832a14584ef3d018f439836e5c3488d943394da109efaa8daee17c274263f8f28bbbd9315214c725ff9fa3482463f195c1e83f0f36c49ed3c046188752a0e84498a560c08737b96f18963c2e61a68dcfdc1a43b82be9b14fea94a7e30e8181f6fd4c99cfbc4a30f06655afcd26ae8755ba306fd364eda7af0c17cbd22136b2f1278ec616d78e881a453120b0f313e66f8028f3cb89664a747ad8ebefd0a3cf0606338c2e30ee6203ee94f6ea2ab82871d4c7bb22fb6f809cdcfa981460e6ad4e08c336cb0251003036280400c1480a0e8c0a30ee630d76e6b13a2e731d1c17c67d7af1e3c8f39182f088ba24c720a49a1871c4cf2f9ab3a2996a59c338f38a4071ccc39b669b57791c71bcc7daf6e2a2fe8f627b3031e6e387d8affb63b95b6e191a4d54b2663cd6dd4e881196d34f06003713f69d3b6ce93dca0460fcce81a37ba3230c618376cd448e346bb193b3803a1c71a4c6fb9748732a9c1aca743ce97143cbae9a4c13c729d2a4c84892829683097aa8f92e44b1471ee194caab2ddd26a78bfb966305f4dae907a30a9bcf72123e6e1bab0248456c933e1c19c435b78cf967758558488d2d9c15cb2ab73964f12ecc63a98828758212b6685db74308baabf8e16f2dce53998e279793cc92feeaf1cb8582faa447fe26090951622fad4a8b41d1c4c4905d7fbfe10cd4c6f400303dc601cbd922d0989b5c1f4e5397c2fc60643983753d3f521a4656b30ae88ce3ad594d3613598dbd4bec47f7acf621a18800693d07be94756673044cd0d8b55fb494290016678bf52366de16bff736528cf579678f82af7c9603c393975f544977cfa184c97ef3987cac8adff88c1c9f1b63dd49f9b1e065318e97a39444f0c910306639d99327f516ae4ec2fa47223e547574b222fbca572178c3e422871cb664a81015c684f655d4656ce16ecf3a0f447bab72d5d0ba5f39c6654d6d6fecdc2215bd6c8cd8b61420103b080a7d71c193978fa5ca1ec17747c39252b14d143845827a2df2a5c1e7794120b217fa860921842bd6be9cebdff144e7edfdad1df3a2978c1647b4a416707191085435ab38a58595a3b28607f3259d4e49ff8099f095f1d8fd59d7342365676a31d235e450c6802327475989409e414ecd4bcbdc29b4b40bde3ed56deecaa90014af0d2884a27843a71332009a59633292a0c4002f2e3c595fa08c6d1972c45eca4b4b2114cd1f524c50929025a548a949245b1141b110c42c9f814bd7df259870143b83d82bccecb16b34d0c10824107d321b32b899fddc140e959f809d3253960984388da294bf40b436eed911dd717e6f41c948efc25556a2f8c1bdaa176262fcc1f734df4574ef1bbdd85af615226e88aab31e922bdf1a32d5a59bab97023e9911b5e41f85db8f092ef9f0a8d6fe155ce3cb3493b3a5b90e7f5926ab530d8a828c172e4f7f8d0223b1d2a84d12c0c415285121e4c59a43a480b1553fa7b2c529193fe38963b395868a63eec45ae3a855f61d2397c8ed45859dd15caa46829e47a044b2bf8be5049c9911c2b5afb4e6a3f8818afc289a9754a45d57454e1f75bfee55829ea5498c2e6a4921d0b3d294385c14743a7687f293f7d0a934a21757eb1cb7e2f0a0b30853959c69c8dd2fb29924a610e93e396fd8c07ad3f298c7edf4994b83841c43f0ab3950896c34b4dc4f84551bec88c89cb6b288c236eb3a22561541228cc412b451555a14f1892cab7b9e81f12f5e3098350d9bbde743e7afa74c214cf6d5bf2af085d36278ea434bfbf4cc90d954d18cd752d9c12b226cca73b2cb4d794fe8b33618871134e998e1f36c5c47a1d2c7c76a77bb92f61d44d3d6521a7a4476a0bb0844949cb4105f949859754c2146a65f2c84b29615e8b2264a77021494a27815097f36479fa699230473bcf22e6bafd4a9130e48e94cc2f04a57d26244cd5e7c1eb7de7477f8471c259289323c62b4447742179b776c5d04a23383bcb95ad14762246182ea2c7bcd32dc29c6d5bde4f8a307f9555b8f6dd5b3711a63f53df9e3e879e1043c42bf1b4f34e0e6a3b4431a9bb5f24ba7c0c61f48a704a843f1d6654089334bb4f2a2949f22d5563c1b0004218c2e85c219b31263b6510c64ba373d2058f2823fdc2020491cea8c9d9de06820f12a2e7ea7ad30362dbeb2c1ee1dcc72e7f5075745ec9048ffac12054bc4f1f9e758f9b741525870f86a0e452b22e8fd41dc28505ec61ad2d9110947a3858d03e696363ed3c984f279d922aad9d85090fe80c2dfe3d498864f13b20d2da32353b989386fa89abd317aeaf83a9374f74a8d27fca79d405cdc188223b25650d9197433237794b88fba97148a86ca9f0fb210d07934edb177c674d5aed6f604288a6748aee92f2c80da653428a9c644adb5cde0663a968699122365c2aaa04b9db1accf9469efad8cb97ac06c39f48a583103969b83a42b85cf30a42868682cf758844abaad319ca67deb1b47274a66d06a3e5b0f859d75b6997c154414b87d2ebc89029b12be93194b52fa6a9899dcec2627075c6b32aa4340a83414e6acba9d34c4f70c1706c91ffa6fe73aaacbef004b112c7d2f45e30e55877e99d4a871d912e6031c4ca88a813ff5f2e9c75733f29fdf3d942e761f611625eda73b5902e2fbfb2c05fee4fdee69d16164c61299994246bd7737905254553a3c368d10d1d2b982d455d2e76a4492b56613797943ae8a95088262c23a94e5f9a42e2af33e3ea2c2d05d3e94b252feb8b422259758ab8bd408124bb4edba40fea53fe09a674314b926c277095527487f0f14b13cc2656742cd6ae5a9609860b1aaa4f65848fb3b6b0802598c3cb271de4eb93ec4a30bee59b28426c88d1a62474399ea1e90290505297bc69c9439ab5802318f3928909cfed93928c6038b3f8cff98b6048dda5eb927b2298820a226b5c12b1da1e8249567cc9e593ead287162004931e35af95b907031193456e74c0309d9874e661ffc220bc4e47febca4ea7c61b6cb23ed428d900b61f4c29cce4a5744cdca5e7861ee8bd61d17f35df8f15794c812d68549a84baa77252717a60b49b2246dc28529277b95ba5ecea2ea5b9892127fded52962a98a2dccab7a9a922b5c0bb34dec54c14dbc63480b438e53114b446761d2799de593c3b996b228ba08eb148e852a13643c448717c1c2bc13b322aec809dbf815a60f4946da89743922ea0a5365bb9c9cf89c2bc55a61aa5211b34e1d46c594156978bc8c972454d7ab30e54ed172c98dc892a20a9398e0ed274723473415c6f6cad3a67f54186b52fa58e74e61b214bd6db9f4fd2a628af7de53bcc25218e5ef629e5d69e47c92c2789f5ac9e36514e6ec14bd7f3d8ac294963f8c94a82a59140a7d4ba48fe381c268ee6945825be8b57c828b5f732967957cf27ae21e2d173d24ffaaf0e984499f595b291155173d4e1884458be623b409936e957a50353bdfad268c575244c676eadc936782ff2a516d499830a9bb49f95a5498fc12bf889b0ec94410a9f49628ae47bddd5abba412c6f932955a8424fdcc28717cd3218e9787f52661d05177bbe32e6f7e4920ae3e4685302281c93ecb275de6d49030fba85239151fdd6e91b1f60843bec8a62e7e658c46df00c370049eea6147dcad2935824932e691bdab2a8597a0a1e24f55901f7ee5a61d86c10893a7702742bc24f36a2fc2e83977989a7db310175b43188a30277d229e68b1a04350224cc9f3bc696d57080311064f41a9e77ab50baf1cc2f4621e57c3574318249d909594c8dd33b24218b3439dc97a09cbde12c2242c5bbb6ea73cb9a04198b2754f6586ba76d205611256a35f94481372cc0361943c4997d5a5957705100639a264d49af40fc6d1b553f14ca77799f8c1f8b9f6e1aa651f4c91e25f25f93a1f4c49a848496c3c5c2e59187b305ce94e6a4bdc30f470505be16ae4e9f82935100d61e4c1702ef36f957e9382e4cbb081827c4018783068939fcc4324a5aa5abf096e9c51469211c61d0cb1f77cf34cbb8248dbc1a0643c3b9c97e585b80e26ebed1cba5e9e1cdc58d4811f844107931239e9fc217ba553a13998fb23cb049192eef33a0c399874df53437785187799a9851107a3e6884923adee924e8283713635df82ee1094fc6f3024cb101e1e73371843a7f0ba038d5ea8f4af6652612012070402711c045248f51e00c3130010404078441a8bc462d13c0e85e1071480035228245836301a241e18161808842351201404844382502010088541814028240a27e196ec03ab41f74a5cbda0cf38737cb323ed8a86cfd25657810116da0600aa70ce296e6ae67566a0e70b7654604720f737c5c02e0d64724730741c6dd034c8fc50bdd6880191268b4923507cf74d766582231df89f0599770a1a4c373db28b2b0e747984ad00cdafcf08c0997b5e6e6eea267b805f181beeb6aac9539bb444f24f37fc683c9ca949faf447fea535fe479cd290c5f455fae73b6e1d5cb06d98220fc824eb376fd0c1de1d4480b743ac6e74a47b0f15e183e4091e968a808de6f2541c8e584911c341ca0bb86b6c938d8b7c3c2b5b544b4461523983f31de5922592fc69c79a4524c8671d92de4c7e09eead39f5d4bfe1a94df4278e6c79a33ca999541f6dbce7ee7fb86a418d54ffd00120f8140dbc9d22f28d7ebb9f1dee3f4a15f72cbe0681c61d3aeb4ed422a08aff1d39bc1c530481076fad49d9cbd92fe58118611efcd5e88ef6c36e3b08c946c14b908e148a6dc8692dcdeb6d7b5af9ff140f940d20c69f84ff2d9748fc199f7c0bb77bbf8d53bdbeaf305628eb7dd3512db1809933c2bbff7a5fda6e21c36a472e0fb4d899ab41175cdde6bf844c934671899fafe9b6045225aa6d60af4015ccc7662a87ee9f1d9487cfe553ed082d1c63fd550089f109f0a6476ec7a7ad90111def3be9d273a26aa725beb92225aeee3fdc6b4808250dcc5ef550e2b79094d8a6a18a5a039dc6d8357c3774190f03370365a7a63c1c251171ae9748682c174f23718da31b7e8203a5cb808e5808638d4d6dcc72b807b6a18fc51b26e5a233c7511c35f57d8d463b36ca40ebd4c484661f9c80837d1b25c6513ac446e73ed07f0e9d13fd339a4114886b7d702ba65328781a479cb5bf8ce1ec300d47a91f363af189a59d4e56ea9f7b9ab99c439bd905f5c0513afead53f1b3046c811da319a4ac96a56eb9ed2007c14672098d6710e0e0debf6e209b3fad0c9146ff7e6189d501df8bdd8147ca7b8f21e8e05ea2633757f4e6f3966859bab60e8bb5c1be05cd7c762000b61b38b6124703725a8808cc2d040efdcba015185262701af9e67ad7d2d63104284feb64d6eb5f0993002109aaaac1112dd71c4e6e0b4bb5e4d97cd9d90ceb3f0e98260ce2bae69033045f53409dfbba11a06654e95522090e53da0559ce056640975de35c9600f50932ddd94450109a84a94701587bffa21592dfb9e65012a0fa4773ae11140ebaafebe8fd28132685d21eca13d6a10f9ae18ec94421dc56084c35c66e1d1eca59547ad0fc0ec170bca1abe70d078bd5c17ed7772e7effbd63e4f37c520dc8aa5b2a5dd5887f3a93080e6504827ece1014f80622f0586fd0d16ab76c4055f7ffbba49c96edef3a47c98e35851308cc6ac01b602cc3fa2f23a0a7e6a87f02ed28826339280daa37f1d8ef6e28012ac3b7992e2db11c3c4767b0fcd54f9a2def88673a7a85ad3d44afb14ac087e5771d3c87903115f818a8250e062f6d1ad0383886173cf08a56cfa2c142da31174c58dd48e3914fd2ed80b49b531898070f7670907e822dc10d19421bb4d67440104da63b2a891a3ca4d51acf651f3c71e361870a357836b71da9ee74a069a5b6fe107877373c9b81ac41405283634e106755661a13990f1ee43a58befc278558c50436c5fdb45d569720729a7cd112c1206b628641d3171a19641d5baabba99dff00902c5ce031d27cee7732841421211974f0002e3e1cb08387e50c1a123dd7dc2192f560b40032b1c1f30413780ae0e0715db9d5c76af008ef83c6ed0f548e6a0d9ee7a387811d6507cb7d0d40fdab60c7a3f11fc20d9ec428864318099b40e6b307b4583b067722f1f9925eb156d5cb4058ea76f8be871624460c1a0669aa32683c0155cc4212c68ee001f6e97a29fa702c27bb2822a855719d837524ec18bb7678848d649a3dfd5dbbb5ff0073e0de55a38c9edb7b04a6dd12d71b34ae2dde6aac54b5f57a3d1efb775e284666143f458a510dce73dfbbec702304ab4c344334181886046dc4a1c66408a01c8b2d70ae21424e16835246a5346d0dae1894169478c33b565351cc4ca7e176a8e929d2614cc0e98350313f9e1584987a8375820e80054cd8f0c08b0e06505803113633f98021e3e088628c88c30ad93daa20163c484fc40afd50a4bb448f3255450e5a401a0ccca1b83c4e32bd7500e94f16a58d3b472e6c8135694c26de69913c7710d4a8ca034d91f673434fd44fb3e5691d2add2003467379045a5d75f175d3db4231ae012afab4ff57c033658c6d6d4f6eb167658f7e374eeff55ed2110f629d4a028503cb647c662edf598abc8f49fe9b384c8d9fd8c05cd5af0d549d3c550297945fd5da01e83faf6967c602eef7ba0baa36279709254d0da59235a64a31b69feddba8ab7b6a2354f20fc11ebab08f3e441faf066b10ad9b25ac15ca5516837a0861300f507c4e244389afa32cdffd7e37eb3294eedd42b1644ccbc68a20f37635b74cb661cf4e9445865d99cbe342c009b91a06000b63ff24116ce487b11a992c81c9b9db81761434f949930bdaba7bbd6c038d55283df3271dd4e7520c73008b4737df2c31aa1888f3b0e1878b1cf0b921327884844bee5a714bccac1ea25bd7f0f11e1b6e82f1d96dbe6a0d516fe8d1912c35f05a0e75b787ed813de8600d653d9c6b17aef7d2fbf5809de265ff366719869ee80311899639a26019e509f8151c866ae27e19840b2463f1408e11784a253050c4c141771070e9670e5cadc8b03d1c743106f610bc51c4fb0a2262485030b4fe61fa81a9fcdffce8654d55a8bf96213db4db24e8f92428c50414d5f7ea1db0927440a7dc31df51da2554386a7a54a906b88bc36eae965fdd8d8657d007f771fb405e35798557e9a6009aef56e2fa71caa281d2d71190a7f09990632fd0a90bd39bf0d50cf8b1a02981f8f9c18c838a061083a9012486c106702d84a56ae81d3e989721f1561cb282b4b0546640a1ea5e6d8e9deb6e2e06331afcc76b697620892e0bbe5e4b2457166de73ab573f8611a1f80b5d6c422c073900b3116aad24de0f3a0acbf719c3ea3988b7180b8014c160535c3871bc6433615e2ece25ae9c9197d090c624b1fd1c0c0dc0a8286d070801706b12c6e587ff95a8150da4896b50d079916720ae98d2bef454ed81c969944bc4257c8bc372dd3d215fca33f816fbabd579cd2d0d56a60667ef624413aa08a31415638ea0526713b34d30661cb537620f9b9eca9e0ca09059b34e11691a16421408d55bfd206f0b868ebbe6e9524a87530e7eac8c8f0a3b3d3c0bb8ec320c000eb4b950a0f5a89df0e3def45b0507e33fc65716c7f25654279a5fc2bbb791669c662cd9ee4aa39ce62389a39c175a76af872761a0d7d6ba436037aa1d7973c62eda5b1aba73eda03bc29ad35bc4e73cd0d34fcc2344ae4f6ea2aa4ceae9b1271ca760f1dbc0a03bcb7fcf552b02ae762167f9c545a6a41dc9e7235f35e42152451c14d5d2e2473e2bb1a7663b038cf79f831fbf1a41399f39950df4cfe176f8f416ac5a09f7c098a38c98b3c927aa2fbb697f0b31de0df2935f1839ad316e184e6e2be53b26e8ecdd88875969f73193c263885ec0f809f6c4fb0f29ccddc163e0a369d4e211774edd66eca0ba7a4c3ed95a8ae40cb70c1c693aca14c43ed386b24c54a524893515afc1fe2048b2c806b04fe8bb54d320e34542fd88ba4066eb37e8d2dc3d1c5c0eb4aac5923d9a76f3f610fbace67f550b5203e31a6e93cf4aa2ceb2eb429338628bb8c8d74bde9079364008916d853126280f980d9dd74e40d3449a65c58bb6e46b691fb52791582cfc56098ab40016e046131a182c29043533120706c40423b3d7a72b4dd417623d49548ae078f503e39425e044db78c0b65a8d5c12b5968e9c4897ce33b75f273e1bcb07ba86b3680161be25abeb05cb2cc30ea5db9a3ae57f41bbe72e94f6d8cc3bab49f93700c6dee1444990c542a8153af88f10494ee60e068957e8b5f945f483b67ebadbff389931e049939a0f6dca66cdbcc92fc7af95ad9d400f09e415a5ddfaa0ab5b495c9848644c8e68e964b84bcd453f28e142b58ac7795d12f3f0f47f20d966f0252cbe851e5e4eb152a546cb880600923287414314b9bc651bf76675cb6ad8129fb192e57bd2a386935e1352ee250d3c45bc5b02d53f201f0dd3199001ac0c98be3486af99261294008cbf83dfcf5f828e8867b750a5a3f6199b715c2a3b2e9fc78cf446b11896e53a15d74145014079aef2c1db5058166d1039dae12685e5f4e9caa0f973d08ff0af43e3310cc9a5e573052ff7610ee045b505e49106ee9dba0a4070bb03f007f417c967e3c455356bbfadf7ec49e47a40c2852004a5ddb1ca97bdc04e43cf650f8ea68bacfd829b8c90f0c9b24186e76fae090eb90a0007ce265734afa1281e43bc97fd59f05333e36138d5b1e2f802f83d18091015291935b2a23e02553970a05e55fa032c6cd4580f27fbe48db17a7788e5ee6f4074a331de655c63453a71d691f68a42db119e9c977de2b076dea2d63df8373c0090794bc017fd689b3bd7bb3205c9c8b9b60ae44a9c961ecb7a156be601ea334a873a870dd16fde4c2239bb8ee4788ca3b839c18cefa2c59b21f019f0b37e30471098be5daf339f81e07688ebea1e0a691e6851d422d3b74aac8d33de2ec6894006daddeb1b0448d6165971ee04a4bbbb7465093ab6950bcf93a930e7c00f8356e9d1bc67da851e07b79e39a579b39caddf4bda6333dd9c46c2a72cb2b034b261e209c301231cdf434b7e828f2c7f4464fd6cde242445cfc43c77ffb02800603bbe3c6fa133f04203b8a7d5bd1cec0efee9dd082435a3fc13bda89336040fa736b11e51fe7aa5ccfc20a6507c42bdf69fab2221e1e382593c02adcbf45b5add7a506c92e9ac02f51e620d37209ad315b59ef012ad22d3b3bb85ae67a4ed1f1a4a12c901c2549273db085365ce1f769958c7b0f1bc64a66dbe8318deabdb8986dda60f4b6e648a3dbc21263225b8b325402b39f406b7d23937360fa309a5bb68c60d1beeb67800a3100047ab552c63c5f777bcb8160ed2d0bcf74bd604723d4fa42f45b13874e9e95186c43835b3b80b5b1028acec69d0f71325de08d5327e9d8e0009896f340190fc7232b2991e1bfd1ff4133eed2cb74ee46c98f7b2a170847355a911f9cdd4c6c13ce38cddf9f9da12caac149f750c72238ede31641f0183f2e2bdc266a4f1823b01a888fa2f31316897220b27bc7461daa80cf6fb489f53d9f93ff6482e016258325523d4ea4d421566ed4384a3db5f5d987aa9401250734f5b7352f0d87befc1dbe41c92a4101e73a0b485923ccf99520071d634a14a8ae50d44d118de7a11743a78e936444da33f07ce3fe6a5bac02c14ee24de0752df349db8d0b2c2ac6960b8c58d3338be231e3a0a641c3a8326240b4593cde9804adafed63a74f0fd12b1a9ebefe57a445a814301addd9afe8522aa3f6f7206153ab1e480d043dbf52f9057adc890c5942f3801b6852d1c845a1a404a83efa945e3860990f826ed5a85574fe5182748320a55046810e52e0494a23c9f83c18c71a462c071b3903cd222be6baa84c8b9e44de1be90a54b6ddec20ee637e4e31337b734f05942b1e473d587bf3a711b1ef22391f2f6601cc8ebc6a92d684e72b04a1c99113ba37d665d60d8969bc13a5ab1da250b79960f23c0eaeb799deb659c22b917ec462a4f3b1a2b332cb16885033f106b17d04d12d2821d354305e6d04ad0b3bd3fe31488089727e858e118a5882e59628975ef7ad0529ad1d58b22b32c00a852d7d66b26225fae6fd03791dbe0992d2079d71b5e93972423cc1c3b2c4750307e12b136b6826583a11450877eae119c3ca6d26d6660276bb2a2d51445e14743b1465846471ebc9a8820750ecdd4133e7956a89034b7b6b427c53840f5ba764501366f91bf26cfcd4f040c261466dbbdf1880781125f3c2a946a936a61697763341490cd65e0ebd9c712e71224408a6210b7762fafd5faef3a9a5871585a6e94033c199d77f8e7989771fee7191990da6b5afacf4c3f5c67e0fa39af96315f44d15a02fd8e7cfdb37831e87e930a81e882b293284689ba1a5c3e7126bcdb4498c5b045ea120e4abbff1b4eb03c1799ab56e1155ae0fbad636244d1a9323b50fbe84836e19a98e52b5a490432a88d2a294441f4d16d1ced6ac6e02040fc82a20cd1b63b2a87f13c12441a199da27b8da08a9822f645096078ab13d8ba83e78a970596418829f786a24274aaac14ce13bb6909a26a42ef5ca50e4af0810e51f85df0ae9e7e0f9a9e749fca9f2a7cf816abced80cb722490ce22b75e441342ef96ca933641dd02cb38aacf8820ddfd85b9385822e5bba7ae972a817df8a66f96db2666e915ae768423ec88f188968a321d62a8178964af08cd2e104d774a34a87c4d4c00fbbb3834cd3a8b2626b0a015b393137efc39fd82249d0b67ad09043473ed2316bc27c142f254b0edde9f1805ccfb2986eacb51f67499b124b08405fe7f824b6b39651a4f9d9ba8753a5b525b5a8ac00b4ee70f035ccd38751480f8833a71680278183e8aec9d776283fdcf445b71abbbd05a6896653bc7d651ba5c680841eedc27a3266ccc67411c0b458d67f63d5a6daa13f31b62eb8b55f5c155ac30873801bcda2c0c6726a64f54527511838329578edde956aa40ca0d8db018d20f5a86401b8f2f8d5daaf7edad1667e97da463b3451f9e66606912225bf228fdc820ea3db5d6baad7c2905e8c22a22ab237645cdaef6db8b36dc9dab536a4edb4b8fdb24f3f250daa0e47cf7924e1a51b890ba5d81fba2d363dfefd2e90bc52a74320796f53465c2683f8be470ab5b2739c76cd445a8f2004b672115ecb8a44c7e29e2a04b4b5c07a8201c512357b4297056ba1eb08f706e259408c3fe2778bfe47e5cfdb356dbee57a0b07a26938e43e3c81147328375778c26e7706c74920e3f8c416dc7fe525b4b781f7de7cdcfd38649ffc9e71914596cc2a1a8a9b1ca11d31346982a5e898880c5dc092585f19bd2d171811440a85995b8fde6b4b1646a1e6557e3f4c95479690c1357fda02fc43e872074bdde2f020ab9647e6c9210bd745e1fd1f98974459fbd8cf1eacef6fa9b5513f524b8e203631c4d520f7da9f0f27153f976a125374edcabb5ee2b6024c33b19fc9fe2bdde45f3619a50912b174cb0603c186e61e065092a62f25757e7a7512276899aeea41c12eae45a019dcf612222d2c1b0d273a91d172cb93288c354e1c76293fcc7d6058169a804abd08557db0a5ab1086082fc9a4b7a74bc324dc109486c8778003825dc43babf0f8f04e2df4c69863747907ce3acf49944c82032de235bdb5a32fd364e9f13812a59aa92c1471b97eb3374791cce52a1e011231eda1f1b87bfd4b192eee36f40b89ac4525f0803108f2738964fd711cc844025c304b5d48020616223bdf31aa4dd557ca1931068551223374dbe4f2668037d05c35847884055e3ab5c152ce466865d15a01d3d5c7b02f2b1c42db858cb49d39143c96426b9a6551b5b90949f2eb87631757679534d21a64ddc36db3dd172c3ab28e378646efab7b6562cb76fe7e54c62ad2d6f12e008c49df8e2525a89169d3f409075e6221e99a93a6a7f463960fd47524e9954df4f609c1ecbf7f23e546e6c04dc4144778635ba1794c04b00af52d6d32684898e9317bf3b460627abab17cd42a055b28fd6e2d58f5a9c6df5b70d09596a29272329197c07b0433454bdfc25c02934e00115eddbd462e4577f2ceb67c44982d2c2b84eca7652f46466548bcd9fb28a60eb0f2941fbb67b2bbfc6d21be3379eb37bcf56c6b44ef24f50861b00de64cb3d6b0c060d955a50f5582222eb2802b3ed1de51bb8af2867d5989c45a92e7c7ddaca24fa404690d4bf5dfacfac2a22c0b7252f2e57fa74e02eea5a1b9797490ce100e487ba3bb892dc693cc60c27720aabc9e8057dd093b5d4d20505918635a1af736eada7b781254afbbd4a94c720f1f73e786d85e86d327affc96c1ceec4e1b28c70b113a61d5a5d15cf859471f435ec632113db6421abb55c6dc95fc8740acdfbaca88f5f52cb5bc31314b791509b1598e3773dae0ed3df6e13fbb43d6b91a1609c5d2447dfd4c8032d083b921e4939953e954a1c63393416d3a1d83708a9cabdd1e34b7bc53c4983f97742da9345aeccf5ee4f454e77c883d2314b1c6c65c2a926b63776e5f2b2c95f4d47ffba37c9b6f722cce51252cb2db3d87c35d2e5d25f778fbd950aa35a99f94556eeeabe5e60212c8484b072b5881cf2791bb6e618d4a407ac5841d1d84ea0053f32eb4d4e4abcf8dd8adb4b8f7d8e4122b4ded650b64245d8363663f109ed85315872e1c3c94dd2fbc6841a0845564b617d80697d51267c3827b588a48754838bd51abb13825cd36b931d0aac8503dc661e99c20946f185361dddab351e32385fa2ceee6c618b20a4d58cac8efd71478dc3821f1b44ad685a1a1d05bfe0087ca31db53adb69e9a4373a72901da6b761b2d5b04a470d90d312607eaf6189a71e1bcf7f79b9a58cd4a763a225197c3578f2f79646cc8b05c435740658e9065bc7343a21c4accf676c40cee25ac331941db3d2b6e27b3a44f56a9019e9e3586225ddd1bc29dd9b1a29a384e151a30ead38fb03236ca6dce87d46081ac9c54ae9254f70d22773c86f2b8a151e89f9c1fcd37dae479dac3207c03324a6dd0a65bbbbd76482a02eba30b02f58699f2cae7246e94b5e2a98c206435dc03cbd31989c0a83292745c8b5c57ff0749402fc3ca04d964d99a6fd5797b90ad30eb9b7b31f30b9fe80e2e666475596f17709dbbfdb54212d0d1a99f1209dbf446610e7b7f15370c45d8af465fd70c690045e0540c0500a3b81f489fa60bc869957c5f51f10e2e3d38beb1f8cce010c5b01ba2422421045219cd85c8ff667c460c49a519b94da79332ae6af53c562859499f8be6ed3353721e334b5087eb2ebe2c1114d9180e9779a9d3f1ca20477a6ec856c423be0232afd67689ba661cc549e08f75ffbf24fc42d234994e66470d1ccf7c48f86a1b48a81c4d61181019518afefcc281180f5d19c45e3f59d138f45c6ad546715851dfb6b8def5c350c277d8af1b072bba022bf1b1f7e1f8806df8ed2d6f6dcc4b30fb6e1700ffea230b5874bc89e9102d1629c0056438c1dd1e08c00abe1c62cd1e48c001535326ec0727683cf4b60bdfaaa56b9f5ba5064c2973f1fc833b148588970712a192edd4ee483f698fbf81a6fac471423c4b97aac52119ae5af7846a74f314cf587c0d12466d756890513df5c7fa9fc18330832df9f8473bd3ad7c1bfb6e6207ed183e4d015c58b5fdccdcdaa1fe1e0dc8b9792fe1c8c5933d91811967c0fbb31678d3fc578f5546f90389e232861b30088774d8a459628238c8554700599994923bbcdb7137eedcb76244b70f044c59f7e105a3822bfbd42e8e8b73b93f2c54cda5835738b51af0782c0b50fd6464177b85e414aa2b50071e2949954e43b0d24711abf56d6e800ae6cf8231d20a8e9ef672128b1fd670cede931905f65c8840b4c0c99d70ddef68663272021b8bb387ff5a0d7ae1b24ba65ab0783ea0235f20b54bff568acf1ec016e7f6e4cf6babb5914c03d55299e6c6b84bba1e92d4fe9254b982bc3f76b53c2bf3a007a6be2e3d18c0b3c860392acbbfdeba93aae1d1957a59f1a809784e3a791f428a3fdf6183f99039506c64624ed6e74f263aa7c19e14d1dccd51635f5e004343aef20ac11ec979936715701a820f9b34733b456e29e0aa83e6d540ccd037f7eb10c9620686ff5a27ac04f2a71271908e01c6f6a07bdb7cb16d84d8c1c7a18dbed310c2610bf5695c3e95dcdda912cacc075c44714d4bd0a775f65d6a69ffca7a7e3977890c910ed3f27fdb2cc51605f7446d9fe5a7e13c48c921b2f34d70f8e84469e6d9b43b4ab2854a1caccd81ff6c2e0d963dea992902e5144288d16d0f8188d01ebf147849a7b1e9b2ebb155f8f2902cf5a7f4cadd768c25fb907b97319fd7e897ae89caa42d9b6a8c066fa17e3b3235587a0376fbdc7bac3afc35c8e16cc58e5311ac5beae69e8ca7e94100268553f4f76a5619f0c8fdfa18eb468af8d51b8928dd351ae37813c47afe73c7cbcf928c808df3ed395a0e7e0cafe003dce4eb74dd71cee51574eaeda133b1fb0a3442e710a6f06ab29e7f33c0b31ca3e3b41094bd4c48548b8cc1b4259c8330dc00a3dcd8ae70d0a77a6669348ca8638c116ba91e9658d3e85866f77bcc16400438b68a58707ab1fd4b02e53814a3c7e2ad4542224d5c597e5842224290b9ea7a9edd8978a8c8fb94f85f837ed90d075b7c04992a167b3fd3e1795b97d87c3a225961b1f4de9d41b6b81f11ee6963a14bc8c048e9e54260adbef3537cbadc8df12b7441ae6e1aa85a58130094f186aaea06607c1cc3d4bfa06ce304b5c268977b03d6416a6748ad3a5d9d4ec8fe94ded80c0a2f0d0cd3d052a69b9129b217819fc2c4150192bc729b5edc0f7609d31a936365ad1f306a6aef0d892ec27834b9ab217dcab7b3a82fbb2dc5c530dd7018b2e102b7ea288afd850f1aca3927042afb6c69937ba552121f5b2c9a78fa21321eb629054e83eccbcfa490ab27717d435126ef5c9eead9964cc3376221e000aebeba8c9d3b3b041be98e9073aa21758b5ea04d0832f04fb99377872248c54a67ee7bcbe82db24a0edf465d8654d0c3ab5c41aca66a2533c05496426e11d3c658e0a773ef5358348c3526acf586ed06d857a2b2b19044522f2811db6f5e35f22f0a1edca8c8d49ddb32fd47443d2394f556ac9710c510ba4d793013f3063c7e78973dd0681cd02a6209a0b4202b596720e93945e4ed1ccdfd9490327a9a90d7fbc23832472af6e420b18759fced10ab618baf16c4043e94d84e296d3e5295fdeb09fc8ccba2dcb41274cc62b9af00f95a0885d51521fd9727c9a24ced543ab38e436ae80ccf88c4fd2ab1f58046132470bb8058387e098aba5b9361a140c824c8ef3ff12dbb787c9d6b612eae4c248319c3c865dc3c913a47efddb5d202d61f45f921ec60513803fc70afb50bd64777b10f7d649554eec1335b980054a1beb72416d78a871fc323589a6aa87e89d07b6f282de5190cc753336c96126820326dc6755b92e70ec41ffc6a47856c204223924c42f7d67ffd792fcc3889e63f5c600258311b93510ee600a2636b2579357ddb745b8b6489dc1ef29703ea877eb23994ce8afcd7f6e66999f30a06431f46e14e3e5c1417918ed5464d2b723fd0c527ae1e8b04e8e6f1dcf5e2b03cc89088f7271ff5317d2239d87f25df731f2c829d2c8c5e57912ebb159b72827ee8389b35f75f29a6ad16fe6e16c44b555aa9944dbc96ae0b1604d59038216957ef4fa29f452b5b27657431526f66125cbb6c2a03610ec9b82d0147c6cc12643f1143a270b9dd52d57335adf404945093315295d7f489ff562949a17b3bf97e1c08ea044dc581cf06d94c156f831e137e0c928ec018772da783813678286d8a0089c0a3317bc723dbe8bd8610a045cf614309e0257014c5b4cfc82688b70127d68400c8a3305523bf276903dd471a6a6da0faefaf07f25d0d97c713c8c1770ff55602d7dac5ab097b26206133af8bb155783333144b45dcbfc574900268996e2477bb7d7fc3b8171a2ea12d04a465af84e82a42f53a555cfecdb13fe2526bffaac5de2197c3a5dc993ebd7c9c77f14b3e86bca1579f2eb38a490b700e7db049e685b4bf6ec9e23fe9910db357521408aa0978d43b66ad8d80d075f49f89147287d0c3089df397e27dcf21f70f82567237c0dcfce6b85f3e3333d4eeef15f53931641e927830e7a0cc89c5d11008edbe92f904218d371beeb1b4f9136828205f1cb710e29b8115da70396a815cd9112791a240742ceaea4caa9a962e5cdc1a7f753c20cc7e89026850a342758d04ee47b4814b43ceb5236fffd5cf328758afbb723f92557fdf70bc16b3cea036f2deca4f4aa2bf7a1576b33d79b110a09f6b292885bccf7c6805e21b0748488ab60025184a53a47bbee1fda045ce314cef2e9067044434ef088a12b3d6c1ce270f2b378ce9436736e21b38c92ca8244ef3ac14a3af6e5803cc8d4c81b0f3fd412f3ef668e34ed585b62603322cef5bd8fa79aba174a447c8f9498ebb8a951545a2a735e0662bdf7fd29cac541eaffde43b21c429ffa4b86ec1725d6e832116c3f6d979641778a698848cb70ae22b03b26abee697fea238f8f6c61649aaf73a199e9d72fd3e4d4f126a17c802a286803884131fc5d0b14e93fe56586d542ab511f6d0e762e83560a930361e55fd88e1a18a7cd2120fb875bdd120b73f3161908119fa0d709f304f9d87efc53a2ecab3f9055bba5a70524a91cd3e0ee610e55bf8be531d90db4d7d949ad615151ae345f0fa522bc393c02a9796d7bcab3fedf26f1e1662e319c12173b200c6f72cfec3913c7cfc58c395d3b025a6ae4a8135baddcacb538e195a2b5750f1cf7e90227273684425e01d8fc67c35dfc8ea2f3d768c3122bff90187d207738ee4d758b776e53cd68da3118d063a1d0f5bf2a2234969fe0d76416fb69693b1e6badc9160d6b36dc69121fe2661911e704be85a8ee1c6d30bed5ddc3398bd76e0180674c9aac92531dc4ccc3c3c1ae721c152258507a92cb3dce4c6668fca56ccc6348c7cd6dac295010453725ee9694c2ed040525f66690b823115f13838bf5031d7827480bba37a936e151d4a45215c147655c01b5ea6b2cc3928c21dea76594baf491c37ab402416b2a244c99b8ca18046c01d22a03828946c15246708e70106ad758347c2f6728d04028a278c5bb2fa491b30737aa950fb2482bba68b5c12a7435a515a8e890088c4aa2a615a804cb91d968af8a7a82ca2c455794fc53b357193a46b1ea1adfd640a53250b7255d2eeaba76095e6744c7463c031de7330c3d83434d8553522cf484a1c3a19750c5a17a5147a51e88f5c49183cd373afa0afd1ceaa9a3b094f7afcb701488a8655431d4b9a827ee08ed15531e869fca16a84cb08cff9f241f4ba8f0285f65c42f346ba943ab6fab32d1a244b1652b6c987374c8dc11c732ec5ad6f2fea1b02efb1dd8cbd1cad184519ce80fd09c1b9db7ef07ea3f7432a999aa46d44d422bf2c4f9ade8553db582f75f8fb2e47566af15f565b95b560d37a9a72e109848ac3633f5bb2a63d00c882c1a059c18ca30c54ba7284465a04e75cb4a8c8e4695416dcc018d169f8a942168a6d486701d30f79b58279cb5db3c09a632c18b06369a218be336273cad4b0fa10a9dc27d41bc0386ace2214127f248d3a4f32149e19d6e89dc6af5f07cb95bec3cdcf3b884982df87ad8609e354a6c08ca6bc63dc526c36e88adc6c68645d2d8ea6192838fc62780eb764ee5cdf44f346d2f41cf5ed6b0dbf0b46dc734563e5d6730a2d92ce4bb2a5c2a8e601923ae4604a3e05c13e81eeb227c5a918498e897caae8a611a735141f7b59ca22138fce786949d91d9c831b418506c1ca03fc8bc5c0c63da50c17a462d56fd724401c0d66e5c85d05a5e48ca310c2b4ff902402288e3a3f6030b26694086c9ff4c1f0d4e066ec3024aa10591d94008b37af412a40d7a0c9814b8095871b0d817a845a4831f3af5dd66be611c05b01d7977c159a1431f0dc1763b774f348c8326176d47460d8c9014bfc7263c1f32a0284e12c6a2b17e64a36932d79cecbdb41a4feb715524f2011b14790be7073739ccc10e38335c4566fc709bb14a447a85e0444b9b597196626524361376c9ef1038ba6cae039b315e6ca9711067e837c3661bfe0a721bd86d2cb61191d80cb6c5d5b9bd91136c399ee3d8b691d98d65e51887534f6c6677d6be0b9dd88cc9a128cdae8d7af166dc144cc86ae5c8c6b46caa02beb045f90d3660b0a4900330333333333333333333e3ca4bfde37ddc1ff7de8d60c232aa45279a9292921209ac35aebce01de7e01dbc8377f0d67401ed0da10d1f0e4d52abe0757486b10e62c41ca48223a94327bb321b1fa7e055a63ce1d2e660724e0a6e8ebfe737785c565f141c4b1e13738c50991e149c94426d5585f6a5ee098ea47c5b29c7098edda4077297396c821f2ed492e698473a98e0b57d479bedef79094e698ae918f197b1129ccd6695ebd2243829e68b15296548706a3e6bf050691b2d3b821f3ebb9d49eab09fcc08cec713724cc9f4712c5911fcee30daf6690c11bc4f93de1ee45552ce109c24b143ffe8393cfe08c10f6311d467d6233d4170e3fb6e36eb2b3b0304d7b3cac52c5de59a1fb831ba6a5f7ce085cba91a626726b7f4c0b188eed1d5b47a5978e0a4c6e6cb13d9819344ea6732248f611db8793a3e87b4505a7e0ebcf6d0217ad8e3c0cb4813d66e3c546ee06d9eb7cb1f04b081ab5d9eaed2b33adab5f082d87f94ef83acb569e1b6c725211d3c0baf652e4731480eb46659781b24180b2779e6c95154d58c312cbc489a7f2bb2fb8faff09225c9a1f9871c6deb0abfe3284a9fc754af6d2b1cf97854438ea7565b56f81a3de4f918415388aec2bf64112d4398e081aa0ae762aeb8acfee1a334156e69baef49bf7df944859f3a948ea297a7f02579a648ee5c1fc4148e678f9e2d867cab580a2ad4c986258f144e942011fd330a5f2ddfa71ccdc7cc88c2df509a156982c71d0a377687f7e8e0592d28dccc21dada625dea3ee1f49d947ac8924b9927fc8ea12558b020695727fca05eb3a74cc509672285e718de849325a7d4d392ae929af0439248513535d57932e1a71c4ff89c35740e0f263cf7499b263269adb984f763ee36d1e953ca58c2dfd80c7fdf1e5fa412fe86ac1e49ce9a630f4a38496ab2cf5c26e1ada698aa6221ea2b92f067b3860f5f8984ebc9936d65b5ed0f020947cee6db72103d6df2083f847f2c094f911e71847329dc86d481a7a46984532187240b33c2bff0d03767c851c72ec20b29592ffb304554116e064dcfaf19bacf4f841f7bf0a0437920c217b90b73c1e3104e6a5bd6beb74a1343787fa163f3cb66e1e342f8d32621dd29ff84f0c2079d6254f6993708af3abe93f1141fa515841b358636cf5aaa3981f0ca3c27bff1f3ce00c233ff20d774567cf40fce775027a942747cfac1f50fa66346abd14efbe0fde5caefb1458b1c3ef871920d8f7b0f5eb7e414ba23f5e0556bd01a3bf3e066a4d57469ed2d9c787043dc6f23fcc776c13bf81f77297898e2b6038d29d9071d07621dfc4f39cec17d460acdd1c1f19caa3e883707377c10739a433e084f0e7eaa34ed992da5b7581c9c34ab9eb482e58b191c9ccf9c2db25f8c31526f707cb2ed322d37b83982abfbaa4fcc698333f39f4288f6d92d1b3cbf98c2aaf755e6881220630d6efb848fc963560d4e48993e30b7ec3fcd64a4c19b481552485ff5c6340c178421030d4ef504dfd8b0ac40c619fced38168fdfcdbd449366011966f0524e89acd441a357b803168601a30c4ea4cc1f59c425bd5eac066490212f937073e943c618bcb4b8decc95a1ff3b2eb6bef0a28b2d3220430c95e6b0fea3142eb68c8c30f8e21ea4b4a9089721cc850c3010c3fb2455fd525f30a656c6e688be1788e497e6735e0b97404617dc0e1b724c4939d892b8e057e7cae361477af1e82df8ad193faf355ae1046468c1ffb19c3286adc6908f0c0332b2e08cb77a78cd1d7e230b032fb20232b0e08590c1be821ba92e68f274d1257fc8b08293c26a32976da4bb8e2fbcd8c2aca08b14aca00ba4808c2a781f89a7d45e953cbe80046450c1df4e9273e8925ce00432a650351620430a2d230ace5cd0147a26c3c5568d1a99749001053fe23f3e5189b858be31c87882d31756db2d212d4b8e2623c87042d540818c26f89299cf238fc2cc4dc6c542c074f1850714d72083094e6dee4de7d31a1daf8c25f821cdfc440c2a5143274309e590638979a2e3586720230947e6f6c163acb83a073290e06dfe9c25a40d1f117304c773f81023a6c4b88a11a86ed5f4f4be087ea8b6cf1fcfa9559808debb89440ec9330427cf769c329a840bb1230427b84b47f3b17e529d20b895dded953d40f03d677498f0d19c477ee04555e9fc99c423f73ef05faa8349ead1d7647be0bd664fd61ee450226878e0a4c8a5327b074e86f71073c4e69a4a077e900d39c8a164fb2293037f656cc35598780f0ebcaa8c0d9afd22e3065e4a15edfd4b82e71c45860d1c8d1e5f4ff239f8e8520b377264c4bcb1ce63b2d0c2b9f6d68aba6916cec9c7b45923a1a52bb2f07290104453864f6d2516de7c8e3b280d8fa25705168efdff6726af8e1e79857f96a5239f9493d4872bbc1e4d4dfb186a3d6e8567993e9ccfd979b4125678eddee5a1a9526125abf003adcc9a93d554481255f8697d36e498c35a8224155ebbc75a1d9ed9c1ffa8f04c730c7b4df6e6fe9fc25b93e41d95b973646f0a7f2cdbecc77394c20fb12395f0b1a884b449e19ca71ca588ee8d3b7b14defd871134ea3ffc220a3f720eed22c77328fc10ed339c87b1fb9941711c99c7c19f70433e881e8ba6d58678c28df6618794365c6ad209d7cc2549ce0ed207ff72c28b5531df99d4a3fcbb09d74396ca13a2ab09a7ec2a64dd0489566d26fca0fe3ce68f35cb6a30e1d9bb745f889472b0f5126e1e0d9fa36bb58417251ecbc420e991a795f0dfaade3e085f29524a09a723db7d32fa78949293f0dca26886895312fe69ae0c1e1d44a66846c215d90ed70e2b64c925249c1829ddbb33a5922e1fe1a51c87312186565c948e70a23e78e9c923252936c271cd718a5ad4a41c898cf07d653a74e416633b5c843749b3e414b25d21a1225c4b216ca203a99839897025367ddc610e39db7388f02a5d468a9eaab4ce1dc2ebb40e54428721bc1c237d20e139469314c29b4a3f214751199226841fd65fab669f2c293908af2e0495a0412a624e10defdcf0709afd61e7781702b4d88b163f848313a40782672f75761d2a4cc1fbcdf902b85c5f62d8b1f5c8ddc954f34d607ff438a629b35ab6ccef8e0c6584915d6d91efc389e1cba87b3ec74991e9c98825d5a87fec9c195073f84e8108b1dc777b6f0e0e794356f26bf15c6ba83ebf669726059b3a65776702d6cc2255955072ff769c7b9a347e242073fd688ec40dad7d3630e5eceee961e678b62b71cbc4a1a25a925264b8c83f3f663f963ea8bebe0e04cdf5f86fb4fd5aa4911e30d6e05cfa8e571109f330911c30d8ebce6ded0b8b4c19f2ca99307f5fd5f151bbe10ce53071d522cb9585d839ba14722db5c4c88a106bf7c443ab6b7480d49831fe608319a79ec65f5e130c44083a795455624bf60887106e72fa9484bcc47b61dc30cde799aa7e89872989ac528831f2d7325cdfeb125916290c10f324d6fad3706bf277ffa24993e77c7108317a1e53c36c86676334618bcf940ae03cd124cd3c4781c31bee066180b2ea576c966e20557d5524564bef34f7e17dccc79429c489ca70c73b1759683185cf0da5375852017184c83185bf02ace3f36cdac11fed1829bb53abedab6919c3fb64819c4c8821fa2e2be3d858ea7432c3897f264df1837358f71b1750557d42c64a4325bcbf62186159c1c6677dfacf6f5e657c1dbd8398e3368baf78de162cb84e1c50b900831a8e0df98faddfb7de0999c8217db248449a99e66f2c59182638b300c181d460c29f8fd3972d49c3c59c48882575953d7696da9fd5070d26a44e592cfeb63f182055b1ce58a184fe8b25648bbe49ce0d5f747e9552fd61a89d104275eed82cfa4907e7ba18156c46082779b43878f30cff0314bf0a254f5775039281b318612fc3084075feef9c24d6c8f102309fe4fba0ade59eab23b48f0d6fe55a5031569d31cc17f995eef0c8911344611300611fca822fb3f6a6d086eb7c79184c41cb9c4b5841842e8da73bfa46304c18f4655e5644323463e06100c125307296ac80fbcdc71322dedf8e08e37a6c5b85c7a40e6efcec14cf43cf02a25252ace63077edcdf9922bad681a329f2479be53843c639f0b3e6385eadf78eeb4371e057faa0b6de73032f8b86908378897677c6b0814925e7ca746731520ba746e2dd2c2b5af8173dad66e224327766e1d4473ff389b62c6e93bc19258e85f7e95aaeb18485571da444b779b5c89157b831d53be6945f336c5ce1a470999c337bc8f05be1c7d6d829bade53dacf0a37a510555931ab36c7b10ab7831c72982c5bc9660f55f83163f9b6844db726a7c29c474af2c72e7563a2c2f73c1fd541d3fc3f7b0a377dac1e3d336b8a536ed55c653e61624729fc6c39bf5d7497983325851762dea8f48e2c878f1c459646f2460ea273bc280c8b312387394a6ff443e1791023e4b01550381b3165a3867cc2c9f1519e34d2e4709527fc888f91d6f368ca612736fb73959c533bc6092fee4f5bc262ea33da8411368410c4e4628b0c03d08413d22f7d1061fd539e4c381f7afa1c652dd9670c261295d26097bf84f3398a9d27ceea52d2125ed234c135bbd587a152096f43fa8fde424ca97228e1e7d618553e3aae8f3209e73aad87906f3b7f1c92f0b27d881ac3a5657723e18739bd234374dc390909673407a17a62e411841b4d6e12e308d77ebd3e8a4eef5d69849f2ba78df0b072dc3d23fc8bd5dae571ec5c2ec24f7f4babab15f1796ccca525c2d97c215b9e17d91c8a08ef3f6b4c1faf5fe6104e84b7dca14c5b6df20de16be5cc8a9d42782a1d45d4ea3808e1f6dc6f068d109db3c7208e209e839298d22505e15fae79fbab74200a89946eeb3e8e2640387193ed347bf41fbc8f43e71cc9a3fd4084f475b91493c7edf5c1b5e47f29a7cd714735f3e178fb38b6700fae87afee20c5d5839f83d89a87b3bb8418427454f93e78f0ef53761c5479e41e7707bf2c2c7c799437c729b583339a3bb68cf920eaa30e7c8c8a31e530c71da3832ff6ff9dbeedd5b49c83511573dc217b8614b61c3c2fadd70a9e38781f793c34724f761e0e84a87cc125f75418dfe0cabd44ccb176f5c92c089552f02ca4bacc32a131c22878193af41c778c1de51c14fc8ce91d85f4b149774ff0c3d08aec0e7382975324f6f6868ba135c1174d299364d487d162821b7294a3e4b496e049fba87c903257564af05245c8d2ecefb72a097e10527aba8b69ec4307129cba0f59f5417290d271042faf5fba8c7418c10d1da607ddf3299d53043745998c670fa34d0e11bc645d15dc21b81e955d730826590bc1cd1965b662d9cc1b0427be83ba9f9b6513089eac445947da4af0fcc0f95c1f7da776b3cf077e84a76fca6678cbf4c077b94f159172ff8407de5f8e63794739c00efca8e3ad4992538c8e72001d385ed6215d8b79b8ca0172e0845039ccd9c73f29e40038f03dca41c2a6567b0939c00dbc288fa255d286f2200938800d7cd91c2b74476ae1d846b9ca10ecc3e769e19dd684c7f9cd3d3c66e14713424c394e9bdab42c9c9e0876962b7786742c9cc91bf75148f9c9372c9c35efe0ad738ae9ef573817c3c71b7c57f8693ac5a887a487dd0a279d44e720e5ce97352bbcdb8ad6395ac50a5985f31f4a6d6c8d4aad0a37668aa7cc4a332ea7c2f76023a36999dfcaa87063b6edaccf1fc7fa148ea57bc8a19885aa4de18d67a57043fbdcb3fca3284941858cc20df691d78c2b0ab7deb447c35068bf390812ab8282abb168159a7ec2f598bbaa247b2a0f4f381a835cf8d8eaf46527bc28293ec55776f992137ee8f7d6482321addc849b3caadf9837849b50135e8478554e294cf62f139e4d5d761c478bd51b269ca834d9a1b2be8413a2dd87d1375eea6a4bf8513a97927b9f94a7ae84eb2396ae634a53c20f52ca42e6ca2c1bf524fcd414434e1d95fa7b24e1a5d4603967ef38b427126e0e326f4bf44f8b1e4838993654f6795f34cf233cc93efed31ec5fa8e23bc10b52e6a348494368df02bb52a4c76480b1b46b8151a953ea3c2ad6611aef4864647b5390c1945f82942fecd914984137a2a6787c84abe20c273b7b69aced4f09743f861b0581fc28518b518c20fe672fc9bb3570a2185f0ad627658dfa7f21342f8311a72c60aa61d4c06e10762ad599f20fcee50bff271a1251208afde526c594b5c0f083f8e393a8f473a4dfd07a7cc3ca60a17c362ef07afdc36c264fae065c8c79afae083a7c9c6638cedc1f114317f242322293d38f741d24abfec6a1d79f0623c6aba089ac3e8c08397af4e43dbb22ce60ebec4beede0fb658ec3b5c73373d781d90ea483db95b263344799369e831f74bc695210e5e0c6d439fabcc6c1dfa4b943f1150eae654e92f9dc342a7d839721d9f12de5414abac10d1d87d9632b5cfb6c83671a39c741d2d431996cf0ac5243541fd7e07465956c1ec658caa9c10fdb614e558fe9bc4b83ff7190c3b8d5d67cd0e087f07392dd3378bdedd1a5ac0e0f33381bdd7bc3bc6570bd83f5b05346062f25e6495932ba778cc17b4bb9376214afaec4e09d057b0f6518bcecc8476390180ccefdbf77c871bee0877e29671b8f17bc145273f061da2c962ef85a23bd31fabbf35cf06354262651f1efb7e0a5ec142cc3460b4e6bc654a9e262684d16885e1d7c482958f0b5dd6247989bf82857d8ae6445836a0527749810217c7b1456c14bde6973850a61b64205e754623a4cade1a932055742beec41ecaceb102938a15fbd3af351705cbeec3f780ebee3a1e07b0e3b753a9fe05cd01056511b6639c10f2ebae5ac9247e99be06594778f3f8c0e1a2678b933640a1faf5b64095e84d09b11568267f769f1ef9104a73e7f1c7ae88104e7fa7344f5f4b1cfe3084e0e3a42bc4c99dd6d044722653bb06c566a17c10f513307496622f82769a93ea423cdd921f892751fe628c71c9b2b0437e58e62f28c06c1f730735467962e4305821f27c96129da64f8c81ff822b612c2f47a10a50f1c33fbc91b246687600fbc4c3158a69b8f5b451ef87d1a6fb9fb8314b20327d9c7a1e7f9dbf6381db831776ba596f9162f075eb4ec100f217b640c07aeab4fe6685bb63206b8819b5fca26967d5c6f001b781df97a35c7e553d7c20bda21244d7972eecaf058c93ccc5acdc2f98aa134e7cd70175938123d3bfe2894e68b36165e7ce8133d473e2cdcb056a1736d7988cf2b9c303194cb755ce16a85bef4c85208dfb4c28ff6917fda9e70b16185d71f555cfe2c4a8e55f8d7b1c74345b0e05154e1ab767c3908396ab44a2a9c9e994b97b7a35454b8f5a9c25a8edc29494ee1e49bdc418839c8111253f8ef963c8e42be147e8c9ddd36ea34073d298a985635cb1fa370bd3ecc3c7fc4ce1ea2f073ecb952ce23147ed0724b33d11dc530289c1ccea3f9c935a7f127fc1017347bc7ed61c69e703e481eb6aadc0937b9698e6cd2478d2c27fc568f327290183ede4de09303a9f50fd584dbe9cd639294cc5ccd8493e67148ee9a63d78909ff35c2574a6dbd6dea25bc99bb54b163094f428eeea38e2cf66325fc28b6e3d764172585126ebabece7c7196fd49f8c1d29b6f4f648c92f0d652847f0f6be922e1479914113465c57490f043aca6f031e5e0ed23dcbca5da97426f089a23bc28a61d474937b3aa11fe878c9d3c3a9ec830c2f30e3e9c644c49c3a48b7025b2cfa25fc44c114ee694e1eb2b89f02d3a8ec73c06117e0c3955d33c840e630ee14a6ad792397b558d219c7416ca3fe410b92b85702b7518c27f74ccac10c20da95f4f7910aea5cc9c42737f50124178919e6adff1658e914038e3b1fa67f324361140f871d47879349dfff3073f6c9c5ffe2d898e1fdc10cd41a3c61c65f4fbe0c72c6ad71d84d2f0f9e0e5a9081297ce93f57bf07269d80e2b7f90cf430fde86ca520dc9fb3f79f093bf44a494c6833f371e9d64b21bb3efe0aaa7e710edae1df51f695e8f3267b90e6eb7664df1618e89321dfcbba43ed391de4a9e83172cfbfc6a2c073fd2ae58173193e5c4c10be396fe29c2fa0f073fb4ed896e1e43a76f7025888a7bfe4e9aad1b9c546fed39d536f86e1ee788930d6e6cb986e6c91b9daec18f3247fd1e199d326af0a312ef8e47ab7325d3e0fbe5b0535a5b0f3e687025ddc392cd61a9e50c8e4d6a0e22df9ce4308367f159b56337ff0ecbe0498cc86f6bca9a0c9eca4756f48cc14d93261e3a2ec570598ebd30b8b93e0a9ed181c18f88ff5af7dc51e60b7e468de778096abf17fcb0a93f66c4f4a1ed821bf37b5cfa7555d2b8e07768161beb3129b305af42a37cc428b5e0474c512aeec982df9192da771c2cf861e63c76472186d4b9829fa3beebb11cbaf35638086fabe0a73877f31012fba6829f72ec9b704ec189704b69a191829f3b9889cb11053f7b700b4bf93ca40b147cad309adda33cc1cfc93d4c158ba810e204a7530869823716b3b2e4ac262d61825b2949aae6ef9827bf045f353a7b234b18f195e066f449bb764bc93992e07de68f526c4ac99303097eb2aeb5f18ad27e1fc17f9ff6a8e41d7dd846f0c27806499ddbaec345703bd88e93c6f441083311dc9a8ab89b5893cf1d82f3eed2df9999735e85e05884c672d70e490d829fb286c98a09047f237bfa851ca4cff2077e58e40c8b613eaef481272947c991e981abed9653a2689685077ed0d1367fb13f0eb2033f567c681b3d126975e0ffe63953150b90032f6cfec366bfb2fc1500077e249d9d255d3e89ae0037f023bf5c3612726d8a15c0067ed8d7f93cad3286ad165e6cb41c2a365af8519a986d9259a7c92c9cbc621d694bcef943167e858995e314652bb1f0d45f2be7e8520561e1b84792263d5fe5fa157ef0dfd3ada66d63b9c2d9f48186fe68ec2aadf0d62b47b0b14829cb0ab7630f2b7d24e12adc8c728b2947a80abfdea227582c9b8e3015be5fd545e5303a8e0851e104fb0efaaa62adc7398537f641ba2bc7b1bcc7145e6dc4d4ea94c2ed305ad424e37711527895434f72f5d1dd3c0a3f4fca986286cdde8ac271f30b17257d6a86c2eb3a3593cd80c29fa9d7f8cc7cc20fedb183af142a2d9ef05288b38b3df127e984177f412c956685ac70c2ebb1f338a6ca26fc186e42c2868c29af09dffeb2df8924136e6a8851e22398f0256d5427e98ea27309cf434b59f5bf25fcf451c75399551ec757c2491f6d78743c259c143cca3a940dd932092f3c580a9e9364f99084ff31855812b6634a1f91f082a58b1e3cb49608094fb3624e533fc289fefb0f153bc24d1edb46f8514cc5a7d258b95e4638eea369c5738e83f02ec29f0ed3be43c7b1ab5584efa16a089dd22a443411ae660e55d4a453f78a0827c4b4f92b26a3c27a083fea682bb93cb5c7aa21dc786bf5ac4d9e2f2d8497aa766df3b9ce4d42f8a9b9d36b3a085f543d8a09f2d6a320bc694ddd51bb2731108eb8e4b8de83b4660908c77fe5d4a492471effe074a8e17fd38c4f871f9c4a135bfbc32746fbe0044f95cc32ed933c3e387ee1de7bed324bf6e078b40ea2a64eafad1efc73efeee8687bcd3cb81edfe6af110f7e0cefce76d91d0ca9af52f6783b90e6b73ab81e5ad6e0db35b92a3ab81d8748afcc1d2e85c8c12b8b2995dd2671703d54ef8f573a38781fcaebfa63c8aa746f703a7a0e2ef391f345e70657d2628769a80f2ca60dce46878e1e877414346c7072868f6369bf64cb1a7ceb0f79de72f5fd6a703d7be4a04572be701a5ccb7739c75f4183bf2134a4671a0b5e398313a33d9121a6ceaa98c18fead0d724a40c8e89a7c5ecfe4af927836f39ce399aabf1a8ff3178926e2ec4f42858ff6270c2fc6d75dcbacc1f066f2a849ef09863c607839f525ef320390cf71c5ff04337d5140f29217d78c18f3653b8ea4bd1bfa30b6e48b19c2485b372990bce59f684a40f72d0f1161ca91cbedfbde318b35af08367faccc741d566b3e046bb1cabc574d074b1e0d55b78c755dd26ed153c099b434d9f90c9572b3861fba543e47ca779f1b0a3b4c20d99a952adfb2353cb0a672efdba8ac52cac5556c5baff63ac3437d31db3a10a2ff664ffcf9b6e1e7ede48859f2de95108d73aef3750e1c5ca1aa9627b8698be53f827d33d99f2fba5e698c28bbba41eb2f3c4985429fca0f597a23b59be5092c299bed8162dd9a370a3e40fda91dce5ba4c149c654578b95876677cc7a1ba22caebe650b829ddff7564c7b61cb2010abf446c638aea486df9849b428ed581470a911896c28627fc8f5bcd42a8eb550b373ae19c78960e82b1c50a0e521d48c20627fc2862c71d346724e0c5c6265c0f1bce43e227c7686bd4d8a270b0a109b7f307edd8983f7a8f63055e8071180e6c511b99f083905c6d5372112d4c50e92932965d1313193652f89770babb2445788dd259870146172940b584bfb221b572b08401461717d8a8847fd9f5b17b4e295157b4997d887a7a109d7b42cbbbfc4938eefeb9225473f6201e614312cef976678e241d093e4e2675f9e28684973aec3a5d5269afec1187f1b87338c29678abb0b70ef70a79aff1289bd036c2550be92b98472184ba1b8cf0e37c1693a6cfb1087f725853eb137b091b8af0673d7c18d357527f4d02612311fe9a7af9c7f9d307416344d84084af6934c2a52c1b61e310ce8c4c276d172f4def8621908fb78314a23c0b001b6c14c2db681e2ce6d01d734cae0e3608e17b1c678cae0c51a9a941f821a4b76c99b3e5941e82f0831c66cc71777ebd06a292abcdaaacaeac7c5e51228df87ff600e1af44358b31440c6697fdc10feeda2b751cf7e4982fb65081f9628b177451aa0a3b60c30f4e4ecb24b12f52c7aa45b0d1072f870813d9fbaa2ae40d3e2053a7eeb61aa6d26de961f4506334dfaefed88d3d781163aaec9f8fb1adc2c596bd0bc0c0aa056ce8c1ff402cb43a0cbfc8835f21e4683347cfc596a5800b30b6b00ae374c10518c9800d3cf871b9a475de1cc3a4f9c25841171f3841170fa851a3460dde2d54e08215d0c61dbe08030c177cb1c51602d8b083a7f59623dfd47182159814a4e0e08264d5c129b79c3938952437aa0ba81eb0410727786be6f76b71f54e7080018651c1165812d8988313527ef3205c7a6ffa2a0c1674f1052939f076112f2257259135356f96b3db448c1e0bbce00d6cc4c12fd390d992c1a3a6145b75a0cd7bf1451860e80aba48c11746058a81116c711b70f0f387db0c39763ce98336dee07faab75f8c1eb9e106ada32eee4ecb23d4253eaf8a791c39ecb68f8160a30dbe7a6c99f6d1c63cd9dba20b161c5b18166cb1050646b0458d0d36f89f39a5c89363b61e8b8b2d2ec070410a4e5a60630d6ea6314f79324586ac1729b80d3538d61dfc88bc5e5ce02eb091062dadd3ba34c35633cdb6e66290b953b58f49738213787101167881811a354ee0450af2be0883051b68702c9ac6a0622f7e1ee4622b055d187206ef425b7cf6278fe09a2f5a00066e6c98c1f7d850219fd4d25c9e8bad93822e0c29832713730af3fa4bea09e38b1680915c8471a80055f05da4003130822d686c90c1dba4314721746757c7e08ac66cfa7d58a11d31f8315b8e223950cb09831f7f0ea2b6e251ee3060f06cc6265708ff3959bee05784201ff786f178c10f7334ef318dfb8574c149e96f51e9a639940b6ece9ec1453ad58c640b4eca665b16ee344cb4e08b5d6a0a92d2a5f6f70e26fbdd7b2c389d992ed9edea9d2b38b235bfa1d6a3d86105e72a778ef139b09c1d557033648d930ace9b7cb470e9297819fee73cdb43b1b414fc9118b2759028b8b6a93f8378471681821f89c6a658988fb59fe07ab86fada8589ced044f52da48f1f19a857013fcd0c346abc87124394cf02d36422563489163096e481fc12347555a2bc10bd1c166869cd2c649f03227b3489535d521c1f5207fdcae1259b53d82e3a5213ab5467053e5e8e314db577711b4cb9ed006113c3b931ca6979cd9d3b3310427a70c95b4729c3aa4674308ceca7fe4f164f74fc9b3110437f465cae1a291f3793680e06d0e391ef994424ef36cfcc08b6079e22323692acf860ffce875de4198e46dc1b3d1833f7bdc23d1e581131e9f63348c45b703e762b4f7adeaa0a203bf62088dd530078e7814e9adbe0d1c789fea714ef213a6be8d1b782aee5d975ed299b7610327b79a4711e9e31baf165e8a0923293b8ed26b87167e471b169ebd269c7666e1857d1c449ab2f02a3c76670a1b2967b1f0259a8ca51c62d607165e0e136b3ec7ce9257f817f239ca945aa9e50a27e714d3e5dd61c76985b72efd59c3c692301d56b85146e3fa833a4f59859bb54d3ac5b8146355f84126c5d87452e15f7d6b06f3a0c20f16730aafc7dd6352f630a9620a5f632bd67df4518a29851bf31e2ba490c2b3f0968c12320abf26b4c207d1ef3f88289c4d3d69fa0c853715bd4dd3dfc620289cb6912c62295f0a924f7829115390a858a9239e707ab3739035b30c914eb81aae1e568c8e909f134e5a86ec3064aba0fe26fc38720fb1f3cd4bea356125bf9cda1f4726fc54291fa61ef1f83c30e1a6ed914b96dcc2765cc2e94b1f65d7b425dc0e72b678f88e1ea42be1db7d18d971e71c7253c2d39c695b622b33d793f07360725922857f9925e149c664f69fce718c23e1c61434e7ce3239430c09275e24856675966b1f4184fbf3924d1de17d14c226767dd49a36c215f54f6da119c62319e1a8c744d5ca1e4de722fc8f467324e36d174e45f841d2491eef12e16f4c1aa53ffa87194484f7e92d857d203165f0107e040b734136fca268083723e51842f028c28485f0936407a9912384ff39b3cd86078f633708df0397bbedc958a320bc8f2aaad53eacc50a849783b07eb36eeb6105083f9c995fd6fcc1fba01a2ac37399871f9ca416aa434da60f7e289363f48997d0c8f0c10932397d58397bf0a37a771817a207ffe8c129cb9d3a79270f9ec6589f6c62f0bae0c1afdcd9730cffe023e60e5e7b7cb183539a3b2454eae0873972f4317d70c1a583ef992a31690ae123998363f9a3935c297db372f03de54aee7d1c9c742ba6ea3d1c9c90439979a455abbcc153f5a0b28accb4ef063774fac852eed82dc7d106ef5d3eb00ff9f38d071bbc8f4e6a9dd3327af41afc8ee73ebe540d4eda8a9d95638f2ac569702673e821cd46839f912c26979cc149e7a3d616dac3bc197cb3dff064d3e797c1495531f75493c1b3b33149511d8393c94672faa468a38ac1491be722a1d3a34bc3e0c9e4e06d29f64a8e04832bee41ff57a4aa07bfe0f95a88d029e8052f7b9691986ace65ec829f6ae1e319f34873b8e0e7cd9888892db2b92d78b93fb5848a18fd3a2d78136361426c89e7c8826f79f278967df96b58f0d275fc5a26623969577022222bf67c58e295150ec248feee5855c1894924a6145eb93a54f083c9db1e3705254f8e9143450a5e6a5289e935240a6e482ef2713c1628b8c96da225a67f7c79821fc6c58ccb92db3e27b8e1710ed5e2728cd56982bf39ce379b63cd39c304bf54ec249c4bc8d6c743865109558ccffa7c26094e8e2a4729a305099e851ca61c5cf9d7468ee0bb472166e690b152c4085e08398e6899c2f5e58be0a73c29c7131e4470f37d184663de48d13104b743c81d875e087e5c21c79572e430dd41f0e3102ec7dbea1db440702d8450267f3167f3074eea891dc5ec286dd83ef07e26bc6358c90c750fd61c2a5a2c0d0ffcb2b90e3a8ea6fb8377e0e6aaeb491e1df8a6ea1f07570edc8eab3ca590c581f315be56ed0dfc1c269329f769481060033f3e0a59f2abb570724c4134a6ce725269e1c76130d114d159f8df79629ab01256230b3ff020f7e6138bbac4c20d19636bbab78f21b0f027d8b5759a0c96bdc2f1d86453b694ef2a5de15a8a11e71f6c851fa6ac3c6b6485133bf038b29854307115dee638248f1682670855e19bc731a46473ee38970abf5a3e920f2544a643856b1e473139fa3cfad829fcaebc21a5c542d29829bc4a2e5b29973f47560a6fc42f420ab7ad4b7286ef706a915178122b872963f7077922a2f0abb327c4431f0adfc3467b8efe79c20714be450a0bb93d5e8d9e4fb89a3656e4303a5a763ce1dc8da758673ef1309df0443458b0bc2177a4e1842fd9999673d4ea39b309b77275889af346b2144df8914afa8e3a997574c9846fffd92c5b65e5ab60c27331b32c0f3999e6124e4ae7ccad29470cb18413738c1243ae849761fad206cfd9b194f0d64cb352ead6ecc824bcf4edb61d7e49f869528cc9b28f849f72ba9c3e9258110f48b81d2654943693db8e47f89e82aa457438c20d29738e432c6af67423fc38fa2883947b349a66846b729eb2868ae93e7a11ae67d9e09f61430ab5229cea286bca5227c28b219484b31c45af20c2b394fca14b88d6371fc22d93ec3996cdaa8a21bc0ff5d01f47918b6c219c1c4426757c84f06bdc73902a1d8493d7c3741b9ded422a08ffdd53e64eed953b32108e66ef9421de2ad70908cf23654df0f30f5bfec1d7709f29b2e32d1ffde0888ba528967a7cbe3e78a9352b92d1dfb6e3831ba135dd6a5f9c670fde64694bada93175f4e098650ec5c62f36260f4e5cdd5a0ea3078f030f5ea61c6bee204436b63b7875de1f840caff0cc0e5eb40a390ec283c831ab83df1263989842072f4a4a39889123c65b3f072f7d98e39e88c90aebe5e04627390e6e4e6917f5beeecc818393c7db3f9387cfe50d4e270b6e91376ef0ede5235aa749744d1bbccb1c25a2648397c390cf18d5e39e5983e3817f320feb715d8a1a1c1b19f1acb1b672d2e0fa892509963b98074183932ae7e6317557cc193ce94e131e7d33a02165703c89aac5e8f155f964706ce63c8cc1f2e6c818dc48313c3226710d8bc10bf9d80e3eabc5360cbe44c8299face4283bc0e085c9e123491e31a45ff03fec0e2486da94587bc195902991a84f92d3053f4afa63c2528ec25cf02a7d18973d795bdd2d38e9fd2b47f7214b460b5e856745084133250bfea754b9b3ad58f0b4cfa34a41bd8297572b86902243f2482bf8d27188ce548b746615bc8e9db3974905ef3a96d95c15ea564ec1cfa27541baa30b0335d6e04fce29a79c3e31c73fd5508313323b7a98bd37c7d2a7c14b52eba1e71c26b9bfa0c17bcb29575a98902c6c6a9cc10fd45c2c977c7e50c30c4eb5a492d58eb5366519dc4c1a1d7358ab99f385b9e200c7e00bae4106ef3dc8df352b1d440f1a83ff95917cb3e5387fe41083ffb16dff88ca61f0cb6d523078b162eedb58096a577dc1691993bce0c714d27f7c1c540cf9d305b727d347b221d6e0829f43b68fffac3b47c6d4d80256eda66a9fb121993a72ca9152430b4e287f0f5972eef5ecb2e07dc584a5a5160029d4c082d71e76567d566feae4158c2dd917b493a68615fc1cc40edb516d35aae0dda58739f8daa648550d2a781d9322f685cad86b4dc133f1b39f4b661f41ab21854a225cbdc4b3db3f45c761f25ca79428f81efc6f76924f179f5f64208c2e9e6a40c189317956091ead553abb45d1a0c613bc0c691f9a48ac66ab38c195892cff0c25175b2970810ab01650a3095eead452dede71b155bc50c1162fe8a2aca67d00b7c81a4cc0446d6525cd3d6ea4da530ea15e61420ebd1a4bc0c3ab3a66a4bd1a4af0a3e418d523bf6b24c1ff782e33410d2478c95cca23357bb8ce41358ee07cd011933a0acdea670d23b839cdb6f2dc45bf0b1d1f6a14c1cdad31720ec254938670c0053588e044f5285ba7ef188217a3d4f26d9ba7206b0d21789b377e7387641070950bad2f0f0f912daf48d95463f0fce7670d20b8f943baa5af508d1f78317d1c8597dc686c54c3075eb28a3c217610f56bf4c08b1dd39e03ffe0f3b13578e0d6467d798efe0ebc4ff2d7b93e7fecb8d6812f2556fea1c8f9a6a9460efc157b8f21fca4f848db410d1c78221f85b49023dd6adca069cb3ad5f07899f56ad8c0e9f4183643566ae157a7e4db964fe7a9a685174d93254b9b5938d1cc276f92ee78a3280b37326bc5dbe5dbbdf3a20b1ab1f0b5bd43f4f54fb1013460e17c14ab932f890abcf8420229f0e29c8374e0cd0a345ee10a67a4a245394b5be1c874960929fa8b4a8815a0c10a3707d6410aef1e1e73ce2afca02124e4281d55f82d39e88b1239346f4c2a9c50cb7d11613c5f5950e17cb04a1a73189e39f23885e313293964ba47e9834de19da4cb5c67bf1e79b0145e5aaa0b69aa228597f2f45cc8d1cf7ab246e1895864b5dbf049461285e7bd1d9235191de51e0323d8a20b1aa120bcbb2ea6e6ccba5c3a68a59453d88e06289c641d2264dfe827f6ac4ef35a8f9334f3ce41e5f65852746c3ce1b4af64acfc49245cccd3e8841f29a7f021f6458f5f2a3438e15ae80ed3d6e6686cc2f18f5972e4f46868c2bb0966131fb287d9c74cb895d583a68eee474303c384118307c48006263009198d93b4cf6040e312cec73fd541ce1c96a024625cc2e34443e6b633ca448e9b5425dc4822f9bd2e4c0947aa7e23c3497e406312ae6a76da761b25e175745e1725e6bca69a48f8a1e55053884820e1a58491508f5a2585f8115e24f7ff984c39d2d83ac2f7d0d73c8e36a68fc735c2cf41960d29d46784f7b92ba5c71d5c4461e6716791f1e63dc9c358af082f04092a398eee72611a89f043aa7b54f76977c88108673de6f83dc474eeef1cc2d99088507eb51ed6c410ce673b0fcb3b3afdef42e4b6a22a59ef6521de5539a8ca1e2ca5c8488f107e1c7b5699746d15680cc2f3bb10fe628809c297ae18a5a7c3e88f628158a542522542d6ace63ebe903420fc384b984e9321c337f8072f49769c2b578c4f1de407277fce2629c4e8e9238f3e34652d27ef51976a5e26d197eda5154172f0c1fb38233eaeb2ecc1b1b4f133db512fa0a107d73bb67e992a4d1eb677061a7970ad2622bbe51c68a08107278878184248be71e3d1b883375152d49e790fddb71dbc8be930b2265407ff553ec8418e2a74f0a34d26edb183e409cfc192ad16abd6146f49096b8d918a395a0ece07a13f556d44230e7ed2ec5959b4c39472c0c1ab8fb6159115491de40b2f24805b031a6ff0b2e5ec9d3199774cef063f98921c42da1c297ae6f8c2ab0d7e1ccb79ccae90d35684061bdc482a41c634668af28a69acc1cf1e39b45384d5e05ca808b229d633a6541af2940fb9cbe9a3c1cd39a38f7a449be990c6191c09e571ec2853766c9bc15b7ff140727f06b9b60c7e871c7a90c10fb2cdf585bf1c61b531705fa2219231657116eb115b44424aa798187c390ffad42a0b4356b1769e325612369f11338520f6c126248a60f03587f8ccb3e182b8c00b10f080c617dc54b38f1eede8b56337a0e1053ff9df588748a769ac9d018d2ef8bd1e7c5bce2c122b840b4eff871ea22593c61614abaea9913497d4d8b6df88f513a9a6a105377518bdcef3a65c9366c18f5268cf97333b738ea48105bf2d6a7aceafb973ecb98213ca254be890ade0a5a70eb36c39c8c6a80a6e5db8e49155f0cec1a854f0e353796c6c7aceb1e262eb042bd805d098829fcddd33cdc4b8d88ac1910253321540430aaed445394b9675952e5170c58309e91edd52b98602776b5b25325257e3a7bd91557c825f79c343a8faa8734e2f136838c1ed28933be6b553f9c409349ae06a872d1afdeb3bf630c19199edde90f925f8e9f279f4b14b3494e067ea4ce96147a6393322a09104ff25bb47c1e3be889e41829b7b735839a87d84466dd553bc624decbb3607afacb9e6e3a36104b7d3ed338fa56814c1cff1f44732398a06117c8fe9e3991ccf07991c34a03104ec3e4aa6ee89da808610bc770d5e1ec60cb1262708defc4848fe7cf141f00061ab1b95956c2dab8de84afe33c973c77624971f387296d2c5687e631e4cc3075e0ee222a5b1e84d6147a00b347ae04a38891e476a8e83845790041a3cf0d64224a4740bc933b883c2d42a3ac6cb5536694c7a69e860cbccb8cb2e29bbcce8aa8c14c22b648ec3252eb668e4c0f9d06f1d7ab686988368e0c0b9f671f1ec48534e1b1a3770fdfbc4a3d9102eff84860d1ceb9cd13e6ebeac4f2eb6bc08630b3050701816a05560462dbc943752c59c6bb2f7dc8119b4702d3349aa68698d1a555f80b13366e1a5cdd41dbc86b270227c74f5314962e1a47c9329c33278871558d4a215dbd52255ee362f390e8f36f2fb0a3fb4d0719a438e2bbcfa9446f36d8c291fd30a6f4a63ca9d31acf05346d8a8b461269255f89dee293586c7fc5155781333bf59678af4b1920a673aecd248539f6c54385d696424b8f97d4d4ee106af0991a9d9716a4ce19987ac3158cab210520a3fc8ca07673e299cdad05bb79d517877122dbb32224f8828dc1c07eb21797684c2f758631e73ea008553214a92b3530f72e8f8849f2f8f6f867464966a4ff8416ffed0622abadf9d70343dc6b2c709bfc62b4fb466e4ab78139ea598796e6e4d38e79fae836c33416b68ef50fe03137e0a2657de1ea690f5125e4a0f35f96b7dea534bb8e13dc8c16f07aa15530967d5633bda9794f03ab68fcba1949370726945cf1463dab428093f8c65f9bd031ff1c922e105f7b0963fbe20e1fd47e4d4563fc2e98e93da54d48e2b48331ce17534b39e7e723ca311be79d49683f530a964b88cf03b70e9e8e55e04d9a723781ca33314e18b847ccb895ae78c6724c2c951da76d0b1bb72cc20c2894f95b3d2d9f57bee105e0eeff5ca1355529a0ce107b7f12ab318f3854e219cba0b3174744f88b32c4dcb3be32ea55bac374d06f3c8caa4c283f03b44f1118bc8917546108e66fed01dc2a7e5c01208af62d68890feb2ab2a80f0eb62b68f273a3089fcc1f5c966b13d9ef8c1c9e01fa3f45dfab0923e38a5d1b3797ff0c18fd44335cdc27bfa7f0fde8f45cb79fcdbbf7d3df851a4bf27f67fc5c89107ef3d0e9d2b4bee8c4be3c1eb309447d25cdfc1ad30f93e779ebef1d90e07d9265b07e7435d75103ff2331ddc181ea6e093d2d46673703cba972441e33f2296831fc4b4f153afc9cddc3878722fe629f7a4dc3170f06efb93f4ff779027fa066f2d438ee4a7e330f36ef0ff7d6dc2e5c891c56df063dfc810739633d8e047464ab9af424ed98233d6e0686c984b31c786f7c0196a288b787cb2b5310dbe475f479d91ef230dd1e084b449a288f765ca9fc1cf72c93c58c80c8e7daa9ca9528644580667d663c911aadc543a32f89d345888cb6163f0358568c65c89c1f14054b335fb6c0e5918bcaeebacbee4e69a0383ebae5e31878acb53d517fc943c0a1d741879c1cdd453c9c3aa762fcb8c2e78ee1b62b5fa9f7a79580833b8e0c7305ff9349b2db82eb2c12635a5091e99a10537cc7868a5edde285f169ca9c98e3e87cb2fdb61e1b2aa78cd4e891a29ab37b96e91f20aae45becc71b48c153c559f8f3fa70b39e5ac0a4db47c4aa5c7cac7bbf95f7d67474a05cfd3d7490efb7328dd14bc34bbd9f00831a637430a9e7b581dbb07761f75a4e1408d1a4e9811052755858d51161dcf57a0e047592343d966b7cf3cc1bfd41922d3d638cc70829783ce1f623af72c95ecc0173498d104472c46df768f8a89640613fc38b630591fc7db12aa194bd02b2eb6eab2264e666653c7a8b4fe511382194af0725dfada0cd28c24f4b35951ca2f8404cf2ab8a85a08d6a8b10500dc30e308acc86c744ad6c59667a894657694a24db2314930c308cea44a9875190bb57946115ca9243ed9fb23bfed10c14f512de5b29bc71e3d660cc1b35c29b7577d9c334709c1cda1c3346bbad4586d10bc105d913768464bf00082ef71f420da27e9f3b366fca0ecb2aff77439f5d841d4af48ca9fc2337ce0c7fa383b6bf7356a7c61460ffc9aa88f1d59c87970171566f0c01b9f0fe5993eca5d31e2c18c1d3839fd85e4b4195386ac03bf2ea4106be55353c766e4c00f36513296c77bcc51b89881033f4d4ae49f1ce5067e2c19daba932c821936f02c4c6c6b8e8a149d530ba7430ef28dc84f0bacbcd2eba3a3dc453c347314a29d2db3f0e3e389d948933b458981116cc1820d5938dd414cb5a33f547446868d58381d33425c7f59f48e030bd7facffb7e62c45ce52b7cbbf2f90f993762785ce1755de8988ad8a874e903e3e10182c161c16824128642c1cd7e23006315080010541a0c45721c0792381c7e1480015d1e1428281c1010120e101210080a120a060806060008060606000006080685414276608e65301f113ffb4f02b53e38081a6d1e2e448eefe4e0fb5cc5a118bde5a418ef40a7a3ff30dfdc617d9b34ffd7f073d12f7e1bb37969b31c27467445e227f755a721f8aaf4ed82f77e9665f5bdba1d93731f72fa089045db88560ebb5199a4d834c95ed3e0c3d8e404d1a98cdaa2134f16942e68ba9fba41b2ba300222fd6a06b1c1ca6a896b6ccfdc63360f18c3951a5ac915597f4aedadcef6e00fc63a94a3a3b4606bbf1e2970253b672a21a18e88f40dbbad6a3435a3816bde8308bdcfcb169b680e54db13f5408b1acb24ca84317ee7365b9dbc93794b5579120d7a4ae5240048fbc521b26c423e8706e73d5f85f5ac1c5afa60d3a589fa8152aa14171dd0cfd013d14c91443aa1ce2f0943e1a836035a3a983c7980437517be3861a1f8f79b8c1b1f927fafd06f66e40a472275af5edc8473ad22bf37e0afda5492f7681368876d3003b81786e5f64530fec6c8e0351b39ae5ce166f2c92c2e4f8d4fd982f223b601fc623f544a3904486588ffa2f4609c33ecec7c0752a2af78c9e50cae72365db4ffd4d9d5f034c4951e28cf8a206bc3158b8034ff1d147bd080f7bb7c5215e1bf86aa9ef40ebca6dc46c27dcf35d31a2dfed9e13d1ce94590fa7dea84d510c01c78a5e7e03ea7262b79991f097b16d45de0bc047f6bf565f0d5bd5466c0150d689bd21e2d4b011cf4ce4d925ee8b33a8c9d29b4da52c74554706903e0f8fc281d6b396f1f8c7a4b0b1c7cfe80e15baf1acb1670945e9f36ab648e2ae2c6d954997c2cc80ddee4ee6cb41a4e12ede533a4097a029fa4a4ec773ec05976c55a48b8f09349043b5b4a28a671479ba5b3069e22dc94788a66345e7fb8cad240ac505a4a328a82ff007dccce8d4ab68283ef9412e3b125435a8180fa0a4a56afb162ed4be7443bd5c403962e29574c00cb41c01e849dbb75a9b68cf96f89d63dd92d6eed27aaeca953f48c9963ea2c04db3bbe3d7f183d25a25d32a480d55f84827834a980560455393d3e25adda443cc509046da84f6a044407c91208f7a3f80a52b9c0cca6f2890cdd31822bc35c105bcbce2f53bf4d765625b1393ed2d44b9268cd2bc06ea4e09b5bcd5bac084fed0034fb21abf6115ab06e62168ddbf0feb95e4f7a4ce9cde2074d78a9d21c6d57f7b5cafbd44dfc3f328e2e5b5ee76589391d0fd824bbd2c3b7d43c9e8a2ad048888d77a5745e48aa7f2d7e3a12101ba7a136ec898891e432fcdabccf66ea0f52ae4d4dcc70754345454b8a8052b684ffff4a5f26add98134ee9460064916abf75c718583de2c9ceb02e2b4e15afca12711fe70cba5fb1bc39e9e95e39764a8cbcc907b0dc5c5486c44c9ca42be1102f402ba5b95234f000fe40158a79905ffbc14f40d2525f74f40a85166555322f1f70d2f4c06fb2b339a1b2af326ab74f181a4ebcce5d6e6b32fb9051a7e9cc2341be933e18cdf05087ece950e94975163b55431635214680eb1e45e63900ed1901c956df73349cc845b2a216ab50ef40049e2a0fc6b9bb803e146d5aedb7e4fdc789983c9ed8817ce44849c0ca78be6c68b159b3b8a97609dc37edcd8158226241d48b004d8f039933a65a25fa0236cb4cd74d06c94966ecad561f4a198f8487c8518669a09c76cc6ab824819b89d942325ca44e8dd2f9795174188ccc62a4d2ea26b5656cf15d7b2eae7a0bca35a67ae7e83d26ef945f036f900b1030d8f107ec1700caa943234993983d18a22a49650d76d20897aecbc70e29c154e2578275b2af301cd9257af42bda9126b6a1b51d3cc92457abbf8a38e9985799d8b2d951ba41710f283d174e059d883163a0ba2b624bc6ed34d99ce504e31b2c173a342ffb6f102b49e09585ad229b0cb2bed38bff2f439d37a65995dbae0abbc1048961f62ee362f04b4d213c22eb7ac8b7342784be7ad77a30a41233bf7b46ecb290f83833f9bc307696ea4777580c982a941c4f715fc34589d90f834a4adbccef9fe469290344b86a7dbbea28281f0561a5fbca2408e420ea552337eac8227057a935e8a52d892e0334c9ce596c635652108f790a16cbd412e96f3a9631fa5b76cdcd1d096178a1bca5a55a454cef8f0f51949590312af52fd24695dab7da521e9811855046b01d728180095e577b1c659665fd3208243b8f42903c07959e8901640a990bb89bc9cf2b1b4b0a014182183ea944e1013da0aa376dedf002b4136c0533c1ba5ef98054da57ff75b7a8ba7f0905690241fbebabec72460bbe53b34434e4158a7a4c3bf7172ab95a54de9030704f411f2e3560e193d60d7a90b8a68fe143a8300f0acaa5600cb64c89291f98d8fee99156c19c26cb4a4c86c005c5b4c74286f9e05416ed8adc9b0443dabcd45031a54a44c719b5c5a3f1d93b47208fd96a81c9eeec29d02c5bfb7d31cc52c95b380ce2b6ba652f96cdbd52d64d609064a090f33b5bf85ac07c2019eaee010202013b6c352bb2ada2e5dbe4661697ff80a0678af24fda14cada154ad109d768a34502f1ba57b035dd4df1e3662e40725b987da53ee41685d6fde29cc4b342adc9b43efd6690cfa5860dedef1a4361a948e62504cde6d35ba2d5a49d758aa21ec1439e477e9424faf023dda2409af5aec88c2b99ef188836c7cc52ba3de648ab5b38515a91687abe5cbc924935d37f1407150cd2345a7b90f4f2e6af4e259950ee6a07676a7f2301b1c4df9ebf65ec7e7ad5133889599596d0595e355e213ea6e7bf67101aceae57912a7985c82d11e8475c5e4aac4c3f01d09cb25441a6adb32a478309590a6e8a47d3a1c16a3c61608f78e70e7b7dc2dc45af4983f1c94cccf2669dd08f98f5563319a15505053770e6f11298d706013bcf3c60e3c727feaf918fe988819a1a215ecaf25eecb1cfe29232477c21f97a611945678d33728766099f9a14ab62dd78cc888b346b0709f917598638607ca9305263612d850c308be4401402ec908f0454546af35427ec40a97580069739498b124c803d968a10f1b8a7afa46ab84ddeb2511df72a696ca1b55be0bd0ecd58ec06909711c7b5a46a28d5547ee7cf1daaffc286401a45201e09ad4cec8b8c0513b6d0f097de3e6358420431f80bba358630827fa5459c551b535731f80e59c2cde40c25e39b763f82009b4f293383d5ea81074fda72bbc32106e688a10450914041825764d7fe7f58f2e0081c24e56152e6e8e475250be06c6d984c32752011dbcc593b5fdffbfeeaf99c5022f40395dbe3bec2e11dc014c3c3a2311c13d063a2f0fbad1447b00f87c80490824da5260aa5c85ca450b745158e263cab2ce3196d4056012db99b102a3100c6a3f99e76a64bac0e628ae133b3aa59006bd2d43959391a90cdacc87ac62a02ee4288121dc11159330b63de8a333fc1d77968bb7faa4b0166a25258b4e4310767b7a0ae651928a396b91d6d7048fc6fc437a0ef7237ccd4d4e66b00dd59f29ab01b4c9373985b515a7d989d8d5c8afad9b9b72a3054e9f8e195ca45e01c234ecb5d4994779a860d15374497bdee5f84618095df991e2744ae8a492ae497b846f48d88e4b58ac7ab46dd8912832d97873e79925ef0151a2d5a415c4b0de7a664f6a342d0ee6b501e22044b6513ca105ee3ca45117bee4e33cb01d461e78ed9c4204f99127636cd27ad2995adfe6206925d63354a8ce1679490e0f7895f46a9384f28f8c4a9cea12b48b675492948cd1c96aa7a9bfd9cb71adf730b7d83b4d41c28781d44e55213cfca21db544ed4b01a96fa24c8bc80f16b34abd5dd1b6899832e75082d3261a560aef9aee4651f5a150498e30e4fa30acb318fe21e917892ff3621c4646ad88b2cfa491a410c4a19df7c6091657125e3f49297b7a29809c2f7812f1e64a04c27dc801b6248c043de9bd5094749de19cd6007d97af0837aa29414e5148890be1f44c0550d3c8259770c19462f8b426bc3daa66ec46d72955555e0daf4245bc289eb0c5213e4353d5014c141575761f954003e3d0381c8e60a9a3fbe47607feab92f4dc8c66a6edad89ef52645c7d3f5570a112f49ec6a26e92761f6242c5ff7634567ca4fc4754e64e5dc591501639fd3c03633e8a2c63ede1316ff31e4988257ef77ffbcdf7a1690f58f47c9c42d73bbde0e289a73074cea6149252022552b3fdb1f9229034ea5747a56744e6707b8d03ec9245596b9a45173a2e48c1e24a0e1c0a6c41201584a458099c7f64a85d894fd7c98d51e352810e725f2a163144a8d3750888740a5e9439186063ba8a88209cd34aa2f4e11e91e0eb79f4ddba3e334eb5128b6cc825536940f9114ab0de49509212767c01867d7b918bd325894adfa7fab8669db630a03f7f3ea91182dc083cee7c83b1e644a082ebb1ad0b8ce949f2a433e7986f08c20120b1651fdc53667b0d20fb9a07bd532eae5700d443a401ba89f34502ed9f5477b62a52c0c666ae6daa0a4c659fdca3d28aa184d1994b09d9ed5661c919d488dd708f5cb11803e6132da66803d121633adb0b90039cf3170e0b37e65862bfca93611503c61074734b1535dabe239326746a2902cd32a92a0ad1aa9dab303e5c74bb4b2713989cee1cdaca26c402c1c868eaa0249d7ad4af0d6795e3d3680d09b79dfae20410ca217cda3c1760ff686ac454c08548961c5996541617154f0b87333c72a254de1e097bb386516a314600e041c444a7699478e5b34b5385e3f226ae00461af8b234efbf4b22d1e89710095321397a22a98179e92936eb336ba64d1bd35f7f30d84d07f344595035b30978e9b6c9311cd1f7723ed5346591f1188be49540c62932a08be7228441999a9d7a9075efd56ce0034a8c000928ca8416f91dec4a7433f24562e75db5632be999334f2a6726b557845a773768d8c9b8495dcdd4e474c6913676198968f139478a3f7e4da5a1821e8d25c52de7dfb4358ab744c8e44ed8a2e70a3a749341c53b230937dfde8cade31f4db385b80239c1e65f29b74681c5d8f5e876f113aac87ddaeaf0da31c1ef83695c3253864d4d8329a37741aba91c3e8a664a83f0b7eaf34b87b879b1757469a62410d51059f44711276347a1c5a3c7c7678d2f3a75368ba8c0174a1f834c1dce04c7c4fb5455f438e008cc656046e1ce7ff5c44b86bb6ac6fb3438021ecfa34b8e70ae7718788987121100e52f5b6300cba7ae0f7e0aa7d9326479bd643658ffd181b0c1f01042f5029cdc15d051113fd001a253c10c78b3f10357907dc7407ce136c8ce71052a0370a826f2a24443da59a7a38c2807410f999029f05be30586edd3b7c76dcdb8cf23e5c88df94e1ef26c93f972c6cc04283f90b5cc8f3afe258b0f4f9c19d1791ae707eaf9df318fdbf526fa68cdb9756d9f0ff85c2b923ef549a5ec073d4ad22f2904404ec439f7fb5898e27ac347a2b0b1a1500eb7f6f5635118d18852ac24ebeb50868c9efa0ae0cc5d007a401778f2e11cc6877d98036bf02fec3dfaeb801338993300e53cdb670634730fc83c9e28b1e80f620745123475ea5a4252ff5d807aa8542fb0c6f03bdb04e8525d45e9e91a3ec93c55016a322d8a7f02e8aad2b2be3d708ddd5d779dd63b89385111d5d8367e74d0f44be72d9280c1cc985debc2eced4503d3f7878fcc9b1bd1904df9d9f7eea4bd11db68b4f84df69ec13e23c66896b206517b34ebb6a6faeb6aba287327fb50c167388ca8f4cbb17044f47e952efcd10cb1e9d56c017fc51dc959d88c5bd7fdaf374f10fc9dfa2b812aa11ff6a9280e32e91b4a558c522727a8faee1a7ed56d7f00d2debcbbd3d9f15524c4491ce740c818957da3f17700e6f4d2deb0a37628284503368c8ad4b4a753eae0a4d637eb130700519400d800ea3c0c686825aef012d8b8fd9c8ed0b896918621602d239a05e24b81cbf602b9d0fd0b50000d3c38c7af7b035c6b9d8b56f782f5957386eb766d713d478c5f23e3e2507444eb57a78817369d02eed898104002d7ab2bf811f05f0bf1ada8770030925b691310db3640f63a41718a91e4b5d5a811222daf022e668e0cf15b5f4c1f40f4a14d36c3c7a7cc897444652ea15844500d1bda8c6fdb8c9946f094d1a96906f6970711a21cd58598c5d391bbfa0da0d26207503a85844ef6c57bf8683cc2400b9cb0df71e41fcd2ee2263fe17adaa5ef808f106af4cbb2a01c25b09da9e166c64c1749a1a04edecb6ee4285d50607d1a546040e8f2671d9a63500dc6a8577bdae4e8dbb37371dd292589c2163477b47401eacbb169348e6f2f1d141bc0ca8d7d2aa6246e56a4949c6e45f2ea7a064eb745193fd209a9c2fa0f38a01437e719a862ad0dcf6e347ad359e0685f6c6f138a069fd5dcc685f5d50031d0f9607636e61910b61e9e17ddc846dcc89508ad55a9045e1b13b70a17097c4022216d2102e80c3c17b6772cdd19298762b73ebbade239b2146a8db532eaf6d378ff39acc89550a640a46bf1fc8d04f7105280a6858c3e9100aa50b2f32b205fda164ed2faa9613b8b34b6ac1f1fb26e684c67f17ab955bc686244bd6d2e4124e669db06470e9c2f1a9804ce35a3eb54d1b3137bad0f8cb6d1140f8c235c56955be911004ca25d810472a90df4b6d1d0cc026440b77f83d2da8f0a17e009b6286dfb5d3f32e22bbce92081572c018b5839740794c965b8586434577dd6b4ddb3b36c6a77ef30745dbad89608b3ffd70f06d442ec0da09164087dba36f038c2820d3e6088079a6821e09bbea05c14801a2e787160dd9db28b0e2414990c6affd7ad95ee64fda22f1e1c8d6134e2054b4a7956ac8d46f5bf2813e45ecba3690cc10991684333e92900dd4fc9aa2980a385e63174ff12f998cdb4b39dd3cd4a9aa56d61e93c5113eb3473ec4d9a4c3b55d865d770c1dc69a5b6a8810e91c955d32f3208a86098500cbeb1628c9a93aa33a9b4eb22af1f7e33e77822d73b0fc3059bf9ba5f0f0726fdc4f4b639dd30a748eb8ea9e93e55cc35969d6d4b6c70345c5d16588c8233799272522d2725a20f106f60950a3eac8fc60dacbbf0e0e270a38f44f1820697be78ff8630b20a7386fb94a5ea3c5d11a0cdb9b79a743bf6f7f7de689ce18a6eabc4cfdbc4062011cb263a198ad9f06dc8364a2997469db87f15c8814167893b3c7b649e7c27ec59825a18a57a6c71852b23968563e12e22de09ac620a5db2036cb0f2706a4b579c523cf402a5b41fba1bb72953e281c457604453293ea7001e1b9147763d2a8ec587c2563f7ffb65c8f217c7395b56d648a779bbd6170c0e9b99337bbecd9ac8a82ec1b880eb4b33a5ee01484550b3a2456a02715a5b77c2c3207c6c158a69c578a549a82c495e5aabd192f10566b7a9c85941d39c1c580a6883081eb744b320304d88213f5fe64b0012f0e665dd7d62d9be9c345334a2fa71305ce4e2964071a768b7506f17b670a94ece1ecdf2e17691168d6c3ac277e2347525738196b25356f602a42400e3682b33f497062515a4bf4fed6db51d3933d5f4643451866922918cb67fef684d5022948a3515f854ae1d8e0530e84e7f274041d60005b25faa0f7b9e6137c68ac301c8dd56771048f7a4ab331d60a333053a139c4e21eb48a94dbd80872461441c324a515d0e0fa6c52e5d70e7d7e1ff1bbf41ab3d5b778e0e8c355e323b6fcec0eef53063b366676e23a35971d3510999cd83d27721f01e6ad1bb7b26d37ab5f8826089200e8fbb587294f18deb220b75a1b437dc747e26912ec11934b95e1551ff8b22e060eac8c09ae15d0b4b6be9afc75dda0deaae5e190305338f758410ce49ad9b9b75787b61a42e5dc2cb6a147a351df04e35d38c992bf985dc1cb8e87808ad4e54012de7ba0d2a593f142807ca71dbd6c5706194d3be79c0c6c11e99a2190391dd1970c88e76ed7dba93a5913e8bee33e0b6b32af9ba6f62399a6649ab915e1d6381083dea087d142d8171496ca623808337a0e0ebde307554e19b96ec224d0e9fdbc74834bd0a4a5f8dd8d93582a7634660a9a11252200046da4066c5bd4298b9669ee185d029c790179a43fc08b2ee170beecb6d3f57b19ef4e9e14720867500f83ece013679e5bc5ed613b8cbbbc4d5c9664aa790984b227b2d8df330200f0cc0a16c167a0225d6e1c1bbf3623e19077a6fb8fd20941a0b9309196968477e8c9a12e6cdf7c8ab8498509b2e7baab63fa76c25c4a5cd06b5069e952157203c83654f51f5a2b2ad1a434ed5ba2842e875d78d06dc8f595d91cb28b81a0bdff4da939462c9e045f8e914be8d359d3eed869d42da1694bc64ca56acf6000486c8e844982ca2f8ef43139f6e93d76016772d40177d16d7c457651ae4ae45dd2cd16a30f8b8f2dbf30e942c9011d8a2ae5d2a2dcf237e24e84445b37dd8435f4eeca89af80e7f6c0386824180445586f6ec821d866ac93da463624e075f1772cec40b134eb44786f78a96fff28e09468c81594d4c71260676f3110589e879aa0731a888f3b14428a4d5422d63f4076c15a77c2862b420ab1fae43b6e5f0c2f831379bf3af7fe9748aac1842d262487139e3550d54e1801c63445ce6602a56b4998b828a0c49a5485a24d2fe624e86b88d66051cc1a01b960f1cbdbe3cfdb50290400132a07819de3ae92c500584fa09beff22efd3cc9f6d7db49e5516f0d70b15b4168441806c818284fa3b031d5c5251a70e21e28e4a6ab554bed883d617c2418cab0310a7e6aabe1ff60e9ef71c54cf7c51e99d4ebdd9b48744321d5d1bbaa2ed6e2f6de673a1d97bec65d8abc57b7a749727fb5fa28cdf46bc475dd2fcb79e907491f6b935b90eeae631bb3f9576722ca14b48b7be2ee3aeb1d7bed76e5e5ddd6fba1f5dde7441754de9fa55bacb8751de8913bab1ba82bb94d37b5e0c1d5cc7baf6d3ede5bc2a0b435a4e2bf2eeb0372daf015d36b5bbfc43963ac8d635dcade75d23bacbdf7895d9ab6e48dd1ababf5c776b650691c7e9c2d415ac4b52d74e177a5d64dd8abaca5d8d783dea8ab3dd42e87011d2eeddf4d6f476e9f5f0f2d405ed9aeaf5ddbde744cfe0f9583720d17dada1678d5974ebe93ed4fdd7fdd55d10bbaff990675408ede6f4727a7d7a817a35ebadfbeaafe2a66b9be1facc689bf8c930abca77684f8956c0b8e719c67893cbcf07acd96a53f5706355fe36225188880a23fa090a0983b42efd80622050158e645920a3a3e79efacc0535e24664cb277d86a2b1fef7660e7f141ad76eb950045eb3a80522ad1dc22b8ab5b73c6c58ac4cbf9b9b927bb5045957a867ff01ed2017181711feca5a8f8696be0879c9662ba0fd6f2b3215cbedb600ebce62638facd876494f9e84ed5107e8e6d857f580f4dda4797c5757f5cc8de220280f2e4dda454c90ad1cb649e5d9b0d7d09af97b2e89b99a867dbb64a904208b51fca950279fd0046d09cd38f5ee40d794bdca940b38025a5181532d6c071840baabd90215e000569667e851533f098d91226053424ecc8565812c46ba5997b570300abb2970f659d5a6d528fa2578736588e78d00ed9a2555573bf7ac19bae4736776cebb85ef1df6f67cccd87173c51671ffeb0b2a98163707103cb76c5f70a4a6f42e04897f5d591c2bfc5ede80097d1e43b30ee56f59ff5a4fcab15fdd6cd74f8927b0eea5398ef55fe7d3f44d6bd641fff3c20beecee4ec0903f129e187add46db60bbd1da525e3033eec967aabcf936b6c2e49fa8003dd1574f501219874cedb2632f573b05c430c4b21e2471ff5086a4e74c6934d3f9b8368e66a687fb288eca34891b8448e8e2cc1b5c8e438694800864e62d8bb3d1cdd1b9f2ee83b8a2798a4a75dae39b5d0fdb0f59b374aa7e72ff32137519b284623602b02a7755a09f82ee10b290d1be4ad3d814fa6db0ccc198eda902a1181439a20f48686f5f016d9334c4c375937569b7ffd5523c106436c2fd8c75bb943e57a0c54429001ab84a78230814c789c1732e94046e8c4c017a30399598114fa5581e2126808ea8e405601b80c6418e6bff97423c83457052f37c1effc7dacfedd74108147102fd5fa380bf3ed070668e82ba913204d78e6272d5ffab557d7347489406e20b7e00a411a0532ed422048bfc0af00a0b1a80be0815509bd41ba5ee0270aa55ec546810cbf0722e39a7fd5ffc005aea5af11c90288bc48f03209ebf526023c0f64b247505134a600e5d7a8e7194f18a3d485c363d1b58e491b807a3bfc3748fc143b25120b08c5999247fcef837a74fc149423b1c2485860e00632697ac8ab9eb3c1aa39f64b0b029001c102d902b6026481a4106432498381eb0f049169b06924441db2e7ec6b6ac12881c31a647cae7bb34108826c1f85c3707edc54d8f600ad48d08d505c0632f9a6f40035952023490215d22cd0eb60a01e373c18580c2ebb02610f4d0913f8410135124ab856bbd78c8f1a972a8155098d446776e00d44a7a92750511cb095f42fd205d9ab573352e50bd60dac46cdfbf659e1d2c7807d94fb0ef2360932c11d28838bc08f1235000187ab2ba806eaadba654f65ef868daa2029c195d1347b68a1c87aeaad0b028ab53b972f4074904207f003fc003fc00f20db0889adb5de499429c9f2a95e21e722534a29a59412c3d7751fce38df70a4d134079709030935092849abb65d984491a3fee424a6e2a73fd8564f1746d50dbd3b9fb4051d2acb8569cee2bca8a43f8ee75de8c00597d4c6926c49cadda2f0b4af6ab999afc3166693740853f7512dcc277ff20875afca26b409c0600436669420081f1011392cf01a20e03043072dba55adbba8662db216c654740a22f24255981db3308aee1953e2d9202965094420821a23344af0e8a4ea90c58c1a353c7410e2e181808e5898836753caf4336ad4400974c0c268723ed9548b5f613a59a7962b2a115718bba40e2f4abea9e9a81506b93f71fb16962459b3c268b296ebe8f419f1d32acc419930419892df249d9781d44e154e03e407346e38a02315954e6a54ad96f11e21353c6c9c19666a830e54e8f2d9a6b16919e3a5599f3f5e44ce969119a9e314a652f9920a6d4ba2b63264809c8083c314a610a679b2c80f35cbf9606b187494c220bedddc454cd0771529cc7ae55f41f4543d3474002272a330a6dc29b92d1fd5ea1685d94de9c99f243b140695a49473d4149d3a897fb0257a07288c2e6245895ad3232ffa602b9f30594a1f269dd88e12c4f484a99389df9315d64f8c3ed8d63a612eeba4dd7992d6a5241f6c8513a6b53bef52ea3927c71f6c3a3661ca3b2a558a73fdea8cd584c92efe255325ac8e124a5948d09109f3ff870902e19d0688475a0a3a30619244d733bdbea47b4c973069359ddb36276809e21f7458c224b99f08ed163b23229530a7493a8a50514c5aac3ed8da2861ba50a92f9ea75caaf5c1662be89884d154c7bc18714ad8820e49984e662f947685f3794522615272ca387d79623d27618384593fdd95595ee41e61d0caf124b784913dd20fb6e208636f9a6625a1a4dc973fd8ce4464d89801f27b35403c6c887434c29cbda2ab6ea92ff7920e4698edaea477d30f223b7e4de85884a9c4f1f867e1977c4c14613ad1392de82ceae78e44986cc484e9a65a07718208533a5954f81cb7435cf77176b9adab62a525cf8ea13f091ac27c27ae5fe5523a9e2d84693e9c924d90760721cc5616b4bd9f18b24feb1884c184ba98af5d259bccd621089312ba3a84b0a04018554b892245ff75923f40184b527be6268a8fdd3312aa20082724e4e81f0ab36929c7cd9c5bae5c8c396b3bfc6012dd52a85a1377f4c1e4256a46f498d09d8422aa821a78c4a0830f26f13e42cdc9792fe5eb83bb6f64c8888d8e3d98b34bc9b65e930439793d98af32cb3a85f3141ec22c74e421f5c935b4db1380c1086ac08083e30735424254d0810783ca89a73b18b6949ae06f723c39be7630db6a9f60a5e44fcb50471dd00c2b4bd72a97b36c2ce4f88f2a41caec4e07f3dde75d0e6929f44c47c4d1eb113ae6605e7d0df5bfe35e6b92834909ea5f64b8dd5f34fde360f44ee2cd3e880d07e3096af4fb83e90dc650928e39a69d6e2fd5e106d37d3c21f465bb0de64bef954ac5b4adc36c30fe8d09195f4b0d5f91d0b10663854b265a54e6684b01e149c0c10184ffe85083f9d6f32fc813e75d4f3ad2601a17bdcc4b9ec3554783712c8993cb44cb9a1b9dc1d42d26754bbcd196630683ca9757fff94cee313bca604a2f222da7920e3298540e65c9dc741a135f0d19cce81883297fe7fc8d0e3118467aa83269fd92d8274e4247180c3aad5ce5e9f99ca7c4c376091dde9c86cee9c4afbf600af1966eeef582f9c58210e7e9a4527717ae7ab313b7994dad98756fd17392439570c1a44dc53cb1e537efa28e2d984d7afb8fa6e374bdd81d5a30ed7d527ae6dd3fef25c4fd7cc8143ab280a990915dead21d583049a635cf4787c99620918e2b98326d2d3ea592d74e4ac60b38389a091d5630763895b3b37c324c4a47158c1754c5d7621d543029c9566684c7765653c714f28ef3ba9495d7935f171f1374523ba460cab1f4e7a81b2a5ce88882c953b0f6b8b5143aa060b279cf13f3781e9c196a19e8788271942499605234f931718269b404dd1e4c124ac95213cc3177fceeb3f466e799604e41899730af6309e6a09e942cda2525983a9cb8f87e9a76720a868e249884db074f7e695b4307124c723577e4ee925462551b388e619254924cad9cfc388c61b439658276ecb929f972068e6298b4f4092bb292fbe89318a6f333311fbd3bfe05710cc334b7a2ba392ac9deaa55814318a693175efc4d46048e60184c67c9057d9ae3b10103d31d3c484be62f4ce2e2d45ce9926f2ff4456ec9526d56854b8b7535f2b282f7961ca6ed854910f9568fa6b2534962c3c6c13b0e5e98cf3e872d41d8c6077b17297da5dd84fd521766f99225d989df0825cec59ae95ad1dbce62c75b5792df4f52427333345c98bce5c63ea5a758da988170057de6020e8e5b984ee85293db45877f12c400872d4c7262e1653f6ab8273fd86c80848c88c858ae85b18332d554911686cff6ea9372b8291316c72c4c26e7e027a87d979c9418b42cccd9a4a44b905ac99249e2e00003472c4c9296539694c8115a270fffdc12b4b980031606a54774897657c2c0f10a634813b30f0e5798cbedb35af34c5a61bbdaca96b6654b75cf3ccdeece25439f943870b0c23c6641fbd4662e5c3ee158857176f4a792649978b104324315264d0f4ad250f231482e70a4c2b4ed39c4ce84bac0810aa307cf3ed87c00e21882d2672f23b951c34b1a9ec224dc67c9ab25c94a6599c2ec1dbef2f7e875f1bc14c6b724e50b7d5143059b145bae2eabb4bb751d9e3da51c1e85d1475b4e59beb38e2a0a8385eb9653ff3842612e25fe277f89bb711d14a6ca72594cbcb44bd18280e313be8f4eda4c505d042e9880274c27b7569cf8160c383a61545d51d144ab50ed45e0820924270cfa4d7bd28fe979d2de84f16af446b343cb9e18248980b489c80019b9a109639d0927c73b7b763765c22cfb6796e34149e0c084a95285ef94175fc2f4a6cade74ee78be74b1c16109c3e79874262c8921c408a4122629dbaf99f820b231250c26464428256f1abf4dc2b4b26179b115d44d2a09d348936276e364ad9f6bc9038e48987a2c6c54ec29c9b40477c00109c359b0923fc1843c1765d4a891c8e07884415e520aa9e15102b6906f157038c224267928f996653fe97cb089fc071a39333c6680848c74c88848238c96529ef49dd6f296bc0c3818611e7195f7d361fa10bc8d20c0c0071c8b30474fea55d7ab83072545184b94a45b4f8e2311a68c7867a87aa8572f5372124ed7111019365ec08108639e24fa872d9d43986a4457f024491bc29c946423f3528927d7c85108e37bed5a901bba73bf1c84307a0c7593d5ef20cce339f24e0ce5f971148449a92027ad053d9167b22aa881c7e1088479d4847eccabd97ad00d191f62839b0310a6d8d9d3e7fc273d6a7d8c1c16e4c7c8b1914118b9e4f80356b1ec6a634cbd5bb37cac73107e69a2fe317258c0c1f13132c2c1a17e305f366972beae9bc5f203ac0a93f6492ac928413ebfa930bd68115969c162afa830d8a7480b699652509ec2a0e24f990a52f468690a83dcc53b154f5c44a530e5ae20eaba39290c361f74bcaaae52988cc21cd6a669aa4b4461f435dd925e234a6a4928cc967368adb1d4410a0a63c5d2f1e3efafcaf409835dda2755923c6192c4c4ce897fe9a64e182f48d1b024cf0983c79ccfeb1f59d9df84b9a468116abce25aaf09d3499fb9519e4c18f6b26e9c7c4225318409839e494ae91111a7722e61b293827a7ac5e7e558c2e4392a8ad2719ea25c09838a0aafcb2f254c6fb735df97c4f1741226f5f9fbbe939230a53f490811ad2261bedd5d4be13a90308993d352546d8ab6ce23cc335b7ada29b47a92234caf7b4932370b96fd469894f849a8934c18614e25c9b13bd48a5ece224c175774db3d5bd88b220c625e45ceec449872927e6f225dc562441877f4ca2cff9e68da4318845736c9f7358441e4986c117ee9e52c84494a55c1e5469f1426218c6d3909ba94386f826c10a67c26eaa912cca365451026d94356c6c711e656098439fb870061b6bffe2cffa46256fe80074f1955dd0fe6fa792b15b7b5d3ee83c92e8e0e9bd712223e984e3a0be1fe274c76f760d029087562c57ac57a305f8b1e1d6b1ecc2e7ad4f9a5783099ec15bff6bb8339c7495a449576305556f2ce72296bb93a183fc95972796c74481042c8f3cf5acfc1f84969a8d5fa3442d57230c9a8feea8dd697521ccc696d9f544576551c0e462f9d4bd408bdc130ef234225533d4ae406937dbc29b96b0f0fb5c17019fa3f8657149d840d2651c7732baf3598048f3e7b6aab4e76d4605092da2739c53b7785d3609273eace1f677f5e643498a4554ad94f9413d9f1198c9fcc44d39db1190ca7f38c302fd9affc32984ed465a98eb7e1276430783c75d24236bb4dc6603a7949145d256230e5d35af154faf76c87c1204b67f3e3c67ad082c15c2697d2299a4c4ba25f30765730c94b5e30ca999e57f4e4ffc92e18ed635fb7ecc5ff920b66bf4ae2762ab7600e7d1d4a27cfa99d168ca2738e995fa7f27559308a2ad9e7795b2c9884efe027bbed15cc2ba78458e8c5d69315cc41df8ba59baa6052ded9d3b253d03351c19caaa37988eea8ea4fc1d427e90bbd242779232918ece4caae2ec9841645c1dc37faf7f6de2a28818271ee5a4d499a6ae9f20483bafaebce75ae753bc19c3c44aa5eba09a6607f1f3d9f5bd033138c6a32c593bb4b30d78f4a09a61b694a2979b424985c2d0927f2c63d8a86048392d23e8eeef079bd631877cf4ae82842c6620ca3afa969db8a613e41cd7897f061b4a6c43088948f32ae0dc36c5eda73ca63e8662a0c734e1f2b6997eb9e4a83612a532a0973a6835e1230cc298791a7f3bf308d6c8c7a2f6194ecfb829d7dcffff47b613ae195f37249d0d6f3c218ab5aa12e8db9eabb30fdffeb29f9dd924e7461d86ded24654f2ecc23f37bdbcbc4380f2e4c2a9e3b4e7dd2fa975b18fc527c7f4ecac2a5d8c264e94185c9762d4c6a61f2c930a13e575a18d552f6f924ad5baeb33096bc54a7722a0b9370e287fd598a99672c8cff7ad2c68dde37818559c5da4d5d2e5f613893f2f44f922b18b968af1ea65698479aa5ed9c7e84fbac3097a68a7dc719b39c5518ce7e2df4e4ad68a20a93a47167b25352618e514f4a33541843c9d36bda97baa44f915222fc047db229cc39a6e9f025a514e6901e3474b2f029aea4305f92426d864661364918dd1f11da9e8ac2dca33b4ee8bc1439148651da4de78a7cba101486731925cf7d8a957cc22016432825c7d013a68bdbc104a5c24e184fce29e72f53c1c7424e98e3bd5cbabf8739a54d98d5e4fd88993ea9e49a30c82bdd75c29e09839fbd27956f553909268c71a5f774782e618a919febbea48f53b184397e99c99dfaab84f9bfe4fcaf4b09f39e64e296ba9c525027618e3f5acdd3f98f1825615215524f4c353bc945c298f2a9c4c95d694d3b481854904f9d5a2b9cccee1126d5f93d7ad6aaef758e30e82c3541da9b6c5e5d234cf9f49274ae7e57d531c2e426a7ff1599351b5a84b9b2945cea278a307c8ad7e9de245549893056aa4ef52375748a0883c9a57b74c58a501ec2a0a4943f076d6782aa18c29c93bd5ab6ba10a6de17b724ec57384b7ff1c38330d7985c2e72bfab654198f2a4104a4e6a5a9403613e91f1e649de2f95058429f8772595a42f53d23f982d4992a0e412f4c48ffac1bcf9bb21d45c929df6c124d42939db9412cc523e184f8af638a54a1247b907a3a9f423dea2be45d3f460ce4fb597d3cc83d96d47b6bec9fb56e2c16079754dafab787f7607934ecfad346d3da9991d0c3bea92f4252c8a685607835a4bb24952d492974407c3bb9fa0533acdc1242e49a1bfe29efe921ccc9adb41e9949224d57130557b9f54c2c16469fed2c28434417f83e164f9fc2eba1bcc7e552a4ec5d0d1416d30578d8e2174101b8c57733d622d073fd11a8c9f4b2853f293ba6851832997905d49fec84a953498b37db455caa2c19c4cea6798588207f70c86ef4a65a7543318e4fa49eb6b49977019cce9aa372cc5899592c1fcd94c6754f2b4dc8dc1a0c45f0c79366bb75589c1247f0c154d8979f5255961307dca5652f894625fcad7402f984281c1b836d23a97dcbf605dc6bbbd785ac8c5eaf86c51f289ac4982ffc1565e30499d8332fb924baeb5aa0be6926925593e8f6122545c48aaa7aff821ac2d187dc6e74eb9a985bdb2775da6c6abd7ebc5d3f569a9da56160c2346794ef9ce55410d3c6a5058306a48efe05a5fc154826acddeee18ff90154c67294ec6e560150cead57639c2945052904851c114dac376baf2d3693b3505c35eae79de393fd8a4600e1b65926c4af688b61f6c782021231905c3b5883a412e37c6836c302828982bcd9224c90a5a6e4e912718f54a3a4ff2f555e96bd47082b93dc6a68d58dca86e06d504c3253968cb6ef557ca144131c19cf27a4b92a4be874e9ba09690a4c52a2c2518c3ed7c734dbe888e6f25c1dce7a6e494d57bb70b09c66cebb174c24d10fa3e3b86495909fd1e5c94bc26c518265982bef0dd9e2d86717b33440cd3a9ecbadb6d7ec8304cc2e30459329e1fc46cc230ca49f15db9aea4124f1f6c3ed0609843094af283add3c88d326098e4fb13c424fffc5c930fb682444066e42f8ca162414bd6764b612e41872f4c62e1b405ab245b762fcc76268a67bf796198bdb45f8613afe3a81ecf56124901e2217d1684ec5bd73ed8fcef5806780793a4bc4a76bcdbb8bc201a37928709d00ee6b0aff77bb2223550d7c1b0196332342f1b403a982dcc7f4e594bbe2e3938076349fa4e89e19e1fb3837230d7971c95837e1de360f0a482d041ac2465c3c124a527a9f49c341584928d1a6f307792f44dc5995cd51c037483418f29a57298c90949aa65886d305b3ca9233f55de6ba0e7410d1fd0280107870818816c30aa992c39467e7efa6b0d66d39ef4a8c5a806b34793b55cb2c8fe5b300d064fdafddf4af2d1602a9db486e797eeec9c3318deabeae7e33efea56630088f23f65bff83924f1a60194cdadc73d6de3edd514206939ce3def3d7640ca69cf3c8d28ffd95223198fc3b89bde25fa353270c0659420a06a3b598b0a1bfc42f98dd84aa28fb9f7126e805c3c45ec3c552b06daf14b4546fb6dc74494bd205f3dcbbe9d91dd11d6711b151c3a3900b66ad68d5237fadde1d8d238305885b3076f05379f1839ed3e1c7a1164c999697fb3e6300b39055d66856cc5bbaac7026a79cdf4b59c482c9d34e094ab89c2b18be6409bae72dade2bf080216a040042e98809a26d00a7cb977785d6d886c85d1258daead94c42a2c77a544f9091da9603cf9ea94ec789eaf94e0140c4add892daae45c4b270d11d0484f402998c410b95ee27a2b58ea83cd460d8f432460140c3aacadb3cefbc14603a1602aebf58a71293f07133ec1d8714d977f3d22726494ed009d60fc142cdef67e12bd0f0ac22698ca2413cd32edb4ad432f036482410997bd8ff9f62f7a1f888c849c11912598367dafa42474b76cab1aa804a3f89f244c8c8b93ea43a3c68c1935108660124cea5795df7f1dd038211e6a238804e3a86579f224aaaeab814064bc40051c1cf908448688d9cb4812101a770c63a95c6277d06fd501a146e2c103746424e5658c243744560535f0a8c0196359ed12844a7e128262182fdd9e891a9d2742ec32561084238651de2c98ba4f0dc33c6362c9134bc7eca84e1826614de5557ad4b5985f304c96f2626aa2c5c1c1c131850386490e7d27c99b17edabe417c6fc53dbf9a2993b8dbb3ab116eff255d3f13b7e9e9ccdbb5e1876adde4b12345e183cfdbbdededc85712d49e275094a5d1894d29f4d10a57d827a2f1706d5d034b58f7f4a3e8b0b732c3ff1e27b720b83e7ac7897bee6399dd8c2942eeff5d80515cb502d38d178f9acbaa07a5bb93c7a4f0be3e7f50adb4fa5fe4274b859983edb28397d9770b230f889a6ae73f0b8658a85d1cf47ffc84fbb9d5f5898ce4407b7bbec15461bebca15a6f30da9a2f7d30ac42e2cca8ce5504b277a95b4b2fbb7362b0cb282ca13254fee746815d65636bb9b4ba3f19d756fe1ec842c13cfa20a838c097f429c1c97479c0ae3792a49e7d36e264e438559dcae4b924c7a8a4259123f5318ecb7cc47c7afc4b74b61ce65ee152f67cb49795214b5bb3aee2bd7a76dad658892b398d5a33075da553979432913af1385295dd8863eb19d47edd9830b85c153570afaea2bea754440e1ba5b8a5a49ad4f982fe9bf699fd21f4dda13065b3dbd2b4149272849d7097357b8a09fa4ead239bf5e384e18d46bc7b84ba10f3619c7ecdce881b94d98d2b7a5aa9cdb7388f35d5034613aadfde741492f13c6aaffa417ec04214a4988e1e038210f72983098a5d56c0f51f273b62f61f4b10f4afea44a091a42219c258c9f4227259c9c4feeb815e12a61f8b060a9c3dc892fdaad0a6ae06183a384a9848659c951547616651c25dc24cc2f4ac57512164a9c931cc249c26c52c5933f6ab288ae46b848942b5cca974ebcc141c2a04baf07a5fd5dcdef7b8441eb99de7aadf4f88f239284d59ff8a88db811e5fa12b9ee107b7b59cd3ce11a77a58212de3946982ddde52aed27d494d8224c9e54f80a72564ded451179892faac43bf3126152feaf972daf890afa21c2f425871357f62fa9b97708c355db7fceb69e214cdb77ba5784acfcd10049f60a61ec38d144b124e57ac9470873e6b789bf3519fbfe06612e3be526990ef5d3f69f208c26331fd5e402618e3ab25f8210f5b59d0e0e10a9a552b1512bfb0aed4e69f13c07d3ae87bc0e745043c62d10ee0f6ec8b9bff6d12b91c1f9c1fce147e4ca8c2cf1751f148bb714626e25df16d54a506a3c4e759658f1f8603c133de588aab894f3116e0fa63ad94ecb98d827057170e8800648c88888c78dd343fa29492d0b7342270f57b2bf92d5925f94c6e121edb157d24299279d34031b77874cc35a5ebbb3dae325b19e46bff4ea23221e36446670eee0ec603ab7ec7152086509ae0ee6ea4f82b613db5309277430aa7b8e65793ee751627330b7c94a9e2773474c2707f3f625f18adac5c1249ed2d5c1c1e849e9e93149c91b4c49861026ba17dd3de706838652fa96a349137f5d1bcef8545bb939ab4b66d244ad6851d7e4d860165929cec7d21a8c76764950693f4689abc1a4be453c76c54e17940663ef2549c9374283a99327c9c4efcae549ce603a25bdc74fd946891e3318e647c7d22e6530ec08919e7193c1d41a97b28dc1fc39aec991264a3ea518ccd7e361e6bc8292c63018cdb4fcdb6779972e81c1204dbb2f1844ebe44ef67bc1b027ac855c3bbfbb0b26a5d484e90b71c11cd482103b275b309d64668210134f44470b06b9962a3c56b260d0f9d35b5d8d05a3e737256cc65730fa5bba7072ba24955ac124447a6ead4fd258f2ab60ec92fa79a194b426f6543048b91735da340583b070c19485f2517a2918f6635ce7fb5130eaa8d86f224ab47728983ba885dc18f917fd09269d24bd52b932490e39c1e8490aed67254d304965951e6b4cae799860104ab4a52429f7a02f4b30a7a6aaf6f77c4a3089b85df83709a696d71a1d91f2be1e124c49990996963c865174cc536951725bd08d61b494214edbb675febc18c613f6c4b3b29c180635af1794cacfdaf961182f9a7af219cf345d18c633f5f3e8a76098ff656c642bc030a8feeb906f3a55aafcc214dae49c4bb6a074dabe30a8d0e14e16a1f2a8b917c68bd6a2836b658d14f1c2a4ca42dd785dca268a7661146149ed6249b2a514e9c26c99a7848b622ecce19df359958f38e1c2b4fde14d56ad3a93bb85592dd693203d4e3c6d618e596257b9a96ecd502d4cf5be7ae2b9cc2749b4302729c5ca836cd7d02c4ce13c78ee139dbd735998449ed83f268a85295b49f23142b030456dcf35695ea94a5e6110aad54a1631492eed0a63bf9eacdeba15464be993480baf92c40a838725f511b29d6f5e85b184d01f5a7c76b316d8ba80d905eeea22f0a103101a17280e5e0ea34001021084e402fe22228f6a84d858000046446eb8800001781d9c1b3aa0716420400022218f6e788d101b09880100020000000040000b00000000a080f71a342e20d2ef35683480012b0262e32c20008900808848c24100019c91e31c0508c019395e2384e300001800041210f21e0c0040001e708020d8e005828cf800c477812023323e448e87470252173666a05c24af3123152071615cf53c13363d086dd25b00e1cc4804485b1c206b812023211f22323c3c1290b430c5afe8a973bdb3307d2749127a61f2a7bd6561aa3e0b2ab7eccd95508d19337e06cff8199bb1c8aa64f9bb1cb38166fc8c9df1335013168906c88c54807c050d90198900e90a933039efe53fce2e5e6346fa1839337203d90a0419f11a336e7878242059617259339959b26398f083fbecc69987bf1040641c10f436448a8dd00041111a202332406e241e212dc8558cbcc88c9f61805485d798910890a94840383352011215083222e3c60c0f0f04e4294c996b623fc8c714e67eef20634adaf81db314064f5be2fdb32895a693a41885716c8ac2943a7b10f2f4e85bf364288c9e2dc8bbd7b7fe17144611622354e446e315e4274cd2579f9f245e8ff484493095bf53fc2a41cb101b40f84e9892bc8e4f52d65f7a13274cbda6b43de8b44f3a64426ec2e8a62b3c090fa6e2b7d4c4952aa558a92e7d651bcd36794866c258f964dc73ce0942942270c1041213e664b2c7eedb4a55335ec264f52727597c63d52a6909e3765ae94f59a98451fdc4932ecdfd9f7a29611c4fd13357ee244c954f98d60f3296ed9384e1d35c0a3e62dedeb48c44f2f5ae2297d6522be4b28dd07ba71adad9848439bfcfc4550ba33dc224687a16154a6bfae97070a4238c955f6ed1ac64bb20fe60f3b05163cf04d908f3a8df761125c60873caa8ee9ce453d7cf2fc2f4ab57823a71f74b5a146192f784caa23d904c8449ae54ce9ba1eb732d8c08539e7ac9a3a64b16cfa143983aa7e792f25677bc3b6908e30533adabb2562a540883ca1bdba5122184f94bdb9b0e2ad7c120cc7f5549befdb5fc1c09c270f2e93022fe48e3200361d6bea43b7a98db5c8e0e006170cb5b51a2a585ca655243860e3c465ea4d81f8c6392e82728a52ecc637e309ca04a92f298c925057d1fccf94f2a4916bdd926a7201f4c3a66265f540e22eb0f6a84e8600fe6dd3693c3789204bbfd834d0fa62ccb97041f59e447b4069907a3c55392924eec9c04b58c0fc183c984efb2587ba972971b7807b358e9854e2e27fd441a20891d4c1e4caf6ea7e8880f505a1d4c9220ed9467e9d7ce061d0c7736d25b3cb6ce723f0793a404d9498e92fb602b72304949dd79cebb566a486226838c8371b6f333c7a46839367e4424657088c68d942a483898f20815d3c193f20daaa8979c87a757fecfbd56da04991d0e0e37184bca33f7bf62b6e19465477f967daacc68241b4cd963625e0304366c9c909155410d3c6e906b3065c4c2dd67cc254ba5de56f24dd492d4e239483598d693f89877d134985d3cefa9ac9dd4c8190da60c75722c693c4b797f06c37a9c1394ecde0cc63329995c921cce949c530673573ce9697d2383612ffcd8889534f623442e30432167390663f52561f721db90111b2906d3e7effc24491eb530988338c94b54f23269a604832673c962ddad5adec5ed5a56944eda7112e4174c3254099e37cdf482c13bb848f5f4c92e98db243769bba28dff13a8a0061e2e482e98542c754bc7452fc73fd86cac6dc1a467ba3d94ec95fd93c8d91101c1d4827188c0059d055350c2633cde050ba6a454a509f369547f2eaf60b090a3f27cc765f52aad6036314ae6b3831ac82a982ca6c71331f53962ccc54052a1b94aa55ea72d6259ede5144ca17aefe24af61c264f2998af3ca5d352b28a783ca360ce3115fcb2bb75be100aa69caff760a97c82c9478967f1b2934e30951244454d5213d7441f6c2320890648c88708da07b209869393eeb3133da88f950e24138ceb2979c96df15c82179eabe7243d359e0f360fa3412ac1e8a59f6295ee83d13c904930894b7fba6e3a5b094a9e4622c1bc2545ff1e773fd8f818a61b517aa55f9d52461f6c42e8c17b84241e232033decc18e6fb64d9d1c35a9f30fee0699462a0426c8ab4301a0f6880bc203d80c43056ffc9e1243fdb123e1f6cc330d8a7cf262bba73e3000ac3a43fa4cbfb97efbafec1e6f13e001939323ea42e18d6ac59b433710fb54ad1732895a4e4e2df0829d6c030f8a8784e2a5b481715d1b8210210fcc2e47174cae7259ed2657c726478388d2f6f230830f819274404692f03847d61d269eb63ae27a47fb017869357c4ecaeafa8517961be8ba6d2a9b57117a6feb292e2093a8a757461182594b01667920bd3769f24fb4fb034b9425c187c2feba756d589ad6ec1c69bab5a0adfa51dd75ef25e50137eb0d53822201c1c323e3928e0e07819203666d4401c1c2c40c1a22d0ce22bf7c2dce42446570bc3d5c591abf849848ed1c29cfec4ec5de66fba6916e6184b4a897f0e29a69785399824a8fc21be047142b1306a7ce509164d4ed21f58184c5578b4e4c19368e32b4c9dd4ce6d4cec0a53692dc93636bcdeeeda56186dacc489134dada88f082b4c925ab14f4ae9e0a75d5c853989e96c71848926070668daa80a9368e6a2ae63d2dabfa9309992b257befc537e212acc16a746cfe675d78d33c0536061561d6fb39d366aa77da0298cfd5be779f6a4507e82a530b577f04b625ddf4ea79014e620c65198c3a5d47759944461300bf5ef24e93db92ca130697a0963a269e75853c9fdb48f50e169003ff103f44410b013e911a7656aefe43349c809c3b48285db8ba5ec953a4775f1e0260cdb167af5834c13c6ad784947e4a5f5e83013869d5382dcd88c983086502a7e5749f2323b9730ffecd58e7f32a5e7ab21a3aca025ccf296e3f2f9c70e0faa0496bf4af5c196dc10c112e880064872e3053b05a484d1eca4a9f211da4eca380993b0f8d1c46e64953c3ed0c899718792304d89956a374c3ed8426c00e13d641c1f7c62244c76af5fb515e4724148ce1ed1382322344a900609b369114ff3a21f7e1f3e42b170e9dd6d2e887a59c54fb2ffef9ca90374844168d7b21cd637c274c19364d7297950254698e452be2df33f96b4651186932d5b8a3028d3237af47789308baa8b735751829039228c95e4bcfc5582fcf2d0210cbab492fca8723f416c08a3aa0725cb4e8cebfd0a6174cfa1795a374218439ab60f2dd5208ecfda56595171d30ad71022ae65dcca4f4198468bd82dd11d1716d141c8f1b00b84c1646a494a673f893c68dc08f1a8e108085332d1d3abb5ac05ff60fc2d495e4ada154ae68a7e30e9132e9fe8174fa50941807d30f6de9d9ede356444d33c66dca071c807f3788f2511d332a2f4b80783b0b21cc6b41bf22325b002eac1246fa851f2a8fc1425f6c126e2a1c6031a373e46540598878951a8642c858342d27030168c44025130105236cb0100e312080020601c8ac502c2509ecab9aa071400037044263e3c242220180705428138200a06c3602028100604018140301004851e12b5466aec6dd202d642c7d1043a3303790457422b52b1483765c50ec603e390758149ef1a47ccd51a256ad7a2e30d23725ebd5c390a40dda5cabbb9717f88fa83d8b896bc0928eac4fa97dd102efab30dfb58fa3bded1b9d10e8546d76a118e1c7db2e8731f9f7d1d4d1ccaa4110e4e65f18d10bd829455e32ffae1b30f91a700bc1ca8a529d8343d6a8c7151890a723baa76852b405a0c5136421b3b0652fa88f6dfc192d60c7b43bffdebbab681df7f89f73aea123ce3b6576a6073f0fc6250e4f2cb84ccc00f8aced3ac643766987c360ba84482a1b0f5c1aa89f0bf35e10272e09a962168652212740c44ce96238fbd12658eda8941beef21a08cd2a481450f73a0818bc4417dd0255067cf95fa01007124cea80f88831e7652235a0a50afb1d7e731cf341e044ae71b71316280a05e5c349e3fa2d75c7f7a3f2d8db63885800b15fbad77d2f0671046049a64c10145aa098011d16299e65000abd35f9542496231ea457845d2a067cad9e46a030ccbbbb8ed374887fe5c083bd8fc8e6cc4ebccc5cb17862b9da243a72582a8118a599d8b36ba711a87d89898b4002a655995ca2be404f2a23bdf430e88093b2a0690be06977f38b56e30d0fab96c7ea6cc82c62cff16440f2171544c2d025c61f1925ad00fb72917faa9302493f43b14ee2a6f4e310a7bbcef9458daa0e7863a7c43752e0fe720907224f53870c716e0a3225ffb68efb1cd035717e80f26283493f19f6d3b39b8414abe59f047bc24ef9d6d088edc2de906c7843cdd04319a535bfd982e4459fd26ca2b9b1228e28e41497eeedbaf08a387f5a87a5e51bfa44cb2b9465972c196215d675b0f2e6260dcd11756f37f755e2c86b95d9a01d8102b782d16da29d22b8ae7b4e6f8883ad1f322e26fa57c80bcae8b747476d411b7adac62c233c2619ed943a4b876ea232ad1861471462392ef62494bf68e048d312d54568079b57794281c91f827e3c0a18f157c5b0e1c65d24a58a827e17c1a5378c930ffd84f3238cd837c11b905fcd88eb61f864b6079f339f45faddd987b29f6f8072eaaec4800ddb11689b7ecd78fb5204973113050a121e0fac233b40a106490989d6fff2515f0da8486682c5b705cf471df6279ec4965f206ca8896e32b9c34d589a659f18aa264672d106e0e19b5d3b1c66f6390c4519a8cd6d17f805b2f8677b6a7a8bb647356f9bf3effacac6914789ef01a39d5d775d634ec2c8921437e56501c775ea6f98e4ef902b0adf5ee88f9aa49c5f7010e6b16e6efebe134896b0c5d3c43afdfc09ae7f0588987216b055276cabb102522c103b7badfc9c42befd4e2deef1f42548e55c7de9985927e5a47be46ce1ddece4bd331a29b5a9d035deab7216ddc26c9261fe9920ea204740d41889a950cc5561d63b0070a4f8848e66172d69fb4f4a9ef5ad9a29ac9fb3ac05e14932e6ecae241ff586980da5d5d4a733f2f2a57d089ef538953137aa0883dbbd042f48f1de869728dcb57129f478199153eb1a7fd9760b4d585c6c808a537107d605516310bec2e7388d483190439d129e099ad6b04d5548a42ce1982aba0223972b107efb78e2568732db94ee9bee544b10f31adb6b1f9d8867460ac1bb5c450e40a5985c0c316ff80aa34138a361bfb291b466255a3210c72f296335e37c5073a314e7775f146eaf05ee224dc4393f28a7e8ca114448643bc0083899467574d3303e26854d5aa238a4786530804fb26961674882cf1a3f164063260b83eaa32e434b781cfd15f4a93c3bf8358b63dee87d00e9828574a92a5d539b45c37f24bd7a8c5d683da32b2f45e6859b6bca23221cb529d871ad042bda4cadf28ea4ba5bf07521e0cb0089868bbac1be6d46010ff54b331c81164211d7baa4711a898b9b49a27257f7e4017886c659e9aa19e4f9bc9bdda25c66d0fecde1dd224c7b9eab77faf1fc35dddf7aac41fb3b8102a30b9442c76cb10dd6b614bf1e3e692041d902e9b4e035a1d82665a484b778bd1bbebfb73897f9e8e0f23423eacc2d750314760364849fc49bfe1496c7f5671daec006a8f4b8305a75c00b937b20c78b4a94605cb0ae9324c8529847636b603f7ad512d5e02c681621a52f767082127b737acebb3b5b11fd93d8039027f1a47afda0ee071645304ce4bd77e458ee384159e6b5b587efef9df2066adc1e2932155486c8ab88e3a39f5616307c6ecaa44b573ebc61c2081d89d8428e997d17d016ef43d30b788b71182ab1e471588c1cced97288a4640029a6f51a74a070490db2c59403c751c0aafbe6102aa00dc361b6bdec27aee50f94a7be8695ece5ec5dcb98a80a8e18d4dd63c68bfd2bc9e14d42ff2ceefa39cef1e11084f0f1a99495a9d4c9f412748abb5e2fd1e0f45c9bd0608118b0a4460278b3723903530dd94d965419d70ee3a751e3e04a9e15008f8e51223fd921cd8a55f2ca5702231a0f64920d6b8679e79eb2c9ae29045d1bb37d4905abbafa59cbd9c5b197790ba6fce4a497be58a6a2f7a1cf12591b29226dfb22d392429adb9abc66b59f03ee64fd6d081af2197e63f971f24841804c03b129090293e14dc23bdf2f50bcd29f3e25e29e31f0b9ea46ef955319c7d788e140e97cca1ad466a0785adee2a000653f7b5b09b13463c8368dcefebbb4e761c2941bf36b6dc215e57731fd5c6633297dd722db240eacc4c98632c89e6a23d3e925db23fa3c0d4b176cd1cbc307bd7b22f6081302011e1eed53f45c63cd3d845e220701a9600d2670f78b802e9fc65c602827741b57fa7653382338de1e8f7d485d20a0bcc46f2472c9fa2bebf602c1e04ccc41210268a32699e42e3b906e50bcfba8837ca9235d17958ce868c2615f02ef8e811ae58cd7ddb196f550b521519713a543e5f8a62024e558258d37082aa6938d7e701d01b83d938945a8c84b4d1cd167b00ba7dd9edfe07c50e653f2844167133d42fd970dfacb889930514cc0581bc948ef89fcf0bd66b7968021791b468518ab65870c72a1ba2ce420d3bb897c5a55d275278d0fa7f67e638e742e83e872b2302b4b5f7bbe0a70d290cac1ac56c52d24fe589f3e1d3afcb49127ddae7004546bff062c62ca2dd8885450a3219cfd50fd84e4da6fe0fac56bcf6f9c6bcf64278b465a209adfed5c614a057ededcb7bff2c0088965aa85afcfc4d04273366da26af227c9971d84092bebdbffd14a074121d1ba617910216d1bf8edb6371c10b601340450413381867dc080cc733a50fffefebfafb7f80b51b00fdb7cdd170e0f13237e0679bac452723101dc83234b5bb1196f5165dc2aabc208994c186295fbf700b7d18e255965977a86f0eef1a2fca416265cdc114473f318f992231e0982fc26a1f35c3f8f7f5a43736b3dbddb3d1056673b6da7f83a3b609a38a86d8abb86a566bdda4413ffadaa1d6551aa6a0317812f3fc1c7769a3b8417da10e8a08cad44af99a7a8b45329702d65d234dc41b0d419d5e12c5abbb88b95e9f8161b439610ea18a474f62c40284c81380bcdf8c038a89ae78c34098f036c5047fa69d3dd1b878c53dfe695b5f8864d32d390a5d7ac2f38cb4d087e5984056ea6afcfa9ee0234576a10a784af94d92fdc6f56543da896a18e9d798f36a8506ea22f48f3eb5c22052a76de41527395f18b92e0b41ce1e4f41026061715a73fd0ec0eed3ffc31e1fc66525340bae443a40628a57f349ed51beda8ae2359c5f76249fe3f9f8429858fa18208315a9a298333d2380014232466f68e3d545191ccb7ab62e2a2984d5bc7ea28cf47c366a6218b6e0a8f67ec25ed86fb8b580b2cc49d5d9fa7647a0ad14fdb25e430260a5c28218c6e48745e3c70a16aacb1e4f074503a254cceb27b9cc0fe3cc191a1c72d1771522c51ec0a18d9cd7b6d9991028474346be9c31ccc2cf988bd23c0ee7c4cc1f4f6ab499061df36abf8824cd42b292014f9be97db9a9331eeef10ee40cc8561cfcbe8e4d364cf0cd954ff8d7ef613bb4be68fc195bc2ef2477dc962cc25551bb74b22d0477100727b0964eb70bbc1ac0baae647db86ddc9b4ab7cc4d0e12f150e764f73ab808b767bf438e3a5d42f9fa298dc7abaa9639303301689d189b64235f0eb415965d1ab3d466d6c6d1b07d4baf6075793f83dc77e41e28cfb80885827f8a506d32265c5918d036c3b23798a08f4b8268671e8435a73d7d9b09eaf040dba1459bb5d3375286baa334784e1864f848bcaeaca8607d2d18571c48938125c65eb8dfec2fd33904df9d443641eea5c250f71caddca2882c2824851a965b2751e525cef9efdddc11c54158d7dcf74f83f29fd681d17852d9d57f3948befa84fbec052cfb8109234973ca65d8d9e6bcef4f9854e5803b3aba0f2e8abad37568cc5464bde14ca3c5e76839ae278c151449cf0bb104080756b907292fe9ca1f72a631ad64e02e3066e31aa73d1b795b1c0ac4939a7314e94416dad496d5fb159fe49f9a1e5eb428c573b8aa35b47385f21441503d741872fd1730b2cbe066093f3d511c0dbe264f381361cb6f93e62da6e55c6445320de65a10040c8cfba98f908752c813f049a27450466a0517d21ce714b064cff6992cb05c330ad441f9b7862a904439ac5ecbc22b8e72375c6fe8d7c955391cdb338bff23904a681f7176fc53f05aaa07bf301b23ee5bbae34a9354369c25aafb7a39a7767509f09f5a364eb3ef5918d91ec179b9b594392f67a8fa435de527bc133ad6b489b2cc523252e7101ef287191f1f1b9854e4d2b16034c533418f616e6c3a96d426c1e246a90e70b8edb2bcd8e6e21fba0dbf250ba4d465dc788d6b750c00cbfba7e2477bf29fc19015786a729b9e3058c35d4a87b0236f7c74341f05766b4a6c51b7f990ce6736332bb7fa53b9e2882e5ee4ed3cdd0379cc9711b47fb751849d1f75f8bc1b060da4c1fadce78177c2f5c4daa6ff1c6d23eb9d9aa9b6e71369f96e243fb31702478756c77a7bebb81d6d48d478dcc6f9b44f43f9b8f29626f7d994b2fbfdb7c55d4f231dda56dcb0a04bfae52a949e6222815543d7c8a555e8241b5bb7173f9dadb2bf16c6d359273bda357b1ad603dc39140a0c02de290e0ab967f7d379854037bb712fee010c1b6e6b09d8e791fa9f9cb3bc5e60486070ab8986d4b3c480dde0e139601c63c3db6e80381975661f74cf32d8af7b38a2c15aa16710675ffa66547743fedadcdad5306fd14dd7813f249c0ecd44af802d327629e3f81be6b1e6010e004cf56a4faf4880a5e88267aa3a6143b4023ba0ed8f2d6bae6b3be370c09e5b89816926aa207db24e6c87cc073a506722c5a2d12d164a4fc0b025df68d9a52341d4142cf498c1505cbd386eea446a0dc7d8882e70b3adaac404fb45050d1eafc23d4576b21188fec0d7a55ccfc5c0b11104abb3bef167a6e10db4168d7bcd61d62c2df5106c33f57ce2cd51f9c26a0010e084986ec05be05b01c67d8e24fa75201be42b8ad29d07e5531891819b74cb2e78aa619632a0569c3b08210530dca661705a0b594a0f7b21cf172b7ae737aa68d87521b74265216d15274714d8592723b617e08ac5b7080ff010818583fa4619a6327d301130e484633028ec95fdb9c1e4906da575af185d373bdb36a85b4544b350418102531123f04398b8476dea4aa34d8c916dc5766f20dc60760d6fa2cd0aa41b9241ce69291ae44cb7ff4c2570c5b68a30001c1dd0fa442f211b1033453a6a1d3dde5b2298cc981ef9156de0659c54ab5fe378236de6c201e347b168210166de6508e669563220711a4702d104c0553efbb62bed3c724155ee6b7833365d579124d058ef11269c5f0f9eeee6ee19ed91bd1bd456d8ee55ef52f6673fc3bdc53f5d15d61e617c144c35d3752333791a4327592d30f0bb0da70f402e6e2790a3fbf842fdaf8da4b15611049a6b1f4a10f5446041f13edc03c0ffdb413a5ffde64d99e149fd68d044bc15b2c549f6ca4ebb5a80e1a4f9123eee4d989aaf079c113557af7f72a2af066bb5f58bb64e75792814005e2040221f6560e26ba7f67e8f86d98916a0442bc6a16464423454616b05976c11325b58510740ab5b4e222030173489cd49ebc29db438166d9a4dc29c8dd41a9c909833e22a67e56fdd3ea909ec3134f92edd68f6fa546e32e9803d93be02884671a1bea34854efde78ec6ecbc2487b5e2e6e48ab7731f0463cebb7bb9f6705b7651e911ab10027e22a19c9dfa324bf79f58f9550a965bda60f8fa030a6b25d7066f22df78ab82c01273d5ef08059ac93da83b522fc007601385e234f9207022f1bf4d96ca922b3d0fbf056b0aa5917e05a89962c79944fa505135c0339cb9c0a628096b65abb3fe79304a144fb142a8e0eddbbd63220c0f5420e1245927826e4124f7c2df0c75c9d6bc512680fb4bb91bdb0ef343ca5ff242152ab8f9c9d92af3b9913036e290d36d60ed53254d15ab979b5a2069914a0bc11fae5477c133419a3f144dd01704a3e7394026ec52d8f0dac21633949149988a4313cf04aa59ab45a70e03cbd269034fa25297cd3f4cf0185e94cf02cf8def2d91642c560bb061377f9ac56471eb2e908e0717acf103b1987701ba470dcba4c3147be0a26cc1915c99eefc75186ff1252abec10e15a52c67179ec0a4ba586ea31b0642303260191e6e2d1d19deda9d37e4cacde5ca9526068caaf02b6233613aa1d21b1473d9ce2e5d95ce5fae69681356248550d7eb45ce136b8028cbe1df541cad7953c25b197ed3adf32d3f9dd3442552f7767fc5c25f445c1a7ea7461007a2e3c30d76123307ac379982cd193ec6cb1d2a109ec509f0588a1b70a4fb0def95285a750f55987fd7460a90a46fc30c4dce33ff4b000f0e63bb1298c4681830dcdaf23c8a67db30e028f07db816a5ea9606b94f235838a5aed97c9fd322b9d37e887aa7596c4d79b6c5ef6715f28c44bbc4abfa191fed1d3e4527f0e0ca7865daba8858234f57140e3cb1e754f5c78370c587dff4c6e5d8f2418142ab553573f18979b05f95c489377cfa275a50118d20c6a33bcb519bb26b5e2c495b9a3a6749b6b4f921db042f860729ba77af44107b6a1d676c4a7c99b86565d489f1b302186761f4bbb386773373ad5839b53dc23655a6bb4d20cdce7d4dd7c0ab8e90211b3cc0cf6a2308ebfc83fc0c1e834d6dde20581862b576c5179b4ecb5f6a04a3f784bb73543a44b59408ebdc6a1ac8031710cf5c31171493c14ac4c3f9abb283cadb04a5adafc9bedd363e5fbeba67692caa69abe260c0d791cfa6d37e1055381dec62006db84d9f47421ef5e7268e5f2a85b3cded468531775db7d6c33763add8c7f2b89682527c30070e44b4d54102b476757c037d26d21613222918291bd762089bfe886d8172676723bd8c176f67a69663d59d06d2ca0babc54bcabf570a740b848f8987c959eed4a236bbc73ab7ca7138cd3962e80565749aff806cebe8bb2168c44b8d2d3c1c2c7fe26078956a5e887925ec48289f394a19ad789321abd6205972db2e6144671c9ad757a31db7fd97091db7e875762db7c01b601e4862242eea8ba4d980107701b795616499789361055ea7da88d4b1ff4c0455740b9cb2290e2d6c69268f7596bd5889b86f0b92823b0e43c4955236ef6f26c6dcd4adb9917de652216aa62b551a55af86dab96f4263fed1278db316990c2ffc914b2fe6f424254cfde29d37699582021d6708ff2ab76f21ed6a39b13054b6b3fa60e9ed2b681b050dd4b0af3efaa0ec45a912e549b4b682d289b1df507464d66ff2ba8f2e45e9d3bb6ec63c10fbd82dd9a6e49c945233587e82da87eaaee4490390263344fa1660982dc1959f12574ffde37845983cca07922fc0f75319ab217e664ebdc79b194e02ac958ab816519587e1acca4fecb0bd963aba110cc0a754e3b1413448113ce9cc9dec2b2c9880ab7fb3fc4098a8d445926786c6669651713894f8ba69b0698d636d372b785030a76773c2ba0a11dadacb9cc33f18f76e9134898c88705e007f12d45c3f696de4481a13c4486fcd568b47437371ceaeb5c3bbb211b4f9aaef4c1e3a0f96683ef45aec90f51bf23e2dc2dfb9ed2d2cb7fb80c7520b9dca4032174de30e58bc7f9d9eaf40e869664e87d170c6953c16d12b4758d79324d47c9c34f97aad2aae7eb61c798f9af34c2b96625e0536c5b0931fdceedec387b929fb164a0d5715f16f3d2de3bdd5f7d282223f65dc46e093632d9e08cedb10ed5d3554c263aecdea0540a43a5d83c29314bad4497d3e7f1c1edde729ec51d853d29c15977801fd36064ec15ac8fbbd59c7114f4dde54835c9ecedef3255a250cbbbbcc45151c92a692a04141c321052343bd200faea101ee8c72d9e605146904c45061c7a3acf1d34627048a871c6deba7dd1a8e9801162eb2b0540608481cb0e7bee262d2b89f93e462ce078802405eb63f2695d4edc9d3cd5c02a22b6c7bd95d37407b29e2a113da40679f1304aaa5ca92aec08acdc985f77f232a0b0f9de32c0fed3bb13b859e65913248b6bc2b71c186f5ac48375fd05bf7f45ceece8ca65b4ce327e75264d1d12486b1b6e709726058d8a0068a1107ac1e01a1b6cba60b1ca0054543059e9b5da1ba58686329ec3245355cf99e2d04e27d07f2446e8fab54a0ee41cd453004aae1b66c5d69e7a2a8a9f87dd546f7321d027a2c7aa358d0405fec0eb110622567ce455278607f05c1b032c04f3f1220deb220e2fd5f5552769bcde517a988ce1354fc0425935c8d220ea3c853bef1109994bebc66f2c26c29614bd832f0d890382d35814224e0c173d2e83b37cc3d8c8779e6a272c324ff5297d09e2f234b3f3c256219690a43d4c2d585a94460249e5c0c09d9448e457cdd9921bcef82f63ff8c0c8ca4b410345011c01f28db20a6d39865840299fa90757222b5f0da0331ec443241d43b115a342ef2a6c5c3395ee0b243d2bb52c3b9a82fda19439d382d48894b31eb3a24fa1cd85f42983a9c3dc992a52230a8d91e0e4badd33f5fe7471d01ba4b7ae89b7ee66e220b4288403e51640a34a984a3367834bb2ac8db6bce2341b144808087bf0cc3de51b9b0abb71f75d34f1b124c4a6b5b1c95897b20d828842804c2141cda623d4a2ca134e219d7dfd0f2754e25900a3dd8a30f1fdc87e27f58958cd7af7d8446a7fb3d96ade5e1bcb3f015de47e3d24db8508579347befe9324125afada274e2981d0358d5248a18122e124b615985a6c0eaeb99689270c2626c2868649c5ba7f6f17a0c7438e648f89d0cc57e7463b43a9262f489b0e650b9fa04306300b20632a90e1b6f4e3d69b3a4417cead386a6ad8bac776f04447afe5c4d6868fdaa95000ad5e1ba60af4460e710147baf586fb7a8816adfc98bd6d43932cd16b56e1d04d9d5d8bb032f57e89cca12d3cbf259ce0a8b4e00f8341494a94aeae4915a8f8bf7a202a3ca1291fc211451a6326810a12e25b1e4f9b2b41b44eac41bb016ac6c0d8c19cb8558052632c3892187a008f60b18d9471c356e8082187c6c16af703249cb6ada558ae264398b686694036bfd2e64d93506574dfac010bda8652fa7792b4a1032fa3b77e7db3e9a9a9d665b50ec1491e483b6b93959870cfb8b9a3e2c5d724ab616f69b970a425ac3aba6fe3677558506eae0262bc934d8a1ebde696c56230e5b55ba283e9c44c117a9e745f38e26cf98c39a435e1254db2813ed291394a19e866139934a3623652fc44808d60891689b3d2a35be87ad5ebd891bdf0c03d1bdf495c5604e5461b57736aa4b802a43d9b406ca00adcd9f337f13b8c64a7e58700aece3d08afe38918b9e9bacbcc02e67a94d16abba965ec0c53090747b6e93864c03897375fbb6ed9cce93bf84511dbab07a8cbd75abfdcadd7b0e099b19bf371dfd0a", - "0x3a65787472696e7369635f696e646578": "0x00000000", - "0x3a6772616e6470615f617574686f726974696573": "0x010888dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee0100000000000000d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690100000000000000", - "0x3db7a24cfdc9de785974746c14a99df94e7b9012096b41c4eb3aaf947f6ea429": "0x0300", - "0x3f1467a096bcd71a5b6a0c8155e20810308ce9615de0775a82f8a94dc3d285a1": "0x01", - "0x3f1467a096bcd71a5b6a0c8155e208103f2edf3bdf381debe331ab7446addfdc": "0x000064a7b3b6e00d0000000000000000", - "0x3f1467a096bcd71a5b6a0c8155e208104e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x426e15054d267946093858132eb537f105fe52c2045750c3c492ccdcf62e2b9c": "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d", - "0x426e15054d267946093858132eb537f14e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x426e15054d267946093858132eb537f195999521c6c89cd80b677e53ce20f98c": "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d", - "0x426e15054d267946093858132eb537f1a47a9ff5cd5bf4d848a80a0b1a947dc3": "0x00000000000000000000000000000000", - "0x426e15054d267946093858132eb537f1ba7fb8745735dc3be2a2c61a72c39e78": "0x181cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc208eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a4890b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27de659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e", - "0x426e15054d267946093858132eb537f1d0b4a3f7631f0c0e761898fe198211de": "0xe7030000", - "0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429": "0x0900", - "0x4a83351006488ef6369cb758091f878c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x4ff3897794d496d78686afcfe760a1144e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x5c0d1176a568c1f92944340dbfed9e9c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x5c0d1176a568c1f92944340dbfed9e9c530ebca703c85910e7164cb7d1c9e47b": "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d", - "0x5e8a19e3cd1b7c148b33880c479c02814e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x5f27b51b5ec208ee9cb25b55d8728243308ce9615de0775a82f8a94dc3d285a1": "0x01", - "0x5f27b51b5ec208ee9cb25b55d87282434e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x5f3e4907f716ac89b6347d15ececedca0b6a45321efae92aea15e0740ec7afe7": "0x00000000", - "0x5f3e4907f716ac89b6347d15ececedca138e71612491192d68deab7e6f563fe1": "0x02000000", - "0x5f3e4907f716ac89b6347d15ececedca28dccb559b95c40168a1b2696581b5a7": "0x00000000000000000000000000000000", - "0x5f3e4907f716ac89b6347d15ececedca308ce9615de0775a82f8a94dc3d285a1": "0x06", - "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe700e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", - "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe70e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d", - "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc44f9aea1afa791265fae359272badc1cf8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e13000064a7b3b6e00d13000064a7b3b6e00d0000", - "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc4de1e86a9a8c739864cf3cc5ec2bea59fd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f13000064a7b3b6e00d13000064a7b3b6e00d0000", - "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a000000000e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x13d4fe63a7b3b6e00d13d4fe63a7b3b6e00d00", - "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a00000000e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x13d4fe63a7b3b6e00d13d4fe63a7b3b6e00d00", - "0x5f3e4907f716ac89b6347d15ececedca487df464e44a534ba6b0cbb32407b587": "0x0000000000", - "0x5f3e4907f716ac89b6347d15ececedca4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x5f3e4907f716ac89b6347d15ececedca5579297f4dfb9609e7e4c2ebab9ce40a": "0x00", - "0x5f3e4907f716ac89b6347d15ececedca666fdcbb473985b3ac933d13f4acff8d": "0x00000000000000000000000000000000", - "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a000000000e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x0000", - "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a00000000e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x0000", - "0x5f3e4907f716ac89b6347d15ececedca6ddc7809c6da9bb6093ee22e0fda4ba8": "0x02000000", - "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e169030e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x0000", - "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e16903e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x0000", - "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a000000000e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x13d4fe63a7b3b6e00d13d4fe63a7b3b6e00d00", - "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a00000000e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x13d4fe63a7b3b6e00d13d4fe63a7b3b6e00d00", - "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade980e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x00", - "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade98e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x00", - "0x5f3e4907f716ac89b6347d15ececedcaa141c4fe67c2d11f4a10c6aca7a79a04b4def25cfda6ef3a00000000": "0xa8fdc74e676dc11b0000000000000000", - "0x5f3e4907f716ac89b6347d15ececedcaad811cd65a470ddc5f1d628ff0550982b4def25cfda6ef3a00000000": "0x00000000", - "0x5f3e4907f716ac89b6347d15ececedcab49a2738eeb30896aacb8b3fb46471bd": "0x02000000", - "0x5f3e4907f716ac89b6347d15ececedcac0d39ff577af2cc6b67ac3641fa9c4e7": "0x01000000", - "0x5f3e4907f716ac89b6347d15ececedcac29a0310e1bb45d20cace77ccb62c97d": "0x00e1f505", - "0x5f3e4907f716ac89b6347d15ececedcaea07de2b8f010516dca3f7ef52f7ac5a": "0x040000000000000000", - "0x5f3e4907f716ac89b6347d15ececedcaed441ceb81326c56263efbb60c95c2e4": "0x00000000000000000000000000000000", - "0x5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3": "0x00", - "0x5f9cc45b7a00c5899361e1c6099678dc4e7b9012096b41c4eb3aaf947f6ea429": "0x0400", - "0x5f9cc45b7a00c5899361e1c6099678dc8a2d09463effcc78a22d75b9cb87dffc": "0x0000000000000000", - "0x5f9cc45b7a00c5899361e1c6099678dcd47cb8f5328af743ddfb361e7180e7fcbb1bdbcacd6ac9340000000000000000": "0x00000000", - "0x6441fb391296410bd2f14381bb7494334e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x6786c4cec8d628b6598d7a70ace7acd44e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x682a59d51ab9e48a8c8cc418ff9708d24e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x6c63e84bfc5a0d62149aaab70897685c4ba24bcd9ac206424105f255ae95a355": "0xb104000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x6c63e84bfc5a0d62149aaab70897685c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x7474449cca95dc5d0c00e71735a6d17d4e7b9012096b41c4eb3aaf947f6ea429": "0x0100", - "0x74dd702da46f77d7acf77f5a48d4af7d4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x74dd702da46f77d7acf77f5a48d4af7d62556a85fcb7c61b2c6c750924846b150e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e01be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f00b304f91831830500622780fd38770500", - "0x74dd702da46f77d7acf77f5a48d4af7d62556a85fcb7c61b2c6c750924846b15e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f0001fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860eb304f91831830500622780fd38770500", - "0x74dd702da46f77d7acf77f5a48d4af7d7a6dc62e324093ba1331bf49fdb2f24a": "0x02000000", - "0x74dd702da46f77d7acf77f5a48d4af7de5c03730c8f59f00941607850b6633d81fad1867486365c5b304f91831830500": "0x01be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f01fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", - "0x7a6d38deaa01cb6e76ee69889f1696272be9a4e88368a2188d2b9100a9f3cd43": "0x00407a10f35a00000000000000000000", - "0x7a6d38deaa01cb6e76ee69889f16962730256ea2c545a3e5e3744665ffb2ed28": "0x00020000", - "0x7a6d38deaa01cb6e76ee69889f1696273f0d64e1907361c689834a9c1cb0fbe0": "0x20000000", - "0x7a6d38deaa01cb6e76ee69889f16962749d67997de33812a1cc37310f765b82e": "0x0080c6a47e8d03000000000000000000", - "0x7a6d38deaa01cb6e76ee69889f1696274e7b9012096b41c4eb3aaf947f6ea429": "0x0300", - "0x7a6d38deaa01cb6e76ee69889f169627ba93302f3b868c50785e6ade45c6a1d8": "0x10000000", - "0x7cda3cfa86b349fdafce4979b197118f4e7b9012096b41c4eb3aaf947f6ea429": "0x0400", - "0x7cda3cfa86b349fdafce4979b197118f71cd3068e6118bfb392b798317f63a8910c174c55fd2c633e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e": "0x04e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e000064a7b3b6e00d000000000000000000000000000000000000000000000000", - "0x7cda3cfa86b349fdafce4979b197118f71cd3068e6118bfb392b798317f63a893e73123ebcdee9161cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c": "0x041cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c000064a7b3b6e00d000000000000000000000000000000000000000000000000", - "0x7cda3cfa86b349fdafce4979b197118f71cd3068e6118bfb392b798317f63a894f58b588ac077bd5306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20": "0x04306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20000064a7b3b6e00d000000000000000000000000000000000000000000000000", - "0x7cda3cfa86b349fdafce4979b197118f71cd3068e6118bfb392b798317f63a89518366b5b1bc7c99d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0x04d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d000064a7b3b6e00d000000000000000000000000000000000000000000000000", - "0x7cda3cfa86b349fdafce4979b197118f71cd3068e6118bfb392b798317f63a89a647e755c30521d38eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0x048eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48000064a7b3b6e00d000000000000000000000000000000000000000000000000", - "0x7cda3cfa86b349fdafce4979b197118f71cd3068e6118bfb392b798317f63a89dd4e3f25f5378a6d90b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22": "0x0490b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22000064a7b3b6e00d000000000000000000000000000000000000000000000000", - "0x7cda3cfa86b349fdafce4979b197118fba7fb8745735dc3be2a2c61a72c39e78": "0x181cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c000064a7b3b6e00d000000000000000000000000000000000000000000000000306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20000064a7b3b6e00d0000000000000000000000000000000000000000000000008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48000064a7b3b6e00d00000000000000000000000000000000000000000000000090b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22000064a7b3b6e00d000000000000000000000000000000000000000000000000d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d000064a7b3b6e00d000000000000000000000000000000000000000000000000e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e000064a7b3b6e00d000000000000000000000000000000000000000000000000", - "0x89d139e01a5eb2256f222e5fc5dbe6b34e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x913b40454eb582a66ab74c86f6137db94e7b9012096b41c4eb3aaf947f6ea429": "0x0400", - "0xa0eb495036d368196a2b6c51d9d788814e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xa2ce73642c549ae79c14f0a671cf45f94e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xa37f719efab16103103a0c8c2c784ce14e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xa42f90c8b47838c3a5332d85ee9aa5c34e7b9012096b41c4eb3aaf947f6ea429": "0x0100", - "0xa8c65209d47ee80f56b0011e8fd91f504e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xaebd463ed9925c488c112434d61debc04e7b9012096b41c4eb3aaf947f6ea429": "0x0400", - "0xaebd463ed9925c488c112434d61debc0ba7fb8745735dc3be2a2c61a72c39e78": "0x18d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a4890b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c", - "0xbd2a529379475088d3e29a918cd478724e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc632a5935f6edc617ae178fef9eb1e211fbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x047374616b696e6720000064a7b3b6e00d000000000000000002", - "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc66f2e33376834a63c86a195bcf685aebbfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x047374616b696e6720000064a7b3b6e00d000000000000000002", - "0xc2261276cc9d1f8598ea4b6a74b15c2f308ce9615de0775a82f8a94dc3d285a1": "0x01", - "0xc2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x0040fa7f398074858a02000000000000", - "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb30e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0xd17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae698eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a488eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a488eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", - "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb3e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eed43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d", - "0xcec5070d609dd3497f72bde07fc96ba04e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19500e3a507571a62417696d6f6e808eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19505905fe216cc5924c6772616e80d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae69": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195066b8d48da86b869b6261626580d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509d4a4cfe1c2ef0b961756469808eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950c9b0c13125732d276175646980d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950d62c40514b41f31962616265808eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950ed43a85541921049696d6f6e80d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950f5537bdb2a1f626b6772616e8088dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f", - "0xcec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903": "0x08be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25ffe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", - "0xcec5070d609dd3497f72bde07fc96ba0e0cdd062e6eaf24295ad4ccfc41d4609": "0x08be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eed43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860ed17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae698eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a488eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a488eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", - "0xd57bce545fb382c34570e5dfbf338f5e4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xd5c41b52a371aa36c9254ce34324f2a54e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xd5e1a2fa16732ce6906189438c0a82c64e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xd8f314b7f4e6b095f0f8ee4656a448254e7b9012096b41c4eb3aaf947f6ea429": "0x0100", - "0xed25f63942de25ac5253ba64b5eb64d14e7b9012096b41c4eb3aaf947f6ea429": "0x0400", - "0xed25f63942de25ac5253ba64b5eb64d1ba7fb8745735dc3be2a2c61a72c39e78": "0x18d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a4890b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c", - "0xede8e4fdc3c8b556f0ce2f77fc2575e34e7b9012096b41c4eb3aaf947f6ea429": "0x0100", - "0xedfb05b766f199ce00df85317e33050e4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xf0c365c3cf59d671eb72da0e7a4113c44e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xf2794c22e353e9a839f12faab03a911b4e7b9012096b41c4eb3aaf947f6ea429": "0x0100", - "0xf2794c22e353e9a839f12faab03a911b7f17cdfbfa73331856cca0acddd7842e": "0x00000000", - "0xf2794c22e353e9a839f12faab03a911bbdcb0c5143a8617ed38ae3810dd45bc6": "0x00000000", - "0xf2794c22e353e9a839f12faab03a911be2f6cb0456905c189bcb0458f9440f13": "0x00000000", - "0xf5a4963e4efb097983d7a693b0c1ee454e7b9012096b41c4eb3aaf947f6ea429": "0x0100", - "0xfbc9f53700f75f681f234e70fb7241eb4e7b9012096b41c4eb3aaf947f6ea429": "0x0000" - }, - "childrenDefault": {} - } - } -} \ No newline at end of file diff --git a/substrate/zombienet/0002-validators-warp-sync/chain-spec.json b/substrate/zombienet/0002-validators-warp-sync/chain-spec.json new file mode 120000 index 00000000000..a7964c0cf14 --- /dev/null +++ b/substrate/zombienet/0002-validators-warp-sync/chain-spec.json @@ -0,0 +1 @@ +../0001-basic-warp-sync/chain-spec.json \ No newline at end of file diff --git a/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.toml b/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.toml index 12951575f4a..e388af7c94f 100644 --- a/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.toml +++ b/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.toml @@ -5,7 +5,7 @@ enable_tracing = false default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" default_command = "substrate" -chain = "gen-db" +chain = "local" chain_spec_path = "chain-spec.json" [[relaychain.nodes]] @@ -18,18 +18,18 @@ chain_spec_path = "chain-spec.json" validator = true args = ["--sync warp"] - #we need at least 3 nodes for warp sync + # we need at least 3 nodes for warp sync [[relaychain.nodes]] name = "charlie" validator = false - db_snapshot="https://storage.googleapis.com/zombienet-db-snaps/substrate/0001-basic-warp-sync/chains-a233bbacff650aac6bcb56b4e4ef7db7dc143cfb.tgz" + db_snapshot="{{DB_SNAPSHOT}}" [[relaychain.nodes]] name = "dave" validator = false - db_snapshot="https://storage.googleapis.com/zombienet-db-snaps/substrate/0001-basic-warp-sync/chains-a233bbacff650aac6bcb56b4e4ef7db7dc143cfb.tgz" + db_snapshot="{{DB_SNAPSHOT}}" [[relaychain.nodes]] name = "eve" validator = false - db_snapshot="https://storage.googleapis.com/zombienet-db-snaps/substrate/0001-basic-warp-sync/chains-a233bbacff650aac6bcb56b4e4ef7db7dc143cfb.tgz" + db_snapshot="{{DB_SNAPSHOT}}" diff --git a/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.zndsl b/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.zndsl index 05c458fbf4b..3977eb6788a 100644 --- a/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.zndsl +++ b/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.zndsl @@ -14,24 +14,23 @@ charlie: reports peers count is at least 4 within 60 seconds dave: reports peers count is at least 4 within 60 seconds eve: reports peers count is at least 4 within 60 seconds -# db snapshot has 12133 blocks -charlie: reports block height is at least 12133 within 60 seconds -dave: reports block height is at least 12133 within 60 seconds -eve: reports block height is at least 12133 within 60 seconds +# db snapshot has {{DB_BLOCK_HEIGHT}} blocks +charlie: reports block height is at least {{DB_BLOCK_HEIGHT}} within 60 seconds +dave: reports block height is at least {{DB_BLOCK_HEIGHT}} within 60 seconds +eve: reports block height is at least {{DB_BLOCK_HEIGHT}} within 60 seconds alice: log line matches "Warp sync is complete" within 60 seconds bob: log line matches "Warp sync is complete" within 60 seconds -# workaround for: https://github.com/paritytech/zombienet/issues/580 -alice: count of log lines containing "Block history download is complete" is 1 within 60 seconds -bob: count of log lines containing "Block history download is complete" is 1 within 60 seconds +alice: log line matches "Block history download is complete" within 120 seconds +bob: log line matches "Block history download is complete" within 120 seconds -alice: reports block height is at least 12133 within 10 seconds -bob: reports block height is at least 12133 within 10 seconds +alice: reports block height is at least {{DB_BLOCK_HEIGHT}} within 10 seconds +bob: reports block height is at least {{DB_BLOCK_HEIGHT}} within 10 seconds alice: count of log lines containing "error" is 0 within 10 seconds bob: count of log lines containing "verification failed" is 0 within 10 seconds -# new block were built -alice: reports block height is at least 12136 within 90 seconds -bob: reports block height is at least 12136 within 90 seconds +# new blocks were built +alice: reports block height is greater than {{DB_BLOCK_HEIGHT}} within 90 seconds +bob: reports block height is greater than {{DB_BLOCK_HEIGHT}} within 90 seconds diff --git a/substrate/zombienet/0003-block-building-warp-sync/chain-spec.json b/substrate/zombienet/0003-block-building-warp-sync/chain-spec.json deleted file mode 100644 index 8c09e7c7b03..00000000000 --- a/substrate/zombienet/0003-block-building-warp-sync/chain-spec.json +++ /dev/null @@ -1,192 +0,0 @@ -{ - "name": "Local Testnet", - "id": "local_testnet", - "chainType": "Local", - "bootNodes": [ - "/ip4/127.0.0.1/tcp/30333/p2p/12D3KooWFvMbTsNZ8peGS8dbnRvNDBspstupzwYC9NVwbzGCLtDt" - ], - "telemetryEndpoints": null, - "protocolId": null, - "properties": null, - "forkBlocks": null, - "badBlocks": null, - "lightSyncState": null, - "codeSubstitutes": {}, - "genesis": { - "raw": { - "top": { - "0x074b65e262fcd5bd9c785caf7f42e00a4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x0e7b504e5df47062be129a8958a7a1271689c014e0a5b9a8ca8aafdff753c41c": "0xe8030000000000000000000000000000", - "0x0e7b504e5df47062be129a8958a7a1274e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x0e7b504e5df47062be129a8958a7a127ecf0c2087a354172a7b5a9a7735fe2ff": "0xc0890100", - "0x0e7b504e5df47062be129a8958a7a127fb88d072992a4a52ce055d9181748f1f": "0x0a000000000000000000000000000000", - "0x0f6738a0ee80c8e74cd2c7417c1e25564e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x1809d78346727a0ef58c0fa03bafa3234e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x1a736d37504c2e3fb73dad160c55b2914e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x1cb6f36e027abb2091cfb5110ab5087f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x1cb6f36e027abb2091cfb5110ab5087f5e0621c4869aa60c02be9adcc98a0d1d": "0x08d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d01000000000000008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a480100000000000000", - "0x1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4": "0x00000000", - "0x1cb6f36e027abb2091cfb5110ab5087faacf00b9b41fda7a9268821c2a2b3e4c": "0x08d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d01000000000000008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a480100000000000000", - "0x1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef": "0x0100000000000000040000000000000001", - "0x2099d7f109d6e535fb000bba623fd4404c014e6bf8b8c2c011e7290b85696bb3": "0x08d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", - "0x2099d7f109d6e535fb000bba623fd4404e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x2099d7f109d6e535fb000bba623fd4409f99a2ce711f3a31b2fc05604c93f179": "0x08d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", - "0x267ada16405529c2f7ef2727d71edbde4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x26aa394eea5630e07c48ae0c9558cef734abf5cb34d6244378cddbf18e849d96": "0x00000000071c0d84db3a00", - "0x26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710": "0x01", - "0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545", - "0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746b4def25cfda6ef3a00000000": "0x4545454545454545454545454545454545454545454545454545454545454545", - "0x26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439": "0x01", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9007cbc1270b5b091758f9c42f5915b3e8ac59e11963af19174d0b94d5d78041c233f55d2e19324665bafdfb62925af2d": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da923a05cabf6d3bde7ca3ef0d11596b5611cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da932a5935f6edc617ae178fef9eb1e211fbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x000000000300000001000000000000000000a0dec5adc935360000000000000000000000000000000000000000000000000064a7b3b6e00d0000000000000000000064a7b3b6e00d0000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da94f9aea1afa791265fae359272badc1cf8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95ecffd7b6c0f78751baa9d281e0bfa3a6d6f646c70792f74727372790000000000000000000000000000000000000000": "0x0000000000000000010000000000000000407a10f35a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da96f2e33376834a63c86a195bcf685aebbfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x000000000300000001000000000000000000a0dec5adc935360000000000000000000000000000000000000000000000000064a7b3b6e00d0000000000000000000064a7b3b6e00d0000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da98578796c363c105114787203e4d93ca6101191192fc877c24d725b337120fa3edc63d227bbc92705db1e2cb65f56981a": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b0edae20838083f2cde1c4080db8cf8090b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b321d16960ce1d9190b61e2421cc60131e07379407fecc4b89eb7dbd287c2c781cfb1907a96947a3eb18e4f8e7198625": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9de1e86a9a8c739864cf3cc5ec2bea59fd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9e5e802737cce3a54b0bc9e3d3e6be26e306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9edeaa42c2163f68084a988529a0e2ec5e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9f3f619a1c2956443880db9cc9a13d058e860f1b1c7227f7c22602f53f15af80747814dffd839719731ee3bba6edc126c": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0x3104106e6f6465", - "0x2aeddc77fe58c98d50bd37f1b90840f94e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x2b06af9719ac64d755623cda8ddd9b944e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x2b06af9719ac64d755623cda8ddd9b949f99a2ce711f3a31b2fc05604c93f179": "0x08d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", - "0x2c5de123c468aef7f3ac2ab3a76f87ce4e7b9012096b41c4eb3aaf947f6ea429": "0x0400", - "0x2f85f1e1378cb2d7b83adbaf0b5869c24e7b9012096b41c4eb3aaf947f6ea429": "0x0100", - "0x2f85f1e1378cb2d7b83adbaf0b5869c298ef7dc060436e4ed803af07632b89b65153cb1f00942ff401000000": "0x601de9615313b00e8cea3ef84e79e50b2fb70e2c8a47cff478b9fe8b3fa8f2db02000000", - "0x2f85f1e1378cb2d7b83adbaf0b5869c298ef7dc060436e4ed803af07632b89b6b4def25cfda6ef3a00000000": "0x601de9615313b00e8cea3ef84e79e50b2fb70e2c8a47cff478b9fe8b3fa8f2db02000000", - "0x2f85f1e1378cb2d7b83adbaf0b5869c2ff3ae12770bea2e48d9bde7385e7a25f": "0x0000000002000000", - "0x3a2d6c9353500637d8f8e3e0fa0bb1c54e7b9012096b41c4eb3aaf947f6ea429": "0x0400", - "0x3a2d6c9353500637d8f8e3e0fa0bb1c5ba7fb8745735dc3be2a2c61a72c39e78": "0x00", - "0x3a636f6465": "0x52bc537646db8e0528b52ffd0058dc2705bea5c66d15541040ac6c3ae971bcf5f1040221a8d1f8b7c17e61bf21cce87411480b10bd8daa5e3c2b65f8c4aa364e5a8ddf27c0313827d06a2d6334e074db9ca7d876ac8d052862b9984530f4d340bda4edddd6e4de5ba624536717e1139e14df2d875c7f7086dc3fa3d398b64f50fffc58fbf4fb73ffb0d39cc2b86761cfe6d3073b9c1fcee7fe611b7f4875f9a7d8cfe208fdf493f4d3b07d9a73ad05c8cf39e5c4dde679c3c8391b9ceec4fd78c824d218e4cfb79cb8be9cb301eace3b7f8a274c182edb72e2e83349855e7e4a2a795d7e27998b94f46d92b42eb543afcbcf5f5c9e5bf2d52dfd9b2f93dc33262710e3fc79b943e09fe2d00f8dd7edc4350b92a692a2facb7adddffddd3d89e9babb7b8e0b9d61050b2b4ddf3efdfdb3f629e9edfe9c18c4f8715bebf42d6f6e3ff74be1b9c0c8b9187cb89c83618e5bce6ebf90cb3918729745244063391ee9710cdb87bfbbbffc6047f275725e904518e7f53cec48efa788c4bd67d104a4eb81534cd2bd67cbeebb075b4c32deee59a43da30fd2d0c979410f3db2fb2972cfcad89d0f822c7ab644bade3b59d6eeddc9925eef8f34e8645980eb0fb2f8d9b2cafddec99273d7bf234bee5995292c3051e1fa97dcb31285eb5f76255cff23de917c3f72c8afaeaeac6ef74e96462e7d70864ed2ef48be2c9ef05d8f1cfa6e67cb79dd0ecdabababab5b225d7f4a72cfa6a53d9bcf739903246f521840fe916b813c65e41c0c50b7b60fe76078bafc61ff4c1bbfac7d3887b3bafc37979f73580490ef389f9f5920c8edc3f3cee7075fdc3e4cdba79f1f9c200db97df896f532c31e008355cff83a7dff7e1791b4e5097b400cb89ef19def24533b4524b567fe2c96c02292fe233d5900f2edfed96d8f34d29c2680f3270934e67054b7a4b7bfceaf95fd879b568e777e395e3aa7139fded3ff484f77779fef3ebbbfdeb6364afae9f74c32bf6dd9ef3de714c839e5df7e908f8c208b30f2fbb388847f8a2354c1e170305cb6dcb3b2de7eb0436e9ff9edc33deb3fd24ed29ef50f602cc7dbfda0ac7df8f683331cdba73fd63efefdb2f699b79f45244e492a38b708a9def9f54e6ba3643efdf9d41acdeb964524d396f3ce3fd247fa2f7380e4736a01f2e59c72bcfd606d9fb266c81ce3fc32bc0d3a198071be3f3f8b27cc0f725b7bc6cf3d2be99da45f916a7e3f38c349d21b7211a2597587be4b05e6ceef17b908d1c4dd21112e95f0ceef777111a289bb43225c2ade9ddfffe2224413778744b8f3fb594c4271b83bff48831d3217995ffa73cff86bfb94f3faf3834ed69ef11719fdf9592481f68cdf6ded19ff91063b9c64df908b10cddca5e2ddf9fd2217219ab83b24c29ddf3fc51346dc9d1fb60fdf7e16934cdc9d7fa48ff4913ed24c72cff839a76dd0789903a49e5d06c80dcee7f629f9a7e59ef1f323cd2903720ee774f91b22454f610414ad21610c79c190160c991a32c6102286c0604808865831440c2057860431c469881042da10f28221370c9961881742e6186245881c426630248b1035848421248e214d42de18b224644a081b42bc08a11212032164081943081842d6102203212e102286902e84782184cb902d845821a44ac8154248304520a449080d3d36e8a9ea99a3478e9e387ad4e8f1d233464f0c7a723d5b7aace849414f153d24e839a247aa678b1e287a9ee889ea71a207891e237a44d053821ea89e247a94e81941cf0a7a5ad0c3821d11f448d1d3448f163c3af070a046c68e1a3b69eca0b173c68e193b65ecc060478c9d17ec84b103c64e979d2f76bcd8e982878947069e251e259e241e2b3c31f0c0c083dbb9dab963c78e9d3776e0d891c1ce971d2e3b2ed8e162678b9da99d1becd86087063b74ecccb133831d3976e2d8a963c76aa7063c1be0b9b293c50e163b2cd859c18e0a76a476aed8b162a78a9da89d12ec3cb143821d26768cd82962c769e7879d1b767cd80162c7033b42ec7460070440ec0072c70e13901b00b9da69dab101481640ba00f102880b807001b20490278094000813407e000204902cb51acc20a61390a51a0d80c850fb52bba376558ba3660710a5da1c409280e06a5635388058a9cda026478d8e9a1bb5aada1b35366a30a86d51aba236454d899a096a4c0059a386a546430d57b3528361e76987089d2f74dcd0a9d25943270d1d2a1d18e88ca123860e1b3a73e880a123874e0c74e0d02943270c9d3674ccd0214387063a32d0a9814e171d2b9d3774d0d0a143470d9d17e8cc40270e1d2f3a67e808a143848e077478d0c9a263834e0d3a34e8e0a0d3019da61f6afc80e3c71a3fc2f8d1821f5dfcd8e207173fbc981ef8f1c40f277e90e047133f98f8b1c4ab04f34b8f0c604288573fbebca26a54d0c8f083aa2af9f0c2c71735197e88a1d3c33787ec8e9009f6434d1b36573a869a0bbc2f3a778473d49e422ec2168453e11630203c1bfce0522347784527869a17542d68984219603d7442c086a8f902e34167294cea425023469df26e50e3a5878c70a926d5259b1d6267c8bebc5eb0d303cc03a1d2384307467490a583a70e74a851eaa0033d8e10bfc070a8568c3db8be78687c74f408e2c545b481cb4a8f14e06c51657851856d8c3bc8bc78c5c047d40f2d6476c83421bb416581cb062f2f2f34646ed42d7c24e164f1ec78a9e15223e6c54b63d4e2c38a48c78c1d95a9068d5a11f54aad04b51d5c68b86010adc61a6ad4a0597aa541a39463031033726aa08901c9445e21ade05841c6602307a9f423f827300d1b19f4d4f1657000825718382da827e8b0886ef4808123021c23708ae809030704384ce02c81c3054709215d709cf8f1c1f900ce062a10383e8852b468d0b2c26962c686991a7048b09303ce08704a504bc306861a326ad8b0d9400d0c6ac0c8990187861a3a74385063464fe12ce1c4e003063ec6f831831e40f4f0c04b8c1f67782ce8d104a8460fa79d257afcd003043fcc905981103764a2e8a1030803d005433e007ab179b201818d10f406a01dd48ece868e0956431743dd42bff4e8402743074387ebac74576a0a2a15758aae06b1aadbc07f60c68c971daf2f558a1e5a3aa577aae9a24bea66a077b8946a9868c8a0a1010d1d3435a061636606345e66e2a091c18c1c346bd0a83143c7cc1c3469ec0411ce40860b4d0b605a68585093aa69a131a25ba2c982e605b52d343e8c1bb0c901f6011808604f3c88784551b9c8ae646dc072f820fe88991bbcc0e88ae888e88c70c9d03dc18aa8319851a3f683c8c60c1a325f646e206303992b19ab191a66b0c850f1a282460c9c20707ac00142e60a192b6049302b3255c8a4e03df03f00d181831d4419d4c6b0517a55895334493b30b41534565c4b2e1ccca99682300d980e5e0d6057604cf306e31a3655231b3e62f08241f5e245c66b0c0eb48c408c3f8c1eb08943868b07e2d5454d1aaf2b5e5b6cdc78a9604c0387089c271928402e5e55d86001af6aba8871d4d0a0070f3634d4d8d1c3071b2b21ce268b8d0d3367d4bc01bba1c68d1f2ea859e387979a18c09a6c7880d95073364b3565d0ab9a19d4b2b091e175831a2b180d3859d4d421b6f17ae2d5c4cb891f37a89101784718c3cb0697198e858f261717ae12b846e02ac2b585eb042e295c53b8927081c015e59a72b5c07584ab0617169716ae14b8b270f5e0f2800b0bd710ae255c4eb884706d7129e17ac2b5838b07d70f2e1b5c50b8a270657171c065848b05ae15b8987055e1bac275832b07d7932b042e205c1f7005e15241cf54cd183364b862a8b99a2943ac439cc3e606110e9106e21be21d40bec0711273220a8068b169c3956433c3aca3c6c4b303073cbccee891c30e0e385c841b7899a1e30510aa1a143555b5276a4e4c2d707ee080033b576021d88961a7069c295810af357464086100bfe0203141600387cc13322600bbc0f100e8458f25c02dc030769a00c1787d51b1709d51b3807140acc1cb8b9a06ce11343000c204a40c58075e65d868a9b1012ba9fe00dba1034137448ba047053369bc6cf0838d1e3df464515bd0566ab8ecf0a0d34563f1d9507bc0116205162a544da22e5195a81e783272a2462a9e8b189731052e3b64553eb8689911bee18901048d57171d2d3836e0d48033838e0e325f006143c68b8f06b5a57a458c8b2ae5aa636c72a5d1e303a21db58a1a11b5281f31e058a92800a2850f18ea0a5e50d4cc21dea0a606231a43b8801101f321b4e25b8833a82a10e5a849c2d10296c533e3470c6a5c5073064e08bc1fbc19bc2b5e0c3d33e8b1a367e81a7a072057b4161b1d76b4b8c2a01903e452bb41cf17206a0021a3cb0244059d53a743d7d4d1d075a0d3d2fdd005d1c305080f3d5d741ce87ce87ae878e880e0d1d2edd079a0cba1fb40874377031016e00c61f3464d0daf0d9d1c7ab010b700d7d0b9a1870d73861b367676e0e14167079e2606e060c101838621e3820ea39de8259a896ea29fe82e1dd55f34091a0a97aa5cfc106fc423417304cd123448e41891e38408845884e834163192603402e4400d23c6464c8e980c649e64909029a207971e60f4e822a7889c12e488409c41e4808885468a460b1a15c4ba88c120e60558450503b442d64566860c8c19ab993b66eae8b1460f1af460237644ac043124782cf168e22143ab8adaa56545cb8bda45eb8b2fe245f042f838818f2d3e50f02178103c11b12b625bc4a44627c629c6a81814b12d3113f810c207123e86a8d9e0b9e1d1e1bd018301ac0cd8182316a31763163eacf0d1021f57c8acd00981ec8a0f86efca1783a884480271095087ea0270872a06a8e585e5b5c38b86d612b5205a4c842c08c908b1a835d42cd586fa058d153eb4f808c2070fad21ea0b5a21086f107e69bd117620ecc1d3a2268697453746774617032058d870c026861aaa9a1bd8d450e3854d520d1c364d3638d4dc5113860dae260e1ba69a2f80cca16307101bec28d145f42cd136340d4056d0589aa973681e3acb9ca3710d03902ee6d5acc1b4c184a3c76a5acdaa49032052736ab66066b164a260b2604e31a5983f4ca989c584629e60e6a609261573cbfcc05cc1b46246318998219843cca46965c6309f260c1357c50215983e3c994d4ea8b820a505a1261098400424f08006a49000144e40c001941820090953082300100091282c38c07979c648c16a072a6a528125539a00b1b0640938fd4914a0254b5abf8127529c003dc1f92b5c548401202551a440292a025a00f94c1cbc0c34bf24d4c40914222946455058f0e0956c3e89895a68e1f556b8a80848a8c7c7c0310f03b7700099c7f1e05c090935712224d48400349c3bb848084a1323a0274b80802cf0018e1d2cc50251a02cc10011900b434ba04cb94651805ac04013141ee70b03ad7003067a22c5c992274da4084d71c1060c64d4048a519426464551a0c870ea6021a1264e8c9c3421328a228500301c2b067212454a94254d9c44918200a3282e4871e2e4f6c0a9019429170345500a80814be2d020041c3a7270e660189c19b01ccc82132953806c70e26022175680628128529c2c8132e50255a0894d06a78a8b9e1035b90010d19215a24079120568ca1228536e91901429284481d2821404581c38780a14168a8880a25c40ca120c00057d80f3063f018ab20294a2282e18357122850a14178680961811499902444404c70d7e026589115011910b4e6870dae0222028465088a4b060e44293252b2c8132e53699f2244a1322127ce0c8802f0065ca25020a2292e28013481c361808c80520171290c213a015566892c20f9c35b828c809100b4ebc7091511420222016a240791c35a240b1800d4e1aec044a5114284446558096604068ca94264b88809e084171c116e4448a90ed06070d6e614913a3264f9a18011d0086734606a00835816204250a14191c3338c88914a10a2c013272c109501520189c3298480a01429e404215686214c5050b2c3172024404e54914284b96d0e880367c2083918403c3ca97cb4820e770b83b919cc66355b1aae694f951efc6c6fb273d1bcff3bc27c99b1b8ffc1beadfc75f7f5d6b77adb39bf963effa7d5d2be576e68ffb03e9f4fad1a6def7791fd013fe987a7b5f777fb4995b74ff9add99b2338b226566ffd8fbbe9deea87760f7d755efcfbbfb1b476ef70aced44a99ba7762f56e96d8ac3a99bac74ce64a65cd72cf9d3f0fdbe9d7ec2f661bfe987ecceca4dde9e73895dbbb72f5cf690794fac7edb4d93f76fa71d3ef73f7bc8fb6536766ca9429534ad9fb28f5f6ef83317b53a64c993fca4e653e66a7cced9476bb575ae5cafef19021428430c8eed4e5a20e7a575abbdd0586cc937a5ead1f738fcc9f3b6598bb5377efd1dd2be0eeb0eab5d6dae3d8b4dbdde79c3e67d3f6f6a6d4bbbf6edaecd46beaf5fc2af5c09d3af5599dddbf70c645db43f7daa42ba5ee2ff6f656bb7fee1574265d57ef4a7b093b8d31b37fd3dd41b052a069482b0dc31aef1a760fc309788712a8719ed3bf5ab97b727fdc13e4eb09e21e0176770a1386ddd3b9bb99fba3f9421aeace94db2140a97baeaf7eeef4f3a8473d66af52eade5fb7fb473fef8ffbc6fb3effe6fc981bf600dab4ddbb2937b37fdd1f7bceee7d2008a34054a820303bbfda1dc0cc3e3bef98b9fb989bb9eb66c7ac6eba772c67ee58ecccdd64ef581d77ce9a5dd771d7755d73d779c71db3983b666618666f6731c73033b35831cc95997aadeedd9f7b8e7b7737a51ed0ee80f6cbddbfe6699e6e8fba7703ba76f7a49501ed7937ad1fe5e9cddd1f7f5fc7d49dba376d4f61d20528c0030e9d7f780218051ad6f41ac7a969202774cb7cddb06eeafd79b57e8e0098ce016a351d6f1a86ec734e9eacf6febeef874c7ba594c62adb7ccc95a73bedd0dd457710e6e476b06d427666a6dd4ca33edd41f77228655a29ad94b6f70ca5b45217a5d4044a5db429f5da5e2b58bfaf6777fb6cfe3e9c0efae3e993d99550e7ea6cc3ce6266af71f7cf6b6776f630c63e67c8ede2768ecd364077e8edce727767d51866f7ca732661febc69f3474343536b7dbd5e73ce5adbbd84f6f6aa57efd09d046feaeefe7277eef9f5d7947e1f87cedeee4dab778314ac2085e9eee6ea9f37280382ec3ed929ad15a4947e1ff7d7d49d7d4e0ec3574e873e42483d44e2341e76bb7bddcdeeeeecfc7ddc55669e9f659cf979e8ec79dd4eabd7dab47af5efebaed56937add4a35e53da3da7cf39270c4c7be73c3bca6af72e403b28d33dfba360d7fc79d8dd9336a594b67f4e00dbc7edec3d99bbdd3fff3e76e6767667766f6766a6a0e73ebdbda977f7f4cf999d5266fed89ddb9d32333365fe98bfef6b76ff989d7a5f6f7766767777fed8bddbbbbf23dff7cd6aedafcee97d3319113c99effbbcef930d4000edc950af7e9fabbdfdfbbeefebfebe98f77dfc7d9ff3f77decf4fb78ec9a366d9036edcfdbddbd73ea7ded1fcf39448a2153380f6e0c10496901a805cf8805a448219a0242009e0011013d2192b2c427841e20284446207c0043d323a5a60b72d2a402424252402852d3c3470f1a1e464550aa00dd742d48e981620120a22996031b98284053a634b9f10b00450122ea0e5a806214c50522cb81058c5ce8c14115201696184581423465899322282ddc0cf1e95145ca058c7c3461a1c8475013274e80827c42e8e1c14188f40459d20314d444a8024b5688028585a2262cbc102128413c00f8800807690244e4032868895115a0283a3e3e807922048505274b8c845c686201a027b4ce88a88951d1073d1cfcac00a5888c7190220c00052d710245a8022e4c99111575d0e29ea22220a2292d4871b28408888a142740444b9a143d7102b42448904f083d539c0015fdb0587062d4a4024b58288212058a05661f60c002508880a870608980a200adb00400414208a1e709d0122946533040e4a4039610101520a125559ab480035b418ad09215a240596105294234b3051f0c446401275284849adcc054017a12054acc94169a181501b500c5e87b449102c5c84993a2284d888c96184169a1022e14d1584f80808a96b420e5499426443606c8a88951d1922022291730028a92032bf2596116821150d19227519a2c01226a32a5052943c62640424e9600add084488a51d112a1264ea4088140250a90b338c8922852a014110151594224c5a8c91328424da82c2982b2240a94262c38b18005a42c31aa02c401952840fe03aba3f986d44cf805a466c28dc462c247472c9009b7c20e09e9e8e8ab48ee47484820528b09231d1dbd8e8e68bb33399a4847474794c9d13cbacddb64f2c27c611e1d1d1d1d3192787474243261a48f8f908e909c9190e6d1d16482348f909ac96dde6ecde485f9c20bcd848f90909cc9d13c3a6a2647f36832e1a3a3a323a48e1e1d21cda3598f26d264723499091f1d39133e426a267c74c448481f13a47974e4313942ea98204d24a46682349991281346426a268c8484e44c9026d264c248938905bc342633cf168a9a70ff6aba2dbecb9bc2179ba6703ceccdfb193b61ec6d8ad3fa61f6369d5af6e654377762d95b3bc9d8a6622aae72ea625e8cbd219102ec61fec6fa1bd3105beb6f48a4d0bd3775fb6f48a450bfeb5c0ec6de580fb373b4b709e5b4fe97bd4d97bd7993686fdd14da9ec24d2876c109ea68a220cbde9296425bcbde904881f5f46f93eaf6330db1517b63d949e5b47efa9ebdcd29a7f577f6d6d5766e7a36a8a2065a90800530cca9a9c58c21d4f882082b9f3dea2b9a5002872dbef460a37656517915a572a2534d533447713977a250de975e0555e5509eedb450755fba13d5955367bb266fa25ff6d477757507185faca087266a3ba6cecd37bc08c30c20a4c2b0b1cdbf6cdced8f8b1dbc7842862cdcb0b1cd6d87735a7f39ab6eff1cc138bfec70b7bba9cb1c1c59a4d933361c31c711671c31c611611cc165882e59dc0c8c9c1b4288db0f5ece0d41c5104fcc1a30bbb3b395796543826b58f0c86e3ffffc59fbcc3075fb6f74daa76fffecd86d16fe36cee5c961ce39d9c66a98c3873984d395f5cc2d371260cf8668c26947f0b30d091c10081bb60640bafc2fc840c4b644c4d6cf362bf3cad61609b64773ea809492486310fd0f6e89d41d5dfa25eb006cc6ed2c11b57b26eb7724253b57a2ca562d8eb568a25fb228f9c105278b10f8e01e4da4ae9b0b281f40e625e61c9ad77fde00f293f00738346f3f0f5e6ef8dd3759346f7f8b25f065d9a0f9ac269a5cebdea8de21bebae0b73842f8ad16d87db348ce817ed8e586cf7a10ecc26e3dab45253409ebc33fd2247c0ffe24c16791e1bba8a4fe9c96b936cbb6936bf3590f9265b3a8d43be477e08c269237db8dc9f47f5c3a9f7970bade7f28a8b003166eabf159fbd878dde7cc98b0204667f3d1a38ddbe9b44fe9fd8c3baeef25842a30699f8ea54c689f79bbe7d1c274bb1fd2519edb3117299f9a5bf219b7ab3fe57edffc46deed07694efb74443d45254beef7f5fbe6cf32ebb00559a2094852782dcffb727edf64b51fe99125d2f5823c31c967bfff6cf98267cb79bb497f70762bf16f25d3b34ae677f737e00e425c8fec260cb7accfb9197c18c158fb78df3d1549a85fbe709564c270eb83dcb8fbbd47d68f2cbde73fe21e0c777e7b55f502d6fe793dffd83ee2f3c7daa7f5cc7ff339ed539f7fd63ede23dd16297e25914010fc231d9236f559396cb9f4451dbc07b95cfa1e07ceb8f441fa208834c367b1c00727f8437ec1076b908d92ef3bfab93e259feb03bf3ec86a3d5f56cb8e509ff5ac1db25cfaaddf21e9d2a0eebf0fbf92f3b25c1ca1d56ab56c50f725fd22a4138a906ef841de9f40ffb3a5f7a165f165d52e6431b4e5ed86ef912fd27b89394839935ebfc41cc4fb693be2210976a147fabf48b6555209cb06894f5f7c16910c896314df3df03d5b8a0f5a1bf0bfef94d017ad0d6895d4f7be821ed9fa2fa8d64f49fd6a12fa2c5b7a0f3e089265f836ace70bbe47dab0ec08dd830f5abe1c98e3d2071fecd06b3d68cb794befc3073d6c91e197f386df8d002601c1f767d9a179c57a7ffaa02d5b1f92e0bc1e396f8be43b2ff3ed8618b9fcec359c0168182ebf8b87c8d1446a7568039884410f5924c16d39a75802fbcf13fafd595f562e52bf6479e86439aff760fbe5760ffb32c8a1279e40df6d59af7bef950e7e210d3bd10095eccb22e7edbc9fff89273458c5138edcd6b3c8790d8024c56d3dd80a5926208d10e50e1dd52421cefdaa880024a7db7ab04396480292d31d62725b0fd6b0251a00c986db7a100c5962121eae1259a20948b7f5a02b641da0cbd7fdb8997976aef2a8e97a0f86218b65cbda2e5779e474bd6f91cc3a65ebe787e209fd2d5b4e164356927ecfbacaa39b4588ebfdbc959c17ac618b49e8fb4f71c86f903802d2ed3eebd9f91e34df46498981dbcf17a94e2f892c583c0a0ee4c09405072f138710ecefb7e99e67f7ec9136ddcffbfd07a3ffc1f5ffbec9ee677bedb5c7df5ee59eecfd11f7c8ee821dd90fce59c3d83f3b0f3b1a765dbff7839d38028be17d3357f3dcc976ecd907d791bee95b803c3b3082b387b193b89cf3418ddb405cce7540eace2ee778b04a6264a5ea96485178b774e1062b2eff6bf6303a1597731f58e2ce2d977340bc71752ee780e0c01449686541758798dcaa1feed091eb9646658c2103e296464f408065dcd2688632ba5b168141821f504cddb2286aea561c8eaf2effe56f1dc0a179e98394ecbeebbeb8f300fe6dcb5c08dab8f4e9cfef49da28e9beb8f4bb2f6e598474e977cf7788afaeae1ae9f6776ddc79c4964b5ef2821d3689733bb2fbe24e9184a72233ad512b7927c1eeea5a9b24f3fd4998efd608e4dc105eae51dfce96fd54e6f547bae47592bc6d045e7ea46ef69739ee7cd9eb3ffbf9fd5d3401490adae4fca60d23e76e38e3d6ffde6b7d25cbd607b1be7ef7dffb834d860fba481bd7f32d91aeeb3fb2ecb643af4bc5a8afebc31769e3fa79c70769d80f36699384e270177c7afd82df645f16934c5c8b24b8fe458eff91ae6fd2c317492f48c38f643aee8bf40b76e147f20dee8bec0bd29edc7dd41b3ffc8f643bee8bbbd9d425be5f317c316e48f68fe4eb8ff88bec38e8fbfa6e029214f5b9d63fd260f308f3bf2926f9beda24f11bbedfd0964851e070b749f0c129ce1a46f05d24f8305cb04317093ee86f5c90cac1735cb00b5d64d177a9f45d81685ef0a98864d230820f52710416e3820f7247bb72e0027f0b2e86eb22792ed8627d83e233d75aa0f8618b2cfdb23e64852dd6832451288afd21eb5b248b26b00e8b9fe707ebecd8336aed752beb996b7e5ec029c3482fe76e78c19461ec2ee76e880173ad83eff3bceffb496ae0fbbe2f0d9049708add5cebbabbab5ceb7e921ae8ba67711124fddd73e5225420097c5f0f32333373cf6772dec9af906baf6f3203a3ebc50f1ffc0c8cad677dfdef33307afe7af5bf5edfaf31c05792efbf1659de777d677d7dcfbd7a2cf0abef2495796bfd6f72bbcbfdddfead36a8fef72c1ea0b26c8974599375abee5eff880fdd6ed76675edda3ff9491bfff9fe4ddaf83b59c291cbac537effbd937cbfff2a9151788744b873caadcf621226b77eb5cc3a247c64593fc8ff7bb092966888ab70b86b04735bef6e14ded6d767f1842997f547ba92444322dce69abf91776b5f7f164954dfc8bbad6751c992cb7a9c2111eee41aeb2bcb32ebb83842f7b592f3bf725efe8e2cfbe733b5b5674e8e757e5880ecc1bc7bb0f307a7c86d03bfb625d2ed79fb9899ffe33bc9a1dbfd6693437e5fd33259d25a2793ee43dfd5d5d5975b9b1cf25bed9077cfde7f64f93d95f10a511c0cb7ec1ffabec07075a9d4921544bf3edb72bcfc4d86fd54beb27f8888ca778b90eeb42c2261efdba86febbd6fd9a1f9e5521669d497beb5493273d7bf4524fe1ec9e57cef9da4d29ef7b61cba5dfa5d8974bff9555bde6efd26677777fd598434e423f0f77b437e29b5414aa892f96e83f89b59b3e2d03327768055c6166f787a2663152e32bf6fee52f1441f1f7cf1a5ede37df8fccc7359dc7a2e3243f2b9c673f9bd24f5c93abf4e92ef145b606b04d66b5e904524fcc1c69eb59ef5e04f11c9b425d29d2cb2458295a4326f392feb2749655e16eb2bc99782ae6987fcda8ce077feb4cf35fe792bc9b241f5c1a7e250bdde8321f862fd14e7d2e86f59967f82952cebb35ab644baad89a405daf276c19f248bf49eac33bf340092149759673eeb8ff8d0ed7a3fcb5be490b3fc59e4541afdc726f97e64ed7a6425c119ceff489b6987e6f52c6fc1e1ee8feb8900f426a431a8fb0f6ed9d989a5677c3937830fe0c4d23e7ce9037111229e4b043f12a7f1f399ad6793966a36ef99626c58da2776e9d70c29632c85eec4d233fa3c68a090e4fdfc23fdc2584e2c977ec9685cfa37fed16974f8e004104e4051e17036efa96d92382a821a4010431027b0252dd56cf399626cfc494b6dfb9e6900b6f91ec93400db0d8914e6df50701afd3975e97b7f432285ef3d7b3be234fa9fbd219182f7d3dede69f43dcbc3b9dcfc92a7980632a8800837c230820c2efed21f1283916d483a6071821f7e98a2cb1233b0b18dbfe4b9f4594ce17138dbc4d23e1f5cfa9c436dd06ceaa63f80cc454a1ea457d93e2dfa1da547d73b332eb55de97df43f1bc5b3a5f742ae44d5edacf7a5dbf276a92b612d6cb89e25a2765f1e5d21241fae17450049b9db7d496d59e57a14d6a2e9765f66e052cf46e1336e67a79e50b0f30515f4062df7e672aee9cb053bec48226efc47afabab2b1f6c2c227033632861650d1cfd39e4575797085c0f1a86c8e244d48153125238a3297cc62502b7f30515382a0248ca55c1b1164d36fe3203b77be60030ef949cb3a1896b342f1131f0193696c5f11936b637fea3283f7c000c18bee070b66a7149389c8dbfbcbddb720a48c34af253d2bfc506ec7c31c5958d9fc506c0c81823047758b9bab2f1c7aeb77702d02925bba7f3ab5df7fe951cbbce6b345cece2b8b29e754fc979410fe97b1d9d9776c3c0bf72112f65d77f7a7d67bd7befdefbb3bcaf9ebf7befdfbbfb77e4bca047f2ed90b41bf48f74bff7d37b1bfaf3f6b5a17078df7d5e47ce4b495ab9c6ed06c8dd532ee23d7fe791437ad6bd1997a767ddb3e865ad52df7f5adffdcc7fc0effea67d68cfea774f848b3cd7ea770f9263d3eab7c8dab4caa3fa8fac69f5bb97b50febbbe72db71c72bbe7c145ea3b55e891fcc1eafb43dd9b9ed5ef9f3fc5fa36dffbed6bf37dcfb91ad4b89cab018d2beb597d6f885e96e59ed58e6bfc2c528f9cf7a891ba7625406e9fcf9ffe47cedb91f45924a17be6da08fef4711082c503f8d3af4f6d592ffd7e8a4355926280017787ca0bdcc08eabeb7d11d2f56cd1674bfadd91423529061868951695545b56015924a1a34fc511bc67ae95dd47ceeb911d126a6d92f8d3f7a736a89fdaa1db2dfdf677b353007e0f4e1109f8e1775f49f1998bb8de7bd0458e8074cbf0c1677184ea0aaacf1f9265fdf9e014d9835dced520c6edb8e6b53842f78b64fd16392f08b278807e16eb4592f52d92e7b3888465cb79d996ac6716d90ffe9106990c1f24f9822c92c0367cb043909c9745125a97b956f283e00cc1f08f34872059490c8ce183dfba654d526f688358df2059b27e2ae967cd568be4cb22f956be5e475292f68cc3e95a409e32d22f65b77b9eaee3b9dd773fa47b5913b7fb9bfe695b67e4763ab7fbb17dfabbaeeb9e733a1bc4b923907932cf27207fb0b0673114daa77c1adab8b92573b9f4bbff6af7f7f3bee42ef77b229f4f594b689f7264a17dbe37d23e35f77b15da87733534ddef25d03fd4e6dc85b7dcefb97d6c6e19bb2591fb757fa46fc0263f21a608eef760874df6952171bf07b927bb6b685e5dfe3ed63ef4bfefbfe79ccf0671953fcdda074baee797b21bf6e176ec3e092ebba1fea37fec9200f20e19230d586eff386120bbc029c3487b369f67fc29e92414d0b9b87bcdedfff096e3cd097b46a3009e230826bad0800439dc20031bc760d4b288643e1db17ce9b17d64b73fac3c6d783987a58d4badac67937336009968ec1ab6cf1c3b00b91c1b745dcd30c70d888445871b9e7000a34b1177d85804e7734ec943ce7bc1497b36699f4049f06cf9d7fbca1f8cf6cc96467e5b2f6b1ff0fd6fdae7033f16cb96ac6f3deb0b7b36b6cfc77a7ff023e7055924873f451278dcd096e1b7fe23f986a4915fd683b379baeb23f98224df168be49e95b23bbffacf95b771d3986be5cd9db6f4409fd323f98a30bf9246dd9d21d86195eb3d93652d2b7fb0c9624ecffcbfff9e7d4c52b29cd7238dfcf24f72ec19dbced69ef578bffa0fc5e170389ccd7fc645fc7acee569cdce03eee493b1d6366e7f289bc187db7ff3649ccff34ee110c96bc42b6d5cce5d11e3967ffb0a16f7fd47a769fd8d047c79df5988b40fe7ae7cb9fd46a67882ff7c1681c672d63d11cecdc074fb75fa67dafa8ddcdcb44f3f933c3d6b9d9ef57b47922cce581c615e9d9e4d71d6b37e0a8c47b7b60fe774371d0790c9381ff48e9832e2703818669f30bb7da4670e23e736c0e57e709d72112e1a3977258acb972fd885948bf4e5d2bffbf9a00bb26b24bbfd4e96936888af6ebfd177e9839ea8e4d52473adf4af9cc4fbee5924c1ff3bd24ef2ad64d97d39afff47da28f1bebf6d50f7def3a5245f4f54f2c1f52c73cd9f8a48ba196576fb67dae6d31695700da2cc6e5b3bb9d6efe209b3eb96b9d6967b3691be498d00b9dd7f2673bb2d274e54f2baf49da4422fb5cccecc5ce3205dbc7a7693bd05387f82977332bc60a6d132ccc0bbcb3919eaa0fea0fbd0bc9acf62166f06f1724e863ba693f37e97734c42b02ee7984470653d6363d620037617b9d621d7fa99ccc0c839a62dd72fe7985070cbcadf2f32c9d4c495f1e775d535763b80dc0ee89e1af9ad1d69e437c9c4e170b83b9f92464eef7c4ae7146386ee0f3a39599c7fa4bbeefd5d44e23d73f2eb9fe2fc16bde7a40138b18cf3d9320d387f9224f0052739831657d6b2cbb9a52fae2c1eb688645eced55075653d6b71885ee61a7f8b4886e6d5a5e15a7f8b24cc4b9f4916f927392f9343f3eace771109b5b19ef54f52c6b57e273530724e862362345c846fff28e322ad20fac10e1685174e923d58d833ee597973e7bb2ee764c8e2ca7a361f64ea3db973790e20370876cf3dab5df7471a04596c40bf2d912efd239b3b8b2af8b7bd21d96ef4dbe64ede906cf48f746d9fcafed35f1af95561e4cb29cc777b3bb22d213124c2f57eda3a92da72deee3db2f4db7d93fe47bc6d2ca6e0b6f9479a927c9b641bf74fb521f9517733813c34726ea98ddb5dce2d65b90c63918479fd8fb423cda9c4a70246160d807429b521d29c0570b204e49e913091f8a74842503fdf20b64347977fb200b202e81d2ff8a29d9b8074fbdb863df3f7a79d4742bfff91e6f6b119a1dfdfbd9f4f6bfbb82dbb0ff2a7ef791fb64f5f6fbc2a00590123f8a2bf84e5f2fc72de69c39ed1a70fbe4c18fdfb878e2e1d9a97da0a80dc20b74f7bc824c8394a6d8497a77d4a23df3ee5cc48fbd0f7d7699feffa8fedc3392531ae7fac7fdae639d79fdb27259834ff120097ec88e099bf976002e096d4a1fca71301d3fc69ade328fbffe0961fb478025371fb6b869431f214976f49adae9b20e91af5a5cff405705954d25d6abb6e7e51204319f90b14e42eecf21727e052afecd2f940a0187279faf7a5ce65066282f173da87763f85726eb524bd030a19dcf9a3fffcf4ec87acc6ed9e26d9badbd95228e73e1b23dbe6b482883b3830f586153a9c61732ba048e3baec7e4ed3e603891abdcb3928a86ef9777aed5e80dc3eedd94a96f5d6ffb8c8e77111afe3229d73116f2ed2938b4cae79cfdeb441defb7b5e93b567f57bef67b565add7fbeff3bcaea3d4bdb9487def6792ef76d523eb7b5d3f3bf4dda07e4a96fe4548b7bf497b98028bcbb929a2e829a06e0bd13ede50fcd3494cebff61a6958d85e5c33c2b3bcbed2f6197610f8021978342ea1af5f5279a4d65be006e8b27787742b14e7f0f31f2852a29974b446fc95d54e8d9a463246f433581ce3c9b30da339d9e75397358ac6736582e7d1bcf8ed0d77bf642055f6ef7448c4471fb5930ea1fcff517a07d38f74413b779b84c223ee3ed248ac3a27f9240272438f7441bfd1ef9002b73900fc045910fc045d133be3ced53d621edc329788015b639447c76ec9b9e35ec0131e47ac677bcdec30fce56f25c2682f4c412414081613583191c61632a2ef3cf8ef40fb5f1330466940f4fe0da89266eb71351dc6e9e198ce53febfb6e0ab2489e32185bcfb7f5f3bfd6f741f4e9839d888465025292efa72d83be9f22fd8f0cf23e4a270f6bfa1b15ac19e286d3283c37c83fec197ffdf69e7e29c473ebb31eac64ed591be3f77c9b45d6cbfe536dfdb59e4065de69a98dc2733d1b44bfb32358aeb3677077f7f9eeb3c7985eb610caa17d93dc44c5718650cef422c4236344172210e2f9beeffbbeeffb84be28dce5234beec25d7478867011f0f96ffa67e6f530cf1f8e3d00a6b7c9c4629e5b16461221f331b171e61b1623ebd9477bf67d0c19ebd9f733e437edfb1639eb190cc917f6ef3f32b0960c599bf63d8c1c7bf6fd48f2f4ecfb1739a467dfbbc802f4ec7b912ca167df87a4093dfb1e2451e0daf7ec3f449af67d3f7f8a23f46d59eed95763ba0b0128da92874b17c6e2b22dc51785786e149e1b147eabe4b9b30c6dc973c3cf893dffb70fecf9cbd88d79181869a467fd317248d3622cf8230cf94e9bffca9189e28ffe03f3e3f7c3902c22196d19fe57fe15df4596e3156d19de72e48bc20dfabe1e39d2d8b487cf96b3fb31598e2e11c808c67f1739739aebbb63f7fbf0b97fc2a67dff3d7873bf77912212d1d69e7d7fc443922c6577da3246b2ec67bb882ee3f89e9d43e61879cb9d638cf5997462ccb83c1632def295467e8634adfbafd67194c9fe673c3debc68f2c6796ebd9982582c575e6be7624c039bbdd29ed989cff8948645f8c6cbd18d97a3306237fe7e22a76e8206d752c2fac3d63ffce3fa8b3b567ccb3d6cbcc9fabac72e9e5cbb34507a50e7ed37b1aae75f4e69486d487be77e1e4e2fb96eeee20839f0472b808e55cfade046bc8e4bbe82efd4f4442ffa667fc32aef14f19c930a21d2dbfeffba8571a399805e46286dc1b605b9670895cfa538c71be1091cbcc52e8bc80bad3d9656a4ba4282e7df79f618cf35d88b75c3acb18e74f2e287da702049fa76e39a48cf5112ea202d7c42fdff5e5ec87884effcc9ce6e1f74cbb7eb5338db11c5b3cac073b474906ba30a28ba62bc4c3c5849eb946a74d7186e4bc2209640463498488ffbcdeffc88b046718b2fc27d6347fff58f86a8c446e8b88ff2421517fe96daff72f40fb94d5a7be7f09edd3ad677d68cb1b6f81ef42442eeb5d547253010e42405d21ee7259f4b2c8b23d7b7d2491c953617b4ed417e7943377bbef723b59ff94e0b4ee8938ad7b7e06b2c548ffd6b30ec8d408648ab19c5aa696f6e96f6b342f121fdae7733aa27d3e4b0454fb44b58f4d4f2cb77bbedfe8b4eebbf17295a55c05640463f725a8c045d0184ba6badd3379d23ef5bb670137a56fed530acdeefcfeeeab98506dc95c5c44e259233a9be05af71d4219fb482023602d3dcf184baeba5df7538c4a2255e6531212f497de2644fb94d3a97de8779f0f8b48be5aad106f51a28121b8f042758598ea4e7a3d925e4a7208f363fdc3b66aebcaf176b652e7fa7733f7d9c0df97eeeeddc75dd7f1cc72bcefefc85276f9fbb2eb3aaed1779f1e59c62e7764195eae43b8c66347070d27173d3db2b6c6e8d9dab376a6773ecffe32bc73ea08d7d8081109e480219433847f96c3c577f937936a72573bebc541bbae637ecafcb2aeeb28384da0725ba270fd2759f2dc39e79ce5ec9ad0b37e27857898cbed233deb9fbc85889139bb5c29223d6b4a96425198ea064d8b44a73fa1d333de22813b9fff36c5a8bcb94239977bec596cda92c89ddffd4ce7bdf7294444c65bbce9348020c8df24ebdce6b94de476f9df7739b7ab48c25a8fb450cee5a79c33e43291cbb2d28bf5cc93fdf5a6673b7276bbfca6946b311691944244eefcb6b3fbc299bffbd2f3f83dfe208fe716fc938b7e3ab718e7cf1890e075dd7bd77d10a5f426d67d4929ed485b32b9dd53727631cea746dded3a4b72d9755de74f20b70fbd6077777b7bcb00f697eeee3d6bbfccf432fbf897dd3788a8af5f5d3107807ee9de414e49a2795b095f5d5d6effb2bb8d5a890817c9a76701e98325330d625ba70b2a7391c945f896f4b9b6c6382f7dfa5e7b367ffec806f885970dd0e6394b505582d9ed449313b8ef8201726fc0eaf60c07708740ee12702901167480f38f984c7c694288af7d027039c744976be4d7bfc8fdb84873cd595150b18aeec585f791f1b1bcd4d7e55c1371b0445ccb69006b53a8456c05e1a247bc6050239d02165601d3da2226468232623130323cf50a3855408239aedf2e0196db3fc4c80765c84528002e915bde9044fe4454c6cb3ff4978a5fce5d4af6b8200d295943ca2ee88594e471c12fa4e4cc056b48c9980bb2424ac25cb0155232c805c190923c170c434a861714434ab62ee80a29c9bae02ba4a477c131a46477415848497a419890927ec19890927dc1180c2c2626e3b24446e3ddc9ddd0b580f30aa8286e49a19a8082f280169d86c262ced9ed05ea0caa840f4a24415929d1841249283184a7441b6228a1c496fa8d97734ac8515d31b0bca6568b0360750ac1277189dc12276831e10ae7d42b146364282e505bc46496f012c25c2616de662249092c4b58dd3126b3c41bb5c28493891a6238c74416d8f8728921d8625518170c16e04cc1571954d3edc94dc059c41836146e323373126d24e18593f8726524c87c11d39fad4a9ebaced39673887333b72a798ada72e6b69c35151628d87f3f8e0ffbbcf88f0c4dd9552fc8946d35f323e3f15134b6b574ee3fd9287694d31aca69dd4f4e6ba75c12b95bce2a9eba652f4199ec74923dccccc7bccccfe75156198c2dff636c29b3e5e8d45aaa6664ac66aa50cdcce0bccc30cd3055cd34cd3459c954dd923249d9d1025bcdccd4cc8cac8b4cf6fd4de53f3c686c6c2ccf6a6a2c0d0d0d0f4b79f008656f4566ca66acf7f3a7d37492eae9659c54cf1ff3b3cbf3ebd9a614fb39f52fb2e78e71dad74f29191a1e5353aacb949215999fb132a599b7223369ec0b323b3363a79722a4db39ae75c76c59636c39c2d85206b3e56cb4e5f7bfc8ceb195950b9ef84007d0880304b6594b2db551830db87165fb5c8ba8343c80abc3043656d73147087032e08ab0816c2859e9d2050c4e6063a7b95e7ca79af1c2644714554d6ea585e25ea04e2fd0a714c0616b24a66e4999a46ee75cb3d9d8b2a54c566df9f7b3b9dced9fe5b4388d9d3c5bd6a7ce962394d3f8525bca8e2411e534be6ecbbf50311dd303c83925cddd999f89e241130545c38366522d4eebe741e79cb28ac9c46233333433333c66666a64646256c94aec9564373ff333df3236375f4dcddbd467ffe161797c0d8bc682cf36997d61c6be20f3ad076913283e65125f4f712fd8bbd5b7555b5575eef3a8ea50ac677fe2a9b5bdb853d15792b1de45e6adc4629e6d4a32d6a73e86a45ae69496a9db1ff3e59c1a81d32d1b57c563d556fed34f4eebafa3ac9f6e3f68ad1ad731b69f26ae9fc62a1be7d47c9a5652d3d64f9d1a14fff55552b7ab6e4ff194ffc8c4bac81e05a74d2a1e305e669e9d36be8cccb3d35c6fc563cf4e0bbf63969d063e28533ff6e28c65a7b15ee65f3c2c3badf5330fbbc92ccff7532dfec3c3a2e0b4f93330b6e42e773ecc965566b42553ddf92f5b8e31cb4e73d992bddcf9a22d65a12db9eace07a996dbcfe33f2d5b56962dc7caf3f178b6ac9dadf3eb6521c1348c1c20e780ec3face707adaaa68d454e1b4fd127a7e12ad3d8c44f71fee3ef24d3323631ddae2375f72e5053fec3b62e54d40b7d826a2aae7226ff513a8ab1d5af4fadf0c9296c396979a55ba8a5c97f94beb7e255eb4c4eebffac37b93375d465bafddec5f2fbf7f4bd9fdfb2b63fdb9e65a7cda6a6f2a2e5f6971d75fbbbc97fc62a1bddbbc828eef697dfdf915063e950936d2fa34fd73673d38b97cfab9a39a8692515859bca35531729a7b537a99a3edda64ffed3475831061a1da86105b67e0ae53fae830dbe1061441054d8fa6994ffcca519c0b8b2baf2c2d64f73fe13e40a1ecab85ada62eba752fe339da82307263a70c0d95a4bffd4e23fb76903bf5bdfacff89f21feffba784fd55fc07b42538adb79838ff695914fa2793ffb0ac0afdb3a95a262f789605a7f537f52e5cebf72eb7dfddbd9f8971d2aa0f89f6584515ff61b0b2be9c5a2e2f4d1beb5fb077f173abf52087e2873ffeebcbc974f92b09b333cacb6827d4d2b4bd443b9f467e1496a60df6adfa254b7dc939f04b2297c32f792effcc7f6e283c3f8c9c52e48b9c5d5ce4a422a717d6f3d72a4ef347c169e2f38f22682753cbcea6b6a5cc4e2d4e9bb6fc3bbf9c52f367b30abe3f4f0debfb13a995b258ef5f82ff80e0cf9c361fb4ffd992a5eefcf23d5b724ec6b263674b22d569d4963c7776cd8a01e49cb273255b3dfd92a7a82dd996b3cbb664abeb930463399d9e6ec9565655fed3a50b1595172fe594f29fdb1fc5d8fca793ffdcc4f7befbc207bf64a9af6b3deb4bce755ffdef4b22b79c4e2e7b7b41f4eccc697d7bc1fb723a85f641a95ccbca589c8baa76fc884079b6b2d34a9e6e2175d31480a327fb76da7ddebb9effc3faac16188ab19779feeaaed7088b81791ba6698bc9ccf0a8f9a4a56aa37999272df1d86c6c0d0d199391313c666448598ca4e120f363c8fab15a1c040c6b6c6e38480f1f381cc425be46184ccd746fba8db445df738deb9e7ef8370773b85ce35e56bcfef737f7a77f0bedadab9ce650537846960b1c5b7ff3b1a79ce6b73975e3d9e404c29acaebec6d56fd847a7d2e741c2bd7385c2ee46155415541b1fe6b2a707cb6815fb693d89a4ea3eb4b1e5ff65db64e89a1958176ec26961dab954d1dc5d83e5b9dd6cf36cfb28dfa0b69762b0b9073ca59553faf7bfef71ffafc1ed991569c9256fc236f325fc91b8f3f8ab1252d8936eafdd2b4794d947e47ff567f69daeadfba168bbb5f9ab6ce5b323154ad5f9ab6968cbd252d89b62426116c32bf346d37245288bdccdf78d8db8c5d9a3619ff987f8cbd4d2aa7f9c3d8a5696bf9c3ec14a7f9b3ec8d89d3fc47bb346d9dffcbfecd6597a6addadbe8347fd14ea71b3bcd3fb44bd3e6f9837636396daa7aef8d9dd3ccd129ef998ae7e3aad69793aa658f626cddb3ec518c8d3edbbeafcfb6fae584aae4477a6447ca9c369f92efb4396348b3bfafea8ef44b59f9b79cf5dc31127dcbf5ce62bd7d4104bf5b2dd0bec00a9f3efb4f685f68bd7e3efb8f52d873c73834ef2765530affc624c4f6b22f802efb42f879569e95ff88564914ad67e534ffd02a85e1f753eab3e583560904676eda52d6b24aadb7525fa96539ca69fed47a562cabc47a2bd5be409f6d4a2ccb4eeb9f504efb703d778c44def7cf2546ce2181eb27a927ce2181bb9e37359f9efce766c58f626cb5f5dfaa3259fdd638de723edd9884d858764cd9acf80bec3411aa6c4f3d778c7fdb9673887ecf1de308ccb5b256f6979fd44c629c498ce5e7e459959f5397f9d4b7fca43e29ff994f4ef3af751c65b25b7e52d79ffdffe23ea74fea73e2336ee94d7956de54cf2d3d9cf7e4e13aa82e1d54ec9694aa63a26add9236d128dad4ddd2735e5c8be7bacab5485955b513aea59eaed55339ad7826ee4beec253d6eb7389712a31cedb5fcea7afea32074715a9eb97179066c766c5a9288e15ff52d361ec26e78be9b159695cffd2fc6cfeb2390f9be3d8fc039bdb9bf74c426c9dc454b359712bdc92676ba6b675cbd630b6aeb1b5b53508b6b6b7ee9984786c24c9ca6763e2b1f52fb9cd3b9b8b3697b1790f9b7760737bf36712d24ebbb637fa4731b6ef6bcf7b2b2eeb3acf8e6e6f4c426cfe4c426cb718b7ecb4f94731362621366fd21cf8fec334b6d34f5a7a99edfba4a5d1e63df8fcd57f929886d89262bf44c4d6faa5d096b4f436d6d7e797f94f12d34d28be5c3ffe528e0d7cfe318969664b5a2262837dd2128f2de6976636985f92d9c64f5ae2b179335bc741e6272dbd8d7290f9cc21cce78f215d1c643e0c297290f930f2c541e68fe4c821cc7f91321c64be8b8c7190f92239c341e687240f0e321f24652c647e8bfc38c87c16197290f995ac1c020799ef91351c647e47de7090f994ecc141e63be98383cc6f128783cc3f8a99ad05e8d15f8a6123494c3c36ff256a6ba71d7dfeafb25addf3879dadaed70883f1e78fb111262ac34698c21936c214e3c146986e646c842987868d30e9d8daca9c6684a9deb011a6b1071b6192f960234c6febe7c761234c331b1ba1964536e276ac61236ddf69f3f98fe86c2a9073ca6e0a89b1ec9e3a29f1add05c14ebadb00b4e500714d3101bfd9b9527ffb137b732886013eded86f3eccd7b1944b0b1ec0de9082a64e8ec0d034a503029b18226ae6c371944b0517b3b52c38730b43c75c9c1e6f4bb4f5a0a6d5e8faf55b79f296663799de7e35bd489aae3f134f63c62ddcb4ce13ccc146da2f65dfc1b1229906fff063ef9379b07e9e76ecbbe86e2fe657fc3ddfe9c8b1c7ccecccddf904821e667fed6317ffbfec614b3f98714eab6573914cdbbfe0675fbab6ee7d89bf81cd8b7f63692f6760404dfc6de68aec6dea8ccdefcade778d81bc7622f636f74caa7702c6d82c9be656fd487a5b4875dd2b1d5677d39e658f5a6e66d605ee4f1dd7a98538beaf657279967395131958dbd895f639938ad7fc6de50705a7f8cbdf138adffb3b7251ddbf7a1bd5128af72a886a2b15df53cc5e3c9441e33cf637c2fe6f523d46d575d280e21c40b47257abe100422480d636ff0b0421925c6f9bee3f44b77770edddddd8180618e12351a86620e3a345dfc10c3d02592e0e038b95d25d205e1be42100b1a1d43590c66b090470c1fc0843de0f020268c3131cee79c58c8030b0732618b0576266cbd80e411be154f65a10f2a7068c287818f9a3096450f9b7044c10dbd0963399b1ea10f236a7c846710118387cb0c8be72d3223e390a9537322dca0508e713e75777797c1096169c4ea87231731950c7d60016343191630ca41f82d8d342714a35e1d842010aeea410802217e10be72086761cb0990d2c2708c560521fcae60fd087d00e1e9842d233a2021521312e37ce7aacb5f1391f07750e37c7777770a24a470305bba13864174e5093d2e6690b053639ceffccc3b406a3a3f40a0cd3ef0a0831c0e2cf9383e7adcd8d4d0c878ccc8c46260785c43f3eada24e1b93eaedbd202b608af5e3dfc3aea125fcf2292f18f34c82212d81f6998ef594412c3748c7d0ecf902305402105264fa618e1926653cf3a4bab95e32d5a9ae6985a9a6696f6d1021391cc2ae66c82b7cc288edc1614de64ea59e3dc0027132ea97d7c1ce793771daa00469c3052654a1b56538caabceaf0c1881025108922c2021339bc3079c2822b8e26225a4c1832c5101550f0d20585145410d7984943b0a0c043029e128ed0c152470a5042488615cfc4a5a053021d223c7610e11942045ca30d9d39549849319bbd0c669f336bd54135f322811c26847264630d1e7cb0caea773f4b4452ddb84e2f483a2994735b767eeb33c1c82dd2a8bbad56cbd69b198ce574fad6b784e8a72212f08477f0c90d15df4d8cf5e54d7973c1564bd602bf7ecb96e07f7fc46364949b5b3ef944245f3512c7752b747363be18cb822c0aef5ba4904c268bc53e161945764b16ae7ffdde1391781f8fecc278304484622808bf450ac5ca5819bb2d4a416e9fd67b6194d82d85aeff4796fede772292d0bd1cb742b10b0b613a53c613bce8077e39dedc502af47e0fb6c872bce00bfcd7d3fea14d03fff5e10c403877c07f3d8fafffc872ca108f4f45242f6b44ef28bbe3f82f925ea3f009d7b748a1f00365b2da7a6f916578c177b20caf0b7cd7d719803a77c0773d8b43e1f56c697443f09d74bd8b485ce183e477757555c70dad5078c50767e822e975d156f97018f9bdfb1669e4d73ba8919d9c2c67cb967f5bb29b1bd9188b8de16d7d19b640f0f35bff48b3482a2db2acb7f54e96357c7f3a03c073a7a4b7f5fe21c93d6bfd1107ed90b7ba67916595a1d92292eeb31e299e403b6a67cce4a00890bf2231f2cf0180ff334aa9fd2029891f1b500308aa314b07738cafcb393594408063ac76ccde185d7074808291950608368ca3173433466f8a668391750508698c2214514fb33ad200c20318a4418307b934965890460c52e377830fc8183d393ec861a46f7840c358d360638c0ed0183b30406862ac5b7800c4c892ea800553d0e2780206682cd102348ca08931d6343ad862a4657460c6c802c3832c63ddc28df15b0108478c314e80f0c4c81ac1075d8c303efcf8800e5acec0b2c6194a5db8d8f2410f638d0c3c9861ac29f062fca2e8e089b1b5841523ab08da0c660c7141b0327e977366fc70671c3043cb9d9fc3050f6a9871cbe761dd3c7f09fe439f7f8afff8b3cdf3cf9cffccd6f31f61c17f68cf38cff6f5fc44fcc7d5e3397cfe09e53f391ffb98e757c17f609e3d781e9f5ff6fc28f88f8fe7afe23f33cfa408822deb05e19bb499fd07dfc177e48d55aaf99bf748cbc1dbffff481cabe475f0b3af24cd2a75f7b407c91cab94f3cfc18b648ffeeeebc3480fac07effd072f439256c9929ff33c481f568926f3f56948259b57f2f15978b9207c4cc7d6c3c7dffc8b54f261affcb02989efe36bbe5563afb86c386f639568fef537f68a8c4de9fb9a97d97cec5b1f432ad9c4fee65d37effa98bde236251eff7a16a97463afd46c4ab0bf717deb29a9e4b25704605302df47cb5eb9b129b5bee66dec95984dc9e6e9c3904a32d55ea1b129d5aff9b657aa4dc9e6fb9d66af4c9b52ec6f5ec65ef16c4aaef7f19dbd02635392f9d7cf904a337bc5c6a6d4bdcd07f64a8e4d49f6aff7e04352c9037ba5655382f1ec95974d297c1fdf81bd42c4a6e47dcd8fa4921525245b8ebdf2814dc9e6fddf5ea1d99466fec5fa7ff227a9c481bdd236a5f16fde8a1292cdda2b03b029bdde87556259a5f19560af04f34ab18ff92bd3e6e3497be5c7a6c4fa1aab54f357a6edadd27ca57e257fa5eee9e3904a3656e9cab4d9bc0fabe4bdd2f74aac9fdf83548af91bab646395645e69e69578bc12cdcbfecab4d55825f095c257125fe9f5ae3fe2209047b94b43b2d3f865e4cc69fc3c48149cc63f4356711abf0c399d9cc61f23abd3f863481ea7f1c3902a380de734fe919c4f4e637e1749c469fc22c9c469fc2139999cc60f9213ca69fc2d52e6347e1679c469fc9564c1694d4ee3f7c819e534fe8e7ca7f153b204a7f13b39c569fc4d4e2d4ecb398d1f691ed1ba12017283fcdc73c738c284e25abf0a5cebf6c058765303317ee397b381184ba6fa619cb7ac138a8b14f10f054dfe8f6a4e8f6a2fcfa45d62087e3b8d51dd62d5afbbbb9b54e02245303f14f47abe4530b6a9b856ebe787d97236bebe9c512b98ba8d858bbcec7f2d8e9a358ddf6539b4207b5354546b4671b5519f8dba1dc5b5fe26b6d591868061b3aa4175db73652dc752e6e4d04bfc21309cf3f54114ea5f41f4881b97f841f44926065121626010751abd20ea43cffa893a5b06512d3deb328836f5accb8f36d1b3fe209aa567fded14fbf7be7bfafe9ef39f98a5514eeb87b1ecb40e46479bcbe572b95cee874659772fb7dd8b7b712d5ab468712d2d56fdaa5aacfa55454949494949b5935454545454543b39393939d1262ba7282b2b2b2bab693535353535f534f5f4f4f4f4549f260e377113377113a70277e12edc85bbf0f0f0f0f0f0f0781dad4d342a2a2a2aaafb69136da24d54ae2ef234e322e00fb59c862068cbefd97ca2962d6f7a36653d9bb19ecdb167734eff30ca25866054944b0cc1a828aa16ab7e54542d56fda8a85aacfa514545b9c4108c8a72d9b28ab61cc3a81b2515e54d2d56edffbca9d56255fb7969b1aa179d5c2e97cbb596afcb75aa5a4719ada202499d5b555555552555252525252535a5a6d3749a4efdd3a98a95959595150a3cc5533c35f33a3a6bafe7d3ea55fa51a6fe80538db2060093d314b79c5d3ab2ec926b531c8173458a3c5abba9fba0f97c51e0daa4f1cf6c62f1cfecd234c50880203272a4b9eeb41276fdc18ea47736f98f6cfc88fa0ecddb3f9b6617ff91c9c6b1cbfdbc26a70d5cf3aad9e7d1ef1ec67276995daeff6c721f6532dad44e1e0c40ce017bee1887986b1f0a5c842f5bb23d307a141929b841e1d77cbf47d13e6590f83639d7df6c797d0fa9f17d60017b9c29987f2e314f7ebf77699f92af626fbfdfc5689f3248e639285dcbd7e780742c3debb7a433f5ac9f243da967fd4f3aae67fd3864fb20dbaa67fd3dc8be21bbaa67fd3664d790eda56773d24cd9e43167a60ce9627817e7e2538e854bf916cf79141ee53476b716b0c5aadddddd44aa8f54d6a19792bdcc5cb3e03fb58ea34ce6e57e2587442691d9fd50277573924d5cebff6c39f3d23ebdb47be9597727f5ace7979ef59ca367fd234c25d336960e8ce5f40282b1e78e916f0a5c643ecf8b4596cb392c926ed95e5860753d4bfbf8f45cd3ed7ce1fc5318e2f926b2a9b8083b55d3d7677debc1ef20c6a27ef7a74ced1334ad479111059628ec68ca65d9a245ca072c9ca684e0f2d43e41dee58a1ed13e412ec6d5d597ebdf3e8c657b89baccb5efcb49e54d5eaebf37799337f984729affa4f3b3448ce564bafe93a9a96758faa7b364e99ff6c187fe692184e89f3ea29be8997f3b8d2591eb445eb6ace0d8126d2963fdadb63af27091cf76d4f765375151f97ca69d37a93a8a8b7cefad6e7a96fd6acbff9494df1677529df15f4ad99ca367d496e3d06ca367fe2328999dd481712289930505a5df7bffd510fcd68b1fbee892c17ebc8979988f199a5f24f3b197b132b11818d8f8728921d862d5cfeb6833d163bbab5dec76a7dd77d8c25f6a3d75dbf676e4bdf72fffa6dd1fdd34adfe47acef64fd47ded3efabff512b46bfffa8be077ef7fd51ebfd975a369817addf7fd4bd0763fdf74720cc78043ee85a6ad9446b0567fcdb52cbe6b256705a7fc40261fe1efda3eefb996a6cafbf3deb8fc0ff7ea9651bad151c97bdb1beeffa47fef4996a6c626841cb2dd6d3ee8fbeaf7f3beabe6b59fab72396ad7f3bf2af7ff43dad479f773beae891b7fd0e01363f2840ea03b8d93c538dcded8dfe6dc9b3f90fe11c7d5bd8dcde965c367fa6191b1d9ab4b3f2ba62aab1f9dface02cb53a6aade0dc8ec49f792baf1a5b4d0c667481b0f075139b81195d60cc0b269b81898d2e500616139b898d30957a3132638f99188ceb8fc21f6f40d6d7fd91f74e440f1b9a97752f93592b38b7a3dab2a1b156706e472d5ad9064db69b9a9918cc08fe51f8aebf2db56c36d60a0e8dccde986a6c3ceceda8f5333198d105b2beee8fc2f7bf1dd59f89c18c2e90e57f14fef7b723fa33b1bf1dc93cccdf8e627efcdb11ec5d7f3b7a3df8b723f1bf3f0a9f35637364ec18b31f636330f6066665a395bdec8dcbc6449bf347a17dd08e2dcb2c1b56fbd9da21f4df8e3c1b760821f41f515b3b84f96e6987d0cf7f6433595220fb73fdaf7cb074bdf83cfeeb19e661cfb18f29737a46c690dfb37e1812468ea4cc458a64488e2d16890433671b20b74f10578d4145b8bae38eeb4135280c1a836241b2a09ba0b7422204e5f8d5d51dd7e71060cf1d2351918f21fe21d60fd51ffa7ec8fba1ee87e80f157d53b7bf0809d16422b6e5b39e8865cb9bfa44d596b2ef893e5bc6bc27f26c39764fd4d932ec1913515b52a9b9fe44fddedc6da9ccdc69735873c600e4f629f2bca2aefba12216ab55148645afd758040313f345ee324533333c8a643f34bf48f643343688686868841186e60fc57ec87f08f643ae1fa20fbe92fa4afa8766dbf2f6a4b1a56cdaf279d872e62626634b8fd952068bb1250ccc9631d768cb97cb9623f8546a405b862d5bb2a8d45cfa546a6e2da9d4dccf96df16d7f3efec10ced5d5d5a5b6a45273dd96df16d7bf34f2ae5b2a33b7ad6cd227c09b1eb3c8b44c33f3f26a6c280f598d89c9843d9b45da8e21172132a2b7fba1d7a532c3e2224446dea53f24c2a512bb5d1122a3befe437ea9c844eff95d9e8db5b80895f07645a8d0db15a102738b506951e94bed4dcf66112ae3eda7e2ba5e848a77dde6f46c1669eb47804c9fc8e87b7eda7d5eebf96b6db15ccf1f82a14b7cfe1136fe2bf6fc31d78589bd917763de68e60ebd2e8fe7978557e689a8d0cbe38de89d79a3d81d12e1da1019c15cd91319b52ecd1351f1aecd1bf5ad792222a3f1fa7822a37a7bfccd1bc9ee905f1c2223d725a2d217c736d7e61b7977be0fd2b936bf0749b936ff86ecb836df8664716d7e0d59b9369f86fcb8365f467a5c9bcf830cb9367f8604b9365f866c716d7e8c7c716dd66a23d7605c83e1da0cd764b816e35a0cd768b826e31a0faedd70cd866b355cabd56af3917c4cb7ea26a9154859b1245585941452725f4460031ee478aafae28a10b0ae48828731368e35a717d4000c28a83881162fae08afc8218771e6724eaa885b8eef6b744edd690f358c327777291bae63b1b9ffbbbbf70da3eb724e0a861b5ece5d41c7ed2ee7aea8aa01581241dd1e21c18f449090107fdb2877fe5123cd1e01acedd34dd6f993e79c64cfb9022e5cb8542e5c64df5812b9a38f7fe3e0e978f6bb9c9e7161755688e77a9ee7d93f03acb4769de75531c6f5aa80010c150b1876f0210926a82742d0c515705cd1e50a29afbb2e2d83c7e58aa4eb793ef4522b1db9e08d29b810e38c2fbcb03117ae250fe74ca29e2d5e688163ea06343eb0851561b0ac30e3035dd7759d155bb07458baa2b5250b261e991552d430bb12b028a55356f4205af154831532b8acd0e1735070cbe7f18cc86d69aa62cb16301a872e72d862820f6879838c2b1b6dc1a53fc271691572e8d04ab1cbb92d465cf0726e0b102ab83296fd749bca7f3c2fb3ca9b534ef3ec0b1eae8b6745c5349ba6962a4f4c3cfef37d7f49a47b1b25df69de5447da34807ef79d7da13eb5b10d9ce1870485044c9bf77d47ffb347ded3ee864403e61b245801ce569ffeedc8fbefab3df2fe85a3cfe25c0c1964c1d9e8d3eefb65fe4343701cd94f651f71e73fd934a07befbb299b06d0f79ebe376d1d3992b643eafe3cc0e33f6de3075f4f77faeb5d4fa442eb59df302caa70ab475a01e20b302f3a6883bd5b2414a6c2bcdcf994eaceffaa5ce6e9cc53d807f3627d507c5004ad4d3fab71534e9b0fd3c5a6adee7c5733b55337b5963bbf2389ba17c1fa300f635f807d7db689301ff331f685ef619e6de0b745d2b18f817dec5954e1fb986f62baf3452d777e8cb4f11ec9167bb02389fa55783debfd895468bdebfd871a70033ffcd737e026fef8ad07a7a802eceb4f5185ef611e85a4fa30e1d787b136f4679eaa386d3e8cc4d9d0e974e7cb58a8182975e7c790365e54eeceef4652e634a2a27987868814a0801f2252c1a601ad7f7dab9f48059b06bc5e10fff56c83f9b648baa70ffbef41d8b3a882f81f0c09236dfa916cf5412a2a806d49ad7f3500fcd6b7a882f8af175508bff52caa30da97b5f1774d89644856929dd6226ddca2c01d42974ada34928d9d763422755d5d0072775227c5643763cc47d9181bc7366698819513d440b5851646884ed45063e3e51c1549b0018eded9efd97432a767b418dc510618531da0428a2c7ea82148a25688e7765dd7f97377871b556429430d2f6164810596ee061afe676b7ccefbcfe83f9ffdb276dd8fb8ebdd6ee9765d47ed1af53f27bc9ca30204b77c9e6e066f94c5a8e8c0951e65e5786354d8304367a9b8b2e44d41b798428c18a618c30a8fcbb929d0b8f4726e0a32b8413abf2fc3eb799e57dff33ccff3bc8fa43da39ef7a3ccfb59fb08f15c5a1b07907368bf0da57d3bb8f38914a07f2ad5cc9dc0eacea992e7ce1c0a7077feecce2a140c714b2377caeeb4bad4fb3ec08ad50c99c21e1083975bdbc7610f88c1a9677cc1c9ddaeb6338e31e672ee04572e4f39317af7a5ce0562022f2935c11b9732d9e8c7fa87da28a5b3ac945213b07129a5fea3db8e83cb39135c71c5cb39134071cbf1697b1726f0c10447c891e3e58cf096cb43faa7daf87352545dd8e59c144997c5fe233ddd18633fffa69c1d19eb99900c9c88c1972b1a8050818d5e71e98fb92a2efd9bfee11c0e8793c1463fa77fd8466de95688675c63e45b8eb7dae6fc26c79813a3783907051cb77eb9e5f828005fcc3e77a6902f403a521b92aee58ea45c73bf8d9c7ba2897291eefb3b2e22c7954d27e9144e97a7e8aaae3f38d4fd34724e055d9e6ec9530eb502dca5560ed573c7d8cf391574f1efa4fce7880aa09ac65153b92e5254d75530d534be65e7e5fa774efe43a7a895ffb49414e788102969f5c68e366e8a8bb42dfa7ea8e8b3fec435ff69c535fff9d4a58318dbce2f5c73ce498971cbee72fd5b88b1ac01e01f87fa1ff6e11f0fa54da8c4a9150cb4899a041d536a06680441400353156030482c168e08048a26d7f80114801098b2545a9fcaf42888814a19430821841802000020002030334c0002449b3da1f71f290cec0d6a2eda91cd9c18032ff0dca5a25b87109f947ed71b47ba08981d9bf2eb8274611b9bb453e3e7ac8da1b052cda092de2ca54eb20d304da0082804cda4a1f3c20b1db431f06a0187aaa837b4efb965f92729070114f4bcea59b995635e6ab964472cf4a36ab4b19709c2ca9de559662a421ffc529d1a7b238b3f2aedbd15738daf14666fd4f24795bdb76256f795d26a6f84fde51b60d7db9446a2d08e90226a9d8d122b1a6cb88ea4185e8ab8e828c0b547bbd13679d2e8eb62008f3df7c003341b2a56a1313c5bee8c133f55ef2b6be3a8f64de1d95bb8527d6f859fb221f71f6bcd8b6c8a9d7e5ae19cbd1d83b6ef5dca812c912fb71f29ccf63e3881fc2ddb5d2cbf8e2013a84318cfc5ea0ddb63bb22e7865cad61f213d625e0059b3965d0d0ba019f1b9c8f463543f237858748ee5ea3cc8ce2e9169db250f69c42c4957ef25f05bf927d337805e7a9c127a68ab304437b4fdf1cec75c4976720c5cf675cbc7c9600104ec31deab1daa6da90ea2e68b2d3fb183b47fada1739a348859ad424dfcd9b5a51a636050bdaa24005bb3e09d32a06af898c3ed46bd7ac2df71250bb69135da4b3230e9a600952a3cc8dcc1ef833daf8af458999fb360a2a0b55ccab6b747098d712665194cb54527b1c476b4e091333379dbd6d06867ef58142c14f115b2b940d25b4d25e5dc424683aff6af940c398b7e6d19b796ea7247d57f6f1b29f5a3042643962d66c46aea38ee900a581e4719715dac6a44d115c8616ed20a5c64ae32713d2162995829cb618dba14a67e654b9a7aa0ad972cd3565b969a3ac543a5ca6a717047923c352c8baaad3acab74ac18f070c0da4cd214b5d89b3bab2805208b9e7870c36ad252ece6816850c9a571009a29569705ebaac0e73f4d13750b574673759a8e009465223fd72f4de9a84d861936f12ed4982c4395d1424c35e51c48136a3bb71e1d79b70b521edddfdd699a24380f1faa9b9e956b7b3d41859a768f66a9d89e720e4ef1c4423e57ef896749b13efdcf6ce9e1356c06ce10e06fa93e1305e565f67da0669b831e088c05fa2f19bc2ebf67657f7d691c9ce87d1f5761c8bbe256fe5cb3f027af104fab7322ded5187c0c5e42ee42ce8a270b5b252e3f050235054a7b7bf28ab5bea6c6b4f4964b56e2cb65ff8d2cea2a8a4b3f71ed05c0442127b2aa9aa3d5949d533991365698308826d8568c9a443f916060611e49de48596136deddaaca8651c4e1c762906a01a1b40da9f7888ada2ba960e322b592daa3de0455ba1582813a54d77f8d896cf131506088a9bba9f2e218a5a46f5ec66a4faf1697b1753c30fa2d759189369d38b8d6059246990ab474780e435d3f1772b935304f056102dd56386b9372ef6b781125778254d44995bab3eda025a1b15072bad43cc1afd5682b16ce25195ebae8309c013ed5bbfaa9c7820349259df8681249971dfd2c01ddc3db884b424f3a0126be38a999dec88aa3d05b904b4bd83d2ee6043c1d394cfae52f77a340521e074963371f336152fe576a72774a16cc67fe0188393e5257b75f154c9409184dc7882e8e76c44c617f8bbe191a9eafe4d9243cae15e21df29d5863ca452ef3245a288ba66b90922243c5425aba5c8c845af81354dfb276445e7638df27521ac547dbc3cba9a395ba982649ee347c062f49167dbeb91b7d93f4daeadffcdf3b893749e28ea96747a2251dd12dcddf32d81258ac5e1626fd71cad511914d5d789326ef8c6c39e122d373d120c1974946253fc4bfb63eed5e467fba65f46440959dd836ea6d27bc4a21e599bf34788ad8bd92bc90f8902deffc3049c8b70c9de0629f23c561da895c73531c7471978f3e349ec1402aaeb5a6420bfec49334613ba38eb3267466eb8ce8d59adf4b3e7fa89e2274c0b2c1d5e34047f6fa091d695fe9d1064ba530cecb62fcef245c4b8f43d09f1cfb284d2456bb7aacc819ca1888b7dbe2ca0ff83c8994bef1da1806f9c27a7ebb01f4066e489df2076af97793f05fc779fded8cc8857e1fa2017d627eeefda020eaf90d931dea0bf2ef799e2b75c10b0f8c339059b86124a8db6a81dc435fb43b9890082202d636438c8a86aba073f75df8e3cb00f25ec6f0720a6cd342f71ee185cf3ecc02d4534e7487cf64be6feb6ec18d340400426452f811407ee619e2f0a440bf0d20f1252a42c6506345663530c1585405f964c212073a6ff8b86b0d61a2ae9c0511f5e57ec7bb433e6514688a56697d15b4c70ba4dff9ab8ba44f7a83dc758e4cf30c54e781d89513d83d6c9915014b882ac53f346c1c4b54bdb424b3db0688c95498cb9cd1f3912197cad54afadd7992b8f40e38baf374eb32a5e899740e46de3a43a8f39bfe7c9f77fb734e886a2212d4c175032075d54e4f44663a096901c81b5d71042a0f83841fc18dcfbda063064b2b09936097c6d75db9116b120847d2f7e01baca50e9ee5276548f69e0b460954143ed52ace21ac28e0c83f9e3d68202df581b25a558ab3dea6f7903571f32706ea6f46e7d1e53f6d15283d8ec329093f492b9eb51e5911020f4c6275593de84cc4fa54886d513dfec010bf4ac8111316299d70238b13cb64835f4849c7656d2e0a85cbaf474a1b9ef97cc84dbcad93e7bdf19c407ddfbbdfcb660f84cb303a705bea1c8ca65fb7955df5a2799b464b5499d4ffb010399475a9bf24a1a5aa03ef2c7dd2742b2336842a1b2c0ad87730a7c4ca3f80e15e3855f446d650449477629f313c4f6fb4a4217a4a3923e2f24408ec1d306fe55d3ce2f2f74536516422b51e0064cdd56b59be5baedd1e0d3f181055d0133f7cc1fe93eaa5410f74a11b148f70902a9f4e2676a6b4ac09fe8adc5f2a4f92aa5b8eda56735b937214772fda15e585d2c2a28777e3e755039e14322c5e88726dd471b446e35431e4a16d93141a72c3cc5fc1e0ce7731033d8ed114ad8b28fb8134a6a282c1fc20b6c5bd8caf1dc90d42bb6a4b01633d71b7b117faef2ff0a21c6a04c3e80736d1bbe6e843733cfd43091f91d2457f54f5355960682c21079aa9029fd89d215e307f6a4302057a57c42e62e034e52adf29c32f54f2d3d99d80053b9635ef497c564f733fd658c2b2819f189c57e9ab1ca23f1f2edf474eabbaa0371d966c29c6a30ec7cf09e866b7f88dddf0491ded82d9750976336d482c070633bb3b74b3fb1bd64564faff999dc059947cee8bc9d7815955e5e7a395c65a9988e184cfa2aba11d7a67263257d80c86466de8f6608bbe5ce27fe78cec69c143a2f2fa3064b76765d5c5d29e4f467b4d60793bfa8711d61bcd37bd612e548d115f7e3601fb39192e1fc068ec54b4eb8c9bfbc03f0d32c346d587193b8ea03f89d7c3b0388800ce66685019b0302d438b54cda15e038f79fc73f15bba5e4eefa3854b37d6ed5b9871a4c68d574525fd6e5007eac2a7ab425f0f09b43d6b8bb407bdd007d57dfec15cc52977cc66dbd6aad4cf6ebb25c7c66c7477729dbd1e4102b4911dfc436e9c29b3aad343aa41ef334246749f382e62d8d479cac350015db653088a4e93b24be39fa1beb8e1add7776c9826d28c4e8a96d554e4e62560277dd21e413f73e700c1b10e90a442a210b5c402d206d083c21b9b9a166ce94ac1f82a51040b1f3125afd009698a7b3faa49f4758298e68b352fbaf599bcece122f88bb819e604cc23088b88bd725c06333d184a2fe4285c4adb755ee942c78e0dffe0ca705cd465f6cf41406053e51ba9f5d14894bc014deaee964462db16cd2b60296041e8c4028d9db38eb6acb9a1451d6f72e963f8a96bb4ca7913b7e16a174162118e1d94dcb0593f660ee859b9736261b26643ce67ff9f7cb76152f0f222db9042a421a9d4b642938423414faca9aafca9ac52a4e42fefe1fcb3a9769c4daabe989c05ddc21873df5c3296475701c66f8e8e05e3e4626b0bb90c5c81913b61afcfa5bed9f78b5d667473e9752ece61a6b78bbdc0c0f572d765d9e2566c5112dffe7a7967743bb8568337ee2c091e2cd153c350a1ef642ca8e59a70b18be35a73b227334de8796aa5a5f908ce82566553f0758566843c57684a09a19e832946a089080e73ec42c0e15dffa5d3fc3a22ed6eee702894ef04c694441d3882bab5e3b19b77bb39b9134f94c88af0dacdf39e785c32ce9e98219758ee795b329c4a3283c89609c765679600e120e0da74e43590531452a8370f7acdc890af227ef833ed3f89dd90c8c4212c55c15753ebe2d2d9f8d70034966d14f77a869443d5e7dd4f25387ce285d9fe78cffb02122ba74e6ec3d7316672bde6f746497f635c08deb205c8fba9babffdf05937e10c0ce4b7c43971ab6ccd20005665d40581912a831504cc53d99e2078a2609b21aa271506b5435301ef04c6d6457862dfae833c81651b0f1ba9dcc52a791f2aff85393f5d68a7855ab398698775e08463158fb97bbf52eb4ee24fac01c1a5354f3d257ff4745dd952081fbdd08ea83dcd92f6ae1863a07dd78ba04d4290fed64b1c6014814cd81c90ec593fd8fc8c9e66b6c4284518ca65711cdf049454e5a59a16f34e93c1fd23c2445da0b891957c66f9b7466cbc1fc32b0a382351bc5b631b89834eddb2a8d35d2c4f2261733aaadb940cfacc87c0403e7d8ba238d3f1314c24f4941115f54a5041b2fc58816ae3864ec399039a91f8502577fc5e9918a5c0e752ab49da983b4b752de08a80bf1d76cba9f556393aa8ee96a2d9d76f3a8fec390782b9205334370d4f25d0f29510e2f471c6684044fa496ac299c91e9cf4dad132aba8437a109d4b188b6381dccd4af3d725174dbbca4ba552a85440ef9cd9a2a2ce1b0658827443de4eb17e69e3ebd75c3eacec4710b3ee4c188d391abb468db4fce44553bfd415f77672ba125a64755f54e99547dc8ca391131c80eb8b647d9f2b18d07b17d015be5927b2a40a66bbdc312e16731e49afc6efadd90b887593c8f0b8ab7c48a8837d2918e7b9b2ce4b12cc5211481b78b474713c641762d99a8aa0aa5fb258a62a393fb6320e78f168251db5e5b57aeb0d02ea9adcc80d00245fc80b9b1000f99ebffebcd30bdfd3fe403aa53a590a57f94ebb7d4511a1e9e0442465b695f028e6eba26cab08cce4bd653d01a2494db4487a3dcdc294f84dc59c341ce6f57c976863b57e1c376cd23fea5c09ae5ede3444c64404597f3f3700f12dc40fdbfcc89cb974adddc12545701f469326f207c133d0e620693202b01a031c8f102835953a465db484773104294f553ce22e39a560466b228950fe8594d689cadaff46a6b27f4e6e6b26313ac6365b1a27268a86e41bdb58d392abd83920819849a02631c279e96adda9889d39e3be786535a4ead7082aa2641d98820623ef3a77bcccebe6adc609d7d2eafda7efdb410b95844a8542b575d27ccda880f4c430f8c40f9ca179b09fff92163c85214f868e9a91fe9dcea6fdc336d507b73aaedbf3275509a8ddea008f3a04e5847b6ae6b006c7b4655231cc72021e81cb57cae946139c848cf14f3eac4f842b16b066d8e2354def71ae1498e3b6dac3375d7f1653a41de6187acfef508754220543135350ca52ba889eabb99aed267c66d7a7627acbe02a279711a81bbebaf5eae1c9133973f49e66f9c6835bea8ee90033c0dcb5a3dea5ba9d7c3a65c454448d6eda84c84ecd37120b0d8e18f3bf1491ae04dc9fb8a980d92486aaa7ff1795f166f6ce68079ac865491a2b63250b5eb7728acfc0968cf9f753ed242c871a6a4d98c43393c93d281ecf57fe38bfbe7df0bbf3f5cdd764dc7cffb471273a2c76a9810446a1c374f97bc526978649b85703a35e6a6e02429332ac0d99f08a41bbea26920312ce7a72d4ad4bcfb2682e1d1de0174d36aa0d34abd484d402463d7916b493b31c135971183a4214ae08f2ef4c8d5b16e2ff523225e1d5e2c263d71fa0b1e0e2b9739fbc53e46261cd3e6f7430c2baceab7dacfa6e80f3c78406efc56e47a642c4de674c8b5d7cd35161e98669cd281daea8be38ce44a3a790012e4e78f2da5c1c0ac58c0340db48d6e7a1e13255ead70dd2e4a27c4d3af4bb7a517290d679628884204515a079c8ae88ecb4681903a942059fb88880ddcb8d47415132e20251249bd05aa612adaabd5cc0832e680c9faef141a7ee4abcf6c5613159737bc49cd19fe629a5f1be80b35cf8c79d78d591a96cb121569ae5c61df116e892e4090bded4b1b15628c1f85e2831f5414c8d0aadd23e8950c7d3694885a57ace181a0bd4b93dd6742033b4b982c5cce4c66586c3f3b1f682a9ef939a64b197e260b6c5edfc670847719916f30c7127d7b410344119fa2c0af3f72066cae9a77af860fb5ebbce040579efc9174301ef5ced5da526b5f20689a7905da5c733fcb7f638ffe874cc977a9d16eabcfd6f82734be5bac2249c28ebcc59e54a2bad5c69e546c0080ed310755e92eaa5a74d9537f8921efbc44ac80fa2a7775c46ac323495bf245eec0a02e64b99e2e6f0acc6f7a2625bb6d81124e2f7c857d09d08c9f065f0d70d78e3aabf2c8fe93268e87915e7121768a0c5dae4a80b502002d86d462394dfb084145326330cf6ed07196d69bd5ce3dfbbfbc629e78ff792c4071317a6dd87cd79fab4f436a6ec909a98233ddb29e058b802a16b4c66d537bac5c8aad17412ae3d0c3f3a4f663dabb21d51b393a96c23e41cf7acb5d10044a7e8146bd97e9f43dba6bfb67fefc076d7826dbf2fc01672e0762c4708c5cb2088307d946e52d7cb124cf662a0cb003702adaf04c0345175b811ec78bcd83989788f4e1b4389789fe4dda5ee4d74da8d54fbde74852312ea0c790ec4ce2a98a419d4b735def0dc3f20e6c0177c1f676532c82487b1d5648541255404d0cab3c6bbb9483628e098e6e823a18406276b89152fddabe3ab79a3fb063e06277a710a31197a50d815da9ba850d8633da651e85bf2945d10f58d559a9eb2790fdfb65c841e04bd5afc866cfe55bce1dd1738d1d2526e04e7fd7e59e1a35302c3511cf560c8fbfd080e1da8b05137ebb0e1ee3afc97bf49fc18031abc78bb60536b59514be897565860f2b22db46d52daedf17e0476a962ca623042a2a79ef79b8f2815258014be8610c01b17c89c7a5111ec4bbde5e67255f7ff18b4ef6a23a5e2be22186c1256b5b985809773e3ed2de021e8354add2140e28e298e31c7b19feb0c3fe768aa8c33f9ff2c6895f2fc12c01713c7147e1ed5238b6f429e70f6dd475e5f2f26645005e23ca1bc15f2872c9f985331550a198863031a98da57103656a596bbec59350157ea33a60d0428a78d711bd6a807d49371cc728c1abfb8a6aae18c34d0b2b36fc0533f4c929d6d01572763904996ed490ff3f41c37a44fa6eb8993050330e71b5463223bd8b53788cf6f648d7d2db560290c1051e6450723fb978a0c213f0bd1af931561c271da4881e8397c02f79b1a75b67db28d6f6f20051bdda420fd7c4612b20a3cbf9778f96301c4a70981940a072d2f16feae28627b44a64981e84bd589c105d1406eacd04b583fc2d78b2162e5c2b6b32026ca2794d38464d52211b47f2101ec587dc58e470e0b8bcedc70e31f5e02e2ae12d31f99fbe766657e943ccabf125d627343edde9df62e9de6a5b5838121e3f9fcb21d66a893986b295dbb78e95dca72a153110bcbd2efca9f860203b717b06e1b2a2640dbd133a3c80d3b7f474f176898ceb2b2772e0dab1f460367f61d11795fa715b91d3f17e507b47031d7a432bc7861d1f45db58651491bd0fd197a30a51ffff9fa2ccf40e934aeb4dcfbef2fb76d4e74c7233840be7bb858202832b39cc70328959c10045cbb234e06a2c1281acac44e7a2f84c7f7fa30f4308bbd045612a72f1377d55dae2ba29ef36bc95c195437c1a2cc4313c5528f6790c9120f38157128e41cbf10406a72b85e0507b7e1228a3f2a80e6b85d29554fb1872046ed90deb2d0e170023928856dc52f3671e60d928cf63edf42886fd2d4bcb17359f59a07ce5048edf58f6fd55965d770220ce1fafa445a0c11ddc30c271540d3f8135d170bdba4ded555d8ad4b3534296f2b0a762da4bea83d60d89373d5c742bb07c4cfb76c0b823edb23ecf1871ed27300461a3d38e360ee80d2e338fca6ad682b06481e8e83888d758f9c4f37764f83d8ac023944ead7e0a5664559e8bab6451b120d42088dce7ada71cf4a1c3bed6fcb48193d39482b288abba24643bcec7442d5759e9b3094c52dd1a1390a166713d6a0a37b3c7350481b187e25d71cbfc1feafcda1eb22b5d8730dedcf9be91adb6ecb16144a25631a496c5c66ebcee41d00b4640003eb9b1d394f5f8ee79736e2929ce3791b1cc3df155e6dd80b2bc7f91ad13c1997874e15ac12488acc3f4b56d50582f0423087562b03c5e14cab16d17910cd795ed4c93e496aec1c8e42b259af81988b6fa1b51a5e488049e14d63290d30463343ae3cf120486af08f1c0f37fdceaa01ae14858b4a7b33a1b33c1a12588bd226edc4b4b9e1950f63c6c1b91ed74cdcf08498cac054231dfda990740021df3369b6b917e083f70bd4650c5f4debbf50c304c2c02920f1ff289abb20c24c23f22a7fd0d09b3913960cfa389173cb50b1f33181fd6abcfb34618c82a073353a14dae776fe127aa44a747296904b4dc0cbb7d2462e042552d0f9a7770e103a780df978a841f8cd6e4d18a91eba4e27d15e4e2bbb5fd1ce94b332fc4737a572399f759f2d2de70d92bbdbf391252b54d4f9d2a85d6aa832c5ac0f259bb6e013ba2f6d387fdefbe287834c341e91eaa162ea5470ea969e6aeacab5edc457b0bfcf526f0be7d998d3acb54876ee31fe93b885ca08e03fd1101a9f6283b664cd8b66f7ae81af8c330f168269a3a00a2c0835be103c2365db06607e1b80df50733be2f24002d1af85080efdf2891ce24b98475708d11c44a9ada84e8ec23e5b6540f76a277df5beb0078ff182e145082c0b48e70b745ad2651bbb70bc8e4a44da8bfd261341f8b1b9f0eff3f5bf8f4cecb0fe8637b6414d0fe7dede56801b0c153b3bc732fe6905419785c47e72f5c74dca782f222d82c987d84d46c3f83849577f2f1312d9f7c43231455d231806b26dfb51d8ba02fa1be8a6899e3eccb2f5296a1ce3657f20cd4173ab6d5c6642f29621cbff6f5f3ffef84151fb5da5bee1f5de807e861ef139f4b5d0c8eb07ada9136931878d4dbab9de4a8a783a8672f17e87d089e3d744b63154270cfa78a78fe1cfa704129f5fa478885f56fe8e6cd20e377c600fdf148f36798aa837e0bc17ac305960771d14666f739edab5822869e9f5131173b050a24d269c7bc12eef2af6cfe83165b10677ec60f740aa0e14e8edfa28e6412999eac68e15de1d1fff9b82492156030b289ba7836893213fde4d4ca4d6489c2133a8332edc8f8e483452c05ab127846b65fc5930b858c4f6fd0adc85e18fc675aeafc65d9b9ced088ef36a8602b422833128d4263be2cf94612d8b6809da3fc68f4611417b55ea332ec007171df88497c2d16f589402e30bb79ed859d31d9d83f6904bff7f2431e7120b7517bd94dc57fe1ccc3965094d4c8e8be8a2e5481b575cc5ec4f76122c0318b34f5ea50322def9c366a9a9956b9089d7326c330655b82edbad92b26b29f2fd87ab40b833cdcc711dfc62f9cd7bf9eb0738d4cbeeeec7ddd4b6015639ebc1f7d1c01f716642d54edbb40c3a5c5aa960a7dbe6a063966885fa62d49b28ea00681281ccdce548ebfcbf26e751f1b299a8dc3c21023195d54d3347bd3ce61a69da8605f89c6d161737efe6b5e527544cdf3827f3e62ebf33a7d7520031b79f3b8967ff40822c9467bda6d2bf3c06b0e5b42791c3b04db66ba7aa48f10424ed7cb763ab0cffab6af5e679af3183869c74b4e2f63d2ee48f26712972c2d4e1e4849dc4c75f7a3100f5a165f5e15697dc70a5a3ce1f9d3998e8ee3e110c87ef83a5fbc2a20f64abcebe87293ac719fe5b20ac2afcfa7dd558e9be395d0d972a074512b12391d7a856e1eab046b1542cf803f928923f0350a1d76efe4800c91d65eb9659b051104f7163bedae3d2157fade540eccb48e49522780ed91c88b4882f1e6d5a9e4e956859ef320223ea68a57c7bb565981bb56086007e70335f42c08ff6d1ce6a24850a91251ccf43e9b9617100fee0f149ba9b3bbc944eb403286996ff9774228e77b6f9fcec469e0a3704fee9f7077cbef9c3e93117f8cbd5d915b3c53ad34a76cc7decdc8fce33cb69fd1a3db3d11f9963ec58c302e7288290b5a3614a0be453e048ac50974dcbcf9dbae46a11a2d01ba9d9493d386007defb4108f7504d77601c4925a6daad1c5363942e014ef97b2e7dc4a6bde641f4abcd86c5c178ccae69e39aed0f09980653a7d598a67d87587c06110e005a754854af55ef79fdf2034e5efba7bcfff842e16cb8ad4f524331a30ed6ca4b7d121bc637b804f90307a5c9175644db5e0917add4308549dbd5e51a4b45a208df16be7b50dd54e58545da5ec79bb82174614fea40bba4e5433357ff87c143611e007b7ed55347838820b5364dfd7de952e6fd5bfb344420f8ecf3370f611f1b8ca86c9f1dfc5151f5c3b3de30d55ec60359d2292e926c6a7595f5dbc7300730539f47274c2ffe43306cf8ee6bb2b18693b1dc4095bda26f3360a7d247ec03d03693849c8e3f91a802bad6cc4a9a4620f93c0d3e1a4c744c6cccc1d7a9e955431c43649497d61f3d162d53379f79cee4cbe6bcdc2d61751f09612519cae44ba28c9d9c481806c777a2070465aa43dc7b50ad106e6dadf39cd189d95d647b22a8ca6d931d7cd4da0bf9fe28cc59e705ee3a7e3368e5df8e746a0540ea25c8e769f6dbe1d9b5ece225b7c796066500bf6ebc057520700e429d65a4bf05bd72cead9948242ae7131f21941a627a08c6ee5635749207777ec455eefce4c13a8e956b4509c4a88bb6d7190c73399899730719b5c97974cb960cb578e885a1e3d1e1099dd25a1565d2e3cbce28987d10a8a7d9125c41f0163c50d7bb3bc7eb4a9bec9cc4facbcc08e202dd50f820bd081f446fe007d35b7c60d01b1fa136a46e92cf79aefff226dc939b539589da8912f1a6b4481dfdccad4b23ee88ac7312ca70d9b3f2073aa1a579d8fe7573bc7fa2bef54c696c6fdf7e78d4519e4c70c0c24eb83497faf40dad191c6e70faa3e93ef1d4c0b9eb43ec8716fdaa9ffe9f2dd04c99625a72e36f9ac234b0b681f406702964653482d682f1f31fef22bf1fbfcc0abb32da30bc7887cd6e1080f2d610fdc3c070a05da2ff98797c02832842b37a31486af908247de748b1b685700e2429d718f46ca2b34d19be94d8182562464ef17dbbf66dc9a516a2ef0715879561d631f86bad67db5a330f5d3143db4864349b4e5e439e6a145353bfca7928f2feace6eb5e4f935d923728bcfb8b800028ef0487a83fbe1b680b9a91fbc49d1847f4b0bc6d1d810bd1501affba3eb024258d5b681c5257f7bcf598307101af3bb497916507da43ced9205c51360fdcfa0ec6f9c3d6907a49c3944942ed6b1403321c3f47189122d85e842c1bfea28ac0f786ea654cfca4badd50bc7521af9093e0bb0ce3af8d27af12451912a7e03f9ba0884a04a6f63c436d3e690703b53f8016f8b6c884824a342b9d4bd811eaa40f474e30e1c54b7ce52f91e860f07616aac89882820a69da2f20aa2f5a7e48b6ae869c82ad837cac55af7c9e5a685474730c7618be629379d8a54b4bf5d6354c2dde2d975fc749a699de5bcf32dfe13e06054df534d6608db699e91390cb95e39778d8f185a045c9a6ded78cbb8bebb23c9a1657a9b4865c78a40a224b6ca1b7e087d0ad7113b3ea9dcbf4e5c377949d01abf2c32bba86950ca4d43aa3e271cbfa86608830fed8589fd5f57021ecbd1e54da6438a2454ef04a642a9fd42f4fab6590527517b7dd68956e86bbe299359914199efaf4397ae386da63f6c14e4a36c81f054218576a384b5108b23cbe4cac271234053799dacbd91adcd74df345dce2345c3a9707059cba4dca3537d37ee0ea4cec7a8fe6a79446e06814c687a9c68818f439d39aaeaebcd3e2cfe75774397f32430b66bd3877911495c0b90ec1f01cb2451211e8fac316c1084aca550cac2d1cf43f788f935a21c0a17b13f88290c543e6931996c1e25e5f1cfd818d68f1d718a14012873a7568e4a9c3ace3871dc91a530c3f8b3c08a115bbc421eedf719a144536195e12bdd800777f408e6e9aaf1d3b1b0bb87ffc3c94e084a0819bd9d3abf590030552b44ce0fafb924615dfb78247e8c7fee88ab90e7e2fb0f2f3d0369979b5e7fa727d6eb82cbceccbe6c2cfd363a489149a724e02405120bf626e544ca0fc97abcdba3054a11e20cee642794a24f5032853cbea21072372b64424a011e0df224280a169000737dc72ca147dfb1449e13e8e677e24480e70a695a9813dcdc5b1e3b94335331815de9e233d6bb925f0d7d308a3643d99d31fb370823cab57677ea5ad136b1b45c389b3894ae5f5d2f3b31d2ebb1e1d08906819b867c13fbe7975824bee474b0ed6c4081ae26e36685abb04e98ba00838ccb34b2f802a02014695e898ded7a225c4104411f9f92120a301c48795bcf49412e8bdce70dbf5198df4dc5113a9d52dc7ba1289e4b06191ae36940f6b13dfc92f6f18f669e92e0c3d5136c18859daa4a2557298b148187e29d8705f06809d260a3e5f676e2316ab31df76b55d641610ff61c97b823ed61e45fb25b89ad18d96d9168c1be55674a901cd7174e0498f1a1959721c12bf32c59a6d1b0b7acc96e006f714aaf451669379fb9637e82057cb1e8ba710c43ed117efddc17d4b67ecbec195561f8d195d0b51a654142b29848324853cc777a8fc1a561382e3e232004670bb3cd56762ae8341344618d4d47208f9ae5cc52718b08f889da9a97e06a80f700af8dcf73618428cb7379e7c5b5052b59918b751a4f32224c61a66047a9d609ef5cf7252744b2127b7b0dcd7f4d8d13419201b06df235b024967dc87a922b4aac44fd1ef94ca98805203aced89ba43710323d67c2ffd03dc483c224fe43dbadfcce5aea24ad2bcede482b31e9ab7a13b324162d56635f5aebac9329954e1d1636841199d58b8b0842b667111739611d939f35196b8329c0015252758e78be56e19c3f1d6e7b73d4973a07edee1c8f31d9f1d20c23403b2a69d1afbc501a68c5d04a537f5b6f7f7d8170edf8dfa4ea72f16891514b5d8cbb41345bf16564761d5c89ee29274db5a9a08350f6a2952bd1a9f8631b85a59ce5d056e32625c6c658d19dbc973c83bf165489269f42f7c502bd3c52ebad09cd44b8ab5e1762a868c442724e615c2e6aabeaa3e46c1ab7e6104a9f8312b55e914184f51eface583add07f9da6228d3b514c31ddbaaca1e2c5399ea3000df3342ae2ce01dfebf17217421e038494c4b3f8a52cb91b36c77299fa336043a349a2a5f5d4896a244afe4726e94f2f1cd02e89a8cc400eca22979c08e8fbee7aa0ead455ad470eec33fc85211e56fca0e18f50dbb16823a543c0268c73bdc87d7a13ad4465e7599845368875b45e64e77f9ac29910108941c4df04224bee7e0af26808da05b6f30a0d558ff366302d5b9441918617386790e390d43dd8972b5025c6c003aea8906482493b7eb6987e1c89e66b4cf8d66a6432f225636563d47896aa06320b538703bd7233d2d1529cbe7c7ee2dd4423412b1455299adba9e05be87f440f5e14012d7e44c0a70f243ea516758995fb4641dad229c4b2df55f4ed2569830fb84e55ddc040e7687690240734c5bc05981b9d3ac122aa490e35b08dcf2cb5ca0f9c3affeeca04cbdbedc41302e1f76e456709531f609d1747f497efa36735819d20bb73efffac7e9eff52b0b59e4d3378f92827dfd5044f3097f927bcc27172a13e535873bc7ee971f36e2991b3e5285ca6d09c9b166b6b2383a7107018ab6b541699593207c7925a0c5050de446612391dac6b634082cad3711cadd66844153421af90ca6ec7a352020316d835c08861f77717622817ab926a6137490c2df60c003e46831b23ed3539f988fd966b029475e30ccfdedaa30e92e76fdaf4b1ae25e58bc6623d7b0929aaeac3d7481d9575a46aeda762796905a64186caeb0bd257d996e9fe03c602b168926d04f5b3968ef45f001c25311619ac1114e23fd8b1f382abdc0b49754ab15076aff23f4159bd0fe8d8546f24b812f542c1fab63a0b775563536c8fab6282a5450a59ba64521d033718dbbd107e388c2a55fd0e4711900eb7ffb18f10f7f17ec0bc10d484c1f998edbfa3218494f575857949868393238dd66bb50341c84409381a5c5858a3090a9a5e3b58533aaaedaec495607d3fc465dbb027d826ee187dc2d706a0e058902d099e6bc132daee3c5c5e197d20835cc6942e849f9fd7a20cb3c51f707a9caf9af5c11c19bb3a83385cc47d78e1191d231f8ab3d1d9e783c7a17147e14f2e8cafd98a4cf8f1f9ffe7b1de3e8fd2385fe6e16743bd53565ba155d8b4f40320b9581ece0b38edf24bdebc6ba75c1fcf395c07a846cdd367357e89fe81b277ba6c89bf63ea5ca94e4784b72e43615990f0c0d770aad51c735ee622927c9ac3672eb2a61cb3aceea79f601296b9ee528c6354265d92cf2e03311e97acfc850799408287c1e6ea83720320c2a0e42edff504fcd6828da11b30e5fcaa543794f068cbf16518f78073053f5056c69896d91d70b7f471f180938f2178d0d091153276065fb61fe168fec0a4768f2e52ec14dc5c6281026d6bca4897d4a04f074a38b2710160171b4d2dd41e0245ef7da941f11e1c2d79d6ca006d018b395bfc52b92cb4473910a29ce103749da71e5f1feb322497717a0000ecda2e68e412d0ee340f70aab402bc7fabf24c05ecfed15496fd39a6b658b6f098bce75a34662085a725f364e6fc72b38368ca87693e2ee25a06cab2f13c10633ad73b4610a0edb78bab3efc06f38b29d3540aa3f72bc90efa1e3bf52e0bcd928af40844e9cc78b7df1e7d01f822e608089c4007f1578090ec3b3c1e9b25b89c2b07d48d6c7c7fdb0dc4b3899a32c7456fd13a8082b44dd67413911bf6bc98e8502520b8b90edadeca68de6641375b4cb4535fa9283490fc18de9d4df6e03e9b66b13103cc9ba7d5f3536e4e8814b5d70c2f01c7fb69161128cd4aff928ec7a4ab49e6bab1c7fe7927dc7adda2a08f0d1c37391d73346781c2aefa346499ea2e5d2ede2108fc44a03a8c38166dd0c4a95162db39cd9b834c7d804c4d3ab9eb3635502deab599d5bfb95d72b59c90614a5b0d74eaf9cdfd00982b5aeaeba9ccee837140dac541f5d0f80381e1a6a9730c4f8f7e8b592c539f96e73b7516b998db9b6940b65d5a0f0221eda939af58f93e7d77a24b06c49ff53589f8342ac16f6fc94ff29dfb4a585afee9ea933122e8981223bf3efd4af410088ffca42ee334992d706f527a8d8f9989af067e5a9a2cb1dcf0bea18232260654431dd51726d2483c29add94c217d05bb8f8df072f3290689d49212f3cea2fbc337c2c0a9812ee72cfb1d7acb55f9c35d61e5443e6aff8c447252f4aa7a1c1a61c06ecdca76b8edf64881827726e0601e59b5fb844b99f7ada63a13627730e93ec90310a41ee5c744b0c1870a1844a91155f0f08c4e160f9e8ba0a0decef6d6ced168987d707bfbb50e03073924d44e4238f11b1b9002bcf11b746dce92af119f877e66bce32ede73a19bab999413994040d76bc561c893cec7801149659b8ef301d6256931b573ebcb4b5ce0df690b72f8c242a9586967dfecfd553b34ac214c3dae889f4ff465a916d8849cb108a4dc1bb46d2e4753dc85642762e9d4283287ba83db9657a2e62004f4b0d620a89cb1a8784b54e34aad099ebc1ad7da627aba9597158639a5bfc526e68674a278d7b0587598890192478083dc5015f28582c8c423d6b7df57e2c03e92f99a19231ca14db9243bf11a8bab0a0e52b3bd1d4669e67461f34c00dfd0c48617bd01416c725384c3ab741c7f9c3b6da7fd521d4298563ef8353d0496a901838de4541b4559cbd589b083a13a5fb626ea4c8c042f89535ce839ab143ec88a50e3db04b581c7278f551a8a0c88f2dcc588482abcca00ab84d498b8fe29b401bbbbfa42a4cc226c1723dd88090ae5b22ba8917b5a060f2238fb5182ee2d41fd51783b1ce5e08f16626f5150a104e8d63eb005c41916c3b78ff58b8c4eba0dbf7ccec9aa6d2ccc3187a3a3c3e57243b0440e80824362fcfce297ae40bf0dffc84b19e9a44a14ae41cb024b9744ab18ede9e9e2cac6836fdb89bfc895a99275fac83c1baa87f0efc48166f755a68405144199f467d9e57b559937a996ae5a5f18f8295ee7db7a98a459850aeed35e90a245a0c6575de32d8eb0a2a7de98741e77e219d80119beefd82086712390ec8a2a37e78aa88704aa86a250c2f91d85cfafa9debbb80f82eb54509b6bbbe00e6225374e4a47fb5554c833ca88ba7eec656e9a5a403f7c0843687d500d2e66659f5ac6e26a922e047d0d0c9e25d47b4e48879a0caef173b279536eeea391eaacc1c095d2bce4f5e1a700839dd29cff2c1a158d13d28883594972f14f4bc943dbf18c1486a472445615dbf93f665fd7422e5b5382f6b9d148d0608df5f9209313c53139c979a50c6ad89841cf08101b2c6a84b18fab12f08fbfc2ca794c2c51817d67f36a01b56cb36ad8911d2fe033cc1359926ab888be8b04e6456ecd63805422364c752783210f6ea0dbfbf1607c35e9d40945be8d54d4d7fc90e7571e20cc7f8bda3b6547dd170a3e917606cea48db513251ec0129194d1342637a7ba2387ed867bfe195e002436a2f8f93fd2e79ed9eec513d79d2a185daa39101982a301e09c7c1c225ac2a62d9a3fb42db993f9a3f774e321c6843008dd08f367d3ee56f0543be85e04438800b0a64513803b6ab4a312663f544386e738e6f443e3fc04d0a4f81269f1ce79121e9f9466cad5c5eb475f26834f72cf718638528c3e086107f32ae58b8e29b3c9b8583796e9c240c0faf9435b770d89b007d2397b2746a1d9851f1b9c9b59efeb06afb1620d64dd67687b5745721b673c94adad2a4404c602bddbb2d23658d969318f449527b0f128cac9931845bfc300420011f792e93535fd3ea2126caf2c6b864cbb6bab4d30214e246464078127706dea43bd1db23d6563ced164200c029ecdd9e3330ef7d76092a4c2806c348170dcfdc08625bcb20cdcc4ad32ad2d289bf6af7d119037f605b5afbf130a6092e072dce1beb864023a9f79c5a3a5f98dab3a65515609b404d5ced7bc1375aa94ca605f68846ac4ac88bb194d6f6da7aef92c63733af3c43c30810409578e3d8e22d31d0b06283d6924c9bb4901042a939610c44bd3feb72862b816866ad20a54de52c01758813ca8b6ac36be0c97708225c799a837cb3cccc967080bfaed5163cf3d8382d0a7c5f482bfbcdf0a4ea2513670bc39a5e00fdf19370dc6542f5c3226d04b4d2c0c8a65bae7c481bc49ac926aed78aac0af2cb110aece11b8f2b6fb6cad716f50441029f1ffddefdce253c4708d22604a82b2f5016a63271cd02e506c7ee1c80cb4ced4e47f6383fa6eee82aa0472af9552e176672d5592362440923fda58a8509a950cad878e023c075f585dc3552eaa4af92367ec4659bf5cfd8e6afd04c17df69629aaf19d1855479b5f1d7c722602babecbaa9186e8895c4115b8238bfab23413046e63be7970c971d902fb5ca2ff4dec4a236343bea3abf1845c1b469d73a1582d164635cfcf2a04ec1e215e89b940fca1cbafddc50fca43805600a8e086e85195800ed609459d79690f4a0514c53c0f32c1c1b08222a1950c04972abeed430e0f17eeff06544212756bf8d66c5dac489283fc60846329da5412f28a0a83d30ce860d16f201887c0af84de974d009e0018964aff08d4a9fb14785d023bc804899568df516bfa449263b931b92fb3cd3a4f2708fdd851783d1362ca45ff38a0cded50a959292da82accb2164b0ba6e0d6ae606d2109b53f666359995afa62923bb4c3254b0bef114505603218e9a56528fef28461b3483249d1e9be49f2445b7a3b878eb4cfb1036ffc01f57ad9908c34da333896b780d4f748046462c192b269501842175b0e67d9d29481ba563f82c6b56f3421c637bce9bb65f7017c4cbba2ee7d9616657655095c1319e295d1e00c640eb26f2f431e1ae4587a4343a79b870d4528c8e0f69595a624599e938458ba643a20681980ab6970b017ac0d7efb1b5e83f1b1d1b063926abd58deca36d3565288acc2d4088b8e13896da1e46350c39c5e761abfc4703271e668c1059894bdff08f0614aa4772d9f72e40ca6e04fc34193503ef1c082e75c79095e9839c18185ff4a1551f946cd70456766db1d0a4f39e59c52f62cdbce32ed8a8d3dcc41fbdf155471ab636e474c6eed245703acd50824f44e0d6295915c1412371d0dd2536287265c93a71b58b937d47b6a8671bc106c95d7aab570c244ccba305e40c4d55127dbd9c5a9ba9447fb46c313266191a701c076b04f76ec98206554d22c4669aa6c85c0c762d20bbe3f6a9f1ca611594438f7895240610c58f75aad70cd75470f9a007a30d8b5a66b6cd5bcf836809b187d1ae86248f569bc749900106cc2baf43949fc306c496b9a6a34ec5baddea773dcb7be6e2f04e0e8839f302abd884c807aa696edf973eeaf905e67d6d1ec80e4026696ed140ae4713a22c64b59ea37cbbfe1b35c3ca0e35f07a2990236b360f30ad7e84b23b55ba60505cfdf008b59d44305570b0a6c4b61ed2fb085c6be5482d0a77ff94280fec16f228d04adeeffec810cebc7be2a3943f40c67fd14b0b35c4a3764e1b639249720dd7827cdb22a04e235c9299802b7cfea5b7e9b07a554046400639ac884ba9f7ca5c0315daeae4ad29a4a780f5bd9929780f771215b229624002975ab68241f120a3611a03619244c0cf5d911a6e70449cb23930c93c99c03bb04c229418c1d2547720e3b3f5f11a0e84f0f51fba5af4768708271f0d432dcd8c1f808bb517fca85b7eb18b4ed187e5fe7dfb29277cdf1e9b9278c766e79590745e3c9648a4a94b9f5111b59ff4aad2266bd4dcbb7515195fab0ba485c4b62bd46873652e4fe998bc4fe4ac1a50d4b0eed44010b2540927b78d2ef5310655f3234c947811482fd9c0c6cf8d57d82494189b66697dc8798404ea234f787ffd54f04af4e555e138802ff0328b4c181612b4d80208dbfe6fd60659c42b0cf8af21dfba0e02b4ae205ceb8d55ba19c43d801e50abce08d4456940b0b515ad01552167dd7149183d6d7fcc918d5c22d5a993660a5d87f30da0149d4d0b147d6e525d843a242acd3368170c7568ac5c4dc2c83b5623bc4197daa2e0a13c07552705d4dc3717ea70adad8004b6c51d8766d22d61599fb693ace46d0d7edaf0a79f426834864b8fc06c7faf4e63cff3dfc316a740bde3001f18212b212881d40245ce78e0ec4fbc0ff945338c6d62800ae1449d7404da370037535090fb2dc3507c93e817a9f9b5dc5ba646915052059b0130c385531acd4a53d6ef234cad7165e4983c14920a6b1dd439844c3e49a52035ee80c3f81caf89952fc057db6bc1bff7c84b99672ba5292ae0930bb2ffacb8c8c6eaacceb0de43af7b79575dc5e36931cf83f68165942fb9de822b40f64fb78069f6d9c4665b39d6c5a356dea6c7f23c5f638119327621b2f5921f5a38475344a68af2ac4c0f4c06f1dac3127766da05c31da5ccbcf18b6cf3ecd417178c808cce370407c25219795f8fd540c9cc89977073c9fc4d8638d7f1b18a056b42ba00da1a4ec79674148924d98e4d9dfd73e5260f663507af88dbd72c9b713ed17a919c655c4fca9b71693899e4d54dd0d7fda5dee217f563d1dcec94593801d3a5284a4968d5cda17684dd1ef507c10caf1ca437aceb7d0af69e89afc4bab4a19d5a3cb79d2061cea20e49495ff6ff4f5b6da38298de4dbcf9188b581a927935ae7da7395a63d717c8ac5eb18f1f5915e6dcfb781c4092d23fa99817d889bedeb5190597d71c448f9b70346d64334d17cae44d9fd1cd6abd6a1d1d331ac63e837550d40ae851ee34b314dca48f9de4d3d458cd0c7b422494006ca41798f11c6fefca4879067a76c39bcf38af2791c92ea1e810d041f517ea35690b4c32cccfa2ab67cad629c718014d15d0e79764f1e06fbbee7388d92db5c918955692f2e4e6ce4802bbc02cbc6016b35dabd0b3d7c5e6c50973edb775a83f9f51cc05e6674d572f0bdab7dc19438ace4fcda2c8787ed7cc0094b21c5127c6ed177f6364cdd5e92076b7d9b7f9a4859ac965fd2e454bdb77ab009e205a2b8cf0ec12c3cc6800e2745c3cd5d021e34bfb6cced466231f4446b3b0843de787a01c1c04d7b7380246d95a9d82bd2cae6d967b9edd23a9f8e6a2a61f96d5e277650b2057ad66aa25138cc5e91266e3be80733d781805527e225d91b044f2b3a1cecfabb3ae8e095f8b1eafb2ad148b8c6d410701f6c4dffecb8f431a49e70f337d1dd584b9a6095069ea7d87e14402c5483ccb79c815860349a6fc9eeb639cfd52fe2fcd5808d066a66c6300322d74e199fa8c014c78b5424abc5949dcb81c7e5cae3d6dd813a45c4582bd5bfb8450b03ae76ee5ea2ff5a1a3db944a2d5c638414ed72eec1656b46e2167f77dc9761e4243021bc45f7990b953ad35eda2538395ed7870f350cef1ba503aba18f172dde2d46de2343e22de42d3ea1c2ce175a73bd67f36c108ad619e7fb06bd27262e320e95d21774dc1b8cb65355f3db34c36bbd2f596b1e4334be8265e6d27e6667a8e163336ffaacfec3473d3bbedfd5b8b964210594fd36304cd97cb09daf43e20eaeebe79f08829e0700e685a3f98078c98e302a0f5fdb7d8d3a1ab30521ad8f42dfd27c7f9974f55f2978efe8f1124b194eda34f5fc79a825b8868e3796bf411bfbea58b0afdb042941457f3f321dc53128a36b89dbb2dd85bb9f96faa21961a3448033f29b2ee181443999cc30fea01d5e24ccfd0c5463eb8f51e9a1a8983a30093ba61393e1e8aa5287c92009f1a7058b09acdddee731e7a6c4861afc55c7091f2aa5c8ef698fa39eb79e0af6ba2eabbc5df753a0b36cbdfe42d955a3143cd93271cb8f012652c43e54775a31cc3e3c9b60fe8e495c395937bdfb8422a340a3071b8245a12c4f2480edc87ea8fc93101fed600f825a4314fa0482adf0eacdb07a029c1f2f07de4c4fd3a5c0107a6631078867a3a812c272cd2b97addd7c3b4c0c7c19e13396721783c4f9272ea714669dee5c51d246dee723fecfff678deb7c37756c4538a2b1945250e67c6c117e75d0a619163be94891e7f13ea29b7fad1edb8988bb19ca2af144ac13acdabff82d07dd1a6d72f527d0c1c988f3ed1bf0fa1cdde0bdec42b838035e659a8b2c53e1231ceb843235bfb1d7eb52dac6a6af0dd4feda255bdfbe90a80d5b24ab259f358e4f1fdd42ce99778784529ce1088e9ddb178ac67345e4c80bcce2120715a1ab4e17c0790abaa4b395439b5153ec5ad3fa4018bca598f242c5200df5c3d4ca72f72f4236e70b797355843533b291a40c63ad423ed5c16838c586142cefeaf2f4073fd06fd1198db10d4e327a9454a04fdb0afbd25dbde2d15179920e06664e6986a9551e6d0e750231c91f81065aa5cc56f313373c110c7f022e05a39b2b021b6f59d28733088dc715c31a410483dc68f022e9286016b05ca4a306182b829f5fa3140aaadf5160359b14eae2daaf5d9e0e55d52a97313d46c0ab641de352f092cbacdd880d85e0ee3be096076fa84c23cf3280fe1d4406da0bf9f233e1ea908944b8bd1964c5f8f0f765ac4c0fe9a9e0dbbbe42a6f8fb8b4b9e423fbf56393256669012a4dc005c89325a5ee52f14f98402e22b5bb2ff04692007853f3f3a376c7cf9c23c987b5e443c2d488a05c8295d0f0f84c6ca7360d3f22f3632f0c30377167e8d75b10c515fc21ad07824e0ef2b53971f73edaf1653c5ccca861cc44cae8354b3e92b4d99bbf7e590ab7a982dbfe883b872b2bf4c72841209f0ca3895360cdc5e7e484738d7e4b6886e227c1e2e2f1526d583117d7c654a75688b0c0f1310b6cf6f2c7dd49dc3a84d0010f2b83839852265f1fff3c307404f18b5926493b6de12288b1e703cc5f7f5ea06ef1dd2011202c80ffcea302c6758de23336d03c5d25f3df577790a4de49efd09472ba626a60573fd3320afc9893dbb35cbeb08014003cc61bdff6bb1d5c46590164c2c7a0b82f1707b8f42789a6e9b96640fff53f71c62840ddc5eb34aa4d3f3ffd8b9cc782a993dc2fff8b636b75ee60087bfec016c72cba50c76d30f9da80d8638f029d4db221e00d40a908fb7ca99f32c671387cd3448972d84a69459dd1a17f1b40e5512b04e46cc28b5c8156ad54c13720b0faeb614a97e08bb4a78039ea027bfccff6db0637cdd6e0ec832423ca170ad3deb57ffe3343c34f069a5349fd8eb8de975a56587044472f49b370550fff00b16e9fe39ce7e0afb4b8c0e43e234a4db043c88d04284e5228cca274ff92236ffe0f68ee67be398a65dc407da34fd518f807840732e79b881a06fda39874e17964b0f4742c2714e3e70d92055827725bbc7942d9dc4828d3227c7735267230ed24fbad8e9883907a1e336963125a2366390709741dc89e9448fdd2145be4e6d34a4d1d91470dac20b4eb76b970ca456f8572fc4633fc2598247b792687b1c7b331a3b4461f0012e4e9c9ee9b04dc587dc8371141a655998648ff89e91ea9264bba62c8e825489d9c7b6913443b8b2141bea76f451f489d05cd8241023b948b112a703a173fd65c849ff96ad41837bd93a18a59dd35fee4e6f87a9e5aaf775041f5da2d8112a138c0cb8594454a45ca083886b4e310d0137d663668d80b30a9ecaadb345d561049d459bddf0ae98bcd165f3d1ec3fda3e856e095d7d0800feb329b39f95c9fe291876825792a3203f4cdc3addca09a724f687018a24e104c3dce0bf414d27c0bb2d14bfc1f5860f3bb1d1b84869e0c8949b867e390207d96b9506fdbd486deefac20a0b1fc459983bc0e0b98aee13da113a36ad2fdc654a2f9fd8128409c00ca213bd405f60f97c85f4332738288791db25ca328b4e7b3adb7c0fef638f5cb4b1b31e94e47b9ab1e2e9a13753e1ac41f849edc5777d3e79e911225d79a952d93ac11bc52b67451cd6b87cd75c58e5ec3d2c1790d1637276914bda8b547057b6f09f9056cff04dfd118043bae7b50b13af90a8cf86475d6391ca5b22b0a23d769a35ade080c36174db8df670d0b7555619623dba5f03abe959f440ef0fe46f5c3b243c71d9f7e8a50aea522d08a3a89548150983254d893e3c26c8258f62008eac8e3187c0db5942ae141e62412aec3771cd63e1fa224b42a59847c6e7484ed31b26a1fd8381cc0ac1b86e6873ad8ddff7a50b08836baee156592c2e418a7c6b3294d246683b645f046163430e170d4d989fae7861782e9e85a4a8d677f8bbe23ffc486cbe8efe00a4832bda64d452a3000311df6aaa591268dd750376ae9ae734810613de6931414f2c3d202c82bec35f761dbf0588b62177647db07a0e9f9643862cc51e6403f02914657a27f457d717f19afa00bf6084b6b34731f5b9964ea7cea07d5fc5a85c12a00210272f19b38803a94e9a412f7de54621888be887f213fc7d9c336a07c5cb0bdc4dd73508109047147332fdf6ac19d17d0afb263dea52bf6a651a5a55ca912ffb69c71e36c05dc2484dc2aac4d0f848e18ee5718edeb123600c02b8df0614883dd215e67070e83b980571522882f83a1e9ce8e828ab2bfe34f42558e6a9817745974927ae5333d244821f67d9df9c95495ea16745e861e5f70b72027b74e25f0d125871b44f3463eb9a068bcef7cc2e5516bb9f3328e897121b563e302d606248b579f57b2deaa605316584c1ee99e24c5a257a590124cbde59c00253c501317b40c2afce813c59075b831ad1e47fd01ce1b9ea012264450f8d083cb43541c6b772bb254f0ea63ece3168b9a27ae823339c97bf53bcc40755ef1ad035c9046fc2f43d0730498fc4f82c511b831d1f6f671ffbd0f60aed8d1eda8b0a6c318dd5006684b14fe4a9b0d4289fb208146c66bcfa93837cbdc17268465e11b3bc4ec000eba5b06edffda7bb5b530b8f076b6de88621c368be445efc6934f7da18263e4945fff49415072fdc2432368dc42cd6fde6a9dbc6999eb59bea5f2bc2c1a311322b57dbbc7d66815760a6245b0a8801501fc46d4c86204072ea71310dc2170ece85a1a4e93fdb5f3279ba9ef0d8b214e89733782b3073cd170ba670e47d832f8d44d8cc452cbaaeda04e4bc0c8a5243f98713b02cac0047c88d02d7be6a9e661c47367b2d984668ed2631e89d848a37ff8f8b7466fca64fc614be9c9da3cbc16fce7138d531ba6d1cbc5f82cc7fb4988c4693f6fad48d115a621fa5a1386c3a158c28c25a8ef9dc7afe78faa7a3563650455c591a0d943da8b1854a3284fb24f48f8520da6e6ce0a50ee7b2deced0701ec88adfcbced1801c4f10b605819f80522e20b15084141fbfca155e9687368b7bac253f77f83bbea5c3a0a03ac22aca32e7dfaa5bc33b3ddd928ab92af639675012a1f14c7ac8e4370cde2f184e1ede5465f7e7e567f3ba9313ea13e3b371c0ab55900b58463fa2b623f2c2080b8bd6f0f040552f2a3177953cf405d8d64f1cd6f260cd10bbb1601cf91239eef86da322d064eaba184c4ff115858062197f40b1b91bddc8db374aadd3248036e6107e12d416d5b45e4e0a87f5e7366446c84d16451d93f985e9dc5dbc64394b513bf93b560abd74eb79bac566cdfd7fb0fefe8da81f9fcb266991ede82bcc349e8bf7302175f6abc5a2416043252e160e04c232deba30f24f5b9cec79f61801c199db899468416c198e9adcb709034392d70076c5eaf585cfc1f102ca014081a18ae0a5e32bc6acca708a6c160c57acc3aa20169e2bf91ea91c10aa8a2a58b2d498c69fb5ee647cba92832fa4473bdb495e17f6bf2cdc42a82b2e2bc0f7aa8884b16f147021f23b06554a56a21f9b0d9f235bffb1a1a9edb2e3b012cc3777409541acf5b275561741ece824ac7d026f0c39ff21e284ecaadafa04c34bc72ec88c8082cc287295d9c217ef957de0e1bd90401db8dc3b7361777cd144deb06d680236367a2b055381d645d6330af6005ce078240fe72b7ca0c303286c50f68ac2a419106b6d863a9b97f5cd88fc70aad3b8cb8cad39af5f736e88bd98415ebd8574e562f1c614eacf50215e1c82a930f3e2e82df5a21da4bd7120bd320b8f2eb6cc6d542e995e34d900988f5a94954c33bbca43fb6ade09cc973c836d9230ee66a2c0b4831ad630f49691ee0a1cb1465ec1ae046407f225fa016553e46bfdc4ccf459105440ee49e7da5db84014e2ca337069a8998de3b3cc25aba6db94dac1530fd577f6846e09e4e1f5c9914d6b0c78bf7ff28e9881437cc0e00ac98277405a7e8066963a29156f6a41d2d6a9630c903da922c9d720ff8fba2adf52e117f595cc200ae9ef0e7b51966af7e78c5ca656c549b6d617b8ed4aa9127f7ae7d80630f5536ac75ad2b56300dc9e1bf14a71d6b7850c312c702bfae60d0a6d50f76e07a9e3f6347506f636b13d271468b01ac1605de2217f5f0beb2f2e85c26ab56e6a91a108275b0bf844c958b0af0222ae7ecac2b96ea4f56f9ae0aee3b7845a7dd181ee81575fc1f440eebe579d10078131b2379103566478b904b5f28680a5fc9f3684f84bd7eb99967a9f2278595f330bbc41d10f7088c540d0d19a93b65aabbee34b26f2d6002aa1dd673837adbca65866675b2a125a352fb68384298c38e825f986f052db5bfbd1216aa11855509527d20411442b376f6424aa518d081a9371b6cd032718b22a6f0cc6e9667db39525e5a671575a706e6e5e644bf8b3b158ce06bdd9593f11a0f1d641109c25c9c0ab03b9349633aa57318914c4702a53223eef1923db68cb1c5020d905c01d0dcd38433006ad5255116a3dc5aa7e084d8ab10d1f270d1c786724d6c8760784d109314249181fdeef836d59c79ae748aeb2fadf41ae298d92d0ddba53f1f1f1ff30ea125361a23578ad4b937caa11a384fafa1c4978c19b71ff2f3b609810971bc6be60c0fb31acc3ef21cde2b85fd21aff4958e738b981883b7f30dc7ce85aff73e4ba80d4759108954456b8601d3c93c4010b24ece63159ea22bb69f02b60db70af792a2fa220b1035cc745c6018a5e967edc1bcf2e9a2ead4ce3077810b6f5c2847b43b85511e3ef8dc4dcd31a6158fa8ab3ec035d8bd4f134eeab0bbe1fd52c5c141e06577af66599783ab038af045885f2aa6da28f48408f667f8ea5b59587b5c475a1b1e55262b217157993e50549d4927766119e674a733cbe8caba446bda7cef55a0364a41e1aaa69f965c139b829dc7427e62d36873d7e19081ee1ca699422c92bdf8288e340b8ca33a9a35c58a92263d3b5070c62ba0b6313ba837040f4639a22d34982149ed38fa1204117cc7af4c959e0650dbb161f97ec704463b16a1589a08c096da40464431affdb0d6c0ab84e554db7aea6cbc316ac951f79a8c9459daadaff17f543c9c4859d36334b7518c52e9e06dee6723a41f96840d2386d329eeb316709c1d95caddf882b8cfebf27ee199854b124e1adfcd81b3c1e5f4ccbfe23430cbf72b49bb05c7879ed1aeb2acb1bc7325b900938318c7104d8dd2057eb604426907a637ed7e19c6d7336d83d112b83f3aa5fc6ff0984ad06cc6b576f6ec62c38f37f7b5080ece2c62d3025205eec7ef77c2f5c618669f1e5bf20d792365e6c44d3983f83128179a89c7cce1f7f9add93c736c36eefabbd2f501d1d423199663227edc8b90efa5256ad8c8206dae862489644544aae2b5342f9a2f4b325477667b2fef471db6c1144b15fb04e1f41a87a43f14ba69515b4cab35d5ba326fe8ee6917f867b9bd4e50a8f2230b06c8bba75dfac5785815c846c533e0983e997aac1dc83ff73577f4740df9ca1fcc3bed13b611da3ed055b25b12780f32cbe708a56a79952bc6e3d23c99312246b90d38d3e3c6c2e3c55ff2f04ea1303ae45b3617988af9ecfa86c6808f1b6bdba20c4cfda71e6430c58fb6c0e9c82cc0d0a9a2e63bf8e93eece12a943eb702e748081e9b4d2e37fb920ccbfa6dde536d9f6dee7f7abf2c6c13b0effcd1dd4990a52cc3cc6687ca703675dd1cc074b308e7fa60d57076e56383d5e5f02e1bfe29592fa6ae0e8c90ffbd94e8757f89cbdb196d1502cc598368cba4989beb574a8ac3022354c30a9fcd6a560c9e53c4975fd7757d74334459df724a84d6706975a56094de3e9d39090389951b903fc16fe19e6f8c80716f7b9137f6911e40b5540f57c27a47c68f40475000231e8c613fbde599d0a08d9276c2f58fcb1df2f111428af03f2e9d7d1c942c4fa58c67eae69bd5e51400b097d544b6be51e8c28c66048315e3d5cdf79aebebdca54118d5f32f5e024144027a63c6f162cf51527d130c5a068c8a213318b7f40776de479df22dba62d764b5b57b88c7b864a62d088466307de16f7e2d36751ebc1e2c4d046d2d1b6fb46f14c592589eb6fc5ed105b73692674121b979988efaa673f93b32dfb4641ad085da16e1e3a2cd9a9abf9678d3c6db4ac74c51132a0bb1d858bd9f247c016bf870a2dcb824231408875fda4ef8fa2c52114c7ee586e213834540e622014d6acb682ffcc2cccbfd13571f1266051578669dbd9622319359d66d27f14042feec254952d3549d8b027bad35780315b0657360aa18ef18c10917a0a9937d276cee2e8a4495b1c2d7c6c3ac8a06a69f31324b026b0295fdb3474d5b3c1b606eb62d851a1e2d84fc3576f99a300016aa356b11baba1e0dfec87eb544743ba15c92ed5c3565706ca8b521e5ba8631070dc1d1d63b5307fd2e871acc1268f0da20719202ff0f99f7f0f53aff74b773676415e9b1455e749d291e126bd032798675fd4725a2cb877d0e83d9840c74cc6e93d4c0011ca01a4100e396ad83ad8ba3bf80d3e3a93b4048edd829678d3bf9060af91c49c06c5c92d5d4827b310cc21d75817f02cd8bf4515155f90812d30ee24f69743314677574515b5c0463fd3a49aadec3d61be3067e41755a76cfa96e44d4dce5990ec80cb998ace89e5c8c728af14cbbcad72ef6559e0d65100e879db9934b71c4856f53a49b490509c2984f8612793afe9f285d17338e80a47ce8392239a1c451025f70ff2390538b89a5c1fade36f54e28cb17391294919f780f945fd047b639787c588ff4e9913e77348fd09e8ffcdad96fc16f52f72967b50d2de81ef3037455bec94e6e6f36809804b7306776c639daea9a85fe120c60eb6019526d3493490f65d5c9f4d7260b6dff838b311e1240f849c44e40a8a082a86843461a033df32f2c5f10c13c642b22563f15e83696f71c875294cf5706c5fb10fc7feb9ac57a4bb033ae537d35b204c4a9b0e6569c85a1e4ddc8d48371519ad438a7623eaa621a57934518f2d867b65d6b2582daee8f78be9db3a1076d945cef90d7edc816074cd461f4a71171da3536e38517aa1a7c1bd18433e0d86f82da4eddd6defbdb79452ca5d0c400d950d3e6f5e740975cdbaf8fce0bafc74d1527e6a3d2009cdaad4805cec0431010a42e2484bebc5dc1bc82648c8c802f16f563d929511f2372dbabab4173f59e082b69c28d2dfb188b60555c1e566f563f5fb665d50fe7513f250516bee2322fa4d73376bb0ad185a31b482546188288bad5f42d1b7055b39ad9e18824b4b1f134254c2ef9ba5e2eb0df3d7c777909f766f3368eb9b762b2202cdca2ab38ab0ef25dc8bbffda6159d3d7c0ef45db384be2dc821118538dc02c2f466e122310516687ed3bcb7857a1f74a48505373f852a0e4cb418af5bb8f3ead14bcae8a814abffdc9b8a37472e4a513497545cc446bb40eaa97d282da791bedc219544bafa8f0a8b045ee1ca9aab9b46b33547ab2e54735724faebb5e63edf483aebdece68ebfb66fd75f24559ab8cfa0287c3e170385c08e6d09c035f0c94ecdae541b7d977c6212d0c43f4b34f038be70ebd04bdfcfc9d57443b507e46f78d0f511bdfb9bffd4380fb7dcf0cf913c1d26c212cf594481e99ad79953a532289efe7932c711903e641871ec2768ef7e03fb7ffa15faf52889a427a82c8311ebd3faf8e1f077f9fefc68f553cce589724974cebe1943c3ac4d9cf67b73b1e64d92b566a679633b618b63dc0284f3993415ba7953c3f7aca5717d1a77c89117f4acf522b83ac64a0d287082a673c08959a4a9e59115f10bd3ccd267b96a083e7be9f7d67ff9cc4e78be0f7dfb9af8a526646b495fa871565d00e43258d4b262ac310f2ad34a31495e411162579a445191b221a95f52af9ae9edd82f0b687ceeef80fbed6a3b21c23ba28431c2c5219b4c3952f26309e9030cca68a3fbbfd218005ff7bfc96f715c328b3123746592211934ad04ba6a0fcb47485f1028743ab63c4dde6aa458b8040de6bc3e826eef4bda86851c8b68635ac210882a07f3db0f2c4ad5fdcb4174317efed3b73e842cf81d0bfed1fa29846d31aac9ed1a334dabf3ec6f904b77b6f89b1115a6febad22997b6f0c245555adb5d65a6badb5561c36e24ad1d55e115b9ceb91bd169b35f2077ee1a7f1ecda9b74034caa3c2d74a9e88dfbefdaafe62f15fd7a908ab808a3903f10346b842888e2f88de398c7118fe3388e771ced388e63ddb99eb3d974d10f346b5cf3828bf3675e604bb3863541f333cd6c9a26bed634cdaac5518faf6bab6e6a7ad9d7eb553fd8ce318eaf175996668d7bab47d54d1396c1f0af63fd9a69dacb34807db234611606abb9b437566dbaea982607f60d017009dea233186d26c6625acbec27e1e0dc9a8c6adcb7d5235a53adc6fd593daaae5303415f746b2d3565b058f176496c9408ae180d92967034eecd4ffaa29a878746c3341a8d766d85c1768effd120968afefa6d7f8988e218414ae36a194e998473c63b7767c7eed411b64d2093e1e0e4e4cc664d3bb527043f112747cfececeaecd096684b3c97c77eb3593dd2d1d9d9e1e1b9d1683d3d311f1f5c9251ad4040f8da71c7a67b2abe9687a67b74896bad866bb55bb322cd6c227bcc1a3eb4ffb13f15f7f8d89f5bc340b9abc6fd1bf5a866f0d57b86e53d77c5caa01e55c7251989e8a8e26523cb7bae3022cb219308768b156916b2f29ebbac718d8c4a23f2351a1989a191ad3cb0d247cf4a5befcf4f2da82654ddab9baf4ef6ce1345672a542ccd48aad5665b3134444434a335dd6645452c74ac458b16b0162d5ab468f1657c5bd8da53339b6640b4594dac41b66c02f2201bbed1846c4dee33dab56fab3f43f1b5280ac27e0800fefdedc15f5488f4d3ac71ffdcfaaa5061eb07733f4fb309b5e605e58a3a7487ecd0a7c2244036c25d5bb1b862e887be2811d1ed5654c4a285db6824d228864848e08794f145b24848485506db3986cc26a2dbad286909572b8b92058b580bb3a9fc8c32bed6a88ab08de38988cc1a96bc990618c1772002dcad88450b23b3c6fd5a8f8ef0b5b51e552f329bc4ebf8a2b5bf7bf6778bb6d66a3d8b9f495cadb579cfc0d246ddba3316b4598dd455377f6b43f445599806b06f74a76817481e64fd30d1d769607bdab03a5ba4ea464797cce72e3fdf33a3d8baa88da02fba4b24dc8b180cb3a9c6b03144d8cef147f90343717c91a5098b69d9114ece4c678787d6e3f353030a12f21355615b3144742b62d1c2081f5d5b9182fea21b036f510838216bade5d72a02b25eb2d65a6beda006fe6c91acd7f879eb625d72496bd6c05fe33e07f64350ddf2e8d23d3615b0f315bd17a05ffebefce12f5f20d82ec1570ffa8a6e0c7c05edad6086596b6f40777e8ccb2aabf7265a74e7382f0dda7a07f9b768e27b4b6c7a366bd8372ff89c03fbe641149b4d1fca817d83f3f6e0e782dff96d8da4afb37b13af12ce68ae471fd8af393bd5bd4935b951301e3111b8d136b6641b94c1d1204bc4e0deec6bc6bd595ec525e5d86eb3269d7bab269947c7e78869dc11631c866088437c86a82649fbb9ce5967b9c4d556b0fcc8b004cdcf926399bd963d332c3d2f1d7fc57268268c06334d8f5d530d6e8b5b6f9af6edbe6f1bb797682ce1a01b67f418c750186aa2dfb967dc974ece399b5245659ef50a559e505010134035dfb8194035b4de22dd0d70aa8914ecace68c2ddc52122ee9b7d5cd48b28b8a9d1516b4d45bc344cd05f57a3d23c8a0a939a0ded501add15253a6f6e3fb9644d67ed07a8b2aaff2ec54af17c512d490277dd658121b9cd1cde877e525f9b03caa06c201d56a49fc18fdd45ba4857323029cb3ca8cb8fc86baed77e51971d9d8711a971c4bd1dc719db3feecac9ff3af276b8db465362f7839462f4fdb12aa9209355743894aa1d26bcd95636c24fdf3986fd14400e9a2d3b8d78afd604755c2f51642cdfda061b53acb542bd2ce327d20c7c37842af3527f3d07f646809f5196791b26b748bff64c2d09e2570389e1de7c3e39b66b348d849ecc383d65b647b18e7dcb5d7413e77199e3bf6dbeaac91cffe9df5a6b55366038c6edbe3711cc7711cc7711cc7711cc7711cc7711cc7711cc7711cc7711cc7711cb168e3e91609635ca3618c6bbfadce26264b831f1feffdfcf47a3e3ebd5e8f8bdeb6b7ad4e4bcd56199e1a0d9ce3a9b7c842ddf8aeba6050b3d2b470f4ad67b519361f1eda8f4ea3b550f125e70a638c4b1f2743d78e4d04947ebb91a10ce63c8ebd5a267be537b7dd7078ceb07e20c7c3ec558865e8be619045caf64ac7501ae65ddd5bc6bab7fbc4bb4f50ecd57dba4f3d3eeba9b7483c79f6ca066d2909c7d333e3e1e9e909122228485ba49186e65b346ef1a9b43133bad974199ccbb7a8ac5d6e64afd1b0d49beba191e4575a74973f3aad6ca1a2462dcabec31f259863cfa9b91ec75e2f2ecbb284f59c5697b33c5c9443d27765122b52e915e631c7a6024ab7569bc7ea62386e9964ae694c342c920df4deb255118d2d967bcb8e516ba54f5c6fd86967588bb065aaf8cace0fe44000d66e9178384723866627419a571a6aafb2e72b9cb33d5c943d6334db5e6d076d755769e39cf22e9fae5216af52f8f5b3e346cf5e9ef8142dd2e83430e8e1299e1de4dfb8f2756e1be563073fd06cfa5ce7b43f3bede79cf6abc539edcb4efbfab41fb36fda27edfb540bf47df4733c2e3a46cff1ac16892c1d9f1bc7934e0b63be5b6c15347e94b4efd88f5e6b8ec777ce8fa66fd88f5e5626dbb348d9471f3d8fe8b661f4a1eb30bbcf4e8719a5dd9b0ee7689edd2d137ef3e685bec763354773acb3e3aa84e3d8c39af3713c3a769f33ac45a3e39cb8de46979db51ef59ca387423f3a6d44f78def47c72602467474b4bcb78cbe3e6bbd6df2b1f39cb516edd863a791ddf62c935891b067a2c71e137aecb0d76374db3035ec34cf7db397e716c1dfc01f3a79ee325b2411c561fe7c7739d7fa3882acb67d9f1ef41ad9e2ac35fad14551747b6ea3174791c6c5dd72a45be748ab93d7e2961e74129be6a9c12d02fd737b7ebef556f7d662b3e9739cf4721ad79ed8bf93036c36c57cebaf9bf675fbd77dfb5ac5ebb1f3e7f398cf5c9f3f5976fe64f4670132375d03999b9edd4471c090510db4eba0384cd78e63e632cf91c2ce9f05c47ce63f1faa41cc673f1ac0dc74989b8e73fe7caee339d29cf3e7437f1690e338ae418ee3f8e738280e183e54031cd74171fc7cae7111e839521cc7f1f3a11d68a0e33bce809af2107111e833df4171e0d8f11d5407cd91e6788ed4ace9ec9673d614e7aca9ecaca93e6b1a3b73a4b033475a9e9bf6a0db8bde001d708623e8514435b8b70c666d34f69b331de499e8006e1148e3de40bf4ff4e719e4815e6d20ca81fb145ef108f1c918a9b3f7fa6ffd585b5d35650fd83155af32b82e8a9ad694b484f6f377edda2da0166107a32bc229cdf9bb5e6133837a84773cdd5bfd8dabbab75aedc5b0ab9b45a1abf7aca0abdf1834f62aa6f8695c5e0884d669eb4d28f5d04081ed495276eaa744516b1acd337abbb70e7a3d124dd7dfc09fef0d076c8dd52ef500e7a3862a1e47a8c0c3619db0814956ea81a52188375569b53136f8d6ad1367c04ca5624ef0822e253f304c9a22bc948c9d3ab4d15b8cb5d16f64527052d8eaa51e845ae59945ef4c3eb1a384def982fb6280fce0a578aac8d653ad328e2c09612bbde77dd29638ea1345cce8520f88f45b5bc29523572919dbc9b23fa4802295064037e429256f894f2bc5c30b4e2989afad382b398344554ac684c6e82dead03e2488524826ce2abdb310114ec24e113d85de59d64368081cb687901ca4521c1ec89670aaf1a4d27a29d8b7b7be6342ac4b6f114848ad0b171d78b5fc02480fbc948c65367a67120a718a29466ff127434d255195de1d9c46d8a564d797035010bd45924de53255a54befe39cb64c38ee94142698e8520f5e5fa052187e0c50cbbcf55ae62dd2972bba948c8950f4ce2fc6a0ed25a9ce48e19091e155e68c68268af04c96b18c11b90b9b714144e3842ce36334234378e6074e991e6740087110c93019cb44e19cf9209b717a911973660d4c099c32278468869067ce9489612433251cc28c4e2c53430e9a15341925f98c0d26192e386782d065b68466bc8848f81c09c9408166ce8867ae40abd10c980f4d8f98192be11929ca7811cd2891cfac5006cc2884c606bc4a395bf9e94ed5dedd81533d98dd39ded226c8d381bd114fe55de5e5a97a759fb62c2feb70efbbcabc7b05ea763c7c957b1f0fdcd9a99e6eeadb029f2ecf5e7d4fe0957dc2b96f07c3d75a6b73c618631fc771b4d6da529cfdadfd35fab3c7da9f81bc00202f0dfa96f8626c36651367f382ecd96cca68fdf087718da4c7582b3f59afb5166374976fad78f517e77bd1259eac38e75c7ece18573dce5586f59cdda2376c6dd7f51cd7f9b9680633c7f12eebf312b7c02f5f9f9d77ea52603de7bc5597878bacec94f9f8723287312dd3315849be463104a770ce56657dbc9d9f6497b481ac7b09976b0f43de7a046e4e5bc0ba8d9bab3ceb343078eb349d75c739a61d64e0e95062862dbad4faed955aaf5d5f4d5bbb1e0ce993c4a555a0db03afc2ed49a25eaf52be81ff7a154dd0d77116579cf5ac16c9bd5ea50c8a3324fafaa967444367bdb9c8af67507c95344f415f17aa79d1adde2c0279bd4a2dfc7a06c55709d3b3bf6e33a2d2d7836e462d5814d59bc572f47a958efc7a06c55709d33833da5fc72dbda0afd792968e8c5ab0a8378ba5f6f17a9590fc7a06c55709d338b31d9a8dda5f9f310021fafa0f8d0120b938326a516f164b3d7be1d73328be4a98c699edd07c6a37bebf8e410647f4f59e0364f00287e4e2c8a8de2c967a46e3f17a9562f8f50c8aaf12a671663b349f5a905fd7200241f4759a03221003c60b1c928ba37ab358ea19ad76865eaf12057e3d83e2ab84699cd90ecda716e4a8edf6d737d080127d7dc7021aa02029068c17382417f566b1d4335acdef39cbb93832526a41018ba4a2183718442f86702b906c36ee0ddfb837ace3811b39250a9262c0788143aa378ba59ed16a6ebb275801928ba325a35c0b2516141425dd6210c1187ab10267f37b5d04ba26fa7a8e57b3060e5d054b39250a9262c07881ab378ba59ed16a6ebbc9bc5e2526bf9e41f155c234ce6c87e6530b72d436746361e40297c4c3470cfa3a8e930f2619152ce59428488a01e345bd592cf58c5673dbcde89e00f0eb19145f254ce3cc76683eb520476d433716462e703092969ea060d0d7f5102800cc609251c1524e8982a41830eacd62a967b49adb6e4638b3bc27cceb55b2c0af67507c95308d33dba1f9d4821cb50ddd5818b9c0c148525a9a119544067d3db64b6241000030834946054b39250a9262d49bc552cf6835b7dd8c7049f77cbf9e41f155c234ce6c87e6530b72d436746361e4020723496949c68c1ba0d4d40afabad964ea6958100000cc609251c1524e8982a418305ee0905c1c19b5605174231a5a6143cb7b0ac0af67cb94e4d741cb14c3af8b9609865f7f59a6d4af9796e9855f8759a6f7ebda32e1fc3a8e65a2e1d7679609c9afef58260bfc3acd32b9f0eb3e9629007ebd66998efc7a906502805f77cb64e4d751cb34c3afdb2c530bbf3e649998fcfacd32b1f0eb2c2c930cbf6e64998afcba0bcb54815fc759a69b5f87619996fc7a926522f2eb4a9629e7d7972cd3905f97619994fcfa0ccbb4c2af07c03251e0d76958269ba5baa74f94be356c156aa708e04cc1bffeafbf4e03f6d72dc0f9eb01d8f9eb00f0f9eb3382fe3a13fad7650cfdf50a58fcf525177f3d07e3af2b29fd750ace6a91b68cbf9e74568b743dc6792dd2751867b648d75f9ca245ba8e3b4b8b741de9d416e9ba8b736691ae1f9d348b74dde8ac59a4eb2d4eb748d7599c368b74bde8bc59a4ebb7d3c8225d273a7116e9fad0996491aeaf38972cd275db39c3225d2a1aebecc53832988af346feebe8e9a7d01974029db5f3e7dc3376c5b2abd563a761e7397715f3d8774e9d7357358f7d76eecaf5d873308fc72e3bb7f5f1d8f5193bb78d7aecb073db248fdd3ccb735baab753bef268380c361001cee5d44ae15c4ef56b44f752e589e8ae57352bc420baadcee943b785da6574db295bf5d8df1a599135337ad3bee646b8ab847f30fa559ea59a5279336e8052533396664425594a5a7a824ac2253df62f3b68847bec9fd1cd480dd7cd76eb69d9dc860d4b0c58fb40daacbc38dba83df64f033411dcf0c00c475bb23113c10d6db33133f280164149bb91fd46b9717cf938679ff349578b847d8be5cdd5d42784708a2d25903085ae8717352510117eb50732388ce912c4051282209115e69081d72386ac333a22241ce1252c011128d4c0c584294af092664bf8840b574ee083102e1f2768e120d38da03ba1491256824033259c80133444818035c58820cecc109aa0cd1340bcf940c90d55cc3819ba0a13840a6d94d47082324c3c18a306092134b4095302191680382289102098b9210d162354e0208a287e2051831211ae1491c2f77ddff77df58a13595db6a420458931bd20e80b1282d8f0f402991344208284f033cd0891a5a3049e8e26d23cc4e7127a7cceeeb7abf47ddf057a14896255e487ad11c6bcc981e9f7c1bef2802893132409149128165a5882462b3bd1c2536865245a4bb4866811d1ca45b4f0105a369c3f3014c717599a3272776f37c9bd5d276153f776a9eeedfacd57e92a5da57a95ae52bd4a96eae62c8f3745eae6ecd454b5bb5d92a79bb34f4f96c7cd599dcefaf8ea22b8390fd8b8b90d947a5c5f7d833bf35a97d06abe337af59b118f57c7252dd1bcfa8cab642ac1bcfa007abc3a0607c8c0c7ab6be080085ca5254e9efe78f59f2278158bb556349b6c93aca91b60b8cbb29b013211f3b4f419b9929461c0dac2e117ae7a46d76cca41ed550afa478bdef6ca8a59e2e469cd73fcbac5ba01a85da59cab94e3d76b39388d2ec5253f3f3229f4ec5ce2e3398d0f49c6a2746d498fe7343d262642dbfcdeee121acd34c99c451b2de1e11983e824dcbddd253bbe63863df48ca57bbb4b7496febace87b7f400ee9299e734da62dd227b756fd7730b1a837bbb9e465b191220b09e82af3c20a29e8cfd344086c3c608596276a9cc6b7aa5eece5c404d655ecd05dc5486ea0ba2a065cc4e8b18aa1f231ef49002892198f86063450c1018728200c2abf22901f1c2e585228c40e31466cdd83543ce194957948f1a6648a28627217ed8906f789203c8981c80a0d2040f3acc0026081f6fc2207e8040e583820f614029524723a465e9ab5dad6e8f5bda00575a57ddaa3b874e14d19d6347e3310284fe43b13f4675d809692bc63bfb5773ae18638c6eec1f8a2d768b51119bf12763d65a6badd5daeada005b895759342ec637dc92dbbb4bb1975729fba4a0eb571a37973f2760ce19dd9f874e7edf9773fef2f77d9f8bf9dc95778a637df988e67bab34b1ee172abae39cddd1b2aa156d49e3ae886efdb2ec2097204714f1206a7bb6cc55027368367d4c501122cd6fcbcb4df9bfd3fe0b225c31e2b7dde51d50570682d9e7339b3218fa7590891e65d0fcb6f7011f9cd83f27b3d9f4e126bbf572aa392ecb91c95ce6158699e7380e1c9fe5a01e5c29a63ce1a03a1cc741af0e17d92e5c64f5059900b184807db061041f9cf8d064874f903c7ee5f9f0f47921ab6d83bcb7d5b1e8bef2aef06aef2b0f87153e3f551956ab1e5906dcf442e1a211f4ce4f6015ce7d5074ed74dabfa92a9c9351648b148f87733952eb9fd5778573301d7cd8f2a44bad7f5938b7012ecaca3d9c6bf1c313434ce952eb590be7725479f3e6cd1b2bbef207e22cabd1fdf5defa063897b770917574572dd4b4254aa2dfeeedd3db4f2a4fe5aa9ef54feb09e7729a58c2422fb59ea1b670ce3a815579f76d655e9109469e9cde7e4f34fb41bdfd2eba7317a8ed2786ac968903fb1d84808310fc1af56b3db24cf5abd71564b56dbc55ad16abef8d096d7d6b7bf1ed8729460b153d543867c99f0e4e4e6f26f9c01cb41330ac584211872c16e49088664988e37805a7e3647c895680bebcc8320baef270608ad14205f8611ef766734296592cd83433486966090096f16f997bebf162c24e007cf51ff79910b0d80c724b4c972bfca631415928da105a2643eb9d37329c0a8094c0c9917a5a3d9a4de5cc723c23cc7494b6e8ec7ca1e025c40ecf0f49578e858796f318ee413c5aed19abff70095584e0e7617a024f5a7fdd678773396a7803b5440a13da30712487df3e5c9ae8fd20c148942474e9f6c1f2dba792397383086f8cd031e44dba7d70f8ed63a5c46f9f2b1f2c2d3e44b444fddd3eaf2b9fd795cfabd7f3eaf9bc7a3e3d3c9cb33991850c0f4c7c6872c495df3d25b061099b10ac38a10211e9eeb1f2bba7891d9a10f245ca153247d2ddc3fbdda375e677cf16d70b494f941792297f774fd54baaa7c94baa87ea55d5b3fbdb23f5d7693d9cab5746b6ac382199e2cd90b4ca6f9ad65f29765052f5419a3457e9a6ddf09be6e2062468b2a42cb1cb92ee1e2abf7b9c9e86fcf5dd03d513b5040dcc123431fe9b96d545ebd245c37a39d1aa5e4e34decbc9eaafd3743857a580e255094105104a3062ca6f9a5391d490ac1c74d0ea6242ba694f527ed3a0aad090c58b0b6894880122dd341b7ed3a4fefaa64dfdfd4d1bc1f08c607878d4f070fddd3c5dbdde5f1eadbfceb3c3b96a35441026a0f8e0893354d228bf79a4feeea4b2d2a4f0c31133e9e699aafacd531535044b08266868d811916e9e1a7ef3585d61fdf5cd93c5236664c243e49944fddd3c50533c3ea67886f0ba783c3a1ea7bfbec3c3b9edc48ea9a822524cb540c3ef9d094031460910281cdc2c49f7ce0cbf77ca1c4105c994a91a76a090ee1daadf3b5a7f7def6ced70b5d989d266cadfbd5335ea769a8cba1daaf169076a7cdad98d3b527f5da787732ba24822a48d14179b23a0fcd691009728322d0041c20e27a45b4786df3a5d1948212545083abce1724af7ce93df3b4e7f7def3ced0cd1a203468b98bf5b27eb4aa7cb950e564fa7aaa7c3d3b1faeb3a3a9c2362d3c49724d448c98a4aa77eeb0899a201092c4f5c31a12add3a4e7eeb4021400d1537663e6063048574ebc4f05b47eaaf6f9d291d2a91481b91889bbf7bd625eed4883baea959d6546f4aebafcf76385787f0f1440813c61899c22385e1f74c2acbc9c9852d4e4ca124ddb326bf670228a2862a40a208614c0ee99ebdf07b66f5d7f7ec6a86956646244dd4df3d0bb766e1d64cd4e588ba99a89be5d0c0820845ac10a5072e5f5cf89df332b264ca1a2e19485022dd394c7ee7f040a50405ae3146207993ee1ca9df395a7f7de76ce57069c989a225674a4e931caa9edf39555739505739bb1c29adae9c9d43fb9d133ec1099fe0e0e0d07ee3845538210e1627281ca9bfbe71a672af74e3508541da8441dca8e1e2f92deb0aa1645921542f84d29221ca191f3e64d8c1ab926ed992dfb22aabbfbe6557322c7009191170095994cc876cc8ce6f19545757974cd7e56495a5b7d65c5674142b53feea2ad04a37b1a2cad250597a9725f5d7633d9cab65821882ca961dba9a3ca5b685df312d28944cd165b1c1865dba634a7ec77688b082113b62d0b9a9926e9de4b776faeb5b3f6910490c44128bc5b0fec6b2c0581518e38131abbf1ed3e1dc986508104ce0a16b8824290bbf634e3574545cbe484121871ee98e9de077ac2e2143171790eca6d44049770cc9ef98d45fdfb1a918d5126d9670f317d6f575c1d47c5d5ca0130c7482814e30d80ee7162085cb0f2976f84164f71b56c14441452607246d8c18936ed80abf613ca826ac4ee044854c0ee9861df90ddb3018961518112b517f619f15ecb3827d59e69705fbb260260fe7727c70240c12416cd9c1c41babc26f33688a561b116490a2254cba4d1bf5dbbcfab1e48413aeb658e121dda635f2dbdca6c985c48c8264ca5fb3c95f73eaaf592565424999bb6d4afdf5b287739509146890f232246a2b4d5ae477a95501178e58f9a1042740504977b9f596c8efb28b053655a474ecca2c916e13eab7e9f4d7b7f9640ef97494603e1da598b24b89f5b7ccfa9ccaaacfa9e4edd2eaaf973a9c3b40126b9ca0e1618db92185dfa5539625b4788152c24b0c26a4bb44e17749d543af0c9621b8146193eef284dfa5d45fdfe554ceef92ca0bd9c68b9bbf6457ce22d5e42c2e2d324baba7a5f5d7c91dcee500f2e508167638e10986ad21bfc91ac4944eca0a503790c025dda409bfc9aa024001b36608992b4c82a49b14f29bb4faeb9bbc22b19e90449e9051a40f72c85f12aaaaab8ad46d9287733c49daa059e2e4c7961382fc7e591d200c1145b4803ca52993eed7d5d3ef57d60d26f8b801ca171d2944a5fbd5d3faebfbb5f5e2ca415e517290d794579317d5df57557e41e5d72ebf7a38577b505d4a1429e28d115da92de1f7a895801d2660713a8344d491748f5b16c8ef71851b98b4b015458519a8a4fbf5e3f7cbe9afefd7d36b081ec1e0514cf97bccc263173c62e1b10a8f3c3c5afdf551877320b841480c63c490b01322f5f17b749a8185146a006303971ee91e9f9e84df23d411dd0c312c41262b041de91e7723fc1ea5fefa1ea7462a6c456c83ad886e443522d75fb1cb4accb2ea59ed706e5cd2c4901e42662823432ac26f512a07942f49a69440e5871ebea45b9c72fa2d3ae143161eae7a38d1a149ba45de87f05bb4faeb5bbc12b1701091080e2246bd7e8b50184af4210ec1525d584ad461291ece6de089335474d0d1c2134a52107e873b4c6d21c14b218a3031a43bbcfa1ebfc3ac0d58e04161450b0f880ee90e7b3c7e875a7f7d875b215711619422c229e3efb04a2b6ca215527585505de12e94faeb600fe7ea159e0e2d4360d5d0c312e98edfa09690962c3fd610c9024256bac1ad0f7e835d7fa5da8809a31b42058974873a1dbf43a7bfbec3a7bfe1102d20182d62c474835db0fe825957e0942b100be85402160d52449460f2258874834f7f75bf412850eaaf6f702a074b37487589b4b944dcfcfdbaee4ecddd714d7d5953bd292da9bf417a28618286aa89287a48f737f56f7e7f559fd55fdfdf15ceef0f2bcd47244dd4df0f6aebf3f1776bc85fcf5d9fee86a9526303902e42ac4e904ef13b5bfded42a5851f94b8e92125ddf94a8adf994b0a2c418ad4b0860990746737bfb3d65fdf794bfc9db9bce4285ea6fcddb949aecacabb9da57232fc7802ca8e24ba256914bfb156d5902436403142e40459e9c650fcc65d5d57968082c85615978f74e736bfb3d3d390bfbe3354f83b473dc1609e88d9b88badc245559867b10ee7aa559b34407a3abef850a4eb3776c25039e81842ca933527004937de3df11b4bfdf5df98eaaf8e3656879bbf4eb8488d13d743e1a2acbbc3b95a86479612c82c59410a98d489df57aaea5a31b9bf2fd6022e91ea25eaefbe500ef0f1376bc83bfdf59c0670975205f5667ddb285fc194bf396618a2ebc70a3c64f8b2246de2b7b55a00102427f43802831b2ce9b63daeff6db9feda24346e91f56da3fefa03aad2586fd62ffe3d8af96b9b84e9b643ec1313bfad53056c8c10420424b844e892b27927217e408982cc942d4b6cd9f284e50b1a273a1de9016e4e57b4c7922f639e44118509e9c5b9ba0686105ad0a1c908315c49ef9aaf00981e11212c99024c557a95f8eb38f0affb127acb9ce82dd3e9abb76e6ba2b7eebd75f3047aebdd5b3791e8ada7deba6ea2776cebadeb17f4d6bab74e1ad13b76f5d663af58158faaf382de31a7b7aee382de315b0c7ac3786fdd0683deb0abb76e96a037ece9ad9b3ff48675d1dbecbdf59e2d7a9b5b597a9b5ff436796f9dcca2b7f9f4d66961f42e7b6f9d2684dee5d65bdf71a37739f5d677a0d0bbe4bd7520357a97bab70e8484dee5d35bcf50e84d3ad19b9c7aebb318f426796f9d4704bd49dd5be771d29b7c7aeb2f2bbd5f576ffd9545ef57efadbfb2f47e49bdf557958be8abeaad874588553fbcb8e2458f994da2f3f41ebbdeba57d1fbe5f4d6c75e888ebdb7be0208cee5d4ba4cea2ad5add00a0a940f6d1f3acc6c0a5d08bdc7a9b7ee60f41e796f7db645ef51f7d6675af41e9fdebab6416ff1eaadeb287a8bbdb73ea3a2b7389ba2b7b844efb005bd45dd5b171241eff0eaad8342e81d5ab10e6ee90d5abd75708dde60d65b9711a13728f5d6750f7a7f5d6f5df3a037e8f4d683b4e8fd59bdf5202bbdbfac87f2200882a283601623511ff27ce8a6d9149679d14bb34924cd269066a57768934aef9cf5d64d287a67adb74e12d13b57bd75b288de19eaadc79eacc780e88dbbdefa8bca7ac983de7807bd7110ebe293deb7ebadf7e460bd078bde77eaad0745e96db7de7a5011bdafee15c03583171d4800697325cd497cbe62e4c7679f65bfe1ec349d4ea77b4ab3111fb6f8d05f665398035daca3d9048a6653b6593827d3c9743624f496e9defa96eddeba6c274b72a5080f9539c9745f14fd5f0ef779fd7e979f7fcf3e7b95faecf92ac5f88c6585309fb1ec867c76d06ccab52a7d0f66b3e92ba5d0af2dfd5aa34b157419a5ad1859e13176db8d56b352a489ff3c5f2516ff55a50a840b9fadd98471ff15a1bf5ed1ee65bc1144e9a4e82d9e59e449e1b42a9538691e4b5f29320196b2b09489e505c58ac345d8afc61883a8888b70d5bde1f034deb6eab1ae1be7a2a979accbdcaab13cb5bcca9205b2e441014b59cac298a5e804acdc71428c953b49e81268069aac9465d1db5e5d5d5d5d5d5de1943b5b39a598c4ac14d55ce9944e75b553024599c18856caa674f5945a47f629655bc49f12a8aa572b3f1ab4804a5993a0527fd02554025df172674ded2c3f1d325a962da8284536b652e45a51c246182a452432515926b9955f1ad16e5c510964456f7b7525b228c5234a71a66b34bfb528714cd6f78b5c6599ac0d6f947345dc339e342a7b6a4eac4538173a765c95f1557f5199b2579ede9465caa82da22255e15c88da2b32323c268fca9b9a6faf663a92aed2b6568f1dbb6851ab12682eca0f8af592442a3f5114af704e0cfa7c75f86660448ab637e79c69554697067ffb571df40e1f7c38572cd2ea598de09716c1ec9f69dc100cbf0fbdf13d08826808becf68c6e126a4675c7e58c962d046ed267e9e453dea10c5a9a0ad6f1c4ec4b966d3222449ad5e95212b0d0dbaeb99d6355ba6cf33ba6fe01b2d63dabde1330404b83a5b8fb2676c367dd93400f9e6cd6f1c3add67b483d16f885f91b2571c21b83f82f8419403fc23fadf35b5b4f52dea19cdde1bf8b3df376f42803d3f652c6af03fd75ba4812e82a7067d8b354a54d3b2e72ca2f8f6998681116d7d572b119b4d1f885ad3003a2e00e1c20f016e463b80d3ad21abb5b5625a5355aa32aad7db757d6f5729a7deae5f1ae700ead1f59c8c36d5db1dc0bdbdbea216fca0d19bf6167ccd6d94d72da8325e7fbd8a4f1863a85b84c590062ec24966b5f681f6dcb6123bbe50160a63df007f7e4f31f41c8ae199dfa2153c71a8d634dadeb8c7f5fac65d259427de0f8d756b64abaa76aa4a5dd036a1592a5e2d4700639d2a5230377d8ba55b290fe01c0c45f57d6dcf8ecfd0471bb6a610b551e69fe5b4786934f75bb652958751297b355e9007d1f6642cbbce4fe801dc9cbeb8a58d2b1f04cffab9ad36fb8c73b6fd2dd7a2ecb5cf5b97b6c74ed06c7dfd1aab36cf15004e9ec67cebbc132e8df9e629ddab87d64df00b40ccab93d6afd9047a788a2f7a782e8179ec7412d3d1699c03b8b7ebaf13832ae6e9e7cde8c49d49df396346ebd23fe2579ef884f6df3acb0d51e0d31880d72bf2662ad2b595b69fff88fee342fe23a2190079cd831cfb2549bb23f393e8a4488aa4e8a26f27495288f42092249d244992244992244992c4c9f199a9cb4c9224e943923d64a9494d239dd42167a4e79038a4cb48922449922449922449922435192361a4499664261de8ac9782ecb553c445d97f4e1b2996f072cd45d77f81fe73ddc783fce7a219d4fcc7813c3bf6d1c5fcf432dd6a6151d4bae2a0f3ea70d1cb814edb858b5eaf97bf5e4ee3be5e2ff7e979bd5eafd7ebf57ac972665eea382cc6f3bd5eaf57cfeb4543b7c8836ebdf3d241b7d5fd6bf6ca7939ce4bf6728d6e0bf5afd7ebf57abd5eafd7ebf57abd5e31747f4e30747f4f26fa2a5f24ba3fddbf72d7bfbc76d64bc1e73fa7888b3ef739352efabcda5e2807409ebe2110a4f56ab356c7c32d6ab1b5d8626bb17f19049d043ff0033ff0fbec67cfcff3c901fe2e309f568faef730a9ba53ae9276faeaf9c4dddb122eba8e4bbab71b8446df2a7cabee5548020f540f3ae8a15fbbc4741a97667b9eaaf4005586ace71c6b9175515753ac47d663e7cf75d26d0a3b7fae979ed30bf07360dffc580527bebe66b1a184c7eddb8f6118e210dda367979db11376bedc9a178c2e827ecfcfc76b36ddd0ab79033f017aba9ca17af0a2366e0fba350dd0d3e50c9407d1254e9e9a68d22db2e29b674dabf9a138f14737554afe2ee14e1af5c8fad882f6df22f9354b95247fd1adafeeadbe58af5e170c81b426a8faec3f4cf4b6bb7dadfe7abd17ad36eee9817babb5d6ef73d2def2dbb9da8b737514f475a1223014185bae9ca1d8fc7dd94eb1903f300cc12fc3903f300ca33e10fcb21afb81e0976308c2e6efcb762a7f6018825f7efa2167305ac6e49c79743927f18484fc8161087e590b981cacad923f10fcb2182e536e905a22e74ce6ea03c12f73d1d223e74c43fec03004bf1c953f300cc12f47e50f0c43f0cb4168f8c1bafd40f0cb27a86073b64ba6c879899c57e821e76c06e37b31d8f5808688b77e1b418a2b34a001b3c3e38a4081bcf8e6308761ce91befda56bae1cbdba5895aa522ed14aa215fbdf1d7ef5af32cdb048d7ab93e1f9d5b1de3e7386e863eafce775dfdf33c07afb5e21787cebedcbe07f2478ec7914abcfc6797df55bb357276b48d3222a81c704705b2d8665d4deffdc667cc1effb2c0c58ad479fe31ce22d8390a4bd49f2ae3c2da8bf713f06f2050c9cc2ccfa47adf94a5951b5028be8cb9010222e2229a2158874ecb819290a43a464851344552c3e2822f2e4c663280a16405a90c04209d18e1622ecc06237a445f401113a2f5c3d845022081e0c584154f0a10513ed8344914ec3c614d9a071b89c408b3810e1a0c32945635644515a714249eca981826c9321493497c49001c68b3cdbc2e9c8806481b25c581b9423738891d8f3a5c52c0c0b7287a24c2be2b68308686b684665137980a8105f3ba0e26bcce9563c07e1201494673d00e92a353bbbf2d3c4070cc393412674b20ccd2c6bac9c1cc4038e48e341766b7c195f70ef05f7332fb8f55e6dda10dbc132b93373ec84b22a7dd96dce8ef3bd5d8b5ed4de7b2f112f116a24a9883d59c22024a0f87ae10381b0f98dd0d6efcd366808f26b42c3a277feac944ffa5665dc6a9dc80e38b06ffefa0df1b3571bf9bda0770622a37307e1df10ffe702ac538fac59c3fc8a8af588a719503fbf0ec8e987e2f020e7f0cd14babfe8ce135a3c33ce395f8b03db1efc7dbf5d5cc415875f79686cb8d7f2b2a665dc17ed5ec67b7b86042f5b9248abdb31da46f13194e0a1c3951f8e20a24c5a2b88820b550e3bd82401c142f1d66553aa8cfc96039f4f5da56fcf40073cf67beedb5f7c4fd4c6edb17f32a90f95ed6449eecd7acf11bd653b190f99d355cabd951129222223521455e4a368c8df5d0425dbdd64bb22d9aee8c6c3b91a4c52d0b1c044162042dafcbe59d00684221f38a10b018874dfba7edf96d270e95a808147096fd27d7be2f74debafefdbd64db7b9e936b7db8deaef6ddfa0feeefeea9bd45f27eae15c8e11ca08e11df18147922652277e1369fddd41260a0626929cc9926ea2267e137101e20305365c88981242ba6f5cbf6f4e7f7ddf9e6e43b41081d122e6ef26cad257445df4151196ee1155e91e114ff788acfe3a910ee7aa9a214852c0c1c81a18aa30f19bc8490a0612945c45e124dd444fcfe6371114971f393061e20b5710e926da1149fdf54d3445fe26a2d244da68226efeee21bd1bd2bb213d35a4a786f4d4d0d00ee7f609bcbc312187373a6459e2f7d00b3a2755218871626647ba87b67e0f518006303a6489a2030d27a47b68cdef21abbfbe87ae62bf87b0d20c1149331405e3f710d4d6908fd8d690bfbea24beb86747ac8e9afafe0e15c03c20061c6092423bc014289df2bac9ae84a82ca981c88689921dd2bae92f8bd220b4b6bab0d4f47e449ba57a8f9bd62af58c1a56545142d2ba6ac68b282eaef5e51155b115b115b21f5d76d3d9cc340cc112c167ab0c10d9a1489df362d105c684184351fc80025ddb6237edb7a1f6831028a1e5a745049f70add0aa7bfbe573cc17eaf18127b6203137b621363eb62c3fabb6d595536dedf6db3faeb361dcee588caa18525588c14699225cd6f1b9a188ee872e689d319a874dbb47edbb0b4c023ca09549e5449b70dcd6f9bd414d55fdfb62adb94980e156d623adcfcdd2aba624e2ad43871fd85c2453128adbfae628773357448783494800505efcc6f1552434dfc80626a0a4c1050d2ad62cacc6f1555171082e68a8b10639a48926e15bc32bf555805f15bc595fead020b96460511581a15512a7ca818f277ab80826da16e605b2a78fc75948773475a469280b0638a2921647ea35a47a889828d151d2a40916ef4ca88df6856932294e8a1890f51a8a41bed15f11bd5bafa8d6ea51be5824541a3c0a2a0538e7ea355301eda8447054361280c95faeb670fe76a9b1d08563d429042e607dbfb7d563160a80851040952b89192eed312f1fbb422021b2082d8d1852724dde810bf51a7bfbed12774084c84130c4c04317ff7097b3a614f276c77c276276c779e3b40f1c16e2a4a93273ec6fc3e3da0c5083233f08010c142ba4f31bfcf18d63cb952c1071a76a090ee73f7617e9f527f7d9f53e6ef930a4c1b306efe6eefeaa9e9716d79d6566f4bebaffb0ee754b8e131f1810213bb35a910bf7d04a7204ea08a820c9523e97630bfbd4a032b5ba8a0b0830c4d9049b767fd76abbfbefdcab198381126517fdda1cc29f7313584d7c5731dcfe9af0bf1702ec71122d0a4e08305166ab0f2e5b7908c1dce7039c1c525cc07e9160ae2b75056069c78a932844d1125b449b71010bf85b690902982902982909010d5df2d54650a4199423b5348eaaf07f5700e035d636e6842c9921f74c0fa1d54a138320213676ec04ac2857407fdf03b288745489a10aa70c16221dd423efc1672faeb5be849680898203060c4fcdd4159bda02ebd20acada0aaad20de0eb2faeb413a9c8bc0162740b0a10ae10b0ea997df414e2190828411509cb070440de90ebafa1d046505c5ca4aea863160d21dd4c3ef20a9bfbe83a682a84a266d4a266efe6ea0ae2935535c3ca02c5e8fa7f5d781763817aa41c24409251f9c8025e5e13790140792f0c035029b2e1ba64837d00ebf81a480a1ca13504988d8ca4a375097df401b0808ab0d109136517f37105409e4a3041a52d6ba4a205d09e4f4d76b3c9c7b00970f7690f24215ac255c7ed774a60c3145550a2a84a14a776dcbef5a16053c1c4cb08107066b8a74d7b4fcae69fdf55ddbaa7191b528646d4aad09d5df5dabead5a07ab55d4f4aeba7abe6f4d777ede96f6d08c9e4070cc944ccdf1f72ea879cfa21793f24ef87e4fdfce8702ec79414ab16744873830b4c58fdfe410ae2861b868042450712e9fec9f2fba7eaf0640bcb0a63acae9449f78f0ebf7fa4fefafe99027fff50b569d3c6cddfedd345ea7cd4903a1f2ef2c9278b7cf2e99101a022a814091a0f7349a714325323c00040002317003028180c8a06a328c9b144f90114000e63b65260521e0824f220857110648c210a004000008000008001a588ca00984ddc1a451fbaf9cfb961c8ff7b3289e65cadbdd42222f66c6dd6ab7c1bdf1cf354aef12ef285df769b694d6dc1a333d0b5a3f8c7961c74a0d18c4e3dd24813a7e9f27ff25e9a1dd91c9326343a600a343ef5146b088a2bb11db8e2bd1fc26e9e0acd637d1d476173dfddbcad8b587b7267872f7993e8e7dacf52614b1bdeaafcd3e9be3aa9665dfd2e71d8f38ead7514b0b51baa7d7eab015f23ca901cc98c0413bace4278363584745700bc2f7ca205439e90da644d1af0b2c967765d8da3d3df290edd2f9cf2f48b3bdca118d5d6219b6ae8b4c33159f190f0ad12d23661796dbf0d3d46d64c6096ca0565c41bc82e53925b09e0195e730346a1c0642ac0762c782667a657bd58983e3a8369db82fc14df4c805591c5fbe8a63c420b9f468bce76a6f6e011d37547d5725005fadc4e0fd345637e8e0cb18c4ae6dd1061371328c52b1243f80e949c444a63ba5761a8afe2977ec36594747496e8fef731c433c3eeb1d0d4fcc9fdf6b11859b24e1a25930c61d914d4faba54e98d5ed4fa360a3d63e77d8aa7829e273a89c921b8aed9487bb9631e24bb547289d42e9521f2525d787d157d6f87f49345f26d501e97472c6e0d1eab884ca5d0a58fd4dbf8f3918233d097deff66b59aafda223d13c89e77d3a2ef63da73678d9de076508298328aa1c0f6c8bbaeae0dcca05c424cec1a375b4140a5c3e1a600280a39219be2449bdc19889004b31d38a7abb8d11953520f59b045ae700a7da6a498aed89686f7e93aead269de6e7c31b9abd054b762f40cb42cda90661a5b4a99290828a69def47260d649b6b29dd69b987a21275aada3f4c3616e554ad56832442805a962a68854d48274f4a9379ea14136e4c3e8b34d6377e003f991b3b73e4954f2920b0a5cbaf78b2852ccc7d6f7bc11981e052475c585592380b8d49ed07aad0b6b4f3aee88367545be5f15a2636cf5a225089fc7fc859ff7d41bfda5379385a2293bc6a1e9bc464b9b2a059484323829b897417ddd929969b47ad0a1ddf0339df0f15388d7c1e88a801cce4e69b09988e7b99428bbb2bc51bb64ddf4f022d57f4feb932ef720745e33c403818245b4f786ec3445ff9b020a71299336c04ddadb0b968f1081b6981a7b05a70276f8a3e2475ec520972156ecb28d02b08c266e1ea436434c9b06eb243fd122bf46219028429b3c013b9b6746ab970370f957df6fd2f64f4edc25d7a53f220339b5337a1c145c448f46f9d2f638b9a1288abfe40a3ca171740f87c1da80fc6349a5cb97f64094a383086c0dcae24701e8b0e17ccc5c07accae4233dad06aa3f31c706e046b7e50e7e9012e270c941886884026fa8dd0cb94b8dfd96a9bb854b39853bb78b30b30d209e810e5f256e703a6a041dee10f28cc625cc31ed8dc3520c2f8593c4632196fd7a2a8d9a0739414c4692c11b771f94e059c92aab39bd05bd24ec8189dccbd68b43e246ae26b2169b03bf141a60d200e280b6e6826703a008e9eddaebb7c5c3e5aa63cd390c8884e9e5f203755dec2f9bcaf695e54d5990806af7b6795acc3450fbb5534e322068ed64018e2f83ed9ef25705b193f2eb28fc91190b3c4685e17053dbe12eaaad9e4b683e9e35b32dfa544f1e87e301a1c4a6a5519be059303174506af9813a142da9596c9f9be4025a77ffb80d9de20e5db07286065345dd331684fa9dc4c352704695315322e616356d685f5aa05b043aefcd8882a949190870984a2a0ac1711d1f32bbe380a5169c09fdb553805cb7839203d0e961b5c3b6712d736b0178dc0c8fdc3604458418ef59a1495ec17edbdb0fd93e482a505b98e645884c80cfccaa2ebcc151a4a59593d76476620572e0288eda5954c755846875d40ac7c68114296488107a4231b80358a59fa70b383f0d36f684a5119885bea4c36415da8f7e8e4b551d995b449472234e3e14f58c2e75bbb060e558b7014abdce08fc5bc86dd8d83d18df260375ab882fcb42866eaec9ad651cf204ef9790048beef049781281b24a0b6aa0af03f183259e16a4ae993d60d471ad0220cf65220df03161ea5d63150ac17e5828c4130603d662d2b7bca17cfeb7cb85913df739cc507e3edafa0525d79d0c432ee0611f908d7bbc0a4774701c159ccad6177486e090f8e1c26c2432b74dd77c9109bf448dc2b1a4d2594d3f90b5260b1f31bda13e67ff72b008d1c7b5813333008eabc0ab8e65b7943d79827b130f38fa6b3560131e08352224285d60ad88cf75986348845da5b733b53b4f6b2a722259df684eb8a197029e92f568a2328bff318b4f6bac434abf55c42b357f0955d4e879607e48cb80849dc3cee84f722fe6daedbfd4cc20cbaa08904212285acc9f76b2f9955511db465e06dd0a82d9052fdd53da7c962ca46052153222a0d7e8f7a82fd0cba40458bd8105b97c4fd3bd2728d0b0797559fcbe18279dab5b9a541ae2423f23e971d0fe1d60ef654a3b512932aa0ea8e369d8240358f3d177e410c37ec8b918b4a7e97a243b382ba64e96924e571117f7458b358242b6795f0afb0fa388445fe239e16cf02d1be3e6df042448478e1bc457769af7e9705c560038c239c0132892f0e270e30408e3f8ff30388a864794d9f1d8511e9940a802a88ad15716c87d127116145711ef66089106924c820dc365d58b73e8832248a65ade3ea71a224bf922885053a7b8371eee4c3988b55d516e545bc6e16468f800f27808423fd5291b48db1ea191a76afe23448a6af1277c06994c93b41354182680169c2843ab568f9ce0718fe09d05f3aa1f9b51aeb41cfa0c61be9935ed6841a1da7d44b15439934f91c5c412857b17b4fa0c89dd026c15ae385ea91c9a906505e3acc355dda2e9ea456de8a793d5f3299d80a9230f0ce2c4874d849c8041603445b9e26aed63592e7b51d4bdd4c88c9c39a7cdf40ac46fd4b48daba5523e440b8a4a44147ebe6666fb573dbf1b2359bcc94fbb656bdd1871efcf0d343a5a1cb3f4c545905919fb0e9da13a75a97a7cbe996b30fe5562190c095150871da3088bdfb3b235daf2378c3f1a6df731d7fc8875257a1b79fda8859abab929b323932b3e8059187c810170466ec1a012018f5c16fff5837e1e203cb1a110f85a23d09b23acc203f0818b7cb9b082fa1bd61446f68b5e03d58a54e2bd96a32437b3e817b459c661966891ada83fc2aac6da067c268ad1b58a88c1fa290553f059d3c30638956901de9d54485f5269b10befd432eec6d1a1ab0cc8a15b2453f2562c781526acde7801927b34893f06373533b7d45e6b48c4ba67d09900efee3e23162e238ac260bae8ef40a22b255264c0c3f21ede8b771d884692692e93f0ef41656946de9c9c48df1125a902fedfe302622fdfd23eed8633a1ab3c00a2b65b20fc67d2b913327b3a62b8912564d3781ccfc83713331dd27e782955322330f1ffb9859f8806e76ddde7021ad993051d9d6bd4eec18a7b4644e566a86d4d83864c2c426920dcd9c8895879b326902b2a14d5362e25053a64c2083ffb9b8d56f80b492721ce0ca09e3b13a3efedb415726ac3181ccff810dd5bb28d7e79890af32c6245a2eb3e2976034bd4e6f084d2f5aa0fd257493ff6cedd36c84b4087cd42bdbc44ba029a51dca82990a4767203b454a90ebefba85dbba68e356900edff736e47094354ea2855b898c9edc0ecc225bbb48fd7ee7896122cca36eb0bf3d850d82dae5665cfa9314c8b435b858f38556080139d75cf5da329d6345f4f12ae567c09dfa7213c130a08a4e90d4aa3b149384fed197e3e9477129567cc28f4a3847701d85cefb443f7718209ef39de54064c203cc2e07a9e31d01a934a57080af926fee6e5d37fe1ea521f6c674e5c8b44ed060246968eec115a0bb88e0098dd38be8e0d2a7832ba10eae4b325cf893e13232ffb06dae919aa1bae8d0d1f0b221c40a6ee862a2cb5e4d0714bcfb4a90fa3f3be27e64e92fdd64562c1caf3a87e0e96db1888000949f57014c69543bc7f05861d99cfe52db502d7b1af734c23b289c6182b2422d007b8195c932001c6c3fef3b1b3864f2067bf37cf8579a0c28466851c129e684437b6a7ef03cf06843c5d3cd0fe73ce5b215f54e373ffcb424e03654e12654f6e8fc1f49d92fa264323626bcfaae27342a64a33d4f09e32ed5a62cc85f0aa4c846381b297093222f4d1220fb4f64465e0ca7dcac093f3eaed7c36a7d09d4cc832dc5c15084cae1b96644ed951f18fb6d95930056e34cf3a2ca5b6ed0f6809c9da8b29517da5f008e020bb6ccd9799773b5999cd49eb715def6ec2eac642b4adc5eb185e9adf196977edbbd1331e867a8ce6dcc46cbd39d08edf85e80a3a967fb6a701457642b3b6f5be1855987f1396e9991d913a99868f6a55c23cb36fa9191101754a98a8e72a9f9e4a4cab429fd3a2771ec26d668590e339a39c94d7c687f245174db142e813901572587117075de0f83632315b37d0bf7dd455e649e9be53cf49c7cbecd459dc72821124a79601cc008aab5fec97a88375dfb7681a5aa4fb89d8bc40096e803c76a7ed9b7662c06a3f1327fd75d9dbf0a4f79729b0362ceca7466814a4fe0a9484d16b1b6acfa8cb5ace96f5aaa7f7cca31322ead83cfec42ce1205249bb845c14f9e1b7208f9c389a323aa820a8fe11c95a6a7d5bb5d4e35a7b190a4893578512ea3bed8484ba220a610d20c59aa5dd4c2b01dc5933a08e4bd6993e19922d8c509293b355736992042b58528d3280039fc0c3069eca6881234248338b9553a350df75c7f3956501c5cc0dca0c3f662ca6d9e0cce59f58b491c1aa71572702580c50698b7895da5a3e135e2d7a423024aaf7ca9fa1490b24cddc0e507b86167f263e5cf811e1b086eee70a1da8813507b5a0842b5e38a8fce326bd784108ed6a15f8eb5454850ee1d5a255d5cefb00b5e7a72234919859216dcbf7764b37cf55a32db7f6a6231a9b4c02b7d9478d263aa4ddbec17be80ae16f8bebf5f897e9658d4d7debff96542c658de7725754c5823eb134829f9c0da5cbb9d2c2f7d5f80e06ea244ccb5a3bb789963589fa5bc947dea01e293b509473be1dfe3cd60277f28ed50a59ba77c0c297a28d9e84629d64c80e9b7cd8dac03b02ac31f44477532884c09b00be7de1b71ac0d2c33c2461bcfa848d4983c833663d383393c590b80e9c8d9a95853ab5783c55c9c8c4afafba0347a7d192498e7b38829ddf3b8af967fee0023afbed51f7a5c73008cb8185dd3351a53b62bbd62fc74b02948005829938a905225c98302e795aefd0c2160bd7d113181824a3b8bb4ca79a17108c11faf4be4bcc4963b6b280f107787126fe5ce523a487019daceda0ac19d0a6a982247e0668f07955033fd80f668381a07443e6d854dc63156722aa9d71c9a90824dad985af379e78812b7e0451f161351403e74ad4bf00067c7cb433478e438e06779f3d7a1e4a8d69c1c63c0590bf4ca3e18b9841e8ae086ba00822f9478139895d6ed92e9e2a905b7d2daad989f46def36eeb5a37e2eec5899755eed980d75a2fbf5a1ec6e20b64fffe8681d999cda81e790dd0650bbaebe074bb9e78dd9ed1d4f7ed8e078e4ea2cf3f5cb501ee9b49cce98601063ceab24b4883d670fd72f301ba80ed73332f0edfd2390ff702226192f95a702cd767276ff17a11b87a79bfc81bfca5d02bfbb893eac560d4150bd82989659a32737d06256323d8e61020adc76a3a741101b506a1d501416d1a4abc7b9108bafc12b004f93da056573d9993f7a2822cefcd1034608d60f3be8d22a0a6311121eea938d6e8eda267294070b23e8f64994aafb95edd4708936005ebf2ba4282e2060176d1be11558a6664ac90e4eb923ebd25aee87d0cc9f3a83ff73d935c7e72bb8e794e6025fd5bb33fbcb32b8934164120c8fcb28307face6c2afbdf80ac6a06f640a816ca84a31380a3b138f96debb920689701f19327ae48be359c9b27963eb0f45687fa95f7d888beb4836607bf022c9a71b9d649079a271dd7226be9762643c9730b0cbd1b6d041baa65a447f231f84432ae121000326a32e488a01ce3d051f2d4e8b23e53eb0b4d5cb81712760de61828c35058b8c9ae89eaa85f8293eed0b70104e3e9f0997e4e879232bd392902816b792bf96264f442cf5825da4a24d6cce9a453c8e5188fbf0d508c5d468874c374f7050d8e58726810c81f1ed0062d303d0bc289b5ae7986409d6c586e9331021e874e0afb0e915ab0c8403b0c9e022dd6e974b7b61a60933e2b0c859df4bd48e0839288408cd1e1276550810871c30bd053b50153ff758d83967fd7c1779b9bf0b829c30c98d5c71df838891845b1f4256bc45c2268a33e40408df62df428d7800e4dd0bb0ebe1bdb84c7471986c0549cc2c0e7580fa422decd6a2ff549fb350766b16e063da049a96209dec7134ac46add0c501a430358fbcc7ba82496ad61553a5c3639bc3560d734fb13f0eba8a6f1159dad44f5ecbc6e0501422e8c18c223d80514bdf5e29b1734313cbff05a0820bf9bd124602d479094885b834e18772341028abb2d6616a820739c1305d59fc53323b73b7b3887b2da9def9060bde6570e7f40564ff7e598516f3cd75557c0736d25924e958430a0519a643a183d598fa7c50ae46fa34989ea6fc4fd0b0e5e022ea0b7a585b93f871fe91f0181aa7b8dfdf48a7e78dad35508581b5f75b7bf79898aef7b8724b53680afdbcfa692b72daeb800667fdf778c3232151a33c7dceba9e904e33642b15026e027593b26de1663fd3134c53efd07a705a2a277b6d65845bc8df1b1b0c754631ecc3dc1f622c1f19608e17727da8ed45c7ad38259694776dd713bef6ae7fb8296455859cbd49fe76b64e62ecb46dc35b2015882b80bf432c04c5e97ec9183d0e94053ec7ec53a24c887bbf63b4a30f3ac740cca4f0c4edccf83663764d3dde5118177fdccb8fa922b500b99e0dde9e98efb900cf727b1b715094475dd1506f070f3ccbd5330c7839d0bc2b1355c6351ed1a4b80b8b4fd662f1abe4677a0d39a82504afd79087554074b98613db55a5161c4825d19e5a173b9486a4fe9722201f8ac91b2deb558a83d1560740d10cb71fe45cbb125f1536f657daab26c995ac93ecd5623d0c49c6c29417475c8b7d7da8a49de1ef82e5c50aa85e92e9fa25bd3b59490ec1f182f90220e6c9d3dda03e676f26ef384c027078964f11b3acb9edf188734ab8cdc889bf71abc4041a7fc64e733951f06b49b551777b7f481df974784aced2540054d8bc14ddd38b8a593657a1390701e14b6178848346e0d2431e3b9f0b83b51e02d49bb82aa8d0907e71362838655a8d1c0b798a4fd0858ed8623f4cc7847f758be0bd1a894b489a54176f34af19786657be77fde0a0f66e970f0ab6c323ed33b9a2bd58d8768f535aa686c97b5bd12db1acc955066e47cdbb8b0ee0ffc4b78cf4e1104824ce3ededa5e168f6f0275c41120fe2aa41c4d56795225e82e18437c9f2464bafda3a7acf8825ee5eaf8346b494ff932c0dbfa1873afcaaf0be3f2d304ae5ac84ac7fda4baf5d3cdd94c9fcec4ea83d1ad99600b89ba928719117223081699196c1f058f0e2f458a9bdc172edcc8d6d833ebc5cf929a0ed3937dab80888a2e19ad5d2c6dfac4d842a8fb5515d4e7e278ea572729b1d75d2b8cbe65bd5d20ca72c5e70116d4a919b0c42458a8d1c5c0db95c7147343cd1ce75ae1cf0ddda17484995281ef575a06558fcbcd8f8955b78cedf8f3ad053482da3ca8a8c4268c6388b257d160cad4bb8634a3be743f3403e6b797014b9327ccc02d405f9a2472dc05830a1471a264ea008c968296e2da4bc80fc303462614614dcfcbcd71ac0a1af1cfc79bc233a4ae3c15691501abdc18440c409000d811e89caaf57c4734b1cda101535ae6a08390cc2aa778a44403e75b276fba8b20949531fa481ff8a7176f0e4a8b527acebd2ebc2af8a935aeab85e3b27cbb2643d4aa8d5cf052add460e5d0d50248abd0a309f0bdf883f843ef7e7219a968e64f9d6f7b8cf3334acd044c63a5316e1d0ea89e1ea13c6c0faaefe7c03c4853750c8bf591e6448a6a3dd0734e7ea2652b0b321d516cc98fe5a042bf754a5d6ed54e28ef1de1e6588cc280b1760dfa4b92d322d025f4c6c0f7a1800b8c9a31a8dbf9dc732d59a5caedf273963ca7f5b83ed9bbc38fff45702159e04ad5a41d9980b3d6cfa40f4e6e73096b17843d47887dfdfa867cc0899b16f57b5dc173d407072095ba490be9601d19560e025affd6c3fd7c72b888ae28a0ec089ea787cf622e4038bfc30c9e3b14430b77d3f9e2e9955c9fc53bec34e6b2a7fd9b6ec69a7437cbd112e3a8c52e5115aa5dfe206b53b0407521bc8c62b86fca04e4960f144d7f2f24972c019d6a001e8f5f0884b4f3ea124aab54cbdc12d6d0e7fbe953293a6c1359f3d2593f794c3a2898ed250cacea02ec41ecf08312b999794fafba93070a0883a7b1524cc59fba3bb85a02942bd2e0d4160f1686b98815f8b96ffccd2b406f581661b70e921a0a2ac80c15ff39c9f133aa0204cec49142024cb765397103bf1f92989af2d67116e133ea8a8e86bd323b5c256584661fe1f366d40e3aa20be536254ce39ae4e65f812459779a91ea84a1dc9f0d58533d205820462ad75f484d43151de8b765bb8fb060fd183739f834c8aa4387e483075a3c89f4d8fce0e7a163d0f7bcc9b276611b57122ade7f5a03916a861be49a04068093a094e11deeb2fa00b21795218eb897cf0e59b555f738c92299d7146995ea78b274a69353f632d5c31c39e4cdbdf79a91761bdf08305938617d5efc49f755aa0e6b5c6bf3223c9f9058b33fdf2a88479e96428419e484bfd46a8a741f31cfc7d4d521c11a9a1c680b1bff22b306173095c6d3224274dd22db0e4fd467f9990fff220b758e21b4f406f9acb6eac1c993250de2d35cda3156d71ebb25ef04476e3e0cbea9882590744c3be8cca0ba5146fbe7f3dcef9d7a74ecb14884158704ed2aeff71871939e9874a5c6606af1f80cf558c1857dc4855de7460d4511126c922215c3e742340b31d1b5c3b75c848a71d71e6f411274e3b1e0bbc306801ccafa0c24e30aeeff05bbf99de67a47cb6f9dd2a471819902dbbe4e13f2b700ec818e7d5cfdfb759c0909b0ffb1105e3475cc00d382ed67a2a9321e5eda935e9960ccbc2da161f65fcc009e8efd76dda3fb759ce9ca624b9a51bc1d25470eaec57cd68bdc9e40406221871d87eefc7e074c5b064de1f97a7f874603671b74156e2e9e2b8416234bfabb8b9b1498df26dda1995549ecaa2d6b47e406daf69f5c8824bd11d2bb6581f3f7012b74ee68ea0624c3ef044597e1bbc7bfd047c087376b1bb49a575e6b4ed52531f1ef9d8671e77c8c6f500a0365ddf2ec8f8e58d0177d8d8a52832298678e6f27781d35a3c4fd4c87eb124863e8f644a01a630ffcd5c45a137d57a14fe3a1e2f87d2f10cec055a5753c351b3355520821ae8e90144e65b3d4410b5046da3d54800aed416770de131bea0df5d0e6fa1abac86944d5bcef9a9061f5dc82757e998fdefb399ec5584834dfc4ba4f47db06991bd1c7ea8452443fbd12c9c65979f66093a5ccbe708e1a5498a1722619a93cca0004c355b70edb15d1f5b3a601aa6b8d647cdb147a034da108e24448ff708a5d34b979327258edeeadead7b2edc619199863ed14db7b5b4a7a54adb74f45a1988762a2e1098d81277134d7bae71e526b5473ed7a8729ddb5d0ea3d3a20a57b13c4825aa64ca96e0909c2384d7b0f30fb3de700afb1887675accb6e401711fba90632520fb680e5f28c518b2784dda01017dc01475a245e3560d324047758ea20dadcbe1fa590b641d3051697069985b00ac1cf8a5c1ff7ac920093ab8606e52264cbf63d7e8c034e32699455cf8d1a2ba5a7f80f77c3795940d8de31759c66af7c333103b7fce6182eabd3fe7f051c0a515c513bc87a5ab8b292a6d7b350eabaae8b4584e6d1dc67d85f9bc0c6e912f69209ecf93291272b659e2069d0354c36d4b744bf9d744e05aa98d94d40ef903cf4a33e4751b66cc238a9fba76e1bf2b136819a3be28e6fc16d8293d73b75ddc691a393f7793154d550d2ef70c8c99cf9de43c1fb58b1770835e819d8c590f9c34995e818d4734319dee4a18cbc9a4372002663e275d4283733c6ad80f69361f768fbd9cd1805e454074d487ebd9e398116f14f22810f94f826c01b903e9b463ae9d050e2a6cc801c4ef9e3d7afa8d174f172e44914d8208699d85f0fd77efdf3d7b849e922f52f24d5238bfa59e9be8e411b3cd0ed770f34fa8ee9d7e318632d1761fc03287710e6f86415989ed8e6857b82f81597b2917434d1a72f0423ce20afd758085b152d02e07aba0998e7c9a75993e3701319e70ba52ee49d07e65bb3491c9eb96cd1247779441ad1284a30be8b7a162188d97628898a318ad09485f419f44a2119d7aa6bb5c63b4885cfc65dc284474847c8954964f07f8db960545d6ed93fe8aa96dec8cdbb208c8963dce210dffa58f45a63923feef227c4f48659b27a2452ca04573f369efc7cfaa39e90f7bbc926617be5839d9aec0b85b0765f527ffa39deb652860e5a4a53ab64d6cee1dfd345a0cf0f7f7a54a120d6e3278d78ee1145c456ec76d58f454525baea32bcf14952008939d338160179510ef2ed0324525a2470f499733857cbb5132c3bede02842e5b5347186e8f5b13c3aee74af83818643eb4c23e7f10ee10696b90a07df12444af27d75765c52dfe9211869af2c1dbf0ad9bd768a31c9c3fcdbcc3c39d54a0b24408969c8ba15bc31398af27180bfdd0e47009e8a1a553623bf67d2f281a428e1ee9a70fbb98cbf234b4a0814be188d57bdf432380d3a6a6b1a800cda084184ef999d3843bd8fe96f4ccd7042670597696c382cdffff90137bd36d7bf6cef744ac335c5dd75ccc5250a954a1b600200a758f655bcfca7ca6a2448c340b242dddfbcc5b02ac6c7b62280067d49712319607c255c78b4466610e790eea16ebaf9765fa21c5a198e64260112c05ba9382fcb9573bf730504a0b59cc16f914fb8c640d9009bc94dd1128b260184970ad6d20af4476c883a557250abef836ea1a5820ff10456a84b29c24ca66aecb31dabc89b2d98c4dd50cc571101795fbe9677c2eadbe349b1fd22ad5ba6e6490e96934886376c79567291ccc13c10020c25811ea15691655a0417566a5c163dc6c60336e6cb08ca53e903ee50bf82edd7d5508169b2cc2fb2d9e9e79504455bce4ffa821b3bfa8c1f31faba1f9dfc81875f7b2f2f97fee01ef3f56f6e85c3cb428310494dea4454f03a1f182da2387a597878ae59f070b0b640f124be61e2d7b6459dac9288f438ab90b7f22cd750f74209e10d773bc2495909d36a13d4d4b6a3d5f96f83d9096a87b722d757b542efdf670a1aacfbc40b7f724b207ed9b0edaece34e7d1c4d651552af72881d9803e3f30b266654b461d6259f36125db2a50da697d4b561f8259f3652a5b6db06d3efbd6d24452f97b4ff27e13243ef683da48c43c1cc9b64b5a176d97da9fb86f02816b329924411489c501812d3a8ad606d0146113ecb42bc8b919cbaddae0c66948909a629a246d0683b65dda31d4605f79413619c505c757c809ac4c98c7780d25b9b032f0e313789efa0a4d4e017b329524018d15b9be4dedc4edbd35e8e6568bd34cb99bd4dcbcabd3f9699bd302e137b732c37f56a2c7ff6722c43eea558ceecede84e60ef233ae2c732a8f6c9f92658b9894c8f9099a9b60eeeb0c336dc80f19d7d5f01ff46d5f07393d53373b7ab2b717fa933e5865227e6ce566fcaad56ffc4cdaa0e999ba49e39775b5d99fb4b9d393794c7666ece708a19db4b663659197d7765ccb0571031c520420edda58622d7dec7e859ee4324e8dd874dd0741f3a41cb3edc04cdfb3009baefc32668dd8749d07a1f2641eb3ecc04adfb30095aedc32468dd8771da6509320ea2b50a79f4e6ce337e5499f81713949d4e2aa5969b2ed1e457350cb309e37bf76a8b26acd7e08d4250436914111a5a5020d44082e252c352148e1a84a2286888124553031214c41aaea258d4e08242b0861214911a5aa240d440f2e4510d5ae2ee01b89ff6b6d23e1967470a5b710389bd8a5da7bd22d105c84b6852c3703faab5d09075c08e60a65707108e6cf751226990044e47cae72df795af1f7e3ea1c14bb32978fb2d28a18b0c6a47d24407e86db92a3f3655e1bd88594e436c355481d09f19fba94f2da6039ececa6a2ba1db369304359350a72516ec7cecded51b1f4064ba791aa75bffc0da11fee13708c8b8fe9057483cee7b22cba86e228915ebb46bd2143a590672c82bf340cb89463f793628d9af50fcb3ccf3a6f0b8bada356f807fbe0afeba3c173428774d5b014a5a52d0ba091adaf7b38b308133229f6ab544fb40af14949c3dba11da660d92e10782c84df32ecab758743b1629114645abbf4998a1d0126ffcc3a1d0a04dc094fc10e31d7d7de0fc53c855d810ac644a513cfedad39bb61fa8218009f4549a1f1920122cb3b891ded681030a6e5060c54291c8a20af0068ff9f402097710e4155177efdb30b243496212cd5878d58650fef871238488f6cbdd69070db7f4f8a6dfe1baeea6ecd48060088d15101c0f9d5c2b175389f6f2d540243d884f0d4c47e0373273a72034ec36ae693fb5837a6a3bc959b85c6f026966187a10da300f610d99c0c3e17fb340959320be4a683ed3b530f8496ba55a0a18c527dbd8f347bb0e23647156a450f3431d6b8d4bde9ad9c55d0004012cc62418eb10e39509e6f77f6afa0c86d96fa2c3c27523d82fc5c040b2cf6a34bc06d9c26513a23dd1771a42dacab4a0c038d99f61c00b575eaa0ec8dbe42a773942d82a923816423a58af41b65d0d9528b05dd75c7540561e1611825c33ea0179594483e07d108218e109a7d31460277728bfb887a89155ea5ab6e5ba8f8a83c5a70a6d376ef4bb60dbe55bd971c4df31b61d48189dfdcb5870631e3257e67b5248517ace70b1e4b42253518224f0a8558b7719c4c91b9f837b10637c4cae21c6f8807fee5fb803fa7bfffed9aff4fb7dfddd5fe8f75efcbfdff41f066e8a505cb01b44e6242e3fd2aa67ce67fb8262fc0fd4ca1be1a153cc366ad50a9a5bf58296ab5ed0ecaaf7bfbdeaf5632ad5c303e73572c07558b9880016a73859ad0daa24dc943d1d3b0730078a86e85d311e69d769b1a321ed96873ac9775ba1240f040c27744670d94e8209d3049053f4c9a2850a4137916854b56a84aca506bca0d115e44185048d4dfb3b3d445ff8ba469a36cdbea834cb51a259105e39b72c1132aa7dcc519557243af3b5427e3df49070421cc0fb86d0a65a0059a4a4bfb360f8f49aea084dd5ca39254d8d255aa69a030bf3321dc609fb0966247802d67e10b5461567ff8980bfc97c831d6aad5181183f71c0ed3381b7e2d0b461b383b07dba7e8d2bc92670f843ef8d20f3bd74163e3aebd215d8c890036988238459bfc3263b6c3b889aac2a461f0b643f3cdbb402773be3f5a879120d2393a1c06c8b5a8ff8884d14206f8bb414c7f7bb5b3cf29f8472ec94409bb3e3083f64efc0f9e6d220114a6a02770391b31b86f320afa6d3d819bc6660a35281fc9d170d061a10796ad6000a8c8963684011c2a4395464856a656eef0193c3b662709eeed769bd3e60741b0ec67a837b4feb9f8017f097510e63f42b76fb0a96e306affe1b5299b0e38f9683ff51bd6f4144f551c2889b1838dc22db9a3b1a742e75ee1500231fd565b5adb1efc7afc6600cabdf84713377be876af28f2ccdf3cc6ef971b3ad034709c6ff8b30f1ff76bfc6b81541088d6f53d1f24d25a98f339704038d51be8c4e0ec2745057192a9c444530b38ba8d57ce150d15774a8c0654cf19debe0aaa829a6a8427bbea12b4f1a25b2c63a94b5fe5c9429ec51a617e22b3c2305c05f5104ad034746582c42dccdd1ac5d6ce523a2b383d4e98a83ec19aecd590f1c6097064cf7f0a8bf08d1f78e55b0fa5250c99ea43407d706431cb42248e4122686fc1f674860fd0765139f1526f451b415653c9dc1d2cd5f9fabb4bf2a0d44aea6bf4efd13f89726d653f60e3bfde2c92a1b871196f7f997e85a93fe8ec948d494be0597f2c6a873f780c8ef3c8238380acb747b462003e6463410a1fca9ca27503af986504a7365ea451c3588a5f7fa23c4199a0b1e6661587d821320eb323998176026156a3a0dd04495acf90425724b9c67f441b9413a1b02d145921929d5054711fe604cca4fa26084ead2912aecc4c16a261fabad8747859d19451036ae8d8be5fa1f479d40051d1144f6be80826c7846648a34df0af6f61674cb0d56adce67d8eff71f9ffa18e951bbdf9dfe66d671a0aec902c08e8fe2297c8edf6b823ef1010f7f71a44f2318612539b58ac033df658c0fc3b2747cac106a417305a37baff069cafe733c1a19067707713a6d543abadbed259b5f74247702e053801dca07add35e77ed4f4491c5624ad0abdc05c4d8641e84ef293327c875ab65653d8c81443a571f8e5f74e5a2f240996c441eb6567d64349392e7bfd5e513453d76eee12ea57dda92c2bb35c99f8f44a18ffe04e5aa8be4fa10d8558738bfb1ad28bc5c357cedb7e067861f186dbbb3a245960965927901f5c23f9004a2e27005ecb7c3b9352d4cb0c0b4d2d630d8e32371a64377dbd2af7900d45ecc30950e2643c76ccdb546daec8e6223e2bc9bf8b5425b0a2d24ad75e055472234cb101a81e7180dead1278b1e09abf3c7355aa4d5c0d16e97e81a711646c6975c6c3efbe6e8687a5a20304037f3e9cebda2d2978bd3028f7bcaa1d09e3889a49472e7655bd50428c67731fd43fc2443e0fe4063a48b880b9b75015dc58455fbeb2f81ba2923730cea811425dbd4dff6cb20e76c33e8e4f528506721fffde6ba9dad16a32d3949b4ef1930f8bedc94df49b7c002e4285cc5c8124656ef9021ebe6b9018aa1a7481daef874c19e7d710e52d1640a4809b3490562c75feba6ead42d17c6d2e1fef5aaff8b7d012ca1aa424838d4280e5052d2ff93cc1a20b2394cc889305e324ce2b5c643a06051cc679cbfd0811e503197350f38ded07eadd56cbcc0f9d222a21f14be5741b8ec479bd388ccc517c4d42908d3c398cf37b2ac243a6c78ade57ea7730c51b30273e2e5e637363ec74567635c6056609a3c6b59eecbede479deecd0b2a7a4655f73e3569f2ed324eba9e1ff1520a2b4905af6c0af514daab6ac69232e5637be5091385079cdc2248c063ca1b985149239f1433b06081381f11b81b3a968d90775d6f3e55442a4b8f3f3184fd181e4e6762f0afde111dd22080814703b1e8886fffda8de78dbd5eeba706bb1ed45803c233e05121f04a613dcac7ba7ee2b34ac59a2ca9f439ff06f7fd158f84f8d508a3d4aaca7505c7bd07b54ecaee5bc708619bfaa0ed09709df31c6c4f21310f11bdb3f2bb89df2ba91ee7f7d425116290b19ef5cc3cdf56404b46951c0c8874c678b38986c88b2fb6b2973c13a57269323f5ec79f876612d4b58fb91c44586ac06cedbf7ae14b67fb009cdb3c5318fb90adfbd6c6c48765b0b774cb05656b1ec65762fb6d728b2aad69ad00bc8a0f692348357eb87530467343bffeb1284262a3fb3dff9a8b075fada0b76e05065b0307f14a765f79af62ea7ddb916e23d76c7dee007dca04eb8d8187516c2ffe7f505d3f5abefb8b68c124288937dadb9930f77d395be797c2a4a7e60ab9aced9cc3d4976c77f1682e847b27571f284d8f3a514482b3f37b000b07950c45955f900f31d95c937b99bab8ca47d1e7c83b0bc459f11a19f74fe2c695e72bc8ea395cedac4b38abd2ff977eaf906c0c43eeae22a93032a7870d01e19bfafae85ffa9a0f3e069bc0374bbbe968176173b38e4c5383a35d80e4e863500e21905f53875dd4d78a0a5167e30fe1b87d34b058bcc55e4e22c83fe4f84cac685c81efa79ecae4a310b5946793fd85ad07c983daf78b0522b20105b88e251a85dc8a7348328f4ee44775e3e901eba5928c2e4a900c02be691f12fc17f014a3020f68370e63c242f120f822210281406693e1e897e47446785755bc4c3899b5f5220fb96a21742b45ff1c207c99369b21494b365a757307b070a11cbf3123ecb1bbb242996e907319e05e397b96caa6efbb7658ba41e4135c5f9962f7e0422be3ebe65e6d6cf69234bc15fa008f0780137fab22d3b01f08091f96e154e218c8c7c25fecf1851bcaa7a87a93572ee23fd5c07eb0bee3eb4243ec8d5d3fcfa0ac38931664682b7506be24d5f7927abb13d5220ada0198536889fa4369e97f1b60dea267dc127b17238b89b29de63cf74d19bdeab661fc9728796dd58b981f0f37a98124019be0afeea881ce2a58da5780f662531b30dd0e44035eff384e77c3c53d7204712b82224b5cd96cd69c6e05b61f8a8421f006741af436c36b573e0c32d62067db26a0edbd89616698bd4a2d7a8626f15dc670aaf110701e6f24d03d90aac01b7ee0ce42f957f7fc73b9c40d290d5dc885a1e1b911b9211398e8be81a3454f1994a26a89ea276f884bba7e8290b0bdf5ceff1eb39e70b749210340053aed762ececa2763938c8e3e1624aa79e9a388a5078631b4bf7b1d71b7ff492b03879d24f7d4efe48aced9423421656f270c5dc9b4587fce4a1197487ab5b92b7eb079cdbde043c6b60ce5c3480b4168ea0b335c2e32aebd5c4adfa95ccdb8796f854e097f0abeb4cd2a85d0be6ce5463bb14de77c2eb2d30cc17ea507d6a066e8727d2133c62a286376bbfeb5be8f6d4fe8adc44371685ebf9d843edde3cadb992ad9eae20272ec18fff90f44a602c13a64218756e0affc3ec8919d70f11b86eecadd3e481b5334de453a4ed9ba318a7df66a3366e18e16ffc6386452e0f1cfbe6f61e41b5b6423fb1cd40ae5a884dd68c2e396fc5041cc957f4827e8b796268b7c97c25f80ba7c6f8eb8906c240a52162402c6669a62f6953c77525d241e13a0cfc42e8e9107cddd492b08a452e9845a16eaaa942df3428150915e8e62a0dca2a6af6b7cb3cf2fee2a267cb831de31f1357f1ca9263a3cd0c05c87264e20f192dd59412abdff08bd5bfe8dad4ab0674a81cb631a1a202309ffcee12bd58ed3ab9c01585c3b20eb9aed7ebebae70c6326ed8eb19c1b05d48de221504784f30282bfb3a52e7d0c0ca25601abf79eabe090855f26880bc8b7f1d77c6514ac1f09ab2d29321de96c570d726f6467cde180f895ec3c2fbeae36680c66c08d053d7816d484578de03d64c22457b53b8cfbfa40fab9ad1cfd93a8343d7db99529b5cece2e0853bc7f0c20f348797e8f3bb208f2949e64bd788c9626880e8de2e21d092e906cf31e2bf756d33f27d8cbbf2a0a06916ccac5118b3cf9a15dc265f61f874637a17b3f026abb91651d02e2f74be731cc86d4d32e174bf2bbd84c31a6ae5d3f7e9a129d24422e2b61611f852a505706abe7f21893fd5bfb0c0f606260a06871796246bff54b9b1fb4bf57cfc8cd6d72ff3bf9b31471c84c1a51be4774e5c0a17911e8c35a3f4d281a061e94bb5a75df2b9e1f0f21b6bcb0b38a37a3ef32e549b74181e32230c950bb842061fcd8f6ece4b4178ff27b8b8c17da1eb987ac6c1ac84bb41afa445190652c6d8e21457b8677813399d59d40c9d5e4038edd0eb97992cfd3607ec75d1b5b2ff97ae76d93a041a598b9b42ae5e2a840a72058ab80e854af4e2ecdda6387520473db9c345ba22eaa93d33d6991ffbfc996ee939d17cde47d2d4b73b4d10ad6dc0762b0b626a8a411358f362e89a942c7a8b466cc21770b5061bcf26faa3811df30592b8194850377900d4da4dba5196c6eccab2cb091bf4551eca27df5afccb0a955b5f43ae71df731ec3b02c93ab27a000c7304cb3011bdf2db43bf375f1910d58b6c44e270423b5e480160b8301e05b28c0e2404d403636e0114aef7181ca5dbf17a0e274f34609e59fb6b023a50b969862209d4a0e0d1021305ecb60a13fbb58ce2f81306dd7ab2181409975458129d875694ae7a13c1a35495fc76647f80b310acbb78c4ede3c2812947472f011606919b6ba04dec376b3e734a07b506804377c7ea4f6120c7d851690fbd561c01ae76b8b79e1935c122910b263ec61be06c75bc2c7f611ec1508971615c22641ef0e0e3ae003ddd25a4ccfed87b82815fae19da3573c813479c6997212fe2b215be94be2921a73dec66bb97f25b92510bffa04c25a85bae883704c91cbc82ab3fccda12732d94a36b29823ca4746affa834bc7be26afc809abeb9269b5493fa9e9fd27794d1711a85adc3a93871591dac2ce4cc39a8332dab7290bd7423cbb63678dcf2dd2ecc72f243ec9489834080d2c2ee06f4ea5c20d69b9afee922fe2ef3e4c99e80fa54785d4d32990bee9051f460fe02dda20af7b70bfca7a1e3c1b5c42d2e509961a102745eacb08e8b3019e79dcc019444bd2042d4cef10f1bbc665ee2164051a4adf0d4a278b97dc50d69d387b4fe0a015a2d8d3b95492bbf54b10400af950c9cc5b7910ebaad51e09a0129f5183660db0f579242e6ab4d0e70e98d0590b427ba1969f05e949c2d28061351bf832e63c134bd2945dadf3e36823faa5f19bcce6b8ddb8af81b643b892594f0a4c35ed9b77383083ee8e06ad155ff61359a939f6dc39ad6af842b56b4304c562089a1e5f2b32d21a8a6cbe96cab661da67ce0baed4719fec895af4179814f0741b893bfdc21d275a4ed8a4d0af98d641ff746396e0d669c92fa6ec5094db8a3b10ac697fe3ab8aac1d4318cfa36a0f56e91f6de0579aee033f77e9a757d7284368ce5e8b374a08540c8bfa08d55ca6fa036d8c30ff3d6d8dda98c2b4e9742c68f1ef89c5935b0b930791aa39bc756cb2139b6114d856d9ac9cfa940abbd0abf6d959b56c169cd211c2b1cc72a89f43fb52b0e728ccb64d4b6b4f42e9d600dc0f8542ec300258f2275afd6c32860ea73f82f1d77504183906a9801372d70f56fc6700295b99a83e4cbfa524045a33896df7015237377d9748a0341e5a5faecbdd0d9f902f429913836eddcbeb276ebebbb1d2223beba63e69fe30298f387d87e1f04755200ac8cbc93529bef2bd80962a25ae865e4bafa033bf29b0924957812c228984c2738812d203f65af8ce20c281e940e9c9f0c6b99c4906ff397173ea1f815790e3a55088e78d3fd82f3f7638e30cde40384373c1e02477d9579bd6de1993560dae29e0b12e0624d3639217ed873c6926b3460688d428fad0aeb687db9fcc3b36af336f75806f920060b7c3c01ed9e76b43a67d31330f578187e684b9a7cb0773178070528f9e1be1f3c36a96f3812050cf491a1e414efda1f46dd1c4da13b7dc1614a627d27366d30dfc5e01a52f3212eb208398396a4818d774364bb814be91fd7e27f36f2ed61cbb6f81bae58dfe61a7b19a29978c79f9f1fa23c3da26a9124c81bd8a6e7ee09a5e1f4e6056c1ff6bb2a9131d0e2e5edf6034a59d4dc23beb14d673b55ce77618ad1e91b88a8ce0955291f773ee8be47fca68f44c64612a62db627296d50f74445b47222151142e0235701d166872d863298bad5d9a9bba068a030bedc470fb834cedff4dcca543f36e84515722dd1cdaec754a591e2b2ffe70c334d0c4e12e10f0fe9fbae674b9e743ed0f59d674a45b17c44de1149d4a0078062924580ef266394d70d4f5d436248bd5c5c9156342b9fdf0496988349aea451d356ecc639f8f2322aa0c354933e1aace38c4602b6419d424e27e873cd401f4d74bce890a33e6b831260c899a1be34f709f43f68d58796b80e3fc8d3970d8a29ea3d70353f550561faa2a76315adf09ee7f9414669e1ac9f87261dfdaa4b5ceaef76f9d34f9264711033aaec27ac1e5998e95ba38da9be1f83736f0b9057d0f6477ffff38ab0b9daee2b907688bf35681ab33372cd4431464f335ffd6039d1582957816b91348c0a66623b9422795d797eb7a087edce1b35e0debaa8ab2d53665c8e43880bf0fdeb1a0b38273e5bdfb6c16d52ebcf28db601d146b4bbee54857bec63d10fc2bcb486e7694eeacca8d91307cfbec3935d2d762316c5616d02c1f91553520266aa56949ce2487dd2617ac020d83e9b47f5d677cd0a455a24caaa1244126eee3d6c6ab6d94608dc5d0675658c3861348aac0f46deed4d0e19d1981ecea73f28e2854c62f5f7f5078869f3e18f7e77b2be0843935d50be495e9b5635978c77aade571ee4aac066895332300435e00e79418362cd2cb03f4164a8c1a348b80deec28c1553435e97aeea1a4cd3c0662108b32aeeec32ff109f58914e20c1b742c715e1b50b8b47aee944b64b11a691454887dd9a2316e7f7cdf38d195a2e91aaf97a46fbc29efb5dcbc63c89ffb5143ab8d4b243470a158b07850bf1084295148b422e024817830aa615c8874c208a8537a24385054725d462bfddedb83ccb227cf4b34287970257f545f3d34148e8e6c26fff538458b91ecbfd59229f178a2b395d68da5cf4a30ce4452698f0135306e7d7fcc0348ccaad10b25df686bdc8d131c46309012e115894744663756279538b17891640d460680f95cb89a5ad0434e13905bcf9da7a6fafe672301afef0c3b72d67aedb8ed8f147e68a164c60c4b65906765e564714f0b0d534ee1f1f91da6dfbe05f3109670b76be344f044cc2690898f25de1183e8340e5bd5c2a27a4b585e32b428d90a675a67cf610fe5761228b8e6c029961b36b64a840960ea1c3e9529cb1d6ade5cae23f6bbd671546d28304979c51f7aaac25528ddac359a11f8cd632758f401bfc44fcc19e76ba8832bb11ac80458cd8a6433b88821cbc80374b057dbcf4607d0072504c14434cf61de7feb2515dd597999f9270227dd9d7c9c242e9d5d8436a46d2195accd86d90c28ec236f44864c1363b734f6570ad865fd5edf34f4ffd3e6493b50b84509bff453382097ccf9ada958380befe2966463f86ce83dec5886e8fed484b62352fe2754bb457f411da78891766bcd7832f9eaeac14e4dd693b8c92b34ad0d821e81573b7bbff2205901092429cb9e2d8c841b730abe05b9d32a3f4081928fdab4395960d8a26e70b81d73030ef2a1399f708cc4663780716cc78ab8e56414b0f1139611735caaf157a9f7829f4595c4bcf35fcc61d67507d08f0aca0028e4f508b4b052737bdbf46a0f70a2d9e43d2b24b07dcc6f3052a2470da80d2c50d72204dca81f9246d4034838aeaa262608096de97dfdf00d491f0e8be274f02ca624a3fa3f5fb46af1ea3aa57e5f70ac1d478a4ab7e0f84460013ea1ba3d42517f185f1c7c854681c4218ca810ce011c30d5d205054c58812d1ac946d38671a00b3ff3ed8ad2be3f4f981f8c59712f14b8dcdef20d26d8082b7f139935e9cde131c350ef97b1f3c29f459ac456f6b543bb94b1407cb50d0ae19f0ee428f79935c73999730e15164627a23e8b7fbbc123ecc78bd505090e9a20c2f485f0cb8e074e16edebb753b9c41b74366539b9617f1a0753581eeb44402e93c5cb01ee8215da3f4eabcafc2c639ba18e55f192b29a24f8011a54716beb885ab10a79caa3bb75a690bedad7b9f832fdd5f112d579296fef347fb487e506d2d835fe05988130b3c7ab8058f735360287bee1775848e5400b473d8dee5e5e49e088065727d72673f788ad2d63905209c9c90d5d7970b96494a2733abe136454a48722ed19f392a6caefbe082c109a568ec110cf146020410e6ae3584444cb4d59754ae8b4d22d52c3bf7f2ec907dcda65e4ada081231df4562a7032f2c4d964d10b8a3287c615e89151649e08b97008e464a0867e15286277cb9492b71abf136ff0497ce8808a8c8cbf1e52f8a856dab61e56c1755937951ec7c70dea12eeb5ae848384457212c317d46c942f377f0463b30043b41f0a0f67bb12f4c0807f0c304ea2005dffad0057602fa7c633656d18bf681bda8ae2f7ae73b336c2d034719f0692398353aff7d16ca0671c61d7f5adbc448a1cca51f4de6d571c4751706094f1be1602be5664f6eaa6372071c8ccea8de6a2f06ab83c2273be27727082661878944d76228ea601c1531a01807d7c2f9298f0fa4eb8a4a2f0fa78b91ca7e0a9210dcce16249532a4630746383c072e303df59aa34a019e25af6f2dac4809a77d6f90a29ccfb9f94ca4e3d39473035e61594a49bc296d3ae5b1a804a7323a972a1552b56aa68f12684519f02be794d06c5e9849dd3f5150beac987d80d2572ba1103230c1030ce349618d8519ca772d9921d12a89f2c83103af0fc8b5d189dd90841df9c911ab72d28319cad9b544edabe35886309e107ccc09e96e3284e0c87948b598caa90b022fef9b03726c59b7f23e02bd34ebcc9a185d623f599527957a4846003dda1bbdaba360687323df9d5e9f0a10c911d45c4fb8bdf0e8557fdfb45323174f49bb33036a7046e8deb57e602cf8b890657da8ae5c1cf97c763bfcebb5e62307de5ec47f0a7c307c61702dff064907854ca69a55493da7273bb08222b17eaaee7fda7c0a18644d84505de606da2be649464765d77d111159e96a8c44d66b4d59bf162a1aaecaa8c464fea76cbb117b55a71c378cbdb38edd1e8ca58e00d3c8c97bdd8f12dbf147c13c01a4c9000e26788631d62d3b736036882f57a397a5ee2ebb0a9946b6aaaed0f56182d795941216a947afe632b3848765c00cb0cab8aa3f7797978d3bb54b088a4058bbfbb660377da40625952210c0e8083d1623402060ebdf8dc697ef93118f15190f36c911d9088a78ddb18ef7b6a353d16bfb28952f3df6a520abaf632a00a5115ac909586741495e172c1862cb9af65bd2472be1ad2c5a96093ad05be1d113c4ee6ab50e50d766d3a1021a790b9d20a1b40210d2c9875b8ba95b5b8e1ec3e2bc85d7c5e11ed456d4303b49408a6ed7d5844ddfc2185ed7bba8a265c63e47992ca6fb0e597721f44e1eecc1100b11e6f0b96ea0e4d7a8c35d79e865a32de001606555fe5c25aab513fe434779afb16190168038c20cc496e114c7987343d8adc9976bfb2e689e1e3da4af10f6b6c7f726a9b9abc9339e988169831dbdb1a52af73cf6cc7a83b2f18f6306bcafacb21fa1934c92eeb94f26e9b06b128ceee241f294056a7160f6273c071ad600cf1ad829f164590cd507011264bb0741676e4008d28fece5e0a8f59448e4b35a8b735c1ea2880333f07033d8815bf022e2285b0ca525ce3acac512b4dd1353e1cd97140886b1d48d03a6ca31c2d0b83bf98008c8ddbbd66a6bb192ec0689ed92c93b35f246f69e8e946e6af5e81ce52af6a9c2590a2790e46f6ccf38456a017aca453e93560f09b9981c2e422e2c834864f3545b026987fa5a01d729ba98fe84c0316946fcc4371653dd99f2e560ae0b4bc60162412b0bf3975987ba294b59e2877ece0b71b6c448dc2d99e1f856e1cb4b84699ec1311cea4d29a2e3824bb703480da5c08efee30408bfd6b9272481a39caed7c82402eb3988a6893a3f5f8576a84946a8e2f3600f31f7f2c9fc27aa4a70b6bba8f6609764bb2ae05e43411b34f4ae1e665084258e4c0904698c2d6b9da455f2b3a68c876c6ac722e7cfb22d658f26fe74a9b438d48f51f4529e02b8178f6457c832f4e8ecd3a7c762037552a5ee8b7fca1dee72be675431a99a289668201f6dcd4b37bbce033a3c59e5e115ca00f7702a86df9b5b27915122a7357b4a16bae0ccc855103271dc4dcce6112965d42de6ada72f51909a08351900146c317ee13b27d8bcadc42a860b1b0472ddb272afcdb71e89485044019a3ec47b3ca960463d651eac263959f01380f8f919e2437872c0759b8e5c09264e0dac8e027e662c2abf75c1b1940c21e84e87a754d703713872cf1699547109aec7dcfc3238ff05873f96c1554eaefd0bbe377a29e80de5b85d83700e540b3b9d3ce0b024e41104ba6537aa5820da19a703cdaa62056cecf1c67c309c701df078e6b31026ed56e5e75da84c77bcc89632450232d54fd155fb03b19508b05002a310906a7321517d409d21fef5df3695bbdf86bd0ea43c5562c30411d9ddb6dc52a694640a3f0a930a7a0a49baab77559830c7a7c6777777ff23dbc3af9478632d47f7ec6c867d0c2141fd7d521f305e89359e34a89f2251047586342258a1c41caa2e939821478d31ce58718253da345236ad60819af6464ec125205c6567da9a6823679ae60f3346ee1760de63188691e6d2442a1f46397f985e029991b46dc70b368d944dea038aa0a0f5b943c690109eb08365825dc7d102a232658b9cf1de8a5c2959ca28658c314a12c827121dc3c14475d62d7fb617836c624448d8633f4c4c462c462931a90452d65fdab4171489667452d77b3e856ac618e35c4f6e552aa191f387b9bdb0756d240ff5fbcee380f5e2a3e20ba5336872386b2576d1054432c618a39452f20aba075ac728a594524a19638c2d85849146d05926d823c5467bea07817888c5253e020285fd3c94f1100f4d3efab9d19e192c7105f6386b0510c208218430ce28230ce6466512ccd2a13a91214bb22c215a32549d159fb92f0956fd21843470f5603761a8773295793217c166009b4c5af4d87fb0496d9e73a7a8a87987818ea8e4ba39bc3337ea10c3a28c58ef6059e0cb5f722ea58cceeeebec316e841c9296d25f3e74a34590c51e93f882b9517e652a7882c5abbe22131cfabb7b978461779e654a39290a4b02859a1b151a827232544a29e5bb9498942e4991247f3d967a786c1913844390ec52c2b9514a29254c179bf5c984978c31c618a5941247062ed7faccd15bc818638c314a29a5143782a1b880a3ec22482388e2db8821cd1831677c4c76362f6463e3332c903354df81a33acee6f3bff9f25ff3d001eae8201e1c1d280cf62f5926dd3413a9bd1c1bd4cdac0659616b6bfa4b2468ed30b922b2ca8e48890414230a7a7102f44550955c34fc7e6805917b9c3366934d36516cdc666e34c610b988d18f986a8c928a18e3a909378521a5134fc5fffa6408598b17f8dc286b21e4594c76648c31c618a39452da3cf119a44c22e7d87d85aacb44af46e832665294bde8eeee32b6df444d34708da62db0eedb24accf199dd0969312ca871042093b1a21a53db06c73229b2fe3cbc766b7af611b0efed14b3db0c6a45319d316a94829638cac448c3e027667c87d53e3016a1c4069b7fdba1a3f2e25bfe66103d4d11f9da06c803ca00ed4d16f32c1bc984c5b47eae6954a7ac9f97af17968d55c9ad86f823a7352ba03777a073939f84a7ad13a6e6be277a4eebb40f587ebc507c2258645efe0cf0b9c4570f9a432533024647a073b14935366922435b94919a3141a236f949a4cff9e874205712224b4519b1d2fc28c9874f7f7624449ac0b82094921a1fe190fe551b0852b7f4eefedbf444a229f40a1a6a99238b842f59c2b01d86555ea0cb03451013568d30038f842264d28312c4a8ce314f772b06a7bf79f476c9acc49229988b4eccbcb71c4c663cf0676d99e4b3f622a94d6afb66e07a6e92b70bf34de90e9930336afc9d2073dd18b5adc622946295b40a564e7cd64faf73c14cac66688cfd090f7cc209baf7dc47ebd38434926ca038d5ee4a6324bffa2c52998905e5ed3344eaee2ca575a6f1ad72bcd378de39526378d83ab12b7c90702137fbec3ffe88e27d013101823f1e917bb13adf33f4a2af590118b353edd9afead293881788d2fe9de2ce504b411f85eb77e303e0ebb11f8f1bd3bfdf01adf6b746e7f7dcec738b6dca394524a19638ccd33371aa57494ff6cdfba787ea64419aa47f6cabc828357ef41e95af966d81dd5d97bd97254a7a4ffb68a55ffb83c8440df1bec4a75a70175f7652132a6fb4c4b4d2fa58deb53f6481829e388b0d715eb866c4d7f944d723dc0b9d12b252a425d5ca930702ab141d5dfcbf1cdb81f99a90c650fd8f57a977ac8ff7e6d548fc9b41923b2281bb03303180fadda3ac84af5286dc1da6ca4b4b1e12a090358e9c7d7ecb509975fb46eb78644ca7ac46e8b564bedef8c3126b8628c53ba122637794e789e6f3fa1ad9452c640e73b16b7927c79c1482e47e05b943039355226a794513a9531658c5101793029860e5ec293d2cedddd1fb58355a5f7df4e229fd88169fabf4d9decda1f720e2184117b77c5103b222cbab92f0ec9b51e3b4f2261ba74e9327d90b24a9cb3e3dc4a1fa594b2b4a132cc83d08a3d4a4391509913892e6397b14fe10546fb48caa67ccd378d944d140ff451933b0c7e8f1d9d7f2b976cc881b521e421a2d8cc629c9352938905514a8f95480aa29991668c2065267f9b1f9bf5e933444248299f638c12462965472b40992d605d8c31ff79f43f948cff6c62fcb7ae17d306a580ac173f3edc940ff67a8b2af693ba806e32b8189cc906c8a634b05e1361afb499b48e2483b4aa08114efda0814d01b15e0c5797263e0ce771585420fa8bb4cae6074eed7ad35597083930a8feb04a8e0e1a86e3686afc35000ed51f66dd733562a0fac327f273a35b946d8112030e688cfdc055a4ca773f62aaf29deb266c131554ca29698fd89d9c78ebd35d069a0d8aa46da5196440d9d94da67fcf43a16c6c823c212434434ccbca1333ec68d0abf092242d470fa594d216accf1c359e307a410e9fc2f424e39c93e161d773251e3960a2417c3860abfa0f3940395472a654ef207cc97d471cd6df1a7fe89877cba457c067009aeaa68f729bad1527439aa6df145fba52f7cd2d8618ea4765cdba1f4a23a0f0872cad7187dc7b805576356e7016e1ff91e3d7bec6183fcacb3c59857decbe24ae0435354dbf0c0c5ad008bd015dba74f1ea7567fa68638c1c638cec0426d9a3a0497fe8b0d46362f2bd63a23552168954f9f1715a8b5becbcd483df25d63986b1173b9451c739bfb93941e5c7ee9b1f8397eff0096d71288c8a1f464e760b7fc71328c40176499a9b35967c6c855d2c01d92e409274a90628857579e7d1dda33bc767c618638cf993891bb1ece1aaa8fb84a911a67e94865865e76d4d3f8ce7ad4f19042c71450a32ae1d48265a3254d9c71fa7997bae431f18507f9f506afc2fa6ca0e026d4d3ff30028723dc0fa41a0f5097da40ecf0ff461a21fccd803a13fbbbb7bc78fc31c343b0a9b7e26ff221d7c715075af82ba0fc117047a85754dca01dd57fd7888833a0542106272508fcf60ae63a5ffe8f69f09e6bf5fd5cb7fa41ae767a82428c744fb207860b158ac157d0d869bf1f2428d01a840898ba51a6718a9fe839638b934f1b7971a3fe37cc02a89c657fd7f60553ef683d6ecbd044456d921d92e95d4c5ad8932ebbe10d408975f66e75b13bf582310d57f13105d8947d4e48882d7dce28c524a29638c11670a97bbe646d751805109ab9450a894914b3da27b1258e543f9fcb2f301d6d83918fbc26646f2a098935293e91f6709972b4ae95e7d0521a270c8f88c1118b61ee61553e2476670007d0105e7c0cc10ca8b012966537a703e918f5ef56e08f67ceef28744312487d60acc103cd0c2d74a4f5d00e4386c22e4cffcfb1153f57fef09f5ee6f6f9aa691cf2528930aa69ff14c0330c2144698a65a8475cc3e3e6dd5f6f2f1513b30ac09c576ac176d24875a6f879217ee4b9ea3368e6a26129771cb039511930f8fd8d4f8b00424c6132c5430eb9622076cea129923d9a3f8c8aa7964734286bd76f7ef086f9539ce87a51f70044ba4f8630f5f3efcc861ddbe7663c713a8ffd6f8b3d423da90533d7ae7f3c86684298c30c556034e38c5ad1ddae75da2d8d08bbdf9e582cdcb00d42a197e6d3a195ec0829efa6d3e6775eaee44011e2fc30b51c0db744aa4f42be0bb13c2e36578193a253c3e679504b5f99bf72c45bdcf407b23f7a6eb3e5759157c35cdfec48212e1e324d4fdadb1053627a526d3bfe7a1b00d9680406c8bc79d84c8f0de7b9d12254bf68a26785652fe952ce11f7811b492c2bd005e86cf59cd1550f8de2f8edf6f56b73875fafdd661d5007ebf9b70eac6ef374fab08f0fbddc3291bbfdf4f5895e3f73b0aa74cbfdf3fadaaf9fd06e2548ddf6f2aac2ac0efb7154ed1f8fd0e6a958edf6f214ecdf8fdc6c22ad4afccaf017ebf8b3825e3f77b0bab0ef0fb6dd447ad42c0ef3bcb99b06ac7efbb4e02dc09ab52bfef4fdca755aadf6c67347d402406ea986e0600ddcc4c07b560b07f7a00852e48423dd0228469c70748e899010097030b88cb8145657b80edd4fde778e213f6f69fe366466362c8909941a386c9c60deebbefbaeff41cf75cf7e178fe9cbaa51edfc11e1edc76c3650ae06c38f8ea8fa1fb260cdd0bdd67dac7c191ae905ceced9f38d21047d2c2debe0d8ef4626fdfc491b8705a8bbd7d1a9cd684bdfd199cd623c36932380d88d3acb0b71fc36942eced534ecba215692a4e3b6a9afd14a76d619afd04701a51d3ecefe0342c4cb38f004e0b3a00a751619a7d03701a8ad39e30cdbe0e4ee3699afd02709a0ed3ecd7701aab69f673702423a6d92700472a6a9afd0170a42c4cb34fc391849a66dfe3485698663ff35998ee9b1fddbaefb5eef32aaaf29fb2f98c85531ff6535786bd53d6d1c035a3b2cf2e4edd1862222818d57d2ee22dac62b21169e9a98b62b1154e6d152864a9fb1cd4aa5eed6793b11f4e7d994fdddfcf7c3875823e300a36855318104685539c82ba8fb9302b9c6214d49db20f547f92a01f746547381d006e5718f7f1ab6eadba1f3920ae52f705c02951b2243be2b59272f25f82802a442b2927effc55dd88bde5a95f7624031700ee60506644bf7e99bfeac2eea34b85bdec0802b1b70fbdd89badfb31f0d00fbab69fba0058522327009ce3096d673e7ed57e1e9df992874b5402e52752e12f078027d49344f835c2a036bca5f6f3164ec9f77e6d967a402b4a38cdbac9200832cc1da5a139c51fa462a5967acc1fefce9c29d3027d1b7461a67bf6fa73b0e7ede09784c22a29f377df35274171dbbd79a1eeef600fc21d2c58425e0ef6a012edb727318944ca489dc7218128f6e092c642b4da5ee3966c53ecacb4b721087bf07db0870327f8c649e9d73829d873a9c7ecb6090a3f86236c0802b3391db0454ff5ca838f205bece860c362b9a1ab0366acf37bb6f468d85ee7b373fbb0a9a424519bdc5753e7673fb98fa6cecebe01d4993177c4a662d84f200da8185714a7b01d2cc51ffe7c2deab7afec6b08d1ec49af91b89f29ba52dbf38250448aa854f83bb08ab3879f638d2a3c41fd76d41802d51a0889c33ee3fa39853d01aad82a5330aa6c434424a808a7becdc203a7aa4c014b859f837dec00dbab70cb10e8967ef0e4fab774034fee6bc66d1529bc2a97cd39272966393e9b1a2712d8e5c70ac108203a706a76275a6588a644a938326e071e046da907a8cb8328b450616976a61a50d30ae8e755f8455ab52b081fe38a703bc0af82ae1076762842048876972e15b2480c5305160c62270a3b2b25374c3464b418982f75da155eaed546822e2082cf8af44b78044106aed5e97356383e6705c3e7acfe7356dde7ac6cd4982123062d2979f9527712927de94b9d92d2679fb37ae17356317cce8afb9c55ce6abfe376098e33695028fc18388ffb2f5ee07070a82ef4e3d7eb05d71084ad96d1d18b3d7eb1e746157b21817e04b437b0f2bb0df6463e7f16a2ca4fd8e3fe99e63ed4dc7a6ea6769f2938849c88b23daed791f6f34511f5eb27cd8a3db429ec71048a3fcf13a56391cb81e2eb753464145f928b5e6c0dbf47f7865cb61dac2b5c5b7e98f04e8b75459525ead74fbae30fa7bee8457dd5299c621d13d425aef038d9b6137792008e3f3d8e0e081c7ffa3867fc79acd4235e9103290e903838de86e823e827c6ae0738030714d61ebc7eb185838b91cbbc686f606cb57e34aefc71a855710a512ce510c491177bd35de3ab5571e85539c630047d810138e24fabbce8856e9b669be6f923117b1363b0354540559401a4e1ffbf71e3e78badeee2cfd630571b54e8e745ce434d4ae06abbcf5463cb8615f4e3d76b6f56d59449bffad5a4b2084e1d10a71702ae4ea7ee147f57a7e7f71e5a63c842e3891b628397ba5700fdd41d88e080dee06c70afa5062763050adff4847ef107a855fcc5d2f03387e1aa3c82ca1f9b88ca40ec12e257a603fa404c7810d47120f843839bc1411e2450f832fc32f8618802ece1600c0e965894870d0aabc2180eba60100f7de1e050d3f0938ce0a645e8064e7ca2f84cf9f9b9a1c42d6cd2a567e54da0f09d09744b3574750224799df0b2220bc756dc012ae271c25ed429a27eb149e579e23d3d0ed4aaf8b38329b6ecac3c0bede2a7f26b6fe4de7021d2c21e3fd1162f2aa2c21ebbab7320f6f86100837eb1058de20bbef6a62bbfd6d21b4211da424bebb057a942d4abf8d2db8be051855cd8732bb1ee1536d0c2a499e5452d9d56b39af0ce4ee52dd5f0428d3f4ba05ffca9b0f4a3eb27822abfc4ed4aeb0d08fc5ec8ced5bb6fc9ae366ea32085240cad346e57923302dfdf091d25a854e9c9520f50d7950517d47e6d0d7f3cc5893dbf38152b3f1b716a5d5c742a3f1f754f4761d5328188b9706aab58b1c3af2fbaa2d87eb814a17e3d31e9409cfa62cbc5a9af5f419cfa9c4788535ffca95438c52d22eae7565af5f32b7588fae1a89951fca92cb457e800063552910cd4048d2d4e9dd8c55666165cb17b5d81414cd08f836ef07eed4dec4e34c81a3f762cb435fc469c622c5916faf5e3d756f78a185851bf6671166e827e3cc429ef4e4060779b0d481c13715116e8a6020ae58d1c8c5346da6e24712721a49c95c69d84684a66d3f86b9fb3da2d66d98bdd89867571a1739240af4e12e0df7eeb44407afe5dc1f7d7be243c597e7c589add0f9b1a5535beaac6c7691cc66123d9c7245cb3eef4237ee7035723f2d7c5854e95aa2ab97515fd548ddb1589db55e4785055f83be39299075a16148abf8683e3005665f2d7abf3f73f9b39290d92714998a6794801dd69c2284545285e90b781df6462ef701887530b21dc66d80961af83b0d75c15d42bbf0338f590fd0b66be2144bd3237f110324326eaee76ef6e6feff676ffa1113a8311c3d6ece7d4ad5b82e1051ca71b364c3568cc9091112386c2bc94368d944d4c466f2ef5e330dd6e7709cc61662d1af42c28bfc6dceefe12bb6ef729e95e62a0eda6f87d57d5fcb0dbdd87bb8421057cd7fbb77b994de0b367edc7aa91e6947feeee1b77abdd95800855a0dfd736cd78393835e4dffe93bdc781df886fecf57774c83db3ee7cf8717a924ed215be0b216ef799e0cf55650f29cc370db71d5f76303eec9c3d538c5d0f5e8f982a7c29c828a57c9798c4a4d7d825e10adfa9e0eef0c6468feefe53da9003ab57ffe07fcc70c297330ba1186394d284ea41a1e6464d419a97c327cfdea29412c3b028636904d24b3df8796e14a3a2273e0c2207b1d6374a29a59432c618db05ebf38aefdec88f9a8a42a171dc7a4bda6c6757d9fdd6c4e84fe4dd87d8b418639c73d2dea22d6fee5bd45bd1dca84de5b701428c5146982e3c89b076be3531e70a4e93f4113e3d57e201f17be80453ba54434ef59fd8b70f5cb1d7e6d6a51fde0cfb65ce0e4957ac93bda51b62e745c02eda421e0da1e47c602863e46f1fb8eb41c687ab23fe46eeea48baca6e3958614bc84c76aa9c1897b1883c077bf23df6e4a3d893b5853a28e3fa0af659d7575a8853d8cbff30ef6d4e5658eaf14215146ba12afda769a4730b63b0873fadea16c6e5c022b928afe47bd1ded474517d8b2a3f3641950febe90822dfb4e662d5b00de36690251ab0da8f7158d5b00dfbaef2fb8a8c51e5f79133d991df58a4785265073db3a4b0523fcf1b6b71ea93d9e1d487c3d4c33a9ce256932ad949953cf5c381956ee00f6c6a7bf91ed814cccb1712c406f940ac0afe348d7cf9436a7c3c173c13a623a809aafc60104172bda85236e99d22ec658dfa75508d26823c7a0ad4217f4aee2754f9f0a755dc6a9ad27f35de53f9301bc72d2c3d05f2682c56877ce923a8e93ecfa8fe162d1f05c2d6c82aaaecda4efab1871c0631d8b0bbe6614f76cb3aecc91df65ea874d0d6cc981c82f069177bf25fba06624f9686a0f2fb49fbc497dfadeca589ca2b4c2325ed1a4ba95bf6b6eeeb2c59117bab7133b0275fcb36c8e1d0c05867f30215f49ba9f2bf47710a56f95e0e4ec927717d853d99752dc49efcd975107bf284f51556f50f8bc5626225bf8338b5a9ead3c57a5bbf1a5a6896a5d95a7db02ccdf6c04ed54bd9631c576d7138e36417f49bdf030a7d28ad5fd1ee84fdae5887694ed8c38a75dc624f7e2605fd2ab520bf0eaaf26515f49b55be7c29492cc384b633d88a9df268ad2eedbaf3273d73c23d8a5b76ca9a7f383585819808bef0c354b054c873a542d65261f6ed9287531fb37a38f5b98ff4e1d4d747d2c9d17ef2898c52e1cf1406ba822ea74eeb59b765ddc47100a74a0fd9461e65599665fd5fd72c6866d9c3ecb3eca83a15fea1428ae591b1a00e9f2fc78c8f8d3ce29e8c057970142d9bd977f771fdf88759d079380ae4e14fa08eae87ab951fcc873d1e7e88e91cc9a3c95d0f70739e5651da499ea6c93a2ddb6612f4c37c6a14f6a0ff34cd13c8c3a5581df0a14f2ab606fec7f5f327153e73e73eb16e95574ffde4d12ce2d409e661253dfc8cfbdc0763b52a16613e58cf9be6cb2dc097612c0fd904eae0c2a923188eca14b54af2b46c0279482b5007fc37519e58d4a4d2d9c9a31eb3339966117b5b785a25839a069aa8d4acfbb028f06510d67d33ebac3319f452e567cfcccc2c5bf667533b6bc9035f5a813ca411d4c163a5c2ee301ff68eb6868b34823c6418ab630b5b035f4aa30a7f4615d4ffcb58af0a3356c6246bcd17a78c38d5c3fc24b36a0f7f1e712afb197984b57290fe93473d24a195df3bcf9342f2cad6609143328b0cc2ea80cf9c1cc2d640199471415f062d2adb81611b58689a0679eb66e6c85c12f443d5c9d0e173fd6085023b254b564b20f30d7c23d710429844728c2ee690c400a94020f67aa83affb7aa16ba8999b3ebc8f5bc5a2d14b95b684b0f35d1164e9dd61b4b6751a27ead056ed0d52ad872d5102bb4b235fe730594e10b06cd49a9c9e4cd23e88732d5ee866c8d7f0bb52a87a5f1f77642757f8d3179c56f5467c2aa77412c9cda2a5e04d50f6af988a840e425561550503fc8059311eef070cabf5d9c3aed7812f5834eaa0f55c7e16f62820e6995d734fede3494aae7a2f07fa65f9b09b49dd1b64077c3381a8333f22396ce561172e2a8a8bd198891a8f061aaf93b46977ac4d0b46d7ef940302b2c6931629adbd8830e85edb319323eb26464c9c822bda67dd6efdda576271f5bfd6bd8eadd8e2ffce7e7541c7e79e75e301b0f6774321d5c1a9c263dd6652f349094d841939d1da8e0ca125cb0cdd9bd5b317607444f44396a96cb0a52b297eb78f38f886d1a473f868342e349dd897f57349e76277e58e56fede7a0a02f5d13753dd459d8831f040dae7598a69535a15b321b77f2df1a3f5691385ec8c274c594202afbe7f0bc2a8a2a77a82aa8869580f0b0002654bad30f9727e8a9fe393db43139b05eec6dd53458f267ce077892c00b2780a2490f6b45e3a1d4f8053071558e46b784c6d378cd937005b20026aedabf0026aeda1d9425343a29fd52fc736870529a8b559bdb0cecd9b007677085aaf5e00ea70afd96b469dc565802224fd082dacf251c505cb06a7748d0fdaf5b9bc5e4c072c11765cfa120027af9b0a1499090201042f86a5513f58b6a41e1179b65b0772835a1f8053db65a2d085403048240104b8b080241a01a5d340d7914424643746832b443dfd0465be58ba37ac4a953bf026a8cc161f8f810b9b6e8d76b6f4e2ff4809a2a4c85df437bc3117161556fb12a08e44d2a7426b5bfa85f85232a08b151e6ddea8ceec0f8f30e4c0627c43a974fec7cfae19bbe7e5261d7722d68276169e067f5eb2157510f6d0d7c1c9e4103fa75ab5bada2f1f0db8855d5781853bf6ef5f7cede34511b310d7c58a36b2d760c7ddd1afaba15d3aeee83810f879e40bf6e56d011a8c0840aeb0c20aac1284ee2c62eb81971a9d1680b976ef08d4b409c61bf7c4aaad635769f076af3cbd51f0cfc276cc43615a029157e4701721e226a17bfac20d42e3ea27edde48b55f1503fec9d21232afc9e25885c0bfaf5d0107c085953a0c154bbe3d7d6c077223aeb56b9024f6d22f6e07f5ce3b724015fd590a93dd4aa1a73526a32fd7b5eb76874ddea1935a05a7f01f4858f0637025441ab58a155bd76516bab8071d45b6a0c81c2d20ddc8d6d5d02d23380e82cf558538cbf476e87726009a5f6b3528fd6e1428d5c8c0a4b3ff6bfb81bf483a31ab95861e986fdd8ed7a5e7b873dd82df6206b68ab7c81a5c25ac261bf3b243570edffe1b597d4f68d39fa16fd50d1e18fde2ff8e2d409b6a08e0a9af00e4c41d8f3b335f0fbd43dc4a958e1779626f2963761157ce26a2d9cda2a5db02afc36fa9ce53a15cae8dddae1d4077f2a7c58e448ebc06e52e1cf2c40e8f0676fbabfbb1fb6063e57f8700aa79430810f59ec4116e4610ffe0b3ef48bac0a3fb25a059df4ace0c756dc8952a114ab2f36893d3398013f803e82ec8dac39a0cd5718c0a0ce0c83f6861f3ebcc2a97df804d81af87c621f9cea0adf06f8413875a3c2ff01326115f41112c2a9adc245940ab554b85c2ae48fde28f8397038f511000671ea94e2d60c15ae950ab9637803e7e0d4c9042b8ebd81b50a196d3f75dfb4022a43ab0200b323e8fcd951c685c422f990a6b0caa687c464a82ea949dd8fd4438a5217be738a531ff422b238f57193d3dcdcc888fa3997ba91c984dd476ad5a5375841492d4ef1d4ec8853cc5c482c66c9bc8cd88347ecedcbb05d3c3172ad92a0ff302441bdb731711fac375ef317cddffcab5537bf34de0de7b9ab69b8de781cb6e118688f6cd8f8ccc6bb8d8fcf47a7c7f1f088536e63834279debfc9c4dd112cd530bfbbcf6117b926f4c3a2d47dd3e9e38fbfbef9d1cff4fde7d9645bd85ba34affc37e6a76d4d5a031a3fb4c2fd37defc9e83e0f15a3cb7c62bacf86494033a0de65af0c003a14fe9715d57d2c0aa7e00d6e2b89fb3ca8eed313f7ad95e73e3efad68a0d1a6607b940f11e87e1ab55cc3c5e0c4ad02f3b621ee8a2d014bbece8e326fbabf116006e573e30c110786ab4a005364db30f03125ef72686ffe6c2f01fdd176c1efbf5d77a93813b09f1f6a80a32385a799fb3dad21d11b023051d1e2c75ffe38fb7442f728483ea26e9ee7878310fc31d51b8c2cc5354c4a9d3101d38d126caf8691f3633146193cdc6c0c23b2f226e93a90f6fcae8db05fd3628898fe5d2926a320618b36930193d749bbbbb79316e3eca6b150f41a8cfce07c6f14a060a283f377bd9cb975363f8e285080aff232a0ac2362818803ad355e66e69fc913932fb47766f006b414a2e5b08b9bb7f6fe1eededdc61d68ee1ee72faf296851281b5e158a72499886872a502f6d51108c319cc561140ac53242deeef80298232d998f6188a828089c1886cd396d5c41a8aeeca93999c79cdd3d7fd99bf3677f4fd39c1deca67ceadd67a23d9f605be4a62ab05ed32c033090753f96a6bf3faebe593706d45ffeb7434578f801b2b6ca16a6d4fe21adca59f5ac3a4ca8d72fc9f3421e2fac4a92ac853c26abee7329763fe277334da8425b06d21a5fcec7e128a1b47e356798a6df25778a0feb16e1d82113185a0f4966c57ee1ea805ca3f7472cc6f81873d862bb3bb1b918ff7cf66214babfdf8500eababa7083ba6dc951d7d545a7d22c51c618e30fa2b020fe0c630140a2928ac05cdc0750d7d58527d497baae30ac34c32e30c182164840794161042618c8034b851e72aad0b245123b34d882cb166ae081ed2183c15a931ee7cb462aedd30d81173e3a7861d1d30323aaf0000d586083214461052bf0a4000c29fead28d2c41456149e8085a585a7987eae94d27fd0050c301da7262a432915b02c91456271052be850da052ba84c951c0c5552dd2a2e29ea47a1cc00084940c2105d24618515fcacf81f85c222830758698214a0d0a0084f5c8941fd4c0c797a6044142bb4c0e4f50fc42a28383822092944a1042ef8c7f46f031858e0678b1457086309415491c50b725084235eb005125842f8008b140844c10509b478a9c0083ac8224a9421a8c064052c7801152014094e4c38a009275842093818421255a860c21646208494524a29603efe1447909ad0993e9b18429e40081a26a8e28a294498011458780a200d8b2634a1e352d4efb5d0821cb55d5a5842d69a257091832368e1043d2862d5388c9deabac2e84295755d611ccd1bf8a854b0042030907022075380d2802d88a2f841124f68190285ca228a1ca86c3982082bb610644416cf62b148f099989ffedb000a24559ad0320250115c6042164f88f84901128ae0420411522c9607fc60092ac842062e2eac7041e5a75f8427b60a472062a2488a249a5471e2e708294d3401b40510b0f4e4e04089297494782541c78a19c4ced4b680051e37f104284d749c3cf1411195d5ee20082c28a83882111257acf8b7c4a88ae5ab2b8c292ada335b80bb40a89f8c8e23258e6a503d0c1254f8cd50fd7795850549e86942ca162656fe9453eca4faa338e5bf83532fd5dfc60141f6065688048450b52be99cca51631735da38827ef4a12b0b46a834aa3f34716ab759c56f9dad12418c1bc4bf83b14e8a11f8fdb25392b392bfa520b23bed6a36cd0ef933d511e4c386203f4026426c56cb16ed6bb978a71835838d0e14ff0eeeee6462e61d6c89ddc19c3333c78da61a5136ecb54692dc45d86bced1348d0477b0581a89599cfab6cb163169e7540ff293cc9ab5e64ac6afb79261b392f15f8d19646c1a89967e3f07ccc7bc36a4fecec29d1dffbc36fd98d2cb520fda49622d7d978080a04b972e433576473ccac1ca9da53217a4f4d2750f51c372f6c6bd1669950d4cd3df3ed8b381038fc4b3714170d89afe1b56c79459263bc8ca02876a7f7f6bdf0f593e3f7b8d29cbc77ce85a9adfac5a0972562188f19a73d833a77d89db3824b08b977a68a46f9246fa56890008192f045cc950c9e84e41627c8c4e095c8940c6c7f89c553faa39c80daba37f72386c8db63725ac8b9c0d5bd36d037b1d3b0f870e6850ef7c49b8fa3369776ee0514046272546b7a52031bad3aefabbd44352c8da9ae6536cd2ae2bfdd0497774f611c48686acbdd9da5880426d1c4c38d8eb2cec7cb0c7ff896098860b34fa3bb393a47d64f833c31e435485306633750c8704da4882d6a8ebc2821335d62d4152851c3fbc02856010e5e01574296dda7b85091a407168b66da651ce14d331313486b6c9b4850d7605dcc10a0ae2d407afa87c8581f415f0676e948353ba586db8a810540254c9ec4d12f686fefef73764fc500c380489d81a7e22b008085ba43eaaddb75da01c0cda1a6ef8a7de2c5b8b534df8a196161f5566ee85bc44508761e987d7207ecac54a847f074e1580e115508769b8053b4839ae366e403f1311e80787b4186159960cfbd47cc6985583f636ad8af1a55f2bf205e6b71352408506a87088a6428f63e8da80705543fbfcdbb4fba829497ce1bef764fc6743e6bf18d58cffb25a7ab82a1a5f2a3d8d199c0c27835b4e3ee44affc221698097b8e592b07fc376137bd0bd189d088088f142c0558c183f572d444a975363e4ac62fc6c1ab601fdca8d031aa3c7c6178ed5102b7bf7ecb9e7413813c01ac3e210167b081288e8e0f13b76dddd9d65bf599665998c09676bfcb353961539e2cf03a7369e04fc246152dd1d8baec7c14cd46fdb1b2ed62bdca0faebc0a902547fcd27b0375185f21d5be35e6de480fa0f69d59c1b58ff22fb45f50dc3d4aa97edfd5d1301102faf9562d7dc02125053240075863f1b185c5591a629e2382de793beaf3375b351b798ba65757bb8aa18bf6d1f83dba5217d0c4782e14893f4cd6d5fe2e6f7c675fc2dcde79ecf73766d92b942bfc8114fd235fea08453f3b90577f885dba669f662077f484c89b4dfd83372423a65339048ef836866a872a551f9718208e941e5d78155db05178bc51ac1ba8c822a3f2acb814525f56d91f30a2a2f1121b74d235292341287636b60eb57da2fabb49fbf714a3edc39c334d98e2f28c923751e7b9c7133f3833a7eb9124e4132d2d3b9fbd8cc3aec5b7345923135daccd5fc96cd2afba1f6cb55863d4e3787c4541b07ac7a00a63a56bb33e2b4e58300f34e02dda50bf74bec1b5bb9ecdc5aa0824c38bc1c54a0eb7a15d5cff41aaadf34e1f0729c82ccdf2a84592bed69abb2e79f1a6ccdd57c12c744089bd5fcd65c69118ad691709a94713cd4f8b9bbbb8c08a85b02b253a8db4139f92b59d70a04f34190a5dc9bfffdbb20d97b17815d651d4b8e34d0b65535bad082b5da1b1ac4a11f6a6dd29a33e2b4d4cfdce9477c7eee3ed819e13f75e7fd3935a7f6e9c7e7d4e6706023fdd388bf372cf1b78c43ee02ef6abbcb3c789779975b08389f5f6bcd5586ed66dd94dcf743ed561a49c2d565d4947b330fde8575ee4299b3dba6e95d02ed82aecb8ba2fa4d2f788884306b158d78d1f28275f28f8fbde44eded1b08a5dcb8651edf9afe263bf2dd32a621f39b92dba8a0f4b3460753b1ffacbea72adb98abf252002a8db4101417c1cf6eed285b74b975594400356b1dba659f6b6b9abdc605b9bbc49595e02b72ea6c60ed4fe41a31663cf6de376353921ae7570131081f0ea2708947efb21a56efb21fb3bb650247b94fd16d59c55ce8a3d761fd43826da538ec9f6dc0e3028923daa497ad70092869cdabb8ace958020a062afc94deb6f58fda7c64969d9dddd5e7ac93a1fb8627362327af747d78eb6ad9282fd6e15e209705f2190c562b1e0d27856fd03952727c5dddd7d484b0a129b6a2449d7f95ecd59fde84702bb544e7ec631c95e0829486c6a9236407ce64a35e464dcaebc6309888c2a716858fbb18c93e20363dd3de3cbec7c607f8c1d092bda72ca35081debe07a1108efef770e562d629c0f2cb1f7d681d6bdb1c7ee8ddda8f2b1caed33f6e9c7c23af906d8a57a27a10efeb81a81ff4988c9ae86af2cf706f26824904beddaa51fdeddd6f0c76f23b1ab61ab07b1da7a80eed009ac5446d25db854f88ca4bb7479e903c3ae078c75c0eef3973fbccf5f7e977050e2f18708620948a56fa8442c98ca9a5432442410000000026315000020140a068482f1804cd223dd0714000c7eac486a4a170985610e04318a216388210400001000011019a26d003f377ab5bb613e6773c7b7ad172515035068d34b4714ff6b36f4da4ef25b18a866ebec8c5ed5ae3710351334a1fa1a35d8d8b174c1cb07a3cddcf370caa0a4f18ca71e5e99be454e27a5bbd3b4d9de8b10fe01d9231f0e709c8260969bde5826edd42652b55b6554c5c67c4d7150b093502931c43656081818b8e4e561203835855b6ba3580ab49429c045171e75af299afe39e2b17855625631fe2efcfd492ec320efbd472ac454ac0d48a413ca6d17ac683863bc003292ece4136a8965134b23c12d9811a31c2595432145f489df68ed5a99f95d0190fd1c40642dfdc45792c4d0df4a89242691056950718080448f40d6cd63c0ea76833a10ac5466b185d102a1a4e7355839cb5ebea1d23bd392a94185e4cefe1e6720f9f29400cd831ec228dea517aaa5eaa7fd2751af49dde8252993126f0f9581b70a8d136fe121d0b971d95314e17ec59010fac9bb7099e2554d4da0ea396844a78753a088b156a13c35b0eccd07f5e52c5748f32479dc65943ed57b9e024b7540fa8ab3b360f07ad38f0b4be0d40889f2839aa56db96b347e05a1a45117722763bb0b7ee74d12c4ae40f590b045b8f6bde26caaf3b7f07379cd3891ed63cd382985e53184e3302c1af07ae6302ccb3d0162060a79104d50032e374709d3b2352aa940126a124d79d880190b85fad77cbe4de686e74b00e1da5deb53274074d1fa9f4eff58fe56dfe05ed1b5a4a9dc50998fa3b8bc46dca3da9ac6d4d5e4878a5ce0b424aedccf5ed6175071495bab00615c6cdcc45b2bc936a77e46aec17f6a6741608de59c18565aaddf8f9a98592c3e6b9420226b4510ed8b4a4a44a2c55822d87c10f7293f21a2a941620984b42b51d2a423d1325f18d98a3fb7ecfd3cf49b48e4b259d678e7efbc6f2b21d87ba3151f0b7b8d3b16a8fb5bd8a3de6f575b6f462d367ddb2d0d6d04dfa37731b791b020fce10a45e8bb872140ff05f1fe61eda5fdf7a7cab18fe24cfcadb5fd4971c8d79274cd9c019e3c3c79af8af682a2ea5bc6855f9267ffff6699908005ebd5250ce40f72aa81d73cf979c417a32fa676b7e582309174706aa7ba44be174219de7c7521a5fa8e07609ddd62350b69e245fcb8f7506f9c9f803b330f2be207b12576284b970715b935c7925b216a1fc0e73f6124472a400b158805e52178a5c404a1d65c916f563415684f90bf0fa7309fe49d7c9eba8e64cb5b9784778059d16543dd218e5fd94730d675b81bfe103fef107f1bf9ae58375e39248ecf4625eca9d31ecbc31dff20b894cbdf73e49911aebcb04e34fa05dd270cf385476397d9e7c91acb81c6fc04bfac104d93f05f0f053c667b47348c0523852215fd47c6913073ddc5efb8378a65e143b861c687e438d9cccb30a89f7072af4b2aa5199301ff23dba48c45f6ba662b9a912fbd49533e14de2da404e36389f052a431bf84983ee5c586e2c73345554642e1ca39a4d0220162bd7e23a0b0e6cf0b1f051b8b9c8c9c11da9a91742d3b660994fc5a78fc09fdf2354dc9570ca1f3a798d40b861bc03d4916845d32063d460b76ec4e5674535bb53b1631522eb46873e13419d20412c24cd02ea3b0be9780bb0dd7ad4a4146a9cf9bea45012b4c3d643de2613dab88ed250903698938a8acc6c28cd685da380aef9d36c0f5a0c1815936a268d3e41957e15804be307f9ab066f5d8ef7701c57a22b946c337bfc63cabd55d7e2f1fab31951d9d8aefaa2cc918f74e3519dfba80947184987f5f22e05321df6a8ba96ba6edbaed4521888cb65a410f893c97482b2ed783d89a103583856d1e6108849072e3036ef39f6e76fe4d3a4b6111fa7badec21f45caf9efc9fb8331219df48783a862be17c2466eba2d3679f8e1fa728e84812dcdeb1c4e0d023e7f32e1f0768fbabe1fc896184363d9f314006a945ff67042a23813cc6b53ffaaafeb0f26480e5458c774b0a493fc8f8ead0774708975ca0d9a4069fb21354fc8037cb3c8849c2fa42c7157b89286b2da1f412556e66475199af4e450d6169a8cd68e07a65ffdd4c2857be10f02df592be35e5275857609e02980a7cf32b77ef9dfee5e6ebc6e5c675d3edc675d3f5e6f5e675c3fdc6cd6eb8ff19b99fbff927c4c5f109072ff7473bdd16df1df5eb8de6a5ac0df4edb08ca5579d79dda5ffe12a1d1018cf8bbe172168e0a7bbed5e2abc6d54fe26a8529266ba3c2477e67a6045d4e2ab5ef98173209562a4e71023df1a619548448218499e589ed90975f1c6d5aa394337c2e32f214e547d71aeeef764a028aae6798cce850b3f839ccee4ec37a4be16eb11e22033e67587b863675e130318f1d1602a414f824075f8357b151b85f110723038cb02bd8b462c65d0621e7993f4635267c8ebc5068d3df1cbb41e9b848967f232ed17db6dec092ff3151bc2658e3dfad7841f8a1e56c5e60c4d19dc88b4054a00ece8b87ac0793ebc1000eec281cf8b27615aa01f25e3afd0b8f7ce03c7ef8dd00898ad28e62dcdb11b408e27de71f3321341d9a8deb9f2f2db0471ca006148ec19054ee8302e35d9378e072dfcfd44e840dc61fa2550b52af66a96937c8a8cc5fe737f43c1a2f6591404c2729e645b9487e70efa7ebd05be6287de044badf7666c4ed4feb51193f42bb9613f79e293a96b204aa383eb9f941bed3347eef13eb25af4434358111b3096092ed31eeb06334504a4edf4dbe4ba59e782fc56495355beb7c5d6d9440b7a6e9489855ecce444c882fbbde221ce00c275921c6f93d8ef43ae1d47815c49201edf2aa880b29edd166c1748b11354ac7b365c6a14749454893af162fa8b78e3ab25bbca0ad69dcf3c3ab34d3a48ae6b4bf76e97a6a982c4b8449ac10c405c6cf077dd54940365253560b7ee4c4b4475403c65d28c2c759c53d7097235521fe5f5a8e9429965a43a6f548f83ca70427f05c3a35bed4bf1b4a95da7265b2513beee10942f2ca95c8daa5c073e6030fcbb60f5cff4cb003d2df06405e2d2655def0b0a1a7243423c409eeeb5d22a0f4cd2714d87459b6095b510db21feb7b7b4715c9b615d43bfa65f89bf941b27c80b1f41b48611daa2b11bda36c5bf3224ed2a4ceb1a377d3129b3af4a492815c298e734fd96cd5c056a1ccdb93527c65e4d47f11ac058d550140ca90eb39517638fddaace56822f30768faae5237e1f55c3d08f3a6321bcb90f8a599caf72c97404484e985f8f28e3c813507c10d42ba427ab83cdb76e86856260ed86b23e5a13cfe74041450f6013d516cb0aea6afa82aae6d1ecd1cfaad36d8a85acf24419c50e63da3ec8ee934cc4dd000e177a4df31d369901ab7670dfbd494b27a16dc6c8e8d77f585cfbf0c45bc9c8dc86a4584bbc24c1385289310d0e0cad3efd8a1a862d8b06074838b6a9b52dab0827a2cb60646f16cb4323da13615342c9cbfc866646e513f53a5b4101d92eb63cc811e198a2b76b99d21454e32f02d8a06c56446e4f90783f0d72ad3ca1f7eeb8e6ccfc8361495f79a53e1077d316e7dd8758c5d582199002e666a8a5e5c64aec2e37384615abe9c52a8eb4e915455144c7949fa9b7a7e69d81b275aef28d32a69e4cd4bc11e196cbeec649eb0838cad87536708627419d5799538c0924276af4e10eb867dd6448fcece16ec464d78856b2b40a8b2cb5745685d2544bad13666b4230d19cb5ab9ce9bfabd2a3e7f6df82b02e744bd312434e1c26c68a79f5a8d9c56eeac28360985291f9b020d4a4f30fe1c1da0668eee333f91d4208996271b57e39e7ac239b24d92f61561ee335007e08b3ffb5be396983ea0ed3dfc4f24cf8d3cf8a8f4a662870e057ce0924d031c1ba98bdbbca5dbdb0478352e6478089d96adfb243cd5adb2af412ffa8e85a7cc60d3bf0ed0fed6ebb638efa405bb183551b35f27da1abf6d5864845270eb8c284e1510f8cd8a8212aa13780eca6db6a02a406ccb9c8b7322c2779828efa72238792930b88594e3f7b14bde0bb007708869dc115327065423b7671e35380a8476a70b0c4ac28dc9ae62469a98a29aa88658c1f1fb472ea88de83eee85c72b295165d8922a560e249541274f441cea02cb6b885664052e1022fe209759114609260e06bbe326c2e73e725dc281136b5cf0417abfb3451ae9d83dd52657041ad6e7f70efc4b97ca602623581181f991d06e3e3fa25803a78d12acef6caaf1607127900b7225dc81e81cbf566ab1d005735278e026e041f3d10613981aef008fc75bc277bf243cb94f7af030530431d817a0bf7132e252fb3b6c64c6b5ad53b29290a38096823f22a23961fa0289add9851277f335edb08e90ce950575c2178dff053d927456ddb8c2ef58e68148685b7c4a07a1e429f28a71df96ab8b68d294411dd33ff1137600ab2399b1a2b9a9901fbccaa97fe886263dd8b4ddc7115220416d52dae0c3c04f9388ecca5e76ad5c84d09f60cade4ef45443733f0bcc55e1cf9609b4ac71636e7afcd59e03c36a9e2fe72e2de3108d2f1b75e8556ccf2218a9739721968add49eade57e3ebc15328cd1332c0f0c0e3de997b853c3a6b134da6865fdc8867a7186017dd812a1cb9026f321e49c27f409b26906afb980c5d95ad2042394bb1db3a7a094b4ff2eab417998f6eb7ebbe7bae9369b7521b6c87cd9a666c302ba0e4deea8a6904a0fb8a9b8f920420871230a3a4eb5e4a9282855b3b15f7543117832439fc1e7aaa3166c2bc45db3877a3b80569c606268bf6327093146a0e035134298f03c8edd736412c2ddfea52cb484618163e0b47848662586d1f4e19a6d17da0a561a68af1cf04c62c8760cce06f41f09ea0496fc186c4512cb54d265344864f81c47d58c043438485835d31b1526da80b46a3bda075df8616580db1c5eb11d701de4f37e86a8f11eb472ce4ccedb8884f038e617ccc486b6b4b34d7f39670a0ec2a013ec0b99aee1c2d473e2b1922d5b8deeb2cb9b359ab4ffd1293e64702c53a927288d6ccf579387a48622df94ad0e4540b3c0a4b5007de1ddb3d64caa4bc2bd52c75c9f901a973a0a41850961e52616f6aa27e4cf08c205b20704fa84588c891be84226479e1ac6411715d6dac3c00855e37e8633963f0fc291608a95132c856caa8b9b5a6ec7d62a15ac6fb4fea54299475597523ae48917c093ca6ed24d70138c4e89a67e8df9bcc7b7998fcf8f6c32a4f1d5baeeb2ac984c382b70d3d1c0a154c5dc28d60c2adbc70a01881e7d67c980f2e336c783399058070b2209bd4afd09e929226780fd5baa2ef7ff464031b05824a8ac42e889e85d9e6212732f4c3f30d3d8701ab37ad231a655a1ae023728a303557d5e6e98b68bd7da95b7b15e9ffb6b4de2daade39c9abcbc619885ece1414cb595c3bb9132b41e142c87403adfa706f0daef98af834507c9c0628962ab657a01d6e07e5aa1365d2e248eb7cf47b0a5cb42cc2b3c32f91000102ed721b51bf1602e7cd3d5a4f6606c96b6f3aa1745aa0b1a8ec0285e46f0a01d91c846d82b83100475fa9ed12250e13641b51128e5a69e7e123fea07aeeadb0d1627483797071053b81628c8bb42d0f5bc20cba0c0df9e844854704a116c3714381c7478f64e1daf2838d8fe7fcbb629cbeb2c21c3e060d1d39baf60068327c9284575ec96a8401c4791cc48ca3df2c1a1b421645ace5c1f66139222dce0adad47cea0174ecc3a374aa3d1f2b5e3e8b48748d85e3a940d7352a805bd7c9591e549b6a6330f31d851531a3f2780ea1729b0bb145e920610369e00446da2a428912e1b8509118fb39029bde68cf02093b047533bdf8d114c2ccb956ea7a1b90b6d63684be84d37273b9f06e65553e8ef6db3d2bcdb4e2bfc126edbb54aba3015dbc3e4227b96648af98671ed6d286f375d6dce40cccd60d6b2c34f910ba84dd22aae682a23a4676b7e34f3f9e0f347301ff35be4b1808765246aee8d0193030570510c2d16471e8620985b52f82282c0422a2d603a3d387599e1c247324cd74b6ddc7ca1b1ecb890a1c857454728a2b0474d72a7bb5163fa5bce701076dda943d32e8bea413af0e13253de6aa3fe9ec13016f30b828bf3be7fbcffdf3b36ef11b2a2bf4c8f95fa36aec40f96d5ee2085578b8008530dc2dfe6fa573f21702dcb2686a64fef40160e8738c1810b2ad7c298d37eb0a3953985f0af10e08d9ae67041d50d800c38028a0e38c7b9aad57b24752a67db9f771b5a959570e2efc39c8f900a6290d66f26cab4d3bb540d069ddb31bbb7e96d10cadf7dfd9337b95f65e006f0dbc8f732293c510cb8530fcd93e15e81564ea390a80ac2876b75f24e3ffbc217dd7d05d35bdaa11bc619e7734082034c7c485d2d4041b9610eb221aed05182242cde059461c3c0b818d4a0c03c83bbf864ddfd745f9a937ed2936394287350b4ccac57c6601b65ecfdf0a81c70e6e285dbfa38b2c47654621f002f12c1b33a5d4e23b45da467eeb6578f86f6840cda781b221c3f18b97ee9a2dcfef2a9c7fe16ede06004d067436990090c2585ececc6ee86964e02dec5de68eb3c64cbd016e25746bc18c491188c1d2c7fa4115bb05d1c8285ca51bf7090fe68ac50090f3a140ae70d88afd2d085b8649d146923f1facaa537badbed807b80d662ba08b0b728dd9f2e1193419b1a45bc6bcbd2418c07ae1b037c0b225487c7db855d19d05c4dcbd3537765cba5410df7b2fd08e030a4ac17b207bbd4cb9dfd6baf0e3d31db8918784055bbc3bf077316ea1dbabf74c831e5f7518556550d3e372ac08b28d3082ac26f5b145face5a8253143239e8c214cee939005d1eaf77063aa72b7e1bb6f656eefa5ab54d451f953ed61f788461d8cd50279074d341d1691668feb7ca4858e9d6c907e4e2401c4dc29077416014ac9f1345935b8b59beea17ea7d924471b9efd8c03971ae0d9bd40c663029954e9068f3974208b688caac6b1e90db97312e01d8d8cb97073cce05fcf85ac5fcbe831613a58299f07d9869d42bb3c84f0f448a1d9ea9850a457d590353d8244d423ea95e07fb494530d5ffd538fa03b85484d939dc0d59238cbc4726f7139d3ab699bd6a0aa99ba728aa1226a4235e6c09f038e7d3d3d28ca16ce021a2fbfd85c90e66281bcd2124808e92d5f1f9d46baa3577d93e58ebda38671baa9a212651f8bfc72b61bfc85b80da9f4d6aed850fbe6512c3b1740236bac56463a497df357cace294ae31493ccf5915e9d6313048da035c809e8285a23b711052196a82eca830585de3fc564e83cc0a965dc1b25cc0432e1db47f6d89c0969505151d5bfdfaf4cf02382dec9ea91e409b6411a26b5940a1bafc3da0c14b974a5ae1ba534a5afd108e6341f8f4f86bbabd07300007223fefeef8543fbc207342018e957b88802d6ea17b398ac4cb5a05133f6eab839537f6b0c89133f3a114aecab88bb776e409612419f09dea656c16b5f4125a3cca32a2c0938707e3663d6b8b2c0a982598d9b4c8b30ac2fcf5a71f858c0f121e871a09f8b2b259ddb6219cee464432e93b2143d405bbb5f30dabfb20260b2bad0be4cd45edd8979dc1905b57f50652ccb16ebf50ce68ccacd66f35816138e06406d5a45cfd67d1ff2251c29fb378f11410dcfa5d39886f3d6d2e13838bbbec5936ad912c562945812d4a02926e50fe89ccc29001572fdd5a0bc87c1213e829ac54a8bd5e39294e71e696941c1678698f5c9eb4bbd0c5b3dd834b54bd629eba7d45808c983b1f6556570f3d2ddde0860306105f3ef18b52632fce3f7d8511cd4d129180758890113d29c1f46e3910a1b7fffc8478a7e15a0c8a86510861614af5a86c66240533f6e2f5e79a997bbc05bb70fe5c69bc5c0dbb1242b2018f684a596e6928496b605db8962f91ad2748132247db5855f27989e869b4781c37df347cef335cd61ce99393e9c78dbde19e55099cd48251574931e615d6af68fb1830e742b6141c7347d0fe89f03866d4665cec8e188333df6a8168510f52a929de4180b4dbe97d2302d4dc733d3d057a0d44200eaa8562a464d429005cb804e00d4154df4a7e7572cd8c56c6f35b860416d80f4b164945f3551ee171b0e922ee3dd3746e77432c27457e49c9baf2c463c4eaa5fc1b2e55e84142773acf6cceb70becd25377050d1901fe5dc4f82777651ca2671a0994457372a88617f47e896365fb7d0d2630ef70d250fd8ad269a1d1b8d615d45b0e7947953867fbb8f82093ecc07501ae06f0699fd383e57d23427fda748868d46831683a375a0f2d522b6bb988dd8e5693d693882cad11b7fe74397496c79b7cfacce01232020fa2b13ff0b4017aebb24b37d2cae2ba2c8680ad70684ccc01923369eb6c08b2ccf3050a85baee3b5c7657c13bcbe4df0720766037f093ea6f3a745f7031b3367d24ac6f694e34c533c47838623335f49ad5a5f7b85e1980283841adb9be0a4b930354214391e796c051b3523d11987dbf4ddcc3aab83bc818191c76278c5e9468d01a3e9c3e3d08526d9c53b39e550b80abe04bc2193989f124ca73b3e4d373c7672e2df8d45a78c85608d61c02f81bfde5afab9fb845ddfb173d0e7c7719f65b89e3864524ed14e54887da35e192aa967a49e8712947449ccd465497a1e3f8e5aa4a56122385703260e781dc0e123be0688fcd2b4f655523941ab242aad40c461dc386c160a8ccf39ecc017c52d19ed38d1772b5c70d74e2a53232b020d75c6a0bdcec0d2a7e97114ff66f49aa358b8ab63a4eb451d5230351e20ebcfe4c6470b9825caff1e82b2d7fed3771902c1fbeb6dc2840f31e93b7bb44c18ad3244d152521210510b6e3d507eabfcc8f1169b1c503631c8d29d95fcff95221dc492a06a5d8f55decefef653e219e8d2d9c655507fe0de978befb3b694ecd660db1927c5460fcfea93eab27cbcbee0521ccf339dacac74f9323b149e9e50eba2bbd4e6d6f21c54e2fb489236e3266a0b0db1f27171b70148cf8404324384b17013f43c45f32690e92d3f36d24a32aadf180d936ce5e22a2f52ee46923b44be6ef6fa2e25bc257dc63d0b5ea5d6b7f54ca1e233f12d5a6c3dfac15e865f0aaa33e5d4b3cd44b62b3621c592e312da4c3884468c861b7e9ef5cf32d613a888320b8d506ebd336f404b7532da2bf93ecef13402278d1ab0c3cc38e2faf85a00508c675fc1dda1d407af9c9c9f0cbd45db155167fddc2a4fc702f7dc45e1205759e50691d2bb31c9c6ee900b63ae15f43c32c99c3d7843606f724374933b22405aa81700fabec8d034a6453f305f68eecb3883a579d90febc625194b9a84034fb72a95386aaa662e6b2b1e6353d5e3416ce3ca67e7463845179c43f633199ac4404ccef2ad050cfc2b1c575b368e14d928a0759f34664f3d078e56b17a027f3a62e19cfca5bdc81e5eb0cd7f73aca6a40adc8c45fd6d3ccbdf78362ca2f9e8e2f07e39b571dadfe9b08a959def576d7d7036b8421d45ddf888e6a0cc384bc57126488d1ec6779d9469f4494e60d4467c2e12223a7108ec564e2925b9e8f5c91119c4715a42035b4291474eed855cb294d69f232029db6b03b1a1751d34b038dbf934eb81d46c078fcb474516e9e04e72c4979478a2fb8697715fb18114e0e0320c3bc5e79835ebee5fb3468706b1d93d96fa2a3373ac7e5e28182740483bf5918405222e13641475310e63ac60295206a11fa141d1014101a4fbd0565e8845760fe424294b458a66670dc144aceae853a3009b12770926346606fa01cfd1422cd536bd7a34849d6d331d7370dd0adc365ad720063013bbf393dbc3abab4986280821944fd81837a65850e83eeae9c9e52c5fe403eafebc83775203a14a3d0d351cd0f0b40f6a9bc8340168dec8e6aa8b588885f687a1758a2a894ee7f7e5125d522cbb5f0389764815f3da7467e0e88f3c03ec8d2e15bb01ff53e5fbc22fb4211fc0dbc0472aaa8cee97bafc190b33b3cd1ed1bb281cf6c19c94617c5f496752448656e1abf3e37c3946a25845c2efdc8efe6df563c24334103132586c1aa7627fd95707308f33a693e7849698804bc99b6b0874b5e8ef94414c3320406021455faed68f05376b6290dd288fd50227966070afad681cfbe241ac50155ba00279adfe2a6d842f14c6fe54115efdcd503a264cccfc7dc9095ae909fdbbff6bfb881679b9e3080c4aecffbfcc043d7c2d731a652f60737a209361500c02e0099f2e9befd39d5eabba98626baa854beca1d51cdde819368b67195d12a0c3e7f0bb7df218d6ec85ef0757e764b87d00674148dda870d6e5cbc4d1476b30890f74687b7f64378da481c37183347c4143b0daa1aa4c6cbe35a98d9d61175204c73603e6814dc6cd00953b0f10ce6a5b3cbbba2e703c9fa0879297458793d95ca1575e03ff265f9a9b569383dc5e94df14ba7204f34aa86e51c00df341bc3a8eb57df6b135f16b01bac7da6ca265af0e8ef8e53d2f69dd9cc1b84d0a1337a8cf0901768be4d5a23a82deff1a7f68866d9280d7df16417bfca2f30ce5b117c81c7a2b2cf789ef2372465e31a9524fa965c0b0a2da0c325d0f69720d25bd49038ab1cee418a6e2d4b8a129f9dae8d07e64adaf9cea2485f477f03d72609bb99b0ec600af2a1e0a11946d18910f495872d1fbe0e3090271c03a9e74095da90234ba249616044c3d1038eaa3183a8aa9a8c84d3b673c7d840476830e244d1b19e6fdbd6c05bcf336eafa2128072b3d97dd345061b144c4bbcdafb0b16db59a2bfab1b847ea40d183c1bd7730787bc1f91db15e7b758a966992baa6837608eed4519ba45a1b611564788fce29e0f88d5c11a26746c6ee0a3e3327efd8a31774adafed080d4a49f3b0164903009f97ab9e532770ad0cef7beffcb607216eea8026fb497d6a48e4c0d8706282abeacd1a58bd876d39e5ad8b54e78a5f28881af27653c3539fd06f6d0d66463bd557441440469332b0272793e782eff237c73575fab3a030bfa284526d95d89c1b9c041ff0b68113ba713e191e2a40aaed97bfe44420a1b0954480d8fd5db81aa31e003afc0c292984250ed599b2df105124eb7afef43045f617c544424b07f241d151509992b6f19c09479a5c92185165bc595bc5a2e02b72bdec2eaa386667911b5a54d2c1f9e75886ecda5cc1a5af1ff3203c863f98a20f342da55da62b01ebdc48c93d3cc5b72171df8fcb62b4bcdd533d90d493b07ad2428261984a075387f702adea3ff1446183ca1bd706d870f82d6fdb22c8ef905a7cf0d34ff57570eb262cfa2e6255c331b4028c215f1eef3de545e069eca52d5a3725b57091296aae4b1ffc87987b28b2e591d4717015e6319c4182193e4269ec515993a83aba7c21b935190e56dcbe33aec6d6b501384c590fd7524464c370043c2becd636f574dc18d26ae1c27909b428be71190859d94ba77d6d64151825280178286b0fefe7f6a5cd8af505d0ba29c05bea2556acb0fde62878136fbd99d26e290816ca8afa03477d6be4b0eb4112c5bb7dfdcf962828bee15ebce9ad9bd001771241604289db16074947eaa6201a308eeacb2bbb75360e4ce80c32a2d0de4028c00d3a9ac8af175a42bf564b87579c1cb37f065751b9e53e067a70683c34e02bb34b95736acf6b31605654b86810ee64512a751d395159f52bf1905d156b3ab709f68b94b976cdc737eb6d96d47b816e91230cc51ac78f7de223c70364cc2214a043d4fb9349d26e94309540078b1f1472bbae0e84893f523c31440cda29c352a067983868b1cc4935c0981a7674a89c48fd3daf4524b300b9956e54e9359ca7016a9f6c29b1fedbc99ede995b41617240a0c9ab53a72b7996533f3584d3e2c6a0011346173ec65ec01b23578c0c358c0fc7af9173b081689c5930ee4b510967c602eaa2fbc28f56e66a41854363cad7b2ae0984cfec4fbeb4e96e5d559956ffa7fb02cc8991dc870b08bb8606ad9455950e9406c6b592f9d210950fe58fdb8ac101cff9f60f0b60fdcdebbb473122ef8730552e1479f462dad68a993a7dd1981b21634bbcbe9294d41493c87ffe26c1344572f38ff84900666250402bbe0fc1e86ef30d48521463e973a42085da45dd18ed0c3d59a56446cfe06fb8d63941d79a62f20715800baacf3fb40c769d0a7f0c290dff1764538a7e37f65a996939fba1d841ba9b90abfcc65e757b9488d38f884421da665881021f1c4365f1291e56ef5ec76eeab0d204c54835f82642a13fde36fbb80ebecfe4c8eebb56b13906ed4dd22829b48a0f530b6824a262be77b9171bd08d8c7154f5c0e90fa4691d8fa696a7835020c1841c5d549679d3473b4f07d3774390e8fca31f8c8f30c524a5eff708ec4e0f53b3ac9da378119046f14693918ff3499cbea0e0ffa0d6dcc21857c905c558d5039e1d0505fc174d2faeed90a3d1a24a80c6b50919e7f5af72841c03bd895ea3ec4c84fe85075c307e239f915c38262b98d49612ac3aa4ed0f464480ad3789251b2131012e1bea8efce99b60d8bae984ecd3f6696a61a0541d275d643390998aca62a9789c04de27e5644fe52182ca337614e3961df5ede92c65cbf8a5c6c0cf4045c229310dbfe9ef8a3a42fa34abc7a606e7e69466f8486615ef139d4e257caf13eaf634f6188bd04c037736ea6a7bf783463a23f40802f43bde08c80528aa6422f4b869541100a3ad677c41d28185c86cc4c3b509dc01dd1581a1f09635c547ff7b3bf792cefe3d3104040fea7302438492345dde3ec9cb916a01891323a9c34f5b38ceabe47c1919752dc444711de5670f702142570227e161541c4d1a900e32fc6b09b4e1cf4082e676647ecf0404c70c575bb90384078b340a4f4ae76c5c1ba1088bd518c4fc14d8c32e0cbc65c0a2cee3fc6edd5ccf2228f93a93cd622082c2cd4ee614776d45c67021e28ee6ec77e8c437f85d923ec6375a8d3d1500eaa5d465d08b9eee0ce59b9191dee77e77c37695a57a546d13b9ccf42bc8fc5bbcd2f70952921c20694411858e0225ea94d7d86d48e046833cd401b72ce94a4415233dba5b983e06a662b69f21624abc613d80398ac2177667f56489b48fb45e93c95636dc8c465aab680f040ab0c773e10e05cb129703c1000b5fc0dfc4f32ba4be3d9c738a9d6a4086c0706ffc4d1ec08bb5f9fa7df24a84a3924857410f2cd3e9186b42a0010fc0545b644de56e9ba2f209d9b6f95b8eacddebc8e2dafc10acec466e455d186e27443134b6e27f591f096de8bf365756a7eb12743c33ef03531a8e950b450dbd170524385d6d2ac9469357be0fce6a3401f647c3dbe8e8343f13000f3b624ed16f704855cf53804dc2af0fe7210abd5319f1f6558d5ff40a4323601c95ad2661046d2ec327f660e6b69aedff825b90b6ab01f5354e03d653ebea6270688e20095c6492fb5ebb6268851e95f27e167b77b19797ddaca6518d7283ad3e5eaab8ca880cedc37f667688085d4a29c1d791e002d983b3c31a87ef5229d3083ded95ead402b78f716989e315619b641f11203eb49b1a451b00701383e382e080c84d2c675be7eaf48452879f88d7516ca04baf1d5fa54d610f9798cc7928de56bfaf705389d6ce4438a16b7848ebb9f6ab418369c51f72f5bc16e926628666dc63148df66686deaa9d45aa2f36e54f14538ce105ab35ac04c44567be15387643ff0fdb6cae0ce9c3a85ec15cbe485e0b4e96cb12de946be7319c3527b8cecc58fc1a92e687ca66005e87e91fa5622e978abf8f508316a6ca220445901048167d8e7bedf98347600101d1c120506002028eb1750ab4c2be3473d6e4d0aae7c2cef6f8577a200bb1e6554b26de6e965c2594d76ed3167b341c0c49b48946902a4d808b82e1a36af0594909891cec57a4486581e37c04c89daa2181de7104f1c8308604ddd1e029b747f9b7af0f228b8690cfc0c9b68c5a34fa7c4d078dd5577bdd7bf443d9cca7823fc1635b5c0fae65b621276768c030c35d9d073613591d5a7916ecf5af7cdc0897fb68432d9e93f25ed5318b86a6a0da8e4126a42a011be885f0bf5df2071412bfecef2b8cbdfa90bb7e2ae8702e85bfff1e732bf541dd2cde0f5e39f498b65be3b83933cd624465b722a4e52e3038d4efe310be15d4735ed0570be421de546880fff9d502ea49ddb98dec4eafee9c93fb1bfc77461fdc35fb034092401cf74a125015b6f09e52eed0138c4ecd49ee64380515da49957512dad8ee044eef060b7b1debc48358e596e49f3f82fb38179e4d3fb25cd99af884caab2f6764613ef18030df31784ceab1bb40e9382f4aa696f334f908a370ddc14b70d316e9ae93f82b81b2e66a5742bca027acc94c7f1290aaea9130b9ee841123dcfcf6abbe94fc70621c8af7e09ad8b3cd3258f3621e1622fbd99c661a8431754dd49f7dd1bcc8a40c81628f2c0df6e23fb897841dbc7b82c2ab877739ad4e43f7466a987c20c4a4bf0e286fd1a34c02194c46280ef30eace9cbc62dbb1c21be78599d20979a5d8a4ecb31b5e8125031da50d8b3e645fa062639bd1ba340b2e22fcf06ba4bb2c58424ded7fd7c35068966bc859fe48fbf1c2e770cb89de049fc393e913a487a0c228c6c66f564f60d4c248247a51912a1b023ee9e92d43b3900ace1e1ae30201bdc4f59a8bbe512220a65cab16b6e952e0f98c7750bec33a11b96bb3eab5b03b4e03f338748eb3482e665a6648a6349291d068c522be61da3689a75749551c5c9e82aca10e62b8f05bc3e2882d4a30edb55d8f1b3ffa6f2d10d26f52b9a38e590aaa0115e0992e3406e09270f03a3093b26d5a9feada1e7aabeeccf8fb128be603fd7313c5e9754fd074a6e533d6033b62625ab2cbe7f47642cc719654b3b96f7aef73402b1241399e6f87b63dd6fdad57aa28caa1fc35dc11d0f6abf552a2a6a12b9739d226eb8029cf4a6b57114104a492ad170fa75e807f24c175ecd20a31a3205e51248fbbf7907e1887f013634fc21fb051d6036cf8f6dc220ed39e8d3056beed5f593fa00357b9c17327d14c480683390b57888e0aef319fa56805642d9c58965676340629f1729becedb473059650264b1bf2d6e595e7eda059f595a7edef8792c9e5210ab5322f509ecc5037e759e8242496f119a56d6d7a6b28985d7c10e23dbbbf127227460fc439cd8e9c30874c80c2a1951c1a15259f12644173088300c6b80d8b840cf6bee1f2e0f98414674ee7f323538b29a5f10736aa39743978479579f40c5ef5832fa211e315415578162ec1cfcfc0ae524fbe754e3c15c56adcd7e1d1dcd0cef8b9b7f1278f56762068242138372c5edd1f883f9ec903a12333966a5c71f6293623f7a63648e5e3d7924569765104b58374ad2c2654158b1e94c3ee075fe40b20c52c3da7450fa7a3bbd2830652121f56299af10a5739b87328886e26d810334f30481695bdfdd04650eb668628b8a487a6f045d423a90ad6fbd112059bc812c9791f9c4cdc9d68cbb791b19af03cdb7756b30e9a0d7041b58e091507df2eb039052d947011eab0a72046e9c55bc1a45f708633ce5b5cac508e2018c9a512fd48891f21888094e6ad3ab2bc8cb4ae8c804e0ce9ffcd5004872d3045cce3680e2f676912562a57f6260778ff8100ed544454f6b672e27f5aa0505ba5a648c61c13eb16579c76fa986fd82e6cd63cdfa1606b17d2004f643ae1b0fe0b13f3eac65dfe906376bb02b7e11c17438ca458b01733af6915ee5b8690fcaff7c0af759dd167b599dfc6cf9aabbca6cdcace2a94deebbdfca5c11e917e64cf961cc8c29168c410eca9f3f24fe23cacf51cf6c8317f69c2601b90ca761b92f3e2c063f5df41f9390af587acb014f8a19714c8de40dc0b234c71b2c5a5b8382c0cd9cdd1fc6e1690d48cfbbd17d60e0f325ae3feab4f9b7ac016bad58e96687a308263be84c924c03d663617ef8b2f88ce62381935dbf9a5b275a3ccebc298080083cff471d819e23713fe105c30c203e9ff99ae052fdac47aa6ec924e5a53831a5fdce3251ee85824284e0b1f45676e5cca603a45405eb98fc64f4bf8003d736e869ccd99c66fb4f4b4ef1387e0a145d81eeb6acd91d7ef274b60470a04a32d43fe53f98c2475149ebb0a425a3e87d8a16d664e5073abd6ba43d7748f54757d592b8c4f857b51f9d692a5a1b4620da0d95a48ee1b2626b75cacdb17a34264f91aecdaf6ea5e1a2a381a92af3546c204fac86a40a2f01f606264f4067a902c4261e1af98007c2c46e3148784b0bcd7ec6176197d64b76e104d7236eb577cb88ff4a3f6530b4bd8583a5d100cd02db88c64b6f5a2a456284cd022cfcd2981e8c889eb54464ef1650c1b0ea803974e05d727bc01723ec65d5dbd2c64195bc2f02acfb62165ef97ebcca9295ff6a31bfb96ed8b9c43e70b0e29d3925d43d6d07c1d058398c570da909dd23be25bb2c02c1b9a7f1885a5d0f7bb13317c76a772e698369948411a38a4a8161d0dd8be8eefdb6314702ff4ca8ef02da3500cf1b399dd291d086f008708614a1a5dde41ed364206e13f15fb00e54e5e4fdd7580e5bb09b507c542b09e2f46a82d558e6c640df3164e51d9aac1864cc9b982d6c8057ae2d6fcc31ff22533ccbb95a2df33566e071a306158dc01efd77ca1ff1a7b661af5d15330f2ed55efb73d8008efe6dbea3c03743cf21e8f5a6b0828900370badcd8df6e51610c725378646c5fc300e886b22104343ea1de191b41a05796c850e3b59c32983dd6feabbff874253292c6e464e00442ee1586b0b9452002650b7e147c55ea8aa6ca6129ef227f7b6d7c13442e7b01f48d98c47870328d9f961d9bf49911861d935cb18ce5246b04e0f3058d33e46a9f28d6e156dd62b5c633440c8221d71a5c12bf5b6104acea94e69955e2119ddf65b9fc2ad3d5a0524ec4fd765ec97cb9003135ce31d674d239b0a16a59b8021dd91aa215589618ed0b2e3fe62c57f42d1ed600707b5b764abf009daf8ed9d54d458a4b7d91f51a8961229a4ac01d6cecc9d9c1e0125eec0f2ccd9bc400e3a6640a1683e8596760ae73bcd9469bcef912c2109f0675eca2438a8313e7d4c06e087d1f8a07d8f50fdb963142c75e43d59801921701004f08b3ebee574a90c92066232a037b9fdd097e325f300b6f1d6793961180ca73dc58d9d5654cee84d62027f215736c2462d8e8694ac8039633419c563e7e0eddff8c591c5bec7f5e34d809d010301a55c65272a1d50418c7ed0edd1886e49b62e8e0363bbc8fecbc987fd5bbe31d1805251d88514cdfbf7d1a113504bf64133bbd776d5af1fc3e7785ba58d4334fa0033e20b4ac56974ea8b35bb11b8de12a3f2af067742f0774b2cc99645e6e3ff048887514dae88af3aac78f2257a5c627134c40a14aa10f42c8183d01075a6e60ab94012e58a7164ef0d714ad96b27d0395a7d9df22af6c02461e475fb1c03aca0e515831ce2164b70877ea4f359036289e1c257963aa827eeafd8f1a184f3dbec109f7728a9f03fba01846a9d7121c5bf6957a00a3c95e2e3effc5cc96c214450a383cc00eebde608a37f6e52c53802b6820b1208622bb870204332df8cb425c0230bd3faa6792f514462c0554c96b39301f7bc884c07d0b2b0ded407a6dc6829202e89904385e4a6c2d0bf3550ddf5007e5d4a18311882362ac5792cbf12b0ebc6aa7a358f5b18a72cf9821d7f804ca206bc804a0ae734bc86573c67e1df8b8e5f119274766ce6e6ef295af6706876065bf6b7535256444c58445f70e80901587d9b333a6f9dbf1440173af9e1632565ad9bea741eff3896e64f17d73427b24bcdecc50b80fe31ba345c84fbc7b3d82722a46070faec51879c1e5fd0b854eea3e09e2c0bdb009a06b7d5188c9aa1f904185bb3bf1fe192b7eef5ef7791c7c081d986b0304e3f9d3fd173af2d3bc06736aa03f50ba787f0d497509a0cd7a16629853dc84a8c852cb0c9b1cd72112120e5ac57f339af7448fdfd003dd04ecbefb19fddf55778b869d191581182c84da051f55169196193cd91a6dfa028b2e6411c7309141222c2d61947e5c5230cd69df1391f3312bac67045c1adfa0caa9022f5cab051d5302e36541083110d2abd78e7e1abb6222e1d488dd89a20e75a1112c001c4fc9f8747afa88516463aa48bfbe606a219dc30cef0af2f8d90fbed0344806558cba64997210f779e9e45f2b080c3499416fbb3eac1a978318ed9f4fd34c6fc764a689177105047697acf52d93e8472a3190c6798901b36dadae0864eed48165ce57765d61272031a229d6605be903e38b3ab044730ca7f0bf28c182cb4d892ecfeba20ee72dd13d7bcefcf92a053ca91ffaf301a486ad92fb396cbdebfb3920864116a41a1d9dd27f5ebb53e4dc6a6fb4d656a6f4678b7197132046141040add4b2a135c027da490c22ce2ef5fef5d569ab94275f00b9be8a1055fd0055a19870788f1f37e61e9bc24c8b4f1852ec1a2c3e622a73ac3aa7fe57c0d2ae1bf372047d1dde0b6e46069d71113e34824b9bfd6d7206d706b0df6b389a17441954b45665bad78ec6e24a5d222daa406158ee49db4f3d964f8d7d908a132a805b65b5439f62f2a679c764b7260c2eaecec3a35019a0ad9fa4b35be9dd113fbd9e3858ea8f243c038bf283856a14642f6cba12abd3b9c7df3843e148522d2a5906b93e035ffadf996bdf6c648c45c84aafbada85302d3053b4c9ad653a57490ae578358f6bbea9901146417586e9a11e57cf050a4d574fe8087db4b98035aa6e4c84c416f19832c0737f5578829dfc64c38ce32768adb9c81cc655ac1d12e19d0d696da098f8cc2d10c66a7fb8b7004e71f91376f2f35230988784b8e911eba83ee469078ba79d1cd8097e472ecc0d5f233bb558e6dcb17509010f71c225cab060d5991004bad2014e0ff4eacae4337dc325acb80e63e9c5963b7ad6e52012ef07748b21b7b5be9eb79dc97fd8820c848c8ded194317ba556b9b58e364ef82b6986629f56d4ff65aae25e90e94271f0825996302c5cf2833cb825895c97431e5f417a483b8e7f3a61c3fabec64f8b0688be30a1588d2a337a16eca94e4228e6c5e608586cf6dd13345b408b2650a62073ea6e3038a6e0aece2bf6800513041f4073de9d53888969ae66142d5dfb7e2f0ad8a99607f2deb46db4a1dce01b311608e7562587d1adb9a1e9fcb326025410c629e0aa2148a5863d6a9c76b353c67c43ecb158ff0efaf596570614edba03f98e9f55c31daf8a7f4d8200defa06055e14337a8db6af16049fdd257aba5f76c54556489ad91466f800751c79af635c37aefd3e665d57c830805428f0ecf2fdb2caaaf55e2d8ccb7f96219c2fd5306d931771d8e206a761300e50a937782372767f7edff86c5adea81bb92b8128cd17c23313bca0dc00db8bae083496e215a0de67582f6f20ceb75dac2bb4afd98f2a6cf9dd780eebcd6fcb66203bacfc293944cf93aa72441c23df722f07c07161bebe940464f8a8fbe6f9e3cea2cc834b7c30236d3bd6db17479b14bf63b8442aba68ac1e2573b79536e6155aedfb17b82417273558261b97f9bbaa2a80ea96273f1e8df597d91df824ace3452377c5b96a48bc8b434e838d2d95ec218a35799e81833c067de69ac2836a0f57cb37dc07396ae0bebd0abbb1072bd0fb0a2c30b2d9155b304754b175cd6d94cb4b44758ebaa38dc8aaa5957a9dd012aabf7620fc425d05a30979ef357253b1227b89569b685eac691d45aea740f30701b341b51869572430f1a1c70df06150df65eacc14a1df08d446bd51ba730056b143b086031a500a2a0129211b4f45fc11b311d37b0d9e273fb6b3dbd0f0cea5d13b3a67e5856a51af7835de2fa32904366fad847229dd4af2a72d3ec12cef9e301d8ea34b18c6531867e4127fcacfe419240b427c662b6fbbf0a7b969abd2fe6484fd6da591b8e03cbe21dfae0809d6de5b0418966ea510503b8f3f3599050b6dd7e11924f429dc69b2d1f82d9305a7401e716fbfd53f8d51b0b7fd5f3ec53eb0fe8b76062ed9260a740626f8ccd3cbeb38d646dee589075d039ef7208f83e3373bcec38b05820c05fff0b681ef98a384bfb1b933198f2df981e8445729247cfe186dfc7c756683914e5df31296b162623309c2f86db977e1acb8904f8ef9e3f3665826c1c2ddb5c3411f8424d040afc982042b8845f734d2a7c0bebf0f0da25684e54bcaf4062271a080c3a9b81f601378c9ab74a3a22d8b902256efa8c48c3ad3dfdb295c5fbecf286eab755cb8be7f5205ec61f17bebf8464f817713224da978b44f8dcb9a7cf720626b2a47aa3360b91d712477ed3c61220e6029802a904ef16cba696206f455781a71bb73f0127bbd002670c9ccf1f132ce0a32be28fec58d7418c1f3c5b4b0681c3b73fca26077a88939f4960ee07721f1859e33f9b8b2191022883e724494588741e2fb858c1c823b34c20c2b1b96c609cb396d4ef7891870ac572c5d5c60e60f6709bd613e3809764109305f01adae46105e533602452572f8690f09e8ae449ceaa82386c90d62c22c5236a31aa3589c6ac38f864238ab0bee3a86dfd674db6281557a9e034975d3da35976d6a3a42cd87494821d9dd5ca0cec2753d1a45f6f2dbae438fd077500bd3268389c57793af96d834854b5f02124dca720def1c66d285c63d316ac4bd482bc492147c60720ca0de0c1f5bc4608679e1226a1150a717a45c66468b04714ef17f88ad968169a43c80d6c7cfb8f50dde222eb957e7ddfe5ab517e8d17bc5aa3426097ab67ad2b6cb2d5a56e70494673a465868277ba7d2d3f5654d180fbb6cf727fdadb85260e3383e183ab0db365dd8b661a2189df0a9f93c0fba98640f5699859212933ede180d2056bf8fde789aa1317020d220b5236fb351112c838d25f3bbc054a197e76e4addd2b0edaaa3ba1eae32a39aab52c1a40d04f85e281a69e5f24502deabc3862b004d6ef22c6ef0e97bc0b7d3abccec9f40517bcc06cce9e5e83ca14229120ba21b1e4672f6a60b53543adb6013fd60c89de7bf59622350b5e054260ba5eaf461269d222dbcdbb3b3b1ed46269929396bae63a0ed98db64a35791f5a307c308b242182d1f881335e7470f24145446a9d71065a02759047d439e714783dba45693f8f9de0e490b834bf861c68d9fea284f4cb9c523efe3f9393591e25ec9cfec12f8f37bc8e42dc3664678941ad2768c73927711dea2f42af9256617bd527f339c68c3f95bef715b442c3eef239e07525cc8e68d2590e6d4386b111b42ac60507b9c4048633a390c89ddd42feb4995b8bcc71d27acd4d4452d071d5f1a7327f51b86b8b0a747f1b46faf80789b81f4c323f67256603040095a34d6477f47a17098d4661829be1be804e3d69e95fd3a0a3fdc4457c76de7908b73dfcbd24cb5cf69041be019449a573b5d6a972b1dfaf351e4c20224e70323cde8986d509413cec84b017c7f3de1349a6b78da62b5389060f37d5aa4165bd11c7f6238de1c0c08deb6c760e108897a9e5a53f281e8863d1c4758dc0a15f3e3e927cafb6f5bdcafa920bb86924c119c44e1a482208278e222140bac402068280953cef01e60838b1da8898112ff941a4969c496309ccb300fcdc7ed72457a131f67886587344b15e2c0b8753faf395b432ac1bc82af3a2e0967c250532f0858fb4f6bba4479952b1795a2164a78fa9e3aec4203aa5131281faec613b4489109bfb9d1a6ae516af4f11953d65f3b1bc15f2d66a46ed473caa07e321e697b06483957a0f1aad5dee791b005fc57580cb4b4c0872f597d7d7b5ebe53b9c34983eacd97a18f83cfc5697f8f9d01fc280f2af023efbb1a795135a1fac6d66ae10285bfe7efa17d4911fa650b088dc6e393340ec6cbf9879649c27f59733638e4c1d260fdf808ec9762254e6cb8b66e2694933db23a8052f11526c75083f212ce0b63831f5ffd93acb91f9716d042706c4d6ce06350b72b341cfe54fb30721a97e5a2e203edbeaddc482a634efade976873fe04b93679877fa4e17e1ea812930c4a755365466517cd649e53f9c7dc99406f9687c1620636971419c85cc37539c80823c9c4472e50a7c5e95ec1bd725c02bc768d31154bd70da3b2e7447ae8b438c6387d772904551fb9ec94b8b4ff52c3d9403a6421f946e10197a016be6e401c531497ad9ac3317465d6dc5f676bdecf28a67b05380d5205f05dfcf1ea6bd031f704d3819bb332e8a57cf1d74d66c82470db235f66f96483ee3b6f80b4e6ec1709f26c59aebb28d54b757a3b5e7d4b4ac6f53f596c6d9f0deb1f2ef343311bbeaed4320f22837114d58880d05b250203abbda419731584f001d30e633aa6f8395c04e1597162a0c3ea572e58c5b423eac970b180fa25b770b9380c120bb37e7968ad5da8fb6a58bbe1ec88f368a628a8cee426274f5a20134d933d785697cb3b58859573addaaf3e0adbfe6d182c2aa56d8e52d0270c2b44813560bf3739ee468ebe74e1e8d910885dcc48504a661506fd7744fc0091f8f26d08893dc85b0fc8917e273f129350bc268ac897f1792c2752112c64d3f2c18b4e3fb38782c3354aa0b81689dd087d742895d23c98aa26727e61125f764f4b78d78a6a82c543ed5423d88e395c2ae7e279794d67a6159c0faa5017b0c4bc03d231d53cdfc3abe089dee5c4209fdcb93acd3c802bcda62170d47156adce77cdaec5b6801e07adfe56153b80325d3a37df6fef3bc623423daa63640d08dd15a8b7a2a4f4650951702fcb5307980ef1fa87d53d874931b0d4e7198907b9c0cd1fdf87a79111376184e88554b08143c091235197971cdce96407d2749fc271d286c752fa1981c2871cc049990f6eec5c51a657fcf4ee7862f578562df757d674f80edfa86a826d080405b1ee0246e60e978241a6db45ed6f59a90b82843820294e269e2ea0e6066345992c4a607641c1fb48eabf528b2cd2ed3897fe3be18992734cdf1a1b6a0497443bb6a7688f70e0b3220c5d0c73569e889976c70e0cfdd9111ab1829919d9b8a840e6435dcd7274238cb8689abdba6a0b6abde895655020f6f4d28f7edded0ceedb8d77c64b098026a210ab6a5261ee66b6d73a4369f8001ffcc67b25c6760fbd5a8bb3c4ad8f3f50b00a85ff61a8ec6e96ed2ca5aa537f9b115af98f82f46c15780f44a57409c69884bf8ddc48625c4376874eecaf928426e751d125a4db14af2737e227c98ba713f69909b2b46ff00cdd9c58e647d9b9e1762da520607e8b39baf9b707584ee277c55e51b8ea0e9cb039f2badc3b1acb230d6da22f8525f3054418711c66c69fcae312bc3808f098c17ed489c9861702ecbc2f9b9f4e48bea2914c8c158d1804b30df29af34522307832faf004ec720a0abcb5199a18ecb816e6fc5a14f5090a541d264cf9dfa83c31ead138ca5615b8b72d94b321feedefa56e8c9b4baa64c358a974f9af29134fd304b798243ceb3477b032f2c638f73260c9685623c57ac0b33c450821c78b6be2f9917ef5779b137c3a4e06c28f287d7645cce97c8891825c1d442cfc38af9b9b6e452c90a71f27b55388ff34a4f56b5c5c1cd69fbf19e7947e1aace7b60378e375ee65ddd702f986d9c24c19d1ad712026fe021b3e98b7254c64634364626b2ec625082138c9517441677e0568326eba12b939c04e473641e49c49eb2ecd72bc0cbfbe8aa3a11d91e2c32db1ab2d90dd16b001f8b4d9711d3f684124c6d9bc2a9dd885536613d295d11bc51ac7b2005a4d299a6952a903c06235b2f97dd6c4cb364d41e43bc3b445b4a2afd81b86b222729418a62806ee42af7b877b67f9a1b17ce61f9bc907f2be311b7d74f70f300b4ad76f08480d3b6aca0b48ca68a57a3930f54f438fd046ea82fbda6c6cc76a87ae52a03f006b2b75b0b6f4a832e53d496455c3a42dfa667a8d380a72e8a451812f4964b21b1a67afc228554a8488757a01523d59048a5e4a8b1ee4ef13a45aa4c98dc39ed77642bf094d45c41e83919ef5b28eb06e99e8cf76066173d4b6cf7fe5662d18a8afe4c1c26dea11e79857135d25878abc0a02ec408a62eda2d7a6f861226c9a99b3daaefb4fa3cd07b9199609fb27c0d1af0810bb335c28dda91425542db993dffb7e127725c5002cd793f33197fb82800a076178913b54359a44cf5328e149cde8c1576b83544eaabf341deb45f394da6230e0862a1c7c6c10bdc66358771b5a144dd2db223b595f8cc32bc79225034fc05dbaec1302904c7291091ea791793e7adb41ee4b22564198445745750b274751cfa052e18f550c0b4a60645c6cc6eb748a4836e3e75153787496ff230f6b5fc9abcca6a19ca4288c1185fd1f27988a21f8d1784b0766304d2da89be3781df4b8807fd735387a4299674a0c2e6e005fb953b5ff8b1f6715fe9c71404a246f1cb0f06e96c8897f271a17556c7ba0896568590e2aa41638317bedd969febc50112bfdff8744e43475d6974bdc6118a322f69fdd07493254c9fcb47dc2cf87d89a7cbb65e2d2399dab7667174d7fb21e427b39614e2963155f18b22ebd8ae875c2dcbd8e864b903c13a8d7d9e1fbe7b46df27820759b844fd5bf47cc3a5fe53d3d48a2cb344217916ece7e6c00cb847ed9918a887c5373da3ca224341025ebc9437b903de8bd84d977493f3125774bb0fc9f6fc94e7a4af7397f97d60356babb2939032bef769694d79c291356d658ce5441a67ea118ccafba69a4c8e100d730389aacf46a6a49023bcdd9aef4aecf81a3a0b9144cbe9cf3cedf8d8b4040c3f6dae8e44a38c7acf6e0582b709f90fe38186b3d82ff56b800867b1fc4102bce2ad5ffb856725b82f08a7974f2ac14e52f75422834f1c589c6177166ac552fea5623afd8587d512973a993551454aee3e0ca01b7d9a2ddf44b0a6b563ae335946e1c485a2f149787a4c6e410586f57b1952f53c75be5d87123a0a733d3ae465651a508f172ed5a1768c1cdf1470cd7f1b61fc76c67daff94c3dd33a5de821f08b6d128fc6e72ce24821ea945366e05f0cef469c064ae33bf48912f1b03ff9ea20a5e7d0f2adfdd48d5de69812a8a921ac48f7ff90b832819e2c472c82aa584360633c32185fe92257eed0161b2f8ac8d836c7153f6a51957760b35a1d6d665b58e35a1006dcb37450e0a6bc425ddd4cdb281d5254f991c0a193ae1c1824191b8fc29133cf0f180cc62b2bfee3718f875f909792f7c51c2a228945b5413e15d5515e721576889f942c97657382c29e6bf201584929f4fbd60cb1dedebdc87952e8b516c069a701a15e0bbfed1af9517de5e85ddce3281d07dc20f2a0a65411ca6d54412d5763e3f8443e889a7aa49a831bbfc9c0e84fb1f04feec07c50031c2fe91e2fb02ce28261508e48fcd42027aa03d27da747b3de5f95f95ec1439262726c9fb27a676d70e0ecdb2472570b1e70a40f853569be95cc57bab0d7e57d7a6904c749dd7955cb55d35113aa481be3b98effc3d662f7a595dcbe57cc00cd7abb613a31829756462e2a971b99e8283556ad0469a981590da86f1e14e0c7fef61ea00ddaad8441bcd631e9f68c3ad1e420d59d24d184a3c5e0d1bc3f230a4d24fd4430a2907aebcf28322a0cd9cb368e53a3420f121362dfc4843b190fa026f56f9f006978e6913fe3afa1ee2641ecfd52cb0f1f5f1fa68517d9a4567e0958255c28787f6eb294cc01dde4a82c7c3ddd2934ebde822a2cb0c1d0343a7e4cdbc638a9345a78f9380a96af9ac1131c6d3544e4e734cd33d4e08fe77fbc32638b88b7a61359c79462b131b4a53dc3be738de25aef21dce548b2b462125d6e6e167c409bcfadb1dd3e8fd937017be40b0e2bd58312b13438d9aa92e10148bb1b496aa41d818446d48a688b4fb65947977f6fcb0d6a113a053bbb363a85da5dc6f5f91d54db2892d977f8c2c2e404ed0d403c8d607a6035e915164a5b5ef8bd462a04f24073f528649bab27510f61af5669bd98ac7a15b3d706e751f217e4f4582f9cac9e42a310c3688226076f761f5fbf102f2c9dbe30b573340401dc9edcdd2b3a9459a00021959d441cd1f59b53b2ee7bd62e8382351bbe8b5e3f95e9e282bebe9c48f34a24fe377ca46f559c754e46746ae5a2ec32367eaacf56ea9360b92b31a647542b99da86c3c8a6065c24e5f9d1cac23d41b8810bd2a2ec55f4a52ac3cbe8de1d94916d392497c31c0767828883f938c090f18db508274a4e80d206f0aba97f07f6aaa59b062bfb7c7f5f0f9d381ceb4b9e54103be29ffb4efcd43d6a076e91e7ae3bb79e2b1bc512ae0e54648327e0e3f47d347f5113aec681dfc71800d151773c3aed31c03e45d7f9a7917f144531fb726acec0fa583849fa8d7c36a39a7deb0c8c150884985f402e50b7b384555610150b7afbdda9d5a46c19e6e79ec9e14c835e9685bca997141c73f701cce9d94f4bccd5cfa7e1f25a0411ac7311b08a6e10ab633782e8fc2799debb0454b5adc5dd77ad97aabd3eff8cb373ccf8032ba461549508d74f7062aad45ac7e2012a07bc91ce41a253bfe2463de0e5ea2ef32186121aa3c65fea6c667c55304f776c621c0d99189ab5bd761deaaa021c011a6681084af1e61ffa6420b2a3ba73675505e7428138d47706aaa4b630e1fcde009daea0a84895a12bc1123826f9d69d0f3670778a0320039bc1ba93a43658d41139fd7f296b863e6a6ddf6f5ab75bfe707f1d97eea9fae733268e17e8f703400169994590c6f2da7d55b7a446c4a59e50c62dfac0670f261a87374b894b405cb3623370e0530aaae36982f31f57abf2c2f5de9f0fe8c5d2a226aba51ff0d13108b4f8c9d421ba9030d66aec6d88b0226974e219ccdf3617568483af6fb37485170b6e3977841048aa70bf493fd4a17eab2a20c7d41f4960e91a5af8d09ca7da9a34b62bf95fccb07353915d15cdbb238f53d6dc1b61b6c0ac853ce216c172183d971ebd9e90f19c7ed23efd3e642e95f8488bb55c8d4ec472bff9a8fa8accb8cc5a586990efb70f0b3445113479dd6fd517aa15e36de2204ff7c181ac898bd7129c17017d91cd8f8c57d01cb4ae8995f7043474a9e4fc1062d7f4e8d0d95cadc1a2f4f44999c02d962e8357981ced71fe64968fe72486563b6e1d070aa5f523abca9f9f99ac43fcafaa452c72684492e40ba4e8a2cb3abc21013b23508c34565318e4aada1cf6a645ae0906edf030b6b4936460942c603f5da29ca358473e7d08d0d53c1b5f059559cfae579bc3ada96ccf0fd56cb7a0b921e408d3afdecdd7cf36ea83ab805ede9c4cb1bd30ada118e2828899050829e0fa9afd306d53f0b6b42edb20014e80183d73f9f7d06c69950d436f8cb1be43a12a95a7b1abb94090d790875e92232cb213b516b36f3d9d4a7cbe67d55568fd095c70db0a52b2e0e18dff623b24735d002dad91ad0368e0f6f1b3d4fa3b2384056301a34e6406359f9d408e308c5b70a75db5f395b479ca2b001a2a5104a5f89c922cd4d4482539ddf20d589023bb0f07c70bd3405521b4a86b12036283a768defc7ec32b08a7e63c09cf4316cb6c9e242c56a207c422f4c97cbe0edbc2d3be4c7d3951567afad7bce6a7b8b1f85468f97d63e6fa833944dd5d8d31fd0c5ffe6af822ac9245432b75deeb6296058345f3a8ee36fe42aaef01edd48c541099e3182e76d1f19df1003f14eb997708dc25a42f46fa300ae10edbf73b45f748f002400f93de9fef9fe92c03b48e9e8bb41e92c868328c78eeb53e92908dd85596f04da1383a7b3e6194763d55187e3220780a7a20fd501b31e5cd32052925640135cde8219955aff51ea08c5973acba08816c681569be9120c785e0ed54b9659a071a036ea6b21ef874512193d0141863673402613c2b0ea3c6161312f0007c08161607bd97bc404ddc522b42abdc1a8af10abce2eaa93465d1ca1adaeaeb3535e269beec6977ae59c76d0dd5d5668c92444c02b1f48dc356ae6ac0c9891f597710e8940217ddda28f1d8c815af094c48194d96dec3f397a460e1358919defcbe6b6011f7e04670e96e5928a9e08d2aa04a8852c9ee8faf5dfa748b9b063d7013ed7c8c911b3d8f8da1f3a62a87b4dcb4da545ef17931d8beea0bfc86dcc99160aa56ecd047b54248b2f00ad85d38d7f693afee7fbfa2128d018f99937dce7094db93f6bf0eaafb4d736bb8cbf5b7fb84efb93150127f16a30b353a6a9c3d9273ed790d90ca5cbbea36d80555c025cfa488e25eba5ae7d5c566d8540dcad41c80be280a3def80daccb8be3958f4e144d8a52290017864e4d2fbbeadb30200f88fda044e0c7438d8fde36cc56dab54264ce91140c7cb7ca2835e28748aebdabff0f0c4ff606b69fec88aa00b5dfdc10be5c37db87e3ffe8c858207429d37d1650772c9e7acb15bdc46af3353219b0919c792334a74a3ad9fbfa646340a8961037ab4f5ad1879aedf735e6d092c6b778021529a342acf125a44047eb094a8066fc2803844994b947123c1d4548a7804a9a642a1b99636574b67531884f4068d3f3e84d795368fb21399462c01f79ed4c89f24c58755c8423fd8b821a96257874ce559d8bf92e8f00309587029872e9a0ab108f846a386c245dcd1892b5c3dfd9a86ff085478f350d12b4f9f11b0bcca23d26af3c53ffafc6120f653cc441d675ca61e6384a09a7b75b347b24409633e3bce09011330ca3e3e0a04728a926910a36e0ea91c9b7340c50e2347270ddc2a8da6b816507f0657d532678004a8fc4b13abb08d28a85596f293346d9d8a42a5a70f662fc9cb07a6703bdb242fa139c2d861a9575a8f6207a10f8eee1d6a0d832fcb39f65461e7e734be83f1795bad95d21646a99a9fc5f0bb32d672780c27fdd0bcdd9404d343a7526291ce4238dd835790efd1429da4bf874964572044e403430fa9161dba21f70f703e2f635fe0c77c846b517fd2203039cdcbbf8ad13c6f3af43af3a8c92fc144ad1b4f8bf6a71c1ce9a238d256277e93aac5a4c0521a150bbb01a873c8907479f28d820a51639650d9c6cec2d0885d7724955b670a346725a04e2fb3b33082e55c3191ed6f823abfe671ee28921d919c6a1eb5b11aa0ce8346d739ff81fdf452ae2d74dedecc6bd93c5d0b45f94d5cd1eb40b15ea3a2524197f3ebd198520ab466c97b0231fe8629a8c273399e17e7a23a7bf9b76c281555653a07f986c72bfde7636d4616592a953a79afd01f01286a30f83049e489b395903b0fec128f9f3a074d986f9a4764350f0bcd0e54c6a3cf8b29778b775fa95b50f0af0034e1ca4ed93c4d3206e7541a01c134c62291125625a940b12a8e308e2fab3962764a80735cfc823d0d08aab4728565565d1fc6a205fcdd42228492f1c3a6f17cb0f6b5f9ca0674a8c592f11fc6a98a249a52c1e8f548cc28fbb73bb6324c895f862b2565a60b31ca61cd461f52b523193e27c598477e46d043e87012314e7234649958b8d3ea9fae87ec089af840f1304e061b65736c7d8809075585dad0d3699a7904aa1a3a8cc510ef7d5331ab1aba16bbd2d94d080887f8ce7d5d42f4816d70ed637486f5d00e654ffe14d52c3081021a8cfedc416ba75d7d6b2bc7111729e2409f4a03602f510ad65b33ebea2e98a54988e063a851ae3f3c0ff43b8136206132793b4a3ae32ad5b60358ea4fd3fe03e4746a945183085c6127e3c0b7ae06fc6c0b4bda553f12c9538a0f9f0fb86925a00000393c60b2c3b410cd4532ec09b069c89a819f95ae60af26ec66cb619c502b69188ff2c7ac883445008b909a77b81f97c20e5027487020e1100223817a1ffc7ce380412c0151956c1884e72bf1dba0202a6b25e2f2ee1c876f2f0296bf6a8f790fda128c9ce581e5401caecb39b0605606d6680cb2c05b33e8069569f9150d0ec2f9defae1fd30af0dd01e4ca75f829c81d6a29080cc9667985b76bfbc799a2fb65ce1a43382a9a512bc0c4185d562977ded362468a8be1e9a3fcefaa1f6f33374fecf3ea3e4150b0dc108e5335ad6e317f426e4055dee4b0414ba9e6df0f73f270e3701fbe2031cdf2927723840115c8a08aa8f7072f303bd4bc6554edbb2cedbc12036ce2866200434117ae83a45e59526342d1ead13981147d1b91dea622ef50c8d1f378b005fc06d5ee210b61f92c6267e9cf46efc41b55d37b800f2a619c2c2bc255052399650e2a5a8b1f2818fef77d1ade04b052d45295a6b561d92455efc1981e3260cc568f25a496a164013bf83ab9ba1b17df021668be876f9b61a194cdb92a731269fff309ee834e8563d5ebcde36b8f801bc300c2c1140cbdc12fc28e978889f12dc25299acbd37b8fca11effa843e0b72cf0b0cd474e678844ac4a41aa39b4d6a0d4f43a0bc05c4034134e14ac7444bbd301677a2b10837d4e24cd467058d47aa21cfec762bdb72794a0a2bc0143b90596fb4a0ef9e67afccb35bec6c54f25aaf8d4edf6d2d1e73f3cc18eddc61cfc89ba29bcd1f5aaaaae0952e79f042a58ad68628d515d2a6ed0e9b10e5a42736b3172dad43e4659fcdffe275750c9be96506a066e6d1d839c255446991457248e3597dda864b4f00176959fc0f3a7c6f1bcc672f2b0ccd4a5ccd46ecdb3b9a63a05a85beff49e8f88e98d3890349f92207d338e1337b34472e09a0b098cb43c9c9a034882dd34d893a364f65131a07a2f5da74f592834db75a9b3066030ec30f5f28ce8bf08af571ff4c47e8af12c6196c85b0975f88a3f089143e835b7a1879ec3443460d62b2b60915b88ba0791c6475388f47c398d026d3ab1ee8dce226203e9fb13820fec0fcb9b34f82e16e60a8efc192e0c381a1417306bce978eb8d05e958931c9aa533e8d0116f32e0cbe982b0e6fff77e19ed904fd2ecede624924e8bff0545de88763d4decadb6b07dd6115e9d402b999da3ce19a66317c02215914d15bd016d5cc13e674c27a7d0e2221cbbbccb0092031b42d52749212c297ecf6c4ee983f48ec0756a318aa168b934838d3c3324a0d2498ba3206a7cf8fe2dd13a9a5c29cff5c905caa9469760c80739a75f67f28cd02299e57f46b8623484cb00cbf6859a4298e5117f1cc41a61d1943199dbdeeeef45040870d5d3aa48763433f2370b0cd2a52c4bcf9440c55f3492e2e65f3914b0b380a655cdcd48d49608c64d981a47de3933385535bff5952d9376b4287d3ead35b307663c79d71bb4c007e68fa298c080ae047064b2f636c189278a4bb97784de29675ad1d8042baa85a23f810b601dab69161cf493108bcf7f6a1f67c397db571cdd169caec777dcdda34abfabf6ea70beacb82593c7f680a58f8a09e988f845616d2a7ea2a15bb166d04c1d32ded1ddc3be2562f6c252a7e49de157a2482a4ae92715ea1461a3a0159a990fcb344c37ff81bb0998100252ed801d8b98b067d53d11801145e7a6300e104ebe01405445f37ffe7856b66ce4ca3ef3838e0d6439df1a4e86fe767fd16fdceaa0d20c74fe91f3bcbfe7078fb3cbc7a67e61b6ebc8044cbe1a72fe2f7015aa71bc464cc078b630038a555d985dd73c2ad80e4ca6bd372829564690c857f14f3671d7f4737d7ff5367ec68198a1569f563859f5c60b7443980cc1eca7e4a0419a6ac875bfc598fb890cedf31f430ceb416d344b7eb007ce3eb9c8483faa824c7313b84269850ce88471b05838889064ca57c31ac480678f38f3d94c14718995aed836bbb72986dad40dfe4a65a24f2da03fc25042a6157a95a30d815271df1a9248c74b1cddde5f6e2a8e6ba65edffe82edb4892c5790a2d1d4de854167a7c90fa12714c2f6e57e904a07904ec884081213bc56c66429fcb8f0660d4baf7a451d822a6ced5476bdbdbb61142c82664ef2df70e5c0acb0a680aa44ffa19defe76eeb3fb7cd3cc96d0e74806897e589f475bd55a0e5b49cdfda846f490ca54327d6693e964f2ccd8fc99407307fcdc79d6a51e587b2f0af583e092252c968c138aa9a43de5db8ef2713f7db7441a556b62cd1699b3c3c3e289f9c9c0cf8f063210f343b2dcb5d7dc6f246b4ddb4d1876bf1dc65dfb4c4bebbad6b49efd997ebfd2533ab47387d96e4f43ae3b636283b4414afaf6c990be5dfbec35d35fdc4d18a6530fb3e75ef1ebbe8461a4dfbfb4f697d52c69c3dcc8eb42a6c8403991647cf6299ff6d3c71de5db6efabc97beeea34f74d2177a0cc5560aa9a5b4565219625c99819f1f0dc4fc34bd01249555faa6efe354865da67b718a9e647fffb2bfa7bfda4918b65d3b8cbbb5daed8772ed3bddf4dd8f3e12d54894462f5c6bb3c3eeed33fcd27ec23052ab6297e95dabb3528652ae7b9209d7d488ec4b58dbba90e53c91e88b2dda212d405ba347b38436cbd60c3404a1826290cc913b4a3eee337cde515fe8299fe9324a285f8a9e4895862fb65264a0f0f8087991a0eb22080a1a81b5f7a2503f088a404890b5f7a2503f08364a173af71a138a0a78b225148e3bd1c87daca9924028b3e2ca7cc7a23964b1240e6d3343160d59b8b39ee4b8d039cf74ef332d1b02b283cc7d1b727517322513e9d3208c865d349443287353dcce618ca57470efbec3fbe931e442691f289b18f787931a55ca956a94777fa1bc8b13e58d5f29efde694ff94ccbce16946b32a77be7beee9c0e1947f94bc651304cc71ed65d068ed3e217ca5330eca461da9dfbabe3ba9317fa4ab8a686f49ad125cd0dce4e689433495f6c09098a693d1283a7eba2eb64b4b16449cc85424ae1b6a3bed3657cde51bed2492926ce76295f6c914cae26ae26381abfcc0cfcfc6820b6b5f7a2502c6bea80f47bbbf79a93c52e53d7e1549f8ba6eddd5fdbbbf73b0cd3e14aef7e3acc2bbdf3be9d708aceacab190f8943dba474a4fcf457ca4f18a6d387999ef23a1d05c34a3fe118327dde4b5fca9aeea55ea5772fa5ec7778377d47f7d2a7c384e3f44a385aef761f8de109f974fd1095b1d8be96acb985bc6ca150e157dc0cdfe9a8cfbb8c0fe5a42fe5a510377a7767f8620bf5c5968c2fb648251cb345e6ecc470cc98a99a583af9f991959be2ce4cc167e0e74703ac19ca40cccf9c2d76ce392de5b6a3fcf49a947bdc86537d199f69e9b8489f993bbdfbebd47da615aeae1637660ec498e832f37c8fe862f366a79d38b4f1a7a35e8ee8d29fa7400c65202dba0615dcd3bd7337dd3ee52a1db61da58461a5a7749d0cda60eb64f8e55d0686a5600fc350f009cbe86497b1291ddcb7bf381c67865fa6973009d7d4dcd7885ee39d7bcde8db4bd36efbbad0c813dd98fb0394f568c86b8484db970fa515794e94cf3fe5d38ef2653f7ddb475fe9a42f65ea2ef26228555b285f6c9dbed81a7db165127db1d5c5cc16a984c7496318895df49d8c19dcf0ae061257240e3102c547d9f203b78a2bb3f10f6cc59597178016ae7c877e48d5f3105ba45b207ddaa7407888ad9a1aeddb6bb297de3855b18bf498ede767ccb46444bf9f8f3ab4dbbf2c86e9347e6537615809cb88601b96d191317dbbf6995608e6a923633ae9abd922c2291da56f4ff545b7f6a2dbcf6f2f7dbbd9e7bbd297ea974ebae84be9289df454e35709c716e9a2df7b114e354eed4891020f4ee06447e9262ca3f312bd84613a2f7bd161dab7ef109d034a20e1890b68685a220ccb6e2c7d243cfa745ca2675f4ad3b62f25c23535a1d774afd9aebdc67b0df71afbecb1b5512153356f3fee9345640ecd4d6cd9d8ca7e4cd5fca4204933b33922ba947cb8a23126ad953597559248b0649784e879a29914095aafb821cbdec8228d43959c9a9996906575958078c3ccf017a03daedce0862c1edd129b7559837af2451799c562b1589946a94a5c913ff97451e5345d4e1f0e47e8014fab93dee9935538a20a39ad6e7a13264f70c3049ed6e91fac04318b214a5a76dac027a8a5332f714a0753e9a6cf64d267f2fd4c1e7d268b3e93439fc9de6772f799cc7d266f9fc9f63359fb4cce3e93eb676025c88410d43abd0434c2a0a48582f279b1c13b1285bc8edbec923caf61f19dbea6b1a2a06058095a51a54b5d81e8ec0c51d5f79ec3b3c4a851176eec398305573ec7c7160c4fcc22c9933c9fa387667122cf4320bac4aca5663847573c4fb36f2f8e9117aeec9f79d3459530fee40cdbd0d4e8a4224a33d1a45f77c9bd7bd7494f7bd7c54945b4a3d402cf3ad194807dbdf172afe86691cda2edf6bbdb760f257a2612fde2f08a3ec2212a775ff82cbf98c3d71cb877b7a11ba125fab65f9fbd5a955dc3ae2de85a8c03bf3498612737ac91b3d7a89fcc3294837db5e1fd667827d477950f9c1bee8752da2c6fb3c84c4a8baff59e33cfc69ca2077308e62035d71f2f097349ccfdb03f06c495c9720016b0c1d9ad7883767b613030080c0b813568823c4f6337bc12e8e6d44bbbbdc5b058869686532e6d66a69544fbe254e510cab2932909d3030d59b68087c7933c234b18b178354b2a521b53ce796f63db51074dc3b012b4aad0c5709e74b13b635629cd689665d9a946c4cd88c0a17999aa3ee5d9999167a785fc08d260cd3020ec3c519329f6a6c5d120fd15375ce5db60f78c46c5aee675b16b25907a5601c306701557faddb11a675927c4aca43102945393b29364c9901b213e3f82c0accacab31764d5b07142d59a932787489aec5dcfc62c91d56ca12d1db4b59a2a6a69dcd16c6896987b88c151e4c5460e14ea07c1d5aa8bce15f3c1751dd73dc41479b19143ce6957d765a74a4619623e9a25b4425e2e986649913435437a88e9e1e57ac1bc62ae18ce1671b55a1d86c68ae58ae1e1a3c60b1874151b66a3507395a3596068ac58ae181e3e6abc445a83c62a7a34583456ab154d0b2abda71936d21ce3ca6b344b7871a81c7c71bd7ab061754f36a8fcde19570554a974028971a3125dfaa5db565cd7719dc3c5b259d1a811dba28cb83d344b687bd878c111f323082c87cb7a396c34d8e2613b4fd6060e1b2f3796090f2bba34901cf25324c80f2137384790c07a2889e1e1831557807e04f9010403e2e142175552dd16635d276d78c4f49034f2864804830fa0dcffd16d9ccc71bd9aa55fc0d249906149eece85b4d08dfad260a31a943e70ef1e72f7ded13a49f5fdd436a359c2f853eb411aed57346a744bf40250184836aec6f0a033e28a6cd06bf0d9edd7e125bc73ef66e806d71cf57c34d87fbd77ed5ea4d5d60d5f1be98ec6c566511207896788376cd886384f6933959ecbf203bd3c4d9d81d7f2b8c71c230bf7d07eebece779d693527ad6fbe6799e77ee0b676c0dddf02c8b7cb8bdf33e9abbedd3b66bdb69839a77db2cdbfb1e0e376c716c508b59d34e3ba44376972be64d8cdb03c73498fd93c2ed87f127025523ba1fe2533bc46bef3c731ce5c4167ba459ea61eaadbd17853aaa491399a4c12a711aacb7b3451e69547d9548ecb5a87b14f81588caac1ca27245e57aed8b1905ae583c3eb9c678882d98a9aa625ca9a4c1fa0ccb9d06eb27852ba7ac4d38ddc88356e220f105e20df3d3621c110a793ee4f2f4a1691c71a50c37bcf9d6e89621ded2eebdf7765d4a323379a770c3e8130407bda49138b4bc41d2c8badddd6dfae28692c607874facf206f99b53cd4906f2071d0653b001142d450a72761a5996652846e415dc20d3537a148b434343938216b5414f2fcd810e4c34410c5d48c10bc400a345a3c8947699524a293d856e509397b36cc615395469400e6da091c525648f61b42267437c51051429a8428f0a8030040539fb8a358427677f3122673d446021672f856e64b11e1c81232160082264fa1bba416f2290f4a8c8e189460e67e44c256736e42c873472868224c09cdda2a0276747d9e4ec6f96cca6670814e4ec2356a6032a9a082253c0135114ba9145a146a60f152144cf8c9cdd339249968e4e11c418999e531142103b310959258a205240809cdd460186abc5584d105a90f5d414c139ab91b32ccbb2b39aa53ebac45c4f2917997edacc467616bdb3e50718b2e8c1177e983831452b83226755d080660753f8020c9d24b4b22539ab020956e4ec349a45cb599665d96807379663de71b133bc78b4f79e5033ac56356dc990aa0448f361013da19e68925920b23062064dd505828b18f445391114041a9bae77b64414bc40664dd3b4d3207c11842733d35059eb398112596341ab5efba34bcc5a56c49156c53c8125485a1573682f0a8922f754837278df1141bd44aa3dab59560f20834bca91878b2105f0220603d0c2f572e4e12227c9ed72e4e12249017eae8c1c79b8904245836b73e4e1a209aa2cae28471e2ea4001ee16639f270d185ca095c7ca1251f01345531d397f6420a99e6d873040ec5e962086eec0102498e3d401891b721c71e1300753c59a2c0f86329cd33356dfd992ad9627dfac90a77d0a499a40b00f1939f34283f693a30834c1f76900ea52a903a48faf8045dc004364b08a50f95ed65593f6995fcfc3a2805d75adad59fd962ab882af92b9c3801284b2a04fdcc96d8720214647de28a9ca1226d00c1556356835658a10609e5809a856679ee8ba0661965f90ea743d22df2c80f67827086d70a2f69b4a60f92d84e93243f4e0421cb276450b384bd24cb870d463d92e5659d42969776489697960a4b45db6021b5f0e9427ee15333443eb1ca611fe138eb0364e346e39721cd626f6c911b7b636fec8dbdb145ec8dcdb13b56490ee993e5b9d08dc638ea14341acda6fefc6ca11b5d8f344bcda93b35a7e6d49c9cd9125b3b4a787c6aac8769433726860123ba00e0e7a626cf7469b2836c6caa1a871588c70d9ed9626353257fdb07757d5041d9e736e1b13e1ccd7dae3f3eb21e4e9ef8110426a483105d3c10ad903d309338c2c429ba45a6817e92a6c11a9a2136f2ed4474f1403d9039c693ec236e91a9cf159ee4e863852d72687d7cb6f8c9d6a759a2cf15ac681612901b7d8c009467c8910a3168b20c51a04f9329f6000dede08189533be489c31c62f6c147dc22630fc42d1a89db3c3434b9af10db014dde22d74f1291370dde1829522409ce9128c0901b89f5c9c9d9d949d248942cf16162254f83f230e878bea027490c1189e14e2a633c2af5f80331e4e9cdeed460ac8127db49170d368bc4a913d56205c6624e6c036e0f4d1557b493a8ea8709c832f718bd85c9823c51d060c8bd0a23f7971869b01f672a82368c1134ca7d181905d0184e40d9438382ecc51772a53396819a259c4672374b7711841c71c88a0fc137d8a780912e3418b97b8cdcd12587987f40c5157a525c918fb345c3332da94d19144a1c197b8a6e1cc24dbdb6db6f384efba55ef6da2dd6709099e7e35313ebe85686230eedad8844c99e55d65a7b061157625a637615bb553a5bc64e947a79adec342f917934935996c52aaa2a204a7e5bc7d1d99ce4a2260a81c82f9c91e3b3500e5e68c38d2cdbb8f285b44a9c5c6bf5116333c680c46b73688e0be53033e56e846883f15d77e3dab822bfd0bb9103cd368a3a11271289449b4824125991481365a24a4553d42229baa1b6654207e4071d6e9e77d103c921e6781e628b5ef2f85e1f8c18b7c7c3f80324440b1720413daae2251039595681849decb595fdf0ad842c71b89a715483a89924c6a03b73fc0cdda89a0dba33b4430fc9d95f6237118c394630d59d7b97b7cf005914c5851bc626303dccb709721afc4f13458a18094216326d5ae9875570c3991cbb71634ce9aa473a6822884c7118794ec793a2c65092572231dce77005529ce77972b4aa51524ca49208273b59d2c7fd7a5493dddaa4cf5e633f7ae314c52e92f6793fd39ad9b5bf320dc3742e86d98f0edb9e5d510e8943db68cfaea3bde257f6118689bceedc76ab3d7b66394fdbba5006d469419f3c49e10923908c138acd913ba3fbd347bafd52dda62fd5da97ea6c33b99ab89ac8202020a01e69f1ea2d5a8cdb0f59150810d00fb3abcdbad61ad2b9571d2ac35dfb0764ee7b9cd231bafd0eeeda65745edab9cbd88f2ea3f3e2aee154cb8c6e71aa239008e20f21d16566ae08398434811c01a55ca6d2f6d7e8dbeb372ed53cc4d6a8d5de0f201a6e0cd6de8b42fd2048234392439b5d9f382f456688916232625e4cdadc948e3a9df4a13ce513ddfb42efbe7bee1b75cacb6c9145705c1966ad563a622cc678d0e18a2b73ce3963766b310f40329c6aaef4d36b4c4739c5a9c62e6edbba14ae54ea300ce5a6c34e2f95bafba5fa5d37a58d597d712a7b37c2a90c7bdfb68bbe947d77d1435f4a4777d15316efe82e4aedf01ebaf7d04cce707fb40c10a098a67c3af528dd63cb7b6c99be542d7da98a5d35f735a353981e427e4423576c47644457935db6b86e12ebdee91bef26f49d6cdf7491c6e99c50ece726d6a46f6c6868fa2674d15fba6f668ba88814e130fe28d13e9acf4b17d1377dd32de822fa265e30ff00a4def8a1e254db7881f911a45b9a8633591c25695347afe17eba992dd2364e1ee10d631a2c5bd97723d8ef5354f58c1b0dbbb6bee924ba88d73c681cb412d987fb4b7bf387c3b099968c4d9574d2431a049aaf466822cd32b3226da459ea90fbc596bc29822377244f8e92fbc956119c9c1d253cd927fbaa0d5da4735a49fb344eef74ac6fa66aaebc99ac4b4328994699151de5d34a1fe9a65166b78cc7498c931f4052020102fac1b4b5e8f735da4975db4aa34fd1b7bf441bd660573412e1687d709234362938397207f5d99f3eed29a3934a753b95eeddecb9d7681fdd6ddb4efabc3d75ff6a3761d8e81a9631c9a4bc64b5cba0dc3ebc2b199d17eaf73232ce7df4c9a07e9ff2c1745e28144ee9189d7baabffdde6ff81e86721998fb08cbe8bc4cdf2e83f2d139946f9fe9a3efd6c3d88f0ea37dbbbd8ed1ada69d3e9dfa6ef4d2b7d2a8f4eda4a75edb49df768c4678c7f6d14730edf7b1451a7da5ed2361ea1a5121d2a6484e698676e7822eaa507ab984d2f7982d324e23bd07572cd4c75dc6d73de543f9fd4cb75faa6ea72f551f4a652f7d4b94528a83524a51534529a594d24829a5946625d26b45a174ef122551fa55a9547abfd47587a19ca3b4eb3eee4b357e7ffb4c4bd3629a45667a1e37d248b7a4f8a08f4fa296b58bde94cefd553a87613a5dc2a97afcb2ef308c746b755cf7289f8c8ecc09a7babbe99321754f55d2b9a75ea47327e1780ea72ae621b62eaee941efd18be8b72e34a254f260a193fd05bd7c119a3c67509e4ea69db13c451867f4893e7724d752c293a74f9e9e2c325b66d054cdd9c4499e4524cedca1b8831a6806379c3bdbbc22a88a08d4134e27363c441e160fe6cedc993d789e3ca078eecc9daec1bd84b7c84ee835dc453b9ab5386c9a5463978753edfdb5ddc31b27c21268aa66ccf327679b2d5e1325b365eecc6edaed93adb933adbd77a7795a49fb28992df701dbc3f6699eed8bad0edd706defe6ce74622a993ff38a3c67153dd349c7162d21ea20a01db225c2b09956037dd3e666e27411ee9c4c9a25ec2e0228dfe91b9df4d7e824f0de843f55364e95bc992d323af332a48f2e53fabd7d0da574903efa8bf4d1c4afd22fbe53652f7bfec754d1897f78915e3a0fb1d50316838148b8f4b9a68a9ef48d7e1fc6d8c453c695b8321fa76af4f5177a5c0e1b4702149863e4d0b756a29d3ec66791a9768d6aef6f9f0f2dea6f13e1d40ea2cbe720c2b1c14dbe747fa16f5fe8338481b293af8b741291652ad14a9c14913c3eb14ce9c4892bf41d96390dd27358e2b492cdbbb36b1a4c20bbbbbbbbbbbbbbbbbb5b7677db8bea6f49109bab17128936d971b6a6e6f6a5e67cd7ddc3b0d0bbc33ce9356d7920b0d57bf7852ee2ecf62d13e14f76dc66cb4099306bad5ad4773f0d6e91ab3671e85e8e07d4a9cce0662fd246fa488ce6c5f5b1cae10766c255eede5de6ccda7de2d05ed4bb87e04d7409e52ac5edbcc3f4a13bfbf61cb2778dc3794e6a9f30dfbcac974344962e2282f5b58b7c98d9625bf5ffc47d1357ea43f76e441209e170fbdcae3d9cf7f09d1f6afbdceec3fca9c13aab7d2825f76aad943951552f71c87da806ebbb5a67d7dd13964570779106ebb57ac366a23613b9be999038f4ebb970c32ec2a2d22c757ece39a7176b6863c53ef44e280a1ac11f4184fc90427e48ef2fed7a892ef337c796ee947b188f9029f707704b8cce7d36b6157af7d508c16a856e635ba38732485ba0f7d116987d555f57347c61dc9adac18633d9e2983f32dcdac9195b52d1129ee8a1bf44384e5508a7ec438fadd7a74afb08a76ce83b460f61191d9911aeb161b5ba0b615bdc778444b8665e08dbea1e5b1e76bd7c39aae85b3542dc568c090863121610862203c25845a6bfb305e647e2e6a1b75fa4d69334190aee0bee15fd35bae8f222d14f18069b91f2a5d24f1806bb33a4df4b895ff7270c83cdd819aead10dd4dd3f8c1c34402cd1a1bdc340dd2110eae8ca3340b77da9d5e2a992d293ccdc2a45942a740d1a5e485c8f2d2a01514658a61d1448b08441095f2c596e94727c5ad398c403274e3be93e2663f82d450c4ed3cc369787dd83499c62f9a88c211b01006115f006ad1d3f0499b4f0060dc27cd92d96878862f5632dc50dad8d4e98cd3194e25ce8c2fa5fda92fa5e11f5ea9cf380fb13503c32e4e3db66678f8149ef1451a3ec3e50c34c8af741a3e199fe1433d86487fe9b8a21df5c9f8a44dabe869fb1c9146a8cffd2493d0279334d8207d0acae8933c9fb459c2f45367c212d0b27c04a81722486f634ec99ccc268925d08659ab06c15879f566d4dd4d273fa7cc892bf311cb9d06230f8e1fd927cbf679992371f0e28a892d8748225922f9b6772a49dcbef797e80244e6eef3f9cbd9261a8d46229168f4eddaa7e592c9f4fb1da5d26fe932285f4afef4d8227d2989533a4847f98efb139639fd1e05cbe8bc4ef85e86f4d8eab24fcbda2512890359d3aaf921448ca08efcf8ec072b7d2fae982fb644210dcb1c9b371ddc0a06d7b605940830b8f9b1a146534a299594de076aada596524a297e5981ac06a72b8c44c861244296407f3ed62c210ba6074ae99663cf12262cb511e7ce6740e858a64db46850cb6d93a495f4cee5473b3f3932269bcc16dba26f9be8a265fa1e22b2c03448b7e89698a9a27247f2cc16ee07faa2696a32c5400fc9b49443885e8a6bf397d2d1ede84ec23542bca5935d473bf7fbd40eeef7dc2fae21fdbef4e9a476e8db374ee9307bc2589283344e499be812caf47208a594def9d5a01bf64e2b992da553d3e99ba777327d67fa52db675aa52fb5e11f5ea59bce436c99300cc433ad9055c23a1d82a6aff4d100c38d2daed59deb1b7a243649a64b32bdc1992dd6de4b7f3fd27782d11830cdd243440cf490fb23b5904d1aa4177d92678786505bb48a9e760dcd939f2f32a5b28b4cfbd3b2b599f4c556e672b0b971dbc4151ddc8a5d158cdb8f65ddc5baa8427ff821c8cdf24066196872109bb3937e1fca941ea477c1348823bad8d3eb105950f4acc8928a200522c7a0adfb81c082e0e689551ae4bed1bd4f14fa40d64f4d5cee5c7d78999abfd3fb8bbbf7790fc374267e79bf1816a7273bcf4fcb327423a523f4d15f211ca76a845f9faaec33845753458f23aed07bdfa78abefb5834a54304b79eabe1a6f1a776bdc110c4f0931590e310ba004556a7bc46e965f6507ec391f6a53c8739eece7338dc3ecbc50064798e468a71acb8707978f4f07129b970c3f81379785cba1379e4b51c7ba0c8228777053702653f6861cd29d2826cf1405bf52f1d2324bac8cf8b20f6704d5304371408892b93155d4279561c2382084ed7d67329ae5fccb985161db1d08105686a9db3d67a591bcc76b3a19da15b35cb74e9af441c62bc2114b78883a4efc6e100b27c78036a0000c061cdf2214aeeb8d26f2d6e189b8820e24043ded0ef5f20b6b060a20b6509c30b510b395221776c61916608bfdc8f724e29e7074a1c06106f90af3400904359664ef89899899cac3bf372f6f8653bcc07913ae8e2bbb3ac3d309bc956cd128a38ac5bc5f2f7e44597ea925db6962d146e189b6020ba3421cbb3a6aa87980b441c5e30d1a5de47f2842c1044e6791f335319ca81c6184331c31ffdece7810dc6b366cbed97c4a1c61be2258f96e3c3d8042666d0c5568d7c8c57e9d67b6096090b2cbfb3de5213216ffb96e60909db431ac9939ab860e931a3138a438778c3fcc42c23b05e592fb86174d2835a7befa39356d95a71443de8bad8639ece5833ed2079c64fd3deefb2ac434a2badd92773d5c1cbd9bbfe428d6adaa95671d75f988591ce9a793674233e76ee7e16c3997bebf8b067e7b066cba4b392529a6913d3ec21a594ee44eb7516636a06a81c1f67a593d619638b26a594dad43cdb2c61bc8c93ce39e7ec8e0b5aa0546a418a49062d68215a21597e5a1a032dcc89238ef25352e9a493bdd560c5799b25c6497134d88f361a6c1afd15adda0fae0d2058b38cc2e0aa3cd3ea0ceaa4d32c3dddebd9d922a3aa3e461a7d5e5ec6b85e965846907a1bb789626b53cc0210714111d900446e28c71e17d428e17239f6204186fc9ba172d68344177296654560308a9ba98aa018ee28c71e247e4023dc9b630f1231247cae82044e0ebfaa2790544a2ae795d3e6d974d22a86541837a4d9569b9d5a39a2b2fa7431c618230ebf1c278d94ce397bce49bb637777ce6194360a3244dd21ae7cc7d67ec0dcb4717ee243b905503f8632a8e7082472d8345dd3437213c91da3a1a109a29b8432890872b408430c2ab0410f6243c8a1f4d9410e654c62d1319913ebe8a40540c8a28e4f72d7cc9c808830960862084bc08101931cca224608914389238fe48eabd9e24310648083253b4fb65085560b213721db196b42104f8c410b1e317e5a3d45ee5f9cece54682152a4600c1003f99126122532264c8f43674838239461c0c90b96ba11b5c4619b182fce5ed59e8c6c6534365468352e786a8972b9ab42afeb42a66ea04045a5d11c4a26955cc4ab069d56c41a1622d6092eded9b25a4ff28fd8cdb90e2db9843546e154185ac69a7a59f9c653c4520e9236ed8b19f1690868606081e1a1a3b5bfae7e7a68b4c234f27a42e58790576e1ca10e544e264c9495114f6ca1863dd682127e0450d4ce0042a827002103d4e94411453f8a6894c4f8375a2072567286591e98d0d5880844c8f0adda07726891b90a10c487821451450340f144540913296b08230327d4a8480154f38a2022504f2618cc1586b2d8ceb158b7fb960228d1a8df1f33dc4263e31c618e3a682ac09b3091fa8481423dcb630ae9cc748f923251631461a638cf81469157725c4adb13d7b26d1c959653fac92892b1fb1684a29a594524a69a59452dab19e2554fc4049cc162bd151634716d4fd4e344b89c32c561da02eaaa88c9260439e3f9805716b27133058b58cb3e7258e9f0ae8c5157a0a647f5149bce8327f85ae4f01f0b933f245e9e0cab7066ed7168951d4663c7d7170e5e365164839f6576badb931ea92727833496679f9cc8594e76d6c91a48c73e5a3ca6c25745165e200274f7ff28bbbcad6de3b43301603820f9cb83b477cea1463c874708489c9cf33450bace8eea69466b5577727c623d6c3478cbe6009cd6685c4b559ce9d314615f4102aa707c6cda1bd3f3589631aeca15dbb0f7d1e0dcec693ca39e59453ce4b1cf6889973db68f3e83135ec9a314d9afcc4f468c2c34793263051a820df0cd44595f06e3d37dec881916e8903144f1cb9993f11078e1c4bf29c3c730a2249b6b879d6501a2bf21444bac8da125411f2c431ada5d1e012f6abd962f1276d7b848a1f1b6a4829aba4524ada5236c1d3b35b543ac618e3a3c4df887059f3190d54661744e4f4e2662339311be4a9a494524a29b5d6524b29a594ca15488f70795e6ce0c841a9b53725c79e2558b841ac0875b670349e4e94c3a756d5c7305cfad076f40341672b23cfa3c41b503d327dd5e8274a5c49a963a044707e86700399be5a8066fb6dc3a7b8321fa2783ee4792e8227587e11661553d639e794724e29a7aca11b92ce1ccdd2b3e79c731291854b26aba856c898f4913e32267d60af4019963e71a51e003cb8dbedb577f64bedc09c2af53a890a52b841196a603ae11236b265bfa38629705a4038a086a755821aa6c069592c839aaa6aa7aad630058e9d42078253e5801a9e96c51f0d2f50997d5631a2a422d8cf6c1ad44595b0d264da302b1aa48ff93448e792e812338d5d6be9ec209a0eea201a1e164b071949b89904b61dce9b36d3264ecec4f521d833dbac26b38c7e4183324c812850a6ef9d69edbdf3872aa1c8d4c79b3eddf4e927dd12c21d9b35dd90da759ef499dc073355f4351c71a1d8bcf8dae17ed238b62a9c357348a6dd1de4136b42df1d343b1ac213e7389c4428928963278e3671b28933a5c8f491dad4bad32db932ff40e9251d22aae88bc834894b95c8f41587a84c73ba90e589a94d5ca19f5c1177d263267786120a9c4c3f71664b131155f447e4c4c0064ada2674a3876472c68c8a26964bdac6da7b51a89634422a8de905b4b9276eaf4212e85ca3cf3d71b5980b26ba94327d0f99e6ba7c0d5fdc17fbe1c81eb7e87dc3dd8e6e7b5703127706ad794c00bd10b6c686d5daf01755f442d8d60d2b35e4edadc4a79095b8c6d6c5c5f71e0d43bd6733e4a641b06d6e6ca88fe842730fd17ac81c92da214b452a71673645245132809be8c283835c95c835895cdb87c329b9e18dc3323aafd0b9cb78dfbe830b9df3bc875216bf369cb2dfb8879e7a710f9debcec9fa1a90b832f4e1a896082f727df7b54d6f32c8620964a3c4460229b119722381b61c1b4cd5b7cd270c44a14cf631f10a64693736077da4bb69cfee96565861450e591a62d20994859f5a4317eeaa4392c644972fd3f7882e2497d9b6e3fadb2605e9690d5f5c170ee2dae7a05fb1bacf292ffa4ccb1b8930ec7e34d36a199dd7fde832a48b2e733fa29d6374993f19882afa3801c0832b3ae9323342291da48bbee37ea44374d277884ec2309d1dd20a3be0e2062fa0a16991f09daa968e9c4662cb0be11da593b08c8e8ce8252c33ba5f6c75a21cd1a553de67b28747df2a4774e94c65e69eb85a5c999d3d9c23aed05beef3eea98b9b61f0ab22973ff50b72460e929d9c06737696d41c6a9454a0c9a1a4024dd67a882e33d3675996512a8f9044642a83c840f33386259206692c94e1304621d37758823c710f394d7bd29eb427fd86855bf151e04fd735721a046bf491adfa4e466a73844597104e7419407499b9be91ecc0a20bcd0258c2cd00b073654ed114c52eeedeeb87705fe37c9d33557513e3f60d8e146e289db48d932adae64b7243e9244ea18323b9737de7c4313861840b4b2801c517805a7d443a914e52605c0d770e1ec2adb48b066be3cc961cefa1eff01ec232ddb94e86bb875316df06e736c5d5b004c2d24983f5b80877c2d480c455d5fa6ef694dd54442986c595fa9211892ab5b6760521503124f4840655e8a20a08be0630dc50f2f0742f3ca28b448991690c43a6d18b4c1faf90e9398d4a9ed992b2b4ebcedd5afce2be61d8760ea7ec630bc6bdc3298b6d8b6e53dc8aa5120de322dc50eeb4f66672b51c2fb9d76aaa68c6e4d21c99dc28a5ec2ad2308fb8428f852b314824d2189dc2912194083231b129c1e0081f538e3d4b96a084114422a571efbdac958bd2d31a4b9ac8deb54a744055634224887e712bada75bf670db28addfb66b1bddb62daae86128add46a543bd55e1aa477f9c034cb8b521bcd224fa190020d6f96415759d1a55b624b8cac0b4417fa18558dbae25611df80d8e29aaa992cfbae596bad36f6d859638d353eca1669f871657ef20702ab42f0f9810abaa88223bacc56b7b8af1475b839f440a6b2d5511129ae4452a68d6f5cb93adc4c7f587b5936bae5029dbcaa32ca31267b8e115d648e4d5c54c84c0306c61583b9f75e18d72be67ac1b85e30ac55ccd535ba67ffd8c8227ee479d8c82e71ccd7a3c196f23c7ac4f9f81ecd127177ecd851bb7da77d3d627834d83c9a45daf77b584dc6f0e8d119c681590df6bf9706adb0c28a1cdd3de2974c91c3db3fb8a1cd194d271f35d20580501271ac001d820c60a045567d2ceadd034518446826788191eeeeeeeea63dbb9b3261c2c4a7079f263e384a39f62c319243544f7592592a8c484204303ca9f72ddd979d861abac171b53ed380c9cebd725cf6ec3e7030cdc2d5d75aeb39bc7d309febd560cd7e3badeb05f39cadb8706bbc6aed898248ceea911bdaf823457df7f282ef6db63be77d355a555970fbe14aae7498fdfe61766d2c2348bfaa24c8fd4af30441e719a748fb4bd355c7d16870fb3e55f516b5c44b532f6eb8ca3514325373ca6ccaf53d82748ba8de064eaebd53a35922cf929c5cebcf92277218bb90118b5c3fe9aa59263dcdec8c08223c8944c8f133a24bccf2973474a3b69438e8434dd3341ccda2e16e1c0dea109365966326571b3824061b6c9ea661a359ba098d1e2880624ddc7e54e95ad34515ce4991b8420fd420ed2f32d56692a964ee34487170399ce812caa3df67f473e77ead440060dc89a495a4e44b13091039464ae2cb934a1876b19d2aedb0119e69350e9be7c6fb911d7d8461a393704ccd9e58f2ccb42c0ebdfd3b676862dbc9eef9d9fbd15ff7a36b3a0a86dd9b1ae5a37b6bdff7afd1efe8250c5b8d7034dda27c2f5dfa8bf41289849a2aad278cf4128e5355fae88dbae0fb46dbb8e38a761957343b5517a859681660ec9b21779374644b2b99aaedfd2e64e38624301f7ae82fed63d5d1c073650ed10fc19138589c9e1e239de6cd39499ff6d117e7d612ef207d8465644aa35f1c5bb195ea1da4df7b1930dbefb8279d84654cf8e2b7ec6db9433bb774424316985802354849a49209e5f6d36442e9e429e5744af9c5d7963eba45f9bd2d7df457e9238cf28b47275de6a67c32a593a8a4ac1775414c95a2190120002000c314002020100c870362f18040226b931f14000d83aa4e6e4c1ac9d32888614e216308318400000001181111d2b40920ba942a8cbde81c14c3fdea0a82824b6abf724bd5fff5abba7e36cd081f42841a3e8d589954911c46deff43d4a417d352a5d0bf67278edc51fbabef31ae69679b2f1dd7c53718eb4ee3afb8976666a8e4a974971f14e7bfdf38fbde0ca8c6dc55ec5d42fa48ad8d2ecca73c5f6996e2f723d936103f66e275c9145969712f4612c0b4531b223d07758f54d2fe9d5b254d19c99c68c975561f8a97eb15c2e93bec2a5bbd2d9fac9874f4cbf027ae16f95b9dc32c4f565a0d2dde3ea347a88ea53a6e693af227ab8074de3b2db55046dc750c71d88229e79b6ba4ccb7bf918896d0459cd1e659e21344a9c2c948c1f580b88168fd34359736516b624f824f43d4cbceaa5157c429c9d4203232548654acd9f60cf4d5077d4f4e1249fd985da0b1dca5d7b1915f5fb94fc274ae5616a5b25e6d5170303271e1b05d68bf326a82f8d260bbf471cbaf7a35e9025707ca0043f5fb7ab67a840b8b3263ecc7a7ddcd4ca2c30387d8b46b73f237b8df39c7a7e7683cff2cbcbb2193eee4b46756a84d1c2b465119c01182ea14d3cd3412a64fa67c286e7f82c3ef05221cea799a616fb80a57c5270400df974dea340696b8046bfadbb678cce68e7c8d00faa8552057e02b5fb713560ae861610cf83d2e4e6bf81943810214c7fd0402c44a772326ea421f35d8bb1800341d473566097ecf7143f5b041522aba2f3f8bca1d41f35ad19a653f799877d78ea3a01b13047cb28f6a8a34ecaed45ef33d6bf160c45298e1c6ce52a533d086fe5afa71844882ac39f71a41367c99d302a77f10f59b4bd36df93aa7b2d1552dbc1232add751559116803536225b4b0a121dba218946e5136d0e835a344bf0ba5a7ce6e16d03068bdb3a852a69785b99a7949d32f24b00937601115dbf53e1e5f7a7287eae0f4532a0d76323d926d91bfc7010afc08de1a571209d26f999481337e3352418b104402042636689f359abcf1d93235f48d5872853dc3f7f3ad2bd331c7cdc15c9d26996c706b6d20785c8e81f1f91cf58df09529a6e46d78a0955eed735b51fd8ddbb65e6aae25de354b86647473697135a38ab943b7235353d654ecb64608e63cb11a83e88a9c62b920735e21b7831b5c2f39f289cfded3b3d641d8e781679335c8a9079e768c77461e814e3e0021cc9f25738c7225091cf68dcb2006da4adb010fc4f8c0546d0e76c93b1b3224ecc30c4ff942c4781139cc82ff2293312b3bf47f2aefc7eae52618ec3c09fc1d3df7203bc0c850d1039b68cbddcea7fb8c622d6b9d9c07aab8a1e94e21dbda163626c5317278f0f06ca4ba80220e22ca74839e36d422158da641399e40921df24305e7e82ed435c376bb999e24e1260d285b6a889a0d7228a209187a20001d53b9d38256b37eb7b20a24fc8d251f69ccb4dcf071ea9432bf5f31467bf588e446c442d0a3fcac9456c150de2f062ac465c443a4b26f569e763cc131502652ff50963634a3b7297ed7edca438a27f163d318a37d428c664bf4e2f501236ec7c18c1d4c97aae59be2c689146c1d4d0d90e5552f8216bc9e2b6de2c813ad9c1b7fc487a7c1bc86c4d279e2870207f616f06022e5fd97eca0a0f0c05f5271b51f3d21e15cfb147bb692a72ed7acd5988deeda8b571b821aa63329dc7676b69b753e1e288a4263bd9221bbd1271b345f8a62c23ca5c946d31b0ac65ee7c057af86d8e3ae749202f030baa6ca2cb060cebcdb88593f0733d995bed518ad7b36225a57ae709c23847026329eceed3d0a0b680e29db470a3ac7ce5b80c0d368bc1a3993d949e9a83e1a4319b740b02e58ad6a0820ab7a017adb3d06d00c8ba74dc4ea33e52ebd244af9152de63303c1e2b38e0b66d317bf611b9fb039518c189f8db5f6a5502e2c9210746fba55065f4631a725041fed2511b0da29ec8373c15a5efa4bb7eba86802f5d5a1dc854bae79daf08254c837fc2b36db3ebe78d09d7950dfbe9a5405010ea4de4aa0807a1340e88284e10cb8d90a2f13935479c3f43df595b3440f2889b7f35d87b3356e3b162afe6b4927ec0ebe42392ec9fb999b4fcc2588912d430e4558d174f54bb361c4ff8ef4b163ec0e790f9dff1ed7c29cf8bc9e64f572ff7dd22eca03f609bab34fe18a4762c25593cd178674ea7b502874384956254f085b83fb3e2d7f7e318f08a01cf8b8c49f495ee913b6101418c659b00c640104ede37e2a3a4024733529d721d4003b5e5b786c29a7388450b3a641ac258ad9091b9bb5cff234c89b72c886b043c21cbddb5c6102d24264426ba7fbe73faf96e1dd2e69c50fcb430792c64a0e3ff061b0439e4c8a88794aaf6d299ee70f8fb3a79c779936d6fafa153a11be724991b0069a8fa52ecf46709a6c4435665917ec884383125606c7775c21a035430de4293ac57cbbda062ccfc23f546c2be6049383bd3f83964a411475d24fbd8c9e43a6712183b120f5009fb080eba7d0b0aa3ac2149a8229f3091a94a820c14219ed5f5914b32bf934fb7ac5f128218b94c128b2b691350239d536e907b74ac039f3f2e69dc721927668118607c1b68fc0ab47f85e79026b2ce30f14c29834ec3f14ce5fbe05d0f1e4e60c1d9a1ee42a79c41d659f2f24b0e1f82edfd56bbe680cacf94694a1760c3144333d55bc7f4d9529d5f8489e2350ef480b787f865293c5152fd9ef71c432a358a0829676949b0fbacc62b9b36f623f03ddffb1e3e91531ec8c128d54407a1e2b82880c465afa49d2fbf0fdf099a8b6807bb2f881ee22caa658f6ac1f1616f133d5ca35d2193abb8d4baac97bd1c4cfc3128866f8eafb35ca1ee82f2b005b8575bea9f27ec427885d50214f1fe6277d71b09b07130556a2cabf00ed30c9c20d0dd9fac0dd6696baf139e6c07ca531e1c8c6e1a3084b0e6e0d50ae7275a2e14140c8696734ef8fc243ed3bb27ec253e2366b99804ce1f90b094e00a5826500b1ec278068d9c5bc017c71c307331f2b332ecbea224bdaa14fa6357ab8b300d2dc81d97144029a9c1f87efd592fe367c51b3836c8ebc51fe6b8b85c123e6f92a9fd7f0dd62bcefe2b0f00a51c75250851df3e74ba4e678e5c49d88dacea588556380fce909cff8039b82d811e0585eeffc727834bd8b8dc6601573e8fbbfba51489b97f8a12d8fe4849761f6578df5ffb8cc4a5ec3a3cde9060385227f28411e8b282fb124558a600deed95789138c922928e4de8c03a82eff7fd4d05dc0501e400388efbd2b91920156622d7f214b60721ff5e1fd3f75e121ad75f76fef59fe249d860b505865d44e486c6114580aa86ab911ce832c155ddd186b5ba2279c00a40c89261e14c926b4490364d17d1559fdb6f79d73482d6b400d73fb05aa973a3fa096317964ade506c46db2aa910f91ae70267c83d62a701817aac49d2d8db3bab47cc7b6198bc75a327cfff3695f557dabd673448d45115a151138d2d23dc5a31788916aaf88f3ca1bfcfb1240e0c32ad0eb13dc1f5b6342a3090695c1a87c735bab6f26a0af94b57b5480d4c9b4e91935899a82c662457cf91a7616ff42d541ba3ea0d46724a4729dbe6f5a063af1fcd6708ca048152fdab2efc64e85f9c2f93054524e7a21a743ea9824712d23921a4a1302109b4783609a22ef39407ad727ce30a02ef619ce69d4886502ea8703104510f52d1d961f642d0212b0bc87d6833b8e34fb6f4cdd55aae01a63fa305fe141d7a6b20541e3054642392c0dea3984fb6f7b3a8deb36c1111eba7dfcddbee491bf7dcf1fb590aeab2716cd9993af260eabdf21e3323295a34bf5f9583f6ad63030ccc6e32a2025c429ae047640390374f01822fa23c72ce5a9dfbe386498e706069f4895cc518b49f9069d39b2587875200bdbc830372e4003d57ac6448bab4402224bce39b1d2268de6cfa0e1bef3232dcc66810fa447280227ba8c81694e1b55a060295b66735bec3b69929d90e8d51db54bfaf4008ea06e5f7eec487dcadd53cb657495bff8dbe03d74bad404af68385497799faba6eb2207b6a943a63b3f03c68c80f3275bc1a0bd332ad79416df200bbce6ec7c8551de0ba6939d0f932a171ce482f1de0fb926b94ef5685febe1610cc3edb4aff83805153de8ea2e9f9e5e332a9967feddbc29c5a00e17b75b7d59b2a6d53c249730a749b6540c870f18388f102b085e44bdb44889c2d956a70360395465bd0e34b40ab5c009f2896278258f705fd28c2f2596a79c10de9d6657336b44f658b390e4e4149bb3682dddd2b2fb48dab1750726bbe1a059bc60c0831589ac33f750ad1beca08f5cfcf0a407dd8c09b28fdd3d9ec31fbd5ab1fc54978bcf9e6a857bd794c7bdbb3a4e9298d07ec1c855ad8030b0520d42df0ab770317a3235f78d1281622604401195becbee5143bada08130deea7f2301e3b6172d7a8715e223bcf31645b27e0e558e5e5ebe610ec4a8b73ee667fba15728dd0e2234009a7ff9e6b96579a3d04fc84dbb5a277181fb379315dd0dd7d820afeb4cc69668a8690d493f3a54604f06fcb73e0dafa07befe56198d76bc7e67d47da62698b0f3b1047386e110e2b5d84da07ce4930f25bcd6ec27fb98c2c7e52f5a4e3922fcd05587c3fcf4649449b8fea7cd947df28f9da4f6506fafd229008bdcb101ff1ad4e0493eff08cf720dceb6852e5d40827881130e003c2ad9e54f15794eabae60b5a7d29075d40c7e9c264d7c5c426b00719a1ac3369c1fa29f1c89d192e1304542709ebfd8a15e724912936aa3cbb48ade181c70ae8b4635c3d604a9686e8432bfe909f6365c1ba7ca85fd3c424f9ccd91556dac0a137022b57cbd5615a189f8c4ac403204bbd61ddc4fe568aa1b24eee6676d8e1a50c4e4d3aed42f21d0b0aa73a806cfd3561657979d4c335be15f0579ef847107b0562dc126b454e39443267a441722ac106583e7e06dfbf9704290b659e9e11ec901f31b00dfaf26e5edec1341ee2bb3260a1872ae7b471307bb97c112be0bafc848de2b7e7860d62e517b6f7516b2c5f26493d6f7cc9f2de67c93e44214cb72c04d46277184c4fa5a31bce681153484768618cd68e147553953517ba55c0ea5867a4088e2d480d31ae67c9b6a3c6d6bc9e21a32c85d89a9d4733ec97e5390942daec9e6d357b2609a6c58f20a76b7e0040ca48d0bc2fcea5132e9ece05fbe4669e275c5cdc02de7398513c79190f3ea0d16410e7bec85e7b055beeec354deb090617b64c72f4075e5ce16e590b599ad61cd043b603f9085be0d6af7d586e7359016dfcf26e5e18abfc99b32e4915346d9b76309d25ee98f7da743adce963b25b7eabf7f976cbd9d1af9f2f46a287c8cb79ec0ea37861a60838c00d2ec566bccd4e812f0842d4db134ed77359df06959eceac428239e854052fdd86d14941c71bb9adc208551f39e3329769104e0c8eb24742735b828c2e2247d8d6453ebb881ae45ca8887521833b545886039302b9ac39ebae366307a4d9d9d3f4f40276d073282e3c51e5f510da1cfdeb6ceb0f45bdb38a64320810a8efd61e0527d6290adceecbd775d47ea2b8f51cf6d06b68516b2dc305f11b656f6c3b6d8da64d4c7741a2a6c056cb64713abf8bdccb655be03cf8292f271ec0e8a468391b4dbf66d975a8005c418b8a56bca370a448b59aa1b37294616ca10c59fc130d7187520dc90a6b6864d2b7432d4ac0e3a7c87853c8dacb90c9630d7c2272fa499214ba803da96f7aba412410cca108698f74e0b2513748833427eca73a3e79ca3c54c6451611367efabcdd872406d8d3b28abbd91ab70c0ce1542f4464e957a59993dbeb2518961ee07201170b1049a010c407c01d9643bc42948e676f14b6271a416e05cb140832cd7601a2906a16876605ddbf5228a00b78efaab6662889966d902bfa16467ca55db9c9dcbbf43fcf4ed74d7bad523288f494f1c3dab4e2422c0ac4fbfc7e7d8cfaed6f97981546c5171023e460c447414c1bb1fe1807374da41f78d4240c54885655ce55fd4429484da394f1f7949b0239512fd02c2ba92398bc4d7eefdd94fdcd14532eec727be4e5c7bad11381c7c2544a7d9b67a5826f11b1e4776aae6eb636c2d0bf32ea995bdfb803ffd8a7a565e23587cd66c3986ae179f6b129399f286aad7e4ce26efce8532c01e85850ad58f609eb6370a7dce18b8018c85824f37e545b95df1b7e04638c11546c006ba5c904212833b48c0caac3a21e367370cc100df488d20e221d1c071e06c16c28682b7a877475b6e123dba7c4420809d3747b653928c2fbb55a8614be89a5aec4e20b36b0430939971975ba923d92c54a8fe760f14b5d9e78f6141234b6507fa84b06c87f47c7939de2dfcbe6f910c3d056fa4977b51eee5781c4c536ab4af17fd623b417e3be4c567f18c29353d42534ab4a460b55be0bb5eb85295b16697499d165de1d5f3e402d51563c83a3e25503ecc45343253ef75d71f358bdae4fc65dbd7397c8937530371b34c803d3ce74b464840b595b84ca08671a610281fe8c1b3db9ff89387926d21acaea6967ca3174cadae1dd6585dfb606ab396b2827e0a57195524ff9a1326d427964a27fa8d3dbfbff44e550fac481ee644e1d89552af309c9efe2cf841d2126fee500d5802f22b60411c899e14b0ff836ccb85429ca8a2050d4d623e691184941ee4afa9e29ef8b865110d6861c4e2f305d9a8351979f4ebbbe759ee0cc9bb1637a78285897fd321ecb937ef08cac77666e5caaab72e2355b11416ae100b304799f5d416e59066edc0b833c01a3410c1b9f04959a1b62e320316a9268d7f1774a215ff21b62ef2896b8353335a32903abd275760197aaba2c6d8918d24424eb0f492315abf235c01b1a29a8b713d121f9f32e0d48a952c2882191fd836e085cceac673cad2f847ff40292e3c12f2764d29c4b2931f2c2b489abacd2b32aff72b1b0c58d242fff95c88cc99bd122d147f6d6a270403c0d8569dfe492478fb051fdfd5564286104b78c1c9155c048000d26276925961efdd6b8feae919f1a5de380f474007b4f9149ebe8bb5e229e4fea7ca54e11efda06d5ae5b930406e0d8a94c16bed42ce73e6d217c6bb5fda479247be06b8fabec7b99954952feab89ca34eccc4a3039c527955fd78f12c85f3069a7758287c57c27a9651e4304e07e4acafc3f6b56152fb7f5d0484656d3c378f5ab38346e70735de0461db6ed4d491f9af1699a0cf3dcf6aafbc3b7a77a053433abc351a6af39d59fcba3aea431b19d7571ea22dfb11c71321ace3b8c37fe23c874766ff44a4320a75d54130d80ec7621df0219b8a8d3e116f5e1d0e85a38f0a84c15dd40af3ed4796a5291dcdf7b012b89c528a348a06b5f9db31b4e18d345f36ded3be82a879744cce0847b0e13fba15c013ae892f0ee8c7c6840c1a5ac7318de809d9c2ea43f2e3a5136e8858f82bafc7b14ad066120226191be7ea480658ed5103c85d3224b110359236e647d5163f2e2f9603a6851bd367e395c84b4898196faabf63eebf1e4314493bd14f09eee37c4f42b4b86de4afae186f5b5d75fa5941dcb0ed5afd66c7f4070ab0b4585632d3c0e8de767d1865ea03bf397cd50e4fe0d7e0203a00b656f2003d3f6f591ec2ea1c6ac7542a567e39c366ef52ae892915081e360014adf7a594227c8f4bb03c4371343f4e24ec34bc23ec80cf1e7db1534186dbada216d7b9cce945e87614222eca43e0e33304c05939e44f5754e7ede6ad2f6268fc142619351163e7b34778a5c7807ead0695d07113e7a11c176a94021c3ed9d0cef3e4b274ae293aed5d9d3e9cfc45e35f5dd2d4b4ae761229b05f8c81db99330c207131b319a13d527980cbc82cb0704fc465ea75f02c4cf9bcb9c320a9721e27a4e9c333133737412cf8af2b3692334d3c4a0fa6b0d6eec86f69c1f88582c6d7645c9cbec53a8a47658ec3e1de06c9cf5fa67e4031e6db6895b6ae9315f67339fa290511850ffdf64f1dd5ed66c08cfd53fecfda9b66c7b49d9fa242a835a9da124ac62891871c1fa5be35e0ad9eb2b27ce3cd42e767ed91e4486bba2ce72df8c112bdd0b79b3562ee5f531d0f01a97f64238ea8b28f054fe4f37b6ae859f56d17acea721d3b7eac6f3d7a85f2e8930bf1856b8ac75cde72eadbed59d53f717cb8cb54c56589f60c995801e94391fc4724e35f0551e3b301f17e40584ee415819b3b7fc12d92f3429c3b54079acc852647a023279c2d036a6e29d480618a9df651e150166a137efcc2e309c3f72b8bb590cad436477909f0b8b0d94b9e6c7e1d682d248d67403c55ce1ca82ce8207b626e4ba6d737a16c7612a61e93984dd6c28a46f281fb34122bcb7c248ae39207674ae287a1f79387df61395cb6679443e482493926bf10290ff5666ae014d6b82b6bf139ddd89a9e34460640b3caf0b70485f4d37ab6ab6362429ad0c8658b76b900602ae8ccad4bfa3582bc323ae946d1b75e44d88ca86d0e5f637a6150882ae0f6aae405ea12d6df77ac663e28ab6e63ac9d3b8082c951d2f83df4550f2e645d4892498c52a3dc023f4bbc5500a3dd810a382966ea97d0697cb4fbb338a4f0b078f367ba4938059f5ed83a54f39788bb8404c35309bb49943d730237444bcd1467f268d8c83c6356bd751820ee3c9c576d3e538d5a87d63e0fa4d35ec0ecc6c08976f9c768e593d7229d4f3e4670f7063698fd873ed5712c0bbc2fcb87a08c432d3523798cf0119d51270496dd5e2fe3e56132962dee12d2c2f3c8f41f8fb29fc13975fe24ac35d696fc52bde035f4134584a005936c80a4102fb56d517fbca6b689da0b0cbe0652848599c0737597fbae03741fb0bd756fd40ae849d8c15ebbdb1adcfce40091323cd7f0a2d06f0fcba69a35c0db345b3170d6d03b7cccaec060b39402f8ee244c649b2523db53c25b6b4ce6512e08d2dec88ec22b203a2901ce5f433f6748b6aff81085733a1174ec4a3c55219f0962c00d8dca47fb4953f768e0a7b45f2147cbb8fd0871a2f180d82af43d00b3cb0b88fd63ec21e89e1e2221d69c7bf8a01cac477750127a4d4e99ad4c9bb999ef51e493b8c8e39c305fa0b86284dcf6c1e714c40330316d555eddba7674a83d2bbc8762a22f69d4ae2ff64381a2fe68a6a2e07871d4f27a9df04aff1ee0ba714262ccd301c7c3e4f18ec3e05a0f9d49c0bf6bb287fc7611aaacda61533305e7b488d4e03701f8d26632847e523797198d2ee4c8c8865cf1876e9b2bcfc1cdfbe6271a231922616a2aaf372894f6f30d28b065e3274f89faf3e02a24b0a541f3d5995d509511d0eba57da48e857f40882b2a65683b1a48d59bcd823f34094b754365c2db67dee8857b277a206a21f42de6ed2c55fd11ffd8d665114c780d8b7de7e685dc7f6fb36b05db99afb5fb745d74984524677c6babd41bc08b1228a2288dbc19af134abd271d76de955e0c5f4aee350a12487ed1013310a72ae9bc44af61a650d1a8b3f006044ae90930423b0b45a9d669502b90bdb098f9b4ecc5c8622e7429a0dbcef72b0cf84c865a8e938138af67523985787f0ab9b97da16f9cc888beafe8823e0a02b8b200756d81ee15adeabfc0eab9e6a3180a6f7c7bb1dacc65de75bd082d13b1b5fd055c487c6f1bc423ece879ee7f87348cecb87b6a8513032635bd29017deb751c9e08582117b880f6c355db47ad76de14a141da2bb894063cadd5c70520ba0015b286f61eabed0d88ded949251b40a1a23b151a1877329e86cdbdb1310936f05cb4550e069192a93af62573c4b708ab221d94210b874e5825bd6b2c52e78e8644773420f3759c654ba1e5d258ade0963191b5a1dd2a1ddaca4669666deb77496021ed3a14f0ac93b0c7babdc59789ae8a7280149a8d38d1ff581fa38b94c16ee8654ca1b6507a9a2b8b0bbb06b58d49e109e2d9019766926667e3fb0c2c2a41e783f7e9eff953e86750555e0d24aec890e9951583924fe18987eb161cdb84b13161c8d41caadf7e0bd6f64ee815053ccc00bc967c84584fcdbe49890a747cb647d014d48deeaa024afde198581960957923c48d94b32e93af7f9eecf7c635c68c2742cec1c880f20207dde5f8ad586e55d6f0987ee5b2519fe8cef1379f8dce8b39a42e38889f7e1e4c6aa3066b780d7ef584c3fba1b54cb268ac10ea5db8aaf13f1ee2136dd87325541233fbee10f25b3d1515bfbf8ce2e3c66bb0867ff1ae219f8805caad54b0a3191ed46f7e61d18020c3c9d8f475d077e188218459fd796c46b7598899898b03a0464140a2154bb93cea55f60d6d6742781cb0494b0954483360abf280d7460b52d3fe84d95b60ac9ed9b977cd6b65cc9cfbe7b08dbfe3af58c2e8d8b847271e0bc4542c1989982a0a22f5453e0852eb76d6eb362ffe82e709133431e846acb9184fb4f44918fe97389528384c01f81eefc1a1fb7157b3b864a2007111d5fb554a6d0ff87097af4ccca2db136b7e23f79d6aaad245ff998800442ab84a424ba24ff38599655418db7c07da9376e5a474a9c7d81668f8acdbe6e17c3f49035e01954d57538a98ad3667d2b332916cedefb47e5202d76441e6acdef3c748ad0fcc267698327f32b8331bf3234590be98077ff14537119c4f2dcc7f64c25f2f76bb187dbcba8e5a227b4f41d43a56b6449279adeca752e449362c7d0818fd99a4baa620e7e057426b15b43daf1832c4219959dbc6534b6667d13312c8ab12d38f7f5ea7f8b69498eb8abaf8a716db958eb8706451414f956e505758890ccc4bcdb44e3ae04d1d2a21603c53367a9e6eb009d4171bba4779cba21816fe0ce2c371dbb09f018c59ca15813e0a04119475bab3c1f0d3ca79884a1ba3d8f264367db973ca699a26bba920aeffb8c98d4acd309a8eafc04f52a4f5d4ce1adda7e0dc7d89e759e2ff479463e34a5676f56f796f6ad4e5ee454660dd642cfb5a874d4886a402ce029744bcefe5f81bedb06b1dd5b1f63d6da35bf22636efe884ae42582bf46baf6e0592385a31c853d564e89ab538bc12ed56fceb7dfb3e037b93d70ae7c315edab48a9c561ccd9dc91955660d371eef1548c88cdb8acb9fbe5ddc4cf7e4f461c335e0f8a3e8f2bfa8e3ce1227b17cbb943fec9e811eb3be16b4bb442d3cacf352dc9feb05c0ee0b3f044dca5477f3994cd25088209bf36fdd82424d8d695d0c5a722aee9ecf28c352958b2882a901e93c4c10ca49e7973e17f96fd56b99efa37dc15a2f45ced1cd63b972b18c1f1d7a7fb6dbe4e483b91a6d842d8e141f3bba1277310b41acee62472f184d24aa2e6423a3943c05e408a20231099174373c763e690950b0ea6e31075d414818c4536aca58f98f5ebebe3488b4a1ffd1e023ea9df786666643d2a4b729f0060eb53886182a9f03435cd75f318c2549a79366761dddd71ddc21d5ff01aec0c9a33d4fb649f99759a393764df9c3db4119e8d73b53dac303a8ffa3f92936ca1f4abf8d0629837090a863d85775d3d4e26e99dcf03cca4c9cf32c9d98154e391b6c5ce72f28e912181ee7fda8046181f69caa360506644df207ee55e8a17223bcdb3719518dcbee8796a0a5ca43003a757a841e88563cd4b72eec2c62f2b081a60213e25b810ea0fcea7dad26861dd7ed56c98767fb7b5a5a6aee612b843a9930bfe15bbf25b6c2aecb170361c67faf22a5066ac01b1c4c9f416b13f4a1081604bd2054f9e46363b67866577d0c621046f7188ce6397ac60844e8d8a818ef1fa09e851958bb252381b84afc7f382fbfb9d7c857fcd79fc8acfaa2f78f88ce3899e0cf7146b5011880d1a1946103572b4eb3092ecc77c4d744d03229a4be0599007439da4ef36fc69c5f59b229a46e13c616064829997155caf03bb0fc07dcefba8477adce1d668edabd14a708fa5a496950148901429609dbafafe7d6ee9432376415a9d4ccdeb11446da6a17bfc3015c6c449a0c9a371fbcb7b24c9d75757ffdfca3f0c043d91124c776ec3b5083ff0cf93448ac917acd9ebb2bf44aa4f5d78b138c50cea407ea53887ba4c162dee9ad00aa1e7ae861a8219aedcade0f05b14374f8d12cc7562a4058c2620308902948dfe6099b0d6ab962ca116d6d97668413fe562fd1a6308ac0f25e8034d8366781757775c88417709273b14e5775f4aaae8d7592b848a2eea62cfbfba52884742dff83cb50b1ce52b31c2896077430c9b3e633e9784b6876e32d065276df0451a1d32c0cc6fbd87e75b93049d37e6caa0fc6ca82250742229863dc0c0dd58ea17249bd06bf7856b3e28d0f5959e9dfd0de7552a892821c1e9cebd1b54aae2bd5adcc79d6937997a086f2ac7e8d1491a27ecfa0e6bddf443b797689d04d576469934cd21fc9f80e65b1c8100fbf423a0a1ddf908dd24ff14bf8f05b9fc8506e4b8a90be677da9560c2afc83de491cc4b97f94403abac0f0a194fe64be626019bf8426dca240383b6b8b7f8ee2d330d5efad6939ccd898bd0d0d8e0142389737439d98512164a7c1a6882194e72292abb10cb6590c0ca258fc4eb274ea4e3c342bf379927aa4477b962f150394ea6832831c8fccf69a5d8a0b32128e18a4344f1551cb06d2950222ba23b1c8c89655dddab670f4846308349cb9c0232deec73a8f44e26fe46f03eb45e5818b704bc967528a9e3620ab508089ca2b9588d23a9b664742892c6927e758dc1223fd388b65fae4fb55b416935de3d050b654918b8e9f78d91b49b994a69c179e1a2d80789b4e1a70843111a8d3bb7350fcba57d154838bbc1dea4f9159001b5bdc71f35a629f69448d2650fa0032919423aa1ca27b606a6fb4256346dbd0a60e3384f5bc9e1f177a4205e8be892ca8f6919246029471131f4efa04f69f26a3d23a3ca07a57a993acda25b63457e1254400a61d9e4e5cdfc13199bc835bd22a848d6fe05801ae7b8fa8a10b30bb7d9c8e4cb583e8aa5ae4830c9f14b933354dee709f909c1df1c744e6124d06a7708e5b1dee475f0a2c06719bdddbc88e4e43b50733fb956e4033bddba17c3c2b66047f32f304e54f56db386d4a0d10e52f93b8440a164719928625ef4a683e9666a56b0320717c0f9f14fb5edf9fce986b23cff84a2aee5271ce5f9798bafa4fe6f6c7e7812711692e83363c017b946c0f91d6f8be40eacf2fb827bae3d54d6d4f9387b8e92f3f82a1392b25f22f64174a19e14149a533725048908b6292200567ed9fe2010c1a7ea3347727ee569d472d03e260065991e26af101c251ba23a7d7480643295fb203d5b7a3b3e6e25af36a9c47ad7b9c38498e771dcfcf31574b8390c9191075abab3f89d01bd559effae6fd0c75e488cfc6379b8bb0dd3be1f5374c87758c011ab5b0313a0b34a32375b190eaea9760f336c664952e07beabfc838b9b8a81a5c420bc1d2856a83b67e6ec93c1b6258aaeca26b04145cf218cefd7b613aa83e3b9cdeee9fb3f1f228bbd6ae65f874212705c407752a0b1d740caae552627de4ea66e87360a180e31827b7c9fb0835d9c7ab168706ff865dfc7e1deb6e85d1a544baf53944d11fa0f6cf35c6355e202dbcecc76c52f3d188a43db6cc9dd73a4f8469a824b196f62124d32370f5a85ea45c14abfd037b752383cb7c5ce4725f42251b4ddcef8b6ad07e5449de1e58cb0fe500f6251ca865ad36c08340110ece19144bab4cece6964cfe2cc3bd1d29d1f193260ce92e734034630f2a35dc34103de3a7dd0e8b8c03d6edd8dd277ab4a7785710528ba32afe6a9225ae4c188bc5ebd50634fba8cc59ea7aaf3c7d0d052325daa473d2871e2f3161fccc44876a1c79595f6a46366296ed1b0c1cc49bd5cab8e05f59855139b602dbb0e1825889b2315de3594e6883d720db5558ab61b58efb142ae4c35b26a14972fd034ce7a9c831207f2a17aafe4de3d0bd1dce621babaed2fc8e1f561660b9626a7902a80d0ea0867508c9c0236c2900dd38d595b3d1c5e5d787b3dd92a23edec5716aa1e56d28f1987b215ce02664fa6b212ac3c842ebb7c579b3881c61ebebced8a06acdacb30ccdaaeda6ea8dcf57cbeff0eaa54252f18709be6c46358d9656054aebb848c7cd1b53223f36e94a5262215b004176f6963f05102b736dde71a69ffc688758c0961515525228552c4f630ec468399d151891721bb00a3a1ab5a92fd29ba2f3f465784c904adae0b00190ca8b0ff5cf003e63c258a2dde978f139c25b7f591c064e854521d02336fa3ed5953f9e6b66795c1a3c58affa386f8e752d4d57b8b57a88a4bbd31a297bc82da93217c67f803278cc3b8c6618154445edadf6e512e79dddfd81383ccebeadbe3ecf42e7ad28a18880963254c9e661bff80a7c84f7d7c53aa7fe71afb3c5004ce2e37ce595e88c642599718affcbf64c904780f035931b5c98985693ff9c6403a2b10be6750e6eebc11867ea182f0134ab5bb5c79a5fb7f527750958cb0e08229b4377591d30f91d1a534ff23e87f5c2054c11a57ba12fa3c2b976c00c1346185f5ce14de8ae218266e45ddddf98344364f4f214178f6954bcee6855bd3296b610e0fb69c8bd219aad27987fa31879e4743006e5e0f92d6bd15cf2f4b95fa0d8b7218ab21647b0bb1c0b83fd16ef26d9148d389bb09c5963cf9c9d4f6f539d827fa269cbe81c815c4f0752eb32d86352ba3e3e0427b78244d1e360c5504f830394b40948ccc8686a6578759b6991a4df92984876467262e6636642cd55877420344bc6569715e12071e692a7cb22711d90feb500f83d3df3f1c32f2183ef4fae32de6e8afdcef1facf6bbd531703d0a2a8838a503aabeb506bbf9fb87e2836082e1c9c55b0e5c082c0005b62a7778580858ac9d4d82171888b2c605d24b137281cc4556faf70d786dcbd9ecb11836b15e5fd7ea078399ddbeea4c4394fce1c704fde18a3588ba080cec67ea2bc3312cacb2a500d60b8e54ef07e95b3ef689ededb284e8c9c30b587443c77a1628cb3340ca7796768fafdd32442bc2b182d8c30fa54967c312894179aeb37e6002bf92f76af8adf5c12a0a43a7b419a178ca582d4e7190fa735411f01b8246ddc10d866916bee3dc55b59e58facc2713350bdeec614c937012efd402a99c5ca83b1c801d879c456ec4ae621d58c01d65680e52329ad87700789000a5c802ec7734bd7048b6b03fa009bc98e4a7eb2c34d3bd5b811042424680f5bc6c257cc32726f24995f53cd1ff4c746631f090e60892fa7b9e7d1f0d683121e2fa89b09d8594974064b33d11a9ea517200b2d570355eeb9a39f8cae722f970053879cba5ffb90c551e72adaebbdd15fefdfa0f3cf4e04ef9b67f9fab96bfb5d72d6cbf196fa98f1ee1e878ffa145c9bc4aa3e411954494aff8b80bdd7049fb3c814ec70dbdb414c34db693d6f5787592a0f1ebf7c1b89bfcb3fff936d7d7cc07326a52a57206c33ab8571101a11ce9245a6196e1e5f922edd50a3ad03b8e36fcc21667453c4399b0f4ee39f15550985c911cce8d26cf7ab1b815e7216a8e96b8a812462207f8a51e9a54923138a0ac220bd00bb11ef91e1e79f53ac8a70783e7a6998680e36000d002d53ba97fd51a09774f18d9a4220ce50c39fe527ae1024f2f285848ae29af638a1f5eb056305609f5e15cabd7b90f15442765684a010cfe570db9ba66de5ada9bdcc9456a3957bfb48d7f8051ab2234dcce2b8b01ae557c182a8e9500d4867951925f01016cd52046d8325f45add9128200fcd952cbc13230d6ef0563b0bdaafc71ae3c4f3f6e68d5b873f164fa1b479ae98428bb1e3cc034dc658b8ea4980e0fdf7adf91d61992d50a36597734fece06d591028ac47ccc25d7d988101e6b5cb656c34e362af5094e92c20e0d1f3c36dbe2f8cfa0a84372210ba20357e76f18e47e3e4006f1cfa400d087a61fcd2f101b11befeaafdb2994576a78f75839b6a69174175af485abc0e0a6dd81e12377ef180101d3f6d21c36eb58ba64c26f12a1d97c086ca5846a36eb3462bf35697fffc9bc1b97d0266f85c8118dc6594cf4ca82fb8405433583610c50642728ab66df25b1bb94c5efba828b7df6eeaec9530cc9ea33106e18a71790e0e4e531247379efde8299d39980e50a9176e18ce6aa82ff11b5c7f1694ea16294f737bcff2a0d9b4b26bd39db9d4961a32210e5321c667a95be90acac699a906accaf29ef36762e878789970f13fe6160db446ad1d868fc6857e68ee66d6d085b863ed18846e55e501a8aed72dcf5f08bb7ff70b48e50a144e7a037d214043015c69b0f18f16fdb7f9166dfb55a68480567cadb4fb21fe84559bf57e35285b43e3aeb1e5ac4feee183e701a834a55b0cd4b2f61eb9f37ca8a9e1efdc97921304be01b18e1d8a2d50f2c7978d090590f5c8ad4ace6b78b551e65cea365c8e352c5b4d6ae57c5a32e6eb632426b6e6cfb290198222b29705b4219c632e95124ea3d35f2925e45358733ba4ad75a7490ee8e77f8c623bdd3ba5a7c054e922fb8269e684ae154ecc668738bafe1a0188dd3beda462d254bccbb8187a9cc0af38f7b86ba2750b4a83b7a69da5a8316aec1db8a4f1fae550f37deea4ae9d47ece3f63fcb8abd655a94e4a13c3dcea1c662ff564e18662602ee74df9841be146c1c537454c28c53f4ccdac8c632c4991e8eacc8671782fec92f9b7d2495692f01880d715eeb4be0389c94533b93703818e330155076f9aa9be168007635b1f526d1ae5c92df354b5595c8f6bed3cde41ad916a3ee440ba1b65a93bae9994c4f8e601e079493963ee67061874ed5da40cdc0dad7247f68596979ab7105188584309ab480e699430b5a433b3c3013fbd4a1103ee8b570ddae0e9bc2f4567a94da0d98b2f182c944f3b919caf8c009fb15b91057713ee370272adcd8199de644ded7c908803c28b47eea19f486e21cf39d0576605ad7018612958263f1e672d044026f20eb1998ce3a4eb5704353e56b9b34b852dc948dc9bdbf1e8ea0a92a11c0e69c1ddfe16f39449f730681897cab56c9ac9b7d010005b1a93201adcdeb8a75390c6ff54b5bde37028332de40ec70694ce8fecd780f66c031cbfd4aa7c7d4383e5db1d2451baec921a76bbfceeaaee1530d7bec19525713c63f37a1b18df145dcbed6e981d600a6e1ec26b540e92601e841eb7114379313738f413fbade80b2f501f9bea60d12a43a045780cb4b373aa6d610e206ca386b99ec7fa1ab6681a9320bb86402d6456a8866ef352efd816affa080c327aeb164b11c3a51c467a5c78ee303787b0ac4ff528feec12ca3914f778d57b31d8a7eb2b8763d95fc40662d230d0b38b0e5054c775ff232cca8182b3896e6c8d1a2deb67ef93701b60768ab267073c7c89a070257ab1c771f9859c63414cb4f7b00371efde5d423028016cd0110c06e83069ccc4b26762deb14628080bf62b3700526069166038d95e9b1b1124775efc20bab823a52505ba008f3be66d99009d7730983766a9101f6ec5da1c69405036fe5de161db26d6ea785083ac9114148221fb14858b5f911a561296961b2fb232b0adc013b6802a2df0a766aa0524007f932a585782a54be574ef37a4db1095cce6be681302874a9fb8b1f992e2e0fe8ddbb4e84898cc168153e21d70f2bb2c8b9492782e169a753d9cb525e8d49a2500d34eb0a2e938ed7307563d48b321749501595da7af439ccf5861677e3b90632669029110ba5d59e2bb4b6f832425830e954a04d994421dc8a739c9878282fcdc5a928e20cfb8498b4687f921469938265809e04fd7ad21a0773a96e034b02f066edc0fd0afbd445f88487a72973d333ca5037a2d9f90c5eb0619616dc4c575d80569d9827e26a277d841586f9eef6394a325b5a9da5816b0690c558aa29a1331c55c38ec713216efbfb9322ff24cdc82e4d4034b3d65ea8c84efefbd3e5b116471a9920b77088a9d898fcb49cf8c4db764fbebb39b39d7b7b25b121d7ef7958930de12ab652153b0e893673c23b12b60c96f8a7c28d0ba6b5fccfa50594cfa6890e32988cf4ac0cd60480a57a84e4e25f21ac2eed7c9ed841fad933e2777f7f09a13bcf80988dae86dbe877d4e2e6d57c49d22625db425d9c44611310c5f46514c1a2c0f6b61ff1620410c05dcba6e427b9650d3baa8ab87e031f5a8cab39c1fde0be43302f8404f5571e5af37901145875c1d3fce05d7f777e1ef2f012850594b004888133fac7d0e4dff2b04711364bc49509c2f7e629b3a4f991497d542efa31b4eab2e0625f9d3272247e1c4030f9a19416fb5935622bcace9f200fbd6b7704e655e223135a99f78ff664764b0174a824c4ee3b0192c2768094d7c30fc2ed5f70cc6ab68fa1b493902d21cad675f0934c31e77b79fd45011bd0e6c6fa386f39f942d62ba5adfe773eb958318a52ba4c81e075e1411f7538ae17ad9d89d7f6875940226f6d00f823a9c58ef23480e25949414a5f090ccea2542db643f22c2560e906ce76684a618e231164ebace175f8b31e3bfed98153775b3a2004dc9314832d5ae47daf51ee6a813b073832949408cf1ad7cfcfc7f51cd2bd4bdd969751863183fe118995b7a268f35ce53443b6e12cfa4bc34c084e6d3e9215b6b51e477cf5248998da802478bb3192781efc22bfd2b2f85fb536a2e55e0295c094f92ae205a15bbf77e709b5a6b8157832c2d3e67669fb054c1f37c535fccfa7e409f4cd81fe8fabcf52ea3991ccc37016b661ff5bdd1d362ecb0d547a4351d567e1a839ca9e3c5bf27a9769528d86762e0358b7cb1b5a51115ea31c2afa086c93865c2410096e29f320b21f1c0887f25bcc50b320934fc9daf1d6589cfd66bc267f77d1128003c18b5c9ac345e883ac5ee11c5c41f543df29718dcda23807b1736fcaf2613003844b709a76c35d89173668af77459416981f036830aeef0eaeb1ca09d711bea22350f2a49db81dfe1b5a97886d6a15cb98190dbcbb877a3fdf629c30f16a6dbc2d674285f746fb1c2e4dc81f42b52f064ffb8a32da578d4ce9b76abef5a91947760496d1281804ab6f5bc079e19f02fc1ac63f76402f7a01beda48a08230a9dee6de6b8c8998cece6a4b3d3a37e880dedabe170153c9abc9541140cd00b9be5a0678cfbb72f268f145f265eaa781c34e8572b96327a64fe48d57827d492fa52f48907c0726062fd737640661d835221668cbcfd44c18b8debdf7c4efc016d4def3660e89921e037c27c7cb8c350741ccf2ac9b16c7ec14acc7e4b10d25ebd205d7728224187ea93867da359a8a6ad25d56a6e55c9b56c7b5ee3abe763d6b672725238c8c6037e8435fbcad8120f61617690bb2c454aed5e3c3a96f7d9c09342a3170040ba6e8d29021c70326cb3b8187e14c9aa1465b010a933724962ee485d4a46e1aa9d2d34d485827f3cfe37039050029d6d9625888806cdd36c0e1735c0ef6da4e709518ac074949a3c299b54168abce3198140d1de4d1bd92e48d59daa82abf6efe19c71cbc62f58b4efe1290d3e53381f0fe6915aa39492fad9e830408fabd9f25f0aceff1d41e9f51670e3cde28d1f89dcca8c1205df05b2e6c49ce41a81a9bd1907fb8fd2827f41952e5cb779f1401f3893b6a09bd0aebaab5b136590235e02f74f98fd49390757d8e55df118b7accaebeff5e707b4c2dc06e0cdf03d6444b63ddf3f2b7642e585774130b8433a322f989b485f6947a1e9f961a9dfe9fc3ef02228fa1586503d389ccf054d5c5c75c3bd96e065180487783ece3d78f79fd925ddda2c371ffa5fcce34c1e1462d54090d56ad53fc0090617983fc9778893d016ffdd7d809d440149b3447c6567ab62e4b43a90c784f4d42c777dff2554775e325d1c3100bfaa1bb997aaeae09f5c8ec8418345aed6d18de9855388c3fc992e3dc70ddebbf76cceb7fe39883301da39e36de59900d16d9db725f864746823bb16eb2820f1f6e4f39a3026e90d14a0f773fe6ff0ee3cfc8ba0884e0fed0e24c5a4f97c6d0e5ed7e07606e06aa4d5171cb43105dde426b9f227e69800a77f0797874bc401cf356cbfc83f8ff46cf1a38163d58199403ff40ab0177d994b63771332b0a7adf6674aa05b720dfe350fe87907ce62cfbe711c34b75a3e6eef46582058425ceb36c6e28e091e262054059cac5b54050ce32e8c3174db761ab30fc66972d95cd0d64961633405807e0d007556f5102dc2a49007832771b84cc8253c71bd62b07fea9e4772a7ec7aab58b23316faa9baac9a6f32395c986bd4398077f13cf5d2c0ddf0e6ebc469f46eeaf22f1e21714ecb417406a1b90192da3f1d4495c24cf6ffd5d101283b4649796ce7d5a802891d59ece54cebee724ea25adbb4f35512ba0d03570b1990b77c0578cd3364b7e51def8863d4268d1d6f3ec90d2bab2f557233d0d94e1a364474485c72e07cc9f90dd393aa587200c7680cb7e0011238712be6eddae7d5658a5f87a60432fcf767210978716a2283cb0220e5f9724a85107dbe64019e2763722dc8c6319909ccd96161512e216b137d044536ff5eca2434182c31c0662e620cc56752162d5b3fc894812f3b6eb862b4d7b8da5921f73e5d03dc8599526509cdbda1d6e8d80198018a5a91665a9d9fa7b3e841b769834d97d49932971db5659070201c4116ff76a0ee14eac2ca39ebd5baf84eebbf3cf8c2e3af8bad70d973f1067d12744c4b652ce27c2c1b80112115cdca62fff9e27de482a5ea08c6a63b633c514c73b3b52aaa47b1d79a65ede2f58f5b8cf5caea9070050d4159c71c0b9a4d6b552531ecedfec19e61b69ce0591ff82c6197f73478eb6b8fa7e62743169c92b5dbddd52c185029dfe5b558c7af6c7a919dd947c7492798112fd9772a62303014c62702ef28846a4279d129118662791a8ad1c157b9095dc022165cae6f190824e5841cab8c67a9ccbb432a5f18b8d2d3c89c57251bd22d4b62e4865c1d230c32b4b81b825fb074665699c8507af4c97bf4582ee10a1829b3994710b27e19cc96a1d4a8b8385e9b3b95b13694750eea4820d7917b322e6817dd048ef06d7bb21069cb5e5faae526cc71d9823d58635d49cc3221eb57db3aa779b5d38d94c87261048282fabe0afb000f5c53a3ffdd98b3eee06d37c8536e50fbb6b54f197a94bf8ea7ee7036feb187fbe2dfe1cd57637a54acb74ba3bf009e1bbe308a2041c61584b1644fa562000ee0320f33f50d34ed1900cecb47f91eb82a2ccfce0c8707651e422e913aea2ccee913e8ec318dd4aadfd9f687c8d27e61d30695ca6599c07f7b0a8c03d2f0f4859cb69d082462aac6634c59928942cbed1a5a18e439f5e9a3e8dda433d092d38f4a1e2dac01f36cb7cf9e0ef41b21cd4e9898557d15c1318a884a3090364245b86af30149a19866506f0d5e80d8f946142bd4930761b994c6fee386a891704809442f8b43fa770185123c9dddb3918e6c9ebfae5adfe866f66c0627553982f7cff6112636462ab2aba37c4f6ce5cc77e3570354785c2436e49d1d774ca2b9b8299805896a4a88390ad8d821e0c96f8efe651e4f7da2bab403a1c7fb3c74529390ad51ada3c59fa0b02bd22198a3ea84e291957a0554f22948ae7262f74fc312b1dbfe4363a32c04f7d126561e88d0806e2658c38e83d88ce9ce88bffefba70cad88c090f9ad9c9f5c7f933e80b69862dbf43bfc3f0c726eac154eb71e6a8db358a60670b5a310b6541c22c2d81dd250fea72f899a641570219215d52145c703d39008b6e5d31775ca33c57db4818a6909f69ec5ab55a5a6c680775d281c593cb21efc3dffd4a1b78519a893d259d525ee0a9c8e980c9d339c348dd0315746f14b1d2276e5b34c83c60be9ee5bc173c5a7ef69a5fc66a93482a6cbb45690d0ee970e577ca1998c614abb5f35711e00bcb9f90fc50e84b8e47cabad62526873921bf58b5f8bce088c99cc48a377114c0699796897242ffb2d7e2ff4e334cbc1330d3ae17b92e004a56c937c58a6a44b386bda191846ba8d140d2a09bf46f374987d330d8789607a353f5b84bf979db1fcf591174074e6fa06141bc046725d481b39c60ecd7d1a5cd9246f3485719911c2e8a8cc71ee9b7897ab385dc5836d28aa8de7da5b44a6b16545267a718db680765bde65630bb513be1fd796097da98d13ff347daf38a8e535035682b3c530fca9438f7596c07b04ca338132899c851a09b0f0b9cd22807fd9ad4188c16b68bf28ef36a1b1942d474886d7d87518e2bb7b8fa8cabf6ff95038f39e724b979a600f73526f0bcbc59155c609ab86f5e13a009ef1c201616d9f3dfd08816988631464ea60baa276b8f114a8b25d11aa70871de5928f7c6924e22bfd23f8a9330e5144f429573b65d72c21697a070924a2ba0c96fb84b83bc369809b41dea790ec0ce2205e695cdf5e74f53a268ca6d222b21b134638ff7bc1752482f8c47c3bc972d15be545b56601eaf81b55f0d0d3c1eb7aa26dcaf3831ed471bf02cd247df61dd4a6919688ff15bf80b1f16f4d017a30d7121fccbd875372f28d585797202fbbd9cf499ab0082c1dc4cb12303689fbfa89f73765943e4e9c8615c9ecfbcdcc0554a06fb192ae3bd403e834b1adfb0fbf1e06e4f8e921afe7fe707fd0ec9aa0150249c80dbeadd8c3b00e409f83501c10450830edcb9c578e443ed9a81130731c15e41cc04bb00d0c19e06d28f873915cee7b67fd4bf4f1e56fa0f53a127d00337bef1b0daad2867259ead6dc3926d096c053bbec653f99cfd89e433ef5332b0eab9cf96ec78f7e4b9284330729fc23464064200f9e6a9d1da6b487db3c210763d0b6d3bb3070ea95b5d2604946214aecab35051e2f8bf9262be2bb49125ba70a599fbc0377f029a79f32460dfb0df9ee305211a2b4d190a82130b26a0fdad7270e88a5b455d73dc8bce88e1c9f4f6e02a2d9a558a1631406d2db441b32c513dd7b2c3739be0d2d5ea4b5b4a460d3d90af5f9ec20337c7c2c784cb9fd796b1b4e2ad9615a258bd11ac8e92652188896e7799e57f7f249ec23233294b88c8151b5995739219ef0fa17eea76493ee56ddd7c5cd47ff779c361a83f2d1407c584a4c9b64193f61d14bae8bfdd45d151484fcbd61566cae7b8f1eb51e8c958e398fab2bfa08c2c8f8611bdc7466b23230bc2469be14d2c9aa20de768e4368a6ed3848867296d88a165b009de62a00a4f512c93ff57a70dde11ab1078a74b5115be11e43c39517a5ca141346654353c9094d0d4bf35ceb90f383776c47d57420a0721040966b6c1d62e0e997f7c2d3bab51e0be7549c17982bf84e6950901acbb71a44458ef48191c6a7bc6965f61624b48fcfe41ea4c1d54327cb34f7ac221d063b2e0b25520fb4db3523d39be5f20c85ee5a5d88c7da538110dd9fda0d0a62e2391945220732a02885e7b98d0a58009d00a3a723ffb9e5470aaf7e0ef1eb2012ad42522930da389e2b7b8bf6dd8dd44687c5a40585df8dced13e219fc298c74662d9714039092aa6c3e1642880c6f8d4d5243dd87be90fdcf3fbdd9bf5813124fcd7bf3dbcab63201e88d252c876ac5194b4f6d086296d5935ffcfc5cb99cb54b966906a39cc28695a1851906484b392c27b7d195917dabc9f5b3958969dc0cecb925d8f55639722da479ff0d2c232c87d3981ef17a9ab12cc8a61b04ae12edca7f2a48f363c9d18d6d5819b19ee19003bd2e87455418272156ad11ebe17492f9dfb1d3e128689c15a16844f473e628f61fabd0b88fadbdf124eea6dad220042b32e11d87c6a1d5787dc6761127566bdab8357ed1b4768f90d6611483161d22b4a8389186d6996f643496734388306ce548ec410c36c00198ff25ac2f229b9ed53a29581cc744e2e7d8d92490dd28360c14c93598baac073f86fa123f80c531a66e8affc021df8e749432c82839a3bd28122108a8442bebac3434c8a16512ab55955018555f867b7642b9db597894a75ab0000c81f2d1ba821a1a87a1b3ec952e4d2cb8286934537700c6a8603d545bd127f6cfd3e51b35422d0b2e2f007e9a55c284005ddc70d85b2f8df037d3c75406614e0e6a1c077ed9d8d5632779eb870c6ffea54f21ce636b58c94e3a5c437c7d6976d98b3cfa85bde04e2de1553ab7a214abf4ef299652a954418e423bb0da3b49a2d341cbd563cf535779fd9630e88c4de16c02a17d7c36ffe88c10f29c1558e764ba7925ef6c544493b7cdaa8c64c604378ba3a02986fd92a4acdd341a8c0c7bb3f1f7d9d9b7ee58154979b526944e9f7751faa3274230904d4011379cf228be33625d4cec99b9baef68f972fa9f3211a9576535938589bed476b56a5729cb1d9707d4cf43fd6ed0b4905db78439c4318620aec3353342d9203c745d171e85652ada68c2171b556c98ef3f8b0b54a9d2cc0e83c6e5c83ff7c4a6ff5ba22e18d42cddedce718e217d9a21d08d61bebd244b612990112b9fe9cdec3872d4be6d386a73ebb4db0ba5d9f7e21476f6e9ff929a608f52fc711a40d68bb7fae3b06a76718dc9836f5b2cf5a0eb86b529d33183692b028de22db2127c7201a1522de8f22716d09b6cbf1c49b72fb7bd212cc57280db71fc19b9d210a6aa08410440ef76b5f40f73fdf1b7abb41b532e84a03d65dc1c8fe63badb0f5227ab847eb58772ce7dc80bac4287e1e1f5677e908d91a035e5808e9c907eef7876ccde5de7987da71a8f81ae3402dbce411f4515d24fd23bf26d7005d4794ccb965ba56dd83c7cbdfee0cbda9ff7005a1c6ad912a44754dae1a1da6ac49bf288bb8f89c8e7df2d49d98e0c92a304bed8974b46f3b0846296b6dcdc1910f82adfe392decbeb5711772e9f89cd384dcb39c44a1ee077eac184bcb95133c273b7654fbc32ca2a19d783555687aa08388391ab83687ba635e7c8117a620d2658e203fdd06f835623bdc0a9d1f67ea1899e5ec8ffe6224d1db6b3fab67e1252a5ec256ce229ffd39d41259bad1d69a46ce425a005628427d395c0971d0711cc7443e23f3e34b53066a47ce124d8a70c7fd9bf5d61716309d63bfd3aff346054cd1ea73bf0eefa90a1b8cc407069946ddc5b35f7affb6a2bdaddd9792c056c9aba563027e1dccb3119e25f723815bc87de3cbcc770ccbc8ace611f10e47dbe7bad85a2a77b17249c3cafcdd1ddac81f09bb8f70aaf17cb8ca28a5c3a4ea836ed7153f86773a160bf24457ba03809a6469a292ae03a58981a8b1fd87c42431a23ca944501a3c8be85c339c32aae8344a51882a537362f392112efd0a0f62e1b89ce5abe7b08e50a1a3788f8f5dc9e27d7acefde45394b27f77cd22ffbcb26002665e29161b6a908a2801615842cff2491dc1c32a4319dcf622f9a438eee9a029eb80f8bf9e3507a5b7ea938d7cd82169964b6e7d08118982b1328c5316951d699ce2b967607a94df334ec8db489cde8f03f85c1953dae353bc7580d248af29958f941655da334a4135a24539e0e9b88bd898e944d0005640dfd4fe42691ac8b002d08bb1f63c602bf4fed452c190a7b00d93e16cbbe4d24eef721a64d3c84063a32a86539dde55e826264557fce17c04e130918369ab05f5efa631156d2c60f7469b5ccd7ac47dad4714a4524af2a9586f3908d7b2b8a6803f3d6fb58d5a25a412963ac1417ae9edbe25ae17a05e2debc7b470bbaa96e75c3a5966d9daecef89f8b201277a91b8f1467691344bb74a9292822fb6a2fb56be348509e9fc25c1cdd7a0397fd918aa89d6cdc1d51ce9ea0f12ea90cf71682ee34c3362e86d4438df91269162ec7afe9c55b9446a957c4c54a3ff475145d9a6b6888117db4e5eaef1386c221a36cef00c16a2f045b9975e15386033a40ef364c3a1e6c33b74e531ed4592de4a34a84388d2c3aa5a23ded91e4095e5c759960fcfd6f92aaa77372c47715a99b2c48d256de89b11c09c7b5fe2fa78ff22af4e45b99d2c964e4b11c5a37764aed5b30d611ca8c24441e99f960107b4dd07932c5a866d51a0e0cc1ea511541673c44bb94063254860f2679491490640f8c9fb0eb357dbc7ff6c4c2c0778f245018f4da9eb1ebd01ded5c649568e9c6711d811727595ccd4fe4aa0d30647f6796dca042f24746ee7bbe4b5d8d97893cf04944666375771f159ece94482db13f4715a4cf55369689a23c53e170e0bb06bdfd2ee15f9a89d5fc132ade3713db680b7fc368d4bc6b39f6e1f68e7aabd8882deea7461df0211c5426e8cf441e863fdb02e051f5f2f3a15ba7555ebe67b8fea237905bff2e1c2722a412b7c860c3317b6b882db62da647dcaf31a8838088e0c3c0bf4dc411d807e81401e72bf114dea5c1c6436a1a298f332be146f2fec813f1bb54c5707f06be8707c016c9c5a31013e10581bba3c5858750e91514464413e7e88f71a89c92b29b5ad9859b920d7921c85643e18b4f28a75b7060a7218eca89946b62daab95ec39468e071c3861bd773c5cc8b3b639fea3fa278d65a75b9693f2dc0aae433aa4758816d5be7c52e8f64facaa5e78a359e4e39da8ba28991ecf200a3eef2564310bd5b2cd0bea1978c5a89b1a8f5898c637afb718dded1d2f173809134cf29ee3875e5bfae417608fc2bd3dff223a854b9702f9aedc06302d0681c199142edf24eddd33505133192ea41115d8d5242f14791067755ccd10ec98b1b8c4090d4dc5d1ed2bf804ae8eccba4a2d6b4a1b017080e105656f642bf99a80f71d98b7612a1c337048da3d10769c12373ab3c3866560abe4dddd8a01ebc0f00bf670b36e232e160ed07f6a4794d1f717cc2e2daec2e579baf1eaab862be879a8c33f7b9aeced65941ebf2bfa66d2662585caa87724d639dc1a87662439131371e71259f6307ba194d70fab5f59190a0f057b301220076dcbd02320d558602f7698781f5a609ffc291d339618cdd6f1a69e4fb7eccfae65c7507d1b361d880b2982075b676f64d5f3cc909cf50f833a2ce390eadfaa0d41d7996848ebcfff4333d9cd080eb120ecb0df74f92347bbdddcfae579dc14eb05ec23fe354b5d0f09fe94beb6d672706319ef985e5693703c818356242601effec71d2f204746608c53a1ae490d4a2dcfde8ee032c99d7057d6f635b260e811fd882eb490cbc510f7e6ace0c08a1f8e38406963829bd55db708381155a81a52c2b2b4f67796144d965b2c8d38908aa8f0372c3d91e0559aa37365a669c661380d49c107eb60a4c81440c33ab19a71234d167f8a89dfbed148ec217ed97447ace156b4537e0d460728b5c280385c65d313be39baa27ce3f44a532fcd56577947b2edb9bb24c95b5932778e2a6647b2e9bb4df2267eb0ae8329ef9ff284191aef781769b9575becff7d51c5d028974b4c3981c4f4c7b0fc47614d2a99791868f6331046603f3a2588194fdbbfdd998f8049a565bedaf51df07d6892174d19b4876a3f5b1c4f7c5e414373a2ad9874351fdd092dbf8f6fca5c3c645942809a341e7c16c2ad354c759dd39a81faafd4cefa27aa40a914d3c4a5c0419d12e10e039e1166564e1dfd0d1c11991b2f7075c212b69e1b2b1287a387a133a7945213e6d503ce976a5aaa58ea3cc4b0445b24a2c145bfea82778d1ccd086baae94c9518df7e185e404fdeda70e3b0f2dc53b1928b977cd4d9dfb526cf374b9e4b34e740e4bc975f1ead44b2632e1875773861a996388d9566c8037d19943067691b9d7a429418d5387314e69454c91ae403f99d717c92eb0f78fba6228e61ae2e7d01caed2c9fe645013b56b9926db39f0c4fd6d067c8b3b9c9d0bf72e040195ff6b7d6b8bcb5b78b302017869b8690e2ca1a728c1e17d9d154ae12031f01129fd4e955090f31098d3a1655ba9b87b307a9c2c78af427e7196470eb453410ff9870e70669b60651a221166ba6299bb95571825247aaf92e028c1bb5ebd9915c5215c462c8f4b1dab28a95dde7cf2bd1f5f76a7447dc3fb6521dddb6e7b1bedfd76c53d2eb43eab18b23a4bf06d4503e84054e87e666ae0339f87d1fca555bcfe01459818e053bc99aaafef4d5df2810e8db206e31068459c31538142c9311042036c65e98090f331ed60b0bd4b77f30000ed4636610e83a2a664f2e3592c7144fa89ef3e78fecf4fd4072168168a2c5620a5c60119e48cd8393fded6962b22d5f9091f83626ab1a0d1e47aaf37cc3c647590ca6450844d460c4bd8bcad09294af2f527bf63d9c9457826755ffe4d1494839a39b7aadf80198fd179f99d2260bd213770a450a58b7f4ffabeecb6c0cdf066210570ea29d05b2905aa47413d512980a404195bc1ebcdcb6620b62b120142ba720cdd4c36ebb705bf42098a0afa6b4287782b38f514d22b5829ef4ecd30240311c795e886988048f34acc6009a2dd95a82aafed03326905af4abbd258a09f834a312e5366b35b7eeb502ae405a21b5f8b2e68c3a9e71a28e7c2699908de08a9385ed73ef65351af80faf37f78d8a2473742f6df73d2f508cc790c8c0d23539d37f74bfa2a0254fda72ffa2b3acfe4d2fb99ae727738066ddd0b6eeab8907d00fe444a38ac1e8bf63c67f93a9de4944a54deebc49952878bcccab035b0e4871cbc220a5d7dbdd2aff185a6bd5a118a345a29c6c9111bfd96833283b6839664153dc43646c2deca06755095c82098e30213c985dbc15dd1bb967370078c65577a50302ddea93917f2060be444967424c96f6bf3b2dfcd1002138439e400fe3d66dd0d38969df0f61cfea2fa041ac8aa7cf89b02bb63053c040cd416af653ba2e8b7b9271f0f56f0438a491614917de7208e63e4c926cf514fc97a7884602c348dc20d02d14cd5aac8ec0ce7fba996e2ac4a2dca2a347876f88a3706f6274e21a91ff43596fb4f088360d314b7054c25c127840c00a7338f00ea50f952ca8b5cc6c3619aff0278317a7700498a3053c764c0c85331585d36466ac76e78b7dfa88e42ba633ddd3f1491f84a0c2cc1a6d56f78dbf4bcd48c53b9e6234e32d29acce12f06f793634c236afe1f360c294c78feb8d548dacd6cb5f861ff590b7d8041037cf918c25c5687e0c2b69f30bfeebabd6b76024f11fd04855e36b2f5666de151b8b681cdf2d97088a20388f0aba54c08123bf6982b2ee4a300ffc1bf292f25a5007df8b73a5dc5dea2a3226fb400f91deee720601ab4c63df6dc4ecc54661b9a18c93fcdb0199bc410ee40192b9608f1000b3a986ace01e7823ba0027cc1544ab4a003650d12af1227d66db74c78934d7216f378a3d20711f15723fa7b4bee9a880a1fe5060282738b75afb5661f95cb7cb635f42386dd299b28b9706f6c08b0a10cacf71fe250bd90b246b430972b6cfd8a5727b62119ca3afa9918aa36424121fa1ea0638cd4e4c0200585c1023d5127e93cf585a05dc7d485fbbdef7b68d6911d0ed0f4ab6be285a842ddd051c4958d8d9d89d403560b3e78a2d7cc37d08aac26783f31e607dd375f4c552ac477809712073838d30f4e57b24e729d580b781294d763b25c7d3f55e34fb5ec46922d948d2d364951129ba75bbcdc8592a67fe1355a5a4b42707d14b938467a9d43c5fea7a2ae564c0467281a6e3ce255ab60f0b7eff7f7f24dc7b057f2f02fb5479dd954f90f15063d1b4db248429d627e8f234dc2df15d639592e550b3915c7d8ad4e9e7fdcd4d43480930c450dc942630f3238c2e7b176e912e10d7ba2c590be9da0367e4ce7ca02c63a23dc3e2aec3f6e437fcb0753447260a556f8409e24486b2fa72ded0c624b14b0c53313c40244942de5f76e89cc44f1cd62124f48d18c1a0da12d775e9c40beafc8a36770863c9a58952e03ed141240ba04e0dd4cf88b11507b9bf58bf4746bee50cf3792d1af80db365290f25837da91f429a3d064a195876158a32c6ede883a0e245951777c163106de1822c82f093abda3ce1b5fcf61a77972af3de3f7e2892ef55dd25d25f6ae7df6b01927187925ec17feeca6a64f00c64f1646e4d3b52cf75706bda87454d01115b5f67202741c19b5ea04a3c9ae94a999346ad0e90c74d519c4aa4acc6a4a58affa368c5b66afbde5a6b0f7c4fd1bfb24dbce0df84693c0260f22366cb1b2d2aa24036ac494717f296bd1f4b6ce8e75a0451910c3c3fa2a5e48ebf0e25cebfe2738a50b44f313e9486e6ae1e50cac3f20229fe1934a7005665dabffbc725140d13788984a5c12b0c8095a648699946bc37ad362d2ab79a84cf8d4bc0346227a52b40b2ef6e7f1047bd98022b88e71767e8eb8f61f70c81436bbe0a17abad222d0010c26f5b0f26d4b28a3feb1eb2a34af3ec491d63ff6a7da0aae0fd8ead6977fc02b61961cdecf001a6984e41fe7bc0b9a8ad24dc6f3789b8d3eeddd443de6bd3a12abf34ebc2ee7152cc298369f2720e10371929b3b5c38e9a6d7ea91aa4e14c00115beb87b0aa0464eee762d5eb474e77a11bc9a8fe1462cd018dc18060dc3bc8f0703178b3177ea984321610afab35cdba70e7539a8120460383d11889645987b070c481a35e713a2db71acca2e9d06046a41dc2fff6d4d9c916443b5b83b7d99fda4a3b0998c292787b65e8219da5edc0a63488a1c04c37e1ad4469a2821bb38dc9467f05b70ca3f26e640c9b14675042f5125c54b060c70b3f1264c61d0fd0479034796340290a7230060b9be7969c07dd2fd7c01dd33f8542c67665266e51f59946be712209e1e8bed1847982c4788a20839aeab4cf35ffea55e9eeeae1eed2fe8566c81063f3fc8179dfd25004a41e41e347012c2dfe66809d1d659bc6ed1e4a0977a229ad8ecf356105dc845c1211758837d55fbd9ccbf6f7de4cf0fa6e9423e2ee376b303dd4dca73b490eec3ec7fc1253f4fc898802d593edf976c9b38c5d1f9d37d0f7e6d5cdbac952664913596750ef5805413101401176be1fffa292bce4dfaa2261300a0041254eb1ff38a75645bd4c1ffd0446a281ff6f5b1bfe820ed69d32dd47f8cb6f81843801e0f2ff3b52c103dd60abbff87388133e294c9411fb777bbc9818e26e5b80eedc054c40282b280fca915e313c911aa5a0d8f0348ed7072d0147c898f2317b2490e16c0cdf0f3065c035724a19245de8926f3647db59850f32e8e29fed16aa27df418ae91f5c93911aa0205a29e9c70aea54db6c261a569a8864f1002e89db5bd07ddf76ab8c00c767d1218f40f3db05d211f027cdf7debaa0e731a95df72381ef094df45cb9ca0ad7a81ae600c2df4977fb722de929c7f0922f41298f1cf79d0ae17a3e46a6e16cedff9490356a5d211cf8dde32f949b649f493065afa31f1f34c325c425132d0b9baaa196b8302354527579ef2b759eade6745eacbbc11dc4219cd6f1a01b9f05f82952f8233485c9f57079107a80aeb11def45b06c5b0c46a3c7040677bc09de93c9c3b21be4877e02f90f01e77492f25260e3ee9764df120b830c48376c86d206b5c0b2a4b4311b845fe757b7522f500e92aa636b539c14c01fc2c20fc956ceff9b74fd087c3314dcf81ff8e24c06adf0ffc669634bac29c1cbc0d142588bc3f52de2881b6290ea00750ecb9b2a9e204d45102405fa58af25c02166482632df5cc525c751ac1873aeaf9cbe6893f494c999b4bc2c68837bafa865949bbdc3c445290f6ddfce018de6d9bc19ec01931b1c1bb918f34755fbbd61f4bbb089c60cf9b14b169ff0a077754b47a9c4945a12ba50830f3fae3d6fa0e199f5a77211a942351979eb19cd1b9d97ad5bd340873fc5c19e7a83028fefc6f571883490dfbf1bcc41e89c0b7a404ae77b6b2318c17813d9f0ff29b1b147d49cc7553646feac11a47bd2a20c59eaab4b730085f06c0e6d19fb26922f1ee1f05328d76c7e11f0aa90aad0f7aff603d92d3d5eb7b99ba39ccfad6ee3abc1f400c2d770b0af645bc652dc6666bb4f24b8c93400179e52862beb6a1254c97ce6e9de196adab02b623ddde97d3cc766173290cded705e1a8e81519cc19836b77bda6478edb5ea9fa41ef2ed53561d6a4bef3e62ef84f0ed339b1eb4c9a5677644b12824557b609541f6690976ec64d7456dc1d712ec6fe573990a63537742e586d07b7a6d5d6b7a4f2ce3db2328905014762c809bf622ccbe50ccda3742ad30c9c4c19895b5681e6f338b92895fdc217f2bc408dd02502f9027723ca9b8640abd22b39a4332240a7634d9048838e0c3f5c18acbd36f6f87e8cb9ecc7abbb8089366a7d5eb6c3d01a7842c4af95fd11fb3c48a793e2956b3042e8fe14bba5aebd16b71cce0d5d892645ab16ab19da271bf8b755d4938cdacac96e64da98c20e29cc4acfdf1b4f56851e2d80e1dd277e1fd57c86d05340b602fd52c8059e3e3d7e90b6ca7bb78087c0d1fefd90b1a17a4db4cf817b33eb1d507a83929f9099c169f67c27eb6d83b85f48da368c4ab28db4a76de41bd9967f55e0fba0a4c55aca8222a3b79b53a7cd58a462f6234c2d210c60a7adb9d69370a20993a7fd0e60f22c9a0c84f3c4b8404f8c09a47f412e9456f8babe3c636f2500f28d49dbd3abe8678d4dc2535af179d4d2dce797e0f26881cf05b0ed804922dcabef989484114dad59acd856edb10b41400c10dd2dae21503072d95f2615451580a6f8e3222dfb890d5dbe27e41b46ae2720546ce8947d2e6c8866e7467366def50ac1f37fad5169d263cff7773dbb35f8b563290a2229df50a8df80b2841ed830a81e21ffa07f2435b0652bb8c51a279e60816aed7bbfe5ea35ccc2450eb2b3fb5728bcfdd1e5357ceb26b597bf2b71872231a136e67c36845990d8a959035456032a63d67a5a30145ea503994e4191ec1e2aaa874b6a029bdd3c29cfe5f63c1694a45895bb0f30e2c0a823ea2fd6918ebd058120d24bf33f000cbd49fc7ab310afae7e6b5ab39dd9481695cc0a48eca57e98a0f6edf52dd99b6cb9a59429a51475077307a907d099497bfe9e821dec58885b34dc62a1199ec80765f70df91ece8dd6a03c839ce9b1ecb949cd63268ee59e7a64b0d670344ff31a0d3fe4c73e9e6080cffc5c19cb9e460334199c3a78bc1b2e2e48ba5946506f7a9e8b870e560de892cbb5e41a8ad262c245c9e55a720d452162b96a66686a6866a6ccb2168b8b926bc9e5e2e2ea2f5a0708a00ac46a535b6538fee632c3bda79cbb56eadad59ecfb44be9071757abd56ab55aadafbdfc9801c9e572b95c2e170de887f250ae191a578d2b860ba929caf52ecfb514d3329454f8ec0411bcd4f9f3b3e7e745aa5a8cf7776d32f33edd62209583542c757bc80191595c4e539d5b696e37a05c6568af3f08e7466b50f24d1c0886542ce34080d948e0b404850a25966035a1f90915d0da63da63271858d37e25d39540e6655e93e156503c009fbf04503c003f7b7982811f76363054e881cf3a205eb5af407bdc8f36f39b0e9ff619ae37ae57edf9db88423346d51b29f413126fc00ea73d98b781049d9376a8da62d29e3b92f6dc6d7ca19ee448edf9c6c4855a67be7f659329eb3efe2dcbba8f5ffbd3fbb8c6cd6721b1cec73205fc6ab5f2b195bb130cdb84e924242714a93dc76213047579c1d23bbcf26f2425cf5c9eda9a755f67a9ce318ca53a9defa9786ae79380fe01d37d3ca7ee536d1d4472ee6c0cd18f4e28b95df21d99b70983c6aea886a391e11ac991609ac6096d6ad9fe9d5aa0f72eef4e2dddddbddd0db7683c4c544a9807de2e2a3f90de591f13892641c15ee63faf2148a1f2cecc333fceea6cafbd6927c6f3f3f44ecd0e7d7ede1dcc621cdcee803755724de8d3224f758aa974915cd3a6c970fbe3dc3e5127e7dc1ed128e2e48473ab0326f3098d829af227a1981cd023e8e6dc52716e7150316ebec62fb3859e34de3c2d736e6ad9e6cc6cce6d13319e38b746158339f598266c621b746e8b284e14fac1189b7308f0817e53c6e6dc01686824cdd89c3300adc9e21c8faaf1807ed0b91d4ce6131a0545c5b3a27ad60a9585733d558bfbf313655e724d64ba7ec935a1dd760bdf66b3395700cac5cdc6a43b0b0f1695158fca4f41457902c40a6a1555b138bef8520c2eae2d6973903c65e5886873aee01d9cc4e2e8ef25f848edaf41829eb039b7332305cee9987840bf89c2e65c0b262c9cd3f14d709b7304a89333bd0c87c3ff40f1d7b83dc7b429e0f838c939f61a0aa71ed88d630ebbcdb91cb4051ff4e05df483ceb1508344bf89b339a7faa2699173386a70a0c2e6dc00ba702ea79ab81b4d687c6cbed0af860ad114ed6d4ce8dc0d19977302d887ada453fdcde449eda7e198885b2e88f66085cdb9154e3882b7611ce4362fb5f151eb508ca3f105dd0eded89cf3b024657171692fdd45fb80e68bc780e8077336e70240e96989016ccea98063730e00345a10aacd391c9a1816b0b03997c26f3feb51284a592cae88cce3f03f321d94cdd2a9fe66a22f9a2af58959fbfef321fc98d75638f598a9ceb5f445b562226e716cce97428dc7ada76ab8754a04b3be3d3ba8e5d89ceb564504d89ce3e83c42bfa96373ee6990b02465e1d8c5b192a7963cc553d47e966271d07cf1543f0be80423d06fb6b0615c13da563ad59f718c85e324cec22e14b8078ba3df3914aae909fda04d127636e74e989ee27678886c90406980f563a2130f28d6cdf6b4026cced9548c6b32f3936322a6d21e4fe954bf9c827eb06773ae46c5b826f425c7454c45a66322203467a3ba609a01415a0cef88d5c60bfa4158dd7fba37f48636e0d3de81f06f1847671f7be4c36fde617af89a16398f5c57ad6bafff97d307a8fd156e8e7f370f7ac375e56aeab9f188df577fe7c19bb3a71ed039ef2ab150e89c066dbc58c85b64b2621dbaf70ea0f70e189b9b717c9a9c01e5f7b8bed19b3bc640d3ba09cabfeecec528bb5bba43e85cba4008210c1146e8485d60eb7c44e0af167d1b07be38ba75f7d2254e8de30df30e3861cba97295ef70159beaeee391e1a43d825150e835bdc39b5466a1ca2716aa3470fd3889fd0ae5c5e124e88fb168dee1244ef5735d15eb6c7b9c456d156c75f38e95d1575e4c4a6b5037988c527a49baf0d07d0df04244514a5a355a609dc510c2a8292cbc1861e2c50701e4404f758bbcbc4005197891818cba455cbc1c89777777bd07e70fb5226887eae88bde689df87d80d8d92cff77361d4df1674ee8abb808b63f5175d152151c8a8a54b9010de20e2fb943fc886508b14b0e3b4001862b2a7191c312e10ae6840653d7284912499e4cd102830371050cf08570922cf0935c1159052076eece76842f00156adf50a576078ed73c6ac307e23562988cd371f8bf19a7c296b638951fd6f0135446a11d028f69b9bbbb3b33bbbb4b8feece746803407c77976e7436c18068d105b010e5e66616742bd5b12240bdf26cdbb62c7b53f7e33de53f99fb28636f7a1bf9304fe427eb6cf8f4dadb48e0f4da9f3a1b6c03b5fff43612e663303d8ca9c3ba184e359cba205ac79265475459fea8fd9a8f8f7f5201aa9a71369889b3c13a096c6f83fde989fc642f01eddf068b61c3be86adc3ba186a78223fa66f55e5eefb51650744556568cf67f061ee6ce4f3dbc8ce05acce24b074581d56c27afefdeeee1856dff9cbe6388ab23226d67fb9fbb19c0cfb31b4e72bc38f0fceda407bfbab045b315a051fcc48a23c3e1ac6cfc3a30b4cc6d051162e35c6960ef55bd7567494850918b78a8b1a8150e3df88b2fb9b257e7eac5facd84709b335a2f163e499b2e3a992072e9892648b4d0c7376447ef6b7bb522ca6ae51932c6a7758f74dfac3a2dff415c4000911484a29a5921d322600e580a48909905026a07062d54f7c71021efebf091640a8b6402285d0a2c3115478d1610b0d3a0a2962600458e504592069a2a5dea8a1355ed7a889154e68cbcdcf809d9dfd3d39806de03e22bdf1a9477cc901cd1ff9918ba1573ff297fb4a50bf10c0daaab1f3ee2b410cf4477ef16d1460aab103414c855d13f9eb83aa7a9fe655c542f3d7c10d5f885054b78aba39f0c2a546098f66bc25a32641ac24f9e32f6164057dcc43edb701fa98090f7a4a6d278cb8a27af7b1d26c2c5c8dab803210cebbbbb8b104b19cc548ed25b5d7df37f04e06b86dd89e2dbb535d3c3d3d3972701c8dd861a0f3d99ce6d14259e9a7b99d6ccf3a8abfb8cff6b030b03dbbcdaecd699f9882148a39c675c03b1bf9fe1fdbc82e067ee8e37c54bd93b67648506f43825f4b010a9d2aa03f54a420b60895795136ecaad50a0a0a0ae2968cb0b165a32756b539cb4b9be29f29a8fcdf168157d4abdc3577a94c4434b9b5571ea0a500853a11acb3ed467887e7119aa4f22f2fa9fcaec3f6cce7ef2ebb3337c56f43e5c9df4a73528a4211050505316fcfd3c43fb66e3db55aadf679797fff019bb31f143429ea9b835ac789608f9f6750f959e096f3cfc9cc44ad266a2566a1ee100d910f4d6da373569f1dd42dedbf0ee22a9c72c94e36e5bf4d6c133d3d3972701c0d1adc921dec5848e3b8a5853ad1f6c0f7f7d76a402613b210b77a4a7bfe454de479d0c32dd53f460ff467d51e507b9d05ef2cb7d1f696a2edc1de86af504ba046d002550595c269c81e7b4d4a295fc3ae547e2bb2d002938f715c8922514f691da5a5a6e2de49d5db4b94b0e5cf4cdc280653aaf313db93bdbf133551018a7c9f4062b985663df889ad90fbb88adc42f9e57452a3d5b18daa176d4e134a5390424d2b45e58f2888c8777835dd79c5add841c0f49ac641272a47e4478b5c07606783d9605d0cfd3df810f0518d1c1f55c86dedf721ac6794a0f5c3ca5159541657d2c6e88162bb9caf529042b3ba3d337b7eb66103857228fb5dd230bb4e82e529e69ae81f5a89a0cd518259add36a9d1d6a1d9bfd45d23a41adc384db7699d59e867a42f7d4a36356ebb8bb43d6a232e44056b7d005f2d4f2f2b28fcde1ef1e720be5b81fe887aaad04a891b4cebac01cd81cf6b13dfbb13027a528d47a1116ead7409cc43f27a528d4ffe7f1764db439fc0ee4abf6d8573bfbc395c50de4acd9a720e452ed3a84973a80ba46432c51b5de94e6dc02d63e3a3a6a94114d62a72c22e65ba8a7a8f9654e2527aa44bd71059402142772c5852e872e560a4850fa7209efc415f32fb3b4616510db637afafd72b53dbcf207a982da520719c4e62ce15467dd278be20bb0ee934ac0ee93466cf749225ce82a579bd38f6384d20eb573ebd591efb0ab8196bfa0bec609fde2172d58c787faf4302fabf00ebd82b282816416b55f3e219dec4e5c49a3f8257e9142dbe39b66caa0cb7768bea78ccb559d88a6531a6a1da905c3749fdcc2c8897c2752147b353a510d117465d8546f922bf90e7520fa8fa2be4936d4fe5e6d8f33d2f6ecf397dacc456dee52794b6daea2f6c7952bb9922b05c09536a73fc6b81e520eb2c0d2f289dc1c00218b2bf90b2d9dd48e4ad854b752f003900ae04a87da3648a12446628e5fe2176050a9fd722585a2f40ec792455a678dbe78523b4a24416040513fd94232022308f5934f3e0954fb393252af1118536a7f2cb283fa451e221224107018aed43a6b34840a6abf7b699d156abf73f207949f4f326c4ad0fd4d09caef10908fc3fc99f99898a72fa3c37a0d7b882814a548744e4a55aaae407b5df3343f239fd854bf14b5bf0aa5ba45c21c6a7f0dcd8c944ea4112a0959446dd9fa47a1565f6aff4a0acd2003735e6391f65a0ac52f9bd32fc345256c0bfd948b602c01fa63b818c6b2d06f02a211287e59b9746a2e8af6d2aa58eb6ceda56269b55ad9f0b3c44a11205793fa39abb6890913f57325fda5f6c36521b0d47e9c661254fb864c5d1a59e5d40a75bb1c75bb9e8a6aa2ee6b6e05eb70506bef4af0ce6ca24af52bb5df93f01f76875b9bea4715f1b55210b5df83b647e968624747be33f30dd37d936edd87cae487a25dccd73e6aafffeba30fd68f839edf63a5d78e5ac7ad60cfb1b052db7fe8209f93d25652f220131065a1ae4382a600857eada4a4a198a07bea74a05f077590efa8828e1ec0eea9566d0f7caeada4a41463ec3eba425dba297e5e4e6dce7e9f3a4606da5229a59473e54af98e75b283b07b50d5d6d322c671c58afa8227155279c1120c6050210cb8a85015a5385185922258441942f203ad547845cb912184b8c1d5c5163f108a20c85042b7f20ed3096416355601000b02c1aaf04a0ca290e669fc385ef7d57736528ffec5213254fb97e3f83c1e0742fee6f7719fbee1a9452aea1cf8e112c40227f343082184703e67a6ccb565779ab529ffd9858bea4d5c2bd81d6eb50baad3d4af5932a8fefca4394a7d9e2cd45e2b5b84d94eebce6404ad47726c38438d147600be90b84e57cd1f0ed315e55ff72c4d68821236b129236cc2c464844d684213fc1d09249cedd1da4d0e3388b33dd3835128f4364e1cc6f1f90d1e38aca3539df26a04b039fdb1f3ce9398c4a2d79ee76d4e1838dbb34daca71235e8c8448db1c6e78931c6185315fed60005157ecf18638cd1852a460405810809546cf9899da5c62d6ac46a8c31c61b75594a961c434028e68c188649214241d7a0803c157d67a5e840870844d19212450f11e081d2cb2e2855ab8abad862071981a32f9dda5547e009a04e6d8da927ba50c20a5350d30d01d0820715b878f1c30bbc60b202165e144151188dba454b10a2c2d6124dca0ff55bf85ceccac085123ec16e0e413b104695dcd9f8d8caffc256eeba0f7e0888549f765a5b6653fd348ab8d40c28e8477d053ce79b9ea1474c4e547b0a80d5d4c1d9bc5009e324f562bd39243ec7249ac6eb0ce34f7f08b963b7504b11df414a29e50f5030821720615151855505952baee400042b60384141144140c8a658416b872794ae8851b4608a1e5e43614bc056498e3046080097141900200846528600c011c5ea1a4979c1f4a72ea5f420a548fdbef20c623a5ef50e54edeea851942f5555d7e88820542d46b9c3585aca855a90ca1f3dc98e91e00ffdd86584c414779ec244acb6a2c2671eaaa8f07dc0e7221d42d4f4df9cd23aa687dd42609d3f613f44a9eaee6024f6e13bbcfa767807d3c9ae7321d67e46e21dfdc3e2800f77d48f5d7cc5d57d2aef3b0c728783f763020ee3070af69f10af3aa0a08b650f5f83f1e32e60ba0ff57468534b5424431847da9e609cfba60386f43875db1eb7752bc4abf6262e6e409b5ad60cdad4d68a446b53bbfbbd9bb3b51765377f92be2852fb073e77c1406e6a3f3f7f6b7d6ac23dde0d55054880f3dd78ab03df91000bec7cedfaf2582bf575f8e985e8b54ebf00ab8f28b4b89ec9b471bc9e694d23a830fbc180f6fa3ddf89a153bc43015e60e8f6cec7e6f43fa13efc7df80560e22f41f14585eac1962da4173d4829a554819722546104282e20c2059d2404138694219a8a2a264802bc92859222f1e33671c5bc1206108e6843b8c088c88a14459cc00737cc2956469a8afabd0f2d1e27bc07f55b24a4badf2a1da1a56e171f688110aa68b9c1122d48e2c7b11c61a5ba472104510a8660a2080b58f0e3af4ae1080d848c8c8c5870c38fff0cfe85d6353a62ca1147645a767b365effad3d7f17bcef5437e7f48257f7d30b587517e00bd9e905b9dc524a97129a60fc7d7a6e4e3fbf8908b46b3f991e802350adaed11142d81b1d11449552055a943c95f24265ea1a1dc13a0248059de8eda671bcdef13ac5af52f114151d1d2121c9d87da1df561f7513655c0f821d4542f977773b082184104208216466ee7677a1bb37ef36ec61629cefee32fce973be4318338fd9c4a07c87d9c4645c8a02e5668f2d73df56b185fb37dac389c9fec9e35aa4221ecf3d1dde411f150f8ff612f0791b17949188d062988d8cc0a1327ba89bcd41fd6eaaff5052752f0249f522aaa83b447ebab97768da3069a8e7ac1046201f9610621d01a38a255354f80fb1183101054208e1a90796a37e5b0e8690d0208a2a290a5bd48c410aa0b8e0cb1660e030742503362842020a1f562084112994cc304b99c54e477bce037a315a70a37e5bc56680a562180d84a818851edc2a5b2c11e40589269696fc402427a298004e3a37fac333685529df291d5aad563b1ce105cca473a3d93eb1031dac503f1d15f2582a589c7051e14348045185464418c9c0880c7cf004880a9fc7e7891315be0f1fd6088aab2655da3a271acc099d60590192a7763a1182110864594ae221b1850d50758b8e0045b5d28c8c60c1beb0d59f856ce4b141961bb22fa43d66e6863437ff727333fbe021419613b2b44186c8204286ac8fca0b32a48656dadd20429a0767dbc9757f743e8a509cda36b406d55e3f1fd12bc4c7d6bf0fb70b226408f6dfee90d6599e9352f6b129fe211c7bc41844c8108fa73d5e0a524377b7c733a4756a689d8f37d03142d426e1ec7791cfb055d7263ed728e37d5a4b323284ba2e33011b5a49467e508178980c34b763f4fc966f0f4de5e5d5af9432cbb239b1971c08b03a1f62523a0c1c06ac7c9a0f8ba8d4dddd2625e0869658fd9c60e0971d10afdf7cc871434bac6a9f1c306374b2f380a972c7455a45d0cf592c2424f41d47696f635ed39eb34d487bcb4166e64c2205e140b043b86e0b5c5ea406b3ede90598ff1689b7188eab0d29d4a789ee2e96f6564224ed2d0cea20ab3d56dd77972bb5a40775bdbbefac2f4b4c7e7ddaa769e6b7ab756a7ebf5bbec3937ea8cfe3a11b43083f20f3634e3d32245de602e78145aa1d8043754f351d92b38b9fa6fbe6ce74dfa4b4fb509eb3f6b2fb78ea56f82d1598d36bbf9d7a9c3ade3856c241ededdb9801fd980933691d5eb5b73f817c27884dffd6227d80dd656dcf4cdd7724eec3ee746b53fbbb9f759f2ba9fb2dc4ee386bdfa609f473d6909f1833289d018d988052f92643710f399cbfe1792b6954fb655996bd7c9f6ea19d936ec6dad4b6507b926b26ed2dfca73931804895add6e12a65c74aecda82ee774ba875be5e62d24f5a67c906beb7eaf2903c3ecc25a04832c00717ea4a5ae7e101647436fcfb23e3f77765644e640c3fdadb476a269dda8f5cb7322c5a75f96568cf480333b4b7fbdc7dde02121894df1ec6098912c3a694d23d761edda5ecba854bdaff407dc6d8b967d3e1cbce3d7670c2d8cdb781e653e343b8df8120aafafd00a26a61b98f85baec39eac28f4788ac0e39fad9cc1a5ba8df6e0fef3e8f70dbcb511bbee6de428d1f2b6cd96d1c39288c4125a0220c5457f8f0a8fbd204384cd01d361b6a7cb871c2232a61c224e878f1e85015c173e2068e14aba3bd8552aada833096a0db9768eb1be37f83aaa11bb682083b1d081dee8e7686ee0edd89488e476032bb2123460dcd8c0c8d81396d5a669a37ac563c28254d89c51831d61833bd4f9b30e639e7d6850959c4706664680ccc69d33008fc40a2800c491998c105a4cb15083119a974dca360e3841b9b1a34503364c4a8a139c26225090a5ad26a11212464c4d0901244444d141555393aba828464455252162e97164a4a4e3049e70ca537287884224c663c37363568a066c888514333234363606e58ad8c00011d61b19204052d69b5881012326268688a92942c624f63604e9b86fdf8142dc0c711047e20558007ea42289b586366d6186a52ca8e060d4229a536a1d4349865d9369526f59245ccaba19991a13130a74dc34c33d6d025284609b1a247c1c60937363568a066c888514373c36a650408e8088b9524286849ab458490901143434a101135515454e5e8e80a12921549494a2e083119f9f52f145e365e27bc6e5e36af1a2f1a2fd46bc64bc62bc6abe645f39a79c9bce82be605f33abdb697f632bde62bbea494d2a7943e6334b9c7d8d160828ec5d88ef1438fb086eacf32c687f26394cf9551e093164c663730a74dcb4c533260ca528cd221364d28fcc7e3ff3b00f7df1675ff6d134b2576dca360e3841b9b1a34503364c4a8a19991a13130a7adcad1d11524242b9292b27069a1a464d2dca4b9c91402697a8dddf421e82ae794262d738f99d330db7bcbe0e61daf87612eb3cfa64f475fe218260a26b3f87abd5eafd7ebf57abd5eaf215f6e58ad8c00011d61b19204052d69b59e2879c164c623be6cbc4e78ddbc6c5e355e345ea8d78c978c578c57cd8be635f39279d157cc0be6757a6d2fed458490901143434a101135515464456935a4a3060dd40c19316a686664680ccc69bb61b53202047484c54a1214b4a4d57a22243444833324209df01f8f8dff7a78d838e1c6a6060dd40c19316a686664680ccc11162b4950d092568b0821212386869420226aa2a8c8cad1d109ac19f9de29927d111ca8093c8c307ea0c4c741f50365fe37e99ae69ca1f406857a08461631c905f3bc1c2a158f2e72c5ba2123460dcd8c0c8d81396d1a669a37ac563c0001c5e0998586c9ec690ccc69d332d3941590c115c3d80d3730a74dc34c3332c0c789a50e8a68fca7aaf15f0e9bff74dcfca7c373635383066a868c18353433323406e6b4699c24286849ab458490901143435388888a6cd85484c92cbe5eafd7ebf57abd5eafd7ebf5ca5eaf9764254a4b344c66386b9a7386d21a2854f7bf82e7e550a97a78787e7c8a16e0e308023f902820435206667001d90076b4c264e6c557cd8be635f39279d157cc0be6757a6d2fed95bd4caff992af1a86ac260ab89545ecf41f0ae6bf1a31ffddd0ff6cc8fcf733ff7534ffe1d4fca7428cff3c19ffad30e3bf1ba8ff06a0925c503364c4a8a199e17a78787e7c8a16e0e308023f90282043520666d8b86f034a34045912c1901b562b360204c44798c54a386806674f3099c535cd3943690d14aafbbfa11487344cce68ffd56cffc940c5d7f6d25e3550a8ee7f054f7239542f13cbe70c9a583e67d004a18931c69e1707d65d319618f6d8f27c3c11091aefc8fe9bf03f53fc6f9bffc198fea3d80e5ed39c3394d640a13ac6c138fa2197c734886910c3b48c7971ccdff9b0e7cc76fe3a176fc02e4a68b3757625774787f0e50eddddddddddddddddb0218410368410c2861042c6b1ce45dbd581d07b4743b82b3dba943a107a775dbbbbfb61175386685d232f5a35092b758dbc4842d535f2a2c8b99bf93eeddc56ee36fe1a6817f3dcd1ae06a89d1e06a6b379000dcdcccb3c09683a09c8689d4cb73f9048e537c51334c524787200063f21b0deb4d7031802a5375a68ec4e0dab68b375761f528f54833176b32b4177b300f573a5947008ab1c080dad8290c3135aae349150828014456b28b5f2c5529ce24a500a6a50b4260917248104126134667d2eb62fe1c77d47653bf3bda34e3d078d7f5de030ea6eceeee6f4360cd31b1cd00f35e1eac7dd77329e1f3304414914b7ae11e1f620b07824f49b3b284f39ca860a14109e6ef6807e1e8fd6b9d13ab1759689708344bb0685e3a9183e0a158361ae61355840b1179a4e87e93e140c46f331cc3c8d4cf779357b98ee9b35bca7b29fe9b8209a51ad63de61defdb5a3fa09e98a3dccc7701f911af37dea11f31a9f5c680e7b98a732446a0b8995761d04c6015333339853f7cdb9751fd53a1397753b6fd4ee38f6625454b2551886614934d635222af2bf0423300a2459832d7870a4a3f84f5d28e8f71ec70382b40653f4c0d81596cb1a1cedf02fc591cad403742e3249f7a6e7993ac36e4c4079e3c137aaea0bc0fe7e00c87e46f9180facced5d3a90767ee9ccd1b5e53e1110015e47cacc33887cec59845397fce2e4ad3ab4c3894670df40ab7530fd6d89db9adcced796d08bdb339a2692b6b6b304a6c9adaa3c466a6c9530fafcd4159db9db92f46754ed5ad71a76e9d4f067f3042df1cc6d8157e9dc39999b48dfb6454e7beaefa6b9a6fdb729f7fc3f63e186fdea142a8c44cda688296d10c0000044100f3150000300c0a870342a1509646cab03e14800b739e42745a329ac6b21c4761180419ea8001c010430040000666a4d100d0df795064311ead65739644e40f58d6d7d089910dde5a6450c003bd139a4667ee089c9e430be73a8ea1522c421564652a7fe88484262d4c7de3442e4ef095221ccd1477b1c01742d59e3aa3c6e52e799b1cff4561f37e28ac7fa8340ae0d1068d3c4e120163cf1eea548dfe0bf4beb6593d54af47777ca04379f0fec2dd2023f1904834a15428953881b2ac036fbb044643a4427c471ec9e520e7ad5707e81ea4bb5ba0c62270eea9deb49f2f50599a0e9c6d610d24017d80d3a1af5301defb70de48e57814baa059841ad02f0f1d09b6542fb7009c8d5a04bc01bc8bd6674c5c8a265273a75554ffbfb4fd99a50221497fb1c0cf988a351ed7adecce5f0d696c3c5a6d394f4f1b5f0caab64af889fab749fd56ad7bd06a8b72d83b1130f942ea13c1a34ecbf1812577ca9ce88a0df98353b6bf924231a30d45ba4a4154174554da53a0e06540ddd5bbd80bda6c712eacb2d393e50256644ca044672ac681d5721d57a3d2b36f5405d131f362d02d360f7086530543bdd056e6eddf7109841946237ad1030cc04927252ec439263842eedde300f25ce859e460148ee615029f20850064bd01235ede6813610c8e1b4cabc0b2d70d78539d0182fa1f40e5e7ef2d82ae070ca3b048407507d8f2e7f7f9068c31a46d093d8b956fc0840cd5ae720f788626094a750bd69c9ab65e7b8035c270dd85ce8e1f1576e0f025819324b9ac586f30663ee34bd12d18f376b7cdf40cb4ed162c0d75acb7411c4bb89fd10db699bd050b32b46edfb6b6070ce27a5c241fb61d386cf492097ccc059af8a3d4e4151d119235a768d469e6e1d565b567de6a635441691c91e989be5333902c92ec5e6cd308b17a601a8b6fbcec7c83d96cbb208671c05380771a8d0b0c3fb01ce3f1dc746f70d426ba00501d3f5dec5202669d090c68718fd50413988a3736373ec778e79210a88896951cd1e514514a581fab28c82f151e4da366e94782f3f1cc0644c571be3c65830a381fa0364adf7ce615553fbc65f8f26a72f4d6fb6c8802e65f61435ca39db3f85d08bb1f76ba6c8c3e0712a57d29c52e27e3dfb34edbc418de55a8696282919a75d60a099e5817c4d81b227c19f827ac932a455832c5bf4be1bba015ab1742b8b3290a2e9b9c2a7537624ee69173af4e34ab5c49b99b3acdf78586521b7d628addddc1a36859b8f79b8217b781c8f9a4b6b5827b9a1411aa811218fdc68b5c1c0678ca25b5081c0e3152db45eadd4e8cbd613bbdc991b758dd7a5e765a9b0cd76ba891f5c209e04be9196809ff53ff3f22632d9b47cabef33078b50740ed0f2a020bc8e1eeafe34422364d82264cc67994897afd3465dfe7944a7bc6e2a997e58ef464802fcdee263af90836a2f6456aba9cc6bfcb329d99f17daf7ff2a909b494ce5df9bf31ce92bbc7ccb9e732906ad4ee29a87541ee6d76349eccf5c9d7c0814262d4badc4123a4c6456da52462decc5c576d7df7858901dc2d0dc4e88c8712637cea1d1c82ade48f21dfc7ebb2e7e574b54cc80eba0634f80db44d8dbad324502308500c92e8eef143c24328020d45474dc3a0cc2bd01ea2880f1be68222e47278a9c6fc9382b08621dc09b4729b04c0f0e63d240dad460d77ff87d4595350c42eb728852205a312d2d76990c9f1c8589fe4f5b130e2194834cdcb54bb388c7f977d7a138e3d9ff8d5caeeb69268aa4b9fc0d43bef0c71c3dbcd5f1624ca8388d0b2805287b3f16fd9a66136baef238a7c3280add275d7ef67c499c4f69a30e7bc7f668c2bed1f33779ddbd78c0dc26615d33e7df328ae240e8c8fcf4ce12012810aef8ff1cde2e74124317de6ca06c6e5bbb7a182ad3c47c65067bf7135b1ce697ff70979407b833d413c20ef708f8007b0371c9e8db0f939ecfe9e184a5acd59e91c9d118338d091aa496bc48dd9d280ae2e67272dac33c635f0a1ba7dbaec6ca50c351344113856a3a59b731fa4667cc076c0158307c29479f835bb30b24c4523cb12808b0eedc8e31e260a18082814243048c902d9502516e584269c4fc8e50a923dec5ff2998a842f9ebc68a435962aad1b0ea76b7e793a917275110c2741018cb14be13ce6526387427d424f1e13ba53b4add431c9349f50b3c61f3d8145d6be94aa1b38a8e89213b584e434a1d253546f1617772f5e838c071b9127e40ace55ff197b06f35d83245b85ea3de48088a4bd2c4597f3b16fb3a7c36cec6d56d7b1ae3ad5bdee3ad791f54533837cf5a69a32628daf4f4729ef062f0a7dba733b7c8eb1d214936c081c953662ef163e7f0ef3ac14ee73bd0ef6c2049e1b0bacc8f69514a06b623842675d886316682a7fec877e8fdb7e0ed0eac30edfc049b69a97f05533d1fc3b387705fc2492301889e45595ae072f3c8c7eb33e420846a20a5c82b23668940c50cb45c23d467fb1ea415cba14f47f037a70ee9f8735bc0da0003facb729d6a0d0c8ec68413ee73e37905d0bc6de20c572880da62e3251ffb982d41c8f2e90906532fbc2d2a7d25c6747b0511a9653a66f7ac49be061bed33989e6f61b6c90dc4be5bdc3be29e1aeb4c1a9ef16a63e094e6390511fc83e453f3ea7c9c69d8e1b4b8eb7185e9db238b3ebe78810e2eeb7ad202bcff13112d149f469f42474bea1ab1b469fb67a6fa51577e5b8ba236d484af528b1c59fab24742877332ee36c2b08022aba9cc045685f7e274b3ab3c7df070bf839f6f3aa7f978549c77b6daa1de3baf7c5921f4386ef2ff34066265667e2c45376700089aebde43b96749b8e7fcb4a5ac0119fc22ad2d841b284f0f63f353c88fd675a0f69aedfa8c5f655b6caa866868907981936b27d7f19619686d503d90c97178534ae06ac93a59520ba355be79ccd1cedd67e15497a3c997c443ec9658b23f1b5f79164d52132b29a612c6723d1eb5ac9b8fa9f21e760f1d2c142b937cf45b41e068fac75015587e3e36fb249677e54df3fe83c318075450f819cf4f4b843a55914ca0da4ea296f3f1ff1a510220a5d8ec022b45f7c97acc9a07e477da97c98ae1abe554431dd3ce5725b9888549e545ba8ab119cc04468b444d5f11ddfca9cad6e7c4eb6f3b9105d5d57e996b4191d0e3407e46d068b36518a1d6ea0a3b52f7d87251df3a36fb24a03f7c5db8c5c6302b94aa5206179293f052dc9b3eb7aabc04b4cbb80848953ed738a210d7ccda514ba9cc1476f3ee61d96f4ddad8ad5514f76c840e205457dee2ed0a9479217e90e66bcd8c31079dfd0bd32111d8208e3091f20bf4f6f4332f128b596086ad7af5e09de29efb4e7c07e657f098fbcd34112aabe7b9fe07accc09279f643e3b8541f16f5ba4f32019bcd54c1eb531607796c2d789e33ec72c23216461ffa8ceaf9fa3d866307c0a8f6e8ad6c5a0b1de239f2ed0d923623fbbcb1dd3dc3ab19e1a610974a85f73b73ea315834fa5a42b2f7f88eaca71d4ba180ad2ad6c5c77d213cfc5d4a8cb2c3e633c4f38b0f9052ec8ec2fa0ec23087d612a77d41a8ae25706f71d8146c30a9276ff05138c6b008cc40ba9bf70f9cd2bc6ec67090291a34232045387e6d696d03b96703894d074ec635d0c15fc9cb736850c7ff4f6b98685ccc06e4eff2dd1026323aeaebfaae06e2b6633b998790b4bbadca9fd68700d9338de539cc53839f6a9a8b721d880bd8d9fa196dde968eef8e37297c57dbda24f3c4def97686c7350027db4760ee218dbad664b4c05b1735c77cbc73b876000e0dab04e5c7a3b34a60dddbb1a60214d874e29bba9155e5cd1475faec963ad9889d4abcac18a2bda43ad971332e3cd0f961263b155b63b19f6689acc082ec27d2b72a38bb609078dc85bd576045873172549ad4c600bc0e1706b5bf3426dc6ca74812025330451d81d8dc643a16817af9e13385942e3c6c0de4302501a43bb027fe3d18b6e156e19aebfe6b0bf6e3bcfd181cda0ed654b92a432ba0ffee05f613fc4bea680446ad040f6d0a2ca458b65c050769f94b1fd0ff492b6a0b6fb50ef3bd9063238646f96ae75a893ae15709aad73aacc2b8a7b8fe44d356fdf879ec319ef9985ad49e17cec4538b4e00bfb2c3d8495d1480fd1f1752767a18ee8459454fce06c8b02450d6dcf50dac32e951453b0c98e1fe7e2e3de61566cd3079f4bac8fe404acf07237d0406210e2f7f800dc2534ee689f48eab0fe0af6fc8e60a821759fa76383dad01a00b11f260b7cbad6079e05eabd455f88e608c3615ae191cd60727e7de3b08ee483d60689edf9bb43f765e7e0c47ffd1047d13dac247f1268d2c8e17a765d6ff48fc1fed4b3bb443605a5ee55b42d54464497785436a0f74fa4669dea8b3921012c73af3327dc75f82126a68fa36b0e8b059e0de4009fd6a20d715fda45227b9c1d82e37007702c52cf5cd929535a777269869596a7766301d9a734b98e9a8c8701e3e1711199a014feba06b91cba96b9234a97e3fca33b91d122db83a8d142202854ab2a3232761483f03f31df63de5cc63b58cd8b61252b9507ef8bddb540dc9d8b776b8b3174dfb65a9d626ab4219b01b1018d9146f59ce21a0e7e386986366c79d2552b165518b868187328943d20724055a8b1cded27b78c287b9494110f2e8abfc61794176ce0f999953ec14992ccd6cf66c85b5ffd798751f23458e4c177ae9fb3c30bad18d0ec743b40924b4a1f2b6e89250695e6d01935e3c0dc9ce3f2c61b062e739390cf475be0eccdab1655502b070949a5f499d59b9ac08c19cdf28c1850e5d2d072bd0eb64c442f1810fea0762972bdc05e69f2dca7de0a19b63f62c1f8bad0b49ea1be7c963d85f51195ce9f1bd0aa38a80b89c22216d3e88e7012934b65db8af45671f79eff83301efe623453172d0ba0cd103319619761f18fc4e34707d1358c32015e5b58d2e1774988b84db402d051572d3f9497e57ba965e3e3cad30a43a1f25ca25b43901580108d3e6170ce01806ae1a09ebd08a04b3e1169dbab9c1aff4cc3f15fc8e5e0eb16fc9ca8d0cf9fe54a5da107fa6daa580e007636c7146ebfdc2ae45a23059b58d90f203b48680743b458c6fa916e3a368d1720cdf07855e13bd1f53e9b0853754827d16f96e2d2809ab3cf1bef14fc37c0d36679f5a0ffbeae887b99a3959b64faeddd853285608e2fa0c9bd35febed6fec065e0d983cbd8c187924757664a8a1a52b2b8239682a5f8d825fc5d821967a86390d3f67f8587cc2a46a274bc406449f1052635c7680e4e9e36f918cf459759ebe40f5cdb278094c7a3fa635c163f922471f31902eed7d9e3cde038abad625f7da1ff2405cfb3bfe5813747a1607bc223ff872c27663e9c8113ac4b81c569b8adb78072b471bf497600deaece3631666a400f9d1d4993bd3ba4a98d7598443f529d7b2949584e26a8740af14e66aeb2974dfb2908a269e07a87a3b6d1910f956deffaada1417e463f4834feb0eba9bc4e7a58344bafa5de615bab8fbebd6c604a6c28f82923c423f7b18ddbb6c0d221a0839a40a9884d694588150112893a8a72f7c1b4984fcc1f0b666d4868b0b6f46490710d47defe952a20bbe4d46929a59086fd39989c6ff4e01f33775112dd31f0a1c6b9dcdd8b1e40c4aa7e3578ba4d29742bc796cc7fff3dbea996345ff02b705e253a16c7400479fa29d257c9024a38eeff5a36f386354167a59e86e7d04bd74238bc3fc1c020d8ef2eed09bf0c5ab03ebc5dac26c2670a53b3545997577faa1e952be4843c1d474001a87bb15bb92d4b919809bdcaaf77a2427b0113d4248e67253782de84f09487167295a3aa038e9091ea44ebc09b7b2e963b73bfb07312b55255e0777fb601fbf2ad561399947d7b55b36cadfe8c39eb7f07a606a4c348d4dfb7a7fa07c989f72739c42e096be1e0d3c35525f4799d89fd26273a32b7e1f2a7e01a83b7e4029e125218276b6e5568d97e7d5f78c449bfad2b66c991452890e2ec07bd555f5c99dd50e59212de51211af6cb6827cc6f9b17381056e433a18e4f3c132a4c6fa4708fcf3078143f80a1559a6d8b9d10a0689f4fc61425db27380b00e6cca6a2b6047de0ad42af6b6b7dd3adff083c0360a6214cd9e984c8f0a48f8bab19ea50a2b93d04bd972a3a04c05abcaa20e346732c91b58a5944c1505ca36ebcfae15ad9c5c0ec3f3cb6acc271be14d2927f4afa1282d5fc7673887d6c08a279152ec4292fa2a7e6a99bf32885ef541c4fb45c9d15b181c8511ed5c9d4e44d8b656374146cad1bd6c602b892a816efe15f4234266ea2f44d45a8abd90b06e54939d05055bec508c5b76017b815c893115f164dc0b9432d6417efbd137f214c8b4370813d997f26f2f0e8c44ab8ea402d6defb8d32c1879aad03afdc204fa3b03a8ad00baa06f5196b4e0cf582ba8e2c110856ff46edd4e524583796744266489d9423e3782aa9b25c515402456613775356028df4b348b77d9fab9612c22285022b40352346627a1388015821ea8a747d8ded86809e215402a9017250fd61b106f216d465a4c6e822f930ae7f723dd1c57a98dd91bd0bc3a94b7d01560477c0846323eba415220177449bde08ed83a2c3504e52958936ca2639b5d8e6a71ca5669686015f1c645e520dafad39addb64f3cdbc510127c4e495b55201d0afc324cdd87093bd90b6f83d0e0404a25d82dc0ec66a1bf7b601f80f65bb70edbd5edfeba657cb077f4969d7c5e323f5719a7bfb8662ac24996a8f4ff1a8762f057fc9211fd0cae983efc840ec734e605f5e6509629b18e64620206d58253bb22bb03f480e42ab31a796e0f5c1ef57625322cfd184843e6bcc2a34c1f58df7222a7c3790433b7b6cbfd47646155e420cdf42dfc1a27c366d1293ad92df4a7d01a81cfbfbcc98a3de66d935c8afe64335bf1480a8af8d443af41b0bfe830b940a718fa880fc74a83a85b7952e907385eef739858601124a21e0f9a4c898b21e04eeaab7c59315e9f40da080a04b94bd2403714ee0caf44d35319f9ca87e1a6bbb5f7810a100f957f95485e85713654d9fed3233fca2ae425c10475ce586bfbd55db18562ce13e57a293b11411363781cb950e8e70e38012d6c02e4f06251476c14a2a30e21f8d950860e20028f8bab834f1efae6c6e81c0ec8f4c834273398f06eac1a065717b58410a03c109633270851a1f7636684415fa4cc530efff811b7e2571760fb11ce09e797d0e599012013e376f2e04c6c68d47cf077ad701153f3ea2fa478348e50fcb2e05a1218e862bdf9616d603a8fdfd2adff361b9fef6f8b19edfcf2c1dfee1fc8e86ee47573d83ac16d7c871877bce5751bf1fb09948bf858d43d70f96347b052bf2054008810e84037daf658b41a34c7fc8678abb1b11eb37b2de8f8389e05bcf1fdc816cc736219bae92a531fdcd671b2ea485b6e56463d81ffceeaf34ba5062eb537249b136b9564b2a83373bc8e934bfed3d8c66ad83f0e5d851d6cb23c18832a22f4ef93e2641ddf13c8791f06cb2eb2017ae72138f89fe1c85f2e57f2438348e6999c0ddd0cdf5438622640b6ee30796a4b4d4fb517e425b1aa9de428eb56285414240aa00a418661b5724124e29d1f08af8f6dbc8e834f574e6c085950342ca7209794a794e14fd583f4c807860e87029112a7c58db8915d116499f0af0a1cde3867eba69ca6fec51a16c8bdc9e750c35181d4f7b54624dc6692a9e083ad55f69109ba79b2e5a7c8706b0eef5df4ed13f955833c4d9949e2e0d44894694540fff8cf50e253a26f4c094f4a176a162a8ba2be16d894b1c4dcc572d01e04e8d3fa6c19e007a0886600ed5e5228041dea74138ce05528cba891a70b935ba81b208001a75e29d2736b124a85a6ab50e440b147dcaec352575167876bb07fba9e06f3390bf2e46039aea0188f8653456b810805cd2dfea5fb7bc626194c123e97da879e63bb3be3b830c86661dbc29d29651e32fd9ef156c95128652ab3a47c6b5fad20fe61d18d1220bdbf6ee0dedbcfb5f549e765ee92eaa151908ef72b29baed959920547f96ecf38fded3dcb668c9c703d66f37efaabc092fdb4594b46b673589c67e4df6a2dde5c9525290f9272ccc963edc4cc47133888733c4bcfae643754f248e984f476e63653a7623808c32001a191fc4ede45b04afa77da9e2524d9b7e62f44bdcf8820c421022116874f40f2338146e3137be335016a8271ba53dcbae0485fa7a147dc45253e19c2995fb68b0385cfa8ee0e7b51b0075bd75d651fe7d3ddcd948edd303d9dd149c607b32d0a90174e7fc22f4828b0403040a1d602dc520ec239a1f6ddf523322c9fcbc2ea02585f92dab2683442d7fc519df92e6f0b0a4925c5224814128538ab53962f56acfb068e00628c54edf44a2c23014629036ac7211e07919f61ca1ec7bdd6d8cdc431e8a17b15f65268d5c5b46b84bc09706b708f62613b480bef02adc1b69a6d5bf041afedfb1015a439e3fd36516eae779024b7e607e1162b1ff69c5cfbcc25210fbe20257827019ebd97ca25b9d8c639c913c715a18636bffd41acac736f050da63012a53f6c1bc918b21b064008b7c952b505e20fdf3e6ee9b3487d92442d100326ea15da1162c12039e7aeb3698754ee526c182ac4b327596514a2dd126671513eb609fe787f0c98e03b048881f613a66cb636ef4b84e0d4066f1608439be18e23e60e42ddc1d423ef57f7094587c682ef243319eb1523482389fcaf2eda2e0e9a635ab67b0b161d8c4612ae2a8f7a465881762b3bdb04203e209d4c3a5a1d307d42af73016e1c4a47140d305e5d3d32df9b6780e7f32a5b7b7532ed50614b8316ca9187ff652744db4e18faf3658f9dac1000d88cf283a3fd0e5d6ca229599e6aaf4f8ead73048d5c0803e47a5516e8e80defba2929ced244a30f268398d2e6aca80367861d605b2b6f7881fbc4bb86d0b6c03bb4704782251d3935d398863df66aaf9531ab00649afa44bc478bde633e739abc7aaecee9387af290898538521e1e1160f9429f50769daf79506e85f3d8187c20d89555cbb5c398c502e376a80b5a5d8f853ae59648e99eeba0672e121da01c3f72783de68543eb9f24feb5d9dced675119f758ef2efe309099d5c33536eea5fa0c5960b9ac90694b498f4eea9ce02ea426d14a9b1bcb9bcfe8f743c69175a6d5f83aefd3b8a60d932c24bd6bb1945dc905949138db8b41f2da228efe3e7ddc80a689e77d80398d4b50f1a414ab513a3f9abc133a91623d6d20b8ebfd2d65d872291099a3fb4c807b087aa0c1902bee1e3501cf16b2ca68898a045e3c70974da81b4a0771e81bd8e54cba3ab409e92923b0a21a569701e95f800d2f061c752c3abb3d8debf906bcad8b952344817d84a486d4828201d84bacde7a8aa2948dd5488446ed65d34c3747b3631ad3e9f16735ffc227092f697a856f366b8014bc69557d6a7062139dfcbafc5c7b1c36662ce66ff97d3778d183693ecab98cfbe941602d6e3c60bf6a9388147a45896e29d4925fc7e12c72d32a25b5b256206640e8fbd7224202e584188f52ac593e13fdc7d4a5e81337af345796bbd65894e0b5e86c19d9c8bba0663dc6bf4a4663b167bc14592577c803916b0d4e2467c1a2d12ac1463744b18af81d28cbe8f822dd51c1201c4275d6b79e3acd08b00f475003057088abf5fdaa30571ff0e62e419c8d086994cb5163abb796e86943142a8e622a6efa5ecfab5041db15e26d1ffa69136f7ae3bb9eed26407385b72a02e81f3a2daaa6e094e5208c38a84624c64f80fc81d7d9caad4b0aca4953b0eee10529b4a4272f97ef05b49630273dde627f6121e39afce8e575917826fcc131cf113fbeba77f2a265f3eb38611c8a5418bfdbd916cfaa06f4b95fcc0ca5d1c6e5bc48cc1e5d221e3664f098c008ab98cbc929299bc6dfb89ad30580cb2d69830d9a885934218be71570c08f8aac52d4e32de961368063aa7f72a913d98ffa0e09c9d377ac42652ecfd29241ee6369a7b3f4b167f4d7799ac227378aac77aa1c431796c6cc27a422919556157f6f7e7aa17aef1d26239afbaa735b7f0d4941546e6e0bc27bbd4b848c2b55e3f7b7bd639fbc31ffce601225043bc09205b307f020fbf96e734a7f9fb4919dc3c30f82b8b63a35c88b6e007f6f82ba89c30d72238288599711e000fdfd84d8d05ccce8b02f63a5ef4af63764936f48a9b443fc621cb15e439b6043e98eb58d7d2ba85d0ca354025c35524c05393588c75d4ca621ed4f66197e893b5c4e5b04b9496ea94334d32c446d995da7c8d59335a42c5a0d4ae1cda57b3c3b5b6d2c68cc873e056726b059a22e7435eac8a5889bdd2d456c6bedfe386bf519ac9dcac4740f7724eadde37cf22de3a243b3ed97a4fb834107019bc8b97092036d60095ef0eea350d29cf0be4f1e6dde1691453de32a5469d2e675f91846284cd5ea828a85746cd7346f2f8426a1c19df7cb0815d9e9d35290772034f21c756f88d5006de821cae6851125a5da3dbb48b8725fd3a31a25c3195c2e8ba295521c62e856e66d7b68c3d232e2dfd4170939f514605c2a22f3766d52b5005b92c11cc0bf8acce29789eb33ac008f303651b3ff7c645650391f46d4cb1a87a743c524c5842490101eca0a0b56eb74421541bd9f0ac39683603c50c99efc3704c9bea057ecc451baa944b0822355e3f59108a67da51103337deff97dca62378c1d07f17393775e3800100e73e5ff1c24bfcada77d9fe10226546939a9d4b58d995fe679981f0533832bb11a9dd3eb602c7f65e3d35cb15bed3a6e1d8b11e1aa40177b45ed3199edd77e0a2efd584996c46a8913c6fc8589617fdef789253f9279e76c161cbe4d3a8f439c28cd963cb8163fab40b9a0cd8de13abf7c826040a5241fa1a8fd1324eb40906f1f40f9188944362e983d39ab89b87d622df8b32b19c1dbc4d97c4fb9b4cc287ff50de6ec9487bfc6767b2f1b781c853c9f139e1dcebe1c1d7927514b68eaf2b0abeae8c442c775a20598b91456910c819132d19b30fdce330aae2ef32a90db888ef5e09fd5d747c5e54dbf130af6c29677c120ea94e61812530b76b1e60c6dfa31a3a4230c36a90fbfc8846bf932620e3e28c4e863b7992012014668cca1e7346d593a8ac436de93830077cf915f948917d0c21ec2511d831b32ecb99c77fa3c8bbf8542b01ca252d179aed4c24109a2bba3fce9bce75b80f13a3ddf96af9094e3157edf29411e677afe1127188f442ae59a6a5d2ed26c9cd0ba8d9ae3560790e40cbc829b4950585e97bdad5b3908e9a4e108f6a3274fc7915677b74a16091904c21b546bb01beb7c3fee40c8b41ffd07bca9a1187d1eb35cd2cce60b1cef23d58618b255a12ac6a5f0badb9af5abf40bf5d0f201b91b4b9cafe4b0d66c60f7146a6ee25ef7f750a81d6f935027d00ef70e9f48b75d800b0d305db87b8d9e39a1d152fbd1abe6e6dfe0340c70fd2887af99a04a36f173d5ee7210aaca7db26727a5e5e261dceacd56ffcf3fc2038d07ef4a93c12699dae49de9079616e9b38dadbe6bd1c3bedc967f150ef4f02783de16eb8b74121287049024fef877ebd8de1682faacb7962a8fecacd5370bacee8c2302191b0fdef9a79d4a18cbe5ca5ef3bad66fe55fefd8d9dc35e08e8bb11ddbcb9bfbe9b122a6b76b8dc66d99a064f26faf3096a4de5465ae8dacfdbb4840f9334475b8357d42140802c104bbbfa2fffe827859ed650ccbcf5c7dee37b288b34158a355889067261faf5af94d6d2e2cec9caca7edc1662e68a74fb41d9d5ce39fc9fb38539b89e1ad71a7fe2d658385463eff43d63f106f2171c92c559885af31c0ab7ae85a8e031208e899844278eea1d3da9aa5e4a94e8d9b73549ead2085088f13bdd567e1e2e23923072ab76220881d015e3fb390687449bc8ad829ab6286823d18bb8440dbec107c72d15f281e316e4c0548aad0fd8e9d7e7706a427ae31db9c2732d4cfdd671cb99d5c7ad6555f9f583a60930ec2da44dc5423637f9a3b655c284b8269e9a0fd9e446096468056e7a6d598190398341421726f366ee0261c6d0ad1203198378f1881d9ffe0061319105af7f2f9fe91357cb5033999c0c0f32496a4cf22878368556c146eb1ba76433e3921bfb36dc09e1fa738ef170a634a64ad9c2c93d485a7dd7d38a0895d936e29284af993f425c224c3c22c4916790c311bd120eb970b43307cb9273c98501ead19ca024ddca20ed8a78b797d4b164b3223f8a33790f94f1daaedfcdf523808207e8383cdfc5fa2913507d176d1630a08b2f8a090081c41ad355ea28606ca789cc2aacbe421e13bfffc564ea6e245acb8f7514f6f94da50b60fa95a3d256697aec17c633e1ab278fb4c4ba3acda78ffdd628cc1277f9432d2c681419a8973500ab4ded261d4b42b3edb16f4198e89302822bf11727fe79a5143b43d40dfcb1ef38a6ad491a788c4bda413bde92ef99e44604db7fde66a0ef8a3c4c3a30498e5ec09b2a65abbd1c10e906853cf88a05119aa502b8f8fd03e9647c81e1887ef754ae16fbaf6e387db28643b8b66a4e9e7faf31d087f5e1350257bc5c802a07998bf666a33fc3f60b28d9835dcebf8c5809e622378670814c30b9dd457159fb26b53e1c95e168660809b882ddc1c3d4549288db429866d34c76220154ddd4ab9e5596c13f60e13cf96bf5f831737c841c40aafa8e905cd01d7ab146bfd12aad52c7a685d8515377ebc87b2a9b1c3e6a93e0ac6a54d68a86260ddf635adaf7b09598a7d21c060a04e0c9273540f449264330a1d8d3f2a33cd214b7d4b76489a8eb05246f31457281204fd66872eb4057ed6284e4ad0f8095c26b3f54a17ebbbc427c68b12586e5104ff44053f4ac1f17aa6a8a59a4567d7e30b5394b69ac5dda4b22ba27d1c0251d2e60f627cf05e2c984cf15f84e0a9842896dc232d1347dd9a1fb0cbf58c2c039258059c52731179d1fcb8913b1c1a158858a408172d333c2f894e7877824f0b1507daa2733aaba1cfcbeaf786dfac0cf36624f6146a8173df41f0daaceb7d50e5dc2472c079d5adc8361313e20d8f575c031ede05dddbb7865d982f272dce26837d7fb61c6990e77379061ae6ce5b9fc9f3355bd4ff9a7db73f940fdfe0eb48a1152e89c4928723e9edc14bce90b22779c1b72f36bf24856720cb33f6a809bc9d2ad421fed5227bce558898c88f3f23114a453e7af0b0a760f9483396b571a37a4f255037ea0b2986f9a1f398bc80869d5d7d1de832cc72a10645984cd021c490e97306ef075a842a3791b2ca4816f3d23733ca16e917342c1203d8c846b1ab1be32eafe49924c8e1b81489d892215e90c59026138d530d1577b2f8010057e218bf92446dd05de7d6b9678420e0ffe060cb9412de06edc13e639d5a655b08ac6e3523aadd118ee1b108b5902e9f0cd94f59f9b21b25abadd84112b91a60ef254c0f394da418e64431e6eded88c865a976ae8b6332b92e02c324ce0238aeeeb94f1776b98401f04da5fb7e167fe892753678f7bffbfc1829c2ad70529723034e1bd36b9ca33716114aa3b90bd8c13b4fcdb9fc8a0235715a1463a91d7ef8814842283b1258808f4ad671c0e7611d7ff28f98300b79b63e266b7d0443ff9c99f7ca59936cfb22543b319f4ae0f8612416d7ee803b04c63c275d721f6fad0b60dc7a053fb11c72e33a78424addca64160ec17c71c5f0094cd63d2df90d565873ce629ff1f0bec2412a5253932cb1f931b36f566f757061fee36a8b4c4548793ff9e71cf318743f4a1c9488be3994f7b7e86c6e1281db3e77804bf2c7622474d9d9c4ca648988fed0e6d84bca4aac8479dcd701568470bd61f0c0b2888a1f23a35b559c0b816acfd6c1e53b892f17b9ecdb8650498a2eb11c812c800ff12a02b563beb2ef9efdcaaab337fa9572e92eba5aea0bad4877fce4843427637b7fd88535a30829795afff493e9998b5aaae17cbb6cb83b561a84061beb8619da0ca7a2e5142f10096d9890c65502ac423a1b164c23afa34de779d0ff0ef6d883f44c9628dab15b6d5dd7ce05118633e841f563d65ebd0b2614094a2e1b0de1f9c3f230f167c8dd67e2a20fe7f90ddff7b06f55b7462db05987eac44bfe9432bff0133585b7494c9a4c93b76edaff2e6d22a0e93e1e9e1985c9f8dda50822ae7747a8ab46ba238f438985335129a133fba59fcb64e969414be2ed36efd293956e3c89c5ebf846283b6a2d78cd2a5e3858e18c51cfa4255a0121b4af12ec4a3295fe949668d6907f7b5f0b9f9640b239d6d6367073680ab93f2cb1851ed0aacb307fe3145bdf49df5fbd414e3c225d645aa86c26f5896f1d7aaf13cc0a00cc2dedd5d3453bbba6830d804ad401b8fab7f6510dba3a21d65d5468e1107a7ddd63c06645ce6c7f89e82fb95439384811ad02a1ef00f16bca32421490c87f6d3d140d1ba6234ff9a3b74e66e774aec2807fe18700587a5090a6aa5f0f00e868f459d93831af24186695eb3c33d68cf6df43d2d3d1bd6f6420f1d7ef572d8e5d1d60d9f5071ffaab15d02417b4d6c94ace7a8246fb6bb4c2d45f04ec2f44400dac6fdc84798834340191dc18b137a836fd394798eed4ebfc39be3850e33893de7f928deb834d8cfa9342e2eb1250506f0d555007098d0a21cc8e4e3a636eff171ce4160a842f925ff50c3b1d257d699723b3b0d47225b092139d06c9043b87c0bd370d17064c7fa9b35ecfa6c0acd3aa3ad8170850d3c9a5d2bcf14221d77378e28dce1070af311c3c5a72247d9a43eeae38c0fbede23f500cb8a372df5b2c6a1437725dbb82f94dacfe713b8854c1607ef473d8b437bcc5866cb10a8bf9f7d056e6501d2e89ee8b52546ac2c1153f00b7a765eb435eba65bac805fe592142aeafeb5019d6d0f15a6730ce85837e2a08478c2dbef608b0c7912667f3576817d187ac4a22836bca24addffac70c15cce5604b0d7749d856cf75f7875c50b747ede9a43d3878708283283bf908efb14d4544ac28e96a7ef042a54ed91599496c40bf9fbfeea1a49c7760449c5d4f7008d7224d4b3829aac6b55a3f2295966d31821e20de126a7bc34a17d65f1db753ad4868a847c95a79b6d1b037ca9403f12639c5d94eac2e8087b0d302f914fb068290f77be34a0ead151b5e673273b54c0a986c85101d3616387644d3d535905e9baa83618092c54841479a06043804e081821364af4a5bd7151e77606ae4756e415a6debc80fc31e0f40665cb4521ad0eb25f09c307687630652570d83defe779d94d8bda202dd68b64b7f64c39edea7b911f58b975bfbc2de1c1ccd55bbd5c5d98b3e3a6a44899d4733dd5e73f5091ae98d83cce87a252d710a63b68b6b4d738e78b24b4413463850def2ac43fa0a87b9fae3d84a53df24655d86dd6a367f92eec4f52a2dfe029bf0d39fdf1562f38419a95fa3f1a9cb44d35b944c02b499304de70db1430a535522898b77eb812a54d0a8bdc3eb5c07f12e5c215def461a268a01fc77e2f3d43ae5daaf1092ad043548adba9db475f903985cf2075e1dfe217d44105466f6f107349c0290aa4f7e2f5d3a1dc1c8fde1ca8c79332014b6cc839bc05faa9e5405948cb91955c07e00dadeda8f0dea0a8e6cc6a6d93d20b769821f5aa4db2c0998f274583e6e5a648eee828a996341e1497c63118aab06c06c7195b80aacb62d6be6e8a10fc50ca56b9b94ab03a3c338e3a16be7aaa6b3d385bbea89c81b5b907a0c8c2fed07770ad3b1c8390f4c1215313e6981235160fda3bf0f46421b834856c83c6c42a575cbcd255cf4e9419f56565647bc1406f4aeceaa601732585496c4d0fa05b221b55179c211b90934b756c7c00afe15894635538d2267924c6c244a01bb536e08dcd1b35887db3d746dd7bc14923b54a3497da8637dda356beccdc18696cf58e69ab762792d874aa1e44c5a8dd577974d1c667f1e8a0aa72814bca3f937786b74a13198b9355606f8b11fb174a8b8b2d9c81bbafe90bebec204a3a93050328eaa3285f2f056199597bcc353e14b308bb5c3e22d91edd401124e03727bad236899b8fc26d0b51dcacc2b0da9414aa7683c3af2393cb106ca6223d4bcb37b77706a31bff303252e2c015dd0cd91a28fe85a9c28391e988ce70827c1db78ced988d71963e3e6de4b0588101375f33b79cb8d57c09a1c3637663da52523aab19532c031b883922e4ef836f34b515b3dee861f7907fa04c0cd4e083d68225d86851cb9f671c81672804714a9020acd0ca0be4f9c33eafd9286b844fab9c2a8580b5f79c7ed7992bb34c19eb5ee1aa38ebd620c999b91ffec0902d5fa933c47667c0628272ff3e9d58e623049ae0c3caa0f7223a48bd647a58ce1e95a62ba21b7505121cbd13411982ddf338793177c821ef7e2454dd2180c7e968f24cf53efbf7e962f769ded72c00c7312ea2dbd47ca95ca1eff0aeec8a8f331bd7405b44840cb0ba3b0cfded40a208730fe62e537c99561714de7d4f3c81e0824d7a045db8da8f9c88e1114a9a0c97e1fccb7f0126a95d942350ac132157eed442117c22cd69487a004c08d03eff97569e18adf23d2b54dbc924433b6efe4e20f42311ccdd66943bd5e31db7d4b1052446626486800a178347c5475274751719c7ff66073d2120652cdc9f1affc2a350583ede431cc85ec00dc441a6b529592a8aeea99047d257a05744f281982f8178c9a1364e21c9dd63fdae573e2b47f87b138a4b3597377a507e898492dfa61bb255c40fafc8bd9349896abe0a08b191cf1adb21432660a663656c53bae3b8f7db657878b2bb2d93e62ea399aeb6f5757e775b8e7fb3696da882d24d6f9465f1566edc0d2d6c08d2cd1a5dc56f30f9c47f78fedbd58d09ddac40b279026d513b7f9c1ab721dd1f8a6835218b0c62d8e03c6af48d530d6ba7c74ed3f11b51ac0b9a8f319ced2cd2846b6ed308a1551551dd598fd2f406e8731af3a8da3dc6fbbed744e4b22b3d73d5331bbb7245082ac9df6d72fd59db877d9b8bd442d0f671ef0eb2b872439c1eeb6b92368c52b662536b1e85645705511119f00949d5f2890652d1a71d5457674eb761b9d02657498f9b9f7bd8a2cf1cd6b1d5b45d64c00c7f2be2e546ab6e74d491898addc3e762c4476cddd4e5711f5a4ab6153e333204faa185c56c2a81628ddbf4004ccf4ce649c120d20fa33219d0196dcc0c7bafe2e34eaf327171a72a52c93528559ccc5961e1d502b158a7a701114c47f35cfedff455c23a67f5de66887b46bcda187dcb46f00c16e2225e88fc9fcbe5667a0676bbd527d371bd08eb4abec65801c226e021da0e0526dd1882755901482e8070572a43366ac23da5a14bc96330afb604b5367f64ac9fea96321efb0ddad7c329b3feee015b6a668e4473aa520c94ec95d4e367b50fbcdfcfd81e173052526cb65a34aa748476112c0c25dd60eb7a532d90f541bb948dc26018f4443bc714c6e67c0a18dacd5c6141b2ba8cca6bc820658d6de9523a8a42066fb0b3b56eed8f9ddf2d3735f87fc49ed82542fc2f8c4b1b71b1ae93c62ea07f1cc052c9dfbfa52f2f180943ca05feb7d5dfb04f57d4de9136542f9facb60af908e6c4a047496bf382a1658ec47d3a27be7027ec8555222f9f16dff7029983ba3bf0e99a913ee6f98ae03bf295f86469f935e0c0e89658d116a697009a0ab5a99a7434d55c25a770d4b57a741a55dcd7ae33ee33e819bad15413789fa3f1a6f116bd45c9cfcd8f0de0fe6c71814939633b8cc3bbab36ba416e0fc45a5ede806620506a6e5e222f0eae213c7e3a3a359fa4354a6d9e04dab5ced04bd140a0ed447f9ca458a9899933495f0337ae057093e52ad9aab05c6e4e161a540cc70e4f24bc7140ba401b836897e8651eccabf4fc3a1c0c829668dbbfc3448dd5cb20575753e7b1fb97a098386a10c9fc551021eb23eb681dca3c440b98b9bdc80723afdf5f22bbe5989755e2129648133ac04c1975118af613dfe9883d2982cfae922a19b44a875ca75ed3f5b92f704a2a0c8ac787e9f090f1b0c6f66223985544b68a5696f2afffd15601443e29d2afc6d9ffdb4f32b67e4e8720fb29102cdf4383e58ccbbafb106264e5a2fe47ff0f0e573c2e98b849a9f1b3129686a071e9b57540cbad68dd72e553dca204ee40ed99e0367ca45e42ca058f9c14da69349c183d8fc49d8236a0e81c9daed7082366627e9c95f72f67acacb320ed35c915d1abb8e49340e41bd3c04cc591a115e1664a9b6d8397097d9a6622a7c60e7869194589be5c0c7d6f0854dcb9f535625af328875c6266c3c0ff3df818ade7283bc1aaedee4b29e90666ccfe4e2b0d451f0972105ad695abde4cb846bd99573060701d477496c20f5c8a611cda86e46e6194b8b2974cad6b5fed3af15df6447fedb1922d54f71e325e7f27a8303fa42f60c14c6caab36ec22053599b1091540235472e37e774eaf461a4a64c54b9a482629495326b53b08c825e0d19a725f14d12fa7e2efac47bb2cbdc598af68f24e7f338c5d55950b2d47e09b6037e30247083a29038785da56134b57863725531cd427c13af0298dce83e68f17d13a85c2e28fe7d34a05250583b1a4732ca0090be652819091c161205f7edba145eb9f65351a85ebbce227e9aced84dc34de4cab1af36f52a01f287f1b8d58f35a17306270a19c057809e24ff4b78082df40a77de032f987d7827299f616be6249f4e5a3e190cc6aeb85ef605e27b80001a4ec66357ef621ad06649953c201770cdf8ab794ba2d74500a65aad04b9c8d793237185e79aca34c5b8d3399be558c70e4e907e9e70d798d62cb1888b1b0d6aeea4ab6c90c9a2b045221ec0a1df232b6bec70ebd5accf45927311c96e3a463d03039a27c137caff88b36ad06388da213ec1fc0c75c6c646faa14da7fc748dc01be9e6b62236053d79a50181fffe0700fd7d78815c3b99445ae88140febede19210e7dbb3db72b4c55b63cfd78aaefd598595faa58f9e72d00bd9b102bedc15fd31f33fd3a840c19987a91b1142b1f26df9635230eacc243f27b4fce3b1ef62cbcee2b30f3ac216218376d40db08bc35ad5f4a6f5ac0008a9032ed17e78798de71ba21709c63fddc113f14f320799c29e7ba89871e9225ac953bc3457e45470ede7b9fcd70714abc8dc19a4802bd06ab1acd59d69816778d55e7c9f10ed257d28e9c6e9ae0e3d53485a20ef6c2a46d6355a64ccadb040450dfa5f12c3f535c296e08e1183a685b57ada0ff8960a6a0d895e09c511fc79aacbcd03026b47eeb3ab4eb57beac82492303e129c3e168028c112518bb7ebb9fa4269617cb2ab61484914993a79a3f117434dc928047f2f549bc7fd0a3c4e593c7a554d046a94e549cf505fadc3537301f3be458add522bdcf5fdbc9942dcb34c158cb713e2df0ef0db5c7ef5500bff6bb2822c71a88b2c094d1ffc7e130a53552b4b3fab54e8372be661614df20cb7396a788eb565e30979e3c2b318a51257323b0f99ae03d179247f888ab731227111791f95134c2efd1dd44ab7857440fab93bbe07e6ca3e9b0d5468aa1c478ebc60606f5716b6a1bb53c366fe23fcdd205369178acd5dd230abbb0734270ed92436b5e73d0bfab9e956be48f2c31ad986acd2dbc06dea2763ce85e55ca73fb13e3d12fb5e8267cb7450057e4f4a0d1a7e3436ab139ec637c0cfd8d5bf14cc6e43cc61665973524a86121c07ae6611e43a5adbebe35549b42a4488fa0914243d47d13368da811e38483b67ebe5a4ea2f09a23b70dad0dd3693ba771899dce8da192f9b9536b801d3e0391968da8416b762aac180e30add2c730c85e400c27b419a2af339e481522297e3283566d296aa7691c15a87bd8c3a831ef477e13e9ac3d44e62731757b1838ae3b88ea3a5db9eb9c7b38bf16aa75cbe2ae9faede2366a17f9a208b3da4af81b2af3a7ca7b6a8c874d5f0d59e20a26143e911d4ba99925a47c5cf23c72d788bcb756a75653bd55cb0c13cb93e930b2e4ab236318e85d441b52af6793996abeac4e692961f7d335baf155068a2e99625def90b8434b80357e484381a791ed7ebf981d7dd5c202a15bd2536845660dff3a9a1ca6e9b7a2f904d1920cd7954918812ba863411a026440fbae3dcb3459d8a2c44695d23eb3abb56e2dc1935632787b33989b9876c6c3b03e50021740d3ba464d536e85a486004812ad1544ed10c4751ae13344102c44e50695a569ffe6d4083d5b26c2f46d7c5840c27856f45938bb13bd91e193c4f61c1f5ec2ce8e3a322a3b535a992633c3c82b62e5a3b81eee21d620fab80af635b1f85da35d204b07e5b6455d3db7e352f9f2968edce3a0c34fb0ac425da027b98d509d0862ad351763d7c4c9a4432b2cf741e2385bb26e7acb333b093aed231bc695330b188f140dcb89d752b9f9cf11716a076bf19690e8196f0ac4483e775625500edbb88e78a3befb70cbac0634ae3b998aa0b34db39f0c088f2196550552015a405c20cb171bccd981445b21176c24ebbbc32b2931c15a0f84fdeb8a9650f6af563f60b374da42601a6f7c9e1ac6ecb854712ccd5a9e811cdbe2229d8d517ff7e809e758bf7c03a88884bd33f7f1cff3c4e317d612e57c42af0da0deca619ec7a16f49131aaa68d42c4119565da3af3aab8804cf3e81b9c4cd389bf1c95c229a049b696d2f20b348b68d1c41441158a1a866446164e9fb4367dd861f287bd543eb164f57b1e80985bfbb0a75be18ada1ab4079301502bc7fbc086d2691082f4fd94c90c9429c99a703d724ea4287b70d58759a75ea71106b0e9745fbac0ac1d4b8d6b6c06b885413e3165f0fbea378507ff3c470a9acf63d241777f486386cbc66755d170e8a5a80fdc88d26b018aa35739993e7e8992ccb2ccd4edcba28e6cfb6241efe1689dd2f1aae17a4c1f765e5136a2288db67da39672195e702596a0b70b47299741f4e83390e3f342c046f2545766807f7b5d7ec0d867ba5e086ca36067a3e9c48ae593e101c9b517df65a4d2aaa16d3c996a1fcbe7fceb97a1f5bba29715407900f03f4e072335c34be830a347f75b74431496e01bea0f6767c3e7094be5669b514526fe0e55e808ed29f649542d2b641308cbd9b5f899d3fa8557891cc925bce017ebb6ad0c2fea702cc88dbcee394038c6f0b340db763e5fe15587df7d396da30abb4e3261a3fd41a36b17646fedc3ab94e585e989dab3ab2ccf4601e272bd1340e99ea9ed62eeedc719733b3077aecc88a1a77635003e81c1192d817f52afe089fd96df5f61f2c0f4bcd6490acbb9ee362247b8553860b5192d32b9592343c52f51897b45e3184c2986c2281572bc18a50463a2047c234fe0e7182c4f80600dd2c282209d207027be10db7e706e71f17e9c2ea51fec610fe718a5bca17387fed873dd0ecd822921d280487ffce790df1cf8e538c3d2864ca7532db8208f4bddd4a0fa9fd8b38b87c921d762cbb10b490af8262ecc0eb162b9d4218721a71c19618ec7e0392b9cc9ee104ed99474ae02a21b9af976b7b126696d075bc0c253106ad98fb7112844a6f5c91d2dc74cbb81d0225b2ca6baccdb8a21d08b3c500449aff7cf3bc704827acf1ed25ab076a0756d4f435b96c7b3f78793c311739242dff63a0ea974782d6135d49222f2d66f3a801a9f87eddbbef3d4f8bb9d14697587ef19a190562f768ee29b79563f4a7c3b9f906cf54cd1badba02d2ed7fbd5748988759103732fb186d2d1f2107ee1e8a706dc5e82149d7ed370d425a67c3f61686c652616e5eb6d782798ffff47b0a697a02a767655534c1bc1ecb71534b1798dda5c59adcf3a606a08c470d630c48c04ac34f6fca0baee01628d8b52d35257db44e995f3902ed32a84115168399107f2e4ce29733e5e9885f890cf53bab977906c42053d92b91831f42ac0f9562495c29dabe1162d57b2afc61d53cc893522818ac13cb266406b6659c2b8256401656e6cf45e43faa3b08a05dfd0307e6abd2365db2c7b13cce1b62c296d1b839899fcb4ddd31d17929822870756b93efd48f65ce56c0456ed0d376d7ac275282beacdba789253affafc7c162cb205178b92814a447c0a58563eb212e2c57693c25a42d820dbd5bd9df82c38e2e0cfb37823dbb5eb9924a848c83f5e87d53b324855499615300e8bdfc06beeb90bb2357e729f1f5c9c1ed405708ef046d602192ed4c3314b2e882ca19a175bf3a2cf2fb579ca16a4a008147684d7d10cc978abc1a15df0999d00950b92c34fec9340a25bf95e3b82f74b046c20be1ee9cea051055961e997e5c2e314141177a745c328aba7fafd05149b4430135836eca3cf076cbed9c34c3f7a93b6a8e8231266b24368a8b85c694bf7a30a046b74e25955f3615d404585759d215c38ced97abc0eec14251fd0f3541a6124ebe4b0309aad20459f750910cf1fbaaa49b7ab023a7244815e1ae4f5a299123548226d512bf52995aaf7112bc5470142587bad7258cad0ffbd9e5cd720dddfb467a61cac7cdbf0ba8be4be4d5690cc6bf9c2cc7ba65e8ba0ac2bda65aeb969502aa4a1c78e079b1cab3dcac5fad3618953660b40eb0d3487153decebee55dd0fe8f3da986268e7f980ef85395d02b277eae1a079b0ffe9df8b7a3dc7fa208125193c597c5cffb5f6337d58374fc5fe08c0c11bc6d7d114acff3898afe8a8eb47c8855983dbf2c57e0742f3e909cca9221ca770001bea85283cae48429e1466ca9669a4823e5b2842c89a462f6bad5c9b257e8ba1d1adb45382c5ac695d92683f06fe1838ee8da71a35741d3e208e664abccac8f311e8eaae2702f75199eb32efa0ba3d986638fa160096ff52c6aa2eccb10994de7ca31d1b41e75e765d546f0d29ca1596c66e0a59117b2fffa8965517c79dcc1dca80245f37960f606b468de54d8c53a481070ec5a136a228e38daae7fade7a9901044410a0622afd92bd0f75e4186316e3848d975077b9cd2f9445cdd53f8b12d9e9b84a1253f28e335bb5e6b7ca142fc70ebfb9d1a0160d6b740c7f920cb6156ace9a7ddb1eda66d2526151335eb012482b2559b3dca10980349a6a79919a7f0a27b29ac634589715ec9960c9368a5d1e5ad6a54b502b99f81a72483e6db177ab9e6a388a6350b3c9d4dc1a9568f6ab37f0ca9fdff3cebcd75ed1a9d65ac211bb086247334fbbe72d1f2a1ec892446ff72e425f1bf535a9e352d6237dba279d24f2c4cfcc15f18a38073955ad568e208d5c2fbf44f6991d6bebc2314ef3114de5d33c5825c412fe9b8e1ecfdf5e6895522a11fd82c8520579b6699f756cacb3ad361d18f726f57607606f009de77c45a37eac0a5ef501ad875632f44b65696370613cee04283529bc539ff8ab8dc71609c730c682f997548c6b0f878fa5c3a915d4a414fa995b038582c18ac14cbc38eab69a0cd06cc3829fd1955736bea523608fa040ca5f25a1c3b078bd821a093775a22e45f03aa4e3f578d18e9653a78ee96968390f999a04d4d8dfa929f14585c3c59118acbac5731584424fb8b054105c18503ba616bd91acd517c11902cca023e9b339c2745b1441bf5902189d035786038ef7468d2102e1803ee2d0823380214cdb80aefe2d9542231a63182d1a4d1e8cb9aa95c7dfbec0e45fd99e01260ccc7f6a8797f842dc1b1c4fd00adf9c01213731d793ed1ef15cead98ef8ad8600a4b6c22c0b4a6ed630fc3fa6edab6ff1cdb93da7fdb01482529b0927e00dfd849da00a5f0a3af79ca756dc81bf38b55dd992a5c4b195fbad7879170eb6583ed6e6da9567f48b6c29165e094ac78c9314885ca81dce5e83d20ad5abe1748a85a8d77797f425d0c212ecb2d9c4340080c304ee4ec611bc1b4c746c2028b213cfda833a8ab031bbdc86f1573794918cdba8b9b12446de3ab41f432c06b0473964832934b056df907d4d0886174e93207012ba0510a2a720fbc123df3d7973994a2d37d17bbde65a9052c32ea4a9eeca6376f6892efaccb15f2d2f3147e6323012227e06df99c3290224fffdbefddfc0419b35c43f3ff605622c3f1f637d705c6f85735332539ddf944f08899e9f10db362360f1fd81887d9ff1b19883e160d33e8c43303543637dc2ef471838e675033d6422e75718011fad2d2aa95b88ede49e63515e01b4a67dfdfc10a7bdea9fc44c367b32b5bf1373c93f7408590214f8917fafdac853e0ac06caf29c02ddf46e3e9fe6dd42cbdba99f3443b32c03844d7317c46b3736ff1790c121d27f58d02e031464a79d14cb8fa87a0f36cac25e161ae0c86a579ba9dddc25c9f22a894988eb3f082a4db6364d4124b163c427433707bd65f8749a2fe9e48dbb95ec522ee1532647ef4c3d3914245934d1956b65e62c480e138ea381c008cc36ebe541931164619c0423ad3f1b006b7180a670f8ec42a1c5d23adb34f94e8923b6cbdab6e9bc461c1d4e760aa02c9a58ee57060bdd61e69e418db70caaf5d627c8c28b279b0616573d1156edd31aa896783d6b9d8476c399596f6212b2118d9c4252fe9582c1d7eabfa64b63eda4f02831d2c26877654ba5bff1f7221ac21e1978691d5f0ad133cbae796a41c4cfcee54742b8c32b3b3ebf665920ff9c5064256242f9b3123960dfcd6b8b565b05e6fa4c242869cd191ecea62ea130c4022cc75d73722e90214529268a1116da3c388f7a8444f2e38fdf232d6d937a6f927ff639e46822a590bc08334165ed541fe4df286b04e692b3dab68fccca13f343cf2b7194d964600e40c7e01bd482923517bb537f3dca989c551a8677e92a8dffe401a379e020e8cfc5a50f208cb28d2277a3f0b757346c8c5949910935816cff07c5907aa121737b5ec576ba6eb598ca38df1bf9f9ce58e7bba9a326f1f79c371601885cbf5f869ef7ab61de86aab68cb84ac34d8b00719f0b9d79202e34709ccd22c865f825a4592229932b87c68c24e499a99b9be071737a506e80644bda5c286e0eb35d7619a4a482c4f07da3b2775941a499b0b3f5fbd3a203fa0d071d210b358c4f40f33f26ab5ab24db6090e90ce194403aeaecd0c710dd65795a035a4ffd32be81f52b095c2eab2cc1c50ace483e6767ff07df49f26d32563d8694edff2c0dbe650cc0e0d8a78f71854d8b0dc1758155cfdce898d62e813727465086f016468572999e70c8f7599d3a1354c71f3e8daf43b02ade7568ebf03cb076ca99107f81f04cd8748062fa4fe710ad3539493982f23e810a3cd7cb9e0fafb22b939132219f65f8402a77a4dcdf086e2f299026bd5731088b97434779c3a91f063cc9067807b9929ba5c956722dc00482329780a6bc4934025743e02e0ac2b844c3acf44352203a5947804369db5ca4da286d75d68d6f2422be879c3877257725ca3a84f81a73e5a81878164c130a1b53ab3e07a3aa990fa30144de232cb800f910443088a9cf5087ec0425b0832b30765179ff971f412c48acc27764aa2970c71ea67c2ac841c0264e80213a495c07cd7b548cff5f87453f314772d0b64523a4ac346e9a7638a9778531cbd0ecb60ebf7c801ca4a42628954b6bbfb9fe749bf421efef45f71b970627fd0832f00159414c0fa210346f2d3845a5bc917325360827db8e375bae6c56f410c79ab3a7fd70f1a0fba61c1a621bd058c16c7118420a037f5ba8d7260f0c897b19b656565d633d350859f5648c8160c63f2ff1b56819d5bc90febcf4eda5c0e7a2ef10149d7a5baa45afa7f7d423f54220f4342625a48a5878718f04888ba5c4826dbdcd4555e8075537bc473dff94aefec723d89d81838f646611219e01df5ea5515f5530b358e16783424811bcca5e5316dfb61a8f67d84106c745b0b170bbb7d42d0197e39d1a6d12114ef37488a0715d063e84e98fad7e342e2d5b3b0843cc1f456b10a9a2644297791076801cad64081674c08925bb49b324eabfe08f75c12f46308e710d3219f6941204b87322f0d3164ed50d01c8238460597a83a713ddfa14a8bb5daa0e983775317d21c24c17cc8da373c96620ff27c31f57978213bc7edaf03112cfb1fb3997129eb31d5708c2a6b605a7d4b109540c96803eb938dba7cea21c5edb5ca7255aa480ff3ae4d1d188366b91b984cde973022509fd9d301368dadd383439e5dc7eea2bb0e9cbb660c7bfc0224403fff18a8daaba7fed38c06919eea938ed5adc281643325d1de87365f00aff9d50c68036a020b8313f0a67a971cbb6350e14f0a8c06aef9954c8efb6b4be2fb4a13d688109098852e02fc55bbcc01baf052648cae44a93cca4fca29168dfea1d06b9c9344b8a374f7c1058344a47001c9ffc08ed3d0156652d9f2882615ae76d8d1377224a84dfb298c83f2cfb6c3cef1f849519c9ecf5e7e52e62ce9c66f85a9400c63fbd02b3d37e13f2c89809e12741be003afc88f995ba60b5477650f63df60bd30ad03921bb65b4c84582d912426a153b537c7d824cec8e1dfbb33b2cf30ccb31ffd013232d3d53c691cc262cc171a3ae9da97cf5fe677433728acdc3294ea79dd250cea4d9aaf2bd51a0010b586dce393017e292cc0459a835fc652d7cd66abb0500d95e3f04eb309f3ca90dfec8c1119c691fff1a04a384ddcfceb74e3162940920b76e64c80cf4ce4a5b3cd449c839b19c2e0068dd8c46fc506e9a905a4a16c3d21665a0916014aca5468390f8ebcbb375601afe0544b194eb97283aaa499733fed3944241086a1d82001691b75fc051a011e1c98651318b48b8d109d821cef3663627986bc49ddb55b93d60fd720a8759f315ef947b541981c32c403ad430e5b9cc87be358fe514d4d9b6ed211c77e72c71c136412728fb037faddf07e84a03a91bb28feb3c44a96604d781e3b8d100b51b651e029d19fb6b5261307ebcf27bdadeeee7c8fc6658785cc1323aa2a7f5d12d639ad71e91332f80ceb3111d8e701a815ef294ce7e2d247052c99e9b64413e61c87e1b7e96198f8a6244b94b124e7b2228ef653dc35b48e15a148664a360d21278907392cec5b37ab60d703ccc71f2016f33eaab3fac531ff92d840230d2a038b5e15c3e482c42b2465ee1e0542fa0dda7d5f5241cf8536fe98c4de80910eaa0bffae1397a1967e7b00f2afcddcea6023357028ec884ed5e5dc38da4d704f6259f3058d4bc2614739cc6230c9f1467c35c8bb4b6421680020c365f619a407f45cc5bc0197069e6991aac28e3f1589bb59fc99ca1b5aca2284b08e441eb576f2b708b64d414b2223e46f6fb55225005395bb1c8ef94079a7df2d26437051e149f6544bd10a66585604ef294c9bf9a783b17117ffc3a05ddd7073b629bda6a582270f3ed12e3ca40a9a83cd1d8148aef840e8fde04a4f2942b5900b7c79dd941f72be5dddea884c8421293cf08e6527400099672e1288e1ab957df1ba3090fe9aebeda5b48ef6bac2a39fbca30b5baa3691d4ec7661bcd2bdf5ec4f2d7cc3018e9e7da8f9571aa2501f9d3d5678091ae413e81bc9368f1193fa95ee437cd27447d944094cbd034a04639f5a304cca9a0e7589ed157bf66477b1ff7608fca9fdfbff9b9b3b641b094267b4eaa879bbbe76e5fe3b015a3336b8f3383f78bf2ab4a968fc14f467b68e18009de8475ceb0a13775033867d5ac9e00a1c4d5a6f5ad2f69652ca9452b009ff09ad095eb8a6db7857f58d46d363fa463fc134fa3b11e9f6771a6f2818488a1dd0eba24361a01fecb7e7fa36c95879d371110431afe5b190ebf9bf96d76a7d656fd916b7ba6a3df72a22e7f8661fc8cb2f2f8bcc402dca7903099ea45a6bad319c9925d11b7ab228d140b9602559a94af294a5861dda3ca1823d7102aa82c902ca87294fbaf8e1066773434f1625fa54cd98ca2689c6d0a40b13830c459e89145190512203021688f0c2e48a270f6aa9dadac31319ea931b5ab0b8169a685f3248d3b2da7452da462ebdd1dff1a79452002061e5652d38a4db6f474f0bee86647a59b8e61d679836600c2ef3f08e993bd2f87570154d0a799e770156f23cb6e23a6b711d851f5b85978b599ed8595428782a5c7724fe3c65b26432b71b8070250ed368f7cc73698f10e4ada265209c0cc442f66c09f6e59d1439ce10eded5aed97ec58a3e1c4d2c8c1810e1a3b3d3e1198d4c795cf0a885151974f5e3c88b9590766f6251ffbb0eddd521c6ebf7d7d1222190c84c4ca6019d3ca72c752daa42802f57dfdaa61336d4e2a72370b4f3e661bdddf5a2b8714b8f2fb8bb96c96534a798f6af795efa4cd6d9fbf688773fab794d2369b062510490c2d24619e2419a1460b12aa27ac16992254f8d61a37355902b01801451528a84070c50a2c2c9cd43047c0b086504a29e5374f6e562062840e55508e65864ea1c2e3bc10224bee8e5fab51fc54a5544b96268cf820c92029cb113b6a94c8c2e58ef6a7c097f7dff368fdabf55feb83c8f79ee9eb61cfe3fb9818c4f5dfc3c4204e41c07f3ddb2ae879dffa59f74734f9336bb63694a306866c035fa2c758d36511efc8fb22f0bda7542c7a7deb0556af138b5a2f4523ffd61bc9f73e5777420326282dedc1d7acfb23db8e5927ee402261040d9ad896e779b226c2082f9cec2281af50be8b6afa2443fbce18305f7ed17c5934df138d48903ff4a7c8f2a74a833276bef4dc9334917a35d83673cfeb231b0f31484bb4df75eb7974deb7bee547363adf45084708e97be883e52a11e80a5fff0f03cd9e6be5fb17c97759c522f99e68f47246e5f3f0ef5c9cd978487146c51dadf73a845d96423590d65961e54f4a933ff3bdb09b73d22ecda17817ec8c490342ad9cc639a409dd751fb61ec4c2c73ef20776598706652cdb8c9c8a5c2edfe57bdf2c72bd271a59978b46523462514eeb123d7fb67963ed4efaae679b0ce57bcfc3df25067105b1cd04ccdf0104a9087786ad188bdf54d11c1c047105f9bec500efe543c0e554e412adfce9209ea844993eaf7eeb8beab7bebfd5bd271a79dfbd518bbd8732eb56e87d51cbf3de251abd510ed9f6a1d8514693b2497fd2bcccd77dcff53e88fff7dcef7a1ec2513fc793f0c3856c5071509f6bad5855378765cd1df9ea7aaba3b48a85ead67fa13bb251f9f38be4cff9522c7a19c97f8947362a8e3fe6a5dffd9ce6b4a6893e4eab5fff93e0d0044ad8d1e7d66ffde873d9fffb22ff4ff4c4a27e17787dfa369da2e0512ace18505f3e8fee5d0ce2dfbd14833815f9771f447efdbc56fdee6794b65cf5bb96ab25a97cb16e6fc640954f9fc7fc2a0611833815d59fe2cc16a47b29ce5adcf179dd34f9131e712ff4c1f6f31d6934ff0efdc9c73e9efc99fd4736125adc815482064e6cce69b2d6dc8124dfd6ddb5c4bec964322677cf75e00456260c8ac359ece6f67f356883fb61b1e0e5af6003d806eb6b89c81f0f2ad8facfbb76d878745be0c7be88be053bf96c03c3991465b656947d2c55ee68afec6ab70377c04422f5c1270212fd9275fd170bd9666d38d47d0d3656e7777e26ffa8fb991477207993fce9de99e48fd2d0ed5e03275609e7bb9cefbe8ff8d304dfb1ad7b9a31a03ef822d087e9fc4e0c49e902490a7db0f2f90279cd5eafef81746fd47ddf3ca8bbdd779307517121184fdd3752f7d475dd94dbf591dbfdeb7beadea978902b7dafee9d18a8fb9d1088fce95ea7fb5619eb504eebfe25fa93d3baeec5275676bf430ae588b3ef63247890fcee7548211c71f6893c40fab00f521f7c1eb08f7d4c0c421ff66ceb5e042964bfebbc8060c915c0652f3454dd0e08fbbdcf3748f4896f47be828560d81a796ebf7c2f949d2bcd1725564daa246c7e58ec8e9c5f65ea459b78cdc91d193765b2891d6560083e4ef31acfe52e3f20dd1935d9c48e3469e5abff4db6e1dd4343b50e5e5696071848135684115a6ca39fc19dfb00fea93fd20ec0dba2080c543f47093b7653d61bb621654c6c0b5944807471eb7718b6c1ced46a6e8de25632b70e89b9d5b3b2da4d4b4c52a889d6818586ba69484b3714c4d8ba4ddf3def251ab9bef546df473ba1c8f5df090d609b953ff54d6800dbbc6f00dbe67fa291914cfed43fb2c91f69b24619cbb6d6b36dfee8cdfc8f6cdd14ce5cdc81d438f953bfa15a8326d6f5f903a9ef79d666ddfa1a38b1557efd7e924250d599a450ebeb7b9314aa9f58df25d67770075238df15ca5752656a75538c27ab81be5e3ff4c176cf77eca66eaadfb5833b54af56ef755d68821df7a1b973d87ec3c73edf87c5c23e2c96079c31e08b604871662b3afa22850f30d8ba975fd4bd148bea7bfd23db2d72d96ab0b1ddd7df81d489550d0e25d95116fa60e9f31d87d8fc00a5852cacb842c35ebab9964fbe9295d16e4bffef0322979ce6f5482e8d4777be6d59f3ac1c7b35b28698a24b1a234b7a58c346bc61b2a68d99124c29520596272d1e2693c89552ca1987bbc1063254a4c8a0851a2c2c34998207a90c0e862c5ba496f0ab2b5c58f71cde04eba362ce39e79c73ce2b5cb430320409a41470b0cd3477ce39e79c5fceda862e1560acc8a003939929407089818a2b4c7460340095a58817485071e5031a299d264652b850a384eba1c817567ee5ca085a4c388922aa34fd80431a2f8e988200586438024a0b16397421c50f3e504a29a594524aa1585862045a72534c0461a3515c4a29a594524a7718c87fecb9fe3d6c835d72210127a2f0d084e588ac2dce5c5121a74991264fcc60254a114c707028de804e1c0cab01a3d3c4b160198105154cbcc062c604ac2d9e3c59a214849b27babc98f8110f63de2031c40b356099f29c95282a5ff28d99c27577e22c2bd084952d597c81c4cb5499194baec0f04407295c38391182167bd381e86047cb36baeb36b7c99e76dda54c227b5a7727ca3a83da878f4c27c1cc2cce21b3bae7dfb1879ed37cd049a778c2bc3e68d72d95c99852ea31f3147fd0eb2fbd88adcf5eadf2877af2a7abacb2ca8e79dacbf3798a9465e8e38e3b578eb992622945963ffd1e333f03b5ccaeb1fce3ebdaf80a37bc44ffb8c1652019069779f8877f8a2f83feb43b0ce442dc7d0acbfc1ecdc65a5ecbcbf2644e29a7b5ded7f758a8eb2c9e353c6be49c9d0b3feae59fdf2985dd009e73ce89355a2cdb3fca50b2fd9ed378ced7654aeb0b92a964fa94a7052b2995799776b13801dff33bdf231a39ed8845e1fb88463d1fbe518c17ffc866413863c0051fe3828f312bb2e07bde82ef7919e18cbecf1fd93efc97f145ff329ebe0c19ef231acde81fd964bcd18c8a2714f93c06df00b621c5780c4423230c1e03d1473cb27dcfb3ade747598fc8b618e205e1d10c7370feebd705e1914d0cd916866cfb906d3242b659101ed9186cbd53fda8b7257ad50a9647f430a33f4979d0d4070b9de67f3aaf0e5d5716b2edeb20e779fe6370e771be43fb3ce128de1d91e773489c30271c7d884e8b85f07d7ff0bd8f219e7fe1c8253b8ff339e17874731e0724caa1f43de0707c9e709c97e777c2b1efced3b0861536d49138bf131e5d1d71004d03e76738d6b8389f43e684e0e384ae8785e38c1b7b1b8eaf1b13619f43c2c2fa603895427f721a94d3e4c34022973897785fbdf9e5ca3975a5c089ebc18e8ee39c8e30899daf249bf9a79b6f87732e71c7c578f92ee5423df4e53b94074d318718e29c923f522a9c54f207e7342a6a74772d58bee3c44d9c377138a93495a6d2954e257f80b03f451c8e891b1af2260a12e5e0c08d4dc0e4dcac6f119594586105218c501652104e80bb630dcb1ee9788c283cb4765ecbf5bd4058cce2f4effc8e38e67c8bb30f76bebfc551e777de493af9f3849e6f30e7efe88438a1b58285af304aabdfebafcd3e13c76791efabeeeeeef4ba4f2969f2a7264a29a54bd9b49aacd297a27bd3d04567f70ef61da197ced9ad3a67ab9bd22a25129a90e70c0116e28030420abcbe0cdc7e497fb69c68269a2128173e5f57cb342af2ec98465ff67c815becff4cc1f6bc4c26853eb0e67ac19e6d36146301b874000bb832a7c509dcaf7330609b81a890d9c47b4911dc623f5a69cdf39a44cb3a5969ad34031fecce652d50b840ebc1e6bc01c01bdb61411bc27a6aac99322e18f9e23f1c8687913101a83273c41d2d2dcb0cee8e5ffbe1e3037c9cc3ce7f2a9b0a4ead31235bccdcb6dd563a2a4f539a62f676bbfda84f4d5198a0c0708e48dd8003e788940d51a02cb5129813c58b121f43bdd44a9dd4482f9daa23a0a8d1498dd437201f8f14313bd478a48891d2b7ac36fc3e5c14d8d086871914d8d026046daeac466859e5c614793e63a8f8757850ed3c2a291cd5c74b121c6ef776766f3b291c5dcd832a0d8018294bf89005408c143143b5193e9300307c9962070402c0f0458a199271b47bdbc94f4eca62a488d9e1766f67f7b6eb6a53ef19a45e776f6d37e7f5f0a86b9da68f7db22e8da56d9b27853c2b73a197e7341b7f87b2bbbbbbbb650f0ab6866c9320d10efa9ff77ab9d0ab461bdb59f7b9b13c293d2576ac5df953865eada291101b156fd5c9f45c36bda1e9796fbd9a1372a6dbed96c456eb53857aa2893b565c95fa1feb541d13e5e54d1e99e18e526949ce8f7249e74719e5098a0cd51d254e4aedfc28a7787e9461aebfcc492ba43b4a2cd966821f6516053f4e24a52527aedc7132cd28b21f67138c1f2795eb3f71e39c7222eb8e936a86a9e0c75935fb719eb9fe136b66e59ac0b92345ba1ee329136d9272474aa95cff9142dd1fa9d4f5a754b4eaca1d698e9eb9fea61e79a2883b56a5bae4ba6749284d5f64957c73640a8f73ccb4a24bd40aa557d76d236d731dcc94ebd31d0c133ef5a58601c3d379bcc40d2b9705d21554a67021e608054d535c3db504973b36d51d3bccf5aeea31d7cf4061024a0c848dbe347a13099cd8b9a353b9ee6ee5ba4b5d7f1e9dcaddcb1d3de767ae3f7390bdff3240a2ef8f80673968e4d1555421c2e72ff831079f0b442136a71e3ec4fff7219d942871bbe27ff8168044e1874cc59521e3638044322cf81e90c882d78db17363fc8cf19e991be36d0eeac628c3c28df133902886ec08a5dbf31580443db323eeec618044b30a5e06125500c3092617c6530012c190c97e029048e67329c85d0a9e0724a26082097e07249ac0f29009c1e5791d908867c7b6f33920d18ecef398aaabf33820918e276fce5b9028872685867098c04102078704575c1c0c2e0ece5b2717a704555c9c31572ecec740229c21da0fe530c25a31d61ac0e2b8638d6b9f77b8b600d7dab74c9cb9f66555415cfb9fe4daa73581c4b55f23810dd73e0c24b243ae1b7b10248ac196007361ff02896042e07f2011f8aabae3ce7d8577ecb92fa0fb7abdfd725f4b44b92f3134dcd7bb40a2d77fef72595d97eb3d90c8555b60baadef40a2d6f5c254b99e19cf76168009e256f96092eebcb9dba25b90c30fd5a65ad65e4d8937b6bead696ee5b9b5d65a2bce6b47833bf630a18416258a48820a1f3276f4e6eb460d246a88a105092c544b77fed3a8c0dcf9b5249ceefc184834876aad3a2e14e941892a374954f02d7aa0c0823164a6ee38e34b0e253022052398b418f1e68826ee7c1848346bad74bbdd54a0c2050c324dbc6a2c819bcabaf3655ec4dcf94f4408ee7c5a8d0821eefca122a898829a536d9ca25089c2218b93275c8b2c3cd82f83a924b7be8bca13b0560008d0c5aa4b955bdf135d40a2c9480d527ed022eb4a198f893beef4383144d4ad5f65530529983441040b524800e5a6cb08902845820b9b5b7f7a7fc4a44d15140d48a84052c536b3e8d283102f0baeb0a34cc6369ccb9958106768b398d99c71a700ee9c5235dc2995c59d5c906cc982021d3c18920b5f0a3930890bae214a2fa6262da4a7ef07275e0a2e235ee850a86a458d515289e0bca8354be810ac6ecb902693470a750b0c2f48f6a6c7a30813e52d4d30f01882dba225061e448e6c19f38407529519a8cfc1a2659dd75a31e8d245959f2bb82ea6a46c8ccbb82e8ec840073bbb8ceb220d00907851e40d086a489aea1839cfb16f31096e7b9e4be9628fcbbcad3c07d5583efd503220acec89359a459250e188cd68e785b89b9bcd29f66ddb098500e0c8cde624e5b374cfe8c8858923900b7b0fc7791ba55190204284e0ae7f8e7b61a10907f8e28bac5166dd9ccff910bc98788209fdc585b12d278cbd5b715ae3a0947a1022013cc536e86d98d75f6e5aa8609edc51d4223814b19c7f82ddd35cd88fbe060ad49b9cd0b1c00e625c173dc74057566718c8a75873fb5d7a3206732c35b718cc83c2cd46b080d3ac744bddfe5c4bf9f270d655fe04d368878281fa5b0ffb58ce83d03f9c56c28f9d43a32302c9f27ba38f348d2bb6e1a9e11bb06ffeeee839b631bbfd7e866dc8b7dfef51f08dd8f7fb146c23e763b19b63a517f6d591b173476e57e574ce2879100bf510b7bebaa2e2b97ed3d2c9f11c15da9de1343f83c51dfdeaf663d52072793be8cb9de3a07339e618dbb9b66a346c038b6db4d886ebfb3b8b6d7cdfdf6fd8c6ebfbfde6485af08d9ed234fa463f358dcef9b1dddcfec6826fe4bcce8fdd05dfd0f96ef2254953b8b86cd886f7bf5ad7437965d867ae988172574daca3601a7cf93be92a754e071ba3ba7df908a5db37a96f3495297da3ab9a46f78d1ed3b2a6536e3ff912032931902f5172fb1d89c770fb1d06a6d1af139e00fb1c49a56f3813a6d1ef4e6e3f0e95db6fc39ea2a3601afdb0b0d5308d7e306c2ca75d856dc540cd40fdadb0730cd41f463dd891b360583916a8aec8dd907076ec1bece948d2153bf6111eaa27dc0eadd44b5cb0632bc16e4f550cc19406ca12942476ec250a8ce45098d24c1de5891d9bc93e15914295a62939d8b19b5e4c8ec3228527a6272a4eecd84fb72e5c18e9e2e607282b33d8b1a126c09acaa2089b348d6ba99c1c1555509921d253fd85891d7baa02aa21724cc034558769c18e4da581522e4d19aa9c9baa3141d8b1ab5e4f5db6c0ea92c552e7fa8c153b76ce454595a686a099424a6275f5821ddbeaaabb4db539c3e436e50688a936423456b779b26363d1dc1553b92bca7456bf01811d3b6b3e2d2d21c40dc9c98e7ecb80ea48921f89620a8c4b1451a2b8442186cb992ca52558ece84a4f309eb8c0d0c40506325c9450e1b2e4c51214253bfa12ceed892c24a6284aece84c2da521d24861d5e44e831d5d09b7c50d6bb29ea8f8d304538986a7efc6a40a282b382911d8d1713bb928235f0c29e253fe658a1d7d6a4c054a5262c24889b9024b4a892b29313938958711c28e4e0584a3f2059557f918afaa54b919d8e0925879cecf006147cf71172afa06046ee5576e055261ad5003c814b502ceb1bc0d0f7674ac3617e4864073c5d4c2a73484153c0c8126cab3fc4d0d76f4ac2532aa2e5a246175e982885c973650ba643d7143a2624779a34f4833507961c591a4263bca233838a9b42489ebb66407a5255176944a4762514837798b2262064b0b17555143965882e2831de5d21230b70549d29314a62d48ae6c51ca3145b9c18e92a975cb59110595155c344d81623f6ff965eaf64b2a0f9ae0f6cb2c59180f629c1a9c3c63e5a3c4926fa6740975fb5b090aa766c9f5ef97563c68e6a27c725a3fcf95f2692a197971b5aa8c81fc9bb3f5c29b5b94239ae4a465a85879b57a6d6a509222a5345de1aca865802f4a3cd95ae2914d4a59ef63205bc50ebe1448d0643372bd908ea266cae624ffc8f6b54257c82091d7d55951eb67452d57382b3ab2e590267487d41582ecb68701d9ed6f2155b7fb1a8edd74ab27a56ced2ef4414122da6275797786de6dc9cec12e1fb3003e9642d236a5b777f05506f244727a908b3d7ec82bc48fdc35f0f5f821af8b33297ee0cf01797bf077df78a2f365f28786423a2b21b52648a86c4eb3fea3dbe2cc028d1442e34d53968d7d838f4e1ab29a2b2c4b36dad5f7c49b90fad5c8a9fbfa4642e8cfefaa2864be73d9a0ff6397019070b619b2ed897ddedddd3d0f62a64dc76eda83d28e763de83b9deeeed5ddeb8feeeeb5dbdddd6b37adb46b57698fdad5aed2b047f557ed78ba5e7ab35dca1e3de99c41d26ff4ed1eece8dde9cd3b6ba55cc1c06030180c06832989599c9c17ceeb735e39e0386f4c84812f58ef4cd17df7bb9444b97f9dda703d832074627f77fb9c507ff495df0ce57fde4f7faff6140c21f43c1cf57eca64d68e5eec5d9c9e373de8aff733304862bbefd75b80840bb08dee2995219359ae79907d9ca73fe441f43f1bbe9c063e4e689d063e831f607071c4e934f073b8f5faee2c4fe81b0b4fe80b0bc7d605c597d3acd36efdc4f979a2e7c9efeebb47cb1934a5777b3f767777777beeb3d66e6f47a1e594b8fbf1abc3d677e151ec82633803c17bdcd6bbf75edf0aa86cdf762f1cbd1edefb4f30047f31508ebed19752cfeb72f878c4583b4b782fb95852e537db70792f5d9fc33de48077fd7d4e087ff4edff5e14a42cf4f2a752faccccf45be2d8ba14e7524f1c615cda458a2fb782cb5da4e0e17eee7d47df7bf672ec6875debf14caf90a03ff25be2803ebf7f55ba0582ba0a28e1d2dd11347d98591b3d369948ab30edcbfe6bece6377fed49f320dc77eefe70c9a72fa8d13fab2e7795ef764af2b90c1f673b7cbe512e56d47a1a707fb150463f9c71d7da36f6dbd8be3bc1ce8eb89b30fe4175fb03b56cb6d12174873ce39e79c5ab6d8c2ca953f63c8c7837a9aaefcd7e8197dec3352a52b9fbfbf7850470025b6fb640d17727d5f1084f92ed1fb1ed6a0025ce2d823a3ff8130c348f90a7388bd2bf6333441c8ed76f6d2fa1efc75fd9c52a34b9cb99e8a2f97e89910bbde832fa9c658c936b7a4a5284f56a6c2e4ae661645f22047727ac9a90a8220deefbdbe1fb712ff97962ddadcd77f200852ca693ba29c0af9b6402b85fdc04ff080afeb3d68bf2d90081499698cdffbbf9e411082dcefa7260882df4f94524ee340dfeebdb0ef1667ae7f072a20769981bc10e4944c8281644b34a1e594d32437a5b0f9359461c620774e5152814ad851e2a86efb3355f29c2633b3bff4319fd2e94d3e376faeebe75f5da0cb5adc58b99fbf725caed073c8913c612e51feb844ef1369e174212427ef918abceb8bd06c4eafa7dff77db1b0ef9c733a61c71ebedf2be4eb66ca35c0652d592c5ddc652f97b56425dd9d1e0f8dedfe73c2ca6f70becbe572b93e27ece77a97cbe5daf120970873c55c2e97cbe582c580b03d4ef3d6cb157af7f57a851cf0ae0b043f19c85fac000c247362b1e9e5844e385370fea3af1fb621f6e070c99eb0d8b740d87f1ee8c1843d831dc4fe85a3033bf060de97f862a059072fa7bdc41eb18379633171c86931256ceb7b7a767660b158ec5fb1900023b0b1afd669fd31716708471c3d02046169072fd08a218c7d77c2eef6dc0edc715ae3709a1c62200240d94f1c77ae164f974b70594b9698fbb95e5ec89f1376945d097ecb55410d33f687bc2e79bf594c3c0184f9c1f7531c5dff89de77f70b47ef8b8923901b73b99e9dc6379675edc73e87bb4ce8ae15c7be31317489a06520091359bccc409d43ce5bb6f1bd74fd50d390eff964ff999f681968fe50dfc0611af3a5ce7d39cd479f11e7ce2b5f3db7e70fdba8f7831f06ea8fb90e13669ecccccc93999927f374f38db5878164723e9db3328737586571e48e3b35c6da8ed3e7015f134c9897190887813c7e859681b2eed853c1072c6bc1c2ea71d846d8d7f320b681e463af49e1103dae1d43b519bad25fe08338682fb3d5602199ac7910ecfbb99b89ed86751048170693fd912de719023c3fc11751f032d1c8a973c471e882df6211cf4f70646b71ac5d1004c57e863a73c10745761a4ccce1b19c3f22b23018ec3de070fc11c679753e271cfbe63c2c0473421c9d30f63938e2009a46ecc170ac71639f43dae9b41a56d8873d188e5c55e3824d60e875e883abaeace5b1abbe17569f41b33b12c7bd2b7dc4e290695d66c22acc6526aca42e1017bccc84150cb73bf0b1cf38b9fb56add5937df7934da92696bdebce0f5609c3ef41f6c5b2d0c3f88ffc0e3f9c170e48543f4cad46cee34c1c1c1c9c9fa109325e5447fe13159ec1a23f99d00e25f54bec3895c239c36e9eb7d3dab73c9fc33bb43f799e41229ecfe155f729c0c1365cc8a9e48f95424426f87f22305e06052f3e910a3e94fd054f64f616e4b8209cd1bfe0637c18ce76c470b623ce18207ecf1789013a5970d04982c5883539580069795d03a1b33618207ce5e5ba216e799db367bd4e66ab4e0224104d53c63ccd97d5837c24b7bc4ec7649a2c6786b1afee641b55555521034d1a65ecdc9de241f25fb46f592daf6ba6dab7acac2c20f2a78d1dffceffff7faf8a40fbaffaaaafd2d18940fbaaaffaaa87c23e791015176a1f206118ef2f9e959595e5b4fe2e060f1f5fe0052b6ca6d8e4961cf12d2ee042ae25edeb738d08a49c4fbb70a4728a3d66276957b1c7a44dbb6743f1e4e30bb880c4e6089b26595417545703de352176fb93bc7c7c811a97a358f8d242d3e5a8a42fb788cb5149b7fb3eb42f36ad6efda82bb26e157ff8dd80ec8e406eb7dbfd21bbfd6065a6cdaf5efd49c51ed7ebc6fa7356b1077d797bd4dfd9a9228e2345a46d486773d2c0bcfd7ec3dd6eee21d9d1ab4924a8e4ecd9fde524e9a0ed124bf0dff153af43fee8e4ecd84c5f241353333593753925ede7fcdc71e24d5a86d61c34b5eb81a5843cffe9762967cff939efe998f9d19ef7d211823733f1d43d5826f7a1c5c4403558a6afa1953f4dd5a3c4ec266e1eda9f81b837171b05a621bf134b903fb2c5212530501776ec269ab73463a96fcc97efd1a858fbda6b799d7b1e9691b1ba894f5337e91b93a984eeaef94f0fe508c5a6d15f4397459cb9ea2a69951ba16fd06a7fb214ea3c76b968dcf2baae25d6e48f7ccf7a9d4ca4c91f1d9c1dbba99b9a264e0998cee96a9da41c1e4c24aefc190e154046bb4193d17288d8916941e3ebe6c0b96c2c175a2707cf6b87d2491e340a09b18d66a0a6c91c363de5ec9e3b4ca64fcf0e5fdd4973da1c3a0077a131d0147f6402b8d2935db1e3506d2866c3c7e3bcfde1153bf298dbcccece8cc3c809cb357a54b02c8e3db7ad1447a32b9f8f26f3d16c1ad51ca5c29b2815982e6d1ba54c9f7ed75adbf5dc6ac960f00f7d119cd632cc62e97fb114ecd838cfb356267b991403d13fe3340f8d8dd1c48eb599fc7ae79dc9e725a2d8e2f212516471c7ce758e568a8bb1a455633e076c2376e988c325ca1888fe055d58cf72e541b866c25fd84cf887829d856d34e8f4c2e152974b1c5b864b41d90a3d90a8d5b53a113665297d0ba0b0f5ebe5a823315c7939eac8d2a5f5e7bf6a388d3e1dc01256c7e5c0698dd5420363ce29ddddc5277777779fb25f3bd7ffebe934af041edb609e724e1c9df8441bca5db5acd166481bee58c39d597ef9d8a756ab31820f1c595f86a8aafacd15bed16a9886cc72c75a96cb625fc1a8902de6d0c6835cf4b1e2683ef619fdd603a8358dda320b856dbd477f874cfe8823b05feb86be7f3d0fd7776290ee5dff1283381575ef1267fe3571e6570c54bffa19db594eab5f3f0463a5486b2c97c8a28cdb1d964315bd5a9349211db52a73d4fc26abbecadf1c634ba0973e093e74882085be2394f21f61f9c187bdeb3f4f6cbd80c81fea33f931ab99c46ab562e24bd4d1a2af1cf2879e2063a06efdeb257d5848935d38434ffecc8ac07f3d28b2fc697f7deb5f624b647feec0ed102b4b9039a4d0f7f475009142afa7fc632dacc91ffa3487d653f6a4508d7f78aa255af9c37e3b246ef669320b8ad8d90e24efbbc7b97d5da3cc2fff8de5cbcabef043990cf6fbd7fbcf9d1d2cdfef5fe26cc7f7b306b0ed13dbf6fa198fb6bdbe6d2ff1e58f8c81eac7b6589907dfb7dee8b50309c9f52fa4d67fe26cfec7b8d93462f9e3fad6cf6fb5fe138d5aa251ad32185aacf572d487affe67a590b4d51ffd368d2a59c643cfb2ca0069eb442b9fb0f4bfdb1bcd910d699e68b24203153a8c913514b1446e49c9932f5524c9a4a8335777e7725411365a2e3ffd915d0be36e0ffee9ce74ce661c53dc01986760fe5cccdc62af19a873af9479824c93eedea07706c6175632b851410635b43332e490666882f1c577b2d25aa3ae9248b232bb237380124c0188ba228204575277b4566677c4cb512c48b16f03922dc858d855065b2c5826032d1654a2089b7339aa0a2e071184a91285829cac65b437510c9171396a851ab620411249282811c3840b2637de9021b5d65a398082439aabdb11596b240d4542c026290d45e342eb7294162c53522debbcd25a690650589ccb5157b8d09454f941b2f672d4151c9eb8f2441645a4086965aa0c915a6bad33cc550d449e5a628604c1c290145ddc91712c1525451452e48cd4bce63f4e4fac60c4c2de6470439b0c6ef6438341d513187861e9e5a8dc981f2ad6bb1c950bf3349b0c5551556e789f28235f5c7a390a8ad51dbfd62447dfa33e6ad77a33dcf16b90e18e4338b424943b32d55208eec863ae3c73c44b142fa4a2aa9031442d3de9d45c5145d2940a498419e248ca1b23382c490551440b36f93aa4900796a678818d1a1e8c28d964eeda1ddae5282757dc9ccb514e7277b44f83068c90220d0f52acf04413f904eadbc242adb5562b48da90a0852e7e6823612002ea85c90313921e28a53074435c86247838628635e4b9bc4f9496a66b2f476959bae3d73a2f7ecc60f065c99f389a21c907334850b88105304b6868152d545beb981699289076d6b82e471589e2c2b81c55e48b10b59ad76ad349e9a44961e5e5a8225eee68a558bf1c55a4cb944e8660353de09c308249912f2cc8265145b87407966680c10b93149535b65a8d2a92e58e5fab8146abd59418695fab81a10245052a0c946432c40a0a2570814c0a6b9a904b34704314370481c20878b805e15794c8d8e18b2263b07893c3937f2899e48eb21741d21434ec60868724ff503cd29ccd1a2b68b24082839632b51a184fa3064a22e112e4b0830b6c567022428bff20388cfb5b28773327542a31c0a188353621ae289bd3f48cdc0808bcb06213a2010b36a749a9bf6ad83c30b9a264933571c6a37e97664c931b6c426057b6fa9d68d44e048182954d488e0bb62ad27c83fe23db375f7456548d3c230aacac10c2260414c25637e8d0680055aa18926513e2512bc860abf906fd95f61824b26461a37da553d4154bf787bc19cc78d059d39f4f43ebdede3e1b0528eedeee2e9f711fdb867090f083032a574a29a594b286d736f76e8b3ed3e50d1ffbcc781835154fb6fa4e10e89ebe37c666f48db159f913847d79b98b104977ac5d2995dc18f4c18eb22b7f2e40bb1c756b73a36e672e47ddc2005d8ebae1703f64a11ad45208bac45045893636f90d82d04d10c672d44d863bdfdd8bf8e4532674b87df2d541635df1847e138e6ef747dfe64aafb790759b1d69b1eb1f631b5dc17510013c639c2fbf7f8ade112ebfdab5d2ee64d470afd49bb8e8b47d8bcfbf63a07ec97dfb7b6ebf8e22179281a5c50b2b35866ef317e93c76fdafdee9d806ffcdc969934f5934b998b2d8c273045600545d5c58b20605ef65e50e76b4ddc213160d48724aacc87a7ab09e10b164c8fb2cb1e3d36684c08eb44ea6596a951953ab21c58eb5dbbca209d7550b433898ec3834a9a8b49082d3224b0e0e60b023e3a67094bc48c17991e28497262b2f529ae84840163bf2540c8b6a4892253b8a6cb0235329cd2b8e7c57ec204204b6d891ab3e2c2cb0a4a061040b70ce958b62418a112324f880b2235b794ab92ad250596151c28f2a7664ac1615152b50210390a114a884ccf695412c95b2810000001000a315002020100a87842291480ee4d1b87c14800b759852785295caa34912e428884106194000218400008c31c42034662400841b56c86f71fa51417e37e4a71efd4006fa43a135d3dd9925766406335d98e1f3e42b414e52679ac03f9b8fadb2dee55c91f30e1778182846c5412f0ffa798402a4f097292e3f54c25f9bf50c5a21bfbc262d9f838ccf13512bf4298100996c1df0280bc341994c870ab3476634a005339c3ac35044545f0142aaafcb7d202390cf0e4619ad6342aee4896ff35f326500502460c97e021613232e30b7204cbe25e8d5798ee4187c6478ed99443a591507d17ee3f4044db28af9c22619afd3a4239f17ec93c277f28adcd5b12617c01685ea8c298b4fa3d65432d88bc90533c25157b51de23d6e2949123f0c450d880224a9cbfed72488d92710e8b226ed4321e6827097a4e04bc62e2e0a1d64c3da301fbb474a3afd9bc9cdbfe5fe9b20f199d9f0a907e4e9c9b7781d3914c58569fa7036dea1014008d1ca956e1b0e3c39d5e9635d5bedb8c92cc67d04a3ffd72f4696a91e01014c7d70bb6622a11365cd44828e603513073a02a899d4b7a23e85e5a2bda008ca259ce31112c100d47009363ef61b191bc7c2f60784631d254fd276a92219cdcb8de3125580c78bf433350ff14ba7523a0f1c12370fb631cd1d121e115a9be519f7dd5c922f02fa60dc1de55cb7e4790180facc5afa2332de183dce8bee354b21b45c62d69236ef2117f24b4405fee26f65e12f22c25bca9ece60c8e7d7dee37f2c11ec111aec2cd05792923b459d8e705ea15603cdf780e8559bc0a233c572a11c44f6df3d4f933733e9aca49e091339e428d9152f693fdc3274887c1ed38afac03b8162d70c32bcd8c4cd123276b829764c4c55610929aa9823c6b90c8ce21238edeb5e85faea737c4667331cfe8021ce1b669c6a789678861770b2a3962896746e7d7c7e501f18f50377e6323d27fadba284e56d9c46440ddd99b80e0fb7f5790c79193e6991c8db54f059fb01842936962dba14f3a73b0b4f62b1ec615d9d9c4d6d16f8b58f5f86305e517f4a1e0f6f61257baaffdd9b5ce6c01a6f85ea0dc58fa0ea13706ffa74c43727a1352e52f47229761169b983a3e23a562d7721af8002cbb03f866f0426f1e1801f62f99bb2933ba87670e11faf1e3b5903e40da79c3c87b1f4f819f9e01842de0b853f88576255d8a9ed0af895fd66348f2a07b3a5088497b9551c71de3680ae0322c1aa22931084f63b6492df2705fa031976583f01e568ece8af6c4d79ce5f5c59859e18135340d925f33139bc3a3731fb57177ebc4469508db24e289f37635f6008889323ab619f542c1f4b14be1d67b08fba2b576748c32e764558742cc1c40d583fd07b256ce20f28c3484c020155d8c8e2adb1110e8c9e3a4df7c2b33e58a9a7e91b64ea71afa9de5c7a1477e44288d3969f0dc465e5303d132924e1a10225790e101df415554b9efb7343201ce30b3b7ce9b45930a0b5ea74e296274da48b24628f4c94f004e06a5c089d88ff510c7d32d020ce5749f9dd54b6144708df323539aca15de33859670536ada3ee520a7b26f779c21fd5ae9b08c9298dc99eaebf440c4ff7e789ae30a8d221a2818c72bc07627527953e2e6e5037b9e2df569de38a95a5297d9c4db126b4c17b7054d2185549476bc3a402612353abe2e2d53945376a5cbd34cea40eb305f028f655648a4db4fefda2b4b67bf9d85739d13963ec899175688d8a2d0c33cc15831e10040f02fd3d316878e79a528b78a0c6435da6c25ce340d11c9fbc71456e2794791c94c214d9052118ed20add31cade11088cf3a407de4bbe8102d7d28132a9bec53c4881bd99f47398332c0cd517ecf456fcc1179316f452c7e6c3249c4a0165eba2ba422eae611a5465b3e8a3faf6b35cc5c1a216b649e4bdb8afd3077940ac2635f7eb166dc10edb075d5e1735021fdffd40b51fd28ac28cd742b756b4db53133ec632cb56f5942347191cd7e6302f14fcaa6645482478598055d683c69c1a592c3f6ca1666aeba3d043e40afd031d11c79084d629c932679ad7f8e465826f199954919508baa410c204cca2a60446307875713040b242b6a223352e6452fc5b9374f90ddc0684fc98add717c36c9fa0111575e43c2514e535fab39d6392017714691276deab6621e547308212a62ac848a8d78dae616383eeb0f4326fc1ef4b460d6060eea79b96318c8ea79513259e56c95160e62cec5ac56e93331a81a1639eb4b8a6a687f4c1db40cd5850b11a45db9b946fbfd284085c10500c37e26354723ce43e00d335e227acacae44a6b3539f363cd35fcc772d8726ba3f44ba304f0c2f9722b894eecc9c2da2496672c8770a2ca56c63764ca5738923b8b37d5c42a0251e6b66d6c7d9abe487c1e7231dabedab3215adff85e1fc7f6513aed6eb14bcb70c19aaf24ad82d413e364b531ea42f54cc7858d969f07116be9bb2e0300c32915da84f61a6b1298c5472abd8e95228a1c660a62563268545b54ecd57ae16fc10aeb2c9eb4855e941ec079276aeb134b1c76d03d8f5245b8379f22e82b500939b4bc17639f547948145660c96af5ce8a391dc34fcd46d3fa2b3ea23c6745f799f3c4d42e8952de67a925d8f1189692d24d0f8049f239026bda8b68ce7d62a5c0ccf09ca400f349a7631529ee4e26e7332fc4ca9f623c486b32b20edd172fccb7354c6d032b3b9ecf5a5cb960c5cfc7c12ec65bbbed92983280356d989cbb4ebecd6569020aea7e20352b3bb2fb69aee8a6a51df0d067ce3790361571e73820820437ea77f28791374a8904907a70ad84b30595491009b21887301019d8cde5688095ca3b56317d39894ddf196e1128c5629707ee3949ccd528ef7c4e7a0754c231dbac62e0577390cbd9311f60ec3cb8e96c3d4f60a1b4019771bdde4bd4a7e4b780071829878b16304288c69aebc0d34444f6ad1a07dc9f2a3083f214f54b53511246c4134be6b180219d9fda0be16a1c4d1ca6671df8f1d72fc22fa607704f52c9c810cbce163c7e8bc8843a770b96c958ae5387cb6df7f36b210fbb3459225f06b83e6c7bc8756f9403ba56ccc47c59043d04d3b750a516e60f56928e3860504956004554f6b7a0affb84a0b536980414e880133edd9fbea08010fd5c0918a1ead00e6810c51030e0d6e17c14d3ef862857e0dd2c503b7db37c234497773a5483ec6d7d9fb7beb43b7cf25b7ac86ef370a2c42ce03b60848e6f18930b6f9fe19961a6450ac39d9a55de5cb6943fe226ca981a68d77a989aa17ab483c4dd957bd2ca80f6e5f9f61c0f5a5f5967b02d7f6161d0e58a7a2176bc64f8bbb0ff17797b7a1796d40b092b78d907b9970055e4537e2a6e3713772e07a58a7a326cd600c2add81aba8dc9f1466474ee7e126fe0e021300c97162ca537083d4c88bae6313e61c46bd7ea07e456504707cd1165880b636213703c068645cf205d855307ced1c81043a691c2351e6e571d93375ecebf127be3a3cb2c2094cb8a66d47dfdf26071603385f8661f65d099ddd7c22648f6c5e861de69184ae19ca63ee7a1d68607f56aceb9e369b12e7b1ed37261d9dc1361910e633806d77a8ea7a067d6cc101f39a2503ef46247f505726e242c3d2103140f401986032a030bfdb7ce5a6b1591dbf6381ea31e88dc47b03634fb1be460c0d9d7d91d7965e67c9e70a5c833de5d52cf12f64e94ce265efcac479f97809ff9ba13cdb4d7094635a1a63fa04eba1b1b1d3b71b3f2c2b2716cb92b0aa7922872de90d4be1bcf06ea21cda6653e7f2df5f3aa0b33ebead26ab7618e26cea3040d8b83406460f79390839cf83dcb63d26280333194036c26b5716aa10542667907dbfe5d3f1197b4aa0c4e85596d297f8527defa46280de22946203a49a2b48b363850ff260061072a49e42a7aec7b10d5b4e672716cfee4ad125bfc9741eaeffb3380c34cf02faf2be702901256a5ed80e4f684b87ffd87d962c46bcf7bc11b667d728da01e4f5f17adafc0e7e61baf43e3636b695266a2433559bcf5d7698fc913c59b518aeb4b6c66e8e8c37d30ef931212733329cdbfea178dd2804411f2b6591fffd5144a787f4b3cdb8cfd083257d81bdc4edac8fe5c2844f8228b6cc45da57d72b8fb0f62f30e42bda5dd50fa2e834090f509caf7e35bc5a4d43ba829916776256218d8d43d1094fc580796356c45ef880bdd476bbe9e933150892ef8a81b897fa46de126617d52c23c9d9d0aad823cee0e4f2bbbc0758b2ab0ce0d4d343a89d4779083544521a3b80480319c6f7d9587e08064381416a74e492478bcb0830a90598b90a2e3c115ded0db6fb04a438da79ca254c54bd77558ce2612800a7db2cfe7917076b8df4cfa1cf1faf20a668dde5d128fdca12374ec36fcbb1f77f7f1c9ee2bf12a744b6b53137edcaa9b776ea94f34c1e4cbcdf2bf02092e0a691e2883f16c852b119eb012640e7cb697426b133703df66e6615fc8753cecf57e28ac8ae88a6bf800b5da25343b89b6f868393bf0c79ce2719fb825b9568569be30bc3d5806aaab6a19f2d056857d275d563211d0c11d40d06f65d7a260cfcbafea4a6bcfd422c60ec284abb50a98465537bb4a7c83322aa591b6429b3a6698913153b799a0bf09cbefc7714b60b7ac6d3e20f984bec3620f53ae44153540daa67034fc85b09aff1f29cc015478da5559651122ba8501a67ea0ec02db71dd865bb49b381374fb84a23e44644badb7f17a6c4f606f6befe6b6f89a0510a10677bbb4d7e9e165010e3646b67beb85eb102a628ba121075705e536eaa2d6fe55bf0fbcc4250cf007ea711cfe59e5b6720850484d2890d591e5d12de986e75afceb10620b96f6ac0e27c8ca34fe4ca17b1a0852b392455912f45817f39cf02a968331031c823ed8e022c0d06789c61eda6832e9c192ce590b5ddc885d74fb570828880086f5ba29124dc73c9e1f18f8cb83a1eecc8d51ffbb0bbfbf4e671ea104004c4a97b1aaa346a87e02fe9373371ee006d5a4d4012c166c0e3f40a72c77a96bdde65caa49d3f084aed6f65c532abf408ae08cf3b513491a7e09140d7355c89410f16444cd855626314a3bdd0af929772252f17672207cc8239ddc75418d3aeb0e598d4263cd3eb0c4122b866b042d4fdd6cd32b200b0ab1e8fe08f5ca4dbc302807c2cdd494b91dea769564b1aa9d4d83529d1d786f471db47f9dbf812c3843e433611dcd4b07391db4d6e4db7ecff3cfc0c1ade2f451be34cf7d00d86a482614d1b015dc99437ab043756346f361466ffe977d8c6a4bedf4a37414cf7f8814a98a06a4d11ef139081432eb85e856f033ec62addfa2f91c683f52f6bc17108662b6cf4a899fcbc4e840b858fe3127d9912e4ba84352f88c8d34b4338473dc94c206deef759957c90157d712a0e534a485a8ea755d2acd8ff22b5ec754c21487e5d96551e275b10e20338bb0fc243cdf6511a04d66dbcd9a0c59b1657c9a924c78be832b1242a65c02f041293079ab2c598aeb600211b909fbe694ceb1a91faac3f8037dc370d8af630e4637d8644b517309f9074aba1c8edbbfb857cc617e972f10c672ecac8da1ccbc7c680d4d8e38dc6f83865446736e90b4b6540e1145a7e7d4f201833df2c22317721320a43f922a629b197460b21bac26470e3012cdbc5d384c5bef5209805648a41a4c5126e3c7129dbd1d48718bb316f71012f504fe1687cbffa8358f0667e528e578a0463ab8839ba62bfd36e8216d8d9fdf301723527c20f87cfa612652e6f657fc92d57f98359e733d481e8f1cb9ad14cdf7f725920572c678782d9271c8733aa1629a9c9dea4012e5b0e8117f1bfd81c74324a28d92661c9376196bb0ee04e3883889fd99a18a4131d189d9a0ca03e73d0d6c167d53c7f58db13aca35a323c572473bd03de31c1d69aa4337b8a794cf5ea962fd49c035137dc600bdeb23f5fbb080f30e7bdb3c5de8a24954aa534d0ea27fc20270eede74fc4d270781c39119a859af32ccd19c9ef0875032448bc93808db1c4304694485f53b4dc507b52879a027adf3476269a8434272bd12220505682fbe978702073925255462b3a5cb14d90742cc29592266dcbbf28dd6c3571358bc6428fa28993e333189c60b9821cc89f813ca58b0c6a3da74fcf0387f888f1943a1e3306ee4854577b25500dd28a84ac5fd1026f76933435ece7f38bccb0ef16c744284abf84f3a24b9f03d81a3c09449f6e2e7f684ae73749e08bf4992cfc9d7e4e95f3045ee15746c3aae5ff62b10cd9fb705b9eabaad56ebf5e1d2a4f975dc27965097c833016d59eda716530ad9e29e58e2f2ba171399cc3303e5ae3907584bf5346e6b119f0b0a9fb2f5a617bdefade95f4a36e2861a4ccc047b3a3f655b4ff9f65ed139f7c1308f32a22c6f5b56c0d38054d024fb26ad4b7c6220ffd7912ccfab37b59590f1a3490c53afa5870b8463d7e6251a9448d575e4327039a2416bb65d25cfd6ee136d595e6bf28e96b60a58590a805f166d4d0c8ea09eb431a81be04dcb6a5475dea07f0593afbc7dd138a9ff99aac9778bf440d3e8473fe34a663d0c018faeb09bdd5c1d283ac464cefbebc942b49ee6f4bccf3c2e59248cd7bd3c5c0d93c9b68e34c70403a73e2d839b36ad4b424adcd7eca3a4b34b2e4aa294c847bf977559c58eee92299ace0fabd21d7439c6659d7c74ddc78e9d0710354e45f45f6fe396a247be17fb7067eeb344b000787dca4e003d133fd045d75c97e176320d3264fa91324411d3d6080cb99eb2332a26f204cee4d7ce2d8d399618481dca8d8bb577a183f1ecf971c9b94ee228dce1384ee7c76a9715861055cb09a933ab602b2920d41091eb5c14ff15809430c901aaffcd70ecc051e87fa6d62f9a97e48e4a60347f96d0bce2e8dec8ec3ecafd291b9a2dfdcb1219650d1bcd0b4685a4b6302c3351a5f030a799172a6464d3032889fbe1777d41f42a5959442551cff5242c8247a03750457c416f0662b6041352d1435855348f81566769593b1c8eca46e86ae44ffa4eb90a2af3789d3ab3c893b54778742271342e390c1c686d59a22586fb3ac42439011697dfa5127a83f1412d36e3dcc7697087d07b6fa472b9abfa79535fde6adc820c5f0e65d1cdaec158fcb0fceee5641ba6ea5623b95410ae1367bd55a265c78805db58af2fc062916dff637a9ccd0afce96c349867ae41c7a1686d68f056219aacc81a8c291930f9f4602a9e861aa0af51710e05c594434d56445f23cdee64b8c5d43eafe2e6904e97a8fe59b36c8ad1e7e8574ba29ee1478a180d0bbffe8e5db0eac4b47f9f78d91285fa3414aa7293409848037188c0750cd2a349948b7c32795d0e48b4566f7255249f48d56fb2d1785ec3e4934a3365cb35af90b02ec768685ba199072041c4b3d6fc7f099495ae99da95255adabc5fc6b3ea26ee056a445950003afdc03891bd0964ae84e6f6361b98999515378da4037c2b2dba5d5f91da039afa378fc7a382be0079792ae9fcbb5e2920e4514c155eb025bd08bd142b5bc67fc3772fa6feb355d02c50f969b281e43804804b5b01703c9fc386888d4f3bc808c61412de13a3b70e66518e56ec8de304b2901d789effa31cdc8d12331663a1a9c61f62c0584c99f5ddd782158e3df32f5509d191e06bf97defdf704688d80fb48b68b42b0e009005d8361b758ad1fbcbf655c4b2a965449a359738c91ea7f13a528a83880022c893f51020941815c8f6996c36fdf537c9ae3e11272e9334a57a911f8a563c47089a4f33c6b05bc95c002db0e040089ba31503222b6b54525837bdc6966df58548e790a38941b7b28df87bc6c7c9c66860a15913999769cc125ef58f83203833625062ec5675aafb700b489366786c14d621ca9edb5297f590ca43f71a2c93211cd7e7338dc1dd8ebb1015c5d12424470c46a0dd7a8f2862171319cb482092da1a9866e56b5f20afc1cdfa0247d783368164409d05f95807e1f7fdc143ead9269e916c125dac91d2cc0b267fcb641e4c08a28067b4508b77d106fd4849642696f820982df7344ed9910a2004ccd8704c2cbf10917ad74c242e5808f9e39122299a3ff4dc66f3ef957666564a3225cbec265086bd05351c3ecbff9c41219ab8cf3ef1ac58501442b083c09a8d43b26b8d1aa886ccb046d04e152f471b77432816139a18ff6f20edbde91351ce7c4f4be25a6109812ca62dd66eb558ad28fd6decc03263fc7ce143f60af7575d2048213b5011b78ca3e2c78c64dd6e38291b46b34ae6abc1f188057d17296bbbecd5b08c0395120211f3e9e2d588d34975f8c6cdaa3929ef58fd1f393b085bfb0deb11b433c449961c48195ff4011a493492fba7d4e54e94a3c38d1521280116ba5ff19b627d858898c403b4dcb0d1c80e39fb9acdb1b836d6a7605e93281cb1f64746e6913a8910e27abc301b4ddf69a77038cacf1f36a4ca51706aadebe9e0313585adf901482c0de6b14154724ff40308a4076d024ade8b088441d7fe1d17b15bc8bed23921b6101b05f9436b382ebea409e6be863b340cfb103608a87da97775e8cd056c688353112942790ed56ab9da46322977ba0c426af2046bf4025cfa04ad8809dd04d9321f7087b135cadbaf5126dc5c1182421496f8b50d230f5d9a103f0fa1a2d42b4407f876a92b416be125ac60f0c9c10ead93145134cd1cd8b968768bd42af51da46073c0a19dbb405cc30976c1f3874324bbd425e846303b8c8c01542d6863233a122c1144910a8b2396ad987306a4a2dc8273a40d741b60625150922d0167738bac7e4f6b6ca52ab1cd0ada5e55d5d5752d9019f707206290d49b31c3018af200419258098cd159141c34d1fd803ad74a382a4fd32c57d11a932a0c6d9561fe176513e0cdbb61cee338fb54769c20084255b3ded5093fe0783796b18b85d5d93e650f5e39c53e317bc0e881a75c542a36653e517bc0525f5370c68487183b6e3c4f7e9e9ef258a0d67e09474c70c475e761cbd19bc62cb9714c79e9cc13e1d884e4c226f133e181068456373ae0cdae6b2d141dc72b477b0d864a57f5b5d3f32b6bec7e8d262d8a694a030ea07071418da035f40d4bed45df3c18aaefb09817a51e667e81e97d077849033beb4ecf4be80b504de9baba66bca16141bc89bdeab8bd66af424b266e6fb79d09ce85775615d43a99ddef8ad2f6813a7b0f8603ab8f6e6ff9b3064fef8b1843c8915d4616921e58c93593760469b8dad6017e6b289acf31b8b2ca59570ae8bbb622a1538cf7bcd7e41bf59101d56634d39064217d21d63ec8cce3a1b746ef54fcd124607fb34893792122e5cde06d875e2a7330c20383d2af3b07dc37a3389d1ec6197ad2e0586a46d700cd656a339bdc00792a796e3a07131a01a9f47d872938a326074abd889f81f8fad0f2634c1b8c6eac8af67ff9fc9ad0c1a862748e04fad1c8454e6cee6fe83804a0f16f68a6b4737aed674b5caf706e8ac8ef421e6e7f434e799bdfe8426c359764492900d6a7f1742e3a32a0277731c82430cb7bf2c4fde836c50632ee7cffdec82c03e336a1042d3307239ced5b886bc13a23e0a7bfef22c1721d97214e8c50fceb2b4189a583610eda9ad21a0a60866a165a799184b520baace846a7e79a6ac1dc74cbc53c67f30ebfb622a9586a3714e9592da159a5debe8ef376708fd5dec1b17e83d5ebbdb41814935a69ac4c5194d13927bf7fc501a5f5fbd929251f9ec33800c5632a1236f844a75b49106adad7254e06e48a1b13ae4cc0f09463d6ff283e68cd7a01c52720e0c22c9140447295798afb48c93c242df820ff06d70928fc6959be3a16cac9854b572de7f7006af27ec864b576f3b4222d91ed2aab11e66ae912c1040e0a1cf1cdefec6eaa263bbb85ae81c724145f093520014597200a9710d9127f0b3e6601928453910e17a85f1700038486bd8c132556b894455130a96cab26441c0bc9510a2977e87ff002991331f5aa8d4700632fb2f11ddaef0203ad8c14e2cc2cd7dc0163e03582a78a78074d103cc4790f0325056dc2f044b37a80ea8397ebb9581c5d22123415506f9a081e9424dd3413000460cb144a8f093f619971faf6d98a3bded5c8150e7413166232ed59b2a4f099696c62f47a84c39930d26ba981b41aa55d0469519d6a4acb8269aa5471e45c94652ef611a88460bb31c7bb2596fcf65929e2ca36297de3ff4e6027e4d503135649d8fdd91669d324ed39a1061a3439a53a5a60a326dfeb45eec36f832018b5b444f0bf1524b45cdbcf6133bd96a4dafa1c9efca189f8e1260cb2246d8f02c4842406161ad13ed4a55a87b294eb4789fd175437eed5b028727ffe7439b1c3b4962407c30ae26991404edc855c4a01c5b54010584e81680ce4808f1ba314b00ccfba5f19c02ca4a4e14357bfc41f98a3377238f98de8844d1c3ca022591707774f4352b2a1c5d3e856ac9f5660bcb587e8c3580d6c76fe9c396e06ac5e8040ccaa46037549f8d900d9c29c40f96a1863c86aeb7c375f5d3c484fb534902702304fef264025ab229fe65e509871800b224b20ccea288fe7a38787a3b7442f300101b79ce690583384cadcb2546d468d34318fb3280a853cb6d60bd4f33d2143dfd03c062772ca6c9ba4317a3b61dc658da3e35c91a2fc6e2b1552579c52359a109e27667e7294cffddd04a0937808253b7f84dd977f9a1e00b88a219ea7dc50d329fdf0d9d0ca0c23882d1aad09353bb1ff4a53f3250949c67d1da8d420556b4d399de51a0c1dc77b64dfd5c669e6d84efc158fec2313fe629cacd1733c4a5f8c71a77218f2a56950376c64d7302c4b56c31fd3d44959d6afad7bdd39dbdb4d514855c480f23d106dd50844209b0a546723a4c4c82b2f1d71dc3460338f8d59c139c842d5b22de4709c1317182084200a338990fd59f7ce54cd90991d2128454a0823be45aa93e14446f90d808f06ce74c76f3ed2ed03b0dbf5cb80fce8936eee86dd636dba53a6c66c51b567c1262da575c4e3f6bae55ed01830892898fa9578f4596ef081fc05ad20c6c58fdd0dcf9f316b42eff73de75ae1737f10f5f9aa6898b7c8838197a4cffce9ddb44465c92bb6e77a1f79a172ded3a893f17beec8431da52cf0ecc0f78ae3d6ecd3da29eedf8769669d3e9bc7e6e0e59a160110e4e82af2894800721638c65f60fbe3e80b6d89fc99b52cbfb50292f3c7f513bb221f42234d64197a56260bad1f06df318236cea18bb5700149cb01473e335d7cd6ec47d4ae8c902077106287d67db85809837bb821064c9ae0ff9552405a68929e054cb5af4d845b6d342184b55aa25e7efd55e379ceaa9f8672817762842a1958162306ff629d0bd6d6c7e991d61c00343e2b400244c5f483a163a9a76ef38b8e8750e0b07d4be5716ec971e0eb409db861747134338c8989bd4325f3d7b5c999cf7ff595f841959225f04d5d170522941e4242a972e12f5abc280ccb6738669007b59871ce7597f9596b003b41c233b50f35c950793c3a625898fdada168fd0d18c81db19f51313161545845d8db20b339eb7acc5cfe4119b746d671b1e80c3fcb29a0c86b22088fa77ac035a07eec5bbbd364c0d7c4258c3591cc102844fa863353590206604838b78558ecb075a4cb6738bd2e4c203ef9a6990b8077c627f472d0bee8c2140ef111468d8afa022d9d76117ca87b7f562bd0892f16b574a924ddbee141166977844943c09b3e65004a5bf0c34ccc6c60b70d774f6758b860de80cd08d5dae3d0951c5bda3eb9f3ead78e19b26e2b16cd280641c4a320c051ce540433997b337f5f2110be182a954eee183ef8a93ac4d9f250531e5a921c79e78bbde82d4995da489170a73f9e4db0df0c203655f0e52f41305e35365908131867fabcbe1a54d0198c1d001d11af417a6e0a7e75a7fceb8645563e33fe0ea2aaa4c4d84c7b03c7f05ec37e2bb1e011bca3f17df3076dc4ad2d2d242c42ca857cdaed821a0a95438cb5018b43e305a8d188b890adb3504180c7536a90daa81ec34130865db10c82f9501b67a8f50a0c02fa63b8a8ada4967fcd9d7096f7dce32d854e0e25339b217382d835c555f6d0d840f72d0b1a8f8078f55d7afa537ebccdc6a75981a74f60f7f11b600408a7e417ed66b889f940fdd779c7bd194af212853687378f56a0b70fc89b47aebc32dfaff70e392f74382fd14a06f4e43a74479bd371bbf86a09ecbb77bd6acd63e2673d392f61330dedc85c4531316016c08a1c3ebe72060b7a0df1615da352da4b849123a5f0390e3536b2b020899d99ad0c2ef0d9f963e0d203764cdd806f92e8485ad4537bac7756ed400946897d756a569b00687daf7f519e73b75161f0cddcf79cd4ab672e45a6d8e97637a3b2ed1e520a983782752ec266d22ab3b75479ef5a9ef74f5c2ffefa4523dea50a3ff507dadbdf1bcede271233116c70a9493fb8943b903b84b2b340b63109b327c12914cf9f200eb131b0e0df5f7982482c37bf784881c7d8c294221c8b989cf0dfbd0367f07202207ce08d0590e9507db901a2def4478df167fc7801bebeb7633ccbbe3aea84377b533d6d00c90cf9ffa7e20d8809bcdad167cf47ad4ea2790177825eeea966c020f83dccf087dcc27cd05c1bfe448419ca557c94d7513dd0228139b7ea58561c1ba303064f3b5b90580feab4ac661677cb373f9d52d8044c40e120b5b4459c9f795aac1ed50be1c1d18a72703a42ab317bf108bd2c701a955618b240e2fc14c22221085061c28cbcc83c491780115367c83057491b516cb15c1fefb132bdf617eb942fea8cc97526fc2ba21cd3266d82412876b9a0f83578e7faa3e631c16f8749329eaa03d7cd9718b44d2c8429539cfa8eed9ef2d634692c048645e5f2c641539c83563e8514f758bfd2850d7bfe15024421875917ae698cdc1108304ecd83539766e0b22e820edd45121b336072e67acebcb2e1a9beadb84f06248e4f72b0a00288ba59f67ccca91cd94b56cc6c1e8ea77b385bf2c7ce0aaf026c12fd2d7428a5e482a0fdb2362ec17be85fe971759ffd054919a45cdffa348ab0e5e812030159cc03b19d78b2d57be5c076a2d09f54a91f91a49ba38deefc794483c836ea63ed4252b1312f2617c9948a867d6d7c9f95ab61fd6af15f95d66c265bf9a98fbd75c3e73aa30e0af0f8b1e035b13a9d0bb613e8de0556ae00be92606bc95a90ab20462a7cd6b5b9b5fb252926704257f87f4e3887eccb60620efbe4d17cb84c9424c342f989162ecf423588cf36aad32cc19b0b0eb1b1ace3a87092bd070b0464216d203aab6ddef2b2758374d2f10094b4152c7ba5da4995e89bd4765a7adbaa87d5762846d79d52e6621c10e203ba175e7edf5ede13e761c2cfaa5cc17e5cb64618f69853c091ef9fbbabd8b57c9e2d72a14e23d3ebbb67010d8f472c9805423df1e68dcd526e21891d5b0f235e7a59aab86e75f882fcfd28fe8e2aebdd6d2b19d8b9b19a2807349686eb1606dea25cf97b2e587d203232137924fca1db45dd2be7de55b6a760dbb01e5b2661b3381994eb61a24ccbda60bd322646a7ac4114ab145a1c3473ea36a6628a5fed87a616fc3ea760ca41579e138b62731e66143167f791c88a67820b56292353c9f9f318db9a142be455127972a298055e93315f9e548c6518e1cae6fa1406b6ac8f136f4b0a217d2de576672ea170824b1dcea9dd37431707a0bf6a12d411f163bb30d90b5d972394d7b6c32e87b7b5b7b88f6c88e265c2324565f92fcb17008f6c5f9e99323271165a0aa6a81494490d7b935981dc43c5296da0ad648d16551654ee2b7a98bbe0f8d0a5841d2aaad430aa8cda85a2ddab1be7d2049f241c3e5baf1ec8d341b36f8eb49c1ee56083c6d28f71cd6f4653cbd98507081e795a066e226c0fb4d2c6e1fd7fb7e177bb0d390319b4e0948c720ba8b1ae58c6280247b777a7324eb1d57c9fe7330ae227f9e4a49350e44726936775937367fb46b624b6f69ce3a06bf0e7f9480d29061d72c495e0d7b4c9d66289d944857fc37925368e3c34d03429e1e5273bc27918535a15e7336c140ac8124e9c2e9b561880179812cd08e33ce09ea7ac52197b34c9da3aad9435be0d6aa53357fa1303870de46ddb4358694ca249e4632b25d56f4b458f9b0dcf5c91764bf8a94524c589c3756bc0b0af4f2badd46e6ee0ac4e6156723f6f6746312a50495dfe4d5a1f1fc85412b61363b5b1bf5f6d29e1e2c6946868852701d5bb057df911b71f550481dc191d8901a445c12b698ade5583ae67a0f226d1247d3fa6dce4a78a0cfe98d9b4b0581b47b88f36c34abb8e7737964df85e012e77640ca78265a13f4d3428329c1e53f6e152cf4715f8b129145142156d8dfff644233ff2d175d79f87bd37e1948fae2f574b1d274b0ec13bde05ef8db54f1982cc795a40119ee01099662614e7201635d490e7243caae301d912c0b703d8dbba7a78d299d1fa70293202bf7cd10a7f8bbb3bd231bc8a97b0b0060817e13e747687db9876febade1be570d631772395cb676fab1fce95322ec350d9672423da22ea02b930f3bfa90bda31dfd614047feed67c1e4cf11c4ca91fc2f6b74f5383521e5c1cec9e3d81a8e5d948b5400c87f9a0fac49508eff3e1f95911d5dd13f3f1df388466a3af4b1c397446e11f2630b55b061d9b76f2ff7b71885a8ad424ad8f4da9f5b901f5707b438c2246983018866826cf7eade1b921ec3251f5a6283d37699964998d56472bd1a08fe463da4a91ed118af90bf3a7ff0d49fc554f5aa79e38836f6b19ba777cf37f8241aa725dee6d7fc0f1dbd3e059c6b69b75dc280217426f1f3a251dda3fe726e24a0bd10bda449bd55df63cb9bc0ce77f0a32aef85c78d69978e9de58392a631dd21c0dea658065d1a5c2597763c846ac512e0cd160e9448d1d7cda8a5198cd8a825434d4a0170cc266aaef5a78c7d030ae80f136dc41692473b059d04b1e972943d86086ea019511d615e21272599c051e54e458b5873eb3450437a251dd7fcaa5f6b549f1cd2dd1c82dcb680be32a1af7f38f20067e7a249edaf75ff4699cf5d25b52ccf8c35945cedb620f0b9236b267e804141012da3b543abe6bcde1f1e363621ae94da82f61cda86eeb1b2c0e4523035499201ed5ec1933f73104ebaf827eb8bd1fbaa09f829a7206e8369619a47be9ef37f6563e31271c9cb44bd580747ec37cb50f32629a6233c07239cd8ca0b091cb24cce0bebaba8362701d7570b8d13a960d6ba7316ccb9d12737436617e8cac9921a7e15604cb692da81213980b4742882c2cf0d38cfe221b8deae1d01bb26e4ec56486e02cda2b172a7944cc79857a8744533ecb0e5d8d59a67be46712c48ba5d2fa34fac8fc8b3b12f3bcf5a06844ae2c44462761d752a8de2cb38b0018e868581ebacd22690392810704661b5b3536c8281fcb7e1ca7f216892a1b09abe4260a96cff14138920f514a3e86139bcd09875be55d9b45e8a674980170c2731f53f221f7937c9474a400d35900bc75a41ff4d50beef98cd403e4e7b30a89041d6a107bb376dccbb081368e5d5e64828a2e302ba0b5123c048249c60751ae5c747716ec4bbaecfc1c687ee3c34bae01e5ca8c22e1d791f12a72be28d16c4e6efb85c162741b27f2c9d5c7cf704734892da45aa0cf00062c390c5275fb52c7a2f900c1029afdcedd88cdde606925011a85c42d6f3c70af95c399ca9a7322b5cc23e58543fec4ee52a87532d33106f8a4d0167e9b7db2f16e016a0c86ba70fe6c03a712897083ead0d3b31175c331db5963c30408370c08b11e7f457ea44954a54a6f1c15ed771eb2a0fb1335a42967fd05809a1f6c3c3376a6fc80657a9842eda066c91f9fd9043b889f822f83c11fb28e83fcaf2864e5785d0ddbbf60da73b86539feaada1b551eccde7df9deb238a963666179416234587ffa89eb4e19b2a992ae6d68a07e18a672a958df1c69c1f872a9e2c9b2cea80b223aa626b3b23d81ce4a598d2d7c374cc978fff163eac42c84a6c0cf88ca6c279579ded7d6f621ab72e180f5b0279c7b72dbadf5e04ac30d0764834e83d5f15b1e50a9046a94c6fb653af7ef215a08428809b8a58032e78dad5ab058cafe3124c000144920d85333c62dac934dd83c7060d7dacd811dc81ad13275a020e202f8f9b8632577249dc1a8a2dc25ffb727fdcfdb7f9af9ac6ec8a6f096260f7af709b689a22dd2f187ebb73df5e439d2f9361a14b98c48f9eca0c5259abd3722dbb3bbf98b83ca4f440b6552b1837d7aef7c607aee0a78e18a0ff430591b78f62cd99fa314bf7396733b2e7d946b5ebc34d0d86158bc6175d5cdc99560970f34e1aeff5650cf47e4237cca0b53a981862d0e8931b0ef3d8500496e04dbebbbf15ccae0da299dc0fddc597027e4eaafef71bee2d6d74829fe1dbf3d2d7836115a80cc5aace84838ab19e5714dfb010b8c79b0008c6f8d350d3c8687dcb2e48ec269d8ccfaa9d773e7207e1dd28a3857144a4d52057cfaac8bfd41a34321509e9b52c16358b068917d5832c6654647c4e2d305072df04c35b2178bd08b8c29e91a417128ae5ebb95df1a24a06d1f1b1eab3b5b1ddf1818d613909ce3234242c2aa8cc5e163009bd4403e03732846ceadcc36fa935d62209bad635a69c4e13a71f4bed4f81a9d514aecc664cbfc638763add6f8b99ec84a280cf5e9683e07b20b11f1cb0fede3eb5ea69af42e40ec973ab65fe40f5bf283aeb72556df84c4808cb28231132532d2dca7f78a99c857e7c67ef2b1357b28b994988d90a8640d8ed9083d315e71d5162c7ce8d08d4660ba990109ab991ac399b951ce4c46b3fe7873a39021e7e12b04e653a305ba793a54003c46769dee3197f2ad465a298cbc42f3d7a1f480efe98d0253cd95342c4cd22049cbf0b0c267a104c8b33f961e2af95026fbda6d204736b18b49700f8e87a21d096acb73dc1a7ff29f49032c5c2e7a45594740fd4800a368f7e08758f2450a803a717f5ec012549c04bac9163b8a99ab94cd5941671781c0f8fcfafde5279e14be8e5360e18d26e85740bd89085e1df9bc3189fdd34c6e9538f47d061a2c1fdf2529f4b2494a5f0f6de1e40b3156dff9b59f4299844a507cbb36f7bfda9c35454f47b3690986958f46c80710edd2d116c5e0e4faf7c5a68682439bb925a164969048d9e86f2474aba183af13f6dbee1e839e9c36e0a6aa342c86722b6e171280e1ed4e58531ac8129cc0beaa041af085c63c777a5a66e21c2b58b18379948c3f5e5fb3051517b889348deadb315425536fe5dde70fecbfe37a5e3660efe3c87e8ece9576674bb93db3d0b47f3a771cbd8e7fff13887b7bac15735d7c6d9c6ac15dd22a400f3deccc24949ae9219c9ca1e8fc88fd798cfe5ecc8d259a84fd442be39514c7d0b7fd08ef112fb70df9f231362776ed9a766409b8b809b043c681159bcfb72331de75cdd6bebd4c453fd704bf7dd295499067191511415a4536897bb943a6f5f5397ed9a8ab85ed1cff8782a3e889769e5306737b81249517ee2a105479b54f45be9d580f83d85c8039d9b34ad6312d86c6bc48c30a3dc1c3297d855d49ced13e2f353f9e41f252b6a83e72b6afd2a5e7cf54068ee99f2191935166c7d7135db821b3fb4b5b598bb0413b1a30d8bb731e19f57b969083ee6bf340b5547dc0fc121de1d079ac11336e0cc865d22986d3b95826fa6de54a45e9d09f63f2154a6da26dc785d33b36e6004414424fd95dca6682601fc1d61417713aa6a2e0ad11c03e6cdebe24ef83ac1191f5c77f43135db0e3f7fe515b185873d6f6ceebaf125fef4500e4754569303240d40e6d5c7308cb1d27efe375c5a6d613abbd2b196cb04becd63fd8e1612bdb291848e6089a5258991254c0f4c6f4737f27c3e6fe218f59b7e3fdb5423066cd2eed6fa539b4d0018ae4ad65ef9034d7b1592556e7d5aa8051bbfb112236bc6869385e19ced1e2fc2c4db4625d439cca0a309146071687ec3f7cfc94e3aa282c84f080aaab2e4462f841537eaa96378bb74e2c2c7e24f38a3f720aa5f37b4b34bc5d1b2e38ae1fc869fc8b558a35cb6e509670a24a4fd9d024ff6b2d2ce730e0f0359495fcd98a2199ca42b35613db27865dafbcc75c719767c48708733e65b53d052ea0922b1546b33d76cd9b1b0b11bb1b79aed07a20e8c4a99f0a37132c6b86903f556db9130b354698e3303e50c73aabeaa670a6aa297c1ac7e9c66f708fc5bdbf397474a34274f448d7935d8b040285192b6600cd66042fd41400815fa9e2f838c315c1a02fb820c1dfb36d5fcbedca77aad73ce9420e7e52a757edef19e21909bcbac302c7b1075db767ff16e8c933ab79b7ba4b8938f1ee2e759cbd383aeb18bdc883d21b8d03d0a312cb2c307d754889022acca3169054122d191dec1546eeb6b12b8bc940307c36fdb9105d512b5d631ac344dafd65096e51dab35d1c33fb1c1bdc6f535f8467dc5b54b888c6e58e2894fea19fc684dcc35e22e1126a7520d75d736a8ce3e91655dc1e8f46a99cd05c5411d72b6e1ad6b34e5bcedb860ed62310e96a431fbfcebfa14a444bb134a73251c3c1a33f75c11f66d97c813fadfcf0af55f00efd498ab1bb1ca18dda349098c881046e7989b162888d63841172a5bcf65b42af81887b60e9aee9f27b6eb1a1957e6b1fcc8f807642e568621dbbabae3abaa7d03ec80b915f155d01e6aa08f2f6d3e24bbb4c881a49dbce2de1d45f7f999c8336304838de2d3a57db7f23d8fb29026021268cd3200bd7d8937fdd2052eddeb68d8510bf3562438ea0eb21f5eb5611f4f8e6e0871716e786e552e4b480c5026bcc85b7103d65c7059dd30239ea05a4cc337b658020b061174d5c00e5a19ac7c3bc42c2b9310dc491fd37d50451a67aad59a6f12ea4b65a5077e7ea387589955108d7d838457d82c90bbdf0d2ff79627ff9b604de9d2cb55e10329daae942a4c5eec8c53525c53367b1f3e971b63f4a05e36faa7065ac35eb21ae0dd8dac51b045d4fa68babfece59979cb36c54cef4e4363d86377d0d667bf30263d4d70c9f95d620d1a9b1c584bc3f08a940dbd6db17528dcd1ffe1e68d28b54be1347ce0c91e3abb56dda5ba9b32ed448cfde6368f41910160b19b908f3b5609cd833827c990579298fdbc527868f01aa563851f094847dca8644eeb300d19dd419da702f8bd79b2b77a2d210d5f849bf6f771533a9e9a5593baeae695252629a61fb341478dd8151571873031793548503f53791692d5318d39d93abd6cc5e77f5683bea336673382b647829101cc83b2c49405d10a8a50a5b4ac733cdfd8f55d4a2cc36d2144ac51c95a6878a041fe2c79302e7d69b11112d4214a3cc2d6d54ad40b9b08953842f1ae0352bd98938bb615ce3b9197a8b39e25fc62dfc7ef784695315aceb4724bcf8d3c7a4c0105fdcbd8d8508adeec78aca5d536d34840f2d0d4d33019e7fcb75df9becc703243141d5cf935f9d42f6b36e3f67655845ab79add0f050c0ce40e7e28179673bf54c52950469aafb65303d0e27bae68c18b741ba8f7c1fe8f9633066d49c47b523c6f09d7e441895fe50a71dcfac15e0fcb13f5082d2fc94a5df8965b5e11ddc4d11d36f69cae7e93694e214a0996a0705ea35139b3f6b9177343ab967c6d848a43367be183948083883f4765312b5094103b66e8c8d35cadfe3c776154649a9385a8442c86a391b23bba19ebbbf1d0201471337522399b781b5376b9c3ded4db9a00f271904655ac4ae42474a2cc0b1d0f3528f72c57e5e62f800a2c6c8d19413e51c42f6081bcca51ef3d87f16e16db9597beff6801a76c3adf2793a939d296f302a351902a3a9dffbd185ddc24f9eba8d57dc001be14c69b5749c6f6c6a7eb6163b1e1571c6f107abb3b9a1be3f3fc0f888e69d07bf07c24be2e01913f7df895511c74ed0197681ae1f86559ecb64a09f869c50412a9d8ea3759f356aad509da3617f739cb1b95da1e19b5140e8c0ceca139274d2ad7d41247b275ead5039d27667547520f7755f9e2c5c2c6836e5f4027b0160801bfd3240e73a65d1a97f3bb48e431c241028e49eb846939baec30c42c717f4cae9f89a62d2fc51ad6dae1cccd268f606eca0c96dcdaae574fd31152524bc787c244c69b31543bd1c488b29f7101f8e425eef3c6abd2bc0c55b308b305b30d1e7387462087522117596cf1dfd14a079430e312f137220959a27864c8f7b4a2a1fdecfdf7bce75508ee81679731f32d1f7f3198e3f535bfdfa09170ff6cc0a95719916083a0e8ad9d3e47120c9e98ffc7e9398dff0d74fcb3361b51b4f24d293c722cb7a5ad8954b114192833d3b1953ebc1e8d12fbab74116e56d0e07519ad354ab86056234cef3704aa91c1262b4d3db4fcc12c7a554a10051f52800a0dc718c519effe3fd329057226eee2121d848fe075fc439955a509a5c1ff8506c68d54e6bf338995b6750f9433dbebc89bbc3be0b8c650f2352925dd5b22dfb43834f15aed82f3f70c32a948cfb11b4867088fe0569c2f5ba14c012f23df7076eba3b55e2cc70527d42ab4e57191f8a25ceb41b9d4d01dc64a8efc67fada379ff5d48c33a0e1c3521387fb0952918d8427b695e8862f40c222f20d30a13c7c6cc8a679fc2cb8e469018c977c31168ad502dd28428530d1b630e95ca75d90543b64da9470b0a08ba9b1d45b956360cd7a61e4d9fd5f339de6c508b4831b55a222159f573d55de262c44e3efea22dccd0063826ae5882ffa001f78930142330c4d652c067431fb9a574fd40fc436b4b04d3e9cce778c02569f12dc180e092e8629fc7c38a70867360dc6da0d5e37c9c14733816595ec3e418887e9b9119fe8100374c6823bf5d06d5d1d1469354971be8640850805827dfa6f0475dc530737d8e552701cb47a35498dc2e01285f910aa51583e810d622bd16b450a78089c1dd5731e1cc5bb4fbfb2911b3c8aea094426c16985f27b085e89ed84baf28f85eb3cec2d31c65116978a44a575087b72150ddc6460babe6a332962faeb90c4002887d174dd01bd4194e04488afcfe402d54b05fd70f9d19daddfa35e9427eac7f4ea0c4cd24bbb1fa04e7543df268f32cf221b57b1fe9156c034c4aab5576d7e91820be44060874136b4bcbcc6b4f27681575d3ac2c0f396b3fc9e8913c225bf35b8cbbd3e4825412f53c6b4ce56305961ae0abf8ee5412eae33462bc489b6c28a3821e2f89afcdbc34fac7fd573699e46f2b381daedc84b34f91718ecb7de5268734f547f15d21089c88b5bb1bb1b5df6ff1ba655212acacb9a1d7afc9927abd09fb7493fe49bd010d73e0c6f5597c7babcc094c915c4a1414583e6239f0b75537d975540e73f3e8bc0d1b28c073072a1b0596bb36a69696c514dbe9bed38ca8b624962632461e4a784c64dc0f258d2c383d0fdbca7a08c39224e0dfa6e13d99d70cb5290cec2d725181c86ac2e4dc3fcb2a5e630ac60ac4085d76b162abf6c90a3969274ed348ff8c2493ab00b7251da422eacf82247cb2f0b0f4f31bcd82ce43c6a8160ceab52db4d5aaede3f71f878cd109e6795a01b7ecb23365511cf890ce9a45609fe555ee41680d902141d3cb45b46400cb08e53b688df527b14ec84264d0ca6ed9b3615f55e4f4384d0c6d4489cd75ead20a2db945632752c965d06a402f9ce0b0adae1caf70a77ca665e2b3642cbf93557356ba98b4a46dbea590f6fbcdfe359717f1c465a2b7aefa88894f329c22f04e1e3199189a71955e727edb4638f849d133ea0e747b1f3043400d4a2b8d881794cd24cd299bce6cce65ee63603c56d076a4a427b7b86fc48be1f436ac3cb21d969014c803f0ab5dcf72a72e8293db0c4f0d8b4751349e144df9aaaefdfd875a98cbbf9858aab07326e3e44d91c51813cdb84861117bde4e5dc7a84f9bca8e960801c35d29e3b592543f5bf197982646e510b6d53c697bd3518e462d7788b04d66626952dfc99e652064cf68eb6993eea16ea02c30361a1e69c413590f44cae96e8d6a9e1931a45379a742c246bdb78a11497d6622eb2e0aceb201781a1a22b6c1425319aaaa10a9dad236d99eb1019b884ff186d6759e18948b8fdd46d6cf83f5efbc390a14e97f8781fffb40811dfd57bc684fece0db13aa6a1c214493f19cb0707d9cf72d9602293ca31bbe5b8d3834094a8d0e92feb4aeafad66853ae8c3b6dd410abc5c1a5e94137b325200fcb0545d6121a790afc49a8c8cec757f68f5991b0c00fa1086d54040d1452a819a5c1aef4f3738a6db25505a7b703b11659fd0897b62c36f951a4e0abcf1aa3e10e0c9e0e44fea6c1a95cb7c5a36d9933f9445fd45752fe1f1f680af3e92172c55fc159d0f911f9ed2116a323ffdd64faa074e649017f7cedf28515ce3d46cc6d01611617fae87d82df6df30546c589e9817b9694e4db98c63b0b9ec204eed41186b62e4dc60e69dd9fb5e3db4264293b1111aa1be2bf9bd982f2635445f53c1688e52143233a10d374e01895d072ab317b6e878de15a65f991f93d367e634a8019b4166927c9a24b98ac0725278a7dc9afc616e381782d503be9e49422b45377d34ac9bfc0089b037bdfbb0fc7eddc00dcfcaa597d181e39b7ad17586fa8cdea62d8dd906f56333cc6a831b9d03cc5b90c37339b6227489ea9900dd5e1d5908c28020694d9a3cf024cbee07ac85add847c1aaf2b0b62b303e2d512b7c08fe72e17c603a9b7c581a7b3fda3c522c3e30f080921431e3a4596ffcc941612685df714c506e0b216eac8cc7d9691ade7cde74edc2fe418da8b3fde3224eb882444a4392807d44d161e5d6c51dd3b771dd6a4bb30b91a20eb64766b8540336473dd097dfc3490e8de885f345995c8142fcfc62747bea4983f02bb69e1d567a7c0784e456d326a41e697ca8a8f342c28203df70ea7534e6df76201d93acc2f9951ea250261215ac58348ef6f32e1e7fb5e7e69d9dc8107d9a253b4ce4efbd5c6a8075b23434b293fab8042e9ab62161373a9679132b775394c8c6013489ad462c86a24431ed68abbda932058ddd126a4b088e3b4575752404072d48cef7d4a83e6ba7034ef779bd527ff4906b6a62e15d4869f51bd30047a7b60c9e29522d6b02cbe992283552200559a76552a5cf4d684686376d2b69572d58ef12c2bb560c54a9e17295c8727e5ed5b601eebb2ed7bc9d4f52001b12d5ab85123dd70db77b346b12eba8aa653bdcc49ed987dcd9b6fa9e8073c71a311a06c31442e39f7d6954f05400284403af0c880a71f3a096289f9c97f8756a485baca2066f230e0abc16cc07ca8119caf43d44ed5ccdea9af525b3fa5e9c363121d15e6e898215d6a9dae0764599d66bc88bc037f291c879f31b05e9be4467522ee6d36fb1ce9603202d0f6cbb30532a962f3881e604af270b9d639d622457985216e1657d25bcdcc0df17bd023a5729c4f151162514e1874e3d970be14dd08704172488098370c27a90f74e15b0a5a1612d29feeef192c412454da4040ddcd0722963c254b874dfb158253845fbf7b6015b0833ca2cd024c9200096cc9df8a4a41ca0881011b1392401da68cec795093af2e2e7f83916089733fd4ec303dd9457e17a2e44eca9615f62ccfa3870ce672f2f34a0e92bf60072799442adf708c17c163c0d97b483fce83f12893abad2b3c66c1b1ed0e2484170799a561b5a6c9d6c3fcced52b61e14cab90698d4dc9093b6e09aeb491e278eee4c6f257fe4fbdf77f79a672cd5515c78e49e9dc3e81b0d51db9f4d970bceaa75e531383c16420759d972e8f7a7362410f0a2aeb0014fa0fa76b4546b42c8e15cd4f7c0b5228240e4f0c6ef6007debb09c1b4c8e63e21798d5554c21044bcc2a6e7a2136a6757bd456ea7217bd0e88aa3226d65611c205431747d132602d7f7409cd74c167471f8a7041f60b4d41ee292d551377078a5fb9361961513278cacef52356f1064a44ae356380b8bcb6739254beb5a3a6cc5feae7c4f99dbe81073fa38fd3905bc159d13b4e896bd023bba3f076e276444d87360b3811eeede71b96cee3682a27d35282fd6f44989e73f4138c4a29eaacb47cc28f2c5f2f2933218476c497737ed4501ce3e624598b6ef0efe7de6a37d25a051264094fb366622ad6f1be5ad5c3dd49655f0977c802a55e6e570622135047dd0ac1984ad7c6b0ef865ab2e64d15ba658edf0a89595c2a96470eb134283976accf90a919931e1247f39f15296f667b09700e990ca37ce8a85b9fa32cbecb6238a493a416201f6b24beb3e45371c973744430ae02d85237d510c2a5ba7106eb4106cabf774d04ad3a08c66e84675739dad7b11268a21bf2f7e51baf213f4dbfde2ce71fed0c043d37ab246a288d96ef4131124c9f6aa4eafba1d2355ed51a15711e2b827329ab1415cf7c61cc6d2ff614a2c9d05500b310efc37d8bc05f853d6da21d0eac7e9a91ca31841402d249db15a370a44f75ed3991ca3c7a51a9b84e5d765d316402c11ddb9df587908e08054961f9052c1aa5327002f1e2f8bbc3bb594fff81d8236558cf5548a40c4b1b03721e3275c561aa58b28f1fec346091afc844435828685e71cf35814d50886a0012f3fd0857e3303d15f11b2a0a2b6df2d71a9fac43b0084e11063cb411400f4fb08cf6e9021a498f018f66bab530b20e58f0fcea73f64c6d71906adf320cff8f1556eb4c9bd4570d362d1b7db57e8115a8bfde565a4a2430ff5bee598cd0e01ffea8b3fbeba0db07286a4fa5d61aea62608f6ca5376ca18bca8f3a60585fd47d8cb7ae18b2969adea0748bed7ec7442d0f88f5cae067d899c0b9023a76c6388e22cc050eb0b55801c1634a971b4ddbc2d3ad671a57928a13f321d9e335e56ad02fa724fcae024189cca7587d498df9fb9c978a2eeee7ce73c892459f0452ac026b20f1f08dd4d3daa48b8a508a5ca9aeaa8f67bda8fd57c837877d5924a4caff0f185688c4336beeb1034b700f52ea05eca02e38a3fe60e813522e082ef724cab829511e0fbaca9a8eade836e33d3356e41bf2e1f156984b189f56a464fd8cea525b448225407c1a41c845ff5e3fc49c0fe37ee766f0c0caa2efdeae03bba2c0d1a28b28a1d14abef0274162e109a54fd0279f86e9650d038bd6e5648611f1dbc141d110eea7ae35468598dff70a8a31da0516c45f40b5dd835c419fb1844fc593d343d78a2a68d05794fa08d5630fae41036431b8bb5393e139eba0eba01ea0876ed7f6a93ded9cc30733f55d9e67cedc7e741a20f5ebac0ad89fa43b8cc78aa42c886032cef1c11293cf21d23ea0873c0ef7e5be5179918b97d783cce1c1bb965c4dc30b6244e16bbc3d56deac22f5cd50625a95d3f6e4272609e3c0d85dcf23d66bbc3197e73a096ea919a88b1f0c62eb4eafc28162623cb1e96e523f6f08a1fee78a64f6949d1b4cde3361ea87455776582f7df350a30768c5550bd648d6f4234a66cfcf3696cd337357153e2a1fa3f57a6fad70b369b6766b46d9326ab4ddc3183f9e603c9ac3409017acb59636ad0b1e7a9c65743aceed41ddc86b0f08caf5e4e980dd5f326eabc28e1ce681f62307a2f4b7e2c031765f8931c449e8178688fccfbddebf6456f475de2791e12f8e62c434cdafb0a84cf00b5490a36b4548e59bd7a9a40c4417cad2567e8ab2725dd0bb6e1f31072dbe354b78e4695ab14c41824da053256cf8a8c08e118f0d335bef1d324ab554dc01e4b00962f272e9c092fe1134f4153f7f41f4362306088e5e936642260e35bb9a8a7de6f7833a0ccc26ee9ee69d5c5c48909f1bc01028fe64a0fa55bafe8b02302f0f8c2182c254a9fd584ced26ae066c3c56fa68281489fe8cf0dfcf08cf6a93fa9a83d7186145fb5034485b99724f8a3603b54fca0ba520d87a2151b20f75931dffb2dd128b8d79fa20a8da46ea6b97e8d4c4f2ec12bb07b6ba8d781d3712af3ca4d0b1a9f37c57ccb2bbc4c53fc3324feba1c7745f59ea2c010932994243bd40268841bc44eec3e40bbf5ab275a02b1abe007bd399e0b8ce14b12a28ba0c77864c89e05cb5a78ac626ba25e9bb487c5956c8eb16f42b8423536878352dac51a1c92b25b5f583f3bbd52c50a235958cf45b0497cada21a28ca88424c69bf6a8f5e270e27599802c69fdbc0af25e8f70b6e5d66360f95499904e5516c39e7e3b1486bd57a55ba24e002028c164d3614aecb67d141a5bca59172acfa2819f860aded79af98e2107d4da7fea951f16803630644afff40b27e8911a23916f958d579f7780775556001a64a80c10b3547119c29823c8e6f6221ea62f2cb7e7a16bae65baf063169db7b4451bb545da46b5f77f1ac5df1ff72ef38898164d53b23bebcdcdb71d7d45e3fa3266cca0027f87c8e8eb6bfcd5213c01407ee2810ca8a1ac73a63fc5e345be45174753380949448e786161e1de2863e4c76f32fecbf5443b07c1e31c7c579d4fc94632797586f8f363baa792849914a98484f91255aec102e65ff4a92d5602ffef95c437179a5d2c483b724c403d0a1b84ca08f7fd3ec0a78abdbb7b05e1bf110308fdff06e141927fcbc11f340c27e9bc82fb043e1db113239202307473cf339cb291014307da46022786cfbe62bce9f8877ebfb67134312a92345d24a88082d63e0cdd4b7870203e874255b458fe5f3804f3ed0ec25670af750b50f60fb8acff97d707741ccf770928634dbf63d6dfc3925ff9efe8f32ed70ff71f2dc5907aba4cf35a661875ae222693057ddeb481c668c00656b714d9e0391bc1c8c9983f2c308b2f4e69c1620a6dc6c3cae2e3e1873ea13e31d1fa29cc15806580e534e1a48c319f6f28f00e3c817ccd451c82cc28bb95623f4d8adacb54eb9ad0fe7e0b52385281a4930c28c2a33d1b2b2a141aa219dd6adee1c59b172159e466d0071b092368d658315f9e65c6f6ae63c376adf3309f05ca3411848e14af0347c2e446915951dcb91f2ce9918e09d1cc1201cd1da2e7ebf6c3bca0fd8c40985e2519c892915de2ffee9b50d76e54051d7d21353230092ff24e0dbfbadaacf9f85d56c9873974b4382f424ce4007b93d01a37490155e716103de87055724886d57c68468f440c5ab75317b0c101260d3d3f70b790b4e8a10a3fdd846b40ad1731a868d48bd5dc0ffcaa7c3fd6c0a4ce9e085386670175d056a53161b7b35caf514e93f4e51cd54e6906356c390b8c93dffb07c7b0ca69ffdd83bb7e0d309ed6c788bcd3e3d42584af4e49e103614dba2b78cc23b35b2e8228d81d849c7ff133bab5c8adf8264479f86126e1090b897df48f9b3778171049ff92b44010f1cf03f02e32e196a14fa09717cbc829c7cd619bf03ef832d995f2848d0a265abce8bbc8fa2a2d0e430071e8feb302bccc320a05d15aa8a99e88e414f2212bb81466179e51194d1c5a01d9e274d85782d49cddbc46cacf3a14ca1072be7e9bd1799621c41e050e4f423078e025acca7e2d6603f63ef4d61a3e79518036f0e1b0c4521b6dfb4fedc938308baaa7f8833282e24cc0037ce1b27ccb0a411c3bc735a0907045a6665f80e92ad1a844fd47eb4004ee922f5c7a586c46524242603aec740fe292eaf876d47699158faec3c784d0267142d2b9a4dab63acd4ae53ff7caf051615eaaa09d4293b0233e3498667e97a475e6472d8e9cf44fdb26729a570994d223d1e3a424ed686accf7f895d9459b1d5a95d79fbebf67057248922c6751163a1dcf8471b41c49470c29f1f922a2f4d77eb6d00da4135cb688e9960eb28eac5ac380a376e04b86b623b7b4a2cb1a051f5851ef0489afce94bb94b7a8c3682c00b4882051e8b9aa6aa6bd60eb0fc43410255b19749c08d4091fb20dd8e11bcf3f810ab03e7ccc98341747201268c649bee58110048d3d2aeadf623ef2a1fd0c77c30bd7224a93562dbf6377fad34b0dcc60445373e1ec6b2c591b0a450ea32f78623bba2cdf0ae3b1fb4661d4e68a865e6e4869d9727b371a78e87d7439b3bcf7125c169d47ec8d13da26820b215ca0cafac680bde1e66288d7cd7b5585dcd062272350ef5ab500a3644d368e5aac7379843a174ddfdf46150f926dc60d0fd5eb3b3bd399012c1ba36ad0d9d5d77e88c601cf410e56f83cb43896929e6745a0f8e4a43a30e5501205119577328783ffba93e6ece4b52cdaebea94e26dc7c228703ad2cbcfdedd949bb20ca040b786c441791a45a7c986ca4bca556d2b9a42c273008aa13bcd3309db652f608582348187809e4adfeb4a24d5abd7aa26da0791be3b799c1f3c83586ece4d63a83149309296f959fba783ac627cc009ad18f050c88a30be908eac13d503fbed0f6d981f16de606ff194cd97ee6c43407c894bb5c2ba7ff3102533fe649df333b924c2d5d28bc0149723578881229239fd802a8fdf6a56f1bb53c09a91a913c499649601248acda2845d015c14af42f0c9971346139de39630c20c5a60f651f02f6926b29632b641790516582f9f0a3e42e626228feb4ed6abcdad4a614e3cd57da7fddea64ce6303e4e2e6f26bbe629549943f6d6081ddd6997b9008f0dd4e78b761249f84f5632e4800c4fb05921191a6ca173fd1f17c4af8f2171c00509a48c4f8d960906cb86e3aab7b0e79fef798ef5938c8d822dfec981f2dd3bc31375fdd17635204acfac307a3487d0451171c12ee1a209f103cb2b7c45fe2d358e9c5d2b2dd9d300271d3735bb2514ad3adf67699c2b3ef3f802d0d1a08aebd49361c0f9c5b134d1f214768bc6e1cc588fb0fa3aec1221bbc1bb3757378d82807861fef9c634f13d9e9b9c3891039de80cfae1fb7c30d78212860da6046beb7317bc7e760c7777eaaa046cc4f02ba68314657309c19a50367919a9f3e8ff1b54898cbec5cee96c4aea4aa90266193660efbae272cac2e61f18c5c3202f108aba1620d8c2f020182801ec0f2100a6d1b363a90ae07c5bead6fe25784bcefacfb1bd97b4b29654a32a5145804040483043fc46088142a539e9052c462600b059835f57a71bd18d1a8dee2eba3d6d0f057b6592fdfb24adb238558bf2d8ff555b64232f7d547ad61f92adbac6c7b96678568f9172c991048ac96ab86c52ae960cdd130002a180e31f0dfe20d228a6079ec8b68f9173a2d4ac074b27ccbf7fbf2a88d96502c58e6434bf622d34637e410d866399b65fd0a673839d69095ddc8b1feff2dab94838363e87a1c1c39164ece6549232d9fe2d135faedfa95ccc655ba715d2ba3d168a5aa5aaa2a23addc609a6be5b7ea476f55a51b3682aaef01c7cacacaca252556246f304d2565766394d9b8c134bb7384a3aaaa1cd670dc108bc5fa4d8b2c8bf4625996949794524a79c9eaa5bca4252d69b9110dabaaa48d1ba7972775295ed8cfc52e33d8a5c205529230062e84fc4197f7eeb7efef377f98b53710deedededf0fd2d58227537d6edb0fb750bf166e2ab4143448c023aa19c1f73a113899452d3fea6d550a0c92367f93479ec98fc6e79dcf26c0f931d22c49789155a86425608733770ce71b303c2fda658cb9895df65cbec76cae9fb47d59178c75c6cab8028cbbddb238898a6a94a7a86e43712c800349a517ed49ad1cb6ce3afdee22ac6cc850443c68f5a0343662fe58bc7fe07cbb73c101931dbb8c25eb0582b2596910e2396571942acbcb3947e20a9c0e8c6e829a03256328de44cbfa24026eb480e816de68335ecdaf877db87d90e1cd678d7adfb2ded60cdc9dfc132a2b1d241964fb125df6df22f292fab64bd351ad1b0ac2b46964cd9147fd3118db8325ebfc5b7de8aa5527c7959d688c675c9aa5ac96854d9c51ae3304dccb6fd6aab321c9d384cb32f7fa755551fe3ea5428d4cd0cf86e9b19925e2084f0dab0c931cad2cf4a961a4208e146194ab028f22aa6e10c3de841163d903b4d3451d44415192eb420d4d811420861b8ac86f35ad6b2afe557cb57825143fe84ee1d3e7efb30779e915873dfcc211cbdaedc5d811e1743767e6420a4040c51e2c3f70f5e315648603fa900c217865c1a7b982afe00bc80d980ff227c09af8fa51e3ee1e8537c1919653060f6acbdf752098c0a28ba98efdd0fb01212cc7df5a92bdb80cceb65bc7e4735e05bee610f9faefaf70c2be8a073f3491852c6a7c409cf7c34ccf782fc5021ca3f29ea7192c4542ee693113e148a69f4c97c0f3303017dd2139db0d4d2eb033be3abacebbdeff8de7b3038ab015fbe7ced17b9c03097caba2eab8a80cef71edfc1a8117fbed23eaed8e224307f17d2c77e349c0e3a6174432402b044f38a111d57b3190c2430fc7d78cf26b0ffde87150249673ee8c31762ffbd10485ce603ccd409f1b21b9480adab29a989df14f9f92f2ad8f614d08782a53fb820899423528278ca114454a4f474a11342f8e0eb52ab6624c69d2396c2583e225c1fbb034405888a8bf921fe7a1b403afc36808080522faa1c71717952a031dc3b1f2b78e74365dc0b1f6c53206c8642d127eae40a05fa1915d113344b539518d1641a819f627fcf7746c7369719e1791930eb5ea559c2850648b8ac80861c4c71f1a1a10916eff251a2e779bc873023b06d77b41d229e69b4c741c13a6a138f1c6942e707a55924148a1645222c45c0b6f5f16142476de24f1678f972478029400108a00cb880c6708f4365acc0b41808d335f879453a3a7a042d113bb6e7b5f7105589cd8c065093d4d882699d796665db02d17126f73196743e46f72265541bee1f6804531b87a94d4735997879f898bc58131857035b31777ffee4cb2934c4e0d758c75cd7b80373bd45357e8d8198ebef618ac5ecbbe7c5fa1151889aba00379ddd9d1dc2989b1467bd8d85f7ebf7e083dd3b58b18bb0eeeef6e8839dbf113c9722780dbf9d045a8c7d02191a3b48c2ee4b62b06661caebf7fc79630f0667c5139a05afdff3e73d22c21a28ee04a902617b15c8e0a4bdfbf573944382f9bbfb7bbe648808ca69c60b9b9e417b601a7ffd1b3ee0e4d880d6a80c853c652663587337acdd50044c8b790ce1ab1e84aff2e7f253ec19ac640c6b314eb6d40a42c055c95635974073c7f7b2205e670fbe4cb3de7d8cd556104d8bc1c931a34c4e4142cffb47cac50a6cd3283b7ac44822318dba3410ac7de6c90aa32fafc4101114b70c3720bcea7ae5724f340b53dc498c6bf1c518939c463b38275d181244db97f272a2a3b3fbf3c7cccccc9c392f6d3de0e4871042f8aff478b004999cc1e601c6ccccddbd8ebbd7b97b9db9db77e3c608a360294c3fd74419afdf830f767cbe6193f302d6dd1a83bf479cac32fb1abf63d5de0826bfebeece56659663ec67448c4d42475595a5094c1fbedd1ed696486683b525d2dddd4b647b4a3b647bf4692cec59225de5e4d8d7d26e8411427f858e3fc5d2aa5e96aa4a36aaea5996f5a41cc9fe37aae17fbd0d55eb2d592ac9973f83b5eef15e4544395e5766433f6e31b391a584307d9dfafd02a834aaaa663e58eb1dac45e9d922f05b1deccc331d2d59609b0add70291bdabdddfcbd0203e75cf78e94eeee0f2ecb88c693b0d71f6cd75d42b573ce41e8205ce71e3a084fb09d73fd9e7b19cafd7b7ed1f1ce38e33d84ce41f7dcbdbb25bd406cbe2ef55477f7dff6e7de95600183b96285a5ab990ac1367ac04197c33937849c910ec59a0ed3c4f8d6c1cf6199a3c3555b7e4508e1cbec848270468c314a1d7e8d68b8846e79749f21a584988eb6fab78ebe33f60c2847343cba8dd6d1513df7482fefbd6ee8ba1b967e3ad70dddebe79c73eea4c8589285c9b41ad8defd1cce98d5d10e1c64deb0c97d8a515530ff4d0b01434063b46bf7209c4b30d9f735d7fe5e5dd3b217d6629c2efd8aec4c54877aef596f35c26a4403be3895b9e4dceebe760f3b704d20fad7c8f5298e9594efd9893594945e954634aaca23af389837aad16f392a7ef5562c954e712687bb4bc8f022f5a8068a6922cc50a7c928ae20c3767087df33379bdcbf0c87693ce30c4786d305ecc47f61158f9460694c40ddb8682edac60005d85545bf7e0f3ed81da7a0a0dd06bafbf337c39d80e955554546de17b5e13190610996830b62da0a4642069827fd6bdae904a439130e4370bd03054cf5af61ac397f2a92cc28606e27059c4ea7d3e974caa1323910718299519bbe809a0a1db41196bc7ecf9f7764d40d4980de7bfe9ca4fa5aa3833953ec42843a383848a4229c85333f6e899d9d203b5660c1ee6ed3d06c9a768108c484859a8914371c61db62f8b6f4a66abd9560baccb25bf55e611a46627cf32746830ee183cfc130835876e102b6ad0fff4cf113a39d4e33393a6e8e080d3d39d24414a7d3e9743a9d7252806dec73f26102867f9e3869a593ca9c26f39ed486e7d545c0bc446facbdfbf5731ef1c032e1c764b28ac482e8803b53d5f8da69820f112245889060dbf69c7a86c0a498462f1f2208050535219a1b6a6e1a4ad3b4d7b409401930c371261b54806d0c04c4049e5c0d94d12ce4031b4a2d2d9d6117c768afdff32122283c7e18e9e1f9fa3d7fdefe8a520522fd5cc96cb896ab840035f15725abf480d6d4c4eeb4794096d80373bd6532c63dd107c5348e089122fde4891327575cd1a40993b9699aa6695a0e36b9cfc1010b28a6713e37f8c1ebf79c6558ae3bc4aef184212228afda2f16403cf5b5289e7714495acadc5c5cf80626d8b63f3fcc404344507c5a7b01c9a016211b50bbeb2bcbf16a27227cae3b7b374cf32858ea520936cb5db0b43909a67ff3e0e6e387250622e59584c89c7a55e2ccca162e3b65f08135a1671a850de123826f3be57818ae19bd62a3920e9d3662a808c771fc3d0e0ee78793e1e028451cac392f6055c90de1c877590faca11c6ac6cce30724574604d30a2d85bff7f62d33ef430821fcb74bc4ddfbb9f773efb7ebfebabd776494214bb1845dae08330df7ab7dc7be355a262f06afee41f74f4387f00d114159c93670c7e8842a314b3848151ee22176e278dc107ea2b1141e622a6ec70999ee9f778cc638d818c9a4e289a955d66750356d8c646e3ce42cf0214e986e7bd1b8a8b95002dbbc4811a6790232136ac33e38e889d188f0a1280a17334cd35595654130c5a9d48c869026bed48c979af152d97b103e1acf66a466c05497092ea6d1d601cbdc1f690c6c87e395b9414c8e23d5f6d703936377cb6bf481c9afdad563f2bbaede7d4c75314d1341f99906a51a8cd6905093c78fb9af3a73df470560a647f6c8ea3e715a263f1bb442eba465587b9d2c1729988cf5611f159c6620e9b5d3ebeab6ac6c3b36838197ebe2466dfcc6010e40296a4335401900821e2a93c3110c6fd4c67b0a3e2722448a14e190cc806ddbd333e4f4989999b50984da04055058292ee22286c251e8e400036c632226e22729286e681540b8430522e810bea1202127344e34cd3d01db5648a8899290a48bbb7b555553f66b20e9d40080ad061b38e0520310bbab23c6a7043a84ef46131a7aa2314dccced41dfc41414242397c3a9d4e454551a250494d1e3973377b895d0574081f7c7e5d2e2e2f2f303537dc198a351bae88d1b58fcfe3e0189203a55272a8ecce0a41ddbc6abc82890bd3fd86000dc374bf2da0a43516180d816d27d4699f3323703398579baaa66da3a0408a2387ce0e95713cd4e478a2b041a6734d9ac09c50674e601bbb2017238675cf885b8e20c2c47d69bd04846387b183bebf0efaee3e04feaea43073615363320bd853e1832bccedc47cc4d21f9410d242480b283f509cdbe0101fbb0b86e3cb8be68af5dc624fe7fe456fe791ff65f3b930f02b1f5896aab2bad730ccddbcce9fdd7719863575cead7bfbbc9d332bb373ccbcda0e33332bb36bc15a67d700d8c63666deb25619552765dde3f3d8afbb338deedac58e0d9f7784cfabe817d67bafa5e9570783edebcd5a6520f4ded8cfb5eb6fa7704af9fb98cbac9bb461af99661f3412218470480adae7d160058e073310f99122b60842c2c303173f4158010f5b502942944491dcc1922e9a54d1c5130c3006aca74ed10591c9075d3cd186740125092225446a300322b438a245920dc8dce732401865f7b231b8549300d574360603d4c4598c262f99cca2433cd28177e7f2af940256aa02ebe74b4d2f231c56a24861e90f48489912450b213f54621005c67b0d3a8194a94127e862eacb6a6c357ddae8500485a5038c11f74cddfe0fcb296408172ec32a4c09218410c22020844f4addc27237fb9dafbbba2eb391f79c70c2df69d7775f73777f1d3358da74bc533f3fa90cbfe7ce637c8d84b5c8708d85e53a87cab876ce0531e9288e080b735e776b672eb2d6ceb96f6e02e327aa6ae0fbdf85fff103e27929e60a6cfbf8de1be2ac192f01ebdfddcdfcbb5b477392d7ef515fa639b42efc8659103d3d6329b8a7d52c805c6825444586869c14a181326099b0c412459ae05004b6ad90d0154588526af386869ca4b630379da2331dd217b06d8584ae48a9cd9b4452284263ad3252c2779aec1f137a0b163688bbc2ce921aba055878a719f705f7f71c421dc23f7952852a40010a4c60021290d080b9690dd0344dd3340568cd05d4a4b50d3b9a8f108478788444c1644811137b647f36898e0ecd622a16a652406b58244ba653844da11bd514217c9d18e1f2c408e52e0f0fcff22c4f559d2047336c11e5d3622c2dc6d262acaad262dc568eab7e107655599f62ab6a29a5bcaeb6b690a51baf2606520ca5d186aaaad0ec1b737fc75f2e8b18049ea1a5a8c1080a8542a152286772989017f02e84259e6ced0e0d64fab315a55ef2922069a84b357eec355447d5b875db31f78a7db590114c6af3def3e7fd1bea0028140a8532c0d2686035f7a80ca8cc4a91496db897f939e66d752b9b951cd0c95b6b8f394d406de09394308592b4484280d668cee4da5d8c1849d329801c61f2db080a0a7a95d912065e7a6ce0c6f0a236ec2f4a524db57d8ff1e5a53be3f1638bb83406662f31103f5615b73f8f511b864668fbb2022f6ada1ca4c9e3c7644c4dcbeb8ef0d81d82110f0d63bf0dc86c87fb63eef36a0c765e6776eb56de4329af070584fe5a922c55cdfa8dd1923700f568c4157b0a96b8e0744ab91a949af8af203e3ee48e838367480e873dc43804db3468eaa032ff026cd321140e1dd446a5081eeae66d2378dda81bd40deac6279883a8b48d9b0731ab118004100053160000180c060483e180703c502451f914800f638a3e745234140844418e03298ae228c618420030041963084146a1a14107e32dc3d1252b309dd7fa2bc0260079069572cfdd25f0912778bff438acfd9fc4976d00892659e065144eb16a5cc5703f884abc36ec39236ac9c68d22f6e8dfa9c3a2e0689183a8b9b2e418026f1413a23a74a79d2f4fc72542a96905712f3deb2e4531df19e7c0e10e287f6d526f88756e52b727ec51c9fede104e2c3f650d0d090a14c493773849f2a8d8e49a7722596df977ff473ddd6bf929325352d82d02c772d2f10a1ba7c21bc6f6669c807882078fcaa7754a09af00aca0de2b5c291d08c12261090a0f716772ee185e9a3f5fd7820abd449c3d71a03acfbabca4a9aa8ead156be86d6c98de91fbfda227167382dec6ba64cac7a1273009f2c48c16793ba387921bf88293cc582e19e2e058fbd918441e4d030758968975a6bc2a24ca886e9161b84f4f619fe4cba73e775f2985728c8d7cb80f84baef87cc221d1fdffdc0e8b36261c39ef596fb889522843127c9f02c5bf723e22d9c77103d53a8b3b467cbcd70d441bd9043c416a5b9894e80a28c580a7aad37a643bc85460e67af37ace7611ce4517666e2d1737b287fefbf53b37ddab7920e087a6ada1b2dc7a9222179c8fb465cd2c27124757e6476fb7317b7b070896f2b2a5725683da7ebd52634c1d0d732d25de98b488423cb0a07be5e440b8c3f7173c48ab255a8d4f08920620a0b0262ae3858d66f92bfc215a462f4ab9ec066a74c32c4411c77cbf2f2af5bd97ca2a0b8a4f34ace709d8862ad4f5c15a5f074acb7bc720397ea0e50f9b45f845b7fca5925fe750af5e3c4e039c9be96becf7affca4afd7315cb64d276a998bf5f7aefb6d64f70c4e0497604780aefba6bb9580ed4470635a02ce349bf79a2c87fbf87fb17def7793ec92667a06c322b5a46ccf986e89e52c221293b95c33d2dcf5cc8f9fea810e38a4c257d615f359989c57ed79212a9e20f04fd1e045dcb9619677c2353b809c48787f9c1f4c119a01b0aad3a8006a23623b173de268a308dd1f286643599a366c277fafcc6b304e80fd667c9474b61fd6c82a1d998cf082bb8c6dcf29da4957f3286bcb93f6e6d497669a4a4084e54222410d0d1c543030fd0e326c4c6903bbe3d7731db407a623a41a3d7f5b6943a2bb6fe63d2621e6eafc9cbd408e214fada0c4f7c6b7003b9e22c9ac29d851bda1be502af396da6567eef582742cbf80bdc1756e1974d332d2a90507934be2ddb9916c97c88fae15befd0b1acaa06cf0ae97b65ec5104b13e2b729a5e9c117c6503c78c55cdf8e2fb3bc1ae62becfed8a0aa76989c8e6e84e9bd4a66d308826a604d0a170d1dc5d37e88f9a1937630bed3ffd4ca3899990f005511c1d3999bf833e5ad7136548c3977e96c1f9fa6a22fb7f72e12fbbf9534f8bf7960de7e0b86081a2dc883200ef0046000d7b5424c4bdc443b374118dda2a3008007b99b625e52eda4b3d2180355a9591ca6dae395db38bd5e66ee8ed179ce12c97a46bbb4aff9a361f481487b12943c8e7bb34c577a180145288b34353dc659e999fe6142f6002ea0437a472dcc4d053ade531d56f2303a59c22a6ac0f213e5cc2bdfe40bda80bb0f41c4d73525fb8451d0c2506db1cc6a1c0948b986c243423d52ad65169166cafb029e770de7a25c6100aa75cbd122a5a29d5d2b23f92104ab1bc0d8569282a7dcbffeb66251c490c005c6f1c40ffcf6771f2230b80abf8468a92bcd8da023a0fc26269c3d574e66c9943d7c28614119e4e0a7b71b54a4a2b486bbfa9b8e6c996fb8cec6248db170f020a560765ae9df90214c5b1623cb33588f87c01effd151e26bf3b45650d0e2b18b0b1cd23b04842df3e687fa28de7aaca8436702c7a6e166569adf90da6e9aa1c0fd0c65f0b64812a2d1dc6a63924f3d3e2d13d648d97380ea56509c53526b002511e933543b46cb09463ad4bc5c3e4b121bf622f015742bf76835417224e5ebfc63bceb42200f80579eec1fe471a30905bdcad33ec7e36a33b3436a2617246af64f9543a422f53369a5a6e75eacf6b57307d8410b81e239cb9c130d45d143500ece27e0253baaf3f1095eb97acda7891c5755725c9452e5eaaec3e5fc740e707854b62185f74d26b756a599c8d82bb8126b28f0f4943d59a1c5d415d5597bc2cc0f643055500b84a455a768da16ee34a57696cfed198c89b6c509e0e2635c585229404e76f7147c5b6cc73d03a083a78e2c7ee96fff9aba14e925e458618540e171d3c929a094f3c396483ff9632e1c5ad8bfbb611097a85ea23fdfc13214ef0ee3dd06b67d805306a588029dd59873a9a84882ad100b799bbff483b44a54cf4af18961fe9422b20d9a2bfb20955115995842279365c97d77b145dc2d39b4431b753ab06bd573bad8a76b55d65a779238ae2c748150473a9bf3ce516a3283b03092d42f17d0af4109d54cbb324fe109a8998e40bc4341bb7fb2724ed875bfc04aa78cdf12fad6e0d73bb8370f3cd5dea055906a1472cf2df66e9f801ca39d174db1de9da875f416b7b1951d55a7d0a4681efbd7843f769ca8a55a7535f6dcb1df52df8ad8e82773acf407d7228d28b92851c60e2df939a7e5143b1a3eb0e8048ae7cc8a415bc276c6996d73f790f9f08ff254c4b7403481d0902e40acb349ec5f48407b05d5768d9fbfa0e5cbb88be68dbdc59740bf05ceb10d6785981635a8a871956b99dd85d25bbd2e8f5e5b3c44a83e1edc5b9efbfcb9cf902dac53f413e8a43b0942f521e2d6ab2ba237705f6bbd5d8d797e3f788b6d03d87360c5abaa967e74ab22d93fd226f5ca5b9a19875511abc0d883fdb7f060e520ede22391ba4e86ee181bcc5a1347a63ba29968ffcd16cd8c972382dcec61cc72083962a8ce45efad0611d940195a9b97e0b8a162d6e601507107a40efd12b09f455ff7953a34a57137a9cb7e7d95b8dac2068197c3786d8a8a11ba05213fe306bc99c070670be8a0926ef2a4dcebe3d09ac76ac206317c7c4acf6547dd51313e7f979092027c7951daaf7b24298a116736cfc1a2bcf90a91682571c325595548ae8fda47a62d8eea2670e7dd1a5d91c7abb4b299436ef807641cf19572ecc6fa4662979e1bd145efec0c26e39678c4d6984f45e143130c0071ae448a36758acbcf521560913c2600012135c879bb8dfd75afe6f568c571899c22744fdff38d2fcf8d72b90a691be4dcd0dc71d32953a37d0ae133ec1607304c42cc103e2092858d5301cdc7bdcc2c3d4090109071fa09e20142cd062af13d09f1da11e77a0711b97d0df886c21df7d4f0f23f5faf5021eeaf942bbb853d487048766646b481242ebc5e74d5ed648985208dc9c6a61943e7962a625c2d705fabbf840893302d6346f729c087c7f9d34ff97cb9ae3db3b49a215be9951a728558fcc2564dba3cece45a34799c181b5e2c6f7b03f98984262853fcc2269c93857a68ddd8a01c8a065737585202aa172cbaedd78228cd8f54d2fbcd24774d906e64fd8530170dbff84127f5ffec779c7e2a6a57dac009c357b00c9d63a8cc0c30ea20b6dd2b8916eae0f07db64199a8eecf0cdaa0113a8412866cb1336877f0c3d8a8800487888e03e0b0190ab936dae58cbbf610e0ab9e835963fc570b902d867781327c76d5d876268ff6642042c59415be738c04c48f1d46aeafcb171b9a898ea95bb7d2a142e4816ecfb96e5e67eae12f7965312111560fecd486b761bcb42054664986ac5a6781ce7f85070a611eea49fcda12684238fc73f90dc2d9c46ab11fddd48fd7e86d3d8f119ac2936bf1ceeb6b1424bbba8f0ebb8d1dcd02442fb92aaafd9eb9c028526a29d5fd1d34b5ed9c150cf915b81de6034343ff5e5ec45f1cb8cb82e2a0085772a728112c88b88f98caca38228e0479d8d2c4431a44dd7a4b43f513b037ed8a1167124230bb62434bf47786cad4b5ca2809ffd7af6a6c700b042d3c1d74e0590193f4197f65fb37885d86ff8a710cbc451f3cefb04bb7e13a538db8cf9cea37423d8ac44e016d8cf84c44b9f63f01b170b0a8abd869d824a399c46240043293b24c567b36b5a1df40a3119d4d17b5b2f21c70fbae7aa256159a113e1813f0cd272c8fa1edc833da0ab3910523c2577b1dfaff6cc93c5ac8f5ac33ef680c14786c6fd600f2dc180b9e96f63c896e35e43e13a60b05224f8cf11fed8d85b859e75d0341235f73e60b8d385efe0db1ca614babf3fdd073b7ac3eb03e5e8cf34db305188031b1899e9f30148f444074691256d7fdfcde7e7251e08697175d25b1a2cfc6a69e63eaa08a3bd3e925513b10c766c502eb616e5e2a34545682e7f4b12caf7d6a41c81197553d3185bf0fdaf187ca54fe7cc1af5c6463a41ca786c4d60e76a2cf71294fb0ecdb9da3e2765f679e3157bc48c7b684116d5e76a13a0474db2bae834e93e1408944a3377a0ee3e48e066e1a4b6d164a1f0dad493a8bcda73c8832d256375f7c8bbc3beecc3523ab3ff53c4b59bd5d7aa76a2d617df64d87743d5601cf306f1edcf67a742b2462e652fdecd1fadd5ff5a188847c090cedbe91b07f11be7a0c5ead55724fde695667b2748da1dd4b4ccc16f3ac9d1d12e238451e02a6e568299bbc482a695d7907131f1ff76e69876570e9fbc590547d0a578af61018046788c64f6a36c1c683f55c665e5c597f3f3c04149894547d691cd93a6fd3ead19c602d385a55ae653847f812c071ca623b58cb4aeef98861a58432e499e991c33d61004b102443283018bb8ff7420a1e0a0bfd955e79fdaf57c438b6687a7c382a93a16f78147fb2087a20066d0cc3645e4a6c0a7b6fc3428af50826441e7bccbb84c92567935caca940479dbd78b569d9dae0d693d0c83ae597223bfe23024292c36d1e3bd9d755fb4d7d59db78e75d9ab5c06af0de5582791b223606790bbaa6169cf38fa2caa82a1e46d549938987a9ec3de7df22b693c620f3b885c37d2a604e78dc26796016ef5b81a3274cddff09cdf898d84f9e1e990026ffce732c37cb35fcbf8f8272c3613b9a2b7312caa9b7556e16bd7e8ca811c85d8d59d3e358c1b6f44fa9449687a01a8da8878ccd2b73697f225667ecbbfcd166958d2185041ce9b03b0908070f44e9827440c7aa87653f354fbdd4589ff4ddcb27cffe4a0755aa4b1fd51602dfb3c842dc1c0ab78b748c7afd08d1d5418d874921bd0da8b447839aee22371fa4c2ca4a182ad249704d86db449ed91422fda4311018c7da08645f46d7ed8eb207349a1cedf2e4bed7449c5cf5615c16b887f186aa44e69e0b52cace5e8948b190b19ddab7a7fa22a7778589d3e7e1964ad2fbc142063e0adde6750c238a40d39bd93e3c8087822c869c4cd8e12c6d075ed958fc7e06a0172d99bc4328fcc952c60069e14c70427a91c43d8bd5c650cc874836224f6157563aa8af9ab1e1536d1e6967a2d8409959ff1e03b6ec44f46ae70b6d48d1ce93c1b3d38e1466300a3ec8980e9551ecfc90299124b957dd5062cdf648786c70d8c6596e8b57d287eaa87aaa1116e406df1708a2a03396be27ef79338e1498a8e82c747b099b2a791827cf97bb4b70ee24d612db8f6862a8bdc9553d831114be17ba9a1223d6f919e952174802a755753337a7a7ad63e7a2d9e3a5d723a2d530bb703838b20567f34101fd1c40ba07e60ed212f1bb6b0c89f963bb1133d59dfac88f2eab5c7fc146f51d321f830de09760ed9d8afa6c4e50bc02bc560f6d2f026065cc14107471d3b40b4ca80b76a9697266e6a58b239236ee06ecc25cb4bc5e353bee892da74527310810cc6eb7ac3f1f40c3ed7cba8ddf8e270ed0c53966b98797d06c6e75d7b55014c315617ae4560af12e639aebf60232b7f852ec9d479010b3f328affea318075f5731d1f68f4066060977428b1cc935a8a9681b4b144c394f8719e80db9d01f23a18952387d513181ad082e87264ed2f6ed18a4dc1533d0a35997712718bedb972b873eee40a2a2df8de6739aa9e322bdbc4fb71601e03a5a5c05da08f179dd5c2a1eb3076383d052ba2790b19d992f1001eaa70f61f17adf456b6bccdf0aae90dabb80cb0bf303e5fc1ee1fd129f74198490dd877e7eebf9a2df0e6032432bd0699f0229803debc0da4e58ada9f4979551a51f5a9cac181db016d4dcf17090910000abfb5d7c89f35f803f2af27259ea6f8c3e8c2849e2332697a89d5020f46ef07cd770bf1540fea48ab0fd336905e9c347d3379fe41f248a388bc004a050d072f381513f64f7843802f865ff3fd9805a10e93685d59403122f68d2bd8871d5157867e9b7635842690f6532d70b4cbb22b930548640b9cdccbd0ff1e6928f70d2305472d6a13cd4513f6b46745ff86f54318eef2eb8a023ae06211e0f6923df53f7c36574664c1987ed1df5c5adc085e3e110ce91cb791d1fcfd9903b38d3d6615d3e90e75ef81b27de481e9b454dbc9b4994da8b4ce704616499645e019c21d90d0a3daa60760832019816978fda118ba67f67ea0f930fda00e275eef1c1b17d7973726cecd9b75308f9631508f0ec34f606cb92a5d1ec3dc747e44b22fa88827059ae67f32d7beb422ed85948e4bcfa0b9ae1b7ed355a3792101e67619c9f2cba9c440d7f1c51adf1c21acbd7c46982c09467c4463fad0175f16ad4b1130b9ab20671d412274338313d0cba4caf1202674d2144a9501991d4585c8ac48d00cbc0828bfb15149c7311e1210949f74beb65e81a49403401d6a669621b52ce362a8911f04a60ec415980b78fcfebff641e093465091403aa4206bdfc7767b97cc0c8e6da82e97226ffd6fd40644aefec499a666268996d2ee7f27f50c066d97d2118d118b5f754c83632a791765e500002121ba23234c49e17310ad04be4592f31221ea5faf4ccb80af8c14befea77e4d3e1f1e056111a19ba29bbf688736fcfd4a1f04cecbb170dcf51c542ff6a3df4610e173c2d79d0708f976a75f7e1e6d8476294a62af717c92afe490d6221f5d1cdff520681516f47161480fe89c043257c60ac8635a3c57db15fba1d3cd8d71b5af4b121fa3c30e27fd2562d953e22343c816317e90fcb18784bebf259a8a3705fb249c4a74f0e178190bbe24cd352775911b53f09467fbdb3de80c9424a1f73b15e82895886920ee8147b3d1498a4a123d3191e680cc0aaf7a3295bbc64eda3f32fc3aa08764c2492ec5d59ebf4a002b2f2f1d42a6308a00fda7fef23b5c892317b24b00abd135a58ce5701c5d868642238cf32969f264e28803ac71f5483212c94b66bb0b58a719a181025d17f1cc381b9cd7c3c877d236ab68be2e5ca94cb8a3847b7da3a55af18b0dd460742730c790bc19130f33f6ea11019865b1ec1937ebb98378a26a4085c04b00b21d1a62b6b8e116242c5c303bd0e5971eece4e54230ba9ca99cee962b2e89319da81566eaf50dde148327073f93e9a275a665e938342bfa3843675048d0ef8183ab4bc015775e11722490a02c399a29ba427133a25b618f164b496807784f5d8a5f6ac49349d467320e740c9eb6ea08604874f07b906293e8a71a855298917b7060a845e40401ab40ed74082a31a97080605ae7626e256d4e8ea3bf68987c2f0a7b5c653e6431261a0b3266307673cc330c8fc84441abca6d1a95707d621a2aaaee762b0e01cfc89bbad795fc71b5bfef138ed619cffef71b9d05e2c8d394954c5c21a07be021318035bd3f2dd890eedcdff3d024740c9441a4c228651ee48144a1610886d52f07d52f80046620d17dbf58830fa30d1e086cbdde0e8798379629693a9b107643fd51430f5c20e85f5f16084b0a5f5971dcdabe0696c0fe41e1de64eab245d2a2ccb4811b2b2a5de54b57357a9a80a6bca9a79e1193dd1a9a6098ecf8162ea7b2c26a21484f08d32daa41b3b1a1d9826e575bafb7eb5d74b28dd46ab98f57d2d3712fb55a5bd55b955b518b0fc68ac7b9878e61a3c69c629916a6e6aa084e4fc17d47f48e3f843c7e8010eb6c8a88d184400f1bc4198322c1aaf55863fddb0021d3b3c0cf4fee7b2c685617f49e64884b3014e836c0e02a6c59516affa8446bb119c87ffff6b2aaa2fe3cde9a54204eacc1e38d49f3dfd656dda91b5cafe586f5655de7e4658625b600c1dac54176c7b10e81a2dd75f2a25c9743ec394c8347e10a225c2e0e5c0c26a6015e6aef8bb078fa888329d40b450766d639c041d3fddc1048f99e847b0031f09ff9acd3d97455760c55cee5709ad1a40339f879af2509cd68290c6809d3d0182c4cbbd8f611a40eb62ec1c72557edefdcecdda00e3134b5b8e41fec0a003dd2c3506b4bb2dbcf588398ee49040bab7460f1bf2af4cd0d061dc7126e54988505e64f596be25fc828a0c9f1b62cb4f1c5973f0cf9ed439a4dbe68414db052caeefe64008b2ea722b080ff3d0fad241241999f9468ac3bacc28c2776644250268b7c3a4b3906b4b3350a8d141023797459f6c02ede1b74b98db06bf44e30822aca84daebd80d82c32291cce91ac304a80b4869dfebb7151493169da0c419e2d0edab5813aa2febddd1dcdde643e97ebc2ae881074762fceb1dd4ccf9a57a03ac831397509fb913f02663d6ed03c2e03a41aa387fbbc62ef16d214744bf9d96df55f78392a4d25ccc34c0aaa7ca7c4cf3dd47f508391df3e839db57f7b93838c3dddeb73e8e75cdb8898178c868e325028a86eeb271394e8ca2e9b12fb2f172405d6322ab678a404b091aa52cd18978cd32230fa2e4e6f04ebc34faf5bab8f35e4d11d6ebb2640094da629fae19de32868d75ed825f8864108873194c39ebdf25417c4020d0f721ecc4ef525f3d36e4dd63d62a0b878a91a1662315b440f3b1c0d04140012744991c2f3585dd68bf73bfdc804e394ce17c9801074e8b270c616d0160dfb2e0e6435d3020f45de64f1fd55e1b93dd17ba2e6e4a2592351b44598d732114a764c45c895546af728cc919bc4013ec5dc48094aebc1b477d396c4356aa4cd233dc3dcd322e69295e6e246af8bdbf50b410d86136e0e38c5d2ca1b887f07a99d610e5f6b8c4ce27793c1358ab34ddcf63f2b64b65c6ed06207810576fb591543600107e80e49ca619c14936c4c029fa50a4cc2034bc398da83ab6968452f451c833f45b3558207004dc060e77e437e06a17f2c93d4405316ec26c3066b6c828abeeb80ca85c52c88b8ceeb1012513dd2e298c5625a4edabbd1e8b2b495337085df65eb7f05d12e1d03e1234721541f85546141d233326dafdb85a93ab615864e96c46042f700e6b4e43bc65d454b7798df39359e2681b8b6fcdb223d2723449626f106fb9187e043e9aaea82be91247708ef1111f31a46db2788234ffe29800553e2d3a7e73ec9fdf41e6e95ed35c97a4e28513baadb0ddd952cddfa0b91002c46a7a82d802dc73f66522ad3639f886d7aa52f32bac2f1564b819049fd87d7960cba44dcbaa5453c9144df9d684a708056a596309922cae60b8c123b88fd951b0859816791cc1f7232d01ae4fd5d3ab3bc7e15dab9224dc799c934e89e06d231f5bc475a685d4053a9f3991434416fc83b103490cf4e1d882e64fccb6d4aa3d4d19cee4f91a11002ef25288c2c0085cf053b4e7a81fbd1df14ae177f66382c271f78c0f605635d6b53569ffe09b339fa90e3ba63c08a25eafa97f5c554f65373ad254c359e79ae98404b5570793d20f9a92a323aed1aab908769de5c0dfeb13a808b4a58b832f4c6e2e9d0c890e8aad48e063c1b82e04c83e67e34f67bbe963404148bdd8cf6cc0797ae998c84068f3bb3dfbc592af6268bb39cda9b9bc55513933ef62ea18d2b69b4bb5f9ae515f718a77fed7363393fa1097a126847bbc556df26932a3797968dfd63bc928f7c73575c72fcfcf38e70a93e80f9823096bf7b920c2e2cf69be33486e7c90f78c01a75a0770ff0ea613452340755cd0c83696f19beefa7988f5a0772eca56b3db6b450d829854867462465d88a5b278bdc5b75a2dab07cf2a47b4bfff10bce98576ba64bc72cdc12fbd7cf0e675ff41d002582fdcc5ff80d4bc476130ac8fab9729e746a2c9a23782bb57ee515d01f4036042df31593935ede2305d54eb2bfa4cb64aa752a952f60aca5fc8d4fac98175cd697206c7e0961674fcb1031c28b2c9ae9b2ba8a8e861a009cac598eca6a72c26541f219f2a074cc6b88040008d5234f704bb44fa1a28f8b1a4e0aba961da23eb93ec452e8b1ce6d450c01de456eacbedf8845c0ef1ec507aa684d572a6c6d510fa3569066482f40cbccb6d0046227e45264a74139d3a31106d13764b6562f82fe0673351facb4ffffbdfcfc85a30b99b3f2ceb38a6858a7d5006283ce8d2f9526f7eb942a8c886736df899e7c8c6388c0600b4479ff9751013380d0c640ef9445c2e8a9c8d86e75f4ab0a045b12cdaf1fd0d81171dc4396f2b88149f1d6a714e58857f04b954be2d48cd198cf244150c8431abfa02a551d16db246199ac36327142dfb42e57dd990aead33bf41764b8161274801148d3fd506baed5aa18a3c39ca078d08f8b1823c1e0ebf83af0c5a5697407857d580e32573f717dc8a0325c46a8782e7f10af319c230c422a5c6d4f23bcc18e016b09fe90e1a0ee05072fa07e799abc40b7ee9ebc2ce6d5d835b05c7e17db5c1c813d05ef2d3b9aca1d3388293edc512f0624b95a8ca8a15012abf54b67348462b4efa5ddfb56491804236ead4d9d2ec0c1dfbe85ba3a47ed59b12c675e19308b515132b2601bd62b2a10fdba37550f9451e2bf5c01bcf6e45fb66439bd2239f2773c38739eb5c119d26c9a38d6c7475726dc8f6db7acb1bb48d5cd055a7bbf87b22d3bbaab0937d306a408b289155f748d63683d464341118270e86b631c2cc6448e34abf3904d6b27104f80e8762c398e39db084559ae88c3309a52a999bc40be1c09b8ed0c9bc027fd753935ed3cfe4875ec0a2354aee2fab065e1dc10b9f428621cec5c23e4b9058701c4efcb1d81fa68f5a6cf5b87415cd1fea63d5e8b74bcbbc94593373e9aa8552754554da69cce451d28770459d622b7eaa0e057f5a5b2174ce039c40fde8eedee81339981f5116e4b27de56d4d42d1235897cce28375aa95508b14cccaad574859e1084d0b9d581a637c14aa8b132a66c03d1eadac01a2fae834b083c7f606d911c5fd496059bcab9ff82c12da259eaa2d115f395c2a91f91ed154e22e4aa1a8e05e4527c4a19943cfd1c42accd41525586a01fff8e66fa06c876b2e80be2c22f1aa9c2a57860e18f78704999a83257e5686b197feb97f9ebe47494586c34ff91b587b68ce05700b9b72b94f28f1522f0f08cd2a1be22a83fc826daaa20552baf3c9a9abfa88d7313d5c99767482814d9146cc431edaf7849c12ac1a6f7828737acded992383d8622847980e30d116b00e70eec3043c839259601e7378fab8cd9ccda075ba245fb6a1f0b62cbfa3a69b8c1ae753c677f517c8e52aa5e8f861e54264a2c43e524a8e36d2fbbb8b949adcc2ced9dcfd09e3d82f3fd703acc4077cb8292f5ab61cd830c6d43be9855461ab7e2da48f233d53df31c37a058045c76ea4c7a2046f572f54873bcd2db17e78bd488e4af2002949bd5f3969f7de5f7053dc844a28702de30b8b104411c2f8d6bd527ab3321efe83947ef3318732bcfcc6a74e43800240fb0f028e53de04540b80b7ec1bf15605707140b0c57eafc8efaff8182bffefa5627551462394cd8ff91c3f3e1e87fcedd3cb504cc49a93cded15f9e2eb0f0c27732a2cf846c6cc77da5b3383d3c2a50d9d87b4ed94472ea7b55ba2f2ec0fac5b98fba936aab4bea63e791b40bb270775d8497c078d046d3069d28dbda02aa3e6ae0663e83bd102dceb4464e80d0b8d4bd19f33568075f3d508c1bf060ef9bb8a4caa0d15aa6ea98a120a1b6a6ebf599ab1b74d526edf7c9e00851465f26843bac5df8a0a3f604aa6cca8b088ff5859141a66dc6c506be24347086309fb9f161cc2b035475a3424c0ef3eb0f70bce43c280698aeb960f58fc608e662f4cc046af85219b88f460786c5b78f97aa0fc8f3e34537ebf86a2c0b4f5618d042b5c99c428068c3e79a9c7997d35fbd35c0f93439e48f022875a432755d5cec569a6904097a1a99fc1348413bba428fd672553a40c595da1e721838e0a547b6ab1a1f1a08e8d4265f2f9273258f60379ac15bd15077b8656239310758b422ac3667d1b14f4c91c88f6075e742a98b5ce08d1ce57e2643333ce97e42a76083f8f2cbdc484a152ddf43f9b26368cea0cc58987dbc690527a80ea8cce61cd8db7774a6563a3cc92983ad3564bb0e83be9b52bdbd32aef41193da50cf1e1a4d755997a5ede7288e4d48f43876080bedd047309cf83d2f651054a42719f599343978dd444bc6d0f3ec99f30ea4c0cd2de5e2f642784efe7aa4d595e3d6e3c528d2c3cb1f184132500605e51c9e2642a5db48e116f650905e49ed81373d1e2ed86726604938149e5f33a7293a013e9bd0d43d29f594ca0536166e33987dc61db4e0917329cc93c2833391f398e6a4c0383fe4a1fa1f709d9176bdb92536ab646d751e59dd02db2d7a9e0108409e7170277d5f858dac385bd40bce6e0886a7b4b33bf4924bc1f2423e3cc5698ef272edaa02bca8cb9000e4120fe35b43e7e9c801c0cc5da4a93013dcfb665d05f5a954266e20a9705b8799582f8f8cbf0291e681740caadb6cbcdae5eddd814e49c080bce664cab1d8ba040713f0d3849e898d7e36ac411919fb56018b80d403dfe62d603ad6745769b60d0b6046e9d1b4a9c896ece6ce644c2f6b922273abf60e825b639a8034238450f93f822f4d96630af25b68db1b8be58a8316f2313c5f09c6ac8ececbfff4081a9a938da4e1efe57ab3cfe69115911afa49897f0eff48f450c962168644b1ce7796058c260570ba229b8df9f7e85286cf1d38d5ce78b4a9f82d4b448a0124b1dec0f47e0473a5d8d07d9c13f42734ffcd29c450538c8f6c640d56919fc7f230fdbc387130c9fc8eaf02ed16cb74cf7a4eb3816371ab3192f6d82ce8472e42653d22a5fae0ab296d935e647c5a1c5d9909ec6528cf83cf7a4d00b0f74b0e4355900ed127e64baf6836cb8c18985a0bb48b28e2cddd0c83c05ecf088f45fdc814fd915e9207075dd8303281660411f70733f50a661d57d2dfd5a2a296313ba43c7571ee5c46e464826ccbe1a6d8726b67d0a4e56fc2ee76bf0b85c36dff559c1ecf33d4a32b97f81ac0fb3a1ef5fc8db98723f4cc5d2aff315ce2e0a4010112fb97e9b527f41bd67b2a66d43dd3586207f1d654948151cd44ca321e756c5cba9d44b9e8f724344c4e94814d82314394c28733b4877013d1e6cc237e4d74101c84f49ba9a7d00dcdb668b3c3b507e900887d9115aa991fc797609217b6a3de8f7bcb078659a668ec21166c538fe894eb143b3df42cafec0b8a583182ba2c8ae314afcdff3b215ccc60a21dc18b730d59d0d47ec0245c60a65e5440acc76c0dafc93ae373f8b6f56274e079d995ea79ab561fb4c15a5c307b19a617510b3c20c215e3da04ae61b9036685c3b105026d02ab1278da66627f11990970f347d22e47170894f02c2769f5aa0d5f6db46cf3ee996c68ede1dea816bf49158eb9a3a68ea6f613d4c4edd46a9b295637a4c6b2c8c3fe690d61090ad3aa6ea10321e6b559d6a453f716bf19860ca76fe01e8d8e794643beaf0bf322a0771494a2645a95016531daaf5c7a21b4db01c558749e3e159d952b02652d5f81a59fccaf8ae3f280e727c965e1d3fe67ee427e1fe64f1aab09032d7a09f5aaee06c2d4a34a897c1134d9a220e8e0c9b7fb935ca4401aeb6942732c99b8401ff2aca2398249c590f0cfa0d5639e22ecf1aacee33491a5a4e2d78882659dc06d3f0186b09ff8f4bbec1b6e161d164c9a8e3cafa1ed2278a2c8b283a85988884acd6484b618395181c9ba38abe4f7c57aef001fff311fb36504a8b11e9ae46272f810111dcbb5a62478691b84eb9ecdbb514a69646b4ed801f3e8b78e913b89de9cd902244d9cddf12244db728227795977a1814d065e8752d885edf1b4d65d427ac0550bba5417281eb56c05753720dc997c56a08c44a1332f4b46569e13c0568187d8cd7ac97a158c5720167da760119e015bdf1db7d893e0e4a5e40bf0254db2ec91155413d9cfd912a0242e6d27bb974a01444d99436296944c4dee492cbc1a086f250db52ccd47cf478b501332138f086fd367ba991573affd6bc0382975ff0bd10eeba529c6d9dfc12d987ebc49b7954053fecd8d1725f77d75704fcb258c836faf56b7d1a04702903b5a0a7c4c217feaa9b2dcdda821d7eada0da9766cb4996ebeff3fcb283897ae568417b4bda3e3c4dc729a39ec3e4274184316e842adf06e6a528231d82d3c2ddbf9fefbd06f749602089161601e4093f67c4cfd1e8aca4167104346836752cce382ba0868226f0d9428dfce013ed1da11469c158678cd9c8fbed77cde8287702e8bcb3a5f0b12caeb141701747caf5a6d9e694dbb6c24295241a1aed81a7d7e49e22fc0e4a22756e4548e1a222f3da9d318a387db1ab0d8e54a62bc9d2d48a50e98d7db21c18322e3032dfa2d5df302015bcb687910ac3a23708fb32b3128b03f653dae55d9b7370de05305bf6d5e54ee9488f2e426ce857a5fa9b33c3863b5810a1dd8664aac0b703439ca0d038c18b2c63fa24ce3575b5c4f42430088b140e7fbbf1420712f8bf92043c01bc522774d50a33da91a2f22e476bc05dc5d8a308a9829357e1b15477e171c960dec328cd521dcc3c8330ccdf52910b11223069e672ef024fe761a618befd11814951b2015da51ed54193c22d1d6836a6d706f4a42af4ab275ddb9f6ded2339722c9f3fd029b5304c30b07b0fbc0dd092a386b502f802aafd202f554242caa1059f85c7e41fc1d1b866b4349facaba4255b0f849b225b10a513d496c6ce70ba6cbdf166992fb329cf1f5ceed998770d56174de6f724881cdac946eb34d1c506f8ba86cc69b97d90c8b2a0e4400b54debe16e69c6654d2b9f1d36b34f80272169cbcfeed61c5a22f146da42a9b3b9411cd790b2a8b569c7554557e55e555d10b0d0474d75ce281cd59fa3701545170407dc76070bc03e81f6367175d54da3f9dc3d10534fd8869fea87afb0c7f4c527066fb025c2ebed3f5d8bbae1082a2cb5acb1b7bc659ec2ce0f95ff10d8ba2cb1a3ffe56fcd2e4eac18b5216cad870c9b81f4c29acdf211990dff82d7ad422d52e7f8d8b097358a596dd3f19dad9315fb5c51f1f9ed9a0095a396d7ee36c07d1320aaaa3df05d120362dd8490ce469a55b89b0b1bed5fe317edfa1c0e19106046396ab0934af72be7be909835f651a153c2bf208269ee4270067ee0c6dc0e66a52c7340c6d86da2e5dda9dd30d8f7a34e931b7625a30efb196ea2b8b1a1fac2d3250791c79f3ac92a92684107218119ef83d5374e4d78538b497f7ccc8425ea5cd1b7512f0ee1ba2bd1c5981b9f7741164743808341b91cafa456038417a15c049f2169a44e87cc50fb549a62cdaf0cbe85a4bba4af70adb5d479dca07fc654ad1105120b877c4d66f979e6149a7ceb655888f4b51d4d4f5e6b3a82e00bd423b23d334856ed1997562cca85921dfcc512cd01bffa23b5b88053c7d279720057a0933029fdbc049f8ceef897411a919a624198bea23c89b3211c6c84fd77712c9de5b38cf2cd73423ed15de063ead87a817cb85bbbd8e58ac46a202ce112babb60f648eab22a3e9a71e702d8a5e01192136bc1ef4a619d4d0310ac9c14e8d0e80ff9dcaf887dce2795a48416f4e64ae0188a67cb9d1abc3f1e85157bf3aeb6dbd3f6ae40257f95ec3005d530def59031e6360f6468c30a4cd34514240e08a8cc08961bdbaab75590a5692043c17b8cc3d6780d955c4f1792b781a93f45612b932e221210f17429b00b4b35008145482f218abab9870c30e191d0871727ae944c6ed1571978477328fd986509f1276fa6adad31fc978fc5e96db5b7404db0e7086d5b373be097a1390c8a92e617be7848e0856f5a5e53d4376f12c3967fddfe04ff868cd428131ef2444b573d0e7e7899b2a5a869a2ed19da1b2b70453b883e74394feb55f53ccb510e5e0965e2828492022a8a7f88c6f31c5bc6d72f41dca8744a54c562b22401a5dc368d5ae15980f0da0554a0ec133d8bcc023abb40646344e6d17f486dde77ebb0fe3e49ce0acb6afb6e11cf70d874de6c7c2b484e57efde757ac154c4d53ac149bc8b77f414808b2a8b71a3091a81c3710e2a9d36de5747066a9b54cca337b10ea947944079de1791066e959b3192d15ea7959bc1bb39663dd9cef5dbd1f36f20d6fe7b0949c37b7ae135ef57e70de21042b54266ebe7a743089a783920aa537d88f09208d8b392a4fe77d24793fd3484bf6de780b65b2b3fcdcecaffc48000d252076a2d44fde6c283ac595e0f99f8f389780271ec6852f3f63608b47183942aa757f07421b718522199772b50f07580b7e4e98b848e6d5f6d1d784e7b8b8994d0f2b66bd1ea465724f6ab50fc4157215ed830be3e792b0c908a61ae01875698cef994dcf63b8447532893ef274cc25b7a8230840d1d442bc30f3eccce9485472ab1b3ae7a20a7d40089e7d7287048de485c6ade633549feb12cfec21f13e9b93877f32302dc77ebf0bd6f20325c6590236c9c0eaf156777b282724361d3099eb116948601a6f41f5abf30834ed32338f169e4002b3d026231a48a70bef6d6b72cf3df05dfba0b03e4a357ca678b885f3f542c8fc195b52b4ae1e34df456fc42d28021c8ee01c3cc9ec2b6612d17044c5ad99431c9dd7c65155c85b8e0e8760b300f60e4e41e141743820c73b011acbfeb514662c53121e0e8d5e752eb1e8c639dae88638e4ef0334e50374d508e8b31a74acd35801724e8be6f70cd5f0b3c67854283912626aa3d8f2d861a2813752bb55059354e09025da3184235f983808bc11dd8371668c39d49360a4e81ce740d03cf7a4926726b908468029eb280c08f6ab1f32fde9b9beab2ad2fd2217c8c0946e928e49d8e6f901478ab904994568bd4bcca65a92ea0ac847efaf359dcce8517cca9e42c62506ccd0e8732256e1b0250603d41223da7346b75962b6129b46665962307d9563b9813049b0c4d099ee2b31e19544cd33a34392f9a1db0ccd83c7c7ed9598f484247a2d591f0851bd728d13607891ad099345082e1592e7de18e938315063c05cb5cfda080aa52b2ef8e12134c8015dd4287f456aec4b3a842b858e4e7fe6ac348cb0c17360cc32910022ce688921394672bfa1017c757c0cbb871bd85206f64d3c4530c1c6eee1435f61b0356813951920a5626a4a1ba512eb232940c80ba154db09a4782075e87c5cd399bdf80f8a09358b22c0dc5a65f3af50db313913b5bfc6b70d93104f4ea4707ec5c6413e96a849bb9ce589060b725689d5b4ebba4b5306c0d795eb505495ff90675b2dbbf023381e3271c5631ce9be67ef2d838684d3178625ed2d5be716e72fc965c690602f36295f64baaa5507984d45e3250971d9c0f97211b6e67e44a431bf3e7c09566de3f59fd7289ca0dbe7dcaccc49b6e68d8ea5fe81d2b9f793848c2b35196ee684d15d026e802013ca54a2798ada5b29e4d5fba9398ebcd5ab3db9baad6ac6b702375e8d3dffbf6ed5ec7794ec8b28b88b5a5edf578858ec65deb1b6c4c2ee4bde05c8325f9d3ff17a72db12083265590da06ab3f875b0735971ebe7a0048d4767e330647796454572423045047011cfc903a82dde9bbd4338319785fd38c34e19014a2bd6a920f6480c39aa17de8790334c562cfb61494a90dc14a50a95f01a2a82185e63d9190f0caa75a3daeb79f8025848e472da38c13036ce84eb48a79d0b0d1267a7c5ad0733d0bb050603142edeb4a06044d17427b781b27039abe21b17024b3f273903c4a7401957c90709df19a4451e404221ab48f05ac0914e0556086e15447f7e90309edd83a96a7f9ec3bdd37c87e8970f10043441363f3f769bdc48e299662b229b781c53f7d00a7d39bd8eb771662932fddc90d40a2becfec6c0206fff2a6a8ba62f933111591fefb4367cbab6bcc840d8bdd7e052925a878bc1d1369f88629f75c4729e2c7036f652dea484396fd48124f4187d144429aa57e9106d214e7dc212db4365ac8f4e0b3d24134113d1250b3afd606ad1bf7a141affefcd99530f6640e9dde85108b04474ebd1ab8bd673b51ce328dd4e3cdb314f0c8f962e3106b68589df552e11e7903f87527778c3fef9f4fcef42f7822c7ba86ec3e69ab27316a8f96ee6b9ccca6ac3ab346815144563d07b9be14af51fc21cce51dca2aec0910a5d29a8703331df63198139f9004459a0d90638ef7534c9028ed620e2faca92fcecd3aa57cbaadecbc7a0a9159fefd2ee89f793007820d3418991d907e61baa1fc668ee4f8ddff5c77cf488059b9a9b0f5a277b28842588e75270c1e77fe0d9263e940809a7bf95224078a6804448f2c4ea20521cc7b2171de2603585228bbc91a398df4dd927f690972a8ad928167649d34b116bdb020574c04370ed6da5e7f928bfdf263cf1591a4fb63ec147d880d0555e40c022092959e0e7e9f86014334f7afc874940e1f9d15d61db7c8d45ad7698db4b495d238494df84f7074352761afc8f4dc48da95174cd84f9fc02c0f3da4d53e685159ebab0c2a6e2a7af29fb8cd5b555f091e9d20ac014d8e7a32e34b3a030ff6937ca54596ffa865199e49c4e5257b6a5a843ae49bb2c8a58789c4639fd6e769b086f174d0b1f96a187a41b0f5656b8b80237aa8066169d12eb690944835ef2f9160212ec62378a09d43153c9ef9fef570953dabec02a51439575079e680d23b5a8bfe370020ff32a5909aa828f3b5bdb6fcc8af6d75b9f8ae112eefe561f51602a97225b3580264d105ec6fba8dc052d6f9e2000be6ee3c077f6020aee3d52ab39069c4015d8d9355386e7566dbf237d00b0f9326de98cae0fe1c44c4bcf047ccde6a4baf9a7f8b8d533bab5f2dcbea68193da8289a5d068c162002e93047de2d35e4f07cc52b6a65cbf66f8b536b1aba664e41fa7f67e7823b70894dd5937649a7c0a199526f9928bdf722e8aa444c01c8e31e8882a80d5d7ecedffde4637795161d06d9be4960d40ee103a3ca9aba9ae5e4d9beaa8c18b415d7e790c966213f8dd29d4b54ee55cd580d06b99427ead75fed4d1b1ce42a4ba29a9f41039f542d130eb2a331c41ca853941393e9bd1f7596d963e66506c4e06371334b65b79cfb677d61b6bfce635894c06f9ae1d6b5e9144d0c10622a57a934cbca5f6df39240ddba8073ce6fdc8454b74e43fb229e9f7b5450aa98ba4b85c0b14415cdd4433a0ac0ce309c52d7ad733d845952cc7246bdb406ac822d95096e90d814baa71821cb4e39ec432163f6f305c4fb76c6561cb2923dde27c17e5339145b47fb9bfe450c052d893b99e4f7302364433932e4a5e26b0184387bdb403c6e26e646dcf3ea58269f083ee1911b759e9af8d141c0a6cd24a1473194c228bf562426ae37667ea055cd4fd8b7f6c91b77040e239189a79607acbfa7f1038e3187ac3f9f4eec9bf1ce4f04b67a4aeafff2ed629e6ee031d7679774afa270bbb784175cb0a7644fffacbf40438177bb03ee10ee53346403c1a284430bfdd0de66af05430fe8413a26d6bd791c7bf4ebd1acf637098711efa7eae8a6e73aff547a421587cbf508c9b5271e8a5057d136dff739a1fc05f45ef44d553e2b95ff1eccce39b7c5a8447ae1b78a4a6bdb4a09505a7d8f25280ce2a7cde2f6268062a07c8c3985a0136001bbdb602d5713543e8389debcac84df0f156f61dcf2c3e3e462e49b39d3f16c009f8cecfeab0ee65b2a5ef168a9f21ae25e4061a1c2df63a409ab85a4506a2eee736139612ff79044f62bab0a4750e56dde97248eaf9d745346f5a4d6173849ccc8d5f02c2bd55886162c8a795332c2673c7c857f5d689fd37cba093c0ee588926a1f7f5a071ea3452340d41597682663f39de020bcc3b60b0f2c2a3890a4c893d41f26c7097e679a1bc798c3d4bae849079048866861b2305b8f7e9a4a111607c9ba33fa594b7922cbb620de516aa172e6b0d41c033f890110644963578e61e6eaca32cd2e57caf1825fb93bc6f09705f06dbb88160168ac5fa76296042e17b5cccd9c3720032882ff476ff7000ed4dad02d3186dc25bf0b41b02fc53f5a292fe25a4fac97afe7965a377a9fd09779d3e5eed756bc10b6b61bcdd2d354b43ae5cbdc75a2bdeb3a18b6736ffb671d5d1ba2fd8ed4430fca2edd450aad22c253f88805e2bfb44dc8d4a617f37f49bfeadc8b8a97b69f40ed43003ca5166785b30ce424a07026d0563d3624b9e585045b675d6f88af2f2650b0a863ac375b916ef185a765479f0392e82b1fc2c59c513b167383d6704629dbda1392dda331023d02c5379d0573c7b3edcb730b3f3cff125217befbde59652ca246584074d07580746320713d115f6efcb79c4d8398c0a696811fb8f161b4ac638dc9672bb94c7de85d409ebb17320a5443207fb66451e29d163b74618e76c8d1efb8ff65890635e038243192e13aa3d09276358e289e88a8b89ea10c456bfd76b074de4f9b5d62ded9980c3d13770f4e72e98bdf41c30fbbef454a8e1a763b7d66f10cb8473497966a6492e0b6369e462ff0eea3dadad991765cfdf2457f233f7d6124e32dbe06da5c2c9189688a5114ac3d4c5ac13cf3a33c59dd1692fbdd3da7c9a8a9b96b3fd1de89cc9134f3ba7a5d576fe80ca2b355666f369aa8ca394a336b7a320bdd5e6ebc9c9e916576e9bb3d3c0dc3d719cbc76823033a5a1c8aa524ad90e020eed6e5b314867edeead0739daa7e368bd4a5a6d7733ac6d574a99d17a86a33da59436b576d4a7b596a3b46a1d05b1ecada3603d2339ed4caeb5d64a67d6d7959d2caed5522f5c4a29a574aa524a596badb5562ff294b56a980911194ac9504a260d194ac9504aa64c1a329492212aa30d7112c76a3808f57e64d8478fa60c671680016b43397f3e85644efb0b9e0b2db6c7b4cdb6e0b3b47155051438ceebd19cf34e68c9c26915f734d055630d6431a95c6834b4032171b43f7d0b21731ac914125a80c7a389ebaac469d13d9f4353680aa986c8546b8d6a427c35e31acf4f8b9e4bc920e9124fcf52fca4ac1c4824f1a33c82f59c488c9933e69c530236c4d0303ddd508689d6a444492899dfc4738e538ad1112c871fe7d2e4b2f9386363a6ecf264c9044a82708202d49a94499432b36676b3835c2e170fd31b520288899a49b09fde4b930b2945e68cd9657ece897482a04963ce3969d83c0d973f3c0da741430a134fc367783d34da490d92124dbec6b3d75393b3a7bc9e9c8a42c6a71ce5f5a45028f7bc1e54f6a204f15ee79cd7d3d56c79ce2513cff9e6f5709b4fc9b3d56836afa95ef3aa6945535e4b0204afcde035c75e8ff601d2d0e31b24b47cf655e1ba520550bebcc5625c3aa0043de5e95cf434262a86a1dc7b7dd8c205cd099cd0e204d6bad488bf4d90f99bfa7befbd4fb0ecf82d96780bf298fd090e7ffde27ba99080bbf7de7b594eae08c20cab595e13a323db164e5d132c48b426ae89971c300b6584b6262c38920135925ec91f71ee02043008426a1206d0cbc94f08582043e4c48720169a849c9400a8014c8c9c2001c4c216474e9e48c2020c8c6aceb09ab55a926d5e221991428430b088b20598dcbd443232832422224cf9090a80999c7a89f433f4c50f124ffc40e12c2a9c8ca1095119436528a1b12e7d0447d4aade9609218b3c4e8b2717dbc4e4d3bf2ef26c59b98133d6a2f530296b3e8ba40b94c773eb228bf254b756ecaaff2856cefa9defbdd8859e0be93e50d5a2f5e0c81224436d2d097eccf116477ceb2d5abff19166aef8c287232e578b3a8fc67d5db65b89a399ba09123298ca70e5600229685c689ac660da62362c571966dba25a9dcee974ceef7a67860d25b78f5c0d25198bdc9e5d467ad0d57458ab614f81984d6dbd6066a90e101062b94b5d91658b1d7e39fefbc27de1beb8900497f558fa419f66901018114c245dcff51ed02dcd39bb55c9e35ca22658bf49a1ca505b94d8dbfba99f30cef99b42736922993ba6d2c4d14adf48be5b1cee7a08390dd1272257d1cb08cc8fd4c83775b5d84a734787d163cc2a6aa3986c435a5a4899e8ca4b6e400daf81ef837c4f81c8344fe5ac431910276338c2c818466328b9b8202aa2a34498248941248653bf60cc9827a630929e8ee88f112e308ac0782ae3e933901f080864a466a5d3cf34c9a7e9edb125a963a3c2f17a86a8b5d62aa7d3d945e8104dd3d4dedf5376eaa686758cba6a0f5121fab2e16d1acda514a3445a795b25a34396070934d44343f410ee21cad44df488aeda312c2f1db986a8100da2afef1b1a1a72ad00c263a74cfd31313149a61a86b0d323fa7d97c7d3a1efa3b6bab223629eb9d6229e007044ca5b8b268f19a988230178eb9bd763712de18857099400838594297489985a6bbd7992479694357ec479eb7289b75e7126810adefab7e4ad7bef48a4129c1173344009a4a126ae2d4b6468112788626b0e2290c04494f1d5b3a326967873f563f7b58aaf4844dc60f4d56db64ddd0f752888afd8fab0be1889b1394ba7c77810be7eb92ba3648a122c3708c5944c716448496c042a00b1a4a40b20158496104999ae8c5e896d1a2a6fede4412a8900f6d6dbf5226491062644b691921d0905c5c893525a6b6d254a7d299ca199acd43b0d6b476186f9f5254df333f46b91390d93396d43961842501ef1df681c74fb0cfde3acf9d622736a97e9332db616c9a342af7a8c18305eacf826244c4628500dbb89f369516cba847de0640c4a9c80f102230999ba1565fbd2b7a2dc33295545b65e613926501f75524f1b4ed89c3c351967f2d48425f41c75b6a24c7f86da0364be01648e0d9fa3ab38796daba595565aab05a9137db24ecf3c51273379a430aa449774cc64eb29bf6ec1ceb90c95023d3f9239d4fdb90b6af2a88aa437a1fa388fde8b9f312fd87c7a2798900a1b70bdf819e382f1c7a3fa68a4443cf50e1ca90d638b9982872dc4f450bb9ae480c482a7def1a74e943a5198cca14e614e79a44ed4a99337757aea488410947b86dbde0d7db2734939e8ca488b64e486f5518bd4c71c96671ed1d65affb99ea7516647cd534debd6b954388b64ce9469349350c2f3ba0c0c4d7120ab03459c1651a107bfb528c5a8c529472ddaec5b53ae97bb20933cc11b2d5acf204eaf2c0b9438accf10640e94b7d979b48e0cb717e4c92473cd79e1640c565e62573aa350f2f376ceafe79cf34eebd65a2c28161c754ed6306b9a38a4903a66986d51253b76c5624bb228e72862619c33a543928aa2fbf7e55cf47d2e242a8cf260b7b021dade03ba859faed3d3cde92967b41919519eed888a1f679435c13823a7ad4ace9ae60eae0989630ba9837b42e650a7463267883c72464f7d33a23c0d83e5cf45f1c7cd6886238bba165444e22029112bc5eb2079b420ba72cd1d163671507769413e04c128b5520cd156bdce84a44a4891ba85cd1dd9d3c4419dba164479e813623cb530091be229bd22f494a67ecc96640ef5322dd2cc296b6a91d2316b921486f3e74d14e98970ab2bf2a6183386081afaaa62a4e90a11a22b36c03a06548a10ba62435191e6f055ede029f68b4e9eda524b8d24f258b52c5b142f8f88cb4a749f9883be0d67f3957105ebbf3aaf87528ea31dfe6810875112e9a56be0248f386585ebb42ee348c963ad49c04bf77e988180a41ab13c561a366080687fb8bbbf5fbd33b106ddc7820d3a8c73630fcce4117fddcbe604b9060f073b747043c2d286854a67c991f2583de8a42aab168ff0d966e70be797f5e086d27ce5072c9d7f0902019e6c96f2511e2b88036673251cc019d939620949494a4a5c66d69522a961ad1f783dd5034a716a98002080a7dc45041b2fdd032f64e3d54baf60371ba857edaa7cbb1a68b028c256de13364410800e00bc748e881bf39512411e7108f57573268fb547cf11bf9e50109b624c4fe711ab7d7a3ddc00c258c794478c03e7fc7deea2c89a2fdc83bff4400679c40408ea845445373627050802238fd58397ce8dd065d747c0f325c4f79da1fea42474b5836e5eeee0965db493457d960e0fba9a35a6aa481e717e52a73c6ea3ca54990dcdbd837fcb22675511271c47bbc3584addde7b25186bedbcf25e6b6dadaa5aa59492524a697777eb349d61ed30febeee9e362fa90447a9e5e5ea65d5ba9f86e30cdf614d15f93e8d410c2c92dfe418c460bc6169cf51fc35fb5a29a55d6fd42c7bea17dbea9cd7d3dd466bf52c08e69c93ca7b9db22e9d5d6bad1a94c9e0386fe0b0c2a6b47691a758bbc8bc5dd5a2740dcae4e9b8c5fc72529ab95a25adf5de7b6ba594d6ec95b9f6da5a6bd55cdab95d8b6515d265aaefd3b67a2de6bc32da56b39a6badf55acc755e190f4b9e35f33a6bd5b86dd3327bc95cbfb6d6cc6b9d30d8b56450489cc471ae69ad813797a20b558a9a735a87bb70a4e135d5f7691d963ac2b983a250e36bea8e976da28f4f18176a21e6b84d7bade332ceb3365ece53e2a01fe86eab92af732994ddb814d8e3b3010cb28794a7739b95a2a65d97a207e6a62d4d58a5ce759dd763dd9b3b54ee58e917d549a9a3276c09d6e459dab33a795af0c70a7a2ef584101c1753923c28805053acf84c8eb179db658c278ce0a919a454f514c7a9e32a9e7aa6fe35d1c55377249e22393186d1d3536f297982de6e915f473c15a47ed8a1b3e20955840f1c97208f092642b07561eab0e8a0f9a880897be12d4bdbd22babb8cb8bae2413311f7c52006302063f3419b97af0b1c2c8a8071e7cae10322a010f3e312123293bf87081195d09f2d9f2649368c0c5899c7a896483183a10c94174caf825121120a62042048e75f9d571c660a8a4d7e1f74d27b80a562f05196cd76e3f417e8741ec6fa0abcfcbf4585a2f05d902cf1b94cf49aeadd7c33927bf10c1010636e09f1d7e248fcf3df2f8fe2087782d244a86915d24151f19327f21b9a03c124c2ff50e75ecf61ed12e7287b467465be6b1cb1ef398cb637bc563dfbae49a9caab42937e7061b80372d7c426e1ed0adeb1cf806fe8542a60e2598e2490e5a1414b49e68524b94d74f4bc890ee86d613940fc95460a5f544f331075d217b89969c280f8bae700aa6d43b35eea36db2461f1ead11c67e9fc84c3d63dbaae48cebaa64ef477f295bd5ebf1b9a17e9d83b0c6e80a7b06de50df20ac4c4d7485bd82c92f649fe82d7a7c891edfa1c7d7f5f8be1edfa0c76e63168be4c9fce6b1db29bd73d43b358edd26491ded1f76492d938d8faa1fad91063e5a2a1ebb7d519e2cb446f87fb42fb03ac99c6a46aeb06357961ac6e3ba4457d89f62c9a37db5973cd6a5c7d8ab1592875597a48e49231c3f3259cc58bd7c3351235532b74774855d7a12b86e8de80a3b8fa64979a444449cd68d9eda22d3f0b19f28914d980ac74c54c3f1c35b953c5aa3948fd5db3b98e11b0df0468bd81bbc115bc42e9f01a9b0fac6254fecfd243eb5881bcd63dfb6e4544d78420eab13c83d57ad95c730db84d43c1af2680f92c85928e4490b995f0f85c8319e285af282c9d5ca42ecae9634616e3fbd94134d049916b5883d1552a21631f64b947d70f619e00cf37f481d9b63f7a13ccd4457d8714e61e750a0fc0d94df4cd825b6fdf4f98de6b9d449af3095d22bdc44e66007e50e7a84c48167cf6d4bb6b676addfdced582cd11a69e196ecdf1b68034d9489e9e808069bb1212712a71165fa8d62fc7dce8302a13fcee7b6701cc2f43ee61005b14f30887dab5129bd6ac72115cafe45dbd712722c91bb27f2f4ab9467488d90c917d47ec8d2c49205f038ba99d685deb1dffe02d0b7cf97440193058c7c177d3b0cbd93999424795b6951ef8cd40895d23bd4c9b77737bd14ea1b6997af42fef68e873c9d47d3a3ad67fcc0c918b87079bd5e499cecbd768bead5722057f0c909f2250cf2acc19bad1952f08547af107f5459a194822d4a90b6cc0029055470607008b01553fcde9b44149a8e3a73ac00fa5a3b89134014e32c35e1a46f7e578a7c2c588a319d398382f602054f38bc709072c3d367003f9014b5010542568ee0f2d2ca112fa0f19b19194315463f473724f919ea19d8ae497ec65b6fa30204215d41f2d665116f2d75ba02e5c72e7aebba42c58f3de5ad9d6d9bacf0f58ebdd6553b640fca4f90c67333e90529c8a0797b7611dedfc673d36341f3ee6aafbcdced5a0be19194a6e0f670d8e099107c830078db610f9b947d04e9951dc149cebc1b49061a7d967111d2a29d209216a36fb083f71d72032579eb1f2c6951e2c7b9f401985cbd4738416925e8a5b74292d46225cb4b6f85ab85b20048567cca793427bd9e9437889de835b0bb3661fc04717ce6e998c9de09f4a3b802835f7e823bcf496e6eb2ceaa859f731bd24f5083e7384e7a0270411e7da83e9b1883a3086b7ae9e998495af2d33914cc043f4104fcf474ccc078a8f1bd42167a6d3d2d4b969fa0cd679e0928ef10b7e63ce8cd747933e705718338bc3d7f6bae037163253f41033cc7693ec1d9d1e95d97cf35d6b4c7a1750c66ae81a38f769486a588c14f90009f8155e6d010843eaa03471f5fd8655d9662ca4fb0009f819dccf911a47e56c1f80902e039e9ad90b578a73441f319de4cef97f3a078f47143eb13ec6e28b5b002cac151a565cb4f90f519a881a30534d087eafb06eaa8052f85ccfd2f289194927c8633e585207e82e14b6f85cc259682c84ff07b892d853d75bfa0449a22f617df5c9748515cffe0550f84f31b02998f0a479b4779d722762e93b351362080f01287a30fd5639fe1383c77935ef0d24b013b0daf711e3dbb098af017f452b8a10ccea3db6380e633ac1ecab9eb61efc0f92660e7c0f91c9e586250b68892dfddb44ba4242b2f91b018f113bce990019acb1645781b3fbdae459473d43be1b62009a416bc94621291b493a246218f8465e92798e3bb934851bc7e821fbcf452981b9a414db24703a2b1209ffed2d7c4f7216617cc300df0a6ebba5c3b1478a36929f046736d626d0678c339e79b731c5803e2c61c28df03b78e4e303ec1b994042848f593531e9b60687cf1aa1db2e73304c14249e6f56991bc0d225a1332c7e1a87aec5cf7dc8979b4e4d1b863b11853ac29e6147bdad1f2e29238a80d1b8f026de85c81478c375c446346b1a3182cb684029d9317dc41e6e040cd97ab45eb63b55e8af0e2c48b142f53bc24e96879519239f2b9bbfae9ad1e05ae1ed7a6a6a332f248e56533fcd16203c55c73fe0cd1bc0ba2a7855c665353513657d03c3b613e9a3e4a41f389a4458d869f6e83fc741cf167467dd84c14d8403a5e720fd11f5d6c8ca39e29682ea4458dca167dd864e7d10d94f35cd609c9951cc244b9e833922bed0a2800f05acef3681498f318942a787a097b89d465cb5ff1fa0f5e227591f29cd669e06c0a9bba145104d1b4ce659d06cea7a32b623bb449d64dd488af8e99acb92c0a421fb502ca37405f86d94def84ce35ce51e31606a13f9d73ebf54c07e14a96e102d3fd65389d66538b5665258f3e6cc2116716678fa45fb12c5bd4326e03c7efb7e975285be6e8e94cf753bb94d0b491dea12678eb5369168591517e7d7a5a389f269a89e425c99c4eca8c9b4b8f85e94e7a678e38484b5497d50ba2c29135def0e969e1db67e6bd834275a89a02c709e4538836f1b4931b37a68b3635925e59b7363d28cff7a1c2cc7edf2f160a3d2a6c003fca2d131bb7804af5d35b6cd15a950d68a4c84cd37a32db87b72ee50863f3f0d6fb8824c13a0ec71f8fa7d69a57c3006a3a923a2e3d821e71c32ecd91d4a185fdd2e9925d0852c1ce688777ce39a7ca6f03e970c9b8f2a0181cc37b7de2b468e7b401279a5e596fcda7b7de320686d2f374cb7a27e91eb3e9ad6b7367be756d86b66d87dd3d7dc020dd42d5622e7030c08035d1c2d0a2b52fc0d0a2d5c01c39509895434bbece594785e3073e47f3cf557ee3c60be78652bede8937faa5853e3e8e428b3a54e47b820a3e2dda51e543fccce96d816a5909bda3eda0dcde70b4c05f9f5c4d2da0455b82064e47813e7eb468bd877c9518294f01f58e9d28b7fea3772447bd9e6906956ac187ea512ffc0cc7394e478152f3f1f3c17a1cba4079a63c62593bc1348f8d4fb7311bf035f6ab815ab41bfc04259252166f2d90ccb17e25bf28400515578a145d314274a548100541ca6597edb89c2ca1c6a57fde0898e1d2bb1a0464976e933397dfdc9185aaf98df91167ee58491c7646e8a1386d0d88e92a4bbab2b2f581972cadcfa2deb961c01c737c367f1cef4b691e969559e6371bb54ddbfcef78b9ab6930f40ee79b11a9a3bab5ae0f2ffcca34c47963b264075b953c30d0150c94a731ced7fbfbfa0556c03b08a88786fdea320fe319b628c5021c8a88690103072db67001c5481364c8c08829a264b1c1c9ac4c492c0bc5124058e9258ba6af8edd71b22c82b8588a135e9d91c5ebeb972f6fad95ec3858108de0d3996441c4054b5d50b9610cfa848932342c8ce044d1b26035ab0373c60757181c7c180a134410511813bcc244e941284cd21108588185b102041038620af365070854390ab3050f548ec28c910304a8307d354b61352bca8f1850641a2f917ed26071430f4d727d897403098c18d1e58627696e90f2c31d01ca4285e3acfc7047b63280b250e1b828595c2e233680968881c2868d0fc9880d20d7123150d8b00145cc754ea65259a5d539314c9a74680919c215910255a69794e9ced6789d3dafabf1e6161d949ca0256488a6248a2459e4eebcc65acf7377eebc1a8bf20e47cf6f4620ed27b40ca3e75c8327c8cf35ed1c38c2f039e49c07f57cc2c42c91f97bcdfcbdb79f832a79ec180338bf01e3faf5eb9cedbae92fd3df8ec9ce42f2d0eb5507c943c306d3abebb5c7f8f0372cf3d7c72ac46da1d650c8e4c23485a92564c846054a4b0317326446085ad587cc2f925a4f524ebd86d6061b803588aeae6b0056a126e13a05ebab48f63ce5637dd5787b69bf28cf34fcfb824638662eb0163f4ed88b0bc7d48c70acae26e1067dcd8bf2b417b9ba391c5bcc5fe75ef5f51de34290abd39ee1f811c9f56738ba9099b40488574bc8900d8a0fad27d387cc145cd17a9272ffa8e4b1632160c1b9b763134657d72f1ef353afc92e6174c6955e082687b94e5dbde3f9756aa4773abfde31a963fbeb0d46eab87fc3f1eb2ffee6e6e2efd85ab080f29b145232749e72947b9ed2209c4abdea6eead407369816af7b6037b578bd03fbcced588bb7c77419b09d5abcd733a516efd2bd1e02963aa4c2827389b1c1b9c46c6564e1b632b2282063b744327669e7c4d22b9808902035408310960e175abcb5928ab7d60f80c3ddd039af013318c4aa5a5ce13a0e715ab4dfa7815fd6b44e2a2053df52b9e67a0d28e50afc361c9c3983d8e7401c15c7398fc6a07dae3b2e03f33b9f5e0fc63d1e8a0b551d289f66dbd488641a9e401dd72fa13bb9a32345b9430089a50e96ccb1ae52b1b20b6bae098ec894295b1954a8e08cd475b5495bd21fab4d8b99579f4b9e04a84fd8e80e4a1ded46fc0cfd33f45b2d896cadcd42ae660244965afc2f43418380b250e1a86099b2f9b724872046bea68750648ae937edf480861afc1cbda0a14dca921d9c704438224b2ce162441811652b632b830922b62a990a9d9146738a06e40fa9c3c65b0f2275c8ef495e328738e21979b528640119968c028f164340ca4b4b34bcd1ac07c92fa985eb47ac85ebabedb14e85c821189169add685fe9ac81ab6529cf81a560a2583415ab4aedc2f5d79cb001089c37a0d7fc81ceb1c9c208ffe35ab2e843e43e41fd631ce4ed65a4b438bd67f380d3fc21fd4696302280b150e0cb7440c1436c2d8b8a19ebd06fbdc504f79f69b94d7f80cf73e2a2160e11a8950074dc941720688025d59af01adb5b65abfd5390faad6bab5d67a2a64512c99456dcedfe7f54bf6f10305f6a02b6b9d26e5ead662c0ba0fa9a3bf71fe7c9664787f41ef258ebd55b060fbe284c8921e63230c14ce35440c60c6bc9a7208ba612c81a523de709c4f6593f9d8f5681fcdc3d2116f388e6c1a6dbae9e9e441f274109d403c6da78e01c993e94aeae09eba0fa9a37ef3279341bd83b2b0837c64ce03e48a3a8bae288bf53d2da8d32b8aa3e4116f3fe69f8eb73272ff985fdab6211199f66811ca8f1e48799447d80c182eef4aac0d883c666fcf9e045269d2a449d3aa2d64978b490d6d5a3b22fbc8829247dcdd587032862f498a94c6a83f5e8620f535ef3a07727da401871ba8f116a494524a432099b7822c3d0c643e760e879e0aa31602b93ee2e93ed7418c7f8621902c6442bf7012a79b2a2ddc5c7aee398f6ea9bc0b8b741de6b6ceafd7aef39f1a5a5df893726f0b81648e352628cfc0142acca173da85120cdbb9e7cdeadd9c5e89d0ac67f7a4938657c88bb195d01b88b73072b0bc9e59adb5f3a66a5eb34c63d54bfdc3517553de58a73818cf6ffab8f1d3592de668517a074359ceb00653a6dead754dd7a0647052aee44803f5ea3fd64720c058c38fd22509928451c88fb2a6907f86e38f9febd47f6ca5610e5feb877aed1bfe50ff09c71f6f4306d4fc0ca524806cd51426fee9429e4caf610ea96d812438e2f086d9e29c7399b3b9901a5a5bbb0c41ea03c97cd47c03f4997460f3bb85456a70b58a081992a64a165d80310619695a9bffd4d0dac29fceb9300492b9740b32d9864cd7d150d0cb08111b5a45649ad6ab466b0b73d8fc670b2f38fe781b6e60e4f0b57e36e79c8639e0d60fa62be943648c888c1f2e63ba94f1a4f5f3a47d0ba9cb1b1287d21e8e887ecc4743eea4fd907d74169625260fec4157ed1d8893701044a6432d8a7d5d903af0b7bf30a50ecebb8af1dc4490a7cdb6853917b528851aa1c92315a2453b45429489cc69bf61ca54c85f680474deee0215ea9d9132f9f6a644dfde4e2813a9c33bf0463b42f57dde8114a8574d5f1f6c91c7a654322dea1d3a4a399dfab0348221db4969b13da66971a38ad3b7d6a12cd6b7731ca5aea72727a7a69cf4a8348d1656410b99220800000100c314000028100c08c5429148200fe464df0314000b85903a72549bcb836910a3200a32c0184208008000000800801087aaa60800c804c07847778a62af42045c3eefb1395633e29e034b5cdf2546325fbc9c514f576782761573019d19b546730653acc2cc978365d94273680b7ab0d6ba402a841a45626b2a7826cc0148433ad8c14b87bdb74671d85c2fc8e1cd5df4eff07fc2f3af20fe69ede617637829b6f1ac2acea81d7b731e23d615868225d8d30e4a2fd73a9ee00fdb3bb0379f2c623787d6ff0e60bde4e2429651c41054f1b8e5eb177d93487f1a85c27fffeb02c5ee47001de08d4d4e3da1a43b78d0cd36823dfcfd63ab1559e12971e51e16ad1d9aac40d1b8a1d5c36535fd152cdc1dd743a6d1e713dd022c657f81aa1b1ddbb6ffcae518ad2be036bceaf2921aa2705002f800c7774a43b0ce527d08b6496bed3e58b2761805597beb0c54416617d55f1b56af38d66223fbd0a748bfc1abad4d37eb1cb6c53d2572046012dbc8ad1bb71d254c3a3cb7c2e3dafb5f5a980f5c0bcf895fafada1b01c51473e5f878fa12557bf4d03819c452e6f12e2930139c8d49e428e443fa2428e924dc486bc24fa881878a5eb7e4cac4db4c33e138c559a01664d15c9de976c24c17b5706157cccb889fe8b74a68fdc3dc5d1e105186a265886585229a734336ddc1636a4af7ccaaca6ddc215b168432cb21f5cc0beff97ed10668377117741ea4e0f3bd6094655b7986652629084ecb289add5684280d798e06fe7c76f2dd87b0b80c6d881dede7223cf0df9aabd8beb883623568337f4eabd45978e1e8874268ec27d758f2532d17ba33b412f940e2c3aa0f4ddacc85d4d89299fdb772c99897e86f4d6737bd32d3df748eec647ee3edc273419315e634e5a6c633eb08a285b4d240cd05aab26cd03c1faa733e8e2ddf046250cc643a48e2f4b14500262a0095c55191d8b7e95851ca50daefed250b591c12e1f27cea70f3844a68eaa475d344ce97aef58357f5a422136c8d1fe0da71686bef4fecd995dd063a9faef2bda19214a5b53976c43765fec464fd51921955d1cb6be50b676617246b8478ca199345ed4fe1a90006ac71abdd7e67b3b1780ddfa7087d73d18fc125f72379742ea53aa3087501ed05505f77d03e141d17fdca58a194ae6d0c3040397839e50c2346a68db07d05c2dfa9d7f84c1cf3973f67a0f7a382238e01e438756988ad898382dec85da89415f9d93bad46179f09ec8ef6e037a8ac7145f753d6528ebfe58bb482feed01572e5f6413e4f7eb147d9e7570bc205523acbbe61a3cb0387a5b206768dc06055259084c297f7d579bb1dc111afb5defbbf1d15ee906a5e81033acca506cb4a6e9468ed0563273e2d88d221c33e56bdb1c7160e48a876ce33926373eaf2aa82588be50b23e6366c5704446ae843ca862cdfec095680aab539b47e3f445bdf47b92032a3487f5b76d1e2202c3282bc794d2f216d7b16bf4593d654868899018f277eae3f8faba52e7c31aeaae28fdd02f09d4032d3c3b7b30e9411460b3cab5d78d182d63484b6cb23b69315305a9d9a496b9899c4defdcca32ab49c06efa833c6e110e30e0e8acc1ba2ea4561595cef8a4bb8bc6a5520ef01a4ff440c6bfd79a6d175045316452ce210924922315e8d66b83a70966a8f2962788b7730a48439c0c57b50a3163d96adcaf00e8c58928bf5e783eee9f7b9533683224120d8c6fbce093b5cf4e17bd49cd8ec0dc92480420e5ea6fa84c455798b19cccaf848dce911cba782654134648acd0024ba76416ea60957934c9b2586926a42e08bcc6a3915093a968ed2eaf9561160d5b5a798c41377d03a62ebd9ea92c56e65eaa1e918bb67ad93c4d8c0b7e91209736a37da56e81c540a097037024cb036586efa74a4262ca2d657bba891bea062f9026b07ffcb72aaee241b57c1d563027cdfcda26064625d9adcb55825ca7cd8ab0de4595c62f72e236d5595f588094b439dd8b73177fafc8b8518787ffe52df8a56d030a1819e651fcdea99b504db92a225d1202c6c09f9a13c11231a443ff9b99efa069efd92979f4f702dc291b11f316fdc25965832d7605c31193a2947ff72dc8dd500b70802f66daea38bda1eb816f1d2eb0a28fc2411f77a7d5445cd181120e65663e9ec3d12b9b088f9a365f215c0ced12e609c478f0f8bd0fa58d2f5dfecff35d7e121921b90809b93198aa87ba951c80be1f90036629d5b15c67cebf3d496f120e9df73c60bb3b831906e7825194d91319d9ba2b65720eec3e7e3292168157621f2796903e8cb0cd5ad2b5f85f5a1fdcaa42772ee681b7c3a0209ed17218475fa3928b0401e2bad58841677bc944569126e3f1d148abec182d675042ec67a6f1be04dc4716bf184b398c903621717c280132166226e5f549901c16d963e80b4d295543bcb52fbd3e57f548ddfa59c460ddc5a1efce7908f3af2647087f57258507ea2661a66c937bb28509516795888da0695c34e116d433e305ec12cf9d6912e881c2f8a76b1e2e4ecf4742f3118656312552ce3da13a8f37b4e846503f51520ce9d76b10f2419ee8d88b5e4715bad2ddaf1ad1ae58436353cf49b1a719577186b4bd0c48403564039398b9bd6054b8bf13732349794951afcc2adc2265cc215a8e7c17a2516c9a325940469611fc5ea0aed01c03d8d035ddf7fde924dd6b32b8866256f35fca8886f5a4153c445366f61c0bb452a2ff470b0c4f1ed6dd9bd229998be2910743241261156fbb9feda06160c6201a02782ca826232e4f799922bec0f2794a16588fa930952dc4b3cde1ac6a174df06ff9eaf4e46c7caa56040a429ce1a79f15828970cf01a5c806fd636ead0e9df1953890bde4c8fa4639c05db3e0fc9bc0078c67e52683aba9d5528ec84864fbf4e42879d1ac22c28f0977d2c5cc565455db7c7a7fb5160ce50a67a58ad1e6ef4eae88de23df15a9043b9b5297179c238abd060b40798bca8731db0557b35b51c8304a9d7fb63017622a05e2b0ef967f29d1dda46d5b740d2b9f72b4b4f3ec7829eef860d9217b54045dce60b23d4bc8921e5f33caf44bbbe4c05b55fd24d3c00a7f2fff1bfc02e6c2ccd077a2cd8fffbdf1d54245da179e3a1269fee5b49c77123fea85bba483f55a507b8d50f512c4566c2787a59514b02af6c508fcb0082fed5dd2a26b356ba7ef692c9dd18b6e59500b7524c2cb0722b25d082593da662e301b0d6c39769bfaea7f3ab1244e95c9fce51f95c75b11e383cc210e55194832dc2c4b5bc9a977ff0e205beccea0a7bb4ebd82d1bc3a9fd819da5cd48f959ce2c7298ca44bfa02023e4de912c2ba61389de414c837c8ce7bd587017ae64da958b875084bb77c306b8a0c8520dfddce7e072cc0eed5e62364336c02a841efe26f0bfbc79ca321c8eb8ac8935678c599cc85c898673ca03fa93d052917a94364561bd32d3cefd43de8c5656b538d2e151e9bf018f170ebf7f2a8b5a31a79bf049a3fbc9b00e45dce6d81b8d9b4f45e4053b6c741a8a3e1bb364ec15b7718d488fc3c59449992aaf97a1e24d108166cc200a653607ba74325e1b8f0ec9cb25a87c15b4188aa8fd4673e0d68c56067ed2ea874065176af3ed165484b2fc8b0d2f78c80d7aba42ef9d66e3619d3da9d10bb6562604d5adc509b5dad6be2c0205cc915c8f099118c4d0b0bdec8dfda7d266da81ae89f8a6eb30c3e515b8bd846d985c463fad024185eef147a81aaa23b4b761955b027711d49655df8854ec2ccb62206a45f8763634ff0374b5e02737791f02bb47edfb037296d897de719e91d50b92b27ec7d44debbb2776cef3d762408c1466ccdd991d906cb0586f0947fab9987aba1ed5b7beb899f20401f53a79c084d4abeacd3777a60c137220248aeec16e8db96666627e3c4f1b8a5edaaac1535925a8b17ab9595336c800c368f078dd7c497526858b2f330c953a18d1f199550d5b13b709f66255c42c90748c4d884dd8934a82d7c832674990e2c530523a1d9b70f7dad0da3190be9e8486735baab7af0c6a39cbf1f98f67fecfd9fcd81dc4d9d396b7d5862fb0effae3052bb49f27c3c06e46b2bb92977d4be43a32d513c89ef0644447d1697a3ead73d57eaba307b29d884289744de4937cb65864650997a207f7ac5d11c3553e3ca3005e683cb74e79be7b787c31d6bc2bc6fe1025d57cb72623819ae8eca69232971d645c381841b72de279ee4e7bb7f543841c264b85501bc492424bf1ab2184b7d2f4fe1d48450bac1e91512e1e6e117069f66298d3debb42b8999a261bc135446fa74d27219a5fbe8f45696577c87f6f7096c059546712b1fe7156b03d4428cb242d2b56290caccd8927aa18ab3f7db81bd0a6efc765266b76b4090cb6420f68aab7c5db9a54d8c326602dc6a0c27aa7689e159a148f494829b82bd2ae450757536e95c89b6b4da68e897fa20d4e737aa559493b19ad5675a451d27c785f034d5f3151cba0305840c72ea9cf0c6c3369a9abc998f035696f40605549c942c8c26df2591d8eeaf429fffe619f4f9afb78a10e57cf8e12b4298b459565b6f2ab3f7d5c13cb07ca53ebecf431881471fd49b0a6e0371c7266f4bd1529b546855c5406713d2373ae3a294c82ec1034012c956c95889f36afe71b77ff65bb7c0b05071e5f398d55c13537015f0b2f2f4d3c72bdb337addd708a41eaed5b626d09b49ce479e5be7676bd72ecbaf154a11d448ce1571091657c91cf73dd66c58160b61510851c17d90a9ccd9ffc435888c1f364dba51b11f65404ec8bbcdc945cf7b3d3ca1e758a130681879002bd0332d1149fd31bc9d1f2611754cc59d788b2b4bb40215abd0ca033e579292ea907f6b0f30dcc8540fd0ac55475698fe9fc28286208ab0d0fa1bbf09493889ee0ab19d4f7902815334182359be35cce0ba28918a8dba75202a470349f3cf4a8d00b9b765ec78bbca9679179bc57008ad28b77119b8ae8f0889d582318fa6ac6df0924af10399ca8f6c8047a88b651e3892d22d76e0166603796fd69522a3cb88c59ce36312830d16a88e35a43aae866d58d4c78b4c6f116de4fde286a8d9f2d8eef7d70cf9b28633e3760f046d331d15cb4aaaa766d4ee566fd6e0b1c15b29a870f6c335b3de247e267cd5020fb3c365dab1309af01107d8d4d69ef6824ef12d4b3bc5aac83bef9c636a27113e5bd09531089f5e514c09cbe9d80f8544dcf7bb2fa0f4f65548c2a827812dd36c1f49f2a85ba0337b1e278c26358b274335a3f9e632a2f75accb2bff78f45d8f3c142d34746abde7fb592668e568db0224aa35522c4fe6291670f0e0c7ec1b4e829bda17edc6cca97df589ff45b0aea3e9a6f70bd088d6c0959741423f87f3ec210c7fb93f79e393337d8e59f68ac40b652ef684322aeaea11affcc733676310be2860d8aa0183562eb00b198ec628ecca18edc841e533fa1a31b7a98dae68d094a3396b319997e289ef389d09c251f23296332eb3750fbe3c0bc9ca3b30c10aac1af8a89140feb4560004e758844d71fc26693e5020a5d35da4648213283be0862223c3bacca945e27a0dbb90939ce7d91d5e2ce1e6d2097a28c9a3237d32580e3183187961661ff6771d74aecd538be3c0891d26f0bbd9693dabdb1ce18135f2d7db42833d7a390166c48968397abf9c058ce251b279ee9ffc4c7709ccb077c0d21d4c915ad87c9143300c3c36b277eac6c2929d903beb9d1ca6251aeee830fed76d63844d7b73805b8846ddc7be2d377dd8883064528f0d05219905a70b370113a01227cc8fd4463360be2c62f5093bd1f7881d51fa7b71c69fb1bb1f6ebf00504dd41594d168ee702d81b9c6441d31f97d587ed7abc3b70c382eda4e9d3f64e86010196b8613090d3ea64e7036fb9ab876d5390daada4c74c0dc4fe89e2ec0735d3cedc3754d7b922a6d40410e51a47022c6477f036564555ba430978216ea1681fcc3ea06efa7d32ce98ab73f4823771e2c9f022cc84143aa1bc3913f9b1867c4fd3a27c6eb1d9290cfd457907655d44addcd3ad2726dd351e98a0c2bc831745e3ddff79b9d228ad638ce92273290bdaf47eb54b2d457c6df2226981c5b41cddb291e14d48058de736720fa7151ea79a6bbdb90f3779159bbd577b011680c7a1fe3db4fb5bbcb2ca2b7008ea0d1c22970fd6bae591564070006488eb5cd0bdd12f3a477125293a1fc7515329b1c1be54f53999e874f522b4633c6276e5d27e02bcad0b75c2f4bca4529a44b8ad2231b608b280bb7d9d1771d1baffedc9dcd906edaa43dbf43bac2652cc1c78586e520da1574b3161e043e755680380a511748d8d6c7078d2cc0bb699d6b2ed7e2e4d6a2508536462894188f06f570c60f182a92882b643350c22b85eae96ec9cf1300cf7acb00e1aa2e29a3872975be0ad3f104a126e5d37e640e53bfe7aaae15e74393cbd9984c99b293e9ea4636423e811dcbc585e6a6be97db4f9e187887568ebe04ba8e47375044fe5fac39b7446dbb1b0b196530896fc00c0b012fdbe40d13e5f2172b2dc3af6cfbdd62acd0b13174e13cc126ca5b44c341cc43d9ffda0d0cafd4b8a54ca125724f653e4864d51a797b63037f48c261745311bf8d27c410b60228c13afb6c184965469f25ce033550bbb03ce70d5cf28a2f219f7a30ad2cd72ac3ee52dc9b56a0fb3e5d2bcd8120c1260649621968891b1f1de6a626e14d7bb2f8389faa8a9e97838cc2a67c23bdeb028f6862f1fde349915ac1e69d419e5740f5971f559a4be3a2da91338831fa8dda71568e160f06021dd75dcc772b6802c70aaa5588087ff01d5795baedace066395bf32e13dc7477559200d799c4c717f28a21b82945a1a4c4a077e89a149b94d891d2a377a66d6eeb3aa92dc1ecb576ed1241a96814a46da8ccafbcb081b5736d4e90a666c3368ba6792bef17b6e02e5840dafbbaef7df9df9d84fd950d4f0ab930e0d735d93dbc923f4f19341e447b2ce22fb27ceaeccc67dd6faba4550c78b61925cd7d2fd789e7e41fe6bdc7e451032a442f547a4e64ff4dcea090dfbe5eb2ed04f5427df0d8808ae5bb2e9fa79626f4e2c2a6ec2485e54f251424747308560e11a24343e02eff07ec4961221f799614b8713908596d8a400bf91e5d741db91bf1890c3856a7bba7876e1f6d3501850eaf899c0eb76b50fa51b65876989b8634215a663cc54439d5d27a4999d4fe8270a00a2b30046aec809dddd8368885324c129f3a3ecb8cec18db0f046de988643a34a533b52b5dd140b9df3897c8c0aea401f30ff0892df608b26c5e7eb3b17913026dbfe757a3e7fd88bef645700ce3947c6868e369e8e60eeaf4e746c6e3f409cd6fbb0beb404188aaa6f4c5eae5e8ff89312f6a7d8063c3e008fc34cd74f97e52431d42857dc5f7bf86e214f78389e2464658786b5889d33c91ab278d2add0122ec450ce51ec529e307fb46aa7f96e98f925119ef3bc7d836346338d18bf4859e9d67f907748675be65321a46f3312877a34ffeb3ae7500429de8bc423ea758a55279402155d106a446566f0d684d50b77cc97b4034ecfd11a059e4e91e5cd40a7a78276330ead47a3a32c7886b4e3ab94d2978ca64adde5453ebd46df2f766582a6ae39377da521439479d4e70f03bb70b101a21f8eaa988843762525236d4212d1d31785f3b7f16911f897a0b0d6c4acb63fe03feffdfbe821c0d908bdb83813558b9db6253abec82205adcfe71e401e0897f30f3fd192e534f26736359ab24a959baaee44c446eca96a1729e4b900624533c710c1a95314fb106f15729dd62b74b7345dc242ac46ad0114bff663fc011cc2c16dd093413758ad1246c435c796d434123d5798baff894a6c60626b60750c505840776e32000f44d18748ec3b38dc2a4ef87e1ee4f130e2768b38d45eee75eee9d7faa68889bf22295914c9b43eb80ca335ef4a09e841cb00b2ac34573b342d4722eaf837091d6b4220e1263290f006c2500534ca478a29504aecda8bc7e1090fd63d81a9815af311f338f49bffae5f206385e2bd2ab9d6ccea77fb1b1263ecb428dda194dd756b5fb13ce1ae19532d41669cca28711eb44c86718bfae91a382a1e8ca4e1e502e8686533c04aa4734cc189df5c12594c96eee18d21706858c350a3129a873f7c936755e8ab373a35d90b2ef271673359fba688050318a9644a66737e2b66603097e4005e783656d71eab1b5c79c7dd21453cecaf9e417534333e3c4953dec02c44da472495a0086e29a017e0c5fbdfaee1948d5e4ead29c78c52eaf14fafdf09ec09c7a53a6a8773cae0be90d2b75c3be34dc3c36b6df59dc148c0163f3480746fa027a32c953d04996d1c8beaa2fed6c835c9a56675d1f2a24e731d8cdfc809f20744cc0c56fb7e0139769bd057ae106d0487954bbe51579cc42b303df1f07e42ca58a41714cac5d669e43457c7c387d3fc83975088198b395fd3b4965c42c7b0d20e2d5b231d03ac30961d6b9fa1d12e73b7078799f8412ca3021b4045e3a6b34c976b281e327155f67e5d76489d4243eba0150d3fc9af300926debb7d394b6b121adcbc2a2351465ad06b497059430d46f970d0475cf3c8d605c16094316cdb2c6f7f6a6141f4d5ae01ea3f476502bb9fa2bc04fef37625d89614c480a3732cb6643b984549bf623d33b5ba9fd50a77e8f86edbbc83316810b0ce86f4cd2170aeb9d611ec3d8c718a83c7a20b79dde15dadb7530ded64d4b5dcf38fce242582329f9d6b2d70e7f78add99abfe700b3c0741d6ccd0cb5a8a5e913724fc3a89ba16547d2b3ee0c48e36c1a5dda14e740b8955e03debb344bfccb25c1888524de63c6804b546c419fecb95ea41ae7324275ace92a99695afd356abf5c32d432ae104654a61ceae1cb409c5ec0c6e13a513ea6e67de8101046365b749c25d29e4fb1e193c224dc03ec48d9aad7d9687478395062766f1964e7f75243c98db05269174f145149f816113382d8bf337d028b2ed03b98449e48f1c28f3dd3669d9c17a8a27fcd18d28abdbd3a5057f054a8746ee9fa172a9467a1e7941aefa9f38790b2878f2b85c4ac240b06d9019761ce37d8782db30fc6a6ed3094223a3b96efd290ccd85702a4ecb8dfe069aeee384281f705c1a1710fe9060439b05df3c3f7673f38b24fbb9cccb87ad2e5dc84a75dc77f2bb03a4bb700ffa82a017d09b48e6e1373015469c09357e0894aa22d3a0eb5ecfb078acb222d004e8e1b3f46652b419bedf149815b8cd143402f70220a76046c1c3cdfc8b28ed911a6ce754c718c20fed989007d07389648f2e4f85aad282f0ec26cfd5afdd8478320cdea21884a44e618d514eded2d18e5f51b7c7cbbbeac558751ea844d937d7f1c7664dd10408aa2b23bf87dc57f8f4cb64f04bb2108e6899ef2f7b2e449f3e429669dbd69c5ff705ec8d616781a512a602469f1880c6ac596237d602ce35fdc4d9021269a97fb8074c890fd117dbc587d5ac360906cc07f799d3f17abdd6496cc8a9ebaf5b8c2231097ceef6409e63f2a25cbe306f79b00ea9bab38bfaa9bae97b2a14f6a50fb2156c9331c6dfd2950524d1c0108dcf44aba1002ea6a1ea530eab216c731131b482f52ea75415fe8eabf4f11ada7036dd8081523a17b6010b5ea8ef0795bddeac1e7f42d710371f00d881eecc0d7e8e0900f02927764ca33070ebd12a841d6d3495b380a2fbc346423cc4b11a2fa1021bf567c3a8e3e9ac87f02cc16098bea6ede1074c527dadc29a80ed57ce3eb684659039462ceef603a9ec1dfcbc26832f5e3a27c3b7b8e02b297e8881d9a528a02d01fed9b3c1f8792a5f0570c8e261a5a29713bda9bc0fa4c9b5af332d0bc0988a883f9f1dd4b1e0238b7aa34aaee15f23a90849e7be6af8919888128abd00afa80e839852b88bfa0298f878e0a62a39af6140ea1cda4d37c8baabaf07498239a04deeeb59b8b7f8e43fac96c7e3e11ac7d6fb613d26643189e8c068cba9ac075ffbfd3ffefa4c8f26eb34bc914384b07aba06eb957a21a02402ec0b4ca122d3d00de6c16bd64b04d98ada1ca2c71bf3fda34c0cb603558337619a531f4e786224777da08fe0e54e083ea0f6a48c019fcce2edc4732b16aa203c2dc77eb7ff6b7047b524dd9bdb88b01fab841b4c3cad0ce22e7c8870d31bce93967f09583e635de14fbb8a10fe95aa6101dbc5c4c3b1a7a2722cee3b0e94bdf39ee8dd9608e6e22e92c6e2262907f72f0a5a2b7af8908ea9aa924e41d13cbba7cf1ed1841aec16051a2faed66cf96713f9b05e502dcc5722485ac11dbc3889a08112c5f6b8e72dd57905ecf8891d98ff4fa615b4fca0fe93f56a21e7831d0a3eb363d5ea20b2120942b434bf4c3586b3924d375442c59411d8f91790a16ba8f2bf8322b8631628b3cb201b08dc02eb2f54fc6721cb2beb47ff5f62d01ad019177dcf94bde373d58991cad74b0b37db45e97f03765eb7f06e8641305519801e46dd422aff8c65dd78ce8dc2ae80552e658876613ae24e1e082943fc6ec1f53ebf60bf8acde3e5f9ccba39f2e443c190286bb4b526e5fc38c69be2abd470f15e3505e9f9446dab80712ef019abbfdc16a3d5b818225313471c0b45314fd9706126bc85c3bae0b9f7aecfc80c7ab898fb4456797e9a748e94dd08ceff58f18441e8bd41df47a7022239ffacad6a79325f9421d08f4c81c621fdee3bd9185c78f1768aae42f9d6e74c5d4b33fe454a754ccbd5feae7efb687004e569d79af6cc538eda04341dcdc4c140e22ac17b5270cd37b712b6195f3c0c6c299984e78aaf3be5d8dbd785e18b0b58de4ec46038d545227615983a5ba217ab7a0d400b1624d9fa254b7d8e092f06646c9ea557de72b8dcecda8267603759dc58a7ee097566048cfa4580f790b0e9c2a8de1fc05b48ffaa20600a10388a77d44b4829569202fbe10e6e54dc0d4c39642b6b0f3253ef7dc764c896d897a0ac5ce077d7f2aecb22416ec44e3fcae0cf99f77ecf9e3aa85eb7a50a1bc5a279c40a45cd0732a99fa967fc870cde5cd9865a89362bd5af786349e737b70fe5c54f52bfdf90f829a78072007880b2df682906e611ddbab939104299c0bb78c182642f8909a93e58d3d56002a9242259e0a06a674af7854203f2ff8c55b8f3c911a140630ba6832e7ced3799fa6e2e4f7cb6b2efc26327e028aeb52865b8328bf2745145bd868b7b5fe7bb1c03bda037be8b13faaa9c9da5db6fcf055e7f0fd59ddf66006a1e2b33a815bfc0d1ee7df62545f359ae0a07e001ac56b59a019674b2e0edaf2567a35abb0b40c612f65c21af620c1a8783a09cda88c01c908f688c893cc0e90f70bafdb3a80c7dbfcc574e0a0eefa05637be9d9cfc8856527a829b0207d17ad486c881e0c8074e8e807734523d403e0c4e7dc0a0bb3eb84aaf01df34d2c00069a8d3646224a7f4bce96804ca74d02069812c538bc4772b01b63d1895fb7e7a0771ca22e6efa73d2516251da333310f095608b9b9c9a0f8d8b808268e3d710218289a1293df318ba543521561fb57ccd98eef73e7565c362319d07b57a5c67df699719a4ab70e51235c18d59dcc014df08b1d75653369dc16b7102f4cb534fa828efaef19eec0df9f10389cbb233c06631ff5eb4e25547b21bc5d25e09aefc978e98a5af91dd5a748431d774b0a1d38423d271da3a9e1731f858cfbb6286c152241a667b723024f135d2a9436a035c5633b420f38175f6ecffe8ad869a56c14c78f89712fd35c5357f71bfbdac3104642b5a62f134e7fc8e9f047dd925b4d0e9a709172ca6cd3c344dccf0b5d17f7f882e2b5c81c570bf855cda92d1d97bfe2f103ee264332660fa57807a58f9ab6530c7b6b984bbc3a7daacce621642513e85f37dbcd421e6adf5ae764b9b64c2fdc47187192c68f16f615ca7edf987d117739dc7920de9d2b7f917034b37444f488161133bcb609a6b586cb32d41817cb502f42c96ef625ef6ba7045cb4c8d1c10f8cee86805e63056848534e04b01889d5e7614c1c1d87f9194044906db2bbbcc96d88cbcac930bb02a56de121a107b51eb67c86d66db7b59879ed79faf887449a34573f4bd38525acd4a355852e0e6328aeff41343a7bd285a9515cccf7d27636e3a0f0e755eee1bf5d4c8a716e9212a7d36bd7250d6255d7868f75ceb2510d8a36a14d2abf7abc0bcf2e33585cc2bff3784b890f78fea584dbd84d886ceb93d8a1cf6829147f22daa19d85d5a006e01753f484a99461619a567f1729f286b51e8d3d4205be768d22ca07375905853e5cb8c5a4b3532625f0bb4a1563df02ad233fe0f1e3e88a791ec4e0c07e1d621a9f052c963aa6dde02df6722649340088c26c83ebeb53c49473d0822443767526aa422afce8852fac6080dd90ed81b0290d3f1d8b8e141ac258c26dc469736855636f63e0f251fa4184678bb039ce0aaf5247a5aec47d93d17344b0d701a1168df0926e7551c847111ea00f37ec79d0ab674b5c01a2762198df803b0998561ff956a8114ddeac273b53c808c5774c632e26a1344608e71cd720d901db9334eb6e36e4c27773d9cd0a40de072cf3bd71afef9b1bff0d01737a8dab3ef9dc8cfc89956dd50e5eea663b7e266ff042b22ce2add235ea5628469ad7b50eb988cf020d80fddf977df93f1031f74994cdb4d88c3310197406d0fc1379e3b91421596465040bd500e275b5ef1f77b4bb105afc2c4684e0c6d6abf6227f48e8057c184bf7313933141581e95489902f6f0ea86c643d9ba018febc98694093300f851d8ff52817f69c805c1fe3535bd9ddbbfc400e3c217543950a5c3bc99838e114fd55ea9200b228bac4e9d20d87c15564f00d143d1e00a45954053da15242bfdef7ca2cd69ff60fea8896ff9a4616d6ae84d9408ab8733a87a5e3d642e6bc92e16ef57243a359e83c51d5adf6cf5f51636c9fa8ecac699b2ce78669db8ebe04f43f38bb53adfece5ef666251bd4795bd689716086815ef76c0d8d228343c097efdd4632555de08c69e98e2f91738776ef88d203adf3552b503fd4381385f9f7e7340bc8381da712fb952709199bf570b45069903c77dcb608526e8882724dd1a459affae4d999a1267be00a1f2042ddd899a028be5331860f9b39d001ff509e243d9e636346ad4189c4fd9351d06d4ba128c1c4e91df7f96fd71859cd07c8d378927d0d1040a31184a141722cf8e96d72cadbec660c178944a7106cc3a1b97c824c741f33d137503c1e55575d538db5032717969c7fdcf89d5faa692fe9016f1c7b7477185a06ec6ed03a660b36ec115825628b22f8621fe895c04e36d6f97fb523295d70a2eb1ec2a1c5f8ec2fe9dcad70094b63b890b05bcd173407f092dc8373f25c1420ccde3bc5084c70d5eaf2b2b1995745e4cfec75fa6b882fd09c31e5d36e2a57056efa4d475bc18f007891f83337fd5a9cf262daefb57e56d830562622265b29067fcc42e64867fc71501cfad996841e60f10244b41ee01622fbdbc5615050b9be2b08b4fd7e4f6c06227f720a8d02c410595ffe8cc4aed707f022ecf917284a8d3e871c50cef30328f69c5c526138b14298070215994634fef1cc2213713e90bcda24767b84172513f066652b9074f34a0499a6cd0365769c1a3ff5fa10b3380c970adead64306c51cbfc2d4c44c8c6f2776028b49f11718466c3861e40cfc49a1860067629f36d52fcf1cb222958c8c65269a947067662bf24082adf5d0f3fd9d34938be4e22e1ecb8453df2dfdd0f81c3c52ef28270c1b08feada6f9ec6ddc177b2f24b515021dd74df595bcc35a7aa154bf6e770161d2969a54bee6c3dca42d7cc444372da1542581e840c4c729259e51fb6e753fea441b6c4197cc6d4d57d3b491d68e8e4ad2a8f4d10f99b930a28695aa80c109982d1540289cca45f7267699ac0ccdf594598d370b185a117ac3afa9764d9525b550d12dc6f2143d41137b21f1ed0b31fc430d934ea2a938fdd60ee85c742645f24c6770e3448b59e7344b6a561afc7a76fc1a2efa8da16fd3601b9a6843fc83990156f6746e81836fda5fadef4c52eb54da10792a8e6048592d0b5f7cabe31963ef48b4f0c68b0c4b6a729de7030fc0596904f1b0e25419a225f407768e8253a989fd4306fd71001408f80beb6d3e7bc30755cf9ed10f0a515cb8dac5d4a0939ae50fd5e7fbf71e0fff878bc88e040a46f7c47439f9dc6e9e8430572da2d4efebdbcb59a7df4473e9c6015a84b742c519a8b5b9933a58135dab4d0feea5f0efa413d57737b3dba0de981dfdf23aa51e08db8aa24a7d68ad2caa1283134045f444ce97473271c76572c90aff2b4f10d006149818047cf2a900ef0ef34a6406e1bb9f5e438040a6c27e2ec197c2357c8cec32e231abb48b20407994403688940c4b8d6a0f8470ad695d24aa00c083992857a00d5889d73265894a0307bbc546ba01bf17feb60e2dcf4123a721da5d59f5a47e0d08d949d19d20c5ac7d694b6417916501c89fb0518b0c5ab0be8b3d8f60f15eaadb2a65511273255853cce06e7616db6dc48e79c06e63492d5243690d52ec79a66a0f1ac65d5ea2737b324c0a8a1c72a12768e406d54f8fb5419387a270c6627bab9f3f1cb00774e639333d696ebf6666699a574a283270d17d05d68c8e2eca900eb5e72a7d0e6dbb5a7b23d4c2e99ed7808131b5b04cfa281fc0d38cc5677e55fa3eac13ba2b325f887698d59029138dd3afcec9f950c6578e573973e04e6302a33c7a0a0d10544ea43d5f7eb5b5badbeaf63d4fc2d636e19aecc54ec6a12048226a878b66ff7e35c114c438c0423982df94ada9f80506e3aafa4f90eee5220030d15b746d0ab45b37ed63bda7c0e7241a84a46d79a6c5bbffac788e9119845b83364aabd5e2c1fbb8909f23ffa56001db509ffa3ca57da35c7ccb14d1ad21f89c1735a016407d60518c5b6bbce4e79dadd126ae0f883d80723f9e2e8ccd75990b80529c04ff568059b527b5c82cbb2c14851e7b252464cde9531eddd886ba096c8a904b516ea01f06f80e682234a1071722cffcff7dfafefaa73b2431b31e88271bb7cb93a596e48470ef32d4bfa7486d904fdd7babd89e1756b850ba6318c68f05ef45c6b92ceb47833f2f81950a19ff39c0f1042be5a442ba6fdb738580713b0058618b4685e081a32c8208eed57d50fd0bf271d721eb5a0bec1e753066be82714a0b93aecbb729d0df8ea368741ebec11781c067a6d48821822b370186b2e1e6c20e7b2c4b0e55e7d6e1211a3fd6fa81adfd3a7fd114cee79fd75c7aea2dd2e2aa87632840b2c75d13a4631a87d73c7fed14ebc9f4f604d22c1408ff7d27504fe68e4d0e8860daff1b9cfcecb29a425a63e004b454deceaf5f6e94b49fc775400f1ae021c6b582774c18d280c7cf6732e455798c1f719a3c42e6adf011716a38deb6ca293a57a1d4a51f9412851db92d054f22edb91dfd62e6b52be3a64f92521238d6393565a46cf0fac72f38a3cdc2b60a6ebb3eff89b1b5db544941b46cf64d68ff555c8653cb86ba6753b3e3e87bfcf62aa140be722bc452cec56fc8647d8b01edc7071ba5a04aeb598a2eb5067dc4c375cc81f553a11d586f9bed470db9916d6431708ef4f3f162549b0d8192f36159f20235cad552e822d6f27fb9ca14b1bab94dee7cf81be67aaf913eff0e512b7904afe179466adf109bd74bc0c105251b91557f050b13ed4185b69292a9131b03298da5dfeffdd8be5dda7f65f838d0b6fec298c8c445dfe6421afffc3ab88207974af4deac3c9805243cbe41a85cecba93f8ab6d2ee0a7cf30b091fc739fb7850d190a7289a0c297207f87b159a0561d55400fc6de42bc18db19b0673d45d1fde93d6ad557011883186c0c99f01439e51a213fea6958e784b5d7a89b74a64910c758a38425b9b9e6891c32665313b825909ce7c5cc3498b061edb562b8da00b0d94e3112051023c63848087e41cb9e9d5ef30e6dc1c772c730e92c36a00fb5a76f3184113b3aa680459b4e4ecb6575644e27144f46c93e9c2bb359428dd05fac819963db353defac9ba605f6506ebdadf953895a60f23cf55c2ada02c20c16f4887385383602b23aa16a6b75940d19b404bbd5a2058905cc34b70dadc14519a119bbcabd533f47de6f4756944966a96aac379460aa55231692cbbbba35606d037561a4769f19962d01dd2de5ff4b17dfbc4a04cb20ec7e3ebcb0d8326e0d77e9bfb3ec0b17dec52dc2de60b47c1ec360e0162ddfc82018b50962a7a7efb97cc038347646b2ef453c6af4a9d3b7c9e0df8a5d9018dafeafae65d8b6022d0400ea512bb80f3a3dff9dbddd909c792d289fffd196ffcc3fdc3ed4597e182b1cacc9eeb6de434545066cbdb5fcfdf0b28205170da8032a104199b5451e6a65ea15c6898e681531dd096741dc3546f6fcac4cce11c429574065544d085c2bbc02807993f386b6060ee0b56caafba312fed026f524ceadfc55490d8f41160fb4ed3d702359b320c0ca62944a833e344a8d24079ade725b853b3ac979023504cda981810cfcd6b230540da59783ee0cd4cdd773c16b1aa68f52bccf825fc6bf701c73b73522efe067ae4762dfbaf4b6823c6cd7d522a9b84b597283cfe5ba748c42c1cf9227d8a28d37be1843c54e91e2a7fc5cbce2f689a1b79a4d88898f8afd619ee6883752eee43233b12570db76eb9fb8791bee3ff20c7b5e77fde9c64bd8e8c3146850cf0bb81d74f72ac26303a866811da35388113158a891cc2ed6746a5581aa163ba9c736031e37b54bfb6ff00b424e50102554109567aa16b814cb4ee905800c820287c1512bb241da79cb4f5eb276579a83746181a071f6215b3bcdc90cd057e17fb06e43e19d92ed01df4101d43306b60b4aabaf073e4d10a7844c0d47ccaa06b30fd437488921521de8d354da6d2af9ff5873e4ab190cdc9445e4d629b5bd56d866a7d292256d51804be07f35c336a2a53910aeb12ee3ca68221e00d3909a87a0cf76a55d4140d9c5701eaeb7d05c2475610268207ad0d674f56db3eb62d8e89d800655150174b8a4cf6c747124dc15c9798e5ba0dd62a04e8e67b82f7c950dbf8af6aa9197382704a911aff2e458ab934fd7fda4a5620dc02185e972c93cb2b8a8a8317fdef0a9e7ee03f1babaca7760a941114f43c96ea71bc00f532a6dd63fb497aa8a4421c63eac8ca722f636a27cbbf94ac3a81f000ceb3b97864acd43c2f07fcd2b55c30507b2ef1481f6387c33b5902175de5b8baca2be6f900af631c26ae1c93ad9404691d337188555b4aaf9a70820e53ee9caf1b2f284f62908287bc1abdb7d55357006326a6177890a79642b0a270e94cd629d65e0a1eed0e8d340e901c3d720bdc3a28f01a1876e26db30e0d0323111c7f8b0bfdda65e88a6da16b9af2938582a1a16e9f8eb054a01a50ecf05b2dc5a7619aa6249d865974dfa1f2c69c5524029eb3a05ff382b2573c30077485397975a9e6bfa649a4a8072b7ec42349991b30328d330c6e111aac471c664210ca01ca57db6ceb3b01d9c3196140459b42f70df7bd24d1bac7a753c014e3a407df854e157e11b833c19e613ab7e7da017e16c1ac9bb1df67236ab56c013f48504c3b2dd19931384cc055fddbe83351d074af7da1119538b4332be2ba8406ac94c7cbb2c7e98cb68f08265d17f94244c0dd88c957bc58cecd1313bc1e0f1e3b2361381f1b58920d6618890860db7a321c8724c41d826facc5c56f9705b41d3efda5fbe0f7ca3bdb93099250e495136d2f8211b88202684749f86f3d26820c6c7b0c367a1ca3dbfb31f80986b1c3389b4872593d31a84e6a25b131091974764e01452fb5270637e41bfcc5aaba6632e164e68a2811ec5d17f6b94cd79128a9512b3f2f7dff1f18132dc540b36f1f2ce798daff58ef873e1209e6e2ff9821f26101241e8f47ba58c52875d6ca85dcbd1b72238b540bc0a9c4c41ff33868aa0822c70a8870b08cb5d80914ef160a3378da4c388d1a7335363806bbaf1b0e9cd689327dddfdb327b894b091457748d3dc30e605d63abb2ab27606473b94801791e3d9d0692782546ec582337c490fe09943d3e99e46371c1f788810f32b94acdda5936304a585b3d8ebe64092d1b8f6249989785cf13c6ea70bbd94eba8f281e38bd796c424dbda62fd2f9801690e16b6ccd9b3ff9ae9897b245294ccb71f25effbe4f0256d3f514e532794e792e0fcd5b017a4a02e68b86b0d22a169a1d42b7e20da054ba4f8c4d65fb330f729231de9a258a44895c2f926e4b9b4d16befbb2ff1ae9147cafebbe32523788f504bdc1f95b9f0a5e87423867d9e2e3ee6a44211021d46db7cececa656ddf6338ea0c77719217f192881d7cec3f3a26eef04cf2b1937900bb38f79f45bc95777bbc11636232d8e198a9330be3ec4b4677afd2342b98a22d6285279b49b2f6372f259f84fc38536f3900a4d63351744894b4ae9825da6ef650e1dbde149230482f64abc1250aa1c51c4c304db7323de36c3e6a78de0a5fa496246ecefb657edd048221be03d15baec12e72e34a1727947a66acd961c35368361717ecf9177ea0f15bf4eeb7c60aa1a5baf6e1b4a2445842cc3f8b2078b62df2424e59ac2773075a749661cf085119f8a0d997c8ba1efd3b84aa090b4aeddc42c730500d295c1462e993c7c63b338402843a307e16b2409a6b4bab98505dcd4e53ce1b339ae071f938aacf44853dd9b66c17d5a85e81baead308543ee1e8a1b64badc316b1a0b250d36b5a8c992c45379fda70f3dac5382b687f470b91640b2aebc55cd681f9f24df4b9da3303a61fdb1fbfb1efb93f38193c6d08b48d0946a2a7190202d08b7f65eb7fdd1567da5541540bec7314a250e10a1b2d4b476cccb05764acd82858c857392f532b8eb1de95a82c9df013709342ece1a1371c210791ac5b45b70e0c3f0cd0ba6048e413dc458b593450e32c63edce10ac9ef21ad1b4dc825c1510c4aa3278bea3e8bf7b9893dc9fcdeb4a510b65679f608db85940bad7071b7f83bfcb61d08b211e05b255e8b022ee90812189a69873934cf8e94f469cfc7a7488d51132ab8ae55d90bff0d5f9370ea6dd847c4f2d4d54c8fb6825004dbc32d869a056e9cf3cf3d1e0967579520e3eac734eb2621576dd5ab1ceb9fbaedcb225468fd3df2b473abc7578dcc33786773c1da1ebfe2d2108018ae2f93d957f72016bd2fa30eb64c9b3b9df3046edb284a9e86523040beca619afbfa1fe873c786c0f4d1afbc71928f58fbd1bd3ee2f1ee929a5181c64fc24a351d58b5567b4cfbf0228ec373f0a15834f66191bb7ec622ba406f58ae6ce5637e79d7bc83c632350845dcb8fa14241ea1988f0c41ac20ed17d3ab20e5b721737417532e98891c164717f0ffa66b1f8473f8bb8a6d5d2933cf26b46420f794acdd8e904e22fa4cdb530d8c43be850c85ec143b21c3a6faa21bd41078a8e509e9fa09fc48d5747f37652790bc6f29b60adc9f0faebe7ccc21a69670c58023355c4da98852a2f9ed027db7ca2012bc6021ca6b6fea003423405a3c3330803e7f0debfdd0e7a568ea4e9ae51e930dda296f42ff213df04fd1a5420e567125d4f27dbe5adfc67f4e8544f78a1fc3c78507e5292bb970d1be158484d394607000656bcb5f27a830ff7cc4fdce386ab7ad67147cbc66fd57d56a909c3e850a4adbe8192bd1567310673579364780f5d7da7a17dd2ad247b35580961ee44d288d14f72c84167204f455490aa47a39f955b56be55068365f87bf1307b3fab238801fb59ca41283ad2c16f85ced17dec48590f925ee84396ce2ad70ac400381ca959ff1f4129840a932daab92112788bff75cbcf97abe50844bc4166fbe97b7922617b5dd81a91b9c0a8f46823cb168a75b5eb9aaac37e6260fc40fa3afaefaa5bce19e43d1575e4a0f9d332a29f123aab1a590182d7dc1c5624de05d4508acee1bf9ee36d6a33f3385f347f4a885be7b31e0d4a6bc8249a1641eb43f1c1e6994a2ea3b16eebdec04acde26a27d6aa9d7d0339968e7c8721729d85537e38118519fae8a41c965b23c0b7f5c65a38ef79dbef49cd8f975dc7f87759560ecbcc4026540d90a142e953e571f25927fffde1891b22e3c07c1861cf1f37759230586b499a8f4fe2fa31f5645eedf1841ba6527a492c42d6484b25b7e0c2dc4bea2a70e13459c34274e33def0535ff417a851539ee782ac5db3621073d814cb7acaadf1834c73bb36801f802b4b96acbfa4c5004fe59d2bd32a24576cda0f33b41fdce3ab5eeac4c47c8419b501e22c94532c1899f50743a4adb682ceced311479af705b43f718e08946112c486232f6de6ec16569d1da3ed57174bf973035b52fd4d780b3262a732c1001c35faedf21a1d691354bc3662ee43d9453e5d393070d32b7c62b9f14e0ffb845a6d0e1eb2618d2e1b91d20c36d601620d4c64fff067b9c54891e30824e5f77c1944e8eee66d624d69e5465d667c326a9a8ba9a2a3919ca3bcf9afa0d70300337a9a109c3b77e52e07420b161cb735f8a55dc7c695ac5cb8a2bcea0365560c74f8160b10e879693db13a131f9cb6094a16b4076ba397c4bdcbc011189a6dd73dc7e9483a42ddea5ac11a7b3c0aa9655150eba55a3ba56aba086b51585b9037283c6b65955417cc8a6b514fbce1da452ed2aa0a83fc019c85ce05de6900191589ed772623ad73283a92fbb9b07299c89dca21d452b6537a695a55b286fdfa2e37eb4dda913c7cdc96d8042659533c9707a72ddf0bdd652722739402817887bb96cd8ea77fedf9da12e51aeb58e837b41002d4b7f563ae1f07f355dca70179e36cc41e55f0fde64a823708ae088a69694d4cb5db5f756a26f21b99cd56fa04ed050dde746f06162869244a8605d766074d590e3b5d350f06b68d731be29532bd24979080d78aac31c207fe53614a9e74cb36e5f8b2e5a41bbfbe0783004c77a0a649e1ccdab450f1544688da6ddb016d10a819c2793158997924ecef636c34c36427c29f0648423a59aa0ba9860594c1629f69a5039731c898fda902e17f5ce62e541b56a84c6917cacf72cc67a137ff34927c58ff84b6c8584c68141b6d3fd3a7ab403ecbdd08dc1ca63d9ddb8c2de8e7a9fb6f625140dd123707110a326227ccbc7842bfd5aa9ed027fc155a2ef8da030a6386b3312270f548eefc6c88eb20f5c46663795dd9631dbfe45575d5fa9035af6546b47d679b02036cc01881feaaf032c5b23241b675b41801d8b37be5a8961849b9f56c79e0bda89d700f529926fa3eab15f7351ab8d67a5fae2f6a71630667ced0ad0f9d5a754ef5ec8045c8dc438aefe8c0795557b2db4a93ae0b410281acd793a37b0d66697e15c1ad2f244d537a554bf36d53e160aa8ee9a77eb2053a3ea6ef5d435bcaa77ea8c29e9a373862d17038b3f41b7e342cee7b9e180ce21ee0dbd5838e7e989153353138d77d4903631410ffb91777db7f5b9bebd5d66aec6594aae2ef16fbadf63cd0ed9af01dc57b02ed7f489ab03d5e2eba8caf5d04d511840dce48355be0da1c8c5f65caeb8149a6acb1b59b50a4d8903868729d148e8d4274d7e91cb16b59e82ab10c8c3d714f4f54926c3ac55eb97b72d4ba78b72815187fcebef017dbeeed57b062df85b7df8f28348760806fea24f8c1600b6e5c9ad7e17e32cff29d42cfcaec2457f856ab7f30cd1ae01d321914ab0733a8921566407954b9fba629c0448a6ccf3187fa62750b70c07d89db7702be336f1001b33360acc7a05f2cc374a4f70ad15ff34c52ded921bb5599e5b86ebbb1e41b3117c465946caabcd25666fd1d7edf75c0706e2ab513775f8c8a238c49eb3b0e9c6ae3aba42f60094b7c7cc8ec07834d272dd997f7f44183bab7f6f5178e20479b7216729750a18ebf5677e9a1319e0b0a1c22d9fe55adc259ffaaba8f34f3b131e006b8ffbf47e82d244a6804293a9139147953c8171e7b0be689c35ff633e54ac95e6719ea7ea5cfeaad03f31c63a8dfbe06578c1abc8569ce1f9a00d1ef61d165e0d3e3b347a0ce03d44f4335074d86ad6e6a40f692d9415a01dc76a88ebc9030d41118f33be2ac3146de9345858c0d06ae288f2a7b7ac75eef79d35c84d1a3fd42b5cb7faf16a2a9eab9dcb33059ab867ac513bca348e091af38ee6ed54de90dcac28c86168038b5f599e713240bda2c40402984ace1410fd9c8d4e8fc31570865c574290a98f5768761ed68258807aae184709bfa986db86fa690129e9305a74e884df6c5cd5b45bfdbcca3aa3dea13b9b8e982e1805d21044a969a370889cced618bb32ca38ee18efeab32246355104e21a51ade50290b3206c8cb419c844ea497bff09863dc0adb8f5c3a025dec5e51ea3eec5f3ab824a5955cf590db9a875f9dbb52e735b634d8cfe5f28615474c354f346a0bbc22ab5dae87da94742ea3e7bd28a3aa8f7b0cb9cba91401092aa77b608d3518b2b04a7f1e93e065be6ae931a0e7a6eceb93ea78e57788bfb59d3b2b45ddb286a513fd0a48103ce416d08dd331f771526473435079441ca0a060e40f393b4b3fe77e16b8d6bc1c94b0800756e852bc0ddffa73e8c897dfd3c332ba21c507aed811da3d0be39ff6597a0fe50135a74eddcb7c4f68c863cb1837e4a208af34d561e0d84a7a45fe854b961d0fb1492db9862ac80f5ee5eccac19583283524049dc578b0b8284daec6181e1d4b308b1500584e5ec0504563a1de8fc00ef25a685101547a2aff6ab62886ab5811f4fb00e2005dffd74a21dfbb8debd16188c701514c472d12ca0a93d5e1f575d02cbb6520077f997465f797a2527d4c6dd28f1d1e98419c45d76b78f2af5df5ed4ba5de31127e4f1056f075a72f716d77e2a8d3201b1dacb59d22a61ece1ffd3e3d8e1b87e08fc7890b850fadf1334853acd03b1feb2f824fbc771c050494fee381c7542730b597b5eca41af19d4f9b43c22cee22cb27ed6ae5e0606f772ff849918b7de30b08a57bf21a1b89dcaf66c999507d032610e45d5094d913e842a98144744ccfaca195bcf61b96f9a5b751ca651d0a4af77e835c3e09e0efaf6665efda482573842bfe235b0ea00437d914d93277f0d76c0c97a5fed00b014560b27cbaf94e8e2b343d8869d771c9baaa7963a4f769ec11ae617228b5fedf936d75b7fb9cfda1fd0228a066cddcfde670fef4749f7f3b5ca0133893db5839bb2f69c9cc42d0d9854259c05e179f466ca8f15d9ac52a0401c5d4dbfd1606268457b7af377bdef8524079ed339e267ae1a65478999821828a6fa57108ca3a780a382a55b0558c3136e3bd3fe451731eed7e855d713aab78e9ebec43e6310ea79c7a10ccd187c86d35e9deb96c5adb4826783d21840e3c36048b3f2f96ccef819d125ab0ea24d9807d0535f1c855753cfa7def4a2863a8be3d3d40cac6055abf27b738bdfdba734f729ddb8f894429c05ee3efe25bd1d030a8d5a8e78e0edabb5d667b9d2c5331727cf167c6d5058747388a59844f0157ca85c4730251dfe464324010691bf767e287b21337a01133f1230cfbbac12d43bb40967f3775306b13e6e4fd7097b8694287d46f1a8671fa20cf33d51665f89de15cd6b8d4362574c690ba57187839447c95f69f5120e51e4d95efb0760bfd2c4c8991e1a4a8c0b79d1d614ca444c928a56675ecdaa31aa90931451a4ea464984691d322041bd05ebc8635900f4447809e503a112068034374f2dd364e16a95b85ce610786446efa473d9a0e350be60208cce974a09bb991a6406227c92711c01c1106ceec16c7ef1b218d0285bfb34af34d7b8253083eecc5360a820daa4237e441f071fc464fefd4b27edb0f480ef192ae587fa99a805045574ad5a0dc5149808549b6bb7d73852040dce7cbf0ed5f0721bbdc5824f56bf3875bd756c258d104e1f36f94b1364aa26a2e49ce0a11c1fb9d5e8dcb886abe4f0f9d1f27c0716ed71b1342b3348a599e422f56858ed5a87093683a82fe03022a95e4aad209fcd48eb1059091fa0744853cd044e69ba6c29f460e9f4d8af0a10b7fafb4f5c9c70aaae6f688925618bbc27d09cad29bbd93c37dcf6a3c9ceb309efdd0dd21e25a83645fbbfb2b87a7e93407e31264f89f6af4ed3e4022f4640961cf9d098b56fcb129cf4971dc3b9b8fc70eccca2ef332252979afac760e20af6cf26c6d09b54b42290f17ff4a9eec01dab5aa5d463b5c55573b9c7290ee33b953cc781fe99c81154fbe121e5e66f1750d326827c263ea3a9681e5dc0256d2a52975d400fece0314c8335a32e59980537ba80cf416b433dd6b9df0314bebb17446d0646c629235c5c6393d1b0d157094a1cee84bb1aa393074dbe4f16852fbae8a09db910af7a3bd2adccfeaf013d98587c51c78e96653539b62d4c636398491758c1746ff273716d7e0d78e63aea748bf9a48237a589d9baffe2fb64244480a4014e341c969d8fe6077cff35c998149cea5bd1706c6cfc2de6531ad1aa84ecddc68ae1c37360b95ce355293b8295b9c804f72c761f3b57ef2471fc2e183e90d14afdc70c9ef4e98e0b46643596e995263606c3867f45daee83114e74e50c3149d69fc933c0ed990789aa0b71f54b1c5a01a8afca063e29f4152054595a21e101d395a491ee8c6d9bf1d91eae4913a09d90910ac0513b10b0fc6513e17f96584c7d9cfa6bc86ab1ed366df18e1b4abc30d0efe08f1d3680096bf9b376ff81c43d04dd4cc802601329b3b26b435d2ec04c12fe278c66d20979941b91ab1ac55ace047b55014c0ede4ee29d0d99086c2821556f4a91179d56cd5ec1feaf0054a9fc0ce0af4ec6c917f156a639d91629985b13542d569483751a3cc134e22d614e84dd2049aab3ec31297a79acfdd5b2e77fc3b287baccee5157fcdaa1a2cdd6614f9db583b6abd06e90d50885a23489e7a9857472fefc7a5c475352a3aa08ad5d2d18845d8f0cb2f8859f2d758f0f67af6116888b3c5ade1e2ee78ced3e5f0bfe25940940b99e7bf1e45fb87f843462f3fbb7dfd8eda26c8af81b4b4ac7160a2e7f887edaef3a81912b5cd859c81e11946c72f6ffd0168437131f03a5340e714066e67f66b2ab2f55ed676e84fb27ba9428905ced0a5f7a119ace3a840a9c9af0d903e399ca912505c12cc4f3e6cdaba7e11bbb3135b4b7e36677fd6859830084d8c4b0e74ccd02d03157c021dfd255ff3537e405e3f1d0fe836c2f1cb4deebb392cc02e6d4c05c2dd910d0ffd18e42f674647bf1440f5166266f5d52be6fd9539fc52d487b82459e73b5e0ca251216d76c69e0fb4c4019e9b4a501ccb53158a967955c81eeece059a5b0207fc28eda87de2470627f8af7185a818b9893a24c81f3920a25e196d668589492cc434bde85ba8926c5fcb23c57f3d301937d59731a0a3d2008c28a5324098b2bbd263c0f9a1074fdabe4a85121b72a74d0b1314385c757be1a86b50537998f3efb14999ab9c69afd4fad3badc61eed9499025a69283ac0bb55bdea481d09ad2569bde73c6f6927e76035ee3a7f80c49cde86b0cff1bdd4cd575391b271755e2eb54e6191c58bfec1961029f178aa74497bfdb42aa6e59bc16d58c95073ac95842b62b46fdcbc309d9ee4b424dcaa48bb17c5dc6240e5b6a2ef2c3dba724a79f4ef1490a8797fad94073897f428eb08cc76b86a6bfd465a694e3d7c33fd9efd540e9c72d2ca80743774e246d1c8d47e55be6853f5ae0029283a522f46f93fdac991513ff38b7471c802023738a479ebd9d38e638da04d557dfa8cd4573f8a3b2a13c19e6baf482e8d9bd0885a58cfbe4dc53c107ac456ecd7a087b3bea4276d52a1479441a00505c66377d6fe693682738494b3af989a84b6252287b2d78fccb585b410c90d849cfe568103712239c1704148bbda4b342fe07a46d7b0cec8046a04fa23ff468c009ca41c4565a93b432fe50b46ac56cfc0f4e1840c4894bd3357726ca7c36ac2625d48104b707e126dbac7bd7b49f8958d6af26797c3037fa6c6cc0346872f0c4ee63a8c76faf67cc06f3dc6800e99bd53c3bd80ab522e700c78b0b1e052220427042ab99e8d5920d0ba4a0789afab4ff41b19c0d004ede52fd750e36730b063c54713c06f4eefc3c7a3c396b6910303b55651867664b102a26208e9c012ec964a317dce1fb2c3685af643016533fbd608ac93ef43cd92bd09917b4b99524a018508f708df0842b10b283f09d80a7026ca1f6dd7c69db8c65251523dd29d47d943e3f628b548130a0df5cead0d2e413be2a33efa78247feaf4d5d928234d182baf073e507e2ab859430d7270a60d30747f770d48adeed3292b7b2c958783e3717b685c822653efb304b304b46ecfc9ee45001ea15f7a3cf855de4a51a5b75bca745945c0e3f13649f070910081b74942ebdcd3517785c242d5b059ceb033d592b5e373a64d15b43f643dff7cff1d9fa3faf8fd9ccaebaaeac358551feb78a3c171c1eb5ab8c9056b7596719c4179d75f1d44acf1679051bebfa68b4625dbcfa06d9a8cf125ef96338ceabe6bc7866dba76f917bb5ddd7c0119be7f9bbe84a9fd1d83c12a5f408698c43bcaca2085294354c608856d9763d1b58ed569669943c1e3510f87358ba2acedb185862e1e8623619eb03d98ba6a079d9373b04b3d974a3df34c116997b7b0b33b3fb118f34ef348275baf7cd8fc77cd196936b2f97d2e6a215ca8aed9a51b165073dd125ae01170707890e3f77fb6c7bcf1011097c054780447e22fdf3175d571aa70659bc756783539292635cfd6b8eb8a2fbd6e5df1d928321fc95a167fd398411d2ca9e5c0f11894443c90e190ede01c600237bcdf17ff8d07848448112335ad5a0384f11013edece710a09d1b1e37b5028e54dfd1ce06a3da72ac05b46b57b833f0c6e37df1db78abfdca95c7a0f6d5782ceacfab292f060d77e640abd6f6c531891e69da9176a41db5f66d47234790340fcfded2d89c9ae5ff3411ef91cfdf4d3be397489123acfa987635d4eab837f9cb27106b37d55022c94f2bf2973b41c39648d59be7a979f871b035a1fdcdbd65993bc0cbeadf1851485299b9b977c025008c9ab8b32c97eff29392bf5ddccccc1f9ddbdca4ca42757021703b46f624c68b538cc98a12121528474c1475868c19d4986804b7bbbbbbbbbbbb628290e0b3b31d37f1c8e9b0c8fa1387002f16e06aea6e29a39400309c6c3163e8b5acf164c46dddc8ed07caa072c3531151173750bac1e886a4309cfaece8b19391b9eba279970b2e0422caef33b2affb141b63d4589aa67dfbde55dfe2b66d31fa5744f66ee8d2dd37c61853bdec3451882863163251926127d34f9ca5b9dcd98948501c1276b056aecb65f4d9f136668ccdae038e893613edba4f868cc2704c945f3291f74800d8907af94154bf3d173fa005536c50f9db0f69514aed555f90f6b5e2fbf8cb83e4d78adf0882c8d7be2097bf3c09b87d12d027f555e9d00534e587bf9ab08419d22e873242640bf59fc925987224c3ca4e8c3136e9581500329a54f9a908c61893d0004510485f286d6962058c47c42f0c1369ac18c71655fe54c30555fe46b184991a0863c450e5cbb83748428818638cd10331c610c3a5c6d805e7504950e26a982c66d5c8a096a48005944c8c998c0d1d8ec814dd1023f38215349119a2c80260c82cc124ca0c2616706a22c3e5862f51646650a444068c1b88c898b1c102543c8911030e16f87284130401c058c2e40585872c4ba0b858da07644e4d929a8c692f64311b906c20c306a2346cf0c42436864912d4f2482d6a1e5f933146c9bc05b7756577a4fa737b715d712291cc51b8fd40184e2b706202bba1090c3064326a46d54c8ddf0bdb997aa46b0b488e7aa3c62f4c81f6c9ad9bf632ba103f5617e2e344fab1564434aca9fd610df46de07098a1494abb3f5a23bd758de1f60363c42c812d61d2637ca006514a9c94c8606d300e1cd0fd30d6b8ad4292daea1a6afc3589732fa979ae72724137c62825ff7e2dff50a0a9fd6d6533a4fc5ce88f31da3e8a7493730e628c51070be87ed27d77e516a594a1ac45bad8b030ae0eebf8816effec662835d3b959fb26d77df9752791dc5a382b92b342a3b78203da68a38d36826ccce58713638c5e39d2a7f281c7f766f6707804fed87275687751ca9e1da3267bf8a0b6ab1177706298b56be3152e80baa9fe3c9a67f7a34ea8bbbb7bb84cd9ddd7290046d058c3ae76cbfc3a64386e1fb79f31ca9f3f5b93114afafaf3c7285beef4246ec2f776c13f8747e09f3bf6c5dfa4b5bb7ffb87ee66f160f6ff68bbda8b3c61a41b54ddbbe3ae9432eeee8e4be3393f8489839cda6fcf693cc250ff9652fe87c03b48000c60445c84616262064668a0c90e34389343163b98e2454049f913ef24452bd0e287a41df84003154f8a4fc2d6eeee6167ecd27425873262ae8851014622ea01c64c51c516269808a20897c1961a30c1c1f184aaa0faf7f6e8da3121ae80820c8c95b07240f96ba5c0fe49aa2bb50bb4c0a28595ca7f02901061988490c2534480a2fddaf342c5ff218292b0bf886b5f0b3d2415db2e4998a95df73739b93a21fef869178ba084b6526817be166bc7c7441ab573e4b7eb5d3cdac5eb84a5490dd74989863e4d34b9be38e38aeedeb5cb9d992977c739a7cfe9cfc349a1daefcae572bc82c0bfc06da852deceeaf84f6efa967aeee9b19e3f8efbfdb39eb5e38fb48b3ea1fee1ec7cf8330bdc49c5384e0a0dbbba404fb3a62fbcd4dd528699caaabba50c3195ab91ff020afcdafb884976482843631bd53bc6ed07bc80925153a25423538dae3dafa426b58f5a8c5fa87d2e685c94518b316ada27bf7dc12b7f8575b1e3eaede12cd5df54fe4d6a1abf4ca5bcd5e9dac57146d6b6692b5e1dde38068573c518638c316ad23deeaed4b64ddb18ddbdbbbbb5f8b1bbffa8abd32cd69ccc3fdab5b4bb37d6c6d327b46b3f046ef7a04b4d4ac571aa94a66d8cabc9d9dc944a95da1c57f456673fceb66d4bb172ea4a7777df388c7126d95dc6a86952326fdba64929b79a252dae5edd7ca6acb15dedda326874cf9152935195d32eafc6e75d1fdecdae9bbda5e3563c68341937d50a38c6892915192783855e09796215d7b9bb0fe936329b18db2aa678a4562c16a5fe43687cb058354dc494a879bc86de44d58daaae8a53a53457a9542ae7544e44cf709b23e78ef628b56d5b75504043625c6e95d3a57efce5e3a3c2ea476a05e4bda254bb9a48232202f235eeab7e56af38a75d3f9b8771dac5dbca472af08fa69641798fea5543ed045381add68243bed6146e41d94588004155debc6264a4d2a2a6b9e611082866fdf191ca63236e83c2b33585e91e0f92a4b49556ea587be94d6b2828a82abfc734cf92a9f2f90c17b54bee88d1fed83ba8e03687cb21a3b3ca3258122c06c5240595bafdf6feb1d991aa9b31b5f1a91bd05aa183a13585e6190c62908bf852bb9b53e551cee11f23cb1145c366637b18ccbe787ba8b13c1d667b3aca5f1c420c34aace9fac0fbb29ab27ef612ff6c54fa64ce577352aff93f70ccabfb065bebd87937aefaf7e1a4ff5b1886b7afe2e5bf273dcf5d3190ab5b35379d67ef29eee992b6366820fd00f7ff1bc12e3591028a076f17fd0792cf3177f121495839bbb6b9aa6757c0f716aaf2ae020c7fd148750a2822d757e3fb51857c845705445fac5ef1fab7f44188a05f70a4490534a54881a6e540b322068b850a9c631228b585d1dd4c5e26949cb512c06ab61d80a29507e2d5f30ae82b4a6b0c0f717abc0055b53b45f9065441935dc99bb76a4e7e3af2b43b5178885ba92c52e3b10b4cb818a29a104ae288b448a18d515eb68294a110c3c298a13356428bb9483931a466e77a10122f01ef91de0bf998081e1ac6bc4909e86b1a268f547c2b0a2a51f70a8fe4466ad2f701b2ea31449f9236fc87e78cff4214d3274c5d03fb8e9a57e67474b7d3796d0709b90782472d73aaa8ad66906a2eee9fad5bfaa256e8041c3598dcc663bdb59ca7be6f7e41eeeb7c7c63daad4eaf403790ff7a9f8d5dffcd2bef0c6497ee107b53fb6b7363882c4c89c4dadbdccd45c3a6132543ba85ffd48bc8784f66242ec9e552d41bbf697e3c47b4eb0affe18a692271c90ac0e0fe12f88a328d155f79777797957d3de59ba74e9d2fd71982e6cc27c0cd61ad6aee62149049dc5269a18d2344dd38e905490180263831a59a4903dc1a4c687a218c8a198e44a524a29a5c6b47d318368484a29935c79028b35a6502286882e9c698a303da8be94012545b524a7abcbb483ac0cd72df93442b04147101d0307b34359ff392e1e06604206008b1504c8328500aaa05add25a62e71dd054b4ef0a07ddd25a62975abbbc474e44d96fa0a099ce1e405982b76f8618cff2b5b0f9a51d1126954839438bb03254ee567668900a4d0ad2e130f3708a3868d8728d5290ed30e666aaa2e130f5cd490fe5cc2b7d490f500335fa0aefcb0035292ebf0af7445ffd36c41f77763661cd89318f3182d95dd573e689e7bd54b6edd66bdd77d230e272326ef3d52aa714a793bb1976d979d9aa7bf9bff7d766a9efd7ed058a27fd050da11f6b9a95decd42eae5c436eaa1c26a9dbd51ecafbd347351f3d1b7e72eeb86df536de115f7d8d27a45d71e58366cacdf7cac7ea93acec0d47357925e811627737efcb18a5bbdc26f6d23c2958d38b81daba1f3fb1d2c7499c5457c5ad8c454e9abcb84daae3525d978ace3aeac14ac7a58a624d4c36f1db091bf911151db02751b5417e2e95e4b1cacf58f8dba9297e69721813466a29ed62362ac2b1030d39eae663682855ee1b8fc911af4ffc73fbc2f9313f0d214284610cf5ad80aabe85e6514d6905b9f1fbb552d829ad203537bf5f6b63128eea9e7801f2976cc98ebbc48393ea41e51e1ba39913a3213889872d356c2a957bd7c9b35476a2863c2602aea3024ab43d36080530dcfc0d0d409ce7e728efc1f982664802a200e7614801ced3c020ce1704821fc09b1b5f1008a2802b213734006f40d615fafc9579da5c000605fb2a0e28d4c5507352eecf63a80f7ca0fba9d4f37a5b395ef5735c149ff11a66039d1f721217e73782197dcad971a620c314685a6afbfdf678ac34cf7e0c2526da5c00f6648408d582862b2352a47b3e0097a3b8547e3ed3b05dda010a6e871f87057787a356879f9f78f093cbd5319bce4983f382168c17322881422c45d1f442b4040a0c1a018b2d305088c13c394206c65640abb7d0c0cc0cecd14314483118c845efe834b16558230b224e76ee05ad0da03043060a390d4ead15be209e728319a240a1550d33d03f4619b460e6040aad5e8004fac72f8865e0a48918284473c611e8df6eabb112276494c0f616148adc38f4182bc0785a2e509834711919506902395f42c31846a0d026a31b460a18249093ee04ca4a1328d49d39e268dab08596797483153230888198c129060af90e47a076460a1033b06938228a285003a306982890eb68342d6b1c29f10ed6698b2632e712f58453ff10454313c8f96ed114451228d400323d84891a0c6a98411328b4d383981844275c684004725ad79e27110326723003b9ad6b2f686540d4c00914ea34aa84818019c0cc402e654506284ea0d00e94334dc09c56407b4108c0818c245068aba0828015283102b9ae6b0f0135d8900472abaebd03b4414311c8d174ed711618cc10052e93922e512047bbf6dc8719c8000672365d7b41ae0519658a40a1950e4f14dd74ed79d10f349881dc8daebd20f985071a66a0d03a1501469caebd78650b2d92400e47d79e63a146124720373dd0d13550e982040a31bb1358cc38710472dcb5d76a982992815b85194dc840cebbf63887299e20818cc31145c8c0a03ea3062398b604092b92402166bec107eb7bfa98dc75cf751dcd8faf7e3e7b21d8597561f5f397b43871dead9ea5303333f3b6d1d4d43c57b3d56c5b951f4b69573f8dec35e856b93528576e0d2a2b173bd51a5a975aa1a0aadbef340f8b45a993eb3ff0e19b67fbfa1989f2cf9cb88455ad41b515ffae363ea2195237b903a49582fc14f091ea4377e276f2399dbc67c1e94a1ee522384143f752bbdfbdc8afb5fd5657bf54f28e6d338d9e3ef8f0114be1595dfdacabd5b3e72b2f7e77146bd84523e0da0a838645e2d6004abfbf95be161fb5cb632967d0bf12553525ba8572636957c76a33c5ca1ed7560ae189324ddf708184adc7713268e0fa4bbed7efde1159b1a0618b69a7586d294c5868377d1dfbacd0fdb063304683e3a464667ed9d139c4bfb065a21605f8b55f41fe7e30eccbd73e18aa04d967180cf2f96b2cabe3bffef2e7dcb3820ec94f0890cd0d686a5ffeae239c5e66476a0e7ad05251430e780085b62cd0007fb4a630ac700128b45d010350bef605ad164d4e4a80429b1210a0fcb61510f2a8fc49407f7fad207f7ba92465c497d60a9f267ffbb4179a33dc40e70e166d0591d383f6092e567801063cec2fe5e73c1454fbd9cd5782d5c310ef7922eeda1e5e0b44b6ede5a1fd7aa14fd55ee09e9db5d0fc0d51a29188d742bbfaa714dba30544fbf8da47262a667599a880aa05a8cb4485953a9b87a97e5da62f522a173b5f49b949606b94c0566d86b2b216b5fed82cab06a46b7f093c1026a9fd496a7f3f0da4df05ed350f4800aafcb65d75733c32e198be38a9367599bec0bedd1853af799b53a5b7af79aa8f5e00ea265dc6df3eae50e89f807cd9d5cda95acec6af43a22e4c76256e66228d33c47df3040d5766831ab342458a07b6c7cff668ee9f2d1e83a7d82f8f45fc34ff682e445aca5ad6b226d24da4894c2dd409112832994cf603886a319b1cbac848e7b0cd3245462277195f70cf0356cbf67cfbe2af41ab600b1d587186146210000a0454f61e95dd0b5e4f29a985763191fe3eb023f87f42768c2d4d2e040d295454932225d174515c03494a9467686790ea0f6dc30119cda4ddcc8e934f4c16ee0c8b152ad508926d9a91718f4b4c14ef88f11943c61828471e738fcd8cf88b998d301bd16464239a9c363a90329ba5543355145c1a45508c60b1b2b9fcc53db7d6a28be23aee3eea280dc4aa8b7240c39d4d1ab9e7169ba3a0b151236ca53a9bcd664a9369622370699f1e4858b8a3847009fc710c438cb00c5a40b9913468d8b00ebba836a9bc89bc67f51edf699a703cde11ba8eedf3dee6711e9fe20d2e768cf8f8f8e4482aa28b895ec0eb4eaed1ced9a60eb149678a494a95834f556a23cee1a870dd8d0edd0a071a32d18a0627079a9a9b266ae80d26166a08b5c942e30e269b9b3528efcd0d336ee044a191c331e273860f0e19d0f8fc383aefe5222226f282fafbac8f07396e80918395c5647573a3abe33f844be0cf6647b8f1c54cc756417dce9821c30a13319940820924101111f9fcf08f65e5d0f16388dbe112f8a70008b0d9016b87fba6053d77543bce83c71b5de2dc51ed481c208af8949a130d37c6f270a763b2e3a345dec0a0e12209194af59f1d1f7f2d2e0e1d380e070dcabbbbdddd3631a0fc5a7c5985f24edffdb40f8165357edddd0d44eceeeed8dd317677f4c254f566efd8da1641f9e3abee8dbadb366b65709b13c68e9ddca6cdeac4df1882d4be6c44b0994046d9695b472937d9cd8a6f33048d326a51eedd44d149bbfa7520456ece2dceda1efc5df9bb591d790304d555fbea7d495509ba3d761dcbdf5d6af365949299e76b9d9c40ac470da58ddae51f1849d13185c6a32e4654b99aee612727560b8d1144598c9115437efae019c939c9830f5929c7c7c8454382e2508d2f24d620699ed6c718a353c4e98f1f7fb6d8a02def9b7e1869887ff0852c1d5f485939be90e5c117521c319c2f9c4621f59b161b34ec66ee365f386521ad29f21dde3a79cb521f51f50ffac610aec99afb2c5839ff0eff863e55b00d4766662766e06ea2061f93962dae2899a8419558a65489455665134330f183ecc9a104462e4dfeb38625a6b8e2a5ba6a36c1344e57643a7fce7905cb15236a76708ff8f30aac4625246afcd6ca47a4341011e58b0e9e58d0448728b248d1344dfb20f5a44445893035be8e958f488bf83259719f60cae149e205498c5102a96a4890a9dae758f9d05c55601113638cd183950f197657e454eda3f6338caa3d3d628caa3dcb4a1355fb474287236ea8dae358f9d05c581c01e6468c31e270d951441a463451841155fb1b2b1f1aa54bc49002eae8090dba28e150182104b793ce8ede6c971a76496324c5a0c6b759f9883963681874e5438b677471b50668da965043126a6842d59629842a59aab021832664f005112d20a28baafd5639aadad3346591a166a90a518df157ed84937c4dd3344d8bb17972545966aea6254a142f4a4a645c3465c9c2c251e4da1e4ee5892acc1237a8a416638c93a67eb99c06d490c7135a96ac3040d57ed218aaf62ced9f49d5de25c41455fb9d1554ed7d8670aadaffb0a06a4b31b8220b6e4372a2c6d7b4170c41668d1fd6b8f2e505dec5883238b9f221674e036a5c42ea414c8d1fe94e943151d4700415596600e35c9460c0006003d452e3c777aa695786543896a65099223c99da26b7edc809903094acec6003a8288c80c8949682f8c208880d8a5831a4a52c456c6abc92e84ddda52c2f4882eea8bb9445869913b3073821bb517709872527742883f67b6fef2e37af7cf65ee8caa05dc39f6550aee1772d5710e83a3dafda1534741de99e4e721e924907d89ebef9f83bdbc3e6e9872b5b2f56b387f86b6adae86071f7ae0ebf8dd749de53a45ff1e36b5ff1a39918d3a871e38259286a7cd5174bc5b88076aa317e38239176bd14347424588def48716e7c1f6a16941a9dd438654c20f0c154606b05185ab45d314aeaaa3102404643972b27d2744a8b18a4356541d6ae363eefbbfcb5fc85eb64820f945251513c8a694d4949fc1c0d1b51c16691e324ef6125fca4f247a548c44944f10b3916e78cb18bab18e5aa536ddf7393316a1a5be917d7481cda3d8d6ba7fb58feab5fb0fb9045e4323281e8a7f37ef82b16c41be22f21575443463256412d05015b828192f61a0c90ea9a517749ca957f0a43bd1899c0af02f7778c8cdcc87dce55d1eaf0774882f00f274569cc7bf84914218ae0278e19ad0e3bed60b1b4546a4e6e7ee4542b1fa9e7150af3b7d7e616a3f69af69aa63113738e07e1bef3f9e13e97efa83e745556815540a010fe9091d888a1b831565081db17d16c38aa53b62f88c1d60adbcf9f1f0cf3b7af06d97efe377bfe825b7703e12f2e0b9847c130e03d2278012606b6806cbb0aa27dad0952d54fef705610ede517d49ab2e3affe7eed7b97bf3af60fa02b50fef953d4a10b19454c45f3e733c1b468991d390c894a0f35eca893665d44651cac0b0065a2f88b37f2392a95f21ae6af281c2ccfaefc56b24df4042b4b37015086527e9ab2d509829fae18b183862573445136b6879f6417557ed8f116dbc3515c832adb68abf69325a1629d7cf7f7afe352352b1fbefdc79523f1fc6ececa3554cb5a42495977547f61cf729e15030d218a2e5964e02165e84aaee44a4a3e49d876bee7a4dd51fb926f6482f4915be891595bfd496a557dd8505256fe9c50ac1c28c74aded34ff6253f4a1155be92944e6db43a12ca09a71ad20a15c4a0ea7f3809003464074d367e8c9fe302628107e530ed35951f877754aef1fd9f66a73efc9bac3e2028eddf811ea9d1a4055328b78ceeee21cc7c0758aabbbbcbb8d345530c607bf47b7f5d506e57bb583a50ce3bd512b4e917a309f1f311e10a6522a8b7093f3eed62614157c77b806145b1c58747102933dcb66a620201fafddc0e2fa85d60031318b8c30b0a126223643cc4c02af377bc083aa040b8974254ee93d4766a9e30cda3e359bff9c66a0f7ad6b0380fa85d1bf7add607df4c1e4ebb5aad0f85ae2dae6edf5468533bb598ed7b4cf77094eddb8a53dd24b87deb03ee08168668336a9eb0a554212a109ff1c2c40994ad35bb99460d0ef7d1766d34eaf01a69fbe875d20e19286c7b96c74349dbb3d3f639be90a56a1c8ff385cfbaf185ac8d05866e543620a5e6a1f9ed1b4bf3a8d0db37d3f6d07e93cf79e1576ec8eaa777f3d10b8b2c540739d2757e3fde4fa14fbd01e16d3cd5afbcd67caef341f05a292198d8526b1a69076b7b6e87b75d10310403819a67fe4685053210a680f03b3ca0e6f9eeb7e7be1049e57e7a21923a9fdd0be777c441f85af31764a15fdb775f6b7eacf313c2c445cd99f3fb8f80fcd5d378ad14668802a85d714f65e5f168d79684d4aeed456883ce57a179e647a45ddbeff0b81ccc62e0ae2ab06df377dab5bd099e4fbbb64fe5405fc906757e612bd52d6ca4bafdb46b73b6cf0587511568dd1fb076a054287f1bbfbd233ea5fb58e8178f61a24e89d95e917d4261bfdfbd10ec537561bf91585f682b050f859eb457a576f77bce20ede2ef3d3e94ca3ba5fbcd2bb24fb55d8b71a7985591e45af4199130fd19699e0d970cba83052fa85ffcdb218942fb1b22a45d5f147de2518195449178096a62183f50f3c8a3caaf42f3b0a050fe1fdc2d7911537b3581fd0e6218128e88902726e2e13a21baacccccac04c6520c5566662ade4cad1d12b444f146f9f8ec33d7354a7032071774ab5c41802b03d16a2b85cf058d9bdb24abbf0a5400474b5ebc8ce1a63db369cbd462ed3021a6ba6e897a73fc58bb1878ea2e49115565f4a8e6e100fd10a10dca83846ddad9d99e6caf71e1769ca191080b438eb4a66d5d1847f45059fb8aac530a5d18473cf199554e56c2bf9d26e8d6d8cf0e25bc20edeaa75cc352146264f4d6d7d6b25e987d90419a877f9be1e989334a0051c39e2d085150ee57cfadbc86f217b39ed0d404bb75da50298772198c363bcc7bbaafe53df39eedb74a46cbbff9dd07c30743151852afe27ece397ffe0043270aaa1224154ed91eb67d42f361f8d4b79cea22f53d09c181ea43156c1f02559db27d3020f1d747c45faa2e54dffa2bf53191bf70c044f3abe2dfbdea4356179d8fbf1884293445f35bcdb7622b7e53bad80c8a6ac84620704137075dc6a00106c230bf05443ff54940fa0555f1dfbe06a95d9cdac2cbb1652876aa4d5e08183014ab468a30602856a7c020b4c9c0d46f9fda425b260216da5fd84f7593810ba63ed82603b7afc5338ef217d450c38e70f217ffa6c9dfbe4e1ad3444c5a16726da6767592bfa648bad2a4863d6b275dc4db5a9750ba87953419542a379da91cbdc3e6d6b61766a6957ffb884af3eccf28109cbf12b4d5bfe0a6b630abfab0f40416232c2d20db02c2ad9fa2fa84546095fe24759ff793d424b50544abfdb552bfadedabac1b695af27342bf260155e3ee744ee8cece67478436e886446d6666d5582bc149521db3fc6c36cf458c9663a9e90cb7d8ab7f10edd931455f869cd849141f691d817e0489c2e15504ba87edd1411b336307513c81421cc59725c02afda0062435811f4ea369fd3fedfdf0819ef00389f70075511cd43024ebf403c9eab88deae7871bd5b56b7bdea889a30534649db0f2a1fdaea226a36c7d0ed777252809ed72c7a9db05091e6ac84426f8d4241dabbae05a40fd49407e76fe1610f3b7fe62b0fb19ec8fbef6fe24e0802e9fa04203b58be3d57e394ee809f6e5ef2f85913e3e8a3a8a95c1450551fb439b96c02a02ea360d9d51696da212e539417168a1336e67bc8b1815e18ef0c38ebf711ff990d632b1d2f7d43d4def8186ac1424a9306385cb11182454c3c3141780f4855a32a411036b825a01fe351e9256803390d404e47327c5867f0b5989abef121458aa4735cc4bf56f22265090a9feeda47b968b24180c16c32e4d61a63ae8cf6d6c85612dd7e2af6a8e1d1224341c551aa2ddb3d2d675bef2d1d1acc47450fcb44350f304bdabc29dca4afcd3dda7f23ba11060a15382ae334cb56a354143b6c25492c4a86ea00cc54fedf2ff9ad0a54fabe36fa3023a47c0f5e90857b9339f676ca679564b104c75fe74549a4154fde9a0e6d96fa2213fc57797a2fab399edb1b5bb9f6284220a29b5bf9c6f9783536cb49fb6f16a94bcd4137eac50212cc4232ebfbbe3f7d7fa515598693c01390e5de718e2a3d0709f7866c84c5c8e01161242991583630c50804eeddf1edb7136b553b59fb74788105f7d47646aeaa8f36dea4cd5f9d3c6f358db0b0ee0df55737bf7053c046739fd82a05c4f5804833e3319e23d3f29eb818474169403dcc37dfc211bd81ea98ff353de065627fe72805ff1e38c7b465c356a8c435627c6c8c31237cca0e14ecafa77ad53051888029302abd31598abc57eb1646a8e9ae372fa6643b5046d9edd1e110c6003fbf20f67eaeb6f00db83045c9989b9690af1971764684531c6d2594c7fe9981ce3588f0bac0e06f8e5afa37e21463885e4b0802ec736a6e5c0a996a04cc6b22064a1a87c44d096dde430146e98392965b11c025b7dceee2c88b4d0aed412f42b83f277165886b828d13c6100b8abe9ed129959939b9c526eb29b638c31ae4777d75ec02a6f5d3235b70c547fee8eac52b1b721d3344d8bd107ae6776a8a3ae4df476775f01e1182a4ebf2825c3a293d9bb70817243ebcfb5e3f3365f3379720ddbf0cd17b2ea46433a3f74edf8a4bc3db9bddbb67c21847803a75ffbad1415f46342d070ce36a2e669178f76c9ee62f7a87e555e0bed496de7495bfe9fde96507e2d885b80431950606090d08241620656892f5423464b1358a5bf0532644370a2a88b47f7a89e559a27ff0b1d0214a479b69701a6a8a8a42ef64435756646000000008314000020100a860462b1482c1a1236691e14000c7b9a427c56990a84519203310a21630c01000000000008608066c4120025949beb342a08da99c14bd40aed6e5ae059c18bece3e31c32031202481e301737c55a5b07996a4ef450ab8c2c9344c846b0b4ed9c39f2e3e8455d22c6257bcaade8167c40387c9bf12f38617fdf5e8a2ea2c7bab614bd54564dd3a17670f89de9fe9a112a22d00169d178fb531749f72dd5877d220f48ff91ab95c5b8268c8f25c178a7404d68694635be7478476851009fafed2039e96ab767e9e83ac46814d3d4ca2b497301e6338da96dea5e2729b3d48a6dc9a6d87dbc21cfb8d6f41ed4a8735b32a40039082e76c6040c40bc1a446ba2c5f59ca560a3c5451c72bd6bfb325a370f2c9d559ff0d6f893ab4fd1f12021e520069a0b14516b6e0305a22945032da57ff829965ede15325b2ab9320edd598e99f7b3e45d98eb05bf6f44c1bec7a7860ed09932b335007cc3d6f09de42cb657c656d9edf2369de1cd2eb564b865d9fe0321ce12d8312c8509375c4f2a62f0cdeeadbcbcc761d82f2f5b80e6ca90018b2a9e704d2c94fcd6a170ad44d4ffa4faf775322fa1579b46436aa18636555991c2c3a06467aa2d27554715e24a3d38b2aa1d61f45d7398236e5d57b35a4d3011bd71c6ca5d175f0d215d1be0ea7eb60eabdea5ebdff72ed14081ac7342bb16eb2a84f3643b2707906d419451504e2ab2460bd8267ba6abe7e26782a7d0550e3d1b826450ce28e53d3d325785889bb5f17648aaa8e011338940c4c03c2be6fa9427e5ada20d6ada7118b4f507f07d0990ce6c835a1d9ae8d8ad303a4cc1a7975b6ce2a9b378a1cab18bef6e11bd7db76dbecc43830b5d3737dee3e5f06013567dcda06c34d1438de4423fe6f985ea5ba9bcea516c58a060cd26846d2b9abe4bc1c98b08d69255f68221b9a75c9018be647c0e5de9f24a5ba6844ed731fba7e47ac6fdb12cd543dedbe1c3b10ff92d4219b935d7485d0b8bfc446c94d299a4f87b9af0a838b0978f3481cab9933c6cc36f4cb86d52f3c61d63d307c9b28680d1f364b9b1c8dab150383a7222ac62492a5c686a9835a0d513a08dda2463c144a490ed1dcd06dc77f16e3c9d0b94dcde994b0f13d5069433403a4834ae2c03f76ac35318415d3f208e3748e1ee9ff10a859fab119769aa2a63ba9a7823d9c72f4b1ef903730a7a46d9d2cdbd77ff8367e2e871594a6e75dd028f7b9086bad736b6247c859011fa399f401c43b8a742cd9ae6cdcac91ac54a1c9e7cd241bea75782ae3bc9e53f9b7ca7c8f0ad8edc40a297681b2d32f574b0ddd1eae80e0eedbdd61d69e3390e359ea48a393985c96d8397d570f74d7e6e9ed7872bdd8f299815a6d5721d05c17845597d8bf9e64c8ebc5d33126c9c35b5d7011ee389bb5e19b8808cfe9055e606eed1795297ca82966dc8ba3532dba779e7f91f14c0f25e8460c9a4ee4f238247a07f5d624d25548d8f0d15d6dfaa3bf4afced947f0ddad0d1d9ac8b9254dc21f769e44db7bba0f96354d7b45a7e0d89523a666da797c33b17572127faf0ff3ac99d0088b7e966765ee61590731521e813f07311b2251a5959c858f9601aa44d11f53fa49a8e62fa06a5efff21a07a2647b5bd85e31a465ec3b2be336f94ed4db158173fe8719450e01f99cdb3486540eb93edb6036baa5853fc5f8d312491a6cad9896d0271892f12dfa7b8f0388017beb01c3faaadfd32a4b189b72ab2daed67499490dd426de2a40d1f7ec5d56271ae571b680d48d341c3269ee8a96442280579123815fd02e97bddeabd35bb7257ea4ec1af879df3f74ae0c01c6f56c7076fe3ef7e05bf0d552ccd2c733c7a0cbe9546053c312a870ee00db5f3ee538a969fca0ce58e672824025a679ce5216e6eeacf3f505820175ed3be7a5bcba5460dbf1ebd60ef02d610f3c3f90cba9e7648b4187455f724c5f9c9f7aec75da96555116ecf3f3fdc218649260d406174def4f2e2fd267e81cfc8d7881d1c92dbf9ea3f5f154e81832cc46cf1cb0344b7962e31fbd5471f728928e93e69d692670a3c84259f220c66045f1cf5b75baaa7cb0e7ecd804c5afcdb5bfc7c4f8c8ed88d8eed88eda0a6629be786b8048da6d3a2a29f2aa7d965a1550cac60aa52bbbd72c665f54ca6a5d5b2a96f02790f000dea89a31fdf32a9091c6cff0c4eb1f6fc6781d349876f8e1ac2b23bdd70d43348a09c35e3b22bba9ac6486b4de48388afd0203ed374b0346ef63650a0c0dc33fbcd6e3d1f550526c252c313beee7f8815c809c0a0aa431bf552228eabf8864a558b2c1139bec6d35a49e2b7d9d3289cb40cb3832960e6ae2a903bbface4bb5a99fd5b1a8bb24e897e62cdaa3518a0424df95d2146611e29742899449e0927ee966cd051005f36cf42e0bbaf5ffab32b0e7b5e892a665351b2023232ae6f5e8a59da1ce9b54d67b4c6ff3b1810cae5b9a154514266a98cf040645efb3dfb63aa5270217648623142fec434f1bc7e85c4dff0c03f4375fc9cec82941e533bd73a889b932f829ce7b343e6be751fa1fc5b7e5f5bb99af0842199218465909134e78404490113e247b12328fd15b10e40b4a9e70ba961ca33ab1a8098923d29288f1ad6ae190497d2538c52748d3ca7c63276961871ed89e44d2d781b8272a8b89eb47f24007038b2fdac94fb49cd859854ac757cd192a8c4346a01c6f3f0e55f0bfaa33cc79463166a2e2d1fe7b623b52ef03e2560e813f1ee2f13c9f125a1f49f259abf95b4add92ed9b2ad2ec303c41789bb1cfb3c9cff949653f6f967f462b7175d4919e65f021189b2c40db4cb6012c6db9462b70690208ef7dd6070191f7d000dbb022c630093cd3257f81b2d2c2e9d2bac7194ea88f4228766636ca966cd997ec13b20c7fa672291090e7a370e3b5dbe826dbb9f546e4fbca1d20597c57c7ba254d4a3b5c6f625ec79561012156c77d581878412c89f76401ecf2e684804aaab91525138b7d42255a4069cdb5d2c4e54234282ea76b05d96b6772ce236068cef19c5b0438ac8c37895c8352cc0fda0bc3add46852950dc1164546f8b853f1099b9fa9ddd38cd922481aa35c12ea5e1bdca18b577f1567d391fc64b7d5d04361bfdaa5c6536772f6e5db87efc213fdca1b38f20bf81d2a7918c74a5e0c6d3fdd4dee3c6db28791d667823316ac4e01b4e407aaac34edc907d790cc1353c67accaa7380c9a937fb58ef3630662d90e7b39b38c0101b606183eb5d5da9267fcd6801bc20d79528a571e3cce59b3b2e8da18fdf55806a3cb16fea53e3728b07eebc2979e108f8d2d9b532423d231e506c0546b2a7793284d9a07aaea5d03ecd9446d6a27f8b551dc233b1d869e85f654fe929477169c237d13542ad3810ef416c39e0e4dec26d093682873d6d909dd8cee81c07f72add41da08950eb414712285b63d1fa6a0a99b1d2a80bcf4dcbd8f407f3492cb86b4901141ade321c9b7147c20ec43306cf6d8d72b2fb3c962a2e1b547d18e239f4b9c43d65fb58a181e09a0e43ecef88bf95cc7858a6ddc8c0e8c8a8d3b3fb407e37d2a17cc05832d064a4779f1d3f346b74ff69f0a5e88cc5b7a56d6113aa55ac246f96bae29a6cbd62131b56973b7bae3bf81fa0ccafbde42e1996212a081d6d47b6807ed3a5d9186d4afe6d31535b3a71dd6fc41cb83f1906ef84eb21afbc487d95f16dcbf9301f03dc10cd19ab81ad9be7bd9a68b4a4e5d70d8d7d77789302ac51db2bf43f53ca3647b4bf3064c51ec0f5f5dcd40dfdd28bc2d94d132cc829d13349c9e6a0571e3848b2b0228222491c2ac0d7b31e56c942f5ed68bea2724deac0271b0c2dd8677f707d4b0636408e0eb619c5e89def5ccec3304378e622ca32ea91fbbdeb97849da203b157a8951e1ea4bda398ff50195f042fa29a464c76126be7191fe2365e7bef6f5adc696f30c5ab448edc05019b47533efd2d1a8e9a98fe2d2f4f71da215cb33d6b5527132174d202ce7f46eed2682782c472200bc296330a43d6164f4a4c0e8841e907f3bae7b61a9f00deeda2385a7ee777a3bf1f67c65f55c81ccbec3e582f22f2897432d2dbd6e071d5bd68678bb4562d645c79950edd76dc7ce9a26712c3b788875f6b7daf8dee73f79737f314c2623a24acbdbb193958ffe8c3f834c659dad64901b437b736e823824d066221f9f296c4b07c961e8431238518c86e4a20ad19a8e14bd1b772234e0568b6c690bd31935380b6cc9f50b5ef9eed3af09fb477359a3f226e6087793d5e49ba0343cc5e6b8e41534c1a6015eeda31e3871306aa5075471542bd9b324417e10f09789e663bae8f6464847544fb56fde9f8810ece2aa1af6df348888352d3d2dcfc0c19efe4445b65721baa97730f665fe1e3dfdd9cae5c7281e553868b48c43cc863540a8eec6422cb36620147aa6a07e8df4865b62bf0336f71d99058aa51aa302fb2e3f26aa795233cce1adc34ea64029ba611fb03070bf8f5c3a619cf28f282efe9deed6ef22142bd61d9e15c360e4df2b90b3e25e590b9ba564e2944a4966e7e334c64c71ec10163ed9c9e45ebe08a3940066b96bb75cab2c3020cade315faa88964168ae278fe6ffece6898f92a4e4820a84fc04da65026092b58d522dda43c703d746f61f198300635f47dd5640f3d07c15de9c05c05bf87e463e11867141e6949cc905cd84de3175e64b8918fb9a60297b654e8828a4e5dc978c3208b52a14f34a234086da23ae5427fb012be53d3d5a260e45755659458c9624ad84813ef999b24c3c05a4f1ac88e0580b437f4f001f7df7c344cc226f07dd43cb0e8832b6a330c0d5b89160d968c8795b246065516f958c9faad7f64532ef0c20c72d393ca7a0a63afd936835c53836e3c4949708cca9bd452f24d2df384ad2fba0636872482b2c72ca73a8272d5dca3081bb49022b312925c717be76cd4b20ba54d6fde0ba3a34ec9f520e42634a59f83ece07341c16e490bd7cb0ee488705fce61b00ba28282f14fe49dada049e96d3ea7c5ee08bb984c8896d16a83aee3aeb7255296f21b01bc43a2dd4eb06ba5e208fc5c2b343b691b96aba210c06ce91439f09ad60ecdbb596d885999b6758b9ecdbf8f96e966fc3af177a1efd6fd9197f55050c0a93ae7f5a4a1c38e855b462930a7282f7008aeb9d694f6e4134dc359085fda9ca36c205db9fd3aebe8bbbd5bec90cdb3b005c809d8af3aa4c1024a2afaf5bddab8f94a50ae23b4b5bd00fb9edb99bcf1fb0f3deeb6cf16ee2cb310f4b679d9470be66b7b4fa11a845eb2acde4687d1e0b19128fdc2d8815c222041cf6282cc4f7e2dfeb3a3aa13890fe4c19e223788914aa52082578214a027dcd12ac9558d59bce8bb718ba3592a6df05eabe9e83256bcfe2a00c114f513ffa81d1064684b0c9f8d488f913d518c08a9634f09e6a0c8776bd68e7868808832a1300ed1db4ab2719cdc4c6e4f8e2bc55702d411c351c29d2643738ee67ed12ce5da1d099d57590eabf96ecea7ed375516973bc9234af21d3c0c197d0b45a662133912d18caafcb44a09a5a3cfff99748e07dd590c5fce43d50631be3ab47936ee1c4e43f171f2b865fab372a60d956cc4025d6c93bb8afc259439ed9cf38f7a7c95fa2d7f7e3afb63e43b904d6f2cd12090ba11dd3ab90d08eee8d49b8fee235238d8d3275a8ff44962c4d00eb1cd41d2dc54ab0a41d7d86d60c93152cfbef5c0ca3f803831d0f1c14100c64a9a260ed6fe43e2dd41788795cab5e373e1ade5f354f858ec509d2b6e59736cb4d25f37749703ce7f6664f47ba82c21f2386b55aa9b427218d1195ca79f8072e7f0dee8d09f0cf7b868d14061a2cfaeea8d67791bb916f7e8d2a87b05c112730a4b0a9c064ab8134c6cafebabf20156ca9840a38e7e53975f061c76e8335c021ef521f7554e8eadb7bc726ff20a4c4297221642e3a7c4923b854f6888a9985fe6e3f1ca48296385683c5b9372c609068569459c9d9ece3d452826ef245008c09814804fc097aa40a7e0db1dca621041bd08207ca708c3c03537af66d52f4608fbf49c0a56e5d87c734e39a451c7c975a07d5a65aaf63005548b6b82b9645db2d6e4133b46cec7067eb8bac33f2dcee9e22479ed878b866b68fc75e51439457c42aec219b0401884a6f8db72bcd0a662f4e275c520f663565a10610135f5f4924e9d54a0a03d2ffde49039c684b95741e0f7b35c173c8f915aff228137912fba39a768cd4575b788bff724102b929155b91d74001393cbe84af7d46552fb7a9c52b92d86500fd41e4d4cf7465372c8bad7d15db2043fc9b7ca2df98cbaa90d1df75b504a7b82a3705423a17d22acc5c8de3444edef7c41e47995091bbf47fa343924752e6e3b51e210f1248a5960a79c3590933410efcd04a52001a73ea87c9a461d9fb476859a4d64a28c651056b2c93ce99e7f422751d21738ad857212e2baea08158efd8f47ce8b74460d6c928136aba46bc3674d853601026ad5fdfb2d485780be8da5b0d82c98714b6cde9d72a2a747fe6eb29389c40fa75c127812ad3afd5a15622fb55022f8dd0bf5fdfb79adbf08ae2de79131d476b7216818d133fecb35f3bb4c5eab12efed4e125daf8f0ac0a48e6cec99c4225ae4d913c5730186a081236616611d094d3b7fea045756a779eeade5c2c38cf99e5555de212e3506614343492f7f178072b698d77c124eb990fa12f80143ea745a46ed73e8b667d6a9e072e3d5c99a821918b3615c7932c85874236e8590a7814a3b9d8f6fb2c018c5ed045f9c37885b5beab2e5b8cbb05c4af5965bbd6e21ffd0ee71dde62559804070273904a0699d07634d6f373743836c68a5c0d27fb5c9e87ee55f6408aac5ea7aecf5dd543218acee9ca3183041a7993b42da88179c1a657f3a43bb3ff16241b519e8aeee937e80d4b00f892ea09bdeb76f908cb0d81e3984e42e8dcc0df59bde0448e5e5bba48437c1cca8aa4cd69bfc138a9ae8ff0b3c352ed1a489dd720555deb55f05ad0bc8a62a5cde8a82746aca9da02342d18aafaa63fde1c98e7ac68a3f832adaa9ebc594f70aeafaac5157d6d9584ce11b5b130cc2dd872dbfff93d0977f91bebfab4ed7f92c13c8ea7b2bb6425a6e7a501c819b76864eb305b27e004786d71a2e9b0b85a64b2a2326c55e60a586adefaeb15aa6d9357b542755b45cb27431f53206ce52c11f46ee6f22641001d83e28b801e4bad813e7e83c6bbe1a6ab456384f19723c140319846d7353b6e4ca01ffb7e5aa88ce57bfb4af38781b2d388b03864df8bef400bff1517482428067bd2f285bf43ac8593f54788b404370c757647705a15ba1e5d940cdae74c7623905d6b5d3cb356ac38badeff3e899a34deb7dce17f9cfc173613dcc9b62b1cdb0672d64a954dd90370d22c6d65e89c77c72b462014370f9bd57b49938dd17e6c4464aea2d0e63124ab89c6ffe10468ce7b23c828bc51a3ba7cc28d1457fd50bddec21b738340b0b5e6b9c8ab8416d01f89e36b76a667160d9a0039dfd885d35ad84264c9525aa531ae66dcef1822f703e3e909141e29f26325a0830c7b4972be562788ac5e50af9dfb99749cb544e0b21c3ae1cb1cfb44254cb8b162973bc17279c94215d5f4479d86f94f8910b633d6797d8a16adeeff1b126d6707c99d073ce089ddf3c475fc2a328917169d7c614d649c541a659155f523e44858fac6a804a31bd1252950804e844a430f64e0a203890bab444fd84425209496c5fa43d5f5452064482029c6c6c018f069d30577d018ba006fb44e4a0635422efbca3586892c0e01d0b35bed3abf1d02d9e32d02c907e9e4f9dbed8e5bf60a28c955dbd51dafad029bbfb829da53a655c8c3673ded35b7901c98c56a904b8bc557acbc264f38771909f90b2a20f79d8f24e37e41fa898068686235cae85ba9fc32e243e234fc3995bfa3d27ff8520bb491c0f356193557716b353a0f65e5b46acbf4e4a14b7f341b9dcd6122f9aba0e6aea55d3db4def82787882021ed08665181b35084f519f86b4e720e159d04c9c9915281e135c3f2ac4a1a790a67f591b01779214bf9b7e6f9f2c0b6ed88c1c907eda0e9cf552c6448692ed9829c2dafa593b32e2f7f20f94c41ca6c8098ab43537adcb9637d4d2e3afbd12931e875882aabe67a1c034211b575c5725fbbe98e4ae1aaec5aa44f1a9bcdbae868366c43968525459198fe89d368482d8d6154c0314849580abc34bfed219f171d08173991342b2b9dd3ce1e298e3dd5c87f634ea72ac6ac5253062cc4418b5c03af73adf7319068415775135d19ca4dfaafcc4a1c5c81382f689458b144d2d5c857a4fe9a012ce69b6398cbb8979b4c177f6f4478bb92e09f033f032c1b817d99e0968ef9f95b8a3b600ff4850c4830c8f226cdb4ac9b8192a138a12d32453786e4be7eb4abe343063e6a6a64454aea7632ec613dc872b3858fa4b2d29b1de3b111d8c1f1121540970999c73821623ba927afb9abd090c65daf437e1760de8977cda703e043f7016a128c2b17c2fb5ae246408ab280827dbf5525565507bc02ca56089384d007cb9dc4e649c9a4f4870137dea2611fe7dc54f09e2d0e2e83b67ec873c64dfd44f7bd25bceb52d08662389cedba8f174db93c24b7a6721170eb804d6953da084a6454c61780a8c4cc9a0ec816d26c19f0cfd5edf20086e037fb3905d490114c107aa59a08a3e09642f8f8197b7a5f121a6c61a3f3d1a3aa7e1fb7dc2974485f021eb0064da66515b41b77e0b4503d6c6351629f55f7be94859f4620c6aef4d34e2730255574883f33b4de348e09fd3089be315e1e775506b75455c5acd7517256aceb4a9650d1a6990f713b44512526d3cfdb064df0b0ce8788ddb2a433a265c67a6bf5a5fac5a5ee633008cc4271d044ca40e994420cb1412dff0b2c65b479dd20679a6ea5268e8a0d33b48530ad1b822111b4f312a4322ae2e4b7b00c2b8c4f1094fa7dc55798f01141d6eed89f88089cdb288315db50f1477f64b48c6fa1819c38e03e52e5eb563ad94a729dcdb8916a4794fb78dfa9c28d182a0ea12e5a560bfd34be1c3c413f13c52106e604b814f23f18ad3826a0109fb14c1adce0345831d39700d6f4f9ef22e8ceb46855c3609b0cc5c34a5fc546a97b74c5f3bd84ebede1e798de74ad54d963625cc00fb45e7652481dceacbd7280c30786067bd7b7228a0cd0c3427087aad96ab11684e8b59865373102a628605471a476023c9e79ca1096d1ef01f9fbc1519c55e19286e4909ec13dc20318f434c047a6ed0887a1a973835ff0ac7b757ccadbf24febc63a53cf5add643da960a5ad78b12623637959940ca7185a5b314e5ca1a9e7d777cd5002f682e05d3fc21e1624774086d5451b9420ad8b3d042e38b90079d78565be5185a68c4b113da0abdf7a758c35cc636ee7dddd53e078d77b8cc54701536b979491600bab02832332def1bcd73b34a441b525ae77aae318aa2786532684dc5ee13f7fc52a0cade15b086cb861edbf21f0907b2e73f50fdd3509799bb117522d3a5cc643cff9d5b07ae50f188441bee420d8a2efc3bb013f582b22439a5d0464919944fd8816edd694d827541a5c8eaa3aa7bbadc27391b82d8f442b5487f7100a186818d67031ea3103db375899b1eba23b3c0f6d41fee2eb18cc795a8c2723a26145beb918792112cdc5f5dcb93e11f748f18cc525a3459f474c7744bd5ea5b1a251ca33f199bbc87ccef9c0a3a43e2b82dedd3102ab17f0dec9d281fe0969c5f175eb90dbeaf92e061b667cf5c3819e1e3d5a91eef7b6a4d5466fdf2091eed321ceb78bea8e395573066d8df8b650215771b9d3f2e4fcc354a4fda1bf4d7fe5901903be8bc7696fe436a72e2e8cdc1205e754af016edf187a8f2cd2a2da3b335ddb47bd83949000d9743dc04ad0621d42471455f2322331e744ce7246dcca279a5f9f30bfc72d4e7de8a02d24930240280457b0cf212f465b7ae951c7d7ba1a54bbd28aa579375d3f3161a89c3df9f1740356e578b1b364aba992121962e36f2b96d4178dc1142d1d4cc5174e9b11030f6fef82541da218bdc49b6b115f967ed929fb019f2df5f51ea9c0a59fc6beb7ea99c30d08093d31f49ea9856bdb17eb1a73fb953ce362203eb7d3cde1b8d1a55f81233dff4a54ca3f60bb856793a855571004363099abf71a092bf3ea3fbf7f5b7241379a3b1347c603b0489995f60fd279c973f6b9f9d8cace18f2b7991591bef90fdf5283c21e65ad024fabac0de9a61af0fb69f268e8d69b5b5e0ae4001907a8715eb5c7f5c2d8d95830bc02ac5bbf059791c0fd28d1d2e2f6ceae94de1767058dc86d82e7bad218af6ba59fb1dd951974c274a43de9236d7f5c60a4394104c85b024e99140ec6a5baaede28bfaa256336b4274ab905c6e8bee5e92c55e8dc917c966015c6315f07c1d8c822d5dd036180a5dd2db3f6508ed8ee32a6a0efb0a4d1b8c59f26981f70b811ed26818c7004fe0ccf44e758c8c28ef019448be469422514de3fe4603f0cbb8dcd405029c7a63ae74a886e4ed392f374f742d4cdaab4d326160d47d559b8ec21f725d1cb9827bbec15599ab7191ffd09b514b246b7b50404b68ae576ccf2fb6198ff0ea591a7f15355e43a11af4c61625ea302a805b39d7fd8fcd97ca915b53c989655b2ca666bce5d2fc384096bc3a55d4e0d9d79607e829a708e888f7960bd6ee06c2e4e11948c2d35afc04b88cd50ce4c06ebbd07bf54999018bf9b2fa092d1e9436b4c1f0947123b27e5137858ab55b1a9f8913f3667d1c588d362065cdeb656cb0dfc1b1fea4b7e2eefa2e38ef09126c9a39926a40db466bedf2df53dd0201e00c914bb4cefe797353039141de0269ab7719d9d477b184ff63bb7634274af6fc5169f78fc65d1aba9b8216107bbb67bdaa3bcda654722add7f2b32582e798f8d074c838ae7b8c34017e30c87f5764d82bd020bd72d544a4fb2170061c19ce40d10fe8d11d5892a4db3331f055a757e6b3a42ea973efdf1e1ea6436755027ee967a0499b762cba390a1923da2978706703f28e3fb01456f3d5352c18644f16ec55e38a3907a13f2f63ca41b75383a855119e5d22fd60bdf1809d7e30f4b62beb9cad5d2717d97d700fa14480cbb8d6053ed86b2b618c5b3f680a00518dfc4ad6236c9a4128c8187c71bfab5c0c7568b51b2aac54d62b9fd604dba152c7c2b27606c3f8091367de8d04b703d3c3a2800cbb8b3b1b0cc50561fe09059ab97233a827577a435192fe00e8f1917008723551ac688068fe5c75081e33c62a23786cfed5a5c10b1e9b763cf4b7f384e8a9f382882aaef4263e8d4ca32106eddab2f7c87f7f15ef114577e0f1e0e3d5aea118158415f930e6b0f3135a77016c65f3dc810d64d161a9bef1611b7308fa516d96747743f8bf9a60decb6dd4e9f7ad9df420c25084dad62257f963e49288ee0dd309c854f73cc34d4a53edf54d654c49047b23a59c6f13f65cedb3902a226b61bff68b3b6e64a6f8c5330da8e636e0b819c0e76fd426132dbb12436a4cd280afedaed90e772f3c5c46c76cdb6fe6e7b770a521270dd6eb1510e59713fedbaf874434bd78f297bdcc42cb4c2f4da9fa018003cbcdddfab79b432e77cb8972a130a8b4c689d23017dd1753f7dad7c48de8d85e3933f5c9d718897119891c38d4a3a93e7454abb7808c8e4fc4fa230ef4925d0339e92d1ada7b5cc5a482df4a054fd1603548234a7443bc9a2d7b664967c3b5b84b6d9825e27f0fe8f3626ac41985f54807237a95cb2a9af87b01a7462cf43556b902a33b335cd17153b08780528d56871402c5a3107b1f40f1d62548b38b53346b7434ac301d5218b2a5b1a02078a1dfd4d75a27499398d1584dae3a7627d2e53de5c3b6bbb8222ad23a904863d68982a4646b027e21f6a8d5574398bd6f30a6c913027faee3b880a4f5c038a0eb7d3af133f96273c64c408a4001870a93384474678001a88789795ef91a3f214823ddfe8b833f64f61344e9ef3c8923fa1d2ea35927e1030b0a70921842374fe8cfbe1379c0d23c06024954fd4b4b77c98c8ef93beb96c6b165aa1669d32a0897eb705a9031f9636fc9ed8e98610a24ea878b8349198945285005435485833e707b3a91bf6907506f119aa4da0503c5dc7baee6e855ba98c7cc33abae0e23dae57cb8654e1e90fcbaa1ca35697a25061d225ba2b626699b4802515fdf271f324a3af9dac3fceeab0339bfbbf00934912ab1c05f80cfbfae102cd39c978437c61b17d391788a0b0613b86b51d8f5079a32f8498224025e835077f57ff1f055af2846245427d4cb4fd97e6c526a9d7c417c0f6e051b2e1d3520a45b6865bf53b05dfacaddc4a39ab1ac06657ae2fa80ffd19003e2448de43cef866a44d59b0e211264338bca0bc480308fee2ff9950660a2813029a85836ebc758abecd548fc96c020eefd2ae1ef93435cd692b26b72e3ec803eefaa7b8a908bcfa74e939ba82f50a49a1c4e45ef0b6b610f37911f8d28d01f455cf17588d9db97c47780cefd4d32be7c9a4309d31fa2710d4d0bb3c847e8b43cbae682a2974c01ad8fc5563954ec75094bf3f4e55e28728bc425160f4e9621a3a41486dc4c641c08ba3bf170b715d486e355d5059277007297c7a8dda904aab666a411a92a8a88e7314819cda8089653c38ac789fa7e1dfa0bcae9a9aa3eacf03368ca0f59a47e94af0b09a564602734b3e768e48e6b05eaf7be03586a5fa03c73121085295397903994b3c0238fad942ffa17bca3a774abdddc278de187079b60e00a4c775409e3b61dbf5a59b02df8b77ed1fb2ed8041dbf88f9028e36c78b20037a5d2bf60b1d8f58638e3c743289260a5bfcae7946951cd640be6cb80612796f746cdd76977522c4126101d3f0bb0b1f94bcbc9728cab904397719205ed21ee1ac9409052ed54e3e46cf391009956f1884a89c7f0c2b4dce98a5419cb78067dd7a1822b46777dd07945d68d4d7d34698a1a3f7ca2c4998835212e4ad403fdae85a02c45e226b8318abcff5b791182b64c1c90b118d9c29d91dc147d5818b3681154d32d3b33ff8e56ac2192d4052527cf7e8566b489135c78286ae6ac87a295df5d6561a9eeb3038836b58f8a563643afa1680440925d5398883f10508741be320ac6c58d230f8eeaf63140d6c60ac900d24f5c6b5b60f6d813edb94c991f5676157320f3db6fd33e2a8ab87e92f7f7c7718fb507399a85adafe3942f8267216486910f6787ad1b455993c05fb075a0fb6f048d01a502d8b9da96b3752356a944339ceded31007ea022e0d4796471fe2661040587232758e46d6714f81fa53883bcf0ea5590a9ec9e7c4b94a6ec399aad3b81f60e8a2a07f924efc52701ac53eb8e25718c301e16a373b10cd997f7a2ecce6f270ec04dd4c27a2c5636b6b20889e4e6911108764a8e48c2739d83a4e8e66f95a9121899625efaba6cd348aba1fe5b60ec1d6bd2803cb5eac75efab6472a9bddfb6453bc98dadc6c246a1152484c31352cd7785baa371a8785cf59f64fb0e840acc2dd9de1a64d17903e5cc707fc986271dbdba632caf479829eeaa6708945d4003ced1017b4769ff7038f83f32d21b67a3ee778fa1a5d2ebd33776dd796da8466ee68d07f35ee4107b61f00bed982f94d8069451b9b042e78e5ac365fc4816c2c9923ed63c483c7d639aa16e7ad4fbcb8354f748bc3bb67a5bafe70cb48ac175ddd9f9c6d86d58e0911e9bb5f7e9d598012f3135733a0c8a9106358d429ad64603bbf6c57c5d0a3a391c591dda9168bd1feae8de23640a41f1d7d9cee48798e21d0fb4a8d7cd8d7652d991a246b6d57d338d7f965d7e4683f0ae48eccecf0a475245f9f33bad5ec4c688943553a0f94b496de195b5eea86adad1adc0afc65dda9f70e43d853a184df9eed774a322a97d8d1b82304263067b17a5d50928baa384fae2bc007929c22c05bb74e3c7435330aec68df4a40e9622462881a9fa160a6e9493aaf00fc665c2baf1eca494086ee05b59cc74e4cfd91dd0818fcea0f53dbb50b75965b402dbd1e82664a592af2089980799ac343ec0b70c36754b9f7c82d237008b46994e8be4c6a00b545bd1186e370dad3e398e61abf20f980dd4eedf53003f9d3307b30ea7105590a29d2fe55e02388339be7d0cb8a243fd572bb4197e5fc5f5b912a69f09b6a5294848bdd19a652da4fd5c638d9d7879c04bdd441cca7a25a80da135373b5febeaec2f36b2fa4a33d143679e4eac89f15e2cf2ef34550c590c40426a854a627bd9c5ffa2c85cd2e43423ae40c1764a6b07acfe6be5040cc3477250b9fa725f4382e57e0ee2babe440e36434ab19b0ec2f001cbcf821788c2a02e8b2a23b525a7a7f01cfced901640d87c3a48bac72169d92d2c178fbc4881c1d8e2a9f1f411bbb578950b6c5b34af6013cc16af496938044b983981a97ef8031371ae8f028eef7d649f4a0560e70153ff6ccbb72c807b1f39e473de24b6d27d7b6808376b7553223fdc63ed22eaaa595c26e9f3ecb30fc6c9e1586a14773bdeaf2da5c6003e783ec65dfc25bcf354afb64368e9c538d3708e5dc635e2b62ba7a9f62344331510b7652f60e04fa399fe5723935d44d6cb78be7ebe96b57e7dd384d61e2b3cbfcd739dd13ee46959a537091d60b373acef04a3889286789287b060ed76d189fee6708c5f8f1af9119ca241f6b934f0b9a78d487f72912d943ee74fdf7267f2670e6ecc8bee4c2ace3dc3d6f61e3de2e92d993450d10cd5e29ac7e91c0f47c4e6b142258e075356271a64b122348e072762ada3f11899d5b71c8c0680a6b61aa142de67025b57640e35c577d937953d1791e1d34ec1529e7ec01535b875f87417cf4194e36843f664d5c7f72aa31765900be30d760fdad5245d4696d35a6cc05ea853173e50fac202a4e2d903b3d876b34f6ba09ce6eda810b6e5e0d47a664072d09967c18f71f37917aeb9e47cd1c5d02f5da2c0618aeba171719a03ceac7f94aeac2f10363f09a5cb8a3240703d1b6afe0d3ea0d00a72bee9acff19cbac28be12012a37d55b79fba3705763b75d16aac8209bd164771411b3ec96c0e7bfaaf604074e71336e1b60d8bb53801ae258c2d9659d9780514b9319fb8eef09bae972ceed2bfe91f7ce41c861b3c186be4119306f94d9b0a183ab0e0a0c20dd5e217cdecac65113f8a7c320e177544e6eee8b3ff4eb76ca1196eec3b722bd0a16ebefe705ef777ff4e86ed751c6a7f80562f1419b9e7dd01f7f9c0f7b919407316d824964ee2c14663b3c3b0602565dae13059336dd9afcfd9042c4af74abf25b5ad9e4bd49795ef3e01371a5e84084494823b8f93191d14a1c2b9d059be8169866222ab532b233f7a0aaf1613517cada50f71057d6880e118bdca0d8f6265ba1f8582faf97b1d04d8d85e26b1b22f3a501ab930aca7129a05aa7e8f4ab2d68110d0f9684cdac3af5332c753213deaa98a7f079eefce267cb69f7c67634c74eada140b30b3ed83a0d2f8ccf65e73d3259942d1c3dd5de409608612869a198e21c51598cb5b07d674daceb0df4a58640716e2e139fcfedf43da2de3a64a4ce6e7a8f672f3590a1a2cda3c2c4edcb1a885b09343439a15c62b11b26b44f4ad05935722fb4c98cdae873c9be541c207437ffbe2b7a80227b064572552f878e39f838734fde73ba21d8466f8d62c83321d354a10c3a6dbc81ae53c57bf03dee816b7de38c4144b98983e71d9d05fec4c08c53622a70f80c9b268928b659aa6cfd95fe6fa451d021789a9630a71f7c2b1d20e73624d3e7892591d9cae0654052e5caa40aa689c66b111f6e70ef4d98382a0e3123192eedaeb23de64a2f22e68081e533cb840c42db55de4a3e5646c9e0d7b3fb842f7a640dca6fee3abcbedb40f6ab311494961ee2e823189bf6d8aa91f46c333d9f384d3cd43ffbabfadefdf7a7e9a6f7baebf73a483ce68c775af34e846ae009318e83646edb920a31ecd4ff3bb0eaa9badfe6a1d26c66b86ee69e23c67abe4eef8638a6abac625605dda1229853cfc2c31fcc562179a6078db6a82a38e22c3cab143ecf1866d9fc41d5ce8cfbf1cef0eb67d989dc40836246e5e88331b479959983f4ec91d24061c0c88cb7f03c78a1b76e4f9303a2690f0308542bef979959e06f78a4152eca5f9899424b086320ad320025b893310c4c36aa0be34532d9f025a88b5e11e2b4b986b90c4e0511aa0e2c65d06de49d85bd1d7823cc819504f80b6327913e2b8b5aaa491829ec66d9b75ba5ddf5a6bb6ababc950d1046004fb04ffca53a79d8673d695468bb6cee9eed83d101e0cabce36add74ba5730ed7f04876e862fd07a2998c14a0bfe2c9d6d25bc8bb8873707e97197eaf78390a080744790bd61d5dece8360f156da94a3a61d225f68c92e2b0da4a59817bf7f81ddcd16f3a20d649f82cbd38e18637da7306f8968aca7de2c16072626fed7cfff047607001a7bdafcdb52cda29897aea74c59402564d11e9ea0edae44872ee60a8011867cc53fa38401594a3d38a32e060d84c0329b53e1d9a8190a9358f4863544efc945a1d737cd77f5c6e598605956b7c9211e4d8f880b2d8053511601d6289cef348e1f9727598a21a57f99e830d030a2db74ca7e0d1cfc621fc81a05087dedc0b7a3f4a302b63e5799e50d3d9de36534afd1d5e209d6756923916010f94fa44f079fd8f6e6f27645bb0abecf1eec911e1204f529db990528d435293524904cc5362a533d278ca267085ddd44ffcc2a0a023425dd41764b719cbe5b5c8989b40def1417caf775738ae660db10b4982064272a70aadeb92dc7720ca6dddf8625ab312058ced1922592bacd722d17566d4d8ef5212210a86c8c5910aaa06b43de1ea53aa011450c12e84bc58a1acf17b2a014a92eee2b8505288b880fcf8ddbfe7da413467a0a29635d3a6e4a9141bffafa63cdfb21d124df06b2aa82585ee1f178722d4de0931e88aeb9b0823ef4a4ad0bc04c97d02358404c8075ccb9bb71364352ac4a9223a55e009f548037d98f8c6f0d53715938b3fc607983a7990531605ff47322a511a7b7507eecf4889acbe8f2957dd5a2a53137b4ef3e920a2769834e23931f45f70321dc7a425b6b131a229a8c4d7c1087699c1814d751c7c806eb22fa120e07a3f7a59fdbf51c00494d1d9cc947b14ef3103aacfd51a0268469c76a628182e6b170dd8ce36f52b329f89543d85cf0d0c5b87ea24384f2242bcc35317d53e0a91c15d1c921657c05e1098611d2fda349760ac815b7c61d2da030e67aacd20358f54c255add543f22e5afee28bbeb969a661934590ecc1c3d8cd66633ed6207c7d8605a2c9d72bbf8fd6cb6652f37b51120e634c0a438938dfd68ddc941519e8545fea41fbcb2e65e77158f7bbce6c561a951b4ee6bbab3cdbb36ff2ff8e1048422aad5099f9617438ede1979361032887ff2ce2c2f28aa01f692116994dc05450f572ab435778731277000f48ae60288cb01609ca1ca60dbb48e35c1a85824934c9a7b8eede5408e3714b88fead02c511c162502bc4d0c8f33da4166c16acc1884336e123675460d171c33f20955c894bf05737a68e3081b5882f7441a2625daeef79ec96b244423a4f992628be30db48815a9dae2eecdab262f1f9c54df3603a419ed5fd8dd7e0353181c3035dfda84a06270e3db5c4e2a3ee695b2bf5391bb2008094dc4bf417547e0785c17ea56c1e7abbf5cafb40f9c428f8cb35370ab5092b38bd2b33cc88dbe85f7cfaff06771e4fe664cd89bda8f8a9e4695f4fbaa5b0bf148c6373dc77cebc0d8009c05031722303e7ff6e4f49660202ec20d6d6924d8b716364cc8ff60c837ad1086f484fcf64cf71f747bd0a72ab48b7c8ff61fc403adde3253fe6b6f8a726b20c9ab2b8efe03e6a22dcfe30f004b2cf5219f79fb881931be2dd5a5236b3bb3413e02548b28ad729b6e263c444c41d42d4162cf4e3c83e1c6985e84939a8c4c9f5995613fb353ea5f49acb808fb872f2f5d2382f451541b6b0eaa46057fae52c9d7ad15b2d2034ca8f82444098cd644d68c4d5003622b41cff80eaba989a54f1d9ee1be8515cd41caa27c85bd30875ef752e2e27d934f9f74d2d4eb94637968ef5a420a63676c83c942fe03f1dbd1b2aa608faa1a1093d9fde94e3e835ae1c40e29251a85e4ed40c2f5b7a2fcf62768650af7634c8153203024dd6d63c3d085c0a8ab720b66f022d1b9674dfc98e0ea5fdd854d48270b796c935102cc32ed0a389e79cb3fe3261537e741cfcb5209c5d4725161d2f4cb199737debea6b7497d5883567c00c967fa432b1fd511822a907ab5019e2d0289ce79d25561c95064a3e73bd54470bae829825cf1278dee01931314fb3ab93e573807ed7df3f655050ad51597e4d494aa55c08775be61c6c62ac7336454bad1bc8b9dcef3f6b8a88107f8c87dd0ac3c0d5372513f5887335905743d39cd66f20abde60bc0b96623dfec7c1d6c1962fa06495d9723946b1318609cbb7c87c1e952fe8f61beb352ab1f0b4b6cb14e970f48a730b69ff7be4afd9000572c6a83bf45168cb9948bebece7098e2b02e89b0e00141ca8e9e7517c3804c3f1d2233509100b5fb01138f8e50cde1414cb5d33fdaff786acd6f64854ff0d635bacff49aee8a62db2afdd05736e4ccd26ead9b99086bb046250c0de2a53b12a29e81b8f8241c33f737b506823c7259e9eb37ce7c50783ec24d858cf5503b8b044c962af1be529c79f2e1de78d64a728d02ec4e9360d7d69d5bbdd9a13e2a865e9cb6f9bf2c09a5bf98e7345747df37c335dea394143d2fec9091d3d3d237fdabbb4d21429ac60a0b83fa9db382dda7f0d444ecd5ac1009aec380b5a7b6264b9c4ad50b67575dac4a28e96686004f2371267be1cac849ac5b900cc51370d5d6aa11aab3d73dc102d91f329a5e94a60cca5740a9e02531d35e7231558b28fc6455d11b6b3e88dd9b8a59160dd646746125cdae8f19ccb41a47d33083e93073e67ab23d4a04f5c2f76d4b02340183720f52439083195a2964f8b661b7fd05146c1c6f783896e3b5cbf64a24aca407f3791dcf76103bf47343720029dbe239d897bb2d66d766a8ab1710ce4a1ca111d11e17ab3f29168f315d41338845bbe3ed30f5c75a0406c1d3755155a9860511bb05e8b5410dbd6836f0429687d10ae29b2171d0c2b8be71c06322ddee6cad1b6b6b3593a77a724184499a59a00198b83e1ea944ae574f00753d64191bb00d69db13db487946f03d97a9aee4b3ec6e105a0c771062349ee4d32acb30cadac76d5c68b00b26e956528f2d474a188a03489aa88744fd630f0c889b512bc993046919a97480e96ba2dd6525bfd567f95c5588e14d5c2c540393d7e11c9438e07e00141700610229138e94f92980321ba75df15de13b17d10e4d5947122e217d488590ba802142d1069ba847f060bfd6de1bcf10cce23a22515b86c6ca7f037aae88cecb0e252c5d76c113b07eb5a463ca95028861a0890bc3bd228cb77efd30b68fc8b134492b42b5a16b0b292a3ba2247d457844ba775fcefb05bdd7771fb79f40bb60f48de308a953c093a5b3986c06e0f0ca3785e0060295a59529e69007c7a688d815deb50230adfc90c3ed1df4a9f65e27c05a7272ba58f5a9165cfdf07119fcc228e0f5a32eda758fc690ef6a65b7b887b584bfbf54e7fb559202c7a6fc628c82cba006ea866cf288c7d4990c4ad44b8242bbf80f3d13658f4f1f8397349b61ae4dd616dc24d0fb3fd0df0e267c2409806439d14807a0ac4ebfb84803c3cd0d92b0ba2495fa4f8489ce8057625be66fd40cc99539c98f7849193aab82767fd2b4badcdf70d57dd86b0f670d89c24a97da7eaf510b6a73a95592b287824eb7cf21563f0f8630f767e80c3b04c202ee36580fee19fa80abc78dd28017a134093722db8b5aa122173ed4d1eb0765605bda2e82347487c78e065a20c52862cab7d059dff69c5f01ee140330163df3fbc36f989f9dfb39868fa608cd0dcf17b9e3bbe44b4bb31b790bfdee40d8f62d1c6a9e8674ab6d0bf11c151d4dc4808ced08fc03094f0edf5f73123f877967921b0529148db8f49180049836fed2ff509ab28b58de46010ecd1603680f0a687626ff97a5ffc01f63081d6063f69385b5c8b40c0c68c1efd500410a4292106afc743ae5b054936ccab21c7946f899678d57c8ea324d84228c2ca0b24b7fbf3354bc8d5697571ce0c47744492a2e906aaefa9bd2ac2084e205dd58e25d5427ae63f65c905c2b7c3c6abe82e8380334204dbdb66c32722f645b8d0e054d27abcd5773280234feeb8c7fd907c568dedd247c2bed67d547dd6fc58faa6486f50f4da612bbd9cd68c4d0b24ce2df10a2eecd4183753131eb191859768ecef0c32a5f9e26c8e85b068c9a922bfa9e216304d37c2c49984d16450e0d2584440f91edaa6ae7e6e7abb661f436758f067a9f0f43ca9b82c4edb5583aef9da02a6d0f520c3655db6916cfd8a3d8de73cb6618ae56ffdc2e16de5e4b3c86881d48934b73db6b47f144e2d42659034479b1b398fa2ad90ecf6bdf22c923de9e304070793b4d32ba7f4f05535aeb3a0af4fe3c90442323b331a5416dcbea2edc590ea359fbaa8982e73e28485e86401edc51b72560afee7c4d79f87d7e6e1703d360707fc01f17f8a23bc24e98d19d9f37fe1d19ddc2754123e878ba26547402e9367359d40ef916bc289f36a5b63bdf336a63f4e23f211a3cd0afa6763ce09237066874ccc77ddcdde214e406275aec9eecc7c85ecd666d54ff08a508af33c958cb1086f0b63ad85815eab4617d34a71f486d835602504ab82ba172b559755e6a200fe09e25d55b12d49ab4db4f4f5d134688b22e755a7f75d6316f4edcd88f87dcb8a6bcc9eaddd31d9508289271d64c956743aff3f6666f80b7774d44f5d6b35f10c31f47f6a420450c0ba0f235c80f6b5078dc5ea1abce0cb0144cf60f5634e6c24cdea5f4140b581448b6c70950995fbb5d96499dec3c12dd1260f26c81e98ce7a6dcc40398b9d1efc62c46908768c6ce60b04be82c2510f5411ac9898bcc04f469e842ab79b2abfc0aa369e9d993f37457a2adaedfcd84f52a127b854b038b174e6fabd668ec33cd8540aff6c73381732d54b5bcb6ceb2ef10336390e0747247032da9db6b275f196bf65f80d0d1eb6d06713bbab48bcef4cf78011abaca99c0df1f237ddf34a5e09a75fe1563e09425e2e4291d50bfcf6b85dd25fdd9d0174f9e654440e991296c8c395ac6bdf03d54827a437cdf8e61b7995adb6f1d5cacfe2faeaa368be7d37036b4d40fd91900ad7ea668fc0e614417bb16e62111cf5be8ccfd95a17d877a6c900fae797fa3b6162824adedf38dd59cfa949e797cf8b8bc5369bd3ab017d2cbb95fd6637117c08582a0cbc17ffefb5307a512ac322d9888ba36bf4d8928241cf69e0f866146accac95aa59a7e06115f5db1c732e7198d5ee86186709000915a5c78030966bd95c6e53e079ebff20f65f7bdadae2348880900c1229433ec0c5ce1f22c7302a32cbe860549dbb89890f917ac4141fdcb2900eb0f840f1bc1d8e083e5d9dbd3b38a12338345581e53068a07be6a1bc605617b87986124952ced9c7d199b4eaccb366dd4338b70248db90936bada8a417ae357cf54bd41e70fdce12f05eb40b47bb8bb066a3e7b3bafe7aa82e1c32f14ec3876d9f5e0b54e66fc603929bafeaa0799547265e800859f28a0671ab0c8588b015dfc2a4149d09dc8ed197e74a58fbd597ce28b43d56d8a126e508db508dc28b8da17a6880368dd884c0d1276cb9fdfaa549ba4096d30b58c41ad1338387b3479b791627ffcd9c542a65ba49232d7f94ef54d18c3fc60c29d0187e228387598f15337b64bef3f3133e8bc367a01df3e65efd14c8373c245195380ac2cb2b8760b8278470c4b1bfb75fcd9e523f5a69d9d962b4695b5f659afe6d24dbb26a0b67b857083f7f0f718a0110eb879fff0c79a80e5f72c13b64e8e206a4b36259d14fa31cf01a80617e5deb4ef092503ee1a01ad90e7115ef89ba7a92c55196d0509b6c6c15918d738fc1326da169974f6b0da7b77da8ca462181b27d75157b757490457220a7c7e93d31862e1230c578f8f11538a54148ac72338db3c11c6e494345f7bbd3ba0a486f151bb72402f641e321251c08b82a2bccfbd4d8d93204752583dddc8fb36dea1a80fda6693d38b3489ac43440f55b8337d5b3d8412ea35480cab494dd2cc3a8bfd913492750a35ea78a25bae3221590a8d5a8e054e53c9e926120c63daed779ca354b86dbdd5d09ed5fcabdfce30c9a53329e8517715ffb89d3a89a331d37ce70673158cc04e5b75f43be68d78ddf9e63b8b35435bc3812844648c36b4a836601cbad9bd754cc0f875158a627e48f6f316538fb309532b7fbc1a3051b2bc7c9bad1889397415ebdf556be1c587513ad8b04aa66e5dccfb36bc57e03853f52e73bf1b4aeedafadf7756fe07ce66fcc8a14cd8af03069a0e5e6135045f0f8830b3cd3e2e5f23b91378af1b2a22c5b4340fac8db4456a1b165d76975caf3d4c263abeff92b6ee9dd9cc379e8321258ce4322bee5b7bee0ec05357568db17dbf4df684a239ad0b678c40147e73faf5ddf2440e92142682ba82b54297ff48f1a8839dc62cd524a62e932e39d0eb2cc7db4254f210a70f80640df0aabcea7beedc496baa5f87d2a3be20124f456a1262990e93d1e850e0568ed0354f4128424504d600334278146ffc052846424e6ebb233bdb1c561709b182ec7a67e371eaefc4a09c650d7785c588455d3e5c6f2f0cf70799278a685419eda16fa0adc03883ecb9d71f53d3a353038b29fb48fd6c4c804b09e8be4de9f0749e18fc80065694ec1662cf44de97f2fe4fa9fd0cc32b04279c3b1a3bbb18924c98b524a55a7c5f4053bb65713d07dbcf74182e8fa8a7cb1291209a58deb47997b5fb5f281f6028515af21904215cab456e90c004aceac3e2a1757b8a8963d9a271a80e1856533c3844253679cc8f495dda6addbc98d8d8f0b1903b797e6f8d6736902e535e5d7084de8b98a98a265d60f091a0ff8f0415c654877ded29c9eeb95b9aa26abb6c7a21076ac8db903f358e94ce38b0adbe7f61714fa8c028340bcf92b80126181f30a082d88ac0a07c42fa4435ee0dee6fc6917dc0a0ad0db573c024d1ab868d72e876b0e428624964c952ef79fef55f85355821db4fe1e1136dacd26825abeef7971ec42509da3370ea5ff31971d5590e03de35096ccad299602a55047c8ab3485d41563196c5b4d3880ab605c73eb5eb8165ff5ee5473820e93e46d42cc71f700982a32ecf64ff1a565e58ae1a4649dfab17096718e6ff5df6dc059e9c65c4538072336a6ee1ab29d9138d017da1971335e8a71a433f6d13781bea4c80279d2656c0fae2b011198cfa13b0989e228fe2a8c29061d85155d69b51814235b03427276ee228c79a9ff8a3005e3260a942392a9b62ac89181456c40e9665a906e6ea42ea99d4a632c67f6c7958b10662b01541fa53b2e865f3641515d2a685d408db977496d8a610f8977abfbdd27d941c2add24edb67d0d86a7304cdb9637b75f1a054d228c600ff5466a4df03cf5a2b53c367050e8e7179be9e76e8946b9c3917d146c43a78af0756011af07245aa3d74c84752f9b0d08024c532b077221ee8e695d66e572a66042e65d47a505dca98578c8adb02f7d1c2a94c83f459d58f5ed936a9274805dc4ec5d29788edb8b6818d3108f0b73f733a623b08c15e176e8a40cc179e8371f04a55418fc081e5a9e9d2dec90b69cfb0ede5be668284e337c7a6cbc3209698fa366c5c413e3bc0b199c31409c729abef337ee7073b9b1e529d3ae0418054371e9da6979973be3c56b36e12c85374fe238865cfcb55e5f30ba80ef00d2bfc2c79022c8fcc31cb137c6a878f9969921d604ae98899e9d519c75d95171073f12adf00a2ae17d0940407ba4cc0cee2bc82ef564a87d5b0701df35e417cb9a113ced67f0af049aa5953c3aaa3bd40a5a8d56c8280c0b12d4f0a3ffaafae3503637c889eda78e7faebe83bb2b7c353ac04ad8f36c3d4e587c5ec1e0d63c2484b0aab8b297ccddaa1987d96be1209facf100166d11a7d17203d6950cf1cb3bef2ef2d4039120464f7f828f3f7bb99bf82d170ffc320f5f5bda400fc6a7f300e446033bc5f7ebbd4217d853f379fe1b197a3e1b3e02166f4d54394fd3a014b1ef6f3eeaed1cf8a538051b192df38f161a1afda14768b792c609e0b612c2826995414413f65cd5c6f827e922e8b8d5cdf5016dc62db320a212aac3d02a4c3cbd86b6a4381d27be74b4b718502e89886aa485784f20d6eb07a878886e2ced02a9f34d42016b8114d55eb0ce2efe413d6f0336ad4294fa6683acfcdb79520688fd7a2db9fcb9f3e430a24b3ef359467b858b3ac4aae79ec836c62184c2d666d2b1dc3ccc21db6dfcf566689f87e5872e7938524312c563545c8c7c187124f3dd1d4bbcccb0cb654d32efe785d4afa96f5a6ff9879ad1f93bea579049e46edab020ab9e30a9e8e9be68f76e2bc02c51b24328eb2a6d0a3bcce9e4625b0a9bab52b203b50fceeb063d898cf3184f400447443eda016f1874631edd5311134d726608a4523e091b7b8b7eedb22d9826274cf4700aef3f177196bfc1f92e1042be2439c77b4bbc1dee8e5ca28a69448a9014a1a9fd2d5d14b3103bd7cee397fa9d4e34f097f3491a49d50a5fe66e00e92942740839994ff9a88db1c00b8e28102f61d2e0a37e228424a33e8cb64024d34a8de220cfd2c51ba0091c2a227dc84714a60f0f9e4a0fc04cc852542216c5a756e33c914e18e3a297556ac19ad2d796e633de97daa53ed0d66ebb8153f8cd2fd01b197f9c8f3bf89805c694edf192fd134eb942f37820971df1bf096eddbe609563e7637891ef1ffd8c1f557afbaadc7de1cf4545647ce41e51444591b072431c4ec6cf094c2716c365ed2498a81a44f4f10314b15927dfea8c012dc089549f11800b76680a4dd946003ade35ac309a4c420a7517cb1399d5f8cfd91ce8e8d92dcd680b66e6dde5902a4f86df016007d489413689c72c2d4088f5535aadd953295be45b2edf2282593b14f9e77cdd4af04c2d7473b1d3b02ddf76169695ba6320271a1e0d33a00f50c024622c7f6010ece88e03e0e238af667af9d72582dd973e84bc5477593c5611cde8d79285b41c7096313bdb1431520acdae2c1368a2fa5fc7e2012f1d23d355c2bbd319471b77a22844af1566f668bd54b52b4500bd8887a037a843b747bd46dc97689bb32b00fdc518add482328b30461954db7edd1b158a3a2d97caa11059a1bf397ff81b971bd24e8ad96067edffbfa3093d7e9f34639eb5551f3d6e9bc1743d8d6f98a66c9311a14a86f761171f931200ce45d62c34341ff4f677a24b563309b3441b799c2d66b755ed84c571ac1a1747a8e2d460ae239814c142b6ef7d0f1328e11b620b956b5c5996372b9305d001ff4bbf6197fbe40f62d19396234191ad09cd27dcfa0a1410ece3a7355b4e59a6ec71da467360f0a80b9a47fb212dda2a3b2823822511289a69f3a48f6b913207d55a2735a07333f283287b4177c55d1a309be5287b23b94b4f30597ae7a843797dfc04d9d32f3826138f772116631bcdc1f0f252214c0be07a269d9f92e09071221d12e2f4df8e846d6265f78dcf95a07a6a66b2e054cb1f401ad7abdf81bc410532741465850b06d00a282c81561daac2a7945894d2e9ddb80ec7e84dab9c9444ec9a48aeb0bee07eecfb87b305762aefe45e613a62b2e1b5cd2125b945bf346aedb4f1dcb01ff20a70b9d55d445464330a0365ca78ef64c280c25e0f2dfd1f90e9b3dfb8255db412b2793cf91a914d66ee574d8c5481275f2ffc0bd20907ed232e40cf572f650f3b9b20df3c1da05cc511eb1cafc01f3460520d59540608d83bee506c9d49c5dae91f91cd4bf6af4e7ba7ca1913e0e3d22f3fed6f9fba77096a4bfcd09b47f26f1ff64785634666c682e0a2113af42955a70d68095e9567d8d65a7af37ef9d705ad91428222b88276c01a82e425c044cceb2e4d950d3109d1d1f0497bfa5308782de55e93648329c06aa7c4d0216142a4371d0ca5e10e08afc4eda47d343c37b63dd056e5202e3d397c0d212e66a5f1d50406d8c0eb047a8727d7aa0a6f5c24f27e3be894a262862960318f1e3b8ba8a44433f13932945e0108d3ff43439f5743501b415c76d031acc351ca63299f8987ed37e74d7b5365d9057d7fc72a5f8baaaf0b107b854887b09cf2a1c25a684211017a66506fdcacdf4067505129a0c93cdf33143f0cc6615644217bf6c9e21138174877b948dfba3fbef1ab9e99d5a1fdd4493b98040f186aedfef02e1be02e6ee091b958ce8cb0165eaf629331622a5c9705475faced7e17483e220dfa71cf2ae6b04bcf9ba76ad7f2fd8a07d23a8dac6a99ba8bfc929b403f86c64991af57d8c68d8c820645189038691069634454286100704555d647db9828d0007fe4409c9c35e1cb0fa283519dbd3bed45025b60a8e83c487025fca91d8e3e3d828d9a182ff331ebf1bf5a7244fe1edbbe172ea0af4ffa4445a91d168896e42b9f108de91866970c31b6d4d496e00d6f321c933781981aab303bddd364c6ee14978f6dfb448cb4882843516417bbcb6abb0d800d812d2bbdea9d3863af8d9e6af982d0f4e95a1d53ea25534bf23080f6077ca0a2579a5a810dd8615d6ed065d0981a13d10e0215410049c4f949dfc343736edaad8a42d443d0b0ef5b0a342564da2959dcae5d02014c8de1b16f15c0c4db6129e6bc1c1ae74efc756d3d74aa2eadf1236ba95ac256450dcbd78111bc9e38c0aa0c989f6c0d11169ce76ad9f1603eda75de1a7994705748b07e2fe33f707576c80983a3ab82d9235e63dcee29eace753bd8d2e766cb8966be84d9350bc082cb4f71db2e50c1912acf8766193de087a5cb51ae7897a423429b350e314fb57d0fdf3b7419d72c257df3587c919b6dec98ef14278a6c0eecdaebf830875e591f4aa98d9b15c99aff07071b1a98938496a230159b9bcb091b064d44276ac168268246ec19bd67d56453181b12e453ce92666d5ec0b18008d0f925f8188354108fa508834cfec3f84fb836fd40b3b6ca1d7915beb26c88ea44fc9c7de840d8d65cb149ac6bc1655923cb48c449a36e94c256ab6baad13070991588e4e61aba968630df9cf5783a7a0991a8593f0fc7f9fa01769feebb28e8dcdcc77b10a795b0650b956a94597120825018daaab3023cf6091bf7a9cb98ac96078f008731512a3caacf61e5f764d8a57acf0ee61661527361ead048be13be85ad95733129ab05e4d521a1da81f08107e2bfe8bd92533c9d8a756ecdf5b6b9619430b0fb5e4684d0260048bba35ef5daf623938731956b3eacf37ddcd8e268e3bc5351aa6b85367d7da0c0cf37fef0cac309182b6571fdb08775d887e75489865b6380c599551204a0a21e51e7cec8299a31180f4158b573c5cb6d3a8a3bd61f668c36f7337443d231cc60778b249ed011f3c5ac38142cb3e46fc604d40d33084180a7e4b128d0b5c89e25c439179318c088359b3777d2c4443159057c6c5043471bdde99710b04c10999538670a290935cbabc7a2129441b426c046d33421a35e9168b8d4b1b1c6ced3adaecf038539611e5a92bb4657cb937e775325d2e0b5953b448e7b9cbe586af04d7c1aa4442e8813ee399c5fa3a9f58ba7fdc6865bd27df63692294d041a158343aa41f4686de6c3e92630fd906b4c3b16cceb174e2ea7e58ebd7447d3a3d11dc5cff66820d6a0c7364092aa0be5bf0f8d6923bab94fe830956799e47c1c430c9bb6b6dfc9a649ec90baa78b2b359b288af9334259a3bd8c3437ed7c884fb94a0e5eb7ac86471d57f865326cb15618681198e001ac8822833ea83b2095fea41c8af99be51ad2c97308e88facd973845286a98a592e86f5b93f2a6bbcb72ccbe03c7c21009ed392c86cb1f97b056bad56aede49fe6489ad9dff61d489f59571c88fb64a6d7c2019ae3e980265cb43a44e8da2111a8258140c31e93c5d14503913a705a1c1e81edfa348e06d9c28b4dda02d98185868145cc43d72187082c388ace7e19ee9e2b30f4f18f25c9545830235b46ed5838ed0b2b8193b8058cc0bf5abe9b3733a735e2e61ad6a11e435ea32f77530455aa65c06be6d1c74b9e9d385d4be1e41856f62df0cff507ef5f99717c8c98ee151f72a828472a17e73b66c303054cab0965aca620beb0a43996cd91427081d585376c4f04f58e5f74387aca95daaeb2130dbc08acb4d9b81a4f98eeeed61c050bbc0e59d0a18f9927bc5170e403da59663b295e98a1797e5434df7d8cc39f785b7492fb31a65b4ef8b791f26acc252111837b448fef81b9bf0e6d24b9fd718abc11dc1bbb103a5643d45d504b467364907c7186df40c585352abf72519e8c73abc055a8e44e4d0681cd89dcad907254e84ce83b718a1b643a6b564004b9eb36b7340e834a08ad0caecb1f2576c400be6034647b248d2bd3f8a7c6b037034edf8fbeff6c3bd04f3e952fa3d0bd93673bc332b1abaa31b2ac2792fb742fbfc6d477c02204423ea1dd55eb3a0e9acedbed6f182dc80747f488a4d9cccd280f6355226e6e0473f3805489e77c3ac8b832401011f97b6283996d347e97f98d8d639e1142626365a3f186eca5da5a39712ac1ff366e63f74e8f5c4e13f40915f3e1fee2add369bb880ea668564c2d1748035a13c14f42f65c88732a26859a8fcae53f0d84c593fc8d9754df6639d539cb612b90e9ebcb9b0909caf258aa70fccddcefdfb7e12bbe4d9662936922e31bb927817be35362efaafff252f493f97580725810213b3af048ed0b1089729f1705dc2c1572a9060e1314454b57bad6f3505cbbea99fd98490fb88dbaa56ff2221f6faee10835f6e4584e8152668d1715677ec9c70bac658c2dbae6a9a8f01e6ba59b85df1cc63c0c893e04faf53af156a76bf77c707478cc177b71e5f90f9cb422f1428467b6a7c812ac44e81a38c9cdf192c85cb74c727bb016f9e40385c5114e99bc48d5cc0fa09cd763a9d80b5647ba643b0d85d1e288954c35328f1647bae4a7915db438f2f8e3f6d2aa88718ffcaa62af6cad51d435dff35f2d98c61ed1ee68399e8afdbb60aec14c7baa63ef8c38b03110d8fb44b1c5e9b293cd10f5bb0c7c3973f7ca907fdbd72ff83ff35011d0d1029a63110d1702f9d7e61827adddc5b1068d4a3879c252e494d88c7c0e1a77a7df12934e405e00f4e2145990404c44e284bed917c65a083982e55463d73ee058051ed2b5260c501812236ed8137268cfddf25e5ec40b74cacb8c2684c0df7a19fdd7df1346813994b61fb52800d5cdc878571b448da9320894a8269813e96b19fd3ae5a76a4990fa817caff7b9521724243f889eaac25cc377d6df64c9e501d8d44b30f71aba685f85b1ae9857a23d133cb47196b807d4ebb8766936c28bd58d5acad1ceb31cdb59a6826f25cf866d430c3b34af96d174df7a6dfc252cbb0dcf5fc15946a3b3253380be242e3e40079cd26d11c9e730ed48043047f81bca6523027f88a364ecd66b2c083a3dc3139907225dc66263da3513e49bef5ae844c9e4ba4abd3a2ef82f0c31bbbdff516f9d879bba8a8ce59133464d5043e1b1101a552c9f29661e6cc3031b478bd4e1bf7fac6b79e6c09125ce59988a7d1c1b7c278ac13b79f275fe53c8675a7509e6bd4ab87674206cedde3e9af682da4c76bc8b33292013c4ec41e5cf0e71b5becfb528190b58832fdcdee718987cb6ab679bff3d31809e48628a7269abf99e4ec376cdba18aadb642c990f12d3a017e0d26c617db836d2d0296a36cd4fc189050713c7bd7963750bf1059b73b1614aafae80bd0c6e2552abbfb352a34f2639499d226177b22adfa30429c14dd992354800c4b451a374f55490bd6d02d03663f3f0da91fb52c671634ceafb7b7f3e7499c3699c130f75afedc1ddee42e5940f73ce5463f96b857f0073f31476dcc42929adeeacf672f9325ba53c189fe2ebc162efc1a8478fdcd805796455cedf8ed31e87b932b751b006a33246cb2beb94ebe44a9257a5983fd1a9d9f317d3dd10bda11438323283335bc746ed4bb74f4e3bb98d559d000d490ec843cfbdd7587557d462f09ed0620f52c5c6fff7c54e4d593c3341f68405791c1e9b01ca233f029263ce65ea386b180f1e7a9cc5eee69154479bd017484f03269e4cd7f60226e2801227012f713d6abea192cfa6089383c856b4ccbc3c3e3845a507a5051dd9be7c885138d7a1dee1dd6afda4d84aec3b7fbc31c6232af11234b3a0c95c4e4a4e5cad9b56b8b325d69c257a037f38d293feb77a59c1102504f5040612f6a96cd6bc5ea000a626249aa85d0b0fd854c68217e9db8b6e0b1fe833d13f5fbbd6b0788e64961dca7c6a9a362aaa58d508313cc5fb368dbb57f48d9921633a92256bf49a13e4c00369f7dc4566a66f46732945a49baa75198abc50e170373ce3a381cb3bad4b040285654572e6c8213e2d2b8b4407160d4c17695a5d5d9d653b16a12e39ba490ef49ca9c075f2e01c701f725a5198095803ef4601ec5432026c8ed9d33dc38ba021458c24323bfc2345e006b5b029b0434f28e04280ed1443058f53228aaa314cfd1918c2abe80c4aae3f5582bef8576e4ca7a78912fdf9be2ac9d690852cd504e07e59c8faf35bca2a785417339674292cb5a19659a8a98ce9641c48c35dc831bf61d24b09c78c2b67abfade50ef405c288b036d6e4cac9c1271411af959235f602dc3e4e7e882406110f4e47555b44d04e788956e33439d81f33e5c318e1c156e148c10e003d6008641c26d0593cee1282e5acf7dcc4eccee4ed4b36b48ab3ed1b274046a83a5f102f808aa17062dec3324a1e1e6d415ee1e2257f3f93400cb5a6efc1bcfc517024fef04e0a95b3da94d40aab810f24943854a10dfb89b9cf9d0d10fb68a61085800ba14581100af53c3c326fb103c3c9ff012d91db2d44c31579f29f522175a470c89e8adc62bc1a57113839711395c94188003edf748e477550387d636b3f04debf1d65c1974b39c75202235b2ce9e5c5743148224632df292b88bae45c77ccde542c9ca16864ebfae169e04da5a365b1714c72460d4d4203e9385ac86be04c99b090bd2a071e28570b2f71a360324c0357adbd7fcebc8d65c1693c74956ea85bf6e7d823c0268c84ce6a57c7b48e23205e15bd2a68f43606ef4e8d3fc2a1fce594df950c95717af73c00c845b10e3e2fd1d168bedd362759654d113902de61c25859292b152529cfa200dfdaf6161dd96585be5a6dd9ec6e5decfcbbc5f78b99b18b9481fc8db9327b1a384991109d01a804f38756aba10baa0324c6487e339fe2b0db6acdc1096c1051cb303af0c8278869ad1439702bca63293634ddac1856f0147b082fe6332ecad08829f34a72cbcf969c5a24cb1dca073bde74e0cfd183631dbdb1870c0ffaa61d82f80de0c6c4d616a3117574a82809c06a4883ca63e0314342550efc395355540dd8bb8e49c844818784274bfd86465350a8987586625e41bcff984f6edbb440f1ceb42edf8c759aa184f3ee9fd0f06fa6769f98062978f7438d36e72e55d9ab190ef09b27037e477193157ae7b8cf9e808c3bfab668ec1acaf224cf21a41ae7068a34c2bc22a518129f7794f966369dbaf0984c3b4f88d070ca32d4b988c3a18d7bef087233d6ec03cf20d768d41c5e1eca012e434aa1412d08026a5de46c24cc370f8d387030657ef46d4e6744f342070c77771be046210bda3e075d27a4626f16e6a87afb45c95c524aa536f00ae2782aa0915cf5e3bb038159038a58ba5d1824cb04a237d7a94a842d3bd075a37770c7edf0dd11b20a17fb12c05a8223278d57788109a721b8052b0d3cbed9eac8c48e4ffc83e97bff6a9b184118e2c09169e79e16881127df462fbb4f581099a6031e7d8380b9f5499640dbb1f1a445d02d3e9450f96f9c8a5b43eb4e3205527da9fbc799eb5597bd8c761808add79c2e59d0a2161e02f60bcb96d2013f78d97a519f5be94a7827ddae8f6af915671ae50716b64098a2d9b0e309d7158b269248dafcf3666c47cb08d52854803e6e20ad4173e1d7a683d63b9b487204bce22a2f18a2ab87f0a44fc846a3e4c728c2691caa226263b1fcd6a821e279269d0e38ffd30d852947008a180bd1ab7e431a8fc83585c8d8968ee6fb2d6daa3f695837eb558064ce81d3e4f23362c7a30b8def0e1cad6b527ada0df038ed347461d956e7fcd60a7c98bd36b3021513a403c8148f181c03d8fc3f04cdd2b8f8e4124121c408f9f8cc945ef9169c0c8bf072c6826823242e077f2325d6dd0f5de852dd2af1fcfe123cefd014de7237839ef4ae393752bfc43bc6ef06a2339046561c81a5026660293186a703631fe24a76b13323b1509dcd7be0ae1cf6c6922f8013756e8d71108f02ac42473f21f80d70e710e3953f5f1690e22bbb3b8594837409e3eb7519699ede13d5ca6b0aa33765c198d4c0180b2cfbd743afc36777a346276e9fd27c0fc58e10dbdadf3cd45540204d718cd52f8d87313d44fe9b6e9993e519127981878a32203437695f21a5d421d01a8a5c68de7c23042494758ef5d344ca8c3d063d4cb9a570e736ec3e824f575e5d59093de70b271359c5491b5997d2825a5af0112b89a96897d93dccb15ecfeb0488b83d0f731cda2e920e388728daea48b29a32b1adf517079f3345fb296e47365df70aa9598a735e317e060f8a9eeb5c2bdaa2372c3bf5bb2fec4059703a62a0185f0cfa94cf734cd26ed49c06f7a2149d0e7eaa628f588e5d5afc74815b24c04d3e0d306e0ee0a4954f2290d94e7163d5722252b18561f1f5c1476d6b1d75d000c0cf8de0aef25ba24d976d7a7d128d4e2f9b1b41e6d54d5d5bf9397ceef6c311ae8b3a08fad0dcb013a1424a22a65bf7de311aa487bbdd42e7d12797fb46016fd41de6effc87ea790049b86cd186e31c56c448b8554c416482c96d423bf7e449250ff8f1f35d52e07b3188ea7379df6ec42bf30129fdbe06e08eee3481d8888e43ee481bca4363aa6800f53f4877e2ead080625b3e0bd0c71f16640996830d79e5340e91ca80a94e565d94bf4c8134504c581b878cf64f3e87f979ebf9c6a8858786e028568580422ba525584c8b24ea4711b217034fbbe97b3aa73824ddb74df7baaea1fb54b7cc6659acd7c2df81ee5b88c1e7e6b93c82fb04af84b5d583e3e4cb2ebb9a32191397f13b648140cb165fd0803256269bfe1d4020e0c01cdab84f30c5d2b11d43a57c7c3ef5747814508607ec20ca4645a1a0a3e2445d96ef6dc5f7ec5c7c73a9caf42252370b34617b92974017f9924b66764b4e4ecd2fb5814afb2dd413a8a9b12183ec19fed07b5d3839a2643229051139805de8821b962e301161321b1823398e7c3ad40cf155bbbe254af605d610aa6b9f2635b5c065c443d515fd49594053ac6d54ef8875631679637d65f12cbd9542812b57722090da030df62683e30095887a65d7f4e28219f3ed27bfefdab21a31b1665fe59101154698ba9327ee232453eabc5cf943d7e14e33ef703e4b00f891b0e62579567ea8df6063588001fc8edadb34c76cc8f49fbbdaf152e5f60e11285d13358869156283211fb0dd002962200707290494e6a6d07fd22cf3888e40b44d7f8222df9eef51ad11a94117a706c241cbf573f44f6fd502fc345b68cd12ed202b8b89d1072dcd76855a410c889923400d1f68ab640c0ce55e27d8f1e5dee76480523b45abf216863e158ace23579ac4fdbf069fab8476a3afc580859d170050d2d39086df7be33bda9d9881e7a788de0dcf7bea40905a6bca36bc2d04dc81d692a5e11a7cc3a6a7777731c40651a2b5da7acbcd00680c5d476a74321c9fff4ff3085b7eb36103cb0bff1e9b38d0e398e1f9d67c22288c1257ceb910d0f5942b26aa0e31b08bff4c1aad1cf151a952ad91ac6889b2a79e076ac00df04183578208305475e7453d6abf66c03ede7bd3a9bcbe386ec8b3e56e5b3643d97164a06a4e1e04ea7c6b945071fd73c4e12275384f4fbee39271612add7343edcd19048e3dbc72cf78b90bb2927d989274122064d39691326317055439506bf101c5c763070f87fc5cd8233b1c229fdd02a64bbf2792b86d864eccddd7c21a133846ad737deacbba40342702d3ffc1e8b83dd2c273e0cd7bd2cc7691dd290118a64c3965e1615df8bda12fb1218f3b5a0c9f0f79153f4e4590436f6311a08ee66044bd8b8a534c674385771d0d513fcef14b43098489126497774c0ff59ddd5de28df632ccb1a353b40ffa1709a40a073b303ddb557532422aa850e31949a768b4e7603cde96d075c87e492d291418bed49b96cf69e3c651f33247a5e9400c698bfb665b3d5a4addecee71c0057c84847a65a4b0af2f42660d02ce4a8a8c907484038ac40e43092aa4d050bddcb00afbbd70b253bac8233b753990da2223c17f2f03354f4778c8fd6d8d8b1f43c2b7c02e809c0ad65822e5b1688c1f70f0685d0c31742c2886793bb122ab3cc047594d387930b10adfb88ce10d84703ddb75f393dfaa24bc903643b889611c7b03d9b88faf7060b5c43ff8464a42514c8237f1d8fb11bc6c44ddc952f56954350945a02a4fd537c9caad27f120bc8e3278f91bf2b68b998991b1955f374dfadf87a978aacf0fa253743b735678f36bf52b1ff1783f92589e1394568e5c7ea924048eb632facbb07aff3456fa96ce301c4904173ec82c728007a2e7b9402e3ae81b1fe51e980cd41b5b83e079181389507cff283a610c1d4b0aa06641344933bcadf5f6248acdba454bb054066aa3aac8f40a4701a20ad8594a6fdd14a6db03b961347f407058cce7c18cdb50661b842a081ccd7fdc0de7a0f4428b37fb09ff1da08e912d083ab20f3e53fbaad162aed0f8bbff263bcfd34978d2a78e08efca093ac15d8011337bd7617c001d4b5c45253fd83edf9151f59b9b280dd531b3a560b21d2aa37c77c9d25b83a343b993740bc5e568e49f22546a8599d622874e276aae802166b2583a5b5503cef5ae8f1af4c6e5e1314be8ffdaa512705cf7008f849a45cb4c473585e6f892c06f620954f76a077b3c92cc62ca368f2de1847a8b96d7eee47ec584bd8514a43f8ffab21bc07b41104daeb82995c30ccba9a0e251d2a102168e36481dce2c0d163f09bf18284e080c6488505424ba5c256ad2ca04381c9334548b60574387598b96fd7f1d76954156f4dfc445d8b88ed585ffc2104c7858e5cabde0b8da691496b7bb735b9a594322519d9095c094609453b64fad3484b9e93274b261268594af776caad6e49f5bc77ded7bfec7c4dcb4442510f0da81f5e8061ca0b9313198511605831005330a165cc172699116392e4f900f0e1872ac44801922d26808225082856386fd4336008c0194c9c0126d7c7e027063450810214966e505a413a0d71c39c73ce1e6f68ae7274ace8c24486972a5670c40a9acab0a18c33c4389921e50c1472fd1ede50ad2408a28647ec124446d1d413793e8f8e183c5480058a29a35c7f07930a78c091eb5f20450aa6b0c01baa1b971c1480494111b97eec36f9114956cc39e704bda109801e39cc914222d725505084822272fd1d6fa8ea3821b50206b9be0e6fa85a219ca0c97133986fc7c832c60a79be8e37346f5217343806500031a41003863c1fbf5e4c4a00c316585280c20a098510355b2b7e07bb5b8c10d4e4f99f373473c894084396411846e4fa9f4385eea28ee45adf460d91ebdff0866a17f50421b07202a65cdf863754b7271d308ec895e96b784375b3628a1f2576f80835608a57a2162f9074783145982861b6f862875cbf07e88b2e72fd1f4082e4784375bb225a10ee00a36403cc152610c204b55c1fe60d551d1474395dd472858a92ebbfc010e5fa34b0121266b821072eb40c219f20620515ce1417f8708145174170a143aeffa242b48af7755dafa09ba6e2eb17242e50f8c224d7b7f186aa1135d4787122cf7719d9e450e143835ca3960aab61b8d428c68a14acb0a28b5cffbeac3023d7ff2b9ac8f5412c72c8f57bb01893eb03d5b8e4fa3fb21022d707b294450a725dd2e2895c1f842d74c8f52d90812d98727d225e6878bd6aad482899894133edcaf34a9729baa45053830e1722b0105197b8c872ad5aaae821572c5e86115dbcfbbaae976b56c18214797ef73a620bee36518124cf5f7d3184956b9b9e92c8138bce9309b9d65a6badb5d65a6badb566b92087ae297c9862cb0979fedd52459e4f5f3f905133a3531679ce295158b5d65aeb4e9e45042db1f7058ba2498597164734a2c832bbe1128563b7486293b76d73bdb098820595d78d422a494d97292b6437d784992b8b231b1750a0a9c2a866861566b67072452992a935d14c79e1621135c3840b2d2e453258acc0d262ea66f922ca66191343b785118b89122e8b266f04ab2b689d9621544f9c653a62b718ad66d32ef1586cf2c4633187f7554bb2802a9cc25861015a142d69197364015434a9b0002b8ea4a02149920287a2055cf1248514240be082f4399a4c6dfdb295564aab8e272e8d1c9762b872e472392ec5c0c50a3184912403d113198a7ab85549d365d174b020430e3218b1e446278ea0e59d2519a05892a1cb7dffc273bd9c80b224d39f5132998c05195680a48b4ed470845ad0c2ad39c18223eeab091597660af874594a607155392e359122ff52932b4ca83a4930189d48622ad31c645cbb45cce8da1c979a7851c495c971a9c91832382162e2ae725c7292828e14eecc71c9c9121b392ecd30460fa782eef60ebcd0c20d2fc8eeeeeeee186eb6736d312846cfb12f6b73fe25c494835105827e3ac3c9184252b6a726b8ddb382843d665cebb13e2342dd07ab5f2b16c27a0e17693deb8b70dfbd11211ae74cfeb45e7ebc2dfce2aecc7bcf61ef693ecad8ccdf6dd24209667e437ab2bf63a97463c60d6d035ac8fb8ef5716db749eb240eb7928c612bb7f3be48eb65dec345baafc1600d4c9c47642d066daf3c49c8128757929125966164f9f3732207392ca5c615d785a5918cc999bf1f8258cc602040637ce0032d5c448a90d6771f65ec65f007baaeebbec320f88005eeb7f0c5edf4dd87f1098b16b64464cc7bcff3dec320f80057996e7fe8442d2ca50616f7bd0fbb080bcfc718dc772c25077fc95509799f0ad75f853530a5d3978bc3885b6bb88e8d3c87e0affaf9e1dce0aade5ff5dc6c99a3acfdc8300ee563c70e9dad8ba1edec6b2a064510f42efa916c21f9124a3a5296b827cfa2e8d2684a1c76b307190b5142f16f0ba7466beed3126ace6613ffc148618ca498299b4573891f492319258732cad1e752554297e240f553314b563df7f50bc17f72d063f2064b407dfa1c547f0e749e2a2712e33e2a1c420d679e218ce0b92ec0e248bf10fc371a427d7ffbd14b802a048b00bc7909880e4aa9fac54c9b62507de95f8b3c3f93c8634bc41f9985962b57644d8350d67cec78bd646454d39f1479d8978831f95934451ee9a59f6a2a2b8e43764327f269244a9e1ff3c4b52831b2d6535ee38c58ff1870f800e4a5c28d1ebee1fe7020b2d25aa794524a29a594725229250754f5616cfaad1be2c2ac94db263729e595745220b449bc575c07e2df06af136ef430941b46a60dbaa393d2de6c383d95f3757c839e5a5cfb405cdaeda3106c73f78a9baacb7be50c0264851b9970dd95ef6d822c4109b61792bace1b6a2d0e7abb3bf548bd9dce0c8c9cb41c4d1a35256530dbb918db5dab238f1affc3c01e5f7212931d6a7af48064d2069bff74cddbe994d14a14145d249ddd1435e53eb2a1c254713159bef5861c07894eb20271b3d70f241079e4ab96b81209cba317686e28f9e3a2f93c8aca55ad7c48f58ae72742a41f1a41c24074caa111a41cc2fce6def5c1fc6dde8810cd07f3a22330999f79966c72c1904fb27cf9c47d4287923469e4a054d17db9c47dbc972f84e65d2ff33580e65db2fcf120dfb12bf9fd9c8a741a6e3515717dcdfb27858585b8de0617b179d7d77c456a9ee6af1897bebf74288fa202459372b0dae028635d83a3941bcd93311eb974d93d329c51a8bfd0a964f93964dc501ee121aa57492877a92807a5fb181c675cff469247625c9d12ae7f9d5df9b11eb9f263457271686404528aecb8a37040b961877941b9f2b54c18910c4b40e71fc8c854ca96c1acb8321ca1e6f72f00cdcb775acf644c65853e31e2b8012021414145351d4509239dc8a14b1d4d41426a922f9f38b9d374b8f2639634ea94ce9671b21286caac84f2c88a54b7d42487b28b4c924c5dee510cdab23c8a729fbcf84f902c2e618162924eb24ba52d619dd454a46b4992f2a89564902ea16a209157dca71fe93aa883918ecff151e76b212ec77795acbd5729c7176b2c71e5bbcf741a89ce21c7e74daee40298b4d3f94c68a1300ecea8e9f704b7a1ba269b24b9928d25f746de799d0f811e082e4ebcc0c504a83184e6cbaf6b2e80f939e6ebf86291ceefe0225284e4f81cb888fc4d8a101daff345e4e7f8fb51fee8e022fe3a709431d6b33ec71765ecfe90b1f96ef3fae834609f63ff7e278536bce12b13c1f11dfed5f7aaff1b4f3f4aafc6b79e88fc71190e1cda0f87afc7e1dfc021986de01a3804ca3fe48f7b7197cdcfc1a187c9f36138b434f00b872e26cfbfc1e1cb06879228cfafc1e1bb300d0ec1192c83c39efc6ae110c89540599d5f2beee1121163f3ab402d912796dc4991677e9ddee4e0fc39abf48e945575be28e4440e4eaf1263f39700b1e449c5865d8989eb8e83882b8dde5949465d6ef8b1ff2a03c04028f7a7179e73832f8932461bc1eebb1122d87d47c4ebb82279f52dc580b2524e282eea6c51c6de5e4e1d392bddbe5b750772b95b712b1528bd0d883ba3cbfd2d3d9244942a35262644a13f29729f965522134d2abb90ea48460a555fc6c9eede906398fc2f7706024b0e5545d51bf24ee6606fde90e3d8e28676ca4e5931d6be5ecf7943931e1539d81d11d20d3b5957f41a81aabeaf2bea64f4ad980fcaf673fb8ec83b99fb548fe2b1d9b9937545ee13ab4a36e52086bae12dba45ee538418395415d12197dbff70ba750d1c2e4d8e5bb68c206ba0fd48ca7268a537646be470433f72cae176d4e3847b73e5aafeb574433b7593c4a54734949472d8c972ffd1a447b9df33923f5b918cf51fe5de68b93ff490727b49b99f4611eb4b0e3d2bb228748b84b8e1565494fbb7221bb7a2dc5fa162cc63ac50381c52a1324c7e14f2280e937f24e6fe94e4e1bae34e8a314a96c450b6ed3b6a2a777f03a6d086ed94dc8eecd496d4b84706e972016b2f2d6ba5a824d418e6452fd418d64d2e112b640a3586f513b95063291c44107463c08893a21cc470e1c315412c49117534a3a2d4b049c0095210484b556c01430b162b284e0006892701133932753ed0b8187f36b757c6a8c521fd4ae9eb65ed638b438c514afa93cef8515c8cd14b8eef4a3551b76337998a5a26b65de692f27cf9752698fd5eb38836ec47fa21e0d0beea6df521752d8675509f6e1d1ac9f439efbc0ebed0089df282b813417ff9e188608f18f3ffc99e43c38716f24608f3733831ac83cff53fd74975b044e83179e27f9593ab56d56e5ceb762c4f86c635f3381fbd211a35df3eab5d754e62065ef4688841d5d5e3a36bdd97f9f845dc87f5f17be623cdc7ef27add44c34c2d6f28adf556206eda57bd87cd84b3ff149e0c2cf0cc949f48f42d481e8df474070086c890ae81efea01733d8d13dfc77d830176af310503b281a384d5e5e37b89b6c70e85e831baa9110e0b9c6042e9a9e4599cd198f95813e12f552e6b6820c6179386c31de6db647013d3dcd75d4d7611c7429f7b73874a2ecbfe1b0c5647f2f76646fa8c8e30ffb0eaa280639ecbbbb63b7fc09c31d06aa4a4375e1331c9791eaf999423019ea8e0f2304514970a92d2185822c4d542c2b54289c4890274427011347d4b6265078188e7208eee8f172648261492da1d229636cc5e860fc5983129b5015a24253889b1dad1bcb0acc4686f5aacd93a492c478fc8ebaf225c7ee22c76f2f3108a78d9cdae829c6be32a5ca94a51cbf9562108d8f4528e49824472639badebf9fc87cd84744eda489688841351f9f7af6145bd64443c808139f480ceafe87178f31c6da1621518aece4b129c420c7171283bcf701a44190dc9175a2df9cebcaaf0ee7a3dfece2099c4fe626314a5d3c71c3062c49eaca97dcef44b98bdc8f63e3833dec6dfc8d1b30182ceac6d719e7eb6c03ca0b8d8f7ef3937949889c1a9fd3942a35a4a7a51a9f8dcdc33ee7b9ce1bcab1b1b1b992f375a6f175863129d1f862c6e9dc45ce247751e4a9f968cd376b3e995b0437af2f03dd4e723f95dc35af4fe665dee66f6e6464648e6ebece355f679b36ea2691a7ff8bd945a7ccb532c098a1f9641f74d110329a06d5b35a19341f8bc5adbca119160bcfc88821e27d747a9fcc718ad6931721518adc2fd55bb2773f554b019dbd272191a7df931ff50264a7ded413000d72a62a4f0146b2ca474f4b47d6513f2ff7fb8edcefad93376fa8d6ce5de4e98f3987e8f63bd9e818153b2bad95ee94e0cae4c8d40253d1f572646a61881c2a6801e97e0b32b8a0baafeb7a41c9335a700188abca91a98523605a20daa1dd9a239392339894444d2f48321633a53b3f5c1a53e8d002450e9fcab53932295122ef38a14409dc40491253922472f83d3d4877f98fcb63fd4aaab9b13c57c751a970707ab23eefeb56d64655b3727134b6bb92eb64951b9098251ec113d063c68c19d31eebb65a57a6a37165a51c9d3ca95743bd9a1ad652afa6c6b40102410bf6006d30326e38694c98bcd1572f8f4e2b99ed7dfda42c20dc6c09c620dfe13e1debc8838100727f3880ec1d1b87e6ffc69cb37538295dca28a594aa18a5a4966e73d6bad139638c314629e5cab9961de99cb3fb557fce3a65f458364c5c8cf12565534a698cf1467635b8bc26add1c53bf2dc2e8a09e46084d9703d3796db6fc3ed0cb3e1469b29433a5d730c4ae30ced628c118740e594b1975295ce6c49c97594524aa99452ca158beb28a59452cab1ba19b59aad6e46a9ec94895bcf50cab9bae8451c4ae0ca6ec76f88ce53eaea62e49194524a29a594524a6d7c8cbe2ddc7ef9b4bb439d1c256aa5b5ba1cc442d4248fe058667904efa93c82e777106f5b0e558ed5089ee387f5e72aabb6ca7539e2d75a6bac35c6aeb6fa7632b5d63a536ba5b17155cea69b33da5a9fbb795557df7412a0945219a3d71fa2e30dcdc773ce9b5965f64c719a4637a51ae6e4258fe0596a86f4e5770f05e7e33c75725e37382e53029d9bc5e95577f7a455ca2e5772b9b252dc45b3abb8928a2b7174b0b3a1a1abf1c2d0b470984564ae6cda9a6290dd2d251829c1483926090d5232f13061e84c1266d231b015b88a3b779e71b13dc33a885fe414814ead9bc579e5f8bde2b8ef5b71ddcb7d54acf8ed31c8fecafb4ef515c144ba2d534d42e4f1b7dd4d718f74d11204c82c71cfa43062510f37ad9b5e03a4d00a379216aeb3e96a3c8fe5b2400d04164d6bc6a99b76901ef03a9879cadc1cbf08526e26d6cacdd0b4726a60d5d874d14b6edc9187bacd0d2701073f887315243ae174919b9a9a542a2f9c4b94d3ac553d7d57c96d82e5745064efa6d844ec2cd97d065a4e8dce02c10a883c37861a366cdc90403d3d3df267c571dfcabfb8f118470caa407afac7693247cca0a3ba87bf183b56756b50345f254d164af4a7adc53baa33e825620f7f2f5d8c7237214613f7e1d078dde0ccc701135bc1cba8f20512313098925049929464ca28989220fd1b4d773a414b122c2fe2a27325994cb66405160a52b49294548832836486d73243c76ab574726b47abd5f25a1f8fc8ad9f2d26246372eb6f95dc6afdaf00456e3d8824b7be87052772eb8156c8ad99536e254912a3cf67cff33c4f0531d93be2c4a4c2112ecb9373652e27733f392e8527994ba18bcc7939ca036042a10935b273fb28c656837664ea23533a001aaf6090c3a8a50bcd804ad126f2c9611fc9b49768403f66c994bebd24a420d37f2165fa1f0231327db0042032fd9e12aec8f481984a1893e903214acaf48310a520d3ff000428993299e045a69f01fa44729089c08ba21e32653ae14ba64c011f975799f33af9a9b2cd5cab93df96b9dbc9af669ab9998e867375359d8d8b66a6e686151ac9b00e6e3a37f68091d92ea6a38e7bccb9e1c69f2a748c1d63eceed8dd91c6ee27dca42f99f8f4affc22209bd33d467713b8f84831469d3927954e1d989c2955b6fb72e5538a6d94f5ba125b1d816a256537b74fd2f9d58f66d5eab33182f4adfcb939f5bd5a6abf036bdf1b52596c75b0364c4509d9c4001de3733b5f1402bf22345000e3884c68e7b92e020267e14b91d0055f040400e0e2284a28f616c8b80fd991675ec6bf70479699f91fee9fcccc476f68c6a6c647cf068d4fc7fff0170a3766fcd6b5dd0be686b2c88fcc8e5a375afff26f73ffa68efc6cae09c1fdf79ca9c30d5f5eebe2e0d3d40d250ddf7cbbbe717c7b43aee75c2e3a66cc182c3947a5aea5399af33b1ff70dfe0e88fb776cb8709f06ced30f07e77f382725c5e108343ffd6cd89367ce174aa770484f479de04a263188fecb071d72c5a1acc1667b4614f9c4084bda279b3868cdb8345ff3f6551f4a1a77b3a972a85e7a43aa8ae36b8e987138def960f279fccecf0f0653bdfc0dfc602adc001ebff330893de081779ee7c1876dd8039e079f0783df12fcac8c71bf5357cfad6256e178ca89f023cf77bdcb254254ca12873ff2c421b85ec7ff70ff5cafc3e70f77bc4d11b6ed13c100746772b223e24ad294f6297d42975c7243b90ffdde41c096a964b1581deb6547955a0afcb61b9c100115b42652fe944e93d2734fda6c311996fb6553948a8a4c4952b925131130e4502a5dc9dd3fa52b2146892b5f02259a6c9c4d173d0e74bcebfd73fd8effe1396f9f03df88d0dc79f085ec3c08f3e78932362516b20373ac0121e0f3e0223fb003a2101019eb0fb283ed86a5c03e0af1f0ce87bcf20f5fcd6ff5f60b3fabb0857d21d4bff987b45f97f375dfe3e3b103fbf09837d46117eb69bca1d5bbbca1ee5d1feb7574cf7a6ef5dd2865afcd9a94a2ae92d39383c0fe90f31ba1f3dc70e0f78f7b9a83c3435e19c7db1c3d1cffc3c31c78484fc6f1f83f2917e7693c87f3859db717a5b1610cf4641d1adfde100dd8f7309d8fded01724e7619653b9761e076f3938b4301cde1756816190fcfaf971a0f3f7fd0f7f7da10e6e3d8daff307e5869396fb713c1ed293bf9f1dfe6cfe3e188eef93dfde3f27bbefc3f1850d73dc0135caf4bf8f59ca9c9e6a505153535150b5272737f223a424a5a626a524243f8a9a729917f98ce6349f4d452935393dd5a0a06a4f4e4d4a3d6b5a1bf511525212521fb551d37a166b112a2a6c595117b56c2aaa07282af5e0f1f100b953e6fe87b7de88833c3c7a7c3c3e1e108bb0e5b033067a3287c320f987e3577d18d85e7a43f8fffb42780cebc0cbfe5ef6778c819e4c7108ad973df95b2663fd4684769e87061c108544e0de0151087c1eb8481110708fdf791e1fde1e9fe411b66ce7a3d08e0f63144f186b418840bc835fd25a7eadf7aff53c1f2cc88e8771d8015168078e3226b4f3300f5a68e75b6807f74cc65a166b29b5fec6e79f94eb5fc36dd4a851a3468d1a356a7c9d6dd8f8ba461b19b9769ea3f9c2ceafb7f9866e705e62b007e855bf3dad6559a353df5ce539387cc1f04603d315b698c3385f3842cd37ef72798d95351f63cd4b0cf6b83e04ba71bd7f353fbff0e6dd1baab979aebb1b8c3d8cc76a5c51f2d1915f71b05fe67ede34d4c29ee47ddde746df852b4b9afc89427d5434739fb02ff87c890ba0df82afa75c00fdb12fba00e4e7448d50f392dcdfb289b4b966881b4db511c881bff33e80b2a4d5ecef3407dbc886eb4d6a9fdcf9bc04c42758c88edd6886f2481a6530cb270787b8b20a491483a2fc96e1953e2e254dd27c892bb32ca72021d9194c49c6fa618e3bc98ac4342d4edd4a2d3b9a328a6a1a54cf6a71aae73df6c41028dc3ae8595681d093e50f395718033d5985c320d27654023c3066cc18a7bce1213de0ce178566974b8b415dee974631a8c34cf9f7909e3ca427cfef28077b4ae9facff61026ee2929cfe17243497bb2f3f40bb0b3f30dfefc064123f7a118e66fb37fcfef89a11c543d216950547ac8b2cbeca79def0989bdd41cd4a1a5fcc7c378acbfa71c3bd40ac9fd9e42eb3092d6500ef63794910e9f8018545219e5766f6dec6926e647fc3b3c947712dd34504a95a69cd035ed0195e74feb2428e28c07a294522a71f28422cf773a060633c6488113279c7084a48288a93a43539e566a92ea4b511493932f96cc4878400b3424478c9824c961f60025494c3308a1e40149a03a147a3607bfdc558e4b4a4e782d2d51a2134ea5ec7ee3c5f599776f68e667e48cfc5519575a4e46e6391919ee7ee190b7ffc3657dcb71975e7ae9a5dc8febe387b688f8e3c231c65898091a6c25bbccf159cfd18ef51ce775ed7160bf22c929e57c6eca29e5949999796e662674654a714711417a1c788e52463e6c2e711f9783bd4d23ff79e43e51fce72c923f52d692fcc9bbc830eee332647feb0d61e9bc8aab57e6b8c8bd27399555197766d673fe0aba00c8d2822c71228e3f4e8b5f0c8ab97b80a4bfc45362a6a46c6aca5a6855c6ad1a90b28fa48f309e6864f23a80cd23da7d2865f3894c5a7bedfde849a4c8e3f208c71137743146fe75e6412ae54a2499342391ac375d262af5d1d7aa54ef17be72eb0b6d9e42ba1269db5e25b1f538f0fc23f2f8d323f789b2b5979e3295dda5cb29739f302acd22f70925929c9262e4530e27d13c92fdeb064c4d9eb237921e20b047de97b419fcc0b2a7c9ad1543a14940ac9227f6e13d34df061e73202986a43aef9da424e33a50dc6071c3e8247ffec445a450db42f2e9c4b097833b40f901f184b8501123424032d61d6b4e515f28c150c5dd9d521a630c928daf74f9caf366712b0e87b8f0063fb3e31fab14eee7f0a504be72f74b8544189d6adb10d50417471814700722bb39a7063a87ffeee3ca9f41087bfe3669ca91a949d2528e4c3248e56792c14bae3f9da4bcf1722703e2529ef89b4febcfa7923b32790cd8de4a0fa828e01404073fd672e22b7b7f54124d94a69c90bd8833b2632b59e847dbf445fbff8cecafe39fe3378cdb0f5edfc8c8b4bf2ed78d6e5b75291b241f5e3c76d92af5188a5290fd75bc658c42e215c52aa1d65aeb96335a485070220c192238b2811ba0c6a0a054c2962db63cbde045f17483122c6242d081394185e7cc781d95540ebfc722795b69ad7495040d546011a3c313a229b6b43013c5161c9a98f7755df7c6315a48b1f0c2d30c4e2c4df1658b628a3050ee65e264c3840b2624a0b92e262652324e8e4c4c96e43075d2ba59d58aeb58565e4111003916c522abba325f6c2266895c7e8b1cff00d18bfebb86a5e3a4322a6b9b71cd0a04fe903f351f7ffb2800426dc8c416a0ab4d8c4c36400ad16022644c7d2ec47577bfeebc8e2e57adcb39e9e0ae643890b96d0ab7a7cc8c4a2929a986a456cb1b627dcbe3c0b3ea672c919679e71ff88f17452872fc05b8064282282006a9b647723b9b4569b55adf2d3cbd157655dd6a48b547b2b328dbaccea2047902c2cd7433ded0f6331e079eebd7d86c1988535ea441d105397eacd66a5ddbac962405f84f276d76f65ed4b575c6acb596da95da14990fa88773b95c3536b55be5b420cad9500f4c1b1b9b9bd7ecc95ed4b5eee17f5f2f3abda8e633236a2de946fecc7cf8caf672f78b4232ab4c693fab85284ebfcc95f9eca521f18412391a2d9623b1fc6bb1d6760a0009285cbe2c51b3a20769c50f38d81e2b434c996925994c76245ec9f406a554504a63971fa464fa3f4801b104105053aabc10c409327d20415ec8f43f10022aceef07223b65afed0be48354cd0d510aa4207e90c2f85025d79ff186aa0f5b7c209190e75f6f68ced083095a35381080872ab2f42025d767d9d04981c20309b9bee70dd59a274c5290d0a8c9218a19b9d6e7bca16a8520aa5959e014254b14151130b02c8f284620c5084ac8f3b74b850b5b6badb56576108369075a9e4fef9c53096fce39e7bcb88acfa18f5cc15cebd10db91e89c9f51f9c814987292865e40a14047777a0687941060c0bbe9ed490d84cc9987df2850a355a9c6c9e4c417125d560c181862317682470410897a32892ccb658418896a3308a8e987020e30425990bd6056e8b5703926ddbb62a68b40aa3cbc311551551dc2b872232a5db539ae569cb52dbb2406d59a2b62c531edbc026b668a7bd82a6ea525d2f2b64326673f86205da258a902e53b61cca6032a5a02205d385b26426048b1294274a8438d5a008a144c8144d509a8e087932fa9e90b4525a2d78e1d21c979a5ce1056dc9c9931811b7cb71c9490f3b29383102cc618b135c1a26a42d3a90f0e1dae4b8e4c48a0b922c39215a7232c61126883c168fd825b7c9eb89c72213513c167308c68e80628cb991e3120d496a947d4efeb42f3fa39634c924c6ecab24cdeca2ea644e30fb8b946c5f1eb98c1283aa945f3b7ded25f2d8a75fd71cac12833afbdbb73548a61dd94a22b2f5215b1db27d570e97ba8e6e2869921655ef82726592fb6c336f5f1a49c9e1502a65fb5151dcaa5379181e1585fa03e2ceef1cca999cd99ff6673e6924690edadfbedc9837498b3cf6372eaea3107d5648a28f6a87f6993cb40fd744f4a150449feeedbb0939b81231a8b3fd767ab7eff5972cf1a7919a3a83bed26664db28c8b6bfc816894bb6d6beffd05092c49f0cb808da3e12d97eec22b2d521cfc0c47ef55c4f6e3f573d06d477e170ade522875deba4b559becc7be00f0b222303f3e02dcd5f07ed47a1d7a5c130efa310cd47a10bf360e6657e06c33c0ca5e6a390eb6530ac6228331f856476d4a18a4130dbaff97a64ccbeeb039231fb349f53b5efbd878138686393ccf7818cd9bfd5daaf6f0107ed4365fb8d74a53390b3ee61df43ba32abb556ce3bdac9aea37226674d29fdd6b4b3283db3cf51caf2b2773e27d79a3d25f79cf4eaacd6fca6b56fbf8f74068dd43da2676d876d1711b4bffa7a8b085a29eb1ef66d7b1163f64390eddb318c5a397497451e6b27b6ff61b92b4b439a6f71c8765af943b61c9e13e987a7dd502737533fe9eeee4e8105df9698d88beb3fbb890d377a584a13f7799913dc59420e6bf2fceb8a41dbcfe96097a6fe58002e72ecc902a4e2b1bc96c8516210e33fd83f7d45c7fc6b5051397ed857f48f3ba970c8c3e250878d1cf65383919d8bee6de4d067339f55e069979b504ca7f9e43ee184623a4d2db3cb84c2a7c824242f90b4f09991cf7cd61598451e7f3148536492ac85f19f98524c420b2d4d579cb2cba7ecd24b76da4e336fba22bbf8ac27a7450e25174dd28718f39759f4500162f9255e55b23b11f24be4e95a3fe1d87a67350e7f83fe69619914f2c861010ac0fa2ede4b4b77e3150ed491436fca8e7978412412f672c3396b2d1e94a0d2c4b484d64158ac8779e081f71b863540f5dcdb8779c0c1a4c530676158c51e744f571836b1072a98c450ba0dc31c43517d14da3ebef7592b1de3eb25f8515122bb0612c8c106fa2181787ceaea73082eea7034a600f7f11d3948ac9229b5d4e577c45de51824a3d71e02bc2c710da4d537fd0f885bbf33dd24f716e3d55bfc41883807e3aa704ffe0fe346196b9a8392ca98162eead4af8fe867420bb551c4c07f03e346198b42dcd32e6da3c8e3bf857139b74fffe949e23e52616b44b123893cfed1480a8beb53fe3886dbd88bdb180a7dbd7c4274dd1f470b37eca7a7277f9232e9754a8c31c87c70c782e848efc84d73374d36b1ed3845e48686eb665cffb069e0911b85a2500824611207110a6b8ac8589b715be68ec3042476c05e2491d2332497888346dce80de1143a02f57b9c6d447051e795dc28e3d634e36f3fed4f4e2623e2e07cee05c38d1edee186718a88aa7fc619e777b9b218b42306adf2acfba99247befba28cad6cb2dcf856c61f1b0011f20108ee038bf88bdb0f10199b1f8292a88b7e7090fac89c54c62ed9670e88423f646cc65509d1845b69fd721c9c8d03c98d320b064ce2da1c999e3ce5f056c182e40913201597e6c8f424891a25d01daed3ea3ae5d65deb477fabdfbd75779d34470259b9d19c6a5f39decf6ce395e3edd0696d9ea55c51fadaaebd76a3af1c6f874e6b524bbb4b819b52caa77f03f7e8f89c73ce493ff6f4a89aa136ede89cb3937246c5182395b56ba594527a2da5946e1b1254c61869ddac8a524a6b8c91d6788c2f393b2be5fcea54553a372e0a183060c0cc31130c183060c08099748699632818304761cee0a24ed8b5235b172d99cd365b8ba88848a9e46aca71f2f1a4211670d07f840c38e81fb59a12e03e90dd1054d77943abef9e257b8040ff97f781fe4a5468f2a7993ce6b6afb41114775292060e42791deba35252126773582a57917163ed86317078c891c9e315a6274732b54adc1085c6ebd4c2930d275ca61b54d0a5eaac40083a850d4972e4fa53e74a0d5276e4fa968a5ceb2da2883bbf062436d01ca851134b84bcd06484059329a3291784b880549bd87ccc923282b833487408716768b8e0890f31302e54d9e1b6725c72018a1d2ff7e6b8e4c21535725c9aa184292a318733c69c79811873ea2f7d6e34b640e44972fb093339790f3d8b41396250cc114714b3f944b325f46d8c71c39ecd9ad6b2af8b965c99d0d3f7f1f229a5b321b87e1a36b636b926bb66b24cbe99db3af9b532cbcb5de6b84e06a5d8a8248df745392ad19400000001004315000028100c088402814828cd835db10f14800c7292427c5c369708b324c661144286180288018400038801305354e3007682e79eee7040c7e23542471cab3e8a5010746afc592d0001442be9be613fda755f3bff06fc67ae8bc9ca997de96f1d991bfee11f78851670b5b4b95668efef23aa28d84cff32f9e73389ff847f590a00db04c296af65c491abe3239626006d70d79e1b50b2a8e531e915c542949b08c52a423b61c2fda524c05831051a9755895e1a838004331485d7366eea40ea1053646b76a6b3398ffa7bdf548259fbb75d0a2641fe4b53720ccb00a8e2a12e7265874ac9fe1c9598a0014341e72b10ad74c411e5592742c7d0d6560d6e2bbf532d6e3b93e5cf47dc076b5e091e66f6ebc986754743fd6af4aef6ee3a306529b3e65cb17656e46bdba337a7172f212c7dc14a71782b98036879eeceedf35b87e932858369f19ae72d42f10e70a33e4b73084ebd9d2541774ed8808b5d2434c37bda30b660efdfadf39df20e4b9134759d5195464f7fb9e90642fa50bcfeadd576406b94d4941d98490e3b8a18b89e601e2ed493990b7f6bffedf0b768360bc28de26d84ef4c2c1b9172118272f62bf53f842898cdd30bf1538cacebbc17da9c752b2af19a22e18b48ae093c0f38d82df097090c7ee2c06ebb421126d1c4266c9b584e3c7f902d10fe7e96eaa9665ede7e0556184ef9038e40695d5a9bee647059f5c304ffb41a0a73d6cc0dab4cf8e8360a629cfb0b172ee198e0fd13b5ec739f7986cba0f06980554f3cc2a3e4ce8d29a624ccef6d7e09c0c5ebbbe055339800b6ce564edabd1fe63ccffb6a773d2d6812470681e7aa4a32e34cbc41a0e63582ace32718f8bf1771e47685e7db024b98c5a8beaf54ac4ac370b5782cf42ce8c0c190ae653f34ad15f5188a6168b383498461a09652f82a8a1aa1f530afbd18776ff8850cc83b11315bd5bb196e62e3475875ea6f3047d5822bc946de632dd8cd6fca0e287071e47bd136ad41b10b8496a6ae3876c5d8e381bd6dbb1a94ced56d323cf21353bf045b32e525b0e326964b11344d8aeaf6cd8ef23836171e31b7f7181a9ba0ec6525215513c42d561f3f0827d887c190d0652c7d110d751f2ed6c67f011590d1e39c94531a937ed345eba0b992ce21a48d4ebb9d0de364478d859e0dbda75473f819729f61af4905bd86cabb1f27206f3be97e06d9d1a73187a168b7bd811eadd8953b27b00c5eaee05d885db156a8ef6c4a801525026cbac229c472aef2aaafce5ff7a8e79abd1b6ac827e7e458f481e0b791cdb5c7f5f950f5398db7a4ac5ee6ecd3bf9a2e4992188fc8ba142ef93b5a0a7c7e357dea81219fc92fad06e6605d5d4d80d86ad2b506e218a887b4fa9197525f82253494a9a1008b27403dd97f83a2a960c9c57308bcec5825f0250c6b865ee6cc2648aa84018432a72efcd72da302166301ea4f56e9f2fc80f0006b6507f724242c13f630a8cb1277843665c572e9161bda2a4a65e24c5e3a7ad532b5a171a3e3d87cbe23531d81d99a4173d6b28ff6c42bf6eac3fb72bb9e3f0af4d2a42c1e84a9a0d1d271a7a0a2820c7211ea675bb18b356681e60a28be3fcb0dd198b81c2c7e2e1a9237deb891f2eedf971cade6de3593c824b140b528b206f9efcba4738f2be492128ee5401d147f2401103782899c198323182f9deffd9181ebed7962c5bd5e3f9f34fbf6646fcde6b006d3cb342c8618f122078e02c77d27119ff066b4918c31fd57e2130e7400fee29e9010d144ddb296c9d0665c9e3de67ccd0f513362b26ab5abbdcfc31ce12a2a91e98b3314671fc95f9df63b3690ea1759b18b9beb2b84fac899206d6a80ff66d73863c79ea7f39021fc9c8496fc360d121079a2fedbe07955b2751aa6e1516b55bd982b283d37eb7f959c43c9ce3d7b94f494eec30ab16d60d0efbc2cffa157921afe127cfe10a146fa8484968cfa0eefe665107151aad7b6bff957f9f0ec3779c898698d4fca929b73074ea4faf5c8a6a7171bd3263cf97a169e1908adeac7b3d95cfe1802fa74270a3034694de89423dc548ff858e8f22388b915badc1b04d8457c32b64b9051960a5d4ad684b31c2d8543afa5672e85b633537b399a97485d4468f74985ad28b5b624dbe2c011bc1599cb1b98061bd21eec7b63b66924c3254f187d00232fafeee16f3ca502a79ae6c4fbb6e25592463f7ee7eb145dbaa4d7d32ebe4b4548db2520e3682c79a7ee34470ecbdfb4b6755443935f664bb4907bf10c5275e485cd70559b01953e147c477f91bd24db739898e47a03d6e9afa1cd9355437f3a3d2b083c3a44addb3f8613544a052804c2e75674fdbcf836c4d3755fcedc7f2488e7a9e99fe1cc82de48ad6ac17a0a9a2ad38b03d2c57bceb38484b1678aa278d574415bd3e6d355d12f02dca12677f77775506d0f844e3b3a0f4c3cce3ad081b09c3e394db22955bbe392310cc33bc5e76903c2c46541748969f6655e1986febd04cf474b1ea758dec9030fcecc1dc1a3e4d967545d7a00ef220e1a127b326d585dba2f30da5da00b4181abc7c1e3f67a9a30b085434fcca8d848267ba21a7b1a5b7634663975ce777d0892c1cd96672a6b1a646c7ab01d863c832c9b47fc7478a0b3f07bd39e11d8da08cbb2787c4e2e6f903d2721e5ef59a2811fa7065e19d64e69e1f9a1440147a8ee0650083dc729a4b0d3609e47f7f829fa1a9b59b9b06fb672f996d43780981c3e3e300d247841f76494956d40f9529c791dfac074537bf78efd8e017a8e05b986019ea70b521a24024e68b525b16986d6d2f8379c909608178633e390fea3617618e8ce5b833088c111f6d03156e9f1f4d3059f58598669a8eb0aa278eb07425e9348a17472bbe5c27f5a8051a853dc0ccfd5c3f685f13ccd4c7efd7c0d1bd3f30cfcd2c234fc5f4a29d24b5f0de189f6d67d5a7f0a77c48e1b9ca785d1c02c3ac557cd2538f11ac84f54fdc5c9644c2dd0dcec2dd598292c602d2549c45282c581096f4b4a00d08cdf503b70b33e37b54fbdaf4b987b72da3501da27b5656979f7f0420c11b354d47d34f86cb3aebf5aa992819b0fae6e8298e599d5534b776bb1fb69b56639ddd2f2aefee859ef4c5b631a772e7e416d168dd080816f4fd409a194df7faed7765a51b58218501608f5029f9714501e090a281889343c139186a783736bc48c699aa58307a278acbb86e5b1f66a05c6510922d111a0f480a0693a2251a2d0b98b75edf55113c98962c939d21cd9dd11df61ad460643519705930224aa3114acfee91f2d9232e9c8889f12ac2aee97fe262a7299b7c18236e7650740e0ae8889418646be6239c3650c8de14c6d503763dfffb5a45c0222af22c67151eb9627e2686df42edb06e6ed1ccd30c81ab17f10b428b7dc6eb066b5548744dbc33f10c037b9857b166eee6ed0cd9098c744cbb8398241b38253d37584776b7a5f479db366551e4b586f720b7d00ead598bb921c4548f49d9368273500ad01c914a8456dd005a4346cdb2057ce80cec123fbe5bb3d48520c69b367b8e6d864ab81193fa1555ccc08780686a0370be40cf22acc428360e24f018b180e2a27e9598631272b0bff68a6b02531fb6da3a61530c5aa804575c7573c8709557022f7456c2b33629a26c076c98a98a8452242558c13416ad78b4adb2bd2b972a4d3358abf44f088dbf9111c7ec6fc9212c729bc88767724d99ccae0891bde99eae80c2589ee2b3a033d301d63b22c5e209172ea6b02edfd11af599309227ee974f38d9b77ce70a4bd642ef160ffd76e853d9c1fc7a27858ccacb653af36aa478d9a6f9cbf904d437de6771b70b761da17701c138f5f1a1d2dd0930c9e5c7a4e0356f1bd0e429b2144dcc345511955bb471514771f22a53bb5ca1a178b9229cec2760c5cfe549c60fc54b0ddb8f484553cf035eafe0c508b0837671ee314c11f1dbef267fe402024b97b32b40b954080a3e7323f2eb8e58cb71652bab0c1b246bb912190ee56422e3831b6f3a6698d4051b311192485e565aa53f2eb292848669909823d1852be4142869a19752359346daf96e7e49f85f2e152cadd4259339af1658d6e457bf0fd7cced16c8e686434a2fc5c0f89c62d589da28a96b452660a78d87aa8711faae79d2732592b2bd0b3a560cad54c9a9b086b9046972729f17d53d04f9d32a9fbe5d9d0d908c1782bba71f3f0f9749abda0edb1edce33b191de79aeeeb9ab4f6b7c7dbbf1932d9ccca879c11ede04d96dfcc4994ac73d4d8f5e5701ed1038133feef02f4c01a2c8d3d5b4e767a9b512c33c16dd7dd359f04802fa2e9903f2486ce933a53a9b84348997508e10fa63c50dc57d0accadc6004dd37791cffe308d2ec05ce42c60dc60b4484ece62c7a24c495346cc8ddd71984877f02bf4c338d4ef0a2d4ce2746bfc5a212aea38545c1937008cd03e20b4e81887a20b2d0a6a8a96870bdef54f5e943587d33c9eeca1511962ec300aabdd9167a2c59048797045a4b002a626c624e4da50a2635de6b619b2af32e3e0351635b254d4870607f183290cecd3271a8835433d7d10d129b194928d6a5c06bd2e94e589e4ca8ae13c03d9183a63394e3cb220787b8289aad9c6236d35b496023a27e85ed60a14c75328b3ddb69c7cd0ee4c4def6f1b7289089795a029bafe62f7ce585bd3cd1814cfd090cb0c560f7d370d91184594cd06fbea69afccbf1f1c20c31e15c1783c4b3c144da257695487eb793d0041d88b8f60186bfc9b607f2a2446999673216bd2cc7060ac49b079ca05bbe83f83a41dce6fce9afc7b24af4d55481f59de189fff0535159aad329a44a05626ebdbf1d94d18b2657037dec74412c9c000fa5ade20e3e01f49376b6fda09b8b5de67fdf22bc3e040e1efca4a25ebf80f3d8e03da89ea107709c74a49082e39f7944784c2a29479a83c742be426d4c95779174ed814c5b3a66b151ae1a52ddb3355aa2a22cdbff22ae7695c30090c2ffb9b46e33a0b1bd500d69169831b46cb5b9673d57c01c481fef575d16dd22ff5b558de252620cd732e68421f18fbd2c2e9a3624a981e56fb684f0e296392b0ef94ef77a13cc5b4a2eac92d805d51f3011019024b492496b40ea0a2a8b318473fb9a6221970200b4311c39cdffe6832770f85569c58da0be34673e2388156f074aa42edd75f3e468273306993682db5767d3711a0d14ba75655a4c64b9061bb831b6e5c2d0c58872fdab87baed90ef512c184250ebafeae305c60f020fb802c6a169db66651ab9d677a2c971c9b71531809c1c1d0bb6b59a74c33f30e2b32200b2328513dba98e30a73f4d20c3c18193dc02cb46e52684d3f209ae0d801de4b70167bc98f5ddf0885aa2e28ab142cfbc01c99be142caf3b3bd8e8b5c202df8b1ed4fe24aeaefd6b0420ce74816c33135f48233dc4a011ab8dc4cc13fdf762bbedf24257875e2e2d15818a38cb6617283417a8aa6c6a6c36642298cc7f1a17b65ce4902eb64bf247cf84abe02942ec4cbeed68e0b9cdecb995a32ec72683c4029fe4b2d82e946d458721ffa229c887196ddddcce7e20f42f24fb7f012c40c24526581348d93aa66c09d96d1e908df8643270af9e9fd8fd613e256b8b7ff340eef5bdc6597eeaf034621d3137ce4684aeb817bc76a051dcebf2691a296732082ccb6120336e69948ee703f4c50062ec8392a5adb464c004ec477fb56f457a5ae661068608d04ecbb556b577da687a7e67c73627c4c47aae74210fea689cbca5da2f031b5e06d625c1430ac87df6533504dc9f0c5370b383172d82d93511b9d759c7bf935d5230c213962a52a49bcf748044e59be91433e2ee556ff6685ab8fe3b938be2d57db7285684e1e0eae17fb4a2d6ad272da5b729a7c2517ab1e0f550c977ae955c16cb20bbbbbc5a26a2798f5e302ead4183265370dfbeb229a4ecf2398fcdac89e9634f4c60978681e5712a064bb8e2b07a43ccacf7ee08b4af294d8f986bcb304ff82a3204a0a487b72a8f45bd8aba3f8a2333137420ecc71c2d1692e24dee4c63ffef09b67e1dfbcb222422bebb4e1009cb8e2d1463a353529bcdd97bcebd6da2f11c86089e3f20c4a63341ce245ce4ab3de841b081865ded615e8354b45a77bbd8704905a06d50c1c17bf0bb072fa79fa07617bdb52f5d68ae777e033d8ae8be6829de3a20183ee72485f73b921cd56b5a6a3ba036a1e1c4c89355856c4d4b69133ada1997ee7915b0e6e73677a1b48bbefb015595566054de1ea727e2d6513f74c7d52107fd901691a4019422bf1809938bfcf6ec19ab951431acb030ab3dc52a071498643d027a1d41adfdb31dec49acefd200401d66f30435fd0a757f15e7340f89aeee55f573e065bbffc9b3d275ee4ed7862f610d47edc0997caa88ef533a590fc52f082a472957c27cdc09651811966a5ae676a1250a11f912080ede317449c7c84ddfe6659d5d5933c22814764fce43e42cae02fdf3340f4d0a601843d8cae7219a9acf4314d4a5cb93c2eddba4f9bbc9bbcc7effb373a88f34a5bf444435f11eb76f3934a4f404add9282378e3dc15b06c008f766fed68d1e15bcb27a976bd9fa54ea0201d986bb5317f40c31cade6f4b4c203aa967d2871214ee5765e88c8b4b6401faba2b4b2302c0e529385d90b4430c657b15531b57f4c8e3373b01c225065c016998af985014e5c5e8fe99893b300b96ed219b6b5468e4ef9a1f0b960456e299e138695be55514f1e6ae3bc8ef5f525b9884aed0674da427341e50163e1da6e72a2a2674d8678cd01634473defc80520b38ba14dca438d0617ae9642afba9ad3834305f7fd74cacc9ebafac2f4c74d3bd68ee6e827179f52d9725e6599d2f0d79b5668c53cc76a502e1223c729f20893b2cbc85ed5c02ace565c9c6e2d7161e9c96a6eb1ecdb01c9f549f260cd4884599906444059193ea5b27495be531a64c60a375d1caf782b9c6e87deee7a2be5754434dfe11dd10ad41374608285e23ed834a44e2442f4e804e885b556e7a41a3684600e6bd80bc9a21aba2f51024dd1f6491dde1fa6f198ccd8f5ce8fc56d8af9c6fc798adcb52e96572e90a051e1bf94dd36e4bf40d851920eb87be3ed26ac19d32effd0d51947f1956cbfeb13b0fea0e74630915d1f79bb786363b3637f9f3709f894cc5513391db01cce56e827f34738c26fbb06043b3cfc08152ba04e20bc4bafcb94bcc791e7560f054820f3226c58715957015472b5aeaa6bd0fe0a0be6b328e14e95a1ec28928d1d3dea3d85b07d9f2a685333acfd0f4e4f9800a911d2b83accca03ee80bade8909cafa71bc4a738b05d56839f7681b365070707c19a06900a71851ab10e5454f3ca17c793b41cb38e1a70bd96a2c38d9d84c3172032436bf3e81030d26d35c2b1de54350d7f18f24fc4c70898a8ffebb14d378a256defdfec1fbfba3e5bc54472d344fc1ef7b392fda337fb208aa4acba81da0b9e03f9d71871cc1142e40f09f57a2afe442b077d05dd98921afa5289630a4f699afb81ac776a99dcdbb919728241c8b28701b5eddb2aef8e245b88407bea83b0ea893442c61370021a03e5048ea818f2e90f81ed46c7cd0e25827071b00f4a01223fa40171e1642ac94c184e212486ce299b2988515b187ca3ad1c9f45d85bea3fd4705443952de219720fac7e540a77ca02d466980e21dd140d2927d38979029180f10de1c8fed5d368ccc6f401978475de5e12091c62d0149f64c615150fd58f30407cc2bb3923d8da06da6a8b5f52d1529eb9929b32843ea11c5c8baeec819c8afc5848763657f84f6dfa63fbf050b3fd82485e49c30e29d917c29f5946fff9e6b80897fce88e0688ca7e2b878ca1e44fb4b4905502d0458041ce4cd42f948099266302ece1ed26d686d49881806021ce9e148021c6b21d0293424136d047df2ab35930927f1f41c73f42e9bea61765b54af114dde4b3e26234ebf42bd1108696765729a8927443bb53311537c043102fa466c854a4a4955ae5800c7d479abab134b365e59e9c72e83c8c8ab35a728248464794c4858ad14339ce8d4cc57b142dda3497775dca2c1ba3412840d623bf28f6448b4c2ea5d1f283948cb54924b2d423df8761c4f5782c3b12487582925c3a10153ea7bd91708e9196f57115ee4bb4f19708bd23d391a472b981285e486766209210e2c518ca341884bc22cc84267e004cdfe15cac0d7a1062ced52d1d44e1117ca4230a6fb57bc33300f36e9906b476c724b6c13c72ffaa5528c0b5b45764c747b46715688ca847a7153213de367f2b0c7eba016e299455b69d31e82bade1a677fbc3b702fae29a5689e2c90351cd1ce808b12257a0a81e02d7aa7e65f88953bf44ab5bdb6dff66251830ca3f25bf540dbac8dc7b78cdd7e29378071b040de96448ca954ebfe545842dc40a712887f35eb0cd32fdb6489e6cfe715c0e903e8b212b7ef048abd9d66053fe02d60f5ae16d1233a2cd5519050a92992ce98aefb72c163e35ba664a259f6c17ff66fe19891cfcf0254ce9853a8f6884c068031b553d9eb990ec723dc06ceb9419689a14aef187d74ef71675614fb9d753af8feec9d97c89abab3ef8f450f55e13ac0e480edd2f0fc0e53e256809d011cf6b854a84eed9c432a33f348725593419df15eb381a2e730121a881abf7b29e600d6419a008340565bd7c866e6e10a1ccb6a9049ee9a94d1fa35c5c19720b6e25f54c61821879078a03ceeaedc6362bcd0898557b693f587a70971581fd0518dd6a83d2bf9cf1f05f2b30a5f0ba290f83849587a3b795c2d1e350b25e273b5953d8ae5c8858743b5a09d0a2e9d5f772ec8f1226703dd47ef160622d3fd2b5787f17963393184a243ee6fe0861e8d48cd1f97505d6701512ef41da07bb277bf79bb973027fefc9c8a34ce27aa50a99e207e54bb40970cf63c88c8104068a675d515910d24b777619dac0b09b022b7f8e6caf8ef2c2d7c91f476f89de58c90d4c611143a7f772ca2955eb543ff0d7ef5bec1d40cd2b6d4ef97926ae1b98d709ae9a819389e26445727323fc7664bdb1c8f5bad2ef90f1dc82ce6a4682b7a9effaf169adbcc3db015b357fbfa8f9e773061c9d42eb22cd795192f4da985833de501e775f14cd58af70cd2a2c1e71849602cf265dc8a5c654411f73d1dce6997c1c6a02633edfb26da42c6a7006728ab1068f80141fa8d5f9630084026b2524186b34ccf9e3fea705dde4606a797e1c3435a1fbfe8764e4e5ee211e55cd368926eca0437fe0040fe3bf12861dc21bc736891b23112631099456512cba94706e56f50e175c1153d36ed93c85ce8ba194161efb5f9269bdf86ffa35e626f65655e0e1bbd9becbf1853d6bed5685f3fe1b2a08c3be820f2853b5c9e83c66f28530d135641343e3b06498fde7e68de70837ca49b801d8a91e9c8164e23f964979e99766431b86ab2fb4785dac439876afc34491ae029c7548401ee818d7bdda9e00a795c303b679c9ff49ea7d00f5587c8faa59e6744926d643ad35d84e2f8a67ade9c476dcc8c19d56ad6ed1456ae4f0284815427c49f2277f59fb1faa29c6500f1baeefe9cd0df345e1a66bacd6adfec55cf2a2d2383816b48b6efa53ba673f121e915511ebf3ce246deea71578581a904a5ebe1692a8b71ea8fd9635ac82084625148c9fe6698191dd9556b745f8214b257c41a3962df35058ee57b6dac70ad887e76b6dbb35515cdb62c320d3b8f284cf94ba2e53c8f8a6cb4ce4a49b607125112ae54105d918f8b80670e8ac050a41562c3c73436c8a928bba6694c99dd5d1bad666879203eaadd31cb33292999a40d16d26befc6fdb6bc931622ea8fa0333843a397118a10892309441a83b82f84ae0fca6987d56972dd553229fe2ae1e48a80b6370d030bb131fbdfdc1f63437bca62fd35c4790ed5ddf0f1b3079231a9926c135072c58740cefedf2ad536922e3012d7482fc2ed5ae6a401c11aebcb0dd28a0149095ca1f27a8c13722c782698351ae6f7819686799733555a5b22029891d732a365be636474ae59cd31dad8c2972e42c6ab1a04b0a43a9bdcf1e6f1edc8420f10b7c2b189e148c60f05ca77d8ab184e0ae977fc8ebca2c4ccd8d7d03e8f46a4f7797ade07877c1459732a0898f62f1dc0476fbbe4421c6e7dafd02c2b577a4753979b583072ac9739b79ee952aaa965e31bc34a7ce2441f7605457739c0ecf54e8cb11c9604679b01faa0191869a98bd942d11ab993285655dbe54e2e920ed5038c202d18cb7a9baba3dbe66e2dd025ec5685e2738e3c10001ee0f0f548a71e4b47890280b675a028de6f66a8082cdf4a539cbdcf2959c1a2dc148efd55218fce24d410d401b64e5a43a2bb4bb8876c75828931a1b86da756dc2ecae9c4c4d22396129a76274c92f0df2e88753bef5b4ab8fa9a8ced53e2352c16b9b005ee3b5dc14855520f2f59fe210e0b82351c0517c1d8d16927c681b2c7bd1d42a6962093373ae9294fb7cf176cc3eefca7eb2ada239f4609bbae5bbab837ef2156d40c830203efcd2f0e289aab0a138ff68540dc0712551149b4586f631ba07d6f85004ea84b28c1cda635af7c3b231733798faee680fb909cf1c6f9322da48d17072fe433b64c60b256950312dd51b932087bea40ff0ae20ea468cad25d79fc0ed37b3b9305f7864b111ba58cc4ff7d23fbab72170baa458590fde830231d98caf2be60abacfa9150243bb86c0db1504281c9fb9679f33eb505ed5204a9fb7e5c8b56b3dd3788d328e2a9d15b445f9ff60a133f4c6c319fc1dbf886d6c98a2097041870447cdd7738b7c81424106fa275153a68206ee7f21d92da4153cd83c944f827cb786538db0334224640a096050075a01044200eb135ea712472cf3fbf96a67d9180f6ef247f0f89939e90b159fe1f3786adfdd6aeca0e092c224b8006b17751584ee068b5f5695e2966b684aef5b11aeb8a8fd2044275161210d9acfc8998ee926e7ca16cf38eee05303f39a2bca2f8e081954032bb78bcc3ab956a5b2060648fff8b5177eabbb704f1b5555b5de8b80ab10947cf52c1909c7784b8239e60d25455f35de3fd4ad6f6614d6fad5e596c59cf48c98787491785c7725a7fae719da7e6bcf43499db4b14a3120bb794bd99f31404a139f93b8e9ffe6e401b7e200b3e4c9f6d32310473021aeb814e8916c3ada7a5e82ce39246b052eb9219e1ff4d5a00e37140b96dd9d18fde32874334ae6ce2a22db0e31318acf98f351ab5b0e4637282483576f3906ac7c90a40d2a7fac82d52e208be812eb4e05fbc939496122560a7be667e82763b7d60d6150c7f09e10c14ac9c62cf551c45ce322e62fade950371aef2f37cebcb8e1ff09d302d90e9b85ea974e892d929f383ade43a8d7738129fb5388e388ce8a429783d6602f1c1c6cdb7128cb14afaac30283d87f5745aae4a74e5a72feb93da962033d6f4f49400fbe0ecd5bb40adce3f8fe41abec029d5eedae924d0da2df33912e07e09f40d9f998872bb06deca410f84f025f99f02af712e86d3e5e800f7a80da30889e99d62f5887d0410931c807f70ae12790ff941721df1fc85f92a6917c4653c41dc00c7af993400209ecc4d0e8e3c3d743aa198220e45935903411f05e4a033024f88724ea8178fba0eda71999c2c00f2bf73c888875bf17f96c824604cc1688c602e13361145d9ddf11cd5f1edb9e71f5ee2def31510c1578593b75c86c6585b6ae3f2e89d822507a1f7af736133c8d1ff6c9f89d3a09cd2e1ad8dd53a91b9970430699a8da912a6efc3c19d82fa8091e28d703c37d8d2293a3d6baea2445212e8cb1dde0ca857e13257ea888071729b78a170b6b6a805335edc1fe09946f59fd029ef046003dcdf9b02b2272d82721cbecd40d0a8ac8ae0b4e9f4c71c63076a3faa191aafbf096b33ea760bc74d5d78f0826b7b03657aab5b67d9f2636ccfcfcea5d9fe9b312e155a8d0971a78288f78b6a0bbd1384f40366383733f59657cd3151592a4d7a6132cd704c3f025224170cb3172fd66f49efce417cac2ea4f2882d651d3824f9a0320b493df7b410a38ad2722032a9921d06c655cc0c2b5bc8a6476b27e132c237d22d5880275f6a48444be5584281c0d76afacbd2820a766209cdadbb523838535cc5f7f69be0f34e59ebc9bb6ef9327a24e79b60b0105382b5b7ba673ffe1251c2995cbef1ee3d6efe8251ca5e5deafb2c9df5904a401033dbd0f3fb4d09a24b9d5f28b29ae396b4fd7100b6eb4d50e62d1af29f018930e0f5809082b0abd17f1eb8baaa0211f2bbf6cf1e2a51528b71bcac670d6df28e3618c8419dc63d4d5bda899e4bd4c004f13e7bc6f6b88e287de654a32417a8e273a90c588404653687716d675302d3f58513fb6b293e9a9d0c6c868a99a129e3627bcf25cb531d7a79d5aab4413871c8a9ea543d5bd16dd3b811b6886772a65c3bebc39d4e59378f1d63a2f67d48c6dea1f6cfa455dd8fbc38e939e2406d4e7130095f732b307d98aa190a4a32a92510592198e817211b43bf640b8b795b262a9a6274227d840f7605b33181316faf3b49fab71ea06b846f07f4a95baa2ea6e24a28c514dfa730b88da2c698641005672ee338672213a88f17441710a9858c9c64d6c7755689596291866eaf2d7c09c76433cadc46400fc522429928a004ad3f748042adfd9513c207c0208048295808ce7992216693e00b57b8c4bd24614389fb2c86feeb60dff532bfdedb74da93f268e4dbffbe3c0db41aa8ac39399b7d3b0b60d8879bebff4edf4cbc52e84ff592521a3dfc3b01e98d42e1cb57d1fd6de43e9f77534d6b2922a8ca937a0a6bcfa4c70be0000da13c8dabd6777bcdc073e0e08b95f3a3efec6cef025145dd1fa7493930c8561e121457a653ff46c225f1a56edc767b0e61e236c3529f19beba65e2362ccd2715117aab698829e1af7ca222bc91bc101aa9b0a5012ad6c9d4a35dbb130eeadaab51978c5cd5b04f0a4494fc432b1e485fe3c4b8c0d42060d5018f79b3642e4bb017fa604a00a25016e62f72ad335a8ca08516f516201b7d116571092a6413bfd03e3b1714d83eb6f2aceff06eea44745634c4d44826fbef2f7f372da0ee6bbc34cea1033ff82d7fa2a831f0067ed02f0f1a0d79cb26b4d0521da7259f234b25b8b5532c12659de38f719861703dc9b4cd3083324e0478259e42483a61d6a44e84fc3285bfbeb65c2c8e4960dd0feb02655f7418d81ccc99288abf0486318c8fa04c0d82cdb46adc20600e841e4168baa44f5bdfe615c66395e141f76d45e31599ccd9189afb234564a1a787c5e1395ec8cdf4a3a863cd134f55e49409e6f4446d3c18058fafd1295b2e19d0666b4fa2a7268932d307ef6a9cc86e1ad21da32942b1593c2c3462f9d1ffb36b2d88683ba6d7bc918b34cd5f1d412cddcc2f8228b34e1d96933c6c39bea970472655c53f977348e1412f7d0e124b478cecbd58f4a5063ce2059e9536ea47b0e43172c2a7c76a8e7bfb3d84327cd7ca671c957cb5c8b8d14530791061faa95277e8410eb3bcbc6f38daf0d97399e6467bddaa5c55dbd309a32e6fce3ad2e8940f2360dfc8f77b194d2381e55a9a4823a2ea3238041a4238e8bba966123f548a933c8501b10bc6d8639be1053a756c20e46310cbd5bb056ac50edf1ec389f8ec1c041074590c964a2122ade63a3c7857efae06971a23a26a0b18a4cd9c2e94cb146434a928b73a7aa6f71001ae4f61d0884ab43299117bb1626ba9b503f81a302380eb1c9275de3002749e05f112d29f5d476e25b9f97b905787cb7c70ea14f39909099a739c17f7b532216e5dda5a7156e2d907722b66c54ab23a69e0506039a33a18a3abaf859e19e1609d7b3115a4a4bcb6e690e459150b416a587202d30bb5395677059bfda741626babedf072474110c7b8a843a17a216ac57a9925142b179f89e537d0cd57f3739f9ffd50a6f4c02ac5d8443fddc2aaf53bd9f0fdb018c53db11a97405ea87b44b59c85014fdf0a398caf91c670cdb0805bcdf1e741ec4d36ab77e48531bd6afffbb96e6218f79d358a84e313c7bf4805660c38f76e0aeb106fee5197976f2f9cb0e6dc90e1c35fd09f9c68e5f8e3f45d8115ec6f8fff05f772c8dbb5c0d44f4d90ce03336d579bd68d22101ef72a9805e9c7b152bfaac0ea15c8f3ac21b1420c820d9dd580163fdd743b0ebe9a26bd0d6d2197296225e7b18f3e55d8d26538c5728edc98dd85567797aef9298e00f13c8e9bb80a2d956c944b42de90731553906f8f41be77af8ad36e7cc4a58f165b262e9b30466e1f817175d3a1d9dfc36ff68a0da3121ebb820ef72888c0331d0f06b1326d76979d477ad0438ee97710cc1c86a03a21ec778c4bb7b18fa9e7c854df32ed9658c0734da9507b8e628f4f3aed61101d928b65bdcc84cd9c70ed896190f58bfb1be0d489a4b52dc003987a0b4689642758041032aa394fa7b8e04b3011a01c11d020944b2cdab16776f0de19e3fe91e0df5af3b067f760e97245383f4d217e44a815cac4131dc5fedd83e89302d9d38c2997ed03f868d997f3a0083ba568c8ec8cd91082f34175f74c9c9b37df2627262079eed831048b345613f15c2ba1b20bbe40549874805d1635716205574248f2001195a9bd87dde611de01cccf96932a3f51475930903145ed5a5c481416fce8ae0eeda25e966034254c8624db7a5376772e735476cbb0ae36264e044f4ff53f3870f21a7199cd1764918a0c628b054e915e41fdf34d9aec399197827917b2bba39c0471ee85ad4c56d1aad9f2aabf35eecf0240817f197d0ca5844acee815619c6afc4df5c393e8c306f5f26aad7528f80321577e391950e62d8679be6e43120e186df31a8091719dd077c32d82a2f7a90a2ee14eeacd131aa6dec47637b1ea59f52ec76e63a9cc1200f666325d107dcb41239f72f0ced12982d2b6cea4f16bb6f4fbd6aed01f661c877a80610ee1007f5e1cbc83c9507725a9068bd3f8136bfaef15da0f27966aa17cf9afe610771f678c5f70f79d0bb5bfb4b693b9ffd0928c0297ed92f60f06563a4fe924757622554f32d673493135cf3a9ca668e7ec46e23ab4b01735857d18a6bf06981958d7ce7829fe0c12c34c646732fa1ce96141a65e5b99ec6ac4b8c131eb053b459b91ab9b09cd1a223bd789ae6ed3e1cf17e0b2c76b90d34f1cbcd5a002d8354ef18c01cc9dec8dce67e989119841dc514f427ec2d505453fe1d4a932f46bb1f8e7d9a65cb9fecc307362a5d7eafc3e4605e7b2364673ba95043a78cce173ac38c710b2620e06c5370120c15869299bc88b48eefe98278a83d35c46168fbdea497c34c613b31d4e9cdedd4628c4639bf2526fe1121a1277b03dff90605746b735eaeaef73fe08ef8e7e333bdc8e9c00c245840db48aa3beadf5538b3ae43f098870d05125cea03bd43f6cd4c055eb8547bc74ca32d6378bd0af58a846ac0965870a49fc74a7ca9f4369cfad9c21870220d76c42fd4eab9ac029dd336c0b6afec4f3a48c58551d04c6d15b9bf18fb9c2c2890ada1f046b88fec1391e17c60ff0bb9bedc271d6fac69610f17e8ea37fe74a176c82702f4cbb1c1ed44071421a6e296a1945363ceff1ebdb3943e72452c35ccf7765f378c4103cca698204c23884cb6048f4576c7cfd9de75667441d29740018de41d9e68004915b9a715dcb142480469f44b298bcad5d7f50a110472c98efa412de53ca818e04066d57415b8ca81013cdb59a006c157ea511efbdfcdc58d86cd3b2d4b96b209a53591cc17e3cb00762d5f62255618be056110092945a09310fe890d789b2c106b8b6c8abd6b54066246732f7e5575628795bf7d4e503358f93505bf1c30f136a43740e99322ce49bf9fd6ab4181a0f1fbb2755d8d993d3827107d6d6f8cdfd7691de9d8ee7f96212cc5df2af3bf437a2663719d788c39bb36a1d9a59a7b5d7ed4428581c248863bc71c33f3f8a9064a504f41af47904373c583e04b971b4996907e236289a21265b375a329fd217223815c2182639a4c54c03f038f01f2cf302b8c1df57710c4e41e58a8dbc444ee2cdc05aa4c168ff056099f7d1a9626c762e9992b459eb28c3f7db9ef9d4b63160422801b711f0413e0bb555a08336aaccb2aeedd111bb913ca118319b0061ca2bde5d6bb509adcceeaf11d2ed69fc6874cf7fd4021d8d7c8d7da0c3db868499997379cb22c41b8a7a408e7e5c1c5450835fa9e10d3cfd2fc9740245f260d4a0d2bd85cf0292cc27e7fe4858cddebd82137957308175dc04811a349e7f85f2c1ca58dfb9e04cc843b66042e0b40443f01f505360e79d0c0d0d7493ce4b4e7c2e00192cfd717b0b39e5ac2e940012072d8772106cfa90d9bc180a1c6dbb3ee876a19952000e51dc6450c02caa5ca0a11a12014e4239947749683af4f55352056abb144395d9df4d8bf67d4526925451039bdda0d1c744da5e4575145989108407320efdfe34a1165aa3c4608c0bd1a333bc68ea071363b64f8e228a9734727b43eb87df8410c0c1b05ea3eaddbcd7f53bd179817454c7ad158667143be6f7c025410386475aa646816fe4d30e6510abe49c585a5e9fc61e6262a17ce2b153c192ed05ac637a34db89f52a7180f9e0022be561ff29bd901111b5f22a98fd0ffb698270bdc19718833fa847c615f253be815c2570c5c9f87fb061cc63cc50741a52160eb2f6154dd41a74658a480420a1ddcd214acfa5f54f2dc0f108c4753a11d7a9b8641e7c9fe3744ed3d183a6b888fda6417d1f27c53cac96ec2cbf62c6268b240234e4283f07323b1a7617f726151f2e16c668a78cfc22507b1a164f81e2b0746cdce2d0db3c63f04f82456189b9469d6768dd409c370526c6d3fbcaf1af7d8dc7675b6bd63e05444eea6d5e41628db2035349dc171e3af02be77f81a6822d85c29bd5dea00b6d9e45f2afcd18f0622fd179c0f05209da3435174bb789ccebe4a627f11a95692eda3d858310b7a036d4a0eef435c74a5c9fa344a9cb37983b97343b4d2f50a5a42bb88854055d14828fd99e672694f309aa168d63b7a1e5b8441d5f799ae4fafb4c7945d8cca24d40999fd8981889073c7dc3bbca9b060a0ca2ed5c130920b3b0c03893bb8fbd3b5b9a79d92bd31cff9a8fe53deca91d0f3f5c3f7deb1221d58a894e0ff93eeabe670a146b2f18ac119a02b2c74edce75900eb87b2573e091034eb1c8daf9c7a131de8429320e6d3e9116e789e4a53fc619cea1e670b48305bcfb27d8dc05452e1f851c3978d076bcee70dfb8620318b1fe7c9fe3ac3305d737f7f51a738a500a392e7c8e0f2fd2dd7930e5392daaae1ff131cdc3800f1bbd40978907523751d460f1df51c0e8c8b51d9a0dab61b7f580489eeeac852ff6e8ffc6f468e8f9d780a6a650e9ebc3abe5d797e021a0f7597f2c6346252b7e8861070c1159adf9955993bd1eeb7d0ac155864f4094f9ac658dc85f2f32cd9eea110fb58512ceb393c8ae90aa9e31012d08ece5927312938ad0669c0a1230408bf6bafc395ff6d965c0aa9b0687a66639093cba3c5e8251e5f1fce2502da951447c43d5d1acf9985260f7a092b7a5b3e929375e635bd6a8829a1a1ceb4768a912f6249f6ec062a0ba9c0334b4b0017de97017fd2a7c2de60ae95f3be46460010ee4bce35e1f7ef15fbc0ba6970f8dc202fc1c3937fa6771c8185e65fa062b7e1b7f9a2ba3e7cb829abe5f5c3a527f60fecd62d271dddf1b7ea1c4ff19dc0dce809f26476b9f37b55b8f74012f2352683abb408053415a89e912a48b399f0b7df5a15cfb7436c94ccbe6d7ea3c94e2464e51a7e438a5ddba6f93ad9369884be0034d000a401ecd5b43a68ae644e7761f535b081cc420ec76b50165d94ae85a8e6da6892538117e41ed23cd75272cd98b6ac35925b03a17492c23875231abfc0f16f7b90c3b58f4f92d8b361d31696d704bf459abd1cbbc3aea66baab105f7b49b8bc79e7193aa07e696442f3a327c5d097f0bfb2f6cec225cd137807a8f87cba1b9fedcc816e1a0bdd6e2948f07e2b6fb0b71e3cb8886f37e0bea940119a8208ebb4d06106338d04081291cdd753b1eecdaa2270c16b2093c71d53aeff1494867d0c4bd4606785e24b7ac400301901f4209c54a911466b494b4fb183f347178c0747ff1dc6432d6b1093dbb36e292cae9e35fdae32ca9486c3c0b15441ccc27a90c062c03766fd07d77ae2ba283ea85f829e46c0231099d836da229458d5c700d3aa092d510b2b4ceba1ec11650b985ba1709604ca8804c3d3c18a4811fc433980e7d99df65515c5790f10410b8052080ef208b145ab7ea40214168461ea56d93d45a8426c30cc2699e812ec620d71cddbf31eb3974c35025e7acde5dc0ef5ac054a6e30841c805986cc1a42d1a501c0abb8e6934e1b56a40d70d0499de386a66287de65e84962c86645ecad5379ea2882449035d512649a6f6c88a91085de595f4c3b2ebab803d7323aa00c0a7358a47d83f2bb9094955494fe6853495c4e52133840988ab8a72b948578afcb2b209c126a344d56cfe56b2ae33b5b89f96c7d6aa35b788bd06ef573fb71a06075868e4744af71a4aa0b665a4fe79576219e41f2ddb8c77c498ad2167f11aca8c9376a0a199cffa877ba059bf4f461a1373a93c450293c3300103d08642af2b8c1c1ccfbe3fe4442194786d3ce3ca22015bc59259a5ff83908dcbaf623efd2c0a908191fff58aa355d48b44b1a82dce31b36a3abf6837882daf5047d4f5d546677f894b956242799e3a525b7ec3e825f4e003055567cbcee91b265e040d82581a7c19f7952547b41f157e5752f88bf60c5fe62ba56d0de6f45d130007c4de68ffc66af75ea5e89235a5f4b90a00647e79a3acbc9a0e33691e4cb1f18d0a7810442b49bfba1eb77450bc27fca89d6c3f2e631e3c2d040cca1f5579891fe1752f493555ccfb29e675fb7d5ada7e02c6d026d049a3534b342196b075e135ddc6078dcfdf4422e62400d5830233ab6b24105ab164512913578343620f3713d31a6f014b4850811dbeaf506122feb2041250a77720f52e746a6002ff074c9ee00829ad2ddcfcb8abe4b1d6d9832f9427673e9b8bc63de25ceab83be3aae9778918a1b82d6549683187c900bbe43571c4dc3673c480a3de7c9a8fff20bb320c84f2d20ae2bd98dc9cbd220330e27a78bcb1ba279b35e39ee18806cdfe7d7f6e3af5bb03401362a78d994227fd90ae65a5d63996280d857a8999b02e215da8d623fa12f3444ac98a94831d38b07e90f2cef0ec21ef7edb0e575a855ebb0a5aa777093bcf435601b82bca2b22949166a751e5ff79b046b76d730b000dcc8d75f56e7380e810bee5775d244a05f5b8c9568504f39dedff95b53ce24e68fa1e98af8cb77e5631e6dbff8f3deb62620b04ae1561aec71c8df9ce27bb7b7d64bc0b8de3c2d8525778fcfa4252e51ee6f1f366889365494a0853aac874dcde127c9941911b8606f46a9cd6a85dc027b7bc9cda337d5bfb04fa7bc193d2da402cb1e9c3f3d053b6301360a3806692be13812076fb9bb56f519ce815cca7aad43300992772fbabc34a7c2a30dcb375080de4403dc5a109d0ecc2f8de6f19c8b263398b839708952cd354ce68dcf2c6561110235908d65ef5eb404f77f97fb948b8c82108e41d4337ca53dfbe15f31db3ad487386435507d773e59f90a5e5a1a3651cd45b02773d8f71e4f8064efa3a902e815e1a0fd98446a1491f84d8df6c8e384115fa6d1ffa3265a184d3b98ccb21e885831ecddd4ec90663367c0620ab7810a0dcb19f101baeec58e171e4713603e69ef69c946a041c7cc1ecf088ea2956b55c8a9ff8b619d52cd08da70aed2f47a20fdafcb5d4f8912fdb914b328670ad64da9b0d335190d3399de7d611b9c6256b3bb128914c3ce18b34abefb09db252f2107fcd82efc9bc30190853c512156166a03f52a45922e9892f7c017e58bb3e8a7f1f538840317ab8bd931dd20cf69c64b4ab6af0cc35c56e786ead61cc8ccc8bb3c3c6bca3a0808ac03b8822f4747141704e0a783b94aaf7b16327a9787226d4f90786a832c5f2ef2e6b64111d9015073f4c8d67687a45db95651307ee1df2974ca5ace5481e1f1ea2bd6e4e41cd4036b4097fc8ca3467e030e785833f87654bb53570c28f61d52ec5aa93e37dc9f72ad8a2a30058319f8abeee5846d454267c231c982bd9a760a09dfb7824dd7ffec872384b01efb78653f9d84baa3e492c22a741d1b90fce50e79a877a28b80eb23061ef2c3b623cfcc0cb8a13c819cfe049b0b0d376bd0ddc1b8d2df6f249735a5754b6d16b42607981549d74e0538d751a716192777bd23357bf88fc3141d404bae76ddf7fbea845d6c0ab2472301c1a6d12274f3d662d91f3cb94222f8cc10e161063d204f11cc2152ae5a6116fc294cf47811e202a8296874577f8aa65c7d838c4cd9169052fe26a6382fa9f4ce52e92a659d41b6312bd1b50d2860b1c7dee8375c43ec40900223d9e35bdae127c9b459ed75dbe4f9caba443d2926514b6440a11362a04ee0cf73e407280e6d607f3e5c0646148228296f92815124cfd761bf584c90ee09ba17ae0d0cb94f414a65808a15360559c408fd0cc8bbfce46765eaaed9a4e726de66914211222d901d6fe45ce9b8162f1f60d9a90b31dd0d49972673afb202fed1ef043630776898c49ef67adab577e509a0a1a6f28f7e3d12288332ed022898c6716206176d8c9a61024a9e442adc7adb34ec8046447b1d0af89e0853c9491e871012940af7d30558190e150fba91bafea662a298bc726de678e109046cdf7ca2beaa64534234650af2c3b3f5e39580f8c8288adc95090e0a7bcfb26a7f1d3cc0c815e96e2a1c24bb699ab000e8a08753cbb53d45367116130238a4daea5d766deab0cf1b75376b3e3790f21a524a274bd517334da91689bf73e3cdda52854175b0e0d9058bc99101266105f0a24f29c8ac91420af246a264fb2ba2e0ca20e361414424f9a4529d1b34ddb9ce7af76f6c977df90edf25fe1517815c1e021de8c90025f64a97a0722d9afad4ab8766758d2f4461bfd50c9a91f8ceb27952a466a7f01bf4aebb3ee739ec2fd7e2d0f1eab3336d22b5a8dbdbe802362b14496f6a6c747ac0ae1dd13c1d084eb33d7fc1acfb77623477a5acb3db14f36572abe60141fbd4b56ac608bd45462f44d28fbf432647e2bb105443529eeacc5fec45b665f5009d400c76dd6d24a99a7a4ff2fff533bf9e931085aa92fc5c9ed7875032bb3d523bf8851b154cd57fcedfe464e908c1e984fafeff246af3f8082094a92b8d10302f001af04abaea3892e90d9085a04ce7c686dc64c9bae933ebadf1c556abf84f6d6b9fbeed692fa12c6e906264ffce27a9be730150c76ac24735756313f79fd5693f399bf50c823d5fdd8d7230d389afa31f829183f079f5e68822f1d0e891fc03b0bc384550475718205b5f5b1ca2d4b5c15acb571dd3d99de1e346147958693b1945054ede4800f78c357974c4168ce71a78703d63ec9996fdd4e911cc6cf43a941c14e66f2fbd3c0433497b45546e9e244fe17ba133022791eac05f9ae3d27fbbac14e401ef94321f6e0129fd0b936f4f125978873d5d6931e6fb576a4cba0c7834c7a451d8baaa5eb7149cf7d86c43fd55e3a9d311ea3b297f54193d741dfa7b5d024499735d23e4ed0a810018b7437735935ab0d0162850f01b1be88f6f6124892448377a29ce8e4149cace7186409e9cf99d90090b3d007d3a83ff4b652280772fb9f3f4eb0ac5888c06fe1d7745769d312fdb9ed0186a13b03b13d2e241a1e91ff2371de143e982ca0b4d99b74296e47b9671e3b7d90bf9858be611a5f1d433e0fbb5be5000c03405ca82d8034ad2afe97b6ab6421cb6877e2a8000308f393007a7bf13403087068176e16a16ad61a4b5cd0546a601961a263f922adfda6950131b301632e0ea696c1921c32e654b658285a2c267501907930620641a2a028dac050e0d103627a2a6a154304de401721c3443c231988cecf63b6b853ab5ad4c32b4a1086b4c8b1e013ba52f26c96c8254ac201f85eb73d53a56eda2e4b2caf05ca4c90a9ba417e111b6d17c84082370b7e0a0951594cdc1e211d33c11eefd09653f4028ce32b8697b8837bd56e216e73d71669328718c2499b453ee458745c462c386b8f3f129382e3a4c54217bb2156cdc131286d9b68bcc7af32731a8f03d4bf602a4fbf9e14869f0aac5dbd281de986bcd23c2e00a91599f302ff39f6947aab6a329011f584191a58637c7a44f105d6b39b41947686418dd33a36df60e621c91e2ea9e0558073f7a20385eb359ee016a9c697a17ecb78ca760da0b1330a7de30694c6518311058a8502e3862e507779d14149c4409ae8b10be32d70ba038201102ba80e295da21db101ad32a508796f5e0597a49c03c04f33f9c108268c861275bbb0e12a9d57425832dc42b682d64e3c9af3e157aa4408cc48d4f16a59a7f4860950172077d2b4693275be446499064f113846ef55aa755b06cac23d2179e3a951b528866f2872a4b5b599367e0c9625babf1919b3891836321e74c30a7701b2cc68608ba2ffbd986139883a47e937ab0972719d0813605bde34bd62e2106baafa345c03d6a07b8c8181ec883bdea7d6e5aac78414ae6402e608477a9f3d5d2f190f817d8be1a80f78d2a304e01ec631400b92f577d585967ac41f03511ffc78bb54a33cfc21317011a46c1b076f84cc4f06b42fae1fcfaa409ad5b93e5f6be0f0a60b02ea5024162856e3c263758b91287a95b1ff7d6ef443b6df104560a3fcd454f76fa30a5bbf6aec7afed8950e5e899ceb586b5f7e4f112f5abb49705059d4f2339a709d226c4e8ecf57e300d060b4e753e7571a0a71d7262c974dbd14d16f4995241fa9b9f8abc9305b81022f8747fd0ebfd7d49c6700535909afa36bcdee8cf1f8f5e757f4fe51c4d37b2d23a58abe1027bf70c445d4fe540143f0dac1bdd65477e96679efb045119353e2d8bbb87ebef4ccba05460030dec2f105e4ec8cbdb6237badf6c66c009d4d9c048aad6cf8274b5789c809dc8bf4c5b48141010977d55ed8a5c1c6b1cef254fe8837b1d0617638e48474d70cf38724d6d5e7442e4cb0185415aa02b463002d052bd4ee3f92b7641c1a33e609262611486e3caa3a7671e275e84e803b408c408f922470b1129c58a563941e8d4eb1784a614805c5a56e547b2637062a1cda4e737ccc41f1487874e0309c8c081dabffb52347eef0de26a73abb341f976f82ea82297612051a4f8240150ea5fa0b07c6521572b4cb827e4657c57e9e8e08362e68612514b75efc86b805af9cff34cf78d74f7f808d471506be09d0488297c168917044de93c68c2776e578ca6b1108d79429a8ff8c721a520192bfd560ceca52390b16d06c8b649aca0bd9e9f3cce24d2bf1fc6353aca13f95b1a555740685bf7fd9400615e76b6f64221419a31d5f762466068051630aa8fb144f2f15024c36d239a2efba2522a7d8ab84d563805cb19ddcd91c716b476c0f1538cbd034ad0fa73f29ea898652f712d060cbc2717a50dee8a4f2fbb86a350796e8676ae1da0737a83736090944627c91775baffeeed78a33f8478fa68e3cb496e129e41da07bd6fb2c41f17c7c24f803372c542a0ad7e46a7e0d0c753d95e60e8913ce694113eec95d280ad4b55488db6b71350fc6de4d477aee70885b8a22964602ac0351fd7aaae7c3a0f414239d150aecb50c07754bdb8c7e566470a58f38ae4f6b4eab52ea4ee2b6cdf970e2ee609179338d5ff506d46a52621fd44f5cb1550d507443dd1044e7f22bfade45b97690906d19f6788ce2a4383b64a791dbf395d0b1cf9076b1cda679908ee4a7ddc45a14b725101b386b17e493b0ccfdf647a01f5f115273c2eb9eb9aff8e20c7c2708091262211eddc41434516ff09dbc28c36fc11b19c6e44181070af03b30f8bf4fe41e69b27bc186871d360d27b5775f93b7fe8721b28ac5d814875eade81f8b656c69e00ed7eb1819534d1248ab61d52f84f1e004a72caf5c8df0846beaa4e8e599823d78eb383bdaf47f70ff92ba6b4fe16b352a57b370777ddc87ae43f2b9f7b3a8f5c39a96f3ef7bc82ba51620f89561aeeb936e806e0f3b426a4ef0626813dcc52aaafa76fc47a5c2b943ae8594d04366b1672b3486073d7e298e802078e9464a56fe77548afa6d78f996245e623568888b98e57b1a016f3f15d1cb17a2bef10cc2089fbe5a2203f6c505886104be9b8c6c5e7b3c3b18404d5ee37d254851d495a77ab348f0ff4755e0a38081f1fb738cb5864735903ab0523cfe065236f1e6a206dd86effeb3c58565744e24d26f813aad283c6dca20283303724143ef81dbd25b625c47fb7cb478cbdbf53d6391e4a6d6df4cea26900b91062025a850b70b0feb918ff7d43dcd06e9ac72b0e7bcb43f5db7e8be0200c2df9156ef91f7aae0f97fb8463080cadce9d4507be5cad2ab54adc68bc22e64fb3e3ae2ba58f99e8639fad36371b889e7f899d214da0418dbc3c4470b87552d8508a14b7f7201090f522b13a64b765e2c42ba472b5e0395681c8fa2b272207738c4439377e2832a87bb14b6fbe7d90342e9dc69a3d8051c6fdd602dd5d1f197f862a4023426643e8f0b3361c5ec2fb76cf0e47838fed41ff25114f917fe9d96bcbee1dcb3ec976a9e2e55e8ab01abb7afb39eba50a9506845e5ae168b13b2f55f0d9347482ed87540484d3856f17b81f7bf0f1edbc3eef5b7723b06311d84617dd769000aff6c2305767740a4a44260d4408d5ee0fe6d867ac9080b378cf41c80f1cd3aaf18fe8fcd5b15f203da2df112c103d3c4083f9f184b6ad1f22425b1f188cdccc215f8e0311a8fa202ecef048fa9f97471db630271fa81ced5d8f4788d350c0f1d85832c9e7611a63ba30e31db103e2140cc352ee720e4d6201c01a96173a37e3478a59d6a046d5afa24b3473f368af8bf0dac0ed40cc1f7ce3c1647ae998804bb353ac7f65881feb846f681650c856ae1a2c6cbe71190bbe14c0a948ae24765407b168ed6f25d85c22b7f10051d8aead42d4d915b70599c57662a8d5fba727034a91af6d705d432a5c688a0389ff69164787251c00f9217ef9fa4cf00c2536ceb1c039db86ca2ba39f1b63921b941e1d42c7e98f0e290db381b42d7ada32fb6f4b07127ddcc992e2f178a610d5acc487934e0578d07d1b0a5d9bffb75972851df09b982e8340f18705f0af40143c3db451d0821600952638b05900c965a2ad665938d625123f9ac3673cdedc791d7704c3f318a08aed37e99f7eb27bafc2bc49f93446b28ebf749c27dd644f8fe245a0d21ad06b16b3f185ccabd017d1bfee04c4ca16d92a3c2f8fefe16819161cbdbbbde145c0dfd72491f31d25c6b9fc661a5904589eb84a1c48aff52a360ddb3ce0dcc9cf64740d1ea822a08b2145aae2a0119063906e4ecc3706571d595ebb63ea13034012f21fddadc68769823642b863f9d33bc241523b221ad37dd29893b8c5161422e46ffdbf0e78800eadb9da845c5d5321bf1534213fd2430dee2aaa31910b88427e2c9a42eba7ebc52dab082a09142ae109f9f5bc392a22e4574a880323c0132228988b0dcd98faf8eb8698bb6160aaf3c5322c010bf6e1688bca65d5f791f5236bc930cf7abe3dd00096f3efbcbf8ffab1f34b365ec1dabd2b1f859c7c9f062b49ed5ec2009bf90f50ea4db1f983d5fec538dc358a2ce630a96d0040a8af12bbc73b971fafe33d98a6985f5def9b6c8c9cff80b847f6e144d0ccc5f0073f57bec3432e0bc4d7de3c05290edbdec0777bd31e7a83466405a3dec93b3ca3f9a7ced23c5961574568d370293ffe64c7bf559302ea6bd0fc16c7f59d372fca6ef20e24d26a65efbf96721e4889cb4e610520543158643f43b18598499627fa4acc8632bf9e5317994a99918f8c654d4bec62411b76f68680ade5500215d49acb8331cf63018d51fee0f665d01bc3cec895d05bb6cf8f0603014c2a1eca7afa0a2e282b7fdc63b094f293a1b6ca80026526290d98197b521e2b5175ad6723ec71cece2e6f650dbeac74610154c7c1fce1f0dcc713a6a426afe73692097042f0c1b9b7bc4c4e61bbefe2818a979ceb0404fe60a730e8b8df770815465b5d7ec234ef8aeec66d14ad2f25102170c8efacccff3a93946f7350143368afa0bc65de027db0db117978c073317d4838c9a5b140abfd68d9f1b136937a1edd86604f095f1cb094709e6b6ff66212ff29c0ac106d161bccb4aa66f383263bc66c924793909b3ec7e6fca29f9fcbbb7ebedd1cd0d5102f4146359f1cc362905d0faf32a863bcfc016927c1f6486b31193dd5ca7f3de37561ed4e18f14f39343c148c978b5be431c4349b511fd220e726eee022de4cdddff171d956914f188382e5c83b2317ca21266bc761aae7648b2d7a3243c29d96e3df7bcfcee559dea2f52f31654561fbfccab1390e4c2c6a436a66f9a453f8c2af2e647b577788ee386ae6984d68ebb3227edc559781751ea0320e1626b75aff587289ce04a6a1fe04acd230ac85f9ab58b9994a8732bc22c2e25434e69f88b34f68cd3e09a383c228647930c903f88fa2ca6b8fc7f5ae2cf46b99da9e6efd7c3855406ecd3ab83abdf8edcfda9283ccd95d17b4e500ede81967fcd7798c2dc9759894ed46ae3ac9c1dbf228ad8f15742c2b2efbfdb287e574822c51140eae7983d9958e40ca8f689de5361685c20eff44f0cf0923d8f5b6de6d28c2e0239e15dc55ecd392dc68f1063679df00b8178502d7943780674dcf5dcfcabbcbb2853615c4130b5706aec20b074d2a6058565c0b7a12cd0e6880fcc221f9d6c184ad336ae21d71f187bb0014d600f2f7ae93a764722d60ed8c96e12105a8acc09ca0daa53269ab0da10827c5d8ba322b2943953bad198cbd714bd93c06f0e017104a2c08a56cf5121755040e68aafc11ca5d2e8308d62a4d761ff257a5119a63a485624ca89162a01abf7f0227d8ca07dac6e54fc06b236e672345f07a03828daf27705a77964ba15db181912376b9765ddf9a2a0f62ec03df15083d9931fed94972de4bbaf6ca45018aaeb49502ae6ab41461c6b50e512be7bb36d590068a55045c1753e0c41d92d11e096329a5642b273ea91f7042794928ba2d92398d9365aca43b40c99ce0b2868983fdbb5e3e4091bc516848fb6fa85f6f2700a287d93874069b8600d101529681fa52890e537f331a79ac32b1930a41f18503666875a87be7b3ffb93266f78c182cebde965b2b114b67b21ee8bfdc3486d1cf380d17c52788ddb06dce4c298834dd14a032f791edf2b096f83022fc0d5420b69ebb9d739239f424090556cc8139082419ac90fc030f91dcfef2df8cefae62c01c9631f1a7706681e1139c7d25a2e6541cad2507ceb3c088487e8de6a0d60124f07f32d518c14e9f35c322793b89c74d60b6ac7988061044eff19ab982d0070f5134d2e1d5176be0e189470c26bb94e465eaa37f5564fdd6f2b75fa8449b964adbf95efda31a0786ddbb54e6337fe6a6a0a8cd8b5ad81cdc83b9e42899eda552da5c0fbe43b7bd40430ca4db196904acd59fc9dd6d2d9a1fcd896416c28677ba6b741f49e36cce89abb946c8b658402d3e71673f0deda41bc7fb6b6487bf446e944f04d7cdd1fe35d8c11f1136e2238274e338fdb982477072d596b83f0a4c56bc1a294ab6c403d4e2c93beb83bb2afa51d50f603704486579fca1a56c6823972cf7886c78bd09b99251d1dfe0684bbc1415c309ff09a348ea73477cd24f1fd2a87a78f2cb1003fde4e3b9786600eb4976e066c3f6418e25dc6ee42f9e587de0d233524e872570d07162edfa3770a0049c1c792098b8807e3f23b04569b2e5383648e10fb93b0c8d790e1a0b5bd85a7ac29d15fc5d77ed867f1310cc37fe6e37ca687a518c88dd5535345fb8b4719f20719615a0db182cb74f9576b3b8f1f8a439c04172a293f0c4eb34759cf7cb302e6ad0ad0527e05891b90c3b5122cf06957b37846e12038225f01bf6dfbe94e31b675c36c9b0c65c9db294c0154cad324a36b72413ee68af50c5e8f7076af3628b2230fd72bf44a721bf4cf9cddf65c027d642a18db7dddc0dbf1212ee4327657149c8b0189933b3a83a5da495d9fd6cb0a1c2f4520419ba8a26d79528d715f10335a0d4101d4f6da509a3c2e3cd32c0efef852114644575a7ed150c66813c0b7511e9463182517aa608fbdcab48d152bb9ddcb0494171f5253c86f8ff85cb1c905e4780910708422172cacc0962edd2f9d7b08e56756ef9d0965228d5d7c128c278b456c403c5756467cf3764a5987e0fd0693cf5cc8e75bca9ad130782410cab4d51691bf04f3b4130cb514f4de8b4e1acfb85ef18c3e689b2bbc07cbdd64ccb88fab44ba4cb9d7d7312ae0d4ebf8015fa4f9842c83268f2444bac6cb057717048eda2907d68174555cfc1c5bdd6069ec460da69962490f44e20041f43c23ac04964388e08d1c2db030734c10e6e84b17ad86bda100f678967dc6a9c8523469f1f362c7c1def807f5914d1397b254a21ca9d98dab989fadad6fb853412dfc3f63168e9e253ba61b39b2e3ce0165c5fe2de1730d6028030b144c3b3db810f773ce4f98dcb3ee5084a62ad2d076a12515d790197eee0cb0dadcd55cad4614d7d13468234b78b4d29625faab6768dc806c139011752dd36d096c57a4d9e4086915bb9d019673286ae37b02506283f13f2e272a31dad8dfb9eec4e2b48541ab683441fd5854d498757c5e0b0d2b3e31dd9b58a129671243444a72bb75e92fe7f32779320b042e8e1a908fea768a3c292e09320b415865054d17da8168015f0721de685faae1564ee66900744c59ed23d2a839c6cbf582341f8eb41120661b5363188a5ee9431a8bc29caac697344b6abe260a5d304be621a9a00cf171446d6d1de576bbb97864c7792b05161c7c34f455397eba9c509cac949bf71399bdb9ea97fb38277204bd22964ed90a0c0612060c56f7106af32da9f387ffe107d9d099771e509554c1fde9c36a4b4ecd4358bcebae2e29ed99f953e910b5891b7269cc9067f2c06a842afd18d157f86eac1be24a29c9c436ded017fa41a3a4adf75d5bb1cd61b35b2545070086dfb96b246bee7424b3323f379e3e398a527611ea627fa2423ee559034f58e01c67c1573971e42675fb637bbd0f9490d8d8b0a05275651c73d0f6ef35656b58fcfc8a09ba244e2a820769e1316ef82788093076d1e342e595f2b663217e4d2f3260cc6b1c74d844440bba0e4feb2798c03a0a0d045af4a16f65038739c54ee840df2fb9561d32cc8ff709213191d6631e313b95fff0de876c058e23f9d1eba5ffc141640f445c520680c96e8bf7431062921c5a5eb5f402efa7db7efb7998497e7c0caabbc6bfa51e7311ef277185fec4d8e91e0c8d8438e9c651be58019da1fdcbe97d1a046b9c0114488dd928618f71202672c33234fce51cb15f4a6b2733eedc8590044a72aa83fe8a3f79eb1e1bbbdbeb00bab7b2282e801957a693a4f4f0e5954cf88326ca59fb19c002656c12b5dd22e710cc14e72a947050735a09f168582d782d459c5424944948151263cf65b3ae5271bf377e11f235e82966524b1e9aeed22dc3ae3544ae660aae370792182f07d7767b4cc861193b79adf7c8716ae767b1760f958be5290b6fd1b48b0a12bc79be3a6e2330038bf7268d478f83cfefa3baef16f279a6717e616d586e693846fc49462ee5936632e0aa65b05834ea6fa78e6d4a9384bb905a1fe1b5d4fb6788a109113d9be875cdb7e33350e15d038d44b485c55f637f4cf50b8b6ac9769e400d78ff8f8a3ae6c7eba2a4be0763fc70e6350c6a1a2a64a18fb9c64cdfbd52428255502e0858de1a04ee3297136e9c5e588b50cda1cdac118452315f3282082e86b0c4be17073913718bb8346dd8756a47e59845d9901718d53a7b58ded58f442d2a6f1fb1d35b07fdb0cc2cddc5f0e64eebfa18b0b5e6ce5fe687cf1f030bf7c5146dd74c83b1ab7e104cf47ec0bf01947660ca532a778c02772a1cf4d23827d2b9dd3c79e0b9409d0d91cadfaca5056eca7204ef42ed44eb1b1e9443d81d17aee5f0fcc95723961d6d5f6389e86a1ca0b1ee7a30f463e39954207a5049280d2beffa264e30192325a59caeb9573eae34741cc635bdd2322b11cf113ad00461732dfa3458d5bf81200a66f9f79779c844e20845b8a8b7b67a0e64edafa20858c3567d3fe433a7954287fee03240d983a7cb93b46c5fc80ea253a622866a994c01d4bdfc3e235e551392b064b4a434e40d45950006c38b448ab40ae852f9b52c45604235dec6145f6a66bcd709c71396c903a196258591d6cd9bcb7b7bf70b0240106b47b5949f02490c1450002bbf9e312d0fcda6ce5b27e8a6a82192700054155ccf1a118a0d84c91603ba9075492bc4d380275e43651228582481a1a7ea22c35f20be435a52b664b1bbfaa8bbc86861e077f48c84fc8df7b8eee2f522c5b0e756df61474d3e13a95c6fc96e92aaf5da158307abecace3ca29e5b7066b2db049290491380a641f3bf5a87f12ac448a27990676571ffc4a4d4d1446a7bc8f25f5c5bd609ddd79ac0120dfd0520f4f3382e28dfeab834166f4bb27af544399c117df06450565394917c364a517a7a10c310d18f3bf7ebec3605b704ca42242be2532b00166d6a3534d74dbf16085d493c6852eff9a4b002f6098923ea8707857e1f08087b0e69cab39090569ab59df8e5f1035e4e4d21673831592b446a05eba947988535ba06b3ba45bccd54845d26d36a4a8acf5b6782e12a55d90e55fede0fe5f443b57e811114263c668e91806da972a6f6d3b8e2c66237699a1c5a1ca4396a91b1531d458adee2592247d21fa938709647b1b428d7ec9e783b807ae1f835a8327aefc9f4b359364f9d6fcbcb1c4870c0034c53b7dbd09452e449bd224f1854843f7d54000a7d288613225a6c66381050261fa72a2f9d7912240201ac735ebf77e5210e5befb703ca4a6300d7c0424639ed8d09e06c41ea3a21a87b3950392a2f783faac210726220b492b38f90b45b46e671223379a6e606cbe98bf66488c5223c665151290838b8850524ef971ab8d918c70948a62be09aadea955b105ae642224c6762c520cfc44a86db2908536e7ac4782fd7d2f4c4a151aee54982a1b4485cf6b84f88ccc5ad420dba073aa574da294dcc89232b951f5cbcd89abb9eee2a80c5a3ed2114c21e24537f47c7e52b0555d7db24b300e5acb4375ed269673149d42a5e1e64bd778792ebe96445ed33c946f00b0b1182dfe1aa888605d893c398d48892d0fe6016fa3de9665a7422503d10995676f1b4991112141d832422f23ce245c08198b451c7bf9d64b9989e4b5575dc3f70d5b95746a1b8fb26c7ca9490670908d724c3708996af3b9d664b044f7e4950210a2896d13e54a8c1f7d0e6e72c37b53195b11f30d1a620462c02c65470738455bddff7ffb1cd289338ee9cf3bffd169a7650f9ee481544605c7ce19063a87777f180eb77f908f230738a822bfc675d2a4ec8efe0d24fe7fb14a0ea168af7e41bdc822cd1cb72f73e212f3f3d8cffa62197a2795d2857d0aad8af5771079c68935f2727d1930466652cce0dd947aac90e430b2a3bfcce0326298cd480b9a03f2f721eeb4506f5df67403669ae6c7688576cb9dc4aaa0f7f05a11db6c48af522f74a69b506f740c4ff115f2cea0c5d2a93d8d591175445daab3c24e17e0da5b6dda585683494afb3c7423874a235a89de6ea4dacc0a3c48d6e06d83687faff2fcea016a2822cc25d578c75ac9f9b68ebb531307f8ba97f3645361c921369f25656f9b38e547bae0685105b34d0d0e8cd3879973c2ee6f1d99e63a669534d9fa7baadbc97ff89fa9f161ae23dab1cf8e388d355433c816fd73404dcc6901c10c6cef13b9b5bd7fbd03dfab0c3100e6e3dd88187d78b3922eaa803e0ecbe3e6c374cb85dac51f0233f075337912e82e1f884e4018ae22005352d4d3d159d81bd40a5ae914f07f26926a2af720f373be19c36239f2e9b50cbda9dfc7533208a04eae2cc68431bfa0418a0b976d3a204f71c2820c4ce2db4dfa5f66d2e966114c59d143841bc7e82ce9a2347ba002a6d5777fa5f8588185503bd70362e15a845d103230c240cddcb4d0edada2be960d095aff43f20d68f34271cc69cb4d40260c368066823d03b837e0f44c57a602ca1b70703dfdc05bf56f0ef9acd46bad10b58aaae821f91b114da682e1ad3556f4c28875c2e5a3bee0378c12624825c4cc305d20b162ccf76502e3450747f0795210099606813a90863cea75133814bae7767698a76c016faa3ab21b61c5498633d55466f2d990760c00fe48e7d64417e3a431358598fc88f0b78fa200165b40e5ebd40e35decaee6fc696ba546c929c72813384f43923a4138742a443c24c5dbaaf6184b6badb6dd32450eb05ae99032bc5b1fd2204ee4f1d149f836b084573b97cfbba9bdf45b42f81f25223bd427fa528e3718e6baca056bc083b6f89994c838f910eb9b2ef60e2c3f59f9f05b1c6442df0844cb906aa7aff0291659954c1dd510d9dc99bcb9576e21e297124d771adeab31478adee2e34f27e5352d8a43e8499e2f3b07c51babeb5ae7491b4183a66bd84a1b6b4d124e87456ea612a4da147ad49b5fde21ac34ce49c8ac1e364fccf0bb099a75af914e1f60166008fdef134e3999488461f9bb227825df4ad75ca08ec27ed200cd0419131ba6335bbeb9bd623b4d9ee96dcb4126f427e8a458567b7d36f13487dc140bb2587fca48162adc67cd0769bcc09d309aa6d09b23650adcfe97652e00d1e24f1d8d2105e0523ce3deba68e3eab113c5aa633637cf7b1ee413dc288de57f0588ed27cf8ba0732e5a90bcfef8419f1acf73f6318f7610ab07902dddbd5bf84a4068f5249e6d5f6fb9fce44c661759ea3ccc76c031e814453d05cb71461b84aeb028b6143ea3e0dd4231e614650d452a423b5a601db29685d05370e369f4939aaef07c8c1f73f17a51b5e82296cd0299904a098a7c97025eee55d14b29519e75f12f5dc09f4baf55bb8e58c4e061c80dcee40b8cbdcb662a596e9daea7bb60c8ac2a08053ea37f2584c6a1ef5e2e02133d8abe25848e94e61af5381192c627f54a121934a703ca941684582056b24a07f26597e77e2fbd1946fd6760593e9d316307dd13c1cc5cd5030680fd9fbbe537813459e0f28c39d16d1f823a43ee45b6a9ce15d5c0480fb04a5f9178aeb1adec2563e0008b56d2882464efbdb7945bca94640a5b08c60743081ce4f6734b7e06e248c2862e84f373dbd21591dbec59f971fca3e6421e61422e452bdd18390e23bba217535a0907ee2d6e8112ba4e646253fc3b3ed9a64c791225174c1d9138454e59698ea223ae742e713764a6302ea9b9f1a8874b32b211cb9187e32db9f52475d1e32ff6f1e12e1ab1cb3f1d2c6b05298505a41591c202ca5e7e2133b9118c9175771e7e88a6cb11e7684493021bc62746401af40634583445baccf58f5a6a8818298b28ee91cb754cce90c4cbb821af31847361c368148d5ac8cb183e2c09643e3afed286a28ff69b0d3c1ae25127c05ffb0858edab6133faed63a282cff63dfda33de649d93e123009f2d15e7a524640030e358c407b157c827cb4eff12d763ea48c407b29db47821afa4be0c3dd8ff6d1107dbc411c7f09619deab2b1cdd67991b91c5efbacd142b14bc7a13a2939be3d1c1e7bebf4598eff7bc45f375eba14563e51617fc3a38149f439c206907fe3dba321faf41f21295d59fdfca8e58b928ba568f4c5a42f1e6151f2d45ccd7c03b13457ab29af944fa43c41698d2bbfe5af66e6929116a52ba59371e5473594ba7858572f041bc6a335a6b02c1fc6a75fcaaf76257db61928bffa9939e77cb2f20060836d8761793a9ebb16747c7b355ef4d1e1235e2935afc36379dad778ec53738477a6cc873a2e657b2b106ff968ec816032cf1e83fdcc175aec6bea65bc50478c97144384f1629037642615f6a9172f05ca97f259be7c50e25c2925273f8787c36b216fa1bc76d2445de3f5136fc9674d91bf153971e5ef68b234f453895d20d05f03096e3c0ed1e7c627a58c5db279e5c735983a87bbf27b4a3bd12f0008f5122d574a19a5a419364390cef1252197622e3197984bac8bcc6426a5c8921ca9df94321da386e79814cbe15c5bf7896126a0946294821527d6ba5a514a674b4ab9c8cc94524add23bf5ff756c3a5cce73c654f2ffce60c1bf39f93e38db367bd724e2b95e0eeee320773777777c7648c4ba639991963c6d8c3306c323327ed650c0929e7a44fe56cda22e5e7be45d62cab5ce4dc82512e1bc7338b8f25e900c93927bb2acd2a9d53c75f2f74ab29c0376d01be2264bac7cde71727e63b1a0431df3cbbaa7508114782b5f94a31ba84ad52003fd8d465242cb818c3dacb485850017e81050d70c02209ab821dfac1b7018b28f216635800d104c3304c054b2ea840cb009ec06207af08e78a0757b2ca6abff21855bca06b34acd8c1698d1b97a051458aada2835395266b650bee06537448582cc9ace4dcb0e6aa9e7170552a555293ab4ada82b7204aa56a6eea6d6eea53a92b7eb8a92bb0dcd40d82e801a8e57e0123515f918070516fad407151cf483c705284aa904191aae474485600a1564a6b2e0dc0a5b40a1f5c6a45511534e01e84418333785812f2c1aa38d21281d0c419480c61791c39515153ac649538f2e5eae80834260c1555ee2cc09d54a471670db09ce69c734e71842b6bffc089271ac663871459dcf9727e8d72e7dbd51457eefc0771a494524a1b3421a59472dae008cf0656a42062fe9cd3872f9cd8d003305a70848b31e79c938389020c1c512461f5824d8b5a6b553d11860f9688a2972788d0030a0a96d4134d442726cb830f9d1051504634e1a29c9218628342d4219d407b22c479e1244b41940d0a317aa84318695014e107fa6429b341070c668582a21ac50e3c4c178448a25140c941c2ac86bcc5350a24807061082d5140e1c4851428457185095c2062298a1cb8f0c4c82ba2310304cfb03097ab141145006a14e1c40e4554013a29420758952280e0a40726b4748b992a135dacd0ca8526869e0041145104af6856b1b10d10b12b82cd0013e19db8a2497d31c41bc6a42c66d56312bb20c03e31bfc5206ef99be0faf340c4bf566bc31587ffba212f6d552c0c6dc41bbb1e3f319f51c1b9acdb4b09e2e8a834f6d3b3bfb8b69f2aa5a1bef03b893e33fd98e4d2db3310fcae54e6d3a25beeed1ef81e84f8e27acc47c45b3ee3840d75e8e09d7ea2973e19b1c5dfee1a18c6d3088ecb1db8ae354ad17ee35a6b0ff6b1ead724d8ad0df382284563217e7dea15c9324ae9ccbe30d2c7aa473f529b6ed9e37b5c62536c395060b19f397eb0fcac060cc0a0728512582831f9c497b10138f2ebc962fd5b7d5f911217507ef09dd8b7d773a77f8fdb2db8ee188350843aa5ff832ffdb02f94f383b0aaed60bfb9234e82d54b3df6d9e2a89b882f1a88a3f3d957d4a9e3e637bfe370b4f9126befda59c72cd6e834de19b99b2f1fabe37f968b3407da4d2ccc6524a3265a2db0db6524a3237880646485910e6a58ae09891a24a108260840440d8a3080218bb5d16a52032d60036ab0342f23f5604526c5d32a0c16e2ad9dc9c308e01300b0e38fc9bef10a41ba57b4303100f35e6830e29c80009efbb12b7edff82c9b8bbf79949977ce9106e30bcd205906c18285b1f4910e8e4dc3505046df12843484b0d20eb604218d20323a16383b7078ecc03140eb1aa051a8020b50d244af95ab594dd178de110eb361aad1b204be846c327a1a42b00ca94228c01d19315b380de756ab93d0a3b16d31cae8b1b52933efda36d4dddd1b7377d7399239b20747c75fd8ecee7677f7d8e5deb1bbb7d34c0d5863c0c72efe2ea6408169107b49b1ae07f65e986d15fb9ec6b288bd0cd2458be130c7d2c9132a08bbf87980dc18262d8679956a84cc74b78de3ce89329f64661bba7f5766cccc9699ebe4103ca1583ff5a6645469c1a114aa4255e8052e7e55a494b40dda066dc3c6c7e8d3261b9f37ea853acc1fdfa56b524a29a594d99c2fa59452babb3b7f3dd2203fe52ed863d8d4a2820df2cca47429a5942ea59492c1adde60e3b39452b2942e8fe0a72da69c5272ec32659729bbc8c984c904c90425cc39e53bc628bb4da13ad8f82e6990a997ecc8c86808a329514d4d72367199b2a949ce262e534e2967939499724a2e7236bd787c9fcc2e19e717b99c3c2544e614fb28eb9cdfe3d393b3004e6cbc731ac166e34dfbacca4c6699967dd56483dbf7f4f6d17e9edf13fc8d7a717e766adadcb6d7e6c7e9fde0bb3df5f8c6d82c03468d0d573d9be296ffc74e0c7bbb1f7fe727d303ebcf752bf2965d8fbdf97d27869d9f7db6413965fd2f321fa6d3b25ff96fb3004e3c09bddac70273d3cdb0d9036773c28a0f4337895fcb567e58c18dac0323a594527ea1119c989898ee7e791a2ffcf9617eb5aa55af52a9bed008cecf4f4c4c0ceb5931ac2fe6865dad98c8bc3c8dca0b8de0e0dca059794c66647e62626038bbe2602a0eb7aa41b5adf2d26112192691292dd5b5bf2249e4f5b76ebdf0486b1d0a853a9d78e774ea3adee93a7669cff18ee4b4df78476e9ba6f18ea66519bbb4fad2abecd29ef2cee9b59fbcc33ba9d75ef24ecef61ec63c18df68df9ff23076f59f3cca3c926ffab5774fb24b7be94d76699f3ac9937fca637679cbe7387bfacedf7e117f2939a97a4ec5a99ef30fc9e993d244f5aa6fe6552a99998ff9f92b7fc1fcacdf9e6b2108baf6b9af5e9124f2da47755f68bf7e6ec69389f12c8cb73a72398ee338958ae35e5eec498a8d6deab680edd95b42a53e0eef43c5e3e4ec943f9fb9c8a30c9b7d6cba217d4d03927d614552e443fa49d9a40cbdcff695808a7c2acdaa57de8af960ed7d8006dd47639b5f04491874432925a0529fcab645ee7ab40ffaee7fd2b447c27d32d05cfb1aa7d99e6e6603c8741880dbf27b1c8dc3636e75fbf3553d9fbea755a7af764e11ecb3eeadfdf6c278bbdf5e3e36ddd46f1b6fcdc9ab39e7f9957d65fd4217279f7947fbd3b7abbf507b1b54a47941454d57e39a93af79bd3d12fae10cb79381e6729f7aee1e502f12fa2128a27df745b4efad3f24f44329f39bfc90d0f65cd62bf3fdf621e13e294d645ee6e96f350e78ee7e707c4fcb78d55b13c717840da07a99afab42ca7ccdcfaffeaac121f3f337d5b7b7a341557fdfa00ae6653c1c3532ab97f998d43ccd3391f91baa9f7926aabff1d65f333fbfc6b3dc52fdca5f377ebe8ca7fa1e87f1c2005cd557a47bbea87ff14223ac74431074bbdf842eb32bf585ddd7bf3d5feb6dcfbae1d1784c561f0dda0a8c98811041508183283e3cf3d9adfe0d1e68d8fadb56fd45c3126ea3c947e66f883e43d48749908fcca67dbff4b46f85fafd80faf2bd5b81ded63efec9930dbe62bee3623cebad292718563e8b85af97952ee60019e2cd3ed60af5d23742af0c7eabd2152e98ecfcdeb6ea890436f617951824109b7cba3de6965797df0af5fac73e415d82d82d3ce5d842561ffbfa19e6dc7caed7bbc9427dac3275006d6a6aea72b125d46fc1a873642b5df9d987f5a994a1f7d1be12b4920f957eacf3d15fdb9b9f451d77730ef3fafb01fd45b0fa2d18e9b863a0e2df6c1d4485c7d073e707f57cf71c9fe3f6e750419eece9f69f7430337318743d36ddeed9f568f693b3fcf9b2b080db31b05658c0ed5f0037dd3032bbead1c468cda6c635d87111d6294fb27315e8b8f543a2e3d69f3eec4512996e8d4b1c79e29491a79550ac6ea1fc0ef2e137ec5898efdc39a0629f8fed6bc7c2fc2abd96e26e5e91ecf96a5e91ec63617ddd0b5d855b3f242adc1a65bb3c85a0af0cd87d8a7d2cd82eb6f86c5314b1b4165d6a72f02407368842ce03d2164b785ec7288f36c6529c174497df89cbafbafc85245801d9380496b1ec807451dc391e6ebf6d918b6ddcf95d3ba7b2e06d08ddb0044aee6cbadb77b92f8caf6ddf378c9fbd772c047953d3edf19edee16a1e17a1cfb77a45e8a3629016fb045b3fdbcc96ed2dd333bd6a55c3744cdb4ef54bc746f5a9bba6f9d67a6bae6bd3c63a76bcf1fd95c586a561fec81ff957917f26c67ce10ae60b2dbfea88e872eab35fb862b141842516a13e2e62ed86c74ad1ebc7589c915fc6d58ddc754f0bd51f6859776466e62fbef65d2337333773a41f63a4941e493243e7546c6a571ac4d260fc8c1081e185af71aea051609b99397baf34f8168b62ccb237d2491dbb3b7667f1e5b6fdb66ddb16330f89c77844e784418f02db4410613771fd91ba09de6116e294ed88066583ee99d751fa8829ae431147252d0baef30be79c7372546c3f7fa1ac517af4b420ba31f7eb12b26460e33b958d19bb825d91f259baf7732fb179bb7bccbbbbe3f01a77f71befac777799777787797777777777777777f71fe2eeeeee38eeeed57d453383a326d3b04a3794e54e5d4a05f3728325a3847583663523a324060c18d58b92ee74ea524a2cead4714a68ad7453a26595e6f84e89ccd1a111d939e4155b70f4cc112d34976a15ba3e31724c3774a62e10601fd7c23e397450d9857dcbef3a439d4bdd85bbfb7b8f9618f6ad79365b11b91ec52676e4e3dec2cf7077af2291d8f86347b99b73dd845fb6871bb95c356a3e8c6b5cd6cfcbc894f8f2acfad4c7eae476dc5ba6d6128bbe88568b78426dcfcf21022e53c746452ef126bef64cde8a356b27f1e6f9c75f9e14562391c7cd8845456e9dc8976826262277125b49a9a8b97051f21797c8d35ac49bf85a70616a2791a7978837d1ad75a2d84eb468a9f9c215eb0bbfc64931ed84da3acebea852b3fb81dd1b344966acbea4994fe67333623a1b7c4b1a75094530315b542fee728975a225525cc7c4c4e44e2ceaa4c4a553e294b86c182dd2a2a8480bed732dcec4a5c1a8466f914b6e8cbec68d436057fcb05d0bbba2141cdfd960f943d7d2ccccccfdee9fbb96226c8cfc6125aae9192628fe4a713aa7c38814bbfe1b31c8db3caefcdd3d41b1f4b18fcffda6715bf65aad5ddb3bebd495479388669986f5b66958779fcd8dfbc2eefbe91cbed147c3beb0d2d45b54ca9e1e75d2ba8ab179f577e93289bd4831c62aabd58a777a48b768582b76d9558d0d965ab1974fc32f03649ad6f508b2e21dd495cf383f1f9006654c0f36642c38b458f98eb1a0c4963ddbb24cc5230a214123a5947ed635f6fe713e730dd2efe94a64bdf31174315a44f7a675cbe03124b1ec924f3d1aafa65bf235cfa65bf2376fff56ec929b7b2cff90afd86028aba1c807fdc21a8a2ef5519ffea84f7fe3066b8cb49212b726c1aefab1eafb576badf463cb4ddb5b6bc79ae6f0dad12d6eb5f8c64fa0975ff4f945bf1dddf2c7be70bb61bdf38b4166a928bd1d382028b9e8fdfd2bedea9d8d4de6784dc5309a2465e87d28f6a5d0a04c815d724a4c0576c95700dfc8df648f14748c6cc8615c39a473c2958e01704de45100dfe4e01d156e5060f0a5c32ef9f3637c92d1afaf7d3603a25f310cab7269cae0d421a961c69578d4f9e062d1d6f9d8ae4f28ba3f82f5892311b5eb9e4f1fa134189f28b1db0c341c894e78a76ff7f18412b2dda35efb6c72bc63bbbc46c0adce7e339c86387d7dfab1566befe9749ac15f40521f0ca8cf4883324a2cf758f730af7ad99dbeb3dffd0cfe02bdd57d4d755b87717d7aa95e4e24e097eaebbe1b724e9f0eb77b1450b7bae77ff18274ab63c1ef0a7cd371dc6f282f88f5f8caedfef49da058ec27e8af15b8d53d19b7ebba0f756ef7ec5de7eabea79fd8fef89143eef6e985ffe40569b0fb976e736ee66562663e2b1353ebdfeebbfb5902d3bdeafbf156f7b103d260f72727acfcd87d4c2452fda97b98d3cbab4e1f0bc54259d4dbd3a34ef6843afdca5bdd9f76b0a7eec3d5ed7e86ced1713becbbeed9a6fb8ac4a2d9a726b82d08cb0daa61c615ad8b51b4eb9f7591c84776fd6b17857cd4eb12099273b7813962a3bf69596c162bef64cca33d6fd66b40b7e847af278506290fbb280a7c43a906d84561f016cd00dfd06ae90b7449763d2aa5f4638c315a22fea2f1894486b0f6535f14fa58402fac98b7cf3e2f1fe423559f7ad5c7024ad1c09280ea6154413ed9cbcbfc4b4d7d2f1f7b2b4e919bac1cc795b7e8c378ff42e7d00869907e7b400d6adf4f8354c6041de01d19ec0698c79f3e911778277bfa30748ea66d377adacb08d9909788f00eeae96780794e4f5f039cd33dfd0e700ef7f48b70cef6f441c02f1d6fd19fd1e1ccaefa272ff24dfdce7306eb731e65b0fee66d0cd6d7f1178a932e7df6fada47fbeb117dbff42fdfd0fae9b08bfe098adddc7ba1418abaf523c22e4a9ffd6fb59f7ad587e32dfa2f40f653f56365f5b38f95696fa495b4ac6a35ab0f7a8bfe69079b42e760b9d90734a5c1faf1eb740e4d143af97067add507ea9e7cb0b171b0f10ec7925f5cb71ca65b1e39de9827e31b7faec1d6b2d8adb9ca2ed724d75ff4954817684a833cc5c636dd200873a3f6608b5f37cb7ad8254176a11a1004e3c0cee96f4757ae87777a08107f116100ef58805d3c14e01bf9d2524ecb62b51b72d6f9f00360b1f236734efdf60360b1f5fde7e9bbed39a0d367bb49e9c7a2d91bd9329a51a6239dd3577e922c56de21424e4416fb285bf7eb9efbd67efbee7b0e48fbad3f963b7d23ade44ddb9b8f72ecc43a23421ab1c929de6ae951640fb51091d785c9859c49cb1253176ff563515af2566b51aa4a995151d2512735166ff5917614c588e3a4d745de92d2eb28a827442dd44344714888a94b149ae1486bf196901f18881c252d49e9e9e000e9a95bcc13194e7a9168860501f601bde5ffdef228e4adf68e784b7a44bc253d21de92de4f0d273d203838e9f5e4e0a4a7a383931e8eb72427bdff38e9adbc253d6bc349af7a4b7a2c80959dc14a8f0501f6a9de72d90918f216c8498f05243f18bcd51fe4b371ebb4590103e946302e237df1837cc55c19666e7c18dee98f30ec8a32d4db57cb627d75e58d4fead7803d7d09843dfd3e1616560d45379c6fa495e6d785d2f53fed6081a68438389d1373c4079106fd67f7d3e0ec6910c7877f83cd4bb6f0c6652d872318bff0bbf1f9dbbfb0ef3718afea200aa101668c31c6c8aef81e5bf16f7c8c4a4a428ef4e0064764ecd84c8012853ef56cda61981c815235246717135309619c77c5894f66b0f20810b656cac4c474e4c81115143664a623a4e61df9354b42a6c1e460436682b2bd98c15c8cf47041709d92ee74c56e27948a092818daaa6cb02133f15175e94920423a8bd44b1362528aeb1893224f04d231e945b506962337f222214474705216757a51ca89b261d5ae62d738fdc2f9be756c5ec13d874d32738c07f0c2c2740eb78a1dc6b0c63f295629b4610392152cb0e189248c80c40dabd665a4329eb8a7cb483cc8610d185bd1e83064b208c21658ace08c2cbef0342a30450926306083871900c194c4134af8b0050d2c43284388223ce1c5510f16a5140013765eb69203130428b2f5b2951c90a04866108159c961e86e97ad3461a3d7702d6104932266a0841437306a1fb41449741835a805549a8cb6a8428910d478c2a70a2a866842858c13302142900c94a0820aa32fcc6062061a407409c3084e4c21c4141d7079820344d0c0062e6010c590920fc188043734f1448726286109679cc14df082cb900cb890b16404dfe25a18074c8c8104222ba46c9101ced72c965042b542c4e4486594016385480757bb6c85080b256af31bb513467d74e5092b188a201714c1a8054760b1c610429e250442f0392aa3890a9a60804614a38612436432a4022f24242424b4c589932daf4587036891afc396e82de4d19b9c6c1c5fd873830d13bfc8c3374c126f94427fbb51250ebd0f76e304966f84e996cb1b3e08aff2eb7e649c445edf912de994dd4a3d61e3cf2fda25fcf894131b8db055ece5639827035d210addfeab55e6d56fbb014e56b5c7b4ac22f19034d03863256cf62b599379d4c3784828babbbdddbbbbe79c18f6cec4564694324eb0c619647421c50bc808828c1b968ca0ba8cb434c6cc65a4a5a4251a2c4959ea610c36c640c21867c85c461ae34ad218518cf182315430c6500e4968a265088b09c4c8811855c49881182e10e30731726023e632d20fb460f9c11596062eb8302c38228816fc608805b76b821117264b142c2bc0a2888b824205b7a302e5724610714f3f5c19228b10f7e53252184a9edc4e8d2b29c88282ab9d11c44d8101c44565f1c3f51b5cf1214b0f17ab82e8a68a78b8f40527b8d5881d6e0784934b2f23f960071dae652387db3135b95996a1bb8561828bf10087bbe180c99d575c5992e5869b4971c5862c4aee160329743b175c69cad2c69546b071ab1057d6c8d2846b2f23f5a0c915266459c2dddab8d2258b126e97c695247041421635ee16c6e730c3fa11ae5f4602030c30ae706a051ea51777f2004540480bbe04549f521a238db45aa01f20ef6d9a4cc005e6f1e71d5a7fae1a9c5f6570b0212bfdb4108109580003fcd2a94a3ab5cef97702fdb06b2ae18029ac341f5c71346b28c5408ad534987d2c1ae96fb4522c64d51f33d6844666c4e6a45fa433624f2316e7b4737e2c6c3ef6b1300c9b139bd954025cd5ac583435362be660cc38b2e2332a3a02408d0d8b66b5a259ad6c914dcdaf56384c4c61f31d0489c5528079f855bf21f4931f0e24f586b4101d6cb8ba14c0b1d915c22effd313db92597eac39b1297f4a39a5bf5c213e46619198babbab7588191860977c29dc775ab86f488331604f7f089117302f89bd1660579d31e98b47f128c3c17182e3afa885192bf94f6ad147b153e2508348d90c6c4c3aba72a59d81893c1790e11d0cb08b89020cde0879626bad4cb1c8a4e9c0daa0209ffea98951b3ac9ed0f276340fb0f22bc3aa579dc60acb3ef533d495f5ce2484628c1c86b591235e926e1561977c0ff08d740ebc61977c29db73de06ee68d088c300faeb87d6c73a1fddfd61970c13ab02bf56de927f02efcc977fc32f06230ff6f209b023f2642fbf00bc739379ae1df6d26f1579b0afc53749270800c3b00108615c6a0a51877fe8b44efc8142ff40c17da0905d9f73fa9c523be9d0d9d9c8ee0737d8fdf8f958f7c39b92310c8b18d6da09094a763f5cca1fddfdf0ee47164baf96c56675326d6cc3c1649bc7d91b564d567bad734194514a83505c4249c02ef923881995523fab948619581d1d22f3669d8feee228b294526efab1d7e3587772c262f3d3316fd8d42b6a566b96d55a9bb677cd6ad0715cd771b33d1edbaf6aa66d9f0e8ef6e9e0b827b3a4db9e28875d591b1362dbb8b94d8fe0abc5add9fecdbf524952cfa32e62b14b3e0ddf14619eac12bb5babf5c3191b1c21754bbe94ec352fab300d629c7bf18838c58b4b744b7e0b8cc06a8c825df2e3137ce351a278378c464652fb19fcc57df1894fbe51f7b410e9c355dcd0fa0d1e6558aee2b27bad350bc08d4bd5ca0b53f10bfb6cb8cda673e263fcc2dea625a57c7e9e99e117b317bf5bf2d3b055e9a773429d2b5f2fa49342e7c897cf2e798212df0ba5d58a5d2ef4db2b1f8877fcca1701bf70b8255fca9608e057c8d3b15f401d060dbf70bcc53b4da441f92f6ec97fe1c89ffad4bb55e7006159527ab9e1eaa66eb7425fec5babdd0a7db5f7a858edb3a206811a940f34a48508b04bbe8f1f2a4a1e15cb376a58b20d468679b19734d2ce86108d146157e5f100dfd49ae5f0e82e07a7c1fa59e61969100625360ee1a0842c8f06eb6799bcfd5e03d8557f93c9c1cae01749bdfda83fbd4f57bff690c2699dd6f568b2213788a37b97a74e2bc2afd3179d74ab7efd803882f635e1d6df28277383fd10e7662feeebc7a1531c7a20feb2df0a25843d7ddfea22a95d8f9f25a8afbb38d460fd9313566bc2adfa462c0961939e685eb5ded250d93357351dd8556313bea99cb7e4861208f970acec51570af771675f1c8252638dde12ee71781feea3a269bf753d32da0509ba5aac7555ad91f9b1b28f393ef9e2a2938e43cd796c0486ce89482292be8dfad3671f89bacf501fe8adfaa78cfb2efb581a4bd37ed3b22dd3b2f756cdbefa30b06ecdadb1e885093892b20f549f94b08dc958794cff64171bdb586b51d7b24beee8168f6ea598a7a5e29d137ce686f64acb3b280cfb0dbba134bf08f65549c106a5ddd1a0b49db303a6b31b3b20a306ab538e51c29678c7256c138505ddd3a3b03f7d2c20fb27d59f9e7dec07f954d4a7b0477d2c20d4a73ef5d150c30bea837ca27d98b7dfc37c8ca1de3eca4e89ac18a3576f4d4c27059dce99f1e8d3c6e8a96e276f47b7e6470f64d7041d4ba1c1d9e3adf9123b256193db61d32d8f6fe6a901dd9acf7f9a73887d0cf08e0cf602cce33f5fc810dea13fbb1e18a555767d213abcd3fd7c149887fbf93cac02338073b297101d1b73dee63983d86b1e6510fbccdb18c45e88bf5013fbfeaa576de67c9fdf29609f0ebba6ce9d18b6f2d6c4308c6215a3d869074b3f7c1bfa014d9961a60e8abc314ab13232d94894813b40558a6f60bac6dadbcf2cff7eb4f6406fe1780b356def4aaded1c2d126141bc96659a963d517dd243dc72a795ba67350832ab35cbaa740fc889069f68f5b34dab9fd1da5d295b966173238e1b639aa6a27ca06e7fab2817a7ad88b26939750bbaa7362ccca79efd25e3431f27a394f60edaa53c3ab90da6e63198ba55ced2e7b1e3045a6586629847867a67784786d5b5abae5d8f0dcbbebb8a79dbad35dda230dd52a5f8867efd2cbbe8cbd86035201de407e41dfbf45bcc7302e7dc20e0456774548b3a751c10c60246ad2bede8f73418843a901d0e82dd0ad86b0ff3aa1798afaa52ffb2bd9156da364e92b9f483d0d73c5ee2a688b2aac926d53e97a27dd65e0c49e4bffc9e35bc722fa2b6a8546d58743de910d100000020004315000020100c884302a1503420c8b2de1b14000e7398486654170aa491280762140541c6186000200018628c31c814155501adb64ad121e68267de05dc66414b0192b2c99904d78b62811c63441cefdd086fa45d23c4ea2dfddcce1af0e3e2b9ddea3d2e65bba93f07f1c59389cdc74e88304acf3892d9bd7ed743c5fea13601808dedfdb5ee3a724f371604e9c3c41cdd767795a0debb90827bb90a030e1cc1dfd6227666abe0f2476168b85d92c8105e546b2f625141bc561002aaaf419ad79bce52906ea36db067f465719d7696e225044a49a1944f2cdfe99b65d335ff143e31df13fd157505f6c8d55161dfe7a963941dcf6f1784367056b8ac3af7f5e79d56a67d2f31b99adab1b456bcbb4c903d55af6a1b08d975cc1839f970c4cb19b8540775c70c497c8614df17d3c1c6d92d3c4d6a393e768969844f72dd9378672fe1767d6bacf8ad3187b109d62936792a4714f90f447c46d1e2d714ab200cd582025ecea6c41c44b72991bca4827d5eec13d91c86d14333279be7f2495e5cfe611bd1395a911d89829d4138382b157cd759061644b49a4e62f79a67d563ed009d4439372611ab04b89027da8ae8fc1ff9e26894452a0dbbe52e816fa154a9015b680808e3231f1967445fa0b6cade0e21f5af7a2a63c6f04da34723774ec0661b00eae40fa42b09e00adc0c738033ff5aa9da41b66d1628c3473c368cb861967c284e6ed6536b5c83e56f0afa8ef4f7cddc1a78472bb7cafdc0cd1ea4be39889d426dfec678ad6e36fe4714fb0764e72713109a3682a42799ba8702b186ad25858f05f5a92721cae4265b49c34890713baeea52c19ed0afc09751e5e6ef9a776299d9a453d27c28b6d2355b92920b120a556c08a7573e95b04b50e1768a299818d10d1b0c6c9094a98d6413960a1f7d66434bbaebd38f3365d2a4e280a540453a1f4223920964ead75e64f80f9c31489363b51bec9705cc492215a5821e42ff28aa40794a95ec20868a655ee4de7e1ef6aa196f3308396955d43125fe9c24ee23ccea8dc5fb48a9b02aa67ae73fc284c2609569dd126f259e793a6f130c229054df76fe23a5da284618ad2a2dff2317080f55553d41afaeaa8f31e88530de31d809fa84afaa4060733b7d1bbf0812ed7d9a4f721a0b43615996bf1a0bcc6c2c9be85ea43187100ad1db7a5cd23cf6d3b7237ea15d8920f8b6e0e4e44545daeab9aaa6a6ed7c4376879ae63d2a103dd7c5635ee02e00a1ba53d33c3261721a8cbb66166c7dabed3e7250b2a2a6ef6d24b56610f6ce4092ec34e08ea0665aa101b9c74981c65fd001986baac1f9dbe5571fee8f6c82a53d14e384038a60c7307d62d8b99de4e9fd119b6f92533eb4f10b70844a04b294dccdb7e86271bc4248c5c9bdc46104c2ad0a53bc49089f8ed65274b951adbe23bca97a17d3c55b2a3bfe96cea8ff886e2bdee6f48d59ac02cb337148f8447e94a314117c400081ef43b57446fd8ef046e1073101741cf7fbaa0f1a426cf4d4f6d3ce32478e9123d9a85d65b97488fb2b10ff4fb208463a19fef524dc6d95a7f517e1247a350b3c63ca17cc9225685af1777215bb009538521557088e156155fde15749a2fb1fda51ca913828e380c705dd90b1e1dfc973a3131b1fb72a9273e09dd2385222a2e495d4d3a53572a27eaa1238cd2ff51cac5ffcc2c02dee07d88becb4ad30ba7c4c04939deefa2503d75407a767ec217e38393a0d2ecf49581f5c84d31163c62fd866c581093f60b2fae4815d615ccc74ee1cab7492e25400f5556ac244f267636c9c4c5a21172f42a8d6d8eec256c4133059d5c53e682798c6086212a1c7d55774db521a0de1cbf3f0492386efe7d1829b3be6d50b1989f68af2264c77d78fb6a38d6a9c27006900141c17f7879b60a74e64ee56fdce02cd8d5c25722d2792c9aa1029170c2cc372bced2357f48696905c5b53955c7a659029067ae3531fc7d7743cfc82d23c48c4f99892ea7d184ebd733a70c2ddc33752b2931059f67e41a0075b4a3d17bd2ff0d11279a121c0060dfc30b1a449f612e33d5811f7c63a03f81b633dad03f9c8c43144ba623cf0f60698c9ffc860781e4b6f04f7cdb33ef6831aa06f4f6824798609e339957358a4ed42f6d777928c205fa88959fe9dec7f8532db336203713f4f21d6f6122f9eb016717b46bb9d8860ae03f2d212f52006a300f31944876959f48a5ee16d91baab620d705407c31ceb3a6b42f00c255d2f3e828625d3895b49675f695e8b66fb98b5d05afd4ad7ffb9888231160f42447bf7eff30819e938f6a52fb9c04363bf97f4c5414a13b208bacdc17ead0456093b7fb2369a244f849654e9cfc340c471993d1e3ab3f4915eb311a22d0cece2fa919be8a2597a4427954bb9076a0ae69b0469c6f4ba1c2e318db7fe076d243429592c90a360e2dc889d999d7816b9a63b122e48508aa84dddbc4d8426aeeca2bee81e187d8e2ec0b9b82e9a2c9180968426a6bfdc06cee6d17abac1dde03a9d6af0e0874d72e753e993263b2599500d08d944ab5564051a10a0e536a7a935297c985d2d09317920b5ea574b1c6c8bec7e6d7fdb98a68581de0e38630036c1409bae8df108a9707885b5cf0841d69cd09abf9996b5e475633d494e1796c700dcbd74d64ce9220c66c32b3318a4b1d38094d572a390f65320c24d4888c4645a8f34dc7b6a50fee352779e8d90e9d5cdac20e0515835cb03a819cd61724debd0383ec328abe6512ca6ca1d684b5b019cce4d17ce46e18a5a67051498bf3c42745579427c8cbd19fca8535393bf3c0c30d98f04bb8a1c99dc07da1bd04d135b11285200767ed4373f87768a660c91e51fdb1a3351b43537b613c1fb9897b4daf87bf6fa10f414709dd2eb20176c1b52428f071c987b563edd726f7db9bee413acee6ab92da64de4e204dcc74dee9719701c95c6e4a7dcfd5af771184a209a9e80673226882b136a71e609ded70c7293ad46c8ff9c02da7c12cb3a4bc537060ac28867731a823c30cb62de804a186026e937c80e8d8880ba0be97ba24805564deccf2c3189b4708e543a4c873322aff11800904e9f33992cb4e7d1ab04dd12cd9fdbedcad5d25ba2a1880fd567ea77c9c6fb1f2bd2f8e183f6e3661f61095d5e898811624806b71b7404e5dc74b1721e353576697b85e24374b78019f0682b25c779f32b527ad3ab93c88f129b3e91629438eb288db08a33af8d489679378eec838c52b407733003a8d84b998d7aefb39b1c8ff18a370f083f6387460aa09c7450bc0f9ccffad59784491efb640622727de772c5c53b83bfeee59482dfd0fe0fbd8df278a45fe95bbd3494825c2edcab25571d2ff195b756811c65ebd0ee80dd600de274489d0478a5be74fd39a8710e7f8883209e926300270effe1fec05672780d41612633cb6420debb15c6145af01e1cf8c6086f233dff5925dc97cd2a89d2737e74b0da8c0486db67243089c587de1bee42ec1977d1d457f9b75e6d988f6918108c7903495e191c21938a52ca0c9a9206bc47c4eba798be72f9126bea561470f21dcf76cae091812455de57f9ae30636ed4780e78c80b3a0b51ac20e4ff375b4ccc4461e33a8f9757b5442becc0ae8e6b5b44f0baa99036063b7a01449fc12f37561d1b4abffaf89c7c334fdb47ec4c8583da031303907e0c0ebf2822dd5a76606d278a1290fb30e62c38198f6223336d8d446d4a84f0bbd96ea93fc0d692e291744ef4a5abe72ecf1c701ae35ea15f7ce98282df4617edc6792a00342b698b3cdc68cc68811bb8c9834dbe9e0e80d0cd163845b9deb2f766c63b035027ca22d3f1f1dcfadadb8f41baf53035988f851911e8388cdf2e14ecd1836bc77cb2d42ec19e2fb8b618f8c753a78ba803d726d770eaed0d2abec200ae69c04841c15acf60477b213035f72181ab0df77b1950886d7508753c4fdb715f84de16f81a75e871e4c8eef68aa3afcbca306f854f66fea2058670914c556f22e4a605436e3c7711a6f46d5689f0857025c46f40d7dcb1690d86eb0ed6ef3fbe5e0f2e675455277bfe33b09faea9cdbd144a8ecc79184ae29cf48108699f0b4546079e4ae536a8ba24518ebd7590fff3d5acab0ee3fd99e4785c854bbc5fe7da3f5e51385d2e4cc359dc6c2b5c6007cfbf530e4f6badedda96bac0a8dc5e65acc9060fcd1e884af99d102840b2889fc592780161a9fc48c9ec92d1135bebaeab1e128bb0e2f5a2754031f01f99813b925df2c51916e2e5916f54534ad849b34878346003e9e8ccf0862e789ad4622e0f787d25ddaa0d32b567dccc81cebf28d4d01ceb64e80ff753e06a17c926f695e315c8eeb067b0aac0b1c17e279a274126463c1405028fd83ae65490e83d07acb41b2bba5c77791d0e30cac1fce9593115b6c3ab017f630febcbdeb4ab1c8f6d07a11303b00a2588377ca35d5e3249d05b7df5b3a7f4e9480bca93a37c5f3fedb1c13033cc30977e65451a3fe467460782ea48f33c064d1c205bea5ffa8c8062a29a2e099410c688dfa9a8bc4f5a2351bf3bef231a131067799eb8701bc28dc269b4d1ed39974520347759ec502f5f64da015297d3d44a061e3980b1382529b252f07a8a5250cea15aa665fb39567afdb3d572caf7f4dcaf12c9544ae24cfd6e58c1665ac9e7e1c2ad8d443dbc5bb11c29cccaeee8ac42ead27cad770c705b238b0194f77d1224f4ff98a3f5be76679f43e25fa36fac564ba76f7031e90c2e784569c8108926ff075cb8cf2724ae60015922a80725d5ca5e1643a09baad146efb7067e9775a7280d3018a3669f97a2df154d33d91e2ff7915a4a843e9101efc20aaa1a6aea475f8218eb02e890ad1c1cb35d3128ec83d9fc7bd90fe5a986c6357f2f5c8ca05a42dbfa326ab7abd56140040ee4b61880aeb680b262f26d892d77bb8201cb17fd3ea5f8856001f3fbc730d37871d2ce69bb586c81023668967136e0855989f92d9fe7e00fc4115af2a153ff6fc50dda5ef69cb5ca4449242229cdd65bea42e6b98b1fe19b5fd97e2cca219806b17e256a29dd21abf2c5a85aceca816ff5a0c047b9a61ac37eafb0745fed28bddf11e121364a1cb3bbbc25dbde661380e0e1b560fe8ac69bab1dfe152fd34065008520c9b786783b260a71f5cc0c2e2ea9181258ac2ed1a304f87482e43e6bbe10be1f62f503d9bbd6555b413880ac444e5950c55824043303e24b9a14e88e01f039367aa38829dc22721d41e9087c55132be348e63d79760ed90aea7594db9092374ff8bdffc17dfe3f900f918b50be49a3baeca61c67aa5ee82a44e4a4b03eaa10d417c9352f79377dc556e52fdab60fb7b7f6633243665d9cbc2a5241b08105b2cb54003d221bae9b613dc03494c0766d500442ded0e59de875a6c587ee0a74f2aa900d62133981d7054a017527e1f0f2a06c24b0d09d98d9974d8d5509d26f0d3c5afae09ac6de5252536db18b420ccc31649a76401ba124e338af97d71bed34ac4c443d3a945ce163c4a5626061cdccea9b9bc5257d612abdf0c8eee23157458c013cb859286cad6913651d62ac3d81248287f84b32b7467f315b964d1334658a30c4f14179e5026ec2c30e555529436899953c9042b8a196a30443e8928434c31bb0efa6f29c2f8be7108532c9c2b2b46c512afe309045c5c359a7787ef4fdc5a47e10f4a8b7cb995cef769a4287ea4bcc0cbf885d16451964d9a120287346f660b332662cc7b009228c2e8ea9f60038f4fe8609930924b6b08bd84ec56ef9cfc564d605c0cc00e265e7cfe14cae009cb6834f16d93eccdeacdac6e7badadff84e6c80581f20f8e006e0920d64bed46d7fae47a365d89ad71888580282957c19cc55afc347edefecd2522ea26e9562f84e8a0efec7f898c7f05b82743f8330556be75c0a83a32f0a3606e18b3ff9f21b94ee15ae92f9909564b4a664fa72d8ae413223ee34f5d5b3235e659f265839a27af614ffa38a62d4b7908e526cd4e302122709f68f32f74c44a55ba2c2801b66cb199a2515823dcc7436d4ffd033d5e1fa0cf433b2288df9a147dc9467920a29652fcdb29c7d717dc576943ea90ae9b5a393d6b8586d1fc1477b670ff67fd09b5be4022b7abac859474bd8f8f3d572cabb9051ca547247b43489d339d63655bc6d135e4da61ebabc149f9e78da150e02c0babf5038f0984c13ac07120f20ee09c6ddd03f0793a6e622558c994e7350bb00e8c2b5289e6e87320ffcfb3a3651291984486dca9ec8c2026bfbcb4d17507c28e255828ff01373c36d96c97cedecc0f218558981e52cc73e11745d12c98d7911f1c725cce10339321080c68a01c3e2e169e025ac61e52c0dd4e40ed7c9ebe735ef9c229d8ea7602e75bb6746c2147b735a8f6dab5a5cce634f36a737250853531be9023fd4d6412b2ea58c16d055735928677d97ef181c51d170a405c87bdbd0303e102542a9d9cc2bcf71b7ad1510d99a6e46652c3b8814a911bd16ed4a7d54e68bf20e3139ada9727a4e9a9c38266f73f25e37616b53baa7d3700fa4b8be61852ea87ac2866267e524a5f6ee3bb7850cf10c827bafc0e323f1eb2172333df3fac7db189cf11534610db4d6878f9488975c1f807ca7f89490b55688ee625de50dd8f723baa37d137d2cb7308955aef02a312aab1c241566c843bf93971b4a0c204b0368881ca0f66b5b9315e03b1c21b1b9099cc267dbae4c880810c1b6b327dcf250596c7ee5b245b8f5413cc7ec90a515690fb5ed3d481a4ae6f921227349940c5eab5055d3ee976c2df0f28f139d11f79e009ac4356c279cf2cea91f97cb5259350bf1d01e415490060ea217f56038b5eb9720beac1f0a1580333275cc8321a48f3f56cf51a4cde698c6ee246ea9720e33741ce4896eea7e1064be8e5f1af395463b9f5f6c897e46a50beffc65d9de65f9a2089e92ab7563fe32447a76dfdc327447f73c7768904d29ea15a8fb875b887ea37cd48faedccec84b239330201baba091952963db90c6b647284ff145022c78827f368bcfa805afcbd21dad9bb5038dd18a525d890d66dadc241f6f5f9db575cb72d7aadf9226ab13f21ebb5db2531b4ecd5c5128f533a23b6a0f316bcb43b1c1c9cc7f9942b4ca940591cb9e30593dba7c433808c4f8be55c8ae40d9d65665e5e62aad402a16067347e61199a6ea79cc66469f814d222d5ff2bb7c9b8c57abe74cfc6b28ec2ff16e5f25f651950b8030be98a3471a2526937a7861824678cf2ce12598826f90418662e0bc08f16b98634d494152d84ac034164541dbe4fb9cadbe4fee6b7cc78068379dc47ea9c254c405103b6043ec3fead90926710f3308ff84f1136f67c325046fb54929860fef5f78814810def2b736ecf4905408dfa1edd3b5de549bf3f1a4386ed588914572373e39f97624c928c7d70ce2163b877e832e42e37d95662462f1a151f92456c6b1376575d94a073e27e88926e56164c9e080932201e22870aec4f0c82d17db623ebae21e5737c31a6b9d2e8f7100f88439071749e7fe15ae9019e9ae42a0f1fde6566a86c70c401fa9ff88bc6c56ce0d1291dd59ca6af157694989109ab1135f55a0bf4a48848a84f530fd807566601257b5c69e65a6a604c1629fd592047719a9ad3a62a03329ed2cc44008eded2255f5788fe8b5aaee082198d2b9a1adeabb68c2653b8f97e223ff0504209cfcc68b282f391956f3119447462097f8f0ba3f829baa8a2e753b3998e04b19eb69768d834492eb6ab304eebc55f81fbbcb106dc30f6c73a519118cc5c727402f623799cddace960f82405c571733987fd652151a3e2dc672a6c82c8cf00fb5b90d120ea5bc07bf90052ded24bc664dc2ab48b011b8342029f269b27c25ad618cacd1bedbb6b08d15389380628fcca383855077c9f05240b84a5fe97bb1953970691b0e8d2390119a1fb73ea4e2a7ee2fc69a47de3be80ed10cd7bfdbdb14595a4812c1b73cb5d5a5ba1c22541ff01ddcc21637b4c16039b5ded8fc5898f0fb2a61f8d2f8d4e7997da2c1a87d294411c4841c895063d1b18d2bc9b0dc7622c8eb38e4b6eaf2ef320c2212517cb0355b225730078d29efd51fa19501929e8404d46243906e2e2130820ee00bd1d849608dbca4c3a9e8af6c44e94aa48cf5654545e9ad7dec1694481feb72680fdbdbf95c7b5ada979c17bafb3627669d6b9fd619aabf60454228a10a99049276403b5ef266d8eb8c6d72d4ec508fa46480706267d42db00390a997cb11ce81dbfc0f933c6269fce244e40d07b56c8f0044ec12f8a0b04f841f5bd44e0d78ca9ee0f15fbfe1f46c4afc03960b83c37d2f39cb0d72e32b1f8f4bf484e0860a68f0d8b3c41ddf909ac4d5b3d7c4efc8b43203dcf66091b18d51d5571c1cc96ad2d143b0af68bfab3e5d4ee37684807983a730fc53308f6defe48bb53c323e088b6577647305e24fef966301e90a8069f6baaa0b8f8dfc62ca6e549205fa498f73f5a072a63fb44b9a65c2c9671d4e2449d69e6152e8a55413f93f1d45fbe3807240fa2aeb6f1dd3b012952a8cdea136be7f017723423763dd2e089475f1cc07836e2257cfe8d6d87ecb14bd347803ad37dc04bd4b2373e530869e3987d28e0b90da2b6e8d11e6cd13e2624a0435dc5918eed3963801269036d9865a6fcf642e7879d00c41e3acd8c1eb2aec691f6f09175953d90e4ea56c95e12cf98f2223f98da000b884322cb57388bde3d7d37f2fbdb1546cc2a629a8fb19cba1c6e8096f901986ef2c866c542a7d55a36a6bc989714cebf4e431d9d4e22ff30446d7fbc0309b5031b1c02f9d325d223f547373c4ca349e14e85d4a1b3088d1c495b2f512eb8cd15c2b4ea598736625782d600b2ae7656bd9342e3daa030e11f6b920538960f0433605e6d4c429c58e5b5ed7bfb49d1eeeb626c5adb2a3bd190add64b6f9dc3ae55e2967fb870b36e23b7c15a9ef35868843a7040a0d0fe2c8c274b532400074cd3e7589ca6efe4e1090bb5e41edef21799337a627531afbcdf552abeac42877bbb8dc9d4676f5168d0bfaad782f8cfd708ac2ead7ad138cb686279f1fdf58c2adee4230e4922ff48ab7bc062f5c6918f6a5c6de614613e9845d2f0077fa24f9d1216161a06adcaff4a07ec9fe0bf3a2c5fedf35b591b95d4d828f73c0e7f59cb747b99dd3433e5e7ae32e0ade2052abe4e2f48e1b05c76d2499cfcef01427b00d67698b8c733dc2d75cd9d3409a95111c306b748692c9fc74350d6799be551adaa09f1ad6dcda31f5e460f67e06d768e40982e7c212b64c78ce98542022fd9d591bd1baf2af3a3509b3535fe31ec1534b6aed8d163f98515298ab2701dc47f1f8e09304514bca92271f6bc8602f2344424b6b410bb69a5d25195bb6d069b038e72e7dffe79f1a0291759d5af51869fbba2e0cb6557f1cfae22d5c38aed8f33da45e3d6bcd4fcd23789dd5f9f932c35b64723ef8a8190638c965735fcb400bbad5954a73a8c234c889bb84260ab13d138fc0263bedbbc479fc2d424ead3a735ec5b0801198ddb80f317dfbe84185ef5f797d5d72b4f71128e641cab789ee105cfb0926a4e1a3f9baaf81ef7204ac1ab00b46fbc9842e6bdd997b8a37df849ed4f629028c36dab6c4a0e27780273135f619abf468d8ea3a25814a8018c095d7dfc0a0172efb7c644cbbb14db5f8333d0a7bbd70a52ad448f0384cd77a3f94c31ec258a0ce37115eeaa6b62fed5c8123453809a1c9fc806db38a1541d04aecbd593c6b1e741868764c5a2be5aa9cced303dc9beeb68e7fc96a24806f4d2f280266d6441fc0224b8013194bd13672fc08ace2cb7e9d8980e600b48298cd5a82536396eeb9763cedf26a5ed9196bd43d8256c3b3137ce8115dc16aac3b3da26bc2ab9bda444d3e8dca5723d26fe0cfff259dfce3ed4e52f89d622c00da53bec616d0ebab2a57679a4a8b308dbaa51107220787df9fc594871e687d0bb91b84a09f0f852e130c5298ceeab1d2296b741008acc500d2860ce0915269fd47af8f2426765090f88f0aa002935b708a26a24d69c34cd679875cf46442ae65fb0b6b7e0c85f7784c7bb4f5a60ab94e4a36b8ec67b913e3d663357bc76370accd64011443fa9075a9ca02e057292f0212b3ca46c4623f62b16dae1310cca836227de1f3f0ba40ebb4eb0a4ab6602343222920b151e9c4011810a15a07891df8552bf72e6f46af2dfd45d79c959d1c436dc6b9462fb146636125915027582c380ebf73ff2b8b15c4b21f5b99c20f88ddb81a26f132129d80aa81fc55bf1f29a6f0e4e5c65bf4a1d4a0fa451f7ef43b950a357809a10c1ed1501fb92e447ab44f63d4280ad6a45825d233d36c5c670900d0800ae3e0a84454517d6bc1f0b675e01689ffc156ec75ddfda8eb165d41ec411210803abe492e5762f10b9a44d2105d304dbab22281535e5ff570c6d6c398506803328abbc52fbf5767e510813d60c0bd1d8880f6a88b0fe38c8435d6314374378d2ea937b345e32dec1a0cfb0c64638ff8ec2e832bc99eadfc949ec1a97b43bb51da987e301e73ffda8b2ecfb60ff0470255263069a9afefd7c75e269c8d53f0dd46d6ccbb46069ba65888e6badaac8978a31f6724276962195df087fc6bc8469a4ae1790419e2309b486b830f7fe6c287e366db1c398976a79c60c23b7c94ed66e92f54bb61a1a0ebf6a041d011c6cab0994fd80df84d6118e080f072715ee03402bdc9398f078c494144629728edfbc61e26d6c7beea2568c0fccba7712839197799683e359db3710b91ed5f2cbc9e562fc4e1a2d9bf82e69c065b3b29ac139f03ad191fabdb544755e606c59807b6ce4ad4051decf223d840e4f63b7d0a1a32a79de8f01280c02a9217855d88b7bfdcb0f8416432b3539da890547adf85fc5cd367d9db1189e6c79a1bddb73b701b47c89d971c8749d7ddfc708959b6991af53cf421c9d88a5ff1a8c041cc7e94b926f561a859dd417c8d7ce169ccd495447322793499b97668088d899696344ad964cd94c471f80f97ea5642249afbae784d8003a07ee8f588253271f1eed3bd520722eb4fa2eea55059ea65e34572c60fa52489a4e31c029a0f034a1d449eb87d3284abd77858bf7910ea8d0cc0b7827a976b3908cda0a84d632c7ee4a5397c9856ee019f8f93fc0dbf3f374b2434789796b181d99859d3e78045f0898bbabeac292c9a545a931df70e40d3cc108ae2ea732bde581ec67f91cd860cf94218ed63941b1bbbdc4fd443a5b62dee7ebbf1f00a35d1737488a096ca649d118a1b4d3b9498adf1a3d0a72afaa62821639eb7643eccb5934e8354cde6328608204703abd6c8d5c2d26e460381bfacfdea6ca2abd188b4f1a98a5e8431f228e4e82658cb6f2909c49ae72832e8ebd09c1c2a0a588bf490349614ba270fdb94388ce49c8ccca1e2b500804140f54409267342c105bea3c6c787eead27322e8ca09703b7413cdcf6296ffb438c6ae1a6c4620cefe2dd0b16dd6d017ddce8457134e2f89d58c06608bbe299be9dd91f77c028813b6cd53f6debf885c5d45685a42d035744bf77cb128c4b0fb85749000dd0ca4671b26a9648fd3c8fbfafc1bfab8be9ebaee200227bc4810dd6aacd9fb6609ca331e54b5303b58838f39784477c80e04aeb1a1fd63e7fa6568a434d675854cfc190e922ff5583d0e4cf56d8a50700a5b1f67300b8f8fef2acf72005a950f12153f194cbaaea80d5385e9236b0fc53260aa582e69b4c3f9f5b0e6a47e28e780b556eb6774b1f75697f0c45228a60bd608a3285395b9f5c9770e8a5c11c8afbf79196a854a92a0f3e007ca8bf14964495ec65eebdfe97c592c509f57fab9624a345ee8168e76a430992fc7925a4275aac61493bf12f7ced7cd3a14aa7c8dc29266086ad7aa7ab69713dd9fa418fd0e5a43525fb1f68ee103df4f52a6d29277d51feeeea86fa830366bf0b8c6fa5571d881a7e82d4b7f487a654152f6d6029d504dcd60514232d84fc790a245899364d944207c8cfad8b9481c41508e11432bbb4052abc4912e8c4fa20d487d1964bec0be49224d60508e5afc2ac903e6389431276c6cf4656be7cd5b53049747e5bfa2b47d50cf5b4756c87dc9af30459dab09fa931fc9c6362339ad3c729ae13189ad538c8097f53267fa52eea1cd7e6b8dc4427c36849da699955b4abd18d3b10ec3623922d495487fd38e540871a69719a77935618f66795442194fede38075d3600e6df797f38ff491e753bd31af6c0f3cacea884c0b62d2e308534f9baa53cf4f3e5230a1dc6ab00acf66bdc6a44760ee75fee62a1767184c852534d5f02e11faca1429800d2da226c42b82e5fac89218067bee9365942ca8f9693285aaa98290a7ccd55451b4b16d0fc17a9f6376cacda42282939115732d20dfdb177005c20e7852a4b161d6e606ae2f88288556c41dd19c2656b546a0e1af15f5368f63290e3f7530684c80f0a0d5cca8c20d0c64a6723f8375283355aecd0230444f6f2a3a5b156c0707b2635d948ffe2859410fcb05738007aa0e41cd060ff20c26e70688999e52c7b1dba716ccce36dea3d70b3e32e43a5cf047de3b057cdc1870e24f15294408c659de16cbd937e9fd7e20de08df9f7b9efa7f44dd9472a8b6a1fb9a3ad6e63eb28fa6d7a82af61245a5d9cc21d594eb670bc70a733c7edf70a37de7d861b0943417285ad6b0f7c87899235a892bcf25a37fbc12012fe0d24d2c019271832ab12589d0d0de81914ef9d89d32619862bd7cbc405bd0881e34267976cb18c62d7f6fe6a72609ee8c08d197f801e1b472b1b870ca0515125e4bc0247be43bb959925b41055db1eaa204d6529dcb4368c5d004ccf7a58a350d93a81a91b4f866489865e0e490cef54ffbecafd5e6ed8d3bcacc32a2c7d08c9bc9f98ce0ebc6b93518c87e66046b0290723c5047bc773cd7751259e35ece5c880b04f85d4ce873736e648efe11bc1b823a07a0ff8c6cbf15387b4dfa0fd0cd4568450cf468d17d01dd01b417d705b3ceb5d86f4809e7e944382e532d99288ebe023480bdc17ba8673146075ff3031ec93ee9516c2a5800de32ec7604bd311ff959320b7dd88de83bc20d850d3425eda31286533a02cd628228c8e90348bf749ec40b5d1716c7e6d63e3a0be77621d86bc3b3a3d3ac1620065ef4e25130215a49ea8312c4681a2c548d8d9bd093366d3c923ceb86320b56ef84d29fb1691ea673a311a883e16bab6cbc5d5005e5311fff76d61b68bb4a32bddd3f9fba7c509e04fba8aee29d02ba40ffbd2c4266443877cba9dc18c1a6324baca6a6b54cc41b42d11647d8917a260fdb911d5872dab819f72ae6f3576c00e3169ba0b7a2dd06765bb67df0ada8a1eb412527444d27d3f13f384249ed547b85a70d8e6f00196d3e19b44dce1f5b152463de577952cb1238023a973ea392ed895683a8ff364ca5ac37c06fe436ec91c7e91363dc4b0fa194012ccf166557804f9c12774e1dcb6907d2f262a4b0dbacb21e3d984bb725b3e48298103c97ead4dc958e5925bef578d69df4cc37b97869977947d3f49ba071cacc65159dc11837e50daf12e5969b9a52ea613769a65137ab11bc0d15eccc7d7eb98c71173f5cd548f06eb0e8507ae04d7993b34407d389b0a046f24e192c012306b9ab5b4c9497985185430ba511aada683db869352a37e93948b2a7d75a2bc72588d54f13ec7b886a558258208e4005e7a0317a721a57fd6d2c4ac6bae4f1ecb93fd1dfd72debb8f7da4b986d26aa055d2d9e9a1b15c89c62097166f2cca5b3a133abcdd152d69d1f13ca0b4708c264c5d7a298aa5cce299e281ec9c95755b33a1c3d7a046d78c7eaa14df33458b642a6636cdfc0f925561f68c1cc7e868d2d31b1e5d318e419e28d73ec1a206cd694ce0cd4637956caeb778630bee52691252958def97a88f4c3aad9b29133b3502c73de0622b8cfd9e6539decdb3f356040796bd8c9de8ce0360969877b531636694a48b063b8f350a503e60104c598f2d42d2b6ffefed4f83e4086a7fa7690b095f867784e99130efc98a39f8cd322714603e072f41cc2b49570722375e631a8691cb32fac31c84d7a81b490326246e5f6ee53ff2cd0cc62ccee594191a781e3d5336d7e62414c70fdce8119c04507bc741436c56eed8131be3bf04142815e29f05287bf5d88dd0c1ff041428adf0500f7145225d5811a6a8be261118c32af7549e53f4b10727da65702dc41aef0918cbc8d75e20ce7e46c2fd7e7145e2efba17a3fd5e865964119a2785102c1a4fba30e0cb8ba128ef9c7a3c105fac94e51d1a8c47c90c093a298eec3b4afea3144832ea58b6392476b2121a8ffa50ca8d8bb0670db8b8bf39f59d71c67b6c1908f997201f05d1dd5320ef3fa889c07809a87005eacd497a6beb9e40754d45411cece865cba7ce6cab1d0f5c2bcc6dd14e7cc8d0fbcda8f446893948924e8e4ada01d87f81fe586edeab3fc61c06a3fe889ed179c01d18d5d18d2ca2ebf4de4266f1487235dcbec04c382e67b7b96ef263cbcd0f5b8f5eee165a5e307294f35ca0b6a470ecb238880379efcd3e57479b64b06c7436450b6dd38353709ed7addc9e61dca4a69349350ec90158c7056d52fdcf2165e2cd8ea06c8159dc20fb1aab5358f186f8496864aa2fb7f005b0e68e5ea7d58ad596be96ddb6ffa8d03e968b2c599ff49bff40ffe4a100dab2e0a9af88c8853470c0b0be4eb3e44d03decaf0c2b3e77f3586658099743074546596ddaa0f76fda9c4576f061cfcaba691d20d34551d89838c9f287169bdf7a4bf6bab4d845f295b1759ddf06cb72e0349af25df4e61f83407bf273295f84e712fdcfad67d4700ee6cfba8da7c724e0280c0e8b0bd5e9d94ea5ebe3e17a537ba9c0e50d67bb3fb4e4c16f50ea8b649a343cbe72b77dbd59ec588bf915790250202dd10f3b3f5a50972bfce46145a844fce93e7fc3a39bb8f5f264b404e0ce551ca7db9000ac3d471939e1d78d29affeb6fccac41e45d7d96559b1735cae8cf7c7e32787ac64f1ee0e073c0db24b015ab3b2a040c13fb4192420401a03bd87f85ab8ccbf80c0f825328c1db39c105b8d2c7ddbefa6b69cd34d5e75f828f543c76043dab30ea62387e6e257fb20e6dcc2e0c8590fd3bc6422653a582abae4dd1377c1cd6bf4a2fbf9833b99e91e1780bda61e32a47450ddf17b06d347aff92d1002e27f177b97751520827491b639036dbb483a0260741e109786e48b8c1938126b895de91ee94f073103aac2a3a58a092880cb739c1c63990bbb160442a3ea3c62822c92e1bbcf5ca26b114a958abc8eb6545beb3e93e13811d69f52c6a3098a336a024881eda852369d6f069c73edb6142c63e1d67607007b6d37ba494603064488c2daea01d2b542de8252cc39514caad8a98241538c42d959de569c1d2043992ca71ed59de90b91da4276a68a9517336254b041d202d4f04a74d3667d95d91e101d0cacdd3355fe86abbe8f112a05b31216225b114f63ebc9204d051d2d54657c80e661124a008d546542d2876804db8da86114099b19ad230811972a196bbc76e1bff4075832ac084ce91367c1114663bdd207c10dcd7173d7a546cb41df09517639272d6252f3816b5df0fca75b5c4f20c91f11d27b70b9d6685b97b46dea073b67f373cef11aee84a07dfcfa75c162efce3b33b576f50e490717440fc336493572651ed9e11b947e382ba64f94f246d31b51f82b02feaa8bc90c19b6e19edf9263c972dca1a4cce2958cc9eb47ac4e5b1d3955b8509952b50c7206e1c58b711a3b1b681f110d3e6d5afe66c8b57ec6d4bdb581cb1e2d6a07081b6d004bc7562e5ae4ebd8b034407c6818a6f6dccf49d99c77e7b2e19908c76bcf3ec12b3376af1385165842115ca7d4162644fc0db3354e80124b5c291206763fa8c50a3a19a0ff051e0d46afdc5e8ce608ab25032d760a1582320769b439a3f958fa294c79177a4f57c85992e6f3436e23cb9017e935732528fa7661829afa83372d51a7c63e1e946cf4c9e62260743436ea102941ae82cba04a9ea739b550998cc385506db268a9455c911e0a1099f755b167af95ca0b468a8913e7f6bd90809aa429c7d68c7104577883f1c22743ef09ec7395f5b533a8095be91b7c9ab6884769131081dfbf48ef8bbc4076e824f3ec51b460b1911a8cf3eb1dbf14b696738203d5ce2bba17f45fe1b4f14d02061486500a292c46becc7a688168df040c9ab1ee8fc6d4030c3e6f06e851cc54c881c14a82fea782b1315b22c7e3f0a1da2e5db0942dd642a7c7c9940b4f47485651d9a6fbc6cb86ed4f5f1d8d99ff922828c2ea50270ee3ea4c864cecdda00a894bdebdcce2c3901ed0dc601830aa276ea90198204146accfa749a74ac40d5b82a7b648d8c36d9abfa31146cdb284a60288bfcaababadf938f67b1bb223a1bfa81f0fbcbebd24daf4ba41751fdb6e4265c5a50b07ce69c4f2f3d96c35863d4445e188acf83e5cf76bc841596f86ae16f47e8f8cb1f57579c38b976e7a7386e8e6850cf778585e553a3945e61e54050923ad7eea7639ef52f26ce0d6766887c1f62202a1b850ca3c3b44a77cb04563b30ba57dbaf2e29ff450ebf5d60f83379c5af0e7e4ac01de828db26c4c2f5c11d7591706c756f2b6d1098b852de236e555494090d706fc11a3f4f9a2d115702c72bf211b3cbd8f052044e28f4f2f71c27711916715ad96cf035d1ed588efd2d17b20b02ced01a87272c05cfc99b9fdae190b3b92357cd5e4051d5b2bec459428e4cb0ede41e848a0a31aa809208bb531e032aa797e4824596da07f99972ff6d6c1b72c911655b01530221bb10c2b953e7a1c9bc808e751fafb34db23cb349ca12bb9f2833ab1ab5b1a51c2da99cf600917e6264060e10d2db35099904f932622ed48360ac334c7788c3528e668b152e9262d802cacf413df119443727ec3effea4468662fa6c6994d02159159f0220b73496906732ec3c4ca4c9bac873dc90c479ace8f52b71ccb7e549494666658251ccf8556c7adfcfdb9655ee704514a262c1076cd70929dce25c836573b069cc26986c3c855824339d761e4357d482f5640c956a733fe214b6c0357bc247fd8e9246eb9a256a20d5a10bf7b0deab4b241a92618c793f688a1f36b0c2160ea2b2d41f66678881af4dd91058ef52f662ad0a49d75da4073814c7c601c230ea59d524fb8f911e0a6546af7d6c7288c3da58aeac4e1abfb894811e212a2f9f541864d249c4332429e0c0667e463279474f277789105b5ba03273f0f319c7185205b18b4f073144a1ed081c9162ef18d71c652f74befe7313d130941952cf4312338f095163075c91785af6c8229f2c609c6909e6bbf117892f9794b67514f2c8254fdfa5786d5bf042b9922ce2ede45dfb6bcc6e440e2aeed12788c349eaadbd22cefc184c663b1b99ede3681cc52ae0d81cb51eaa92636f966ccca8c7177fb0a21faf331ec03e29eb4c3edcdd5bc2e7db0f29f2972668872cddeb0ddc7983c7f851cb6636bc52acf62d283689e1e66284e079ee6d3604f18f8125ff92b0dad007677a43ae102dc6c21b4cc31599e26d03c5b9ca1f1596a631cc2d92c13d014259da4ad2e027bdd2cf25b72dd0dab9e41995cef1085c2e8e1846f3154a4943ce33f92ba6d1a07ce238606c1c4d415fa78a046d7e0df504df6fd099d112f6c0c1f19b231d8c628f450668f1e31a7f2c61646b6c63c3fdc39cd49cd21853a22d40c66a6e5378e82de2ab0b477d1bf8d50f0081e4bf415caf82e04b895aa342b9e4c0cdec3ebefca5da545faa162628888333b7e32c0bdde0c1343f62ec2f9a2fc23a456eea48de8cb3a9a2a4085821f2c7f749c27d2144afc426878d64829245fc75edaefaa2dd0ffb94809272fcb776b2568c433069df6a5c64d440f06516539e2630cd50282cfbd9151695da13950349541d22b29fbf936778ca390a27727165319701ea0b8b8418f0b4184b4725cd3eedafeaea12984cca61a44b77dde4195dfc8a2b3a9ab1133bc251204e8e5a24da39f82f2c64ec3ba41a7e5ec7bf828440be64073bfd17448438419f0b6399282f2a2d4f335f9ed7d9f748b379c2faf344abcbd42e3a08c648a4205fdb037ea9dc48708675685c539e9c2b48b9dbd38ddb1d9033fc41311c35b9ade22a86dfb93415cada5646b6c67c3aa017ab5942c744be4a33edc089d7bc163c224b0452f3b7dd495a10eb1d480b7428d6dbdca88a504d368f6125ac15350d6440b60f3a0a10450858ca80f93b44da4c27a10973cd323ef86199932585250a6a3e3ab408c035814190e76cf93da062b5f087c8bfc22fb91edddf66ead5450e2ef9130068d78f485c86be9802553e8e34a70ad2545eca03885633881b85507c65bca2ab747b2992bd03624b6a5933bde7fab0482b16282171c76f6fd013b2c3daa3e7d5174bf8726d2c3f402cae5f240f5be729d8b024a95fb49ae6245f6f02dd49fa511b5de45ea6b4f0d8ff5d402193912b3f96999b4a7fcbed572147e0b02f1d3a78f1cfdd6300f93b9c4b18a64efc1b649cdc0cf873692ab249306c87e27d39c136c828b94163fbed501f392989ddd99c817503616ba9c453b3b8e4326516407572dece4e4c04dbcfe9bd76face522671f1318415ad5cd38fc7c1b1972199ab7e90fdd6bab8d63d3613af408f6acc76b054415c06050726e684ada91064409aa081d145761ec27d891df81e195b0e08e8640b68e126acc23247508b79e7e9cadc730a3f451abd483f01cb6e938758216c0f6b1d6e7b67d8a99acd8c1ef1dab92d2d14c977ecec03b872a74f7632a5e1e318749d923b9f8ddf0c0ecee5b9f0b1774b7b81e91b5fb1d59fcc13c0f16993cdb78a2457e657edd9541476670d447538be79fefe945f0fedfaf24b79b030ebb1a16536bd66b87b23a3f4d763b8291db1cdbe4ba366ccaeeb324d91b78a2f533bed512a63ce35b5b9320b643214a6f2c69c45535c7fd1a3bd0b3495a59e1ae8b2f85bf3a39f3efac8e3503fe01ace8c5fd565ff5cf207620c2a1899148d9ed0816bcdbb2ab8574fd54c84d97cd4442c0ee14e3dffa83e65df4b17607ef01dddcbcac52c88363913dcc2efa57b03a6637ec44a8c1e252214e728d915c0a7184b632a3e4f1a92b520c34488a45b57a27c2e98c991743e0fd8f916ca874364abaee5744c61f4024966ccc69482af7d817c4cdd00369285a7debf869fe646fd0903753b1440995a3bab952f91393f1401d6392fc643e213146ba6cc79940cdbdb35310d4d85382a2c1205e528bb24263e850170540fc1d071c4223b441f1eb8d783220681329d1c25b35480311bfad007d8e9b85425956c67b19e2bb4e62b0f6ec495595b37a96aa053d0b7dc54a2ae2223e1227e8fc3a16229e4f9a904103e2376898c56a6f7a032fb17cce48c298faaf103b433e7edb7f4222a671a47800d25d0fe2f39f7db4aa0119b7166a9cbcf1abe35869c52f801b803a759266018ae3c349ca05756310a64203f48905146a81f8a3d9cd0091a8fa7cf378525e350aef1ee3876289b166c10187b9126d8af1ce95b482fc95d47b29b11bf70efaebc56ae3378d2f9b3160907c76f80ed08d5ae32628efbe6f216cab582a0f693e8bbed4236c06aea5d886c3d4f7195033546dfc22d731aa95b038fdcedc79f827b4567e0de2d7f86c79e4fd0d491165bef6b031f83e2078847b52d21fa6fa6975f37cd0e50f3e25e893f704b6f06cba4e4846580f8e70590cc30660c596bd291935361fa23f00803277514e5f585709a71b88be0d5a2b051cc41a5135402416e307d5081959e85af76050b453227611f6d9ddd028dad8805a3c286405eb92f010a8654a7c03183c1bee9173a43bafc2b0cd34f7018360fbec1d0bd46f215fff365159de3047f461830b66b6527eea31baa317a4b27b24ab6013d434467cef156bd3416aea227b5386c11a18768f51f45ef9fb511cfb92dc127a24336c6045d3788951c6fb2c2ea14a73206b7c69d03a2991f563a9eec1fae7d42f793b61295862a7028bafee1b9d5546ff60d8350e56ba071b7bec964b30f4e0008ec1849bd088e1cb28b17366a110a6b39796408140386ffb8d4603830dd32cb4117f70da94ddce89ff8cc0fe4ae0b3355fb90b1c620fa6d85c3b8416e8cad051825ba064cf27979bed061b0132ada91b9f19259f83e5f419918b2f05695e690b64343c382988ebc69bffae31fa57d1b713111465030aacea73174d4f0873094cbc96817ef66cd4eb81c1eae442ebe8792b388a68062c039d16071cf244c4f191a07aeb5a30019c2c8d6d40facb5538438d0c749e5dbfe78487138767b40b47f499790075b8a5dff57c70bd67f03dc5f73a18871de36aecfd292bcb0a89b6c0e33ddbe35e6a541904c0b8eea67145f9cdb4fa0a79d7a0ce50d812bf579259679360cff1398fce1dc06c4599a00332959a472a319a46141cd07805c010c58555e054c56ea14b6087e11af74c0f6b99c82e26cf88199b95e03e0cfb2cbb193dd27233fff25e5bbfe64f9863c1118beb13239fdbe3500f77e4e02606e9c7d3191b6cfef270462df39dedf9430cd093d0f85ed3d0f22b457186870c036cdf239b5d177d05d79dd4a761af2ea46b3a50409e56da306422f4b0162347a7e79e9468c192c3ef773fe6412629dd9b6b0ebb48335deeaccf31a17bbc45df14f123bbb6deb3dbf854a3fb0037f6c88f7c3482bf8b4da1b802ff1b8322f64cf455f2d0b10f9ed120f1c93dac20d0838de107eb9bd1318a61f2dfd8936104efbac5f6ffb673562329227240b2ad50f65441ee15ec930dc74b087552f254753f9ecebe2d63bd77ce6ba9a6cababa926796bdfd5652976455dc1da7ad0ff873349ef3dd10a1a5e0b92b3a6014df06d80dfa692cc8407d163b5c0c9a8ace50d1bcf164636ba49b92b7d49931405be577114347cf1c4d85c2609126025ce2080783f01737879249de7aeaad6f33e091d54feb4c45d2830f88efa01fb32f0fcf67dc66ba98b2060acf504d0ea5df09eecc5a501ca7ec9901871d044145cceec8277a8728ea34483fc480f6cca223019c9c7261427a4b418e1d0ac40dfa170603193598cea1359b3291ce8085318a7cb67548aa1f1243db75719da8f17135064b984b9e5fa96ff056f638837e169bc103dc360a284c06d3e68e79a91ee5dc14ca97ba4242d3b7e09ce531fef4582ef2383131ff5803a36ba05e260984eab61be17d5607d49ce5f6db11c50e90df29def9b44e9e48227c5a6c8a1dd37b5cd59da7f40644fbfe795e5712064042e259063b3b834aa169f3cecdbc2c2fe16ed9d588942a664f6d17a9869f6532680f3b09fb420a875c225fff1fa2e26754b84fb4cc1ae54e4101457dce3d4b2c9177c78f5caba7b5498756bd6345b18f2d3b9a9a7e56289a368f4893b362ea98799b4a76a89cf3261cc1909ba5470d3e078872f1b7287a36c986d2113a29a50964d5c80bf87f3ca481cd6748a91c31e94e8ee8cfda615ab9249eff787bc615e014a11e75cae53f9f9573e8604bff5b880ef8499703463db5a71b093adf60981bfbfd00fbaa8c6690d0fc27b2aa75d58570bf3c1fd77912aba09dbff32274e73c575865d5bc73f9f1cdce8066f925ccd31049c777be01dad7452349408566f4c2810c13b95805792513d0236b4ba7e142e5c8c7dc26e0a628396c45861b614c5f8d627587adb6574d276e68b0f25bf0e7f10e439e80db2c8370813b4d2b4a03c6a5817767d5b328d1092ce45033748f570d0ca32b19d25fb6ac12c6f8b484a8e2ea509f4a11b7996c9e6d3abfe2f1d89ce3a2705f2a1adfeef2ec141f1f894bd5d5fb9b605bec011c4753b25c4f2d4c5d35cecd409ca6d290eaa52e416cb0d601918098a9a9dfea46cbe6e4ef61e67094b313f04448a5e0706d49ecccaf23d083dc8f4c8eaaffb8451746ce85851894960e7df687bd24babc959bb71084e93a0b575db7897628675b9139ab6a9c31bddd58c014a860a64103053ed333214a4e8f928459e521ba4bc1f1936e7e2c0ad3a4f35f5545288345ed1072a302aaa4bb422d041ae5518deaf10d869d939ae43d6bde03b25085483e13311288a27ab6e211079d9141ef89664ce6289cb2dc18097b444a5268fc230a81bbf4e01aedd925ce2d1e73a809f5c1bc6a33e91b28059632d1c7feac77df453a38b5357cdffa0d234d2a86ed0fc34d019e7ded9d87cd6dbd537b474d448af3cb74aa45ec1c6bd7c59a7078820f11e8bd9e8e8edeacb24372e4dde9451ae6649bf4abd605cd6730703437a2f36916deb13b8e8d183bb4d7c32da9720e9f1c23850663bda3d8c268471de84d892fbc28e8ee22e3369c196fbda6124cfab2c54e15440c4e27e4429bce9c4297287f8ebe939dea95324eeb981a14897bece61e35701393eb3ab659a3159ecb19e6d09dc0d2a630a58bdbbac1e0c536f2b6e604eea740054e425bf34f8895719a7be3a4117580571087f49088652af6450ec20fd209020693e31fe58b18eacda49b3b245dfb0ae0aeb0d1c0f036de53c8096582b813db096f3df7aa38da5803fe591c14166bee99118e227b2c81149322489a56a696ae3e550e23f88224c8db8ca0f048d246c9507ce33f901b859235a225e26bd0f35a74a6a7d85d95745ff6d45ea5aae51ba42f5fafea5d64f7201f905155e743d561cab3f0dc8d03398852b8e24a1e27558266a7a868de044c72d3d1d064775bc9de806a8eb7d2d735d70e37f34c33e4c1a08828f333130106f69c60f5648d4f4419bd6cccd57188417521dbd1ea4f0ae2257032749fe196667ffecbb3497ed10ad35873c44db037ff18123195fe916afebf28a5fb90d91c91c702b4c4f23e4e9fc6badbf1b678fe76ebc11333a6db4340e9da126dc84c2ca815ebeda2f7ecb7654df3d1958a7778ee2678bf64578ccb93cca228d770494f0d59ec89f1b2800756690429060430e77c0b88fd7c2214c559d44474b39fe269ae6fee2ef6a35d70b219cea7f04bcd11706e2cd1f56fa8ba8d399c0cce55b18a3e995882733ff0c63c5cf184f3a38a91a902b433dd3c2d3a0dc4c50e30d5f3f9bfd7f60519ffeea0ac96d4ab84c8b8f329161f4622656f01f7252006f24ca1f23d8ce243c4d070a30183f5e4f1779703a65a48da90553b6e410738c84db270eb129c82a62c26f812d9628a15f45a8427f6f0c14100e398c488633d2ac86151388697db61992fc4948da136040ecbc0eb76aa7aa07908b72cb2bcb719a54414c3755229bed338306bd4b5491fa29ee3a16525db5c1007033db451d5cf0da302052fbb766de86f3569af6e46ff0945858f9dd52f2a72b2966d7c54ca7131aeab8b67266b94d3871c513d52e3b532b00feac4bc93fc6399237d0ee6d69665b3af154bfa646a3a578b9f98f7d858893507adf1221b073f2e4c50b274ab280e1b26a169886e2bcd4893c15548f11c7cd830505306779061add04b1e5734bc67df84980acd74574cc205543f991f118d7284ccb4c4d9f54d1871a00c6268a48f9b59dd4ddd4bf8f861a3cbbcb5748660a8182c6cb3e1d6bdecb54f56c6933817ba12afd74b8e8ff631203fa294aa2091f40e4914355da6c1f0bac085388d17345766808ae5abfa59218950dd369c6e256870bfb5789f5e1d4a97340f9a962e4937aeeb0defd980e20598bdd68425518b018d37067d1c365bbc247730db31695240b2e2883c58a8edf1d9e37108b7c5f576fa2ac269b26883f541a7dffb25146bbae4fe3900301fcadcb8bc0a00b0fa316ff8a04a6c55209fb127da406f9674009c2e20db614114fc5743383c2122c52f27daa70ead2d5e00ed2a50de4b67d8542b08675fb39539adaee2338e8fe19846d9a18e6d9682122c8a0a622a5b835db000d3d8318a87a76d769d872a8ccf01072f5f71058770d1b1dd5cfc5a5af457e62cd01da88297319668c5a8645c102158c5e7dfad2932711789a44979ad7e7337a69b7dcc29c8b1279b4704172adcadf81ae682647fc684351ae5da0ecf6ee9d900cf8d7d29e7ceda7385b98b2c05f069991061bfb00b1c7dc668886954bffb0ec5a198982e4ec77869fc79da7d95b92cd901d8c36f6771a64ed81afc8fd0c0d8d5f79d4f919ecb4506badedaf8fda5e3a9de7f8dea577def88c1e0f1b0e14e08a47ff85c2a928f95663d6e2f5d1e9dcff9f001c1306db2243ab0c34ceb26432c877597602bb2e8bf463d1f9afa8e39de67b3b43f54e80bae59896dfc7569b043319cb53e379215b0c8c8b8a7c67f2e6698d72a343f303e715db24d77ad2acfe83d3fa1a65d1f94d719c8d4516b021ae0a488cbc52b862b54cc3b2a858be86a9437856a978eeecc851c8b0c0845cb597ce6b093dcebe0c05b375a5c823aa03e0449c9772e35bcc145c1bd7e095afdec8396017017895285b31782509314209e3c79ad3a9d80b0f7f54390d54ba0699d23e53fc0eb266fa7d777fa244a7dd9dfd7d9313f8cd3980076e5ab1e62c6aefd049aecb887ddf2323fe90df38b2bf76a36f305ee2b430ceb0b2879c63800ca9dca94a5b0dd6ff768d516224ee7d9fbe04d42ae16f8967182d55155f0125526c8cbb1f651ff2867c8f301621f65dc3334fe96b5ef49f9d913c71420533ac86d769173c2e9401ab74c243696de8db47068b7e0de56b63be10cab5a6f09f7740021fb9be99a60307a90676a65c5578f9963a4cc256829811fb2b45cd13085e33c2390f21f9cce78ace23cf2788527024e1041bdc1a430f6cdc57f36b617c1a45267990addfc14380ddb3fff321b0eb61bae24af2ad33de982b0901cf760ec0bdc59cf2a1859e9f0e4269c3e82c06c354ac7552230d26f955da5df27b1957e9570eb687b724da2ea8a377bd068ab26ca9cad6d50abd1d87be51c5d15186b4e0c898c7db513b0bdaf74df89b18fc88770e32e0263df00adfa8afab90f160e7f96c33e89d3533fbe0dfbf6e1d1e0799638472e75e01a2dadec7ff6d3dabd5fa79f3d5d3d74f1ae2ed72793031290757dbbc7136a782db59ff8c85370b2c08025dfb768a8d487797c1fb3b0568af71ac2cf2ce91822fcbebae6b7b154747d6cc2855262fc201294547a187f5db21858930fc157c57f9721204018aeef0bd79ec5d93271325891eb61f06fb70e6d4618abc0efceae62c20310a9063371e5cac44185c78c67254f531638d9c61ee5fa2a4f02dd8b8327c40b271ecc475f411375ed945f2bce50803d41f84bba76bb3e48fa814d610b83136a0589682a57d852f601a757fc627000fbc4d2e2e9035492d7aef38f07aa0b2ab0e8d444d6ca9f2c5b1f92253de07ffb0a17c7990a05665d1cd97f57c089001d3e627598132e8b9e963589234398950076b0876b316eec96c8148b8a2ff3fabccc76c488cdd72a928f6a53ed3a95296833ab8fec8b77be7f10bb1c14ee36c17ebf3108468039b7fdb468bf2f0c6982bfa45e09d88356659a47e95f2fb4952ad29dbc046ad40ea9aed96027fd6243fa4b0d4e2927b06ef2cb77bbf1ca0d66055146aadf8c967858499ee6c85ec3cddf1155c4970cdad5eaedf0afd1c9e7425871e5a1f0d03aed0f042a96b81bb19772dff69f012dbe5d5ef90d2c5052b493fd9c2d0f032d9ebfbc648d5c887cf90b1fd5c93647b4628a8da8d0bfabfc0cb568faf2926d741670a2bb384b7884da13df42a20b91ba8da822951014bda239c58d4e16a4e7d046c7082e741a1510b98c376c596d71227b03550f4cc767bf3c414bc2219c7e2a1cf049bd21cab406de78576d9be0c7aa08b2c24dbc34c752a6466671dd05bb9d0ee2a35b3d5b5828f3e0ce7b48de3f4021657c997e98db2004a823b5e7f98e5fa7d010d6422a023d7850f982512a0248837c6eff2322fb7b77b6862b712b3d094eb835559d72a14689b014ad943bcd3d978942bd1c5059ead3f763339184e10a9303b6b117e2de1eb3003d7064ebabfe52136cb6c999065ecee0380588c7743c848580967695f6c8e67a51a1286565e2a01fb69b104d74be196c30e4270505ef4491e8c8d0103116093c84414cd8697484bb6357465350c180a4eefc6a8399ef384bb39ab2e52f8ac410f13741d8c52f0d467a5462e4852c208ec49f65635abc2251f3a9d7975774e076aaf7971790b78aa394f1587b377075ef14d6ef3acd7c03a7b805f3151bb09847b4045c0a2921ce4e448fc1e0dc2c7833bc5cd4b76de9187654f65e78de35e0c3db36a464fff70f295b04c0fa2c4b03f660a5e875f1acafe4333cc07706290abc7fbae88ae1fa8cd454ee1150b6833e437fc7cf59c28dcf99d07123860aebf1e36f1d25f5c7f4dc3fc578f615dc25340ec59fc27b0c0a5d2b229a3bc7446e313534d9156ccf28a2dd7366ce439da125c124aa8cce12f62f49b57b190c0efedee7d9f49ec8f91013f863474e2df0cd8782d978db791f84b9027bc804916bea310002f7ec933a7f00d10af21d1176aef1a78249ff41ca4603b67ded5bb46ecb6c3e084b465e733cba989d90a92c839bedf72b51108d7bba586494b95c5d41906474ca12e87a9f88e102f0ec7d9ccb23027534bd71218b224a5fa1f21b21679bbaae9094339aa79ca68e9ce5e4cfe626d7cc98484f35db7ba5bc1409044b5e3f6888dce2e8709efd2283327ea95f037c4cfb2082e526e713fb8ebda8417eeab48e9d8c78fbfe74e0bc08129ddc3895533a2926798009eb2f19c884e2256983882467d876d1f6ac0bbf5027e24ef0dacc9967895c09a803e858799a4ad6e5a458b7cc3f73d68527f36ef3f2659d96c945ab4137241ae4280559092d502d739c30917b3263e7321b53bc2e15fe5fa9065ddc2b81d2bc11822fff8ff012c384fdbef667b7a3e8aa276126810f2237fa9a7b1c96c32b20937963729eb527ea326982b5017234ce330a12ebd1c93d05fc06decd5abc694d046e0a517950fe005ef86dc66238610be6716b67e54d9f427c845c9965a3146553794fc236b2b050d7aecc440a00c3d46c8a5149dbd902256a1b4b8073bf68521e6bc186c392b6864311d21bbbd72684415e21f0428891655e96eeae276a1958c8fa7ee031e2bba2d75ab525ae2d3100a20741823747d892c46835803c1dd38ef419474d9d0573d303239b10fd6c104891cb98554459d2ba41382241d86db4049638b1e9eef17edc3332e9038f51b15123f95134c575d2ac7e8921a48d38f7e5a9ad6d25c0793498c25347c80cc92f6de08be9c5092506dbc9a1c9a1e1646cbf7d21f9bba110741ecf26d9ede1aba247b7fb02fb8e80f773c6af5dd4807de848e57fa0fef3595cdf71010152e67c0b4988a28d431faf8a0ba01dd423e3e3d1030f29643fe17bb72f29a1dd80324a5f92ae414d907655e1d97f688b0140738afa5d1ea610b5a8d7348a508cfaeaf2bb8924e462b6516cf15a5f882b1df813803c4cbc0f1b821ff974364e3e312ee21c2a6d3fd0854d8e2e086979292a2dbf43d3ae08a016cfc384680f66cb64c97e8fef67917d2d3e34228ee539f47ce0595825361a264187504b2920c1182013784d06d418b89dafc1469d6f4fab5d8386e940ef11e46fe685cce87337929155f15006687de0d1b1bfd9f9487c4e77d623bbcb9c96da745ffe477dd362e7f6bbb7f37690c388529cab9ccbc577ef96cd0d32ec9981730cf47b2753fcc26407e27aa5b32a229ca3613c02806859097b75cc96c46655fbfa208aa902232821c2402e780cf933608b98f0f3c52f79b15ec196283f481d006bd43fce075e5618be101a717c810b2e073914c711549fe22c39bcf25f1d0b4c636ef92c2fc97651011b59f99c6a05157c7f7aab0fa1645cba9e7395dff61e13e6552bfbb2ef415f46d5ae71f0f7cfe65f3c5b39b5d34db04c5f166702b2fdce5f04c487ed3028accbf3da510c05cf104bcf5633ab4a44ea32df7814acbd72fefaa3f1da9fff62974d833c0b732ba563634168a75cbabd4b4785c762393ca75efeff7bf5150478509df5f8709fd330df110ca2198b5e4ce92fc5c613e4d41c21e79029de18c01ba130972557153d76b21c04b50d6e1a013158f5c47e8a1c77b0aa5ed18ecedc4a523a5d6b0aee7ea0a75572a0b54ad2cf96489577c86edf4e906b1913dea529cd7e9dda1310019c6dc51b4641a038ffd7924b80b9af6a12dc7f8ab09770612152004efca8a65395dd248c96aa4845452b884ae48ac74d7eca51b40e9bbca282e14a265938706d6b101dd7f5337d4b725c61e1a79e46a29303b78d512adfefeb0b1e7540df32f7e513b51def3dc7ce29176722ebd991ab5acf9d7617403c6985cef3601ee5496c7582ae4ec98593a5b746586fde02aac4a2065be599adbe20edb135e9d8ab13ac00add4fa50eb592d5630bfc4c2d325598bb97ee38956233d1eda5602601bdeeaaa8d2904764322021c3a64a144cdc2e8b76ca3b9825144e9ef8a5b9cb2ad281db08caad09dc51d19670b975128d5832d4a44ecab2dd4e392396eadfd322f9479c637e4fc10b55b2afc66e6de7ea30ddfb56bfed8d3e05e0a4d2751f49310c4419262269bc9a2ebf4f8bba0bb94d452fc60a2ed6bb0e578e4916ebbe0ff95ce265a115d4be44b6bf650b5a4eb94fa77341969b3c0ebcb07bb0c7821bc0709a93b4f2478454b741087a35cd07a13a685675ccc2eabc25d8ad3c7f5af234e7241f623b133afa9489f8453227b0a7a259d43721100714d2857f9615cb846ba363ef789bdee76bd438c40c7fea960a8bd55513033348699b7961cad63f6f42d66cc431e660e48bfc1adf43aa0dccd01e4b1ef20decfb4d5cd47021fdceea9e16328a0de9e33187ba04011bf12683b2ff85e8602730da0eeb96e5e1f2ce64112bcf9258ca1ec60093077f690daf1f0b4e95233a4d87c092d8bb758a856be895afdedce82e5148085f7e1aa71e279b8609cc1f89c8f2dfe7201868e754b57eca92a074b05ec878cd5db88ef975ce4906255b3199ffd16caf0fdd4c9cab70ae3872cd807b8bf4a364babb7acd6a989c89eeec35172fc47e398a85490a272b8feb983e69ba725f66a4d10556db21599d82805f6b186bec99ae06d8c068dcca64cd4d34b339b5e9076ab1a4fbd8d93d0a378cece535fb0b6fa581f66561d14b99b374f18c63063e1e7b7d1bb02ce395772621fda74625592a1509bfb7476f1089809039b7c2a26c2d64c320a5252f91e4414ba9061109f2860c2df52966398af4e4c210b6b269869702a909a19ba3482e066d50f8860673122de6304c1e9f974482078faffbbd3a24d040a2498cde2b5b943e20e430a95b7f307517543042edd7efaf93c99abbf5337fa85bcb7c53361c8bcf45bd1df499767c06e6b73ca5a7d4e06d6ccd0628eb48813e87d6a4cf519c1022b4dc4c5bb33bd6f5ca7d45509dffd2e6e76fcc88325810881ff9d11147fbc6a2a1b97fcfb9b5426003eae371b2992d95c0190ebc3bd6ef09e792f93e061a6ea994b32d401febadd90de2a5a6af4658c78c6298fb31bdcce8148b972d98b7cf0d3731e6d91f840062b4afac78bfb64b56e65b2de22231bbb313dfa49704fbf7cb077598514e25e43409fbc3b4e65db3b0c0ce5b835402e66bb09dd55a86ea57be1e582366d67ea58d365943c4cca29101ce70af911d6cc3cc204eb2fbcd07079a098c6fb99d632db6ed099b602002ae7000c4231c70832c87bf8b916facb0016104069e0297a228e4f24b1ffc9e37e8e604403ce491e4469cd0592bce9a5fcd2c1a960d2a96176952e6e6c7c53c950e2cc3efe17f4f8c0215f7f4c9d81c615e7c112cf37234325a9c6a041abee4f2e1483525ed7ec6f864c25985ac92e2b098f6ae42ee429a451305383627096bcf95018cb22cd9a1140ec78319de29c8b5211874042a1a2b6b2005f714d3c5688ad364ebf96c59216c32d325bd66b4149e8acf9817483c9f7264dee0ee6c17252fab5f1afb4e41f5d513ba4cd18c818c557174f6142668932111ae8886235d28355e8ffca886470becade505fa99472c03cdb64e9c76d20e2fcf77d002c69b653060cc13920b703afa67b36190193abfae2edea2b75ba65a8a94f147cb10c388915d2e620c813591476b40526bb0487d18e28d882d588be8c1b6c01b8c92b4423a80279b31e14408086d27f1795adaaee62273c4a2c09674948107482445230d40c2d51200613e4a7801e2d09158503d1c63e1913580a22056a8523239fd8b5eb7ad4d6688b65dd946c63c5e0343e9e207b744fe28390bebe69ab19bce1671db644f5c4d706294bfcf23b1045c0dae24a1b548f832d704c1171d668e046a29055765f64cd122c83349280207f713ec6d7e3362320df75136a5305a49103ba72b27f5820cc524a0783fcc92540a636b56512542300ffde127ca48755ca33eaeb4a3fcad21b18b0a6c2379d0b877c96e7020070fc623abe006cc2c593f76252b6698f12d8255385b3bfd9974e5664117d49c8de9b6cb9a59429c914a5072608a0075147ff084d17cc60fd434a95744317dfa1ba4da541305656914d0db60632d8fed8b42a74adb921786955adb4caab6ed3afb7386cf5c686d996964d76f5943d656b3626b253d844a20f1a8cb25bf64b6db5fa6d255772255752ca8f88a505d7552ec431eea87bee91b6ef65b41db17e7ba46e7941a26cc8532ecf3661d3d8909f7eeb51b2e1dfe84d0d4697c2cac299764c0505b9504389c5a729a62b2f08cce0cb7f8a89415f6a3042b9fd852745cd08fb5d7563172737642a9f6bacff1642080db28ff94db5213e710038c4184fa85f0485a4bb7aeaf54fda0c6020d611c6ebd3f3b95556bd12b3f14fe85437723e47b1bbbbbbbbd65a8f1c8b952ae254413535e54d0daa9973e7fa57ab34cd397343ae9a33e6c63f8a4b110a0b8ff598d8138cd8eb62c0b08e68e958869283e5862e0575e39c7136cd836f9443e7862e0525e78d508cc5f735cdc3d930778cd1ca78dd3b07c1e7cf8f0760c6cacfe353f3a8f5b6b1215715b1d61381244b57d8ec271b3b35c8c15b8a032d754d70f76fd67529068acfba633da64de9857c879f7a46664f0492d0a9725d2a2e71749a6efca3168a11ca56e5912d2dc50bf0e0cebe6106ee3c2a21def9448e14462b979fbb1d57b08f69d085441063fc1a638c532ed56044622b2c53c9e8a166fcb1f62012740130c813b99c6c1524a61b72951179b9cf6c56242bc29572d42ff71e0d36acd9d31d2bb0f46764ee699023a458f71d21c5584158314887f41212e359ffa21f9f6ebf75de11ffa3d677cff25e42fc488c7b7aa4f5befa55fcd949a0e76dacdcd3a220dd778414eb7ea394fb20acef28c6aac32207e97edba851358af1acefa8f531e867b46d528f04fc59efe560c31a3bef48f7f6e30a859e6fcdcf0bdfc5747ef835fb59c429cdb49f45fcd2af48ac5f18b38c9f64025a5e52cf97a5df7e475adfbd7722b4be9751f7bd84b0de9f553b8ff5ac2772cab1e91971cecac609e89eebd35823042e223e25d80b7024d4d0831bbff5b343aa1cbd19bdd67b566c5867b6630536fbf8f463adcd7dfb4e57146375a4cbfacc7b01b14fff957df721d2cd4ca81fae3e3ef55e402a53ddd667b1fbb1fafac9ee595ef79af44224ae5ab95c3dd0faa61835b0c165282aae5031755b9f3da07b1a56f6da15458f487f186fd6fd583deb930dfa0784fb2cf3340ef403fceb7b25b02dd66bdd1722c9d80de95fc9d0e76637a3f4b3c9f28a6419fd2c760ff0cb755e9178b9af886f5fe85e96d198d4d967c46fbf5c791ce8d73e1328fd5e3fb2ef05a4be7f28bb1fdc60483fd2be6d3912f4110cc443ce1e0dcaafe39c2cb93010f7fb833d5b4ae9359b93cae539e753c96c3ca8536c910a7318b558f0d6a128050a150af9cd11055888d983f8c523ba5ce9e5f613c1e011285879310822bedcfe1f18944188b90d24defa452706923f2c61bd58a575c569ea7664ea9aaa24314c5a2614eedc6e40ebfa73d26d8fdedefe8d0245d29a52b1796cee98bd6d904e4a4106ca420a6d308f301eea98655946a3dc3e6e7960b0ee7e10e0fa34ccdd12b1be8492a684ceb9a3259973ceb92599f354c164712749994e09d5a6821455ca93357162369973cec9056dd2e4882964d07ab0a658a1e7888642082396cc07ffe75da87ea54049ec3084154ed04045455e6102059dc354032b3141f650dcb007d4144e6ec84f5041526fc258a3a429a19452eaa50a2a6a157652a8e20e8d32e79c93ce4922abd0228a0a3ee78a2e0d0b090834349440872aaeb0e2c9ffbc79f39455b14605695dd6c75a3071bca0f64d1a1c59bd0cf5a6cc0dedcb293e9b72ce3748ace077ce39c12ede68916f787012f98d0d4b2cc8374a5254ddd0be1072e4c869aefad81aaed8a4e887941bebf0c840459fc6a0c76e16f16def039d75d7009f1d9dd545fc4a59f4fa31affc79e52743eeba0fa25e451ded2c078a28a5947215853806350f8dbff0bbfc610ed7c7618ccb40714d0458a8c793c043f139c64e36f3478e1cb24ce33ea7fb941d7cffaa6a610ed787c1ed8ed1234ecd28986fb33a76374f9613d162aea05b30a160cc2c2920e924e0d0691ea2d0c18e17477899410c1776a40e52bc10a5704297b0cc610799e509a5945236db9299a539e79c5bb42496ce6001536689cc218a3c38bab80e021531a490c50b7660708a414561270a298c608edededebc00792363e08a715737ba96ed0410f884c8df3c98b71a3dc6e81ee8910ad12a1f4941fbd51fadbe97907aa4fdeab35d100d29cb8b525b836050a305954be3b21a2d92ee2ae9fa1663e762a0d690b02110b96e8df8ae27567e3abc8ce66fd33b92c27cfa47d9d3ef25847efdfa1dc93efb65e1587741e6571d5614841dd6e06dfe6929a557ab11af3134e2d78b8df1ce90b261e50924ebd95aedd71e840e8df8cdbe703aa5596c31db7caef40b91aee6bd7bfdd4cbe873d461f4fba83639cce46fad785d57fb8d3fb0d9d3cf3edba4c746b0f68528d4a75e18847ff5fcbd7ec4d79efbedbbedbd82dbb7f7fc85aeeab18725dc50fe10d7d5e86fabee39efc8eb47f6abd5e7dacb8c662f1becbc7e5f7df4b28f9da669da735e1d12224529dfdcec7fd0cf68a5af7df54ca0affd466b5d7daf9708fedd1bf5733f02c7942cf15fd2cf7decf50be97f202265b4289b6a98628c5c966dcd5572488332f3a10648a2c776231e1b729c127c931cc75b59997dd7de40a615bc3be7ee3e65dcb05e4966862eab276a758f05451837c6b8c48a4be365f3e07169bcab2ba2e1fa0bba22d7054b66b817bc055dd10516fc8caec88219cf65ee8cf7e98a66f8bc8caec8a70032a264e0b83264bc1d7365442941726524a9f2fc262a05237ccca9f3863560d77d6d73bb28244144252d0d453279b258cde76a3f57d3c0b8e26a618401834c0e28305c30c01765044085c31ad7816ef8737de8ba7781e7ba175dae7fd142175baeef7822e9e9d28832521084d405cf972f7440a2a44649621142c4192584b83367694af6f0f1adab8b2b61b8cda52fe9db00ac10b9aa252e7d59b9b8e1d26f592323ae9ca9a109942e26903c68b182e32ba59492c55dea83c10d6ba4d962882a2855415cfaac05144f292d028719435c5ca5d1428d16488ae48f1a353c74c31a2b9872a91aa815dc61228b2f97feaa2ba23f7628163c0061a1e6d2d7ba22ea0202aa8b3ca410183c58e0e1e14a2d5f5ab42b9a63ae78e2ca9f49288f2b942e6582cea5575cb9d44529a55d0d3b6899e109a8289cc81d82684329a551892b5fca6a0410ad035cd9a4c7d2a89366050bc2dc71d59942698618a70bead059c167aaca823a5eac20038cd30c3b4e96629471f2b1d342cf1a19766e7062a798a69a62d82c515a524f3d45b0c022f364c57462a85a76d840e1ca24b1ecc459dac254e9ecdc5995e1ec78a18599daa044a960a856539c645254da0d4fe8d454f58185d9942121472853459960c14798da32a558a14700c324a1acc013471853e577902cb198a5762d599f79394a69e986f63fa62a9d3063c4065466c2c0943063260c336f02800233564099c90206eec1ff018518d3303ec3e6cd0842d0f17721fb50679e38d9accbfab8a82e33c1b441155b5f0077b03d337050c6763ec048605746dc60b2aea81e2c8dcb5067daa839a3050726b0f632141a261c0461e56528343074b0049a18b8a0a90216292555283478aebc1cc504889a467ec040524af9335e4687c085667cd149c6e7b4f919b9c5c9bfa393537b216850dadb5e062cd8beaf7e19fff28ff148b157ff8c7ff97794c5fd339a71e413a570623346082f8208f326d6de14368c4edcd5b2854bf3882f1166bc8c1732e37bcd8f21e435bf2016bccf736c8637c5f09a5ef367fc8bbecf7c19ffa2f463cc789fef288606868d5ba2d30caf4e4f460c3b592d5bc442710aa7f0001cc56418cd16da5aadebbb19a760a16efa81857aca9d78a8e7ed6f5fc86fb80d0b0d198e3ac00da35310cc73f226060aa3d395641836e5423e45471b100d19eb4d55ea80815efdc2a7e14dd2c730907ce9f235505ae2d132a9f565c78ac54ce632475d3e40fd3008e65da6c15a7da21030900bc52c0c237ac3fa421d6d40344f66fb42171f400b0a75c0408f7e215755d9f8452c0cd4ffa6898d71a83450a2ba336b20e221edca0fe10703a434c240f2a50c6a50d24062c3a0fb2fc45588104519a5121a141465f5a15f0d5783f25d4f49e23031c5263c24b770b95a8c04312221c85410128884800d150fc9205808749893161ee2d897332e3251472465494957f8d2cf3e99cd7eea713569529b94b4c4431dbf081ceefcfe0a033592fe72fb6392152b6e686fff2775a1a2a27092ee002e434901c3dd5afc2359eeeeeeee524af9bc926337aebb197d38fd6ea8a8a44b68b0692029212669a064e9ef7822e9f6c73b3db8ef8f639a47f7fd318a7d90109f044025e9c647bafd118a87b4efef383da85a055f6e57cf9eabb56ea1e5cbf52f32d1225abb4da5795471a1d677670083657deb8dcc4b89da87442974f3c85483a51f910f095bff82276c1899989a877c252c12b21ecd636e3884c7c8cee306394f3210fdc85402fd76b99828c779803ffd6a784149f0af3f6bade4b1f2c75c60bb3c86f5bdfc39e641c3fae5d743d362ff06d1e686b1ca8e226c18745b4f36fed956726cebb21cdf1144801e02906c226080201ed22efd1e3c945d4a298d94ee6890067957580b368fb075e9d3a78fa379bc44982fdf68befc5e6e24ffe534c8ebe16058f0fb06a9f7848dcf2d1ef2a74fdfe5424eb15d8bd78fecf267998f23ff1b82af20b1cb135c945f12ebb098041737ecf1ce64c3ef6e23b6b8758d06df07b38e0b6e5cc1b11cfbf0501d29b788237f4c6a9fd78fbeb7430f5caf21bb600561c35aabec8af43512af4767f9137511bffef93050af56b4bfc6cbe95397b3bbb3ec9d66efd9f7aaaf5a332dabd98a66b4468334fb5c0c445d48946905875da8d6af66f139ca961d65ec2867d3bebe84c423d947a4d8ecd7be5f46dad14b483752cc575fbfc8c45ffdfce339992753c97d822596b0239528a5948af912a6c91c33658b3995d426d9145a9d25b78261c527fa7cf4c1ee75d655cd42326c3ef5a6cf902bbbd3b4164d8a1224a14a73ce3971e0acc89aa024c86850a299d214154c4f64c8d8d089939da1d366632e5aa89374450c5f5889f23fadcb5074cad0792242894f09cbb97a5c574baa25852403fbf23753f431bf768add020ff9d7276020f95576fe0555ac43d9f935d34ba766f26abd9db8a71c2669d59572cb93ed0fa55383528bbbbbbb3bcd6a56b39a65533a15f13c72cb4c63a58cc997f225a5d3952fe593749a5912175bcfc8ec2ebf38c34b66f6cf04feea00bcd8500ea08b0debe54827ba942edb3f966ea4bb7b411a74b11c638f066316fbf10586e5675d6139cbc62a39dde8aa11b5029b1b81e460f969ac60f9392e2c3f8d26cbcf6961f95759587ece0acbbfb962b0fff1fb698d952fbf23f225443b32ebcbef6524e94bffa691cf77ed031d16654357c631d72ae9e9c95aaa6ecf9e3cd2aae8c3bf6ea25df050fc3a06a9c36dd9e4591303655318d6df2c75f0ac04d3091bcaa62a4a45a9eacd92a20fff4ec2427d03c3fc5b0505ddb8a18106afd70d69950c1937a455d90978c83f1b32a7e8237e5d259eccb2afc618a43583e5a0fb65d7bf12c2c84005eb3f4370ffa0c12f96a5571692672453ca9c65f2e7c7ccccccb17f91735e13e6471dfe8573ce497d4e77671f43bf3f32f3836c57aeeceb17cea79ff48d29fff44c4aeab37e6c3e98b579d0d9834ab13dc3fa4dfef931d07c39db063bb3e7ccb3f7ccdd9d4ee7a4b75fa553122e9862fde51070052a3fd9a046e99c93524a69651b73596599ad2bfbfa8594d2f7d64aa394e9277f8d95ae7243db1c1c1b3fb4769b2fa5d632217b7bf9f20db3eff5c35efa56725b99e1b2496da756b3596687317fdfd1b9fb0423d90581afc6401c65fdd8ddac3e0b8a3f4ebf6d153ffa8842d661433e30069b7d17f13c79eefc000085ed9e7b18a5dfd4697baf9e3b23f1fec8600525a8103e2019aca084822bb39a7943828e6ef6e4759ed39698c47dafd5b31e2976f45a716fd4fd5196d567c4fd113bac23f24ceb07540e04095a7536a66672c505b9da576ff34222770baa755bfde6199137669ccc3167556b500fb0d6ef2a653a72b7a05b3b22dfbc217eb72d7ba2ae73ca5b2f145d8146e1c6f899c07a9e3c4c3d3f645580e3b2428aa156d13452cb45a105153e3b1df87abe0adc215fec351b27a06a14a87d6b833de4a7860fb6bdea853528e0dae28324c5dee1c6d42b77a2a0246c2a777efce2d2276a10dc3afdab3744bbd37f2efd420adc213f57360f198ba2b4dca960cbe001f0fc2e1a6c28a5dc7e0078ff1978367078ee0ee53ad3f5a5eb9ffca8e5d29f1edc3bd32bc2527e7d27a7ef1efd1e4abf5b2cfa1db73dffdd322e7695b6d25418a8df29d392cfa5c914e91a4ad5604f6c2a3ce4b7eb58b9dc2da0bbf30e03f5bf1abae6f627e08654eaf6bf7ec40fe79ddb318e8cef5a2d8871e89ae843aa79b00b517bc5e9125df2f61933aef4e61b0094b131261719a582944be372940a4e57724f13cac6383ca4cddbf3126183e7e085800febe46f4a80beefe037f080707836dec3f130cffb0e827cde14d1ffcf87fce4c6c67fff46dfff3ced5efe7d363ea39feffb8838ac8170bcc77770bcf737bc0e1ec8037a22df9aa311c777248b3f8ef77e03ef7bd0bbf1409e8defc0fbe7c0037a98d7c17bde919f07df3da39fcf3e0eef083b6c83204a6c7c47b218d978d81fa9ff1db1f1c19ea877b8c1f13fdfbfc38d8dff0fedcbdfc8c6e378a3ff9fcfba977f22e0781b6f64e38d7ebeff1d58d8ef6f3c070ffbf083e6f7e1f81b9ff73bb0b040dfc16ff0e0051f4409d077f03fde911bfff33872bc87c3fb1c38be1b379e633f39fe7ba31bfff3396e7c471e8eef891c47920601781168e0e1d0e003f044fd9a36bca58ed9f8f794304140ccc62f75ec7f7a416cbcf446e0988d774f88c7fe6f784772fc8d07f28eb218e9f80ebe23254c121003faa518ebe0757c2fff7f8e1d2dc518d0bfdc3b92c528c7f7f2cff11cbbf1475efebd44d0f138de28c7df781ddf5116a3ff1cdf5107ff7f04f4369e63389ec8813c8ebd67c36387edc0638b7018d703485787d7081cc3f147fc1413c18d17018ee7588c85910948098eefc637af743061de5cf22607de065e00bc977c8efd7cf18af7925facf27dec30cfe398e6c5022eaf25468cbf315c3786651692317e2e7dffe4c243f6dbc7e743ebf3af2f74f97cf8e0f599532e7480eaae9fe2823a6e28a76e5be0c509b91bd2a513a40c2fdc71c3b914ce23b8c1cc7e1e3050f6d26b58f63b82b2677d2178b3ef6453b67d2bd9247d4269b02753f6cd2522ac9cefcde33d8e6d36bc23b6a28a229262287448a05012cb223f86b2c98697c1bf07802506eaa5a8a464632ff150d75ab2f1ff05a87e8a4f36bc230e63878ba6180a1d12306462598808804ad27d01f1f94929cdc3bf5794ba52f70ca5734d1c7fd31fa9629517e3c8407a75065a9c4e4ae716d65e8e6a52e786d6095ba700f3d849b54113343770b074095818bb41c1e21811c3096ec860b5cb514d7668e2060ea6d8ec7254132a514d5450a1d1ac71185882a8264b3026b65e8e6a920456452d2dddb0c5883d3fa0952c00781d830e9391d3b48ca39ccb67b2b495c7ae39f8f3355c96ebef18db0220ba6ece07ce4fad2e17e8deeede2e996bdb6e29a59452cae972d5eadeeedeedeeee1e4677daddddddddddddddddddddcc1e6b5633dbdd168c891cbf7ee2cb96d3a7f469a5f4e8eeee3eddbdcacccd63dbb81827c7e1abde9e3be7b43d5c10e7838dcfb1e9996105671f9d9eb4eecc2d2959b29bdc26b4d2404f4ae9eeeeb23a33334797524aca75c58172cb28375db2b816e703c7c6f7766666890597c5c697cccc2c8362581968dce5486d4a275a9b34b35c6b955a46679eace59e676a92524a3549bfd612cb0d4a2d8fbb9c4efb0b7c95ae71ee56f6d0430f31e41472dce568529335a3938ed46a46670f313030e2c96378d0608f1e2c7b7a68cca0b2517a936696de217aa259cbcdb362b78a110c8a42b109cf2acb326e3e07a475b32b5b4a6c7ca2bea2803b1bb7e23a6d55a90780411804ae7b0ccee7ba1ff2d20910b9b856d6b2140ef89e8bc613cfa6553775537f37b5f74c4bd497c8870ab7327cba46833e3e5dd17c9f0e8478b7ef91351109e103063491e8e3b2eb2a8081180f118765868c18b56948d597b2baaafd2a41f974b716c72f906881a10446125c1e2a3d75f2741191b461a590c38c242e2851a25e71dac2c275289f0f5d6acc8d5467dec42dc6a51b5f32c9a6282638dc5056915602bf3557b533ae1aff036a727eae5ae7ac9e03f31712b9fcee69316ace9e11d97dabf5acdf9cc7cf5baf46c36495a42b5c4cda925445ca690b978e49639a4774aae1b6969854030f456b5f0cd419e5be90b3cd43d3be6d83fe5af36885ace7063b20ddb79e763f58dffac2ee877faf1fff99c07d7d13581ff7b1731edfcd0bebbdb776f6e372fd5416c45663cb6f296b6b5ab665f57385f2fac88fb7b0fd527619374565839d7d3472552e06a795317e1f2748ea10db25730d1777f4b136f2701e91fb6958fbc795a53733478dc50c245faae988d4d1842de4fa823556b0ab973cf4bacc1139ac351937cdbb526a14b8f5d3a17b2217b2600e192f49b1fe10788abb27c81bdaebc3403e633608d1076d14f2164720982fe70bf22708f65a2f7b0c9ad81882526280c5ceefad2b821297ec09f2b6d2f471811c59f6072d4eb23069c70d665d7da275355ab027c8195d51f3990f78a559502de058210a777b9f79675cfeee4090cf711fe76d2bad66744abf1bc771ab8de32c6bd3a17ba1eeb3b55ad75f30eb16602f064d408860ac50b9fe12c808ee7c39878c97a41b9f8ee04a2963dd04bf61816a4900b458d762fde517065961c0c4fafbac33ae3ee7e0baea75f66f48d06dd939a0748d6ec6bba29ef7aec8468dfb0171ece8211bbcdb13750cbff5930de82be3eb0848323821c1020625b2a071136386ad7ef3647c2b2f94778be1c5cd0b8feecb7ecfc70ddacf6708775b9f0d3595c16deb3ce95b08384f3e6fab2f3cbad525b38e63441a6563fa723e9dd3887b992165432458fce49c1f90ee8847bb62e3e253c5f6f21b48bf34322f064454adc72552c788878a14173684b1248822b0a041bac10b2a52f0c49aa617a03883a51ef1a5890b4b5bd4489971e20e9427636a70a18a34f38212197c50228a175e52e044132c984c0933450a253985a5bb301126490e5cac5461d102945c420e1a178620c10ada784953c606364ddacc3047094c1d32588a50f183152956cc14d1650c92152469b2f06108252b5188711c783042c30209dc2041c39a3261d88b28787e386229890c45c43c0a9326f06899414e5211601070c50a2a2559e84c8142aa480f767218020571b248e14b12121f78c0f24445c78d12333411461b20f0a8417243145216195878d374c4164c501af00186285190c0f3660a05484c48be809344c40b4c5978d12189282827a0a0c9d243122e28beb800c60b4b9078e1e9d5449326a29ea2c890844422ce1b26a0f2cc80e4c9982e3d749b33499871a24c0a787e807204961f5334c8f004551518d0482e0ee7688a9492921b92ec70c5882fb248c1c1ce114f9c48228bb02c3081a50c1e20bcd040440d5257527053039425e4c82db379b0001c12acd0c59c1380791a824a082849ba8c31c2890c42fccc2084933a2e8019834706b1c110456c21e70b0c4b3c915a6201e29c3b1828488cfd183dba7497d2047fcbf9b894f2db06e0c532736c61e39fed7fdbd1e08423e55a96a282caf5e8cd0a8faef605c99ecfb4af861b1b1a91d7ff33af2bb259966599b31cab7d4fd8ec897ca57d6683953fe78330f61101d6317b0cdd98414d82c3e6134008cb178479ab77b780ecb320acfab357f6b5c197f6f433ff97f63103655fa5fac2cc5282534018b22ccb3249b92b9f5969a35936e79c349392f9d9a564965688bc0cfb6ab55a497777e9e2ea5dc732b3e5724193f53959f21429a59430068a43eee04f8d70ce39259d35f32624b394cccc524a29a5945232b313ac2ab6c15d00fed81579db62a27f5a16fb63fdceb2efe88f8ef891621c97fa6d2cfb5ef30ba284484c7298fc1c6e2cc7b4cf92e52542f6ab37ca7e95511965af7d47447e81a7ec439ee25864a21aeadb58babeb1bde56ba706e57b66ac7f3f295929656520fe4660398a853b37690496a35a48ba1a0f55285151b4cc1fb0a85158f82259e79c73ce6f86a72c2988422a4e9dd804e2ce29ef9c73ce282876aeac320aedb3d5afe25ca0bbbb2b9a9991797d6a9a94ac56967d8b2f708d4c6f0f071b5dabff5c1f1176f55eb4aa736a9aa6d1baad3c49572bc642c677df3801514c4e709e3ace5add7cf7b1ddd9fc699817ff6a6dfe8b962459b65e45f5301c193b4607a37750501838e4f72ef97e411359d34829074d3a77528e41ae17eefc1a3be6fc1a656c92940bc5e8c7675895b65d9f552297d218437214644727e8e4b084ba5952479ea15382254f986e08e2887af2e4facf1326782403eaeac78316cab6678ea8041ea25f2debf983feae42ba27ee7cae85826a341577c670fd2368d3f0100b2399f0e1fa00b4a13b9fd9cb9d5db24b3f01309003a8940278c0f5e79e3ba9f3263b20ad1f0a6c2baa553a23730deb276aae824be0a1eab12bd2ec4ac4bc91835d71e1c1f6e02786e2a9356ce2dc59410855f47294933437fca02dcc45d5103e709102869730f2045b7871030c29b0810c1236fc8025c825c50a2edc2c718309a27832473acd3373a20cf15b94133237e427285e739dd9506597a39c28f1840b0c6a2995a9e4b201e76e6c86c0c00e65bab860064e17282658f26632b1444e0d486aa05343d2172820020b1f9e9023656e804a933356a058b303179985c9d28a09262d38993f9f6813a529b436dbea7294132e576cccee85ae382465fff42bd2baac8fb54feca65d8e7202844cc1c7449b945ad5b41ab34863f4e862ea8dee4aaec7a406659426868ac2f247270957be7b174cb1fc52724bf68e6eb60c54b0fc910121307f80d4b1973cc39841068a3f35a4e5cf66d44bb03def60201b622cf3d768707a4b2943ee5a8e6777fc9658304ba794ba9c9e0e4456b2c75ab2f27988cf8df23959e98c69985d0ce4534379e7bd7bd8f8e7b3cc595096654fc199516a5d73d6ca94259d328b9369fc9a3d675ea0eda8044e974435e9d0d4000000404000e314000020100a07042281301c1ed2e55dee14000d7992466e5c9ccc635190c32808216388210410000801060898a9a1210e00686d76025bc4ea29c66fddb6a2625ef32650a17d51929d62e56f757534b5b9e7b69a46ae0504606dd7041902b0ed88c9166c7edae2f917205454e88abc5ac38df461653ceac3153de72f6d48708df4bdc8f5494b6e6f0e589b8d05e1a32f599c0eb4703af805f5e7ba19063c3213553b890b1e3413f8104878e29d927f86f3302866c12b308e9971a5f0e562c1f5372fe18aaf8e2e40d0dbf772add0bb868d736f6fa555237dfae0d3b0d09a62de1bf91eb8496d23c5ea087cc370f1123ee8c4dd3f680660bf4b8ff0ee53012625341a6c7d3a262ef00e23d8b42b83ae8125ec0359d869361d26e8998536ce15c471e4ef808d8917825f6f8af2787bd0dea78a4cc528c7fa1ccb668f297dba1a2587c1d45e900e0e1a3020ba5062eee10cb5761b9ebed3d6a6d0672b8cf10a10ad077cb63340cf968c0f51a2c04565806f62d25b8e8db508a6099e4a810b9d053c74d86a66cec8875fddde71ff2ec76a5123d2803790b430886eec3d83b57e1dd3db0386ad98029a74eef4ad1fd92abbf0e77a4fb6aa8ac22bc1126c21b4315717640458ab3492e4d0679644ed8d371a52efccc24715b1d5a908ab0ba4bd7c94ae6032833ea11ccf7efa2c004ba4fe30ee2a1138e6c6868bb86721ae3d088a38a0e8c49e63b24a275a614fa83877dba3a46d7bc2abe565ac528244b10bee5e192a90248b978777b897ca8af3bc37313b80edf8696418bf91832ddad7aa5055822c6eacdf814f3f9f9f701fc49ee5b94b70642832cb9b883f994f2a0050fd767cb1d6a7618dd35b7f49a74726bc5303fdda29631a435b091c33f32810c0cdf439f1d1c71e520e206f798ef2713ae4502fd133463345999c6d44b54c9753a4b943d2c1c56e8cd6e248e01d70bb887a2bb224da2517a133f668b32dddd59f4438ffe030bc036072a3eba9ab97fe5a621d31ff371be3ff8f3cda7b6446c797ae9ff1a3c0dd77c0202b91eb36f6048e8b42033d1e9ec14d211a7d430a44e1c9956731f50156ea6d7b70d1140bd850de7c9e4e5409e4519fcfad5aa90cf606e1bd68e2c8f49a2db2e94a3cd7ed0a1e52790bca95181efaab69a04bc593b91ce64548bd3343ebb108e882c57cf4be98d06fcdce6aba45422417e8d4c8a8cd9fd09dc95ac0e273bbf35c6a92830b3daf1e96bd7448a6a9691c5377bf6d35ab30331450c9926b19468c9792ef4b554f52349020eb109f6ea8c8540457cf80334706f511ab5419a891c01b27f28bac0e8878f851d49142885f64ffbe325bffc7080865f3c8d1ae5391de18526bce8b43d3422a994182d73656537c21ed39cf4a578c435568bd8dcd4d1d0d4b8aa0c8cab19efc2c352b5157125c28f771c5eb7b36f7ac89eb8ae6fd25f3b9b8feb4ce8c9861a7ca6a4a6121de7eb91ffc4aceb45df6e58e185c55316ff4898059a018caed30ba1dff6e5e5d2bc7489a09d323a2cee41a363990e621e5ae9236bf1e9d04c747c1cf713ba3a6c59d23ccee2e929b1fcefdb7445e8f12382c344a3bc2bb8fd904dc6bf3d66c6924d4c746884e0300298393c069081b51d59ed0efa673ae13ac788742757d91846fffe312d22b0b064a9269be70c4f592c0c6c0de52d8ced45ef73c43a5beb5b2ea119b026b36a1effb37f5a12692677ca2c5541421b230b03791102770890cdc7c70a662f1e82aaadd35591c2b36d7013a371e49e4de7d03423f2dae50a3b90e9179cef4ccac2c355af7b1e8bda115ff7f73a32137f52a4f59eb8c6910e1a1193ef2084d82c9d356319c934e1fdc96888d0be44f164cb03cc48e12cf2cb060b0a25a9e54b91e06353967ab779355891c3dc4d5630fd838d8540f72d9e2e0a637784e68821893b91e26c441476473e3c5608e067d75ecc04043e73b800a7dec75044d97c73f0e933ce1b83430b4a851104e11e1a6b2069e4a1c1a262103ca332bca7b0e252e9c66c4dfdf2ae04954229363bea1f88c183b70ecc34a2b2302d3ba0bb9a111c06ec5a2dca278802217fb0855a3ec8070b1176240771efdec29d0b4880d4371392a170cdf200faa9804599f96c90c7dc90260072255633517ff0fb5095a771c7c1dc51dc867956f830a24485d39f37050231e5fcb01e0449c1a2c49b1e4c41481a94a700c177649de02bde910e27fa12161399dfc84bcac462f9142f5b20ac5b29a50cfa442a04ba756843f75e50becbe095baebe4b075a1e2dedb473f07352a268f32e322013f4ac1caec9e9796843fbf014747798d3180c661dd459b583abc0c72ffa2403f583034288187c83ee4262581cfb45a1e6eff1c18333dc76a1b123518cfc9219879c90dc6413baf3b142cd965ecc06d11508dbb941cdb956c18dc67141a85ae572d5e9e7e78289497fb28733aa74b38115f72453178729f537c645adc677481290f448b568a5e7734bc7e30ed2fdb19473908e08ef89f0e4f7324e7f1c9dbb86166edac1bf0225e2ce3801a1ff61ed21c025793a38f267ec88b38328e908ff60cdcb51542c8d424ef440efdbd7eab13d3dd9c8ee930882250051dc5fdeeb70b2ac9eb2ef950bd21cbd697f544aa562c5bdc5e1dba3a89c20da006ab3577c6090257b5ab837564a2eb0faf6063c6d3c8dc238054fabd9e346ee26029deb5232d786cbcb997eb9f237288aab003a534f990912bad043603937329654630adb6c17aa52727e42b9e776e716128f077f3333990953b6d51d344adff581943dceb93a3455d0b577294bc41bec01d431489a681f505c165eef26738811023a4f2a564dd7112fdff8d491e168d15e8f3501af80b5d1e19542ba325cbacb755d2b8af9717eca17680e11b6e5bbbc04bd11a8ab82dda34442adbcf5f4268d1d0adccebda03c2d016e87eb329efce80ba8b5c80addcc018a646550acf33944ce4a8c0a3a99038ccccaa050f73980bb598976e5920d47792da8ba2a7cd5e94a0c0a583de184e8f67ebe25b5d8c4c9c1daa61cc4dd4a2529296f5dcf99226e21b98ab904fe9253dc4fe610150284f374145d57f6d9334f104b7a92c2783915f6d230b1f5a9a1bed31536ed668cea09d414b6979e37ad5864ea0e712b725889622f2d616fe61611e03ea358e44e46af0981ccf3b25a462220d52f354dedcecd5d3f03a2169f892820944e343bb2c9455ae24665a05401e39b6f7867f7a178a544c27a1c51888c447f7710021309b1bfd87fcac3a9ce0babc7d84fde08063f1a8fec58de1666fe375287476adf88e8d03a83309f524de2674618c0ed83842607ac8ddd1bdc5326ee942db97e00be6c4d95042884d9363ab6d3128274de8e879d587779b72e62bb96127844eaa1f1eabfd65292cdf32cd2ab58d76b040ed1b39d738a4f154fdd0ff34a2dc6a1cc05a078814b075386993addf53cb2284628838aead645c15605ada73443d9b002004d930980570187ca6d7f22dcdac215541e626cb6888e985c4e0487d8e2286a221a3dba8987177bbb57b52163203ce118a1ba0a546844fa000b36aace6391cc654bbc9427b45ab9a484d59b48a9a16ceb9f3a1f81479393486371a2e6703064575dce91a832a90fdd323954a60820eca2fa9b24497b94651915cdc36438809cec30630136b7514f7169a381f181c4f93c2dd854806273e69b96b74da636c1af04d7539f3d9206487aba6d63eb9d8ae9f70d8499cba1750f5d4e032e3b8593eb412a36e382715c64f066c874f6970150148bf9182abd3ad5ae846b1ed687ccda5cd9b96800ab09087052ed6927c1c444a5fbf287ace9521cf27cd561892629188c58425f26258a2ef57351e5cb1955a56500e640e0e2c6df48a5dcd24d071482bef17d1899fd9f5630b3c036568aec8d0f6169bab3b695ee320130083f9f82d6ef2201de83da92fff4a66424813cdb2031f3da18ae33a7dae28d83102a9a3f3ee06c46f1d44f83b7824e2201297183c742391ef22a5b2de7472c4a7d4c6f47b809f68723112eea94036ea46fa763d8dcde494fc82f2e0606f80e583749591a2012c1d5a04f4b26d545a89ef91098c5cc8c3ca2dc80be25d28405725a46c9d1aca405028b1073ef6d2f94ce8a7368451c9490afecad731e617e682989c002f0d1d848f63340ee072ceb5767fb370596f4c182cf6a836d63757370a8320ee74cddd8ad0cc46927e8f9e64fa6c1c4587df416f96d9798aae74089c3ec5f0d5075c18c3763dd516627cfbc9b2e8df870996cc7a99d3e5631b9c90b64589ed12f1cae303f8d52ca09da7c26865a5a6f66fff17bd45245a315f5df46e7aea209535e5e30643bbf9388dd477456aa2a00ad4951520f4d115801f0be5e62670a9ae6fbece34b9f6cf672ee60ee0ead44152a26a3fae43e9f4588daa9010d97c7e7b0bf3c0551b55029443d6c9c00135f0d7830a266522780fa1cb1b79ae7ea0e8b14f0b3592de045824b857558e5cff771bfc9ed31ffa6b159fdee0964a6b7a534b6b0b159793b1d0c9a9c9c24bce3e66eb8cfc4bce036ecec3fa88b40706299a6698f4bcda375b51ad53854a0fa537ef266b37e9f2a718818cb075aa6d7703b5cbd5458bb027c58d54ef05f187c1799177ba2f7ad38c5de65bb4ab96a161f6e46dba55fa8d2908fdecb5a622ec76821400a23fd771735cee9dbae0df327f24846f426b84857d027f7b4ce3b6d9994f29466127cf1f4eb852f1509791d416975cc5576f68b2eb0813cc6cf025f77fca11b365f6688aee19c7e856055fa5202cd01dd05447bd22088f42d0d06e808588bd35394526e023e74e1eaea32b282610c7bf4fa4fde324a374b4cde461b7709ce3560abd8592aee09afd0d3fb4efb25bd9ed5a9e2a1fbf9fdba4bef0af6d5f74db0c0dad119684f9471bb57e5bc0df284472af5bffdb98623d08c45fb29d7b905ec28e353409cd8fbfc3c5e4fede3a8f2af098c073ffe6156539dd7c65fcf1e12c3410a7b69a5a24bb20af60b6c707b49b1d4bbb89c50eaa91c077ebf3c5b5db1ddfeb78d4e993807f1a34f62e6d9a8f2e9a5307703304f2787700504a8f61b467cafe2e9c80e10e9e351242c40da681931aa1736100cb7196ee7802ed58efcdb7dd41c76a54f01c2d94b38880324dd9686a0e087aa8efc647adfb53b21cbe24ea0a625ee140d4762277ba9f4affdadb938622f6a288f3206ed7b1c76ca34e9a1bd000a2dd53a424b96558974dd1eb75991e051dcccbfa83e81a22bc40a3bbd472c7f623d0d60b2bac20c48e9aa52720def41c406505c0cd064784d4ad74339ecb926ae4736ac33d5bb5c0b0bf833f0eb4feed4409b5793b879ac4f9da3938101215fc84739c4a78e81adb26dcd612959e08f19fa68928b55d36a715156f08e084733ce8c686fef5281e8d9f97fd146aa81a5a45aee9a72c426c479f4820db4dfb9a3122447dd75a4c7f69679991247902e80793237fb42853bad956f94c7ae5f2edb4638fd7b510c6b962026e3567eb26543b35f9789aaa5002ae5f311cb1a5798d42ce1f1e9d7a4d77da7705bcced0fb37af384891a470d2a63b2886cafd7d0930148e77e1200c207264232e931cc4935afe50e61bc5f8d38c09d1d85ef1994803de4517fd0601e40dfbf91030bc49e8fb818036d03ea29bd0135d20b90ca8d39077286dc7f90851a79b598cd5d5dc711f95496864ba1418173c3f0eb74a8cc7e130896e7b99b03f705f4ff8b4fdeb26c31f59806cdcc4f09d3084044554d1b052c0691e9ba0c6c1b4bfef820ce8d3f4e81411cf9d89e47575a8247302fde9bd864c628585df5918f07b270d202a938c58d1c4f70591d6887ed0c4b07916c66c71019e86dfd08831d08593892a41db5499d17345dde2f39aacf439213882ae02dbef297dc7fbb94ccda52a80ad4d5ddccf2dc73997545b6c39b1f29a105e5e10cccc06d5ff79954632ac034cc395db74b5271e0f1184209474cb4155c88a8d409082df84124cb5ce45af10656ef70b8cd49a67c5ce923ad14983ac3ab530a710638c66434738e03299f25be424011d4e2dfa94a71b63270f9bc0db460325e402953f1517ab84eb0ab628451eb0a474d4bd8d755298d670e14699611b4ae1454a0485728536c6ee46aae4bdc678e7c2f59e23fed3a6c86f87874045d571135e438fc35bbe4a12504ac96ed4309d64ddc2d021b80eca9b2c676bf9de37164d61ed2ff9ba205fb23d285d59ad5d0632b8e0c45942c17430e20559ffa7d8d69a9a5a46ab4506d0ac0147fb1e53431788e8dbbb44e9df60394c6e47c624a28ed0c1da21f97549357b16d4c998457170f0e82628b4f1733696143322f196f7d3f978825f3a0b14478e1c94de9cd0d961e82478223a705421a3a5d47ed49a0e8a57025e6c765bbd8d2cb193acd09492e6042cde10aaa1b6024e226123908891b69ac0f24205934c1bcac72d011103744640462dac81c4ab7404de9170d629d1edd2a95801a962c4d7934f10c127abcd8c21c91217ecf666a99f4f8b9bc421d4a8832618a7a1b503557f67add8e4edb6f8155d174ae0848c8800d4e411d847ab6b084f4b49daffeb5f9c7af769a887245ea40b55bb2e3be2c643771686fc5f6ca27f4a5af6b7a091f7890d36c0ac8761e8bc047864dd09cc59abf21c638f29ee78088d75de7979b759d3800363d57fd7a01a939974a912d71d2834f8c9ca82b942d0fca5d849fa3e9cf23c12611a355fa22ff3397a44a9e86b1ca6d5281d6a67f4a7bd706a7939c17cfa753910e99b730ea713ae976c5701ecabcf3323d01c0a6fc1e85e60fc82fcd4d9b4779eb4464e9f33914289d3dc5521d1f331025d7f3d1ab5f88c2ee2ec72b274583d01fa3dadbf73d4fcbd3beb3e38fa7b962748761c07d104a4a62ac9fb2442fb691d83ada38153f65164de908146378ac870ed904ab8aa0f6f6608293dea14f68a10288766f70accaaa3d66ad4ec19ff266b4427a240bca7d17b27e74f9bbd272930f9ac40aa9ddf0ad088fe16fc3f41196c10d4563c53991a27453b4aea9d1eeb37d52fe06ac2328e6382daf5c60610638b0032159d5caec79adf47e861cb439d60c8231cf0ea05edc48382dc62a836c49c24b34a285cc5783613501101f630d5b545d679918955cec7aa40cafccf208044306029cbf03bbeb2c9b7dfe2aa3102a9dde11859c45a5daea4f2c6cfc506b9e63319cb90c4c90c58de303071196b7d363f9bc82e6c4c5882bc661b472fce6c836c3cb6952192a3fe74aa3f0e516aa24655c579e052b9b45dc74da903df117e411ce32b2c94cfcfb11249990ba9e4312fd84f8e114ba6c184ac91ea88b692d09c01401802ced0c6b2718d83c95ca4f38fd4f00c08f8b8e30f019c2799df2b953995fd32a314d6ae03395ddbc732c60c7d66f428297e5d802dec21a26d4e9881016d34ab9b28ed0012e3302c10a9902f2d70d0e6b4ff4ff8beaace306931d093f5cad0cd0a1657a5331484e71fda0bf5d5287b0424f25187a7b0514ecdf6699ec5f85147475e4993eadf79ffb8016c9e1ef16362041c063dd373590d14caf8fb191410e62c23bc4b6cb04f3105d4c70858b2a41cfa0128b3c5899822cb79d047b1687834dd053a242d1687d2854f8e9273f8ced39e82d10d9c0d10399ff4d7aaa75d8f08a38c108a80731d31b792108ac21e09396d5dcf1f9606bff035113687fcbc695ba3d19110d3e9fe9307600126e0e0000e166ce053633df90058e0337d882c84ce184cfc8b9b1c6385556258e1de4031c653609f20949136ec5d639b1da4d100bb5c48d4f42b17be11bd3559aa1146c16cd2e160d42354eb84c150c1839708c646b064e06e04d085e3261e23c9fd105ac363000bc60441416a299970701609e3b541b6e5045b107b3619c4f496a725b6112e0cd5c4d6ea1fd55f9585981df823acf7939d974c98097d9608abefff5d29fe1c88519b20c652780b632683313624f1f36ef5575cdf6dab54cf6afa1b1301d5c0f8c0bc2196142b04c115748494c20d2c702d84c80d51c4560d0aa5f7b1bb10deba8833a06540f547582209eb3643c356a914661d811667cf2aef048b29ddb45a09a8eb2e6e12968b9bcf40d8bae67d89df437d41a0d063d912dafd639fb7c393fbb0bbcaf1720c09821c9316f36a36d0f0a663bb546dd98e51dd4ed65cbf240064737662d252742b994fcef1bac11060e9b1c290b8570915c623ffd5506cbf02b1e8671323ee0d7b0764d906442a240c7e6bbc147dde0c391e2147dc9cc9a916006d545daa04109458fd3e39803a85ef6ecb8b98982f7d3cd52cb34b0aafea94c562ce26e04b53006a7ad2f0c1937eb7d065eef0fcad34ff6ae80dce7c0e72cf471d69565fe5eebe158a1e95d8d6160abc4782328e5e9ca8438aaf43843dd70690b44f02e5bc894cecdcf8c4dcaffd72dc6287285aba75e03adccd9ccfea2782c302f64be619a09af731410f72614b85407f9bc9f1ac5728f8a38c8fa30bc1f33bc05476c1d4355e235f9b198760f0174120c32e400ea5a9bae1044194e79f42bc9dc6282d2e8e503f4afff1d222d027d2e80386c9521a4737d9f19d5857926cd8f45f99b84e3d5ac10883664f674bfd5d3bed864f302e2e503f3b038ae0974c2707c42fef15a8ac56aaef21b2cbcfa5658b2aef3ba27c27df53e9742cefbc741f42f3c644318201bae7540184792af7e95e87f6b27a94631543330ffb8cc2a062a366a7ade77c166490ae2e0206073933d7ec2a9dbf4e15be9e5a5a9ccab5d2c6cccfdc984f89970ed49577a9669247fde50920b31aaea972d25a7849b893cf16a0ef41b7c8977a2aa18e7588bb5242327db9008d12f5a2a593e14616c0a634fe6731741c04ace10c3754acdc06faa11d3a61381fcfdca365e41eaa37f516550589e91fb1fa34a7f591fc42270d1f85d3e69f297d5a76795436ecf6e9a8968ec686b575e703e3ea8fe10164f7bf587dc96c6f50a4a71efc3c9e070b0e98ef6a8c512edc3071ebe8d16fd89781ae45e010cf24eee2958dc61fa5c30699af775235f552f849676978bfbee5c752242596185527380f1cd40e18c5bef5e599aa335ee04d6c77ddaec1fdc1217c5c127374b3b69c139fa19b83c7998edb182dda062e757e5be1a2b6cb6d36b44968cf1dca232a3658fd299216342724067762365cff57e14bc4d6470e5cc75ec7a09fbaa49be4dd76f3f9626dd92b3755a2d11eae9089a8733630ab481a9e3d461943bbf1bcb5dc750292c1b5ec0f6113bfc9baa8d258a6c03bd29536f62691fa4a200ca6e24767e9dd9b1ad5aca15a251c57f7d615d0ebc2a8943d256095a28835d16ad3d6e60f26411beadd4ce208558abdd529f4c7ef29ac36f8e0726e5050ab329d6b041ee84db56cd83b9b95191aeaeb2a3592edf681721d5c45f001295e8a89e9446e78ddbe23f5f15bfbfdf1df1bf63dbeeb431c906279563457126b2a7481c6b7ba0fb4f8d8e30ebeb88e82f2b350d47f1bd243cb4bbe416b786ef6d193922cd16c5548f5b3b2d5acb3245019201f383d3047974cbc8f3160fa7e107f0cd0177ea67a79ffffd0e25e42138a03e0924702976104cca260c79f78c17a53800b2ca0c6603f2841649a411ceb6adabd228ea97622a2c3ad195cf9e8c029d218e3f3731bd741c018807db42b59a44885b40772b0488cfb0f3712803bec5f1afee58f6237aa9904c4abfdd09d24c22889d924754512b6e435b4ec22753ac1fbcbc8692001bbf386268436ba12afc57710584f4420e4dbc04a2716c5adf49a14a1dbe201107b737c88a07b91b0ceabdcdd53676d5104c3203a71eb93ba402e26a8764bb4bf069d957c795c62751614a91dd2003fc8f5b0af86174049e2867867c0ac114f1e40ade705abcdfc8e4e1458719d1e199c2f184527313cb0da23ec01afa53a2006f37ccaa3d50acfd8e8416aa705d49e058b2b82da0d7bcb3e0420c824d8136306e6b0301e501f00987c21c1b9173ab946e931638c9d56a794cc0b3351da7a604ef8d4b9bc3e8c2a1b004cbd60f58f72b0163e43b16a9b00e6eef7b3c3fd2b886ace554ee41ed11e31fb3816d1ab1a07165855057baaf5aa13f38d629f88b5d0901eca002e4d80357814a437357e0468924dae70ac5293bc734790a18c7910041f99a8efd39f673198574bed10744bfbc0ea5471f8c1efffb4556db3fb618d91d041eeb057f1d436456205315eb75469365dcfe1fdc22009c15d8515306c4fa61db008c9ffd70aebe56504c6c38c8414f00ff9a0084ae8f928824609b259beda0bad48d33b408adc1a10a51175919fbcbbe057ce4041c7be2c0bcaf9d772ae05b48523a962cb06070210d94a0b2822f3fb030e21a08226702a2870a9cc637f8c2b26660cb699dec04f55ae4b8814a27825f01dd3e8134d082f07371799664842184afea0442f00927eb038ad4018e760c4f0b746e19d21ef70a8400d8fc89230e151207de4e0c7d5b32fee2f775c3063238dc205b52c208a860d296bbcc2d67d03eab7e588b25f271c87e37a6bea86e05026acee08d694655c62f6c043209a868c632602271383ea3e6952b08c0ce28ec010f2d62ea4de050004451e460cd4c4121cc09caf28ecffb41d74ff0bd3ee48ea25d71748504112df0bc35a1d6e9d9382c069e63c60d88289e837638596f57fa22da3e7ce906fb85202efef24356e0ad964f6b0be5b2452678af4e6fea45d28b4f8e138c77d1f4321ede96b3bd0f21223a1520d7b74b1ac60c4d1cdde05d054e47f8e01d2e44d0e8ce86ae1bcc030af4d554eafca9cb325fb2af676aa3d125db7b4c5571daf742bc7f80be3b8ca1474324332a4db35cbf6ccc7bfef3a1a7c51a38bd02f494230ff4baf7a6693f9aedb5bd1ea6f80d9ce8a17b35f51b079bff1e76291297ac81bd95aa39a708940fd4ec86f2afbb97b4dcb4baecb008dfeabf9ca52f1b4dda758fe388ac68f6589f2b6dad34554db2b74860ec5526bed67b95dbdf3e8ff87a953c324a24efa7870cf3d73025020270207bf7c4be9bc8a09e3130473def0563ea4353304c5d4c3383458a0100fddca114f74e378fa06145f5faec7c772e9fb9c1e78cef7cfff22e844b02ae7457b07691fa49cd106e03b1b42956ffb91929e3d0f00f2e2dd6ed5db63974e18ae3cd459d9268d4e20bc9edfa95124920783bb1d06c5d35c8191e6d455ff0a3a90d309c7c25c9af449d5ba745fa10609621a9817393973bf4b4ea75958faa39eb0715c35a2a3de6d6976a82a841ef45afdc1f24b06a6003e0b3a7da9e5c1b87f054aa09efbad578037dbdfdd7d2133abe925be59f9e7fd683be7362ca46e37923f00bc8768110ad85c387c76ecebd8875e97ec47421e6093631d09ba734fecceb8af3614fe20eb778d06cf6bf4ec1bc1f02dd391ce80fa96cd7877c0f501bdccfe8487ebc87788acc1445bd3204323f871f3fe0a28f130fdce254200b3f1a36d71a1b6147143f4a430517688f82f7f4e40fbe7bd29f864964b3017ffed1bf2f69766afc7aa372dea1c021aacb624dc06b12227e0cf1600802573ffa4e113e27fc16569bce7616da9da64681e4acf896d45eab051c55cb3de88c2cb8e9d6282e5dee3fd25c88caf75eaaed1ffe75a7682d4b3558aad1a1520d7dea7ec1c1b879e099c0e5a185628abdc28035ff34867a855011efba09fe7ec1e080aa2ffd5d9f194a16552e7c57a9605076d50b79975130283755b4f25df301368536e93dd48669b2aa2e80a990952cf42a7ac1366c946a5bdd02671a495eda21a8dd1bd54c67042028a4ffdd5ec2e3a2d943d0cc8cf2cda0d608090898c939a828457a5ca01774cb12a1963c265f8777caa62b39042c8176de6d63ca2903c0b6982f45375a44f85fd942077aaa7564584259b29ace640b53609d67e0306e757699d01b30ddc2cbb6323427db79cd07c9dd2fa0ec56820e00d1012a2953ebaa1e751ddd44e378c2ce97cc6281162e64a8be58d6c59ff8bb73e862a6be3165103c5c1a845825b93f1921ab432ab021d3e095307f8b836ae77ad62e8d090134a48f2b3edb08f891c2c8ac3ce18492006d6e84cb725f1164b5827fd6caace9b0150f1462d25939f0e075439df17b71f53bb5036e0ff77547a3ac59f3da65ebfb673b8662e88a2722511fbcca8e191896f5804562b1b7e383952858b71ade6407b42ff952f9d7cc09411e84b1f2ab9a3c634cfd258366146ef8a883208307b6091aa6de65c7f5607b780093bb429429694e34ee6fb8bf64b1ab45274a1bd1b5a11615b20a4b3c175cdec3a376f4c04bdd7213b9ebfd14192fa8cdcbd7a3ea0d67c706d650558684fbc0284ad0d5566a75b2b315ade236f36c82709b561e59ffa63f6808137d157fa0ae4754ad479947fd47510a4972bbc5523b73c47b8f505d24eb84e77856cade1702aef08b9d115b99f1246d271f1a2abcfc6c0af38b51a7779c500d74353352c98e825e3c710b8c5ec26940e8ed90de734da7abe28fd5b132874c107198c9decee9626a57083a30d822218f9b781c3395761b903be931b19132748c4372b1ccdc487d56629fd775baa481a7aed10005d5b1f63a023854295e80dbeee46a99df02216fb6a22142622d363292953843f5c5eaca138205bd5a4654c37bac8865ba2584b4b79ecbcf456b6132120425d71650c2324532b982a988e5361c95e114dbf0a8897a312296fbdbd10762e466e0c8f45623356ee903c45420ba12d390ab8780f76c14b08c64839bdf1f9caea41756170bc82022834ffff51cb1fda1e00942a8dce1ecabfb7bfb4785795e5c05f4f1d1a9a144e404683d85653b758200b984a151aa9339324d48b5c3dd1588bab30e335e9cc0bddc6f27f226ec17aa8e9b92cf9ce5999b46ed016f40124f8ae8aef2b85f93ba8cccefb7b1e7742967abc134e5774fff2477b997b570d74571037b490ccdd4d1110ff28401731b2ffb680d28f80a0606ad8aee68c7d3c60ae79a015d5a1aae5df92c74f45211a1fc8070411e78df07ed0e9c27f4e98f9833df9d906d7f2f150391639cef8a3994f0e968096395d9f00e1a2f4f358bbe7ed22d657ea8fd9da9c5edf21440480b606840ded9be0b0d5a4db98dd9d650381c2f1147fffda3d51e13c124e4dae72d5b59c9f4456148e026157f4516f95dc1261488878fabfe755a65c644f11b78018bbbc429fe1a79d861051fe5aa38fd7fec7e653e1728cf6ce847b8643c770853f19741fca90de277315a9a23ea1843d6c44aba2b46d67de4fa5ec1b037fe37d59586305b1835ec0414f4f1c867778154831f8311806b2b0d29923e96a77d19284fbf5518976084b19f54ffde40508fc8a4ea41f27d6817defe93125e9d3035ad687f8f460b5b9dd0616885a4eb540f02792f93b2cf547646315633c8427b9b80401b807da220a671fe0aa22da59bac88d90a7e8a513c9f809e80c84338faeb66b52ea111be9daea01168c49af7fd67691055f1ab15c384d0104715430f32ba7ce080f5bfa05509a95d0328738b1dfd9dc6771515c19a3f4db04f9a24911081e722198753a510133a3c05ce5e30ba983ea7585905940c8202938bc0c6835127306b394f6fcf1e5836b1d9d6eba112badd6f08db63c7a706932098e312f4f200695bad3751011e8b5dfe0053fae8ff2d5c354f62ddae0bfe2158813dfbd4029c2f5fceb959824e2c7ab18f513e7f293a023c162119761e2cc1520075b2f7be552faaa70c1bd6318f3bd6cb6fa64224671ed6acdcb2e996661373b44f065350d0a2e56fea12bc6cfe326ccc1b64513f117fa47e0ca8c583eb25bac76dd47801cafa753f195dd99408ea4dc582564b228fc505ad6cadb22bd22fb5ad412163039aaafebbf07b00c8798034aa81159635892c737653b082b9d2a723dcd4b5260f0d43c41df65bef89c507b2fc3764eaae98e0bf6000cb36f503c8a584d84b7d8c42eff3d05d8331a3126846b390f198d249139448f86f07e50dba15ca7ea3a86622f4408d191cf0dc4f854fd1b52c50c5128c41ee071e37f714eddd1450a64ff8fc6988dbc3b848c4a8684d02b12d87e0d0d3185344e053c89f974a4694c47d54d76cc352d74f86502ff871974f3bbfc27cfc3aa303161ee9a84880953b275a7a759cb7ec9155ede82be28c3f182dd9cdbdf315969d52b6eeefa3a27336c255951e4ebf8556a04b4322eb431a3afc0ccd49508551c24d43a7e1f3895aa0d8e9d72c15da0f8103dfa1f9fb1bedf88d1bc1d7d3f34bcda9f41e26d44b864cc0c2895525f362cd7257d11aae8680d33f56cc98adc548b47bba82430f7d01bd0a50ad9bc9d586eee2ef3620f95f3f37d7e8cac4ccdc17f7e91486dd5018ad3f2257dc475594eb5e8dce5c5408195d052b4d92fae966fafd851e458143ba19bc4e5d9cd3ccd3fc89894b62d96e0de96b8000b760de82d7733c8bfa25f4f5ae0373cf9f8eb2fea7903be204931727066744d0f933e2b24a5e48c262367379d49000b65c968560233a851a4208bf2f89a2d7e11a37478f588c26a1072a446c2d7f46e6700aed9cb9a358505b60d88963dced832ef99dd989eb43cb4a5a69b00b49e02e00a618c63349140041a62acdea08c18c214f9dce10243d69850e5eacefeeca4e4f87396b6aac652b748d72064faa23c275d668c018a685b44e12637cc7f90c2ad8f3236c70ade26fc4310d4435d7514bc708e1e54757325d7d8aca953c0b6a7b2eac1e91152480bd3d3943dd95f636483302483fa22c4e691279907af25fcc833e1688731da7a85a8bcf2c7090a236b755cbb7085f446214e6b36c02d1b9a228769ec69b85f69f8a525e90a7f9b94aeb73d7834b2cf0f84fcc801078361d228138ac043d59e54c240c269d16584950f60a08ff46ccbb1b128cce20305d8a334d2a4a65b3e6d6e646a90c0d4c4abd7f5516f0c0f5fbd7caf1435063799d972904554fff0f5c7aa9ea8127fae8be4b3c112bd8a34ffb2547310d00466f706e10f1cc4b050260d320d1bda3f8124149a0a96243261a6cf78196aab0f7b08b536c16eb65ae7c7f97ada7c938aedd41a0d52b06224b348f505606e53179a1dd9bc540fecff4032f7d7102ec0fe345bcd7229611654587ed28f09bbb5dc032aa1526347af6eae3d9aeac9835213132ea3e3e71b86100aab66b817c7cf7b921560b354514aab3ebed138d8180fc004557a97be9015ac00ed49c3437f9019daef2e95cdc99133519b845ddaec5a02cc0d6e994ad5b33d50d393f0fe505808140852e8a6af9ebfd1db2d8f074ad29180305f87083f9e3fb77ededa663ae9531ce44074bea3e3bdf23d635a0102a5df6415caf4e1d780e3f2f2c0c1ff3494a1102458aa9c58979b554c3a71471f4d0d80c408468633d02c7f645716aa5d1959f1aaa51fbd377584f0daa34f2c6415bae4c2ed42a748b78f5ebc08a905a8a6ea5d1d7d791f236dd456cf52c8d30bd136435afa94df4689094ba1663622d6f737c1ac5202b315143175a7b26ba1dcdbb276246d10659255848206d10a3d87664fb557821a1515b368efe5b2263500d8895464677d7864e4d51b0d3a26821d214f94fb027aad69b1b35159600de727f7846f7a2ff3993d9386b56fa38a8cda76d909d45686216d8535e544bb8d3e6e9597d12ea42db5481b8b925e322359f1717dd83a2d6cebe47a94ad52e3ad9d322c69487e8b444020eb8f3a96e1daddef17b5ae478711141b3120c994371518ac72f9dd302e1395c5ee75b641eb05ec81b84e74d0829c202616050fe320d6f31d53b0fc9969912cc9c205a17fbb0c502e1245f91bfa91d0b0a1b0b042a2049240c6f0356f88fdf56efd83f4b32155d66943f92a8f5d1383a159f3ee1482232f1da96e83c77deec7e7947fa771f9596029c118dde3f9f76b3fe12ff52c5adca917cd59a9b95577e3e132750644803baa609ed0cc25122a20c14531d5cae26ff8c9c0b2a0772401563d5218725924e8b27a081814dc80bbc88a414d2546cd768fc937e857224e3b7d00fb22d82c788bd8998b8f79877c225ee130bcd6fd231fe95bdb48c883332a4284ae83483b2f83299de1780da1abcf41c8884d21667371b046eb4e98109b23eaf2715fbc2d206ff444fa664609340c28131627d622484d4f2824d9eb0534f63706043f1f03f66969121c524c269ee5c3f1970a86f61cec1e69d561c6add3182a252d333924c06ed692e22988e9adc9253e19f8ccc2ac2416c1f0fc947435083d20bb44f3572388405a1335403245a03249bf73b5419100278f563b92674a81462ee0251e942f60671bcf733733064733606070cd9b69ce6f35b785c480c341841251c33e2379a75c6e4fda1d91964c53fb1a1b68bddccee1f266e2c5394385d9c4baf082a281d304863410c3ef16cdcd45f20a6479df3f1bac6024e42a10316e1e58f14fdf56c274fb99fc20f0c1129d9a8670534cb271cadfc0fef4a7ee4eb1fe46e50ff4730050d689249336a46572156d09922a23b5fc30d2f1469d9dd9d33080455665b330d9a9f71bc7a7eb21bb191aa3f3eefd0537754dcde2d0ec4a33fdc75cbefedac2190d502db251bdcdc9b73dcbf9e76a54fe4cbfb707691c92bb2681fd5ef0c22899335eff3d41b0c0463f25dbd0faadfc31258de222b7d70570bc73bf828aee036cb2ac783ad29076daeabfe694ae8812aaa522db506ce3da6debb5b78ddcf357cb72ac488b47b517edb7acc80f8cce616d4c4c25b125e6a21ee741d2ade25fe7837e475a32669b30400c560c3f0cc412a78052f5f82d1d1eb1bdf5eda234ab55f26c7ec586f93c95154039e4eb248f0d8e3b72e1cf5ba208d01a4305c929d8b6b420a9a64542a39442cbb2990856e9e8b61669bf196eb528f9cb8ceb1a7d17021dd34eb15b9541e290609c44e436b99faa512b6cf606f6225e6ffab94db941818f03106f200d426ded1512a1d6b8d814337e8c636ed341e813e5507de6fb8e7508c9e2f8290de405734b3af784298853d9b07cbf098f32f153c70db2a14464c4854aadc45641c744f322d0a4d02bf608d7469fc88e0585acd1b3691f2887cc02840f8217016e9cc87bc205c113a689cbc641b8ce797c32153de0ec7ad75a0e89f251fbd415fcebf7e88a39166ed834e141c34dc861e06c3447484f8f51fbe67cf46a80a6e73a4301504aa7872ab32139d9536a9c1f8e0c584121b2e200f30ea6739813f008904035976f26bbad8af4e090258cdc7aefdf712b207ad71de30c07d127bdc8dd9cf713ef009834628a1c57d510209122f0e2f41199e01a6543e58d6416e8c49f768ffe8223ec834de81bfab71db97c01922025bcb7e1cd3fea60e752d25b4879cbbbe5a6dfa00e32adbc043da5c62a6c1e810f7072d7b42877a81e354b6b4bf13e65ecc804e507b41eacfce632feab55774216b9bdd40445eaf151c457a924e5449daa02640dcff2699c13bf9a96901c0c84c82e1224976475619999179a253f823a06ca6b8fe11f9445d4c995a7e82bede49db3422cbe2bf9c7e81154f07767b193a41908f079432d409f8ccfc964a49d9fda188de07244aa9627807332a6b99bce9e95f700553fbabb053a09f11ab3c1d073c6ae4f4b2da197e6a1754d0381bd9a5d4d4fe45b3d555d4012089aeb442fcf05b978c65f8aeddc6d82a879cc2cd24a7d5aa45742f635be976874fcfb62aa4ede08b7a27b75a3b1768bca69e8fcb1683fb083e069a48e369840199025b737408d365c45645e40f6bf8a3f39d09c758743ba5dc4916431758d7b468d451686402d9a81a6a602c18911732069ab8b2f22d0988bf0ba9a33f728cf3112abff76aea06e2ec4b744bed12d1e50b099583c89aa5941c38c4203a54ff10903cec4f18aa84884402f82cdb473283f91bc5e60f7bd319db11ffc74c4bd3e31b6149be4d12309420e967814f4fb3f5daab019a58ecf89244bbdc20b131c2468e7dfa2a33f7436eff65a8ca751bd3dad736ff04ad0e9fd8ca6dcce3d46c9ac185d7cf8cfb397c4888f043f2cc48260a190bf1e5a6d75ecf5b3f5a31e5b67a34fde1297a8ea7a3a9644d79b98ba856e2d9a9f3e9f62a1f144b022f995242a243cea676e0c1e20553c7af32bc847d0a4376811d688a8effd19f15deef6473dad972884460fab3a1454f4bc82305e80261fb92752baf4971dd19b49de6082e32602183902ad2975d63885a2a40010114a8c999fcc934724e7ec68117872c18c60e60d9e3a15911537a47b5520ea6a1915d0f2b73583ec805bbff55a38422c85d2c1f70951cb793b76412a8390f1478c98e24ee1861bbe9a48907143972a0a85f48e6ce0bb729f4647429869ff33003f649638e700988613419a95e5f48f4e553e8b811e79001c0bbc73c2d291beef22c48a3ba271c604d55a5874fc1b98ebc42f029c04f3d6b6a7223bd2a50bcbb470c6c7541f50c69de850413ba77a7fcd6cf539371277d38b4ef6374aac44e46658e3aca566394ff7e2733e6b6656cb025b71bd694d236a0516e7b3dc12dcde00696df3eca092fbbe3123b9747c93eb179d925bf536ae37c009f6e021281fb2303a168d2115686ee366004201ed70e2405af6d00ee2b0c1065118684297e24119130ae6df79671a71e5e101264114c407e157f3a7e30bfe2a89b4ae619ca3e10de20c843316111df289d508400d1d550fcaf2501da33bb43adce25c7154c4a843c582c29b0dbb9a863c35a94651acb822edd59b1f8bd09ed5778880374cf56999150e204ad46f7f4ee903d6f548dbe00177afbaacb8255664bfcf4c9d12148bbe14fd65070bfde24b1f1434facc9fae1593faccf316e5d3f75693fe51620a249db1f6e191ef0eef924980e94fecbc6a32f9f66f3cf510d66d8b0e531876799eda5d40eca97e9858e2637d258805de1e43b69f0ada8d46a29eccf0da07e517624705d085cc35da3a92d6d489d04af97e2d748793a19fead36dc40124763b8469520b36e9c6d8fd9186d24e6acc52bb791c25e8be971989ba84408437b0a2f0577fd27ecfdb38af4e67f9144e27e6f9aff7f9e282f0b5188014976934a655a1e2307b2edc3d81e74a8fcfe617279e6bb0a3e8526856270efbf2a781b0dd96e3a1d471bc4519c60109e5d216250dbf9905e7537eaf9acf8f71afa86535e08e511179f3ba0024e2305921d855d9295dd3df55ea384f678a55da3779a00d31d262434f2f4b682a33d0c319472dbf56e9abebfedcffb06233e689f9d0f014f0e885bb767a2b8536fb5d85a92b924e01c2cfca852212bd0bddb1ae3528b3c4175a02c590e484bbc8467e500cf6051a0bcbb315f0902cca3f4942a33e2a026a522234fbe3ca064d539d617da5ff1f1a59f15ea18a386159ea1d4668c93d58f45a4185b57ac191adea4ccd4f4378516276c84ecc59395461e0b740e6fb4325384a04a50f48fcd15dd1f69e0244851dba66db4120e14a3b3089281b13433f57abe60137e0c9fc6c52043f9bd76b90086aeb4dbe7b850b750b6bb53ba8e1e71a052b7f08da5b816b91d9122a9abbf2da561d5f3e6209f26915f60c1190af367478b2fe33735775bace397878f302c3742ace2dcee927901cb09d1123cb7372f419ba7970809ea25c6979607d37d402e64485843c47cbf5c952185f33be943d0701a9d7a0a1b3a665bf9570d3d4c7d372f5bc9443714dec33ecc847a1da94dd54bfb9ca4be2c1f195122d0cc042de68739e9fcfe2d045770800829006da2e1041b09f8fb11f577f10297a6bf55584f48dc777ce34a415d1d01f0e264499a0880634f5b1aee639208017038c4765b6a0da523c217d4a6b3bc59fb99818dc5d73f576583fe6fd6300af76371115c07fe007808732198eab5e66190cfcebb22340e64d1bcb555bb2ad0305a2e6f97535d1b7bc2149895044d2332714a09289a698849876ef651b181bd3a42b7b20c7a4c72fb65a8b933458822c85b141234d1f591489a4a7ab9e3c0b4312257ac29eec498ced58894ed8b4e11fabfd5339dfd9e952de5e7de42234654438f3a2830ae8a3029db266f50420b654a228e1c4bbf38fe863bc6d98402760eda3f949441387086947b15b05aecd7a24c33bf2d24e57e5db58bf89c1820ba54cd73919c28fa28246ce977178f818903f31c585e8490f09c483fcb962dd9c4c7203472f7664b1e6892e3b12b7ee06cc9bb18e0b53ad2ece96bbb9eab356cb3dfcf8ac35aed3b0dad5ade14a34c80c53218ccffb769bae236dd8d1199c7ec7511a493615f3e6b4d68f9aea112b5f97e437714dc555f03b084070c744a9b8316e3f2c1d5615de61a7f219559cc7fe17d58206ed80ea9b57340be35960c2c50b25d6ac1c35f579fb2b506c91a8acf130b7db23626b4c2a3ef959e7d691d5c9eba7de5ba65bf4f0cac19165365ea57e921e6ac30fb1fa381667f2d526a38667cdc94155b1f994fdc6662b2a4f3e11b1a4a4e256e819e3afa069824df70a003e161ea426e868b7f49fff155ef02531b13d39907bc000dbc72806374a8ee4e6838baeb39f4aeab34645e838cbef0189c5f97c6f68305b59f2dc7f4e126141ee36b9eee6da581df7a7f840b92b9c171c6e11747f8f2ec31799debd884c75856865c5ef7f75cfd9eb31ec7af0df66a1857eaea47f80973c025c4e456a0845bb004e87370bd76dc530b8de7dd85c862bccd7e730aa94ee87f5c825e93faf2b1d9a4e1dda35079a6b6a763748735cfa19057d94b664c46438d3c5899520d9c6d3e17734840724376ec7809e4270fe686803ea53b143789f9f21fe6aada26aaa3e136c23167a7027a04a9daafc6e7b62a1b07d2bc08d12781e5f83f6cda491f5aa31c23dba13f6273a97b6f780955dcc43d8dc6d23279c337d3562bd250d61b168969b1ecd1f2f90add949a96345c541bcdf1ed967a3b381dcbdfbc336d8dd35f14aed206300f5eb50e65be2a77c1c38b791e6e0839452ba0805231b5df19166df0b99e2e5f8ed5857429e433864ddb549f1725e9110ab1e0737a62ab476d153bf3174d3d2505f1567d2b5b0ea20dfa332893dec5881655ebe236b199de5ab4f412f92d192b0e352a4c211b0f23c2a17a8300c947fb2404fd65db5fd68173b43c99077bfe45bed7c7736b3943017a314369fe560322ec9210c1ee710fb3f8bc597b6819a64858b49f503174eb37065ee96a684ab58dcb7ce4562c80d2c20c78ec256431fa245c30981911ffeb78d659312172e73d17f4397c0a83167f1ee526cd5d12d2d48ffde9d94803956597a386eac8d66c4389797f7f93c53f5d9f4c7c71dc2693aba15d5b95d0ad4816e4304f1c6439b59cadca720fa365ca897bd73a4e133653d93332a110ca1d68b58dc98d26561b362c11dbcec605de270e6889f95b4efa159b8b1edf8982c2661eb11c77a2d1a0380a85fe761d053c8a894028374fe60094cd18a869d87f9903b81824596ef0f920871bb9e1a60c7ee860beb741a1d36b189dadc644bd0a0f95cde7c45e51023580f81e4245cbfc28b23968da0937696ba007e8cf7e404173e6882d027af461ce72092301dc90e71123dc5c70d24299de0cf7b26d3b38a36c6adf0a165f0653bea90f8ceb27e02a43cd541ca43371cf6308bc1b9d8bcc0b2f7889aabeaf138a610a6833a8245fdffdd656418d0327f5c322a3425b6a5c2e1fe1a8189e90e3f02ebf9a77f348b03a6235eef5443e8942df8d3f63ea33afc37d2784167613abea4fb1465e8aaab51f71c51d35cd726a5d5117784c314695aebccf967bd185747154ce9557b457969f490deca1a805117365c47f75a3e4cab87bd1b00064ce7c2d975f9768a545bf77691152c4aa4bb6bfee0eddd98e790d7ba913738e99726cf2f09b8495e3531cded6d96d5119f5da971579f4dda5102c27e563d174d0f12a098139f7c469a135f4b790f350c4036fb67e6224cdcccfb2e9ff1a41f939cc68dc4c0b24070c92a7b8c42a2ab216107c94e621a2c74d3059e3409403ca2c737acbb0d29fefc69c9ff99e06a12ad9888928e4a2a353855d4e171f0b3816973812edbc6f7cceb6ec2a63628dcb2409d5fc385c40e9e01dd1ba6b10935222e416665957baa754260ded401f2c0e11b69cd174799a2c5090358413fdc14ddc0bac60219001fa97322f5b1bbad5a7e1caa8220fec2b222bcf1aefd143e52ed8b353152322891fd153c8d8b6bc8d7e45e49dc89f0df7de23110fcd8b99b28f4edd1497b5d679c769f0fa8bd3b8cb92a035d6788d1dc8ff7f72454812fa6219192a4818b7420e2361e0caf4493aa2bc1b751847d818a08e3f59b29940cbba99a4e6fce60252c70bed88724dee30da6ebd9c4795076d17fc94e8f61a62d300867ef4a76cfe433c1087e66a4a1bbb81d1ad209b579c442db285c11a1e89c66604012f0f6e7e142b5942a5b40909b38805d1b3c762327012a89444cfd78000201753625c86f108f5d180218827ccc1e6bdd402fa96e80a32bfb2b720b85ddb168384d38b36bdb31044fc9119dda0482bf2a575878d8989e3f4a1dc93b693c754cc5b27e065bdca5deb7c254f83b21fcbe680f0e817bd9a800c7c150603f59acbf7aa5c76a3c7f0053cc7889868dc4aa5d54fa216067671fefc11fa04511ab513d65f2db00605248b974250806022f163d1e3bf385a80ed5d2c60a8f2814662a1300adf85ca39dfbba1771ab2b3e534fee7e51129b90cf92fce697219cb7e20a06371a09d1f64e21f54c2537a3c5a0f3ed5398429db3d1591f8c7a66a4a2502bf4d0702a24db41e9df2deeda38fc0101d5eb3654f75c474afab54e8296b60087598967c1bb8a0db4056163b4403ce6dfb68e721f6db933e606d9effba251e7d056513117031906aa79307857c029ccd87c719b32a80afe7c8e2ecf5e2f60a729f28e230cd75a377a641bacbc2221f397c9fb62b9632806e7e33db7a5e5e3ef7d96ba2b3980dca335ff4a50cf36b51c8c90ab8208ae8359d18a71e7bb190ea7fb40594252ffc1c2b1d6b86840725eeaef5da16ec0cc337888ec628e9bf8f1f5c5b381bf2a267c11bf6c634f1be8115b8d6be52ca1618e5906942fbb6a682e4171d849af3c973d414a26ea3d87c23999bb80619bed6c4d5a2906b80fbe8a41af1127b2034ca403e109b7453c73ab467fc7e472f2f6aed293c96f3f1b32fd713b298e060781d8b564541be9c5c79d1475835006174b448490bd65fd0fb1ae60d0ae4633d5cd17a4d0d44d5492394478b9bc9c9650cf4698cf795f64fd40f035d1b72d30762f245c1c8be85f76981758001a1b160a56a812d5df257a297b7e12d084440a8f111bdfbd081a1e320a2e3f0a9f099d032304f77f58d13991b8c6b8ff822977b20c66910606412b7c5d5e8978b2d5b75f7295524db7679b4331c5827f0f81692cb710e20c7f3e20e754b34118defe53fbea9c3a0a65134387bf3cc9810a6ac7b3b3b15f1c8e88e1d068cbcba076324d732c9f6ecfdedf19214f41f85a78039f63da2447e1a9e35a0d8cbd2819cb6ac6b46ad11fe87aeb2641e9814386dde74ee5667180c26371843b569c1103c13b119397a269318f1502761a5ae0c3fc89299a914d3faae9fc95c38e1a5b7ce9083a4fa5bffb963b2770b900e90d587096a9d33981b179291c9af15036b1f9d385c6c85980cf9580c7b898534d88c16ecf5ea245ca0587959c2fc791376a38abb575a8b9b05cc155ce4572d474d35e323942ed289403210f45396309878a57b54065877f3aaa59758924373b47ee929b0830ab75c6fd1fd855e3a4321afbce4b84d15e2f71f01ec0c1610b53b7b3460988a6d9534da8c385188d57c88973db4d5eb8e2007b00f53ca35ecf0ad19cf7bdad3b2aa68cd03fe58737a6cfd2c8b370a70e9d4b433953ad1040def61a9caf1367f02698c694b840df28e078a0a4f581886121f860fbef28995036edc9e4b9cb8ea3f83811f9c8ec5a28252cb80d7e3cced9c82389e410c36002ecf25842cc523a58f7d046c2092c63006d8205537e3aeda22ecf2f4c479226cadd47aadd4985ebcc11e1129845d53fa3023800b358ce38257275ab3c8095ad61f6aefd20ce441560804247c8a7d73591cb1412b22952a29bd18485a0058b9742f6feccfb86de074f1d19f498a16b65ed6cba8210787ca0b3a9201cf8de5541bd599a62d519a33c32c0f7fbf329578322c6ecbde3b92d1be8241e2146d691d29e970832189746f968ac3bd79ce43a5c5558b3a42a743f3127a329c90389fcfc22d60777210f3ab6be73ef8cdfc5ee4b8a90f026b4d2b462446ab5dcf9aa05e37f1e24b47aecb77b63541228f78115283a615d40c8ac4a9d51dcfb567945cb12bd9ce47d1a0e05781d9d351ce863065d12f7096ba11d5133a0f119f930d5f15ed14fbc152a24f5e9b10ec10a1165e3b747c7ff5de5c21603d24676c3f9ffed4048ebd002e5f5427f5e40912f5799587348ca28512a2e4ab012dc66d7ab9221a55a8aa12c977ede77e96f7c0a01aa21c0c9c937e13d8e4466adccc35b4525ff01ac17669a98e31cecf9df6bc825b68b86a27c922104f28c0cbf1a6fd312577ba7f27aa1e1ed80621cfae46ec385706a295bde402cdcb8c0c6247b6f81b1d4cf222908218cf8fa275b4ce29dce03e956052bd1b3a4ae1061095015079d2fbb5c8cbc3be96041e4b60a5a019c8d71a2402301e86d0f5c67190bbd013ea90d94dc4e297211be06015864ba75001be8cfbe78bdc2f73a12279798fd56f9ee918e2f3e65b8cf84208160cd3c113446f2a6894c5136dc033353e9a87b38fd160392cf724a5b591ce8818824415d6bc50b40643d2f61541ecdff9e62e46085683614d9849c3aa6b02ead05f8b7c001b409d1da3ca7954f1acb8281bf3f53f62e7e2ea324247941a97063a2588578ede81f46ce3f59e7e44ce42ee6dad846c8216d000ba5c0a711828bad9fd60ed399fd703c8e9f2f1cf7380807fa462187080b71658cd17c653b152c22cc1bda870e98d68996194894d0867fc7f57a9abcd496cd36b19fe0dd1c54300a55d5451d5b67ea969735de4fd6fc3f06ad07a307ece0074b0d80bcbfafb30a8656a9965ab4c2d8f911430b11472ee5ef1b3a2c053e48db3e82f1d4139aff10d56d5a8d46de6f3e960a806d7202375a272ee99114935c15bbf286a875a28eff62b3f3bec83b765d03e5c8d01eaf1853a380226b842dd18c453ee0720c9a70b1b53a681200b232bea0d2d4db5a1ffe3c65ab15200c8d6bd963422bca72f4541397575b8d61c291b2e4ea95c3784e75c663ecbc073720efd1e8556112c3a9ab2871c408d1df32ed653cd58411034800b897666ab7dc16846defaa9026eae1811785025a33f9d3b33b6b0181335194a82b99a6bc4dfbe0fa3bc6788df9cf8e9c7d1f8098d14c5f365ce355561bb4e0820aa3cd2d786cc44688d226a715456ddbf4e483a555b1683af231b32662d7a1061ad6ef1bd4a8e9024522d9534eb88ae5863afc33461eb6f0696a74762e4b8fb742536ea0a1e01d1ebdf94165c2547d8342d67bd8ca87191f7f071ea412153557fbf0580a723b420121e101b24cedfe97b6d897b9be8de8779c482538a8f4cb047b5fcca13aff715880e1211e7119d2457d3484440eaf0830b6f845363f5e63fe4abd50b301bd0bf746eec90ea03a36ae540b6cc5c125732c9b7daa7878a72ffb84113aa157cae408c9e9928600db33d91108e465e146488c95636715048b86a9155a5dc4328a990c6cadd4d01bd30427de3b4deaf3ae5f659689b5240209b61523210d0576b4362804a554ba98c9f31b39bdc19e56e8cf1611006df99f7edc9ca8e94c54c40e235710a42bc200249d377c3b183f596c60fc03ddbdae6bb4af1480eae36c59c0d11b3d6e5a8e5ae7506ccbb7f884eb6b1e72d84f9695e96d5b481a5d9a4991ea5976db9a926527121e96ad9afd23210350286a5b32cecb68870ff1b9d56a2acf6d8a71c610234ffae297d84125b182a4809f7c6ca9b00821d46ec0a2d6a59a1a805b9aaf57b72544f40d54cfaf36ab7d55d295bef11044015d675abcb831a4046d00d29e109405c01527528f0f5bc821b0722875e8664976d7deaee2ba2b58d6b70f8320895593a5673944e3fbd7e4040b5811df184e069928ff23e309d149381e5b25440902429a8ce5ea394eec643549fc0512a8477ba48df6d564af9ada1fea8155507ce1e45d30be966853cc2b0806c5a76ec92d7e710ba1c0b9f855a59cc094699788e2a747a0971d2ed9a321fc63a22ff5dd6c29bbe21901344665628c55001f998806dab99d9efa692bdd340de9e19c814f4577ae7745bf441344d92320a4dcf8494061470d25e1e26612336677018e4e439c870022214ab11d9e71a9b1491ac1d0b376f0e30218c7e48d497af6c62cf4e7722e56030c11d26b1ca51434e4fe8003cba95407ce1c6438a6b2c99cd33bfde34b2682b3d4c2f8e60dd11e6881b8414182ec2bc9bbd06e579158f0ffcafef3610ecf0d59d4ada78161b2d5fc99548d3a236436b2e38d47f21fe34dd9d240ac85a9ec54d1c4890ced77124d27ae3555cf47cd5dfb1f0a4b83984cfe51d53a56f2a6210620ac6f9c9923950f70bc4c5738d2e4e9767a37a91714d969ad66b7bcf52c9012f15dc602ca95798c59159cba69cd29b6a4232cabeafc8c87be24dd1f02842204cc1332b8afa3f9e09e6cd160704e1ca7d1332b890a2151a94387b675564c52bf662bd6119952be8150c8c4a245ccb22e6db18a05fa121b2b577a94c71b08d7d021a5e64d54438cefc5d2ac4867c10868d68d6d0a4cb48a43084a06f19fdcde7472a84d23abe8bcdd37980eeba6b9ec6a356949159187d4b2b9d8a874312b3b9983514787b102add531e6a640e8b8fd240484b80f3d1ccc95b649b6c2750f4a6397d33c59367685e5cd2530310aa9bbec18ecab748f7545c5ed8c746b34b0102780954347e5650c6c1bfc23e66d7d9f438c32d4903e8326b927d26088b1317c2e3c1aa6db9f1673bab5fd7fbc9d45425b9e413f24b886105edbd1d23ae511b45384614a5ee7710e7b784205456d861425a6382390a0f73fe10770c4f3cf23f8206b410e9639784e632d79fe439db98e46193784ff8ba338d434ced3382bbd790a85ea122dbb1dfc9d474a566b455f2be3fd6d2f9bc6d3d6432eb437accbb4db6dd83271f07828e0857b9fdc64eb88cdf2faccb7dc00be0a17353eb1b0bb6c0d7695e6037abdfca41b88004fd3ad06f7f07ee9c8a1b602c7d306d4e9cb8f75fbbc24c9da340f406ef9b1647524a88c356a14e78072535bcabca2006086b852c903032639bc6a285982625f0b36d3440798101c8d4c531be35db8e9311c43509c378999a52c6415d666c69ca58f6ad912ccf5d91a80a9dbd3c92988222965ae047f8982a412fa9f5aab07407419dd5d0d4fe961da0b013b9fd9f08eea991e4fca2edcca85d4f43bbdf6c3fdbd478cdc2e7f9f9f177569d536f94b7f36dcae2b9a7e59164259bb533f59cc22f97604e83cc41da5c4ec16e15cc6940177352f08fb5345e4da6ac2e2f695bbe694587aed814e117d3737154e07f59bbae3080afc2ff6beac6988862d3700b57b5bce295d8d46816cda8808c4855c1da25c99a205d0a9cc344b69165b1fa50c2d32803cffb399f0b0e94806dedc32864bf1b10178c014815f553a6be84a2953e57de36fbdd9989fec704ec9c0895c4472f90b501d35e95092af866019481205e60e4cddfb82880e5448b9afe51e9d2dd4099be398fb7fda61ddae8610542c683fb0d3750e97e37c055e629b47e4d4e1f268a5700f133d81aec8acd014280bada48a6371d198b3a5920a1b5b2b88ebdb9d4e0f1b972045c21d34e1b542a1923c0a2102d3321ecafee4494e0960c4d798602ae3af5ed1c681fb8e85d4a26fb8119acf774214e61517eabc537fbec3ddf5613264e5ea3f8413ba8d24f8482b94c0109c662e50f42da86da41a2ac34e38bb7991bd6b0038180802e4f9b709feab5b9c444d09473d458e5ac30a6f9bb0cc4b00c24d32f79910ab8e9b36826b73102aa83a331f7d1c0ca8433602ebf935c217dfd29aca8f8e9ef1e3e9f5acf9bc7fa003cb1fe4548b54ace0a4b619b2c3f207c7428ab1803ca56613098d859c885a93dbb01d7a222607e27e71a15a34a7d1d1efe0655b818f044ddd4ec4c91ab49ab18d58a7970021f0c92e99c3a95705a797a99a8b536baa6f6d31d2a74c4c3db08217a00bf8026555a6f869285d79d8a7f8db9a67db608dc994a3d21e07bb7b333c2f423a5b31471a39506bc823b6310441d9f6448c9c7c8aae1bc391fff94419da3e5a6b4c5edd87df9c3fa25b8d4a7da86c44c2406099bbe6e80789c942450d325a5c147f1961ca74b7e688be7ff322616cf4706a9149c9fa114dc80d704df620c8a9b4ce483085fdf63d3154c533b645729c3783c6f4a95537a230c492068e61091298b3cc70e90431e26b516ac8ae634910e1c17f9ee734165f88f366a0552890a246f7abefbbe6438d93b8896be71db18e964ae0f49e9adfbc1e1b987f212148ee5e2ea746909d8f857a17580237b41957ddb2c0036b0db4741cebe30e42b5983f4ffb452ffa9797b00d55fd33f52b3100a274c909c30c60c0907a2ae864b145ca41031eed91fe779141baf7d871b6bf351d82c415f00c7c848f937b98eef20768782670cc962bc4f51bea2c23e3539c6377464acd12eeb6ebbc623713a3b4a22cdaf4c312dc9b3c90d4c1603d54f738e6f889b445d8001709ab1db64c24f057a4350e9de7772d559638ce3456a3852f8bd5f94d6cef422c1f2c40c6892cddff12edbd983d4475fa59bae4dc9b9b1ab9d6b6c3fed4046559700c194b81bd7ddfbb16e7ca2b620a2541c1a7e946a6b6c86036862804e4596db4e4fa6619def02764163512278680fbf40bd6f44485f771cac100d379773d58d2a4d2f21f2eafbd306f26ad52ef2a8abc0ba39fbb9b985f4d9415ce937181466a0a24070956e562bb9d00549fff52aeaa4f4c6cab434d017588775cd0737b551d7b7979ee32c12361a7512a60083907a5e6b97f061a2920a210a89b35750fcbe355fd58d7211e986633101849b9ebf53912cab3d50a61069fd3f58aa08d9f9c5ed69e3ba31563316d25d7ee6c62b7b629cd0fcac976e9bb0dcef4f69eda5992f81ecc1d90af0b5189bb99072377c2239560b8a9df3ac9f9b36f86fd2dc9e7c7b2f2ba82b671d29f11f15777b30544fadb41b1620f2787975a02f0e64d208d2bd3f9e54a00dcff19ba6fd77963227c654c7e358042a7ab72c24c1db6842ab300091f3cd7b37611b94d732b2bca6703fa096d23540b5b1a80f80cf3a2af3b8530e85e388093464a98c3e30fccd48a5fec468d683dea74504f645446f0ce029575e879d855acc68cba782af074fd4ea41169c71cc488d861d31ff20918374900346222eb083da3251ba1ae7cac6d26ca1fdb3d0ad3595f4acb0679855f6535f8d0d954e898eaed73f65b62367857daa729c5d315f223cc7502bc90fd1ef70f73df55cdc04875b5f8e387f2c1efa73f090e4320f31d8fb62833c5a052b2405ae5886314b98d6330309c621862634a6879816a73d67302b6a1a57f10c2f3e627b5f1790dc3f8b9f4025aeb03fdc30744dfdc8c979985b3a6096abd32cde191087125e03b9878f431e0be8e353a1804bbeebaa6723c9832fd53ae5ae10cecf0356a1c8d0ab70e720a280e69bbdfae01b3c7cea347ae04cafbac9e9b3cd707c8c099db3526c06803063b427eb46e4116df13d33c5e5b7df524dd1cc5bba20036f02bae5968a1d00223444030a4c06795c308c4a4e07ebde33e77b6cb6e745b30d681b967e9329debee0e531201ed67bba102646712e7e606ab87e4441a758046cea5487196e5741601cfe3abe995ee48e7f0323a400aabed1d0da27f5fa5fe013c84b437bef2de5de524a99648107790758079c16a78b2a85b0f3c8e5cf38ca2f7f06da5b083b77dbb87da305b88dcbc8a8ac0a5917f7e5df3e201db41657dbebffbe22a128d15db509dd44af71dfe2083df76a5b6de30664e7f56bedb5cd3dfe4dd4e2aa4389a8d7dfbdd6bf3312d14f645656b9fdff1117f7ab1cb0a4b24e54517295d359c1c5aa11f7b54bfdc27dad155685dcc57d0ed8c9ca70dffda4a437e6ef5125395ddf5330ff97c7215403221ceead444037f7f641b8f17762a9f735da9bce155815a2cfbd0c532028a80c51c392132f5078808b65220e15158cac0eb54aeb1b870c93710a0e51462459776b3dccca00be6bb50fde71eeaa268a289568ca2043e9044c7630aa72c3ab7a400a6a0b0bb3872311966a40410a3166ec127084c8709ac4c0e9616b72ffde264b708a6e1370cf599631683a24db15b20fa626094e042e2099b1d6daad5a6badb5731583765d7d5a6badfbd0a696035f83b6f427cec974f1fbad368b4319e816ad2fede27764cb0798810e43ab83e723c4ee2da7d4bed16f92506a69a594d25aeba6744b736da873debb8f6cee63d4086142d209a6086302154bdb96ac80e3c25695d4eee33d6729a4a0046f06b950a7547fc8fa4cb3b9c0dee5d68bb6e2eec6070469427f34a7fc6e361d757e90afd91e382be34a0a5338144ba8084848418924610ab25d6a319ef7939294d2df58bb8f783badd537a5d4d234de0c0ab95615f10cb5487e145a47657150b9f8a8ac2898fc69d3a10a0524f404184e609182e504242758151698105984329e0866a0c061db4184378345c90e3fc867cfd995dad67bceaed076f9addbe4cd2077771daba78d49c5785f46e57cb9daa8ffc97914ea518f42bda638b647a13e9c17d8478d2c3aa0bbf2c7fb9cf113cb0af6b8f77239f851a811bf833be8bfcec9f970dac8c911eb8362f7d543594a5a1232c7b536c77dfe8d02ad9cb9f74422211cc0078feda3e7a1bca172d2bcd74151169871460fbcf780fbcd1bcb567671bb973a3cfe39cf23aa763e14e83df765ab14c29c88f23c07776c5fb6bccf62d9da1985aae1799e8ee7fdac42a9f7428a73c0ef537af4b1cccfe5926c096d9abbce3fbbe7ef44cf9efd3f686d6fed2ebb73b873efbed6aecb9ca69e145df7572cf5f61e7ff77df5ca233beba0ddb443ecee9ede21768805a1fe160b945f1ed9de885fecaed3e9c65201a58f7d7f47cc93e59f12bd8ca78dd6f6cfdb7bd4c7b2b5bbf7442c96be87f6edf0f85d52dcf7eaec1bdebf5fe78bed63a980dd3d1ecb17bb0c3bdf41b737e269c3bfe5e9d04a74d93a7bceb064b1f9f1db2be2cf6287e9d74477ffc1d0eebec478d30f81288e0f8676ee511ed95dfe8ea81b4bdf2b6f042102dc1fd9734f8ae37ee7fd043b2f7fedf2571022b0d2c037f7aded818fdfc6dbe650acc59b41d7ea11989a78282929d19413b4ee50a95695c4de9d1aee96f2b2713470b809e71d1472973aa1f376da789f0a4a8de15ad55dea91ecd35a6bad8558d1a5cea1b5d69a47cd51a291e8d1aed11aad512154d786425dd34f18292d618b794c25944e3da1b98d1b794c24362567d2e1b123839214159817dcafafb5d6dcf64c2237ea0a88d8b4b6422f09b1bf94a209d5e05dc0021e67d3771e4f56a1eef36fba89498f2e94e8efc1e71e7feec6559d5f470ede1357f37356b31b577304d2fd4804cc1c8178d77bfcf9c16f9c235e79231ea70e71c5adca32a2f46ef14e4812d3d528436b0d7df1f07ff93fd1878e203527a774070999a6e1121065f99626d910c9a3d5c444294d559175a94ee5a42555268fd28406793c86643e688e011d7f4c0bea73a38e334c581d4ce872d264474d827ca1d168349a75ef8046a3d160f8da2062f48deb94db6a8e011d7fbc0478db797344db82bfd0b8cd5ad5082dcaf2a12f5e130a4aa275afa3e6ea893e74705059ee44e3acdd39a20c1502a29ee45bba7c411ae2369ad39ce65b10ee3dc80c528530a69c2b15d3e5c442640d12547a6cca7854a19a0f893e5e95cea882873a1fb0d3940db496506daacb4d95b99baacac6a9d1e5d090fa55001d0cd19a001c03cbd1cd2fde412229cbbfa85abaf9cd2938960e0d6dcc6d37af5cf0b056edd85a6bb5b539ebcf596da57a1363551fa86a65532b1b7777fbc6f278a0aa950ab55aadbb6d7776956c7a7baaa93d675962b14dc986440f499cc95e9c6c4f9b52957befbd4b565051955c41432ec10d97b3e72ccb122c66294e94ba74c512ccea50abb4ae5966594698a5304496a5166dbd211363062b495274dd73666506194cac1c69d174cf99953056b47c332b55665644d8df9eb32a5434616940228592cb4847820c461449153ac45c46e69922a6334ad018d1118aaa78b9280e3218417379db5745fa324a62e48a4384acc8e5e1af8a5e53f2a6e69a66a0bc70e49aa1612a7279de57c5a12e5d602eeffb2a1123b336c399970bcc2a83fbfef78f6c22463e22a4bc5c608c7c415489b9c05491087d45b1c2e4226284f322cb4d60ae490990f355b1e55290400a25971114938ba404407d55f41f8c2863e49a52e0f08393cbd349d1265f684c2e3752692da2d29f9545691554da747111f13756b481e332429b2081ebfaa82ce79264cb152e231e1043dbd048e4c2c0260531b88818018f704d4a00235b9926ae23faf572557105a4522a684f4cae3af2c0d92908168ea8d72cad793ffc0961387fb8ede2546a47ab5cf5f1f418d90955433c61cf900ff5f1ab52a97878787a7a7a7c7cc8300c7f7e7e58b0f0e6d461dcddddbda7c72728fcf9f1f171afeed5abbb7f2b5fcdfaf3e3eeeed5ddddab7b75afeeeeeeeeee5eddbdba7b75777777afeed5bdba577777afeed5bdba57f7ea5edd3f16fad361dc5bad5640aa162e5c00bd78f17a6f8aa238864463059ffbd00d5518a4220ad23060c4881123045285402a55a8dd9d060d1a34aead9486cf1f202090a885aa45a802c2d385d3161f510b17ef22c8d2f0c58b202272877beeeeeea5915dc7175f75afeed5ff5f14c571ac00dce1a001e80763c6a0313cc6ada0023003bb71108c1ad467850123460c13741d65c890419224eb63b166cca001127d90bf0d90c823d23a8cc78821838824594d44feac1b435313a9767cee2e43860c70877b24a88106f60542f0489205ee98f139050dc07aaf5e4a396c67ad7a33543342151d67801af82e8f78343e1d46d7a861e3d361b407000058f059e0b5565b1ed1416b7c356cd898b5d6fadd7bef68810ab444d7b1fc2cb0a0d50a400004f0b93b6500166f660e7fafa7503771b890677f8229b29543984f341fde5459f47ba2f0d74b6cc0e7a0748608c1ba298bfe8092f43bf0b40e4a27b5a3fa3014150f17180c96278b3a9329e44dee4293afd0e42838acc98f9a7a1e1084e6c3000e9aa8177ede6b308339f3260e03e283a99bacdc8180f766479f362e3562594c1e3e9f0f48843f04ba3836ae088802a9a031ac49112c870687866cfe0949f029d96afd7879ebfce416b4d431720702721890e7e2d36174e9b04d5f7c1fc5e10e03896aeac54e8a851a6db1c65edb1eea032a17a4d8710383f765091e304ca0dc69fbb73d136cefadf758079dc55830fbc2011833177c8863a685daaeb5ed3997466b6f81661b102bc10f3398d1326506850d67542d8011807d6dad6a5b6badfdbcf4b0b7b75b0b5af63685fdba98f12245972b33b60d2a427f1097372c8badb5d642e00a9b1fc8a0a04413319765b32d0d4cb605b7b5d65a1e2ab6657078c2d21d2c1026b3ade58264db143e0a13ac5b4f5b1888bb1ca7a5cc931f2d4c2b2d67aa84492cb4b489f93cfdac80e449cf9657b80294253c1a2835f9ac80258a2a4bad6705189cec24f18c8192d2f2a4224267470450b42a5401565973b6c2d3955814a31e578e909e662724151183cdb68c800ac7719c15d9374978928d9a8c683a0a941e28247179d223cbd1079cf4b0525466498f2ab42094f44821294d093db6182561420f2cb4190b5158e9b102d3cc032454e9a1a5287c41abc228ed527f8c1b748bb6ae93302a5d62c0f4cf9e332a60643ce99e3d6754ccb06054d4e87f2209a8c3708a538f2935fbafa9b899f23df941a414a51e5298286b4609fa1b018906f79cc59eecf2ff63574cc83ad4aab047512c07bde365c60934169344e33232aed0dc120d11f477264691d64acc2881b652b068d076cf59ec0d0d2ab11390446164333054d4b0e2031812642976d0b7948ef5edb5e38a7a083cfa57a4b4eead1ce9d7bab2550b92962d974b7ed15a90c8bea5f6eface307dfdefeaa7c071bceecb2b563fe1ded9ca356fd4e52b2cb9615cb1a45cf2abc2c6b183da8bf71c97fb9e0af2217d8afa8fbaa66289a7ab922dbbe46cbf1533ceaa840dba8af0dda69fb07e5f83a6b503a526ecf1e7c28da75fc1e47d125de5bbc567d774cb75b3b3e25e78341344d8ee20ff4898b34321ab52719ada98b15b4bb01dccb297b3bd60d1b59a35aa62a55d9b441ff0160740794a4a2149a8cae5f6270532af49e6002aecb7e1551dbc50aba3ed2a6235cd7e746d7b1ac62362d67354252b3983a2255a34b0be26a9a5fface1914a4edbbd47b622d82d1f769e6fe0eb97b08e5fe7e1db978701f73f17e13571b16b9747fc5cde954d11757746cdda0acfa198abea3f883067b80e01e95687f6a995021216be7914db4da7e22816117fefc9c08c32e0e7f16930cb9b8bbda461fdccf0d44bb70b9fd2a836e6fa305501b8b738a46b4bf6f969d214b0b33a8acb2cd3daed3fb184a5c6d5a4727f53535a6bec8ac20155d525965794f521cde7bdeac792c3fe86077bf4d173dd8368f8ea56ff781c49f925ee78d1d45a1b4fe3a16015344f54f3425b7c75f71fd0d2afd6a77c6983e904a47226030ad78abb58ea8ed270af5aa71857fe7552b20faf10864e755757b4fa5bf52fa459efa984c4ab45e478b7efd22740c2264d2666d7374e5fddc65def26800bab3d7a2c4609bfbec5b6d0aea8d1ae0711b29121f4850afc1efc421746fafc5557efdd3851257795cfda88ffa0df4d3478df48ba86812c87d8e48912829345ddcf66da8df60e77f679c95f58d1ba08ae8df54e26ad33c4f44f528a1e9caafebeac77dd42fc03ecfeba0358f3c63113dae7ed457fd4a35aeb6a7f4f5d3d7aa5f6d23eaf5afc447893b44c00051bd1e8910019380e94252040c109ed73e5f84877bfde1ab463faa2cee9fe7555ffa9112e1e845af373ea31efd6f8c3b5f448f2efbd28d94e019551c87f281a24828c93d4adc3eab258a46a2421388990a6b36f7f3a94c61082ecf8ccaecb27ed9dc6fff65af29c198ae3421e18c36f72ba751927beead134fec922e39b14b8a4604b235bba46b36d7c42e699bcd716d7e3a5192e3e85115a2322aa301ac292481356ad4a041b3b4942307498ae2cf8f8e4ecebb3651b2be57b10826b7a8b188116ac4930bcc7d9e31b210f5f55fe7f5a833fea847b2b2eadb2094bcf2c54214bc2ad3022bd22b94b4f6099daf104ab5a314d54a631b17c58a2e6952514c6f493c288eaac63e07f382fcf6194071786f3ffb0a98187c6fed27828077fe3eca1431d91215eab9625fe9cbb67eb4ad97d93607fc666390b66d6d4b8bbc310a25adee9cf407d3c6486563280ed302fb58a462a60dfb3489929ead688f8d3ea6d1db584e37442440c59a2362bf0405169c5ca8c713d079fb7a5ec0bd5d0179d44864b5414fd24b8f458cd027925ea8df19573bf8f572a5c6490980f5d7d4eb4f8d9f7ad4a7c62761db79c5b6938a6d8b448f4d1bd60a5dd2188d6d238dd531a6472221bc5e2e8d1a894840e9ebebe5d2634fd2ebf5727914ec803783c017a818b9ea1f71856f74fd20eb33463086852663a490418c511263f6449ec9e10972891c9a72600aeb9a5aaf67d4bd2426c98e729abb2426c9ae6e1a773767eec720d22fbe24263bbf2426c9eeba777edd2f8949aeb31f750ca85be0bac6fdf246d0b3f6c67dfe1af7c6102b070d1af7ea7b6fd4a8d1ba31c4dafe9406ae5af537b4bb6edbb75ddfdbdc1bf723508c8d7b8da449920b8a111463cb01b7a018338ef03c4a291d29c514079d94529fb5d66ae9acb5d64a29a553b4d6d25a6bad94529aad78d85acedacd5a6b6dadd6564c71688a81b51587b556bfd65a7b496b2dbec1db2e75ce568a73cf58abae14d56590a8d2c7b456d4fb9cf306aa06fd26a5d6526b29ad1445524aa9a6d4da9be7eb18dce1b8c3718763afbd1b9c6b3738ee70e824b79fdbfb06b67de72ab7d56b647b1b277beddde05cbbc1b1d7ed7577270be78b3783ca5a349d668a2f77b76ddb360e5f8e26f99005ee84dcc959f4e79eef50388efa255d12b2d0a95dbad3c59f76af7b3e750caee52cb89f1d03ee7a1b77fa28491fc438dbcf74733a42a716751aa24eee64371da12c74faeea7efbb7dcffc29fbbee918383939dd29a84a958b76d80ce99625f56b991b1a74dcd480044de726072414103ee47ce3061876fe9c6f78da59cc6c671c9eec8c030876fe560e5e86f4dc81e382366739ae862336670396cdd9a0c4e666376ca9810a8ebc51f30cf7c3be4928ec7b3f6c61df59d2153430792fc4c84c21d3b219b57e20cdae3448997de0f5b29d3d53c133d46070c0aa66681234c311a784b540481c60010509e90ad212dbb2b132c8b6d5019b5073c0a187292430d44ba749939cbfaf634cc0129a5031acf03169ca89e18b134f098cc106269d2a6452f4cd4ac830981743104b7009455d0c4d4eb825b21c83131dd8f2f8c304d92c8627273f9c182529e18712a6274b7e3429aa5204f362c20f136a33193eb0e4078c89862f84474d1586155186d8fa67519678c2e950ab42a638af598d8928706a90d2c40629566238d1a83d67525c8891468a0d240b5278505531d3ba33cfb7879a73ce7b875c107cd3af7f64eba074ee0952588ba3dbddb62be309adb3e70c863755681f353386d03c3ccc4881fe6ea061a4c13036c070820a309040bed1e0130d3ae584084767bc1cf900e648461e25bda0b4cb6f591454c7b9f33e300744695027b5a38259dae313feb05801b570e1e2c58b6305412f60c49041b266d0a86103002ffcf9eb59a4d37c727ad51cf6e44a5e3accab05ad00086000376edc20000ea19616d779a13e2f7f1d06bd5287404f7a2890e8e6b80e41206d732caaea8fe2708da4718a32a13f4a5677b7d65a6badb5d65a6bb3b515d7ca430577ef56ebc5b5561e2ab4bfb5d6da5ab3b5d65a8bc9b7d65e5aa9b5d65a7b456badb5d65a6b3d6bedb7b364684fafcb5e9775a8ebfa4368fffb41d0aef5a2eabdf782f7de7befe675f7d68c3bee5e226cadde7be79c2048543f08c869bdb7de5a6bad76c35d9e5d9e9823efbd97db26b74d8a290e71daa8b372b7dedfeebd3af587ca9c73cea04aaf7fd0aedb7b76ab7bb31f04590fdf6badddbe8fdb3008125dfbd9fba6cd41699dd40eea9b14476a47c5d393da51599e7b6f8f4f55f1f4f46c9e9d3d3fb5afcfadd5faf60189eefb7cb527fc6ab5f75a8b83c577efd517e8de163e55bc66399cbb0704614363f2e14ad5d6cefb7418c0c109b0b64934101f600eaa2a1929c551ca41699d8fc90829d0493d06a6902b391425264a2328cd5a5532528aa394da5165150f16cab55aad2664b2e867803a95f089762578c6d9743472a7692384c27b7cd8b051a9787eec1552850c096148085a488e1a9bb0874d0f143d60abd5f3c3a27ab9f3bacc429c17bc601ab88ac87fd808a9d56a405688650394f2daaa039ebbbb7b0577d8bb836ece49575d5544f6c694bd70baaefcd448b5f6de6de3a6e83ababbb5eeeeeeeebe7118679c73477d568cf3e79e73eebacef3be1a443be89c9808ccc9b19bee54965277cff33ecfc999f6fb9ca26a543b83b46a72dbe501411d46a374ddf56da523ce41a1505a6b9d21a21c3b7cdf0853a9d40e49546307dd2110dd2a1e90082889ae63a9bdd65a6badb5d65a6badb5d65a6bad7574f7fc5d1e8968c085abd6eed5bdbabb57f7eaaea3a3934aa5767676542a1511518f4f1895554e1e4a1d746010310407b90811471fde7f4e854dfa449f6a94299bc640a21ac3a2c1112f81c928c42177538de85315aa5b6a14c7a0569916d047a2f5cba68fc2941acb5386e90b3124697dfea49422a184e6508ae4068922d66ceab02f94525a4413344529a54eec1d4a2b0e4478e0043e74608511580e6cfaaaaeebba9f212165776fbbaeeb2a120f605ea0bd5cf9f1e440a2bce9edc3ed081cf6f6b38aed618448a20ad9cb8531fe376208a618bbac6184525396a61a0864455071c66e7f99d43cc984465f950f46cc0050c43d7387b8730aa625fbbebd976969df2150d8778811ec4b44d2bedf3af364df1fd27106cdbecf030d07f645d3b46f1a12f64dd3b46f115e5eba0a5da6cb2484d3ae2f5ebabc340dc6defd68632c44d3bb80440a2e4079c900b36d70e802b6865440a4400041800922ceb68fdbdcb80104961940f0b06d8e7d69afd76bcacd21892b650389364bc6daa06d6bb0586d34e55463ade5b66ff9d93f6ccb83990e98e101cbb64ff200c5b6df1a62b2edeb506261dbe721dbf67d70a01467db0fd203d3b6df8107b69df960c5b61fc20f4c2f2db0a23073b634c3b63320901cddb9b570a40993315a509064042c2cd828a4783c4ba66bdb33d8be3b3051e605ca832e75ebc60e4580a006aa103ec6586bad7fcc9a272d2c86e2e9c598374d80546113b226949a6072118e8953b452d3444d143557d46c69f1b22725b050856e62405816bbf23302a3950ce94aa8e689858ca9c86789a61f198d4acf12b05076022a3c163bb1e4041a27d4f8844e4e5025e1d44326cbbdf75e36489435c59459fac1060d0f48c491648e8a52aa906644eb423ba2acb9552119d9131dda0e19214cd03fa0e89222a326ca1346984ccd494e125d34193831d06210348180a6759862429b241d567852c44b87189ca461d241c624044cf88726b8a933a20967c491114959ebd044d1e606ebf006ca9dd8e2354a3fd630717a87244eac2a8c628a1f51584159739758ef1025ca089c76e80213c10e47454d453bc8a614a114bef036806025a9e0c3942f58b4dd7336850c8c351aef399b3233010833539a76a99f86294db08af4ef399b52c5192a55c2300446e0cffc16e4a19c4b3ff3d72f73e89f96b2c0df11756c624bac6298432bea5c50ce337bea7c39d3f89773884e447d8ef8bd8b3954ec6ce888e564431ff42270a744d47ba2fe1cd17b1d31e7679b0d72306d80ef2dd9d068a858ce1e76a9cb09c410bbd47ba6d99a875c3b3aa2426a9ee7c9947833a8cc479b7b8ffb12dc9c36f7a56a03c1dd9a6cee37cf0a4a72db6b73af83b2d8a5dd774baa4275ac5b52cd3f9f6e4dd306f7155ca14b2e4efe42716cb5fbdc7369e615b93493c5855c9c79c1b46eaa0836c7856073f768ab2579e8ddc7cf81fd5c57f46f5265713f5dd8c73d72e12d147719b11125b91f63dac77293825ff7a80ae1e7c27ba4b967818db82ed8c7d78fce09bd7db9955b93d1e67eab71b5cd4dee5dd034978f9ce2ce6883ef91b5770a4121d0f2a042add6745971ba3c178f0e9a73ce39e755b5bf01f9f4ed58040c10f2e9577b7f0392fc4b7e9109ae7ed8afbf01f9f48afef68fb8aab8ca9ff30884becd39e7d7599c5b67189651127c2ae2a2ca0261c4788d9594d0df971c6c73471c8c039f2ba238ba073f3f75af0d76b00d96dd1a8a83e7c1cf4e1487eac1cf6d288e9d073fd7288ed4839fc1cf4854686baa2c30a8829e9f3497d96036aa4239ccb1581592f1e0734719e87111e61e7c0c23638ce573628ee12d542897a12cf08fd0a08131967329682c679959a682b1cc91e3c68d5d724fe44ff0c7aae7ef1f71ad7a80d4bf2311303d4f64044289904fff882bc7385865818fc7b1c45a1c4b1dfe58862fc6f2398e5659e0932ec6926c31963fae46163fe1586a9fb1958f36f89e7f3c222e8395f01266c26828093ef9d365c5551e2fe043c6a7385815c2f8e9712dc44e1ad3b00c912345fcaa2cf0afc81d7134b0e48eb8a3a31cd59554361a734c2cf118d3250e017e55a1eda8b2c0bf9ffa9e3127bf6e4ca1679b0cb41da58e8e36f8d3458ad3c523e63594045f2566274a82bf23e636b94649f075c43c0525c1e76855686be26038d35e18a68b3608eb621b7cd8069f3baa421989b2c0cf6a9ad0fc52584667311b3cda60ce98c71fd4254397d1dc13f75431e69e9e36f89efd5a059817cc0d3e90fcd2d9bfecdeeb44164c3ae7c11e3963d206df836ec494fcde52f27b1dd43352ceb10450d71d73acb2c0ef9cd0b3ccb1a6a6a6a60d7eab0a3960b2c007a3d8e0e7b8a0e94ec494ec5e8b9692dda3c41c31487e308319043b2316748506fc493e08165901195b3f8b606e95df77fe551ea7cbe6d873a2714adbe8a82c1087f7f33d2cd6dfc0f74c4524603cbfe713ecc6361c5416f818fc2c967a83ba07fd3d8ce679b40dbe3375e07b97fc20cd20cd20cd60fef2c17798831a0cc1f73e1104c1ff3eaf29e1cda0922bbaad2ae4faf7a2269f2d5ed0dd779e534ed90f77d1a78f7a1df451e07ba223117d54163864dbdfe8304a823f4170aa9ad0df7bcfbd40eeb5c1df68756eb40dfe26ab186fb20dbe0b9a2e72a3ca025d1ca1ed57071feb2ab43df8215985eea3c632c49b2be262568d7eeb256cfa7acd765a43700cfc0625c329f404260620e00d42d8c107f3821bf49dd20c5c844d472edbdb0ea60dbf42039feca8c48c9a6962e9d08c00004010002316002020100a87c442911c87f24c14dd0314800d65823e665c401f88435192c34008628c21c4004280310418620c62caaa0ce82a27d81a1ac6c4d01061b5d9edcef91f453135597b57896b298b5c3fed1607cb8201197f8f5f0b436057a8d99f0bf9df4b0982c9d8a91fb0b66e869a4f43fa1ddd75ec69db3caf7c264881990dc6a65fcde8b6eb2fd58728b77d373a70d78b6ab8db30c1258e45eaa8e9bf1378e20dd0f39bce6dc57d9ee720f1fd0bf4ec72b18683abeb89f8ecbbde6857bfd033626cd43430c9911a89c73558d1ade1cc59ecade19f68984a28de704b00c86e1033c924462667a000997ad9e6656fff6e3aa9e4c3221c21951df47598f989bfb3a747f91fdfadc6fb8a6910d74f90fdc7cb2040a317413834047e19b9d105e45e54c75b7a7c8de76a4a3cb8b2b970206acbcca66c79930d6e481c8615bfce2dec4810865abf6c19f6a0c1c2a98c2f23c3bacbca2dcf7f44cf630c6ec94b5026011c8f8f599dfcac8e5c73b2d5dd7c505ab97fb19c9ee6409494fa22491750fde0fd9467f535c948f53a394e0a3fb5a51439a474a43ffe0da2f0fb6225beeae4d2bf425289b3d7d24d1411cd89049d38e1905cb5c1f58c5a7282a2aebb4b01a7f3cfcf1e91334257e1c78ba5ef2af4f6591ce6e3da3c315dd24bef1d6226f74ba6169fd7c5f7107c2e78bd0bcdf326af270dc269fa5692034440a399b139884ea4386b2e6f1818c921af102f9a4d4776d6e1dacb78121feb114e2da06156ece0b1294d364a6f9a945644790f06d10b189394897602912627164d109876a7d104b94a02d963b04c98adfe403829338635d40289c7bf7ec49b1885578e65310819420c4340b0223899f025f244a068b79d492266c9fcff60100068c9cf3b66322c9a0e59f6c641e7810e1f95b821c769ddc56ee1acf5984945cb94453feeafde9aceda418d5068c6ddd8431a9b2431330886538fb0b5f29e2cfb904739c92981f50ba5a8a09900e1cbf7ce45b53a3412d2199c79f3d73279ce7bf8c76555c28536b3115e28e1cf42d426884fdfa5657aa83f4506f8f2c20a335085c96c98e8c841e481cdc5f8e789bce4f5fed95e47bb40a8f0d98c2bb2805ee504f04ea7f02d6119965c5fda975c2f4f89a25a6b61b4201ea3aaa0a9a9f0ebb8dcf3e12b9c10b0b18ed82b3cbd7e99bd98d85ffcc22551f2a8ddb51e579d1c2839cee2b99994c7ff68af798c5550d55ebe53f2fd9c7cd7fafe95ef8b372883c2fd75f738a45ae9d2835979ec2e8472f86e2e9dc91b3027eb487aaf74b275c9bb45fd7fb93b914fc20c0163e2556e6820d3e87f737c6b4167f9950cd460687eaeefb159345275223f0d26ebc0348d4feccdb3c955e74251d4956a1198835f2549e842e1725db120c2984255cb18ae10a0ab8cacc0ecdedfc96e82e6954497942952d6861f9b4d9927fbbd06b62bae756af2d71b39b2891f5676abde8076e883d075b9e6df8bcb3856d6e558bfae510b77bbe76aba13ebbe1c8ea3c63af59f36c84d316917d238164dedec159226a108c8ba947c9c62a0c03014eb9c8d509ffa5bc05e41607c6c1dd535b1a1aefd55f6db9f96d7a3b4266d2eb39f69bc491c6705170635417c76f54703283816e6819c50faf07ce909da0355d728e3cee04d1a8a8918516c52d4e508ab22291c139e499378066fa2098da96ecea3b20d632bee696da3f856c7114bc00c7c795d6c50aea4a5f77c8e8668e51dd5269c2ef02b1c48dd6419f6cbbce964b8875173e27282c87f2e351353154d91a39bf7f803d6d3d51d912d98309669d2010b52e5839308a2069b02be7d3627223b48889c6cb50d6cfe56f7bba647e6faeee75aa747dae0c3b80d82a1b20897a22569a1aee7de6dec850fe285470d4650fd7ed5bff265cf56e3e0b7aa584af25fbca77bc576d8f8e320a50a595325a07b4a7cc9fe66bbf2e1dfc3683c6a8f769f2645cf49f1961276f04f5a9bc0cb9380747d1075107a28e7a5b6d071242cab1cb1e0ea9e3f70a6e4bbeba8fce40b75d97b52356f987ab24fa187d438aa92fc23803271ffe4d658dd7f9d4b4fdc4ccb8e39ef21b13ac9f116ea22bf08059a1029821fbea8ce91694f634fe3e20670d28b1805ac5bad5c52de942e18e92dd1950384b594cf9ee9db5fda8399a017dc3204bd8ca37c8f9393edebcd9fd887d35a00d06b25c7481116d85c65c45232f6495ad569fb53fd2efa112bea7534b0cb2d399b4caee03b8d601c6618d213f97632f991829a2d23a0e988a01184ada7b7d6a20ab748f24b75b7acc32c90d74eae950073858dab1ae2a47d95f83d02dd2e42ba19c89c073e8394857ff25a567ae5be5d255ebee0367125100a3d1895a5c4794c0679555eaf33c0f7fc85480836be9d8a913631f4c1fcd008e5d0d9df2ebc2d77959d0417b9eb31165b5bea1430194084028e88c6f2955dc9b9bf641c3a6a718d1c0ae442a5378d747440564a055d57a5e6b40dbd02471728212291f7bcaf2a6ccce8b9c4c47b03330427cdf29f9263bdc8cf8021c8cce00b28bdbf0af40bd2d25e6b0476e5eb662ee0ef846570cfd469589934a62d5cb8eb8ead95dd475c37147410608873b81452f58247c2bf07c80f241789faf967072df51961e9fc4b31927fa71ce272e5c8be516e761f8754f05d74b9bc8074ff31ac4eaf56e8985bdbd9640b994fef6feba9e81defd161185527321d3ea19f3cf19275ea7135a42da5955200b2a990c4d2e6625f8cb513ba220f1d67fd3fe90b28eda00bdba9fa161133374b3d69d9663794b9d60e423bb4f92222e3c011f1367d71055c4f9e49f007cd48ef0c6b59517c8d34f9cc2895bae29adca51953b4d75035c7e7b437a5619d2e369b310823f197b2411afae924ac4111d40eeab670594b05482e41417a181c89128e3595a6d09c0db69a6f9d5693a3fa789ae4c1265e64768fb4ba30d5f41b7e896c5857a57722bb24c2dc61bd42f36f78b5d972703c07644f72c2b0486cdbf9042177938bd4194fc2564851ce6342ad4d864df71fcc4d3c6755480c9a1ae1eff08b461d3404ab9a28d109975dd48eb47b23a73dc73228d20e0d6981777c23b0be501a1084d4f5cca8b54773e8c85fd612003940f499e88862c0e7e0b4bcf235a960fc5e925701b59e568474ba462a9ba301524dfe5bfea76bf83959878a77611885cb2265578cefea64cc9a2456ff9436bb136ffc38633df479f5325a5bd0587342436c0a3ac35da5f019d2f536810e36076dc04219cfb3ba8fd1fb3987d7c4782e7440bdb1b8eff106a67e52948bba04147c8cf4191cee1aec8d2df88cefc3ff8cbf5b353e4566453b35be6d199fbe7d073f90b35a7833bebb682133595a7c04631904f560f184f8b8240c30dd5a0e449e2db9cb5127c5a7ac0f1a70f57da79237af81cd81088e977d097e61138949481a1137b4de92edf28df8bb787c9102ce7befce19e382e5b761ad2d03d3b71b0887c05029fc4f7497ee6aef1cfb1ec7172feb4fa09eff82041ef92c32ec5de519defc68c2736e9c3edeee16bd2f794eebb42bf65dea99b110037f29017aafdcd7d91d036569bf32e00d8b7da8925ad6fe4eb49316fed23372c42983cae806b82a4f7cc58597a8f01fa84db9aefd1e48f975b892764ad8b1c3a7a9fcc9a27aece21e5883c40bbe52821d8c02b40981d6b65fefd7922ab78966632ebbfa852d3d724b27093a6b47824b0a6b0d88d2fadff1f5901abc0959139faf3fe39d1873be45e5fcb7ed134990172dedcad8e998158b2bbb5327e5a404d95953e1f51ecac2561767e18e45e2d0aae56a8c471d7aa7140f8086112591d9cce551e38f0ebd2fcee6ca0cf604986e4d1e98527302a132d103a27077a31d525c88986c67cf4a82ebf0bec430cc8f1ffe8f92a88c69672cc364ea2b5ae017ba9d74188f0c75acf22dea894fc5a1cdbcfd916491f296fa19c755201e98a3a190cc5ea987afaf44006da82152eac9ca23e503729f814944a78a604891d0a8d0729dcfafb6d58e98603c8bc8eed584fe24c37ad1b7c09658f982fb7cc585f4f8e7e637b3be7c20dc89702920252588efbbbb8bc3537f892a44958ce2719a15f1a5ee67e5b42068d8efbc16bebe6dc98000aeeb5cc297310fb464df60bbd49aa5265cc59c4134a009487c1c97aa94f53c318170df2f91110acbc96d6a289bf75376ea0ec600c3e52c5cab8c0743e878335034ec53ea79c790e617ed5ca5c6066885f1ec090f3255dee96b256f02e8f7d36fb9c1a476cdbfc23e3d68d2a31ab99fd207e6c60e5a74b6cadfcee3072e9a551c4118f3e28faf0be5bdebae8015ca5a829732ad95e599a9348ed881a992c356381a5b5f0df5aab843e029e0f24ef7e5b5861a0291b8d5a124feabd0d0c8591c19ccf10578d813cd4809e55b18f625f879221052f514ea5629ae02e7e80ff21f9e0f680cfd0aff1d1b821be69b73d9a34fc08cf43260813c0ff7a646541136e4394c5c584ee40feb07ec8f1def6592c9b624f73e47dd7542ead4b43b22b47c40ec1b8243ce508114229a823c2d9a8c8679a0c7133a05be73b83765153decb64c12d25895ede4ff315904d593edac9a0bfe41d5d958ca9c999c775e619e2af9d6acb34d2c7f521e11ebef4dcae296c28e304d14410664e6cc9ae8edd0bc5eb6d2c68114745428a0c29a69a5f0546b2d3d2caff559c304e074f7e5c6727ec59edd35216adbd139e32bb199d5837ed303550a2b5cb739ba2f977aeb92a304c20481c9b834e5a2bfc25bb7d9e547f640821ba1a82c5526abb8014898b0b5d051d9cb5f28a445e19b3a2dd950c01204f1c7669ae2131694420c44ed42cbfae04978fa5c57548acc773861715ab9c7f047d72420fa8adde633d1156d5497a5329dd6da7c2b340897cc030917c67c974e145fe28b04d0fa082f6270fcd7443a1dc948c9c297f66b40da218fa736c8e30d469189d5fc6675bfc5f9b5aeb027c3dfbe5df94c11f74226ba670c628ede39fc2e76321503e2a61a02915b098f6ed2584d053360e58a7a6a9c24cf8b7704ed642d943cbc97d07a992a1f5ecaebc20401e7a0203729716ba6b31ce7ebe75c618f998644fd9a890b581586d596240c7626a19eaf11c116e401875c37f5c7d880b10f92237f941e269710c77c07a5acc91de1e4728c5c4d89f07a235634e62f219f18efb3616102006a12c9f03cfadba5514d5a52ee8ef3e3bbde7c2c413a2146ce87e934659d4504f71b763f423ae176e6af2a606a6170f834f82346d632448cda60f28f874541cce70ef4136548a07498c113394e64a250902b398edb23d3a2aa588830149328f483ac398405be16f72fa02b0c214c2d2564c4f7338899174d7277ab2e2e81cb2aabb7624ba23bcdccb7adf73836718044eb753229d835c634dd9e04f1ed9c1623006d9359f2159fcffe3e4f5acbfe2e0f4a815a080ad0735a752a6b2d7b378c6ebbb439450d7d475eaba29ee3a90314475edc8248f814f88aa0701cfda12108a323942e5ffc5446ab97457776a384d1e7073b85d9e8717a91b9ddc1298f4221817d378a7f2f0ab05d3dfafdcacf15462448839c82a2020495d44204bc49a8fbff7f19000d8393c670b92f5e28f051a6fd336f00651d094e25b23325c330a803c32d013db104b79129954d725bc94b807d5cac913c61b84696ce5574615d9d5f6b5ee87ef037c3ae921a7477cfffb77e9e76986055f79479bf16e1c572bc58ae94842233149a8845a279ba6c67a8e6fd357c1cc47baa6257fbf55bea7c025873bdc1ab3374a3ec4df449837d3e841ce9a90055f78f5c05e9f5217e1437c09c05135d35e3da575ea1c2ff3f90c11cd0816a01ef9790c159b19dad415457589181ae8b42bc4c9235981e0d61ef29e3ddd9747826c5f97aecb0063e132857176e11030b302c1d3ffde49776f3082c3d30f3ebb62ffa322861e5a88b238c78d965621ce69d1dbfb1a5462893067f99452f2cebb646401be4550fca1e268fac4efdc31b1f9876d55bb6f6dbfdeefa8428cd0bf3a71e3ec12ca2d341395aff4e314650fe31dae67184ed130bf2417a7a1cd577cd71b3c796e75a0fd6ce479565d2f24cc1ce97aa276b2b9381644c5bbba4168c7f81147e60d5f0874ad8409424d7db856373147d036c6b2eba5c3a042d146cfacb30ec4663701fd2a437f2f8d155f3b8cac7947f0b226d3e25891cc7a5f2f7815e9ee68245c23ab9ad76683f27532dfef21efeb63b4288e29d8365011a4335e2385aebb80d558e598400ab5be7e43cd49d1be351aff492523477b50c6fcfedc8092456d50e2aa89245a932feef1c48415f849ec4259165bcb2e7e2b3ad2782b9998ad1a8f4eb0e1f2a959a2634d643e5ab4b0bf48136b810d205173c7799a3ce7b4319821926feb0c756d78f8486ffc99c46ee5756e4fdbbf15c894814c98a1d5346e95875166b22bfc010c74936f74dee4a177b3fe1402f60540d13c36700a8b44f7fab7e4106601b1f9e70a03c7b262ad83a9f9516a01e7c7f9b4ea9b7871970f8c35e35f08387770dc88e32bd6ec2ba924b91af8830fd36a33d0837be85db1113766167f79bbe241969656f848299f88218757d2509141648a25db98bab04bfe79e5543ffaa492f823fdf4adff6369b37bb93f6a607d73e534dea327536dbd957edbf298da5d7d9afedd156f54f96fe52eea7e407536053cf7129c1e982b8eab2538206b3e0ee40f81582cd970efd5644fad9cf72a46be60c6f537f10a6f688ff4a152227c333d81bda8244522ed828692b3362e1e1489da72b95e14c402478922307856c981ce5cca51772a8712f661d441d5126f9d7cc9b5d821395c7cccc1774633c06a7874c1227bbe284b8a0695582c685817749f7219364335e07068e9264512fb0ea7156be482e076aab1ff85b059a16a99732343d0c3f01b56b381724dbde96093f716025f098329b9dd7449f02d00a1cbaf7582f49e89a2c6347477834cc210947bc3bf93adf364c0e52b95a1c2fad7d8d46345a87b2d83e0b0c2ac7e6817bf6befb6f4552c4356f3ce9bab94e91c835c372da1abdb896fd86e1587567f86506b25ff1cc8137402724630d1a6e6795f0b0b5fd4c94b9a31a81a40913a5d5251b0a82f77c0dbf6f4375eed7e34d7499c9d65fc75fcdd5f839678c6918b015882cb57c4c74d030fd5e06c60661c23b3cb3e30aaee8bb3c66948f776a705da9db7dc6c89728a0716a7058c7ae127dee1c63d95b75324ab28f68ade867531222cbfbbbc7426fa6b245e29c0ce08c05cac466e8d6067f216604e72bc4d0319c93c69282a8325ee3973d5a56ff521dc0a62e33379ed36108e069c38247f2b42b3a1edae6fc9bb45f2648a3557e4280ff6b9209ab9c60821233e81312b5f372fe9de589d205a773c8043d33c16f8ef38462ed9c434624c213aacda13eaf674c20d75d712b4e992fbb2b3188ec9776a319147de8dae1b8140c1f7dad7d16869105dad409a0dd0ca53244bcccb90a397302fd208d6fc4decf8a9c147a7fa33800f5de467238164ea008916557b9a8f8a19c00bddf4aea3cb139f5f0743a83641b764917b8fa07d047d83609ebcbcc9ccdd4f3a4677b7e7acc37467afab81def59a09b8960694d199d0b62debb85613acab89ee5859b41e6f6eb891fce67b290289c0b33419841a70978da9e711a023a9da6941d5122660c84844ebb2b087c8eef95eb0e0ce5a8a1b9494f16e57d05c1e3a0fe13730f9c9fd6e026d1e4e5b68870ad0f832f5b8d42a691bc36db8f459f36c84bcbade7d19d89fecda504c6e64ca2ab9c710456130918899ea439ffdfd4728e2593fc80354cac56a517c6d0010ac764dd6818380ced161d6a89fee0ed9afe545dd749b6006ca89220c69f8f39daf7bde019eac750a129e1612de1c5b8b6da9e438898d667645789e12cfffb0dc5a1759c98fc5b02b387f833aa559310f062db5adc550a04de4ad05e7ebe46c7544d822dafdfb8782273c8a95c0a707babe9438f76fe5ab46335979328f0bf3cae9b4757b7f3ae364efcfd06a83122f0e81bd71a0cc22ed62e9614124125af12cefaef02cd343550b8860c38fb8ad0cd2d5f7029c1180c00007cec855a43d54abddb4ca207660846fcbf12cc9834c97b2318e2706fbb8e75c9efd4a124f2608bce7b5172e7dee2b8dd24d9cf1717a505051eb659b7ac3b0ec6990e77e3411ec89a86d7c106b21373d4f5ec6aa034e24f29f9b40a1575932636256fe1c2007a5a95db515d54f2351db807713e3ab3e81f29a723348b6e0a1cbd158d36a676f3c5da9f85ba3094f7bd70dbc2f824f4640bf6f4b210923f64c061ff99447daa9fab2d10cc8eac73d8cb2a398670bda1eee8234f747aa1650d2657da29ff8ddbb3ab44ca2bf9097bcfa1138391a68482f49b86cf19f345f81916a819ca3b504ecf853840ae4d56599edd4cfe61095c9bd03b69c75921c6f4009d04da38357c226212467928af5885c8aae60b3ee956e7f96046165fcc7196b2667d276980c4f8c51c143685fac6243829f00e7c90e63a59fd993261a1ded0b202e58c4c076be600272a364d229c1c9139b3426271fa5d889eb6522142d589a0420323c1e53559b27e161d9fe67d28ca80855b3debc04c6c906072584ff6c051f6c4e997c74838fb9d157e725d55ef61ab258aac8a18d1042a5cce74833b4e1151d3ecb39d9aa6db8a0dea13bda5854d8196b41c2b61cb0ab2c1d673d280615e84e2311557d97e542a09b359beabbfc494d45b810e82761c3c049487cfc648b7a9bc27c42e68fe89f2e23f3e28e4958e3083356b54fc04d1e5d70fbf034e0db313192aa688bf60defaa81a0889793e68daad33179b924af7ede6fb6f97d6a51b018e3af64dd9aff4879816b728e800f3acd2f2ef99feb4fa6f9860be97b95e9b9efed7ca5d0d3594ff73ae50f64bff6036a92be0c1097e08c24d1525bb1f1047e60946366840bc0c559c0c47716a2c79dfd095fbb35f54a57d0f2822777bc5a6e6783981ce89a55999814a31b83a05ef1f54f99910a78fdb2202088a369fecf5209531f46acb16648c03232b24b9e0245266e3d9d08268a59c394f58acc75b5a47fb5088b5f8b3d5a9602b4d6040a999a29864a860a4cdf84b6c3d26499c6ed6e2f71a74d1a7370a1057a65d25fa7bd34120cce69e954d4f7ed3b510d6c3f6e99fd4d24509bc9ab57929b742609acf035507574b0f619a431dba47ab9b9a61cb8b09f79c694c392ea1bc3271042e2c835aaf211dc2798c58ebbe15fc4b66be58859b631949c78cb0c22b42aba140d28a50dc5c55a8fa56705028dc1c044576a9546c45ecae16666dd4a4c8d28937d66d89d54a5fe386d07c18e924ddf712dd59f4563434b14bc406def999c7e9358ffdba647b9420f4e3191ca553327665ee7f68b0f6525774899f1fc840a49f5de96a5775990a1f9c7caca4e6c55e4af053c36b95a597f5c6a262c44ba364a551f21dc6d275ec05cf7a7b95d24ee44a02627283ed6e3e28202bb5c70d86bc83a7d8f32e2d15be65d53926eb1ac2031b0ff2c860f0ed23dce8ef2dbdcc3d588fade57de8514b067c257800fd300fd1e51f3ad58691b4d0bcbb549600970cdddda5acbbecdcc277e8f01bdf693869a4234b9a6cd216812172d705c8b69a73dc97c31ba0635f8d0811ba7b118b9aa855dc0584a02d2e5941ec1b749750255b3a9bd418ac5117c0c2f4e3b52f4092dc915ecf99af53d2aaddb94ba2d41b3bacf405d47bf7886fd3b5b0c5cc0582700453fb0a906e214cd35247840a12f344939f78e7ca5adc366d90088c01223f66be5110460cbe00f1e84a9128436c299f045500ecfee680d69fe14b27cd3418b273001b43cb65b4daac709bd4b4aea000e3ca8aaf95e8f60fae327734d716aa8d80930aec558bcc424bd2030cbfbd3707de433ba43c6122c014d63e052c08d0118f14980b576591afbc204ba19b80dc5d047fa7f7a3ff92e8df5da75460d85d2282bc0840f9b9f78f043fffcd317206558920c8f5295d520d88779f75436c0171eab692af86fa0ddc7744fe435522cca42fbfd081fea78fd7f6b984222219da97851bcec481d7845ce2f55f1c33bf6ed7517d949e698221c74a21d3728b3748a1f7ef0a3bb1cc917e656b37b2f55bf3061983a21d25889e4ec34a8784f6af12ae3d909eec0d58f730c2ce008d5d5f72eb9427eebd4423c0c8b61a725bc0f9a121b5b3a73c551f71bc72fa0cc90d2a21713052277e2eba3b5c253a8eda809aa671964a7426afdcad8e76005b37d918ab051f27dd13faf625cc0686923c385d7fc1408aec4fb0edd4a9db18c3d1b1023c818597fe145a0be2fc2d1e77be16de7bdd51e1ec88d2b0d859f3a9a1b85d51cbeb90c3961dfdba70952ba444ffaec9c233604976c382678fdadae4a0bae5b971fd85f5c6c6f38a1d56db282ebe3ef698c7e44b47212b48159a00c102e4165aca1e4ba0f781068753f56835cf8eeb97c578a92d0c020c2df5d9d29c532814b7e66c02d5d5ed9201c07843c4d8df519ccebcf0fa05b091b7b60a1884bebc103bae7a71251632517c153f982862cd855b904f70108efc6951b7cac2855c2bdf3a0658552a3f4336f473ca5bd12088fa3becbc8f05c1189d01012faafe0471c262f1af7382ed398134c41ea6a16958a786677efeddc8b77240862b30d07af6ade53dad1adb8d01fac102ae29db97e1d6357926311ee8a712f5b7f23d4353790a988357e13dcc119c5d9eae3d6696cf81ae24748401fa270dc3d6c5280c4403eec3d35125e8a8d3154f84a04d6751e00788a62af714ce12244a61ae16e8779fb231a014c71005fb58df9fb37cd0a916f49fae00ba77641461967b2b493babbf9a9d544d66dea97c3015f2cf04cc93c8dc239557d8503a3824878c788da8f7196781894b402fd8e2d89d30dee8a13eea62bc8bc843193e519dd70627b56a10a09372ca7a609d589c31e755900b0e11033a624200deacd23d58d5a261dcd289b5fec7714cc15907b986fffc9f48ffdc041b6707fe507a3b91d9cd15d74176e6963e2caaf777e0555c0f22c0747b275eadcc03560548278bb0d6ffdf9ed91624299f8f070246267dfc85eb161c05f6cbd9445c2fe0e17e2bf3425050ef35ba3cc0d74a55fe8d73b52feac3fe2106c18b0a8bbf02b207170cc541b61b829e8b958897ec7caab7dc79a17a886b5c2d0b27f69c29f458c6c64e24fc87ed1eeddee1b0ad699ae2fb6f79c664fbd7fa7bc9fe62077c1b5a20289650fb9fb9427790cb786720234980d00a435a097d1b7709e40f0e33b6180f2c56fd3eee3c7ab131772f57afc39e9d735edef9b9ee0d1ab9519fff1e7f6b24f685f8ed0ac01f199585590588babfcf077a6dd39c7b37ed85da08c9a4d42ec6112877cd25e793a398b763075bd44cd6aeb8a6d040612a5c7197da9221a1fad69d837c84b8d08fffecd18799f13383375fad267803dccdc461f53c2f255b9bfa28227f182224abdb06c128548006d3ccb0442d88ee898f13fa88fff7edbced3f26c8ccd568afdb6e481c9af5b21e4e11f79abe4da39c4ccb8961891f5492e5fbf0fb81f8df23f9fb3709714e4fe55b218cd035e6cd0371a5344e4ceba07f3404e20f6a0dfcfd232202345a7bc185cda2331b4e6f38f18db2b1ee94514234d9a4a412911a383a3149400793b7d64e4d511ceec5899d5b7d483185f47ffab1f1ccc61f70165c0f68e842e60eef4014fcb0bcaf6870bb9258804b4a2179b8f372818e90ea2cc5dd208031583ae89fe3e012c818ccc361b26e7a6a67643d47d7a06788f04383c665a7d71e424d22f206a7ddbe0e06169dd0e9c900ac2edb6fd67da36ace681ad3dedaa02b6f7306816e22891715ef946ca29b12a6a2f6a43b1684697740a0ca56261073dc15941cf8cefcd7760ed44d676eb9f6590d52a7a6ee80814fc43593a492d39cc9e6e80e9f85fba34751ab426703d33dc85ec262c751ca69326e6d4104192fd9280a1982f32af1bc0f43201a773374788be3f39d12ec031e11b7008733521a20f15f38e87b0be1ce2394f568bac2b3aef576a8b641267ac81f41506af7bdadb5a75ff18dd1c801b84128f733284e4ab2b7db5601eeb191b98ce5a23107cd0c7a01500f194df7c2627fc52a2b73fc2d955d66e14e6560e88447587054b8ba6dcea50fd3ecfd184388f7c6a960569cd2a4da0be53568e41a72a6e7645e1e6c435ff92804e925857e9f06622170510743db2afde1a329dd0953f27f5344afcde33181b6f010adc49c8710961b92dfa7cd2f55f2b0781808638e209c4c5cf5aaf94166fb1824bdb3c956444aa32379b79743b438972941aa811a527378863190c31bad24304fa9e4059e8afc284b980587683a8f14628b0711709aba9cc5af570870e22e45d3e84beddbcfc382d864324d9eb0409558bd437ca2219ade60228ba6b4b4ad13bc4de71568e492f8ee78f4b8ed1e2228bfb20e17920d8924446efa5e1a4f5c343ea31e9c0db8870fad37e4a1dc86f1618aac9a91a103d4f17bf8baf70a1ee61672b3faca04535b49093a155e38361cf78521dac54b70575ea75915667da5acf9e7ed2a453b015125aad9a8679137e696c4c947beaef0e6e84fab616ef04d8b0549e835aac8ebd9c76dd01dcf1024f2fe320a171f318be32efbda1c7582048bff3ec7196799b5b76d8f97df001e7cf9ab8bd33bd45bcfb73e6ec840bff3abb3979e4d2012ee291e3bca107030f2ad2043f0601ab1ff1be9c7654bca225b14730f6792d315542c73aead0c78bbe4433758363a00dbb3418007195bc1707b0bbb00861909a70cf1d5f3e51ae57bd428e793b071c1bb1240a7e3999ca9e9f57eec805de1c6d99dccf0a345e8c1e26780f32be0f849a3390619a89222be8219617044219a5e20f6c99c2024ace24db1f5b1c10a597fe6583de0d2657ad9024e0c14a2757f0ccda2329a077313a60aa4707da658e6abaed10fe94b078c625cac3c0e75b1be553179c424866f6e8a86e924f6c365abb22f4bd80d0b52d774ad757c231fe5e461f46312f310a37534873ba75162f6febf89aeb0ee1304bcd2f63284d9ed04417df1f9b5785b39b317c565096a7318abb0da0e264e77f2a28b41093569cea1a7b6001e557a9f540a3f26b094a110d0b94687924fd1dda3ab59a3c0138beb014a2ce2a39e3a88d69d98ac567cf394e31205bbfd3a7b406a928adcc6a604f19a30c1b06dc464d514f68029c2c7296a10ad178e9caa7e3202f2b58e3488a643e67b505017df4d11b81647b126653963c701e645cc112bf9015789b4ad71e6eb450e30a957ca0bc1cc935682503a6d51c79a933fc8c11ba37a1ee0941236093081394ad414e3bac384846cb7a72cf9b92e4e102b6fcaa288de03ca052c1aba40282f219f41b43b95d643d2cf0c2c5cfdb704b3208408f3fa3b50332e06d16ef4444bda02edb258ccf0cb8577824c6537389b8c4d0db14aec3299b84ba2165ff4bc4a6b98efe2ea6a38bc84b31f6b3194816b6bf93fa543a2711504cfc41b1c165641e77a718f310967289107bc231444d3c921540aee9b7ac8e3e9aca9b72ec18c266812a69834141bb9c70b4c99d911961e7ad05e7f28085839026f4f780f808fa168b9e236638584209aaecdb0eda555debbf4253825fb0bc3cc63502dc854cbf4341b9fcde7f2faf67070ea4b4b017ff10a8f45052e50d416b58a5303fc6c74556936682952093f31f119ae24bc07e7ddf3a6c2d591a85d96a0fee331cf5ab0ee6e9a30abbd45814d9790cca5fda88f586fa09568205a7ce078d04c46356dc96865a1a15c3cc279794593521988d615582e0c3940a9dc9f37927f0fcdd1aaae0960d36df722dfcfb02ee7ae0485231ae9af86801ce4a7e35f3d3c6b668218668eea9419d2581f1e52a3bab9aa42680e4b8ce2f06a98d7cd92b42ab46410e58d2443064c60e81200b38016aac53148acfc9ba6a9272c8fec5d3e852d0af0eacd018582a007be737edf271901d1ae642f903e319af0ac8eaab754e55de24a56b338ef2fea6a20af7e808ada3c78eff9ab3193f11a4a138078c66531b0053b691b7c939357bf3bd7373e9bb316934e6f00d13a0e488ff57a4a3f68da70e302ac956ab45028908d716a3b98bde9e9444f4a13241afdc42a457cfaf7e4f00be92e45b5864d6785102881d525fcef67c7d7348eb8a0da8e415f6f22cfa9e398cff8780d12af751a08ea5ffb8dfe8e747f2d6b883347f8fc3c7a29b2d9b66a59f3d3a8cb3649456bc206d5e301c822b7be430de4ae6a7ff214d937cef4718477e252fe6bab45aac5d1872ba20a0aa53f171158852e3e1959f2ad3bc7ba5b63cb3622a8f996dc66b5b71cac32dff3c363e1c8ec309d586e5e6e8144894325ea63836d56882ba1553a1c13e153ada13b49d0adc49accecaa10370d5bb43357c8bfb8045d6c4d105b339f76746d297d07ad8f177dad9f23596a6ec75b74f6fd692bc95a29fb3139bb200c550b553a8e371f7cd1b06b33f5e308729eee3f417dd08d3129c9bfab52d32af84e57d117aac2d839422a813d7f68471cd87d322d69c729aeab06aa3f56512d8e11d093bb84ac765670b94740e85e656168a3a6717d3aa9d2d818bcab86abc2f3869f0c563b12b048054d8369f16a08ead9d75ca920c769cc6a7315bbb4094ec817622497ff1865c86224f04f6646f899a13e8da9717133ee6c6bf830c3ab4fa90f328f55d8faf5f445620a9ec07261c74b05d34e11b4ba631f5cc14d5b1d5def056d978ac35a7500be44962c22d25fb878d333f6c13c3c9c5c811c220b83fe976fb2deaa8d980535cbdb565aadcc907ace4f6121fd6075cacbe7ced5bcac5c7cdf1b6f1230ad67771ff749bb994dd91c1f19eec37d33355ecf6ca51b49ca0baa9906de2c4f2dab6704f74d9e1965f9aac5ac4659a5792b1cf6ca60e818e8d23de1a43e95e88c41a995c90ecc0ec22a676548ca6ee6230a153217bda9dabc71c1ccdf6aa967b62d7a8753cb0dc78c835b3df663ce7d700be6d90b55f4037eee03ea2a1a910f2e511c1da3342727af92d5fd7ad83b86fb6d5119d2eb6c9358ac765528273b18d831c370f8c3e626966a13679469b41d4ae427b930049649565a17186a368ea679e37c0fd74c5f55eac3641ca1f2a0c125c37cdd22f12dd3639b7674cca3d0edcef440ee648690a69e96c9018d3c41f19ee6e6ef68dd1fa71c7fa7fd6a99cd04e8e66172e282bcf9245f4a6a8c0d5840b26c57bb6e243b95e9395c79be7bbb75c47571bb83f8fec0de3e0b37c33db2188838ab67a4d388893d58b061aba9f0721ec167f248cb02873e77d59752682733eb3436343aff1a76ae51487accb15b2c6220a157b3538bf8048c8b1834e9ed50a6415ef771dfeca20241815efb838331e59f63fbd2efc3dcf618755b0e8b6d4d0d6441c5dbfd969bc3adf3e1b8bfbf5fd4e212fefb093474ae278e7e9e46eee3231394815e0e962ddc696417a9503d8399310c459f1b1eda2485717544a50418b3174954d5b3c0c30284bd8ec86055be15949821fa22fdf7bf1db0f24ab324ff74b4c9e92b623f8f7ccf1759a534ed63a88a8595530909456e571d3bd3d7c6505b28203ed41b341a5ac67fc4fd82c184ad88bf903cc33adc8d0339008c1f2b8121d908195d2569e4a81f601a0d123f1b215905a717c9d23cb568716b0b7761acb2603fc95d4eb45543e14b4c295836cb48ec97b15f2411d5e1e285dd057e3636def3bc225ad757c23362aeceae3f7e819172297f8073457bf8c4996e52790c0ae5e361b6d563b74efb22c153de1cf75cc075856c86c40ce71bdc9a3211d19654fb457f06c64bd34d5e0cf30ce0b224a22328d74505ef2590199fa8e894d3b285f81384428932b30a644411ee61626db9ca111369c172c6fb3cfd09372b6c884a8e8cdf6c3c8b6c80800a9c42cfd4600bc0817079b61f72312d5cb32ab465a5dd8df1e6f13e8455eea31992ea86041188507e92cc6e7ac90383a25c88741d19fee86760804340439e724b4736e90879cc26e3117b1b96bc78a91e9ee562a0c48012c6f38f0950f8f2797ae61acd7cadbfbda4dd651b4fcf2ba87fab9b751353ad772027847e67d033c4aaaccc05daf4f8a736776bd890c8e123ef3905d055d072426127a717829ea04fd0b62204f25e12d48c57b13a8e7463309c83cc3c6d620413e95dae059ce24692a98291891b102fe314f1352e0fd91499aa48f2e8b444edcdaf736277db2d09f80c98adae794d534de325101097ba05d739bd7cd2899583b67977487a7a6f3e0f13e25682760dfba50295dd0fc82ad3095a76292056a66a8c6cfc802019a73819e0407164aa60b27603e3653a45c93407c691a982c9da0d40902a3d0f683523fa6cffe235e56b3f2f92d4c7f77860437d64e30a09f490a5d7c70f39db4b23c8c5a7f37ad5935b9913e2e755e8dc18477a03ffdb931bea03535e136922b1e514bb0bc97bcc948a79c063e274a61cdd7cf4dc9bc1431de207f08d7cf75c938148886c47e9e988c100232ada72d6928c3530ffd85eb6eb0aeadf4a9d7be23039a88d5eb8aa6707c88b0f5a9067ce15cc62905875cf42859b1ba74c2ddb36dad5c8622c229ddd1e4174f239031037e9a7a4e0a3947d359292c092387804039cad6321936c9a8cdc17d993634817d95c1a5e4bea3bb728e60da7da5ad46f1f1f5986542c84eb55328971250cbd649408bfe9896314693c84d021bc7da0666b257ca0b1cfa811478e5948dfd1703746c30cf117f848b40f01682bbf7f3fc7b5c5c16919a57aeea9e124a45418e148ed721ba7c582ca6d14d560a9c7c71ef32f8e4f9c9b7bc9fb99d9174c45bb238a879c75bbc79fc76704ceba7258af664177211ebfd66e11c8dfd2953b87e01181a17658ed3576d572ae5b42b7df366755637108d4b431dafba62aacddb46efa2bf82d4c48559c9347305823cd5b8324c56c923b13bca18b6e1ba1ad6347ae221035b9a83a5f27b9bc1ba2c65b8aca4d36d644d22381c4baaa8d0c462439652df63e96449b96923e70c15e43254aa89baa549e784beaab4e9061671b648d24efe7b3b5ea49d21ef40eb5e5059612b820e0b89730db20ac5825057eefb25b86cd2792eb3275ccce960f8b10b0bec0020dcc93610bcba5a0acb5e135c67f3978570fdd739a0fa6343b5a43a14d26e4ebbae0ad93553dc7a6695cade9f034fa3b15ebc838b587f78217897327d8124da372bad0143fc0f063d3a02f4548343df13c5240ad4f0e0a6ccf2875f2b7a18a4c90c333aade36b3596af339b287e90f6ec749941718019b0b6dc4ae7ac0b968741d6783ecafec30b8a87e042a6ea9f53630606a1a3c4d6a9bee5aaf1d4a979f41f68c40efb236b0fcb172ba10fde5289ddff7ed50b763c35e5075ecf6449414a15bd606d616024ddbab3454f940a64b958acd85684b40cda3b6c5245b38422d7a3a54a08083271120e65fcacf4b782415c2d21ff034011a120db5783589acc177dc67694864bed5713e4516db58264657a600d2bea9fecce391912439e7b2fc3c3161094e8639b46214edfac6aa178b49550007611456b0a17bee73c1b55cdb1ef155fb7b5d9ed605964c543d286719ca4438f2071480450bc0c1cd44bad920313ecd3f70f6f8d78f2a1c5b7bf2c4b23bffcc05828a5489ea0a4b66e8190eec9120e7381d824cefdf9792495bf7fe1a6ebeef23c6af070b56b5e54cde44b7e507115a8e4f8d1d4197fd2ab7b8795bf701831f1bf0df21b3beddd2f470765a529a23aa8c4a755cb3d898d39031065f6e2bdc9c60894f12d1b79e4f13d23e79502775abfd15d54a42c59c48306ef79fec4ba76b191f4f43733fca00514d6267367a057c42e5578bffff741ffcd0c79201cbc0ce3045baa9f4241fd14809d5f32bc178bc709b6c7949394efce4b93448408059bd4204ed5cd48608d7287e692e5e8488765302fa504ccd65269f541c01086142f4a715b6a1f2fb1bbac3366d91a6900b3750e681f015256201e1173a2e6dce48bb83c114cef2bfff8c564b3836dbb0b59148274c24a041edbbfc4ce336e9eb51391ab30afa1e62d47dc11db58aca8e872fa126d13eba3729681e5cbc4b10e5faf32a7e84b8362d155a7a16f27af5750e5d223e4a004870409f02d4255973875c533f4a78b0795e813334319a7a3a4f36880a86d46f99b76b1814803f3279343814d8f980e5513038ea0f0461d9ad718afa5dfe8554e34711a00621ea67414797fc1898a3979297a8bf04e502e119fcc73353deacb4c6e910ef8ae2826767fdac30b9f4fb26fe93cc1512a0c1c0f055335f1d1026ab425e80edbe137c42759755ccde3a703fa7f8fcffe0eb0f9219bb9d2d571f9219b23711231eb48d6421e3e6cd57e0b1fb99473c415df767618026d58a73cf1f90054c681c31988ba9d4a013e1a1cf8eb9015a32c62d117db16f3e3c7424b52d8f75bd54b99d9ffe024772c10125658e814bd67e8db2075b7f663cbeca7b8b96573eec67ecc241c2c5c7f3c1e837c2685b5e733cb21201712ed0d9be67702c5f56371444fb792f10d8df6cf3b28b55b950f98123055f97c039883102a48760b25efe6c70c94ec7a020b252fe3ef5e5ceed9877973f1d7d17ae1e301dcd44822c72128ebcf149f57163901081c0e5a47a23556d88ebf51fec757f38b87fe6f68cc34bd29bb36fdc77c19e01feb061c8437bba8ff1c1c9cb8fe77d6b0bf9dd933064f2804c4635e6c7f36afa1aad138523e0e8c15d5bdeabcd68ece9fe4c06a4c98df6918dfd657e030838eca2e080443832b0703d44e454e09d0acf0d0df27e43e3f9df0a003f05d7b49102d63849de00803d2527b285d1f4f9f87d2000647663846af838b513824ab2576ec9d8e7100f1745eb3ed4fb4796142245105818d008429ce040c2376fada931a490f225c7297c58f0076a00f88a2f8c422eab67fa75cbfc4ca40be363d91df1f92d49b7bef20114aab86d3fb4c91852e833d73e64c489e44fd2bbe810f1d534e20bd7cf9fb276d0a896f5f3ae506a84d5f2831ed0c9de277079d310440f9cc564430e97a541df9188fe49b9abd8a203561e77022b6dd1ff96ed6aa883aee6f3ee00e132fdbc8c4c4ed23b5e7a1f052a803b2f052106d87bcd8940e7e687cbef6e19a72005b30762d84e37c17fe121a8846dd9325ee8df5e60bd5f30c0d3225306ff6227f06d84218debe3ee16fee70f24a9d0097a4913ac309f619832ded87858522f90ae60a84e01f592455ca38ae13ffcedcf3f14b3868fed29e7c405264d143e6704477c6824aeb2cee72d7cb8a22f56c9922b4552777833fe331cd917635534929f51768dd055ba8ab053eaff83c8265dcae994cf52b99478b471e97ebafad6f13ee52f677925e28c1742cd36baf0e61d85658e080cf5c26b86363a5002a4d535da0407a29ac5b5f8b4d730632f76e0c8bdaaa4873602bf275606813f53a82552aa44eac4bfd1a17d4639dfd3b8189643f464803781640a224b54bb3f0cecc8acca6c7196be52cd47bba012201af5a42e40d19e6f014617aa3f6306d8673ffcf12ecfc3146676103c33d41775b420e199f9a5ccd9e69f56532ad56d2f09da9dea36f59206d65e1277618b9f978836342374875ff278439766893276c298271612655093bf8df19fa8f5bea42e94337b39792813be84f84f6d91a7c22f52a86eb9605871f3d1a975ea41f42895826568bc51c4233e059792c3e9daabd2439c0e343543bef3afec0dada24458e63e369c6e42d14784b4d3d0f1a801d9c1f4d8d9d0f1ef112d1e96f5a188f9be74c55f00b8cc31466bbc07405d72e5f0907bf6f05a29c7c60e0f497f7ab2342f9d14dd82bfd0a7ac63767b27d7cada2f29aa7c7afd3e4a0745bc14863c4e973e39679bb1d016d8fabe7fcc47665810663c078ba646cd126b2824b5f2448f194d765f22bf6116073980a984ee51966eca29ddebdeb045b9d09198af0f4b427180960e4429870cbff7054e9ac0118d663e7d352393243698f55b613d8e00965438fafb4e9f2756e80caf90243a48d2b064ad4d9c443c77e05024cf84a68bbbf69ef0241d7f04fa566cb719ec6c99005a9ee89032eaa23d93f105b0c1f4ef96d83d85998efe6918bec970e158f387015843fcbe7d9fea1e748ed5ca08c06868f6649363d86100074b6865f508af811c94247fd87462fca1b5c35763e21410c705c4b1e07cb081d632943e7c1e3d4f2edc22d698e85ac112592740e03c469a7fa8875be4d92dfdd008549ff60408f9866ec4c6e9128ba031c18285686c5ef6fe31f3ae5dba8b746b7d0ad7b2f7c629fa0312155759620ef37f4bc6c349c6b46087f91fa31a4fe51583f1138c7908a344b937d0c900f058aac9b2dcc12c4e90c093b5630f462fd1a8ba4cd5251a9d91f5982a24bb3f9e8b42a6f1d01401625535d7afd9938fd84ad2701a86c81ad463c49b869012f2c9655a7a22d8a786a2c1748dd295fc289ca0ab2fc0f80e16956048c51de8d5e1720a6b4c2ed0a824b55c7f1bdae0cf278d490f0abdb350c848b88992a9e456793c853bec5d0b3623d693f65e9d12d0af4fc2519e90b5e978d3c9ef0a28649c16f6609169ddcc044bc877e50e9102a04c0570080bc99533890e0c2fee72fc7bd9f1d2ab90d079dec7fb12b43a4a0579c7cd26be8cc968659dec653c3132d026391bd139d9f9efb71baeda2200c77539cacafd6dbc9d3ff142a6940b87212ed03900e936498010f77580b62b52e6e22a2b74dbdf09535fc7e1b2c33d454b61f7fbbe9254b46b58924427e0e36464f0985de1b153adb9ecaf06b007a8dc6c5ab86e7d76c266a428b10ca65faaa1127bfbbb8566f29a697fc3178a3a9938d202ae7480f78dc79fd8eea2d261a56c17d609baf4fd5195443db72a9902abd4f488354b660eb722ceee9cd58ad881485ede5314cf48955a82d44392d8b511dcd5d7a6726b4bcae7825808c704e8a880c892f607543711c43a360c747b486899a22a731940e582c34c6746e476873e5d6ff2463a1ad7a4d266b7bc4a63843701e25d4ba789ec91073fc655f2e08ecbb91f32aeb746a37e1eefa5347ec160912223fcedeee3175728a220d08b2c314cf54569da8cf3f39032f5eb6b275c849b066f0e0ca120c41da2907fdaef2ef627e0d12834cd2756422aff55bd4bb116f5f0dca276489db87550b1e38ed98bdafecd72869bfab0eaf7d114eef5e337bd7c10b9f2c69d6d764bc7906e421edb6ed9c9ff06f58e34bc004901784489a71e00ec1d90b72819d3b55f47922a8ccd7d4c9d4f7f36fa2a196cae1998c99a9d123743b57110d0e3fb0c744bf894287a627230b00a5cce0c0db8add0b690d1862101b07e219f1e4ea5eaf4ce0cc89f65f88f078c974926819cd36804291b8cf62b69056c365ddf717f0864b46f3c7ed7e614af9f295c9fc7fe0eb3e2101412cd38fd9ebf95a7750c7ad60683a26f876e69e33a03ee7887e4e2e6e54dd5d048244aba73607e410c7ec899cd2b7b50d51f75672e90c143c63f575e644b1d6913df6930e21529778b35ec01743d95c099c76f14ed0ee6ba80b127a25697f5fc885cf6f260d299884730fdbe5e7f4b51c270b9699b5dc5f4f8eedbc5fc85d33cd343d455c3daf0300a6dced162ca522b157b3d90c82354a9778ba9445d89ded62704278e52beef9f95e7ddd25aba3afc7e47f3ee878de91ee837acab605771f4f5b72c1afa40b76bb8635310d56a2bb07a99820bf686a34e5c8ccc230c8b4a9b91e46a096dd85e16ecc40e97e19f0959846e621a4b72e5dd38104012da037c10d8c2993a94960c2d60b3bc8d8a09de0ea1e7d2b40b26c2f1446e7bfe41aaaa1878e1da14fee86d9fe51b35c719e1de5215d78868229575f5fa3b849c6fea86a2a04f9acfe106ef670e0459d044fb510424b82d3fa3ed586a052cba5356949103e945cb4da21c0ccb16b6542c2c382ef5a2935a1e9fda1451ad5907f10486f4060afca2aa4aa0aff201a49b403454d7cb4d29802884986baa3ab96280878763b51e197ca4c659d704327dd8a966c10e969ce02af81411f5968e58490de59e730ef83dab89a3a123fec9cfc8af360e27a961345dbcba8f78e322cee41079ea15628b1c382e9f765e17aade169694353d0956d87b0387bf9494f6c3881d58ca9b9558f0bbb18082d4539b747675368823213d496807fcce060c3efaa8b5b5f6abd204ff9edff6c6a1c0584908cf483165a98865e785fd0a96556c27d708bda67b057929d6d4d6913e9d64e90838b92a86addd526a9fc0135d4c162f216c22c0779bf7b0e0086e014258185b8c2ca2ddbc29af6c7bb2f3f39fc5e77680c6e0604467256477245307b8367ea480bec0c23b86a35c937717f30d3dee87a46283e75f5f3f78c74071ea2764f53f66b893f123412be41b12f8efcbfab0f48dbbbdfbba5f899d0a27ba656ab3d4f16532372806f5197b9ee60dc89b69711f88997c8c745e08fc4d9eccef93a7cc31576ea9cd0670e2e017ac84a8b2aff23b3b240e54e27046cd469a25cd2128838e8bb54a218ab7a09e0aa409576d8de1d68c30228151b86ae33a215674cd059defcde2abd498c71fb1a9a2a1319776391cbe97163fa15232e47d7c6508756b25eb81563c12b17a3477eed186bba073571c1e766e54bc79ec58a23b7a7f8d611ff75b081659b59a4486ff4518f571a8123c6545d17b200b75618a7948a703b46f375837b33f3c810b53758ccb5a76b2859709bc23da25cac032c4153fe1f3e1643018b41e733f285adfd6c392ae62d444f98100b6d22b8c3240d21ace2d1f71870eaad62cc139208548d7739920055a703de7bb49818faac984b8874c9dad3e61bd2414f95ea476e43a4f2236a65511b430345e4eefca155816af2bc16229f41cef905677a5e786d64a790bd1b2ed61698b4f92a040fcd5a896a2de9349739d5b6ad2595e028ab0ea570b21ca1c754ce95a6dab084b4a70bf18f2c1953d698770708b1c42def9becdcca4c06f3357205460bfcd901a1a0979c4dab3bebed5bdf4bfb2b7dbc968adfa08879f3cbfc96a285521c4d8fc553eb31dd84afdf382b4f5a86dcb40db0adf644affa4387b996601d657647be5d384801ef5d841da65c3fc065cec94b333d5ad8a03b89db3ec1c4c21232bfa899cc079ff59df4fd78d7216386b88e462fa40c8ba7b4a30e61f0f0fc8cc4b73cca3fa4eda9a84de6444ec58e6e338ec1747fb15ec40afe8643d325e3fd6073017f0855ab0d994ff728fe242112aff087133da467a437f29c96d0f5a9c7d5f3e158a7c9384d10f4900f015dfb1096500586da61f10183b49188971c27e24aa620a564c2128c828653981fc5e9f034e52d9cfe6c6e222d50c0cde28d2206d19f723a42f88524e7b98b9832c45bc4194ee070df3d9081639f5b91a6811e9cd52025d2d259720de8c4529f311111d911e2c0a6bf4d5294e2841b819e5d11b043d4b0844f5d6d4708901197b5804f4756917588b02d97a18616f43e1f88658cfd8a863a01ec49bc3c8c833290876039da4b4f7d48d68bfa6140a6e4c22f6503d5b15a03bde980d07cf2cf6a4c6cff391abbd24d494e7201feac8c3c4668fcf9565a18622682be0884ad162589b06f95c288ed290569cc527e5425e31d2a5bec58b53cd7ef507840a4162e3be4184a3f496f75049f55a3491cf8b1a1ca017699fa910125cf93eeba2bddde17604152f9d368bd8cc334130f94bbc70f88b8ef9178332b48f8a4c38f60c21778c08efaafc4850e0b819e68b84106e6b1fb2c99cecf181dad6aadc3db7ee7a84efe5d0c9d42dfcd1696a2b7d0eab3ebb258768ed961395576d5e84c958ca2112623875b7d998185b5844901b6a1609297410753f91e9a94361cb1617ed19b9f8e272710a1ed0981102a04540872ce7765c9db290be76af87d0efb2b0aa928e85a54be50626b6181b9ba7526a7d45e4ae8aa828d91dd917ad32c319e5a0850abff1c4c8f2d690a0fa46d98c299e91131279ad55fefd96a6031b728589c8df4c3e097568eddf76c40a6cad256d3447942e4b0218958d2363b3c38ce5b6020df4ccfa1ce2fae3892b343aa84251d1ac480f4d218dc481b3d23c49036408269c428eb5c399b8696bc079662b0c143bc562840b41829860738d3ecaa3092aa46b772cbebcf497101da277be91c042174423a6a7538368083044c27453a7469c5b2ca7c35001de8b6ad60d2abc0b3015a1a2aea46b71af2f0509e61201830f9aad4919e75c0e9aebefbf58ebb7605e942c6b210cf9129b434b999f4074a66249975cab3c23e9dfb30db820d7e629bd8d14adfb0c32bb144d2d2fa066ba613c699c469b90ace8e6d38040815ea69e575b1bc4de766023fe3b2b842a1a7f77532539d992f880725cf03767168c21ce1f4698e0cf5888c255a297731c9756795c5cdea96f97e6f28a741e310dd0e841eeef5debeabc71081ae5cc119b4484b5ac841bf61cb3da27b553f1db4968ef64379c46149ae56159243910f9c30b14c9cd1e7196a4d5bf18950333e8c7622a82d9293bb4e615aed431b40d7cb30132fcc8b4fbc68b361599fdadd228fd701ca3f44a8538487150b9a543190867d0c3b91bceedfb0156f4b020500a02125aa8a7766662a41a32fcdd3bb21a58d94fb69470f37f7e43585b0bb5450c0c9da0b88e40df21e3a12e1b11f17e223ef98829854290c5eb9fe265f860c3ec79ebf78a6921dd743daebbaf151922babb4d43fb80164937be03651dad2692c996fb81bd8ef6cc7b697d9dc47b3282a07dccc95014ebd3749bc4fbdeef468de8a5e9653a27464b4fdade2cf8daa1acf0df840266549205902376a65f295018b5aab2637a5362076aff10cedfd0d788b503bd09413b83b476e06510b422d825c62c3870dfa33aa514e4e791f3b64e293f3451900e98c5807c9f844cd57607d89eebbe71a70b85197b206ee6c68f243809488281bd00ee03758334d8d1736c74e7de7c46c1227f22c4273ab16a1f4423211550f8e96b7265af7359478ac550937c86cd2ef4f3cc2cd6618451f9c5e8c01a879223118ff7e499711cdd1f0731b70fdd7b5739cd9897498f716738b038863a50b25f5c6150c27c5536615ebf828578a29d23adcf516f836e14772f93ee6bc694f69a845f91b3bd81333c97c907c8c885822518e06fd035ac09e05a7a3706d62aad3466c923578a5746c79041029f45f99f04d4fbd003bb6805de9a8576002867b3d4d4a6af0197734baadd2ea3e903aa492167acc9259f227f84116e45d529279031316f794cd529db374cb3e59917da750ead0f3b8e9b68de0436595ec1a214ff3d37dafcf1789c65998c049722c5a4d95db7065f97b69a7e5dd57ad1e6ab7f8af21d4d5f5dc042aee323187c7e4f1d82ce11472fbdb1e2f978027dbd16940dbdff59a1eca22147fc79cf57a163a8e877d8723423e27e6c6eb13fd7f68a5ecd9902e38d0b9e6866cb01c3bf9ab89bf3160ad2dff4e9bace58f929a8676e509a2bdaf6ff9fc27a8b78971447af602f70e669ac636e62d715b541017ae194964ae5c2dd7157a8572f2417c9b89af50bb9370e87986bdf96b52e2ad0469dd3db86bea32df576404da3f3c1f5a085f7be512b24e0045e11393be74f98d2660cd5c94589360f152af1cd8a46e4320d1e885204200994515879d601eaaac3fe8c518bbad5b893b481fa43261a3cf89e14b9e3b8a928055b8b53ceb6b5e86bbb20c76ae3d9cdd002078952ecd4b89acfc3465320d6c75a7cf815dde49c3cab279fe8624f8253f98cee7519998059f6d514bac27adba9fa7b99ea998a6ee41b3631b906c532d7be0fac9f2ed29c31c99e9f30edd132f8df2650e7aaa162d21e2c1e4e2e9ea81c6c085394f7b9d706adbf5d3f99a0147e9ac7e4070624bc6add5b9f21eea422ecc48ae550b27ff94322d174b4e4ece165ba3c02b75775a746ebd046b870be555d1b636acf23b9ba4a5d7fcc7c297fb6c17356de085ba43c28208d1aef0af1488cbf65337715646a7f23381f54024f8bb9bfe387c422362ce92af0e2e2de5ac1a84f75137cd7c66ea4052981ce51a173afa843b8e7dae610622f50c51756e567645d189fdf3a5fe0fafe1d2c56b11d531d62679f10c61df024814dfd95524789ccb24469ce1280760a9bd26fc0754a477b498fee0a81c53ff1cb26ecb5f33ddc867d0fd12a41c787a5c5919e0f25cbf221d67be6a12a4b05adf4dd869befa1ea453723a4dde1e3796f2aeb3418d33208b9e8923bbd6a925ae94504a98c48b7d6127a84cc4141a5161136bc54d0dc5069af5416d383a8d12783016990d706720707f85e8b4aa178a726328e9d5b003468caf3b8cce020dae4c7196cea937cd1170f3a4049db8906257e6808ea8e0cf16051474aa6d5db0df643121c991cbfa7c0291f5591b572f3e8fe36df0a72cb4b6d9e69db7f32a1b5fa21f30a99e7742c2ccb4a1c850e19cea7e11c394c178d5055d15c0b490cd15980b97082a1026438dfdf962f14b49edc5654f3ab2a972dbbd0125e324691b711cc37b9de1445ae644f02e4a618a70248b3232afbb332b58508b7068734f523b6cf7a49211e2be59f1cf3bb2ca8b77f891d76fd3fdd820ff9193a7a5bf067e39d55814119920b19a3a8fdf5434fcd901b8565257e60e404ee02617f3d3565bfcd90f0f16a3538d20c002a7ca78580f645b75514ea4bb5076de34a1a8e05657a89830f40db422bf921d38aa287489a3250d922ec8e620ab0414d48cafa09e28f54a24ba82ba30d37174ef53ab0249f3759cf608797cc14c1ff88be8ab0580b8639eb8fccbe8d4eb298cdd5c6bb4d6473024af389685110280d6b3a39d3395132b120482b223f1040bef91ba9a51f9fa287a49ba5a13fd591f6bd88d3743d68a7b9300a984e0790aba471a66ffec552c23ca2fa118d6a5b987910706cbdd69a486b7bef9da44c291e06fc063b06313186d8f7c3c418d42cc5c499c730f39eb731a9598a7df8b11e91490d8d09bc813071e63dec391613675ecff33c94f0610fbbd94c883d6ce6f5d82eb4338fc77e3e3fdf6d5e4e9d836a937312a15ce0d7796b42a75befe89cec797cd338f43c7e3d3c1ff2bc4b64eaacef1199d42cf57c90c8d43dbdc5d455624f55cf5550f3fc27edecdbce46a82f7fe622942acefc9bc6d7ff0c0afd7e2ace5c54caf23df84da38b09161969e8c811f5f36a967c9e3ea55f7f897ecd51a7599b4f4599a37f934e3427f4d3c9c70728eba7be8f8f9028b77ca65396a8a5c71f91871db25ece66f5f4fc4d6e053d8f413e7f9b4eb29757b336e98ea74e198c424bf5652293ecd52c057d159964a20cba62da216ae95148ac0a9fc7f06fb24d28cebc6f1a6515cff3c823ce3c51290b4379393983d223fd1ee9f37cd0579149cd6c845a79ceaf6d96ea07894c136ad6dae480ac07e5e5666dbe8fe5599b50558c21776380bd3883127bd8c744263533a5fa24f0584528de5698383ef85085c33139c9317c2cf561e26c89be12cfc77efe9134421ee7135c94d8628b34c418b05411479f8a33a5faf4617f9b57777a5ea278ac17b35ed4accdf7aceefc9b0775a78735e57856334bd2e64472f3363c6b722a7cc970b3a6356b73fe043cdea69607d4e452480bca44dff305439995eefa7759647fdf161b0c7b4e203ae1ad714ddabf67ffd30fdcb3b945ee98bbb9bbe7c82f94f6b21074a3adf0e94d2ef2e9799ed771e9ba07ddbdfb29eeaed5f99c1eceb1621bd778e6bc5c18267415f8caddf89c2012286bfce0d75b1d7716ecba06251465a2972ebf2392329162cfe3b96e0c24047ad51b912bff25b6d0f7babeeff55d650c14bfd7ab07cc049e87895866507a847d8f30d1a98e3cefe46316d86b01c76623dfc76c8f12b6e4238fa885069e11f672f45eeffa91d9c8f779ef1788e27e1df0142d6575326d3623231aedffc5535cd77b52dcaf0396a222287a9ec8ffe01b0aca2370ceb682f2211441d99c70b6d4bd7f27fe84e2d177bd7bcfe36ce9fbee3fb1136750bed777e26ca96302bffb9ec7506acddad6ace1a6d3cc9a35cb238fa0e5f1850b5fce3557de239226614888898a614191b34979141027e02c9146e825411b13fe98f902ce0e428408792e4fc1c9f2469d2ac8d00a3206196974e9fe66f7c7f31596a5e5237b240a595a0d4ac1acae7a66387966e5b1362734ab2bf975df045dcaf3bcc5988d62939a6058c3d8e7dff74d30ac611873a344886be8c8a51131024274a402b18542624262f2f2e87a8c6c7f934878a40271a344488c687e3c5fa50dbdfcbe3b12abc2fa0eecb67d31900868439a529425b3d6555859ddf7816f5b625465456330269ecb23ea9ec2604cbaeffbe6ac9d6d09cdf57d0814ab955e61dda615c6e4fbe073a254ad8dbec21ac6c21a86b1ef0b6b18c65c9fb4739c9ddd765fbbbb7bceecce53745dd775b3737767263289a6cfe95ee7eeecd2dd6b6766767707634176a89c6efb6e1d13cda75fdfc9cc36afbbdfbbe77ddff7cd2c14fa73b9ac9cd057adeefef96466ee84be3dcf33a27d9e47f43d337722d3917ddeed664fe8e3c3fc7d9e6ce3fbf9ece705d5cfab554be8d03c2be4791e1da5363e77f7aeebdc3bae1a92a9999e85c215d84c347b78320fbdea6ee544ea935851bcd9f9fc1f9d4fcff33c22666666cff33c8fdff3c0392de3d073cff33c9b91e7defff03acf3dac28d2ea63a2d9c373cf9bdecf6fafba572d71b7799eb7867d8ee7795ef53c4fc9ddf0bcce465d22129d7be7eedea921474ee75e97eb72eee5d49023a7f39c1a72e47877c7ebbcceddddbdf3ee4cfa72a7b6ad7aec2a3933cac509b5867b97f32ea7061b723af7ba5c97732fa7061b723acfa9c1861cefeef8634de66e29bdf33ed0f5a2151663201893ee8576b88e3aa52831295a563c55575655c5b2b4d0482c8915e4f323036b4ce94a46c124546df3925268e41ab906284868c7acc7078ba1c059ce63636267cd28a50965a5d34be2244e268331f15e36c4c34b7229f06f422e3f90ee8582e72098211e5d7dd14a5f3c916a1f4d79db73b7aa575de5790ece32b14e43d2e4c7608d85c5a4f301c164566214b22614d4cccd35726b4b6e493bb8de9a503cb69f62ed641b06eba86e2385a6d7f41a1e3c66104827336a424da85966464da8324ab3165454b7fcc5a5eda6bae53797f65475cb5e5cda54d52d63e0d2aea2bae52e2eedaaea96ad2e6d2baa5be6e2d2bea2bae52d2e6d2caa5bd6e2d2cea2bae52c2e6d2daa5bc6e2d2dea2bae52b2e6d2eacb8b4adaa5baebab4bba86eb98a4b1b03d52d535dda5e54b73c7569bfa96ed9cda5fd4575cb545cda6054b77c814b3b8cea96a7b8b4afaa5b96bab4c5a86e33b8b4c7a86e31b8b4c9a86e2fb8b4e154b74a2eed32aadb2497b619d56dd2a57d46756bc1a58d55ddda2eed0c54b74897361ad5edd1a5ad81ea16c9a59d46757be4d2de40755bc1a5cd81ea96824b5b8dead6c8a59d55ddc62eed35aa5bd8a5cd46c7e90ed4366ad835f937effa34d28fa113dbd857fe38f2a3714d5862608241022f5c89800b10b0f28016aa5071000b2ba830e5968294063060010a4800020e8082010a70020106608200a204000a00964a20610425114200e183271e74e08483264c36d060bc4b32c0e0022549922cb0211d2139520105468cbabbbbf316a28798b28d36ba8d968ab9bfd79d06f6647ef77d84950662281379defcbee979a02cc2b48e91684bb848ca2ff2dde9b74adfb93fb826ff06263523c9bc2542cf13c3252c9b4598d6305b9df0f6dd298e725ab594cdb2a54b9fddec9cbae1b9d7759f473f57d7d53bdfc117ece592b4a63d5c84f2e7cd8a48dd6354bee47c5a292c84d5a758aca7613c62b33b9f863c3ddf13fa589f9e1ff1c7072802a09f20a2202021219a50d08e1db51d42329904b21d43434386643c7810e131349b15cd78f4e831418f990f1f457cf480000223087cfcf861e40704ff14fc0f6b2bb02f8a47441b410448221089888e88220002040908519020b620408408b14048101a2d8926a4564b52a349208112096a43865c304402cfc31e17ea2194ef44ba6ebe5b90c890a20c8a883c4d2075e70445628a4c51640228a30b1815f912ca77235d47c59d6f04340a75a0c0df29303255010554472aa802c991aa232456201d5d6143c2c2025b164916689124690b2549b8b8408915061774910106185892811777c99bf17ea1c108c6061a84c16483ab264cc4e0a0c9184e3820a30327703ce8a08c271e98f1c1933340f8002b041032204208682889a0811194d22061840d94400207964a5003004b595000b04600a0b0112500710410458e0902e8c0004c6883000370e304026815e084370c5000385030c09c03a0400701078823010890430109f0c00214b0c58005ccd10006d491d2003a529062e796c207a6dcea50610adf5941051c0b2bc8e0001666a0e2001aaa50c9d242951a1ed082162b0fd802012b4e2e40c08608b870c395087079e14a1709bce0050609e0c004430e31306189e1cb9d4f9bb0e8806bda41061c981964e0818619c264a1414c0d59a0b4d4d0c3162d639cb690b1c1a9cc0d36f8c0e506335db8fce0a54b140e5e80c80187209e7210e2cbd3103a7c39b3830e4480d9010d0f6072617828424c1823a0c41cd103549a313da82133660265c820e1439935667c48e207331488faa1024044b1090208258408c2024308b1c49921da107186093444349143e34411b9278c28028a238c88224de50976e823604de6953db8b0af144770cb59344111232314547004c91192cd82a4244a2ec020832577d46003264d3870d281074f3e00210411944620a18425004009401401983000029c500003a07000042440010b604003a4a4709ba2c20a2c38804a95161e6005022e44e0ca0b12808129062c4d8d6b197a86a6a1b3740dada5b7b453dbd0373497eed25e1a87cea19ffa4bebd03b3498e6a1c3b49886ea1e7a4c93e932ed439be91f3aaa81e8205a881ea2cf34118da6735d441bd147749a58db400748e5f3db7e5df03ba5ff7bf01381aed755a8dc29ddbbc0fefe16865ba1fc39e9eb6fe1ed34d7fbee4b6cc1656f54ae07de1c67b3d96c369b4d4a29a59457fe7dd3a960a482d17c158c5430f2e20ca83be4f294196c5ccae35364bfdedfacb838658a3f089dc856faca96b31bec9fe24dca7ee3ae053333b333b3333333773a5871d74d766766eebae7ae73f7ced9d9b99b13092396396d8eff9c57d8b123478e159e2a030e381f04255127250fa919d58f35c5c645b174834428aba494a449299e73cea9a933da14c599a2443690352997b8a8c2284a92f644d82f9334d9a0d1cb967064514654196ba8c018e2f6b84cf585d4a53c332597f7f425fffb66dfd366cd639a3f452699d734be8d041ea9c87493f9df6cddc86307fe1229edecfb28b3e67dd3e8b2b34f6c81041e95442627de38e37f5d89b3251c55c3429b20fff54bf3ebf357f92f91a9aac55907dff77f4fc599d2eb674bae7fbdabc78631f95cbf444a291ceed266ee1903c5f073d92bb3e671d67cba220c2eb25c0f4a1e71185b9491483d4e0e430b2fcd9def69bdfc4a61dfd4afc6c5a57e98c8c4d474a52a8a94ad2b27597c05fb259e87f53ccf7be21253d087df34de786be61f7b1ea59db9381b413eeca1f407f7d6746e3fe801d9858aa83454fcd0c595623b95e924ae1cc2ef6f2bb6e02e1839a693cc4ef2b054124d029f3c37d9fd6e61d79bb027733a7d2394ba231df71ae7b3ace5f4cefbc029394059baba653d20112e92df31618532d1cda9cbf61dea896aa8eb346957234e727d4f100c4399ec1f8b6fe7248df62f9365792e97cb45eb64e2ca2a9db0b0b0b01a8b7e7d02c13094b9aa8bbe948934f4f2a97c1e6b2f264549ffc65b208c8a4d66ee36f5584fd3794a79c8befc59a59bef6f9c45c5f924aba4d4d02f99435686269c35d9535de22cf62c4536e2a409e34002512130e8a78707f6469c247b17dd41bbbf4929100c4399ec9f8a4de49589b3cdcb29ec2c4993bf43149508c127e992469c249b8986aae20a893723d7f5af9732834420d187b3c450bcc9c498787b176751795d4fad1117b9c4998b612eb1c9bc3723f7c65946f6d64d5cf9df7472dd1b67dd8c48ad6bc4d7ec90426d384141444e6611071c4f23953858a08ed448679d39b8913a9809e046da51255181a7917a5a4f1880a30b2a46262c3ed6185922c122d4441d4ae046ea22838e0dcc31d217951719a81a29f522aa0aa79156aa3590801a29ac8a306f9c461a0be3ccd59b3284c88d3484b2c269a43d555a5983971bda8cd4a74a2b6f0033d566a43f55daf6a2c50a6aa440555a2639068e54165b231316a6630c183a46352278995822c1c27696787a625433457653278bab910a0505350b0d6141868badb1a9b1b49c5274de2a7ffe94190265a2e99dc8d414b03343d588e5cb1a418944ca0b8437f082b3366b73fe1499769041c3184ea38bb44e62ea08ac91ce9601ea8ca7715a1e5b76179f349ff2146fde688db4e1ecf0343a9189026a6434b49863cdc85ea8c1658db4ab9de53034f084d548bdda5926b6620b17592396971458d3ca664b1dcf160b6c8d1dd8d9231ba6781afdfb0ec8a00b041f9c48af07c16f4e127611f9a078035d6e6f4d13c6840a757710743d88f4025dfcb2409dc4254e9d51c575f166b3048d3450c1e1264c8479b1dcef13dfd288e6cb3a21e850d0f1191599e01675443ca1cb433e095c354a8309e1711ba4c72d901fb7444111ec1087ecec7dfcf80181f511410f2033213c6a6e8786b89515b9dd51c4ad9091ea3688e5d1e74a96cc9a5ba0fb592512897c7aa4bafd71eb73ddf6b80def74cb93d434a9b36c01172555b754092f91ed16bc605a2592e6d6ddce25d52de0a20d24136fe2512d0e40f75707b5031813ff396b375b22bcd96c4be4b741a844d6a407b127e107defd810f08402108892053e2e1a30704ffc3462012050122a4469380c890a22213185160a40224478e6c481624495282c10519dc25e3061a30e1a089130f3a7802c207212889304209242c410140000410c504020ce0040314a08b1214aaad8b94038049c182ae262500cc6d0164a634a08c0af24b8187156a2b619ab48069720aacc9df166d6156a86efb884b59a86edb884b1d50dd76119752a96e3b776995eab6d15cda4275db445cfa80eab6cf5c6aa5baed212e854075db425cea4275db415c1a81eab681b8f44a75db5197be50ddf60f974aa0ba6d3397c250ddb60f973255b75de6d218aadb26732996eab6c75cda54dd760f9736aeba6da84b5b86eab6c55cda3354b71de6d2a6a1ba6d1e2eed2cd56d83b9b46ba86e7b874b5b4b75db3a5cda5baadbfe72693b55b7fd7469db50dd760e97f60dd56de3706973a96edbcba5dda5baed2e97b697eab6b95cda3854b77dc3a59d4375db365cda4fd56d3b5dda5faadbde7269eb50ddb6964b7b87eab66bb8b4c154b79de5d2e6a1ba6d1a2eed30d56dcf70698ba96e5b864b1baaba6ddca5dd4375cb772eed31d52dd7716993a96ef903977699ea96ed5cda3e54b74cc7a56da6bae53a97f60fd52dcf71694755b7bc75690351ddb2072eed20aa5b96e3d216a2bae5382eed21aa5ba673699fa96e79cea54d4475cb705cda68aa5b7ee3d2ce55b7ac75691751ddb21b97b611d52db771691f51dd72072eed34d52dcbb9b4d554b71ce7d29e4075cb6c5cda4854b7bcc6a5bda6bae5ac4b3b89ea96d5b8b42950dd32072eed0a54b7bc814b9b4d75cb695cda4a54b7ac814bdb02d52da371692f51dd72062eed36d52d635dda4c54b77cc6a5dd4475cb665cda4e54b75cc6a5fd4475cb702e6d28aa5b26e3d28ea2bae5312e6d29aa5b16e3d296aa6ef9ead29ea2bae5302eed0b54b70cc6a51d51964a18810a19618a4c0385301207ccc1085c94c025acac586a49c90acb8c0fe8a787ddfaf77137fbfddc7d7252c7493ccfef7152ecf93f4e82d5245a39097c7e588c87cebff99ddd9dde9ddf9dae3befbcd13b937c7ebe9c9c14fefc0ae3a4eee7f78909bfefc702f9d820a11db2211eb31e3e20f8c145f6878be48716c8060971917c98ddc145f2ab95d9211e5c24df6567b6870f2e82808b7e70513847e8a325046f70ef7c6e3e746df5d33365403f3d56640f40a1191158055cffd9e38621c82008be3b7844d63e6ce3e9b072b281067707ef6024215c936f346b42180909c968225da6f20682408420d8b91e04c5255cc27ea3b9c112ab1c6067c8807e7abeef6fb0ef6f3c975fc9f79c844e9077f0e922f2db0235e9a16fc810280c7f5ad18822b04cb907082491be9f3d74a875228f1c4ff4ef867bcfa7dff7cdceeb3a6f4eb71fd0f7c942300462d9114a248df6830c30743a5dd7d3764f2783a083a1ac7560083e4f36e19ca1ec3c91e6855606e8b5e7303dd91e967a267c61044366c92c999925b364e6efe9f1f1f9f9010262212166e6f7616666c92c9965b62b0b7213e4e60aefce095f96b649abc08856011f3d61da74226936224fe4d195bec2e16433f7a4311294ae4d6f9c6d2d1c15a564b9137410fcc0cfddfd7ae715d40ae378c3f7e5ba9e573d8f525707e5d2939dfce4d7e5acec48a4be0265cf798393389136f4ec2b27b0cec2ae14abb4b4aa566b85a083134b6ba2f181adf9665e4d2bf06fd3ca65acca772b086a69b95c1de875567ee12227a943c3d045dac0a38cc2418eb9f3a5d60eac500d23358e6bf3d34469219bbaa184e2ee88229c5ef0d1f7f367183c31506792c1488d9bb54e72a58b4c99a881099b6df9ba6ed7755d57ab7ce224d95ab62f5b29054b279836ff4a27e9ac2e327f5291c4c69dbce5e562d157f24a369cc6126d17e1f7b7bee24ec6401cce09c411e1fe65681cae03c12f8cf5f490c964412ebfd86f8f6060da1ce2a32b9236e9874a12063e4ac2b4f936499b4fc5bebaca5aea22f33bf1939fccc9237927903b5f5ec934241288c5664a4581bbb2ea4e09e7ce29dddcf99fd7754f9ba58c755d8fd2446aad247cd44eb491b469158b6959595ddd97e5d13949def93fd2ba6e8f9ab07b29a5c4698562ccb0e6b66d20b8288876828fca740f4c9bdf4e5dc79d6dc4937438a14c82651a4e5ac349f226739cd473e7576935919eb8487e895ae2f670e7d49a35d87d59394eaab0b55aab2b623271678e8be6b3010317c544ea37e600e74f2d31c29bcce5e60cf3ebb84eebce032ef4c8c3febeaf6777cb29a79c5e85334ff7e979288fe6f7ed5726692e0508ca99c691c031c8e5a90e7820ce9bb0839801e68d335371d87ce1431d5f48b065482e6808301b000347ca0d38fe812b26cd89ef14bc9812238e1c3b5e9cb1f3459d26a82b78b89ac30cac2b92703a6850307903079c115b561c78c2ebd47e38a18a34e83c3103163f40f91cb20f813a1abaaeebba2ba400e38501e99b31a8cc5c5dd7652a33767290800b194d703953070b0d0c31856f8121c7240386902cd8042142881c5f1c088c1a0f12c82185a03d5138b2b429734689ab37ee8120564c2068524b1a566feea06163ab8c91d11b2a36535084e0652a3650c83ca1cb546cd0b02923ed0ce94172d18137f241f9619b3754312e6f5c5bc891f2b6bc19837e3d2e538959e2d2cb5462d208d1c1853b45a46933831923d6c861f485c75185c5962f6e8ce12285865167bbec4ebb42cb04be2d5f842133a9c4784165460dd7130d5da6d222cc7d5da6d202897b7ba32e0ca3967d6c847e792a8e5518278b2f0edbcae16a035dd6b0628d71d28983c5957d5371a6be08c3e9727dd3f5bee9d20f7ceec1e3846f078931263227c021ecdb5dec56e13bb7fb5825e2c19e4c97074d2d806fe5bb9ee73df1264d37d9c47bffe941d3ad12abdd7f6114c19dc738893b30dbdd93bedb2332a4e63fad4c3e99dfc4e7ac83babcce05ba3b0cfcacf5afeb5ca0f884ef5cff2a3ca5bb4feb60cba9efbf8f69a44d63bf27ce963cef9bc6177fb5209bf0065e998f2542975113e1105c1c2da5a858d162bab245e3d0927ac24a85b3a54fc9c927ce48e0d1d634468d4c3d766ed6feb6992e428544514d59dd7e6e28cf93603a2bd75abdb50667e6de9a4e63cdb937994576612c293d89bcac89227a0a2594952c2325a3726fa454d59a36b989c4e3d8df663a89ac52a68bf4f3982ed233694796813374fb659544aa61f5d41c3797cdcdb1e6c471a9141d32edb3c7749996c2658143ceed3702967ca8040c1d28a95388460000002011400083160000200c0a070422911c04e248177d0714000f65783a64523215082391381848510c84530c432110c22086102619320ca2191b5000fe119b2f79ec20e98583a718e11691fa39be5f84663d1e7d5568c5c2e90c46c61fc91f537bfc407132d6e8571cb37ea078d81a85a8fe08d532b182b5998d69013d9c71789771c5122b9c17527f21b526f5b4e6b465ac4ddf395a537c3198b9296b86b57126b6c05b3df56f9fd74c84817f9900714e928259802658f5a4ff6f9541ad2b84f154e13037523a695e9f2754a5deec90a13f335a901a3be75bd0f54a724f810c69536d4d04212658b9171312f131e35024d4432e96ee8ad01704a843c4b94703ab55e0588fa1e8a38756627c2b9605bb7c5a310961b7cc6c6e78494891b7c06226f1df093469c07ccec0b16e634ce30f42f44c659e1ddcde70e4e3946f8b495d6ca37752f85236b222e838da1db0239b2390acde82ba8f431446d84acb558c7d2889d50fa64209075818a604537fd45d2ebd4fb748845fe54049309847ada679d79a6003ddfe933419ef93dae1aa41667381343252e3fb92ce76e1491e6b7bacc8b7393f999f6259c70412ffe03d4f3515225a586a51d6feedcf6c36189bee722c5839181998b5a1102b6e411e603f7f0e7af2cdada2827c62e90268448bf44887012665473272323d353ad65e207044bff3b76984da6a5584a625ec990dad613f477212189e01be8c37d06c80662b6d2ae4e82c990bd296c850da2f6ebd3ee6b3229660410843389ce78222091d201fcbce0ae0a4e77d2e330c15cbf9babef1e4c62485c2818e097c08ae0b90b40c5a02d552c262f557b55b37ad1f6289b77dcc81ec3d8c4dabfe0870de6b9757b0a7cf1ad492d8001ea9ce71494afe960758a8ec0a4d180334b21db9e049b1be4dac63e01bac7ad1c96e2154ca89d4d63d0775dad7ea88266ddd9921ff03235860c870cf35dc2553f666e9f5a1a359c544021f178fb55e4fb2af9a357fb5049bfd32d771df33cf334f0fed50f2e765404037058271620e6312754c01d375a736cb9e2d193ea3fb8e1776a82a5f2f9bc248828593022cb73661060810d2b1ed123fe001af3340a59303ba729ce3c9ca6ae97c74964e9d87fbcdeedaf805999ba5a38d6a3507d9a0d81f747e7a67b1cb4309e6bd7709f4b39176940d24ef7bb9c43cc8c240fcab1be31190c652caecbd84b3ef5f8c071c7f4338422e878481383f05dc987019d0232ac0856628df9a39c756dfa50b696367b4da19a9c14636c2d64af06ef86828383b3810c10601af19e6e9e9a52e632edd6502a897339fe73e4ff7f794598e517d9a8980d3bbf67959b26054563f2c0a90fd2e6caba6eeac97811db36c4df002c306c30c50868753b90adf445a62d87c71b5df90056e6506f3fa22b9642237c7920c04f2ad66a1dd70e87efc0e440b2b37748938e61686ebcf81f62ec716c6a449420785d09109fcab8211d1932523a47fb19207ff60e606f1f0ab329a71b13a23da45c5472f9a860dc1320e71daa154cae3e1ed0c26f0cb99c080e91e746fa3f99c4781d35c713a4b8270a16b712e3424e1e4ac969caf2951c96bac26d3189f5db3db9b95d41d4b0d9c465954e5a5a369035256e239b3153a57238a030dd19885b3501f60d45fa02b4cf21e2c4079808dbb9515fd47f4894987c633d1ad70c06862f42decc13071533f2c63a1c685854cfd38493f6bc9e5349b871eedb7e815f5e1520a3f31f6edce2280bc18f5922a8a170b152a5624664c55f1bd2a8c718590d154b03d03371f2f34837e1a926e954fb68cdeddc55ad52aea3d67062c13655f44d7978a1483347967030a30163b86a010ec9a4da939b3b4cf66d5ccd293de65caf3be3f1e2343a37fe7fdf05125815cac8b55ce2a431633010d481c5df059d2be3de0718ec276d215b6321612428f87c7c4617cf6b56222519974dfbee97734e52b1a3890401833e45f2f9fe06046cf8b81ddf2be892545fb65119d7887e95a257dc4ea2640d781c59ffa767c1e10be6fe4da8f33798c84612ffcfe3548d501d4bf576bbdefdbf43fe1f77dd4c718c8f755b895c6365ed1dbad8381a20db3ce8325f4787dae2bd8298b08eeeb50c4b25ad4e44e2d97f771f81680b6ff3c468f26eb627d0fba81bf34dff129a0facfccf1b71d8bf35acc5a75775c4a98692999208fb8f27e6ac4337016a171b90f9466e4f8e9ff72e6f9e3907eb2f29c5b817f8c01a5e11bfd238ffda9aaf282e86f70e87f6e79fb036d285b5403785e019e3e9f019ece2a6c0e59f8bb2016025be3ee1e29940560bead25b3b381d3919cdd91103a32f03a6a3546e8bcd9115f960cbfe89ac14a099df3f3e7f5f3a005f4808a3d26d2c1cdb5f0fe3a6122687a55a1293b2d72b80ba563dd0b9bbd481d32572cff070b09c5adb6e4aa242db23c49688e19cf0c895b090a37c160276410ed5723ad5afa835b9f3d1eb8a3df8691871fe4795b9968dbbb4decd698d8726e398ddb84634e415354c3b88d2d3459d23bf03de538685e1807535aaf341b2fb70919a90adfd36d82e1a88a089da0996d824e814511a080054bb6b2d4ac78215e90654433bbb1b1fe4ee9c2064ade943968e0d4cb630296560a2c4fca83eab3560828230277eac1d61224ac55eee676f298149e6772b53266bf0d6b47359bd004df6a2c534fccafec66bb18a65988d6ac84f566e2a40121162c11310c0cdfdd645f69d3c7701947a82116e12a8a94ffb363bf0e9b30fef63c3acdd4615e567fc8c6939fd8e3950f0fcb341080306317c8d97d6a716da352a5de4ff3794eaac4a0343a42fd5db26c349bcd80bd0124260d57952ddad545980fea828cc28f0265267960d8f89ae3bcde8151e1812e8c5510a2c4fd21aecd6e6dd6234482f83a5c1c0cd7ba0f6d7a506b8a4ce3a609b4628c9e8a2383943995df99fef146ce42a104db1061e4677dcda006328ee7bc2771d29ece5f8971c56300fdf1d3242868c845974b551ff2151a8cb280f0cc2075b8dc2d8a5806c370d115a20a9c546f3e9d998b7c90fe3306f558c6454d207ae51b0a514e579f05553c259a83217f068c3997434c6a307195a4ec17f5dcf04f137ce10297df7114f4bfbea3baf0b8f25042b84670a94d90bce6dafec1318c481d7d25e4b155181af2aab2b8ffb1f4551544d5fa5e16c8141d30cb5fb5a9dd00fab5f9bb37bc658009b62bdc7b0bfaf34b4a4e8fe239ead0968fab92a73050ab64d521b0e0a4656ec944bb35138a1a3e33f369f70980feb26c69a124c407824ebc035965d114ef6258d81175d3ba17756db5d69e5a0b427f039c7640f8541b8e12123d012837a8ad7e6955bc2bc56bc5826a4538bdbeb66114e104cdb134b3e0e15d7f58978b85f5c5d556515b54b7f52c67b338e3ae502e93c3257c0babe0b1ddd8e2bf86fe995403c4d8de3a876b92a8821afe47f812138cf3252ec9be34b3e0a6e07f48f6d1b881316c97b81dab215dacac75b80e40552c586dd1f2ef997adccf62932415d645de4ae27ee25beddad8a34e707de5948c2d559fd4b974a0644da4b64b54da45f6288aac52d9704c38cd364e5a46a25252cba012a1c8c4fae605165e241df31d11be60f7f0d71e3c981f2298dde1ae60495fb5b2165a7580d8f3b32f35a587e4034709081a38ce88be45f34b31dd85232b2b3059b10b22f9c2c50468882d0ae025615cc473d4a14a61076380000701b35e8285fa602dea80850502bef6ae6535645d258bae7d3e269941d8126a813bd24bac76d018d041a6b7258413a49f6b8a6c3611da3c7547a575a2825942539373cf188d96a5e0852e9db4acf01b52c2c29ced8f9f71bd360416c4fdfa9d4b3c152d0fb220e2b12f1bc376a197a4093fd558d2adc3e839fd6050f637276a83d7758df9a3b784cf2492ed6b2eea56d769ecf287db1c2e9a0f453c65c746985501fd6ce3498275c2bd57d2aa3ed12517af954593c6169b794c812c29515866aa7465b4569bdf04a80da439d6e9f6ba7a21edaf63a7130b0474ad4a822d850f8d1553549038f049aec7ad9245b456e8abf8c9eed2c716794a016348594e0fd48f3bbfcfe84bf82f65e1503cecb947d8cc1654278ffa7237b67d4aa97853d04bc9a736629e693d794f6e43711d02220c05c2dcd5fafa8640181540f2f49453ce9419b8dee6cfa512466834ee9e7bb937d3102a504ea62803561aa2084f4ce4ce52010c1a6ccca3b54f5015773f530ea1537f5060370584242c1d845e41a20c709e905e87bde3b6935e3b32c46a951ae533ec7a01a1e2873ab8550d5801471ed35795dced4aaa8c1c312a83251d4a84f276d6a94b9aae182e0b7ea72b184eddd286488663154d12e1697b806e8b8a90ea150c392164183e32afc05733ed8292420c87173ce394774ecd0b032405bdb7abe30529106f868e3a146836661cf7615241912fd2b9f5bfa5c1852cb3aaee8b87023f1555d2832d6db526a460982282923be9d598603f25cf6acb03a71b0d9387f1d655a223b3c47261a677d1808fff37cfb8ff39e7734d73ac7a073a90060cf4447920822c10f4e11f196de8277df9d4e20e761508747cf8d63e62461a431135d9fc4f2770f54674b64a7b003c8bab13812d367173c5d96d8395aab241f10efa96109f9d3cf674dc3474556c461dac57f00cdce6678bc99d842ceea7fb5dc89a35e9a0570ff5d9c91d7b64213f6dc672c1656100a7b3223516add60839287c3e6946b40535ae799aaf0df1a5d88dd611a8e4f5684458be52b6e15917d98e8cd1eccc47ba0cba9f1972d348dfb07c5fe0646e88685b68868bfbf3dc36b261c560ff497e5ddc71ba757a1d060dd0d3e9d8b3c9bbfbf354c460cb8c33d1571b47f97c1de8a959e53f3410a8836d7de7b6d3ddc6aee4d57c1df53fac4ba00de3bbd88ebdd9909f36636db9ec74b7f90abb9935e7296dc51834185b663a0cedf69ad03d0540a951c639bff9f224b25f876a4cb6a7964acab129a6853a2b54eb72897925b5844f589a897fafa40238d3708ab591f467fa2b952bc0e56f31b07efa71851e80e2b47ba2ad49a63265faf344b014756878b8f5fc3c91c0a09954687a2d7896c4eef4bd18951a43253d6cd1dc3ddc8a0c764afa8b65a00087fe415b70926a3a995b113ade89b8a59aaa42fbab28302538926a648caaafff58e306434092d04c233c7ebe0e789a0f1d6d9eae46dd8a6325f383d36e48ef4a6131a4fa204ccefaab8b87d7bb1c91ea08ae86229f364a39b68a58729e0ff2d352393412a547b192f4a14cb6668ae8f380e12d19325182a15add83bab2099e09f3e2dd5275f26c8bda0baa5a28b81721463728ef7cf2c90101d540b12c276948413f0474905d5e7206a8215c8d8e559865a082bbadf0d2bb8500fcba31f8d5139548bff03045de92c42236892de493e813caccb82980b031dfde3ae48ef6bc49c5c6332468f4b2105689c55132e645c9c88ea186d809a54b5742d11c32ae7fc6a0d3038ed887ab7be650817ca585c100af89aa50e25fdd3b7765e7cdde70ff32ed3c32330504e7cf6f983f369018d24fe3f7013cef17c845e5d8dacfa9ba812a72b5d9a0fbe3d9a5d47bcbf67b43d2065587e33508108bd4c53a00046b63ba709e6ecaa32afe5b6c87e03aec259f716a45406bfe56adc8f5e329f1a4b80701c4e9f6ac2a881d6dc126891634a0b77ddc18f214b347d6c692916b5dfbc8414e7c64399628e65162618b1e88169e013c8815d6ba21f9790854513cbe568f00ae14ec9bfa2442ceca8c6ad5c8824ace7f569bdcf5f2abe63745ab65149bc3fbe6c0b5785c116ef208ef017d02f5aff1636cecaa05e09e5bb522e0dbe0d1ed924dcbd121262bc9ad2a6a8748165ba15c542cbea0d5fe81d826c4d536879d1f5fe8584108012736c235bdf7927a704d5bb62d9d947a81058701ae58433890a51cf8e217fc312e5b169ded94efe6b6481aae83cd820cba68c406d27f90f8891cf5c13594748a56c67e26d5fde3d11f37910e98890daa9d4306f84d6c0e983429a0a2f5819c677b2e65b0c472a7778341b25f7f42443d38e0736f00be78c809c5e7c8ef3de915ad25268be88e178ae67bb5da915005260b9c24daaa28b84b517ca3a55d0cba7e0b3c546451c25141474f0aecfc3d10c0b37087c20f050ef77ea44268241aefcbbed82ed3d95871d01df3ac4ac58122415b720ca3115305c31c708ee8df707fa8422a20e721eb102814b232586ed9b606b307e9beb259e7f1aee62038e737fe2b99697c188aa42a7620bbe2fb6c04501a51b233698b5e5f515f191774ec0e9c028ccf5562ee5c4a4fa0f64fa85c186e9867beadd179e8124f63f7b85212459b236622de6454180ac475b59109057721a0826b8d51adaf8866fc028aff5616480418e4ed45694462b7eb5e963666ca921b3e5418354a3bd6ea488282b83b5826c9bdd8e2848176d789afd4f7e62b9fd17e2375203e3fd26366b70fca43bacac9b7d0560c57d5fb5fa7314162be7fb4ec70386974d8e037d22f7fa70e2a7df0b885d1e9a9233508e3012c0d230dae0d2baceaa3be857f4576969d40e57daf6240f54d9f37bdbab66bed2300e6574b711c8b703c6856961c039da44a855cddd5c8e8a7bffc5deddf1c7523400ecca6bfb749aa214f524530011cc91e4422f1e8584c75967d9ef5b8f416ef16af03942ada14299c3d4d70a59bcb40b460a92ad0b239513e7d48f4ebd974a4e5479d1eeb4178d41ee417c1d011242c4e17eacd8249955a4aa9f7540bc5b8e430fa8d8974bd850cd48171e1f5024996bebff4f338f0a024d13262ab3fe56807bfa9d4d5979a5f0b42ab3b04d4f19c474e80cf1fb2e8d9e612723babb57e66d6a326a0db6a6e18b48351d6fa394a71ca174aab190c94ae5d589f04c8f2d9a12b18f53150f2899e89ccb27ff91ddce3345afded292707144e392b581e4849ed43bfc051babf6463d175bc994434edaf9c6789fb9850028b8d74f431a033c8e6763268b4027f1c9108f6f218414ae1e1b1b762841fb748891b8adb421803f11c2bdb12c6a0d42e5d5de84396f6cf6d407092c3bf5c406b1bc1cecd31dd990da0f075eca171d3f0ada99d16145efc1e7da565301de1ed10a915d77e2ac5efe45430a240046b0145f58b75ccb4d98960109ad9263cfbdb598f08694c1011ac47e0fe1290b203faef9bab3fe1f9f82f6461ae1304f4bdaf6e6f949130f250fa0123b910dee0e62d0d3e0dc91a2cbae33d0efcf4c053d16d1233bc2091764ca7b85f29e8e14d2747d8564829f99310d28009c8836e39e3af0ce757ce1bf85c7238f822f29137dbcc37d3f0342207516ba79c607eb919e97a013257772e171eb84da9212a364dd1bf54d7d4e106c0c0be94eed395d5aa682a1f8b8b3421c6b59bfbf11b8bc8536d05bd80da44fd002548db3d605608e0bd664241cf19744d676dc5125effb00810ef332c47d0cb9484fd46715e40f9eb6817686a3084a3a40070ef204b109a11b326294815931e4c86c9ffaf6d0a314788d92c93b3bfca1a1e1733270a194cd274a336678e8833e0bc51b77e792cf4c0e9dc5cf643f2f5d03a93b9dc4025ef80f9443763b77f8ca09c5c5d2380f3f05d29c8c0df2d5a6e49ca33613865edc8527eaed125f0af8cd92d5c0556385ee6ee189796afb64d8190dc57d4f4b8b5f93dfe4d7c07231967daf15e21827c85cac6a977058356ecce0d1cd92f60b0700bac30df9b560702215826dd6d86f07270bdccfd475a912f6e0ec02a5935dfefb1138efd8a745008b223b1886fc8015d5718d48b860db05955b1074d92bafe5823d51344650853d86f4ff773c46aab645fae90714743de5361d050e21d11f9c4a5509ef60eabb162a204d1fb1243bfabd86b7ea3a1da566e56ae370b83acbed768aed29b3b18a45d1a87e23fcf0c550dbd663f581f34b0fd8c8c6e296c0ead83186c62840143cfb76bf7d3f2a70b7cf35b61311760ca9bd6311befacd0281ea17d8a0a6aedccf4d9255c4f529685987d37918fb2e5504d174c4ab5ed72a75d7e4a2d60677214b58f653f960525addcd7a4eb9603793e4305f5cbf7bf91e8b57e498a70834cfde331112142f6e9e51101fae817b11ae2584a8f8aa06213fb39b55027257e7c801c87fee64ba66701d1cef47e7840ece7d085265252be04958ecefe3dce6e3c29c0147d778536f985b43f85f163575d5e2b783386b5e0aea373ad7d5e83c5202e9562ef0a4de9107aa50f164eacba26e784292ea16198d270a14ed60506af0566f77b3cbb48a4f75689ec8861823376d0f7873af70016988a536dec84c6533fa55ef49e277c01b5982332113856c41fb8cba8b2817ea879a3d2f34aafcf73255dcac858771cd324fe60458d3e60f29dccdac5c9a0753a2f7a60238f6bd422853cb438690c929191a91a85529bf1992bf750c630517988ef7400ab85d6d35119be8259496369008aaa0a8af84db509b1c38abdc6d813bfba97c3f62237dc27d85030c719cce17a9fe97eea3e0a3824c159450c19dab45b7a648ebafc68328c6ac55149e703da4d0bad530f4ba28ce731296b5182553000642a9bac31709a7e39f3580e94fecafee734d05d04e2982173771a08f99ddd85506839e176ab380135759333bd4fdbb9ecccfcb4a15d5aca3ded4ee24cc6d3362e39ff3a6d688796644ebb9238a3e0b48dcbceb04d1bda2d2366d3964d99b4f4e4ed42e0554a73bb584008c9ec0a8610080903287e10718edbe0c30e7e045be3af47a372784dfba8f18ac8f5ab2491b254386530108451d5902513953d47bdc9bbed179cc8e0f0b93fef2a6ff01183a8691e15096efba1fd99295c12ef159145b4420cad3f90943d4b5aa76a425496a63f05041667c8d9a59e89d50b24ccd53d85d4c6fbc03fe4575584f00aef5b9ca2362312ef0a3858e5a32d9d23bc5971596cdf3864e1c5fcd43d2fdff24eb2b3b63fe861cc75f2240de001c5ca56e1321ca4e467f3c2197100ab2592dcdb213e71cb2a0d177842ff98c70ad309d398573abf47994866c8007b79d2fbc1dd24da88b7d24ce411dc6a516bf169c8103d6429ebe638fd4cd24905bae87a8c3d743dc87d753ec43e5d1e635f1d1f739faec7b04ff783b85fc763eca1e321f7aafb31f6e9f210fb75fb98fb743d847dba1fe2de3a1e631f1d8fb9a7ae8fb14797c7d8afeb63eea1e321ecd1f918f7eab21f232b13018c0ff4d0eb1bd5488fd614f64951d4babec83d3f222295dd63765f9518d14ec01105716d40ace3659687e27f6b6aea84a772aac0727bec47100faecf492ea65d926ed5d5d34ed6a6db3c7d1035a16591f08f09cedf0abad4fcaf5086b546781f4dbd3278d4fcde8f531596b3b992efc5a7113a7369a14bdb26a8f1080b1e13a7e803776389eb96edb7a8d40177bc3be0f28bf2a64bb690ae190fba85b10021f482bfbb1c7d1e955c6cd6ee17caeb2e8b397c6e45c76cf8528db8f74cbde4d551cb164c9c1eba3d480f7058fc597998bdcc36f5b5f1f04a179d2a70f1edae5dcf3dd3bea8c0868f66d3e7be57de0ac46f77715ef7cd07d4c5a3c988b398862534689d06408389a270b6369a66a5378745b9f2aa86fcb9c6db3b3eed580dc6552f875da3ed11740af332fffbe3fe7098a4f219cb45c93561d1fea806100b8dcc67ba65413e3b905b9899ffa7e3eb495d46ce782831787da586aa8c3b5cc5bf58b77ddff7d039818060df2198e9858cd961199b31124b978dcf4f11589bf4a3888301a14e342ca4bbd5e6b89611b5c353753fc7ae0c413d416477c31805bc64138fb9247c8502644c0224b99c80fdea37828e1253b892658b9591fe010fed1f42e8a28b7ac14301b45b7d7e246cf046cd92c6084827360b411402a22547a78ea63a80962b2fc60c69c3391d7c0b2429b534e48206b9f2581d805544da231ba2a4d9f702a23627c70210f08e0af8dc9214ae9063c5afa96249cd14f94fcbe6325049f256da42e24c9220fb7be600219ee5c06c7ee57f59463b657e9bd50cb1cfdab457ce9eb3cc12995a887d5980bc65c1ac51f99810909ce80ae88e04da59d6476b8a644bab221aa502734575203b12c05e791f6d33322dac0ac1140b981b5581ec8800fbe5f5e00dc869655544575a682e7405304702ed2deb83352045ab7513ad7201b9d04ba01d0b69b7bc8ed600292dd795e80a85e48056817e50a8bdf23a9a2624b6b86a82291422075a07da4321f6cacac19a23b3e5ba88a6a490dc2835d0e3802d6459650171444955fa3a7d1615d18eac89c0f4447185740ade65d4e17a8c4c2ff015ca101846e8a6819660be959e65af6038f59e7f1b01ac2ce956fdd8ea06471127a6a88b80edcdda7bbef0027f71ebb0925024c4dbaad36cba3b58df4f1dcb06cb06c2b15063d00a0e8403cb450380767aebe024c6ab4735241ed1e28059b191ef07077961cc4c64c9f79389b8103023b0e6fbcb212b08981735f3fd71909503990bac5c7e58c49623662246fe7f7964a50033b131f71f0e9942cca8a895eb0f87bc34664860c8f5cb455c123122b273fde5212b88988bdaf97e701095838c05a67cfe78648b11732256fe9f3cb2420823b135f71f839452c8acd8caf78781b830642432e4f5cf445e0a1811b373fde79095440c8b9af97e18888aa3cc45562ebf49b42937212762e4ff9747560a30131b73ffe19029c48c8a5ab9fe70c84b638604865cbf5cc4251123223bd75f1eb28288f9132767dd46b245882d72780e6efd77aad265eedb4b84e8dda55723b69d2280c62ef2fab0e90942f5fa2557039b7e24a8c62d71f158ec2d0274dcd2ab8f854e2040eb2ebc7258e83501b5de920b876d6f13a2e12cb89e58761221747ec9cbc34e4f11aae9975c2c58f42b813ab384abc566bf08d131165e5c2c7a81107a73e9d560a1af09a8774bae1c167b35b1349fe414cff74d81cc5ed8c9b94cd2f00a3a4efecc826e73f4b7dcd74007c30dc37521bb78fc429fa85e2f633221b82062d220578d080a74e9963b505627145cd330a94ac03ae50f81a5bb055c3cc7f0b5c399ad7d31c3518ea81363acd0ed1e6b43403afc3caae17c382a1f4ea7127f8c7c2a6de48e7f54e9e96341feebf8a60ea3573054867aa4f0838be382b17bbaa49258a856e19b386677426b161529f0c858dd04997d417a6d471caf11dc094e0e72d8f18dc4f5e67a3449ecfbf89cc04939b7397ae1565534992f018fa675bacaa3d3d2102954e6eeee8a6f6b21f9a4738aee0c796ce9bf98727e73ffc772758621db8d34bc8db42bbda0567ace869a44dc142b048c7ee9a8bb6834880fc80796165d6822176e2acc124224701275b491160458d4917ba6ff1137ef0cab2a2bc6d013b84e7e1e29c3163c961da8921edd5784d84a0f9efa0432db155379f1266fbadb50cb7e0e083f878aed2f9b14cc17c782585087ad4d33457711e1729f6084f1887d42fd4644d6a7ec756a363654d63c8ecd94676ce0e4bd1067169fa6fab643d27d224cdef44a908f2715c3ebbe35adc470a532f021433382ccf21f2968b384f46825ef81aaa80c2d3339b5efbf6b44ccb07a596eb14670e09adfe230569e9b5a8d16b1b8357d966c8ca6dfdf7baaab977e4397553c99d4c5650c0c6f1ba113e1723ec0853073d33113d9e97cae7e9b6e11d093bf854f3f6391702bb13ed261bd4bb968eb0a9b736cfc69b186dd11f2d60d349226e25112ec0d278f5bdcebfedc39492420eb69c221d67ae5c5bc2ec8de209df94549534b745f9531d56441e1926e3709cf2e87dd61356f6a6027539e119df563d19f63a28ba7af9e9ec79e3ecda97d00bb694adaa66a9f55ec31705632f84ca7c7d07dc6075e7754df867dafb4e8b095372e3c6db295cab859bda9df10201f79f6120107b8adc98be26969ffeb21611dfd7e7794a884ba5c9fc7fa3c75734a6104cfb910fe75c748e1fb1e59569a5267d9e96f054bb3cbab20b38882825bde1df1f4f62d6f61710444c18716487014c517a058f70fefe79e0be48034f5524de6989b7d50b7b65457bde92ff58026f60c18a9cd8c3a11390f64eaca5db8f721d5e137403cd7adb664bf5833941d4e73023ec694802400d29c5603c065d92ba5176ec2eceeca28c5c4265f84007eac27c14eb80a1d4acf4bca5e6cb240b16510cec5a468e64b4f7b7cbca46b7656195eb83658d7b25f7f179e6122c3fcf88ded36270086c9e67c47caf7c66c96e84799d51f25747716da79bb600eef7539d6c8fc9bcf4ea7c8d40c7a06b40d20390144f8f8f54b65f1306b07341e2b935b88592092318267b14509eebb573b5bb439a0cff63a25feae606a0096c4761b67a0cc28dc5d77043b944e5aa279045c217a39c17f93e0b6eb2481ca89c2e5c2b9794690fe9a8e821ed412200eb7684de10e8fc44de51706fdfd8a75b326ba1b32c53e083709700719baf45b5f30a653bfb002002cf8b21310db1773bc429442bee053a8a2dcf438768002021315fe01d43c7b50f26d4ada50a2e5d066ba12e27712f076df2f15685955586f194189b8c005c5a22e0eaf5a114677c1052c12b9c9d752666d3b99418d5ed2972214a32eb4991308974b6e11085db7873389a8598a6bb5d72bd447fee13dceeaa09a8a96a51326abb4d9e9c608217e9e9b8e2c6915c2445f4df18f6b43452faa6b3d77596e34caa3cf92ae04fbfc0227c91e9c087611612e5541b93943b1d3cac13819d66aa9b0130b8a7c55b2bced8f63134cb6076c2443a918f5dbd52f16b1958410250f56b4a0639b2e7ff484ebbf8f41d76058c20f76d70a1469d3165c51da10067bcf77c485ced737cb06d4f94d8eac408d2235c2ad2cdd3f4526fb7cf44d6a0090ed7bfca0319af4b2144ba13806a764a4e1fe907bb8193a4b4e1cfb13e0c5b85013683ddc08bac6748345c19d04a1d515e11d55e39d4b6f0b79e6077f73823bd2a506e076b73a60728409d622d6b775db016fbfb6fbe56ea58e550a825323d8b552dce3e70657add147d15b1fd00159a2967242fefa37d8022d17a0112e373a3201fc1dd32cca4edd3dd9dd8eb20037d12545596dc1818bbf09b676abcc273ca9b8a08d7761a8515add6582f9c7249f8a3145a461ec83d8ea4aec5adbb7035d8e66e8e619e20b379d7ae071d4838234b7362f981f389dc18afb8299f4ccd6b4c5f308149f2fcd89e888f64d6bd44adad62f3c7a5eac3ace4a7521248976edcb06a44083741105aff0f7c2a6fa71f3dea9287372a81f17e29991e3bfde777668a19ec16648c4fb21c21853aca3c045f3ede91acf102aaabcfff8c6a8ad62c1e612f9e741c102f8ebf1c02ad66fc5af60902877f279094e312954adc70c1ef7d12b855c2333d14c68732ab73a8c93e00c94565b1e755ccf4113c88e8d47c432f6006c326d8359a3093b6ebeb9512414233e72f400a1934174c2d82b1cbb4df7cc3315e84a12b50de71b60605ba6ff780859cd2fe063eb05afcb6e383537566752976787a58db6be0eb88d1884912e51950740c1bdc948cdc01bc7da5a585398132b9dbccc96ecad097c85656481f4042b28b8cbb2013d07064bc1199c3f74968034c15a14781f8086f0df43389122ab3ece51ae1b83874d59c99802d05b34d4fd06e9ad58cbf487a4e78d23d6ed0b4427e1ff0f47c2247cb90eca4688ccc5629b10dc830dc255a72dd65c0f40a508b24deb0e5008183dc1061ca6d06408b30208cc00e0bb5978aa5ef7adb862434e8f2d5fe71aa0a57063f4333408ec128244d7c05d253c78de38249c12bec676f1ed2aa71e350178565646338fbe1e155fe52679d282a68e05be44483e463701174012fcce3af8e56e49b4697ffa7df43feb06ee718a7d6e1615169634f3b109599fd70fe49dc9d55215585d637297b086ca92faebf359e77dea47703bbecb70a607f44332795f64e5c267f33db1e44420ec4703d661692d9b6e88d0e4f4ab55d9c0631885b1f44f36a2be002ffc01c89524ce544486aa82e15ac9884a7ef6ce2e5640d3bd334eac12905426b2b771418a99d924c55859504643e828a40d69de91d013a2d62c61fd5a958ee518aba792ffe79813305fab11fe67f9cd2250efaeddd98264b3064ab3db1873b13a0d124fb6a171b504f9b624cac3c6082ade878d6632a4f07950cd4ba95366c1bd42bf96ffd2d1b56b5483c140c0187a37edb84df314d538f61d0b4433a04b174b8390f5b641b25aa159e81835f8832ab19d3e679fc4914938ab897158bc2e2b309112ce6f69a542c36bf861df3c06ebdc296a5189fc2dc2eb5748110a7e749a4622e8018020d22aeac517a42912d56471d784d669a7c4386cf52d072fe5113700806d77b59cb2089786d9439212740acc868e6f7a02fe30c8f6ebe06bf52fa5328503819945d970a0f970e4355dbd9464a31f90a689e7cb3c7c3435ab31656d667077cc1060f53a6aae3a6d2a767cd050bd367b101b0041ad2fe2bb23f76944051e6df5a0c49a329167b4728f7ac7ab2f0386e825b3381c4ac68048d0410f03c65b004cd2b8395cc66472fd3513a05913f8e3ad944c8d45fc5ab1d12fc6b94c6ee8234cb56ea083fd6e7142793418a253a032874bc0a2efbd0753e6345a4b53d95403c4d40a9ac3c034d539e661ed2ff06688789e6ac1b8e76a4a3af3b940cde3c5fcc5f41526002e6975a8123c3647b0e1475a5390bbfa7c6899056bccb9ea0695e38366003dc56a62c658b1b4d990cd95554f7b33c472aed4437dc505eda3487b4e57dc61f3d7e9dfac66715275fbb41a68f965a002f3c221442f3864d53cf10a1bf5318344b1decb3999b39e1c06a8738a439429f5d83f966573582f050754ca212366ddb19e5784ab41ce278c187a92bb2a24b2bef50dfd582f2624fa81ec1206bc7fa2cebe5f5b1b66b1a3c424dc7228d77ed211341f90d6a7932a5c5f0b1330eec3d2f1ebdc1d78e9f3f69c31f0b268bc545794a4a76b19df37ef42d987c74a19752915a78aa64fc5c016a683ae0ca14d1a4e6582ba079f862e9df0d5635283e04e7c839350b4c1c60978050ae78f13b08fdf37e155b36fc2cf5c7e5d72eaecf2c7573e56ada22f4fa491fcf05ec4f820ceb571cb817193dbc07ca75871439caf688fc846a10be9cc03620a1525b233e2282f2598dc616370626d4b537b7e9d43de831acecff895768e953f037fe2432ac3b1bfdfd55d2d476ee491ec11d6b6c7b8e9e5276b0cc7df4758636ec743d2abeeb797a8b46682a7a4c9a1d8e9393c1185e84ed1686f9e385ce4c0ed0ff7cb518917906229432f61dd48563cf3e3b94cad4487eb08b1758e3660e914b6f351479e57199c33b1bfe4b56248e89240455c245eaae2554a54de941bb958890d4af51c8986951950fcd12254d4ba78b5ee41c400327ec2eb37701c591987d91333942a980f327a70055954f220f4b826cc79c099550309816de8e3c814557d16a1a73f0f8e8139a2135f69f187f25cd5bdc971a912ed28d0af229bd207792310f7bc3a9732f70c187d0cc55ce5545ca726d53fc00a9f3aec619bfba0ec4b4852776d589cd315b43e07c13311258379308c11b975a438e38cc50a814edb18ecec3f8f33119ec7c0bcce20074ea60cc3750b05683cea2f486ee98eb26d17515525c3ed37cbb10a12411dd1566cf6eb8f3681a0e351b388dd8303ac60f8931fb3ca71f561e695113b976156e7e9dc11311c9c118734e5b92341199d10957bf496ad371c10fa947cb48fe2d6436828a5581dca2c7668a4afe42c3c1bb23fcb258ae3ec47ebb44ef07a73a6f4f24cb9289648162ea6b51bd85329006461e921428c310cde6125d914906222753416601d453c686078cc6a5237b78736811659927c43a2b245e5374f0a0788eb5d63541644471a390e4e62b27812b3e2b84f2f05b049b358b0546aa1c30d68854227a2343ee3293d8deaa9019047d9f5d50b172545d6e8000cbc29a6d1cde162c1f4b91429e394314a4a3f54fd87744ee82304bcdd1d55e0310c830602c74fc92e094a8b27fdea2b286b8b09ddd78a89012d66c01c6a84545727629ebd5cd96c950c8548ed4fa73981c7039064185e4f28f72fb60e115b93835df6938d8040194dc447dd971a76f5d1a85ccbfb05b2d60a38a8fb47f22d95821d1b53d82c79402b872db5984a55352a181ab3a5e38e45e8091fb015db034184637304b5eac0b1e9c0386be3cad265ca6c67d25209915c6bb0dddc0893cdddad9027c4178527ba705b8abe9a95a4138a84a7487e95651db272e7b8dc344966e58530362580f8061088174a6ebafb67646227f9a89ad0f82ab479fd8afcf063536e726451460561b635465adc3835a05cf612ea1e97e9f91fbf8be34d6b264de119ea7d1dafa4b3a76062c1643e22ec7ea17bb374a24a893d0018b73c1a0d42aa9721b42912532ec8fca885b59014935543f0149716dc72f86014e2bb74badceaa228d5537bf72b538a27e52bed4351a8a06ea638797869c25b065924344010b811eec5cd9f60455e81943189e473542b34d9cb2ffb05c5097dc2cca887be639ed42a2f8634f496d784d2020eca218bf249298b9a82f3e69355ca54a44b0ad3f4cae5eab74e4900ff7c8261c38be5d2d3e7a44b79512daf3acd599e7779522c0087711be71959aaa4ef741648cf059c60800bdb9b96001bca50c8d385a9b02cd46485c3958f5bc850d3491d61927b524424114be8660ee055559ee32c4a6e488c37272409b062c52059cfec17f6356ecdc22eed08112cd85772c0e469c1683b673d84eff8c8a82db8c3faec2e5c6b62726044c6a8deb90dae917dde4d0b93311a13ee12bd904f179c601b49e826b0070dde35039fbfce2d4976b4018a876641e1f348c50ced53db4216c4895dbc05ffbbb54cc74222b11514a533676ed04b2b50315eb5fb75c139c84e5301a0aa9f21666ced5b425a0008fbfe21a3b60957fb1779e379e8d00ee2a85a8dbc45422ab71def9b92a992bc638932ee17a85f0f425f3ffdebeb9fd607501f3d35233f9e40f1c6fea8c56491babf5a2a0f8c08d2f54a98eaeff37dd8fc574a9a60212bb74ee8c4650a9e8b7e14d2040becdddf171b23c5ba7189aebb14ea0d7bdc5496e316b2c74a9dbc235d0706bd92a2e0ea0bdf48c5e33ea053a9e283e4c67f94722cc757b392ae2123124f03c88a52a8dab26b38cbac4347e1f70a5ff08e892f397159e57cbdd15d86cdb918dae75630d32c6724bf9c2af8563dae3b8325dd138534984194867173e7d9e8b906ac9e97667cefea387ae4a997dda43f1afb857c220128fdd3f12bbaaeb7fe0d1bad7ceb4b532f1456ccd5d7af3b8d66a74706cfebe986c183f3ee77fc7e3730f487a51cd8770d4ce115ef8ab2156baa07912d3ea1822d6ba0c5be7777bbff161ec792de29f2940e10ca0ca162708978450a12f97c1c5f5a631841d3e05991e4dedb4eec91a8aa641ced9f0d01ca8c4f991b117541c19fb4e8c141d9c30f37c0378f03f10a26adb849eeb21a16e2c6576954490c41ab7a6363461e7396a5439d208e1b099c1f9850383a402f010eb8a8fa566df863af97f8301e8359466eafb6df57c36a0e3ff90f9b214b6d4ff2879eda8058e7b6b3ed7c88c636c7e588b0a72948fe10a84f23923d37f1c172e21f138f3d23e34391fe85bf90bd22742bcb86a7d20767d161acc8db632593d707745b7e38be07e745ddcd3ebcc1563b587f208930f5bfa0e641ca8939052eb71e6fd74be343818e68a311b680a058c6bc4af003fe3a21d5082b94a5b6bf4edcd6eef6de7ca35cdbc4bd7f88da7bd1efcac9c223e6ebaf08d17d883cff270c85c95b6060c6e66cc99f99e2f92ae58f5a9e798a8e6f3eeafb0c6a06f9f86c7c009d53c6585e1e8e9de8edcd4efd4128a7f046077e353afe90489ff612808368f4e0200f6334b8f38309d2a4df7541515a9d65e727e8acbfb85b02942e15c2578bfbccf676820298cb6901b4b7e03b8322fc15ab49a73f19d7361d84ae9a9947637aea0dd511ad61c1040d2297b8b0a9ea71c7803adecd828267e2ea43451b878d47578444b3faf416521de3205af9788d1bf64bc580e0b9c16c165608bc544e9b16e6a13225b4d8ea58f2425772497ccb8f8a8871de6d405fd746fc0b15af0dd4bf8042b8b07bc8c5e1a656456bd1646676fe0c560a6e067c5413a9459a88919765fd2dd0f58b50a48e958381130d881243bb127fceabea4fa5a112aa0fc5ed6bbfd638da931efb6a48e439191f010489cd32b0b31e6b4553b5a41471a85a90ed1355afa5b41c2dbd525bf1ff945dbfc3b205467a2b602fb65ebf4c09d254b2eb2ea694e2f3b5b239550db193ea969d62659e1a015f258e648189217544a0af6422b02f0e5db2a1af4aaef5c0287f9cca3ae03ddb46d3f402c52f36a4ad3675affcfa6bfff69b7689f181aca4acbb683e19facc9fee7ceb50e32536e9db29495a41c93e668ad33101dbf7cca098506f49db7c2e4f928212cef2ac534c7bf489166ba002ba738997489e770c76dc963667b8e5524e33039abb17a6bb6980a6948faa82fd97bf5cb25cd1004f3525ccefd5cb046f2396e3557c24e83e7e1c664042d3762bbfc3fb39778568fc67363696be9c8a01b580b35cb6be6b46ab4ac055f09de5ceaad881403b310c8d3d7104356d3cb109e1e141c1f75de703225d15801fa85784251b785996ca76f9884c5d5602ecb3568499fa1ce9b54dc7ec49f8482d41755fc20d89175a1b06d362265af4b2c3d07ea82c5657c6da0b660b37a66ebe6536dcd66297cc53f8d3fa6bff62fdadcbb21be3c3e63654eaa9a0e2b8977b80bdbcfe23cdf57ab952d2cb61635e5e445ebe31c9efbd1b6ae534ce7ed0e5043b13d9b6d1a09e8e81080624ba036aa12e8657205816a703f9819b4295991c26757055b82fe96e34a8125773129a97aae8feecfc88f8292ae25cdefbe214013b2845fc8cebfcfdeea32ed63c334d3907afbb01306e789d8d7d99b24cbe15ff2bbfeddd6d6fb9a54c29c922086e0865082017ca6ae58c133178d272c44b5dedfbda311848f6b6b9e8125d97df43cf35227288f41bf8da1645475da04ffddbd8e28c81c7d54298955b468e2e548531dcee55c49121da6ac86cf9a967385538ddf13744fac97bfe86742f3f9def71ba0325b889def3a61722f15e14f6d7bd28947e9aad71b26eab3e1d3827f4f20bc2395f28fa49863cd024647660284412ea54daea36385220eaba3d65a06f9bb5a512eb8e0c2473d49caee99205c9648e92393eb329cf992e3f7533500ef3d93fc99d2e3a1dd4665ab7ac0134c61d1b48ca88707bf410c5ff52a97dac3505e99c6dcbc2ca58266d247f75570d1b48025d1cdf8080569427e59658e0b4180d9b3c67cf6666e7d9546b588b81c3375ad82fa6f1d7f193180c44a5c59101004c654db7f5b7b8591c1e1ef73baa9b099259fd97959033a328ac0fec77646f2628b9dc023e71109c059e71e743105272cf6d5828ec868db01899359b713f577ef2d04f959f9c59fc04abafc819ff8ebb7f60c7ee59875325671c0b3b36ecfaab9fbfe3286baab46f335a0c3ef9cb8eb25a8d9e4dae61ad86ac51000e173e15a6f1279bb66d75ab9ad69a0264cd08a4e8353e388a59de023ef97b9be13280f5ccdc09ee197425e48cff085c49cfef1cff10d8391d14f65ce7409390d073cf21098544fce47f822acb09f17777fbc08259cc624d5517c0bf87a0ea1a1ffd4f9a7d66c82c1f66b399aac539552db6142ca9e73d3df349a93837666656a3a767f5faeb703269d1574eae4f958e97f5c6d2413d9be9c857b779dce3038f0f9d5729c4853aaf65daa9e3083c422b5ba7aaaa565df3829c4e2693d99a52266b56e17d1e15b57893999987300a08d6b13f1208f6c9019fbc99d5203fe1f2fdf82e87cc52c352a7325953256d4ed77fae1ce5393e5bf7f975706135cdfd4315d871aaa6ca513d5389c4b0e3545def3b551368aaa66aaaa6aa67ce6da31bb349811030856f0b4b58774ee6fa6fe0f51bd747d77face17a3f7b8ab9953842278f23ece839d5bac123f449b0e9d0e8f4ecc63147b58f4f0c34f5079a5af4dda110d193422426ed4dfd2ea24762d24c1d9a82c43ce987c0c03c2914220a212ea19531df27c91975ab5b2d92625e5efbef9afadaf3e81aefb570f469d15bda57d1ad1730941ee2f8c94d3a2f6fd2417b17d29b86700ee9d954811717d2cbfc8d1f42fad18f42215ec2286a68caa17ef8fda4d01444e66fc8fc0dd390d29bbef4a6973931a149fb984f920313923ee685903e26441285f7484cdb9be8c39042d37c93f6a497425e3ee6634224a62d3c22c4e5edeb2073621ee687c43c4c28441442460ff342d810498fd7109851a803f3129a667844079963d2483fc4e54921920f63432c29dc2149ce2881483ff6c851bf7f7c1c2f735ec2284c397491ae2b187a1238fa17b0e56340978701edf367d291791d648ecc0fd1f1a5979f497b2dd4b9f144748451f49b1e3469323a748451d452e961625e8852e803cccbbc8ea7610c1da9949f489fe36352314ffa0ac07c8ed0a443223de7bcbc3ce7bc3c4ecb8032c7049ab4cff149726e80262d34e9c8bce97384486ebc298c22f4329f244706bc11de78ebf242dc08b9c7becc9b9e86314ca1f493cce871b8fce82b601f47f89cd3d2f29cd3f2387d03e49c12c8399a4f8b3e5068ab35764a04b64fa7564f7c7c644099d34f80a200d150ca74b956ab2d86543d9897ce051c81cfa305b4626f5d3d11d82993cbf694b15351ba46037275cd4be698f875790a50bf1cc6b039e9cb6f6e73e3d015767e3868e12849a861b87f90a7d9da7713460b6b9bfbed473b3f7485cd71a917b344429d16a77dd5f4cf470d400a3712a5e327be3182056d237cc32d1d1fdc299bc0ac27ecc3eaf7a4117e59f97cc8a7d35ba485f245ca481716d3cc9f22c847c822a4b803d37012f2347f9271e78f3d1ee0ce25eeec959c9993888ef7ccea03e4e0ceaa317d7af9f3a1b3d385d2756ee897433f9d6c61097bea17bdefee169658ed76ef3d0c98384211d6c8d9e9de7b9c762f7485e52b67a3be97ec83c7117647e97f5c61fb8e7f04071df7fb0d748267cbf9befff3c01e72fee6be7121ffe6fcdb3770bbf2f3b0449234fd149469112cc2f38aebea4427794c665b62666ecf9ba51668a9856935d6261565a0a1659a69bb49e9943c7b761bc8540bafe4824ffe2bbed144e7825132f0c99fae98891517ec6ae6e94dea69301918f5834f387ef2e7e71f16c73217923022d2a6df9f0212c55b704e7cbfc3944bc4515f58e78f8460bf173dbb80ac0bc552fae431d72808b67e5faddf8878bbd435dbc4a1022bafbf1372060792c69f03d9899c59b1941d587eb1ab45b0087694414138ea4706f19c6c92a1243a57ddfec0b130af3b719557349860a7044836ed47190433b9baf910c1ecc82eaf0bbb4edc6a8f90a6813a57ce0401ca1901c10601393b87a378b99968326bd7684f1f8a7f09641037461c91156ce415ec46a97ad4b585dd4b0bb6c4795de53927c79e0ca2f785447d4690489035da1741daf0bfdc201cf585bcf213dfd090a3ac3e1b561ca579c5e148a3c8c031af021c05ff6eca633013a4e8cf51f846879de0c5758e12057649200e9233fe0b0082c32e094479355d937aa6eb32744d498afe23e82251a23cf977d334a78b5f1cb4c353a4b08cb3308ccbb8feb39999081fcfeb28a5f46f13e19b10c81f8c92fce272fd475748189d1f84a36cc84d644b18fa7f3fd7bfaf8bdfe56217bbd8c5ae3943eda3075a3061c5cc54f479feb651f6fd4bd226f4fe37a4cdf6fe38a44d871a8938d8e1f99c96fa2210880d087be97b20101d18430f3f75600c9a46e4b26844e48d9bdaf61cd76d60e8a927fe10c029009e486f0b08d3b6c5dace748a42e16f5b0edb739b6df916b0879f5a207ecd012116fc8af9916bc2d5d1adbe725fad56950833f4959cf1245656fae48f659b59ec0e55729d2e99939d15faaa45f00b3b83e6939e554c2833ca9472a9346ba5ea993b9fa584e5ba159d1d3b76ece0e131c82f06bfcbb5a5a48445c2bebcab40def0c034cea335e5206f8b47e70bd8c20bec894b811debeb4ea9b0ae196b8a47977074165c7f1b8ead44e32ee4c95f148ec2d191f08523b331ba8baf3c9fc1556a25c562b158ab98d02530c0207a278fc11a8bd5181bb24530df43dc2b4080c2ef7243d85a46d78c9a6ac7f5ea4a0339e33f5facd335db0e5d511fcaa230a02ea067d02b940daaa24be40c738b4271d8dce9e9a427939e4b945cd8b65381da448df18d16ce17d3f8aa36c1286f62f60c8b15292f17eb89931d9e949c093a03c69b985de79bc9869c50b88217d765333bd2d89c6958b4202d0b4c8bf1c8ae6b53d0903447980212aebf26a5fb32b42854a05c9fd2555c2368506c21699e7869ab96e6735de3b9ae29b9fed40945ec481b2b8d6a257d2a83ca681579d343481a9736fc4e1c713d4b2fc1727dd450705f9e3f1fa2679791fd3c1a8b89c0c6f202f6cc0ae87ac26a273c2939e33d5de32a12f4895f66c1b2934509ffe84abc65ee0d83bdfa497743e928a95e754ff3901e86926667812618e562f009039589baf2267cc531ee420c867115f6829df00a8fa031a9318e8ba9982891418679475f854db0a34f1e7fcf022ba36bb66f959f8266cfa56ec50b7b498b211556b6d84b666490e1f341bf82a14bc123950b6d95ebc2b179683e1f737acc614e65fa18de041a8e9cc5570e7398c31cf672a2b19ea8a2ac9c256de83777c48b515e78043bb24f87a3c68489b4610e7d481cb7558d4ea64e288b52262d1ee0009f8fc91d61433ffa6ade2e015e48861df9d53b3cf3b7679f57cd91fa24e02c65748ac935808d4dad5cb7558e7d6e6cb0e1f3d1cf60e83678849f04dba55ac8307eb53845cef85356829ca1f1974a47da009133fea1efbbafe1aef13e0583c1d8a04f5a6451271e48574c542d32fbb89c30100d704f550d527ca3853a4c235f2e2951666c763161976f6695e9c574c2f5b7a3d077b2fbae3f1fdef77cbde62be8e52beaba14e8d21e47558daa6e89f278c979781a7e871c666147a157ddc27aa5c4dd2d5fc7fda4c6449e0ffbb0cf086c292dbaa2c819568b4e562219aba6344aa74ffc332c32cd8a56c67509a3726da0311a1b698c871dd887ad982f15d3b0158caa66f049759965be1f5f35c363aa9894ec302fac1599a73ca3adaf1665420f43c684529ea6640f71abb9ea15afa68cb957afd7063a00368103e0ed517d98c6a7aebc89ce039eccf181d1993741653e7c43af5032a81a3b88d1181176ac31719e214ffe57aecbe810b329a3311aa3311ae338cef27a7158633e6ef8814303aa1a5418d000a64ce88aaae6773978dc11b6bf7b80c7da75bec2af51aa0deb5fd018743fa9938f862b592e8d491b1ac81b5781f32b083fe0178d4925211b96569127ff3358577c281badeb7fe3a331baa24ca84aced02554e52df77196af441d27ac5ee97c10f87c841e02524640488e1ca51b5336653077984781bbc9f5ff42dcf6a4d23a6b5795c7311a9bb18eb1b792334e5a6445e91a1f2c77a4b11834a0eb515cca48633cd2980d3406d3112224021190c01026d2a9dee12cda0426c051e056c023810e9b389ccae7c3615b583956f61013581ad53c74e77a96399b5168e3fa0d6341d2f8944dd99465e954ef4cd994f5aa9d28d19e684e3426da121aa3313a2de09140a7d2a73e8d5ec6f5d74020b64b4326c8197f0f43d290402718748247cc810981d880b0b75f03df8f8fa76400039f8fee31f0ddb0018ffd4a8df5180e8b8df575bdc586e52b55aa8c5f2e98273dcfd7ab6b48307436d3d9dc5635caa0e4b6aad10d6c60871d38e03d619a1a30aa82c1277fd235382f83f5761ff018e4eb32391306182f47f912a220850f460002860e63c18e1bcff5a70cf3ce2fef48205865ac52ae7fcdb8ed5c4f8244d529d2865bd5e77edafbe58f866167bd4348328fd33e4c41609ef442609e04c3313f6d57c381a53b20cf40e9a798977921312f43fa98f015f348603e26e4d776dd95c819ff900d4b5fe6c0901e66474ad79048a153d0838298af098b79524cccf277463ce92812cc8f3a607e748143be9937240260ba2ff423bfbecfebfb422b612a1cc4b3dee1d8e78542a1d00dc58032679e2167a0c034565a9cf5c412d4a27720df18b0731a7422e649608967cb89d1d1d35f82b5e854a695299b58ee94855d8c5336d615533932cb9036f35b546034467ec2f577987b8cbbce578b77d553e627ff6db3b6549a29e01ac92214182599f674cd9436678c1a112b285122ac15661ad7a76cca2efdd219b6ca3629d3989cf1a755349e23ddad29e9896d9bb53446631cce57d7cc0f78fd810f7c3ebaff0008b63bd61583b5ae384bd7b077936a4cfab6d2a8988ff99898d077b2602983ca94981f3b8acc8f0de5c7aea2144a5f72653cc6619ef4386dfa422a2c87ac228135e6ef1cbf58d5ea9ab1c6ba46dac4aa8c8eded47aae2fb9ae299133313b8a77a43123357684e51fc7cf47f70cf62df2dd50c4ab31695345a2b88b578d711581c7af66d2356c480e43b6206da412d71b09cdab73951d6458fa9d5281b45102f341ec63054b96eb3b17e554a6a07ca5a451358a85c25ec51226d743273cb4f892332e73c6ba3a5dfe422a2c83da75f7771813541aa5b1ac8cdaeafa87bae60b8d05b70b79a3a940d2bca4cdca511e863cf97b95cdcfb0ee57aeaf1c267ac1fac52f7ef14b5ba2f5809a1239c32f7eb1e6d335a394dd2a5efe74898c56719d3eb94e9d30b91e8edb168ed6964ae1f8e27c98077bf849bcb1f58cbaaf28a3933ca476e58b573edf78299924470ea1bf0d39f1c8b2a7743e4ee3a07dd3d9abee884d5dfed20a6c897e0ed96db914a56346b340234643166854817aa92ca44003caf4b59ef4e7d26f4f874f87d0735fa2ff8e12620b815be8eb735ad564619c115bc28b007a72cf7a8d6ec198c67f0d46f50b5a72bb7e5ec0285e83595bc88d615a14e1ba37aed4a28858aa0a3da0d73369d3fd836eadd1335e836f7a0bd93ef056b7357dfe7068118ce7dc601c8644f54f0bd6b29dc8db31c5f2fd5ad2a1fcc896b562abd5f37d3bb2f48c3e9d1d20477d2f7afe0ffcbee58788de8abee5452fc4e8bf9739dd8e2c9665bfc586a6feef47a3377528e4fb914988e85d5ef42eef1f1250f67d53421381f502dbf2f6e76b2d282dba11972ca4729065f4489b225ad883f66ec4ebb612d2a6732cb7815aa444b032685821a2d05e88ef5de67743cb14e47b9717f2bd4b28fa51c8834c14dbe2359d2eda5e04f6cc82b3949cf1300d5b05599386b4b902ab5544af5a37c802a87bbaa7c56ab15a2c16abd25ab5aa51510bfd91f7e295a4b063b77ab688b69e9033cc05df74e7a0597d65d69f8f1fb88dbba3063c76ec96dc9e55351cdefc6ef88122081895180cc6400ea4c308931968c643b8fe332698cf476b74bb188fc1d1ed969cf1d98807505c219bceeb7ab7ba55c33d55cd62188bc1e2a1e26ddbea562577b3b85b0d04ee1e69b3d5c7e91fee14ec15109ab48089eb9d7cb990009231c38e3d6b713ff6ec093264d81b6652ecd82d192b36f41df5b6ba79ceef1f04fa869e65ac60719ac17ab7cab354dd52a92d354b5134ecd8d3f3b41edbefd0c28e3debe16184e597a965a5164b5857de915d2ef04fcb823bb0520b1400ddb17be413aa80a15185185c91c62c0cfd58ed8edde380f9a67e4a04cb2e25ac2bfc1ce0e0c777013812a8d25ab5aad11d3cbc17c460144bc127e7b055cd7a0106183e1f4e7c36f5fdbd9bda0146f5ef868f8bf09c3de72401bd4070923b9fc386d2270ffdd8be5ad8add08f1d9f79ce2a8a9e288aa11fcbac198fc18f492ff9e9663e853fa1fd58d3ed5b9aa2ea9e16bbc759b552cd6d9b556301847e66251dd81e703c27ed66f0669861003bccf218740bc851a29fc29ff0264e5d57a4fdd0431f6286c4aa67c794596805c85d9a6f6bd1bb87fc6c8b53c219084083c720b37eece4ae8659dda2fe85507ce11276ec1fc80e82acf1810c2e1612d53d7e6af10dab68705d1ae1fa11d28b9022b73c099574150d96b8feceac59f7a8ba877e17a56f6e5bd54416acc106cf0862b00bd6b317fc4967712cdee34e3c359b990bc04a7413492345b7a07b4a4cd8b17b1a4b8fae449485f60fcf6aba35a78d0d37ddd35724d713fab17ec7eeb99f0fde69d19f49cfd89028265d17bd121689eb3e32024b9b204775cb51cd6275688a95e1c28eacba11b116728a79b6b023a7e61dbbe7867eec773f1aae4c19836312d5e5b05946a4ecb64f11be100a1b2eb1b31f79f2174217b36ecdba35eb59cf7a26fa3c26020b3ac943898f3bc2f695339bc82bde829f90db4adab470b7d9b6711777fb99e26e1c645bdc9e4118d16b71631e39b33dc8861d79b56d630d77abd94a77fbcd13a174cdc8473090a3a436f211d2a6eff63ad28657726607470591286e224fdb6fa328fe7669a8847b98270b368a104a88f9de6f510899efbd10f4bfefb1bdd8b1778fd4d46db0de6e52272d6e4fc1f9dd90e476340c7b2ba8a5aefcb8c7e96a5ff44346159ca9db51cf3f5310d1b7bc10d1b788420f85881ec9e845db57b053d7c74fdb083485defbd07f4f2916ebdf813ca5c50dc84f9beb075310fadf5760bef740d8a62267b66ddbde51dfaac4f2d3c6ab16472e0bc4767ff8812ffdf938ed59c9630b8b74ac4ba2abf527581fecbb759ad77d921c1387eefe48bad1e6749bc71d6119a4b7d3bc0ddcee9cb7e3a8e6b579e336916cb1d6e77a61a0b0f46768da3c3485deb4bdbff726eefd33857ed382ccef7e0385ccef42d3f6dd8f9e0385f87ba12948f7a3376da1902eecbcff5ef4a370fb91fd9d963762cbe9de9a3621ecbf84435c46ef12f6f0537d99d37d3ff0252267ea87be203307c74ff5394e081cc562fb6b0f03dcfadf016e7d2f01b77e07ce204ff5bb8fd19033f537905e6945ced4dfea16f2acc7ad0f7e613bc525994db36cb381b828a52efaaa556693728a5344e80c01c2375ae801a619c2a81e7a60141bc127244b64194b649650a74d168d603c70fe188e3c2ecc8f31301004b8b29329996acd41b59eb5ced704a3ebac569133dd61bd22692a19ddcdfa457d7d95bd9a70f7578b3ea5c50a83e88458adfca38913153ed58c1a0b408d5533d86755cd60546da2731f39d344cef8aa09f729a4374ffdd1573d66a852a4c8eaac56a932bea957244d25430d2e083003d50463be6898af09868a7d26188c622b9a99d90ae62a92b9260a3ca078e01b2ddc767adbe19bfe5965dbb92f03f0d03656f8f020a170fdbb1b7e3118b4c6180c465533eacb06ea041a03e3c5d5a736a9aceb7c53a7a837a0c20b16cdae691e3ab52f477ea1c346702af472f118a42f35764375428dd526eaca058f5f3870119caa818a01f38bf9622bd8278619fa01105080d73140cbc1ab2b087835562adda82bd3fc15f00df73b3ca61ce8f37328ef568382aecc342cece8ab1b8fe3475f1d69aab3b3c353430e0ce9635ee6774a6fc4d672e5e72af015308defdcb1797aa7ee58122467585602f92567f097e12401466e8294338c3c46e9d3a173605ee60b327360428ee1c0696cbea84aa632d5ef4c5e0eda646575683ab0cf310e9236f20acb292642cef8f3b4c3fce46d04c16032495f3eda89e89dee22a88d2b4197675c85c388d9b1c48ef5a519616b65b1c871b26d8992a674a76738b1a88650ad27a7d888909f18c128ae019f425a830a86a4f1e7d3c8fb42cc4f5aa34104fde08cb0e394c9ac2cc112648481b094167de4d55abf90370a7d558a0bdef49955cc2753c9ec993c2e782eb80045cef877313b5b09247a882a9a54859a8a6735a4c08ebe72e2acda64861cca7c144a94ebaf49b9fe74caf59f54ae3f3fe153fc78f3256dba90289ec267be7cec8ab26c8b673eee4dc63aab41be92994f9f41981f6f9002cd8af9005680966fced9f2cd1781324703e54d329bdc80697ef46a0d3b726c7a9f17e220bb90354d24123128354dd3b417cfda29f31fc9b1561704cbdd915bab21f00d18d5293fadf8462c2dc17a5184920fec0e3855468b31366c6ae58a327250e81322fa165260b9cf851f3b3207f14de8fd17206d385104248ab330031802b286539eead405e2a798eb0bb30089b95cb1de36b07b408514bd7bb87fd08276c92460b1ead70e4f6a95e2d20784526d631ad157fac28c574cd3346db52af57da1a93c69979306ea29edd350ba74c36b1c8dc3d3869033fefefd4835c159f886959044a4ba2e08b6cec08e9d1a6bf87e882834f177434c1ceae488582b53bfe84dfcdef726ee5ec8f748a2e0f09174ff0185dcead5f51a1a8003878ef21c85833cf9ab80ac56da6ab5ea55af7ab581dceda4b6da9ac80a3aefade94f10887ae5bb12dfaa26411a825b928d598cae6bee2b5be48ceceeb691524ae914083ca4db946529a73085124be1eeeed259d0f168517a73523a5dca3927d542295896c297668b7336a1352de81514d4461b1bc7416183823627f51707390703776f7ab3062efca6014cf3af1467111dd53b6c481aef56725bbc020705695b6d1804050505f115244a6706a5256c12b7bb881a9d3a8ac2fae63d68b70abe9fa2605f73e3e88b9d080a92335e586e5f6d35c00112ae48238b531a965e99451a4069b45cceec20290976f4eef5cbec2c6ab123971718528c4ce9060e530e1d4e9d3a75da820b0f863b78bc000018c453000410c38c0c343d661800010840001a0a50538029e058a0aee1ff12cbd2a88ae5a17d3eaae631ee75faf4a6f7c3b4ed98eba5522db164395e776e9bd329f55992a5f652e9fea88a9d2df29c1e02b960f657540186cb3ba70004ab8424765cb67405c8c25cb1c11ded43a1c42500645141b1f5ca2cae2821801558d29559ccb2fcc006f998cd9e30843bafcc62b6e2e1413453b18d84f4765c39df0339e5a720fc14b33cc5101205c44fd2467bd92c2e1cbb899c2133909f805c40409bc370470682e18ed2757b8a3b843c39c75c3e72c683662d863c48693ea8da7cbe99a10d4c23830d4b48a147e6d3cd559b3229ccf09946c65260d40fed7b34ad292067e6ff8fc7a1b3bfc5b0a39c89dc125b2fdc125b2d51e41b8e314d174186c859bca6c05e8e6225e4c9bfc9f5af1a9dda8e97956bedda2c999bf358c6329ea99c30162bcdd34c38884e4da353abb5d6aac1180ce697f6fe42b6d0c21f39e392335d7bda5639308084f00d6f2199e594e6275866999fa858af07d6c42f734cdc3304ebfe1c964a1206b20556dc1948eee11bae82892ae48c5bd2466b438a5790a2f3c05d84ecc1c24d8265adbac00e445af487f5c81997c9aa4c26639946a7cffb5081b35ccc1823fdedfa04d1f0c0eda79e3592e3f617a1e198e3f673620c321cfb678edb438e5b84fb51738c392e573b346cff37c71c957eec815b84fe46bb508f8ee98eb6695be5667353db26a5734ef6baca6bfc748e5230bff3b6e91d0d694d84bc9fa0474790e4b24ff6c071bb73765c881d8aba6d200e9cba53dbd8351f5b05c769396e2b21ca7130fd83eb01e616e1e877dd2247e9e4be4e2e1c616e11e66ab8bd12db3f964a258fe3429a86c4a6bd168e20c96d0e9caef1164a19c3fc19a2da6fcf6d1bf5aa51285da8fbdf363727d7bdfde0c3f5bed2ed470edf9b55b0fdf6e78fde9bda08641bb7e547ee47a1f6ddc0859e0da9e8bb341cf9ebe7c3d6c295e511f9beef3322de5ac11ec4aebdee46b1866a35f1f620de16517d7912fdf72ddf712e2010f5ba70b3d62de4e2f238ce85b4d9e32a47f2c7df1ada14d87e17d3a86954f3b4f9385dc11be4cb4b696302222fcc0f09b8f56b38822417e6c7fa9b3743a12d7c6f9cb743a18f646248a4972191b649c281e36ffca8fd86e36571bcf613c717d1b690391ce1d6a27ded06285bb45f02678bf66540af45fb31a06dd13e098469d13e0c7843c660ff05c42167ecbb8039a468df04be3cd93b0a4b72c6fe078ee2b5e13712b945be1789be2e044405e5d4b45a1fc7ab374bfd31999365287466cdb7ca3c9d8990962307ad959b93a3b4bb2bad5b87638e4b7bc871399ee198e3ceafcf6d2d8eea9e8e39c2ea8190b675b4f98bd4ef2ced7e4ab939394a9fd66deba17427b7fde55c58027d4f9b97f26079b845ea87359cda15d80bb9c06e4f9dfbfe0a8a5db3859b87251c7fed37edfdb5d7e86b4184ec7f2ccb6d93deee4e6bad557bd7b4f75a04a2c2890bc356e3d1a8d0f7e9c51e4fe4008a99b1c68a7ed7021a36d40ae3fa8f1d3709a280ca7db9520b1410e176ecd51848d44b1bd2a54eff8926977ee743c8438bf4c31e5827240ac74fb46b76685e42d67440320c24cad61f590797527f7b433c7440d6701252a4cf3cb4fbcd93903552d2e71ea72cc5fab47eedf1a894751e929b03aaecd60f8542a15028140a8542a1901129bb45ea6f1f0ad5e7ed4bb11a7a9ee7799ef71d0e1ad0b045425fc48894dd51f4f53d6feb72e87efb31f4a328d4ea9cd5d6fa3538aabf3e10593726ecb6ddf0fd180a4729bba1914d41ec8f7e88fd91e887b4bc281c43ef3d8e87a311ed3d2058bedbcb9003badf3c50fb7e6cf543a1ef2ae87de759db6243ef51d0dfe285a31129bb5d38562e046ecff9d85aae7492c7e851b8270301511a82bdeaaeba542cb93917171c857211046b11fa11f56496140c73314dbfc0056b6182143016b77beaca0b1825d987909d0617c172cf546a5404172957a5b56a55a3dcd4298bc1cac10c542e18524f868911330315b74bd9e1e8c92ad30c54936a52a47a443c29508af5973255b03258ac8c1a56260d2bb386959fcb75f1662335048f8c10ecd8ad1d50b07c7e72c0aa3c907881b504005708828b284be041446bc62d2fe9a0c2cadbf24f856d9d524604c1375aad35a238a8540dd65639eb140d0800000008a3140000200c088703e2e18040a20782a83b14800b7c8c407462381608932887619451c6186310218400010118819991ea00be231d829503017ee523f858000fe934e6bd14408e7c2f48bddc293628b7668cfbd82a34b80ff58d0de48ee977fe6222a58955f1a59754c38eebc5b7c60c4662a7a14ad62fdf93d6308ca6c658645293f2e1525337a4beddceaa9adb35a60284b6dc3cd149aea25d23877de2a0634845399c9e97f975dc4b0745e765e4350209449ec12970fff12ca61edf472a8dec65c563683a5663114f67f615ea3374324360f9b59f8b8f8e925bc3c78bb47c48c70514cb1321624a297052b30ab69e8bf9920771daf3e3d61741ddc2d6721ec3530dd113343ddcdc17c4418420bbc44d145f2d1019cdca430c21da2ec409670f01d9bc8f5e1862ff62a1efcde85604ccf36a60e41eefb1c51bd54c743670b1d093a14bab127131ae1be6bfe2fbe49c2faeb40d62dc18686b29292347407b046573618310d36dbf6379cc9a889a3e08101d814272c68e62035168fbea7086647677a35f461cc0120f0aaa2516b38a08a94216a1af50e83a53f990341392ac1eeb63824c8f11cb85e3a110dd3b03e72638ff878994f9a18c49c83dbd9980321eb172f4b02603f81b42c38679fd8607d6870fe780c11b9d4f18fc5b767d9abc51d2150cb39f0e3c8242a02517254c14a400a37b0614c03a2fb04499aff770a17c9e0235fc2a6df0f0525d6e2803c56774c8da1946e0a8bfe47899b04b441d37e92841480725543b64421e69531b6530a15ff2762652e0cb33294d41af9495978a48187c25bdc248fb47135de44f3435d4c227b7496bfb3b49f8b91b530f7f94fa60080fa9f42be88c1634fda7345939f0c5e0d08937a205b297654355e34881e49438c8c72b0fed9ab6c76bbb98742a8f925367419bd2a3db73d43cf59b8e80988191b498d19aa73082fbe54b07f2f9e0e32917a77b9631facc2bb9a24b39108ec8df7f477e994587acb973b682fa487aecc635b9b891811f41140f41867221a81c41df8aa24bb1c86e2ba8055bfdcc9293845829ffba1d3fecc63b2256d91b01e1abb6f6483807e418ec476c25f1b2571906044e2e19d8f54dba583a52724682627cb320d59133c676da2aa6b3a56eb81983768bdcb47e34a4f07f9fc972a2cf1906dd924583587851246d84704f0e746604fb1ad19ea2f9db8a4bf2dd6689d9b0ad1320be5b037fe0e4bbc09d7a659b83cdf2c05c770c60ffe2f8509e77cdef3e6564aad574f657199f75f8f4d06bb80f0f7d322f778591aff05e6fa7cae2503f6b22a3a0e979cd644c86443a9e245a7946d7f13731c82a53c04771922436f8a7fb7e591329f7d456afe2dc3d73b92412e8c614fbde13a0a3ad0a82a6b2733b21132876a7effe14027633bb54b183c822787f1eff91a9628b3c1faf5ab44a14c909145a0ed886ea90d8e2d7e89577a32bd6c2b3dcd543749d839a898fc15cd9b29f1c933a0a48f5b354977e01ff0d5d021e76991e152b354721490af95754fba1039494ce715b34f82e2bf47ca3fafbf11f202f481d7dd457547616e1d373975cdc5a018ba09234bc86dc91d1da138f0752cdc0e5bf83d1397266496b774657556d41b2362e86ead366b7783911866bb7c7f441133891c063be15ca86d977bf421fdb963426a2d7bc8179ce6a77eaa924c3ccef1ca2dce60a6d93915a0ed72ef1efddd737d6e1ff3527a644940c341db1af6fa9ab93676ec97a9f2038332ab555336888815155d9dba9a1b8e03f3dc4e68fa81003aea8afb2fdb9608e48f8454736078d0debbc0be16a9e7101c7e6559e1e2f6b9793794426c564a0ac2612d2842ab453974678475b2391e0b8d9aaa26e1cd46f96de73e3a94bc92ae5d0f17d7e18528db4d444f2837f33d93a3f75e2e7796ed4b8031ee25d3c8f84bdc11a8298c821630fec94e76e46821cb1f975c3351414a4f9c48379ae87d2088ebe8b9116f9bc358cf770e9d8b61a4248a16d2909acad65c2b08a6c0dc60d53d09c59e838c4f0f1c716aab44e1dfd114f2294f033cb843edc6006664473d262991c1be3f261817066fab854d64570e23cdb817da47be1f9dac4394f8aa231d200dfacfd960e0f5cdcf96ae9efb0b07f703ca50b2d3b8b3d3cc0cdf194e84c676f3eca501150378d63684fcf4613bb32837a106310c9ef63e227e5c33872ca6ac421cb9e7c7d864352192a90a146e0314e5bd9f84ef527678a609848592d523c7d2c612ed23509920303599cd4a0ed794b0a5064d734c39e33bcebf80baa1be98636d1787e1b678d532253523036f182587722876f240745b41c385634f575ba32efc70fc162a1ef248ae23f403f5aa0a443145a76b9bdeaea3f92279f9c57af7c0d39d169f7a40b7159b1f0fb7108cee3fde500e851f6e57f394bcf7520c3da842c7755b8fa9b7d9b31eb787d7a2f5867d0b87433608c164c8ae5edf1c00de6db67c984ee2c6ff6c1a894f2230f96bc71ff709924c2d2ad0fd001e2c9ccdc735697168cb56063b188b193380ff0411ec4b4d77385895e7253b2371e3e4bb17667bdc9f226647bf9d0a59b1ea296860d9fe57fd70f696998460a8220749f2b08d28599825099efc44266468207b8df5eb5591dd4a00ec167e27ae536ae8e337931542554fac246b6f5120e0fc359051c998840edc109fdd81e56ce4ebbf9eacdfab1947f453bc034b3d2c27dc0928bd417a07cf5c79e225639a2f792a028de6885f75fccf8f71f70cc0b46c5f1d539a30d5e812f34afd09510aaff8fa4dddc0822549cab8e74126dea9a89aaeefb4f0307a083617586a0e2c508ddcd706162e22daf2ab62b13ce3d99d1fcd678e058821f5ac770d208c5078fefed67aabb894323331d3fbeb9b07ecba64aeea4e47918f6afd2256903897277bb1dc319c9cbc8e2ff6b700a2f99a7a9e10e4664525d6a821b690f3b41afca6d4b504aef3129a3e020a499760829b0086651e0fc8262e80ad8d7e8bd501481a2599666bc9a91f7e84f5184216793e54f10c1ac7e7214092632e603a6fa6c75c77fca21451731fcea82a5eacf26a0e2a06731e8f74cbdb7a77ba73a716ccdbd220cee1d266657f9aa96d9d1b9ab6b9a63ca7e56faacd8a19900d2edaec3fd32bab0fdc2280a4613f46d66ee7fe8523be24189fc9a1569d4d3db08e9d673e4eec35e862586773f2126ed00cfa240926df00a4e6471533fce91396e116474c3c0106f85291e72f4dc2f28163a115bac0c8f82dac4d72b96ef6141bc6c84a0271cc8ff009c38bb6affb12ae4df714c8d16bd880ff41bdb235e4f4f3679ed375198ca3c417d03bca9d68a9dcc8721a004479092519428c9942a80cf2d1fea4bf1359a0abcce9bc687105667e614333327cdc79f46d82a75f2b106c65700bc7c2fe13e1b3db829f677692fe3bb93ec59d188c96b38ab8cb27be0098ae03ba17e35966e73ff587cb7872717d8423254ed537054f98497aec21238c0916e15568d0a4bb2d348f4bebff37cd0254a121ba9dc099f059d1e26e829567f7ba94892b2e6bec56ed354a7c435f4dda696e12322fe789508ff8d59abae962ddfdc1f6d07a0a792b6c2498e492f0fc2a9c0e071981da593743964466e5aa8519997f355ff202c5b53f53c0df38af0b94cbf1f5f1c0a490c4e1e82d56c69188a612045c218c8ffbaa50dec70d26672b44ffe742e19a7f6fdd2663c58256965e953d367e1b1feec4362c335c1f6f5be3f2e2678df5accab67144e5f1d8c7316aa5637ef939915997b923018a2dafbf67e4c00f1ee5b0052d57454b90c204eea5b349de4f8658b1529760d362f51cbbac81f275aa24258a1f6119395a41b059d16923bb865a86be5d9b31bab77e9b0319eed1e88ee80cad6f9eccec4e0450aab8881e3b932d2cec9bab0c695fb0ddba3a238df61978543e1bd7e8555dbc85163f63d42f58e2762dcf7d05fc1e48984130eb09c6df7aa6f8547901942b079802dd79efc0763aa40d4a1290a9061effaa39b6b0db3d38ba62b4ed2e24677e4b5995d588bdaa417a52dba137a069e954c0bf9d893e5887a87478da10a3e5b2d238343c8975932ef3149c139ce0e52d704ed288279dd4108868e0c5fd4d408541643466f25bc4307535ed3bd21224e36b2f0a9c44563e81765c487668acf99733ca5eeafbd6ec2f03f4a4ab0da67e70c0404928832843367f7dd8dfa3e798cc300f067e646e4cb039be3f0b9ee84e2253a2689b4b233434dc537e5285d1385b58062363ae6ec809231eff1f258cf4839f6488b753c6b796ba50da9ee60ea084c936764dca09493d382871997036073667513e39f7cf84daa19e440b18cec99959a85441435bfd08fdf62e51b895b0c17d91247681ca79ede288f1590a41a93f991ad39882360c5ae27cdba6aaf167260429c5793cd5ccd9b1adef5016e64d981bbc6e58f84290e594de303dd5c45f7fe94c4ec6308e1ebc34decc3c5bc0fb7047d05e465b311ead1066bef6f532394d299dbb8d7171522e1b5cb450bfc9b4f0b8cf4afe402cf115c2c3d56f9f7dcb4428341ef1760e68a058af0e807bf42a18adef36a6c8dd3f63957416e08f4fba4f40351eaf5a009c1f3d50d7f9ed3e95fbae627b30ee21495855a4e512850cd9360bdd803bdf8449ddb9ec73db4f2c283f2ca602cb662438f6a1e227c3c135bcda7d698db6360d4bce879e81e189dcbdbd124c04d95ca03d5dc274f0f5011c68a5791f7a6c817d95d2bef506274f3b788c44a69464f2cb0000f3d7139b9ade9ef87659cf299f977d66c2ff1009b7178054ca3fa7db27ab62178c73cb38639ad5ac4b4f9c90c09897a5626750823fa3cc05a2537fd78f294db47a1f3a4a3f0df45231440ddcda4061a57807b421ec3c018ed87cd8fe48770cffb8825350f0ad8861e7a64cfcad27a32ea9370d26e0182db8f2db2c6582717a315adb60f48c00d2a966becb3e52383ca89c8012698d30286eae20cc8eea74f4011bb78e021da309366e49d047d1418eb580ae9b41bf260f1017d2f3f22b04061a0890d9da9683f7cf16a23336ad5010d61563857c890b1e267f11647ab93899b5f62151757564adcbc5202809efb6230cd1d19947b9fe6c38af442929805a357f3c9a3603cfbb996721101a13c5b2617512b416e7dec41999db32e8088502681933ed74ca29c75fe1f1352b4b94ff99731e1e4e79938ecda428228f29f160430a8aafdd90692c71b0bb976d944d1653f3c5dc8e567154bd8b756253e0e7580c0e6fed26b12003a7a8a13ac5ad76f45f67413fa26671ed93c0385c6df61b39bd6faaa109a0829e07143604f4801e5720458188e52959a5d7d6baca94f853d4c7065bb0bc0a789b60892ef01a8d6a6651be0a5803cbb28b5f3c3891b107ee99424b8d6069313d2ebbbc35e62c5805f0c60992c5e090ba1c32fd17e4d684ba47b851809d60113180c84adafaa24b7ec3bf08299051f3980117945db3ce2fd775d91574b1e4b3cb607a488eadcb387fc028e347cedd67e5163b6a34ab912383e3726ee01b85dd017e3ff17a06040f0357e474958ff9aa76a7c45c289b5ff245589b4f06287be8aaec2ca4b1c9c8f18a68c1954cb195a915f8b4cd8edde3fec5a9ec30fbb5496450144f8e2479b68e1e1ddc156405f45e28d0581eb1779d25c272096a1e856c190bc399c0e0c0d4d1bab1388b8fcc69e1997b1397ee0080afac909e7c045b2b181e6c6591e4ad92ca8fb6ca2e1602ba3d5881090048e7cf52791a5acf6ef22e49d18cca55ed2041ce1844555aeedc6334ab92b724d2f8962b5c264750a3c11f111af0fa4befeca44aa2c441726bdd51de875962ee9d673d212577e0494b893dc9f1f2076ea2b3af4555c2499f13d27d358884d030984c59edb302313af9b802246fc50a9664702315ed2c0bed99864461bae88b3e40d254a131a20a7e6ec4cb8081b6282a7be3a6e64c3ad1a0134be3d5dbed2c6932403b629b448fb656fc6562b68bd51bb069e162e09cd03dab434501b48d40481cdfcb9daabd62da73ce2a8a3bf20fc615f166713a7fc8be1ff082195134ae95c96247a4ba918f19fac2c26c4d5523ac3691aa5a5c132a133ad894579c03b3da7628cb296ffbc0f1c02b26d2fc7944e67915601c2d5184b79ab07f6119d595eea475d0968bb2046fa9fd0275a0c9cea1a1ca459abd0e309f723f2d4fcda9fcbf35c0287cd846c27b58bfb2df41090a7cdda70a508c473e33e733ede6fe8faaf627228bffe8085ed2f40a6936244ab85aef85c5bca5d02e0240350d4b564f65d6f27d3b9097fdd8260179d0eb1fbf33905a9dd9b693abe278436450cd299399907fe14032b97261eeffdbb20785798ad16774c7499abc7565588beeab1d9b62c6090d89c31a437633e82b1c861d126619c0d2537069f7f30edc2a2b3f89c9c0ef202035d7fda3d44ed9e65cb9b50b349766205ea63e24fc764c26ee49702dc836b427413b6eab33a95f77e0eba02375da3544ec7ec50997d46808267f42baa67ab44ed7d28aed67c781f8849c86f18abe4ef4c52612525d225ad2aa9335e7a7b6da33585bf1d6f4b592e853ea40d67ac1eb14af71ddc3b482026049b7146318c5b95051158bdcbe53a46329280273f235588625a9e726ff33c793ee859d082bd3151694f0f89028945fed400869570905306138e668650bff26a7f1b02a89654f0db86780258bce146720f3a14a80fc0cc503cfd3265ed272291cba4651cbdc0e4c3d54233b67a994ec94071e17b10fc9ad959c6863de13a3509103ece71197154f810b28aac71b810b982c5f69555cb0561bb3ea3b50ab5ddde324b7c4c19d2fb1972fa2a3b74e4a10354df1de5d49e35a79a8291ebf9b2fee7f6c67fa79058ee19ce729c060131d2af4fd861b510db865088016e153b3050a407f3d8754ac56616cd460a130f98c50babc8e9d575658cbed9d1d221d8b00651cc208058afa0b8310e85cc80a7ddb6eefaffc2e24f7a9bb7d886f1ab89ea8cd108b770f5b4ae139cacdff4a5753a2cb2a986ecd8d1a5672ae03184621fe4e08e210fdd2d3253ed57408c8d9f8a1727bf22ff4810deba87d44c8ebb40a3d7b1bb00640567909b401aeef254306c34412933e4a83fa0f614c494617c85cbd19061f9e8f1cc778453a8f749ef7c45c2ed2a362a8a9333c781fde05dcffc47a7280b957c8e75dec96b78878f9f2eafd40486538f0dc8a9e39944c785d1369c52172e5804b865177c45ed0e44dccb5bf2f1a5a6ab004e73e5fea79926bd0cea3a79e3a93618e933c9c954fa3a37395753930b1fafda91895b12c721f475c1efdab64105c874c130a5755b2daa8d82f4e39a095d9fa488902783718ef9ad1bb24e65ad1c63d9567cce61e87f6b5065a3e2929eb8d70e20aafa251934ecdde984a68e2f1955c91ea19b4e72a7d97c4eb0f85d5cf6bedbd8b12760395cc5b1f55fd90b9dc34f130ea2afad88ab917a9e66a61aaeffbb2946c79c6b23b161440637c1e1b19d7a79d489f52d347dad34711c3dcbc2a220054907b8b7999ef97cd1fc1b298a2a2864974c11208252cfa11882f9bb40d678d9d05956cf293512ee9c19b81fd6469576f48e8d1ef735fa2adda5059227711937d7cd7fd1b4f82fbc2b83b198759043ed751758359cd6da4fe4951974b66fa6156f5200164607de9b8bfb0fcbb561625f65e683200c49793afb5cd2f7ae0a9d5b3e1aea03873e66b1d68336534a935e6574c593d589b44017bd5c1442d51c1377a1cf7a020e84c220038eb037822945d2066bf8bf94383348cafd4ec43f15f965eba005dfa38c5f94d79dd0173418361c2652c4ca4014c6d0cda75a790a6c3b6c77e75d0c172c28e944d97def7b9bf023278373652ac0cd40851f94470874ec892d80e4205840504dd402b76863e2303983f840333d48bfc470146927868b43caa0f9fbe56af036f96627567684cf90fb8bc94437a27313e898aaf71de55d93720a664894be15e04e6b0692eaf21fa7ed279f8ecee91c9fd8f467f3010c54e58b8c3ee3cf83588622120379851b4cd506724796c55f7c137466dd480ac5c23d954a913415362dc572455ae454a2fa6092439b9c6a5632d84ad71aa96dc8574cd10d4143870757fda0eaa43bb958222f8d4f7e664e680ee7214a31420da84cb1fb486fae544dce469705c01619d9c14777395b892979c8276f4e656f3ff1923bf5f7da8e5dc75a76dd63ed1027b3b2512661992528744afbcb8384dc81d9c1addc6d13ca3b4ac70f33e04fb5c09c61d7fd5514c3109453fba7f7376747d22356e95a6c70e4c2d30e43d4f8e52825e83f163451592793fb1c708164ec42cd069b40ef372faab79aeb5d08e02aba14c8f89772c5c113ad6d4c635d718db58157d815a4a540b357f6686b29886a4aea35b1704d1423e1ea514af9eff46b03f7e40c146befa2e4a082743a62e493c56a59388c72c3b78637e7bbff6969afd01bf16b2fd8b8e0759dd5281b2d690b5445a2600ba3bb5515997af3c8d70a40faa3c1b6087b63274a8b953c88c22225637f931d6317e1d340abfe51dce3c8dd119ce2ef6c68a957288fa3e424ecdeaf16857b9189727cf047ea352b7e922e6735381b1a3e739024cfd994f4354e97e3df4227f08e61f1badbf04485f10658a42871c8f3df3f360f35c3990876a23d97f40af8fcad37b82ed38419ad85d44b05b3792b69bbf0a538118210d56c9d4333fa67820e086f4e56ad466e606c84f4cc9462702153efcefb9738e769f499ead904a0a266ec8e39eae699386d3d1a7e69c01345e61371e855938d850fdc6fedb294ae41bac012c82413f3f2f3488bda9195b8929b8c64d9e603e042d3824816f551d775c02bd3e042014622d81ea1455d3d8680b9020ef09b143345d436b4465d050acaa6bdd20dce09b342c0965c976d7e9c25811478f4935897280789c09e052abb292513246b7292ef97b1517837dbf7584d7826355e0c4c82ef4bd88cbedad2485170a98539c7c72774d0b2540bc64188c89bd4c05e44be5e66bfae8ca6d1844ac0aa6cfafcdb2c7ea527bb247fb12b663922516994b220407241a8c15df45c6b444b39f42ed0caa334e947ecea01e0e01b4999fc8495211cd2f03f5342e3dfdb1f314381cdca1b12f74ff7cb04bc79ed7b1a33347745c388eb07c760114d84ca408d1c2c6eeeb920ddd7f4b89be9c9c319e6a46769846ad9ba88646391849671d1224732c42b43c5fb2675a15156caf76d5d332685408b87f92245e70db3c999e57f8ee08e4cb6b836568e291631cb5a634c018363113cd8b3cfb6bdb6e542bc74b74e574cbcda6fea681b1b81da88f32a6412873c804b49388c3e136da31179c529214288ebf626180cbb29ada0c0e92697a3809ee35d5750a928a5a01ea0ac8e4f3cb615b002bca4909acedda0f333409b6a8ed4e3245f99bef2a4fc43a73bef2fb7e0e3d0e7347db10beec567b7f6d1a0d95bd9ca1bec8a6c67c091fb30685e80d6f9df290de3f41b8bbb3a4fec9566cea4745b2db16939930ce3bd515f85d5b054d88475c0bda4162217b89aeb02acd805495fae0b5827ca969cdcf76bd89480d51970bf68df2eea4a53d0febb1f76761c0d640586cc66e62c8f85144b571096a6c834dd44bbf2ecbc343ceee97e0570b77cbd8194313241a8d6f814684919f26ca4f9db682b84a6d591f1627ef86871d79e8a3d83d84f62c0c77325bb241a1b45e6580df458b80d45efcf3ea95b322aa279a250de6927100e51c66d354e259170e4afd76033d9977cdc7e34b2846d1e69aa3ba28c12c3b476e67b7b868fa73353a5cb2b228ed5ef9e33f85869e1186e487e5fe96b16a9b5a272eeee82fbc525cd913baa6052c51345e9e75a87570bb2189594c749b3f56d395d3c95392e2f4efd9452f95615b5ba1cb1786d18f655fb0ce96ea9525d003f817b37329f8c345bf4eddef37d1cf1bd719028622cfc2b325821db19f7ba70ca00ae07fb9e6ff0df889c884134f86796a680473bc76ad9a9b8b79ee7ce6b782d652615554de6fed04bc06d4c5f3bce8afa8171c83943ccd4938b296410aa9cd437b9fe052d0d9d2c078716da054ad7b430e9c20ed62cc48f3b0b12857949afb94e68e2d7779447ce82038a4fa8b21276704162160b5ae71a9a9836070e28496a2df502a8c404f5a13b6880185794ac46de8f1e1450c069cef43213e6d7d067b47545ed0a2bfaff20f11d798c13cb7c0ea1a29814602aca5d6a7d1116f97fb6bb8928afe32fc443b7e03448dcf4874939d2fb9dc54ec2be43f11509cc9bfc49e80cf4552cee392d321a1e4529a54b904ac7a88097663d64d949d90f9df9482f866cd027d9394816b029639427f392b781a70971c310ae20e3591e59c76dec0c768c1d3184d78891321861333118b865d15b14f08487316573211b30fe70bd8cf11715acd5278cf10a3bea32221d5269fefbda5878ebf5e45ddf2f580b1e0a1f19e3bceae34a3ca7159d3fbb125fee3b28405df5d8e0ae8d9c9cb25ea15711ee33faed09b2d18771b047053ee9db5f54c8451d475a20e5a17b14d88d1c8301264099a13358d0639bf96f600c542a812424348cb027f0497f9fe7b13e5732f99a389429bc1f11394787aa361f293dab8b93b52a80a819256b34183c7a99e35c1017c6de0eeb1da011d07809e703394b3ec37148ca8fea80e8692c19ee376cb7c6ed665c16753b526e43c32ef1f1bd40ace941cb2aaa1e66452427fea2ba8a75fab091612876a1e38d134474b6dc3ad6b9fd9b3f94809387112a9dd0ef897e794285fb66e4ac3eb393087579e873d8b645ca62407f0ab9d8095e7d9cbf75008d63c3906ddd2f69b194ad87279b308c445cc5a508f8a2c0227180d483053a945664be07935c3d10bb00bf16f8b34444fb3566a0bf04d0df57bae4bdaedb39497190f3556c51d19fd7353f41971cd0b7ecf145af628b364c841c6d99ded3d8eeaf3d12bedc1288585c112809dad72c3a1141ef622ca7cdcec4ad074305f961212c497d5e3da196ea4fa4b87e00ba79012d0914e225461a172ebf1c89cb49baccb27c31383893d463c2ebecbc5d4e4a2c3b54d0e38ac21b90c5e8a7dfd820d074d70f2dbc5bb1c3cf01c3d8153fcfe8e7768d801dc8904f5f2a77d0b8c91dea52209aec560413126372ae7adc81f0b6ae0d884be4298a59524ff80cadf0ed8b13804f9ee9a5376cc241d093b5d04bb43d01633c1c95082b975a7bd22f27878793d7bb7ab12a665cfc727bb4b30bceff3740683a3d17ab1a07db3e5aafece1ade5cbd1c6506e4cadcbf36a82c44c8714899b699bf1a88637b66f2c9a529b2c3875bf03b4d20e451bb4411dabaca8a03dc5cf031028da62da85bc971de37975f9f4d787cf24de9f236f7fa543f59c33b8da97a6c43227be219de69717263d78605fd8a262ef3bd56c1264c03834d1dff8cfd00fa49b9a18e46bb76633bb89227e609978cd67678572dcfab9405093fc8f92fa9fe8ea643ea110080bd1bb65c107c6d1516b5d8ec820abfb7948d8a91bccedd2219c6f6cb123ae369adf1cdaf44512d425acb64e3229acd232da5259af0681efec2a944ffefeb1cf80774e41f96e488f2f4e3d9e5252364cbefc358e8a3603e4eab29bb9362d37c3a0d0da615934e2d83c51fcd725a16454ca4389ea59efefb34277ab9ec678acd1c8bb2bd39db618a5816098fa94d3fd1207fd74b547ba1db55ae113048074599f588083968a4b4b85c0c84248c2454c3560c5910b455b2a3c58afd21f71767247e475082ab953b7e45f5524e9582465da05eebfbd6997e4f992b2f4f5a4db881c06c0a4d7d67bc1f89ea57781af84669ae280a0b005cb07592305274b13c07cd274cf89909791e90d7ba5677cbc703b3ac5b6a2bbc0458d9430b0f4e52040706b70b28e0a3d51edd8c334f4659e53ce3ea64c5818b52cf7a23b852634ae66282fed75974027c7a2fde03d72f33a0405017752da647fcc6586db16759d20ccd138705eb10887dc2b1bb9f8dde688f2e05b4cb06bf1f171dbcbd80c00711a3b064f5078878e0587d35072b00350cc416c71bffc577ba38cfe9e967af0126ee13f70d83e033a285c5d09334bca6c27ba71d4e8e328cd8a3824c3210daa9f7d9a57878468ee0bca12ef01190798b1a3ffc4228f214d449333111590d5e9085957caec71d2b76522de183abce98e283929bb0c3c32741a628e284cf4c42337dd292702d28e9a063b65193aa756b9b1eda37e107a249721fa66e0f566e236b042477cc24498bb8e115ecfca982a118f28991640a8502217a6d9af9a44964c5451f78eacb86ed401f0986db768170609ef253a239de19d036e78063c364888868eb4f10c2f1111fc102250502d7c51fe605aa6002b85e909bc48b02bcf7759d2e4d8c4208ae03b9c850bfd5234c496ca985aaeb6efd7a03c2916e8861f80379887ace64a8e5f198dbcc28c6d44d9c4ce7e529bc0ca89ee8dd376702f2b4a8b5c505884c3894d7888b7a620bd351be945398c0a85df348a5c5e1e617938bd8799b804ffcfcfb56b9466af445b4c140b745c255f69a6c79349a4c32a1cfd44aca486ff290fa160413f9fd7e16088e5304ff2428d209c36ddd3b0f651d636f423e24e3320371b8b03a12f390054ccade002aae2422e84fda2f007b3e7f929ceb911de67daabeded28e3995939401ab1ccfed6cb211e1fb8e9c187518c63524fef89127360f20a76c851bd7c98df9980922f9671015a120dd825ce4a4e670314d0d5923d733f64cbb2ae0954e47e2e5c9cdcb05f3f7a0d2b91111e5c1d641c654b3f12f543fbef36f58b32b80270d27e48eeb3d44c9987368972cd5938890eee583a4528daa243cb9d2ade01318176a1ec83400551d746c05257377d79dafe0e0d5e1dd9e0445983c947223a40ab65dcef9f373b469a651da47e74725e73d077ec8e6965439cee220736b156d504384abb47256734552ea69b7e3c8c6aefdfd39f684beedfd5addfe6a32c8563234d1c9b611a3e59682de7efc3f9cc9523a56e9d1beae5aacf5140103989c2fc295ad7a234caef29f09fb5e6c8108683702b27debefec2078b7bd8f30d63b3dbbe5a09ecc83aeafad2f8a7bca3eb97811049ac0b7062fe9bcfa42ee160a889461a9d8480ec0e816c7beda7fd032f960be7adeab3b9c8caec1322938b0c99fb87ac18e95726d3589a2bd914ee15614c8e2878ced75a91ccc2b267971f6206033d6c40842659c1870f6f464d0c4966ca4eafb8389cc5c979f83f208c3a8d5ea6a5ecf2902a3fdbdbe7d55b5e16bcd1e2d120c58a4eed2ff44c5a23af32a21eafe5274ae675bd202b1781b7b977bc458f31341cfd3a5fcdcfe4d16fcb1bbc71d36bb536bc0b41860ddba15cd57ac95a4ee5a80c2ac4628206b616561048263bf22c5ff297ba0589ea6596df46e90b8098d1606bbc0d8cb5c1374f38568380e479d9d93ec01835b218b3ed3b6017d4f146672bb16272407914d98677cbb03d85075738d915435a98ee133ada2bb344c77f03229762d1a06247fe9559683c493fbb80a63901fd4f30c9ced26ef9665f39a0cb7827a2303ac124d2cab1ad8efc8815588641a00990e4063113cc3ce6e48e056335808fff5bb61c61091b26e2409cc591941127f89df7548fd6e0a8fdbe87e72265b03bff47b848ce41d279cb386505bcb86e1512a82682e08f039accaaa3f1d821f8b8ea833e666c2bedb0bb1f41ce8b1f41b25704321c5dc7982e73cbee39979d9c8b07a7c1ad72f2455de5e6079621ff4397c95624d4c4e44f563a56fb85ce99d6693187bfcdbc7ef206e312f597f6ff9b4fd2ff8f234c3c873d66afc7ed2093f3fa336ca02f5d93830634cf50cec09e5dd3433f6de986aeab6a67dc425b6d72fd445846b305e31347b76ec7c9e7d26b0228e50bc1cadbb018cc32c211f40973cdf5a195e6c31f891c26d75cca0749b4b01b4d02309819702979098e58cca06f06ab16a7ed5b09ad5a57cb942e6bcc010428c38bce727881b00cfeeee52de91335e62b9b31c3c7e1ecf528d05502ba54c4e92d902da8bf41db79a83351565998c25dbedd2dd05c068fb2d08325c480095ba9da00320370fe0cdbbd9672169adeb1c5c013deb0c6f7824e796a75f927ba961c7da8c82de7a2a60552eb63cc2e7273ae33caa3e8c15def0aa967dab2c1235d47204ef60e8ac14ec39c36dc66272a09d368693d64e1a7d8548b501b9d64436f578cc0a91d7fa1ebcc0711a8a396a00f098dfc105b8fc4450ffc77fc1bcbfba6881b0130f04f78fa6199ca3e2ade1e464b2d54c3d9d36f3eb5f6c814e08db0ccc8a76b8fe0aeb85e22cc28c6b76c48ebc9e4c936c8cbfde80d50067932a70488eda1cc5418fdf0c1161aaa3389b47e3568e02efc6a8476a7a1c95edaf4cebc1693e46c57d739fe01def2e988f36c9a2d86089a8205a8f66a017ecd373c5fcf5c9a7677e5bb2564ef4187fd61ef230d5bedb92d1f3376296d6a1f738f8037c5425e256e2d54a054a277593a3698de56f2b439364c9a8ff736e74e993a741df893fd7fe589cb2097de9d4892cd0fcc27df14b77d7d6e2a4e32781d442a1e5c3ff5a487038e8bfe5c3aa06a8b44c53c4e3fea58e58c9d6d59e43f9c455e633b397bf3547d611b6e0fe3263b90fd73e503155d8135139d6ea9bceb09dfcbee6b68d518ef4833102308f05bdd9bf5e872d11da13a5cea7090c6215cac0eab1a07306d73731c952939fe242c1b2898b4ddc289d37ffe24a95ae4157389dc9d49c8b8f6244b2b55150a2b45e149a04005988b148c8820015d5117284e9fb3b9a927bfdbf90611f5345564eac866f1a22c833b2af3582bdbd6aaab9d683f4e45240ff7aa142329b53ecbe889501b987441c07c799f30585fe236fa0e10660b4c4bb9bc5daef4d047f0d4b9e69de3d5198d97343f303090520fd3832df14cf52cb583e3a6ae78a3e313981ecd011150c5f52546ab710b1d5064abd2d6e1a250b1e325e8dfd948e9b4635af7f821fb0f95e8ae8cdfdedee00b85f71430b41905ce800b2fd544a4f19afa98c9ba5019845343640308146e5ba8ddbe8db12775e516ccfaeef95d2ca8eb6b4b7c1fac90cb34a6f0fe87649fc06acc9d45139c4b2d0f4447a9589fca8468efd3465d36e01ae6c6a556df1417ce4da61366f3b4359e082c43f7832b46c64f52da8cd249d3c30163eb948199532daba5c35013f8ff5c0f246adba9cf79a03f0ef80038feb71211ee59bab93d725d11efff58b77a708bca225c6b40eb87bd468051d9028d183025c67c6b9b8e7c1907b8ed204326cc6ec953a385a8b13b532a145d74d78808b17360117c68bef7be55f3d8f9f1910d46be16b86c3f8d810235cee45e0945e111541407b8f3898c8ba21d73806765582bb4928b726323381f05acceeb205f0f65fe50fc70b016cdee488d459c4f6215b24f8e0f5e5dd2c0bab0a1b2adadddafbf6e10a9ff2ecb0478da5d73ee4691874bbf53af8dad139cfb2a97cc9f3b5be8edaf5602ae0f6b76fb911353420ad352d76693d5b827e4604f7d6ccc57556f35a9dd8a62b4676f062a3f9e7f764ca50b4bf98e15c5fed57208ec61e6aa52410365a32a65e31a3e93dede1b81ac0b921612618fcaf5137f0316924cb2ba91afbc3f088b3412f0ee0ea5c0f05c771a6c00f637c2ff4dae3abb303c073a4860960403e720c204e7f1fad39709caa27d337b3d8f572b435cdfee518661a1fab8e64c7aac1586b56135d92d04ee9f4d63bd516c0b8373841cfbc5d25c7e808eab1e4561e0a7a93ef7c731dabbdf6405a5f8b1bdd92a736942ca38c1eb349ee051910a27e10fa7b91ca5c36b8823aabef1560e81e719523f575bd954e8e7339e6bf5a9e8898e34a5044c255519bda83282a5114250c62d9ee4ddffa2f527888c3ac010c8901da01f4464842662a07192298eb8ceac5f06aacd9ec8c095d83b6fc4750ef763061710191f7f4c928bf0213922e17cfd6536e7b33fff955b81169749f1a24fb6bf3cfdf9b97156092585e526e78c3784ac03e78a6972122ec1f555c61ad2cff36ba604390421589e045a8d8b84c40507adf6880059aa38f437afa672929e0c3aab215180009ec6aac1beee8a69193f681eba3c8191780fbf1e20b8c2f1f62a7a115b98eb1e41499b8844d362555183c6e3eb8d203c692595ddf8712006d00f7be4fdc6b42c90b9d761a1a391f2804a517fbd31befa9c2c66238b965d8aaa705457bf331492926aa7fa412072f2a55d43b667c3572a716943480992cfbab67cba785ec4599643d24691e11e90ef8a5fe71226254ed1578e01342370d100a0b908d55a319bd39f03b5e4f8ef37e08f08132b861af9d7cfa2472173224eb4b1c38bccc3248538457c8053a530a8ae51adb598f00526cbfccc4c04a98af0306c82a11749d0aabbd1b6b792271985770eca1f4997a4ab0c6d8d5338515f50a40d8c8459d845a8b275a4ef9042e753d4f5db404563f4b071639572520742d9187634997d189dbfa0de42ef91b8763fbbb5b317d6ae28543b9d112125506f9e16be829ca297f0c1b3df5090a63763051609219350dfcf5fa94678abcd5be8ca8339671a17cd1c03ff374ae99f51bd1603a2fd9322b3e8e4cec10fa41f4cc756bc46f3a1ec5d0f301ed8ec67339f317579e66fb081581c28588ae07f415013c91c18fba3b17708d838dd92f789e061d1356d24ac02c0dd0d8d3ba44f89d5c8068e967ceb94889e3e9e87064450dbffd478324cf4270e13f38285755964f537853fc403042b298e68b8368f58259cd3b0ce9bb468b55bbcde7aa59f90b3b4629364c128dd11106a82541c474d47441defa9a7f9938c439b8a2997211d64c9642a607c27432e8c6ad1ddf089a30ec1f4509bc0c26b922cb9fd16c68cfa4cb6db18fe540352eaead0413a5469fbe9a65cda02c7ee85ee788a1fce28727b3a4e2eb0d320e1b568b040b8c4bb85aec536a096d12d0c2ad7adb391190e3a986aad53d1cc8640f6f42e1375e6a17673b6af547e90ec9d18f0c7e447f8109d111f3446b3c72ffbd4e54d4e95daf9d7b1e57a0a8dd50c5395789b2d50e58a0598d51e682997d6239a6235c1e3c1d0415cd0226df024a5d5a4c27010ab4488784b62d83eb2d66ff073183d34b028a101ff8c223eac5731199bdbb907c02cb845d3abd65008a26b44b5ac8195b12931140e5271483179949ecdbc3599abef333c0305bd4f7005d9bf6366428191c05f3399ce9027f82b5f5812e71a14ed8a77c4d0cd7a8b9084e4b95c997e3b4041a64a454ff9410ceba45f069ec5ac8f434dc2172e147c05c3c255a094cd68609be864c7187b95aa7c5ea772e295581975fdc8624c10bbb847b41986a1a18f6385930a229bda2ed9acf82e043662dbfb357c6bdc288f4f2f1dd9f77ca03ff6f0466b223fdd86e13ab702b56faa9a1d2124363f76b2e59dd73d62910cf27ca79b55bcd0c179e0a1eaaee09b3109ccfa525ba8aeb28c5c329b5aa16eb2b00aed95bf1f3d53ea74f7af1c0e152137d7690c7e59a8a7442e6505a20e556a8c6d0361215711ab69d2ecf02ca479a40cf4479b4d47c8e082d13e4a78a1fb250f3a00e2a7b03470a6e790f266847048d73c388ebbe0576a69a21867b50a56d3240b84eeb1050ce30f51df03facf240fc2737b75f20f8c1f0bfc00d985ab818a44c9c3b43c214af8684d774b88823520d9986bdc0030b48be3261e90744ad06447b62123fca6aea5c073ab635d7de7d15104668d5471c72af988a05676de3d14e2ff8b2dc947626ce4987912034bb469ec6d324f24d2e0ee99d784db08fe7cecf5b1a85aa0558531a752b115c0f2902828ced5ae075662a5715beb97eccaeccc5e2204c011cfcd0ff0a73b3f79512a78d65da5f2c448e41ef030c2b793a33b53233d8ca4caaed376b14f1439904c84c6a534eae9459c69948654fbe1094bcd09848c0bacbcc65289c9ad8b5acb7253c9e63d59047c13374ef98a28495f3dda9c917b0174726125df9f9242e258eb46ea183b467b38bd29773a06ae66edc46e5d3ebb7c30b5c5ba2d6980648505cb5769e37af64ecffc9c9fba4c3e1236ca722b7740ceb09f8f65017f45029694eb6ee9366a50715d36e507b1462eee151948956beb9ab25824611e58059e24bb288efb57bc0ae052fc7184c732962b75c3f599088e0b2145dee4b46cd260e50296eb3c4334b7da4757d30da6ee8a3dc04250ca2ec6158c4b39c02e002a30545b021a93569152362e60a4fce5e2b0adc835fb1fbc91e79c5d32e3bc4491944abefef218349fefe0615bb64ec6086ed398ab56074b98787878650a5d84ad8688c1a4815f5be54c546513d381a6e744de59086391621abc8062f4523f4a3ffe4e9355cbc8ba6455ca6044d64691c215b44bef2ef281d8a2074969fc411ce749b3f8de30346694764432f467d152053262610252f89f67f47204e3152dffa2b00d39b122377c1906cc63ad40f38e4bc1dc49a3606060517cb5453d0434545ea8e02870b859d2797991933fa02d40022fb9f4ec487b812a6b2c551656b6162d6ab1759e212cf2d42872a43e0e3ec372d24f37d0f7a0e6daf41a95c80bbff0e0bebe6488af7971bdee534414e3251f37d3ac799860e7f5fd4b5a093b152940a8b4bfd6a2994eeefb0eba935904531738fa657f40969208c7f7f2994a5ea02f7a8ec9d0dbc9c4cc21d7bdef28a753fb66440fd19f869495b0254b3fb5a76310280719d06aa424d6c656db36ca44013692b63648166333396415c843628f94abe19067717ddea9b9b8f4ec0f5173844da8ddb29f5b633229295c741d50b64d846a6919f798061e383158e3dcb2dc83e171a1a0db89c16000c92fb1e903789fbd75ee15ffdf1e465c35fff4364afbfaf0d82d4a5c1b64c31369c2a72b2f484b7b5c773234f066760f09a3b486519ec1804b14f5ff005528f40c6c140be2b27d7a87ad1cefee41d59701c540c5fe38cb3f408a28ae60fb1f489c352821e5f3eec3b983c7e84f070902cf36a5f0329dea20ce823e7d52cdd341faf293e4d3fca3b6b4f59a01d18d4fb3f0c8ecfbf3645782d48937c02f98d68dc1790220554f573186f890bc1748a4597574a351d09bbe7cbbb13eea38a36032b7520b900d31dfa05b628ef1c880c30eede5673e8ef87be4c7e1eb3e55b866e0a79dadd40aabd51e921593fb3eabad598bcd788bf04b2c9ab31c7e75d4e10c224a11e9cd4ba65f08e3cc21b01dc220f0f6f5ed04294f40b74bd946c45b5dcd841042204f87a0c9717aed7ab3d2a7e0cebbb3119690915dc9aca0012a7ef3130b7536e2e6ee58f192d5b0ac29fc0b596748b9540714395b971c789a720136ea2fa8be33155595b6d6d6772a90b580180f8ce6841253249b30222e85683a470d91e0ab8f4b70bc75d09e98134fd31aea8ec283a8f09de0a7ee68f366764003e7f76ae6ad0b9d7cd06599c9ef408b1dc97c52c82833c5317b09a78b3d65a375e56e4778f4b56e9b52f5b88efcba089e1a16d9a76bde1d1a2b4cbd5482a26a1aad7a7c7943776cf268f8881cfb7c09d80e120685fea9d962354b9b78278d0108992b8e7119a2e11882358e84b6a0ca60e7f372ea5a4288b6d51fb7484338e9e5e9c055cb4eb64f71eb6fa4a97ac46df0ef065bfd2fbc7191135d0314496d5d6f6d0d4ea9d15c51499160462b4659f6f67cb5066df22d47c1472e245c4bd146381a3aa6a735dc80d6eb96ee6631cd488ef3e049664085221c92cc74329a41edc4081a040d95204220ac4b61e7d42aa30e2a0e28860eaada6da05f6e0679e86e822c548782637334fabbe432b30e7dc3e7d8b0a66d3f8fb007fb6a188bf7533a02dd17b61429582066fa45ea122d13a8f2f60397ee7b184d750926b9fc28f8c4a6d27e452aa3b6a52f239f446ba9eb5507c1f3ab679afd9efd684f1845eed7a9da8cfdbba0bb96f3a2cac22efcad9e5dbf43cd628cc9c14b5ca529d572770bdd9507b3de01fc7ce78bd3b4d4fb9ca8ef177eb6d58ddd0812329467668e28bf966fb571cf5643c7faea3059afbc912ced37bbf97b964c2784b009f2928709a1825dcaf8ec062162887248ccd996342aec5b84102d5a6808ab3063cc6f35572a62e1d60575b5670401b140f2f797353a151969c240abcb8a20228c53ecca4065eb49f49c471e4955b3b000f70e0a4be99a45fd90938b70e66deacf1b407386deaf54dc40afcda5a6fc1ef220c125caa2b68bf22ebd66b1a2b164d048e9b91f043cd90b1eed4d2ef84b7a24dd553fc67acccf4008e53f6b294901957b12f5931b6ac2b113317a808dd0198c10ac51bce247a1bc793b8d6e96222823580bcf9d5e2f028cf6116b88784fa1477a281d1478ca9f35bcc636c3f7c5a281d85d147496f99f93eb35db15e8cc61b4d7efc7d2b79128fb569443dc1a64dc61fff640d6f6c766e0d12215657bfc6f62c4750b4505f78ac4e10a64a32fe686b7615b69c5c0ae92c0a22700f846c218276444d40cbb17ee03299ae07c477e25768117b896aad7714be3377a34a3d45c14dcb5d9f716d6a977369d902cbfce970841ffc4f5af51501f3884f3e731b1a35867322e79ccf47e886d3b51a4a280833144b7a5474a04d89b0964cd6901b48ca40eb973c2bf394752dc574425f982846bd873182f02d91024493f710e6c14c9b46c4a1c08594c76df400da0f2e01a8857bfb5a898582d00ae02214b6e6ef2c3454378e5c21489225b05db4ca9352e449d2f2eee4e5bdda8cc85296e8ac50286eae97a543630f61db0d222c49d757cc95473c494f063da26680a3b9513ee5830a644aad338cc6feaa84f8582bed672ae3304b0598e44f3afd3aeafce0814fcebc18e38b4355e87072329138114b99cbc3556467c8619dc2c96843a39cf5423fe3c5f823b705ca74b8e12b46a32ad5bb82ab18456b044bd7f221badef67c1bfa5b8b8486a96f32ee7604e8136b2d3b1463569c224fd5081938db3842338759a1e62d8975b51cb035efb896ecd57b988c9f98db4b8094598883b5774d6e1dee0ee66a529f4138a8b523d5f4f2ba775c60f15d6eae4df50db6d3903c251f32f6e456bfd982dc5d33e1a89a497b79b9dd5ab2b5bd0f546a63e5fd02c775124834fc825ca88a773ed052fb968884c1f2d86d71db0831c29fb86fc8f1f562babc4a55819fdc726bb5025497ff15f070fa2081c07cc1041d733fc712687c483b40499f62515e8b23b4cd6136430e1f8114dcf68937942d3cd88069bf34d093fd49edb71ae438b505b0db13f7fa85fc3c3f90a70a73c1eca04b893d396d5ce548a608b56aac3f461f3e1883c6b6145afade6c7d47486aff547ffa1e309464cd51cc8abe60b32dee670bf29f10c5d6c2f7b35403ccd563006149c698f491129f04805ab7acbd67fab2c9f2bbfe74ad21faa31db21bd92974f4ce58600d52c957c734a6dcfc42d1043c1063cac03d47808d022b21bcae03ecc905fab4299a5ea87db60ca89c75f3d0d2d6df536c884a9d4de24943b1010180183ff4cdecfdd7ff9241fd9a3f61ec02c3eec0649c7ef1927276019a35cc76d40bbae92d2ad134498f5c8291206df0f47f7da3b3add1c53e52f71b8b45a48358c0baf7b80207945d21a5a14b029f29c6c70cd2d0a7bdd7701ae00ec42ed4f9ca8876dbd0f5a4a714e3329225f7429d8bef3b3c99d5804b695a2a18d2241c265321802d0ca5994d49fd05fbc192997f3035d7f355d2f03040518916a39b8fff20832233f1f635301b10479b9428b107196bd671ad3c79b062bfbda63a66242763aea0c90d8f195331cf40e55788661425ecec129d767ab7dc62db50a9c6a84f3822163ddd55f8aaa6f9070b4fe71b9257f7fe4279840e06a57414ff1fd6f14506cb6ae73d3e82b04d2cf3a883b16f3c95d1a56046b6b242048c0990072ed398f2284a98ede53d156c3e4e8476ff4f68ec85cde5dca377c65af6f9b4c88d5821179841d8db743c4295d300d020c28541c4b5389179e5c20b3989843763fcc75f9d857f5e82e163c75dfe661eb532b4e5578532764f12ea9714994ca643d5d1029edc9baaf7000df0d511dac74852796846c1140f720ba2c0b81615470467bc1fbf81af2b421fa74f0a7b3097fa2f612a1c85999e5e965986774b936cebb08a1615d8f89af748212b572a633b99807a0de10d7eed93b476685f9203cf8e17dee0cb5b3badecc917645e8fe4fa6bfb31a59689760ed39378155441df9f182902d7939b78b6dc8a6cd193829dd2599a328ae56e931a69485f2420d909b73d9da4d84d927462421efa566b53b5228a0107d2fced97c73bee3e59fa9b712dd61f4a8197531e9224f95e5559bad5b270a3965b34fdf71ee4cb7b007dddc6e84e02a8610ddba6924b7a9ea6912e07d494c8523827b1894ba6bdb50e17f14c40cf92aa43dbd6a21fd9b01eb48157b87166b72d1c59ca7d6eb591d4bdb5a9bf96433a7e90c7bd05156dbb39fe5f73f3cea106fa4e084904765faae98450b1e28076b2fe166cc501fc13e348389cc00953170fb69d8d17ba463bd930a6b2fac7a720f214b0c0800f6303326f030a2d08d7d76b8d8702a916a057510362d2b2dd0484e9762b938f4b76836b77c4f7883706d9d1414ecff5c94e9cb8cf875985b3e26fa47e7ca633fcd83da2d6d97df527ce3ebc575aa9aef2890aa645f1ee506b4524da4930761a56a4536f3090473a97474df0f1ad17b5b879d385ba251ac5f9a5c64b7d929518719896832d579e0052db554ab831fff57550b9c2cbb03ab063933e05b1c0293f43044f9dbb623825ac23e12b1fc4e674f0098f1acfab472b1594b522515a416917106e990b8ce03c3c34091291c4e8a813ae3685f0ef1a98500f94308a1d756dae7cb2a5f6e658950c04e4c85a4be542a479914dc310bf9975cf4f322f5b52379eb11037ed306ebfa3655f630ce5fcc01e9f9c98166db4f5fe5e623db08419def7fa089d080841320d70aefef0bf2a4509736d4381f81925b79554291f956d85ec7962c30373e2240361958d5fedfd12f05eff5a5d06742e4678de72102b8c0549b00b2d21fe392bad65083ecc6012a327240bbb1ea6a11677274c30acb7e1e5af74a3b836b195388c735e1b1f97a0a6962a55d1d9f5c813896a7c0b1d1625af4bad9f9cd41c8c43d778dd373bf0f9e755d83c2a86a444a63c997ad0447c40f54632fd0670905deb60dba56a574d4649c51f7a314de94b19759f6c873753408ae49f71aa7b714329dc36bc202a6e976d140ff3529492b5c87246bd7fdf145c56e8408bde28f1f9d5e9feda39d0c5b952a073dff8627b7ea805f9d57b96121966ae616751879a27bc0cd9e7671d894aeb0148c3f6c6b94d53e09bc35b44753a9e4d775fb5eec89dd14b66cce6f65938355d55c0c5a3ed5d2d6ba02bf1defc8d29f330871c5200e9ff49c4ab5f0ff17159cc96ecfbca8520672cf8c917a4b5f3c632e862609f695b774ef219ff7bda407a08f15b0f75b81247dba1dc1dec5cb247d8dfebc17f17520556ada65aa06d490ad59fb8e6c49a7d9f7736fa4af0afe222686b141fa0158aea41ad1e8706f3fc1692bc32e2157c2a4e200350c06651d176e9f0fa304d0cc72a4931a550b6587f31c7c54ed61ce0e010efa047a58c50b2a57fe8b70e481b387e37da9976ac9850bf24c901ffce85072cf5865dac2a908f8b882047795b8bb78919c2607f8dc3c5a718887f70d08520dec343fb623efcb9f448c1550f07c1ba075b910c8f916b65450faaec150dc6c2d3cfa2b56776082c831e885cdcb5b69235d4497e65fab67bf4ff8839ed58004fdae901f09aa887e147bdfbf5d65c65b1999084ba0f27058139ea1e60c0d37cd68948194b7c0e8be9f585c64bc6c5100ce9b7a840c1b06714eb6f7f4e2cacf54326a33a49d6480b3742d5e3554f47ff171e187c51eb6aa0976ed496cdd87ed71aa3598c8c8691360e181bb2247e3dc863f5cad877b7a5eb97135b53dd7176d7dd3006d41744b58b861f889eb4468750ee73278ef2b21ca1d5950073c1e926da58250b7aa7d6478c4c784f0bed51d158f0ebe6fe26330b56c7d07eb6809de72265587175e8cb17e3ce22a05ba4500e543f3fce8e5685017928857d4793454fc5166c922f2cc327b8faa5825437b6d4addab460aee7116537f3cc418d47155f41b21132578edc403ea7f62d4e58567f007ff4c61ab1cb90d0cfaa09a8277a97e45a8b6e78b162a717221af6fb13d515431aaa4a5f1ae85296165a6ac3363d61740b3ab36e1edc34e8e73a022d724bdcd3a980ffab6e1de5e3e8e1ffa931f263d5af061e1e56a83d503791bfaf1c2711d1ee8280d94c371afa5baff85b174653d6c875dc2a9e609f4484b3cb16bf99bf630eea650ee31b31e9bac271579a3eca32efc7bf5eb044ea4589c080ec20ee8aadb75cb7bceb7cc6890a3647ab4a28236f08a7d7fd1d82f40b82a5c231143f6261e17307c6095423d57bbca23bcbc7c95d3a72d2c35b76f67af91ebff4e8dba568c277e13978078944ba48ed8b8e1758a17236f7c5dc809936a37e564f8c8d9d732019dc49802a5ac3cc039dc8c795acf1523141dce6eb6e9aa19fb4f72852806595ad795a88ecb557e5e7d3ec0b85d692981b1d577d4c1668b822efd5c3fadd2f4e82fa47e701e65100a11d776c292f27656edecd981e89245be302bfa8e5e81f18bdd1cba40a5ec19656b02e502fc18be709cc1699f1afc16ca9353829eadd98066242e4f88382bb879148e9da0dbe338fb7d083b6fbe66f3c816a3b20ff266889bec9a43932dc638867f85e655f1384c923de503f4c1af2afc68a0a1fbc2297da0d7ea3587929a9d2838c8e09a535aa4b76d6a054e267e3d9132bbcc60447606306dd0ced5c386721e0403edb3d8dc2b64d09f9a239d512b04e0d6b3814196502292a118021364eced07821573f4cf3da7d6ba94ac75a1087c6e7a78dcfe2f8b87741cf156de9d449a58e552df95b6cef5716428b37354f98f62023887376ab4824a55d27b8852181028d24bb517f0fcf60695aa465575b7d16adc11954f650496f52d24cdc67593ac11ca4291676f48fd23a342dd4b685da3332ab5f4991be8a6c6e89c9df6ca31467d49139b90cce8c4d4c06ea3b35ce854f143f1c03bb7596f7462b25f9c8262d49ad7dec663ab49a4ae0fb0991d0a35b6dccb1f2e7dd5be6ab4a33f302331fc2b2798cdde9b71596d2319478362bf842471b7ff025bed5e28ee6c509cf363e15bc4a846241b62a212c39e895aa38478592d1516ee7b5b95c1be73ec1f5a1285a9a09879cfb76eada1f960f23f59eafc89555a69a21babf1e5978eec61b5c6a626d0c22865e14d30c6b72ccfb049de909c0e5893bad84ba0b090495ebb2e3f0ab28a5ca4d2ca62b40030a16c9dffa9136916adea9c9d1ceae7038e2ad8d831a2734b87f0d7b2f6f4358785e9723027b308fb39385b8e4763e6e67fc9b5c8ab22928039684407cc98a5e7d37803e6f4c1acfed4bb1c37e5cc1963d3bf4c743c06633c68fc7dec89c9e05e61073b5a5d4e9398ddc8c7e0bddd5f35923c931b3d44372de55da5b9506a1ce657a24645f93b58010077e1688aa9cd85404b7c4c61971ca5ed1277364535c2de422f01e082a74240677c8e6289f66e51350561b86de8f2aa2441913567d00c7aefb18b124e53ebf057edda8d7f188b653e06ca313c8ad9d723b8fb32f1a27bedf5cbfb6e1186c367a54d0fd303d7bf0f4898164f49652ac71e0b38f0052b202d93218592a76a96372ce426b1b60e2959267c59fb08dacb26e24d24627e63b7bcf632f6d3d75a08efa32707fb9a2bced37b22e81c2d9d97434ce3a6a7b0ba434fcfd6017949e25e117db16365681a49d5cc4fd7363f520380e6a37518eed6759fa062b811c833dda6528674c0ab7c2be5159a62e8c2abede6270149c965c03a01456f581803ae4773547491a52c8b295504bf3492ffe5bb220a43e1cb6001fbc75948f49ce875b3e055c1fa2d496914d7f49e98e7a1678b2351aba528ff14a2252a6c753bffb0a044f76e813b84b0538fa1060144887e98976c9eebc5f89bd03a3b4e04b68088230889623d728f9096b1b29f97066974153456f15f5fe6aa040ad4df7ea73fe6d737acb29cd20e0b87b158d053836670a23b31c6fb27fc13df39f906dc7a7289fba17c1e3b5d0de847b97058c6799d409d78a93f441be76eb8d0719639cbe3bedabba07ed830c55704aa1054e6c08b7b26be44bf6345fd8bac2094d383bb1863e625c538050df18cdc375352f06e6665313d6789299d5692393fd1d468ffa8889a866fe5a6f9aab8288b89f68889896e146a7427c5037697a0eda944a3f4cdd0d98c308fa41d397ca52fbc7d653a02f5b2ea7f08e00831546719dd025a379c9fb87fa5f1eada8d64c1c3c8e43ff861a331588160a9cbf19027d095e9d4d98f8aa358f23ddd8b598aa89ae982d8431b853aaeb7ef0d859cc9d62c7e864e4f771efb18144d34e1df75abc740e2f84820a387f1042f21e3985d25cf354388f0b6632d949cb9caac901631b9318d1e92e7f5caa3842bb485ad398d724f584b910b4b985c743128953147c49ed9329acf4cecbc7ce2673590d9263be40a25f640c19d3df2d27d04cf07aa2b37eeb8a6cc08ca470b6385b85ba5be7a19702608ea502acddcd01486ffbfdfcd5de33045c3656954c9ba1be85f4f2060fc9faf57042bebbb7633e167f2eb34e47e293714a51a3341ad46252a6f6cd9ef476d3de991030cee72ddffcbc953b68367e287373fcdd7cbf2ac1b5a22d8847abe6ff29a7577d09f8bb8c0becb6fbb2220726fdf21c3deafb67ff65fe7ce1f4e3867c8a6a818eadc00965592df155e94bac654d4c3acc5cc779abc3dfac21c553dab8f72515a061bfde0dc546817b04189831efcb38affc2f17725eb6c234247ef9672a1e89c83791321e0852e196ae8094afa8fa1f5152949fa0f8bf1f9f465ca3a994d33f7b8c825872c8dd086d3b38f8d1f7874ed0166668a903049ff5ae76fd66343d5d093fbeea8e8036d7688ea6cac5bef200826943caed7f0811df30412c11fbca212782af7d19c8e913e45b6b7b46888e1997ba42e8592dc03d6e03f03078b42aedffd213bfcb1f592e4dc31725c33e68b7bf48057fea93548e7bc4f65debc9936efbbdd883e40e025bf7441c6e357b4669b008202f61ded44344c7d0c8b5e9c9068beb6537a4c2b2c3a7b49ecaed3414fc8d9a9609b38f623b0d14f1533e27264ffacff7aeea69e0339abde8a9b82e4564bcb9d90a9251a35217dce79afea1f3f4a311340915afa33a7d4a5bcf6d2feb0c2437cfe7d4a5f0d938dc078240d38a3d9b7fed5124ccac30d29f4b09ee7c0ce7ca317a3e1cc91623755f112d9fb510669083a3f20341fa0ea2ba4857485f7ebc7069755aa734ca69c14360906d9164d84c5fa62029db6416cf029f0e7862ad9d025cfb6d1f3f11bdda828310ce5ac863dadcb615b3b931a364b0d34d101d9134bababbbb8273b3e7f2b9d411f2702aa5b6208df89b9317e2d9541c42e2ee339f4988a49fd10310c3b3562775608f19145b66cb5c34046054878edecde7831cf2d8ba59f37467a525620f6c728434484dbbb32cca6cca8fafcda45078c2d3f2b3f27bba120fecf4dc575610d4229a0acc7f9498cca52a28105ceb7817f358f7db4582d9aaccddd98f5638ec5b1e45cbc7a86ba177178e9ac0d22d536df35e5d983e29fd24e654a1e196ccb60ea7c46efc720b94b39d0f86a0fe526a68b8cfb085d8c81f5f8dca0aa9efadc06858e3460e8e18cfd92f6dd29037017899a9b7cbe2a88f623383910d92d5c36579180ebdc884f95ca153a81e0e27eebfdb6315bf4bd2e9fe78202ef21cd02d1de1283fa8b8f07b76dd4012f09cf85d141978e4c8b0ca5c1ed57f5097f1e580b71a9ebd63bc907d847a4f233f60ec5aebfb7d059840d6d6ce2ecda2975ae2459ad4765098b69d0040c23db036a54ec11ff7cd04a06d50dfa6fe90dba93b3a37e47d1dc3feaa34047122dc329d769ecd06878ae8c1e912f0b9773e1fd2138ae19c70d3dcae23265eb67005e042d415aac143326cdb63c3e510632e5ad72a23fc46b8806810b02c1ae90c6054cd09b4521e61b7a606ce456d8ecea77d1064835b88ae6eeba25c81c943a21b365d98dcf830b070d590f74d5c20098ad43b984220bba0196bdfb4bc9beeaa1088ba4d307ce6675b8f1f3b96d9b940b82cab9f7f592673bcd4b6b4291ad1269c710d9b8b0abc45ec7ac7a85a2560a8f3494432a8bcec00a73fd92046ec9f35b22df7c065b2843bd1a0c3284c47b7c1d47437a70136e0f2040bfcb761f6f148eca114cc925b37fac8ec002a44d804f0c470fa8498ade2733158ab1b913c037c87cfb4b92292f790281b4609bdadee8b8c8fc23ebc390870bc157e6cf8e17303148b2a60591679d76f096378cba85a15f07bf357a085b825fae9737804adf64e537426242861c1eafc08e3eac8380ea3898d9d0a553f53374270a4be45a7fdc088d3f8923ff4f1779cdd4c2ee98926b855985b13d1fbcbfa42eacbfefcbdefcc464e88f56aefafd74314526e408b3b23a434c741706dbd60926e0db4f99b7d8b4b8b5e2e2e2757c9bef8567be60500096dd4ddd53b0be674f347f5d224f569a8cfeccaf9e80dc5125931b737873682cfc43a62704b91964ed8096c527255283c3fd0a6b8f6bcb963380a91e2b085e8dacb81e6577e54288f8be899b6b1f0c2a21672ff176dd1574d6bdc98ecc1848b122994e7a6edfc8d29d62d160c796fd3e5fe91772476be0d676724f5a27007862e0764ef792c8e8598a79ff4157d57e80756e57e29a5cd64ddc68ebd43255e6f8c3cdf60f548f9f98c719bd7d8cace6fb37df13903322e538eb19a8ce3e30a37e7341e7e8c511a27ef302814aff8ff40aa7f1e8d96f10cb4991815fa9ab3bcf7cfda0c03adb5e878ecd99f3f40d31812b34e8034a5bdb6dddee350734a9f6ca88648f63aea30722ba410a8cac1f7a58ba319b1c3b04887e23a85c2ac01397ccab62f1102c705ee10bb878d86b66198d5550233ff8f2ed7f3e22d48bd800cbb600a97fd1bc4adc162050330f7b1942b6f0b499d8e423d03e8faba442407dd8ee0872cdcbfc15e2733dbdbcfcf033160c6c9f6384915ddbc2284d5aa34f025ec1658b221e9efb94240b3ab170e633ad0eae39ee9ea6cc1898fc0ddc662319c322ef2d0cd714b8131420ea6c8cbb1c94a49cc877d88913a9a084567aec4fdc0138b601a8a7db0d8190964b867da451ad845da51ff99fa41493aa927000cd5132b0ab93bad88a3e68cb42430c0e3d5ec93bd91f43b260f983936f65cd1a9b4fb1a87ec8ba3b1ca85166cb9e1a4ed2a5d15690d94e798e1ed24f433dcae76d72e5537f6563046e38ce709ee8b2f600e89583feb492df6f42aa17bc3cebb99cf97832c72602813a5067296e434506ae063fd5fb0b731de2e367a8d130615c9ae86f884fc60e89ec8c8191740f861cbe56dcdf5c21256106951f651ecf6f1f34b57ff1171b763c1ad4ce936068752926c5a4845f048c35a9ed64adce76fb7a34ecb35d5a12c05987cb24718576a6f9b78268f6090c4e1a85c954b504bef34f75227f67b8b06801201887692945936b93851fae203fd54d1e11f7c24334c5c50e5f79cbc3d0dfe7a8be447031e4d00526ee6903409191faaf0e4cabe006547bb64060fb846a21a120d926fe4744941e8034d318e46087b91129173cd765d36917878797c0d15837fbda0fe2206d8ec71b265ddbe4bce9bbbe9387475ec2f2ef1302f060c48db264394fa80ef270c2c09da2d995d8a00a4a500051ecfd06d6ee59f16cf4c4308562021ba1091b63506e4d2496cb0f8274e49b96b4d120e815bd508efe975fc988638e3717a514a238e8b95ec5d6ccf0abeaaac310015763c49e49f7b1886b81f46e1534fbc28ca796b233e820b4fc0e6724bd8614055de6ec312dcd1760164ba2690ff3b61785755c603f7e8b15ccc2d7a5585124895786f69755437f6aa29c3eac0666c1699376c0b467a1e1ebf175c07b3ba2a2cd3f78910b9bb6a564d84c1e2782c73a5422c980b68d1e6dc016f0ef1156bcb41782453e4ca77b2ad3bc2bcc1596fd3ed4b0d6f16243c14186b4ca764df572edf2c3115afb12f730666ca0071549d07a2ca3ad2c20a1fbcccfdd1a6641edb2d294d819b292a5e40404a11af20b65ef638eefe150b9bf5bcc73317a6d60e410417724113a629a94f231d15aff1caf940f023b08456a3b4e3f780d08d93bdc58144dd3a3afc3df3f96adaa68d6a4a0005c1ccdf1163fceed06346eb3e622bf2d62388561442d825d597af6ae31726c156a8121ac9dd171d390e74603481852042909bf596f7187b76cf6666da36c899ba466965e802722751f6997754bc2f372a032a09985ad2428bbaaf6d81ee99c9bef3019c6582974926721629d4321dd289fa89383fca693a5d4bdc60555225f11566392ee259c6546bef9ac1e26b8241ad9846efcda391e160b99160b5157407f2e396e97bd163c9baf30a45c887cd6a4e1735a675374dcfd364c1ad5eb078d511a9bf493f7d54089d36915d74a6bbeda99c742e9f034b5e5340b4f5e791b6c987368b5ca6c019733258df6f9f3159d2a298a5c1f76e51f152558c1e5da90deaa4de403f20ee8f1ca479ad61394fc810817d97f9cf52eff06c2e037e3cf147f783ca5a20399350d48e50ed349958706f4bebe6b9db4175efa1016997b88b4b7f7628c6a42c62377d4ebe88c84f9401474afd9b490b760096ecd5d7fe9038a3eaebe08913395cad829669cfe05120df11339d3ffa978aed2e7ef211f05e2d26e420b6ca07f01322c7052a441b5aa24f1223c9a8def535b541e61b3f160ad3494afcd2f092de90a929eb9bab47a078009c9a53da0a2bd6527e73d000cc5431020f15bdd85ad5f5d2129ced3eb02d40804faa7fe885720d8dda80369d5edb5b5d45d553aaab4b34857914e13829bf64654c9261966fd63dbb691494363e6017c3f98d1b15e5edeece10d8040b4c6778c09a43c6e7e1fa7aaf3628aceed347072e5ff219fbbdb6eb9a59432a514520879087c087eea9ce0a6a445c1f6adb646981096deed8f665b8584a6f16f42d5c27611b2c216bab86d04f903a6f17fa24a61a908314125b1e812854419e1524b1eeca0422f5819fe42dc702e41d29420694f6cc892c6b54ad2685325699226699246a9a449daf4991e52b22e30d8d662adb6baaaab6d1549b5aeeacae3f16c9e0d06f33cdf30b7f1ab43678b1677f7f73c1b0cb66d2fe29a2f01a102583a37ae7a3e9dd753708dff9848645c86f4b819bddcb8eaf974de83de4396fd96224c11c66d2d13c6a50dd63a302947f877115edf3dabd94aa705defbafc0fb929c9070c9f361618844d28dccdec85a4bc39ab061c3fca3542ad7612b58d36030180834ea713344448406079124e9d30e188c460d56b163e4c8dd1d6bbfdad5adae358abcdbad180a75b1eb6a5723778cddeeeddddeddd55ae337e21a04704d02c09273e7849db9e1c80bda3a49b86646847b708c3f68731eaef3628c317a3778191ff24e172758c162dc7edfaaac51322b4c74efdf5418879947f7856cc5ed77cf732d2e75ad2e4d66e0df4bbe3086cbc46d3c149740385c86351249b09d4885091eb3f6cecfc8097b03267e2d73900ad3f803a15e71e71a7f990c060624ea71e3a00f0789d0502409d79c741c1cc956359e2063c7c8919bdb4837ec155dd1155d5b6f5bdc6273fb8e91232a2837d880ea27351d39778cd0aeebbaaeebba91c7e3f178b66ddb647c61258dab854bdbfb47572475ef1f5f481cece872c51797e8f58f57b024e152bf0cf3d35cb3b9a060d9c4262cae7b32f8ddbe245ce31f4534ae112e11e13ddce0bad7180cd40ea9ee1fe216a554a107a771b1ca42e5613c798d0ab1f5459683f20b232b028169fca7a822ba8ca476767676768cec189131992756d7bf8b1c63c766ee1be6888a27af79cd6bb4298d3436b7cf9b799363e40608f8602f1836e98d83a20c6d05d7f8b37f77715d8beb322e39b3d74d298d1ea5f1f361c2865e9bdfb2ce433d2c8049fe8ab02b768aeb2fb6c277380be622ca261e06cc654e664544b93e856bfc5532559b1ec60e5f1897d81f423737b55a4be9cd4d942b1959a462c7c8919b6541aaa591d28d6e3146598c41e246dbb62348dc464712f7bfa1530da54f5bfd12e0b569c252080a2023043861fb23c035fe096892049ac63f2626f46cdbb66dfd59c28a98b01bd3606ef464700ae4806b74b0b0bdd1205ce347e2916d6b7074c453b64ac739d8bde5e06f44b02d16f58a25c44a2592a12896bd8f8a0de5f57fc5183932f39c71048140111465deea6696f10517da8936ce628db19014f6891a0fae472aaec71d5c7fa70293dce5059760de7594f418a62937de755037a61b0f836ab2f12124ec0daedb8087507c018b715d72b1509c146b4770c913ad78ace2510947177089bebf6bd13b3c0b2ecd8f43c47c1881b81e6770ddb770ddade05db8ac068daf26f385f5da982fb432be6abfb0ba565416492d93c9643299cc23eaaed55c2a95ab93459290982c268bc9e88b40a2be5d8ba423227655aaa642f5e3944512334f8f3fd0c1ee641de8eab8fe11159b38a97a17772e1e995cef40d1e7274e0ff42010687aa0771b50bc71e32b358dff87f6c37ae383e223c2f5f7a468015ce3ae831376def0e6d33961411fde88e6ed3e9f8e54804471072deb9aace6aa2e14eabaeafdb82e8b3c445a27eae1b2b26871e102e3bafb8c2d01d11ea66c4597c4e80ed7fdc3d053d09c5630cdcca24e2eba2f9c604c19d7b84c76c5f0316ebb7a4b1458b82d8bb55a3b57aa4872ad56b550c85a97aa5659fc0212c51d8822155ce36f43f4825445528c4552e401d3f8fbcb5452ace213abf88395cb7cc7bd10f90b2e85eb1f12312b20f4285c7f1b9ec5f597ae488a3d341598c61f89d00d6c105f1012030b4078e0b0b0f2146b2e03c92c16f1e43b91343defef5dfc0ac699a0f7772bb8e4bdbf37a171b870a973a7fde876f7bc9bb255e34857f3983299ecce952c9298a5cb5ee9f23dd0099826922ec034fdcc85aac4f60c9a50b5e84700d3e8d802f37e25ca0f3d97305f38616044de4724eb47048e6630c10e07db656e13c618ae749ec700f7f1c3217ec4c1f3ce3870384cc1c1f3f1dbc46e33677ab673eff992f873df4cbf2989e7e337d3df8d0ea6d932a1feacc5c19f7b8f28b6e787c4f73cfdbcfe84e8bc203ee7118db866bec80b2b67cd01ba27830eb74e2bec0cf1bbc7803ff73fba796edbf462bf0621edcdccd03df743bae7be2453b64f12bffbb66f48f749fcbbfeda0bae9913fc4449b0f2c38f1f2b9d5e417e118b11c6cccc393723b0935fd8f62f5ac618ed17b20893524ae78c94ce58a3284e4ae383925239279d944e49279d91718a413f4797e3e278afdeff289fd2b05e19075d7a3f64cbfa23ca3869d41fffe3231cf4c3f81f3f5aa07f04618eebf30bdf47a5df0d78e76de639a2dfccfce49df7521d599df6ec4bb7377d79530e02731888d1859629877e620b2b35d394fe20b46ea279bcac38d8d14fc77d3892405ef711b5c79670a471fc8340f3f8b07c68cbba4262e66a24a46be63595758544fdbad63ce23b124dea4d6e5bddaa9452d64e344d94f2bb691e1df7e99eb0db13f673fd76338a10c491f02f1d9d73e33e54e4ad22b8a6ce561e0e085f5a1f99f191c6e9562f41eb86c25a1de9a6c56677773a2708052466abd5aa6e72dbea5665e5a4a7fb745252295b5cd33070358e5361239ae8ee09dbdd2f36ec58fdd04f9d0bf11c36b0f2b7207caba856d8a6545ee148ec0bf300c24a2965f7f1401f2ae26e75a249bd45d3cc20d038fd650b246efcb8ea2f34004dac5fd07b272f3fb8c2085b708107ea09d1017da148131f86289c564ed8b0b31076166ef4d30d0f3c73c2e9e674bae9d837ce830eeab43ac9205c43e794f5930506b0894dde924dfc1fef47e5368e9bdcdc56ab6debb62ae20b12b1e9745af9670389dce48992f4922378809972682780f083cbe4bd114d0a1203a05bb17d4d206f2b92dc89477151e1aaa8135127073f2cb6d5dddd5d02a6f130da861162300e8ee6e18fa3c7781fdedf112c4edb5fc138f1f4a526340ec7a5fa56d5ee9faead8a8d53a479f8cf4e32ff22dea73fedf1ccd37d8ee3681c1dccc37b1cf7f3f7e339734d7b4baea91f19e3c74353b85d889c71ce3a6b8c31566baddbb6515a2bf56a6dea0109bdc0355d802fd4c5ce90f7fe5c158d22c9fb66601a7fcf62b409a92159d56ab55a0d0912d0ac999bc66ddbe846bbd25ab7ba511a29cb91ec1163947d7a60437f5db7c1e23630b7992f63acb53d5c953b2cf921e435aeb919f5b8d9116385abc562514ae98e118ee3385624b1228d1cc755aed46bdc7024bf27d890778cd8e047dc66bee7312e51fdb07212259627386d8a5415ab2b602f07a5d36f918dcb5e047c87209114a35061d5eae08dcc11b13833839b629e394cc0e502b00da54c30e81fe2b83ce399bf654cb04d2bc1b4e536cd9af14516ad3355eb9c73ce39e79cb3d2a9044bb94b348dcf280cfafb84c2ce26521e45b3454534b138a8258c1dfdd01a2362138d11b949cbf5a781f58471e6a6985f718ca84d51c4b7e3e68d11b1a9ebbacf526b4c5f4f65c399e2b2d5ba6d33156933254f0e42e192d499a82e369c29192a6eb7613bd89952c2b2f763a6666a862849dc828242cd9443ecc1cb04c31022e86d94810fa8dbac3a6d0dd1ad6198a908fa60449115599755ad0dd56835b06e54b061b35256dcc609931a9592af48aaf1345054505166111316036b2ad11525b27c60c39992f9195fe39b9941e667fc4c7f43647ec6cc901a1ffa1a1f7adaece74b13c988362eac77e04c7f8dee97097d8d2f898d0f7d1200fc8cd7c144433403fa175e07538c6806d4d9108db62b581a2ff322206c979a9981c6c73c0664bec6338e1a49313ff318a8f1386afcccd7781c684c1c1f80c7c0cc0be0c3c1c6cf7c003e1ca60cb1f1338f03001e47674394d3e30a36e66bfcccf63a98a82bd208d1a1b0176d459a0304615de69dc6e733f38ee3dd0380884d315f030038be991a2aba7d3313a8bfbd0e37462aa22219dfa21bfccaf8220d9a074c970bf3531416b9309f13ad28aa60bef8648698bff14362fe068d2fe6852f89ccc739d113cd10b1292462538c884d34ba4fc83fb1a794dbd0bcc45a9c39e82e51110cae710114d7b7309b8856e825b8cf0d67ab8b619022184cd3c91b9b0a60cc142db2680e7adcf9c2ced4e748e31aff2e78c76bf1e435afc51d445664c52cd189e8839899a2551c74eaa22d185e60e387d479e0128dc6cac2c1808511f31d644b58a99adb8491b5a2d1bca4669309e54b644d9f59668a6be60ff38a0c08312ab028b10897933ba33839588b446898a9ae61a68a843cf3d08ce7be980f41b7f14d554ccb66b4ac4616685441e6eb2d66cc142d66be68b3fbccd46471892fbde16c4d29b11559363eb40c7470816052a4451a6f9cc8126388248e60d03fb23c92a612ce510c26aebfcf17d7b87baa65911669916524922218318c9d1d76967891365373ced93595a231900ed663f0325fccddd2255b9265ebd6db16b7d8deea768264b15eac178b158233078d98e233b789dff216d7fa28e30b1bca4e4996cb6da4152e6ddf754ad45056556ca122595226a7b82eafc89914b11536942c09939fef1e1472ff96b0de9a7ddff711c99688e5921549202859208b6e3af849bb9ab41acb8a8291d4bd7f1a003bb0d3e2d545f4642092011aa41467c9c0dac2b66ab74593ec275b9dcf7c06f35d0085b2e059afc2071cc00de34b1ee086f1d53188e8729b3006115bad2a31462b3706c125d6d7856507a713969382d6ba6ddbb67d88648049f1ca4bf67ac5dc30be5876854932ca8bf5928105856be2a64567b9fe339e39a145b9e2379e20595c23a3482b5255a0a638edc82bb8c6d5b1497f506cc8b4193edf3d0628066ca481c27e8e965198c65f52b92e81705d5eb9ee4956a758ed4a75aa53f3c5f9278339e7fc7c3e1f4ae9a4f3f3f97c4694d239e7ece1a4fe7c54bbd13c1ff77d2fc4396984b1c562b0d7bffe35e7dce6165f91f4953a6ccb84f29a5aaecf2ad79fce6df3bef9482a116167fdaad5da5048b6c00b03171b53602b08cbde6784f55fd5d5b6dabef0b7554c4d1516b799b05904977670295eff199bb348ea3e04044ba5ce28dcdc895ed8ed89839b152cf7d2003eb0fe7c398a2e5c6edb4c96db843175533eb5d84272d30da7943bc60d638b4b7de327aa41c77d463f380f88df6d9b1f3d2022bf51e55dc04d311505dbf160d914bf7faedc26fecbd5625d8f22d912c9c086b235a16cb096dbc46f7be2a02792810db727dbebfa6f5ad8fe30a656a9a852a55253958ae08d2c95c72a5315695cc776cb411f4f1c74c6e2e9e964aa3a6f015c5322029ddee7864bf1e30f31753363aa4a3855b2255b32bb4d617bf27d7860a76a968a3207a74a0a9646beb6205d30933298491acca4103369c42c0bd7bfb1c0a54d62c134fe52b8fef10bab85eb63cc18bcfcfb0726c9163321f55442515a45b43ad58598daa61853750256019b80d4af2879c0530906e36a3261c4759eaf364210aea726cc55515485a52fd9ba79d5dc6e5dffbe3245ac8a9815b1d754bda66aaaa6aad61d23071dec566db1cd0710a5b3810c0b103b302b56acc41839b2a7eb4fcf6284c42e0a892410308dff16d73fecb8e6b8c8c58e8989d93eb5562bf7484ecdea2aad9344d55250fe95db6a48786b8ee3aac771713aa83f346a95c2073a34a4c43123140242103233ac9db36eb14306084a2b5be48832bc1ff17bda281f3737a36ddb1a4581202f24923acfbbbf17b93d90cc2259d56a35e7768c7adcf8e01a121b4ab89b993bb2562a5b69531a69ec6ddbb656b54a35a9bb8d0eb791e2a43afb32bdcc39e7a451b66d71dba20cafb25d6bed6d1b218049120c491bdd91478475976b676727ba7622084a54241941a15ed2a6132e3d719b3058d2e4f6a11f782e993b4c9611ff18bf21dc9784fbeee3fe685c03055b7feb264dd6228df770e9c541ff3837340f5f010b1a87abbf936af73e2f22918424d2344e4ef390bdbc20c9f97c5efdf9ee4f0dc9e713424237d16914922f36d08a741922631ef5c8018670442dbad3f5e8d445b1d026940965512b5445a15c7f19455068c1429fd0551435a1729b761b896a169394db44978c0f36152342511445538d436920002736a42852acd5da900f360036a0a9bafa01846f7f32e5a05314d7f8e7bdbfd1c38b75d74db90dcb1bb24c004278661e4fcd43f3ec7864d7ff46b760352600950d23ab968a39d8b558cc16c164c5c513a594527631bbdd2dd7bbbb259df3935d8ff1c186a35b639ea73dd03be84b9283a9c240a02f097d2501fde73b8f6846f4cdf4c3b4e787783c0ff32561df9e7b1d4c3a7414f5c2151b6759708d47591436ac308a1a82dbc022699afc6bcc6d7a78b15dbb2145f96f35b7691a4579fd627ab0ed9a32a47bef4bd2d5ee874d53c21ed7e455589483ce84a6fa0b47280d8091c635f091c68d60c31fc51b273676fdab169817fb1702312708174ba5891bd22154081136e458ade2fa6701a3281445511445515477b2f1454a29fd7a924b112ee1b8fe466c9032923a402bc235fe9f13a4eccd49acc52d77cdbc702b553ce65dfcc51b07c1d2206ce855dc4626817a13ccfc2458c42e65e35227650ae34423e020ecd410d7047d4dd0b7e33c34f85e60e9875e60528ed320e0728ebf935a44a790d0a42291c697e8aecfbd39952291e44b348d37e1f3854e8450fd4287c29bb88d045fa2b71697a870a9fa1242446887a2bd096fb9b7ea87a2703b91edf5b75a9ed06f7b68ba66eb7113631e16e8c8c7a787a5dc9467e592dba8597fbe7ce504c4650f24b3fe39ce0c84d58a15e3220506e5b5a56585ae56d5bd7635eec9c27237fcee6bad5f3f97bc15144d226244af1a87da20d48496218108a126ec12fe7586374d7bd5ae48530433c7107694ebcf79b7f2e0fa3f5769d9f951fa021bb26c031cd000976ef00126f5e949f3f0f76853f801130c869a4707e1c67558f33084ebb18fad0ed6533fa127da4f6606b80083880cb65aad56abd5a8c7ca52e166a64c9bfb65737222a94a493b0f1555aef9175a96d69430c963c34858d029cf97e3a371b88f86e6e1fffcf2726898afd7e49253abf461060cfad3d0384780602b705919610818d7662c2b66f3dde3e68185a5b55a6ddbba3098f993827262f22122ab44b8f35c91b922658e48294084694d7a1b69dc00d37dc05988d0b972743dcb105ea24966334f3794b957ec8d1bb24cd6cfe7f3f9eae0e73381e8f92244081b322dbc61de22fd34f847e446caf20d43a0474185d828fecc32c4ebe9d787610a1b72145f50b9a22996fbeebbb9f9978076846bfc6d11d6238a5ef480f483b040c041e7bbcd7c60e10d13029e28fc206ed3d94c520cb20797e4fb1549001def36954b5bc771de8fcd0697526069304e7f29a856864b9e77cf15eb5d7bdd779fcfc7fbe1f916c944e172f6084bbb1f1a8d46a31df1bc1d0e8e1cece1e08d833e722010c4c16e193e88a1dc85a5091396955635143a1a7532274f9cf8cb10979c8e4236c0208dfafb236bbdf4a768042d9271ce398af3e5acdf10a7e98cb07ec31010d6e6c086f6ba7c8fef38fe7cc51084d840dfbdb0262463e380c1216c689c3e1de1022f5a57282143316d368aa25028140ab56d3b463d3a06338399ebe82736d4d0a76ec234fe12a3f333ccbbfba5773d3cb0a31b3f9e15e1d9ac8894348cb98a2d66d7218bb1d825bea2966d4606ef3ed7f87ff7c726f3b76ddbb61a5aafadc6c5a5261ac7f3fd963eccc370c586b1359f348ee7065c62e2243fbd22c953339aacc99d4892f1fe13758a246fd249999c359ba44bb6e42aca28cc87f2142a854aa15cb3fae578626722107ffe8caf03150eb5d08a40709a4e49711b260e63058b5a82e212f3c7631173f6d5da50282e81b9f10718d10cb771116f5785f58f556e186bddb6214245d87645527479a660ebfdcfe1a4c8c4458c1397300c5c8a33f8dcf0bdcb7db515bae185b0d8b88469fc7fa84e228a6bfc0a1bc6566c6d1f7a1f4ed38f058b6bf12d22601c04308f7e5983112e4d0528a0fbc25a3d5f6cc556addba8c7cd5cd950d2ac6256ad184abf9eb4165655a9ba9b9b1bbad55a6b7d52f7616dff4251b061e84a5291a8c4f5ef2118076c33df85e052ff4da4691ccf97a479f88d77439e7d5f6e92d4f79bfa85355f6e68641e709266c25f51dc2074872269014ce37fa35255954aa552a938ae0a19e260ff27369bcd763ce54fbc7054173f7913dae46a4339399184a4f6e068462c51a06c9f56713991e43f1a816008d6b39e71e9b3a104dbb7ebba6e3ebd61ab26f390e17ddfcfcb077d731e902888839e811d52a20474615b3509543525e9314cec31f48f4056a6e9ff421b2af7db047a04bd6d40e87b6c60d8ddb8efeeba0f924e61b1b5630efabb604abf0ecc2b895d389950e0f6e57432a14226985702533b9d4e261d1d2502a05513cc2b71c02c6482791d253cc6eb64820168827918dc98604c30cfbd6c900f0b9d05d3cc9eb0ef1a62d6a63b3d836189ddbe9909f408e6f7ac023341d0c2ed1cffe00e6f5a8f59382a41dfee5974d9f006c4041bf6cc51b3d96c369b51ea33cf65b67065d65167a08f500eeaddb6b1043b9271123b5713e7873bc21cd7a9cff67ecc2f6caddb3665a432da3ccd79d2d15698344b67d55552934fa78e0c82b147a3ffda5f47c4dddddd3d09e80bd8ca94c388c90f5ca629fd21c36230fcc0facf990830974b9fb95cea3a7dca9175ea0607a9128be408f5e00006232ceda0b0f23671d053ad1c2acb7c3a9d4ea73ef58952a7755268ec34b7711dfec5dfbdb8bbec642097fc9238ee03eb573b8f16d6efec9e5e3708d391449fa6c37d7d5a2455ee0b400dac90d98d1e5e2ccfaea36ed846c0208495c16934da9c3b68758c8e99274f99acc7b03559173f317a778a42987843d75b75606a24b5153bd7df690d6cd8ad4869b2586beb38a9487f09781e611fa0f72f82821b9c04fa680d0025712793ebfcc53b2b1e366458ea156b1efe138b834da4b0adfa9ed8119020ec1d9c808df81371555c9062080c3ad83c8a500029322292a06a8566383ed40aa5a4a452527630d26ad156abd5ad6e756bdb463d5a33a4b85caf1d2f586656645ec0b65497ab7dfb500f48e7e1b863c3762921c68a3cd142609c2456669f54deccfbf629926efa497ca2a2a208dd4a4214ed84b80385b5723da9f2ba5cd5e572b95c9c886fbb869cbc2e4e2754cb0a1396ceaa4aeac9e90482b20623c95a2e798de35dfffac562c1e5367d1b50b047e889f66f4fe9f6fdfddbf71ba91ff24e7df0648db06d65db28a5b6e3a55e05180a77fb3ed5ea606f2fbd1f5b1525c1bd0d6ea4af9123f2044b7d4ed70dc0a300bc8502c0c6a9410938416aa05d6c100c02c1a07f0d8d83a479f8105d584a382276da69d970c4c869e774629d4ea7d3e964b1405f1cc7c5da49b264151df9454a296badb5e6c076dfc1a049978508dafdcc5924e6863cabaf5a3b092781b5849429490e323b28d3e773e8b8b032791f6b50dc660726758d4b325c9a21272c7f58721d06256c18dbd5318fc13f0dfaa6312fd61cac5dc023c39b6133d948e30f33051b46d749a2b8a71c05b2dd30db33dff3f15c1679a28f8863acd185edbeb0b7442ef10a26512298c67fca941ef4e086edb272c376f911b1567bc2054ec80df4d6e73e569cc6fbebedaf5d4caccb89d30d252ad6ac58ff6e2bc27d72885061b91bf2dca813d7db65a579b812d207066740ad4820e42a0a39c42bd624ab5dd48adfd4502b4822a96b55d45c35b9721bae166bb1166b1e0fc735421c1c4284be6c00c1ccb4b1d056df4412dfb0870a0b739d524aa9bb870a6b61c842686665b15a739cac5c00b3b826a6c541eeebd4ed20ae7f6c988f9c9b90671fe010b007901841e33414be02140ac54385a5fc04834180328486122b024bc6daa4d06655615d094d11aa227473c38ab1582cd6b6c154890921726242c310a6e9f08cbd906ebd05724c08970470fd89c0000a283d19a6582a73847dfba9967e433ad50d79f6b2b6880d2152b013f0dcfe402e794c888cc562b198903977787c60e6a992826a321b89b551eff40cc1728c49705f9f37fa7f798aafe2adc899354a7b38cde69b1662778cb17687c57a37ac4dba35c6186387c5c65e71e9bbee8574b0729b9614a61ff6eae670e5d50e3329a3bf6f6d6795811d503db0d36bf0067430dbbd6ff5e7ffe5571539ab55575fb93c7592a97f90684929e58e9119dcc43dc3803e1eee330203f27ca4b0ec604ebfbe70f46166f678a011e89b3ba31d5be5975365fde837bf1d233b3827288b52564bd6a54aac61cda55d946bb53614fad128ca6ab5f61f0447a366f58b4b7c7d764faf1fc6a5fe1fa6b84634a10b76b3a351a86d121c3721063d58c294433c220c93e7bf54ca32d7d8c993274f8ff60cfdbef4abe7a39f1107dddfeebcad4bd8203b18b1b65a6b592c101073ceba4dea24c65837fff13f291d758a76c157b0204290e80ca100eff0175917589066120d1a39187683cfc042b854e3bae806e192288bdb42827cda415110075d6efd520bcc11fc4990ab7ad2c38b95715e95759356791031ec7c820dc1eba22dd81094f2fb85041171b121087acb240c0683c182ccb9c3888e8fd8100e7f99c383cc9e93ba8e3adbe9597be9d8a45cf274308d3febe8f1ea973c5dff26820d2e729a5ffdc9d51722ac97cb59a8e8b2e58637314358ce4205961bde64a982c9cd424595cb598ef0e2e2f6eb543f1e1ffad55bc4729dbda4384bac4a9f9acb7c65893de186bdf369653942ec86ed456e348c56a415aef7f0aa3199ae80df5aad0d85fe417074634508eb1e1020ec20783ae108c5d3cb4ece628425d8bc765eafd7ebf5dab6978582e338e68e7c24e9288119638c2e9c4c32af2383fb9890679f1f8c2304300ed83cdc13b14946c4261939ce711cc7fd370e17f27e8608f41f519bac884d9c2889cfc788941c9111c910292972fa3cd853dc225cffb000d73f2236f5dd3e326e9a216a1367454a723899bcef603ec7258ce805bb9e08072433433eefbdf7f97038d271a2d6e260f7f2e19182c5e16a975feed362a5b07cbd9f7201192118a3c56f00e8fd6788580121cef5070bc0a53700f3601b4a039530e8df34d063b8eeee340ee42ddce71f49344ce38f802b15641a0eee73d41d5686877624e420d708f1b8c5c2e3f1b0876745aac7e3f1783ea311087ebe1a699cd890675abc97306157b9eede00506fb9a410278512383f9847949b273a52ba05e5ca78fb31f67432b90c5ba4eb72201084020e1ab1e1c80d48224d7f441ee794d45ab972ed20b88542455253a9b5d6eac9c0846b9c874a7bd23a6e93059372228d8eeb6134185c0069d9c0862db3f12f12699630e908e7c3c3033bcaf3f5ab50a47893277de7dcaa7c00036193152690538324f4175360d05fcdc3fb0a4c03c5f5530db8d0b296a3aab85a2d6ba18e5454ff509d340a2593c96432d9a8879021a998d5687453c4061f3db8cb4b0b6d853a236c7f884bdea871280fd73fe4031b8eee0cb9949147233a1a8d46a3d1b66db5be55881c63c766668e0fc3e50771649a077fbfa00a1760a61c1820c41096609acf1f120117f1174435780cccd26336123bc03cfcdd3fac2132820d6faed74abf9b1b29c1ea25c618afb07d638c3146902cd65a6bad52f610620e7d90213970dcf80c001036e4fd33925e003f2f2b43d7fd8642a15088527a84945246dbfaadeb6eb08a31c65879d63ff817e19201a4c93ecc69f3d8a8a24b72e474bad1830ad606f0869f3f810e97fb7e90c83ad8fd9d534f06f91fbbddf2f35d07deeed37d1495a0c7f8bce78a9d119f8b9df48000e10bfaf682f0057d33de8f803ee8bdaf0718a0a75f1f06e663be1a693ceed99bc17ecc10fb319ff7cd44a0043dc609e483bee71aef0b6d002fa7c3fd70a28f8c7ad9ebb82f6c6c62fd7360439ef12039e06bf57ca1e8f6733f2bc27156c435d25899108ee71a219e837630a71466446415a6d66a63ce39a70e9348245598da9da304db452f3a78716fcf8b2ad61491b8754422e97dbc17aee99085ebefa8482272d2c18103a777a8748db805356534020000000033150000200c0a860322e17848260a728d0f14800c70884082583e1a48b32088611ca4903106210300060404400433ac14053a62ebe1d49c3cda53fe7eae98e3e643a94226bf60417b85a91e3e638bffe5089ea7e763537b32c3cd1b038c3ed906023efb9e63f336e064a8a5567cffe1dbc0c094a9331d30f3b69c1fa8766c68dcdec5dbf79c271ee0c74b7ffa91677432bea0e7760a7cc1827b9935fc8bf91b5072e98c86924426c89c405bcd9ec76dbe2abf8b798d697cbdc896c50bd10f35b60d3eeee2e3a9e6833d8c3fdc9099ab586de87e245e3dd53f5a77d96d350a46ee4a20ec638faca8d75b58722f4c9d5bf121a79728d4dbff51812d25abf793941e0c2a3e16ace0527081eb1399986398e835311a9d843c292e10d193638c719ef7cfd7f6db872fb15176b6af55a7c41259774b743e7789008dcd33fdb5aeee4c0821d8133f78bf84d086cce763fd2975d25249e98900256f18c87ec3ec65ba3796c66396f3d40cb3e4c9235fbd9c386e20e511a6494adf8484fec0ac303cc9fd5ce9de955f3b8c3d890d84fc9f49851918390692050b930aa0579e9ad95d4f67abac99a2156e8e93dccbeff8726d19dbe1f738d5e6ed7c81f89e00e560d99582d3511fd4eae2c29a878ccd80c50717ab9af4827868365075a7a67f4f981646cae036e7d550443e5b091d11a8dbb68935740a15ed5daab9b4b9c564bedf47b8c41e2b26eb9f4fab1ebcac8d42f858421a2789cb6abeafa8603cd6dc3ae1df90ee6c4ac2ee834dd2688f12d65da7c2fb57c0b5720d571f17e5b89b64333557a8403c519ee0153a81296d23cb115ec9cc8faeced45f44fabdbb023c37503c1bda0f244dd058a0871e98bbd4e82b4b63b49ad2739856ea36ca901473eb0b125b68361cadce9e8fb4c36654b25830f9d53498c9060d377291e29da82124d2f2f2b081a8f4863e004b0616448ec2caf20752c8ec48e23aab98bd5aa73d6e853ece07c8aa7c44562ff00118bb279768075bf267ac182846526963eace6824eb4f159bc13b95b78e24f09182615f1f6c8da9cedecf86c906d856644d1778143198c830b1d57beb955188d86a275864d4f5fa80a4c72e30164540087cc42ff9727c32262ea5fc500adfbdc04c1a29e92a9f226a78adad762c357c9c06f4635c001d00ce22e486d8041ce8b8063ddf6937531de8bfaac2e6631107123727a9dd72003ae25618b18b7d7895e442553a98a6bd0b626aaf43ebaf5713efdde821caccb1fc37d15039cdd5081133f990cdbd4572ba8199fae0fd85cb60836e247223e06cd98b1a2fa39f743322774f5ba60978abce004c9f467bb2bcd1b1d1f16bc0c0b1bfe4380594a60e8c292610bca3f87e4b333474b25b02f8c15541743895ff0d42318117dd915595f6cdc4236582b62383e04de142221d853474510a33e68c682aba033e40b58ebc76bbc6290c30773b02cf76fcd1178b3a2ee7f8e8f0fc7390ab6e209eaf8cda14e00a8d0df50fb9901c367b8d55d2671cb402de4f72c2e7e2287ffdb07044884a22902a1b17269804e76d75db1de3187ae9943411682352fa2fa673fb0b818702808f2048681c5785b1afda62f312e6b7b34085bd8e3327cd5a3516ea969af67a2efb5fa660a86b841d56073fecdc848b0ab4820cf1ba6a0518546fddc3aa69f5022edec05965ae0c3dc47e8a6e85fc73ac1b4e09da48ed3d53a56bc3688a032d9ee5c8a52c55e44998a3c187ff1d5957efcbe0dd644cfb9adfe76930432b7015d19ac16f64b416e9a0b4d35431c27fa157c4d6546b94469717208a9ef5e444089ea933e9cc3c016aa0d2d87cbb90bd340d5d291e694d283f019bfc4f428959d736f5b64ec3e26bd24ca3c5f47394d134b17a824e181534f7c4c7016c5975e862d77f7c17203f98155dc4bc3dde2706189ca8a0f30cdb6ff0b7ac52c187aacf776aca195613a013c29d387817a57895e7df921f24384c56e9bc980f61534848c2bf683912224128644ca8599eb24a5afe099b80a72846470d30e9667628615161a4e182ca3ecc012a5f463a792f424412cb371d5289c610963613d2c89bf147ab590b596ad168d09f959ef77dcd554a927e8557c038723f857f9a6fdf08cc80a557b738a86981da9b15998db868ef528d12ae19edf7e79192f43b0030a00dd35ae6422ac970c657fc6f05d16c62d285b56ae153ba5ebf61882126f6416070e6d6caafc044f1410cafcbec35560083280eb41ae14101b312a1f906d0803adeca8d56e3b55c8b7d59082f6f0967ca9c3013ee94d68236909f3592ba01c801f3066d9e8f53db3ee9917d641c7afabdcef143a35918ff1e0b3ee042966632845372cb10a3d3d7165f0781b38fc300e1a6855ff14a54d9e0b85da30c8e917554f58acb08ce62b3b4d0f0cc431fe514351b0dcfa6ee4a38048fa8e95ccc4ac6a6bf7187a708329cbbfb45a20400f766dc5fbe3f8bd6c01c11363d1d5403eb63a2e564ca500c7c5ab9e57b63b842a4ca541f88c27623994bd1223e82a53e4ffd467bf353255ec48c98d1304d65a0bc0bdafa55e8ddf9fa060cf497c2745543ad5855612761105814e8c8dfe28965282f1121502ac17f9e23fd242b5509870abb0cfc3cea02d28700aae84c53c47ee4bf9f48611b8c30af99f36881d16a91b2626e9fa5b2fe34126128a51b518ff14868931744b9cefdf7d89295be661474a494f2305e25a17568dc11611278160b9ea49ac7aa0c4f9d1ae59aebd032ee838a6fe11299727b97cb6f0f3891bbd69cb48535d2f68b8e28d7a7e27b8cf0b8d8e20ffa142478c06d8a0bc22ac0d7ba8b3afc491980c809b0eceec3fd899fc402108979470025ebe8a8a222f98194fb3e9316e16ef9effd147df3da0eba96289ae5ca9e362b9fedc74695958a965df4dad6b72fff8d05d4a4be04e5dcb923077c745526bae38d9d6774e4e7e63afd4922fb947b0572807c84f889a32f90fb771a682a9bdf5155a31e0986d469b0e69181d19624d0ae384985681c49ffcb2e141ea8440f30b0d206d9815d7ce97d04067f1001a7f9aa4cea198e2bc91f6310bbd35cb4658d06a1e560182dce36c20e3ce539d4aae733fbc4a2edb6a1cbf13e18d3c52332047fd2f87bb177025aaecd21a3d78b3f859ad953338f7d710c9944a348921805137c51cee1ebf3b7abd2bd2eff48bc6c2f9f3bdd0b32de2ab613313936e325cbe3749ffa7a6377a01532bf8303a282701f102eb21647f7cd7fe6703cf7f5a0f1fbb0a0ecce432b02d948eb1bb99f850eca8db8a04a2a42df4ae6d8640c26f51a6926fbbd67a5c6f408c0d2229665949e909f22b189f71e1b69207e6e162b7c085dc9b1f84c419878845a611d6c7e1500a61d132064056bb5329615241cd71aa62ee67df9700cf1ef5725fad2508f59f41c94cb7ab6362247b7d9b9914c94602e602c81e1e69b2746dfbcfa05eecd43af1277f83745bf2a2bcc8105fbea6e82656bc44a25427fafd91311c34049fbd38599b17536390b654c662572d6180f070a5e1a5eefbaee7b186f2a51d0f94eb86423f7049c09867a6ba0e8e831c963a0895b087d0a72382505fd857e22f100695c6b2db6d500b563e0d93810de15bc602be8ef3e3e953f6f5071a3cca42145469abf001a1d644e6470733ab6f9153268eb85fcedc950150ede8e01fb480db574c85a9a2f49e5df326c5bedc8ad6e28ef29d8fcf5f0188892809f680888a9dc93c51f3f66d98713b45e19ce33b05c4f11d7bb1fb015bdaf0629ffc8633b1a0fa3aa3800fa003a7f72e4a60588ec8743207b6f21cf9f96b0fe20cb33d3e5361989f0cfa05ee8ac497760cb21e4e253876ea6c690fc812946908b79e8a354dd2665f3415cfa23420fee8b62d1743447aab966c99df93050992cda4ba6125f713a111191a8220b177f575b71426f3c25aea18ea52b6e24be13f90de47ccec53fc53d328697ffa8601d6f804022c3cb68e97f047cc83abf819d3218d36ec4d9951ade708a04561c7eba07edc995ed404c7c1b7f174246a2509c5aaf325d3ab9e467377de354d7d1802a79804da159f2fbe2af88adc376df0046f15a7c6bd109475608da1dabd3043aaa2d9fd190f62e131fabe00eb1487c39431aff841da124546423ce668fe09ee5500fd5abaacf527d06e5dcc128e77c0f530ccaed2e9c9d4b0461c8cf5af3bbefff458dc6aa2eefefc4f69e522bff8463d0343815021966c9f5aee60e025d943f37baeca3e0421500081742a80c14d9ee95d07f88d88e62e88640803219da46a860f1d8aa905b12356aa842f2d8e4bd536e625d3488720018d8663186c8cad165e9f3e44f6b6ca5da5329850b9332056d0ecc5c1cc7eb691c14d2aa9344cae648988be775ed2a5a3767493f9ceebfb7e54268d5c133addbd8c83e93504f758d452df4d7387168061150bf8d1c2e562078c4ceb31eb453672d4e18c45a5c7d50b3d76f27351715f300aa0507b2293d88489abbce4edea2a30b1295927f983f4e9fce7b547a49b1f2dfa38a0bb207e1a3a12d89eac800d15deb523fcc44cedc16afbc04e160e26662b2da8f05d238d6b81fb8abbc5c40e5c7ab175242d54e20fa0f839d54b32ec3ba87ef63e407746998e6536fa169dfd074af8a30a42996c6bc6f155698dfcc3ae14b76c556f0c2e790ac3ed65101d3f746a62e45d12556afc0841c038a7f9226ac88bff4c9e13eaa2ced3719a7a6cdf72771d3d1420cf79af1945e6299988d9630305f06c1643bc4a42d090e97a460602988dd09d55a0f3338ddb4f6898290dc1bb69701dd35b1457e1a0170b56380b06e82a7e86aa2ad2dae523308089e49c7b499da12a5826b44556984b4ce04b44412848a638881b2275c58d00ccce7200eeb5771b9895f0ed4d841fda00b28ca8cfc8f9a3249ecdfc74398fcabc720b8d458b3557ed9fc641f213abf5a7856f49394d2cb8b1a3196f55fba01a9691fe8d5c96701cb0d89f20245c76fc4ca49b6467f2a233142aad5ea75b0b4599ee4a86bf48f546db9f59396f73a836c176ea6544b4a640d6c5cb5135c29dc7ca942ef01f1e9c93e1520c961a1333f1625e04057ffdd71386530417f1a5d7a7b6c91ca2c870f23eb8cce3d44f66492c44a8f353f836afba51fc3d64c372c2e8b473a721254bcf0bfceff3867966954f999a814c4a5d0b0b154b6a3aa5f83770e14de14c8e9c390d8410ff361d5f0838dfe306959254f62e48adc6112ae26527bb0062c12ba5efc99a6fa8fd341bca9730ca51a730e8086ddc4bfda344f91bda9685e9867f16964af46d2da38c4fa40aa814aa99d13749bf4ee6d155d113be71763d80333ccbe9ad85090b228552db7b5bc3851cca82e80705b740df45251a2b3321d7c5ddb0fc8e064c802ad6907067bfb6d3ea8bef3726c87bdbef9f5cca7f30d644a1f5919df5ca9f58d02dc53007b2c001b05008efd46bff4948e11197283f84526e333ea5949f592a79c9a487ee2deaf5aa02d976a25db0710717faf8b196f6df9939ea8f409defac02ec7e97fad3500286567a1fb4178d785b85619f23ef685ce551434af46516459e00fb1c5a1b88c1ed57300fec042a57f70f91aed1093ecc1f4af0d1e34f494adc503a0a40739769cc95808f2f1e88520ae5b3f5940995ba243a12576a917d1beee263657207e7ad94cd2b06b3068c011c60fb1ff9dfd2c07386d0aa3c7f461d382f9ebb705aa3db04f03b651ff004c518e63f7c65baeb517b0845d83523f57feb52cd31a0dc803ebcc521b34e3c58081033b77650efa62e9187d2291b314604b21df488e64f4990c8990a6f36a9367bc838d6719d2ac2d1a2d7d667b56511b37271a94e6ca3caac8e3a1d013a16037807ebcdfe18bfb9e0f6521cb87e4fe087283a3875e9e60b550a0ddaf9eb2b672bc3d3a708b915eb573e4eb36cd2b7774b21f8a3504794586673342f0e8b13d13e46855f2aae9493fb020bdb826bdef0cb42a5aba683fbe60c48146a1a77da9187a73b833550c8bb91060d970ac3d2ec5757b6353eac66c81f4a8e488fe6eb69e88086ca3633b5b3655a07c8dd2ce7cbbb26589b4b8f21d43d723f80f0c7cd8535217eae639934e30caa982bfab4a6c3b38fdf4e163110414168ae9a527a6605160885dc7199f8cc3d9afdf7a369f26742ea7df8486badc6bd765a2fccd717800d46c36962271b06b00dbcfe576984c58b5e7deebc5b0d24608a87799298632ef373118d225bed47cd647e298643587c0a430b01ca837c52e0788df4030c6b52b278bf8b5847f8498a9496aac1b54815cfb50c33e5f0581ddda77c7d95c38ef4d9ff0268aecdd02d7b164bdd7267b66e91f0cb5533ba3cd65840ae0303838d390668185f0f8b6235ce490134eaa7e76ee062c82999e666f30ad251cde26fa4aa5746ea2acbbc55ea1dd785d357099c6b0ee1686d9d4942aa96081d29bab3545acbbd2430500971ed86b1f0b2482530ed2ebf14f7bd4ad3ff94eca7831fb70062ce6731ed80454ba3bdf7475c4b919f13c491ccdf5669416d170e0c5793df76518e18c3772e91b5ef1c6095fd9d4bfe0d973b3666042df85b6e02f1973eceead3aa3502498508f7c082d764a1926122900a2c20f4366592563d1b55f972488987214d63853a6036339fc387248f9da2ef7214e7991c23a16b04431468d795e3c7b2da99257f678d231d8b89cc96a26a68c4b8d82a451fd8ad2c79546402bfa365c58f8bc31137fafdd03be7cef9c594a4b7f1ab17fbe233a665c1f071e5a3073c1cfea76b9b1252409bfb16ace86d006880d08f0a035f26e689f27a77e7430d41b77785b56d31c307d2c0b4b1a33d8ad0dcb042a2330947513140aae52d98ca629b717ece28ebc04fcd85c549ec66f63ed8dd952f1aeffc971f5469330250336e774f057afb15b224c07716bc2b2b33d1c490a67ac82f84147c54181cccd0fa76f5d3cac128c8dd781158ffb581ad87c8e0abda6771283d6995cc2e27a78bc28f9dcb6ab478a95f01047a55321a3ba8b0eda1db2d9e8eeef611a0e0501a83cd3b17567dd1888a1f0aa7b72c48fcdde05c13e5c909eed65b6fdaf0ffe305445d988476f4d518566aa03dde53ea7c45cd1d63cc700457b20e7999b1b04eec640c4e03c0250477b4c24b34513fbd7a58eae9ca9daa3edc905d52069886e01351a9d344404b52337532253dc27b3685bd71cc26f8626e9b1b1f8f0d51fcc83cabc8592099d3241cb7af063e03d71f688938becf2efc9160494a2ac78d5074e928382d6412719339a6e7b07234699d5147c1b8a985495bed6f49926844b2300a0c9f7aab8445de6796253f54205e446f2cd0113a8c3ebb7d3e57361f03cd71a21c2319efa7da6c0f3c417ae916fbacef331ca8196f8d104e594b55be7f9a9a11cea92feb65579f2faeb5d2d2895044ca2979969e3b65d790a0d0765aeeaf254e1370465677b6a2366602d1328664f23693de008ff39441030f1150733fadfeb6c38cff28519b02a145a4c6364d05a756b1e78670fbddedc947e13b6ae175fefd15a10564252275495f6b34c996bcfbb743644cbf89a69b252966f9f4047f5f21011a90f85bab824dd2974a5125f8bc6ad6b4a80090105e6f8342649fcd4da0d86ecd4984e72783f6d1e657e3da8b9cb43194c59fc429709e4e5023e8bb5c50e864d27a11a6d3742b5acadc4f23ae21456b9020ee694b7de5663a7a86670f34d5217f72564eae30bc40f510c2c60b081230adc5c2aacafd1e66f9568b5703f6446c504756ee69733fad92e9aa689823d0a23b97d46b99612182c95bafc9819ff1067cb41922db2dbd3ad5bfe33b48767a688aa33f393abf4933263989a7a564345d7c83d0548487b0e09649f112201c3ed470109dec0296820e1505b76575d44d4befff5dfd01c1fc49b010593470761108bde3a441c7c4fdaafb190b564170de9ab9df051e7bb0adcd9908e391dbad9f0ebf0477675ecdf311799e69b02ee8318bbd2a025c3c0edaac4a3592b79f62a4837314c11201a84f31e9e6d958e57866040a5f2bb06982cce859b06162e7a040a5b33f2be5623200756880a328c9a19ae924fb7c896f5496a60340abc3125eec47590fb92dd03ca44299e8716bea1d047d06acc421483b6e41fc46a4a745e158aca19797068758b833d51a5179d53d42138f6381735cbbb0c2b54426754a62afaa6fa98d0cb4625e0b03ca0a3d371cd2e6dd1ad6da6d2bdb297f5f13f597d5b7077ad97108d0e98ef8ad3321cb4370e8bf374dc67e3e00030171ee1601d2f95086414f8c70209dc1716a50219e35992df51d221d1fdc9a18a45e8b29ac81e5ca93d30d428216c45440b8cd926add5519b0054bb86a61b307c22323015401c2eb728da840ef047d4c2abf2996a60944aae607e0e052139c6d12df55f4e28505a16c0e7ac134af49afc298e4f7493270bfa502282bf2bd621c1aa9383e0a92d5858523b198cc46a14067c1e00d8de0b32ed1c531761786b9e130d373eb9fccc6eeb2eda5d8f75785b906bc1c05906e0097234487c6f9c1bce308eafa1615256edc6b6b87a2e70d81c86576634bba14ef1b2daf37a283a5f4cb18ae78e59b20362d53afe4710bcf560be1b0bd378dc7d95accdcd00d0c880634eeca564b4796895b914c7c506238ae3c395a68137a2195e000451995588909204a746379ac80f54b7755f9c430f7dac534b39ad28c28b99e8015638307e72450b8cb6d56c68b791582e86757a7cb90d014c783178b14b8bfe53fb1abf2a9111591961bd0131261c82275d1628a06024cd36e44e0e4fd5204894b6e17086a8c8ba36d0aeab3737556bc35642082d351adfa2270bc1faf0ba09d661ab6cf443caca1997093d787a97413cae68482221254ca6ad099580274db1646fc195b4b105cfed9fba2d3ccabff992b2e05a6aebb5d6ebc7ae40ddde56c86763007485ae72adbc1375be6925b889e3e02259bf24b1aa12b76f9ad65306490fd405938953c69b71f50d702e82e4c451a537200e3cc349f342daf3a4c3c7ccb0f15e616383124ba5de8ac5d60764c040ff56c415220aea6222300c018f7ca2ea3dc57d508c677b779fdfb326d77d64b7cc573d08f2d8d48e79cecd62f080f04b96580534a807432fe4e4f0433472e7030652a9a146b463f83bc36b46c41ffb48b1325c11a3538a845639d98c970e1445658a013a8d9a72ba36aedb034b621b89d757e460e32d771eb95782d6fc4a726c9accb93774b04d23430bc9e39b9c2181878fe1ceb632adbbf2df4fb39fc55a73fe78cf0a50a40791b2f94d84e756b7c29e6f7f8f0f4c44a87775423b21980066231bd3cb306d03a86ebfc70a38aeecec325b7f9e8c4ac1494ee261f2a283ad8a2970450d2cd5254dbefa371d98ba1b27bfa0284bfb1e4d069735b724225ad6d93912466c1a74f07cd9843d4c411fc05540c4777283635a8ba7322b10910fba436c84809e0c1cb773f53860351cace24da7f26f1aa05ae4c0a1a1cfca141c8d28c05a16ac2cb83404860d2702cccb54f37aa462a600e70546cd3e426f7ced4f257c8a47f406b1a0696ba3af516dd6e02e3d55df110ee1ad2539d3d21f7fdda85ead65d32d69791e0ab6b3be2b2a3f158a38b2d8a25ca8ceae350e29a573a3e1c28310a92bfd4cccaa5ca4602788c2936196e7b694c31001029e7e9131abc4e57be60c8d60d90dcb73f084ff7735d9b6b40e357f528f934cc700c8d873c4018b91b15293e280528bc1abbc95f361e5aa23a6df9f4c3ff3a5c6be857892e384b0889b5c844f5f0c63a698c04bff8571655ba39c0d6d98bb355d39b4eb75e43715665d93f7d840aac0539d367298834087915c53105f9282082bf20629b93072355d70ab1772d0069349560a1901db72e359a81848280cbeaaa41a6255212fc3c9d2c035f185fb6c3f0a95daac8bbc6b7baeb449199ca6e671f1116ff046fc4d2fe77d654cba12b157f2f217f4c9d24de8e021b95fc4bfea89bda26b27e2dff3956947cd72fe88c34e647c24f80a64f157eb3537a44f4560089e81ce39f4814c7c921a1fa0c5e85666555bdb78b272bde309a023bb70ec66ca3005144d6de55edea7ec7394d1b2eed9087eff331eb5bc5f92efde73c5b1449dfb5f8d822094a12624a6de71d2efba4699d16baf0571eeab785a885669f7a64c1b5cd34d43a2e27d12e5a726b993525c633796837224003c7b3602469c8e509304f21905f743b88340ed228bb1ec4ad54bbeb07e8216d08e31b295c69dc52ef205e8ebf038bed90be5f70c60bcda7782207f3db2650d2154d7d774ee622bc31ae36232a1563d1067b4eb0e46aac2fb174a39c0b066de4ad7ff88b6625f7d7db6823b3c919769223f5971942dd7d3c9ccfa912f38f6096ada99838387799883324dbd265f55e9f8b5d34c3cdc699464517ac47a02a9939a82aa997f3a37696f4fbd9555e4189f787f9f71d3d290864aac4a1cb046a33875f5b32e9096f6969c4948b49ef670d0c8add2dd394568bd98985bc772598d18c3eed9327befa440387134671d89c27a04348f8210988b37304870ae817268ea4b03bdab17d757423f12a239eab66631fbc9b8ab917fb0d2dc0b89ea17114f80e01006014f1608233a4fb1f11c9d1b76e4ec072518d98848fb2373b034060fe6b635dd7af23d1188d3873b11a5eefbc847ab0c8308b41eee2d3bcc5fb3cfffef4a800eeb7a48b65d6991fb630aa53788d49e3abe8faa94d78b2c4f9bbb2769d9501e8c5303be66cb20046b5d82acbe1496501670b2e05439b70e57ac25fb3f018d4d37cb45bf7c42f62aa5e1e221c6b9b28407e6e79f9cf6d1b358d8461b9ffa992b0d40fbb18c5de6aab2aa76e3808fac00e780342c661ad75270afe59adf06d299d15461ef5e081cd4e32aff98ba8f7e200124bb361f1b0116e66e6595819e6eafba9af907db765da91d61dda9a00156948626da81e037589f371aab04fdbe959b4f1fe0d267b311dc59689b8ced5e175a1906f194b21712770f3b31c4ef87a826ae9515df000e88dac119c99004266fc18303621595fb33b04b0b8f6306103924ff5d26540b087aa20df6d04adbb9c265cfb6d23e1de3c43204f48533b6d6a5e7df1827e8f8152c75f7bad60c0c4d3deb6b3de5392798ba377cf6824017190849b04e2e14d774ad42480797d80817db91e36a5f26841809fc418d6695c867d0464db2d4390f4260b4f1bbdde97802cae777bb192f8b093b3ebba2a865458d262b1a1ee4d826bed829bfb52369e4a13307990bffc22269b41963c938b646935bf28b90ab1cb32fb8f5ea03229c8ec4610733b4b09eb5997aecad42b68e119bff37536d9c6fc0e240892d488c8f4e26757f640d94d07fd7a4b49c7042f7aef009a8495af1b9aabaa32b69bfb611c4bb6f53958ee3812cf95c091b0f55220cd3c6d8539e3682de051b36c348243bb6f5636ccb51d3bb4ffdf525e36ca342d7c45c5e112ac40b02af57da520e2ff87c06fd575aa8bd9a2128b9902fe131d9c39a9c7fbf496b50aed58cea85b516ecd60996ff961d073b42bb01ea4b14b6b8608ed3901a7f29302bd825fb74f5054bd1660ecc654e76eaffa4cd88fa28caf6256ec32ceb2c60bc50c1544c0fad34d0a51effc2ed614630e777d126164013d729701fffa0cebd3f6ae55644dc6a0798e2a068fae33840a03f6468b5b22b60db75c6faf8c97e0f069fcbf8fdb60c9cc5879357f0188b68376da4d6a0cdeca36e729a63e0ce5f59de37e3017deb575791c57e9620fb2de96a7d8f21be0a7301939ec61819b8ae52abc17fac40ad022fb06304f71a40d20d7784408a4cfb10636de17817ff6fd862d7ac0bb7c2b640b5751078c4885f4fc28b803ce31b20267443e1251f6f248e0607299a9d912e73a18dda523911c36f840c7fd7064a245478505d30994d090c2291627f44552ce0bbc8a37008de2a018a38a4c55ec085301b5dd89d51ef0981523d72f9697d8158d3d030a48ca9aae08ac397545e443675925f75cf51cda139d3cf07e73397fb8dc520884214c292b43d343258314c471f4068682a463877f12c8581681ae56116198752e6735176004d5934c99e2f84f9072ee8d9d153a340fe80906c95d55a8c9cecc6d502255823e95d971ded6d2d6a1cea2f0496c37e609195b0d0e500bc15228be89f59c4d5599a4c5bc19e816d4f6067aff643c5edafa203832bb50cb18980704e560ad70f57546496b34f2d535c779a2a51596e8c7855c05c0e7cd9a8b916782abc2430131ffc773837f1e26bb650ebb846377daa39324f298956c08ff5cf0fbdf2a3307ce0213b375696e2be34ded5835a6a2d73825f79c92e74add5ab94393066d3821526a7c720e83f80a44abf231a3222f0dc7a4538d2f9141f7d5ca2be517827943108279dbb22385046c5ee71ddf7ea41e16b077016028f0a18f000f821cd83ed20afb1638be0296efb9865c816e6292d4416e165d8f4974c87aa9a1f9a49620494694ffb742a5ebe486c5777243355ccc4d942ee5aa512d80452427b384eb5f8dbfb2a53814d19ac1bb310b8e47e243e615d68d9bb18f33b6c59e6ea4cc0bc61a2a24672f23d9b1430d8953f7be0dba7805714cd2984c13f8a7f55932ecfb1ba008738515170f305854a408f2f25b2780a915575309959024221d8d7d3501a3538b604d2472a73282228eb7ab5f1f23ace15cd85aa28581173b847650731cad92b488f04a9cf1bddb329051e1c411aaca34467f5d1c6105c5cfc059d78f33ea865c8f3787b531c0603bb1c6374ef72adc8106690f86de4806481b7a199ffff55106eadf8e6a2349d3025e9c4d6bacad5b6c569f519f2e85771d601c0014c28c570c17659b9ea605010700789703e086fa669d91ca726bab52998ec221c9bc9bdb144304adff22d3738dd7328b4c19f76c16be3f76833fab29afaa5b0c0b15135d7c3a80421a150c48fa4f65792d9ecd9e14e7cbf07530f0122f58a1159e1bebabdc375861850d77449bbeb5ecdcad20f2b6b6619bb9e57520d187f8eee371a0f01c784d1491746686ce3415520922ff10b49cc4aeabb185a9f41c449129b99c51658acd5ee7418027c7feb40ba420ebbfa2e759895257576d9adae4119ca5949d7ca113a18a1e7aaa4a0f5574b0128fda51ac7f91453424e4550ec0b7f3643fc4f7ac1900803085384deb4e016f21bccc1007cebd66d52ecd217adfcc785d857f162877d41016f197b4e2f916689bc7d4b205625c4d348165d917dbb981816180bc59afeca4184c842973693b6568f36e477a801a8b4e6d6c81710167cffd5929afb761c2101acbf754f7a08583f33dde4978af1af3510046f0db6756684ebe3e1401d81c00e20f3185a863e216efba675453b202d28c62e3491d6eb63c7d37aa10035c85a7517795a330b154c7cb2f6083c136e9fbb25c36e6fb192d8fd5d55c7d99f40dcc6518a419cbe4e4bc143aa301705733a263402ace984fb039ceae69907c022f7219788edf9c91d30281ea6026149c39e2c208d6337e76289c62d7febb1dd5101338d03c489b6adc2a94708a556c6b3558e49ac548eb29cb428c0b584cdbb554f3473f478d86a071e67cb2857ac6331c1a99c89537623d4ade22a5b8bb3f58c066cdd5a78245b54d1b46c5508e9aa5ca480d6c0197c30ef4ec078d86c7c72b9b43f53201f6bcd62b5ab8d7b67b01078e005fb58ddf52c091c11fc63a04db4d4f5ba97598ba81cf668ca917e6bf1b021779ac9acc81b2ff42fb06b2cefd491adb7d616bac7d314212a8966e5c79f95bedf02304968fbb040c76d423533b96402fe7407535ae831ae5cc893342eaa58a7052658c43ccdf677c5b9a0a729ce66716d1e0e7138fd5713c02d3d3aaeaaf2430543c12610caceb5e667c3eefb43e9c4dde55220ecaf3df2d3e55fc660fdfd6d8f4a399394c1fad386e3a30945c406ddb95cce3faa541aa011b4fceddf4f4fa5eb8491ad0598cb7f35dab27f8f5d0179ee5c3ff96d970c92dbd67826be8b92a1012207fd80ccf0df4f7663abe11e21717fb20a130a4b7cc3f2a4ad0909836f3255c844d43e9eec2e91a5683962f89c0b8c5c7818e376b0dad205bdcce83f18f207c2e7fc4ea3f106ce02ae803ceefd8611c8b708b335f8c2fd637200cb678123037135e0f237e6f9f18b04e30947bc0f0ca60895407b3e65dbb7720ab08f8fa46332dfd0e26a4dece89b67229f4a44ce1228e404b179442133e9a6cf90af982dc87c8495ed2f55e69c3641533bb5c644f8dcb161f8373a87f8d90984853151252daf616c94e0576a0df0d7d8c8ac2c6df90eb70af87ba0ce497d35a1b0b9941beaa5f6f17d3866a3bf3eba92347c56e7195483a6b66dc4d504da7b010674f4197340b44bb4cdd871c20502fd1caea9b820fcd47c828afa01021027e538b49239b9a990ef86730c82a4a9372e956c04a92b2ad355c1b423d487c3cbc112a990e72f755b721057880a4690a8d1f92099757ba174d7d887f1d9db36756d051ededd04c9b5b5020f15eeda6e02d5bea38696fc277177cca7dafadfb0184ed207ad0f840e0d27bfa626e48ade790a78f6f0cd5a127e283a93ada77af832706bc1a66d87f73f7f70b26859093f05ca7baa3432cafd5a42981ace66c4bcec1404856bef94b15c0af397bada8e30fed61f41681050cf98c9bafc5f6b94d8e9adc8551a31608eb43ff9754dc6d389eb6c7eec194c6234735aaeb5ed3740c5712e0a2c4d550bbbd3820d8353c12a80089856d01d1f559bb8c3d85d141e571c7351aa84001f802004f06e06e0ee4f9418253194a80cae1f68f3ea80186a35893eac6c32be4dfe0731b4322014d8b666a58081ba67c209afea223cf0750746672e268094cb4b1464c4b47a6b3c00476b645250105717a8ed7b42809e35ba86b264e7fac5d704493bde4bcbea7f7852649929b2eb3f1633f1f9fbf8d7a208dbc9b3ab3dfb9b2449c00afcd03ba03660811f9b6bda0d92003dcef87b32e1856e5d1cabe9568beb8ca647d0d32f9e2b040f0c30ae8ba71c02914658d6b47e31d620e7e85d4c6e32acaa125dce72acaf3c3af1770bf1ec9a2c88cf20ab6be60c9a44b0a092432f54e4d31abd701d5515cad6f30f9a62f20a5b983f39fbc3aa7997b9e60fae514f7ca3a18312f396ea699b7362b25e2132c34c1657adbeed960afbb0aac991742f204aaccd7f80432ad058ac4062b68d5d16e8ff8953dc32adc059dc572baa1b7495a0cab58ea3eb14e0103ad282a56b91ed5d43d6e0f18f175c98e02eda980b864ce32368c60381a9912a4494a376d874de059734e878e1fe264c61451161c4d303c98339c530d2a5329245ee2f081964883cfe76601fecbd0e9cb22033e74cadb3dc5857a37c64b5e01c1d6f809f810563b38d000c7557613475297eafb8e2587192fb9cb048869ac64a48737d4971363c80a054806df784cc5ef30e083e9ac6eb8c1701b08495a832340270a4b604a9f2deedeadbf50a16f12aa03dfb2d8009028f3e9baf68732fc24a95b65feb3fd0c25e7b52b021a50c85c02830f7dd0729bfcb440fa7a471cd5ed864487bd068a0a766b5e15305934d2ab6caa449ebee6c51869a064dcdd418306763257289ca32e0a7be9a93e866f388cbd85fadb7d68f55e346b6f7fd5837b3a71ac6e245b39c1f1bf48b0937dcc0045d32a2c8f9ce0f4a29deccffb65d35af6994a24b743137efda26c028afc0482ca9034ef0005a8ba5ec7c450f486b84c65deab89d00acbcaffd3191026b01017b56bad2969c35f79fab7d7e6e555015ea9872557a551cf7636fa579cbaa67e1867991c93db45ec52ed559819a3701d6daf9c104dff2647451dcbdd51ce1f837a86dce8a7e6708abce62b85fd8d8130c8834c7446c571139b3df6a375b97a55556f7199c74787303703de9ceafc1880179a61a075f80761836b98ae5502c1dc9d860a244328d1a33229c3fd7b61fea92b8bac334cd36b971071f38aa87670dd178417e4ef29bab34e4a22685f57e1cb12c899605bef84494cb058b1458fd683b86517dfc6e142c603e48c6cdfe3813a65b8c8fec9fe86a0a80a20deeca116178e5ae71cbf4226aadb7098aa9a87265437d62583528de7ffb1d26c887e855de6befacfa6ad6ba55b26dd1dd27c238589144a2080d8a1dfb3979aa1c8e0e1691ad3911ba66b1ff705856e0d451f8720d2b05964fc6a11509ca76b3060107cadcb45fa3785c418348321caf7470dd5e52f756d89ef4642e241e06cc8626af2d0db5da0d76ba074c59a0f8496f45a1d55b61dc9abe52e250a34f6ec79cf353998e712c62e9e7782c24b68676813113269263bd5a36801f88c39dde6f7dfef6ea4c3972c4958fb0fe63b268dff39f7b3df2481ea4acf1bb5db76fba5c4981b7eab77db2c23de2b11e2ead7db601cd1b6f5e86b5e6c37418763555bc8458eff7e802b18335c72ce12fff68ee581e3e230af6a56bc0c9dc99921ebcbd1674bee1b902237f9ab70edb6b655e82cd7cba88b8e2849e2f15dd206721ad142984f65ef13f3f143e5d95c25e37c4672f3efd4393c0f26b5280dc330e74a704fd6421505f65a923a4b21c40668102f7b15dcd0f82938fad13c4747c591a3ee84725634186877219dbdebbbcb83b98118a4640fe93305b571e7e912112e63e1aab96867e438c612ff5b32b828b09dddc147db76cffe1dc8b6542d388948222c1956118a203456e37ba6178300fbf711de38c758531b004a227f1fdab53a826adf3e6329dbc6cc72f3ae57e566c502fce9aaaf7d8bd42dcbbcded253e6478429bf846db7c0185e590d391a1da5eadfcadfec21aabbbe9c8e97706c6eced6f8b1960f41e6086baa9c2f4385195b124df5825dab2e57afce2ce59628ef6df2f5c644de08071db5a1ffb3d061c3ba083c4c874bd9d040c87dce6d7039550afd7ba98da24f7fd96a07f44040639452d1e8407272a137c28233a650706cd554d37c5f44466dde0777c801ca7af1b3e29d38e2b32321cdf8f26d269a8c1dac3f5e95f0393d2fd0c1911bfcce84da0112d556df7b06748c14c66b1b2910840991a75184b669b0a83bbd65a4267d8cd65400e4adc7ec4c706a478ed4d5a7923e8bf68941a6f397b914aa2137daaf543c73f8415329a5277aa90f6a632d1bb41ba4a9da1bf741b9e640dea902c906f510af80843fb59f17dc8dee8f27c4b255c0338ae75918311eab7100518f536fc3f1927bb56e3b186a9526748c61f7cd768fa1ad1e4376c6dd8ae91391a8a7671ec8b446b47d8d92a27ae5aca8d20368870a731aa411a2ae493fd133ddfb2a2ddcee5a8b6ac3665a6fee0c64124f07339b24d4ae9ddcf0f46ec28c636ac7fa209fa4c8cfac5c4c0171df05e4d8c69b8516816b0df2b05862471f65a7612da344c479270a78cbbb54d6f496a2333024b818b0d21910658e6aad69ab2c816a8d9af76b2576b1447f613039a5757d131b2bfc37351642e3ae6a2b8b262d4160225f937190bc7bd8b774edd8eb2d12108597a1e5cb05213fdb0cf0e1458f16c74c71105ad80a14ed1680dad776e6213c2f7a65cfdca20cb7517802c7d30d25ced7df83a0dbce5212f427989db4edad7622bd731d9d74b62a318858e0586547395d772f5f7d0ab376bd6839b9c15be9c111181d0d5c3cd460a0d1273bbb818d07bb0ed2a9dba9cb59b0e839bc040bed2809aca1b069a83dfe6da1b1b800bce62747dd66a3d270991335d0a80f1fc555a6c52b458369db029071183296ed98990f888ae7240bf8ba8609111b01f64dd4c7f9df805b81a58abb8ef49be421820093b54efa715f42dafa6e71a205c7252caf80b72d2ae51c0c017d40218932150304b2bd548e4bb009aa5a968d182f9d4702f4141208695d230ae6f4c8f7cc28698d3b0672acf0df2c36e57500429b460cc89eec2846e14ccbb2c2d569121dbd8fac0f8f291c02e152e0f51889b02e88b8469ef16e37354f3f63fd038696aeb8ae5574334845ee23ab2ec48cd066aabfee7ba85ce307242abf794d2128608510bc60a4774da2c9074ca44623460ed6da1c958aa10a88deba50b1df4d783618d2a30186845edb4d44a24cf3aee719f0db34cba41ad30430db935c2f30d276f11e35b47b6315e82534d07f8b1696cfba72581e5fa3cba2e7befa8c8350d68315c7f758d87da0ca0bae484b910babc2f0153255da145dee6546d8431fe487998facc1e8a18b4b2017c0f8a993b08a4f853d645cfdd7f12294f6e65057717656971d2bdaf8846350e6a7b4db5565bb91a6f13eb8421f1bcdaba61f5da99fef77b9b8b6ab5dfdb0a1fcbd2624146e6c54efe99002a7d1ccef3a6a049aa79b3ac7a082c9a9f6702df0e8f1fd1c3e0907d13ca2d5c9943be4b5465b0a5922f69f1514bea4cee8368afdb09264d20a92b4b0d54a917b8554efaf87062f2e7c1441b8a6a44eea9fb61fa5d28b2dd1fd20e88281f1ff52d248786693efa499ebd7464b3738aced1f499222af7caebdc4e21c5893461621afffc7edb52f2f928747875a10593dc114836349b219122553d8acb0eccbb105349265538ff196a8cfe7293dfa81ba58ca7b7979ee3300d90c5393ac4a82c6276c57f930346deb7721b993b1bae09e47cd6272867e5b236920ac3efb9b9d6b41e29ec033a586071e5e53cb11e1a8293e1b49673624225597c49a63755c2f53f95e7c5d0857afb31ad163362c4f8535e2b2df837d64c0b6adaf017851baa167877f63733b6715993e3105d6b1a8f6202388fd5d6ce021ed6bd30f7c2145977e786dbbe968e032ee5929e65bb5f1f17ecbba8a587c29d69fe430780d30434db3f205e13022675a75dbb582c0ec8bbf00b37e157934cd16864af98080ce4789b24c40dde2d45692e51726f42e5f5c406deaf27b33c2e268dc7ae03f8d466f5a6043b814fe0a23cc85b7f6e69b6750e3b9352b34e78471f628ddee680be61a2cb8b371d324451181e54b00468eb1edd149feb6bd8b65621b6908b9d90dd1d76da5d212bb6afd6094a2398b2c54f41650082aa65511cbc89f8dd6b8ba81a187e288d75f120fc6581583d6502bb0b22bfa99cd1ee45bf31a3b9039587081cf28a91496152901d9fc965c954cc71dba5c4dafee67f7c0b2b62a1d7616999b27bcea58bcbbd55d7956ba41793854e4d2c59b51d6a9114142edcbe9a6e95cd0a1733b4c2ef80dfbe56c5e92d516edc68646f89ef271cd3667e0c3278c8f968e8020bbe7f51b65fe82cba0ba3104c48716d03d3975ff1046e6644b528c89f10624c1f99b4cc2936f268cb7defa05d49f15d5a82946c98a634d9004a315d50364ad980915a758b35ce3e91962e96199ede91d2cddd212f2f3b1efa465e0ed0626a5fea7652b4fd2aaec1183db649ee9504d5cc415a0f92aeac9a4afc1288341d8cf74a711984beb31a82fb605cbe77599fac0c08ab17929c6367ac54c9c547385518ce3a20ac03f700d97b38167f15e8011d92526a9d6391a57e297222d6a00a9be584d59ee91449bea91c52a80087942c66ef1ac5bbe7f38a3060b444552cc58a6b92fe4dc679542f84061ab27264ede6aafbfcbfc1d506da2b43970db032dafc7056419c003e7614b154482077ca1ddc54a0a446a8116a70f0c6c241ce2b43567bd8416fd29471544ae581740ce95a52983ec0963aa073755b73f0e5c12d796b05c6a7542d9e4e4d092fb8ee0dc89a8f5465a43e0a92c927bb32d16bd6055d2e2abe860eb4bbd652ef090dfbc52ec9fb3e86a069ea63fe3390ffba165177cb3768e7bc5e45d0b86b0aac27d6660426af993da77b80794d1532c1e20d8c52e89fdc370f8f1b087ab689df216285ad668f1a39985fdb8dae8e226e54ad723ac96f8fc4a731e0c4116c93fb97c2857ee985a8f60bfadbd82bf2b1d97387c0cfaba64beac91e72d525beff87935115581ab9afd1812f1e61b46d99ab2e9016caa2b6b11a6959d1212e80aadc5c1210bfca8c00d8ed767012d4cf8101a2b4654e10cac7342fee7fd869e8fc83ab7ae0caf55189511f266375b4aa66227e9f3b1f0fd37cf9ec2cd64d27e4c4eab78490d0cbd03ff96237872959b6b64e2893c80512470794b1855e63b1077d40bf835c93b11675d24ad6396a5327321c19543d11bec71cbb802aabfc55b9d09c7d83fca03ee3af414fda88a4eeaccbb3f4717e9aa7d07a0d19f38bfb3ef445c3f6a5d0c1d9d89a2caf7812fc36d1b1e10bc5a3a5435af6e2087c34e770c1d73fabc8f0fa908aa4e487a8d2f11887952008622ab8b8d9db8d981829c54e1a5de3eb3766d0f5955ab74aa2486067cc75f11b74d400329c23c07210bb1bbc39204f83c445de9875f9dcf94e0415271b5925eb32813035122555500f78f0c4a108d7e0a1b119c278920e1f3ba344c1fe250e56a577710377b4d08dbd7dc3491f4c3414bb9fc995fcbd34d7b408f36f3b10d8af513d3a85a62428f949586babd70c15b0630afe1db956d05ec8fd7ee4d4250df08ddf254e1c27ca192accafad9bf4c9301b62b7fab614d0667351334c92a6bf8d2db855b9d2031d371059e1569b4e3df408b4e5613642a6ed26e65c7aec3c2a86cb2533e29e80c08a3d03d0e653c927032393602a02797119d62c678870a7a13b6420bda1889804c73e930f65179fe8023f3fb1661e64d9e5479e247f7c123e9666c19e89b634c322d4d1b3fcc45c61c4b4574822967601096a83d870ac9ef98e82cec79c008de2e0b9c7afc95e86b226dfa81932ba175268f0d7e390951e40af0b057beeeb756f7983496ddf18228bef4b3a8549f943e88946ba49381da02aa1bd67d0d737194cf1dfbb93e36b5ed54887dbf908a353b65092afdda2d4021b575f5ea1d4f9cdd6e968a96ac3dd6a442343d90b1a28ba19d955bcfe338f40f59e53812f5be502e2a082e501c3a356200b47e7f0575bea4bdae77a9e385ea9c2b71817fb942971cd659b2c3b0f80b0342c7c3bba06adc8d75caa5d44209a8bfc55000053d43868041d71065ca61939017c00d16f9398704c052eba7e4869d72369334f29fc432587c5608ddb47bf5e6c08c3ce58bb1257b12973a89b3640110accf4f26a7fd0ae57ac5db02b7709a27f811117bb33669f1139e2043ac9d1286f288cae9696a75522e8f4177ff0b7456f6170892c7865a92ad49af6a85d11ad4bf6cee3d3e80c7388eb3666ebf4997812fe14e795f7515979f5f1ba3de1592c79288408862985bfe5c33a360dc963397a809ebdb21c20d9b681dec0590f8d98ed8d959ef9fc95de6adf19ba01d9049128f3f9f0e087f4c68d201c36b8aea07a3c7577aab068f79f64cd709551beb2165a277d2a2dbf89e653e512f0f4d905c6a5ec25242e220cf838f5382262481b6b298e32438221effd31cf0a49688e574e65e8c081fbf6a680fef754cd9135a16a4f932d23b9524dcb4831b9fc01e52c454a451759a82e776faea3a6f81cfb8373859bef442ed3dea358bafea3501b6b72a0b2886ab83a210b5378bd9563a7908d4d33622dc3e026d79e58f16a22bb7d46adc2a982cede2fcf5ce5ce7c5ab567c4b60d646a762345473296141bf0833e797eefe35713af32669b1cf9617f75c785300e2a092645bb62f23887c13089796a40954bae6426e1898b3c683bf623cc6ccc138445c5c52d1166cec802b0b6b51d52163e6d0c55989cda9f8d68270f9924a52e197cd38c0bba515d2a69a2002162dafbb5258a61581e9cda65163040cf55f7aff0117d6c2587ff5b3fa9660d53cd50b8880ee0ed3153ae91c591e6cc5d16243c1e06d45e827b377e988ad5d617af7f3f2686acf249ec0e5790615d0079dec7f9339106d3fc44463cac394108fc86c83fba3b85fa4c78aadf5b4d9ac8eb78d0c7291239e65a784091e77eaae8ba450a0a17daebee902daf1d1e460c992f8e5624583c8c651a130c14c188c585cdde36c00442dc29f50e5d3e0e88f6729336366920956986592ffc25e42d4fdd76fa9ef2b8475ec56471226869ee8be0e6bb0624db6c7808647cc9bd88740bfa19d9cd43c061ba4139afb3e22d814d546f9e82d338119bb9875a19294c034e881ab51a072e2888fe8f7a911a0f5dcd830bf4d6edec76b0ae66524519092b7ebda85eb38b432247f3874bfc0023f6c0876dd1476d29ea17c71804a813e80544fd0a3755dc2e37e8d951c8cf95d65192fc80bd21441814bfc249bc4d8802e361d36b86184da2697f3856c3dc4f0b86f1fcb8a33ba285d0a3acef6a23b7074aed1ed15a967d94339086ecdf896a7318f7fb32b864631b18d5761e2fdb6c79a1fb5c043d70de28d5f0e69dd533afac3b3d2d9cfbcdebb309b46388d649d0ed32d30d3dfc918eda088fa39f84c5694b88b6655ece8980b654ec3d47c0a0ec7b7797c0614011f7cf57f9c46cd8d2e90d9125404f92b9dbb36bd3d9f6a3abe9edd2a62e0e595a2fee7a2f67a344090120056b3023ae6a6991d7d20ffb0f38d673498f4cc5cf022c7565a716845f054fbf1573a6a733f54c324376112fc507c329feb837c31f671bd5ef970c28519b66b9fe09e83a5110bc14c031cdfbd4e39ff38a552342f369220e9cdd623f4143b3a4caa2b2a87c499f3fee9744d5d2cc85171825d988dc5bac0b26d8e7f43c25378d8827053bd88b5f06efa3854b530963439d108d92d87088a853e0a63b9743b495fa2d4ef797dd9f2cc3e6c1641d40f112b2d020c13da59676a122afbf6b6d50355ba901ed3384d743202178c557deca94dd20aa16223155b93e7a59eaa0416b6dc4ac8cacb3d39d1c28bb6b73638628266a42753149e3c30ab7f33b01daecd2bbf566f8aaf5a35892c3c9de83f20b90284115ad4f46b9913d9985f1e76757abd9e9c288cf1e45364a6d2623c0a04d031ed2017393f9f34923d5e79a5714ad7cb7404e3fa0a90ac881ee08f39967e6a5da7866d6b2075c293eebe7f4fcfc80c22599d12bc15f574955d7f49e75234d2dfc0536849a19d6f419eafd336789679cb96fb57ac9a6698539694b197593403daae72c162baad2a1988df8343b146402ae6e2a5f30e544cf5511fcf075ae834741acf68cd298ab3a07e7d8b53f040c677542af1221e261de84cd62d6c0956db0d92ef7830ccdc7928124ed20488644300a99f7f0cbf41513a84178b710afd5b47102ca794a3b267a01623308ae01d60f124d88c8af3695bbe8637250fe46f53ebf359ab6e501aaea643d3d597babc437b243ad1bed7c096d2b6e2f0308708c0dead206f7d6092974f0c23d10966b4dc501a03dfe0e842dd0d2418d35dfa0b7237ec43698110e8329a6b2777711535eb53dc2677383c901724df564a01939bdd9456b93aca7c0eb6117341533a9335a10e2d587c11d9916d7c4890c1537a439fbee851b0824b1f523bbff93b580126677f6ce02a9a5034fc9341b8fdc790f9ca2a24820ecffdd7f6036e4cb06bc0301a0f264d46e84621649ad65c7f24917f6dfead5d9385362a829d54c14829e16d559547f288d5a59081f4c9c6f511af5e94804f10d1fa4690ace573b82f10726297953db7c7d38523658c9d4546548acea36cc8d11238a88d8501462131b9d0010cbe488048b0f83d203107bad3d777c587608b6173c8c1d58dc88dcd2069ecd981f87cd9498196c40940ddb85601c467ddda3cd0ff014c7f779cdea0f039f28d37821ce4db6669195cf5f28741341cfdd84718b4d573dc633c42030ff1e7b8d11837ef70b52fa62d2b3c6a8df64e0cbddd91e5ca87173c32a531eb6a6215f9ac61d48bfda398750ff039ce903561f62ee75e1410b8c884f889bfd4ead3621b1dca902637cf3b4d54800eb58155c8869b7a5e1ac823c3ac40a191c894253979d0a7140ecde4f6c412ae707fdf858ca6c6de95db80205d1946460242d8887b9219c6eb1d67d94589dae015e2cf4f4709b5c0317b9513044a389110d22f70840aca7c8c6fbc81846e2a486b27304e1504033e9805bc41194f1b04a56cddaac691f9d612a6c95ab3d2b7dc4f25df31f5aa9349fae70ce2226f121556872a1c1c6333ce81a47de02dc5adf68e2973399991810d14dbdc2fbc6c022921383df5c03ad371fbd00b9bbb7e1ca6c63bb9205aef492813f654c2fe128c1e98c3c2843400218efcd34adce90f64614e752556d77eca1c9232ed2d7cadb928e330c1ed0f88ed9834ad62de3bd00eadc32e5b79aae44e1331b15ac08356eedf0e8e6132e820b28990b837246cb03f54e073feeda6a8ec4f9ecdbdae07921c6f0b06edb399f77895b33c843d434a86d538e0e8e37700c88110fd54dc2fc82c686866cd1c29ed427050751b2966acb056818da3e79b84c4e37b1779da3a101f812af231f792285c789f087941431225bfaa2512af3f4121791b987a83c5c46d2cea321ae16813056e4ffb6c9c6c346d79f5e9b9a7fa70368af5a7ce4f6b3feafa57d1e61684634e07221012e4a03787c7f8f3da6d3107bcf03eeaa47fa8d6b09b2e7549644bad5974b374dcc1da11221f81c22f9343cd58e43f229a3b188163606d4a0fe1826f6eb66d1b6d8a3ecb8e3c434d419af53681c842521ef7f29a3660489543b66d80a1370600e2ad5316f7d3278d376ed39d377a076e01b9e95d65da55c2cadd3a2b6a3ff7d40a3cb14545d08550b967e48da7a903fa632b90b5667ce5048ecf42957ab53b8b712f0dd68004351e2c5d89bbfc2261bbf76795d1388b034514ad4a335a4dfbc17b9f736232a470d5d6b9957d9f7abafc020523c74bdafa9b82f2d48554d56db16a04d0b26938d2d3d13e34cc3a1dcd9a0f138f7471973e050bbe26f6813ae1fed03ef91daea1cab3490a37d432f1af4dfa4304d1131ff4f30cacf53153142f348f7b51a2fc83e58279f0e8603393321d86b97ffa7cf21c8a1d198bb9a8ee3b51c65e4a4e0ab69b62f084410f38d9039920556751fe3391bf6560e2acb3151700311331b02fa54e44bfd4ba103afe621cf8fd1fa83d8c30184a15f6ad48fa9c29059867fbd5caf143a40282e1d819bf3c371bf31f62df1d80d9fbbc5cfb4a18db255c51b6d55a912bb0465a175c291ab13f838789ba549214caca259192ea38bffe43c84a87e4cd5d6498ae94ee3a0f99656d3a825b7172e9bb28150ccedecb77aca715c441b45772fe2ce4e7635ee4c8258274f3eaa94c482d097232a66b7611c8efbd80e5fa315218ab857ff5ae03ff33976c4ff92f1c4cebe43e993f7a5a9b8b2a132e1fda7dec957b3b9e98d36911829909a284ed6ef1240e02171b323e922212c78cf84ccd2453b092e928c9a04c22f7825300f5345c3dce8e5967856b084b851921a6257a68d933b101b9cd135fb12a159c190dd0a212960e72c8a0fe64bbe958025dd845d296a509a760702692575aad8f0bcdcd9eeb7c83c5557b134d999cf01ad47c7c1cd1ac7406af0a44d5fbdb9eda198aef9c41e77061506445e4813239e41dee6cadccaa221fc66f6ad87cb421821fbc9172d04793c0c2e044ec1be5d81e006e2016ce7339022b7d52b37b36e1e648a02f4400902e9d8ca229565d9d3ac04c1dd6a8d4368f302b789915aef24b76d1859947b9a551be34ef9b4386ecd5cba2712d3f4a9afb50bd2f2575a8d98e75b065c8e29328d89a1fc74f2aa6174ddb527eeed80e5fe83475d9a78fa525901e582a05e88f8ffb558438e32d68a341de6e95e6944d10ff97abf89cc5c4d4abb6a55898b09a9c46810b54548556ba7296aa31a80e5c4e2cec5dc58b0c8edfef3e41541b79bb844ca925901533c7c0ab303f9ca371879cb68ed6fb9b900476dfc175be1803f14848ebd88d6af69bfe28be8d0da3896e07d8b8d89f40f348b5ebf010698e92d44d4c2976962d9b576fe6f9bff1ba382a4a3da6a85c7f087df812800e3939c26b4c44de3a2bb4d0d5e5e6c5c09d76524318c2116037afd338985499b26049e7eab7853d6a773c3ebea01f73d010159351c9a303e11c1d5bb9970f18c4ff54d4b690a7107664d73770cf628b8606d13ebd6e4fe80549fd336e5c6808033a8e60d693f5dd3a339fb38a39654188a539d984cbee76662ed9d5d28a5f1a9a28120487f888d825f7c3541851a6220a2eb06c7380cb6733978ea5e41f0ce2abed93029a376c66fa7eeefa056d6f2fa00f025be678e5b4a25ecbbbef826495f01101205991592a7fb231f5e0726c00a4b618206d9a14843f4c30473b4e091d92f41f05ecc1269559fe17fa2bd7b881791513551312b058be92b229f7454c153776162f92579b10ca2b35ef37dc95e504b6d92a235462325f312a95953174a3c4bf8a9599ed4f44f49dafb0fbc49a3b2330b5db7588a792ec00d68677addcebf77680831cc74302c40f2b0268144b5f1970ab4839cf8d466ab3ab00547a45e1eb272519ce0a613866863b69f3e5d9f7b79eb9313dc04a09462c354c2845fad52e5406cc412b77a32c071caac2c8032840a4dac3fd01a6b4133c16e438ecf28812432b51ba02a939892bc84c087b54be99705e77a344021f2b70964c2dd445120323c85b4a2a16334c682fcb0869ac0503cced5b51fbc5abba6b528ab0bf139685f9b09f313c0e9db38cb3955d49eb5d72885d694d8ddd9e42531c6f11297e1f15ee92be370a967092a09eac04759681d0eae33e5043cdf7d2d4129f9c9fbb227270c4ad69db3b3e119002a3726783f273bc1abbcd469278ada4c7ff8acbc5a839aa52a33a8223b3a03bc80eda648a6584a220e504d435a9c014f2ec135faf78cbc7f488b532a868baa0f4536bd4323e7e27c1951e72c65d2b8563c311b676f7c2f7c6eeefa176085a6f08b62e03a23c131739e87bb9dac05c0448093a22dcb491b8389fe4c6c962ff8843ad0e76baa23a6ad6aaf29048e3174d3f71b5e1109852cce9b92a8c0b34a065d5b761f9baa13b335e95e8927483c95c7ae2baf97f59dd50d397c6714e0a5f1e3cfe4544057ede6ee94bd4e21b483ea50917d1aee469701008d0baade1b55e707eab23e929cce9f730ec14831c9be24dc7e071839714ea095568881caa5dadd42a370032a289fc0094731ba4946d479788ecfaaee55b4cd3466a5b4b2446b04a30d5a5503e8523d958afbd1ed1fc70f487a579d11d0816073daeaeddcf85cdb54b54f177e1bf3ddec7075ca8ef32f9735cf82658a145586bcda4a06ae26d61b84a59a0baec5ac897dc5663c81b3b54976e73c92d07f26fc98c78c733eabafb9559e843598ad76cbea68336c70786cdd7e7e0d680e7d9e73caaabc8b4f8d35dc60a19dff7373017d59b4106c569a2839c7b7b274308711c58e658dfc9ca9756cdff2c1716010df4eca49e2d1c2c7fa17ea110a979d7d046788ff86f57ee164fa2491787dd64a5e13a745eb60638c20017e013e04f3572fcd247b0d71abbea295dc36134b4c238b963a08b00e1a690a8374bb12be81ab11026a27aaeb533d117223a35d4ae0467a7dbbd0d5830d6917290a5870e6dc46f9d9398b5173b4dfecaef3bf7ec096ac4253961925d592ed75d9579b574a129bd1025492c08aa835ae96cbb461271215ad48cf5b208816e7cd0c847473feecf1d419cb6bba5d77fa4225a20288f5274846ae94f5987bdced38d756bd8c396fb245a9e2b4c1326cce16a120d8c30d3b086a2e8e6245a358ffdee715c32baff63fa01a32659414a0e24f2db0e2afaec89365f7c45e22b662f31240e7969723e008876479cada45ae650743cb4411d80eb74ade9202275304e624eb0fb12fa93f1586f671633907e4b713d4c05b5f2b1e70454916e45d71ac2cd380764527240489901ee3a00cea6088faa2c5c9a799ba93adc666e41ca3ab4839a53321a33195854748128a1596b4982f223b41f48d514b6a484eb9bfa92d5af769bed16671f625442b5b0f289d39e8449cbd8bf01226429c5f4407af4a07e75618135067374d6e9a2b37e064ed786e6c7dc20cd45bb73b95b794250689e8a557168277439e4bba35c842c1ede78a1f7944d74f4ff9ae151b6051612891b53a3d9f224672f8744d6d09f81d5308fb7ff59654588084f44158214eca054eedab94d6930b15f1452c727c5868f14e02c9d9945ac048439c393af89ab61a422ba67e4d8c07326c463a2c5712ed5caf34420296a3749ebc694fbff47f69753195e2489d98261da76dab7831f5e660aa1e21961104954140165593b5b0b6ec9525a337ac3d0722d0252cb0b1c9b958a0edff3471ef0d509ecb6ad68d5e602a17b00ea99fc3057236d18676cbb8bc5b6988a8d213d1d31634f94a952510fb1ee1b66ea3117cf65463fa42b44b96d303829acfb26b791b30780b87c1c7cbca3afcb97f18adf3176b79f003933d671d5cd48d57f049d8759b5475a5805373d53b003bd004790bb1a6403ac35a6fde7e9aa250ac2dcbb0f9872181ca2f6f1c11070a53a37cb88e2c4ceef08b0dcead10ed26f90dc3594b7d2b1089c4caad77fb6c505c9a141dabac72e3ca17234e5567c08f86138fd871a104dcc34b0bbae329470851487f16acba4b6da1f4f19e239a6d68dd7c7819706a2aa67e77a778db72d911a77801c443b404e6e7a1e91664bbfce3ea8562cc8ffce7700244308983df19e007043dd66d86cebf257cba8227f0993ae355c4c6a1e0dbd5552350495524e5bf594fa653073ca5a38b4ad6e20d5e1f4a4b44d54b95582d74da101c06625259ffc2020662b1738dde95a6c67301f8d887c32793101f74408a92a83c199492de55223dfca478067406586faf309c2ac2a15c450fb60265b27fb83df96ced792663d61f8eebfbf827e939bd0031499083c8e5274b13e6ace4991cf85dbd35621fe46219477bc996b6dd7163c85cd84c8f05ae9c7604e19a8b2cda641afe1a20db79a5b2d2c937c9f31686694670805cbd7f4251f99568fc1b9afbc6ca0fa401221a5e3bab4365240d75b84f64be0195a44da6d2e0ffb1cfa8416ddd994e15307f86225c777d8257ae54bde5e6c5ff8b89ef5e225f4b6c7f4c3bb50851cda62154d0081d34b91344ac33d72b0faeb2605e8bcb69a9135cafade1a1c540ac9e10193e95de6d58591a202918c7044bbf0bc59186736553289cb3397189df8a1b09dcab9378de24dd0434d46b2261e76f2173112026dde1483186ef7268294e8b91e649b36e83f3c92570b334e662233c272b9284a6c9a0da34bb670ab02f519863a3b50f874eb95648b740397870bcdce75b0d66e7d9ab763b04ef06cf5434c1b02c54c51e83a41d7cb7a9d1d3c516cff1fd371737211128e46a2a865fe1ed3aac76d689d9cf22711e879b8d76f1b889f61aa1df3b03dae0c35d49ce3027182ed32ff993444c8f63e4f4a8065c91ab8b0944e24e74cd1f1a244a05068b5a43b1497df6ebcc3a59956cd10b903fa5620b949dae2a184dd589154ac609f1aa9ef3fd0c3e687556e6c943a1975df244d8786240c59a2e490d50aa785bb0eb33545ad00aef11fc1db7b1a674874b5f89dda6e307a6eaac1cbe471c6dc279745dba6e8a982ad94f5e26ee00542ac96cded164bbc9b3539e4343606f84d19a41f76a3ad681a343eb32f7a67978a496b15f4914625ae662a173d536ee6f8a7ba9347d1131d7b96a3caa44533f5038ea67e9993a874bae31966bfbc794a1f35b9efc249a6076e639bee04c1ae6234f66cc53342b9c5983ec68e165797054adb636ae71c6ab6973b63997012747b504ee426a46230710528245f271b0b4b120e46e731cb9f978abf4be721391d0915c46a302ddf7b61c23fe34e0b7988840c8b06b22ae586443a2623be6a79cc08940bf004ef733a5b7a559fc8128986c71170c5e461334b812d87dc9ef3c46bc0bd667a144bc0dd7c26522db94ff204d942a10408f3107b8d3478f51018d0d7afad1116121361260f785beb5185b3a4a91fccd66e982ca89b438865f0d60913eeeb9df77b36e3e79738ea1517c888b6dd26d8fdecd1153dc527187c9a98d984552102752e695bc2c5ae18fe5ce73dc0f050e0d2db7c69fcc8c30b878821a3d9df2a4214869075ad75c1f6e5e0ba980e07f91e53ce10a5e8c18fba754a722f28a369765561456974c0dca108bb1f420f833acf526301b018564d33e1aede0335b000757192324e7df4f80e4c11e5b8d806e2040425b926c26f9be6b1e0ef5dfc70bd993339bd39033abca0237dbe6b2073d7327f314883b052f3831052c2626ed92561d50b1be74c5c423ea7df697540c6ed4e6f2737870ad91d6c80554a17ad37ab9727dbdb821662bfd23a2f8c3e8687e299c8a7125a75db559d9b4518a2b1003186fcd9838303260186ab2b0e44b35de5c8354a68ea69d174b7c33c10f3879709c5fee8c1dc22f6b0c07527011b0cbf6c4352b391f162e8c7424be55e855b27d3ff613db56e85525af830dd0233d1312a63e52be6f8946afc365f9e6903b23bee323535c3321f4124a404496318f6a1f94230d8452456d53ed43f322d04928d02ac565e5d5481699de8b7efa0ff5d9718a89e64d14f05716e3819b67ff4bc5548cd8d8ea9a94c313cd733c803f15c1bd8ae962af3a4d5c491f590f2b3b0ba26c925e48b1b9bcf8e7ca281091b0f5d9ad2f45b655a2e5ae9739edb51658c7a7cc788fda2c833646811f9fcb2792b89de42156a3c34c07a808879bf0abbd9b08343b8e08adee2a3795d5f24196e719dee7b220dca49eac557a741b2bf9512b46e665ae7061f0c9f4421f8ef5d9ffd215ccbd837fa15ac05195b6ee4699740a5d835912aa1d8ca58246b465e9462ba9de0f9fd555288f8e61863697560a366fb0d694f1a03c78ec79130a2bed12f4deb851f40d4eb27fd5c69b885484e8243138a5279c4547084ca1d9f1c6b56ca0d4e4e3c0b616485bd8fe6e5b8c237f8676ece24102ae885238456e04d8cf72437ec20acc47b707dd0d1c8338ddccce6a67f1e135eacb57e4515deac7cb2705b1352a16bbc9de10c2a059f1ac7a2156ae841cb41f6f0ed1af73cd166daba0c5d5fa8382a8fc877b746478b2564aae4ce2a998b097bc527b44b00ee4bbfa0a14c7b807adb4d31f070594c494fe1404537c644290abf3174fae852800e6502c6c04a0d00cdecb84e291c225fa40ddffd53f28bbf2bde3015acc0a03b4e6636ade4f4ed88909ec9f51b2c1028dc74fe40664a989f69b774ed56388b6cf2d7a3f5b657dc816b08766bc3c21724284400931a7a1d8fce0fb947cb0935985338ae90ba30e407b2bd5f5e85751f6be259a01b3fe64bfac0f2f96e92898496c51af5580638e45890a8b17957278a474adaf90835c9bbca65c39d6a5677425eebcbbf7d32c5eecc1c495440f1abaf550ab0347431c9b24ddf0f50ce24a2af3d964039cf782a7bb6ab822b85d6587576596251728953d92f6843d14c207528386942df47109f9d0a405a392e427f1f34b93d83490048db38bb81766e35cdccf2fb903cef71e4c9228559dd1aac0de7fd7658409169c468d382eeb512f87d7bd8e50015f74f207b1044e89644b87db3e0097a7ce2436cf90de5f043157bc942683d0f66c535623ff162b3ce598af3943f27d1114f9e67a466c5a08bea0d97c2cda582aee94e3f8a7f7c4802b7df4fa798b0da5b8378b03cb1927acd376467d1e78b860096683a713e7d3cd8416fda734ece30b6dd376644f1ce3f4dc0f77eba11b913ffcd52335d61891c368ce76e63454937007b63a96ac57e330687ddd2ae8a9fcaa6014849e70e9c0f981447e28d08eebac4c3b5838af4a321a535911f6c539b109705c06b051edcf5c4203a3c628891e741ec7285163099f07f471b47588adf898aba0b7189b80f525841d9f3e1093824b4372fbe738316a43342829b7b1e7374978610bba6d961b3ba4a74d5a504284693bc9d1ebb69854370d0b3a8771bc71dc02077982b8bb03338f600a3d2ebd98a57bf3d46ee7225c618f7ca9071c6a958740202610ea0282252df5d2c62a6651640c83fa8e37691165b359a786ec6858480678b62b8ab6f3431fe743cb023d9b1b8223acd86b169a164e2a62e3626b780cefe4a4088432df4a244be431ae422f1d586faa7bd221433e88866ce7aa7b42a71cb263301a120691d4b5ffcdfb6b8e3209762b3edff6286823aebc5451670792aaff5247b313378042c427aa37816efa2a06a0424f27254ac85ce13a04cc641403b8da44ae5ffabd82e7dcc195fc8ca23cb085482957119db777e14c787d28f82d83b243518e0dbe28ffa5eef745405e37b4973bb43c563124854b494ef58af000c2c182fd76f58a8743bd360478432d4b0ee97ce1c581aa660ff111e65f390cdee20420d8fa4d8d692076167e6b2ef772695fde4c3fd420b94ec04761bb129598ee707397da0518c054ce178a646ce0e9db289fc301f2b432acf1e1cc9ef5eb56448f598c72586fbf008c08e07fb047bb70de34e85f5dfa9706bdace478a0be5a82420becef94a4f1d94263de507bd21dac40648c4a681dbf628f8707d2d2c6dd401904ee01680ebe823304928cb0239193076fcb5efca1cdeb12fb1e109e8491e5207322adf4a044037f4a02818fe52abd813bb931c2509640afb1aa2cbbf218b08f98472092cf7fe0842444e10df19061e34523bfb51038ef29cf29ed18fac3f290d2f211e228a219e0ac384d3ee01cb628b6e210a684ec13b15ee16ff5c9e7c51e1d83657f30d74951381a2cf0f8e4bc458290ba4b340d7e659294937c05ab75c5ae3aa4a38f4a4a0fe0dd2497877a83702c83724a24de7152d459239ef472afe5ea9ef091b66012237412cca772d7b391d89aa8512c21ae54d3dd91f2bcb46691dd9d955ab171df60d861860137a5a5dfdd6fb4780b2ded6017d0b663bd29a4010cab8fd38eec114a37d01aff11406605486fb8ebd155f275015e2e3d893ad5220178f97addcfe06dad81826225888604530d0a16571cceb45635fb0c69f60ede6ff091074722a3d749cc99eaf08c522433b2a75c12532437de9053666968d66dbbfa4d54683e1635404e12b975997243d9012bf523ae51be174232da9065ed45c4886165434e87a136943bd4ccfb9c5e62aa2bb41ec270296fb4a2eb76f1091f79a2af8729b675caea7774babeef5a5b1dcbd7b88c31d83847edadc280a4e02942a1419c4f8511fff75e4ea13d3d40737ed88ba62cde622fab19725a98e018b5d51281eae636a7b547ea4941c26a8b7b5916fb648e274040c6ae13c35fdddd2f49874ddacda922a0ea56eaccaf1a2170c18847246c8feece050b4a1511da13d151f30e331880db300d0d58cef821c90d02df1e817e68b9bad148242f4e016169eedcf00ed03054e24275de95f013ff591ceafbc27a9beadda8c0f1adc4106a00e37b9f8c1d2334f097b9ef6602cfcb10f8c1347717a563c92f2ccc44654df86a0a25d84d364da7ec0d2008f677fdce7e454211244da0baedf597cd5a641a82bab1e959d71eee131a0b05682917d427db195b42fe63b504cd1fa98b8011218f17891852788d1763abc05c7980a2d88f1102a42db1d38804c9d72d7bf4f909c1ff1dd4cb3d2aa543927385e0c89624aaa6c6399ac10f597c568b01612dcc3a981d10989c4042141611b5fa3c7fa67b70b2e8e8016c41abe720ab3eef1ce57c2723de3a48133ab87f047f894f2cec8b5e4c5ad1d0dca54a8315f4e82f1f2d0d7c0c5f60f5c51ebd70bc013ff448b596848de3c2bbe96a42941b86466d643978dfc82667b19df25b491ac04907d66cb73498242f88c54871da6d1c592eb8b9d6d7b3f83276cc4df65ea541ce82d7b84cf2bd3e6a62a8631e3c9c48488183639399ff3e7a980ca4a0fa9f41b6ab69923725f33603a0d8bde144a4a5cd10b8ac21344be6d7045e58b680fa5fe684f3199361f5dec7ac2a331327f4fca6615ec591818d8a8af43a8c92436c72d8a884f11b9e414298e191192cfb6641ba2cf6f1a5f494e5207e14137e16e6d1f78a2c38e6d1cb44e36a214e0587323816448068b04e22538c1f68e712c42311904426712dc5c50e89908ca93707a60126b6e79cc09ece4992cab2288e226656ee3c83530971ea6196aab06bf41e4ba08ab1423559e22b009c4238335a44f64e6f68281d98762c296c8f5c0813904243140db2a3db11d191432cefd034dfd335ece71dde2303a9446d9339ac36e59e4a31af53722e19a8ea36dc0c34dee2912a276f1658ad823e42aab286e1273a11d804aaaa3c4be2dc36e8e5fc2378c64d1edd9f26d245bb1c0f7d9e3413eabdd20e0b171275eb208c94307a5320a9604b32af250a38ed1c1c7d103ab0051d1c0e781888440b77d1af5d99c32ae8ff3418677b3dc7ce24327f9a934f8c02843181090123229bf2c463f75bfba55dbad63689cba2df98a203017c8a03da1e8a6e5920da15a903d9abd27f458ea7769d7c31cc9d5666cf13012eb38c2e4c5d4817d6c9680af1660be02e4427ed4b600ce01cd600702076e890f040c95d081e7d3bf0c3b271a7f28ca15b4b4222a8027941dc6def2df79652a69402d206c606e40623d80c9ff1a2a4c1f519df2f6962824dedc334da87b3ff89c940c791b8153e3e05916bc120a89953cbb7a09e6680a26779fb32c0202da8a7960641508752097452ac766fa01f10380871b9efa47077e53d6fcd65480a19af7d3cf849c67becf96466762dd44df0c5869e665c0e5c79ef3ab9a28cf244ca64109d4376219bc005394a981692149200512e71fd59240d98013d246cf4b22ed64a47739f59f8f33ea3588b5d064856404f829dadc9f290460c262b7c6245d7d171978e8e8e8eebb8cee7222a78d286bbf58a80cd521bb2da9881804bfb47a24e6e57e089629ea8999aadc93387cc23e66a2a993ab3c8f567c9cc2559ab944f230a2b6a2f47d0abdbf990f1392f36a26f7911588410a719dff2334432b04922e1924abed8885a5ef4a3a9e049c97ae6e34d230adbaf434a6004bdba3db4a6bd4c617d786eeb5e0629e78712b0f839c958dd9ea823660be965c6b7bc10a7fa5dc04f31bc88f46223fad18fc09cd18b5e889337832451a4171b979ff12ea0444998ef67bccb8f482f3632fce8650047e0cbf72ee0cb07eee0a7183e0650aa402dbeaf3526634cac48592c2f56fba25d79d65c8245a14260ec86fe7850b7012d131b70bf1f31d109a0d440766a29419354e28f188f9458f16f0bed6f037de8d5953ab012a808c5668809569ca86e990c2543c9503294f6a22b64133551ddd665c4609c73b240f30769fae91af3266886283373ce39c70bf8a987840192127203c60f128689cd2143eee0c8144c4345e7a84cb3bd8c0178200b143b234d4088f18425cc9546bba7e3eaf63d5bf50dc8f340b16dd53d9de366b58a75cf0dc8f34031ae9331f2c701f246de0887e7755cdd34dab205700956b67a70fdb9d3a4681c5ce7182acc47f86ebbb7043e5066451ec23210827f304d739288fbd2f4da4cb60a010f9c59955158bf75369bcd4a386a6c6a7b3ee0669e3c7bc6672882952fbeb681de337366d4629dacaaaaca65bcc2ea936aa44875d59eca9acdcc524ad7bb58ba4206b7608204ec94f36385253b7dffa3a508d7a90ba7e0aa629a15d3f068095724565c7f1a46ac58955c7f8fe723c2ca97cbc31e3f1a94b0defb007def49972b7485ae303564479d02099575fd4d9508c35415c7f8fb083d28641a661a174161e57bccdc1dc182eefc5e76083de879f0fefbd16b94a88d22286c836255d2a2bf4d3925d80357afd65ac11e82a017879b99b99b6a929341d0db83f6cdddddac854421c0fecaea09b2bb3b6ba129d65b591eb6a42bc4a7461df1fe03736a4769d2885362eb0adc99a982179a68e11a4f7ceac0235e71a4492e61187f9974a9aaaabe5c66565555555555555555516aa393cd5062eceeeeeeeed6f89b58e107a8536c14628930c1211858d0dbcf612134b9623ce5fc5881bdd7e81c7c7f4e3188abf56f93f492c3143bf6583640840cecce2311f1ea71fa00baa28b2802907f38a658973bc198115eb8fee5e072ebd7e47ae86dec5b30476af1841e273be37802fdcafb57635f23d9db24d6a20848ee46e26b493d4a18d44702033b03c2bb01283361cc4c99b97182157bdcb6d0460947e720293839729c1c512c2547ac82a8e48e4c713299176b99ccca703c742c2cd3f8f4004e8f3aa43be372de6b37a42947ee69a0426a82650f6d3cacf2c2c94cb0672f9cf721ef43a00fd07f209f38506c1f4e0621c994370ab115e4389415e528479709e226ef1df40a446f973f0938b39d1ed6670f3be5212705ecc2b287b54acb98a60ad370d30939cae44892a3cf26784029bc4e89b1e29b92a6940c076d6a9694dfbd1ca24dede27ed324101c348c1ca261bc03454985acc17599c4f5e7da88ebae2a71a049204cb3bd8c42d6402661c428a1f0d6624c09639b9aa6699a8d871330409bb86bdc03304cb3b111b817390b1a5101e3c8710d23a76a46cf8a56b5f95a47032b8eae7f7f5add3628e69cf5980e12616549ca4d1bd5c0e66c369b513aa56bdba9b5568ed5e7176ddc7e1a2014d45bc11078c8347c2587ce128707d3c80bfad58e0ef49fa67d0fea3ad07fdd7b3c80fe034b2e60f0f1bdb7f2a1d7b4eaf2848f2336a15f791f1ece4bf7f7d2200f3cac84409046c312b603bd9f76d48034baf1e7750ffa1c30c7035d442f6cdb01345260020e6ffa060bbc600710217ba53886022c2b712dc9706432994c86c3712b51586245a68a8c47c8d76b072baca7dfe1322f9d16e395e08b7cbef385f8a10b560c7b8734596b297592cbf526055d602d8bc5816dd1c76d5bc48ae10da5290786f187b2e347cef9e3bd58dddddddddd1a7b5d8963dc9320b650ec77c55207c57a572c953a87a39690da154ba551693492a65269541a953a28d6eb4ab26989c545370fdac443c2748eaac48b0a2f287891058d2456641f70fc72a84f3f1de697c3b6b5ab3492168a5de176668b039bf5846b48eba458012feb3ad0c7f7476c3e90c197e9e3653e9f3a1a9858ffce8ea4cdc20633f3a862c16ed788d1bf09863bd6a5f88ffb78e83eac924fc9673e33b39dfea261fcfb5be7755ee7e7013257ecd8f6bd063e17ae30852f2440ab44f791b9a2ab1e7045dfe19058d9627948c308cb2c27e22a1f1f1f1f1f1ff7711f4a6d4891125aef689675234ddc7332c90bdd3a311cfaded8a0092638874ddff0da840a7ce246e65070a64acfbc9182cc27e8262716ab321addc4b46dfb949873f2e439e79c737a366a74873d86f4a9128bb2a3720c6c62e53fc7bc5eafd78e275c2e53b581654c8561fc64fa77b519b6b05f415ec781c03ae76c1b7c474cc704c3f7d0e50b567ee7c0ea70b95c2e970e4aeb1394520aaba1d2b44d6a018ef1f7c14d1501579ab6efda4198ca6d928d4d0678e81bfe1b49233961abc84710d989059886effb0e1ce3308e03d65ca06fd8d0bef1b0524d2bdda0d6ca951bd6b18e553b44126fc4f51ddf683d0449221c7e2ccb1c33478d7eece29a63099f1d2178bda28462b59b03e9a43ca5e372d2446b088b476584fbf9f9690ee4714c41946a744a3baf683d10685d292edab4c30b870215ae37ca9398be8567e1499c0aeb38a85e83ebaf5d61454fc16029580af6ad48b1e00fc8c30e8aedeed63fb27fec0f140bbaa2ad3d52a0fee43df7d607568914de37cc0391c026e714c7b1384f718caf9048adb8221e4ed95cf4aa6157a86c20e7ac54ba87e826ae607d0304a5e01c70e863150ce33f04ac75450f58a9fe7151e9d98fa760ab15acbbbb57a9558a4ba552a91df8467f123ce5291c351c637323831593b55ab162517660465e4f5a3c158562d91512984a07ba4e225defe2fa92eb9d27a58c59e9ee4ce34b347163b8ac8512ad4b3f20fa5623ddd717a7914bf295af6444f9bada532b5c7f2986bb46a3781595693a762cbc07bee21831d8e453ace46bc54dae285f2bf95ac9d7eab5922ff95ac917378bccd554ada68a065484693628388764b24295a039c6ef064a9ed56baa54413c0832e64260182f5e1edb9cc0e4ab5153c5327649596513922402c748270ee3bc85273df5b56af1fe0b710faa3e05c738e854348c7fa0e85c5c7f0f149b0572c370a0e85b340c2849c334283a0fdab7a002e63275c534dd73a01b218b24207f5fc95713962fa6e1a0742191c079b5d65a3f0f9c71988ee11bfd376a709027c31352c662b5645294c47660515cee84a65229562ae52c16d3905a002f4bbf45f9e4fab33c6c79d87ec475e2933e85c19a34119dd5800684218924830c2c2e1343abc2ca9f48b0288be52c96a649901315a534caf86476840f95580c0683c118c635d2d4fd5fea1fd9339773f68c695cab2995c23006a3c104eb75a100ae07be50d0f75ee841341861c546813c1fdc7befa37bd088abb31aefb9f701faee6342b0f48680e831ee4b9022bce7be08d0772fc4f51c071cc3c2728e7020112f35dd5f804f1df8e5d0af69df0d25d0c097991a5e72a0e2cbe6328515676ca0c252c043972aacc8aff9e9606f835270df2869b2a222b1a8158c4a4d0b6d947c73fb82f6b17b44b1941cb10aa2da49496696b254b2121c8114c0915c9f0234763e722b608f122c7dad6218e92cf447a91ab97188d82ad625aed1d5ae518ee338fae823a5212d1c368e23eb937294b526b19386173616a341c48aeca2410496b5d6da0edc073dfa4ec3a0513b49ac5fb1562c7058859dcee1afd1b7f01d18a094b8cb437f6f314d7771794a8c0a1c240a2bfe0522040926c6518bc562b1586cdb3e2ade88840ee69c7394b2f267a9d65a6b85511a6cdbc61bd76aed68c4b6246bb576349261e871746adbb66ddbf64d60bd84c3a07e7ad997b5f6e572d2398cd008b8b3c72f9670fd6b04b1628ffd55607b50cc61db8090638cb1c9a003db9f433f10728c31a64b5932bd2c2c10d26bb05d1c9345dff0b79e85f5cb333995ed970b4c59970b4c76066b2da53c76e0ece0d14ce03009ad262499210a2bfdc331eebed2beab2e97cbe572b96a0d39c6c56264345d78508494ac9e73cab64cf30dd1a6b053a206334918c169bf7de55eba7b0725a4d324edfad73f728cff04c230cc800d06d75f93c1047bfc306261457e694e58314442b550c21da3fc5ae7f49e98218e391acdf9df7279083db0e28ae17c71e4ee4d50a9ab80cbaf99948a85bd21f4c51c51ea9a0b344dd364386de29ee7f34fa93d3f0b81c9cbe7f423e485cf890bfb86bf0c0654775a9a0d8648c2ad9f6ea00d35e4b421e461406986366861e89a0c67db4036d05ad358638fc5ae7c2c76f43e3e432c7b48a5f4402bf60b5970a5863e10e775dad4b8bad53ac339f7858e8eead553c4e52d77e22bdf9931f7c9e33293089b5a8700d7df554ce357c63b274df64587d1a0c28aae13facb2eaacb50a699b22575244a0a6153cb078d04c380c050b6c9681e92249d837bef76fffcb5a3d572994f6b47abf59ab5c637411554bf1aad1608342b28b45102b9cb16bc6913d464f496d3371c023e30d23afdf07666a7ae93d137ea26b51a7434806fbce66888c6d1c98139559b54677c05418d3a3339335f135e33a3191d978e8e8e8e8e4e8dcc93f2ffebd7afd555841498b0a95500609af6de821558e50425d07859b15dcde3aa6258da4bbade76e530720414a0508da7feee9fbd916c38a6c64350b4a06c5718566cd503c18aed5251c0c3510f8ef177cd5c3eee72b98b028d637bed29f8737e3e33357da8cc586c4ad122d31fa4053327d1a3eaa9e5f9991f80aa27d18bdc1589fa7b5e791d4e830afb329faf769a3e3486478931c72933442d2d2f12b55811c9cef8185e943f35325e87c7a0b049fec8dbf2f2478c1faf63a377f99834b98c4a2ea492e85b5e9425ede98f07913f31d0ad21c00d3d2af46a446143ef695cb062c76231f9c3f2f67fa68c22653226757cfa0649362161a18fa7482c6154521cc6bf3562ad5432406fa9b10473c728188bc5c299b2ce82c5c62ed7eba78a131f1e1915d893e972b19cbd8df64cd65a0150afb02f3bf8a9e7edd7130b4a62e9e778ffe4e9974b1cf5cbc562695f353027477bef2b98537fe33ee783e11f0eccd940ff32419b8fbe8fe7fec5c67b1f9587dcbe971db4dfde4603e76bcf270ada54f0067c9960cd69eeb4abd52c579425ede258bb38d62e8eb58b631c6b17c75c1c3332d359348c7f17302e9a6ce18a6d00ca288cd194d18d6bb2d060cea94d6dd643f6e8a17953aea1693dfc9b2013baa78734795f396f7605fb89c350c07b7c13ecd8f53138c6ff658c9bf3a20f35c6e8e798264c2ae8f9cb53430d38703ccf66cfdc0d4f9a617e369bcdb6ad34da18a8b657cfd66a6d206f03792330ece5d3886f9de252ba09d7bf91f413b197741324987a4818d8900b6040032c532a75c9927a48538d8419d239980e81d5004b804bd3488ee6aa860a27c45aadd3adadd699d010b899678ca5bcb8675afbb57e53fa4cf3b9e8c0b287b7bf1b660d13895aad9da174d5755dd76a750e6460f7ce816a6534912c79691ed8ad195d8189bb89d40b266559135a2a9f222b554b65237beac669df01fe0007543d5a35fba902a98fc044e0d0f6105d9715d184b1a5ea3a15f75dabd59ab1999921f96db53c2fb451c251637313c4689b9b3948376b5ead6fc009c3d22bfe126c0f4bb84c831081dc9e2bcfea8bec73e3a107403058917d4413338f1e48600296916f5d70fdf3e1d90d0d7a3ac56efe36ee15146be07a6afd826cdbb681402216bb12fa40228fa5b3dc4a0d7d54d3346ddbb66d037d9625b4c20256cbad84be0ee46d9bd771356439c161ccb0d878c4939e9f202d6b2923d1ed92d87abb24768eba2476e4a387fe4305c463c58685ba4ad7c934130e5552878763b8ea412a18561c09c089ed7fd1a18ddcee1b49c10a366c94a6aebed8bc67bab9f4a582363f9a1246aca3c1081721d896151b562a51d8f852c31246f6c460ad82e5400a969955b0a947bb8ab83d706db3cd25af381a81110557e708a5a9abe09a15a18511d63ec2465bedd980c49088f580cd601b0c06b37198a60283e1a8117501d3509a864ab57886b08e5829d1d15028ed09b11a56a56106564a6dc60cd804d130c47ad81c48c52e20d4a4848dda3698f7844c715c5754adda0c2ce781225c6f2de8a80247e17ec181a4d62899ca63e9152b2af460b3fe8b1ce143e4ec2ae75447b35c34daf6038b6528160ac51282041344505c2c168bc5623729ce2d9526a289182580c39134351305d0a1936f7eaac05f7d05418d3a23e76c1a680bd8cb07f0e33e5ec563b399599624ab540a435913aad4101c1e33b8420aa8d38f298428a7232f3a740fae33abd5dad1c86b50bba669db65e7256150723d8c22bae8557cbabb3f3d42830e9bf564fb555f355eff9476b7bf49e7eb8ad7742758b00e7b85a26f996911bd7cc5341bd3d02b7a57182d87c2f22e5e1c9fba24f67b1dee45bcfe1436318df73c3b5e8d5c77306c42dff22ca496b724d13749868ccf01fd8c0fbd88b4f220d207e67c2ffa1cd0b71cb111bd8cf7d102ce781f22d0876d7087d0b7fc4de85bc09c2336325ef4392c3f03bc59791198635f460b89e54524fb73b290f83449dd8b3caea8bd0fa3db4998d10d1de83f1c159702865771186fc2add611fd0ae23e6da45ff7670ac3f8bbcecfebe7355ffef297bf5e2f4a619dbb38d15ad358e3e6315f5b2101d1b70438b4461a898063fc7de0186718ff2a5be0c1857dd19e6f09da6df01d2e235fbb3c62d7885d231d34287169db569dd8b68d37d6d1d9b0e083c372c79126eebad23182c5e101019a3044804d38339d23878930298e157c28ce26936dda56ab27f3dcc7758a389594942e9b996bb52ad5ab54b2566bb5eb54ba4a9afce42ad548baaa8e8690a1320abfbeccff022e13c40557ecd4a80512d515bb894de4281ca5e7f3930d1031ab0047b9f3c9ede7516b10ef4917061e848007490bd5e3aeb7bbcc640b516eb77f9352cd063318e18b91e3d8fac6711cc78dd2b46975d3ea07e27134053b63c269391648b6eeebcc04b94edb368eab756686eb487cbbd5753536375cf0388ee338862c47ecfc9186a156ad473dd28bd78139317401060f4e393fbe24a723f47ff40f923875dfbdf47b1ffa482ffd20b05bd50097ca94202b021359ebf3beeb041d232684cc9692d075d09282f3465b5f0c2bc060b7baeb5958b1a90ed977a3608f1d845220429060626cb55aad568be588bd92e79c94523ac1be9225537a75b80f0971ccd1684ed115ec775166bb5361a43f2158ff2aa511b3d9b8da09a2d2318262aac39fd020866d596c8918aa7e384cb1f28a55d37a36c36d7626ae5b212e45d899f67db9569487de1c116c8361d858adf2ab42c7cc35a3b3d96c369b699a3785d6fec31a0fd8a8e1ea2971bfe64282b1251afe5326d8fffbb55afbbf6d4e34959479aa092925ca9c5276777f1886f839e5fc98a1c4ec14fa1f9c173af6a52c0c36f528933e4c334720a314639453aeff94b210cf9c734e1114566c253bdf0e7d0abd46aa170c825ed10442dceebdf73ee47954649f293b1db8a78f4347677f3754903ddc260f13366945c85432954c25234919c704e118bf230f1ddcb1752453c9502e336532994ccaa48c521baa101566e6f97acd58c591a639271039ba48008462a76d28dc0588331ab94cd7754d0242ad10002c7c0d52781d417bdaae57932d3a47659acd077c75bb374fdfa82feff55ce7813ccff32a28b4d1d203d555c0652db450e57a2b9452daff9765e877f7d73c48e2ce27acbf46a2b4524d2b694a24a574d229c7719423cb15e5a85d51b21cb1e28f9e102bf68b254b96a2ab821b720c33b934338a5b02bfe24b77d0093b8ee3467f0325d0af51272f0d3e3703db301211ecf793d2eec8d6db4637ca1a1de0824eeeb4bb9bfea6c3f348d20abbc35d94d00ed4d11be86803450f78a0f73c1f40d77b1d1e690711ebbdc82e1bc01d38a858fade83409482a8b7c47a339ebd1e0741c3191b58fa6209071c331dd75f6d14b62389f5fa50e36a4fa5699e4a330c050c0683c16a361b25263caec1cd5c7b7e9cf8548945a9d5ebea0652a954dae488a86cf7ebadf5946cd2d4e329b1f28acf63b52bfef5ba4f88edeaa655971efbc2bd1097a3a105db2abe53f5e2513529b26a7d31b0948617581f47fa7d74efbd8f9707da8040ae46ecd82caa28d2b19b580f7f504f471949f97e19f1d281deca75001af66262d943ee786c93b4ef6feb1cfcc8a5dfa3722c2d4a6538ac97794a29a5da87615d00b022c452f0653e0b71bbd520cf65b48edb36baa2a0495ff30f87bebda2a4ed7a3f60130e2887f7aec97432dcff0c21081d8676fbab8f53a7a0a26f386b27d55af56a4541d106e0a35960c20bb60409cfc85a511e826046ca04a081384cacd8abd65e003f92c1b2700e467abb4e8ef19c458939e7a4829d1e7ee1c4b6cdd9715b2761484ab05c00f017b06d9536cbb65adb9b42a552ad60fec4c8ab88ab87a544a51a8d46230e65a92459a552188e46fc725273c3329834f95879d0b6f9b0ef3912b7c2bef73cac3c2805969910197299896aa70897993c3185eb29573292a61a2961ae699ad63f05abc4271a66e02a8e718d44a43ead907a95d349f002aa75fa315b4a749195ab52aaed4557a9422f690a7244abbff2dbb63dfd2ca001b9f31bec41fbf99ed7a058128d443fdfba4cd7812f3bd8173d0f2bcf028a56de87e86d079244dc8f6ef7deacd665e66b2ba4976949deaf3c0fa067017dd807fd0ae8c3c7ca7bcf27fe74a0afad9034ed7b04a3db81228fcb813e8c6ec3be9df4388ccb4d6e727b52c3c3fb95d0adedf3335bad34a67195f3381157f5ca55bd72550d35e0c06163a55ab9cb086aa55aa95e2a954ae594da50712e0315b8d979641e7329fef21ead824fac8fcbd09722f4a28c22633b5ab7c33457700ea984964e4bc75b5d41d933f668d1df0183892540d6006d8709f4df7b9236f5f03a4792040ad71fe481a27331db62e65968ee45928a846936ff828b2d3c0b6fe9788b894ec78a2988709cb7bcd571a18d128e9f6f8ac7de0aa594524a295da976f480d087422f0ac0d42d8771d7102e9f28a5945a92e85948f657487d0a919eb8fe4e5c06f837164d84437f569f4224543d8942274bb2608e039c70c13aadbc10276f85c4e30709b342e2615f447a11813f802ffd166c70073f853e04f62861502e43b94c119c63fa4801430ade5728740ea6f95e7419cf2079ac7c917d388ee338707379a8846392f40d241cd3e2987602dff07f3510f8868bdd9a7139c61b089b7634bfa783d7921a74d139ba7796b72f826edf986003692101a2eba8648eb87456b2110100000001131500001808060583e190583c2e9c27d51e14000c61804084643c1a09a4410cc350c820638c610600620000000c0c91a8005bc4b75540a5a7c72b1deac50145f8dc4928dd364c074088a269ee6dfe486a1253dfae4a91eb83683c7be2abe30ad51f973c7c268c732e8ff712c14d2b6159b51439e66fbb7210af987b982a00826bcbf7e28eb27efa429df022e047c4271939921063dd42feddf0f2719645a76fc4a962a073a7af70baa8efb54d55a27d93719c641f8c33029f90d5e58d35719c62d7755351f582d2e269d3d628a6a751ed31a34f8240329c070e9648c5802a045db863d9cf40445b0c278df7d0fdf26edd62eb90caf0a8a0a1d69d84882dfb62ffad8faa54d3307de15dd3a4cade71fc11a4c9fe03c21e02fac399b2997cc8a7581f30db8a441934184df0eba87bfd4c734b0a3500e2cabe6d7e2587073cea4c712c021a900e439abe8a36df876321bd5e1dd189f53fdb99d07b13dd5be66c12e3107a6e1fb13d2e9aaaa80a707b64848797408927c17d4278565c732853861a9b5652083c50acb269abb8d77f5325231858e3bc3604e0cc020993c41205628091b626e07eb718fa43c37cb4e2d484f935d82269a29d0c2698a6213032ec325c24380ceeee5160a8f8307a02a297966fc2f63df573a80452eec54da143bfcdeeaee51ec6f06c1c04c9b27c675ce3ce96b1300961209fab8aae6c6968d96a2ef24ed067633fb5349caf52c366b82f5361003c7d5dc4f209b46aec54ceae2bc361ea71d77f6779559c9b30548c205520b84d0c6c00b953d273ccface5a88ff49f5320dc4cf82f7e966b2d97d82ea59e90de3eb2284f69e12fd4aa8b8f3b63a290a242f139a2bb71e7fdaa2dde223820750fbce770f88ce7ffa4963bbdccd1923811cb1a3310872841489428b57cd37e8bca7095840ec583dc08bcfe2a9259390a06bf59c1972f6db1ef75c123888d24db519f82c9223ec9311750ca9039825b68a01cd4888bd54a844d70eb0c32e7366dc4dc32fa794fe4ffcb78259a2e16d2c1397a38ba90c9bf56a2f4060c24048bfb2304d1612f8b233594f77fc494f62a29c14623721828a1e4b5264090272e3efb2145450631bba11192cc5da390cab66c8041590d50a9bb19390378271977000321aa13ec11b9c6b5ef849f56990610c2891094cc57ed207da0b58ff2630cd3030a2343b72fbaf7863d5c02ef0fcce269c574fb398d5f37922212a71037e680942eaeabafaca5f8d22e00672ccf690b3efb177ede1c8e0241ea5f6cce84181921802f9e88ac7db43133771e6ffe87c5078b9880fab08ef7f586d6c305f763c9753bdc537bc200d22a1b3552a06463d1c1ecbc7b1418fef7470020eca9b44e47dd34f56179f4d3979cfc99ae87c3d50a586b4e45b9f38162737f84268c7f031aeef6deac37571ab87ffec269b6622c4b8ebe1bd9bcca9ecfc587f01d74ae4205fa715b832ff7a18ccd52caa79ffe0bf8ba31fa94da79c386099d32273c4b492d095d0dfad08c5dda8ec265996925e12f3dc56165fde30179e24c75ebb34ad4d869ea5e7d04d122e6278686dd34d01192f098e5f11178f25da24ebc534943b0c54da911116a0225c41a7bc2b1ddc80969369c512d042a0983f92fc084a8ba29eeb386d4fb08afa396330a5009b14ab80775aea993744276dcfe0824b6c90a3c105ed2385304f95525c3c7316f5e508b3e4d48265a737cc2b2427e2d809572cf6190871215ddb9b526e68599f27ca8c7e9acf43f30f9180aee798c64a33295cd17b24a643b62ea6ae59d78f71369b67de7a77c0fe88eeba008439a19e32ef7b88b2095c2187ed8a5bba01de81222a89bf6167a78184d1e358988615b41bf88485c56ab78871c2f25a76443eb9efef0bcbaf66041011f07b8b71797d5d82c0d326c4edb90a633f4dae21cfe522bce3b749ae2a19ea31fe08ea8cce9ca9d4c17157ee00b22931e61f68d277b4ef9a623f4cd7ec43c2958fa53a43b50fd4a3fc47bfe7a05a39e5be281b6f58110248ac2606f7c1e7848cb2b5a0e3ed9875d048c9e8e69af173ea71ff6910b7d4dcf9fadbf1661c5db3115cb9cb1aed85079706255abdc40c69d0d2810a2a1ab821f4dc5d2a141f3c4a74ffb7dc1fa3337a8e53db2777235f1bd902d7165f482f30ef08313bc4d8e827f8abf1df92fb57482ad4f85ccb67ff6254990853988f8e34c1ff7c7c2cc1a8553ceb6f714dced694df8c12b789fc51c671a3d56e358cc4ed05c3c08be80b4322d7fbb964c450acd41f24390420649b61876ca9e84b4dae0b44ec88662bcbd6627f1f9cb43fb4406e7a4231e6686635002426c5c5cbdc10157e2e0d03896c2b2a85d91c7ea3a2388270c6de417c82f0296b6ee7ad0a33c5175fe4bcf5c0488d85c42924c9f66caaa4b7cb5c3c486ce6c1e4f736f27c42c10810ea7e52b86ca09826317c1f4e791ffa7f970d753bde5b1d8890e2110aae3e960ae47bb62b05c7dce68304d4478e444d0b0021a16dc5c09e560d108b55f9a83fe4ca4263c25bfd1ba7a8cac88314099149e8b8a3302525ad21e6e171c4857023c0d22425e956613687fb84caf0e1085f04a5dcebd05aa14149bc9000f40ae7d0a979eac196b3ea77cc1e900472d196d9dc10322a43a4b63824b1a73cfcef9544ad41a9f541500cdd601ccdcb55239616fe2cf20805af10064c9a2c103eab785fb5afcaa0288287402fb8881a11ce68d4acd689fc170f0dd4df4605deb214bf82b78db0c5dab8a95077a0c43e074b61820de2d5b9a3d319331124705fb27d4dcb192e0403cc241667f512595d84bd36f1fffa60f0455f9ac022e3402552c38da214794ab8f1f925952569403a2769c7dcc4290de6d76a71702b2d5b8c26662793abadf79337f21efd7293cb1d57f27c43e1643278f7014493a6eadebec9eadca9c8c8337e69fa88b81601253b10fad222b24f717d93155181b51cca11ba3a945fb686b5e81fd95feb5aae1d18036c9d58c781f997df3afd81d4c32b8fd02498cbaaf172d0ee81b76bd4d4e8d6f2edfdabf747de81b5f0a0ee42841b7f50dd2e6ca5f682e69211372f3bd5ed3101ad0c3415cf89f4fa0b43f7049528721df18c30e6bee31e41b7dbd12ab574ed3128f7bf85a1e0603cc1611690fa946e93cd34c0464626e8f1875a506b2264317cb3a1d54fbadbd5b0b2117bb166dacf872c6f910da40765a58474ec680cd3a095990db68c06cce2be4490b31c7c2e5c63a1a61a95f9a026ffed3669fd2ff1cd5b14cd2c97b97c05d12208576bbb3aaab596342dd5653ba3892f73943305d99ed76676ab49765defd56c6444a20d36059d73a3467917a7462baaf8c7f5864bcc84a436553d58061691eb013920b0ff338f4af469f67cd8fc77dc77b15a3cc7abf038185113104ba82059b8b47076ee02b7c3a8a02af80e0917107c765d0a9a602cb280d28b8a1f1e37e678b1d6d1dffd1347b2433322eb500ac5c669a3f595cefd6e21c7fb2cec274ae8e60854636543912d940011857b03cb3c9e40071656d41a7ffa2b2c27ba5e45e73e406acb1722fd0611a45d56117ab5793c0b41d7b8e0cf58a768ba160db3ae9670ad342aac065a4e48b12a8648c3b2b0c52498e3aeff2091cb30f630f9f360f533113f92ddc8d77f4c7184a3950b9960661865dc046af7fd502e451a2c1ef5d02ee69f95a2810789004dd525e386936d41afd48aefc038aad78adb8fd03b3b28580a296c543deb10f79af3a1cb06670df1cd083434d9e1baaa7105aa1b1d3c737064b21ba962fbdea89fbb4af8d4d1ca8045700b6411cda7b616d1b7a5269eea20001de27a1d306c87eeef553e34df3cd071d078ea81ef12f9b34ada1905a9bef9e589e60554abb265bb1315d20c238760207929536f6e2ba2769cba4c786d75f9f3475e1b14ea60bb0ff131d7599c205b8dbfd92acb7325ccc4b069d0563f30ab50c54812c66f0a7b0eb7555c3105677d10c2d6fa795b06c9a2b6e73c23be86dbb3ba01fa702162eaeb905cba71a18041a138899b7efff68b82245aa071c00a3f2af2cf5a4f01fafb2a3b6ae0202394cf177e37d1c739a6998d2d3ec9e60706782ff3ff22d4de1f2133e0b22c6c04eb6085217a07002426f234f7207ca3bb5afcb0cfd66c61c8770aa7ccc0608c53c43e753cb300cbe0d3a1c2319b96fb9c510afea4040e9285c320bab877d9d0af1580c3498e6a16fb58566dbe542cd0fa7d945d8194518520194d2f26278ba18b76b31a4a74088c9c3c35060c85d9007a4707b6ee0bed053c580d2efcf5911213e2300b0b510058f2d040c9ddc2ce13f8e26063b40f862245ad3920a320fa5012ae625435b878fe65e367265e5e35bee89b3f612ba3fa1465a463c141c99e6da0250c96a9c2ff6ea8871bcdb4ae49448a0f033d9ed696bf24981cf9efe568edfda34912c0e3ffa3df8fffda3b699910c4d5c183d98d05bd8129e1f3d1e0fe7fc0d5c813375dcd1b51e0f4f8ef2ce5234a35051cc4c0c93ee922e7645c121ac28e2c7728129633860f383211aeb1c8311f3b9633dc0e506ec87ab243dc6acc4f05ed9f2da9423f54791deb92ee12e698f3857b4b0f7afb5e33307655cee87cf1c5757db9c25cce8c40aa0a45331790844606dc4d40a696465c4bf79c7d10dcab3f7b8425cf62826480cf5e108686b6f85d1f626e12a8107026d1d48d56b2407b22b34d4807efe83e83782bc1468dd24ca44f1aaa2856140929b19a24885d06161de4802df2f01c2f932fe726068cbf3dad0baf78b193bd59c0923acc2590b53ae4f915fc0a22d3657d085139dd3d52c45feb687c9a03392cf530bf92095889bc942763396398baf7a754b0e2539a16db4cc63adcf983900d2f5cf077192ea85ce7c3f94b202f32648055b102a69b500501ba4cf025ba411714cfe7fda756d812543b31f7920efd20968bc0911faa7c23a24ad8ee628eeee220337093e246d31362a87d746bdadba15ea2625f769d93753775056fa3cbdd5bc36b1d4198e8984b67a31d8727720d3f1351916ec303c58efe0a0e0bf235296b3c8fda15d69f8270263d26de3ce55556cb61a3c2829c4241695c6874c0e6700334c567df1a25fd379579364e3d563ce9375ea227f13f027e6332152580f80a6dcdce6bc34e17331ad311e9d76f43a1dd64e1bf8402b6066e5f9bc2ff61cc4e27e1469e01f9c3cba70112ee9a4fbaf73a47445e9913963d3c6846c16d3307af07dfb56d9d416324d3e933bc4644b67a61d4a1e4e9dc3d66a002207672bc3b66b8cdcb0e09af3d3b97ca754019f934b61541cbe73d7c109f3f9535cb97a5f75d5c086fc2b4ea0cbcea4bd2284b609d4a5718201e069000ddcec080ca97f8f7fee1dbd005cc8527250d8a4bc1179ac1d74aac425093c162aff0f22605059b7994783f3232f4dd96c5bb1fb3fd522d2da87bc2a28d94e5ae2ddb2a6c6004f2a51dd7c0c3e79640de48147ef7a0f70c3272916d86e3939c8d83e88328bd11127d56b487089a977093b4e2b676cad27f44dc3f4d28139a4d6d81f5a91342974a1ae1b8634396d64c634708e28e48d39df050ec23d228cdb2d45ba753eae3f81b3282838d9c1ebea26a5d07deaf56f2fdef6d014b4d7621d7c2797c1532378df8d1815ef922536e52b1305979a9a64bd3544a486f45c39afe07a8d4201407dc16d2407cc31b247babe960952c56986ee75c5c1ba142facd46615372e9e88a360f0165fbe01e8ea572300c86cbf3e8fd1499d999163cd8f620e21433a520b80fd80e1557214b7a644f09f897091a362adaba63c5071896bebd27e1c9268f425239540699e6807a2c23136c082aafc4c29502628f4bfdf396e852a62522538c0780d812d3fcff8991528c5ecc10800607df981879205463d8e9e2bcd776c3db3ea0bbfae2b431f324fa3d1636b51e554f219273ece699f8f8088bd9757390e4dcf481fd97414486aecc9ced42c6db6c2d68303366e8d51194e7c443f5a8d62783c4b7b21db259b9b52b777db591cca8e2bab424ef7abea063244517d78ac424b1466e8cabacdae2d665388a6f811e69abd342e1e9c55516ffb7cc5924670db1c26c9932a7316a88a4b515fd8e2ffbc378d2465811f892c80d743e5c6206b1c0c5b6cc23f0bc020d695d64582781fec69c308f352e89d3fc132cf19f0951766d7875d656172dfded480a15532c3c5c741836c39f99ab258fc55774a35042a3dc04b5c1d89fda1f0da289f1296ed453795248dd9542bb27281048bcd6aa8f192f41bb39c9ed3fcfcb65a3c28b4f09ea79940efb07de19203573248c986c7746c95a1574a9eec60078c0f6dbe5a4b7611390671d38d5f3181facbe02a09e7a3f2bf1c276aa60be6d1fba3124c272ca8c67701db7168dfe3f3f5f7faca407b43cfdca7d442b390eb595404e51726c8733da3fe70154f7a671bfa23d03c286b8aba37efb31977c4d3a4d6405463e2b504a896cfd76ba0f754f3e801bfe5a18633422fd50ba93c24302eda7f820584210c54ee037d37db88b24cc733511d1711e5530b02101f3fe70cc297d1f2977103e3cc33f7f50c7b830bfd2e485d5645ef17fa1e98d5dd430a7c3fcab0f546238c6c6003c2c48af161ceab17973e96f58e256782d8deee55172021c039455d71af78f6f4a9b93e73d8e665b94e993710bb710854c20aebdd021e6964d1909a875df30fc3755fa9b61e29443157998c09c1fa8546cf1202d8c01520d3e9a63a1c538de76203d87ad2f673fe4d0ad34d90d04fe7d4ccb14759e339d1e886cbe9c59c05f73c478dc5d6d05d822fd26e9b137b42a97756507811d77b89daebf9b18e7c6bcf0e0f08e1c4152bbe7860af7515db364fc86436f315ec87215318ad64aa9751d0ed9286bb5a9f1ba25b42cfdc8d62a58655d82f200e27269f6a43c8eed9a7483e24ab1c62b45ca509e9cb0b0f84819cd8c7556ed2b8ec83faaac3949d56c3a2a197c9f53970f2c6c37af0272c8839b2017316b4d38ace2151e9f3f47893dee1c6d61c31d24449c1bbe9a5d667f0f70ac9159b9171bf2e221524b470c24ea40bc16341e0fc172b6d3172488ff911e9b5875a0b2626029b8419d76aca1031f60e323054b5eb0e0c350642731f88030ad1faf64a6a4076f1f40e9ced772881da70437f16168fa5c3fe4c36cb3245a04e56b0d195c6b8760308052cf8931f62fe34ff28210bb876abad9210731bcb1e40f6e126a82ef504461f14788de7870662695b53b2b0f75b58e7c20f6ffdc1fe66e78fcbf6390f5c76d10b89b7fff00d43cc1e0ca9167c82522cb7a5e1c3b0b052235d5e96fc6c87f58310fd0873bd2e551b8a5e198cb2a27600f5057b94a474fda69a6dd8f10837b6ba578f561e94f135aa25d0b508a58bf7afd30cfdbdfa5544192f6c7adc0055db1bbc95499e227fd40b1ce63c443fa438ea2b72d7ba454c6f6120de5f48a79049f4a4426c5253981a4e0d382a4a965d3d0fb769ef5a5d6d3d6bdd28577a3499ae518c3f3dcfafb4ae3b2011dfda41d042bdc10b643f1b231d11659e6d8cc8ac395bcd948932e81da32772c416ad932f0db8c4ee1aec87cb988c880a31167c56777e7851648a451d7690089a01ae253995c2511792f4adf9ed67b40e60bc179c7b8f2bd51afc0c80f7631628cd6a126fa6c5d1c66d568db8d32f7f6e39da066f5c62b9c49389d1c9ce6a70c6a41293dafeb7d726cf24bf0d9240b0231d628690802d50238fb5d01a1958150c601a9821fcce1c9aa2593fc3f5ec53ec007c1cf1c7bf2fee13bf71a34e04a4ded34dee000cdcc9f7b51166e4a9a640c97ebd2d4b287525fc226a5e1959851825639227f7948b6e1cf3cdbea9398373f86c8cae16429426c462331cbbef3a338a57375479af28b6078e1aea62909b4dc30fc2bbc50843dec6f7f28942283bce03c0ea1e7992ee34982e713d0c6b11ffd5e5ca23296f27e97ad7714c8fa414dd3bae9c205fab2d077e6349da1e40f620ac725f145565b231df862fc9405c58b2d507a2b699935287b860ec7da0150b3bb93092925c232729ccc1251a0737b6a272b82a21a65cdee1f15974490e8eb826a6a9b57f0940895824659a0fd44fe73be6101b7ca86aa235dd3984a65b72cdb6d801499f1f4e14fbeb22827f4eaaa5327e2af6d472faf5ebd9c9d672d221c251d89fe619951cded6cec9788680e5ea9b617f5e667670adc80ebc230f4bb9b1aa1e26a73fa787c3699b244dffc88053cae09c51622d0954d96ca725a7f1f196d7e7c5af4da93afb134c6336dc4d471fe287701d580986d5e2f9e7ab6413380dba9aaa6b469e4f86bc82affec94353ef1344244873851ef8ff96aa537a6cda05c3f9dc0faadd387c0dfe1c07fc775a0f32dde5c4bdbec0c6e454a172de29f596ca138aa27f77549b24a193707289be392fb54524394f158abfccbf0920ae379963689ef1a3819932ece9c585de74d697bf0b5757cce238c27f5aa7c015500fc27b751339eac4655158f8029a87ee2dd524fb7cf48371d437d7507a664e835ea064c0183bf90ed0d504f11952aeb149d4405f6bb08594b491c4b891adc52251c800a6631b2f458bd3e2fffb06ad5b7ab5739deeaf65f9ca59d8fe8a1d5ce5c62a378036d148ccea23351231951cbb37e52f153997274782f33a1bff0120698706e508348484cd6ade31e378ee644040cf4b1e94a062cd992696a782938ac494395e597356e521cdee2aefe7b2915e2168411d38dd3ac38c72f4aec8651b5faa50c5d0ea5417b75fc5a042a38c5b3306c7ca817f50fadf12602d0cc1b904e747fe73ee15ca4f31d0ab20911ee0fbd66c972844050aadb1ed586fb23b6beeaeb80353f31dbe00c9f654189568ab15beb542b692d4c60d17a8c01b1a4df9440e41abcd118d3c27b627b78192eb976effc09f3f911fd4d55c4e0296fdd250d4dde80ded3991d61704414efc5de9a403852b6c4c42c6f015c8e75a6fdf09bc45070e70d189d42eda5b20aa431a3dd036e894e60523c20091c0696aa367fde0fe6e8011381c49b84a0a050c3c200f997b00248f1ee8dbb7c26d7c0a0928128f3aa103d40d548bb5bddd4b873a1a799e942d4e4d4fe9080804574149f75ec757915984aa798b75522da221fff0e37269123ced35d12b78ca6782db74e630458df7f4942fa7b910ebacb38ab4f45b572cb43322d9305d409c737b6929d0cd6fc84469134c3f432dc1f420e092a2b1e613a948f502a5165f781d7cb447d97c82a9ef0a94e57d827e051ead65655265a167b8eb4ba198fa2372913af11f12b88db454dee48893c4be33b40347ad01a57e2b2345dd483e1871a34e6c57d36af4b4dd15651891bfb71450902334c1fcf33e97c749e07cde87cd8adfe233f02b5ca7cf9746660fce1b5c0f09653979fec34b3bdbb86e56df7663cceb82c65b75bc31233df99d32ab520f4ac9154a587ea42f7fadc824479061fc095476e384c73722962c88c394968af26b1189abf3724bc4bfa296f4245741f68ecb71ec5325171fcaf44cb1fff56ba063234ad465741a2a11e6e5ea1818898bdb7d37517f6f16da61623641a4e26bd1d5588ab6a9c6129d5ca3a4259b943d295427dfa0b9baf551f6a42618c906118511675b49378daedf12abd77de1975a091e6a8ce98a170a3205b749710175d879859b457ec988bd89f2100eed0a9c02e95a0ce7bea68d5a18dc223b08d0fcbdc4eea3438e9cb310f72464992be3f5fd45ec6b3cbcc3a282cb0455f91d6e350169ea9045aae6e0b8c5dc190511845507f105caecd0092e6430c512dcdad69d622a6af8373511dc027a65af7e8f3d3f52f6ed97416f8717938837aad82dc000b797f739bdbfefc1e0c740a49b2e53df5339af86aba1bf116d34094ee24db37a0cb16eb06f6edbd451c7a5122d1688702a56c18352d5ea017838d9e8df9f33d8e51e9c80e7cd84253991de7f31b5990e44c210199b5066ec89b61d12af912333a253f76615b7eb899b29c8df7b591740f7c9162b20038a6342796fe99a66ec397519e602f352dad809548bb3a70403101c069c3cce76b40a202af446ef9145de16e0d33c646e9e36258f9a4ffdde85c3155603e59c6a07296a3b93e0003e552f96a6734f6e42742cf55cc1d425ca2de539ec2c4c9c7e123a77e40791534e0697e3d4482716dbb5963a051ee7e6e381d443ef62e132092387350e3cff79c22e028cd4dbd70b150cceaa2cf7449caa20c679576d15135eb22bed8a36f893c6c1848d96b89fada8850c29640b639fe6368975bfcf863c5d27b59422b181ab0ac18e04c57a1bdb2a98a9653d16f6e651853137c7a1b546088cf06530e1f0e17c0fa75bcb8f2f4ab6c29fc3dd81e5dea0a4492573e6c0a29f8c090ee7cb10eee41c28c7f79dfac954d95b8e7ba9302d7fa57f2698b0a6c496c77b483767e423778200c2fbb5615ea53b751e20daaf9964bd37bc787f61374cc20dd36482840401de24097d9610e2cebc2273eb99c866134a25ad804b24152d751a8596914c2c01c5dd76bd388121d2171205614445f8166625ff79ed11b425bb4f50de399f3fbc3011c78da96439c0a85db5ead0dbc568fad5763c127c3be6b2a8c2f0ca463acb8969fe8480f289acac064b8ce5c024abe6abe476391f258a051486d35ca14ed4988a94ad0285dfb60772d62a2611a811fd30002cc86a296752d1dbb7bb4c6a88cdd9a5c90e99d02d6cbfc97c64dbcba749028e38fa7fc33030f7f6e21ae7e680600cf4b2a765fcc4b740ab6229776e1561eaf196adb281bedc3f8d10efd1df336468af4f04438d94987b88993cbdf7f143143dc6636a7efdcc838e65213a1dd11adaaa4fe2810ea161a1d2cc154c3c5c28d8898a7b8b70344edcb82ba762bc9c8b35cde31d785c59a2122860b117b3078339018d3c176b6f07c8a5b2b41fbda86c63a48f74cafc3d0d99819debd46a724e17656abfb21d20355cd0572a5f85612ec6f2b58486c5ba80811a90b9c69ccc90cd754844a53e49a3f507ccd51bd2d8952de78ca474df3543913422312024012c670e880450cb97a18033a464d5356d57d2f51f2bfcda01e5368d8db7c89916c773d4341f75c51a447d420089b5e6d23bd5eff3f439e7471418c0d8b68deedaded2d4ba2dda0d0c995856196d7766ac0a1473f5cfd9ef411ae7ddffe3fb2e76633c5d17d9eef36a420a236e6ab7159dc573b5156b91d4ac6687978703fe02861ab9b808f7aac5c5bbdb137e334e4a046f370c4ff51088ace0bac5c232a250bdd29ac26e8d7db9fa65f93a12203996726986cd1c0a1458aa42b16e43ac1321a4a31a3964e5e0486aace2bdf936f2bda43402b080b083eb1200b0894a64820c37b312138815e59abd319d121456276f22973290f406c61c489fa920d75dc084cfd5c1aaf7660f238f0329f8132369431b5e48eb67c612a3e336cec069afd52994048045ac69c7065c410d6278171e99e096a04e2bd23213532b970656c5a06b75906b73b52f51c277d5d63e70c7a2e8ecaf58c89ddaeaad68e40855ddf76e04d3f1edbc88e4093d84b3cd0fe67e88b983fe444bbcd88ccef64c2930e1b7aaa5be2cc90122816d0cbf48f0fae630ff71d621fda69d62042e006ad96a3bbd0588a19e65d1c8712ac8b587909209bbf5f009fbcd2e0935628a4e999635aa1deac96b4abf7272905cca58102d8aa9a8f80943d735ac52faf6b816aa35e868306b9d1fa2b56249fd644a23f49c73f10cd6f089bffaa859ebd3a1694b8b21cb5b0ae9f9adc17c23db222d00e04afeb2b980db309fa90700bea810a590d23f809b03eff7d30962bda5fc942057595f79e2879df7eba0df55ca77453e84a7115b1dc9427e9c6dcf20c99dec66e6cc34962dfb81a60498a40b84aa7b3cc04b973cd63b323ed1a16121d826c572db5bf4e7cd8a8dc5748741eda69685280d8c3c416cc87a983181a29a292b201e32f40ac3aa6d035c82543e2955ba01d0f1cd355b3035a18b72bcaa9a3ef6544de4a3729542ab11aa9590ff1d2f1895159cd3d46c008c608b0c940abc6f6492ae342c7e8c19072e896e93516d749b646de09cc355385753472a71310e4e5627d4bcd9455855c3ce353cc0efeefc5f318af3f731d0d26f7dfa9f308f0fa942c003c2fa7217dde59b746926d44e33031d1ecff9574d0b9e7f2e13537b0d167e903fd5dbe050e1da40618e7382a709666bff057b39b5373a96c1d6aff5a10546234cf6eb08289cbe8606cf75eb41eeca09184bbbbe27c334ee08f0401505812346546cb03b08fb6affb5378624228be5211f1904987d4c6376b8191e58634fe8294ae97ac9091dbc67018bbe695492668c02dfc01819d98a25e3b26be8c11891250211e19d80764f69c64d241c49a7f5b5700efb0e0218dbeae2ab0d41c6959ec1f7eddafb5c19221e0e57944a892b6580b8de6eda32c49fae0e944e8d7adf8bd841afa058aa9c69b1a44988ca0aa1f2e2a4804334c581c96274917e99f3098ec0cc8ec29ab4709aac9ea68a7e9a5cace3f1725010ff310979cb3cbfd06e3de92119c9f3831fae082e3879909c50c02c71dfb2e83233e1b6f43c0cadb38f62cee202963846ceaf67fb202cb1e9674b19abb2ee12a57e757bd8707f150350b4a52988de0ff06ecbd83561cac68454511ee69cad9b752aaa851cd63787db35e6ea54122436a4c3564c2058640dafdb67a0202c522dc68d26233e1f0702e8150cf955c7fc1557cc1e90fe3bc52a5750d85ca24f9f83a0576994a75a300aec370eb29877b107c8e656df2e7b990534b0c1292b3c4f5037f08d9a7e265fabb8c0296534b59b1b364f8e6203173d67ac9805d1011661750192f3907cd633db59a5673125d4f7c323590187c9b0e0f043a307e83fb9b22722334912263c16177a9bb3dcdedfed2bcdf53c5d4c32c8522d75f76d74208fac5f80259d1300bb2730c86b93a029db926ea0f0ce83f45347923ba25ff2727ae66971c9c2941ad5dc4025428db6afc1e7b72d7befcc6db16976584a2c66ae1ad676f6245334bf4712074155800dc048cd340c0dfdce0585128d1d53e0fae1d68229c6d70542413b1f4e5a4b9815be942c537ebf901d98158dc970a00ef63e77de541172f7da53678bda02c0aecf2c121a40bb9a91bde2e84442177e397264971689c0240adbdeb4e83aa18eb0b9cf6b3986c8a39865e6949231710c6e720cd05a5d7dcba28e2ed5f934069ee0b70bbdde8c7fce7d2ea26825bd40b5b3a04d3b62c8708898637e613a22e4e351377c95e0851ea25d85b9276850852e80b2c69ace512cd2463493a0eb80b91f2532cbfd3f910c1b2357a468dba2e7dac6414ce295f36b5bce993ea757d450f78950c1040ae921e1838a881fa99ddb27b8de1647364cb323cc77febac0c4d9d400313027c21d205b02820e85a0942e9e4047d65b9597dc26e14b95e3ea1586740e113e218772e28c21cb8042bb68fad17caa1536f8c7f54d816a02ece6e7b0bd09d1c487f32e55d7c200e0d036b473f45ace576a1de4007b639f3fe2d7e8d09e63e6c04a0bb682cb80ca0918b71ff16ae4e94bd4b2aa600975ba444477c55798d321a177506d5861c9617458a73d153b67857c541f84aafe698cced7e09c6600205f03ee14646461c63527d70843c690844eb7178b591122f849cf1a5fec5bc0f07275d5d102a440e5912f2f75b8ac5c11e65328970e9fd410e55cbf4ee0850daa696581b943869be35e431a472951d7c145b5d6df832c61e5f1fb95428764f2f1f1b13582570f19f7f16b1c275a33a04b370ff5e202e7755483fa0db6bc41b142a431a7ce87cd09d41154022c7e36581e3cdcfb81cc9c20aa2f6a6e362c766f4aead5719f2c3fa95ef972bd1fe7a500acce6c360455cc1535692a8d34f030aabd67b52ce855d67e3457b2089e8d12f3468c05403f414f580b41a0e302c1b8894a695b939564858c5c7b7b7425e1f8eab981acd58be6d2094cc98668ceba21168e6b6bc94ff870de594f041490ac3cc09e5fc80c818c95563361e5fc42656ec689cf182e15e4ce3fd8dee70c89afde7c072f5dce544652145e04c2c9f1e31c02299390224b68c4b44c3a1bb5342cb491900d0983b70594c132176b9dcaa69271799715a01ccfd72b9e058d9c991578fa81aa50f541a55db386a327fa6af400548ce9c2fbf495b9ba520b5df6b4fcb5369862a0d4f43464379c3fad7a6802f75782c5bcc9863c5354536f0a4c090951511415cb22d7d20e8152576efd513260582c2a1d8754d61515fd25b0d4e9ed72380b9e2683e62a3a92c5efe570b8995fcc9d620c46f2c1578f3c7bb5ca4805b3fb7984e87ebd06062b5b5a68fa3ab60a0dae27c1b5851e337d0f9e01a1f2d2eee0d74e092ab282bd7ebfe2bdbf0d419a8e61c615fb8a819ec759d4c0d114f17306584c9ef46b16f7761a1f0ad8973714897e3ff8632595af32aa4839d6d7901e103a5f1ea6a5153602d2d416128e927fd978eec93a40d438e5bf6bfd535dd8a13673f5b880a9f5ca5734526a4118b2b53fe96f8779ee452b36d3b98b08cddc18e2ff0fa1366003ea20ad894b4bfc2d6d3c73f7d4ecf32850085c4b6a0d97e17ec7e2fbe12269bb3de3d8c8d0d135de8e9f97a5ba007f91399e1b30457beb9e1ed01d2c9dd9903ca645f022d28b1c29c4c80bf65b404c16531f3ef30cf5297c8cc81e1907bbf29c463fbd4b997fce4a5c21aea9c78e732ec67c3f551734bcd1388ddf7a5a7bb1c10878359805e605fb4fa3bb28aac12ebf267927fa7e776656d325f74ba29da5c2bf3e97413234efabcdb51d309c362bae4cb685612ba04ee50e7e9fac94df9445490117765325d9d9cc2536f9576f79e0b607495e3e5a75285a0adee504b1a78e65edca0862f2852d1fafa4888d098df513802120c26800c93d2d729a0722ac8b1d43bbdc9c61b8b0d61551c6b3ba6d9c76844f1da1399d459cad53f660a5b08f37bd7b5c60f60a85597d7f9bca4a7928ffe83e1faed5b40776eb974403f42477c91c664ab12a5b8625cd0605719f1cc82b9d18a2f100b279901ab9f66eca211f23d9c51155bb0d67bf434fb9a5e52bdb13c148a4b4f5068124bbb1fe18d3efb69612cc1b021d7e7859da69f8af25084406f289bee11e19bce8fcda2beaa94e02b552dc890cbd8068f04d6d759d916c1048bdef77a5fc3f3c1df687a8592b0246f0b476c820d7a01546fe5a2f0fe1d450eb551a492b65eba8840174351856bc4b4b1af8062263f8685cb81ecfcf3adc661ca2f34dc6089d3d173092c634266b9df1a8650e8912545984129363f4db3caebdc130a758209dc38777ad5e759d4039ac2e68a3149b1fedf082deb1b436284a6c557a6ea1b0a3ac7a10206e4d477efeccbfc3004ae888dc3eaff9ee62b8248c68e66b66701c0da40151b2c41fb02b3a19dd0c40b30199bb13db63e566fd6af3e3812f469ed23341e3c0972cc6e1ac0868ce0043cee79f89922b14d4b9d40a7b4c5ce184f5850d4a91de0e6b0497598062604245d60b27a37a27eb37faf6e801a04e89b12b080f74925705cc9107f29085bae3a8c5d368ac4e1a76bffd6169eb1f314100acfc4923303f72a1425e9643ffba82c3da63b90ed822eb405711f21ae1915f8816051ea837bd335bc10c6a3aee24e0fa4c1323cbfee3062e1b00516f60e50ea2758f725fef3a27ad16fbf95d7958cdc20b5e81a44aec8935f4d17116ab8f59a24c74a55746075848b991017651d3d1a6b9e6185e591c0bc206856988f2f522d132cf7428c2b45b678aaa38ca5d2e99a80303b95381b8d51450ee7d40c4f18cf6428a07aebaf22533ff86f8c43c192df3e659320c71826e4060e945c449d008113db777a856e9c89050adc8a96765a74fb13ff8853936d1d60d98d764d2d07c0dab6f795719c8283d048424295effe0711e12214489a970351b55644541beffaefc7da8c1a86fdde7deb735ca5fe3123ee03034be9bccd4ff3df460a9e8f31be0dfb49116a5c3dde10d9c955479994d3fbbdf7051aa94da6ab5c7391dcfd2903cdb350e40a2bde5710bf582eeef32128e3dbedd2b20204bccfdf0b57754169b31d72825dcfe0493f17206e6b06103c3091bcf693e0868183eb34f80f00763e06f04e2e60abf92f5f8103e288ab431266ec594e0d80c68dba450c6ecbdf7a0a84d4dcbb9bc5b21866364e0cbb6426993cfe5dc03a5e61a6d62805d8c2d8cc44f04b4e07fe2b97f0f608bf43d47b1678e0ba9f5095e5340d492a795a0d9de9c398a79a9caf105763ad6f0c56d492989fa088729fc1d62b2a31070f3a3e7c7926761884194ef95076370ec4ed8bb2abe0fffd4d1e8fdc7bbff8a912e552d42e44e91bc82fdf8878098f5eaf1bdd0d8e3f4684e13a778d0c5fc33ed7f048ca2f9a82e9460767949f6c0ee7fef146590ecc664b28e28c21e309a0b004974d44447fd1ff477ed9403e08f27864e4d354aafe3bd8152a89610276fb71342a507220493e94da9266d2e0ee186e0a492695111dd17793594b90709daecf592826fa480300293785fab87ad630c430163dd2871eeb1ca218d6d84d52d58e8ddd4a6d510444b90db32b562d4a5e76a84c281630cd80a3c41468757100ddde4d28bbcf1282038984171203c268c697741218ba0bcabdcd5f82fd377a1eac1e09f9524ff0d72a8d43e5265767cb79ee7b25946abde2ce090bd38f907ab823cbb3ae3255e9c1bd27c8f4173cfcd6ce1136e908828d1199cd6553dcbaa45cdbbddfae2ae13270a5e15b11dcfd28c9f040b76e1d189879138b807a116b00abbd1850f56db94a9b5cdfa1c294ac24811992e510c463a31d8dba010494d8b77700b186677e94fae402bb9f69ce396320c1412f65641314b73280580872468d9671b0c546ddb8b585ff76210e0e028a98132a098d1127b4bfd7b3488a129bf3111144fe1ad63e085f9e63c6b6022b35a557a34cbe8f8d82c58d6f015ad29d46d4eb607fcb4bc102e3cc726d153d3c0657d4171dfc39f3ad31962629769fb432aa010e43a5c30b4e71c0d8ba124355c5b2a111280037569a63eac424322c432758f7a007f0962720ecf5915ccfe1c01eaeaa75969ec2fe588e808da49ce8135f7d4c51d58ccf37a9b8538576afe6218bc020731ffbbbfd76160d546f570d58bb2a9131090dd2c31967d66a471c1ff64f939e38dc7b4df8150bf4be18b58721ad96a177f577c3b5eae7a398e30dc8297b476aca74ca8234b076a5afdf339381200b8279e92e98bdb4cf4c0aa48af634ed738210497e6d000eb99cbf1ae704071a6c431c9abc8997c23749070d53fe4fd53838acb06aaaa79aa46af9c564305718235a758add978bc65d315bc0d01e5a2511b4bb03c3715973a4666b9cea3cd9b783e86ac224443eb948c2baec8c99d18300410cc1713b92202ca86f88a2f877128a81abd3b08057c7c25ea57f2a1f8d9bb974ac05c7ab0aa100df66600ffbd3330ce099be1dcc11f846ba69ec08b0c96b6649ad5fd96e11634260ddfccbffc49665abc458943444d0b339c4c445e16e114a3b6ac5c498107ffca4cf541b30c684729c16adaa0dc2460b8aea248bf7e19843503b9fec3bf7f1c6284944f6fc63016e6890f07fe630427eb0cb471f191e238a43f194941738a0d19930e8da9a553d3c681673a832e013911cf85407f0c8dea55c91b47c01179f94cafa55f19480ca240c7b5b1f372b6e405bae9495d32e36b698dc2ecc60353d114f89ccf724414c2d28fe8cc36308a5e6d4116da7f59aed50d38ba103fad4bbdd6f183ebef044732439fe0963305ea5485022c199eb4241ebc6f89dfce44bcae8f927d67ee80467dd20e4ce5955bd51f62dddcb617d399c43ce46621f6e5dd0a94c8c1ad655b532a43bd8cfbfb783eeba32618e662ab00c0b80952688a45423558401a1bf07c8f67ccba199db609c3c1d31db6879fb919e477ed6e940020665062a84ccada77f96af76587e404ef4bf562ffeafc45a14dc8b18a4129dbdde07655c940c27cdbfac313d04e80b032574a434c66bf19f9017e715220ee28f478f748c72190e61638fd5e763b5fef74318115a0d85c9264f6708e002a50fb158144a4cfc23658848771d8fcebc522942405345dfe00f9b6e8c19f387b13470d6ee6907606300300008382d4686ef3de62517c93837f2f60fa9347d211f5b166fe4d7e531c05c57210b88b29e56c1405cd6c9b153e3f1bb5c5703329037b2b254be23223e68746dab50bc1f25ea87020f2d95c818f21b63f386f41c0fb0dd8254155b81dee18cad39426ca90e4a535cb9e76a27a089b2c3ae6cf104e69ab3a99e937f4ae18940efae603b8817676e4d600c46d4e427dccbfc714dd5589f65b645eb9ff71c70f9c0374304ab21d76e386d628081d98f0b3ba608ede102340af0e9b9ef8226a8a72730635b0921a25b3a0578a813cd9db37dfae130e929edbd48b44d6453c29f2bea4c53dc358e8ec9a1fab04808ac103f8cb8fd59aa9992f8c241449b5efd1852f7bf1c9eaa003074815f9bba43fbef249973c30fcd29e5d0de69a4f6b6ec6cc12950ebc85d7ace1d0ce29d7095a3ca01db64cf02123814f82fc5bcd5dec1eb06582886a34249bfca144872ce269aaf50ea4b7e71ece906d7ebafa2a2bf81646f4b66a203e1c8b44f7dc48f2b90f5e7f728b3ae5fb89b6b4bfe90c0d3fac21ce81545abfc3f0d7bbe37e209b71310c9f53bbf4236ca4acc586a8a70341397f12344cc97bcd25f6c3ceee685eb9a35c0fad93837ca52af8ea92d03221df9eed6ef563b23941f87a4fcdca2dbba87a8c2b9cbd05a106cbbca20e16f93d3c26415e84d970bc54ffe830c866ab4549a12c23ff84645817219f91fdc101048256ece05958c0ef86eb38eca2b55a28e397904a0f8e0b9f94d39d49c689367610fed215e50d17a051fc26f14b07743aba98a218a1434f2ef82cbc168d72bd658550cb8c2acd8f3fb02ef70a9367ab085d91a51e8e5c4f2424ab56f0f25382d4c11903956da35da763f89e4da7bf91a9cdfc7a54ba3cda529b7c04ad2bd23410288075ef88b13a9cc07e5c8ff4cdd79d476666c049753515aea4c54fbd2bbf28020b6935e6b3b93a106d310cf407818ef8aa6b31df4d6d190dc20094924513cf488e1610899310ae60cf9946737833a074822250cde9288cbacaba54b3e124c00da42ec163955197ddb58e9375c0907220c93d4113ee729e8d98f6a34ef8c6713609972666b4f84e10c7f575742e1f6f8d641d99524446eba86e9b3e9ccc180ff0ec3cb40c8f2d8ef8e520e180c289d3c4ef298d6f86e257cfecadd1e4638fd72f611339af20bcc7b98b2d71b55a6c2c468412487946907f476278c10500512a6bd8386e0ef261d9b9d3f4010487bc45823b1f36ea63f71a06bb1a772f14a09d9b8c40d250b6b8ebe87d0c7292b8890da226011b96addfd8a75a04621a851d368a0a1879e22436408d11e66e984338db2662e48130ed18ab9670d824c80b189bbb74fe25b90258a03ac816cd00a59566ed2e7149ddd341bed866deb076fa4d0ddc32c0952815a633eada34deda23925d3949eefd2c296d2b2b801d502933445214d79399fc2df95b7d6a311add180500d0eb98a965cdad919edcfb2b456c832560370607c0ea605330a6a25c63a700760279cc1f650df6bc8b7f85776dc6ecdce55b4bc62eeca940663ec638412300d0fea94ca33064cb8f4e022a5fc8ff9b1a71f15227ebfd770a511be21f2aed815b9d27814f88f35cd51a197ee29273714c2ac5ad8f75a898bb44cd8571aab8f69cb2af4db6676db7b2f530e362b1c3bd0fb67caa48cf5df5607e56f78083e7137aa97bd7da13e3824bd3c5e292c81d26f7d1078a29935e05f7503659aa56271c5262391d6c8e2a08fff86c22f6bab3f3c1efebbfe42cebd00433f555e517ed822fdbd34de4240b79b5c2dff9aac290c3857463180f21591ac197e218244125fde54dfe404420bae25f8d781e28c9ea74a8c2f746d428ceb70243577eb03f8321ff9abd41e8e6e7a8ba6b4a3bdee9168d2ccfa499303d53df271a15245f58e0ba28b94377ad046138e287479d9ff58721587043af7c89b03210cc1e8249f3dc5f45cec07861b08d7f8ae5bc094b0a52c2dff86cb1bcce9644477114ee9b257e4446ec63de1b488b155a8bd9955425f6be3699c5d2be7ee10a4ad426d2a693d7e0ffc0e38d2623cab55f28f05c5557c1da59896b38c07f89f141a4336c304cee5c289e9a05581b0ef813fa1cab7026978b74413d261b75f6114aa1d5124e8cea8cc4dacf091128675bad07d6f2b6b55ba182d57cb5eaecec5a39c6479873e0e37587fccb6d07bb0544437e2aa8f2e89a548e87d3329626438df0f8f8becba8e0c41f45a1e4fb5a5444eadab86d8156b6319654cd1feebb1289a09664828afeb4adf9a5839d01c85a238ee5be9a24569d7146f5c5a9678908c3c4941c72b6666e42a3e6f4db434198645b9686ecafe52a100316169ef4fed55e036ccdc099afcf298d73bea505df608abc60225504566aae2b83d2a221de7657579748efccb0a7c70ba4a6d0837cab4d58e46f9a48a07756b53a1a5ea0f7635516b907bb64881c5731e8fff60097fe4335b275e56df9d80d97a7739606a23efe4fa7fb2dcde63ea992acb3491851c1f94bcb67a42ef5f7844d293388b315223cf205409cb9680103af2b223dcded5b2fadbd0d339c75bf63b19042aa77869f1ce4d54932f4e9b7a864a1ad8fe889077cc0c885ab105d6b4ea87eadc70793f21aea5e5418915951d3e7f59783e9a48007b1dd3ef033c6140a6b41ec4c64f715c6343507d05b88110e024350867ce3f6ed080e90e6d7f9a480556a5a70c5d17ae4ffef9011f769c763cb0941087965d3ce4b4cecfa81dc37f6359e4dd370bbebdb1cc895dd53a3b36fec10320f4b16bb39f2204210ab0ed1d5fc01cd489023914de7aca27c8891dd700cf07bd28c9278511f3fc2b9da833aef11cfc46f4b3cfa147b2977b99930c98f359eab14c71b750b8efeef8265c868c0d15d5175e1f77dd22ec47efb08c44930ce860d12497ea7b9ee5b6354be91e6d0cd85ac4110cf0d84e60855c5cf5c3a60bf42c1034209c8508d516a49e360014f62be407adb5165fe7e6d215f9a21ca0f1957a92d3bf40bc6687b37e8b90347d3e854fc3d06146acc42bc6e512bbcc7b90fa3fb627d5e5a70a3048dad8ac721f5f3e11112cbdcee5c1afd6d1a31d0a81c91ac1d6a50eeefb966737e3ba4728275dd0a300573c37a22470f859ff5db3a31ba6fdf2e5522b143ed2283e5e8d29ae429c6b6b81b843118e67509bdb87739b1527c63491df3cd2916c69c5f7e09c7a7e6cca493eea08c77144706ab7e5f3e1aa8525d3cbcf2ee1111ceef895f16818b06901c588cb4f71680c411c0a6e7a811ee6e71b0f5096304e6b2469cb131c4ab174fbfdb82d0d9755612428bdb0f78f85fb7dc4565580a61ab107fd4cc0b9ac381a859a8dac21d182c00efc11d842834289f2c3f487b761447d55fc6732427612a66dcfc6af7321812de5277a3c681f7200016c0574a107f1c133dd68d1ce966ca0a5d99fe1ea1a77e61b0aecccfa1273a46036a1563639926abd89d323eac27de61ce714c9b840849937535767dbc79925dece58c574bf4244707e91aa2fb9f26c01bad21602bdc064682a30e3f5e5a48c978d2c0faccef90cb904fd1e7ff7b13b67adcd221e6fa6ba7aa63d05190598dcc8e0a1b60cf58ba335aeda1d983b6ebedf045d4e77d11c2270ebb158c2655ef7fce3cc45f39c0a83f3d0e4104d0c88b71cc45dc235aabfcc9cfa71c115a9161fa08a8f946c2d205c023740cf063e0041d98a91684f080c5fdb00cf4defd83cf92a813f93ea01e1e91e33d8fc60769c8274b254dca39fbc8c2f2aaea89d0225eecad34d1886bde1d9066959e853474a71ac6fbb44714026c3b5af802c9b977aeb83338d5479c9d7ec01c86bd357d04c80e4eeed0564ede4b2444a99d9121b8a823934c270906b48ba2d1b35e0057ec2608338c70db90b3c77e5548a002d88fca8b68d07136a647de9d2b94a0dd8f2323c60ff2185237ba07efd8d49b4bd809bcd0b22a864ab8a279cef7cbdb22e0ecacd8cddeb6fc8fe24d94f2788d91eae144874a53abca9e1c019351654663f5ecf40e1b256d13a3012fff19af4c119a5d0a3d256c87e05dff323f3d89af38b8b6975abc69d3a5cfd70a78bda5488d353a97bb20805262c3884eec00c098c9472a9c17661c273e05d409c1d7dd569a25d0f8e85859751609e6805a8079169517dbb8cf82671034c8ccdaf73f8107d191a524d23bf0853acc1ebc400305425371bddbc230e35675770b0c5c27e0d59e294db4032b0fac21c83bb971c4a57242b40c14d088f9b0b3f6fd422a951da18b66a38752273df0419a74579e1d18a82bb8d21628ae1dfc1744deef83163062281099fba4840177acb4f68e4bc97c249f4a98c1e778eb63309528785e6ab1bbf9f48f1f155b0fa44a76e764e2b678c4e3282e9d386ee6d5e844981fc0d068ce827e092c66d7016f28260cae6966b6f343a2721489a3113fc9cb5a7b18044a2b3c883c4a076c01cdc6853036d4eec04ad9737bd327a350df1fbda99a86da8c321057903c15f54c82eb040daf29d310666013fc8c473b3242f8643d1fea179e1a3539d4bbbeec7579da5f2d0b4a0057639d682b1cfb7fca089c02b9ff52a68242802b71292926a7c2206572a1903acb4f705704de9f6be532ceac4a4b30014691d0a94c12096d7d4659a86061fb91228c073ea4b0ac2364351573000dd3ae49964dbbd915341d3c548430916af268b05883b15a0cc851bb7e755a0325a0b12fbe7b2c725484e50ee3087ff80c2ab5730b91b5e5e2bea2d2823a40a68745e75d0810cc1a5e9bb5b35c1c13af83ed9a1dd43984659e4acb80bac93f55b2efd6721635a0b3713048288f2a61c5082af585a61c621046c37133df6877d84e79f9d1fac2490de14c798440701c6d41a00ea2996e1288467cf08a7825e88ae82358fe05293ae71f91ab4ec498c3a157c01910a31cc017e27af57f926f1b4a11273342924f7a0d08a48b707560adb1ce9ae81fe0cbca97900b771bb5619a88b133157fb585ebcf264f26e0246a29126c18cb7692456abdfb48c1a102aa54ebfd5ba3ad107faac1bbe07c8ac8c4fd217e29bf142ae7d386cb0ab4e560a9db9bbc25effbcbfb8f35df51ab5e76fb81790176a6b84331800015895b09e8d8caaf5a2fcdfc518a2bf8a31ab50ca30fd6a28ab11f96ffd8a1be471c34613e29ec673cbe802e17373373d5b069f4d8a8531066ce2687f0c32e0056c1c5fdebdf3d163b32da327c74d45f97d1cb31e73596d0f18a3a0622914df5d2716788b3831cdc3bc4459bb9943150ef090bfdd1742ac89b472388cf746ce7c6e6115e31964d4d22849c1e50edc4c42fe91cc4d7f2ef3f0f66898183514e2b07b72b73ef9a63313466878209f0b51901ed12442924d60512bd10562b500965b18e8487c73564df6a393e1ee64099c13b880d3004e31cd1d3bf0043a9d2bc52f6875d7bb22efb00e01bd10256817ee8c7d02935cdfb4925868c2e556ff0a0252c6f80b41e3ae221a845b2e0d07188a6b1f22f533a02f2f13bf2fb06b317577764c40f057808b3138e21f7b430cb79f800f16f899372296268643d6c8aa884beef196ac118b2355181c687341856628a9fbda1222b327c99420912bf62b838599195d1763c1f7be40aec21581be1a12b2d7e267811a8dc4e0cc3242973a15308c24732306a05da8320926255fec276050ae29782f8eb2aa510f1d55d30682edef929e6ccb5d0342f4411187407021b5b11b61a4922ef93e94ad1abda2fe548c4a81b79c3ff4dca1db0984345ee5a064d070d09c51b7a89a423e97e198c75d99d0363112df24cc35c051bd577e3e6f1c4dd0b8d66a5ced9ab0648c8dc6ee700d445c3c3e5f0368168ffcb0a13e21202bfd678a94891c7be25fbc7f8b9645fe645c8e2de4060a0e496f2e1627673064fcef19ce19e313c1fb3384740fe77dd6155804e46fac78b905d906ea28b7771ddfe2cfaba204eb48d65c1c33e2c93830940ae44e5abf50e0c50e67c7b6500dc981f7831cc7d421a9cad4119787c1bee501df5b3e419006a21ab5cfaec44c6b28bf082ac31865784d732ad407974a6b9cb3fc788702400bb233c8250dd636e4cfa559e73dfdff531f7d151aba75b13c93d007702759d4a0d5c7053d3c1f84a46dfeab5f1782e766fcf738eaeb2bce8edee1a08431aa0a2c5743ed412a0d68208398d503d0104080c86bc3cb4901448a1224f9d4a57e49cc5b06a2357ca97f13fc3067a72dbb559af7f347983854a28597e0640619c0faefe4e306aca40c6c836b92aa3935154a7d2387994c9eb371374eaa0f64c651ca76eed4d2683286ec2a6c648e9e4b1f69aa91fac2c083824a1381c583f369b8069c1df44e799f0ea0af8fafadcc2c0804db33a7fcb5e324d55f4271a63d70ba7ad9ddbc59e440316f1ea85ec74e62d1d5a9200d965145f1480d93791ab88bdc71cffb508d587e6636dbd7c447f5416f087196abf41e65823eb988cb9341a9c84549ce4856d4d35545fb1936c8003f2a637751f408daef9dca9bc63121197e57c1133520e770a5c19795d9019c9668a1546f7a318b4ce74a0c49e0f6363ea597e60c77db1c54e20c758c58ca1e30c27a22e4304be0207c5d18d246253521d122c008222248bdae69217f5bed647a6b6df7b43ed3740c8f2cb7d8239e0b0f2fd82253956b92ef29f123b034040c8c841b013f1cd23f3bb0b2e595d5862b560d52fc24342b656393e7fd5ec1220d0b97ace46011d61c31b2cbdc87626858552362dead4bb43feef46d346d8133c72f9f09786356bef5354ae1d1720be9e0e382cccb9215f514d52783d63749d5bcaf56d9287cd287230339627380ea20a0850b5cdc3c4cb413dbfb493f34c827670404e281f5d34b80e1cc129f2e0c99c6f3bcd475a38c10e261d22460f6c68e59c50c328ebc3e069d1bc1860c69d3bc3f7682eae08874ce7f8a7022e130158eb8488c5af85590e35a53dd5fdf54d716e3e7713a331151b25386de025b0eba5362f4b8297d66ad5e6f152e9808c7e921145ec445cc0712379bc324936161c6f5cc4cd0c353c12683aa6a424a502f3d78c42cad6a5f4b7db57d0c364e32b3e8d8cad4d01c6472a33f002257cfd7585af45a41084f932c2dfe8acb5b8822b79861729ee055ba89b96fb025d7a6de8bd9e6297dd89fd206e4fcc209c29ea187d8e496333d2789a8a6dc5e20ad045363805188fd2d43aaaf9aa99d066429916e81e1227977e065a6ae7f3b85ca5069a59dba92d96ab00fd17203a110f5b9892251fa731b8a8494c2818734315e364e8366f66f69170672ed93283a445207fc617244e11ce338ebd22d5d7bbc5b4138e2b9075055f91b5a28741a71c22d857e07865504197f63c5c58d9b4556aa6b742fd0109fef09250c4c4cbd037a2cf9a96dd8f731ac821c863a5130bf5e0f86f498f5d22554bf1552200f753ec72111150b412f80e2f55aacb764a9234525c2410545c445efff46ce2f2fba6d58c3fec874e694563b8350820d4af9fbbe6ba6d14c983b3b6716b8f26cf73457fc576ed54206e8eba3ba6b25b9cecf347d9a06edd2a3dae8ce97035fc246050206568ec815dede61d503cff6e9b7753604cc70bcf80404082eaed037f629d3fbbec371e7a5a077ca0d9b50c9d38ba11bb4ae6f28032af931d3e183e4421c39c91acf01a99d6236755b914b8655d29fb86c0e543569ffa995eefe52d2342bd951147cb1a4bcb4cd4d69d9d080aa7bd07b57e15a0e0ffd8f96dddb49381bd0ed88defc964af041207569e67777a449d6934dbbd359bbc45a4b8d218a8e9e6729fcb26169f74204145ab9e2e67f9ac7569aa9e70471d0c367925e9932c564828a2ea5c91f7aab2415285edd2d224671d34e54961a5b1200a25754824a3fb596b699cf108b538040bf2f00d43e8e158f36ce6a77079cf78978d94735332300a5c663e441ca07c7415f7582d52cc565fe08186c0939a0a53e596b62a424cc454683919280a218f8e21d8fca2e0a0b609bb035413167006be16a1cb9eae2f76893444efe8fa26e0bde54e54cf682a6f91a0d2faf7c4f31d9567972467452d2524982c6706b242d35989285902e7503c14fabe5aa442fef51a200eb495490e6a397dbfc4d594ab7fae388774a3a775a3da383e650521fb5936b40b0beb12c1b87bc088328785b80981f3510da3114697643df3d280fb6608b84ef69a7a5904d489334ef150a74ceae6ee6d704ee2e9baa7f4281fcb16f4bf315774f49ebca369678186912d871e9cd21f8dcf28eed11284eec6be42140e551dd3ec59e9344758468dde9e9ad00caef1f03e4827aec27e46586a51de2d26fc2e17c470ea67463130669f0c6d34224acc32458e2747edb44ed167f33fc2984ae8d0e75019673cce3130e6d4f549055ae941a0c6c464519221f73c728bf376bf0ee4e680da75e910f0f618b0a3c599f425f67acf2c31f6fdb95b38206ff8eab309ef755f3c2c31965131f290fa771851352125e7a795c08159c6dce4894d046aa1b6a2af7c19d8e8431c5ebf29997fcc22b7841d2039e5ea8c01195103574b2800ea16fd15388780eb1bfb2bb052062be6adf61884f043f871f9179681b40f2edfb9ae04d4f09fc1df56daf2a5c651f6c1655666822177b1f6c27b3a2bc5d5bb46476eac65e2be24e6095e162c138b6d46112c54c97c18cddd5069b836aadd18c1112eafc6ba8a044e07fec0b57f67cdcdd9cfa478890ddf61ac7b04c5abb47bb8525cdac4776185a100e74d6e95b92c1e8872adb07a329c9a7442f5ce4895dd1cfede15d6898a54b063d8d87274fe88b3149274b56f75f5f6bf5a6ca9999611bfb2e114742f96c52600b11a4a4491b09f046f5dd3a3e546f39d177f561aa35d884e49af9c0e2edf900849213edba22e252d5767ce0404f8bcc4f6c8d974214efd982463a94e769bc95ca00bdc88a5f62f5257e62f2f5f9f5d2faf8af85073b11a176cadae0c413e57cfdd23803405502679c8ce929c3fa88cdc3e0db896d470480b1cb1b4b47be284049fb79e04ed2d7396e927fd383716a55d6a9a1443fad25ae320a87ae51c06ff44a683636ef354d841ce451b79e8b5e896684c22ac6e54bbe6f73a01c8613cc80d52437bace8c0ff8b7576550ad2043223bf59fa7a000983d56c3a9eaa428b73e498832606a1cb8f3f7fc3825548527004fa224cd934c06a8d82ab3809418f8adaa2892395419acd0338386b6d1f99754625ce03630924dc74575cb37ea3b4151951fa9b6c1d3ae4bf689489fed48e86078b3827d37421ae1d146c4e9569bb0274419b72661c39b43376b9814ca79f2fa7b28ed9e04a3d498529413af3b51373c16d0ce9450d6b74137e12043045b530713d5106fabc45b8767b30c11ec4c51aa224aa6baaebd9950afe32c82ea597765fc020b567f681c7247275e748ef440dcc1c3463105d35b2ff94c83e1a73d2ce7d1fa0246bd20bbe58a97835d2830278bb9406767c80d8db5d849a0fa73d95e06636009b583e7a712e7627a64cfe5866efe2176890413af4637fa870f6340b501b0393a8c5e4a71c4e71f22a594f6eff9c74f26393e865cde5313fcb432bc99f000f1c1bc69b32aaa99c3fe0f1113f83ecd5a65915bc41db9799eb6b1b03d0fad3c6be77919ab232e9b6947d02ca6e3350f57b46f4d0068c0e319de44b7823b5cafc24385408f55a95057109fe411d2d77421af97c490198168677da6e59d8c469ec699bf93040b851a50d8f57923a2b36b25c5024b84f7225fd6a9c4c76f389dca07c64fc1987d8ced0694e106d58ebe39a001e471f1552b831b5f050da9dc19fb44171265e8f0e1696166579104b09bbd4ae41efde8ce8cf49f4f0a987f9120962c6123d25008387c6383b252b2d89435dc002017675f5efc51b486213c6608dc104da9ba66fb31cc044229fe9ac5b3db9efd0de219e511893b408d3798bb57215137641565d5ffd5095841b7a3ba6c4502fcea53910159284c2ff910612f2fdd2802d1441b242a0fab9d74a3fce6137ba649677933de48ab67d9ac2ccd62a31844db8db2016fe6753f2708e37237d8a9beb85c71e2d981327c33823a8d4207df0b0121a4c38badcc72f8f650ad8a3f1c964d61410a553c7fd5350e43063a438adfff5fc929b5e6e1d0215fb11cda94fd962a69645bfb0397f2dfd9c1a2267a56cf6c14234184b7365e5b880c9ee6fbd5f5e300502344afef7ff8add0203ca4c7e021f0901f5b79f2c99745496a16dffaf962d4bfe02aa3b4fbde7af311ada018384652168fea2579738ba3daec9a2a614fc1bc6bf633c5e4b5e9c4c29437885f927690cc55887aff87bfb58dfbe18f087a0d0789d4a454be9c37e733f6a39b1a14ddf0acc8c2d4c1db96b3a42511a01b3ab80dc2c50265493cbeab9534c8fd878902b7846b72cfb4434a63b67bc3ceba0ff42bb8c552572a560c04e9c8b76cbda952e23031faa0c39db5b158833d958451a9a6e320729f0b40c69dac259afac3ecfc852d05dc22c71425d543951a6f592337fa9c4d51b0306ecda6d23c7a6086fb5d96564dc0f717cac82b7679fda27bedb4d79c118f66cf64873e374023a55e29389186a0e1b8f64e5baa7f0894646129fe468ea9e0b39ca15be2343988e5a85344edd1fab58be7d8add79eb726a5d0544c836029d6374dbc85f93636cdd0fe783485e42d708c13344d208a9eb57a0a2bf368f9f1978efb3fd57501e5818debc2d3281d176a029379b0ef90b29adeeda8249654530ab16f489d43a6f8b04fca74d48d42d44752e2206c64e5185b3f8ef31667ab347b0f4908c8e963fe49d5cb246904ec6bdd574d016e0034701acc1c75c86c1c0435b9306473cf8a413794fb46840fa559adf12dcd7c3e09f86b7b17c912afeb705c395eddf457d125bc23d745674d3b7be5ba4ce3b9464b93095ca11bdc6a65e3e3470f2c834caf76ebb588c3fc654af43cfde26a0e0ff79626de3cd93f5f8f3ba5fc462c6a9928914ab0f2ba7ccd50d14d4e567e2e9b4e1e50f60c8151d11f962ec175609bab069b70f93b158618d416064138b4eae630bade7ca82bbbff0f54180b654ccde3528a950eb43bcd0cd30d5bc488fd5123ddb8b5dec0f395d73e67ea618a501f0a3d9a31d04332b92e9af355373c1913dd5a98013cf8f2637beff06462c9c5ccbec42e3237bdd7347374d9b3b16940be20ff8ca6119368087edb207bdcd6b00cd245d9447f9e92e19548e9fcf72ea2a8a6e1ecfce44af6864a9758b5eccae389e33e742f235ca10007ac79942f4cfd1e200320af1c6c6938516268d3823bb20f53b8a0282c6ef2d9a5dc3f0c9926685c3ec93d6a488a6de61b2b57271f7b05a997c20a87b080fdd8c8980c4e600c37845a4db55de43b023e646074816fb68e431660bdb72db70c661cee0888a9db65fe98b8a1d574b7950b5e9e51b24146007a2afb9a1a7c8352a10edd1fed170c93753848c0f70e708c21b552fbd9255ce646b2ea69e1fed9110a015633d987ca8fb6b99fec50402a5dc40d8a349a4800272867b9ae501fe9a94fcec2e7e86a209210d9bc2aab338720f9e28612ba1ecddd5cefb91c7dd5902f24937365028a879e11c17a227b2b38cbc6d2f79794ad52eab5d1a98ef13aaa3e22eab5db0c753e1ed856349e3a07ce6389722be9fb40077ecae38bc3b619617e61450d276646e5879c70c1d9ee90206960e470fe5da9fe925e8adb5672f3a7526665807f031d960c749d6cbc73a0ee040252e87ffaf36703e1bd29e1d540a824631f2418e7ffc8f7dd35c9327d0fe1373d08755ba1f290771fb65ea28bfa1d1ce24551743ea2f5f9e4f2aae934d870afae0dd1273bef0c2d6e85de10d9b59b601d7e3d0b1933de33ae204da73b335c366dc9b5188eeb059f7a5c6eb2228d41903c0859b0ead3d901868274fa4068e3c813d00033741ea73c915dc548822d584e368c0afb9c8fff7d4650ae2c2051dc60ee3eacb4e37afa2d870529cadb159d725835f05dcd2e56e16c2a14855a8ab285d8cc94af527e35605952cb29ed045ce53ce96d3012d2b87cb5dc9c5940688b2ca999417e43f13d350ccf33f13a8c24599a177032b13fb0a9828bef842959b645bb4be9843ce7bacfd24360f686807e329afd84902dcc15c93da620e0216276e80ad7e32891c526510d878fb53da51ef66f25e457e971c56158744e306d30ded17ba8cc9703f94bc2c663ca5456c99988df30cba8a9cee778d8051fa62589b34b0a5bfed80a7ac5e9f8b8067c0676581436a7046a87e95aa70532b8a9e64899a4a1d79d4598b914dad5df0276cbf5a0c0e6bf643dd2fb9ef53ea8e356417cbe71d05b1b81a51ae3ddb78995c1490f492ead7046b19c5fa0ce2c89175d9010c59bf2695a926bcf96ae79d347fbbb8319e9c2adb28752a6b9c1fcadad91d8d95b286b34326808aa6903dbd806fe6e7f1c1e899571b0bb4e22296cfd7412783b127b1c84d762e11ce0ff1d7a75752e198641454cba8d94192cda93586a6988c8ef74d97f6d083ff746376eaeb14ec5a1d6dda6ef4f261a08acc46032a2bf9b970e7aa8f6a6c4d7857d1fd2290477ee669400ed6f746a3e5572b849367d029632653ab6106db9fd2e639531b9e1098218a4f53473e2bb3d165b365b04f09cfcff0ca8b42ad7dbc66e93900b90020d984e76b5260a7658d0826120c8087850a135f7fe5fd8a30b2ae7b8c3d9fbcff4558b267097dc8eba576a2270ce990030638b75b7d462729830b5b57fa46638c6c00d6dcab8381c768a80131ec9b059b39beb66a77973a406c9339b06c4f376df92b49ef6904e741bbd04417a93b388909ab029f1c5db8a19525995b328138b99748ea71456e7a413241b33241d030ac8dd5d5c4014163707b1cd0e9bc5f1b25d7fbb7c3b7ccc80b57226f47da9cd3aa090ce9aed9b97c99f4b96b177130434f5f044b6c3c5a68bca0835bcf0b8df831fbb12c7e6b41f4dc96f61b6636cd2d67b4a5f804ff482464b9b244922654a29bf05cb05c2056384cf83cb4f3f94103246cb4b5d903f84b0582e44878a344992244992d5e52095e2a2bc4ea7d3898ad39f2845013eddcb896047740d85c169fcd3f79c565229a8405788ce7890f1adf0991b0aa3846bf6fa243ae6f35be130df666a2714bf82f37a2b5e892b89a6b1bfe4a7782856f0a753105bc4901fac7be61d03d608a5ba1d90130cc33014eade7befbda11008a6bcde542873280cc3300cebb1d1aaa27d62fed80fe5f90976a821b06359bcf7db7e58adddba17bb376443947da7c5d5c2d9b4f628ccab04d134bbd429ddb44dbb30f6bc1cba3f346ddab4bb5bebeead9b366ddaddadddebcffa4157b0caa7e3b615acf2e938ae082c8a6cbeb24c4921c6b53056f988e83be8de2c5f9cdb40a390f320366299ea609867bfee7eddb59b356a35ab59cd6a5ab679b125d42efd9ae6477d352d13d9bc5cd1ddb4e9fdffd13b2a84ebbaaed369752ff5bc9c413014baaeebba7c34cdd7ce78c576180dc57ea2e9780ff1835df5a0c0758566d14f7ea233a09675cd3753500582601af4e4613860f04070030e5f5ae6b305b5744c0aafe0eb743a9dacfd0f183a6763a6f9add6b71690795afe7c26d3667295b7bee5262c302569134d9224fdd60a0fa6be050c3de33770d3fb81ca0b5306372440cbf400402652355e04920973349fb80933796e3299a6699ae6bd366e4c9527582854ea89142567cf2a8a8a8b8a429521efba2e123c9dd05ff6b9f8d59b0f9a977edbe72821b0d85c847f9120830d5b506e830a19a03df4aa4fa1de7c93d237e99b660875a25028140a55832bad8ef58c45e061be011df33561cbd0ee017bae39d3ec206ce489f59145318e23a9ec1142ea9c929488d47154a94a6e855dacb550f073b57a900b374de747b221af72d2b1dddc60bfe1bad15123d040086b0e1e3a22d034ae23819e711e1ae673d7f9a85a6185518676e27ed241142fc2ebb9ab1fe4018badd27185d7573f198ce3388ee3385e570d1528a59229c584086aa754723a7215e148bc896badf59215c287b8f9f1136ec4061a7a16fb8b8ed263033e680002dbaf827e72afdb0e158197c475a7c6832ac0a107ff93826b16c130003d2a5da552a9542a595b23f4b182529369753b462514ef755d2c2ca15333b78897e4f2b067b25c696a0b1fa92762a75eb2104ff53cb8036aea181e5c3f2f91c254c634454d2693a99e40d44a92e5ebb85bb783cb5ade9ecea853601d554ca1d28131de386d0a3c23145b955facc0627ec9c2c6831d8e500a8ba1971a60f1caf0b2048b311c80d6af069a3d50433b096faeb986fb7da09d84f55bc15361d1eb3e22f067838733c24c099c4307f4491e29a295003f797af0d64b02f2b390b72b14c81b9ddc2852a6e83c89e61ee7799224499224795d35700f1126241126b2bbb3ceb22ccbb24c0a07ba6bc2e17b9b841d8e8cd20f94153e9ee79ea184a29b5ab2acd600411908d10297f375bde0fe8944958a2442d14d36b250c846e0ea50c500080eb836290cdb68e0b1ca5bfe1da41b6e735296d910bd6063ae80715374a4d48ea4b247888e3dd924b66489849fa91d59cdda56f762ec7939836028f494d2cb0bd15014fdf0421e0b13d833cbcb711f98a8cc510e904d896ad4ef420e908da734e2c9329090115594463c58f644e3687f9891bd241adb22ec108b72c933f2f7a8568764c707ed4841375c21e602cae1d9b1b292735cf2ca97b3925b720e4b9651bd3acda1147ace096b761790e6dcf6e9724e0ecf0e973ce3cb99915d3e1a38f728c725d3c026954fcce1f4c901d57da20dc78386f64da0472ea01ecd9872b30cd4061ad6cf0606b8645f0be8078519594dd33444f40c2dcb233a0b7a648950a435605d526849672e130df3f9f244d1636b60c78eb9453aa67e57eb6299acd0eebc35d99114beafd81213987e383f6c18586cf3e6871d473a8ee368473b86f5a654bec5c465cce639cebe8481c57e02e4ad00e28811977dd019f046017bc6403cb8669b5da39a96fd014a53f46819759a8d701f298fb68f86e71e61370f9af77bd22cc0f75e1f3548911162f5125493f07307de65027f7ed087b756268c18b65ae5ce977b2f4bafe15c86e3388ee39274ccbb736e39950e24e2bcc6008d002e947580451f3fa1180a49ce43d770dce751b4cce71b8ea4c1ef3e97a26368a87d5e96b4c440f9ef5d89810b748d972e43c3e5cf16f09a2d7fa6a169b416ab9de01a2e53eab8da0758995d1e1db76929cfeeffae95e3f8abf1d3e273d9e6bb5ce3931d3bfed4f87c3a6ed340b563ee83dc83e30a40d45a315b310b002af08cfdec9b409b66c8b699e301d05371aeab063686b5f6b2172e71e05e620232c4b2e7a74df3ee8e5d1d0e232b39fe23f41bc21a7a156ab889562d485ce9f02af40097452c671983720b9feeea64c0fc13b90e33500ee1e59f58f3f6ddf061be40349c7b98cf5912d8e66be19b45d1a783a11fccb24face177307c7819592982455178896c3c0c58233472411882e3382ee7cf4745c64ade01c8387ac99d5d724bd6998157be729917508f3619a097fc0179cba7e3e35df8cc92678058be1ef28887cbbef21a11b4cc679719f9472f2b36bfad805eb20c900a885f5436caadf4c8c572d957befa924701957000298c4acee7c301c85683114f96731875c7ccf8d1c67d7806b843140f057a84734b969157f2966f68596d2e777b6e9101bab7e5e215efa2c16081d24858ad3c2e832151ce9d8d037444e066078fea590574298c73ff29dd2772b350bc95c9dff01f7a8696a4a6e9c65155852af543dc756ef62cd2abddb19a200ca267e8fbd03768e5618817f40dc2a6f1ec45150d856ed131d46c9a6adaf19a9ac4445b49764c74a6a292784d6de2325d9324e19fa087a84dde888ac52f51533fd22fefada82615559b5cd7a97bc61d46afd174681ace344410f4d4343f6ed1338fe4838ca7919ec60424000441a01452f8f154d69e9aaaa8d1666c4ad3383d62ecf3c7d17fc450972601a24b744c915a83f0082a3c8d271dc6204174580149891105a110405c25741883a800054200319ec6244e2f40d2848d0ba66a661cb78e11bd70aaa083b516afb0788deb0842a967169ec01f09bc0061d82a40c2046038c2e03ab88ceb8c54e772d2785d1876eb652d86a9986853ead4bbbbbb3f4702ee8cfbc3cf0a8f7cd499d6ca82ec89946cb56a619c1287cef4c595d65aff71b390c2a2af2ed18d274ca9b121464bd42d9e26e76a85d918f4f0d0d3c3c3e8299c9e6ef5e0ac56ab9567c3f3562b4ddbc14385094f7cd05a6b075e7c20c1627e5a6b39841449962b2749cc23aa26282524e9799ee7d119aab3e309c93478244a0025144956b4472b27d414249df1d6553eab758d17293c57d4ac2a3ad3de2354499e4ca5195a928eab91349246d2485a95ab7255ae4ad34fd2248f409e48484574828c438a189d8c41c62145ac56abd5494de7399a3facc6d509c6d8349d3a72498ebc7704d8cb28f8ca66a8cea7d0353448cbd0d01d466ff452892c91259205631ae487d2905211a5911c499324c91a42a10c8436e083070d3d42a150284492a927caeb254ae45484f49ef968d7f38f86f9ac7d62163e97826635ab594dd334da1d734ba552e95dc1cab2fbddeef77341462095600123e89a175c4648d35c3d3c55ae3b991052a74898f530cc285f28c153e04678145fc251a46b4631cd9b8186f92c468f934422e517722691346d070f179c4a77777777f7aede1ca5949abc887690144c24f426ed0799fbf943b52ccbb22caf4b8b5ad6b2a2ce28b5274935ab939aaa4c52a9542a954aa572ee546aa351c4094a52a32fe2c4893412c1100b5f60b1969563a10a7cb5b004ae496a595b50026399c6f5ff6421dcd6a2ad90b5907a98cf57fb52a48ff42454288a42b196f553dfe2add042287eaafc944d7d2af5292f371312944ca3ebab9ed37c7d34bad68f8528b85d86e690f3c341f4aba74e0b267c7d622d3b500e38a168f30d34cc58ca06a7b0c32e7767013c8ee3986b78d5fa7d8afb5ec9c37cd674c01555cb0759080277e832b496652dcbb2ac652d65144192e5ca4912f388aa094a094692368796e18ed13e5c75d0198c1f80379017587452c454872ac791cb95640c2d43438004e1cffca030ef425ce603ed76bb9f9bf513310c046088816878ae76c7e7a6af78d4ef668a1b5409b502149193c934dda04c138599a6699aa679af8d1b53860e7ad5cda3c70668e8a6d775b917b829752170a61fcd1887563ce86ab55aad78d47aba529038d01ff61867173dd0a104477eb0d65a104c65daf54e5afeb30603b30985301b1d5c8a7a201f6d1c8805284001c228078866c5c84d9e032a48ce491afe7d3e2f290c0cf7f9690c8c41e1ccf12948be388d72806c4c588dfa5d28401023ee5df80ce47918c268bb3ee0365d7cb5b68f9447da47c39a2c86ad5adb9349a8ce94a73bdb7d9bdfb66ddbb6bcdda6792c14efed981c83f79d7b3d3f315a5a71ba7165813fbb3cc1a2ef34cd969f07fc7da287bfe5a7b67d94480fa639e557f48d2cfa86155e6891c2c165ada67d626bd9d5b0ec6adfaf5ce673876a012d4183bfa24318117eeba4a413cfb2e8e797bfdabe5c6ddfafb45c7e6bcbb9d5e556abdad0228b89f9b39853df2a0974bed9b42ca3f289f77e3e11e3eee33e31b75a1c07d6e898908d9b8ed9c1e3069cfaf9171f4c96144b88c565064b904abd7492f4141c71c4e98b68bef32e84e5092c9fd862884159348bfd84e513fb0cc72c7379cb2fb0e4cf083080ca27e3dcd2322d9fd8397896ccf26d94a394858585858525b3b8cc7099f1c98d9f252443c60aa8c683a18eb121dac183860771721e7427722ae2a907959832be33a2d66aabbd31cd9badffa7c09e6f9ae69fc98366c7d4d4fc0c5a86e6b57833090ad5738305169dc6cdd987606b6cd3b80adc0c30962fe87234b016b4125e1f17e13379f0632c0ec2cfbf45cba85208038b7ebeea513553b106d488f5390163d96607c9086db6f92b963021e2a6693eabd7da0e862bd3c00f7e06b984b7090f839d5074d62545665d4e9e60dfd9d1988096b33c03368388c27c773842e7953dcfbccec3bc83713ae974d2e9a4d349a7934e279d7daef499fdc8e4fb890f8f74b9bb63185823e482c4464130c46303363616134ada41d0dddd6ff0d07bf0114f8e0ffdeb4f131004c15a59250a957a2245c9d9b38aa2e2426b8cbff4b07bf66299a6699af61d0e2c7f56bbcc65b15bee99cacd8cf33a508f34500db31e7da77d8ecaa080b32f14ca26ca35bfd84d09bb37a29f348d4816ba41a15028146adb68183b1b60ac29d87996251d3a9aa63b555452809df4b913bf441be91bb507e572a6046dd206ba59f4f30ec1dd24539c43601d55879f5ace3e1a375aa641811e693466c83ce20c00b0e234d241013aa91110da8339caf2075a4223d9870348619ef6608eb6ac65d1f3c126fac66e6c422ba1c15f3dc10b25241fc10ea7ea4b4c4cd5a952a2a4c7799ed8799ee779de7b73aed06064b15aa723534c52be54e4c717c2627dba4fd77517cbaac0a2b35827d64a7edc7d3eb9eb3e9f87f38ae7173d29fd0cf9e17c92c56ab1582d91889e8e3a4f2ae564b59a8613f2319a46628d45cf9375b2ce2d735974161774c5e4c1a74d5c8687929e22ab7f1485d1314d2a53ca4404f53bf74fceea4c2c16cbc462b1582cd655a38edbaf149165fe2b58e5d371db0a56f9749c870516a909cb70b295560aadeeee6b93650765d9b5f9db319fafc96432994c9a76a2678f55e7b8accd19e833c34d7df4394ef843d163a1891e9f50f44e9c448e1a7ae17b87492c7a5ae81e9d494015de0cbc2d3cd149abf644777787e82a1402c19cdbfd5d6afb1158f4540a0473f6ae86e323cd5d9645279908d08d1e0b23984b8c48b14003dc581c0109967b7a1eb4f91b7d39b67d46ba8fcb9a566d1c908d38fbbcc44ce025f0767531d40bac7181dfc5d00fd21c4225a1b761437ed5cf895d951281205523b50245adb56bfb05fab073dc0812518c2320da1045463c9e37202ea8afcb36713a91669323aa22292eca9e7b3a7912272fc36ac7dd8ed3a8f0b8ae0b39bf3714047a825fd0a61c271dfcf9860ff866b7375eb361b96e9f13d1beee98eb52b400bb0ccb1758ee220446084ae8c6bca75396ed18adb5d65a8b596b2db6c1808a2a701676a1e88516eb70703178775805d8731294babf2021438c9aa6691a160aa5f22766cffb7080bb58a5a0ca543e1df7659fdb5d16168c3d2f6710bcda6adb6a846c885eb0710087459bedde2d9ceeacd2dddd38c0526ec011515102a8e85bd7759f8822c5eade7bfb2f765d1fe63baff3c511a81110059cb45062b4b9d0e2240fd2329f7750e94174538ecbbc7773c4eedbb13bf7ee6022d1cd329ed389349b1c5115497151f69c4e2b1b9b3055390cc36c9aa63ba92801b2d1d3eb7ef423d2ab4c0394427802cbf7c222a27f813c9d5ab4568e0a6b4dd3344dd334e94c2804821e78c19013312851a31c200ad0190269c4e3194808053838473c5a1645d67e8f553162cff1bd9c7212e6eeee5cb6a00fb492d0039eb9bc7508702f412215f61224ca5026ec25488ce193e4c665ff9c84611223b9ce45b6c8d8ba2772022c3ee9650042dba3cb2d1fa8613cbb69e24fc5cd2fecbedc315e2a7925f16710be8b5baed7855d6e5a1b1bebeeeeee9fb5d7755dd7957178c92e19072fcfc88fe401a4977170c92f198719d9cba4fd8e86e7195eb24b9ec1cb335e5cf2f5edf0f20cda61cfe4cd57758c0a26f6e5931be80554432b096dcf0f7cb8c16867809e04b9cc7814280c7bc44bf2c12dba00038a49924f3ec992f1019062b3eeee16ffaabb6d60791865fd70d68f1387fe1d8e6a2ba537887af402ce0f51005a851911dd116a02d0ea23882602167fa2a1070fd66a87b53f4c2c168bc5fa11b2f1e1a1564abfd5067cd46bafa555cb5b7655bb691976dd5aedadf6baf7da22863ce6ee8e5dcc8235b831fcffde7b5d49ca2ccbb2b274f7a157d7d5ba4a4f728328fa0676c3d6ec701922f80f2e0dbab0fb6291893c51c64cc6fa86a57d03cb9e9b66a84a7778749e0daf2357b0539e1efef59fcb4d5c64714583249779d702085307a1cfb235e2943c4cd96a95996e19966559869ab68347c912c4da16ceea455d6932f03ea30116166d1b823ddb8cd3575f7d5191c5b0ac0a1004310631884bd6087a4813d137b24c81f01f7c6479211c08acc9215d7f307a66253fdda125238b0f454616df0832726733686615460d819587fc900a9272313e2b327056c99fccb29245af594dcea8edf0b18a505dcb5a11f075752c2cdb2643fb8cc8f872808cbabc8525217564393b060c7c84f0b38a11c2cf1f28210dd2cfa23b40216475cc93a592e82caf94eabe3f39f102d327e7833db0582c168b755d66ad6fadbd027fbc2458ec966a478808870b85df753c5b48bbce092c86b4f0e66f5c81b3f01ec1622806ec490cfebd3871d3c239b55aad560b27f582eeae5d5b2ab5f4a2f4ba905094124a92a5cd46391b6b6da8c03603010720ec254a9284b69b408f74ae6cb3d8ad1728e0ed72047001fe2e5aa1a396ece0e43d95dba8a0ff1f23def702fc9f93f02181c56ed510a769bc898ea9a23405141d128ca309383bea055224a2244992f43728176bca759ef8576e93fa5c8434112962e3505e08bd2e6e09ced12a702a7c65d246d3b4ce33d6c960f34b16d8412fa105d56e0277dd6bad09ca186a6e7930ec0e077e50088c57f0bc9bb13cc3fdb04c02338e89c88ba05bad6e75abd53af2048f154eeb3ccfd3da8eb91e93acadd553700267d75ed9fd687099bf9db59496e06cb55aad160e86854129a553f0f6ff5448ad6507b81a241403096fadfd2ec77605c6e1f770db82f3dcaec09e4bdcc39bf252447e9ee779f6b8ae2c0aa6b5d65a6badb5ed3838f7629c7316e1d0999c5bb9955bb9955bb975b3ad954195123aa71c209c12e48887cb40424490608d78b454a9d4342dd664537466465e59242bdb4412d65e3bd6644ba59bada6597b5df6ba2856b14aaf6bdbecc57da41691eb889ea12814132a1e1b2459b52c8acedc286090c242c5c406255bea9824d7674976b4452c59b2da05f9fdecc97e3ee29456ddaa944e415114652d2a8bac9106515e439f582788405116c5836dc1684b2b9bea9826e7ca96e8ca96ac2dd9922dd9922dd91286995e13ce28986952cfaf188f42dd7b31db11d1fd4cf4f32c014785f0ff47f03c8ce1192108660e1411423734b4dc619685e84cf9284eb4ccbce9cb0b9ffda8042e3b5ce9900000000001c31500001808088442a17048342295b7b23b14000d537442825e3e1b4a849124c9d114a30c328621028801408000c150892c2ddcd8ab999bd4543d9452a28be475855e6441efdf869a9c7eed04c8b24feead4d784bb5e98b0eb34645472f2c0aa6a5cb1e45c9525fbb94b0cb7f78143c9c394150da8d0fb07dd83214b014cbdbc732b77ac29132d9d931009fcd1a086ecfd58179be1a213dc83a3c45775a5bed482df17138484987626691f016730dcdd1047c6aaf9a6b54421a328c5e79562cbae5dd98150d7d18fea05a2d2282bd9da99e3b53515262afbb684310daadc2e33b5bc08160d9c1027a6e280a71d70e120f70c43c48f97d58de2761878cdd226f85980c9a9e93cd6f7ac287d8fa75c023f002e713c5b76ffd48b5ffd85062a200daaaf1e0711042b3a8126bc2c5640cf13778af074eaa29f81fd4e241a49165a50e9f539d751e5c906d684d935cf592db0d35020ed627c712ad834431c04ac64a13f7a72aebb6809974d250527c7c41f7f427597b5cab489f7c2631f34e88cf3ae4f42baf87af76ece5576c5bf0b49233e4484a6fcbc4d814942b2a9c99f313cd00d97a5482901a68aba5dcd569425b9da6c8512bda8a04f531448d64143806f621a0b7ea653ebb21fd1296bf63551cb58412662de6bc64232558eab703222b9166339d28217a538498d8c55f451fd8d1af76ed151e5d86b2ff932ffe56c4c59b4e0610aa12840804debdf5af4577aec948eb8fa239b7f47fc6f92f4f9f5753b41d7a0a1d653f6c4625c01e609eb15af69727ed58b9a14b2cf2b0ef42e4cfc1312b79cc6a86359867f18b96bee4cca441a7ba31888c4c3ca6784cd22a999a54e6700f6238f43715d7c03c7c9345e2eda3e80047325f9ecb2c8e083dc48427a206966e39142e75cc1cc5a3263331e9ca51639ae5996b82cc04e58f19ea44f3245cccf0ed4bf25b31ba3103ad980316cb264fe8bcc08934ceac860f64eefba4d5969aa5c18c1d7948e8424d9199def6ab0d9a1152cc7d11fc038e70364293e7f79e80d20d7d2f823710d1549f325459250e8157debd11b931e82c9662e4fd850176a1b6be3b6c7d3bdd29ac108fd47ef07dbf639aa9fb076792061d28b6dd82aa88d417f2c7bfd63498e3a1a9818731ccbb2b967def42f8bdac8fdd6c19703c113ab6ce9e2e2236205166a3a77f4f01d4239b635650920adc89154b0d635a23c631fe10436de96ce08af2ca3065bfa1789a704e79d6c8cde9cd1a1923d65fa01e373bf629356c1448bb36329877ad885d023c5b4dcac57a10659764699d3e2f7c2c3b128553b6913ac4f039d903de3a342227c0212916db8893c904313ff3b5a92336f6b21242afb37af5c72bfe908db124646186a3fb597694b6930f12dff4a139fbeebd09a57638f42aa3d5c33258f8565a29fa0915866561aa8e2da28c3761ad2884407cef8e13bbf490ecd17d5fb1be6bb9366b8fcf79418540bb930dae190e431c90dc9d81a97ff9f5328331a95eef4b243f6efc1e13c8af4d453ac47c1cad32f35a98afbdb4f5303d54434b73a45991f9ea0be154d7fe48a9634fc5f5104fba3e8209aa723ade8f9ca96ca9c2bb4515f1128312160e910cb9249ee7b93b105d91834d27c25afd9ec80ca7d056b381a4309e6d30d258f92cf6059eefefa98d76324424840a08b839113193246ca59d296b6819e6765a3480dd053fa0bfa54a876a85bb1bbe512c7c105c9499d51b7c7bffb46680060d06dfc18a9dd4b735a6366b41a07c84124ea9415ba8dbfc6fd31553f857b0423e67d215f3b52a113bf8348f4c407199978f5ceb1a625dfbbd65e570d5485b6eaf5a58597b2103a2b9092ac094289327835c09a18acdb282964aad6e6e65be42ab39e767c9349b9fc89f96a4599b857c6ccb6f70d3b8f260017f8b9bc50ffaaaf705bec76082e2d52cf42ce46832193772ed946c0d51f87d935ec9517a2a1dd450760926bd0cf24167426b79cab2e456a44583a3a89de85bada3cb5f48f567504b26db24e66c26e00e01529e90cb19c29375688e776d1f7397e4739dbe1ca563ad4db46de9be29db682dc5068e5d8b1f1c944094d5fbfc52d08e9886a38b2983efb848a4ba6dd9e4ab1a3c6b5bbb713cc4bb07a21f13f378c9546447b40b9d5c3764295d85368a96637e3cab8bdab6fbe0f8bec7eda54bc205bc2d75953d535cf8a21d3b812a47eb8c76f51bfea362c45f6c87640d79d2bdbe392530fd0d22233d802a058b8040a129f1b7f229457e0ed2aee6a385afdf7cb0fe457e1d320bb0a90068c6b9f39cddd8cb0c7740ce68d61e094cd3358ed99fd5293a661d13250147381caf90ac58f5bb87ef6cbb67aab2e7156537593eab8f1db81a2d33f5d87d3d1046075ac7858f336c9e4f54b03065585d57298ea3d6a206b5db8de10eaf2ea6159684182c1bd447c407aa4024149f67dc69612c511fe0413d63cafbe347419a88e88922a901567780a0174a07ed577dd760886414ad95eab06d2f1b01adc55728ba22793c45c155e69bd6a40fdec8068107cb9e9e97518ffaec2545a5c3074c384f3bf7e14c80a691c69f272ff146ad861432a21a8cda43a420e1f26bd1357e29e1bd50630cda39d6c6d58ae035c4ad6120430a39c3d2d08b882463e094073fab43fb2905a94cf4a50e6eca31c4b0493857b59174a84afff3f07af2e9371857c2c53c523a93d180eb59cfc3e1b56f35a5ae0e377840be332dcf11f26041cd29ca979a20e84c27b2ed612a9d4bc3f00f5c4fdd6e8fd801bfa3c0ebf2f7e28c4f406a5f472558a880c2568dc266fe86f51c9b9e22e62df55e1b0ed003f5ab3533641e6f0d7842bd1b0776a6cdd7d63b21185e4f96ef84ccff8611ee89aca01daff09e941101c89de345514507acf9635494e88e928b08ee93bd14951b00416b84d0eb61b10c1d2f73087724c45d8cdb374b85bb35c2dc3fecd85a230860b1093419bfd64dbf293284571adfb27bf951c70ac945e9a5f6b54e7917e025f16b1204595ea3fedae44f196ee001af608028511be53e9f613e9c844dda4741ef94333cdbef91f0f16ba810baa132ae82c70597166c28dcfe3f0d9f3bc01f78f62ea20a0d6358d00e15e32783a88277903fd06f672cfbd3acecf5d7f29bab88ea85b3498e12827d984e489f360583fbdaaecfa6a6714aa7d21c8f23334f281ba678af6733400fe9d11e5e25d0d1ad1497716a3587a749076624f81178015bf47cf0106e6818b828ba65a2a287ab12398b605e17f4e97576db31c709d88e8a5585b6a1bb512e628e73731fa8d754677cf6ccd9e9950874337f880ad364826df075a46ee444ec74cea06b678132e273041644d8966a8f6368390a121b8528966239f2ec58e798a9fa2b0a8b5e04d9488fce37bce285e27b803237a5c45d382ffafbb3a0be967a2b126917e219cb090a06de48a5adfd84f623b681742e860197dabc1f004109972f51651c495bb32c0c4a9b93eb99a331cfe8cfdcd4df2eb753ba9c34715886ea2f07814b2a7e633e0bf1fd49e6585e0e07e68dfd1051ac0d928acc8a21dfc91331f8472792227d6d9102c800f8f1fa35dacf9cf3a57122b5ccfb86489c049f2c6d27908adbdc1d3aaa36f1d4157d311ff0003f7c2baa78e4f4864161eef5ca101c97eee9caebae37532cbc6b034f320ee1780e3c626cab2df674bc978ddeb801cf5232133ff18bd52044ccd9ff0912177a1cb610924c1ba15a2d31a35b428223c89d55a2227e2dbcc2afe5c4f835d8e658dd92403a8730d87b9f851d70f8a6668efb1aa091b3ae5b9cb75b99173432730ce5e2e6ed66c972bd3085200b8bcfc257aa77cc964f483df88c311b89b2d19606fa6dc3b7953ecfdca90afcb81924870dfba42edeabda6b7898530583e060c6f27164cb67b094a2e3f60838c84afd8e95a5af628822719b919b1f0eca7a68046ae16bc17940aba218da2401ef4ae03d0ccd018e2808d15a6b5a0718b24e6d4014e303f3826ced880eff2f206ebfbaabfaf8588c3c2e623f2f51bf1cea41e7e4c7a13974921a5f42b346b01759346773c6e704e313999fc3e198dabd2bfc8935e5307991f1253156dc2a2c9c516f3b0d8e8871bac88740b3f477356c2160cdfa29863121b5d6dcb917415dd70bf50691224a16809f09b104b0ffaa0e0652c28484274c198be2d0e36a948f873f36c03133caf074bab48916619934d17319b20367ace9ced6e2505ceee5aacaba9241ac2fa4d5a228ce9a7192fa2b7b2de3581f858b11ee84746dc640b9d31403ccbc34194c1d59d2360cd937da21bf0e4267503cdb2e8872c9554f209116b6c60c7d0b15f0e2c2f854088734cf646a874709f241d82ca9c0e6c1ec9d90be5d7cfba4761d64520719a94ead7fed8f17e085c0dd17115862d334067be0b9b8e4242daf953f16b8c9cf1108a940b2788d7138ce0e281b20a4353b231744df56a1cb8c97af32eece387a3340096528af1d160b6bc4d2a1354adc74e520ccf3cac1841c0662c122b12ae26ace04351ca9657dffd66dbc59bc0434e5e4ea63b1a0a49fc7bc3034b8c780fe46a50c7f8c90dd1794df8c3233b61750f470c31005a899268ac887146ad8c11e16df532592c70cab5459eb768ac26a80808ad4d0e3711c2acfdb21a80982b5ee83354b2846450aa51cf16c798327094c5ffa98a28266571992ee3929c06432fe51fa14ef291452e77c8c32e18de83a195d1cedcb151281454849890fb730ab7642ea139bcd3c9a329a11fc002aef36f923ecb0c664112d8a557dfda6eb513d98fb5b6e2254d1364a788197055c422ca8fc1fc917d038c170dd88d7a7bd2d9a1909e1dff0695f854635fc37cf9f03a066a6f8674b48ec80253b1b33eee4cdbc32e8cf5c7663b06942f0103495ef4181f79c00b83240b5d7fb635d31a19db5ad1533d78ad5eb7f5031e779ffbfd13b46aa49088b8004b6d7ae3a15b8644931ba55e535998fc83cc252b1d1ae62eb713e6f94c492a2d9fd6103a2b9d77e78fa7588ca6c6b4c91b26a3ec974954fcdbd4d362ec644b2bd68a7bd4ac95343f73d898f26ee3c1c358fa5bc574b24ba47094304be79cb4da72e345b8f33678a04129f6652e3971ff22047e77706ed21b38e44113a1f8a347582dbc64bc4dcdab25067118a38c438ed952a323a9f83a3c375d5c5d75544f0432c7d416fa6d0919403ca69756272566d0fe9052e013dbc2b5287add033ac768518eeeadcb7faf3ec4b9abeb7538e2b836f5530a2fe436a1314ba486c41bbebebc2fe6ac95e0f6d7e9ad1065c1793100f255eafbc923186230c96ba9f2afe0f8555935a54a542bc54c457755002bd6c969ae0006003a0f2b73782b98681d45941b3c5d1f512126f253e1a1a03f249e0a9b59d8c169ba8ce5caf66cb16c74fec5e74c46097c3baf86302acaf298b6434926e9d337b30e5247364e981e2250fc4d6f2a4e5af3a59ebc51bd6382e86f35831ad7ca7ba4b6a95c1cfe746325ab5569f2561fe53156622ebf91d08a3c377fb6425bd6b710613937c0436c4ec796cc1c23c032cb9fd4d8ceaf6122abc18169e34e098331872e81a7caddb273a6af965b56efa1bed756313a8f8ee8647f24909599c4a2196542a0f96685b840e6daf1848b4b1fd9393409d76229d402340a325f6b1ce00297cc4680b79fbdad7c8bbd341cae7c95b92c1024ec2eb6f4976f669099f0a4177828589554a1e6dc8d9f47b9164aff79661a1e11fdd1e310d2933b224bb08ff5a86250b04c7f6653a0ab6ac9b1e93b9fea3ed7b3ac9c76112fc240ca3b78319fc140efdf24770d3f4306d6a33b1a49bba76db61c478be52fa4cf948fc51a6a587b9a27288a5ce44d857c3f047db005c13235bb79019d1fc894db43914083c9c90a2cbe950491fc22a5fee2805ca40da169e83fc1e6b82f5e459abb1dd35e1d6600c3b4d00f973c77325b9405b270ff2f55ebf047aacd26df7c2139698ec5bebb31c9037c183f299d70e35e8340072f4256dfa56d93a14b9c851f40e9b94b89790533a4a808beae3c3b83d08d105656073183c34f863b8f48768bebe057e55cb5be67a04f0e2d7ea5a99725de18ccb1477a74fc87ccba2915a16a593d49cc52687254b5ada3b15f61f9cb721bf1cf4bad678c2cc2b343893f9f0cdfb6566b0a14623f601185b809f957855b7a6f7a6a6544aa9456d3e85da043b47521f0b60e7505b0c335a73b5fe20d9301c668a083dcc442d65dedcd77386ef481be2c844d4ae8cda706627c9598a6854c3c77a6e04647e320dd7e887a1b8466f188c363fc31f9fc94170fe55b210d6b80741c1fc746c954dd99d836399066470e0fd938428a7e1780e1f4be40426d1f529d7626584d6934be930bb74393fe6801716ea34919cd327c5849e2da71ee143b1b134cfbf12ba1cb60ad5a49a9d80e72c4de474537bb21d27e0612532e872e90de18a426b08ead20b64bb0086325754a02e74b95cb9a45dba963f10b630d5a15a6e4c09581100aa30b33093c4098fa8214362fb676e06ea4cff1310b4d694b05b760519e5570fb1e522ff088cd2aa1cb3731797f6df1503a4bc0a7857f9086747f6de797278dc203b5f463c6b8133217dde9d1fa50e6cb98ae2b6902e727512fa332c0735b6dcefb3e6144c3756e2c69835c79b29fc05a15140271d86d973cbbd5005eaee72d9724048ca0b05bf6839488fa1e5002d715a943d2820a65f1a58e2352b55fb99f9b5f4e492a12e4c3b0ba06648350b0f240e0ac455abecb750644ec9064f7ce55073192d2ece691d217c3507705d6c7c61524719e9ca3222f1b8475912e4ee159ceb3b798abe032330945a539458135c6ab713e67c7184f0260702683d2a8e4c0b13ec223d61b9bd01823603a25724e2d174eb60681b8bde11de521de241c8dff470f782bf55abf5128ee0d3902cb002c74c5cae10e76271d6d81fd0475ecf48e551628ac9485143393589e85878c1374c6f24e2247285330b599a56670381222b54e57d3c1f38eb00e8dbe5e7046f808477978bf0ada4a7bb7be62b1c9aae02bb7934731c3be8c964805f3287b46a2ee216e66d914b916b130d063616a6eb1fa44d004bdabbe70860859c9675f89fd5978a6a7d601a8a0c6c1fae93419903aa3839e24ed43ecd44a80df420364e7ebe333a295f95328ae6f9a3fcd908345ad595069bd72be9058b281f33e45bf519c5f1714fd39b82e473a66ae4098982c6b7cbbfb7b30d949e94624affc426e449b924d16cb8827a640bc76e18b170fa8cb6548eba488d5fcd4de90ebf8437427ecb2906e65b061d303a29e66dc3fb44902e69ab1836a86207e35841309926d3dcf3a3e6b5908c1f1521f4fb9c34bcdc203d796a8b0be8a385b92addd0a36b247beeb210c0eb8ebc2f48770fd299055864fcc5fed0f37d0b0c8992b6c29d2c3af021779503ed1aa89ed2c3095c43e2860e50491439c463b290a7138035f51df94be4576dfed226544362c6aba12f8b37837952208bb260300e83525abbcba683344af6f7c164c19a472ebe85f68c54264fa30114a9f12395e88ef9966dd6f0ab5d1d3bfea1e8f8e36196769a885f841a27980dd7f47c0ccadf58434f82ca748728cb91a525f466290c34993462d9a71e7a47f0e5bc3b2303be19588d96e1b89b8ce24a114da4334ece8466647034c093855ac8539f141cfd72e89a0de523cd72f2cc65bc1ce9997dcb7291c4424ac7c4e6c2e1a5982d36c6279fc3cf437dd149b5971db863aa414fcd673c84b159828a1e9fc66412c90a70036c181425d6697b84515b11df40700f9d857f1026f711c71ee06e94e86c476ce1cc6cd1b81cb8c69ff05a416933e06d6d3cd18761cee8060dac5cbdde9d9f067b4d622f39e8d3f4c221f343f8c1ecaf2c6d5b9287ce4dd85e43a99148aadbcba7ad20fcbca2908c27a0742b821aa2fa84ba5df63795b17ab7a7598b87fb9b728bac19576f6d9a940b44b964924d82e765fa33ad33924e0db10393f5c19985a36f3c0faa42717072f9e2d9a34e048004167c9dd0ed4f679cc12158d91466e08be8b694994c934acd82e7d452a9cc2b4408b084341a74443863cb6713d2d378627414eeac776fbb3cd793d76ab71abfefdfca86eda324276ce779afd6bb02eb8a6a8f232c0452273f73bad5729877460ebdf9a663ccc4f27e7f559375d252d37a0519b1fff036b77863480d83f0a2b529506d045422c94951b18b221a269be1d92846dc607d0da70589fcbe88f9785c6e60c62f37a940f889d7875266054b07a596cab30915957ea5f201e44ac5595279d2cc7e1565572481f395b24b2bb880e722e3d738a166a4f213a06ba7dd128e1580a5893eab2614b3fbf6d6db963071358cd20bb2547aadf04537d228fc6d1a72baaf4ec38c905c04a770f0b236433df01584455731321862ca75d60ee4b5fd7f5ac9ed4380ac7d113bfda8f65de0d5918109bcf810a3b401340879b4f4e9571b2f5c1c9fb1a71fec99ee75747f6b6efe9a9460c001ecdd2a5ea819ac85a6e5dd8886937de53d55d81ee982bb5d682b3c0e921d8ddc94d7122499950407d112d03d8c9310e6cb3f58e7d31a90e47a6d7a729fbc425871ab26da749446f36b70c8838088a34c3dbf02748996daf5b45adcf85e57a88049c85b9e71f2147ca5dc3a8d2e6a1f84b68bea956fa149ecbd97b822d50913f41f6902d4c58823d9e3ffd03a911d04ea493690bd0d4065028fddd9c3088edd487b5887f8588cbf8b70d88a160cb90aa62536b6334c5dc5001b3e4485dfd4b8de407b1537299bcf6c36492d7b03762e3122d59d2fa0a610e8d4067a0bcb816417b52b34ef41807b65fbe7545ad51f11a82b4a395f498bd87b90915b19d7e1ecba217de937d3f68f85b0e23ca03438a623811b25505499286c3d6bce49b3bb4fc701d5f45d9cbe229b17ec6b901214eea6c5bc2b28e8695a111e9c8e25360b9dd536b29193ee9683ec8101c3d02276b85d7bedc25022a0ee8a5feebe209e568e868b66ab75febe44352b82e8b6155517c89c4442f265a25c38466a0fcba093ca29c4779b4a8886083a39ce39c6d6c836476ca3d497a43c7fc9621e5eee377f5b295b9aa40c0592f460388ba129eb18683a861b447f8085f42df80a4e58f068ed7df32af9078671d953e839581a456cca4d034aa923db9bd42b0723c46198a237c0d18cd6a6481e08edab6fa438b4743cb2474486e4b8035ad6fcc4530c03068da1c04d62c472b823f2f11d7a5e6007c84b2a93c9699e6696c29ae5d0a4937b17d0f4344053f481183087c2bab8fdc5b87fa62873cd53811d911e598ef194408376707b8946030aaf60689f790ee014b8de67dee1ddccfd149e469a9644a4a996b2f8a7a8d8ac4437209bc8df37ecf054c9fdcf2eb5c7cf87d2e477a9a540286e6d821e898f2ff22d5bf63bdf879db340f9dab9ddcf984a0d53f1bdae520ce76cbd19d5efcdf1ed36dfc1259aa6c202494bc4e02f60db1e8cac542162ad04efc1b77b4db45a73604514e3519e65224ac4ca4fcc4156680bc0a7804ba455c8f673070a4c3fe00b02d5ebf47598a635a18099c18da48e3c5fea6421b6711e9d211b437ac2ad60ada11d3968a7e729f6850e60a06c13cf2db1d17cbb4ffe5905a41f877bf454a24909238447cb2ff6f60497aec953c884b35fa82c4496896c765fecfce8a2e94f8d4fa7160d356a1538a0d87e80538f9f0185c38342c8e0b5a7553432ef4185b06dbde434887f6b2f9dee6d0e8bc59a458d226ed979d86a342b2b331133b72d4e89dcc152da2a6952ca3f67ca0b678d34b77dfca91654d5b45e3177b9f2888c8760ad99e99bf2a21a05dec8a82e574b1cb8aec136f8d9c58e1d921cbed385fd5ca04cd98b20440415916e30f2d38c211a2d4bb96e82191f7085c495f65fc599f30628ed0426078bb8fc2a81eb485213d6b9b8e3ef5ebe8d3dd2d2575a11597e50e26f7d32a4c50a9fc762a95f55d07b189f4039af12e4f3afb5d1bf642568007b70d96e9e93433b306dbf826f8340fe257444366729197fca98c1422e64943d46fa4f36db1e819c3096b59e9b24ac4e0e4940943f6599fabeefebdc6d14eb9165edb05f330ac5b6c0e27d17fa953c96a2fe53908b8d88c4cf76a18a8fac1641b9172768f611a7d3c904c7d0dd0a0f7f732dcf78983d1f7debefca4b0695f1c3955a3ea6bd61561a01286eaa89249ce4329ddcdb6bc11835d5b09b4072d14d2b1f75addb4a908b39fc3ba179c6c23d89688d4a374e8fc4a44bd846400cd0e57fe0ac52c3da024e82b94c3cdb084685e028256418cd8d57430617c9c14884bf877dd871c74ae9498bcbfb9173d38722f84602a18575e2f4185f5bdf44c44ae305019471ea44061d52c08564f9259d3d73d328a636ebe6132ccb7e8d6b6841c1aa00c93f177c4a270b52e3579bacb8c37d4badaaabfaa7758afdc594a2d09cdc02f66d89f03c780e3a001b8847aaa2831d97c6cffdefaff8eecde42659dce336870af544a12a0b1d58af12e5886ea048a275e4a25cc01c98d8b66f2fa2b5c774aa18528259788466897d323c54ad109d97f05763c8e2e1c2ccb7bf7fc0ce200cf596c6b8e28ba55666e0eab2e3fdfb6d5ad00dbd1ea6773fc56cea76d806a02ee0d8cdb632039137e56347d69e18b46715a5f4809f6200ebeeb8dff6f6838acfeb260657f58ecc0e0c5e6a6884bba4126c68485ba31f37343ac04e89e863c893f129f3e92a14acb844976f6175c01472b24c56d270116c7a72306c070b99b18822656006d40253b1a7428fc5b990b717c568bd05cc7b11f1c13b9c2907ce224bd32ec89aa9c891999dd2526d9addf0734c78465186b42accea6778b5f06dbc507b27886c515172a13e991a915e7c7f95d181b30d20a864f7b7c3d8614c6dda8e1475be097025355c8a49d671d9b46723200eb0a9658b803676ffd2d575841afd2336ebfc1f53ef211d4043bcb34fe88c06aa0c446706b8b3b2283671eb71f9568e39e1215ff4372088d534564fd3322fd25554710dc387b47f44bc4fab8e1b6c707e9980d9ff268ea72f0e2afb2f0bb70090cd1b0c94b3d61031d64e7d23110b6a846b26cec0b5560eba1d02c03e54320f19aecf6aac4aac952585b8601800acb40271a67fe84c7c317b3214d8ab36dc2728a8135a780278e48de7475467bb39e9b7343ec8f8d08ae9532e8800400c6089778d57e0a12a7cacd0a7dc5b5f880e7854073ff2109118c9dc04445ac2f0e7ff78b4a559008c6ee1b841a88c8d906b00ee5acf97466ec723495241af1ecaa9fe5b87a7427bb9356bf05137f80345092d3fc339b623a826e6d2f28213c83dd1b95032fe22bc7f2687b2c88380ac3ec67ef491b7dc6013b1ed877371b72028ab0a506ee4d36250438335c1f7f3cef52435f7f7ec7495431a1644f5863e4d1a4250d60aa2b5536cfaf7de04c51abd4de05ab98d7869d64df4242174ccda7d22ac7322379e4d19305697244e5124495030241406573cd425cc4ee9bd4d57c033f277ffaae35fa1096f3d96e4eaf36dd302bbcb80f64ea5c4a7978dcb8de06b1824c9cef5a7c72d741f6609c0c572b2a65953f24f71cd42bfc7d29a019767b7b5885e1485bc31a8ae30148020032cf944c79cfd3b100d76ff7c99ad6641b161f3432ca1d70c5db91064f52f86f977e71b5b5f489167e5ec635081fe9584180a5dd21855e35b95e53ad4f8d6b372ab4a9a39a6abfa482a2d19256d5f63b837c4f3188bad3785f4514d00a699850f37fcf53708d2a0c06915286d87adf1f5bf8d355063c7d605860e73e537f15f4806dc6bc08d1093b77a6025beb459624ed64e539ed31e95e8ca5ca440c5c5193455a43012b7885cad713249cb47ce2846c0283a0c490e6880c57beaeecdd5103e99851790f4011afa5f325e235877a5a0bfa96d38f535810f688019782d41a36f358e4265466a0468721eecd40f8193352c4f6aa20432475984255634430b6663022534997844970e1ef01bc69f4f63f2814369d2f745cd6dbb6089657f6eec3d081850cd36827b73b8fc911951ad2b761d81dad57462aedb1102365ad864f5b7559b924e0c086b05d425cf2bf8d36d99cb56add289899f8a7153e27c6a266128fbb88abbb8ee24c4f8f455645177cb1c9fafb5a549f95cfe69970c3f9771e732adce75ec10b16acb8b716e0f22481889b92b846525942a72ba408a11c751b59aa81c7504123e09a4162c554dfc0911ba01c62e4434b542c78fbc35f576520ec9d2115e4e4d5a7369eb72326276a29a5856c96ce2a86635025b70f0ae0d84f92d5a8442bd4d8c797b71d9f2df80ec33f2f8f36823d38a39bf37b77ad434e09704aab409291dfda2a8c01775820ab32aa38020b453c68d7bf2b9dca0401d51182d56bae2b78bfb411ec771ef526ed0323de1777690c47c9a20566f74d9e86f03b33a4613e80c45f1e0c341fa127e0e68d36d3a2846c5b4e944a2da195f784658acea1e9134be42dbea2206f4555bf142020aa876930b272764283095da7fe21ff07c27489516d9dd280c12ab7184c3c55df743977c669580e6703b0f98bf269730b4036ffd27bb32df59e6c8f996f539c046f880a99f85b2602917da7059fe718875de643ffce75a9400f7363574b9cbd3223d7d718cb7d2ec3f3e9fd3582dc4180ea186ede1831c07fe295a4c5288239fbae18ed1d11deab78d40c1217e6bb663fb742dbfd620eb36950a025045a1296f1c8cc58d69f6e99aa882101be12048017edc87860a4a9e53dfab05ab783ae6ea58b237d364f0e1e9c5871484c94ec394d6cbf4da1d54ddf72c08ddfb9f4f0ff393c5ad830534777bb1d4f4cde55f3659a8837f459e5d729ae3184105352b3e69d8fe44131ce64e0cec3808685f7ac4fcd40684646025b97caefd5464f295e8f4e682a74202773e3b15dc9c2cd7eee918a94fc7c454ec9b789291769d0d32ead9070df8284ecf81f0cf91b56f2e79871bb100839c550e1cae97a346dd6c62afdf4edd7e810bd910e48f717c159f6765a5bd2f3d601cf63427009544f0fa6abed4c316d45f10e50afdd501d33afa9e105a6e4a01e5d6c9dcdf274e015b7f9f008a259974f18b9e4d54aab50c16ad33831590e00c96f9d6af6e3c016f14a652b44a327787dbe7d3ac986e84da957cb4aff994b940a922e81ba2eac0b8f4be962e3ba8d554dff58e8b897ec40d0c8f4a680cb11a228bf3105e32617b096bf67b319b64cac1d4c2f74445371329a21c6d403f65529de61419a800c9b0247fcd3cd8f96dbbdcafd730657e651519359cc2bb5b08d98f819158ca983629e2239cc82d13e46631162cfbe46262b1c7dada16f2c36d9b0c520ba9059e92a496226f9736c94c39d266c98530f51b2ae9cc0f3a633011e2d730a6a22563b272306dc398d5e52ac580310883bb690595d3957542b4ed3a711dd780585f5982df60fa42d3aece90db5fadd375f12e988d65ee80b90083614da7298a8bc39ff1d9d918a65f16ddfe890ee74db420f8964ac240c120e59d942b0eff6f9271b56b23cba943efd4d439fc41da041294b8f263f3ecfc14298cce3b6b22fc6365067143721287443c2b33ecc42ac551b30a3f5f00a75410a94698a6f9a87829e8de2d9c6b2564e118ada4c223d8f44b0cbf3f934942d02a4d4d0511a99c530618cf69b5c9359f826644addd9270d0675e06fc5d1ec8bc2e480762caf181a47ab0dc13a95462d5cfb93c3150bce59c9231b7ed5034e647ef9d4b21b960d0d6a898bc528551ce0fc3a027ffbc48bb6de3167f2a0a4e9b34498774b8f03c032f46591f1e5b8e8900d1bc41b404b1b756afce3c3136dfda82d4cc1a5cd7b319a2b314c33790d4b9ac47c22083743da1428b803910891909bc200536fc5ce2b45df325e0facb0864356634716975bbaa784408a06219900948d87d54e7208ae128e29792e4ea8fd560097330308a7e8ef08225629fd84ca6f0a92e96c2178e5184aba21dcf7669ea49a2722e93145ea34e90816ca4306fbc759641a882854e50d0a4173a06cb1d40bbb4af82e278933a5030d220bbb944100b3824a05507ad6dae71861c8d38cd42d68c62c7ec37be50611861950bf32661865fba32df5c787b951a86f8d775ca81cf594534503a4d36b76e495251a8855801b0d734579b0f8bf4725a16508503bd16f46afbbfd8a31fad25ee017ce43b32651569f5b26d3bd9e4db1354910b8cf51e40040709681115b9a05d8c582ada63aa48b8ad53f186f716852eddd94ca08a40aaceefb10a4515d9930277a5f10a19cadad1eb3e9f5930cbcb2879ce29c67a6e08fffc77968e454646ceac21dfa2704590027552259af8edfbf5c4bba74853c5abea7f7b512872d2c338a0bed9bd85de5a6b982f51d10903e204afdd090ac23e4391db273bfa630750ce748308c5428873b92858a481e771b90ace55c5de1c6ecd36def60e73e43491c9f4c787889a619d90a82298e3b0969a88a03ac0cedc5344acbfae1d3d1b2313084a2da8f87ba1d6f82dc2de50c66cb43c0291c5c8cc0e7ec135534e3e26ed040915622d22c39f7dcc0a26f137b6daf65acb96aa95ff2b50a6c7ffe7f2ab0954ed6e923f1809f872857f44e54c264ed7732d28376d9d4a1a055007fa10fb923b28d259eafc47a89e9756ed4357708067e0f6de7c969dd6200818def3bf5c421dab786992512a3939f467494737d48d0c0d9c79a78b7af3c2252418475ee41573d6fc47c9a1801ec50ca36862b1fe984b313fc083b0d0f9be92476e760416115bbd4bd87da197e1cd83874cda87c0797136c5e0a578e55d7e71d8aab97ffaf2286a834db791270e217c0d9fd5f706db36e8f24d481e821f17ef33dd99797e3674fa560b28a1f38af89d1312020f17f146a36c1d23dad75c23992c613a9124d3e5545cfbd3051b91e55db54b1b40bd43a3f8fd9493dd1e3d5f6e48ed5a29bf429a614671f9bdf410479363bf5e4a7ffeb86d3e013628fcf8baba271c94e1bf6e1f16da3d772b39d75304b746201a950052c08f9e7d04828e86847d186aa1335601ad0204e836bd51adb0345e22508484b6cd3cdc9c0950916e318c33b0e74e7f0de57678c8e712b1c49ba01e7238a15686ecc70963a38636c5631ec7df0b59b85d593f2817ecd8a432bf6cc6caf9a9729d7ec93af35ea781b68ae94b550133c35b7da0c8e0f8f4b0b2ea4eea7dba7d39568f2acbf999916ef77f3d9de4ed73c38969bd3675a10c04c9c8902210671f88711973785f216f81b6be9043ca3144faa6767232edb5f6bfa7963ca3d1c9f3d5d81b28ae4d5cef5e22275433f5b4ad917a7f211bd0cb08b0ca7663a2153329423139edd4443597871300b00019ab45225fcc210cff1104660cf48339124969758af975e8a5e7cda4d37e4603270c6985d5facb53334a215b520a61802926db529552da0df2c0a1d2463628b36857e1e1d94813e212d98c984013b66246fff8bb094a59fe4bab6ae159bdc900ad4268d2cc7465d74fa49cbe73cf8261180d1c5b71f0ed938ae74eeba71cdc19a4a5dc0028ec16553fba0bedba34897f73a25aac2a8b7c79fe2a7e287395812d434c3bdbab6b0a81441d6495ff76dfbb55319af7c93cb4b6e9257b095d2c008844dacb0825f6022fde172b29b9cafb5e2b7e622c789d22eb73eb78461043a173e2b933e28fa50ab224578da1dbd6fba8d219dcb0fc7d15a2c1acefdc32a07dae30f0177b15265ec84bf153da268cc814640642cf9224341849e9cdae095a95328ca43743242924f9c1c61e924c9b38e117ad34c2d78e90c5fef223119947ffae2460a98ffda68add68482ef2a462689a320894dc1ca21505b993ede407aa849cda1d073298c966dcbfd935170382c4d38eb7a72f533645919c6a71a48628a91a831da57ec9c9b76225a00a47dd99ff7b93046e2f6240cddbba497e997091b103c0e144aa447641422b238adde70758c94311ed098c55ea92b407569cb365a8563e40474d7fa959dab10cf06a34392bab28821b43e00614fed85356c3a1aaa55bcf61260f3bb43e93d97394845a885e55a0be27988c2c48ae0737fd175fb38598c3463c62018ea43c5272098b73249ef7c4befe1448e86384c893accd48514f76da6e391d2a91e7cf669eeed8971b22cf808d0e20213299cff0f6f5860071ef14a431ca3c91dcbd96acf168933efaceee2b411c3a05215e3f23725e70a63ca02945f908726579ca97a85d468d75945e883d9106a53dd93265564431b5747abe0e48d0cf96782189dd99e06ae73e4fd26982f595c6ecb4dbf3507304c1a5511a345be9049f10fe5390c22dd52d2aacef0235a87d1c5cd7a8da2825b12d2e9bc54b91b6dd1857f9c7963d8b58f6c18e05c073a3224ca1d117885691f9458d3f292e54dc6fbe542aa982b9746f1788e8e0a318e7b0e24c458a7d2389646df1fa468e8a4f0c275e5949e5535237c57a8ba7699316ceb1d407f199ac0893679398916ef827ee280f3b6e8c027bc8029ae130d35de8f4ea640802cbb44baf51c8c9ad262720902dd02424ff5abf0ae738b83fc0df9eb46d4e17ea60b3b887a273aab899a30a0827ca0f79e0b8bc65829edfe9119cc504a7c2a691d102e74efc41000a039c7ffd13d6267262f82b4c85cd8986f274dee642e56e0009e97e887ca37137e0213be7c5c6d16f771ecd40f15f69e95ecfa5234cfee5a426aae4cacba826f1fd7bff17633cd826251768fb6b06f0dd44f50c599497a60015dee1f1ba9c3c16d5e3b7cdbed23ad6d7bac65004cf4f9613977563f6aca206135003781de7617aa53590432a14a841c10fa17d3b7009dd31b0150058d569b0d735430ca428c4a00e98d7fcda98d9afad85c07966b9d0374b0c38453bbc5c36c331a3337a0bbf23730783a31f860fd166eeec27db2eb80834f5b84625e345207427fc3d84633141c661b4489054fe0969d61408c6162f6f513c8160516b1aea89ed26516407d5605e6ecf9d77044c1da1e63ba72d49aa19b49f1e4844c70e0e212ff9467ea48b4a5d0760521d03af1081b83fb61ff05c664034c70e4a230ef8236b00ae89c80e62a7051c911d088c2abd88ec8033522a68fb87db47dbb1d03ea16cf1c1c9273d99ee14c80ed27da91d1d341b0c78d00e1e36723b956a09d4ee7f2eaf586707aa9b7e44ba615d7763ddc85fb3dea804fda11ffe45b0703aae2efd40b27e5fd01f7096f3dd9575d2325397c3e0e09bfc5308ac41b21ed448b10a32823f2614ec147dd003f97857224a761bfd7c87fc01271dbefd6b8b63831746132883b6c432b878881d462f8c64b907fe23e234ae8611747aac8dbed0dad83849d648f99cd6b6ea21ce5483bfa8c6a4504021b72de308264694001579647cb42e6a66a07277a56b8ee3a4c50e6cd4a65961d14a67a7b84fe0c7313e5fa2c4c43d738380d8ae5e23938b361a3eeb4d770fe657e9a198e0c4a623c17e337d63e9961024365682ca5634ae910e8e0d2d495300ef162c670b78368f3027a87398e2d36f36948c8313008f4e062b85f7bdc560c9a66e1c91ca9de004f7b1cb38ac571f9a81c587204b47bda16e60b7d644c7fee79f66f2eab53edcd93b3bcfeae6db6dbbb63c21704fb048c8723129d2c40539d862e6f37db337df49d1412695eaf3ed515111b2a4aa0fec3dd429d127b449eb60a25a9100f1466ddf30d9c76611a89e3672b56fffc605839890635541cfa5362da2ea532a34eba9b10c9629fa14ef1bc0be4dada92d00906f811ae3028297e1fd156f84fe4f0303bc77217be53897629b1142cd96c9601f57e6725472c0b3716c2110e1b20824cdce5ec02640fe2bedafaad274dad4bf6aa8d662b45ac47cacd2d74ba53d8bfcf92957966010e825a1826df349107d95feec3cff04a335d96639134e7dba1606dde82c2ae0dd9b81d1651c37ff369601587a6c53fd5cc8c38adadfa2ba43c934c129e653658372f6ddb0df3e33544caf26268642839cec97119ea1bf82efad609ffc42b8dd46d474136a7986eae95973f7acc1acb8195a70d0b3596d931c24857839abe40c452e390bcf33e975a4e4255d487f5f173e56bc05db85fb98a7c8069d4bae97a950ad51fa6cdd788a20e4d2afa788191c2303977955ba1939e5c8594670690a369f956d10cd266b1409f0ef1b30592a01fa2a6b777e25149d24de86446102c11584e61e26f9d37b09f735eeaf68607831bbb16075211d896c5d27cdba5f99482edd822f44042ae570fa249e19f50563e056e41cb4f019935c04ce1f478ad260569b721afe497856c61af92923c2edf16028cf65477fce56724b13ffc3d30991e89b29f101831d715e00ef4a304bcfa1a5277a94de16cddf5eae3c5fd9ff562312777e04f4ed4ea5243179fe5f44fa3e64f26df2d1df59d4f73bf14b82f2cde5bb9c5109faf9eef0893137224a2066a6f9aea3358f664f383d1b8b8cf3856f80334d3958283f2d7bd74902b28f1c888b74948448ca1be95efef9a2ad0a18c57fc9759c6fb907c41c89d2672f12fc26b90b376562288e5549e95aa1ca447a245d842f19fcd5197fc771bef00cdb6c4a56854b006f6448cddc84be01382325e85930ceb74c852ffe206421747bc45ec856dee7e67c952a78c255b9e6a0f2bf3248e97935a65cabbeda869884bc533a94c7dfad72406aa24c37c80c23419fee28364b0837c7d2156c3a50b051e2d1d49cef66b9d7152509b126bbc7d7801b27c515311175deaa8384a0ec2e3e715aaaac39ed95d7de7ad128ff1273bee0d7cb3fcee70f3819dbdaa1339b41e995efaeeb5a6a65e7015e6ba1becf7bdff67973b606b5c936b6245d26d0af47fc746b53a9b4fb3b30ee36fe48970febe382db3d734ece3f7d43d0c59299686871cec6cf7e09401317d21087284f384c9d9ce30092db0c5fff2bed078e0343c35b3011fd138de43dd35567822f7a422476a558a381c231bed794f72028b43eafe664ae5394d4db411e5203c5da6a32658a444b4fc0ef4f3c6f661e73f1cb09048b1557c8fe6fd5885c8b7122b8ab494329495597b1e504df7e399e50ab21de2ff8e0f6b6c60d792816273432c029b431e8b17a111a7a3c1e759903671cb8e1ab0d924d294be502495e23b5efc941ca720e1e0bbf2f56352ef8262f0a62f6ed87d4629e4fe09893b676221de295afca56bc3247eef64e262c9377cceafec2ca688dd873c4be3db2abdc246a28c7cba2de78675d7361d76c840a651eecc0a2db9ab4e2244c53ed942c3e2a3ac6910a710b39cddca4ea2e5c52b2bc660c2568a3c7583060b5a38bf4c7f3ea190ba8dbfd33db917b13c1bb45217b54019f53085be7e1de821d500a90c64173c43782a49adf5f5181c80dbb7f41c1f9c9e13468140635d8cad9f0486bd0a10b1ff21bbdae377caa8d3e764b8b2439b38708578e672382de17b17a20b7a7fbae90e62080a143073a48098fe0e26727a84741ecfc5bb473b59c71fdb84f3caf7b6d1ccd13c68f599f8fe40efe26871f641fd3c2ebda29736131809387d833420d65c2360541096242876668f6344351d469ddd307640f6d2f58d48586c90cfc69340d7758d3ce9a0d9f2775e0835a6781b6806871a5ab7151f2190168919d21b95ef3ae8bdfb28251d50d6650cb079bc6e248c427e34a7366e71cf048584a90a9f7d185180076d3325f4f2c30c1be23a48385e12c2b3af8196e47a183e085eb1f02237317a52f875576d062d2f0e9b0603350312819bb6bf690ceb789319728b7c045ceac783437796f38b75bda27b9a3d581a34c3c5d6f41b982b017a991b3147c019656e02af822f1b05843ba721b4ab531ac04c383c3385c0a76160c84901a579db7bf4604a20da31ba8ef88886a123fdcf95048fc3a184234c59a17da25ede799bfaf9fa3b7e6687dcd87048d5e92ff39a229655c0d55aac3bcc07fa3684e2a357854d0e4bb529d7af08128fab5def92e858b01e2dfe27552b3cfd03c25cff80c77490782cb0d657141537ce0da170c5315a42671bad21b472d2c6ecebf0deca0596b2af5111695b398143c4c717b1bebb7ecdffdb65c62a81d5af918cf6f0d58cbd655da5c82effdb54960ff63364658aace409f922f2671e66358953347a58481570d3c0edd9a9e0a52174873424555dc29ddf8b9a5594e1751004d016ca8570be745feb7ec6b0a47cb2cc79e63af02d06865af1ffe14576f562e536f7437cb70010b23ffe718649584d0507b4f63714be9047529e808aafb75de0441980c5035a980530c3e38886fe823c110e0b10f54a8cccbae674f1126abe51666a91d97814a6970a32d39ad5f76d83a3319d1865bd14fa2fae908edff19564b2f6d5632d9de0e7c0cd10471a0196629a5d61e99b09c4664f07a8320faba24164460e1fb4e263a4d2c8cc356f51a08189f95e2589db59ce086e884e30f5dd3e3902ef04d632fc530cc4479f8f166a3b8d6634c17c6684b2b1ee3a6c5b7eea07082fa4c2199d5279de8567161f48145f7de3af54e94f47ebf4c066ad4a57abcac1730896e23cad79aa8b5f8b57e4aca258fe438d6495649024f0e308b376744b5c662a6d1ee95c2bfdfff2197d486988608a2aba9efd1733342e704ec0c42c80ca78f4b6a4572106ead8947bcc8c01735d465d4c4b77ed1974cff9f3e28a04137b0144b52a7efbcd81192855b8c5f3b9ad29f195de871c4926d4a1aea5c176ebb4abc54bcbaf0563bdcc26bba15a58f9adf699d4e5d53c500d6f55aaff687dc70b78e0e3f762e240385cdd1521f13bf5c2d2ebcce37baf8b5118e905d15180be43f3d831c7c91ba7674ead6eaef5a18be999e09bd51f94156683f40afe48e87b1d1a77b02247268374ceef84bd1cbb8313c75d3819655e66fc6f8d522b94a518cf068e4c9f76d72ecd5910c8354f7d71bb194007723d16be13bf81c37961c4f67cfe9b853ca7d350806a6f1c758c47573fac9da52d46d6675e361f698d66588260358a4d918f59edc01488f30e8ac6ed7b5af8951aaa062771fd4dea41deca000c2eade0a404df79f19a2427905b1cde9fc72b0ada361dd9147a168e2fa1aa46304affa74a4e6cb3a68d3b9db3d248189a350a6735677869ca4783bd1ac7663545ce792b1dca963bca87db8578b52405837412154a84929027719f8f84c62a2933f452f0ea85131a970369b24df26211f74cbcf37f263ac32a22e128d80981151c435e4a24bda86b105873e3d8e660a8cc23e1698e8a146a5005f2054e9db911faa763fcbbc0205c86ddd23e47e91a76895bdf3f63192ce712ecf12c6d714cba02ad6b7c3810066ceac7da83c1ca30b34386e61e18797161fc774163e909b6252152b557bf6bc036f319dd7537f88b4358a241754aade0d866bf689c6749151dd9ebef34216107da9ae61a0ddeca5d3eba7ae18e4c9653d14865a645973e5546bb530b430039486bf4b420373355953677a5f0500acc856c816a874d831f3ed858e9c1e7d3e2a00f06b475f363a053e6b846945b6b53e8f0de71eb37a10d49252acf174a529d4298db602619e057e041044331ad64caadc7b737898a93849bcd1ddd96e9f81bc6d207dca8e6f1f187a0437101c8d9175d6ad37057a3fe6a7346500126370d06b8c1ec92aa651ea3b7cd17ec37912f542132d448c3024f53e8d6d47ea321e98914b0a7c394be700125276e155e7256f3c532c0fd5d1a10ac14401137a776be45ab08127d4b805f9c83506636f4bd64732f9875ff0bf5a69e0fd42935c062cbbb816107e9ec3ec6bd5688e4a9b414ce28fb04b31f0be7b5fc48b80d194ed333673a6b9a938a8260dbda2567726e1664fdf581fa5c24a0ac561909f5f2f03d204133b2a38548f56e1d750368dbd4dc1cf3dbe246384de6122e22e2e022202fc7b060ab5494bdd6a67f48383b21941f18d376fb4099998f7139dd6aa271573919b47466c16d0cad8580d00cbfbe55fcbe13a0efef82ecf1bec2592070cd366d9f721db3d9b48315ec9205aa262e35f2868c4e33b21a0f1dd016ca436160d6690116086294f17ac4c9e3f402dc04c940d509be40d54e10893d8e96a77eccd6ffe7a6b268d4a1a22a34d1d939fd67f525cb21b8d4c60a09a22470112fedfcaf8deed7e963597e885c8b099843db0a8bcb386dda43c9f9961da5e68b1582d985830e6bb5fc285a07c92c27c4a4c537983cf5d6e10c1dec23d657b5d612ef17650efa05711ef6c6f124bf152e856edd78b2a0f1f0a43c88f71e1f15f40102d9bde3a49a798fc85eb214e8a0f72cbd3b256d3b5180a832cd500359f97edc354cdb90466611ac6418ecc6e40c4f40df5eb56f5052e000346f7505e3fce4d5d18ee27e30114a96b17d02b1dac569fb06f4cb33b85f8352438b93d9d4116ac376a3d92d93ea66c69c5440945f74a43ee38cbc3a5c2dc35f2632d6ec78ef6479916d47f768b0fdf3715e402be01bb07b85e62bb1d8b466868a89e6a83a8f1bfaa8a2775453530e4122c9f16df2ef24f77b7a986ec2975ddda3678406e06d0ba7c525d6610e773c83d623979fe9cd23b00d67f9ce87f1cf2dabe327792bd225d9b3ee225fe9de7427f6c3651910958ffd13cde55eb05d90af8af11211745872a595e0ad787b6837055ff53b5881ffba8833a332ae57b13721815a47540549e03a9d38b6b89aa6a0071439a390c3414399cc49d0a27e33259696df06ad09fecf329718eae36f58219823d8f816a0764efde7542999aed9ece46319b876ec8219c4bc8a79750b6e87d02623e293a63b038c50656abf90098de7d1667f0569a36a5cb19f7f2baa481ea8f53570bb0d744bf5ec6716f07c0a00ee32d835a428ef30e3071c9b278fc19c4089c1fd1abda374c939dab7ef38083315b8ad9676fc40765a22c727640fb24635b86da0e5b9ee8faeaa1811c5152154195d1808354ad9da2a5ef80348786b0c482c7aa44d81f39781ac2e9e87616504ab229033de9bbd63ae5ae105b9f282ac1e82a3251e03b2955191efed4060db9455710c618f92f4f57f512e5eb8aed02d74d71bcb11c0ec2e9c4e299a8ca72c600954829c32ea7f67f7bd1e1e1f9a9844d9614cd8f5b78da4bc455638707a299050ccdab95ad4d2a91bd9f81288f09225871a358af4ae09ddee54edb7801bd51ee01350924555abd312590b106755314e86b4c6e4daf14fef4d4cc60e7f21827bb45d5612456206a2bc5059010ab52ba3ab568fe9a8e1ff303c4ad6a6ab38de4887af7107b9cd2408d83e154295cf57da5500f0beea88d89854d180389837902504e11ecb1f53270de9d5811ac4224c074463702917194b2c822b8149a4293c1f02c82a688b49a1eb55594927b0d051c06893720d4749e07a417403918c18c2becad3010a9badc01605b18c1e5e37b22c4f508af01ab719701eabc0a7489c5bdd0ad4e9e55a01bdfd295ad85128f288092325df61963020247e7816491842902553f9e4b05668a367639fc7cef98cc6afd0164891bdea9c9c25d386c084dfd13651c7ea16022db893f873e5072e599b55d627f513aa95bd8b1bea372c32893199219199753993a484ef18e8af7930c893b91c5206f254dbd28514a14ff14064365eb1449bfd23165e47cc87593a6a84134292963c87a0bbc8f3e0c12a3ea649bf499b87ec60845c44adea44009bdb273fc21d236ab7e01e0ddc267def96c6474096a8afe1a49f55a2da00a0f30a3fee65047db0d4da64ab1153a01b7c9f7943c0b8e30df564b149b7685a617388d5e2fe1564ab3733c899ab642e91da185d424122d84bf410f2e9e79064e70497869ef50fb9b9d8f463114c403296c93cdcef97415ce4c0a0c5a635d388547f47043c623f3abff46f9c14ab9b5f1c3357198c456d2019a69f448e52f532d8ed2dc474a96522ca1656f0a770f6626abb5384c437ee3857b212b3b88aad59e6b565d8d47b6b79543ad7e0716d3cab2907f512b9069d5c7de3785e068ce7b312d1cdab4765348d658fa6f539a5d8a7306517c8d37113868461bdad4b1f32a7919ad25eec686b1f8f84cea836856a94a07456a51ab56fc96a91be026c15dc5d9c07521a50582f99244e8750f9b6d575e83373dfc4e2605ab5812c920b9a643133ebb282cea0334f71e5437d98da1eddc0f50f36ee7cc78966c6aed662be312c8b1ea311f8ecbd349051c66e0229b54b499a77402f6a3a3f4149e629eb977c58ef0c0ff87f14c8a904ba219f297141efddad5617102021c61a5053ebae4d9c9e40123ca730744ca68a357114b0661da17092f2491aae12c8b9c8aa72d3327723554fa5f75c7a5be608e7a5674ff534e9e82607355abfed7b234eda1a6d6ab9ad3c35814553acb070dc85d0ceb806dcb0f69f71ceb8ce3878d708cc6b848e8319275b90b83a1a72790c117f7ccca65503c5ca178121a89eb47cbf575a7b7388b6143e8d551cf57c085590ad40f9ef56f84945457140875b882166d4a9d22e92a5779fc880595cdb47265f5ed1241bed76eeda69e00eb5d61b272bf792ca393bf73cf5b3a51646851fd5af9f3937981de9abfc75a7aee959e9e2eaebabb5dcd0316e0a7b13ec0a24e67e94cac4375acfccc01cc7496e80738c5d8f5fdc40381d05b8bda1e770541f9630ba1907cce783756c9803efd43f977c8903f59cddec74cd972bea9de860aa5c18db6e4b47e591b265d91ec7d476950bb3fdfd64c8022746c7366a060b451c0b502c9a9e3df5d74035bccfc9d16058f2ef1ec2f5c15c3f966850826cd7aef05814aa51a7918285702938a996dd0c643647b384d4f9bbfb85f70209d4bc1cb9a7b4100c31d220203b88d597acc1d6060e7b986c1b111f9d22a211640b5b8c0e4bb40482e09242ad3c80d6435d2445decffc44d03d8053028147f33ceab88dcab9b78592cf697893df46af231629a8c8b6436090e95ef88b66167b75c7b6fe7ee52edfe56fe2c97e78aaf11c57d9dde7d9c52627399313d27427df2885488164dbbd231b56761df171e81648c14f158de379333e83f9b7e1501e67ae5bdc9330f4d46fe320cb49d2b055d2a18ebbc4dcb008b9e41f1a72d54027cba7687e4419b658e4049b5726eb240e060cf599b58bc06966d5941c8ba904ff337ae8fbfe85fa838065b99e0a049a0b38d3bc5086095ee0d5a298d364eeddb1cd93fc380ae6764d2e8503201393b6284ad90ab557367dae61bd08b604d2bcf81979fd4a643b68764d4c387022799fc7be21083eedc7134f643312578f9fb2d2e6fb1598eca608ff3cf9a49ffd41ed1e525077a9b4f889692d4310515a4cf2c3b2379fd533fb12cd74ed248703ebd74bd544da6b8bfb83f97f39236b916760f5df44423479df36bc6c53c5d4f03c054ac0a85d9076444e85026ef7c4888c483b2c46c010350563f5381bc58b5af76f2698b0f52702a805f1a3cb9a7c5e423186f93532c686d54d9f39c0122c357dc5b01cf2b88b2eb8bc7e18576a30d46308c46075267bf043ad3aa4606f8ecdb15f860c69d4133c03e42c1775ee5ce4c748640e859a20502e97df08009733f5f1e93a8a8a959bacf20cd4b46ce47768cfb268248e00873d8e7e0ec1380948c087419910717c2a385fbe93b5e206d8106729c2b7e6e74896a472c953f9a2f80c82f2f285d1725c272ea735aa949244fc9f7005d2a43d23faac8e788dbe840436f21df1a5c0e11e16159ffeeeb6ecd8850d21ea0187c41cf27aec5783b2c379a04cb65a6c209337ecfcc5433d6df6ee600156b2043b2536eaf00aceb28ccd3a6b86ac0f73e8c9f407950221f1f77768339590766c967c617fc651e0ba92e2dd006d0818e1cd3df05a29d5cb5a5e5da07c69a3617f4bd035874718f4e7b437e20ed2904258405d2d3b1addd8f0c3e92507970281cff5b1618db7ad3a6405a868fa739c2969ea9864d8f1081d203b6628d50f6ceb2c26422fd5920974cb92dc8153227eb4e482bf12802fc626fba616b9cb30cf3f087ebec37f8033ab4bce2cd1e0c5e5886cbdf6fbff038784f9179ac2800608f0175a8ff5745361ba60d3835273e0d1eee2d1437e2f7f8fff57be2baf823d78bf19be36b1a485b84031c8075097e19a71e8ae80882dd92b507b67152011f2d3c737bda76db5d1d316f01efaf9e0ed0fa11738f5e8808e08adeca6ef235aad17838e0bd7cbf4b15c53ec793286025f6fff9fe46ec95637e1e095e5dbb8f8a115ca14baa15e373c5816d386c00acc88dd1a3e472e4692b1960d082ad5e8a062a953ae6d220529e4ca67f17df9bc69cc2903db8e41ee9d7ae41d63d56bc0dfe076790456f18bb160b7fce44df852d73d6067791eae69d6e9b06c0d8739433d988f0fc769f31e2c298b9ad0db0dfc0aff0a22f6b3c008d09c906b081c7131a886c5941c2d9e79c7db5303ec6e504c7b7e3cf24d28bfec4aa12247af47f3d5171d5d9dac0fec0387de709201f235138832da48a3432ed961ea72a140420a48a820c8676a9449b62e2cad85f63f64e779ae341898cb722d6b5242a1cbc49b43c43022c895d864a772881ac87423db7a94fff7df2d763957156e1b0dc2431f6545b9603ae4ab2838e0a5d7e42780ed6121e4548ff02959e8ac6581eb102060fc1bf5738c7321d4e5477cc73ca51388e1603e00fd6580b4064561c004a4796ce7c0f0d561e416a1a48ba26a5542456b4f46a38490c4cc5dc4f826fef82c8eeab2aee892b78dc7de1363c86b019d5d4817f067eb7a8722575ded07e5397b727081a1c00e90388dc9ba09c21fd16b23ff72a1fdaddb012e174579ea4290d4709511fe0572de5df6f1beba6054d3e8dddd03342e817ca82384b9c487db5ca88a4e1b73fdf500dcde5d47a419419212a025ed51b6e64cb18310994d6c36a95b7b8e1cdcfa4a27d917ac8f10247e40a03f56497894bc86cb3345863c7ff0dacc3f602c0275e46e4c58d126a59e171544622cdf587776645ce89df8007a086d9f1b786b7c50040e4bceab847c2d9fac05bea40a6848f6ffebee3fd053e30aa6803d0e9136b22639d1bca08785ae8fda927a81959ea3b13c84b7081afe73e1215c97bfee0458580d59453c853ccdab3447149d260a9f93f960aca9e5949f7a2ca6f7aeec4c8769a2f4738d79c632bcc2ea737ef4482cffd457f0658d4ca8874a7140ff6e76d9dc05616ca4ce82bd05b7402c3e18103f7e21b1db179a121a823043777d7ac698a8fda28be778df475629d4e64572b4ca5061656040ba3ba79cc3299c14aabe35baa2b457232c12d150a4e9e0d3b7a4fefea3e3815fe300a090e6c6be04e8fa511f7d9a65112d3a48e35fb97a03077500ca39f10dc249dfaa7ce67edd05501135aaf30cd2935eb06de6f204149e60d41099dc619a236b7d20634209c318138f3216a69a1c9770e4c3bc0999b33f23c2be1ac6cc98e1f48b4da194ca9106f257c8449dcbbdc525b7023261ba145fc4e616b1f0094559b7942176c7824f3969be8c09eba3fe4310ff76dd5ef39b018990db75217b3ed7577815e1b96ec5c271f1bb8d6ff53d859ea0c980335217e24324d4ac1fd5581b6483f199990c6dff014f0a6c7b46ffd0fdc1d035ab33d595930dad53607e5c8dc585e72aa45b8863fd60f0e78af06e43efed81b58131b6b27d4b4fbc55899a3031d56ec65d89c91a1060a27c1604690d718705a8e83f9457e7f9e6c1d0803e0fe7bf2e049fe9f8fd2464b9b249152ca94646205860574053e45755a29469c4cbd47d662f9567a29a59ebd3806eb9ab8f7d251278aab64431b924e4c8200b14aac6889946559966559965f7ef9e5975f3ecd975f7ef9e5975fbe17923165d08636b440acf811c9164869436bc3907c7d98ef67aa4aaee4743a9d4e65792a4fe5a93c95211b96655896362c4b1af35f9665f9e597effd7f59e2adafa0c39e96b021b640ca29eee28fe1644bb2a17b5d156c68c37074981a86a10d6d68c397ab34030c2349154e766fce7064dba8497cfed7a84d4eca904206bb94fdc514a394d20bf3b277af4ab9d9a3fb18dbae05c7fcf0eb303fdcd590922dfe8b81b2cf2ac8bf0b5444d3ba4e52fb730139ae6c67cf9bab0a5384385d40eb77398b4c8395bc3ce62ddc2bf71572104eee63c67ac4324692363732aca6871e3ae9c4c483003129119d084729c7711cb771383f080cfcd1673961ba143e7fd6e74a702cda86ff681adc4731c5077a0ffc89b6d1393c98a61a8073f5351318cd976841b37eb40d9f4247ac29dfe3f09e3db9f3e03931beb66aa7b40d1ad2144c01838ebc851df3cefd4ee5b40d6fa552ad9c0b7b8bd56a1b1ca6651bf66d4a350d7fae33a59c06d399985eb7ba065ef87c4c42071eb23c4aa93dd8ac1437e23ab57d380ab930f470348249c3075238bda0280f3dec74b84dcbb0e63167f4f0416524b9234a29a594524a299d18e7fcf9fc87a80ae35528346766df20d8a30898a04b8f7895af4d05640a2a910f2158562511f742784c2d51e76f673b140d8ad22d681628ea0485eae137fcf862b22ccb2e1a97c025a2a64b494b391d3a0c8d6a5d0b0fdadfd741cb287d8c7eefc0ec077af8eb073ebdd8fe3862c6d829a0e60a35572857425128cce650da36f8b9cea6c53eadb97ef02b07ca3f1c4551144551144551144551d4bda19110c2d0462770220bd4a3380c3a800043eebf66cb081530c678bb19085317f1da22d9f5393add17395618c3b21a343964e4755dd73499ae1d95da1db9acd4e693bfbd817df695ce15ad533401840483115a26922a884832917600294b20330048e43967dc073d938934994c26934966fb81c1efee340a72fab6ab967620d6e1f9f953dad54c8d408de3691545892a0999836a728de3d829cf7d918c580a96923d675b1ea198353899550c804963219988ef68d2c4a2f965d883e1513c67005a64fa9d8f233e4670a6625471f538f2e0466c15c2e73bda862b691ade4614610a57620425aa2528811c57230e57e24a708cd738625ca372857d52366181a1cab1a9944629f574321319ec548c4aff1472a5c9b142ad344dd33c1d4f87b1bdae9661d85e375585154d581bb76d1cdeb86de3f0c66d1b87b7546adb36ef25b4790c1bd0cb5ace89dc14881e33f84fc76b0ba2584a3d218212726a624a8245b1568cf1171983583948a886babc94fcda637d755d0dc5ba0ed234b80e420a1264073a08d28320a828c49448ae3872ce5967d5461a83c5b410af61ced42fb848824344c6a1f8ca552a8ce17f956a6555f831ecf157ac93a12efecd64013e84593d0a93cf875059b6e322759d7380ab542a95b52fab8d8806843585aa6e0200838cdd8729ba6e7713864c43eee59c73d79b5a2f16dcebe14904217e3deddbddb79b826677d3a7d76317c83eb6f4de7befe6850c7eea67738cfd3f14b04891bd2f640a81ac83c5f5ae8b8b32e79cd66698bd40c8321b17727d50a60273e5f3b7995d4c61b6ecf0813cec1235c3de5a6b6d6685ec9915727337441081ee8af495d1227fdb9b9a1f993e58e307ac0f9c2b1afcf3214992bcf7254496aebeae797154a4722453cdf615b95ab739b8901ebc5f6b9cf93db6eceb532f5d7fbb52069adb83738b1c201ea20e39508b38ec8b21438e5c6ee370d4dc9426ea9b3d67164eaaf03172a2078d691199fbcbe15199938cfa9426fea02e8c658a1013dc6863e17ae374fc9024cbb4d30fee614964ee734b877bfe3fb8e7bf83a344d091e70fc2f3f9c10683e32ce0f9dcd22a2a313a1ff957de07d7e5ce07d739c863f437b017f58ac6ac742ddac7985ad72201ee57de022a1fa30bc2a3d279ae9ba20e688a3ca029ea96c3b4683fc4a7817f611886611a913a52977aea247d726fac25ed63b8df3aedb5ecbb3522d5544b602d655ced50cb6853ac9a6a69eb8a700fd6d2a804aa715243b4711c4712d7d295611a892d79d552b6d512564b9ab6615ab66d9bb665dbb665188661d80f2e9381190c06ff055367b2a9c5bc625ad1812ec568b46dde8bbbd490c18126071ca81986d4596bd79e329ece26e3b99bcdba2b32fdb985429a0efed3fbb7d66b1c845a6bad1d155e593aacdd42097b10dc6a6152eb6412932426afebbaae2773c64a53355902164d7247c3224f56aba80da60daec89ce93cd7f512260d876927d3f3f7c6a2499324258720ddbb45b65ae410414c1b4d360de736ad5bd98f16d96a915ce7d2c1c241692b8c1285c17a7466bcd036b6566bed5cabd4225b64a9d52a795a2d4f89eb783cad96c78343c7699082b5d68a22c639ff6b1fcd8de7a8a190e7e5bef7da720b916ba9c1307cc21fc6e00cb75dc015007cce8217e459679d2dfdf88710cdcf067bfc36d8e3164c9ba29aadc51275c1c0206a218af7be84481d23cc39efbc5bb4966d91e99555f22c45d0319e0c2928c20b9fff006cd04ff17ded9b86c5b6cec7111f5b37b51d884ba6a0b4b71c8ef97518688b4ceb4f6e87ecc33bf4e31bb82ba239e77d5eeeb82ead7c42a7d3e9e42cc34a0c337c5e064b0c510534452b20950c6a510cdd8f23d8b3fc87a5e333c8685106b98805f42023842812e3697c72376a10f9597e05d4b2a2f247f011ed8710cd009aa24f86719b8e180ed01a484706c845193445db16e33d5088ca5017acab9d9597e163f818cf926198eb1ccc029a2dd218191eb33c986374169dc7d1438dcd8d0f397ed001844aee782787ec743a9dd99d4ea7d3c99f19c3097905bf4a1325a81edab74c974c6d24c98925460c31805838cee3a1c901877b3dd4d8b877d33fe800c2bdc65ea094524a29a594d29e349c93e5edd7183f6bf8a60058e0a35a648a669195b7b1a295ce8710a2958f010ab1688a3416509f20758396c89770210c51a4f9114c9c208a348a8223986089b47a04a9092d91664f80d30529d2ee14486a8012691793205c4125d230145054220d2b021454a148cb84ec201469dac602ea2751842b91b66d2ca036c2881ba4441ab7b180ba0826544889b44eee84c0f3d5074d26478c1889b4012cc94f54bee24c1bfea4690871184c9c3397e7b36a25cb790b3b4f2912d3e355b5c49c73deaeb6e68c2fe68c279f4a075622a52ac4fd49dba8389346eec0ca8433e173fb2bee7d6c2892413b6ab9401a4259d1987ca3380c062fcb8e62bc2562ce99edc5061a3a7634b16ca29e8ec807da519de29eab3a1d8b4bf2d90e94d9280d69d8aa3046476d10af87e1741ad2b08661188634b4f6e596d955be18eff5ec23ce0ec018a6d9bdb53692318f5266cccffe721ce013350b8f34d4c54e549da84a1b06398274a152428ebb5add253587aa0b25b0c6d5683bc085942f56f77a09d5f03c29c158ad30cef93fc7531ca190e7652e2efe8f13f185141c0018e48f98c15ead1ca673accd716f6e3169f48a0aab1386e9c8844194e3c175e05f57dd884bbe21efb460ce894321defa8155b9bac77814dfb0cd5952664c06006cafac7316f690738693e9e2bff2e273af24968f72fe7c7c544953e54bc8988b9e9488d9b91467b9776d6dc14d0dc3bf303d475123a68bbf14244aa22a70161593b88f95847125a9703e82290916c5b6d65a6e7bae7beae2e07f18ee66c2b611ad1e6dc3a604d75eab65afaa3db40e773219c6183f6e1b3a7a4c7c84c76ed6a6a6ea7a11258aa2288aa11a353659d45ae76ceca2fa824c5f730fab9cd18b0cce32026ee4ebef20d41b5399c1df8ee3388ee3bda1910bafebbae6e4ba0f253f9e4fae992e2e8009865c43155ef3e347f6d8ffd87ad42175116f6ac81a92478fa68bff689251c85f230ab98507017cfdb4fb40ff7f5dcb0eff5d8fb300041924d1852d82a08552047687795c2928a145175f37a7838c530627596373e303d7d1e2aa21a37531e7acb356ecf3c7d35a7b85464411a191a99a53b5aa610d925347505a1508ebaa54dddd1da2636fdb5328582ba20926910f219a481729d191d9796780e763541ea4513e5a2ad1122d8d4a9a66b79e344e04db69d756b56dabda76752ad59c69fab967ebfcf643883815ee8710691d100da94b8b4dfecee78e862d990a25659fb3ced3d11235512a326847d9db133dd9d169644fa3d3a87b85655bd6cd3963b37fb9fb58afb88d82f4823aaaac7553d5c861ee4a4557aa95ea5af14156a9ee6d194f5cd7cde5836a03d7755d97733756e4f999f63df86fa0ff5cef85643006d1e4e01e8e1e40a522c66661f39bd5d92ecf59af8b5bde139ff4095bdec4a1987ecac950fc496a625fd2232715e0d3beb62dd01b8dba4755f491f8d51a02716f840251263455494dc345da8d843811235ae7237519cd1944883ef2d168f4987a4569d6a2c874a6711e001dd3316811fc64568b22bb1645ee0ffc7c9f6cfbcc19ef743a38e2e7b3849a2a52f173823cb96e063d3a4b02eb01d7389c0e2bc8af850cce164e0cdac59190728044132d22c960e8a3223645418aa2288a62ad9d1f4c1ba0c8f33b5a9669dfb1d66e3ee6143e602214f9b85e080f293a72fb7998f6825a76b83f5da5bad7407ee0c7ba2258868b4075f48218d4757e1d9b0ef795abe97c77b8ac6e71f30495fdd168341addfb121a6952e8a9892909a694528a67eba3df4adc05479c2871a2c497cf3452d20ca5826b65328daa9c24a4911494131393c9f484c94d3e254ac95af156cbd432511c984c485a2d8bb24b9a4c319551587346e5e20a5df8dc3e685354455d4ca696a9656ab54c36c8df72fdfcaed4d5c42f158d59b99e78a916148fe9b28a19e3a4542a954a792e219fd4674fd4c55b4e52d99469cea04adc85e2c0549a4a53d932b5544b98584c399b4ca4c96432994cd70a0c20b40199265babaad86d0cc3b02539866f080df15f7f6d13a9a1e44dc6f2f939038446413748327d709236ee79dfc74fe96dadc66168cc0f3537b4cb51ae7a24ee28cbb2eceeeed6b29a39a736b5d63410f7f5c7075bde344dd3b4a7716d730fc7d542d74a69571965c6d7b5d61e31abfdda3d8d5f208caf8b3a6a9cac3975ec1089f0002214d262e9506121d77b6f8dc145fe0ffcd0f4efc075bf7ecdbd5173df723740e045188d829e73ceee401503584b336248dc7b2fbeeebdf7d2eb567bafb5b8de8de534978c4c4a46ec88030799d2c8ac7d77c39165a426c284c9e19ef5c04c5d92df3bfa7e942cfe74b807f381e9f9f370ef0324989e5b92ed20006814a0a8708232423a31b15fe9052253831ee10371f83a1a2c0f6f71407f1ef26bd9c1437efd1ef2ebaebf1607f4d7b2c34f2490beeeecf7a41225914824128944ba3744ea187177afdd3d8634a626c9c964c4f675f12b810411a2dd6ab28cb465abbf6f4eeedf98e47104e2030022b93ef83a34c78300be3a031872f6f87176cf823a3e903e109faf3e8d8fa036b9974b2cd94734943503b5d4faf9d86cdf22feb40de4b5d85246c6fbe914db2abb2bc5ad467bb04b353fb00efbabcbba161bfc6204feebd1bd5a06711797d265d865d865d865d865f8a2a2827d9354f6aac3322ccbb22c4b6b5fca184ca04e27146b0a9395125594d493d309632ce5ca329f33442efc099281c4b4f8449c928373c8669c7d76b91b7d5a32636a6af83e594c27a793a8042b419d5a6082214af04dd2de93b34e18630cabb141dd40ca1778d049e183dab60ddbb0ee31fe1504e6fe911a615b66b047d5da17952f68d6da69a7c51d1b5bd3384204492484d664145d3f2f900f7e4377b70f5b6be0e694c1900acc21b7f75e5c20bd7365ec7018eb27db699526398d27c8f56ac2ca8a528a1208655fc103d58884095648018491342a41c2c1109c71f45e42b4c385765d2fb9862d642b10d7556bbd735a4f167d5517c624d684d32a8a1255123207d5e48ea3aa474a2bbd51a96846158db9c944594959b8062bf2a42e2fc83a8fba786800a50cf6489be8aa010e64e0a655f6e80a3d5aad3b8ee3385e17e785cbc0b6dee762528fc6e76f593e9a61b08690b135c3bec4f45cc084a906a37164afeb3611482881d3a3ab464db9412142134f89d290bbd3a0b134e744067b341aed20f7e0e19edf7882f60ba533d4d3c57638c820a6251d6cdbb6b57a6cdbb66d1dcffbcf4a6470b63e70b2b2fd56aba58282eadce4a03a76c86053065b01711c4d0e387aa8b1b9f121c70f9ece6a73ec8566ad9d765ed8cf8bf1cda670041654221f42d0a0c24a1465ef43081a56c84288487b2166167250240aa2ad6fb801c4e1f3cfe14f83835540a72b420efd10419d3316490f69daadea97698c942fb81ba150180a3b0c851348c04d08019309d38a9950088970088e1234eebd84b073a75a6f46a50b46f7de1fe4fc00ca144d9053349102711f3781918c93e8fa16283214597c6837eeeea57a363e3428a24b850fc0f8c0a9f201111d50aedbc950971c2e0d122a3e70b27a3055d5da9266e4de712ccb1d9f4ff9293f234ea271eebdf7ca9052d3552c91b14506272902df8164361473890c2394423bc4aa6d35ddddf1a9187bf083e149624badb5f45a0ce49f18a3753cdcc5ffab3b505fcdb99da3c0052600030d683b546050426b5c8d754790107c11da71af2b546305061a8b00df9c12c5dd2f56b7680c0de70c28c6d7a45a0330258bd9635bafebba2e989c6f5c1de8e3bb78f8879f86ee91420a84843b0a7d5c3a4ce91e48451cdbcf4e87fbad0b627b6e7bae1b421404f79d0c743e3f7d95ce67117e5af2803a201ca2f6da6f8f3d2b88edb5b7400bee2ca0fdd65151744ca7d0162d411a8496301948e4e11fedeffa9a6538e6873b1ede3474984ab32830bfe811cd4a352bc5eae80f2125d13d275e16de161e0ed6c562b1582c16c65e8e62db5a6a69cb58eb323273a63ffc7692572783657e166152978f0a191742768cfd6554f6de1a342a5582d184c5643585848275a94bd376bd2297ba346738b144c74fcba7a2fd8794431f7dca074d29b207f1cdaec8a539d3ff83bbb80fee6203039386ff8c06e60c77ee060ff7ae07bb74030cec9b9c0e334aa67d373bae86325513bb8175ad2a92c12ea14aa55229c707f740aa9b39c33327d5cea6811f43a1b2ac860c0e3452604c92d9c74c4336b96d5c6419b68d66ce601f27e348c6e29250f03fee36f206c69d4291ddc6fd9cdd3daebfd129cd094992645ed180a13a94a8c5c0d62776d0597d630c04cfd71d0e3232d78533a4858316929648e2e93c264a85802924896173860c0ea4e6311821b5bb975d204e51d92d2832385b94bed8da897da23f421f6d3320cd39ebac5a5649b4da11574b29a55893b06fd29ce990c6ef0fac94c126913e0f88b130580eb30a50c06c8a0893c6942839547cce240559cbb08d524924128944b2f6a563857befbc531445ea7934a48d628be258924183eca1b73c9bf8b1ff74596eac2124113853b7033ff5ebae676022b78c26641f0d046708a70cb7484b5ad2520cdd7075a077832dcb39430cb2add124947a61e2a16c5032039939ef17e2de776df45b88d77879b1c1061a3eb16c510740684d42b69f13294d454585eb171d667ef4c39cc8ff953cc0f96cb0fff8b3b7d1402dfdddca402dddd574495dfc4b20ccdba1bbea5e0b71af4527f93ff1092a7ca08fa6286f5996652903671cc7d32a8a1255123207d5641ce99c18ff77163295a9e99691e971cefcf56559d6cf910cf6785d374a669fcaa8840e7a64c968040008405000831500001800068442a16040302094cdc37a14000d577a3e805e401c48644916c46008a2903186190288018000019299425500c62fcfd202af25a3cede476926b63f2a54c0fc9206d818fc040159cf0a4f6aefc8f07baa91e60ed749d43d2b2075d1742bcd3bb80fa7945c6b03d62f00a582e2d7e383ff660afdfb19659cc6015385c8a50af437bcd7837524f7e494b6b04eac50e64b6d2bfa44c81c8133c6b6b6e73ced05c1a6c24ed55d67c4e793a6a61b9a093193f59769678b8a9688a82c81b1de893b294755e589a146de29e630e9526c64172833fec060d2124d7fa25cf39990a45895a744f0967917d7c338afacc4d92b9f99e2f1427963fb6d07bbcace34e5bdacc0d7fa2d28aa0865e6ecdeb93f5f49cd395c52ea42f19c6a8e88b23f8427b54f294d5953230599815eff254d31dc54b89aec8180f0f077c75465fd946cec4cf1462a94c23935156412b78c13bc3b0c5dceab9ada90ac8ab60db5aefa194ea07c7797fe8537843952fd2c2fcfa626275d37e31da9e4ccf61327d44dabe18340429de298001def786b431a7ce3484191777928e9314ced8158c3ea8e836b83a3ac51886c4e8d470523b04b12c0e8dc2eeecde12a9cc60f7b6ebff74d1b80f0527e7c2677df060728f3455f7a41ec225d68c8fd8579603fa9d283b0b1c37a7e5568a19c1b3586e2830b848d02e99c4dddaca53fc844f1a25075c611859fc4e19206d7511e6e3c024201e88d02ca61076ff5210056b04017c2c22a71ee401e494bd4f7f985fefd0eaa0e459f1b64a5c723c562ea632c58793adabfded5ef5542a57da5716045e64bec5801589356b54dd105eae52abd44ac0d454f65a70cfcdc7553f8844295d833232334965459bcb2bb59dc359b221cc1e6541b33ba8bdd2994ec0e1b34f1aef368c5baf83d472599f6467bc44adc24ae290a6d0b8a8ac76bf3d42a0fc9f668b18bc958f481124b044e07f00618073b1925e58c15c162a9b830bd28f0e61c41b2629abac63472c652f087b0676e3b2d85f830ffd62ac5e22d87846f368b9a357c2249ce95e10fb9080af3a98176a217ff4d3d00a6e4bbc6cb81877c78e0356ccfb560260c3eac23fa2d9664fd88a11e08fdedd7cb6ec92ccd8b522a1d41008cc3c232bb64545679de519890597285d53b2671ffdbcb0dea41897c74d49caf1341b38640217cdb816821984cd168191389176c94cfeb9e17e068949687149e541f57a3f69ca67466f159c142a3af050b1549b8978345f8029501125fd07cc395a18741557f54496a191439f69def98e4ebd420bd64219404b58f3c91af362336cffa5c9eb0e42640bec22829b772c9eede40fd4903d2869df7778f7ecedd5774f4b100e746776a2fdde95ca10a3feb74a75ed01bccbd4516c332926999679fa8951155178a92b9c692a0ff1e3bb012689f538ffd11e70539114f90a13b0da116f6e3c87c8860ea453c91c4518a98921d5c6162d4972b74900ae45fcd8753cc61c5370c9d9e11ded5ad755fe3d0732817759f78221afb637ec7c57e3993e30fd67becbf4ae2db726811d0ddede8ec02734a435f2b192e4c8217c0ec681c956644890b25453d4b6bb720b1302676c43213334d24ad2b627409b327d1bec1ee3f06fcf0cf2811089ca9eb4326473277dc27d2523161c5617e954bca0df6c2a9654d1c3c4ac6719087917a382dc680231256c87b822c5a9e22c8c20d0035e542af3649632d6a533983ce8842a5e13b6482689a6641792c004890c1f19842737664dcdc43b4dc79fe6452dad542b3c48a7ddbf4fd26ec1b3b4be258c89f982de888620b28d7aefb09c469da0dda58e9282b58092d48f7e06fb59753701b436c87777b513159b43ce6aa785751a5b7a13fda5703f485c159a418ef0c1cb98b569e23eb32ad5bd151c5a4f75409c3e966de62d24c66c405825a5caf780d4868827bbb2efe6ef83e3543fada09ee8acd91b92a9b0a426799ed9a2b40bab7a9abc3c5db38cf3fe312c2424237a6ed5cd106d07b71e64f297a4626c30f4afbe78e2325258c0087b639dc9683ef76edc4dde00a1a83b73fcea0e18651830b82d60940785535eb302f5506faa736f3df332b86579a9a462e8880934aefc18270b8aa317628cbd245e60eadf848b366b064eceb7d199d023bf3f16100a7b4247af47512ca48b29a84359047501d7014628363ab2d0c0942d7f851b8cfc5375d3a63dad817a3b8aea4733952284530a9b16fab7827aa40cb3a437d74f5925b64dc5c9ea6ebba9a5c47bc79474b1cbaac42e3d8e96c8eac84225f706d16e113eed66a1b265f84ee753c6521a063f4b09ca749bb03cf7caa3a76c7f69e8b1f1fcfb99dcedbb67f5d3ad68d2390b39759ea25be59ba325308a46b3023a49c08630957c34f3ae33cb446b0b5c9b5e9526978bf55862dcc9afef56b072f2ead393efa23f8971793aca9c6213419acf51fad0cb2b6c17993ac0a27d94827d9e38e3a8725b527595ca7014cc4496c734fe964eddba4eec1b5bc25595712997d68405793ecb08b2cbaaf88c396dc02201d1baad3daa4ceaf59775714fa3cbd06802c95878d0f3431633bf964fe213e9cf56e1cbea79aff2313b56781c3b8dbf7e13aaa0849bfba71b82643208a9f129918a03d868e86987b589aa90fcfec0b7c3c4e4bb58691cb1b64593e2d5d923d4ad3175c5cc0f5173beb928e59f8bb6840abb9f8eafc30ed483b8fdd9d245afff0c2ae7cefa90b6d35de87e1e1ee29d862cd3885499143fb27d970e85722c5c52cbb3ebf78ad6d0e58a9cc5f238cb86d06ddc69ee718b9286c15cb7108c70aba2b3e70a0a23568e62a0943c745060c106e314443933b9a5e18adcfb1ad909891b11eb136071dc8c5507267982866d613a0ad7388ab6c2bc329d5ed826cfc012a76f19c9a3988218e8294067e7c5dbed236ceeb30619a490a95906d44546fb7fd59222729df91a7a510eebbdd71ac0972b124012f970c39b4159582f8f0850e028d6fb234f1244a00d7d4bc171e21ce81ca925d2e2afbd23d4a56eb6a5023d7193fb1546da43da033abc5fb0f2f2bc3f54290fa6d20c8bf6047381407fad8c58c7a92af6d5b0514ae1e97e74670e750a1d0d976830681fcc6e292f87305515ba69d0a87b0f01dd8436d5a65b0d7dddd1c1a4353ac00f33e38446398d9f5744f1deaeeb4e2e164462740eb0d351137a8b3e5d63c9362a538e21928fed3076071d05c96d070ceac4705076eed0a1f266c64a22826c8cd4769cee50b3a53303fc4a5bbd4e210c0d2645487d0fcbd224d63d8a5eb6be5ea590c1893c18a1f5a3c2c68d287343f743bd6d904ea00c0804893ecf34395237e5372b59889ba0c9d1fa2e302d13c2e94a021aa63df3faa3e80bf1eba8f27120e25845ae8358c62998a84a232c5b43d11a4f275bf5aea2ec8c1bab9842ea2614ec2ee030530a52ba9101eab409698f939c7e1206d1aa3199288e860906bf12451fb6a486c9a6c6bbf9bd75fc25246bb6136bbcf4719ebd4212226e7b97ec531c84c31f66904e631171ed4d55c2d0380c682eb5f7b8a837f3b0ccc8dca8ee36381b7f5cc9267ddc4051203afcde2315f9d4f4612538025cee70a924a19ca6620035decde70fbf2ccede068b1ddb27b9edb09e66d03ed5aece4938ac49a8edee848260b224bfd6e7962d97ee60f805d230c8d1dd279911c49c01ba0f7a87b04075784ed76de05730e121c45a9043a483b9a235152f0964b3a2878527cb45ebce69eac7dbb2ad2021d8d3e9178189e9f73a0b671b28a2384421a7aaad69ed778b30e8e077e63a7173e756f25240fbe40ad1e69156ef56843d75efa0742a11efea63ae4d076295fbe6fa481a0417f63b7b1e5eed1b5628f40e3c78686b2a31587c1be4a591bfa28626150f583d0bde714e8ab8c753552a4f6ab55f77010a542cba9d000980deb78a603befa003f74ba29b677d53a72da7eff92310c0428693d5ee7fbe99b32f5d4b6fe01c78a5563afef4336d82e1e2214e2db9389226a958270abe5b7264cf60315f5925058e87bef5637502b2313265f7a7d268c1bb5ada9008fd6c01da67c69980ee4761022d52020a4e2eea3a905fc41783f12068291f85803b834847ab62adc49313ed6f52c87ae37eb8f5204fdb9699cbcd6887dba04511866690ac16199ab8cc8c7b0827dd10608367e664cd177b3758d2d1d3a2bb8e7ae8e62175da57d71b007a244438b459b49ebd2aa139882d373b52acb6852b1bf4fe480a6e351d3a6847ecc255e889ab30701322702ac1f31cbfaa16fdf60526665a88cd1ba9414600720906d97969b2ec9cc8dbea16bb005cdd17ffaa4b2eca181e279fabd82e3734013b7c862760ce382162675d95269bc90612924f1fab6e883ac02697a89a58d4e89f567a4373ebd3bd0bbd279d5d20bde63ff24dc10cb2fe235f7a5c3735f09c3529571ca80b6c9dd9b078fa726bf31555992765c38c5c6480a32da180196656575e9bc1044b9758bce811411fcf7d2f79b2632ba4bb46e4f9c1a949e19f07684770459bc3546a743fc4daed6874e254238b7ec78120514ad4e40858343c960ac18ba84ba168b793da5daa2748615689ed5e1f8d6b3a669b61bb2c0755e472892b60e97f16e0e08557544c43e12ebeff854cdf4a867343e8c32c570b8549879b5f3e323d5efce881b44d5298a23f8d1ad7e026c2df0c58fdbad2a1d1f57286163fd8faf0414fbd9f38be581b686316684b50c2a5fa6a54e2b41462f21a7d503f3aac04aac67c142060662c32aa1273d0dc0f8fb4499947ea15c2d629b125694007e3aabaaad95c1c475def01edc2243c1529e16f86c6bee1cbbcb233b38414f8f800c2ed772f81ea9a89a67405e8db86dce67ac1e266818a31a1dae67ae4f0053697d01f3190302d1de03d40a878cd722ffaaa693647f36581f2b4427c7070a17948e194be98e3eee1b62663f5c03944cd88462c01711e99d943610a93f2351147d0e02f2633a9074efd3295c7f0fb9b3c6c1994c911950e2c2e8170e98f0c85656dcbf80bcda19af36be7951e1d634b7c154a5861e3df779586ad4ac54c34c42e00323b66e1c3f6ce7ae6688a4b7aea13d433bbc017a036ec43ceb13e264e04141a93ddb719f9b3c41cce03eccdadfb9e8ba4ab95dfbd3712054ee8c846cab5f936aab94c202c0a2949f90c9bbb9937ddca230fbdfb10a35fd5b6082487f18eadaa173926a8324017ccf81574eaad92f8ddc70d4585b75e34e82c643d70dae5a300e26ab120bebb5a83c12917324849b9b8f1c5bdf154af4ac99435cb445eb02128417149b91c116081bda59aaf18140ef2bc55207ae028835fa038ca06210bbfb11ac43c50a7657c687a24508b74ed3a693f1a174261006d245692616a5fa3618ef21138a308bc0b946efdd1d8fda64d15e9256b637ad0ef58f0bd7e7a0982f7ef138555a04b57c695924fbc242f4c9acb15afa8416d5284f21424517312199d119dde35c73bd8625e7a54d7d266eeedbadf38b837c9fee88fda35690429069b43fea9282e84d47117a465160878ac87ac67df5bbfa8345a3f86fee172bfff0c0a2184e9914a09b02dc3d5e5f9aca70c70c4db170e68cfa030975008de8a28e2e9b124792d0606fcce338d5e11dc1121afcb516011f4167a9f56430654665c78ce470fa902e53ae49807a477eb9e6fb4e03beea5c03eaa5423744e0ac17d1abc548ce8989854726e764ac4b1c109c490064d77c6ab5d3f9302370a9143a13824f53e13288f9d5b1da91cef3031d3074afd2dbb3cf4a6d7e9c13bae16a0e108297d07e69e248354e6d527f76d9a617475cb14085ac564085c80276dc57d4b6a41031a3feab429dc45e61b3d19abc7582622174e7f81d6337aa97ca672a64d5562679c80d9dccfcb8abb6397cd7f8527c7fbeb5af40ae8e64b4a278b23dfcd0bbb6030ae95940ed9d30f21281fb21abed9ee79ef14c78dceda006d7b6100514d9da46ca952809d4d42f8ae722c9dcbec8f9365eaf22820ac3b907dd7ccff00b164bb74fc3fb8e26ce70e49d8fbd5289cbc4e3198515d2e80ec75eb1f728a6cee7a557ac117f0cd8f189c55134ffe12cd95da9976b9dc750c1b48cbb805f6e6a0e8e928d4cb407eb2da462aa9deb1c0ea86a0a5fbdf9528b5af05241d8519c745ebf80d00271df256a2969e7c6a0be9c8ee8b8bba52ae4f9b12b2c1f7e1f6c6cce1241beec981d945d15d3557a61078c11cf3f229e81f670ab09f7aad3bbc055fb5d2d3d16912d8ab7013d1db96cfcea00e5d10f5c5201aea9dd38d4823f563839eb0e60c862e46d7f228f75acde2270c01685e8994854fe83ee3fbfe42350f4bec63245bdddc83de2640a841670c1e67965d181850347ce1118bc8e69f630e7036f374b6f382e7a6f5d065098bc505d3bf725c4128a4ef7e2a06facb1878d8d2db970ba5d807040a4a4e7d5ebfaf993092dc170719ebfe63cea2f025a64dba471b110192343732696ddef6f38e5fa7e8eac7115758fb971745998cf4e0736073a719a537b3e16d89e999ee0f0f244052adff6fdf2cb6a84b37b71ced93c9915bcaa99f23b01f674cea1600da4f57ed62664d4f120e8da4a1843612b108688b5938086ef15b7e460a15bbc0978e60c7a087725c212cdbb0a062b5d93e5d12792641c4f3bbcc128c8e6ed5ccc0851778ba5861aa36a35bc8fbc4caf891a2fbba244a7d76994c7e7fd1f2cf449613c71b72f16ba0029fb0191e93b45261e64a74832ae3c1ffd1982e5ecb7157024bafd75c1e5812ddc30591b09fd2e72e95fcf45b060c5a2ce914234cb65d1acf974629f98f274ed0903602a73a6391f4f6bf702b8cbd9a18a4ac92b075260403941e4fd136500848f702375294b3b47ef6e78e0499b33e4deb9cb658714d2219cbb93f422d78fa87f17553eba3224871548bf275b646056b6514009fb8a6032fc0e9409750f177df7f303987bdd75cccbab3789b56c794ec7f85e6fb232c4de00a4cd6e03d8ea308b25dc3dee58fa5762708185c82bf88278b96d8e305c9453c5b830103dcee14fd87d1f76da413cb7a8cd30f2e878fa02eae90bac34967f7120a7379d0e0f528db0382a694bfeec64f772e546346ff0170137718ec7d2a33bb4acf155a03f18eac426612784d1ef466f4a258081482589ad54204e5997f3e92c2c1b08190ac78fd80aff472a37ba9731cf50f6c9f56afe1109ad1af84d10bf5ce63ff9c609860912d3b6c06ee193d855de9ef3b41049b757f5ab942cdc0df858e16139267780795e100e04503cf320a1fe06e3a451719a441e40cb9d0e78dad4095f62094a27b7b437232895bc338f5ba0b4938f4cdc406942722940c851e5cfdfc4b93691bd718fd4eaddb71d050fb1c37cce18dc3617782509c7175bd3625fd4b0d9e89606eb7fb2b00a0ed54839804260142eb72a4477fa1c331734e13798affb63729d209edbf4a50c4ca900a98bb4a0f358291ab785632966ba14b57b92ad73e04fcb49e963d07fa266dd8a050cb1d6a95eaa7c18a8c225502e5cf8d4bcccf453f5998aa177e5a5a53130ebfce7c7d7e76ee4c6668412a52a044d6fc987dcc133df96880185254081c738184688e7dfa69fade9376b03d5929143d3e480eb9d3d79c42865384e3f24eca2294d5a8dd6947442cd3ee8c2400cf18127261846273c3362956c65b11a2ad147e658006d611c68fd564d557e73e988ed819ad84c9b5454455adb63458d31bb7d121ecbde3e5e98476d89485bf05aea48ac27112c4c6e1dc68435c69467617ef027f76b7f65ea0cbb34b5c44ca0d8096aeae18832b541f515cb59bb64f6a08f7d8b69314824368fd2f081db48c7ef890c3b7799afa9d2c18201ab1b2202f2e42dc8f672e13f0c9a2be755776c3772181490b98ebe09baaca3d6f4b3a64e93c74803dd2084e34369709fb7f5949c739727af81c1707ff4cdb8dadfc8c00814ae121090c48a9af2bc882e73eb046c1e26b042c46dc3143ad20a78110a0704374546e3884b8640a5b06b57ae60e9600b574d4838281571522703b89a54526930c68a26c3c23f53946535c1d93cb7dc2e21bc772fdb4ab067aa14da4b2719be6416b92c707a27622c55e204b34085a743f77148d6a88972d6c7c3d7b4ba2600a1f59f2b959927ced9917331e3b8e5cf5fb76bf1b2cb3108bee4ff0d0a7d01a882d87e30140c61af2d3212c971f7ce678084e8eef547e0bc65ca54431a0534cff6a4826982847f2b6a8662669b9e48064c6a7e7ae0cc52ae6655518ba5765a7d2c57f4a7c3850dbdb2e5b8f657820f72dc215e34dd75d49c42454afa42b118ba87e195d562e56c346d57d4c2da3f5b094fd492da6b96b41737a2e632500f8d0f67f53414132b3bbf1f17b861de0dbad2b0f1299f402e538ac08b200b901d054222e08f4828b6e9062094cb11f3578de02b4a15db227bd9a111416762043725c2d7a533a518608a0a00ed3608a1cef5b5b0cada9dd7f4474236a6561362710bf3350565a1d7dcef49c17775e161c3a720fdadeb4f45696ab530aad3fd4e190227d0cab95f0ef8553b98f6875b514696f119c0a18c7083336aa63912d980b351313ecc3f66c27a4e61462ee23a0a7303be455d81a6b5140fafcc1a71acb192b30a80b3dbb29d737b67a2238e9c7d8fe553028ebc9726f6391c81a88f33a83dc9e372dae6cfd756ac34336d1cec50485f887843086f90d11b187d6fe9e68062a59a86e14f646e01156911e652cf54cce7ec15d98bcb68b0402c29ef3f8b2ae24669698192896d29aea2beaed1fff9c63aab186ebd93b4557db92ba813bdc8edddcbec07112583da2333f62e6bb075bc12c88f7c87366230b7ee84a3351ffe7952f8c03a0affd90a56745a28dd8f3cabd53a33b7d0e5029fc6af0a8f8168b1fd4364b1c5e2ab7fc0a94a2b4bcc7904e3bb3f58d139c2dc8c5e92a334222ec27a10a1cee06c18a2bdefbde33645c916d10ecef3e38994ec8a8494c2aabe934a70cda2b8f31e1649082252aebc457394d42cbfd0983ff21625ae9a7004aea66aa6c3b6b70817d1bffa9e810ea5599461276c1afc51694fb9357da37fd556fd96de313731a7e92ae2446715380694f9f8f3a652b8f5cda16db33442f575c54c7f42ef0da60bbc456c8a5323a8c410d10b8a134a49954a0c1a6d7cbebe91463756f0a526aa7b369438a8a6f9c8110a68433f6c35097176ffa01fb59786f85ef4b2694518afa5813668c5222faffad826b97ec92c8b0739989096e970b366a2b2fefde632f3e199cf492833be9a54411d9d78c536022ce502ac1deeabbd86a49682275b51ba0e797c18fe92708457230ce35cac66d4701dd7ffcdeb316fe4522f27a3e099653808749ad7d87c7518fa02fee83c10e1067057961f5a4725127e11a210ff99d0f9065629632f4fc0e82ca94107886a2f40a37731c45cf22c160962f3d59129142d642263f280a9571fd1127679786cfc51b9ff4b9f25f0d3da7b2294c84f3024376cc0932069de82f3141823447403e555fa6e04d6511272cf0d2228c98a2749be9ccd2c0292d060e4f2012278271f012e2c32b652360bf6e4701fe2b84adce4a3078dcafc8cb8474215346293afe42439bf02cc3d0da7d92979283d6c8f1370c68f286441858c61fb266776eac6f8dcf2c36755a16f7801bdbc9bac2d4492e6ebf76efe88df38f0d3b87e8c4a3999236902fe525b2db33e36e666635380697508fb3aea391b8978c6aa6585a3b3201beed8a582167e97a90ac9dbc75a6513902f9cc9c80216ab400eaf1e7433c306129641faec246b2826fb711a2b0f5a0d7da4bf0a249e5c8ebdec98ba026563e0b81ee30ba846e42d01be1374026089fa1e58a7f3900c1d04e11d15307900b4c784a3fda73cc3bd8ea1eb81bb8b232613c6fe6344627336b5431e11041e9b5dcfca3955c858101333642a04fb71b99172035d8070b5315a918c639043305f214c083388abd9900203e62c52c9c8c3382c276492b971746b4427865414beca5f1e2610ed5a27e9aa4b453083c5652ef161cc04f1d49c3b6ff5f40444af49ebc71e15de033589e68c5b982e1beab107b85793864a084eb38182c94d0ca268cb4d59c54d93be162f6fa4025baf51eca72dade4d00684ccb84fdee4d5d6ee3e7c85cdf13bc1ec699dfa0018a6e3bced9868757a34e860bb38475586ccb3177fda5b6fdc859b5600580b531706db503f2bf55a7416289fed1c5e877baa0f37871be7c09c0d0ef7b7ceb1301920bd49902f834f0ffabaa2611f08230fb4d2e7fe6e075c0a1765e753b899b6bb6a5c5a779754369f7e4ed93ba8bb5bd4cf7194b9580d8ddb60ce85da4e0bfb63faccb5d4778750f2eedb84bf80c3616f1f8542bea8fdbc22eb978e4a030819d8d705c0c4aaf12ba3f1abe4ea7316bb8a3f94d0e694fce11cf6c935530474e099db288d3fe924b72e99f64aefc04314e637a57454e930b43060d314e992b58148d3fea48cf94663b07f71ab7f1255924d261158c472bf0dcc1630a642afbd931ab7d19d340c9344aa8f4daa86be9bb031a1ba52f730573028c50dd95fe8e7447d39832e3cc2d5aa740196573a802b4b9b70313b173f0d503bad24f0fbd689e06a401fb7771ef79d80d88dc4bd36bd243a4dc198646261176094746ad89fa779a74dbfd518c23d95335cc6b5299e0d6467788452cd09106a3bf62e537faca88892f228851266b1c6343248853388634e9a733005a145c6d46ce45f1921a120864c79a9e5c4ff0a26603e681341c3bb25bbc16fcce7fd242a904b81271a8b07c4c75da1fc39925d9baaaa8575286035fe5d24571ae28c0af6abb6c96171e6bfd9c4ab18527bb2d018c6efac2764855d70044cc800b9ede4b6b7ec38ef28738a21933bcaa25d105dedc687e8b8189650eec4f5d1db1dd32ff0ecaaabcd16caf445bf47d88261c2f869394c525e10a758e30999ea6eae752dc4917c6d1deec71265482f4626aff6845f47be3527caceb76c1153b235776be5e6d2a4a4ae63c21000d750c548477260fe0891eb1b9e9f1bff3bd9de9ad952f1b4fc3cb47d12d2dd4da2e585fa095755e56e2c9b6aa40573bfbbc6f1a0a34871e358454c5c9faa2908d4b50bb10f403f1e381b35c9ebb39d00aaf58374b4917498563dd488e341b7c0aea43de8f160de4cb5c2a2883998f6668a48e9e21d96d04f8f07311f34efa84c37040e92591d9feb84c23f32a7d7ec04f35872b51a8438a9753ce82171e73e0000f2d7beb6f236f2ccac0f548b1b06b4a254df3508dbf3e37aad35604118eb601c0f4a2296ed132268a9b805be5a5851cb76970ee3385bcffde98f07bd7a968552abe772ed5dcbd45946dcc5f6cd302ed6b8570a31f7d356e323f12f77e24141f7fe9c76d60dbaac3683013e17af1318282172ea45f93eda84fb338432f4cc5d488ccfaac24c6eb676c8be18f9a2ddad0c7c02bd7f118d7d49c669fad6fae566fca49f9d9adb279d4b1e6333ff0610e1e253d632e83437d359ecec21d3de502f2fe217923327761663d93a7c80ca6c2ce5993b71088ad7652650605e8d982beb012c9159c317839d61d64a9be669f10e85d98d582c2c36af66b5bdcadf66ea4de334682d559be1555348dfe01e8ca584793797476d32eba446061bc900a050bbd3676c3974934f974a10d3dafe8630fec658cb812e00bf7b81586474b0e25f3309bb501781506e676da8086f2924888cbb7ffbbbb9df2333ae069acbc92f069e56e916ba901b6e9d82067a262d6700f085dc5a802dbe0e99697723cccc2e77526c26f15b34efd455aa20374acc9b6114c6a64e36809af56de7f30e72e3c1b27f92f1ffa46ab97bd003f0ea39ee3e75263c072aa9b567572814d68a0671fe698c82ec6003f6dee5943232214b76d49e39151f3069e13c8a378baf3b4d1d08e0fcd63e09b8c333703669bb65250270f60642dcc63b0eb78bec38955cac4db336834fdda5a419e9352c371372cec4f59928b60ee5fa87080c7458df60f82162acd52c531970f0e3a8394d1fd6ad860397afc96c67c400ca3f73f869f892af4b1a046ee5ab321e1f65b650a76e2ab4ef6ad459b23600150b76b800d6d88d3b36ef11dbb710024165580b33fbc125f073b4e6462a4d2b1a58f4ac0315a3b5709f7624e63a3dd1ba468739dc167c3887b3a9ddbc456e12853aaf91cfc9e2a2259cacf0c5794b6ed9f3962840f5418c6b772cf0724b6d6e3c3da2ac764d404d5e308313cd56ee1f455c5f79738b885cd5da77ad4a3e8e2b33995aef7c456d0a7f5792f19c840e0fd9b67810e2f52d7f503870003c3cf4d7508d50e2b6c55e5b93849ec62b24bc929aa822e139c9b57a6df12b4818a15622cf075f32e9eb4952e6bb9510c109e4608ff6931025cd02bd96d534175587fc4d3e281ec845f68dc2aa060e94465c30bac79c2f8bab7cd2b096e3b2ba66c8f9b18ea34813e2e172bd55d47ef937194cef571262da86eb9ab5b32d1a317e196499a093181a8ffea317296b928df806c3f6b39d64ad6fb8fc8a78b16b1da3275f280f95b13021ea4740c91bc8dad97ad2fbb7b6b2787745aa5a46106c7edae4f062cf1254e8435b535f477dc9f150e5488c20d88f0473199146c83405bc8b5507814d8811dd049c4430bdffba1dc7727fd5a25d5cc547b4b36d52a4b4cb2354dce4100ccad5b59eeb53617671a9c6bedb62c6ebd901743dd9061a73286ca38b830deffa0166562a5b61fccbba29db1056722ee328bc16b77912e85b3d807c41b0d4956d295c6698e070645823240216abce102d212b3ce13a24ba87c5ddd6ccbcf6238743943edcecfd462828d7c2ebd3be4af91e738c60686a334beae5266079160d4aaea3cf278132342a6909cec0090eac12b2eb41bace7b602b7f4e23a7eef8ced7ce0996b3b9891bb51ad6f799985d6850c0225452228c159eec8056261ef2ad00d85bd12ae2b9c5e2642bb2606f092c714ee3c9cf04ae1e4af59d0e0213975ff9c2de2281884701a08c2806e3e876851db50256794bbe278afce23a36d95b7474a3dc80a0f7b6f64ba8d3e82f15fe2ed04432f147e9180561ee837ffec21a1a13bf5e304d39bfbcc6b0c4aaa71b315a4a0f7cd437b090cc280ec7d860fc7e6ee35315ebb906138ec05457f98b36530933e1d391c424943dec3701995ac57221b8a2fcc90063d8a8d12402561abfe833083b300c6bef70d9d53d1b79eef8ad7a91b95e7f1d810071fc6dc24d44f18e345bd4882f30d4d186a09aa3cc945293c33cdd60448b93432aaf85651dade7d436ba4f0e77a8bd038eddbabe862f7818be49d9816b3316eb08e47aaa6ad756fcda54138663c37475ef6184ac38125863b4066babe67e3759b7523fd551df3073cdaa10e6aac83c075303947d746e0bbe7c0d73ff5844b7d15a45e834601395651ff71c1fc2da244af3131809795685e3d11297b38f7b5ccb9b5663cc2aeea5664959d8d65bf9daddb1b2ddcdd87b2895b241a80e22b326d3563c80e56a769087346bbb94a9fd96c989f158fbe28377ea9f6b55684b4fbabbd525399ee01a086e08ff5483f33ecd062dc32b54220315d99098901ca28b3403e0f89a07a893d67278a02bd865366f915f1dda5a7b2c71227c5314a1bc59e8dfb2aafcf87e07433d25c54e9b95a526067e95fc40b6a6fe4bdfeb78f4606c5ac4ce2d1becc716dc2c987fb919d7cdc25d395f2b73d54c4cb6fae1351b928086be2694bbb87e244bfbfe15362386db0016d7ab02864a3ca2aacce0e98015cbefeb3a773e7ffeacc296df5c579b3d0f07052a1b9f48aee5f12ebda73f79b95031bd48f223c4b638f8d4eee87fb1ff9cfb295f2977cf8f269f9f93109573ff27ce7e99b8bb31d79d9ed602181829515d135df8744601e8179f043a86fd6cc057b06fef9af34ba30168e46e553c5b3e0fcdf9921db8a1a419f6c7babd0edad46408b9b270e863a32cf896b3a1ac7f25992fdde4579bf7e95ee1cb161aeaff8af849c32ef86009005829537f0a521ca54ca16886c3fba55476b23068d7a24bff95c6660dacea458e1006fcc4197d6b8bbd20b77f6b14bdfa37c5c495a6c5b0374f8bab7622b56039fdab072030eda1ce03d6a1330e0d33e0046d4a70667c273a5c61af4f0b193b896c5fb99a68b26f0a7b442001ab48c9e5fc04464eeb386d3947db3e14a2c38c7a25186e75330c5a816c210b3c65b43a6001f358bc0c6d8406832c32ad5a3002fc53b65f49ba405240e31b314f5aa1fa4dc9ee366fa7e0c4b4c5680672a4b709da37d2c9448ac1b8a317428590dc47429ae841e25d718682497dadc2044cdc57540a0c67e6c0f96033ad7ed71b48bc524a129c0a4e0735a397cf0e51e5765f56279c2a72d0dd1d59247f8abc64ca5d0519a691b710c8d5516f27b1cc6930e99243c1971c65d27414a9c34579269eb13b7ebc4e999ee7cdc39dcd3ba037af9eda42ddbcd9d882d2e816f85b6e7bea388e452b75b7841dd859f25219d08f479dde74cec802e86c81624cc7229137d0979b3ee3342fb7f949b9ae9fe467489b7b756bed08764e7221da1abec729c513bd42693470f36f84c8205b9e793515d70b8618bd0398b6ec7599ecd8c4995e481770d848d81b6a1d1384646521155f28833fba10cef0e603ab91a2ee3e0e0116b3a7685f474d41122cc947b33199d6262ad28b06047715a68ef2c94b329b38ce8d9e428e894c0197cc66e05ef783eaece0221a2437bf60084749f82e3fccf9e779e129c49f8ec1624134fae6852f8bebb967691ab790385e6c3aa4a35b88b9fb1c6d167b26a43e6d10c3ead4a79a5eaf8fb68903bfc5165311637b894a16a9c34eb438170f69ca781d6885d6a09bbf8bf0dab88a38a34f75d0f427d33b3d2a796156bc3929b30efbc1c1e06e226cebf61795a52104f5f95d470534bd0bc28bd19457a79a6649c7625820554d2ab695f80ca0c708f0cfd0e7d59515b81bfd9b0758fbd2b9d7bc1b59e764466416c7ac1cfa87320eafb891d73ac579d984a3a6d41d82e671ffff9221b7c57edcf2187bb0b2db16e0e445722a1dca40c78154dbcf7536cb2527d87f4d3b56604b63640b6b3978bd10af4ce70d0608c4c66c8d6260c8c802e26c4df85291528d6a0c5097424aa31a680df5ec9a41070144f342d30c5d8a4148283cfe5fd74a4a5be354baba5e725078d7d563fb4939b36681cba48a2ff5ba201ae93347547f696b5820b66e436c0c2731d895458878eda0d6d6e440d60ae1dd3a5d34e824b9cfa96dcd69e8329237df73cc6d8be2becee34b5d7edc53c9503a44138031a9be24f935b8e3defe95a8abb6540499a91385d55545dee69321fc1272d08e8ff0b8fe0a17e653f0254aa1f7fa368c6d4d5de4f29dfa8ff4eb976df7b8f554a571b34aa371be258ac0bd21078f044ab5154c9aa10ed56668627ce492905a42feedbcf234443820730740fb1ca9993869643364dbf4b4c6ff4d92bee72e44fcbeccb7f731f85d23195fe8015f0b5816b8290fb37505751b8868c5365152005b97705289c65e7315b5b69f76193c4f6dbb69fec77be5f305bf426917c0249982589d14a620c0685b22191c4a6365d17b8f92b7d3ca72c35f42ce9af50f627b0029ade625b103523a367a696014f20ded1862fe0e33ccb19092868b48ebb4ad43969951db46390c6940d8c8e80d74367915a7780044ac04df259b3db4c7dbeba6e6f56dc61edc215b69b283639aa5981de21d14b8a62599a0e59538442442b2235b090a1c5989d4687fcc93b9eb0c22ce8207fb6a0389ba0870738319a125d6326332756fe54bfd33f9973c0c35e91490469c317536ad3d848c878711dc1e52952ee89b32f939596fadcbd27145407313520dbb32e13c5229e35f9b857cd3d4604a8bbe63cd4cfe9838774a5d3a72063812d1b66e9fbf1591ea449964d4fd451e92f5daa1a5fd6e6e48a21a4814247ee3ed4e763511169e06f9c197fe00ab271b234f27f993c0c8011d1401b3c3db4754ce7a3ec6be141f91efc5a2de8ddbba7804f99987ac9cc8da33607dc479de58405843f2ae6ebc8533efd97282c32de3de3e835afa38d634d1aa87d76a9ebb0801e421959959cc34efa54b3cca73927fcf653b56de764a20564f4feea9a7a7c2603fb351a5934b33c0a278a49cf94a7822a52b35c4d70899e6d1a0e7b384553f4416387808b62bf3766ce0eedf077fa364347b031024044b52034989abc811bf4126830bd443ef833e5d92f47b1ba082a6232e46cd3ed6dde994c71ab76827e18550cee24921d0f157683a711cd58ef8afd3b27bca1f97afdec1eeb2ee009d895ea9dcbbc99c3657c7328ddb9258c1a347edf58200739425ab30d9c1ae1ff84bf291e616f5b16198da5f74ef9c1aaf881ab447b549e7ab1486cbefe1ca097e79ef0b868d7a501c64c178a7756f7547286aa0dedad17b2bf1c4d8608588dea2b765f6074d57e54dc95030e1a8601650ac749c9395b254de1a79833ee153339322bf006b01e7a43a4b15441857e808593d775c7a85587b56937194434a089469f741a236258cb04a3d5dfea4079e9fcb2711a1dfe68c3bc22d150fb499aaf431056d65079029454728b086999864e2e7fd1f968f72d37ce77601a727dd182715de56e0b79fbc661e66c289b0ad74037a5e536958fc95eaf2c36ea6504917550966164b5ebe2e668ce265135ac4b5c949f9fccaddee62f3d9e5905a91abf536bcc029b51dbd38f8e01cdd3c414975086a2124e23ccbb19818680b2d896a750999a9b34b826e45b95977c74981cd0fa9a64bda3fcd5ca96042f914493b8c8172f4e6558594275025dbc90509b84c5580809d22cbc017b9f923bd1c71b845a928bd91ebe31a50af6e3a9f38d24086e0f3d00688c88cf8b4ad315b6202ee7cb25674e5823ee5f269c7c281bcb207ac90438a56ec79a5cdbce21861819b798c98d326da3c06644a4870ed890150fa72fc24067cc40d02d856ce689b315b63d1c92a1619fbd9022bee6a94e88c25209fe68446a40b229005f70a4e45b509bc78fcabf4b0995ccd9e46d9058ee6e0acf26349a9dc36324903bfc6001880736541f402c5d40350d0e331b822d84ecf43295e28bc7ccebd75d1542a6b137bee79bf053816251ce6ce89883b1918e6f879f1a51324801c53b3edfeb759a41730f928ce53d70eb3a01608931723075b9030503eb38297d38f3b20a444952e7c4054a0971ba4cf911ccc8f3abfa0dff23fd170e0cf0ddab25f5ce308178be9678a6f7aaee4b1ff45bbffd4e1fd85d9fe92cbebb576bf28851cff3924e5ebff27c1fd184c37d64fe767f71f492abaaf7fc96ac23cb479ad16c5bdb4019f4c84fdf17fd2ef546278f4c27f937a7c1bf053772a53be0e7886572a930ba9a9cc55be9190a61a23b51486c4e6c901dc17a6eb4e7626fa93a7051e22163f8d34ff8cb2f151fe5879fc8ec3f09fffd50510b52cdad8cad8f5d317614a36048f3391ce800c49bd09bb91e90f47091f96fd59c1a5a7dbf47ef884e14bcc756f59815555016fa8cc0dc3fdf9de32af5f64ee14ff57aee0a26cefd51abfea360c8984add837d82b450da5cb2cea355f7fe47b63fb196b8bfec78be2756ce9eec2cae5802662eca7f98303388efdb864fd1640f6273d59cf1f32e1d81fcdfeb30e66b9cd800f5a33eb1f75849a41fe574d2c5f0d4e0cfbbbd35186c238f2a7f064367c10594038be2e51cc942037a7c5f2b1a6866239920277ba1a65e7a60c4a23912883c430c41a09d8e62aa53795cea2cfb61624c836fb879a9574ac9ef68bb7fd00b5f3ca7f94766e9c9a7e225502fab91b99e0b8ed631c1ceb84ddb012b8e93836fbf77fbd56001b1f8b18b61a43872df64e6a94bb90c13e32541878b96ffcad4a8ea41924ef319c0a65e6e068b7317be246a2d1744682bed142da46dfcf04fc1656829a733f092bec40124f0027eea838a5409fb4e1fc1b8e1fc245973fa6c53fb9a9661b0c0f9e1ff7536a92488d09ffa3c1b5a1f0a4cc7fe88ab0960d04b17b4d8f79bde38f0b2b24f1ddf30a3fd75b853651b4e73da1c840a1f0fee536fbabb213292ae7b1ed40dad312024338167b60528609f15457ae7b6941e8ab01302c72f6db288ce77f7161eb35dcf89bc84d70d36ee6cdd0ebf1c6ed077bf5caba58ea497aff1d9b3bc4cc9802a7b4ccf2f125482d6e0d1c6c4cd9b43fcae01f82c0562a8fc3be3fc2e534e939fcf2aeaf4aff5b0cb7aaea70a5c1480de76e00c2b35b3a205851ff1265490d126f0df0614250de7dd3bee49b0b39e673f2e4a62cbd0dea0e1f0421cc345f63afc80dbc51d1901135342f71aa1d2d5862118c869d050726d2ee09fef3e1384078a916accdbdc7fac1bc9e4042fa26fb9fd80551a75c67bc8b28c6db6072d070f54dbbfcf7bc826fd172fb42ca356cb4c4a9761107e0214e95cc482d756a342d66b4b6618d976349b25b263d2ec79b53c7d439cb1bbf8a68d0bb0ad484246f111a908c2be6adf43360fc50e093c311deeaec42e0c5818aafccc6c815d3244d88999daa4257510c34b43eeebb2a608b674e2b3bc4c38ccf2659fd923c0ebda89cb2d767b7eb9dc727a4899a605b7f5722bb8882b280ae252dfe0a925dd002ea5db098bdc349b2d9a57d21210eb44c4f9961c7f89d136fb095f9e0cf685788fed0e2202cf27780eeac7aedecbd2568d63627683ace9f5b6c69d8391a6a2b61d18c967a9c050ebc93950dbff161e59cd6f843de895d14f302161659c0018c49e36cb7bd39bb81a8eeabbc06540c5933db06a557a904a3f9c56d9d0786e4118e1b4b53eca846ae0212f930d863b8738af580067a3ee5b6c6ef1a64c1c27215324817ae8ae9edd62d0af33f031de707c06431e6e2de6f00edd47958444e5e7e7de3da0349f4670a6aa1f38ed2300ac7aa606d111080b2695042cc0f434870bd3bf710cb5255fb557f71ac6957f04684ad49ac63ae19987e04fd0981f4930dfafa236c39610edfc18040e8fbd7afe72dfe70a04597c197fb41d998c8449dfef34e650562586b6d09a1cf9610559311b157de674834e0b051f0faa74b196d14074e5d78b5ac6fb2286efa45a9a1d1189ed4573fec3323dd514af5d0f5de4e4affc147d2af527a69fce7b5376a90a4d86678ca62e56f5cb250fe3796fe02ae90c4865677b9874c40ace6bc288daf987dea8c841964cc37dabac6b5885e52234433dd6b00525f3dfea2beebc068bff9f6fba915231bc603b87d7a227dece951b89e2c2057babef5c57559efa59b2f7677e183d53e718e978ca1df9137daf4359a884937b40596392364a48fa217255d2180817fea2d3eee3352533e66b8c561aac40a0fb33c0044280c7059dc11cd783222a481a0cc3cd85d985b13ac204b790a357a845fd1502e9ff07ad4c1b51885e1a2a374748c00af687576219f57b49e8521f7e46055b6d1ca53111570d217560686c50c58615b78c04c1e217d69cf5d5966d6a6fc20a0b5ad2d5c541750704a9a072628af962b36de467b563026438d740341e4d359759609402c1935ad60eaf6f99d06b02f8781af16b0cd381e06f58745309c882490170d5f546aa9221348173440a0a8f755f335ddfb2680a1b6975d95fee57ae0990c4714abcf53f2bf79bd03e8a8e8b09489dc474a958b10e62c9992caa0a5e96853d7f2c490eff718273224720119c453ae3cf13bb8b151dae622a1406ec6d2b00913c26423f6d3ad5f16ea1f1940363aaae7c989742b8530d7ebfc07c6cbee8dfb1d7911c91f1b18e570dec5182dde7846af6ffd200231b46629dc0b791cc674c0568c9e4ea6b8f86fe1ec81ef7ce5dfd505b78d36764fbd5d17cc2e357f95e38e885c71d3c954f17dd6209ca7d83975b9fbeed37dfc13966708922ff9e13ceed8baf7881c543790cb87f5d2f80643703c35c84351cec52905dffe9d645f08bede8eac7b3377119700dcbecfe8850b0d07b1a710a90190b66965916bace8ed1d34855886ae2e0b0ec88e0f50f61730a87d8a062fcd810156c26a3611373454756110286255659fe2515023ac282c454b70f80fe0629c2a5353b1802d35e33e619e4e4c06ff81420ba10bb08d31ba1ba20e252ee90ae239cbeed027d4af5f06cb7482ccf30bc254b19ebcacad8b580c44206ed0ececa6682e8f7ad65e77a43c663103b3dc23cfdcda54e48de000473fe9d6cecec9bf20dcd05e7b32b3ac8b71d522029809e537f61b796e185dc8d63e700f03c07e997dda89672a6e4f6eaf9058f0fb884ad6a6d3b8bef13f6fb76da64c2c90233b4455769bb06b6f3b7a91dfd753c986ff6157f6a7e653d96fd135e32b39aadab067499268eb8650fec8dc0261412928500763aaab80224dd009827262106a2c900a6273845a42bd3d07c5cf9f21138a82eb3b7b2be3b7c264ce752edaa35d423eb374da021dc2b617f189aaec1a368202bf297fbb6011ff5c0157e65cda8750b7e3adf2536720b8cb94419bca4a4ac02de87fc9cc95c1f64df8f02ea3a05e8fc19f85d63cfda3c9257231064f9979553bf202ed6582d1dcf75d8ab168ecaa3860cbc08f1f188a72fc24754cbd51fb5fac4f5bda78107b25d034480fa370074ce14c2f98e31a6340372b6a85b2dd7d1c10b65872871a8c89bb5b6d6291f1ee8c83118fcf4c6876d2cf246139e3c829f00c64132065c272dd26f5ac72cece4568586c93564d70375fc7d510ddb0e60f86a1f0adf11ff636dc17f622a87faa8226278d1085022421aaee77122a234588227dc00dbbe8c6066c38cee9bda5a9e93c8593b917ca05a114fc24e03e5775ec6095f9036aadd1e386bb00e4272617657d12658342e3426bed1b2278c556ded8d22ac052084371a8558bc01933caa1188ad95843ae00892f1479aca1f8e0c1f94654fe6a8e966fb04ad38c19ae7398c83f0b65d8d28d656215ab5ec576a3b6082e9125ca956472edcd6a12502db97b0bba51b225cbfc2e490961f3f3fed7880fa08b59aa3175cb616083a360c89279efbf5166a5c151d8d7993aa16adc259eaaef8c919bb1881ac1a2c0896bcaa74d5b72bb06706a6ecabaf198a65b58b72209d2378b9bea7a78b779289c2ec7254d75c3544a945e6d79cb32f42bb8a4f0b00434151163a3a4d593cbbc6426d369380a067151dc55c3c44113fe7b1e8da9612806087161ec3c75d206ea41feefa987d925e7de71b401fa6bbade669e311a6bbcef828393d468030486ad9d006611fa4aabdbb8abe9ba4aaeb9847216303cda8076fbd851cb33055574b202204a0c3c2c487b8dcd06b37c294674a88fc99b45c6469ab17d8585d2d106407b08eda019babdd79f360aab765d93f407d2f46c367854779e40c571bb6e430fe9930201960b2bfc186d20616637db5bc8be8be444fb7c952140884398ca66b1e00319a88c4f6b36451b2c899e79d3f4a8c5d5eafd4156c28b2ea970200342957ad083f86c10fb690b3b74464bbdfee0b301fbe685ddd420971c29401349a7a5e61a7472f3e2e6d676ef9ebbe86ee1cb50fde19a33ea892cc59b4222cad73022a4a917b128a7bd6b60622979bb85b2556ad77a382574afbcf15e4265c35577811ee9148a5989c3870370ef610b364f21914145a5122ddeb6f87950dd87e3c3ab69dc869e68481ae43b4fd0b36868e06a391770e823e6ba442b8b8453d80d2c7088bd6aa039971a91da348582c4e51fa7eaaa558a09d72d0cb232b291826038f626a44e4d0463751c787c021f6f0ad2dae04ca9cd1aa4d2466026c8622499ef7346d7fccbe7490f2d9df3442051dac959c7d784330b081fd3736317d2cb69ccfaa5f43e554e348a07c7a095eb4101278aae78b6991289f71e3a2357e21c2fc2e0e793a206011848c528fb79c64f53f219d9a6c5b81a1650908ffaa9dc7e9d7ac07c647aa10b15a8fd9c31be18ce4aca22f00499341521cf195c24a79cd18a2afb1a332650ab7802d8d1fe5baf5f42471019d50091b5ff0592954c789db462c19ac469a16ee40393b308b58e6f35104913ac56f5bf340e7a4d0dbae945c56cb7e0e1d9566febe127029447e204513d76f5fdc4a470be7917d9e972f0e2afd2430052b0a9f4a2dd4669f739f8edf1917bcea9c4ed0079fc420fc25f83879e54cfe90781411004cc33676ef018a598ccd600acbe051a3e1093ea39ee4d1fef0718bf9540164a5be16a1d48fb887b09f902676f91636cc4d9ee83a4ce38032c88dfa74628a7b1251732d4ccee2cd4ccb1ccdd36111bcee342406ea787c79ce397508e5fb2503af2b040a824356724e30a502179bb8c6a336c3371d4fc658935d4181f5c1a793c8f89eb10cf53ba5385894efc739781f1cc15a12f910dd0cb5fe0430a9ad4ad9e4569ac71aef71079484e34082b2df19e760f2a821145f0f7048d6f4146aa939984803a547d77255fac21e1c2ac6665f153400335f81a60630f396225f3e2c7465cfd14e6760b20e9d6edaf1bc6705f4cc8cf575e2c511dcfb48c8297d7e946c67bdbdffa73a0207c97c0ab0e262cb5a7c0b733a4bd8f326439cd44a81de72989a25a3d10853f3fbfdd1650b725039e2c57eac1650f9b10cc4473dc3a04ae8f4c4dfbb087ea1c1308b2e0fd02625aa1b514395d709b3aecae19c0c31c5d4c0283126e959efa474bac198aec8a1a6c53052b04857520e8bdbce80c7f34beab607e660bca8bb97ff423e8d1dc7537b1ffb2fe2a115d15c5bdd556cb94fe4475856c94c9e296ec990a240a0d331fd0536d0722cebe172aac5afaf47f25e366b9718e26bf79987f9202a9c829c20745c35d6c2e852c984ab202a6d556dcbc04de62c74ea6ab2212241bafdce3345136362a721c1c5c2019b6718b0a7e736e5acc00333d014d7ad6a56d040afde47d361f19c93947b37c97e24d47655da3327a9f594e46c9f43c58991718232130a546c03cc0c81ac3b12e2361222ec87ae6b40b951a126ee409e849cf57c5d66555399ebe38e0b95e8b2020b79363c5fbdf73e0ddf2d0f86165ed56acad1c83ffb6a1192ce5941e28d3270113c5100fa50a1ce683430c4301531c6e7b1de339a102f4b0e6b6db4f23b16b3fae68f4426b151783312d294e22f330dcedba593582e6af622e1fa298f97de5d2f9be1593b7786e33ecdc2a6ea96b036d7e882fd37e39681fef2b7c0ca90f464bff5e2a1933be6d8547859e972b94957afd0d0695ed206fe0b75fab9f04cc21ec242fb26c8c09024949feba9f5daf4012e25b6deeb4f25ef105f223b0c7d71fbfca6d43f5663f25c5ccf86c15670b0434c33bd77cf31563bbc19106981a6557d2e29088d67c468b07edd397aa99b1a6424687092c6ae79045722b4215280d7ac5f07cb1180fa0c91404b1ffd0c0dfcf0b41d1dfbdb1dc6e2575ad61f401f1f71827f541f9cac859a20b6e699450c1813eea20903b01bb8c29c003e2a4fee05091ca637f9e1fad0ed0227512a2a36bd7e63aa3f66b388bb52611d2e246c9cb591142f0373b06edf2c9fd78b7978f6783a1a7f090bf18bc5fad13bccfdc237bbf7cf2512431cc7c5430f313f0fd7d4884598b9cb2f8632099dfa4836a4a99296f0b8a347754e78c3e08ca9216a0423366b4e3067e76da5298f5aca1827f1d4bad6f03fa2db26c1c2349f32c0ba210bbcf835823c8c420880a0c8ab1b4824158d21b1cccb65b6167bd85c21dda6e3e50bdbccd0888b10144041e8674e3036d6a178b31d18ec327ee9a943954383479c93fc21a8fb543065b21654a118c13cc0f2c34c7889a633f4904931d5ae0d2405b973605be9cd9fadd91536d990f5974d7970239065addd0db7ac20f966b58c0cdc9f814d94e6ad31580f27424b7189e1d3b7976e03d52238ff767396e1c4f92966747657b04611fd9d63fe2e0811485ce948c095fa66ae95417786cb8a647c6074dde996e4f96d5200fa995f495de60bbd321bfd2ae379cda28fc82506666f15e7672fcf57298bd7c4b90f62d4ff8c2c8ba5ff6d285714264c6a6821324f29d794f9c40a74abb0bad2045c327a35cac25c12a6f60f64e035be2b0b92fa2ba60f9e53e183229f99d0b399168174bee85f673526349e43440e568724b72eb475515c35feecc644627f181723da4c27aea1a9d9eac2474b71bd45675dc744506bfab468cf8a0dca0b2b01c517c37ccef474b744b3baf5cc8658444a1c87c849f550b08a2612abaacbfee646a1bfb6a41759b1a0b44c0de52b38311ac897d613c277d5efcd100404515274294d4e93d9c1da388c9def1ba4b5fb66c18451f11eff5a5e4b25f62257a84f12aca9a08de493aadde18408532f7646c6bc75071a17773b2963e8863a8ad04f10f1cbb87670858c9773ef6195aadc4062e7f996f310e0f8a4d4aec1a157e4fba89a2646b5ecd292a75c1106a549dd58f3835089d5b00e074a822f49b00a10753b5bfff2b12d574d4e31daa9faf8a9c348e65b610a61d3f22769962ab6d4a853f17c532a59a29e36f93ad5c9db2ecae4ecb64e59a838b57e599d04719246a41ccf12cd3995bc7766229488946189c972b15ce6cc5924798dd989f05db20731dd2d2cd1f20a94c1063bb75b9e4832d7e84d6a1a4de7573e5673f217bab3320e470ad88db461ef4a5d85e6f00d782b8db003be0c420cccb532a782b8608a898f451c96fb7b92f3129d7a458547f8a928e373db2134f70a36f491a42164b162ccf162496645d1d8d9c4158ff59da588825aede81c172a59ac534ddf4a873793b168c1aecc059d8b5dabe17a2b865b1d32d0dd6ff646195ce9e5f07f684ff2394ce5f6e7f449b19574bf66df92abb02ace7520c1a4444789ee12abb63d8116024c62c7abb87e640e79ef8f18d96462fb8dd631a940e300c2ca9ade500ba0aae6152183d96bb6403537878613454272ed7867e19cf02678358373aecf4b66571b0f83f850b5a7c652e674ec8269e56348e02be54ccb12db18cd69b23767e7269993eeb8d8c5279645ca11ccccd3d2fd1da18d5afcb718d96750f6bc590184d1854c8ed27ae2798207ab7c2a3ae29907e1eff4235f7ebe8040cb990a7051891757bbc9593d08699c76d50ea016a7aaad68870448f34eefd45660204fa03d463e1c6409860edebcc3a27cb4b508ae45cf2d2acfec0d91f51c4fbee0c1bfa261c1c47d152ea3a7aff3a8f065a3e6b192892faf85a03efc5b5d6336941fdf590607ef8acec096c22f39fba11a00f6672fb08ddd888788025d740039f11758817a72c055ec1889daaadd3e73baf9df1625a0891e750604b302069619fc0036ed6c53ee25bacf4ca31e1fadd68c77ae542f70dab8826b00ed10106a541f99b5f54a5fbabebd0d991ffaa927fa78d560add28fe08fbd66145349c2e2591ee4aeb1dc256fd4ab7352f44310240b89fd3bfdb9d289fc9d437379c36058bf256ac3a63483b4e20bef9252c8484766c03d68ae5acc436ba65662a80b8ccb08de04fdb449cae5ce49c4319e60f5ce8fb4972ab858ad2e602af963f92054348b38249379e1ffabb2df5b9c220cb702f92a7062177efe5bcab725c5e53943dfba69f310f71d429d497d96ce300ff1bb5f551f305fb3492fca17de04273f2bac0194baeb838bb000d2556aebe7d40c31255ac6536af19b34a8a3a040718dc58f167d3d16551c87a017f87647a27562ef4830a5c0430b673508dd90c55260248731939ebc4bdd7abbfe6e5e081fe0009e79371a580ddf7e0717cb251225f42b267a87b675ddad92aaa3753463bfd230b8ca0421a22e61f57bc33b0d0fa1a2524643ea262cf51251f016a331f29ddb3d8749606f57fb6584b77cf6b90f742b7c7b4bd0c0161db3b173bc0ba93a8f554e5f09caef6ac7e5139112a92528ea04e0be8099047c3e640f55db57bd8969c0b7b5a99feefff4d60fb8fad07eb142c21c519129a669825994fcd0acec5602c9d0bd3b59470f8b43d8c0b730eb4b5dfdef619b2c01729bf2d596bc9125db0774e08a742d1a6cbc53f436bc485b1ba429198ba7cb428f9bb216e6efd17b20676218157afef3f81ed0734e471f72d90250c17a8dd75614ed910756f64d01f59be57060ab23c484d8f196327c48346d1929ad0cea5c8ef4e918a2584c625ad33ceff46f8952f4d7607562ffeeeee633de6d7a2fa421ef27a980da427cff4d45f5962c1a70d6b89b8ad58852aab47af230092d01cd60c98321b4aeddf0027da7273549306515d914fbc4ce5cd25c43ccb5ed24379381801557f19e1d7d2e14ee0e256d89ab0a422915727d16cde6dd128d9d03d11b51d5c69d7135534ca6aeed8e5b05881fadbeadafa458af811c91757f29e1cff2a0c5e12ee76c5f5ad9e80c4d7798fea8bee7b8a3dca2e66e4ae3980c203378dcd52172416d9855a0d0038099755298a1ae0f0b86acc3392c5eaf17c71bde76a3e32f3963e470ae263c00438661afe371977a22442d9b837b99251b354b08784bfbc3e21cfc5134a2c68a94bfc1b8027819581db89aa3763b775864d27c978fdc8746b1ea82581d063026a2ca293561a8b1c0decf1076a18aa4fcbe73837f959b7ca8216874b03103fe1a43ec22340878ea697d5d770bb87ecabf7d56bace48c11aff6a9b08309cb341b7539e3c707fde42f72c2166a044824360e24638c31065ad1b82692c0521a8871ed51ac032dcce313f6510e0a4160ce97a3deaa8e68eb900d87b7c2726ef86962376a7e36186fb9175607a6aacd97b7c406c367e85bf8f9a6355da3e167b538bec7bd541f191b1d2a0176dc2c4832138bd293b54c93dededf8410af2f72e0e37c4e033f3f8980617a9e2f4341798a5ab15a798d1660d4028dee75adee4d0af74649470a228571e9d94b594981a70a84916add37da6026c110e9bfda93072314f35a18f956a49698bb5fd8d12cb481e51ae5dbef7b5e53222c570be1f9955b4fc03d825b4061e195b5ffb07b9eeb3a750f40e848b817fdf24694282d0e17fd0fb860811cbc7565c19fb4592545b8fd971aaaa25aa548479b6a5babdaab57ac836201179f129a1333f085388eb3986fefd370dc56b88265e303ed6c0c0c53fdf443d9502d28835768ec33cb110f7d9dd9ad3f01c39d6585f8cf0b5d2aafd279c421edad415dc82ca599c8ac29caf5d6435e8cc7f9a52ed4cf5ec25372c543812469789f28fd8d8d96072da1262fc9b892ca149acd93dc58f18fdcfdf45728238554a64821c356a1ec56461efa9926f4a5e509b7715c341f4eb15237c60eb4c7e2b41340a0450b4d1c0173e7dec2bf4c0a7248206192cc37916e860be965b151587766cdd785fa005d0b20b2357bf7717ef8e240c619e8aa01c627b16de979b3d56cb8191983cdddac1893911d6b4dddee1591f6a01126d65a492b11b074415e2c07590dc3f015c1182b92323d2ef456a1abe24fdcbc12cc4f17b7734be358be389844cb19537b0527a42cc7a685c4bef8e4fa2991f0bebb45d38ba4f3f44cb51b3cead60c764fb02760c51dee1e32a3bb671f67585322e23e86173630c0413383e7335d77df0a96d0ad6a6161aa14a4d4815a3d7f6cb74c4337da781761fa92a77e06934966e735eee1f9340410151d5de5f0247908ac95e60d67ecd78b9e0794afda2c47ccf319ba1389eddd974eb73c23cc763b884de374cefb9060dfa5ffd031ecee0b1119600ce1d2d069986bb1f099c0b036b1962c54a5ab693fe44675bd83850079da9fab5f3a073af9cbc2154779793ab22e7225a272f7dc599386f61ea1a2c148142d37150ace6786b2ce67caf2fb90ff46b99a616fe544088d99d43549b818211980f5e374d0aadc7b38ba7162aea7e785548cbda4ae85fffdbf7afbbba4384c634bdf9f97d2f1f5bd540689501364980a0e47b9e9985154f91ff9407dc2437901b9ae648fa30021fc638ec2af60846bf3123027f2bd07e508da449c3a90701a4536e0781313defe21cb11482933251afbc50b9164c01b75f9327e7ba850d458f7c5c27632f825c9c4585885ba9f735b8ba78c2b56740d6abd9460069c5d02aa71814c5e4010424e079c48509fbd9d87254ec77dc26891177202d14e2a3955c91b46bf28b6354fcc4f99f5ea70983f81cd73b51d11e662407fa4dede007b5248697cfc3e000c01690dfe98597fe37b1b3714289b67ac7dc86f7b77db724b99929429b704f104a80477766dec707148a66463078f7b677776efbd3317a14c9d973017b219ac07180960383c2d2ae2869033e9d3592ae188e082f2c4154c18d8d431ddba278a3c9564aa2ae6d9e83bf2672af98ee9c7dab1c88b8a6e2fbae8e26c36b3b163cb8cc717fa640bed2189fab0042d82c160303aa444049986408623f758866c48b52dd2e7ad20b1e5615e248aa2488b6614082ba5052a5a24d222f145175d74d1451769a92864a2289b55516294a468ca501351f48fc5542a95ab602caed2297acc251689f090cc61be63c23277e46c478e335a98f9656eb1b9154571c8771e3063642fcb2de2d0c762624c8c4df1b38781cdd0bfc83136c4846886bea585c5863445c533994c9c899fcca0cc4cac391363be3391c4c498288aa29128c3c58484a702134a2975efee9eb5d65a6b952d1a5488ff7f57ffcc1f49a3aa2bc4fa081b0c8e87367c17a539b42d2f586bdbb61582a769e34c6c7928d03b27744ff70a3f9a2a5dc75f69cbdaa75572b6eb68784ab8ee5adf29ae11030c8c90439c40ee20ab136c249bcc1df9d32f2cb37665eb8f9b95c8de9de04116a315118ac9623c82c631a8729c4c867f51fc9ab5be93a5a4f87f7f1434e0ac22ee50074ef0f6f696e0cd04df91220a5246ad76fb82c2ad0341e4d7a13e35a48c897bba19a48f7529a791283d294ad143a186784513bc6bed6b04293d51fcc21c9b0a10701cc7b54c06050f1ebe834307997ee5e13bd68e76a45f47aa82ab64085f69c4b2d609a5b4d24a7311f1f0f0601ef9f1d42aab9492561a004a29a53cdd0326b96bd624ed56332cb72ddf0e494e8e0b735a9f0b3826332546b20ad1134e26eb3b6b36c8646fefd4913b3566f774cd09b87ae2ca2cfdaae47e7e5923fa407804d594a83c0de2314390134ab2224231598c870cea710cca525a60c4590b8ad6de60b797b5d676b693373b4d34786a08811ea0943efd1e57e62a3105d2fd218b92d2ffff27219aa064d908c857a8f29ee5d7e56971dc45e9b04baa586d569bcd66b3d96c369a1a96bc49cfa3fc87abc96469562b666a561af8f1bcf6214d9d37ddf6530d431d3434185ce9a8c1290f955aa1c306a3b00dcb632b3e8cc23658e8c3365f0aa750df89357540d64b524cc3bd3c13cde42c57ebdb8fde99424cb57dffcb9891dbade5184b7932cb32c7fc566b6db5542adab79a41a81431f43385101942fce1808f98ec47ce600508db8f47a94f4a653fa5f724b11050f020f4336f3a1f23ab905c1784c8f94ad22709e9c3e15aa4c6aa8ff69161a45cda409eb8d29ab5dd51a5846f79625aa4a2294dd38fb5f7ce94e40d759bb7a1a10a0299705da247f754fc61be4bcb98d84bc798a69fd7bcbd8cb1623725a48c892b8845ca903f73e63b3f676f4428d631a69096f144f20ce336d80de6dc57a5acfa7f251ffa2e3ea890ffdbed769bb79c6ab3b1c1c3906e45c62f5fab1175cd03305d92268d0680182e872b8f2d1fc4b1a4945f721314aad631a495ae8d58c669abd97258695d6925b55cb45aad56abd57a28c116a19f0c988e1065fe020c068b113d293214246b2294e46130a2144e5c180e3da59340c81e2409ba2f1216ac1949605316a1425c6bffe9ffd75abf4787bd300c433725d9bbeab24dee2a56fd731c676bc51c0854bbd51213ee31752c36b1660fdf913f9d65e1e8b85c978d2f9c0dcae1ce22011934f0be1328e528e59842a5505c9696c6a5a571694ca152282e4b634d0a75023f8f86e6d6d0d0ccb05e1ac8174b9c425dd673014f2770e9f34ee0d2d2d228e5f875266b39eec32fb3349868e84629471a6818979696c6a551ca51ca71695c1a53a8148acbd2d29842a5505c96c6142a85e2b234a650291497a531854aa1b82c8d5746fb2914ed5228da9530b3657574e9c7142a855a1a1dd3cc9f203dddfde481cd719eed4cde079e64ee0c4d0dea53a9e04085940d7e1256b9111752a9542a582c52ccdb54e23a2bab54e645dc572b10a8c32b160b9b3b02949cb9f3e2967164b1484d2c361b0b162c6e5aa06646d3e8c511a9765373a52865b1c614681fc78202064ee81e19cc005be31cede346264c1daf7b4c4832d913a427376496127b0002cdac58b0bebf333317df197c71cd6a0e8140175c32651f8805fc64bc930dfc6c349b5846486ee44648b22732d993f9a4a8a8850b9a24e24c9e96a32f5e80408fa977b893f867d8b13a09674448e845786791196bd10204aad8c50743465e94aa03b9924996ed6028896c68064dd88b172fc2ee9e53b646463264b676db368b5c33cc0dc607e01750e9839c6fcb38e6c4f87c25b1cc70da6208c08454abc9c4298aa128abd0aa003819df0c10acab6b309e369231dec4681f37cae91e0efb282b5a2289aa11677d947d93f1998cb229b359abd59a0102673b292e91424c868666cc980142081505a51e4ab2888c8100020821d0a0b63361894b450821844063004ff3311c36680cc05fc9279938138b339c414e3880afbb71efeaecec804016ef002db15baea44fdfd626423718ebe880401dd6010f309be7abe1c9dd417e98e3cc3b753adcb58f8fb64da69b4df6954c9c297d1ec98bff0f7b0ef8f89db4f371a0e2effc8162ffda7bed94d96030189030317c12872d2e32cc185923e50e294676982c5b0ac9a59a8d1c6292a584c1602afc4813c84c79132365bf66912ca51c132583f8a70e8f0e08b3ece15e62c29a3a17e46e8988dc81e92a625ef85a9029b661bc84f1c0b54982041b488211207b2d7bdb9eb20ccaae8a8d62d692373f4431029bfcf8bd10f48061c10d6eb8410c90c01811213f9e3539263ffea993b22c14a16acdd60c144262160a304240226c322aacf049999d5a8879451481320c31898e636d20d2d13c2676ca6ce2346de2f494dac4e9fcba2a13b0400465488d881f375800a302e48614252b416644b622455b84dc18628c727362c80d22642a03c06e298068cd56b843162a4a64b1f242873b933b4a96248cc8d2c48b24ae4cd08b1bdc0bc307395c9a1b865c9413183029306e23123e8c4938398c4e44318a995d530b3831dc0fc90c1fb8dd8a830b19ee69042c48fac105946b734749a221d55e80b99f3b4a12521049361843dc2f7794a42c2ec4242fb0580e6aeac8562a779425885a4bb557acc8d1e10f733f2b28ae3ff247822b747c0a8e2dfe562958560a8f6b4dc04b695ae155c5dc63ffa16354faf3f3d8621d8f2d4b87e31af3a79f748c8a6b4caeca99d18aca95b439dd87f45e36b7784c3127574aa10a787dc34287fb0aadb53fdc0659426e63990f4ecab55163864bdc76f7fb7d79369e9826a960f1be6e60b8af36aae1ee3e6407dbf4e1f50d0b22aec4ed3f6e83aca1dbb8c674406a8c104c62c07de34d164bc96d2ca7c441e99dd6ce1e8e54a526b9a2f55818cf6a59ed58c2ccb087013e4bdca3d216441b524a2965ad392d5aa7848b2eca66559424299a32d464766777766777164700c8159f26122560820387d8d0223ffeec0e47bcd793c58911a70991217f8b204fe495ad159f6007140c65b9c188177e2af5916badb5d65aeb10b533042830a29fbfa3180c29c84e72e068f2eb60554858d48f2d41669828aaf9e1e57a31a2f92166888c6d26489153134a170621b00922991b867cb4930e413c116c126412bf22221d0e2f364f052d58946ac871da8816645758883511c3d145e9080814457028156d40c85864051c369821c1d104ed28880788e0606244e11544a31caad150b8d9b25feb2c094c98e4aa88b1706d6cb872051e82d89e1283a231bb700205930683c18e44d1a202203da50363a6307eb860ee285aa49440cb0b5c50b95cee285a6090e40a102d4ad0aee78ea265091b19b4b828cd224c6389e90ac79de30548dcb152e852d0414787254ee1c76311e6be46c8d415e4ad706cf10a67e998d8aed0f1987ad8b9cab231438a9d5563b278b82f55b70a5f61a68e5f2d17a5dcd13da92c318feee964171e93b58345140fa878078bc96dec49a1e93d4154eb110cf4e8b0ffb77c3c010d645abf8ae90a02f36b4fffc71d6b8489232d0f0eadf4516b25eaf6705f570292a7016d93ba8bdce188dc12db2c16af6fa4cf8ce57eefb4923f3468cc90051357e220b7cbafcf7d5af54f25e276585610d79faf62ae9a2a06575cfd5692c94a12cdb062d34a369961ed1d8e533b9b7cb2c4e7cf4be6563672a1262e4dee23159a6489714c706b721fa9600308ee4cee2315845ad0eecd7da4028c862bd325044209181db81f0c421e6e97fbc8470b4224d73b7231c68710889323372a37dc0f071832a8618ae8c3f5721ff958c104b7e63ef211a44596cbe53ef201a3b9a37499511bb8a74295c245a3e570d16834174d872b878b46a3f9d72e1a2d878b46a3b9683abe3f4551dfd5c7db88aa48d009aeb9e3a2d1683453cb90728a0aca08e1c4613b2146feb8bd132de68477174d872b872b29c9f522486fe58438e10c1180c879e9fd2d9ba391ed235bc68cc9d45d8a31ae5f07a8073febb2b56b1b756e34da08a12bfc2b8e42152b57925cef2e9a0e570e575be92b9df4d2c33027c4e9300c3f10fc4cb7939886735c2fbdd58a31001f12bfa40b395c345a0e178d4673d174b872b868341a0d575351f46decc499aa2f9c2a3c2fec7a2fbd7be68781a9232fd05d5e49ac42a680219f913c94deddfdffff9d524a29a50fb8930419ffd34b7777772ce54bf9ff4effab1e67b2de75d6c479edeeeff56b777fa7a07cc09ffeffc6656c58ab52d15a2b5d514a4998f7b3dc8dbbbb4b4ce9af7000e4631266f84e030306954c316d3c95f3a8fceaee6e4b6baabf97af1cbeb057ba12bfbefca29452fa2ffbcaa189dc8ca59452eaf8e5b793c194524b29a59452ea81df077a4aaf97e9a8dbeeb7335fb9ee6a739a46536b28eabdc8eefbfa724f2f956259777ac78425ab9b6567284daba69452fa1ed8e0e1779f3add3dfd294f6d7116f5594ae9d3cad98e524aebed0429d64c1d8952eae269e5a03ecbd9f99da9ffd27f7de03bd269becc75758cc63cad0f3cc9dc194a29d8dd327786a60675bf199aff477dcdff7f8f4acd7c3b5d4decdda2391da331a594524a2b4d0d8a529a9ad286e2d777b516d72a3357ffdf4bf1fd972b255dbd5ab955df2b85faff5e2bebaee28a1072ba7b6581edb66ece4963ce3973e6f4e9d3e7df64efeeeeeec972ef6a55f2bc39a7e339fd954657ed7dce9f52cee67467bde69c73ce39a75fd895787e375783faffff9cf596ad7f73fa4c25c5e0e7513c29ab398eda315f393a865677ec4febe931f8d9dbe3563a660cc5e17dead0ee6581ec983eeddaf5ed9873bc9646e7bd3e98d8c3691f1242fbf4c6f3f0347926fbada6d723db9b2debbb9084d0860b870e04341696bda9b9412c83db08374f4b75c3803bab9532bae72439cb8194b21e012d63e21bd646a57d35dbf8367aeac84a95bca3bf338060a6cad10c3c7490bf07c9165b9e34501d2141fa37412808216a803283211b55e194ffffc3c712875454ca01c8145b8aa4859b2e2f9e40e7883f715552c5c95083235fc28f5a95e106a2039951f10521b38420e28b1c3822dbbe8d1995109bdd2391680890a932c00c63d783aa735a29ad1fc470054a7e61a32b5492ae8c30aa5c8162063e821a1331519d1626ae787de3b5c91b00305c4e04dcea9e1499c33cddd399c31cc7610018b935b738dc608bbb2cf0e3e66648cb6a750cae95396bf220777409c575b524667f28e7ab1a8ec3e15fcd9793c3129ce1309e3a26dce18a2f873d0f3768b2d85911086fa898a24409b2ad768616638badef38b6f8face636bb15d7140826bb1c53756646c599cfde1b0b5788696e369cd90c3ab2188ec0e5ead153f9ee1062270936db7188fb0a0851147a0c0d8e182b98f8ef03074bfdc4747720899dccf7d7464098e0bae29f7d1111a5ccce0080b2e5e7069c2e080e0aab0d4702dd20b1a2ee782704603c2881035301244d1f5dc47465210c28c14d9c8600829bd69fa899a4f2557396a6f3a4085bee3d66788ec58eeffff2d27f32f4ff3ffffffffddddbfcf1de3ffffffdf29a51eedee6e53edb8eeb6ffffefee9cbbc9762050e37777f76aa25e77ffd7dd0efa9ffeffdf72efee52e6ffbfbbbbfddd5be604de53072e78b2bbbbbbbbbbbbdb57afeeb2ad34cf39a7bbcf5ebd26276d87e7ffeac5a2cf9a33ecd56b26b7cb4e8b27bbddddfd3bb7dddddd4d83a3ddeeee4ebbdf7ac773ff5957a652777759a9bbbbf707fa40ebfca4ac5fdf7274e94afcd57274cc3fada6af6368fda1e72a1dc3d9aecafaf5e95793f7b4f6f7e0385a9fe3f073958e01673f06fe7e4f9ececffda9d71e88b912d3ff80f5ffb49a68db5775d8a1b5d60567bbdad3e451295d5c29c1126696ac3779ef792b5f1779deac6eb735752bef0329066fc870ac578ffc2c1a13ca4df8815352d938373ff89dba6350fa2c21acb5f7fe0dc2ca580b42ae500d342ee46082792f147102222345e6c8080c34b2966bf04f1d1f138d23188e589c2c13832c834f2090cc494b11f80211ca046c054e6ae311413c61e445952317828e8488744cf95b1c872d132d20c95c01321d8283231686402ff2a53c62416c2d31edac90447eccc18d122b1ce5aaca15ab00816a132b5635638523f9710a10e8392b5768e48a6d40a07a332b12829d5c71aad66a73ad15dffa43ae18d72752a6a88043814095e21a2247e4a7921fd38040bf82232235cc1459f98b45e6a60643029938a8d4ec5de88e1136400013170000180c0886c3218118071339cebb0f14000f4c783e5c5c2ea48bc3a1481003290a63200662180620c410630c610632a8ea08003bb571b1b5d28e6ab92538f456f188d0a93bc2db4e411b91dfb7b4856b84d6e480282c8c87b213b860ecba34d473f9b735bbfbba91cb070e27583551eb3da938d2af070a9dea78e31d45ae15bdbc4b472bb0e231cad3c4b1669cb35b5de25156c939cf179ee56638e10ccfecb6a85f71ca3d35163060397332c2b945e7be8b899d412132c255c1f44537de41fec2f8aa318cf66b4d8990abdc9bc6ec35b76dde7ac80fdc36a53e9d587abf2f40e01e3970815631636c60ab0a1156e1d4f90f3bb46b4f06b1e5cd616eefa50cb268764122a6fa3d35d117befc737f84ea8b99db2c2b047e2f1df8604004e03229edcb7c70a7f661750314339dbff564fcc0e9c9a593a0df6f6882278635bc7ad7f242e6bc7fc8b650b4fe4b03d8bbb5a6a20cca8cfb705ff2d320d58f8250d4e15356a630b331527f21d78f0b09784f078618b31f88b506c5d3532bf9d045cc023420f54490e05374bdc7cf38d30032a38b8a40b693497c3e92b0198836f00edbe47f10128bc16a040f0755a466aa3360164d6d76a313e9451b5ccb67e7a33897cb09c30f710a3d73ad16548444cb207e87903444ee736dbef78077cd2f9adc6e9d6d3ed530e1a06a5634c4d4df1e24d7ea482951f4d033d2e2eddd15e64dead564dc9fccfab1fb39bc2e9c18b095510f64e817100070a66a3277ae0f11241a121fcb9dae7e9388d17891a97f1a180b4c38bd1126224e5b5f1888cf60c1c7c3f6c8dc5c77bfd82b912b1b53194cbb4a049af1ed9f20d4ed3bb4663028c538739f5839151ced87d66d92105c67058f6ac9c9f2c29ff0bdaeac1800e4455c7948ca6556a6abf7ff36e1a195a095bbf4daa9614e0733785d569c6900a7456c9b1520e50b3485d0470d4c4ffc09715281b1227c1a850f98634100e43b1cb279f1ef91e2a0a7458833734d31443a01cf2af6409bd49ccda11d47271ae8d5ea0e2b1df7e0d5b9e358ec19838921dcbd474a9b967b9494b4fd6918deead420956a79bbc567fa0f0f1736d0a0c00ab61bdd61fb4dae7c1c1dd7fc32c05bbc67e5e4884425336fc30b1fd3be75c93ed4f1222ea65960f253ca2846d2c0f4646142dee13f2dd0a4587877bb31b64186d40d1983b70503c40c61f9fc363133d3bacfb6e5a6d6eb386ba0c6d09ed88f1daf1222abdd5a1fc352bcd6c50ff4dc9dd38c2c09b5f1fe02413f3673684382a1dd44ecf827e7fcc956669913b75a0ae217bc764f8efb0a243667170f49b01417109bedef089cab7c89c627a9f7a7cd11493dd61ad6b4764e46300cc5ac8eb08f3b448148dd44a212f5437073bf71efff21b519d91fcd1729f4fc7684d2824d965102782691e37a21667a4a99c44e0950d4c7229be3e1faf9d1031a03029070b454a7e32543bef3069c915bac9b164dfd320658d64a7573dd8875b1376feb28e972e1266fee6bc5c75bfb808279c340a64e7c16e01d88954b8a5e38e6411fe04adcb71e5b9b20d20001d2c3b3489378b067930d9d171d2166ce7b6059692dbc6b14fdcd90ab2ada6cbdb63c0177a94aa6ddeb62a3139d49bfbca036d955ca5d145d29616274e6074620e8250891af575cbf83f6842ecb19b97a1e8c4e684d010dde9685cccdc21916e103fb0570e37e309a892693f9af27a698227b21cf152c854629ca0b34cc9a11a5b82278cab805ef2a2fb4aef2a3de8f203ab31848683d4360d87393e574bdef9e349ee0a42f7c1e13f0e620d005ee4364af3269467a237b46bda1e525da1d3df2495a4cea457a4b00acf0597da411502a56c7e9d3cc79a3f1d3096b2ee52a95aee1640880977a17450e8546d5ea6f0808b0c8f95c8815b50ab034236e2203c299503373d5acb9164df38d7cf932b14842ef4986b174a9b2e4b87f125d2a8ffd96d5517aecdc05c5158177925257489e9d90bc2cd2d0a534717bd0b2e8f6d4444f5464642f883294c9468ce820cab0c1d66012be6bdc7e47b871e7ee9bd53748e9f69a75a1895a1ead7aaf550686e75ceb529576945f464141c587a4cb3204891a18e16122232c485208b71c93edd5ec52daa140c96dd4f0b30dc7845f615e34a5a515e7cdbca068b8b1767bd0a3711205ba86ee9d3466d51622022cf2c34f7df617bf6e2ff800f9fe85e708b8417cc4e8943b75ab91e2f0117867ceb8c38142b34a2ceb90167101b8de441a66b77fd6e96f6f826d3006654bd33989cc79ed8582d574a764fff390e2e84a2aaecc89409f8dd638dbc1c3b482b9ef0f0c0505acaa620c53473345c9b22df075a3130245c7c962263f3b1911645aacfab545a1874317034359eccc515a07d2021d340647c1d7cb00555ec111cf988773c93042087c75c7cc67b354c5d2b3325c5cc260cf05280f81744499cb1bbf2556b89e3866e94f2fdcd9a112cffc07d51feccca81b3640ba1224109303432c4625229f5e8d87c620118894ce78261509d979c5a7b1285229d5c3cef4e688978c40558fd2b6350d0c15359c7e58d328a8326c6eca1802fce969b51ac6fea73488359b3c192ff8a0ad9862a79f2cc9463e5957bc0008058878fb6f122f4dbf4b649f0e61cfa6520f9df547ed9cece0d4cdfc2ca233347ec2337e9d0bb503c31b3c221c7080c828dd2b5439409105a0ebf1bfce1bc31032d85921c6443319c7b75c39cbd2729c9d510ddd074fcf1c422cd6adf9c80a7c3f4b091a699d1e5bec8e3bfab5201c630048b68043c31f3b66df91beae21889687aed006a7d745e82c50943cdbdeac4f3ebbb56b81c14922723d8f1e163ab24604b350a78632168fc3e30a1ff41d0073f52684cb9f089405181267286c475c016b33f306eda46ac0481d4fb529ed3c348860a38e373818b30e32f97b8bb124a366264276c5c5dd345b9b1fbede1ee200dcac8e02e2fee8dc9537f0c9e715fd6f6554e15ff007cbcee52bc1cc1e088283179a5adc121dc5e240b593518c8defdc1a41a12ab8ca33f19833ad77a39d0d80c2326f993ad123838a40757650782cd4660d175a2ec5195c84a008d94d24a6c4280f6eaee278807d2de44401291366e1ffb067dce109852b637b10695bd1226258241652a93be4959341cb5131f29e57c7ff4410f8551044860963b1130428e467c38a12858bd45a9504565d01f6ba0c901a2b90acd357d4e0094e1bc5e08ee580141088ea9d41bfd321ee81d8b055e759ea417e1ef71aa9f3eaa2a9d730b028a003cb997062e0cce01c6842ca64c94693d1a10ef3d0ced97afc87991acf5cff9fc785f2a13632caa1976a054221de0d73272465f2ca3eaf7f2be160f23a6a61b8a24b5b6b2283ea1ea3bf40f20c75d8de09753543dc80730bb09e6df2515280c52e3a4d0861da1ccf871f04f18a15cd8b00ed03fa5da1a527bf617a5d1e071bcb33e5f66559a8dd31801770a34e0acd35cc1882befbfb885f41bac8ce8e1bb42b18c16b5d28ac308b12d90a1c20f01c405c8e8f5c38a8e3b09bb614d92bfa3cd07b5f55ee47073e6601423ae0d1cf349a2eb1a6c3bd4043e8b156d764571a3b1eba08519a686bc0ba4ec4af54ade220078b463b1cfa3f5051854869fce246e841b834ec0683c589fb5bec071f3642bb2188dae89042bb2cae7c6f76cd42d1054316ae824c36750f883dd77d3341c56f9837ffa0c86500de8a297ab5621bc4162ac042093f2349de0dbabe6e93cc8a00978113b173012111db42b857dd4c08cadcf8a9f89443f87e9a8e5f46a5a5ea26e805729e8b8fd2053a2b84de1f9794b99dbc9c076c166d61b321b68ac2ebae1343e839d7436e9b27873c26988b3b56eed102b978223ede406d382c081d5458164edaab6c6da1407a417eb380dee5721459c8e641d68a30319bd2ab71c5487b42b07d183e763c98001f6d913e2f1a2aa269bbf0a462c8c10ac7825ded2b39c74d3e2f344cb2922bc3f61506bff128bbbab4e6a70257b0a5b5cfe7ca82c838bcdd291a078233da2638400e2b1a1a1e592ca09c584dcda74a0fd30ed18dc5121838921208750de5ebb6442a13e42127b3881d997329bc0223bcdfa30a29430c59b430f5731578275dc7a8b4e50e2e77d0838cf293122a9a680197c2e03cb49b35d70cccfc043cb5876e4176adb22f4905d8bdc2cef495263851d456c36deeb236c50b70cf770b28380ec20c2f6b9f9e4108759127261bf535613e42e2a3767e140bbbfc703f919427277591623c6141a4f50583eefd812f158edd7841af0d01316d1bc3e8631a501883b7328caf40244e9f005bf83c6a7512a4f51ee94de344602d96f05140fd769a3c351ed80d9bd7030dce6b9c0e913988a4f0b2db1dcc8feed0dd28253b91e57d19330738ee82f9cc5890617a47ad0bd3d229c701749d200d2eb8063867707fb3466ae9a72e7bec7df4e2baf69bf5f6ea0de4072a8c3280e008afe7617cf388fded2bc9411892cf9532963c4d4f0a888f743a98f44ecb7fffba61941e9989f0002fc604a06a4c00562c8462ae47d433040f0d1c90891ce0491294c4c5c985bca61919ba3127adfa366db86b6ef2433397c862ede49572217db7d3b21596af8996ab62446dd79eee7239097707ae3610d7deb6435c9bff8e6d565eb652904d46badbc1f11e393ad78ecd64033bb1594921301dc629dc529fa815df6601c1eb1fcd4439dd9a409a59c8bfba4990940a014137357311a94a5e73ee3ff18abe813048a9e0d483926f9bd68e3d9e5490b35140b0bb5e31ceba77ff8396bca321f38b385b902f493c3a5b5bf7e9afcbce86fa1e7cc3e297270f6a68952e9fabd6377b0e946901ad59895ef6c34dc4aa56a899aedf3fdc0d14d616fb08a5ecc89d2b333764c38a07faa87460d064f557512717902b37029eba00d92a44844a117b8374d5153c65346b3e22ebdfd1c20bcdf030ae244c1770ddeea3a86995bebcc219107f897339b5269ec8e7cd46c53fc1b0521b36f3d7c94db3e2675aa9ff644b4d8ec76b75d84f9f4ac72cde4a7c4e034b2107a7081866484a7da76656423629593a7ca81c1e9481d0d41967e3cfe00b44451936e111ce5ac1c2c64bffe56c05688cbd1a1be7a025db666b0d717ceac7e7f6dd15347ba1ea26f8d3221e68764904a5d1ac3792eec48b8d652a0e3fa21a4eb727717638d83d3043b3e7f4f32560439dd21b809d36ec81af37ed0b55d1b89a757f790d1a397846d84d5b46696a3bd6a6d12bd68ff7851486b0db7e628759e7e297239afcd881d99ed3234e4a13de9a74441b28c7691985d35ef3d06ea8b388adcfb0ceec20831ada9eb4e3f7e7e6dd1af5c29b9897ae57dba4e4714a3a5d391bb49c7672602934d403e6b483f49099910ee98983ab6eb252ba4267ebe742cd6cbde53de7b04cce4cfbb227c4dfe72f2d82c7d65eae4a7e3ec8cbe9afd0f97d1a2f56a1130635012ae1222b38d216204882ca83aa80131625dff0abc2feef24b82846646a9ea9ab2af577da7a720dec7a8afc11a70798c9fcd702503e217f133a1557a6aeaad46f3f2ddab59050e300515f8e4c9bb06a4644579f066dff9407293003862807bcb2caa5d618349f7bd81299fdfde77c1043f7777e7fd5a0ced70cadf7cbce5588020a266fc1fd8f6c8ecd0f50d3d056eced0e95c5e6c00d8b4dd0448adacaf0e69b5c067607177c61748bb37c4ad6f02eb6560146352417555edb29d5d1616a799ee5c9fd5c092ef97f9bc92646a9ccae6bd7324de5812d5d5ab96a29b07aaf86a66ff0b7e4dee6fc8d26a1e92e2e317991507a1bd22201fd552177d1e7addfcac2d686330095d4be520e15e94cd0903b5b9b1bbfa03edd82dc1871c9d12e8ca1d6a4e6fd337b3a64db7fe896f2bd2a525899bbd62b6770816c21cf0389502280194cd9f91c39083da68306f8567e6f70adfe37e4097225d8a57b8edafce75be8cc88dfb0c4118ddc5df05c32d406edc8777dd0e459e4995d5d1a5020e38fcc2c3047f134023aed8328e7293dd1658bee72a3771b40f9036cf06c8c644b5e5334dea15f3e991bcf92ed441ed4081e5a1c1fb9396dc9da999c6caa5bf237ad0468633090dadcd9b6eb53a635d3d92e8f572c9cedf4076e34601040c3797fd1b619c115b48003698612dd274322a0ba5e6385c499cdcd04d7d96aa41bcc5d958f03677d18e9e0c858c7925b4147a189c9909f24b62f1855db48278587d726238e474971208fd2f23102564415f1621c31b5ae7020799b151f659769a7e71f01baaed61567404a65dd1c2ea7adc9550aeffff50292fc1161f0b104cb161ea6a704aad0f460b244c109e476304daa3c2b3898c466e574bb6b08a5308e64c2e194f3d050d85b81ab4219fb074758b2bfb847047d8dd29fa7ae882752bc52570e8990732144fc371222dc249cc9acbcd1613cdba85355700d5243166ae8c798de09341d44041bfc8e87e8087af7ba75aa7d51eafb78e09bd1740d58138b81f0242c2cb2db38fa7da17951fa94523bdada8a641129395ab908721a50721ef5482c106fae070630c3e84126f2e7026e2cac916608e2c9cde19bd584076d4e58ebaf2fa0e416a30058348322c48336798a719bb8ef477d4d5a8106d437baca5adcfb22ef9486b7ed95a21fd11f5de0d52d56ef777b0f86faff9bd024772878758fe0ecd4b4906ba855af06d2cf03f74d715a82999b355edca070660d5f4ffc81d5cab272f1f3f803edb52dc222d207bef40e0751e28314f23996faf2f444c7ae53d6193bb016f9082fe5f724f903710fef65f740aebd792c13a7a45a1fa03e6da6f334c5258f63d4cc66950ff56003518be09529c1f3f94197486ea0ff39e67c4cac99904fc4d0baab43c29e2546c9c013d50cae6f2c49f67a528cf309083eb0c44671c5fe34541f08090dfbbc6544a650d1c8db8d30eca03e0eae5f27e2cacd570311733551af20eb8701fb885d50e9838f154f1daae4482deaa00119cfd741fa0953135681e38c633b0c35c4b419830863958d5e895f8f14616d5c7565d4fb6404727bc2606092825728b4865a8bbc548f55954552e1aa0a4f03930a48f64f8bbf242355c8c5f7a288b81d4ca01020f1799afa9cbd4f76d8d52651e10956d0aa1720528924bcad9e97446a1dcc2ecccd12493477e6994fcd031647126bcba93b6d09f80ef115d1b8f5652778a10ac4639454dfabc77057ac09f3d69b3e2998a63d0b5baa4fd16cb1d8cfb8f9f8fc496ed431aa7a5748605d6f74eb7c71aa5eac94662cd0a61da51a3eb3240a173821c467965f81154a185713cc1d94427a9284467750a918345fd158c7e1b30910b84dc5b65d2f8053252b006cc75785abd70b4263d62a80233ab8922ae393216a9d8a5674c12ba44111b3ccddf2a7b02e22f6ca7e5ac943ad686f0a4cd76c5a826fe61fc45a676c129b8383021bc4396917a802602b4271f407ab4978046c92c1ff39692fc6bee0e29c46987074c60de4820260195e75091838e8dec05f427593b0dac948a1d76c265f0489d4f68ceea602d18ce71506212d51f864e60c1ce9f77eda39433b7bbf1a0b2f280cd9d524392b4ff0222fe8a62acdd6b36c2c2a64c07b946ad2567cc2ced2d0d9e1e3d6a56184c10712988631762b92f137d3fced2037807fe6d21ec72827813d073f828a6c3b5bc573dd7a60d265e64dfb7476ccc961827600a891e58027bb7b8f044dc299d4bb0435902ef03b31fe65845581c192be887c17cbaf7e9ca897c250127141ba4c5f76c0a3c422999b39b7b52a923d0870078d55058891277ca6b3504582dafc146418a77c22c0dd1cf99741164506a70169f1855135760b3494832766a53947b33bb40d7f656b8caa6138c4e628ed40169c036c4e3e2386ee31e0ae55852b5a769c78a6e2a9f7dbb6141765b01f0502955608a78a7098ae16e75b19590c20a47359c6a144545628fc390d1c8596b8eef54ebf11ec2ed84b0fcf34e784a65d72f7a592c16cc4b693e6e14f0868417130192a5cf2323aae6c51d7cfe710678f8c87cd61d4e2be5c98af5311809b45be29f67eb5e30d6c9c6a02c5b5b6f09395b5510454600f6b673a21b2a9c50f177cafc02a20c63e23d06e898f8fab8fe0a693c8d3eeb800d390efedeed045a871110b5cdd158c8f0a0b82adc973fbf98096d0ac01dd8183ac7572251fbdf2f2c71a8306ecccba9b430027e74ad1f5eb755152d5bfbfd4ca1aed3e11d7b10e117f51da6662015f828b08a8c16f1168356d79a7a3d2611fe5bc0f0876129fa873f06c5dd54c6776ce2060883d41e41ca63c08141eae13a884e2059ff6a73ad63e01c127a0da3a4587e5b54ba8ba97465b216b997b6dc1bba316196c69d9352b10bdd0f94684bb6e95670ccaf6d5002d915ec185c8a6def1dd1194dbb7cf828ab5f0ac445b23a6a9e87e407069a6a5a8b06eb13084c5ba02448556f6680497be2e7fcac45743a4c492b69bf053a5aea7e28ca77b1cbb7a63c40ff29d5230f1470f22c315df38e99a6556ae4e8b6e8c39c366a8a96fb8bb7a8a264ba12d7e3d0bd689b4d5c3e2267adf52fed6ac145b50640ea6ce06b3e63245a4fe4cdba64454b0e182a5e640d50f39cfbe1e064a5e0d24fb759b7741350c8eedf6a4f64bfa7007bcec918f2b203c8dd2c7f4285f9a37b3e49a604ae703eaff2c1c59de380583e815a07585faa489448890bca0092ca8ac6fd9f9b93a9ce647b864f8213447ae2d045cef5568e5fe7c0229e33a56bff2d42bb75d1fd3acd9cf60ea464fa8aeacbcac788d094219caa9bdaa04904b148401fe2f010c0b5698a438ce50c7861b0096fca4aa3f871702dfae180c8249f25abacb8655612d1449efb10dc98bc1665c2fe33ee7f92500c2ddc59418083a4343a996525c044ee8edc0be298bd13f28be8561fa401dd0ad150530afd1108238889e9f5fa64f25a71bdb08e8d108e82888683d8ff8baf82b4f1709109e927612d95719e402c2ba0b1b9fcd1fc5bd9fd9cdb18600a626bbce6dcd9653a84b08eec2191420524f6678dcba412d422656b898eeedea9d2f2748d57c88b655cc3c31ed054a4dace0a71d7b4fd51bae7752b81311d65d42b7ede5e3c477845f7a06bffbca4b41e4305ae1e4c428ab7341e03af9a0b6ce8ee438b39ce09edf48025528c338b8c807b737080003a0884764b972dbac5fd8a1d196b480f6d5f1d9356a206a25ef7dd5504b46973418090c0265c30072b3ee3344a6f18d3d19cab8df175db8b3890d88d12cf097ea8e2f1543c1a0c06946f556b3c23781df1af9ac3fe2dbf781e09c614a10697c1096444f7e0da43015471de4d2bad04eae4493ca8a56f6cb8a4cb78c10fa4b138451702ef10394d19d2319a05412bb045efbe89a76e72b7dd9a4c0de56367ed8b2fd1605c9e5a4b7b5291a8cc992d2e2810246c8f747b0de7f7992395cf66dc180ea9e23cc14f5a55945c28e822cf1b58e4c7240b78b22e4e0973cd5726ce60fe5d20eba9fb791a036c29aeb8dfb13e22ea42418b06fbd28566c9746891fa8b388e8791c48c000b868181b06d06376ab1824ab776fc08c60a26c537d49d1f65d2d4f6830af29ef5b1672d0ef57c33f3fe19588efa84b41b71ebcdc6c474af7db3907f989235fe93297d39a50c528769dca711ea614a4f773951a3d3f6e1040ee7df39d6e922ccde0e0a8ca9aa25e29e03e8601a4956f4eb518588b727f21bae53405946812e8c89a32e8abbf7452a6697e78132994a47d69f6901f05dca76e278121f5dc4ab2f9228fa2865b47e93564094e39546ba2dcfa9920b84e2c40ce523f8f5dcfd91b25729b4fdae63ea89c7b241e1c596999fcfc03575cbd39fb0695d55d8e5152a58a1597eb72981311e4b9dfa368b8ca33c78977b54d9d3fb7525162866409962bd7ea34e201131f8f6c21e9a518e98fa4668f1dbe156cca4771886439bb43d4567ddfb34cb9dc318f3731c24f82df80305d1be941461806a6670859c3fbd984d197d53f253b32045021f40091dda44c0175408d80b235f82b40d708bf5420b6e1612c43bbc614c394a8056e818b82a0fb0645e94fc71411c6067aba2cb208c3b420e1cad140f112112a978947b8202353855158fca35bb8a2c201fa1ad233f64e8891cf0cdcf6a73b12da81546f188eab38bc602850d241a538514f839d01ca624d5a7b05496136a5a4a80fbf105a3303ded484e83f2e380605eb4162826e800fba03e24ee8082a33e003748787b10d426d980a89f21af41144c7d85cdb6af8d15a60a5819d31658226128875c0aed86a401109c64a37565b310a4306ba89614ad0d895cc682a52dbc0663ee9845e66e46c5ee09542140406e70a9c80b40bc92905961153b742fd27cc0358f9d22044411da85bc8dc264052b8d13e3be0bb9fff5be8dac7006c4165f30f349692ce70d6723161e0a716c2bdd6c29cfeac2468d3c8e81bec420dbc1f82849155b98a6500cb1db90c2a13fb8237578424368653da4bcde9f95bbae556858a874b739ae2ad6631a0955ca9247614b59e083784a6d777e5f555f9b1a0490f623a95dc651ff8f81ad093c29d208a832dd5def508bc040bb41d2775fc1bb80365efcc7c14911094c1865c6b9ebb71b58c02552149d21db10dc93f09043d9186996c0af98f3ad3a06713c45bc3abab2590e318aee9e0db39a807566fab1a0e17d8a0062d935d08d59882462120599e6eb945e714a131af453fa70f40584ae71d703197676c62b09afc5bec59786a72db2657265298f89d7f3d5d029461480913ed70caf81d9f31cae1495513ba0b39451a8591dfa0ceadb989d6036971f24c2f75d36ace8b8f298413dc459b9a7c74ec1f372833b21cf0f88500d4d61d930d0de98472abf6859082f9beab109e7b9aa24f80f67e2d273ff3660ac2ac265a037409cf83bb723840be1dd83a47b5946a12a07a3128448876cd0d456554e4a2c6d211009aceb63e86c0137ce21cbccc84c23d59131265004aade2336d2fedc26a1c2a9cc5aa272fe0cf5f33d27a067eba590e0b719e646292547faab164bd0c24d5a85bbeeae1d4ad72155f40cd2c72248bb0a10bcc284379c751a96a5acb54b027bdadb032b2ca0a54aca352b6b0921913fa0e7a0618c5602ebd6ccae333feb8fdc343f2d42f3aba3f411d69d26c3c5004bf99b3bf535877cb58f101d43d93daa296a94bbc8820a61569671d65e61979eac9f2a86a2ddaeb501fab41dd543c742da0e4527f04000a1c48feb4d10bccc079c4b36344416ea0948dd4bd7f0fdbd682094910ff468616913c01b2b07850e81eb873128683e889d785589c3c0dafbe61b2661f1415db244c18cfac9e30e86774b2b19e0508f3d687b4ca86613442315c42f1244817a7eb07aebadb654b3433e886534dd3839a6da9a58dda0e68b37dce520c9ee66b8fcb8ce6361c8bdf81d950821ff46cc7b40f97ea5d537e578859378357420f722a3420676ad204a8d619948677d93085936cf314a8f5bf93fe690c4740af777268f6ec35f0427b45f3cfa6da2374ca57a03ccf6df6b1103388cddb623884acdc4de051515d958878757e1125044ef03c9ae121ed95b353b00efcad93c6dde70bf12a077e7e227f01e2b5ebc00d0e0bb59617434cd40503490e9ac80f32265cfd297efbe64712357d5027a021f05a6c62081a890012bdad8a8b123b1a38ff706c0caaa50290c5bab95294c4c5c1731831ce932ee11a59f9ef712a080343d08c527263286cbc0975a4965e23d37c4b519cc4a05873e0376443fbfdb0e5d645fab842e6dfd6950389cd7cafb99818b709ba10eab352f3946bdfbf381cfa0e644df698a535ebbb98124d42d12d2b86dc702eb21902186cc0ff88688cbe46f1be0263ca1762029b85414ded2ff7010dfad105920f77cab0d7f4cda2c2630fda6d469ec3b904dd1ac5de0e623cf6a8cb46c709016d0dac2e5bebf3c0e458bd6203578dd9ee112a57b4915149866d828525105ba01ceb9f21da4d9c828f28eb8e0f5f877eb362c0bda0c6d117727344c2367b10ee3951aac6dd98d2759328f0ca6a99e7ac7d20f361fca569d8982d4044a028dce1d28bcf18d548cbccd50900298914726dd6b47200331cb7cc8b519061206db8b39a0ff8b8e6a261f9134f23cdd44adfa5e30b2c7fff9da6e6c6bcf86996a6535df054f3b58029f557e624d0d08bb1a8ddc1f195a23f4ec51c69cd7ff81d4257ee3d52abd59dbf4e6233611d14d001dd26cd1b077ee3c5f24f278b34e8fe201b830da21be340fcfa2d17f39924e569830e31f6d2239f7a09e3b9ee2990148656787baab78b42418742346653ee38dae9da3e2d363052ff6d704c7f667852f25862069e583fadbb1690df6e4be619764b1ae7202e9b583683ddec99b2fa1395e3271676b68df627c67d35d2774a0cbd91f65a021fa06aa6aa0059e3d9407e79ec8fa2941acaa6cf0ff4af99226a0dec8ebf9f3cdd36b099eebc434b9b235a519367d2d220fc2b96e065d4a348fea9e6cd2523c3a56c2721aaf8f51bc270345bae13c2da86b3838b8e2c7d708473d1f2729958c95aa65143a597c9d2e4b74eb82a6ed184147de7dc465c2e2a8a84ff5a0003d1e1fdf17d1458932a442ad009a2719a2bb145b3baf82c39858b5ec5ce8674599fff3828a48a3ceab0df7e9d86ff04d6fa7cb6e6bc031c2aca0b7310d090d812372faad95c09b55f28162f13835933c3b46a998600e87588ede951b513b77a1f43af5ffb1eef6801f4b93aa00e362310a02ba26d2dced2754a19156d7d7c246cbc939a6aca78ace58983c035390836758af77463f8f9fc349cfcc27964549dac7778a658361d84137ffa7d46c4518caa2dfbe738f7629abf505936121feb49babd1ac44ce3275a63fcba3c4c6b0d3fa99a5baa69dea226ee5b6d4fc5a92af6a5e52e97b135e54dc89b7cbb690a93b5dfe92df775bcceec12e88bd322e63e7200d213a0a9f3c4e92d950d63051b65ed3f42132fba7ccb62d39d5800f28158c2eed121b3a17fa7d1326584537390aeaae48f5d97cf95d3f584fa274acfbbae2a5ecfaf0ba6748afcfbedefc419b62b55e2efb49dbaa3770d25ff99d2aa31c67ddc7d5ecd8f38f42369502c3874e2d7beddc255163b98374571302598979ad8b2ff1524934dcd8f226717a37680e0765d434671d730f546be0b3f91a17a78e6f5c7c707297950a768ab7014d39b0986a31bb9feb2d403567f2fe252cfb926c1d6a20eb6f6e74ff8c11c7a06dc871c0fbae4c48bf59aab81557ea515661f236a4e8dbb07b38f824ffd068b786666002b7fb9b477d457a063a059f9a0e0110363897dac74d98adc34b3fd1d8621b28f992117bf00979eb09749c50e2774db1efe390935726f1a32da030e7f717da7b12b3c375490a6741e9edb81045d994a0a677bb87afaa66c4446bf55d68a1a11fa55249e671dcf97cd664ae851cef4552332eb1c76c1af25d796f495ea10cd49ca740a95dcc4e6e3b49e899053d542bc8ffb8441d335228fa17ed3b5251a8fc3590ce1fbdbe02135e831b30becb6438614d5fda70e74e730777331f43efc9a63348eb8fd7662b0d97386d002d8e06cac2354ce136bb82b5619ccc9f85df17f630c783912085bd1e259c69657249d72835db4005ce694427d4f0d5be59491c8ec4cf0112acdbb5b8b60da1ebafdb377af7097684703747f45f63db5f62e0c5403b497349d457a7dfc1f1d72dca54b40d38fc69f86c24f35f13891fee5b466f6821b4a0472dee3333a8c5d5ca5d1f0c18ade7cdb6932d9c75eb56ba342911760349dbcaf84a98dff196a9ddafc2b8ad6d784da52b1461198fcb2e318f71580bd217b628e8a119fba34b2219504d3b0ae0d39a41da448a85f2474f35462498f85321aee754e204d2e05bbc1e0d4fb167c85dd27583ac18f7ef81268bd220bf2b682b4e41fab524c55a78048aafc06934f9c83d641afa8c4e42ce80445762e5b3db843cc681229fe5b7330b50797105598237cac3a4235c397d81e0b6d22f4cb7c9c9cb341c1e7b494b9cd48a263b27f1cf1945ef0b44f4fc8c95ebe4fa0e6dbcf663b1693d8cb636dc7d2c4ad5ebef3c35b861db3d257c945e2ae536ac32de15ecd5369b8f1a254ebc5f18df7026cd7913706734a377ccf79617bf81b85f0e36776db11cb956dba76101a033d42e33945ad70fb7f1c6be0b9af58444c7f1943c54b3d485ea095feec24b208885e10dc260a5050c889fb21b68280aa67910063523b8ef200ffb1397296039e22b5c9b46cf1f48a88ee9c9200de0e1b98b8733922c72f7dc615f62d6456927a7517836f64c98143990bba0905980acd21df42b0658eef1e6b7c8602fb0ae65f72397c0b0b47f8474aa43fb564808c64df422d25e81d93bea0e04b646d644ff8161af25227172ae54ae674649a25f30a5ff42a92536c7c678a1df5e1ecc35700fda37599f7ac4afe7c2b81062b6a375f4e224d3764e1cb93812caf44508c5b4a2eb3eff02245f3803acc018e2ea94da9d17afe89b067f96b5195943c3392b8816f3b08e9e1c0b7ae7669409062000491bd344303f805133b314417c91969a181a339cda45a721404d16ded7dec0ae7e9bd9cd9ea9810c70a2ca6267fd602c27e4119779102d1e3cf98c9188111f8f60b4a85c14be980a14f31873567713f6821f3c5d52c5c9779472fbc0cf6374a3a5bc44d91f8ca6c85e8d6d7afb5f9bf7d65302460a01790d50f644db96bb809cac62b42952e0d7917983166df5396d739d6e871045e369403c518413586d8b27c3d7f350b24a83100c70dc3859455671e3679a5c9c092e15cba6012882170131a7022fcc1b739cd1051c018e1975274a46664e82583d57798dcd4183ee2fa6080dcc7de6f987979db612c6ff4cf1d89b76100b7abafa91a42d19151886ce07ffc557a49f9dc49229a889725da0bd10d60dd5246977b581e74772a33774b06ab9dc8e941efe114ed7581c616b66f0ba3a4dc05ddf48aa372d0cbb53c1c44596bcb14637f5e1121a48b14b569e6b86bca70bd01fb4a3a7277eeec368450d309fbe98ca9ff87b2c237d25d5a4149de38a5be1bb17e7fe666a068ff156d7b5b0cad2fef355fc14fce04e2496317f82db4727209120c0f3a2fd8be93e0775cc3c6a6761b8b75e37f99d4be23496e5708b92267735723443da89f0f96ce450360b9d31d1dfddf48055efd76941f07f9413e86d71c5d1df2e1324cd89dfe84028ff0c4be4a36d4b16eeb364f7efc2af51be8d1d7eb080bbe41c20a01be827d098f00f0bd1c52add0b82dee12b137753a71baaf8c30fd14ab81f33402690723e747e894b0f4a3c1d3b3050ef9f669c3d1da11215de238dcdc12381d8c65b2eddca014bea6d73dedbf0c232ec5e8ef5e4e786cb44a6d4631a99322d9ffe0c3495c196a35df44d56506448f1f1739d5dca53b8fccb3819e7f17f7673368c8b8048ecd4e3a6daa1072d75ed32d8bebc5c49199163c3394d926e24feb7106fdcfcea91599fefdef18d524e90337a92d9ad1586545c1dae1c3df6e040dce7f55a9f488e0011a36fe9460f8528fbb3e177127de898afd0beb6927c13fbb4dfaa78617b8ea234574b7b905bdb0f974feacf00be10cc7e0cc0f803c0e1e94031d30b37793cf72027675505ce053c3d537ce5b74c9b55aa9a2fade9faefd027c2c60d293d13ef0d7728680a70fc8f419041c9470b558396ecd2ceb572221bb3a7598339d2abcf1001bb59edba032a8446954d5f42db8fb5485f68c626c60feeb555da8df251182fd708ea05b834582f7de84012ceb40dd15bddf0ad3f86fe4de17585fdc5d952832b995316fc396fbaea639da06c606029311fd9251797a4ae870d137d329d2ee8f33bc59fa6c755f87be7e3382409c479c7889bbbb6760040889297f1a065469ebd96313e988aea3372293bd89b626fdd375a25b1fceecae324cdcd6a708b53ec4574252eda425044b255c78d5e21a3a1c29daeb68605c8be2fa4dee0a026d1f80ee24e01bda2eded0d8e1c07c0a3ee8e80784dc22b846d7be67f81b618a4ce7e186beb9f5fa6c8daefe87c2fdf58691319f0850ba2df97e62411f732b3e714a85c46dda776c869ac65caf1a74d493f55c7b1d8ee15f0be33e784fe7174b34ed3beeafd92026445b84eb7979050c0b2d16733cab7a2e6202459d61f9053746283a111294e593fa454c66749a7254c150bf507565f0ebea91417d6d20187ec42f5fb7ccd77290f46294acbfc67564d0242569c3090c90deb09200ec87d86ae83b83830960f96b5248e930bf753a9d5c19f59a135b686b42df5bcbe7ee9a9ef299b086c72ac82829e8ebbf5620d777324a5f94cb1cd57afcdb4fa9e3c3c4a1432aa1a3d826d92a3671cec4262104b8d070bb7e7a515061383133f906604a072141fc965bf98de1ff341069658013977dff786461b3b13621f27d4b181adde0072d163b1572d8ea08d1529612230a3b9d39a8c5d83ffafc6e30576b7796377da74a31a985dae10b0c7b4dc9954b3f7ec3313325c60ac4920dc5d19d93e5798189f7575938d7a4f2635e635e7220fbedf9f0356e053f4bb4866636ddab29d13b2eb767d71fa6115cc85b492ef5d7452ec4399c670f00f9b453dfac690d1ec00080b69305949de57acc2a1326e66a0078191fa68ea255b76a1357456f5a125187b6831afda8209ca31716a06d782e4ad4f3988e0dd2202ac6e31c3916edb999be0a17fd97a38e4e61c7348bdae9dc7102de2b788bbcaa36ba7221d3bf5a2d1afef867a39a1f64d59218628dcf9f8048c942aea766a318d86c902d31226baf33cfeef09248a0a4998054edb0e98c3a98b87d8f3abeac04db5751e6d1cb6ec93d4d36d65553700c782fbe25bf44f9dbfea94ac227ce586521aba6ade6c4a9c9be4b4f467ecd151f997c7c6255b09abb95098f0fc4f56233168f9a833ecfe0c7faa7aabfbd7573ca46f6c23d2d11dc0c51c61b56557cfbc10501d05e19c860f34f810ed214e774dc3c2be45e1a44f2c7e9538a622f821861c4c92fdf5281a7d0377a7e139d3cb9584b921176745999a5aa9a9e465fddec800fbc3e54c417d6402f525e9e157cfcdb6e864f83c8e0e96dbe54efb2ee0434485c96aa3d5fa1420cf0ad78ecd2943af11bf5f72269e5a64c879bd9c4f005dd5465c47dc4d13c66428042f9dfcfff61865a926a5032501cc4853f90b9a23ac75a23a943e7d85c51330a2585b43077489602a60a3fa82bd0edf6f46811adb5ae829102279f4b526ea99bf0796b48bc5902521da50b95aa89dd91b9288d9e00dfd2b804f6cdc9b08394273464b033bb8b2013b6cb7e47f8807f129bde855d2b7242c147e66dba936f735c1123a79efc6c44c03a0470310fc0497e2e17f857cc340802095bb10fb857ff1057868c6239c054f1d058889b50cee6fdcca11aae53a6f454c2d15ab7a16039702a2e43539b60ca68e562c13d4ecb565d95fae5c29e3e669565dfaea37b7c5b4b84de44580c17af18278e7a6d9b564c406857746e4d42560c0a1102d2eb069cdc01d2ef5330a2bed9bff252b9e887d284d57c89b52b6633969511723e48d627ecdf26279c93d6cf263bbe7370aad25d10db31d38beecc824152bfe11d6a713da9df7eab0f1b4c452e8d0e8a320efaa6d49947fd82dc34b389601d0f8aca9db686f6c8ac376f4445b705330038ab7efe3b3a9714812b6b242b2d6a22eb23bfe6e3a613f33d4ce3f3be2ee00e02662aad313031e3f790969fa4276d7329de32355f77a9ca9b50061391b232cf0782c946aa684b99c7170e367e1a72a3284ac33751d8c95f28a4081fee4c86a0d97a094c73947a6e435ccc81e3ec3d0e3498ea5ae586069f8193e63aeed1282f523b0bd5f0c93c7fe16aeb05f70100d4789a3fb2b036ed7f7f602abb478e5d63bd3381b612b61ef7fc1bfb3589f88bdf40dcbcc6bc95aafba8ed05296e40080ba6b79d4664630a21b62934cebac5fc73a197b0eab7b3976cc8d5674d457b5109bd70c71089cdbed50f0490628bd5c47bb45effb36341cb17bb19b7ba3986e3966b0207411479311b02189672e33c4148e5bb06593f37659d196eaf9b2142ca8dd5bba539dc77131e50dc29426f873db21e1f0e15c8e35fa2eefea8f6dc979c0e09cd9d7272c8ae678b90411c97e9d6b004e12a37adf668e349f52189c83554c356ba386542ab7ab81651ca45e6afb8c3453819b252625e595c5e317f2aeca3133081de114e370c3322baa1fed60877745f37d21382fa7a0f95641d60570eaf0f9930cd14ae03840c1caa08d3a07b4cf0a9a0d34770daa393c75bd769a76580d35d2e68fddc7404d4b65c3dda54a7b7e3854c1fa3fb9aa0b7eb14f9979e8aa4d0f7c1a16b1d6cff434f2c52382ba795289d40f41c3c2f31b977e86fae8310e71fb58672871e92bad782850aa25dbed375eebc901dd0bd9e9273c087d2de24a51434bdcc92629f2ae19aa69d0bce0fbdae98c03ee5e261950b4afd1c7215b119783a68bad0fd1dee23391f8dcb35394899a352832d2754275e99746677801ee5c2cf3329fe89f3123193ce52efd31056cb003d2743615bf3e7515b3013cef3f388569f47bbd5a0b6862bd3530ec34707f4fa14360337feae21899e100355deb735777fad88089ba3b921627a53d82ab89795e033ed0ef0e879598a3163d4229eb86145e8dba7db6b9e4e05069928cebc7cc49d2b02f4b2793d0a6da10c5945366e2aede6a1639678e3ed7f2a4ec1da5b8c26a78124960b70b461f82419ab75ec0703ac0286f14549c844e937920c94347d20e4582e45057d2b3e5baa3a51c9a8fc05407ebc2c5d420ff8823ee160f294323bd0005052d25ac938e05f4ec0eed7d3b4c9e087c834c02433fbb084f2531c414bac8920b45ea75f52a61698ce6e747bd2e018a7d3c1cd1b42f96f3dece717295958d84b46d8d75a4952ea4a176ee9a87696e369ecc53d7465e4d3c759aed2957f5303b0db25675c0d4b889ccfc4f9150b5d96eb16b49f61794aa2a97dfb397fd3b6662766a209ac593ed08b00d88eb0131bc97179612d911ef00fa49e646b6152a13ef69f3fdb0d424df27496b44cbc3dedc3ccc7e25c96d8aa710bdf2bc45e85182e202c5b0d23dd65820dd6a65506376152d389a5e282c8b898527b317256bdaa3be98da98527c510afd369920d9b616058b2377b9e361af7dd85bca3d35331dc9d373fce60bff7e704678fa1e3737c79383e8c19f8760554dbf43148110a6068817e9c8ac81272e3fd2acf50bc1e0320018bdecf258d48852e9ecad58cc3faee4befc393bbfa76b18d66c07621dadcc78002ef3a9180594bc2267664547444fbbceaf8a019d7c22080086c4748b5a020d90209b3acc2686b1fe14c1b02518bf891fec37823f95658a15cd83ccc8a023c71c5e8fb9021d9a3cce4aa48622bf9793f56e2b3f7f9a6dd006e803ff2d534bddefcc3b24b60f90a508330be8390941d8cac27a1ff39bdddb2dca07253eb8ff74d3db78837cc02e3d3faa41e01012153f2b15df2423cb48332bd4c7625ed2436a61d91f1a0389906dd6a74a40193f4d051fa7a61472c5e709eef74f16f307e42fae827197d22412ad6fb9c9a40d09a9c7d49495b5ce2836ae9f82ff8dd452bd35b004e658a2818f1c32e2bbc345f80ebc54afd32aeb33708444fd8fc6c9b43f312991b83a8c4c7d1189bbc83fa131559bbcb69c8415099c3b2a14737596183e465433ee60189fc42c772a1175990792aaf00c7cad7ce604002ecadc5f73c650910570eaa49a7d602c6ab799a87a256888310fa8ae2ece0fbe026a68c2ac6fb40bdeec8a921ed3dcd3d9af03528a866778a11da18b06f8f85a2596f2170f572a6f939559cadd9e7ed33c225c55e4ba9aef80072a550f0d85931ac021f68703657f73e8925f81cd779fdf4184bb4cccdf667bf03cf4eeea24c54f08f4d158faa2574ddbb9edee98cea195ab7460685eec506f6df97d14d5e5989c054ef428c2b462661433cc2c7be41a546b09c3636792310c300da66e4776a4848b3a3ea6ffa0ac9896aa4d0f77bcfc15eff57bbe5ea37a0981d1d07131ef6c333740e199a41d0e12ff0c49f0f7117b31c49ac91ee9d33b161bba92904026b665d63083c07905ee95d9ffb49b1df8e4f7ee3b92280ed13a3084bd324e3dc161787a73ad8b36eea42d90f332cd30c8d10c34e65790d59095946f013a3f630b81ada24c075bc00b0837c9c54bb275ccf57a2ec947789d0b1c6595bb7f79399f1e9dc68d804a486c19be164a450b431381d82331abccbcd0cafa1934206e502f76478904c492be848b6559c3e8b2fe65f947c2edd8f245bd6115afd0974873134f6730b0cc74f359f06047671ffc500f65432ead4bea9f1fa6ebd86604267d1e5b5766e3d77d3c526e3cc2ec9c21425b53390a0398d49fb9a3775f4b65039932a8a6d3673ac46ebe94706b4c004eadf4bc158309a55493ab94997836fa9ad91e698ae1372c7228d282db805765cd2d761d81debd680de4b9ec23d23381fc5fe2f6017c49a453a361590a574c1ef05349642d9d65a687eb19753a73634726d6c6b9f10b21bd984ecbdb70c2d0cfd0bff0b3f6032f4832df2bc5c22ca9f792d6543552d8bb86a6d1131a33c3f7f1dc5196c49f4381bac5505fb655f2f419221d6ca13758d257b20ab394964a711b8081c64bf7894e7446113c6a978ec29d3b19ba2299ae26d748d797a244489f2a42d5a94679c731e80c7bd899e2623571368557cd441d7a0af8936284ed163294cbb32201e8e38a45cafdd20e92c8955927b49ee222d6f56eafdcc7643b416d073f373d3c40dd0cd913893dafe9ba01b2b1a47e92d858f5047a12877ad75b38158c2c0b65c2b55f5a9db49557d2604fb5a0f6bf58c72dfe3c9df25942b568fd1a071c05c8fd5a0716cafd86b3d35d2ab520684a650d028aa0b88c419fb7ada13674eafa74bc41994d7d37aca449c49793dfd8933a8d7d3261a87ca1571a519712d1b34f683c69ee819eef518111a23922b17afc75a72f5f22c0b8c091de2d124b25167d80e723da6b31d4da07924ceacbcebb118cf27933ca317752d4b94eba7075a264d9dc6c1f2fa0b49ae3256fd9514672ea1ebe7899fd3a07b814dc1374790eb6554d4ca95e8df0594ebb54efdef01f38b85dcc3fcf73017f2a7606eaafb7d0e2b75531d4e0d913acc6f52877977188c63a4c33730bf18e71ee6387fcac2dcd4bdb7e56f4bd5a5c373f9c815cceb67d2ced52357a9771db6a96ba54a3eae5aee928a4172d5826512963128855baaea4d295526a91c72404a8734e381e9ba2c48aaea3defaf35283b3aca3cefef3a6b934a317e7e7e689665493229294b4a4a2a259592ea4fa9a816957e4a3fa59f52515151517dc62357f54866414212a6eb8e783cefef2c4f2614399b954f9d23d95913922bad2555f55b140d9d904d91ab1572ddae1081c6a3b53423882bd792ab3aa426916bab12b1db85b91615e5fa7ad4bd5e13925bc0745dd7e10f3a212857a05c3b5bbf6942b9a6d8934c922b6d8bc6d1597ac1d28de56a465da36e3d5255b52cb4aa5ec80b3a50f793ebe6936b85c2e681a7a1d322570d0bcec684371e93a954043724106f411b904c6a1cdbd1651a7a26d1383a5756b5495a4faeda0c727df58255c97832dbc18c27d7dbbb3511bdfad3dd80a2578f72b723770b8a5e7dcadd9044af1e7537a1e8d5abdc2d49d7a8cf82e44a631255f543b2242c916e893311942b52bd8bab194955fdcbd58e90e4aafe48557d96594b91727de947ae341ea9aaef4ea59f5c9f25c915e72355f54036a8133a51fdcae596e091ab0d8b56d5d77a14fc65f5167fd603b98e20d713fe626496bb1d758daa823fee27d7734cc499ce75abe79a88ab529254d5734b74492c92a423b9bee3366ec95614bd7a0d73ade8d59f56ae2f25d52ecbb623d376546f326d474f6c59fc9492eaa611895ed57aa257bf618d277af52f4ab09fc693ebb72ce20ca713673eee4ce2ccc9ebb7a3380373fd8614678eb6d8a2d892e2ccb77121d7d7ed9f6694eb2bd251d5c9b51ee57a4d6e2cb7ef8d24b9aaaf3ff0465ed15b1d912d25e55aa170dfd29d6ccb1fd3552e54d235e051f0291726814217228141f0db91cc326bbbeef73c996d3bcaf5a5a25a2acaf5a62b03af1387dcb8c18a7d7048a6b883121fe80452de8e51146c7300948323792b8294b7225b446f834582608ebe59165b5f6c31814724c9f0ddf83b62a7a79094b767f77bfe6011a0e86dd656275a52b5bdef44125d230bf6834ef01849e2d99ce0c9db9dd0525a0e84f2f6147cdcc95f4e90a64dc1246f5f53a19337888b00e56d4950be4e04925c4123494418c915f6ed441cc915fd56d2a610ca17fe9a8a9dbc61970823a9da0e8d24c915114852b57d7b864eece40d7f3d4552de9cd0c91bc5441c49d57623db59833b20cadbbf9ec2c8897fd9edbf0e3601245792b51d36112457a9d3210b07b250be1d1a218a33a56f4694e4ed42793bcab552b5fd74b72b5bfcd9bc39d1ca1beea2b71d1a6999f0971519e5ed2da191a3bcbd6336ec033a81a49de8641a59a963293c91a604c237c2f0235ee396586e0a0bf3b557ed55833c1fe409ca54889ef6348e93d3d31750251a473d7d71faac7519c995fca4cf6ed02b2d336233204091b32430394b22ce9c4e9ff1c41994d36744e24ccae9b39e6c8938833a55397dc644e358393db5226657d82cba2df2b6c3247a43323d6dc995d6d276d094073d633a3dfd41af5a4e4f85e4cac5e929915cbd9c9ec2a0bba90d323d9624579c516986e5dd3791ec0ed5f18aded1cf34f4449a498da33b3d768421c5192c08f3912bec545382cf5fd0a5c08ea0b3cb039916b58830a1be0ef31ed8535848ead853c72e04e6d79b958a4f3d8775dd54bcb98e3d1ec39ec238a963c781f9f51cd6062455dbafa0bc3d75b7c36cd7eabace0ec643afa41b34be974c5199a6be09c10ef3ed02362c8f5a7336da6ba2f6c286e5baf066458457645b1692730086533cb06387390cbeb9708ac7f5eba9a7369b882fb072202758019295fa0f9d5b7295d5d20e4cd7791e1090d692ab52c9f3feaeab317c7c7c7cb22c3b3a7a719b554292484825a4125245aa48b59515c995d6aa3ed5a7b68a327d6947ae342359020a92463b3b3b9ef7779db519cb679291dc82e46a23922aca41d12afa188513b82932e5ac68b2ed6c44db5644e4026f45529564bbe58ce4aa32d18670465a129c1167945ddcd45fae4b0b22b532bd6674fa2d081555f4305d672dfea0138c720065fa43a3db82327da32e391bed84324464a5b62c1a47e76c2bda582ed7ddada86b703c5245b72a5a451fe401fda7f3c994ebc95453421aae458745a65b1632e5764a2520d8526dcd23997240dc4fa6af8913a971d04f2d7a55ea6b080624579155da7822fe361764faea851717b24a3b59666d0793e33f98fc957632fde9724c448f1ee5723fd1a34fb95c1397038a1e3dea7247a247af72b9a0e8d1af5c0e49d7a02f01c9d5b64554d16f4cb22136898ec8b9254a4672b51d19657a17772b922afa97bb191dc9959665d61e65faea2357db4ed6551f94ea93e94b48f42d5bd419dd5b2921657a969b237af4db8e5c955a454fe92dfe32fad3b6f375cf317277b3ae4157e80b10673ad31f20ae2a9254d1d3d3e4e8aea0d47b6735ee8aca1d61ce287af4970afb71464831227596957a95654f6c3ed4e5f45b12d1a33cd1a3af78db891efd8b12ecb693e9b738637a8933dc29bd8d33df29fe3828ba38f37156c8f4b4fedb8a32bd762457f49a915cb55c6a49996a4699debe3790e48a266a3e72055b156fe415bdd511d98a94a912ee5bba93f5c974e542251712a1842012940b83e0912cb3b6eba4cc3e9a5c5b729565d6766d65fad295b9f9891e7c0a17e1728d883a436edc913756a44adfb8ff88adaf93bec8f3f2bd04630b26f9a0501e42b22e5c845461f9cb4af7061f58a49964753a9e7afaab8958ffeef3ae234a72fd1556d46f22d57fad848672d77e51aa1d20a7eeb4aa9ea7a7d24a3fe34fd7a89f9c022a4ed56f18d65bba76bfeb80c9254e074cae18967047a1954f7450628e1f151376cb3d04b404871f9be51e025242f412af99bd64d90b98652fb21798bd642fb2972c7b41b199bd64d98b245a96d1f6608430d2a04993096343d4b3ac258c11c6a15894936453f41941932200810a2ec880154190239011723c2ace7017908e8ece0e58f15d5c75cb1700e42f86c68daf93c896596cd14cb27c7f7088849192892920921bf9834994c025566401990c49a20a199790b1892311494cf2452553c85f5ce26345969734e0c97288065ac8f2afc110b2bc375483a3dc4336384296af714196078207135ac8f20c18628249962f020a59de88a11b504107073ad8c10119788a14a1c7a788157e868a8021cba11f21211ea2560e9214191d21dd20cbc3241da441e7063b3b60034f1347e85122cb1e3282f4e30411509010114f963dc483a32c1f731667be4d28cbc34d28b7d014497913da8c907dc82dce40a20cb7242cb825c9cdd9c4d2155d37e4a36404435f68f101419e9fddec253ea8424a9e73ce39b119f97a2791628a198c60ce20075d0a2613544d6610021990010c43621c010c2be8cce0838ef95aa8eb1c1d637a65a52ac295f686456e4455bc8c19ac4cd7d10091e55b75bd74bb7c1591e5bdabaf0d64e95d38124b298cb6157d4cb4020c482527d80069044d8fb410c1bdc71ccfa41fcc16d0132da0f1424b0648f9eba22cdf56c877f2323159ee2119b4e8921944accd3da4441bb2b027b987944022a2b50f52061209d1d09841a38b4ee491349a9877727970b62f8aca646ed0d050e5c8724ead7236d8c466092bcd8e863703001e958d9a7925bb2eecba2edaa815b9494faa68eebc24362f99f3a4f39a5794534e39a5fc94726612ce89ea1848e3ec0bc503adbbe17c9c53e2ec0abfb0e7f40ff62cf19ac8c3cd715baa240f7c81b9b806b9d3ed9cd23f8c2c78c9d95ca39b86e250a877af22ea5a09439e9724f6933c197ef630e529a89f6e6f0afe687c3437b9beca7a6f78cbfd6ec03f68e496dfdbfbdde4fb12f7433ce18f473edddecf3ee5f56a29d7e68616f615e67a697fc8a0ee77bacb4b9c8dc51d3d18bcfde28e5e0bee6ba50d5fd421d75d43dd0f66ad391d50e59eeef77cd2ecfda1b37dca9b4b4067abf2cbdaffd0d9e21b5a5815fcd5bb1c723aea5b6eba2aaf9129d74f56b939b906c1320a63d086cb6b644dcca2075d60df6398eb05e622c22c05c71f8b4ff01dccaced3aea792cff6458fed1d44896bbf2973b391b95a7ee4bf4506f7977bf9cdcb1e49614fce5e494dbfb5d057f30ab1cd67acf9391913c9247aae0abca57aea9ace0c0aafcebb2ca6ba2e491f0baaed35df0e9d8e926fc7557777b597e6a39ca9b1302f5165c6fe7eea2ce72bf6794157bb8726d4565e5d637a75281e8ac828360d93e7241c03469d26447ccf51980b9e21fa8af5c9827b74326a75ce5167f5008eafc24f920f51c411e2323a12322a496fdd745349efd2793abfd47a3723fd34f6f6e07e4c9292af88b4056b9bd9f4cb6aff77b9675d7fa1aa972835c59e5cdd9a86020327f30a3700564720afe78d87b7abd28879c0dca4fb723109d2d0e7205d181264d9ab4b209ff90c9278f3b72b5b5aa1ec6e4faac56fc6df8078ddec997e7933c196f71d5aca933800891e8d1ba71487b6534cb7ace47c80361e7c060c4e090d135e2bf1b06e0411bf1dff38c4cf4228acbcd43015d63e60d442f7f32594787862a80479228a3a5101262e180d8409c8155682f62a199340a3212ba060c401b2cbc7681c007a00d5647d7f824ccf276864d58e8c3920f9093e1a14fcb962c0c90abb74adecba48c5d7d5d04d334e4e7f5a169c09ad2101861bc380c6491bbade8259d64cbba3b2667de0b68b210ca0c4050a28b88a8c602b2bc5ac5e50b0359decba65c49d69793eb9039148221b9331c02c18ea9e5fdc6e98ed3f22a6a8e38c8954ddaf12100ca2fb987424064fefa25244bce46bab80c41cadf3cda8288792ec10940c81f3542434b6e2e2e93682a89392ac87e14c800f2a674c43cbf247a51069616d1d60c269e3f716662d1aaf8a905518e474747aaa0e17137d6c5c54546a665c4564427c3eeeaa0582d5707c5822b6fce86e535918888517ec94d44e40845355607ca53de33af93cde97dc234283b02731345afe584cab18b7abd29775ead6be5a812cab5e6b0cb9b8118c4f591a2c750ee970198a27807cae5738d440902e445c6404ea6c03cccb31586951c3434f9c80704a6264d9a346175d7b0ad7427d09d4dcc9fe8c5cec7757aac00353f727af2751ff39d2f98fb28a78460e5698b0201d1a0d40e7a79fa2eebb2dc51a0959be5a02a0e3081d8586ee7959b659cda51b37ccd12a78290f312a778dcb4a8d103666b12b576928841d18b4838ed2d1807e3f0d8812c97df3c858720e103cb05a7e40e64a5a4cb7ba4eee272212d4fe11e2e7ff90b16d2dd05a724e6f17297964b2002f448f42e6db95c5a44e5b4fd2146b9a7907b68c808326d512671c6f4f82c1b621f4fab50c9f1b4886a91291639d22ce47829ff6c892691bce48f59447d81fd2890c4418c381267604bc21389bff664689e9d1e3b6dc9a352504e6f59a76d207996154c5530968251f00957fc7979074dde2890c9740a34b31c2dae004dc6f00784e9a6933b91442f4a1ce40a424893264d88323689b6162acbbfe4eddf34ca4e232f4faa745c789e6e9f1fc53f68b2f60dcfa049247a1113faf901029a447312116597372bf566c9899d3ebbe6d2b9d6d27579777a7bb43c75ec0ed1f2141662e4c6e5dd85a4de22790c4961173c892065f9d91afa409119904a1b9d5402b59800922bdaa29802490a84bd33a53ea4c4a91d9ffd494c7fa80f6542ca679c8da42d7903135b391e43527739057249e13b7bee1c123df9895dacc17e3979ee64996d55bce46c36708420fc60c8a5933ab21f6d115d7174b493450f529cf926912de2cc377f72fce6901c5b4b620f2ed48a38f3fdf801eaf191ab26b2f3f95da7adc6e1e3c215b82e9168651a85c6d157e44f6e91618b1a5d17863c9047082ef77161d85272e991a872b9cd921253a02a02daa2401f355a82f6f4c096cb5b6e4abe59ddb1a3388321c955cbe3b124aa4377e4cac5e3290fedd1828d3ab9b38b7be94855fccb9d4952159fba13e9ce23a98a7771646dee2110a4217ff3c8e5c2ee9690000422f3088910bacbeea624a62dba641ec5792404ce884b0c3a310afbc122b8127df041073b20db927be80936e427bcf044d14f4b99a3dcba054e2a3430d04498c92e92ba89acf8c88a184708aba50a3b02464c0a24403188e1f3a29c72ce396717a44ca459a994d1186126e79c534a1b39e9906c49447461d817ae2fcc78c10848ac0470de0c6d2e51d367ad22a3226dbbce5a795df68ca7dcd825239c48d7135910b66801d0132420b2001e9f2764d08382a427828082999d4048aa3a7b228a152c00053a3a80b0a311bb30ec8261041b2377145d10438c28788105387cc1b2e48ec20b4e14c10b51743d48b62e22cecc13cef4dba355d76d77215f4ac0130e6e1a84105a6b6d2dc1ec1f4d861d764cabb2cfd4d8ededd10768b3961ac34abf6e91d28fcd2eb863348d3078cdeb9a9e91adb9878e78e10a360bf9fbbc47433b524516062928967be8881443ae9f9c88a717b439693721bd539e2c90a3ac79e2c800cdd81ba50239c6d32cdf37058165898174938c6118e711391ecec72c6e51d7755d5729f7d01126e4cf7ee640eb188de330d5fe936b13b91ee59a45f42a508c9f628b5c638c3046182352aeef187f72358254df874690ea8d8f317e12212455f1f144141101e39d58bb76ec12512455da8910922b228e2e2b9e42286b4652a5d5973eb803a1acfdeb298ab276680429b3b68d2065edb0891fb98a2c4d3bdc01529ce922ed2db5778cc61323cd82968a5a9cf893ff41e24b9992513e428886ec59ae509f90c77e599e2f8a6ce7963458e9237bb06338a2feb514ada20ca5100a6aa01f9f9d3c44d1bd018a1ef4bab33cbe6b39cae52b7749a9682a97e5a8fb37be69c2450a1d54d20a5286c75f4be1c828432914ada0e46c22c65e2335ecf60d2df02704e8f04280ae8bb3b988446fb6cb8d30d83eca31c60bd2a3e84d9a459eb185099bfde0cc277a970a3b1f77ae9e222bdfff681010504f0aeb89de757474a4f21ea9428332dd30d91367a60cf2bcf4996ad0e9c1ce90680434d48321ac83f29c8941974b0cf58027cf5324712615e7e74ff23cecb1fd8ede8ec9d9348ef826287a2a1772f488521a74a9fc3aba7cf2853f382b6f79c461b9cba3cbcf4fea86e5a9b33ce5027de42a75d31df5eea86bdd6de95a30cf9d4279c68e3a73fe221267523e3f8be40a7578048d60512b7fb2a7855a9ff168ca783f0a75a1905431498a1e44f28e1e3475324fe2ef47ec9c1cdf728593c3ea4caa7eba46aa8fbd71aa69d668d30873f744c513eea993933ae79c73ce39e7fc49e5b84f8e3b0fb99a5a51a61742a4492f26d19bd717a06a7e9221cfa9863c4faedd0c64393e1edd0b8bae31df42996af205b2a767c87eb2470ae105b5679d73ca25c823a0b460e1b116b6445bc1c2a2b460338de62963906da52c3be1cf5a3c4dcfb2ad44b169858db95e42d1ab6e1983691b0796a79c22cfd951fc93373092a704c2fcaccf354543d14e9ae998e9167f59663793e9d7e46caa50d64a375561adb5e22f55aa37dd1f4c2653ad37d592092b99ea4b2b7d714a3b764dbb66d26ebda95ec3b2c725639e0c8f7a8f05746f298058de52106917666ddb36ce86fe6272ed3a6a1c58f40a8b42abe667e93acaf39ad46e56deb9a0def21edd5db09095776fc1428cd40b5139eacdeade2a1d16d2bdfbca85a0aef2d4102a47fd46e5a8577cb3f2ee3571720a6816cb4d5514eadd6f50ef5edf756fc1382bef8ea302391b1e2c3db98347b10465f815a10caf72a5206299577951854df140bdf3d7513092e208a7490194e18b6047c1285f4771267efecae2428a3312338a1e93c696604558ab8fe2104552055f449cf95a8a534ebba6dd5a51b8130c046257748d79b1d6c5965cac08b3e2c87e368af81167e8e7a4415235b9cfedf3725e6e1167b417f5b4788876bea983b5bac6445dc594325d339d6ebad8d7a9d33b0b01caa6db37a7c3def49a78ba3f98ac35996e4d266b712a6551ac111a8a351d25eaa06b74b6a65b5392d5546852ca8961589bd2de9673ce0bc34e4bd74412e38c104278b718e3c4d98cd7fdb2aef15d2288914a794929e3c4536230cee092f18a18931ec4b0c65f863b5ed7bc660e8573083b646a88fb983300ff86cf9be1af8d72f6989b828f390ebfe1a68688390e4f41dc23e638a47adc7018bfe1301e00690a6cf6d835b128893d429484a0241c654882dc43486802094b202189dc4354d8dc43541cc9dcfd66e64e4caf91abd4498c13ec611cef2a5c93c9958753a51838558a8153252144259309008f817164ee6537ca30e336fe9d9c7236275807b762e3a6e065bc5933ae77d57bc4b80c2c44c663c8c0292e47c815d0ac4b55ec72581e4ec19b19f70eefd5780c8ce3bdc671627c460a4b46885291540ade06be078dabaec238399a164fbc9be262dc1477ee9e7715c6b171ef3800788cd410337ad4788af3aeba9018329ec3eaa1bacc65b0100f5fe0467519188706d748553c1052156be29b65037f4d44031b816f1600b0e44ede31b2779b756760bf4e7a76f29314134e0d112386eade853c06eee10951e14b95097bb8a5ea6ba19cce1a0e17c6ad81fb74b38cba7d1d9e0809477213292122520224747294fbc18c029fe12c86848a868ec024cbe41e12fac94976b60d951ae21e873be01e079c72003e8c18f77e13e31ec63172729c141703a7e05537321ee331304e8ac3a92166dc7b8f19f7b0102337315ee342bccfc03d6a7cc6676021315e03374b069671151662e466c655172203f7505dc6656021dc55b8a5ea44939c0da732e3a64c4fa5a49868524c29de4a0af7d44a8a938153284f7137329e4aa1c898b1825354b65b141977064ea53cb57273192bf886c655dc4da5527a7087d67ec6950144e66a514ad69eb0acfc2b87f98ba7522e9ef297a79e4ab9dc9452397794afd0a4c0bcc09f8c8b14cff47217930aa7b8d368c12915942fc8cc283fa9bc26e664538a3bb9a9d4cab9a71cfee4326e6a050f41e3aaa738dc8306567dc6653c95827bccb88ccfc0324e375d2032a79c64dc96aad355b7a5ca05d2dda4499336649413cae995b34139eafe885ebc4518c1c28cf21f7e1cc2c37b82bf994d87af917106e5b18838739a97717892c15dd51c96891ec763c82f55dc077540c8e16f66eed7e1551d3e3b39bceac2132c13bdb73d577ac3ebba258883cc2026c7711cc75d1cfe70327778af77b7ccf418387572d5735826ece1d4094e0de13dc66fbcc7f8c963601c2327f826c65518e75275f21827b89fc3aa91f0367781d0264d9a30d921b3c680dbac184064def007b38681c8128e000eb759306eb35ea260bf1f5d84b3ec628fb9cdbae136ab46cedb196313b78ecd81892fa630e79cf2f04a29a5d426ca35ed1aca0f9a0c3921b0b6fde446cee6243e27cbfb3d4720c39fee372f67da6e6f4e8637c8b55ddeef46deb8fb6d599b3ae8350c51d77e733e85c59cf3f31e0d19334fe25544eb984d1e420861a4810d3112610bc96b0def4723c39b60609b551f5f83c87c437e850afb6d25d4077f75ce68640cbf9382fd3cf983468e9797c9e2cc87cab285a609e0ef11ec0735001c28cfc3b8d6dc8e79183fb9dfc9eb8366a4e4ec7508c04bb502086c9251ac853fd6da1b376e683a04e03afc6ace2687d7c4d5ccea5773363ba04ea893a6556b6db53f9c6c3c8a1eacb54a1e0cbb2857351b7c92c706361ee5ebd5daa4dcde949b6e54123d28f385630bc79947f8d3456022ef50842345189277f80e45207245cee11fcca72da0489273780e876289c66dd8c9c9c93cb9e289cc41871c0e374e07cc395cb3a75faf185669d0e9302c2c29296f8e8525e584c36e6861535236cbd9d4aae3f4eeb5c26a391da7eff0eb62ab9f6ee7541030ef70987738ccfd72f20edf2108017c00ef68accc8e9765f6b7efe674c01ff071bc26621be5ea75b8343434a75c3dca8534a7f9e9d809e6155fd7f59caf9ee535b2068919f52d25057f39574acad53511b25cabbf2e7b5d36d6b68c8a5a45464618923b77468216b2c88d043128b1b9912006241ba783dec5bbeb020a26906c81040a22499664fa08c5904c1fa13852842d327d11aec8f4ddcda27797d45de28c193366cc10d23366cc98819343e35c0aa72cea299f05a203e6ec33628d15eb5cb81cc31f8d8cc538eb23516b0591282a6971f6cab37036b57e72db9bd38e72533a520ee328efcc72181e5eca711e5e13b59ae73c95c2373cbc06e3f4701e8ee3c3733c87d5dc3d0f37957a7eb372dc54aaa62663213d9c87d7f4e003e4ee9b7b711eee759d2e9657cc741a4f0162937d06d681e3dd4df7b3f93fdd171708ccdd258763ec4edffd59fddf1d1e77f45e70b76121e8bbcb7b81c03c00fc65c771940b738c9d0a6773e10f275f3511757a146743af410e08cc28f745cab19b8284c728d357242208657a8c08addc435464d1e51ea2624946a293e9afe48911830346a9e6c3cdf11e2e0f7f716146b930972ecc382ef67b61fc8147cf72dc87332007f6e10c38bd876bcd5d3cecadf7874cb6f774c19a68aff77ae5250f0e31317e612ef0310c8ea84b4e08fa8a534160c791a88b44b65a8b5142501f6e0e0bbb9d5fdcce289defeddcc3cd61e1fbe5644a2477eeac71a86b184cb9306f712665666b32bd394a4da68bcba2579f72ba66ef1724460e01f51988d9877dc7fdd0ddbe539e723acca89bb2efe13039ce728be4c029fb1ce7e1ddfd307cc2457ac0298b83d8e1399c073cc4880e01780e3cc4c8ea489c656426b56387e7f01d9ec335952d09b98790f864c8518cba30290b36559f9383d8e102b800b00fd4777867980a2287d757ec03f51cde7905f3950e872ff8fb75b82e8e934f98b529b76731d9145b537016bddabde2d3399b0be6a77b17f7833987a37678773f9cbc3abd1f4ed621871b24e61c0e7383c4bc03e4ecb31baf34cfe24c3dcd2f997ce3f6ded0c2d2fcb3f906cd339a67375ee284a04d9a3469922bcea277e3cde9a0c137be9ad921e8c6953a5c49240057e670e51237b01ffcc99a83c9723dfd84bf99ed3526ecb79ddeb9721c67632d863f1ccc9b433dce543c3b16da75428d03e61bb096aea32c375a8efd861baedf7043938b93afb7d88b0178fa0933a5e4a4d4c81b302cbbc7c0313860f853adc51fcc57095bfffff3bedb5e3140aa2aabd61b99a80651db80af7129b4c4ca4f39fe753cfcb331efb8f2e1313e6058d403e601b754c9e0962ad5ed8cba9d61b4beae0ffbd34fa7afac5cc3b69595affe74235ff57e1727db5f29c71abb3f6e4ec10180364eaf91315f077361c6a48fcab1a75c4d6e30299ccd75dd0f02d95ee56ad7c500cc11c8f55f677a733627db25194bb92b1a2a25db265945454545e55f17d9fb5d08e4facb9aae1f379b7000a00decf67e3a646c0543a213ee681a07ecf0977df52cf8eb360065fc05fe3299bbc0aadfc62127848d9fbc466600dc0f66188745366ee3326c5c067fd606fe7ed0c83030004ee3aad74800dcce32ee97a9eed7e51af79347c8f0312ef793f8078d3c4fe3defd6e320da824d2b81dbdfe2582fd32ad844f5698c8f525ab72ad7f78390bcb3597bb84fde2d191f77cdd775c1d2673c1b227c76500c49e823fef84bfabe0afc38a60dc895e123d70080b49f9e61ec2c292ecb3454fa6711817dac9306e3fb3761921a9878c4044fa40266c66b6ec277af51867637116bd8a82ae016fed0a13ec2751903f591467ba43974395c34b14340ed36947bc9049103077f466ae4fb95ffde99033611df51626058939eaa864e070cfb396d6fbf066e5780fefc1c37dc0427c380fef010b3172e3c379b8901e9ee3cd8ab906b7a813756024459d24265107e64f0dd1c373bc470f38a6870f98077c1ef9e3917fc8641818dcd13b86f119340e23c62d0ccfbbaad398110307d59bb39171a1920b7188f1c3e06f66986b37f9f47a0de35a6eba761e9ec3aa16a786c8711e7e93e33c601c23f638f526c779380ff039700ecbe2efd69eee07f329e5d5d6cd743f1ab962d36ba4e9dea7dccf7b7342c0b88df9e9de70c983533b6246ddc56b24ccc5e1302e048231f7cbf2fd2f0e312e447299d4e8a35e666badf5516f2d13ad96256a1129c100ccf65048e8542f54ffc12024156340668b81402660abc2d60b201344ad97291c11b95ca2be1e5efa1ce5b0208c98b75cc1bce52ae532390ebb28d79f52ea4d3030f04793eb636230c69e973fc92393e30e19e1486e79e9da4ffe82c48cba8b766df3af18ee9cae35077d603e1df6f02ff3e19fcdf65f97ed3f2fdb5fae78b87dcd6da972711f6e0fb7e50f997cfaaf9d2ef409900bf330fd29817a0c63c8266c0893b040c35aa3721ffa68783519da099aca18ae0bbbae09afa0417a45a88529b33c23af2967f462cf75daae9479e9631e3bdc6e68c1a68248f1318fca9d3b7f13a776a0327654c660cf77ce1d67e4f624547ca09480b00d4dc02e7a51ecca4209dc381ad6de9c19c811a3f89a1cc8f130cec8432886ace5a5564d9c6530c3160d34b863769baeac35ccdd3967420dccc8b25d2a6345d60c4347168c11b200e7ea406bb96261d89583102c56ce3c0246b80520682c0d6e57abe6c90296456fb3b0db2c0d76bc6eb396d0b03967841ed0e68457072694110e41c37266a075a9bd920660074e3ae7829009373c10d4829d12a020091f104187e107f69a584e11248c0cdda00966e831ba90a022092d4ef043a63bc3fe6e83fc793468aa60227f2dd44986aaa8414f14296862086a1882c492b28972cf1b720f1535c9a6dc434548f688d6cf826d2e421e493e45d306441b0eb48ef920cfbcaeebca2ad69bede6dcf29cef0b4462b7c8764d6e14723371a66aa5f78138409c89327af2317a387048f476a8dd400b11fbc9e46db2c06e7126420ce9135ac764119569e24a9b8176552a22ee207f4d09c87798d422077104b4b09f0c16f693c9376b15bde806f2754920aa906692269d60e155b4b0f0f29b110b85748dbe0a182c3c8c314231681d53935b080c36fe9a71c618048b54d0b41c67e39c0c71ebe8d93d67f7ecd9b3bbc140318c6254ca8961584b2963f2bca83c867b46b694f328e8c7a6402b652f3dbbc41fbc32eca39f5d83bd59edf89af304cbf097fda2b77ebb27d72ef7c9c38c524c7f7439fba4d8857f1421ef8f2ec74b25d06fdae18d2da4e672230c9b768880f8fe341c44faa83888ec472d621ffdc1893fd87de1ce4060ee5f37b5e37afdf5fad227f6d19fcfae5d3aebb33b2b9e1b86951e5f7a8d2c5d98afc38abfaa5dfaed66af77be5ed330bd2d61fc75af8f2032777fe384886fec235ed334fc553c4bf7a15dc336cf4db5cd73977ec22032633e801c41af8f2012bb3ee23b5f1708fce4769c726ae21df1fdb8a3cb5fd32a4a7d9230768650681d330fa1fc25040b1f2f2bb0e53819e9a8699a8f2247c8b08cfcba20b88edd4706642ec281eb9d254e0eeb7ae471e1ebf04e213a595e0f8194980611ade116b90f9108a069dd0ddf57b0dd4162ec9eda15ec372584337a57b0d9a78410c2ac218470369411e9ef8285ffbaecf22f71e66edddd36ebeedeb2190498bd0f2184597e9ba8f932e7dc8106000fc06bb0514353386ae5aeb1d316bd993b0a3028c95df41aff784772fccb148260458e570840a0d1488185ef4d87488370caee6e8bd45300e5eeee9e32c6c4c4995496b7eeee9630b08d7d3492fc804681902a78db51d84290b2a09021514da7e4869c0228ab846b5860371067e2e171e20c4df4e05519e64f468706f302da8364d9342746310cf380c019bdc982655858f089d82b04bb5261ad15ab87174837418a335be0479ef9b94d21996cc43c4bf70d7f7f07b18d9d8795e422205b44f4e6514e60e790a833758032c59148e4c178628c31c6083725b496f029f2018fbd11208d0862fb4e6cc27e91076a10a7b2c76738882d0e49d1cad8e3cc1cce66346275a2146c7cfd23ce00cc1f95d8b586339e60df6e77967f453a1669640552d0c91057405a0106223a39620dbb189cf9ab3ee283cc8c1dc38c88de3c8d94c2d94a944c1d29298c3a3b3c30893c672a08cc47846fae07cb3b8c8343852776585d77712012419041100bc7e5382fc7717178533b4acfb961b99188bb474e47841c8f96d36b5a844f5d23f4dbdd3175c4eb031ede5410a5c797bea3744af107e3212704c70096a7ae414e01cd6a79730e60790ae31c216f4094c44abd7b0660ce5e23e32d3dbba597ba8b0341c03385100bc7053ea2a7904410cb883cce0b3ee286198258296ca474177c04968424969193b7b038c1ce97ae4c5db973c89d3bd12b510cd57d6641e6cc6cef446f422b8c66963ac212267e8aec767b7a9a379623715647ab112caba8e8cd883f1a18362961bf78abc3be747abf0c578046f6615fbabd56baf1f4f06218a5cfb0434b33faef26c30ad0c8df4df69e9f3a53c7b4448c31e66843b1c89361fbed1661f9d54165b97de441a1c1da4f163c87b07c0e89de1cd29de52831c218233c1dde53778dc0b35c24ce32f2d2b19c8bdc351695b7ca63562a7dbb5f4ede340cfb0f9db1e76478bfe7084c085f57de5c94a5d39b93e30d72e5151c0068e3462ebd466eb7a3b7650ee51c8eaf9147dd6fe6146c44f47ed0c8273c77a6ce144a7189fad947457cde99608b4e9e7df6dcc4990b70df80c8d8558185cfb2d935127e592ec272ecfea0c93106b119fb01224d9cc93e9fa3c6932b16dcd1cb6663a16b58a16dcc6b175ad135e6e98557942e3cca227a33ab6d141fe329463f9a4c6113585932eca92c8bf391888b900e3e4b92f2bc4f134079c6a03ce77c4667a6ac429e3a7205ad88aaf979052c8ade8482fda68ecffc9ccd3242cb9167b24e0dd041823e72c5806cde8839fff2010bff02027b09a5441b628071f61704cb7d7923ebb79d114e4a31ce112cfa2b23555146aa6472c7c3932a1739b0f0510a1ce4f8971cb0e2e5fce7498f860b27d44352d0c9b1832c2329f0e4af5b9c8e148a90bfb6425eb38b332f71669281c6cb08905808641e73ef319fa20530b862152e256cc8c109ae147477cbeeee8edd0db1abb1eb6aec9a92045a1c4084534a29a794524a6d421bb023b431e5001ada90d25a137607703d8bd08694529a8080958680ad602963ec18e337f3978ad0463fe6993b69638ccc119ff2d76519638e97dd0def17f3c92c718cf29ab223c45840712e8c5ed725e31111bb9a482831d8a4dbc69cb31fe1bcb00bfb81c5ae26f3921884524278c2a08497d863298310c3221614e3a6e85637567adfa3efcee240b32ba6db867ca984bf23f2d5860cc32efafe840328c5b671c1d8309e408c4e194f5e34db221c006cfa2a4b598c56c26a29533cc4c2d7c489d9b8a49098e7b5d2f6755b561bc7d4b87b6a95fc76a53c59205fb133407326af439a4ba73b2c964b1848d79047e44b7275bb22044e402206186c29f7901236d0ec25bbae086722f4e0fb82d73c84104208af39bd6c622f110ee03ac5b2972c6799e72c4d6cd2db7962d9cb8bab94c15206e11bb3557cce2cc9946491bf4e52a4a40a29e418e42b265f57138e902f254ae4ebc615745032f97bc9c1841e26846109567ceacc107476094755c8df96278aa80479526188880b4b90420c2588c00a4ab8c2da2fcbb009f644470be2764a5089f800cfb682522b49ab415675404b4f604e10ca86884c70cdcc4e91822ea080080f04996147676768880d44e814a5d44026cac490813de58e420c6c802164b5dc518ce104558ce1055f18c30c66f4d82c771463c88137033ba99079ee28c850c5fcc001e2cc67a3a60040a0ae6ba27e20c08413af28818040a402851f9ca025a60d489aa8ec0401c8058c249028a11205105c40052888a09288a0029311b2eeeef6011172f7690ac0a33f1b675266314fb0f0fd3883e7212b7a727fbe5c97854b50824496f88978868e872965747663d735a38c538832c2d2a905c20b4613b412b029ffcd39273c651f6d62fd9a98d1eb98bcaed933a31836e7ecee19e48ad3057d2161e1e375cd6be294c472c4a2db66d9b265777777675052011e368700982057a4b4616268c30b754ddc3171e144cd84104a3803f003fb6519a8a58456286163bc1a9b33b330c88e3dc3b28cca2ca318c33d6397638c1d73288c4dc4d87dec7336f6c67e659916331a23ce6a60d1314a6cbbc61170ce6641291cc9f663c71c081f20e535e735fb03ddfd5386724af99a78c1fce564f9a923c2a3c81d68b2bb5bcaeeeeee8e51cad9b108730c5d843093ff72329c17964062d89c58b7a9d492177627463367dfae715d18c5e6293ebc2e2f6bd8d735fb7a4d2c7537be2044b141264f39a544a26577c309610732ece779fd82311a6918bb21ceb07c733912c227c42cce5ca62ccec0381ba722ee5cca16e83296d1f79db3c212cce095e1a71c81d4eaadf5b262b54a292fe7155a8c51da07d5a880200806913065f6f929bb67e4bff92cc64b39e79c73ceb89aac289b905168cef63c19191a1aa12c7dc83e64d3eeabbb9f050dbeb24bce970cd3c83db3d2bf790c675225e72f0c772b20a96ca8a46d15753d8d3a4533224000008314002030140c8804a3d1682ccc13416e3e14000e839a4878569cc9b32c88614a19630c30400400404000406466da00c0c436764055e2e393cb7f7b1169696b44dc3d53a14306f060f1015863a2d2a8e5843b9ffb1ffa8beda4fb023d1822bb81e7dbad20d60725548b59eca7d708e201e3b7810fef2df099633a29698dbd2f1ced3defba012367169b549e4d97c89dfa747367248fa832b38c5672abb70631dd62fb7c83312f247bb3001a6313212385d857242d53ca162676cccbb2253d5c5e75268c23f738cc0ed896aff9c3a49f7b4211fea5dd17ebcc4092a25af46e284d62ad80824a16614b6585ce602bf3971b0c8d51f74d0ae44034f3aea9ecf41d62ad7d8108397e3277bb31d0a1a1c8771c6c2e2776520bd4328b64ca5ef0d7aa8ffc40782d4e095f26371739baa153e4cfb722c8e14744f4cdca76cbb26eb4068f060f03935dc6e692010fe6aeb8bd090278383d7c603c47eaefa506271e63afa1838ed54ae28f32a6b9064e12c10b0b4488bc7adead5c92720472bc2420b75c37d19f2ffee648bed2445cf523c8b70c463f768135a76089b243a87348f645980f14e377a9cea930fc076a81638f0d0d90086e1d54713a8721f80ec81b7ef4c39bda043b160e3243110d5424069a3480936c7a4d954cd512e0642e15543b42337a6cbdbd8b8d281116e2510fd134f9c9f57848ecf632a45b81b40d5be89fc85854397205ee5d25fad1ae49424ceda8258c431a9d380e047c84615b261da9fd3d61af153243bf0aaeacf3c6b18225e8c690dcbe4416ffce18c230257e1d8cb20e0c3e1fe18fcd421986c2399fa401b3eca1ef13d0293c667ddf4869e7858bd67ef8bded878b01c03731c2ff9be456fff7694ddff5f69e73e8a185cc91e73b8fe6a044ca8a7ca55efd7ea8f8961e72e36431c4611d3fada9655befdc3426b1c299cb0487195a16511d77fe3b83ac56a9502e95d8a00ccdb971c23c1dd65823ac470d3418a6fba0523b28c099062a9e98893b143d5a8e1e9b0f2478495e81b84ac1722cf92302aa9269b36de546705a4bd228249def296ff7fad39edfa4317049cde183030ff9e1a30389330ed683ca5bf18a1f1c5d1c51b32529375d164e4ff80208ecc4ac8f2b3bb7c4420fe3904d931f937293c371d5466e0aa0e34b00d6acfb4e0c58f7f476a28e13f9884e0cdee4b5eb55c5564bcfcb3edad5367a6a5797caf0956978b41005a2bba3275d275c5d210e7f919a800383ae15989db5bb8c2f32433a440bc8ecf88a61e53b75b7ed8a01c2e4df9c4062b1c2b6fc48f701d70a8a87e34aa2014adbc13e7245a93bb0c2a6f41108779272ec56c733252b48e88ecfc0c57e7b989db3a5ccef273b165d5394961537143bd85c1bef0447647df647a9ddb3eccdf51f021bd69a5c4814db14a2df1b3986e44abc4dd8c2e9efc10bad6e0edc875bbff776c47ef0070354dec4310362cd23194b7037e939e3c6dcfda97aec58aeadeccc3afdc97f380e9a284383367c04da44e6f14a2f6f6046bf80c9598f35331f1a0e5113ba8603c2f863028743239e6fb643fff67e8948545b549626777658a5a50cc544b4e1639e4888859c598a9279f210a81dcaa528ceb010399ad36a9dcb4dbe86e2dfb9b1ba3c9169a3ca4ff1c4d288165573338e200b8e6140be97975c0a4a01d11b881ba1b0688513c657481b947a58c256a855e657015c8437fe54329753b0f14ca5dc2466031d3003d348ac380c969c5bb6fb579cc23582874b87202068b76b906831396ed9352a33632cb81dccef939a2960823a5a8714fcf13ef3f4521445ad7fa4d496d3dc4efb1c7837a2f9ce1089147a7b683113975e80d235164f2c02992f69340182eee9aea434f4c5b3f53f804bc98b2c1e60c6d0c98471c064e711a9cfcb5111fe990de1f10265f67d28cd21a74a4a6384d49e53e43b191a7e781f1d301129f523d964b37957d8e146ac0e673fcd126e69718fd540016b8314dee79fbe432bc35daa3f3078388aad066ec691bd0709840ed1d930e67738a2b355b4cfda2a494a9cfd26c6463e17aafcb5815b5b48ac8445e24d5f1cfda0b9ef3777c0f24a2f58cab0e4e63fade0cb9d2cb593caa285d84c4125bd80a1c6aa230d2c06e34a2c78fd74dac4733a1287122223f3ce7351cdb88d925b0edf02711ad3fa38f264d2f039299df95d04dcc0b17dcd11f1149f079538689e70eee6257ba8ba85532a9afb879e765bf9c64522a7f5aec4cbd9d8bfb1689f41dea405ad318c868aa5391754a78f8d35b47db53e8ecf87fec02ea293550fef24dc6e0cfc11e93b502d626c3afb2e1600409277155fd28a69bfbf18f2a09f67cdf609f61f8a3c890673951edb4f23d78920cdb9e08b157b1c168f45ad2f8cd73931a232c2b62d5c4cc108516dce83a4bb3260006e8848136064b63b69c5e8fcb9e3afbd61d9fc4623bd2487b5ab41c337246d643af851320faeae845109fdc4600f216fe429290eddaf6aeb6a8648754188c8b3ecd379e96ded7132c80288aec874cd785721725ca353b4903ba297d656f76292b5fa5f4f9be561c4de639a6aa0054f89af41cb7b338048ac33e7d8ba371515f93c4badaaa7d9222ab3d6dd2906da792a2769d17164a3ee090c88c545a3694bceecf4ab1e484acc4d232c63fcee98c29cb492f40352662cc0147d07b2580a19392e91a0dbe45ca52a0252f0d1fe4c976749a875e91a9824a4ad32df1acb490a2958b2b571c5061bb57b32665108f383c4a7d463fe69469322de535b6436ec0d31348b52283e2ac868bebdecc72e517c662ea1420e2ea0be47f8df233a9dac41e771df965e986cd3557f8ccfc73defadacb0c835c53fdd2f0fd4b802e585a67f29d292d08f49912853080132ccac600496561df98a1fdb943f1a53bbf403c907e392a3125bcba002b1581853775d46ad8a84d89b9d0c527f885ff7a1bed4a09bbae225512e8eaf4bac07d6eaf3db807dfa8edbe84036738d189bbb8e0b83da99150ec914475556ce094223ddfa764366ea61d81ccf668c9a81564ad7c843654ef76b2ed5bd8407d61621d86023f2d32b1d5b38784d4179f1db676e9f6f96f97882a70cd33e84d51da044ce43897a29e8010191dd76e3020d94cd3bd912696a4b2cbf873a099050f5050e1ed2443331784cd4da9d0dd116b5681b20de4ce509416829d191ad8f178d8b6a168a1a68f7a0a9d509b59d6cd9d732b57451ba7d59caa22d1c723552f4246b63fd06a5267695481dfad90f4a1646f68917cb45692155f4558c59cb9e6f1612902f88593d046c10915ce832aa5a74a0cf22c141fd5a75c91e608260d02db438b5ae0c2d453b39ad74716da369e58239773c59fabd7cd27ba89d90a52ffa0c3b4624ae55a9d99aa145307dc6f5675e79e3558f1f8cb09086e9e61f976c3f7f9de8331061585d02b49e0961dc181c4d8e048c0529375f4f8395255be020b88ef7e248a757fbddd76ee806ed79c8533fb2f1f8b00f0b42b8e62e22726a128239fbe2fe73ffad1d0478714e044a519fdaf4e4706b801dc16332d2184bc824e9041b6a6734ce7585cf52fdeaaa9498aa3fa449102819f0005b45b9f6667f4fdc400bdeb3c8d4f96a8144484ac9b8192bc7c2446cc3f370c42559c58fd2304f901cbc2cccd89bd5c4db98ccf407e05db64ab4c2176dc67ff2738b667f9706aaf55578e3980512f3c94e1c83fdfc096ca7b00ada08c4b9a7f2981dd8c3f3f323baa278672bc14f3d8d8db265e2b4c21815a78f7d19a500fc55762e262930f4b3128e2a7327b23dfb944c190fd25da2a7a6c2f28809f1e7390bb4a77614e8d9dd4d11a9c4412a6b06f6829beb8d73898743c877264b60ec764d5fda11561eb330f0fa6fc9e29f3c61444838a18f3b7b598987bf87f83cf8a0c707d900fdb815b7b5302e2e0a0eeb5c011cfe26a6475f8608b5ece79af3ea01222d31b9b3853f20b4569878eb9b01778bb180136b8917c6130551a2ff655fc189b32c56875b63e8277465b8259b2dc8a724bfdcb9645eecdb04da3c7ff11aabfe6a5f52026c4cf1978ef96c9f31a56c230882b9a2feeca8b39a187e28e1294e2f79aae36e05dd3865255b32214d4ec03e3f435724c100194febe1452bdf276310313add860c512a98e9de30fcd174571a482cbf73c78e5c08b4f9c49db2bd84bae61967dc7b7e7e807d9ebcf9af37e5c1af22459ebc14c8b2108d54b7fc92f0e415b25d293d9c98c921088d0726366e4762d5c16b62a72d3e058764ec60809aa67c49937576038955367aac259476368557b563c9b418ccb7055523bb40ce828e8ce4ae77d8b8e9acaf4cca4f081361b3b084f4f935099791bfd4b1751eec0aa0d1a604816ccb54923ba5798186c0690090ad100ccab762315eb4d0ee2fa776a9d09933c891169770441c83ec869ed7745f9ddb91d665069cce12176d12dbcca8b1048224a5119d499cd0082e0b24f74a6d6cc4640ef820b6ab6836cd6d374099f74421d39336dd554ac6c59a6328d5c4ebfddf7e5a1aa4db59b44912b25d2b1637e8a185ac0fbbb455a2cc51c3d06059d4d3bc9b72b419c3527e85cfd0ea43c1963f023d279efb094fa4a962a75a8812a24bf50fd36234b848566b364e135b53b81e8ac88f11e3898cccc3ce692e2bad8a36dde9b7d61a6aee17a0ad9ee49284a283424f4d9130023ed4858813e0347fb41d54f96f7986dfbf09875b67ab3ed2a2c0b4e485391f37334b7280ca971cc8638e572d60e46b5fe4ba501c40d5b777741f316c6fd5c56704405ea6bc294616ff95d3ebfbed3fdcb256d56946b6c04e058d732bdcbbf14c4b2b5465581d70a26202dc5d50b49f321dbb18bdfa69a0c0de8227873ee9b67647f8a3a7bf381295f219414cf7021d7b633b7f95b04f43857ce6998beab7ed66e02ce435f378ca9afc2d9c97267c9289dc9ab53f92b4fe7b2b506ce9f49b073d8bde4c82496ea32c16c043674bd820f5acb061b56b0edb407cfc93423bd161eebcc7be83b4127e1fd4609651aef10343abe834f1f164a3c949275cbd854ab9e294e231946bf9d5bf170a3ee72466d9a6562d7656d0525d3209ec8d839fa8834a3af685010b97a062ff3ae0c1a80a111424f8828620829497fef4953551fe52ee21f884a3fd53dee6fa17644471f1c59f7f7e01f228baeba95416b67d24cc975394a85685ec21e576c7446fbe1a4a701dea87f7381a10a929fe6a751e80f5d7a679b56dcd61db6553bd133de15a585c1cfc32babc38e429df36b9cb1b3e93c10911a0ac7665edbb2de33cfa3b101312a0c8b11e14b129197ff0eb9f121a617c44a805c17b44943f5cbcf4c288a5aa32ee2a5080ff8b943be8d6e0a68ab835a78f68c279e43712e350c34c502ccadbb24419da5c3bf22bad29696e0f3854772d50f7968b9ca069a2728d3905fa00329552a684e4e9e5f82d55121c1604db0ee006f1e0de516ab1d70bc0ea68472480b58334b11f2ad7a5ccb5a4032ba260cb212eaef0be6ddf4c95e11c346772740989e9faadc8f8c11876f861e512b894d47a39921ab4c6460c6e8bebc09354fc804cf9b59bdad3cb94ce9085005eac5cf49533945096844f8a1113b7b4af69ee9e75f7d0099d6e75bbdd39c240ebbd0213f73a4df4cbee7052df8dc2cc845f49324955886d000e51c89c8bd9a78c043fd1e48941fa253a1d8fdf06e00d28860ba268e24d049d96a813972283575024338d4c151e95c2a4510653434596a7d1d305581dfb7be6c5115b9a93152c70f647244f735a9298faddff763b70bbfa4d5901bea34bef9f4219f634fa35a93533000336dd0d99116e4d3a23880084464052a2ec469d321ece80db6bab330ab185b32a876637306004978b49bb01081d3a58ec5c3b2f9b3b5db17a1a4d2e9c9236631b8624cd2862fa1c324217ef737e0e46cd79c08f67b5f39db24580b8716bfb096bc790fe1b02ac658c8a3c33cf064d2ccb50905963826c6850e3a4117db24ee9b2bcd77171dab1bb4aaf63ca9847a0e70cdfdf3baeebb801c617eb6e7dee919eeebb194b238fc8fb64705eaf05ca0e8fc4f56510939759682aa7d5277b968c89e172ec3aeb851a16f05bc67c4a6715cd10a8db04dc5deb3457c757a65c8a3c667c5e3ba3c81ceb5036cc17bae2a9324c055af9e7234664c3a306f5450f3162a074bc5048b6fd7663501951c48015fc300a7a97dd7ceb05a8045ad549414d086536d6ba4fb877585d07e99f7106a36e009c422fb77d27df07a1e93137268b1bc8a23be72272f76ffb3a32bac5248c7ff8fc7ad3d146e27950700e3c2c59aa1f5c4a0d083d68187521a83e36b473cd5005f19b35e6edc23ccf897a4c3fb93f859dfcd1f0f26cc45a40859488c8c4a11ed9aad3d6cac4c0c156f8332cd24c01b1bde76017e945da6bd1e13db405e8aa020319a69b4826017a36a4afa4a00d51b3705cd4f3022e88353c8a5d0dd1fff6dfe234ac3abf1e9156411e34def8a982a74b9911909931e5338cedc5342f31e5e251b9739911c2954798b5140edcdbc72c2db3d9802807395a921921326292c6bbef0c4572a97bb5d7cdd5049a2294788648820a1fc9bf143429fb3379fd88c2ca5be114100b2711ae057f598cf75df8ef1c38865325177b55648a1d15b7a5252d04c2edfb49079b9a3b4046b1e1f87ce526545a018a071aeee55747c87919e11237180b5ec6e02e41a2e5f77de1d43155514b9942ebbbcb2ed59a8105e89fafcd38858f8ae336a7afce90c14e8eaa874e40b64c03afca87c1cdedb4261c9ee486e88f09527e4c24feb0924caaa40831326cb457a85856eb55d282780f5b939baf9264cedbcc435326cbbc3b661ee33848592d6acd4d983c34e06a7b5bbdb4af61f1caf746cca12648d9da68786846bbd6e645615496d98242df15a44904dbc2e4721600338967605d57fa23233cd0d4af629f0ec9e6ab90fd4a7412817a33467402b8be0161a62288bb95c135cd23402a11918fd250f3d6d0904f1569af6a54cbe389600542e2fe0b3707eba68556a9c522e8fdfbb31b6c46212d765977a0286045fafb3918d38c38267b0e3a972d811264401cdf3586844982dd59af7e0058031992c77450b0250bd7e5764320797d48a0f3f36030e45c1a21e8be1cf44814d080a7b15e267236f4740a927d028e4ed0c97bfecee88272bd827341c703b1d4c857cca9fbd3d10a96b3e6f9fb1421e1eeec91d1cb30cca8506c120dc7a6c616e370138a02f2ded6940db5c1e92941c416c2f2af7d50ae5381fa970c8a0a44edc0fabaafba29f38c902a34f9f523050d944688ac0dc001df3ae96a435fa621cd81a601965f2985b798ad3243c70765eb68f7f67e1584400b5d9e2729315e714ac75b0a0b32c194a75a3e9c0f0ee1acbdaedd40214324409db721cbff86ca6887b90b800e7860b9ada5e3cc499096a954134f4e765f6a58b33abc4dfa1e0221b46fdcd08adfe3953393f16a8a2a117cc52bf1d0f428209ba78b10481c55803e95cd3ec79099771ed3507e7b5f6551fad4b49f0f7a32c71a052187ee35c347df512ebc40bb7ae94a2389137dc510b694233b731af2a00bd1507e07c441d9c2f219b02e923ed5e5b7a1bd0b544e226474274ec8f35a85130468320076bc9ce0c26dd033b154356d9bb33d46c556988a5ec27b97de18f4915751cd18aba8dee4a73eb172742819871c40f9495d1121f4becdffbdb6617d1abc3152254489d6236309efce375519506ab2fb31c2448b9b32d91efeaf93b80251915292cfbd573dd5ad75726989e843cf9e3934eab3bbd7adc7087be75d787647cd70a5b69ca3337b327dfc7ad5569e23663ca5ee844b7480054b31fe72b96387aca843c0b59334d599441dd664685b56bb9f4db46997cd731d2da3b0089ff13c11b09f98e135666da5306a248611337788444c59ac0aa5c614035ff50f8272cf339acba389309006f8c477867590bf080bddf6bfa523027ab143c68498b11728afac88f684ccd8e04806c91d9312fe8411b6a4937d8102715a0bc838a49f1d0e0b9e27c047a1cbda06fefe380392fa1fbfedc21a0651d93b20c81a1111a7ed0c44cbcb8247cb703e575646a5241a663350e5ee0191bb9167a60cb71321cd7211ea634b735db159bb5b420b343d4073a333091046c703e45a5e43fb48b98fbfba7761d74205c68f733cc25bd16db1a4d633a9cc89d0cbcf3058f4b58e231da5fe8de53672689e03de0ea79afc6538a62d36d729c33c58ae66712493a44c9799d4016ca6e249e2dded55ee119f8d43ad1be5920f725668c8f96465db3a1c9ae67468b8fa006363d6d2fee85ed9eef9a113896a08d35bcf3783d121589757eee278b94e71e4e94e41bac9c0e7bb844740e3abcb211ad2060947948086da401d702af6dbdbbb18bee1375ac4b2f088909309677193aa468fc3125f3d6170a1afd7fb1e551afbbfde8f61d0b71d00ac1fe932c08d62382c1f97af39417f7cea6981b125f2f3b5f7369060f67adf4dfabd5ef3da7d1eaffc64e3178c0df4958c132b673b7e24dcff797937f72567034de94f3318ba0f66c241df9003c2f09f9f71b71f7974fcfb6e2459dafe8f2135090fc1cc1468b449dfc2e5b67d926c0af2be9a478da0005d53f3fe8fa8356d2470d01185b0e45067293aa82fae2ce8445117af79631f84375d7b4f9f4e7855a9457d3181c3d0a6c13dab0a1a41c8aac32bf5c41864cb436c97e7c739d749b124941dd404c9af42f60f4da322fa05dc5aac283f9fa612567b80a664763787b9f1761fa06ba811147deac1207d0c6ef943c33d29e9a031bc144b10b32e30cef6b7d5c7ee4a1762825590e05f6b3afd1212f95458bbc1a545cd66ba2adc3b9a55a2aa3557770c610c6d051239da83d277001dbbf035b77c7ce6da840f04d43030a3f065eb5f74a0f70b78f2bdc7bc9785c5b1369c9115d790cbbd8cad3d8a23d1efc6db23b8faeeec31c15489bee096ec7381f8729e6886be1837658b80a135c4ee7ffa6d06c6fa304994bf8ba9c4e7edc8f50836ce1e1c3d386a1c6edfb9ee95e5b1bb52dafa58f7be9ce5b0e882195125a53c4e33e795eefb3352da1c20872bec804997f96659f111ad109435b95773eb88bea1c124c4516ee559e7c581d9b1143ec5ee10f32c519e3227882d82c4e74250d429c23b044616e0a70cdfb63b616562f6231c37bb53a4e4206c21ff4d9d1c431a65963fdd765f068daaa97d009778b37dbe92fb13bb0e3ebab4821769b56b7347a32d1f0631672ecdadb753719d6a17949fade60ec0f1d942bf35eb5fdef580bbda9218bdde66519d8fadae2c4f36ff389b5e8bc79e67846aa4faaad24854e95a55e654cc4c4da3720feec8dca98950ba6598e9ccacaa09a404d52945f55248e082d366abd210594afaf5101cbda6b4ea4abf6e3efbece722946f79c2de62772118514a3e5dbff9af6a22b5ddd7b152eec6709d74341278a99637a94e297d4cfb40c8e954064fc3810ab0ea6e5a2b8d77f6fafbadcbf05385f82396fd07a0441b857f752c696a469414dc1f63fc4589df6a018d5cb6a54bdb3c59219ffb3570172b02fdd65bddba677814fb1dd29ae243a7f060bcb25b7725286bb3745eb7dd95be95bd7c47c1aac839153f2e480b0b1ff021e8f4a4cf3b34e5978093a48691fc83150f2e875c0cecbb37f6381de797e0ef00dc8b883d25f9dc24a2a034e05e45682bdd7fb3c865a501f63e52af077a3ba2501270af23b49502945e25c95c44e2a72753a338155f4aa2825b35ff71efd112e499212e3b7a81d00693c768c07a13e736bff9b4e35dc5accc57a344bdbb776326d4fc8e870aba582bb7f1ce91ec7993d40247a9e4491a9ef95a5853dd4551a860f1c5b5611e2d6adbc2aa5c6d152e5a546a87f6a3e5a5e0221b658e30cfdcd11b9d873690b833c345182c771b0a14f357ec53a0d611649b93af066f6ee3a460943cdb21f3724219771f1977b5f3846750f6424112a885cb10b10f48ae93756d470ee3ed54ed81ce8cae6c3877db6641b0643689973367125ef406f696eb58c67dac6f1c1767d4eaa82d0f4d35236c998b3c0bbec8301ef4871eac90dd66739b2c73936dd6eec169479eff6d8632302955ef3e01e20193c49115aa31773c625a1eab0d69c01fdbddcf56b6f6a5a799d34d86438af30624bee30d6aa1498514d436a73927182302d2d4fa426634492cdff758548690817c85aedda916b44073f881d0e1ce6aab2e7aeda4cbf24cc324c61569186dad962ec6de7bd095ff7b0c8d52f1b64c9686f70c73a2e3c6e0e29c283811b93e76f4579878bf19a1a65cac5cbf1dfbd53ce1621dcac6b4bf1b5143a90661d14ea2287de3c97d1066a4d405e76c20e8d9ce6a622ac9ee42d232c60d2ea1f672a24414458366e6e12abcdd3918c01d7e70aaf05ae487994a5b84fb97becabc2e6a564d1c0638516c384cb27f148d497f208142b358366adeaaaf229e360b28779999395849d5fafcd6d89d96b05267ada1ed91f9bfac8985d396d38f464407d46017dcb4867d7c5d1ec491d235a0d1c65233840b9f8bdbd237097aae9ada2618c883db74dffb7b2f6d0adb19c76492332b6e8c80d8f3aa6c582595464cc0ec84dbab790bfb1de86cb54bbe24e0ad25b19ea57cac39504a65daa8791c17b2d3479dd373ea8e9f0b7ae0388da35b29953c9d46cf08c263d24e66a91195dc748a67ab3ddc1d1b565acd2a55109b199c553d040501ec9c3c101470bcf49e45f9b40088dd22a0a40c2895f8e28d58871779e145562689e9ba8893931faad1ef3b13fbe728d11f0dbdab3d898ca387ad000b817166914a4dc89800c81c1b526ffc2901db2bfc615a645ea6d5d49ef7728900978c9ea1a02ff31545255ee28100e4ec7053a2631e946ea050df4559fdda37ba1b8ede8ceb446ee7e24ef41a7d0c7caf81b65b67262f7842ac705fe36f803b11032c3f4eabd191de8bbddecc64624c49bb0c098b73095799d5c69b0394f3f884c4be4bad81d892de9e56b8562be2ef4d20ef440d028a9b13a11cd8fa6fb9661524895dd322739c762bc7c13ab66d7912566709ab1f522c406dc6e3b54549b86a7b29fea9bc4604bde5d1b4330817d0d7647be40bfd5030cc6601df002854190fd186ec7ceb90976503dc76238653577055a4ad1034198b32d30302fc9bb6560af0705596ca06b4b6107c5003c225bccd708edb6cfb9e84defdef90357990be679485cb9f112cbbad0c9513d166aa8184818749807b2665e0a08234a81b8d6ae0558c251e684d3c0897d532f09a40b1eedf699639a1558f6c75e3761350465114369edecdb9e04f2304527a68183230327280e61d2ca7b0619efa07e98b133fa0b860a735a04619e2002e9e9a71732bc51bde299beb151d4d5b692711a827bbddd1e43592bfe844ef243065056e7f40ab7760504c6adb9d899c2a601eb2e44dbd635c1b051a8ffbfb1dd8e9029c9d15a4fea5b74c905cd615ad9f8643a9af046d59dd90121092022c0aabacf2a7dbcc82250f451e008646d51f0c655a6c86796016fd266ff7b2ce86f13fe6154a4665c7333fb049d6f7f9198ebfc7936e74340d74c3e745e6149eb31988b046f38e522b2422a6bd154ae0fe6e8beb7aa4c816bd11436a59956eb134426ec501ea9e631aca105dc86c151c0aefac881e0009149a496091be97713360f935337768040b217d9c407828882dd48091779884a834ca2999c031ff13681a1884d3a90819ede08e4b07c8fc5747144c598106e02d7064fe5207613864ab49276eb27a370b197348bd556d9881174626102866a2f862d6d6c10004f2ca0887d7f17f17343074c401d78ac8fd3f47ab55cb19f757a18b1e33b324dc8894f0307fae4575108d37cd7a08aa9c157df624a116a225a1aebb0fa04b38009a9cecdb28d20df2629a4346f2b48fca22bb65573bd28652d02e4709b663d7923586ff586f131a1c22f29f5303db8e5828011dab99bfeab744e816123123b66bc96e9e64e758f805bb202dfda12395c902566c5f506626f0e2cb038a9c7676817dc72e1bf196942893112c3468e306cfe1c0ed432497c921c6b7db911b823b7ccf7becaf0d1dfa618accec50ac6fcbf48b2e01bd3d781a7a8d21bdbe54c612ed8c8e433ca4b7f8a5328d1dd9098ccc63801d171a0f131db61dc46878a0923693c19f599dbb418fc85c7c73b7e04e3ccf5786dce0e06e084541d9e1db27adddf10bade7a791511e0481bcbf048da90aa09bc7bd019eeb51748644e9e6a923a363e1bf5c6b537775d5e722058fe6402a725e61fcc89a6ff6e379864cafcac0c03a844438d9aab5a97792ef193d7d5023d706b9a5b96c865dd4873b350e3322886d3a512bab9f27c9fa91b3b870e26647d52626ba26b332c17a22be9d4add760e3375d028fd10e7a6df2c416119c56830b8e0fc91c6235d39a162a047cb692e56eddf63d7138b0e26aa3fc693d7562be780c432dd54fdd8e18a57146bda6c30623b846f82737d685b2f42141c03edea0f4924e55a45bbbb07031c9778047e62463849dc3a2d25f5666a2b502a1d3593ff07f04bed875ce1105562492876d59193e79ca4135c387d005cc5e758faf234c8128f740c35ddb4903e5cbd69150b9e5e145019b7448c24b12aa0b60c1c0461fd0db1ba51eb4a1b81aced55864b569fe754dc6418de827663bffe0b38aab8cb0b75ffba296d84bb6ee7a90d16ff3ec936fe547877db655672288790f5b9290ed4f9285947453ee85522da2e033a6f5ccd52c828803d458c84647e09ca9e66c564d46b10c85666900bc5149bc5c6468341b3f737987aa0b7dddd2804e9f5d1f0318d910a14dfc9202141cfd79a95aed2fbe82631584c8a44af2584d8ffb2a56c90fc9f1d97abd66fb02bbe384d339fb7baa271dd04cd23f7ffb3faaa7bc34843f0f4353f21d3748eb401ce0e795831e0db60024f47884def0f5cc6054fd99906ef4c46fb872ddf55d3043f4e6c23b3ad847f8232f7555efc0fe5232d7dc7c5b3dac37be54f9781e030b2d2cc1f41ca1674b116127a7ddc50febe8eb00f1d14298791c65381eba2fb49474523e2ec5307a31bc65171ce3f098087a030a79a70cb844e88d1213cfa58e54904d86d2e0222075148152a7d1a2efa27041789aa4f8eabfcb5a43f2f905a6b01200967a61d15f0ab11cc558d388fd40ed4206662ee52f41930ecf87a0680223f8ee0b1f197e21e1666d19f6f4d5b871c07a92ffb8b8e90e30c16213d6a8d2a4367b5d207fbcebec1842e5dd7ce59a9a3f330ace7e29428cb660a06b3436b169ec66b92bff32f7368608a25a3ed7f16ec4ae410111a226c0194e7aa3a98e7fcd3ac238f6f34f5fa5711c37b6081281de0ab688ee667448fdad44ee54da9cf6a0f6f94cd0ed114f019b5bf2f9e6ed21622f3699a4437136159275c437736875adc7654931be3bb41d2e753407be0984e923fca1b4b086a5912c24b104e922c7ab58fbc374a12d75be1bd2a48285b00365bc3692314369eb1d71b85c42f09d747ee0054c0d9eece12f11596e86443013058c81843033b96f2031e8c2c39611d1f6fb4d384109fed2869b4f5313da0b9800b41ec60907fc9894170486fcdeb5835960ee31fe63a0d21e3f8b1539e938f775b1fed43ca09b0d6f9056384ce40d992008ab0bc44696cdcb99d24ab7bc031b40ef7ad59c7bc93c47bbdfcee8f5643c0504dfa659d794fe8f8643a0bc2f3ac9bb99091af3b0ae2784e23489f71d22f42a09e46b4de865befa2a346de0bc882642231c1f76cbf6094c23002be31429d12222de7450de501cd8b2af9202750593bd38b6c35e2cd25fe67819bd523ca87e5c24b7e517b746a23016f645ec988393a89f1122b62fe4862bceb1dea888c825bd5960d4029831af2b9aa1075c647291690fba5f82dfaf332ed2540c9bf3471b8744ff79882d22b5ae7d318d70192b5a12c4460d46cf1af641a69975b7ff07d41ef2a65ff1e51f36512af357c16c414055e5b3eef7b5268ad64650e4fd8c19f4f2fa3a842d1f2cdf0a49005f5d0350141f9490a5e2061dd03eda013346af81468b1855f1b9718020d0d158973a41b38b270e3ced6b50c4ff42bb78b4a3361b121ccfef2472d4c32592a2a3f4155dc202a8e784b661a1a28d224714853636900f10c37a31deb824732a3d56aa2daf861ed337d7cc89e54b648a78666279d903d475f7d0520561a4a2e1c25ca1a11ee59543d90ee4b80aefbd9d776187edf7bc35b3df1efd2f0c8410d5bca2536c75bbf08f976efdbebdef84cbcdc40916b9d38f1a13f32ce1f679fddd7c24f5f926c1a2c0a5ff8f7a657eb0bd21f1a10a0adf82e62abd75d057b0960a08773cdd04168a40ea6b9c8cb1bce3f101b1fd1fffa4dfcb610905f8279b9d2ab87f2db75757ec60c93937bba28a78d31753e536f04f9e84d6c7411adf693c26ded1a4451d08afb978bbbb2bc12591f520a5d2bbf1aefba606285c479ebe5acecba1f008bc9b4afb3503739bf1e6bec461d55dfda827fb3195dab61702d48c505b88925e2cea0fd0bc86eb7bafd2f480562bfed37fbc92b2e2e3904b07100f8da40494087a968425c85bc743e011b137129fedd7752a66f1dcbbd975e6fb14a047ebad528168f98d9491fa140717bc20dbeeda0c0aa4ee2d0498b2e017e21fcc06c5a8dd63dd56c7d93ac939832189bb20e7816c0e0b3d93e7dd3cd51c79cc27397565fc31cdb4ee34ef9365c2812c341c70e4d312e0076d0154dcee2682a1ae2aa9db1881acd181954a2e1743661cb7a3f524a855c6f05e4629578c357612aad2b23bf8b8e9151b14a008d4cdf7d5574d330706ef158b04f941249c139d7b2aea6e5bfa16d649055a7706e8b883c0d64a3331d08a65e56dac6fd367ea257f84ae464b3fcef0555aacfddd6f6fe9dc5a2c28f2b0382069deaf7cae4c14dde2a4af2540967ab8fed78d2d377d70084c2266d135b61410e1463f212360c290d1c7c4792f721b046033d6ed7acf193405b973818af0ec7e026c80d0a28b9fdc09ea73bfb0d0fecdc347d193d107513115d520c0739fd34ae7525dd795d0a4d6a8bd189042303c3944dc2c3bb913d40a918722ad5f08777bfa45e90125afe3160a9cbc067918fff1847147324879610249f643f88086295a6d7ef1b1ba0c6999f4fe41f2ff9b88d54445b94f58b066d56d405b452b3b38c8f51fea981f4a21da56426c1cbd71cba4dcf362e432481e4bcd317b5bd0a67db67b0a559dcc252b459ea1847dced7c8c8b153e3abe034f70e2b29f708783ac9c8dc073240f49a7609662801c9f89c48d55772ba037be420b47a473329e21e033021ae4da13729695a7bb563f6c277ced9bc63e305ea3bc2b1f9c0e7227099230376bbad2091e51edec9e4dbf0d2854f8e75aaadf13a5adb51a95bc19cf53f1d13716084390d1e765f3d4b296079700bfd7647086e9e01d4e35223a303b9a10fc061962bb29667f31261e7d6d00ab8b044ca292b91ddedfbe6877d260096660e23c6b8c41e883763b636c71d787c019b3eee8665c401178af18a6403dcba1c8b6fdbeec3a0fee6b2878bc03f30a82ea62d2cd60c46524e445205c68cce4a49f145e2aea07be1e7e38e41ccf7e091cddc2ab0f708b9d210c8bfc2af7b4d9b7ab67205b53667c8e7f9274e2eaa3c5e4cff1b6d637b802f189ab81b1528f912e0f398a6e9b6dcfbf2cf968822d95a69b1bb98f6bec02f8b2d4dd4e5ea78dd4648d4e9835c2c5d6ea6e57a633033fef44eb478a056a485c7523348583bfc549673c39768c9e0c51649f6792be29a213655f54ee2df44610776c42223ebf6eccc4fa6eb7f122fab17d82b85941859e556ec947e5af5ed293382485a5dd2e8fe0e34edb3e6a0804e92f23a4bf9892102abd65310a2d65b1fb7147d5a29155deae468fb8e470296c6a9c55f04b2dc6d42ebf8d65e6ceafbb42cdb526f7b1af844b7185234b687b6fdb64a530c5d63b60b062db1a9b2445b6d424f563f784e0ec58c70ccfc6c6ce04c70d2d7e48767ce7ac6989679918446171e50791dcaa69a6125c580e5dcc4ca1bce6eda84dc3539c95f658c37075b16f6843b3f5d306cbeacd5ee5c14906f58afd327cde5c43d5cbf7530ac0d510b206ff85da670d5ccd1b4c40365287bd48fd8ea07d33241f7da4b68fb0b4a4c55f481f24118143c7a52c5ffb219cfdab489303321cd0dda1232eea3ad777538a4a7ceefe8b01e7e10681d51bbb283ced841ed0d0df633d40fb174de1397c9b193c0e638828e82e2c9a20f59329ca4287d61feddd39fc3e476e4d5800cf9fe1f2ec61ee4313409af24d344c38c57c74b3ca3c0d0dab0ae4e8b91c5266605797626ebad7ab3238d4a7411d554c2c233d6c96f0cd15fff9c548cb6d38a7633359294a4c2d203297e0fe8dbb2392385632e915ae5d230d9eaa57ae5ab014b4519fa4aaa953795f9385ff9459b05b7f88f98cce6821e3532f27edf388d9d98fceb5b92c3276c4cd6567375a29dabb52a75da242b7a314809d267959b263df1e6f373b9c77d8861c95569c9e9797aa02b7883e0027637e1051995b20aa1e33db0bfa6a0c679088da269cde95258d64874164f02fe2a716bc6805bb2b5ae2e85f77508f28d09e5a493fc7c4b4ff811d0b205399221532c678a4fa0b95df74ac3c736a31654306a9dcb4e9465a15adc26c57442449a8c83319efdecf6d74592421c0860b68aaf60728912ece1ab8daa507e32caa501484fed83c9a5689c2de2ec0af973caf23d907b403a64b6b1f3c21c2e12fb07afb69b89aa6b81718dd20eb03e086e3cd27a9b64ae9b033b693fc4e1592387b1aaf070269e2f716cc694246582a7a7056c2ff46985a397770620a0b33c81ca8c908f889cefde81ab7830d7162800443649c13961076ba66bf3ceb306c45cd5848f8b6bcb6495f7013fd3e84baad8350d369f53c105739851238a9f0c3bf7e03cde451595445093100e63c376aff60a216a5d51c43ec80bf1fce647237a7f22bf19c83199388be072c3982af0259066fe01afaff41a285f6d990bf365f5546d455ef7ee8aa0c71fc95033068d0fb35e36278a00701525151b92729f20716ebca2a2a91aa73b8b3d7cf1095874df4b74ecbbc19523818c603877fec492228aaabcb49cb0c5f8256267b76647002d288a0d23591f620067e987c241bcd08ce276a073e21b3acf61331edbec6bd129c2e7ea3df45be5808109dde59d1baa6456912390779193ef5177f0ff4e977552ad603758a1373dd6b5094a626b55de0f336a058e390abd183a49cca8a965afc770cd8279be614b1ab9d1e3cf458490030411c2e1f2f04edaf1ff1a33d3e08961988b2ce49c2b0636a076cec93e6b2c90520cdedac14c4a87443ac5cdb189a42223ee196d21483486df2a64820c35ebd7b680b1b7f6a3d5dbb5756a7ae7d79a82ff82ff440b4ca9afcc1ed44dab63bffc93a3ec0d87697d2290374b472749fc19a42ea1db1dabfc41cd085fe6d52a1a557e8ba08e9d01c7db50515c2a32e3c5891a7ddae9223edb98edaedaa01915330d2b84e2e27a2b90ab1098c149a81b60b522e094923e158d9fee0f9b099a281d6ab3e9445ef4f4fd062624736cc9e620d256743c62c0d387c348c2fb60453d74f1a8a6164cc68b81077cb0d29d4d2846ae974afff20a6eb3df9e464f66c47b4bea18301c2eac14adcd9bc56eb6a12c7b6bf45c0acffab7a7b1fe70d69f6ae5093143d7dd900ca021ae1c97700ffd1b16617b151e8fcb7ed40af480580c9cb4a4c92c69b383cb88edf652feebd84bcf52b30df8dc58f485d0e74a8b2fc908bb69f2271a9412c9077331f537765b857be7d6ff48e0601b03755eaf7e5d2434077215131d55aa3a361ced31dd9f7d055e6cd589a5a48a2d43b0121f94b6a8bcb8353526b8c16ad83f7501a2df9bb237f25fd05bd8449b295775fbb8b6abe34f0ea66038f385c2451ea912db50134c77dd904a41ab0c54c1173434742c690ed384ad073ddc05144870c08ce31fdfb5b86ac5fee2f9e49a276613da33d682a862fa272236ec96c36015446e356d7adf5fdc197d757b7d7258eac95d90481973785b6471ac802f726e17dc824a5860dfd60f98f253aa6bc8376c71bbf88e14fcff5f1b0f473a03229308410fec36fd004946a8b6808219e95c75fc36e9dea6cc242d4d2f076e3c17bb0e7602a8012afe9450778acec6ecbe39d865b8e73ae85f9f3c448e0d7d5ca2bba4fadaed67cba29b985e22a2442daad690380f751dadc931ac9285a6054fd05e01a8ed801b0db90749644673383fb808a8adbdda51000bb08c522fc5768e8566b4280b0408c36d9a6d12ef4bc0a31095babf53c64793a3b794eac375708c3769ca46786bcc2d90d8b9e2f8dfe18453cd24f1a495fab30be5130fa2e4a5b1d22256f43176c4a58028ff12eaeec070eb35abc8cbb5beea7a0d3e390864b13ccf18d74debecb0f12e4db6b1b2608da8bcf3c4a6c85eef8db244b691d5732cf20f0d8aab1f5b8aedbf4777b4f4801a491f40ac7f5735ad60c42689138cb2d648ca60fd67548933c869d5f640aa29fc533c928911e99d375fd8a7ebe28309376500c48970cd28c020c7f3a338fe889e1766b276c6d175e090263edb794ac371a1a22b9adda656a7d3e3712cf20dd1413999b0ac37f0ffd3227c40d136a78c74592ad3d91e89becd842ab08a3d0b16d0ea230c5994ac0bc829477fc6e8891778006c50533b83a68542d30c36aa914408f9190ee72b73379b1ee6cdb9d8db26cb50233137ab3cbaacd0736f5ac3995804fe4949bc0dad0e1108f96f39c07e1b63081908ebbf9576235bfddb489460bfb94217d09d176947e8d50dbf4dca0fff975254a3b275b297b6930b2d04d9115e6865208cf1097a0cd1c41df0f8ab22434398a976fe8872c37d4171202fdd969cd66959ff487001c41dc62dbabef24b40a14e733f824bd4bc401cf0961aee662ce2c08e7e71dde9da5e7fcb0464ecd7c7b652403d712bb9200dc6c4b9dc80308b91101febeeb9d0ee049af0670d0205307a09d386e1016ff3e0247e563addfe562bf8f1b589a605cc713459c887111c1a6bded18b0a33eb3db58dec051796312261028fd66af69e9dfb822439c9a0274162d61a1a4c72cf0b2208404114838055e53ff0fdb86856d3c6e4a28365056c9d28b19ae8fcdbad74e631bfe053aad406170f9692583f09452b3f298dc7cf2158b4429cedcf38619e620dd60723a056213103904f39505fe4b956ac0e7e4b4ce3735d2db55e2400d27d5201fd2bc24cf45d2bd8878a0838383450e6d2826565c180a2cfc76cce131ca61a05bbb11fbdcb8bbd67e40d668ad90fd0a11ac827a5d07cfa0555d2b59b8f2f2b4f90e833ff119da56c87108581c2d9b5a7a03c70c39e1005f18f72845be647e7cb63c6bdd8d58bced3ed7df99f355492a32ebe824ffe90b33e8bf8eea189c64038f7870ef9bd1aa9fee79a43dfb806d11e55e24610dd3e0a635a2d039fc55e449d1b62f22c1662f619891f0ab0ea2ff76653c17985fd1b25881be516a66449f1832ee84562b63bf104f8d327b1e56bab6d6e14ee347a64b5bdcb23cf1695d7c85ea181e875c570ab971cdf2c80a15fb49758caf03da703063f19abdb6ce6e4356fd1c131efc9b2cf1d3dedf968608391ced7b96ee6d071c6a8e38ae76cafc922c3dd99b7eb5c25da32c8892435d119e8533fc3bf65ebd02015b7013b82996ec98d18793a6c43625f0ff004762ab4df9c04e83b4768ba6df27a8b407f5149907819b5344f0e4a76c433ef88880293866ff353ff4f4b5f35789694ea52008808e815026fa225f0cd3636f65846fed129935f410b495045dedc4e2a706cdc292203e0e4188a27690bea5f86f22b7b5a857cee935cafb9dd50ab51b32c6ab96a104271a12afacbd795976718602098b257abaed5d77d1eef63650f2db3e2f815b83a359f31a74486571335467c4640d5257d731515bb0ded783e589fb8559e3d7f17f455115860d679930fd5984411c39c2df51e320acfb8c2b8249f0f80501558bc9d97e4edc268de6f98b60905f169ead6517061521999f68d1e38c251ebca319e222f8e48f084eacc6ce695f847925a83d2db6b75ac221d6e092e7338a703e66f5ec3a3a4930e1ec40a7805b167b1256af10622fcf44b11dd191f4f145ec0ac5fec7c99845beed924138ae664b56fe112ca3ff0a2212a043651ad8b579f32710de1f11856dfc12c6be0f817fc81a0e9e22ebc75806103faf3bc26ab1854291ba3ac0649a8aadb04452e18456af98617a3fd3538f315e060fd875bef2fd0f58f8c2bc0d134e14f71637cf880c955edad8e8b611258b9d0895cf2304e46380b28b1c598043e82dd57e44ad06bc617f78ad02b205c9a0d292e0ccb903a834989365267713e54690647ea678a0e30f8545f43420a700b965204ef96330855644eee547351a9153ddae1175c5c3a49615261002a89a3c7d28061d6870254bbfcf8c4d3f232c3b458bbdf452b4ee34f22b3848515cbb8621ae96977019660a2a566dd107b2e69d8f88b8b63a3a3db4c384833cb5dec81772ed77ad64ba5d2f574c2cd0f344976ed58deba32a0351fd15b151547da3ee939f239e01c7243e77da80e84b77ec27a9ade9e837aece030d51662288da86781348da2cf9e4d91fb1cf94d77fa9d82927fd506624718b8cb4168d64f1be9d785abca0fae1fe967e8bece4a59e416fe8fcb06e2a6bf560d9025878d4ec80b8a1a000f3460ca67d4d0f389276b674c70b4222c1c22c5bfbde3e51faf73e1d4e1457d17d911bd02e2e9d96571a739353a1a39d22247711eb86f688155a2726035b1db07adfebdec94af9755e8a48273d18c61d81e6f03afe27cf96adcada8b8e2422475af05eacefd52e17a3dda8c655a41d9b8300f1e6f94d59a743ec7ba5245af0517981f8d9e6f8baf8b86a0c82fbff35b84fc993861b390bdae49f3c4c73768f4106be0437f20d00e5b95a3cf611821aafbafa8c73e48c18a7012c4d20f6cbe87e71f5c6fab6e44556e79f75b643915068073f7a1d94604f7226ad60633ed37bd4ab16e4415a7b80d7903b448f9031760807a180d55a7f1854579b5272b11957aaf1612d02750c1b0ed4a59f6a0260da01bdc294e39416814845ccda753801cba9e02968325471d550cc2b2ef8c1fa0fc8700126355ab49b98e12c2b160ad383e59a00692599dc3a35e8b9b4467ad4f78591a0b8fae470077f55f1cc14fa24a682c61762b12d9f60de3c89110c2408f3a83c4a2a9c87d0f3f111a71d5a3c35fcd49da62b08414d6d34a28878cb2b1a625dae9d88dbb12b6385b1ce48e25584b561963cc230d98d1c2b6e31505279a1f0bf4dd9f44a5b50108abce5b4903110cb5afcd61c89c91f2ac4be423f7de443819a9b38cef2b501ad2a42123a943856ca3e66f327b4030242bd9639c4901443a99f54c2c08d768bd4bf755ebeca478b2aeae56c936ac081d81c97b3081a4a48d49978870f31f7f774a63f0102348cd06621a8465bc756d11f7edafaee277d33e7f2c35ac543f025e1db35138430a298f796cb30bf208294ef18e18ed8286233e477bd1e21438a8088e5b88fc664bdfefad96158f5f8db305babc207f361aa787711edcd0040de5d2b60d38652981e2f1346fcb1af0412113ce3b1340489010c7f373f1b4218e146858c017ebd9305f3524de2fcaeccdaa814c7dc88b7202fcdf6aa417745bc1ed88fe3e2bbbffdfeae08fc3196641dbc86d76238e96d608cc0444359d7de34765505d899cc0d538bf10ebcdeb8d945abe5a1ce710b676394190b80a76b7f6aa56ba74f2a7c86a6157ce8890a5dfbe0a62ae28ae7347f0bd44d3b67461b7d85a6739215ee65c9f304f1d64d34baed53a40b135f1080c599e30fd504f462631e69f743e766f7a8514ded78feabb6ca781789b2eb83ebe056286d212175c9e08c0a5f1991b14825c501f3e7b8b59e242a11768ce43902711722b383c7e61e150d4eb1dc3d7b99dd14b1565b2f98f16e59e3f6d3506d1ae3c1e4f6b310da49462744bf307a6b1d361ab45835316aa96ba83fe8e2e5d5e2d0b836b396ea62de9b5f83e1f76cc1fb7adc9c30983ee0fed148a50489cbd1435bb0d69d2d8ee98754690fdec4ad02506ebc30f255bb96c281e1dad74ed2a0ac3a477f597d961b2c7bd0627a42fc11d00d04e5b59c950ca94d00b64bc0945fb3dc5e58241b4c3c13b846b61424c6c86c751c55749fbc48a2545b6375a0b09f5ad8927359de381f0c4b1294a50d8cc73ba487915775640afe2c3cc45a7f060cb1ae44b2931ac78a2e5539b3ba79184d775a5fae5df3d433e32c312df49171bb3c7ff1206a515562446b7a5a0b399d22247ef327a5487927fccb78aee4d40fa26f7c0757bccb233d8e2af61d588da5a51f5a00f32ca59af193844e11787f86d1fc968412c1af469bc8cccbfd775580dd646523d2fb63ba43e608908e372216bac21f61bf3a359da80ccc9fb3689d5fb058f793d2bbde05e6f1339677b48a606868818db2ed04fea2c00fc730f03586e116eba4642c404df12f6a09879ecd5d620c7af27ddd8e5b72a3790c48239ab4155e147d0c26085b1068686cf17b89e8f62156670e25f1d1b0234a2c8c2dd532606c3f2b8940066deadf66f56a922b8c9cf60da212194af4316cd4536a0de98198bfc9388cc1b7c5cbdeda337e1ba003451175a7b390a11d9e4040894ad34eadf3117b6b3861d7ce0de1be0a2404a40f7de0cad44410e0f892868a392ec0090cfa482ffe87de1dba5402550fa24fb045ed2efbc9461e05b52ae48b35f65185464cf6b462e063f4f2c6063dffeb4848b50b52a0a14105f89f0aad3dac2c35466ca7af93e8723ffdf0271dfc73506cdfdd8320a28137221b7fcd608d32ac486c2909c1ac125b05ae3f11281019adde1c1329cb3df59849f502c88f1bf3b9dbe218cad2299ee2b5cdb14715068dd52809b001e98740673798fcbb4569e6b557a9f6daf4cd90b4b55f6e151cc2fd4b9646e97136b108fde318263696076ee49074466211ef7c49c13ae075e9d83845ead3cc005304d81fb57cdfe489f2594235f94478622c8bf8383ff6074a8daa64024811500fc192f8c1a925a5db63022e2821d52dc8c53e41c5134433693b7f67e0429f6d0a93422a684846bfe3e797c3dab31cbd0e6dbe76f6788711d335c3bdc070c8ad0cb4ab20c22102d82989e9baed187e4e21df4b23ad043d91383869311668ebba68721586a097fa504823f94abf8bee2c60787b4e58ed29486b2290f005ea5b32ab0df41b648a4b8a214457f8d006b68db587d26a474d55acfe7bc8bb9a795e2c101aa468001dccf1271148b7818fd7728108d3e94ab8d42ce7ea4e38e1e8429e985c08a5b5e2112f514f35ba2f6efcbc52b672a1a6a1d8bb31a3353bbd89267469059d30207dde74a498105c20be18992bc0304053b1c45aecb1e82d652fd88a57e6d875f16ef84f3e627ec84d1179fa9cf46e212ecb9728c4938b398fa82b1517b33f1940bb31e13ee69adc6d9b1ac1c4de8c40caeb788364dc5bdef3805cb6e2ceef695627b21b443c45613a8bb2f2ed5a0f2efbfc2aa0d428179a308318c8c7e5daabbcc30e7849bfcc11c8db56ea1583f0de3d322cba806c9249c5542b2c9877ede25c23475ab5727d3543e7cb7a2037b9356ac95ce4e7ba518385a5bb1a752e9abc41d73b3f36286c2f0599d3e9f23895ad4c5c4b442811bb430c470e634d0751a5c5eb0b4eba30f482f35b67acb748c7a7df179c043f661a2a1531e30fa6a7ce50f9c2162097b0b3d168abbec56b36d2889ab4a8af033097c9aa15182f3f3baf6508bb669e14dc0fc26055f4699522b318cb6fed27025105446dd3c9e62d3d796934d0fca083ef3e54123992cd5be88cb6aa4acb41ef6c20e394e220d368258ebcac7cde12b2a3231441db814d82110e9a078cd9c3afa8e7cb06bbecff84ddaba5e21d0a20f66938dbe31edf9d6f0b28b8bb04167eca3b2ffe703a230e8ddbd4bcbe576903cb061a907e2d01feb3220be336bf9640965e64a2d71ab29ed35b0bbd0db739a0c3a686f44b2d3c4538836f9bd32c4921b8867036bf9e0df731b46458c0b24100ab9daba55026c39d8ea78eab8951f7248d77b119191f91efa5d7b698de7e209089d1b452f538762a8b6936a7da646460e43d49d78424a3848790bb9c2b9bf641b1dfcdd9ab695301333bec634e610165af8860cff21e80f301cc0053cb26351fb4160aca6e99fc9c1717d635396a8052fa97029219c6570642c519ca55d40883f1a49b1b94e42d44da967bd7983474dae43a0d9c106ab6957f7bd7e98f919cd87e29f46b4394ae40724246f783dde38bf5b286fdaeca31981fc047567e7f6e353833e548ba1ee51ecb2cc6f575737568f203bbd412c8642d36a14c10347b3843afe9079b67adf8bfbd888633c531ce524aa8c423e4c106a287a733c2dc49892493e29a394ca38c289136c34fc730d6400d66e56f5befb615a3cf83910b1a35f704e7aa114a843f0bcd23fad81276504b8f31298046e11e91332dca33890239c82d924439f258e00e3f4e621b6ea4a645fa1c451a0383913cf7b9f070861a92b4b935b6a513803dd7e65ccb44ae88611f7af66ec68ce1afc575f9241afb39943550afd4e8cb67ca4e6c5cecb86de427b290579a207cc7d8252b27062dffab384ba338d4cd6fc2573f02d4a0421a51ed218b19f2f0fe3d81eb819f81b4c6b735a31edbc59ebe5eba4b081cd151ea943052f72e036b76b07a70455ea383f291b6904f1f9eab6c793b645c73635108abf378a9571fa6a505de763ec58f9195c4264ba895c09c3be0bee4644b65b029d48f3c48c16859f04251fd2bc24d5d83fede56fb05d8ea311abfb620e56b13fba59fef5f22c98189d3a94cbed22b0bf73396d9ed71a986d07bb75e56f6eb4955ac218b1243c205ddc5b6085da66fec5fbc41953b27b7b151e7317c3e6f9fa9006f0f2f89cb53092486577244abfa99065e705a39e4ae5e2f9182626c9c67fb0c3c17870e6a3a9514a789e90dfdf977865d22ce65218a910214de41a7894766e9d41b80aed92573c0c12e1da0fd1592a78bcf60f9f4fb0c5fa1cdfbc792f78f9714ce6cdd692c76e05684158b827c2fa26f03a9dcace322b61a76180d8e91063a8807731bf46b5a4f05db19373b88d85e5ca06893277c57bf2c1d781aadafe2256b599f2103d19a9ebc7c75c42aba47e25e31883f138f7e5b214a3bd32ac84c41ea1c60dd43cf2aa7402729e7f6cd68bbd47e26426a839c8aac6faef6552267d0d7894bf5e95618a6d7bdffe5c5ede31515e1b4ed325f5f1550f8886138ca405ef357bdc79bc0115462404d615762d78913c8f9292bc007c9f9abde4ff78a6cb6f0d2640ad4407602afd3825f50af05fa65db34e8c8ebe1460f776ec01e512e4b64f62b81b3367c1572b7489416368859071baafbce97d325940304d6f58029294e354f9e03f4d03a42e4cd0e30b88c61d9399fa25f076f9bf896f4733a986d1d9a63d17e26705f1a681a36bf5b9452383fa018bc48d01a3f9d8344204c989ad191c1b6ab65993d57ffca0e9e931f34883821825e8378a74e824e48ac94607602f5f2659d35d41682c275c861afa189b898101bec6e1470a82a16ace3c95a03e878d8b76c6dad9578668fea2d0952778403f082a683c5df519c0a2580eb9dde228e0284cf84c2936d3777395d49a13dc50d38bacacdf6cf2003d309196c92c17983a179777451abc874331d342e02c115ea9147a565968cd52749918105793517e9ca35af49a18626843b6f1a63fb087e3b4133f55cf2ff79ad6b113f40e04420aa1cdc447c6b3700b6041acbc2a17fa81712445a07f070db66f4edb4408a8e499fa7cd821908bab367cdbe5f235e3023c588d872f3f415ffe0c461d2faec735a339303c63e74f57088cb89775dee600eaf9a53e6c9608dc9a8467d8bb5b4eebd69c2ed440927c45337184dbc906963f627a13f13185898faf4443dd558ba30fdcdc4a6144333206c945d7db4d5d1460596c31b2c00e435d6326e95e239394fd8e9bf411cdadcf6f9899195b0898ae37cc25720ad74042788885fd66da309c6b13a0d73bc0678f0afc6b0a71fd7414e880da125f5158d23fb53567db4a42141a121e7b2326c50d3ab3ba34bcd2032ebd41237c056575d26c85c426a8ffb575054ea3173f1c6833fe8582a10a269bbaca3d082ca1a52e5553c871f0f82522deb356c416e88538dad8e1b4b912c176413573507db238d1a725533db557c2285d9304e2b7d19ff4c4d24fdb48cbd9b6f19d9194ce5c3424431c0fdd583ab25305ae6cf6b25811edf0f01f7224df67873b293930dade3e3672055224dd0f9ed455cfdaf041268c8f49a7beb51de0aff27365b215a241d71f41174257eeaafa0a68beab5a9ddab171a9db0721ac17aaa90242b6943c394feda96730f8f85312d12c27a7a88e8049486f162b3ce5b02111db0fe360ca416d27796f25d9d2e78ed1e5ebbc0a20b4083120865fe96daf9125256bcc530a291541fe87c72eab57e15c9643d2a61e4db5cebaca8f52f9a85a0c78a40ecafd1526a927f18039af82075cf1bc0bba98f7a00402c1b803f4c574f6d40db76cee91506d0da21402298b2bef6187aee3b85f7e153386580b82914a4b3c69cecdbf1a108c70174d933c9db0f54bdf8f546b514fafbf0512de6d20d780a002bda80a5726055bf8a28603219d862fd92910297e4ed0227a3437e42ae3f78e8e6e22345dcd87ea404d0e29f6818bc82dd1da4109e030465210fca758bf462a474af16fab51128c5cdd66808b9e038eed7cc7ef9956a00bb082b1c4685bd314aa0ba2492cbd7d10bea7099d18d1d6a377bbf1ea4db13656f600611c12a84cbbed41d571aeb9934036ed40536fcf813125b2ebd953e25bbd2a45cb7a24ee5f6622e8ab37465619bd178175df9b7c95ac64367378c3cd0140069f1a771f53c1aee04e1f055038c566b91b95c7ca22655c860f06904f68b7e18261c129e2dc1066f3675361e66e7d2ab46b72a4c2a377378da04199aff21e80ab70b35db6770582ba46656d2137222a01a683821b72e589c8aa7f49217a74c628dd2017a48bdf83b2f3462487b2606f2f47b1eadd7abaa23616f5adebf77a39d3d323d14938ee88ceaeae23e1b4c9b3e3ce1f472632f5b5f39d76c946a67980a135458b3ccb1c9509dad37b522981d514b41b4c131642b50067fcc118d524317d9e9bb442ce396a86e5b428b6a40b0e6e9e857065be7c103a77ddd2532889c1354383e1f9c160afe5590bf756109964587b7c9f3d92666eb9783551511848096b8d8fd30f17c9642c58cee5c0d6de55c522906e7c45d0939454bb44fbb47348db92fb76d51b2e1d7b32abbbea0d179d49ee3913f8165dd8456d2ba61a5000ca6596b3b9f3723523e0a7d82bfd26912cdcd8870dafa7bdf5b480290a8a735d157012a965415686d529745418d21602241402b778291d72f7fc183896d77ee248d3fb8b61648c9c9a8e19492e106ae93b0cfc4306970a53bdf9059f151b3001eea9ef41e1eb894adaaf54a13bc734fa0e6f6112685be9f080717db0122d99faa1fe97e05fc1c57e6cc110280d9ab0dbd8ca86243f9fbcd6dc56ad9e77625902dcbfd7b5a172cda669cae253cbb95c3c97c18ec3584f70c4491f6d34a2c55bca6d25d7c99801f94e7661c0a03320031466d9e9adba4e1981b7261dd844d109016712db57388c1d35d1b999928634f84d5ca611cac5e53d2e2039b2d2c38a0d3ca438a9502964a21ed1ea5ed8c044b3e022a4aa02858f29d365559f77471675ef0755b25c5bf04c2f9f3b1f39d920e1b498a3f92020833c2755565baf15e96b2b266a118d40b39653c63033d31ba1db30d33b5f2e9237b2156a46bbb2c74619f06619a53ea93bd56ff1fe58669fe7511c7a990ecc1a5ed2bc9e6d45f87e5196d40abc44772e37ff7f101988e8a9ebb9ad25949d694f124c02153cc6970290d864c9fc72aeff8e522298c4cd489ce25e2789c1921c1422806bb805c617c8981f9af5fe0e4e9b95e6e60fa69beb19c5fca08a0bea187eed957d3893e77b59a91fc97d7290f6c23b4e17520f9430e3a898c7259cf76caa23d06ccf16d36e0c7900dcf3f1c0c6916d425e20f7bba9b45a1d09dd87e58bb85a621ba8d74406a767ab59f97334fb7bcfe113e966f57ea87b90f6ee7bf4ab3660f2436c764f87e32bd6a4a5f978fc6e9ca350260a4c1d4d1dcbcc7c059ff8de670c2a5faf08f5cea1d9ad4f931ad45fceaab8ca38719bf8ae152e302a7e03c453bb3338d02c226c1776fbe8e696def33cc9a8c9000c6b680a5d20055aeb5f01948480f2206be62f668247ddf0c7424ca4916f324aeea057e551b0629edc70cbb75059d714fa3f5d707c4602e27bae0361062da7c6e503e62ff3c30b0d6ea39534d6c23d2f89dc49d6488392305f499865b2e861f20775641888c38bac092a1338f422c4e159c1e1473ff24bd214cd639a5fbf5823bbf3537745755101814a4cde63c0db6511d4390fce353cfa12700aeef529f39da47d3d78b77d7ffc08871e5061d166580596586a33022568e0a95cf7736f611b39b315357615d4a3f6f86211409cb0cc64ffb35760123cffa28be2fd724596afd020fd0606d159ef9d5720fefe5273afe00cc8b7ed5865a5d488980d67ef2092d5bf331f2fe24071b68d51254e57c1881dbef8b4bcddfb4553081196965fffc1b05b39562a191b41e6ad1551f9afb575c21efbe8616e516d9092005a6084a09459996d80416e9ceed1877dec58fb910045aa73407dda5e58104366d3712aa903d766c352b84e78676f30cbfd99547d47ca08c2c8728e5f2ae3df8a8312186375af03aa99dba2af73c21f87ad675dd8798a7c997a65a3ae958d01b217cc4b98bb08a3abbcb77237092036d9bc43092367d4d0aaa905cc39e28e11a72a5045123d211ca54d98e669240dff4883fa2de45daf38c752977fa811c1b55609c8309b3550a367079c1f6fc8ed12bbe2dc4c9553470a59d54d323420762f84022764669e2bc16e67d0bfbf723c270ade8cbae829256ae252aae31387d096eeb18989067ff40ecf6d9be0342960df95780ef81a84951b907fcdbd61bb4d88492c590411462e5e1639a5fa251c03212ab94e4778ebcd48ad5df206b2fb4fc4033833b9034bd6ead0673578d551691020256fac43fb95aa6ae497134ca08e7d3518057f3261387cbddbc1bbffe402c25564a7f2af46154124ac783318364a6f22f293e3a82528bf3c284babc3d064f142758ea9d291de32f62ce0008ade2de0a150a61c86b011430a144588b7ddee8ac29f9fc767a89615593c7cef9a3e02db71efb96210ffc816057bdfab5fd9edfed807ffb3cd84a99ed564ecd5acbf159a7662b9e83f401c9489b65f88d28c97b3be308c3119a80eb23877cf281eb11a6be5e765cefa15ac4bcc8dacf47d8e483877609393d19f95c9a51932adea06a1ae4cb3c0ca4867dcd8dc487acf0cc0296852ec641da9d7c90adc81ef02981c82e33da89718949f34877cbe0787bd80b8a88a08b0d6c8e100a911a79aabc524e257890db7cb927f4305ab2683ec9d378019880afa570ae15f6a52e8e170567c9a91092fbc294a7bf71f5278c5f99b46b78713fcf3b9810f421acdb2b014059e9cc5627e96660bb8ceb2dd172f412e4f6c614bbded915c71ce29d7d6eea3da7cd166caf4ce413a5f66002edf6b1d496bde3823c26117940b9bf5f4949d6ec4df19310a57bc43a6ca03b020a28f1bebdeb251d164edd02169a57247af1122ca37431883469aa901e50aee0b69745fa977c45a9477c1f45acba96be8bf42a68e4a48ac6ea275dc87d5647e2e4bb616ba6f4586aa3a8fb3deaa7b8f082cc90e104a1611654166541f14826d253082135ead870a659606b596b8adf85934b0b079d1e7a348209359f8d168b15d0ef918bb3dafe822f91a9131008bf9bc199f3a422af1388d5291f23219001a3f3d5c5e109fc8d4ad62a06c63db3ec3d1f1c59bd61ca52b8e4f8c4840570a2e9e26665b3d8541ce32b34a5b12d9c425857fa1bec75d78721537a4ef452ddc253b79c087a28c5bf338978dc89be8f76cd64a252ef0e7d46944b1d89efa1889ca5c81d67d660f50610fbe71ad304d29f313fdfd898071a4e0562cc3b3a65c72a4341a59bfd92fe192d481032e53482eff4d94565562c8f75638a1ba60594a8156699ae300377c18afbfb4f302ea6b3963704a0410b565f7c971d249255883432743e5001523f663eed6660591eaf966200fc61e1b87911d4c7522d50ec5ec51c15578cf50f497b113e1da18444d50dc7e723f0363c352ed6ca3406f959e0f064827e72f9c80f923804a3555826927e11609a0eb522669404843073b098ae0603a2041c38a2f4214289217cef2c63ae05beaa00c4b77f7620750c01f1003331775706336f448ad32d03974ea0ed155c22e2c0b50284ac48930d58be043c9628b8faf8661d782ea9437cf7dc50820019faa5d8c33e845ac65b064d007cdf0aef93ccf25126d3827b7c60497cbfaccd4530e981976044008879c184324b2281f396bea0b15df5aef0a80ab4a74398e3110515c98a8de0caba4a43eb33607c9a1bd0776134292c039741b8e986de6cb8a66aac1ae7bb9472fd97d61c6d8b84070b1ff7096d4fdc52e66d17ea857ec064a1b77821eaba5c7cf25dfe8dd9188c7a70f327a4386953898c50515c5e07b0c8d6e20e0c40e749b414ca0dc4d78f302122a0d60d41c0d7fca4c5f851b06e55b183f78e629b3fd93c1677a707fec77251ee896bc52d6e13432c95e54ac7eedab5a6d4f4bf009343e6a283a80128dc03b60d32c47e69ffbe15c3cf1539a46079ebd954b9b07ca34564f3051b25957b3fd9c146a43835ec85a59bdbece417978db00e2d86ecd767eb9db491a3f74740fa159f871790ca84094bfe32f747885cd831b693d2e63e75e963254a313fd01e86d5d29436397bf7d69a7825a8084a5d17d7fa6f130b642e0e61f86b346e15fcbdc868f4409d046959b16662eb78ad806784ba3bd0f467acc909bef00a7acd467eadebe651ced6543c8d98538731381fd0a23cf0ee97170830e471309294933439d001954d21c72ce443210703b0805e073ab3bba107a02a78b87e77fc3c2384222163c35a4c46582b2448b3c808c48c862f1a2b4ccec42968704a2a951d320da2c846537b0fa1b5d854da779109d7dff4dc555ae775322a750112438bc976a3628945153369e17c1264478f227c0020a773c6437c7999e6764911aa5d8527567ff4cbdf0143e23842f5ad3c06050cd6c4de29450a9f2e0c9d248992872fcc9ed18dff47fc32527d0b6fe889e000d54e71ce5cee2188dbf37fc98f2e3d34873d09982e4011564bac12adb29f0e5790b47d2812800808aeb89821365525dcbf8bab4ff7737a89f634a93bc80acda41e358e611a024f02399520cdcd11d4486c0908e134c2f3c7c18f93a5bda9d6c5e54118598f93131d9bf4631b0cc424b11f043741ed6204a8c51808115b9e4b4dee2d50a31608f1414c3fc4de83a5c7f1687cea2eba3b92782603bfa73a54bc78fdcc752537c60b0f5f1fbfb4e05140588636e9918dad3f48d75ce931a02f39d4fe0b39a7d0eaa3e224ef825cb7d94d25380e1fb87fc36c760f3f6e6b62e2d52d4d1682f8e6684f49df629902262fd646ba2a011e70d14f3ac26fd3767c10709ee101153500b44e422a69cf21b5381c6f4b15f724317092d9fd7af23e6e97258ee7220020fde3f01c465d26bd888663966848540372608437fcb966a8d309a7d75858d131e72f173b6b85f1a27c80a88328a1577b68d201f1a77bd0dc113b061d544978f06dfb4fe840c2d8981148d625c85dd069744b55b65908bc32a4211568bbb20af3525d106d0ac97a0ec3f7f27349087e89dc5ed7d33f3bbfb5711904b085b6cb3e3346e0c901a641874a6de568564285939a19e317c7b4aef66b744d7ab0163911b1e911d7bd2f5ccefd9fb12a298240ef6a837f32714e3709c6e08ca9216c981c9b1a582984dcf0059310c09c55cda92ef77a329a8e86fcf0f744767a6c4616726bab748c5a6fc32f1a05e45a1d84bcd20c2f0275849aa97ad4d3f0451d0ce73a04a45016f760d36643afb9eba6d021ecb6e53b912cbef11d1f590bac099b3e98e8fecf332bc009c7ce15185796d3d2f8acdcbff84a3b11cc89eec9296df8fed6a231a8f41651a673f14540c1190baf6382354de66ea56ab686d7361281573ff327442f7a085429844b800364a662ebf996a6a3b21769b9cfcbaf41806d7cadc138b57b44a2abdc60a731d9c54a6c8323fcf279c2fa13c5c8e8b97896cf3c54be90ed130ec753757511ae6917b772dafe94f521461d63cedba8242e1105f28a261632a30db863d7e29e7835f3b71168cc8405ae199b538d9e3a5d89d16fcb1a87dada4f29fbb52b717efa0930a636924b530aa4958d20941a66ef0564d55ac8f667807bee96e083e2d6bdeff0d73807fb2e08a6df6154fdc05ebf09dd2603a9a387f5d6f0d146676f5274409f10e064f8d88f54a6cfffe2e69b994d5d69757d57c921983d16a7d0806cbef21ebad0b1f139466ad8b0c0cb8a54e53c3080c616b026149cf39c3acc29e759d0fd6b54dd428ccd182614944a9b71adcdfbd3e8a95944f79b1337050feed6ce72dcd4fc6b36bac51a05083d62406d0d4e83041632a9e84d3d0ac4ff393059f7224bf0ad5a4cfcffba0ae9660ae3f350354522aa3394da4ce1383faa6723b8063c93262a593a590d76d00f38c149e69925b9ce9ab15c3b5e88f94a3980050ba82eea1d90ff8530787e72564125ad5d6c9a2347d4d1b1bf6fb712fb96bcf2c20116c762b69449118546829be48b8d980e1e04712d4c90136832f2fc03bb9ace910446bde292d37e0ba2e228b80ab527406c460004db2e108a23374d737147b1cbc22532b8cac84b1bfa9a55ad8cf29fb11e04b18f9834763279aacc000b88650c893678a5d1f4ffd844f7ae79e04a33a1db7b89e7a4cded60883703d4c430ba44c7990f59b5e0e1537afb6caadc2d649b18b19c4b236314192e3ab8c5c62f007341ce35a86d809756859fa14afa6184296f65a4c262b14b9bfef9795860986eee85d52d25ce6ad99cd48be425b91d3b6a18236b5a6b327532a26d2c2d8387a338169fb882cf145b7e8434bcb7d829f22f5e954caa9e86a1d7bf1240feced94f80e00eef078feb402f008ff05ccb20eb1a74bd61089d92b519064ff5c2176cf5be544a2bfa705ba62bafda1c7b1551cb4460bf0cc233e2570b2068cad2dbcf92b112521ee8eec2d9703da3b49fc33fab217ffbe97573271b867b7e6649fcfeab4d359ac0e8b3d37b2eb1bdf4fc38e5a8e7734bc6e282b34fd6d292528a9d92740468988f9a2be8e47a838d538a0cb08b914e8dacb50c9e996e91cd9e63aa1a8df0533a60289ac23c577340e6bb490676a1f1c23fc8ca6f918049f05425f7d0d240f1562f8e05ab891bff85ce6fe67b7f265e1903d2e44d3c9a030cf1b61d62ac6cb6ea29283319b65cd3d1ed99ee9b00fa0bcef7f83076494857a1aabb73d8c8dab2bc97452e2a10a1d158fec1bd1babf8a836dbc0924759b67a1168ddea7ad06b73e05390e8c92b79703e6def143f28365b62e3c1e0416281da2b8f3c9b3adcc2398b0a7a4a75d9617a8fa5a27a5e9123056b1adf2fee36342c98329970c01b0e9271b4012653d4355ee0552f0809c288fc352b8b71bb2b2adfb224fe3c3fee3f6c9c236781fa8f452c1a3da1aa50fd8072aec2af1fc479ead2505224c0e7cdb00cf9712e282d964a6202fb6732c77bc425620b1a36a5f60bdcab24b99a5a453c5882783a1fd8aeaab85865842dd03ee87b3b4b7713b105ea4618ac3563234e2c2d2a249f7bc63e75ab93663b324ebca3775ce4bd3c11e40754d45fa24be8fecf73240d0208a446324c7f5e86c2a00a735a9c8e21dacfa4acc9673f33bdab6cd97cae66492989a4cd1f0a2431e58098515a1068a1bb703539672337e9b7b25ec0747737630c6e2b259967efd4b77d44d2a92621a25865b3900657cab83bd399557bbe6711c0fb0acadeb930f7a42feefb9e21efded7a2329fb1a00fb0288e463824882efc21cbcf93f671aa687e990f23191ce25f9a4d0d5f7eee8292bcd4fc031a1b9cbb0774cd2b8a792bb8d81fb55485873b875183e5f91ebfe9f1de1d8da605fa615e3b372b6d5dda3e70451c252c39d4605fed1b0f3bcd993005a2c398c6d0efb2ffb421cc4424563dfb530c7aef1292627ee24226c6bdfd1ace879a94f379bce15e2bc50071bda35c0beed005b269478aa892aa8f605c5556668fa685f7212ba0523881d261005b245b6301cbb132a45b636bc5c8d50876738073908aef2e92dbe881853e0b9785630679571d900bce84b8fb6459efe8c6d6227a2f5be9b8a0e274e6a57b143f3e52a8a3a1b36916575a00c0a35e238e3ff4bedd51fc1a80c7fb01e11d04d4898ca07fa9d641695cbfc0b7bb94595b05fe9fec182ab259ed771f4027a3a892bef38142c92eff302e5b4a3ac9c1a95d339ccc253766ebb29b6595d32d1190e23cebc5338cf91b4f4dd9c92bcc677d392690519712713cac72f3df2161f4e22e4c153ec8dee26b4918bf30b507460a93cc3d6cad0c40eadf6808ba37e80d93e31904f568edde2130984a123d19d58b59f02915942a54364e8540560fa6d9aa95025d3adcad447d05a09b665f02d8c2e319ed1f66f8b2e2b11392574e8d83405cff9a54b74fd2da9ed6e0497a530078d8d7832c59e37c813f6f4da8da2cabe89ed55647de9f912af9cad9100f4f1321cb856191e57051196aa9b54c0061c834be101a4d700ec16528155c16388913860ded7c62500b6098be0589ae1ceae8de53123dae708cbd9c8a88e96472e009737a1ec6464fcc28fe1983d8abc58f5fdd9353065bdc79ff750beee71b2cd45fdd3251b223a95403726ce4635c5fd20764ebee9e2b7e725afa457513bddae2d8468a907ebe1cddf204c831422bcb07c36d046cc0512e1861adfe67af02477513763bc8bb4de4f2ae3e04a201c9af37c4b8bed3e8200297795510a0f166b4bf301b8020615120a8ea242ee1da6ab60bc6373cb32da51fb3ce051013a7e20c519cf821b7d1c36ca1a0f9854d52f799b0454b5da006bf3b83c0853995887f6443a7e545b4c29495ee0ba8bb50f403ca75b35f61bfc0948c9e033afba4edbeb576322d49035e4cb60d113b40370cc87a35328e1f26f8dc18cd70cfbbe0abf6a81f1b0ec1760e683c2bdfcfa11bd40c2eca814f4b4195819a985203b41fbc98377f1a11fe498e21485ef200af052d2d8b7c40c87c8784e0799bbbdeab5de79328f8803f8d942a24e83e190ea1a0912fc950220ec17daf0d5928d2e8e2de07f2e076f778b1ff6a955f2d1602aa5cc1dfd30c3b70d0a7f74d2826c6792a6e211535bf946a4f50c684ffa188600acf10f00886014d881610f3c6b3df2c8a5a265dd2c45a7ff7482790ad62542af58fb8b339b82fdc171b28269acb4108e886842f7121ae47cc9fc472f4536506478e182201dc3e246496513c05920a3cdf6a8c3b47d794420671e592b93cc258b73e9a5d6901607523af77118d2b7e2294e2d6ab989cc80754359177bff28ea4341483e3b57779c4b80f5a041ff07ce5fcd9bb9a2ae1b624f6aa544e11c5c55f7dd8aaf1321fd9aa92e7640038545b24f0240d7257de4f2f4b45a08cb26eac54fbe52e2a0267256c1be98f6e7a6eaa3eaa5794d21e19b3c6341bab8871dcbaa5ad1b32916f152f7d5baea0c0a9feb50745a268ddd70a3c1f73e4bd7ff1362d55147c2a3926f92a4815db9c9eb1610fd357702d3e74cfa28889a6f3f38caa7962f5670a3fecaf725d0048036cc1b83b6f84aaaf44d5e9cf6ca300d393b03c517c4c08aef9924e26e7d02e9386fcef14c4ae018c91982f1944a7e5127acb6681bf4401d975fc666314642efbb7793b047d45b3dace5cbae92cf46b1e97428653ec23c06f208f1a4ef13cf8aab69e3bbd257e4e27dba671f5e128a4b47c1e876d192209c353f721ce48a55374b98a697036105457ce1e8ff732d5d74b10d1e68235647a86ad785262ecbeac5342b20025229dc4e2735552f37da064f36a573e0913993afbb98938dd4c7473cf71b0384a630c3d4ec85d486b69525095815f4797375f97a045fdefb535c683e5ad08cfe3c47a0b75792b35b6ad427f71e0106e2229a3d83aa9f22ae155bd75f84151f5e24a0c2352dab48a3d577cf0bdeda6d7cb8712e48a1d3e25b677ea3742f15953e39ab5621f869ea1896f6536c472d79b2369e70f98ceff2065cec129d1b389417b2deb536bfb04dcd088d04189d9765182e11e4354930af9a80361d397c6cf92f6d7427f2bff27f8ba94accfaa5e84384e45954d02ddec3a6504ef07a1c45f4268660d2645b258d2734d885acde6e204a8412f7d7fe25a0c3ae57bcaa747e6c8aa9225a71fecde5da8cb98ae17192df28ae7a6db30ba2bb1fa92bc051a1995e8d1c3d98c474af51a6ef010fc9ec1956400d1b6908a5c5dcd5c408d9b3e20807497ca37247f17e1cfdcb7d8e44556b32a898eb0d2782bfbb90d68e41147ba2170536329f531930daaecd543012cc48752177aaec84110dad6809c969a0ab6968e323e658b64538ff43c5af121e4f66399092acf200a25d932ff59a43dcd2da420c5ee72d4f52ec56e1904afdd7a87efe2431635a7ebd7d81ec5cb836eff8d4b22634ebf11d1438f91bee07fb1c30031d8da24c10b1f6b66d48c638d48e67af9887f7e59985698c2c1bfe48ef0281115a153d84c6e21bcff24231662374f7202c00ac6bff57307432222bcde5d86c73597deb83cdfd73bf2f3961308d2f4eb625b46d16b88ab83264a2861f3291a4929636885286d79bf9f45395462169ff6bd53e898f54509b38cf24570c6dd89601a5028cbe528a85639bf8ff0a53995cdbf18bb8fb9d9c9abf96699cdb4e7b067f82b8e34fbb7f095c98ffca8afd10c29b1b217a6d91e8417c1f5fba6725bbe3895db33948763429a69526454262779520cf05ffd78a07fa8a8997174a8d7b2fc34d6b39c6cafed1a6032546b2f1de727b0385932851a133acbf694ec0fc4ec9565958f480b698c81431924924c8075e56a52d00327c80ec2e2193cabcc2810b7bbf0b46e5bf39b1ddf653195a5aefa3ee4081a218e582349bec13c5b46ad910a7d036f0d2c608d9ac8feab9b1ce781818404bfba61f81394d4367bc8bc61157d70ec7d878e63982905418ab0692e4c5f7b3ab76fd588231ed030e1003665fce7c9c2440c421d28381098730341048d10df3dabf079eaa304eace1e3fe012408a8f29a844371f2546350d8787b435ccd2d014aca1c78bc6cbad243829972abe2acdcea7b9a88b50a90f0c9204ca3a3f9b54305e15251d2f4e10ee00105140cae798342b731c20e6cc34bb3318e4204cdc37d1219c52bc53e32e6bf45c1d6ef7bbe8e72ef9c5aedf5f175380a7e0a7b76ee2daf2633ffb1fb5d61a2184904df6de7b932de50e8b09f50879093a76447829c34abad4df71a1b6bdfbee7c3ce553cb49a485c4d6ac23a5dd58e7d27295dfa695d2c26b52db287b55a0c24b4ba11dd5d3c70a1cc147820fcf43e0a5edcdf3f8a95d5611f2d05a92c2c753e9b1d4e381b492f4159e02b9b582f156cddd0ade4a83cd3945c05f9af5a7813e699f4b2d3ed3a8c33c092df3e47aa6b33aad33061fe11a186637994da6042b5ad57ec587a7dae4c7f311ae41a789aad475d94d66b2b48d89dcf86815c12f55871612d5e5f391119c3a0fe91647e95ca93918ef7602eebeb614c00ba73b8fa8575a3ec233e28e9eb1dae384946766867c0821bcbbce92df380d65b80bb84e8b340839c2853cf2e31ae03a2dd2904492a4ddaa77fd94ff68521ef41ed2a4bc89963d1569b187b4ec65d8652d8d8692acb29b0cfcd46828c9aa8ddb0c15a9cd4458c729d650e41ee03a2dd600c59d9556dae2df774cd354a7572c4a7e529cbeea58ad187dadf49556a230abd66318f68a5ea66f6573bc5bbfe396aa53f7fcd6b7ec2c036f33e8cc269c52b1d38b321057a71bcbb4c7caf4ad761bc1cccdac4cdfead22c3be9938267503b49bb89b2963ca8b53a6b8297e9da5bdb6dd2b6acab8defecc79cc8f7d24a3974dc7877658e77a5fc7437b66f46c7d5c48dd79f0faeb1a9e05171b7fee38a7dd837c5ddfa327d9fcdf16e05dee1906dd3759795e9cb402e7cce909c1ed7c791325c2347a8b8f559d7d5707349d769a1869a4bc475b6aa26b95f5a084228d3577e93e9cb3a7c63bfbec9f46415518a76abe227c8ca742389ff1c141fd2b2a712edc4ac4cdfea17fc68eea97832bb595606deca6e3355738d845a276d899f145c637ad73bd98dff7ae2a0be67a18c7d302f2d3ce941b6bdbcbc88ee494d569a0e8fa8eec6777b52f00c2992e12c2cc2dde9687821bd6071fb431851069a961868a8b91de35e2e5b4f0a9e01df96b48e67c4ce69125b13908267f061ded4076ea82dc136431863a4674ae5bb80e82b5031c59cbe7022909997dff42d93d12a2290c9ee00dc0cd856c6ab38d3fa2e0878ed0f190c048ce816f8800b8580b77e93b9eb2e743193e670e640518afde1e6707f78404c11ea6762a445448e4a55ee0cf9012f2f0a50c0010e308001c48861125304f8aa995c3145a0947efa1543692da0ee021953044ae9d4640ca515614a51b9d6cfdc3a2b40a51501b7e4e670b2a29fa1b9d2222287b3b9d4258199cbf67240f44dec6572e9756bfdd3b6573f5dde1a44ad94b224105d19d17d175e5a674d60fa344331c4c1b932af00557eb25d4d32c249dba619c82a98a6699ace9adc80fbc31f62f8128a6086c69a8991f605326603ee0f31fc1c55f0f1509d132287fb0333f363d4f813ac9ad42298a1b9cc7f98b9932581bc3cf19df5f6304d30e7348114dce95369c9b315cfa14e878756470d2d24c12666fa4c8c8c26b1bb5bd6701241f79ecbf4cce384702217c4cb229b9ac47d4575ce654ed932f574df6ff52ad05da7e6e9f5e445b7b0186eaebb035527a33a2250b00ffec13554d00f3815fa1938157a47b121bb56e85486acef3c2fa106d9a5e71f4e08be94b570e9c656b8945a0c844b7dcc39abae4d75cb38c508e1d48c641068157a4a9b5ec80f1f4da2d7c09079c005419dceb52e4ccfd1b44960bfee62fa7152f641698f26d14fed0c593cd38be890517aec331f41cb8e20fc657514015a0d5cc7ac8ecbea704f65ce79aa59f3d59a16a5d6034d7a344ec79a34dd12a71dd1cb534a27ba750ffa48e50fe7b4b07bdcd114fb08d5c9d8200edf11f56a1e47e34c6a524da2f4f5d9da55280d1910da40b67fcb6cd3d849e99be6d1679405f254e8619a690cfd43424fb18bf89029b9747b492e3d1cf2bc30d22dd4693dbd4e4d4e29f54c5804de5c3ae9bbb9f4959a4f85fe69d953a1879ae8a9d09b6893ce3a7f69f31f8fe65e367f63de8b59866c13510ca3306ad679012fe478417331152cb954dd668a1c7ba5300c135d27041704355f313bb56da6c8a5aa3bab88eb54a5aeb345c465ad4d245ae9167a4ba3a7d194de3d7af7281de2d2b7109c10f323ea1555a94af5e9b3e7f24e2f7a2ef0f47f2ef1f44e06b5258863d5dc210f4a2ec24316830484281a31b5a007d388424c13f2a185ea64e4dc290bb91eefd655ef66f77d7242c0fb4ec47bef04702e0e36e03e06dc17c47dcfe43e00dc67d94d64a4b216c6bdf36f9959f408e77c56e0684632f89c17979f2bc3e5e7905cbf1e5f9048111ed2e35ed60ed1c2903dcb86121d7041bc1787bcf7624e6deb89ba392e989979729fd84ddccccc3c396747fdda3dd78e63cd9d5cbb5caf2ebbb3a364a2995a109a967d4b4269c85ae7e160d527cc364e9c7a629ce959b4dbeca94367c85c8c8b111dc62b08974018df45f4e36b8c81a3edb586302699a6254d4c44da857d94c18b57d32d930a215674a4792e289f40d773c13e659f4ea6e863127dbe9160684ca0d893394db2ccc2e920ede3d1324ccbd8c7ebee49e9e3b6acb6a69ad8497ac7b6ce4e770f19dff10238d954dd69c954d9b7d397b6a72aa38c30d65c33b3331dc08b9664d32184104238279c304208219c7114a58c324231c421977a9d46a0915330890b823adc91a7e4cea55eaca9e91ecf051a792ad4df42ec64390423b46f48b432a091e7f26c0bb13513031d136d87ce90bd9f5f0cf509c873a999a7ac8881c5a50e874cf7e1034845f5782a14f55aeb057074700c768e611733a9ed15b9d4331f59e50ae31ecf856b322ac9dd5e1697fa16e3526f0875f7843c15eaa3e995ad4ebde7ac5665555cc08943aa1d911db2fe4549447ee4f832ed443b32329ae071340e9c5ef7112adfc9d82e0136c943f63ee7cbdee31ed5c99833cb442492dd92b8eeeebe1cf05b13d79500c68ddf5c892fa59452da1cf1d0be491619b2bbdd5996adb339e0379e9fe0f9f33a37d9e688b68a79685d57ce4d2a6a0c1940844e15709de8ba3bcb9672d46f73babb140bde75ccc4bc4f1a0ade567dfe5944c8cbbff7ce6326e6591ef1d2da1cf5f3b4d2dcad135a27de794c3c9dc77be76179ccc41db0a110133f644c34f15c98a0a1a1a18979114e27b92625e14cfa906dcee630ce750faa33f143b6b91dd73aba855d66bfbfc88405f8466bd287ccc5af34c93d3a19d3734316930bd1104e854f9dc91eb2cdd9189102c3f770ced7a811b1125ff39f4d7d1238566eb4a51c2578b78a79772716c8eb9889919f1a0a24b449b0c0051c439d92f23c6662a4e5414f599bc31d6aeeba24aa90a7d23a213fe57c2a6e9e873c0fcbc3b91dd30cec6906dcb35b9a5b022679c8a66f434c5f70823a0f4a5178eaee53c678ea4eccf39053ca3f1727ea79cc57ea939eb24e886278501e4578a74e9d1664a8b9eea4151ad75d67053920e16e435cf739499fece49e6bd2fbbddbb19c991a3a4146172f8b5b6badd5a2281af593e607e3ffcb06e09515c02d0c158089dd4401b01f0b00eb9e8ac766189db46bd7ae15acb0768b6aadd5568b1ebe52971b393639363936d5fa5551d70d9753b1b0bc1f2c34301ae5480d75cb54bd4a2dbb5375486aad20842548d1ee18a7b690d8fa130d2bfebaec46e34ea7d1f2cacaca8a5cc12c16cac2ac4c7737cbb402a5bc68c83f4b5978c67c979597646141b2524f69b362e9ee66e996eea9592696ee696261a1c162b195841f4e55732be6ee943912102b9f78c6f4e97d0a22247ab5a294ba8bd2aa02d1ead4c5c235e8998256f56a2e33d50d1942082194333a569e15a5ab57b8465f3e2a5e0d0bd790f45bf56a6efc3b535b5919aa31335fd75ba33159d0b2406dc3a151978f26a14f771faef07b7cb565e1191264a93de1834ea8ddd8e2d6361ad5b23c9c5b2baaaa2aeab22c2bcfd2eaa726312d7b1af5e0a4b3e724bd748ba7b2ac58c896524ae9a5692c5ca3521c1a0e8d998f43a301594633099128cb58b06fd395daadbee1d0ee75eb553b66a75544f5d2559d890987c6c2352a16295fcda558409c5285ac8644f594361dd36af66aa5babb4bcf61dd1485d123161234ce4718db96a8bfc768ab943951e6449913658d3ddd58cf3955c6c6be31927a49cd292fd337cef909e7fc46cd39678cf36c23f5b6a32cc6c738e3678c51d6cc2a227bb4a5f83e96d58f8da00fe89ad70a8e6a8abf2a05e37d9abb549c2ea5c5f864acaf4eb5eb53939f346a8a320b75cbe4b9982d8651ec5b758f700de9b196aae766ca96e267e5395f238561169bf198465f2fe1bcccaaf5ebba6c7579dd3a52bd562ad218638c54468871c80f92758a846e57d2d2ba3e4a2995e9a795b049e97ba04b3ab1293d10fb7cda0f175981507ea319258910c9a244dd234261212917a136acc88d9752f2b425b8527d2845dbce0a60f26c41d28eb0538f171149e9067aa4de4da9ea7c85c9b7950bb2156832993604a2eac330cdddf71e469908fc68d63d1a251bc61378720506af8c5eb172e14bb5ad5c4a29ccf215977abc62e5621486612b37567cc5153ca3c8159f06d9fc6024cea2cfce9a7557df9cf3692549cdf9de8cefdd94e731921bef1a47d5f3ea9ed11161dc79cc3d5807c6c94868b41b23b91047157b8a71be15aaa3cc8bc798df8fe71e71ce0dd25b9667de5aa93a1ef4899e950944d98f87d2fe71eb93ef69dddcc33ad43ad3e8439ac9611e47abedf989ca62769b17cbdb52dffae4272c8eeace3ead4c7b3a97d0273ff1e8e1ff04d79887559502c5a58fd6ca86a3baf3950a14179e9fe02778063cbd9b2c222823b9b1bbbb9b9f704ea5415ed47e40b8755ce6f279153f6ba55af5eaacc167d7ab95ce39674b47cd4967654a62d562947e7b8fdf7bd396e8e51f333b66c7dc4a4ab33bc64e7237c8dd3af190b6e74d6f9a3d379eb302d2f617fde8a7cdae6e9e33b38aa87f9885446631bb351fe33a59cc6e1311f101b9954af9de7befc9091ff7ab43ed7d4e69f110be5bfabaaff4ade273d17359992bcf4e2cbb2d5755256de97d1e5a7093794d6de93d9ecf5c8138cdd9afaab375c49c56e6e153aa533844d36d954de66d0dc5859fd4a51193dda69b792a1211752e8557c62be77465b453934ec2c046ea145267855aa5966559f3b22c4ad9baae43eb0cfa654153c8e51a78e3704056dddabebbbbbb9b7ebea76a62a25b9e8c333afa6eeaf3247237cf77dc86efd04dd38ae6e79942e014d28e7294f51ebfc7eff17bfc1ebfc7efb1c5a798628a233333b3075a5df3de0512cd996522d14f72d3c6d6ac7704d7e8b365091172e555ea7ba07cd7bc3f51762be75c1ecdf6b242bac86e22510d8c5ff6358f40d5428206008f26867d34a314bb89ee0d18769ba2074fec76131bb2b05f1ef72fcac8ad1446dadd3d3d0cfb2c0ff3207f7336cfe5a4b81c0bb3a869514a29a59452b6045fa78d4c4c9c764d9b9999395e1a2b3373f3cacacb8b356796894494d23b1a798675782db9754d4ecd9b2e5a727be7e565658544fa45229b1a7ac578ad57913a7422086fe6cc3291e82791acc9a2afec4be419f1f24eca29e4f24b615b040f4f1a89f3c96c2871a35b26750fd5e6a9d4e2c3acf79e2c83f51e175c43deb2ae495e58cfca64175ce3559627f3489c0b99f93db6cf96ac1765195e5bf2467221bd90d68bf4d1923837de4d69a5945276216f2417f23d89433fa7e71df3c82e7806851e2a2f4b4a0fac26cdad966559f559d985e42274bdd2ea5bfbc81b97853b6597142e0b7c4ce329a595d6bb801b0e87830387c3d970f0bb56b4acec42be3e8ae14ed3651738ac57d5d25092c9bccbd6e329ae5bdc8d8a419b2e08cb6e382afb8feca25ad985bca1288973a9eca24172e8864b2abcb9151b028563a577ef9d53cf7f5a7d6b111412bd6b464723e9c3bc2e59eec15ffd0b5eb7b80696754f697d5ef0e6c250bbb08ff7deb39856dfeb7e481a7a51c2bee3c2aef53d245ce39d21172d6d0936f6076fe235e1cd8defeeee8df6d5dfe8db625c7e2a2d9e73378cf3b9b1270fbf7ddc9cd9f4ae5b7fdf3e13b0e0af3f6d93168376649d1fbf02f35c9800d96d9e844cde7b87dc5262c72c24aafbdefc09d9130bb26d652008e5256937b62c24aa176f621f5bd0c776651141e1925b2fcbd2dcbdaecbc2de2bccf368d4533494c3d044cf34ebafdee83757bac5b554a77ee34dd2c248278293c4aacbebba2e6c9bbfbe4d7b7d5155d7b7fa78c77cbd32b3a8522b032fd49933cbaeeb882a0f7f695beb5c6923136f92dbf578fa94cbcac06bbdfad63a5993ae8b50b46915515fb2ecc6d242a2bab555ae4fd1c774fd621f978cef2fb846a56c7fc133e2a9bb14de5c9652cafe62023500d45063bdfb55dd4d0821105d920de19ca0fcfc24c3b76d094aadebb3db34a3e3c94f0f08a6df711ff5b7756f93a16ca94f29d8ef51946b50b24fa98d3c039ee7a7f7fedee127aef13e515611d79fa557e419f3c15fd78476bb7cafb1e3a59abbad3ded96364f69f5308fe12b16ea96e90ece73ad9555bdb37cbc0c12d2469e5155761423d7909ff8f23719bed4e9ab0c4f94ddf84579fa39e37defef4d37421b79c6342bb676706e75e51b0890cb80ebb4c8c9b93936b7eadc8a91ba05bbdb2a4dc675cfe5130f92daa354422a0ff3a44cb756aadf21733c87b4b2a5ea155ea67abdce5bdf7a2bd6b9f0cc966fe5d2062d8d3301a4096ed7a195ff3c5db9efce3585bdedb6322d66335b6a8b9d5af6b273a26c891e7bc4a2b3327dafd3697339aeaad44ed465c1486f455885444d621d76d25c0ecc8370e6e2ea08960d25982eb163b343a90d256c2c6103f3a866d95882f9d948b6a1848d259ecddbb96c6309e78212ddce8d9bcb8930220d455bc2c689c634547d137a31e13c2efa862fb4f1369488dbb38194cd8d87d82314dd0b8675228b6233fb44300eba732e29f7c08f34f75234e754606822cd3914cd0a7dece6965c07e5e3355919081d7fbad1561978a91c78e797e01ad596a8c74b59c953b6c46c97e01953daedd95cf825780684f444e3188e71391386a6a16827f555279a8b715611f2c6a47ab495c4c99cf37f11908f274368517b79efbd373fedb3598287801ab486eaaa63c69899e185e4b2484c2df2138ca45b26f64bc3ecf604126624d331f313dd62c53be62835772d4dfebd62f05570c9a4e4ed7412bed142cb489a04374612cf4822c0976f51f17d6e59b6da9c4b76cbdae2c7ca2c1a4a32ca6e38aa63f4932ca2343f59eaeebab3d8af63f05ab6749d9a0065f9090b09689f885cd578a8c51810c2d09d8f318220744bf1f4f58134cfabb35be8734b93af22c300e89e3f90e6aa568920ed5611743275a94d6d0bddea52543c11dc7f8c849f58b13abbc29c3a538b43f8c89c9375260fe123131fe1217c44c431d6737933097c8475f888cc3c5acde465f62eb3bfc73a7c8412429f01c9fd755a980188b49b8e2b0fb5f8c8333339de9544c8770e6691982c22a2140fe63d8b88eb9876317f72374277e11f64cd4d47d4fbaa3c41111101e1291bd23806f4f164d6eb890fb2d23cbcef482e8cebb458c3cdad5db17504bc59b74c0babd0ab96c6a734ca5611f49174a389365b251e4513b54afc8926d2d88a003d4c8bb4ec28dae7279ae7261ae8ceb2d131a1c3f46348737385c6cb1059bf5d43cdc23c07e3676e9cecadae2d783ee29bc23361159655c73ec7b0eb309d61d9371010184d4e5044175f8472628279387461d7f99e0c7b523c299e1493a7e5116c460708f41110100602496c4405c8032b9383b42dbb333a3010f611100c34b2c204948140d64d4037b138039d848e594f9126d831cc9a3c115e9e5899be26761bc10cc86eecf9c763b70cb33e0a320a320a320a22bb90145a369bd1615d24fa645d348964f33bae1545a2ec5366d15b728a2815616589b42dbb333a325196890ef344d63d5ae9ba1361229147748fe5c13cbf2eca3c22eb338540d84766a27fa6d004fa605384817272d2cacb8591797e896c36a14c2793c9149a40d3679a98dd5ea8cb5f5ae419565529bbc5d339e374c2940b90f0e1f20caed3420d3ad4e62a7b7daa7f3e9f4ff5cfa7faa7b4e3560e7e3e55755dd54c223f339b62ad5ebdcfe792f968db435ac9fa609f4ff5d0e7a1ea0a1da631cbfac7e43af60df4ab7a8acc747d3e17945f36f4ead7517e7255199cbe5d329a5899be21bb8d6086b37b32bb615745f908cfa86c35817aa9dde0a71df5e564a54d77b7a7adf3118fa7c23cd83dec394c57fca9be65af144eef1a7af560a7af0f81348b89d48f87eb2dcb6e15d3f3113ec247f888a7631fde7bef82d2c4e4105af09649e419cfc48462138a4d2836a1d8e430cf84faa595aa4965627299fca2aeea323953186326c7ce33a35ec913c72106f1873d9c31c6159f5cafb71bf35d87401fbe2c1b6334615a85b6b9fdde7befa395765cceb24358c157d91c0539f53ecfaa2aabaaec302fa3fec9ac2ca3fec9fea1b8faf0abe715f594f8f9565596c2aa8fdd463093d9cdb215351f84675074daedd94cc2a036ec6eabab99032dcbb2ce3956b52cceb12ccbb2a6c9aaa6eb569d769379599c1b13c9344cb3a65b293ae3115166b504c37b5d4d3a51e9289da6191dce4d229452eaa615ce393ae77fcad2fe7f68c54e3c16c824bb2cfaf19c602093cca2a28732d18927f33cfbc75e009fd089282546004e3240010820630056d3ec05100000c418a5c010a19c9884401f4f865d96a2368ab2b72506ebbdf8de93efddb27bce49ca7e9772644589f608c89b2494721bbda845f958db6e4cad572debfddad7dbc29e61575b95a5941565184b25d5c9d8e4902b1fe37c71aa26a7e88c804c37cd382335aa99736e9bb555dddab4d3dd2625575e29491a4717e9faf74edb6e2949a6c72f489051107931c403849275a0942d25948f75ec1631ebd5f58fe6c91c13b12a2b33ddf8884c131fe1237c848fbc19aca118aa93e15c7c6e92da96f5ad264739237411c6cb4ff67db20bba6137ecd449e6a4ddac539b8fed198a1180ca6e2f77fb6d945025cf360fe65c7913bbb1911bb21b34c23817e7cad0419f76e301dcde39171937b9732e0438ca9d7329c061dc3917037c74e75c4807c09d7351b900b4ab68cea99034e7540ca039a752008d009a0c6d009a732a34d66af6767b11800d80dd56006063d88d34b229763b8c13bb65d26e32f186401fdbf3a2a124c36ca52c2b13af7ca5a56a29ea4dd196f897d9271b79c6cbd1baea4839c2a9463574e74eafee46b4cd0df5a699eaa9d4e254e465afaa5274aa8f8054232b4a9647a6e88c80700d792aee163aac3c9e438b3d20bb356466666666b615f4bc5b551c5951bd149d1190917cd53b8f82c05797e90ac05752db463537ba2ce6cc3291e834f2a50504692a7a0fad5292409af7f2b2b24222fd2251c35190471fa722293a232055b5c518d55c8ad1ed2585741439650c1b2ab194524a91ddfef8c44a28e508e7d6f7deabec28c808c8950c318ddea35d5bd36c538a4e671195d018d12d0e833459641195641acf4b69a594a320ef103eca51104ea9ee24f940e33215792ad3776e74725e8cace0dce91b691a05c1d145ba089592e4522c95f0744c8329f25c5e5e565648a4ffbd225de4cac72925c98d1f05e11ad528488a0e458d6a2e9552ca51109e11290c16c01ce86f301a2826d7096b17a5924a2aa9a4dba36207a554bee9bb3e293e94e2c6243f7b554aacda9275aa4abb4d333ae4e994a7534e17a573cae953b7eb74bea24c594a299595a5205ba51d51af9f522291234fa594a1cffaeba297b624dfb4d69005514aa90455b55237b75a1425a594525217a6657f9ae89386726872aacd7fb4ea308fe935a5e0cb96e4add75f405c29b8c6f478b2e702efb1f3b624e9abb4e4ab86843feb67c5d54528da89963d15eb269a7b139b8f508a7aebd53ba7fa641151d15bab9452fe52534e33577f70d059d41fb7625d31106fad9ab5a664a1d40a83a2a09cd45b2214eba2fa030546b5aab3a5faaea1ae3e205cfbe4dbfbf17edc780ba556ebd937bde94daf288e5267c16a5d1e26fbfcb81b8c1f0c639232ba07868d012346c5f5c634b2392976cb60882c4bd3b585ee81a45d920042870ff7e528e124348ce4e86c6ec7ed0c41e3c25c8065a016641e22783e63f880a8f02613a010e80f211316989c7caa38f9c4a3bc8080bc6051018145cb20d231ace8101513a572cf855ff88557483b4c8456906d2f1df8cb4530be906d6e679b2d5b63314563d144da8aa6e2c19051c6944f18b2cded4c266c5e919d9d9d1d6793813354d72d20e09a5b724dca0c10226d0c847b308d119c1b9b259d835f6c08c1a02c6c707ffa30a9f74932a4c87381e767c43c827a99b21092f38a02dc8c68ffe04351649b33f2e8f38820c988b647b819efcfbe7c608d2fa09b1797ac5578850ad214fce31a3152396803ca03a47f16869bf1a89d3da2c27d771f9d6c7337324dd818c1373733f4630a79136fe0cd0d0d7838a10d372419cc822ce00c8921babce3bdd7ec5ebcb6995b430b49b08999e11ddcac04fe64c1c60b1b0e831736d188112336e69c73259b73ce25d9e68c349c18e6b9c8bf1bf15ce2d4a47849e106373827cab83b50b58103b5d908597643348d72908958d0e366a11930b89febb4888318ee969dfd40732bd6f39660222db9a19384910a2fe0bcd8438f1d3b9c010b254062e00fee0a10ee26a2e26ea41fdcedc5077773373db89b335273210fe690e40863f0811a7e78010c7007406c01270a353c74e2202466c60a19c4600d72c8c210a2c08798feca737140164cb8828a9c1a306108317d98e7e2b2480213867421061af0200e31fd249e4b0370e690072c6001061e57c4f46f3c9713242982199450410728d82066016668c10ac0608517841c89699a1ab0a1f298020b7d40430de620071b0401ea8006150f78140951c105e6023f5c4970411772a0c8208410562c8021b0e10311f480033a08d98153bc81055317d04007287ee7c590374494ebb61892852147ac232c794ec417fc0b23a0ebb470c313575eb7c50ad0206326c0096e3e8639b8a49e89a20f3588c3139840042531dd5ce4478c3ba02e60430b824c3d842e4c95138e0061f0890f52204245c1092c48a18ae9c4c4872d64b006eaf270dfdb62055fd09b2d64a0c5c5aedb420660b8db23139c1093c7f3aafb1e1a7e6be59efddea3a6a99d13629a64047ed93a17c47b6bbf273778af708a3312018f609a3bc5799eb2ceca591096005238e9a4df22c7c8fc4967e4182b8cd2cd2b34855ae184fc4acfb175ee21a122a5749a788a16ceaef4add14fd3ca95f255ad1ee35df50d58d6bd95a90bd051d43c45e79dfb085ce8357c6fea8f60e6be379d9a93faa43ea94f869714457d4ed4e690f023988980a31cab505db760539fa51342462744844e08f89c10af9d101d3fd996e2dfe361bad497af5193324608a7e93d7e87dd7756e92398b96da72907b67b4208fbd49b7a85da564d337bf6ebdbbbccfede2fbd57e122c699e57869638c18dba955e62d6db38aa8eeb42e68bdad0850b768ada89de27c73be4f32c6279af46467154c4f359e29cd2eb5f2360601949055eeef2eda8f217bef34de9ce83451ca73b6caf44b736fabcf2c3b3569a23e69f212c6e8966a3759750b94d24ef2512b8114627ea377b3275875eca2ce3cb4e009363195b7d0831076626a7b010b3cecc4d477e30220f888a953d59a13030e919c980a6f728cc4d4a8e343484c95556bfc041688a013536790214284c4545ab5c641a6f0e326a65278d0c3196a626abd830c68626af5052700e126a65a794092b3862038e811533124b44127a6665a0cb1424e4cf564810b3631f553b5e6bcb8998226a6829c165f6c01276687b3f9820b45980d40d440c36f48034d4d4c3da95ae32d7440849d988a52b5e69a015b75793603f85554b5e6eca0879d9a980a0346ca1e84a0849a981dcc6f8b2f906c2949dc9ce634cda9e15ffca4c1c7865372dbd81c86c1e54c935d420c48e6bc1b433127cb4f0069244f0a32f01132b4ce9c93aad7ab463dad3e0b4cd32f7b91ea75bd08774bd7e3294b630ed9e888ebf157a5286de6520d87e8f69f83da4ce5ce030d29e504a6cf1731cddca76def0ddfe3cc7d7de13403998d70b4e69c73e64a6d939fe4ccb52c3ca30ff366203318a4e4ee9b514d93e4a8a649324e31c2a74c2949ea08488ace2808cf98a0803e608f2689609a373759f328c84dd60f2699baba4b5578aa82b7e0f3d139345e562aad52578081c015229c627c36a1132f25949406a9c944f808e49c0b2f2584d7263dd122eb4ffc28a1d40236dc82d4c403d224f98034493eca4ea2fae9956c244f8aa86dccfda2ad502756b0818140b7307c40ac90f5b739ab2cc2806ff0049b98429a24af9c429ac472c736032b1c3bdd542ada6d42f17c5e2bebceb998fcc2ee5c16f26837dee46c5e5e565648a45f14e5e434e6076f6c9a34591a4a3297a3c3c2c833a669c7754d3ad922eb6f2ee746073c70f5c443ce0322815427c34db74e2554f284099d9311c94af5b07aa5dea2d349ba05b6924afe5d1a914664196495a253ed280864db5e344e1b699cf6c2088744312e83d4469450a7510d16190e918c6f1612c5b80cd228c8888a0b3b67cb7a07270bdd8b6e89d148b2ce190599e01458c029eefb2848fdd64fe1ad73ee1b05494972273bc99caa868a846d86847aca66b148b68944a225504de8609ac82df154f6f7eecea8e9188b2615b1e1226cd32d946d4e90c09f70daf8848cde15814bc838068cd38a1bb94811510c1263d1840e915bc233a285d0081769e281de3645951136f2399f8b3cebe122f7c5ccf29b78d9465a42e592385d5a6861861e1701b7623b3144acd396641bcab22454d5215b4a9b4dc88cb879cf72f78aac240fef46ba150908ea43740b5579c0e9e0a828bee421314417c5385320090dd850e2c69350272718418124346043891b57647c8da040121ab0a1c40dd2151941011b3148403c7743e2233ce4c8345d73e2234ca4d6a16e40dc6a52cc7242f0090f323e5b19275d46b790ba25f2890fea542dc39f40218b775d9dd4647cdf7b7ffc77f73ec4fbdf65bc9055ada4ec66f654445374d2da39391bda11093f587eb0fc60f9c192fd6081d60f4a29b590702b8ee507d532c7f2c3ad38961f593896898bba0d7199c66516c9c233e02bbe86442864a2e2d5f4147ca75d99f6fdb83c979fd8677dcfe9a39068cec3d0685c886252cd53ebf3232d0586283bc9e2c287404d1dfc74ab2dd17a59c712cf52ab65b12cb52508a939f9d637ba0846ca484bd1606432226522f8dca3bb65dcd8dda218f7bdf7bae70f961f2c3f587eb0fc6031695018429f8f941f2ba5b41b12d30eac91b2a1e828a69dd0a5168a62da9976604d4781c1f816822de4ce77145d73e79d9bd36e32b0c77bc6ce06c87e3c8f6e240cb66082348f0fbd6452d2504c3b4d82dbb46355d5b403806f5900be4d013cda8dfa27c6e33633d03d02b0ae55b2bf56e918768e2c8c771a31bb85328c3ee512dd3997d14f465a8ae61c0ccd39156a1d907b75cdbd6e62b7ac85dc4b64e35d6d431fd1bdac876828c940f29ecb5eff7c3cf71105d7b82edb51cc40bb73a3e019f1991619098470aebcf08c2078b9a568b32a605437a25ba205e214689715d22f12c5ea155622238ad0b8c7c76e248f15b1c52eadded2a8b3cdebaaaad8f5155fe306c4b672e38b6dd3366dd336f3d166a20e35e93d74abb6b91baa19b96feedc28764e1a060ce0a4653370c22e5dce74cc22e1727c480d2ae16e748b3ccc8e69999439ef6e9a7ea35ba08f2b35c7d3b4d24b4cb6d25f58ad3393929d243ad38d0eae11a8a42d98643dc9d4880000800001011315000030100c07c482e18838d2242da40f1480108ca24c6e5219e86192e49032c6184200c00000008000a0499800d2c3730312345a41b15206bdacb84e2b1f029f9d8e502d16e8f9e56813233a05d7e6f9c8d82ba6c3e017cb304a39141e336b391e3ddd9753d16ac99b135d53d35460e5c9d4d87b49be59f3cf10ed73be8c02e28ca0009158e6ca59f306c35e552500df3a93e1c977f46aa097b1a5348ae8a5e15e4a59949d7195efba0dd2cb502fe35239603ae269b8975ed2594ab2ef2d008884cd6708c21b7349537e83bd1c95ea4ef8508c587121c40d06bda614777b35ece57c29eb573b2c5e39897c65f0be5698e40cf11f4ba729757a4f707b57fe60cc5f42ac8155b70a1bcd4f752e784364612e9dbd2ee8d85b85346723e0c502221ecd1a6545dcc4740916040c75e432cc1fa2a228b470daca363049e2b5eda6fe879a78d3d6a3fbc1f772b2e3fb96440008a3a1e05798919dfc836ec0dbf9099c5f7304ccd142332e09710fbe421ee299b6b2a787e60fe0b62745cd66ded1553cf41f83ead56b0085dc86fccbe95a63f976d03e45f5507290051ea7a0d17d6f510b7137c179850bcf9744392e16f609f4f113e7141b2825be0f6e829c0e67d2815a1fb71f4c3ee57ef1363fec21af9ee9d7a7b6d93a30e144dd6a10435c921a13e479a70816f50b96d948fbfdd0cad29629c63fbb808a064ddbdf5f285252857c0103cf4bee02e3e05b67950c87a2b964cfebb9679fe16ae67807ac185d35eb265023b73ee520530cd95a3631b4bd85714d8561ca9b12607418649635443037306056badf3fc80a1d5e3c3c0078ba0e3d15fd830d039a2fcbbf9e7d065dc1c5f025fbb4045110b3b2e64faf077a995daa30a2f52860410493caf1dcf1a4b24c0f2fd148402567e9d823f9f392cb5db961b7ba388d1db9ca20289d2acb5e88b4ca0a881d2991ae4af7049156f359edf613591c5a28c7bec4d3b288a4d61a952cf63fda3c8104abe4893c2ceb4fc686df7cb84eca5422aee0c8fa1c05d50f2fceab26e40f8b6377951a2cb9e685760ffde5b4acf2fe30e3b506f89273b1dfdb8b2cfc03ce8bca3411943aba21d2045e22d41b7e5aa0722241431ca49a19f0a838fe78f4e4f0bf36fcacb4c416a46d7dfde6f65da9eeda75dceb65207ac21f8f8bfa61fe3b77e0a7493eb84190b88db1c52d340a04e0e25ac283a97f2c1b7da38d628323c35b96800c3baebe1380615ee94a0fc25f33e4b11332a53a01cb821c571da192c18775f599c7ac55dc161352378efe0869e2e10cffa43352cd755a583d4dd4188519a1f0495b647eed4bc186d94c371dfa188a1eb1a270d48c9c74efb4d43c21abfd81c3e981af146730ad2f8cb3bed16782e0f6608bc291bf6e8a58f35953fff4a149032b1aabd3688b405e0e5c3fa4bf3eb96b82f11fdef11189bc4e1331c4feef2b1ef1f467307b6fe095ae9b2755e5699579148032accc1eace3054df08fb56ec6b645ca7969382e45667f8d4372954896f0597ea72e32fe50145e8e18510798543664576976520555ccf44354df9154622a337427fa80c5e87a45350a18341ab2c459d9ddc171639e7d8f68c5d270a4a383210ea2eba3920708022f04a45507e3ce61341110aa9f30bb3707b0574b77bd27ac4c45ebd2c8b61a3a38b619e9b341faf3aaf399c3a9f212d899f9b7e2f534d9add4469b2d4397f9fcc2df99f8d799f5fac7bf69492a66143b80fb9616bd314cba11f48afed0edba3232e68e8d2654e0df4516a7563708b9ebbd10d82c95c8c6fb9498461f3d2788b6c8ad74f0991dece840e90c8ca46a2b7ff8d68d1d677ba7b2a66d72254b86cb1a32085e0569978c770c00683ea85c39c16c55ee0a3515d9205d1235f2e3ba75020a4da072d90618259b4d7a1e890e422efb3347f49c5e8e8239361b2477cd28fdb5f587d166b5266edd8212a32799f223b098268f14b9b7200cb1a85daa48ac8a3a71b9a75bcdd01f440feb3e3782f5ce66033418ff16bac6d312e97451f4747c996334c916b367156090431c4b8c2b2fb195f87f1e6cdc62e9c61122cecea36d525a24918ca0b7343756ba003ed99fafb9fe3cbefef7e92577c8e7a8c85d4733942deaee85588154a31fab1ab585f3c21115af0370eccc6c6fc6e146ebfb2b1f9a5e4737741cf39488af3744a43f4195bd5f81751919f4f66e505253d3e04db13c7ff0d63c163f94ba0517bbb3e38763a508fb4cadb14016e28a617072b3ae29b6a9bccb0f60f24370d93b3a0b6ee37ccbc89e3cafe9d451b4c7e7605930f74fbadc11f612e7d37f5a0db49dce6412738859d31f05f8209661263e7e54025df2030ecee406a058066334f82125c5802d9205d7354af750c9c109bfa4dc64e19751268b37bf527bc1906bfe9bc3d06bf3d8b14bf785554b3e46d68062de684c403f4adb71fe0bd69a27507af91a600a1ec38dccfae80295a8f3bfe4f707e300e7885c37ece307b775ce7f38d6a42e998411f4422ab2b2bd8c39ea86368432b41ef1e6c3b0aa2a6442b76a8afea7ff39ec1c3cb3f81e24c3ee05b46c55850828a1a8e269139d5fcf2d0ee87eadb8cbcaa3e9c67218c33bd048a66c2a3cb318ad97befab4cc05f10ee07f709c54c9f8782aafe31c65ebc5e590c4437cedec9a31d59afcec40f02ccd9f9e29125d747ed2cb669d3d5ba2414e19583b4854aaed797e51e6a543ab7fc63cb80897c30c4961ff42ca5df99d769fb69106937cf32018654bb3d24a3a8e2671fa130fa8d3ea44ee706f2f85d1319f93a5f075510c5d11793b9c88596802c48532cccc51abc5db62f942d97a18f20428fb7dd7fc9b44f85f3e026beae560246c11571579f0cb7da5dece975c8bd20fba98bd6cea45ab3e31a6abf5fd59a4f3fbae4108c0720d99b3e6b399e42d3ac95e2e52eff661b8905a17c150ba6e1f359edc0b2b2ef6e98ce0b7808329e33797f4562ba2cb85f3424afa7a1be43903d96a54700df5880870ccd76b970c9b06ae137ad74e4156fd40b53aae42cf87e9b7b1365d510b5a0b735d151e08ec28ab9c30378235f119eb2437b09e932d4e016ab76908d933da0aec442c204e436a8d48ff3521fa9a2bf3021ca717e0b019ec7fad46b3207bffa64cee6d83064633ebd431ab94adf8b14717dc2086faaf831bb0e6f25c05c811e53d1087f85c97bf250422572a9efe9fae2a2af9b709db20eec9f498f344422a77bb7f2fd0595e966f64609892e1880d675f0a0ba59006d55eb64600bdae4e503ae2a45ca9a196806256def0213130050c4d15e5a8823b9b5bc4509cef0f39c2e74cdfb5a953038f3bff437e456f8119ac619d45af52abfd48fbfc27497c1c2d73feb9c7edba0173ab8e2b47cd9665cda557b0dfacebbc4ea7032f2bf57f69694c91d64d787dfd0991956ee2be1a645e5f0b4b30148b3b01bc406b8551784a18c2efb3dc86af943fa3b40f78e046a6cecf5e0355a4ebfb90fa7b14244316d28f43c3b3ba143123281a61f822a484f79769dcbd1bd6c76e1ac8f4b5d8e2d439528d707f395c1ecc1a7715a6b431a0f6fd89b8aa0285801ac875a99989f3e2e7630c6914e8b082b4233a3636039949dc5c6cb574d3c5847f4590c821897d207a116f7e4f5c14846aa8ff8f186e47bd9a49c3d44c43515eb3f34ddbfa99bf462ed95f17a3496673bd525367fa8b70bf479ebe4b8847c4af3c799001a4304c0eb826607120e46d61bc52f1275161e2cc84fe91f48bb50ee3dee807373d20fa3a6c5a5a4b755fcf8f031d34c5af19905c962426b0f99072ac3fcaffd9b390335e242adac4fe9f60981daa5f3921fb0c8761169d05782e3343b4ab290f4289ea918a6f512f9b020e804f3a64b13b4c64db384924f591d52b773d28ac046a4b81df9d24d3ca3a23cb7499db77b4e339174cbfc628b6b46ece7eda2b026adaae926031f03d30dd64b475fa820c29cebf8f4c75bb0d94a73b0c96f8c40d15247f7491a7be9162c0aade681b0f2675951e43f1e496cca6e8ce236e1eeb535a58fc1075a399e692e36eea60eed8880765871c2b78697a233f7aa17a975df36dcb7c5bab1e905893c32a41dad72b8f09152d65e20bab56584448164c2478015161904c0191d7cced300c98b438b6f5c857c2207e066a3f5fc04fa07aff49c18e77e59248211845faaccea9263f58edfefaa4b511f98d2ac3e502315d39d0d6d67f72ccbca371c88e5f429ca63ec39548e20325d98951df6eae992fa9adc8037347c20c2aecf5dfd0f06a1f653a3fa82e318e7760eef521a67816050212cc15852623b4964d531e1318c4d4411d2468aedea76da63ed7f4a1f7dcd03028917654f9edc46e39a778ebae52991488043cfff9b716e5ae7b0a0218a41fc1d4329bc5f32af06dd2ce15ec3f1c3e6f541139986693891042874d6ad25bf9525e41d2273b1006e84514238141b1074775a74b98abdc71490c0c96f0ce7e8a938a355502dc7c29f206ee7461b7c847a87e4b5b77d77d88d1e0828f312522104725f0f311b662f0c176668966fd7c82d3ac63cb53f82902e16d3a3195e8fe41337e651e58b285ba66ad358dc4ed77a68e2ce34a06b09875abb4be97c3ef01b0e5536b8648f90d6d0081614c4328a988772313eb8ff5612170f15480b0fd826f0723aa141902173dde1128721aa7cf33453a5cfbc6ed941cd8f0b5c5d7410d76ee17a8d5112bd03bef2bb716f59bf27374d171192df29fdc65ae70874c5df4adeb7fa87f625f569c996b84e04faee6c017b8e0d927b7bf127c728aa2a6060755cb5d0e930e4350dc0fc21408da19b7130075f2a5419b86dcebdd1b1382d89b4a943bd46f0640e8d17ab7d0168b277a3d3aaa453fc3aa47c7e31a92de240718a50670e3fb01824386c019a4a04684f448b01de0901da054a557027f3851d17924a53b73edc52ad55493505e017320f83e6e57eb514b2a72cdf470d0e8ee173875194acd0ed91d65770e2172c6312a4cd7d15b20a3eab600bd928077d55aaf086caca49a0dd68a6d5b2d564aa0c38dbdb28815c3402e313f96ac8f40316b28e9d428aad7c7e44807800269b2435f3da5ec446610ae5eb39051838018fb9a7e8ec0a74bb6381171fd99de482c8e8bb5e3edb65d8f157c01e2f2965cd70c164611664a6d01d43afd9b4a1b5469c90645ea739e132281ceb3308508b039ed6e2db4f9e7e97bbd36599010c313f36c18a1bd3518489fe8ae1e28b16e980a8f786260ea37dc95c889fb59f58230482a16d738cd50b009efe79ab0b5fc2212502000e8bad67b3fcdd3926a04ada27444ae69dbc4debeff9758405f25504dc685f2a69b28b6e0050b62e6667c0c114a18acd5e0d830f3493f35ea05fccb27b7cd8332be79d87868df6fe6d6ac5f255f3a69107ccb28143ec2f2213025fb087a74412df4024e4c2fe0901f01148d6d84d96a9d4b03fd8654db33bdb15d77236ebd135b254aa86f529fc3372977d447afaf24377da1134b8a58d8a6a52c69b20f7c2c2182fba4414587e05a7cd21cd26518a018a9f7ea2a78d789abdad06c7b9bcb2a845863b23bf39b82d4ffaf616022fc3ed961f46d62ff0a575f32a915ed9f7705c22b5227ced444d5d1758c7c52f870cb6e65dee78d959aa5aa40d87bb33abf9cbdf601aad9a8336b7e922e0c3dfad325ce257842ccba8f26dab31312ea462abb91594b73595ca7bca129d9958710a7ac3f3fd121a9cb53f69c913c4876fb3f2fe92f17addbe494252198f2fdf09767feb85353ebccb79f67ad39910fc6fbe93e0c7cb73ee5500a3c81db5f208430f95512820f053ac814f2cab2cf7aae262a89db970da58d807d0d5cf5a287cabc1d4b7f3769383c4cddb6a314b69ecc2be9f35d7d305a4bd94b887dfdd121abaa897616f7e5a537461ef11b979c2823349b10db0361c86c0d0ac92ea4489b2ccc7c1522dd42463179151fbeb184ad8263283acebecc87c8f58833c1ede47913be93583a57755fd16edc611a4075f16d029b7af9e4af2550022b33236145d0ecd5aaddd409a5097626aad88a2133bf1f3ef6272979fda28c3ceb9a14919e78d9028b79e444bf07b3f615309a7d4cac2406ca7daacb996461a54f06f959d153cc60c25e46d3d09170276baf4b39d37d9a18f092b8c1ab2f99cfe9dae28c4534d36eb1b953354bc992ef2c4b501ad0512c372a0b89d3382340043118f43e502913c247a3cf02982b2ad82d1876d31edcd3fa09f9905b283119a088f0ac4ba4a5b5fe53bfefc108693d132be8234385feebff6ed6bda88ef6d1a4a4710fb9a6798240d3e33f1b385c20a221ecd9edae3e407547d2181987e22587dc4e1f6a8a4d7cef68dcaf04b0b697fd8a1068bbe667c56d10e9141ee5974215e6a08c1083546377ba5f7228f6b5121e54b7862f9af677897cd92ba8de74677a39f26b6cc83a8479e39f644258a1f808fb8ba7aad54dc90eeaaf9cc9213cd13a6c09f443e83c19bc43e82c197443e83c191c331d30524d2bf03efb7937f4afea8216701096a422c5f4cd105e286bf982bfaf0a454f1755f80653392c82371c7ba7c163418f4616ca4fd7c8d2b5e0b8d5cfab4e83d27389b3651acb6766d21b20530166f91033bf316e71779152568b555c6c4a4d0a6aa75c9cd7dcc8bde3a8c09949d0b95c2849b6c13ed9a560c7f62e04456389952d5576bd5e11ed6609a8bd8f3ebf647e19f1fce29182be444f0dec69fcfa249a98338194d9f2d5f14aa70d6df21b9d74d01a3b1e11c71368282949ac53352cd82d2a43dd679e8694edd19b5b1b77940b9c9d0bb321b8ecc01a3768b365d814848465def84783350d6ec3a1073279a687e3a01a63e6933206489a3bfb9ec7326d28dbe684ada197e82d452a984ae58ca7eae62510f0508735743adafe18d4077144cfd6957f9176ff49d8023fcdfc2b28b14cede2c456cb06787f55ec16d74c3876cac91c13bab853545e13781d1fa4130e689905739b0becc649365f083e5cbe9bd255bc3ed4b005b17ff569d6ba7dada8bd8cc6ba005737e80f5df14c4a282d7757648a3b07e40af85c732cf4b3ab5b4a2ee2d5c46c74e06bddb50dfcf5be7de0133dc7e565b21d68e8e23560f59ceed05acec5735a5950adc4ecdfabb0b2b1d1f468aed0427ce672d3e0a5c6ae31c1329ca09e4e4e6b0c50ca2135a1f30e2d5083b96c20d74d77755e20cdb04b62fdc48ae20cd2bf7307ed21f7bdf0e9602ded2cc6899dcf376b526c40e159f60ad2109f435256876f564766bb38ac6dc0446e6fc5cf83e2ff6918286461c95aa67e7dabf5ba979ddfd96338af4e739c29a2be051a7b05991e25049c9c7d155318e9c421fcec1fac42d5f971767e8f6cc39fcbe5b00620136ef80f94511af7751eb228d2e00202856f4d2913df71c2abf2b02cbabaebbe4108a4da91f1ac506d9728768ff47c0a59a735c1afab2b85b4d6ffeb4d96eb6de8349c4848a83ee7a0eeda83c12f9a0e51a6d5955295552e0688c3e5655502162c54bcb685f156777a7f095f5b0ed9a5aba2e4966ec49b6ed9329c7dd1bd33adefc20ebb6d174d9ed86126aca5162e8861ea7f21b43a53cd64c12935286c1a6d3a0edf584b278e91165c2af27c4d5cfe13247cef088fa19ebb9b50ed04c225fddc2bafa4012e7a1e30530cd95ca51d52f6513d54ee1838a5069839b2625d84043f5649f3a6af7d8def5442e3f22a6f41c1d776ce8f259e206ae69d5327c537abd30eb971eb7479f3e754f42b0b31c2710e382856b6af1c9987e3caa24a75a08d8af8799ad2882e0931abde72cd90bf8f0d4eddb138e6ca4c0de55121e1da4eae8bb616ae1ad94dc3a00de1989e995d837d5d67b839b6a0bc13384460bd7c06b0a3eaa00030fa81d8d27b4d2b617068aa1291a557f7750b6e626459caec50c25ba8b9c96f5beecc4a30bd570029621e0bb26f52245b513efc320b1ede1ac634f2ae668b9a175cde54ebbe1209ddffe70ff52d1f9cb14290b645f21799ade1c7a018eebf2e330562a6726949a215d2a532bbf5b918b52ab648cce52337f403998e82438cd2040e92dc85f363d977e8dcf2c958b263bee7dd0fe6b3cd9728c423e79388aa498be4665a7256f2bb8323143ff55532a6e9073900daea1255a6ec75a12a3a072d8bb05b311dfccb10859eda8be5868e18340c3c3846dc6cce73215a131b95602d3c3a1a7fcdd0d9129a8a396657908bff311b4d940e36e603b18eae4733e61430aff35ce431e5000456d0da32073dbd3a5c5b9a402b9a515d99291b1843edc6cc49c9e8e6cd232b8242361dd65002f0941254297863bd19a8cf32e2035559444a3dd0838f8c6585f31eb0f67fd5cc9c0f7bdc0f264bda06ffa52e00c5345309fbc5065e26b3fe190a74f106886807dca3963c0d84da793e31d630c16cdbf49b53495f996dd68e5e5d11f2027b73ae3dc8cdd33b191786b9dd4b84e4471eb4fcae60b347a0ad9ff1ba45e3e02ba8301a445724e772d51e7d5459d2538650ae414561f0a6d1f8e5eaf03ef2bad5ab0d8566e45287f81fcd9fc78c065a27a8a05000224e2dea7515e42cd053402c2fa2ed74762cc48e02b2568f24ac15ab297f4a0f5fbb2580507678b903f571e2315b450626fe4f28795c2143739e7c61a54cdc714a9a82d5f4187ff3154612a522ca7bbcd2649d92723d1141d2ab115ea2f4492ac6210e05100d510c05a18507f983ffa91c8bbd63e898d70e87d5f7f97f90c44a345339f319d56df9611eb4e7e915c893a88af4295817fe6db3c8d33f4c327dacc2c08b8ec1b9cbd3c8ed079cf6388aa815d269dc144770194a4ac0f91a2eeb59ae1caad7033151ce527bc4ac6a28834283ed82dd8fcbcc656121bbcb6e1b5aeb92188ca9adb400ca769b23485c65545ed95a55bb81561d316c1eb9f6cc5315e935defe7ae12dc33fa1495d6c01cd52bfd77c78fc681b67613be429ce6d53116922bc3d0234328b792563a74b2a614fb2421f43f3c5ffa356963199ef295415cbdf9a2811d60e93c105ed23dd070420e4b6e667409a3184532b622d27ac28498080e418835a30b5479b8fb0de499b1fc80e3f42e4b54d0bf3fd1851ec1fe92ead42d50c6ab54e781de310568ed41399df2d478643c5aa11249371596d77a86b31124ac6c944dd0a9145cd2b67ec0cfdf8e3b69a7bfdcc66512ddb7e657df1683888331d44e65ab17fddafaf5cfbb3e0362cce8bc66dfbcab67eba0536e88d5a0abdb266d2347b029cfc273afb498cf8954bd3f210acbedaf9a21ebdf72103b52a7b7102504d52dd0d20cf7944082bca52a74ff4b55907c48927b79e1e5f38d70b9de48bf0181ec28ac1b95139a3cd13dc57faaacd3c18eb45598612ae8e36153699b1b528ac8c5665b3e397c84137afbf5b479dc22d6ae84770f1b67c6c3262596178cb709cc26667f1d2caac1608772b6930cd23c3e800e084f019ddbb0d8de12532b1bc08406077a32bc451f22406e59fb055cf7dc0a16861d9dc680db19d93ac1ac0d1c74272821a1a6a53cad80c6c8e223f45b2f1e09ea79bc24b2ba4b56c8a7ea8213e341884445b15c6bfcf7e8166684a94f80b0ebdb59dae8faa5222aa6812877da3c7f4790375901c5ed0d1b152f42422e581ee58ca20c0ffddcb60c7b3795d5c989e6c647983237cddfca4fbd6f5c94fe79ac2633d15c057018713766cc4e3dc64048fe79894a30b3c0221f92d95477994c32ab724a9e1c66fa68e73433a2a89e1d08c712d56da68ff1512b5e5a36dd0c2414dbb39750751c7ab3b59902dfdde7664544d0fdb8d02d002d4917b4c39a0ff0301b600f2e0d501ec6111a7be9a7ec61bfbd5af0b8a9e9e28ac8c3d508d174a21b74f80f24708a9ce52aa104caa2e4fa38827c09908589d607e2928d8716b9675f6ff2efa00eeb1ce04719a4e7d834dd37edc8709f84aecdfe374250a82d3b488273a633f390a38a0c51f1e7d5d515b04d8095d866b8ef06e96691cd690a6825ae92dcfdda05cd5354d49f2a01c6ea20e0f28dd50b4c118fb1cf2957e00608d7ea0839ba8c27fef304fb29f36ca40695c98defae48e8ae7467566a2233fab24ad5df834bae363d6bce1b4639b3abe7e984a9a687dcc63a7987ac4d0506a516f41b2cd84bbe7c66d942f650e936242f191d79ba72cab6c7e970524c73d63ee116fad4d8b1f8658c3c48871bbbaec31d1e4059be678d3f4c8b40ef9d0e3e17776068636b7a39dbec899ced2a8773a28e91210b236b4f2be6c5368a730c016eb8cf649561b694aa72bf5f58ae1c63c798027938e3dab525819e7f44c609e1c5fe0a32f6069ce9982c973e5224f921f25388760d4ca0d8ce0386266351ca0e3c4222db7e72ea55638ad22c74a57d53ce6ba3a5f5e1a46005932785d0851ea1a6f1e537d145eaa609d0ca03530981532fd0a04a6b4309b85281156c6e700e536682fb7daa26e40533394de5fb501527aa918671ce1e3a1227b975064bf41ee59a31bcdbc37082012d470e5ebf79d9586f6a2274acf5bf8b24ce15e78395740a66f87024500d82048beeb7e720f354cbcf8941be0cc2c609d510e0ad3157120ca590ebaa437218e8dc088c4a431911caf014226ed4ee2ae1836329a9c0905cf736a96e72532009a9e612dea2f3a501a9c2064d6e1ed02464a7382bea98ad208a8193a2360aa30fadb820fc416fcff7f4782dca64ce1ea177968d1c20d0276ee573dd98f8e2528b313efb26a0c05f7df49b4229ce9dca97766166abbc567ca1ff8c73a75c54dcc3f231ca8eb99049fedb3a21a9d00ca4dc0fac401105520cf6c3364a5e223e46f7343e8e27f8f8016607185a54d8e957af3a3732c018026fb0522dbd01913cef0f0c9cd6e0a53fb63e2417420d97210f664d205e212860b38e7c8d58a8bda31226d781812307822ed8546bdb7870333d9c2383a7d624b704f3ebac798e364dd5cfed960d770fd34088628fef15362ed32bfe6dbf53d62052300c9ab35b1d73fd6aa19888d212f6aa1012eef5624e31c69c387c6be3154fe218c5903586961eeaa296f170b295e23317a1503d4adfcf20348f2317c32469765476976644e05e2a9b63be363aeda872c73205c90b7a8d312dd8fa2439ad0c4c04c77239dfbbb5fa6f311327c6d241dbbd428bc707c72e41f77ad2907c2351fd02f47029f6eba31e737d182f8f46fee73aa2f7db0e6d130745d3dcc2576e6c8bd9c37eff853a285e36d41ec7dc7f7964311f80cebcb5266db0a48a9bf2e7632aecdc86e6a04124e890d03647c9b029fb3cf4a5fcffd2e4fd379a34bcc5e2cc52f392ea8a7620acd8f4c548ed52e5d9bbf4ab4794117c60c38a30022fe932861f62a3cc432d0cea07f8c5e2524a84d37a232e870a81cc3522f29df0b94de6c83547a34f7182069419fcc6e8c5b0718dba8d8e1eecba729f4b29b58d198854d8db401cfea8905fb30883efab5863cd17430d61c3807cf4e03cd75f5cc39705436e1139a0509401349ef7e2a3560a585d8e0fde8733fc16dd98163e834cf2b4e34f151dad2f09e25fcff4439469ae678e730f2c6402762e4d184804b07c88d7df017e47957423064aef54ce6a30d2577917cca79c116997f237c82e34c1c91f152cb25e6cd8dc38fed27922ef985ac604065c5ae5bd2dbbb0513ae2b6c80f001d71ab882d24e294f55abd4b4c4fd31c8960b97cf4226d1531baa897cc01584aabbb7a85c5ec55703922db3fdd7f5dae9480501d8b66ddf6c81bb8e81be69387c1c85d61221685b82db91822d8e8532b2c77bb4bad02760bca09a9ea341e8699b22c8d1986bf1813ee90c1029613c5bc3462e42a47102a7ebe14f4100c7815f4aa70290e683a88d9f4c1040ce706487ffdfa86210373d926256ccb3cc506d44b9bfaf77d0a81ec20f87c744691588ee7ef1c42f3bd44c755d4661369b6c45f7c2cf8812bca8e69aa0d7d3f817efe793e07bf904109af190f093bfffeaba66b6f0f3b51867ed1af86f649b7eec5fd7861e1acb9660b422d91bdad796afeb441837f9d7182c8b670c4b546031591220706ca905003592156d8afa63f8c1dc1fac676ba257bd55bd3212643bb95a1162f9143c9c436be3701ab6d8bc496e0fbb9dc94828c5885e8d045aeb3884cd08a1ef822224387d02a8960d33eb872668ff53e340d99ba243ebf8db5726dfa52f3b9521d1451daeaa2cef858c1a27b5c092c2f22ef74091d58ec1ffa1968b316d5b597cf909e5a5c9b1d9eab2aaae491ad87cbeabbabe42eeaef7a48a3762abe8f13d63867405ae6ff25d6f6ef0dd729be01391a8b52f16cdacd4a5d24e9f798a5db48eae76435583b5d7e44bee70b68eaa78631fb0cdf66e21e510721bf7918d8b85c944c4746b6b4688cda0da913201f1302df90623809ec4d2e64fd50d71124f4a04e420da47b44a02ed2e1d723c0f9c7a960426cbe15662b15219f88ef463b5359f0394580d1ad666442bcc4c69d3fad2939eae3bd6ec245157118d53c6c845caac80d328412355e1c33bb8f66e4b7dfb549773cb76a260f36505222af4d58cb58b3ac47295096a29d644526b538c819a148cf6464c5d3d54e2209e5b4b688f62a8fb3a0b3922e1d3b945a5eedb3369d76d731f536107d0402f9d5f60d11ae067bd0a6df04ed9f8f8d216cd290a7b23f43e2d6524f4d17e94f7bedf803c2497fa202ddfd76b2271e9ef3b791ba4a014330465f6d9be68b70560a3c4a5c7a19d45f8c2782d61a5cdfd738eb4fa202ef37737d0c1ec1ac51afbe203940c978aba6dec1832918074ac7289bec5573ab937697f42af6cf25065fc532d983f61034dcdc45b5543cf1345f472090e212ba49f2e82ffc54f442d2629f02eef88b44c48bf18702dd69fbc61621fea404615f888584f6f007afda443d564245029d55c8ec31f9409fad5a27c2c54e8666bf571209f3f532becabe16b7ca0fb34f48ef9c36ab7d5ca3a1ef4eb5abdbf41da1351d1b39b7d3f16807995a501eda3bf6b110a5bec5739615df0078663d3e53a73efec50a1519f015b315be005f9ae2474be305a4bb1d2eef89c83c4280d5b7aa87eff4c36459684c37a1bd4a66659a5da343dd9cd9dda9507b917c3b11ed9c4411d299675e9b27134570a92b9b68ebac8c3fa0f8f166dc68193da21f3780464fd6267b634982ca6da1513fe03021b4c6eb1237235489af974a600430d3706a45c3b0e34199961d209e5442c85ac62802b516d9734571ac34c5d6afc40db8a7b88f156c329647d4d0ea01ad1d4b166cdbc04fb8de59e43e4f25577c05b6fbd28cefcaef16dab5645fe08ac572f7068ad2359fc9c3bb51886b640782344e7921bad8f9922001cf0a751fe15f7caa441948b870e2ce9fd6d6c803ff7892bffabb0c0f48854287916cbb0ae71890aceb0d73cf0b1a03af6ce96363e9ec46959a53869cb954d2fc5d068a90359cfd7fdc86c278b1d574657e0ca4685661fa81d58744301358e60c3a228626c4ac8894569892d2a8f1c71cde57a94b2a8a88cb9a2c06822539e1aad35d062096f816e3384b92b5f5433af902a2bfd7f97b02c7733c8f8f8af1e5f8d773326fc20d775ce34e9047c4915a725607157aff08f514d1184ce6928abb6b0d39fb6b569d1391fb68c83ecab34a7ebb76438db59d2ff6e567a48af888f60c27b70c4067b20f75bc7a07b5cbd1655a768de92ee5b2f5476bdd815a9736158c7c757bf4618d1d18d2efc32fda7f3d083354ccef84b7a4d1c457e9c5e9ff01fc0c2e7cab690277c5cc5e72d4ba03bae321472a89d2c54ae3cda7195a51b6168718c23ee689d4cef1d765eae266bf5426386a6af8486e9ed0b79bd66577de2b69bcf3a6b7ba12fd672773a6b6986d7fed0724e3862ce34c2ff2239903a2498ebe2e652b172a2e8a6314608ab7d5ea9137fa3223efbe7c04a4f23f0cd36a6f0529952c25951c458a83ba0b9de9f4b178258286bca029108e013362bf2312ecaa5b12a5a5c3b6a1f1f774d3dd4e54072f2f65d0e5945ff792e05173e191624b230da7a20aaaa514f8e0df5c213766980d38ed5102568916a877417dd5041c950fc5c88ee898473a10a0a342f74fa4e832326caa2a8f16a200dabd671098a36a9091d5f269ea23c23cd26702cfeab76dd86335730682f54d146dfde1c2ae92cd4863e4301edc51afa9e8d7190e5fbca1580053e714542b7248f632153d4954d3aa1c597c923b4252aa841bc45d124dc4c8d54bb48e89f3d48c649d31a1a988146fa72f4cbd7253f081336d624b14fc2b62b9cde8696bf36d480e1cf62a30424946c06aa51d93d0953aaaf543db15766020e4888014e6aed9eb87084cf80596cd3aeaaa910baf60ff55cb086c1a1a5ee91961627cc45889c3990fa842c6c08c76dcb2b9115bf0dd4c34f420ef6d927f971df43817d7dfaa2a75679756ab9a990e22f7054d1915b6ace483c12ae09b4e09964cb7724e92c928c988ceb063b1c6da6ca599e3aa1c064a6f00d6c3f39d6837e5b787400ed8fae4067552115681e3ed505d4c7fec01b0cc4aac186c962d010ba1a5c972e7c57430a228a4487497f6759152bcac87570e4644657bb559898d272fb04c9cd314c8700ad6c4917290cb58d34ba989896b5164291dba324f5af2339d7d9b825f4748446e6680f0db4e3a7d83f3175ee6a077c94801272c3452e7c679b2bc9e28a87560ed884f349675409aec70d5c53fec3f980bba6dc8e681d8d05b8c42ccae51a204e7b7cd8cf38542abe43fcd733cbc172a0473edf11aebf7be106b8c0f9e5bf52f14ff80f83a164a677c2cfb016ac30ae28eb4fc8a7a5b2401a50ac882b223f300e0b22f5fed4d99b887805e581814265d7e730bf1e57f41d3865bf842b4ae80632e004b1b8a21bde42c776efe64be3ac68d5aa043283e1390b21aa759d57d89e817e7454f95ed76bebbad9426114963eb162c92344b3041bf729bdbdcacac07e714d16b775d8839cb432bd9541e6873ee7236e47ee27bf6dd0c43cd01b40703b0b03bb243323aa34df40d213a0c3fa8caf5fbb6d3d04bec6e5ed2f1b2754e5be961b5e98c658fdea053561f7358a5367fc9f73f93161d0d49807b20100dca7da6ddde64a9e0f15e92b523f687a8745b8f11ece51d37dbd11a094008ef235c8326c7bf09e262759ce755f7936878ed6b82fa57367a53e243977509a0602b59b14786bd0f2ee2b1c909cd7bbf1f597e9fd55a8d5b6d87f07b8602006c55dc2cb3c3c03c1ada255117dadf5064f43401ece3c8c2eb69684aaf34914793ee5dbe7bf3a5875349daa6264b55f9e3f88ccfe567b68d3220942e3e3d54327fbc9329de1bde43c4f4fda2f5045f51ae7528ea79fc7be871c32a01da368e929bf31b7756ca174b7203fffbdc1cc0fa5eb7ff71f066530c5b8154af1960e66db0514d0cc0734bc5e7ff0d94ce19b97f4441d793e9eb496f480c4b29d7d2e4efb862c5ef4d877e6795e77cc39e6314a42e160ef51d3f16e90f75a9648c8a4e075135e78eb9de38db2fbff5cd203ffd4ae2304fd3777117fd4154d618579dfd2955f5c88beae3f5c26b892f6bdfd811c974c7210b4dc83260a5d4fea4566b5d6371b1fc2fea5a15c801a16fdf275e17014ba65113c77d79f7ca0ec170507da136006220a24dbc23949bd644c8a1b7d26fd40c507a0a328d8454b55596046ed3305bfc22f81ed4bc3cd88fe8b0c00265f7d2d83979bba4f33be987f2af6e6d2201521a06d3e805e1c7147237b309d9eb7ac0e9e93f0b833146d6798f3c8f2c5ec742b43a2413de78b9051f8aa22b1608f247d979663670a3e2ca54d187ece2734413d79c79e2e74bdaa9dfedfe2b9304bf46d5d3830a99edb9f9ef76a086cb06816d66abbe79bf711dff5bdb72d2fd4dd7dc2de0fe88b06dcbfb614d035904d50cc3ad799f7ddde0a75c7e081c8165c29b608d816840a5ff49e66aeb68a6f482b429358a8e00ead8364a78a441074e3183a9da92466674210cf93093c7ae62a175530abe7337c0cc21b152b199ff471071dbc1fe31d150089ff7338206fd9954711fcdfaeffdb37242fa757fbb192430e1559069b8f39dcab3945eb75b5cafc46c88fdb865366efe5fa516581bdf7301817f3f55e68c47ffa60a4ab336aa57e114bfb83d2e6fbddc5a1d9dc9e67f16a2fa66886cfb6a1b5ebb5ae8abd8a1e6824b08b3a98f9e9f8f2c2c20c8264f0a24334cf3380909082e4e9df7df4f387f4137cad1aefa28da7f78bcfe3964005225450bc522464aa646cb295ec863c1b06645cf590de5b344612639d96b73c30250e6ad691eb214b07b5859f253456c9fe757bc9f38b6d63a7d5341774dffc1d004359e88987ece05989ee9ec2b33dbd732a7ad35a267fecec16de07d321e16241ded0ba67d34b99a11bcafc577cb49ecc3d241f57eff58ee8059e57afeecfd766232a2c18cb06cf22d5323ad3708c77bc7fcabaeaf94a2ab3ef4f58d7626dd513931f69379479b74f081543ffbed38db4a61bca6c9c1cab30e5e6c07833f8067b3c92e216c23318d7cf677662da646b1ec91e9459d7367c03a59ca7f5abf317cdb67840fbb78ae39ea6920d49aa93449568a431686c9c8028ce29489ef977c7b90fd78fc58f09b7403f4c0430075998a41b7aa7d18dd335c3ca0a47d74f109bb9524aab6a57cc019ccc563bdbdc5d00ca097cda449f2e92f0459271939484aee83fd1d51f6a7519fc03945818aaf835a1ab726faed994b6b223a8341ef1d09085513872a2055b86d2eb9d20e986cc9a2724309838967271942bc78c68c6fcdb55953fd9da2e6c97d3791d3c1942967fd82424b6f3fd4a8db88c4f948f385fcc69934d1a195091a518b0c7e8fb35c60ced3fcc545edc9929c1a8ca165f59cfffd509ca85ee81d6aa3ecfda056b69b9defd0a19795dfd83c0498831763c29c8316912a55e45495cfd1d2118a2b6efc117b744ee1f29711a1c754660e570429c1829a5f8869344634a9d6b05b6c9644b61aa8e94985ea5ef59ef5a67b54f60a4c450b850a1b22391df37626ba5c8e2c0f2e9ffa14055513b47266fcbc83b94153b366864662646f9068d32575fdd73bf699ae90a7b20723672180492b2ea3525861ca0e6014cf98a8c9040a470aece911cf3192737d042ec851c9665b7f8bcd830040162c594b354234f1a1604ddf8c3105712f4703310f4bf5efed90af739c85e4bb8f55328f4cef5f9fc3bd2c11b6a751bdc96705af171f228c473e2bed244103ebc02682c633b3188389cf8b8896f0c847b2e3e460dc3aa4ca80f52812517fd9375231178dc73c78a44ba8873b038d030154c9faaecebd50f1da10f1eb7f69729554025e88dfe9c1cbd137ca9e1ea4aba164863ae4b34dce136292abb78c072ad94a57dc5beed0dd8d6401f7b527722b7175316165f47b75c0b072f16ccd768e90c8c45278e3a91000192abcffb4d21e8189852f8a3f949282b618cb34ad5253d7342799692c3daa5ad070bc006508fe1af4b74ae7bdeb856141f93e514cabc3c834c5ca1b8755e0b7d5ce1c6ad6b07df4c2a0e8982fe91c5c2a67643c3c3dd2549a573bc14c6b22f87631dc01d4d3a049bb68de86f5a04339d5a7c9b8ccd68c7013629a2f850cecfeecdda5f4ea36449785c0c2a5bf95b437e873a5ee7fe6eba6436eca1ae50c1b03f47d49325d2dc40efe8592cddb7b3e1b45e3026aed7aaf5e48da524b0ecc9ae23bdaf29edb767f5a26a331bbff04ddb492f8a64e2a83836d9ce136910aa436c85b94161d95e43e1658323f45ee2229960d7e7dbcdb3c42ca206850f93c62a62295a7c638900b107c37de0811c8840042eb0a412ebf9ddcd37589a3303a31c373e45d79aea6dc1f39aa54dea88066f3fc6dd96fdbfb359b780441d6cc55042f562ca2bfae51fc854271595351e4b8f33ff5676e362a6125ae6948933698b9b1a720353fa6efb4b1b62b3edf9da12240a9a401b47de63744d0c05f070c83f0246c98b92ba58facce6bdc873f1e23817988da1232887cb26115f65fdf03f32a551faae98d1beb2bcff64390b57d82b671887820715b043cf87728889ea8040e0cbc17f8e1f03d6c2eac5d8c1de7ef8d98e645d383be6c835f03bb300d58f102d629c47a85f8777999ce2c34da9fbeefd3659993b93fca6d8013323d4b37ef0934e7a53bed3251e78b36af1fc4d48fe3b09f6747c1cb5d60336e998aa2fc593a0a9041593b79d419f394d8eaeb4cc6981c2c7d80660134120b7091decfa710bc3ba99cb92b8f0a090e39aedfbdfd6ddef42ac24c5027b50a1c4a8c2720a8e51ef90518832ed4de913b6375c3306b80a7c065e1844f8faecb5ea5f55ff1e08977741f0e9e2fde7be3c0108e5afa93a3c70ad72163d4ea97027c3ff2aea2f120837f41f616b48473b79df8cdd0eb8892adc2f1b17f37980e326e1ddd21085693bde25b9a3ddedc0c0551af368b0b88f98893468708738500c1b15f5ace015796b38cba948e7f533bf719c3ae414f95c39a3841e5430f93524c3e38f2996fbe93ade8dee9fefe89b8e1e2576d135137f33e5d669ee9a56b9c61e05e97e61da3db18ae7bdf239fa96c8b4e114b97f02f430d02f87ff370f51fb3890ce9ffc9a58242d990a93e9584d2e98e2d9a473ea70b91fe43818552c6c2cc5c1a2b02ea354b27cf2f990ab36b0da8b51076e7c3b1639c7e81852c255b705b96df329941dc49ab8fd475f2549125ed27d70f306edd9a4eff8b79109506d9ba3709bea94fd03fa4b7924dfe3399aa09bc7342eae1109cbb5bbe4002ce11e2b38fad73f2abc6c86a7c521a1ee8cea929789d39ef76624e300ccbf422325fe99b69efb38c3fd420881c02eb3e4d43d3ccd6814721fbfdcd914a02f2de106320e7ada640e9668a54b5e32480f1a9da13411272aafcf202d6f3c96578c111cd4acc894319b27b94ae244d70ac21740f12432251071ffde208ba19e4986e01066f70ea7f67d8c8cc78c34f0378884362379fd124ce5d979152fc22b2cf4aa630d5bec3020204574dc975f7a1df3fbd243b0e934c6e535231434304ac4a291f5a2f4e725b0648b40ba8d9843cbd87c4f471980dcd35b18bf4e09c9e21852be7de289303183e7575f38444f058ecc4cc6a491cbb3bc0c2b875da9c8c05d66ddb09e4c2d8b5cf6efb1dd3dfef0768ebed33a9c4bc832b2239d0f10062cda84041b8882da16a23d1237cd4f70288638cd85330e97aaa90800b84f05eda706f012cc442f3dc3beaf8088b1f3145ab54c3f9a9558b23bd2f1ea4883bb64e8ee5f38cd25f566ff570988b7fedcf25c69701b1f48c7d96c2518754996f0fee2ea6f9971363fcf3cb7378add722801b5fb731e0a197e04203720dff274eb5ae75a8b91be936d5c2e0d1d78acc6c16dca9174097a85ec3108a03f1034f1aa45e0022651d678d0cd18a04a84d43d068ee2566f452325662d274c2e67900a85ecc0476f1f052f9fb2913a393f3f2c0a6118939084c9b9936134881acf77de67f3cc4b41210d4c984aaa7c0b5384c8ed97d9e61be5ad2df0e889c072f84ce64a5b875e32a7ee0403d843dd2f56613555f9919d3078cbad61f059770655b5644dfe3c05bbaab56b21c2a20bd15dc85fa56e6517bd343097f6bef4bf8e710adeeef020051eeeba7c10983d8e82d474774b052cc0484504a1a831a1a9888c3f7128251b95363f4b4c07d5a7e89ee555e1bf2b1c4e9c9b030715e849369e8c3956d9c654779ac06f07c1ec3879fc76a401a7f8aead108521dea63a252fc0a453387c2b2e8a5d9c267c538ace8fb66dfa9b21c6dcfce0f9cad69f2f56c2e15c35ada0937078fa86d689bf132f599c3ca34e4256875ce3745cc8bc7434581f9e66683e999369f5c75930980e367d99dc0340184c6771f4d0e5a3f9c7fa2d382716d2298c3e6029208c50b3e73b32dd4a0af8dc71ae9e85fa03c8ec81c56cf369eeb60faf7f9c04f8a053511dc943332018372729fd368840b925e73777a7f177018ae09ca095ac19eb84cc52153fb4a61384cc11059f62a2728a827c5ce390b280cce72ced14df6eb3bf2edd9892b42a384dab92a9e47f84ada74a2588d73a0e0d645885a81a08881bc6da7b89c48a16f042e18b07c12069ac97be7bd49740a5e61e918843d7ccdb41b41073670b798a61e7ec5126b60bf443b768dec77cea7f0ee89f921f4e20807f58037d0a9bacda27c10c385889bac0a0838a6ee245f69be64b956a368963d4ee034bae244579a5023b7f34a1c9eb63416204ea38a52d240a0d89d6e9ecfe38661209181a88109daf73e3e0d1107921c9f235e0c34f12db0134e090bb0b7c3f579e3e05caf931f31d3ce2b905ecb39131737f3facf5b26f4fe7e6b8c04c84a014864cac690f9189fcfd25db6f85b133717b483263b4d36e59f34b3a3d9103922c5cea5349db183e881c3ba97d0e5091b27a9eea32c62ff8bde0d526c633fd08dfe2a581d9f764ea896c77acdf4e0790d942b9aa8993ddb8e923e2d6f5c4109361aa00579472ddada7bb82390c0b8eb651ff5b1bd2604fdfe5acb6c4767ed8e057c01f34ae6772e8e8b23fab3cfc661474624fe477f4960cfeb884fa353983725b2b2b4e94af1a2c939f8f24ab8ee7ff36adcaf33b46eaeb29427c57c49ee3431a027b635433ee893538a2054db5641063858146a0f7f1ef039f70c0ecff47e31ffc53da337a302aec793ec52a2c510cbd57f2521645fb87a4fde6ec2af2958d13d462747a9a5a86fa9fa0b99fef00f829820fb3a38f2a23c4e38a468be9683ea87429b9abadc38c4427cbeff6b5ce6db791fb633f888a2ce1501360d121a3529f1e5e54070a837c9ca44efdf4667d6a7f2f235001345ca372c6eae26857ebe89973aff7b17edaa29d05af280ef3bc3bcd378f90d5cf7ada6955dc5ea75070af06b4b788d39f9b05668e3413db5eb15073d03f8afbf43871f6e0214f9b525d374b9f72c3bdeb6266c88c5c92779b2a27397014158985ccaa84069a064347df1c1846fac4d170318f5be1e5eb56cc61985bf5243c3885e1cc1449ab69f31c9c261a61dd8a2f0559c7bcf9fad0cb5ec185b3c944aeba2a9dd3b8cd83d838d3ac641599a72c89034ed58d113348ab64adb0d26554cfdd40986c7bf7e1f8ba2db85d7d5d3cdc49ac9e2f989ed13136a3f01a7ae460786347a082a347a9454141c718000c458a4c5febaa45a8ee4bc9eac82f31602a47c8c13d94be9e9cd3e741c71a6e2a90687082ff2ab3fbb5cfb09d95ed954fc2b02dbfe41ea90b06cac6a69dc218ce6c6193eabe4af365c0271ebde7746d47474c385541a698baff630a7e91322a6e425241a5686d6f0a21333fe0a7e87e1dcae29fac9545859b7e91c23ad042df0ffec48b03290a4f78f080e59e3011f13c1325dcb1af514eb19cf4159741b4befe620486377f5f8b0994d19991199a327825d5ffa319f852522c45e21683e32bae8e1304b46964562f0944755d64b45b8e8ada1ae86993fc95d9aa179bef28e74c30e2983628a85a36f4796315f514894bc0fa33971c25bc3fdef25ce4c605d72fce41993991b62f35b74d2c6c9d91c3463a35b3f384a57b6468f05c63e06b711cb34ce621d7e989ed212026c83a9d71d8fe6a211d7205f428ec50ae048e60651cb8b776b75a160b2ec371b34fca664348b5151b1b52a8fcb352f4dd2c264aa13c0f973c62a28d39e031ca875c1f0413cb27369a495baf622b519082946dd111f3256a5a4b316768a9d8da1b9e6606e279436b4db6781f676e2e51f0035944b83b796c4f4150cbd94664161873cfe8a8be4d6443f0aa7e048a08ce2f736e23df47550245c63c91bf0c590b3832c9acab6dae5ee7bf3f210175e4c9461f75c4ab93d425fc63387697c7d70ee5d9a38abbe986a676bed2fe4d2750fec5607418ebd0cd82e36d93108b9a8e55c6ae0fe34dc6bda482e31799fc2b095e332279b7dae068c8af9b01069cc3d1bcd928c1e3c815fe98e4077aefb810e66aa40c471f68375e60f8a496ba81edb5692b8575d7abc8c0b5a955dbe6ed69c7781343a891a59671f48287f466ec02e3bfdf9527290d00b46bdd9f84dbf3b703e55b97b9f72bde3b1dae0f419fa40c0468fb727e090600ed503a0162b711f23daab2d8027c75801e12355686594cb943441b088dce43c582f53177a4f119e97c02e9a3e6155204199c80832fef00b046fafc8b1bf4f56088ee6077f6e73981ad5a235adc22d79ca70b5bb6c3918956e8d27aa39cfa1876680302a58584627516896c36a2666db867f12074276f985ba1267a696603ab7aa25b2920b204c621ae740d77a143b0a95a6d264aacc87014a0610c1e92a695daedc44192b7c893b4c16aacbbb9e12c9c3f3e722d617f70f4a5af6df88003aa8f037645b70c9ad9802e788223153dbc3b115ef5ebc6eb1f2536bc8c9fc190fd565150ef4b2f46b79c4ff7aa256d8943c626631a738fa1eb6e7327a281b7a4bbb53fc340ffd8ab47298b52547a04aaee5d1106c81a9e9fb1b8ffc16d8a40d0bc83650e42485daeccdf108f363a983322a55c7a5133483af8609d56860e1ef5c78fb75e05636a90a3641366dfa081d836a88e440416cef8875504a3c5147ce98cbe05528a1e8e229b611e3bb1a28341e47a196931ae1fbdbba9a92ceca542caf4db7ad4a7dc99a58ab8aa0d24bc1429162bccdeb9cb30530b9e5cd3ad4d1618cb29fe3ac0726c71ffd4b19cbf61e1c8e3d0867340e6ba57340502207589c7dc237a0409bf1b1fc6520b372e4e6965bd5def18342a8e8c907d2abffe08e5860ba01de9a2edfed52cf2432975a3eff07bf3679b34e872138993a4e5310a2b1fe5bd48bdcc481a8bb4143389bd73a7e7816290b33b9b609301ea29380fe44ce498a671954ee342e55ddaddf8d2cb15c4a3ed82ba5c5165854dac4f7fc82f82c37cd77022438a517fd01628f515e4c872ae25d8af1d07310ae848c36651d834fe4d1fb8f68fdcd2acc2bb2fdc9bead38713e9668b520900f531cdfd272ccbbb1b72e6e677aa66bd538c4f82eb3a1d5d349febd312dc577458ff8d397c3d4883e21c8f6a30cc0918db0f457900cd49523b067973d599de240ec2cc72c0b7ecf83c1ec4e1daeae01773b839fbfa7a38d521d75e18d08799eb645917a6aa95e548e0d19e0fc516b1f962da368b9dc33585f4c6243334d721d31ec8e8066cc924152fb52297aa3099da70d27aea79f482559c47d273d07673e0be0178d90800bd57e979095688ce5380d063713cbdbcc91afd044aa169e49483034fa0b83effb162071b9575b18da5aa792310210cacd5f06b5431d8392813aaeff41b4b52c0d1b8a0fea18b84e0ef542aee8dcb2272744eb6d44849e0a1724120f39c9ce3f5e92ce72f78cd9ded2eb0368dd331e215a619e55ba41ba651779ad324bd55b3eec020df8b3c5bb073854edc765d2cb7b8626506cdec7ceaa61338df51e137d69575a91e9d3f9a3a1bec997cea751080ca195b19483ebe8ed1ecfc2c7af3ac0b33693f105a12def795cfe64f0adaf2c2a8cc04194d6c88351fe077f0d10c8af5cbe57d912203632bdbce89cba418dfe6a2876b287bc5fa8dbb21ea4bc167b19c92973eca612694972d2f9321ab8b50269c3ebef7b3310204942ab828a2087744b445c042eb69383b451454232fca11d333426ee9d234af604529e7899048f6a2490ed8a78faae832d20ce3f3b31cd1c08eb816c8654822aa6a7e53bae05db4ce2894667a07189ece585c684b0d66ea7f3ee24a565012eb132af3686c9cd777fc9deae96c5347e292e239509e9a0943ee7e2a677d0bede172fa9ecc2f940e8038c7e04583c1887021f6a8910b9bd40bc557f6c729dc6df6b170075f0e2df1a62225ee0ea55fcad3aefe7c68a56f73408fc718f0d5a28aa3ddb8252e50fbd6986788d8015e365dedb90db8873317fc472f6530aac84d869974a0cc69be77959a3529836ab2cd5ad13be0b7b99949ccdbc320cc3b07df37f784c5e57f4a1fe5f38e3758cde0743e07c7e419d97a26c9f2d0503eb98aba575e723ab0c22f97c7320c950f9f2ca8af1208814f391d1beb29463fa68e3e5fbfd035b745477ec012c51cc8269d638689392a2ba7e658bc84c5bc8d0a0841843e79795bd323fbf68259b0fdda0c5c952736c6f6ac133f5ae4d5472c9e3893ff81473ba53904506a34640e3f6b5cf32719923eb8200607aacbb821d97fc6bc2abe0956773d1f6c6713ae40cc0a806360e838d5bd9d515ad6424a6ff3fd04618fe36bbe06ff8ea461fa7589abaff81ee8d4507eb1abbaeb771043d2989acebad62c6be310eba069e57f0269b5dae895e26498b4b14bae39fab4625f31739611f7b6024a43316c223fb158db6b13b87b21166b7d5e6f7606c61a433d7d64a173c696a39ee79f5b3b777e20ee67e9f01fd73e2ce587bf0f6d52c77e4ec22b69481134d07dbd952217d3e835dd220d595cfa7c24768dd74c8a79e63391d055e1aa9e8ef04d0291fc594d8cbaa596df39fceb4bed1ea6a474f4550e15e377f9c21a6eb31a97c682377ecaa5882fee86de1b854dca73b0d9233923796d3364fc3c743ff62d94201cf0f30c5cd2370a7454d73489db1c13c76c5c0ba8d18984cc1515e005d13aa83f23a670fb62650a576f4c9c298357085dd8d321660a689aaef300024440ed6206be6c034dd1b63f2bfd5e192e592d1793308e2d64096bc57736e9b4433424fcea1120f7b0f90cc1c30d507e6215a81913301e22eb1cea93af7fee4621a287a00c2588208ec024d5196ad82f34a8317457292fda110b7fa235a7525e758365f56738fd180d5e1b48a784203e0554f30521a834e837f2bbf44a7db6b275be2e2d185d9dc7ed7cde7478ea523ec1b987edacea7de36a9728a8642729adaa35c093f22ea7aee4427e7afaefdbc27487d06fb836ca7c7944ee6d0041cfbfc9634ab6e2ade2c13a823cf00d603569a3d0c8d8b251688860e9e225e300ee3b5699d0fc69afd6e6a95292304ac4152311359429853824dc5703824eb29309d5781aba626ed73337dbe189629248a99f28482f4157be885429c89292ba5ab7b718c098b47bbd57928c8c0a1261602ea3e866d3113354b00127b2d4d123dba66bbc728f7902440a3d89e9c4a0ce39b2aadf6df50dca410d5ef42e3c19fba01650c2b1c3be5c5ada3aacaa78f06c4f06d6b4bb887818dba24ef35e48df618b74d70cd5f32216b07d68eb88c621a148fca0df027b9234fd6a8dfdd5c31ad44d622353730af211761c518058c379ee52fe5e48250e885ae5d70175d768f9b13e40e4067bd75632c2ac3dded4587d9575b98bca7506061b4d270827ac7fd859cb75b3ace21890ba35a4d0a69e4738beb255d10192f64bc13ca2042393fba8398b28c59ef80245036699da8fb95228e29f682fa549c4637b8f2276250e923faa944e10f947d7a4a821be89943fb9f1911fdc38b430a3f3077a4bbf5a8617e34f2299886a9441466cb2af85765f404c837861ddacaca14c32e31e5e5bdcaefa9186fd774bba26863fb2b8becf7253ab7ba019541520c81b154fc9fadbda940f61cf42169cb27ce500d9f0edb6f3dd8217e0af71b662e4426d2b3b0d7f37e935a94d17b8a4186ed544d6879ed22edabf946bc3a5f4535807f7670c007d52bd4f466468d947138ed1a847187adeec84108a1ece2b01e184840a2a24b07fe60cb0de83dc76a4cf99e3f4fa5b4a34b340fe9312bf305363bb8d97ed4973302585c773d97e4374d0e0d5fbf208d716a77d44d31497f5e80893fc2d044d48f91821264968f2d9f6f19a2a3be8421f4acaf6459b455e5d76610e443ca66f9fcc659b4304133d5414a8bb875452984ebbc5e703328864bea78478a5ed3897a296b0037d90d151db3f79c19c64f14adfe8539a5463e2548236085075002cfdc6a543719dcab52f9c71a67015aa0a0a295e5838965a109e79b2975158e2567c0cfd11e51fa9d3ae9aadf2e1f9bfc76a0d4968ae2ca1a2f90fcea9689578b8db443086fc17ac09e411eb0c25aca4ea9c58fbe81ae7c62763d02026f1c53048fae4135e7c500b5ebee3e599e29a735abcf5e8ae43be4878be066f9c37f96c727c65f7d525ddd273555e0abdaad4a84dde0f3c27ef099b872421b1dd1dc53879270dadb699adf06ad37c533aba059963a73dba4ac9517ee9e526a47282ce14e9de4fb2195fcdbafd5cd7be8fc008c198ea2f2c02536cbfa0c7d9a80280ac6fdf6743a28956477bdd874a1ab2ddc4a6b850ae75d5eb9a10a5a891562f62eb6d888b38cfe879a45efce135cf1397d004fc36a1a1809255c85c55140a610900de2a9898dc490df6e01c189d5dcf7338e2851455dbab25d94fe88def9aabef3334ee4a1abef1bd011b49c733da7bf1cb1111038889c82039cacea16ce858002eeed57ab682055cb78a514846c29a8387c863e49e31bc7c0aa4e1b83e52e1e40de5e3eb52fa43d61756022e82b26091c2c5171746ff28b227f119080392384a55764e35f50f1518384cdde3844d90da4b99eb4541679e6d063eebd9b7d75885fa6d73442a94be876ff3c8c45e67a70e9947993a756a445589a46a3e06bad3434a89519f71d3ea63c8694c583420b4d498e899637102b137e0e30f6c2ee779584a9655a31bbfb3838ed5f0184bcc8e1d74282245bf4eeca888ed708ecd35316a74bb29979996000f90a6e2e68d6bc75d689453be5b9d13ee6d87bc647f52fe98c51c1950dbbc015e70be8b4f80bcc82da7d5bd0dd9d29f4726a793bd6735c9e56c7f3b233e490325c5ee23a66441abc2bf3968f4e712f115a154576090055a53250d52f0d16536cedeb34e389112a25b1a0cdd0cde0eb101a37dec22546157704f411a7ed00175555aead7f0da932532adf7e8512a3dd3f5bd911eec74a1a2acf8fc699c43cbe7c54490b88d3ec4f4cfd08759d58c27b380d05f28b6d215afdc7f79a745dbe3553145e300bb017dd2f0a1d8bca99b2a939229c68cae867de88d8a17dc0d26ffd6440fb183516b384fcfdbacf27e2d0e6fd05822c886f872764ede37ac1005405f918b590dcc916089fbdbfe3266f7d0e8c453fb74308a736ca14e46e04e1645ada74309ea90cdf9e45fcc2b6b80fc9e420dc8cb90ab4f4f83655345fee478cd8b020f500be19eaa8ee3e741fadc57a06f81caa08204d5f98356eb94bfe786eec711683f89a047d04a6ea3217566f3f25efc9ffc39362e0dd5e37260139f13dceb699153cb33a16bb246ae99c2cc2ff6223b309ce204384bb946a06ff82c4ecdcf5b5ab0e8cef268af51d8d4b9a1a46565785c5095071e48fafa3875e2c297a01b04b6b8e2bb56a7bde31d60462e1e4e28e4dd360b762b694e17c96ea150339b417c6dc70166bca55cc2639a71105366537b56d93a81d1594215b46fd0d13c12b099813f5a176849660b686f5464995050581da69763eae0871cee2dd0576b62808af46b46120d2d572d049c2cc2cb90cad13860adc57c5160bf3c1265ec28f1741a5631ade49c354cb05fb8bcc2bda74e625c93a4e5a35d52f48de12b4475bd4da1e824207d520942d1a684f4ed9e6ae958faac307fcc16013c9075bdc351d7daab10d728efef4dd1675b94c4d0aab920afcf7b86461da940a8856be0485a6dc2ea3d33e246d8003948d2f0a5d439b7a8727988d3471fe89616c69bdd9ed831eb19ed9a95be1d2d77d6970ced3557cc0ccb5a0def14171f84d2e50cbd4d6c0f36782089041fbe7af430408d1579ee94a443aed3cc782a96dd1e8e6c6460b261026f4d41bba4f93a14a18af6ffe9830f2cfc341330626685c17b10c592e7e4df47027db918bfbfebbbfacccce51177392acc77ff964e1698a88166408d18600a6220f3b47a97665e2d451a2e6a65eefb6826fe9fe88d7585177357aa4cc9e27d7791bd1763f26ca6db1fb0d1b837a3304ab5965ecb647f706d71f6272977bcb7ceb8e2354db9ed5bdde25f2ae531848fd707f8f0ba7adf7f099c7a454dee7f856ea1c31b06d606ff97d6e2454cd366cd78bf04c6f22c8b29e440f9017c2d9181253d76ad9017c0c7c9f233f404c97081e913b8310e937c9eafa57d53b85d07447a81866fb17855c8ab2b8781466df59733d46a4cdb4472d77cc675bd2f074d9dc80d7b06319f14f4462c48cb6ae27dc625ea8f2e8ec99e9fa95c14a7b0619f82a1da97092b2b1527b77aaa7bf222358e4012f0cf65def2a460ce3213e77513c405587614418f68e66e824874803311df3f999ab7f404f03c9230cbb6773e8c8c4cac9ca0c603ad1c453633f902161170f784ba0f3313e311d89620cfd1fe5c73967012b81de8d1860266bc739139895e911f38ad04664f7ced96d4394630d4d28d23e40a6acfad442ef3044ea219504bf1380b1202b044e85027ba2f150b832165e90958ca59940ccd552aa7a092cc85eedf8077c908482494faa30d0da37ba05d8f12d69a0e0d1da25a451dd4720f0d25ac863a3d486be908a1d5a17e35a8aa0c89a0903af060da1efa8ec99c4065d726a22766620feebe9e9e74d7fb2ff917a279ab3e45ba2f5906f8d55d518fc00370f112a370edbf3f8713fae71fb2b2621786c335d14a49f338e75b99d6e514616244ec244a66d9e25dc3794f4b5bb52f92e42a309af3aab04ee66987a8391e746df02c286aa1005ffc7c1371e1cafc120eff56494869567b6502166b0293b089f3066603b042679cf92fffae2ac317fe16bf4b87841b23a1767558bc9ccc70c8d050ec6ddded14b9683fd28a783198366175befd99302c25a4e886b5f2de63122df975a704e1bfbf5b97696f6905cdd1b2b2035814663c59039b23ad60a8788b6816a7891e68bf12f2e299deb4b401d151425bbb06b4005d4f8c6d187399adf053163131fbd744851aa9deb41bf1b199cb9db9051d13350d9f75daf35e52bcd8a79fe505fafc960f09e54f554b3c2c55f68eeee845e9c28506c543c7fdbd95211e55300f1aa41c2f45dfbf337b2167c36313e879aa8ba21ea14e38da60284fb37e68eb58fd5b57a2ac205976344fb91e0bcf15d446bb32d85f4f70dbb6df52428289a5172134c28f8cadebe84984a4a6c82017f34a780611531e3e1a491fea603c54cac59924069ef6cfb800d201266c45eccd40e93adca972449c8a6672337b2c254f6e1e1adb857845b4d3322c6376406da41e0c174a002a13a5f0738123ea8218a1ca670d87f1658d0ac263764c48e23c3065d564619e05a68632052688c552a6f15e77cfc9f0652cd214f9c0044463460fd4b562031d842da2e40f58584614e896d0cedec8a69f4021aab53b942b259b39e8c42ee3782165f4dc43acb1332fc580fa39df89b55ea0f931238a557c5b6d88ec93291ef0eb721ac7d7bb33c74443644606699822e74b32c1de3fdf2530cf44cf1d12cdf76460be0cf8877a50c075648b7303eb9d911e959511b026ef40f213b1cf5f56fb3bdc44b66a49e4d627ce35e7e52704db1a19fac9350fdaf64c6acfde2c9b0633e8ae8b6be2ff36b27ac43cac1cb2515220e5a87738972f325824fd22e6b7f8885c69e3042b7191d61b004364d89ed3ea65a1ae340944628a3e6f90c4aa194bb33730354d7711b16ac8cd7fc94c1b6589b151e3e0d00d25346654c9103b9de31166288828e105e0ee7b56dd7121542ec7c0345e9014309f9e5f86dcf932b7892805d856171551ab8840559f3e7f0d24c63d900163cce1f65a5873bdcc6546902a1957a68bc1407b7e52e90cf120ca87e05d41831339834858ef80db09fac0f7ac672761bc048554d8f1f9d4a03020d27b1af27e3b2b2f981af778ed674edc8165745239177d9613f72d6e5d65875ad5085121fa920b6769a6824485b8a73352f602ebb4ba36c452beb37c52f0f6a8d9fef3778f531d8ca712100bd19d36bf71ba14dcf2c63060af9c3d73e58dd67da15029d97a6cbbc746a84e8600913b1320f4c86dcbf278dde947f9052c4a865af96426c0ab3629ea190de96cddf59552e86e151a200c5ce043535fe10adaee7a537a9cb3ebfeefcd0befee356719664f43f6fce44de17865fa44b430739caea90d49129b841e6b9840faaf7bf319c6b0ae631c28764c719196f3454a2619ff5db129616ccd6ea684491e83e2ecaf26d1a0c00203de21af9cef4509b79961b0c3836889ffaaa7eba7fe8588d691276461612240477e115add24f036438bbfa9d2aea987000cde69bb6a72fb2dadf4aa66ebe3892cd88c34840f1e11f6d92a55d90306dc44d5f2fa5810f5f76c848d2d07ad793b66137a1a9026e338aa0c29d87e1efa095773fc58f4324c506bcad8c3401bffab14a606f67dc5bcebe14af28a5d94c2cc2a112a4ff156a2a901394fed2889d0b1f2474792900dc0ce619cb9fc681d01065484a8e21402476a1cbb48ba9e7ff611d969f839b9259aad21b3cf08f6522a2a72fe6e246a9c41bb2c6a20f28341712ac448b9ff69a352bf0331921932c4be73e90d063f543644a96f76724abb6fc1c6ccb2a141a03b506fcb8ac4cf929ed51c084ef662903b9704100540b55a488356dc7f082e1f0975556658e008b1b15f165c7619778e5c9d8b582468fbedf8b4473b4b4f175aa128ac47f7ed8b81530b81123820f09c5524d56b03ac7826fa3df532f89b110c4fd818382b1dc74dfb5421dc351e03231a3ae21aa500a68583a769dc4c29e6254e13616fbb41c9315f02c13eaece9710cef714357ae4ae8ea14a27adb6332847ac19a906a97fe12f91d367911a4c470d6c7ab1e4778b3d915a93454a7e4e59bedee0e5e5a14dfff5a3cb6208798fe22ae54a128867ac81f9a4f452808111459881a02789f266b838cc1fe7be3ce8569d2d8385fa19449c9884342249dc2d6985199a74dfeded4ba3ad0724308d5bded47e74ddf8cb78c1d4ef631c1fb143cc168d1df724e697bb7da3b8bd3afd3dceaa3cb29d1c2aeaaea024ae9b9f529628010f8afc4130f8e3287688b8d9f2a823af8a18cdb4819bff816ed0fa95048cb5c6ea13fe848b468883c41a09f17e37cd1d018437d1df080f507c0c9822cec49734568e78bdd684bef6b8df10cde6d803aa8e45593e8bec39a1e80127a239975046f1b19c6c6702a0e8070eae103cfbd5515faca38f097102d22b09525c7a8aff0054f77eebf5fce9ba00a226cff44384d256d2cbf646760b0a421ecc25aa96d1647649435ce747df8fe1933272f44139f2d2f37cc721e013015885add011d0208d0795c3607bba3fe1127e3a603539c272d62708d52d2f37d880e3726b0ac55b7406c1aca5038d450eaffcb31c88b71e91104bfe90190e03c50dc485131f160bcf75811115f3f57a3c12c12fbcad9a25685004f81b3e4e422a6101282afc7c3028b86197dd7dea1a61b5cf1575e243dca003a50930cbc517e7d8538606233c32ba37f7d8928aeeb5d7320c237255054409c105c2f75c3c60a36d7cb7a1632b3353cfdab53d43d73773e9c36c5efc847e0a819f2a340fc9e49907797d535e31c8a651ba480af015c98600346e04a2a97aaddcc2aa47af70d8f828b86f11e1cd4712dc4c46edaada701d62dd9924d7bccdef6d304be2a85656e12e175b76a6f353d8f4c6b0a941f2351f619c5e5740e5d9aa1dccf99a2b68c5d50f3ba8d167840e3faaf3b1dc4d0ff979d8e2b090ec916845229d18725b06f597b2f2359fd06593c9057f1e8a8cc475c0e4a3fe745919b721ccca99b888e444423c3a1494559e9345a2a901ed7096db378b5127447a31c518acb7fccb20ea53b613575a3b078b9b5eaf24b045f4ab110d996eeda9ec15d1b7bf89f4d548347849549ef480ef0ce0bf7ccab20411531220a20d3d77d876e105e02cebf2f129e906106912fa1be7f020c99e30d35fcba4a8b5ad342a228531d257ee47b67bc45398437b6826913abd58048399c490e033b07a917075800359e6f8949060e180a35b7d82574152a1e9e7998391f6ddb5b157003f17ad50c40d580ae3fd5a320b30da6a9d5213ecae2fe8215f7d0a26acb85f0c772d5603438a9d0edc7cf420c67bdac978d75ae132a08e518c77315800db2fa4c52871450a2f44eb94d70eb3eba47c7a28e910077db28a2ce404a29a9130c61bdd24cfa06ab6df2d688d7bf5a5a8859098313a4f057165e8dfb73fb9abe802cc8690a9141a6e5dffb2f508720ba006915f471ec2acdce5aaac040438f094b0ac947786e4360e5135cd229fe811520863d45128bccb41413d17d32f97689a1189964a009e0caedd78e264a2341b0481e5ac9414665501bc386e657c79b371a736205b770a67ef25174176893a0c9f2709e14363252a92ec2e10918a8bdda5dd8db433e0241a3cf1062f064b534a8c2668dd5b7dd4b2c1878a9f9c510b55d2c990f819d43e438d8e03c75ad39ddab498ca308bada6d51537826ca755870444b49bda83c51b4edf6283850d3465a46b7a5918f296c0b5040934dd76874f376a83ac3bb74860ba07ac7a00b267edf2638dbb85cf293a281fe73d058af830aef9d87c0170fa790c7bec95eee2595f64471993171aba06dc0180a89a2e29ddb6674d1054186e82d20d4f8164e164b078ed49772b78080cd5b955ae49f7bcdae20e45320a4be59874e7f591a37b46303563e99274777271316c9006d44737d20811ad68ff462d7cab94318d33e936fa4cb07d1a5c3d490c72e7e411e18f0647400decf95bc540b27702313aaa60c21c28c608930ebf40d629b7608a4fdd962fe78017f0fb0bd367ff2b258af13bc4d1e0b7d625c90d0213cfeaa9331ca72a1bc70c910deb150c0f5574d10324b6c5b09156eca40582bec81027ca271e4b21d1af2a4585b337042a3ca8b8cc7da9d808051db1ee8aa1c938894e54e2d9e2563d4a59d467e2a8a357293884617148c947c58a7464ccc57470228e7deef8e70146530069aa49fa23975f9055aa6b735a27ce4bdb0783afa24a4adfa493e1543ce6a567aff2226ff3b6541860ca091171a33b7ca9f4df459e8903ff845a9fa4d87243810d57d7ffada6bb8f24d247cbb36db877df7bda28ead8721b3ddfe147185140a8e9980631625bcfd8e55893d103a32e0adbc6877e28a3aac50bc0e86c65378cd44e0d240f4b78566d92f83eb0992e984cbc4f286aaacca4d6dfae22dfbc0f543425fbc903478dbab3343fdff9a94336f154c06127f43db2c87d3b0aa52e3b20639132b56bf01d871ef98df05966afe3cb60c99d0b4c785c53480e5c6d5bd3ed563525cab0e6ef924a158f2eff7a27323fe8def7763762a41d9b92c8f5eece23cb596efb5683a44bd490cabeed49e87ffac64e245a3e310e50547fa21a2922e67ea2dcbb9df44828a9af319771338945b16816bc0cc70a2d8ebc166d4ede75ed2028af56841e943da9e4d0d5dbc7520bae4c0de828773fb53cfa4ac80d920e1ef9db2216fbe7dfd15777833e24c35e9f8a8d13bf9e11e8427e5d2c791662e4c930a6f22f54e68538cb310bf2f85de14b76f7d2072a4af3fb17c5f4d2184ab904ffaf6353615e06ecf0c4c83efa8fbf4bcc6e40328abaf1403c7885a5dab800f2083f4e7a0d415bcb8101e82050a2f3329c82a3ea96e98888330d5e9dad3926189c03e8cea2f5283ef6a17c8dd2e40c8b328a12981b867596143b095abb6203141e85c623d48a67ca8107ddb7b3278d4aa0d9e2618f7d9edcfebc594d5c8045e8e49668895f1b1f54feb519a6d3d2cccc4e8238bdc354c92db4078995de9c5ce02d49f608516c7c4b4537a2986db55369f12b72b4a5114139829fcbf10f08b777b494fbe7b5fc6c8c11f4758cec291b9905d25ed3863514fc80470f0f82f129bfe88c28fcec4333686526f389f26cea3a525fe887cea7cd5d4a70d44d076711067639138539097b5af5161f67cde416e75ce085285474e485d1d59e2d003bd3c778a78b023c7b1387097dfdbcfd6625f16e435748c521ea2a4f452de0dcc18bde63533bb837fd213265c38f953ff8fdee911abbbfdaef2df8f5de6bd9f76f56fd72f1f2398b9aecac4e32e2f79541ffdef3105fd5b296705b925af93376a68972bd882ee81e3f4ffbf60c1aeca6743664f0ee5133fb38472a6c39f6317835e28ace65e7474e99465bc0c235819ab61ae6445fffd0159f2bf11da187ed9c9cc87fe10b67319fa6bfdf630602860985ad4784a18c9a36ff3f52a61ae28b21c9feb6a81e05085eee3d8c6cb9cf893636e5d1fc44664b55f1005f35b4eb9ec3ab93c4a6c01926c85899d17a437b7c7bd745fa2d36775c80597d43845884747f52720bbd4d9ab2129b120fb5d222908af7c17c68453bef0544646bc9b52492b6d7851837ddb1982d42c6a8a0a735b8a6ad9ee4e346bec0143619dfc1194860ad9861a8d5a477558952781b84481085e6be1765160240e26137f9fc3ab7fa7f745cbd8e9f97561953a9c02f9fc2d6a3c264e2096479106d956a69088c54d11655246cd93e12d4b810c33d930d9524926309874200a913b1c2755119f3461b39fdafd86d726887a8b0218c84cd78b716a55e10ff5764990d0870a58df4a8ac99ce847e9d9b5a61d1eace785f2280f460481a9501aff644c28660c685ed057d65f7465504273d4eaa5b3864439f23b1cad7489e5dff0cd567244eb0e49c23141047e6336dd1046bef4ff17e949168a21df1453a62a2101b179e2fa1acbd5474548fab837d4704d8328ac181b4b37f4e491b9d6c6821578fab7807c8d78642eb09535ddf778dbf7e3c1a8174a7fd3c86f90547da5004f371dc794a1f6cbae88effca0a6dc590d4c3f4b31c245e40e4d401aeb20609b41528bb8af929ba5bc4003972594b65571548e264a9af1f6eeb5c8722654d6d81b4a61aca5af2c42d5db597b8126a1276dc860342662f8228c1a0cd2f13c0709c6b8ec68e46f894ef28c775ee049d4daa253d8c78c2c2f77adaa869f68bf5c2b83826c181ae59b73954f131f4c3651d7ed0bb09d51f5893565574741a1c9e64394510d9c233b5128a06a76382daca3e18b778f8be8b2febfe94ed782f5baf445c41acb8a73a65ea98d8820823beac0a50afd1252a8641fcb8800c2e0694e185069929b9f8366450920591506b440b95ff6d931b818f6c8539c125a3032e493343c194fd5a506e7de9717fe8b43888d657d63bdfcee3bd19c3d021238c803899fa60d24e33b5c8263c434c44336a63a5b11713e9d748be5db1de927c7603757e127e912abd8fd42d3f9b6ddcb4ad2327462d1964cca8bbaa28ebc296a5de7746bdf516e82bf3065dc0c165457d3845258a6d819350495b2d3e3c303961eb8ff2460d9794845e5494f731c49940134a64fd5dd0a92958eb91ca13814d0c4ed78ec0004a581231438b66aa117291228abe2f585ccbf634e63516db435671f803ac3157005de9908284cf932fe373d18a8f0e0277312d5c806b4ab5f665153399fa7e1278f3d5a8eea451ed8c5d7d85fd4da9d70af5762b763caf15a1c0e7dae15779c285ceda55081391b4e35e224862593d219ec2d1835022a713958b709ccebbef3bd89e9d6111c6fe3a2e5c8d04e9485227396fe34fbacc317cb738451562f292a12ae42b106f7cccc1369990b95e5a84dad998e1c953177a40076759502d224128c2b9ea43c984ed1dfc09b6693dc2b4f1b8e399cb3dc1ceac3dbfad642a883023cea85913966618ae1648a35d4f4b292833e63449e42401fde88ccfb66100d462c9cee7ff211da2c09d26e453b499919936ee3493627ad430b2d9667016a6e94a65cc4c46a7d90235cf4a585bd552abcc841925b3b8b30b46e3cb7649c738f38228efd0747e7ebac029992b97c52654b26fd0cccae9e896c936025c1ccb9c4005ad5213ad1afcb13e97a60681bc50c0519bcf70a1c1dd77590a2b86788459a47f16a97909f78dc73770ae5de15a8364bcbc3e35b84a64e5e26d857daf71dbdfb5a55985579027e7a793593e393a33e22aa6959641305eb1227f43937b592886c52abd4eb294dfd22475b98e3a5b431ac678a2bb10f9967a02625250431087e5d13e4333f6c00add16799dd0f2943a1a68b032e7804d4ba4cdca1c2df58d927e122987c62091c633e33f5b133dda892b25ce8bfbfbb7520e77b4b6205a5cb0e79342f928f65420329477b4eb85c1d876368726573bd84d7d16c08351f793f935eb6fcc615d6d4472e7f6285f9d1727c6ef889301f3839c179a7da1159cf1ad7d3d4d576215e8152ec6fba631113dc69c03dcb95e9f8a06ea97f596dc9ce39658803a35eeda7880deda2eca4d81560dc0b80f943842fa54e81d78b2eb8285ee472368c3908e6c29a822421d6e434c8dac773a62e8237d5a99d2dff0fb1a805a08bc23bf9c737d53199a02e7f9ab6728433720fdefef05a79659f9798e8436fc634998a6bf77a0921268dec01a29e0ad821600066705cda322b0942b6a5fde571a61e0678d80ebd0908230757f6142129ac318509f59d04041249c505055e7d62698c7006d610f7572f6cb1a025124cff694152481f4a062a7435eb76759c4c8c60b0906bb8230e1addc5c45fa645e1b0543e1711ffbbec4468b207ac1ab1a20b54ff0e79a9412044469ed2fb5e1179d92e24be3dca770398f794f6f5ede03d79a7108771b1d886fa7a997b41cfddf52237610ebe1c029a8f89bb211554a488387298a3c21fb0d40c96909558920b2d0339e9ba249019ae390ffeb99b7cdab6d33a392de967400f7f024888ecbf1115b3033c948c52663a79e840bcb3cfbb1d20d631fd4ff50db0f3a745bf8a98c6edf330c72eae6f61b93ac97b93d6f55359ddaf76d3eda3906ae0e6ce2465a0818cb55ef155389602bc8e4757075e18b7269a264b321c00ef58f274f599a77127041754133c5891c58ca66c9e671e7f465a4bf7c027dd1f34182d9fb153816570f6f40e602cb2250039e5999424c738698471cde073df46a8173569c6db0076323ee137b5164db77c1a7acc560d77c9177401520fafa9413bac9e23154b274c6023399fcb301cf901099bfe0dda78f8fc8db75765d3a857e4bfc5cb79295cb13a7a8c654250f9d6cdbc7a326bc416eca002cbceb30f4529d9dc36d7ca90788174e5ff26af9a45764c0a9655f8d8dc8458c4b2af0a92d75f33a511554ad465cb3ecdfbd45eb2a5e91a2b74f51cd9983bf92bc2d32b3d4e034bab0479304e559e908305fa7add04b986404372cb39033d9a164695ddcabc884f72108b6d30239d4f8434e53527a7aa8a0c6536b86029bffb9228473df97462d41de9d5838d02f364d2240f2ff5046d4c611860c8bffecc35ba2550a2c447d14185bc09ae28bd59f2cd1969ae4d8ae010feab22a71f5dc4d3cdc5d424ef1393799ed5ba1f23e33cc93cece99bea6fb93f950b377abee6c80505f0cfd23acbaf5117fd54e5634e5bfa0a1f1208eee8dcd096706ac748005d7c64ae940dc7d72fcb849f142ca3fe936e72c84d4d521aea97dcbba3a74a099a8a8cffe0f45b52b09391413883eb161da7c38efe86989974d059c9f842a7b144f0e168349fc571ec2553d549f0de50ff478fe5ea0a24a0f106700e8f56ce22daeed89574087f7fa6b634673eb54980022c68aed03209c423a4cb53a81baec9e4b44f91bdae3006fcf61c9d661e4d9b342cb5a614a10a2d8fefd473c3ad56da07179083be44aca65bd15d999173aa933c1daa50258991f1cab2efa04cbaaa273c5584b6113f6016b8bdf79b8ce3e62fd28d540fcee28bdc640725b7ca1448d8fcb7571e30e91f5a6ba0b23fdded28858400f370178722f5fb70538ccf202e6beb26d81293227c3b651650ba9d8f2f3d61acade1fea2463b38971bae63298a6cb2ef4e84d9c8f21b2680d495cf2dae338cfcebcb3150ca238e2fa34173d5c6409bacf91eae00dc8c4a906e06f86a41ba571961e79634d0ddf4887f9f96d291e3da9aeac649266762213a347c88db941d3519249f661915bc24e82fcb0faabb0bb5ac30f83ca7f1e826e9828e7cc1bf480e710d66cdaf124e1bf8a214556ee67518131e4e7bd54527d50c3e1535cfc449e8f5a45768845093c60e9b9628c233c92bfc01747eb181a64d165776d0b22ee13418fbb1a172986b3a20a24dbe1165a637ad3e990f32a50ca8818493c062e1eb4c40a562ace5e5657cbe31424ec248815330ea675cc0a291ccdca40fcb5831a5b7fe5f2af6a52bad90ec2113d19569fdcc3ab1f045427462610610cc211b83e8cc62a3274dda7c07faecfe5a94a41686afca89513f265207470495e741b9aeae82690ea82c3c57d854766f0b825037652e87902eb676a0cff77cce229bbf0f5f9fed23aad95b55c13677ded6cf1be087137880e06bd0cf71b8ed39ea289a2329a98f48bc4c44d4c54061da9f21dbcb5776ae3bb7a4b7c0baae9ec94ece7ec8a7a8b80a19afea7da117b641964c94b9667717175754ac80d26002f3736e1482db3fc840a5da348cffe13308c22a43f4a11dcb9d0800af0b7c20d4640ec0b6cc2342af6490cf3017a6e518a198f1f2290b11ec50db7512961467c6fa9ec01e841a5b84fd1ae0abfa5e6992eff181899e142a1662e529f7a4b96c2aa121b97540aba5ef9cdd14346ad3c166c7bd18946a2fd8a2e6feea7e5238a2821dc0059b6078120b2f8cc6dfb65de819224593a4dd40cfa811a210f8073836ae4e1da694e72e342718e7dd355256323c11ba386bacc59ca502e401e3257f9c2e060ae047dcc4ab0325a6088708a6433a7fc00e2f0beb063b7578b381001a8a711a98a05dd2b591ecb05b464a073482db1fa11b49d2c68cf71825668a3ad87e2521673128cb306a815548d5e1ecbe66c0f74e426c55e1ecb0e12b48ad5e5b1a44b4280f10aea59d290e27059595e92088cd523fa2db62275624fff44773993fcd116cbde923274c58b0ab45e32c1546c034a158e6a5b30145ea503da7996d0e7ad34be5c6d5bb8cb595a4b27a6ce13003b19ce0bd01fe258834645ce122ae22511c5161d628bdcf0f801e33eb7bbde4ff37afda35e0ad72ffe8f269670e1bee17d834a7ffce22d3bc8de64cbbda54c29a5cd0683068306346421ef166a21168a21c68f6b70842ab696953f9439628c514a295329a47260be0ec373c498715877c55239b8fa67a91cecbf37dbdc5870dc8cb9c17f3e5755d908abfdb6b586bca687e8526ef69c150041507e45a66d69c2f9f29fdc04bed56ab558469eb59b80f06b3748e56b3fd3600ac71c2a9a48434b46488db33538f252fbe79459651a354e3885a8475388adc110f08f5262526ea80f3b15b4dfde533b50bf7d9cdae19f6ac76c55ffd9aafefd981fff07aa92406307744a6e668750ca47fde6eebb6973325bb1ea550c72a8e1004328575709872f0870021cb2f0828315e011c5ea2ae1d0831516ae6931238cc023acfc35e933c3a44fac4a9f137b29a7c4a4f499c9a86931238cc02b50c6cb74333191b24c37f33134326464cfbf71291c8ce2994c866518f3fa67c2180e4de09fd96233d8a20eafd96e2fc60c931ebb3119dbdd1d6bd9b1bbbdbb1ba63bef86114497c8ed5162324ab92b252633e93353aec6a1c2f82ea5e4dc93acb56024c7c86566d8cc30cf231789612d774a96f24377f795bbcdf5203d62188661f10a0cc364c4aec062160cc33029b12f24e65fb29c207ac430b98aa9ebc36b5ac76b5631468c433df699e3ac0ef73634d98732aa8e4dfe7ecaeb788b07c4f3693048bbc03630b02768ed058bfc30293b66e6f828c6e9be7df8f00192c2e19f0f12d02984da3239ce2eb2931455c8b0218a183728e151d49095e090430d798897542e7ac9e0f0030350a81728dde0440d99b5a2640316a6a2c5450e95f9aad790c3912d9d53dd38eb423ba523575653829c4471648601c81083f8d188961aa7a89186276a0cdaa1a3e1ec2a73d5abc94436654a1c894804612938e245415eb34a35b4acdcf080238c948ce0e086071021a186b0ea55cd902a90f88113c8c30fb6a042b3ba493ff052032b66c8c28a1c9470c08245d27ca6a25543a6a255b51857a8ff8186f3851c5c23d001ae1c1274d21a657cda3851a671c08fdfa790a08cfa55fd313f7bd487ab1b9c4a617ef6d9e4388e7bcfe9e7487051ae598eece79c9aa6693eab99fdcc661735962dd89666052e622b9b73c3c9d628616b74cd987b394aedd63e7b02c2809a00cdd7be0423ba757e3f4d7ae6633f7f9a842a28a002592cf505ffe2a5fac854f91a90f50522a06e7ed38b64585307f303bbc5c2d23ef38f88e6a9fce5664212babdf64a4680e021b2ad2781f918ca53f9d7333f95fcf9cbc23e55f62c60d9639f4a3ef6cb6221fbf9f3fbc1c01030f0e243abc5ca3e955c96f6bdd7f8d70196401419b1921c3c3d0a68c8454c1e1134ec22958bee927f0c8df3d3386110f971510a09aac373baaee1efd81917a7d59d3776c7766e5eed0760c188d3eddedcedd47d77fb6777f7c605c70884b8bbb179cec8cc3122f18845cfc89c25c6e8ede8e87883ab78459432fa17af702eb6a5a9dba0968d3916a4ec97de8e8ed7fc40c71b5cc5ff188966dcd238f1080c74a87119290284225b106088224e45b21079d2220376a40b1aaca06c60ca860021635ad18e6e51036ab5c56be3820a27451732c0be90a2b58ae08ea4b80a2353617e4f5061607e12a930325ca9300f238503a62b402af51bced4144d4d7d4c7d11414da5beb86a4aa9e5434dfdae004449b16d3475b3a9dbc7eda79724eaf67448ddbedbbc58aadb838db3495f0c31c56e4e0c153930e20b220b787531c4c58bae4ccd9ea8d9cf8c0b126c7183c5f12e1543610b2432cb22801a54fff954c593106d26af0ac39c161796640386618cdd4036d920a59472092c5a920829a1c54b1750aca0b224d960050d590d65862c0d01ac494fad17528d3f6fc4f5828b11473380410e929c205a22882d3ecf2cae1ae4e83a0d72185feaac68e8344eccbe307e3a4cb5205269542f6848690c61894ee188af56ab55e428c9155c38f1e2cac11169440a58b0558c5695115de934ceb2fc38c3801ad2744982290b23598a6accc2881a93862003e84ee6933927457129129465d1b8e0500336b9f81024776c119471118286a804e362c411d762cb0e2dba48cae504397486147772692207def1d4e4353bb9b84068c7109c3a224e4a337c914a32801758d440802050545da519ba0ce0896e759566d0a244b5ba4a3334e598814969062230f0efcf565d6f6babaea7daefbad5c398e83ed7908584d846ccaf8c671e388732f3f22fe77c42f40b79a96e128c2fe4275c2ca5eaf093da8c04887d3c8277016d905543a061ece91ccec2d33898098e3cb1836e6d79c2b21fa76c19f6d987e9c4784171c207c21996a19ef63bbd2bd49199b7f21ac6da6582262ac60082d228652c21b1262645998c22d98c61034f4e46f2d46234d1260a45050d5d028409456d44201ddd8004885ed24c9c4a07b93fb953739566299aaf30169723b99117c98d932104c4d0122a538e9870a9182ba80161f63c0df2c8fefb917d3c7aaef037ab071acefa537ff007e9d8c91a769e4a61fe8e6facc5afa381b6a22520e2487b47b96b8ff25ef02f3a2f1470a0d03930dfbfc5878109b30f39f662e488607edbfcd9f3ce87931f11a5edccac82f13ffcb587e1af3dc752f3b28f44f40b7a16cc47157fdd4cd7f46b2ba09d1419541745426713db3eaf4725102f3e225ea1eb6d6d6173767936085a4c4822b3f79af92808ec6f0efe52330cc3b22fdcefc06f7ce9c110eb8ed8bf2c22d4af07a3baa7ea9fb5bf393d100790e62b4b284ab08c208a96111c69ea8fd9dfb93144897bf8de434b69410d57df030dbb97122d980d70659a8ef10f7908480fb53044c92eaf0024862f08d78486eb14841fc837d72de58361c762a93868832cd4eaba2a46432ca12449c9fd8341dad81bfe06ec092ff8172f3bba55e5d780bde1da5e07ba4a4f05fff2e5cb97da5f03168c2ab8cb4f676f646dd6a921585986d2b0d3b0659f61588c40acd1b1280463be61e9004850595789071c146009edba4a3cdca0c30250578987293c18d5f07b8ba416282dedb3e4ea4a1e1ed7d5de4041c36deae17352da750f32ce32b8cfcfcf21013a122833aaf23659a0c7d688cf41a8dd3132a7a47b60d82cb4649bf99918638c3ed1fda36ec4b634616caaf2b7ce3e9084adc19f01fa518bd2b2d758d3b44c7bceb0d8621b581c32c5e2f45377b1a07c192f624af582f2851a477bf911091071282e699cf9dd854ccbf862c47c5e44bf229814d71f7b0b68b8efad103d1d373c14741a94361290e0cc1cf584f9974dcd999cc9005b835f3ec83632b7c1179996b49961a856a2cdec51dacc50dacc309436330cb54ccb0ff3a9df1ec59307745d4f4f4f4f4f4f4f99cc27e38bf18594c27ca1cdc77ddb3741d000314954326d8d661b315a557e7cb23596ee8dcb9f93d2ae7bf94bd953f9924a83724a95ccbb9bcdcfbc179c911a1c82ae8dec896d645f346a2eb6067ff1c9de7c91696fe44b25745a098c14c6bd029aa0303fe3e5c72316274eb1a07c39e38b465acc17dad0afd5cd2902a500e8ba19f12bcc179960d080c6f7efcf8be44fda715e94050909090909098983268a6addfc4c3ec641937e554013348c46ad2a3f1a21b9965e4c325b63a590b115e4394258f2a390e74496fca8240e7d2c8a4d362858edc7dffd5412908f3d0b8e7d404d7a16c85f7eaafd88b25f96fc653dfb11ed9837a605195e0bfa91f7145846c0c2753ab51ba10723f480668b369a9d95820842d0d09f78dcc96b4ad8010dbb656f1844a914e60ed8c5485cb4af255751d1f217c3021abad04e7b933b6571269dd76aa99b406f2667a55ec8012b21d085804cda096d8dd49c9476dd3fd8af55bffa1583d7c407e235d1998aa6a061bfac6c4e347a6d0dfe4e0ba5c2688a1a7f33f21c9a45a3ae24ac3cc799bc26fe9c9476dd3f08ae564c948a100410cfe9d7cbc90926323de938adb2803abfea406aa30353e3529eb3d8a1a01da0159b6c036324f6263e17f109ce4a7ddc44ddc87368c450a1fe5da917a35517fbe411f5efcf3e9992c0b252bf291eee1909fb908b7060518a28d3aa5cb492de6bf7b51d0150824d6e1ba7fa63f4f7e132fe7cb84ac21094fbc17ddcc17d5c887dfc2020e5730a07c7d40a42eac6defc622a05d48ed3e9612e770648ccc004b57db8da334002864bf5a76385d7c2b362df2f5f074f8fd4549ae6c3473e906725bc447e10b94d44aa0c2212878e704b57ba90daccbc165a537056290456aafc1b8db33ea8f25dd8c1098b949ec2812282c68a83bd0c8e2ca502f6330d764464fe3958056eb509c12a69c815133190f27584a046d91648849478108251015d25212521185816ba94e2b81e68ff2a0931a9d8af6f18c6428da3d2fe3114e771d8dca67c2e224a3db37e98c5bd4c0ac7fc28edbec33e1b50b56a50feb2745637b06f6713e1075a7fa0d8739dcf2d240d2a69500a3528352bf46bc8462b603a66a6d0551212aad86fbcc92859888d3c466a50be00aa501551ea97c53dcae3e9d1625640e3b1044d793dbc463ee7f98842c36daa12ca12757e412410277655f9233f062168b84ffb1d7d7808fb9529283666a6d99b1eb21f7d4e4add6d36a45bb338dcddbf0f40b32bd95a93d2676262626abd8c3c92e80ae1fcffff9f3c74f0c0e44f791a696664907037604c1d9fe051860e51c60892cd33e3d91926a349a49991e1646a68e641c9b0e2bb86a780523495d93c681f3a7662f849229c4f413334b403ddb523c4483bce42317ef3056f194e345c97cf8ecbe572b9a490cf8da741973b0d6e41c3e9e2a01df6666f76d9fc4960760d13dbb922ac18f4536d1f4f8ca7458f025ac40202e35371d1def4c3c0dc97d0033ae39391c105c5d88a3e1e0eaa28d58e50fbed53ede0df9e5f48155277baeba672506fcbc2c9c582f196a5793cd4200a6c834bb027f433d1fcb888461ba59a4341d3aa54f854fecc04658287ca5f68233343433a8310ff1ef9df4f93fd7afce3f7f32384a948912d32d4a7715a1c0edebdc0daa06117b64610ae2964ebc2deecd3b08d0bec09fbfb855bc57ef1eb582816317fa78f7eaacf1f3e5ba54a75ff1117ebae52e5a8ca67cfbe3b85a3b32cee0fecb97e347aae8ee8578e4a49daf863588f9f3f9583ab0f4c642a476318b61206dd1b8975330deeeeeeee763b4de7d90467409b06411bcf46468ee338ce9b7783a1eae158f2632592df0f0858d46b38994a01e3662a076bac699a37350fb5715b2a7aa738b5198cf0054fe3540ecea3810395ca81550e47f584ea0ed55d9f7dbdbe70a91c5db9bd49e5f0caed8d4771c0487130606052746fd893c1d1e58895c66c31a8989898182d26262666c6c46431588c8c311ed3311c7302bfd8c50cf38446514336e2a1d496cd07206088edb3623cab8028a80ba7a7713819266e18b8f2689c6f4229527f884151a4d07c94204f9e2821c5b69cb9a0092b4840b97b70c5513061b27df49db3bbce93a06d65a3fb1d25879928534cf041fb2c15666ef6d2ddfbab06757a1ba73b7e389d7a7737b66f9ba0057dbd48e04e9d3a75ead4977a0f9c301a5a52d42038a345431eda6716d72747c4a7c9556471c2a589cb15c58997902926f880fa2c158ef254c3a74bd35788c0fbeb4a297d77e3faee7e3dfb294a09ba27ed966977386b0e58e065e7c60c1d68b82e1d3a74789d0e28ee2e82b8bbbbbb5f5ca675ce3f7ae156d9dd940b3c4629dbc4141d9d0f596989a61a3e85120528dddddd1d73772cce06fdf7c6bb2c8d954d83fbdd206f3bb3733132d6e43b8e8a7083b92ba0fc73ce39a70735f161cb8a4667db2fbf95ced3689075a46c273c8912585c477614bfbb45a8abe4a40b126c9c34dc3e3831738f06f97d70f5f1e17e0f1f3e5cd0d91b7eae09ede183db6edab4695d274772024ce5e70f003f9290cd86ab2c450a17b91e9888a0438cbcb8ffc18ccf04e59e8d836dd7e5f4fef7864a7bd8a250d73d46667e0c8b8286ab1d5f89c2737431f624185058517612d0fdd5f2036b4728818222e2729520690853e4c95a8aa281aeb866239818824a08945c69024915282aa65eb3cfde8c42775775f7bb068ba06b43164e51fc553d9fe09947d2753c14c5a1788009e7c46c2b3498f1a8c094ca39ee72a171f6092447955f5d7a340eadccad2a4f20d95243bea18519ba204de1691c6e41e5dff53929f51b0d12cd5fc5b430c405f2573ea2418dd3534087a2108edc5d623724e6ee2ee5638ca57030f67247e28e64ce22a8ff7f838d6152a83f867dc488e66373ce1857f06a7a31755d47b4f1f4c47f148ac79c3c3c5e3d0db644794124cfc67ddb1666af6def1e797ad9164476332fc398962512ebe1c2d7e8f9e8ae9bf3eb71a3c5850665d6c37d9cab2138d3a0fc3ace5eca28d4ff553bfcb3cf9a48fbe8691a57d983cb85246bec065b92b610996982020a8dd31f3d09e5e6666460cd38a9410d6d666823115aad5641336040436e794f31826469fe6ab55aedcdaaae68cc0f5ce980ab07e90c82814fc4cb781a3df6b71f44dd403f05ada599a56e0a0dbb89441123468e8a1c0d79e9ffd93ec8d6e0efe7c0720ed0a2096d203e9e0f8fc70edbe8a0da3bd9cf148e2835ef9be1ec695a8a086ac842362d90866090bd41816d70604fe86f4d0b7a544316a2c12d579cdc9091274f505f3c61c26408131f5e0d2ecc0be8d72a3289155ee136c5cdc1beae03f766569bc69993c77baffb81c61ccf1e11f68bbd7fcd7a57b520e857285f549957a50d7612342b92e4430d509200a19ad0cb01326308fd979ca67d7326314b46d33c63b5d7467be34e360b1115435328b122d4519efc3d07e6b51ffddb6bbfed0dba7dabd0bf793d1af427a18924a954654b65a52a5dbad544b0df9e7a305ebb521e6aa2e69ca86ddb8c3a339a935277327ad0c948a7ce18427b66764e7376dd3f08ae56298f480af56d3427a55df7afad3414aa7bd25ce9289bb398b795ea0d45f57602c6f64e1fc6c873603c877eeb35309e4e08528db37d1e6e40088c944783609bf6dded2814aa67f6bd4429c95dbaa687e74c963b35e8de46d597696ffadd488605fdfcdb8c21df0f9056cb63f3c72bbc6373de6b74f0146b65bef6bc537fec07c16ac45e9b3888b26d93d8172e5663cc767fdf3518d03ae3ea5cd1073dcca3c10e2af47ba401bf0f08743ffcb8bfa908ec77e353edf874b8c2d54cbc22290906f47f65a48c0da5734257980ebf12164b4cc2201ec64fa741ef874c413ea603f641bc4af9d9476fbf5583197ff9f2e54b10af1c0601f9e964afe3ada47f343a67fe8d95ce8e4605c90674ca84fcdd395b4d7ff71678b6c68ceacf23dc205477ff95e76c1f2b995f94b287c7c7f341a1fd27a8d28b51a5b74b489654e96d7553bb37b2ab52feacf263ca5ddce3c6dcf3afb6c68ccaafb33524144e705f0cdbb75e83fa580814a2a4fee8f7d98c6be6bf59669dab95484a438ab817b2f5fc0889939b3b78da41465da52737d84149294992ec411ba4f7424370b9719669869716297a9c148df3ae55f73abc867f7d76097c2574a7174e15fc4b5d50872ff9cb2964ca2ed5ddddf1812f35fc69d5fdb80abae8d75daa1493d1578809932f5f5adedddddd9ff6a8466d956e8f8d5a4dfbeeb92f1eca300c23e6a373c2501a44560d45436b9e0685a0daf7a980a23e5c0939aa3fb42851da2729d79e5909b51feb2fd4deb5cdb25578f36db291826a2d8b14b8fa2f14285d52529ea4a43cd12289249ee8d2c4d2d258c9501aee2bba0e349c759bb33f206ba571c23929dd710ffc81f21361cfafcad1771f6c20e857a41454f9cde840c30eabc293199c407a6bcca8b1f6f311b5e75c7d50fa7df40616e7c7829da385ac038a66a95dcd7c41ff8e42b9621f0cf10b7d364b8dcf9a4fa4b1eb86b74383d0b75016640213c8c8ec1eb19732945232b38c531e716c7759d37380809a00654f81eca380fcaa3032fae7de70f4ecb47f2b30b30068a0fb11e8df0f05546a0876529c862a55765f3c7834b83c1adce769707757fe569b06b7f31aafd9d75e40bfbf705d2b2846825acccc2c9955df2da9115d59798286da5f1bb1f7d0f323a4e74748ef7e1c04ef0a614dec8b086145212cd5673df1e5f7133beff66e2a5c5b2af69bc4e54a9dbfbf836b2583515ad92589b667ec53fdf601a558d83ef5a90f889b5fa722807d60830cce5feda7170aa9a1f6a86deaeaeeee0b3f2108e67ae033f13fb29fff237b08ec6826557e33a9f2db3ef3683a677b17ba66f6d042c37dcd6c57270e7a784a32425d2514e4b0bcdb02ca7533b804e599066bd720af409edf1f00196cc006a7084f34039bd3c2fad81a5cf931b038d10651962455dea6ba5d2a7f0536c747f658d095e734c19e2bf77eac2d53d897419ca05ca5122ace2dd719f639b22f7bc9adfcdc23f27cba867b40df091535d4910197989d6de1bdd2c44e287f051a87824ddc6ecb8f908406a8fda1571b209f90f168b0f7b5e2b1e113da3d1a0dead8b08d04ec09fd08c09e5731a0a83a27a5fc3d8f5461bfac9edec67e56ece3b9c1b59253583e494a8202a5698b1042114350ba326504fdbbbbaca40b13264aaa50a7d6feb033298defef1f90d7ac8a05195f7ecbda9517d2ee419d9d16dd8dceb4caa2a32d550175a13852523718fe905570a4a4822e5e18cc0b6630fe19ce9959b675f78f20723d7cecb7e6b01f52ca7010ab7f22848c0f50647c80a2a4944489a5244bfe5c8f80c2748416a10a0ae84f038b653f9ffd1f3e8ba5fafbecfba781c552fb53450985727f74f78695800285092682824aa8abb484117fc1822d4f9858efa44b19dd37c77f7fd0cdd05ed6c90cea1ae999f891e5ade195df8ddce539f15f04959f1da9b22fb514d82f5569d506d45daa61a8ee60e4853f7b8b880921a0404dfa81e2cf0f9bc90b1afafcecbde51ee439254041819af4641f1f0828eb57f64c2a16a26abf9f263dd8c7e79ef8fdfc3451f1c49fc0b2a2b601c58f5bcf3df60179150bfef1e30784bdefa77e59d293f1531fd0fc38bf75a075e2b2f1901050931eedb1073202d23e36f21a1ed201ea63232ed8a7da4f4581f9d8f764af7d3f4df6b517c2eaaf67fea878522f84c57d13150f50931ed473a5c04f10b3b09f8159d803a154fbc1d0335ffb7e7a780dff0496e5e3e535ec427db84da9cfc96bb2af5b5e93cd07dabe16c21ea5f1872d5419fb80fce7a7daeccb1e7b1632ec81e4671f0b1890d7ecd74b610fa528e0ef4abc865b3ee42da45ef29ceea55e1687def21a969605fd1a7aab72f7521f35c84b6dd420ff26a49b0a4d71bd76f77f47c78d0697bf30e2a8fa57c6f622e8462d647e75ec34b87fa5f2f7f2224992224746a4808179b98290b06dc9d6d86609d6060a3bbf79a8a75e5f714531c462c2a47154dc6fddfe432ec291eacd9be12f64241aff16c2c9698855a4c4941a32d2875cc4b193cd0940d3efa618bf947ecca7da3ee637a0dba8440ff6243154340300000aa314000020100c064422b150389e29d2247b14000a73864c805234944643591224318c428818420c308400600c101a1ada2600cfb45151019851a3f4ca9642e3cbc9e9e230c410bddca5922151eb6290133dc8040710390dfa9d5f2ee64468b80d7bbbf9b50c6a5f8db9db7bc1bcdb5b99a8ab1417d21efb8839dd7eef530afce31d0b0d48aba7fd31c98afc201dd4ad87cf68586ae87da0b73c0051f036bce1c9f10bb9d9ca75d0a548cfc2f04b21e143bb30cbabc158702965b9984b789d054b0fe099a6802f25f61e62abbcaea765bbdc3e6cbcc26b135de1d173f2bf57e8fc0fd30dfe28c902297d465cd2c6071cc1711a58b54da2af8dcd35eff98c8983a40eba74339db4b835795e46ed6de5bf7680a20161c46f356cd46ec6ace0e307005ee094ef35939c959e05e7502ed346a00d948eb664b84ea0fd76602d2c4df7c0c0e85432409a2e4ff07d3efac79862deae4ae6633d0f8980bedf9e1d6d4f3f185b9bec6e75b0a20ac2292149b94301ff592d1152560019f0896466a9bc403f9a3a599624420d5414ebcbb4642be8297680a4394efa251dbb909bfb856a465519e302c1d58c73c26f1cd072508acb8e4f6c0de5976b654bc022c0bf059154ec50115f6a43a7fe5d5c351cc885a1c8a568492fc6688f56678ff62d926b0cd78a9db13e0437b320f81ae1533d5d9f233600ba074ebb18800db48727f031e718641a090c8c3051827e9e649f29567b897d1d03dbb5b1bda355624c9becb19a793a07af76844b36b903f3eed7d13bc65189837eb28f5a6ff06a5ae00af533206d9a0b10e636db6ea0df0585da3706480490c8821838ff5b65cac4af862f75ab69fb17df951268f7ace8eca935978cab224883c18b96d60c48f77c51cbd60b0d162becee62040fe7e8f281813cd569aee986fa4a2abdcd66322ea8891ed04b10f5ace5e7bdad198ddafd2634dac9fcbd12c25e01de377a1280ad60b6d78717668c492518025b6363f5666e28537bc547ce8f0b61814684452c48ad1b77e60a60f81578d9710730185fcd868486b2977a5b38bab058db322207ff6c23a064ce0472356f9fb72e5d0769ce2d49b3690636f2adb9e9937e03fbeef0207049a13003c28153d0762e5eb25e380af784f8966daf63e9870d52d2787c02fac858b4c47d6105379ae144801d963e187d1cddfca6730e8bdc4a816e28752552286f7d182c57429cfdc376ef3d673a9e8e43080a275dba9512541f6c2c8bdb9bc08e030479e366609660917d9dc516f60c1694faba7be3b49eed38f89322139d6bbf14204b46ed3c8c0477000be3d3e3a8529c1983019e5b87b7362baee849a4e7bc9e5798c2979f3909288113db26d78ad91258c30585b7fd390efa1a9ae0ca5af938e648e1a06021a961ea51a796e5c29a0eda16a72c8b298aad7af5badfb3dba5fd94f5da8ee00ea751e8675a6180e552e03d9f01cd087876a7bcaa3266fc40f652ff305dc5cb87b22b7f6f32c7d0a69ed5d56baf6924935c72733ec42e7a5342072a5e0c7977645060151b4ebf484ef608807c17baae0cce493f20bd65f20f3d00cd5857f5584a05863760897937d0b04f8ea5d85cf263fe26341e0d0896fcd69d58dbb6ff00514d4cb0ad7cdeaa005bde134efe0862e7ae15dfab73e63d81905206e6363ba1a3475e15bc721bc90e92568481d88b641266488435d6d3dde216eed4fdf199359e04c5ae0dbdf5c3a50de72f2f452cba382b003b584abaab53659757b51f6ccebe345a9ee57ac148f806c0f7a4b386e32a765651a45d14b7405708a8d8c7114db2b1e13cca7e9ed21d465256c6c1a6d0143bbdb3600287fac95b9d13b4cc504ab3e4e5d97d5fd028ae8a92557592f2012afe7990db1b9ee1bca96ede4d3c4bbdec8c979ce08569112729833c93d108d91b7e0212ff9f2e484f03d297edf234fbb4f1833a5628b9a1add0ce938bf5b50b1399b8341c17ef00520c6a10bcdb878826bac303a286e00be168961dcc83115f5d1eff3521c85569ea590cb4da5eff5c2ccff80546487f15e8d6dedf2a81c60aa8e103466dc75bf52c691f731dbbeb9044ffe12da857b36d23007136e7b24f1d3db28db579c0470ca200692ac2a3bbb79abf16aa53d97c3d4b2dcff097bf68563d9dd21be546e641da3c60689db8417fa5fc6aead8d4484fea1c55ab3a2b24b851752fcd4e74ce7473d036ef03a3df503c2947de0983e82648e7c9685b37f8d246ec786157689df0362f91b6887737efb7f4acea4707cae198add6e9e176aae46c956fd416bdf44e8d4ef0c1415bd8e305e8c3b52603186061dac74f078d86f0cefad81b6524dc9e89cde71bcf73ad0db24c805349958a17922452adefce8cdddaa0eb1f553b006e6d8825a41760241c8f45e6805cf5aebb45000187fc99f2c91879aedafd7a8eaeab9db19ae57a65fb9ace508b8253a279d96fdd3dfdcc9ddfa85e0a7fb57112417d9e741625f337ce2a6569362e8f87e159952ccf799783c830d5199443e66c30e0fc95acb1b431a30ae451a56c94e98039899d9f2ea24598cc7b3f6d363a5b6248425be3c213165574a24b8c867a3dc4b43643410a826568a0e1891131b22f42006136368ad666e5d429a28e46473f157e98374559d29223b4a5314c4072e1a8b0080c1c1073a484f09504e8f30264ab5c5c1edc05d8e2f9fbcd4b86be5b6774dbf3bf3c10c51705cde0ccfe45f19c056288801e5768da31fb4d112fb4a0a827164d33526bad5c4a38d966731f36d792f3636c50267a092c5f52150b665896f1941f2d2a6aea15033805ea2465fafdfa94d2450d4acfb45e6c91bc48c2807b50da164cca7d848e8211656ab39d15febff3678c214ae11201b4beb9ae8b5f075b4e17a0b08f1ecef2dc53624743e20eaf33da156f216532f64a4dfda7e2f98be5241c96426e9a4dfc500dce2f202e276d59ed82002528555407d9a8b216d7db0e4c79621cc76579e6cc7ac2e8ddbdf2c1aaf8f263f0002b0410a50cdda8eaee3fe413c1d5ff6c8b55666e6de9947c21b952d650f112abb16af715c9b3525a59415724ac4fd808fdef64de05d91f43a10a36da60d2e847e3694f82686c174a00c84de0207f9ba02d20b1e73dd60fd645372245041c0be35f37a46cc77b83240f882950a6912e1be9de86b355c99d87d880cbeea3426c06ec937927c65f4edf5ed52dc224a3d280714ecb67490569c92db668bb78c7ce42e41e16f28089611362e5ae459d1f105d11947dee239fcc91350de0e42946e0f202308a80445749decebaa4a7c13f634acf318b3b0a74327ef2f7890a40162969c29ed09152804966498ada0e7cc6c2d3c6345647c6f8ec41093c7e30b0022ae3111e80efeae238fd5eb426c3c2cf35f81fcf370fb93155754fe8763d7d32880ce330beefeacc904feb219491e1845e96a950e2523a9e6f5229aa90132d071b8b1e9cba1e29d56fdaca15c0b940731a31176ffcf6f9c3ace50877b5f3e2eead764a2b447442af776799df1092c83f7bf9b561783321e18ff9c82fa043b7067a06a1a7cbeb3a534bf9424a8cd89ebfd375ddab26c0a932800dd0000d53d4ccafc649d8ebcce4a54fad78fbed1f4616ca5b16100def77b8107b14ab05fcfac65f23d81abd3e9a2ce180e3c10bf60352d6b1b460857c52c3210baee9715b94b39ecd3c97e95f5e3dd2d7babb1e6c4eec7fed7c6fa55d5c8b5d615314ef9e36c6c34427e5a7e8fafbc99343030489ba20af84c7c3fae2cff247a234afa1f9592ded8203578b1f80eff5c3a07be6d3c0a94131fb4c10571c8379d0d422eb743a993848abd36accd3ed0629e262279b3950f20061cf3d99d8afb7c0918cf1a045cbb793b1608205c52ab32cb6a89361319f3bbd6b1fb330595552ae19954b7fca5433bc9e413ef398e41ac00e08c220f8b58eea709e4b90f8829b4287a2c770dedff1278a6ec97d1900e3c3e84e35db91841e11c3693f44e867f51c2188968a1a79d24aa8e41ea4ec0b9e6c9080922e1b75d8d3f00dd21cb468cc23204180659cfe07812fa7b171800367e00fae60590120ffba117dbaff94556f5f7dbdf5fd126e3cb1fef00c8893c4f60138f6863fc4278f089e247add297f86dcf4aa5fb0156196639901e183074eda75efe1c40b5a87f289f2e6a21c6213a8083369a1f835b74d6c8741eff024e7f1852c0ed554881327236c7b04e18d495a8e99cb22289207518d8d36e1b0f98522f4b376f0b30cdb1bb326f77ebd949bf354d052a1e52dabb3d0846d2f12ec85e44b32afdc50b8ef43e4661ee4f8189009517b98033f8fba3e58155fa77605fef0a0a04d5ae9224236d0c5228c695a48a67eb09d0c5a998bd281da0115c50d438f19331b42e51210506418e64064d11d10700c5bf87aed1e270e2b65052e98ddb6caa101c20b1a9f57c880435a6cf0a3ffea5c83694f2bdf6caf32e183a2b344ed92d9a54fbbc2d605a78edbc3bfa02b57da010fd9725b69f3863d0a28fa9f17ae66acfe5240d072e48bef1426f375c6d6875d0ce3c044eec0daf61dcab54aa04cd44f97fba40d4d88f30ccd08f26d24db57050c640687a9a199ccb1c2fe058325a4b9b43b3860c6abb49a6f85d4f6751f25fde8eef2241c31844c4bc36a2fa1f3e5867929f37684c1d14abf247ff53b1edc8507c0ff76464b68db3c12c3b5889fcfec2a47d0a35185a9615f8c8be63c95a7aff06f8f3318e5a2141746d8d41363251c386f09f4daa7a391f2e4c1a82583f4cbc73e9d5de5271786e73b2e277bb63d4a27633c902c7810eca6c2db134463b2ef38b21749c708e2d949157d97a645b792db50f23e0969064bba67dcb2ceb7d5aae4dbd60aa3097d979d361341146a7d343b42e51dbbebaa4eadbc21ce0f2815097cb0508c9e3ed6d8fb692d466bfc1edf1b2758e11f00acb397041d9f910aa401c476738145d8e2da15821c87acc3d95589fd293beca5bb9fcd1eea4cbec0db7de335e5fb5249b89a1688d9c40dd884bda315a1e55bfcc5bfb9370a17476765596d25dda2f889b8bc66868d209fc8638e415f0cada750ea232c6a793aa64e38c0d49a7412fe9948f31f867a0e98c026ba719eecd328b73c1f954f0b63085971cc1823be1ef9148c41c38777fa21b1ed374064aac6778a8a9e3dab4755928af5025237ff98b89661366bd702e2f70be7d67a4608828d86154271f9349b02751e0030a4711abdb4799d80bc9b34527baa6a58de8a1bff5e7fcbb71c505560c6e70bcf5c58642045794b7e85fccf924caf469f2e83dbd4dce90588ead3606c12afd46c1b6587ac8aecef66136370eaac6fbf9142d344448c9fa7f29a44320d8f3655847c06feef6d65a2a26bdc25cb2081eb7f98bb3f9feab89c6bee2c457c315e5d4b0c80c5e94b94ce295a31990d6a18b9b4fa550c82f1490a437ce3c90f3ddaca51e892411f7a4eb3648cd332b2f81a68b7a60a87879997d748887d5dd3a6a6578a98e8bc3eeb78b9e40544a4dfbbe2903ec7bc879f51b00e33e5b59defa5adc3aa39e668aadfc08b42daa5209dab4b9dba5d98c6a3f12e00a3c5b455d1506e110050a15f135e06790fb49cc5259a9eb616e600c4d27a279d6ec272f4b73b5a4f8165c2350523a1e0aa69ffff57e54147216c7ee780a0072513c430a29a1ec5ca7cf4ebb8e4595162380a0f77861316828ca47374cd61e3393b36e40f7c9e5111ac710ccf0bd6b0815061820adee301768752f0a759cb219343416fabc042357fd143dda81774a865dba41904349eda712121c5ded7ef5fcd131952c3d016775cb5b61593625aba23d041568d31cc7d4132f8fd644770a4a5fc9deb28d073f225a8ee7534701ba3d240c7a6605cbfd8155b27fc6799a4e1239e29cf110db55ce5e20b38c33b3adb49987dac8a5b877f7d067cbf721d7073879347270a528733971e87ef318d3386de7a77a87a212648f2fd6778de2988508bd9f4f2d99ef9a3f461229aa1d3aeb46581ec0f2ffe2ceb08878dd9c599a5b25fd13a57e698c332135f3707b5b9d64a0da08eae159bc9d605b683f6802bcfef7fab771cad584cae63fdbf9521db0e066432d8e7f17685e5f6fe92abe10fdde2151d0d2321c2a8148d10ff4138f63fb9b1c862c5f2afa6221472d14db06f9770028c9007c426e18658c24f6f4cbd06fbd1a5182c920c6cc4a2a2631fa4ddabd21e786ccb3215e87f24dc2c3159c693afca6416cb3168fb200029b728a23549635c8a8943b69ea89a113f57a448ac548c1dfbc747c8b75d888451a660a47e1c9278fbc5dbab6e843918d788c66ec634af895925d9522e9a060463197d5d80613841827bcc22d714c8643ddd12991da40d766314511d420743b59187815e1b06e63caacb6f673a944b781ae9d95cce0a684611d70e86428c421fa6134e00efab882b4e6e468b2018f6d59be986a198225ad01d20ae21a42d6006f5cd7ae06f67edd443201c274e99e0099bbc47c022ba01c6d8969872a5183c58397558e008ada6ee4ea3e4b80d9285eb390111fbd2a773d5e487d08a0748b5848240edae13de2db1dd3f0a7d01d8a962217a92003db2046e706ad27962f9f8fbc141aef1caaad7de40778b8b757bca3c4d340befdd50aed43b7ac2e1613bb337982884b47f75ba9ea8fdcb1968f939b2ab90f8ddedbbe17d3f345dca2921695425eba9d61b48702f17395e32d24263299ea9a35de8c49fd6796ce5342f1a2d26300d90dc789e3679f4109e7d0fa9963be5cb048786ff5559c5596e040290f1eb6ad1f4df3f93a01dbcf4855514919c2cfb174cc4f03a1aa3dc2a1dede485b16ac3a9749b9420761dd2d70ceaf04f92daff4be6f03834cc0eff37b38177a171804000d5573e2b4ce5998fb296070879f9f4571e61c2ed78598559c5b217c3c7866ce52e5998655c679f43ecfbcd055ac48a81af2ba7d151d295eeb933caa58c9f508c9f86ed675ba20b5cc9e7352208f939a103ca2f164e658dd01fcca7524e5e963ec9ae2517be1f69ba3ccbe8df1f65e565197ff9552f1428b0ee1445f01177f28af03ca6f3434c120f04154990a0f91f1090e9a323f0bae498b91dca3f14eeca78f210d96303343ef4235037418a9f7fdd72cccfe850a6e4c47ca23e4eeb9b6cee1f83647781cce9277b4f41dc6b7793e2b27c4c8c186688da8d4ee1f81f44245a10577440406ed496edfb96ca23c636f75489334a81ea58c438270d60dc8b61b5fa2f0dc756fe9593e623bfcb8ccd5516c906f9672c51cd31cc452606ac662ac1fe2d65c18798f40895d1016b98bad17745099d8645c16016153c11673d1cc2d05d083b08061e66a5a25ca6c07bf782200aa82f36d6e282f4d6bb036938e819df0247060f27a08e80b0fb048c7aea39ef25874af96b7cca606731d2315ef4ffae78280016124b092bf0e00c6d94c98ffc9a9ee11b02bfa403c2a9896375a501464eefe342d519541cb33d807b0ac8036d5f6ccf85f09cd8f79ade7570b7bce9641edd35654c38c3cec3b67022c40152d6d00e8d340025f95bd64b0132ab2925c7929cc692b5fec458a2fdc3817b24876958cfcac8cd4d3afcf79de99652ae9719763e3c4ca6947711581a25062f8bab47dfc0b20c171db507f67df9a22f28ac5ef24552535891fe7fbea4ef15242b2c4ef31df3494dcd720c088bd2cca466198a44f03c2f4dcd9a782b3434cb044e5aaa0f7512ef3dd32d9537e098b55dd33c18de4f24f73f7af927bba3c7915e1fc93a38a5b9f9e993c1c9a17b257b86bf3077a547bdc40fc9474384b0b50d912523add5ecb54ab1fc1e48b7154a381f5203b700616d3a34796103d0c49eaa2864ec9e4b7203bb0a3a100bba733d18e1155619b09619ce756db14e6384d23c2b4764a401285b2cf1bfb32888a1077d0de9f047a9cad26f6fdda22c65b947c521f247367586ba46ce3a5c1ca6091c677e56a5e0b9af919179a6cf9366722dc779ad4458d5adf40f6f0671a3f78d54a2631a6abaa489f9603a82f4b31bf70738f1e64bace59ceae66640f46b6e3f25dc051177594cddb84063883d6c6e3ab2aa3e2f5bddb894a16b25c95970a630e6f2fe42b5c1f11901273876310693ca6e19ed77602a3842f1b2069c01bcb13b16ed80d0342bf3de0b05662dcd10da1f5092a38c5894639a0db6a0e62058b00c53abd56811f7cecf3927fbaac1804853a478ee0d1b52121110e52ab8f2ba79771c864de8a3526f5430ba4ee8decdb81d60bdea0181b56d91a6ffbbb4bf0442f1926b3e8e1e15e71005e8f1a20e27e35ea76cc162497604dfd9d0ed3b542ba8ead33dcd7b830e3ce1b12fd1f0353f1f45eea6d62a423502b9b364ffa6b92dc05bfd3ab1e0deaa79a2e42ecffc9d57647f1f3e01ff4a3a7499f8d863ec7a0593a0ea4d94efdfc5fbc38c996df201f174f0b32ff6e8af22446eb9c2002d4a7b30ac8c6c5d77052bba7ca078af639a39f8a470870e57bacdf51018363cff4233633e5490930d98ae9471750e915d0a456e7f60a3f6c646933333c5eec11aa345457c8517bbd13acadd4bc2773c03ec7652e80425c68e8ab97a357ee35312ed0474bdb5a1539cb22d8e10a87c70eefd8b9f26994e8b3a14fadf39450459e4ad2136e58c5bdd44a861db1d8892c10e1523774f8321dca50264f6fb5fc4578418546975e68332dc42d884e5965be52bc45272020dde40fa65a0f67add422dd70d25d3ed54a14c5618b7ad30beaeaf6d54b9cc6631ba176a3e7ae4c6d4f70a8e92f2b40493da63b7c37a98861d90f29a462a30f5e2c4a7ab9699b0d104b1aa8279e87831e51ee3bfafc1d3358cb9ea7e3694269954ec3e8705d42703d664722059c47c1bf837894ed15e247e23dd745e3d8397cb728204482bdb5c614de4692adef7110af2958dde7144e0d5fa696fed12354895d931765794e2e4c16eb89b5b2265444bd152914f62cea7c9330dcb37f9a0e32aa0a9ff651562924fee39bc24eef1e5189f7bf3efb3fa6ff27c0009890f2db33c298a22c0cf419e576a058afefc0a8fb3f9078cf344c58f8b063a683f833d2d2fbb057f0982b88a87d2b3155cc32223d1893dda8a207f46777e33bae1f58b6973325fb613fe57e8001bff08f219cdb20a9314de5bbea6225b1e781aaf796cef47c3e826c414ca71f0f85da08b7fdce7fcd7613823103f6a17f4a38a87e144163fd8aa5bfb6230ee684210bd70f3867ee4154505b74f00c62aba397d81e42bb492dbbe697de556dd1d33df7de63ad51e02ef888121854a850f93d9a222629591e19ffe309bdb1b9b9fd3eb25dc1df0e8491c19cd6ff40f2b2da332896c368eaaf581c83e8bffbe8416c86c6a6c34de30966865e927895d4b46b931f826cc11b94828737435dafa4f9558dd97b6fb0dbdeb7b71397c106de0b04edc022cf3dafde623e9f5481a6b7502697268fd49fbaa4fdce873991b553d36616614ad0a0ed37805522e4af6a952c397cb54294f4480fd3a06655c15d88f1f8c2612bc696f874a128f4ff25468d726ece0a80468e08a2bb16f9ec681365690b7461db8ffb4445adddfe973b19bad28fef28d812069e3c9a07c36698ac665c9a4f77c57fb7670f9279a8b6fb030739b53fadd4622d9323fe0254f06bb74c23982b0e2525db8b8d0a370cbb062570a2aa64c15210ba0bf5a19052dcb86ec6cd2936e927a013a45fb6914a3318c59041ef1d5ac6aa08b39c0d5bfb5cbc28ac0e7da844b0ccf03db957900f1952c60ccb413f53d801c15bec5d7678fc9f496bbf36cd20cd8068dba111307d93428b1ce410b3e2cdfdf5493d43a0b3a6881b0ee411a0b16e3a4e65350cdbbec972903ef25d18c8470b3b594044766593d887b211aebff1cfe9e2f022a56ec4fd6573a04938c9cc554569f3e8e8d391a8defc44bb3098a63dcc9595f43d73da9e0f41554fc9d7ddc23f1ca6bdfc60cd411ba7d8bc2c4ad05beb66e6eac530df71d59287b7ab247e52d74d27a61ce98a4aed40ade9eaafdc282a8e967e24043f299b5ef2705b5ca5c1b34707c75976d2b0a18b785b3388f8b6ca340a7d3d8a5f7ca1e40e7a370d48066eb8a0a36ec4fd854aabe6bdc8f7431bf22cf31fdc79192a4003ef0bf40c2c3f4bea46609293d7b0e3eb8065a5d3cef62c4dcf053f12c1a857e65bd9458605bbaf99a93b9d987accd003841a32cb60351735979967cfade3c2a8a69aea7e9a0788b2e779272ce4e359d2e5359086f79aa56417b722f375b3477af4d2fa2df811a15ca84e2a2bb0445a452e70df980a8746d658a442415ade9985ee34159d30fbe95817cd58b9b27c87a077b011e5e8b68602533556d20e4d9d057a46a697d79882911c99949fb1d659f521dc3263bcf4453dab3ff94c7d8b12bd81d17e22a144ddfa6b250d6efd11fc906b511fb5541083bff7c71929575ecd4d830a8eebf03a136ece40351c6b89c2ad14dd6413031c7ec8c5407604f4c3821b032b280914ee9be88a57ca953ba77e3c83884e912425ad2d8a15a73b8307a72e696634bfc6b74c8da6498bc9153e8aa15383694d045f325b0765c1ab48ee88558366e18d46010a3bfd5d7595f9944e2e0f39b2e02a2190069f3396bc04d66ea8ee1aa719047a175048150cc4ed6b8745d147f1b6dd266e896c5ea1e93b357087837864f3e88fdc98d4ece64b14a19736483e664f945cb0e38eaf0cb50af122620833064ff7fb307b6f06a494eb6056b4ab3ab84dd8698672deb25c390b0171d19ee6623e4f47b0a9e64b8e36fb3b1abc2210fdba6f3c94138f66720a85be5e025eeacfcb80d75eaa9918bbebd914f998b9c3ef581b465445cec8541b96ec4d9299156730a0bca221fb38421ad31a90bdee4b4a215fe8171f531900830a7209a245b3a6b8d02854410b06289263718fc6d08a492ee5b6a506985ed8138b7e00000c6f4b7ded35e6fcea4f614b8916161a588355a063061c242c0a5cac779cf927a3f88ded44efd55f142eb8be316649e3b7fdb029a23d638abb0f68358877423c6caed110e57a76a051c287f51b87000acad0344270991de63991ab3ade4738ecdf6bbf48eac914086397b7032f61f483d83f535ec19a4e4a5eb3bf6dcd1efc4ac50de291e9a8d2d3f99f6b812b855ef641ad9ac86a9ac6336929de869c9ca0b6e2bbccd1204dbcdbc8dfa470f4742d783a92513f4a0cfd22731ef3b0afd14fbf05b5329be949ee4e3fd5d76c59b5804127cc1ef2c7ddeba106b33858f2f62305dc5b75951c395f3bf0f1cd4d54251db70a39fc6b631065f70d83454f6b5517ea49055b491cb0ca561b16d0ad241057f02007426e8148d9d4669cc47f38e1948816e8457152d3b59a74b315772f5a11ae842ecd978b150c20f336f6226bf0367513ac98201ba2465b9e4745740f3e46a920a75cc052b69d0d41a42c46695c76210d748f57e889dd77c0706ccb7d629a946a12c7c21d560b273618333411114ac4e933bae43c063e86672463710b8b57b155f96b2a8fe0b7614e0f6cc8bc9d76a268328a94b5afdfd134d42c35e6e35c506cf7fecd518e311063c929cee93f701844925b80503fd58513058e7308ba981b98fe5e23ded26918d81137923b5dda76430e5eb6e7cbf53161a160770f28601873fc0c73dd7b843142ca56ea388d8673a8ce160f4908c60ef0b49d2489f225c84f3c208c0a8e719e201801c19205156fbcf6926a8d60cf69d1bd28f65f80893a0535b4023c25d713ce9be17e4c839505320c18c2835237fdb6cc5e124c766e659a17637c6dad1bac49ad6919c8b7a1318c687513f876386da7e77a99c001be4499642d9922ebd3a302cbaee4cf7f5a9bd322e5c5ac58ab0fd250d4ce4987bb213ab5c3e75f07fe0d540b6ebaa8b0f92bc6d84770def2ce2c1c905e4e545118fd15383b8c7ace311869db2e6d3ea488509ac157328547c8cd2e50c88fccc0340c00948899be0306ee576999e31c0607ce173cea4853fb765f444a0d753e47f63d7ea6be648c1bfcc60308abe7d862c68a1a90a87bec1b8b15ebe16128d346b6dfb03a1a7ba90477a3d81a3bf434a4790a5137e1c7ed64304d75e026467be2423121e955a87dfe82fedce59aa263baa83a1da5f83c2dcb51292e5fad1cf24a93472c58160964f139e3242db3f75ffe4eda4825c1bde6ebd7aa2b503bbaad18072ef1aee2932cb7c7d854b2f4499ecac1a921e40c8ffb8e6fff2450d2e3430eb9018f8c69f2dc707513cf522d5734d2acb91f150a9ea542e5daed3449809f8e76723154e3d0c76ee4a656d07df3bb452bfd872a270db53e5439706fb6ff2dd88c435bb113ca57f2ffe70d9fdcfdc41340ad89803bbaec959dfe9a32d8138f176793b6040cd4c54aea0a34525f18efc6523faa6b3ec7e4b39eb491441f6ca53e69613d3418002d92f9ece907b50f1a8e3fe1c77368d05887293770bc692b02640d9e6f36d47c00217f4d199fadf75066f2fac4bd3a836de016d9b669cbb31c41d05a5c8a00b9d69dd8d1c94ac1092b891b7aaaf62c2e7d22766841a3bebdf390fa669791f24559dedff72c32fcc9c97bb9b8b13445a2d4f76c6971daa55c2284c41851629b88fb113f138a6a5ff521b34a845eed5b2904e8f5ee2a2fffa07007ad637fa7519ca5a315b536c909aced28a720d6f2ad62ea4c7b48399d27a32a20bce288e8ea3228ce97967043e7e1e06295159ab85d7d805e01e86f312834bbdffa02a5ff2601a7b2459ea9f030eff49df6d3962580917863f2c89e32c66d68b940c424f894113aeebb6d3e857c71540ae5c9a0dd96c491c43295946ad467902f196103d54a33523529cbabb8b82c04a875546749a7a975320d0c201ee704dcb30e91890573fe6348a0d0f37f79badebef3cd1306fc4dbb7db1744aa045eceb66fa66bb2e171efacb4e1f0758fc77b6aadc819b1a7d94d389600384b3eb4946870b5f9680c28e6734d8111ab4dcab7e56511d375aec6001fa7dcea48c3236dbbb80836ab9b6b5b75f4ec4eebe3d2e8d64c5ead9e6c0e6d98c89f911de90ff118bb6e2039f0dbb55bc820fbf9b436071ae80ae64edf5d8cb85fdb7b7a0e21f02d24df941da8c5010b5a27db34681e704391d3b4d771d7ccb471a303a258955cf4cca0146459c903d21854a91373d06101419ee3b52976496710448db0ed5f4b557f670ed2cf5a763b790e18ee88a8e2aa86e03a07d564a394ca4d8c98bcb2f2c48b9903d9344c4432a9dca485a15277155bd38a0aa3dd34f3b5ec24580b8cea5c45b2469ab8ba6cfefe3e7e639082aec95ca0ecd616ab9774b83a099c0632b4fdc2a23210486dd1b6889c4825e3285e0672f88f93a3481ed4e0545b85fc4ca31a2c584a2b4b0fc27dafdc337ef604c5dccebf69acfd0763c6d1b26c665c0616dee4dee5d2d7b80cd332cf84586382824072d7c3a9a71cf02f3406b7f11cc2004822701108c4636aebf80d2f07e55b38331b4e496fc05eb00ae9370d33720da213a1dde48dc65c94eab29da2268a1eee83c5d6801fbf24152fec6033c4fc55bd14b56223d5c48da0e78559c6f6bb31bd2fed400bfd6da3311e96839a62a3527a9e1f616124751451bf8e77561693f0da1f0bd30dc005aadeec77d4070778f469ea4ba277d38c871a2b8312f4100bdc2dd7831bff46ad639741fb1eeb69bd2130c3a20afc0ea4867f04c80d112909834799749b25333a238a434fe1b9a947110d260bcbd01e80b69dfd408101180aa984e0a5f99f2f6e240e3e8584ab53766170d13100b7c95960d0cd37ba3c85cf48055414c57ff8f94df64caa0d624d36eac6d059f11ef76cff51755531ae9dc235fe0b3a55e3a852e73481159dfb1471ef6ea06f97cdbf859045ff4dd7a89c2014b4d4925b96179739f0724fcb445bc3296afdb13024f9eb54be0712671d94acbddd88a4d27850b90c1ac76a4c255a2aa611ca2d16c58a383f73f86c62b61ef2be35864f9bcaf1a08b9b89a7605b93e6edd011875e7ca6587ef6cd2305199a5c4030c6341e559ff7d4cc87a87085e69dc70c230ca46327e718189dcdee089f7f72581b61e314c3b376c3072d8e75de464420a86f7d64d8245916e3d71fa7b1021f1bb1815baf4f4ceb1eb87a8dc136f17a8130228f559f4637a94295e9d951f1e3ac48c1a9cdd9c26bd407b6ca7efb78206285b7b76eaf6518d2decee7d6895b3d28e6e2873a896b0bdb5b18aa822e68aa9d91f1f5a70c489d5e3b7dd6815adb6482a3e8861cfc9610c1569f967607e0b4685861e6cab162d4ccc78072c72fc86e6325a66168442461eb5dabe01979f07bfaf80db00b0109274506f0476588f7c150d3c6a377c2aff2e08a7b316efc89ddde2b8bbdf26ed0876f478fe224aaf9ff74e094834deb59bcd3bea1e64c7bffd439d85ba11a930c5d53843701821a772254eca30a85cd43052341e72d19c7ce1a6fb91ca23fd3001ab526c1b9c0ed518857d18bbc1e2caa0b0b3a35e6a7853ef283f2ae9a2572d1ceca57b3169313aab34cd6a8d920c2625458cac4d57df04e48bfc16f8b974e178909535e26b965ae2ca251c881a995c6fb6206cee30a49dfb6e91ef822780527430c5ade57c0572e37f43d6a86d6a62211061c1b27cfd824320963cea0bfdc0e6123ef780afe27f4c0b5a3472cae09a9d1bfd5855ca6c6b0e214f2a2dd0104b027b518356adfb12dbfda7772f26ce6f9c98f0e9d8ef19fa4ff34677a3d233c41c0fa424bfa7e34261c39156d7b7328100db7fd1f3242db62172e3371b2735ca7d4e67d2f3b98e04a0fd74b9fc3f555e3ccbd3d024bb482758fd9acf44c8d88bf73105031e162bdb9ef7c2f9c08ae7f771c32bd945a0550e17c00f8c66835e9d7970f9850eafd31107efc955143254bcc9a67ba36013176080185504228c705d0a4e6c7c8f2c1792c79163206efa5deab2ab97b2986c4d8248e0b1368ef585981b11045edb837d014d0110c64d9eb5d79cde7192ad70d86c1460063f80abbd69c944ec1ac1758e2bd239bc49429300054f4bb0368d0cb30213b36d14c4386892fe4d10f19d30e075074f12a507714a853bbadf4f633ee90dfe85fd7939185afc14ce7621cc87e178ac6b9622e61fc09d29554bb5186f23447d8a35e9d36f64b2a0390381677a4dabc577b6dfcd942772eec29d51e1ff351e4cb792a234694da0a8fa4804d0892f4ef24cfadcb93c767484cb52b912a7d4eb8417e19406fa99414cdb410836a53841fe26ef0fc68933af2a73170c7fed35108f01157df71dd1156ccaf6f7540613e8af39196dda838705d60f1ed1a1bd8ad7178cdfe6e9ddbafc2e61650aaec18fcec6193ef860ba31bc6af99761f5dcde3972e45ac3efb17952a1d7be1792b06dc11928f60b54d856538f41ddb6d57e24f53c19983b8518c97e321720cbacda5702f6cb194e83d0a5a3d2342d262767bb78535b96134196546d064c927bb91b50e7e708f01948ba39158744333d441b68cbcb14416788596ce5a2307638d3b4ee925298dfac9d96475727a8e26a7b950ca53242e88bef7dc34be4461c703953cc3c2fece071e8d8bd5a74ede4b271735394725c28f45a3671dfc136fbbd19b37e834663a272b8421fbfc15fbcef3d18a2cc8bb4e9d9e8cad0f9cc75450148377a698bb949a43fa5067270e6c3f55a5f79da08b0c4a9d0fe4445f82b37497837ead2dece261244d4535e765c6f9ba336fdecbd48c75966d0ebd207289dd62fbd4f0e531fa24bfc4791d8ed5174367a2e16a43840c6aad41e3b93e09691f9923283d1115a2b451efe8a527e8f89b1401dde5161eb0a87f676894ba5145f7bc8b2a2a08e69b940d3b9ddafa9659ff272874f1562a2619bd04f93fde11c9648779c592dea291be88ae8da90c6cba989d911d0ab05250118e56e56395f634c2e4d45bd78d936dbd70100252e56966554caa6e51021d605bd76edffd8f61fcd03606f2318f9a408d03a2605117e2591a326f317dff9872b30104391a0a4ad3f54cfa769f4974168cba0f82ba17041a8135633708a68b665e357e0ad0cd7b1caf45e84ab0f1736336d08a7808109210fc5ad9814c1796bd82db351a3e704b5f123fe9f8f9d30d5685d16f01ea9ad21ca79c214d0bccc97cd9556e2e8d94295bee1131524afcd01346b482f17e3be3be5a9d02c7d4dd9b9fbfd6edd86f65da6905c3f45425b8582ae89049297d46363b7f0a544f80f14905fb306bc7fee6ac69ae40e1b24d9811f9661cec821e7df5ef5110f88d312ac5339a50a1c4e35251d94e0befb8967fa2b906744b832845ece13c1f8e630e1c281789b60ef09e9c5fcdef4e543f042d3c058b5a066772b240b5d1506d45adb3e8293d7b247ef76b1372fcb1ae35a16e24884204d62882f78d7bff054301027a5c6bf0cede50987f0b8e7b1fd76fcf72a8055e76bc52bc814310eb2c9f999e1aedb3766178cb05e81ca38dec64576cc80228e00f1422688ae1e7f56c4f6718692f1d7309f99cb2215b997012bed94b2f08d6a9f4b47e77452d50f50557b6e63d4f524439d35f7a054332857595f77b1ef290b42d4c31c1d2d039c69592b8c671bf57275e5bd72fdb56129954bd5fffedbd64402d9cf0e23060656f70b0d0a31e8ffaed2aa6c2a1482662c8f46b11d682a1835811d0095f85b0f3d30bac7b6784c122056d0058ef4406852339d8141a44eb7a01e4b50240b0b16812758d7e2ebf621afd8508bf8f427f4deb467574e1e9faea1cfb38ad45f19932eea0d97cfe312ba4295a37efdd62152ac47677754d0fd71ca9f355274246f366a1e88cbca7970d74e65d9b7ab5c1aa2ee4e950486a4f71ef0f992546bd326236bd1ef11a692f364788936bbd5a039b8e11df8b082a80737d102d88a92b79a8a151c155a0ca04d2baecdc0102699bb10e6b6d978714ad7d07e092e3a5768598071c76e04e187e285c6fc08caf8563864e91b4cfc884e532966049efb50323ebc8984d8a1170f37ff312af579f545ead37cc8eef25a52796100ada781da94c7b4d5a0a8bfdc1d6f7d0abebf4af09c70a1f9e22c4953a05fcfde3b16e7394e2a0ceca462ced744272ebf47d16d6063e87f730a673312fe1f10412eeb2a74f33410c6302bb4c1b86c2ff362fec2ba113538167cef340bf120a35ca65f74bb98ccc92f6e60efaaadd78fd5ac41432769266e7d7591269e4da2aec889a4a51cfb69ed5f66dab4d38ce39d8b380f7d09d17aaf2d36f0b264225e733581848528bd415474cf066a03503ce3e72bdacd10bb94a5ca304b455c1f0317c3fdb9ef75d7857cc4797b1b37cb05a32d05b4a75bf579ff595025390933fba4df0c9c4e6f3e9aaa423a7233167d7d7037cdab0f6a872c4cca02e35669bb252485dc0fc066d5d13b038ea9a4eab91cc5cd1db21615d00ff7f742a6b8a0df1712a3a74eeb38da4dea4a9104f95f3fe8291e355ac9f4355d4426fa57ac340ec7860043d027ce62a152d54d94e5ed143590344f664f1c0dbdc7b9ad532c277d76fabd94ff85b7f5feecfc3ff9fbcc84c294b073903ed3d098c2cdff1b0f2ee17f474af20bbca5084ddfe2301f0b7152df30e6ed3d7f2bd1c49bb320050c40f7c4edf9666fa385b458bf0a6a55b34d45f03fef9f72c2dfba39890428084c51a675c2507dbd760ac82d69119bda9fb7a35d321ee3bf12c589ec01ed324e05f8fb22f0271660972e363313a355f469b380e495de7dd510fc099ad40ebb169dc1a2112be88a0693cf86dbf47e9b81d2444dd845ebcd236e35e9833c08ea364c4c96456e44108264cba85fed342afc882eec2a273e9b83c65c97a8bba1f51ee2f4aef6f07a96c79933ca373ad08592b8f3f8fae7dc427b363bd8974e287cfc41c8aa62f666bb993d92da350fc1a0284524364fec375f98b9a757959ec0934a34bcedac2181d2ce390f79635b6fe0d3a2f65e471f65e1a99a702a5572b3ed3bb71cccea078c5aa020ca489d505e833c853dd155989f9dbd5619f621c579412d7641ebee51c2c548886a8a9ad18a9b4d4eb102e780effe4f8c28ee094a08a60fe4b35be16eb9c17dddfa30c24e98124429bdc06a4ed71919ffecdec856cba0ab2130739d9ae3267be008f4189a38a1d5370496e39c27d8ba01e975b55e9cc7518654c1867193d074a24b9416df456504780acafaf9a033ead10aa18bbc673d4a562199d32c08f0932fec0c81b941d8dbca840abe1babc68698ca2456953b45abbf823aa18a85a35e66eb7307c9cd4f29c29c4ca55f7f9588a885b963415adb22d0f033fb980398171b15afd2c52a8aab933c2805e32837eef01dba94012a18901e9ab0bdcca10eec7da348bd220fdafd8f35ff27f4a41deb57d04cf8b7fc12b4492f401b96724808ac44f263c40bdd650e945862a2ee90f556bfdfc540c4d43e49581460b48ec146ee9676156feda2a23390a03ec5afc990409e48bde24d00e1167e04f8a2c204211599d378c41cf0dcab8364ea75885520ab190cff3b324c7deaf16b367c17862338a1a4955f87da0a1b5da4ec1cb545d060458dd60fce281012f13e719dbc4dac4ca7f052881123ad6d4136d22e2a4225d85bb8333e9d1d124eb6b15870f57f63664961bb2ec86cc7967940f8c92d04191f2f9ea3ec4f963038bb4c36245e089815874517aa53cb20c050d6cbe57380a65d74b3ed83778602f3e53190c7b21819cb1f2168aaf869a5c57a997d9d7cb2b4df98b2cdba73d1d7742bcecb5beb234b00b6a79415ac596378e61a5953c801c87f467669b355b31bd347aadd7f4f1984ddf9d1de95bab69f2393dc4526db9d8feb911a9dfa805b462cdd825a8eb15864bed323e516fa2581880094463fca5e5f43467cbf4102874c0f228bcd3009dd05c77860c34767e7b038b35034bd705967ea781efa816e9aa97c7e93b4bc933ae9d418ceae0cf2cf42e9ca82b4a8b87045d11dd2c244d9eac00ad4897b9b83cbffaf46f91ee00092e0e6cc7cb533ff384374e05609e9192176f7665f938007fefa9750ecc4ec186d6fbb355a974dda7d9d97d1e9d7ae666b5020951f2d56f9885b9cdffb2f1b59d39743aca9ca6cf1988369e5aa6a0f065b1b7b9a1a81e4f0b77c88a87d709f94af9f15ee23b1c25a28cfc944f4b3dbab1f336883d86380bceef246126f0228e6ea8aa1be83992b91d59e2188a3c0ff1ea6a68b0b12480bd52720e6f2e681cae1ad9b98fcd03eb5d2eeac5888d50a71aee9f0387e09b1467ac24b69ff0364f3ee7e531d0f846cf37a4e36d98e1a7b608feaadce873cb6ef24852cb88043934c3bcf28c6488edee100de2c38af1f8b795f207a57fc5be0f8f81bb0326b8c3f738bed181126f103f20dc8c0f4a7a796fe89858e1da184e7676a2a38f639eddfb9b628e8cca1eb313b10946cd78b4c102aeef53e503119cd142093924846a51e32adf82e51019d4b27598c28b9fad71e743d7d2356dc984a544a7e32a79f4664a7a367933fcc25e818369f672734d7083dc68c3ce667afc8f179fc3876d49948142ce28a279a32a48241ee59ef957c14ddb92d327130f14c315945690c21021db1b571411cd8ae6ae61b042c046020301e89080f673ee0eaf721152d4386ec1de5f08ff8893f0b6bf3a665050703231bbbb9e516f057b56040e1e68e139d38c7c00321b648ee97ea8cd62c2263cef0f4da533140f399631fe3b8b081252414d8a7af9ee09989d1845f4c719c0f031a18f96ec086c1b0383b143e7336a910ca8183b112cca18f2f0e35da8d8382f89ef22a47070cf204c7a981b4288f697d4be99e7e6658652ea6ce4d0f91b2827e0ef18fa6531fb66ed5991218f0fae7fc27967abef1868c4aba354227d4cd408b1fa01921f6650983ea133ebe354c19e694450ae93f9b2ca7297bb4e736d8fc3b50868eaef9bd86ee2ef58ccee62917978b3d4d00dda33a215dfba9328c029b31f5f4e8df522ad3cc211e7e0a988c803ffbc812ea5f0173a2a4f907742e408498191b5a6c767cb377870df4755281d5a3ff99ecac9841baf88b09b45ed6ce5c976e4ef7c7f56c162b9098620b922a20c464d1cbe20d34e637f8624deb2269184e9bcd345b88c40dfa5918a5e4798206cb82739e0b1c4e9cb4106039e3b1017129288eb15a09aa50cc0375c12e31fe941cb6918121a2a1fa188ee45caa997066e256c02c333b3edaaac90b8199ce11c06dc62f18a3a51042957146f2cdeb179c8171f73f41a2694d6e65a79c41a2333e3686486137b1906099395164c3d845c06a30d2d3ea12eff1a6da440f7dd34ff895753bccf3130122cfd22873a4daeeb90732cb568ef8771f321d1c6086049765efe875f10bb7839d43b7dc974a4e3ea6b063d171a9128e4e983633dd20f04e2cd64584654b45e938d7ea7f08e527e2bf0f0a5b462db45d89adb7fc61c553ace880d2ca49fd869164402117ac28dc87c5868bab71fc203b84f8210798e72de57ea7de9585ee7f910f4e9ad053bde203cf43640496f3c73443fe4a8915d2196053ac175500e940f8e8dd487e84b5bd9e107b8ab4ad30ef8d69632cdf039e433032622b0c835fefafa45d4f0c41b2233e474107d20b50485da81339fbd20911d59cc7d9dd4bc2e0b47f3b1b3ad42374c0ad08d40626c076a1ab66491377d3627a17b984ac04d13aeab1bd4e43040060903d391c4fef60a458438d7c2fe63ae70b38fb8840c2329f2fa43aa03e562df0e1629abe281f63cc7c2d8a5ac7b075a3c2f162aeb086d9e54b0c5ef6134a5b4db468dc77fc1103a92570c44e648ed4131cc630c4f03e4b2f9b7511420cb4c00a0689964a070dfde5cf9a82357cd17fd6f574e4a26db6d8d8a78142fd45b5575a21447925d7a6256415202a0ccec04bac5a174a843b202522cbaf25dd125310a691bf6c04f83ae6c306b34e697b8337761eb6eff4347c62e9d035e1aa30be9b033ba311bf85cb1494fb70c6f23fe780f72db9c6c8b4f8c8093c516fb6ccb982db2eef75239e5579868dd55643c2ebe773d84b4c3b53feecd86b8ae70ed562cd9e7b4339fda497f2dd35cc8c30014654864a1f5c7568bb31f1c20ed38c947d63a1b34706d01dca23543b96eecd5038aec014d893afdb0179a73e5d7ce0287213013b71d6a2b2d3d3329482c9903bfb397f17d6b511895c0311840c6a055b445ea38c1154184fc64d8596a1db590d56b5b888fb9ddff83c083977a57560821c66414ec6de11f15a98a0b3d853df49d1c8a56026226e7e1e9bb3c3b716dfb864773c06cbd39c5009d5abaf5509955651b9f246d50f64f422887de398f92aa79f5428d4be9006bca81856210b7781ae9bc5ac9cf2de3a22b4197e57a2fe3619569283b606b446cf0422d314058f148917e9dad43265a326e590a0451a8a35dd9443269d858a0666f34150da644c64d8e4745211d013009fe4f04dfecfd7447e695f12454ef5b7c9f3350ff8ed0761ad73cb4871e2d22e6e749ceedd5321ce6012cb316ebaa05c9dbf9d5234a75315ed5df280c1ca916e121cdc236871361097716fa3b35a660fd5729bedbd139ce34db8ab29c177fc656fcff5af6d21c7c4995cbe4e99c75a567332bd842c339971b63faca21959943f7d2ce2e374286bb8d06a5582151850c71fcb441b50bbd256f34a23fa2283909e6f34559605293d39015f52c82df23ed39f8c37e6c15c94554f3a5e7d4c593e806aea1ebbcdd266584dd9148645c521261dd70a108b051d936a9207bb082cad684bcf30d9f36355c13169c3c38a279e2e257dce65d7f8c60ea11daedbbec5ef894adf4044260f15a2a9e4a725805d866121f171f384e666ac0169d0e0d5afa616e58f48c693263559aabfe6ab7dcd9632b481c40770b702346b6148b74b6324cad32b362398b7dafbdbc8633364186bdc20d0881ad338f73b1644a663a7f3c290a1f93f7e0adfeaa1ffb3efcc3c20006b3a4b31cd1f5c3c01db6d2ad1f418e6e78a400cc1e7b2cca06f8a391b1dd1d9bd35de692a06888d1dfab601c37808991d79a6cc5e87bf936bfc090865ec7afd4dd335e745523f8803abb9623d54a3a666d00d9b0353910b30f8afcb836ff7c5ec5247425984460b62f64caa234755d85970bed17782fc7c089a19a544a880b1eebc14c363ee50a9114844eb83cbc19fa662c39d58ef1bd82f1ac7ec5b29feaa1ccd3fcf197647048c8c9791f38d39c58d454cd7b694fe84eb67c3357336af946ea23b48f154c5512c21b227e63bcfeaaa04ae87e6027a380a5b706a22cf853a51cee12fe72e7ca7ec50de09676fd36926998d16d33f539dc1fb59e43a824411497b2ceecd1aef0615a597ccf57709ed27e7ae885e49a9ae992c9b5aa05165db4b1315bb997b4906519bddf1c8976ecfa6af7c9b7895272c2c0972203eb4d96247568634aaa85fa93e304e375341dad0e19d94eba0e1774f4095f3fd82a187049ed8a52ab1ad9422dbf3d9b6a70ff0dc527b19dce49b7ec49a0b0ccdee5d529a4062de19ee1bbd980e6adf3122d599344ee2371b4d7f15435a527b09d4ea3a1f8ac5d5b2df9a01390486a5df421a7405f806e4de1de8f46cc9e137a1b0b7c83ac53e4205ce2e7206cc2bdf39b2164c3734dadcbf2b669fc5b15bdcf4ddba31871963fe457857ddbb8ff884d7b0399ef0c604df356decc4cd68717bc29fb78fc66a11b367c1efdbca11f4bae259a1da674f5be6580650ed7b5455aa49f3ff325f9b370acd31bd359165fdbeaa13f31a64340ae631efcad27eda700bb479aada4654d2a88d7884547ed4fdb5849e2e5974fd7a768d6a740140efb3b52115675ed730c5f8110a6ddb6b884370eff78261cf9ff8ea048b47e2765d21126777f38f549c67b10e06cd870b4475aa9394c50913435a7bbde803d26413ba908cec5550b3f0e1d341e7bc88c15eb715925e66b3840b8d2dfa65045699c60b7c4265fcfe59e7868e6958174d90177620f6e7429744d95f4310320332dde683bc5576d9917c72a4441db07827895c9a80f83b5c9bcdddf1529cad3d7b6d385da6ced6ca54c41058c45fd624ca45acea8d4e8d397a9a743ec6b38943659431c2204d7d180684136a4a3d61b446400d9de162ad632f6cd01b48ee56e0e3b8043fc1a37f38115268ec2e3712c7a263e27853b6bcf28006b4b2f05d8e945242de1f9ac69dc96b5ecb6a9b6cce2cb9e61f4647f9065079f8eeb26b1842f4f26ff31aec8c9d601e2f3d42346b2e39ea550ac438a2292fc4b852f1ae43c67b25e30f101f8baf9b6004e0604e3dd88f067c0fc3f2f39d960f1f20ed173674409b6597102a9f6e14363f963d7ba694e21e574b397d501c89d7cdc1f17017300a9605e662759916c8c513243f786bdc6c5204578db07ca09f7a6e7ddb5418a5838a4d07a3f3b98d9a127cb75865edced017030ccf23633533455c63ca68b6dc2b046797c117199f4e8bcb78bf24c970e1d95f25bb29436478e14b1d6f353603f5a1c09302dc040ec7051fd5d2b67b6cd6a2ce3404f7c8cbb61b1a4a4fb27722638ac0de2f52f20839cd40b3de6c194cfda7bd0927c9e03beaf13d8912f0ebd7323831102f814646ae0df83f72b5f92ca8b0a7d021975bba41e1a6d6aed817e976c5c7f1409fff3f569fd91be85c415e1233be46844f648ade9e60a445b7c6d9819d9272ba4547a88299e87fc0ca23f61050bfabc553cab042091b71d813459328534bdea20cf55de19499be78a1febd20ca5220d90ba80724205c2c79ed0648b31e4cb357f3083fa2d40baba705261d07e24f0bd49c01862379b867cab68c5e68189aca39acaa01de8a864375e2b4d643b1dd73f92a55d94232e36b7525cd921f989896137314a742c402658590ca1f0a0e8233745b5e90ce628aa07c5a839a1ea6cf5dcc0191129022a06384e9852b5d289094baad6e35af4bc7a79237e26b34095e11491c9dae86468baaeb2026433efa38bb1f884db536bfb337e3fb9c42bbf53653fd3fabb9a3a1192f0ddfb08c1dc13283062428c3a3acd7921d1bfe0b6f3680bbd727feea3a06b1d00fbfd81df8670de150805510ccee254adaddb9eeec820375158e95d349fcdb57d77e37e4bf8f220cc7789e8532f33a24195e72af28cb4dfcdc7f96ae906317410faa957a77335271f67a11f06c64853ae19f0eeffd284e11a3f514a12ba681028b22825913816cdf8eb59b488ef06bcb118444a79a668ec6d396171eb9ef03adc121b9cd3436c92c4334e4d811fa59e2882eee1264f48c86a20db05fe693b61a38a0f410cef60bee734978f2bf38972c021f04e14b240ac9fde60399aa406a1245f39b5ebdf993fb3bb137f2c3941327e7b91b54d9ed6b1c59c95eb0d8dbb473b1442af4afa8689b7c958dc4579ecb2cf36253635fac682f28801f37312373147c8e7779b52d9f63bbb70ba58372cbe43411137285a3e783f150ed9b68ad4ecca9123cdb5c1e59551637ef484616d76ddc85151c5a912a0bbfe7e7c98e98b0293f86c5b4709fd1db455d6afd9aaf89c8b1fee09ccfea4daa25df9816a3a06ce1f80a24bfd1eb9f039112771467575622a342819afa2460a1b0d6f80d6ec42ca711d76cefea5fedef7727f85ccc09486a58b542f52e823ac2f34922bcb3135cae97bf69cda06853935ad638d55046894c0dad57c8f44807ea144a074e2fea4a0b8c8cc2dd3ebaf9f4fb863c1de4cb0dd7203adfab18cda6e65c0da14d9b9d0e1b0e6b7e483c19aae9ebdc9caced6937cebd1e2e512479c062a11acf774e7bb8a379535eb9505f4b5e16e2ada1ce92a2e8927067448e958180bc76652dcd4975ed48bb37d425d0811d8f41b25fa6ea00c45dddd20db14b7cf3c0d10b38a6ffcfa429bde32419a6bb69fbcb70fe5f800ed529241314479b428dd0549fafdf3a55ddce521ec03939955a18cb8cda2f3550b4f3d9b53d8e8a9c22150335973beb48fd8d26a367290cabee0094be097d3410a44fb28c9a21b164bad8ebfc8045bd09eec244d3ca8e49cf60f0d8a9e8d05811d07b2cffd7533e5e0e8f2c4631802dd9cdcee2736a142c7198337cb6e919eaf5b8337efc1449a1266d3369992436fb8ab8225c76594dd5e5ebdb0b5962bd9ef4f9e3718ecc1cdeb9f53b494b5497188efd2aadd2dd8fb192bc5bf14b1de22dc4341ad54312fb0eed0f902fce205d55055fefa45cdff123d7e2bade04c8853db7f4195c8c10804eb691d704b96dc6cb93259a23ae23e1c5f1a76ae9fa9de69996040c94646b9c9579f414b935d84d6bc0f70ff037780dbf987c23faa0535b898b4642d5145ae1b472ed5b9f57ed04ad3bdbceb2665a8a3fe6bd527d34913685aa5640361f52e00364de62be7c500b1adcaa92310b880306f5c376d7ae82f1b050342f28a2b54e28e491142604a43c98ab360ff070e6f457e51a37de4537e097b0e3ea2ac501a63f8cf97f3d6db198f673c10e29d21c688c2898b4488903c6f5ac3c4737b1d5004d137a86bb15c0fcd090ba5e42219d026f8d8f2848d31d0f90dac423cb75ba7ecd3700d6065c7b81d237c277d8062459df83d1eab50ba865b15c117983f8e9c40212d6de1e76b189b0ee108691d763d20229c0051247c30dddbdb3a14e4d69e09f914384fd5550b55de90a502db8f81df3d0bf33e8148e0a265373f93b1af792de3b69363f11912d170b07665bc849aba574dafeaed60a471255597ea544f6d5172aa43d3333d9f1bb68f9d8eedad3b741a2bd21f0ce6ab06e6c947b91a090b85c764231a898e7c315a9e1768b9eca83827b92aae43a771b7d1d66c8e844d36540d67adb50e19a89c9184ce7c7ecf955e7caf1f454d75044957d54d498daeeb0dcaa3ab0a5e6f103f6027b0c8e21e30b7279f06c19cc071b98746b8d2c0e149461372b430b0d3286262156154ed6916f0c8a4820dc8562399e971d4a12e89690dab4c8d28b30be170f9c8a534cd91d4277492fa45996083b9333e9078508c3ccb690c3fd423d7fe2bf594c8489e44fc929831bc199a219406885ed5f00b362aa15cc7604a17a38e85dc3dfd092c68038516f208fc452fb4fa88c9176d2af8557dd242c7682faa8da1e730168afdfcce77760de5780615726b025590d92da3051193d013699a5203571153e4be4ef16717c6367b61fba8014a301210526258d14ed6b73d60a365c5338bc60486c92a44ce103f55260c9896a069dcbfeb0e3834e41e494cc4870481e025d732e05faf0936884af1e69632bc16adc7ab70a7f955f7f82adccdf3e84e4249cb3559a1ea8dab4f732a3ead954279720de66a152dd7e6ac718381f84c28b42e64625a040b6de681fa543084d732d64a774653e33588cc9c8e92788725bc928bf4a90d122c4fda2046def513f6aed96d24c363b31deeaa2cd0bbc2167315301aea8a320778ac59a6a9a866a0638f6b2c8192d2d19a5d957bf8cf51036553ac474634416e14bd66324d9e6db380c7b057ba5813acc65b48ce8abcbff74ad0e233938cfcab854af10e0873a8710a5924ba4bcd07b5f1b90a7f8608608215062251e48cdd1f3eddcbb7280ee1bbb873418a12688109dd342dca4a07739e5999988e8883d13f5fc8d3b1dd2203092a449ba500cb1e25a554558d81b0393fc46d260452ee645fdd18eb3c7b0c68dbb87034c38feb61d85b762e9f87362208afec3748291114f64d3fe7a06b7608a0668c95249a704ce32d88c3886c76b025e4e3b11aafc2c40fabe81eeaa142cbfc79506bf292848d26c5e3b8c034e9af8980fe60761cba49c8d53c8c5f3d691a35178c40929a58c0d32889ad674f36d3234154e44f33907290c90e67076c4e8ca7e7dd1250c9e2e1eb010840bd276c6ee25e3da6eae7d8e1910a4ac7a42841ac1545b3d5c144488e3277f99fc201f129bd3aae73bd3c85c32a327f013e3b6ce40ade0819eb831147800b5745047a04b2cb07ea5e461e95d7dae88c499aed0488a1e563fab5da784f92fb4751da51349df5320a9b459125efa30e5ebe0efa55e7152583ab3dfee44685da5a8cc04cb91cb817cf3ee65e22762dbb152cf4dac949c56d4857616d74877b790f203f576995f85e31eb8c94910113758fb0bf671002fff176e06c4a3e2a58bcadb903932b727ab31e3482a386a774d6af6b778b552e07c6d9660d3b416e1c9134f9441b6e1b43a30ccf40a611b868808bb9c5447720081ed9a43df1485b5182e9071175e05cd65352936e2eb53ed2267e83b7e964d6eabeeec399c6432f30104b1e09bfee48ca514cb383164318ef063c8b881b35921c0135a310ca4f22284b9d0aeae16b1c9ee16094eb5e5e827442296f7c533e65235b1e511b31dda7646a4fd2cc1d1b67aa716c32bd896979f4d1fac53426d34d45a756ca25c1b518fda847a511fc3c9ecb3a9b42e2eadacc210eb8599e19f4f7b71e05d21e576a73ab0fdb4b829ea4a3853ccbcaa897b277cb0bca209963dd77517e430be48aaf020228cbc70d6c42e926bc850bd313ba0f424619ec67d990cb5442a7a206aabad19580e64ae12a219e0ca366872c991e41b408d628ef858c208d6796989061538f736ea05dd600ef095cb8007e170176a6e3edb78b7df27f077cfaf778e219d27712610e2151542d873817cf377b25d266fd765de3b05891f83808c194bad871ff5d45514c4fa0db8cc5d87d5c6402e4c2c163e2709475783a8056e3182549847f899c41c6ff5f3d442a536488b12f76e84bfcd1ec95405c08a73c7183189d17a1f125915473b3a9998480d7256d0298de110854bdc8a498258f9a03fba0c802ca2ba1e8e3501c871c4a4a950314006d923ab12a39c5178bc049f02283dd1035382e900d8adc81581cfbe1b4dfb75853c010a30c3257eae070c0979180961061806d0918cf31643ec2d77a29679caaef3ea9854ea33fd34426e8abde615240e4cc01a3e8d4800837f290f31def003304643b8642447915c5a66adc13263b727f2a8b82eb516d0a4f4d16cc305648d9cdaba7e3a5a1d3e9a96e5bad58275cd3bf81d1f91f8c35bc1813e8a94531dfb3aef671bc5624212697c1d25ead2da6e586968fcbf5b9d7fb3337a9cee9400a5732ab2e353e42438e4a44e818b7c48891aad87199c76e57b38213e1739a0d46ee5987504810d96eb5a42a589e717cf832e2a675aa776471aa3e4d6625c12affdb37eeb0711babcceef5a72e38f4848e6b650e7eb20dbe6197bd18eb2def3e16d0ceeb0bdca7cefe194f6884e907172b2f1eac18ac62970b06f62d56a2e169cf025c13ca1c27dbbd109cb2f0862b9394a981ea112c46d054a8ac48587dd59b92c145da9d122203ee412871598332254ce4300794d219981f13db341aef8c36167da1fb862583088ed70d89e03c38e4e65fb44ebd12046ba4e5df539b5c887801f22c47e611b477d61c55b2ddd94557ec9fc865137c2b0fa1959d6e2ad0cfe4213932858a6cc4941509f2f20193f7a940768f59e400f4231657471762e4217a1253a47bb7ba45e0859c082553995305ea5937d36047e1040e5be54c21c578315b553fb39729932c57ec87abb44a538dd2e9a14229a96f0c866eba8a520e0c84ed6cfa1e57e8f81a8db4a70b4bdaa495dfa1c976e8b5c92f2e59ed30d0bcf266809abc7857e795951c06d80deec776d4067d1553fbb6a4c696e46ef9b54b54bde4e9bf90bb68a952c89d99cc7cfcb00b050be0c9a476993c2c49e4ae5a54505ac4c3104e6fb995cdaa591658c4ce02b5921d121247224a14591598328279848a05daefc1a5290e0741df15efeca455b86bd5e615f233006b94086960c088b3c70bd6f972c89f3bc2e79fb93368a3e7579bb074880d0b51cba2a4658cf83c6a6fdd6d3fd54974297738b2d58be18c9e120174661d656a45fc2ef974def5c93a7b2db5e24481fb46771bdb1b8c1e1d858b84bbd984ac13cab19dd8846c14c643a83721093c112dacbaf87a74ab723909423cbff584dc07fbad16f981dd60d81178bd76d23566bbf766e77518cdd350a0199ebb6bc32dfc695e379843f0dd301d3d046e35a51fd7ed9ba4fe1e9b9bb5689899ebff137120af01a2d1dc68e08bf4e179c9418883ab82112a553cd506e339a1b48782c8891071796755dc713eea0c20a3855a69a2cd55aeb93ef5d442b139f8e69dd1f2dc78a4ceee2b0c9cf0df3ae1e9bb61ec21ffaa567fcb8d50dc174e343eb0ca3718312bf16888edd414a3ddb1d644087ed395d10767031ed792e0cd591a55028828a257d4abc7656ca2fe3ea0dc6ac609176ceb92fd629c28ee0179723ab8d174c821cda48a91a6c317e178626e53f16fb20b2742b8dd73800df074756eadda83af3009abcc19eff36b80488a527ae8bf5719a12c3b0bd4e5a98b5dfc04ccc31c23df32888ec1fc197d26f2e484c5519114dee59529425b481906e0cf3239858a986c0d9e93cbf28773a4e1f133444ca12b9b934ba6515239551f4dca89652285c2993d0f4360547b30f20e64548a4ebf2ca44dc0b481faeb59ea5a6111907b4ed2d1fe84148189c8b1a8d84a4cee667e06b1e2d2ff677de30e70923ef554f175e9011a373be6e99d8a8299c13db923e3f2f234d8477eacd8ac47a9c56b97478431c0f7993065177a1a1522cfb1c88c1e47b9a0d8b4eea8b9a75d35432957c5fc4f9a5b15d6b68d0af483c50d3e97809f782f9bdfc025c575ad7759546656dd39357d050de280852c6a4d3f57e037866f9838ae595f637d4bb5fed90a38fee1c4fc12baf6db24e83f6b11756a203904db334b6df046451ff267de3bf2138b61bdc5269b538a7e9895e59411a84bf147ae9e98cfd0cd221f1c40e9fa7383372a6f3ca5f88d43eba34290879dc7a9f69cfe3cc2459b819b61c627243bf58aa5c6a7267ac78cf042f46853d9b06c963057574fc01a8db60a3dd886596705cd280d543274e3b8f8e96623c1ac5c866ee533667f6497c312ad9ea725ab6f53478579fd871235a96181e1193637de84e80dbfc105e7572cee58b0188d7f1f6ef51f24e8dbcacc0232833af1324339273ae3eec10f8b0cde8cdeffc02c572ec49010786319d463ef2513f320146103ba3b82745c308eba9a0ea58266fa7dc08955740b5c605360b57c5f66d484a679b773ec9080c49501be08c87ebe00cd3cc310ec0ae14caa4340134e3a5eef9b4c21c36e17e94fcf1adce9e476981795bd72a191e668c416d2f6eeb6e59652a62465070740072e07dc0bd93a300572e1e675c7820a9d5bdeadd42b485ba43cdd82ee47b89784eea7d7fdf723755048f7938988119095cc0947cf74aae15538971cd6420eeb7b2794d3ef9813d40cf8a98b8a5cd9d6a71df5baec791c28a43eed7674617361f251c3c6b2a4c54e9a2e29b0ea59df48848afc5bb693c3dac9c9a9072ff221284f5072e64bba27a8b09d5af4204a1d095585448c88a8fed5bd9cadbe71f8ea42229a9733ecb416815aac34208f1f0e7b5195eaf10761fd2afc593deb71c8fa9fd56af5abb0c8ccaf1e874054cf0a8918adc21f11bf2a0c419553b0e3708ad11ef49d195d56a864e2985505c6de6254ff2510cb8d64b26e92a6d3ac67b319d5e32d79227dface5c25c03b64c6913bf325173c36d2152cc1489f1476c8dc60e44e3f09f43da99346bb81bda5b33ff6960fec2d43e099bd1f7b4be88386df8e077c3b663e410acc7ad58f8dd43497a8dd36afbf11bc67f2d175a9cf7e273bcff3b13d15f2fd043b157a4beef7b8e46e2cb9bf91c03413ad7f0a5d216f2473cea80b55d4471794b885d39e9528da09a8ad74522389c136a42e22f0d8484923914ab57aeba386af1f8d444b809b16cea816bbdffe8065142bc98f51921f230f4722d60799628c688236fb2912b29e1516f99945b4223faa67fdcccf204da4a22b27122ba4edc17cfcab1f659415385ce118831d366b4d4b93c98fbcc621817d24d67e8eb65a92a4cff6d652912d14965a1acea4a31a064f30004699fd14c8811df772468374cf853f463ff73b4ecefc7e2a1cef0d2507ba30806176286228b8be9cd95a6e6ad16e16c98643e05196152061f6adb5d6edbfdc9398f80226db2ddb9f5062748fcd91fdb9c5beb4d6328151629dca23fb938afd293f13e48e0d9f6a9db485912dd26802bfe8b3dec88c035fd47bfa9ef7ac9008ebbdf0e7fbd41399f93ef53faa13f2ffb4de7b16f8d33debbb1939e03a0626a2f91fef67be051a01e99ef53cbc87267cf92b9933a3d77d2034effdf673d6fe3fadeffe8608f09ee681784ff3fe3f461e02e9bef53fded3fc8fd116026985f77f68ae7d1a5ab017befc573ff3ddccea675e4030eba9ea59e05773813a2ad44c1fc7182c6746f4f3fee52110eebdd4e3f881c493c91cd61cf8833a288158f6a7e028ba9864b2679e91ad2b145d4b29e58b0a9e7276695a7eb100a7e020a5e38c1aea9e9f4535e35c629ab59e13706ebeca27305db8508a23539dce01ff7ff53466cc7819353443381c314e38ba38d77fe128aac21a8e327f854953fa1196118eef5f138e622b1c63b5a69921d6100e41f07e27794f083812e64f461613bb7c275d1b7a0e0040d9b4ec34da2686aebb4d7bb282c060b87bf794ee02edee6edadd9476373872b9a7cf321f8539d9d32d09dc6b4b8f05842be12f5dadeeb59dbadcab7d4aeb04ed579a6f485d2d23309db2c55a3f2d787e8e9672a72f0d3fe70d2cc051eb53aef56f0872ad4a3674c9f5ab7cc09b7190476f8a1a92100293e96fb8a3a8354a84926ca5b243aade106292e9d35aab8e1836685143982a5c706156eb0fb9d62f5799ab0cb629d36f117ed46a24268628a2706109125866b516e54ac549ae55860f4383951c198431e7c40cb6e97aa93db208da9466004388f67042b24c5a70a62a044393a002212a65c9dcbe6cf9c2a54eab4403112f6c36c460c06022d7748928c05e9659b278829100e36499258ba83c62f10ba727b4e5cab20516368f3fa5dca19fa3ed14789c436456b42642f6bceabb4f2993974c2514322d273c00859fe0cca950f6e7a3e33ef5db4b0fb73c9ceaa1bba2543887b660224666aa4fed806b1e9f0b7fa8c2c0e31ca20d557082a13a4818ad4d010593964c8fc8f4471911f4e7049a4095fe03ba47cab7639280c9c2e9697ecef5ad222929bb97dd6f985ce9095276e9495b949e38653adbc79c20384cf2a0603b09da4cbe6829207bf27c7f14b05fcfc969d1715accd101d71f71b2879fd3a23f8665ff6d0478944e3eba7e8c752e830a5dfea20c4a64f7d9b783c69716dbdb3e2549292500b2a5d6565ba96f1b121dc8a38b07198490ed1e065078c4221358059afb45e802dcefcfe19fe2c8602f13ebedaf17bba1a45f0fbad1c740fba04438ff948729d057e1e62977eaf75824fbb70d652cf4b721d1fd5a6b7783a0088f3733d92a53a6d054c184a60a2636d890840d33ccf032a74ed1841f1434814e2174ce06cc16a5218ec5feb5041e63fff37380346cfe30014ea5607c4808f12121440baa0d50903aca1160a2d86dabb556bbd99e5270dd68583efd1b06aee1ab7fe60e63e10d392738f64474cace19043583dc45e089007beae7e7108147093f80cc94edbad40c21070f1083ad0dc4116d282be18710f865503850ae6c99504a41c19f9b5639a7a4f425f09dcb90c8becde958770cbb2b05430d47fc426db7dd22d28be12f29ed6ed99422e1eea8975d38b4c56e2a84a951151b266fc3e4cbbe9b531a7ad98244f75e4b3d69690949949f63ca29a7cc3165eb88f6e30d30bfeed4dda5b4a981c17db395baa49c51c3454e96b5c67a6d6d12d34b73299de15adea52cdcd195a7faa8089f8a8ae0addcdd6ba5b5d64a3b9c929293f24ab939b53555069d73f21081ce10bd6d72a6f794524a29a5f2f502e1480d1b192175e10eb9dcefdee1f8fa1173987c569eb456bbdd71ec57e5afcb0e4af9d4e5e3ebe6da79524a29274d4a19a502a594524aa9d7b5524a29a5d4fb542b3cf37d18a86cac5c18a75836683c0ef42eee928b044770aca19452997f83b97524a594524aed6d5fdde01aacd68c67696ad4dc8a5975061c5399db6a64cc70d9bc6478121c0130c3456dbaecdfdd6c90fd3b9c9ef18d5073879edc49659f8181cb868deb06a76ce4fe8e86c7b97eec1feb3bed9ae9775d336db029a5e1b5b9a95123fb77e1cdcdab064e8b8667737f0700ef29695455cd8df355708ac320a536b36bbe8865595d4d4777772ef07c1fa59452ca9aeab5e54949b3497a299da192b2384aa9ace102bb7baae54eb5dbbdabcdd6ceabb4aabcefb374deacc32465e7eea56ef348c9b1ee8c47371a8f4a4a6dabd64cf95eb3943b94565aa90c8f4aea140a6af4dae5dde6a975ba3ba6b9bb53bfb91100986aab9d9133f65f5f0f6c29ad332d1a302d9a992ff6267405405691810c6a6bdd2a4e8d960694564ab3b0f645ed97d60be31b3b43ab9db9c27ea9f7d28e56cb62b1baae7bd985b24c9932b6be36d059bd6e7476543796565ba68cad3602b8e1d9dc8875ee9303ae034a847670894c892385060e0f2c0d1c0f78aaad0183f3e2e9a1d5bfbe2c0daf96563b64da4a3ff09922c5cde3a4fb767476a7d56e38346eb27c7a656d819c84d940a062cefaf007c3968c97326a70c277587f4d173c7ffc57e80a4000bcdb354d19c8c820834f47fd1a35d4abb5bfd91a2d0dea8b34d4bab442e3d3e12ab0228c7e58b45e18c33cd8a7637b1b1b78392d977f5eac4c242c66789b6c6021a12934a9e0a821f349cd04d54766470644f4be173f1daa176ddcc0deeabf1e7d801956d779988ad7f94af50d994fbcce0415c8c88070a9af0d7456af1b9d1dd58d8ea7a323bb4957d66e98306f34ce104e269b4835cfa46945c804a1c9ad5e304436b9e4709c5b643602b8e1d9dc8875310e3a0eb80e3af0a4f4b9dd003c297d068063436a1107081a383cb034703ce0a9b6c609e7c5e3d1ec49ad25266ff5822ac5faea9161b9483497c93e1df46545b2cb200cd9b639adb488a58f9037fa93903bf5034f4a1f1f4f4a9f248c5d5eeb8dcfeb66a63978824e0eb23f75f798f489c91d9f14088cf1c54e0bb3c316960d3c44d1f4d0d492e202950f543a1fb2b84b5d23aa218fddd460f21cfb293799281fb8c8aca7cd63e38a79f5d28725eeeb28f900743be83a294de48e0c2e410f2f5c2994789062edd74f8725c00e284852da61092d1b614daf88be3a8871b5e8a04408997e875d2efa2e7a058728a40ce145174e66f4c5e6a9405cb152e562af66091e4516f20eb976453a28c1c9f4ef3645173599fe96938229327d6a37a5211e32a55fb9e4e420e50465327ddafda083031513e4e042a6ef395ea26891691352e0f18a3a50d8cc8cc04d578c1607585b68a0c4e0021e9a8122f4c28a5e160f4c544d2c612a4e3e033411b5520af29c545328e94690f44141810ba9273c2859b8c07550bab80618c1500a4a18306c475c1420254c51624862002786a2387161a916258a0b062041541422036ca145a1c2845e2e3480134b51987819c53aa6650b316cb8803924b028304cc1ad2cb33cf9a08114d826cb2c4f48884cf08c2cb33c49914197272d32e0e2290ae604af90d4a8823f2736ca60d6908d21f08a080d76c038a9c613be4c3570c03335510b5e6599258c164c61c0a8410553174416b08d013606e69e9c00df285b4809e307518c510d1bb097651631546a1c65119374a41613b3c5d6a493392924302bcbaf5f18065f292fe82370bf510a5aa048ee14787bfbeaf7d519039d4722790b715a746f5197c5c4609fc205c4eda2058a5db885f108c214b1618c714be90616dcf09447fcb48ad32d98eb965d0577376f5c33601fa9c733a6e011a7bebf9b9e6cd93e02cdfea927f8738e965212a9beb08884a285312420a168610c5af6fb94e3387ffad465a8c54240e58e87f52be55e8242dc3bd9bd48909ffa1da9972ab8a42f4122cf41dfee0d456858e7f841ca0f600b12794f411cdde37d7f2ce6b21c6070151ef2289b7498b8269d2b0afcae16a58bc0c3257379cffd9bb70db4a0dc3102cb5047eec8afdd5feacd5d0098b08ef4997912f1a72111fa5eb885dfe22482df3f4ad5a9c019e5b04afb81c4b1c3eae3f7503aacfaff784f7f23a13ff5fd2922aaf0e77bff2dcc6971ae5ef58f55ac577d10d6ab56ff839f151209b2fa51fd785618fb9574588ed81830f4ab53a039a32c14a1e14f051c169ee0b0eafd98d7f6347c6d21fd1ffc1ed2573da534a4d1b0c8cf1c72587dffafbe9c85627b30df7b2b68ad8f630c7d7f2449e87b9fc4ffa3ef3d10ffef5b416daaf0b5d5d716fec0db130caec0090536cd61f53f1003e5fa9c18dc42f5c330b8fe6c9a4935e9db42da6227bfaefb0de43e9532d21f391b7881c7f76a10264196c9aa26ecca4d690946269d4128773f16c99386eb8144e40b8018439b11790551153902055ea2663fdeab422233cb0e3800cd8a7020050c41b38e6a0ffae5ac88e442862a42332fec0f9433d79125a425ba24c70b4573b2d2626f791d61e9deed515e774322ef91bcc76ba4f99130f34c016d246107da88c2374273e98ffb7602c3a979c6761abdc8a19a67742427538b1a3b6a49f38ccd25b7182ec678ffd5c3bff63bd27b91910374a11f8563913cbfa1644079826d942f28c3d85244cb0e1a41e28129cae40df49745cd33bfc7b778911fcdcde57228177605d1bc47ce80f2903bbd8ed80277c2118b39798f87c31ffc1f0e5ff3677e5e53f541583346e16bb258af7a396b16e84e0ee5b0ef3d509643d603112322ac377afdf03e0172a6fa9aa74335e0091f58019e54cdab7e944d56d0680eebd5ff1801c1ef7dff83c339e4b0a079e4b0315ff89a0b50bdf740beaf098918f9f41088eabdf766dec88c45f35f8df747e6ccfb1f9a703239ac5f334ce187745802e4cc0487f51fa9be6936318da999504d5fcdffb0bcc7615007d15ef3ab79ef83d4d484aff935ac67853fdf7be16b862f04785ff341bcaf097f8c80cc7ccdffbcfc695eb23e48cd4cf872ef83cc3ccd4cf8f29ff19ee669bcd6d3d474d00254bea505ba934371636067f2a5169de64beee454d4475d94db432ceed44950ee1464f5a3fad53b943b2d60155220a73477f2aa38aacd3ea7e9984b290f94339af43ad2d1dc21e9eebed7e5925e28a5f5012dbabbb7839fc3eea639e48efc98ecc529bb3bec965da48d7877347436c7032692e6a18f3f2665b247ce205ad417292515593e0a0e90208490a70e52ac40210cd5202ba58aec3fa5587fea604576b17e92303ec78657c8b54c762bddddaa6e7882dca92fbde46a240716f8a3c97348183dfac0989412e63547f697b0fa29b0eb8fecdd7fc20b914db7392f40261ab4e840c68b306ea8412cb14d7aa82f7ece5b31b48527bc58b550c33cc1b48277d1c2e54038c3ad6d58704ba48262b663b3d25a690d16f097a59210458c21c4942d4244b13428e91c2658760068be27440bb93eed5ae9bf8e00aa1845193d512962d43f2f9411982deef9a51941e132bb7928eddcfd7a97a500168a64f76e760a159986f386e3ddc2117b8bbea82c042656b64d22348f540a6229cf20bce45492d29424733ad7c4a9e3155869bd7a3dfabfb3877bf94f2499c8ad9e5ee656cfd4864cee06b2c78625348c3e0d65c3c601f08c2040691ecf80a4995640fa804e7d053a54c20f1e4bc6abc210155aa443c20a04812f7d2f2e2a32a514082fd1a73fc42954ade17e377b7bf9e9f0d1dbc66ba7bd96c6451e71be933623df9f136886938684472fdfd4bd9f0af1a4f590835d54ffd6d0fefd8e227de41d7bc98ffdc40b7b68389f72bd3fadf4fd09a57f7669f55d5cb66071519953eea7eed3200273299003abc0f38fa84dbe3f6fdfa121fcf23bf768173cb7344f33d5ecbd6f5fcb3ce21291efbd6f8ff09422af0b04d8887b276dfbbbddedd29f9f2c5f51facc21b973ffbe0264cf8442c29898b46891573ef8401441d0c686c5baf77edf7b7f9cb4fcd7730d6dddb5928142fa90c3a40fcd15cc60aeb5d65a9fbb628bc0435ee7dd6ae55ef0e762c04745cde3ea82bd86a5fe0643f64c2aa496fa4c4c5ab4c82b1f7c208a20686353b93c674deed4af453e44471f9252e4ceec41faf4d76642dea85f8b724861ca9d8aa536538bf53beca5166b95d4932e0bba1916a64c64cf0974932dcd5b30ff205b876cbb06dc2b8041a579f05bd6db6f26b2c785ba903ddee430e943b34dd9af35acfe3e0b9c605ab48f417b05db22b037794f7dfb2e54e59d496a81d2619b17712f7031e0f9d43c76c4f387a25412b875381572c73a90f441923e7e8473c081b43890088236360e2404044e026f368923913bf6534dc224789c4dfdf3de24202bdb5a3b9de40e7d9aef4f02a3e030fbf762ecae1702ead30f529f86488064b3995772672d18c038bfc8f6bbc8f683d0a709914c27c9817d25773613a2e0d65a2640b98588b2fdb63fc14481ddc99b869ab2c5d247faf474923bf6b3ece91a562061f69998b468b922af7cf0812882a08d0d8b85b36dfb6058fb36083c7ad9be0365fbd6eb99a00cae0041d320041843d90801f6c068f0846590400c836fa8d0f0430f5e7e1012bbf80106b10abc7a0116633420c236592a159d40dc01d764a954c484175434d001b3b2542ae2c1865091932745405ac4d8a0c953161867a944d4e5044426d8801605080606930649b863a286126c97304289e8034c4440d8d082b72c958878f0614eff6eab57473a6520696459abc9f293e5947f6c88dcc98084f573b1828c269cbdae7379333a9547af87adfd6ca5ab16f67ce5ad4a2ddeb6b0042379ba2a75f9f43a4ecea7a33e6bce1c8b43591c48a704e1d69aa0a6bc413d29592d55cd274ef73c2a6578d2a3299b1befbe365b43c16d9b7f73f391306987636978423a413940381d9d8e3f59432303261e0600e87e8f36a98c192e9b9b215907fe8694fef0b1e6914a4a185dc9743f980274c515474041c152a58244169dd36ab7f196b0b91893f993c78e7443cafbde5bc311d370e6de5bfc28b7f42479073ef83043972fb490c169e61ea81285cdeeee2d031e316e9c7657f3c8dcb31ebabd79db7bd2f3878c6a356d4e9f41d3c1f1a64079f8903d43648f321b903d3c96e691251a1275df605765e50196d0b0f9dc93710ee540bda039e49ec354c90c85f69caf21dcca5269862a799c41b98416271641997beefdab7fb7c999021d227de66637ba6ddb6fdbc681258077ca56cda0a01fd913812119909e0464cf1087bd181ce571b3d611ab40f9b5825c0a747a9dfb5bc2b7433e51f70d689ed8090d6891c70c2b37067fc63a416207d528d149efe92b5f94116a7532bbbabb7177775f8735a6d9eb6eefeeeef65abcdeddded6058da4694de48efc9512980cd49353d214ea204a29add45b4a995c1aa294e21a9e2f7f8eb329cba7b44b8bf273b4982b78caaf1183e5d734a5d49b524a699d492df250f711e0299b5221f49fe60ddb2f3b245264e645ba6750e041b55aedffbf56abd5fe3f6989e9ffbf56abfdff77d004a189f4b964ba073b3d413575116e72393d54510bcdf0ffff1f4c172e5b269625115ca97708171dfd44ba40ddd3b55aade8a8a8a88b7e740d045dab0975a935d56ab55aad56abd56a35ef367501438518649eaaa8d56ab55aad56ab79d01fe9ec745aed76b9546767f267e77d95e33e15bd57b5f26da3ab5837f32cd9e4a2d39680986a28788f283a2c0578662061f55960fd16f22ad21b8a0cc8f6eb513beccda709824b9ffbf26717f9134b6c224d2bcdc3bdfc7ea6a79b9ac9752fc62ed72ff912153ca548ce225a4fa12cb97f9c4eb2fcc9448230b1cc1bfd92e674c57c856aaadb50ba85baa4165241518193502fa95a28053912d63d0b94123697963a550bf92a945d03f2fd2976affa7a7c4e85aacf87ab64119e3fd4505aeceea1bb86b6e22aea1bb078ae610bf50bf5ea1b81fa1337fc277b0f9617f39e6d06b56a0cb0102247510b5ce00596284f3851c4154e30e960adb5b6061f5cf08219c22ca104083ac9cb096e1212a37ac55092263b34f1a4cb17274e6c5189b842cabdc208870eb2b8e00b185b64698111f5083741e1c15eb1c24cd312375ce1845382c3115a94184af08014461d02045c962748ee155090d45a6b2d81184b0606ebe58a1a85972c668a349822040690c00287114c11a6c9163329a7796e9e33c9262182cad01412601ebae01b9e10a203415d82a3329f3d8284e65176c90e45a61ae571d226d05c32859c8825398fd34af6a67214953d004d8628ba72e5ca0c2cccfc633c4e9072e4055f4039e1441033ff19348b3cc9aa8e58248bad73e0459dd8d6850a76d8c24b91951cb4f8a18bebc08154134a6e70128515485e70e1160890baf9f385807bbbe97dbf79de77537f5f08d86c98fa1b522e05e688b5d31008f75dd87e432e1c63a1c3a6ffcf7dfbc3fd06e4be0d8170bf85f8b3c02c937f8ce8ffd84ffd6cdfbd7cff5e08b09f7a20f653a10864fb2e7c8771e06bfe1b995d30f5f7132067ae90080e2be46cfbf153b65333fbdbd726a6a47207676fc0097247be6784e7c75a942f71748fe01987dc915fbfc0217da8b4b96a0007e562381a70824c862079b6cfb593390c662061dcadc9a59e2c3dc81c09997ad0352a1a19302053ee3db04648a63f45ee7b0399faf07cbfbf03784e4d231407acc608ee4d11ab570f87f4a13e3bd596872cb616ac68e10bfd23a4ca6502b422b43801921034e952a72c81258621ea0b2e822f5c1430d45a6b350192db4215a0285a40e22f7c0ece52e9a8288f1fbb5e0800093cbefccf1175ac064af866a97434248e81b72c958e6a68131c31b9329924b11c1df132c6568778ca5d964a4378916189b5d6da301f688d59d244eb8b314b527004e83b526bad958b0e1c145c8078a116610598302ab8428c099284f1c3064518474a66b8ae219686b052a543681e2ee575aa6f05f290b0fb52ca5b94650f7658d3af3209bb72c9089228e3910273ae091cf852bc2fbf1ed4f3f6f8debb59db63ae902b5117b61ad65a74a28eccfed441c47aa7bf43e6eda6783856ddbece3cae3ccf48f6c231a65219c92a8cf11bc9d88570bf92592564f51cf72bafae563be4abbe7d16a8d330fb1514b9d48b62f35831d63cdc5bee6e7fef9c77daaeed169dfd252592f288979440ca7666bd68cac9f62f879f7e3a2c70819953bf43666ebbb5077f5c0a9c92b2147024a9a3af7a5538aa8c641a8e3ade774672178eb1affbcf48fe7aacc6ef57a191bc0a475927a4be4a0a517d55a55eb5a382ae56ef90d95efbd95a6b3710079939ef9d3766a1aab413cf5a67752ab3ba2783a58023b516a50bc7f2c764217c9db34e20e89c73fad359ebac4dab774e3178fc1ca7230e32b5d6d818f27ee02bc834ba3fdf2bad94d254caa6524f53a930265bede05d1f62caa72395024900755cf04542cd1ee851fb77bbee479c5a4cfdbdf47e4e419939b0befcb617f5177d9a690c31269c20bc796013d162313451327b05f929229d88528299117d2f7c059929303935cde67b2ee6a6eb240a542a0bdccaf2bbf995febf101aa02fa8b46df844b5643403000010042315000028100c87442271402498e8c22a7b14000b778e3e76582c1a089324c7511404418c318618400820001162184254441c0020516c50695ce0c5a843790fb716cc6ea340f88e8727bec67ff44a591a7d4a03d016515bb9882701a944cf604088a9ac816dfba7aebf6559b1951f11acd87833f99578132e8b05894b0396bc3c14fda0d81c251ae4becb11b87d6df5b3b22abcb0321eda997ccf0553aecfa2271e5203fbbb049c307d2ddd77ffdd1754039b8b1d2194851b34e639d94b16d7181c34417a142328fc0043766f574ed165c011b932275e5aa5044c2139dae091585a8e578a2d1336986dcef41d8a343a2909289e66c6fb733806b46ba64a4123c90e2d87cd49fc6e03bb9a0322f89e04b7144b6a4664b0e235b373cc9dbcc5d5e9d5fdb4c8ed074022da12347a37f75f2637d809ff5aaa49c1207e4dc0ff36febd6f733da9323a466254a02390fdc1ab8de241832d2227f81dc8894000d566a6afda11e08d31ac4a34960b097c22b653a056ec1c9659af2a2c92d5f952168d6d5986da6a861728ed695f7c6c98bcca5dc585b20d0518e6d7556507c6ccb4a8aa2567ab12d6b5f718f3e062835b4ed068940d137ff25650e8471bd865f927fa139ddf988d7bf7af073e58f322439d70bf6c7bf81e675361d6008a9efe03c9fedd952df8c548de5ae9927cff1c0ede0e57e01cc7b5c0299081af12e7d99a239d46af049179cd0789f2245cb38d45bf2015786f07f8e1a444d1c025635f92dbaa09a50a1de1fdeaf02ea3ad1850150a7045f6e050e9a2af0c47432503e80f843ffd477f8bce44b7a47a9ec4daced89ff4d5e0b1d45d5fc0c678f68eacf4b061d677700538d4a1cf10b87e09d69bf802f9217aecc4edf23d0ace0ceaaac108501a41eb2d5ddc178b53990499e3bd7b804cf315ddc373618138c396eb1b57f2049a2483ff4f90f0322dd830fd256ff00c58a483c6fca47dc0dd3bae6e76f484a42bfe1f7a8d396f725d1c9a65527795a846f3d77abd5516e4b1c1648c87d555170d21316494f28c21cc8b32eba08697c5b3e01b72b4be9a80c61682a1861b4266e0a026a09947b0c78eed58bd7b674232d34f3ee7f09b099ec69e57efc7cd1c6a0907d1d0b3299df18240ac9ed79905926e52d70c2b08e8326c3dfcc503b8f21d7e589eb1260be009d1fce33223a67972f8dac80c55953eb04bfdd6b53088b008f77a3471df79b12c164b189474cf3efd82833d3db6ed2baccfd79e45b364011f2ad740de9a8407745e2a8d7de6218527b48a82ad9e5979aadf0ad542059db4e4eb07f06d3b5a0f0311f719d8e85d7f1080d21523f8b68c310950d4300d1814d8d7b32127e42d4b5553eac0874ad205acbfd234958e4a54458423f57cba213eea0326806bfd7a5852a4fbbad310b100e89ac16834a27c0019f7406e91b94b91acd056b1e086f0326a5e1fb51a64bbeaa56bafaed72b597588ecc825c9f9f1d18b473276ebdea571e43284a417ffad8d58c788d207cdded3c885732d27e8ba41f2c5a5d03f1765913064f5e9dbd73d28da823dbdf12dc756b1106e6793d369c239adfb7dd33f786536e4189798ec9f9ca3cc61a638e4a5ca04083d6548ef7bb3e1bab03d208abb117d6662c2e16ed826661bd35e3aae3426342d13bb8e7c569d7d719931ec6d173374fb16bcecf9b05870168fe1508c6eda0ae5867260ed3cbeaa26c4815302c657c4915a5af1328cdcde240804e073031cba83425810c6b8013a379c53b30b17e3527a427b35937213b184d4132e9948f5438601f71afc250e2c874f691eafb9a1a88252063870888bc49ccd9e60c85ba3651afc0b875d9e0f69f5910d01be54d96a5bc92d9dbe7c20450de810987c49b1ec4a39c71e988f3981762514d65a19446c0ed02a648abf4b43e7910c4ee677dba24382c020ccfe9f8c90c81c12fb4c9a675a66fe31cda40caf4f4698734d3d8d1041ab89e910b5c700634d049f665aeb12d6fe1c771995dd38518b11a01f0fa0a3ebd4437b8733e2628aff07aca3fa00d3b69c9fbcd178bae094903a04265bbc15b8b67701065c920096c17a21aa166da90b79884decf2d5da173f54201b7919997b71bb9ab38089fdfebe4cf5c88ad97802c2ca559d966c49b1caa2065e3bd18cc909659a7da867a78ab4566445521db5e200f5698186f40151831a1404ba072a1cdf1ba4319e93458fa4db89c9679a2b4bbd895ba381cf36372b3dc9bb3500e6dd863033007b6874ab93f0e2d795e650d0d768e9eb827b654bc44a5cd6b404ad7d646d3ca8917eb37868c8174fff3eb4372d147d9d1ff188e24667fa9ee0968a7366c10e2c4cbef1adc26085982e28947bbb1c907cbf8363e5a3c4a5daddcf20f8e96edd4c5060ce4b4d5102f4dbe2cfdc6b523f559a4b7b4df7592db24bb0fe1038d4813adcaa8b42055120979520b5ca66ce2dfb229f4be442cd08941a1591ad89622a79db854716fe4a94c5faf8e129cf94de03152c15338c9c68a0790bde558927e4fb6f28b26fd68c55a61a1a8906bd6302deedc17b2b996b196186e54a13cd3d7c2c407a9e284ec8dc8add9b6fd1049892eaa0451f25be43898ef8d567697653862cc6bc1628fa5672906520457d2bc90a4df8c8ba0d041aad13904562a33b797b1bf06b63a33bb5d9602cab57fa57b4c9c729ec3691d09be1f09415dad8cf364190135a7898d270a88c1c200671b8e1c767971b892a02dca774301a69c277232c08c7739d1a0ea04b05e44f67a84c08d1900afa40c3b704c9b44bbef45b57eec3fe374b339c86451ce7300f0d58c0c92cfc22850e9c33d3806099e4dea1b02589b7d8a2713799084703ca7f4e5ac476d70fdc7a6979f264d810747871fca9237808392b5bb4ca721f4c99a7a82070c65e7794c4f35bc4bd1aa66fe42e76a6de91544f5e6a63d7d77c9e190d0f5c00c91a5bfe856dd3770c5e8b44cc5a6b145eb348b578e9e2c74c6b9abf4e4c67c473c8e91b57f595d54aa527c8cf69020f5c195dc4f3cb351a8ff6c5aa761bc46aa706c7a7d915363791a760476223edf30a6ce021b82aa8a7c3aa20603d009d37640a3d91e0e26b0c0eac4d5165ac679aa2884cec34761f38dbdd1dd2ec38dc3a31b4fb88812546426777cd3f8d24dd4840b301bd1f0f7945cdc8efbe6fbaf30fcb3f6033def57b0520255f1126e4605fb55d2544a1d3df0f77c64eef6a49dc46d89373c6989547b44d06925186815edd9cfb0197be2352f67b36f602d480af3c620ed5a206320a36b1529ce2d9b5038061bf04e5de27b0eda846f6623c4a221fd76652cd83572c9f2391b4600e92d9e3729e0c005af50d79013f851d7c98144ec7d9733a329861b046ae76e4d228129d8d46fcfeeea1580586971509264008285f2bf81c6dff8e9b3efba76dfd97bfa8fa2400e1b00a77a75e2278d42852a52d3037e8897d437e1afad513ba13b24821b0f604640821f003706f93e6f1936c0802995ec54d54ed25b18e5a9e4877c72b7e3f9b2e61f8041f3cdbdb019f7f89a0e1af3fbbf76140ce2bd03b89e16b36e0d52b1704d020a129bb7339b01ac4398c614162c0be8b55792b8cba87f93bb602ef2ae0f499b9191132c82edaf336c43a81e142947d037e217cbd06c9256fb496e75d4cb0a48cedd2cd3ce05691a418996e99ef4734b59626ff43a8677616ff544f830985dc9ff8e4668a5ccda95efe497fce8b890172f6ed0d254119ae31f69affe67fe8251055c84bcc7c1cefdfc6a007dc9049518ae28c4e559c733f96acb5e5ce305cff268f0e234be81045a5e9ec4530f2ebd060c813ccc892bf88d395782fcbbea4ecf2f9e95f91d090f47b2c9d1ca48058de4fdcf60ce8ade0916b2cfe757f6feb9d2bbd9f2f66990ff89d46eb16f31827665765909e4c5d2dc21d2706cc273b9e69fca00db21273ed7c06effd3a3de8ebe8506f5c5626f40927f7b3061172ea62c176c449fcbd5c9f41e30c4f8818017b9ef54531cf731415c7e875f283e601d9d3234f4fec46018ab325e6e9fb0dd8bd58f741a7f7832f8bdb81eff1b8e30bb2d955ac7c7643ea6d1a99779963d6a4d811629cc1975b20f9af9eac32c67eb9b67ee3e18d48ba7c6d8cf7ffdfeee7fba579caf0ccaa756587dd14e6aa8e49e8d79062aefa82e723228a2aac0da806056f60346e1502c376fbc55e1c7223245e9af5b09312f819981dacfbc1105996e88f27b6d2a260f2b6ab12d9b3386f80d78b0951874f8cf63133dc63bb2ebbcd76fc2e8805d8592c5685ca52edbd920df6a4b53718ed2d791f9005e00d1ef679edcd3ebf1719f808bc9c700ec06ace9efbc31d32fe3d033560c3a88cef583e0e2ca13b574c13fb9b297b9d74effd5a4640313abc947bcb48235e330b49da7720cf9fcccd159616af63ab41f5bd0478a8a602d9bc9345c76a1f2c768d0070bc2df3b9762e401c97e8bb2f1d1c6d19058897f729c16fc1cd33a788d110cef8c3e94e29b425e7496b49b33c89321d1774aed8e672925c966d7903d63a11b64323fd284267a03a1d5fa3925e58e785e51b5fd4f6fdad90eb72e7815b31d30f266b8c2f81da0d6983ab8c9e22618eadae426de7031deda7ca17804ef99e46544911d6a769f6ac7b23e441bc96319da1c8323726704782029267afd29635a373c2f97ff12136392efd0528bd44f635503d2b6a7aa3dcb7de011973d9547c7339209d46e40af776701ef86499c7628ba36146d1e12433b552fe630ac42bbe30669a6e871ef3d47e93023ee883ff5300c865707eec9ee9a041f818cd4188046798c741828b83c06ba351ac3a22b6c5d6e905d38ae6e37c40f0eab05871c69e0fcd2a190eb4311cc53219b458caef1b33cf7a71a8e80fba422cc9bf201ee431f7a0b6e77f411ca25b0cb22cdec8c9042bf84d26ef4de0256ec37278ac8722e894c203f5feb8ca2797a02f9d3845afbc130b3d9ec75f427cdd27f7d0449b07dd2a95f73c79ce9038fb03d2af94f4745114b63693ed184d4443adc1c26e7d5f5dc574b4ad1ef626146834229e5c9ed63185b7ee020c950d1ca715589b0a95cb61a2637b8bda10120a0335f616e821e4c2882b6a2bd8fa25bfa88924d14d7e2292e54eb4f7233ace3da17fa6f32ecdf3bf3a4794438f3b9f832e73723d0d393d5596eb48501bfcd3280e11c7b70a73b08927a43c4f28ae722771f07780a46e16bab5c3c937e23d8b55397514cb3a5cce89459f55b72b4088b91caab967ce8fb007747b3f38a3377c599d1fbfda1d4a7ae65002face8fdaca2b083553e87de3f5896e02805156e0d71ee5944fcc450d3938016013a8d0d709d97fa9948ef9207cf2e620eb3f2bedb7529e3901a75719cc88517f5102c4614d6253d2bd9d7f3ef1a96687742503a0360a71dc85094c76be8cda0590c17f0f5856b6c8e9c04d9816f8fa53b6c8394a6c2933e093dfc453042707d7f22f6aa79bc4e0d6fe2cdb17eef233ebdeb8570bbf30a952a69d90df002c1a0480005cb8a6a12713e7de42142ff5848b3fb7ca268e3e2a3b68876b6393064d894b7326f428824b0042c324be77ff4145704f90978a4a6277695ee7ac18805e2ed13220491286fd1039bf11f3b1610a83beb79f175b014af4ffe380c305f36abd6dad40e8e3339f4190bad78145bff7d0ab424c4e3724da2d3e20512c82eeb3075a5f26fed40f12974b1644aafa62b1e97558fc072255533367b0746defebbaf63cd091f31e5b1f0a80e5c22c4c34e1ad68eb0da9b6e09e9df2e4b0e440f8f10812b210395bc14e20474f06d54d54ad78ff27565432b1ac53dd1d64e3d7e9ab7f50875a3c330e759e76a60d351619070e8a1437715316f07157f0333351c899deb20820ea568cb675b71c669325247b479216461feabc23f2797848c42651ab3f4976d9de701e71d5df03180524ae6cb38a5c900f8924638d9271e1d4aee733217a2220062ef1ac5a6bbc00a09b7bcef4cb41146fd734fe0021f35c9287fadb76cde9ecbf00a4f8639982f1e20e837f12e970b55d1111850b10aa575306cc6c88937e41ec789a0f81da85df593a2c7ee0d7185a37efc0d726ef8a8daaa73a9f1b88eda2da7a2624a503349499692a1686c99990affad100801a63f31e2500cb32ed3edd8d85746625b5d94d4225971d6647cdbe4bd87d8bee7d788c2e16218e7a432810dcd67bc6a09266c149f3522282231aa885afc0dc742dbf2a0a645f40e10621d709016b6dc03aa38218ff47f8449dac78300e3abdc899cc161122be8f82e7d86395571c8db99ddfd8a92c2efcd3c0e9c084420cc8b2aa7d4846800d08002259b3ac371590cf50b80d50abae4dadc004c6fc387daf60d0f73e51a4ebbdebd725381e06c13d8afaad461d4bdac6dfb347e95fed32dd84707d07f32ca6244b938a2df10461f6158af9b71d3a2c966fd4e73dea272950b851a9846c02d36ca02d0b4c621e92e8d7300e05c198977b57e34aa1f504a2cca1f7609b776c55828c90c35a604d1f1af9e1e7815fd1dc88852026cd817d3d94a7aae6155ff30f6903703fc50f9ff9eb9f32fe84aae19c40179be7c0e0d927fcceee2312394cab7500696461cd20543469c71922e4c15f3a2840d5407946cb9c13cca6667b9bba34ef5563a2fd26b26adcee9eaad40c506deb068c87c28a25ce4ac7193fb1981c7e03c56ccd12bf8caafe96371002092766ba901f13c105ddae20b71281e304e62c78ef5ff360869eb60b84e979baf76ded16721e89990fef9757c959cf270fdc9007a92d0fe5860f744b21dede2b55f9f9facbed30acb4f27b4623add5a6a1bd44b4074fd531a3e8219129ecc41d81e185dc3b0467fb2b3193cbf141a8f30baccbd51f155ca065344ce171ace7d4a80585a11a6c073a9e3282a338de6fd909d7a9acd2c9685806d11f6b7a7ec843690d08de4758ca4c016eba7dc9475158dd36f00990189bd5b07a54f0256b2b59f1f41a361447127df7aa29af93fbbb1ca757b2b221c4ff0b4c464656ba560250a491a1fddf9344815e6eb19820539aeb0d3aa57ad05424a6be231b5624c67f5a3d28fc18442dd08512d909714dc8874a1c284a204882677679e184128b933d9e96c3a196bc83fc902ed313405ad257de8eaf0c1ef734314afa34d22b70319cdc419cebc698275ad5a7e0f7d0e3ea6634d65714e8183f24c12e8eed247cc5246843acba50287daac8dca394037d93e7e675890364fade86dcf4d2f603b7ed025608e698181ade8fe74a183a460f203a03301d1b6d687b5cd9af18f1266299f29bbebd3d393958679948eff17f5d158dd1457c15827d625e69fb0d0994f255bec67998c9ed902f3154110514b6f2984cf68f5cb7832b6808238148056ba51412fb86afb38d65140d111bf3e1a0d6b5febb1cf09dee7ff98f06b893b65b05a6871d696b1708848668c8621a0858a0aea2316c3a20e1e9346114f45f2c7ab3ba6529b167b7dcbb1f478316de045103127f2830ecd763d92e2372dc5be9d1daba5e0b5dbec18763e8256adcd88c32cf1623a6f54e8bcb99bad1a52ad75c164fdde84c114f6257022b386c038193941422130a3cfdfeb95c416c53b25ebe54777de417e7a79865af4a207329b3f84f366d0a115a3919490b917ef14941df2c6f27cd04f0aa8106e628e92c76b386abf9a35580c325f239808d13633d2359c95f935634f16862110ff3dbb64eda2e78e8b3408b41df9a142ab8e066798910c42a2e2c86f778a7c4c39fe0536876d398fb901f780516ee6f9ef91c001a22391747873aa6dd654e70d66690494da4be7e5a218b911f7c3464ffff6ab5c1ab906105991e9bedc147b01a25e2358f3e3eaa9f7e2cc1d9d06870495f6b00a236a19e17dc205baece553bc2f94b87286bdb113a4d907e11fb802b7fe0dc3748c6ec3ad468e4b3ed691b59714e2f8d78834f7b986706e245d9c5cb9c345d7bb1f6a1137232585459feff0a33b540bbe0f55bb801b70a63ee3423c03db16171fb19821ea326dfe2b6b058de401699069f75d3126a97a81111305bd5b336deb48c95a6c1d60130176523c1a6c1cc658912e047c54912e0da4c0514ba39f9e0cc0d06cb97dd6c367b37d6e4b20fd160b7ab8bf4bdd8fd4ac9920bc6742307d7814a0d64e44f9b0270d492111e8cfc43606b7f509b96ef2e9b1afea5e5b380a4cdbac54b35c5d77e0a53649601884b4e9dcc7265c8e498f944bd43268364c9c57306939b6bc52edec8054d740555c151c6b366a55014353356c4151efe858e441b2afb29f095e4aeeca0a9ac9c91e50b5616c75e515fb0bf67b528f3938124b02d10729b82cb0f88bec6836f3e3548a278eaaf5e6adce52bb018bc2404dcdbe27e4ffbebb16e9d44cbeeddea399ee4662674a28a2ed795576d3dcabc62044de2618792823058d130f0f1509dba8dc43108731970f7dbd05fa5ff17b93b6ce01e5141f63c36b34d11cc29939564804b9cf98fa249f296e16bbef9e1a791500b98c12d3713c4ac9a4cc2366519616a1fa155cd1146e33d8d35c111406c1e900cdfeda1e2bda1602fdb3479910d1254cce02482bdac45fe2188feecdf23492ab460f7765237debf4fa8f7440004671866716f439c3939aee079ae57790828fa349bb9d263a6fc53de1aa65f7c8343b6522fc59a19dea1efc54fd92e99485c3eaa8bc392d5adbe0d2c742cc64d08d007bdd0274dfbd7e4e16846dd8fbc017e984929526eda1fe97c23e71d8381d45648df37bf40dc991d9685a022fcb2430f73a8d1b755e18dc7a335c21f25552c127023ff180623d74fb8dd498c7c0c53986b17384ca4e0b1a67b96217030aa7a24d6c39dc41cb2103491bc06e0cbf638e0967e4d8961d5c5371bf354eb9a6a7529db08ae3ecd5bf60a94215cac55d92a107263f92e2aa3d2f82b120e70737471560f7b132f5d6195b82ceb476ec9a9f86afcdde12742402a5c9b227e582e934e83f8e04cc31d5072c195b491a00ec454738a82b297e36e1b334539516d6f86356708a0ad91bd17a3e2861af30ca145f18c7c98b646ad40de9478993f9918c256e14240ec424ff2200c2c2e9ee77c057e3cedbc9139e2b92032df6e4764cfc00cb65aae672077e2949452beb6341536ef657f79690eaac86aa564a4ee53279d7d0d1bed754bcbc7a245f24a7af98b0d3441b6a1916bf360ebf583cb3968289a564e3bee2055ff209388f81058b852e52243c1c49d7bb9553d1a7b649ce25e6c4a9c335932c39808f37026ea32410be16d7f918bf9d65221268f8996c39bfde4374b02342db7ac237feef2f9ce33994f69f633361f40cd70a9e6550e6c6c6336706df0950c26c55525a9f44bab34ea4a8afd1217c9e9d685badc00a47e5b009e6b15417f3c4591815b1640ce00f2774ba163c94449cef009505adc4ba48b53c434ba1431f1f818916286484b6ccdeb4f76c9259676a760d0f2e9c4695fecdbcd208b0e41e48ed125ea7a28d9be7c7e9565f5e8c921f2bce7c1fd8b03702d2831c039864015159fe7ea8654fde8f5fbce48815bf8955762b616da05f0e0887f2bb9f543611ccf635d94c3a751da38183f71316d079c35b84d7a9e628466c05a04bdc88d3979fdc3fd67c08e578541e6bade0e3161a7a8670a9d294c18f38dff319506a02f9bc8ad80b10d6cce1fb2e68f083b03d83cc02ed8640bd439808fa0e902e9b1bdb51c9db84a41534b246d4e5c3ca981264787129b1164a8d6456cd57d4187f155311b785b7f2de477dd1147a6c114e445221a6ce380101048e1501d44f5898136505f6841ce181730c0e68bda980f9804f9de6be6d8c04235a470124c35c3275b6b78017d61b3f6b8d436161f09091c9ae7db61feec1a27c02bbef8b141dfb41c8e1e268841a225e1fdc6237f6fc61461c18aa4161d06920ffe6744c87bb25d75a6308343d378e13eb44ee71f45f81b16a12a7f16725efc8cb585028e814547180d708f0a2c98d102e0f5a93cd99ac08949ecfc28accfe672a8b9dc0b44fcbad8fd1d461c76a4785d57f3b04ad5f994c4f8a3f60829484df216ec4399961eedee8111bb59b041e9232cb2e5993bd508f2dd3f02caedecf428c0189316ba87f4fa5819c0a9da6a8396dcf9874c9bc4455af3a5263274cea2697faf1f10784c703a3a8079ccc0f26eba12497080e1e73aeb9a8f995a63cfe5a93ead4e1d7ed9921c0c21b78af7ed9d9d516ac8d00726dc9d5c7922829ff2654d64ac3df22dc3e9f27f78b38f3f6a80d63e1ddfeeb59c42768c893168edc5435f85e6a135ca7173c5eb892df138fe7099c7c8829fe128ef49ab75ebc582d3fec530e87b688670d2b3f51a59b437289555cd744da04f10a7100f8080d8d13915d5029a6771b63da6340bc2c2b6cf1e7d87b1df146480e60fd6c53be531c02d7f31a4c50820e5319c61b4931c81b57f89064d8a1f5351c85386f431286892426ea9e95c099215f68c23817d38315e580e39936975036569855f2024f0f339652b4c51e85c75740ae3d9fcb882437dcec022489ba24b4e6993678fd4c85cb6493e69b4ac192fd4f77afdd3e09c51749d9b93a75d90c5ece0c6bd9eaa3a37a5612c74ba301f3eff94add6417bd2204c220f90dfd1c927d606604f87ca2dea73556214ddea13d917414d96099315a11c3d302b2b70961aa432ee50dc165bbba49cf4481907e71258e3e5a0734d19c2f008206abe48c8ba99067c19fadaae9a0899c96abd2ba3ab69162c91a215d5da5881e614f751c69a74c5d8ec0541a44321a03bf1bd64ee391915cd5038d361e37ab2792ac553080363067d2aca54e2722fc544d63423332d8bf308cc08e3d08c33f425ce8e346d51f7e7d94c3cc1d1b7fa20bc3b0b457824f69f89454ab1e1384c73e0e64fd7801919cef697dd5c24df6385aa71062d7e3a04952949e71af3804bd0b3d400cd8cf99a4d4460f3a05c4942d15477e4143f86439ee2be46286be9d90229b1d7881036e0aa80270a7e47164d5b8fea73ffa9d7657d06ce2b364414c833e08604ae54943f49c1c4f7c89eb0bad3a643f4a7bbbd4814726d02b7bc29f6731ed9445a2060d0938178914b0beae8f7e099838356247ea574a3f9f003858424155aa5ec5f318ac715bd218531d2626e1eae94eb99eeb1660916db862ed52f8fbcb132f1c00e3c1376729e78b6e1d22f022392c56cb67974b5fb413a1cb33ca5dad651c35be0ac24951fbaf1c6a8b0e93eb9714428b36af1a3c5f6995523ff86ca18ada0e1b6cff976b0cbbdae3162c284d0474c76219d3142c86f1a0f83351ba91fc487d863d747aaf3b0da2d72cec230043712e2913822629c2d91c62a5338c173fd7228d4769866bf789bc1e85307bc81fa78b8c26c24921b415ef83f2ab4875353c289c387a9e613003ceca0ce96edc0430c8f7db88a81a27067ae909a2b2cd2c8b292459df237653802698c8097552afb80ca8ce6c782812248c4bba259aed93063395176eba28cc17072f5e74c42e4ea9081ee104b169026353b9b976470f4c72e6fddd8f1e26616b5677e805d3d2ac71d51f895544efb86f0793ff0c8b699ea4626fbb2336039e2fc34ca11fbf1aea1ff22461fd60bf7d86bcd6f8f9ae30059de7583b8205e240f05a6f43b61d1a23545c3d531801e60f5c0794345072ea829a7f5084003caa1404b90c9ed84876b9c9a7499308a3e0241a4715f779a33cd5f302756b22df7357fb1a26bab7bf02d2aeea1db427a784fe1a9d878806a85b1fa13fb44416ebdd04746a4245ac7b06423ad9b21e193d5bb0ebd73db5fe8db522014398110173f5bb90341e0d9d38ac4f0990d553be5215d6da88cc15fb5145562bd38466a40dc320aa757493a26e4bd8cc12c5200f4c601ec99795c9210c916bb8941452bfca5eab46cfa7f1f174f4044db3d25c38b3349c5675e004c4d29afccbaf0a363e9610678b55dff82947071db794d94d186aedb80f6ae695c2194f3c7cae24d635670899d996977f0b4e3d4ef54190f2e9eabecb611d8e7836551dbc35009415cbba97e50b5a864094a55b5f20bb49b14d7e15f64cdb496bd219f8267b205aa024299fc8a5df6a7f3f7e94a12bb25854e64b6e281aa943854dc3c31a41a6450c3e1207acf8af9259f792fa99350769d58b6df6dbd1522e7596b6677b66a3f76be6f030e06acecf5f68d8a40c61d20a2bb01c22d8006f467573cc7b600f9bf859aadcf1efbaf2efe1590c3541f316428d05647046be359a52d6328fecd3f17c93f8f6847b2314e552497b4d47dfa1d5c91966a806d1636ae7df95be10bb5dc3d0c5b3aa1157770cd26017947593dd2910fbee83996c68d2ae693c959c7a732c8f3d5e9298123b66665c4cc6e24cf14022179dca80aa8292124653762758480566c448f9079840b2df1d0b4a2b50f644264db1291326804cd95baa7bd0cfa24e649777d366b895cafd16a72b0208812025fa3752c8e5bc6818f5c8ebda7fdd367d7bcf3558e3c7e05de9430f1e5672e579c507279ade88a4b255c3e593f410732bdacd11f0d6ee8464b71c0023ef79ea2a7a406dd5e1be32e97c074e302f73b5d99661b0c36efeb5c721d8297b8b55f92ffe75640d633ccd3a44a2c29f639a6361e462db691cf6b32444d6fbb6c88dc21d63b8db2cda2f012b7b46bbe2b253f4a63e8d0f5c2f637fad48f901167ef8aed89c56b4e7bd5f515c605b809ff0f41fa93b1eb003b85f02ae24deb775aff054ae1a8ef034aded829c7a1f7ccb718d58ff522da9f9393dbd1f130bb1dd5cdb6ee61ac3822826f9f61a678d6f207f3edf9538b5b9014848674b5071b07307b715b5b6f93c871ff56b835457f63366df690e1f806609675b9b6db0af3571b0f04420ca7bff53cb0fb062a0c609fc715ebcad55fcd9497e4e898693c690d7153509f252df84b7e9df9533c8d022876f93c39e017aaf07be45c268241c50b613a830b550dd77e7c9180ee43bdaa5916cd223c1566e96044b96e8053556bcdbe2a5c3b903eea33055eb817d7c36aae87d795f168247f29f19c195617b2e40cd6179ec4bbc577f86cd74d46fc1dea01a4f31f0cf07a7851a87fe99d472bf65330d376ea7cd3a0fe1071380d19a87dfe20e16e7399a10ef84f1560b71b9edc08d4e2d22a6f78a89e383b1edec4140b84191317eeb39055ebe31782fec44a591466b45583cec81642b3a89a6c32881be04c743bd5483b7d9757e0cbc73c3eea1d1155f35bef6af62a5a15b48e58589cf7502dc6432c0da755dbb264a596e9ff0ea95e14e0b0562b6367b27442107acd36a6b2ada732efbb8346349a3cc2b148f8e5894cddd2dd0fa54087e800e8bcb067228008870660f41e9614fc98335cbaf334c659e3fc72b442c32f9f9e23840b860f11fa5bdc2bc99beeecb108f33be8fc359cfb807a56b5b661fa08b1cfd2ad182b3eb3d0f32cf68dc0ba23bff5e92fbcb72b133c1497be6a76886014ef1fdd09dcdd1d58094a7ca599d2c0fd99e351d9695d3dc6462e97fce7b823665d7c94140b893c51efc054de99e2fbd28fdd14b80515a91c98254199a9724b94c61a4d07c3cb19c8ebabe8e3d1fe79488b4652dfe9c0a491f67094c6b0602ac27d3e8e59a6bae0f71147c1d6da1bdbf6cb046d5f7d33d07d225e9cde1d3c43c479ec8428192e2563bee28ff769ab87badaea5a9cb2478527cca698fae8bbf59ac49fb63b13e712d1bc2591f2ab0abdaa9d3e11d44521deb07cd5705d453de9339dc37128e7ed3a52a8e8f8ae270ff56b3e9aa27b596aad85546b9f393cd7e05cf82d89f46848855f0d46a375b08c35fa8b37023f32bb39202bc853543d2b26be7e00dc077438d16d4adb5ca5d8cc13ebc0edabedeaab6fb9229a9cb80e6a4ca9af6df21142f93cd4773821d122a916530cc504f05a0e789dc6b5c4d45c0c3c587944c4178e3685b2c496e4f523d2499a8ae5741501b48646f4bc853c7d6ea48356c717311763a3b16e1e8119f78e78835681cfcc4a1d88308e58659ced19cdcaf467c6383ed4f522cd1292b6d920e4a3e8890df8d0a0beb3729cb54ff02580747172ed7e1a816d35123e32e336c26cb58e608705a78c6346d54f105dd93b8849f1a13da4733d8a46a65b54d2af3399994de7fdd3a6f05446c6a8ddc0e9908c15dc15cacfe11061ac56d0501bd066dd121a212dbc5dc880b641977c325fdfc57cc020f8ca1555e45de688208b5d3533425e706c52bed8dc4a47d5dd7c4bdab9348f25d3cc78f00d0dd9dcc4eba2c731b3f2a7f822858930eb8f8a5b24c8ae664f3b736fa65a9d7cb44e9d7f287492555acfd877544a9b8e83dfd1c2c53a7eb1f48fdb7adf90333a803b247492f5212cb69552b7c4e185fe58c45a12eeb2975309a4cebbad6fdcbe1b25d57aefe23ac25cf7464591e8abb495b4a31bb4ba73d06e290a70055cbda55a452ad41dd15add8b1ce9f8b1158bbf5a5d183bd5280393ccd0e3a42d1779d5113d01cb1539dad3aa061b9e30093babc42a2127fe57d97063f7798610b747f02c495b55f1f4a03a38c706466cdaf789eebf82cca093071bea8499e16fa2c9b57c964415419fa240267b33a50031f358b83de58360e209e0bfb43fc69979a47a799f8a5ba91165129a9f4f59e2d30d61fd6787640ae1cead847455f7d5bc35eb7f29ca7441ad3964ea300e5ef3ebba2bac00ad87d1886c8cc178bf4a13493b29332a54fd01f60405551afc63ec6f9fdff2b4a75c95d80d8d12210192192c6ba568b2d93069b8a8956c10b867d5e442e179426a2b88b213bba8cc037687aa499e0aece384522a29388718309f40d5f82942e2a0f337296f3328f75551eb46ae97225411cba07b7e4892d3331b9a570f154ee6cd99293d4e7d8525187915f47af3c6b395a6270a009b0b258fe00cb0dad6f668d1b71a335a551ec3530321c3ab8a04085574af56c120880866cb76a6587993ef5350a9642e810d2f4f32cd927575943b6834ea1785424080958a12a918d49d2a6be5c1a84d987a5fb3aaf54d8c51aa439b29aeb7d901c9d0107f42bfd1833a87713aaa22570a4f5f96103419c0771f667c33e5c4d444c38406c5562f7b2c145ef83ed86bf8913f5f070f3e0d047c5fd9106249524af2ce9f384926023a33fdf978a4c6df9a03533b524166c5c83334bf89bf4937ff87a76981b750070583c7919014c5835284a422a9cb317cc2fd629746718f3726df44b1c9198542d805a578327e6f1fd548ec43063922866ab83303c1ff9275319f10729824c1fc63a4a9d9b0c89040c238079202a7d0ffb2b69250761152e280c439a2248a70ea2cf3a5a03139a7509e1e3f7f59b602039686a616b4f5f9205e13084a0715fc243b0b8f36239c78bcb3f5fa7867569fc3fdf250e8246dfd16d9601105480788348641dbda7250e6dd392e8bace96ae0ec21c21ed4497eea5da02408dc13a9481db8e0f166cf55f9f01bdea053be32c85d1fa2fe860ee6aa0b9eebb58d8812cff4b624c8a3c1dd43d41e7dae38e94ff6df8298a7fc060102b0fc378415461f26c79721b8faa27f2bffc059f603501228034c3430c865ca3def301c5462462777aaaecb279418d7a7b7d688cc9574cc3ca50094ce3e4393100c51ba8d026eb1888cc988c6d6cf36d056b4e181798d92b630d43b25cf3f02195aa0d4883828a997c9616601e8cceecbff89af12881a496fce5ca5c218c76cd7511add428eba094f587f0fd928198e559c1583e3cff159b1f98af8d2851ee7191ed3bcbabf45348451c26d16910c2932fed577670a07b4308c53ea14ccda7d415d5498c8ace6a6460bad15ac5dcf1967edd2f14610e57630a089742f8a9b13e549ede8ec60dcc72d5360c1dcb25d3ebca23e3467b8830cb08ebfdc9d125fa27c2e588d08f20d2a06632d94224626f56c524e9368bac3a26b52c9a6855d47d72bf04ec0044f52131a431468949f7251b3589fc7549a89b931e9df73ca42375802ee658763eeb567e0698187ebe5f7c15843b7ef6c2f9b375341ef43cf77afd621ba74be86555d996fe834d8c11c1c753d0789ba37669a0996e68b59e35ddf31edf2b04c571cf2433c5727a0b32b1d159f77c60e29e556bb81bdfa3b6b3346f88a0d55a532364d5fecba74da018e715d91c9128acae6558a70269fc85e1d904b20b0aef87fb5b1566f1123053c9dbe3db0d4933a239d53170007ee0119558b90cf63d961f5c15c6992ef22c95b022134317106c7d0c56a1036ac8e167b40d2a44a4c62cdadd5d3c77b74a513b7401f98c682b8b020215be21cd5111ef0ae699946c75f7bd5577ae152761ad8ba03fc9f2f097e265a379b954e2fca6575a2e60391e2e84fd160447724e743ba2571b85126a1c76fe514a1c3de9a781b2da681954eb25662ac8715f2e5069ee3752e78185ef019f9cdd6da7c7dc8a6723ec04ff8f543f441d2661d9a808dd914b8cf7530e1d6de2d74c6a9de31cc5036250388ee29851f0e85112066f01a04fe1ee405592049484b0793105390ab6a5dc7168210d89269914eca8fbfea500c077f28a69ce1a366a38fad2093d0cb276f721ffe4c59c1ba6126fa8ee071af515b3de22bc96b8dcf6a4ade847a01d7e4135292718a2d2e0add0384d7a79d3e56cfd25428d885e55ffae1f5556d0ee2f5587346c220e8003bf1a7916dc3ca915a4c8e71b2bc18b5edb5e934e8625bd7c7c29189d842c36baca0a7c06b4c1ba8f1a3579306f4caf559f016df8a5c5ae96a902a7c040f91e3c5fb9848df1702bf09e365c663061b02fd199f3d162d24164533affc4c8f6f8bd8bdf3b6c901e2178e43a27301a1c5902a1eaf1fb4f85e50cb5a2c85b4c02d20a4a5bb47b118072765f140e32963e40f5557b9222666ce8641b8bba8e5c592efdf3d38c801c5aaeba71183ee74c05d48de3da28b21bf531eac910008b6a7c3baba9e60560f036c32c16e6bfd7deb9d16896f5369d2579dea22aa2186a3869be52b3f636f34ce97c0de6d9601f8bc195c59288260b8228852f382aee59d7b668a1b763ddc3134f99113ba7afaeeefaf674025afb1db183dce84c915782a9228ca94834e4cc1f265b5fedb66504aa60d1cd82d548a830e8dea02aca52ec47fed7cd5d296e693c9f7ecfc67a80cb721aa7419db0ecdc2c08d6ec1401428972bdccc593043a5aac9bf824b70ca074d7f63aacf9ba6e72c9a248f78753b509971f0aaf4e79f386e7c1811e8699d46217d87a31d101becc98f8f8c757e510dcf7826f05b43f969dc401b814051845c36cff8c00fd1331ef31efb95bfa324c0cca391282cf75258585e3346cd91b21fe5da95ab2caf814a6784396b7469f4acbcb3603d5af5bcfb15c84f3bf4c6754d404feae786d2f176fe7783effc714a0f7910cba6f00bf6bc4ca2da359ed3734c5f28aa257b84e3a0776281ce2d7902a65c96457c311c89041abf41fc61ecf7647f0712bed908daa0021b0700b1b0c68bd720bef443c118f0baf120fe7c5fa213b5d23c017cff4692b9dd95df857295628c29cdad5c08cba7ce5ba53514834d74a4b660f9f1fbccca1e83e10e89ec0578c0959668fb436e51189053dc331d42a1607c679e4090c6017192103872cfb02f300d47343d7ea10117fea905532dd6b61630d189c501325e06b64d53602cad5aa31e1fbc82c2c8682fa16dc798b0c73216b402a849b564a524e27e620e0855102f3b91be8434700030511c12e84a21d75dd77f95f2f05e1de40da2578d4875106cc53a0864cd573bdac96f65b36950b00ab1cb04bb2e6edeb1f6c4ba90ee0cf09bc347dd955379566a24c742f3ce626edf6fb38ef185be73ece603ca1d3466676a39d692c74f04436c495d269b866c09281724f914bfcf6d0d5be93159e8abc18a72206403c0b50e5f271d7d66a047584f1039157516e222941ec506620025c6981f4a6585424d87751a7eb762dce3a2ea1207608e229a3c72abdfeb845a2660b28ad6393c294f5bdd3ba0527022580a06847c71c7d98f16454a88799e90a43006d69ddcbafdc6a5eca74524bff1002a2ca910682fcf5d991e3173ef3fe1fdbbdde64fe6b2a70ceacfccfde4aae81e146ae88426669d7a754ef29fb52315b25c48e2d84d65d9bc3109bf3c852af1a87189891c9e3260989ce8920dec1fcc835c959d088fa1b5483dec5a5fb397cd273d77942f7389a656c00fec3284ca0fddedb3ad337e8476c8b0eddcef591187079ba00a7a14e1405ffce9f50580e6aae652b7f12c1fc4d514c239bf2a95559663cc0fc85be6c58b023bac754404064b778205e52d894c70d6b31377ad734e5081d885060aca23e4dccd3403c9d535b8557279fed82c690aa12818c3edbb64742ad8f092b6046be6148ccaf2e0363c7d85330eee4afa7237802a6820221863e51e3fd6f9f5c3989db6ebebad5017e3490e1b5a9cba19b40dc91b49f9e914a4ee728e6a3213f33e1c94be3eaa61781603e32ba41ad8a4c5afd5cb9a9f3579e4eccb60e4f8a7739b1432a81a63fc3b5258f0e791d65c7cc97c94bbece688256fe0bfcca66596bc717d75338d89925da126fc4b43e28b0c02d6999af0c197f7ad3d15c4738aba0092ae1952f60891813147fc45c8589f74aecbba9a0827c72bf14fc06253b1971f276c75eb4c1536cc634eb220177d8035cca3cab29519b34cb2d55100f7498bc1f79da8533100e7cb7e9a87b35b5099955e5b47300d6a5fbc880aa020b7096a66bfd34ec19ac5467fdb43552b501ff4a4de5548a9385aa40b3edbcddd0c6fe3702c6137d40cc2dc28974692ea53048e60ba53e777e7ef3f4ab010c57b996431925994d498b6d43c15960162296a1ccd0a4499506644b98dec60f25e7e3ddf029ff067f1b499d4537ee4627537e3b3adc02a3f46cb0588341f116ab5d428cfcd860aa4c1e0d8ab668e0e01471d9597e7e0c7674e242dff7bf02a161d79303d0267d6ffe279dae4e8d0a9be9d9e6c057c8678b79b8afa40e9ea24387e2a217f6c2c4a1e94933567a43242d3a9856c3eb5a175d445abc9a8d09a7b5c586b22d8d0f535a88b6c64b46b4c2f7206ae474fe843962056d41c58a70fa86dbc83c875a6ec6f9cd9a879084ed19a3999aff795a996c9c084b75b33e88f5f374fa92e1e03193c6e45a02ffac065d5ae1bd7d62232c4dca862914b2aeb724f14f498f11c528cdb68b16bc46482c5e5b3d13634d3ec8e67c3e552b4664fbc3cfc123082dab5e560c1aff0aebcb9f4b6ec8dcf5b1b231baa59c32b5578ccc54b109e43e7160ea7207805dd334c63cf758e04362c69d093c1b68c6ac2de3bd707cfcd8da8066765ea5bdea941139c0db092dfffea54808cef8a232694177ab17d7f5c97289389347b83cb33dc72ef157b298766295c4111f8ff25f8f1b38ba00af6074eaee86b17e192db2932c3165eddaa1ee46d355232ee844456497ba8e103a5f6e611e7fe72f900798b31747a88eb6800d09bbf09d34bad628dc7a1b00e1f81ad874619b5f1a8852aa0aef05fbb5b5990e672ab6332d7a0fa638c14a0a0ee024549459dad99a125d15af537c977802974e4944d1000633b8fb48cff0945154ee69047c5c1050e0aac8a581f89c3447aa458d114fb42239cfbd132abdffb87b08e1e15f3354e4944f12f4e85037394897ca3d0a512183ffca8cbf1092e98d3abcff28f118a3a72a0c4f6ee83db674a0647e513684846c39db1c6d4f061eb3b6a147be006d31a3eae30bd86082595a0f136d6993e0cc071c81c9b9112528383107648ce3aaddb6e7be075ba1f4012c601a514368008dd85b2ea506d8719b805112227ff171b2a6c4aeb290d42437939b2442592cdfe67a48ea5227388026a0b21283a8f870281d2fe97973738efb8c499aaf3ded77fb2819a82efade8eba95330e93e2405fb3b11cb012bbbe3a2197220eb55d9de7d63af674dbc1064eb63ea6facc21cb214a1fdf9d8e96f05c7946005ff67294a825168fc654335ba99bb381fcc4216b76da9ecf19989e7097df11dd7e6a4915717d7f8b2d924c35506e02318ee603c74061c9fcc813ca58c1af09d21c4ba754f020bc4609b728edcf2d7c2e4a3248dd5405719c9e98df80bbb63c40c8e8bb99c233688a6dda36e873189e228c9574d37099dbe2dbb8f318b86af32aae615e67e46d290b256fd26a398d4fca71691f8ca390b9c7af221f079b2e02e1072bea6b05be4bcf656704ff2a980bef27498ebccfe51e289a86fb44a365419be647ebd08c180e2d256aadab69c3080a499f9030dd9b96f0779117d964c0c8d0936c88f132cfeee15365592e46daa6f1f5c884264af51f876c169010a69dae6fbc3382f048de9bf61338b73f4ab5f02d2ca32f84f91c45a7ef25a34a9d4daf98d36a26a1592cfc366999369f75d1fda2262695fff49a071a14afa7bbbe72385e9be60a9b21df9e09f435e88c09b615185c564375cb2d1433dda29d0a9cd5eca59376dbe4ee6b4f467e2296a18aa4f81ac02213296990b283a1d36c579e8dfb8f846e4330d139c598fd94cfa777f3081f2bfca1cda029e63da1b946f213f9da70cc6e29afe479444673a73ba945a1802fd87f7f299165abd1499c79da2684f26c901677ea1e453cf7a39e774b128905eee31cc996dbcc17c040c9359a9f1bac8dd063436c783b225e722f0312bf93730a1f5cfe16de425ed030b6065e85f8fdd6d7734ec1981d52205fffe8daf6d5224b8137bc05981ea3109d4fca1be0c810e99307cfb8a4e131f1ab357b785ae0425e8868d71724b79f5a71cfe61b8cfdd9327de5a1431b1bc77fdc804339982b96e026d4ce8ad1f53cc98001121e2f5225b4fb84a22469deab4fd2780d8e76b3703d467a465634aa08f79f01e34000bcf3f011b009c28b42c75a45111ca824441c147a89a7cdde1b242cac3e6443f8c2dbe8a20151f4962d6f62364420d65fff06d5f034d2da4b2746818b286b09ea7bed83fc13b256318e407c81384a7063382ca1f8bf6bc4e48517fe08c6297b06d0cbd6019414690a29fd30cd9c4342854e4b67f347c861beedf4b02b3d424cc0ac0a4b78410952cf11b4f2166f90f053cbf38fd104af7161ee364fefd5211423bbab5449cc5e7f035f2a2b1bbb313e110d0ee4d1b6b58d44c1c3de90c0fd0beb54ad1dc064b6b787c8ecce420137a3ed3417039de9765813397e3cd8bdb4d0ff0a2b7d9a6ca0031f1950fd96f9012f35f4973175c656443217d9fc8dabcbb458d9f112ec68a7987a40ca812b17fc5bd67f6ca70d89df2fd88d6cbe9f44f2f924f355860541ae6f936a94a6fc65b636c0516b10c5029573b44d9a529926d1ee84abaf68daacb8d4af046de4cb1747fb7a8b9d23052118b534a81f5bf6078bac85b7666cdd3e3f5294c198a43cf0e9edc3279d288bbafca0caa7ba44c50d432ffa00869c0d3e1a859c73bef7c9142888e02a6188e5aef0f762b117949480a72aef49fd642f2a7a2bcccd4a20a0080b249aa1608392fdcb81c6249d32d21e83c2d04c65f5542243e052756976bf7243471efcbace1a614f4ea7ed4de64a7ccf7a5900212a51db03b34be2f41b563ddd989fd079a732d01569dbf802727ab65aec2fcac2df7a1b7cfd05749930a77644d4d55c136fe5aa47a2dee5d9004a373c0136c9e2385c666fd415dc1a4e4d3f0061d313db364f6294f60f2f0ee974bb3662bf87ed336634c4531f8b3d051a9fce19790eb924b833ebe8c045ad312ee7825df5b41d45516708d2f9ed2831f2ca1739cdccffa17a318e66b94011c975c1721d8b63593596450b23d0e9b6cfcbb9ea1c1285abb561b1cfbb96417c8b4f922f6ab7f2b0ebd44b9c3ea59178d252b384387f44bbe22e05b00ca713dc5e67367f98fb8cea641c7e803d7493737022d1ac1da6b41f48839342eabb19687401211ce6f77d45871e878f9d2c18b1b837d4611640dba82e3fcb827ea1bbc432541546c2bda81a01879bb2fcff748711895c0ce8d47338c150faec01c85fd8f7b8707f37707474b9fc378479f3f5b93e593102acce44de8a84fb2c62c350716904f1ebe596ff6874ce5cc800a16f6af99dde74494af689128fa7b4b0ea2d2b986504cdc4f64ee8a74462ac3b51824b59751aa3191bbb0e70af3a16a865604df4356e8b3157aa03b55f192b45f72d95fc552c96e033a827c6f5937da44d6b16c78c5d43824603f495ce7d309ac420e9061dab768eafa78c0f7bc4cf3e57ef391bfdbf7e74aaeabaa204e8152e0061a6c2a71be0e8aefa0fc6aade9e994bb5439b7ba8de53456d61a84d1d59c867e50ea969df1cebd011d801e9a3139ed3bc2d0524f99c2234461e22545a408d539650b381defaa4f9a35106aaf89c038acce3623a0e9d0eeb3d3471246e03720a60b6c748f3368de922502319eb716bd260d74cd03a364c97f76bcb97c70018dfe9e26f6982703eb3e3ce831deb0a2dacc92b5d8576e358da850fb49e084a202fdf5d97f57dd4d145e48068c85a0fa46ab1836e560827aa32802c61544700fb0e0a97206ee0dfbd650645e99c0a686fc7b5f2d9fd95f693ff61dd34ff208cd4f3c26eed4a6267dbf574c3f60e4aa680e741271bdc522d21eaa5ac46fdce781b6c9a380766e3ec3372c75f2c57014a42735d20ebdc007bc41dcbcc3a808ddbdd24f99af727c1e42b24d9d9505b3973164e6068ffdd8d172f8b1204a558a34d38a743e5cb88797a53bc4de440feec468754caf0e2c341679e6840dcb677103d87f343db996a5996a20e60af6355c6392af3b5c90ab0fb180c9a20960d0e07efe1df80c242382306ef787514f4c186bdb9a514f76cb587dd556e793f36878c9c6e725db870ec5e7c5d06244cc3e4e6d1c64bde84779756cddd44f66391dd7077618d51985ca45cb8010681b75d7112f4e423a217bbc403c3e4432225afb5356ab59f57109fb3ebdcc919dba08b8e073123a789de7669b91a50dbdbc5b866b23c783198f4ba3b555c71f2ec457c5974f358a687724f111532c3d9ecf3c947ba5c1476720ff0fcea5ee031a0f282ef3e319450b873705f0a12d108442166e4494f4d82f2d89c3288c7b7ac5177037682bf9d0e0f404071f1f2dd1848fc8df11f88a1f5be4b4fc098161b2233d17c92acb861e5e78b83d2add5c58dfe591193fcf52413ef7bc7fc3102feb4c87d8f0ccdf64177626125f357470ee2766f9f806e8ca4bd79e2311136ccc045bad10ab2d691de1cc6399433e4b1f77b2eb47f3f39d32a98f2c96a93b0303c96fd8a2d8ac0a37825f07da91a8d6a7a270f0d43717402620713050032c60267abfd294e53a0a9150eb65445455e32e6ed4dbbae7858be4d8841e28ae254101843e3f887e369e7668ac383c38924ea08a1eea05051ac7d754e87324c60e805bc12766e826a6c7082d65a9e4be20c7ebb4511f6a642345129e55156d5d57442846aa5c83387d82cbcd64664cb737a171cb1b6ce97b174e37166aaded1ef2358695be1c94ccdb91495f6692e1114ea21bc920e6380fd997057788767c30cfbef53b81a9f2289eca0a4804b048f7150b844cc93e49c3911e6257f9a3ac2ffbd669a9064ff28556c04215c11ee35d110c7b555b0ddddf12078f2ec44d6d95e3d0686098a6848f3c6a78b55845443ba6b16ddfeef16f8c6015328ed8d5c29ec088ecca5dea9d0cd9b68fa4200671e553c2955620e651ed6fb4efef1846a70878639ca22622116f5fb8b7617b348dd54b60fe3901027444abc18337eec0936a3a880b01a74cd97ee2be11d8972df3af7b2f2d384b22fc6ff64264f698a3d0ead5aa4e63d913c93f13bedb0ba8a5f7af021e9db01fc76c5e4fe944ab6b7964baeebdb6dd3c056e20b70615296a5061126ee1c6f4947ce69e08c4b99c4aeaed95e91b99aa0336c2ead865cd1e507aba16d2f88fc695a47ddf946fe0c19f511602d98ffe48b51ffd11f3353dcd139bedd76969ce674cc201d681c2ebb7fc5ca21e4bc53864de4ef0f96c8c1513cd01e26982aea0bec34c8791f0677bad5ef617643321e164506ee4c16cea4a2070bf64b42002c34866ab19360ddc3557576f9add31d6feff031b49eb6e490922dca732e7a368e6b131910092f574b5573760ec0cf788a16a40dcb9bcb91e2e1bf455e3e310563d0fc8997bf67b76f03b109e46e862bc27da116018ca32887896bda74a05ea5c111daee99100b11665670fa740cddd8278ca3f9eaa110385b60f11db22479dc7c6cc85421681278dd2200b23cbfa8fe618d275137688d335111b2823082cb66c37f76104be175c918f9fdcd86cfc34cd8065524ddc8e741195f7a9785b8b791d996dde34e1ca109887ee18def52ecfb4df4b759483442f4d0112a357e35321dd1f325e5e30eb3c97d8230d1e84c5ac2295f54f12608c78391ae7a69f18c647cafbc20832684d3c06f12e8443291b8072c4c99e1b8cfc1720bd5e19beaff324ae5f874cd0af84ce694d00dd84bf894122bf6a53199d2ea8057db37e14e9a057be7a7dc82a36a8b50bb9243e9c61b9843cb8867c50ef273781088640da142595f80997db8b485275eae9ca772ded5f9fd685ff701d2ed3314de89634274ffb921639ae2b3b2e6dffd395ba0d77c0722060bd2d94ca323b937e2b8056ac6dcf2afa5ff00be75fb102e9e7c947066001e80c7a519c3503a727a3df72ca339f8db338a7a6e2b974d68b5e4a2f75cd283571ed90916b2c619b09e3c9f4102e74fc9b479171f05676c35ee8b2dcac462c8c223fa371d7b3c1fdbe4b04d20ec20075bf13ce68a7d1fe73526ea8cd829f32d79e0b1eea0ec7b7afa64fc135f9c8cc002d2e2a90351102231ec9a2962fb96d8d8f4891e2246ff9130197047cad5adca757c74437d21bc9c805a837a4b62636b5149e15c02e26ebf6ac42383ca48cb489a5c08820deb1bf9a309e0111b3d42ea3cdf09b581346ea12c69a80cf47e7b427fe0d5c641ed1e23538b315cd23d267931875064a8f537965db436f47269a60d6b6e1464596d9179e3c82ef4851c9738c34062613ded7d4cb8298c60c9f7a96f4b109bd75dbb9e2620a1a9e8954c3c68034ff67fedb3adcea225a5d96a5e03dbc81934f53406b997f454af585772711a7b3cc9d3535f66c80d2c12cc3e3d1813975321fde4493058b784769d137e9ce2a4a66e511f2c327e93334e40cc3ea1fc6f03c2aea330ceb0dc3e340073948f5d991cbdb0d2715dde35a11949f013bbf3d4d90749db3b2849907eb584edf1cbd951787be304de7989053b9e384ef79278f749267ab4c62c946a260eb9e66fa223992b44e564ec5c45edc0355c3c0370a9524e4429ed68c90cc30d123bf40994bd14c25a754510940cf2ee9c14630de2b52efb7a3b8c7781f2ec77c2193a8a0941e37eca682b2fd337c74a4bb12a0f1477758d9759f3f07424488568e1ae9c706c6b08ba1b8b868a9146b9667f85e41b9b7664fb433d04d67ff32bcc966df0d2044ffe35ef26bc05ce25917c1b492822e9d4de0064696d9df6bd8b280e1dfb7610715349ed3ff83da7639edb2896ddb0ac3be364a6369e6449a0ec7fa322a11b6d66a83c205378391d746bf7e12bbb1c7aa988fe8c08be9a0d793ef08a8f3ba56f32589d7a2303d665c4568616a7e477a2975a1fecc8ae785e61ef148056da1dcbaae4f2bdb96d37bbe87894292dde0eec39c426a342190168a17698ca7ad319cee9ee5f26a0c174174588ba1b61959206ed371367f505759d6481572db2376a285d09ad2f92378797e10881072dc8463f4a2e00d85778c46642a0895f65b071b1803995420fbc871ad2a698552a936d99e7ee844b306c450cb021fd073532159225a4ce29179c47c506b9429cb28dca138eed324291084cbabc2c4b3c724d1977d463dcfdd439435132eff08401140358b5e7abcf00decccd5df4012ac2530a2990c6455664eb910c589bd951c91a8c30c7eeddd785993d835d1000f87fa1f046c26fe7a034b14f9beb1b1e89d68662092e629c149e423a359f7659696f27457496e3e2289c1d84321e371dcad42e5ea4cef279ab217b78dd2df8eaa6586f08b01a9ac77b200206e079f6ce107464f3568d586e9375f2d383a182132f99ac15ed8c2d15b75cc4e6c8c3148e6e3699c12251a83eea859cbb988ae03ddadcbce8b49d04372a319a446eefa6ee2da51c6342519363918aa982b18bc5700a4a5f8a5c1a77f38bdfc67fdb089df5380de99ad73fd168234569e22957c80e214b52f698cc912a0fa817c4ac45cf732251e4ac8180c015ddf2728f271a0bb63b40ede29c23487e5dd5d7f3b75836693ac86ce070aa6def697a6b13062f5e6d6a0822a5143a14b28e60ad60ac30236ef71e96dcde405d68b3071941b79c0f70cae1905a78e7ef9c73c4c167743621afff5112adb2488ab866e35af5acbd6bb9e0fd2f8174feb0e3e3dca055ba9429705d6c668d8ed95c88561c50b84e8fe5c69720d7eed3a83237963f461e8627a0b1ff92d492842afb7a14eb436686ce71e43df5b7fbe7c4948ceefd6dda4509c836d46d619f25690c2b8cc1f2a69a20456607c8da030ae6f9508d85508c22eebec9e79505504022674a2a9ffa6bb1e54724326aa91d41883c53648b077be2e9e5864a4d5b5bf29bbb283db8a055020c877aa42b08a957206b8b547f34b5b692aeed043340a3332b229d6824575088f84851072afbb648f8a0ed3ab031f3134107ca614880eab57acb8ff718a2d23b6b9b0354f76a1479fe00fc676a4659bbb04e03bebc62c60ad9f56b6d4b5e4c959e430947d35a1f75638c200c71644cb4485941e2756dc00f9df4ea80f8ab3f86af5a7eba9481116bca9b7d24b74cebae16955fd8ec94c1d3a2d957684188824674aada8da4f87a5d10683a8860a50e1e9834c6ff5544dae0ab7be4280a713ace8cf28b405f8ec4269767a74649e12ef07b5a19050d218c530d6c29ea1b18d2133cdab7f0fa43661851b6da737116e2dbc401d208b2453be61488c657218efc64e520466f1c21892710ebad3dd9b8983ae22c92ab7004ecfbd06933ad5d31d3094b0131825b10499aac357cf4908b374efd10c81b5fc939b6c5a3107a2ad3b5f4084ba4cdc24d13e43c57e2ede44e60a3bab70e71f709c4c0a8dabd805adc12c73a9b01e9ba9f4aebbfb478677b6f6460bb135297dce487435f47bea5e4532e3182be4d2ddd3f2f06440a93005e4abd6009eaf521242c6fdcd1f2eebb3d5dc853f591835907b414ad9b16287f084e8fb174dc7a696d70fcf195d4a511c921dc79e00659595b6550edff40083121a4c8ab8ab7875be3813e1c34e63877092b656882cc976f995a34cf117cc30e30844707e4164eb91bdff4c166e262b7dc128b2e87620fe26d3fca32a9bad41a95d1df3ce2881bf832416b5d6692a128c3dfa0a1b31136f669b4dee3ecd1a7363749172cffe0787cb6870a47e700f2259d43515406836181ad5776a8ff3cf5915910f586ad919cf875cfc3d35a3f814e21c9f4d921956a29a1ecbcb9033b54a817eb0725fb3931db55a027a8fadd840dd7e0e0c691a67e4c1adb61efacca5ce07ea28bfcfe5112d0e6c896e5687b236ae1f0c949f0c89ed968f07fe49297b2680fe27428de7411d3932f50a040d2dd4bd89d172d49ff3fbf993857eb30d0e19763662ee4f6add3b37e273ce65ca70b2693b88e508b53031ac7e5290d114abdd77432c2f8a7636ea85a2061337365374d623ce9812dea8d0fafc9a660aed715a386562846ed94a55f3868e0a151c186032f68fe65d038118f1b94e1f8fc3ce80f73af3ea65834d8556f459e9929086e65b19a44cd97081fd46071e82c841a3dcf2d76c1b23160f54ab5cd0912bfa3a23af989069580d7429db033ccbd7d5a3f4fb66f258b8dfabf16d52cbf992472b16cb8a193456e3c322d5f736984f7daa2fd5b0e63d3c191796954326321b8e94766e9644a5f79b3ca394bc1801a8abbf45241e6a3b0c36dc59030af7e385591bff1a54e6b622f888d034051a56c7c3d650ae8431f405021ab8949c8e750bfcfed5b3f1bf58e174e9e43f295198121a2fafe3eef746207baa44d77e3eac97d47a901e7cdb769e9144942a282cb7682351a744af2b8ed865d21ac51a3c331b63ea5ea00b35610ca36a66e9cfaa87dcb546d6e31684bf197221d16141a81455d64e628a8677efd0479cc0c47ba845def81d7e79d86864652099ac6b02ea28c40d10aa366aec23a5326b71b5e1fd66d78b813324008538efe2fff289e51c461a7cb218a7c80f1ba0869f89334564c112251219d7d849c944d57614ae5bb442268e24c9bc069058122b911e703b2c24c3e24dd65bc8bb350eaa8aadfeada52920d779f13e11b2687d73ab80044965e09268789a6c090969da3b0cada66c38bbf1995368660b35a83d7ae06a7b843ce2bece287ff51a02abdc6b378b9d65199ef0a72d20219495fad061224d241165a544a7d7df22322786e74f59199b682bb014a98c170b1a39e52e9ee645184637613838b0bcee7f792d0e03dbf492390f1790c107a2174864ccc009e34995b029074e0da5cb58f52282adbb03e9028c0abd48f6d5b7c9f01f98617ada1e93d0d45a79a2718f3630cb1e3c51846d0612e8c08560b304fcf4031ae96694572056b24a07159d088bb37ab4d38d0835da51aa8c37e30f5a145d4c1f95f6dc3df41cdc7f89ef4d0f2b5a280998d1ba9eb8412d2862063671b8617458bcf0b2f0f1ec2812f7f2761e7dfffffffd4ff6265bee2d654a29052f0909092809ce0c050a43f9ccf8d1c44ddcf4352971539307e1f0516742ac3d6a5dbd42724b7dd9fc3ca8fbeffba17383d983d887bd51c70d75eab85023759a5d17e2f0e1e0416ce54aa7ea1eb041aa30871d390e0a6a3f053d67ffcb2891992425e1cde6264dd3b4ef4971d4cb90a3529b73e0d8337e4ca0107165e241dd771772538bad43863772541f018ddcc568d62eb1ee9ba29a9aa2a2fa888df6a14bd045f40aa494b2e3af518110203cedf9c9987f64f899305e3d5445e1ad90c4a9cb4c9849163281ea611f1c877084a96cd42d1ac2b6d57449ed1f4965186973936ef5373b912d6cd01622691af600e23853bc71998a780884890e15deb8501cf3e9130927c0a30f5b1c72802465044a9850b932f11828bc02ff0e063434a82b266aefa0f6e43250672797b75f9ed05f000b51a52376c09efe3eea3e2266ef9fb94e0cade383c7beb277cfe33a23d5afff0e9d11eb80e13430e71b9c4c46dc83ad48791ba31fbd1a43e37c37bffbe272409de73136a845b01d436aa2d322d890b29d76f2203e8a2151a49c6e9edff9ca2a223b5fa444f3f0ecfc0fcfb42cdbf99dffd1debefa1d2794f27213c2d884decb6f0731d3afbff7dc04695e32135be11edc85d9c94a759b1f3d1e48ddc426ec02d6bc0b1b74816df917e9d80eac2316557301998f79ffde52cb473794783c3ff2110f0fe223a46ec23d3ac63aba466a529d06dc15c720d6b907af8e7ef758cb239a221ec4aabdfd349ff0003ecf67df4478be48892cdc164130ccbec33103b59f871ef96ad7d91d3ee1e19fc7860f79c2a29eff4109d80b75e67b106aa05977f5fbde2a88664f5bf43e87178a586887e71b7cc2f319f8c4033c3c3c3cdfe11310f0b0f33c08ad6a084f58d4423b3fb3aa31e11111c3802fe048a3e24153537c446b67db59366512de8a65124edf18b1947e32cc69f2be7e75de56bf9cfd59fb6ff8851e73ee5e1385c73e4516575cb982a972303844fce910c77149781c87f38437e79cf3bd07daf371e1ae8be33ec5fdc671e17844acdc770dc4f5d4719d3490882b8d3571dded5f778f66d6b1dddd9e725f9d205efbbd7638f650a9171cd7dd3dbbbbbbbb7fdcdd6def6e6fdeedac05dc7577777757ce4ca3a9996974cb34ba750bd26dbec875edb7c1d1aca7af48a5964d2a25d5b2d9867b1bee6db8b7118458d6d3e7ba66f681d9febb1b11397f58477f90ae1b4d6faba3b5acb8f087cae933ebfef17136862e071151e1bbe1e9f413e9d40bb4ce6696cd9612bc5977c90a2c5450c192153c5802133db0024a18fe194b4e9bee54ae7a93744529cfa49487aee88af2d015a53c5c4ab2945366736bee91fdbae473727e952bf0ef6b85ea95ab0ca0ca5f06d23ced3dee91bd7c0d7cb1454dd334eda56a487b5074e2699ffd1845f65ef5e4d4fe47b714c3355442fa7f34ab8064ffeb929f8121eb604de1f5e414eb90bf2579628b5286485e5213545ac1e447e218c21be9d10976000589082780810410d60b2a595260858923a27cb1031e1891a9209531690172d5a985b15a9af2059309aad49e9e7c8a55952750a8f2fbc91be9aaab02085594f09c78fc19674870ce3a42c2ca61d3ce5e526609ca30c489976551781e645dfefead0d2a00b7fc671886ef0faa3f0c3cfe1838d411c22f9f439db9350b695a74cf62e08d2c030c91610daf9f25a5f8f9fea19c3635ad8a25740828a92a8c84d08670da88c888d0429b9060c6b42a6210845400115332294700e19222796b992081028a60f2a2601a9c24555125081a58f0e4ada50ff3c34fffb444e07575ab40614104d4173e8881020ea0b4a0700694127c48c38725218c98c263eed147abf6be1d3e2cd981ded7a2949ffd942c9d78f2b746e1c9ae6357bbe31eeb7d2357395d7ede1a9ef410c90c8e81100294cabf2f50d58f2ac74ea344a5cb4a6e97fe3a92fde55355551f1d5413eb9c90a830421dc594142a3fd4714775679f3ae006f81085038fdd3d03def2e7a4e598f66662726a402ca5c494b4af557b47b5796ef1cbbbcccbbbee2f594a29a53fbbcbe94bf8944b48ba03954ae876ce5156ded1d7dd7d6ed7ed673ea1a2f639e62d89f1111bcd1a780cfeb64422146a9af1f33da97ec8321f7461fc90c4053318021b48b0f1c4162ef025234820fc208d0dc30a2c54502e62204608360c2a94e820a2a80111413461c51629e613543cc992bc20aac9921c3861841c2009c9d45da2e2045418415997ec52aeaffb0fbbfbe24ccdc9a5e694bed3478b3b7d939967ef99d30f86393316acf4f9b548a9d47c6a99bb53f7fc05e27f546366667a84d37eaa25993d70f70b7082f0f8a1b668f16056ee53cdd9c185bd9d7c7f22d520c1db976afcd775b787fc662224b23e89e92c8085e6b3d00c8f3aa1f93a4160aa3f4cf5704c529f7c6086d45beeee04b1723034cbb22ca39452174cf1831a34955fa3495514c10a57f9b31774107e90aafc13092a5e9040c2a0326f7142e5a5f27753073989caef7d4a4cb85229156b4e9516540e42f570fc9a9fd54032955fb008c112a1a5e2a3eed2882bdd3d0c222485a12eb8a89d85d3c3f1abac22bcad445cc765ea2534163ff6c5aafc3204d9170aebe2e7df262a767fc0b053f97128eaa0258201c870aa2cb20462142af38e0dc76d5a29a1b0af7d16703b65f33c4de129970bed7aa8bd7358973fcbe51ea52c5072994b1135449f2975dc2ce28e9fce615ffcfe1c730846731e86d7bf54c695daaa20371e185eff4ef94d4260d2fd532e9722597cab8ff53378fde1f91cfe04d90d77f8ec87496818d2a2ff0c59a101dc86212d36ebb4dca1c8779ae8209ea45dca12abeeee51aaf7cb65225c8a649101240da4e3d3891cd471b354c7411d774bf528ef70e4a3f61f4a0668a0558281d2376178232321212121f506161529215f7e92da034c93d0f65c4759ddacdab1fa4383194461243662a7f6b3d20a414a93d52285c6af528e924003a1f954cb32b044a7a713b51f072ee30ac99be1c849d38974007054e0c9dfd1416c44b776ecf0f161b1562b24a4f1e767859eb61a74eb679b81f7c3492218346852e43b25fa026fa49e5786a7d33a5078d5078f1778238fca38108166566c70813ea7d2c7f3993eddd215e73b28579cd3bb5d91f967bef2ce8afcddb6f85795c70fc2aabf6ae367086e7f59e342559875f9b30e73577f1fa52ed5ff874850007649698b231dc5a4388247f5e75e985e411d3b987ded7bdf60e99ccbcc54db750791cc5dba31f306aeb7e6fc49837431b8658d3f9472f85e1adeaf385948f0ba21b4940fb2094b5a1c5551a3cb4c428225253021e1042dda50c284c2092d2fe20c1b6981b0c61426a2a8c0093880811a501c21460649218f5220b865ddb4c06b4e22c47df645a9df3e891038c45beea4d39fd2e94f7d12a1a26d2bcab62442dbe72d29bc19c6accbe927e4de7b19702a9e0c9d0af94984f8a5b7fc930811f156f69fb7fc95b0818b94b0617e1616cd90c32cd4b1613eff0c89784b4847fefc2a3cf0c75b2ea512549f413f713390992a85711b55d5811ca8937d12213ff256160e31ea286fd14f228484236909a698d00a29c14f7f8557c286feedc322ef3bea578876a863c3f6fd423a94071dbd6a8067ba4c7e5405a5a19199c42d7370e3c3dfeff6d53bdfbcaf9d97cf6a480fd3d81e9cc43ae4b7e49dffd13796ec8093665b37b887f6f2c66fa0b7e28d1b52c78d1bcf205df1c68760b7e28d1b3f321255bebcf1db3be8db167e6f7f23e4a31691963012d3be364a299ddbb67d2f1fe6c79eeafe3d4339ccaf6b1f78836907eccaf2c6cbf0e5f7dc06eebce83fc6e0f871ab39defd7380384016c89f55bef1db86cfe0b8559877d5d08d23620dbf55423c90c5194c2085cf71770394350c290cd34ef4f1ce55439de893fd8f097ec4e1286dce29a17ce328979a1af33b6683c6872aa79cd27307bddef847b51d1e77779e2b4c13e4df9161864fa337f0805ba90c2e77c04feb181cc51df0d33cb06b71d5373031adfe7b8e763facba626228bf116e9449fc49c2d37e14abfc61256cd00c0bc5c43d6e60daca5032dcc03d90b00ef9854c4c5ac73c2a21abffe8af7e5534d0ff543330c8460cf5c37a16615ee4466b78e34679686407362ada818d36b063207701398a8bfc22483c1b703ceb7f3497c4f484373253124331ed0b2ccaf13afcac67a1acbb01f67c08fe6f20f845907096653e335343f33b7f464ce13371fc80be1fbfc7ce8fac9aa5006edbf2df0177758caeeaffb5aa8b200aa0d370870682edd0ff5441e8f3f71f1ba578c0aeeef473be2807eb7960d1ff582c168bc562e560e5c0f139fc7b5efe4bf0250f0c4ec334790dfcf9687a402f07b8dee209e98a86b09d704c5257211bb528657e5d270cc7233caa7f4ec838e11716edd0a227026f6428661e3e70f0f8f1791f8e276fe48e7117495ff33c1c373734a43720f736e098a3662111d780e357679e061cbfce844c0c9594c450ab4ff4f91199f5e327036f6c26947a1eeba9b34050a6004419b2775d53aa5c2c90b048da97d6473eb4230dcf816c6c5f3eb89192edc147ac43be6cb922d3d03de297c2470e76c7806ce5a4265a9453fee769cf494ef695bdfc1e9c6f633ceba16a39384cbf37fb1f9e038e3d95be0d387e5b48c4ffa37b3ea9276435a7a38537a5140f62b54f95b3d2df2143d1fd354d63f99016ddb5a11d2dca9faeb9bb873f5be53bd287513d3a3b365fd26cd3380c9a492dd39848c76ab93e4052feffac06daf9d5cbf769209d97dbd39ac7f9554991b23ae44f1b2d6782f46dc0ec73b80de4ca03eee2e01c58ad9353d37eaa86e6c3681c27b32c530dd1988c66dc38e0c8aa33f593079cbfaa4dc3c18356dd62a9fd9864f5dca986769e53694f44fe88e3959f06e7573c5b0f76621d47583943783684445a944f1f07dc791e50e7370e6c8b9df8e504ae727670f1564fe5ea6f562b1cd8487e28b32ccbb44cd3f833d6f8358d5552ee93012a0fa932540efd351b671bed1d84edaa866cfe47f37378e4a7fa3bc80fa312e2cf6f03f2fb88dfc762411d83693f323bf1b8789a114e72a285fc1ba83dceaf6a933a60afc0de01fba88d5a94eb922fd286ff9ee7a438e1f4c0e3183bedcb5f7e0fd8f32cb474c594aa42dda5154851b9addb01717e05faeb8039dc64555936e7bbf365b2cf62f3733ef54c56cee7fce855999c9f116bced36cdbca79991cd8cd4b1b4e4543f60cdafcaa82646ff33f5a03190a47d1ba09a640afad0292fab9deca09c7ef8bc0d7e12f4a22d4f33cf43c0b656fd3036adf420c0ad13e87172a7fcf73cf3bf8c4033d3d3d3dcf604f58d442e0ab6af8079f9be0290d84f3f2198a9ced2585e12a6f8f6d75f07b9f037e20b860e76d215d1787e31766fc37515a942f6d42761272528bf23d203cd6d802aa1afe8bacec9798bf87bfba813776ac911a481ef991d956edc11ab0e61d1c8754c93d0d38f654999f01c7afca844e440c038e34f5a563dc3b0c3f5a943fa481fc191c7f5b4d49234be5a74758425653d230a332cb9a00af0784e28d0dc55b3f2dca90478b92478bf25755030bf5bc149ddea1c435cf6c0cdef632b353daa66c383938211b754e185bc22276c596ca2a205d659ea1b8ff088e58aafeebb4c9cc99f7fe6ba06d669b993321cf99f7dfb6779006fc544333cfcd8032328fa45dc667405957b56d1f64fef632a091e9acc463a175550ca9f79e9b41e6b7e75a45c3cccb84d1a5cafccc732fdd107dc9fe12a4f9560991f9992a622ca937ea56f1a24b65150d313133e10e560dd53cf7a3e5fcf6b481669e478b3099df3126a93ed4f0c69f6a0426138e49aacc1bf991097db4e8dcecb6f7a09c9cf047ba8536e07c4ef8ab67214ed6e0502465e35024bbe4c436b0e655aa20335ff332a08f167f1a0816c3ccd73ce772e7737e2392b3b393f3ae1ada5435c83af3379f6364e66b5e82453aaf63130a89f91c5ea8db1725115a3d0fab3066cbf92de765c0271ec8c9c9c9f94d27272cc2791d24b26e7f13fe34d04c081b3949a68aa126dcf1f38337728c97c87cccc77ccdc7bc3fd79c7fdf8facbaad827e7ce647afdbd374d00f6ff96fbf3d6f0f1c5887ff168e5e8bdfe69f8dcd8dccff6822fe3fef8f03ccfbab54bfc950c65f158587f3dc736c5f32ef3ddf0703859301b932946d731970ebb675db16ea6c32bf2dfe688ec96ca11099f0090f398ff31b119c2f52629bf99c9c997094f96d7b9c4d666395ccacab4200ceefb66270de655ee61b88261cb91ad95edac8af79ce8dd8fcf7d90e329ffd28f3313fee506dfe03479bcf6a6ade553170ddb6c604a9091db0dec27919d026ac0147991f699d792eeb6a40f93423d79b99979151e2c1e3e74746e6c7af9bcc8f5fdddcabf9ec6dfe47df803a78bd9101475a657edbfe876b5566bf81317f038e3bd49ab789a9b951d1c01ced6ac0ad34b44e70e498ffe13bd418702b0ee88123ad5be8fd0f9fdac3c4469a3a3214aa316d3101de7a8f92670403f2bf6eb8aa21bbad9543926d1a94825b16b7a5a0042f539c52cffb3ef932e54ab7e422b74899e5eb0ca5d3944e9eb73a54cd19c6d055a98e1fe52d8b7d71d9987642e08d1b535454038d2f53b234d0f86969a07163aa3d76571a287b62f251c4a819aa8de8981326df82249bd857ffec0bcac95bfd947adef7fd8fe2d6a5c5dea2dadbd868a1eef3e8a0d4c684d5d1bf5bd4133ce9d44057f665d4405b7770f124d4cf23f7a02dca5bfd0fe54bf2984c244a3deffbfe9d6a3fb7eafe76344de8b180fc37c5bf0522bc19760eb620024f470759b587c1544d8ba241be16eac0d57584f0ccc0a548b8ca306aebe2a481b693500dd42e7582c8ea2fab87230f955f9e6c946852a71195e792cad3a8b2ec52f925970ef22950b349f5291ea4925d5cc988698937d59e46ccde5289246d4a9bbcd5b4c9839e9a9a68136daa4dab872a25dad48637f2539353652b4e3c51a88164f7d41bdf206da5b3ca999fa90a4a5b825b964ef6fe498424a89365ae436937dfb351aaf245529d3fb27cd449b5ec4a9d2f756ae8976f43bf0c8b9490df9f8536f06f61913f7fd315ae5ff66c9dce699cfefaa66dbaa6bb1ba669beb3de3ad55c77adea97e6df51dba7368bbf797e67e6fb69ea841dc30947efe36791b986959861f8a90bc78f0bc74f85a398312b51de58d2ea8423ddcf09470f271cbffd2f1cff261cc51fa7ba5f53d4e2fe0ca8e44f1ee4635b1b138e9e172ac184235585e3b79f0a9fb670e45179763c6969387e9b71d4e7ad56d5aed439e182b4a7bf7150aa53bfaa2156b7b4dfc06596377abd55b603c1f9737dc415c5d868a4557214b7bb9ee4634be14029a17400bc99a4c2913a73a92c95a5b2549651aa75777777a7f8658adbb66da3f9946af324ea4d5a8c62448b1eb6931671a078631f31a9de40485bab9e38e19653e0ad15509c547f19c340befa56d92d10e13943e1b6527fee2e4005b8adce5e554f5587ee45d60eaac2b4aa838caa7b8191b158e5cd6181e7deb5db17112b551db2ca441cabb0172ad3e0c52a7f17846395b35851c6165354e134c594de6f75ccf046f1f3544e58562d761005a255baf2c21bc5da3cc43a859452765048291bc8a594325c4e825b393993383314fe2c41b946b8ed9b167838bb5c6a531651a0c8236994e549090a6fe24ca2b858699212a597f491962c549438899b7489aaeb5477fcf0f30e6d28a9d4556a719f1966c7cfba606ab4f0ba37088e1a2dbcfda902c2e14ae9d239ced65b9bfcb232548bfb315ab89549b2499728272b4d4871245fb2450b1315279dd4b12e579ca634c1463012d491cd42061c33bc6d91856386275b5cf6177e0e351970db6266f9d2259581d7ff5503b9bae4cf26540cbefa28a954964aa354aa4fbc9c107851bc7eaef25bdc178cab873eab7e1fe22a5fd65042cda50b78231542142a8b5027242317eafabd1ed491a6f60f03e1858bc39d91b4e2806cdd17d755128208f56b71eb2a095184fac1248cdba83bd7c5ebe290430242d65d1a820f940d982d57aa4a8bd1db252d4cf503de2e699952f7bdee929626aa6a5ffb75a3b1e2cfebeeee761590cca0d2dedd2e8174b8b29a823e5a641e73abd7f3b36d7bf6766f21799bb144b62a866c6edbf6ccdffdd9d63c5ae4267125b81567055e566f3450fbd75715e466e4d4151ce3e12d5ecac3a5cf9e3b3f6564c183673b319596c9679095131b4827487728d6fd4f12fa78a27d87eff3f2c9d127a43d4df7ff4085b4e7ae8f635d387a14d6c7d18f90f6fce00e407b6625d57d1819fde009bdb000e077615be0ffe11352c2c31f2db6774b2e8389b68294272ddf500401aaf2b3b80ca4ca3e95df3d26f73625b8e94ae4b2ac331f16173ed78c460b3d18161b48cc5695b3a7bf0dd45ef7aa81565e85611fd5a3f9eaaeb81f9f25d6293baa1ae232eeb79c4c35a48519a53506ae0dd31da65823c193a31f5cc8074d48891c64edd8910f42b481bcbbb329a56caedcdd9bfdc0c1ecacb265f6655916ee77077252ba37e7a3d56ce53ebbfdb33a5d35b47582dad66db3f74bcf54190fa6bed4ee70eb56372584558b528aedc3ca2ab7fb6ae7491b48ae9cd23d7bd726336bd9d7dd8d18522ed7ace1f1eec32491695cf71b854152a5675a8aeb568479f985d9a1c2bcbc84635195a9aeadeac027319c16e92fa970d795fa1457e9ceaa2031af814f62429a6eb1af74b986cfcc27959abb160f975da35a66c8eb9a5f7d672699596acb9ae653669a9639e179443eb9be2b3aa774399dd022ad780c6e2baa72c8b60ef0949ad4b215674a07b0579c9916b2104443f2533b32cd69449f9fde8d61607efb1770577c81d9647d79f9ed25942d6ee1762ad949e66457aebb751aa4924abd279ec6592853d02e8986fce7d3ba99f4a9fbacee4e93bdee2fdbff684d0b97abd3cee2f187da04b9669dacfb72594e4a29cd6896895e5716b981e68622abefa3ccda4b3976ab59e972911b5a24227be0655cb783ebc6d5cb8f3430d91371a7f09f488b383fc8324ddb3939aacd15a57ce75f51be0682caef330bbb06da90dae0fab90685c00ced48c36306c2758802631ca1e145e5f746fab4051043489a4ab324e5fbf134ead9ccb299c2104f4d68e1d2930b6a963dcdb3b2503c42cc5b9b83079e5677e989c9138fd65d7a427a3afaa8189c94babf340426754324fdb520ad90a1c4b63e4aeb05174d57f895eacb65471db70b0b7564231e3275e4265a38195577271b388d01060bc05063290c2a6218218695165c811a03690c294b6364c182022c3ec0f224d9f8f934279c0f599665d90a7c985d202105d2873356f0124402b6d8c1144b68d962898dd9832ed030a2ebe20c1904f1a403277cc185ca954bc8c1199feb8b20787c51459defb3088d104fa4c106133c28411421c9832526b2a480f036005ec0a0cef9d40ba73abd061a797ecbc593359c40a50d17b0e08a286e708457c45bfced130b31d3acbaf081a6caa75e0aaafcaf8b23bcb6041e1f7fd44a0e9614a1c9833cf6ac5071842c82948c045e84a869e58a10bd058a9c568850e7e4a57286940851bab54d50283c2a5f166fa55b5b47b16a44b8d2add57858e16202056c69e298f8f85341044870e2815753b70a12889043081e4ddd2a4868238527783275ab4015b1c5f3ea56814a4205243c9bba55a09c48c251168e36d0ee4eb99276f777f713ac245169beb06e953482f018143985952080becaf9ca853ab27cc61d3ebc1b9b65b700403a2f6123b46052fd084b5a3061c907598c60698b2b517680c552d3117c588ad20265898b2e4b3f687a028436765f9303759f7a0e7e021bae00c2084f0841064ba060022107180801064f28d9c11231777767ef27ea589cb999b9a04e46537706132a68a209f729f5f424babb3bbf3b3716777777ee31a4bbbbbb73636131199e497777777632ba63edeeeece3f72952419eeeeeecefd947999bbbbbbb337167777e777e726a3c570f666777777eedaa18e907ef9cd8e458ed14c6e021f00d14c58b25041d1b4250b2c47685a38220b348ed020d1a8e623e6880a0c8ef8b842fd8a91f6d405c9080b946c09131b40c1b263c6c90766ecb822fbcacfcf2b9c94317184169c2406d44684932ba0b04829a744c2fc058371449447c42f852e66e0c591ef8a966dcb931b68c142fd4877a4f3b94182cb123e57322fbb728575e8a93924e12da8c00041451954904c0ef2138cb043243d91f4184c2f4da62481090b1289448ef15333832e68f073659d382e74c0649db0f0a05e83c838b1a2081e481c898fb16259414412ab7d67e993f3baf63cc2922112e62b417e0ae9e124dc9ff3eeb7ba5b802b929e01d7aa96cf2a24bebe2a863252eaee5ab7ad92322cafc1254a149410c75d837c4512672409ed165cb4408a10e74a9a100613a11e609a8a580444f08249a8879ea4c98458194a423d30b310dc72309d8163513582a4ab94a10e5d8d64e1760db8658dac04a9f6732fa04fb73e160aab56fd4b0f1cabe3a543d104de56191aa13c84b755d0b852fd99634cb1260fe21897e618972eefda208e3df9a0b168f4732c8d6d6d9555352cd30f269efc6d823128a02835d2902a20502b14e1414dfe4c6e4a8e9a5889518ca981baef29b6f34fe6a7b1ca1c638a516951c95127c18561e49852ed576a208d4a03f9c7a05a037d939c83f3e52526a67350a3a99c0de7600ac7c14ec74155652d1ccbd262c782b0313354313cf1782f61b8dd8aea493918199b1c1e8e3d79100cdc77dd4f57a7027df625bf5f876b7b541874e8f87170fbf96129030c04e851a7eca01fdeea1ce4aafb9299191a9a2536526c6c6e6e8e7096c0c1c9c901627583d5cece8e6a28e5cf4d9e4c535982fcf3532ee5d6e01f0487b891831b2c160b05265010455185292a743e5a3ca8475d1d66703e9d8f6a48ea00e2ef9896da9307937442878e9f9f12b0a003163a1654433eb1206c10c7a0bcf5145bc22e618376ebb65a50d2826a8895ac88f0465612eb3a72ec8963593a8895c4941cc5b6d46625310f3aaafd635d4d04c1108e5d1d57c92b22a80b520d718c4b8b354835432a1c532f3ff32d16c531a8a6e71897ee59462584fbee635441e677e1287f863a466648b7452da8a35ab64ab1a8065a185aecef5440becad0a6053eba3ae3820bfbdaea23e48dab34e4070c36c4a0fa09a87d71c7a55e542f324625c47fbe2743ca4a90b8f6d105c7ffb5b8a4c509f3b79e9c224afdbae0bc1b5329ed53dfa9972afa23f7dbcf7129493f05d2163b74da1d1a91df8554be67dbcb37229fa6a47cfa0deaa0d5961ae552dd214db19462b917eea6b6712a9898999aa6a01ab685648716611f0e4131fce392bf2135ec36e5e8403118a98eeb86e873373743eccbbb2fc78a1ac87f6a6fa4a808c9b64313c996524a0f2606a42faa0e4c894016c80631605b41439c01433c08b62d1cc6f0a0dc45a08c064e4c7184ca7fa31ae2a5eeb9a8a3e361705ab75a655a7c299e9d8eeb7878523ed85628a26763aafece5907ad76b4c52692d57f2553d9fdbf00814603c1182e641686345fccafbb71e3c68b239dd4e958ac1c2b48da71e0d869121bec720c29c263ff1cacc5c3e15540629cbc71a1c623ab9a3d677cb4c41f899452ce0e0520bc8eb1f68cc4466ccc190d278aaaa199f14b0ec7917f59cb40e92ffd0325bb8208542891dee7d1789e2b498c2580a18329a260d22cc836c0860b90886289255af083904b41a35377498b1234b8c815aca0026ffcea2fec0bf6420cef3f807dc10600c3fbbbb02f980b42efef635f301f3fdebfc7be603d06f0feaf7dc15e3ede5f00fb8209e005f4f283f6050b5a97ff8ef707da170c685dfe2cbc7f00f6050bc0bafc7fde7fc7be603bd6e5bfc20bd682cffbb3b02f180b29bc3f00f6050380389ff5f375ec0ba6635dfee1fbafb02fd80aebf2fff777ed0be65a973fcffbfbec0be6b32effd5fbabb02f980aebf2cf79ff14f6054b615dfedffbb7f6056bedbab49779ed51d8170c8575f97bef9f635fb01cebf27f797f1cfb82e158977ff7feac7dc158ebfa1bfb82dd58973f7dff705fb0705dfed9fb83fb8281ebf2eff7ff7dc19e58e02bf016086770fc0c7af9821101e97dc18864f8ecf705230af2f4f705232ac0a77e7bc188847cf7dcfb67fb821119e05f7e5f30a219de7b98178c88e6b77dc1880ef0365ff3fea97dc18868f8ef6f5e30a2219ff338efdfed0b4654c3af5e07468480e7f99df77fd9178c2801ffdff3fe30fb8211d9f0e183efefed0b4694e3597fe3fd63f6052352c08b8fc2fbcbec0b46b4804fe15bef3fb32f181103dee755787f9a7dc18888fc0aef7aff9a7dc1881af03fafe3fd6df6052372c0b3f00078ff9b7dc1881ef03bbe0518118f07fa00bc3fcebe604437fceb05f0fe39fb821141e07d7c8ff7d7d9178c28023f8077e1fd57fb821149e07ffc0befbfb32f18519117fafafe3cfb82114de0617802bc7fcfbe604414f8187ee861bf2e7ea20a843f2800f6ac8b7f0220cfbaf88b803bebe29700180150675dfc100073d6c57f0388b32efe078037ebe2770068b32efe068035ebe22702d2ac8b9f01e0ccbaf81700caac8b5f0160ccbaf86d0061d6c59f00f0655dfc080055ebe2af011c0272ebe2a7014cad8bff00e0b62efe19406d5dfc0600b375f10b010bf041405f17bf0c60af8b1f08180319957fe885ca0f0396ca4f8001547ea1312a7f75a1f2ffb852f95f18801895df851e95df471895bfc7abf2bfc0a8fc021040e5e701eeba824220a7ca1f0070d7b5036c21a8f2b3e045e5070050e5ffe9a2f2eb00775d2b80bb2e17b8ebf2015500f953f841e56fb150f9452e2a3f0ae0ae2b07b8ebc2118e9eeb06b8eb0ac15d1708be0f2a7f0fc8cfa345e5df59e9e46051f971c0ef8aca7f9342e5b7b1a2f2d7b4765d33618cb7c4ff52a5f2ab72ecba381c1b48a9a8fcda8dca9f4dc1df2b0558d1c8525b485ba95c79090d2a756bff04fae5e98c2c6a4edda53396a8bce1d45709e9a91c7e8ff3e4350b96089113cb51f2a4d440dafbacfe924a3765e164e5e94af54d4b6d0f37264a3def7b9ffe3e4aa78731f4fcaf4b675ca9feefc4240a977538aa746a71eba26d51393b24f8be2d6a6e514d9452598ea234715c9840d13d1941c9625f502f46e0d07fa1b28b67f4ed6f514c4c4c4c4c01a3daa884cdf66441ec10d1080000004100c3140020200c0a084422a16028186ac2b07d14000b869e4876589889c32088519431061942080284106008010081a99a1a00f9eefc6488e4606f630c03b257007b312e2ae872714fe80b28e7b11eb8ee7de9fb51e6850079288c27a492b5b8cc4e0ca9bb0b089bf9989a40cb37aedd12c2b831f3c51c25944241c49080b87349c3b3196f2756f4dcb3d198e2ca92cdcb0142ec2e6d9a85122e32f3b3add43d7208e66a346218d43b459036438066a326c6bac0197ec1a6520c2e8177586b9871c38a360c139b33ce1da8864f61120b5b3b2150ee3873c08193f2949d54853ac1095ba41d9b08498ec8f5c1727ac9b53ed393922d0d19372d94e093d1a003614dee8426b5a2ee7a151f27bbd18d3abe4f18e3775fdab7e6c3dc5ab68d610427098dfca8290f6bf87df1fcb8c19f3f5470c50ab5092b3b91e26fa60887da360a52be693d1415a9a9b4578876e59f20d6152da1bb68e17b847b02ea233e1e05fc33147ad4899561697016d0ae5421736d6450c4788038dbb671df1df7d0d45864706ea12ba9637766a89a6a626c072680ae5847f7d2207541c40690e54b32c3cc0b56d824ac5852bb0c6dd0736b673ff1903c942b182afb33ac6d1d7227518eaec7d4f2b6ab2111680e17dbaf76c521d58dc44ed52898414bc34162d8b886d5c17be1d1913a10845f76c69d02de0d37eaddc0b966968e51ece602eb2b6e5dbff1c89d1626cbc02416219ac459e80dff86eeb4ea4f6f02732c4450bb31ad8aa620a833d6f18fc5c2978f15c36c5d7352b7a285ca6c824933d01bdbc28bafe835b5eaee12535a7d930c75ec6812c69bad96de61e4e0e1b876a6dc03d3df6eca4951ba959ebc6004dbdd9e79529d42d151f3ea4da13185da3ededf38b31a153b2c55a8484415f44dea024194b51e77933876df34bd09b06f0266e5f9cd888db8d8d18c699f7cef8b5f12a243ab83e1628118d96012cbac3b7782f5f40b66e9ce58a3252305acb9042a757bac77fcb6d75c5614eebb15e9259538483d592525bd64ca04f641689c43cfe2d1bf972a108a94a555e3fce690c34696ead7ea767bcd61f08ca4236318919832d3828f02b1e4949dfab3a0afaff772198230a1883356505b8c45802ffe1a54d5ec1362a726f07c98c54585572940f8c54fec247823cea4e16379e0e25f19ac40c7eb86c431d1572332914274e5def29ca91e70cbfd20513ca6683ad34c2ab64ada6bc3620a8784f67158cb47fc9a3f3aecc7bfdb47d4d2c5644e5225f7222dedf70bae09f1c2fc1432f051c83cc8c3dfad0f45f5387988768efa311aa88f10c9fc5a2ef726851c20bc7d2e4405d39d057c3428967017d04d98284bb7992f1d85ca071555b65112092d52c7015e4ea5d53aa95f27498b5e20bc9be0d88f82633bbe908aab84ec82d91f496ca4ab16bcd68b6f144e1c46158a7a2d738b6dd9b98489e7b655454444b1f9b044b46977e7d1ad5f477e067e20dd9a6c3d0e364303e33c65a092e9b6f6ebec860a55f0f9de0ce7ad3c54d0f9513bbc754574b23e9f157b04780733720161060a77eef886c4380d5a3f33540ecc2dec2015f41035ce00ceef0460bacb043f6b0f7c27b84403513f0761dab0b0231a8b42dc3889983274a0b525c4c89a73b6982dc600d5be0f354aee607f9493b4f784887eae02474533726db297d12ea77290102158c9c490613faf2a861e75309ed024bbe9b9c708a79da204ef695ff0df6a74b70c0871ffd65672ac0b7eb68920e9c031a3f461bb613aba7b1a2fa8b41d178002e5b3ccedca14dd865f281f9078b7f50a41029688ea389303ba059932d58a0663e663b275a8e13b1df3f734a14bb94ba7c33799d75beaca92a1d490897e38b2cfd64b4c0b788475362577926fe0921033a0949b9a22bd037894db162657dae80072abbe851d93bfc3e781b07cbc2a50271165bfc27848db09f3f223c43227d07a412d214578360a672b0f9b31c2d5ff4f74c88baa2ab6f141d1521525f4e08e9bbfa201c89bbcdaf1495af381bf3069f145271671a8191b17422b12292a9a961087402df67bf614660199c9896d6f5775e7c567213d4c8ae730cc42221055ff0f402c902a7e6c875859e566414a9f56b5a1745a81122f0dc94265205b401c0ad2b8ecbe818f4854ef8ab42a0b53f3cdb4a84f755b75126cad72242d20e5c6337928e939902c24af9872da09704a499f320f751f0b2fbd832427214c3cc2118de8bc28425fe1f2d1690077c6a9a7f59ca0a2bf3172667840627f53dfea699579ff59f7928f3cb946c22cea9afbb0032008baa6b79ff8a00c3667ccbd3fa1c8282c180202ae064f858e3156109c5c79c3778102f78806289ae434d4485e0b5f18a4f82bfb40c60191411f01d0631d3dc190ece090fae56035c442ead1f6edd0803ee7b953be3077b134dd02c65c163b7cfabe11b0569d68b37dcfe6a7e7699d667d91793561df202c12728d18db0161e2bcf0e4dbdc8ad74542cd6c3f0811f2b1a6f2a40ff9c8073ef5299ff98cf1b1b468aa088745c1f8ce38da69915dd4134eefef453338ede853eef7f2941f48609b454c5cfbef3eaf2ea21db2db879d8f3c39f2b4c2cde497c9b1e84f28535a747aad42ebb249aa31c0cf213141734a510a31e002355e1d03902fae08c22ec0859df5a90c8073145ce05762c85fc8c7cde1aa96b76eb26fd81eb773abd2523acb6dfce923ec8f9bd96a727931cdb5b724e6266825226795d48c2d19d543270c2ce777f91524644dc32433de2f6153f60fcde82e95c01c379056fd61f34ca02cffa4a67381aa0f09d244b816e08168f404fc930f2c1f9783abf0d22a948bdeb9b8376189f24e6331993837c1b232eb140589a9429fa5e4928e627a964c2c97ef85d6d8a3dba18156d06b42cf0345ee8e120062bbe6888c552adce5bd291efc0618875532201727df082ca2faa11dd46262c9a2070ee5de89189b5fa9a6d55bdad20d79369f620b1da05ccb366b3a37aa27dedf55a4b4c6b25305015b29b0323438fa08b07666eff1ce21d398e0e83e00cd09196ccd0ee46de74a5f1cb01059ac03a3c9a4a082b65a3c8988b9eda1108ec9403b9c5de265d8efcf13a387866484fac43407a92385077f9b643d9a386149b17b7a477750ba42c7c2a9a77b3e4b79e61569902ed7d4173cdfe2b54a31dd6b819805667954e5a4751965ac08bf9e713af8aa85f2d6f8ac1b78bb0b1ba07cd5bf08527f1a4d294733337e618f0bb259f96bd7f2ee4a32a4e4295146287d4664c82e39a09588b403a7178b9aa8b91e14ba3511707660c2c703e306c29d199f0d9d953e5ff625c53fc03eda24dc81d0b30d537178b1908e52b171b9009f3652a26dafc8a5cad5ef8a7f1be640c8037b92294ce3a51dee1eba66188313b5ce45d8c357697b607e24e153a4d91788afda8fcbc09c134498c4e589928bec3770c5a6ecdfdb99bc73cdf0a911f4ecb0e75e5338b93557f2f16b1987ac160e414943238aafd7bfd936b1792adb65449ad6ac6bac2bd8fd289a0211dd0b4ad78ce3258a55d24560973b48cf55e5051b32432411b9d0d4b0e67e4ed9f9937aff6861c7d2d0352edd2cdd760ccabce0e70198442eca8df812948d8481bc978264c5aa9f26f5c01f5aac7d9cc563c09d4e1b70bce7c3b1dd66e1c26163b609890aa0f800ee322bc22f85875be551597deb6eb7094ec0a4eeb1945136be237bd1e009d463c8ee43488352c73cdd96773a7dac0f8bea55cba42d0794b64a73d2e980816cfbaed781c6aa06b51f659dae1c81ed85d36e153b57da9885a525ee9120489b23c276bea0e895b697f72c31ed88575475858a9e42afa2afa1d7d053e8d442676106e7c8ce4888eeb66149ed97d5def5d62b09c077714ab6dfacad816f1a1af166b6b2014583d5bd93f5339524035472d1d75871a9e68b6a83a67598284b1a2d176ccd7d9f5456268e12e4a6adc6789792ca3b01f29e3dc857202a600d6d55de5c07273a86788e8ee1edf582cb9fbde07caa546e9005ac7f1c9138edd6cde523194bb7fe258c6fd7f4a6ea0d409ddf62d6a53ff0b4c264b89dd520ebb6dcb16594959b863d38ae118b060b7cf4c1e62949e437cfc78e46c6ef89393f728459fa8ae08e4acbe62651f2c31c513b49db553df2185d9f12e23d6127341507a0a3dfe6e74889c072681955c5cbd2e4b0ea8e0430ba57e159d157ed6a156f3ea0d2edbbb2ad3181b4dcdbaddc3870acb39f0cd9c57024c4870ce01f883ca9b2315b980860476fd4dd4cdc5284bec02e60e95ac48fbd56ba5e71c16b9364bab8ff688f16d61625e28b77db4f7f17612f7b76e3798f95c03e7fdb8a4cad466a36e2f0a3f52cd2251e51432f6a69521846afa678f18f0b8e9b6923b4bb1188d79885401e82fa8090cd7d53d2a6144687172a51e6572f10cd5d1b0a13c8b9e2be11aed72f650471983eba2f1535dc0b3d3841947673bebc42caf1a57723072c3f0a6fb4e8ca8ead49941efa7f452b5128c1d8a4bd58be2174a2349c0b0d4811bc5c51b1898b932ec9d5e91f43e6be20130cdd2a1a675084e75c10e0ab6b8c2c1f6320bed5bc0ca2ae320472303e345f7d0639511a2df7f264cbe7d245bcbc99f16ba304817cb57daeaf0d8508a4e8f431f7b351465902aa68fa5c8c919d158e6a1410bcc3cc8ff50773182a89cf92e5dad4bd7ef09b1b875d11bd1dcff16f2c3b5907dc0918b1a86e341d3cbd05ee0ada485d2cae7e3a288b879e77c1db3cd04210bb2c88f55864b6304f44879f79473446bfcbdb62ecf68020e12d51b7e2398502e8f3f006454534f913778b33cfb280ff6af11da4a0190a74ff92c27e8a93da8379e5c5c9a0b9c617aa27d7590946cef564bffffd3df3daf8689e29810456a6243810e2f2421cf3c708223711eb42710fbdad89b38cf2ebdc78dc3d188c833fe8b4626611c9c373a4b3c08bbc0b51e2bc13a76047a8f26bee0332f72d3889a34d1969809c242d351106c2b97b1b23cc816693fbff5e52b49ddbe2abc5793a96f369318ac083a04b383fa7148e83e71a0fe972a368d910649f01642683b900a7d4abb50013c72ac97b46d3611471f6a87d3ed7b7204c68729557d883469f62a96e911e89752c798a0f2853ea596b982b4ae8dd6d92cf90ad3cfc796d05965b52a91f2e65a1167079043ea34ee9ddd40a19d7e7dfdef008e5a3b0745bbe6439af15b14b07872aed34d68bad17eb2c3f4fe27223222870c5f48a7f0066cbf9136387d53d7f6ce32b8afe50e4fad9a09c812ab3f0770e1e01fd465b212956ad9325abdcf3278a81633b8fdef3841db66daa5d6eb4a26a418697355f3cc448bbe0bb88c6d37b2c31f0aeae963eb307395c065d7321c459dc167b20b9882f47e5c56b8b84f6a8659c993b13b5a5c0bf7cf641ebdfe3a0fafbbc07bc76636ea1c0579078bb17eec81cf79402e009d68279e7506d4d13dc0556c98dfb0ccf3c855cf16ac55626658f47055e77125a488234a347f862ac785f936de0c2b22459cf21cb8b26d8da80ab62aebbaeffa78a291f15562c46bcf813fd75ec18f7a7db6044e4f70b4eb3707de20844f64408e98b385adb9a131800987ecda89bcecaa57ce810c9e6aad1575fc8296bab0e82e36b5ce272f8a36288a8b36603e951befa3c4578390ba6dedc086f83a2fd7181c8c3b3f17384b050b49a0ee78f606c83280616e6a0e7d01e8ed0d48312662f6a6933e2ff3bf89b2d7fb194ee0f1c374ab69334e65ef795d9d483ae21a57115084892259cfaa7a995e7ce72d8869667ca217b9399047bee81d797f5f5b4d657372620d8ea2f08460e0c1f57c4c78c182b517e6ac1fca82f6f5e736feae807622129a7f861df57a09c9b5bcd35a866bf7ba81f2080f8db1456d397d0ece0d0cd29825a5c344ca7ae9436abd65e2f0c290580ffde2ac9a7339faef3a930fa94703e1df9b91f4708eb086f1e44fdef492ea567e4f360596f88547a110caf8be7614b347c9f11a1b503794bb29ba52cf13e4094075ab0609e0922a7a35540baf0fc774517278eb801e7616336123d375bc427dca20a6673344a030dad468aae6260323a6ba75065b192d897c8049da355bae2c6e72a98c6d6a637c26009113c63a9390fd61cec4f583d2141a9654b2f176a6c257885d3a3d0044db333eb8f8a5f60f680fdce7e72e702ac750ce9b221047c73de797910218ca882e3a21c5b78fdbf7254d489a291d089a001e171d6e1fbc2897b33f193e3463ccbfef423bbc8cc2156d37e6fc46577a1132a1bc2147c55d8b320fb3c9093a92af11a55370945e2168345c6173c748868676e4f359c901e68214bb43c883d94cd7e793cabf9469c024c5ce585c0085f6734adc0eac894f07303377bf4a1fb731db83346691a8e100eaae3ff91a7862f5805ec70a94f268f6c4b4b942e933ecbf6406988f7acb525320cbb83f08dd27df781403de7095d192e9833f77f49ef347b4e57d79862a600c790a5ee528edb0dcd28be1b930e9aa98a96e3527adf0afbcaf029dd8d9909650ffff17a6ed426861c53d0901ca0f56fd995fc04008a7eb5a290c5e235a4de9f5cc5a7767743eaebc0b36cec8ccb52c71ef68625c43253dfd6cd2a12170cca252f22b3ea541cb23bddf0db0065a3fbf3527d97e009a4d3f4693b3e5afeca161e0b8dca863691ac7364ff9bdbef4820134278bdb1287da0da96987f3028e000bd93145b071a3582fb980d2d11b57b5a7f063523dc6dc418188916a990f023b01ec20d1ab4d1a31d2be8c791276c027eebaebfc6e8c83154e4e34618e63e71bf851bd8091b8e20f6aacbf9031069ea5ba6e9fb3574ab74a3c760d72340d2004040516f60e1c4fe96b7b61dc0a665013c2259e69954130e24a600814d502fccf0656d7d697d818afd17ab08558deeb858a242f58851649c3644b12144d55cd3cbec6a5cf4a6098aefcdbcd0bb6df5252a9a5e5faf3e9695d7cebf410327438924e63f3670631bdd0e432434e0959037c2f8a085447e563b3bc141bfc14b3d95f66cc0cf1ac0f1d7658426e743742504d482462496d63d8c567a5ca3473b1ae488ac243d002540ca44d1c8817fd53b41231731fbd8f1c36eca96727aa78b6c256dc5182638b420e7787dbc626d2b03493a9d27ff280718d0f376bbf4ac6e576101885938487dd9a3be01d7b92e1559aa9e2c2d53f02f91cbfa691a0009618a2297326c819b2c350636d6938ef01404a53c90b4a13d05a548a402c87d8b4d4aeed19f0405989cadf35f52538fb08f31e29f30a1f2e17a226628b4c57a0fcece4bb0caca823db2ea24306f25a54cb41831502f5d94c510dfb8c1313ba0063b85282bc10edbb50401ddc3b3a3b78799412f20d3af55ff7e300c06d37a8469944c8c79f4187411f24dae4ea3736ce0ce41049476a877264d28e853add467063c518011a45e89baa3d09ebb847059b9a0c68148071253fd7a0844b3bc830f27b3a937e3ac187cd8e8f3d9b3fc559d6105d540dacfd4c69bdce8180a8ef7211e3c2731cf0a6ea0d29f3df8ce2089551465a32a1fec8e9724caf9f6b5960f9729b56d51c26c0e3e64321589bd428e8c7338b346e4ac22bb360fcb9b89cca0be226ba870e6c32146304991433a06a222bba8e49882772dfe9541997fcfaff30468faadef75533e3845f7cdc7970e458855567e68bbd289b5349ab79cd19567fc0baa93894b2d18c4188e445c66d1d323de802cb1a11a251acd0d9498e2dd446fc4d0c3032b15ff8c1301fa474c37f7a646c9fb12883b3450af86a2132bc6de7f53fb7c01f90797ee618ec40642e1386c2a33ae710d2ed616c613b77393be485e45a6bd065a55ba4b0bd7febacafa65477fafc0855ce0cb18124666cae0b747b40243f07f6c4b6b26e82563d7528a60fb4158d90d82cb7f13fa94e5c4c7a7f3fbf7ee5ca1bb43f4aefae641446f00a160fe3a54671802e122e632010f52208b5529271b60780c328eaa1e11dcba426f9abef358139aadad7193bcbaf2216e9a8679489d75c6ccb5766e7355a5144c388eeb661d3a1b138623075a7ee66800709e73bbcb430d2ba48830cd610c225f002e4bba40621c78b67dbce47bb925eb7d9258d548bb593c4a2cb1d0d1034e53d4e79f0979b90b795defe507eaf8a6c6f9347a97a86c1fa5035042ac1abacba4341db92d34b8b80cd509ad49feb9c9bd6e4bab7db0086288d704be611d42ec8b1db752cb0b84fcb012f0080f68cbd8b8fd6c008c7aaab58195b592725b2bdf0faa4fec9a63ba0bd26d171deac847696d21ebfab550aca17c8c3b5f64982c980c5cb230a0ffa18bd6e545e63dbe763b1f8a748a9676e61565b1e0870538a29d9a8bfa545879e246441969c4b8935e6614b1bdbf9b2d45e388413cfaea829489c4b3c8b83462c5c2e2b6d4d35aa9e8bc5baa7436fa5e8a9e88637e4022c06f06bc5106e48834a5f8b07400c5ebbec14d4817d86add15679174dc482a01463ad6387765bc3b23d5dac8b73578e6f88714638316d26c6c540c8eee972d4a22acd04483ed7d9ece3c62fb5b26596004fda624c29ea860bb85ebc04677dd4b37b3e9befb1c8bad691081b349b2695c2d6ccf483824651b259604bebfebaef1b5710226c97dcf9e0803fcec037709fd757545eef2ebc770698043b3bb7fb08b120876bb88e4cd6d678dafb77e31f606a0dec0b4d71635500deb1650f55eca1baac3961b0a85cb556d80466369c2952ab1d9af45676986df38c404ab0304d4950f0e7469758ea3f4ecae494704e07f55ee1c0e5f74ed884d1a6020efddf5ada633448315490f69801958faffd25bc17e1d8e00702d1909e01b6e929a79626b5e0f25d62b3b4a41ecaace592cd78b07d17c818d903e64d50ff820dcf75528e8773b7f77c27c2feb6fd4937be255664ed8e79cdc1e4d50de3ad3a456356b6b550d66c17bf9a01a5cc836b08dd355efd7914c136a56b960754f56021268a710b282c072a260f5cc2c506b3d223465acaf051036f1962ca6ecd3b769c40233ea1388c8e27e6fbff44390389a7af60c7c71f252f993f11aab8b1e74818753eff1c0966c55a6fcf94ac237d3469258e753b08f6de14361d6ce50e58d27634ed840f71496cea0793b80a128414c4fbbfdde27ffa2897c94d63edf2fff9d097c4cb3bddeb5ef7bccff66824fd3b6d7fbe6ff34d9f83038ed2b5c8e81d8156c1687d78e18db2f055087f08043287082b4b061b5bd211d224a1d4eedd93f867b88c25fff88dccf87bdc74cc690d08fa162d9b86ab650cd8a6ae295561a750aa2a13070de131b7a55913ec3dff0f4188bf5748954bea5c7e4eacf81bc17a6a184ac632bea9420901a2d108d1a380d6cbfae33d0342e108d1928512e9f7469a0695c20180df06dcf58d73d1080327a3e3291d77ed418a963466fabe6b6d758370e63f6fe3dec28ad829ebac279bd8c6d838de95e91f98e020ecee5719a5246ba97b8f7572dae58fd0b6993affcdd6a43e983f20c54533237d132dc12ee4f8c8838502e70080346b24d697d433ef0b55d11624f2e4cb651eab2c1fc2896ef6ec0010ba55a8e820383439e3c5f42c6a43dd4362c87a3cf1e50bd6bcb3e9194e6f164c1642129d684a497584ad71ba09d1dd0635a7260ee724078c2b558bc5be82d2b4fbd86175717a993dd06fd12db08085ed7467c0bcd872cdadab301ff6e27b9101f2a6ff4d8ba8704312e2095f504569e87822476261e61e809778629cdb5dc55219a2946ea6374db0376b3f2904cc5dd2b501d07ab80087841334518dfc75f985c4a834ba4dd6e863e4345e3ed98341e5fa42f858b3294dcb80bad954b8aa8c0fe13c8c8f704239f5d4df293ea6c28240240bc637b9070d9bc2d7d02e32cd697d1d8521d3d2e34ce46e7003c6ab88e7a6af2a4021ee0c984c62ed3b927ffbfb26e8c8d6971193d2f1c5c01adc17e631cb359c73015735a3eae6f2c519198ad9f42f9a1217a964898cf6f7ce9c45534497db944d5e99358580c2d5b566e2cec050a3c48bbb12c1a8ca3e9235e13d1444a80031b9d362b287a3143e6c86eeff4eebf207160a949dfbf273bb6a794cc701077326da9c3e2fbc208d63348daea79e08a8a040b10d38cc7da4ac492b6e893325bc6b0d534dcc3a4a6188c6eb580b53f505fdd798893acffd0b1deab8767c53cda342641ebf82986382ab531eeb875fac03c1e8f4418d170eeaa7df3247727f04c7c3dfb3598a3c33e50ded0bfeeda9c0b0f87a0bf7d06ef03c474ba2048c0a2353b7c85b00ea7937bfc48d442c7b85f3e65037fcf2415c7d38d447983fde0323c115b45020b2800c2f1b14df26f9f93c250f0fee7c367c9fa13984509933d653f685a040d3ebbd8f0f91e6ab89c003b579254c758270fb2e7984c0d1c0239059a8e74dfadef16ef2864d250b6d7e33c902b11491d77ca0ae35b33e0a07762ad06037a1244103429a3c19c023c42c5c0412101076d6988d04ae24d6129fc7301cb7021fda98d6733f9d6d968d4ef1c53554ed63959b5c0dbbc4f4430a9a1a288bfd6a98319824ea338414b42bebb84a2a42dedba3793234f828336d83c8c991d386084a60598a4ef671d412e5343367a5daadbf539272c0c67f323e6aab78d833b378144ccce6264d4ba0f5f65343588ad626f51f6360087e93cc8e82986456f20173ab4fe75cfe6ee70c9178ed24c21561a7415c89cecbf6e3d16a51063a45aef0cf534dc7ce32ac8de356cc528a5aa0fb6ee16542842adb549669c141a50ab2d4008777827f1cb8a4c106e3e4a37eac07689cc40192e910d71d5d96b911abb75033b6b91a8ad824ce7c6331af35805076d3fb0aeb20da0432deaa61779b3fa0d5eada633e1ab410bc4e8ac05a809e4e4b90f3005ac1fc6e0d34e9154ebb6bfa300022b28ed9be72e3105bc3640b19595810076f3aab0314817979526feb6eebf7868aca4ad49b1649a85f228a1a7804f22551fe9da5510095888600f7d6abc7303420398f1682242ce20f2b7dfbffd5eb6c215bafa7ba553f71866b0eb4e47d257a1810166960450917f769c6582443126c0241185f7372e1cdb77ee061c6c2ac43a0344b65f6387e83084712137e20fc2a233360ddb18b0cfd10acbcd5ad41080985d9b5cab7965c2ab27a3f0529d9dd6d07c1d6bf0d0be707b5d69c683b6eeb6e6a9e8515e42a6efb75a62fab2361f235fde9080fc7d07895a7d65edf77d9f1fe52ce12c9de1a0570ad7716088da90b9fe7a8527999325dc9bfaa9078197efa95af252bd39ef924e96d1ca8e0fe7cff1d12270d396d09d1b160e9560181973cc70561c65eb6cf8ffe3ad236ee7061c4f02cc90089e10906300fe4c173cca890436a8ae6899cb0eeaa6c99a0fab25716e367ea814df9f2ab2ca5abadf652d70cc591416564165e9860da457d370fbe2f69d219ba14f6d74e2c4cb42892c0853e1dbb028cb49694f4f633eebfc65a14fd4374d5a34733e288e3ab314e922e33104f9bce6d137edf119de8ad5fe4bfcc22b3dbe2d78f515b9f098a768d2c032bb5041026579e46e422dd6640d27d802f2b92bc125b9df5b2bb9fa36a640290f1d4caf2fac484cc06236dd14edc48ae1c028f7a0513cb8c233a0b153021607eaca4c94290d816884008f728fa85c6a321b595b8b4fee7701465e0a887b34ce401ba93d93866cd9ba41c12c99b1ad32d7919df403ee2cd9e4d40491a4c55eefaf5108299b0ccba5c24e16eff6cd88c545eb8166c8374c73588d8104aef40806354900dbbf26c25ab866665f424995a0fd5cc1b83ea7ed4b9c24426875f90e66e8763a71a01e15c60261a70648579dc3bc55228bc8c31903350a34c1fb31e389824bdde9e6fd45e876931f54e988aadb434e8553a6fec51d1d14df848f5b39525bbffeb45ff408293a6fe090607702248804fb3b8400f2ea2ca89af7211fcae41bf2676c57a254770fc9db0cfdb4551fd382cc2628738f898aca16996fbcc76380bfa17438fc9bbe21123c81d5e0fef80c11398cf91c94905d6a8a2a1ded801294f22383fff60e2556c549845dd1848b96539a212f87941a02d6e15c16f6ebf063f91ba840c4372152220b171057ca18ac6e01805915087965ec6c621196193a9a1e285012e516de7da1591166c516f4d79e720d1fb2578fcf25941304843cec79647009dfafdcd3be4d29b1b2ea47c4b8181d8a641f01297f052c66c56f9dc7a0ae8a8547dd9efbf6ad1c9f356986143b7ed6504582b7010423805e114f7142bf1351a616184518425104a67591dc9a5b04de73d42d29021b34230f542f38442d10a1fd4b8b9c080290bb801f7a4689d90cd6d851aebd95457c39e807a13caf6ded826a85a815ddbec8100fc9228e3ee8588126510eaf84bad0015083c719c3956636e2d921b4f2df56f48b029de0b48ac5b236228fe083e031fe0f925b77bd26c6a6053d0077be8c6658728823a3c2b925ad82a628f658fa5f44b3ef8b478b8d51c85152c9e2587ac7f9a7be4b101a953900cbe45b246b0e34cb082187843a752793cb002710253fb2f7aa45e8da27edcb3ddb313f7b094c9f54055d2b61f501351a5ab2aadb0b61cc80ef314ff4ab783a0ae16ec626265eadf8c5d71f89a7b2a936209dd8a3e5779903480b159f6ab0451580983fd2e747f12d1c00943483d09296da2690cd5bc545f152fbcc022861901a4da55b5c74bf25bb09feea946bb3bf94c7b7a96c5e554963638e40e088649163bd41b05988490131af951b80ac287f9aec86ca7a8faaaf0e88ee6ae090972ab5d8b3134aed521416ff4fd5d64871494439f1009b53c67e7f9181dbd68d047b05e64c0b5a89446eb7471a00abc6c6db9c0cd4f8c10b8d1fe93c5da0d2f0c9a59ce4f5bacb0a6840fa2a669ce1425d6b7f3577b6fdbdf667a98581e89de94c9cac8139eda2ef1d769421fc202d869e6edfbe74a0629158034f404437731a2144f4e03293122851c5941a96f9da3a57e59aaada82cf5ae4e13266b0db0b2704ce674a03cc99b0829bd35d88577db9ffa83b2d461955140624d8cee3723c44ec857eafce821e9d5585f6c414d0f90103cd1aac26e5b0b08c69d0068e5b59df96efb50fe27f9ea3aaf8ef4366f8c884d573b9e7dc819239dafc88a3911cd3294966490a404cfea21b803953fa5398b60796bbd86a070dbf95b2b32b75d43485c8c0b8e7cc67cc4d6ba6cc4ff5989701e00d5968a4856bcac825b8b51e9533d53f583990c3ebdbc70f0404a5c05fc604ab73b245eefc092023d94a49998255c4c165313985e2651f1d8cd9789b77cd9ec772ff2e047c46aa9819c5ab461cb052f1e04f5e8764b08dc882b70d2c90241527f53de8520f1b451df0a5de2b1ac3fc70d58d9de121a887ed0be9f4181363c6ed3d346a863cc3faec6b19e476d29e134b7485430c7bbec1949173d0dc1500c2c8df96c029a073ffbc2e9654b9785beb439d203f0b96abd44a63c551a581acc088cf3d18d8e010e72c18a0a8a238a865b74fd47940afeb524338775c8ad9f0bc41c15d5fc473d6331dc94462db9443c20eada804fa2dc046ab03c1d8a7472e72574f924b621099fcd72407464f46100c1aaf40ef39ae23eb92ce237d2ec071ae441c2c7f43e8cf9dc4cdfa1b16336c57a53d474cffb718e75941df08670953fbeb05dddf38fcc6432f2dff5ac80f736077746014b75f77f1188a117bc5c42a69d59b33f76761e6bd636ac5467b723eaddae97917767a9b4764afd5ae239f9d65e9a5ce982e6357564dc40fae15b92764b568aca946ec6685957f99140b098d067c8149877d329fed61511c444c684c67664ff362fa85b76b99fa97cd155e3e94e0ebcf8b22805e28cbdd8b3c8da2d47106e2cda75a6fae759f71e6b6c33dbae16a6f3c947123311dfa6717883eb2e38f24867825917cc6aab32c8a65881e22c628a0d51d2f6aa66897b70e4afa400389ad59c31c530f7153e5a69a6fe296117d8d9d60775020f4234d1be5f5fb11ad42fd944ada0be201e1c1f9d32d42c4c9c496f5d3e10afc540f02913590433038fff6f909f74ef61af49719e4e273a0cfed51127490d9c8831cf2e251ae621c9b3cc53e8192f969047d187e9225b439058ef584b3ec937d948644022d099179b862fcacdbf88cb4c385baec8d5470ae8a43e8b2d04f843cb829c759f153ff2f2962ce4b48d0ca6f8c3187436daaac1f8e763b3acb93c5d36b28ed82571a1dc23e18d28a75fbbd163c5ae51e9ab74736fede2b11c86ea792d4b8efef8d806ed0723ba9b9471a527a34ab574044a22ae4e5e23d36a213f221ae8f0f7c3993b5c3999c2b7b859e0386e4065195d9a1816ad0905950254be89e7b597604c60b385e1d40832e8b90d5782d6bd600de17050476f1492aaad58c33d5c34686b9fc297aef57d8d7a29affcd6801e8539980ab61dfc8cd6474e18ac0123c6794459210dc763d8d939564974fdc4e1e48de9e6a72059717bfdf76939bc52c2ce104d519e4be91691e8377f29ef45c7d4ffe8edd2d9673cb86eb25619bbc9e40df2d2dd678427283b4e69b4c43ac9c8905b8ba26113031ff381999cd07eef14b27e39cdb7c614bb39a7e1e2a7e831f4af16da5dd432424bf35aad0a28da8de7039738c735a39c71f0d3a02a754b3501563311d701d5224692fb40fd43466b81d53748a6f55ae58cd1165ae2016523d31a5a7242e8ed5a11f162ae0ebd0f94940eee4a909620d4154121c507b01d38a9093cbfc3d1324407c5eb5927f4b349ace513f906fa2af708d88f9dff4ce2e78e4fbd4a9d7ec3e2510e63eaa1227e220f6b9ecf112188bd95d213b5e19e6d9fdf6be208c62a989a31dce9c06cfe66e2db644597fca6763d424ee4896f7d69772295ce5413d14525c0b9929e7f8c39b3c742f8d2bc5796080dce4187661fbe67215c35a0a610fb03da8374b0ee051102b9a3b72ec66798750f3c7bd6c874da0eeb750085235baf4a645800c479a2347ac2db015a27e236485496027de882f1a8b8a32150bcc60280231d6522e1d20651d591f0d4cc1c0ce23bb0194a414f4186120d5bc6de6d8140c1e2a8b297624fe124c18056b02c346988291be19e089615a37e2a1b21b1ca01e6c1694345f49196f3dde3785cfd9876f8bd8b5566bf0dc185cd26a5b1faaa41d8e248cf76aa3ab737bd5d1d83182d7456b747cbead6c4494aaaf93848c4d7a80695d5ef46ce766a58fc5ab40b44f5ed5d46d83a280a243f1a93bd0938acb7c0a5b2d1e26770c65bfd2e2a149c30e4fed0ae649fc5fbe306a77fb243e2b01a399639eaa23922e23ea13990daa8922522c6c3e94ac880d8707606971fccdd7aff6bc30fec947b141df86c838c9c2392b68d30ac6d8d3bb8e0a86b319d0d2502ba6832efcc8a5600cd1586d31bcba10ee66080482abd4fb46ea4d3678279c018a7399db99f81233c39e5f0723cd8897ccf467c89260c326b9c41e77136af26a3b972cc61874bf8c4fa6cf02c11df424022a0f00776400c49c1b0ff8c630361b9e3067239549e250dad5be14361bc20242bc0c7886190eddaf7e3e3a9d63ce6734457035d02ca859beb04cd0841361c4b39a754a9d33376287d90647e625951b1eac1c5e64b520509b9dac34e5fd657322142fa119fe1e7eaa9dac1a44e9daf93cfee98e6398c1f4366f82c4899f97c3d4f1b8b627244bcf13c62399a1387a8bdb82c350258edcb5509b7db00ef35082bc9c1cebfcba4d5aa3ef6c79442b4ba809915b16bd346708c16a02a95b220dea6abd819ef265d0e83cef9ecfca8e5b6a6467c9b167d18524e2bbd37ae05fb700aeb5a7f74f5d9bda2f1d686b3a54a254926db7b17427f85de99e442425fd723a0d5f8359d604533f0bbf99a0762767fd89941ddd922539469150aa4753110acd9bd52c35672de04d291c1dd17a0c4d01086ac0afd947be46c289eb8480c0f9ce12f16b9ee07b50d135fb404270aab9db50cb3a73bbbc1df7f4b29db6b432dcb6e3c1b1d261f091e5eb83ad5fa6703565567b9143a2d0fcb79a1835801ca29764144a769da946381d69d642d555e26c064ece57ecd1d6c11f049a8215fe35545e453868bfb9158f693c03f737840bda1e72d66fbbababfc4a3b0280634c47279a531fed08030e50186f01b0d37590781ac41eedf8c50ed160954606e26334f8bb34f8afb3e953390b213b55e6c436f557667f7e87d0e53f09d0a51a2efe167df0b362f9ecf0b4587864b594739c805c61428054fc40127b4a89661979808036c7a8794548fcf7ba76c9d6dea1990fcc159177ce34ce0fa9ec2b6598cfbb2c8325a2c49321714be67ace643539e70efa3998992c2f235c4de5c6e6be17dc873345f5ab9f75d6891de7dea3e3c7d89dd2d13d6d03ddf6ee1fd6763cb8a4014623ca256af7e7f9dcaecaa487e82cf163191d5d54322ac0673119351ca4380ea6d909dcdc5e6953246b0bcdae7a38a2ccb5ecba7521fc310656e6359d155cd6d976689036dad860a40a57f2be2c6e1928871182acb859667c3edc337d3a1a25ffb5f5f0a732c4a2f0adeded62abe871816273726c26d89226a3fe4c612ba633c329a9f491ca92faacfbe3d5a5d399a7e0dbc03af97d0408725fe74458e2a2db05d05c96b03e33d064ee358ba03e3df399962640acb927cfdeffe993716d7e125269755ab1bf500ae9624dd1c881bd8b74bf0b0c49959460af1adc7da2206d70dd8dfdac74415e3fd1011d9dae8b89ff0e04ff1344b303aad860aa2d248b78749548d467b78509e4f92c3e61a2480a36486c41fc9c3491cf10418d6fc9e82c97ea2e9819bd63c79b0614c82a4c1ff79746ceb4b65fea2baa6f7686a7b9389dd0ec2647332a50de73ac11c459aea451b949579cef6fe9af50ff37c36fc8f61ab484d6907c34fb994e3f918e54264e03064761fa1e317abd33d2b74684a310fa876e97630a6667f9e23ea211e4b1c6a494d5a74aee9a7bba607d657d74f96b735e3b0f5e21f920bbffe78866833c079e538ed7f96624d4bf98b94a9c9b549321ebf313e745555bb4d53b4e7cb48fee313b72e64b6acd240d2277fa2e695b538e76ce6cfbcddd61ffec232977ccbabe80df1c229ce2189856afee5741cd37dc6b6df01599f1ae6fb789f14e9ea2b3871271f96141b69cf7aa061dcc0d2b46eb76eb46e71980f9f0d53484a1fe71f77dbc9a09476abec4e3ca089196f10850298cb63502ae7878718503bb50bac7ce8586a7ce6e712e63f225a52cb6e6012da9a3aa43b4c30ad819c30d789abcb9177a902bc9a40c9c079ce4db71c2dc429f3196468a3a7f13570ac5b7e7d63cb1992d602c7822ce274d23c17de3656245b06c6e4733f265ed5f361a9431d276f45f8dfa79953be544377398733a8b3e8f2904452a6b159cc54082a3907786326d1eb864b0bc618e5ba79ea8df84e37a42ca9aaad10ee11249b1a759817247da7351d3c9c7b640560c619f23b30ff08e68b9b18ae2d94053f5e9309478f00a222c973ec9279ab53c7bdc16eecb89f53e3aa9cb38444403ef52d35c69be5a828417190d2fc315e30299b6991193736754659db25f16763ed5e8c37b0c0ceff456c5570a2a578741565b825d17486694306f2b6848069c7f3c19ffae0ae87664bb0bc9c22c23257741b33c5b8186fa8a03125861777e034ddb2e8b2424f73cc9725b118dcfb0065ab64f47061b7d7f45323b8d55aaf60e193cce5c104249b33513480b0f65bb87803a4131f839917c738295de37cfa3b1548e584f4198c055ecf23b2c837321d9c861d1ec439d0a0b9b85d8a268251248f1c329dccbc1c2f0272abc01f145e784d1ac05c1461688a5e2ca8a14ae494fbd187f847c62446fa52a20c97be9415c4beaa69a7b8d17f145fceb25db941fa401173bf618cfa47366b00249b193202eab9f1e80339d2159859333634f1c1a667265a6653b75356c8cb6f4400a6b884e60ec1dafb7aaa79f09320b3053e8d3559b0d68e7cc4d785febb8c0cf02eb979aac9e07f12566fcc2a9cc8423c1bb77f95c4af60bb1fe945222d1207a64a44c07bf8561c7122faf80dc0c12d1dcd9d99beb7b2cf80dce237424df2f13e63f1671430d224003877c21cc7b4e25e5501c36fa1d11056b5b866a958f3b9e20b43f03d5047c11547958962f6e96447e5d1308d720fa774ff67314f8cf7c973667e5c673fa08f6960d3f243d74f777ad2036253e2d492ade5322851df4407180a00189368b1b858417c7207a728befefdae6bed13226e41506232d28e1bfceeefa4949b4dadb720cc85424259ad5e858d8f267c43c23c660fdfe4566745b6addb15be8c03240ccf353dcf0fabf7b7947200e9a52dd02fec5a454a152f00b10e24aa89810ea6707ee057d41c883a5893dc933a704e1134cfdb2768f3131234582a2a0975357c0e1a5c058a6114e0ae5b06ae7c1267ec5da3da86ff8ac861ccc7791ae7cd5fba1fea287c2137456a51030fd60f62db750358c84bb708195afb69116ed09ae13f963bccda18a2dbc52403ee6fd48f4f3403619a30305de273ee783dcf033d69b5d2daa58fb56832d3f28ac9d869357489602e0e52dc5804bc5dc684abd43efd682e71759858a0020c05c8b5188538817cba910d721867af7dde666e9a1b6209a54fb5d8c3f4656a96c96ae3830ef2a2c41b8da17e75e60a8745f52bc5934eeff30685508be9ac185c7d9c4979de4b33cfb266993eb579f21eaa0018725473368a422f0272d8f090c677c8099493c16915ab8f45e7f88370afa20bc714c21b6d028e51b34b3607ebbb00005c5d4157a7b1f4908a9487937e2de75b33805eeb6817b144d4c3b9626f313cacff3f7971a439a41df490b29e3ecb84461b3b8fed352aef0880cb1b16cafd3d618d5e63fa4f09e7cab2f5399cdabadaee92e29e144bb0b62416b958cc0ac4dfa72dfcac18c97cbb75069d0f38149f81a7be1a98a713ab792b4eaacdbc7d6ecfd19d6f722386246f1e08d84b97fe53724865afd5408f2248b721480a9663fa88a55418b77df3e1cf26d4f9cc126fbc937992084745797e5a44d326d393dae0e221bb09a19c4aa23cf8a30a8d30b54e4fdf678cb82df834773af527fdeaa13df84fa2308fd1196985623f755911e1e0853ea2d9abd7d469d82a8cb63836592715f5d8520755b9832430a508fb476aca2d9da8c1bb0c30fa3981b39e7834a456e13de0f19d37c91a241125f35a34077f4b328638098294d7303092435529df441595886c160ff2f558b5e0c342b514f32736a6079c11eaec23e986f50ec9ac4d70f91a71c5587758089e17ca857412b5832f899641d6aedf3209cba44b3082a7ed574b3a5dfbf5369ba002554fdcdffc5b1f1507e686fe3d06d6271f780781a386f472400fdd5abbe9ba9747e9322c562b18333406326806f2dd31636407a19246d2f219e56435c7a72bd52d4ce3aef8002f82e000e5ba7694a17744ace5c107913036adfe8237d697354714d5519b848ef6e39b13a9886f333fc674d44ca5f130d57c2798dd83a30c5f3336d995cfeb58a4af7570a735fea9d66e846693ea2c75a102b63a0ae7b953c51cadb05fcabdf84d4520b692a74b840d10b099f327fd283559775c30cdb82fa93f2762f95ab04584ed72f7d829971a3cb955de0a06046020828b9d32d6de7130ba5068031eb9f055ecb91fee8c58eed8e9f9cb88356450c620ae8eda543c53666c267d839389c32b7caf1e9dff661cd3b842b6e8b64af819de752954e643369b669861a0d29bc5d8242a9caa64d9ffe1bea94687fb2169b6d3a82219d95652f8e78f95ac2b41a57b2c9a5512e7322b526640345b9200ee8f54ea0a91278ab849e943ebb390e30b95f1c6ab3f0c3a9eb7df16b3d6d570e1f99c7e10ec65fb2edf08a97cfe6acfdf911ce92127d0eb97d7050100cbc2a853b91281f56da2a38b8ea14f4f9fc3439ede7d2c1dfec4cc9e5320c4ef15aa351b02bdca1831248d2042bff9656cd2dcd4e619fd11a66586a88d9fc3447f437094efaba76577e1eab4e17c4a56860c9f989925b8d6e052f294a2c8e4a0d4bb535b82aaebd60e5f55279a1d314ad4b18d9b10387bc3694eba406d60f2085258c387575991f709dfba278ec8db674d2e9ea12fc2bd0c30d742977bfbee9920c24e452f4d45169ad7996779d2b2a956a3caa932b94452f3894a59da1c15c3bcf77ec6353ca6e3381eb121492cabe9156b8586d8b5582b33bc53b03c8c6821626f0185873fbc58bbdfb31072a9e4f410fe1dd8d542f735eadd3981eaf29d6ac3dd1323010c1b94e258d27c215c088933f81352bac5decdbafeb3abb243100f18c609e140d776682e93b57efc5db13c1df64417fe89c6b7704b08fb51eeaaf66830c823e02938845456ec538a1c0ebf8f91e6fb31596c57c49140c6370d7c153563b69f935d05ac705b60ffac7108d45f33ba436f4beb6f436563d80341fcfc3cac5e266cf8d564b9a1d1c897947115b09968a23d4e30b707d0f195c3060d6b71d4b367bfb7656258a767185f9f7f69d5bd825384d7132cb5b87fbfe28bffae397fe5c4ef46051e00dd07a9b72cd06f573dacc0b426b42981049a287dd7bd0b1d41988cc027699e6ab550e8fcb445759a09890773e4fc8541236f1bdeedcc7932b8944e19235aa3c65956fbcc78ec85c6b0fafc92d61fab74eb0b2d2ddce333f4289e91791a55070cb537a64b55f53cd558af5dcce24ae30b68b73e6429842836f4b35f9eec1f0df48beeb6fdf5ff79508e830683c8007c230a51dcbce0ce2c22291080850ae5a9a1349436b0ee3ecfea689bd1b3c16993fafe59a850a2c034f02a9a71f66873529b74ca318c8834986125f6795bff498e8a91e726fff3ef0aa3ef3b5fd028d23ccbf3e07a125f8537812b694e828edfd95878b0606db73339a4979422b5d64f42a01a68e1b8a16641203f01443b33fbac2a062a9f0b65270cb3e106c84f502b823cbaec2dc26ed0a8b698afb39c685ecea60e51c35794af2092ef085c1df74ccc3cfe188c4466b7a37e0f1d310e1b438e10b2c7eac248594d3a8adf9c1a68796375ce682d452d32f7091dbdad105a5581c8364013d542e0b3a0e528987c3c8d1d8fdb4693f216eb4ffd5db84e4be09f79b95f1d6bf87b529fbeb3d1327ee4560823ff7fa6c4b1202ba1e4e4794ec472e7bac40a610c451814a77b2d950146816617410804133272a09902bdc75aca7378202e100fe28eedcf19d1d13477206a85dec5cb72b95bea22189ce04608a39f02a6b45dfd3e68b8532076d7e7f6a90de6fbb242999b890612b057398dc0271a9d0be9c0ef2c88129d0fdfaecaa383f197bd731ba37ea5738ced3abe820f9e804b1b588368dbed309e1a62c0a5a3c71af07cc2039b7f183fe40351d6d82a0785e085ad31593ef885a53358b990c4cc2c650462a05a3e963a63ff2b5decd164022e07046205611a485f3704ad821078410afa13af1205963767094a23233c585473f1002b79e8c1f22d12f241c48078826c36a492b0438a81c414541668aabc1c3066eb36da4a77bf7234336dddc5402a03bf0fe3503de1faacbbedc358ce719212712d5dae67c294508a4cf7092648e738be41a9c4a48eda2e4f386c187c851255390630029e21a92caad7d54c9cf048138355a38408d1397e6eb4e35e259c95e271b815d682e7f2afe741052d1b70c0876809277e067c62211a0f3a2921b2312e4bcf4f7aa44d0b57ec3e1c8fdad372e13a94aa9366747c52554bf7427f72c586b8191145480a7cbafa2c47862783a41a0fb2ccb1f0036d0e9faf5e5631a35668beab75c36fd5d6e827f05a6a1e5c714f3c493870194d35993218a55790d5af757520d484c97bd9640bd7422bb1d42cb2bbace5c6f5fda69840d95b4d4e097e657fcded22a9d297fd92507d8c0ec7cd9371b704133acd1db8bc6c3e1ab79f15e985a12349ed035bd02ea14fb539fe51233565156a9bd6df98626cedfbc934b9257554472cb75e6b35c986a20b89d41e4039d0f2615345015fd335187337d48d43a2b32094087f2466356aa54b0099104f0a95f92591cae96be5761dacc8c28909ea7b0296ee4dd651d9557177c6fbac2b549f9904303f652d8e808b85051b3078e68c524dcb64f4b61805f697948f24076667af59af26696e0e4cb59581497f9828fe61a48e547c60f782a4fc67e84fc9ac9784d42beb0881345060d544fe5fc3cb0d2846e732b3240caffcc60ea17429cfc9277e6515170afc4b9ac4b4f9c93f81b8e556af197bd5bb16186b690bc9f1cba7d2a683ea5deab15d10ba4d09c66fbea91a03c2242a4e1a0733c2e029695a8fd10b18ae74ef255c72a1a9ee9fd161d3677f3bc4a2ce9afb6233e0b9f9aa8b98325776be92498eebf9b2e4e443bca3af48c4c57ec280a68872e52edc9e76caffbc2d55b7033161617880cebb31241eeac80211643066b0cc04e1724e48dbb60d545db168a55e778f902971ec6de93db1eb56600532ac31f28fe4133ee902d2a88c2947907d036080d4da0d35ec811ea84148a98645f7ff9716672dae14c0c0561d895b5c17f13ca97eb0120987c4c9dc08d0e10bc86194f71e7ff8b5df8b82253d08de99f58bde72b765908d4ba5cf493dc15783cc46e435e4bd14a02de3bb1425861674c903a3e884e8d703294f68ed54e7e3ea95038b2cde679e91d7b25c33007a41acaf75ea2f0dd5f75ff8393fdfde6bbe300d66a95618ee036f975ac47e8c9f4313544e0f3d2a4287b82b1473368304d21d1914f5a92e2a94a3382fb9d29008950c7f70a5106f36c910d7d2acda31404a656d92f8186f27fea35910a43e22fb2377254bef888ad473091d7b51150ac99efba4b1b6c0c7889c86c27c9cead524481344710a20e5beb252cc380479677690bd9d633141a8dcb3b9285304f43d390b62e37018900e3b512871303f60e8d9cd1fb6c054b902417934e01f3660b0cc8886ceeba4d13cd7b6bc7951553ae520068b110bc1cce3711aeb01750c8c1f31de6ac7280320135f0fb5197c40f603a46648e7325d45e3df7e21cfda9d63226d3d5cc2d810556150fcd89d32747e1913d0237eafa57ab7646a15e1d0f7e928f19cdabaf10c089226bf661f41da524553c29379b763949f8585561392d604de93a0194701a7ad4824779aab316b452c3d61245832b28f67b7116d684d5ee495a49b4676028abb3cd18a0d1a44946aa0764ab0d592f2967c8090f4c7b3ea737598e7771a59d6fb5527eede2bbccab8231304b8eece0870966648aae87450c12a457ca021e76a7c0419551e9a6da4b6cb07fa53cebfab1d381b577207849e829fc85b26aef139d3f02ff6a55276b53ff6826125340c15fddf869757b7585e72b217e43af610c81729876da5020a81615e65d4b392e02228d2d498c301d7be3350919efc6283a51ec580136abd7373844676835c2acb575b4de25ea6cbc245bb31f394a93e39cb53c4cb9312431f58c4b12cf24b3e399844f02935c1b5cf0747ef74256084628427e5dacd6a29898b1d746b20bdb7e6cbd32a00d5f02139d3b679195c22f74a63dae4774b4def34752af12978848b33aa92f47632375db472f05732adfbb2ae4520e6246081dc2c79275daee00d32d8bb1176d7ddff20700b2ce913e8df552e4c8610ccaf03bcc734c04bc3888264fddad1985a9cf389d56df72e3335e08b265773dbb273742697d6ca04f3c1e7411aebe8d56b428ef06e3324026ef17147e11dc17f68635cde19596806996c501f4b60b3f6fcdf898db9086ccbcc8e37d87040534d3ce3276956c96184a04f2026327c26ac9b083ad4fa37749affce8c434f65de20c83ef62926750628674c9c2d8d32fc49e3bb0461f0486580582636ca890fa84f202e097926584d4e496a7f3da8f5a34dfa565df0236b5a8aaa117f773d2dc3899d9382e9bf5cf07c429431fc1392ff3460ea28353cf8b53ae210911b72b0f70ae623fcfda213b4d5ec7de833dd1b9c8af60948a422b7a9c1ced2a3151c3a4ecf657f91ecf41bf5a825611c50f691d1ad49444dc6a8496de21b2568062f6dc6f7dc9662eb9d3302d316282b22483012d595be867f40f69feb582b32339b2b97590a509722cee918e409e8daa367d5851d12e23264d3f6d073d81c25bca2c2f94993046b571b3a636ca93cee0db21a27a90836831d103b22f772a06ff5b61e4e074f00c0cfb8fb15f108585960cff591eb750f91365622f60a6788b460b253117e2a5055228272f06c436e470d56ba961789dbd2ace13c127e3ab9e600728ed4acc51c0e04ac2dce67312a7cc8903b5c0eb3da16b12a7f1dc40d53f6242491a940f0990cf035cf4113c12edeaa9533426627fa8207a78af9751f09e4c9c6fd8bb039bff2382a027b890b7ca3dae0ed1755c202088e88e1ce8384a66e6a9a4b46261e0de6f02b91e7e38a373aad6ec7dc9b08cd31b0bca184963eccfdc0f5f321c9a6760b933a73cc00cd59c16ef1b35506899fe830f02f00a2894948c36f934d6a7ce046558d0fc992182c9ef8322cf96d38da0e2cb9561306a7b8c48ac0f55a54d48aca0ef32a8dfbde94b278398bc645e2379dd76ac6981b2a4dcbb994c313d167d6468a27a8aec462031529d543d7be62aac314d036c2dc252b905344a8e278ee4ee181f3097f7edc64d289b148e67b3e3593ba59eb2adb7ed728d464a9cd06de9a410c2d2fc9bf31dd4897ebc9ead42ae4a8d201cbb50d207a7429acfa30347616bca4f497715a2523bbe2f1cc1ec0631885ee1352fd4e5885a511f85674a423598de4df2edc6b9e956f1ed77426b83825d444e461ec128b58d25176648b07f82e6269aade0b346da6781fde324a19c029e543fdc5382f8557046ec60be8e9fce64b36d20f9180f1ffb07bd2878f522628e6fe996ebd7cae35a713813d0b2a6e49b4b0d2fada5f9a6645342ac876b2aca5ea064fd13d9652b007a365370ff13f0bbbe7dd010fd7b294d091ef0de48e30193faf6d0c55e54d3b9adc1310ca826e64261755e4d5034e56a1f0d1aa13fe38c5af61105430fb29a09188e6bd23ab2b66819a5c20155f7d1fa011de8d6240e76808a8888ceac6e5bd67035e9711a26a117d67c5c14762f3f94c1e0ded36adadf680b3a5b28325331c9ffde477699d0f03dfb813176b8c4e7627959d1d877e474a738993f46137ba1a297b2534e75e4f908256ceb87792aff2a1f11ffe99ec0eff0e2aa0e4262715de4b79833d3eaf5226abc5846bd6cf061bfd9583b216cf248abaf1fd6070913a3f707ebb26ab86cb0b130871b2f616e8f5141378eaee594765b8cf649f80af3fab7be17aeeb753aa64ef8ec49cd32fc20dd5d1dd96c27d3cdbb581712da6fce8f987986f0deb441f3ee751339d439cfefff96560b11842f861d5354ef28079106adf7eb8088560e4a6b22074a849a588d5c75042203972e32b2da77bac9585fb23d7db17d42a57bc60b7d08054d953e64554de39a04b9c24d7945ef22d7cad9ddb5856b03aa400feed5aabf09d1bd60d06f089516383c311f7f78ac4c6acdb68c419e039a6150bec2e09046c2e4995f5bce65dd36209c3f4e2cc8054292f9f009e5f2288da554c560d8d024430d22d8b762a16d92cc457243442adf25d219a0fc89b78a293fdefeccc77ebd918629a947aceb601de8258fd35ac83b5fe228a0f328dad21b3e75efaade1081ec3b5a89e615f2489d72261356f43faeb0c0e02484623fae1d293cf55210752c0ddc40265ec0bf90613c142577b0c4e5faac573d715287bd2c21454401ceecb45722f1c144530374ea460de1e6fe0c3c3f2b3c9af1ecae2f2cbc3f5ecc10060a080a26bbeb23e1aed0ddea806df98cfb8fca05e9257e1139cbe7210e427d6af98b5ff0494bd4edffa01ce8d848efc1e34498b8a9e38e8c0d05e87fdecd368ef87d9845d2b0b34706cbd67c2331d22548aa410e88f2a7596d4e2df9d59d165b2bf4fa973386d8a6a7d15144cccc38a436554e0399a74a854e375d2faae9c987d99cb436e7da3ba0bba64821e390098571d8c2fa65af64681e570432bcee2003ca1c0b2d0115e87648948fd30b6ec6edc1c05bceb6d4154fca13da8b4df9208be4c1f33933efb2556f88715ff7facd00044defd8cb25a65c1abbeeb4656146fab35f054ce56ec50f1ba0c512c52aa02e5688c5069e12fd97d802895d459cdfa4c06c71552f75c1fef78f1b2e5911ec819a004ce2ad3c5548b49d52e09e9dba0907351bc4ba62911eff30bd56a95358cd3fa08f3e9201e85069855657eaf5834d5d52544248e08d387d6f75c58d4c02e2c021044fdacbe06eb5750c4fa1d18631af2d6ed49d79098774d4f6ce2a6e44d3d27709e05331b8de89c57a76cc1c0336b35a70cc4ccf58047d204dc7a456bfba0041eaa8e35992ece03f2982f97fd0c5d640d1c550c4f8b8ca071dab771364b32407a967741b9ad744972005361f29fad3d36a36e7b7f476bb8b6a6db48e02beba9fd4b2415b71216ce091ec825515da0251456ca44f4a2cfbc00edd6507a2f44890ddfa91d96c234117f87014388b171ada3bbec39e8109a96cb0a1bbd6c9e2bb6223b64762e0be0961b7e1805e82993ff9dd181f5d13e5ecf52d67a763cea9859603f27b97bc54ce62abdd9d1e18a107147be07c8b53ef2488c208ba23abd504c51ee8796b24ccda856bcdc24cd2a82524bf032d74b502d14588dd3b4ff3b7e1bba334393ed6984406714eb0a67192dbee2ba5783f6b2c20ccc7f4d0f6651059c548f99e65287da537d0a7ef056d5be81031ccc2229290053dd106232a517d40013143ed9c40a191dd8dcacdbcd7a85c0ff0342ec32f8e2f65a8ad45ae53bbe4500cb9ff783cee8bef7060d1c202354082fc8ef0e8fda0b09f29144210ab08386d30d85872c603442a19fcea13d58b25af1abc43e1440c2c1671eaee9c9b8fdfcfe78e896a0d3a08917826db2d815eaf9751caee6230466f25fe00ec3f7aa2ea033698f68b830e702c170068b51c3b80270ed68831eafe352a5bc4d5f0608808bf2300d4517f620976234e846852c629bf5c1f0e836280f836d336e0e674de2d8e953ca58ec744fa4ce0f6166a6519d8881c37d3ad4babda1f1f06dc81746a0ba281d85ff7815c1d35d417fc7a2997f8120d1df0ef67dd5ad22ad6668aec5ad5a2d240254a74faf79d9f90ddec61d0f426bb1828868af387edf13a3e87e0409092e6564f80370591b80a078a2479aa6024a7223417141dfe94ac6b0ba87632773762db9676db70b390f0a2df2f63501c39195c3ac463f1aaeb0e3c05111217505fe3d4077b33904d06fdf348aabef16d160fe25bec9db8b6501ae4cd50fc9d038904b932fba76e68eac89a9e675226da5bf35e16426a86ba2398cdb5df39730c6697d5b0062cc12f256bd78e83b295be22181ec09280621f256113204f8e34c49acb713f850b5649eeb55d9580aca660db1ce28743ca196f7b26afc5b7b6b6a67ed140e4713c37b3197010166d05a53d27f5ad16b86491753d3e2f391a48359c400a1fb9a7403735323392e539aaca2e5cebb545a5a32017433245e5de1248a1d6955e09edd3114a9a459482f356280aa2bb98fae329aa57f85ab969fc55c11798291d3cf59b994dc555557b5795c9b32ca1b9442d99c19210aeec001daa39d94893d6a1e29a831f34a613c8da73600255999931d4c7390e64ad457f9b602e980400572e39cd1b88e5c9f052fd930db7b13e5016718384b370cf7edd755ea75a73c736436a19d03215fca359f663c7af0f16818115b9033cecb7072ea4560f21de6d44a0ec1abd6d9f3af81404a78d6bb666b5912105d921fc65febcc9f272db2d30002b616d477eb18e714866b6e41890aee1f3b4061dfe4b3d23905a67a98a882833acf6261ae426d0b4344795e1748248bc3e89ad48af708e13caba08cdee3d3b94dbdface923b309005973861868e7c9295c34521e0906ad854e2a1419a4e5b10278da3345fe65ee728c81a61dd348e2e3604680285d2402085b52009a98e1d4e61f75e17eef53aaf407bff9bed5b07b891a7030d7eec01a3c3289d749a6adec6f78b930b702fbd3a8bb0c081cb2e11cefa88c0c0c3e7bf036aaa59cfe626990dfd3e85ecff37a0786e25060b91933a266451ca90d03c73b174c7f00641e2999a7034344cee08fa7d44043dc7db3676a00a5dd586c4e6fddaaef302db3694e511aaf3302ab443525587ead793bf474c7d3b6e4a3192351e83275319fa6cd042f962cf82aadfded240c0aa2dd9da2a41d60c8ae75441575a7d1e638a797aa512c20ec2acd380c3e77d321660ef8eacfa32a4514a28fb601e8f87f357eb7d82cd167c45c4969a3af2a0b6055d046d866c5d9ad8920eb90e64d7a2d4734713c0915f12444d9782e768aadebabe43373fc139fbd605c4dcc64ed934c2e1130b2ee25bba24fcdb1d1f5559a55543bec4c60fa68ca079ddc53e9dd7e4f447052dcefc61ac20f8c0da7de6dffd62328740522d9e5e7e8cfb119f86009c0a0c72dec3a757ca64c64495d9d16a1550a3d74bfac7aab8221bfb6163d45b0a53009fba81f259d09fcff4a9ee3f30b4303afd87a23789bf1a63ecaae08578d09190ba5f68de5efe8c920a922c40373c139ad601506b2f4bc60e2129b78826b17ac5d954de1ac14f899a603bcfa2ca18742b3d84a66e23da145b4a3c42ff5c773a62226c8d6a8caeb50a208908222b2f601ef3c37599a48fd505bab6b90436c5cb2189641dc542603de80c1bee938e68a0c28b48e6857c5daa05ce25c4c84b589b3137b280c1df8adb5f4417a497947f05217dc888f684f6873793d12caf19dbed38cc967e408b900d239694a982ec62b7abccaefeed39feeab13aff90550e70e6e5b97c2f664e8b09d49df95b3729ac67ae5086f03261c99ce9893e7b7c1972822bb50a06395a4319405ec18a632b53ba958dc67ede821bb0ab7d7b36afc78a9722eb3cf92ce6619701f55333e845b22969d4a896b8fc739ff61ab78b66242f3041400e8045eabfbc66ef5c4082b2c0990b31073c1332480aad092714d30d082c5ca6a74b9128c413c873726cd010ca3ad4dccd442fb8551afc2fae2ddb82a5622677245814dd6c37342af69c895da809f94c4db3ebe4232ee2198ff218b17b8fb9cfb36747aafddcc32a02d91ce5baac5fec92107d7f2a891baa738867a0987a92f8c2407c8f54d74a05e5310a2da05643be465f374e90f8324638d86e7aad04f8e78e58532eb0b1baa849183849482f33c2660a9de2f5e50b245b417ba2ea706a8ce83c55543fecfaa8816301d98f187670088c9d9566cacc2941a490b470867085ee2161786d1177d07f673e2c0a8651d868a4ba2b976e0f2f8dd06f2281c2291b6a92844ac498f929687965d36d896adb294ce9c643d0435c05979d56d159ada4a441f6101b69b8bdbc114102f63bac7ab7ae99d62f3237d4fc4fefa46e8e44b0f64c847cde1ccd209f135b8c391c4a441bd2c2813888f62b903e46e6d6ea1f835818cbef94196323d420f5a89ba871b54982115415735db870d14297cf51d844e6c059e8fe85d6edeb533217611da6b19487b3aa91d41a006447654a4eac0a0f286982eaa3f11d1ef4c4309ab532bdd7202a4fe76543a2c481d450055fceb279621e445a4324b4a30cb73bdc817d6e160dcd84ce914226b992d106e291267e4824eee77c0a9d465bcc8caddcacc50b1b2642c8448e5a8a0f826ee8300e2e0890ba7c84500c22a0380a81c759852983bc24683ab87be4814ef38e2ed55a3e00400c3b505dd96238d178af20e18b40a622bf6974d7a3a95c01157dff989f8d2e2c9e75312064cbb8963ef7f34ecc400730d482c3e4a9aea1ba95ac8dfd0a264c43694b03542e04e9034f85736c5a14a6741115453c244c33d87d9829f102fd9f2db3546e166b3fdb1ac0d4e7f49e0e7cdc3e97e9b0a9d2b968ebc04edb20bfba1da7b56e33d8a51345864119e91be84653069dd51201cf312abf895271e2a37311dfb3a9d16df93f669992c6dc4b208a62254e84a5b65377632bf89ff7083db0ff0c332e9064eaa61b39512645774d0e229333b48aa845b4f4eb8f93b8e69b360db8639100db2b50ea1d4b0c76b8b33c4b620cb528162665dbb716581c7759d6c9d2cd8d631b594a474a9e21bc65c048c9f6716cd4b9aaae4472329f49a7b9bf8c5b7dabb606cf6e47930f0df472f604a2a62e03118d07ddc31746b9aed06d79387de62e286343f00bb5fd56bb02373d25c62eb8b9cd082689b50bcd40aae1b9782406b789695b073c271d4ee38b94de5c7d178b8ffeff91d46eea483089603f37804bf83962e656543c2324689a71d63423f88fc2dca29e319045b90c6050f19b74da2b9845723bbf2924208d8b65874a13aab6805db757a398497e9a31ce5f011d3076e49c6a271ae7dd147418b061602753ca51e6a2f7f4e366c2ff4b992719d174bf3c21dc1b286800a6724b51b1097d1912d3ca829da55ea9850e2fc19aab11bd571fb743fed9285790b98402741110da9e3899321f0647c243d5cc2c7605286a4475108446b0d46c2aa985409b083117aaec0fad22d080401735358cd4554decc2d09f7640b8ca7a719db6b129f72d298b6381d24f5ec83e4e9e861300fb2d6c00f34fd4d78b619383106c3aa5093274bebdfc230b8255bf44c49c6952e1414594f66af4361cf24e1734a3e36553297e296496af7d8db57c5af27243b959d51f20c7eb4654a0ea2593852adb900b5c90c17d03aa8bd8e6b9954ed47653882157d694853eea42c8cf59535e1a81f7c0567c45441d5a9b4fdd7bcc2ffee32106a88bf1921d66970313ee34652c7b2db0c41fdeae14d3c0b93832d497bb572bc004cbccbbbe704d10f2c7018fbc2aa4b7ff151e6eebd78d87c010c88c11c2e799e9273ecebcd3b2b4d7eb3be350bc15a8ee8d648cc49115a99c775ad63349caca8e261316b716a94b99dcc9b00a72dcb9cd8448e470cf5d90e9c5a6883390eaa4bdd84baa353b949145c98e6ec8b979ae700ebb7c70b0a2f9a86cd3d94bc6188fe4719afcd7394afae850b8b8a57c1ed6ae883a520084b317667408b69296bf68a92c51e0b00910f11c1a066361ab7cc40d01d83cdcfbad8efa6400c7b2b7df9cb84b6049808a74d860d18fa8f347274977067aac57790114c6ab32bc74e8039b06ef158cc5ab529e8b57b9147575f9885846d0b365ebd0e54b3d60171f0bfe7ffc2445f5c610b8d00cbce00e62b43e14dc55d2a32d63f795746c0d9c84a09d19b0720b6522e490447cb42b4619c3fc12d125e0484836180364b16ef6dea3403c74d9f92d93028102134dbfecc0f17c46a4d6317c5cfa69ff395aa84bef9d4ca8e4a81fe5b9e387e8663083d098f69e666294620842b804e0b10d7e5f0fdb2c30e7b19c5d7ce9b0bd54f5f5c4ef25fd8e83d22dd6201cf5008a0957ef1610e8868eff4b34382ffd76a5ad167718a0970451fba13a108728a21e040e8ddb9159e2a4d66990f6de00e9f4a49da729bc994f32fd21ad4379c602b13edc5ece29cd88c161fb53e7b5bf221fbfd1544b408cdfb9b69738c0f444c38af947f04eef7224ae440e85ce81132ed20fd6a08b7e7c7a22d5d731145bc1af3cba061f15d7ae04e76aa435bbf6d5a20cd051450cb00d054926f86e832992c800f82a449879454bf11d111e40907e146d6827956a0d0b635c054e844b43b8b8155af0a47b7c1b92f9c177f588afa6a15e7f2c318bea4268bbc11af70604ec9be9f6165d827ad68d513cfdeb919beebfa6f2b92d8692d4abd2c7e1c109e6c2513504cbbb6cadb2dd4f45504b77f8fa26581d6a7f5d18250f8289d705dc1d8bc2d46c8c8b56a3b6ec5ba60bfe37b8cfdab5e744706f4fadc4814ebcca050dce2a784d8fcc6c994d4854f977394212aaa46f915d9825b331f921ec956e6e5a679d0b0e4a4a8e3b80ba385d93016fcb835f415f4ae21fa8685c8df21ccd8c4ad0d20dc4cebad442240f415d6839c597d10f8117d059e0533017288bd86258f90a03710924b1558970333af678dce4bf782cddc68e6c849612a8cf84d7ee199579676266a383fa729b69c1bb3fcc99e42506f55293193accfea1ca602199655b13b20cea5849144a48da0d2bb7bee180f0043134c7496603a65a4863ee49c0d77b724096229b309eb6101274202e2accda05f0c0c3b034b533330c6ce3b3149bec663e2ff0ae78e2264739ed3f79bd4c06cfc0f54cd25f655cc5b857b92be8cc846f037fc398a656843de93789529a672d354ef5053ca722c71a628119cdbc89539adbc011256f4ef4013751bf94622331b18755b188e32079e0059158dbf2fca29fa918ef5096a93e27ea1f9e7b9586fb0db0e4ce103fa71927c5a30523a4a1b557ba611d5181049f87b5d3578efeb15ed62555c45c95e739dc48d5d89b1a19346eee9649720ce20be71ddf7cecec471e3790bac553678cbb848f0a2321d57063ac65bad11fd0fea13d44d12222989482291bd690760084e07b0073203ca3f72503621eac4f840c0f5af379d7e867b4ecfa8437fe6d613874d1a6b4a8fcc7d55fa56383125ac63d7755dd5d0dbaf32f63663d6630880bbbaf247949a2e65159675adb56fb19bdc7f89497bcdbe0848763d92f65fe7eeb57addae6bd332eb177fd8d192f0b2d30b76e207f8e362e211f4b1711fe311d1043bc62b95abdcd33c8d5ee2499df89c0d2c184a1d4b7b9e3427b566fea491a86661463b9256423ac16234e0e803a683e455310fd8ea0f9fa828ca96ef590587e2cfeaa3ac2af0a5a2c71b04499ae9ef859d197961cbaf681bb1b634e92f866dfa6d03024aa53e6f67db7fbfb36ddb7e1b4a42b76cda4c992933fdd7ed4c675baddb5002bcaa3c0b226902acb7d62f86bdb5d6643299be6867d96fdbdffc75fb9a724f19f8b587d956b4b79c846e0dfb2cdffc25d998cdd56399fe35bf7e90846e5d61e79c55aa6acecf3dbab027dc39d20eb955b9cf97347b8e30aebbb95ba77c2eb54a1527f6c42e480487e4c79f28a0860c410d77ce96b342183d9797c72eacdcf4da2aab8fd10cb3f7fbea150e81e14f5da137037d78402f7e0761849ed72a6bf4aa2a75304429c03ef62d60df02b744ca92eb97d4c72e0da50e108c5eaa8a1504160a61bb7d485eeae89fba62c04203e0eda6674c8c7388e34044fa56ab351d0825c4e8b3aa755befd65b5e1c41ce96357abfb3054bfd59f875cb4737d473c884518694f51656cbb2f4071f47f4e1d5e73edcc1e8b6657dc51b96bb68647d9dd6b2acafea4c22ddc15495e538ea43fdc1b774a53f77aaa30a28a594d2ea734faf023a84d0e974a702858218ba6c8f12dfa330c07a9475fa8c925616ad547644e05aa5cec49565d518e3ccb9d785510cc32686490cc3302c6298631886c11a42955583449905b99910d72a8d6adad4344d46d7340de20bc3988d0eaf0b5bb7d6420cb3f6664259a669dbb64d6bc7971046cf9ac3abf9b6c19979c41056964bd5d0b48728c8cf77fc32b05d6f189b4c27df3dddcc8c27b42324ee1cc8d309e108899b833cf06b788c31c618b5bbfc19a7749f4b61be54b992f4c481982fb0d003949a77ce2b39135ed9baeb6c6c6c6c6ca2436d03521fbb00906a3acddc1e39a7ac8935355e032fed83e1749a99e1381a9a1a35f0c6aa689de130e73457484d07d40175b1734a4353a3464d4dd779363637372854aa67e762685574deb821a35f35375046ef6cf00dbe12dab0216dd88836bcda6442379910148ee3407983729c6843dec09104ae40638ef9835be24ef5ecd41c570e1682bd317f292171dbab23f3349d6d07e6c163c29b96f15c1e8b5d3c3cd5e27158a37d45fb5e871107077338703e5b08b5ce9183f32204f403c210421041870ecfe33a211d6ec70e1e3bdbcece8eb6b3b3b3b363632313ba2184c3a3f615ddb89109898f234772dfc91ca1fc5c177de7e0703964f41c392aed33a7391c73721cd29cf5a633a11c5cce0de17a16e48a0075441dae83e66428cc9d5474284f803d4f4767c70e1e3b3f42266421beaa954a553435654c792a958226ed2bd2e1e9e87411da910989bb0708f2b83c78ec509e29a3f3c0aa7d4b3c2f13e256277ed43a3b78ecf08c20a343c8b343661d3dc6e831422b7ff59bd0dda7363f222866f3d8b163270bc22313a23c3221d72828f8bb0e631129401581e107459e11a4ec4164fbc748d4790a0001c884049009c11eefa9da5734c2087284e8b0070a85d4beb1a3fe260081262c8c6e44c6996c77aa69a414d248e98c926a0de91473ce49941373a0110906d260a7f657043f3772a31d03f6f73d938804c03be0f8dfc78813638c313a86151cb2ed1923b7a5ac01f5e855abf5b562dc75305715dd441ec444d8092184dc7dea5cdcaa28a5d4a97b2c62d239e5c3af43f2ab6ac99773da9b1e2f289d93cea9ef3c83fec420c5bf0ef94f2d44df7277cb5d4f49abdc3306ab307f5214a8be728931a4958ba4f690fc1bebc72b095b0f777c5a7754e2db7591d4aef4d07c9737d88ffe0d135809dd951ea25aeaa1f83ec3d2972caa940942861bb24c1720e1e1080e2e3e40022f5d0081cb126362161d30e388279acc3082262418244a62e0a5035998a84103369c71045a31a241135f9e30592209337e904598264884e942c90c2906121b4c0cd185164590994195320a10850c252652c2fcd0c5bc922305195e6c20081f34d1032ae6480f61c0600b285ad0031371cb912d3e948004484835f8820c19908104298d1ea028230c2c494954073598628a256a80d2039931908821a3054300010aa32f35d030530922c8a032c4132c64446024c34042811684e940131fc22c9d012684230f0021cb18198ac082e6e0c8ac02c9092ef0618b3159a0e10130a81847ca78312687107421811552fcc0831eca50d9e28b333e3066098914400105151a7ca1e18b1c03893efa000f9618d3449829611cb1028e61860e70b86203165ba8902408c3064e0091a481249070010e8a8408c1126472c032441857c0e8c10f860801164258018510f308119668a207625809410c6e9853e091a9a50b078a30438a1f68918418f40bdc12850cb4b84203661c81c313934a1a5794a0063878f24412497c8104822993c609c68ce0cb1667502fb48031c313204ce0050751ba4092c2165d6cd081862852ac50a5235420819409242d30b1850a25c48069a265a6801a01c41622e822461844d01b1c992f80687c6982e54910aabc400772043f88c00654b4c00a0e5ba2e002890c63c268228827be58c2872d907c51c20834c290c18a3368a05e60900ca2f040822bccc0e1055a403252762042074fdca0c50cb309241698e2041fd042891b82b0c2060f38e38805629630a3075e680d669214e3e3012caa4841175e84d1046a11812aaca46183204ee00507ba1c296201106980b105193a5cc981d200491454ac30da010f1ae08013740631d00004305ca0000733a2805e661648341bcc20450b30a688810697b802314a3ce921cc0d42d02d47240f31474c3027619eecf81188f8e323c6075a01e365c7773137a72c29fa7895e84379b0e3fb951c36ddc1beb82cd378043525c09f2bf952f46ef08071fc3ff635f237778d370229c6ecbbebe6ed7e6642366f6176f3a7fca5f6e96f7296bf157676cadd679928b5b38f9910f69f27d5f8a4d3d1c912f87327950cb8c6bf67416abec607c90aa3973d8ef74eff383e6234faab1be37e467f7e0c247f6ee898e1682875362db5335dbddf6c31a569ab54e9d93769ff883ab08a8d118b91d43f5ec7bf7127db7abfb9827dc79bea3f586503f9d20fff127d28fd1ca3edc41dc7cc97c2c09f4cf912944792ab9faa554b4a86061a68f0bfe63412e44646bea05de92fc85a7de7db9e31188707f8835a64f6e3ba6ac5b8ebfe33b8af8d999023f1439628367d0c6a195221f14396a44d6b75749d4201eae931e14dcb2e10166310474675fb58f153138cdb6b6fb529b0efeddefb4375fb6aefb5d785b3bd32cc6a1b5c98fe946127d3fd7ab7ec3bc3aa1635acfd479fa86947f7de7befbc990d2e2c135a68616484e52f67635fa3cf497f7557bc4df0f49346e3199a65cf68d9333371e6bf222af42b38a33fece929fb36e5df387f38f6fd4dcb593ee2a9093108adb5461b5fa6ea4e297dabb2acaa48ce105007faa81fdfc6c6042f6c19718e990026ed6cdbf3e3c76967d3b2aba4b28ab01859b08108b344f73697aac9356832cc33d955057d4929a592beeb9ee8590f923a99f0965d8b51ea4facfcf564dde34fa24f7d8933b5397fecd9137f8252330aa5d78362a27814291d8a01dad388cbf9fe010155203cf9032552f4a9a46c229bc826724acf8532f341d18b3ef2639229e22cd0d81f8dae2a897434f6855536d4017fd5dbc7feabd087c7587f75d39aceb47fb00aa55a89dcf46da5844aecf38954cece0edeb4eca6a20d49db6e94e6bb1b98053f2adf649bef724d9e791aeeb5c76ff115b072fac32793ddeae55996657fbb1aefbad310d6e81aba66dbe38f3f61968d31bc7dbf313621faf8e3a4fdf2a7fef7fb7b47bad8b24a4846f5dd49f4e2e32ff873244792187c17945c3fd951cc4cbc5d2cccb9aeeba29452eb9a3e57a67f5dd7755d9665ed58182db263557fe5b96bbe95b66103feeac4138a65f1a665106e1d1d1cdda6bf0eebecf8f6b2177677f6ad738b9d1ccfc39b96edd8186d88db9b18d9d37f75c67f382fc1f4f4b993def8b7b75b166d599f3fddb608ecb2bfa2287b28fb216b6b96bdbdaeebd22eec56edf433f1badfeb2f7bfb417263d7ea0f76b96e3fbcdf4bf06d6b6233b7aca75996595d62972e996bf9da7a5d6da30b2875826203287655a16f3f888691b5828454a7acb08e38dbb9ed9d9bde5d7f443b1bff7d7b73c5827d63ec462f76545bfbd6d3fc153931e9aa318d556ce6b4693965d921eb33df9b56e464574af5e6dc78fde7f4f70259a0ce71883afe34436aed3b86d94c04bb14814a50c9a1d276a0ee081503fcb90f108d1d7d9cd817e4cf49fe489de851fa0d903f3fe857ab8ad3afc3315be2aad6f710faf5c3080c922a92dadf0ad8dbafd25fead2f067ef5bce74fe746cacba2e4d94b3aba34d8ba436d54377a691fd4d5dde4e4eb5d65afb35887dec83e2951fab3999f6d95c4e4311100c981e860c98be060762d24b1c88e9fd6bc41bccde94ddca4bdb2d7fddf79f8e1dbf7e50bc377b98ddec7abfd7fb755defba48ce1eb2bad3385a89dc4355d71b3d9ca26558014365432b631ced6e432b6178b095c43d4497ecfa18e68e25895b49c5f2f5156696c6dfc470ccc61ec3bece8de9fa7e6928a7d4fa44a20fce1ce74ddbb7b6be045e637c35a6ab43d7f9f0671ff5634d4718c40509680fa5cecf20cb940122e5f31fe265caec21a222ae89fca1c0102475744aeac82aedf7dc00266d7a85942c530648a6c542f7a3eba856bde97b0f8aa345c5b3735b6b71b6cdc9d976d3b2ebcd222cfa0e8a78d82da59f43297efa3350fe70dc9f3ecb50d9cf3c0472d24b5099462960db6666def4309cf457f73dfdf60d98d1a687d9111666fea497c02a75502b68da3b10fca8161c087e07f2612d053564c8fed5307a1d04a2d5e8ddaff9734ef4b0d4a9aaf937ce237eecf40001459d1f55918df10808298c5fa94fe833dfbfca775da55f5c8ae042c49e1f87442e457079b267915b5d8e31613552814dbfd60af557814df557813d047fd2eb3fa81dd312de2118e052041727732b997beaa8efe5520a5ba38f125a2bfdfdf6b1d0a36f037d6af4a27dfa1df4713d7d6bb3fc18f6f13be8436eecafdc411e0c67571fa1577dfc0cea602c75aabf740779aaf9357fdcd657578da315ee64dbcddbf53fe2d88ef9176dd75f7d0a03ecfb8ab8225225e697ce96f988efcf8fe60f196387434d9dcda638e83bfc0972273b48fed4a50fe370ff00d4891f97e24ffd751b092edd80392a9f1f595d58e8357f3dbbdebb2fb72fcebe39fbeeecfbd04b80dee36a9b4d99c6efd94353c61868918d3108ea55911d2058d29e32fbaa7ddc5cfb8b3dcdfe16524a7736f6f52bac6aec87b2afb6b705c06f59c11e33219f655b5dcf8454ffed6c0f8abe594b29a5d4dddd35f6d907492dfba699fe7636fdc135fee0bfd4c24cc80ef601d285ca9a73caf8517a9c310a71c2aededddd7166c09f57e9cf4a0404747a82458716649f69ee37cbde5ffe9c2a9abfd4dea6eb6ffbfb35b9060dd6327ab5ab65d909706b7a9e4cb46e5a6541e4cf24d5964f935465ca94a95ba45160d93ef6f7d29b7d633e5950fd97fa56d8b362d8c2ae6a55f267554d19b140daf32bfbf153a832feb9422985a8953f98a4e5e200891fb69450e290b976717dd79f7cfa36cbd7d72cf74df6dadb2b13d22eedf2781dd92ef616dbaedd58f6f5c8d5b2b77f3d561fbb6c9642d1ce78e2ae1f5f72ee9c007ec88203cd2ba41894b6f555cf18eceed42184103e9c4257fe9ec89db8932ddd0996f9d39a724a6e4ba93f4b3ef6d8755ddcf5f2edcc84a4f4cafa2a3e5137777443767029824b94524cd70594caf17672e4ad79a6653ae5ae6fe5c5393b2998049403276e3bef964d6ffaed31beb2148ab6696b307ad7d34a7bc8331fee9f3fafbd30fa571577974f63956d0352749154b1d839abdcaeb1733bcb72db78b1b86fb2bfd7da6bb32cfbbe70df6cafefb7d033a1cb923f6fb8bb7c1a7386e05029e38b0a0afd59299d4bd38bd8bcdc9f385d010da3870202fee6290575fc973adc45cb6e129654df924f89e694ef50cca5c3132cf214e914f1e33b3440922d9fce4dbf4ef74ca88a2f33d1dd3152ea35fac49f918a20ec0ef4240584b7c3e3e04c20993157aa16dc450a47f33635ffe10db91f1f38ffbd0f8eff727c6efce7f9d8f0f15f6a93f01fd01f798f12508ff2d13dd41f4dbe79541ec0771967d764283e5fc3fee4018c1166cb975c0daacb10cbb6e1aedb6578c5e608cc4a972115b562dc75ff51ee141809fcd5db6558a52607e049c841de4716f2353200fe270b3d4e4efd08f9c6f7641c2f808cfa2e432936978f709fa4ee1e6f6fe4111e47ee795416001553173813a2b12e244319244779030000a1548690077a3d2cea863702576f97e10b6480058d11f8abf8d264eebb0ca3e09ee66d6cb8e7381bee761926e54cc1dfecb20178e872016cba7499009c179adbe51fdb5e81bfd9e5126ac5b8ebbedf9e974a755efc6420df651fbb264339c0d3fc7c8d03bc09f9e7ed4f36e10f90a3bc0700d2d5f0b0cb24d828e3f4f183628c31c6184f32292949fb1a244934c4f8f8a2143d2f38d9bb401e2d5227cb95ec4e64a70279b4d871e6e3cc7f914b0277f9a72607d4edb20f764597078071d1e59eec5f5023f3fc4fde8f93771e95773c8eacf35d16c0b6c947509fa46e1e6f3d5e2e43086b32843b43b8c3c3eab143271f8190c7480c465be7adbc34b9a6e66dd4bc083535b3cb01202133f1307100f149f857c2dfec3200382df876394526ea24e16feadbe51e9c14396e974718d3651e202575e37cd0c3e8e1b88142039b508f7a9ae7dea9a03ebebd910971a8f7501c0ad3649bdce51d9312feaa08b7cb3c1e6254f6c9f931972eefb071464dd6f135b2f73f39e8bbacb3ad4d969b8b3128bba703d3641b32b5cbdeded2c58bd29718268e893a34206335c1dfdc71bbac236b419745e87208d6043cb7cb395b086a72085f23e7fc4f2ec0e3e41c7f23e74765111e47d60f9409f05dceb1b90cc5000678287f88483fc238e9e8e82893f025641f06c84c7ebe8607f2a3a5c02772f44bd857a91c513942bdcd8b40f3dc5b2f13b2d129146d08211a9506f60821e7e402641873e89c6d641f99840ca30e01725cea94701712f28ff7914b781bf9df06d5657d9552b7cbb9ea80bf0a80dbe5d7b2a58b8f4c4206ca2ec665b07bc40f923f36cca872254bd4898f83237b97e879c9aed4651c1b33a2cb37503de8b95db6b19fcb507c7c7e7072cf002e0e6a7b54ced91598f3b95d46d964a75293bd4af42a19e06f76f96673198acfd7644fca5e253b8d8fa692e2fec6e6f43701f93354e213aff245208e4c2327b3e35f2f351379141fcb1f66d4a926f2285be2e003d296a7a29ea8821166694ce1a5ac17766528d80f134e889ec49e524a31aa6d76c01fc678d04257b042ca0b51ca082c44ba1c5ea864a4e3f0822c2ebc07c2d09903936de32f5982e1143938b1bfbba39414fa70337607b168f8ef5f1915c4fef5715f9f659402f0df4761ba05540bdbbfb5305b80c6850cae040474420a2c044d89492bafcca4262fa015b000da3ffe05f9037f85e853450cfa1416b629d1c7faf8275c81572ad00f79cd8b5ed575bd705d4a1ba752de77152e2d0002712a4878bbf4bd9db0c5f8180f49f71ee194c14058941fa720825dd522123dba2fe56cc72943e528c658f557d5917429ef9d4424104fa6e094c147181416bacf0b6b8555b6a29765458b69d9a11069d179a5624aa6a495722c4e2eb6edb2b0edb3b7d9b6592793c5f055ad4bd334ad5a18ce9f3fc9b4ecca6a666536bb19ceb62ccbb2ccd2d6c3fa4b6dfe24ea443762c7d732a49457bbced2d5aa1615d2487fbe67fec6dbf64b6dfb0169f64d883f2e7cd5277bfb37b20d1c8ee66d7297617d5b6766ac9a1a341cde5c309994f0df87d643ed743a65990e7aabeb8e968e8e96e2d1921b19c9997884d5ac565c6b05dab5d628d68575524a5f51ae2cde188f8ee2516675448a4947b5bad157603086611886bab1e930a3a5a4384d3e20a57af294d5ac2e549fbfddc88d6a8862845305555512f6769c28874a49a717c9d94352d7eb2e830d4af287685403e6a287f990b2f43fbc292a7fc6915ffefcd31e3b7a07218ebf6f3f3b8e6cca1e7573e2a287bab9c16167ef4a5fc6ec48b323102612c986a92a33cd859d6938af945856e997bc6a8555b6cd43f2e7e7568c16b6ac9a1f7af531a62f3d87c86da94091c4c0202c9fbe3771a320729bc0ba419c49b5a6c41f0752ab13d1a3bec5b7446f8a11d047dc4044ef6807ccd5ffb0172f4b4a5e941cc90b4e5735aa732324952b55934ac2a95143662643af8c3f85d4a0017620f3514ea267e56ac99c713a207a2c78730758e6d0e03ed4d0e2f5442fce1d60a951190b90e7caf6db4490092bd4f0823fa8e4829c3ef4ff5fce6a42f4cac0df4bcf8464cc9965e01863ec2612d6d34bb8fe8b615bab3fab8a12bc8f5c9f046fe83dbef70b277afed8855595aed14b5082f711ff24d84bf0aff9bd878c1173c1f2adafe40c5275c35bd66412d630849694f2f3f0756537d72a3a05014e10f0e747f15f70ab7a3742637f750355f94a4a5dba402db54a596b4de29bbe53aa5128e8214b13d144d1f34ff544cfdf03d890f9c5b0e5c3f0dd0f03177861cbff70f67cf9f2cadff5f5ad4f6eebb3b6f51f8e6519b176d543d6e70f495165af28f0bd37a386dcecefc38dfd25effd7bfd7529662de6ee1935c4fffa4b0f5dae3fd410b92f6d7da67fd56b7d51b9ed3f5fc2e8535541719b3b16e176d17477f23bc659ab1860df9dd481690499b3aa26c8137fa681e15bb9304cd74b88dcf5bfd63a2bc9559dc6950a70bc4c948e3ccf842b4c9ec0401bfb947b54b06f1b23d0864040de8ed6dfff07bb482995e613f80baf9eb63f99b2c72eec8d0a78e5aa441e992d5fd62c5a556cd2c2209b69ff75d8572630aa7ed1ae4bb0ab2a1c24ed6f2b2f1d117affabfaea11df56ad2c9d84eeaad2a82173573f77a551d517ed4a9aa8c636f08728eac80f6242068e91df754bd004a5c90ae2334e8d023ff6d2eaa21731fb1447c88d5e9cd782f46de5740aa13f67177db069adfe7ca3866c77ecad22387b08c782546afa714e3b5fc87ca1ca55747ab155f96bfcd7c33b495984bac936b9abc10eb05d7f5516d837edb1e7d7d05f0f0e68467fdda95613ceaec5a84bd9337f3ec6b5fde7799ef6f171601830b6d01e422bb6a6e1145ad52c4dd31e4aed09007f807e401ffe9aa601c91f1f03ea646000fde748408e84bbee3d0f2905b4c3401e1b4db0fc48136d0c7270c54a1949fb53fa7120622cd5d002fff5d6d78f5fef95b1871b7ec4aca1f9f3ba3c436168be1cf26c5af353520790528efef75fb73b1b9a69b4faad0aecbbb24c58cbaec5ae8a54c99f52dbb6ec2d8b94dbb66d407b4b6d58fef89498923f15f0b2457eb0e2aed3df7b29280668cb16ec5db4681460ff20e9ef4a385e680cf9c79f6f59b7aa1c8582fc0f921615e3c4b6d9d08a182d56651109817b88481691f38a9842d42e54a99e05384c7221b53dd79e9f702935addf58ef4f5d000442c48958fda0777d1b46ee6e79162fc1dd5d471b46d4a9ae286d1245208417e12cf01e368cac1feac3a969fa23c2b099da1ff6433a1b811afb548a2815c4faaaf5148498fe52d0339dec9fb2b7699e55d70ad999a960952953a68b3a7115020ba10f9a65fb4b27b6bf10b7f24892fa4aac4f808c53d704500d210fa5b9fa2b53c15f3e66c4dad588b52f25c3cb7677f9f43d53c13315dc359e720bf74be812eb2d4705630f3314b09dc1c03d0462ca309c9e72798994164e6ffad44e459f4ca36af4a2ebfa033b03957ddf042e34157d3ea20b81cc3c0ca6e79e9e7ee6e90ba9fe7a9aaf8710d2ba29b5374c600ceb88ecac8361060629dbc3c0bd897bd3b3c069d36f9a85199d653bef299bae7d135054a72e30f884a01c3a60cc5941c41bebadeabcbc04140ab24c19e9310cd6706e8771155777568fd07b58d1670583af84e0b437e2eed6ebbaae58aff40266072f607630da514341b1b0952923b7f5371b71abadb9bd4e6d0c2c25be5bbf7080ba14e7e1bf1dbeac2afb002a239611e99e87c059b763d1726256915f6613e93edfca34c3cc1a328dc8c801998618dba4628819620b104cb144c548ee6049054488913421bc4288a5a32962f4306f589268c0a008b7d86cbde3b0fde368e5555565966559395525bbeaa165d5b7189df5a77f16a4c26e5996cc558e87392bc3ac5b68699f910f87cb84dc5dad2bf3b72324a4da15f2f8756596f541715a9635bfaa2a2d334f4fc86642e49e9047e6af0add29f3778570853c75b31bb66ddb766ddbb6d56db3b66aa373935bdc7ceba12589515828a79c724a09a3124cacc0ee417624ac2884b0a3049a907ad47a208f9d99901f417c4ba9a1f65279d4244621843da7860a42bfb9e1a441023838314e4a679269c54208218410429f16662d66ede4ec09fd5a95fb5b1e71a2ac2aab56abaa2a286755559555ab5511e14c5ab9af555b4eab5955ab56abf20a7ea5616559b55e17d600cfbb989d93e60f0bd19cd13c2177ed866ddbd44429eba729ee13ce39a7432ef037b53cb21ea594525ed100cf23d275d67e73cf39bdf2ceb2e6acaa5a41f841b128494cbab88b5d183666f81ca574469c1c58777777d71046f85083b156021b67430821c4d9fe9002a6d40fd8e3eda43e1d5c08db2bae77c7d66cb14ce796dbdbe9e142a8a263621633995278f372204ffd4c77367794dbca9b6977c7dfdeacbdf6f7b34c639a96f9be7342c8536145afc82b433420a89431b32102a4e2a8f44e164435656648002000000043140000200c08868442c168381c1266557714800b7e8a4280661fc99328885118a48c31c6184200000000006064a6888300b99eb317ce9b79d38f19cad04833b1c8ff42131b0f32e2999964f16c2d046d4001a38a3cc705b6129d10be10723156099b1938d7682629f39bb180e7a4e2d2c460f8679ab9eb21c7e75aa9be2a3f29444e4abc12c4357b7388ca019d6f0536016a4a6b6a2df0c952d5a04727c83bca2fd4a46791d9583fc0bef459748f5aad60cbd08f630ecd1bf3e78deb71fdb9b88a488d7e56a2c31190e808912d857b89b2e5e7d88d13b607671d0055a047d0112ab65471546478f726fce304b44115771db376c2d161300de24a17c947635f8a08372eea69f7d63874235ba36f11928c8102e2d83a0b319f9605352a11ff330506663565ea2b0683e34b8480c03cc22410f2d752dffdc6a6e75f2e6f0acaa709710f641e7ac302d9b58d64e7809009f169525f499a0da11d9b2ebb1ed9804287635a3f1c7fd481be2d9f546e5f1eeed2beb031d6df1e17c534c4397884520f796cefa41de72489ac8634ded1b5de383636fb96fdb0e943039b398741ec865e9bab63873014c78a6c603fdca883ac74969aa6a9d9aa8ecc840eb18fc64f4cf1ca82469952bc2518cb80b12c5570c69b39e85843c18d4e585596eed365c90fe498579799d9993620c0be9121b5367b38a0d0c3cb5acd341f42a2ac1ce50681c68b60529cea113c53de7244aa31abf5f90f9768e2fee773a0046135783a1854059838adfb0205d481ef69461b784496b4b469c571a4a847451729075da4a38519b77ef07792f65f062481d79fcd0e6703ef3f37c09551b96d0539db6e832cb1a875d2e681078783515811b70ad77d8d1c89cf7c22937c662279d179915282dfd73d2a3b7cf2202943bbb2cb2d4b13f2c5c28ea5780ec033a514246f39863c5c889e1318a98d2dafadfde32a76da48dc84f0bcc13cb4493feb4847a22f2efba30b6cc1a396d9d191460f314011d98a13f76eeff5602776c6f393fe2e448e64b5a75daf31342dc435ad5cf831aedcc2d644f924464787187b896bf375023fc83fde3f1ac645db2f41ffbf09793fb3cfa13b42e9ab0613846b824c7fe87e11b8dc976e4e808d1f310cb5cc9e4bd099dc2dd6c06940dc3c1135fe64fd42cc3d414af1711f4c34796904ed35fbdcfa61bfc93bfea10bfce4db3894c6441230c26656b60c249f3234bae73084f2544aa2db933c51a9e337513258dfa1885f5b5bed36ffbbc3a1a7e7016dcbddc085219ad490efb794af754e34e9ad505975b89d5fac7fdd887ab1b4f8c858c755db5901678ca35840a0b4119e2298d90d5393773172fbb46fd5a961e0d688d0cec930db2eca6a999b6e071aff0beb04c9ee8c0c95f3c12e13583607e022c73030038396d0e61a889e38bd82727b4a2abf82ac1534fa47d426f855a50ec8e4e2f12a1be4f82ce814035c0d9b00139bb218e4da797e182b160f42a3f7fb8c20078fba474de297aace375ceb374e32a84ac996179336d731afd90a967f98c835f1e143de1950dd86014171af2ede66eca02362cc1ea2846a090c39b9403360a76b24283074e9a305f78815c42882e18fe63cd3603647af0bcc5c1e49ce8af8cf5e9cc29fb524a9fb6e77d5ad42601d58caeee6a8a032ce33af7fc2af9e3ff3aad83fbeec2a253ae6dd00c5a444f39b125891f9f81be0596e0ca29a5e9e95435912a4390fc43289bf5c651cc768ebcac84453f2e569ce56dca979aa0c914f794878f3a62793b09037c8f0658015a81bdbd83e4578e37efbf969f1f71b770750dbb8f8b92c23d1226c15ce474955c8a92c7717c31513180820ecd1ec0d0ab7877d414dea391fa0aa6571ddb028d2725bdbc5958877aa48b31983b30f7d51d3057e84db622004103688962f0acebc063ea55b806c152345e113a8fd096f542a52b1960f9c9f573a08aa1d73c2656778a9c46df9ef4924c5241a6f9575a5929fa0c09dce942cc689dd8712d33a3dcecd4a6294e70a0b718872d5d055c893ace9e74008cc0ed83dfb78020b32bec9ef40f9312bc424b0cd0772891755d5a5f789cfa31d18a39210624270c0857d85b2d561c35eced9e04186a19499dca5c2f7cee1b4ce2c1aa34269bb43f8872143c18010635beec9acb090f30051de30754d3f0e70bda9b70e090dbf10d02a1c7f87089890d07b41056c2e479760010c25e9d9e62725b9cbd0dce946b56b63a577e44c0c64f7206fdc814cea47594d266ab37e84946bf68585542299070162c63e4509677e0c98a657df302f302e024c32be17f36483ff47a3c53f933550398108b945cc74b75abaa3cbf72c5a99a5a29c1d57a49246667e07d462b05820099f7d848fa7df70dfb4ef5a8f4a5a3dfdeeb72041b424d620f94a2146e79f187527959348c3c09d41d7521253eb3ccdf8b1a7fd8197393eb51e5d3ac04c6f35a66a584b3a33edb06bb365e1d271761049e28a04105ba24588ee70c2501b55507d45dd9361ed1cd26738746092115dbc9e52783e22590543ef18ab2b15ba1038bb0da8329f99b7f505a6ca8c99f0774f1ed00ad4a120a05295abd4408bab8c22a04956d845c58de8fcb3e42d46657d10a96026dee86c581157c78ce6fe1af30ccc2c4209d449ca8ed025b0b2a8828a945d3b900da61609c544e00af4a0bc2fd827862831347c7983c0b6acb92d0a1a6badf0ed93b7fb35a9a54c916bac9767a5bb71088229472fef590d51dcf300154363d3e6f33a833838d8c0c5e05866571441ba315915654d5a51374998c18d2ded47066e692b6ec8aa9c6226f6b9effe8709b402ef81f9251552bc7f7d59498d17df6c8642fa5422ef28569e8909afc4484b1ee3c83149ffc643cf156f24e1662a998da5dbd83b63a15ff86e8dae5e0785f67c39c0daf205cbcbdab1ee3ad37ae23eb915083bcb36e4ab4add7f87fbd8b71946f600a6d4c15037a06bbf43c00b6813888eaf5af34d9372e6578394ba6a64ea6bef3f9acabd656a7ca6f238775e2895965412c414f7b75fc8790ab7a9f3ed5a2c8945523b866653396dcec6bced98392eedef3e3cd05bdec2b655577d1c431e6061be6cf25fa43591aed0a4db74db8fce72deeb19d48a7d12eaf49db8f5f983d23369a8fa23a3231fd638dc21f2d2fe3ec882b6a660085d3bf9810e5573212b061a03d0dd510882336cf1c57474cb50d0b29e912cf67edf09817affeba1cf1349cd885e5bebea78c52b8fabdb94173621213cd04802a45466a12d5c880f21365115fa914a46d68ecbe500aa537b818d82ba52567b1693ff9af1e5e152645a3131b42bbe5bb9eddba2dbcb67c62df50caa35210c1946c439ba983a79b2a947d5481b646ac4e25ffbdf552f94a9a67d78d9012e7c2489e89d861a81362ce9832a7315f1c17cc2154816d4c606d58538f178d0f528d3f70c47c9654b586895304d42c6d77a800d2e0734b0b9d184b89328d207056a4aa52828b35f72b626fe6e626331b166665148dcea3e85f6721e9206d083212db6773841ca4fb34a442cae70e4927d3053187a3761842005ece952c91b224f74399dc3895b2e7cc32079b63a73d256b987a4001df2606a269115481a06b8286947efe218a7940cf896e017c2c8eca100f805dbe6afb6962205fbc03ed798c61f8a42f0d423bf2145f8c70f32b3bae9e46735e195a4327cfd05712b6221138d9cf86a76bae042b4a5960e389bede0d80d5341f6c129fc9318b13308a012c77fc6ad0f0d95853e0a77b262c970e43631ba11465658b176e0e6450d70a08754bbd8b4c17396aa1f0d25ec1fa5d591a37d72fd9eca151a8d4b8801c78ac45912942d8c9e5a4b46f030f055fde15f343d7d1e6fe103e639254b342ecba69e5048ab0d605b88f7d32df24ef3869de4cb0268a0e4fc9b544e651846934d8703235f9d604e4cdfd15e6b4552e15f44265cf4229449ca9430523fd125da087ebbacfce07959863acb9a9f946c4f5b91106167cb1f4aed74661a4d46c48d5da407058b6b02e64568fe1cc45433f51a7a74615a83ca4ff58e4f070796cb4ce4c553b88a59205c1517d1c72e607e47e09a4d009ad335a5bb846d843e41ea5c4f0cb9f1c36de3dad3c67b9fc335a37e9a711222997e0d20c6e13b19f04a08718b8bb8c77da05e25088d777661c588beebaa10ebbf6e49807b008215a6aee5031f8613a160f99f6310140c9b29794b6b8ce91b8d4cff4ade7a970193267470b55853777f6fdd953d74ecff7d8a001f26bca7761041c83f35ce36697f865811ac6b5aca776b035307a75432d9a3b72a17fafe854d44aba7fd5243203faea55ad071e492b27403a554d725bcf3aaa2905dcb9d1bef3cf64685d80fce310de97b92be5bc2c3d55a51d4973fd60e5e9c3600f6cae970c2f58830511fd5ceb40ba50a0e270286e6067a65d21e7638e193afe5b3a99b59f42a9546245ae2dc99773b291b7d85fc537bdc3ccb8c9ce9825ad4f8a18c2eccf386f476d9702e623ba28083251ef712fa083ed3598b4c90182d71612d14465182f8b0fd49048a27a5e091747e47682cd8e6197fe0366e25378ff345d531e34ea3b761aa39b545cab93d7d040c2a1e254e1d9e3a68906140dc237eca1aeba020c6ab7ead9295ba8509164571b5ffb10c1fb6e3aa333140f870f647125b07c5d17a18e801c8aa3d6044ebe3718f2c41daed1568968ca540a3d78733678246244a2b841949669e0d2751322adda0e6a0ab14785bbccd4151e89dc61111695fbd254b1d5a33b146c9742f811e2e30ae5e63b370ac12a2f51aea517b17c23adfd0b20c0bf6911b6dfc23b3709d2f3a59c59f1b6dbf40920d05432013844032d413c07543425033e30ee4551583b62f611913e2e1de56c4cf1f6ed9f5aef7bfe7bbdfff3d3b25de134d3e1bf7e79df8433831ca605975b997e295c38692004043d0c0fda08e9269abd52aad7ae03256eb66053fee125cfabb04131bc56aa00ebe350d23629807ab4e9e93e5afcb42fcb72f5c0c545e2935ef17d650ddca3b1719cc9118fcfd62dfac7664cdfb0dfcf43403b69de86320102014c4fb0391134d6463c8045df4c8f118411a308a2fb4fcb97190a35d6a83c199195ee22dfa342ba317817db3e4c6595828065c4c700e9e3d37fcfc888d7ad85a30108e776347a70386a9281160f82c1faaecabd40d6c02a81b2345c122dc7644cadbc3cf8a23114216312da2e0a3a3274f0d942a73e553cef868a0dab8a4cb1795d54ad5aeea151b603f65af270c2ce2dfba6725056b667f2e2745661415e6a5a26b69037f9527bf9e5da708e688c5be8a6cece7e94ae555095ea2dad49c0f30628ff1c6edc840b1c5a4b3f857b8a573e35de19717efc83796a945825b099d376eac2cb9dcf76a4c687396ad4fe18d260db60a976ab88ef6080b33941433723fb3d94971571a61804115efae603ae575b619e005e72f04722f589b30c64777dcf4d79763fe9c06500464a26aedefd2075f0c007e64fd8b3200c634b369cd22a3dc916e7f2ee4791474a33106c0c8fca1b4d70fa81e42ff989e520362f7b0ea08bc9a0ac1f420e0ed93f06b2a99efaee2893e45452fdb27d1c8df09ae6daf40936a894bd4880d933b9648ddc14084b5a4b3c3845c1b9381b831329ef1445e1b13bf46df20888263197b88666f2c0443e08aa31ef3289e3764efa6ffd91ccfb9abb5e4ceac0a71ff0637368a71e6d315c7260f435dead76b200ee3db34d02c05a8c01a231d4833b4800748787a364938383374a19c602ebffe0e4c8d497e682708440d0c114aa444f93c83e03b2a3ddb3d387319482fc62a35bb93242726aea90882c53aebf01fe8191d93280eb6ca556aa07b20e088b78a880c24bafede68da0b3f9da7e5e91b32f19b32d839d2036f1373512b90e7d20384f1300c8d23835382d70ab7a1b49b048f96c62fce14e5caba34df71d8591580454c4931acc9e1019b6f512848ba03fac040fa15eb0fb372369828e71b5e5763dc6921b32904060ae63f7c2032d783465e2c1ce4d013c10d5c4ca996033c374527560dc0981bf81a2688abda9421d62e30c371a99871544cd46fbb822c2c444b5f10a8096e92f74d12bc56c28eec9fa581c4e97062e0de451bd807edfd68f5b234f880a90b46841b08fc2cc4924204e8eeb1015df476961d99cc607b1cb1271f2c55f1c3d22208306cf99f3bbbdf8c29cf04e3c57cb047346c9273645e07e726be99d0f7206bca2a0ba926f227573628e295b2dbb725d939932429412b5d9868c73579eb1f24e3da71b8a47baa6cff968723b0c330ec95019cf7c1268c658d2975af238653650ca84f80dc5c86969ce1fce802c5f84e63158ce087ac4053b31d11374fccdbcfc6b0a4693293693908683faf26ee7f000ba79551fdcb208adb2be718f16ea802b1845462cadc7be00c8905a4cbdf8b07f2a8b900e0b9807660e760b25fbaf890b772cca97150b3b518616ccb0d02361d86341226fc53a51787348aa1d75771a7de437cca05c38f75608b73c71f1112d81e90b457a3b61544d7a928310091871ba15ce31815084dd0e590bd1d192b1a29bc187623768576eac95178635e9ebe757c92518a368fe143d9bb6920278dc3360568a352359977ccd59112072c3a91857464c4952a885f30ad5cae12a4100173cb1600b552a63dc0883f5422e26cd4ac6bd044d1e63b1ca9c6d1471c60bc40040771e74fb11a4b23f2d4988069c9bd276e7773b437f4f69fdeefae14a5a9924e28a063d97b42fd843e81ae8c34557a988ec6a210719cf8ffdb5a9f9e918d6694e64fccdb915fcf98b62af8b40b79c6cbc2bdaaa6e4fb1c8a957c0efc09c61ba19093b07a1516a96e858fba65a05e7cf16a70f117cb6487704a865c6bf6edd606cb5eb6344be7f72a2ccfe9fae24ec93b1b3e5810146af75e0653b343b2a8897fd398041c9eb9f2f537a96e27446ce9efe98e1bd72439299cfc46d5da6bd520aecb4bbae01212b0c7672a600ea6295f4db58a5b9c363d3ff7349a0317f5986a70e9bc52f0edfadc2a0f61c0596d3c50413f50f56c4e4c51849ef403496a1f22c474d0812a73b586921840095c093351bfd29d4bdaaa840c94052670729b7b40064a28609ce26f3362c4b603d6360be79ec1b67847b69510db70378f9230d845b106f5550753ec23b87c8591766494d8fb0552a5e4a437bc62cea06ad937d72aed82a790a9d03a589ced49829fa30dab9a35e96e6ad6fa1e9f8f9f021fc7ccb921ea6ee43700092038f24a1e337dba370d90b869ff2ae9d307f92d1fb7be35ba88efb60f0bc7b32986fae188ae5c990c747092ac447850645950ff40acf7b93f4210d0090f33b9e946821a1d5c3fa50f20d2e443d8933ba42b6be7d9b8a6d3858467c05e47570f207ffe1546bb581f7fb3e790d838adca144639bbed26a8e629ba878ced081b9aca610b25a2f001626ebc0eef8823620ef356405cb6ef2dda04dcbb9968dfde6a8d82d50ae1b6d153c28bd3d4580ee532e802c3ff26f42013bad61da5c54ab3ba5a6d42ca5e482813c52473c6913d35f3e376ec87015947394d749c4b9c952ec50a00d13668b62656a7cf703b2a5ed0e628dc196e80e35b317e8d1b07edf7cc1f17f6403319c6115b3a28e01c6757dd4509495c6d60b61d83fe3e921ba351caf987b34bbdc5eddadc457f8dc06de9f2a19f8971bb7517f2459166947dcc8d516e5897956f5bb0b02d13686d46bc44459cd770a20d7e7c120ef074212e6a1b6d41d62af94aeb428f4f4659960c88ecabe4ce91cc9744b8caa596e6808e89c9264577dedc235dfc2e66b8ded6c14aac8e166e0a37ecfd4b9b83b12a52256a4322b04359070c7b87ec62bbf0153ae810ff32777f3e6fc552af48fe6da06b8ab2ec8370322dcd5bfced48497122a8462e0d97c7d401267cc8fa43df07e3c35bd7d7db9afe734bae24029ee0f27a69cc7dd5b41dd0904c73dd33898f49ce93ce0985b73cc1db77e66f112ac2db6c3cca9b49dbeb188fbf2c66ce01665839d984c87793e28c1199f2ce136b82f3af6e4de777e1e3600ee06ef1b56497220ecd0edf2ee279fc5bf24ec9dc835c4d55adbac878ad7485e442dc44776bb797ad79ff97aa0b763a72cd57f766af9ff69ebff227ef453661417b9d33c53f39f7265c8db667a99ce3c5bfb46e3df1fc0bf70b88cf2fdb59950ecd9eb1b7d0043be8a7d956d175e6116aed345f9ed2ca638f9d27bf2558aa7d8a7b840ad65f87d4d5c0481553dc9f81ba16ed72fbd7d053a7b5897a6f46d1f94e27a675be71ebd5635f1962c2a6027a97c44fc68488a1c14dc378bd1cc3d1b43757f4ae40b2c9bb5853f0a0efacb75b13c8aa0400672655c46f05012db3faeebfd2e088db1b738af8d0bf1fffeb628fc38a694b0fcb91cc544b7c32a4f60e024dc5540bbfb81024ef48f48392ad571e17da4eb69201c47cf5c37b87df77f9865eabdcb2d44c70049b4faf25d220b5eb80ec617041750e855f4e6687628bcfbb9e2d741d68b61ec99b0101206dbaac3821073092c0e1e00ddc3457048335214471d16b07da708ccd965efd74ae15c5135d172c4d36f9b1be0c47b9698abfe904614cf3a451c92d1ae2b0d5a405c8a86f2ffc54b82689b2b0bc7f06df474055da040295a87235304419a86fc42f93c77d8fa26f1913df8d8885a5ccda66f2a322958d80fea2a472f6a333c8ab66761b5e7d776527224c0185361e0ff97d92a8c89641190a0d6e2bf100e1d733154fefc33f8e0ceb84d06c8d5388c831a512508c03593a29fc360c5332222cb47d3f76395a54c96585b46014d66816d6302c31f03888f08e6fef60e99c347083d686c53e66014b2d7f3aa6a40faa7066cb0941e9fb0fc1e45105d6661cff1df877487dd0405b62e07650c704de170a2c4350780848148270b78d4ee5dbaccfb8a3239655fc7b1f97c5e4d79314af7156063ed6abd8eb567db3d7bc64e0efecb94ee6bd6a8da21c8824d6a8199b6c3d3043b27e8322ccf665126cf77e56be0f99b3e618cc69211fe20144a515b5f5aa9f992b7ffb08b36fd95e7aa3948024d7d424042529062b4fa592370b355b3a743591f9916b06aab3c03760093de1c6d4aa12e17cbded4f4ad9969d1eac0f06d09fb04e4c3868323b3d3b247a144d795a936f5a9fd5ef8e0cdce71d4b68891fe4ae046f192f3a241aaaf4ac6a8c16624679701a439ccd1c58a24fb31045d3f84914bc5aed122851dc2ec9874e6d3c0f0ce4a1a4bc05a9b532161dffb13fe440406735406507259db663d2d1fbed42a564a445eacf62a7cbebe791c0723e718177c0eba5d032e1e7a681ef1293f6f9f9f9fb9e74bbbc24eb88a70576d1a05913d5606564a3214d94198050946bb09dfb8657a872c2274d67b2b9446c74a6e9932d4f91a1ae45108d83d450ee37037e0413f360a6660bfb34fbc11f74b4cb2c08007cb5f64975889cdd83df3af1c046ca98eeee5a6d61757272902b513c50c2660b4522956a22c7ca859b1f2f19563ebcca604d34ca5a279fe6fb14338d2cebaa445b95c36a16132f750a5b38c7119fa504d877dc61f228076e56deb965cd3c1e0a119211cd4046c72f6467375d0697a549ca60617b29d60f5f5492e6d24b1dfc7659ac44e24f69f49758507994ee1cd5c3203c2ef441026c3e04a4e54c4bd04c8b18c8f294d41142f20a1372e27e07c48897ec7b87c69ad28608c46eab274141075611c9d38140c4c60f4567a4a086028eb46c3780ae886344e649a076edea083c1ea3f66a7a9bdb8e21aaeba4947bd3cbc2dde0764b28a744d622873cda3f88b65a454288633935a1addb590eda51d04548d0cfe976f2a8bab00c66f16775034b13ed9e9aa509a3ab4524c5fb58b305782cd345a4eaebd31076fb6fdace4916229def1c7cb8029da8eb939d63f4fad2000152b351edf71249f0b2d17eaa263f137a89ad82c5a94a9a388441bbf20f4f2a40694d54b500853cfb16d1982e2c94ba1e7b2e1c0365cf71c696b4d6c848b5e3240fb7a071f52a9ed934c56d2479fe0abd077eacd60bd4dbf16d451b6842411c9fdd3374184ea5215e4ad16c20da9cff2a005f3036617eeb33b50718bbccb46648ba5e2f6a16914d6f9ad2867f612b81d50cb9e5d63acc04891900a0e311ca91a9ea5d606838622777f96688a41a97c7fd095d36030ea05c5840a13ac48c9a6d45dcea7a1af0349f8981ac4b6e17c616e70d19f8a5e73454c56f498c8f2a29552c826c0066228a5008ad43bcf2395da2980ab23dcd8b49732ffbc7773004e1466c8b189040c3e7f24bcdf8ab8452df50699f1457bd4988ce941aa1e09d2cc8d30c99d8cf6ac6554f2a53f00842131021c14ba6ad314ddd5c912f12d7173401e16f04c0580875b3e2f45851d03f7296ca22ac7a4aefe6e919b5ae5c49f7c0d394b66b17f73ef2ca732b269e4c17324fad68ce4e6d4cf5339f92c9ec33a61afc76a573073b9c661845a32b661e746474c17fa574f194da3a76733f944acb529b7d0255ca7ae62d01b9b7405cf08e6d87f48277b60830e4fc70f893a247a080211ebe3f12e8e3465f4970f8a25adfd4531368b847d81a59200693ab4bf6bba2157ea81f2fa4a4aa8b672282035ff49e7511867a59b150da0cdd51e9ff4f52d4efbfd24b85086ef4994d6f0a495c1493bf36e8bc3a1a818f0cfdee61b623c248884acbfdf6c4500c074121a98e1682b0f7a1b366a72e5ba45101bbe0175e32e8b134bc5ed847435a7d06ce14023d7dcd0bbf2cb716b88404a286476b8419e888ee6beb0df853519b89ca7ff6c0366936caf064b1c5f1b2f8c09457d92ae1a8146142001bc60dfc05023f9127aba0f7a2b8dfe5e64ee53f29c31e3893a12ada442423e190911514cd040f2493563837a0aba541012651739564d2cc57b86a75661aac4a202eda38991f8e126cf74099a4222ed67d22b3e8a06baaac3b294d91379deb6fb5ec77c179b72631cd62460902ac8f34eaff4c40c199c0f6e75e68638724bded50f8aecd1183f4ff6d92455a4009857d2b41778faea65b53a570489eecf07d94b68013c3b296a59ccc39d12e420e02668a4873157e32de3645bfcd77663916e80bb8c92e8751f4a03a071f14efa11c01e42332838c8bd8d3c3aa7f10fa705f2ed537867f7101c6f82257a0b7552da28b4473ce54408706adc18fbbf7049ca5b4b511f4d1bd43438c1d6abb963db66cc378caad73431b1e2de595eda73bcaf5e2ff872fa6313c2bf673621b85ea366e315ca38520d318445b05b7c4585f40dd4beda6ff7847d50b6cc0b575d391bf8f083c291d288568bbccc0da89a001d5038900a4ca35f3978b4dfd4e064cc0945b2532c3e799ce52e36b46ee4cbd6f36b1a1a6da315d56a3b8948e87b6340333117ba62e80db55389517e5eff846210f3b77159c687b3f68bceb817181695fd23fe7470d719566c0c62e5cd69141c97c4f538d56420bda604900f48525179c7d4cd514206515d5722697c14c80674af95f37f6acffa2317ac376533e787db1009c49bb48f6acee3ac2370b2780630aa56862cec984b12d12abff05637521266f7da6ff97781e1c869f7298e320c31c30b296c064aeb5356b6d7d5ffec855bf7eea41e4bf1936b5de845e2975dd16a0dbfd44d16e8354ec76341f35ed6d7f795e4739b9eb7c8a8864d390286deedb7ebf8f97fa790713599f9890a2034044a77dbed0aa84b375589e644650632983e7a4e5d035c56ff29f2ce79181ef32bb67c888c23d85c9c360328cf5126c309aaa97f041f04bdd4c3be3efce04eba510afd55f7e9c2293300cbcf32d1d082dfbb7953b114517b3d2d16fb6f3a4b31295a96fef3606c1468a376fe36ec12cd93771112feb1a81588e040faced0ce8f08f3b3931211b40556d5e4b279831a0c0db6d3f612cb82e252c0487c6a115aa42983a06b41c2e8d05c44b5943163e80b2cfe5e70fbba3aa8633cdf268bc435cc422be60673819c46d75897712e1bf83ae2fe7c282eabc82e3a3588ff984eb3ee7afd448e789758a6f6776c4a27eb335c529d164741b4cd6a2a4c669fb64b7be6a7b83684be167ce376914fbeccbcc322577810241b0aae424b64580d86e1632be5d05d3a6b7ddecf61649b06b3ca4e44b0126fd6d1b87882acc47b88a7f95748efa7480c80c0a2f11a03d19d5e34b9d4aa29e482164df30021f1e272f7972b44aadaf7b9297af02f96a4eaf303a743829c675c4b71d777f6f0f4632914e31edef7a3226fc32af38816dd7e971f5c4a32170517f4941d766176a1014161807efc3a8a23e5e42a1d6eb8b1714835eed4de404eeca1349e3f077e09da66f80edfa9d8b82b15acc897ca200ec1d68948387bfbdc01e44b4e13a768dbb7e3102b7aaf6369f5f280a2d45e14bc35638d994c44c7c71b0006ab9097a1db7ce419150debfe9798ba93364c2dcfb0f909f71855f232360e6be38bc597790cda887e00278f5792fb53cc61773040782e728d0be49021ff68ba4b69f574b9d7d4c6184564d08850dc2788a90d14755538412278b9fc8b340a11ca64ab3edb14d95701c206ae1ee36d5d621e744d4394a99eb0002bc498d67e81faed6dc91c69f8f5089a68c8b01551edd80acf0437a7e2b6936387179b38e1fcc1d4ea94515abe0d3fded7b171ba5a72fea1fe1a1201947383f525cd41639ef787c5bcd22bff0982949d6ea7c152a990b94ba60c4fa0ea054102d1ebcae1d0da2af52b94424e229e2a69ccef43a11ce71ce7f8b19e05eeb1e03438afff407d122c93d430d8d15a5dc3c8d269fe104ffa09d0c7d6a1640ffd7aadcba9e5897d966f91efd580ee2a3757ea53955a5509b3d65bae22210e0c0bf9520f11295a53a4f573197218f5cb167b5cbc71b8ea2a3c3e3103dea21c81f6c0237150b7b75db481321fa39c116886ef957f7b328ae5f74bbddca7b6f5344fd09b1db1c69f820d503f49e6a7cb8810ea6ad87ff290511670a4738b6a0203b9eecdb116d4d80646f747c8d97ba311c0764581fdf98ac28c76210d4593d81b3d23be4a37ddbddee67e5470bacff2761551f00ef5d47aca184cbcecf6296137e0e37df8b38bb9187a6345336572a1cc34096771ae6a8698a68e5d18ae3d965cb178f347f606939b260e2acede0644bbee10189ef89abe5b0d7fca0d4020ee4dc8338d09b4d6e17ed2aa611683e6f5420f1da711cc5f5c9c86423e28253eda9832dd8db6233bd6e4e7c468f6cd7c1c03f8d53889e816f44629373553a1cdab5fdc48851c0d0b5c778784fa7e5c85a3e7e72d91815f6ae51423bb985ba596b1dd28ea32d9a9d344300bf54e75bd76bcc1d3762b57bd9ea6b90afc445764abd8fa4f3adeac6a892ccc91b7ae8b56ef599b0df8bb4e384470be7ca10f866194b55b90d12451406af1d447b14c8762f36b13e5ed937500a9463462e16ee2be628df16d1ff7855a8274010fc8e577c65a7e8cd6f2b66a4a2c848b5b6ef99ca7967ad81ebbb46ac16fffb7b235b008b1f89e20e396955e050c60086021833c3fce2d4e36b95a4d8faa574d76c6fd147a1e04702d3da269938fbc92185de559ee53dd0db0fb96eac950f01b39454317cf454fbc75ebd1d7190f5bdb394bf997386fe177aabb6f60b4d9a5b99d464f8c8b10fadd7fd029483e1562dd22da7874694d392103f92dd7ddbd4d89e804e6133495d48b0a240c97b9978362fcdb18ceeb8f39c64d4bfe4c58e6f7c7b69d73ca406102966e160743cd8be15649d6408e4aef42162eac6fffc0de44425cf5debe7de5534a3154e50e3a6a789d965242217c8b464480a4ac41050e96404913441f9b13611192773423fafdbaf6885252aa3b019bf35f325d3a5ee30295fa524e52ceb100b5df4bdc087e6ee439b2b2186581e0c7049abbd701e89fe00bda5c7c2795d30026b24a464b5e654bdb507e9c9c482a6654e759c998c8206b71f0a9627f59b0344f532792b55cb50f4f796c2b345b33940be328a27e1bccd1298d3ea569848652542a314acd926cc951e4229d1ddc4b2f728c58248f6258b153986ab68417fb008fd6d3a58e3a8d47249d5b055cac118afd30adba1a9e04107d04b5534c5cb77565ae04958ad52a709af8af0cff5ee8b715ce97c08f821627b17537d6008684f31de2a6c09c05655ed87d315a36394669f10dfb07d09f1008fd87721af0aaec924d82c8d246d20ef3f158aea12687d5c5f4d6cc1e4ecfab57b42e610cf870a9433781468f94fe50171b35da3fa1cf93e5a3ab3e8faebddfb1d566becaa841e0980581981fa32c9f8e6db4dd169d66052cb9d4925373727953a7fb8f19b14d0bbe703c93588e3ff35054398b27302b087d03fae6d92bcd29596840ce942a8edab1fcf4be58f3e3db8b52d91b243a8620390ae971908242bf7fbd5360faeb19c70baca3e96f3a8497acc08cf6df4992888edc6c67244a065169c118df4dcc6be1d44068c39e26693fb64f8df61f56c6c079e551f4ba93fe60842be5f61e015a21e43884f6caee37f962d3540c8d0bba43112d012f6d567f98d9fccdf602d123a249270ce2f59eae36b2a1f6bfcfbca9d9f7f44b13f70612366125fd13472b1a63708cd7477e3eea693d7e4eab06f3b971e2e519b2220189c406680668f9e4be10558ff819b58bc65fdc7587de86440f1623c3bc5baee3efed42207283b67a2e2f0f4f705de34ffdcff4fc5903d9aa358c3af4ded11743fbe071db7bd98bb9ce40f9d18300be2af0bc2341437e4b240728bfc42d66fea9e9ca77024c2bb671dd142047885293192ff78f48fa582763f3428cab6d6fe9770e90833b1480c914f88d0d77ed73aa3cabd85e101a9d2e8f109ef134893b4c840c15c06298c97d590831b28be4cf20710f89d3bbb012ac1459616d50b2b4c221b7f363283ddaecc9690e66a419c52fd5e84c228681300844ba7925655bf98d010006feb986361864ac1cbedc63a4139ad3a031f8181a0981e6a182dc7ab6cff79496b8aa4aaecb2b209f2ade21197413dbe7c7fb9a5eff83807657af64416300935704677b44408a6415d523fd027dcdee8a19bf969c0cebb8a776348c7bb627022a84d873bda054c5a23c1ecf3224ab2719fbb9740e6fda9626cf229d4ee323809d66c30e1fc9a3bb683c0494ef7f95fb2b060258a7218056d589be600bd8fe28a151581751915c782674e6ffb623294023b30bfe1d5f9ed3ea15c0d94fe2527148a4b1fc5458522480363b82d0aa9334a239eaebffa5eee83c0175c09fadf69180ebbda91cfb6d3c67effd3a7db74d6f53fac42699e8ed4024b1e85e3ec528ce53c772d9e483b249c64757696a3a389ab7562028a671ec60ec8329305ec4a2456d9eed294f0146aece6a59b79713c3db73ea49bcf0722ff33eb034147ffc5a175387e5032a4451d9947ed8652fc01f44e7f967de58c7c94f525712e92286d57397a9b19f63419089c836b68ae9e0004c2eda55dd4c82c4859d3ece3e6ade01a78b614ac3fa4ce12fefb52a0f552221b57a08184f021f71456ce7cb3371d6d94cb69e04f2ade483c7091360807caeff8e204a482e4181d2011410c78ebbeff126703844f5ad32e4aeca8b4eb4e3f305b8106bda8bc873773b81e7941168834604a42571596ea245852fab2bb293819247f52353bd9ab2450510f710eb540cfee3b50952eac8f0ccd3ded4089d4e2603691e8658832932946beb7c4a02d4db161cb8752858a2ef236c78f807a5cebc38b05435b6b3c5616304469a9c9fd245612bdd066308232e09a94485708497472ef2498e0e875d6707a68e35ab7f4a22633cd4b8f69f1128ffdca5c0624375e6e8003c0191e48d08f0cb659b0d08f7ab0950aa1e20c897c561a85630a3e2b18f8d37bb1f2a756ff8c927198d2d24584099fbbdaabfaac20274306087bc629269af20666dd7f3524c1bdfb8a1e49541d1df30b53459ce64e6cff92050837fd4fd93cab47c80e3b431b941267eb4cec6720534528d3628a6360f53144610fc4aed0fe1f931a7ecc9a39c2cb7ca603651d14c1c2aca9bf0c61069486d708ae2882f931f39ce619a5e70cc87e6368cf38ed97131c1145c8492ddef5676bd56a0cf659716638c7e7e8df1f1ea5047a45f8e5bb1b6045085504f13f518d410c7892e1a36909c9034fbaf63db1e0896337418c11c686d71d142bf4b445ceea2daaa91fc95fa69610f6a1950f02ac5db4582b9e472fc78f5eb896880b4a74e762342b0145927d6b5f9a6e43c6683226958b02e0fbbec4f0f3c96353da961fcfd1c39f9c368c2b0cc4797cca794037f9bc06da7db7bac34d203a9c06788649db16d1bff2077ecc6220bca84de9b2c183159f0ee2b5280ba525bfff3df986157965284d1890b3287ddbc664736a5ca7eb25e2afee50a940fb7e3a882586f6677914fa48ed865154753c7c524d63b785d374d4f53bac436b9c1760f55723be6d3f9d46604cdf32bf76160427b338587d8c0f46e06d367530f2ab4bf0b2e69b446f177bc75da7185d47f5dcf6ddee7350275e65fe0d8470bc5623a3ad6a0d0902bc21b06dd8e2a3abf905cd410de32925bc716a3d86267c4c04115a21a0d20dbaa7d3e96df04d8c7598f0e8fa15d2b742657e1b6fcd4fe14d2fc39f9aa6219ded46e4d3fd876e02e4aa7e41f148cb7181b6168123b44401b1188c7ebe7271d44ecf7c42c8b6eb529970e9557c202b4a553411367ddc656f85a06cb8214a4b20f7e934128af6dba4fcb8c23dd2a5bb15385262aee30602d13390e5f7af58d0bdb01366b3675cdde503164b9a75975b1d96addf1bf02bf2be712c259b7f3c498e77cf011663fe9e65bc98eed0a458490d2e621fe1cd87008a190b09c2f50e68e5167de078331734608aa5a3efe994d0b832370f99bf3e3a67a894707f98a2faec0dd8cd48a24d98f059a23774f793bd33bb9f79972a0059bb340a6489185a0db6c74e76dfc0e08e0621e56143b0e0f1a6c2298c1d76a3114510528f2e08d901b68d07772067170a05718fde10d2476743bc06d8e34a317ab2f4bfa927a1507e1ea18ac89de1e33d2c3f6da054d2c3ffe0291dda8851f1019d864128ced7bada9239d9f0afcd9b753e2c442eca4bd223bdcc490b42dee88b6f63edf4c94a4505bf8da54c080402746b217832c831e3d587e0256be3a82a3a9c2906f22298e1e395d5cb4131c5ba91657135918464e1e18386f3cac20591d5f9b8d1f0e89904fd163f3fcb631a1cd77bc082e6599a3f2a4f4c8e26954c7600a3c504fc05f7d167290b1774faaf86c05394b553805b7c4d70865c09230a43aafecfb1272fd4284419521b5319b03a598629a005e26c8fae3a9eeea510c3d761b0f53cfe1b4061d42431f48c474b70475b4abff4b99820163596fb38a4d8af197ba6832b606c1c939608cf1db118e3cea5670e4d1e0fb2471cdae58a626f4038a684686c68ae64a9f2bd74759f0f6f91ae0add030864421f0afc8def56f58f3131ebb02e99bd18327ceb0c3e7ca22c08296a5318ba31a0868a3e80bd4ef9ef8f5a63f2951efc71bce656b1f891b766f0adf619698aff31d5d11f02ce4e93022296c7abba33da3e83aecd24d791d24642ce0f88fb6e8c8286ffb887d22452b4fc262d5a6e915c72cd94c424cc98771194ba74587d8984f42dd0f5d2cc1a7e4b32d7ab0893de63ba3a20e54b266352b800dc2de80fbdf33598a68cb54ab9f38722c78ae0b425ea6ff031fd51e7fd0b27dab233ebe41e1b892f606ceabe49ba1cbc6edc9d2fb98f7b57e78297d3d6e086af4466bedacb4ca09776a12ec2b6949265a49bd4b6ddce37d9bb20aaf44b7e1284f9c4f5276ff8aacb3453fc2d2ba51c9a8e0c50e4fdc278ea5d839140e527de30726e8089e3c0c5c9f7d4b3887ecc5618b53da00b078a5e2bcb0c50884356eeb5594a1c595c8f74fcce6632446fab8dbd306c6d2aa59f99a01a35126919bcae6cd7a825a2cda0b3c2e542f41155747998f13e54c38f75d9e281205c4796e2ed31a08154c99653bafaf9d7502c69dbd0d3c3a740f3ddcd3b3e5f2786ce0c42f10d8e951c2d6e255c02157a94093cf4c4619b6651c44f3046cd0a2bd31ce0bd40f8cb2151dab3e13ff7acf1d2c3b82198abfbb861422461d3066cafbfe77cc489a52d3981f62a5c766ff6c2e29f3349c48c1c0ce748e2255e85d70c4161cad2c8acd3528889158ca05248b5e30d933badb774cc585c0a187a4b5424c9b15a322e0c5a6320ddd445eab8881fc7e34a7d751bf20a0a4f8fa6c05b55ac0e7eba2cfea298f5b3939383c24ead1a2c83bb5346958a5fce57c0e299b4fa4fa5601c06b96cba86185dd0bc115e215c7c7c9fc1d78d242f5cba099283619e7cf8aff8ee5f82ddcbbca6d33b869528fa4e3e598ca5d14b6251ae4ee0dfdab080d825abd6d08b91c28cc34cad010a3e6867c87c0cd14d00f2546d75e027765f88ac9e3dbde2858920ec6c6575ea103006f19955c3ac3cb5a8d41d33b8475bf17f05853d1b8c09a1b25784a66307fe7289388ab84bc438a46262f1aece39e3ca57bb1b2abf550d063334a1546812ea9d6c8a205e0e45b6ed2f6e115819a419c9578b1f2d1afe888c4b79b666937ec56d2b3144bd26adf100e41172bdaa1eedb2df12ad8006a66659574c006c344702e24b54fe09a3fd7d2a8a87ee3c55161467c80e26554455d2a0f0e4a4910c4bdecca2485707658734a6fd64483de1a901caa2984be1d108d66a9b5d04f6c2326b6cf8511ffd7a049959e3383604068a3e375f950850e356f5d2573e5f77a4ba2c04d04ea1b20eda36b88ea044f3706abbd37840b5f3787ef14094179129b54c283393fac80db3fd317a2b8f553f6459a7419d8b158589f04c5c70260255a1425be6a2de5dacd88961fd5ce8f49f278627b4831eeb3a6d735688b7a34124f935e03c60714db3ae3fcfdad8c8dc6ba4ac3cb206fbb7c4cd9310bfc0786f1b5e815b5360c49ee7e8d26f933823f05675343d7b9d53e90602b2aac9034a94c55c2e3210a6a9b6344e6d2ee78dc77e31fe38ce639f862654488cf0bb548eb32fc4be9631583c6440edc3327843cd80c96d27cca7cce4094cb60e3a701f845b02e9c91fd189dd9ea29c9e1e832d15084b59fb9bb9b213a02b70cd81c4328748b9a8893cd0bb1f845845ee25b9c1854f0166512cad266bf874687e298b8f42785c2ea1014d25e3b6565a9116941be22b8cf919327970bd956cdcd3dfd226c80e573079116ca1b223adca1264ab3962ddb96d0693942c0f33dedb2c9a662b9e3d0577c2f5b220892cf439be7c91b9fc89c270bd4f781bda9c1b97a8d5e650afa681abd0bbbd8c4c49641c0912a1a558a51243ff8a13fd7a1e7d0090ecca7eca19726b082de1cbf65a747b14a77889e1e998d769fa068f6341dfc433f85a41a086898f67007a9579ba3c29b5a899892221078faae6fcea923cf067a7d4484c1e2a412fd7ca898cb1eac519c3e00cbd8721b4ebb99dee40857a36c4db9ca470f830d13b5893788356ad0da70be61b0cee21197c6e74555fb5dfda90320a4284ab13daf28b1517552f50773421aaea469b2233b54bb2e7a78f526cfcc56c4d6040394b9ff8fdd1640d3b2bdfa797e66c22d2b29a155a2c25037ca0961dde875ee5f547602c66c609e8f6e53138cf986d80c78d0a5e8117ac743617797dd99970920daf81ab550f6e0a4f1caa0fbe1ac3f52733169a8c3a4bb8d684958a8c5029be4e821443a8f4145a04993ac4e20948642a2f35b6bd54d477f704a8ff3c7417b142b2b2e8591a6c0cec5c2de996ccb2c042d81e137e5b8c945e4cc536e678b11cd5c32be80e86d2f1ef04c897dca657ab54e4e4defdc425742c0dfef9383cb34c07b4ee36c5bdbeea8b84b0d25f58a3593b61d9a80eac846d89e50d9518ceec09ebfe11ac102547149125790c512d72ad759a36de382e7843f62758ea980317358daccb191184678632b5b5f1bac28e31ba1ac35605bdecbd9940ef1c7f252e73736057c43dc3cf543f284a4252f5fec770561443c5da8fe24e2481dca7fd0d38770cdc8299ea63a3066033626d8ad96b5393541a5b873aab6b5d53f8e911d02469ffa36e8c19df658716d0bf2500f3513811b7613eeb49488d02bb490858e2e017b17c4156be46083bb2b4e77d57cd1a716d0c249cc14ee368cc830c5698020ba66d958a59d0c1ace285f2072852158d12a856e9f31df085ba114c9a721e81447a0e2b93744e94117352b29283f8b541a1bd92f38221b339b3cefe0855819315b104d4cce7cc5881ba176991c26f5b3fb845416b30e7a3b2bdc139da18904c0161c42ee339cddaed9e88933bbf4c101925da4cad0ff333ee312e0decd57242d5f2e6655aa4b6afbe36b2ac9914e7bec2dbe0f8cc107113b5576f3c8a4ff7431110e59b26352e81c378118fbd9f70c1da569b62c64c8c1fe47da2deb45d10192a234d5089fc44406ad98596d915e87864573f2ff3f8484888c8fc5bda034b998a2b71450891b70c2257aff1a81f5ccc61aed5099702ec7b60f12985228763492c18322534ab3afb11105febb0a3f394a5b1e19540ec401127a76b16707273e39e80888231e373ec35a71c711626beb21d2bb07e413926454ad3d4cd8dc9381fff122a73fdb05d54b0b02e4aacf22321e2ff19a7e6bb9015f6293708a953d7c16b245a55e17c946cf08476fe4a0899f6dab3c14f7a6b284cea90375b9f3b7724dc781498297a398cbe274eebb29077002e863af2cba0c82e31562ac05ad5dc2c86331251ed000a1c830984e3c777df04c6dc178ad935e7683a4ad43294d01f6edb9e1797fa15c9191f88f6185992dec6ba7ff961be0c6400014790b17d50850406bcb019b0d0eb628f40a3b4366d68d7fb4d0cc4aa706bfc3c8f4030915b645af3957f1b469189de2cecb86f5236e225db0696937b7d3d56216548358530a994fa7fdf2276ecbebdcc42493b4fcd2fa5c71d9d6f166aa0b225b37e8031f67da4fc222164e2ba52deba42aba3566fe4a6105214376d70d1751f284ca131d213cd879792fd7ff1f2e9b1aa9f896b8924ef7a8e45dcd8fd97b9e92032850cbc3ff76d330dc40b45d46bb3543bf69f051c598e303b568a0e1e53a2c5542e8ca32f4336011e36a9805ea5fd446744a4e5ea5f55bb7a773899e43ea13aaedc9b53bc1a1073c3fa01dd01da8830228726146c8de594f386a4c920009602807bce027bbab820c95335269406bf82e703fac04638089b38fb446ea734d1d178fde7f1c4e940d2b52a8e68145445cc38fd55968e9fa3d8feb9b676d080750fa7b698947971088f12aad99ddcf41f1a5c93ab9ac679edfe8850c6ea425ac39c72ce2b5b814bb3adfb2f347c3e54fe9adccb4411f083338eddfde64ba2012d45a5058ff1255163dd71e4fa4ae4da46faaba14297ea9efd2e6baa41a1edb9508e3b67e3bc6e8975c0a29a2fb28fba630cad14773154d2b1abba50cbf7ea2108d8e0a8ed1593cb19c506dcb42ee260114e6bdf8821146933cf7f5e3272b13dafda40c0169a98218d85eb79672bb1b2e1cd0853262e944ebd01d21602514a05e342248d4b08e22eb43f8546b4dc430cf8a8450393ecb1a31b9d0dd8a2a61da570f94897f5beba7a462c9f5367805e043f235782e7e537c70eb4531f3d3c3f1a39be4fdaed6ead26b1ed761e539c2230655b14eebc7541b234a14370994e7d6c78af4d41ba467807ce2218c4d82fc1087a332d35d99b1176ef3696835e2e40cb4c6b7ebe60edb414cc331e8be095a3ded7e6bf81c5d0dcedda76d04c2aa7a1a0688db4fa6aa98f3c45d61210d974c0046fcb5d11904094c6700b73d1c48cc20eef16ca8dbbc0181e88d532d18ce1a2f74b5296c1c58ce32491535290fe453d41413d9449d0cc5fcaa79b88d8423569cccfbafa3f502d44b056b689911612580699422ccc95022fd7ab5919c285284bfecbff3a04e50b7614d971b542b4c4dff36a5de5de251090899c8a99b8b2ae10121dc2224a5ae9e0e84338545802c060681e0ce5893465ee1d2f38a883f85865d4b43c2a240dde6857ed476803c60dbf578d8dd1fd2f32172a9d02b3f94c95ae5f2cdf2b065452615b8d343d91a915516b930730a58147428dfa48064e4a99fe91d550bdd03812a92333e4b3a78649d1f69b484fcca9a5371c6367682e864194a4ca01d90eb79ceb9a35e34e9a58adbc528268d2e1580fc197a89b6b03086588fd187cc073898f437bbc669cb128e7b7cdfff8544cf517f2b833cbe1233a9aedc78a7b9f446d3530d1decceb6e3c1e8f5d6419cf025d289d75badd0f3e18987558f50b526cafbaf35a6d913aea65b16db180a0cde4c0ba6b463730267efd591483f515730fdd8c224950870f1049d3a0e0f1a4c4d2efc3f125466c1b318c394d0f134d919c289fb21801438fb85ee4eac5a561d20cddb2c176733a4b502370d1ea802202948f44349da347a7280f466c96c5242756b710a85d2e88f0251ef70031e3e85342a0a960badb1a693dedda6da76e02d2c0993235a9367a14e38902903663f6b3bc7033108de9c170f68418c40a3f3b9c90254f7f4372858715776d3905f7e2cc4db9dc83f2c9242f4d73e5cca68273ea8a5e9048cfb50091944f7987974b0d8d9a89fa6c8e81456c4f5e1240e889f36a26f526b753ff549a7b483c486407d719eee4855cf8e3d6da9b7c4ad92e2cac7612ef1ff41f5264711a8a797d6d424921319638aa1652a77a4c109a607182f9a0b22b2baff5bde75c20b990697cd60068bedf5463181ca2f820fba50599e12eaa09f97cea7f7768f1526c4dd39c5158167182c1fe9b82373865a29ae35e1d76956ba68ee21428da18121c268ddc9d38a2364d695a13250d139ac47f5619fb8afcf04fda0ad034cd5971e1d06038e18f431e4c07c3953f792d40e26c10cdfa523be712bbb263cf089c353df708a60d1e13ca5ad964ddc07e979b15b208471676a0bccce2238b2d5e6710a175d31eec4688a80c66056ff03fcd10fc64244551556fc2059a7c5058d4124fd39a2cb493a13309f1e49d3200f6e0436e0fca00fab147443b7fde8158bff75a24eb7c0acfb4cd047acbab1735b61a0eb6d61fd81f9e606a0cbf94a624f30649adacf1c742fafc048c25c8e1c08543b105bd7f576b6d38834673d34abd69007f76c311c4e902bf80464f914ae5acea4a4fdf20c1a67a41e6153e3c87ce422ad85c3595663c108bbac3323f791d275387bcfab21666c357078436d9a9f9ed2208320f0cb6322c32125ea1673579a3eaa76a8f0e726f9bf2c0bea7abf25aeef491fe22e674ecbce9a7831453771a1614cb67187d419a1ecbf8ffb5c108b085d29867d7e9846d4eb6653d4d99dffe46352533ea85e793fd39386e312ce8fb5cfda468903db37e52c3f3281d889acd0f2df8afcd19bc29b4d8aec5f156941432d679804700c38d9c07941fd17d5b43139f192effe95247eba61647b77caac4fa21584ef124b0bc24dbcac1adb18bbbe264dabaf339650dfd09f5c0f647915c15be98b165a8007e345274b0ae5a72883141e56722762750415c47d6f36ce0b0da24ceb7274ca6e1be5ce260322b2a698ba737bf7050fbebabf344a09f1cbdce722e7f566af567dccb030fcd51c9f667ce744f900b22ff84fbd3e87dac73e0035517eb2668a14726758cbd9710c944b9d51502442be1db150591dbe1b078e3d7dc020030b32feeb27c281600c928b3a36fb04ed2d077d4dab56e97e9c2707a14553b158d1692640ee8345c3fb2fea77d25e4a10ff8c2cf10df133e888d6e9f23f14d0aaa2bb7731cd578bc5bf541232736022dd9d0c7530b13059465556cdd0e5a4fcbf2bb92021e21ce9f4da86dc3a93f3eaca39dec791e11a7e6ca4f37594f36b1619221e90b7df84ddc509b920a610b61095788677c95f09b4867f988e7e3b10405f19ec6f21aa120c26cba98f05faa090a50d14288d5c6542fedc914db46f093dd0df6c61bdcfc5dea94ec72e647af7951e8e884701024296417074d71daf1f269bb7f6f077f76a3bd82f272c6849719cf20ef8b0bf9bbf56f7ce92ca2c17f0a217082387668bcfb0cf272312155d8a28a45d3fc9edd1e733fdfe1168a96657cce44b4f891be357f75dc98f826b4d4590925efaac589ded1edde8a25c4021928b612cbfd7c1bf46a7ac8f8813818112eee90017cd8a2d46436b6ff39e169a8869f69773f653ecc2032f57f0725745c9b986ee452a7f064284628f32599d3a88c429bd34edd4a489b5334f1f4dcfea84badfdf5311ed0cfb48d2bf4a9535b3c4a5b648e8085896783845bcd0f53bb3eee625082e383883a4d0ea9b3912c088eebde91def124e4cc76f808787156a62fd041cccd82c79c2d1ba2401661d22787125542e19655782b635b1a6f99cf2503d7f5fda5ea6e2a73b6bd5d291fd5e916418aa11fa78c2c68cb6036805224e562df0ac5ea32d3972450f5bddde9f68b7087328f846fb8b6f81b2ffc41fa3e1ff6e3e52a2ba4fc56eb8904b832a4dd51a31799e4aed56acde29f080e65f6388dafc04e0929ef018234fe9183c41b0d41694070ee547e18e77758a574b98518e1b5fc037d11a307ffc2af06c03dd84d68cafd7129c1dc855b0d829fc163d15bfa82fb13a929e3223e52b0a8b46e29e0a57618064d62d5bb301258ff190132728490fbb4aa5a45e741eead75352ad2bce7dcce531e20b9e5cd2c3390f1d2517139fff5d6b422e383ce9457571c8a1732fc160e02aa97816230adae105acac57345bb50959dc3f1635194c467068c4c05d4aee649594727181f8d8492e73862f5cd477f5e1823532ea548c301e85d372a72c968620546494e902e25d7922ba2029b7177cb8296b58e8dfcd16662e0d878c5b33c769df460822a6dc6e9a63612c2d439aee9bcb48bd332f99d1df7314a01f25e35cde0d85e89150e2039b0ad69fda9642c5095cc09f7d8ed98bd01caaac4bdbdb18e4c8deb0ad1b632198053546057cacdeee19b503e455d424c111852c65b1cd87dc726b9c5e6218ce5340d446150fd3e2317479120f978ee9bf60420033c040dc3d667e92885c6ddf33763c4dd15164c7803158194ce2194e88e94be3548225ddc1bf29625cc0eaf498d97ea822cf1dd7e31e67ba4d51a94dc327d85c4cfbf17340b8d99b73248d3c3cdc82442b338271a0fa01897b4489cc5a2defc5b8bcc00842c9cb252a60a03588e1294016b3da55fe866df3509cc94dccf0a410ce99e40afa883971bef29944c619217975196ac4a78166343d899bc0e76f87842695320178999c0ebd8a241f39fefafc583f2255973ce4c27776c36dd1bd7d78d1105686950561e9dca5d172ef96908c6ad7ec6f563fe314eead35309ccc54f983a0b06aa39f68ff588a982c3e1b23b03d4a7732a8324e2ee50ff43f98b3158373e9b470794c9b9bc1704340c05ed490fd03050e0a1f91a2d4831d4db04ae16db5b0117f6e5d81a463f52230ff8bf52e6797281089b4015a381fcdf019783c291b55965fee711f1437089a28d338722e070e8e3e71909b1196ace829e45fad7365dd8270f4d4e6a327725a1635b33b8c4a6734da08322cd7397cc6749342883c7ff136f0932286e41a5120fb12c2d1d18b23500c608bda0029e41bc0d6a038452a12d34641c28c6d42193ba12bebea464eb1fc5a00ba6df921f415ada821f2c65d87a254dda1f4a0fb3c9448e3e8fc4fa2e8f39ad8d20a91f7bb65f7c4ef62417feb761913fd68860b20978da8e4133a3ceb95e2388ad1a5bd10388a795d9ae8ed3cb979763f42b912a411cbaf22842607bd27417fb7a200e9f61133d1b4402183267f99bc0369f42580d9e90819d762e5d5b5ad0182cc1acd4f243f5fa1de20bcb921d5845667c453ad3649be0316e54d17adc98bea1bd4fc46a303c2ad18d1a81f721512be64fbadd6ae367c52d6c91f663cbc41ff79aef786ca552ba820e01280617a83059db9430f2cf0e9550dbc890f0af1309cead5e0f209b0a329b5f315a0c8df0408780d40f1c876dd6d7d973ad67818a0734da102ac34aea624e3bd6a54815e895cfe6f32a9f460d07b186c59cbe7b0ffa7b91aad31ba977733b4f2fc3bdb758fcb9c31eda20f69c346368bf1713100dad1932d0cbea5cd8ec141e68b5dd5e8c5d1205eb830dc4a78fabc0b80ab1698ce5fbc7e96abbb2a629b74db6488ff4559050c79b54da564e5305e21b10f799cf54b5e347b432ac60021ba63e53d0ada9e384dc2cac71afc203e2f180773c5a510030765143a7319a2bcd86513238227c10ab23ad11fa8f5628e27a555d548309017f61a685ba17ea7f5add012607a1e9ba3ce8f4999a6f12526628f7ae8ce0e709867e7c550d026ba9728a9d71a31cc110cc202d9dd4a61f091cb7852730fcb24b491e079198a4913b26c2b0f32deba055cbaba8b184b8f4f5a90900e8942e464ae1e00b52ac29f3e40b7704d9d074ed8dc368e08d46954a53ce64e0f3d99daeecf4af88acbfccb9a7441958494d18cd0e3f3f2bb704815b1c595937852a7a26c058665297d195f41b1cf3fa17a3e7f66213741450116e043025b6a56c1fb837c641b00cfc259b17f47b367be1fb6949582a0a0f8631f2bb1fa63f3b6f089b3fae8acf289451ec8bc2f7c832b5c29e415efe905d3aa3527b5761b4473b480e00e244d990100e3e88632491ee5d7bbdfcd69adc481a15098e42cf36694f5efe0882b005c5a41903f0f7f905296c1d3787e00282f164c2aaab966a788770263f095adfb748fc416d63043e45fe3aebf159352364de4c8e6275039b1d6a2e124280a03f5e6d26529d855f7aec10f8ce40afa49054606028dc465c9af853b3145dd61d875a0958a521a18a55f6d286e60d160b83f2cdc27b4235e650714ad9c7d00e0c347e8071a1927b880596e745354b28e82ffacfffc3a59a006e236586cbc74f1fe1d3cbece560e7ed8fd1fbf98f0313d3c1c0d9d34115e38d07e831a8f87f01b695cfa39ec8c3ca4908de6abad71b9e3b9c9c24e05358589708d413934ab1bac654ed9e05c96f3ee89b8070c022d6d61a6f7c55592e8c7565323c1bb0fc3e30781b485090d0757decc9ac2b3d09a1894aa213b74d18b588cf2f935528e8053a94f940fed7a03042a109eb702513fd9b57d467c1a27f27d9586d09c337e34fff214cd8cdc6449dc220d581ae25e2990d8e407a66026338b64a1842d57c292d466e305ecbb87580584136b28b3b8b95f573e723498e2a4b4313e0fc3754fc9b31bdbe7e1237f30aba8b6c72b66f3cd4bcbe2e01ed602c88bf20da00410fee28c37def869f5d06563cb232bd8d245f06db57deed11d1f59849f6b2ec8cb075e4b9c76c48b8ed47a1818884d306f2734aa8389c5cd28fa0dde97c13cec3c18cfad30cccb11ed9e213c79b95124ff1297b308cde9ab4ca097a0fad72e480b95d06784e572752ec1d31e0297326dad5725a8c0de32ccb4ba5d6f2af6f0e0aad26e0df52a25eb01b054c8e62e68081bb606633821f73d84c2d02df1dbbe98a22d453113448873f34e875d329e502a743acdd0e6f3f492f5874dab25d3c9a13b9237ffcaafbed1e071443c3b9eaee983586663964538018b2e12053a147584fb5fdbf5e51bea540c912f75cc332acb2884c1a3cd192b5026abe19e01724d8c9429b6450c14f4dbe59556c33d4e324345c14af86cf84c17bc26d1971752687f1f535065cdca38b7ca3a9b9ff6986b4f4335f0d1bdcaf6bba96482bb56384b727f5ea82b01ab96f86ce556012c03f06e4fac0e551a417dd43e9488869d55929df97404c29da98ac4c1d4952b0b25294a3ad89faad5438026399620ce36103497885a595b3bd4a0d526a04480dddcb233f07464ccd0b1e362a01365516deecde5ee9e28b329e2179504515b1930b6107a437a3d65a866f206708c879d88682c74b673f2f1dd99d24908c68604ffd81056a82a2b315b8abdc828a735b3e5a6e3dfe66e1917a628017a0f2856fe3002574b3c5d46d5f5b48a971a9063f1ae592d4f456f7411544c103d578b3d82be3a40c90fabead4c326b2e359ef86d07bcb7fa31ffa43b6bc96dc750aa05c4e7b3b4a4448457d806f9c8df1a5b0f53833425ae384e48bf565ebb45d119414456350dc8bf033dcc31663b2e0fdf523d8406bafa2010b2002b82823f15af74a3ad7c4c3e87fa4e03b63ba54465d5af2ee74988cbb32ee29365ff2083e21d85da37efc84024e6b51b541f8103a3f4eab92172f527d12360c74691acd3e77f1106849b51ff7f19a932900b531201875b719acc448b6b792741020ab055262581e78213a028d13c3d901123aa2c8ab098271374096ce0cd3ce108ee55f5e145c1f2a60157851359b7e5308ef576f08e3e9227233e868220ccfdf6ede96b6344f3541a141d1044791d8f08c30773a50df496cd3c4ef93e014870475091b88e36373e984e89994c5641430ba57bd7553582bc42ab21b88e179354b733c2e6ccac454b283ef2f350e02b0cd887fcb8bd9e8cdc70ccbe8024598fc03ead9a6019e866a41590211ea6a1efedbb79433e6020d83d6f690624e7ed401d6e90384a1e85d993cea9f83c199e16e462be0f383150186cb789dbe08f7999985d028b0b328708fb49bac9309f99266a1977b450abf80e5e59990f0690ebe02916cb5b2817982e40bb403afa0cba3a58f81ec7827f61484fdcf27d1169e597f2252c2188ddb984c8f4f0e8514f1fd90aff02e878401efe45b92dfb6ad4a317454776067fba0ed215a01e9238790280f33bc782272746de898dcdd85436a30814318ea9410618f35cc4877c7cad245548eee207d8225919594a024b8afba397e6d689bf4c15e87501e923e810d234799b415bc869a13fe4b1fa4deb99234ac7f561894783a90e447654df6faf1d98a9877f61a148aa1b2ba37d2624babcc86cd63497393681e70c67bcc959407ccc0600dc1f20f8770953a4f87a539206941ca30f24cb7e9d6062f8ebac08d840688818dc5ca9f98054a25af61310817e05765198eeb76e7c86487bca056f582fd1a39671f70657f1f59ba5622000e5443f6a3c442eb4315b6787451321f0e5efca5d19bdf9d0897b2e71d4c2a7095c2a13bd7591e1f55e7614d9deda69170ed7d1111f2c6216d41e8ed050bee96c7cfdac1318086c2915b955bec2821441269a2ed0cb5b114a82a416a5e61e2a3aac6a16af8a4854c242cde70c27ac553f4e939288e5e85c7a1ff319e5ad040750a69ecd917cc87418fea409359f757f46a28160fa2b457e99fdfdfa8ea7070adfac3eb5edd733c55e929ac8e364470da2ce336b8db6f55f3276d9da172c8a1f397bf59640307c2679060b7a183a6c1f4f1a5ecd19bc74c82cb7883ac9baad7a4c11cae903186766c33632bd780681f34bc6991c0233310b9e8ef70f6a946bd1186ad330b1668bebdd19cf5861fb06f4078f5fdc8df7d4893f208ed8be7a0050a5fd52f76337581ad61b9a967105e5cea8336efb52cdb3127e0d3152d4d1df52a94cf12a23076da06c5f63c9e725a5c23fdbced24fc4c8af680a56196dac59d8f2095124c0ee825b54ffc3348b5587e075a6fd6aad72b19a40aee821deb17be888fb4c0b3eedc467dc76481e01a506422bc1f2d977a98160923d3a75300934132e2184b80ba5d93b93fa5fac96db9eb4e43057bed1654203c2f3f2baf095fd335e970772e52e69418d363974d82829674ba0a3c064fa407695fcf82f1e691b6297df41d5312b8e67adbf4b2404e9b66e747cd3aa25abb9243111ee1f82fe560dbb4bbce29d9689f5f6da7e59f96dc046a7f7d85633b7210e684a767bfadc5ccd200f5649d0985229296971d5acad8fffdc2c1afe5b8627a8437e16f754dcda395d1f49ab7189988e3bd9fd26618659a50ac43b1bae60fc304e0c02ae1868cf7834bdaee9a5c7fd0cc6096eea06d17e85ec997dab35352eb77af98236451ca72018a5aab42ae11b02fe99ed0bab03222c82022e1bc0b2b0267f7572e3f8c4f6038e82642b023feafb046d7fd3c116be8fd7da587881c0ffc5ee8796613ddf4f82df91398587a629961ffd65da28963ed2eb25fe33962bb4b86b97849f434d415a21b473e6f0c9257ece9bd99ccc9cbc2c04da63a093a1cd6840617407ee5ad5a84dd4296d09ed2c52ac376e4de4303a4e3bc4aed34aa1aab836386f7a6658c3494b9f2dced9d9a96186b89c889d20a985266bb8aeed13de92a03e903cf33d54597003e49fb427172f988ce4aefff334f84f213eb76a2ca398b8c1135fa2d70f74f5e52a695f9d974c3dd69f8c473f5094dad7fc92e092cb212374182639e71cf99ad2fd4c9b97dacfe3e367ac6c5438de6169c7cd4dec5551bfb1e06be18cfa45b146b08bd3f47a6f105e54496f5301cc358aebb03d6ea5f7919a293cc41fa6c4305a75379eeee9080c2b402cfdeded5802e1c7d0e3dae484279350e1fadb6206e12b8c2be0041666ccfa3a927bc0267371cc849cacefc73b5ad89295708113ec15cf83efc0e76ee14d252ce68b2072b25b8814c2533c9b387e344dbaa3aed98fa6e886061ba3afaa42c566ea84e61d7ee0a9e1c3dc5eb74a5d818ac0356675715d48b9492ea2f7f18be5317227d7e0bd8163eb2cd7cf018379712ba3e23d47afb61c270c7c4cd25321da3669df270526dcff1a489fe1db9f313f8abf0e3dec5e7ebf5b01693499b011fa95eee93e3b471506597d4f4ff37e0d2bc9f1dcfe9b259baacc350f4d6ed4bf7b891f6d5500441bb3aa3a9fe7c8ba49faece7be1489c463664797ce8e279a4464162c22706888345828fe810774e4f6b38885810a1146e84e845bdac08a3eb5f35fb9916c73b0b1ef4e3e4f4948d3272169977558048fd795f11c6519b8b63e2d05d354d24fed29f7be3fe302cda5e24c7a52ea7d27b4f7988375d48b66d4dd0fa5da3efc27b562ac95d895ce51ffa7715566af1cd69f7336572ba4a7c5280a15f3373635aae65f5201b6b676c86dc124d85f164dc759da2d5fa4efbbbc5dd1c4f91413854a15876e3f748d2715f98068581421b25f8ae29ad78c69c4416895bdca8c46e03aca97be88e2ae480449c2640df963708162b07b6200297c07c29f051de67d817d3988db1a879ac6167ddadc78b4e61b831095e4e309a7082784d6afff3ea16ae3f35cfd7ff1288067ebfcb284b4f07c61e6feb52750c79a069a27398f4759838e6117290eb37fdce596cce00814bdf6fbdcce3af8466de3fb9da66b9d2cf9e09bc2983c0071f28ce3c67513f8ce561ac395ae40a1d7740c6545c667f94ab2301b361dd6925445b4c558d02a2b7503d6b185a5026001f7ea6fcde53a88e6f9be701b5280b5fa57a98abbc6578cbbbbfe9183ffa71d3de546698ff0a3dd8c85e19de7ec210443d5e84c0f774fb699c25ee8c20210c51c28f001037289f6d27f312f5f45fea8006b110f44c100fed60034a299e4b9b35f216d905418041a35b26140e196fd72a06c77f61cfce704164598b54f27b9959723aba4b8b2205a086141877b223f1cdbaf25f172565ff9b7cf077cad9163b10a1b68809ffa3fde074fe796546bdd39fd8138c5c8ebb503d69595cd968995113450f87beac4c6fe2b66251029a43adc74ccb5d5fe21993315e3434ed13f2d8e81ed7dd60e76fe52f347feb704f036470c720c28b965fc656808c2393c0b6a1b517977d54d17dadf34befb4fa25ea6c7cc0a12a4cc00aae7a174b443e483ea686f414049286f627a3aca5589e935fee235c3518f8f0c7c20d2319e8667dabdac051178d4a4cbfe77ae67cd2ab45aee7dd200ea90920efd30717f8bc367b01ffaa0a6bd3c0d8b8bf8550dd81ecd80ab3d1f4a248d2a527386223317471fca78cf6b619ce7e36f052882ec1dcd68b212727de8dbf39bc9c3ed0226a910bbc6ffe5097b28a229220a6382841d653707fbe69e03f6bbf280dc353d887b88a093c403629fbebf695022c720887bfa65772233ba09f782c8942a90cb1dfbd635c59390297111e4e646334a669c5e573f2d1ea120eceadc5da012b584acd9237927a702ea2f97d172d4f8fd0f900e6a1874800bed1ddfd771d644e99ee54c58c5e32b500b8787e6fde59eca28b8c114d14f834c74a1f8546fc3d3bc745ab9b423b369353d0b73a2b9c9c1ba3839b3b91a557fa7173fd8ee029698c59f0de3bfdd4fe0f70714aad4d743b6657f1ef7fe7f1e794d2b33d068a89a04d8051c858f90b14f647c5b1214e25ee8b68ebc1ca8edb6e386dd18ce9b45fae10e1111317114aebf4051acc57b53fb8812c68a8d00deb63f130f05896aaa38bbcf6f563aae9004a3eacf21874f74a4120aee8380ad2e459c28a3ada04ca520391d832e2d83e5de943b110679f3a096407dd3de0ddf802b0d98d3c1d82ddfbff4e7f3dfaf23a888e3b917ec717028395ce7372a8f05382201ba57d1fdc37126be791e2f22feb0777d4663a940561a2c457d575fa57cd5596c99abb3825d187dcc7e42cce4e7f2f644b6636cefb479f7f9012b7f0622ce5fc033c7fe846f076808a11918afb3e4355d223abb820c741f03375303b94613a16f926beb660ff832f46db3677982ac8967af136b65a8f5dad46a506485e3cf24ba69791961704161eed3413c376975940a190d2152e5b7f3cc7660bd0667adb8063a90d72da36ea8017647547bf07ae857f5b36d55e23656493ce74b4059a409a71b054a8bed97acc3966334cac1f98706240204f14b433e3d261a7b1d08a6d73309bc9fae4a3451991395ba6e565816f8ce4e752c7072d440a41fe121295398de1760865b178e10515e3cc3608139eb711df2fc9543a2287791342a4ee66ce97d4967d1b200f549fdb3a43479195541896cb4bf5aee709e8116c93d40eb0ff3b53519bdd9818bdecf69e7ce0013a4115715ea341b746a4c0260d3faedca6b0b89a3a55c7080054764d4e7147c5193e900b7400735e040c24e0f2023266b9f33d4d9d4a037b742a07ed223ff4640d512125c2484caf71e5439097ec2555377a3780e788f266d9058c33919017843aec43710e98f204fceafa42f6c1d528df1e2ce2084958060c6f078a4db164b9a4eb7c3e2ca2bb35ffdf49b0df7740f21f0c80e5ec59367c2d524524d09f32529eb4d3af8dc0f08e65b2277c3f2fabe23f3d347d8e3598a110d1c66860b2147e1e851a07270c4b052460c32cf4a3381f13e79b39ffe91962da126af94c9bff80196f0fef0a525eb4ec9f2b63b76bc2ebd3df1e4a3467fc88c12cdb62a24ff01b80eed8303564a02463c0989b52f669f70c37045823d470b8602fad1a40681e7b23effc6241df80b61be2369bf1580f260a414b5c87343b26e8c16fd510187904bf8fad3f5b1bc2ce905416e0aee0f64988f6269250882cf9dc832ef83b4cd21e035f7ed89c11d351c9a2971f5517c515e88eefa5aa76d65b90c5752550bf9bdfd0e3ba634129c3c5af487f11fcd480d82db932caf0fe43defa070a5a4a099ee2ee033054002cf5a4cfa7c97ee8eb9afddfc0dcbefe3a8f56a9ca3027669060524e79a6ba13c3eedc87cfb051346b8146fda85329ff6765a983fe848ddeae3048aa8911f322580e5a7dc36fec224d47f15a324e43fd4a091c691c28f79828c20461c14040ad48a9059305816a503f2460d49daa6f7c11696a91b2ace1fdec5ca0e4acd0c517debf1827a4a560c79d233ee01188823eb83f6e31fbf2120e805054e012fb5b9acd453c1ec3e0a9eb42c2fd3a71e37b3d6882464efbdb7dc524a99520a8b082f0924096ce3f2fc31b04de9b7ff0e70f90bc03f7adcd45c8699a91835a697edb1593aed47abe99f085a208c03472317d2f3921b3f15395a4d0f84505115284d8458b2fabc6b6a22c4922ba4be4b57eada51f1539ef76f32d5486986d5ee5372499fe3ee84d25a4da67fcf4947619af8a4e824eb2d7f01763cc4ee6b14dcf859eb8b17b232277cd1aca2254a04ab387b6444a21b185525ba0437c227c2aa91c58151d3464ebb1fb7286732a83097871899263e864512f5e3160fdd4d24953f3b69647b0bb0ca83a898c528dcf848fa870f3407c6f1c18403e3c88f5f01b6a11fff48ffd070ae8f6f3da83a0263e81f9aa5ed237299fdb88b25da48025e82bdf8f448fc4863afe0466ec59f338051a7d5712fc608551bd3f931c79d71fef5eccd39d342340c596760589504a2f8474ffb4892823dda477c2c7ef4e6523c299aeaab3577592d05553d3c444444695c807dc48f11034c13ffe32624619a780315d5488f7bf157c840cd3ec5d33f7ada477c9389bbe809e34699e44d5a4e44a41425da673dd9fb50b9381ecdcacfdeb9202de9921d4c7630e91d4baabfe60e37e8313a6c814629c76fe6523691e88d3e3f66dac7052ea55fdac1a4b27b2ef6f3b9f4b5b8757d7dc7924a5feba6ef14c228e3c31bede773c568dd7a2f97872e9699a664bf24977eff88c1ab24fbd5113733837b300693bbf7fd70778037da1c6d54fe90cc5c223272965984069fe5535aab49723ef25316f56b2b577e3de54a2b526c2f91d85bfaeda5cbcbef2aa5ce887bf2b7aea7bb0148922c27b9674e015c6c270de49efc1b3ba8d98fbe81b6e81e67d93dadc76db8bff131ff5118d5cb5fcc46476d2fb76deb71373bbfeb46b40d712eb9d0d8f60ff9b1c42a0a51f1a9cdbb17fbfd42ec42edc267c906e055fff0cbb4bb18e5d1f81ee338d3f4e7a1d806e2a061fe75d94fba8feb2fdb3ea4c52105a5683cc331fe57af9cec45469960a49561e662988d8e9a636818e39c6aa8cf3d03483ffafed6ba5652259d6a7079ee8bc0fce874aac1e5b9e781f9d1f3fdb970dbece95443e9b9e789f9d1dbc02b2641949efb20627ed45c90530da577f922257bdabe74d28ac4d8d3668b909494eabf3c4ffd17eb43457b1f97afaf591e5289b91d262ed6870a8fcb97de06ae2fcf3e80eb5dbef4fe3563b8d8afdf6342e8676fe4eb217e3d3414961196e632073d7a7818bd26f486a2853806b7213dbfce0c6e537a664e7d8c35f22fcf8d9cd47594daf5144a6bcdf8923aee8ede2c7bbea2b615292addec575df8650d5cc76dfae9477b3ad5b03df745467f03b3ff6e341eb7f93ed3b4ec6f80c0cfe93182047e0faeba2114037c1d0dcb201c753f2bee7f5640dc8395079eed39bbd9c02b1db8d91c1f007c5e610e2d1595dda3d67fba64cca5131a1fa065646ea497c43ecbaeebea2e4a4d1ea40db1c3184e5b2adbf90c2fef27949ea394de5c8a7d89d48d3a4dcbb22cf34dcbbe3b2dc3fec22c4b8f269899f9e740154a6b894f4eea4e3e7a9ed1e85fac0fcc8fdee7e549ffb3d26a77f25277727f97fa31d607e6ebfbbc7ce98847edec8e1849a24e08388126a1ee94591e785e1ee679b081573cd8007f87ec6de095cbc3581f9f9f950e1456cd66f918cb2b98b7a71d983f65d6065ec1d8d4cac57ed7e7c08924759dbe5f3ebdd4f1aa76bc2219711b6ae3cf41c85e45738a452a85d16b4af786c20a2b806c5a86d16b426f247c8c1bcbc8fc78771037373032333d6a6a328c5e53baf715db651b8625faa70ca334cba80ccc81af33037c1ef833f0bd0ca3b445c506ee132efccdaf0c5719d79ff20cd72c62422b92a71d86fea477f9d38ecb9f6ce855e94f455625fb3fab51fd6a3fd2e8e75e2fb3a4d27f7e8c310c7b86b0ca0863f04415517c981bcb9847be6919f642ae2d5bb6b461c31f39055c9ba9d248230e3448c37d1b3532a1c243df1d601bac2bf935eea8fd66bebfac0bed3c11f981757ba0173e7f462e7cc242725e14cb8000c9b0ebc7bdc1000244757343afd93df03c39af99197a4d197fdc3b8ad643d492c633d767d9c32c756fe0f82ccb328f8bd13c26bdc6dce8bb23d92fb5731996f83f6ff4fdf57af8a774a07f8fc949cdcda8f99db94392bab687a8eb2b0ba1761bb98ca2d55c9e7fa9a82a7bff1e32c398dd8b3fc81fe87dc557493f320e7c5a03d9356b3e1b172e818728855dfd7ab8d1e7c69883da3f82bf74bbaedf5ca575596cfb23a8d35205f81a1ae754524ba7bb41a51fd4b1419dc1a57db40f7f26ea217aa21d9d19dca6a18ef6e1ef704bce0d4ced238afafdf7a0dec0f3c1ee3bbb8da8c76d3ec67283c9543dc6de41c9ad37c4a836fe31b84d9b4c2c1d45d4af9a58cbb2c630da5996cdcf4e32649f39d76599f6cc651af69d61df18f69de6f33dc1e73bbf7f7e6f9bd6652719605b1ffc9da35b859164c4fe90c48e59ea4efba56e64c991be1b6354fc517c2ec6974c13396b993ac22b47fa909b3b8e2285a8332ea4d18778e10ffe23bd8928d643ac228a262e57a106d1355dae420da1abcd8d8aad52b799736a327e47db9f034f50a532cb94aa3019a6653d1cd146a4116544ac1e5f613a355373a660ed69222d510888a2101951374ac9d0b40c4208bfd4d58e348241240bf58854fffa7e97eeeb9503b9209ac6715cf771cc6d9ab669ad75d3ab75f7f5fb302f0e3ecc8bc3f51a65ce24e3dee6d20b8eefdb2503b45f920b3fd2adc298e6d53db7e95cbfd60da7c5410608c60584fa994c8f6ddd551847f56bf412aa9af6d95fdda7b19643ea6acfdca5659ed1ab65dd977d0ea98b437c987539a4e86557517825a8661442088f5c11218cdf18c42086c53859e8daaea750c5fdf526a822fd75913a18ca6d5e8d4bd858857d9c5807e328f818db4a837a59ca2b2c5169d462a4f3e1351f9e88f80cfca2664f214c72a1fde80ce0d7f06f866118b6759122b9f39b5252f4895009245ae7cba9e5f2155f984194032713b58c101a11bdce06f5bbb9fe566aaabbbb7b8ada2374990bf2566ebc1ed7ad855951112c9229698b8c7c84ddd9a0fa5ba9fe1f17b5cdf7503c0f591f640955a1d5242474bf2b0b64614ea06ab2202a42b9110b9a72b5645e7c980b6efcefcab2a36981a80883fa4d4dcb8d3f599355194ed68dbf234ac52edfc089d01d627141f108dd3ca8a87ff9d2c0f7cfcb57d608e2c6e7314585cf438a28acd13dd078e693555a1746eea018d48f85fa892a04b1b4206c412bb55fc0838aca97af44410dac9abcd48dac0285a75c58c19310b0d0a47a603e6149994058e124f017ac2c454d60c284279a587914ae7f8de222faa9824514222d2d289cb8c2440635c0019117b3ce14c040e3410aaa002209fa53646967a235c512ba5e6e4d31c6c52eb7a638632ee1964401cae2074638e2889567e00b368a5a555650831c1011456bb68c52469413aabcdc12a2410b51849c702688105b422a9861e880460f5cc084222ba2285d6e0941112a020241ce979fb4d5e553f9358b269c70a5fc198f16492a09130d88e81a0c31c485156674b9e58328acc009723425891478a1c5d009b24c2088b450e2074b10f14bb2c052ad27435c78b9f5a404330373085f620330890c942e7c53ca035888f0f324063e40620c278e085263b25670834b0bf9de9c5860190209126230c61a5b8c20011663e0e00acb77b0022e8eb82e27818b9607d0b8dae5561223b8dfa7a4179ab713ef543a33ec2469263ced7ce3369f0a08dc72bf4dc53852de7a250a625c1cb77a97ddee76e8eb4c033f36a1ea406666da1d8bb40bcb5ef38dcab95ddedc15aa5cb4bf6ee6d2c138ea9ad736394d9bdc77525cdea53341d4f59adc3431aa76dd8cb445bddc26fbeb395bddbbae87a155e15ff1da6a37ca344d7bcda52bfda8ab245bca3ea3ddd7d787783f1dae666d0ff1cacf58e8d22b73c9a28114d757dcc69d57d362db42125d8fb7ba0d13d10008d7b3d0d80b26975b5d10e072ab0b2b3709f44117f785cb2d1f44b9def6d98cc63b2e8344bd5e931886595ae5c605e1614acba8f32737445eec35312a256dc184228e0b82618df110ef11243dbc9ef934db360c8b379bd0b351f6b48cfad55c49ad8431044693fbe3728b4807d7c3b2e36661e53211164358586935717d5c6ef580755b5f64b9dcd222a8a585932bc513222b54b4b0b4a6bc6cda18350ca1fbc2e556184eee4d182c30b4c46ced3736a216308a89a2a0445554a22b626eefb8deed002304444caec96db8d583347a6006902cba3352ccffa2890b80cbad2f987891c665e172cb0b2d2ebb4d0a5b771fc52e04eec428655a7344cd6e6efa0271ef86c76fb0ed65b820482ec65650d3e5bacb7a7c3b172b3d89e3b867ae318c7bf7b8cff127759fcc2565309051b1efdf3ccfbd1e34602f93511257847d003e54faa998d83d17b82018666a1c9c69078b5aff8b97f437489f034725faa4cced4d7f4f8f7b2cc3dd998c2646cd300c4686de7284edb84d66638744cd7ec4da9e3ef6c17041280b580f0cc7eef180e168c85e875b3d381a6e68b820a4ef3b391ab2b7372f7041483fbb9fcb6e43b296723464efbd4cfb7976db60ed788897c3be2dcf65a6c1be2fb533f0509da7dcc51e062c286b815ddc90ecdb520cc37e623c37dc10eceed434e99e59f36c2b526e3c2da37e3757cec76c534a7fa326f784f808a1769895916f4fa0d27bfd8672f98bcb2d2eaab804b8182764be96795e4d0dd6a3e6eb713d0ec37e731b18c69118751bd2f76f15a62717a473903ad2b7979e392f35fd18a71f439b922aa97e8d89e962ca9db9dce24204976296ed377aca29a0ca50a737eb4edcf315261405d1ec4906ece963f6c4bd3d8d9eef0e90f41a471fa3db69f4a3cf3a24a30eb39799863ed67d29ecfb3199d49d76c6bd1bdde584c56245b1cababe64308acda069d42dd63031f9268ce2abc3c51346f1fd523a5c848069f83601aed61aa715f5b071d7a02f5fab8fd9cfbb18d0165d5c9acbad212d9752a1e532110d9e98d6b032a58563ebcea75926c72c05d2217194fcee8eb8279f0764c02b81189151b8f275a070bfed7e3c04733f1ef28e6ef176908cfe00714fbee7d5d4f4a87949d57817e769cdcdefb6c0b443e2cdecc634da0f89b7ed28fbfeaf9b1bb245f7346d76231b8d44b20f8485961c0dfdec5e4c74d3cc8ccc0ccccf984c2d34c60d696cbbb98921062031b8e4c47013b99b1e82ddccc29045fd642ec66dabca588692b80db786547025bf9becf4e830ce842ac85e3ee16adaa6a3c3c3f333f04851fb4bcfdc901dcbe39eff484ec7bdc805e9b1359765432c3704dee6283b8e4c4c83bd10ee694cf7c120e9993d86eddcfee6b9d9f76b5927432404e532d11466dc7a99688a1f5cc62244e6621b0c523037a4da9feb0f611827db8128f9dd3b5095044ec93458866118cfed1bae7342faa74c872475373bd37ddb4bf7f5f880dcbc97bac9d1d951f18ab254cc758ee55e8d769ecb9739a2cadcdeb62d320efb371df9b8a75ddb75514a63865858a8c609d13ef3ba947bf27574a0b6b4a9aede6064324ee9fd4d2c73b7d7816930f5291629a5305968a42f94d2178a75497cba6b56a963a6d9dc2ba27e48646ea5dab6e1c802d4dcce713a9c2c09e2b849c905e976db4cdc93929503ca57596e531b4afb111d90b88d3b71c20549c283ea0f01b7d97a6e30e2dbb68dbe63b8197e6ee7b8cde8e5c7e03693dbb01386b59452a68a6c6580e8ca211fb7e116104eae7c20a8dcaf9bf8fac9958fb5c7dbf2c1930bc3e5561845578b1c91fad4a9b3cbb847b226a6c9b2ecb70e89877141bacb76ae7fc605f1a75dbc3cd63b24a9cb29ba318e0fc72a258c922fdb7e321c1723ff8b49e29efcce89ea2f547207cc40cb1642b707781b0890107045a5b2986480b52a314e015a6700310d544df93e3ff0184e3061ade2fbfc302d15f83e3fec006a22c54a5a2afe3f9c90e0240aab68a9f4ff00bba7bbbbbb9bbb25d3305b33d0284263e85ebe8246153097afa041e52a216a30714a64326e702ff6304dfc1e8269e23ccd06729b18372b56b86a004f3aca57a144acb287b8f163931bb5dc6fbb3d04e3cc797ba02ad54050c580f9f282ed610c685517d1a8f8b451f1dbfbacd5a1c3e57e0de4d240d9fd98a853b8299864ab6a1c151f4866858b8a1df5e9b86dc3eed9fbd11437451d5a82151d2c97c8029b3aba74a3971df71adc5c84b809aabc99fe3143fb881fdd541fa6bc51c9ce10493656fbf9e5712fba1ced304d7c6e8afaf2a4d7a24296444a4d6a924f44462f474f6464a52881f997973d2fef43455a986abfd14bfb1d692ec8e8e50b67bf929c82c0ca932f6af6f1055a7c0d08e3909e5f875f98e8729c139e7bf0fb53504260c6174330e2076aace07f12f5a331a298c62f147d9900d195f642dcaca85ccfa50845bdfea3345c598681a88078afeb3dcb32bfae8797e501cbb21f825c9d0f7e31c62c8c9b7b1d8ca3b668cd6235fb88b3df79c8fc877b79f7d34b86a88078331ffc660c337b2f8e645cc805d9a1b708f99f7b7549ee9675356754aa79ffdcee7a80dde44b72e35f5434fefe1d30a8dcddcfedab76221dff41a02a56b447f85b33619c7e93cc9bd6e034cc30fda076c15ad498f821c0aa9fe123ee39048c98a0f6efc06afc68e0be76b5fbe8b23a308d3c03890b8d647152effc9ca2a09f73e67c966b8822212834212673ce391909ac1b4ca9c22ac210583810ac882d253cb04407a49452b2e042621221a594920821823099fc1586c604a65d6e2da16289152d084153de4c1ce932839bab73d30e4302872e5fc07ae372134b5b7ad069b55a2d1aa79cf26504f5e316141d776fb54c5e8eec3c881a39a1b5d3cbe436476f416186f0d84eafe8b4af1ea259d0dec1851f04a1402743bd03cd6196805e58e1f5c743bd1399a81f0f0545c9d181aaeb31acbbb9baa11eeaa1dee954efd01d541fdf990981cc936ec26468c883a8388b70b0019310a310810842601d6c00160d018628832068af92f04fd22ff767ff588beb115a71dd9db280b852807e35ad8ca3dcb4c5c4ee43d0428b085fe8dbbf75ed4c4878c1002ffc0a9a8fb84b957697339c5e466e1eb033840bffc3b94270e749c5d2156239c2de11a8a233720eaa2a1ed94280050b96200e64a1290e409287c1e9bb3c2149bbcb091c1a01bd2f6aa47fb4b310ee13d158a224d1f2b11653d5125f9878423e8d523fd6f24510be0c909a9afbb1961b8ce4403a618cd02e1731b61e333230148608cce5089cc9d832f68b0e3e2ebaf0a111f814c6ce2463cbd84d90b15fa8162ddc6be92088824f9b35a596244ed4efdf29a5f0af7f9d2450e55df65dac549ac4b3e2a5303d519bd0a2458b162d579a802549171742f8b109beac8d10cd43a935fd27a07f6054a856415a523fd306eaaa53b7673810b921f4d239a590decd795d7f79b2ebe109cd34a99fc908f5335d77db6148d4bf9f77eb90c4620713a66a6194f34a82d218e5bc28966914ab584629866159a66d1bc78d46a49ac154227db58d1bf568b4916238eeb71189546ba9e4e2f2f2020313c3059111a2a670828a0387c9044d2693a9965c60626e4478c36fdce81ba5928bcbcb0b0c4ccc8d1b26538e6b4aea5293ea1b3f986e4c381c070c4c4ccc8d1b3870984c3972e8d0b163c78d1c384c394c39749cfa9443c74966470a9d5d6106002cb4e0a15ce0d1a3c7d643cbb01e3d7a6c3aea0623733ac9ec484185ffaeb3768515666600c0020b2db4e07928940b2ef020f1e0c163c483070f1e3c78c8ec4861c78e1454f8ef3a0bbdad9d2315989dd9f9bfeb989979054e86a8020b2d78330480112c1851ddb6d082e7a1502ef0e841e303a3970f1f53fa88d07db40f1f3e5868c1f35028175c7081078f1eb2478f165af03c940b3c7ad0a0e49cd2615c30419927d5ad0b1c91be3d54b0525fa83406a18931c2b8bd20534475eb23150001c0d030d0d0d0f464a1a57604d0c44e53ea2f4e48b576f0f3217c1d05b043085d4c103d14fbb8ac89c7b46cda0183eaf282faf1d0ced0d0d05016cda1472882ee7403bc4cd47ccf347acdb75150cc8d989f4153b02a49146c23ffc6cbcf1903f3da283ee98b8c1e3e09be125237e1dec9dfad40d4dcf120889a2e7467cfefc4a8cdf1475f04fe8b55427af823ab840a0fc9d257c2308524ea07d52fbd074155a985588539d1f532ae1a9182b05041198c93cd3bdfb340d5280860f0c0abf028a8b7c0b55c9aa983e3a70e5425390255386c433171769b1ed3311c754d0451f349dd7cd9589ce5ded472a73371d4f4a02677ce6c0605050505ddb933fa2015044d79a9228a4934499fe32f5d5771b1429a329af34b9dd441fd3cc8a3b8cd97bae236e1361f5fa9122528ca6a742364481097c6c3863e83e80d44314ae97f24034c21dcdda1b7684d027ff83b3d146015cc04d826fe02d440b1d70fb91a78355f8b3fa80b80377e0ff6a633b88ce8232957bcaccfcfea212a7632399dcc41a5514606be3ff48f1f87a40fe66b0f5f4a7dcd1d0c5631f7847f869771e79c139226e9739c3422b19063c1e17090a036fc18db4ec76243afea9b60ec72523b5055faf93f02aa71554f9973d6e0ab6a5b0b44cdce594f1c08aabcca8c325f9b92cd06a276e55560155877ea8477be5b619c22a88a6fe241c5825671a7c6927d24a53404898afcacba055156b8379f347fd4cd975bd4cfabdc6e5d2b6ef3e1b8f3e7d756dcf9f3bd8a3fb7c324cec7c13393bad684c65544612da6ba4d216610f793b935f08a096ac70b2adff95feac6eb239f986f7c24442e50a2b8aa003db46125b2da38c2fdda89e6644b116df3c16c3d4666701b6825063789fbc9780aaa4ca6f89aa9b6a03244c123d0623fffea4e6e79307bf213cff51462d863cf2b2a4fa8ee04edce1188e215c686ecc4a81db12098213333d727b5bb9b075a4e0c53d2bf28d54107a8468d393ab80d5f2918041c85d99c2c4e90a81bbdd839295e161887e03e10830b4c8c1f18218740c500aa720835a057d890c17db97c850d297774f90a1b4a18418b9bec4c321d17449d7115fd7adcf8f165fe8377dac89e64f624c3bb83cf9d94ba0d845235339e4926422168d7f5542c503108e96bbfbd4eab590db400d6d095fa555335fdbbfdbc5a83c6f0bb9b7b98377b0cc3be31cf7e0713f54b5d8ca35c71ef9cf5f961c57d8e675d0f06395035ceea78a0726bda689d00d1d9d318994da5eb73520b600da5628c99fde0cbd3c8fa6ccdd1906d4fe9e8475d6454fc4c067a3f9f9b3d5b0fc69a5e4a0b0002e6e3a108bbcc651513ae818529a7f90f4fcb8fefe3a7d89dda9e6a80ef5f24beb44aac1225fed002271afa29e9a1dd81a8f927cdbb93664f0c900f5fd3ac0f0bfe0ff195a4a43d69f37f569b3d6996071ef9dbfc9fd5cf8acad0cb27fd977a5e916c0e0e2719fae989483ffdb6bc92160d2a27227de9f7a5f644447bfad4e2405fb35709159ef8a45772d2de2a89f674fd4923d9d365315b44c6f7374285f6c045d7536b011f08e143fbc3e8e147ab0344cd6738e1977d0ff05e492ef673aa21f28c3ebeb4cd8a3edba44ada096cdb411035e7d7a021834ef4e5a9066a79e49f78e25fb6ab448e75bf168aa27e9095e33a6a8450b975f97e70680a54f52a0668c40e75997250bfd8795abc15523cb1c216bb16b819cc6cb16301005bec00a095a07e94852d7633a4245ad862b74266a57e3176b6f542282b958b6e527f1b680713ea4763a782f6248a4381414d1cd58437c1638bdd8e2b3b29177d618b9d8c1604510d3482fa511f5bec4edd35907b4fdc6b92da62a7e3ceae9d74fdc45103a0976d2088f214aeb4295cc805811c6f95d413d032cd4308614321681042c834d43d18a78410324fe9ef90f414fecd5950598a00ca08a10cf54233cac0fae95fe1cd1ea39cd7d636878e085c18c39ecc21810bbf3df93206870bbf2b506fec16a31c07cc3108eb978fd3598860ea7672351216da404848a1ad0d40b91f674983d7b8bddd0b060927eef5f17a0ac4bd9c105da6a93a228b4d76a3e988a10bb3d48f7d84509531704be2800563a8e1a40652ca78c14a422c57c600ca957fd9082f74d03ae204373ebd62239ab1e2c65cf9b4827165cb881604910f85145bdbcc98429314dcf8728bfad53bd345577e943b50a144171f8001129240c51cc2054f5c90c78d50dc184d26d642064a6c37625f98da848171c42cc2093542965611683c2122cb101ae04887208a39d064060d40d1c0086628424803538c98818829401b116f6ad305e594725e39c38b39e7dc1202477114da84a3e496275cba90e58c222967248104356bc2fd6a3555982b50d0407d31a668c1779b1391f9e3c49dcf949a482e9f753a5c10051fcb16edf7e180848beecbe700affc972e076c2bba97d5b1a4c2fbc5e81c14a8327dcc8dff2a0e1badd501deecbf1b1c94dea875c441b9f061daa81f5774e18f9ec3c238d9c3e7cc701b9787cf157164b88d6ba5aebe465f7244b08ff2230dd84986f8d8c7c7e1e5a37cb12719220ef24b2f5febad748a5648e9e5cba7f44b5db51f0feea8e3a12f673fbad9af9ab6a2cb5a6f10420cc67252380a72562e8c10890a3f76f386b6606e6ae5b2501ac08c4a9d97e7cb37995e4e8c820f63fc669c1e1a4aa9fe1fe58860d76d756bea72300d7cd9e948d598dca66e9c05f5fbd44d0e8cd2f6d0d9f5cf201bb186eec052fd53eeeeee5f5cf525821604868a6a6aa3eae0bfa30815a3d79411fa476b819fab83ef284265efafd4abc0a1bf01f601ff45d32e3f64557740882ea264546a5ffe6b630cbb54aa948c6114fc43328e0a17c20ba1055282cbead800023f16b2018a0f3fe38244185a2be300c13832e3867037da8c4a85973929d9cbeb7229d910fa57f7f98df2e3d55bb48b034c03bfb92119957a5d08c4ae99465a23eec5ef537c5e65ef2ca86e84280650b2930cf179e2cf3dfd4cc3256a0ee318b98171e2c36f00ff507259f500154ca6528961b43e4c036b9ca480b88d3b61038cbae3dfe3957d270b1620687606b59f4f1e1f5a254a564aa215b2e255bf9351bb655ba8e3a2b2ad1d79a87340c6500ef291c02d5baeb4523cb2582b0821dcb265e55bb6a8608d1ca4c86732ae14fe359aebe118e0459ac96032c84083e4af792785452507ffa692833fbb3d11e9ebfdec3fdd16883aa51b5f23c9e719165c22e5b4532d7d7ada81d60451713eb5a79db9a24fbf57d4e12ba1d683a808df2f7b0351d1e1f717f16739e40eab10c10c6a53aa5258f2990196158b48cb8af6546415fbfbfbe10f90f084751b0a1ad30cd1a8db44d88d80160eb2dc1c97afb0c1ba4360528426975b4320e372d1e5161945b74504a13b4b77be469acf3ebda2fed12dad19a36234da229ee7d8bb5dd2abeca36522c40156d803f52a7b13f6d967ba41035a1d889ad9d78c7105d9a11f29fc48bf5f89126a7b6ac66022fafe45a875ab258916fad7f350eb4385c7bfffb2ed478022d03750901decb52c5a9f5e65dc8e0645a3cfd9688b5809a201f58abe6619a278a0f56122c40156f4817a757db44b7a757d0d1995fef5f1a137478fa31ddabbd5a27fd9d30eed55967daf32eb43c5065e3151424549665b6360581a0b44c167ff22bd62615da06e50e7e5161144440c0115911842689d9999bd2111124a184550462a0b8d67be54b4ff10de80c6348a20d283a296106d04418408c804d41aa24882c0d426178470c6d0d51982e8679ec0c48d975b432cb9dfa7588fb385c6333836f84acbae8ecbb0e6d0f12e36bbbd020f6a578710be91d9f5ecb8c745468ada4a670f59da9caf75bde209ffe32e43adf3558a21b7a062d6870a8ff6d9fb68f2a177d2c8e415e43c2baa7dbfd8d14752b677ae48af36ebf3c34ab3b36b2b3d05a2e0639d110aa9b568d4af592c0a37eb2c6d0438b6ff622ebffc41ff9b5c4b9bbd69cde2308dffe7c275fe991856997ef20fb9b10d86b33d7f896db4cc740056298027c09effd55120870ab00f7f78861ad79f70dbfb180ad75f07721bd75b88eb708b3567d4ecd93d6e48f6dab5c50ede03f00eaeeb34ca3921432e4ec80e8d456e988d8614512087f6e17f791a5a9e70fd75988debef5bb2e06b00ce0895c2fdeca400d115f7b2930254571ceb466b290bea47a9e6970d349ee12e8fa3e27677e20a4854f8adc58f85e4e7b88c3d76c73d2e6af721349ef99ca734b3ec295da59b7094f7138ef215a8807d785b7fbe5c109bebdbe569e116f5f3a12952aef721efc26da277e143dd41f01f541e5a87fee14a149181eebef19477468eb837c56de077fcfe243a40d5cc525d4d5a0a520a1da6aab8d7c409fecf8516f62a767de7f714f7fa79056d80ab695700aa2d5d8ad1ec2b01b48a95c8821b072251e5f54fa42083fab5909523f0fd752000a7e00d3318eef90d91bed31eb9611a2f2280d70057974d419415586ab75a0868470e2a7f771087304608234c615829478e48c1a85f4f99d21e1dbe13582ea0ae7b8eeb5fe93a659c78994bdcd59c91011e3a08104ce3ef4c7383f3fd9b4c371815f5bbbb3bfe8fec2b0dcd538c43baf33dc639ed29cae799ab537c25d7f34b5b43ff7c1e2554a2e5e1bf5e49ffbc94cc1d58d47e36991c06acb5e646a0ea9a454a8c1cb9809309b08a7610377e43a14d8b2660e4889306e2099742f1208a7d84d11c88da99445ad48f8b8cb8cd478f40c06dba280235bfe61bc7385ff64def97fd67d967178bf1bd0dc6a4c5987dcc3629a1d45ed3ec69085fcdd69c51a9f63f37a319ed7a80f7b25d8415282cb8b204145ba4b18a9e8a25d0e0ddfa87774b54e9efb90725848e43fc1901bca07aeec1a4b5a834ae9574410c15d1000000004314000020100a86c421b1602c1e95cbc2de0114000a8ba0447e529849a32008529842c610600c2080803100032033325b05e52e2b6ac05478bf273b1cc876a547901d81ba146452eef7bc0a948c6ed2dea62f4c9784d52eed030910924114fa59e0de1db03f7be46813a14b0483308478a33da0abdd88f57483bd0929767d894aa9d6a74997a1d1efdf20adb8322ff4b9f2db32957ea26f2727881446ec4a0366981f409e52a16cba27c834a97f45c2e8d2266ddfe35961756aafff73427e714d0be498bc34156c2712b34a8c19376272f61ccbb04846d1069abe353cffe41950d37bd97b971f906e73df893077e4af3278a08a15d69543ee8a40d25557e39c1447ae6f27d6fa8623ded381c5db8e2645ed5362123465a0da19a66d735cd0901b33250d21d3a40c601e869e3a9b7e400274800cf624a71aa248b5af2ddda3104e8262d332a7d4534f1d695510b5435dfecd623eec499ca60a19a64b673854e7e8b8351a8c1ecb49f3ec57b9cfcf6218b3142dc652067ee3018ee3f99e4bef8a6bd3149fd698085d9b26191563177429c4204ba735ae485996d66c534f02d8bea5a5f99ebf4df263bed1a7ea3db6ddcb779e5035886f68f9ad01e7e6a411591c11a285e9d386e9b95fe3849b3b131296689b60c7047fd6af67300e35afd4afdc8b1af0cc57d479aaa5bcc3b0495a6ebb1a4dee9fbba915a5e6b9a7b7a83e7ca942115f6a4c7636452c6cce9b2d3121d0873852869c1acea97138132297234ad9f71a7036ed93dce4a3d06876107bdddea8a2497b7a103032e60360b535ed44e2f434a3f286c8db3040a7724415e7855431fd9d2550691537de0b6b9ac00cf6060fe1dd1914837aff900d09e14cbf9b34ce17ad80f44f4cc1c7bfecd97eb4ccf1e734863287b6749e0a597b3217d375eea163f35075453223b0ad0463ef194305c5e3ae9d5d9bfb431a0b34fc277c567413af7ad0516f20f7526b81b41c14f0285746e9244f91818bdf417f1fd299aaa46dce45ec861de8b6ecc22c1f9bb604676a3429910131b10bb7fb15b3b27f806bcdd4dc9918ab7e5c3bcc653d35625686ca8a00dae6407f0e3abf8444079703b0dc69b0aebec2138ed0e46f218f23ed8fe9337ccc1d3174d3f22d25120b373ebfb55aaa7927d9e457a984be67937bd4400b158c16a7582a3285187737220644d1674744542e2491a3f12e3e2c208b0c3e6a31cdfdb8db67d6d421b0db3c3561a3deaa9b3300382a6375739025324c9f99e14007fa8255f8a775a6cd7b7ba1ed1430fd3e025ffae9914960d95dc21732ccbe6af91a7d969d7422103823d92b876a54989366723d29155b1b652a4d0713868417e99da2230a84b62b9ffa95df646bf920c6f5a5a209df264518f62e82fd04b877ec21c699d05a8fedd529a529a45777e211905de71d67dad532308ec29c450f9704cfef7205cc1d5b01fabdb8235f93c6b229c1b0ecd0316a9a37c2b468962deb93a00266bd779b973fb622e9455b014f10e126fde906222f62ed50787f916944f8b3c326ebb16f97c21ef00c3a881b683c196137cd1dd2181a9b61d00cade4d67256ab6c36811520dc8e8f598eac6b96bfa24807d0a526715456ad9dd5392e45d278fa52db44729ca53d27f8c746fdd628e7680b1ac639c0b4479ea1832dddffe9310f7cafcde26b1ce83ac0aba9fefde4f20bdd4a697e5ad76b4658292129e9aa3cf3a3c5e64808cd35d65d1ff1831043dfbf4e30da8f62e853e320e2ebaf6b4074bdadb306c5de1c6450baf472f59d1f579acf9cb60c940737e52f9529d9d54980e634f15b3732c56dc00204014a399d294e26a748e514f939650c25c9e4833f71bd3294c0602053a530d90abefd540f85f5e707211f476e865f51315c05ff6706376ac6b493cfbca1cd613bb8704c1c043003fc100f0b0c98d6ebde89a300ac9ff3cb4d9e179da4e307e3564725bfa5470c94d164049b5828ff385689b94f3f892c0f8a4de70594968634ea62f95b603392e10f934458131cc2829fb71b91d5ab7cc5ba8fdb090bcd6462d6d6b7112c209022d00c703b61ca3f70769d25dd7ec93c91aa1a3aa08b1fc2618dcf4bfcc7614dd6968549b6da939444e589d17260dca0d9defb984bd573771752bbdcbdeb245fa129d25aabf4e755a6d2ffe4a6070ead45120df5eb2ecee3b1116a37fd61d0bde355392efaed4f917cc8029f80aca4a44bab6f04824e7de31648a6a7f1bf33665d0fc8547a8d0cd6d5ce61e82974da717122f615cef89cda9cd04100a3f4fa2fc88e870b2d10d7a4ae535e15adaf48b6941a754789547fa6a793c16fcf49acc54866c396dd637c756f06d458caaf97b08192b89a957564ace6fff982c7a17a2e31c0e4393eaa2db87b007be308595948fcc286d4990731ef073d9cb7a3785dc08ee79f883b352a2f98d000978449cf4f78fd59966e09315f00af3fc7f9b408bbfd74fc03ae091c8e1ac83859f9efa1d1f78f1e10db9accba489de6a94231165a627439d5e81455eb98cfd404f86fe605e103c650133029087cbd2aef653dce4d82f41264787f5bc94d02006231e10dfb31802e9d52fb3d96277c0add8219480b9ec5f6b7a21d674f51b46d88d0354a802d758d6d430bdc4d9050da6b49b7f4b30ac0b552c13985651d3339aa0c309281050b4ac8cfea394236cc0da609e7e904b2159195e69959fe560b265d7682d212ed3065409136028c1381a0a6296e0b1c7c812f55d46b07b0fea6a3c346c3c451c03b24b260f8fef63aa97325c0246fd5ef1209533ef63d32cfcb5606d063cbed33632929786041d91eb23c1b6ce4f8538f013c0cd045ac3a21e793ff965ec171bd0a0537e42b9642b34c221238dac2a9bb72073ef45cf5f82a757abd14608ea9922b491ad78ba3bb9fc7405c6077e5c40193d65d9d5ff7e750ee19d2e361655c4e5dcdc4e5f09357e400891556e5ecb61c11823acb329a7ae7e864e5c6c8c23d75f74b9b5ab47844fd31d2aa0307b2dbee95a1d4c53cd2df7de0159c3283ed866c9232018ee686577dd0adadac3724742074a9a5f37a41fab171400a989cfd0c878270414f62927f78d20875e2028ce5acd0a66db899a666ba5aa361de96b9da3f26c5baa4cecb276a4e5b79978f005b3c25b44f3cb2edaca9b53fb08fc9e1084eab2d037ceca42956fec090a18a154383bed00d6a7d03ccde11317107e09c2351e99af5eea103af304365ec0f94b65a30f7d228c5bf72a36afd4c24c1efc99419f3a0c0fe5db33dd2358f60f78a87c52402324e1dac9722d94b5dc62f7543d5a09e03dc74cb3ddabe0228c297a720f54a740a663202a68d0e04d1367602598a391c92ff047c8d34f4446f95dc3bb60e0e5b86a49ce615ff5df72bb576a04f11d13b706aac6f23f4c81e540d31e5c0cbed861ed42e1b2a948a2111fe46a8535d1f168f9de235ca0c1807d8cc2dd870b0705520a0fc511a2fe5d442972e5d88a1ff98e7965ac31ca22d3ad1ab59b99b12703389017d6c1ccfe2df1abfa3da2c94e9e106b9bd9b64d112e9a703b389c8b3c9170ffd7ba022d5255ba58b040b37b066a79a934e97b8c14e99cc02c64d5de8051d715edc14114f4821039c4a7103750fab7d994471a32b9934018ed0c73b1637cbdbfa5ac8276e26179f5a8826018534ef1b93aaf04b00ea485c9d93accbeb24b6854fa6703077bfafdc655c67cc7565c94a39ce94922c5d64e5ba933bbdc1727df3818fda7d1cca32445f04abcf1be64a10f3d70a47026c02201fa35cec8c5692b88ea2ebcb178a51568d406e51b3a418c592a246fad460028ac0519be451405a592bdd065125d37818f459c1679adefb20963759cda88b6f52afdc628c9f1bdda3471d5b02344d492da4a48a83befa10ef1b8944782701b3c16360662ebbdaa6564130847ac848941251c5b41301c42a43d12e0c6f3defb328aaf8287fc051846758c866c5420f50325ce3a81b8c038780f6f81f11b83250b1ed750f0d2732f332abab1f854f780c34ec4af3db42b048ad3377828785e680d43e4da611d579e97de4b8b2c7c7f8e4caefea89e321b5fe868c617e68dc3ad178bacdac9c04a71a9f4f6e0005d1755752d04bb84a239b5ff2cd50865596899ca1cf3e5fe2238ad0d87e60f9316e150c8d873b08f7a08cc86576b2c79d5acc09b8adb4009c6528a54041815ad12a0042d1a7f5e3dda474554576152339e9ad1faf866494b9dadb37ced17c7c4d0ed7c8ada71d3202246697637015ce7c71d3bd6f1325abf119eaf2fef79e2c15c9fa7325a1a638fbd5028136684fc7e76092aa31c3f3550255fc22c9f1c89817236b743bfb573262098a462b22a4596de23e096f79956d744e9026aecdd18fe05af37ca753c6136534ab3de739f19054798923a4bedc1984f5e92e18a090ade04e7c8e8d41171e32d38e41514000bf47d3b57a52a07405eda8a9ae0bb5f2f329467fb89c10164176e2df92ac84c578c384f9bed282e0b07e3e5a46505e2d0f8e6ef0afda3d054e7e86908b1be913253285f1115b4e9931aa0f7c11823936d2cac2d05857e0b4bc0f558f2523a93f02dca963fb21a3eac080c54cda404946b72f727cc8fc6990d624b86f2d92ebc50d73eff95e6f3d6b9774a943e9c42f027669b6198a80fac4bcbb12b6df2fa333fa408dcbaef4016c3860b18274903728e23079b04d026968e5a3a07282190b052f0fcfc130e0d433a8eb485c318bf20e6d88ab6205521991bbe3adb22fe3c67eb88676c5fad8b9b3eb4a4fd405bdeade12df9fe364edc2114449d2620257ae4c46d534e2a41e5d09707e814995c550c7038d47c7249db13c408c308f782bf85f55d97f897e37a61e813f28e73824720d7517e9a17cd5320f8edb31ed5980ce787d3bc4c490b1067caf6c20448176731f37f323cc8a1457c04f7f26043a3f9d1b8d814e3c62b7c454b36d158da504addd16639b109602714fa48cbd1059970e4b7a2d4cd4e07ea37dfdf7373e1a18fc6a9d5b31497adb38cdf641a8837ae31fa397d79a303731f4ead154cc48aca45f0bffcd6d64684dd7dbaf5c7b87b6a04aaf049400d48c1a297bdf2621252653aa9e6638a24d39c06fbcf75ec2f87d72b15614142d422db44cfeeb8a15c73890a5b597664220c451cb0524579543bff334149951337c918623c4bd5a4b4f2327843ce48cfd78e24b716f18e2dea98361256ef990714f5db2f767dc5343ffb88ebe8f7861d07c9bbcdb843b66bc696174c421a27bb6e98b1b114fb515bec98854ac57d9040de57e57130816135731b67295d3923796e16aad075132da0947464dd314b4b2646d4e2ff48089b4fea90f0461d6b4cbfd8100e64523a02773ce0a3fab64e6955b2dc76ed4eb52e7231cb328c714bbe4ffc9caec215593343167eca95d80de326b113b0f1352add7b31d634103b7100469be7264a03e31a9e18a44eb0432510b6ebc53bad80323f531a8108c7accc67da2c573fce609ee4bd78cce03f17c6e24a31f37f2594b5d1ba0d4b573b1a4341635da765363f2840c748850c44c5abe535e0cafafa284cdd83facf9ea77ab4312dcfbe7079430c314c669efc11fa9730d3cafdb5a700bf5c1dc58443b76d2f1ef700f9935a57321f382e44e6b92c3b700ccfa43e6b9c4caafe48b19672062a126e26f3092168983a888cceb61799fdcf46b207075d13fdce31ac66a0905b6bc7fe3626d19a51b461b3a6887be4c55ef37f25a431daaedbdba49a0b14e9bc0ce4314c2dde4a2f7e8db506d6655a851ee2f2c350a78a5046b25dbfc326643802370ece24a4e445d7deb158c71a9bcbb02e6e180c00fb9eb3859c676d9bfb5e6415e93505454adaed082eb2810f364a619b37a69daad3431e0cc185d5fd28294b4e01ceda81d819f527f032771e97324cc8c94387aa6b67617ad4cfacf611eca215866d6355b14a6013cb2dea0c203d685bb19a6ee84517863e21c9c4ffbe2eada1ddad0430cffc8b49a6f118ebc3cf73bf846dca495129d3be32f45be73d2b126c500fd6e4fac65e5f9c7ae21d922970e43fdb2c32d507c99e60b2d67a5efcc1125302bf2dfc6217123bfe65005d9055ca9659c0fe162ac480015502b28d1fa26fa605e6a1c409096c70e0027cd9d214c8d5c82b8ebcb06cc80c05ad7e8e18cef5974e9f07032f889f8656e7a8187146f73911058b549f4d673f378e07be6dcf456db0f6168fd51fb2916d6081703634833e860f601737315c6ba830b14a3212b7e30d3b7d9b7dd7ab340037b2a9a60715e175acd103c6067dce1cb6e65127357410a9f6bc4dab2980c3bb30a911623d193d1be1162243e4447ad47455db0e3eb7e036f1ee08bc825ff2f43deed1791a4c9484525e3f4feeb73cf85a3cab289544c588f452e74beb10ab51bde1d8cdf162cbe246fd0a4958dd75713cccb3ccf6027f71144df0263c46fd652f25a15c81fec0739798a593dcdddd56db573a0aebc1556b45da8f826de5bcbf40b3760f6c8ae86c870c034fd72dc27333da0c62e04b858c1b0bc2e04896a7edb1bc9716f065f681e97724d7b653f8952b3ef9dab0fcdc95709064aa66041c19153ddb10183132ef5700c1068ec7669da674b56f3ee2111fb33e8d02ee44f8fa49353011cb0ecb865e52d0116480b9673d063f9ca93d33cc429259b33dc6ceac1d09e8bd113e80957871b327b9da37c9f1a6eb120b46ff416836669400c587eb62c3762c35744c22494c6c97c0447ca67b6e60c7ce7aa7444046e40849b290bc8b37208c395251a26e843977eb2fdf64a9cff1aad991be60d5a17d1f74248813c77863f37420065dc4886ff338bd69cdb46346e2d5107b014f6ab990e7169760cb9b9aa42a19f6428ec8fc640a8978b1564427dfae96f63602dd2646a14efb2b1bc191d364bb0c8ef68f1301de8e2edd98260a2a98034a2606dc383fb36e208524e19d799c18a913ab05ddce6e89915e29a26df4be867b87379d22af9b0b60d54a7799782ca38a1f390f5da577087def7a70b9b501729ca66a08e7770fa695aa0e0789415d7e6dc901ca6b75d769a52a86bb42d8de711fb3b83c4931f07638bccbc113c2b5de1126a45d0ef455427a22d79c5c22876cec885b88e80e40f6dbe3cb852057e0610bee421d5b02ff0f956a1a027ce331d581190187118a7988e594c16429df372c76704bd81951bcbc5e109fc56336b71d4caf960808092b06d3bf7301b4839954998e16f5924996e79cb5290c81b96a34d6e067f894cadafcbd2e2ca672cf96352e6064ab72cd3c7be6aaf35a9896b76ce81ec1afa927a30c2562bf7982aae4fde3ee893ae1b137d9c01cf19621788ceda0073592ea93b9dbcd4eb9f8697bd6716c6b3a9cb9efe994f1924f8306c34680f71042b0804f4dc0f600721efdea709803520bb08bea44d79e0aae25534d2e58ab3e564ed356b5a7c4bae03fb3e8683e0e507b37f7e9f1008ff0384017ea1ff45f2d46b725c10ac1b457e8c0dbc245d3b630eeaa26e7177c92c0d3b02c7a364e3ff33bb0db938f51de7e8e5933ad8ccb64613246d12899651599b2d35dda96e99a179bb4b15acb1a3508d1f7b556408691c5f169123abd9c66237443d96f9d4d148bf5c199cf283b5db45b0e7183e884c43865c7f3567d2f7e937198ef87a6266697e3daee88a68e2d374eb7b4636acc77b9e7a8f3cdb7a42fb43b1d531b2011d8aab383c5ed3def1059c01245a681efb10486e94570191376bdc20d663188519153dd063dfab66bbd551373c0672a3d9487d029634cabc5876413b4c7785c51e8ae70dc11f050e3b1a64d02a683094124bf966628b8e068390a815f7f79358729a59ce44697a9c11d2a43a5cf1572287d3835614391608cbefedccfcc730b17c489ce03c5d9954f2f7a24a11236a346feb1d3f3250204fa0eed4e8e8f45bc8e8ba9b10aaf9cb8c086137a75589328d3657bcd94055b85de9971b430508f1f824e7b8fd1e969caa6acc22aa23fb2e904044239d1779a0bccc0f6525acb21e760b624ffe5a645388865b7c5db599d6096723f1e0a11a8109a734ee1f21e84058bce70a939426bee69a1026111c802593595c890746b195c18cd42acf43986405f82389520df7eb85605b81c3d5b4516d771f22a6a89824fb651eba0a60b624c77ccd50a1249b6ad692183f25917c96e447cb60122b5b911c774692130347d8deddf74d9281a088b929047ffd07fddc94f6f59c8a249a7d0137f038bc0c7ddb825a6351636ab377a54217c148ea145fc2545f779b4181b8403fa22a92389685c9a8542682534c26bf4a1847962bfddd31fabba703c94619ad48e4c982d5e71643cef7e1259a7109d9e5a7d281a0ebc4347120a4244192985f3a5ca245e0f8ae86700ed946f00a02599e9bdd1d5dd3be72c471b0f3074a15461616ad8f8048508354b727220b2959104d84b80185b159302858c7a139d2b17d0a32c9594f4207ade5b51ca0e30eb67400cc8e85b50a5f28feef9b5be983bb277e40c09fa40520957205cbd7f3e993383b518d2eac89c107aa03299086ab82c94002590122d423526b08d0e6fdae4b4b2c7ed2b83da3428fcd8984030eb5bfa2a093a9203b6954ea25cc151d73c182564d38022c89a43f236e86995f82b923dc5ebdb0402826c969d42fca782b95fe01ed3379a50239446922317e67563af0033351bf28416815746cebc787ba436d66ba23a3d0308a2346ee384b94bb48ba865127928b9d220b48c97efdca93fae75e1433df6f9802bcd50becb760302e69177285054448c61ee5f76b9d570f9066220534a11d86deeb35f7ee18b9d82a82e06721c1dff1fe039cf0faad120edb8aeddaae051777bf11aa57be06d74615d0772cd1783234d8fdadb3743057f6422e6ad6125ed2292834d149219f63e05f7cf258f0c8f5e5148409116ab83d7f731cf02a553f81887b3903eb4fab00aeebeca8cd29366ecb3c91580ea15adb83aa02e02e07184df61ef5f15985e1ac6db9d976616ac85673fb471c2eab814a2d23c4f83549c1ce7c0d8dfbe67789fa2b0b09ddbb01ec673e709059306244e9db32a7cd0f4f9f2cd4658c68a1fdd8e6010e1d026bce66ab451045e18f861c0735c3a60d6f2bb220111e90223f5125166e66282b72db65c4f4f581eaaa7f2b79fa23e0a33bfb27f561346031fb0812a2a1c6155af99e406a80c33baaff903441c69d96f0a3904c56c7e35ea3901fe440d13c6716121fa25d7e49448a88157eba6f650d50e02ad89d0e8dc02ab765488e049a1e701afb1061de9b4390aa12428020f21bd9a0a23f1b73bcd8de32a4d076c4ed6d0edc60c52fbc1cb0c4cc7850f1d10755faed489edc0b925868d0981540afbe5ba5487bc28d6ded347b0d0a0137d4732e5cf996161685018e3c7d2b900330f2667e9a82bbd074b4ce64bb85e6f2f3e28785e6b0e2b99a4785c3bf403eca880bc787965b5079e63f5025e4c4b3cb3ca4d7dd53b4c30c0322b1370ce06fcf188aa477bdda064c09cd63ccca775558d45c9d127542f3b63134b80f82a53b75091b826dd0d446feaf9e97eafbdff7b7eabd33366b5310103c652141d439f577892f5d0eb154eecc3ade4eb8ad9c26eb314d8ea205e12d17077b752e21292bd69a9e3a5ba9b2a786956328eac0d35432dcab5b009d03d35f7a34fe39c42fa9e49d5763a734e8b0d3f9539d1bd0c3288bd6c26c4d6a7c202286ccf43145d921d206c7206234557603067703d32c5257bef912083ccfbaac09bb3846417adb8dd823a047e19bb001633d6591ff6565caea25db2121e10ab7a7b25ce6b28b05b821eb41b5d1ad819fe036fa53e8817df628b4b7681810fa8dd9f2eeb6197ee37f12dabe44791c2063ce607c874e79683fd441243d54144fd2a40475b772154dbb2be2330df1fff6db04ffb82c39c8bce50ccead992c56c6f09dc36197221b7fef7ea2bea65b7206237d32430578188a4ca203f7b1ba94b012d16bcb1485d754912f53749c8d760aecc70fd7f8a35b346a6efb530aca2d1a7bfafc3404170650429b07f09f72140ae078798680edd8071c8995d0cb9796a691907975b6ba8168d7e9973c287397dfa401e8ad47bade0eeab76fa47a102e707c147d960aa870f99f494c4143e571ccbdf32f79cf6134187b3170f5618ce44d5be290d31d9a19738319a00e66d451987c1acb5bf2445fb02b5771193aecdcb086e1281e6c15c8c13c7f8b9bddf936d8ba73c41335b3807f493a4e581e8b7f8b066c6405e0562d0f9737014be10faf2b3f36dd0fac95ff0022083e00425cb96bef9b6477dca946fe1466c367662aac4e83c2708b9ebc283e4de28d92316d62d335ea005fd531c96dc34d10e36af8e8b3d8b6a7912a30377c8ef8d0b7fa914b95ade0855ef8457a313ad35bac31ad48059abda2ffb4895598d1ebc2bf805627f193a4b2bc61f2280fb75aa655b0e427a14a0e79abd5ff2344c24478885eedfffd461216c5627c268089e8b5a16a0e5a41027543e0fa31480c212ec46cda9dd4797edad82c9fbf385825214d9331362824742a45970dfe90b3a21d9ea124ec478f86011689493cfec428f9e78477c42340c207ccfd9088861f9897815185850117b8fa94e9ca4b8684746816948d47485dd40708bba1c218e0da74801c05b190e0412c20eded8216d4871d6a4b869e65a1ae2462f1ff983a71b757c8c42a8dd375130c6a32121d22bda395dceadca9d2bbbf0677efb43fa0ded84bb0f40aba920317f0436b35f96c0d76ac9be17bb87886d4c745cfd416c4e1b10aa370ee30174a760ea796a2d265af60eae5f6a6245bf28a8c3be279d4a1781e7e1893158f133ebf1d0d7460817f465765a0e545c8d61b0d2547cc023e62ad2ee741798cdaa218bd753b6595c6076c8d1f0da89589ec7b07f3671d098a0479b70040fbf3437cbbb81b60433434f2795328a0e15f58aa42a61654e29332cfe10d6f25efc1b5d40c0520b94344d9e463a501b9393e6cec1fef15a55807dc181bd0b75faf9d0324c9c216ff41813fd617de51c93583ec0123982bf6c1749db84152357d2ea545087d48b89a033f4f54a8372d4ab56ce3b1ac450d81f69053ef372d379a1c7a0540ac7a24114711e08f85ead3870bd92d92db746df7cd7ba24bc6ac19eb8e1a08caffdeca19502f4c90337077113f211db1055bc0dde8fbd8d5be02aed29fc06962e91aac9dd3d8858374f40dc06db90f9a9e588e6f6fd90e20b9063e57183cb544e726ec5a94a02839308859f2cc3a609639647c80e81b0ce86376bb8b1085080f705295010f1d3e3912634f6b603d158acba7abf7a9f815e919988e16aa9020e927da69bd4adeea9afc705d5735e81e5adbf47643e88f9629a46b3971299bedbf2e05d1c0ec7d4e7c3219b256500df450d9042c2b2db7fbcaca9fbf282514d673b03514b03c706504d281c1fb9af02419aae94e1dae558341596867ad56a2e0d3a98169499b61e9c095be1ca01b09be153adc014935b2ad29b40ccb45f52c2aa089d9288f5409038acb2094078045267b96bc6596e498ff730a34f6a4fa6e2c3828de795c649a2866029e009382fec8a0d92e90da0cda6c2b84992ff75dc7be6b8e5f39be7c1ad5c4fd4ac5704bde5a2a0ed77edb3cc47779770ff44ac4f7be53e739bd0799a420f46217d1e6a9fcf876111c796708b2a508b37088aaa3975ca087a05ae7c259fcec9d83c3153d1f8f5eea9f17a8d6412950c45c04e91c8738793e8e21832d7a2a2b52755452dd17b53b1520d6868a7119f94b56ec3bf9ec27754e1f8ec30ee56eca4bdc4009a60f05d3618ebec78d266e4da293bbec28b05999fa9cbc8abf8c2a95634d1996c1745d8654e0580d41d48765eef94679790861f22f428872c64180283038dc0c741573e28686907140df7d5e299e6c5b8a2ef05ac1ffd1950ec858bf4780ccca2bdf06b42c20c51df415976a08fdb1dedb0fd7d021e3e1c4b2dcc5d5b5d77a24e671260a4237b29981e0a5c43558a1b56e636f97ff5169966a2ef2282a1ee075b6e00431a936e130e9a820a8d9ae34191240e7102eb753c8263f83afcfe1624b4065d3cdebf60c476c1b852155f6f8fcc3b2bafc64d9382d1cbd11d6e59c36f1272adc52ce743aa3c3d9c96b99be2f071e2704b32291bd74a80c2ca9ea9a26e25475cd658f864678efffe1ff456d9276370dc58315333e6096c1f3ffc30a1c4159a64c8591a4b997c24c3a32ce7c1bdfe84eaec3a07d0b7b6fbb8e374864cb49bfc3ade10d9babc5fafe88279ba5ddb805325d88d7bda0e4f229cf694e2a2187f894df0fe1465bfa997d8e10c66a35ccac58dedf0d3a0010b24e6a2c12867e83edcad13cf7663ce119bb8d48c0c977e3319fce73a6d3fb6e9b10a7fd9893e3d5d236c9cb03b0b0ed3680404075212903fbb664189ab5b9d3c5489349dd64a81dba502dffb2f9ffe2e171b36f98eabe52934f7d58d4a893da075e9cfb61d7f80d53668f764bbdbb2a4b0822df2df6beb583810601d36bc0c180e3683e3cbee52cb4ded0e4587c4e86d9237709c9e2c93c93e133136c4e3188bf25b8665368e489bd87c0e407faf38ed0f8f526d25d073aee60fd01071defb843bc933eaa99d4c1a5bff5a650ec5143ecd050a360f9e75cddb7f711fbba8ffbd2df4e509f0d2614d0ef85602262ee633725de6d102101ef6d8080c0fcbea500ea1fee0f981b53ffd6f77b735b2a5522b212d201f8a7fbd79081ce748a4f95779db0aef77eedc3afe6fba12fe1a6414c2f0ee5133726827bd1dd2b788f759cddf5b215878a2cb3aad2d420a6574352d733d389c02d19788e4bb9958bde5cb86dfcad33c24d195d56728b15614ea4a4553e290606bc8f0103ff3eef8b7dabbf1cdeb0db1273f37de761261bd966393628017534dccc4f3204588bfbc37760dc4a263944fc2b35a787acc4f6c6e912c458a08ce238ca2e104b6f8d7e7d43dc03bf26e3ace8ea7170e18a55256cd694ab3f32a3d838351ec47add1443284f26f0f13656efdeb73ebb211cb726b28c5f1c6519193212b8dbc8042873525d136da06596a3f4cfed931766ee502e6a1968b5ad5fae3e23f41aa4eb59ddbdaf57b75606eac5d2d8cc14adc5be57b75738d49248e2e611e8e5d88034b2aff775df9f7d36f132dc2cd385089ac4e61c331d30d995144211ff08eb37b85f8aba618c6d3102971f07c0dda6646de24e3f92fa323a029611f0b4f9a5ccd6e14c1429e4e10948eeae99f1b40e460a17e29cad00a11d88f1a4fe7055e0131a7b2091cebd4d2cf1e0c08264fe128cfa2f95a2910b37d4ac2c86ea313e45e02bd49226c3ca7c0e8e3573b788deb087f94337b62c134b12a3291de3d35848974f950ec4d77822c8d0fbacfb3f814104fae5c3c46bdf0907617a07deb27bafb0cf0e82f2a103c0daa6897e9e017d988b103842dd3c258b4b5e7a99f77ce3da4985507132212e56558983ea53e23c52ddb4fb149daf24cdee054df3e3f3863e40450f2ff1d892306f934d98e029fa929fbc799010883e7f5968d932bae83613f008043a3abee220b67315e0bb8c6a89941de6d4b90e1664d88cbbf4c9a78eabe9ee1809fcd8b87cd61e8caa50b663e6b308921fe509f29bde6deeabf577cff906883ec57eddca4d29d5bc4ac010ac5ce2a14ece0fb834e5e18b7b26ac6bd475119cf9f0421625071817b146c5a0e751b952fac022192f78050370ea198513055291067c37b37dc3b51042815482f41dd007a5b7c80fff57c941e1d7b1f01f0b196257e536541f3a29a0723e718a19a188aabe6a20d630a466cac365d1f95be9484035d100b48b29e141afa16df78d8e3f0f1c9e534489be19d2ee6389811e86207e601fe5afa1824d730b7665c0ba55958d68f7af6a7eab9ed802cbc32163a2418fef7276d2eed8210729d0829d63b1e5a5222f55dd2b392a8da58b34754f3606cc2b723a5a3ece8f6389baf21c95d91d4743e1666643ccc15969fd5141714b30a9a73d647f7dd4b4b6ea2380b9b2a33cfe202e2ce94f615782dfe4f4a61c0868be12d6debaf37318f32d3c59812542576e32ce58b4aab773f2d24ea282acd03fed7e727bb407b2da611f8c1f59ab4ac8cb515a1cd96a39871e5bf0cd7237665f2b6e7e3a805839e3bbf2aac6808e8b0434eea516d7255366e13754cd3cb6439b6dd03a5d1f62aec269ac1cf670d4bfcbc297d4418e823e8d63f2a256a142a31c327f3e6ee40368f465e07255484f8068a1a46f5401c78a17b8a4c0c39402de3cbd71cb294f91c5a3d578fbed0207a363d35a8bf7fd5ebee5f7f3f5737adcd4c7d390e04a24b87137b36a74dd91ec62d197570a677cb4bf4b626056b51ac28632302761c27f6e8f4814ba7f88ff15fabd97bb8a4f9872cacc1e970f12b118f235aabd43fa8d5a5fcd509abb03d46c26b300ad24488c9291aa43a086e0180947840f0f5775e8c9b4e5af33e4897857875e22c35de80b0d249c0faa929f73ab4541fffa518549d436de8caf339b1f3a6456b35eb199cb6a05c82fa9e96b09a68f930e635e204ee9038e280094a783348feba6158fd8b41e3f8c66ea32e071e066c0b9d048caeccf5be097367484985fc5a843d5b0f001cec072df05745d47957a68a1121b0a7f94ff3d732f865b7789400641ff9a545f2cff2a750601a287c880f6b7276af38c4c7582acf5f41461df3fd5d2295e864e97a1533bd725654f94291737eeab7629ba4750f9118e8b131fd0682a253097fd78fe4267b9662cd7acbeebc82318abb7886688a835b18fc85b4ec91ab0207a4afa13f6ad192c09808fa5ceda217b17b0c8d5e7e20ccc7088ded78678f66300a2a982ea80f0534290694b16ca53e9b8e389480e7c2e2d733dc9e8a2378b7a3157a0bae8233885003ad7ebbd501fc96aa7cfdc08fe688c06dd261dac840704b43542b9e5389422846d5d27d1950c6a40e800f03b07900fd9c6564cd312480bc880d428ba8fe4812475a41c3f301b4af8f19ac43d371687a11cda8fdc87d4868f43c9991e94a9b53c51fd67b82d559c24451933eb22e9dede2e0946d9c61cebf2bfe09d94eee6f6e410c595d2e770fab529b2a2f9607b9b2280e320d7d6b5ca1cd6dcf9850aa300c5714f4dfcb6320332552bb45667b9aaad4118faad946cb3bfa1c3daee34b99756c7eb681d116e418fc697e0eda2d872b2962701caba7942467c097f3bba2068860181e3f935d04292c19816a4d46bb1dbeccede72b1b00474b1de160731dbb3029763efaf1dc8c5c6a2ea43e15118896686563705eb7c364d9d800912f1447dbe0a5ffd5fd92234eeb1e312132d7f1c7cbc80065252137e7f842598d870d800fe2c540285449058c09ed2f1b7f5171e8ad80d18000caf9840ed78eef4e07914efc0b3829fac53f21ce40d17bbd8c2ffc9ace978909d5dc244d55fe03bdc9e1844696b4f4d801ae426b0ce8a86ad3e16ad7fb324039be10bd8162d933b09ae8d9520be283a500dc9353fe8898b70bde56d449fc091389ae4cbe96d2c5ca8aa791f838d40dcce19b56ef6c92d88d79b0c9e7ae87de26d47cb540487b80ec513c7793d904038891068f0cf1698819376fa8b352ce56adbec09293568bdb4e099a58c716ae617b69c78c731a7038166a43fca05c2eaef19caa4c425053f957a47826175372a125220fdd58ab6f0d02b12da8b56926e04ec4a8edfe9fed0321aadbdd501a94019c2bb96fdea3ba2645d1197841b2add2fc5d5c837b3334714ebfdd60ea9b6d021fe7fd468cf58edd8c6ed1a90222c9874f3de69a26b74d322bbc8942abdd1fa622934526a0746b69b2483032bc7a789fb33bc94d826ae63769222b50a0a67be7f804ed819eb556fb35bd260cb2857a50cef32164bc6c414a78a1504bf3bd08059109cf57e9611f55934e1179387266f1ec47477506e326f7dab99261d568f659379fbee0cf38ae81c0cf988e250466cd033a70de8dcfbefa0c58c2ef707448cf1aef0b7be9415b08e1df101fcbe2b49d1ba5e1c22db2983ed9aae7a6502af143a479cad1c3221750fe03ebc24057c111f856b36dcc3b01f127bc283c69a54ea4b423767d06d7a535f4c51d648eaaf655343005c03e4713733f39715467c129436c627b526306527dc8d965421ee4921310441ebcf07dcee60d92a87e0f3c11f1d436681e176f8e81a56f78b20e07608a114653800c8241194c14217bedb270d0a85e61eb993a29576cf77cdaa2c79a4c9b5026e1172d0a30a9c57bd3236a770190846d0be519b60d058300a18481c07cc0d342691179e2ca010aead2ea8dabbb103a2a14b3fc8aea0f9944f75cc2bc48cecbcd0d254f89fd473f2f19ba1c40cd0e2d26a1b6d98fc92e3d585aab68d2b38ff988f7a16c9064f9bc968137ed1c73452c009a228b8ac0d224352ca052617734cd24c610cb1492250854adcf81469a4701f8d0d02efc3e944dff76e86efeedb3d8c8e9124b42fe6c81a946841abc3490341ba4ddebc39dde83466e3918398f393d66f256664bd89cb8b57eb423e425035bcbb8486a8715445c80fcd6c8dbd335465fd4530abb41f6105525ab9d83cfe30324fece74f59123eee3fef4f25fb25a9189124b55256fabe9365ef435e16b48bb78e1b75fa6a0ee1e4c383514446b4d72e95c2e36555a3cad7001210e4fe7a67c36cd58cde12a657b1402ead77dcc32db34c1dd34a3628c9b518e5c2695c437d9d3e60792960a7ed673411feaa3cd07209dde7e6c0156283eef6dda6bb9aad4c57dd05c1792c6b607825ab0b47e4a9e0c267748328477920056abde478941f12b0a8a38fe9bb5f695b84b82e80f24a74f13e96b1a8e0b255022170b2eafe70d3ce53f65c9afc4fb8348b90598a9617b66591634b525657e3e24b08710c06c5969bfc6ce0d24ade764b4c2d857ef0db3e50b5196f1c5f1a827ceb5c7cfbce58ab28d37ab1dc9ef3a0c8ecf252b806c684fd4f75b18279bf812e51e4350b4069c9e2ae22dd8f181cad06258a8c4543d88f35bcb540c95e13347d560a0ab67a5a1c135ccc23c490c7fa3c3e934020ab6b3652fb1c6b5c819c514b582ad5a66c4194ee2a5f4edde7d824fb48e8371ca629667b84219cc30b0fff6759aac367349d83ef960ab6865acb24a6a7cc7eca1e8452012f01dd20d2b467ad84f033c7881c262fbdf4e60c071c112a9962102c8002d3aee0bf2378ca56f129da8bbc9c049330010936b92dc63e9f5a21b998630eb5882e2b8bd01517c0daaea8af9aa2b2e54dfb53ad7852c95c3b32a3a46cfb7cae9fd5340afb0171f63ae53744da451796bc30f3aba41f2bb99bcca0099fad28ab7a813f54677c639b4bc962b5a9b77b24e0852a29e4a0b720a926bae75202b9f2a44d811e7c823b77d8219fab97015e10d8e549aec085aa7927df32b558c02fc4db9c5c7b81f5f3d9a29663c3cdaac81f0f1c167405ef2e8e2abba60a463ddf80d1337c55d133038429ab6217a81908f5b9b9b23517b964a37fe090ef1efec62ea9bf2a14fc7e18ef3165dedd63d3f1bb2c64b925b6bbf51fadd04de5836e74ceb5cd57e2cc8a741b6d6e24145e159d1a852235366816b938492f085d98bedfa8a955d58c7cd73d9ae548a7e5ce6d0c8b7291548280e3263408800231299049872da1e42116a7bfb7afe14097301e2d0926116728eef9db938d209d888921b8aaa12993f6570e728081aeb50bda2c6ffb5fe9e9d98e33bc7df9d952a43e140d6a3b06e76220b769733d9b81bc6c2c7b74e81c33fa1b31e0dede5df22b7c189e1848f704dc7051eb83334187b2112a43bc0628f802356719b0186d1caf84238b2af6cf719e61a27f640b3ecb06d33611f929f6145050c43ef8718cb099ee9ce4ce008bdfaeac68b59ebf36024393e5cf679ed5271f8d53539eb40c316ede5009962324cb1fd7a8beefc1ed507d97174cd7e7cc5a839f133dc90d0fb171a8200c3fb463651dd033dab012b34415ed13a3afcfc25ddaa462d1420c6a86410be35776359938bf3ba99cd195eaaef4709754cd6000c7f0e0ab62f49a92117f2ba9c603ea143f24ddf45069b263db0fdfa2f09697ecdcb2da448f9d53e0c029e068e539b8c2dfaf76d382f9ea8d95304f57c5f0171224e85262052032ea7c2f1a0083bc4822480eb55e2e09b504a5a8bff361e3378c38fe8c20151cc774a8af9558cfcde866f858e6459fd3608b1e13db70ad36cce5298769b27a8bbece2c99dc99f91089a506e36e42d6baa71d396735f3cb2abb0b3d6250b83c0528c2b412ba00be3c95ce0c83e50ef944f05dcb454bbf7c60ab8ecc2ae452d0beb89693385bda25e7f87e19a0cade78ebc2ccc1416076092a42edc1b52ad8f1bfeea5ffc8f91a245cfba7bc607184bdfee0033361d118fe7371b061395de9c712bcc649b4a95dbec8a29ed3339f83d5418484730916d243f7a3237476e588dc8a5f6c72e2d4aa88b29159d5fef08291ef07444d588221a63af7992fac83ca35409e09c5bc23a72ad641221eaaa098c90cf6383dd0219c6fa8a6efc24cead13fe4999642619c61f7858b484264fa17ae8da2ad05e86f1a50b537f1fc47ed14579342f1db00b1b85d2cb9cb5b53590a0878cd7423866961ad5b776c6828fb819d78f5a2ff62792a53e8ce6d2ecc94a3a1cfa635b8bf9a5a3fb9e61888299662ae648047151c46e303264c517b5447c3a095479edcb64c65b76cc7c5d98b6d191797d9e9605b5b4606f379761fc669ecb196aa76c9165a8e80e2c021b36605729d9243c2b6f0419fb9ee1a905cf82adee5bf298d297156f1e6d943dc70a3fc40c0e07c59e9a9866f6b3119c7549b05bfc0c1bd3e652f4751b8d56cdd52060976b4db19fa827e895efb7698ecabbd038c7456e29de81e1e061f65075f4c8244b8d4c004943b266402deab8b2921e55c63c5fd751782cd0201c78070b68a5ae6a2b21d9fcfe3ec6ed896f4f3386c4365fefde1b6de95fd9c185238b206ef6e10ea6dbeb4e1f9ec4686d6c5270dbcdef08ed73bd33053e2f84df5ce6bbe5d4678c07df817f9e0f9a9baf629483209dfda20577bc5192c09c89238e8c98437e22a4b46692f003028a86f8fbd06f251d6ffc0e9207daa01de51c1563843888744a73d8b61a505fc576d26265e4c5b5d232b2308676189173f20d26127276e98d40b9a3ede0050b2d7c381b7c157555bb16cb36a9498630a6aea33564bb99bee57596f0a92de5f3da3f8801801161375ac220c96acd41537540fc6397098681da7fc45d7b1cb940959f229320d70ac517ead4c59077e46e9abc8acb386008f2474e8adfc9162cce5f7375c3e001e84f69498b4c7b67b64e62996e033e9ab04d7b439a04e8ede2510431b08729ece639c07ec3c9e5d7dc4ec82668e08e1b7f5d6489bd065e8fba125f505301951b0a985c7f66cff44cb49c7b62346c0301fad1a61c6db6f5b09ef16ecabb60a83a24398412f43843ca833f1f363f847155d5daa59c17728f8146b315d12ca8c238eed165b0fb01141b9bd65f0e6730a32b3b6aef82aeb4be9f14b993e7041b327fe9f6142ac7fd3654c271005873a6a41d4a404bfbe05b77c3d94abb1003e7a9daa5f6e52bbdba3eadc26aaa4fa43be755a6634d5cbbc6bcc87668b4245d8076af5defee1593d2e71e0ae0b269b18ce6051a6758669b4eb5a6276d280d7f870245c3b185c92166d43d6f026050714332d109fac8ffd3ea3ca511740b6d1d0e4d47ca048761a79946aaf5177c8335c3a622133500d192f412973a8160e464548a00e3261c8ab390fb2474ea18dd716bd9b062261e7e8f6e99249642e9aa618289a3fd9f6d1b925067b0580ef27587ef3fb9f23db0bd91b3c166d1be5e962b9320261cdb07a8f9df29fc698078a46b9c200ad9cfa94077537d8b1aba332f3c361bd0f8fed83762cec4838dfb2d861f48f1dc41636994641975336f0a5e667964951c40aa070a4812bf1fdbb01d8d0b73b37c3886837a06522a61d8f396e4509eeb0d238bfacf05ee7afec6b713a22be268a8944d7f0f0a44e3480e922bc0dadf40caa44542c5a2759e4331a975ab10f9094f1b56bf23cbf8d15386ff9d0c5c47c6e0cae4ffe5046c4da0ed542ebd3f8869fc872b1b71a866add2f050d7eab7d293eca5a86b072db2db7283091c218eb969220fd5a3f3d18253a23c0852fba7520593d00fbb7b03a783bbfacfea0b50c41d4549a5c3582f0299f0d5bfd0f8724f06fee71eaacc90724271b09b482a3ac4ab3f14b5c4b356a0b87bb83c55bb812130ac77fff131eed246bbb5575c355c241787232eb2c85c09079d01d20f1dc3f04f58df90becabe2ae8e4dcbb450b3e207d64be969a4fd136a2f8a051240f38a6f65210a14e3ce9eb575fb0774b838a8341fe90959a29a80a892f5e86a819bcc41120162f2248a13da26ef90785f240bd398039063e7d748fd124885cd07ba3536280ba47baff810a84a828e146b5219bfd08dd867ac61d67a3a85ae181f3be78e15d4eb74737bf7f79c168cd836de2c8bfb2e21d4fcb049bfcc594607c425de3ac4bb1459e07dc1e28f1e02e547007825fa1328034e7c2e18d03be8b713b4f21a24cd132e14ed7cce02537fcfe7696eb7b95b8ae96c0b6a8e003c9948517fb617be3ea21f5678336078c62c68b460a88541e235890a90b7282ebeac89c44b700d3f1513da84e1c9b8fa5819f5e6dc916acca2723db81fb1557659c8ccbe2b9e35b997347c4b5dd168d0ef4113a60c1e1216114d7d60585ad20f651c76abaf908d6da96c20017f26f6702ae133d2cc70bc65c43bf1e65f697d2e916007cc0c68de275055c71b0b4a35dfd21fb7d64633a04db23f49d20bc194fa4f72c4a5e08be701d0f325a0b1340e3ace5c979606571cfe042cffa80ca1eb922d362d1b968f8750f1b95d200c45e9ddf396b9f5563d7b47a1f1fe7db27d31bb6f415b9de9f32950ff0b443e35bb8d974d1fbe2029657c4334db586e8c440021b1119a8c87a3430e6e8d05978a21ffbb56347c176834fb1eec0da0a6807743e814e575f3a1173d6e11409af62e7ed7d160ea76499b3849dd551ba9ebab0a1e4f7e89da279e443c112569c9ef0848e9b88ff4b72ffef58c9eebbf0073fa80e4f38892c6fddf1e9ed68a44ec631e06fbc12cc8106d7ce3c89172f5fc37e65608550fbee699a7e788cb95e0fae5c8a36ac4f47a6207fd557fdaf3cf465ddf79da157652a67562f66683668990200c75138a4a210e439aa8a249e804423807e69890ac91c33febcbb36a947dd85a2106f22361e9d93bdf7a259a9c8f9b4e0818e432ebf4ff1290b31e282237ccf5cb17f42b8cc57b9e2d73db46c8d8175dcac384283f3d841c802af8ab43051b9c9ffac2148e8da667ca6a2b10ba1ff67ee4062bfc5fa66ae5d7a542dc197bd3bac25055683d719bbec07689aaa7099c3c00558745e7c1cfa938e05ceba3d5ee9cf2e0b7048750045011b9133d8d63ab2fcc076c41fa26bce3caabfcb5949af058951d9ac53c22c838d68a4221c28b3180d38f1c8b46f3cd4d9f3eac2b941dc718d40916f8311380703518ed721c1f042d7d18268f6e2239166001ad003339fbea7c3fe9c9a203a50e3433c8fe633879918975a8cc8a5774411bd959f69d573b791a2360bdb8c1ec23f7d5e0427b7e6780199c81530dc8d21c12f14a024f03e220a49b4204c88012c48397306736c16394d090c096fc0d75f5f1347e128077abdc0002016900d5fd6ff70e360b6ffcc1f2bf3c03b6d5e1496cc58e8ad0d6e162847c1eb282b5909620187e6800a636038096b4d4cd9f097b8d2903e531bf674e9fb159e34b1b1050521639f9d50f083fa5128c1ea11cff78f022f2b9c6729a1732e93258cab6f88502f6d7a222ca9ff41cb81703726a7f250193ce455ca70f3f918388562e19ae35e374d6aebd4763d226caa9bb28915577eafecde1ba5f28b47caeff0fa4ac42608066a6ecf646ea4231001d0386743d6462769f81f71967deba1117282c90958d42bc335215a451f3fda094e5c6a927a10c10312188944cf17a4706c05ed4e344c37d3f3e0b50e6f3abf3138f3b5e2401c84e10de31f09754988793241dbc580e656837604d156e3d5abd96dbd549e9d31c04b4ec33de7418904545294910ed2f60c70d3aaf74325f38e853b9a4beb41ee442ba49525fee31c2d4e4f2acd9913a7d584a13e6d793818b80202ed4571a626e7bc3e4e9fdcd3f44521049f63bad551b6c733f37545abb4dc07668a2f51e99f35d4338de4638588c64d0a17619c96f6920884441bf7d563c744681108fa96223862ae7bdc4dbf46eb1c4adaa31a40ec489ebed66921e3d51de1a31dc6d9aab594dcf94eedee1ec71ca4196edc8a7674ec33129bd56a616339bb502113e16c4e888b5ea4aba1c5520051dba1b438f691deacf598c3c9151c28df5961fb637feea239dd576582a441787b5f364c864fca9c4aa1679fef747ae3f488fc032921a30be9ec244585a2564eb7065fc6150d1b621b4026013e5abf5d057b53190f08bf10723373487a637355cecb13dfb6e29313157f248c62d3dc2308daf3f254f06f3f70238e671e7d9440d80e6a8da5ab67db447d51c519121fa412fa23d011afff5f8c5c0be0fab2b2da751d0d16adaa32cad97e7b753a7ba0111ce340114b38145c66af14b10f34d600a5782e15790f72b7abe4b214d040f843e9472679fdc9df40679c7da2177a6b9cbd087dac25433e9e7e549df68eda3221fea3f30d081914b7c9a204986c846db6ee2941661e60874f8b752afa147b6440c53965c1aa75d3dd457c9afd7dc687829e85c384efce6a6b0988789320372eddad3e957c20b7c03ea4e777219d0b636442f2477f060dd6385946d2df75bb47cf4f7afaeecf1e57b74ed179e9aa025a29e435fe1e7f7b7c3e8aad1e88c6d608bbb49bf0c07457f9820d8c9efde01ef6e8e72a8441f6f4b98e02c9a527ba270bb0f922788b11bfdf93fae5645dac0a6352bf39ef36729244a0245acf3ebedaa4089bef9a624ab56d18f03e602f773d8e6280ba3635f55db76e6a00fe2bf95e564bd954f1403dd3be0cd9ec81f185298d9ca704de1ea97f7694a973b1f5899bd67f12efe210fdc0a670cd4689cd43ed8e56383b01b84074205f22f47b8933f5954018ac8d98e61c6573372978f177938c1e446a80284e0c28d23103adfaff4b27d24329d1d685ad791b957dbfb0fdce9d208adeb927d9874aef367c0004c13ae0a86fc3fa18497c5fd8ef2d92efc176feb21ddddb02510e9888070ae8a517ddbc7742bee4b3a1a03a03caffdea17fb3c886de783adbd0750e388d207babb1e7de82bd80ce0bed9e949fae977dabbfe6614a4e881d0a51289672a5ead9a75dd32238660e11b59c81e48df6a45407582d593f8b3f34f79fe26aa040c5ce6849287c31384326c94edbb2744472929b3412b4b084b996b987afcb18c24b8ae4e0550b5c0eda1110111a011ea270c18852e70fbc38b29722e43fb0db79bd7736b1f0fc519e3ce6da2acb6f297bf610f9a7bdc60bc318ca762af290043af03e799962b1018f497b132476b87515dbebb7eb14cb1c28e587c58cbce3d33d66e9c90ed6b768795c83542308246582d4333971824364a40ec7c3990e73bc0b9f5d4ae59145dec0809fadc3e0160475703aeca8a9088530bb7c95d4aff4b6ed6c9d421240b7b815248c823f03397c85e2a41c29a94eb3eae0232027c3d82c9265dc480afa612fd78159eff068e81da3acd5a3aecc341431e9d86a610f2bb8e056707cb3b9f044aea4178e78bc7f0d062b51a77b41e6932f133d11075b4861ec78b9c2ed8994e2921597a07a488468ce35fa15ee4a5115a5197f62a66329a7aed8962d0e4fca1e4e3e7f92286fb70cc29f96fe414f43975e9f1379323f2cdabd545c5e6b6391afd1f2b30ea39c5affb62ee9f89ef15277f7dfa2ad35921f0b3d2b7b87df6922f8dc7c4524ed7bf955a554bd5ab27b7e761078daed1dc56bff2b50643c44ee6a54dfb705469fcc90078438e330365e89996268fa47d9792841c7b09f9df2ec14074af02cb26b708c85943cd94364167e06231e4ba6c31e46213787ccb67e6fe47cc5e3b6bdae95d6741660898ca966bfdc8b434b673385ee702dc321c93e04563cf5cf29e95e190411f7f1519b0a3ce6339759d0753b56028f702dd83be8c7db0893ab19dd503967060607b7425838271edb2cd2dc74dc530760483186771ffd0c9bec7bb086c4f420bed030b5424c1f781f3f9582156f54cd54a8eea0371bf2a39fbb647a9be623314c706390d2f1cf636b883c543c08ac7ba16aa77ad9a4667b93cbd15769a0cea2c7e92d600cce287f8b73c11497ae1f04b54a482e9a7573cf022c468a2a8b5b02a714cff14ac4c7bbf127c0fcfd47f23f367226806faaf7682b73b178e13429154edb5e544c88fe63f4305ff4baf5e7b95d0e53c4885053be32053ae00db3f4f052d4a30b05486a1dba7c1ae2aab3bf215078dc9a632442f09d8b08e9b7f5106eb72db85f72d7c493624505abd09c32e6cd49689cd0273510ff736057bb1d80471be62c7fc1507c11ffe57ee1147eb8d3e2cc2dfb8a3b6006d9fdf8bf67270535d3ea01fbc055c7c3640ffdce3a9cf878b0b057517d7fa73ce7f752a731676979663b6321f93e6c32cb615ef3c3b2892e16a83b1dc250f8902d28ff9163647a1b2531d843be84368ddd9ae942aa1e1a912462172cca85e91c173703a90ac2d0a65266a1828639a47313bc239eabe79412b44e96743a004299cc418c7a733d5c1d5940475d0898c96274632f5811cdcefdf03ec5b1b852b89a350eee2b0eba0ba749e872bcee48b8991781ed4cc5cdc4c5c7942ff8429f3cb818307b3e9e359cd3dadcc8dbcb3e0de0dc05b0bb814d065ceda06f2d07149510131107202279bdc7e3bd2677d51211f5865da3c003ba4948e5160db9404d879ef3d19f6b420c1613f10a2dd068d0424b18b7dcc36535aebf215aba4ec8246fb4c833dce17c83a06d4a1d00960bb1c51af5d1c57e5fe237a8d665197b2e42c956f8a1b262871ca2e791d1a93918ac3450284f2b143197a36e303a9bf624a6d445384457a4cd8bcbecc86e83af04a31bc05723f1e6cc7728360f2905e2586fe02952dc6489e33859abb869df56b6d6a46ed518a7bc9d221e58ee918444c0168e74ba8ea96415cd1390a56837a2b41a6a975af0c830bfca70a4f25c644a5c83016fc3b945f40b67c40d4328fba9aa4e6b26acfb27bc3c9ebcd8efa820d133cfb260101ea5b83ae634200bec90366eab172bb63cf01838b26d2004aee5829c1fcc1269863bf9ac7836d1f74f9e9ec631a9513d2012752c610043966be300618ed5aaae82b05e2ab33c1e0297fec247169bce5b62ffac3614721f4818abd7943eb6e6064fe2eddaf09c2f31572e26ae93bb008b7ae3518346548de1db3676bacd119f3c2d2c9d35e3794bc0d95d788b785627f69534b48c82b073d39ec9621821f0221cfb998d3fd1329e0586fa1909553da42c83af706365a35db5cffaad4e830bb5c71f77ce9920a4c7029a406f6bc022fd1a3faf7784e6987b8927d4e5e382254cb38320fc2b8f2a7491b29a5f33eca1e84fc073936b6b53356a808934396c738ba00034b8786e6a8868512d614efe9b33c8682ae3e56efc4832a1b4cdc178b0f865e3eba0e0721ce80209ee56f076ea7b622c39981a0243e5cd7e378d8832637f13891a76ab7fe9d8a5774e5bae530dc96bb60eb81ca340177e51a562a3657b6d51286eaf050dffa9845889ec3a9bed78fae9c0dca40e52b31e04cd752aa97c6779f0990afc40e679fa3d10ede239c3203bf17464b0366172fcc7647c72ac7097f79a822194c0e52fec351e9664096ab892be59ef697786a5d9e1d91c768037d13b4a289767bd53f241c499a13f13baed4b7a09f44ae5b8f2d4c74f1e259f9fcfb987e33772e1f0424e9d0470486df547e10617e8a08f1fdc641a83eb4aedbff2a2f9f4aadf9f6d1503719b862958c42b4f1218674b47929b136aaf84cff9de88cd10954e2ef9481715f941bc38a8db262635971e359a3b1acdd6856d148d63696151bcdaa1bc39a8d67e546b0cac659531b07b152091549c06cac0213b78e07aef383d4f5e0753e409d1e5cd783d6f9c07572d0ba1fbc0e7cc05be707af7bf8ecd479e30e1231514c69cada36dbfd902c8f19a6143d8bea66a014fd10a01debdd63e222e0f2b33930c137ba7be763440d00c7b83d756c89cc02a6060450c696804245d50ea43794cf10b03db03f21ea3c7a1b122e464cadf9ff1400fdbcdf1c9e4f7f043b4da142a898c56af9454af79d857782f7636e58b4c8b5d41536c325002a5be2f4f864bfccf4ca293b152b5c1a72cc1344e64996d167ff1cd4d774134e2176a01ea4f9f678f3e5ccbd83e3343782d9f1c87dd193828aca06ad874e712f65d9629f929ca9d8fbb16ef6b4d4cf2b12e84e91ba20281cc94adfe7db2bbd21509e6e482e004853fbe03f5a0e422173e95133eaca3d979fa0336f0477d478651a9a9011f48aa8b053e1a00a1cb6cade011b03225cee9cc0227675e31d3e16e0fa102c2568f577d0a1613cc4643c24d0417a7e0b52f1d038a361f0722c10271326eebcde6236144bd1f5518c3dea46eedc3869e90942de91ca9bc2ed7ff2428c6e79380a3b1abfeae5dc9a358887f90cb10188e164e4148d8b97594a01b85f6815e2a483f19577335e4d91bf6f784e9e0ed0d97dad7bcd7f0ea53afb6be6717f8e79b6e86161245a8be2811a339dfcac83db3d8e4720baff9e0d5936b79c75713ce2c68b5ef389cfe8fd9d683dc112fbfeb2fa5415c74e265e4e9fee8663093eb4b48bd4f681800a6d6191d17351c52af7ffc8d2164001a9c4b20d9be4781ccfcb0a8ef2a54725d3b9e00568bc4a818cd38dd5005abf2ddc3ea2b79378aa0f48424ad9e0e7a09c8064d2a20c111afa95d31ba7113aaccc9067e6c8549d640dd307d79c53727e6e1ba9b854a3204901ec76db04eee47e17540c092c4eb500ad60e228b8a0c6d5c8c0ee9b59526b2128e1c33253624181c06b51f0a09fad74efdba1c2121eea0239cc40e9130028bedc45ec61d975ec288fd0e7d2eb5af9274a0d6f91227d9b1ccab9d0154845b639b524ee5b5a91b2eaedfba29c82af83a616b9d31e6d8efc9dfa4d2513e8ded4da8b17248e2e08687ba6189f3a96ad847a26de7f3659b89c77fb972868e1fb547e080edb9c42edbbec1f422f7d46eab45d1ab5713b516ad95a22875906ee8c2857806c4ee33823fefcd92df0cb8658ebd950de6b58be2a1cf4fe9aa827f06622307924c1bb4b1b3b59e7b8d5ddfec7322387820884cfd860174813567db4bd4027a91a49a7801504782f37806426f0e19f74a4f59c2004627c1df0ee635b2fa6b20f3a82dd761ebad1272e58cb1d82f7965c320a0306b3d767ece37077d5cbba293078d32f357f0eb0b78ed9cdcd921b5346ed56fbc43e18918e8c772875ac17d3b30658a5c90c0621b22d2e4ae82b8648c146bcf836673f5eea9ba5896051416d84268f7c3a5f941d615f3107d763a26d914c1b6f04e59fd8b3e88967ad9f94fd6f455cb8b571ef473f5ac9a1e44b760e4f1ff15ad2ade6ee0104a53a98af813119d4aac13624fd6a466195bf6505f6941f25d7730bcc2e08bd0c15343665c2fb2fbcefedeb848994b6b0a927819873583a27c61a18cf353aadd06d2426825469a1b4c5fa3851e66d82aaa6783efd75b88738e2ca7156e209f8d75355572d5a65dcc617122f112493ed94f263033ca4e908ae38046c3d8f2bcce0ff1ae2c1b26db62f4db4e2dfe08cfde841dfd2ded1a96b6c15ba2ddd00ec5f49d6ae60496bb8b36806469ed07a2391d2d692bf3bafe08aaa1b2a5053eddd499dcdc9b323ce93997db5123135a8bde95285883f3e3d0c5ed3856a52fb79ef0cdd06914d52fc9c1c00bfc16a9e9248b2ee7f85ef7a1c1775a02010043139f828239b722178474a97876c431302dd573bc85f357eedbe6d71a89c2d07ff155c62688582d18cd591e351b3faa04b17b142f16ade4a93bc6c1f01c2b542baa8d92b59e11a88d34d0b6f47a7665e9174f7bce57e62ef90f7c939f2a87266f01b400788defaffd5aa46631ef391bcfa234ed8179a9a4b8a74d19bfbfb87a122abee14fc047e65700e2a3c0c3c3185edcbe20c65318278bc1b90824ab1de9a32e1f805afb2c00c0a156c5fed2dc98601534e145903518c896071d02e65a9f7e9453e39d1914a78d11dc2ff8390272e0225a32f75dfc239f938ca5ca29e568e99ab18a301071436ed07f672e29ea893fc1aa78368964a99b69a4820fa1ecd2b5e983c4b1685dce83d01b301c3a146ba672a763dcaacc96bc7be4ee0d54dbb35bb0c4a23f5be655dbc8e61ab15f9cce82e750673df208d78ac87fe3a149802951309f5e7b247ac1eae45d263e8905bba61a51ab771d43c2d23ffc00bb0a4fe9a8b39083b31dae12da68c408b61a00328687fa847cd8afb8eacd465fbf054acb2c674c2c244ad50b4af5afc9c1f666eb836545297a7060bfa7da8bb58300e76e4d31e5224361e4b5e45ea3b3ea172586f46a95901462ee15ba77bbcaa867aebb39b656523f6ddeaa9b6a9dcff8c12433380fa617996c1774ee499986c7e6b141e37f1d095f2e102cbdc4b06b655d5e03de7990250d3f478879ed20eaf74d9285be921c1f3472befd87120eb9a968e5c6c3bb772ec329a369376795351a89aa0d294f16eebf4bb50418448a7156dc385a5d5f5f8abdbea74f13ab2681ad49d4a7bb4d4d406c0f2fc3f0993b498cefd1991b1f75c0858f96c2e49d0124aa0e2ddbfd5b0c5995db19e23d02a222db6978cd045304c266c623fb5e4311df671f70dbacc03fa16ba58007701f6374fce0ca1d8772065779e287442a30ee2bad4e088c503d85d2a4e71d2d666d170dfeaa851a38188c399344ff04fc168f902e9bb9237e159d3b48b5c5f609f147826967f05526b550f06d5c2cdb200126a350ea6b54c84bb185876399602e85fe9a3124f04dedc454e2e8ffdac819505c6d02ac0949ef4f739ddc36733a6f7520846d4dd4aa8e618977a2343b2253d0f7e617bddc79f12b0404b6f6ff839bfcb00498ba49afc0b3f7c4001da0e7556418c0bb4d5cb3771c88573a6a4c8457abfeccec09215eea152c4831c1a024f20897660fad3ea0d2f678e9dd897f73fe8ce398babf8a87a00650a148de1e07dd59ca1433c15ce95cc18e65dd55a26f0776e51225ab8584abf80752f44ee6e67c046a10e37360e196fede0fe1038b5d2b6d1243d8a5a6a5b8168deeb0204172cd553ff26861d5187dd0b1848a192f7efc1e73453ba348e7f788f76449696fba56f674bf9d59818f58251325a4c5f10aa2812544c2fc806a14b370b9c446abf86adc2c98dd83ece888a78a8ec7407895cdd33d8cea1b9cae92e7f9f4e8fec81232064bb7ad8c37f6258d6dfd0a760ea4f4a695d734fb841b760789b1ad3c8e7934e5b36cca5bdd53dfacd927a3abad36fd7122722d0c614e4d282b711281a1ea444275157265c6b7714f6276876c5d34c8ff3ee5243f800eef3a1132cd46067b39caffaea48409536fdf4b09acc148472185d6ce77904be2a7f25e24f500527b43beb0f0efa1a4bfacc3c92bfc63a8b3f9c06759b2fca2297b65984dfd4ea47c62db8a08395a99193686375e2f4ab81257828e1069e95f4fa12261ae6dfe55896bf1c4321eb401a6945c98e234b312fddbc527e367ec353fa9facefaa4af46d8d4eb4376dcb97dbb74f90efdac7656938555eb49b47ee78eb81456501ca11d6df07c29f19acf71c75d9868d3f6a346642aee4d1701963eefec5ca446370d11d7eccdc098220779e359418cde4527a0115c1b0b9d3d22800da87bca60184d04a21ca40015b01a21813115420377200e3284805600befbbf0506e61c9408ecac7873d75c36d222463fed21a0935694e159c31293b6adac5e28375b6e8d8f8ddfdd317467251da698b8429c019584e7e1e3c7b62b590d1ef9396658ea5ce3080697b2d0352da18366454938e8e7b6967489d75e70628bf7e02cc134956693a4e575156549ba2d2607108bb34fe78186fe4723941d11132a799e7b6a6e3042dbd6070a80ee9d048e7ddaf19ac4bccc37984909e4801772b7cd1491def5bbbe905e4424bd8e6bcc19a2d7e7cedb793d75efdf173b0b17ab4944fd7cd7143fb786b67a3d1cf298177c0cb21e82c95fd0ed039786c5240eb9f2b504e5262eac612f9872fd781eab41004a72efe87ea9dd45fdc17085569afdae8fa4fdd1cecb5e8685b544831171aa89cdfe478ecf517f6e464fde1987cb019fa3ef4e83f6a9909f7f879723085aea16a374a2f0ffac47c5980711b12f8676fea2e752ae33252f626df3419e7e358a62054335d447329bc43860836af0f8b7154d2c5dc0ad05d2af46092d0959208cdb6d5bd24554fb94bc2a9dc4960d70bdd673d6e03d6d1d4964735fec078158822b7cfe44e99ff5e8249854b11a047c18971a49cce6b061069b02de621dd49060e9d8ef2749dfbc1a3d10ae775dc7d9ace45612950fff995d29b26de8c6bf1196d4bb52e9126201d4878155131f45d15c2d58207387d6fa28ab1772a5aed866f4bb46bc1f16894589191d423379b27b37a5ab4f389a49a72f728264c92eefd8c04afa85e8d1ceca4eebd7a1664b48ba68ae99cf01ad4b861cc533b83bf6d4d679bf2e113030fb2be0079832fcd115a8324bd1a7fc6a9b45723520371f3595b21c95c067040465a69e7387bf96265d710d6cdb4e089e35add86284b09d46b6f3a5d4f7c7aca86ec6913dac00b17b00975ad8b34c07a2deba83bd630542f280b22d768e9fcf7c2a4a3a8b86da35da3e3836a0b71281fb687de0e6abb54440b77b599e58f4eb163433985b5543dc9dd784d428a667a5787a3f0a11c931011e137c607dc3fa9f04ad95f6279ba63957cd576add37bb27cc52c0c127e25f7ad67ea4db2bd43fa52ac3582e159d726c0d432201ddee8e36eee44a53ffac797a95d683a9b42488f2c1896a773af7aed21c287b678045a99f16f724b3dcbbed1ea075726b40069a31a8bccf178e12cdb11dc3aa47f494ec00015095e3b0c586b79c46f0ad7ce1dc362f518d8ec4c628270417c565b6d3f996acb7fbfad6f81739681280f7d3f2e1ab93fad83c74e070dc4e099c6db654e9a0f7811ffbac96e853990481c833092b788cc624b0ecc0557a529b771573f664216a4462a5af7e7fe9f904ea42112e75f4fbab958a2439ae0b624141d1eb5a4e5cee7a38934fc4b9483c8a1adbe2bb51933a21adc42b1b0245cb42825fb5c6000574f7d0f86d41695d05aec3f6308fbd3b3de47f17e23446f2914cb83c462437a373c8522be3422a96532bb254e3fb80dc74cfa5f5af7075db85e8868f85b72e5a9c114e8bcc5af3d9680992312a0cb90fef5e29c0faa58fc72c973c56e8e24169171399cee3359587e7ca71a225d0932131587174f4419ad995d433e24abb8b156eeb38de9515448ca6a820aa9beca337b53cd666b6503e5b01b08925dae3d91ed9f878895ec6097885c2e795acb11913d93a80ad2ac4e2fa2a3ca209197db4887a4909664feddd79f97454ed22c4a02d9ce0181c4d466acb828b794773819e80f5837f6fb957202ab6410559a32a97643e40b927981b7578af8f4799f19178353ed0a3b41067743e46ce76ce3befb6bee86c7d80f32595c76e7ea33d4ec87d8b19c6fa9b1a2d3f69858db9490e2400ccb71d7fa66cff7c1e669711abb1bdfde74c14fac9d04a126caf9bb5ab5a84110d5ae16007d46b15fcdb46c0046a1cd50048dbed5effe502b5858fce71fb8d55686e6e59ae21f0477f687e6f33a4df7e6805a1e4176049bc7f297544ea8aa4915b5a6730e8b2c3b2d200ff0b2054baa6d26cb46cf87ddae15aaab8cadd5c1e2d835adc7c0fcd81e42a6a72698d10d889395e4d6deba38a0bc77ff9442122033e0e247bfdb225b825f2e1891dc57b958e57a83b61083da7d1829d235e5983cdb253ae86b32bc4998c9b00a664e471163d80cd352c8066528ff34c1943a4a07322bc8176b3a9946988d3f494fe5769b9d97ebb447a4b5f60ca80073ddb6e324b8fc73c959131f1b5823bfbb85c27c4ec7a25e4f846b7e09afc532386c77ef36a5ec108e9a999c0c768acb0b653be3451f989dc2b83e0dff812bb86fcdd4050be19bf70b5ea9553e10b134f642f1b6ef2fc1ef0aae8dd16782ccec29588fb37b4fcc3c58b6ca06a948dcd88198ded0ad67cb45410e06554f9856e51880f1911bf3abe0c4c27663c7f8480754587990f23e01ff25920c8996177d652a2b8900a8c28d61f7ec89caadbd843d1ba7792b878a7dd119ecf37845ec9267988c0f3947af2ff6e118355ec3aa62bf6878c5bb41015b3491e361c151fe2bd4ba6162b93872f4cbacc439507509a418f1fd05a9aa2e77d5fecab00554874638061349471f2a0b9bf4058dadf5fdc8aa236e62641a90c2e5ee315c377f9f52d83811a97721bda5ea6a326d397cdbd17be3a81e4371ab8e59dcadbbc9ac94da1c50e4b605d5431338ce34ed9aefe851cf15f8e029c702dc1ba355f5deb0068dba91eb2c3054b42ded2ac2ba15bdb3baa42259ee1cc50844f020022deb1c72c3e7233dae06c19eb4dc0623c3b9fc9b05e6c4cb1f4cdaa33bfd033fd46904275c5bb873064f6cee7a422bc8569699f39adb506341c6f0fee328f35d9a966e9320e4ecdecb3045ad2ae246714b103951e55031a610bd89be241bd8921cec4307d29da4e6e03e89087a28d7af8a104ec1c0795db59ed657c459ad73a005ef9759977a213b95ccf20959895148d969c988825a75e0da30e990573797d1a16adbc6372ba1ea149dd10078a1cf817db91b32639e9b7e4e0d3d8080818c1dc44ac37572aa5308ebbbb9f804c85136290c71bbb7c17123bd4e8c8922294f4a664ab15241ca9dbc1fb0e06850c7d4208f48d1b3b3baef8bc2a6cab91ee60a7a8e9424968532d1af40e6c872afcc7ab75fc08e27784f13dd4f729502566a138a723137cf026ccf275cbd4c05bd7f5ec14e24ea7fc0679e5acaa1d7b01a783325b9b1c5cdc12e30045a1c4a8b5328376b252d93c700544bf93c224d4a29661e074e05b80c997ccc3f869b27287a575ff300205abf720dda05442179b15cc62f4c1e7099b664b095743ac5d4e0953298ff7526950c1a3c728750fb93a77abf94e66defd6d214ae0bdb7a0fd7085bfb850bee5407f3c9dc1a973cd8a0607edc5e042939c59c49009bd84e2e5886427c7b26864e1e51e53b7a2be111be3855370a067c22f7a65af10c5c7307db899944755676ea0fc52a3511c8c302bf6c2342369bef5b265b11fec35b850233673cd70a0491b91a777a3ef3d634db61532158695964da4958c9b01b66e08b0dd44eb26c744535939c9865445c80b2f6421efe5d75299afd016c8bc60aa1783bfc0a356ac17477b2a85da4622d3cbbd496feb5089a7ec7b81db171f97277dc24ba4fd3fc464d603c1f49ec032d08e742accd7542671d5914c163af8208d1aabc614d264623ee8ca4c44359921a77f9ba92928d607815b8c6461f983db426d1d0616b5b333ae1dcd392977ecf181d5258d5550d4b6b39bfdf14596b19bb7b6d77283fcae385eb5f1e2363cd66987f2774e6a3daa64230328d1a8ad6a8accc6095110dc05d4a52b4cf7d8d6aa7e849c51ba043e0a823f57295f66caf769555c3e24df49850f388912941b94648012d5be687e576d3f5bb586c56654f748b48b26195e3f52f18088fb0beb82affb87d7aa0df53fa49ca086edaa16b4614b543d3d6652bfec05f654725d0b9124c03d278efbee4e6ecb80875e511a58ecdfd7128ce61744963c6e8f07ac783cea320dadf749066dbcc391fac9a9bdb651ff26838c9747b7cd4876ee717610ee7865ffb4f6cc853bbb5f6db5fc7f0b89d4af15500f2db06518de6939a10af925da60cd3b235f128bd1aab5e070d1b7643cc7e2b885be673d3c39ef359c6bac70c3104a3b5f03f3121537c78fd7a8aa6a4cb3fa77af704301b0c87f2fa5224f87711772e62e2e9747e52b7edbed1d8849e03facdde91592090ba9216032cb8aa12f76621d24bcbe42f40247e91562ede15ca60e0e73cf36e34eeec7d0b972db486382914e00c06b540a96a4a1a15754213f8e9aeafbf78ae17fca807ffbad584ce691ddd116db74608a126b4b2bb7b07280925093009878f64c89faf29e986c70870a36f874d293c75f83515bdc9e1e9000e7f0570780e85c363130e2fc4e4f0480270f82543874761c9e189821c8270d8a1cf811c5e861f87aff201d209494a9492f0806489c861cf7d1c7af097971e58f038fcfce8613db487df083f720880f31c3ea6913f5fbe3efc76aee3d0bbcee12597095485c69c1c5ecbd20978890471e4a60568a5c75a784e6e5280bec94d50b4d2634f7e23372140b372d301b4d2632a7c959b0aa0b9dc64a4951e23facd4d457a2be0262ce040501e04010f3ac08914e0468c7e24173d96b50d4977412731403bb9f4177b082edc85ddc48501e80fc8052231fd0de0db85105cb811222e0429e0420b88b5a0939c72dc8fc845d82100fdedc75010daa1a9e0a024a7adbf1d990206a03f146e08f73bbef7d69f0917da424f7242417fae8b1082fe727e11427892d30efded0bc004fd091d85c75c3872895c2341416e420b408f692a5c0b26c472dc480b381ed482b621c9e94f720aa23f13de447fb10fe024402181059d9400edd4d2dffd072c18394c53b92c10799213131602a03f120ec402d01116989c080b1f0480c883b0a0bf20076ae1421040c2139de484a33fd881682af73bf2c308d049582204c87fe0273f9ee404a43f58d6c2d07f682a9789fe7edc25b0030101e92fe84234150e48c8939c86f4d7fa124d05ffd0df8d7fa0a9e01f1f007d48c8979c04168280e80ff600682af7c87d0284c89320fa0b3a094f8290f0242798fe700ee4c9cd8d3c810179921311fd053913fd91f0007cc80186aca0930ca09db0feeec7e33e3495bbc29127399db082fe863c4853e1562012e463051efae37e64051e4a8e9cc80afa23f2a027ff29c010157492938dfe4ef85ed74712fd057d08921f1f9a0a7ee9cfc77b682af8f524a720fd21c99ef4d0542ea7bf1e370992070505fd04fde027e9a1bfd579f4e0f1242724fa0b7a929f23f990158c9c707d5c252a10d19f910f5181c89027399da03f9b2b51c187fe587fa9e0e3f524a723fa23f213f437e44a5e82510929e8240268274d7ff73a9acadd4d295c9e148ca460444b21058d3ba2a96429e8efc88da8f022994ab69b8a4a20d29fbe0e4de5f2e828c11629c2a3a960ad3f9eebd054b036a2bf9aa97075ae692ad7d61bd1543823468a1829f224271d3afabbb73a749ee454f567e4b5c8ed4bd054b2dd9402bd3c97a3c21dd11f7d099a0a77a4842739a9f4a73a47c4a33fee5a53c1db8624271efd24a7a9bf239ffa2be1f442b3c90004800293000c2d394149122426e4111ecb247c67a00b65213f9247780999841bc9402f92859c481ee14332095af2205ff0411948c3ff64215a02215ff041f2085a2ac917bc0879e72164efb00c0290ec13634efe23effc83ecdd47ee79650f64ccc97be49df3c8de79320074ce5566cc894e72ba863bb47422efe826a2eb648f4877398ebcdd9553cfc9d97172f7d46fe48c95b7e39cfa2a6757e50ecba6a5969466cab4dc225fd066bb021ab648b36bce48a0c4022936cd330b0d5034d833db1d408006061269861b2b0390fa059b1095741312923f14683bec0bbab7d6c3251f30952f68067fd08c9671eade9b5f73f6744d3f037fd04c14970b6321f9032bb53686242fc8577dde00a65f50845d1152cceaba6378010afc052dc52520848290148989813c3546f8bdb0a504a955fe1092af0d52f943deec801ffb87760ff5845b9b457bcacc9eca1e94e5a0fa2053b21d81b9a98439828881bfd4a68f6bb6fc96af6ce71e10d1ec18e26e9ac0b65dca6ddb9036ddb659bfd42715e035e814358928d6180a5f767d9124b33f986606f8bb512aa828a5690618459f484a67a500d296b3d62921851b9452eb5c00471d0586cfb2419ecf428966d494d97996edc44bc9a4e4de235fe9710f7a1ceeec42d2831ee7b81e3d1ef34e8f2cdbe9d123fb0ef723eea8c175e7316731c6b8f3e57ce736eeec1c764a72ce390046edcf4a972d25e731ea2931c61863ddf9dc3bfaab42b9d89d9093f3c5ed8212235f59b7f32c6f3b99ae54c897dca94b70c8ce65a6eb17f9c2227f2a14cf79e83800bcebe438941cbeea3bba3e411f8946be7ee0b2736c789e9d9d9d9d9d9d9dd73452e0fdd5331b03816f7cdffa3bfeb9f60ede3bf9dfdd3bfad3baaa4103f757d15435f2e78cfc992ad04e908a334e789eebb8771c5dec7b2ef00936fa3b9975a83594af9defe84a867cc119a94a3fc121fa3baf3c348ffe5c00d03af487f74a477f7773ab1c38f42757aae3ad755dca75eb82bf8894f445fe7c53693fc91ff8e40509b67c85923fdff2144afee0b83c15237f762e4fa326508fcb53a50924cbdcdcb8f987f78d9b9bdfc854e97a87fe5cad7f5309c7639764e7b0a34ad04747850257285d01b0843f59e6c975f91e19caec3b5996c1b98efe2ece3dfd619ce728f345de8bb1cbf5bf5e30d817b423ec7068fde5dcba32dc391fc5c91fbd915a608837b2120c9407d7a78f93576518625797b8fdd5a5a56f9a994a53c96acda30bfea81255923f4b6ab63c851b045ac86c18bb376960798bc42375aec02f36ba2ecd6a96d5d71398db10ca026178d8c00221d8df6f012b78883ca899b7c0123d7c07353c3019ac70c8384f63e424a464245314d04d0c7e8b2d180c16020c0683c160416021c0603098bc71ef4ddd7befbd5ca4f04e209b9818f8a548908bb1fcf9512395d3470a31126675030c03fd91baf7a6eebdf75eeea6eebdf7b2388ec25b44ead01d1e3e71fe7407f2f011a2037de25d96c3ab584b1583e7689c18771004304c1783d3255f31062790168313281583f7d4c01d776f90345832cd73624ccdb4ffba344e182c082c04181c026130d85dd96b56579140aceaa81d63d448afb592dea803d35257e75e1daf6b5ecccad5f8aaf47256522ee3a0bea01fb0204499e783abf38ce7d2ecf5c5f3ea51af65b97368b7f66a2909fba0c72bfbd537bbbeb4529adddfab8704cdd4eba5c15ef5be226dddea7a65daccd125a95aa5b5d2d77dbd347d656e9787069db2fe7eb384d43f1d7c09947d2645ed6618a31986d938a29860a8992a023c85fd9285a065032d6e9cc0dfcd1004db4b93e1533ed205914bc041261ba1b9c88aa399881accd13c643765d764d37da6f458762d27ddf058a6951ebbba6a164733097bc7061996c803f4d1b265cb1c76803ef2ad2a7006caf121ff08c1e1c6bc82ec1c8ee61176d0c01fcd22d01c420e8e66187ef2389a4168858066203b8dcf179b067f540747f30f56991d1ccd1f442e5aced1ece30648981182b504d30d24da28022bd910a1b45a228a85c40d2a2598f0129d1250ab2d565880e34246b505aa025b5354b7050515d09ad0705bc4e021c504d4b685064b978bb6a58d1e889a404a82071fca1041c46529892474205ac24c1250e84094849a24ae50524a02044a444c984922cc0f444d5c72d0783f2c1de3964b2703d2019e293c2df98a3aa49981926ad75a5b2e18b561176994f100e9062f2c69d6e841039cddd0a305b8ab800722c02c0cf808036b4df4e0a00a2270b621183442e0031a5bd88059649090907e40a38c1eec5cdab08b36c6ecd71768a4410234d668c9c10e5128a17936c4062184104208218410420821841042324284f1a201df15f830836dc07c8044163d5650851558db100a8926a640c28331f0dd100a09227ac4e06c43282480f0629352ca29a58c5766526ee84329fda69c73d25aa994724a29ad94126fb9240a4a4965a694ca2ba794320535958b0a0c2184104269ed9c41a6a5f605a370a296ffece79cf39bb79452fa694b27a573ce7fd99cb37ed63ae7dc2a47d3e06c2aa7def47b0d01ebfee69c733e421ff8cd39a79caf5965a5130758d21aebbdf495c4a5524e6ae9cd6c5d73e9a51ad2bbe6d24b335bcfd09bd9bac6d6ec525bb333d5da9aada1d7d635975e7ae60cbd6b2ebd34b3f50cbd99ad6b6e5cc9ae94935abc532f6c5a6d16630d5b461abbd45a6d4699905e88823489b42012e88b16a01fb01e286f8f84e5095165d2c2c46491b0543da318242c99ec329753a9a65f28e87649ee6f778284d9ddeea2180245a6881441905ad3bd1913d2182631910b8d484abc540ba1cfbc4d9a8b71b4914b47648184d2768408761602117e80f6c7ed6a64d7236e30220c1641881140ec29718c1016f4579669b892704a08e12319f8c988a495b5d6c2664f7cace2880d5ce18123a8382266add2b6d65a6b6d50d06b7f2da62c76e02f36e5590113103d6bf0878384d9456c20db6a8004f3bb94527a420c3050031a41d040882e4a88c97410812f6c43c51a5bdbf2fc8837ec2f4811f8655b11ec0f8eb19ab59dfd6177aca5d6c62d2dd8918a6db394d9568b6d7fb1eb2f180cb67d90d01222226eb0ed9f403962db4779c1896d2f0306ae40d262859219db42282268c0a4650c9722b874b9b22d84ca0017f6622f62b6b50fb2d65a6b7b64e1c0bd9d076012a679f1210363260566071ba6cbf562881a0629c352460e148bc572831fe6089e6a96a40bc826504f7488206213305db238819b8c008d7429fd8075288049d8186a18e1011835baa8a106163d30c0aa0dc1a8d1850f23f0b6211835c078f980ef8660d4308303141217c8d9100c1b5b94b0fd6bc5bb6950a2440d0b54755cc76198109109a2cc182595627e3b929b3eca5e77b6b4cdf96d9bd56e75d65a6bfdab6e72665de04fa7428922034483f47a990934ed0f50505faa8e1ff0847042a8a5c45077f698c2b4f6846b179a98ce16a4b2473e35c67ce268ac8184a54b9d99cd7296d15c245f2ca4745c8a4af0009882aa81e16397c472306315a0062ffa090cb56f179217f38040ad0c7fec06c47d7e3e19c357e5bed12f587be27927962e775838252ff504f89387eae2cb9697f67572437461c134a286e002239a2070902a03268d96c833bb21b9ab974a5d0e490b16c102a1845862df6cb92447d8f2d5a60ea14fe5eeb32cd24aebebddb093ef5e9044c70f986e4be40fd556432d44f312263045a26b75419f3a035c796409f3f5d556faeb512d1443227bea5363e827b00b0ef194c46d2b19ae0e6838d82e1b0eb5d65a71b85d34e104c5e102693629a5843e74d2092f6574c176e50f84b0a0bf30b51267905286b1d18927d0937618a38f59529b669a3e92f747f38b503bc618e352f67b6917a3d0de69aa539a462c942e118d80116ac9eca187b14d6608a554c9cec84a4ce84911282fd4280c0485444949f7d99388b6db0c6348287dead2141b78098cc92529ef0b6212c6e6375967ada78f59c4e244c6a6ebb387c296b4826c7d1ae36a4d2a8416586ed8794eece78de636bfcd6f9e91fc7699394f49dc5edc72c3edc566f6e2535e6ccb5ebcd985a49682cd9eec3113ddec37cb32884642b1411e2fc2a889ea679452a289346c90e766cf3aedc5ec475ed41e91ea29c098eadd8faa38191d6557fdc8a9283beabaa77495edddab7057dd4a0cc660ec1ec6b6d82591303c8049dc148624f644a90bc978b3176b517ee23951a9b25ffb5de9a3ecde8bda48fbf58c52d9bbd76d4bcdab5c5a50c6068e422505c1a691524a29ad144a144a29a5dacca44501a5748b0d0689b4a1b673d8c01149860914af1ad883da73729f7ad17d4a577182af72e474a43a3db2bf87faa83ef5953e9a3b5be0d5aba84e6f57ba4ad59e13d5e9bd4d17a9b4b73dd1d7a752afaa2b94fad41ebc7609460536f8f0840e19f822765f349f7dce5bed44b347fb4b0d342640230c24ccd02296a9741558ff647595a96151474e45a9cf1fd17b2d2a0663993e4a69cf89fdbd077591fd7d51fdfc07d33ebb14622c3b9c324e95071f4351f6d4bbc77db3077fe4b4fd28f5ec474e9d2ea2bf3fca9efacc1ed41ea73df84d17ddd31f51ed412d03d2ecd17428616ff336ed39493dbb51ea993efa117dea463706b5a6ec4252bbd7525a5cb249d4ad84edda29942812804bb5ca5a291492b5d6babdd65a5fb3a7ea084d69eb6b985a19207f3eefcbf142945a6bbd078740b873c021f465e8195bd40287c82a1026f100a39658041c120f213c03a11816ece18bc0a86311d0876660533172cc025f458cb1650c228b0cb6bc05e08b7e0661c6968f715f1d97a00fb5400db67c84102ecdb02712d22c6385495a3a2595b27e61938254920542e3820637a8ae6c61c5997a450d2ee98cae0733d6e4d0829a43adb5561dd81c542c11a8ba484d81820c18d134031bd460072796a05e10517be0806a731b4205f1441a323d5833704825692b488091c314293893431850c82eaeb85c9c01020b986146cd813e08a61fa99b1d90b698316306f26c6e674ebeb07cb9cac03c32e6e00d4d087da2a69312d9aefc81504a2965bdf9fbb561841d84a2505c00cdea05a00b019248427290fcf9a07c8970f856ecf0ae7d781da1c3bf051e067c012f177e2800f6c307d97148857cc18770f822120eff04e8f02c08393c94270c48c0a144913f5f130b4f1d3621e0d961910f3924f2a0c320ff6152618b017e806f874d2b3c75f83515e0d9e157a484c34732f2e723a2e5927cc11b397cfc42fe7c418a1c3611bd0bb596912f49867cd517409f7a9d31f017a3caecfa28a64c7d952f1813c9c817c021364731d58ab59672d9edb35b2dc3feee69d7823e57c7a5ae49a6a5dcdb674357dbfbec6aef664deceff1afc6f28573fce14f71ed7b3b2538f8114b37021438fb1797602a95c588c56adae52e6ec121705b6db16427e4ec387f566f5b8ae3ba221ccfa1ab38d9c3fd45d9df1457a577ca989a65bc21fb794d4a8fe178130e3d0395426892147243adec35529ccd53cde56c9e69e4eb862ad51b7942654185c6d96dfbc23d51a8ce091597d516ccc4d26283e50610ada51b1e709472925c9ccd1509c71a39d4786974bcec50a1a3cb0e343f93cd6832005086e70b1e647a8cf120ea25a6078b0f9ca05c7e9cf1e16c9e6640d802630a418b085846e06ca64004e16c9e68e4ebe69b10cee6f9245f37f7d10dd93cfb06c4470f10204080bc80dcb46ed8701b10203e3e5aea0201726f06044896d90a8290114408418810988f8f8f90880195a6bfc9ad9c314b6391af8a5bae1db18c9005c3583d527d646aed2cbb37cb62a09bde52aca97c6dd9cd0f80adadfa223457f4aac8d55b6a7596c5b8713b460d73b4e02f46c52f7ef922ab8f59764fafbecf3ebba1d68e5f84dd907d2a73406b47fd4dd9574f69ed98e9f845fe7cb41b8a5fa895765a0a63a6fa64d0da3bfad1fd4531bbe6c8f214d8bef1cb06a486fa4a757d9623d1ce6e65c36e5edd85eae805880f187f3a9773bd76762ecb2df9aacf9104cefe71bb56224bb2f80241807b491623803e707f5b48de7b513856ca6eefe918357beaeb925e8a51f255731481618cd5323beacfb5a18f1af88b513baa4645b5a40757789c00771b42618145191f5c808a170a7085c203344d6460c134051630b0580a8389ef2d9376564a2b9d954a2979a49411afe6953f334a29a994f272369093569b5ff313c279b3219c509b32c29b26ab66361a279a29291a0821a438986dc468a6d2362a3d234633319aa9b48d4acfa06a6cb322118295ceee55ede479e6b287e59bbb2648d7b8eebd37621a35b95811850ffb834f104a0c0a9ca298d00006d03cc1c36cf292e68a2536231ac8ac5146cd0d67ac985cae5043857ca0a905300853060c282618b7032ce056adbde280167b75ba5a750087bdbaaa4bb282647457acb1bb735d920e7eb9820a1d5a3069a82b7088612079e1e588e8851559d02ff78c0d60993744696ddc0d285dc08b316b54c181304e40c5ec54625b0e6cb16d6a5b6badad628b12363de5a1034f154d6c7b2d151cb0d65a6be9611535dcab04864958e67401cac53e09319d18a14622c91eb8bf8ba948c1929323a27898c1131531d062861717164a2a8049188f1164a0870bae1b82d98193193b90c247961d6851811d98000736c2e031c271411457ccac59139b37aab7d393a79e8c41d86403c71c5faf18c5e002671b424df18507434031850a5c504a0821a432d628bb9871ce99d93a29a5349b76d639699c73427875d8a69c137eca0c3999e79748e78c311ecacb28c116e99c93b26084c1e61ad8a54c770a241ec86092228d1cc6589a820725319ea600a20230589ac2081ec6809ac2e90632a26a193268c0e4400d17186f08260d1df6771cd2c08018692cb1031ce016b918bb18a59c52c6edf5028128683e79f5f888446e76fd5dd3734a2112ba604bf92412612182208fef16391a6f2bc7c2b3a8c50d053b5c601965193c378c0c782106195e908f686478216628398a9297d4a7f6b844b36060cfc33875f001dfc727e910e2834f332249b821d004726965308d724e55d376d919c9d8762dc7a739b9cc1c9880f69cb71b45b24408004a48d769bba9018ea773de9c118b04c9d79c954a092f9c3d70aad9828a405953546ed5d4da2a9b3ec218dbb2d67cec7a043cb6ba2b48fe84005fa99ccaf52134c15be60440583369a780ba014e6d0825451a3e8690e28c1460ec6e432829a2aeb665f4a9d4a65d0c8120dc5259769ba57eb56b7a48ee2f6e6fbb67543f9f42d5d333aaa74fa16a7b6f964d2b76862967187b6b96e1cc663c5b4afc7876566bfd3785a7d6ecf6fe8b99f6ae1e82f2f54de1d936d6db5cab151ba70e5bab556374b58838216a2bf5dda44024983e9e9eba4610a3f6b25bed65ba08ce9e59290f4f4f4f7018f18293524a338dab9e93ca182319b576a952d62e55c71438be4a69350c744f3d05b6e52c82ca1b1b3480e1c3e0cb426b0d1c2fa7f0ec18e3149e3dcf13a714f16903f7e9be60eb42afb843b463522960e9b63293598aabf976d92929678c12069b3adff13cf2e7b6648fdc1c2e93590d60f9ec35f37cc600d77f98eeda35a148481084792a9b64b2ce6d730432ae7602d011bee6ab6c4277f6fbabb1968f99eeb867e4991ab73c805fd76d60082505d37e9a3fd58b33a4e8210db659e3c504c6673e4872c1fefec396367cd0805b5b6489c2cb52144cecef4544e103de36848a62a9e5a262a622a5f44a09e79c73ce39e79494d26cd23969add44e29e5945266f2be6094c6ef7b5dae9b35b0f8e037ac5f26ad36bba9596bb5f225ef8f311827ca7fb5555fabdef5663745b53937eebe6ed00666760c7233b17bea267bfaddd45aebeb9ba7347f5987ba5258bbd93247a98b7694d65af5a5db96c6255f50c5adba24f05072f3aa99bfc9755be0c8d9dca8ad16a594bb9956df0843d549c9cd0be16d3229dc340a21b4787230c0f1355575f637e7cce8cdaebdf207de4a7180a5a473ceade3b0d8b009f8e5527265e008e19cab2cd35524105b21b1c6524b2b0dd4d635965a5a69a0b6ae5943abad960c5bd7d0325450c69a32ce9401633c53c6cc4119136a4d171c37395a5bb5569bdda036752e417e7435501d2c9ab05bb2cbe2a214a4c496ff766cf81d48246e8920c821104875a82ec378263b60e7248ba57494d9338613714b4c8a4848a94deb5210c5002865b48debd2f2a203c5a170bb255b077b71af1712a15be7352d15bb244d97e7aa150eee82b9588129dcb0eebee068c375e1c2850b17c8850b9c40383155c76d5a54266f78c117632c9960192424a41b9aa0816b820ce73406eb092b5450a4e0c6179dc4b277ec8fdbdd6119bb3bedba64815b74832203504f8800a7f9b89db556e044164e423441868b04504d54e00699a14698113c098162424c1c038a1928818118bc98c0024b21934503496819620359d81c3c80a4451f3a5cd26c7afabb04984d8f97b0c1a63c6c8051118c0ecfa64d6b36e5e2b4e95d9fafcd8383314a9c804c53139b5eea005320586bd3245ab029941248b82e165603aee86a0527581981034427040e2f749cb1c9a085458e0dba2daea441a3b855dc242db57ad84a80a30dac04ce96ae0d17746d58e1eac1b526cbb6869a6e0d3170769093a56bc30cbb83141b2758ad41828b46b5668bba0136d4746bba986bd4c099a00d1b562658b3858574c5f502098acc0b1acae03594e8aee83ac688d41536c4d8aea051c65e69b9726c08e5010f4499800607f07737f528de7e105949795c3b50603829fe04d20e537fb2e93fd134edddbfdea5bdab6f2c51460aae6042aae2a4e9abedb38bb9632e45027be8efdd6c96dd669aa76a29b019b5411e3c81644c27661ef9caced26480716c18e80e627d09910bbf68d3de3dbd8c3ff29c5c6de419d9cf6b8fba48fb165347927b11eb9cb6124be922ed5d113ed71dffeaa26df39cb05e5fc47ad5de2dd2eeddec292df0b32cfbcd32d6b58d9b167792ce98bd5eead888754d7b29dd2435fe91bdda357d548fb5778db6b3b41f79f746dab973fa086bef6a8f88c5fa1136d2479c3ed2ced2de2d621deb2a4ef7ea22acd266cabbe7aef69cb058f89c3eda8eb7eddebd11fe9177b551f7edddb7145665a20c65f664d7f20bac55f62ecb328c6941b3278b58e42b68674b4c536a4d1be4d956abcbaf3a1b1b9bd56ae5c47b77239823078e635d25e7385ec57b8e5b8949d8c91f79efa0777ca39cab728e737ed4ddf3debdc87b77a98b72367c2bab17b5be7afceac6b1ae62f31bafd2bd752b31a9d25558c7afb2baca4a0c77c72fea8e2f8f6daed255726ef32adebb5b896115cc717c231c57e9a39ce3c8398e1f79cf7118935d124f7b91ebaa17e9b46ef491cd6f9ca5bbb7eea55e74f3d58bd4c70c7a4ca27dbcbf70cb6faae7dc087f471fe91c3f47e7f847aeab72b2c77de730e6658fd39e13d7736ea4f31d9de7e8fc4875d7a63d4d3b715d7503b8b4a7dd4aec06d0d19e86bde39cbbeed2559c8a5cf77415a873e81ced11b9726238349e3d32277b9a2b7b5afcedbf6718cb89da8b5bd7dd888573d63b9cb37e74e369ddcdbb1be1b08ef38e759c1fad7e93d24e6ebeba016eb497ba95d50d80a359bfd15560dd9c1e91cdbda2ee30c624de7eebb2973a8cd9642f05e4053d4ef51f8c2a923d267adb2cc53ebf90a1e46c639927ba70810e9e32ed31a1b7b75a4ad534c6b2a2c9951a2222e882572f3902cf675789dcf544f2e7a2205ff0dbf69b67fe22929ddbf6cd6e5151db3fd8e6dab66ddb52598bb0bd7d9e955d13c8357bb61c047decef9c73cb36752d9522ca02a77e9ba4e007a1b8772b9b1cb77803db1cdf86e3baaee362ace3ce3a8c6d94734d208eebba23d6b9c318c775b7d968c7499b89595fddc8c6e62b7de4347fb4ba11be8d66d91cff88f5d5eaac17adcefad445f8361792b24b01c66e646f7e35e75cadceba951b87bf916d329c3dacbca93a4e952f9e3d54c70af0fcf743bfbbc10e4ac2a8e9a106259a6a30c40e492d08030653982fa830636fb03a2d68c286304a6394400aab0318558c1b5610b5c54c0d586ae982dbc2cb952bb6060f2805f50086085090051a25184115b11578e0863ddf72cdc3a0b2508305582e13e6e2ea722faf27a8a079844e912ff839e18c9762ec72fd305850107d3a3229a5b4a5c33329a57386286f1adbd4b822f88b4bccc7bcbe809171e67e3a1066308319dc6aadb5d65a2d7de40e63174e7f3344cd3066b395da0f8aa182c6d7b64f368535b395521d635652334869b3c43441676064bcbef818971809effa8179a0b4caa0517391b09274c5a5a02818547c8a5d2297c804d1ecbab4e76193d8658628a6e8c40c63b643910f0a92d0ce9066cf25f055efc248544c970be309e565cf29e1ebc99e8f51863d9fb62836388120661d679bbc719f6bab609324ffa26cd5b56c73b86995feb46df3450922e7375025e0b259cff1b2332a809be7bce626dc59df62d62eb3bd0e13e09bef759800cfdb6b9afeac703902d31b8ad175d80920eaefe611a05b4a8edbfbcb62e521eddc6db04d86d0475bb1ec6a65594aa46c36e3d8617baa57aced3677dc37eedd6137b45dcbdf0c43da59f66a18ae24d25c71336c284aa4ac0eb7262db4812f6c7889a4bfbb39dd1d4b24782eaf20d02449ebddeaac434fc926a5dedac36f96bd4dc45ad4f4070314a41d03dd10b0f138373404ac705e8e81f5ce1b92c27dbbd552585f5d062dcb2d7f43aac3a8bf21d576a1b9cdb0a36c2599d35f448236f90171d35f44da753b772119f12a07cd9774c1107713d5211c426f1f5065775f6596a6b79a9eb03a2b4b4969ebc5572fde3ea5691886b6738f7a6875d6ed3f2b48dbea08d06df5d097b6d552bac32ee7782a47a4cdda3547a42de5e639cfa199b09e73d90ddd3ca789eada6dd6f2eab06372f39c9c9c7d31d055f68658bf39eb25c002c505991d332e764d6e76d4526c0452dde0ec7532de2a8abfc16e88fbea36774d589f8da68756d71a2b472fb3dee5cff5c9b0216641c882c75c406d94bbc9ac1bfd459b3f6ce1d6c9707299953f2b4838ee23d2bc4b37c9defde6f84ede6e471638daa7e2eebac76fac5fad752931d0ddfa77e3f0f6563f40eeb8d29fdcab6f5cfea06c2e8a2a43f1b27795cd0b5bbbbd97a1fc91e190b5ba71564b47206e9ae48b9bdbdc856412ee5df6ecf190ea9e3debabcf72df70b657e5d50ae7eeaa5577782e7fac7faa73d7b2c7d24338f7549e6a75f89caf3cd5f16d6eb377e3ddedb79c7c739cdc3ac769f9e639593bce8da6a9f4d0cd3d8ebbea387b9c1e627d75789ce377d95bbd3bf7cd266fc7695d95bfb8556f1d276fbfb1d19f95bd1d6e57e5ef861eb2b9b7fa567a8875acfad665acca71af6e337e97ed6d32ebb01b6261fd5959e91828d7e5edb06312c28e31c429735b1d01b9777400efba430b1c0fe7032c7c96e385663774b3e373e40e33738bdcfe5a0f889b76f837e32ea5303563fc1253293d3f9d9de97ba189e92facdcec4ed8ae6961da94ac54a7dd085d707c2a03c2f12c098eacc304584a03b27fc39de9b8458b7c55fa6d76f84d38eeb5c7b93d0ece715c38872e1d97628775131c1db1e4fc669c692109378e2cc9903d395a96e1e814570bfa581d976aa10ea894ec98a972182a44230000000000d315002018100c09450271300e26b2aae90e14000e7796406c5099cc634990c4300a82206300208600630820840064942aa20301946a70aa9e4126bc9c963159da9b7e6a1782514880c1f32f774369bf5052c700b13e82cb399fa52af277b9f0d0be18b0876bd0d1747de2522fd6b50b1a412694da9fa8f606ba690ea60c289d1859eb9757a711b4702dc182bd32a8bf5bd29f58d408607197163c02efa19be661da82597e4de90c15f52dd204b4dccbb155ba44abc55220889d5250d440e75fd6a27da565ef7305e2b31502c2c19f7d8e10781857526cbfaac8d603e3898e6577258a12a014bf51ec1e95ca69561c00a6ddc5a608be431d301860c8ed0e9787ed2406c2825bd58d10a623630f58985a1801676ad2893ee0aa3da594a1d5b4b63cb02e826708cd6cc5497ba94dd1aca2a9dd5dc3dd3ebba452329d7322174473a262d4a6f510c7818802106581ca7f830da512e18d059778e5591a15aaba37ea057c195b8ab37314dfd9e7993adb4ab593cd51fa3c57d402a5b839d5d9a2492cc4404247883acc4420601484f3c3e32509d7f4d2c15b8db31be32fde779d62291ad12f7c08e24d5c84601ac8688684c6819f30fa0b6392a7619a5db3e8078d97710c0c3f517aaa1510eb405bf551329e288bc2ff9056fa88ca11fb7dab724506fdd8fe764cae53dbd5447e6898da82e3324e87191b76b3fc09ad65d42f271fab29f0b484c439502f24c003fc647a0bcd03911591df42bd02406a38b8924d50c05a00f190840ea00711de30518268952e84556ec3413eb6469482923289a966e568a7dc7aeeefdf159baad3f4b8d5e50bde370db8674310eb77e59379d9a708bb8de482ce0fe90e0eb41e9f366bb18a15b55730320d591aada7180f4708bae3668f6e0678307549de09f455d8c0b6cf12b9aef5a36b5c8e461425e7cbc1261836083b22a328e9ccd70fe11aa5da44b57014ebf535d503372bfe085f122aa26f168e462e048cae005da3d801e6ecdc0fb443e894dad8b204ee41b52f491bf611459364f61598c5ed6f56646f12232159dd37a3f51e093754c77ff125fb62f8a9a21c86073ed636a8306528554bca2a25db1278d603e83e8a7aec0f352028a6792710d15705a2807129821033548d75ec52cbbf0c7ccb466dd056e40db05d28c9066c9710da27c56ab21b26747771cb5fd6ec1d4afd5824a310322a27c516079ad0322ba7f33d30d6d017b8c47e0c635085a7904eef619e2333c063995a1f648d4af8bfed8937aadd61cfc061820cffc6434bb763c34a9469f74464d9b11014c0d82b88f6c3275a18af3fa2b053eccbc81f34f059cf05e5fa10286f6b4eb64fc53d442c55ac87a72a648b153e835fb66d132b61ad1adae757066402db534052afde3751c88106a10cadcb854350d5eb2d0a31d335feffcc303e46f324740124ff816f40f4aa2d945578ddda388c22a4bde6fe2942a09285cfac04877883264e0de93c8f505097a28be9c0ff28e7fc4ac6c8de4b23292e46474a3888090fa88f0a431e962ca8fc4829dff3d90755f0dba504acb0ff256e4643d7c8a090b63591f5d81e4bfd6b04b0041be29c93317113bbcfbb55815384933a3291b2f08297ed41297e88123c8732329ddbfc545915e56a7550fe97e658ced39b28d4099f935b00b0f5e443b20b0a2cc3f68fb1b4e3f42936b35be4836c0877ab9486a0f5081f347c59d72f0940ec17b1deb8107098a7392149972c8dacab1655b33e7f99a6adb094374b432c0d9298a45e82d9906443b380d9063ac1eb9a80363b5814adcbca7232f47d5cc19b98fc726f8ae8f807244683456a59b43994f645e2bd28e0f4ad7926517f646f4998c70d332c7a56300922c1a5e3797e0729fb9d1f8aff46695713a835c773c1451123e07a2a04b04f943c88c9ee0b687c1d6aeef18e71e4a3338505bf8109201099ad46bbf7c2837dda08a6ab02508bf0b3d5a1ae930a8ef2c208a23340ed3ad630e46967a73cb17c45e148f5c1c9a9cf4065f9ec912ac3f9ee6d11830f61eef026e2365957a02f820415dafe6ae30738c188b31204a109a36d95b03b2215fab322183f36f5934ba754137d1b0ef3c4afa1758f90fde37819d434b84c74011bf0d6f5883406a5742946e507d3c0e5bf204f09860bd9d2f2ce7326f982be1383b0d8438443745c9eaf514c7ac95db1d521151327b6c8d50063ba8a5882fc7372186824a45a886b788000e2db420d801a31c8fa1d76bdf45f84ed82478a347920e89bf93e1e4fd84ae03e90aa43c32a7c4da37295fdb19269b69b50c0fd179dfbb1f403f33e297b3bb1df44318c470ba591bb154592d76eef54e5b91e54aca063f1505188fefac26c045bd6d53a82b32c5d48e6995950a0a5161dc71ae261c9772400637b1f6bd1d3a8c2c58516d98523e787c62e072c7f421e206552147ba2a8286f120fc768f8504ddd869b109e1929ce61a2c7315011398dc6b07cf5f9f80647806d0d56fc90fcbd6967940dee1e67a841c703847d26dfc27babc58244805092230346d4b6c81c9086625d49577f793a64fda86db5fabc144d5e47de5513b60eeccdee0159c5786939a7224193acaebdcdb915b3ee50f2c71720b3158c7fd940343018f99931b24577086451b9856323104308868701b0ea87945cba099cb6e789a1fe861cb7a2336cef279581d2e13c1b889714b908074e2028857e04be0ba074e77f7edfc0d4022476e3c2034199af049d206ea9da807521d3741495685d4d77ce4dea8ce1854cfa64592bbce8da72af921d075f4fae73a15beb57742f29773af7c84e298ce4496ff7ad524ad47b96d3d46057b4db5d3de2bdcfae76123ad6456fe4feff92161ec38e7d4374d572448732fdc518acc302e148ce9b98951f47d092036369e59f3264b60ee3423cdba8bd1c846425ba95cbeea80b7e3e296b0badd524bb8dc4152fc7fa8e9f95434e31c54367177a2960930e2259e490e9b3b03298787912c0303d3b43585bd119e2686ab6899081d3b6bfcf5bd4d23a10d760879f7d574848956e50e411c831b2e5e698828b9b6171471dbbcc1f9f03ab5c84d9d5f7760b13797d82e5755b71f7017e7d60118f914b1926e8ef11c59286b602ac20fadb597cd132fc4c40c4594d3b7acc7e809402db5066463e7e5d48c3d8bc678e8519807a0a8bce6ad127a1e24d452d4ca096b373390265b2954b8ccc8d4b974fc361668f8b47580d2ea00c879dc83e700c917592d8b91167bb59981a29817f69b9ee6a806ff97ca8c821180d09468c0106221275b05042773577f7eb8fef0f3fbf7d489b68645de51e027a1a9b1c9ccf2616f613e654ecc0082bc844467a52a42f2c00c1ca99479ca6fc297dc4a235140cf204ed843676cac14cc7e770000d6fdc65404f03142fc37d715e945950341ad1c755fbbbff3702e311cb9450f23aef20dcedde5e52e6f02e4bd2fbe7fb0c6882ae633e0626e0f7838fee265aba10dae4817d1eb425c0d77b1a57846c2cb6c15bc93833a7cc250ee94debe58db9a8c0a6d83a014bac2555eef64801b548eb46f7ba60d2993688d86fa79cabecaa0721be4eb4f521df625cf7fc864c188afe2baafcd7e99e3e17730515795485e99253cb35f7b10075c878086ea5b58931bc33e6260535fcf1cea904697353ee7a66969854768685b721c4c67e97f950891cf6631f34016c8004ffa45ff2561350747fec1604d219e3b26e26de4a9882b55494af9706cad4a88f73e1f9574cfcb85db1e183137ccafa14d378701222c9be12f621639bc9480cdea0707a13208a91ac6b208c9d1f20981a3163c3da617b87db3a526af0625acd3331a73e0960c6110ac8fa81d80baa82b6b5480ca1353523f79f5f314ea0a8334e2814371860230a1ed33d3a98efb10b4a7211e67aa1c5b9908ba1ca54c57c877c42d66992ca5e601bb3ad8c34c9d8305b6554552cf3de2f6f15a1ade069c88f83355cf4a839a04d83c11e395888b6275f71518ff1a0679768233cf483ddb2bb3d3e326e6166defd884c6c16b208ed2eeb989469529213ce01b111826905af023fb7fd6146df1277b309dc28e102203045ce2080d9cd81677fe30b1731997effb4fe988f0b34f96c8920c117e18485cd32eaaa74c1c1f84dbeea2cf5096d66ab9cfde0e65cb24c82554e9165476e9d4b935570cb0adf7fe7c15951bc03c26e12295d8da204220424782647902575b6560e172535669f034f5664e8d9389e9d93f58bfeb290c4b5d39084f924bdb2456a75b7dd6a568be9531f0a69d372011842c20567a6f1ac496c63ae4f9b48bb1d285a412afc67284a350d5bfe18eb049f43268b998e6980155e8f231c49a5bd4e8d4e8aea4b2ea83d252c156b08c973bffc8b4498bc9ab33bd5b0fdd317e160b031bc5753b6950367b082867da2d11a5d34c5355dd642993c54b5feacc3b1448cc72f0ad4df1159ea12335115e7bafb71bb0d76af44c9bedc2070fcbbfb36fcb88ab86684929e1053925736ad2e88011c731b293e0fa73c202fab60adec36dae4cbf0252d6c46ea76cbf8d2f59122ba5c01057595955ae2d9acc87ab821c423460fb5be1034fe9aeec9561adc80d95387d82b0e924c6ac4af58f31a20541537ea762b2fab57422b684ca95204188d823d2f7c9c900e0ea445863343847e43520938bab887d81538e8eb936bc4aae9b8a9be5f18cec1ad2cf1a767b2030d5f1d85bdcfce8bb6d21806c9e7f0b9f77b86be6f633d91ae2ece2e826ac4c4e31b875e25e476b2ea89894b6805d349bb99d41c1108cc84af010bea728dc5768a9dc8a3d8f977299e0f76b3ee3bb3d4bd727c569fbd855e410b93475dab51d61e42a40753011e3190d58b53e4f93b6d64fc384e2ecd106f16fc0afcdfdd70849d953a037b60e9eafaed1768446fb468287d11f4bb42601f8e3e41841ac58826c6189acda3fd0a70c9d7792f368791418c8e39e4e26eefadf0ed092784ceef4799be02370b075032c3179aa66558db0a2397d5c8a87b50ac49661d149e32ebeda5b0edc419afa4c63ba19e6f71eb3a1c2d2b41d5a4e357eca4c3974bf00fd300ff66722210ebaa53fc0bbb239ebc3b778e603c36337ef5deba04ca0c9d388a917907ef7539abd1cc32f9cc4f364449ba01e3b7c11dec29590ead6254c078bc35cc368b88a9074775575c4b084718b99af999e57599e1c1f619a740200aa6caadff73508544da8729054cda08f6c93ec723ef55e7a737fc8d35c10d6d8ba7930755c01014d1a930faf638b151c41a4d93a982645264c9c6d1a5dbe08b4d937bb900e7acb4ed2560731fe6bda0f946cadcbf4708fc2e0a2b097b0f259ccbe97460416baf5dae28bce08d04050bfa6cf886cd577e3604a42af3c3507587519e0ba5dc98eae3c1e5e95925a5de75320d65ddf7163de8d203d00d12cb197c4e1093638564893641620fb3bffdefc88119cb59b7a4790a5cfaa07e76f1d71716da62bd8c250e082ea9470df3d462259532917fc00b5fa8d9f9eefc917de2483cdf2fb5f6a34c0fcc3bd0030b7fb0661486fb452f6c508376b55ea3c0512aabe3cd9e37676dad4f1119aa4cb12574eaddb5ab31a4f0caa7bb268493cbdaa9e4ccca2e1082565e55b6a3d7cb33282a6a14e64b95a7c4272c5a6e43b1213e360e6ed236d447082d97eafa04a58645371a6990a78a2fda40f12ad972e1e5d6aa9f0cd3498b93096ac25c89594dd6f262e006f185e3a0e811ce53433dc0cdfb887b3856044e7f3e105b0f046f564fb1c9cd8820c381dc287e714e0cf0e14289fa7db38944ac40bb9a15b285aff73643e5a83edceb5cbeda46b44503638bd7fdced406e75a00f1012f6742c4395dbb78d0b62073c117525475de6c41a9979a659ff6062790c6cc20101e43f59026320631cc26855fdd56bcfb43692f9e85e9390b9e10d720b74c523304a049f6d5a25595cbf820c52a41c5b683af0081a627181712e3597b6d002a123d6a054bfa532eaddaa1f9c2fa43297d1db09da529ba77277c7fec848d095121bcc1fe0ea2e4d71b7804deeb1194f65b3a3defbdeb6ba0e8d7be27454f985105883d9f19c009c25ed2f558c8552055d4fc4e7beb8673e5feb4354df06238859f31b5cd5ca2c1985e9d7dfd6ea5e4cc78b32783196a30052813c453d402707c9dd481d22d66a6c454cd65959d106b3961c1fc04838219b66f3a9c0d745895f849a2d68e8bdd2768ab90099289e4ff875b174dd9d0aab3844220aed91f4ce8c8165a5cdf54cdd40ff0b4b683708b18ea4264ec849a159cf2500a62320c49be9d0908afc423d8ccf40f6f16927c7c9e029ca1e27ca8963c20a8f15eb27cdc542102bde92dc18bcab89fd3cd6689f698741cb659681d73beef9a44d50cabcd6ebdb92a88f164b6352d93b05d236848089ee5f1a07598f33279907e2c1b9fc55bb73df30945321dad79a141916b23296d07b9d2170dddccf9fa146534333a9985739dd620fb3bb3c88c2822f7bf4133e9fcb6cb960605fcc06cde5e5b94186d045bdccd248845f7298358e49832b4a3ce2c0238747aca0e883ae39af6f4963ab029ef3d78814e6dff8220f5ba41be765470fecd3209ba44955d00eccd9fb924ac175967c264c6a445f8fc5ef76651d571fc7e4ff731f0a564b408835144d87b883d7aa3f24750404c06d78c9f065b57a7033331883a26fa1d3de69aa65f453f6f732b623b23a21d6cf1fd9a35ed77b144ccc2cb0ae39a7b744f8eb4856303818e5c82d2018bf22a3cf078e359753930dea267f48e4e9d3db1d5002706c724e494e462ad471f7eccc734b7dd02a384c4f402b662ff33c35be93c06889897d57657e7977dfce32a0f6d02ce3adc77b34af9f22263ab404f88d1d9573e6a1f1b1607927e81fd79a4d1e8ddbf3a2c8e1a92f8141a22c1a22554bc88ba5be93af5a54ab608d1fd8cf2ef04404b5f8aff50c82779c3e0e68150535ce4e04bd97aa28541bee0e214e14a204708356bc113cda25fee0b1e50b9c00645de6cf6ae8c113225a3274a6303b34aa7408b8e5c5e35c5cc80f10f24cdaa6c87f18b4774405a24e301b712408287d9e48a72daa726d863790fb46dc3543c8b7cb7a3a1394b70afe84867141a6594d2d36040908abb65d6eb539929de81e27217e49450411fba87c8a175df0beb3f81c64559f45532bae17626adfa837056872bc8f51628726817274d0c17b6703aa0c559397133aed1a7b12bb1d6029112b79cf5a26529069098aef22f0331c814159d4bae0cc91db603c5bb0e3481b479f951c67a06f075937d19a4e2d4cfc7fc2e604f59c383a88f1775fbae93a4c22c529a4581a0ceec498a782cd6bc6991f4c08133f7b14a866a7b13861ca448d738ab9a8e60a2015dbc2db192097bb1d87df887f85cfc2d462cb6e1c54ca4090374bb12e91d331c83da119cc96c8dabdd859546c3c69be55a6dd44924ddc6941e219f2880595749d9d70f9ead23a6838d09a5c48cfb800aefa1d9978105d344d13eab180a0e578018e103145a6445950fa86728cdc7c59ad19a7030f34b25f27f7fa0651f8b667db49140dc1596c6fb969a6fd2b99d1ca04e3b380172b77aa7262d428127937d0d8dee9f40ca82450a11a197bf7c4b5db0b1bac56f7f28d629cde4694893d7ae88b29a01bd2a2944a8afd05fbc0adcd3c32e58047433ac6449c48f360bd922d28f180b8c88629b92a95bb77501769136a98b3f2a12eeee8e53804cd74351a6b2264c2444a240b25c9330580d820ef0cbd726f6e1749f6faf279e37d1663976312a4b485f1e18abe117d2ecdf162a1d116b18975bc27b6e806df24cbc0618574485beab41b8dabcfa9e0530fe93d20147ea837038e13072a496be7c23ef60a074574888d979b6a690a4cdd5b0f67921f20177ad9b782d86ac95c2b4acd297fd34d84e81be44750f0503ae406e6d909e9d0f46a9009484942124af377600b4a3037f68948f14240406a38f501aa1257f4936d3a0736288938b80a2110c6a2ad1ffe29445959a62ccfa95f719235e4cd94c83a863f75098cfee97cf6c7d5b0dad3759b35db5ed8128cd0322919e2fab0b7d08ecc302708b99df12232d1c824344fe3670a0c21534f89e0bdd2f7740dc2ec794de2728657cf141e0456cbe33026be29b8e544f6a4e655bc6506cf9e9540d80a3b92bfc78729e5523c8f06d4a942d72fb1bf7cd3451a01c0904e7980ee45956d23cfae32144941d336cd397e37d509e6124216742ec8548210b9a6c9cece18671639c6d704f63bb6565f7690f7678721a690af9fc2987d0548595fe30dcecabf6192d83c78f8189260caee6bb691d9e5e1c388a1a4089baf06861450ecbcfb02efdf7cbf0a8ceca30eb394388959f2f2375cf46470a9dd6671e306563d697e89c7b427bfa7897273292062565a4b0a3f85fe76a015cf2ed6e4e33417aec98284e41dd54f517c69324cd5892b9cf478a8440b876e37d2b6bdf2d6833e91cc56071aff6dd82038f0a88bc643f7a64bc074518f8e200719813b7a096f4e435f632ac612c6657a4ebe74d23aadc5b5134dd160a474a1a0034352b1daedddd909917d152ceb277cfa11a74973f15c2803abc6d71fe45cf1a879adc8824246f99a8c3e00db7b29c5e1b3058b7878fa9db805fe1da0f2aab3e50f687b5aac7023f69c779d41110cdfb54beaad3db9b7e139be161eb7b381debd203c96d3b71dd5820e229067e67bc44cee6f5416fe2043f70a46a9ce7a88a4a41b037f501374cb9968144aa8606ab69096c65d3b6a6d6d9f9bc845e2d09011a0961b64011f35a737b46b4679b68599013b56e54b5e277eaa384b819ffdebce902a64b8d002c094124e91e1f17d4b2bc8c20d23510b6c9817e45ba782a94284683fd4dc18e474dbb636981adead3251354106dfa25c1ce77da0c0130ad39f1977d592629e1125846d6a56336a105d8fb58d1ceb641ae013772cd3ecaf0b48acbc4bd3ff9b70565709f5989960397a587c4812e8cee5d01e27ece34f5b16bc86c37312ef8cd7307aef4e6b6b66ba1fed527dfd5ae2d9c77f3ae61c6378422f422e9ccc85541904d391dc4fb7a0153baf24700fb94965adf575e1596c694a3d3a381c6d2db755f630c490017e9a4ddbc505b0bae695a6d42dd2a492782cb59c5d5bf5922af9b5f3202120c53b3eea8c9f2021b0dcc3c943e1ddd0e843a7d9a8ee0ced8dc87a668f6deebfa164db991e1b032fb462585933b6751032b651960d0f2d026eaf07565ffa40cb8b25ed15fe84544923eb111e29d2efaffdbabfee193a5dcbcc5c30def70bd7f585d37cadf6f2a8897b0a5ace33f8302b64b284f547a59ea976592065a23280b35f2780231becc3198b035913e200e6e78f38a3ef9ae646877463bb09c326537937639be1320652dbbc72cf2b645055171bc9601cbdcbaa70eadbf64c54fde5f78c42f17d03351f529b2f3cc55b1bb9466889013c6074210694ba8c3944ddfa8722929e668ab163625f7cf03d3a61078fa779879d71879d9f35c1829c26e55e83adf9cb255ff4bb0ff7fa237899ddbeb2b71fdf93fe59de5f6418793464477730cf1faeff90781cd1ae17df7ed625dc71e3b4256547fd8586a819b0f26dc7f49adbe7f09fd7260259d5845b50c43071a2b2346410b054df91ca0b1ef371adba99a9d556be71a95ad49980d26185a8c6ae7808a999a34bb9375b423557648d6ec92d1a68e8aeb3152257fd3573477ef62471562ccc4474707c056d612e2f1863fffd44a0685990876b1a7c1a6c68fe27a1127102413b432700ea794187c6f042718ff6f6c0d5a532514fb5c83aeae80856d64f0d5c169e4119e56cff1e2f878855bf37df1a5fc22cc0c6c98a933efb111054a7538bc1c32976eaff63040876a34e60eb67e442f4c126442abdbc764ca1673e9a8a45a766e22c30224a2c41bc9a86b10d6d741837914eadb275ada129bf185b0b9c46eb35afaa91f133d5428d1fc0d251ea7e8e1e9db869301e22078810d9a459a8974cb822724f588298a4b0b25c69fd6888c80b94df1086714c726af358b756f1fc6360b469571aea4556fd16e8a2760a2507d92a05d2eb7f6e35e9ff1ded52175d7b163de694a05307c59ab70071fc791c81f0b8ff979e164e3d0e1bd3fae6d44677e4024273174119f23bc87abf1189d5a34ce780d754415e295301f711fdb51c80dac45cbb17f40095220a97a113c50aea2e979e044aa17161b2ae9289f408cea251fc0a36f84174c70dac9d7d4aadc4c3ed722e7c2ab3362e7e02751cc9f7145af7821fa032d5b3aba9e7fc3fa4e358501eda77ef6138ae9ff0e0d1cf1bfa184a350a85b5fe1e75293357819acdd3afd62137e1ff59077f0301d32eb45ce0f98d46a4d46727b091a64f9a798093b97b92eab9c249b00ad3674e842c58fa9329f1378297a8a75f1f41961ba3d9ebaa2ac65354d92af723edb1140eeb2b557117f04bff12fee3807f9545998edb4cd24ae37ffddda6a15eb750be48630bf0147a7c0f44ed909d96bddf04658fe009600344284124d14327f0724732cd16d26d9c4271653faf0646318bd4c9198fd8a7014341a0a8bb02aca93268aac4b99da82c7e5587e2cd51c45214cb7229cf9b43ebd20c72bfb14f73978d1a42c23e4a19434d1052cfadd44c3b45122ae519d2023d8bc19f61fed2f1cae851b94ee122aed9c09884b283524967ef9e0f80fda203827de0562e198c2e1f0936a1d0dc14c53e4a64e2de08e5cd384e32caf568e4954579c32a2fc83b6aad4adaa702b0e8d64ff2ba18973ee6d49a35f3c805393b71a1c8a3429d2ffdb623b166801409c82f00374482053462dd309db084a50b73f5ee42de462c1d4faa12d3fac9ea167dcc4b7803e2315bcca7a75154f5fe1802291b5eeb94647c580b297d485e8cf17d47b74dc55632fe149cc098dafa4a8c577c0d713db689610726ef5bb95f3e4ab1efff63516dd143f51ae6766f91c826df31f9a80e75b5ee97bea1e04d80677ea5ab55e08fe736d5854746185d1adc0ad50f3867058a3439d6d38618d85018251831d37007818056263c73993f21dad787ed20e203e3673dff800071902fdcc2089529557c86a5b842e7ef5c7f84022a1149122a8e17a059c551802f07cc64bfb93b69b116c247f26b3e6bc5107af75af33383b87313d3ebe6753b6d0682f12a4ad0b79b4e23a8760a8bf7d03fb4cc6e65c954fd578471313115ce7e2d22898892ea363828f9f1a5980509bc78ce5d32e048a0d86533c881edb05847e2e922fb12283e738f69c17d79229f848e923062247ab94b8d17ed6012d258695917cbcdd64a1913aace0b10a61c6c947798f42ec81d84f2860390d48ae9bcc269998f2c79e66ec5bea917a849283c3c705851b90043dc9c784b8e5762c99b03c4696258c194991e64ea43ae20dc996f1f86f9db8e670e56054d126a679c15eb911fc048700299b6ef609c9719e946381850d8129079a058ceb6252aa2322b2dc797415e196663f7cd40c5edb42583769dd8a547a4a6cf0a1d7f169796506bb6cc9eb1e6ab4badeb91d4335e6a9f680cdc4060b9e2fbdb87fe950ccb19928ca1742f99aacbb63c2c0a64d7698f654745d34155ccfa44c18c3a841390b6d38c97c0c2cd0510582ecc6bc3ad17b26ca34a2fb215b1a6e112ed79508be134e09ecf97a84ea5fd9eea2c610e4aa977da1cd9011207630af99bc0ebfb13da475e51a8b92bd80ca80017c1adb0b53d66d009cf97e8598139cc072c423441a75501f6f45ad4c1afdc6b7c18ede322a5adecca571632a7ca23e259d0b3aa7f207305f23a17e45d4a20deb6e684c9dde60ed83b6e121ce158c704ac6ee642644befb05667a4b5fc4c01dd37e4d476adfb6ebaa138e93648f17f90c963a989aae13e793d29e1488050d44ad528692c5ef8444193c4687d984ea17efedf49cd452264ff6916c5c33a5306323adc1f4859fc30df9c4a09dff6eae7240a7ed4d6885fcb63ee56e975eb90915dbe883501308aa36b0eaefed2da7d5f5e7f10e37c544df6f643a7611c9947346b59d71cc60c46a1d5d6c41d450dbb410cbf79f17e202c43788d89b275d838352962450fad12b2348404315c347c994688b95544b9f85be0cb3ebea3d961b99681a5b9bd13c329aa23d0a6d2ca80551323394e1fc76ef27787d0eb4b89606161cdb68e5f538a41c7528bd9b525624db2efa1dd18be7f14e7e858cab45b2306e726789d1776b30347fe90d023495b923b74d674739702c9b9901cbcb9a4e7d3fbde930d6ef6c1775597df630baaf859171dc51d1d93fad28e8a452ff234801a9ed7d2cc2b1684453bb99527263b9a8c11d654ebaa5c4d098099e49332a29dfb6113293932dc50d822bd19af295c1fa8265262dfa0a5973e750e33ecd037f8c76538ad373ad9f63b9e40e4dff4b85e67f79660e27ed1e45d10d710ff4b92e0e0a887bc72c915e5fdbe6a5f2648ac95f163a8edd061bad1be3234b27308c611b91043d99acb0f64ef6f6ad04d56bbc4e779248775e1bc128fe0118e33d3d6a44c0efa759e7d857a77b3436f6f03d455a29286c20e6d9162cab9a5a0d24d1c31fc7db8964be9f4fb6d7435a0f2d165ba0f50010af81e0527a6170e738ac0d3f3c1ffc77b2cd750627a768cd1200c86597fc8d7671a41f1fe151ea7437534874612c25cbe5a29bf7192c5670b807de735659a91990d10938e0cb80e9a3ec6d5f53401f3670b9f3c2cc31ed0e6cc1311a0eea6989f92c9e8ce89ae97073a0e84194827076ed2e7e2e540485e5c5cd3c68ba16aab9b28346116a97cf101c815257cb0012250658c798a256a8e8144d3eb0da89423721cb0a25132217968207a076f8e0d40dc0607358a35963e6e74ca502187012cd8405efe5070064d9f403f79cf56f66a0c0225a7c7a1fa97d0ef6563bb6a42564e43539fc60006a717829a05547a3b5af02c43cfbd40f196ccd5c9e4f037042c46439e805dbeffaa7ad0b5d3018f2f3dc72ec8521e1c5fb974b90503d5c76b1a80404695f710028f69e1f87d34deda7b7b28058a70ad53a5f74eb429c44a52f046500f5fc9eba780256c6961d14835dfaab413b21fde04a2800dfe89096bbc878648bb6880680d9047479687fceb201b1d57c0fba429aa967c96bef8e6f0ad7136670656078e3ee3fbb4d65cb0af1d4f2a0a1b85fe8e0862267f748390d8d45eb1d16e0fa3631fbe0933de0894d3c9697e5ada267cb8c050bf80906ee0cf5fafe4517cb801a1951b17088ec2512afa0f4be5ace3ae61c343c627f78e354bb97cd0629d1a6e924571008a63440fad7d5f69cb6378a2f3f456d2ec4f617f5e8ba8504dd783b650c988e5b49585048602970a1b5642a00089405d71ca4f7b40f617bbf36185784fe04ec4d9b5a83ec0fc96e1c76868e8ffae0e7532d6b7402e5864dc77eadbe9275e403bbea8ada205f2550c50880e9b0342851c5c53007b7d8520847fa489c60b3541aa4c35a7856af6496392486cb14bf83a271a3b693f742bf102c2635b03c601cd23efa33646f5fd9b46fa5e44204727ccbb221934309c111ff8758719693b6ba2e89d12a3ab6dbc7b243f4bf6c8cbbb5d257d00e40f3e1fa92a9b8e9e46493256de71d1c9163922ab0b2a7d0a9f5cc9a8ae335d000918099ca029229a66de2aa651815c8428bfa1b94782f799057549f606fb8ad3d58cf1a37065da603094eea4653bc593ba402fbd7b20a3366c246981378dd291aa7b44442e78bfc2084ffdf38ee82b8d612c7f020babeac14ce5e3ba1fb707dc997652417564188382db5c25be645a6d41b16e817488c1a5120fd866885048788d075226599c81c1df626c59c5add1e5fc1962baf239237f6430c0fcbf97ca33111ab99144d798e18e664d5f8e852eb48d85396620b0f19cbfd12e0d867aec51d53cb01a81382e184fe12b8e90f7ba568dde8721f7abfc30ff322cf097b48b8eb1ebfd004fa5aa9600184ba35118a8cad1620626be68c7bb9592970a2785759d6e86b80a0d39ba9ae6823d4c810a286bc913df00452d023c6e0eb2f04453fd514b413683505c662c005bfdd9be192be185add7af4524807145492000d2ba8426b0bfd8f5de09834e0ea1f36cc59e79388f0c9b695fc273858ae101d3bfd2464bb53854f9a82418dc01f374dbdfbc5655b938c3da8dd6a0a0ef05a0bdf496a7d24a919181709c5ea58313e4f5aa1c1cdfcc38d146b4d784bc92e95c47a132b7023b613795646873fdbce42803e05d0cd01a9456a3144b18020e76e185d232c6edac45aa67b135c050526101ef051fbfca73b21c0a02cc5a9516dd0e04ea10ba00e3fa2e674c251450122b9f63a24cd1f262344f9350647719dd8fa4c24eccbaef7c4768a043cae22a5bf7a659198f14ad7cb7533818cac48bb6fab60a25723aae79572e14d3ce7bb56f96c38ccd7074a86c5743ee6ce79036e66c7dcf7e119d5cb789e85bb10dcab84b35900e4d40d66c1c34c4f2f821968b3923fd314bdeb55be17aca04245380daf4d6624866311133b40e4993951ab5630f9940e8ae0502f8d62678ed5278773c3faf6fdf7721aa02af6bd7a7f8cf2f71adf29087aa8b6b77715765826b9f7cfa73934d1c16c50e8f9101de132a073a7b3fdb97ba216314bef4a53bb8dd17bb72050d5e4a7951a176a57d6a9b4eb16bf4aa854210b7496ab3a461c29ca6bed739e81f59e071b53447c40be7ac99bb6d166de1f99e073f392a193bdaa7eba1ef3f7f5bbe1c9e92e063a8a816e8ea3f3ff2e70ae67c4dedde7c332d6b01fa00b3e8c7b168791d82b8be9a15d6118cee92786ac1743914515100db77d168a298b3034ea20e4a4d5d024a470048598a83695829585f56d995eaf536ee0dd0089fb9c28184563dc83f1436837b83d7cc3729c3e9e10f26fab415d501835712bc23eda7a28c49a63a5d07d202aa2f6fdb1da32dc38bd24110eb63c8102e11d5ed1280b7ec3f741b7da61e7eddd1b044a973750132aee7b96c2d839e0d3d41d506bc4e2cac0d001170cfab6e2aa593b166b19b9140a4f472f02a51d0b38e31165294dc7a274ea029eec584048b2332d551be042a60c59cc91149f59b46162de580a2dd2e2e7d225f60a215f7b96b89968390c1496c075d1015fd598842b8612607d07212a77294fcb0a3ff122eff95e06a5a208bfd4a6a91622d34518b43f5c869335d82009033422fa0383c9a47c21a2f00a80dd96aa3545e1928fc0e47935e2305da3e61e48ca4d281fbb197c0b91c43cc1696ad70d51197847dad972cf9238f10ae36552ea649d176f99f987554654a6b24eeb74515a2e909a2718594f4a3b47b385aadc00ea8c6ea49e2c2f67233f66e14014592f92cb2851836052b393df3df7690ff668a34144b2fe60917fd8ac04d177c3669d12cff0be796aec9e94ccac0f0e024803def499f42c8edcca491055984141164ad60c442a9e344b62ed9d559095745ba141602fad45d1b0562d185e6bb8421ea34106620010d574da18ccfae55d55f6a596afff2b474b8ad57793be1d888fe579e4eb6047f7356e68ee30c442403bba346bcb94d66620b8d24ab0382e818fc5de51b503c6f8485959aef311a511dccb861f546a9f074dc0ed2028b02a44805efd094051c4a1e01d221b7bbac524a60cac58667888073bf6c4803e037cacbd4736bb1759db6fe3ba8d48298e8adee76750e04a2a4cc2c3bb2292f3122468a9b4774e4e91d088fb524ebfd01d29e094cde2009fc7ad0ea755dc1048f53dedb49bcb3d8a128f61c8f6ee56d8ec2355bc5af5e0672a9a0f41349dc3a8abea87c0d9deb8693180736adcdd35e07e75c98941db24d6fcf50bfa9a76055313fd48a8b6f5e2ff3312b9c492c18ce7a02f6cae990e7705512441fd1ce32c511127be3b5c6041b76d3bdb196affeb68a85dd6ae813cfc7ffdd8488ca98227914a2bfd21edd4e80e091bc8c3258540f3a9055edc0321476f940732778d9108ed69971c0c79a603cc46a5530199d638aacf3edd41c8d3714e6d4489f31aaabf52fa0a0d64743e87ee2e5d8f9b1b56365dda61731c39f528f477c2d232d62c25ea7bca7eff94333e9cc22a9c127b9d5e46fda01fe421fe41d7fa742c5a847bd351e9681830a2cfc31ef7dfda2d8583bfa70189164754ed51e284893471c2c27277a98016d5a330930fa3247ceddd90474f273a09f331eb38d09bd3152b1c44f5fba780c90be1682f4315836691597fb9f43e8b3b35240b80bee139034eaf42672b3b19014954e1f04ce9552d915dff0a9492a37f6f5337d4df34fe112d808bdf25ebc349c6f39ecc1cb74af5d09c193d11b3c798f07254258fa60231e6994b609c0a8688d707ed82bbc1f2c86ccfe380785bab3864d9de6eecb703f2119491ac75ece3b445323b0eb24c81b6890d5212664a8eebf31639d2250ba96994685805762541f83e458e8f92d603c08ca8c17ed410f4807b06a68ca6243052dba3d3e6a6e4d7ac1160f9e83a6c4a9653e718fd8a0d5d0200db4f5695ed3ce9fe5d74f104b509e917a9f537191e36ed33b7b42100bf2eea794d8289967b95e7e37d79be102ad82ae718160f1afa88c76ae2b6a617f7e93bc7db88e16793d2ae0b400860a8fc6eda1952c21931799da4d7475828ac4e29daef9c261d69c4e04aecb4340959db8705445ec0069dec6130f1d18a097102dab338325abc82800d14818e9924d351f44f95773d04f1646dbffc889a88bcd28467d6eff739443b8823d9a4cfee693a96fdc15da5a0c17566ff6dd7400ef44e48088d52ffca79ce68e2e23d73458f65bf9467956c74bd504377b207b4e605bbda5c8e6750d7b5d7dff79339e0895e314a3b7bf063d8aed54dbac394b6efdaf477768559e5241082529a7a1208e2fd5ba55d85e992ce90d1c5e44a2b47a97ee4887b4ca778d408fe721d0f9354bd53cf17c969f398a76e721a2f92e0b68e4fb10891dcf060102b484532149295345eefbd4759c0db7d8cf3dc88c6fc34e8193e93abba1622f89840f2d21f72ba4ca447e0b6f73222a32e56b5193ae4f2d2771120d0228072d7218ce77ee8197fc01397ed084346eac458ede2413e411fbc95b91e78da772091de8592d8b4356d43e81d1aa8651e463c219a120e154abab04ae4568b463f104b57296a9bfb39100d49c28cf1c719806fe0d79ee3d5e32619b9fb41c510fe83ec729f218884e7bd181eea68f415fa688c4bb37316878ac5c4c0d666a5d8135a3d6c827a00e2b9433325ceb6d7c0696d8feb1c950fb150ed54a0dda88a563a84df2b5e37ea0b678cab460c84411f1538d0dd65a3ec5de4cf0c3ca8b487da1445c6e1a02b97982a719828c486b34c59ec0c16f140e44813e2c38e1da7f54dcc7c878281ab1492167021ffe40a9b5c56715f051bf525becc89bd97e543a5120f916aed56d69019d8c1d703d1a19ae38f1791c4da632f9d0632d000ebae327488bf46391d0abc3c1e98131e95823c083dae1a30860761062cd2d3cb9c60463cbcb67953f019077f52419e385f410119636220194d6d1c48cdbb04d933a1e591ee8f3df70d33a92841a57383610298606a421e121aec7e35f1222585328614fadf7674414e635b36459bac721c5660a70d9293f4fd64d9ab6265e7a4de49c205353c8f20327dfc910d531231da5a562a7e28ae1192545238bfad2e616d6892532dbc09034984b5905956b2f2794bbeedfc3678764ec104f8507feffc79df90c00d614914a394954f45575f67fe4d6a2f823bd476d5ce8d252b55175f698d725bada9424d08b47413abf077ec37c03dcb1da1303b8d97e9f1a1c227a51101f6d75921294074fd37370a0d65541fb9fa4977de1d542b98d94742d08211b97a483ff63e4976a36f51ddd197a4e865ec7c3bece84d88fb3659873e5a2cb75a18288204276614bf7b516fefc2300761dbf29007e1dd84db6a51d5d02dd5ffe26010f2ccf569eef88e331d4d6e9b1b6d3be695215ab6540b5335691721decb8bc1301c0e4eb547d008dfb916c49debf5e3d5c77a5b97cf756459c5bcde33af75a1c9f5b432ee3a79e77d36bc140971d256e6a211d5fa17644a06cbd00e7ab791aeb804920d8410b5b79b4e90cb72a6b29aca3cef5576e268f812d75bc973f604e2b6b4e5327194ce84fb7b284d560589a67898df7d06f950f1300de90fd34dc1d247abc374610ae63c971482350d986ce88f111571a4165661b91800b72be620aad9fefc82310034053811a08f0f0aed56a4d8f9206f11514d1f0ac16db842515c04fc15be54b047ff9dcad7be144dc765ff566908f0044293ae69f991733cbe38652dc66fcc9413af71f4924e36add19a907756c38b3b5b801a561953994a3befbc082d13941a26ccd8e97b8fbe9d9edc7f1e827b0ae786657d97e9fd106d8f91e6897ce945c81932437b85ad516698b6b1447bd8a5298cb87cbe8616e69017a2314f53ba2af6c6ecc00fcf9a0da605a1dd220f483d14593ff533bb2e92cee4746b4a833330c9cd3bc648982e176d41d0e965ec1318ea6809e1c64c63417f87983714d25950d26e0e56fdbb8550baade8448fa485cb2d804b12016be1d9af962fc6f715af9cd141fc0b58f3912f599ee1f8de42053688b0274cfdc207c413296a3a768088e1f4e0bf6e45a89133932e978dbf5e3a42f71781a845be8b484f40114be285a63da57b6e9815bfb9062dd707f8e1716f7b527550b807bf6285b2707e9df9de14134906eaa0e7409bf4043f20671926abfc3d6b417d748df1cc1be5c688fcc91349a224196e9421aaeea1bc67845c58843e1a92e37fc903ef76e52f1b59018f1e4b1178ca28170a622bad08664350191cf3f90500244dd754327407f8ed1b3629dc3e8c7a2ef525899a8ce551972cb290ce4b0006b9d45e44375039b0c194d1ae29381500e3e8c51d3fa971bf48daf18c8e8b9d0763b8f141961e80aa2f1ca4ea20fafba97909c669fa4fa9db27cece60092e3ac5c7349985d925baf86db82c86295973d183cea0611eb57b4f9170d6a4a8f066230dbbe15ef97d14f22308496b62b16423af6c4e3d32d97539c01735a25548d0ddb49119a6989196bc81f372e2ede51187d0f1d1c7789f744de4a87de6d0112206268057e7fb982681acdeb6511bf2da70ec3a391f1542228c3a23b9025c158b83e00f03da1bb9e3ec6c2fe0989c519a9e9e21b4f0d8e07d2367d1d5aedafb38e87be4f808da21ff13417f8be908181af67ab3b51c8c121e8174e13af04fe85b93d4651f541f6db745b3718883726a25cf9a0d9283d1e1e8d598d121859e8b509da3e64aa798ad086e29028806c2de4438d3775a060943d0af375bab9284e3c3a131d981c8cc3785faeae24622e5f87b06fc83119f3f728400fc7d790e70572dfe909d11013218ec3e5ba52884bed9803797f11496292f73d795ee0206ed23225b5af1a9e8c722cb081cbc97a68a450d455e382fd2755aff05da5bab498c90abba44b3f03fe9257a4cbbee1291429d986f105d3d8aa736bdc624444740e3c744576994fbdbc7a1bf949ba99eb113cb3d90ecada91d6b758fbf07fe79c56ced06962a3d51181d8e47ff0a66bea5d4fa7f3d4d9a7681b99b497e57af3c437def6360a44f3ab9c8b7d3ba0f21d73eb093336846324a120e47f6537f532a8e7a328f53a9a8be269318f31ceaa25304a0c4db6e0ceda2d2dbc504cd174ba6f864510e628557f13643afd593c2e382339ce3c6fa24c00221250cf1a9e441a35af53ea6de4d014e37a7cf5484ac45156453a4c5565e74369115fd505e2ff7fe00a296712612d3e9714a6a38dc4bef3c308f0a62f5095588d2957f362fe5f440d820d94040e628174b28450f781771ab234b03a282a0b93b325fb5ab4456a32e071ed83b539efc35413e5734fb527a73e4e094407fb8e1dfe2cb5d7e6e1e4335291f5fce22afd1661185211a5fb0f6497f331f7ae3b061313dc274763de4ed1e7b9feee9adc1d319fb2874ac162d99cb4ca56852017cdff765021a388689ce8ac35b771b5acedc6f12e8d377a3fb10c126e1277a503af594d6976c6d010158ab9d8023ad011742b7e035bf9c29d113912b514ac01eef3d90a27845a4094ccf63c8cce7c3abd5aea13aa45a18bdc4aeb6fb72e489b2285cb736f556e712a6e1088f977bd27c953385a4f1db7cb1a9dfe14774f3b4dde20bae242d388c90b4ea63fd515330ada29a4b0968873d14cd98d0cc88d20a67f0444dd8e9486b0a957cad909885705deb791089b40e5e8dc4f21d830e9aac746c093d2f1923db53ee725f22da3ed90e0121ccd0a42e169586e0fca06c3e4e9fe7dea2c232496c625f6011b3b6bf8e21d2bb61aaf28f7fa3afc03b7e15e5bc40f858d723d1367e65871d8b25b8b917d8009084e69032c0a618e7b5b218928b01027b4cc8786dd2f4d6a846cd8e22f585d985e0b8300710396beeaad4cf252a27576f1459bbc3e4eb7c5f48cc44c1d5c1adc721c538c18a432293a310e9eaea5a1d0736bef4bb64c6dec56fcc2a0d75ea141722fd2f8f9ef1e15b70ba4d678fdb167356613e4e264181fef776b60a605a39629ba7c8675c456fcb211203b34ea72deba70129d399bc749c0411c7722cffaf43359c113454c07c5dbfe846660e374bdf84f022919ac66f9b73c3defb6db5849235548dbd857cea9e3005a31a13ec81c7a08e14398ee23f54beff73d8a8eaa0d7a658ea1142b219033070b373bfab879f5e5ee9a9dbdee9060d68f5e04742a65365c23685db4d5ada6785ccf70c96c185eaa177e407236e27bb4d29b011a76be2f323601103524a6678d4f88df32e5855b3fbe59f0b24ec285e85576fc6538a7e9cc75534e70816766729c05198fddb6e9d6c248d4cbb5492f10f8df502029027823f808dbe6b42df07953648d789633607a5f1d9eb5e97c54abb1c8f74f1fc14279eedf9fa96a2090083751e866af3c9ee394fbc464bb5a5922e65722ab1523502c0e88077f7700861148da0410fabbaf00ada3c88eec1de7667cf5be321f77838ba587be1414e9ff540ee4b1829d38d06930369fe3b3cb206157aacdbc26e446bc21a14d49034627bb476c9b620091431ea590dda99280725277e81532655e7f1e910470eb26b33373e3ea08d0c76b4424ecb0d79d78734df5934b548574b5944310697556b7bac23071ad838482192c44f7cf829c1a449d4d4661ca3a6862350ba1078e63619c5198378cc83fc1df7168f3d4b775a923c1287dccb4b8dd6280c5294ba3e59dc04adb14f461c1e5b7de9ea9aecd4550b85b681b66c6b637d8a607142f2d69ed1c25d6ae0c5525b48a63a13ad597303b451be63ba66eedc75ccccd40765fd9fa853a81e63e83292c2de8c6d6f415d8e6bb7d6c4bc070eb9a456a2cb5a6f59c532aab890a2f9dba868a1125817231eaff7e59268376eb51a2dc920d182d176897d5847b49c217f0322e22c0aa6ce63d67110bd3944a982125e1216505da7bd61cf036a548197034a7cc58612ea387a6a9dc9fbe14908908f40c06775da13e384ac2ad72e404435b387fe52237082e8e708d87f29def0e6f44f89e9eb85f3560d5661139281699a8f970408881320c1402bff78c3569c9484e13398030a464d8d764f6f70d137c341d5fd111397a9cc0deb4fff2a253a6148fe01ee9676ff1ad3db52c073537e72b869c4d247ee53461987b433d50c176b1b26bf032b8384944290d5fd8f6c7e9c1e90b91b1c15bda0eaec5dd6aa08b9ec32852c60ad47c4a7c846d6954e88da3586bcc26f1271e90888266f54b54e3bfe31c02a88a50aecdca378cd81c02189c8d46436ebb4cc9695347d33536bacb80d6666b0cef3f3a3a16a4b631d197ba1212aa92164d61aaf3bfafa3bf7e691dc2363f121db81e95c49c8f84ba8e26f54ebb543bc7fcc78bfd3e83d550b30b7e55f90b1864aea21c4babebeb3a09013c37a02b193d15697104f8bc56fe431f655eff81170712f0f269812600215c68cc1ea446548186c3c86c43504cbec79a8a53aece6c9d683f5de3c5fd588ae52096e3d9c1efab578fa0aa902257546d73420bf6b84954d7b8d9997e9f204279dca44742bdbe9e2ec542e69ea41927bea276dc091dc6409ce3dbcc514944961ca08e5be73918f6431acbedbbe3ee1443345a5142eac0cd457fa51671150092f3f9137f83866abe5e8a28079b36e8cf042c122d723f56d7808ecf26b1e2c3ac53a12c3247b13a13d5c0790baaa883e8e696b799b23ba58ead308890676b35c466106442e3201418618589c805b7fc2fc2a6b023d8471dcd6c083c3627c90964ef5313771e414cf48cf4afe6b6508a99202bc95eae717769e52ed24452c267b6a789329e351aade4756027b14949a248aedc23aebc17afea089924e913c6830cceff3a670460ba0fd0d1cc6b96e0cb33ea64ceb5b3ade67303547b7330c0d9ceeb6b2f71e6d60cdb2081982483567da1a1a7f0a413b4c6e720035550eaf902f34594addac78826b09b7196952eb72d924782296790d6734e0e3c29b414224564ecf307fbc8466b70ff638238977e6b2b1bd0b60dd0f1949adbaedce51d778e3a92296f96cbc047007c457de78093d0c6072d4e61430cc89167fc073d2dec81923acec6e5a896ece6307b7c4a62c542b4995f3e16a81c6fcc70b58c596c3e1879fed05c1e3639ae61504c48ecaea18e2f255ff09ce0568f1ad9ed298022b27980fa9da7b5d2a84e4be56dbc6f3813bb443892bfb698da902a9d7b3f85a86b9e6f34172e6be038704ad825e8636cf341e9a5b1c34d53b7636be62e2cc3168fdcf99c6d84544fc280918134a5a6b35fc3b817da4dd28711ccba44864cc4f74445278c841be91d4f8f8a6594a5104199e97575938dfe086bfa4616b742409f06f7df7da00ca54b986fbd20bed4bc881050d7b5c62a9633a778d15ff959b2832aa5c5565a55c5d456193ff6befde5f7be58d0054210fd9579ca64ab835cb1784ef6028df3a65c236c56ab5e960e1d8b1c7f2503f5cc5ac4b25e58ad55b452917a9f62d98e94d1fd58e2eb2a52f9269c14826cfd2e983657f83c1536b25cffe5e5c753aaf6a6ceea7c94302949ed7fdaee5feacc2f5d4a5659dd673d9fb45b948e8c36a65b1aa1f2b90c94a973938bc185a87d8563f9a9b3beceef98d3b4013b31f4fd9c92c6cb61bc65617aaecd4f5ad3dbd49bf93520a77cd506e41c28226aa6dc16f4c25bacd16bc889161b9ec39446b1e88e9d65b1dec8d575c568511d748d1b2e3e977b3fc91f2fc1190f0473601628284d2814dd681197b9a5244f379ef286722203997978cf5f830391ad1acaca6b910b28a3a894f807d02b30bdbc8a2bfa649b1a0b10956c055311facdd3d5ade6339834c085543ca553d7008103f43b58cc96a4211f35f0de33033d0e73d8c490e83334d4e7c8b0a8dd8bf686f4cd26e79d191a6675ed85f72c52b4a86ebda19cd6ed01692fa9263ae453462e331961b2a862ddb0b79a3341cc727fa27d4202a0bc98cbbe698848b58a0ea195ebcbcd2b58df7e628b69615ccde5aaa14f8eb9869769614c64e55355e7a64fccd48cedfa2076831a0c0420d736ad59ed31a65e55e15255729e2eacf88ec62f0cb69476ecec16a814f705452c5ad6902f72f8e3559a838fafb4acf35d5edb502b9e5f2c5c1517b616a1eb76c0f9d6240b76bdc5ebb0ea3b40145eae000fa9d42412fd3788d9e7817185b930a6eef4895c61c37fe7cc2e3f8c71e5575cd44662e08381f314e3251e35a24a680b97af984818d3eb8871967ff84c0409c89a1c70511bc3455379204aa6f2764eef76652335ad9a6d1632d782d3b955081dc72f9e2e0a8bdc2a42c95954d9f7935d0598f104aac431b09d73b58cac47e2a36e4e207fab3773390cd83e50fd37c0bcfb587ac99b6f30375e980a840260b203b79a7afa81823cf02287609d4fcfa146e6ac642b4158149f7a4cca0557a69d3ff5f733edf3e06849a0845742e0e11432d494b6bd65f3689b2a67d531ab7c5e82fb70ad2340e30f2c49a264496d0759224323f63a1895a43fa3c44c83073d943648fd414b3f74f10e46f770adb19f5470b7da00abf5ced32b191e3decac62d7a97463ca5244b40f915955df7fb20f662431676038156331062ee94e1347c5ca0f181a65049218917bc12405e33cd2fe3ee1f468e0726b0c409af029bf214d61dc0c0cdc26955765397c77a12336224854e61959e735b0be7b501e4271f0f19b2d6b570a8cfed4093062293ec7c2c18e22c7cadfb4e2fd62f5179b32e60a376cab08319b6a348108d2a9deabbfc07b9526d75a32ad05085d9c3a9b9f47e6e0410948793a11c96bfad2820c6dbf540a60620bc0efc338dc9522be3e8574c422f7b0f4bc128fcd30dc95fda6a4a73a5c2887620e5192a54339703d79b369117d603c9e1a83d924215c7aa3eb12bed2a3bab202ec14067168507376f9fa2dc4cd435fe57559a934d0d50e8574f5b811ea881ab579de04b4d46a55539326847741eb13dc4b400b5cdc55367a0dbd46060ace696a280f638c7956480fda1a8bd91dc95607f2bc00c2247b9a5eaf478eca8d1d8bbb312f9de172b5b6f120ff914c48eb7de349a497f4461a02f9b5e5eb43457bd2240ba523ca04570121b817d007aeeba11c17e756ddf3364bff5da359806c705dbdf8cee8b7e48dd417426de632d27fd140a53aeaa62293c5dccc2d8b6f4a9ac9b0734216294d209a58a788fa18c75ebfdee7a92268f108b12f4c1b83c9d5be8fa4e346877075b41d51a7c6c5e9c548b83740995a87fca255ee89ace12a6493c9486eb7dccc9b02d67f53b846bb05afc56b1a064d86080258d6175492516995a19a634c37707721209125d6362cdd600adfea90bad40b0eb3ec7f8d9eae2488f5a86915a29d3447e7597478530a2f086ceb2d4f582cd676467804fe98e280c381dcb2932889578ce6a8990d57710ad256a6c8398ee412649c14fc7fdd1a0f3a848d482d2e3b770e00d5eed8f26a12f044b8e57578687d4c93bfb88df125fc104de081b3a5b801e26e2edfb4da4e3257fd7d10515a2ef164ff78c627ba5380f704c3bc0c093d9b32cf024487e491f4d2beb110b8aeb8ce70db4006c240088f4d1a60e414a84d851501418b21eb542bee74d24fd3a6b7524b19491ca8724ecee9ba9b96b3f26d3e4776ffb93148c45d493a789d83de6bebee24461de41e017039d1980b67eca5c8489f14a4a75d2221bdb6d479b6bc9814e5b312d2aa485700190a83e0df213fafff6e158e50cb05c570f29026ad700ab9508df1c1c10abd505952ca0e6c0c6bfe4ae3b9ad7d5110f11325650a41cc050c28e90ce815c0ef7fb4b1e327a5cc2fe24afdf46e4db41517350372b77381c69b8d00a98b4ccc451814feefa516035f0b2a91bde09db77ca8057d4266b2951775955dd0541cb34d74a4db39d35de5f9291f4655c29a7babac2dacdad8cd37033b9cae554f05da38a321b205ec0a0805b85edf40966b9acf362ebb585c58bf467e4d5025f30dc1d52b997acaf80358711f41c4ee3da5c7df582e4d87029229471c5d06ac69cb5f138558ad1a91b2c7e5d5308856642827eb4799233ac8a58048dd2ee3a254a5a13250328a35ad75c505aa6ed342d53d0ae11b2e91b32f97aab90b0318a6be6742987eae3fda663b44812b8c924db6c539a63e74c1573b22b4b52dbb1d3a6e64c2a07248e0af5c7f446470615049e9f6cfadb2989eca66c4bd6877cdc4286f4d0eee92ec82a8185af5203ee8368730dbb0b9257afeca0a34aeed888672ca74b2900ff8204b8cad939d07df4c215732b11d4fddbf0fcecd2f41bc3028674bad903e4b0e2e362dbfbcbe471771de895363937a63cb5086678e3594e7c09cc29ae4bfaf2137e086d5d4c28a20aff0e24777f5c5aa0587a5a3e82fc009a9a873a1f3a06fba77772716228f1c7c5abd2a1cf38de455ae8bc2c5b08e9fd2e469c4ed41bc27de3caa3f82ce00d8f2d76089ba66d4f00d13d0c5c57287aa6b9fa1f758f8b76caa09b662964fbd719488ef500197caff04c751384a5a83e4efc7693bc727862c04231f9d1ae15b38e70cc710ce6d4521bf6e4e7b89c0b369aeb0c8c6afe240b22d814b5738936b6495f33b5f5cd4327e264a1acc9f7d2080038694af34dfeb4a69146e8b872917c6b5ad755e4338b3a191fd6ab53f465e571d18f5e8cc22f4633afb92d01a8408247e5449f3a41eb66c959bbb9ef416a0a790503f534801a95e41dcf8284b2ed1d91f2a4bf174d264a33ac7d82b188006c8510b0e394fe60b84f352c8f67029bdd15829bb65413f0a650ce13170c7a52d61ce26cb36679ddcecbfd34ca9a934bc5a801ffaa8b62f78a2add22ce17015ad01b06cfbd1c5c1c00ee4b7129ed0a142394784535ebb24f2028d9632d3743c63429e5aa5ec2f0bf5939632a569cc31faec9c0f962678c64615f7eede107911a7feec98884f94160e2527541c728e620f708b647d54d96e3c4e55e85807783df46bf7b5a9640f71c8ca1b7f35d369817625ec824efb6f64aaeb98a11f3d5197ceaf3f2129720536761d3ef4e0aa6e9cd6201b5393e55ea6570849cef792461ea65303edd41e202d279555107e2a8a81e135be8acef324c421d19335d1f63f7b612623b46a182a1d38e9f8e0475800e010f586ced1dc8dbb49751023ba70c27e4a7ac8c6cfc045b65fe54d7842b9eec6768d024670413c49eda57d780e3a745bf8fed7490fe974737a943cdbb9a1c7e309fc31148f1bd0aab135e5adf6e856af3383e1d7113491751638caf37f2ea9de3917e680c77fd255c9d938a0080bc9560bd889ffdecaaaffe432e4bc8adf53b0f99015756ce4c5e435094c5742e751526a59c212e9042967502a53cac0e541ac50fef424e7b19bdfde79c4d13d53e467892c91edf86c69446a5940ce242a0bdb726ca17945544e3979aa8591a090c27534cffe9a5aae4bf50b39ce66468bdfc7601e2ef9d47ea32f63e3a91c22fa4960332565401c977c98674d675c281ad91842aade990dd7325360aba6a77b60ccdf76beea285c15a22233906ce039b524d730af213b3c5139355e8572ec045d2392c05f0a1c82440b3df97b515d912de448646f8bc63a710dd7c05481eae14e120a25ce9490f7000d134fa9cf3e5904c7203137e5c6b7999d073950166a931c06454014f521c3c5280395cdf99786d0877f51f800b92774853c0f30059c8423771ea84e06bfba1610257ca8c989aa7ecd5e73def82b538d2986bacb6b0f458c067934cd29ad551ea422742c3e12924a7fbcf1165beaaa039cb5fbf55eb05c819ce95f3f4ec4b11d2c3655b856b53e106607f9e9c8cdefdcc88cece54b01c5f81b46146cd146b7826c7d9ad93fb9c186cb46bb7e258e5e83a905348171b0b0824e7aa121c53384844e542dbca334b7310436c0fe4d1365a2301e78f79c900881e124fe20130319dbce3d4c68b73290677495eedba5caa53f8ce246a400412f5f1f4be8b6f13f6e575c1571d5ff6c274a8064591eec224ca81146ad772d3603b10db186d22c6839597d89e6436fb28c4d8677010e7458a65651f928567d4dad0d28e1c4728f056dcdf30cea688d929f439986247e173c685394b07bf4b8d26e916874af3e0a6e650a39e2a3fe4a9816016d5aef84e3cd99ce6c1e93d7d56238f53ad78dc0f4c386a5c21d45b243902607a9cf730e4183518bd2d968ac6ca82b2fb67dfb2f46bde8478e5c10a5cd7167221e392f8478ffac9787408f35c64a3009e904186b1179b94d571a5e01d790dc684eec09828914f9c05facc660b003d1b98b9301d722f6198d040377f0b3e8000081676ccc0add35383e5b2adf3d3f8a461109e678e97697666712eac072090eb94511f3f97e905186cd32eaae0e6f196db5c1123437884480b2ccdbb95694bdc0feaf1f2391f020c9457b02d1939c83b386759c47316d2cdbe8c765f2e25df05995f8a3eae348d3c5609642417015d966aa991974ea66ff3176d08d00849d88808a21028a8b6ea396daa24d99330cd1d3f390db7ca46c0b810be0420ac4957a0e14a453225320501ca580345cb71b3b567b3e487cd764cf441fec6246e89b129004182b374ea4df53bdd15f4227dc88ae00c8216c184d75ea8aa4a5d604b0c4403ef80f42c7152bff9ba9a22d30e34487bf0033c21a29d6407154ad64e87e13cd4e2c0c6d0ee0d59421f678252840cc19723ab54803f1adb66eb9aa56465c079887d09101e62b23c4e513242dba9994dbeb241ca16fa8888617b6cac2258d507a4bbd8e428dbb8ec71d341c186257cc8c0a657392a239c9e2c15771d14e83fb8818757704d07e07887e106b37587cdf9dc269a007a31d5fab398ccd4a09549ab9718156a892aa82a26327347da40a065ea5838f4b208fcaa462f29f718d981253f769071ded21064702f49697ecee70965466d56f6c4e961b2317f379f657ef561a6d86b05535726e79cb89a6582ba228f29402913164dea1580003ea5c17e0bcf44a26d21dc189f1b5996351ebe9a9ba9eb08675d167208e1f7b8f3c655b05a67468ea6c7d8612ba0b7a7cdbcecf735568394b404c0266f480d1800e7935342272d346405ed2077d4b16529302cf50be2c4150a112bf770068914ed6ee2cb73b4ce68c80e087a31dcf01f53857ee3f04bd3d6385bb3fe4eb47aa682a9633f299ab45504fa30bba25a20181ea50365fee81889443650d29450a0329046b6fd2852c97fd42a8d6288a74733fb5daa8a5734901a1e8b0e40602a430d721efe6d486786ce9b85da93d80e8c0c12dcc87f72017ed466d1482344eebdb72444ee2da54c3205c10a8a091d0a1308cba1b64dc68eb0d714614bf5ab5e0e1d6dc5835a870e09fab0e97dfbee9de3d9e45bc132489ce3d1114e7ff1e30f3cbf6f228fe7348ed55471ba8b0716decca75e101c250c8f1d613e9bf0c40b7a03968518443cc142842221b0603efca00584161fb21bb020818926c876c08204ce5dd4576ee07e61b1015bdcaf971280d00de1d323134b99ea51a7582855d0475d3ae9bb4164e7c60e2ca3b1ffe43ff91f6a471dbd02d4e69c6d4347af002f4ee3a04038effb86fee6e104b1aa94ac815299e4df8c73f6c0b1c8e284216459c214ed20adcaa6ac3d928512848a7670430dbe60507c5005113ae860adb5292f70b6b8b1e8a2c5931f9e40825112580f561c618c0c0c1d72d87a10460cb8f8c1890d37f01026c9078717d20b0b24271886611804a6c082071f2051f485123e8412b0c801ab825a11461068b0c10b0f7c40a58b2864c000dbc1042fa31f54f811f358688ac30eb04ad3a04783fb25c50e1842083d5ea14165ce89655224ad70bfa4d062d24aa552c954a158cf81af570babfc8395d3b66d474cc22affe2b61991b84b8da37fdb5880f13b8f368ebe24b0fd7a15d5c0fd7a49c14f8750bd94e2c704710047588afb2545ab251936e84816fc19c5129cec203d4631466683fb15450fa2c892443d5284a31d18010544c85206abb528acb8200b31b4a0610c1aa81811a910e560ce395357c06c81c208cbb75108a9748840c83be79499084dc909657b944c53652050d1875e06fbe1959e11986300810ae718700f7c7989a832c5aec1fbf4522b36abf2e71bd65885e3c5994e5e3a70b53419a3d795a42cda0ca0d71357b61cbd9ef882014df11b29425ec54aabd5e1e4e81568e9538161bb10c202a0e8af4087e025136ec0b1044b107e94525a81a7115172f4e6681cf355c0b3051c6dfa663ee7cd1c3f5234d5e444707cf8cd99b95e20220752be1062092928c0747882f900290618866158bca1e70d3ef002888d0745d002872776488253ce2909a0c3133e5a580cf7cb892710c087971361d897135f946007a9c54910aa1356387105899a52428c51ba7faa7eea2e31eca252cf11720501fdc4169824a4a32d46af22a221215710d08fb7c024211d6d317a15110d09b982807e602b499118601812a407cf0ecef72a4be30d6d9f2224c51525080ad0931f9fd90a03e64b9217a42e475cb66831caf2ba526485a8cad0142129ae284150809ec81fe9235b6130982f495e90ba1ce1c8c5bf2d5a8cb2bcae442b18be4cac2273641cf20f36a055a9e7c0c7b056a95494cec7eed481339940972b68d950f6370ea861d80fb3a8ab2ab61fd288f147e3801826bf3bdfc02adbdd0dbd3b5651a9e774e350bbe9dd6982edf78657409fc6d1bf42c2c6306cfc9294f26569963efb5aea52e931997d2c956ec81c52874ddff44b69a5c280b319638c47266e2fc678638c5147e3d0c2c647c2aeaad8f89d819f4ffdc78170673103b2f1e96331fbf9547ed693bd7c2a367751cc30ece6ecbd2ccbaebb32170aea9bbe34c677ea39100ad1385429f78edd1da571c0d9ded0c334170cdfc6dbf48dce417333f5af1b626424f12fb61552cae8d0217c6c4305dc10e78831c6d88ee35f3f0d42ad34424f7637f41a6608a3c396d808c4f16626d82f74e853d8c611e3f412c4be144208a97cf83146195d89fa594a8fa671cc19259533f60d7a851b8d634e2d621fb10845504d1822125eb1ddf276479af50eeef9a7083d6b658c56222cd5186354417728638cd325ab0eee170f5e30f5dec6bdf8589884e49f8dbb5f292a65b15008ba7ed502d4bef49ce784fb2ecbb86f4c9534617141b8cb7de699ae474d5ce9b94c268bf52007f227d8ff86e14ffcc77390fc5d2e21fef96b5e10ff6acd1238ceb3d38b306dfd80f1561218a4a4a38c3e7dfaddf46b2398443d4aa9c948c42068235cbab9c91026d246f46256544158f82ecd4d3ba8f33bde28638c32668865308319cc604e49cc331235ffba6191c7de4e187032e45f3b0cfe3915eb5ce94df533cee6f937717f1edba1e4246e9e38afbc99480a639e39a9fd6da3b54b395b7677cbee38e38c33ce39e7752fa2e085ad31d41b05a41217f221d991e5ae78033f85969d0f1f7ef11c5984096a7002777f1912496929ff2004821204e4aef81e04545d5268201272f9073f432ad65d10097ae9241c5da631e2cca49765524a8a69190644624d85b9749ffdc5a750662944c77cc8d938e263790458becbc611fd739904991cdc638cd15d42f7ee6e82c148c559d3e590869e02f78b065ce0eaf0ab77a418ca17f2414b4a8fbdbc13a09fbd054a8ffd122a42b02ffd92ece92fb9b01597d09ba16083758c29814ce800c40f2bfb2aa9bfcf9f71f698b3747bbc9218af0a089b2110108540f1e6aa58603304a28fbdd35f82fd5c42450866fa55fc25f4aee21582bde9b1a75fba4bec53ec210a4eb858a5a75fa262601727de380b99a784092c3a4a428845456585092c42c207894505aa9480503c080bbd4277bd826b627705e75dc1f916c03e7b0bcca793e54a661006146fbc95c4bfde02817a2b02b56861f8ace935cb814c4bb877b7673de7a440d8ecda60118a63d21b8391a3fe61de0e367f37b20da689db8e4c857d8ac2ed471388336c8ada36d555f686e794aae9bbe3f4ad058861961dd91eb44ac76d9af7e8b0e96df60d91fdd1f7cc945d29318d086dc77322c690a27cdf7c4079537e63a39277020725580d840314d6b6040e9660d5504103ab9e208955e32809563f4ed4a971031a585dc50962c0eae7893a359a3062d598020c568d2935b0fa87449d1a47f8b0da280545ac0a861358fd45a2ce0c0e5ab07a0c560f01074fb03a0b568b210410c2b0fae11735b01a0e5181c2ea87425147c715376cc16aec0a56aad503ab1f16451d069c008a17ac6e2e4760351080c06ae824071eb4b01640469820b0ba817004563f4c8a3adb1090b8c2ea8760a2ce0c2bac2d095b7c60f5fb4fd4b1f185d50cd0a18b1eb0bab9d081d5efaea8d34f6869620b963ff1a18b18b01a5e8185cb15ac7e278a3afdc4d018276075562507ac7e7f459d28041a7c7e585dc760758d82d5375a2005ab511083d5ef495127e78814b0fa1d4cd4a1b185d5363becf06383430c58fd3128ea94acb04e5a94f8c26acd05464060592b395ec1dd6ad5d062e598c5b672d412434551abd58223b072ec82f918b5688062c4cad1cb5cc2a8d5e202042bc72f9468a8d54a4207568e61729c50d46ab5845859fa401a865a3e43706165f964fad06ab55e50042b4b2825318c5a2d22a22cc1a8d5ba8207569652a018b2610b2c7260653905cb51ab25e50656965588306ab55e70042b4b2b520747add6105958595e916206ac2cb35001d46a4d798295a5162cad566b4a1656965c8060d46a4d9982956517295cadd6942fac2cbd4cd751ab65840f2bcb2f9507ad56ab0824585986d14ad06ab582d0032b4f9f1db45aad2d64b0f27c5284abd532e28795271428865a2d2a62b0f28c82671449ad16951e58794ac15d049ce794c8c59b121105064ab8683084137e68a1e086ee07a024474a10a3862dc2d0a2450e48c440e1435f09e20b134e98f8011440604f4a0003ac8a124cb181e27e31618299c54998cc09866118564312a4644e5c590d4a603e3870e2653a6902f37182c5886c87ac86221f319ca8c009941a56e083854fd0124e843003ccc70a4c8ae924cb747202d30ab61ab0d87c98e0848b520d5e309f273024d42838273d30dd60d2a20626947cbe2825ed207d8c40392182fa184d2758780d48d2490d309f32680d5a322735d48004adc2e704196a092c2b4a90c29ad86ea0e2414703550fba329ea072123334c1dd2ae6e177f7f5bbdb737aedebed89790ecb486c68da69d358d0fe64e266688257a8efb1df3dc779317772777eccf7982e1288ebd7fa266f65bfbe49061f9a0fee63bed63aa36e35dee4c1168ed15a78f3f29199af41e36df733347e06024d5adb68fccccc8c47bf763450dbf7a3be7e4dea6b6f3dba4a205dcc57cd43691705adcd3694d679784b79a798467d95b79bdc6bfdf579220daf717b9ef5aa97a1501268bcd2ea6bf5b91b33540e50a8dafde9f439a6c66bd7decb4570e5acbdb948cd6ff6e65ae365319f9d22865dd73dcab35ce5b6cf9eabd63eea3b7b5731319d8dd96e8fc6797b24367077572894e5663c279379ab1e8d536f3fe6372f23b181eb5d71cfd53ae3ae667cf6b5a3a152a95434ee6a46ad3277d575d90ad5dce937191999e7644ed9766580486c60ae7bae7b8ecb2bd423b1814fbfea90d8c0a9bbdab2df32eeb355f7dc67dff6ae50b747e355ea7b621ef5a998477d4ccca3503116d5bfdd1e8d4fd77e67bf7b6bbfb3dde59ef372132b57546ee308198d1da9ccb22c9b32fbeac9995189bdc96b20d208c43e661018f612a9c2cd07166594df110806047b1963bcd9b1863bf8c1f027180c1f8b3ee6bb40b38b4120d35b09e978e3f21e8138462410c326d4593ff328eef0b67137f372924c71a642666e8d6c7bcdeb18176e5ea279a8d7bc7e2de6ceb83083aa713bde7030cb31cca83f83665e04647ec6631e90eeb7afd0ab368a4a6fa3c8bfd69b9b208998fee6ad7cdc9e52c43d343e2b7de5beeb7adbb29ff1ead665decc0cdd4cf79907b9ef381fdd73d9e28c898ffa5a7df8dbc60477db37ae5f2fc775377fb769db6b703b3dfc158faec77ee32311c2c6a1799ce7318ec5dc9c3df7ad3dfc2c4391163e126b66840946b1e038f38c408ccab8ef47fd8c77243e5cf9b83ddc779fdd1eedb7245d9793601822f5aebb5948d73d4fecbc0c5bd87ef5320cb82d77336cd9af50832dcbd16c07ea65f5f2aba2f5ecb79b5da8f1db6f31a713fccdd3eefc2ce2d376a7e6f59c2e1288b35fa14ede0af5d99fbe5e197c74cf3deafad85efb2cbb4822ceec0fce6e0ffc7ed8c21a677b647eab3f63860b333366cc98e1d1cf4af565bed2e7b22cbb19e2da5e861477ab9ff92cfb1a5e6f40b6ea75f576bf09e12ae4bcecfb67b84a5da8b1c9788d6be94b5fc38b1b10fadc975ca871b99bc84526b2373d8f73dcc3af35e67b8e445ce37af5b2ee6b78b546eddf8a6054cc968f64db8eed396f957d97f1787685d4d8be765ec6715cee3ea37efbeaad3ad40af5fd32df7d7dce5b718ffa98cfbcd5e9ed675f65bcd4b6552ff5325e4dd5cc6ddb738ff2561beafb538f7a6b7ffb1ae3699ff2627ee5cda43c2d06e5c9004f57c8ea57ddd7f899cfdd1552e36736eb75bff2666a78339f79dd5b2feb4d488deee6263337dbb4ed884724e2ec22716c4309ac09eb0fdf48f64fb1d62a4ae501bff4b5e4d54e48295b21f6d27853aa9f6d6ff2b8bb7d7ccdeb29bde94f57156f4cda735ef6dc9b5cb0b7238d3726edf6946af7b5a4752e9cdebee6753727c10f79e2f6d27ee769dfdd476d092e7d73df516e2e9c6ec79b8ebb99892dddedf4ad952a8f92e7037ec97a27ea82fd936f3c4a3f6b12acbdbda5ef2fd19c04e7fe23910eb14bb0212a0ff826887de6955694529e689ade95b4a7268ee39ef332cd4df0f63909debc9ef9be65bf651a7dd373f44d4f4ddac5b6db33bf6eb908cef47b66dbb671a026d99163c0d8e72218bb997e73df83bde9b96bfa8e01675fbf1d7bb941a0095e75a6ef4ccf5d53fbb7dd9b99e04bc4e9a58e3d5d7afb21967510f7b6a374794cf8990ff8f3963c8857a65ff9b8d8c49e2d51b7a75f79401ff4e13b2e79f9c31a863f4d25ada4693717f91efaf135edb5dbfed5eea10fff74fa7af2b20a9fe8d7a89dbc06d2bdfd9277bab9082e55d5e312f7f2e310acbdfdb8eda8df7d8c77ba9989bd72f3e19876d7f431a51ae371f5e2ca83be0ff854f3aac903a27dcd9007fd69fa7ab3e91e91a5928f1e4cf001302feeeedeb50df6ad7910620d279401e2f852cacffec88633d99836bf62a68961d83542b33b03f63360d894917a0c43a876dd104a2803c4fef1b13fb2612cd29f5e9c7f8d6417890772130c679833cc4772c2f3ce00ffc826af1107c3c33ef6d682ec913e9f05bf0d53c8472046e23fbd8629e0e8829a24a043f718a59c13c3324a4bfe512ad15dde4ca394d11d4aad524a391ffacc4d5a18c2f70f2787841f3ddec0813b50d4b699c1ca145c7ab9054a165cfad209c3557c8927865b32188768290e15c5a1a11987e250f63568b08da314fffca97fdefed92d72cb9d9fe116eca85780d86112eec691a11658bef4f6a48704627a73fba77dd98d4798946a8306b604553318d2b6adca703fd5fc53f506e5b7bb175092a8e76834bd83fb5337b04fffc3c154985723088bfdbc99f6883a4d55f87495746f6f4b2e36f76b02bd820c1070fc20bd02f522bea3e0c5f2f817ff42b1f187449d8e415e9166c8e67e0d7905c1b4927743a757a08ec10d48f6f2d634c1e62638cb6872608564d96d9b1e4651d5793bb17ae9e75f5954c1a67f6c2ad53719cd943e9f4aa58770276e3b7947339db49d9d5ec171e95f88c173e2973e01ad43e34de96d13a552a9542addf0aff4d0abf793a7496347ed665aa2115e161e9bea4308e3f6a3093679d2bf4ea202de6067bc7400d4ada3d34d5c83de0f65613f3d21de6261df5e66821b89c4f3573ea00b4f29c4b2b039e52502c3bc8e37f1a64b8c3addf166d88addb171b401ac804f98e8934e13db13bf33ee221d8630c49006dcb73d24b2850ef767f92b1f262caf912b300ece5d06ceb1210bacabc0426323b00cdc6d44766f2c50ed8533cd6b074838ab6854dac9f60a2aff3aa8de48c10e58c01becc45db443165f149c35ec7d053eb1f0e59d510bc0c58d1e0a40040bbfb5da36392bc231c26d488e4038027928f0f78490d2c60f16c3cfaa9fa803595a8df30a8e39d8c679fecca9ddf9439b5a193f3e1d22a9a492528993c373b2a7b452fa254c353b7fe68fcd8ab227f03d258000d0c5ca79058531ec7c41f8f13dc720a04f02277e4ae5396129009ed8f70fca1f2fc31ffb36b039fec420cff1279e13dfdf15853c67e58de1ff60f8ffe339fefd8a51081a57d81efdaf69349988afa5accd9b70b08fbb0847881a7c7181e784dde9d18f43a343759fc63fcf47bc4a1370de91b2fd5f08ebb9ecbcaf9ac2e66f35bf1ff03b6e780eec07ecdf63becb2fdaf9f58d63c9e2c252088c8b0984e5f4a1819d3f77b600f0c4629fa7f7640a24dc2f2c493970bfb02881bd28ea74f424cff9e239d8536aad4af59f7dc99330c6f82c60eed1344deef14449e341b192c6e873ba43b1be333d27fbb983f30c4df24ee6e520b2133774d8c05624e227bd817d9c77200b6cb6d8230f2a9511a4607f9a96299bf96d039bba0afe190faa3f4d0a435e09c8a6704bf1830d70c0f862849f1d0ca8c7173b3a3a0b3684fd69686cbadbc6a87245a11f8233b0425f7441cc2dc1660c0828eac496c4801a03c2802612306582c568c0fed15f13a971fc7847d88c8393031ba24540571c1afa420bf64f55e9621176e872211f7215fcbd1b6c76210b7d0862e853a80c611f5a41c83f77a1298dc387a20f6c8e4371c8e3908d2245684a169b5bb168b6aa0f95f9363c0bfbb611b28408c75fc5c07a44fc359fc8c23b44deffc1c691cd2aa3e789371907e70b2bd83f878a46472aeae0dcffc1661cac81f7c17616341ae8151a0f11e239f05a213635a968a9c0b8b0bf121ff9363c8b3e0621ccd8c4300cc3ee4ce22a804912755a9c183653087443f5b1e16790abe02fbde97215fceb0d6c76232ec95aac1575e43bd21637b253c8735e5f68f11c0f8a32c5b93061734cc2fed5b760376a1cfe52e6f862e1169cdd08c98de4c55aa61cd86c53d95114b66dca46f3a1225f95020c6cee97e5c2661ba5b0d94ee1fd1042082184dd72f6ecd9b33b1e51c28521e7c3a3961747d83f55e408f491574629a38c52ce38b18a6118065d49112fc93dd247b08beb7ceba936212da24256db7047b0340cce30c8837e9e508d0642894285f5f716ce306805bfbf0a2f84b03fcf8e0bfbebf0e207b3dc85c0b9afc8ff6c3a1fd82d7ed34714c926a97a00e65b7ed33c55fcf80d069c80f19c24f8e0238e6790b874c2400d40b5f2c40a352712c28d31d0b2e2397d8597271870f2c573561870f225eaa0be7bd95ff2eb8eac8b78a20e8e6f363552d8fc7f6505406c38be6f3e6a188c79c4255fb00e143086cd4712c2fd42e27271bf9088f0c72094e765e9674b64e1e72560b07fe45183b1db8d63debc2409e725449888bfe21005fc3a0d540034c2a25aa9c23305431d104ac110429d4fde07f0d44461db891b965094420bb500c718a54c410a9e7640eba85a075509f46bb0bc9988bf70bcb4461296c61b252c8da276d47126e8c0e5d55852f033c452d2647c91c31616930d08b6a0f809623181b003b56d4cc0840c8e581546814511ab8d78a084114b053c60e16209c065049722569d5ddc40882156c54cb04412ab662ae04110ab9b8002c688d542b0c16788d55f04e1082256ad5af4025084a41b92584a04d022a208442c260bf029c20fabb1f0c20623d6f7050a767f1bcfa1c1fed45ff3af2d27e5552202564361042d7e586de3d1871a1920060f492c252a5811c6118b09aab5c5ae8448251e049630462c29fd8bb025bc42861118575094167c253d7a83a10130a4b67130411404ce1667095f46081d32a1b60d2d515a8247248636efe0ece8f01f9e03b1a79023855ec133d3f7a75cb31ff4e4767568b7fdc6e10374f88d27a015d0381e4feb04ec65af5083fbb71da58f1efd92e7a3e1675007bc3ba723acebf09b1d1a50b025d4b6f96edadd6472ffee99be898ffb73e933897dfaac61449f4253e9a6fc939a855f189ba9dfc08fa988fdaa1a47b4c266faddf0bfb468e2a07ae907ce340e7fb8b1007deb4ef9d7051715f42256b547d7a9ef697ed3ad00c8650c9c1d6741f8b0858ba3219c298e9716a17295ab5ce54fe3153aec57173dc0ac975b64caed11f6039d8a4aa148e44352e89314abe1353affef31f9ec43ef51a9f9f69c9a87b0a606974a5a95534c2e29bd42728a7f9e9442fec1cb43c2d2974a39353fdf8f681d2ba7749caa79a5506e304afc9b9fc4bf195f06c1d02b34d6817d53f3b34b566a3ea7bce6b367993e64e3fd08147eba3fbd816d024f14bae0599ace05db76d8a8f16abeb71d36fed53cf4e4973c16e04b1ef03188829721aeb936fed53c8fd7ac6116b96e1c352fb51a221f721b5658d3ffc0ade636163ff38691c34ed6c6dbf879e239415127c99c70e298b88753382821b5ee39350fe1eae1b683e6874005603fdf850c748ee9e767ea7db618d5f0516ff2627ff0318f0686ff1d84355e8e2f74d212c6e3317daac18d855a9a621a1212f2a12a442f37f22d6ec5b3b8162f9a9e93b10fe2dfec998209492121cc83b8cbc67536de8643b75274c58750f81a358ff6d8781920aef9209e93e10fcfa1475a2ad745f1cf6a5306c9201b33b0335ef5331f5f0a094921cfc15ec7fbf9b268d69f2fab78ce7605cfcf320b9e443d1febac149242728a1c62c1b124a2c9a7f1d987e8cb8b04d2fbc33f1b354f1040838d5d3cc7c6cf8f4851e73f3718e9aa79d37ccf931b0268b05906f504f16ffe11887ff4c8284151c75d320837f42af3a14729b1e9e62518fb98e4dffcf7e217bf99d9e7f6dcf322cfadf837df5d13859b29ae71570d2f435ce3b18d4786b11bc348b1f0572ff333de87b46cf19c159793ed52cfe334980fcda743f2ae543ff3b9c1dc0008d702f73e047f760b1c1288e5cdda97bed478c653d1f088f89fe1c9789e0c30c6cb5ae643783eca93211b1267d723eafc9ddca659f8df377de502c8416d1b79b2fe4de95311b083cd90c8debe90c8b30f3de939ab7879c4b76f79649915a845eb582f30169180319965df798d136fb0a7168b5f33af6b11cdf4321eec9bf8292fc683561a75ca2ea47a94274f39822296619909c7bfcce413630cb55608f405679969ca2eaf2c528be422bb74af2b451c07adbd48208fcc73b02dba544aab86f2a015ffb0c77995ca62367c605ffbcc7f8eecc582fc27eac43cf60ec573a2788efcec841d798e7dd4634018f3208c611fe36547d4b60c83b3f7417a82b39f5070f676fbd104a3ecad5de7446cf0ca08c4a74722717c231d8ea887017591407cba19da7bc3bf18fcc39e03fe61db860027367b286ce5348c728d655f3b9e7c3c27d3bab6297af705ffb0a71a3d71dfafa32f3843220989b85849ca6d74c57330ac888655cc84758fa5fc9b10a848d4517552c47060c0bef4190da1b044cbaaba5ff58924f19cf8f57dd4afb5d65ac3e0fa4d1fd6d7d115dc5e70bfb2d8822bdce6170c3f460d7a595ec1b008e248875863187d2638bb32a9be464fa9571657f0fc1dcf51f1788e7ffd1e5555359aaa5458efe15fedbe81945ef93d6afdb6a9b707b6b0252e300327607051c51554848912813862055bbad8628b11c48041104198c11170f02148881daaf051c1ccc28814203184215cc9d283186300318f3065052a3f4f4822cc183208c2420339ace04b0f2508eaa10a96021370f92268e04cb1e822bfd287d269d432460361c4a8ff0c4db089b5d05af0bcab161cf3386e8241cf72e79c73ce3c21c5f36146fbaee4cb246cc00afb3766d89c73ce09348e7e991c6c8c3d5b7ad1b7146d79d11d5e5b68c1bd4516dc2d01937c93d79b04a8cc62fc58a2b494655966929b04fc8bab52896634e062bcaa69b6b5afdad7faa79b93606fab45f0f6f6330ff59d1773aa7faa9f699bb6755e6e125304f7ccd3e87e86c6cf68cf3df184c6411a35be964a5f4fbf51ede6ed2bd7695fbdda6d0fe16b5f3da871a7aafd8909e65ef37c701f03bfbb99d6705caddc37d6b6ef3cce9ba1098ef99819dcc77c6f5a0ff68dbf4298bfc678272fd73fc9a03a542a95abed6eae1f83656ca5b1b57e198665d8845de68427e88261199c451815a51a9e0076d12ab53f60aa2382e1cdf32b0438ede38cf7d4335ed75d8d4b693210aa64361a3366d7fd065f06de4c24055393d31ece7ad2b4874422707af8dc77deeaf4f5bb6fd7b4d5e9725fbf3e470477b0a630f7f0747bb6ef52b8bb4452d86e3eb6db2a1a57ce9832a914d4b40e7615c22e057f42a85d6ec26e42082184282f13c1288a632c8e89f91a73baa70ff51c17f3a76fcad9989f93a6f0bc99480ae56522a98efb69396ea6344efbe9715caac3f3bbc97199480a6b29f88021449a0834006207a926020d80a08208462919341428385ec16928500e10a1409161a0a86cae58e9bfa3809e9ed669321675b279a1fbc8c5a44cf6a22e774f73ce79bbdae1a8a2a15aea53aa97b1aa4f69dfbda6c99c7ed6ee352436b47a35cd7efdd879b9ebba17509db742fde93b4a354d5ba16efdd39fbe3ef7272fbff0029e9afdaebb446cb8db23a379446cba4bc4065b1999542ad5a53aad6adfa53aadaafe55afa2e9ba17e87ff5476783e21ef539aa5da5ba99ce90b9a993bdf99ffb19af370834e11ede6c83b99b89d8745df7bd751de7e5176c1e431a0c6930f7f6db7354d86bff50a9d4ccc39f79eba1663e26e6a2ec678feaba1770ccc7c8e7bc8c7acdcb2f74977be8698ff24e27cfb166d3a3bd041a732fd8f080386b3df51df7d6a3b14d2662038548f53b48e0e265b383042ea4a0368bcddff78551a1e70fdba1cc44d052e7b7077fe51f83707c611eaf3202e1f6a3f8ddb862db8e9ed3ddfdca7ee9d0fd219c4d6210c4ad1939b09926486e2d10a778800a683ca1d7dc10ac651b9a54d6f0b77f98b3f67f088637737f02623f88d6533ffec7496562a6bdfd55894ff1e5576dc710863fc385e1cb7cad70d6c80186cd45f0f63602333ef5aab740e055f5d4b75f3dece373430061ee51588668e1f9337cc4fcecde7e05f290831ce42007b99f0fb98ff172fd917aed2377737cb1f36bb511e87ebef6a7b7945abbeaae8fd3d56e1e82e773f5b31e10a7b2fd989be38be5b8db937aedf6a09e7b1eafdef4b2bd443e9c7a5444cd78f8dccd7d258d7b2462998733785cc6cb4cf0b4d23f0e73af453c2390ebdbe7aef4efe625986adbb6c3f44022de2260aff48ffb7ab59be11f893be66b0fad7fde839dd087faa64fc2404c587beb0dc1311fb71da6b6c11c4d4e61eedb5f7a2af5b6dbe9db3d4f4c7d90edff69a0642490d46dffe03545c0f4d56463eccb08944c9ec5e202171ce1fa36428ff3f210cc7d47934c8cea3feaccd030c9a86e7eccd1b83350375b999b8ab9f99f279e3c2410c73ce765d467eff6ebd7efcd879579ce47cabe7c6e0886da43eff4315ef78e4f5e465d5a737dedf49c37c487c675cf133b2f33c1f56a57fe87b7979b29fee4264343b0840800220b128edf48208e3e64acb0f99f86d34082111536f70bfe8e0e1e8feeaf84a3ce6df1bbd83d957aebedae92be4d58a62bb59b8fc4a01804c4bb441e2250e4e19b51a21882168c833b8a214809426afb90d5316f9f55a800ee4d5b3ee2700b6c6bc184bbede7c642f7f4e186e439d86f2fb71d5b103679361fe79c318495dc4ff9dbb7a4bf3ddc1e6e011500f1b67ddc766c4d7694baae7b16fcbbcdabcf794db0c435cb3cacfa54a27e663fc76664b1b4c78f209e331fbe0e16f59aeb344b7a2688e49f8ccf04671e12962859706309a20b5e006e2c41bc009f1e7af9886f9edc76188165e0550bf1edb310dfcaac04fb5b8ffbdebc0976ef8863eec22d600a5a15ac3d4fdcfc88ac127fde8629cc9743fe491f700b9882fcb943b5b63d932acdbe09ae52cb3e635a9db89a30186b0eff6edc10e0868773d338fc336f003005ff8a6d3c20748f374e4f320cfb52c55a0bf1b3cf10630fe3bde11f8df76b1c3c7c45b388aa695aadb53ed5a6cc5efb1a3dcd93d9c758327daeaf51fab546198e64b8745be832307d235d06ceb2c46e8271082c3070cdd77cb09f0f1f43081bba3c1b9e05855e76c8c6095df1ca30f11109b1d80c5d2f03c42e1d58f80cf879d67cfff7b781d3e61bba54345909be242fd8ff864dd9e4584db12f9b2d24427e5e6343a737a85654060e4e5216ec9f2388902e3aea9bde2524e47209b9a440178ecbe58a49415651d8243c858868ad120c12f2cf8d8ca04ba607d005849424c465250616167e4c7a127bbc7afc78c0d10fd5878af419b5ee1e416c606310608f30ba60ff1f3f640f56f3cfa6781e8025684a1ff578ede8c83255a881cd36017de34f593b8dc38da4c80115acc900230e6ca62d486db05118f44d5f4d1e863ffefdfc98624d0aac114fbc811f05fb13ec57608741a28e6d1fb48ee91d628161d185ad7ec1332c77c9a8a5fa968c116cc1a4cc08368ca01bd9435711ccb3e159548a24b1f1163902049b3ba9086c9e8f3aa55799262cd18bdd8e37f9db51a4099a8b0a55183e54a3a13bfe2561338d5b6cf7079f8c2a5d38fb910c024202fdd01f22ea47447e9421911ff99117ecef5ddc0b9574c88f2891fcf123223ff2a3272da5ab8bfa72c7e3c934efb8c7d71be1fc38f39ab08ab2ec2ae97893a3500c6ac28a40334dd878e54b62c1ae2c8a3744576cde21a23f06e5080494654747961865099b77e27b32409c77faeb5ec2365204f2276ca6389a3472c7be4082a14a10215d62908b0ceb4f630516c628d115831ac74c1376826142e3f0998414dd592e5bf18a85374b2224dc464141f3c8bf56bffc7bfcc05a3d5430ae42eb09d6679eb0f0711cccab83b0bfc4c971251e6d61f3e73f5bd5874abf0dcf2abde69f7b3c5e0f256ca6168a221838c00323f6b1deff82fc117cb0bf0dcf03b4dc20826a7ea38ab7fba879e2d314451f30700073ec042d4ac148c2fe5acb070a1582dda14f6c862df8b303ed1476b6eabbe969bd41a2e9be406fbb7fd65f94f0cc9dbb53bbb0721a1164084c0f2ed8ff07929730ad658b43a65716a424239b61bcc2e608b47df7a7ec43d14571910a84bd077424ec434343eefae2d50822253dc6c1acb77e1cc883a0f52050bc29e2b697ab8bcd146b911221e43f2fa129561c0a7c1b9e657a77a1a12c363798f8039bfd487beeb3bfb68fe1155f18c78289ade8f0667be1960c07c38144b6e1e6258937fe9a67823ff1860b9b29a65a12f58c09306058e9a29ce8f57062b7c4de1277b06048699982fec91dd8577545f6937039d0904b4a15a3e8452b6c7697bba45004fac1591205cd90416404042a8c3081135b8001f4431345c020c51006fb13f9b2a323862265d84cb514582f5d5aa6a0f4b420db02a42d43bcbcb0ff0b54a3e932c43f57c11f853036d3a8c5669ad48497216fad228c9708ec9b35b10d88ee8e2a15fc197498e7f3b90afe363c8b4a868fe3dfd71e4e7ffefae2dcc0f95c857e1eafd16b6bbd0461ff94a4f24694c1c1e6ef7e9fc5e68ff6f7e9b8b9af7cd8480b0fca947ec1fe5a9047f129290bbff2d830f66a1cfe364a80b9a20e46146fdca3640f92ed4921a2a82387a4101196539e0c2baf0c722914848786a43c9248f4775446b082fd69bea688a894ad7585452d11d10c0000003314000020140c094422c168241a536565fb14000c93a248745418894990c32084900100100208000400000088c8dccc00bcbdf5763e6c71bb01c0cee3087158de58af47fafc668d52d7008b50c11dcace6ef541765362c9b20775709e16b79d1e2c8ca5fd113d585aec72495f95a9b562d016689e6e6d922c58f60627a7e5170064bc88a92bc017595dde71fa0805c6b5fb5338e888b1ce8242a363b4dae59a0cfe25656837fa81860b6dd383116b0544ae81af24ce2a5bafdc4a8308f5741483cc46319365a504c6be0e5bc65d12d3daf2fef471af7f1d91f59de9ef45639e56ab34d38417e9494cb508995c9744f9449a6a3909af86e09a94982a0690e6e8c28aecbde3bebd5e8a9f54cf5e83dd01c61ec3403c0ffb3dd6b1f750f5ee416ece557ddd8b94243f0ce583c9acad7be96f3249ed9cde7e4707c222cec723d0bb89738586c6904206add0bd82ba833c64027d57388382da5eaa8340c150adb0b3b07b53699df40684ea7d299eabbe986c4f7d87a0c0d05cfd008b8dfd5d85f6025c6f6ceec522e21b48633100332bdbe1040cc59c693db8a589a7dde0c756affd0bc1a6fe293560497f05b6f2870427302c2298b9c9dff58a90c1563f85691b21146af1fb6b6c2f7efd8b5ffc321fdbef62171035ff6cc51c694ac1af619b8a96c0c9d84000fe920376504d4acee79413ba024f8d9cb34fbcf2da288c33154ff8e28d18176376dd4c91a0c3e4969c85ceb9476e2574164263d7395f3a9fa3a7686eb5a79cada1dfdb82fffc84143d670e47677262eaff857ff6532badcede4f8f3ebc0f8aff899d6f4b46d11c8a819d0b96ed2a7898ad8b98a6f6965b06fe988f04efaa17a1520d020ef7cd69d983ee35621a4ae0d0f997742e366d3ec9c6179193ee51c54aff24ad0479472076105a47773dce41488748fb927472b8eeb82ceb988796236ab76dd152ce500cf95dd060a41556d6e03ff9323729cca2f563c671790b4c4335e868ba18d520c042d23214509e5718dd5e9a6a6b566be52c1852624b4e9a721df7cf094106ed7919aff9f1f071f06bc886188a6388081bdeec4f752ebeb2879cff93dc511e1fc92ad38a3511a483f971918cde9ce732846bc7cfb927631b868a5571f61539dbb0e13f71470ae4ccf9b0769b06edf3311b561bd0f337c9982c39a77680f6fd7483b10eaf55a387369f519d6ea5769b0fa9a5b6b0216d737e565404e89a7a8625a9343e25f753b87941f2bf64f38148b0bc512cafd94440e136ff4c6901e8a8ee9e1fa149503e02fb40d9b1476046497a64fea740bf5c9bffb48fa9756d1e32328ccf4af0be8cae66c24fe16e3ec865fc28df801d155298633e82815a526e2f779ffa687a0ee25a9f2f15c9ac3c0e7a65266f3467a6292e638f1ed0745895ba109b088a6074749acffad589c30ac95b854add954e3dd31e384c874ce359f09ea159a19feac963e71c660c392a1873510eea586f5504ccbb0b53fa2c2ab43d3cfd85a7aaeeab5785cf7715c6534b1c23af9b221e53910aa53b475a07810bb32476b1e6001b5817cb5c9b17c719a6736118962623323c10e32a486a24fb9cffd444c3397fca3a52cd70f0bea66e38cd39b1fbb6e22acfabcc9ba169e7e45f97be0e9711d0337f89ef6340cd72ab1e21e29e81a0feeda5064feb16dfb9bd6b128c405ac79fa01c6955df03f79cfea36f52f7079ee5b4d1ec9d50f149f1c0f6dd86658f832d60e088d234e3860a66423b3b9be9cb60d3d3a2451371c8bcbd32bde333731b619d906a8d341f009362dab908ec4980607b93d3a94001305c7d0bd5822e959bbcd2868fb30ff3b0dc88b74dc559a8f328fec37a1f39bbd06da88a34b31fb030b1e5cffe26e22af74b5d1e45a689c9811d4c58aec15de935c61d40463f52c8bf9b1330fd0eac0cdcb096a69c0766b745a810a546f79e91cb3ec8fcdebc8985e2f7bd05cfd34ffa1b62dd312df30fdaebddefe3d495d032dfc4496398498b61ae80bc23e89e1fcb58aee1052ad20d5aa1cbd0993abb70fb21fbb735605ade496bc58b80d1963aa41803105e44a49e782b48602fb8a26697874799b3c4a71bcd2988d8187643241c341a6166f07156f5b41303f713d488e69abe29b2d413bf940df1e7f56c14a7959dacb56df8c9b85dfd5e4b14cee8cf8a565d3f9fa11d3bb9457a3a782f12227d3ecec7b87b706c9135bad7415c47a48bfc682326992b439349301585ac1023033cbaf14586a7dffa9d1d17bdb975cd7517aa8c37410cde23c208f28783a0972997a22f00fea8051609f5ad58e1d8b47ad8ddfe1c64ecd3a6a119e75e2a1004b24f15a613991bf90411eb3461a34ee642dd4a4b9ed255e4ba05c64ae9c8368c2ab8c2c39bc6c44bca8aade4cce4235c2391de27b35db5d113c27251a382e4336fe64804d8ad5b13f161233d29a034d2257cea0ea8664e0d4b7662530a2d4a582a7de90239e8486faf5dd8453ef9911ba36eaad8631a5131319769c4b0473e57bb92252b6490c1cac908bb23adc8a9e830e91abf3a24576d7ebe5d8213d8ff942ac1c5c074a675942782b2ddaa1cd08605b3952af210c2069706d119893499d79bcdf9018dc59d72754d0e398e86f3015909e70d13423543ef2782ac923817c9059df621323f33ea39e7e5b3c4c1f614dceb990ca6ba30722ad6a7e183dff41f72ada08cb49426c0531f8c37a211b13d1b5ce424212267ab333a4fd7c9819b40bcda9d15516624df0a46ad4ce98e0e5eb5c8dc636fd0d2d58ca86c3ed73cae0d307d72b8d703922c848148d41040c6e4e7a1f48192f34f5ae45f79215c30df061682a07c3fe089f2b3b6754cf4635c5d0cc6c70501098278e8de5d29c8f0c6381827bdca12bbf22d84217eff3f7404ba81ae8afdcb818c64d9bcdcadd521281e284adbf2cfd9904696189b8e11a370e9c2fcdec7b08287d4a26ebb8f0b349121f2b9165ab0602a2a0ddd4bea3ba918c5381042bbba75d0cab849d66b1851677f2d80ec9ddb9d3ea4980451ca5baf77e003fb8a0177d2a4505e439f5cafd53ff5dd2073e1150bbf84366d79bde689588fee9ac52ce67a67446aadf09bc379cb106d1ad60b902956fbcdf3537e9309dab6be41b135e86034955f0a108bc753fdb584fbe2dc2fda70029cada1a8dea300b986ab35f26a03ca6853829c84cc864ca023c3d26752c1a2db0ad89a52ad9e3932a3f0a7bcfb5faf5c7b9a7772b708dbc86b2f6a66e626975a836d85f676f12e4c2227ed68311f29d812191224f0517526739bbd30cbef7de5570093dded20bfa76daef648e194abccde1b8f0eeb6ca48371f62f25929023190d0981f7dfa946767405ac0cd840bef0dff841cbfec4fbee1913b65405b751e6c103957595c9b2024437de8685632aefd073825c6127d4bfabebb3fd24dd3337302a9e1d7e48a7968fefa6b015bea15f37216868eccb46c37faa5b790bcad875b6c98d3dbd9fea891a711a50f77f2399c0d73ec528490bc1894b0eef3582d5f9f12c76f80e10ace64b4fb189b09d1f3f8b397d0ba0dcdad2f84c257ebe2313d3b7e9b9d2e98cb80ab06d8a60738f2ac258a52747b5fd0050167f5efb745223e512fa089e6d2736205c34939f8592a478e94feeddae146de36c96159713b85f8fe6eb75611f3a376884071362c27414d16bce21c536c7b2d54e2cb5d5c94401091f497d088d88202bf9409590b3f67545145e7816932e7e7afe262efa42c874d4c136b94fd46ec2d565ca8acea621ed3843e4d59bc831c4d1d554254fcd417ea6d0224f7ae40fc02d4fa587f37bfc605eccd990f8d1f80e95a4f83a15f4d466f92c87b1372befcf7ff9bc278038f2aa00aef575bd28045660ed57fa98d93bada5a14562397179cbbb048769f7bf888d8a8b7fc6266551d8c396b35b82a09c8514edb8854076b8b7c82f29a46b59812da87560ea2b934f9cb062b0390be579df51869a11aed68f06cf40fefb0d1e9db875a9edf413178213c8e717a8967780e5fad8be9c27926ad3438e85bf8d98780fbdb35937a0b571d0b755f010c483c97a16fa67730cff49e55b38bd615560da418c0c73fde0cd06657b1b78e2b86ac45efe18ac892bfe01d0b2829039f75b80f66c172ed913235c221dd7b2ce73546a9adbad89667b466603168f529acb08d2b6b12bef714af6437797072a58277e402ea2c9eb7a64c4ae5912053ecde75f5497957eb98f90a0fde91251e4dcc12f089d4366610ceb8178baa6ed38ee129f83955949ff37ea7dae43456ae2d875a9b26a37ee2f69a4c97c3fd42873c5ab026d9dac78af3337a77ea0b9a094913b0ebb9c840379795e061cd88b5ad0229745c40b9cd824967801d4b75f53b1c6574b57fddee2d9209c9646391f643c939b48fc4c2ed03753fae15da873183239cc943d60dd7e61e1446f4b66b653b7cff29f481b0398b82c434e919aab04f2fd21f67c097f71fc3651b5cf772545614f3860ef8251b76da66e435a68c1a913b511d39a9c2f141d4c9f44dade3c4f0cfd2c4bba2443248d45bf242836440dace00c92c106c5597cede299364e5248cda8a02c2179dfe03365ece914bb80090b7e3367a80c1b9452014cf7dc5a1171cc0af17df33f618557aeb01ef14a7d529cf190da28fddd1270d7f1bc4773cfe665b1f1d9020c4a35e32c55df1d934b98c8879ac9d51943632a67b0b84c77791f813833f906deabee4894c1793655dda5fdb72ff2778aa0828ffad5c6b2d03eab0210fc18f385bd319d0b8a4df5d6af1907a2030e497c9e104110740d0423410c5c126983222aee559ca093b5063894843abf799b46d943b2018431edf113a6e6b9d47c30aab91e2760ef7be455040c9596e9637a9d061dc1bef7ac06a4bf5c0c05155a5bc5532863557ba890bdd350f3b81406a042de67f8b320cfd50d4a1f6e1c478ec2ddfe7e48f3e1f222d4ca2313b09b39b4cc57256056d8e760bee7cab961b9f4ca7fcb20148cd7dc0e39a87e6169ccfab6b10537702ecd7e60c503edaf671d5796319db236c3b9432b92b621053912bf51fae699800d6045c8a5c0569c5664c6959a02cd172dc55e5e0a7c29fcdb450d10658528b28e9089972695584dee4c89f1602616bc765c57aae40662de3f6a216e8218678c9c6f90718cbfb40625b2f377c262e862a71af1afb431405ffee10f17d790b14c686fde64bca4455eb755a360353a81c1c3f3700b7c40bcea213a0a2aadad071fe16a37ad5e8aa28295b4aeaac4891f26fb2d1f2266da1f73181df6ad8cd76c2d89512e12cd2a498dfb0539f8146072f58376138006177472f901a3a5e885b5da22c7798e0f82b50fc3ecf53486e84f3a499d3444211220ddf027e64418f8b1d603227ab351e564a486f436cfc6e5f4ca98c73670dacea3042df1a217343a6d97d8693a6b115b9a7810af3b4432b8b167804a005135895d1bbace946ba8bbc199f6b0dc2c333ecd2e054db3b4bccb5f0a380a776c05ca1dfd8bcf55984a9785581c2bfd0ea79666325038ad436b5a627dac2281defd6a352ea7bf1848033b59653e9986eeb4b173e72edaf015fe94d1406bed8af9b3185a865c34005460c67463b42ba4143181da0d584219a0fb6d0c2b44d3a469deb7e3e45793663c837ab29514723eed0c88d734ed1f3960a04536a3b023b5021db3f3b05acc76b3194242a157414c37920258153cc9aa3cb1a9209224ae19f7d222015d37313c76662a8ded9bbfcdd564ded0c693d2b7f637ec601481ab1bd8a30158782528c3ee190db110d5244089ea11d5b34e3fb196a644ec97acf61598ff7e57dbae3ad27c79be08f85e0b4add6e2d845863c3a4e5e361ce03f3f60b32d08d97d19efb6f12aa4b6608aa2bde3353591ea0e855429ce829d50d9fe7dd02c5d4544472976b9db3b89073241d899236e1c7f021f2a31f5b1bb927d6097b502c62ddbe9f438f32302f572774ecdcf25a5e62bb7f72762781c8e28f32d056642de8fe2168be17e77b96c26bb44da5088487794177ec8fd1e3fb03ae797705db034ddaa6c421e090be3f82f805f5a721520e54922cfc4584c2da675761f0b26c800dce8528ef89ab60d8e6c962edc2e8ad3b455051ac350795f55b49e896243569540e38620f58ae9318c82513425a4e5a0b00c880c8df865bdcdabec578c65d31a7766013a319adcd5e08a7c393744c04124ec55506e093e8a10bc81a1022c500660c2b6e11372a852aaa75eec54f694ca101136df74a591fd3076d63eb7068186711e3fa62100f8cd583044dff7717b4382a46fa60ec84ebd6de0e5ab58759a5dae8e6dd82be47991b72e33195b76a49ce5549be04329ce0a5edb4f4a441f481a1fb6630befcddb44646bc7ceeb49e0c1051c04fbf9d1afa108e789b22ab61284549c6d3b43fc8abdb64d5ebdfd64b1e2239513ffbe136deea5e41cb046ce5bcceb09d949d60cb224562673e000e60f28f86ff0f64a4eddcce9b1a63e58a0d2dcb24f89df13202f5baadf62964d6fa3a6bd092b9b516efc9c2361d403355beb7a7e7606420f968f991fb279cf536cdab4310324fe01685f5cddf0882e10a6b5d463668a61ab986bf8d5cd9876a11f6f290dea7f2980ce94485ab250dabe997c02a473e399000cfabe4ae5eff783f6d281e4f57e909983c250cd3d1722b0d6c915d326b4ad57744ab6fa07adb81b578de5fb8d3cbaefaa4525a8e84a9900f2ee7a4ac2f2fea36137964de3ef2a524a30aea830f4680ac29618ec860567873e82c30bb54cda869e676758b27a360bfc99bba472b505dacae2a0c2b882413f8d737fc882b57f46e09950adec77578cbfc8c4a9facc280644d60b5d49be8ffe70479d610f50422f813aff62050c56b53f3dd860dc6ee6d37aca382b673f09aacb9a195ff80ccf6fabf93b6ea79212a0dc37c4c7db5cf95978d429977b152adf80ca9956d07cf80fd6fd3a69762ae4fd39d382e540e837d5d019ce8299178db971b7dbadf2b5a39fa342607eee133fd1ed9dd0414efe3c47acadee50ba6205f69ef82524c4cbe793cd73bfc6628b010a9344d626f85076b62e41afa88b7811101f6bc02d89171c79145ed83bc87328ae8886ef772a31fa4270d487c97f6290dce582056b4e3da0b60e666a9f9251ae843591c79cf7f4d519e76baf6b7171a90326ded473e6465785bb40eaec41834773adfc90ce8ae00d76ab1da3f16433b84799c26d1b9090e65ec19bc7dfae3d403b1a8f3592b02196102399580887b4117cf8a324fcc894e4fa4adbb83737a66e5157d0e130254fc2c0d673bc48b34fe46af4cfcd35f8ea6f8981a7afc32f3c592dd2a37cb879a89a1b5a54d112b29fa26e5ebc95d10bf443a691e3c1d91040fb3e5477f8a8559acd64c14d970bb17bf02b04184d426a068df17a5e31605307bdd85f1542510732b20ff8dcf39427563d9bd147c5b2e0acb2e8535a6ffeb11680671d62126e5baf9784993ad0f50d23f98aa56755585898e16d2623230f584acee1b1ce551b3e32e007a2124c4afca4970c48f646725aa770f7976c07d0a817a2d7d778fc4f5261374483b5cb6eb46ce340b68cbed4ad9ad300a86d5ae59da4132340a3514911f7deb56f4fcbfc88c940eae3893ddac04d0990c616f49d262b7bee75c2269121d9ff9bed49af63703d6238d4263f59163e2fdac8cf598e628f80b320517ed7ef93036e27b3526daa65530063bb707cb7eb5a018f28151b090f053804486272ac002764ca34e2a907dd091755b4823136a525b5c78e90f95b171cf8890524394912bcf068447ad868f0d4444d1474e4e3bcae03968dbd503c16797d0542aafcbdfc5201e26465560c2bdcebd33d0eff34536670327786342855c6c64e7d224eb00091a5fe8f9631c4f575754657f51eb2a4ef2ee780a0c2ffb13400af9484d3b86642649d00740a26fd0c0ad8d9c26f56f9b83bafa44f4fb7e0f6d93bd4b7d034f95636ca01566e60fd584c4fd6676afb592e8cc86f6c016c4b6d2c31ebb4d99a524dd063a7791de64f796854799a825ebeb537c10c91b49023c77594625d2d36d3e06365977e2863f29f8f1e6254879550f54a9b90a64650716bebadc514d06e3384380c9003b5290e42989d4f28ccb4bd733a0e5dd88e08edaf1aabb02aa09ad3ac24835b8043bc7c580bb9d061971e4fb334402ac542b17b54a641c47696988f3ebcf9c33980bb39c73d005b3b78619454ff35e1ca763443958441a1153820de26035086c0c012e787e797f40351738703850a22f1cc198a37ecb3a07e2b310ae52b57db03ee03fb27602d6530dcc1955b696b2ff0c27646af7e21fdcc14589c2f3caadfc98b273c9574b1931991549cff4dc5b657a51419e2b19135b07caba82a574c092313188015574fe605c3e05a275603f3ad7a0d50955e3e29df7ad8d91a28372297fa11a1f45249fd7e173d467f7fed9aa699621c1509875e2096c5ba815507c32d33a99ed598f5a14830fb4d4ab9fc1392cf97043e6ee82adc5a8eaa91af973b7dd19381a2fa81957b4f921144d9ddd6bd61cc4f18f432e932fff65d4088f85827cb1c5e2d34ba0267f52593aba9deb026229772971d928ca843aa407f027137dff4b13eba0ebedd147e23ba8a02c03eb65a3dada1bb84205450a7a9aa25d92ef5854d54e783fc2fc445dbd04c1fcb8bc73c85579c12bb271be3861fe027c39fe5b1cf080a4d79cc7c5eac2e896aca823fd8eb09e6b0704c1a086b54d9f463540e0191e000b74442d695a1799a4e3b955ebabca6b3034eca7b6c2b3bec138022a5b25c8011c6f5646c81c3fa844b9891597dc6539987ee13ba184238f0f2857348218eb79455fbdd88e500d5ddd53a9ba62c881504abe4cae3303daf32d9113bdd196a02077b24c919c2015beaab82960ec3b37578aa4de809a62bf3e8f7c63ba898bf0c9f3cc26914bfa0479830785cd17578ddf70306b4422bdc151047fa90386e8089386adb24b6b8d15572c7fbf01026c5af2de7eb0c2b5adb36c25b9c74dcdbb061b131e38e0bef894f90c3a36634e02851212fbbbf8ec840a06893e00d5fecd986cb7f6fd24c5c473fe7f5f66fe582c52e2b7f23935f19bd81dd0961016839db5f21991a58d70f893517121404f8a5622d4c0a074c7bf6f150d3b373626a8c88f27d5308e6d48b7594147a1f16f88f3c8f173a5c8e4390190d6cbeadac1e8cacf980becd5e9ba39d3568cd8381cecfab96dfa91b10b7b58bc89da82659afc7990b1e3e97f1e035e92449c97c5f6e7acbde920b652f89f785207e0b56b92c8db69d80064817bf5ba94a32227b959755ed526e7e05e98581bf23b9e3a8368b03508ca034e49005c802cd4490aeffa99db98a33bb15fbe8f836ef5752b14eb7078a1c43225c3d2fff9882b6895c4a3bab235804e6cde26d6bc41bcc6bf0cd72d33aabf709645b3829428d9a39512b1e76570af0822f8d8f878203b8346174a61638943c54c4a2ead1b40e4320211ab1d5bf0a0868346d582dac8986ca3b9011243c7f85a851a72cefc6d019c5a82893f5b84222c512f5763c73473ff3577a9274791eb64f101b1953e0c22ee1e30b918d815690c3836e779d011d1bce269ba653c4985b5b3e2ef479d2418b081064647d19b84aae48b889e39c943316fbfcf47ae349b2417dcc27eefc2be900cdf9719d693be3695664a53771fef8654bdcea05cc41004c378fa12a2cddf50ac98f43265e3e29328cd8a2222dedd8cb2d0a96563ba029b66468c7b8a56c1f02579af90519a0d2ba936922a254094ca8edd7ca4a7ea9f0807a074ad8dd9aa03098d469fb5df074d6da54fb92968572c024cb923006c87a22fd81fa59c499a3d0e773b4e68bebcc2455756380fe895e78b014f0545d3af69778e40ae15ddd4532fd3460808262ac9d30ea1994c422785cca3e629e9867ecc1855d80d799056ec73326366399e8656c693811c8ce653f1c07756c8ef1097d3b9496f1196e0a00eb7924743b2b8152a4953d11e42ad9abfd39499f4be64a833dd70daddab9d88e0ea1d46c50d83da768497574e74563eca8bf5777be0ac635f584cd65b9e9cdd064778df888e18d70f92a1574a904ba7209a61ec8e9ea2db350b2b764bbb78114e8c4c40d7828399a097ceda9615b2177c239981cc333a1eb5e75b14eee591eb486f87e41559658fbc9f3a83840a72f79dc19c5f30544c80212c36cd7c633c6064d527e3144907f87083da6c76fef47c49d85837bf7872fb5a3fb68ffce50649e11ff3632f2130de24fcd2029101c40a517b8de2ad59ac9dc7b5e85b514e8b47b281ee310278a5a4085633c5b16905ddea50fdbc8009913260e8065655320de44257f6bb86c6424acbbac0fe8839895d4fafaac62234d33125b83082864c40749d805fe81e70d4e9f6b67c1574e82d0ae40a8a829adfbe0100cf122ab347a56239a0052a5d1c1734141c1667fe9ec8817d2f6d7c62db5e3b1726eb44de3624e9d25907093d8080c56b1dc81858b6a36d8fe49cbba0291713b03cf99ee70030e00f3468eb2a1231d51f18abea950ded7b3a59c28714476b38e7f8507281315cced5d2130ed5ce20b5bd82004b3836f98b6e3172d971ffc5ea0b3276e6ca3bf135c9dcf49da0fa7336b68ba399708c3bb89836b104fb69aab8a9e3c431f21453c013b37a21d25ed2f3aade04b71e1133b36184bafe1d4c119642d280d81677c5867ac4d418fe2358ba8296ee4a8f0f2cfc9e9226823c2a5b36b1558fa19723d5f3723dd3cb2a57ac4cf185e93a7d91bfc4d4833c9b0cef64222965c9577134b3f5399c2e4bf5a6d3b74143bb20a04530371fa8612cc16e2c26a279553eb061504b860e838d85807a4fe685fb0b8ebf112014bee891d7786eed29ae0d6ce127cda968be7faab74a86761d727fbbbfe483630b54e1771a59fcfe7076762c00f27475f9d9bccd1456e65f64c9f7952f3b8cf5a61025961ab9c2f28f9322e95daf5de131c27f026755bee9f136230595c0e9302a85d1115ac6a8e785b4db2cc06b5e55282b81c720ccd3a5c6a4aa2a7c3661de3428b94782e36cf5e2dfee4b58777f38496da8ffa05483c22cc126d4c74af752cb35d22981a3147767685e515267b275320877ab5d69c66c8240274233c04771b59d4a9faf952ffd8b48a894e59087d8609285a738dd3faa752c2ac53a195dccddc5e6d4c9089507e2a2bcce59310c2b7ca15aad2e35b2f302936a0207ccf1da58143e4705601ee50c6919e430d6b039d4d79805614ee1db5ac9f2e5e0efc603a3e9b17fe90b60f11a781038b1eba91949c04bd49e4ac62d60a8fd374d287c649abe7780482399d05147a29113b7fe23bd5d3f9723fcd6adf25d5771480b111e7cdc95e4f538d7d6b66a95fd994256aa795bdd59e7f3d59990a36392c19baa6b0f77280f13c45eb0d73dcf1da213e1883256b7c71a00e8480605c0241f5e8065ce15200203d55bd87f360ad5b640e84aa34120614a0a5e456fa942aadab667848337d5cc9a117f10897d8cff7164300889796776de4267586dc7f647be27308af6aaa74147b31955c9ed5d6d528db089511ee643ee422b8c68ba8daa06c463f175a3639439fea3f1eb5a9422d6da4430b93bc9ccfd78c1868216c745cc6a865a148185d86a13040cf8f4029e99fe8511e69d52d974ced5d8737f24b5410529c3de2ef4221231098eb8fd4f42dc92ab85b027a300803647f805bd1838a707658a76f8955a7300dcd55539970dac5466345b9b697397dfe73dd8a9c33b6ddc8d7c5a0e74c6964fd7bfca9ecf1da92efeae0fc0c31f741c1ee1771a9ffd78f0c66d009e1e0e7260029fad0b242cb3417ddb607f20b204b8b8396f25249e18c6839e4e9a76d36fecbc7f813ade0ac4b68074a615c0c2d47d98bf12b1824e6187dd0a27bef1b0ba43e257624aed64c7ebb66f6539246cde441526fbcea52afa6485049cdb7901db46aabb57e6862af9bc93c51a4e104384a9e8f41c5b49dd40afbdda07daf023f8fd1dcc294bbbb709b8a42dfb07e46a6696e7f6cfcbff343aa54e471e2ebbac8a2144f74fc6b1e3cc56a71f2f34c48193d6c9fdb8d6b1f21c27ca74adfb502a81c0916ac79861090cf068b4a77cc07dafd7b65d18973d3b414b658d644a66ceeb914b1502de40dbc9e8d4fec7f214c11a8bc0c940fb79fb2b3bec90e0bd644d0b0510df7e7c26e759e8e867d657bdddc42a5b3b713154b64b94e0037a05f18e46afc587760a6c5bdd26b50d74253749ca59afbaf37c90bb74a37bf2ea46b37a9b0418f7bdead514d04fef50eb1159b99dc9e881869e071350f4fc21ab915a0da775ae5f61d4c7e2c5b3bd94cd5d39678b511b3c546af275cbf2691c692c7d48fc04ea632842c16549e632d3f907199d84f9caaad40bca46b809f3482870ffbea262fdac543f19d0fb176238dd863018a7a4ba2bb6b025eda03a8561e7b3f54ef0520ab683e32ed13c4e085d00845bc5580747a032c29db7e65d5e65dee425cbfa1a170810b5d1b0bd6b21ec90bb9f60c6b2e1653dc07df8b1205419eb7d174dc09d8b0a76111db1d50996385d3605e85885d6464ce1a0136eab729452b5adebae5addf0e1aa1a8bd61388ebf57a69f3a1d59fd4a2305cef3d814beb1dfc705656c003a0fba8b0ccb9e49e5bc2ce10dd2c0289b9509bc925e431229628ac0f26e2a95f59aaa7e188a2ab64b8a4114a8212c8caa7032220c07f5ea13a4e4870f92f2f35083443bacc68ee1c94b5f9f0ce784b5b2b6673be54a913ef889be364e1e2313464cab6738f7a797714894c3f48a1374212714a6ba2cef2251871ddae1abc1196146178b10a6eeb7fcd5a0186cd9475960133ec2e0e235c485ccf1672f6b4d0c9869979a50bd02574c77e36da2eb2c85cce22f3a4cd6eb00d1191c93b3c1c0af0be5965158e153c873ff8086b5a05a2d06a3a59502a2b98b7f7f12025e72fe85cc511f0396fef2053f9875a4752e429c7a11097edb0c56e0b0cf8eeca88ca796bb13311fc6cdf3a198697e5aabe7192e1f666cc86c08cfdaec702a506d8c46e03ee9f3513c9a8002f3786cb5b4fa83234bf2671c32b65745007c99c02a8827da804deaabc33ff29c39a25aaf6e7ce24510e7c0522cf222ecf793d018e19b4aa639e930b9df07879c1b9891306daf1eacd6b0eb9164df44d6e2e033de5e70173815c310626679f2b20bba7f03d0f1830856d970acc922a04f4147456881ca0116703379429663df745db1ec3c4bf370390bb00a9d8df5317f1f0dbf458629d0ae7ebd3c1632f39fde2ac412eda147d296acbf6f681de73b78c47ccd037090f51511208eb6d026e499af8196f6467ab17c0ede3c3f50b8e01f1d626d49e354c5e4d8ff9ee839061b92079a77b9d6f0372be558dc652c0f9e6a788591f64aa93abb59cbc014459c423250e06835f90e624b73f5f5d1a1e84c37852edb3c26c1f4abd664981f2d5852c9e377039bf01de7918687c8d901eb3a1ce1984db8f968303ee066b6a912c51c046fa7832df2b660ab588bba9737dd33d6c15a9bb5da75246c86520a8a0490148e078ce25f25b674cc05fdd1514ba073408252f414eb4d3c791845aec4424770b5a4513cac9d416a67be8e075b3dc5925ce50d663e6108c4eba29144adc2b08eba0becd5a3d2f5e36683e7aac4f453150863669c5072472bd230db33d06bcbe0e6a8eb602257c4f10cfe03e3f712c238125c587ab72bcab0cba1f21a2ece27431d3eb12c760eeddca04f41bc741179c3f211619fccd0ae50379275b4cbfc4ba6570262bdd8ba3face03a6e65d2fc6bd9c1fc4856a279de8a0c5e2ea58304b7af1b95a5ba6c2098a0debe67315acf99def2bd16adf079cc9532fe3f50be04123445ad2cf72e855eb36ee3ee3af5c958ea6d4436f397bf106727bb8dacaa0a0a044cb31f456a3eaa7e2c96800a3c59b6c3255ee8326545d956c9119c2a0a697168e06acf621abc8f4b81b49d40f25a1df010bbb1c423a37e0425cad5b2012ca5d4e3a0a33809535c4a730221ab583f478be52edc5f740adda94558c02a05cb0b56c88690e729bc549b94abcd6c2c8625ad95f31bcb22ecbcc88543bec00ab75aa7dcb1060bbb0577317bd8cdfd0a967d2654543e5eaa9f33aae3e901b2e4f1a97f7d374918f86ed083bd42c5a4b996d2739b7b038bdb46bcacaaf79bec7578ab39d64ad25f73f65773e859e2256f225d23fd74ee4ba350e12455b79330890dca9b7f42e8415bcf418991255b2df27434257b5f79831b7f2c19d930405c1f06b5e75a503e0e68398b1b0023e21f1923b34a75a1abc787cab4f2f71cef7d63915d4f5603d508159e12379ec711291f68b16399504dd2b1467a97397febe16770c0f2be84e1070bd7fe1e8e1e5ed91ad8d01ff3d9fda9380a4549d1ff03ee8e7199adaa900de48ba7e9716dbc5037dfe3dfcdf8287e58d41ba0b0974b342d201c991870db7aa1025987f13d1684998c2349877e37d0870fe0afc7187a0cfd23a91313c4e80ca78d029708da936e8b639735f06ff3dfa3dd4c0b88b836295347dbfe18db44f88f48083edcb1bf8d9b6e631c8c024199ec4a742276a570b12d7f6d9817a641605708c51d556f44f2410425b799f17c9d0e5598c89c75c86465e1a7c2fa137e45e7eead8a23058afcbe34ae1faa1797524ea3d5ba8cff0d807ddd6186280c5d452a60ba9286dafaac4d5462a6ce0accb9c7f2d9a2dff6f8e655d24213e46593ae40cbf59ba930203b0494d8590ceb027611ec73cb4af2da26f59d3158d51b921011e0513376b951babe06657128980117b3236b8a07e1b6339518c4bcf802621f2935e2541ea1510604ed5568a79db93029ed547322b7f491d814cc97b3dd98e957eb595f210c2a6291a01afd7f7322ca4547445fdbf605986ebdf5c1737dac4e0a070ba15efcddb901c24df73ee1cabaec7fdabbea8dbb7a21962ba70d042eb7eaec4d3d6a4b2c4ee8f17a12b7ae6057ae1d8b7f5bc74eec9501c25193300e1281f59df0099b98d44595c0d89e54c7ca284127fd416fabe89988564e4b669135d83f9ffc5c8b83049e2f0e8bbc813640e5953558df94f3dc627e1da26a1230f6caa37681bf48c951748b61e686c7fe2737a89680c6356ea4ab9fe392bcebd71d6439764467b3cb33758bdb38ed7e5dcd9d5ec9826a81febe0f5160696ee01bd105f2d693e5b3607a3e60b370fc8213065ff51080ab42c1bde746d3be6cf51ff385a9cc6b6a5ebc25eb4f82265ad6debfa04af85cc0433e6bd81dc9b841c618844604312de794c2c35a40b00d44f295f7fefc42d6245c853c9700dfccabaa12921e732e3bdc3316ae6d2288b5229ab0994ae45208d8106fc81be67429b16e51b58c2526a201e87b0c3b592b449df3c577d71f8a04539b6db1bfadd365e8e1ea1f857b310a7269f8ffca013ce0040e0a94402d721d2dcb7144842230d8ae5ba6096a0ef0e385442a06cc3a4fc189cb29ba7c73f01bcbe4578f2220fa8e9d8eaf2b3b30e44bd345fec1f4465cd4174d36df8286691f7de610c68036a1da277f4f4b6f0dbb9af096e28143741fab33a66dd42986d0325d7db58f8f3f1aec37532b5fe98f4f6712b05132edbd7a267ed2b61497fc5326fba562c135c5e3a7cf6e69b5c79d986fdeb5b5cc4dbd2f2feb682ffaf7b3db72c769a910c38a84479df4e6f44c7d965313fdfec9d38de5ab865afc6bc2f54d61391c793408189158dfa73e1326506638c269a3432c8a6a5e419617a7703406c8ecfd28090fa106b6fcd4aa0b694e2fbd71660f3c158f1ed1a71dc6308ce5e20e554460b5b6aa556be16f32fe045605dad9f9284a2bed96c0b38a5d4e3dbfe65669253d5ab09fe7c3f11499a8fa8946ecd4a614920d903daf0240cc858b286627860772bca0fe65cebf983a77b7e30b505f9f441a956f3a6dcdcff57d8185c2a02b625ac154d9a0c6bff61ae24d1e922c4356b5ee11a261034ab120f1c0d57b0e0ff17637de91264cbe05dd5bfba08aa52305499d3d066024c992e30ead93c16a2518dfa4021fb0642e0840e5b278d7b83130246640a831e05218332971a8f3a54f534eb50d421b7d53b055a6bd8278b46dfe7e5815cdeb6246eed85dd5fd7f696b988dd8e956345175dd20d87a952fa740653813bf5d6b61fe75d4f22cf02fe8b6f174f40e3fc6f5bffb2c390a69b8d8d4c2b57eceb9ff0cd485ef96ba1806728d714ecfaea3ae799b20a9005f3097fc71a5a35e225b8ac8732a79ccf701472f36e3f4e4eea47516d88cc64c1392908e19247c44fb364024b8d423a8f38c2fe59c47dfa238253a0e6d79301d9d776320b921936acfba6ca962596d9dd78b0988a802556666f5433b3e2f6eac21af4ca7913798aca6e28fc208aa14527d3073a77d12624deb7b20815ab75e1813c3519c1c5c37520a20b6aca1725d068671cb5ad166759d49905853a92e6c2490f2178feb5e8e7a215abdd4c4bffc239804416b105be934b40e1541934858416ea4cdddfa126f4038608496fe05cc14880c9686f4cd2e5c720282f44893c8b1ce3d65a78dc57b40bdaaaa452873b9cfdf65f872bc031a2c0c70191469a362e29b856639a90f17f131393ffeaed7f7d5e60bc82c8f7b1aee3fb798511eabb05e370cace1a987e43fda50243f5f5e7af26244a28e05f3d530fe25feb942c82d3d846b453a21f02f8003ea688a09eb4cda85f5db4a84b92a203adb2b91fcc1e838beeda0a61bd634bb4d7f3e07d81e70ae5ec0bc7e19f46d14da93fc3aac6270c213b42de1dfcc2214826946a151df09f67e61465d77b315040663a254059eaa2b2f7442217898c44e916ff6930ae8632d576d72680681391edc4aa1070d28a6984ffdb07fae5fe720a84e655682fccca14b3b95fe45e3534d2dfc9a8c33af0f85e9efbeea970d7ea6cd67615b3cbd1ae6fa268b3e944a1b257542308ecb256693482c425a72058f851080a90de600d140c17db9529c5f1ebf25624bcc4fdf21632702463ad80557089eb12bb31f885231372294c6b89be502b9fb67970b0e1342eec0f2e79a978e3ece3da45e3710375d4574a7d37b7ea180012f55c028287d3f196292b8f15cc730148c01b945c159079253081b0469f3f173969d10373e8fa3e1551be375b6c7130257dd0f0c64454faae33038fc283da2728131ddf19092ed4cca205bf64b58efde89a5f2588c80813b57c5eb62935436ab33317d14326d6d1a8ea568fdc2b6ed08ac46ac01a7c6947b5bf12d025d82b0d09a51d51b3706b8029b2db32204e8c14c5419f7277aa22177da15b9548ef6a1a1021c546c0a7ac5a55624793ba578bd21dc25a704f71dfbb7e00f0bd3a4d66f2052810cc522e9e6e2fd1fba9b82b60aee239697fb49c3c5d70552d7f5d19bea8bfabc0fc2b0ddfc9af698f200d9eb9c36c24743ffa456f09b23e9e5ed53aad1d7fd0580d173ec03e6ffc819e846c1b48e11ab6f5affda2359252d08c1d6e85e3b1ad4d54b987a3972609006169090f3a2ecd76e36025e1a63e586f9e7e3ac7056dee318a69c14d43dc3e8d10b3979b0a1ea2d5d295e1158f018553ae51bfdc0dce2773b4b5b40dccc626ecfa4315d5ceff2a04fc9bc5cd17155260dbbfb6aa4d8464d7290cc72a8b6dcbedff33af42ced74343d79ea8b0ccceb708278046f390b0e4de0174542c8b348f49e974dcc7fd668a3b60584681de095c4bb2459a0b4137e64a3c14254d453902b02a538db34632bfe1b01ce2aa901669e666a5a729a3418750525523195c1a880397813006ad911821c16b8a8036775d650b3b4171eeab7e2bb31cab766b05f649c881a2ed1e7c75c14f31b14128c4612a88809e212672cebd6e33722be749fc0802a2327d7cc5754ca6c4ae7da09a891c1f0fe58f9b454bd4e0a51af5e2ecef75f772b497423c4c649c12251070f9ca16cfa0738aa38968f569de57e21d23ca41e19f2575b819719b570ba228fd43bdef991de75303c8ba5293209598e9ff6b0f526ef6fa43060f12746dc9a07c8b2a5280506d2d499218a00488ce0e065ad8863dfed034bec077bfafc3161ae11163f774c9ec139cb2d5645518a76590f1bce60bbdac2d1cc4fda17e58ddb79968b07490841ff343cedf3ac1a30457350b99fdbc68e947c76eb6f11f1a6e0a5b5ae848e1bffe2dd4089d334657116ca14ffe2eb60d124ad10c009a9bb07005b3bf789ff688a22326909cefa80538a43198460683a9e4471b1a53bbd8866e349b387703335543677d9a4a54b02491062ca06643ad4a2f7f24b43dff7cf10b6143ad67cb1b94057efa53d0176317d56de1f6e281d8f69de842ac03dabc5548a7c980f8c8a21f6b3078814fee14aefba6045c5be1901993d17487fc98217755fbb946c6c411329b65a23f1beaa30c486814c43435bb9c359369b3f51b18f1a93f5dda68888037f42830fad7cd6950c6a76caa3eb0aa1553ec0154a844d5500273429f0f5099cf157084e086401591b370bbb965798bbedcf959deb54a07e91ed9a85943f7859369dedd6d94f3d6544386eebbd81189de3d5d7e804ecb2743fc9e2b1f55d390ecbf8923ef407b8891b187cad86a4859bbad945a5bd79d6a2c3dc5ea744dfea26af63501160e57cdb707b757c2b6f7aacad8fa76e36279837d4b118865a31125bf98e4772b2bbb74a397d1cd0ff53edfd81498facdab178efc1abe1d446f8d81074f6ed8e0e4011c36de9f15ea607049fe08e1a3d5e9edc7474ad2407c1d239ff4b0bc3678446e9122070ce4adeac8f87b5959189db3099b04c8eae02728c87591119273e30f7a02d5666093552ff32f35887b66daf533ab82c2988d4c1c6a5beea8a25a66d08982e842b471793713aa60b48e69c0a2a0e8e3d844e287e928afad1e0182897b98cd191355c60525231682082aec10d9edbf30243d076d89a3a9b10b9852f603b6d3bf65bddfc6dc7a9759f11715cca376b9d9d5e6fcc3b32da6b6e8e06ee65eca0102b82ff39f059c6891caab193a428729acd9d4bfc23b7c215c7358ca0f72994cad2a3636f244bd555399c8fc738cd689127fc465ae80fb0c14a23cffe05e490e4b2a671236d64b7f8bff6dc556664665174097238b61ba621725dfd58a6fa1c5b75df1d7ae3a10174c558603399f5c3ae3c0f5bf15a307d5c0cda1fee964db22b8f89768254c97efc8142d324820a856b1a00ab6aa4cea9bf90a75c5fd2f4e896c198a65b3b502722d5f5f333c066deeaf55da4814831026585a4bc27922c3f4b2b3c3ebad9fee018d5c454a7f491b09093edc15283e58d3f1f864030d00374f745f38ddfe4c28dca9943c9f5b9c3c368f8cfefd411a186a12862e4cc28f79b594c44b30f5b3dc42bfda773ee74147176acf1a2b1589a03243cda07a9508a02c9fa7d1b3b9b79c96b5c9f2d3f5ca7f88896a7f1f652eb43708d58a65b5b9db09456f17639dda832f0996f46c15450a8c404dad293f53a5b51b5201d72fd818bb8cd000d4da8c724eedbe4c84fa14f136676a679252d945d2c7e3f3349f7a94f9beea5afb334d341079e415b691620f70f04e0dd33a974800f6a81b68fec66b060fb7b80f2a6be16d0c484d78c2c88a129cb2caa3d7324d82d42a70328bf8262d72271a79dbdca2c1827292b4bf4c19cac9dd90b150d1179c4299c13a65226bf94e2a25cb5e0a44f2739f49c932539721a425806efac7923b20e85931eb52ebe109ff57261b7e026e0ed79eb54fba47504a94089da386ee0975c206cd5335497ded0352ee7b17aabefd6c059277c127397212d0a2619d6a3ac15409bf529a1bd7708ac51218b7ba7a4385c83bef7c2e2c74c0d823e220c930507d243a2b9a5c2bb944ce17ea5a0bac841d96af901769472de5ceb2dcea0230b7cdb19d76207f06815eaf8a6e9cb98ff004b23bd05db6ccebb87bcce47052c18104589be143e2523e7c3231874ab8ebe862ef4aa39405b87d512e4a113588aa315e72a3ca3ff692951a38e7532738c4f7de9f903bcf4b49ec12115caa2bbc765a706b32d9c3a7fda899315ac053a1b9f0882519ae659be9325bcbdcb0a5e8f781b88442d7cf0515fd7350887d2243e28e51352adac496b8d3f80a11d5de5f029b6c847d5929c985d20ba849ec6b29ff50af08b7f8936806281d2142383a45c1193efeb21f025b3581d5c3e2c2a025cb32e862812469bbe785cc8f4c9f5f33e0bf19827380f193fa5b4149fd2cd0c3da989d7130f4090fdb16813f460681c915ddec339f0ba91b75e50556fec47a8f3ff98d20132a371b23747458c783c76b3cbb991d5b0d65124b21711f927a5ad4ec04092a709b53c5057dc5d2996b50ec75a134e08ea11372f79ff577607c973cc4f8ae6a659d700b81d517a2e4c8ae86ae58e270cfd8730007945a36e2a961a9ad62e910a2f49302f72e37b5da2b96509ed24e34108def9699c60d764a048f4b15bd8c6dc5929832bbc255281f0d1b565b3437d8d5f79c38daa64e202f1e2486b6a225d84b6fc8cd10c6a1cfda57615c56b56493c513528e1db1f698336880c37dc6f28f003734293ec044363692ae938aacb95063b6e836df1a150ae99e4b620500ffc6f02d3c2c5ab76eca4e4f5f49be4b62b9d8429f7b119dbbe8f5eaf32378c6c974d08dfc816a3adebea48ef26c87f6a5a31ef4baa4ad2c5711bd842fc4f35b5b6bef928bc034772e29d7d12fd3b3b61cc39288ce02fa2aac3f5384d7795d09e161981bdd706ac5975169f5564fcde8730c8e9e333aac2f6b34c82a265896aa1f0cffa2c3922661c287dc70d38775a6102b0362580cf630bead344a7151c89a78b38b32e14e69e7e9225651d4d5e029c1e3ca3dcf644d57ba33a68bfeaa1a0774624230c57310576a5763e20461afe83d0aa7633b40abe05035e1227f91f23e20b2d2fb35738ee96a9b25cc1f2b4d5fe9e0b721c03c2658362cced80d794c73fe4987831793fe54fd9e8ceec69cc7f42d1ce401f9ff3ffc46a6b4a3def35dde3169f11afe2f511bd129bd3b98cb50a044d759978ccf24a5b2c36735f4a8d1ee949d3a7d2b2e6fa6e04c773cd9a9095188c777ba2faf365212be1a127917c8890e51b967bffb5d795ea2530742b83ebcaef03f0583b5a4b25dacaa5b0ec576bc8c8d130cb625a00fbdb9280863228a6175d163175dc7bfdad5c8e0f0d3bbda73b69623b29362c63783b428f3d7922a5199dde691332522cc5aef067f2f08f5a50081e761c4f2913036f95efd24994adbcbcfcc7b67f2e954c773e824d3d95f8aca04cf5e52bc671387778f56ceb445f671dd88f421e7c434b4977ab40ee5f5608f9b7ea08b23f2d870dc6266c3605194e09a9d6b9501d488008e1395ded04f2c8d0d744e23bfa87052621fedd6fbaaaca5ae1b386dcd2261468c7f76b2c289ea6e72743e3fb43f8019dbdf0b4504878d7b69528f44718ae4cc75d8038a4c2327acdeb3c6a6c59245c59c82f2120b46149093f23a21709d6c33e8c9df6fd25c110e7e4e248f7e96b1f914a6a53c431b0aee78db8ee06874dd6367473594005f6165249a87e8d5393cc1e1ea229a97170b82a5690513ded5b63712d0ce5d205d0024198f17a228d8f22bcec62a047a6fcbda1963d5d21832ed074457f62a30bd8f21aa1aad4284515117ff9607538eb51d51cc531d0fcf88ca9900bd28a07ef11551a114a2e691d76822e62a6c6274c8a57a33513f4f08d815fa6d6c4e69cb8c0fab17a8f8ddfe12c19a92aa13223213437ab2c1a8d60f4445a4017f2939598dd3a66ec29b695e89d79a5856594134095eca45f19823022a4c667b5791d28359c317c523090091f4f931db7c78421370ea8a7db22efe62cf1d571faad191899379ede566f02ca7d0c66215a9af4e8d8eaee682e4107545233283eb5fce62ce0149a554abaaf182ce649a4127df77911efb59e15b5ae5a98f481bb0ef1c99a95952def60ed376b73996903c459aaccae7f91011a30d6f7012136000dab754e0069367732339d2facc095341c57c88862ad0834fe7ac044dadd64adac246ff99569a120d11ade2f87666c8f801278075d0789038a7f70966c77d3e2eca2ddfb93524ba5b7b7fcfe082e6f3d6886b3b42137225509d7239e61520e98c0231562b6c1a48bfaa595b97eae369d9fb867b9d2b518b5ad89d95010aa1603afb5131a64f2c77524ef052659fb2d28398a995494ced22d049a22e76ea742391895acdd52ad57392c0b5295ea0f3188329614e748262de426f468b782a8be5fb653de30e49a986083863d93a004bce83179b28551d2d637f9ac90c28eeb637138b582491f55ebae4caf8fb76fc4614bfa141f62bb84b3e2ebef9aa8cd8b3479500e4b8c90ee94c49e8568d48f70a97f810b3f92a302e475bd530d5287bed51551d208922e93ae7dff3826546786d01ed0187a239ec9b8ad563622c4d849a7e5f74b7e1f2d1d13eecc1f5eab5ec6931d34ae1cf0649b4cf3086e85c48e6af65d3a2c97ce4b90c21c1048dbd9f76d47f3d77303a7d4d4228ed7329207655185cbd133a401dd27d6dd8936dae049bc6fb4a43a661700d94cd8ff9fd2a72a5a1037d5388662543abbf6855c2bcce3ff48a120208fa26491d12899d0c65882f715ee6e93f28bed2679a5aa7559b3ff172a82a96b1282f642d40fe5ed612e91680c93aad62000baf15bde39069cea3150173aef8acdd9c97784c6adcf93b5dfff574021eea110f85e88b446ac170a5293dd211ab2b12ed2aaec3114f309c2b4c13e883d91327ff45e8421ea22af943ddb9c214dc95a94a7624dc40faa378d1ec3c755e25c30329de3398ebe0327ee892ceff16b5adee16afc3806f8b6bd25739f23907521c06e90320bee22d3f754551f31555653323a9220070efa5242b183fb3365a7d8fdfbf8a95a3138cc71673b2432bb2b54ff07c12656c1bc10066a6a0120fd437e91ded602f30e13510dc192d657d4e6244189caeba892edda033d490732f8fd562c1f85dbe9310cd7df7b12cec8c21cdd4c9995de536055cabe1913b4d1d991e154b977a19512cdd7427b68c9d53bb59be4fca63a8b4d4fe9ea2714ca07cebbe733bf3550b1a9f62105ed08e7e1b329fb0a9c4cb7ff26a9470a29cbfb283543aef326aae261555569bc0efac348f9677f67df59455ac5755720b9d611d1b571db4b1086d59b8ca443fd1eda4197616bc8657e180ac710c3d8f21ba56cbecdbdfc4336755fc215f552fd1693e37cced71a8f242d3328456d0ad64f2ced4c33dcb08fe1dfb71fac591a99c151c8fc9017b175a21a04aea05ce380dcf14aab1ecf42e4487a57329b73f176c9b87ec17108fecd0480ede99343ca5caad7826f11d8903cf63b10a1b5c2b917ce04001eee1a7fe8aea78e1c32d0cee443b16e6d785111ea8813960469687e1eddc4d8b979be86295df22e6918045cf3e533e9f93a100ac582e3bab559e8bec866405f9d55369ed8768448232a148336d1253f6d3debffa81da1069eb1de59a8d955f8e00ea8168ea8658c16fd9ed04892e7af2f523cefff25de209e56e9c3b4c448e7e32afb5718778d306a9bcf61e6677aadfd604f15d433a567671d63f43019e94204a550f4b356273e5133f0aa468623bd8944236aab1c5e19c449aeee9c620bd057218a9c6cab1e1bf80d0e8a6ebe48a0eb35204d2e951bb9c752c71acc3259d5567c8f82babdeff387965e59caf39c86c53ef1f400480067edb79b70f388417f09ee989d306f35f8297908629f13459d2094d4c45f252fe6eb9212cb8d77960191d71191c03fdd7aad5d5aa7afa696e89c99d120179732aa8a3e6ac933abfae0606fa0e078f761c1f09f6b0cc64f0f8e167545bb22232e773fd268bf9695837f8ff3fc90e0741b4fa71a50cff68d9e460e851089ca1cf66640038782fd8c80738ec6dc1855f74d0cccabb4d84e5f2af83a98a44f2075759b5c23745d0e33b730cebb73ab9ed8c8c6e0bdeb4996982b13694d66d6bd341074e5b7e56a1466e559807ba23c1a2e2373b6540f3facc01aba690805205a8f11bfc74d4b2701688baabf495d5b87938f0baa45fbac3736f024880386b85009edba18285e07a8b46d7355d246a1bf846934a464a611e3a230512fff853999127e3ef347f88b0c563627502fc3de9b11a4a80e01e14fa6f1673c824eefc0b7d3f1aa1a8549365a63a95ce8bf166b8c8ad282a1d9a5b06f0132059517569a5a8a2f7b534f822c7315536b0a88a930a3137892a6a06c86d2522e013a4eac9832fa08ac24e462417e40a005208eb86b691d58f4c8bc82b1b75fc6d07b48f56854db1fe061ea5617dc1cdf3417179056abf928eef12563a60360d563c9daf969cb9737a525cd4d974592f16594a4375480c2eb41978b41e03fb48a88c0f2daecb9376ef900d4d47a7dbf7d1e3f7e917f889a3b2b4710e595d386b1e1a0680de56021a9487e3f9c613075d839febf48c5c3744ec44fe6552b11a6fd6fc485290145bd831a9497570557013b7067486df6ac1862cdca39fef15d500b7e28c2595923735bcf4e3ab95509bd45e52a4bc3b9ffc38d25d3e27854a3ca8e4e26a4866eed9c6e3604fba0db65a6c91029707e0067163fb52f72abf86deda90c7de18237fd17660ba92fc427806ed598d4a3359729750abf70645f8d3cdc5634d60eb338bc2281bd3710fbccab1247cd3eb7963c9c46820da15cf66e1fd5cefd9ff7f562f4a72aaa15abda7be8dfda8435662052e36ce1d1f4fef6c1111650267f682402ef3f9b97737c5af86db8c0c246ac0fc99c43995eb8cb5b4353079463af2a90b865c2041a111916ce0830b195f0a00874912f3b771f39631836bd29057b5ad4dc71ab517c396cad82e9d31d86a691e82afabab71340dfdab0b2677ae437ce823723902a3015b00edd6639b1d36f669c67934554ed04e7beacdb6372fcccea641ca77779ebebdd308ef4c764ab61f71b27caf467fdcadb2d36bee49f103c4df75571b4257c2cea459c15a2bd52f2c2bd7df629ae20c9ab853f25890be9dae831087d2161291cccc48d6bfd4143d19bad2922a20ac0316f29b277dac55017002327b050ba836131257ab0db76aad90d2a17183901b325c6cab9861d6b593aa447dd3ca07ad9e4658af4c51d782308b1f83e892b04c749ecfae959d68f12150cf309f90e8247eaa7234b68025fa40728422af00ce7d27ae78c646ddb0083eff09f72450b0cafac998427f618cd1715ff8c18ce3205cc47652c2c993568a40345f5eb72779b0004fd86eb2c1764525afe3d44d1e5ef3add97eb3ace00e9347afae4cd5f9511c33f807362e6f855098d3aa38bd3d26128dbd8df44bd80fd95ebc643f328a62e1a2f2421642a0c95a7eac4e85ebc41002fa5cfd2f7b40de7aac2c749dc7b65400625748c463add68c337ea116fe396e13ee1ab6ca65108bc8427dc1ee73983942f75538651245b4b6ec931413bb4c13a6bd514943fd65dbd27171183f6aa2127c8449369d30b6f87c8142f7be3fbcf1ead38ddf0c6157b0df3f852c1172663c8de5823db9b351429a6b176687428203e0315bfde28dec6596b15ed03be9c8b32fa4616dc8424a332aa680f9b53a1502df5ddb13bee822c83ae4fcc2f332e1d3a57fd18a5892b6d5b8639bb5f1813560d19240c3b4810faa1d8bcabeae02916d83b83474920a261d51bb09a8b871359647d173a61cecc81336c525edb5dc713e8d37046da3dc58687a93811c13bc4c0ebaedc5868ae89f85b59da4b02d751af3e7986556a75119e41753d10ba14a1116a127c62bb841a668642b763eaf92c03386436e1be91e3d10e6f83106a446e96a338e2ea698738bf6b8b34349e56c0dbd9d4994f4633ba2962f0cafa978140ad480dd24c8a521004c373f3797faeb90e1e9ca4b3e4b5c470a39ceff250c59248714e0d0d6e8381986fce4c510c3008725e6c1e6b04fa9dfcf572e5f1a120721472dc512c74d2ae082a4942fcb8dca9d6b3ee1764a0f3c4c212a8e30260f3d098575b04fae84a67f97e5fe89ea784a0279fe26f784848a2e4212b492bd6e24bd4cd5c14d0cc2a3616202fadbc1622e94bdd5d7c85f9b88c9a0e8ad273f0591c67ed80e626bb1e9135e137a0a49ecf77ff6cd310973c6500ff9bad5b5787b15e49179987fa88f077fd12e32e9c04cc217b587fbec7ec833d02a131e705868ae52eaa64d83aab95dd497c681b0d2c7e502d371e776cb27038fa7b094286daafbadb96429dea74f4d8e8f8e3df30e72dc6120509f172383d77d235c20373565d566be43eb966f8121fe23cfa3824e1ced9bb1091631be68f79f7a0670446479b462817c02eb3c32172d057557dc3172b12dd868099eebafcea2e6e738d213108a4faa0a7c30d39f5e9552e42477fc0704b9314b14cfdfdbfd6854d00c2d4b08cf33c52caea7c264433c68c41c6e80c51911c70e93f9c6d338f50d19965bbbb6e6a37167c0d70f2669d5d2feb413f7245f90ab387378d8bee0dc4a55fcb5760f235d0687b51b9e2a66cdb9a2b76520dadc3b58b101da6092bdefd940ede63791edcdd93bc71e82ba79c579e631e0760cba65f32417d977cd339660b4ad3698cba07bf385b0235fe192739f05167bc26f23b33cb891db00ab20dda7aae49d8eafb080829705033f324db6eeed74e327b98c736e8d91ee9c98ada6c686ac3e406771b287264a3d0e53095b835c723a4dade439d8e51682676ff8860b94499e1407dc1d523e8640b7751b2a0fd376cc50730cdb65551bd5f64dec28f7179538337346787c68e0ee50a240d563758714b06ec483e2486885d943d65ed65292434b69ad965271caf1f97d62380345602075bc3a41419cfebd0d88a681c4342b9b7753a3634fc19d561ec449598621227c032591e40ca818edcc5dfb3aa86450c4416c3c92a20f48bfd1421a9b208f56ca8cf8e58278c6077a3f10ba37413eb63783aaa089b217e755692f1b0d1e6d7bc4455153b60d3e8bb420968181183967b4b942fe0db86b1de6a7c1ac63dc9c4227a5ce1001950b6bd1c65cc8ad1e67e3d664a06bdbcf820e3b473cb09567a9d6f93bd24be0880165ecfbe206fcc5fa3e2affa5b682337a7c16c377e9c65500a7119f621220c68d46d55e57975a25b5ed45184d7c6e1cd95432db77667cf31cc57f6f2600494c1fe51be80184222db904ed2861a59e36fb1ace1ae02c068250ef9f4e51c2c235fb2f94b3b00f7f1802f962578723dcede3ef035980bccb6d38133c7936b2e3eb49ce18c9f2c0965ea153260e59136ab627c154b84c9403d45cc58e882e1cddc92add480a26ce86b8372848c3ac8aaa2e1c320220b52a8eb08eae20ae68aac994e2a88824a5eb791afe1447d443447c15852a16dac0f102f6ec6cc8832924983f4070cd22551e7ebee86646707b7e3b1d7fb08b816a7f77a68d9e28ff43d3264efe0497057676198446de33f15baecce729ccf3cbc77415a5d64af8d3a0dfac6d0c042ec1c811d7ec4e973049dc6a0eb9e0b04c91ad08fc7e0f4c08df76e33986c8da0c7a97eabb891fd996ff3f02e104b5dbdf9b7831c0326b8c48956b200d8b95ea7fb30d3f345a0447c39a3a5db56a664420fbd6e4896346f4888653f7d72e813cf8174b385feb65679c62f0f95d0fd3f88c4601165cc71f47d43f3b801a4ead5876e08903b2f523ac97733e25e5f5e74b757406165397a0045ee3b3eccf8513ad704a08c732c921aa775c7e36c469d20e97947026abd1778493790367dae22b9d70e04cc6ccb76b5faca3e5d6844e0bc50b7c2c910c53cc872cc5c010874379875a83cf0abfc92e2c4a57b644fa0ab02ee43c7e8cc328c8ef1cdc04bba8a29c0ead76d08963d5d089c0dc31aa4968d634f6dc803b7f7ca42fe10656ecbfef6f7f98faf7024a6d5f5049d3d16a97e23f366243806c58119d2b20188d0a9a209512ecde8fb4d6a1cc3b3c12ea4980a19eb3ccb7b53ad52209856cb5ccf01b73e420ec7e213f24e47bd9198f4509f9548ed496250749f49dad347e4043f6dce0b9735826d4a554fc043be7dd4d722b61aa64c7ecb3fca0eb59da5ebec9664b5c3dc4755d2647e4d41aaa9aebe9753804e38b5028096f964fed9a5c86c68c642a3b04a10df45d79cdc1a4641170e84b07d7067b07efd713c11c3c08bf401cb185ac46b4d4f50d69c5426f180f5ea342d7cc38e214d112c21a5b2affcaab8970480308cd3289c468b83a4f5b8ed822e2c2bdadb072aa5e8e3c1f399ca90d1de3f4cd9a00d474ac42e05295c43e51cf4320db89f78a8a59caef7f688d9a20f42d20065d9a19d3db3c9555da4680ae3562a7e2b612b7d7df47d5e447ba40e166d365a9a4b61cadbf99f16c3b75793b43751df1fd5547fe2fe44ee3824e85a54f30d0fc0f0fbaabd656a87a197625e1724737c18017109960a68f042148cf554615361fb46909140dd9ba5e0165279211b909a8d0eae444f9a099751d0cd60cdfe4b604c26a05850d247587165af630eb2688a9bb0e86a23aa7370408c4fe739bae2f1a63ac329eb81d076a8ea3f57c124d6355b44f35a2875cf390cf4f62a8bd1ddc14b825e4bb18a4fa236a949cd991efbd6651885f9b0caccf96c8e504be8cd53c722ab890870816744bd8ba37b25b59503a92ea64c13b296168c9d25de7104601d726e6559e9eb466d1777e1f79945b63eabf6ea511694d22d915b4313b9fdcb34ad9c2d9d5d450fcccbf82d1431bd991f9dfc05cd95d4fd877473e8b5614859ece1d79584ee30ded1e5676c76802679b69fd6cf9c9413feeeec8fff29c5b3dda9972977bd7c096cfc83ea76475790f04a3de4657ae229b7c225facc13ff83a6599aac01e25a8697d487febba0df9bff4339440462996045cff0245aa5c7d69b0dd04af41d0e238f92be64bfb4624970907077d2029330b864ea99315d9811858d58ab58a404bbf5485161a1612bc47e6a0676e451fbd209cfd024146d456f39139b50cb5f7df726be05da8b039bb246307542316fdea80fd80ceea02d0657ce2028021626f9abe05757bc020cd009a7a764ae70e82a917ad45cd24a193cb048c8d14be9445b63b7dd5f2fc084f309d1bd9b19d093e7b09b5cc927894594ab1a683e0d2ff510e7c414e30036c95d308c5a04f88036606ade109e013e48019612b30097e425c282368b5db048b031f201798095b0193f00be24099410b7002fe0638206686e358edf16bec1afd8d4ee3b7f16df4373a8dddc66ee3dfd869f48dbe46af1adb0dfa763665178128689b75b0dde187220af485a14dd085f09939e78cc17a9c3c7e66ce21635a4e93d39722d798395b0f13e3e7c89d330d967372fa9cb863c6d1324f18be47ee9861b60c13e677e2983246cb71d2fc19b8c6ccd162e6e4287d2e73206724d8f2a17f52f89a38c6ccd1629e18fee1e0486e091b4853770f65f1f97be0ce8c9375aa895121d573ef05cd9e76df3799ba14a82dfc5053b97d38009eacdad67af1c8c53e1d92883a5ffad380b420cbf229f56115f427e85bc3d2c87f7d1f293b507bbccd5667587ee23b807c1d60933f0325954c18f2ef11e725acc54a522370da8206f7435630a88d778e2b60aab653263f866d7211eb82031e018b8231098cdc8962bf5d82a539c7ddaf7494f2972a24d1c04eb3012101a0f3043e2959d42764987ee2f5d1e11afa4ed1dece78d48118c83b8991810f822692371e713fe66b6b2912e3e04a4fadeb90544590d3e7d18581f773e1e56f61641acc0573de12d6af6a0d78a59f4037767d25e33606496cdad5a83d215993fc27270dd6d22ba7927499afe0f3aa77af935be6fa7680965757c7cbc57c42cee0ae6c7833cc01d6b72eaaae5180aa3e852b02c973a85c017094b6d0f05bea797a0247fefa4cc50a5dce370471b0d9f6d465b6d002af78089e6aaba1dd5c56279b79c0357350f8a2eee06d2084140c4b1d805eb670f6d3bc43f1e54d8b391898aae102146e2d10e5e1cea833c895fff409fab2b184d9802e5cee2483544d2aa06975b483180a0f4fcb2928ee5ab0c1c775182f8ba15a882bed8c18f54483fac31f9bfd65d67c7d3c56f49194a88e742f9a92bb641c829a6608558975106ddbb6dda87a00ac68a70d12e5e061d2ee0674031d836b29db95eaf35676312dae63eab2f5d48c9ab1840e06969e395d80ab766927e3475ee314249585a80749d980c51c2e0f1d74d63b9e6835859f47ede59bb2c80814173d427d94d84741945cbb4f7d1a2a3bfd01fa4b512d40e1e36dd8c0c05554378ca76f78865f39458902a6f3071bb5fdbe7cd5f86e2511f5b77b2efe85eff72f5f65ac020091516dd31002f052b539222fa2f84127c6ad675d7b505b1621173952d648942805f969d7e4a3f8bd9cdf338b5f42f5f39a80e50345f3dc5504707b78ba7328379374be3c4344101f7b24e78ca78f6002977546776606c0e46db31b84757f95e10959184830e28ce5ab43250401e3b022f7340dda7db83bbd4d4e81456f6f82d1240da1cb35d077cc185d141b1c7ceb204581407cc6a52c813b618a04c7f806caa8df3d09b04a1d1ba57154867fe95318446e12aafb1b0d77cdc0236af234f7724a65454ab80c144f3775c92cc15006975936124b1c7cd40cd6c4ee3013195452dfa1341cb50228cfae44bd87812e15a0e514f5ca09eaef397dbcb84a35220d686f59b634be8810cc306c03170223c95054b99b8f33c1b14b20233cb3df430a868cb390c1ec34d3644fbd6bdfaa555697d7cb5cb24726dee2f5ada3c4da530ee15a693ed31aea1bf3a5e937adcfb1d68ee301ef9e76773c0674bad3d45a00adafc360214523581fecdf8464a40481cb22d541abd2e40b8ef0c6b2c64f2bd60ac3953522a148321ec7ff786a5cbdda9b39a791e09dce1fdcefbc08bd787c5aaaa79ca9602cd6e0f78b959163bef69198ac99e8cd7f9a8db0ac46df5df67960829408e2fd72ab370d786214cd223374d57cddaa898df01f7dcab64767004b9bc907a697cf090f10447c46b41506910d18ba78b4920dc3924dceff96b412bf23688150348a0d51cffd1d413b1aca1f142394e3afcb46b02a8682fdc88b15ac753d5b6f2163a9e5b1c492861478723700fab7aef7f9c3c7859627491a888feef4943067df6c42040a9ba8c93acdbde4bd03921b6278d39fa69e13dad6ecba0b7464c6b70ec34b93451b05f4c4600098e8b600b4681109a2c7340ebed12e62b301a936349fb7dbf7b0e4e7cd1ba284a71797a4dec830c731b37cb65adfc25e8fe8b27221b9debbc7084b026a1d9f53b0cdfa5fbc066d5d2d97311b27c8ae715085a4cd42080cee17c742163be37a9c00495978f9124df0075a2d8d77b3b575c96568a64a454c20c733bdaa3108d771c809e8d4a577d566f6e071f2e68ce086978f01af5eb88f80c990bd1154f98c607d6944bf6ca5984a8f4298491569d55942a62734836f07b17303723ceb98880cd87f3e0a82094cab9e73f7973ce217cff33510839860ea318856af9d58f16ad101c2a22d722e456f77c5b5dd27c5e22230a384496832e095297502587130b11645065f821443d336a74f310b4add2b779c18afe515f513abb14f1aef373d4f20532f612bce97183c56da0fddb77ece6313092d8fa1fc45bed5fdef6f0dd3b68b82024aaf760625dcff38a9a49c8c74d0cf8e1e574ec4e614a12a01905863b599398275b16f12e3d997c5049550196a893bb4a2ec5f5b6eff2bdea83b986d1e7a94145cc256979b5f956bcd9767498fa281c368248c8ec512a762d76aaef4ce388c4527d7c7b7fef2f5ca4de219be1f66189ec17409a0818efec1e3b1dd77c15a05bc63d0031041439487a46bd48e9d05a352734f3ba923d262d0af8a69ba2b4c1cc58055932742516311aba55c8b8196837e8622e1fabcf89002496e234019ed7deb3440a910209f8917e2ed152aaa86ed67618de87795fbfa3cc32e15aef20c1c46cd599cff0b030dabd2daef1df37ad186a75e2ce2addce2ae876876c3c0b823b30515f434243ce88baa3b9b881a669ab4a75630a774227a03a866ecd04f178be1122d2e99b5e00d5e0d343620347ad070e341209ea49d52914ce47111c809b802aacb43b88bfbb9a568211df44629f642ab2401623ba348d3ca60ed8e619005e1b9290b08e04b2ac7213aa7440a30e903847d6eecd39f7580eda3ee9dce0ec220c05fb2c51dd34725acc8ce054226c6426e942f7f53f24efc8b1a4605fb4e6b86cb4d6adcaa8bf53a68512b1814773b77557d8f6f32caa4370198910a00f99e9382967342e214d981edbdd03d83b91513fdf576152a2e7e70500c63f1ee95962dfded85fa3047526fd03398c5abcf3a3e1f02dcee7dd60d1d2d0884dd6631de69037414374dc5667e1180790e46449e10b637610e78e4600cfcfd6c7e1207300b0e1dd01c7a1923269269c866f8b6f075f3d5ac56904516f9ee9c5937a2002e66a0ff7c9c4c18bc9950c9a489974581e781d2779628435592d6f4b6b998259e910b67df459514a19f9445601155232449e94d723a6f9b92ab9d6727430c99c6282bc79944a43f2aa476efabe79332e9baff489d26676a4ef05f07964008361b60cfb10114efd31a910886d93d72ec3605762f722b55f26eb894e91db206d060ee4ea8e9238b974c465cea1c14a6fb06543629ee1165a34ce39bb1ebb617e96d80219105c3d35e3ddd246e2357a1c893e4f660cea2398632d567c28883d2e87d99baba04af7bf04542c24b2058ce767cc05232b48ab9d61eece5868b05533401dc2ec8bd7682de66ab711e89848bad04f56732803b2c3fd76080f299e7224e05b0a9fad8fc250c608b29be452ed8d8b6306556acf9f389a1270836a04413609a1d1ab6e1dd5d9d235057235390fad6faf8e21fa6fa9fabaff3fe86ae8e16ede74fbbaa32f73ad664d9c495ac98eea0e279ae266b9be1be102fd47c6f91570a91938ee7d3b926e76de3f3d7ac2ace80d4cb2d12a735769c2113368f28b44ffce9649faedaa6b98b7469a2fd3b5664608d66d6154ce85e4330bbcf3abf9d513c40d3d9da9801482019abb7fcef4e749ca616b0978a982d3e9c866bc8dd77f93f510422bbf4a5d47502761436d0d6e951822e396c3ea2f8e02b8c2b14d00bbae9f9cfb97c9d4492166458be0e3ca2e31a663b048bafc4cab50015039f67ffc3ebab48fd1ad68fc7106b4f36dd6f69e6b75264fc11c5b0c791de3ce77f9ba2b7239feaf4a87f7afc0bcced94842ff29d82192cf7daf49dcb93c2028b56ca886177fd293591807e18384558ddb900316b04ec3d623754250071fb8b6af2a4d87d18fedfdffb807cd408cc80f380030762e57a05d375b465a73f5fc798c68f54b4e809a4cc519618f7af1a468e126ba73d1a07906addcbfac2296f0d03de079189249d13c7377b9968a38ee2e0a2f6413a0c8df57327b2ba920f7595cafdb8fa79b58ec9a0ab4f5604d95ad1f697ff02e33c5f76e615fe588546fe0645ba6d1af5b6ca803184912f778b0db503c8e9b44ab8f98089b7294ef0ac01a60a4f1187a34fe4262909f561fde3d3ed1e6a5283c15b9964b198444d106e50998092d80a547d492e12f41a0c023fdc80ee111c946dc629081a3cda10a3b1e85c424ad107a4f6dcb99cd9811e6b225721990f41add00ea8b35b85387e09132f7e05e3a0ac49c9362a2a56b63d10f7c511b4c20250e9cde6d876114608e5d05eef5fef43caa203487dc81f6b805f97c80a0569e57b159e399600614a1ecb84c013930e49a7f4a9294f5c0b51e682cdb43676ce46f299b344ff2a8ec0b8dea68df35a3b10d5a5498a561a9f73f8679c7ad9fbf213321144d11ce971fdb9001581a8274a7003bb88259a7079903779b33dfc77dd5e2c4e247448261498158c4a6e2cb858a29cffdf2449b5f66584447d9a0381680f490accacac57bcf6c0ea0815357ef47bf7427a59d0de069675a8c7772d4ca9b6f6489b1efec5849c33ab7fc125cb50656e7ebecf740ba9ce542581c42a27bb853517d283e0160e445096a44577905f4b75056f4f86ee24e71e7a26fcd67309053f7a27cfd25d5e25cb7e152b2593e52db08390b96e867ab683cb6bdd64de1fe0f3d226486d5260e21c98a3c1fdecc460aa4589c9c7e2fe5c773c307d0a126c0ac11a4eb59e36214f7d9cf588b5da94fb963e3ac5e1690bfb9e794fa207e2a37bb1c92da3e0c611e02c73c9800c8abb6e3e96e9914e449d4ef6a1f531cb9c04b8bb0254dc6b99b33726e85d243dbe6afe96bddbb7364db8f90ddc2c55c56b7a8787cec8f99c2fb3016637cce6cd02d4c8edc45dab90e92470757516ab626ba967a81fd753c543e85630b70d7af61653abef4c880877201e7686d60c24773bc15c9a8fd5b4a2539bf3570ed1794069d31a044eaf39408a99bed0502aa6de4356809527399936eb60edc68b1be4921f5bbbd45c5ed17540886310de573e9024bcd290724386bf95602391dbf5c2a3b3c232d9d38a67422c80dd2a46f04b2baacd4b89c52986a90a5bb3a5e41740331f57e28f4acf81b60769c1e4302319c427dd1856f10704a8457ea09a50d7dad41ea1b7cbfbd428f3c7c2baffe07804800bcf8aa33785bcc42c8c910bb16217f466c237eeb8c9650d606240dd641329c2c4a641807a5cf4af5c070b261e4e3b3db17af687e2f946db01cef665837df1cb5ae982815b0e072ccc5eb6ea4820a553460be7344177a439c41d4eff30d84d8c69b360cf1dcc3c571b4b37b685ad6af7e7f30a7cdd4bedbac884bbd3b2d6eb4dc4d68779abbd387eba064596bba0c1765171b336d0e6c69a4be90223d0bb6f287b517b76b7e1ab65690b6e9cb6c2a71722ee3be095a78b3d4187e205c97e13b2f9212549ad7ff06a72ff5d0c7755feefe737097489ec6006b38a3414c8a8993f9f10bf5a5a0e9904edfc24584a06992e6de2c6738370cce0ee463df57aa4b77a59aff5ac9ed54fe137e5c6bd996ee8e6546481d5baf16fce1b74e3bdb6f7ee656f0aba21de6b1c017d88b85367f14f656a5b0bffda996dd180b98fd1d16854290a47847a04939bc1f9f6081828da7351104faf120eb2338274de14f873d7a7a969857b31957f1e323c82184b50b6abafc0b446889e2712db8579f42dbc752eec51e7a1bec5de6a4b7a27f678dceb3128d7b4a897e49e75b84352cf4e3d9374aba3be893def7c9f20fddde25ec7a05edd92f6b385b3eee562c585c2df2cdf2f41fed0d2abe7c2e2fab2e297e15907cbc50aa3f4e3d27d89c21f593eae1bf0acf657c5ab7a710dc14a736771e5cdaf90c060a5ce37dc5c518c66dec5952957538a577ba599cfd2cc4bb43206654af16aacd442b19a798b2bb9a8a614efed95373ea3999768259a942dc5bbb1727b60cd0e45375756db89b7f24a54fcbff2e8e8028d9f433f905edb8b0363fd5fffb90dddfe47466656dcf036f171a95ec15a377913e0e325eb8a5517b4dfeb54330b3c9e039aa3aa855b3052aa9a74ea14ae59b46ba470d6de23dbb6e9045638eb56919daa4b16edde55cadd2669b5a2c429a0621a8c1a841fc2100400529608e28a8c5c5e1ea20781e27fafd7eef55e12c6bc4fe8b1caae37b3b6d612a2d636217b6fb977e508e4071a08d3d5c93063a6f70428304134ade323c3ab90c4aa726154ac90fd26ee31c4ca02051e68c07c56a746a353a650a1d2f05a5792fd581347f922b613726c3134193e653493647590c28e0c9f2309f6abadec35b9d845c49f179b712d57aab7c34b21c37755ccc8d0c464f8ed03351226c3a334f003a10e0a199e7b7951c67824938ee24ffc9155bef803039213421d9ce10f6764bf0afbf1726e86af49d8afaa60049d3c8112447342863745f9a123c3bbd6b0e172d4ab65b75981ab11486402f6e8d33bd12cdbddc0cad938f1c795e1332e70b82a71e28fd59125fe1870f3848f8ee943391ec77aa932f48c92c68606f6822a00e00a226fb644596baae596ba6a3031352bc4d4acd082878367430cac5981082d980183e3f52b9b34934930482f47469c0d334a22986143110e36dc60030c830866942237ff2cacd79ea4b36389b2560abb59aa5a666a1f1d4c6c73de4c2980f6726d75777777b79431a3b3bb71f79d73c6ee8ec51e514a306c7c3f4208514db8bdadd37bbc72856d430c55518ecfa109413e44987ca802473ccaf111c9a7a5813a56ee5e72779883dcbdeb7e1022773f80e1451047b0c1858f4f8cdb5879dba8e46dbb0d236f3ea4206f3e4d70d00417b090b5c336d0c828ed912965824fa64cb041a66d84e00a0ebc9a1fb478811442190abde4243cc9f2564a964b4862038d2ce5490a1940b104a38d04d5b26125890c18174c36583093e784a922724ae8000e9450865d2204f2473a401cea92e59328813ab03f293e225ff211952f0db046fe88c421007cc93560f2d540470d24a5b5ad96ecb70e2c0cac819747f2104e2c7b0b14d8efc740a687e99b4803b38940e4696d8f1e666eb6daa3ad4ce7040206eac82f85dcba17038170b1c7bc95f1e6c09a590f03759460a58c929bff4e799e7042ab65ed5773e2ec0e869929868135b1f4ec26f172b64d579c2c5cd77ca90d3b7f8900b9d820cc566126550b2c0e7d13719ba065467b1ece0c4f3ce95c99613fd86bb5b6d592b03c3529365894bf24b0cab550a7b521ad8a7603ad8a5625571f6d48aba255f1628311484720df92675865fed9dbfb0f8349b0b6d24674a8854025a5437428d3a436a24374482bc106fb86cea6d995f436195ac928d7734a49a59452ca7e46339a6536349b369d4d2af31349da858c8c12d205ec66dfd992ba9c4497a3f6baeb4f292b97cd3eec322a3749adc8ee6e39a7fcbc72ba9e645795bcd3f2ba1c7541a6eb8926a59cb3bd98156d104688124883d50f5e6dfd633769ab924e94ecd47c581626d8278cd504ec8985524694230e803a992764e8c29ae8cd63aa0242424242a236dc0013e20398902a3f5202a56f909090909022ac616541ac0c3c071c5720f08aa214a1a13caf0cb1c168a9a252b56aba9d97e23830fd8a515830b231a2318ab245571e08a2427a91e50d07884068769a8e3d22cd545f1401348f4304d234d3b2c841ab2a14d4920cbc52d5aa66da81fda051a402eacca01ca240b1816ed92dbb65b76c198dae1a72c2e0c0e0ab6f61366258179113904498bf885d432ebd7bde943833d6dd46466b7777d3ae5bb7d464679dcdaa6514d367df289d31993541d5ea49fcd25efc8095313c0476ce395bad5ae984dddcc056fbe6dd314653de24d7a5bc4d4e526ec21a9ae54de3b2ca69336f25aecabc99b8d2c699386eeb60e84f53a96ea7086be067d10661a6076b20aedac4301bcdfe699aa6497a654728259bb3c8890decc0892644232072e287a8893432972191134300b52a154750031809694058102106900d8608030968074700418a15238080046486116140e9170c324018525a5fb4b42108815404243c1a08f10321bc60d2da322412628bb90358cb22592003322db0801416f0895181dd32240a228d9717b6cb902888a3208c0e932bb89665190f8ca094d23190fa05c748aa3efd823ffd82325158ae06444dc0c0082b55e4cb5b020bae341124234413506cab89272e2840c05a9adc618433a0384a810704bbca70e88c19c83439a307af32ce08e3c76e190e9d518433d238425249ea17f4f9017232001b3ca12f1f9200449524606087164970923d20609905329a65b406233489126589295714418a200769e4e00a1499cd3ab0840c5c800552e4600b1870f144e3828b2856605944404de45386444045e4cf7e8600a21184d08f1292f82162090330f1092288688827800c1044510928853434308411c4f8c072190ea521254a1a53764c61b30c87d2c8c11a6914e5c0b41ae3bd980426d7971a6918e1215c202221a55f5068a84a919101c038a23979280d339a20c1450f9080381a52034a9e191201c144fe9e63d6c46b85268d6a9a0788d08630541a011199107caa0a8aa05682b42b8698568a321a1021855045be604dd2c18f5012183f0308824f52108418c0109eb4981cb1321c4ae3072220903a0ed4564ece6896d11d32b02c19121921450b234600c508275e51ac29432223909899c2d60c898c18228527b6942191113e438a48aa7d038980e0402bc321352c906986444c9068b083ec8b21542a08c328096900d10408d90b8260d37082524a29f5a10645449c0f42d0807641240411911055e45586444240c9c0061be76bd958637422e67863582d43a21f1f3c614b39466984221aa29f2d887e84b2cd90e82708099d26c020065460618231b6b002762101318020c6154a88220650aae813642ea0598d28d410418449b135c321353a60a5e529cc73d639e9a42d3bc3f0cacf4b7b764398bb7be291a452ca86f204310a6a6db568b4c9df12aa840f980fa9048da22961e3db4a53ebc369b610c6186b8510c28cd65a82b07ea74bf7eb2157ac69a734f6a8a7771a654a9f4d082b841aaeb7f488187494db89510c3a3a12231e5589c10e9c32d4ca964a14231e9dec91ccc596b5167f47e8e930ebd262eded6157e4845b495aadc3c0e9dd5bdd3bddfe74b256d5a24552743b9db6abeec7ad4edf4eaadbedf6ba52e75028570a0f3992ed37fc1dc991db56aa956d657bc2495a79d5b276b3276b397bb2f69e77ef301175d90531ad5e254e8bea36a53aac3dfad445fd645d4e27a96ab5be242d7b249fbe42a14ef4747a94cac4fae9aeceba4356ad2399a6ae32e1242d4a8f504a69abd59242c3913c7f4f4669e960043a20410ebe324116ade4562283f84bc2e5c943f6194f5e6997b48361e2af475e6d6e938bf2ae3e6f5744c5624d6b97b4ecbcfac7d2e4ed3798b5c7169c211e8b1aebdca7655d6a3bcad5e567afaaf638777ade263a224a86441e18ca5ff421f2405046d939ef1019a1c6d98b8a1135c48b11e3af872c53af29db4b7872fd112526539b5a08cc8d75e0c94b622e9d967209efe4d4c07ef028d325ddf23e7d9276a1e5f44794f0b0b9b0d8b05fcd137a347449cb9123fb459fe8d2e28297b476a54a9c167c8408fb4558e4431bdb108158ad830748d954aaa1d6fa392b2cbd5edbd0b0255c85fd603089e3daaee5489caae10a68e7b473d8b51d265fa68a2319b0c6749369337da7ab15ebe1b767fae5c242261cd668d8e9d4116ce9dbe72b761160bedeb56123f334ccbb4c97788a02c0189379790ee7c897e93058637a16b604435ac24876d305c2f4cd74984dcf3293e9f14a1384d2643242c34ddba0098394601f83ba54a511cf8305b5621739d6b05f0705b9b8b05f0cb22252d12e98b029c3a69214b2aec0d22089bf28f412d4d2500029cd32186986a70eb209547b2624871cd8c6a15a39270b8311c2881f10a3917cc9d2e3c53da55f42edc94fb902cba47fe44b66b87ddab30200f892bf425a6e47ca1848338c0e2437f87a81a82fc5580f733d84b53edeac529afd19968f6cd8cf47218993235ff252ca8db2b0618d5a48ee0c657767a8a83d9823cb1af68b463627e7cb89460be897bcec97b4f25808b6d7b0972b38326219adc07eb625676715daa8264cc861613f2e77e9f51c9c0a308a9beab36f56577d536587dc94df917d6b3abdda7b755557a6306c0f6733645f222f12ed11ef40b3499b37562b1c93a53a0baa57f2f3f26ed9252b6a3ad4bcc34b86404fd62e85c0ace1782a6fbab2934175d3a5c49bfdbc29752d85e54d513b2755df698be52546a2ba09236149bc446615ebf5dd11c95818ce4b16d4ea73b58a744523356997a7ab29f134e16fd219e349c618a3f693fcbc277b59f1d7d3b7f6a68baacd5a5d1586556ada94f3b0a39485e55feaf5a6b7ee57b36bda670c167f3d64fb1bf47e4a3255f19055acc3c669b1f0973afdeaadab24abf08704667b61961d0c31b3e01d2646328964d7aeb14e57afa7f67e3c6493bce9daab6eaa3e753b6b37c99bba260cafd99fbe25d2528c7a4569d9e3915ccfdd8f875c67d681874c7db2e9d9e9ac37ddd2dd81568c645ec21bbd7a02deb8c2de6897da391b141081c01ca3ea281c2916d1135572e9b36bd7ab7a765195e5d46ae138b1a42a4b6618c95ccd194a574d24594eaedf2267fa2667e3c0588643eb829c2e0fbb19703cdedc48bd85e5b55e53ffc63c0ed527fe9278a8cf241eea15856754c9d093f56c62d7eaf328d5b3ba425d7595eaa2eab74e6567611b346c868ba48ec2486ebc9378291c6f1029ddc02d38585866df49eb1b3559e6e3a90b72fa9ca8393f3360513f1d09d667f774d6955d90d33728a5f4b2d56a7559575d5befa26ae16869c1d1ab54b7565917ee7476d865a5a350cf6cc8cdc27acbadc471b93cb1d81676d9e17ea96f6f8c2423523a0a6543669d85bf245e5f55cd70afaeaa73bd5f0a73a89f90d4a3bad6faac7ad945827ae7c6daed4e579851f7f452a705d990b598a9e6d26737a41a3520a7744bae971cf339ee4b75f984e4093d221460828a10a0e4d96f400e8e6ef96122216501e3d1e4c05e2cab8f40caf4ce6d6b1df6e7e4e453a491461a69a43021763ba158261c2d2d2d1c374c2cac154a754ae570ddd01423aba5595690f59de6b8b3dc387545b673f61c8d34d24823a5f6f4598e7e3b6d1cc77d5ea69c7d8a3e753f2179bbbd9f907cb2dc763f7a14b641c352ccb19c4b92f3519c2427af72b8961ba7e75a386e64f6593764ce701a2267e04ef614638ca79310976ef58d863de72454876c9556d1234eddbea45870b4b80ea5cb057fb505e3b8815930cbf330ea2f3939a7d3e92424c7c60606a3a1f13c1898974c5329fcb5562f2f17b645a55eae4afd2585ba769b3a9d8464d555f84b92934f9fa7f77e51084d5d6b734e54488ea739a79c534ea6393d14010911410e0c511221c892e505dd7769d71064e8eeb6e96e9a39a5940d9bedcdf92d838778d2b477f9c93cbbbba59415ce43082184b0b1b0f15edf05c3cc9d638edddd52ca150864a073ce49e3e1acad496e42fc13b249a79c3383c910692279341952da40e69473ce09e19c734ee9cd39672c452a71b43e73ce6932ad86a8539bb46693d60c0b4d8cacd6ac0d3a6bd6c69c342b514a33adce4cab6d64339b5ae50e4b39d59229a514cf9969b50d9ad579941dd92c7bbc966571ceda4696c11e95873933b9711c47b336b6d66446a306bd5a67d775259ab55192198d1995117758946a7d9c8f5aa4996cc3e462b29964367358b0df4c6c3dda68464a6fd9c41efdee121482d58ce4c4d2cc5a3768d846ce49b312a534d36a96d1c09bec309842f7ade3b49c1cac65da2cc5eea62cd8a314a7a6695d106d562a618fd852cbb21964ce88c879ad0b5232c98de3b8ada78cad96a6698f734ec945d3a4997c74c969c51efdd3a90b92fd3425ee6460e3b78823ac291d962e21ac29cd5caa9ac45940df007bf47510d0b2a1c8b4997c5c6c6cd94b86bff0a646afff132b371b6736246a398116db0c7e3a289c0c32ece0940c5b9e6d6db0f863b9521619ce3bb3ec5ad66d935ca9656545412c323c4b140875e0155d90599a32058532540520c3774d562e4c6929b2df64e9b490210bbc01c4494b0cfb554d27c7aaed08800c9fc30cfbd5b354605d707060c07593e1cb0a554c3fc86153e558c0bef999f4c7cca6f853653287f98e0bbb212fece1af872cf3ff5b22730a7fcc85d94b017f3d5906c73ce6dec3dc2f49fe51b81f0ff99f401267c624fe4e6f18dfcb7b7859f2c539173604fb4da01374c49e03c809bdaec7ae4b629a14a357fad52f2161a7933b86cdfe4da01a76dec265574300ee32e2c2f333e6891828238a50cc85f7c476e4cb85b9850b63aedb933f28d4ba9f975db838e251cb40c3e2a359dd8fa5fab4271348ca513cfab8fcc5a389c50368fe68527f60ca03a894dffa7ad2480b6d5c402816007c172e8cb57061acb5b0df4b3e19a2d003d703a45f58e2b90f757ae4fcfd55582925cc95dc3832347d03899c90c102bcf92a111368e43e0b5e041998729321511257f2869af09008102726c199675c02c4c185fd9a8ceda6331d8d3c3d2aed75dffee263589c21911256e4cdf428c4952ec5e50a4bcf4deed18af6e6e9277b6dd0b0d9b9974ea58e08fd40760de17014eac9aaabcd60061f108aad2e8cd13c69c8d917d608eaf4c82854de2e045ff35ba954aa37a7944da1de57ec65b5e74a61183aa7acf4913f4aacf0a489932c63f3a97b031068dc1b7ca4dc1b7cac189aae2954faa6bbe89b2c0bdbbdd59948891f64d8d1c0e43a3460fbaa734176dee83edf4e248eca9a7092770343c982f1178b2e5ff47da13cb5d0679b08590e91e74e9f2ebbec27eec6a1f66646e9bbcacc0a2091124ff2cc3f4646454748502091123e793e5e699c199b2c325857a816167633c8dc425c5724fa904df1ca7663924b8cafbf7081f5fa2f096c521c457fd13730cf2efa665af1a34a1256a41c8a55da9b309b88058c859cf626dea13312fbeef371a86fece72395be41f53773f7ee1bdc9a333d93c25dee54a8bd69cf5dfb93b53826a16ebcd2836c833a3023319dfbec21cfdce1ac339dbe9ba1c3a58b8496cec52f2ea1444edd3324f45c9472b3675be4b8c89db647a510d93e01a3bc3d0bb97604b0c66422c385c0a13cdfa44a864419a0424786444d8272ed23230b54f90132f1404a224a1bcdd9423e453f5434d013560bf58d8b0623edcd33c9f3f0eb22f2bc227f2ff98b4938cc17cd204b398b57fac5a47f7a3b71d95dd4549a79bead50c9f33d7718f9f8f8f8008990b022e94a9e9ffcc9f3891a59e44f2a416f2a6531a96fbe5894e75d70664279beae31b90d76a54b848abec97a32ddaced8264575dd9d1771d91e893296e9f7825265161a54fdf449f3c332b4d46dfc8f94eea9b2c0679beaf40ae0b925123f8ea8250a23272868d1660cac1a8e298c48124141fa9c2da2e86ce3ac4256425b0665e754b5ff0f0d0de844935f47970a804c10ba1580f2a2d84388a4d91447b16a970451f1f2aa21441e30fa7ba5b1a484231d8d1eff4eac258a4a26f287629311b294f3aa393f6e6a3933cfb531e8711c2f089b5d1eb0914d4c9269d51e66b03e3d1c06ce8945067c6676159edc5576d6641676c1b9d53ceee081f4307598cd0dded75c37477b794db0fdb766d64f2e7f23e578d5b6c9b9492b694b3bb2184d0e64e09d31ebc9452ce9b29e74d7777378b1933c6d8ddd9c60454d671db35a5a8a9b4954cdbc695b614544d2ab1a026163060177a3108c8b22cbb1a8dc0d4b030418ffef480d2cd4c3b64f938e98dd09b593725b69c34d36ac984ca3a6ecbc1d40d39caa6a8a9b4954cdbc699784add90996ab5d412947153c1958eb449b5504a0f4367162fa66cd8700ef98a93cd9291c5524bd544e965e9565abb212518fb5431a52c5a76ba32bdeede012b7f704a6b0651b4a1812a489841132bb17eeddb1f7253a2223090e5a7a4d99338ad28899092270df294b80cfbb5e2df3712a7c2e25b0bdb928d484404144ae1b4b48b4c7f8fa8064e64d99c19064174812c88886022cf4b0ba02053fa6eb528a5525079decce844885ad9204c865289f8eef21b0a36b0dde3eb86c21636c3b300e35ea49cf234f9949d7e3a9d8ef4cd119a4ef58f85b3faaabbb0bdee50da0c7f47724881adffea4dff2250ed2b9111488c3f59266529e31131b4296fb0a87d72761c72b0a1872f720f4639fb7a28ca59b7d3ed451fedddd50195d39d7d3be12fbba6e57acd27d767328ad4eb5d40e3a4b425fd2acd9c83c499b1aaa484848d4eee18361e0730723f8d1f2107e1d45bd256354dabb5d67af85a6bad75d62adf46d0d7d80a81e54037c9357badf3d5f45a7acd6a56b39a55ad6ab5e5663a91984b47b0116eb29eca6aba34d55a6bbdec82546bbaa9be845bedd563262c4ccdc0d0b22c05b046fb27a59c00f6d00e1b6a34b0466b6523ed69dfe917d92f067511500766ed3d05d499d71ead0415c52fa25133c9da95aca19135326ab536d33ad6ab430c30974e24e61aa98841b046bbe90856e62f0611a9efbeae7e4fee21f55ddf93af4bf3b2a6bd6a1046c3483a886eb141984f46d3112c15ed49813a11eab4f27c4ba9711e28fe54b15f0775901179be89140ee4393b0479ce22604d0e1bd8f8af6310ac99e768e267add606750e1227fecc39e747137fe6eb5733fc593a23eea22b869d8f41918ac681735a213527991af66bb5e47560fb72f6105bced6b8cb69ca696fe65285cdcc46515f7e1ac9043ca49f33c2181ff19c734a29613361d30eafd596f059649b854b1a47083d7d292332893fdae96dc0a16ff2b6c939bb66edb65cd23b3932c86e4913994c91357cdf896ac27e1d254e429327a641c80de050922349bcf6280d0f4f90c6dfe4c951f69671a5ef745f54910cc7d64aaf9f37498b7cf759fa2cdadd8dbf1b3fd21569ccca6296eab3342e229f1599d73eb34f9361f5794de2c8c5db1fcf0ca8f75177a1f010ab952c863cb95fe5b56f99bc0adba061255ed2a60c23493deb159e384bb57cd62d9bd5b1e3e4ba23ab2fb9ee2c4efcc943daada4edbb7fa4af927e92f6e83b3db26b181b84b19fcc9f39334a5bbe4f46c8cb1b833cfdb431c3fe30899bd5b2b5c4818e4a803929aab0cedbb9ca93ce3927b637d0c70b0ff207f3923f1a14963841a66f7d8c4c899cb8608923583c60bf7a030d00654a89342094e9bb05b1408a52831f2b404145d91414f06056cbe5d01c019b1865589eb9c670c6457c10d30ea14f64d84e296c1499cfcf1623955fcd0da5644d395bc258fb2666b03dd93489ad5619bbb9da77e609a314aadf44ba34e37433510961686c5e28945f6cf4924a29a59cb2b1946163d19523c8404198ad8b36f1944a7db04e75ab92f1b46948d8fa79170cac2aa652e7696197a7700bf3a45218d2ae95da5c6e4fac757b622e41628ed7aab575f26a0efc822d8cb52e8c9d7e52dd0f16a9345cbd7e49a011068a98f205ebdc65bdf6cde95bbc2c1dfe7aa06caad4bd9cfa25cedf72ed0ac75d375c5c386e6017015a7f790d2ecf812bd07297bfe00a4c61a4e52eaf80ebade85dbe4e77b956be4e6fb956be526fddd6679363927853a943a39cc22cf5f67eb08b7c8268a4bed35beaaa3ebb20aa14fe6656d9afaeebf4d5a395eb3adde52f6f5dd7e9ade7b8ebba4e775dc75baeeb8461e051866df9098f462f9f393e1fab481c1d9fad4f97d5a7eab3e5fafc093a72bcdc54aae59eee725bf7e3c9dde95d27bb225a0ad7f6ba4fd995ce42dde20f1a65fb6d83028bf2e9f5d6bbbc27d6faea56e2b854980626aeb7bc75971b69a9cee3c2aeee3d312117ccd3825ddd7c4f2c5691afd9c29607106c8ebffc84f3205ff3e799c288cb5d7739cf144674bc75285f2d98670a232d3f01f3b4dc8579a630e27a0be639825d304f118f10f99ad7818f84fec12328a70bb6f2650f632d2acde578e9c9b09c041659d4d5eae95b6cb53cde8a0c893cf0247f3143220f00e59e58cbbcebb6bcf59e584fcce5f6c4b6e65cb727d6727b622e37c65a2db885e3c9f4ee96be23bfea1a1291588dc3044c78518426a18c13e209e50d7cae0fd7cac9adcbe43241800f251f175a38fc76f9eac462219cbc850b633344171197eb30bb9eb9767cde35249b3962279c4a29a594524a4c23941c3972e4b8cc711d394eaf0e281ddf6989c216f69b4a344eec32c05c73d8ed38cd611784c7bb570c8cca9c1e7917c9eb3043188cb91f4da6df646ee797fb45a21f2b59c7656afa08befab5f6511fa150a878b4d91c7641fe83dbd1d65a9965be513222520c71f3ae87e311ac690e8af63428da13584393b2271914f40ad499aad3a45bbb6dcf41c57eda2aa35264bd7bf8f3be09e4e32426665d0c32cb7ca35b0e1bd8d3e351f7f2ed41b01f4d0282afbecd5b2d2929a4d0accbdc06aa3505e1514ac66ea35c03f50d8c3906b79356a2bd0934a5f44d6645df08411deffd7905d489691c9f4050a7f51f38fe1d078e7f15c7eb61c4a142f2d527cfe5e3f92ddc85ebf2811f50c3ce33761969c1c7835c88cb078e22860be02f3cbf2796b1eb0139a74236f807feeab1900bc3bdab09c19a7eccd5ae006279e1c2f018ee0b177235ef76197605e8580c587bf2c2d5a0c070352903fbd52a4faa6d5581817d92dbc763de9f494420548dd803ea7c22017500a09d51b54308849e71d8d5b07397911682e0d9c27b62d06524ff85bf8079048067c62ecf054304c0231b30108a452658098af5c4a6d88f266dde8579fb71e58f1f3e6e43711bca1be7eb5a46284ffda4f336b95f16eee30279ccd5b97763a645126702c9d71911084da26a4420da13ed45b4e88cdcdf00c0c2ed27b0a60fe43614edf575f2044aea6b4f2290ee40ecd11a4d6a0ec09a06c085f9476fa081daeb9e026b1abbbce7bb30f3a556f40afd88a9942dec179de0098499b03782e0a4f0afa270085bf986cbbf13f28df714a813f3be975957e15f0bb30efb887cf559ef22fac6c7bdb7cdfb50e7c76ffed9dc7d857f35775d8f7f9d4f873918763504e02e1862f69ecfb34d198a65ecc289793e0f2c0c1c14c5f25d784fcce64ed81eec5bbe3cf18735520014eba19e119be2df7e7d7c8b3f5a602294f3a54b10e113f37161daa38771fda211c80d5e017f35f7c03117079c041c913834fda277a187c1f4f42908d15f8c8f54c05fabf56da3dc0b7f31bfa4e7c93cc7635744c765300c33af8bc47bcc3bb286e63cbcdb93775c9867ee47e3c275d510801674f02314e371e13db06640149b42e29c980b329f919efcc743963bbc1999dfefb4f43c997fe6c2bce3fe97b95f4fbebfdf2287a5bc0f791e314efa464a1e972a7c02f9b8845d7eda5ce2efc72790c4d389777aefe27bcf3b4cde07cde58ecbd3ae08bd5764e63318c21a19f997779a5f7632d47ce6927aafe3d79534a7f7bcd72576edb8bccce975edf8cce90e3c44e6339f91c1de77a4773f99a3e0d57ca729cdf13d8ca4e6331809ecde775ae62e91d9bbbc5f0d7ec1fe7747e4de7bec86c03054012f91d9c7e93dfcd97c3ff01299799cfae0c1437a7f7d7b5def255f3352e6de5f3ce469cca5f45e9799c11f95afe9c48977893f27f2530999c71c097aa737862686493e8f6fb18361067f3d7966077ee11d352c9acfdc14bcef348ffbd5fc7afdf5172eec155ecf778a9ac3ae480d7efd15f37b1849cc656264be2369ee4e7ba7a7f9eb13eaecf8ebf599d35cd8deccebf51e3dfef1f83ff31d77c29a99d7ef7d7b5d24b07b19995318fe7ac8b0abf099fbd93c739afb29c934df71d83731f7b1037f4bf28ebf5e7321ac79e18f27bf7ce04f490c0ff975d8373f6e73087562eec3067f3ce41daff98f0bdbabc19f92fcf2813f9ebc037f3c4ef39ac75c086b6af0b724bff0c7e333df9134f757a1e630c37ae01d62e621e36124f432f732f432ff8efbc55c739afbf19067bccf5c9ad7dc1d34f7df71fb93b907bb22afcfdcbb1f0fd9fbeb4258e37de6e55d99ef38cc01a13ba8846d979435eb149140000000000315000020100a064462a140249808bbae7614000e7a9c466a509c0bc44112c328ca20640c308410020800c6001821a21901b02068fa44c7b603af965f4e0776b3e92439e6ee0df3f9043d0ba2916888a315e6157695466e2f4a16c7177c6a1cc7c508d3950d20e02481be892c2660f0d4ef419fdcc044cbfececdc2511a38f95a2efe2825a2e2ed5e42266650b9a123184c883a5985dc84eabce2305f065d9498a27bbbecd7322f50b349a2c92f2e591998dae67ebbb9fb5a98498346369818f17daa06af4ea3b9e2e3ee3d1b2f9240adec3664146f8bd6d5695ba63485d14ca530f552cb4c6fd15505d5be01c3bc03cfcb9d94e9788e729dc460dc8fa174560f28a237f4f44b96f716055e376589a1544f00059fc8abca1c349aba8ee5ec02610197c6f217aa1735a350b00aaec080e719a366ddabdaa7ae547d03a1419b5dbbe2c0c01dbe09070e1549ecf5f3cb5f819cfee76ae6d199e2757e38286671c5e0f6022810b3f32a86e6c3fc6a4e144ec95162ec4bb6bf2f85ef10518b454c17488d565d4221ff5f65c52cacfc016970e7b3140ee3e25f4865c7613e5397cdeb5c4db0ada37f9bc309934cb518f52ed3ff0146e557ae35776bd7e3deb7018a63c34eb7b4c1ac7d263d249e85fd60c762948d33bbcb8ce8946607312a51685b29f83b344c73b300da18ef91478956b4fd6377205d8c0a72dfca52cdc7fe47a5e80415542a9c802c4f94d679a9716dc78ae3f102c1653b2adea0e183061f3752ed685a1d88e2bc25dcdd565f0f2a1b81964c5adaeb4266dbe492c2269614ed8c80b0fae7642654bd006fefae302f749c2c96a2d873b9cc1786fc2e482c6326fd0c2e36e18618dda6b4aca0597a408a3f78815d2e9a00590a481de70484cb6f8d6ba4d0023d6b0c22a14d5876ee92f73c7b703c28d6ba62c4a9beeee1ec4a3e06d529de1c31e19c342dd879ccda2ff965a389b5c5ca79d834cb5fff56df25967095f1ff54a70d53b8983f5dd55de7cadaa146e8916d286eb4833f1d1a123bf24e39e5db4936262573fc28fad5369a46bc26dec02a0621ee02b1e13f7fa5896ecf3609c4c8ca5fa93695324f7e2d138916cf3f7d57d070ff0a99d71ada9e80ac8b9cb366cc399dbf0b8ceab1f55c7befb385a686eec46363e992967f1ea8416963410bf4f09ca5601112f1a0fa208e779d3f869a4493b048be70835bd1f6d6480cdbf0f75a27dfd58dc3f32ada23a9bd1c5b1ef15fa442cf400bedf203dd468bcb41c911a33837d941f71a418a2a96d3daa7e235fd29e71ed169f77381e86b1b2a5cd05fdc0896966360e1c621ea85e291ed2810410e98916b25f054327e2d7a5ed50d5fe8f5f3b5a93e52d6a6ae004b79c272918756ecef181daeb60355d748f975a7bad227bcb252f700e5cfaf9ecdb6d44b17144c155e2ef25f6eefd6fa166ab5fbec9900b17b4a9ac4313f0ef70c1dbe26a7469db161806c76f41e4f67550a101151da22ceac33fdfacc80fa9db3da808ad6479a05af102851e1e1b840c572ebee8f06eae4a6fc0eb4ac65f7c93144d98fec669b216d1b140b1f974ab36eac82fd0e1247b03bf2492b7237e6b7412b64f566d79c3ea4ddcd0e41013ee3a51d10af92f9a2771245d1d39a4c4a1b8858dbd38402f77427f1fdaeec5575d6dd6c5fca8f9a092f760863dd6e2b4af47e5f8e6050396de8972cd01d24d2bf9aaf82f4b1f9b9df5f217a21f4a22244b7f4f0745a3d5250e36ba70c5a592832e39960c15793debebce9dbd577826d60755aad603239865e8e4cf58851cc09ba5c8e6a2581ae77dfc27739f94d0cefd8e5c96bc4e10c3b253c4881138c0f4baf9f441e5c16a46130a90125618ecbb923494a6c27ad25e0d7c683706c3b9fb186370fb4c813e580ab3da85243d3b67d57b34da8f1b473b214806209dd225ecb78840b1c15cc7bffc78cdaaa108af8ed90e48e9fd1c7e6184bd1d328bc8153ca03bdbf3c2de2c50b60b5d06ec36080295bdf9c1c01fba71ffc84c06f67102f109780e0aa37f88b7c4e105db150b328c4fb0daaad6fad8368cc0b38a96dec46ec059bafcf0c56faf5d683a41226754a5ea094c6e05dd889b59bbd0a39aa8f870af1af6c19575a83f98d013097e00f1dd8c1745a6588e4b5c8fe8cda2b5d1e092a7923c62308bb7b14e8c8de31908216d89caf7a5524a030100143944549212aef0b9a0dfbbd7503f78003bde88f82d2ab8b55c555989d7efbf6b3ffbeeb98e8cb23644c0b5b9bcd2baddf06f1798d07b484cc6a6ea7f38099f162393b6867c91dc844cf7ab68e200dda96fa22b835aee20a135a349fc91522e4939b0a2248fff9b982f7720d0c4a1ba5a004eafa3c4f48776cb6027ad64715d879259c02660d2cc768cc4157d78e33a7c460b270cc8e5f372459b094dd6f9e36dd99101d1a3ad0370806813ea517d860dbd89995a2ef3aabafcaebcb0b56e293ced9d4aeddeec9d84856c52779acc58e39ee0d223debf7141e440ea059713e20bccb8e292bc0f0b51252ec61ca8663581f1280f81c245ec1cc7977418b4216fc57e90596fd21f8ea9c76d72921bf110a570a7d5aeeca8678de1425c72a6fefc3c7d526a557aec32801de6effab5d326c49950e16a56915182b2bb77ae37a2995ba27d7a5e7dc4cebf07804ca590e512e6f0497cbc8bddf992f8351c5013befde93cf3ce1ec75530b77946a453ba6882e26f13fd280c6d2c2a9b941e8ece17a4150f12d0a7861796e4461283eb77ceccfff0c3e4119dedc9785e19bb5b232c3f750967d825c20509f3090bd2b8d5592d298de1bcaba35a86998f366f484e85c9f790aa64e1161b65e314c551255ee1cc975f91cce014173bf4f6393e67b681cfee8571c3c82fbe7287665489203ede7879c856ac0ff738e169c68c47ae597811fc1a97fdc31c8ecbe470604d8c944003875809ad1f07001d117d4bf41857a92e9257b229b5f0e3318f1ec45b2ac903f3a4572d2136d37d2e0ba93bed7949f719b95d5fc55e45163092bd1fb729e78a9157299862fccb460d12b24c9edd78512a725aaafaeac63dec0cb282bd0e7fac500d7a9d9357058482800c6f5de20d0034bcb860b7e178165ecd39d90e1765bb39e3f82694a29ea30589469ee19a8a3af6d06a1edcdb574b8238b7d1b60a1ee3b0b02a37db4bd5f068d36cb2bc070cba265c377010af6c8669addee3d1d16a836e666a2a1e439307d036be7ed505033db9dbb60918a99360b296529bf9fff472ff87dd20283145cb3452e47d540833cb244291429029c3e71855ee3cbce409e16553e1baed26a875957b7270910a90ec1e021015e6b8836af1e01bcf6db986d23800d2c0b5edd2f9467b2e5fee8fbfc4393f15b763e8d2d9b0d1c5d9d9223cbdf06ca6dfaba08dfae1b9bda5d35eef451dd920383a6190570c17d03d64a1362ade067b8e975165d3825983264cca8a17eaba7dddc8a3b0b63bf1cd0cfd4e28f2b275a0ca6650d1f999e4bd822715c4148cbec4da862377a0679ecc77bb38b5ca3082c4446d5af019ad54a74526c3de0b0d1d637f3ea900bd0f1e776e66b57f97a80a3eff39d57c45393bd6a2ced250544e518cf086299b6b5f296d4130c9d9e80b9ec55a27cbc8680cf4eb0b55512489908ad637368b41bcf4ca700ee22c84696a5b73ab419913e9b3b64d6ec5603fa793f7fb4d24cbc5ada6f707b029f8e87f8f574cd1590b0880296d27446cbd45a38f532e4abb51621b40aefe864adc4ca0be1ec84581f2b0aaaa036e86ca1876bba5a30556e50981cc483375721f0149ca674291607e98ef668094e200ac068fa3bad6e6d046d1ea357ff37f743fbd16408c3e68d238162ad19d0b4273742a2c842520815cc3954bb9b2e0eee5ec8ff8a2eb86463dff758d25182754e764cbac00124b950667135b4e9a5f1b66eccf693dc8e3cc8ba6709a8ff8c5668af6bd15ad455dfb8b1cdcd295c4ca9937db9b1215cc07faf0660a4d0e9ab56fc481a6482e17492508167ca0041b812cd62b4eb015061120f2f775a1fca969af74d37da81a5bae7b8a318a6260329924495bc617cab2942392823ef4bfecb5de493a6162049225133400d3c10c815a0824a8b937de7fe7e836878d9a13bc5cce7a15dd2228e04148aae1b38382cfd7fe21a922fbf24e79515d01fedc6d677c81caf82c76976e8a55cdc40054dec6a240019cb5180393b207e357076f05cde25057d3fffb7181a273dc280cbc4260b7cc1356b76e249b759197ef93f1e3638f7488af8b46adf11bcc19887e8fddf322673de1c7bec2eedf12f31b9ad0a3003836452c572b3202562c8e82cde5071ce422396c10ebb4a6168742ac850a430f8affab0182c4130484d95e7d199a629c8c8cd73062c2661c4d143bd218c32e2cfe99f07923d6adced813c0afb41d836ef6d6e6acc09d375a63a1607f0340feaee97def24ed69acacfecde6dedae6eaed93b15677143ae87da89da0792582d9437a7c23be25ffdcaab5985ae65e26fdc262683c3c0fb892519ac27549a32d5271919e4676313224ac2755b6132e280956ccf6c6d6a6ebf2072cde802a3b5b0008372c4b6edd349408e74106f5b222d6136f5d6add4cab9350698107c1e026f8ffba6c4e75f070fa84cdc2ddb1bfcefe156932bddcda48abb79370f3b92079d35c9c4fa50d24a344705b227ff5a50d2e83c26088526e5f36745e30d1200a407a0147b889d7f05cf5825fcfb53c4c60e3388327a471fe42f91dc4441349dbe205e76e9c993feffc43864c591212b019558eac49692fb46949e6242d63bc8cd57b5e14d0170c27c569abd1cf025bf65a62b86f5a6340b4f03e265fe14ea937e51715f4314ab830239220c504c15615a643da015781eee3cea4a943c7f57b05a409245b93a1985ba856c0b50ec4779fb3e55425d4fa3defd0c5bddac73977a50543c5913b672ee039fc54e3dea3524caf3b7373dd9a4aabb657a603293b800b6e87d7b38dfabb00eeff5f6b28af5907621c89e5d82b6401403aef75a7de21a7538cd39dbb3c69b81cd452e8bb1e510025d04e7358296edad4e258137a2146c36a58731a9a9bfffaa915b4cf3cd06329012428317524330812978d47acfdc3359eb2400a5898668ce2807413fc3ee2570359c260d4c487debdd38bf9f07174f7206f49e23dbf6fd5a8490f8bb90ebb97af23ba7373ca85e8fe1ef1c3ea5b5df1b44952b850b67d9f68b83fbfc760b40357cd3eec28f634b25ab5c358176170cbb1c00bf74d4bd3f7f3e1ddee2417c77bcb0267d55db500e398c3cf6a05407ef0d03c9b04243cae235c4d319a76cb26e007aa40bf2122abe7e70c1a1d3c308a2c523a7fb4d1a351664e9106cc2674255f7df56e8256ce2dfb03e8079dd127b5c9c36502a9562f163dc76840d594785978433128b9b3eb835c2992650d156763670139fcc2768e9c2cc7056c7cdc09d8928f7b26ce7904024cd3a34c558df59368c563f7c917235182931c448d523f278dda44f0a3712a8a5ddb87809d2d72478bf5d1b466ae39f83c648959e191173d04e6f42705d6a281a6bfaba156598f58034359d6746261e1439e3865130eb07452cf218b39cc5334857ceb5bbd33c2e35e7090149de3bfa9c5340b9b646e817ed0c5bcd0f36a3cf1650b2490ffe9ac2ff05cacd54208e80ad08e9dec17358093dc7eed1192173e62b593286525b865a646b09266633336c06bcc7ca48504094d935cbb6290e1436ef075fa26db2902265f3d46b92937d2c7e1474cc8a4b5771279cc7a595153baf967ea9a8b50c84b2eb41e30e1dc1d4d99da4a5a8ad4c1caaebcd144ccb6b3846a04079b56e73e02e8b15d7d334d8f40a4aceade42e3333d32de4a2310b14f1a3b91cc6007b42f46b25a11f4839db46db88075cf5c01dae1af370580c601577ba06bdca77e43b2059a15269ab2c48f70d7d137361cdfaa5fa53c8e6292006722b63822fa0ca3b6be7dadf4b1d3600c70a77fbd24867202940b735c04813dbee21bb1b94d696eff9d7b9bf0168938580eabd7b2ad8911de8949511bd92071db1d0dd4c80f95b09e78f637f06d112a11ec9fae82a42150d667b55a4c03d8d61cca31ec1899993ae5a66bde19ed685e210fbdadfabde97ff5e01991a81661a227ba94641bf9da21095867aa1579a468f3fc187dc2c7023a7074548ac090f68cd1926d27aaad2ba709d2ecaf13d015787526ca3e474016e9aae3c5950c2d581805a1202cf5ff54e16a601d422065c4baba8ded193d825f3e9ed84230d7643e5b94505a732336ca7756ad47549f7cd06185dbf17312c0a285cc36d290c8e545dd9f63d9a7ee87b7f3d761b781cdb58abae61ddc99c5202d804353ba22c53cfb79066e2b4efa603fa5edce43bb5f4beafd3f0469f996ba161a78c893b2c28f5da804f84c0fd615941028714f3133c6692220fef1436ce0fce5d98a6aa38c16cc18a850f2680326aee68ba3f8d9d53b6cbd69167b98b7bd35e992d88e27813980f32218a3a66a0ecbcbc959db9661bb004c98596bfb91a61358d87a099b3aed0c4551a5cb42041149f101aa2e471818f793feef44f1174d7555b69179b7571af375ab28ac8f8f1a33e31c41335a8a18d8cfee8373c7845d5cdd3975e7350c6224ccebd87c3e70a81ddcc184c8ad6114159be29ce518285bdeb5808fde507751b31807335727d4fe4cd95cdfc384f6a4d002ec60278dd209405be92d4259a7e38229f3d50980c40e8e9141d44e2592c092d11d63f0360fc83232b6c074b7fafa265ea498d337ae6ff9349807e688668b5399d690292931c86fa51e33ca3202a9a77d68a9cb326945c967376a97c3d3938ddeb0952a492eb3b16652d2d473af01a4b0027858bcf837a424f989081634bbf7a11b2aac11f86eb03d31526ffac2b82dce9352e8b5ba1f26aa6d477b641a59ae62d7af011feb251191a627382a4c3e2ae2d8c05c1279439ec1793e4081db183ff46569500a9157f3970f642a37dc79bef4ad142533d43a0a24d75ebf7fca1d8ea65b1438dac006a74e6d7a8b238c64e000e846e63f7bd08eeb1f1d3e4ed812c710205c106fbf6a7e2d29d03ee7cbfbbbf11415fa5430fcddc99a95bb947153dfb373db0c0723c299d7cb3673fc7db6e4ce7a3d0076f7044b6c39667bf435dc5cc346d94bcbb05960045cb5ecd32d12a29dc4f984ab8c199ab97e51f77203b22bec7795071792321d3603af129574be29994e96186e7df2f5c57c9cf9d4cafa34e47054261e2bcc6069f094e5c1e1b1e2cde17e780ba90d113b305d8d9bb5913f7f3e489c0ba1d9868f3b816b835bf242ae9be4818099c2c8e6dc6b17e31235949ca12b9242b1a05323da125b2816710255280f0cfa6b768463bc4017b82305bb6815095324ccf5750c2d829552d0c38527c00874bbb6d6a6a4ddc8a65392d3bfb1eb6418be3c7ef0b464bb3d42bd982cefba7cbef003e4cb4c0e1ee01cdda7a0298854012a826b4c9b61cd1d4d0351a0415a8d810ac275c3e365563d8004ee64455b13e044e1c8951f8b3d8f37b0fd057da759ecfbac0a724e6abe63d01c662df91d42b8d1ca2bebc0b9b601fbc0194f49a7ad2fe5fe1a9136b0abc104bf2a2056b15ac89bfa2ad91e0ea53b116dadc4b4467d3b6bfbeca01e9172618f2654c615f4c61523f7e0a7ef9ac5b0430cec126d63c7af3ef0e0173d0c333437380175f68f096ede2f42b81672d3fe4156ee26a6c8dd4f241eae5b2f2a2f7cd8e544cde8813cf45fb96031970ce7632bd0820f2bc77deb00477a490eb47e2701d83456b2a08c4cf3158c455c8e217301ad11101fca9c80a1ae0da80ce68928b70d70a6caf878bdad5736d36a9793d0c8f605101aa4818caeb61806dc6ccae7bfef71affe90c02583e6873a1e1ea05319952a6561f8631750ba03c55f83698dce94ae5a8c7cadc299fac95d54e738e22b0e88ce40a330619c44a720c1ba2a844a07d6655dbe62e5f40fac450ec50d9f22404c3b624275373288065db41ee54921d27e4be57e1c0d8bb01471d7149a452a8d0d5a731ad11eaa1c37652203c88d2bb84f393f3f59898e48518f0ef98d9d6e260fcc29323efacd3cd5c17d137939c20b20040f1328dd98e33579f201d04339ff4017c95d243df3aef5e566f25224311cc6cb073d92f584e4ed94d0265b53a1e0208a6a4c996a3b8fea42134c42a6bbe74b4545c31142fc9ff13a08b0c0535486eb5928b4681b92482015c14ee9ff7d10791b55cb8725a024ae8c38d0f449205d38a198195d0fe63bd72f6f408b626126c93dc5353752e1a3c5c591e9efcd33efc937b4f128f48f9228457932695c3cd7f27004fab7508d0b2d3d539684e268f4f5906eb96337fb7aed9a89eb2c1537f7471053b9bc4a0bfcbe488d6f75fea79d30dd1793b00480d8e8c3da3e32acb1269a1c0f7930e89043dff22ce348f45a3d783b239c8e22967a544f998fc0b06275fdd92a0ea1a06e1f21bcdb68dd1f2f782f8db3df79af89214f2aaf20ac040f0f7cd3389357ed953df2767015479284956ff6900536feb77524a738ff418aea4c04cab2bd0d7ee14d356ebbc9ec07f2a7dd0a7e1ab7a65bc64d1bb2b0863835b08420669ea0407c0e3d37ce99d460e0030475e0ba4a470a07903d82981787ed991c565652e4c4ed6c156852f305a749e46c241e848fcde89608f68b823d08013dfb81342acf7ddba874dcc144c10d8257d24a3bcc8d2a936d7978bf89f6efc4db972e6321b9060a8a59c671348d3d9a2fb6b1a6a7da31c5a58bf38e01245e297108d0db23e060e19538eaeafdaaf8cee62f1acde682e041baad57d55b2f4f10773af3bc098c0772e45f4e15f8f4aa3a7714cc5c6b3ab22fb5bbaa1b16c11549421803cbd486009e5bc2734f3059c39479b6e7a9cee54d42fa56b67af70513dc55fd823c2b29111ac96247c4b531478a82d7102555114ad92185ac0b1cced4b084bcb20c5cb8f27bf85738d7d99ec2da8f5596cb5f5c5d250148adbc8634a17e68fef426b25f9797a85c2c6d9e175e96258af56656bff9e820110769060218a383f7f02a9cb56a5200b0b11893dac17a4d84dd2de42143ed0807201cc328d97c1645d4a0c6ea9ab7b8f7e9c09d3f13b00ea9c812a860af5fa1641b171e032aff3c8755b956a38a8f074a79a3d3571a1dcf10450f997c4c3a46c4485dfc52ab59b1216b5428e5322824b24012066cf2c857f044744156537ee79ed3fc9a2f94a8b18b1e160bab61e43df306368d30594f25867e4b220ea4640e11a64fad3fc3f94b537fd1dfc1ce268d1ebc5be5762a03de9a10058c137f913ace1121e1d11de1c1139693aff947e1fe9d734244b0459dfa2efc19e1fdae752d6c53c2fbb945cee06b882210c5db15c132d2f1f619bab4a734b56319aaaa1ff10bc0821d6634c969b0b29fa06432f2422d1dfd82edb74e482df624d0721a88b846d28d9296402eab19d0ad6f0a9ddedba7221dad00c84c33f1d16715f9842b007c8dd7231cf75310cabd2ce5d3dfda69daa7ffa79ca9f23c1a64eb1b66c070b6f1c7b9a909d4cb830c9582c6169dc100b188f1fbae69450c80a319533d4f2efa2e1803250bfbc6ffa61216af8dda157763ea727ef9b7a5173e8a884f39ed250ffb64153316130021725882b3752a37169df64b16c88ffa1b9cf1b784302eff90f006f02beb80e0bbd760fca8a2cd6a235d85d9dae54e384484f1220ae12851b8514e69d9e6bf1a475a8adca139b8fd7443aeec2dfab20ff7c1aee889e572817ded39fdc9229e66cddd4fa8cff1c7bdc5e58c43f37f9b6b7ccc79831451c53b3e7a17a810a42d1b8322da0bd8df1aa3e12ef8f305b1dbf8fc5a4c54c7b360b3de04785e97f1e9202b361949b3c8aefb3f1da0ed894a45e254bf20d0fe716ad321ef782fd02bdbebf3f25b27b1a66fcaae62683f6c8cb951222c03274dfa0736ed5a7e117b321e3fe16a034c40517aa4386d4e1898d8b725f298a99cc4eac79074bc99c1ec31a638c52eeb8ac6f48ccfb245831c612e81b733585c6c0cca2be6507d9f05e52e7087c64e004a065c845a7d724e786a5f7528abd56808b91b04f644d54aa09e1e5970ccbc44a36616af429b902b2c0e3e461a6cd492c69f0367446c9da40c3b09370b00f9c72048bae54d2b5300c5753c87389a2b65f81d636b5f9836751b7e34be400bc29df146bf35e8f78be6ef5219699d05886a315acd0c828cc63de998ca30c6fcdb285d05322c03e7d7f7a2a33ac2d7f53d2f063ab9a360511e721d47aec7e6ecd3ca3ffe28ed76bc7ddb89e0a64d3be9073b22654564acd9f9505e75c2728533a9671a127113cc9256b1557a26b7173d614d5144f6f66157bc2ec287672b10b1d3122f1f028a79bf6d4e74c7d426d2dca4e086de05401b0a9c8ad7f15202132b1761682ec6ab4a0264ad49e5c74146d40d4b92880173d9576243f578c641d63289eeeb22eb9e12eea32552d3ec026e0e7d89035155b8d5e47d7b607eb2fb2bfca7fea2c81ec52f1182cb1421d057a9079a420ea274a93c7b6fafdd1d7dcc886e4c8c3479515faf485a07082d5780992f524a3a674ff01523ac6010c453978eeb06417df9c72f486cfe88e826ff24ba2738c39d218b395ee884b772e14aef9bd615bee5cc1e9e8cfa7b4b627367733e755c44ed69e2321107fb97c68b39bbd40e54bced37b16655271c9a6d575e433156ab80f9e2be2d1d1f55ad959d87dd4bbb1c33140088f927382363dfa681710517d850a1171589da3b5df4b691404f733070420c7e9bce730cedbec68f032d352d868a815ed7ac43ee5b26e0189f62aa67989423d8c0bb8240398fef46469b9d016e3642f6a976ebacc63a2b6de541638d8ee5ee16777f78a7b62ceee5e71277752faf85a78c82f9b38a0274678964e9f056eb843e9bd5b06c50c8236c71f19ee0dccb07b2cd311affb8b83b2e4bd9a8ca6385a1494726986aaa51c2959e791f1720263a2e3e1fa9b26be238ebcd524fef1443a5874a3bf36369b7dca90f3969d70b869a6bd68374844880e5fb849704073d16c0877b35539f94e6cde74b351828d87eb4ad8dcda85cb84bdf3d8623fc6f8ec2a623c2df5025c666ef5c637f70b8ea471bad36d909d54676cfe99e56e500bd3c984463082ce1c58dc80aa7e577ec9ca3f9c73a0582f13ab5a86cef34fadd02fe0935667515a2a17bd6146f0fe878faf163c0172ff17f46eecc87192d23e961fb4b711da473a2166ffb21d49cb647a42bcb09d98cad42f628f4bddd12d09fc8731322b9f45c7700ca2897761e81f98d03823e4344bae104143574ca3ecef34f0d048f48ccf5889e0898df0527f9032b0a4d62c094f23fe38c78c9d0b9ff6a31c6a73cbb06f09e16d81b28e34703d869cd234532a4f90a91968560edf633de1ef7edfdc02157632debf0c71108713b30e143dac30d5ba72a55027b9721b7b04818d46dbacd8c6c9b2c53e3ab73f1fb2232118f5e5e35353bcf59647de5e41347aa9da68356a6df0ea20a50f236bbafc3eeb0421e2832e6de699a4287569517aab185b5dfa1502a5ddf6324e3428c90e97cc5c69f8ada10252c49671b277a116af7666f6c649570e6933f58211d8d7f50b91fbcdc36b0b84c89f42a7e47d68d612920c454053d4b48bea5f94481fe43476c61add25f8ea9ac634726360dba16e49f002fa64b70db2232dff0e020c940c441e659b9eaca5478fbe3345b2afc961b1418f01f84c61c24fff478abc556c8cf9182e7421ed7d5ba3e353770f60fe5d15c4839f671ed2c816194d64a588a24871a59e6a168a314b9d714db9310d6f99573a27c7a17be654ac317ecc9fd6ef11cf828a71c7b4e7f62d3398a759ea00f9dd82d94928da72cb5fab68da11c2d21e64d23f96d1834e0d0ce8f97aea3f24cd735903bbeae0cbc36d66e3ea96e7f028d066361c306aa914119015c316ab6617c0f932d881a518cc22c708cdb77157b96dea6e8935dd7243c271045fbee044ff88336d1059092067ea51342678ba9ad0c285de1165632fda90d50e1b7209c69d3c275404d3ba2177f6eb63e3fd5daa5fee0a7bc8ee9a1a54ba4d7eb2358a2048f8019c16bcd7578bbfa48488b59b8b87a188a0ced4358bcec8d86599d973899c02c7e16357dcee2d54f7aeeedef295685a3d2aa2bdd8dbb4eb3293755c3f02b6f76166dfa9d94157874a8c48243785c590303d3334a8841abb29f287841b2fa7cbc9ba280de3883246a91ddedd47c67b9d013424a055c0c24f28cfe6cdcaeccd56c5c744b812cc1ca50a6c27086ca610830def270da47468cbfb4c4d1f4260f208d36324787cdbf27a666009f760f4d36de1d9466dfec6052f80508e3fd17981a349b40e06ef05400250df235f6a9134a257937875bc11bd55f52dea1ccd927c51489ed4e8948ca5b86a8315e913a95b2492e725a029d69a13cb646b044006c93233672c9a586a803109b6d0d208cbf8def49d2897b03ed20428c4e2b803fa0cfa37d435d31aecb57737e76e4bb76679e4c7435d2302f77eac817650f735f069730d6cf2cc64c052ece401cd22eb4e24f2f122a6f0c16f56b95802d516a68a017cfe9d50d00fe396885d529006ccb32864d1a8b3041c149d3514a1800609f430caa7e3775e45f629b8a8b882a0a627b9a791ddd3376b499bc5edd20c2f73b3963876665434767afa375e1535699096bd9b63b31e43a846fccc5a99446c9259ae26cd2ab6d046f1b40f136ad4c9085c20323959c775c575ff12a1a7f3ea338f991e65822458955ac38f9bba68e34235e02db4c68dc73a70ccf4cff33636b02f34ac21025084bf42048332e1641a4c6b4b11caf4187808d510174c997261fdd06a5a8a0443051edcfa0428f94c32db3e7f89fb140aaaec66e2d2af45d4f7ef224d488cc488d17a16615d986c76682840f6b08bc44e66c60e8b0c75e4710ac75354783c554631a8a3e0607e090157e3a476069d920ce3440351e175b960f5d542362d11cc6f10be071d1b4ea4de1bc554402dd9c9af70e7265479ddee7aa94c8b97b7c424e666ce5235b519c478fb450819519c2f1f1054351eaf23edb19092dc5b96b674fe8ea22622481730f3d955183b5b66d663753c19d3182b72cb8344e63ddf0d4da719d3cbe513d6f13ca766982648ac48b669072157753abd61ff11ccaca0922c0fb28790db39378143cde2983d44479fb9c2fe50e87e83f11078ddd623f0694bd13708784bbfbfc46b46c17e0b5fe87c210bf3034dc3d1a9439ce9004019c138be7d6f8ec5bc010b4aa7cf01ecadcde2477964810d87c52c609a25bcc1001c0af10525f9654138dbdaf25b24a58a22219bcb2640f26cc4a507aa8024ab04de3a07f34032307e1b8d11224080724be7bf4cf855ae2a95e5a6701ad534149e920bff64a31043b415cbfa7470091a8105091065a4af8c7dcbe489b2de24858aaa9245d8b287309ef17f86b1e570cdcfb01c7ec82a2f61767d1c94e47c5f0bb2c7510063b63298a1e8457e5ac23ba3726d85015ae83ecbd60b1415e9c94dc46db990325e022cca6de063ea9215a053389d7b49b35276a49325269d0f94e96862821ca4c655977251fcd7fdf6ba895842c782c2c89addc2f89a5026bdbb9f48e23d942273621210fc2d5046a07c156120e6b04926d83b593e53469c61cb736e6259f95fc6576fc78722a05a1382c7be2df1fbc8bbf7f7237d0c775af540046d53ec7247c0de200c70150f7e7fd5127390442da085bf0367af3ee2f89142a561ea05d4775c4463d821d92ddcf3bdbe60cc776d97339e25dee77bbed116f4da22da6a26e30bdfaf36318b528263d71a2d07f1db31e18421c5d6a1f02c6ae4c4ee723489cee042e21ceae0c3b1da6acf9b2d3298ddb0335d2f75bd9593006f22131c6fcd30f57411c00f4fb95a6665edf27979c6e911387be4322767c88844b431f1120b5fcc595fcff81e5c92a3d1f8a1a64df3e82722c2530a8f817d481d231590ffacd4420607df6ca37fad9196846ea5b51d62f8a9637c40ad852b5eabc1aaabe12a23988161c0ff30bb25851089d8641f11efd7e8e7146030800a750badb7e4ae18910b9c796c1039d656c806fb38b0a3477da4940519c800c473b1dabf5a9957cf236f97eee1fdc002700779783379cb577c7cb3b030cb9e56dc00fb7e7c265317d7e96533ba78c01b4544c1e7171b9758e2a465950559ac6e902574571b553e8c0033933e7750bab6e785ad66290e0699cecd744f86cc1e3a28a2a3f6e6abb557cec7613cc49c33ff13a82b127e2865005563a44dce0a2a114d523f24f03f4b372ca2c40f5203f5858a9d3bc6e97b31600ec94898bd3bbc39d76dc8ee513aa7588ee3b152790822963a341285685c9c8cd095020c74ff3d1378ff9ec6e52d80947f723b438012d01590c2d897dfd5cb778ee793dc5ca7d7e6e44da4c0d9eb2f5a5d6f376081cff9ba45175677dab13255a6c0498c3320b53353ad4c9a4e18972ab2831e9ad7b4608657b1add140a8aafa3d4c923c04558e1e30e362219faa771a5592e01c68b0aa4149cd86873a8805a38f69008f1747e6ca3b6589d5ca524ae4ab40971520ad293c96e01ef592188f2ab977f674cd1917d30e911411ef7aeddd3732fe53c5bc49b72d90cbc09f3fd116e11438e061500c0abf121c5926f3b7f209d86f4dea6553c5692fa0b903074b9829b1ba0d1261ce7a7bd9fbcfe69521f1208d3d313130b21bb95cd5965dbbf549d39079973a237cc393218359cac66a14eb71c414d47587a4d8ee6930bdad911a3a2e72beba01293ae3781f4fa442d440edaf36a75999aa8373e565d65488e42e2f536031caf9e90a05aff63a621e4ae4e7c41aa42561db13cc50b353bc08d8b1625d33e46e6325b3da2058a3b98eee5e0566518a793842f2665cac31f32e523728a45c62cd19012c11b8877d84a0a6cdb0e74dafb450ae330a2317d174bfccfeae03fd09aa4e264f31df64d28dda21578ca331bf8738682faea06b7d45fc36bad03f6d4f0dbfd44d0697933e5577d1ba6e4537a7e6b7a89979c155b01bd8dce5867e287c4c988ea7d748e11df60c9c40e5bca48794f546268fa8ed0b068b197badd674c75db7d335694736869e557a6591859039cf1bcdb35a2f3239c29c3818457d8308a623260e56370861c5d1f91b7cffb07648ed4b3b5d51c3115e4771725986c33512f16735a5d6da85a040cacb2e84147c8af0e3c800fc722864991ad49259432d75e0d729a9587a681ef98d242b4db20bd95df1f3c079d4c98c05958f809cb3fe9d9e487c68edece4c489b6f2aa1887976fade781c44236e1d71de5cf59a64bc8f483384264f9ca1697dc5454c027811d29ae28618af915b62b2ac280d8ae5705d879103afbf99e0a86bf24f0ce7798d61d7efe5ec7a26cc95d0264e6f24300c491c89cbb52b144d873072fa34270c1aa25d3d7b4e2c4520587d9ed06126198fbe09fc6d32ff3f786ad29a4094c015270f10fb78cd4c4646cf851f903162e8608b69dad535a02040e933b1676c64d675c64f21e70428cbe12c06be37838bca025caf060850b217c46efc0f86c9a8478af759f71cd7ec9d5b51060d755c63e8e1761fc1feeff4ef3c93108d3666900ca89856d0c8170045850dda988b1122a50e50e5dd94cf39a98d28dc133457a230414d86c91824a4423498512fa1e9dbfb1dd1467eafcee2078e5189c4c2c131d3c7046eb1777f574ca7660a84a895625edcd856bf7adc61de7ee5806d28a399d54310f33a8acfd6ffcaa719fe13949f2b2af71f2df36043920a3abe327558193ae4022f196e26dd89ba84ca78d7b29e2487bed123cf01f32e9b392731cd0af8bc7735e481f670ee52c263362a687f60ec00dcf561020bc3fccb073de519e08e5c297242d6bf7f9ee3fa434ed0269f7ebab64e0a69c72e693e48204ff1f3e55ad59cacaa88f7cbd226fe11796217ea9eeceb06205cce67c2d12bb05ca7c6eb97d46c743d4a6bb44e4b891c5c32144610dff67612ead7ba95aa5e9f25d5b32b3c55197abb85bae026bf2a252ac28b79eecfe6096b08acf263def8fae9e39902b6412e5bcb3d5026d78d6c28a9823fea6f3b4c30f3b862c6c9ff50686b06c23d6f72f17a17d3735a0a602976856b086f53ca34353ae9e4bb0cc4e4a153e318ff55ca27c7219f7ac44db6f2906d88f3fdc382f4711c6f40dcf25a4e4dac4d6f6b1c809546c234352bd805bd5cb222e031824e07913aadccfb5737630d89c8c78d0ff87abdca010fa12ef0bfb431563d8f582bcb6c3a809af0d6f8a492e84056787288dc7f5f1c3e50b0ed1847cb7ae2ac003027e04d88047720076c46f32e11259137838f68bfc98c55637617a6f6b4aa570c0f182852f01be59242f525a1eb54f922e38695a99fef75a40c7f1140b6eb9665d30c3dff2a948882ac700c83669d8c2cfea21fda7fc2582829ebe923a810a8627b7cc7962eacb7048f2051344e2e656e357d4992d095e60ea0a52e7b4039e535bece44a7b42830b45468752db46c0ffc7250a71b8c26581bc3c89f9f4ede2b8843847a8e64e504352f117f026a5561340765a7901a71221d02bb3fd4c64a65c6200c408ae71e751b924bb92d5482375264e8ef531ae536cffc09c4d2fb3bdd1a2d727e8aa5c428ff47f69eeeb22b65820d1980ea8acf7b479e20747cb207c2a3b64ee49982346200461b8280b5bd1b0f9510214348582ad93b821f6dd69451c41356c323e9b75ea2b891071e1a858beb05e6e7658101b743013801297888ff787758c0adf91a5c3b4767ae292d5673c75a418c07ad272457b4f4740e103e9778bd15bd741511526fe62e28f6e0965b50a829bda3d69a6d4bdf318987a8fa66c76cd228d2e540dd5c4741a095d5b02a417fb22d7ca4292f544243fea08c42567772c28485b514a16c2077a4b9c81df7a8c57497e01cc5291fe29e05f2a640a03262920b5f2870432dde660c4d99f10a2f94b640c972c8c5cf27d4053062884958f496638de088513398203964fe12b51a08ead32600d9e02e4f50b177073b25152e53c876add683812f6ba6cc44c87807939f048baa221d200735c02acdd02c58579a01e5e3bef97306c4b79bc58eab3cb12b513791822ef92b84211318c1566f553f41fd7108b495d87a9eac0817ab9a34f3fd7f1bf94f14ee0a834d0c01340af85086367af9b47d4f0b0c8a784edf9dd8de2e697a7363d4d925402b43ad4ab08a619f6317e666d504fe06a2622f3fe449cb6cff387e49f59c641d7aae56cd5025246d896958951e4ff1ac80e83f35623d37ed0c517612be47d96f1005b21e4b680a6d6dd17492587add0c634f0e67488e10c5edb30abf2eb7015daa3fbccb94d8d81973174ff86760dd78b47bfc3a957977c3a7b39ce558e2353183a50bf9eb72802f3de1c06a7504608a4cdc8f8bedc3291ec6152cbb71603d0155684e29a02d218925086c97ea100e5c280458e9193dd949230f5d4d081fac95e9d0d62a7916e8e271dca11e41485e6aead38da1b65766d3d312fdceeb28c6fcda1142a1f7025697f436fe71919bc47b9e6e91723b6096b4833510431143cabbbc579500ac15ac664ab0d6cf3b43ca2a8d4c086d50b9ac8ba65b5caa0300aa23851c8498471038afa8eed0f78acc1dcae0ff851e530ae22cd32580d46c1d26a3e09deb6ec72aef402e643f63fe0e6054d0c8f413c9ba1a209ce7cac41a742244785f58f30f40edc3180cd98d8136d3e816aa4209d2d46d9edaf44736f1bee359fc8ad2f47913fa4c76dbe689f5d301211b528c0e8b364a790039c228828df3eb460a982b5093f1f47e5f4090a0dd1150440a2f26b63562c8da0f0dfaf186c8b7f7868189726584eb56f0171e1d4556d209b84360e97fd7240caf04885e2746215c7a09b157a0cc8cee307bd4db08ddb649dc1e8f27e3b81bf5d42865ff07fe31f1f4230c11f4d1bd065f1f9f2de940594cebae04412500906897d400312b36f1145f372e23175646693bfede6891f9816c10c2cc122219fa35877b28bf9b92db5f4d77f1639cd12fe69dab78f3b7c52b83b6131daddbf204978b220001590833aa0744408b3b1092c12aec207b35fb49b5dd9eab616093d709a4280510b3bd5b3eb02d8b5d5d75507a33d981cee236ded3df00a67e0bb2b56512b5e0e8b848a81e34547675a0bc88bde54bacd38062981339358f5d3b43e02a5e6bc004813b2c5baedf4449b2f7ccaa56c40889d1656f214b62d79feb3638b936315857dc31aeb6f794a93765dbe470179e4f1e17f0f452540dff1538b0409bdfa08197c51a92418c91c86c097f50b3b4981e293893b82a8fcd4c1e3a693c057f480f40ebbb8e0e5bbe72e07cf8d70d1966672560c79b9362312ac623b859f7c7e6fc3c680808d344c82946e1390c3f94d234451a936954db84095cad206d7a781a89c8fd6b49dba45fc32e09d5705717a8d1970f22cf3b772f4e87bcf483af6f25200a0b6e6bb250ccff9fc4c03aba70351910fd5b42dd293e999c0d3d514a698b27fbd689a62411a68d10255931f0bf940fbb62746ff45ee238a300d02fb11e2b85266122237119c0c4b37f18021f015eb2d6fbd6e58cd3de1ad5d8156c4692fd01132389a3df001b6200eee64b43dadb077fc8b0f8ce3d714cc26a764f8b7a3d8c30ea04bef18ab8f6189687f6e589ecab22b9f0349a61ff695555571a8de1eb2cc07ee3729e393f83c4171030d7321b65e80ea3cf71a1c7740b20400ba51c1ad3b3f122a4f83cbb1021d1846ca5c059477d89feb81d55dc74d389b4b7abd76d56cae32a9506c1198a8fe2a168ce27069d16a0105b19b226404ca39010dfa5da48e4b2ee27545c288d96ed643118a6b0916e459889d14a2105bd6ee75c65dc7c80b072f989e913ee159625eb230b2b30bdcf153092654f06693475ff7bb51d5906b3f9ecb74cc67f46047f98baa8b44a7542ddf776988762a6d66abfbc8dbeff6c3314eaeb9ac9d12971d92a689d58e8fdb0f93b395008433ffc876fa4ab638b874e8d404867da41955b068b59f990f265bfce2466899584d147bb16b96aa568e3ff2efec3ca73a8d27db14142d66577e4a0cf79dd634281bdbc9199e303b374ec928beae8d162c9c81ee96ddd9e5ac6ab35f88c46fb0753e7658b17253ad62039c6f843b0dad17eccc6b7bdbe6e7b8e5ed9a717b9c8c673e9370d21903f4921b85e982afe49396e5bc35686eb499d99cedb4becbfab9442baa14d200f6e8e7977a6db458b86eb143a55772a9a13856371a73b8fc846622ddd61d4cb4fb18d4546665692c91697b9719f22e9ee7d08119f76dd3267b8b9337e836e31894a07bc41ff9a84739a00f8cf91b51504ce4d6e538a214566a8ff2dfd355433fb7f1732c358a4409d01441dca68362e22a257ba5d723f7cd04669c09b47633c8b25ba49d3bb5f0b8f233ebb875999759aa1908368a33d068415394fa2e3481119c00506dd26e8b4e1c6d3177e4c3e75e14193bf933887d798a02219676bd71429bc1d10e176765f71cadd8e0fa549daab12193139a263aba7f24beb642d7b1002c13a759c30840978c4ba097c62331d61b281db82f2eeb29b92c0992cab28bfa9be1d52ce87ec06ef848f6943b6d2b7f872d19753adfbbbe95037d2d4d057872be6993884a612d24eac7fd854ea7e87548e05b595085942e0281cde4194c39d88d7f681dab247acf6d412885346f4707ccf2c5dcdf7bedf5dd002c03001d3bb957538db3ea7fbc793ba2cd37482bbbc3466aaf1344226fa3799515777dc0225e1fbb54e22d921ec33654102ac1e8a2db9b7bb4f745c317ea8bb296889d75e19692f86b76ee90bb266d89a2c09fb02520a1c581378226878b1474f50660f78c3eeaf3c260a4b3f30c2c23f38a1ae8a8ac7ca9222b417a796a021582890c817ef97ab63fbe5466255a0c3f1b684f8fccc7e6eb3c47a435fb8d1cc817421557bd5331a2862134aa7dabdf5e72c4f595aaba36d8447ba617722ec28f9484738ce3f3ff8c3543c9df0120c37f9d303181550530b6d36cd7ba0b719dc0eb47ad0c4c9f2cbfc1aef7b96e80d215f4426b34f6b2ffe33bc2a1ec878d5cedbca4060e06db58c129fb3798ca7ee07dee4914667374f93813afff3f772b6249bd649b781d2941f049832e3771fda8c5fe1d0c891c991778f63a7747cb88b3e05b8b884828885440f2cb7ab021d330bc4d4d0d96ba6e470bf7318e6e6157e1b3addeb2eab7e6b2299743fad1cfcf03fdf026213ce48fac7f91693d229e64f103702f3b1b62a033a274b08c765d8c3791dd4db8f04022f28f57ef4cd9bc71616db93d1d07d7207d3cfa3c83a873491095ba3acbe5da1a05d3cc29f254508ceb6476a4a1bdceeff6ae9f9f31450afa97f31667e1004329f9a9666ede9e806caa4ca1efb2351f7a1af6b378ba37507111c56c2e4d76b5aedcf944b9b6bb6fb793aeb088513836d475a20fc2ef361a1280e1079d5747027a5efc5d623941d4fd8d3579cb17dc42f13e538f5645608cf85ee5895c195325e247e5824e31ec5f83fd6d5b868036bcbf4f2c24be4100cde8178eaa66a034a357c9a1920bc1d70b238ed62e33cf0e37f42a49b8b2f9752433711d94a3e6ecf9dcea9b7c8d4ddb7a7c0058ae04bc61bfbf7a05bc7acfc1823d559be4dd06428cae8cd392eacb5896f2a6a4100b3012a8ae9f4f400cd1c88a02c68eb916021891d882afe5e623dc27fe1abd55d1c30f901e40019d65bc9325c10ada4dfddf4b59dc19731f2a0aae1385ac302c8f5f65aa73bf7a4582881b3d27b467d367ca2530b40864f471b57d13809a7dbeee4461033bc99819a926a084b735c70369f9e61dd347c97a931fa5167c3d51700d7bd79ad25681cf152ab9668dc982309076927a1f85e08e6f551a3f89c10add3602bb2f5e19a12321a0f204f7bb8d8ac5a3be4eabaf01cee1f687a29b7fe33e84436926005e4dc311ab8a44e581cef9c88638d5fb11274d8b1ef1e6e9064f409ac0b992d31e99d324031e09a1cd0f82855921d2d2881f0f5a4207748d10a403a04d465c008856251c91b0f3af112b6afba0332f621c6d25934a273234057948019dad33947af6d962e226857644bba37e0c03151cd3aa38293aa3ace9e2a9bdd16469e5634a4fd987f30612ae45d6a067edf7e51e56f10016a4752208096722e8fe6dcac78f34a975250869359c87ca8eca7d230b01e659769afe11d4fcbe4c964269734cd7da3598e3fa6f42303b19c450f983d1b973ecf774aff043864df2a2d2b31d160b93824443e4907bd8ca5c3f07c7912101510bf13b734a58d86887ea95b5b9baa27c38c487151b07d3381db4c56fe65b49abc9cc76db119fca588c8ece62a6aa28b00273867918bffb8796bcf3f0884287d8d7830e4c3662ac45c1823f34c4e5bfe6a98184e378fa9153b1665be9e9f0fbc610e34754aaf5c86a9f03798e2487d0c61a53413e0dc849a0080dce9ec665a04b63152adf34737d9d3e6d4c582d593dfe9c2d3ace9634555f339d3ee17ae4e295224c6f1643bd99d04eb33ac7416d041e9a496491c241ea668a806534e925a33f199a5cbf83392f4deffa37239ca8e07c7f171358415640ea4683fb80cfde05c6f30f3e8f9d2f15b8c3a0e0ca3b73f95bda3705858bcb4947686fc51c2fae87bee5726642c8b1a8154990961250b6cee87f9eb1a32b3657cb5ceff8048d9bfdd0a502ca5271c0c56e3b237a782496ba620809eb15efa34e0afe524a1a0b56db7c58d066974df6c1dd24a23b4a0a48bff6a10592abc339644316129611fe9c49c0f751c44f88195fff0353d69731c0a444e4aa0f7ee350e1fa18f12e575978e25beee04c2b042a0ea206ef51fbf0cc707e40a904a83e2a19c8904d3d8bea774934f138f720bd88871ced7fe8a1811a68d8df742a608849aab7fd90b95eb8a6970698430a3c720e05a2fd3b174cb6345ccbff282d7da3356d364ea437f859c959b9d10639221c6133c94dd357d45080d9645b1e804ac5fc24e751e624dd233eafd9a4bd46e45faac314e108ec77b940bca00be9caad4671107c91883dc79078ed9d242214bd5696484d8786fa7bb4b303263b8953a8686a2c1f07f9e306d844a4afe6c245fac954f8d667a09b1026cd8d67af985fbc8f969efa19f0b666fca97553a335a06e12df3b583f21b8583a9a79e8372e1a40c805c70fa402573beb132faae42ca492d80fc1257952c24ff524025716a9dd5461c89af73c9bbcec7ecdb7b990a85489c9d9960c7bccd8e745b880cc709e7687027cbf02702dab7260000df6df86ca3314693964a7147de667560bb3db2656ccb2cd1b7493220a9488305617330ccad252db6eb094b581c2a69c06cd773c3c611a33ce5bfbda061378a657d1f6c31a2bd1f6092ee403156ffbb3334cd49a67e47a5ac9b8b751f2592ebe512c3da705d99840d246dae7bce7d8154c2f35f9483d0e0939d1b4ced99b6a47afbd99a0d3c4a6036e7af1de05b4f4d2d1b32cb7c45d198aad21d3fc484e2c0307b89b8628dee366ba2e96b0c2a1f580a38255c17192792aba80badf7e978e30e42b346e8cc93474df35e2d0319199c0200e2f0c168ad9803aa83408ffd9c458802d226956c41913c17490fc5003e00e67925de798b0cda8d5eed7431f7535d0f1d0f052c5841f13396998c49a48a37dd00a4dd03a4d29561f9b311f436fa1e5740ec6ba106f1631d0e652278cac462e6afe78082a2d18d0109b926633c410153e54eb9beb1a1ad23cf6f1e577ac8f1b3546bea0c6d0d01cdb98cde4e356ca1cc2d0d0f897978c6d1a91fd319ed55d914169d32c343406945bf228ba2ffe2c0c7ca5f888b19f9742435946d01731c45944dc6d2c665625f0d6587ad2de39716aa244fccb73369412bcad4ccec3237ad9d0aa63009eee0c9b5a0f334eb31d73e415be6455d70917d28b6dd632fa973a1a9c63df2d45ecf2c4a921ffbd9b4235e441a568c8abe79927889bcf7e7ee417b2f23d3c98eaf770ea9cae755ab006cfada004af056026f401e18ab5b5937f0034641c92b417f59c627ccf2539f2bf5c4064767ab39ed6c01dcdf8594085856064481b430f8b2cc1c3d167ec61f22cbba8890d5f17baf63bcbdc505776797c635953dfb126624cc7a9ddffd784963de0f4f3b300ae5728085a8e8f2c2ef9618598eeb1b8daf5b31e6eb67eaa46f1521e250257b1e3188758b78a21f7f1144943b7e4aee978bfb1dc28a95ea03b6321a0a0e6b5f53cd1d10527d4176cf93525085e97427478cb5ee6abb5d6238462df3a2041b9aec01d99f20219a8f00b011409ca22a7909f239b1da1580b6edf8571af32ef8874c0a3780302b83c41f7ed57e30c5828bcf4bd04b8d9b293a31cbdf05516803134eecbc0df37d697382baaf8c66f9cb06621c23da3ccd14edd41428af45302d0a0ca353fd16f30f8f318c0fce43a6bdfee2c330f8ff0a80b91f3273e37b6484baf67a1a3945a394b944f3d165931ea5a4858c560800af2eedd82e9c3812977377c6c6339bad9351e3877cb5864743b44befb2a1a98708016247f8174b1413d82efe76f887630f660ac3039f4101458cd25b5c6a05e7bf31024c78d36f3ca53b5c91f672a964956960c775e80228c81e73171e5ca34c2cfb15d98f78b270a93b82191a0ac5482d882884c4eab21ee7f5a3f3158fcf6df191a93ce10bab165b5cd33eef7b3675ff2b2262ac5f2fc9dfaa9f5846e0a1c8eb23ffda8e459860426f1ee2c49a5f4d14b62d80d48d6400e6a42fef3c77862148924258fdb7fa4b0be1dffcf25cc8ba475c7d3a78f051c20350c4be802608ca1d4fe8afa390bf45e03bb94846786e42e03ccc7b7f842cca21545df417eba1e7469273ae38c4e2117f81f772d1acb24c4acf0c707a600654b21d96f9ee1cd82577d650c46b2fc243fc8a92e9c4377f25c8256b981afc17281a2d977578fd6e7e5ad2d5567b2464996508dea7544578541efe250c95fddbf958a373b80c57eb1d04fcb13b14cfb3b5b8bdf76e83713d1a4c320406af41fff1ee23e906deaa6c0041f1d9adf5fb1bb56237f607866b7345c6557bc119774f7dddd676aa0b1efa4a5ba8f10d7b6741c67311991d239e2318db93651af27e587d3f5604f5a0675d24b71e931b531c7245fe27d248d5d5ae8a9a64d62b341b039f90ad395a99f7f014a3daf22f6b0d24c1a38686a055dcf94b2d8572cf6d382444cd31ea8af32c1bb011a98b8b69df8cd243511310e481bfdffdf59dc9b4013ce32b72a29497f527c0be9b2393813e7b55cc0f5a1d3f9037950fbc53af8b0c185c411f5f880e0deaa51287a719fa18b82bfec6be3c1af461ac16f981cfe7ca86c60f8110e3ea286fc0da5dcf294058f73e5e3620cf552eb074a766e2b054493d12341c299afac1e4037213af44a8eb785b2b4bcf3e081c49b9685d3e7e0c0b7d9f4bb50861e4e97a83216cd1ead54f12f894667136d05abcaf09dbab318ff0904bc0368e3805ac82d7df57b57a76ad048f8a5c11c11c23048cb810c0515f63d8e3b960a64fc4d09f8a491301f0eab4cfcc505a86df794c892c095af8148d84b48d4635bf7405dd5ae9f35fba1de27fc18209f8b924e0d9be53e172ae94aca3bb26dc07f650c12614c479b1163dda2d08625c1881272be2a36c6e63b6412a67d85d9452e5a126c1f46d699b1b1753ea684cdc30a4777a4e520ff0610cfc484ff24f4d8c29219f33f660737182befa6e623963890ff53ca1e3689e9a0509311ac7ad383a17f95a6343234573f5c62970c9c3fb948fea27f995fffc4e162b55896ed0526e9fe392c077da2082c68fef00e433168ae3ae8fb6109908f0ac9b6fcd409d415e45375f0e6213e16533d626911fb7b5360c10e328c04423a2ab6c106f94ae59e35bea3903e235a29f4f10cd642ba33b09bc7a88e4903ab6157cac5b255e161c43f252ea6d26453128a18f4cfdf3b68e8e7cd61abba085f7c9d99c20f4b9116992f3eb36331f599f6845c4a8825e3d8002c33164799075bc1f9f3373ff49771179ab89fc7aa56cc60af0d474390761114c38d71870fed3fb9462bd63c736966c78b45263d7d26e17981df2e1baaba9dda2b24d2bd5591fcf2892f9984d128084fca1475467d2d1da996848948c52f8e7de949b9e03cc46612ed03d1dae1c704d17998771ce7af4ef8fd1188882497323dae7136732c6332217bea2bf2481ea3b4e8a7cc0596333c5a5a274e3f9e29096d3ab72b3fa231d8415b2d65cf362ea20bf43e3141e62f7c3312b119d79d365a93cde83494ef914afe180b7178864592e3fb6dfbeec3fac5b8bf680ab6edf411335a55e939597d0692c0bee89402384896516361ed06470a3e325e9d9a4279a1cfaf0652067a2d413f0471c4220c5cf8e8291fe8369f6ec633c9f7d9477b07aa6a7a10bd1da89565df506f25718716080a2a123678bd00e1557fce34d72793f8d1885c05f00ced1cea309cc8f0c69e8003675230a0ff32a552f8270cf5dc81afbb35ecb5274655790030677e8dc96474a0ba38e6661b573a873f4b0d7d4f75b9cca52cf29005222cc8211e194710899691afbc33017e9d5948c1cad5592f100ef1c603d7aab6c80e486f191795922c5cd3ba61dfe254adb74e76fff95c03f6d2e423a9c62298941ba8c1a2a42a1411005f574783983b6fb1ec8758318f35588fa83e8dcb112ad1558838ee0693c06bcbb1a7ee5461f882c292bc6f415ef068a64a889c1802f195fb3db1526494436142a5d3d894e606c4c33917721928001a5ec743fd55714cd366a71774b0df8211fde296c86eb9d174b1347cd51ed7fa73309e72edd4a93e3502cf31b1bd00a71e6a0af65dc8e4030e7d4a6ee469a0c67a9bcb2e24873e972ddbea021d65ee11a67cd296a4e365a0fd13e1ded90f219181ad20ea7d3ee2b6e773fee709439beefd52efff063776bf24e57f1cb9e92edb54a8bf904b46f70efacf844c4415ecc7413bf5711a41c1e12f9044b6a882f900facd184f0abae86dfd84de4169f4c508162492d16d858ffee2df7f7c4bc6ab0b45874c700c4636e706a283db902128d610e55e1dd3c41c694bdc988cdbb592f6445495c64cff52e3e37235c3de85204f6775c82a0810f39b0968993e4b7b70480754cccf08ce92770d60062cd4fd68c0dda4472beaf89fb2cbae928892146d4643b8fa367f503ccbc0301a83c190aca98f5c878fac41bd25c9149e0cb4c2b6247dcf99f859d307ed7bd2af9f3988b1079b751967558c42ef424eeeee43e5439a00d16aa98f9a727c699f033a7cb2618be02738c043186eea545597050865c060f5b0a154e494974daaaf0daa8ac4c2cfe1dda1074565c41412902e8546d9e752d4c352a0b4b5d1f4ac3292b687153ad9fcc93b2c3035532c26a96b2a7e69c5f982dbfdc2655cb3cd1f889a2a08bbf883980fc41b454b33572fdbd6d9ef24cb080a03f8bb92a150f9a53c12f4b393051e0516cf233cb9583abe0d26385acbd5bc1e9c67755112a739b9534f4c00c9a55c6aef0621824767528b11e3c066c9adb185efe676fb347c2a860ebe8e58af54d300a9b304d17b38fa486ba36bb7b61cdd655091451bf55d2143e1ec897cb62a5d4a3456361824e428517f5af97a77f69e580dfe6b82842fb89d0c49bd3c5f36922ea7c890c55de4faf2e7c02282c159d5734bdc4c45a84f292c721f2f36461b9d5ef6c107663cf30426d4d1f3160d3f86e101dc7f1642b7b092e4c2ad91c7b8408935282197bf974c975d201e95b79634e5c33864eb958273f781cbc5c6a11fccbd9a306e048c6d425338965f9728ef992a969720747325af16b48884f3a87aaf8d438ac9bd906e97b82954ace7e2ba378db35179f949bb09854e7705fa1fda630ce122e880b457c68670172050ea4ca02f2be8743135c77d9e740bd26194ea78885476dd6ee42125b30eea87102aeb10c3841073436a7d1402c69206f4f0802f9baa8bd67f39d0c27de9db3a5089818a9d2fddb2c348a2232dbf7daab43bf5cfe4d2f73f32a2ed5c5fd29e4a36a25c8eb6d07421c6de2a7f485b98f9baa861050cd7ccbb541368f73668e93208312138a528bb2336d5671a429747517c712e452e0cac4c18d9503b5718c8d97d6eb3a5b8e5923ba106039bf4dde3ebf2a01879ee3b668d9e11ca3851ae06bbcc74802c2393c0c7996907342b4ef20606cb52a39cf591b3fe72d67a34fb3f681de528ed701f8a40e0359db72be58f12c337f8bc7135ad3f3f15385a6148d2255d7a1e5af3c5387d494c6b97772bc9a7b974c46576719db46d5e8ba12e6c15fb3e4294428170d9e4866331eca07f2872ae69ecccc33456ac6855200a7173fb0aa4fa828066652ac1827ea4810e6d5daa94aa30e134cb9c841e6d85d961c2d86c38019dac91487936f77e5658c3234b54addab6502b8870e91df3b38a00b3e41417f55f49b9a956ebc265b5722dd684eeadb3ba279d0222b78964d9e685846ea4a80ef7d10f575c8ce21b51a29e81aed1a935341ad84cf4ea799281e035fb2f6e81ea599950509d224b8ff372d1997cef86eae563bb0a3d887a737045930675553f9200e48c9dac89d21c1a154bbbf54cb9703f29899032d6516e9dcaaca79c75d2dc761816fbb6875ab6c22fb79b9917451dd6bf9ebf0ca8ed822489056a3befa110cd8f5c95225395cbf0157bead8683939f48131e5e76ee3528a20d8323ae619288b8d77dea8b9964b1c1b92d2c49c459614ad50190616339b8281391a5b6bee82f2f8d098c9bbbcd9947caf711366e345c126f6a2ed9852eea45175ce0c0c07d089e70b7d8ccd3fba09f3363311ed55904aeeddef3f00dc3352bd18e24c433ec658dbd02f3a013893885adf7b96b4e1d899bcc91e0806790dd4978d8c59db5d075f40e5744f576255bd7816d8217cfb58c35e4a16f4b1018d528fb3468b5f4163969c78f45a0d2d5a32a281fe9c492870eea5cbc3d9d5f151380e46a383add0c5cf1ea679fd026ee68f42dbbc53d973cdcd530cb381aaa910daee7822e423564a6a757f0160745033b92854ed4133523be8d1683d369b6d980fc590606b3ec3a3b201e6fa64b4b1e02d3d2097291e0f54b4a059519a7b1a4347a3cb4e288f8125d357dae726638b95d4136e5222ed1cfd3fd5c62329f48a0fea5a1553a2b14cba21f55dc969ad86f1d28246d2945c719acf5c590412df332ee4e4fa1dbf6075c46b058f1cd5d873c67333c12c91662062fe879d6aa0e4fe330ef1ed06c92e7a9ed6f74d8d704b79fd37f9343e76962267ce9b014d51604557c3cf429fb43690f4891801fbb738a2901c86a64fbbb08825c7986052786786dd5d414c32861f2ae4ec2e0d0438c6a146764632a3dd25e4e3791f9b3d1e35ae7f4ad6cd17f0e004475781549a9c971954390f3ef0b7d310ded069e6896381ee5dd8183f9d69adce7f222380d918fd70435e5088df77150ac73d820c7d353b6a9f9a8d2a53793063242643a17385555e0eb9163b147fc9be7e208fbed7406b155c4336afc7dcc7a671a89b7daebb6a8574a95e3af8d73b7ddd688df10d0c284a0afe6a64299ffca6beda704ccbd12b24b6176eb888cecf2219c7b0c04b495b334cbb7fb2d82648229856f71419bc62f494d51b6dc9937caa690394fe598f3182d11fbb527e12b1a8017aa004f64ad4dd2f9721d88a2493abf35f94b65d025107d0d1c7a466a08e90ceac13eabee18337a8869507fd1146680ae5c66162aaf64134957c7592c485eec09a15fb31a56a6ce48c54daaf542b2878383b7687b2e63a7f411eb805d1700bfc56d072c9a651448073615590c70eaacdfe158067512cc79e6e3261eb13d55663b82b65b18282c8508dadc1b36776b196890e47cda38bd521ef61fbcaf201f432218df35bbdca3be2280dca04fbc575b5fec3bfb4e45505e6f4e03dc5a2295f2cfdd929619c3a80a92d3ca9e799cdcc6ddc2bba412c43c568aefe0909857824b6176f8728627b898e99b1683b124c65c82bed4cf8e5f177a87ad263861a0ace1efa56d171ec5c5bab5a7d70b4b1e609e70733ff1a72eaf1516202ebbb2517c1ca2a5c44f9f7e72282127882a977cf64faec89a235592698c73bf6dd6afda36cc6f5a9f31220518e956b3d3ced3f35157854c4925006d22bb394e17ac656609acf1f69b0e8c6ca12d63b580cf1336f733e34ce992a713ecfa3184e506c80be221e500c383112008750e509a883d70e0875aefb2029db9689a9048ab9bd9a1cf5955682669f85e164ece85ea1b3296e62edd4f22654fb26bb4758339b66f242faf49621dbb644b5a6399ca344099d9fa48e17aa0bbabc6f9f2c6dd1147dbfc777f53df961eed49ddf126583585efe9023743f14232b1347a183dd76f3a45c5b0afd89896bb12d5b702ebd31061572c10f894cde200b654171027b610c193ebd95e82565b5538bc00f69769f409b40709f969a6530d984e5ea22e0f689912b09cd6f796954e15e4e91fe09a862fb2d35fc38a34dbaa978511e74d0a26011b121c07ff2dc1172a23ddbb6303233f2ab7cd7749f54ff2723673d173225d4daaa092af0b4158830397061b2b27565e1ea7fe2dd456994f32f5690afee26390ebdf8dd67776d0b53b4634bf81e2fe734580efaf1b8e96d5dfcfc51862e12273270167a2c6a8ddf808f4f8459eeb8c0dabf70f39e347a38a943e073375aa435a8b6e69bfbee85320a82952e32d3839f56d31d647bde2c52422dbbcafd0d416c3a80956b1a946dee704085f4266b0a1ba43d043a1a1f9a5a305c15351d9981a263f758ddd46dd4f5f7dad545b35ba6d52a844a7eed36a439734fa8ac5fbd02c2071e99211c00030b60ca0084d1bdee9c330ad85c00f4001e6d6bf884261f632ffa08f661bf35db96969a889051237bcbbd777309f508dd0914239d623b3a15fde41487a563d4bbbd77637b775defcdfd60c3180cb3d664fa51287aaf77d7bb1b932fd5c5342a7805bf53d74d267b8750f94ad783e8dbe5556f5dfeba3eba4eba56377bbb6b92e3e17615c3ac35997e14eabadbbbed9aecee8750c117c7a651c138f6e7d5d464abf295df2136bc826d64fb9b7cddb03b664366d1adf683e817ee21fa867b8c7ebdbb3e62f2752ac2a347f96b4423a625d2e57997bd2eefca7e5d5e67afeb9862ec2a81bdbe1bdac8df65c3dc1f3f44895e5f595c9c9edecaf920f27e9663ef2af8266fdfede554e075f1a86511fd3159723ea8264ab668717c1aec42e52d4ec3f2abb46039b6d1295a5bb438cdca555ae0d8a92156b00a8ee91475717f69bcbe2a6f7ae9d977baa961ee53b2c6a12a571c62217682435b42e17bbded1db9fbb7b82c5fb9f82ad7050f5c02eacaf18750b98b3777cab1727c1a95bb68f17b9a16bf2dee7f4fc3f216bf1f82a5850b7c67963ec48902c22e30feca695c541bfe62081bf00b5c6f8bdfe4ebe2aa1cdf95c764adebb29925d75d931c0faa99f9af7c0896ab5c72a71cffca698e574ec382af72161617c72c180fe102636c3b557f9323e7ddff342dce72f1f1102d70c4bfc9337366aea8dcc7c8d0468ec72ca52da9948f3e28d38629603fd891ac795506512a67c823396229bbf664a98a41a9a44962cbc21695d4c28ecc17f9932f4b620a841ab139383ed6c7e463c24c39312726873227f644ccc7fed4253144512cc2d86861478290c8217246fd15521b65117246edc6b2882145f4758f75aa5fdc920c6c1879ec44a15e8c883076a6e2651147f0a1961563376e1cfab8f9aa17e56a5cafdd5267bef4adeb32311cf3b22ade262a66091c8da1666248bba34b84b13145fb6e188e9457cf7c8142cea0aff5f2c93ee8a504ebbf7e4171f9cc970b27d72b93e0e8d4fcb513031b4a9e70e664b90509836921ca5c4a228c4a7ece0de4190653155450c8533221cfcf9c1a8f1d003aa6145812c8224c66b060c8510b39c6cb0d48184c6a000231d65c3df345093e3972b561244f8ee461e1c99949266a5e20b64c0c3420a6e6656a0a24301561e506e6bc0c19b173c74513368463a7a475b16da2304f368526b5276b9e4dbdac96b4256d29a93c6273e1505a7d35166874935c6f0f36543860202f8bc82132070859e3001ea6c6b14d727cfc04b2a625130bb547faf03411190a9b086661d60ed9b2e843968caa92216710892a18a88e3d2e35b0d1464b53c5228df1891d72bc8b0c1adabc0559289040598749fbd8a64c122986c35196d8ba381eb24ce32dae064663a634d6fbe2a519d85035b34d548c14065bc91c311f1a04ad5eabd7b5ee9e3cf29440a84b72d7b48f8d3eefe8e3a3ca99528b3e78a6009d74e80f5d45ff4c54979460c3b884dcc74153f3c3290575c91591bb7265b3edb4ab8b4c14bdbcb1f796bb2524d8f0cafdf71160e3b2648dfa0dcf5ba169337368d533a07553c919d9eb89e4199fc81816976057765d5886165556bd33131533511876591aa31ad81e206a7834cc77611bf3a5071c9fbdb65374eef0d2325ce24be8b3ba648c7b56ef4dce64c81821cdbae488645765a2228d5844cd5bf333da8ae1409bf8bbd7b78b75915c37ec93899cf1913e1fd2d19641d2bff9e678c832094f2cd4209d7b64428166e9922e0ac644d1e310e110f349c0cca523368c3d618c0d1c34350ee01181eddee9b7399a30a589053943e659ba71a6b267573681bc11e95abce88626f0d68899043e720ba8f524d2eb4938147dfb453a463a7612965c0244b71fdd2f8b6eb2f5b66fdc76356d6241a289f96419a536537b943342df5ef1862d19437be56af4e9294743db4626194389ac6a9a96b56b59bd1addb6ed35e837bc4d99b357ad46f6d0bdc9968c512d2a35496f1039ecd3c890af44af9b8659c7cea4f36e44f6b0d570e863b368bc62be2293f9729d0b5dd355f944d5dce1512ed1c0d277cc0e13e67b3daa5e1527cc37fb56c819327296e87eefac6bd866e4bbe876e02b26422126f23562f6f0c9be07760f63b7b7b8b83d729c8f2d6f585a2163843eaff8a25e28f039e964cddb7028a42787dbad87b887369abb6fe7ba6fddf6cad5e87e3d05e85444ce88b9eacc977a9f1cba538a89a2efeef49928ea44a697c3514262c319c47ddbeef6942be6cbfcf614a0f912f3f6530ae40c99b7538ec66671b766d775af31dfede4add3e6c6d5d8cedd9bec63eee40c9f522063580fdd30e58a6c552443e89e2c57b161ac6a6dde2bc6236f8fa21bfec81b0ebd87a4b6d96fdebf7ffde1d0a6e6efdeb4d8fbbc57aec6e71d7be7c8193163de2947c3ebc9db75514dd4f579fbd25b6fec920dacf53a7f5d47c06579de64e27d2ef1de24f0bc7b21fbd0354dfbbeef35e6bfdf84cf1ef7cea6660e6fa11a44262e59f34298bc4acea00fa9f6cc85661a96216364af9d3bcb4e391a19932caf092b31f19c3d7b942167c89cb964a793f220afbd86ccb2d06916bac936335f58868c41e911edba76dd38b1df647ac3f3c8b15e77562c63a63b4ed98436fb864172bce24d8eb74920634c26b9df37979439a031a714b0886152461f9b2c420e298249e3585da04523489c884a62f013951811224f6c3373054cd9c694b3bc917202bf028d2db438b5162da24c8b162c2c518685656525caacaca8a844191595d329ca9c4e2929512625050525caa0a0984c51c6643a3989322727a55294299548a42843228d4623108c32202812451991e8fb3e6ba38cb59e17653cafeba24cd7715c94e1b8d8b26db165ca685a9645992c0b85a24c28145b30ecbaa2cc75595694b1ac5aa34cad94764799ee39a3cc9cb145467e5ede486909c104e8a70a287c789e48b2736489247472884821b26c92c515414b9848f12325ce1563d12bd30341a91461bce28a44b04215991e063d55ec9e2aadd78609c33353071a4329c5e982166d3062c3f853310cc37eb09f8e91e590962c8324905c226be426251356e630027b2387c8481f1313132fb52ceb9a40b5704c471965bcf53246a5ca22d7371614f3d496b1ce6add1c88b0b5946d620e43582343b055080707e41a56a1cf4c17d4bf19b1218dd9b558b3cc14c7999219111acd71c26c745249295529820d9f290a063da57f31bd2813e7fc8dd6f5a17b93fbdad48c61193246fdbc8dcd46422ddaaa181e949cd5a2966559169667a439d0faf29a942b298388af51e6ccce224f6b725f0338808359b81034777a16d19158c43c859846e44924cf2b7c4cd49c3c988e649922c655cb25661892a3e4287e01e3666640cec9040b47004a120435ec4451038b0832d87440822c18c18a220b491822054cb010638cb2bb37dad87c99b13b7637a594524a29a5ddb17b069452ee1b1762f63eceabf21095efbd76ef09bd61e9cd25a0fb09c342144d0e4bf701239f4e3b03418ce9ef3d39dd996949890a9ec8f5f4c5fbe4f4c43be9520b96d2574a573979a9f4caed78711baed9303f14141b504c9fe92b5d7b71633295dc0fd4647aca0d6f72cab5de5ea484348b5cc0604fdebdc9f4dad47cc232640cd3eb0d5db2e9338d82e3448d6ebadf090e61e412e9c689d2bed1b649ee878d3b0fa1dc9de3be594b0303857af1827a1e087ae1e87b41a905bd172f6e9c29cf761a0d8c9b0dd7d36b2fb237fcf0c5855c476fefa581a59f3032f7d0bd4b031bfa80912b07235399b78d865b16343747727cc46e2002d01460dc4004202964f93b6d3802f7892c49c581a3ac54ca48230b8a3e8d52cef328776f87ca4f1aa651c19ee6554e3bc7d1c44e698f9daa9a17d6ea795ead9ee9a4e4795da779ef3c4eeb3c1c59f4d1e93c3a55ff712a1de90453b92715fbbaee386155a72a27e26ab5a2d368441ad9fa5315590e3c5591e5b8d355c141a3824fafb59eab1d47e34315444db3548612c98aa84a011d38ca4e4e4a99157db5d6d1886447b556558761d69a4c3f0ab579efea3f6b2b0571d0cdf36a15e1eddfbfaf6a15f7b0b5b31da992ba3a1a8d46231044a12794aabe4ff483eaeea24f54323d364c4a8aa9d4892cc5a12a77e0c88a4ea3118ac99e946c6647d64a1c22eb6d9b8a7b941908c2714284aef34cf5dc8e2ef33653ceb28c4412812392c7ed40b9a97298060577f7c07b60e76d998769baaeeb700ff01e281a91482452d7913acfb3342654d7ed309d8b3b4c184b795e77af13bd870dcda277dde8ddb59ee79148249287c3eff624d2f72e7e64459fe9a298ce75dbbbebdd5e2e9ecb36d3fd4183824d9c0da5d96a48f32b83165f70a2ce3ee3911b87d9bdec72cf3e10147d190e4dd144b1567bab918636b0db87ad4ba4087e66a6b86061b32cfb68a3413c5b20e5a1e5ded9ad9769efd7d6b2eeee5dcbb2cc46f4ce3dd3a8956937d432dc63c4d1daa36c949548e006825a9659dc0dea43c85d7b86411f344cbdacaf69a73c3051df1eb8043c466c27e7dd4d33ddb3a311062d16711d531c87439baa51aa510f8737dcbd1ab0dcdb02325b9f5a9665f778e4d6de97bbb5a91aa59a46b9db542eb4a959c371cba1909ce1117978641b7a808b92c06176a2b089e298f0de81af4cd64e940ef41e078410e00d6d3278d1fbd8d75bee3a3777cab2efa60b66a2ce70e33851deb6813eb64d2385b4921dcd9ef49d466f9525adb7eed4022d32053cef74020fe2eddfd6ed7d8fe0d69d4de313f813f8ed21963f7c02b18d981dcc0e3ec3e8f7ed8636fd6dddf67e05718fd2777d6cb97bdfd062afd495e8bb114923913a52e77d218fd49fd733f4ee3b9d2fa47fdf356aff99b87bdb4874b2ef814dddb9ab8936d2a5fdafffbdf187c1cdebbc5028cb361105414a3abde1e85696652f1da4b7fb4e0f7e7be9f6f840cabdbba29344371c611f5bceb230fbbe7df47636d93b78698f0ed35b1f9ba5f7e8bd631f9b8fad1d00848d9cc1143370828f2d5b40ce608a194c71b0061a8eac659444414ae9290ebb6f9556db3d76c39470889146f560b5f5ab187b2aaf44aa28f444d64fbb77dabee3f495ef60b94a47e9874f1b5ec1342cf766da0bb7c74feb28d52a3e59ed9eecbf6b9dc9844f169f729cbe729a130d8eace1d0541fee2152a9448f128552cff3a84769ad59adb56ef68638b2cd40100c5119040f5ef35431df907f1cf81e7d2822d2e9f41da313dea182a3cf36adb7793872d7fd2405e524238128267b52b299c892ac5da17693f1047e74d2cabfbb912ecde923f0e65059b122ec43a5cdaddb56aeca4f9765bb3954f0cabd4bc382e35576e52aa759c12a98e684bdae533e545127c7f88855953c8f69a284e0bb2190fc715c08a4e32cb5f6d64e6d3be9edb449a7a5531c8a9a36f77a8ee34eda28e57ef8fe59ee5e73f6961702c99cd55eefa9c3373e0d73d7b8ca719d394cb9136cd35c49b471b7d72c672d77bb71da6739daf566efbacce4c9effb6e770bea903d72a14dc665dfd7894c9dac36fc914db7131c3de68ee3344dcbce5dd2b37b83c4ddeb6e3df07e3814619bf6ba73b7bb373ecc7157f36c9ac33e7e009196069ab76d17512cdbcff4774578b30dfe7b87b189a216f7681bd2bc61edde64f086417253d228c3dad4186b1c961e47f4deadb2ebd63fd87ff8068edea3f5bebd36959c0fdb1b9fb4f749c3372cb5d76ebbcff2287e05efe11ee06ddf90721ee79d50d268e4f5d6dbd6ed7d1bf5d6bd511c1beb9e7dc320b96d08247b07ad873b7a20f9fb4c77789b280f7cf70f6313e5dd7bf779d47adf4bd2edfb3cba7db4f33c9499eebede28d5b6cdebee9dd2eddaefdeb0946a1dd5a6b6d13e958f2d1f6fc1d0df39cd0b92696d8be93bea7d97dcbd5b9a17cf8536f3f346948eecebedb52e37ca9d62fa10f743fda9fb0e949fbe43e529b7f76e48b377eaf0a7f23d05d7efd486dde3f70bb4debd4b6b101fbc537cea4ecfbdd60e9f72a0fc741a144ca375df431a3dd605c9b5b35564b75b7ac38aed462da5d45afa7978d451da7d1ea51ca59bd5a4773311a5d7d2c7a3ece88f6ed6729f9974fbe928df7142d9918225f8a8a23693bb386b6d7c7d77b96bf6ca0e7ff5745b7fba33fd598cbbaddeb54fedc41dfcc87e23909bd67ea6439b69efccc2bba1c69dba7fb728f7f41a84e68463a3fcbbddcd91627f7a6bd7c65d8dcbc20c64edf494d39c3c1a149c929e6ac319b50182591a24bf344fa8d0dcd5b0de369bfd13b5bd5eee9e69db7ec8b09da82d7236d43b098d28c64a1ae91193747bf60377efd96bd753876f70d8c391defb7743eef16ddf1eaeb7eaf71f3ed4537cb2a7f7bedd933df72db3f806777a79db876da8e5e11ea25bdca3f4ed3393bb9496b651a4a40a8259b6d18df39e7d0343d9768fc361dd6a287ba8de1f39d4358cc966fa0478b8628ab9eef7ae7613b5a139f49885425b88f36e2fc7891eefdd74b14e79f8a10dcd75bbc6dd1ee063ce32108719c8e049f76e77431eb9b321eea6100e79944e4a38fc91edbf874c3814dd8b273547ebb32c3bf8ed8a0ede1ba21fd9e3eed9789b6d34ecb7cbfdb8c16d59e761198e1385c30cd02c7328c3a1cf4c798ae3478e8f41fcb0a4f949f1d988c9d7f7e9d58ae5f0d73729babeebf2baaeeb3c7c5dc44d527a123d985db71dd2932befdde34a7ea661bccbdb6818ee339d92ef6e4da77870d8466c628a4159ca08b4e19015b6626ca27866628c266dd22ba48dd094c5b044aed6afc6a185758e8480340c860384a988cde9db68982cd8503ee1c08ee1207285fd66c523ca707986308f4ecd03e9d4bc69e60cb1c252175fb0615cd2d6112bc051a2042272e844d949a58ff53a64be504bbb8f9462be08315fb29989f326a6200b64976098b526535c92b5deb488fd0822c2480f84423f3a4513c0c5a01f5186cbf4fa44a04e94b1995e2a1165ae402f8970090399864c1fca3164fa5076215329852ca74842a65c963ac814479fa892a9f5b09deb126fd7bc3f36943a2af43b3586c416fafb043b846297f499424829268afee8a09a3cc844a9a53a211d580b63132575e4a9951b1882944c21043948304308da27b70fd044054d54c7051b4aa06eaeaf4929e62402a353856c222ccd3e5186abc2a2204e27664e9461c9fdd93d6530719d3913d55fc9819539081334dcb507d98e8368b72692b9c444293175e6763bae260f620b1aacfcb952d83851f28a896a30581994fb73620924a1882d7d202020a03ec6e44661dbe78a4109a494b25b36edee96e10e748724ace1880db15c84d6311912369446480dc417cb23c8f4024654c7c49656c2368e4e755eb9810d634c0d13638d189638606b20a22e53080af632c1cae7d0215afc0e98e4013be325cfcf2000888619000160dca0ba005a1ee3383cf5500eb18e43df7ed8f8882d3387088a066c3873a65c71df68e623ca649f8fc9e1f34088ac8cb758394bca63343d4610dfc5637f8fb1616450a772b827ed3a3cae64dc93864f3964dce53a72b80e39dc25870bb1e1321e5777795c692ff029870e77b90e1deee2722101b80e38764ac33a5caec375c0425077390521b3f65006659f993208c705c6f8c696f95f20266a3e07193776aa050e51319d9a2c388c91658c1cca1d142a0587bf099770682d883fdce1cc0396c31b96475c1061b55010190efb584e177ca8b0c72bb30a071c7050a954383cae04704f9dbaa7c6a71ca994000420800bb1e1a947ec12464b4b0b0cd461a00ee34202f096c7d50df7249fc3e32ac63d497cca11e332aee386e7808500e0375c0616c2040d007ec385d8f0183711a0c88c1d260a35800be3dae8d4fc0d57755b6e8c8bc3cd38dcb852ddb88a71e3ea861b572d37ae60dcb8ba6ecc03a83153b7621bc6c400f4c53200ae0dd7c5ec7a9eb042cf135638810f0c0cc330152a8cb1d1c34f8c12248001a358ec819d748a9e3040a6101335491e2801b69a31cadcc0fb94353632c6943f0d037e8a5aca020cf96a7b289bc8f31207d200db470fe5111964c5555d49ae069781c4969969c17af77bbd46c05bd7c8106c057ebb427440b5fa3ec4aec003a1848a9f6c3373c5272c6f39c87ca9a71cdbed4fa1930e4ff4791e0d730a611ddbedb7db875227f450e684b045c2d67b8b74f7547fb3e2eea9e209d07057756abec34150d8e3805cc38a09eb71b53d443d5b6df71e9aac0d441932e4c981f842447cc9260b268e9c6123a708220c378fc8b3a661e28a1447b2c995a27bade65db9d3a91bc496f9eb4a2457267165114964a2e63c42c3b29133e4084a105b72e8ca5c8361d95a12a2c2528cc3c6445d2558f9309b1a0c8a80c4bbf6ffdc4a7c7a1082247890a80286945236866158cba6dd2d553ba07aa28ffccf44c5989999989923e4e4d0443125f24420030e7549b17a58d775cd5f3c72c7eb560f375986cfd20b368c3e34354772297354a2842a72d330810d314a4513ba20a2020c83a80917801f20428250980daaa0e9a805d49452411c74c5c1c1c189a886b1d13895cab91a89c086126789d9b4e79c162a478e20c6e80b4b1c598279491c216cf8bf982d67cf77b71665a62414d8a9c4199ee059459410d8b9842a46a0b3924300421474565189108ec0596975a3777ae0034728b2babaf0269f6e5839cc40c630264a7e07497a70566d25923f471ffa5b3fc1d573f55cb5d65a6bad97cfce5cd26dcd25b5a7f6486176b7a58a735e2eb55eb556975a65b89c40c7d2c9eda3840db71c755a4746ebb44ef5913b5902c9242a974deec82676e4ce04ca5d8449c4c2049a4016106850ae3ad3886d64a241330434880659249e39ada83ca8a1cd933ba886a7791ed03ccd9306ec48c67ea8851db17ab6755380381ab3bbad6e7aeb5eef3bdb6a2b05a84522c8735a279d2b03d9c2575b97b6e0a433516dd5478aa38c98b47a685c92650e8fb8e4013c2a0f2be877af29b6cc6b328a177cc0a7872592f8acb4ee001337f05969549ec00849f05969b5e7a70547569ae5042c663064a55d5bcf112772561ab60149c1b3d2b0adde134d0d129940e4089e55454d948cd911988004243b44622044d5348a61d8abc51e0a65c65e6f45f7fb41cb189edb7ca83ececc8a6d990b43f7369bd1639ac5a4155c8dcad19076648a17ddce46928c5d912790b442c6980f61184603bbee0eac0402ca92abd41a4111180cc13ccc091802e8ad6953656b94a996dd588f6d974e1486d5502814ba7693af4b2e4e1476b2b01d65d942a0efeef3406fccd7e79b9614b8ac895dd69453f6b02c7cbaf1d97362cbb22c8c7aa19a2fd3b22ccb0aaf8ba27f81cd2dcfda018cca4a9bd2534a69a5b23695b9be6fadb5ce1ad82badb4d25a2b0cb6a2d9a78956276dd95d67d3ee39273eddb8c2be2c8cfe4d9b36a530daaa1f9bca6682165f8419a5216d02413fe9a7920833833a456fd109058c760eae4b42b752a0dc9f411d6d6d7a051b5e38b92b9389eaba24b6583d9dea3fd7ead3934319106c587d8e4c597daa143f5950cb8699ab89335f84c064bd62a6ba02a9c0ca26dd6448ee954ca9414d727f0275aa59a2b0a16c02947b7234b02c9bcc972c70e68bfcb5a467db208727d8303619126402992ff4dd6f988a598093a392152891c3d81395a8e08a091357f3a1b5d1b9c646c300d17303096c189bf467a6cc01d23038ab6e15489181f851d3ef1f551d42a8923a3c35353535353535353a74e8d0515353535353a343870e1d3a746056a5d9d1a91361d69af00e150cc334b15335db6aad12c73376fb7d1688873db1a7fba14caa4e81a3930eb2a87ce5a39b43e58461262ae4a715dee4ec212b6485db0f1277214da35aadb5fe264b59bf6119f2862ed946c3ad6eb20cccd95e10dd90268baec53967ca34cddb9626839fe91f7b4513a5eb94bf5e1a581819c60c7dc0f0ace63616154a555cb0bc45fccc2469dcb56ea41c05ff403ab7e3bb218cfc7ddff77ddc51fe5d7b7139eb9e4e180573971edf1e46b724fadda2f42b2cd7acedbb28f8a44bce87ef28f8548f727bd23dd57b2761584a4a4acaa9621a1bfe22936e714893519e82439a9c72edc5a9742747a3f4931394d3afd3c9c9bbaee34eb89393128e13757f724d076fc82393aec9cd0613a613755fdcb89ae97b4f9484618c4e718fd12deeb18272c38a7dc0f856e88a0b96d7d3b75061c1a1cc2a57b1d7ac8ab5a00f16ab60dc8df644a09d74eb0257fd66e572c36962fc86cbdf80c3553808ea383c48001ee3372b19f7242fe337ab1c6e8e1bae3acd0d575d5ea5ba0c1c0400573d880dbfe13738a860c4b8a1c58a2013c523771afb25777cb082dc30bfcafb53672a315fb61e1934711ae6f44e61d189325c6619819d79f495539ffebd61b0563daade84ca4c54131657465ae982275dd19da09b8e8e4e5ca5c4d549461d2327df3c651fddf4947bcab08ed14d271d2b4ff9ca532eef094bee58197c7a2ec98e53ee12ecfc699fb9a46156c209c40903e28a470d5e7918814ee4e36af430fed8187de561ecc98d250f228c5e4294913bb12507730711e6e43d97903170d00521c288c087272b57f248cec8c953ae3c5d693252fae476581c9c21fd8e28ebbf574c599749b4f46918d23b943ff2d3a7979033641216b7b85e4c5967b12e77a24c8bd8622d911b473c7ba6ce9da73b713ad54fb9132574d3a87f72a576a513dd133b05fad0c82e87b49cd149e4feaa74e38a74e36a74e30abc713564a56558eec49639244485c5b0c4012277e2e6dd78d343a2c51761c5e9e6e9d69945bc775c983af3257a98c5a2a9105b0a39c345c628437c41437ce9236223117b07b17d109f105f342a2219e48cedfd1e4394e1de2d3a0bd974c58b1332cb3b0849e40c1a19830511a6a65344fa501841471379896cc402b1a53fd7106180c89cb9634413816147c4549f67e6d24397f4eb82b7aee8d45ef2ecec441996fce5fe7c22a50925a223cad01314f9294293d026624b9feea89cbb31b69cde82e5ca23220c7d424c519f4e5135649ac54579764dff9158fcfc5891a3613ab9d65ba649148c541a5deb596777727a826e42a49b944824d98488dc44a0373a6dc22b92441699454091682659913c512672356acfd979a73b0d439774aa0a3983662163ace02574872ed9c9134f21f7357be71222aaffdd898488f291319634cc8c22a65a362137cd625291db9b40b1a53f9f0841c1ca1e9eef4b1a66a3594cda853c0aa91ae47da88fcc51395d79651228a66b335140666a1ee7e7e4fa285d1ca4db0316728604628cd9303444be9025164d64938804223662cb3c7861c8ef456c51cdd4fc8c99491a8bd8d2e76e8f21b6f4b7db6490319e1051fdec3615b1a910532e72464bf1e284dcef20c4543f0ba62b4c468022a67710db07b19188a8be75fb8888eaeb6822d3c8199d8405d146ce6822b7409f202ff1851cce1d34c4598688eab7b8f3e72ec9730d3175c41772bf81763ad56f2372bf89c8fd9d9db91345c5595983145738d13384123d4284a1064e044d9c23e008e28c789f997693b10a9ad812438018bb042b63da0c7194fbbac194410b42ad71b307c7449d64287778b7a7e9fe5dfef3b0e9662531695d550c8aa14924cf1c2c3bc2863268c917ecc4456822163f57f830a9a24891bec4b00c8aab89716856c8162a08c68499420499a4496654c3c8d5270e0cbc3083b4287a767777239948827690c8254c41f2874221c2483004fd04fdfc502c836415f45dfb72466155da54042919423e620a9f385f26206f83e509d8d82c7d105bfa920731c684913b9bcd0f28acf56a447bc368414131413287f1c746187d76421782854e8f248b7c801c95d820284b4e869e5d8876ec4242cf4e7368c7ae23f4ec9403bb761dd835eda1ec210d9be46dc8277cc427b2fc4c1256eed022cb5f3631280605d13c658eb56a1017689d97143a4a7c8ee8d66182c57efdc77cc18c881a4684636a9a0830b84294a1292da74882fc81d40167a36144efc7663981053fba10d149affff9a9a9694084912d883f3a37b042981042bae8f5a7799ad1c1d3902e7ae44e13e718611007618206bce83a48d8060e0262535c31a1cdcc17d90f0390e56d8833a40a628c3e6647a4cbbf8832f4f2a4fec804da9823d8981d6acc6067cd34733eb4c8da8fb78ef4a4adb15d5e9e6e5ce217b1e593f235629638a4f9b352fbd4dedd6f363314ea50167746091595914e8e99b19161a973d56031ac424dd4d502454d1d6f762fc8c15982176ee0830023da6d4c549f6a60c3c86363c665c26857990608f20307a771e41ef33e54f9d2b02f582c54354723b47d08eeb153563643eb4395352c6b59166ca4481c59e28989ead9d34f744ff360938707db393251488e44196ed607f1aa77337faad66bc534df411ce47b909b5588cad67462727227b6f4e3ec79e4889c3187e496526b91687411e95e0983251c4464799774633ad5a3eb7913d38c46d6da8b623ef06a7434127d640a32ba27bf5b9ff634e02df80f07b1074728d14d28d3e88ab0195baae4ce13d4fd79c57ce18932a1dcda73b6b68d63aa8285827c820aa89f9bb9e9c3710f4598c9d3a966429e3b1665b673aaccf950a5f05899b54f80f61139033322cf6f9916ac7422893cbf5db3b6d8309e05bfef8237766f573e617907af63748b858c22f81dbc8eef2016c2040de9e085c44e7d3ac07fffb01012963dab4943ca9f3cb17c42c3fa137d9f083cf7378c45babd90d2c15ba4dbd3906e71e920b60d630fdea29cc803ef8db090efa35b17f54b570eb10dde3b0de85d748969be8fb010fb9177d169bc8b70ec14f8efa11c228b8097c6298777f034de413c318dfd085f744ff3403ad51360405c7d380810f866f5b8b28f40a25be3ddcad8192957ce876885acb5d44f9e7a2ae4fe09a70f0ff3dcb7abcd356459a3bb7c8dce872a6fdbb34b6dd2d0b013b7cb5f903b3b4d828096fcf8c81596f1e4892d54d81096488e4c54b73c92fb579ddb4ce9014e963b71623151f44d66d0bc42c76727f3c1ce8e8f4f94b93f55e820622193cc9c91800a9c30740089945276cba6ddddd285ba58392af14952440335c6ce52e4f0b109108ddd48f639e79c73ce89a53c92e7e90d6dae4c7ffdba82f0ba2f735e71e412ec2573a80ce51902a28930f597e71ab2c441c835e41313d8d02501d488f6992977e6cbd430dd7246392a392f68864fb28fd91158ab4a9e248c01a358b52eed9a9846bb8957d42bb6a0601cb1e13699ac0d7d62d544c584aaec32511d635355a1abc246faaa186ddb3ab3b6b7296742b034dfd0acd6758955666aab1709565e073c2d833e7264a29640f54347e20c2901349b0911466aa18166048a2d68b0611fc97d7aa49768249d2476f7916f8fab1cddb7ebe8be5d88761d9c90ed9926638c38fc68ecec9eb28796cb30131ba23cd61128a04082fe749289a2bd83a491ec20a1d612b1859a7e620b7d88084b7f58320dbd4c2189f4ed2c456ca1a71963622d1c62cd23c40ca080a20a3aa0a2044248a1831c244890f8f4b060618dd0914148924c89058e13990faccca14492f9c0ce1c4a2448649034431259be590645999bfb210f6820f73128260a934155d8cbe201425225164d8276ac8462a2ba39196465108c9e257a7a7a7a321250613be7f280165f348f5944eacc588247a684953953c26648d896417c8999a8b89a1151fdda84c7090b6c189b0c6131c1ac41c87a6b96481aeb03e9543f74b1192d83886aab890ad5c407045fa062b0d288c61796437070e490a6e8a8740d97b4450b158d0000000083140000180c0a874342b170409ce7e2201f14000d8ba64a7e4c18c9a32087510819440c21860000000019001860b48d00628607bdae1afb40ffb997e327352707c5c08a31b0c6489061496de9c085263ce1ee420974353c2c846dddaa2970138d3b18366d0fbc58a44e6f2755c2a99ec67717316a3968f5c2933e9d4a07a9509afff7b4d8c0072a1b06556ee68ca99b16357f77514715f4bfcec3981594865e7c74ef684e03124c027f2215aada7ad1c71c1d48158e77b03cd4fc2c5f47fca94f3a3b503a6f068dc3a14d770f61384a75e19e8350a5c96202734b3c1e23cd2563cc4858b4615c368ac40e99074db6073aff19db91e526668a4a7072c223bd6307be64872dc40879a83d1ef899ce4bfb6b618c07a9be7434516b19268ca6a26f768c7541a9fac9b1395b16992975874c8297f399d93b2bc8546075c5dbb88b3094877b48c6ce5ebea85d175ac86f32b60086657cb4dcd95ba2c0381608813623b9345baa6bd30eb626d18c83cbb42ec939fb0fc90d535306a2a58205c5c511a1a5091ca9ab75e852704458f038fae6d9bf35f610fee3ae4ea846008f79f9c09d96d92200c10fc09486385854f58036b3fb8e650b2e1ed5cad70fd2614b82dbc82c225195a5c037425d75298ec532e34b3dac180fb07c17d37d9907ced04282a239fb43ab9e2727a1fd3026154f51b048ac9ef95c035f76782d4c597402d3a9d849ae540749b0f83a42a8d6d90c57e6d61464600f2a1f95574651e19dcef569e2995595c1efee95463d23adb4e1dc57d1a2de6e3917041a4677841e0d66b28ba49bc5175b51c8543c4b9f85fe166ed878dea8ab12655e8557bcb1afac9ea702558d69e64262721add1b9c861405efbf33ff7f7cd13d4cfeb2c795ac646914ad58a8ccfb8d15c581c7a7d40f073cfec2318cba85327ba13f730c068da5b202a9aaedfd3268591242487227c417d30b10c7591f0ac52c27b329bf3c217d124c148ae91b67433e3bc51c1ed8744d2289ab68817f53249a9e0e9ac40a71fd9266f51df2eee8a13697d6c8a226179a17e5640b9319b345329d930945838988a6d2b1c567ec232cec72f6ac0c7b9341589517e5ae624c635207b53de01dee30683cff6824f9fd8cb44cc91d345bed990a0c8dc0dd2545aece2162ac058f5990a5906c64d92d397ac8303eb0409117a34282b1c09f12035caa5027c31cfcc875681038f0e955ea9954fa93db312722d52529df8292fbf3ffac215e7c5615f635306ccabe11c97c65045162946e63c9057a3898b4e1b6782efa7c93a4ec95be695438ab73b740398d623f8d223a59820819336974526c021c28877a57bd7797f39353d1fff4350d8e1cae2164946f6acf09304d23b83869f0d0486503b7be90e812aecb82af5ca668363cd0a569900275cfce2ab009d49336b63c6a101e24932b70b82e239e16bfb2795cf7261e54dc7b53e49cced8d0e171a252640fcef3768e04be57755ddf9627e0143dcf5d536e1254271380209a0b18a602e8cf3f9c4d1efe12272acd42c954ed60825dca15a191e53d4a3a7385ba96ff26766a173d0794cc660df0fe26156fc029fab5ccb1262bedae6bde670e071cc74896c7f38fac9d5682547ace9172d764fed0504e834d9629ca27d0201d5c920e42c882c6485eba7d9224c6940e44220959dabb4a007a6eafea42f4b7b83cbf27bfc8705919388248198133531ffadcdcbcd56f9abc1822647196122029a7be49bc44c70f27d12df41546118e97af53939bf11e1cebe8340b1782d65e3b5875633abf152357bd10787073e6740d6ec3974ff5b4e4dc5fbab4a08ad7b963ee6b44f8f9e2fab6e2a120ac1ee66b8079d50d8bbeecea329d7f8f4cb4abcc816d77d9a3a407f0c786f636303394212d41cb90aab2a242cbebac4f6fb8b68f862c64f8995485fb4d4c566c09c6c928cbf6f4f4f775522e4f0671122003f418dfadeb5849d0ce0d775d16b852b500ceea511325f59d408aac02c3eaa75fdcd034ee001821539ffc9d73c79918ed6f981176616bd19494521bdc5834977e4466b16a8493e390eb3dfc251ff5ba78d2f1fed70467b114f50dfeb7969c8561238d03f4af733406d58a33b385cdba9062060e76790c65d4e4a652e92536c0249c3bbdf6cf9bcfbeb8a2317257cf0f0bf72bf651548189d29d586198623adbdb8329db4b4102da44fc92c9101fa8d40734f338817a3873031052d18e4e31cc6ed614822e4ee1fd7330e85259e1f6bbc3a49d534e4ab8b95882641385884e24e4cbf0f57a1551935c6c313910e4d24d957e54cd17522035c54238519f022732cf265b1fdbba166561e8f75912cc26d2389e762fc476b5eba6aaefb2cc6d87fb7742ab16807a8024882462a0b81f5f003e853a8af3760165530ca366954ac30601bb138321b6091c7ab1771b82736818a41113157ac72e446cdc877a21884d9e049dcf0a1c8ec227d75518a4baf78bfe9c60c8a51da32312b2bd00247b101c3a0c83b8677373f1b5cb4c527dce9df333139d690971ba4d263c570d21d7e14e22f70ad95a12d3710215d0c4ee0bcd3f475c2aa0550934d93feafd5052ab294d3885f34e0a33c1aff9f8442fcde8b8288da1144f2dc59cbd148f0ec47199e49684cc99fbf0f9d34cb47e86d0b42124188a2a9608fc1412ea4dfdcaad5a170a62428036542499f762a7368ea7b4ef9929636000e27ab13cde83b4c686b35f60d700d9b92b8c81684a068730b64dc00007587f7651d9316341b6707be0d78ca87c031bc46f60ff0a6a3feb8fb1b15d0a8b3024a0c20cfa818ffd458f5f386dd84e71df6b8561f86bfa9162384394a0fa5191dad7fa402ceb7eaee813d7e708a166012100651a13c761f4fa95355414d5b00e99116730ed2ec688d398b195c8691212905c3604e4b3fc171aa9098f86281bb1f2fcc8b79bbeb33a876a292bd1615ffe92f6875e6bd4e92e30350bdb859a6a6c30ed5ba14932b74540e29e3393735ca1805634b22e24f749396948c614e402f7221eb8341db72904d642b8e90f9d81b4c19e7dc8c6b9044f37755eaf65836cb796b7d5b2f7a57e79e95bbf458694503e43010ecb7e15194e2e5e8abc69d410e9bdeb47da050e3cfebed7bb28d6a0eda9dab852211e3f1c8aa61d4a6b87ecc2c0cc3d96200e086cb06a057355030262593a3aa3aaf06dcc05c091e4115da068d87211e456e48e8670f61537cffda54792aaa078bdb8a58f804948875811c155f0c5c6bf021162b14b78f017ac709d942374e81675084201990bc04711fa700eae9bb4139622beb02511e0368077aeed34718113eebaf255c0cd9e84897a0216f8f0d80439c42ce08b641eb4609550c1a8dc839c583a72b46c259c364135cbf95519ba2e6c07bb1126cdebd02c29e35c413bc09f3d2ab7192bd49dd8322d8c41e4246273c63db828c8c4a871590115d0c47233742654423fc0565dd3f745f59ad2800020eba82f74049a69fbd2ae31f4719b8744594a360c7053e621819262fee971119ecaee6417c5a2e40c984f8ba0511ce55283841a48ffdadde6034f69a0481da5356d607128adf1239e86c8060ae2ff24a230a3cf6869e0c7a1dacf47a5d7b523542d17349c9f5512b4ed8d9273d23684e6c953651c35a4aec9ad9d232fb29ec33f26213e242950131f49b21870cf5d13e943f498db245856e3e20631ef9e438027d07f35b8f216871591b2498410ff4cc5c2a49fd6cf44928ecd20a970d1716e4e060066dbe4465c5475512cac110eaa9ccaee36bcce727f7571b18b702ffcbf630e2d839008d363dbbb8c04113077513cfb21d616b9e8a57975615e217b90194a05f6e20959125dcc43562ac889ef8f15d87f61d35acbce8484a008f1b3addbec08bafcf7c5252c390ea0102a4d8ad9286f1c33b23890c77628a1f1ede59e88e41df705e8c7800435e2a33026f0c481eb8fe318112365407d4361c47c2fbc6afc9ff2a0eab5312528a3a090eb894341c9e9a56c496620f617703bd1dcd92d05b2eafc65caabc42ce362a121fd3c8fbe59c3263abf8dd979c0a25ae772e1bfb55a153566093f4dede7ecceeb347b07d90ffa5c990a1226ef0398666faea318efe3bed2be149e85db476684276718c4247e04f7970af61adecefbf5d971c639af891e5e079eb98e8e3eb27a8d1f540e37fb815a27205661236db8425d2c749e1a7fb1edad2cd9a9ce07ef05633e0be4c8018196f2f738e1f1db99e8a3f21655858e9309016c50007f9f38593bb32b81286d4ee4771a64bbc1b59e259b467a845383acd5d51a285d68e63e56ad0c58c1819459aca1af798c53cf05bf7bbea429fb01759ecf44521394c9f69b1c1edab754c8f752eb80942976c1f2ab15ba9f956d347d036d9fe6b1674dadfdf48c127bb2807d227612c209d8c370eb07c5297abfb93d671c7969004f132f4c01a378483b45fbe74bc9dede740bbc3a04be43c19e2f6baa03f662661e28360803f26592a234abb6c8852f19dbb10db288c75f89ced5494a66da9eb9e44d4bfde85244d64702f1182a9b867d22b0cd8690b37ecc1ea0532650ffcc3a03556e49cb0ebd03d5851b10fa199244231dff624088c4a9f6d8f622b14646a672e4c6fba9ea28bb27e6734922b49398f15d37ec9b6ef7f94916abb4df63e5c802d0ef67289a5d157aab46832c5f281bebba26b1228b94baf9bf8f8240c3088c86c6f089da104c7106f78a3d13aa6918e5811cc74508c82ee0b472d6e55421d64ac22350535c4465ee37cb3d1d062ad3bd5e960ccfd89905b62684f9f063c239536c8f370964f866e7715ad2dde7f03729dfb203a4849d3320dfe406bada3363f2fe0e9de3d9a1928d06932471682d598db0abd0e28bff96ffa41b966c8b162e335c1ffafe241bedbdcaceee3f695c9bfe9381f35cac15b0c38a578a0da2760fbf93f4eabd2d1ed969caa04709f57dc274de1b35120e30cc68825660a31e2a5134f749b2c25fa4273d21a51c7a8aec8987a9780c1a4c69440a37745bf360220bd646fd06a710c3f9be977b793ed9a10a89372cfcbca3175001505b4f2dfdb4dd6c00fdfc623299202b95e1492935e4eef5241c75919cbe1d62ef7d49dcd22beda0da22c26db1a98c3250207254f40e2ca469788abe28e60541c6219357e7cb6058521b352756f68d28c883f70310fd94e01178ca2925848cc952f7b55fe3f5b2e00592b4a3e900032d46d1bbd40262c05a78ba3619e26aed24bc4b681ff97e0515e909e26fbb8270a4c9d97829df39d22f1036834d31a7b06a9a398f6018cca5a04df981a30ebc332ee016527a101bf9f537ac8ef50cb5bdf83d409fb1a96d72608da24b9993687560c33879029266a53b397bd6621856e510280ae19da8dffb1da775a51857979aee9c1b2812f7287873e8fe6b8fb3f95dbb15d233a1f3ed0a818ff671c3a395ffd9f954674800c3af45f2d94b8443dcc1f3104766083b71082aeef22f40e8abab5208af1f79ebcc19fb841b0f3c0ebe5ca636a3edf111e79404ff15cdb62c9cfc5a3d39d76d5f8297a13fc11d8da2e40ddacdb6f4ec0b52bcf098d0b544405b1b243131c23c0d48e9fc7e7c5febaa2a2875a8e5c421045d6dadf5b904944468f5a0fa93a71b5c41dad3fe19fda92723bb4dbd86e4f7f3429e66fb326470daa4d047c3eb23c1abdeb3bf91a16b67e0fe3ec023f76fc99c329c2ba05d75812b313250beb0c05a049c04dd74f9222db0bc29c14a2fddf76a60012114f913498285289cf7f96149c1e66bf8ec66201a80ba7b479d478ac6fe18aeaeb96a692bf36547c78ba32e97f59eb52fdcdc7f1cbfcd9677cb896fac05b718cdd3492336468dac9da2705b63d08ebb5cc8a9e52983358621c5c3ab6701d80e7480fb10966b6a3624d1a1bf94f7862477df7abf62af5965f984398216d8f4930e3c6160c0b9c9bbb771c5306be56a5a10b07973207dbb42afdca03c045241077a37151104085067f980f54cc70544b16187d45231a718018fc8131182f3c429908e426e7b8ead2439d1d4761b4d516dc89a71b6cee25ca89b3083944b19268bb4b51a2c3d49c020d9b1d1592297553a38cca8644e2231983fc526bd7f9a15cb36888f5f08a6a8e21df4c959b1f6b6784d8dbf7479821c47c27917dd804b79cfc96986ec1df61b8bd04d7637ab6b39469a773acce47ac4d34f072c54466c978692a1e3c85a7975f90fbba33cc38b257638f1069cca3b47ca15406fba6af7e8ed127de7f3074331f232fdb18f12a86e29e7f86ed692c710c6ff74e07ee390268572264eb0df42e504801827821136c2c20b0cd670e9e92b5fb730ecf6c6abe183253916875f1c37c40f035befa1050afda8adb3fc28458aa113810f2922229e229f08c299d4a8a8ce0ce1866d1a0dcfe7bb27f21acf24c43033d295ea8fa097b94c83f3816eb19045e6b1b39ea906d251993d53d55480db661563b1ec6b0cb36d03e55a016cdb89292da34e08e179e2eb28818d95ef5b881cd035c3dc559934b9d8bafe4bde69b865cbd9be2ad4ca7fb234274d95a2b7325618d106e54d8b4ee736132f0e0854727c15be2794b37c0414a54d89e60cda5c7189f213a28025646c555f2640759771a6526538db1c2a41c3f95e6e231ec59e6e0c64a3f9d590bd703af29e7546f8c8a4d680e8bc4a756e0557bd719aa0a885a4583d9b1653f6e01fc9e65b225c12333a3709809e431f8327cca9efb862253c64ca2683773eb78eaacfc1c07bbf07cb0b987f0bd82f2ae3ed7ccd3493b4151d7748fb640b8998478008edc8ea9c746ffa54703f235349a9f040e6866b1989113d064d0bafea15a88625ea7d09c923a8940b74944c73bbbdc9ca18a3ce4ca53102436e24a8bdbcbf7e2b9ebe3a9db201bacfee7a7fc532af8e73a1d7f5917f63b52bf9c36cb5da2c5f4c8d90218b390ad98579f7f661c2afc818015eefd707c9386629e8f4147ceef50e4a4a9de77a574980947bd891146c0f88fb6636c1025c3491ad48395fc1104b4f819124354c26347a5b03230cf0c0eaf54269bfbfbc7cf3ec23480a6a9909c1727db3c0392993c332c9efef8565624840dfcdfef80681c5d803009cd2abc50e0d33a5c120ef1b93ae73756945ecc203967f25598a90c845c2049f5fb8da3bb952187946c820faaa7bdd84f24bcf7d6b3cb630d2302aaf334651025875b762363f3f0d896c0fa43bca885c1725411b32619c47927d7cbecd6e16e4bc216bb0c6e8fd85fcbd9786abfa4fad9f0803ec11dada9a971a319c17e5f4266ac96251ee9a30beb28ce8d6cdfbf7c25596a48ed12112499580306b3425989eb52ac3439b96916467af337b6d6831de854af6e81884c80e187b9975ae6ad9cb9779fb310ffe17c9b2efdca7a835cc3532883e36c444b9909910108a65e033abbb7b050431f5ce27049108b97f4a3d8b5efe5e2fdaaf340429b8e4c548468f1bb312b12832c1b8dae39db1a438b51bb4ef492594664aee7e694c278b8a7b77de51fabd9fd938265dd22289ad49c5d340939f9e950a7e0d14473c7448eb6bc8ad2131223cdce37689592259ed4e6dd0e32e8a6344f88928ff66a1f5136c9c4b980693be0de0af7fa5cb0919523d55078a17eb8efe8f6b5b1965d35f5ef237eb8e46e2336cd437c57c892393259f241705b7bee0dca7b7a80cd073ae8aaea5d8a6dc89dde5109be94a2ed11b35b4d8cda6f8d61c055492e92517aaaec534ed527c0fefb482c8a2288de0330d6ea5094ad2838aede9c554859fa0c22623d18fd120166e49ecf970e63a1357ef70a7c830a8ca64cba4009d94639b29e6c95e3925f522bcac6b91b4d5ca75ed383f4dfb5063cb3bef9ca551454c044d29f618100a7ec1a78ab22582ee6472829230fbfde79cd54fbe284d893b5e5e2742b60f43b91528f91a1da137d64a4a9585be30b30e8f77eb1be799d8097a8990c6ec04c9d6f7f1f99e8678cc4f21a26f519aa3c3a16091fb9470f882a95957ef828c85c6415925cdb80b4b08b706e25dfacac1748d2cf3d77f96db445be5aacfd4ca5e755606e2601f042c45787794452f91d7a91bb4f4c5e42861d542b75ec6a10017436a247dcaaffaf751cc0389bbe19a40991c3c33ae166f0617d0ee1a013c49d5c4159f1f068f1456acbf894413f8330b027bc5845d93c84a5666e2943cd39b0f4dca5e87e38cbc53aa5e904d6ef70bb21f0b6b2b3244161b990d808a66826d04eb60f50da8d071d7f47e4a5c3fd2d9f7b4e1e0d8c0bf8a96dd7bf4b0d6c10ec1fd0aa18f524d97939b2749e4be3edd4a603afbd8be4312467102d1c5ef0f2107d514bfe681f5d5b64702bf0d4aa00643d1e13b30512ab8e61400949639ce12063e6dd402666e3ec437a24aae3e864835d4fc6fb38542625f60d5ab26bda6d1806e4b70f85b872819906c3a43f5a23c084962958adfdc1eb9a84ac70d4ad690306ac0c33ca56a76d1bad5bae88feec72256ce13578550e1a6b895ad964073ea0c2d571aced296e48c92e1fb358af3f810656a0da77c47a681eabe1c36069b4c7b0299b0faef33ff828eb1761f7f75e2a9cfe921d882ee73d262050d383335e924e0588ec6265f1b380b7b3957ef0c9ba0af2a51729a0d16484c9263d7c2a8e960707416ace6a1f31450c8263c3531beb2ceade9f05737180cc2723685368ae1302cd054111ad9e82bfb0ac0054c1946e81c720c8f83345d749d29562debdc520d595dff094aecaa3b71307017e3665c50f5044747a4116feeb6af777ac391d60735d04739d6b6ffe42fe970f01aedf0d308d965cd4bcae1083d6b1fe7428e8fe6e6003702571e299da69044f30f6547cc7565be556c517e9680ad87fbd339b48bdd93afa66873ca2f0e3355801d64d7659a050b7704fe37acbb43a237bafa8f573facad95cd93aeb74e850ef383f866db75ea8672014e23d2a1f217e984d2e8c1ccf85dfcd9837ad3143d3931867fd56d91f118d5888c04267a79cc408890d8739bafd490bc3021d5738497ebb59952fb28d18627692b51125a36858dd7f121ba7b8e2533fc70e9959c0188057b24c853c5597cbc484fcc741d16d30d35a69abf55471ec44cef6a7c28e04134105488fa66a503d20253310828d89aedd00137d1c24a6b311603104696dfce1ab0d69729d676acc8613b8c2e718e601debcec66092ee4727784e94355b6701d42de6e0605d90a983c6635a74dd9027bc5f57b969863efc1f6328fbbb1c8f2f1237382bdf13c01b1a68729fddb928b73a23e579b9d60d9f6f6a13348218f7bd20819e9a9293ff7c2489e4a69f98f77b12eea61bb57df466960334794f41589fc96261f28e7cb3c807808f18adf09c4fd3e6dde7500590712400b0d3cdf905a24b1c5bcf9a63134aeb1827d71debd7cc6dab84187c7e3c379847de41a796567144b00893d94b39df68efb733746b0f8028fa83640f158ed8b40bda609cb7f53436cd55f9499a6daf7662cdcad645e721b0813e3f4bdcb57fbeee427ae10ad2e9ac1e852588cc261603e8b984f5e4e94f3e97f9d8b4f6bb44d2b0ff7e9f93468a8612a24f0da13b94874f1a0096eb23763961a99116ce80cd3cd1ffcefc8ca8b33100cdca2f4b0091a4c05800a4a60914debae28d5707451154a325447d4cdfd6eebb9488225ec69cdc962f93b7e1f952ef5c6ae8f8326df8e362d6c1ea2efffd7579681734c23b637824883943b588a757eef5de1181081c07495c7c3ac01092c0baf4d648a54adf7ae347ff9c6359c213b49a81a795f64a14400b5a8fbdca5333b80122195d96709f8c9e3042c2063c8587e3ce9fcd1c3ad0527144b2d99c95cb1966b8c2648c9c11c1a30ad7c5bc46dd168aca9d4527466b2862991613f10fc96b8b225b8bf5a0c941e0a7a47ac3b19fa0f02b888ae93c6afb0729b52c1a3bb038a8daa25b73695d8ca4a960331a65267c0c13ccfa0f234134ae8696bc7846e37c744859718411a7658fecebf6c371d1ba114dc6d7e19e92e2bc772bbcf076fefa78ed5bf916c7431490e0c49801d2eeacf3d8e9f6bbbd2673c7836c4db574eaa25fa0626b82085ebeb8721e98dada40716b49bc47c77ceb46a40c6ed8e575e75c3f96c3fc186e328050d687e57fea9586bdefb1f29b32fba775fd5f7b2bff3f5f109d243b5f45516ea67de051c45719003d14b7940c4f5ae016faeaa00e7d9cf900309370f48f76973a6d41817cee190c4377c18e37639673936e865ca289b498a64f1457e8ad064151e87ddbea0268786fb15624ff1b5027fcedb9a1c7919856653a2fcd76f5286965c6b5c284691e94edbc98fd19cb81d92b1f11f9202464084cd3a645814e0d0568396e02ca72e64709c0fe891678b2a280d78ec435b5e65cf80faf27b67b31ac960098bc9f1539f5ddd76829adc8c84f529230d97a601ff8831dadf23a927826b169b4fa450678ae6876a81b05168381c21ead4a65a8475b657e12fed4eb040ce8e4358621e61cbfd79762478f948c4c98d90867d244b10dd3dd917c844f111f683a39922a2ed0c5665b1f40c17c21c4f5e34d4ec1202892fd68cdc390336fc7635f067121eeff5894d696bb22615b9ba04b08aaae208e70056b5cfb3c7f037176951f0b42719a1871ae12635ec3faa2740cdf1022a6c7597d0d09f243a19b2320c4e4d94d6e1bde4af0e310ec4796b178af415b80ba4780f045db65a3b8484f65556d88be28624466a675d6ed55844afc335a9b6a35c14d5218257b5bdb2bb28f481e5055307a4792da78ebfa5e5bb1b8aa77c55aeb27c515ce57739dd690ed3b77348150467808aeb64dc2252d8a8cd83222b599a173363ae9f40c1a48ec84e93c0009f2acad20fbf9295d03cc597e28ccb27022f861b8e0d895b28d597ead89ad120a269cfcf71567f984c1e29071bd6e4a46f00bf793a16770f899f2c5080287495df92945972b825897c96237b2d42beffe64621e9068ea3d83d6b75930d57d40ea0fc88dd22e5d0571ad8c181ebc05d0ffd8c7aaea29eadd323c57b405ca2c5045ff53aa3b12870b42ad5af5c69376ed4c128213ae66dbd9ec3d4444fad85a7075513bd444e0f8a7250dc0a3741f2b4af687ca3251e9acea3a5687e4748f00a06e4e490e088e40ce20b732a3e7ebeafec9a6711db1fcec9333660171aab313aabd25696dbdc6443e820a5f1ae43a3a9f411b321e0ce47ed072aed688ba36cc6052fc231427974a93e83d91d25ae8d9322abfbec95a875df97fcf56bc679ac7f062584d3f244d6e28bfaaecdd78c8674e88b55c2c97730906c3ed27d1cb97a1566b9f0f00ebdaec9019df914719de311e1a98010012b04db445539417487928dda744d5a72daa1986921f625d0282e94fb8e671d8bcb76380a8d475df23d3d60e7bc83e2361d860be83427592e15864c454eafee81397d5a601ec49a5fb5e79ba18722bdfd556f7978c0afc7bd15d0b01b2c0bea72af2383dafdb9f2729b2d976b71f28e8ba86b8c6e0bac7febf26b6e2550aa2810f2efb39781981ce990dcae355caef5f80f62824cf324f901c8011b404c708997a1ae19864e3f11e050959ec6b15aca471b17fd62a46ea7625f4e1b01cbe02b3a511a185960a715306f3b6658e3fb2fec74a1da54ae2a8132977bcf40759617e3094457ad059f36a2446e1f4745ca015cec3ad6f1af4c7c899d258af398b07c484b9040e249e0ec07d0b7cc1a4a405824a1e440cec3814da7af763aa0c42854161e3979b5d74de5a4449886ff8c36e22859072351901993ca87422fe7ffe4193164b185346dd82b89a2f7ccf60237c3bc52241cf475fa2c073fd639869f07a89406f75bf97f1d6a2726f1f6e065e382f700c4b13977b02e26542bf9608668310175ed9f69ef3004ab41a3994319a9fceb397b3eded87c3942df923a102e913e92d9ade92d6e39c7a95b3de92eb6192d5d3e2a9e81df30a9b807a51a4ee4e89afef2438bd146341b5b0c21b863b821b0a6ef4c36d104ea08f9d294e93059400bc9e9fa5387ec31f9f1b81a21e331fa0b96054e9c554f867dc40223af5cba662018930334467196fa3ff599e0dab1522c9beacf43387b0cc8b34f033627e81439d3f8fa5ee3729c3f57ff6e937d0952150ef75c728b3e6d67bd9843482cf48f9aa1d004c24977b56aa024f7518ec7d283e83ba8f7e511f9c0f50baf1368d791f805f52e6b8822f98d9bf91bee8832ec104233cc007700b6cd8d8852a9efcc9ff5bc8fef8d4041207a7795af176472fb0da6aa9a85f8502b70b41c2fb70ea286a1424e1c84537da386753c3c2a96666c521defd8be2082768e90f1109e677c4c836819cc88d2ae85cf5431a0872ecba05c421d0c3ab473c0e2c0f7c63a9fc55839a70b0b93e8e51c25432ef1032f8eac30e43e3aeb7df872e8a87feb378637f7104746ba3b77e1a6b3304ce5aa88ba42d8532bf064a911589b8eb8436b988a4bcf4174a2066e714d105a6cc8ece993df3a6d91551d858603c853e88fe1ad59cb64540e0ff0cf53da6258c87e5862b8d8edd13fc1e4713fd16f2aba3bbd356af62574d3c0139fc55559a6066d908551a34bbc576e5cb688cbff6acd00cf49cbe1adb5c4397335d40b0071e247c903eacc0e4a68ca3afb62e4c4a650d775fd5e4a4dab5ee27883ddaab2a1c0b5dd7d1998270e37ffed63f220eb1c6d9915a78c5cd2b3954c3bf0bfae030874e8fa17b5bb59c141046e4c724c2e20daef4c82e1306484923990bf7185a4bb8c2ec5595accc2e99605b865ba8dd15e0891b57da8264a71ab3fc267e1a32d2054d1817993d6b596656c65eb635a8cd0c2bd255b381dd6ca1d73753f20b59178cd1bda4d6a612fa15fa6f62419f5ca5947a5f666d32d790e8d60cd064373654ad147a47f401cc37d800311dbbd2ae7dcfddd1f2f8d95de384d6efdefc55e3dfff87a111195be01a1b59166d8016ac40695e8b50e30e34f1ab02338901ae5f101f011bea97f90386dffbef87a6de33b64b6a6db42cdb134d1505cea1aba117bff7927b6d32c4d5720c8182f699c1d3cd073a68e6ceeac122c96d1eff180ece1303b0ed8c254501da78a1c2f1abebf8e9124fe81bfb08c84469c200b715eef0d7ffc7871ef4ead83eaeb961d9602769c104f6d37284f4a7a5a9cf13596bb34fde37151e8df0f21970a3be913f52fcf9fffed0943e4fc59275d2291a87cbf3e71738b359d5b7230754b68a4ce85709ebcdc98f4e6f52e66a02f01daaf1d512a416a375982d138696206c89f31568c8fad663078d804bd53f657de6c7287effff7de84aa063fbb8e646cb808da45d12384e6b84d0adef87febcf70c9891195d08d4e6bf58d1a21ae983a01ff8a0c4b1a59970aa892722f4976139dd51304fd15b291e05178d4a63ac3655845f23bcce9e1ed9eec8026ec74da1fc3cc12fdf59df342160e1829fe90286226758fdf284e4d6e286b1201e2161c1a7534bfee7885062c1960d390de077d0ac3d5895d8b43af33c4287b34e5fa7841ba73722972d566db4d9fd28276ae28c3bef3236fcb4c6c7466057fcbb73ab9b2ff250df546101e259bef6b91b9bf6fe354b45660c5b05c36bf9e78c7a9c7269cd1ffc7648b285d729240b1c183bfe36c9dd348def7b44bceaff1f1b43ba1e94878722fd1744e24097a2bd67a760ecb8f31b1d506085028f63562b716581ccce300ed36f9b87d78498bce9cc63ad17c58cc6da32bda4a63132ea3cec0de5534c770c4facdccfb73f97245a2700929129aa3e774656b18ce47f44f5ab4a89ca086265493e1f45abdce1cb727cbdfe9dcf90da5484788a7b330c3d97d01c7bb8d4e051b6a87159079599b4f04b15e7f08ca4bc7cb2128d018c2ef5ddf4517ae5f35f05bfee049eff138a9bb8a717997c62ceb77d91cb9b1f517c0a5aee084af9f7e22b586e210597d33a5d392217f97e95cbf30337dba09ff5555631668a87ece94740ed49f475b82647209a400fba51baa9e12efa475ad5a456359be11f2f9e7180a61dc9943d5ca236b5f9b4cbf7fae8be445cb1d189c310ae8275e6b24696d1ba5a9b2c12ea22bb10d80438bc79af361c4066492b3d4ee12ae3b1d03dad55f78803a395e30573ccaa678c54cc6aa92cceb5d90d5a90d4063f7794f3d111c8a413178bbe4bdec5937e668268f2b3dc8fd5065313795b6a25167e3aec9de7c9bd1d1b10b817bc2c34c375fc71f479d3051bf6b562e013f9b0f99c2f67a2278e4cb75a7d2be0c2075fc8b5f33857a54ff423922f4acd89f8ce79e3ba4fdceed7719ab91fc361b647b79dd671175dac08b2e50f0968619bac5659c591e35c8f6d3e9a935b8ab8d5d82e0f57bdf9fef91b9fd6c0ed88a20571c619c9e5eaeb955db03e94eb2b1a435876d38f8f767c4d0366ffe8963e8154ab042fc94f4001a5397150b12e169d154930ca42980c41945b31025369fc40b839c275517cf4268e84104cbb83a5e85478d22181537209e56d0d37fe4af4d162ae371aaf6f63991f8233d77dd2a9d2d66c9391cf7f2af6f972b82237780303ff0acd31be0bd5eb1f37711868d430f000d4a338330d917ddbc8f059abdb0581005e13fb645f1af29088ddb3457d2259898c1fc54c83b94bf2faeec7ccb34f40df3511c88549703c0b361a7b0c3261dadd19f960e093f01abc235983152a9e14ca00e06d9cd19220170d90b8fad7e87b68a6b64611dce2ecf05d54ad871dd4684cb57330e5c0a8b0350e1610fbc593125a338fe97949ab427fb3ae97f33d08e12e4d3b74302481691c06fdd3ef1ea631b3cd7ad9ea1dc2689081e4f609959359d9c5c4ce268ec23f967cb2ef53af6f9d04029f05f7fda2d4a22646cc26cdafe5c0892012fa0a6753407fd671c1a59d73890f6481300c04121e5ab354448bb34d9870c1dc3d69c75abe124010becf4b456b444d0921ce64463ab12e933c971a930ccfa1678c86b9f7ed2eec857214f463b43989008a5c165b0c24cdfeb7e1860990b7135fb8319a7ccfd9a1104ff3ad6b5d1aa3ad51a734781d1e33dfa5cdd0bdbee9b26999a3f776fac94cd39ae19914e0aaa0744eb422e9b98d84ad5fc7b47da148c88926c916331a1d51c616352cd4111ba3f3d77949347b844432210af0d53efeb1ffa78d30b3820a08ec9913c171207c56a86a4e3ff364a4e8774fcb1c30c85fcab65f4ee540469e1e85b4f03a167940cb6099cbcd566e6197dd6f7110bf087ba164479c5fc203fd6c4661836b4dec8808a7597d8ccd43dc086d3c0fc87885546b21b1c58df4b1409267f82b4c196d93924b4bc5885fcd17d97b2b751791fe64fa21c1044c9b905737769917efcaf510a2b257a2ed5d197f536a009bebfd82c5a3c754fa5f365daf2a075875d92c9df63dad3f2c8dd977803a46c7363eb45dffeeedd59bd2fab8dea7a949aec59f3fcdb58610d1ea35957e249b3ffcf39491e4cf50b9fcb75815cfa3a6d7b6eebfc61e8b226b054f1347bff07d3c681fda6709ebb1f54b5a2eaa087c7a48ae7bacdd8a6012b8e866ad8e25b5d271d11a369462582a686938b79162ca33b8581242c40f8e623d274b6b030808daddf556787808c28148457a3f4195d5bdd4c60d8ab9d2add4fb49c1d5ee8630813ddd8d4ccac2bcb5d479db2f8d0756acac1e4b84db705d3fc54d0f78c16d343ea84d8e4f6dbfe64bd6ef6982dc2814e19dea1e8b442784e86bccf37118343ae302e95a26005381d43b4846e5873e1c815c18f456270f1c5ea4fb9601d01bffe4718745561397f3e132f14df213d42bae99ed8b13c4bea4fdbe026ab82c345d19429aaae2c00f78dafa8a9799486c4faf4f487c91b1f4f0de324b9f580989d0631f4f74cf6d63f9dd727a94a94db30029a06770f11be353ff5e71d3635d47592fdfb1bed6d1cb940eebca73c01c0ae17d7b9b803c7f9ed8b1e333aa6deb53a72b804843a31d10fb74375d378843ede6186da44ee83be5e8de78db31e58a1180f0f7957d4e21e9c7e5ef046f6e2bb291205ca674ea22915aa36ce9faf73a856b63e010be1d8e9f5924f6668d2f144c3f3f35614dc808101c0793877b3f53a7f8b96c29d2c7281f45450c27a3b6f62ff30bc51d3667f1aaccd18179dabeff0746117c47247a905a4b564c4bd5d1e5cfd2b9667fe657498026ac77dfc22df02398351d82f4982f7741a6fc9fc790bd3116b210c020d7941f7404a4733e950453dd04a8e9bbe48f3c2eb3ed7def4be2f172fc69eb551431ab0e9b530c4eefa7b5d5e42f7f26c7973f3eee7dd5c65becfe7387d9b2ee3f6fa907d19c2df3ec01401debfecb1d266eec8283ab30401d17d462a667df3e920ffe9af30e2259ed8967a65921988c96850e4786da3f083449086d50c02b9593441bb72ba7c1b66455dfeecaa1c79f021e3ec84c1b580d928a2e3901fcc05c2f43eca28fbc12c3c8a33a0ab94ea3e53f52e270c024494b9010c2fc945c5e11b3641c7112420be99459fdc2cc9fdb7336bd5e13882d6c2954819a04a05861710c4eef55992a978acbef0e040a0408c836dbdbe4061a366c36fc6068e8bfd9c7ec889af00e72a81109b0482ccf257b660ee7b5d20f85fa8abc3333ad29e1a70f8d2221f6989fed0a4951e3d663374e388ce0dff6fe171507e53cf8a8fd3c85db761ed251fb599d7d7515a657a0e2400f20497fe7f51fbd8ff9b1b8c67c145738ca58c57b2cf38506a243370a3c71fa9d5637a337855a8b78cf610613c94c419447526ffe84d9226c102d2f29daba57a780f1831d10264baac003bf984b3f47f18e37c37cd455781d7b3a6de687af9dcf18ba8086f1228f9c49dd73818793ff97715ba3dc67693fde399a8c6f0ba498ba420cf2420135214cfdd89011f710fdd80af0f288f4061b62dd24175967fc9045203f01e7ef298092ee97d64b8db07fbc335acde38ea0e201f83185a3efa0d87aece6dc907365070ee5dc5e0e7c5034e9fea5a804ef7eece687d6f088e7adee2275b2b888bcf0d510b3ca98d550fcfb7811306d8c9bacdbe6109c66355965bcf819a678996009a8e8a10b41176a1e368bbef54ff0a128b2e8c2d4a52b31243704101d71beac519ac3f10aead0e9ec6a5e4550fad8c54151f35e5e4b5bba53fcb20abc57c413a2607db266d6b5be8511dd1ee54bf7c83313acfa2c606305f0c701fafd50b58188ffbe11c71f50875c5e9201f520aa7f0b6a9dada402fbf6dc3548b15317fed91cbea69c8fa3a1f426e206c5bbb3f7506002824bbc2b834f28bbbc6689fedb14d6e14ecafa532d10b8f328a1cecb28402affe93b5664f5302a76bd085d124d656b6ccab8b85d1ba21c287d68a1284777de096be4ca8f89e98e4ed65404f5293f966d179300708f97c7c2ab961d5e1202afb389445add2318ae66b554b8d91332a782e4e49e6a473fb79e8466b34e16d8f3e4864a31e53b98840a65cb50c01c8030c7952966618d8a530cfbeb29764056f2c168efc00774512338169e582347617ba91bebdf60ac71b8371066e1b3f5573d3c5df5641f25b57fcd4b572f8a5a9c9b5fcc57ba58778653173d5fdf71aa87e8a8e7e8a4baa0002246c176efbc41d425ba12db094b8e64c706865931268c3330fad6effc93ae9e662d2b99ce5b51c1fa265005f25f15346528ba902fd30a0e3066b24608d677a850a14373b904e1c38412ac7fe332266b245e166301a26db75baff4a675aacfea15b9c64cb9add13b2ceb5b588cb3e7732a8546d53321002a384013319da24ae808d02b761033a6ee1fc57d430c54b4a0f8689c344e9ee9e5a383a832c54ae5e65dab3a16fc56f200970aef5687587c055e35a41d4af49dca9425950c7b03fa04eb8a665c34c1802e257ef3df5b002ee01a709584ce6e7c230ddade4691b50622da9d0f65cb4bcaba29b902a2da60eae7a467a9e71ce51632795416d279872e267b26bbe98396b9ea6760459fe23eb1af443f024f4b47fa5a0b4ec2766ba9e5ac8701ab033b536335917aa21024947d324c04057eb812753f8b77fcb0b0d490cbdd5c487ff0c1b916fb1620e4d6353873bc7775b755626f827352dd3dfcca7057d05e3db356f8519708239e63ed51035742498451878dc444eccd3ab5775b6450cda8742de5f380548f5e769fdab294ab3b4356fd91fbf0a8bc10c2e7ad3e2e55c92156d046af0571d9da3b28d460074e35478c0df8d7902e12012f8c61454b8399232538206deefedf20b0ef564a4eb504bc379ff4fbf80e38d5fd03f37a8cfc3b853f7546c879aaa6d21c99c9962555dddca49cb2715cc86f28fc868ee023dfc724bc89f075d7af1d81ee88bf4fada419e2e6c016fcc5073369c186f4427417e150e2879c86112c13f61bcb9a97368832af2a9e06f182ad3556bd93b434f03e8bc507dd231d7d56de8a0de4474318f9b7a613ddb4357ee4b37be0333d0f2c8d747ec185dfe7f69b9084d5b6b53910b01a74caedcddf79bffd3f035cb1d900a38739d7f45b29e9f7418fa07353f7a3ff07025d3fbdba2621b6c7fa0569e0a74292fa6d792af2b25f804176651387b73b181ef324aae94168a8f4f81d318f06f9ffd617de22821bd28d1b9017c6e7bdf0ececfbf18fdfd7bcffaf2bbadb522714c3d67e7aa12bd20299c20507abc7e2867ca6b39d0c253ab94ad8ccc02688fc7a887f802fe5f5a8c284a3be640362fa8af2c55a9ab38e923c4246603c39521a751d04930b043ad947b5022617dd64ffd8982c3dc153abce2937d5c544994cd69a2d54302e69e97a99e9f42ee2003dee33c67545c6b4e57b6284fff0344c7dea9bad1f014b335d7d39e2a240b6183e17dc9a0db7c17ba5cdfce15eb1f0733d059251e390353211db06071e909907af6ffec9e52e02eba2def6e40e340cdd5cf4dbdb1aa9c3c257cb22930936376b16ef0507963a54570e8f02c7e0525e83430889f33ecfb024ac44cca9937a9bb746a8ccf279e5d7f748d8558a774aa7e3f2803f86b0715d49345fb36724d06de20f8b0606a18451c662bd35601dce441b86ef1907022ae11a7c87341f62d063e5dfd6be5dd1225101f5412d340003248945c9fb9df7fa265e84679e600a1abb15c0dfbf45c050331f43675d8ba296ff00530754fe991a46137c216298df5706588bfa80fb779ba20a3f1f94c14f5832e6ee1afe190a1708c773796878f9cfd4b5a6f6ef531a31ce784f5d531c9ae1cee7c6b611d17f328e69953199c48cf902f5a206865b5ebff55090c66710084e8f0372f80c51419a77d12b388c00cc840428809a6b83050a2a660e3e5367badc8572db4ee333beeedb0139d72e103c9d9a03ed7bbdca9d9a06f9a17d4eb714cee7ed62df778772e8a81896454a1cc8f58c34e3fb74a60b19691bbfa238691c624279862ce434b8ac9e786734e2fcdd8acfc085860cf992eef37b5def6085accdf6f284a824984cfa1600ea710114949735afee0951e9fde04f09761c5a8a6e9064ab8f69bbeebecc5ceb070af858e9837c0747e4511542e21cdfc99556051ac94fa44ec01cb2e14b5641e5e33a229dc858246dce5339f74ec46d44a5e1dc8b45cb5b51e075c6b40d395126c5883bb87a4c62cb13c2b7d9a25a47afd0de4122c6d15cb4578539fa51a43f1cf6721c770f8fa4e41db134df9fd1af59a4b74cadc5c3420aadf2e02024780ddd1e320a1af632b002aac3635e75000feaf41b5758cf62eba81783bb7a3dae55af842964ef46d1747390d3f1c80e774e42f53fc760e7da7f097fc231942e06a91deaa8b8d18316e7d610a1aa27a73a58cd04381e30222c033c3205769b4be4de8545371a9fc4b2626b4b165fa08a7d0262ef024a1724e06077f1b54c6c4ee5dd9dc6f3e6a22b17df717326f689cd014fbf1e14800f14e1d4b04225288265d303ad3a167951599b43ae2d0b0a111cbebefd654926a4774eec0d3b97288167f6bb27e0b96a0f82faa8b2e13d0d4b8301b16aada9478cb8539d3da5797ecd60206f6295dac05a809b266ee39965116d346fc8aa4e2ea0964d18336412a14d1fefc763590d972acfd70e39900602942324b7ffb2142a1abc461dd50717125d06b953373f88bb64c6f72c4d5ba14a740d68733a11c9a22f386979ceeed2653c5d5b13b61b8fb3c67560a0a187b443e4fe5aadf7dd9dac47390c4437569894e779df2b5a7f57d6a4ba449ffd8ac9438e11fd3c88bd327378b4dc410fd3c2358455f1a9bec3241dae84b3ad5b6e847c370b47fe2d82feb88387887595ed99bbc1ce21dea7b189e98eee403315b48fdc1dbbeae94f72c9cce4d8a6bcf420c57bcc13265fdc9ab4954f52aedab343de063298f3ae6d2cdfb5ddba3ea6e27dfbc07cd807f2f2b817e6cea1f9be30dc53ed779730973c903925c69df96ee75ad45c9e01bebddd27b72995eaf50f70be3c6eaa85dfaa490ec1aed418531475c64231c2eb5fbb9b070da55a27191703502c632eff3fb6e8fdea0fbd0866568105b609b9806587af021b0e1f2f827354369587d78b5e7a7db95e2146887f4d4ce1022c670f269a2abead3b17199fbaf0ceed703e06d6e56891d6ab642782e7708917fc252d0aa663a8c3e63d8b5deb91f1b548e56c0aa7192e82826544aba0bc698e10cb4e9d1c0eaf9bbdea40ceef248bf896f25b40c7fa8b762d7572d197f4ee686e018bbd064f29f2dbffa32ed90726d183e05cfd02a84767336a1fd7c23663815093f2ead7620cb68f0760f0c2d736c9fa79322dd66f5068770fd7eaff4da3a96c887ab32f2d00454efd616e464a4f3518491fc0c24d2dbe0acca9aed5fdec2becd6910dde915dd61956685374929a46573a2dc0beeb81cf90f799a1adcd1324f547d5650978a904bc17270f8dfe584f6d3e8c67a959eb2ab7b952bab14511e45922a05547d128d1ec686145c53c3ddeea28a36bf219e18a95800f6231f833e113c0c832e21bd480e6a906eae3cfa060f8831e3856be25caacc7f8e24f9d68a18cc001d85722fa9463ac83eb58945d778c474bc1713df6a0b7a00877ca660ce3842b31f2540288ecd9f263d6d4c5d7739a968edb4aa81f7b945079434c09050ccfb2052492239d0e509590c731dc1ed1596780c94cbce128954f3ed4b5f2f16a280d1c5a0ed3ef01dd9ca46cd0d9930076c4a36f95d15e4734f7473e9918935b63e9529d79562f4fd9876127d95bb6c3400fa97d2b756856e6ca37a645c25da54aa1d785afad3c78f5763e4af2e1b038c02e3e62dfa549d230206f6db499367703bd96645701b1b82f2dfbb5fedad839168767f3ccde49841f8d901be51c2369ffc9b86a7b57b58ea47aae7996c80ac16beb51ec75a8fbe390a5f1d566c03947540a3ab66f7c0578ab3c5cb3d1b599cdc572d6e425665c1122b3cb52f82073c679d6f8ba987c3c56c3aa3d9258e10eb988f595fadaf7a8fb714486cc032fb53824922ec3d72f13613dec139e19c86297f5b1b80066a3e7c6b3d875ce6bdd0a5e4f59512ae4fb5a830971e8ac84609f2ebb0a9ac0c1dfd7d7e475497d42c11a7040ecb5b9e4f9087bcdf643fadce4ed61e6c17aca59ea785bd7f4f6f9dc3eb675bda3269cbffc212d62b0920a4a947815ba31b22a7068032609208024fd1420b86fe928dcfc91cdd7b306f70a6c75397da793aa2eb240ac0499aaba8ed640acf6ca08ba70110fda1c68839b2796014ca340555d0ea0bff51a555d06b2453cecfd1c3fe040457be16ebc0d967fcd158437846a4e39a6d094294b018a2e3ac7d59e105ce86035f05c938f245ee1d730298cdbd17c55a4213fa39ea93efaaf8e0212750ebd525b97b5eb24dbaee862cc7de73d9020c85bc78cacd74e6aaf500ccbb657a9aeeee9819824ef74f6558fb850570dba49f38a33510ed58d40eb5ed181a347e8815abf4e7caf5707b9257554d49f0f950c76b047664e448687285da13d0eb8850b5fde767208872ab4b66770be68a5594929f497c64a65d2658f007b70c17ad8e28ca3949400a8b369b57b595bd78a5a56e12c58fe22ab7b8a15bfbc2cb33c4fc03beb67cf206bd86809d09b7d98e669c3eb26ba485f8d5f794d0046fc360aa4bfab02a50c129b7b390b56414eea376526659e01b9f1b923965c25b1404c98bec2b654576aa70b30214b4c6070acb71ff7e8dbf145b0a912a829940c6ce1cb2e8da003060d50118ba6de5946039661342c445000c91f4bdaa7a343befae0498e685e8c4be658eea3c939322d3177452eb0c1c2b39a13045d07f336216b33435c79aba815469009191840ffb406c6fb583434b3643d5d921c4fc5408de8e16430590a4e6681532cc1690ca642ddfc79104b053e859b4645a9f9a1fe4b27c7f07532d8588b512e0124326405eecd1c5377b22619c6e24f29877f6f36a0fcac1a7a3f8eca614067a55ef421497d32506443d5b1052f479eb164e908172796206286dd576049671a6ace25607663c262a0a2c06cc0246b4a1853f26e53f00c5ee4e3cbf2940560545c9ffdfb9c60f2daa22d0b2ac7977676e6ce159411b00147a51a42c7f7b4c9e12cb0109921cac212b9ccabb2e7b10e17f570e5f2b2d95a9e511a246461eea60dd847b70645d1eb8536d01bc0816dfbe3317f74785ced5409624fbd81c53c49520c4f0ac13555498f97c38c1eeea51ebd20fb2c126875911478662a22565d50071a8b85e560781b0b50a49783212c8c65af3650693129bafbab400a3790e71d65a16d62a00cb3e64cc0b36f22d665a666f73e28f8accc080cb490b026795f3ac4a49995f6f364a2c1c8e4d2ab97c1d2faf12f4ab92d8e6b6e35e2512f70c67ea236a05c55a67ce2e34ba708f324a21ef50609567d910cf2d0079b6418a758138f755a1e848d198b9c1a763f244436aa7305272fc5a708df17fd982ea707dc08045b9a2cbbf2a8a9f3adad3bae3046e42ac0654b468366e2e88943cf33a363f29e51c17639f5cfecd9916623415abfc58928428978cfcdffac16600477796885a2e3eb75ede17cbd1ee4d2923df5be3e94dea46e47261ff987827c74050368e6acd15aeaf17b8301f60905ecbf50274d27dcfd40cec0fd189d9ec6fbc1c61d593ca8701bc32de304eea365189ad683195fb42b7c62562c4391b33eb960df11aacd957d11955671a741af1fcd1834ba832506110a51453387c7d68f049905550120684db6093fc2e376ab92726e944272f92c54ed9f108de09ee8b8fc8762bb926c04e459b476d88fb4b9304216b5c2f738def7589368849250026f14ba30e2073c2b83d8f75f702318a42ee8aff18fc6306c6f73e39f63671bdba214045c8c508936db83d8ef349b7b12aff222a08295618f1222b40a2f30b3626fb3930ec2c8445f902d689761d7b71bf445006e3c723c1a40a505198e6285807898478a5d12763015ba061bea3341ab38faf0fabc9b8b1232c2ac4c5a37da047491907e910ff3d82c66e3320283ade7b87a0fe48aca078952b4af222fa48e8a59577c7a9d49e0a814ea0b82d1db792e2a218c9a7dd92f69d556eac2a221d430443c53dfb9e766a07821edd4bb66400be005511986dc2ded50aa9fa4f5a4c466ed5ab0ae34a944f40a6c06d4862b848df4b893deabd4920a8f9a0dd99345a665923bf33790b35ce07b64b2e8f3f6d2aba5f7e75345fec4630164643cdc5f41fdbfeef62384947023cc67375febb2cc75e5c83c21424a5fe24a15b511f98f2981306628ee197baf77d7830c298e7df2744913a80056b9d040aff9af96896fdaa437b7bb82f64e0ce61aa06c4b6634c180a6b0da2d68caf2c1e633ee9cf704655f48721eaf962494d7cae0e7fe1cb00eb4d298c873bc6d761568e661fee4fa06638fc86d5cf25a607ed1d53a40109cfad398325e70afdc48ce9bbb6f093890f3967cc2f6d9b111b4689651dc209879d00e4e68538da47a9f067d0a11f1a0ea353cb93a4d182e363d673b0d3a59ef13ec08ab6c4898f8496a8a09f49e9cb728284b1844df4629c47d09c90991d20069dedf75f889fba4704c0963e27c7f9a4f6a7d06162dc6ac10cbc07f4fd0e0200f34cf26bc24d782d0a026e0e30e8445e9390da239ff4f00486f162c45b86da762ba40fa36896bd03b190a50a06b04d0a05ecc379014f4937e6c98429938084b45ef3bd2efe03d19879148692429ee40dc9bb4e476511231e930bf054e5474032daef52d61adde609f9a84973890783277862188dbb69a8613969f551f6228e2714fdc8df000ec92a988d1882d865c8ccf1ec69b034d2cef704ec510890e845d099d999060f0e96b5a10e88d556060745c338533eb7d0b838116e555818cf009735b56cbaa26ee2cf2b4a897de93cbdb0d1453af75f5abd20e2619e15369dee064b555ea1113a1e28c6e516ef465823c781c9b073600539376c9db1a829b1b0e4db98fea241a1d81857194f9f0e6e52a1b9b09c49f46c8b08623865ac8042a58eb62ad996032f86fa38c95a5951aaa39674f83f82cdae16468429e2c3282c63ddac98c38666b076d704dcb4bb72bbdaed64356a8c56000b5453fc80ad84021dea26fbc9483b0bbb0f993408918de67402877a453224672508dd36972c00a78adb2004df56ecef3139d80ea9c2c4099563738dc152b7eede3413f938d53a7c22acd1db359070d4795498c8cb2330a5ae21e56ec9d6d66dc590ff49c0441879826cdf5d3f5d89c8e8710f178e135bc1ac8cb24de7fd23d350c2eda84b01a6214a746efcf0dae462686219c3805ff66494ec4d69cfeb7e608d87619f9f3d5ccbf019e5d228c6a1d9a15d902b60dd4a6d72ebd7a0c0eb6710e5ab013f0613faa090afa930898c25cc09528b44030d2af60de0c8834a51370f849cfded966dbaa61bf04d1b1d4fe485f1122b3e6252513bddbbc5a3b5264c759a49941f7d7e214586ca401cc9d4d4dd1bfaaf32350fc6486bb0d22d0e8851afa22dcd0dba8f3d0aa60190169b0980216f34252187a5bad08b7b19e2a2f8e59233f69cdbe925a2e8bbfa635071575e30fffd6d2ad0dfc864ee86d9bb14513cc8202aaad7f82120d525b00626a906b7d852c41a6df1c17bf1073e109232e30f3db957d7e7566b7de694d0c673754298e8765a9d97976f44cb0773e0566740a1e0489d405219a1ba19fc5cc9f8abef8b7423862d2779b8e9abb19b109dec7b5079a253609afbbaba7879a03da8612221f0c8a2c4c3d204cc7ab3a8f1965374388a9f7a94c1f2cf022b3fb5cff8c0a35d7ff0a51d2f902a295714621d819aa7fa60c1ed787dea6ccb3961541a26769039be9e9ee6b7c0f1469ed8030f9d64f63094c4ef0502b20f1fa9c513e65e66829b1e7936b18e9eb9f7c180c80b025c96d49c22feae016a16650a5b099f2c0ce4db4bf5b86c97467cd37345403060825cd333909978d93e57a066ad6899acd09c5c517565202812342cda186889f80391cd41a0799d657388749462d9ce25138161b505fee4938ba17770d04c3b689eecd51159dc0c02d0962a71e14e0426f04eef5ff5b22d4d1cb5546b1a58b26c0e2c2b5bfdbe0992c51cbd7767600fbad66e6c5dd182681fe9c613d68f31fc00bb00b39c681e411b2396d125b852c2e0adc29c04541354499feedd46329229b3ffd412ebc37646075fae66368eba2e237ba646c61e11b8e14e1fcf9abb1495bb614d1d45390ae4414ccc2c991e6b0a1c6fc20eb4e2c3dce8db1998ceeb607321183e4ddab3ec49bd2e94de4965f43aa0de3b6eb7632f8ec3d8ccfeaa33a502f7a015d0b79681ca9caaba5ad6d182d27101bf14b5b0786cca9a3ba025ef9e5ff4df7598d0462ed92cd46a0bab22793148cca27b85b1ccb470b05261f0c3a39c4406de6fef7f6386116ff5b0b5b56b752fc8ef18194ec4d799fcd0c0c6f61ba22ebb374a01783dee533df1095cb6e91d775bf1442c8ad7ac447768f39eafd2058ab8e91e2604e0bf82e4405b386e92bff7bbc11f1dcfeccb2ba3470ee5fb8b9ef2f550dec104b991c325075686ae4284589c69a07ff948f9d9e4ca544022a7f6279ccb2ed352ad4bae9e6e65e9bf34e6de1941209e93bd3507acfdab285d961d473b7b16d9d76fa0a5adb04373962582c83098551d512a6baddfd23ea4181e401647b799c38dbb9604072d617edb9601cd7bfb6dc912f96f8f19de6a01e4f61806d986737a7983be290e3b417a45dbabc81dd355f38084812ee0e2fb66159fa67aa63efbbf157044ea181062b9a85d29d26de6301ede0d1c096a9ac16141850e834bc6905c6ce17e12c0096a28514463fc576be070ac037da5e30454d24369620b5dbd3b4ed6829d3060bd02b5a9fbe10b18e49eb926d1f2f6cbc714cf49c2a0046c6da30713d62f44dd7d71e53bd98a6a86e1f446c325bcbe1290d598476aa1a3426b62a7e248559bfa573d03268f9d2a8fda8138efdf7b7276ec25a51ed1567265414af8631dca963e38631e93df9e6a5be373a672760ac6cc6d5f30662dd7de7dc7a75784fc02bb9fb157bc3b76d9027bdd5e195905163149d795bbe36538c00287f67406191a462c6db3b3d62740d181fb6a7697ddce33c50bbe574df0c624085791db6a8fc3a482f651fb613f562eae59d23f3dab0dd2cca8ceae4cdfead67e6bd9b05a2c82b832e1bfd75c1cad825e7d2550b274276740889b18e5819529a98047cf3e73cced1232151afda058c6cfe5bdbcd6a230c3ec0a63b332769a30124806b1ab73b7945091b308a3c8c7c452a6ee2526d2d1d043518282cd1dece5b1a778d978ae3a1eab2b96352fb124704ff7a6e20f3da9a1a6123f4e984d33e9517949eb17da46825c5a83e4215446dae239a015512a7851632a3a202f0ea8f8b186f4356c6bfbdd05a87e0e67e78f713334998990ddedf2000d18093088372202e96f22ce482ac68c11d239c5076952be9548dfe642824905b24ceb58d49995ae0214b655630b44473c0db8b6f4f15160d936cb6179b43ddf380acaef00875f0de106c747a3c88d419fba00135e3dd579a71346f4ce33cc2d7a9dc1f1c88d2d585d74a98a63945003fc6f9ff471db7ca582098327f2217c099843bf4ad2f82e12542fd4b2900289a3aadf1e81c745db4f50aea27a196057d68c0e7d450f4ff72a460a512ca60a06bfbb4ebfd1d844c5a9c1c5180177d86d40efd6ffdb47310cd96230babd22ba62e5fcb879e39193a1abfafbab906f6b0c14fe2ed9f2f15e76bd84d2e078da2b61cb13023e941725d6ca63446eb370ef99098d3ebc9c6b2e5605a3aa24434ba202be22bfc9c10ab01f110e0c7dec7ee0673a087703cda24e68b33df6592c62b3aa55013a49306423b269b8db14ea2ed051c839ac3c5b57bd01d717cc04aadee10dd53e30040728e723185b9bc9c9b813fca7b9d8f0e06b665d1add0390f369e31f0034e6b7f93746407abddd81e54e05c8167e6ee2c21a5751680d6d64ce0925647a50ae00c9434c80bc34224273bd40722b3680fe26ed73a990f20bdfadd20612340a0f8dec82262bdd910175c53c457f4534a14351a4134c213965c8c5fbe9e776fc1abb9c9072af9616d2e934928cc6b4d46ce86f6bfeeeaf059e3c6c67b726f3ec960a74dea364ef2e607e276bc10512b6add49da43e47de84f6a1686cae93442a740109a251e70463d79bff20f6a8eb31238b7ad0fcb0f425a1bcbe6a83e1afd11173e365ab8b9191c1b70eb3fb979fe8a4f0c959993c44e68789a89f52b2bd3cf4d5a19bf85575a9c97f5f66adcdd24416185ee936c340738f68e3b4cf3b06ffa69a74a4d62b966b18387311fb786d6361b53a2d4ecb7e759011afa0b6ee86103548f48017d5d3028df992e21bd264b033edbb0a1f2f70f6323eca4a85fc15e5fac1d3d047fc5e762490255ebd8c0683976a6f2e6451325d6e08bbb8340a3cb871b26693c6796e268d926e5d54fa1a8ed277989e1fd86b892e152a106b2d6417e4566540040ab1ed099818015dcee788d7ffa55610d63a31507e66397adddcc35d9f9a82ba9ba4b5b1e0731d63fb1126b521fa7d758c329226f029ef6df9ea5ef787b25ffd3843cebec7b7111714e06501f4740d5ca2e61a24ea7f7b42d9ea8b1b38a8e001d706326a6015e3dd6f77604c0a19c532661406c4905a5cd5d616c483c7d1363dcbc505463f97652e08ba17326a1e807e3055e7b2d1ec775d54f668799a9523cdf8d2590f9bfeea4de6c2cf8c3a17334da1891d57a9c42d8185e425343f41a0ba3b98ab9a4d003e5d0a4f0109c5f04c6dc48a289cd85078539ef429297428f5061c65325528335a7b20c867f0ff38dc455b583bf1f4d83815e2a96eb34c966af1677e36d9bd6dc5ffa9314df9a1c9e5963ff85f431f4734ce22d3a8be55e9ac810016573ac31dee82810be687d8c0d45d439ff32c7eee9c34a55f6f20d116701b08a3d48aa2b99feb410a90abcfb328ee655b6f6f2de5335e95069c10613c8bdd392d08e77f629cf6d068b19e4146e5d443b48153285d633f9d1f1484c2dc75e62c4923b74f392afe401f215d81d285dc9aa5b8bfb6f43eb2633613a4539e1e5dccab933bd410f11c14853c60d2f73537a9821d230d7ea0c52f75ec64ce11d51cd4f19a5509c462d18f153d5a56a8f9d867827d80eceb02e7d439177a5d3071049762228f7d6d6af60f1ed7b4829a2d053e1e683cb2ba12ab57227f894ead70204618ebe08d246c52d11cb70f15e698302ef7b87ce31c5aad0a9090aad6589160caaceb93e8299f27e5715459967f98e577a20052c2bc96f5e5a4df606b05dbe961d90a68a71a55c31d8903d489d7078f8a9c683ed70d4352430478fc095c57ef58fb322560a1501ad71b809046a763b8c70a43cb983ff2a7a1415c6b07e991cbbc1a7445e0798aa6859735428ef049363016f4d988105cd61e3c9908c4676badc587b6bd1a26105057fdbd1e699b9a9b1f2b12c526c2ee279ca7dacaa990049e7ad63f0c53a9914b010164382c2f9687fef7b7af337077beb9d640a1c9d9cade1a972b1ab129efcb9fc912a52078d03f98cf330c7afb64cadfab2b93477788b52f3184fdb6bb6f712f86982c7c1eb2803a4362f3cd218e2a7ee80c7633ddb64b087092351ae700b38b5465a057e2e8efdddfd47a2e367af903a313d9a8df4dfe203169e7c0df1f881c4ad6ffe63d2a1610ab2b147b47bb9af58d3deac4771d64a9eb6e89e0b2cf20e683958653a18e49dcd69c16b36cd39034700d28eae67b15f05356c3f3d701ba69e71bbd9ce66395f1915f92039c0135790dcd492719bde78cfaecde9c6a93803e4116c52c67bae250e605796c7b9cb141cdbb8c85aea434e8388f9a84357182de00297eb62e88917fe1b4b5bab71fd839918ef48d6022a5cecbb706b92b56e1c9fbe49b9405a88a2584340c594bdc492908ba41e7479c479df6d3f6b75ff88a4b86ea6976868d66378587596ce93faa25c66a837795c27511c4cb3f6fde6091614f4cd567bab274c4993448de70f80044f008c76ce7174d4f85625fb4dea6f5b45a28eee96122f2d3fcc4ab02663687036bc3d9608e9ccbdb0773dade8cf4e911884d9f1572870cb913caa319ab42c45804a468414f3d40113d1bb04950bbe93bf4ad809274c76ca502b3c0e5db2172b3e172e239b5d163c60f578dd934100b62fbf009bc3d78bb31b4673d7213a46da687271ecac2d04d388653094dad14c81c147f4a49ee060f38b5173b4128b3474eb3a81bfb1f5846c48801ac068f0e3225a38184c1cba33f91a0a09c61160974ed849622312589a5c7da85de78be4768e1363ed1fe5218a26ba0905f6dd7fc7b111f050e9408adf80bd00f8deafae2bac60f19ea04b664fdfd9a24b9ffeadb0ce78db4a043b8f05a8f178adb10ba2232e30bd5d7cd80999be2cdb89ae1b18450a5a40a13373c2f232e3774c9166dca8eeff625504c8d4d5458d2da0db043a5cb190829cf5d090b3a5262a181075bd071610f1a3febc70b38e6858714508a25c712b8ca430709e191e5605c79c82abe3f5dcd156b99dfd7c53c0da886e979373e141cf8977ef2fd280df6c977a83838d08558e78546c3d0a93c57338aeac138c06c26172fc4fe4b38497eec5f834caa65fe4d5145b3048fec4f812c0f66b37ea11d201dd0029783b900fb21c0327cdd166a1e1c307c84364d012ee39fe04059112dde1ddf05454a7871238e45e69645dd649bdc921f060a2de7b68a8d7015350333450a3e5cd57187e5228cc9b7de5ca5d428bd61c9fe64abcf1b43bc9e335a76f3885a0ad906476904b1dac781fa9db05a3d1391be2daaad449cabdc483a79350e909847990eca042c538c4c83b74ea1063a47112b6af25ecc3add7cc6dfa563adbbadfc63e619d9b063a8098a819cdc45194f70bfbdf7901696fc0daf5e407784c158506d370564b1a814a4a7182e2509ea139beac8e44beaccfbde739b6cb3ecc6019af8ac6d115095cb56f039bc2202868f644755abc9c21e60cf48b503e853d535f417c9171757d716ebfc30520cb4648437f9ca3963b04c7da77e5fbf4f7b63ebe14bd113afee73dad00557547482ba7a5e0c46efd5af86e44ddc5332bb1403684b537f1ad9d7da06d00ce803b1934548378d1d06cec777b0befe9257e14d327260ff3201fafdc7444f5b15c546e9d55363a75302ef6b184358c678c7f6afea592d017abff6a67ae1df8083e75667a423cf2033b83678f2051d98edd63f56d3c5953351871486e5bca5df552b7f888f53e2d087ef1457f5813ee8529386587a762adf2c802f0767cda402916ed9586f5f8bceee5f433adfe7ac1119f656aa0ccc4cb046a18348c61471f7986b2e84af3353c60215037d5b1386b6cd95c5ab37d215353bdd321fda85c6637626f86294838f21b3bcd6bab439a592784fb83247345c51894b8fc83f39b5db053107132ee40090799cdc41900f577d627062243fb0f6ac2fdd021a828b48402c46ecf090dd94978fe11bde4d40d0f00405340280df5cde43f1ed2a025657a744e71c22d25e04bc201ddd20beb8eaf32b30f690d6fa9a1a02cc626704e8b32138ddbda631c9e9620d70a3a3e83280dfb1487bcb16c3ce81a810e1611dbe675f6555d123ae87217a27095f18b47b8cb58dd44e551eb4b54623c4282a69b88d54fc6e04e0a13d51dc9461a938f931f7fde18031bef785aa16e3278e13cf3dcb712a447432570cd78707ac98661033c6fb22fd44e6adce7fe30a1e308020506c5c73d25e0fe75814dd831155cd7dde542a6a4f1287dbf9e1ea79ea3dea1e78fc8d4f20c79ba0747d187d5a132024535fe86334aa388f762eca0e4ce498d978576f0307419e74c45998ae3e73ddefb84de251dd37bcfebb579b95ce8664d7056260f5bca0e3768d01b607c11321a2cf2187c2ee4f318c7ccf4dcde900b3c659727747d2ec528f3c9c13e76208f4020778d0a3c0c51e16dbe653346ec71d8cee71630ed69b4097b9f78cbabd0bb05581b8956dc853cb9a3707edc49227656060c34fe3f60b994f6e487e1b1047f105487e8898b30f3ea1cc2bc8e78922f2ae82126b7d7af5596316c4180f1e0a1bedcda9be7e82dec06e8db6f148030b832239c6b5c629afa53225ef50b4f02cd8bc965270fc814b67f08b76dccac8d8f2650da286d6845e603a608a455455ce66a02919faa01612c9f7535ba7fef713309fad078f2e157740116d02f17f14be0f4677fc5931c5d9de49b251811fa03ddcc4c5165136e41bae56a1d3ffe83bfc800a263dc6082fe2ecfe15ef5353567a824dc3703a6afa96dd0fa395758603a064dcfc72d8c4149eded1841efe314a01e9914faec47084272cade2bcefb0ef7b4d30ea927be12b1551d2849b4664d955a381db40757e530d7b4a3f6f86d33073ba4333bdb907fa2a3a63568b217bcd641b8fe6ced657055b31fb9f037f706094d1df567f60f39850a936d0ca4c81aa4532e987c72d30f9e59ba57406f7dcd1b84017affe2f9af56ceeb8fd45a3d9bbc98545a65bbe48712be9fe960c63a25ab6a6999b54bbac29e8f1f6315dc302541a060a3715bb2f91a949cb510e48ea8bcf4cc1c21768bd3d2a12d40d01489c910140c869bb9897594601820ed3f3feccd57b7b3c503c0d930f1182b1b1a38aefe13ac206cf910035ee7e4df6755cd09454b5b642d3a21a09040d6a0c42cb6721cd91a8c894b148c232ac224a41f697940ecb4aa220f73b001efddeacbb642d4f56053e67b2e4c560e7377047809fb85ac622c794c212b85f435ad6c4884e132f22c474768b73fa5ca69d763c78ae74192ab88f7c8f67f8df8ae381ced2769d67e23f6ed00d86473c003609de6d07a3d884a32f9ccf8684652eabb3dc08e0b99f7e7f5b31b83d2aadc707f536eb9e97f682e46509262337d1e5e17c627f8ded0148b15a6764708b00601e4615de3027212e4321abfa73c622d85317c88e5d9584614f4cf23680892c1c506c11a0908e7e6b793ca49191ac00038a7775e6ef0cd5f3e3c7314ebb16ea6698dba5e947cc808b48b300d7462956f6a3aa1a49db126d2a612b3022592ca24638010569d2e69d43843621e8ab09f4cbbb66b8734fe2d8df62807f20e17b21502f9052a101e44c87e5263a40021faf533bfbe313974b7661dc2598055c55c0c83a660f9b1417aeafd372fed6a202344e15e4c8e87fb0cca3869165ef0f36ad7170f57c09cfe824b671be17166e360dd040317fa65b6bbba50083b3d782d8eb48692d646700f431793e29d38ae8df0238a4f5625113e79b98e672130b4b8a0196464627e1edfda6146ec714f906083b54bfdecccd65223ccbd07fd86870cb4656acb541007021a7bea23027c6be2f6e0d4f91d98766f042fef26998b50f52a2674205d22396a59eaf2b8c71649a8e056189c0deebcc5f405355333ae3419941c74c0561774b0b14007ba9079ff9f40c4df4d788a094bac77f5fadb24aab7074d76622e47f28370887aea4c6d1dc87d523b365252d9efb86fc16fa321900616046ad41515e26c6f49d3dd3f560ccf85aefc5c48a04320019bb596fb3c901c766bfc86757f4725176382b301b2d360d9d120c16180ec60b07436b371757f4e824d53132653417600e15775de6f1c8e6f36dd5f1e21f71d0f50dd116a059edb803cb789d03c7b431c0b003ee483bcaaeb971b072382b703b2d761d9d331c1d67a3577078b18789a7b940f17a643429b7192d3c649b89951286f1275db9475d55cd21a6796a68ecb0fb5776e0e1eaf9f2a76d808360ef6b3c51f76bf1d768c7e56df7d677018c76ff10aaec414d58fd882dda02c230ea249ae1e0d1b886cf1cd93d5318c4d7607b577164c8b95a819e4487e99da2763e6a6d55f4159f66f186092d80f93a8dd4e9d8022f075cc01b56d424518bf05fed964fd8423cae7dc25478968f5ae8448bf6134b1d89731a69c3ba730d505987a8fae1ee1759272f6c5fd112b33a4ebca4e122ff67475f659e562a66c84ef9a6de37436a4acd1aeb5725f8c6831416cabcf8c4ca3aaf2814fb5a7a10e6f94a77789d01d2b71fc9396b3b6d38003be261f7290be1ca2c1018f432c0951a0f1f2a9e1208558e4563227be3c332da12d26bdac7ce02edc29c34da7344600448b04c3ba059dddacf0be424eab0ef2cab9e4800eddd247571cb18ff6d07d1d4a2c01363d6a8d19872d748e29cf9f26b3800310769dda6ac68319c5263ab0711c9a0fbba4d271334baa9739e4ce4450e38b4517d572498585b54613a9b5ff94ddc35c1ce11d13f3eb60332962022318de3141c39d000b03d84039d9c00ba60b676d997d99223eaeb3fda3f2ff36f3e0df25c58e4976536b8b3771073a59215f4aba9c2e3e1713bf6a659c9a06ae6220794de25fde6555341e00aadbc806e442260faac721d9bacdd710e887402d99dde28284ac60dc583f0d36f1fb2aa43b8dba23581ddcda33e26dc5ae09ad356da98940681fe519bcec25aef6132e54087f437ab9d941695d9c92adf9d8d904e15246bf2d9cca2146a29b7738f71bbbaf0f9a44aa8564d0e717afefe421fae29a841dd9b1b7f6baf1c1e688d7ed23f47c0c8ce5189acdef3422ce7c58b01177494da04dd31ce7ad3ccb9f78ee1e125d2db4414f5d15c7f09ef036ef9f2e94a0f80c402f0264d44fd9226a56f229ca6c576e2ff71cb86441f1c689b06b8ceb0dd7caf85b82e3a9efbafacf34591dd73d689fec463a1f11f2a85349c7294bc99a6585c1032db728cc08691d99dc5888f081601243ef02484e938af4ed38bbd6bf0d349e425800a2e424b602088d67c8a9970b158dadbbd2779026fe1e877e036eeef79ed82f258ad63cfe5006174ec9da4fe9d22c0883be069b9d20eb127308d31a363b7844aa5c3c3e405bfa6ac2dc5ffa74be0c58ed62f1650208b0cde362cb9708578904628c80315bb0d521f79dcbafd177527cc690c702d9a16a193d0b655f8c3ab92bb22843650dc74167205404713f6ea64fa2d0b70e8a0098af23d6ede4dbe26fd38a02189654ed8c523fb3d12bcd3665345a071c6159594a84044726ca62012d9547fd9c5be115c85b1b8984ce0713415773c0a51b8e135aa4dfa95568959eddaa3266dacbd5fd106935e285a894a9d7d0a9e5ac28d63aa3a4ab7470b29b6e1cadb0a3111127f96ded162420edb795c13991dcbd3971ada597a0a4f0e895dfe518776e1e9b61939fddb0123ba5d75501ba1983b5711894ad4a4ed17edcf5fa9a442930c2630f23d80068ef6645b7724e9c3b0f1318a0ae8bc3a7c02672281edc9b16d630fd4b1d84de422a783b7ffcd758d0b04c684b4854a09b2f0a39470f2555c858ad088f6d57cd03a9e676896510c15cbb44f2aed2ac5138c3522b54cba4dd5a53bd5a02f34d40d61f254723b05557b0e291faae9aa6fc056b6473601f8a882a261567979df3b08421dffb10ca6296e84fea9f1c5bd3ec6d011bbb6f4924a73f39c3ad1cdb011847ae3e9b9842aa654f4edcdff8a63e17280597e2b2aa5ffc7a0d8ba7b45c68dff41ecc6fd99c4a75f56b616d9109c7b86978b11ac9d8c1a4e4ae280b9712024aabab8b22f5f56304ea6ab78e6a3b029d5c0a2e61234463fe89506b44a4af04fa3874c86f6ebd0ca96fabb25ad8fa0311906e00fdc65c0785d9e9a3bd053c9952e5a34ffcc5d298a35cec3cb9562123a026e8f1e4e0c3839cb042afd09d35ecfb25c61f332521359aa7f6c9240f9cf03e82d731f9f5f487c6352aac0314d3021adc555f5d30522a9b0ef1e28426524ca8ab663d160dba674e3ce9ae2b07ef3299aa251505685066cfd96aac86c2e88aebf742986220d1c260a817bd5a040af1300a49a1878ac3a36ee8c6b98ea1cfd6ec45363dc2c3881006697befbdf79629a514f205ec05b305bcc1aa6f321d9658d2df45ec244bd23699d3b4134d6c46b5ed88924d4868a64454341372f992679b6c33da8e6c421b0c969c6626d995bf139e127a45f589e44e9cc9694e482152cb9d546772a6ea3f7da6cc6936b02bff15c3f3292bb72935e47b20a7acfa2f973306ed4f6304a095181512d28c9413261f274c4cfe32605e5c5a586241b11382fc6867fca9e850f00d7f15d19fd819234b125144900aaa3f92ea7f1a8d6a5852044be2b02bff203e1dc6ae8010fa41142f96e462497f1fee7994a652ff2c9a5ab650a5a9e536096911c36215344755152ad86847a5763763a2ad7e63d0d94d6b9f20744b4edcbd930e688082c61c6b7287059e1d9511d485c9c3d3625848335f3e561f17cc916e8ed067128428c8d177baf9afb95bdce11102ed6f74706c1e4f3c7ade77ba59c0d25800696767fc4b7e17d072a1b8ff8e1dde9722eed0817a17e6a7fc875ae1e32aef8cb747d5c3538b5bed10d4b7f1503c3d288ebb33de7fe20b5c5346158d0951a211954f51e93fb15869a7917d5040594dfae7657ff81e3e2bfc920c59dd0a47f73c4a6b18ee0afcf04330f47ed206cbc349b2bc479c26fd6f9af45edaf116bad5dedddd9ca404a9cafcd73e511f9c73776fef2697d58ac024454535a31e5a8c2c94b6265ca9d53c218618328218b80bde82c80b3943414008f1d9284dd6090e2d6029bd89113257152aa8cf76581097299c4d66a276c9486c1f765de735c88a60f275953b13a9b00d3336628193daeda4b6f3a6b03577cae4c632c54293debec6a063f7919055a8a0fdfb251b19ed380dbf7896aacc7369ce1d168e2a3f4fb7542a03d134bc03ad856e6dd211231fbe823f5ad2911ad42621a63a7b5ddcca335fb10de81ed5ad658afff58d41474fa401dd2f3d5a0c18f5ccdcf4fd295dd0929b18caacc9229f752b759310e8696fbeff6e44108340552b8c0c60dfe6994273543e4785a69df1dfc6f042cef33cefdbd7f721d8034e15f0555a54a15248814853535393d89432a2787ae2a94997265331bf339f128e5fa94923b1318d59bd99a8de43781f48d44bda08e56d14f6964975eeb899c29c4fb8ac03dda4a127d5b9981e4dce9f58932a1650fe79b58ca4d2f78b240ecdefdffa8790eacfea968f9e4769ec4b560a9e47e79093ba4944c84ea89b34645439e6349e47692af54fd24a52c7d6f4cf3f000fa9738917069dd58529764cf56b117b8ee4bc8c2edfd3f2348a501dd7e1f710ec979f2c3465748a1a9f54c00a1d17957548175dbe4c81638f60046d7997f7173ba6ba89fdfcf21268f99751022ebfbeea98eacbdbb467e4e56d34cdcb4f16d2ab493a6be46efc948b4aa37e98e73c75ddc19973ce39e79c5d4bd7c9a5630a99f3873961384ea3e226a7a2f2a8ef49993eb5e5e72e94da32ba5646fe11631c63ffc6719a14d88523c37666e280f3e7fc9df96541b7295a4165a6d71c0d7474c7409949e8349acd8ececef8cb0826b0d32c74eb7bcfa18367a88e584644cd41d5391acdc66667fcc313db6c0daa04c28279192fe3431aa2ea05044710550fa8f1345ef532f2a8f134543cfe47f8df9d5919550b68797e7e525fe8ba81ae726056fe960752b728288bbd33a597e2400a1be0cad230ff29fa80c9e543661a7f5ffe357e5ffd32aa1ef05fe379fcd7a8f13d22fcd7f8ff1f7b667c8dadf1e2f3f81fc71ed5ff8b63cf911cd5ffd813f335c67df1c85166c840cb55a25e8aa6c02e28aa964b5bf958f8de4029632c4fd1b2352c5ff2104e78e28c0354dd405751dfa807bba0a7ca309f82498daa1552fff22aa4c66d52060ccc7bfff240eaf730e2e732f234b9b38526b75a001c3bd37f125d402cc460e0892181681d4ebaffd00474541ae2be4610f71523ee4bf579b5db978e163398a63fe1cab8b8870c031428309cbeffb3719ae7fe24daf8f046da7b11d2041b279430734300374455f8ac07f21280a80a6f7c8e00fec6877fe3c6b36ea0f040588fc2e7b01e85f1c71199ff71c2b364c61cd6a3f0288c3fc86701b9210001bc0922eb4f106f3c29a2f0366666666cbc09e30ff26dfc8f137ee68198f0404af89cd597f0fe2500e04d187f98f000f81f25fcea81bcc22e4124c09b200ee04f10713c2916e00b20aa38a44d0735e941429b6c9b55ffada85ba51fcdba45f4bd1f756bcaa6d256444b9739cc5d4602ba7de92815168a0afb44856dd2fb243b653dc6e6e019ec0d7f0fdfbfa3fcb04b363be34db6a66b939d014717ab9e8630b963d89533d9b08e01f1a7a880d5324505cc886398f7d33086a1612a1eafc2f97124e75ba972def3bcb1c7cb540dc0717df58d2e5f398f8b391e4beea1fa566bb8bdcb33a5eca9dcc8403be33f846e23ce78d3e4d65b1647449894c44ec0036cc9107c9061a526fe61d09295941aa502d7fd2a003c9abc05ac96bc05ac763e36af79881562613db4ccc51b610d1bb94993fecb83eacff15619a5c29c356c14f79d08564f754c0bb5ec09a526bd95fa951c1c42a78f4749c29559d7d1a36b7be609db85fe685ee84f6ca157fe9c98819df1f7440cec0d1783765defa679c2eff9fef43de02f9367e4ebf7449d1ebdf2f0f4dff784a7ff9e47f8fde9797c7f3a7d189efa1576037a5c5512b45c261e4ea77b50605b0758d27fd4b133fe9b8b72bd35e91f9c1c96252519aaaeba494900a102cb8e81205210c3d49834e121d03b2684fbc42488ea34c94c63e11a93a6a1cf29292a2a2caf32aafa577e5f3d2e9f32aabae579a47ccbcaab7c4fcba7742ce3ae8cb4855d46d95c79069ffdb949b7fc9be55bbee507cb188295f108f840640da482a3a3de1f48ff27d3e4c3ac44600625163908d5e2096419d3f1855ef17b3bbe62cec72783944f797e1ce620670939978ce4a4b20e8bc5c2c961d96091a806a3bc4e932c43b8bea27aa139ae7d7aa9c7acf2ebec740ba6f2c340e303d68c80a23207618450e5e7e1b6f6a1f2f3ac80b29af4b1355bb97befbd6edc1718841a89fdabfb7e1b4dd37127f6e895b7d3640fd761b58d6e7d651f652eb8011353122d60814cc935a51a55e2d7f62f5f4197669064ca508ffc31095ab23c2f06ceccecceeeeeccccececec3f4d9ef8c1120c8911c90d03bcd9d9bddb1b8b203e3423f18a27962cf919829f109205121a9ccc40d4440a2366109a2205480cad00c80a211560b14b8ea2348164288a228de44807283baa7852e4480bb890a17a90c44fcd071b92340144d4440e4ba408c202206a53d8c086fe6a30248aa1708a2234253f0005315bf2e467c8cf2c92439325419014418208dd6700ad0ea9adf833ede73add15ad6eec93d965504f3407da64044db5251d74380ac2c2892896242931028a2555bc000914330025d54cb08276e2892f7a7bb777bbb7677bf7328e6ea5e65094a41cfcd0474562dbdbbbbddbbdddddbbbbdbbb35318a6c3e0b850c507a77b4df6cbfa3cd26de6c37dddac6f279e38dc51bb6d971c3db363b37f34df3f6f6762729a9010fa1fc2bc3738c7065ca19e379a9909190883890ff78fe333dd2c53db72ef315f820f8a7ef091fd503fe49f56d2dda6256dd8af1c7798977b12b7f1e5487e24cdc97ce44c55951b36e0d6d6b386762695a881d52ab25252d13063000498ae28c192b2bfec38d2de33e3128d7909a74ee3bd4f729323561df09c249b757211cc1ef1b4bf0bdd1d5a40df8a50b649b19edefe19272cf7395bf837ade7bef5ef7fffda2bb54f7dee55a66eeef7b15b67e63f879cfdf89464eefd234a7e79ebacb5bd79237c30a8ca458b2e1081b64d58b8a8a8a3847c7b89bba514ea44612edbe8845ff6920224affd91a21b666bb695f9b118d8b84d0b29b98748be35105ee69547d5fe2201d107eb79db8686b9886add815c91dbb2b716d0c42b92fb9569980231379230d328fe6b1c744b4d3149a327e9616626139da1a2eb6e5c5b638116cebabc1c8b652dedf89587f626b54dedfa1e01cf4fdbd880dc261dd8773e4185547a2820a040f41aa7f87d151fa07953573691167fc27a69e13617e135f9e672d24d4b3ad49a9eecf21a12b5f6e34baf2e55caa48ec846f30f9ca7ffaf00d26a698524c89c608ad168b3565b2297317b896dbb4c9362396d191c21431e651a2ea19899db0f44c8414a1991251d14c28e64b9ecd52336488f0cec4d433522966f2e11bfe2c4c3ea713cf58624eb3c9b4d81c9b11cb268bc5e60c605e5e3ad641ddf4662e2d2cbf4b61be9a49aaff36c36e22d84d86b186a5d964be82718ecd886ff8a302375f10a8d731d833099529e6e8ecd6a07e64e2d6a854ffee616bb83fd6e4b83bd3429a746ff6a91ca549e6906833b1c307f2f2e7ffbe0fc71fdd7f3fc0f776290a98042cf749d79f9f213fddf7ec13efc1b11b7f80db0528dbe709a862f04fcf237cd4d8e385370c68d7bebc574ee7ec8c3f4369928beaf705dd4616e99afdd5e0ce35aeb112d7d6a64316d25ce3a52e7f546ee4d919ff79946a22a209e7740bf8fe5493ffdc6ca265ea26f5a38afbd2b5286e544057766d0d379ebe24ba8d3adea6d3f188a3d3e9743a4de634e93839364dbab7747af8f42ec8118de3d435a2a0dd77834968d7349bad112b5d9f5f14fc83782f7f478d3a76e6fb8276638a8e59501f62b6851cc303cafd4682ef32ddeacacd61836ff89f3e9c4d22c0726d8db73cd82e7c7d5d8532154b20d57b70c7b9abea6f8373acf646006ad7502453314dcae040b9ed8659d8db5077aed2d5bc28540a503420f1135b33674a093e12c40e218bdfebe8967faab7a6605229a430bbcbc36c9ee3f2309ff3f2a95f9787791e2e0f33aa1ae665bc7c6a54f5ef4b064c932c1fb67c384fa78d85d296959516951696efb422d2d08517683d3d7f8f2728941304ec8c3f8b07d81b2fe28dab6b580f964e53fc0441c50e3f4d3c7952cbf4459d7329e5f5c8d3e4e4f131392e683fe9abb94caf81e5d91a5ae7b7b035f3a7d75d6f403dbf471e2ca83fe934fb9aaedaa3aa7ef5b301e5c61f996c3184a157feac49a2a29e3957f967673ac811184d5b88f301d1b32e6a1943018202e463c856bed334bfb8891d08317bbd66b32e6a23f07fb6860b4f10083f3c8da2e72b70f4888a7ad69dc0cee76ce65238773559d433577fd9b36de49f9db9b1a9cd3c31361c20f8295ed0a288ac269bec221a6d224d21f307e6d3640a3893b6046d9395dea4f96a095a4ed884398d7bde37c392aa3fe581bc548d5219fba76ca31a34977a3661d2644d9cb48954fd5fcc1535bbe8710a9593c6cfbf094d19bf50b7d8f368bb029f859a94cda029e38d43a5c0db269b42e537e9a22f35e94bdd2a276c0a75ab74da1c72a739ad5b4bb37103fda269a949f70eb717e107da2f739a09e3718eb359396130d50ae1cf9f4d544e581b9934186dc2605ddd7fc07ca1c6d904035afa12adbad3684bb425da52f5e762b4745a1735e9bf421335d9335a1bd168b4179a2bb139788cbde17f7a7f37da1a5e62094eb21d25cace84e015d33b5117b05998000a190cdaed395bc35da38c9c9e51356c666666661e4b162ac1064110fcd0719af410f652056511fc0ec3adb9707442b25b5d99b9bb9b6178a1f3b156734078cae9953f07e27c238b6cb21b6348b7626b38eecb0e22e18ca3d3834611fabdf7fdd327f4f91ec461f38bc27c4f0ce2bdbc07c520decb27c8bf7c82d01b042867eafcdd0294ab98ebe58de2aee602c6948ff499d0d92dc5e41ca8baefeebe49cb5630123ca33d763847dbe0c2f6dd871cc74d1f581141dcdcedc4af9ab3dddd45207377779fcd9b37770af72278639962eab123b2d0a47f221d83065a0c4124690a307c50aa0205330cc1233aeb3e0f5fdd75980ff90816b63531b1ad99df0b09e14043aa7b91128e6d0dd7fd37c28c72dd976a1b550ff01e7c1ede83e1e63d0f301c55db6824e5f7857af067b5cd27e6b0263b51b571ddf6df7be1d8037aafdac69c6f546d1f760f82dda8da461cd49f3ce63029e8fcd261dd7ffd4593ee305fc5be316837313549035af64c24a2a5c3981cd6ad6d8288a0ea5dfd55a40d87910e837143ecca1f89fe61a2a9899734a9c32322adaf4e25082ac776c67f08e5d1c685e49afdc1a07bb7fbe60d04b76d034fa80de4f0b481fc1bd8830a4f1f828f7a1ee0a3c653f827149fb6499511dd9ef3d8fbf80b41af1b59a4cb0b9237293e1cdf0a9acc24740393d0fe44564fd9944da139d4db9753c6c44253c6513e1aa8ff2e69d26bfe7dcfa32379edfb5ab7befdbe5df9f721287aad919a5ce2481f7f1c92d71ca95bb56e95dbac2ee99697be4b886aea085aa66ec881fa6fdd7ea8032c00aaccac270d9b51032d1bd6b186354109429747fe1f304292c5308ed6675d9e688114a5f881996b35a41d983908a9492d46c3a0297ada2f29cecfdd5d13d0fd263a8201121c363b6e6ca80eb45c9a0dcb85c4ee76b1a9269ba363aac95e124ed0316c32202de1e8baaeeb7e7b9bf6bc6e75dec6799bd76ddce62c1da5efaf29d5f28774ccccbfd3e4bfd840cb55e57fb18167078784176c8d8778f8197a9be69a060e9479773218364d34238872111045b3a259110c4533a2d98ca8685624039a01cd8488848a8c8478a1fc30d18edab9e4ff264926654eef6f83ecd6d25411ba35cd02e367cf903fb5710cf364a2fbada496293545f4f62be02a2a189ffcd80e0aca485d32d2f6cc48ed791cdb5533d2116db78924c4b4a36ef5126666e6187b50d8083f0943b48f5033d0466ada8f44747fc4f184d6401032d2cea800a41af1cfd95e3efe08c1cbe5aba01951cf84d0b2675dd4b396b5d00d347eb2240041f702e1ab66f469aa49268e8a08b978d3e4eeee6e775721039224e1323bb7cf8deb3ce5846e935bf3e6ed9f8668ca555325fc50c20f5984ac9202ea620141f73dcf474f8905eaa72eebbd238e4e4d87524a757056cca9f5eb34b7e1e8f8ceea0f4b70bbbb2c8fba76b89c481d22bf9c39915f8baaf9208a154504a55c43d4c7225e607676677766676676afb150e369a106456c8a2390581f77a03d7a23120b78109e7f1e8f3c9367a7c9de259eff7f1e5fda6181679b3b7ec33bcdd3c26c6b1ff3a9d41441d496b400fa82871f9808a5bea281f2c840b3f907887fd88128a514e88789fc004d77ff719afe2939c63ecc3eb13f516f7e6143bb45a98bb5a36f5650a9dcbbf8a09df84d6e2e624c933d95e09fbf7371b04df7418fdece30b703fdcbf4b82bc474ebd4a44d7b0cc29529d746b7b6da58afd5bf2fd336627ab5a586a0278f8996d45bd24fb57ca1ceb9a47f7b759630d4fe90674bddfee6474656b7df19cd48a86eaebad18c92d4cd6773fb6fefd2adf9dbafcc06841b76288285926b89134860f1ecb25ed014093950fe0ee830ab22072fe020ddddcccdcceb62c540ad20e2c4122d6214394110314c6f6b31e0d06464440f458ab868a2429644142a9210516406126858f213daa0ee7b1c6b1e19c6318eb14f73cd6db1e6d9692a22abc74393a7d960fe556c51cb57826e1ee7799dd771dbb6b9bb4fe6cda793208313473b14b5348184431bbe4e23d34bee73415dac19ebc00721eeeeccce1b4f66f776253da91d014612417c3cd07dcf4ba57e64f0191181388c37784ec42b8a9408519188a00454f480c81731081a628914454a569820091a9e7c5794a0464407198d99d99d7dbabb7378c40a21b57caf1ee1dbf438cfebbc8edbb66d7edfdc260f68b948373898210521995008a1b933cfc9734e9f93594da8b8412d7fb21b75ed535a9951f76f7cd53a9aec6e1860e4d3344ecbe9d636418488466d76f473bd719a6daf69a71a8711ef594f4bc5a880f21351e0088d2882848e5e30272087a39a0d6666f73ccf73f6e9ee9b3405915aa650e09344b4248908a8d5b56c752d5b2dce61b444cc0aa35aa66642c4c2f6be267a33bdfbbbd605922ddc87de6cc9bd8f364d36c77936dd363b96f3fe9bee5f990e4258eb13ed0889d6b414122d6c9e328aa0f375b68679bb14de4057b98b421c3d7030b033fe2a4ae8f6b3396cf20183073eb035cba1c0564bcaf3a8bcd3dffa79bf4223639b9a7cc8f89e948c6779fe1e984f7d8f8c7f7916984f7d0ecc987a1e735ed8c5260533aef7b7fc0b035bd39e4baa49199514d1d5e46260c579a2a48d20d06d3261b174f7245c19274c4b5b33756bbde7b8aedbbca02ed70a3a4d2ccc1d1a45481a8dc6756291d3eccbc325a7f17cc543cb223cedd74bbdb494fa9c7bdd9d4be19e6b7323f3cfcec0bc1bb613ed0889464b21d174b6c6bddfddb1fb1c705c5fa57ce5cb5b4a1982da8ddce6b51729c272eef771db6cd431f55b3be543433ea55c4019b56c847bda743f25e81c3d1fb706749f3584ced5a4ab28a1deced20f1ffefe3b3c5b73aafe18d89aad66becbd4251c4d93d35b4d3f2a45a69629d269fee43852622d656a7f7f9abca8142e3745b9746846020000d3140000180c06058321915840281c2d7a7c14000d77984c724c98c9c37112e3484a29638821860000000000002a008188010df3fbc11416fc68e1939ba6d428385c039439c70c73e9987a22a438b8b27cbd3f0ec0bd2f1f22d8870c8ec036211322c125d046ffcdb2a9682ecfd7848c359941eb62eef31ea41a0e9b0f22ecc16e6be837be6b49fb4794791d7be959424e05a7ff7975cca5eda5be88d77d379a1029b74aa3b986c2e6ab6052ce5e6d389b260c3852d523674af5e37e735140f685ce331425c46ef50458db95b84efe0fd76345e183d6e036bb9725c2e9d85b0a114569fb336e135508a236340e3d4f9a84c68fbdd4043d39cba62339f6697f30b53d7440adc6af45b42a9ef1c7c420053c20e4b87035ae92f842a1980ca84a01b4146da423fa5704e52259f53c57affb6d941f5ca24f58482a051301dc8b753579501af73808271fa9c0c101de25bb1341a86e21ba0df56907a5f7602ee0ca6f61158c2e1171b889bbbf67d5decbf929e574fd363e6f34f6f033bbe9d0ce6ae59df543f4b5ad0f5cd38eacd8882e9400b8ca96134338d0060ed4598b28d11be4b90407759965c2031640a104adb086765c590900c830007eaff2eb4dc9aeebf581a4dffdbfdee4d2df10eac3c7f2dfd6ff44e8faa60729746b02a1964910da4b533abb72d90939ff7afb5f288cbc1bb2c8744846e69967ea7750d08d87093ea4586b234ac576fb484b9a2b67f5000dc66bcd8d11629fbb0868d2861964711ed1c7088495f57397de8d4a309629a1d60c37c9111f46aaa07df2f60a789a99d601eb52b2b87eaf928d464531cc7e616f056b63c4425681df837349e18ffe0665ae9fb253da2fd7f7ebedaa7053793adc4433f30d94d30558bcc756befd89445c16753f59b64fa10fed62d23c4cbcca728eb1fe505c37a1dc8238ce0b6547026e71310fe90e73d0c730e421eabe4ca58f290e85bfc7207c840ef50cf28491560f6d9d8b4b19799f6d4d1cbf5296b7227dec1b4af47bf42b52f3b52852821db91d977c65dbb011e82fbb65e80d1b6b753668d8185d961abc42463504faf64a8ccd40d40da7a643e0f953cf77738fae3b8450dc3f88744e504222eaa0c036d13661f55d427d44c2b46cbcc2279e9fe2d9e92494a6bbe651ccd1d5af1906c83f25a542fbbecf013867219334dfd11a35417be63b4c2bf85e68ec4c21eacfdefc7902456f12be23e185e177779c3f78d9a0803cfbd8dcace043d3c748d10c6cd1fd9f34b0f55003326deb343fe8dae37e632b0803713f5b0473dcfe09f2d421053924c2eb654f1ef0897079a1909bec637fee543fec201de7c8caa3ee2046af66d309015204a001c4ea0f83865337b95722c98f149e227d09154853184e3657e2f15662ebeb3477047081690e22c62b91c12207ffbd4acc6a948974686815598c5a787fb28dac43ee0d361bbb0d3e945ac7c283e46ad40634900dc1350ff6f9fac9c285b9595ad7f4c281831772578369256fdbae12c7c01f0a86554d72faead2dc2d584589a82fd6b3739ae140685a093398e39ab6da2d3aef3bdac73a219bce352b3ed8a71a64741e8d500f011dd18ea3b2a211737d0d6b9ceeec07f7f58ab2a8bfd17484cf7484d9f9edc399df64d1d8329e6ee816adedde4596aa0ed2ce129ee8ddda18fd757f64023078535d1c109bf4eace3aba2b11e824656104e1bbbc0ad1c7206f3255041dcac6317b8cb230a81ad5ad58c196afa96b160506dc04acec05d3350029c34483d9b8990c9d32aa309adc08f7b491adcf3e47a45ad764f6024d1ec84dc78dfcf17038cd800167c74bd155f586ee9a626db3ec90c8a89cc5695601388dc52059cdb936c6c1281642042e301eb352ddb5d6a7af88ca9bd6fe37567816108c9eab58f80525ddec093759e7e9ed9d5f14954a5b9ff4cb93ecea763485445cd3ea8ca0ae5853ba7ef3fef741627d1fde17d3ebdcbf5f48bf031a2b2f27bd360a4b536e4efe4ddae0ee84e3b314c11f98ae123c429195f4fdede52e9e6a7f7c0d867ae158eeda51c704bb242a5548f92743812c2124edcae58c59b47cb3a6eb33ae1aa8f309153c7bfdc3c07f5f9129f16ecca4e9616d0ae86298611aaf0939b63e3e16cc5811e971dd290654c5506ea473c3c5a1a21434f1e1dd52a42951a9923228637f30edce85fb6e42209967c60848484b5e8db2a00c53ab31863cece850edf8ca16109583c72b0dab416c0f9bda585e091ca3829c40c0b9432203828fc4b3c3db08ff4093bc61e8b02a22a75de6e7e51fe8a4ebc88b6217ca056c90ba61ac70fa9372bfad57a9b937d3aa3fd8088df73cc272f4bd6b96fc5aaa1dbe4a61720dc781225d90b673814afa0ce53140d51ef58cdf15e7533dac44f8d8388fa25a89b94f235a44935f5e75ab342908252fe5c5c0ce5700a8009cb8061de7a99d0d6a56df6dc767e725ef29978d1e62294b940a6fe088b1b9f29f3097127957996fdc654a89a6e4bfbcd04593f2ff565b9e794030d3d9d95ed54703e7a0e4762f4a05f10174f4889fe5126645622b1e311eeef268d62ed3555e1c38529359b29cde014619720c59c0d2e8f7a17493a140ac916335708ba24eaaddf103ad728f2e7a10b77b5c9a737b76026b17acfe11e6f6779852dbf661d56762db623cbf2b8050ffa974d53dad7aaf9566b919b7774c0efb0212a41dfa65e84c27bd2b5ca9ae31ad02a34c7a00db57b5b2d81f113350a10b5fbe747f8a51f74e02ab8b3a6238e47a8b877c9c63a66219e6b0e440e35ef9379467501042493ab185098993d052fb57bc502c01e9f2110c4618c72c4678947ffaf2022cc0d86cc64634f68bbefd1b0fe8a74ebadeb1013db6b19a730a24f0409a85c80e5759d0f8d225288e0430afb41c6f48c8d9bcc1d6acee1673388346128589a3eb01e6be135d13eb4c042ad5b1fee5fc7b8407ad6a8ac11778a785105e0da8ccf8b86155908791f15f11c93e4dfc2c9617e4a0b246a3cdaf7d7c8e31800d588090eaaabc54490705670e4f726ad1caacb41120cf8062cbf3e00433aa2855a9cd4c72aaaaf9d85c6f015d7001194346ce6a9411a74fc147068890c2715d6fcd06e5d36cdb157f6e206062edce0499fc2468dad53d73bce1016f06a5d534cb4b9b227ef86445db74de10271c7a88a014c344e6911240ee78b4c1621e1b1f7a87964034a6f5bb9a7b5e8d3a7931a1f53a748209e099b771964db42dfa653315290639f3503b06347def8d35d579c9e0a6fbb0978615f728d1eeae36e6da27f945cc05c8b29d2b0752b68c04880232cef1f964e66818f6d1a2a044030d23928af467772af42de8023e2f503a37bc2972e2ebbe8cbabb05f130a2f4db22b6f4452ba201ea3c16d9737a898de8413056b292d1e93e18b393624f1b6af4982db65dc955ed442d92fb2d4c44295480a50f4a6763c960f656ab6d82737c5b4764317905846e2967fd1fa144fe84e828ef904740b2d3509a15568fce0733469a0af51749040467c9d8abdf3ec86678da489a86c51ccdf20d9bba9c9a10a21493acefb89f4124a01ae9b5c36f2a21321b192b18c7910a134bbcb8a326d3a6ce1a65a4385aaf1b0b5c1a8130b925c92fdf42c98eacce4d8930dfd0459bac17a15c2275d1f0e214bb9edd2b674fb403bc41598286f41ec868fb086ebf84341617d1c820cd5301caa7eaa34906278e4d4f4011aff783948690480b6e30b670a58955b24a82f8e8a940a2cb59dd548066e16a04ba71cb36f78394bfcd1453f49415dc2855ecfdb4f42d28849ed44c9f51e23a53a25ee003a6d933cd0781ef91d7573db0f63ccf87cf0ca26be8495eb1e06d104eea5a87fab87cd974c1e626a745ef4685de7261b4496e5a49462d3b67568ca821d8f2f65c9577f6fd594ef10a414bcfaab2d96d556a4f8fffd00cf0b3fe662de8b9d178203e0c6d861d95f4c70e8913a75b38f60ab00e3abb0aaf7b5de3629a8d448297982a21e20a019fac1db5e10a33ba3c00cc301a40af6cc506deaccb982b981ffb64f97a769b91b4de11acc8ffd8694e505899da04900f87f65d37986004c1222a81ef06be634aef422a700bf783c7b3500b2398d3ebd6024a70cd67e3ed21f1c2c27668981d293d9b0ad3c9b59fa1a2b38b32c5e18ce0e5b9ea9491807c5caf9b7405f5e6a292ab53334be0f03f8d750f7f82848de80519b34628e62fbdd9585c772fc459802705df60fe0831dc399ac70db73c6a3e542e320c9fcbb80dc4a3e29a010ba6b5bf5f4cebccc06ac54f1c33407e39a45507e2cfb3bd5dc2e451e36d7e1b5950cc3640840e89bc45c0174c59fe31a22486cf2b62dec2fe1a9ac65ee04c82ae9c3946d6ddac1a8053ec01a19a5cfab8afca6f3e0a7f9bfdc03c568a5f12d166e503659993e619d3b145f11c7254b8497961848cc62c47714d43cf7f7b84e643dd1c2c363b73383393b10324bad722fc410b60c6d38b44f009ac425500636acf2d180b34acb4c72b3b0a31f2be2eada2c785284742f21b81938ca1a52f7e3dd27412434d316947f9c2457ba69b9c5ac75cbb81ced1dbd0fa701a19c76d3942fa5e381f2c0c4f274cec4458c4987c3d8903458e47314903657956fa29af88a22cc49cc08ac33a9678c5f318d4074689d12b56c90daa79cb65e40025946822e6103e18c8e9b8910e7a59fd788c31fc30d51a9734eab0f25e9090e6a26eecbe8da317d7d8a8b99a60e2dbf698ef4bb406d391976a69f7478027dd3d5db0ca93dfcddee1b8892a4ec8eb8ec66fcfee2593efa570ee13fa7d26b7d7b6145899bb7c0ee822460ab2aeda0b219cbe3d678f6e3de043e3d76d1fd1d233497dabeaf31cc47d48591677c3033e7b0fde8047fcfd1d12415b3dee8d6f06199ec55c04904dee665234f66f59ebf7ba840220fe5cbab3637f4ffa9e8a9c59da675b25001136619807f7a5acd1319ff2ce814bcbb01c3928bbc425c40caa166eafb78278b116879c98756018b8bc8a94922f4a8eeddcc4c5c9c3de741deb995dcd50da11232bf78e242916cba97ea1fcb7ef479d55209e6c48913ad83c8f110446f7a1166c44bf180f1bbaaa104158ebbad2ea2a4236f44e658f9821884ff8f90cfee783d4a161c9a0d12386d3e27fd98a27448748ec9612ba99a66258300558863ae49d1ee342b9be15b06d4a4de1246d8adebb57ab312861647ed5ba9034fd49c4971346cddb1b47501dca38fd799ac04c0cf62a765cf339815d62915197eba18fc5959dba18e731419e55eb081613cb29db10f4769ed8c796a4fa5a2f6df7708aa7ad6b831efadc91b9013ad3c4c976ac2c3894096a117aba338b63d1c61ab4e049606b054989c751eb89c4bbff00a5aff4339b6c29e421e330014253f3358bc34926ada2b54bd483e12a9800e9297e91bff59abe75cf90fa2c53779cb012fd061b25e5ce26370ea529c42a5ee0bb88961a61f4d3dfeefee4c03480c6870bcc18e42830b5bf7028eaca7d9f6c3d50378d47c0f7b354ddd9a260e9ea118e411b644082e9a92994e94e665bca2d0670db440672c70b0027a8ac42ac6437f400cd99dccb6c74089f382f314dc486a2f5e3af36915360642600f87070e3bba4c06c6840b2179d1a1003ee9842fecaabe753511835db8df110998418100b370cb6921e37949d9771b3111c2dc74a86fe276d68619a752f332201ecbf315138f377eef90c7761d78c6e268ac2b2b9a9299ca316065f6a1b75defab79ff4aaa3d1722a406b0fae6686b6ba8ec1a621f58644ac702182bf5d9b274b863c83c7c608df188a437eb6823b2049135837851a590c1c728e5b745788eb0f4b5808975b31701f4941b40ec6e8133b80ee02a69e14e7bfc1149fdfd10a62a70fed82cce1e707e32ac6a11f59ba9ded4e25796024b1c729b0e9eb1a9e5f28f7e29ea2a7f2c37474df742470a44ddf75e180414b8a10290cfde0d97237c67395e942d233be269c6410554e2dcc5ab313af66b608c2aeb861556b383ae4629ce308778595f389b974b24f5dfb9cb8ac9019650f80ed15f94c67dd048a858f6ebbfd8551b393bbfd275495eaf6c4229bdc9bc885bad1a13312a8c6e73cfb003b18d924c02af490f4e6c86d3b8cc83b8f493a2f89a22380a5d9dea0e47a68d950b697ea7bb8f1a69878b6d870f14b99c446cc67265c2c78152dd674e4ad9ecb4c76b62b77c0d0f58655eb1b1a0144150a7926bad4a49c39b6ef8af0218c05affa96b0e31ef895f9ea0a684c072c18cdb7c3a6d833230eb9a91712fee75167242de473aa6e5b35e6782982ab068a5984aa944c7e9c85bb1ed8cbb05e5d140e0736fe3b4b774fb72428d714a7dadcc9b5779e9b7ac2c22d0e35471af7d2a3ec91bc49b5b58ed3c85e415407df96cf8fb67634b8b35901f299d421f8d7da1041f09580b2babb23fb6e8c93b16c1ce6eae2c60720211843db7a5f857c7b1ac0a4a00515a138934bbf88774314ade4b2beb1ed3f14dbbe19792a026dadd2c3451881689e228cd57800950e378647520f372b9d0b866d953312e1b8e9248cc12951b4cfe3e32940a3911efe1773dc191f220a154fef99848803cb8784cb8d8c882c8bc7c15244251553d13167e196446b554053df7da43d06042e5ccb7a30b12a6e9eaa6a988c2f6748dadea5c6ee8313657fe6ec84d5567cce4b24ccd760fe080f4f465aad8147d8fe1a317803c6d2aaa841f9e8e85983d9dd9ef13ea14b104248559a6d4a790ec178f57fbbeb14601983daeaef49c06b9658d34599b596b548d7d161482392eec030769aea81d1efc9b2a77fe0ce54394775e9b9fd4aafbd44db4cc79e8787c862e9e8b3c794e9200521abc41c4952d3ce651949685340ffa65219bfdb6d9801c26f58c9eb53353e5d4d085720e2d445b17d90551572648b6941544171101571e88216b74b077384a465568801c5e6ff331bdb352f2e97a7539c446949560dd1516b092caa3603a946218a40b8d9fe36957196de6869564abf3f47aa19e833ef78e90ab46e1590a113ee67c415576651f3e91e76481e1919c35b12d2a56755b8e5a44127162cc2abddb09e09052529cc6cdeb3e58cc03cd0e14fab33d0afa33a93e170c6a0466fa51114a1f5f3768c1f23e4815cec692d8662a0bcf136a623067a60f1c9093d6ef8cec51d4b3f65217b9a9b6f8a5ae6598004943279803464c95fcad3a3a000fc1f9fbf002f3d26873b4406d6224c261085d7fc4c1ba9088031e5b0e5f1f483d7a1a4ea80da9083a8d0bd1e397ac591886f855b2de7c375f0703b5398e0b0a3440b19f3cbfae6e09f492f4328067205035224b6a4fbc44233d78f18cb43a13970949f5834c4f40b1495b8e548efa78bfaf29955bdf5746e76aca1ac9f4b15e4184ecff0a35fede4c1649c6993bb28136b88929f0dc17260419ded7ec09d8d1e19b4037e48f57d2de6ca730eef147de7ee11336b3594356a2ab2657f2b1e720e69663d3fe36882c5ce9daa39a988880b0d1ad0fb73f660e15f6ee0e6cabbf6624669964f2d1207bbca2bedc8997697472588cfb9bf14f993adec19cd118909c29f31416200e89b843e74d79d0df5c610ac3c5f6ee48889c7e1fb01490cb1a8256ff117f837ed28fc761e81049eea7c45f6d130b29c52a065645100c4b000bd424249490a1d37b6443dd88601288d22f39b894501d4c1c8b64495c2df3d39d7efb21540f646cd9be060fc7c389e023752955d64bf53cf5da8b7fdf5552194bde3925aec7d23d1b46b814bd0ab50e82da3e777a1d6b278b71ae994a0ab2e140e14b0659979a56c2d45149dc04231f9b1dfd1942fc36a95864d4fd4da580e187c3b36e400fa8a70f193fdf727ffad0d95248bc1e2ce03ec11d5d8d3e1e32f331c047cbcf737da00bc35460330e473ef7166fbfc75dbcf387be533b00e9615d86a430fba7663af55690463d2f715a8715333b1ef6aa2e0170c4d2e3e912df3221e861128efbc10eea160079bd593ec5bf4af22eb648c8b45bee1b2da6796d50512177a8bf1025f1a4da4a144a5d8341bc40d4d8837327f36fed53eb1eb9e690396539f699cf9ac483cecec692175d619371b974e3ae5de58e2dc082219fcf1f033664986f15bfdf4941b48686c549143012e42f6123f4d8be8c19c510f3b506a1b68c1eb5437dba20277c11d94bd94a671b2f0f071c5b43c3c1dc2005007022e4c1b5c45564005f5bbf67b8a09eb06ef25b36b38945730f1d903fa8445295c71b9a706212cd02cc04c9a7ba73025dfcab49faa1776fd64cc2419501071d20d37c7b001b5b0a4b21955be26d966eb4a731ad37a0b9c8cddc0cc27def34a06a00cc8edc2d982c4eed931cc894cbb3f4cff3933b7151b71dd7f132a195ab05f9e420f3f6ee5a6bd2a189231887b9bd3b46f3a7b8864df31537c50ca7500f13692fd427ddb1453dbf872dc35c36a7f88bb69668d8672b9b48c3bef9e99e9a5e1e4d2101ae32bd079e144039325070725f0609aef3c552d03e5fa17041e3825db33711064a59eb06c2f9b7e36834bc715a4dde151641832f11efee1219db1419c1000fd6f221b4ba9f31cbad579905c6ea7dbf142c9da8950065a69819f99dc4862146bd2ce2d48c2a83d5ce0b1ba64d7baac7fc7a87254fd1ee0f762e0aa608338393eec2424f6fc169a6a6969a6a682f07a08006a03c797c0ec2392813cf6e75fda81bf6c3c93e844b61747a1c5d72b3bcc9982ef8af861e5299fca2ad589ec227ca8b1030b63a8e83e4bfdecc7abcd1864be4b3b45267731dcbe4e8d9752413689f2e1c50f009f438fb9ceb0e39296c816c124d44caa09bd2161db0f8911a094c1b487471575d552dbe1272e996a0660d2daa49fb03dff9b1a1252ecaa70971217b4533a0e7e59d8f07871c69f8ffc3399cd04af434440a8c30ffade43a287eb3117bc9116626f4c1005652d28f5468ffbf4f4a3f17290e27b06c1a0f4a37760122d4c283be28dcb9febd4b063c1a5343f134177e152e99bfda3fa150d25c15b6a18c69b8a46c953026731f4721853fceac236415266e898b105db0a3121b4d682d90f44770eee7901096b539863155e3e28b8fe235e5d474b4b0529f0611f060379a3e4f37d8e0eb397c932a01ed678d9018242fe6eb4b5d36be482b957c0d11e7ac0cd842261417289430d12c5d081227d207facc291cf02d22a75087ec0d9cbce192600c32fc62c5ed331a8fc5e463dba0d4a0711a1545b4a50acb31a43f95991d9b746d162c099f7fd8f1221224a8c416fb84a589056def4002369655ae7708909b982b4e7487b6d6089d9d0a9f7bf113468af5364ff749831a6c407cf782f2f99927150d93ca91b8587ef3223f2693fcba2074ac93fcdcadb7e89ac564c4d16a83975526e813790aef8851ac4b6adff1e1c41f84ba7bdfafa026da3e291802810610d78c34329825710724dd9a5367515d5813ed59b5c8959392ed4c462537da136ee3695e2495a737e5ebb0508d569ef820045d693719f549346aa410975f73a1b2f062bdb21da90df7b420a55a0b5948b63133ca6bc586d5c4117d8f1877f3f13832b0ed040127ab0873a05d20fc06e857fd5d43400a8e6623e5253e0a8ef4d85087bde4fd177122448e6abcf6803832ea731aa1c95fdc574f60328eee7304754f625f27681a37264897c84df8cdcdff3eccaeb95051646187ef0b716d64b5043189928a3710ff9e2763b91841ce42b10489414382b319a65ceb0a66571213ca6d2f546df4fe7d8668188389035e5b435d5d719a83d8c44079dfabd196f61fc60c26fddf345c7214cb6cdc80050a7a1212e9cf3032be97285421af45af006c4a28bf674e487d13653d141eaec1b729fc085faf2d6c6f3dd8769078bbe3aa86fb8b4258f6a344a2cec17070dfc698413a5db57ab9ed6ae9850e6b8e460b6d6c08853d287950af928d296fe4bdc7ef793f811a326f74a23eee7166fdb83971e174f140f2d243c9f98a33cb8edbc18faf98fe2637196898be92a3c94aed3de3b5a30d233ff5b4a22600a5b91174c649e5e956cf66becf2f9b741132ee7f8391ca5ef43d3f45f96f64a00b50b9e087589e5c15c2f42d57e0a95e1ccfb449a032b6f75a196323eaddcc37f24cb75a1060dffbec358a00b0fcecea97d04d09a50a578f14c92c71ae60ea816c4b8daa0e43a61c9ecb19c2b557b2637445416e91b1ac0d7c6bedf4cf8298e1d57dbbeb25a25e3321c2af5803a4d1a14e3921e4dd681ce948d9ac27b82a43f6f23119b0de4ba31108cf02ec93c53038a7163f2539588f0262eaee92e66ed030cf299fa03dd74a3f0571c66b5e76f95ba204de9d3b955354f53bc7509dad7f8e7169de94c534c0cbc3bca43e853482439b71d5c67a01bd0d036d65d76e5fe1854d0e923985cc151abed7e4ae614cb4f20aa988924f0b0bd7ec597629640001583632bd388419db9e27947ba6e93427fc3082de2dd24a2546cf3b7024f9eed1b42df7a56b588c888e88816a1dcd43df2b0793856693bcf97abd227ed703653ece68694f8d2c07495ec490c722d02331b960d59c9c0fc7ae2b55c4da7ed976918924dbef442795c2cc922f031c995bdc79173a291c0e13663f964288efb98d839289a615f8ca700101a22c7ba52934bec4f54fac46b11f955469bc14bed644e40184d12a353945c624a4c04f2f8ec36ba18b1024f4b01698c1e5f644983216ce2e3af9a85e2206a5c683c013c1e9c06ef95eff5ae4180e3c9c923eaeb40e7b57180702cefb6d368de9b81f2f6cea761bc7a4f55fa60eacb19229e5026e68e0892a7dff4183db1ba46ce0bcc19e0fb994accd11e87915984c1a508e2c3487fcf240e721b0cf35b1439a51757118b1c1481c0014e1c9d78d7303623d9ee86291ff9589d9a82c7e2d28b14955a7e526b096a8b96df6bd71e7dfdbe6a0968bd9d283bc7b347c39854eff2d18407e77e6d4365230ae1fe5e3e35ed5f49ee1e0b8465004dc2d0a3a559615b511ecb0c0d88487908ad1b29f9969cbe2935093c030dfebaca2454ee37322224fde714d23e4262e08f87f0e063a0bc9fb98fc9e2aae10812e2202da38311851983a9d9c901408159b6ddd435b87e4d29698496557762d9e16bef2b71260ea3d507a08db74187c1e8270dcda32bd8a543a47b1705df594dc0d1cff4e0e3146a0fc3b0778d912e4c8e34b56ce63e880558e2fe6263a4f5a80e963e5b0ddabd64c5bb73a6cdfac1bc260447d243aeada03a64d8dd5f094a2636bf62421f8c25d20b4b26d913508c9591420143211f55929e5b539882047029dd47d7fecd7809fc434b1c3fb8a4a940e9115d2081023f38bc76faf1dcfa48b46b1e20e6915c18ebf4328ca5f54858fc2f4816df280569903e81e6f68db31796c12d24223487aa2a178297a14e4ea390fe483bb8660f24e962dcf05687402390042d30a2c35818fa9de9316b3c79627400688daccb7d23d96e6fff42d7f63dc560675861cc35f5260f6236c922dad351e69ccc0756f8ad67b6e323a13faed0408200a0fbc0dc3780b22e7677cd3b232237aac64f862f33f64084ae221348546aa298c789a0d17c1caf968d3a262a08ee9bdd7653747dcdedddc3dfbd79be29c625f919f786811dd8ea280a060b0631b69941e50b0085f1dedd87ba954b097f5cf7304b2cf63160351c78fa4ad3396b4e58de021136df7c042e51440bf92556677cd630be115e14070e272fa0ae6a6f9fec24bca37cda4a40ddc37c9c204abfa6af193787b6718eaff64c0ebe362171dceaaddc6cdb3b88d92613cecb7c832ab7ce503aee2a0a64ded8c213b91ef35556b84f542792f9b5321002197392f180ee9a78cd21cd98333c305eb1f53372745721af6deb742a1aa622e7dc1964e377dbb9d319ce33e94d11a5d211964bfccaa969003e1d533537ea2e52d46f98bf8917f57247a4fea49c91f6711361f04bcbb320dcc97ccc81c84eccf956111de122cf40fed5e855841a1b4546af842fcf0a4d1645c3fb9505e887ccaa61389e4825dbb23ba77335633c895b41279e46279e02b18e96f566753825a7fe98c2c62fb9527edde51e43ae85263a1ba44096ee8135f2030c7efaf90720e8a7cf44a58953d3d6903d7390dd5dabd20ee242877b680de21fb206a75bf68834759d4a87d31dc2719b513ef806da4519b6271411bfe9afc5b8f7b1b6a0cb0ff02895ef908066ef2609a9730be939a87ce91cbb273e7c442f724593e24b06a9ed26d1ab4a009e67cb218ca5798f35c26ca5b71a2b065c7f52070d5f5f6ce7389f3654b49e888bc081df70334bf20e2c7b2276c07dfc2dd78e0fe6f260f2205c60f882f14180ff33400f5b9badac39d18f13ae12cb7654028ba0d88209d560d02dece6ca161f31249b7282b149b84d973de88b45044d236c23861fd6bc3884989f8a667dd7226a65b7419a1be57b9f50d40c73006ea32745945deaa4a7cd2cbbcddfe101ca46c72129a295db4c91f21895fd63dd4bb9cdaabecd500475633b252144fc64b93ccd6815bbfa47e73833511ac69fd38559a9a08fe6bf67e6197f2fffe35d51b0dca43059e8e54d206b7ff5fed050e71462428f233764f9cd883067ff7477984140b0acdcabc8ed97b6c001a6bb506571f5989e750145cd7182f8217b1e786469987e171b8dfb6007d39873a0c2088b278a1957d20d06073cf723b09c01008c52f118d5886749f0625dd612e5681f8ffe209a0124e6d0df07a9aca39029feb3de5840e3e61754e319a7628628ecc7312b19ab64cba12aa665c25348be574315432a751907eee057ccb1655b97718795713db1a76ae05bbeccb77395c9318e8fb539bc6790098a7190775ebfeec78ad4fca06954db4a18275fda419023f85bfd0a2fa705d335333ade35d661170fc0898a8f0759d3b2bd097a2080119db3d99493a626e3d0c5e23e797225824442b5935c28e2223020639764006eef088eb8f57a9d129859025f2e1d5cf16ecb8a6bc6141866192d813765ec3c215f2cad6c0de3cf190d94da301551af1847db2e0796aad32049ac830c25a10fe15fabe4fc74af39f9285fc19d6be8a76e55b190609581c8d070d0f708b8230bd269ea6c1f2d7e9681009511c0c9d4394a90b6548963b35399633bbb9b054a6b36c44f28cbb1860b1fcf65998b991c981b528b27147e7000001ef66a784360cf301a1bea9274bd7ca70baa9ecd245bf84fc825de6e579c629aee8f7ec0e867b30f742cdc2e45a9edc8c890b5075a8bb4e7c2df6c7e4a4159c989d941d59451bb67695a00dc60474134656936efaeaff697739af4a57f9272a9a6aeb2507b4b536be4643ec2189681bde910fe99dca4479c6681937a77e4f1432261a064efdde8819d950b5b00a4bcb1a4eb5b1a696ea43aca006ae917eb0ff5922430eb1f772f6b97ca30a578b4ec97585ba188025fa12ada180e563e3387a2e2d875e6db425555f31b79dccb1475a24fed96d52316aaf6a5cd932f85cb107c7f9824835859b396ce9302b104951c9c736befb0704ce8f5947894f4bd204065d4faa47f212dedf21149a602d261954d7cc52a896e81d7b578b381f9c0bd7694ccc7bbe1806537cd04354c002680976308d4f637af2d4d988beee962611a905c8319e3d360445f3741e7977eda96c0678465a7e08f367be9924f75bfbdafcf078b89221532a0bf145e6b5b9454498d4b35c2f993a346b39bfe603c57969a17083a49d724b09b6e2b92adf050c6e40aa8f90d38b5bfe7a3385764c05096cec3adb24e6e29fed5199b2966911bb70dfd6801ba3288ad9728f00ebc8aa431ee24fcde9f0457780e88a57a7872734befd65c282c5385c13cf1b7e20dea9f92ea843e015f2553c27a8697e0de286f011d7de2e5f185bba452553ee65bf820a04309bd75dcfd79eae5366060f09a9836a0723c4e9beaafd9f59ef4c2adcafaf8d0446cb7f84699a7efff1d32411d807e771e2e36b7156613f36246b20cc94ab67013d613b6b38cc7799445b435f1f8c0ad3e8d2a051575de7f44e10f00f320e664aeff8d9fc5f4ef2eac3b64a6db536b18d5e135d0dcd30746fd57fbbfd3c5c26fd1062e76e9594cb2dcc424cc8145025b79eff727ddfc86b24e3bce3161eb5a3471a1a60a12333c7c49496ea072ebee09659f78f7ad3dcc29bb7dabd0b1a4233f623519f32b6604c9feb7391181b2f6d304024dab983b833dccafd795e83f1817a87d00618d12008456ff77f440214ba82fc88143e5ff403c07a82a3fb39ddc2544d7d45ed2ffc267034b3a60291be53480a266152a8a30c16789d4f90217a19f7e5b4fcbbed992bc6b064bf494888e01b2b91d04d362478b4f6a653f4b7bba916655cbbebc8bac47745b9a16e34e4c709b8b05ecc39eadb585c847a02bcc593d964e63c423e414ead3113cada04b6fd6db9fec86f951f3a7b51193ffd63c8f81dc27106535c05c26c0efa52303114f43ac43a16f757a8a9e67f4d85f1f5cddbc190dc4f58f6f6333e0fc847ae275addf512e75c638f9bbef4461a0be4eece9566d315e9aca6265c8ae288fdfcf474c3e4fe3023cf1d4fb04e1222aabb1920cc118b7f489da1a1994649d644482b00764d04064ba7d23f054957b666d8012eae22e413485bc2a8d3ee75fe0a8bb80582f50ddd3f5d6751d44c63f76344f6d220aa133df4de18d86b5df2fe00c6a2fdd0233b1849b5a644dd3fd3b3d137f1a4597402c6faa9fac072a9f9c55106cfa8f4a36d3be334585445be77da1e8c072b20d8da1d464ec5053cd0b562f183cc8d8f1a1363aac40acef5dac70985f2842507870bf9dda91dced1a5c2c9a74eb0be67ae46e4ef49945208933da97b2a177ba5525859524f4c394295cf25fde937e1b4c02441d128a4345dfc4eab765004af4a97e88343dfd3e93521815972bacb25ca5b7226feaa98986cb2a1d4fa6634f04232adfc92cebb9f66b7bd5373c4a37c323f3301fd88708c52a01201ea30e6194ff2109128b318dae1af48bf420f4afa8e5b18236acd8717fbb265a7a72bfe1c631906c4b794e707b5ba2f94d243709a599da6e28724bf5a080b193315f9bb3f268f3f0a2980aadeceb715d091d83b5f048556b8c65adebea09ce19c6a526c00f44f18cd92a7ddb288bde3c681a513c099031b9af5da8f94388e36d31097f1dd3c128b3a88d941841c5afeb9cd295752766d3e85353ca02e3fada6f6c785d63f715bbc51cf480b4861a3feb90280b8b1276aab953290e8c30654f6fd3d11a6dcd1891dc51e6a51e5859a49c7e1fff56aa0fe80d9eb4d97cfca6490ba583f388702a3a41b23787d1b4d6aa81546e6eff9cb013a3fcbcb115e3fe7e068d8b21c420dd364283e4f1a36bc68e9139476546dfda5982cf3aa138181aaeb04f7d2b2c49276e90ed4d438214bd8d471df05f61c706ceae72ce548023919a98f7fa3169d0d467f982154a0f714c1f7eb547a58e98b57f43c4c5f33f6ca381024499232988d1b58b565ab2435e6cb9c35f25b1209669968f2f587d4a73aad5eb9144dcce87c224f6e78cc906b9525cb50775048c6a36263452d3af46260b8f72a15036431a1e6830fec2f8393935609f21f119798baa429fc4a201fd789dbc597fdc1691e8114849d2451cf3772b9178fe2712b59c9745ea4b8cb103924d3b7db400e3d9ca1bfb912daa478008c21c2345ef9aface9f66000388bfadf97ac2bdd523d7da6f48f88e828bd30a5bf9e5751a096e5de821a194d30a48c430c34da648eaa5bcd34ea197d40854be0e927de87d5e3a93a8519f5b56e7a978271d207eca08f90e0197bff84adb1db5c48c1c899540f2066795462ab2d86a01870eebea1f67cf280b03ba5ba14b0ef7cc42ee7083aa1f373386abc9160c50262d10f93556daca5a180bd1213564d6bac95973d0c9519c0d8559b38a2b334645a554f2d563069e7b72e3d3bb89a89ddda15b31c30c07c373e39b5e674863b72ee4e1fdb42265febc6c16a9df5f2f8819fbf7666f967007effc78408f46fe50f619187349984d3f59c7ed3b46f27bce1d9711ce83e43a6f657d05a47f3f5f4ca39da20a6a947ebeae524270ef6fa44fa952dce8f527eb6bc8818319e73b05a063723d673108e2820b30285d8f83eb689e2eccf6ebcf2ddd63e313bcfb3e9497f814993a251420e79efef3004cd65f44cd16ee16c4777dd44abd9eb8301342b3d53ff223973471d2ec5d2720810eb5e1da51ff9d583e1deac8d97aa84da47e315f31942480d10b8e3f7aecbd0b160a11084df7b12259a0d99ddb6e606f1439551202b33c5bec2016815ed70de6b3009901855c7a3e90c515a8662bdf4827a25ee665ca178c151ab0ef90f464e42b9cfc00fe404e2629087cdb0b57210d77238fbba36f7d53bf5d302580c34805f77a32ffaaa06df248fcd36edf08567e5c99286b0ada10138bb8db9ec1e7917e5303eac1d3b7165aac99d97095718f43d1e1e21f961c8604360639657878cb8d2a988cc6fe14b4838471e93d9b5f4000d6bd16096b047656f0a3c4a6fca24b4ecfc37a1e300fa3b13b437eb3db4112ae99913a82eb91ef2dcebc719aaefc0e0301a1d18c76b31ac25d20d8837c504df01834f6a7a03d248e4bef6deb4e409a82fdbf2cc780073f4c748503d9a881cec4005eac9951d46c53b792d3c6c732168496899510370765aaa9ab611210a35bd7bfe0938d4a685ed62e1ac8a09346973a91a5a8c939eb7243388edb0db00673a351b1733beaef82776b4b567812666fe0114ee0617e2340b0d4f0d4358080c7a09a961f25cfdcc539ef61621ad90036cc9e15c009aeb6b252452f3e5d3f5d3094ef5c23e793a22fe130e3898f7632c0278ad9cf005ac99510a95d48a03afdc33be9ff03cc32c40af01b2832ea1f51d181c14b186f5d155afefd093e31f94be008be92bc005260751aa4d83009b20357749053ec65d5aaf98f595c1f185807ea0ef0ae10572e683284cf7f4dbd88b4def0249eb4f946a578153bd4866ff0ffd085d7d6768c37c65732b9355e67356034f17a9079541f243c462b031951cae285944be967cb6148781a62b03fa70a7d4dbc7a1a755c2b4d1e90b0d47d97c14c3272af5edfa3a6fa87f3c0a80879883c2a4cdc96c406b3e461c7281a6c26a1ea040428e70d2e74caa11eebbac4639f8decc0edcb82ce7b68c590a9b4dda57744bde3d7cdc9e3c274ec5b73db9642d10e3f47cccb4614017154daaa39991191e2f27352180cb10faf3cceab4dcfb10e5234038d9f61c4e06106ec690af1cec6921170f0c623e4e04337a7be0ef7a0ee1230da2734211c5da6a171237cee84686c0ce14fc6553531cacd0e40bf13ab6a12841f6833d39481fde961702522b84588f44be52b874fe68e5fbb461d716d7a9b49a923f02208ab0f55920afcede5c53f3ee39e083c9e01b997d9a6e0f04021e8678dc8f6a3648f8783e7734c6cdc9b8d7dd10a4e79435b3fe402733bdbd137db27667a7266538da8747be52d6c9909721f9b9a13bbeae1c7b014423a14f18913403b0b1bbd2ec02f1485641a9286ebafd37018471432318e0871b29d78683042d07c6bac0a083c06014dee087606b92c2e9219759d7bf85673c7a398e72682dcf681f29cb410db429081be670285e91eb4ac28c70d5a9504eb9a502f6382b9f6f77c250808b97d1f5071b1015d55002acf2f9f3a09681050c58f9b70deefb7addfc0d6b02057f60426e21f6236cedf3d9f54eba4a743f5e29d1139ea8ab6681c02bc728848c03e290bbca49dd959b82ad7defebb7c9d789696dc215215cd533684f108c8d24b2016cf0f39e0636645258475393cad28f784371b83c5c3f7772a4a9f7dab0d241694cafde3a086230b668b27391220a6af86bd93c4264d9a1b676c320626ab14187f51caf9a374a9961ad5064400834365d01f6f43405128d12353200506d6d3c3bcbc184c7defe8346c67f45a8fb83b1b679cec59a613f762c992583b577be8082fca01b3b230b4546301e02e3b389326ca9eac9abcec968451540b68171a2ec2b6751f8218e2063df99b88ef45c76447dc1c6a6bdc886ee0fb7322578d10acb78ed89f2a9a06890b80ad54e0b48a6dc8ac41c04c35019f06a57bda24a7866e461ccf5055832ca556880bd87a418065eabbd111f1f6006dce20aa55efcda4387ba4ab633d31679eed833ea693f82c6c6fb7a9b826fea1b3d3d1655b442cc4fc08eed39567688d5a10178a766d115b21a1f2e59dd32e0f7c6a0d7c4f06de1659aa683b09962e31a863dc582b2946a1de2fbf5c5aa4d01df379e4a7b78ada380cdd52ada2fd737e043546c941d1407e156953a217cf7f7711aee380bf4a8c6bdd176efec9010a614074131beec2b52718696f623212a6c01d18ed0e23c6b8bbd3fd63e531999baf804e971e1de1e4dbb439446c59f9da1b097a2a95ee30bd0b2c7bde9a7d03c46d8e6ab01d7a59e5267704fe8d4668b5c82fac7192d91a60d547b123dc8a8255ab43672412f15b0f1db95f0479fc2297017f4336fcbd9faf54bc5495a22de5b0d359c6c33e872ce0fac226d0a1fd042d0c6448282955b92cbefe9844d7cca12b4a19167461109b20552387d25d3a7ade56ebb79441d50497b923651be1551c5eac20100e88492a54bbcf211861b0e41204c5336671b5123d2317e45489b45abc79fe55e0b5b9972d21f0199994d979e8111caf33ae07d13a15853f88aee26a0460522a3f9615954e35aa7a3d9fd064951b960a9a15914e2965286d56639043f5d4dd29a364dd73414d0643a9550dbdc940e351ede8c5bb304db3158c28dec2445cb016896227985d7588fb225afad8707771f0d78967d2eb09f6efe21c8c648cc8867914ce68e5590d396c74bfdfd20fe8aa53cffa8b14b3091d466139a97c82b6caefc0ff078818a18f8ec208c20c84fb214b2fae3a80d2ca189b181d6f2a9850b5d79920069086930a0298df90a71ab052d52fb2507164f3c1b7518c71fbaf4ed5e12d4dfdbee5b0199f4b7d0cf1e237352891439c9aab3852ddd268f52ce00464f03b6443aa40e4fef5838f2f5e90f3dc05d52d8a9e2d7d279615e5eb321260fd19105023763005ca06728d2bbb5620abdd05a5cf0cc8c0c24d8ff86d5ad0223b3b243bb50ca3fab25bcdc39760c04d8f2a0bf814f19c68119b5c8f0fdaa0bf7aa75274cfc30b1672c1810a7c42a0f9ecb7c8db58786ee6a34b91f792ae2f7a19085890aa653f182c844819aeb445b387341bfeb21129731307fafed2e5177b3664611e9b805e242207a2090498f8d3b41f7b4f03083e21dcb35713fc0759fa9ff6f67319c2f6377a7a95895e2fa699737cc390bf02d15be435e2ef4eb4678aec76e69264b880090eb241c04488c94ee9beaaa43e3f6c40d6a8d637a048477170818d598394c88540d07c155a3b1baed30fd878edf0828862e5dfc9147aebb178beaedc8e3919e2b33e5493cfb79f8c39267c8a8ed757a6bbdf93bd0d2ba6e643d076fe1fbb5746bdbe755cb2a665cdfad65fc150f7058cb38e7190095fa859f9d51abddc858cd2c86330b585d53f80d717af937454e00f735ecadfc0ceff89c2a0d9e196ce794d25e8d72a55f18bdde7fc8ce1943b08721bf63789929805d48a3ab52276c320006f6ac1e0db86b8703ba61986ee8950a2ed1be38a44defb2db55393de7aa1486a1e02cfacec5d1465a63007fffc92c5af01fab2c09451eee72fdea689806842475a2a518a982df3aa8fe691cab893add33330d7e8a17e1f3223a4b0c414303b7415d90fcad51693565eb4b3fe26812a25befeef5f5b73fbdfe182f12bd73c77061949c82517d30cc1e22a49dc6198c4211af38838ea5b622e5515568b297eb1eeb2639e09582b1a3704b2d636335d85e916e08a53b1f8f175155a098cc6330e6307c7466f8e790833be31ad2bda23d935b7fa5f68d74062a8f1a18c9fb7b0f80392ad1f78cb5b40f61a7220fb79caf4b80eee42b0f6c17df375e0b4fc9a7100af0c9c976cd33a37189c9ae39d853e4e9603537be8c69a6eeff1522f4238208c0beb20ff3d474a47196b0433ff0bbe60ec47e1157bda2b753de0dd8e0784761f146a80949dd0bbf526b87879ad9320635b3bd9df280018b3dc1c65f7c848dde78b2eb20e7981a9ae7ff7a91f2a8f5ba347680408afa6b659749bb26c9c48f72665d097445d2e7e4dff201c0ff010f48fdc207837713eea25af7f158f73eb610e53462024c2c9fbe75ccea90d13bc7f1e448c4b36cfdea86c11641f7e1922d00f2f9e1d4864c91d40607c97ac8e2d8031ebc7f5ba288f5e1337dfcfeaf0d3d5a12019c0fe4c76371811ca54069801aba595d32d7538ae73707f3612655ff26c88d4cb4d8831d5afc0833563d4ac2039d2ea97363434801717a8769013c11ac0ed6ae54b034d4eb059503c60106a7e21fc60c36b599fc90ef24603d84dafd0c4176e38c3ce392f7fc0060960cda47953c2990e57ae671ee8378368294ee13b3d59439897668c106385d9decae81d59278fad64d85ca62f08228ceecdb38bdb70f3f1197f809e9a9a30a6234447e6526f07bb7d535471cc348e7012623b308df1ac4816a19b529cc81bbba2c438872b0da2afca4d3496a304c56ad403a6070ffbad1d02dca4c3b05d90f54f1d82f20c09a1e05c7bb094bbe282e06ff6fb91bd5801229eaba3c1d71676d787b026f485785e9c17993d7ee3a27d53736e86c814a754cd144ffe2283c1359bdbb09422b45c6d29f592cb46da5285927d6546b4554da13cc65ee1fa22740161bdfedea00c7466b2643f0c3005eaa968856b49ad193fdd639bfa7d1e3674c91c92b9aac2bb01bb26b0a6225e6da9ee4f4ba6dd4d75d593ce761abf0998d6bd6cd2d9d54eaced69b7423d572862cb204970875912faaf2350f53e0a0d36e159c77a6f91603a4902b2519dd0d93b259571604dbf3d55765335dc752fc94b23599b08b050c2ae0b5448f0f97dba61425e89fe7d4f692c3e57d0838fca8777e9b514e9af1ea5b4e804608a616539000d469c7d6b33ae34f0f729c360f204f912944639c82ad312c4f31eedbfee0e00b7834297eed56e23388fe37b328d8ae927b4a8efe216611d8d97d8b835619f899c9581c2e427ec6915b2d2a4ebcfeeb0bfe9f9801f4c0275d10144548d8bd19c13e712d93349e3141c881a715d76259441ce4a2195ef70f99707f86991fe35b0a36561d9b11ca3fc497f68c613581ac83b8cdcc3dd9d1bc6eeffe13dddf0f6b95c135c8fbae10b46ba6fd8b91b427cbf79dce92b382b5142dc4469d28a65ec97e83913bea81ead74abf065ad254eb6d3bebeef60a89f5a25cf5d00bbd09ad583fdd17e7a6f186f8179df9d91919469b5c82e9045c8dcc59aca244253ace5f99963aa04ec1b91588041aa28566a89a220a3da54eeaeb5f889d87c1d75796bd00f5437b901c80da7cceefa3254802e8e2d62050984cf78fad896c8178049d84be4b4e1d6a1960795bec6df3e9be32b2c7ae6d80041627b398600d9eb6b7d3a25f718d40b5f18f5384d27782b4de90bc418b5c232b1614e4520b9fa6b47f5700806530b95a170921e1a53c4fdcba30f9aad59ac8b28710208d5860a529e1a1ae1208dac52ccc0dacdba22230d71b63b32c857fb1ebfe939d5fad572ae0828836a8d9fbfee7b880cd3a4278e5a3463b394849e731c6ddc8387ab43e443f6beac6971730dc49f700632d089cdc7e00deb0593caf0ec76d05df7b192f73f23184d42b4f7ecff851adc419d75c077eeac863014de8a58f9fb325ca546421fbad6c62aeebb8959f51e7a1ac9d29b9910ada085c85d5f1837e1b57ae24b4b93f5df9997cc73e04aa36d6a07e0d550ae270cdb3be37da01e4af63c3931343b912cb7debbabadb7b522d5541c335ef0a5d0c712d1e5d38de53f40df5585322467df7845f810c68c76dda9da9fb5a6b7d92fd5b00e9019dd88f5579c552ff95aa491df6dd2fc09cad9ee085f17ec652a4a385ee91732c0557620bde0b8b1a71d7e6103a8e90330d7f82aa9872d9202a630e76ae9c1737d1b658b124a124bb19e866afe9ccc25ee99b0e00a8214fc37ddd4600b27354bb58b332c9d6d78e690052955f4abb8cd7492714c59e1f1a848db44fc601834a812196c18189c36c1fa60299c464e1b246264be61436c4dbe08be8f782c1d1383b32b84e6fdcb922d348c2f6273c4c8ee0524989d1646388fabdbdc56fda910ed365a5cc8694d6bb314956ae4b39dbf999381cd7623de15b9becbede367f99c1db1d373769d30db38909b162e4339603e18e8fbb08d1b416463454ba419d9045a350749ce859abc5cfa94364b688a6939f88b325fb96301319cdaf405354b9cd62f8dd2c2fb9b90189a60bf9ab11f3108cdb9bf0fb5d7537f67aeead166028662ca07aac57fb86704e0d83217d64bd7fad12acf24dfecd197e25ac6bf9cbf0cc65c9bf148ec0cf7fbfd71dd6ab89358a7510a4f014879568fbc7aa6c6391c19f026879578348a59c7d35786fccac19f0bcc5a7d790080459e0b63d50606a551bce726cbcae2c01949aa3d35d47a5aa461d5301fd0b5069c03439c8304e5e76258283ffaa5b01f32505105f740db868ff561dbb0a45b2e2b72362250481d05083b10862da728fb926bb0b8ddc35de8cf87d4169562febd1a524e9b533ad75b41e59e1c8a7c1cba1c9fdcd16eada51cd5d86769b9073a9c442e7acff625a7dd10ade5c05fd17f1079c86334459d97ef4ba29007a5b4a64d804ce84b38bdcd8e02c61d1f793d50c60c7578cdcef582ae4dcca74625ab6eba6a2828937c2f9e6ea9a56ada503ae4d900b0d4ff84f7b01c51972891285f8676c659227ae3861b0efac63ca07668524c3264ca2d3ae502a0a342f60856bdc840d4a0d81f4018378b36c0cf7805f6b52405f25a29b75417622f25eff1ea2337f286acbae0bfe368d0c4580b941eb97328ad4623d743de60613f6cc48f248905479e7467abc63b1d0d232c3cbdd3cc0b05a7d93b49cb47e1bc20b05e4be2c807df9dcc11ce60e8f85c6d8b2cad1e9fd424b5e65078c778c41de4972bb1136dd8acd57fcc7f5f62d57585eb39d43d807705ddf6e0b25bbbf0ad35e417c713aaa90d1e75a3e9e411b583137f019b9453bf00d948ec7e9b88bf6e193e0dd3f8286bec8f32ef8ac2c8588858bab1c984295b7a44a0f43be0a3bdd44cca25f2c6e344304047e94ca94bef7d4567f71e1cf7660284223276374c01ac173b543217e095f77ed05cacff9b88752b540c300f6ab1612f8c8009e470f8e2b7f3853244fe9342640b5705949f58279d57d5a41e2b73ed2942981cbd13e6aaedcb0cb56dfdac427700bfabe36698f757af72b8ad9ba5a25eed143c1bfddaf0f0a1ad613d3857212e6a152a0bd13934a7f9fd567a5230516468f2deb78fac82a90909ce81073f2ec935291c3f09b3279609283f490fc758819e09d92de5f3ebce545a35d564e576f67f45158da1d4646f8701bca2063db25cb02a087817da464a2a48102e3877e02aeea535fd4da1651a1dd565618dbda9c8de4c4fd77c41818a9050688b2578ccfd1b4e23c17de61ac40ed2d61167afcbae548a807fb67c010eb26b9fbb4ce3791f228e70e06b48e8bb44086dc5f4072352bdcd1456582f206bb3c078d09787ab047ef547eb688f07e30c7dc30870156bbe07a2cb6f716758274632606f0089d4ecf3d73658cb392a0528a80f19779e538d600323ecab97a0e33e9a25d1817902306e131759c315b6857453287c0c46930b4e80f0a7fe4ee082359b21a222a1bc1d4566762e9dec8f5dae24eec8ce4ae9b51d492a20e4f923aeec1b74660d4b5afa370eeadd288e63943c6c25806f60a77137546ffba9091b0ccaf2093b6ea353abbb5cd03c56ca06b08a4743232cebe01817d8f75aba377972b0c7386814b35c940b5b1243e75dbe67d8f434ec204223092f4630adc1ebce4f276c2604c0b9785106138d63df3fe69681d790d1a054d1c18d4ecc2583cf7fcb087d5311404e5a8a51613f932174ff93e1bce5580b80abc9a025281091d46340a90c63a0ae926344f531487a6dcd78a6df4dd7fb8b419a6c9d2ca3031aa8c28b5d30ccba9a0ec5922617dcc1ebb501475a21a6bc70491b98de1303dedf668a235f05dc25451a34654439ef38be72d3c3d1e6cea9a2f3a7aa3040a48afb45665745254483e64dd3bf0f21a021ef8af767beef6fd2dade7b6fb9b794324919670867084508159ce241391f8a15cce82573d99e4721215b0e69f32116492f872d7b82b1e7130e23ec1d8a6c5761cfa71cc4d0c721fdf555917376396f38e47c05a91b08220404bba6b0ebcd3b8edbf88d0d39a72b67a753994e4d3913131393eaad16325f2b538dd5e9baf47495313131c9549ccd76739bdf820809827f88030df156557df97d9021df97f3f6e921425c3349fa97ced70f5299aa4e22e71f80ccd720383f3ecda87134b665dbbfdb6c1accd7f82017e69036af43dedc5811799099f7b75a8c968b5aa53a3950c5189732ba36d197ffcca9413a362f833ada88be74727490ea2269527551261a5d8e32bac4b54a91677454ce5fd6589783973dc3ecf944a508ce133991d3245a8489ced3292f60a638207b782bcc2115e044b3ba847e7e5aadff71ccb97e2ee70d290781726f8abb6a1512fa11125acaf4b9a319cf01e3e75a2232d7653ae21163cc43a61b7f0d32027feaefbcc7737e9f66e1b0ff8d7bead2e777d8b1483211bfc683c4af9f45b2c75d78f44e63f14642f0e78526267470ba56561a0511b267ed7ee62df339dd6920d3b6e72cf2965bcd04ffc45fe441d8b1952157ad80f1ea3ce6398e35dc98c70935720005f53eb814972e5251f2a42f4f33c98125792b47d3189d51fd64cf9f547bcbee40d2d122cd9921cb38214f5697e9aa22fe39ef794e0aeef0f01dcd2ae2f99de7016f686e6e6e685c2c0ae1b5f3532ce2f91d6dc4d22c9adf791e2328453ccf7a239da74639cfa3270d196408c9d344a6bb88e76368232834cf13e38f5e34ba88f53bbfa3ffe8455af03b3f027ded3c110bf45797b3a6ce4011eb6368a30de60b5797ebdc6258f05acfea22f5cfbfe6d14444a014fdf3b09ec86b9e8fa17d54d78e26b2f33c12d8d19345b2a69e3734f3e666ded0cc247b3e157948223188fc5bc062c578124a510ccda32d2089b0b4479f8764d17c8c9faf1d9245a3591aec3ceb79f07c0ccdd2af2745f67cfa379466521a1a4a3b3a6f665ee88d66d2190d79c81d92488c67e9fcce4b20e7799ec863901a5717cdb348223abfa369e88d2e799e88cec77831e7795e7422a6b5e753932e36bdd5a0185fb67462b030d68941d2a51f37dd79fa19c88393a44b3436714c2239cffa1d92f544747ee7a994148ed40d95da8941ea3c0f99f3536469a0f33bcf43e777348f9c67fda4d134a665c89c8369ce5325a7b11c927271973f5905cce2d0db796fb5bc2585e3230da494c65458d08fd14af3294c1b3594066b01be699ea563ee3987687e262fd190b5c8f4a15f436dd414260dfa744697350434d3a7359cc77ffab331975c75d618095c69a8a555afb5d65a6bad4cc250e7ea129fc5037cf1411edf8f19c4efb94ed0ddedc67a02196f501a9235dc55b1cba02293d60aa91a214170e74136220265e6dd841944542f3083beba6acab905de4e65a02eac204e2f5e359ab56386e6c397919973cefcf44b9a65e67c99cf794e994c43ffc7ff0f22c4c8c78cd498a5b254760e09aa770c31761e78cf3d11d5ab5eb45b728e4934876ab63f03e690b7c73999f0a5cd73439e7bbe549ab5237c9f2a529470c4fc11e44021777b4fc1a713739cc8fd383a753a6e6f15f520f248407ec99c95166a6cde62e17f244b0310d4b3ba42fdbdf72c1edf7bffe9210ca82ec7f97ecfe25ef5472f4fb32e0f56f7e37bd5177dafc29d2e12fffb4f1b893a08a82f77b923a77dc31d44e5ac95dcd37d1fecc8f287d57d24abd33c42cdc21f3eab7bf18f5e1e8b8766618d9fd5e9a2f0456d04a57ba30ed447af8f7ef0b3af2e77f4e81de09da20ed6dcf66a16fd72d6e8d482fecfa169abd17e708cb9734f054a5d8f53e720f27c23a55b7da54c1f865cce5a8f1e07b0f9b2c70e4bb78dced555675ceefb9cc39f9a6c2197bf417f7fa10c727e19199907694d4d4d4dcd1fed1a7286863cdaf4ee194d004a23d778aba7ccf8f14f31973d1867f0bd05eaef896a06d2336d8fbbfcfd26230579bed338e7654ed81caa2d6ff5a81c9e400298600c24597cd5ff84b5a6227790020075eba706f9f8eabcfdfcfcd4e3fc580522c6d179297871dc79a794cd49085b4af0e18a06e8a65fedfb73d0cd2f69be317dfc9843d5fd68535dd20c4c1acd8714752a66d55bf365a871a0f11de87bef6b70e06e0f480edc8d835f4562ee31891f879c791539f3204896cf7a500764913a640e39a74b66becdd3901eccb77970d2d8d0d0d0dc7d43f33536244d8d98f34a8be2ab4abcc3f99ffe911cc99ed68c1a42b46cab8c29b91cc739c739de382e019c3f7b621ea3b573a649ce9ded4fbb4c707eaffb3c4f5928b6dd976ad26cc81cf222ef3feff1732c0dc0ff5e02a09680a785b86f85dce99f96c692e7972d1c5626cb0586a6249854d75a16955cfefc30115fd4f993a2b69ad0aa7c9a55b40d0ed9355c7df82a92a5c1eac3950e593c444a021977ad1f8c1bd4e58e0d64dc5de7e9ec2debdb3748c351fcbeea12c8b824cf5de6397acbdb75531aa30375da03efe9db0781fcd8ded34969800f9640c6fd7df71fdda08f93d2a8ef7df7def4967f4c545fe341aaef6ab8cbe61a845ff6c7834106152239bd14402e5d6c5ba06a332c539c644f9230c59468d294182f37292e5136da6ccf396d92284e2f66d25470d3443c6923793e408a0c14e61bc9656b0aa1e5219583214186ccdb10212121a1214184dc820819626b90213ecac965bb73e9600a5187c900ce9eee098b11d410eae004f9870f4c6f4a18e7dc026343cd98261f64c4f063e70e358c7bbed39eb40c310224ea8fa48f15b9be9d35deca795e1921c8f4e73741f10ceafe665fe5eaa2df91a3eb31d32c3cc9db3be77c3badb5f6ae6ec77d3727be42ba7d6fc79153dc2f338932c05bb5ce5ae7acf34e3be79c13055b6bcdd95b638db7eaf8f3738d07e15725725d9b75d639c588961662a081d6724d87f1e8f3bb3927ee640c81a95bd1b39221b79eb4e2c7176cc894882cc3c8c4fe018de145a64bb116688c2679e09772d9836589d326632b4c1a2cd86c537559186c069b59d8ccc26616366b22d3a99bb764907053ed404377bd12b99cb01ed56dfb615b9876a5f6a9f745f7056e194d7269c19e2419e791abd5a095e6a654535c4d9ce26ae11457fba6b8da9411d989da2e51b9be6572a0259b85b1a5551f32dd5cbc55bb484d9fca79315dd56a6e0a964beb54dbdcd4ae5c6d3b3950978a85ab511bb689d2a8514c1b1d501af5837e385057a5e610f7775251a718b7e428efc2843113a5b3aa5845f705fedc4cc06d39240e26666afad8bc55bf036ae37a3169d4af5bdc755740c5ae17cce865d7e7b22b4db25daaab3ebdddacd3cd3addacd3cd3add5ce64cd68969774c9cf8476fad2e52a95e0cc53ff2de282c0a8f9ea8c2c96892cb7a67170bd4add52099b7b65ddf3a554bab41aa9fd9da76a95b0dfabeb6987e698ce524298c731ec77f0ec95bb5e438981279979cffd1e66033651e3919b5b134673427cb7a756ddcb57132991179cee6d75dd65b9d554e565df53137e33e094e46c1e92d3b9bb1e8ab9e65ad18beea45ad7a2222c521cbfb30b47615eaf9b29a45f59c3ef44b9f85abaff9c51aab41add68f63ceadd6ff38ca623333dae803afef3fbae5ce2e964b232f945f6bcba49591d689b4b4a66d6dbd55579daa4cada58f8d49bb3e0ce39cc7f16b9d7948642a65f3960c156c5cadf39514f58605164eb3d96c369b952e639a61ecb719bdcde8cd6b22d74a4295aa37f0e7f392e99e52f5bb881b8cb01a3366cc181ef665b5d1075eb53e91db29de72a95d7acd69d5e518e73c8e4bbee42191ad936df296bf0c156c939d551a387b26b561bf14aa957e65a25f659b665b6bd3a60f54ad2e511a54575d0a3975ea692157cfa272d6d65a39ae723adb8c33ce18678ec6808ceb679cbdf5b80616ca00d32c0d6f418328eae1ada794524a73b05f605c6606549c39cb71d776ff5383ba9f5151c85f98c277b2eb2182a00782df78f366f8148681873bfa8f45b6df3d7d20de83e39ceb541ffe286c485211a50e7e08f93c1c9233dcf579b88b6cfd430e7c70e01fd698607ad8aebbbb5f5b0f9bb5e500ce1e5b6f489caf64f717e4549d4af5e148a9be8eeb4221e28d215ef27df1c3f70fe242fcc12eab9e95f3ea698c6e0cb627f1f126c47f08927f5ea998e03ce87ddd6c776fb5c01dfcea5578ab5ea5cb957ebd77e28dcee66b74996b3eab9e136fa85636dd156f745e87f3385ff3e5940b7a5651ceeb60b104ccec959375f6911cc9eff90d828f7d71c89f19def2bf194c1f7f2297e55b3b20eef27a83780b4847d627aa371e791dd7dae5c774f95b5bf30c360fda58a82120f84bb9fb297aff1b74a321b025d9932948494aa0f55fcadc7758b2f7436ebee36ede717e14ed88f3f6e7fc71fb569348320e79430e7120f0e983460e3491863890ccd33772a0fcf4296cf5d4ea00bfe671805fa3774de99f679ee68866c65b2b585efd78ab355d572586de83159c02998c86d050197d42a750249a4495c0ea59b0bdcf14e73c8e38eff842c89e0d91db904614667443da10551b4cf66c8e9c1a3284088aef518daf9cc0492bb520644a0477bb373724ce0be15485c1781b57c8be3343e2663dd7e49d913aab1625a34dac69a9537aef0d0a83cb65655df5bfbdb07bcaaa7f854f5f2b4bf3d5caeb05b32390ea8bfeca3aad766ddf03b5c5813820de739ef5dccee37c0f9d1f9fc82f4b039ccf791ee3b334119d1f3f47138152a4f3a376223b8fa367d5e58ebd7a276985cda119384f593c5fe218ef896f693528869ea00ec9b279d61fbd7648968d6669b0f3395fb4f3396f63a38b749ea58d705ee78dc6dff9a3978d4c4d6263e3394c55a66b4f4a28bd0c8dcd8ddd25072a2f9102aed24d427fd6d97c5961369a01f4d26a9095c9b0954d1ffa443e3ece4f7107d2f8384f6b8ca624b0d826270762fdd4a035879f0c84223082e390d7e62f17072aadcc81eca67fa11c683e1d9164d3bf3507cae9726f5436fd3b75c5781012387b3ac2894d9f43f2200b6637ca81e653d4d4a67f6d35887bd1a7b1b19c549303952ec6c9814abb64e640e58dd1689c9403b176143d7120aeb669cd61534e0b962807e28ad8f471988ca903eaf6bf4b3568d4383fab0b07e779d02f548680e16818cee3e80fb09e48901fb50f0dc57ece8f5f4e2928464a694eb39ae7894c7ffc9c37c27919231aab2efaf9f3e3905df2ac2e1afd95ca1c9279fa76c981689efe172b6f2c77311b2edea22fc5066fac065d8cc7f1ffc67c767963565f30a60fd78593f2168da64f38313b2b12c86772c76d2ca7ef359ce791f3e3f3c0799636ba800c45886961d444a014e16896e76896eb1d398ff3b24f72c891ac49d5451f87f4c0c8b6c9ca2a8c3e7943f6a79756832617382449a18b2d7ca952993e14ca8322df9a7e21e72faf8d78634647fed5e3c8bffaa36d146e9ab7214bba6d7e454e9fa2dbd4c8bc2569c8b267cb4cd7add9ba4f9f1317d0da20186dd583dd8ab55a55195285d5a4ca549ba6d42ab5484db2b2dea9de82adda5161d5b54556ddfc7d7b4356a4ebb72679ab223d0e79539d36fd90bc01c91268979706e4d1c7974683705d6115e6f75eec15565dd32515c67947362e002720931927f1cf880f6230dea6cc271bc46cfbf84bbaa452894856eae9862a9b520c367dea54836848e0cd061836c5917a9a12934da1af12718c2fd972308740a03bffe775b853ad38ac9736fe6d2d7e2297799aa791c9e48aecd103f45820f87d0ffa3528cda6bfc34707f48178902a03fa440da00f7e5ec5f11b8421db3e91ab2cd8f38efe434bb69a49d2bf66de897c86ac71ab500d2b43de0c6a58fde32d2a02ede77afda9d57fc22f403c5b38f006c1687b886badb5d65a23300218a72a3e052cc24c728f1d38640ce8272b70a9a21e357aece851eb9173ce3d7614d57614f5b876470f216fd11d0ed48383a639a3d4a9d42541869111b8121a62d304304c774ab3830e5ee825a4160cc8c129a54e67b0369b0d2ac80bb974a6ed4c381f26a4b0810a909cb0c194131352174b4b92a49e9cb04198272b389cb04117b35188bbe7930964bbcc2f83821fff01402dcfecf954430e4872def3a9862700ec90ed9e4f3530d16252c30930b89271f67caa610a0cb8c8377b3ed5f005064932b7e753939809983e882376d9da4118f1f3d4e4896df77c0a22cb2effc72211c2fe8d6e416f357e684de6533f326a432693c96432994c269b426cfb348a6ec102de2aeab8dc17725c48e61a2e871c076ad61742d1eebd31bac51cba975cedcff3eea55b68b227f7094b8a9555d9cf8fec3ec634aaa3356a1b41d4dfafb26bf316a63525b9fcd9f6e7caa2b2f7fe6595714f3c8846d9264ed31ad6b449466bd40ba5516b5fac179096a907f8c1efc41cf8efddab2c32f7fed88696cb9ffd8910d0811ffc4f977401f8131d007e1962f2febda4ebf89e7b1c9fd6e57d0ed08d3f141fff10f086d8032f28d6f01f070aeb1377d9fd5383ec4bacb24f844c65a0906f8da38597546dcfd21a9555998ccb94d04daac3b4265bf27e6e8cb36c2cab7d8c7f7e644b41e66d6aea66696dde682d28e7f5bd87dfc3182fc59498c61d5a1bdf5bf6b7a53177d55fc232d90f77d5bfe1f903ab3f4e5e1559a65ee89615d4cae742d16899e63d7eec698ae57b0c7edf7bdf73ef69968efd7d9a45e49f8f92ec3dfe3cefaff7f83d7ddfbb98c5d95a17f97e496b58bc55033ffa6546a35e6acd05067df095a0bbdc4235c87b8abb77a1246a63ca31c65dcedc385eed49d3870a2565406dcca7424d55897d1afad21cca40d51cc7dd0feac05df62decde3fda97e671a636a6aeb6193d6748dc7f1f57bf7a5939be520412fc05e5fe07f7ce9996dabea44f92cc913c4f644ee7b195efbd77ca5bd6ae7e7a6f6b49dd9747ae7e5457fd624e306bbdc7d883e9a0df7d9df2d6b4b86e6135551bfeb2da7c78ec8703d9c718df171f3f381590c59fa28efb62102bd47c78cb86399bb6e9be242bc7fdeeaf76240c2359de6dbc7b64c873a685a9fe7b5f6dd8615ee891d5b38fbfa55c4e29cf61db83d5a095d6512191579fdfbfac369b03ddb78e64ab5230aca914b539aca43fdcc81ca298f3481c7acb72da6132b070da5e68f394a907f7bfefc41cf7f183dfd1ac412b30c4a2f844fe7da28ec9e56e100c6d9e72a981a3fdbd0881fbf8a9a8e33ed6e2026e0e6ecbbca72120fef7a07843f51e693748c57b498f043db2a45946836086035446fc4b8a1f79ffc7c6ef91e5b83d2aaab4e7912009641499e417c9efc03359b7b8cb3ede3e6a107e85d5e642f6245d4596b97924b8b915595f1ea9da5ecbc95671b54d1ffb9f44c67fdf6e9b44436de88420b5648bcd1f35e847a806e159fe1ab3dfb5843cfbfd2f91ab6ddb47807d960eeef1c330fe74b5551bd374d9c738e7d1be85652772e96050cecb3e2659dfe3cb912cee3bf10698b3bdc061298b124eb25011c5cbcea72a4fb6ad71e40f3773577d1aae65dbe8f597dc559f09cb72d3e8447ad9f57b68c81ea334be8d1d40c5ecea91de86c1e61006495ec4811c68d33fda251583e9944c88c3ede202e866e5c07fff6a0a06a4625e3dd645f9655e461be53f7aad7e54d74c4bd39ee20d16d644afd5e7bf1ac80cf3020a609b95c36efc7663cdd241a996dabe02fb2939932b301e2b8703e87b9a95833bdaa0b8017dfdd08dddc8f4194012d89edebada6394467d0b033d00571ce6489e54679ee4451ce6b0fb778b035d2ae5405cbcd6a25d5a752ad77f3a356d2dda6ad1a9d61cb25ce89649a5f6dc6293e026f0290d0acbcd974c706ebeefb857fdd7618efbef31c73ddd9c7deebf27a737ad0762fc16bff79da8c33ed656b3ec7bbf7aef891c7b7777f0c3813e6ff5f777d4a05c5d36e5b4edfb7bda68511a57e61be040f9ef9713887dff670ef9ecfb42431910cda1f0a7456dcca8d1337cd34c99e11bffcccbc8e819a51fa6192b34cd4aa1cdc29739343708923e4a72f8f8c507c3f0c110fc50b374ec30fc4007a859e0afb417053e7e9508be07fe07824f37087a9e66853f37793189c36421fde3adabbbc8dc7f24ad79ab7b16dd5ed73dc61df54269d06f927151497775e8fa56037463fae007a0d8179f7b20d6f34992bd0faa4f926c27deb9e3c8f34466d9b7f9a317cedb7c11cedb682328f68d6c6eb4d1cd8fac1cb583a37df7557220d5dff1ef5359cddf2f2993cd25aa2e990761dae821c481c4eeef1b7d39b9d818ecfb3fe690b53113640e797f7f86f418a5e1e37ed09c5b5cc5c53dd277d7819c7843fc2b36e0886e8fa43ba434fa3e6a1c94f4874d5f6a5fbf403cb12f9d4d1fea4630893fe78f5e2c5c84f339361ae7b12e1a6ff4f8472f1cfd63247fd8903e4a32cf13f95fadeabadd83fa4afefbde5ba129b92626eae0bec43177900f381fdeb24fa5541e328194feec1e634d044a91c703130175d6ef1d49ceeab2d406f63ecffbc00982a27e0f5561a87aac33febe7b173ff171f7de73f841a29f5951f75e0b3f58ce19f73d66e9a2efb1ce2208740c8bfbf74816a73350e4fde769efe70b7b9df6e93345d007d0079606dd7bcff2c7f8e3f19e03651d8a1070cdcae16fdf6e513adaac1d451cf4b01ab841a78f156ff8f4b15fc5397dacb621fd942c9313cda93ab5e122581da6ab5aa71ea65c72b53974041735c5944b677272a6ebe4f489495cc935683aae39bcb7de516881426f81d3a77ed9ed59bfbc78bbb73440434f674b52f04aee3607e806627549b707f641a863c64c4ac3f334b65ef747bbd3737bdace21ea85d38ec95032379dd2b0356ec67536fc219716466f30ff0a951f67cd894bf7062edddb126c093687a610484df5a32a54857258ccdf22b92d525d04a424d8f4a9e1835f86f75683426d911cd4585bd86d5b98087259a796a6e6d017d446ddc22d714b4a21207912ae23389dd93974c31e11e492dee88dda006361b0593dfc341310cc5d7299bc75932c29792b367d02fe2ab29b2ddffe73d2f007a56a10385dfe17cc8266fbe3f8dd89053092bbf7bfa26692f42f03fcfd02a0904b260678efbda73a039656010510720e4a5597006c752a80ab0a352b87dde1db1dea92c89ef2d6fd21d2c5b8ebfee7449dbc75df0024ade2aefbb8bbe0ad063d2875bf8252fbeeaa2b92b7eed7f70fc37a54c369094b407f70b5e78d1a5bcc9e9e16a5e0ea468d2db2f59608d62099caa4b6cba0613a08e298f3fd0390867bcea8135c89392ed8ab8a63ce39e7cc60cf05503de7a474ce39ab1017b470410b75bb2e8d4400674f896f168c07e125eef2b762ac1824a4224536bd4a5769d3db2eeb33b164cf2b7b3ed9a43678410bb509492e31d4f6c7500e549b1c33d5251f6e870ab515e32d5f926d937bc923b67a1e554a4df8be7e5fbfafa0934cbf76b5ab5df7714fff821af205dfbbaeebba0f042b58a93bfeeebdeefbeec16f00bb7bf0ebc00ffcbefff48c06e85abf0026f4743c20d9b2c17724501b7c47e26583efcf3de824d39f18e76c671096c9d9b30024e4fb17d490edf7e0b76a1087f3c61bfc48b2bcdec23fb14c8fb7bee79eee398740a0377fd101fee0ddf4afce7101cde10f3e48410a6a0ed00dea06685b0013aaeee1ee131c0c91448230823852041058182145f45b1533850eb31d5e68f2058a2ec9085937ed0e6f29ed700205296870d2430f598410a22b2106ef488f274640a2c5114d767842c2b64f63bac0965841142f4628cd89050c2b4788e08624685c3a101851041fb1e285d203591246872637dca0e48a0ea966457ea56cff61c8fe5697970b058630010f5d58a01dd1a41ba126e5dd0bc05050124b0285a8147422d46c58cbec06a428aec49a88a10ba196053c62830d2928a288305844d0a183d576a0a1476a0f15a69890984a32c6c68da94de198e4a815ac0842052b5d48490aa31685b3b956259a8070fbe2851794623a7814b518564990a00b1451b4c46ee0c0f0e891da0bb7c9044249102980e1e94b1556c4d490d85a922a27a93e4e8044851121d030821b56501be132a9553bc50aaec4906a21c4f0851630d65afb46f28eb1ba8ce45aa9d0ca83521213145844b0a289175abe702e7b1b8a5411831329a418a946b4508195b4446103432e47ccc930048e0d159640291155c44a186e4acbecbb4942a0a549971f6eb089208c161cbe7b24532d33d0e4249e444b0ba1529416116c8ae06265e566518497ceb3057ab86551c11547c2e8418a1364594060c20aa618020bd74511537858977e6b0a9e84cd051b0951bc38c20ba78222b6747ea4c90b51b531379cb083162338304520e1719574627b62427241072e382e94ace005081f76f832858a6fe96e96215172052d0460a2102326054530e52bf32506206e43d41053b205e74b59e856d17a1223c4174d285061845b1125a86ef55202272a2588218c089c1663b02b390b3cf4c0c50909214449ca62e64802bef80085890995159c705fa400b9903282929426b65ca14316599210a960295964b952801e9414e1f4830a9880e15464a1225ac942823c44eb10173c48d990c20f27c8e2258b920c9309446df1c4c6b43404150e6a0c9e4018148288d5848872e3ae80020372d34a1434ae64950081ec3df244834c0aa72b2a4ca9370c111ea1800e26e410a50a132454b1026aca4a890424a258c941845b9410705da0986aee110a85e403b27e641a51220cd314314f5e64a9022ac67147fede7baf9523271494e0e10729da123a380aa0eebd7763d764cdf4f1b7b73c87ae8bf92c3f846003942861603b7054101106c621635cab942423584871e10a264b8480438117d78fd401200166892c4e8cc0040e5c88d862ccd3c7c6841a5875a18b2b218922060726aaf8a2045db829a0f08e14e96207134819610a14332998e8c00c332c524ed084165d4411757d3a81029715580821ea85239c1411b4d06a21e20a771d8718931980b08202a530382888a8c2390d242c9488e24452d416dc13449400ac4cb630c97828e10712e08965b6f260d10483ad8a2a49ccc09d40866dddda975f212289c68a063688a0092648c022b6026e0b11307ca9fb8c0bf188148d5b6a654631d101d97be413620431b0c005942c60a858640939772b26e894acb5d6e71347381183a2e9052a489c280178a402575491c2298523312e4d2c11876841c458487001092e464040e3981822d6b9d2bdf37ebe3fdeff5b45b02f09dfbdf7823268c073885e24c0ccb09e5c266b7d66a1457d7757cade840acfe7e47499afb676de5c75b02a7cc102172938114105596c4fe0287984791de167937a6489ceda24e53273bf4302b660e2842b5d84601ab344ad6b22e2e7a8290c122eac70c10a09342580105725c83e5f2da8d5cc5aa11a84adb5b26de8c49624820f25f060c5cb72496cfbd4c3b65fc381eeb6ba0432330bb9c4e37629e0cc1864e1436b86002c11802f0090426b842727d70bd99312002926188491710c00a892710b4764156a7882b9a2a4208a36050094c8aa3d9f68494cd17ab8e04bb6d9f38956c3055eb2b7e7138d89b62484ecaab0f29f3dd9b7df696387d2a0efd5bebfbfcf397d7be9e307d874cef93bd4460694067d9ae9fc0ce8d379c3891c4fdd8e727eabb575fe4cbc13a3d571f7bd960e28dee8eecd1cd97117efe018db6d0f95ecf70904573dac7a08c1cfc3d539bfe00ff7feb8add53bceddbde3bcd65abdd66a2bb5ee6ea79d6228aa9c521a1c9deeee95d269c15a6badd6ef9c40f54bbc7184506a963cdddd67786b3e56d27577da8eebf0c59ef5be0a86d37edf773f50bc4f2c8ded8fc505d8aa050c7113f3fbf9de5d3a5b5dc6a1f50f745eede52e77b9ce76b8ce983fc36e5a71f8f8b10801bb3d2ff41e04c3190ee4aeba4419e41aa48090da30402b4a559d70b57abb7aa562ae4106982e7f4fa62b69585d6b9986331ca8c39d9d1ef550208e16dfde67163fa420b3fdc71f9670cec7ec72e5cb9e60268df98c12c1fd73eab4e79411255d3869f20313a957d41662d3a84d8308c116df3a90d0161f146f882a104cdae18be2e73065faa26a47fc4fbcb152893a0376871ac89cdaa01e91f87e9635fbbb32667fdf13104aec0f0b94fd3d166f7ce3f6be136f7806c0f80a958da5367e4ebc8127d00092c00cf083086a96d96c5b5cf36dafa8b7432b0a12c25851e40606edd2d0848f4000c60e2e3c4d75310b02091fb6503a6bcab3f594a504b1fbc41bdd986d1f639ff2230863892b6ea0e104501c314495afc3d16996945cfeb7ae053b3ac4b6fd6c9f7c90b22dce6073dce7a80d04051412dca0786284941767c4e6fec781b8afc1bd02e6e68e0ccddd75dba78722db5a2156d7ca0c3be9e8e704166d267c2a98855114f1ba9802b338018371fac29410ab12c6065cdc02a103a8942df6553d0b11d90800000023150000201008054462a160349846caae7614000c7f9e487c54968ac324c861148490310410420801000000034668688a036d8f710c200871e6e8a3c2fd99197feb07902cce524cafefd92f2272bcd65401e29fd44a851cbb690287d35105a34ced90c269de87d3e0be909d91bb5fa76f679e3117fbba73089e70420eb9c6e748c104ff861eb8ca2b4f51f3746c329ef600837f76a8b554fa6763110b7f4471eb75b4a8843c73b2372d6fdd865942867896a2d7345abc89abcce20d52a29b6128bcd81db8c86442338ec234cbcb83b6365398fedf854fbe56c2e36f1919cbee65ed49651a84b2d2021950d80245c84933fb059f494e33b854c2b17733857119ffdc11fbc0a82805171c16ef79e67f9e508bcab21dab9bd39fdd34e89117ceffcda36a55d60a51af47ead2570ff91d6970548457d049f538d49fe984f55a7448217630bbba23ee863dafa605f916929aa8c9556831477fd2d67fdf87a78a645e24d71f83fecb1ac1c4fba479b8a441b2ac63d25686ba86877030a0368225201cc865e5de05230a1a5068326f85ae1db86da83a1b84dd5ac66478224ce7c46b31354232fc493dd4a20283fbc2611d6b827ceac5992aaec1f014a6f3c4fac1a279c44aa76864b811808fe53ba7669060cb5a591fdaa5d1593f25a4afaa50e077acc90d1386c54e71e81d4c865a2e3e2766196e6a177c2e6d2aaf5f70402d7349561510db41f2151cf10e2a10b00f33e25c212184dd76d121bf4b8884e12590f16df0aefe8a6304f006d9693b9f6a73f5e80ae38a013717e144eefb77d3705dc29d984dc27a6cec0ee48796056bfceaedec36043ca5fb045d17d472061b98c4feb21138944c98a089c2cbababfa11c4827a16999e6a3b28b1b1342e0f87680392c503abef768825b451e818765757622b81ab5e217f49e4da8db92182f14121fd66bca5ac8726f3ef89b8b271097bb930e24d9eef729921c195378342661f36e92d849eecd130e7c7bc327653beaeae6f6845db752730f65a72a78fc49768ce0112f6225a100578128f489e79d1885b9f7bb00c1b0dd565cc633936e97440197f426c243ffb76c482e9826d733c0e3646f34fc6c67222cd93bfca368aac23def846c5728ec3b129774bec3e2e4d0b649c49368dda9644eb1b9b48bab135c1de477c18ee7221620335ab8a53350ca6867735764d98a5c238056f043fb133de1817074fa4834fa1297161212ad602aa122bd622b67531cce05f4db869de9249d103eff160a216b67be296351a73c72c2a1db5fd7291fd89b5a4b3db780b28a22dd354c8dd48c5db792cd964413b400e6d521bedb08fa8aaa006b988ed2eeb0ce3d13c48f88270cdf57794d4a4a5b0d35288332432c4e6de9dd37e9323f52637ea01d43b4b4eb213b224211288d915d5192c82341d15eb23c94591665a3b6007d41f901e3af918fd4be2e548e833b5c30ab5d456b8b90d58a1b11e01e170cbf870024d1e774975734acc1670c4f50496653161b7488c5c799244005f420b4e0585e7466a0e51aa980f59e468eb3f42eb36006b50aa93726482f5569b95312cd5489087d340e3b00d339839f8f88fdad053e7ea13d8c9031b388dc5256f34874541a37b04672d2944331b4eb190e0f665ffe24aba897b774ab1170dd37eb49c12b83ebee61887d905bca2fee42a7b5dd869d9725bc5f8cb96d3af5258c4e73e9759806f80bfeb254a4e61cac8551876fba88335ab9cac5c2ff0bf3d0910cb132763f313fe432b2d06c76b958cc9398e9a4694c911cb32c6168567e2874c415115d534da8e3d836bf9cfd92f7521fbe09297a3dea4465612352a76cbabc51d4e78925eda8a98a86291416b539ad401209a7864744a5a3013003c65e2ff738b6528d7b8c404ff0637ab0bb45f3b8a9e4cc9f0593981256370007c416025a8ca3f3a329754d015ea4ddc946922488b0ad28efa94a8f453a8f6657241b86640952350a862d412d01c35369833306f0889643f44a46a468659483a5d84ef7f2aa297eb72a8aa46c5f7b63215e395ed2948e3d05cd5e3f2a5ef6bc28208d2186b29fe9fd4dc77494f40476dfa33314401025e02da5111fe31baf7155acc08219680ddb1a54409f1b2510cc6ee9d202e3322841bf706824106fd43652eb3dcb47c204d3ec8b905d7b1b2f2031b13439eb7f887acf40d21a70fb149fa59c93cdf295a897643186806b32be00f7cf31ce2bc369c9d4f35356bb187f51c289e4b6474b5e2062c6114f8d95e69919c89b352f09514d282bc828404c2ca8e753cc7b705dc7b2471c693b62e9420a6b981402c1aba62eaf8b115d1f53d468bfafb6d517d1d9d6a2501e571d509a3eff881e11de5b7463775a0002d7093b55b24ca71acdc3be4b8f474a6fa64bd24b98a5aaf99027aec3e0ef6c4b7833c81ab30b7edea79ecc071c2ea37038870a228971b9311b9ea2ee7910f26f5bcf29655e4b85e89031b5f81381fb279dcaf80242a0bee71db5506125d5285062f242725ef1e2c30c78abdd8e7ee8b2d374a91e0243d59c7acd54f46d2be44c0b7b27cdf1ac684158ab40c58e6df6a2a3ead8469e3163be4178ecfbb53a6a43b7a4c895246d9109f0e0e58dbb7e596217ab5804742e86c292728964f7de04dacde186db7f09d2522751f7e021596fb0d4f8da8e5df75449f170178618fb34b60a24c43586d6217183e275d9325f509aa248e94c9cdfd6c1c2bd2cd3ed692ff0da7f923146fdb2b39ed7a835aa9d174a672adec0d8936cd7222935e0cf19db4465f0c99efc30418fe5b15f8eaee5f9021154af5e8e330ee0c2983fb1c0d811c7a2bf6f744ba0d54b9108a13630dac02bab1af867a87a5d53402da985c12b9dc7c25b8eb96024a864b3988bd2f87b917d19737f8f2a2ef98a492d7085fcb34a90e9e09657061d901522b85e4c391ed0c8f083c7774841bf96ef6b9fbd4aa248e42c3b4cc206d5d55040124989029dfa364c8432141044e462f9f74329e06031bc263f792c4d88203bb0841ddbe2c6815fe09d01c2ddc6de133771c4a536bb97abc1efe29c7b970dbeb30e7e6d6a9d2a88b8419afa7c9d33be8092e32fbe897cb11a2308360a465724d24b35cb3e7cc167193fd0383b9144214092eb5964e8ab220d5c4385d6a15620befc840c3f1b6035aba29d32d11e33a14a7dff61bb931429c3931f29a994b444999a4e25a0114ae58f5e406f947acf1e494796846c1c816dda64d6729874de08856120e43a2db6120af832ead6bc970323e358fa5358b5cd50e8f194f9e7af149fa7be620ed466a74607c66621292f0adfe88aa038abad0086538bc9038ac66c41fd1fa31be8901988b219a5bbe18615a36fd6940097221161d7a7175c87f99b85e48026aa096c8454404da8972d8bacc0ca388c5d64e5ebfc9d16b448c68be0e1d2ba9ba2e3080a23f41623edfe3af551659af70b9524380efdce306a16f46e3c409195f195e23ed018fada946f30f6e871461c0b732d16f356898f072022ead6b864ec4b721944d809c6ad3728e469e0f375b4ebe0d1ac2e1f8b82f02de4f023fb37ca2466ebb0a0c5c7da2603bb893e566dfd6dfdc1d79dc6d2f4e07e197703dc5501e476e68ce57bf2a323faf2f08a6f86933d638ade6fd8b8b7e6e78b81f78169ed0ce8a3578a6676e518006674c169481a8b30be9c541519ae1972961e2bd8b729810dcafab18b580cccde253f6bf5386fc86c44e95071b47f632f19fda19f2e805858b8973bb426539dabc414195394169b693549c9c2074ac903f0245e0da0ccbe553bf07821208bd1f823940bb08e175d42a68ab2e4faa8588291332694c31cd210ee6e3a96ddd2c4d5ab7384009e6ad5a6c93ac577593037626fa88e7cf92672d52d324c5d6c96088c37a6f5fb5bf00b9543cbcced90e4f84904da2de0d46f60ed4415fcd54b8fdcd0435a8d16d5d4010808fafaf9cccbb657014bdfd651e5adc7c5cd75d514c1ef36529c6844ae9b31ccf9a7c4b6efb3670e11f2b53307f0923963de024dd8fb8180deead008069c27b10d299a84d9ed1be6d545e560681688a0bfa8a030a1995f838ad76724519024bb1c4a5f9af344f037cc6f48859c9c2f44d5925e65f0d48aadede6812dd5f3b77e6f90d6a38c5fd0cf474da55c7b768a6b0673454eb32731f17f4f8140ca2846a640c6d2855876d4fcf9b4df27197b167e251837b7e175aeb37d945980bcbcfbb3ab07b350ee533fa234d0c4bb22ba140fd9458b1fb63029c5ea1f7a37416250e553d6b7eac8f53d4c79154134c91088c5c19ea7276df25e519326bcbcff9c10e93a2a7ae5d11b3d7a2bfed0ab03cbd130a10391f87b1e8562519ef4f5a46be5e5f2ec1af93ecd8ec786104230bf4db371927ab3b0323c7cc853adbdd7bdc025f08887230ad5144f855e8afa121cf0a919b6ed61a1ca4d66ee6ad03a9374ae0b46a0d7932b700191a815394efcebea5e5ab7b783845ed7a72fd88c9d95d35b9fecb0080d36a5f92c8102a6182c0380aa1d61f3d956818174caf9f764c8d22b1e5039bf27844b9d4ae4d8a808e08a984a384dd3c99ab9a21b4bb9ca29dbd2fb3aefaf0ed3e4117221cb8d9a42c72da1640e6a6667c0195d92b54d14b802c961e4f31e7b3138245b85f9872d36624cc29f254d617616ffb5dc348850184f162305622343c7b1061ca69db8baaba312471aa376df5d78327dc650704987df93577c0fe832e32dd2a6cd5b60208433173a7d41bfc98947a727c0c726d2d70278b9899ca3be51271d4a9eea132d2b7be91693bf8d17347ca2a34ce481958b9c06589e7329b3192160634a420ae91a14d62b01c01622994da47ac829b4159762d5a45c456d9f5984fe08070a2136323d20831b3f76c492176975158148989f1064b25d2e6c660a7f8d6fc1c8d2cf8986483a2963671cf3b628752e265acbd42669eecbb6217dc5acc344920aeae4ebcaf63252835efca55c6054d883699aab499087d42c14f46c96f0f94825e0519e47aa38d7816db244346fd4cff28e9ddf5fcdd81cb525e7457deb5f4de4af15bf410d113111ac6b87b493ea43948c2422d4417143680a5f56073cec1b177d12aef3381a84079785f35c8b02da768ef2673233a18baf719a00f6b6049e897a377604f01b510a3d668df8e7ee6952464396a451223ca0429eaf7efa3d25e267ca04e83dcf350563cac94046e59a8e3679fab9f16b02813ae0d4e98d5f65743389611621f6051afdec4f697f6fae3367c7fdce313fa19100c6d596c33937d06ad2a875b2a60d3bcc90433ee06e44162ac5ac41c02f6f96e2ca1e12958893104793125b10c0d891577ff0c18c6c4a21573dc159cb788c67d8862f73604cb5d50e75421a14a4147d62f6e2f0f92bf7051aa4721a58e208e31c49037979472d1557514b7483534a21550498bcc95d88d3f813d5127d82d786263e77939904e550d76f72e8b74aab3607942d9eed3e7317b1e98e5ab5cc178e1f1d01757f49bc3c20cb1ebc546d66004f303a981333ab505889b7320a029cc63fc3a337750a876c65bac26e82976778493a943deec4bc73c1ebec2c284e57a6ac0cddfa6c3c5ea55ac1c7dfcce9b7a5780e535be8331b323dd7286d8ee090ba4c6c9cde7d2996a38a0698cfe9813f3cab6610d4f974c964e41d85233a6c8b8c05b673fe67eb04fc31f19fb36f503d51f3679933c137fa0d0290590c18b32620155b1023c388808b9de48df91d1dd87780b6c70426da691d7834550a2016158e3256354f58a082b0afa78671a0423808744059d32990555fa91b6b6cb80be5d9a7b599c764450ac90a4608ab145f80308809adf3dbec8c2d6146286d9c7dcbaf1b07da8e11384f603eba4859326d156ff6ece92da8c6e406bd3456bfb315eeb386146708298679951248c8caa31dc0370559407c32e899673b52922a7dce31d52d7d35f0291768461d326722c9074c9b64618b4f26f1c57f17bc0a5607e0294850ce26dad78e7820a866f2973e5852f79bf3cc5d1449a39beba67408b5a42c50c91d054e8ac9df40b01e2d20e212a97d4259f0a88808cd0defa879ef11c3e4ec28e9acdf3667fdb86658a08cd11da9e81610f86ec02125e81c733a6b3491dbc0eae111b6050e594da4dc28310bc0875902ec4e1b692ad73e984bbe83a601910115b6cb3a4ac1dcd080d3951b941d55914e9293b33aa02730b2c232694da072e341105a699575cf523ab14044927cc8c714c0e0c26da6352e627c76670cb35b876cdb04c24ab7584d07cf6041830cd0578f380df3d9e0e0586d2fa8a1c029703d6429317e6cf0dd08ebba8cf243c9646fb3b6969c97a233816686b72088732ab2044209b1550a309dce7722289f3bf8aef8a248de09c7fbacc20e7fb775ec535b86bc58565426e5df5ecefd09d29564aa41a5f707f28be0d1531fa17c41e87dbe76a74b2ce9627eb190a5a8a62f6bc2c3aedb778378f18b5593477a45942b6da568eb2615c47f417cd0a954b3bcd884f680e96754dd20e0b0577dbdf039682875c0c6ebe801c5821a776197d26f9f5337b4a9c217155afe6708ac80d55f9c155915b68ab8730983025824f3d712fb8d787780d6b4f7219c21b77e2e5e32579e63026066d29e68d3baf8e919e54e1800edbcd8e104662f69437f217d768c58e7d09e35a09c23748251392646e1b56183cedf2b3a44ed73d74c160e6f473f2f002757b0d4a79527641cf89fac7b4202e9c9b4ef1f1e0cfc59b3ce9d87cb3fddb6c8be1ee52c5b2166d063fa64b8913abe39e4e27288cece83d183dd9fc8a1c6150dc0045f2eef76a206b60c154580e39f4c5ae5bed93c282a60795905a2aab3c9fad55e4960a30db96ab82d4d91c3f93a36168d8b5c703c2abfc37c69a455de463d2c31596cdbd768bab16d060810665c9df288da236319d763910b5cbc549f4a88e04ba39041d55be33d1490bec296e9bd74f3d27f90f8c8a7e595693367a8ab7cd19bafa03a9e0b1b1072df9014ff2d91874516160e8035439da747e4e3a1de180509e3660d077dba87dfc185a2a0d8d4b01d84ffc279123ee7fd619cd553baeb6348341f391c6431515367cbfba8a4f9abfe1d345a283880dd26cc29bfb4e76e2fa68c3eca4518f1d4594a1e6d2edd7c8245ca90735dfac80dbacf99f58d063a23f884913f47516a157106a122cc9de5d63460ecf0f6565380e9610da6117378590ac4ae726d276a69beaf2fde81b8b0c2326492769a6fa57af0a62ab5105bdbe3a765b8dfdde93f5f89c762a933463b412497cb0c4659c673050e12bbea44ddc5e50432b690c37801dba76c973f096484723726ea2c1d3e1730f2ce7a06631a4b0f7083a5261888fc691d3843f29f631781f6d4e475490e8111fa08a3c28963a52ced91484441c16a5a5c1e1abd0a7254b621fc7c7c847e975947de3318d52667add960d7c1a659e347eddcf6d36a3c27edc22a853d734311198959d471b20d6ac00148c48828c90ea6cd7142b83a520e522fb7f72c89722581cc1de63af0b058ff6dcb86ee09f0237fffd486cdbd1e4ee818f93c1f8c99b44632beb11f998a9d16e79930cba43d691729bee0379dbaa8058d4dbcf45eb7500e267dd3e88bc696bbfb1e2feb6c60a022a1d7826ed24ea77de0038578e82809238578e88b5a93720dca22235a9134919e0ea949a0f3db03283b7b0bd468f07b143f56f1e0073ea7fdba5d85088ba210db497ab80fd7c68dbe409c4c1853467d0acbb5cc21a442d49cfd634d1118a251884becd7c27f63b002b979b1939cd9ca0937248ca431020190e2fe7b3d10090ec1a88b3117c7a1b0ea28bb3a391fd641c980ca5d0fe5c4c90ad02a7915a9758d28d42538e3fccbe117adc740e3acad8caeba6a4a6d3414a39850c749b4d2703bc6b244b5d830c4ac647e4b6ad74d7a785acc28ae0d5d85e1e90d589e64755ba6b9c6ede53ab4a89b84b358cb82a794bc2f8faed871e0a7685e059ecf1618de400afa4526b43ed5de41d767c6b827cca2792d3112f5b5481cf86527919ff69b064935feede3e023882b2361c2548e8a9c66ba34e0975bbdf2a5285366762239fc725335b4cbc2412d1018e336c0a484834e7598d1eb147cd7c46257178b34012aa80f1a9c306c6d63d4ab613357f47090fd42844e596a824340b3680489457bf366085cae375733d30b61e4c64f4ec6d833d1050e120badd0259df9f1154de9865955b733738c8996aaa1cbe091966e68cbf13be8d9ca71ce17606a9738bffebd651c38ba6b23410425d1bb2b8eb91db957a96409c33729636345d9281c1b320651f8427e4a8a97282cdc9d57a2d5ad34e1e579622e9e48504aced3c1bb9c804e5d513cceebf69c67b6e6efb63c9ab0bde412b46a6e884a53f98cc2d817215302c7f5e804bbb9d7434f551f287c419635faec5497de2bb7fd319265ea31cf8bcac5f4b9fc52d5c4c60dbac2cc244045cad802b64d0310881ae4b811c7d70e70a167a31275e12185fb901f18dd254b79863a352ed85dc4a1dada9c7143b189710bf845c32f5685f872cc34921775abfb74f17a32f85fa7ad99a78e0d9f502dc5b479043d531d84060c454ee33697f3fb87785225091e6460b48997a89bde974e202e57caf7a6e4d84b555de206508655deaecb02956bc52a50b9dbd102b73a2818ce8d5b24fe28e77c10969539505d5c5a9571139882a2d2b9697496914335120c26fc917c3ccbdb1d4fa08a19f9755be20e44409fd7fa6a699198aae6314c2be68c8d17bfcd156043347c335804541a288e0ed573177f9fe336755b2394de9bd9a6046ad8fffc825de8b6507774001fa222dc46ca404ee0f9ee05b032bd900183d587158c4aa81c80c5be47099911e36dd6e1ff21e6cb36c258895fd616744426461f9c441e03bc8920a1df2034eff5de2a8f6b554c61a437f4cdb552a04d6f62b2672f23dfec82c71e57c5c2ac5d60812d353b92df92b41877bc289423a6485b3cfdad755210248ab7324ecffae6f0a30feb9b26d0a4f1749dbe10464de05c20fe8e58861585010b50c6ef69d84438265a80005aa960ea610d425c433f4fe86dafa281860e27b5921346eef35596eed0a3372324e98a3620e684096b49b32cfddddd03423b14ec50847c12480153070b4923fedebe2e9e74e29af29fab189b643ddd67b3af9915286c13e69bd5c8da852425db90ef02af3eff628d3513b8b90203de9c28b7e4a2f191b4bfafc65efa0db26fe78dc60ed5a95403f28f231fb05006b75ceac5f1cdde6d47c73058480bb8dd6ea5d0527854994cb35d99842b634249b01e9360aad971fb54123f267a2cb78c90bc9394f516543d0fe79d5bcb447dee6d13ceee72470dff088ec66e67981b40b50bd90f499452480d9be1220c53d80eae6d5b1c362f4bb8e3efcfecedb5fd621671e7c32dadc987abc3a51eeeff0b86c8097eedc06210d4177a959c6aabaf0ade1332c7abc33e267d1f9cdf0af150d87347b4804e15fee3bde26bb4760f58f5efd6733b47b7e21b781886eda52f2d20914c871bc9aed6842218a47ecaad0932cdc6f4a71a44166db01f873b5db97ec511448ae13d7a18bea9c14ba4a004400d9b9f4bcd59110ed1b8ce6c0ecd195dab4ec9fa98da84adc0c37dcd0ed9cf2f82625d90449a78d34d09bc7346f579e981ba7d21c29aa748f7815a5aa8c7ff6a16fd90ea4169237690982119dffdc63bc501fa4095650e8f6590e6c34fdded79eabf797beaa983ad183515369235cae4312ca01e3920db2a510c17c298fee689afb94f7f54fd79f05a8a46f8ff3364549f1a21af4224c9bad5faee050c4fbcccb16b4c832243f7a493e8a71c5c26e910bfe08dd322572a85ea26b5efa2d630fcabc8b54bbe817a72fc6981e0ba285f55524ba2113cb19a009b68905cfbcd6757fb75f569f14f297cb6ead4c7402c301262282a644081a97b35e0305febc42eb70e132c9c7e2c6e9fe1db2865f796e8c4fab8062c16a3e8ac69a2749359f68c465a1a42dd3de2de2af20e473c0d85f6df729b69cda455f6784f4eeda12e1f8008b436405e5877b2d2b2cc2f71e1822049cd117660f86032783d892b040bc52111dee68b8fd05950adb710b8dacf4b0f3a732622a22d18eb841f0df15a70365c4242142dd0670cf257db043cd878cfb6898d3a49bc27fe859db052d47840f8e4f406bd7ecc599a93533928910dbcd45f871475cf839fc643b470fc8b1c89805e226b100ac2fa986710e1720266d7148d2a55bdc0e70f8a2f10c19320f05a9ece04d13631599749bd954b9813ab11960385a9e55e04090c57b4a4a0e4318aed26a947aeee94e360a72ed4eecee06e7b04b24722d5c4808e647bc6e8e1dbeb3d5c5b7a4d842c4b7c2e0ec7ebe99137fb0c238238fd34aee8b21c45a280055da9204c670a5df10901c8fb228b38ec71427dabc1e54c8b2601ca0d9e4fb6198b08385011c97e4f74d6f9811b17237cf0d2db135a188c99ad81736fbcfffccfefe6771f2a60e98ee426292b92543abb636b1a2a8244106f2ad7721fcd19ca66171c6ed70322bf162a705ce8eb7a95a2d0494881ce5907cc328df0a155cfc453c0057f405c10240ed393e898e8e507e2e443f663fb4508a9679e70984d6dc598c4f1d603b1e5e8605d70a05849059e6dd6caeedcd5dbb051008a81fac4513f74891331e5bb94150bd0dc55a87e6d5f33f7740e051604109564b8b49c4b9c518b726aa45f460c9aa33efc2335ac8573edeb3ddceab85a4a604684ea15248d4ac273359b83f45032c7ebfc7d0d568557d261ac2ff01a42f0f3467583837a6011a62634323b59b107957daf7f68fe3fe947fa2ce34e591dd3491890c1ee75aebb9ba3d90c1674814bf8a5af169e4bf4e00f1e732a78c9b0cbe05bd01b8a704d76777bee7c267219ecc7b5affe90b02bc7e09dac7f4d1975c9a8e7f6e66351112cd80bf16e44ba13011d2a0f5d011badb03789366574cc8f0e60d29ad93cc40f58360eaaf619adb6df42c4d4e0e6639b429647c9f0c4672a5ddcf7c7204dbb1b0d568e08ca0dee4b5acf3ad746a0a13f6f1600d64216c34e69a920616891de81e515d884b80f49f9f44aca97859e79b42d3535a1f2007e83cb70d247be91eb3aab89ca9b357b0ee84f90c9fe3717480185bfb7da6c27256c1fef6607b6346257df31eb705155d27bd341647421e26667dc98482ecaa88ec4c50c84451a0e4952df50c7c540a09bb490ed13b0fd6686bc1e92833c1806c67007f1fba87f10c49a20604eb996cf479a8543bb003111baf87b8c4316620f360d492dc26f11c4101cc274653dc155cb045f9f9bb90f17b9bdc54aa84ede78f9837e4816ba654c213634e5c55b8e5a0538baa4a51584f98b4b14186a70563ae4965a812a6d290fe2d6b02b933d012e6e06d53a259777a86a5c8d40c496c8b6851db7a7be7505d74193d4e86cfde7b5b4b147634eacbd96f0ecf8373e702119357b6dbe10e43a51887a52d75007cf1ac203c162f802f77465d6ff9257339231577b7e4388390b6a2bcd42aa2a7b27d1462df3dffd00f92cb372ee8592cde9fc4db6ab044308a4709dd38d85bf319b090fb53011ddea6dd4d703322f8014f7dfd7c9e42de6a98490dc36919be84b09625ff99593a81607a21ff99d80ac5de1086828d5e10a45d500f5de27d91c041e03dd348c7adeb04aa11efa968eebae1012c79cea5ea6de996c4f8b2038dd579f4afc71873c4fd9dc4302854a26e5557b5e2cbc0047f9249f269fdfae83388af2e5909f79b1b2df13b2f104f998009dd206140519f8267f284c80fb535634f289f81a81d49e7c2713afdbbc5ecee769c2e26919a5142cee8669879c467d6fee0089960d84af82489f0878742b61a9ecf9de3201609bf453f482a6171d10d7516f0e4c93aa75d629435b71a352f47e9f08e2d6c29838e9e23ffcae87cd3b70886581210558242de111134bb7584a2ab3f9d168f18af167059eb2a2af2a461f300c7518b33c56159d0d978a51a1a096389fda3df65dfaf59488c862d2be5762e1a34bbd652ef43a7355b50fa7e47f5b306c6c6816d98fe1b0f0c6f2e12f981850268419ed92ae5ef29308c7377ebb7d1c9ccc2cac28edd3cebed585c3fdffaad14f085b43e78ec5b1274e910dd72e11720a054e4c117d8c4954d120703aab5f42ec2c8fa5ae455e170f61d2e59e288d21721822ba9a6d0684f015e36a60cdf80ec50d28b6dde4d572dcc6263cdf015e40d50374952f8f8adcb41e8760b9de7213825123db2978483f9d22c1106894c9e850c4759a8dd4d592cf8e3d2b964b1ae1a2caf9571701cc2eac65e1130bea9d9dabec0c4498f4300c721491b3aaf95f3d54cd2a2342750c8beb5c35c289d96e61ecdf84d482237a4c233eb4c9bdc5005b92afd41fe9d2bbf6fafbf3b38cce7250f592fbc52c90adfedd5fc4a2ad5d734c3858a0a06d553a0de4f8586b8655321dd980652a9bfb8f1586fa61d3332d3948e1b5738ec7a2a73542aeb36efd8ce806025c2a29fc21db88138ab40109526f1514ff1ab0d35d9f323265f4bb09d59769acaa6288da21b3f188e0c62f4c7307ab466a6daa1518cf375a9b037de6743700142c23d9f1f11a01a78ed735104ce10a45f78ded08cee6d4e0cfe7d5d8af32e258b43c82de6ec22cb43aaf3ec33ba4b19752d4f8e5c04245623e415e17b55149b63f5db00889d8a451e158ba3e867290d6816f33ea5f10d54bbfdce0a6cef939db5c694646f85b0752aa6428a2d05d2ed8395e3d3d476692809a7b044f0d4fc417fa741c5f837c609934722c0bdf518599a7509ca75b4ab4539c6cafe484a9e9610bcaee2d9c17fb872aa0c23d26b1fce5c043a0d174a5c90c33e3e50fcbc34438f15fe7c3b95b637922d2cd4448680ba54a3407d3827765301f7a00b8b15280a3a4fe5327a6579c31b81c737b192c0d0eed19486bbdf532d4adc63d10e6e79683d98583213522c0c08c1528b88f51dc9529eaa5fc2e1959a28385a5d6a48d25e891d8b033f378695c0eb15523f02267cdd728b3fd08bb42fa3d8f07df9cb5aefceca2cdd1a106ec25185b75891e00761a78160dddbe03e88d7597fe0613a6e3486c341343f789d68f7f2e372aa7688e9bae12136183f6f7a92bdeb67e881bcc38582ae26fac4f8a9329fd751e93331d5fec6c7ac725098341daaf34b37480f8e9cec1f59c9095d9fd1354461578aaccf2843249973c4c9ddc9bafb33ce3e0c4d098bd079ea8861a7f15a019aebe7c62b0d4e242679592eafc949b84f04d7e16b89b3da40c83d607c218d2c374e74023a7f44bea6810e14126926710e5929b84f8cac7fd6b59fe2c936915d7f633cab9d400fe0cb3d2a1b57a5b34e332395453172e9e05708d5e5b5bcc39c1321df7f071236380fde011dd26270500aa519b2731c398a384696c81d06a3022a6293b5f7587d5ef3112ecd748bb950237f4937be3b3eb206aff085485e5dba38446925ef4ba835a196b0cc0126f1aabd4b4c07823a12ce845452d334582f6bfcb6a1ba5ba612b9175990eef9606d6f47ae4661e97868a89b4c845f1bf950d4f98fbb51b1ce3305a5f893dffb315c4cf95900a0c2567a19913708405c0042e8dff254dfa600fd76c4a242dbdfd08cc06eee27fc3a2f10048996755b18b67ff419c1fdc04abe3c3341c06922e83da7997058857f7e79cc50b16018f309056fb7118caf53fa5061bffd8bfb35e9dc2ee93e73f235c1ed48742350619c3e99fe321c4f96731288234f801a076e7ad65a7944519f70dd3d4314b5a5c41c1113889da04f23db4c87915e0124e066ff9ece35104f7217cd2ae131abd9d335ee583b9abd66b0b56719e0bfc242c98ce6cb8ec78bbea43f6a8667b20ec84037fc787dfadc9c0d986f8d9c4d4339d0ed4bf86fe7e543297569c08a71e928705bee168d2412a016dad6c2b5345a51df60f9288080b07b844ffd9cd41998a9c7c7ee05d5e44d0807880acab4b39cfaa44157fac4a0e6ed29938a01fc586b3cb3a32de53117aaf55b650441a8b4bc2eb179fcc87e1f50105c177cacd33b9751a96315a4869ea779257f4cc9a4865b53ae60249db0242ac9d83e408940675e22347357426d14a74b68d1a18c788e30f35c0706a322bda97f2069b571e51f28e3c3c59588d3dd24a8de4c11af3a939e9a0e60248eb9b323fd064f08e88cec5647d2b14dbf99473c914cf2952982388d60b3dec2124b78d2119210d326fae7e2e4988ee40ea7f138925e3e3ae884849fa290f00b62965ae31db3c2bf13d05daf792a7f51302da1e2719613bee873331678720367c6ef152b7b34243a406848074f16ec6a3eb40a7588a6c8e1f4de399b899eb807402fcda1fff38b1580eed0f5fc0b47da9d526e8a4031939f4801d10a3ae242a67e66c24116065849233e116d74c9d8033354908aae13a73cf137c6ec0b40fe464836345c17628dd7f586bdb45a4d6c2c86e67286234e548e46628595d2e87ea12ede97cf2c652e54d99da85b20c150309211c38717f31e3517a0ed4f294d9055bd3459e755e2bd1bbc1cc462fe1198a287a27165ba3c6c10a59050f91b319454f80e72f39cde84183979a6102333f9c403b698f9d3fc01c2449bc8a46d3a469210553b227898ae1036e5ce814b4cc73c8a0d6b412a79d769b31f7a1fc869570f75c4212e5dbb6be6b4dee99c5b4b656376f925d079fcb70605cb936096d0beb93639e115ee4810b271ca59cd55edd4737e761eaa7ed90a1118621542011abbd9e36ff4a9964eee76ce62b6b17f7b1dff4eec31a7bbcb40c497ec175a81dce25e7008932facbd713030ce1f75030ddf17db37a56af37c0ff28ca8c1503f526384ee4a2e04fb1081efa6fa34d1586de26c6d6f43a99b08e0737523f9d47a0bbe20070cb23cf04eff3294f8c88df955c18ea2cc91b263a9fc7026c568a586b4c1ae78e6482ee154d1d10c95170db63f19dae95cf08871d959dc56f2837cfa66a9c8b1d61f012480822d831165960c4ff9b9681c566472bc60f5fa520199de14d2bdedb624cca0a9c8d24ea21c26832b9353a48729affc205c5fe039b9b1ef52f305038bd97bd4b13cd7b3a247be40148927f1ed4c194408965c0927b7a2966d17a4a178459b16c01ebfc4fd4ae043cf7754bba6a131c080c9a2151799a1870da1b79da09a2583f4b3147255ee66c6e23ff9454b20ea6726b97f6614c139a376a49cb8fee32ed2441c0b4154da16ad885eeb4e2631b5da6c40d44ad475baeac7f2ace1e7901f2c465957f8fd929f2df134c6ec3b0b7e953e5d0ca45a1a2a43480033b8811c3bee2f2b29f62ba5f36f4c293299c9bedf24fde4b11b4ea9e83001976ddf4b760a07f4097bebe0a562f666018eecc31bf67823dce1c02d7ac28096283a0d6342a8f4a237a3e154bc52d98c381082ebe1fc17aa6169ebe3af05d0aa35b2cfb4efbc6a88c006471847dd72bc4c3057498b1c79f5da2db6386586ea2451bcd500983385aa7233440fb126f352068b06e1b50b477579e7e81743a56f2398a65494fbfe15409f4bdb829b69e255c26102675c3ddb8c3d1cf0805ce6f86251602252c366eb4d3397767b4a0a2279118b4a1e9b34336dd679666ae3ad9f98ce959b3ee4180904ee9a40c511b808025b18f71c55d43457b8340358e3e8aeaf2a28093633020d404780d89b28eb12bb999098cd4091f2cc2dca0bbc39e5bb07be190c7bb2889264dba7bd013601dca77ed76debcb6039a9be329c2257d709fa004095c8666ba67aafc0e63f8e0f0efea3718ce2a1c7255f20f8e4bbb7459f480e4b1c9e7e910f99625da242c64180a8a3c153519882b1b836ba19244e1170eb94c5b3145507bbef996412b10a206c648b716e1fe9c085d9f7e660f2e21b1d1fb58ecdf8721cc9bb318067f9468a91efaeed88462584c340ccfbd9608ff46fe2ce7f6b39030bb6ab2f1ed2dd3fb61794d48131a17e09b664753e3f60bfe441597d0125773e75ebcde6f526b98c0e0ec3d59a406d51da3d1222ddb3940f674c98bece6fc8d38531f23f876e598b65307b66eb3fc1d23f21eaf406b6467dedc07dfd10ff36d0849b4262dbb95a172c39251b2c00ba2d109e0e603eb0addaa1a21dcbec670d05917ebb2ac95195d35d0008fffbbc0047fdf8cec334e9df575d3ce6cda5ead503da56e489d90255e0e872d8b0db0635adec800fbcef58138c39c353144012007337fc63f38dfe4e82723ed0b09287ea2ba6bedbe05ddd4257429aa3304fd764c3b47282fe00bdcadf3f37b730193c343da06c80b9015536be084d3e341ce2b225e037c9a0bea2ddb76ef97d57cec9d7f2601802571fcf5b4143aa35183cab80c6b7ce62fa25c557e61009e72ce9fa5898c6578572fbbeb6591cdf5de9bbbd48ce89f1d0389d5ae22d465b6759d17258453577aeaafb9c6750bc155a29f144b6cb68d014c39ec1e4099d201726271e95ef2e811eb047bb971c1688fa4e8d6eae1350c50dd60c3e296c1a2287e4aa14e3de4c5de840284a9638806f3d0206871856b14f8bd48747bf1ebb7cd5283b09c94208b37a71c4cd38144230744ff9d15054e5484f795c05c7d25774bcc89fee821d095070db7592ddf18a84aded3b59169696daf60c997a2a8ad2847cf72bbdbd0232f73882f8ccabe44aa102d2fc61efda093fd21e7b57180796032d3c35e0d684fa1b1e0bf83fe84eab8d3f865ca56b54128c8328f77cc936bcb65cef8ae279fa62085d34877578e0c5837b374dd106fbfa35f955c40bb5a5f87ac93d3c1ede77b8ed85368e9c14ada827a898b2b900ccb1c7876884e3d3f5186c5f31ddb8d2e9393e277034bff8a0f91dccdb00047d80aa1feacccf1e1749e5940c5c99f85eb4ac1c0256abbfb4264d07a77bb1f7f3d7ec6a6883b937fdee1f027cbaeb4220d814e06b66373768c580f988796132ff93b7e9f2f318133d286e78773f058d0a8d5b46fab4ce94720adc581fde2927fe0ce443577c50a7aedf8fe75e21d98eeed93567833bf8c878b5b088131128a7456b593c21c7f0b8c80dd0012cd65dbbcf6d3f132e097081f1cb04c9385e1444cdd836e2f019702fc856a3ed1ad0188af8637f830320670f0b331342fead9091f1edc33c5128bd259d9a8ba89b95afd984e6411f7a2ff19440657edf17c8fd071a119901de9faccd44b07bc9197b5e8d72bf587a583cbcfc096054f0f78f0f43686ff9e7e95457fded4ae03359cf0db5a98844e7a5b563096f92f0c96c463209a51cde59c5ad4e3180628b7a2912e50362801433629dea3d3a9e41438301fecdb9150bed31b03751d5861f604f33697378c396867988f925953a2994b93cad955f42f8f07048a81f58d47f3ed931cdccd80ae8ad54d063ea0a0c5d3d19edfc72d777276cb652d90b307f2d1021edf9212542e54b1dd7c3d2efd90f81831d8801b68850b3471536298481492ed68d2940a140f8a2b4796cf91d151eef277e2eb0302c64212eba6fa5c0b38a1570f309a2f79e4372d09dff4ca193339f9686c635a7cac4929764d1fbd1a1d09b29416b72a7d3bd0e82567842730562cdc7e6ea759d79eed85b0ef9591761af20ca076700e276985e25fb12ec662f0db86c6e801504857202d6b50facb149a6f445449ce14f62480ae455eafac6bd218873b10daaf77fedf387a71751418bd7a9df80501829ebf41b4edbac835a7a602b1cb334798d0bc7f30eff00acd3502fbf153a91bd66e37a372ed3e58ba073d2a06dd1fb539cffa98ba07cfeee901e1ec28e121069922a5152793c5cf9fc180804a0e726a8a308167989cc9654b3805762c194a693acf66c3c0e34e7dbad11850f1bb6fe1d408364c4cb10f4f3760b686adabb460bf486844bd2e67eb69a10eeed5599f1bfe41e11a59110451a1e914d6dd4e0832ccada086a36bf620eecec50993f63be23304cf04a0cbe725a35afd39abc971d049b65e0c4fb18f285d382256260eccfe056b839b8fdd70b2237f7b060b32932aecfa2600452425b2009bcff687be3814dfee877b012bafcd10b851a9e44fc1fb135408e9b1f9f3a910bd0c1dd88c9496b45fad4dfdd97bc51e86265d863cbc328b8ed8c18e511264f894d4c668d178b5d86811e6bb726677296265f5e494fa9a15fe058628c06f87eaf3bf88e0c2036eac63e0c91ef34f50b0595bbf4072f7224f83664695867ae1bb678015bab4035e2e109b949ecc6d66a341839dc7a25d8fc84bd3c739b90a1be9e3ff519571d624952e46bafff3ef676debc25ecaf377055694cacbfe9acfa7703c946da7a0383ea2eea88cef330c855f7dd8a107b31e45619a4a9c5b15cdadfdd01a5891c289b70372b6837a44517e56066bfaa205928739260e66cd3fa8e6925b1b1fbce097d3e0aa33eab0b7c5ea4c07e422449081da0cf1771b30515bc63cdbe82635e3025713ffc0f56d6d1900748c3244887d7c68d9b94da5cea781599621673046ff43f8ecbb14e53ea300921b16e5b03deec222193f52b3b325dd9ad631c6e933cb147d83cbb355ced395242260f66e87059cb03568922dd0c4d4b20ddd90f3594e823af705800bc4b4ca4b46ed4544e9f3ec5dd01fcf74e28426042237b53c373fb7ab2ba08d7784b2ee8dd6548c3a4f1234ae6b8e3d630b52e61ab4f8b031c349f124caea74ad91ba16e1ce341bda6abde7b1ddddcbad2762666762cca329da72292876967ee170366736cda2a40e9e3c2b3cb523d29a7c4bdab1b8e130d5b493ec3d7dea6a920dbbeb0e51a5c55a6605b7125c8d0ce45db87ed89582803e338efff9c748e30ba310384fcfe1af1f7268c5fc5f7d3cc280d6c903cfeed9d66110a02af41a2661128815f02498b1d48b0d8a9eea79a54ddea152b552b4e566889b5003f6069e273e49ae9437ae5d59ec71ec0cb865a135693202bc8c646a88256a0cf712a8b1d3bd57345b148cd4e53171af122dcda5d0af1529621a0edb20baad2accbde7b45ed1f02433195802c0af09bd866e6fa8fdf9e2ad2690dac35c5dda13f24f37e2b91a3b890bb53814b40e32a963771978f5264235dc7f63fa82be5645ec084dfd211f57c5693ddd32ef309ce0526e2d226a56f498962c4b7bbc054e8170d8f8855dcff4ac4245d64811a2e580dd662575bb33a2d72973736a41bf55830ad71148335787eec433525e068093e8cfb2bafc5b9691c3ce2397dec4b1402682a8103b420be13475ad71ba9f8a9aed8d94f7f7f5061dcf987eb2d3c592253378fc14d0a3aa0d10ca2cbc59fc1345ede6b5e8b9aec74194974712a33a46c853cdb52d61c6343c784ac5e6f77be5263de5ee219e9bc670346edf8677756635c386ab22913393c9fc2ee7916b130897a55e2b9d322a1185212556c16b92e45ca748e0eb0b0422e27503822524a7c9d23db635a49ddca2b07864f2ab00c0cc0c97e212e2d35db65102fb97fbfbf135a6cd391078f7fb81c85cf2b7f7c9e36b0d39161ce7f4b5ec9a63392126d2f3b1085a10500c2cc860c8b24ab5c14b996467aa3c1a45cb8f48e3d9935ec51df6973fbbeae3ff0bd2bd1f2d42386d183c2ae4d966796a6773e4da07b73b34881c627ecac67a7bf3ed229ed927582558d1c75fbe91588ab00b2c160de0a456df45981f73dc98e95be68899d8d13c7acf6017f02802fcb034e168560d1404c5ff9eec40adcd935180b9c33ffce7eadbf6e571d741dfd3c0e92403a109ff6ec9b7f70535c6df2c1e60537fb3fafe6c99ca6c8b0acd6c2b6756b410630d3b060b3a58d0937a9b042b6daace8bc39a0f87d122c38209d96553ca6c745d74c6ea889b7dfc20508033b81c9aa083a0c93874038905878fbd84463427651a32acda86d16cd58f92e2bdd0d97a46866ebd28cf428accd2463049144cff229dbf3368a6867c3c2b90efd2dd5199fa10f547bbbe1e50e0951c1bfd086d5947976d04c2fe4977fe644319cfea2112622176327f4e129714d5dbe33cf8bcb95237a7e510e1668fb7f5c51023ae3db2b8ba49ddf9f0eca1efec402cda3c2d054fd682187693578281022468b3a6a604adfcb66b6a718344fd0d5a1ae03173449ab78a1cc829980e0f6dc5d91f8a07d1ea32c31b1ad785205e776638523f788c314347c11957bbbd80b374ef397e5d3a31a105daf920493b9bb3beb701ac738bf906b4fd03ccdbe4b09f923e5551f7241f43381cb5a27602af570624c14db3774dbf9747fd800249c192e67e9e63aac9cac9e48057fdf155a577fc35bf9134317099b64b85a8a5744ba9b440872ef8e6d7abf35acbd04861c2d59b53496632119b0007a89312cfb97cff6d4f57b2fe35793677261abe12b459edeb996f74c30650a0792119ef9700adf973c00b3537aaafe3c9b448707c100b30a24d3f012d414f36cc291b6af2ff94cdb0f76cb6ea6b129f466b702ccad0fd6d8b99835ed8e6cb3b481426c2bb11e57e117fe590091c4229924c34ef030c1144dacab32ef4fa807afda534eafe958be8892b6e843f0deeba39d2f711851a4aa693feea33fc437744459e105712a2160bc5eb054c35c35b424fe6c8760c4bc8f925ff452b7913b4e416749ee48386d36e3e6e9af29d9feafe3ccf9cf42194b2d24774e9da182a59e14268bc9eb81cc2dc0cfc232d5362afd0da1862d12b0264a62c0a9ccce61648967759e0359ca7f0ddc99e25682de13876c551f23cf4336f5d88716008f9526af3f14a99e1514872ca14569d290c9d9f36f655040820b1255fa0e97b3f80e17417959aac383f8ff197638a47624a058f704e1439c13fdab94e900836fa3911a13328a2347507b0cb4ff63c686a122e23b8ba0ee8cc21966aa22db1b92d58c913aa876ca8a9dd60853a4dcfb760ccc9e50e710b4339eb01bdd9344f2a30cefa95317b017965bf447100b703a07451085657c8df483679788121d675c2820ae1070248b46284036925edb7a06132ce2a943e111b585123be604d8ecc0b1777af93a540bc5f9e1e7cdc5799c65d7423fc518a862fdc698c5be32bac20fbb1d0f2dc41d011d034319fe02c2154e064cbd204fc0860cfed60aae55a8ba9230780f31f8a9631c9acf94ee20730242f7b695fca20b002086a4e04a300166947cb6d7812f754e5a83d5c76faff07a0072b7500c7b125e2e2ef15f6bf2498f4b7812d2e83149ea24a50185e09ffe5078f9da944a60a391365c0ffa96e6055388fdcda03eba851ac03e5d736651ade4aa54529d0612cbadc5c4351d28a5b7dcdd890d0dcaeb5ad2d8b048e1cc8a4466c149b577aaed0a357792bb1c26419fc750c681e2b5024b1392ddbbc84b1c501fa5c622ca68a4ecbd62740e5f96c65387846bee10b14382e177af167c12bbd6756a15e64826bcd3df531406022af9e179ac496343dbedd3cb7532cd23c6f3f429a5ed1d0400f42eafddcd34a6776372416486b5009cba5ff45a70c3104aa7eb6a54d66ac272bb83c786e4e3364e1e786f57083013d89721fa7e3a192e1b8633c40cdde621615498ff3c5f1793b704a27bc6f36580e6a2a5c1799ecf3b2fb1c6a516ac4a12c45c7ef87f19bfc750cfffea3b64c34e9d7fa75c8b7219b70d92c6cab6c13311850d18eefceae8df35d00642f3a7f79a8de06605c93fc23a9ac45a419e4308a89382675c9e79aa7833d9f52f895b26b0309938a7af24520e061c984d3276a136b5d094532d36d452537325942e7e7ff4c6ceaafa25ffebdcfe1b5b0cd7e1fa084ab3d18713cc8295edb83c64abe890725728f5459c01f9d46595013c41fa752db2c6aa6653bdcd0552384ccf118ab95d9d232c06df5ef249132161791026c1500853755faf0fa6caaf099d90526e7859863de08dcca5a5139b1ee568ae9d9e7f0093971d883122b9900b382b612094d05ab9746b332212b5aa40d02003f66694b1a77f52af97420a43f2df22bb29a4111a4912bac8fc8bbc4251de925f96561df87e38875e6b9fe69c1053c7c3019993f1ee0ee11504cc0f19810b0a43ab4fc2b76e71bd1fac498cec8a12509e856d6011e9881304cb23cbae4f84b5aab03de24141a7fea7da0389e61e37497a878addc42b5c8dfff061727bf557c580472b3351ace57e162b1d731f1125c5ffef82e93bf7bf6b7b4de5491f39cf1de74aae13d6e1f1fe30235a49080046aef913925db858efa3012f9244bac90106393713e26cb871b5f27171c1dea719074323faa6a5d900409e28500b0f057a3b576d045196118a634446f23802d29acb8dba93922543e846f905a3e5b1470d30c9d95b808c913a6ae0178d0cf0d8481e2cc478250ca4b44e333e3d6c0dfd7bb8cdbf49be5833198708041afa67e2bab4ab2779fe9c34c4b5f5f3be759a5eb9d9ba8d50671bb81231317858daf82ded9663245d1dfcb4164ce8d738f02ac146cc7d008c1fdb7f54c0f4803a0dbe5f8c3e605f2c547b89fe3339864ed1b2da0bd991ced317c40376c5f2a354e4627881315db417eb20a85c08d1bd5c4c6955273084307a62b9e42af0f55262e54c5981a6e110df34e8e1fa0b9904628adecf83e4fbb2866f491c85f8106aa1030aa96146296543ec21e02945003fba134e46f6e25f393dd0a6612aa102cc58965e9550e48c389c1c04a326470cebedb427e442f8b848df82a8c5d55eed0d1446c6e5d6e0ccdfa2d219019ad3d400fde350d690cf04d083844adefe5069c7066b0ea24854ef3f5853328d7bb2ea735b370eccec5f0f777a467c98f040c423fc4c3df237ee8b1e9cee6c859c860c0297667809ffc0b73af9815b01384834fcb56d3e782ce11ac9124345a3d34fc22ff7e0c3149d66f7bc8feb9743bb54405ea88902011cfd4ed07ee19c6b8e6de6dcb08e2e86427e5e675dff052652af14d7af936f032bbbe508c54fd4dfbd16921e7b1c1471e96f3a521b911e32a5888b5a4083be97a3ab843a1dacc19e60f161fd84c10fe94c9952829da6979a83ff25faea14df6f6d5c876f3103a8a93deb51a3834c9da185355a8b189585f7c71ca082295ba29e326e60b9d08ec5386deca533a03b903541380cdf616135e348c6b09a5cd4a074d7c2e3d794e44a0c4ab8537f3f53b12ad2c2a996c5ec0a1b6d9a25d920a782bbf2120262a71f816a66ffdfedf5e5dbb868d37517607e880d697720a0119077b19df4e9e8709a177bd25508b00c6c79d4b1c1ca7f607aa7b18e6f93e40c8ac9d8705bd9deec9626cd4aa06491416430f1e204177b62d1bd18e9fefa0da4d6e032f785851dcfdd3e2a2058b1811aaa976c30a067d9accbe4504abb7c2a39492889fe518dc529cfb481320dc05a785cdac3fd225936716b149620ce252d079b0f14a947bd7efa17868935b6483516f7653fe108e5c1da91db5a58a3aaf920ecfacdaec9cb997d80860e966fbc4c2cdc52f41fd3dcf8bfd70fc4a28f99128b1b5e0d412c91fd59a9deea1d9b5170e92e1ba12064847d72f9ed9a58874ce906252c6679851b735cdd5f3f17e35e0ec6117e83b9718e85bcfb608428bf03df02e2950a07e80844403f21b8b0e6ce349c5ca2c260aaa780949050d2d9fb90f890e0d33b4a8263b0f3ff72d06ad34072f3567c85a6e301d5b374d9a78a94e5a3523735e3f9c2db0734aa7c7c5787879687b485f1fce35966c742b896aee8f0361d98ff221b58f0746a0bb4ff1443b1f21eb26e1503187f52903a842a278d3cccffe3328876cada9acb5f109f1679265c39ff58a2f5f63162117f63556389d00b7ddb9cfe0346c62344ac0c9f130294d0178425920cf8c5623e09bd387d8f1d1bc4a7df18f8f38f20680ce2734505fccf2d7e13a0fa68ae5f7f949346bce6896c992cff605197740913534fc38ab50d679c92bdd04e6682ffb8581c3de476b13bed9e72cc7807e6ae6a0f0fca5cd9a03086c1a5971991a7e0a074c128727a4fb8e63240df8d4e87ba2077b50ca0c1de5ca6b4a09fd2d16022aad1342b0dfcdf706d13d433db3f592bb467f911fdd09969d1fcb4fbe4ac156a4227dfba8999642bbb7239cc6bc02d4e1cc5ffa47642171b9807bc2e62027befda4cf5d0b994e36b110580f40ae0b8505bac989738219bc3deefb4fb85037482687f8f196ceed78ef556907987d952b042016046c57e36e47e9d5e4c71d5fb7bd2327809e4663d75a402c9b6d89857d2d07375273e3142dbfbd1c4c658fc64e2436ad5d8a714d9a626b8c6a26c3ca5cd8b7bc75162e5ea63a1644e4365ed6b16107b8462e7186586b0b2c43f526f0656c544b70f5e59e809462b1e00853cae8bb57e39c55abe0e2435c53bf68c0dd39e3bcf6da3250f4ad1d47f1e9813b22b109c9f2ca6b06b362f8a0c11774cd90321561ea5633ae94828698a5b87a338a0a1ee58aa9e3759a68ebce835ab5bffab1cb564a704c220e8f451d02ca511d3a61071e59d7a638c6eba218fd186a9abe7144e21dc862d71cc14fbe19898710ec7321917cb26df10994c2d4980eae0c9c512cfaa4068fed52d0c57c9dc3fe75b51f333210839a37ff90e8508bbe215d7fd50cc4c90daa00e10194fb660fb38b9a85be80afd5232edba10ab7c98dd8e5ca4eaa6fb7828b529711682b92e5c980bc877a83b9d7f0b848181110e370bee7ad434463f90c954705032d56c0b86305b83f61642daec190941c8b687f46d70c0c0cb4d627c0af930844189d3df40c1ac2c5e0f19e598bea0d6405cbb41e35fd850f26bec7aae8873c883ba0fe69c268839681796ad11c090e891f6cedb944fb4118092d8b4397dce87fb4755b1ac74217d12597496c41370c4653df24c3df308c2c9605efcaa3e8fb55250eef97ba85bac046d6aa82d249fdd348bae7b1f6e658b8072a2aae3dc22920e419e656810cf8f80398bd4dbabc4df89b4b46328524ca43edc03677156dc05a215d2c504db8b28e876a1797ae0b57de85f634151a8bde6002948ae1f540fe4d5f53186fd979992d4bd95c2fffdaa0d02596e17b439ab392ae0f50e6bec0af1ca9668890801d5dd1c9fa69c06ef9fb04b9b0260e8279bf93f1fb0de27d60b0c0d07329f986aa78e6660a8d0785903e7bd71fa74fa1ad87a952a22ca0c215d035817ef038624b5445a326d84ca96a7486058add15801596906b1d78381b9092f504db0008628d32fbca6471359d445a248c0019ff3b8f6157b7b45c14c76ef673a927ac5e425c0a2cb71cabda5b2f323aa037543ffe1c84c1833ac61c016bbcda50b219bca8b2d210914e2e6aaf5483c943fd4e7c68228b26bf751cb466667a66529cc4c19812a8306a25776f5ceb24a601baca327cbaf470a61955474f3d9ae0aa8fedef83fd62d1d1e843a835c3b993a00f09faeadf015cb28d01b01fe5ca49864b667ba0cf0ceea8439d39cb2a9ce71f7b3a5a9b2774141bfd68baacae775d48ba40cfdeb1d1018f77ec090a44ca5f4672f8a1b6110421edbf5014dac6469e980d3e207f43e25353c1a7d4d010974e145a7cb8a5e05d7d79c7f4eeaacd410dab582adff9b9ef8ffadda3682651dbd8ee69d60464070908bec020c622cc00cee15aed981698ca7d413b83b78fc1a2e6c85bc11787374342b243093d26301476c94e671d7008c7f076dfc7d5ea5d765cc4e82b0fc85ffc8c6637909142f4f3fc943170002ee6e4ffb8a3807970aad74a2aa0faa7a3bdfe4c925757497aee9bd3c1ed174e3aa9ef62d6c8df963d0272545e3a19aca824d7ebb9e22d1818f67e98d5dc3e1b3c45fbbaf8a5e053db3fa77af51d975a22ab70321bfc40af2e3828542f4236adb4755552c9437ce84d39332588d33eae8fe5119eccca99d74962a3c9f09ee67eea15f24e58fdeb5536db348f335c67ddcf19dfe848cb1bf5f2be87f5641032816376f9dd3a983822463898a9ac4fa1c88294747715251561bed2933c08be3c006f05a7b3fce71c179e9fc1bb1de53392ba96d0080179c058c441b9e370714526fe5a01dd1ceb43fdbd75efa6324d799955a4cf9441f50c25e456c6436f95fb183851782552a4e3ba51d2597225b8f2b84dbd01ab4bebb18a49712ea84e86297c4be4e394a3d88646bc8da23d09373a2534fdec05540253bb9435ce0f9c1ee444de9557f880d3bc81ae16dee47085dec4022057b0d3cba15569f542939f58609cdacadf9d5055a9b123be4fdde7985a8a4eee0d37032769527587fa1e09cc7122c8323d1c7ca23a98dd63e970031d8545288d6224c9cc034e60731a9212a89fc6704e67f4ff3638366168abe7c5300fa1dc6b95f56e079cc9b97595750031d8d346244a5619031e924c5eaa8ab82200032737621f4e5684fa19c40de1ac18cc6d416ca42dc59e52b07e1a69f3dca3ce63ba55a4c1a3cc761148f83808c62b840b9252ec3fbb2060b9e7c75f6d94891722056d24771bdc8806d3c5124153b2e07ccbb16b02987c0e0ad70a29b48ddba6a3201ed15f4c055ce2b9e3feb5a7ff082215587c9d891c9c02c2eae1c5efd8625c6535ec57be13465f5d4b5acff1945f0a7a11b0e41546b1e8f3a3ae85fff4ec1c89c2dd44398d04e7689464ce2c631929b4652c9e7645684a0857d6c2cbbe2363496c88a5d05050fc76d488ba7f953959cccb5ce8e062c203df001a542cd5e3ec4fe97eb15619a9149022c9ad71b9de36a3a5d257a0d3ccca684666a703ded560df69a53ba546dbade63093831c306d04bf0ab91ef00f96e22edc0e9745ee374693ea38e7c9a66f766d395be678036af3520d65e817f05c7a9e4b5ee15decfdd2c40e6a75789c112a2cd02da7e7aaa27b57b50626a8f989630b47550d39efbdf17d08da5e066039e2be80c51a0221853d0d840fea4e5d0a818de468b455d1a99b98b69ba89c118ff0bdcb250fbfaef760e3eb3098b92512e0cbf2cd32052281727ce17a1d55824fe953029190dab087eb179c5981c1e785a2400bcacfb5fd63025983d3841b2123e21b529bcae8f9162068db42e1280053dae8de583b3b713f2f78738df67188b7a01f40f0918fa1e51ddf85757ce251e903bb996d87ae4c845a420e6333e0a3c292521190d1318d4840446166d1241f4a837b47179ea554e144991857037225cbcb44e782a9c08d58f166da0e7dddd3b05ff2f7cb5ca53e445a3e6c06a1e3e03c7912619a8418606b4b5a6d8df274ce2aad313d5ac4305024352e9219046a0ec8ff68f6d7ce075490b9bd41fc9940f8a73fadf6577a4742f08d0524f72500d944e950ec1a7b45d2bdd46df4bedae251dbfd53c97a4d3c746de80214c46675522ca77fcbb13500597ad629d5625f9c2ea4c38d1334225b00ec20b9127dc4a15d65f129f4f95668768b51b02341df16c8430c163878ea13ed24b683b993732cc35b987c78e2bd25f1fc6ee4e152bd489baebe997a247076d380c092acecb79c91213a29ab370776cd2c3b3871204cd156e2ce3ff091fd31b65cfb824f14f400f6d9bea7894b8e2744e60b68cc0c05084c024e1cf64867a132f7429c9411fd0c9e225f4828bd9f523bdf3f5a8c21b09dbb8f4770bde3a488928ebdf0ff3d2c300bf6f4eccc94c5b1e4551ef25d144cdf78fbab3fbf37f01160ecaf91b153e6a9322575c082c4eefcfcb41f606eacbc87e9ad7022a0916ca782ba8a2bf4f408d135a1605c85ba1e211a78747ffbd1ba7c36589bb7cd801166efcf55a8e2e9e24bc6cbcfbf1ede191a777fb4a6a67a39bb92498b8d06b287882c859d668a7757716572334aa19f4624fbd7dfb3cd42a34f6f12da60c850a21a2e9998bf4256b961200e57621dff71ff89860ab8f1388b889e6836fd22f120d9f42e08f4999454c0523038e056404d989a3dbee88cb59a57efd7c5bd3827bc85a0bc8c02953ed0d7dcaa108c115a48ebe00c19ac6a0b7daac1b1468d6d8252e93f061bc381523fbea0f248d4de1945c704fd01510d54aceebfe791ff1a44852613dbeddecf2e7fdff1e981cfad3c615f65ec413546c787497f2dadcb2022a6a2aa463bdef07ce1f303b06c8413357261f8d662a71d344737504ba69b8be1ea8252e6838ca8936dcd7041dfd6a646d1cc0b12436f3c89a7feaf8f57fcd34f860017798b1cfb22395d2f2836dd02988ac37178f82e5c543a98b8982e59a0729168c866526ce53173da0b9300e6c17ce85a74032f052a82142b290911a0edb93bade04baa6e061678107143823fbfdbf3c06c0dd0de671ab6567cc3ee3a657e7ecf6d10acfe4ecb89f9698307623643468e0ecb86d9d9b18db9ebd3272d674b43d42784367f2454b3759ca6bfdb30a9001d8b0ec48ed1378d40a33524c3a81de9f331833c8a3e9cee970f651dbfce88b26ed8f6a4240fa2907529e11a44d4b35483310d25e3c006f2d7d51432acc216d43a4de48db275262f925ac1669a7e6e9317fac48f5a8c60620767062e78bc4d93c3fbd5dd47a332512d2fda7447f76a7badc77f862f290ee4b89804280f591a6badc290d3e128c46b681e69d71c3ed2a3b6cc4c530e0479309d6287b692e08529de31d830126afb4a4652a8aeb3303d3547d00b93b661edc1b226d6d79a7761fd1e43264a090a0d8e9cca3454ff74b8257714e299ed3c6f5b6648b9c26bc78ff09121b9a485282e4c5c2b240129ac0819c8532b0b9cca4472c180836f7285d09386581375779cb546d4c8ac6043b3255ab1035c1d6e07647f453130bbe2aaf04e5b7bf49d0cd6474c25a75c67901a23870ae77c32e61af3ffea207f8749100649c3cc054c36691d4127bfc7ad18e1f018ed75f0609001dd83e41d6e2ac66964c248eccb2802c378c9252146c8674ac23b81fc13b0089add0152a1141a6472370df94ae57e54ab1c3a26c55f24a1dd0ccd360e794f0a63987a08d50ffb84a76d3689ac1211ea5d8917dedd6abf81476dd0ac1c7017aee6abc9ee1a41e6f5edd0b89b9d99983857dc32914abc1e20c29c2c2882c21923c947c980e43393500716ba97ec56ce33fd4d01240988636baaf5aca649f87fe606606fecb888b6a7c62dc99688774d648982ce1cbaaa3282467050963b31d95c29f55d427d4166b142f767a695ee5be116bfc9455f405c12a1c3e7dbb14564f94c73dc0a7af0aba2b89c172b2fe5f9c059c0a51fa792481ba1fb6f97faed51fa1e1857eafa818290875f34d876e2a17e5adcc7bebc7b01b941b9934c2e4942e9064d836f976444ebff2dd6c52f44fd9132f4a4a0ab659f052f5b80e6696d217568dea33b7a90302d011384961f7809b0238ed7e26a28492676e4368ee5548a3f5be6b7c3f4342ade03db48e82bb247dc95b52638fc38802881d0c2691f2801d0be3a66700ca06e22070d3987ff4d44db8f952832f0a74e43f77b7874bb68fa67435fffb3a5d98b034ae7766999e8c9563366a70d86110deff01dc7cfae0391be8ebad2fe2d816a06daa82ad16587e43c91dcad74b672541420d12c50f82f737de005ad7235436f404e87ae5b3ac732a92a34bfa3c20f267fd4c7ab07947232044ed716b52a0eee6bbd8388d7e4d15c904a4ac17bc8a7c57032a9e8e8a5c30ceba4a078e335cf0db5a938e3233d9e16a503d741755da53cb2b848c86c25199e1245000f93043ed0b8ca80200a4d1cd64118869789d5e90f2b393c38faf9492f91051c29563e737b8d7c5c704dd199696ecbdf796524a299394015b080f081b083dddfbbb0e92e54cac171d082fc24500c43d3192e533573280171d8acfb0e33fc3cc2ba48f17e79700bc38bdd079718ab17b78f8e26c5abd38b570f0e2740200fef30889f313080d369831481685caef5a062fcea0a9e47b518a91645422baa2362f4ad98e17e5171e456408b2077fcd8b52a900dbc50e7436cd8b9f6366bba86dff1cc9aa4168760028e60680a22e0104c59bad251901c5cc0050d40b004700c51b8d480450cc0a00455dc4a5116dfa2180e2cdce50208062fe0014b50730a84d3f01a078b3f3880050cc4440516f10146f68363a0028660380a22e402b1b6dfa4240f106cf7c4031f780a226c06bb6e9077961261628661e50d41d30316dfa406694857f80621e00286a01f88cfe8ecf70cb0728e60080a2d631c2ad4dbf87d175ba30baa20f0050cc1c80a25e81a2ca69d30fc7bc012866ad0128ea1c5054c1367d1c50bcb92ebaa26f3300c51b15088a2afd81a2a6ff44f90614b3e6018a7a0798b46d40f16657998cb26c0d28dea87480a24ae70045adaa59e300e9cd162d28de6c51dbe055ba1615499d99a40227a67136b3e19bd31a5112b09766d4d42475269426457369ad198cc2742a8f5dc49c9868100d923ad9680924d86ba63edf5c37cb3564a1ecca2d2525a9c314862ce6e4464652c777b7e1177e022761240c0b1386c32d5c05136121ec72fa7c6f4e6540c96257264c8a3109690ae5ebba3f5ca32b044605a9336363665032398620757cdfcf375791ac601a93449c2d933a54db5c446c2fbccc10238707fbf9ae9f6f4d4657f445215949636df91d8d4d8fa40eb67c20b2c73f67b1ba7b752315f46e7bce0eda5fb6a9267b2d49007b326dad71b66912d4a63ff67c516362e747142005d8b283098a40f6fc1f76fec654c294404ca94bd3d6db9f7ef69c2a5a7a983d147776a84a2582ccf6f7917252ea5cabe420875486568656665b9e200fb1b0b267ce13a6e7d3393fb9bb3d6d0e91aef9405461026da74892ec49bd6c31f7b03939e80955ab5beab9d30f7e53eae1299cc4113ba16def4bf92738cb47bf50d65aa5fa705321fa725aedc559dbb8ce4bc9e899ba6bd2e66cd0dcc081812a878e1a9b1d3c6efec3ff9bcba0cbc02b92b327160f2d0e4e475f3467ad73cc3407e3ae38a741e7f3714c74e57405e6a17d24586ca645cec5b99c27c8593e6f61b287522ec63ddd7baf067f2f0777f5f7de7bc3bf37c8fdbff7de7bf3f7b22ef8f7de7bbfbf97e7dafcbdf7de9abfb783cbe3efbdf7eef87b815cd5df7befc5e0effd7175fcbdf7de1c7fef002ecddf7befb5f1f70ae0e2f87befbd37fede9d5be3efbdf76e7faf8ffbf3cabd7706e0de7befd5b95368e6affe7befbd3deebdf75eeeeffd1000f7de8b736feaefbdf73e8de7c1cd206783202c9e0e80fc188000767c0440a7070034c0d10087831b2b1dc20d34c8c1c9c0c6df70cfdd703540efdbb8edb79b8d9bb1e96ab66db3d96ab64df3e0766cdb66b3d56c9b8c6ac360db3ea523874c25c340e6d1641be3138d8d0e870e372e8d8d17a7c376d452b9361db455c964797399ccc7a7f18e3e6ee08ca6b5f6cbe59a1dd49f6f0ee394cdeedd14f7b6e7eddf896526f9d898eca1201c398bd26a85d62b58b687f3de572ad2a702ad5eac55b6f7b548f684ef7d6d39ab6697e76d6086f4a9473c2f5234b677f35e7dbd9e5e605e514ecec3a30ae953953a78915ad1247b3e2467d5714c1ac791e98af37c11d2a73e0179911a01933d35ef3d1d725695c968d191f754c87974bcf7148af4b1403f5ea452b6b703ca59d6356b79ef609cc7e6bd772fa48f3d7ad1c1d81e064bceb2af57d3cbcbeb69741e1c4e481fab248017fd0925d993e3e52c3b8eb011c953bdf7ae83f4b14f3b2f3a0fdbb3f19e9579900f156d2fbff7538cf4b940d3879d63c2c89e1b31675d974be68272cdb6477385f4b94701f0debbafd7547a2dbd9ab647dffb7984f4b94ad387d5797126b1bd1aeffd2472d61dc76934bebc991e2fce29dbbb4fb23000785186b1bdcf80f4c140f3bddf80f36cefbd0ab207bb64ae984882b3b0cbfb22d2071f4d1ff6a5922702d9de6b04e7d1defb10644f7def43e749bd062f6eb0bd773c7ae08b747b9f237db0128eec71161ee9cabee7fd943ef869fab0ef79af81e78197b4ab8bb2b8eaca711d4d1fce0acf1165715cd5ae97d2f4e15e1d286dbbc964a36c94d5a7e9c30101a94fdb7e9551d6368e553656d9586540d3677bfa01e4a2acedf572bd5c2fd7d1f4d9940670f4a2accdf57abd94a6cf762400a56d35996c948db2a7e9b301edd8a76ddfca284b1b472b1bad6cb432a0e9a33df900725196f67ab95eae97eb68fa684a01387a5196e67abd5e4ad3473bd2511a292bcb64a36c948ddbfe7d9a3e1a508ffbb4ed5f1965e571bcb2f1cac62b039a3ef90900402ecacaaf97ebe57ab98ea64f56e2e0e84559d9e57abdb2ebb5ed63a5e9938fa6064a948573d65886c76d1fe7e39e9ea64f069a3e641508c8b7889ff653d9531995ad40fb3494d98083715634c801713200410ec659d9f6736e523c38ee75f3dc6bdbc7f9bc97714037321e321907b4ed6750d3e9189f6a461de3f8b4ed833b389beda554b3bd746c2fa56dffc360c3b1b9b6230c36178ecde56daeed68dbff1c9a4ab6016120c321f3641bd0b67f6323e7f1c9c6e88d797cdaf679dcc034da4ba96ba954faa5b4edefb8976aae23cda5b934d7d1b66f53c3ce649906d4b564b22cd380b6fd1a239dc7a73c8ee3530d9ed68b872fa5acc197d2b6cf693a2a9d4cbeb3ebc8b52d78b4eda738a11c3e95641968fa6c2328aa545a63d9ce40db2ae98f7b926de3f4e1be481ff66d4bc5c5b4903a761bb77d95f7816f1930a78aae9b6cbb93f3881369c79c47ecfcf3ef590478fb53698e7329ecaa8baeecbb5c1f3817fbb8274ee6a22c0e8cafec87d996737151dbbab898d4b13ba78a1637d9b6bfc99c07cc06c5c168ce5a4b0ec90d50b995742e666dd6aae7643e2ac3e2dc323f559a0c78019c1054903deeeeeebec3f3c0531f0a1e62145cd91c6c990505aecde974f373ceba757fcf885377b73216dbf5f3a79d6ea79b1e50fb1944e1c62b32c116e6b6e005a48cba165fb88eb65402e8aa3fc5acd0b10279c57568e31ab4f15331d2474a1fdbe3a761644ff7acc9346663c7130a8cea098bb429f519ff6cd2a09851e0e1d2fbe0c88f15ea7419e5219612fcd1cd8fee681af7daa6713bb6d7669ba79b1fcd5aab7e0cf7dfdc600acae7e119a9ef3b3c112a131393b7349d4c934903b9209d134dcc06e3c73b4c745535d734cdb70f3450771ee6fc6108c4cbc60fa429c706cd01e92efe1adffcaa5d8105bd2b2075f05340fac05545592af80abf93e8318fd9e0094e210cbc22149c4473c83d83f7834c1fb9e3e1bcdbf4a9efb258de728c93e1f08a5cb07a78856cb3baedfa2777cd5da76d910034dcf950f594898eae83c81eb977360d695efc1b3830f091db878ebec2ab1b9a46e5ab95d672784634217494d19ebe9812e9c8b4f1774f71784552600b73cb8062eabbd75ee519d1de035b981ef3108b1e63fad1ea400decb4ea7d0b75e74722b3f3dfe764073e7d8e7e3a609a82f0f45e58464270b8f3a1ca5b9476ef19a1413ce4412226991327041584ae38cd30464a2e0b8235d1592daae17970f347e319c9e01c0245ff4964348de88bf7690b48c82b72535c900e7ff8af52693de60ca1ef4feeb989bf7b7102b16b7846f2fbcf18394f77f49af144c8294febf09b4393a8a3e338e6ef5e14f2c022fe4da26f0ee550c18f82d4c1eeae4e88b350a02bac04b524674d58ca1fc0182d4e214b97a40e7efad151882f31fc9f23c7cc0c550167d7b450b73f1299edf9b387ce231ae1c04ef4d745b6f7231c38893238877c0a4d21222e7bceb30905ffa43c6a26a78c02a5ed15f1dec116e607f953ef9e7f4e7d2ccced81297846dd0764fbc40eb60bf18cbc4f9c401c89418c266c638c9fc39db79c07c85d1a7822e4f7bf224773d65a2ce4be14e877812d878aa64b7404e188068f70e0053cc4cfc2dc1b98c28f17f0a3e03cdb63cca47ddcf6e579c5c6184856d24baa9f4c94557de5df650d631ce2e778ecd3af7e8d4f888c64eefc3b94e54fbec20f66e3a8240fb33106daf88336fe1f4fb4e87f57a8fee4f8bd22146c61ee0c6ab0fb68cd15c6390b37701247ac42bbfefd797fbed350d09eef5836fd1c22cd45a9e09df781ddf9a5f529377c737cd022654d222faa26bd9484ecc9811e217dbce88acf5c70e127e8338a44dff31630ffda22f3535e91f917949bc23aafc8b49bca7bc11e1e52b08e30412959142657f591b4a45de98823750059813ee2ffbb3ae82fe93fc41dcc41e8191235729ea35a93f66d39cc75643ed2f695fbfaee84ece9be7e37df03c5e9b2bd790b98bf7945e63b9483f1996c86690c6afa741a8bf5a0459fedd8b3524f531f7df21585499a7a5f39d59aaae87f28f34b1ff19887f55998dbbd7828ba93c3809c4774a75dab4bf6c8fa4960c6a830bbfe0f18b4e84eeee43c1e73e9d291a8bb23d125aa44b160f19c4daf7858fdb9499f3cac150884e915c8c34a6352a7be10fa087d16a62355094495c89eedb9dfb6bf9fc881e274d9e6b0e8ef3207e361fd9c1e747d975587c252a9087675905e79ba3f63333663dda657a897c7b111298cc2fcc859da8d5ce25abffead4857a44ea558bc68fad023a48ffa957af926d592a64a49489dfaa2e7b0eb733f5c5aa43198f388f4efd72fb2c78f50ff90c8587fa7a1a23ddf7d3ea5e01cba9da8556eae503757bd4e596d8a7a719e1e3416be4ad39f4f9f648fa493562ed5f99e9e8775856a77f6d01271a0ed3b149c3c48ee0fd164687c04c9058f50f07ead427f86eab306ab874c3879438b9656cb3af3429cc77e0c170ce11b2104e7a9b1e007b66efb41926d2b0d61841c9f5c51f76ad4ae4f6badb2d65a6b7561df2c575cd9a21ce5df0fc179ee8fa0a239abaefc6ab0fe21839e2d0fa5644a638271cf33342e4a29e5e74c8f3e2769473f107ce30fa2895cad0e4a991227845215826c0d04d96208fb88fc4e0c617bd769da431b5fe34f903df9ad9e2f93f26eec39ffbe8d1a9fd42627f3a53e51a5f70557989f0a415436dc092dd0b267befdd944f638cf7dfb53c8ce2b2205c50f6c79c54e20e731c1431baa54f2e7bb6690ec9992fbb7765224e9c3bea863b59c55f3d321849e20d878686d9289f4f22d9d394fed0312a5f3d39f4f73e6e867bf15ac7d77495fcd7befbdf7de9ad4791ff8bef7de7b6ff579e9bda9fb61ce5a7b185e9bc569698ba1d427482badb4f2f39772b6b4f33895f1192dd55a6babadb5d61c1974adb5d65aadad44b22db35811dbf6a5d7df62be9fdcd509cb96599cae6cf7a6b8ed59634f1d53f64c4daeecdb6cc73c45db97dbbf8ad98413ee0ff10bde90e9743138b9e5146999c50a2b5b66b1e26873dea9bce8a6a524d1a7a391d9bc907c2041640f1a6364687fe44abcb1e9933da93742d40ccac3a54d43038af5b52bd0ae11db63173127262c5b6b50a4443bca630a4316734aa540d199f6eb8924249895dd75a0e8aeed5406942cf6b461528c4948dbc6e1d89819942c67242b98c6a42b9bb625dad93b5b4be36850dba62f725bbe4f9e3ee8ac51482964382b1572456b8c8c8a85d64d4f0149f6bd56a98e7bd22dbd9a4445b28238e0c5da43035eac4294f0623d8204aff1fed40cc942c1c88bf50506bc589b2ce0c51ac3086ea30ac99a2e115ea42950c08b748b222f521684e0ba08c99a30105ea422f8e0456a020f5ea45912f02285512892359d10f0229d81c88b94ca7e91f630c4535e4896b70ef0a28b618017dd8c02bc485f1022e38464f9cbe745d7d2f3a2574180173d05415ef42725193209c7599208be3a68d0f225b883657b9c33d775dc10cfa2de19c43f846e1e601ad504a7f6947e62b735aa499f6e339d765ad5d1e049aba6b1d91857156caad56854a1a6654da3d99a06567b6f9d9fa837e6b4ac69793e0627c6396bda764268a9bdd652fa73ce3927a53f2db5d75a6bafb5d7da69a7b5d65ad05f033bfb48926ed68871d2d68a55e8c40e23a163bad79b820e4ed061462bd44de3e10d2d7a6aa973bf86ff2a95be5ef40929489d8b8287f77384d0a2def763f7fe910d50d6101530207d24307ddcbf7f5fcf21b13dafd8f367128b9b4ff82183963d74df9f462fd0dfee6f1c0625dd91308d9fa6e0f7526b41fc9c6704532a653b9b42e5e94634d28b1bdb8dcfc627e5782754eeb49c2ad5dc4013385054a924b881db089a90672c386b8cb2868c4e20fd46e0e40f710a66106824db390f96c9f9358953923d9e13b22725f3a91428cefaf2b8fa929d95ef7747cd987bb31b38db665af5219ded189d51564542ca39d248cee37bfe48c791ce2315e6e1b45291ea8bce26fe5918a82807b3e7ff8041d797f36cf4079a1fe22c1af071e813f5329b3c9c4b37b468fa1cfd56a8938629da602df270cea4ce3c729f85b96945aa583aea3cb282a92c903d5eeabdedbd979f98023d707b2a6e4f917eeefb5cf7fdc61487c1b2ed3737fe56f02d526a86ec997b3e3d63b26a8caee6cb6098d5c99e55863d5bf8452057f34db0e767d9136a4f2e629dedf99c5791a4cefc9c299a22c5f6fcf91628569f8a64aeb9fde63c582e6da24e1e4eca654fba14c659f3e9cc79f03f8eca662676f3e992cfa7239d383634b469be3365cf033ac58abf89e59b41334916c6de2966e447328ac8cac67fb7ed3e12996d04ff055b98437cfb8ed0df6610c8c29c51b2a788b3985a8ae9a455fe10a775d3bf20dd860ce930eec08b69e8af02de2dd01e73ccaef4936e7ff6f0d07bbafdfc193567d307c8f4d1e56c247828e5061bbf9633b246eee654fd9c01458d6303c59f3efa3529545f8e5c6dafa596bd3d069f137b7b1c05d8dbdfe8607b379201c59c02b78de6dbecdbf87e6c3ccd097b1349d81b68e3e5a64988d8b06103c4913a1b48f372d31f9a772109119ab79686e6b7ef7aa0b5294d0992880d319c2158c1eefb8979cb9ff4ab88b3e55b210090b187b0fce9729e2b7fb65c30611b412a09d9b549ea95c8a46472a8294b6b194957a9d4cb4c29864bcf820553f5c019811f28394ad1b4ebcb3ae794b5f370669a5b3fda39f6c22581edfa72f7d8f291d81739b03d10891cb37fb0f162fdfca1f31cf13ef450a652a9542a053ee8396947322b985f4ad943aca037f39904afbef74368fdf29e013d1089f6168362b69e0732bf713232325aa60192c8e55effc63da765b4d6325afb8ef33eb1f380842593c88dbff1338f648ed95ab6f748e698a5ed3da62fa33f2d23da2da3c1f7d0f33c24f6c5d4b740f70f1dc0f172d71a8fe3fb99791792903003fe2469251909b9806078a145e4c7850f8c59420561948186983144665e49122233a0129abf910291d8f7b81f66de7e343640570e22336093999f81ed0cce7c3333df05e8ca312801a9e3afe399408b322684fd99b742ea27765063066ca222a264e66b804d32112599aee42b513203bab055d1e1081b6658220a23221f904e2f314a9a9eaa4843082292aee42ba9f14a667e03945503d47425df41155dc997719926ae8a2a3bdd25655df79a4384ae4fc2f431926082ac596bf7604a1d9f2931498d8273ed39b779f9dccd6bda8df69b767301674d28bac23f299eb3e6757c8e573d063c387edea0791b357ece6821431210c20824384f9680b3fee7a7e03c746aee19d1344d48065050380370c240700a7da0e6f1353cbea6be6351b4555b66c1026873b5dbf1dd3cfdb4ffeffbfafdf0f6ef979ffbee771ff7ded77dead3fa6bd4781a9ac7f1dd507d187c8e4ff53abe1cef9f8eaff9fc6d3eb96f7e884f580db6d9f1e1afde0778dffc64a2fff8e70ed0a6061473ed6abe9b9f3b87082d4ea809f5a263d9f8455762e3175d48083fb7e39b9b47cddb7cf58cf0f89aa73cbee639ef7688c0e36b7e88efa8f95a987bc7cfa8300e14f443fcc6774dfd0bc8953f940cc5d9b2e1f1edf8b2873b3ebb6d3e0fb4afc1afe39b613cc49fe3f39687f8559f0379881f83cf5d9f077988ffc6e79fdbf89cc88b3ed79fcb7cfec2ef7d0ef32b8e743fc792e44a1e8efff9927b53f61975721eed77fdaeee5aed27b5cd1e11623577affed683ec5aa767a4babbdb26772ffee4b328143c6d99a5cb95dde5685b6b6f68d1d803c1e737a3b0bfcf3c0cc63b34e7bc71536e5cbf9a9c358c71ee7276d0339d87136a688a21595a9ab131c638632fc8e59e833b7586fb09e53cf9797c267bccf846b0a0c433aa89640322d84c318de5f01d408420a58a27050900e931e29e160eb0852440f2e0dfbc6eeff0fb9187dc73dcbddeb4b7f7b6efb64f4db1b2e4bd8cf6a7d3fbd4adb53a6ded3ded53e3ce4fff62b132b494df6508b33508abe831d163a2c75a942ed5d73b897414a2ae1e3836236da21e1803c18c93e331ee7307e278453658d5caa55efcce73ca4459381ed3590d6d882a1ca03f81220d0a6f809906f428edab0ef41507e617f3c679de7beab74d6fdb96da5e664b6daa6ddb3ec8b66ddbb66ddb96e319d9ba6ddb64b6ef3aaf03c189e319d9c0143cc45ffe21ce851dfdb66f6e0dcc86e99c4c9db75c4dbed7a14a148baf9cbe90ee47a9481ff8c8431c16491dfcda4789fcc96555360633141415a39449f6d0ad514da323dd9af653fad071fac0afbd967a24323bf5be395013b2a54880edfd8e8cf7da93f1bcd17b21cec3bde7b3bd2780f43e88ece9def33ccf7bcff3641ef48c78329ee7698fcd3c967951bfcc8d5764060cad56eb094d4113aebce5091213bef6de7b2f045c509a26fbb95694ac3c011440464b3c26d65a6b9178f295041365021261804c482208ef689a1a3f4b96905ba8c0b0d87105587111490912ca4c7ea680090a98c8518a1f7cedbdf7de8b63df7befd52266b6efbd59b4e82c29a8416ef1824836114608cacb154ecc96f0e0f262975c5faacca62934686826f304370dc99e5cb9f7de19165f49a5a526ed01332f610d1dc0884571c117504d88dc1df67dfd65df961833049530c43873d7f5a2a8cac507345cd5015c185da24a45174552b80294305151f282285230a94c38456152b493f1c516638ccf10a22b99f3cf0d32dae414443023308808dab6018c600c125f9c44b0022074706d3238e9321be221bee00756748318980f485ca1a105dc1623c238d9a10902a8254304c929c080c26310e957d1146ce402261915d43003bef6de7baf962186f6bdf706cd24b0d8333a202bc5ce40492042a889097624c3740415453a218b714eb0b04e8860ad566b0a26da320a588bc849511dfaf071feef903bd18c4411bb4e6890c517638c3186a2096a639cc31014add2345adf5087cea801430e5880d1058a9f31c65011c20816dc07ec300baaa207275c15474f3efc4802821611484cbc10b1c5cf84c2618c1fba128ee0a18624ae1841144ae6932e320419618c711090af649091a021adea7e5250c49210c8926a80a24395a11b4034f9f071fea160cce42e859f31c61896e42b393239d905c062a110205c3c18e1258b2b58680f5d8af0ba94c0a5559a46eba5314362965c308c31660213b431eea1cb82461951b41f262e6ac03180382f78428b2d404c61e50b26921859c0822c323198145d2c90c08c20ca920ce30e328da32516482d58985c18635ce5c3c7f9b7415aba5cb10d6d0da0220811784d00e921a78d68cc9596eb0b580e38074b74022a122a87555e2b4843a9e80730309528f785289632e00a59138ca5d8bb64ee501c7c1e91341fe7c3c7f9af42450bed89b5d63e31f2957c6598465225fd183ee009d34e102fb90aa127202a85dd42d3b8269a2685144d4dbeb811205e55a986a46ee9873a8009d7bdf732f1d68e945454996d8cb355420b0d8c1d722ca850c2894b8a6108638c9d6839c00917187ff2f4848a1374618124c61833f9f0713ea84b0a0aa32219c688fa82a50c5c44654c92a6699af653e42b7964e50a16a5127e9670184230f1e104569c0cc1840c430a1745d65abb84155fc92b198b56522dbd91259ac29d2ad689fe9a74efbd5a64f0b2ef3dc2044a206901c58c9f228c83982c9a946c0892df5a6bc388f94acaa08a84316bb98a4009e12064c87eb44ad3688d6fd0966d015ddc34848238e8d1c245d40ba2a2c002862e36fc28a1699aa66521e42b4964f482212519c9624ceac249ebe2cb931fe20e5cc64c7162cc099e98627471e24a54f5408c28ad20664c5c60a96734a518d074efbdef23048d9a664ad012941d6ed0678c3176f94a0a11d9225b18fd1845c8b0a488a84b1337bc649210d22a4da3f505bf20995165a8082943d8862dc61a59b640810e5f77982e8b2f166ab55a31608c31aeb131c618bbb6dc2283d0c6d8b593c060a225017df83817e3ba25cb0d395ca37ad444ca3d62ce643269c8702706891d8b2fc618638c316e32c2cac6d80a4d0ba4705ca0c829622fbc6028081fc4bc8892b840c92243030e5aa4f03065054a44f105d7d02445152f0a0d5cb23c63a4186717bcc08698983fc6788c2669204dbc61fb846b63998d31187a581b20c62593f029484c1c146f26c5698b202fb27851a362c0d7de7bef55c0102d4dd3d2c3089a3811c2e8c7059806241f2a52102e269911cc7849914c235dc96cbb9c819dcc2636bc144394b404132a4ba4ac00cb11627cc1642597a525268c317e828bf6908d1248100514315aa0d81002a3218c5a60b92c1947284a10dba161009391d5b20570400206298a20818bc98aa19264c91353d3981fbe98155130b6502e387cf838ff4d59c420858849c489549c1882660b4b2d529c5ab70a30568c2a3b425b6a88a2822f4870c49319943c29f1a24a9221588b0a0e60ca408a61280bce0b4d0372460f49d0e0c44a165e10c153367e5db497e8a00417b2041e8ceebd178acc86dc321446b68778b652f45333a8035e18b5ec4d4fb49c8a1f2daec75c98e84ae6265aa569b4963286a6699a56e42b7964e50a16a5a5052cd19414dbf7feb8039a8062b2538788f94a0e21cb4340e921662a225a4f842bf42efb4ef184114245f98bcc842f505a0b0b70d0863e7c9c7f210fdf7bef76b7eb5234dd1054a150b282a12a6ff1c518638ca950a2b531c63570d1fd6895a6d11a1301652230553af8c08f1645428c71c4c513938c222b5eb884a317141c143f0049e1d2c36c630c055f7b535130ba925bbb4b2d8021480a1aed892c964cd932cbe2880722a2789112810a2334ae931ff287f7091a829aa2e81283c18910d5034baf2d34887105891db00c398c51daa116162be2e1c3c7f9bf181812a30727c0b852051522b7a6b12f0e44eec5185b0d4fa182102c696202511469e143154fb4cc10021aa6e4f0650fedc841e34806335e512ef8c20823820033b524b19480a21ec000d3da320b8356d1524516a9a0d1e28b855aad56138c31c63936c618e32d474c1be36cc7259a949d291cb64f348d8a29464f90f8ac598c313ec3e52b299489f403ce3052bd6be609eed2e2a29950303ea93c542e4442331d232ccab862044c284144858b0e2e4e8a1aa880e2046bb55a4fae6482b2e2c485c9101eea92a4699a06f395444a1a999c620f1843e62bb9c52049617297178a6820818c66354dd3b4fb9ab7354dd3b42366be922d971091d16d00122f8ac3fdd162888240f518638c957c2597624dbe9256ab2110415aa569b4c68106dc84039525fa6b0c3a1830851394fd7b31de72451a1bdf8dc128c4c4ec96518a14a37ad444886dcb134948f91d7c826af1c594a9d56a51c118638c319eb22d9bc288da188b2562d8b62d4cd0821ae38b26a204e1189ad208639bc64499819e41b110143f685439da4952e4840f3f28e170839527a6174c70d102a858abd58a6225153324410521021fa298587c31c61863df18638cb36c1ac18f56691a4d0375103e4041b1a40b204d9f08f239676cadcdf9adb5d6da28a85c42d4ace51222ca259061a47d9a267fce5a105cd62a1a560933d8943a672e64bc76cef96d9ca7dbf91f27eb336625a0d17a2c72b6399909d56ab5a4dc2bb534d1b4ef6c37b9768d2c6440fd7815a3195e4489bd60c51437c81dc408e386fb2f7b780e60c6921b6078418b491573563486071b3235b2e4a22b99996427185ba9513c11e48442b9f77eb7afdf7b6b2d4307269e68594195344a40e46229fb76a1b20315306b5dc539bfdbb8fe9481914559ed7b1cbff2c5108d0e3f186f50687124b3c86634bc38bf7d7db981bf2ffe8ca1f8e2858d9f461546c9c66fe3aca0c5a864cc184a7b9aa1a90100000000c3160000380c0a064442599ea6499cf5f614800e6596526c50369d86b224485214c510a3000000000000208800829073b4a3001789589a955a9b67b75d52f2f90cb9b4157bcdd2c16ce3e00a990a31292226c739bbbd9835c20adcc6afa81012339a8037382fdd96c7f08b065c974661e27fbe4b6b2600cee951ed6d1c1c96205aba8556c83643ff8511e10c604d7a368661f77c56de01b4617dc87331da1eb9a09829d58134a28a237f74e4ca32aae8855cf3505a7cdce072f6b98838a5d6a375f2bcd63d2c995f60756cdabdf3d30f62ae806482f2e47fd2d0745d633cb442a43114e0ec4bcc81e0860d4f474b978ff8c71f480d3364e88b3bd2e3bab5e32faf69da18b2cec5c44bcde9d49c5e95099b68a5a701e4e6baa1272bbd14fd1e7692dd4b3bc99b8fba5a9c3c8ef5ec7a01abc045be1013800ec5369816f763a72e882d5cfc32bef807ff526d70d39601b99b926465357582a9a4acccd80c1d7c0992d1a68bfeae692239d12300edae46f6ab7ca0bb8d1ee94cc9925dc131abc92cd9dec37e20944b2766e17a123882e69f99e7e34aec1c67275835854084012c2b051d2f3360ef867c98be957e8668364aea0a8a4054494ac64b56fa0f73e6a633ffda7d13a6344c142b028d257aab535d8cb8d4842da4457587a87159ef481344ed96963c519c67e13addafd15397b633a8a08a34b8f0ee2193806ba69aa9f7974550bfd34c867623b14251abaf7165845690ee8d4aafecc1a9c3d4cd2b5efef7c82a8e9adb37d6935613b7d97c1ec4c8d7f0a486aca200fb12e3a03bdf243d0cdf6b57e274dfbed096f8dcbef9150e58292f0d7dbc28fd5854239db3400c10d241b4e16e47881bf28b7815201a36e38c706f89ee09557e7df2edca497860a1da903fe008c478d59a620c59a6ba01f05cdb7e18c0433643bd3feed737260631c9e07d006b5bf63808adbc7b45b7ef99aa0e5083a693e85183120e430db11e3e40907ea4618c467097b8074336ebf41d69d1874b8927312a54df0b10ad126090f2f62175a70ecad31d6ac2c30535e3e16a8ddc8948978012eaa875417b41318f703dd749607b67573e026a9e06665b282c4fcf8e299fcdc5c45993af3108d9f7046db141719d84240fcfdd6f09f3a1a9efe7603bb0744354e9c20019d4e9f5e7bbd596b9fc885e9e5e36f9fc8a9ab77be6c6a20d05a692df0b1253154b6dd6d245696b2afc72accb89cbd07d6ff1f4797a35be9f69ef5debc61b848a4c37341738aa729631219d35f0b839edb3b0d2e07523ea99bcfbd208cffd0ea2b9bbc9596451aa0dfebd42dc888495b4cf1db9a9ad6a0e38963ac28bc74e88861bd68a7ff8fdefaa4de013b5af3d5f2a02ba7e43255b2022065fa05515dbfce106f54db4f28bb7552e39881a4cd65865cf8fb0c5a1b38338633248e159842ba32e12268214f8a898b87fe3865ee5ce60ae80503f560080caf3abfc94ba346cc56d73435b2a66abcc7a44d1a1cead361b9838097d26b0ae0d8c8740f7ee85655c34356d631faccad21663422484ed4a4f5fde07582a2273f61178228dcaaca68055963f8e756ca37296d4b64cd06f6f05d172a7ed8de872a3081d11de94aa91798c980f1db1d6cada53246d0cfb194a6f62a0241bc0ed903f193288c7ca587c734b5be99d57619649cbe0f4c3333ece7b34b58c9b4e27f03f5b974ab95e9c89218d10b1ec4939bd4884953396d851d368ddfb7f13f340bf227dfd1741bb8fe5af4f3ff34e5bc49884ab6eabc5254af84399184029c3e5f463426b2c7c695e5542f3876a1597d79e0ffdff15a0a423cfd07b6eaa2756eb4bff2e7696b6fcd01092b9f5ecfa9e43cfed87ea1b0cacaf0b63910f719b5b5424e60ef026281698ffadf90c95bd336d7509676ee0250887152e543fdf4d0ce9b2835c2d8cd087e5b6e6f6c4aec81e1da1d356a58ede46d3f906226a0e856db6ae22c73f686e3f4bef09d476619aa291edf112a6db9eee92f22dd96cbfd36e35c315f161f0b46d324b0f879bcf98adfd8eafdeedccf22c164249ad8ac917983e181f9f3915ee441bfb6ad680c9b45468589bec364fc56c0eba51a864602bb0cc7161784c4224ae9089b7914eac4ac63d78e58190f1d462b80638e0bda7f4b5021af785c2d7805526776e6f60c979ce3d52ab4432dd815e35e4a0c4f94a25c16741d6911b6896fa3168042e74e8193560fbee3803a5716ef90d40c94fa423e994f9704d4563e9c484af9c5410bd89c4d94e3b1fb3f4e0493d562533e9b8a33f7032a42b646c56afb7b85d5e98267d4435a07e53b1f84a77321bca95925b94017437c005b39a486aa3415ab3194553288c478e017678604c213751d05da19359bc4f7ace368bbda50b60392e5b505e63b35aa39bd0d7fb811f2ee6a0c232cabdff2f178969e5c7fb3bcc63d0a5266cc2af47b925b1fb997088f34e21bfdd7ad8fbe7c0d518a52d68a54158b8e57d8d853c9d7b41062a71f60a10af8796db6cf4f0a7be6c8f36d4c199cdead3c01f747b2f2b830947dd087a8940e63b820f4ce65f5fc8b2e2d0bee4bdf30ab550cee9425a937136018405d5ff245d7ad8c077f4018cddfffab03b49e78750b570a49f50eafc38f9a12d526bcc88b46059a4c234ad28fdc13291b2e6cc106f6b4f5aaab4a50201a6842fb2bb6ded57dd6ee06b5567a8dcec04917816a71c1be608e44bc836ebe3958ce016c3f9857777952765a778f18874585ff4b64e6cd430e319939db0887f30c11ff5528158b08e1792ea4cca196046a792fddd925973b6012e7c3441355007fdabc21890579fc706e18737901ff960b62c22d05b65ccaba1d3d969ead8a4af0cb4bf12d6815562c66d6f3e13f2c54fb4b6ed0eb74c3e5a099abf3f3833b79d176563c9530bb040f2cc04db2c351e6f998d0e69b4396c79639d498a5b2dd351e306d8dc62280b9547fb6615e3cd399f5be9f2f5b9f7dacaa9699a7068a0361a48466a4c4cb17476da2f5f47ea44a089e4849c94e3d0d3597d7afce5193179f4ebbbb45296fb3e1e059b747c7340866b8e310673e1d5fb4ba63b2911115dbfdc595574b2fe99dd5e26680acdceb8e799a95c836ab0d95ad4b2b908c03427d96985045c49a4cab93d0f609765b4210d4aac2933e935c8d6fdefbff8a8f753c03b457ea60173cf748bafc448e1b4ebc7fd64d839dd7e7d5143dd05c1b32ee9e004b6c6aa99d00dab977667a1bbfb1ea856257b7c49ebf00824f1aaaabdf5c31433ff30f503f9635521c3bb9f506bac5431512b0520d378e0aaf4d90fd8022f72d806b13fb283189e59191a3e6c091c75543cd6cc87466b42842c45c1c1e8d0e71e93536a3fdb4d1b8b998dba6df603ce243cf117eeb6817d587d830e262b6721cd541856c8a0347fd4edc940436c308b33634fb4e99ac15d2d5f6931fd3c1c26026f0389838850355c373e04e41188ef2f9f49cbb6951ebca41ed52f8cccb902750158c937424795facc0867281b3268eea29f3f3addad0ebbc8840512141a9eeead73452003ab6759f4d68225221076ec90ec1668c69650907f7fd8ee3af136ebf9e2b6681b7dc42191c1b33dc6e669eaff2a3ed0897a3808ae34541d35f771594ed5b8ee6fb618a21cd6c3ea4006d6783b9f9a58fe76802bc45df94f7f5b16767e193a3a9af43cd6f0968d75e8a554bc605cb00399ff6365158bfead1b489b280ebcd5ed20869684e1de3128354aea070461f9c7c2c9634ce70001e97bce1f355eaf9948ac0330701751cbe76efb18859098b1b79ed39d974a016a58dde34f0e0c39ddf12b8ecbf8d7b40d7697e1a5424b94d7f062f46e184889e7d4be6b0fcf064bceb37c45909a679d3826a0cb8936ac8b26a0e45bfb0a4d22689f3ba237fdc72e41bfa32b6346ee399f6e9bc1350b6a9ab827f80fd3cb6f2004a13f6e02d567ced5c13344306bbdc43686c24447436d390603ebdac40a0a44c8f375e1f30a5d02be287f97b02fddc2aaf64b879c398ed31eac6f900ba8ab2528816cc480fb4799602d3fdd8caad6684898ecd63211cbee13733b51ce5fa9c21b97bcbf4ab59b7497cc855e666d904deab169136a81c1b34a455218a8a74388eaa106eb05050d23cd599c0b1b91e4e39464527a120f8fe91a612f693794c90321131a6bd42e4f0c08955e7f4d9a2db9112b83faa8317cd39fac2cb94910b282f74cb23dce4143925841abad3ca5f1dfc098e2165c3b5abd46d07339e8b1737cd4f7ab84d3250058e04982db947a6231d2ba7698b342020aac7fae284ddbffd43d9e816a87a3de6dcd0aff6ce0db0546392b5fa8b0e9542b6e5fd3c944ef5eb794f6aaa5a3589b13d059de1d2c71b6ac6cf0c0c5d72449d795f81883f62dd32c97bd8ee704a7d4367a014b589bed95bab6110b91a8cf39d23635d994c7c8780437ffbd4de259f678358f3e0e2738adeb753e3396dafd4ae5a3b16f2f30894027dff081cbe640300bf93240ec925b0bf86a6efac326311762adb8167f316cc358293a39821bfe952bbd81b4b6c2dbb51619cd0d6106261c7323a41ca0dd5667c1d9c7f535caab2da27f06787de384f4ecfba96b6fdf15f4ab0e08eac7fa3f6cc713b323c7361bac2e96280bec301cea58518c880e4db1cb61e9ab1488abf04ca7c0920c8aa3bd7984ce1587e6660f2b0dfa42bb0c5fb48eb78037d22bf0aece3dbd3f15c8e073605e04e427f4de09dea961ea93b2a98966c2607436d0a554619bc09bd9de262669ced06e1a2b0cc061ee782dd2e0f851c74df6467246127020c73703a1ea980fef963cbb9048867fd464892f49cec9a1f5ff783117af870030c73c4c37f5d99daae862c3cfa322734c74e760c8ee0c65b4ea7fa5e74934166754317c63ea0746c6d434b585eebf15dc4697ed53f178dbdc65a672853f4a6ac12e7745b94e53429f3bfae444d989a450304f4a46ebc9c491fe7c812dd6c941342b3196dc54fdcc9385e2939da9fd842a90cdd0fbd9348eece2503f9592ab468a8f864f6d41ef735e0380ac00e84e11d9ffc7ccbb16b35a83b6cf030a042873c97dea4a22394a1ea657ccff9d20b2515e133c75741df6091256d2c206b8510ac14ede483a066513e26213128eb84d4a4ca4d9442134063bdfeb22e64e774ed8f77b9be1d70e9bf37454037eeb53ad91c6bc1df58342348ce0ded737d76df5a3976edf231b2df75e38dd26e397f2634bd9acec8cad7dfdb84fe4ba971430111f13619fcc9344e55fcd7619dcfb4b427a1da24e10cab86da1785560eb19d8fee95ea9766f3e71c0b87c4b20ecc1f8e572973cb560d5d3920b951670218f17694b82b30506aa73890abcc8b7300384bf6b258932d1f9205c1494e44d981b7922db02a1742397cd3d8f66379bca28a990a2f9e387fb25e16daebe96fed5a79e729851c9eec0ddb79f4b673b6a9f4ad2239a17ffb39897185b4c266d39778f7bfd4d4ca694d5c2c3b4fc2dad44465aea4297525e633446c6a57e5f781983ee1021776ae690926950c4d6095ab7620b78ebc894d4f8a1339f109a79956ea64caa05acfddfd52c5b2af1488ecdcb0b9982297219c97846e9c14f7c6b2d561059da05febffc313935ab09b6e3d3e6fa69bfd06cb36ca4add2df7e66cd8d5bcb0a6f1801d39b5eae9b1bb218558193518f763a38c698a702df231f8ead8bc9d6ac55cb495488b18386c6ae39b58433ab9114de31ff5d1f4b7a727aa9979e19c75de1cd68f2e01e3e4f3f3fcc104e5361fb654c0c2c0aae4c202f308f370da17e580750c075e1c2cbcaf86101a7eeb99380aca3a15c0465b9375b20b912bf46c4ce9dc691f34cb057d28f458be7b3b25956b8b0669d234d2497ed1122ec3cb84aca600a4111ddd0d13073647b901ffa5becb4a8e354435a900668c127176ca3d40301cfbef411a268e7218f7cf23e50af1e0e4e3a2b2c323d3a4312265cae7a124d426a09dfc6099eb50a25099703c7da69b261dea18cbb6455e2a6cb76d283ddaab5328afa244588b52ad98df7ae3200e1558b00b1cc95fe3fd5ea8b94ac8b1f98ddc17581c780394bd45db415e705914c22efecce660f107bdb2ddbe618168781ddd0142890026c3ce6f55278c0c5911d3e6f9a371e5332f3c5d8c707217a9529d742266b51f8cf069f3471b78feb66cd8cd56ad1e78a873e44ebacae533e0ebbdd7e118d785a67286133ca6023264953a19ad6a215bb961b7b1350058e43a35e6b22619893a16e45c8e0575ecc3cdc1aff031900e37c9b8fca8b1265fe15bddfdeaca365ace8cf540189f30de1ac62cf4688007a52a0ca3199eb76b6180ec718053d6cf00b116c20b9203de1ad8cec04d0b8dffd63b28aa32f945bf6703b0140272cf50939a40f93d342d2cf143c3c1d38d573d0599cf963fafafbe1672d7587ab6cd9b7ee641f038dd12cb9b93f94cf7541290d1ddb0258159ec7105697facfea65202212d3f4c6549731712c6186ddd32888562aae5a3aabc151fdb64ca73b84b9180b1a753e9da5ae2eec31adc1440d814ac76b75d0510f7251a633234d0801f812dfb00b73bf1608c6471e0a127edb5fd6cc403d0c30cccb13f2a7918a6428428e11f40c90b3bd7121d717a5032e5791c714fa966e258c99c8c529489ff5606aa729cbd7f865836680a8edcd0ff887766e65ebaf81f215009b466ca1295afd3626468d7bddff5af49e8840da54e7901691308b91e6619afbac60f621595c6c7ac3ec7ddb00343c1e4824653b9c6aab38b30c052236b0a39910517957c391bc801fbbd8505b9294fc0c9682c53537112b056537dbf7bf2e6d752d349a679f0a021585863183dc88d5f02faed84cfeeda1fcbbe2899e2cb38098b5d815d408bb03d3b8b5a6052841f0eac59b9914e783ad42ca8577caed35c3eb485be09b41c43d08fe53acc92b763a1fed1f8a453de2556860c3b521adf769252364068ed6b730789fa7a0a66fdc475a61e1a93c0b8046e4b6bd11aa54726faa50ad02f00936eea76063a81c2a22e2350dea6d6d595fa30916d7f1e80ab7fe82c21336cbc289e3c5e08a6c3f2e0d7426ab58e2b6b953040a60bd8376710b639f5408dcbcdd1ecdb3501a3564ff3beee3a5d7ba0a6758bca2dc81231e0233217306e6283071a93875903b49955ecead296480b233d18fd9e90dc1c06dc621c1e1e37c8f6d7bea717f5a48cebeec09a7cf974ad3eebdf259f9731ffcfc732855afe4217b9190d7473185ec11bcb2e56a42cf4d57932b7a5fbe4fe0900e4e1c0afd7ddd3886e4564d801d9bc023ac63181ee9f913a0c6e013c317474340e8fce98d6e10837a197e636f782fed760c1d21bcbc473f8a18e12243a15aa9bc69124080c97095f74544a121e55fcf38c4de25e97d7f9ac047f3927910d770dcf00d0df614e5d3aa0537dc4b695525805eb702025228c0cadd5f7bec55e0aa4b6b64d4ab14c6e41ed9771f07b6fa135764ab2585988bcee7ff00f6d4451ff7f4ea4578244f5a848d496cd4ee1dc9d14d4b6109be34551b7d781d92058c43b8f700ce53611df569fcc1f615479b6b31dac4a62899897dbd3d066095a32aefaea928bbd9ba5e367406dd8359b9ed0c1a8c15ace934c229b0e8f0281671b316184261549211124506650e851c03036b1ea8c858c428de10ae205115a1cee0a593d4e37ef14eef1582caf7a8a96c52291772ba28a51b5df6ed897527aa45ee514a6641fd3afeb29a390247d9ff9a3b79599ec9b38301b50ca505f8e5bc9db5a69397e36a663db6524bfe555e9ee726bffce6352a8877ee90a17ed44da4f4028892ddb5b9ac9073635a79c7a04a62ba8d3a196654e07ee37fecd2d94a4bcc10c81923b420d8bb30aa0cab28f384d2e4433214219d123c72474c1e8cf8203d9ae303a22a5d0c7c8a29cccd9e357e8711dce9d01628d59a5f1019a24c518c02865ae754996d5877c66ee5b9b8128314485706ce39a8a59f62198088ff674c9db5304feadefddc6a53ff5753855e1743124bae4215dc1df5786896e80330cd8205ba3921a1f7800b16049dd546ba937b7b1b06e0d92f4e496c2e5cfe16eb2de57032cdaa0c92840d04e98c5c58a05821d4d29b6370000bc76c7bc9a303d4aa336b6798b0dd11480d6916f8c164502c38a598bec0a4560a6b7ed4dd5fe37343951320dced3e2af9c44665ab358d9dd4466d9abc90e06b32119e3ef818a82536be931c2c1bee502b4ec8d0293c78c5e78707d370b2495f52c60149a5de65c05897e1db3aa52fae888a47bea337539644803957c5ecc7969473270fe7ca7022678b75e6447e7753b296166e8c0c0288aa5dcbae9718ef1003f5b850bc0e09af26ace3b98d6c94e5e6c3b31724f87091d8f9ff2d1892afdcf6f28f44b0a4fb1cb96e8f9671c840c20a00eabf249c1b2e4719f03d3ff9216616e617eee4eeea27dad466666b181fbd87a26a0b9acfb943b803a80ca30125506721cabfe288e8defa16688228a8e977273afbeb419d400ce206614c5052b257976b522809d31aad04771a44ef1235c3eb4022135ba7393fb944ee74f767f899b392605a93a7b2c1d6ed32ab85699afa22194e6c840b680acd09170a72357f7716cd9ea73dfe565a6146de9384834c24d60a176df7ff0e7b1fd2a2d7272a7bbb47936f108cf377e0c157eb8ae1a27278d613ae701dca901e1a567bbf152845744d0c5df4e370013e3dff3c91aa8d91088d25a3adff19d341e0423d33117bacd8ac2d3b7c5ec8576c8e6008227ca1bc9c645bfb190970d69b54b11993041dfefeaaba69ef6f988e71f4512502626b07201d364c84d56c90fc3f619a9b24b00f2d19eef175fb6c7c9db3703019e000c10c5ea0be93c3699fc5b94a283ba89e13f2b5a8afb2a3af5853d5070ffe843a1e9caabd8f2e3509da9316711ce0d398dcc19c3ad271ad5cc3475b5c11107f739ef604550391d957d662fe4a50e34726a73fbe47120a1e247b545e8def59e39976046985750e79abf9b4c5477cd508286e1011c309539850ba6c9520bc109b265b6302a0b170a0bc35f4f59ac0244cd82370abafd888d4ec14f56e502d53ef24c03f30793c010daaada864dc5aa204bd4a30b7b243ff1152533a945bc4836f89cf813e10fef31c07b5b7d0dacd43ccbea61880c8bc35c5f0b4f5e59630a8f1aeb822febd9320285119d72f15ffbaeb11a4324331e2ce0a9347af1e9101209f680e00fabaa0b4645a4e04ceab5e373e54acaff45d57717d929c69cc0c14fa55abbbe0312b563e829e464aaf3d6635ca1cd3b2d2de4a39e79efe3f55b847fd947c36a13447afd162213f1edc32e61caed08ba90a20b5e6da074b74a2621a0eb29e6541db16ab48534b772cad16738898bdfd3e842b890a6369c79b399f730a6507b4087d1c5eaffa76078fa59623b9aa813db321c290032deab6718561743f2eeb1853ed0315344a00ab4a423c8cecd8d146b1535ed25c0a9ac2d15cc31142e7ed4cb4151a6dee7a89c36cdc3dda901a771b5d23654f2fb767d2819d72d20c37795e493fbef4f9add9c6aaaf9103a6c179633a0c10d7b176b265ad039a53e0e4cc37057a2aec74f6061e2b3ec963f18aa9b0c74327c9c80a1afbf5cc133c2e890ade8ec574fe1001752d77b49e83ae1982e88f0516961b742e0d5044a4aa62db5eee43b47da06be9839efbb397d0bdd8a174e4ddd364e5a42d54b15dab354199c7058f06817686f30a907385fbb0ae55d72e44564ae994bf3d9782d1483d2180633772d4bc2d742488b5eaaa7fba0027c3460ad5b487be964988395d633cc33a7f3f94eeefb22db89413618f0502b875abe51a563b8950aefb3f57c4bd270ef316d762b7d7ab329e93a19a5dfd506ec63d200ae5a63d6e02d985611481c64ba2613238deddfe28f1eb0b2956934395b06c5a61c1bdfeb857736a3fefab01756d581a4cd30b136f763f6cdf2569456f4e04439f20fe90c1485031132a9552fcad82a3899445923a5edee0307867e96ec2e7541d3b5897b0de141b01703a312e0c2a543d9e50df7434fde4857117dd54a436845d57a7ead81f89e54ed113903277db3bdc2a233deda93ad255f118748b2ff4c9b8e190aeec224a0b0ec9c8e3aca01beca1f3435584fcb9dc421c808410f17601c3c4622cc40e481dcbedd3a18f464794159791bfd98168fcf5e7c9a2fe2a88cd955f853d0a690e4b53095c1b83fe1f72d918431b218f9f94f900bc624bf65f6e2a5180f95bc259802aabbf352c83a2a2cf586b3d4cd2a5282cbc2c96aa5f402954d7db7224c611a442429c39d33b0b6c4f57f077afb388b46d666d8a9290cddf9df890856b65c71ef967e03d316ba7301edeb98276a745b202e45e1eecc6ca12e68804626431a4de55328eae00dc317887a8d28a234beb74a7cd19650fd06da3ae4d006c0e850f09eec6d2d5549e46f0180a21e6ce0c8d997e327787723caf2e3e346b23a9d309f0f16e370ff47e43580429d0888ba247ea44a034f1a7a9588982170130c0c03edc250f928f669734fb7c1e90bebab943662ee26c2344357632e7aacd0cfa5d47c512edbdfb70cdd173aac1e70427c81f74970889e79110b91d80c3d6440f49bae8b98afa20a27ca8fefa46baa837ff42a94f952f15342798e8ff3f9fc773899dc29a00336144d71bf7854ba10142ee4060303af38e77a3e5d3b0832ee792228e2c707b03edb572382678c336979426834a5d1b55298f91296e9cdec3e6cefecd6c0f43d9308b54ab9c5719fc0d9062eca721844d4f6eb6fea7e959d720a06d48100c4620a3274615178b1b4a4d7b53d713f0139b51a02cb46c1488b587051cbcd70cad1674047382e9234828ff8b460d5e15e194498abe6e51143f6516eb11859e6c8e8e8dbee3c976ec28e408d81c9a5d390a75e5a5e2b06fbfee77d4d380ece5015ff9e0d4b9154d3160f627fe2bd847fd1298ec42eefb6d029e91cd7f2060f08270a56b6c04bcac807ea68e3537b2c4d0f1d4ae41d0370089554c840b586e59cadc9594dfe893119d0acaf1bfc1f65b83392ccdf8f1b847644c04b4d6ad7fd5d4ce17989dac28253b6e2f3232883f2d8ccc30581a68a5c21c1b10bb1c93a8936a55fbea790fb8aa7a1b8a5f31c1e39e040d2c5b457b67c3bf7e4870f4677f4a19c58fdd3a6c82da9929b4ad5484d34d8219db0c9a4cbf5a606232c40a137fb50e0c2c85488b1430c5b39f72674c12276e356a270cdfbec9fa705fa874653a611ed8e245c7ccf69f9d1454faa1c3dd1d6a94397de4c79d2f0902f3a5262a16274edffcc87b631b3948cd4cc2947542cae2104d86ac5f896115c782a00ee4a89177da304ea6ee50ba0aad21c80c5c34f787ca23e1003fba884d2625b3a4bee767a0f10b2747ca10dc81777d797312079718ec227476d6550449152b3daa840d252f6f5b10e82f25bc9c17ed61e1bce605eb46ce8758abe9f0dd3911b66b212f1390d0506d2c11857bab27525b5272a5a4b95a0357ae5f0d2c4a8350b2e8042d740519fbc09de395c010ee6b4e22755e694ad5df71b09b033b765aa3b22d527eecec48cfb47e39097770a09141e36e45d12736344e32ad630361134448d3b126e990337d485f2279f0fca461c0fad128f530fc15f8b923ce006407785fdfe2a06d5f4194e016d6f3c57cd5ac661ec10a9a6a8f7ed9f69272d136376b182fdf60abc24f497116f4d572a1b636f9eb7e026ef184484e35a07eab254173a83fbe147312c6106a646d9ece9d448e440045e1def6f90b74466721029b409240a849e98ae9646342e3ad809641e74ff6c92eab02023255043d1f0e0e67168acb766272c1506bc14e2164b4ca7101ca09d33b6c3361ce6c2592526bd50990ee93235853096f573040e6daa11fe543f02558e453fee17af8c669890778e7b2c887b3ca9af3f419347050bdd07088063703ba12c100239ed2e9d56c1ee7d00a832a0b5713e5c0f2f45fd227757aafdd15938fde3bc5b417880b7e49c89eeb35a46a68d94468f7249077eb55d1b9a39db78d86de774aed3e3e7b574e61363daffb5bbfcc7dbb1f049b3aa9e1949dd566bf9d31c9ebfecf8b1c2fd5a66253f62d554c874cddf04a4e879f30f0428b6b9990b36d68f1314dbf3d1070c1ea71745330e60fbeb19ce7f9583de72b7cbb76d79b00991072505162a4c4eb6d70444ca030b88416de653057f9f1c6e1df800e13ef3d456c6ce9eaf825faaad51d7031f2a06f51d23f475e89a6621ed9c2d6a9c38998ac10d1fe344e90a106e41843d1176883a62d35dd119102fc7428eb9baccfe4a786dc0364c5920501a97e176d7316969f876f6739c4cbfab26e1251cf021cb1dc48bfaebc7c2a1661e27221c05315d1f41220f8c2835dd4bcc4b78567bea10c8ba4090021bc650db5232ac295337e7d40d43896e5d733f5fd8d95117c707a8d5c662681f4f3bb9bfc143d06a2d248108fef9506536d4cd3980881ca12035c8604f2f32161027ce85c4f7507f0873e2e7ae53bef9467828504d4e3675b22909502c79bc87394d48cb7bb209d60dfa89234ebd8eb3772631f80f01c85790db234ef58808313f398ae307c6f045a3f1ebab74bc9d09339e7770b569e744937bc2763cc4d6636d3bc682573ef2b996d96fd699dc7cda1c7c6ee590c6366666636cca774c5156e6813420e5816906a7a41701fa0dca1419b42d543b2695d649ff95f67ba61807f370200635939b47dd3c23f4ce54b1e5c2e155e9496418e240f31c7b2462efbb7579e897432e4a1664e357374a246216ab4426f97827616306dff2c7153692b3a8f433e40dd47ac317836e98ab48158b0daf241273c5b1998eff9c2728ba6575a8de0d4e5506ed77fa35c0cb61e4f899c3888eb247b615ef28ad104820a97474f8d5b2c430c2560f68b9e27b8411fe0fb85496d3c5b508c7828d3c3a536412607372ee4ff630671c31047b250640e72ed825d012aacabc7950998774a54156f78dafe42781fb9a8ba666fb8c4ae8a4f6de0e43508321dbb0e0a243669528246c8cfe34f41c9e1f11295c46ed444e1825b8a076b0ef8376b6d321ae0bae95d83ee51f95336304fe008fd93f82b58b36cbd5f822dff0c78d63cf1eb2d40e9d4aa7f365aa688f6072bb28f2643fa25816012b3d328a1f24e638e4c016f43e31856744d88586d60ab2c6072f897fdc64f9f3bb1850bf400f4a378dc6bc46833dc661b1e586a0a869c826b54d5dfb1d7c2c9f2a21bdc44792ae0dbfd8ac8095f69b919d4f58060a2e88f988ab14871c0cd63f0efd42403d717cdac51f26443a69e1933386744ec296d79562831dddbcfa541b5726ce8eb1b64cf3ad9b35cce735e90ee36865fd75c97e4abe6aec350fd9e043835ab4b026857d392d8b09cb41d5a4cc9a35346f52abd1d989a9bb0d62829e6cc4ae43ad77095de51a73fdb46afae55203c86bc182cf1e1f22981e93851ee4e88e1b9a7ca2ca8d1faf6a9576bf6547b6e63d40f188b1c52c48ac51d7c215ba3fc77c5070790c41a409a2541979493c9320b851a44767df89a11912e661a85acc95f226283ae522b6ae63592fb868b6b74a622d80e80e96d4d9663eb78ed2a40b2d824a4acd9540db9a81c3831b0a06aaef679994d5f2e10c4d71264b7d41e3d9c67035789034f91c479d5410df09ac25deab0238987124a67770e26ce4a54e42352334fb10c9ccf3a7d0b00c34f3a2e75fcf1e00e52678fc3210c6228fb8e510a0318075a6c0082fa8b8ce72ed2a54fd8904734f199c77ec18d217a34d1a225c2e8c682a60599f0aa0af2649974306992da04e251559a4e7382f1fd3d8a4ac6370e46c20abaf6099d2d84016e9f2e7ad6b5cff332fbf7abeed81798cfefdf44f2cc700e6f62ccd5a2006922ff8461dd0d892630f3709aae03f3b36daa95e53b4b196ceb21ad33f81ef200c2e57b83664e44279bc9f4fdfeb5e6fc92f408298ebfc144551ef4304019ba7b583111f9c30ec66082de8bc081b90ac28d273857f285e61aa311ee13b676c4961a28d3f102b41be004d188ebbd6ff37feafa90bec272ceb2e1ec33a0099770c744416d9e5341c1ccfc1a588b6a8ed54fa65e78466ec6995df8db07a0d1e44a801adf1a85fb14b19d30befa0cd0bda14357ce81536c29445604f3775831e43504717de0ae52972832c8820d74611b1a2bf0ea6483dcad463f2d0adb56d6a45b6c4281e32c715e9709edbfa7089629dc2dcf70b4949632ef32dd77f1245a60c9c48b161fad4c855ede1c7ac0604324da651c362a776bde28fabcdbd30c5108855420f776d40b10c9d5dae25c1ba3889f8cdcd54dac626df8064bdf56e765519d82faf2bd9124f804a58b2fb0fec80bda3bc0ec798848dae2621a1339a1bc2802a628f5259cf00ac225f6ab086b6786278532562970502f380d49b3954da170581d96b3bd1f79d34afe3886eb49d9ff2287f1b5f94691089d46fa9587799e8718ee1789515ea918f42f8b11bbed6a10451ebda1d12be87cc40b3582971c9596df7827b1a32fd45f3d479967ddc34d3370f8e12b0c43f5e6d49a87b2596c20a6f47a4612bee31ac43da2f96ec073ac1da3bc56b731fd774d3f822008ed3969df670b48d7223108c3451d193ff1dfc9de0cb000642a8f188b5550118ea17c95b21f68507e705d6d125a078929fbccef65f63d16e3516e1cbc4e80aa894dd00c2afd388199ab9de1d1e7352d889c8b6d3a637453d0ed844ee3a01ba52fa16a147783217a2029cbe4680d14fa0b5ed0d8058073c18ae9851a603d9fd02b8912ccee92526e75f0c42d89309de25c7a3dcf6c3801de6550e908c58537a9e41864310661c61e94672375efcee09389dcdc5f66717c86c744ee8d50940f54c85f2fc9a8ee2824d22b362c507ca4e9b7dbaeb0c80864c58a0d3358310b769153eb580d47913127db0287d75c1e84dda7f1e8adb3c457e010231e23be631a2b806724ca20ed9581920fd857b32ecaeb0a1006774e1816b983bbb29cd0351c6d1373aa10e8923ae9fc94ed108a52fabc4b0c5f1544c59c2e0d4447e50e5db7d8d07024d204d597e0e7ff9a4fc7a9e5b64c171939c21005819fd344ed80529addbcd97083213b8783a0d35328a51954c085bd1fb7416e21e4ec2218a2423634bdcd969cf5a593beb36ce4cb7b0354c6c42d0e4a870332fb0a4b6da29f5fc4bb5ff2a6c355ba6825addfeb60bc0c287e97e6c951cb19be1371a419e5bac0b9bfc3f28690afc62aefd0e9f18b04dfad528291efee35fb8b4c66fb9bf954b9118f2ce1e1276385855ae0a2267e9f8e665b2c6cee23a5d7b4b9a7d82409c1b1cd2fb1af8f0ca03442e0761c8f4e3ea25e86a46174ee1ebbe84613534f50e4e1ad2b01645d9122082cf84d589198c717c228fff447c95be7b5e558a85e52a2e94c55eea20ead7fb64e565d32b50b7c110bf4b8505bc2f1e07d76b363472db05391359fb902cb97dc265c6cd52727704e6134297bcd346f58d4218dda55f9da213796d347867a569c5105a40ec6f7ccf046aee230a361082874e115264bc25a270cfde7a198052a3c24a6e8e4f40cdfa66e9cc0abc9410fe492b4cf60af66437d5897896d8e5592e86cfc651ba058f8c87d90d4cbf6270f1e46aeeb1c4a3e77847b169b27c339a87b91d66507156f3e87a6331ad5e4e22bc89e3b6416739dff4813680a8d0fd9bf9ff9b52191dd985754f271d4cd9f21becb512408d8531304d380c80da54ab02291326d27c6defc6aa9ed1cbdc51c05cce30238fe112e2f3cc326877d6aeb472b3bea01b9909edf4fc2c16a54d9bde746590652bc643185dc07f3f15347bb2acda8dfe1cae8b9c914d4a3c8e767840c7ffbf0381df9c55ede8ab9298aa18428d5feb46410f388b846ab63da3c946309471f5b0a982686a5988502d6e8f1dc74c08e7ff1bd320bb46e1780776109c2208eb1417dffb95a487597740497726180bbda7dbb831979ea8a51b44d70800022a8b4223fc942327e7c5754739388a7f76d4c397805dd72887c8738756ad7ee74939376a8d49d7cacf858bf0a08a5aa64ca0caf348114b309066c67a6868255465d31554efb2bc42748dd9e69484573a032d9a0c880a90e3e12ad2dcef8ad970d8b04e3eb8bd48e347a658a892c73dca1c9748488ad029173fb7d58b753ba7dc33005f4e8d3e5f3e9e442da81be733bebc9733b95d55ece240f71e891c79a64bb23a8647f0778a845858ff85ea61aa4a926cd5bbbb9d924e76017843c0e35186f0aeb8ae12098c4caf06b2a5331d83006b47d39f6bb84f5add049e7b46c744ead670ffd58a2ccf22a618671783c387bb810662f1957d4e079e2de68f1c421a6ee779019008a2e39814b144a6578d579e121819799201ae4679499b01213c686037a6c28c35d5a1b686f1a623c89191a19358ec71bef62f6a04c4fb52b9e1399aeca00d993a5677e3d460200cc2372ef0dfb911543e44165453f1f23f6b787dd77772c9734a80443aee6a300da711e271c9d70960df3ba5f5817321da3d434d6c1313365f709340946ebd6b458a061b6eb73eb91459b00ffdc300bcbca89a16068d22d3e910624543c395fa9b28416518f4acb060ecf8cda51427c5f15b8a63f1c0262cee1e8a7ed95d7264b5f43170ada9ef062fa6a3f3bbe428ac9b42bab5bb8c6fdff66310611422fb262f6c5e1c9bea9a2b3a45c6b1dd8ebaab36ccca1a99d75f82fe1d1bce7c1c283ccc3db84842ccaa34245d895d7f67fb379cfd6613226ee557a368cd37974f8eed68e8be29321ec737d5b524c1e73a25f64f1589679b2ad1318d6dd2d825d27e5abf1dfb89b8587bc288d5015315f5a54e28041e73749d522a92db017d75e1475979b91da947d821b21723f3db9295671fae647e0309611ebea3620bb31d7f0aebd4655df43ac39515daa521dc14f926a59a5177e338b6f2a38a4459581af11b73f58b9cb2e7b05797343ed813bab7d56b4576d41f3bde6e27f6b9ebcbad079f650b66dda0518f4b2c86db180d81e8b5eaac61da76509846def8b79d8b64b12a4e735c16af521cec3ad27b15cf44e82c46012ead88bf4485c5b60fa94110f14b54f12c21c3ad3e7114782a589e79025562d2ef3a5d33cdaf40ced8c094d900824663e18ae84263c07840536c220a17d5c43a6e85fd2cc1462bf1bc690f48c273bb01b4505a8da50464523e594c34734edd07e31e8f93163955c7ca056a1f223d174272c59725bf2a6ca33084abbb765355a19f9839c3d6d87f7ff2acc55a79552b52211d1acc5017429875516336307e3fa8fbbe2cee7a817f2c1aae411eeef09ac0a4ef27b4ffa4cf3a58ddf9037fe984af5d78ada657a779e3eb3ee20aa910e1ab38681b03e1ec76e7613af7ef9ba47350265158fb494687f2cc55bb6a2d67e0b53a334bf585243e13af5c2452c5e0d2eb6aea38cd91c4275ac567f8ac729d47c61335cdb6bbc4317e9679436e5bba709654e49d96763063ffc58282a4fe1883e4a7046913bd508344e2e4a2bf6f6b62f6ab44c099d8948988d3c214179389f9bf2d43a42c5ac20ebba0d56865a292f1ff3c93d178df2ad6b311021af1c2d871aeaf2ea40b1768c0ff3cab3da038b08a45e1019ff77699096470c044a48d727bcb7182193401574558fe58b61b56c7ba3585a3f4400c4720206ab3b0570e881637a0ecb05885458c5cfd7929e13ca5a14951b18982e92945e1579a6ae36884547c38e0ce353195ec03e374e07f65dbde85b2e8f174a0603a579e2132496c52466d1125b30e68afe2d96b546135cfedb8adf98e8e882f2d5245939ca446df3985394ef080dc324ab9eb061d30873734f572e922d3abb2faa370f4fa27d59b1362fe09a9494d1c1f015120e0219a610c8a582b160178c142eda3d49e2f3e44eda428ffdb546b7af3b13aae2e80822c3752c041a3932aa0bf2e94492939a6cf95961328a6450beae94aa1bf0b5effb754c98cc1cf492edca4859c5f4b26fea5cabc9692c8dab6308091691426542c378737db809e28da8cc34a699b75427a76e2f2e6493c1958a35fb75665b9efa57297b107468c987c12031b34fd6b47084b59f553e9833bd42c957faa1125fd1981e644fb2e738d30dad10c473949dcbfe1d3855c3f0a32a2268b990c7443ce0c3817ffe1d0df8c74428ef154f0f904af5799954bcf60d85137fccf076e31124610f80cfc1131cf42225945f469c878573509c0702920cbd0e1ee56ea69a7d490580e0aee677ef78eb05020282e97c7b2548856e825c67f0c35fb6185c23da3777acc48636401519f28c93c93b875e8c09ca28d092315189624c1deebe190746df0fe88082551b308c6303a3417ed682c9f1716b94adc72b80787f0697a4062e6f891b0701a7a1ea5e5bd66c9baeac354de33ac65e0d995e98d91fc98d79c350e29659dd93c7c1ffaa83c0dd5e70312da0137d228abc1f074fdc606caea84071a0d1cb0869d705137135746e68c05260471ee501b31bdb490e6cb7d6a170a87274cf30003d1262642c2372fde55b048486d2dcacaecf8cb280fcb530a3074bfba8b8e823ba41600428cf91605641879aa3d1622b5be95b98751166a27011f6debb0803dda2305dc5c3120986da95839ed014d2fbbbc92466991ab207ffea54f17231cb2fac40d9682c2e1df2f48417e11feb2679f20465b474202cba751a60afe8651da7f84d118e50b4d38f275aecdf2ef7fd89022e3968074dbd00d14e23ac3c533a82c1daeec2ad0a729c0ab65c5c0375c0234fa9d0cfe4b4a89c8e3e20cc522b18c73c56d62638b19cbc7f3a0b5d03b108fd1b912e0c5458b14f3cb6bc49cf6158a035a77cd38af323618f5c08311d77298ea4324f08266a6c561c0a0188136c4f47b16ea3603648432f45764eec0b090b0ba6fe03bdb057e1474e6cb369fa78a2ee484a13aa2bcb88452d7977b4fdca0d28829ed07f09d3177fba494240d11bf0433cbaded6ace02fd2d0e7303f0634a00ed92a6377e48b14a0483d560bb94ab55a4adaf5a34e2338483cb14440e9f8c9b172d52d59f31aee3f7b73f1f714048fe511e496c8550e06a700ade3b983a0b426d5cf4f6e29746893c8717946c88f5249005a271637ead003df1b2cd41f41b08dae54c00d2d4d8f42a3b100aed136485b260844d9927126265f7a1f05d301499df38d4a003d27a22e4ab0f382b559f66a87624ded8aa84e7e623730f26da39f20075f6231852f8f1004b1cc032395bfc362aa9c067209ff305ef02d2c6644579a9664781a903c2a45621d8ed70839ab84f3e9a952293fa5e82915dabf83f07de1ce2652e0b5506cfb20f1d0648ea33180f477c69e451a7b58856312409bea0f6e2274e65dae8420d8bdc060adceb745251edc9fa068ae23006276eb161b7098a5432fc9d81e81b0ca498b24820e5b53704462a4a655c0146540ca16009db6b9c5af9b52d23b05752d548596c60834878fe92e070fbb5daac7ada19a6564d4fcde160b013f20ab5786d29ccb5d05ec4d1a10368c2ca362b935d5b2aeb19ca10120f34403efbf78b6f425070ecfe16ddbb993dcb5519adc999da7da9a7e3dde8c2cb9dea2fe843377c538dac473e6c06f812ec5314376ce44fd69b872ce849ae27273c392a5965a03674da7580a229b73263d4b7f48bbff652cbb78b6e69cf9e0ccc71363af5a23a084c6effd28e59ed35dd98ecca00e2c3f866a7a692665d3f89899d95e8ec7657a7955f4498dc06e62a4687655cd99c119b468e804b0307ac311e44aa3b007e680098e1f1f24d4c8dd9fafb3676a45212d7986a5e2cd3310c09ec7daaccac3590c8a3677ce9c10e20801d47294dc0d74da03b6fc0bf6bc22e6cf576d1ce6d25c9cff9c2369dcbc99732c72dfbeb7fe361fbfe4b2c4a11f8fc51ff74f4e4cb51c428c0133020a005bc4e94807c27f921a0c8e82b8154fb2df29c56aa6ced8abfa6439b8d02d55d3fb5b4f381eba5f3f536573c7060849301f96ab71dd6cb24f59ee5103ecb2c426803595d3ede6979f9161a9d7c2aee61463857b7f79da891926eda4b73b87d794c9c6be9f449ff19141cf65b29d4e93b39c77cd4358dbc4cf6b4d517cc52b61382f91ab660195aa7a87a4a28926b3237ac437c7b9502c91e17bcde2a847e4d19b0a63f603da66dbd57ac7c11c74ae130db409f89e336cc4d86bfcb63bb3f062b255c54cd7d6356656dbb3c77997c32b36b126343eebcf0ebe2762ddcbfa9ed03166a55144d630970207dbacdc3d072172b9feac02046e8ee44ad24d3caccd7fe2491cf998c16061c78819e45952a040e1d1a17e56e8661cdd292a7b6ca1c27a475d1e0850512388f29063d46ac41f2347ad28ca1f4129104685b2703c07dbe18553a8225655971bf1fa2185b414fd12ab568ea40af9831639ac47532a31c62e9f2c967eeb4290c44de9ceb868fac83a15e4b8e5125163c4bcf6fb7ef57554d65dac7da1c15a03a4a981c476086c201919aadb3931f35609cafd067ca20fbf98879713a0c87fcb299d710060c274cd3da7f0a4f16611cfd6873c429e504474b25c65cee202c2779de260b7c42d202609125f4a9b6ffff35b97f2c3c21fc08ad1523dbdf64bbf65a937ae8729371c039b59a97c0ece0c438c2efecfcfaa941f96e0802a464ab1f4fa931d03ce0c07040e0c03f33da93132116f6ecc5dfb9fdf9a94272ce8802a9414324f47e6c14617fea724e5cad009c310fa03073f5e46c3d218a9c7cd5f5c94adf2d12f26023c70f70131e2c2be3e2a3b8f73a62123ff1f9871f9e7be742747d5f8825d5c29868c6a5745ba28a55d7aba30fe2caab02f4ab7638107e4cd629aca00a87abe0b5b81a86ee00b7f5d577a38b2581b1ef34ab46c47e3c62a4fef2cc02977549bb691b55619ea0d80c6ec46814a159aae992d400ad34ca3f5d719ce9b97f61a0186be9ac02700494bf4e0acb11ab2cb4d833b76060475e49600c3a30df85d221107f8c3ab0e485e02f41907a1be6cc627e90974060c54c7928dc3b5b07c040823864549c52d100acd95263c0f78405389802256be0f66d36d0a78a608d909b4236a5f59ff1382fbd2b7fd5c5bb6d1586dd9399ec46b415f6330b2bd9b83c2ee55dc045759223f394a1974dcca9bf72ce36ab44f7f0671f894c47b836c4819b6fc47916d9d20de9a727d8342682d80d22e2ec2ef56afef612ccd31eaff59cb6c451c5c2985c50e836b65d1e22e05513bcf83be4f9d9cb44fa54859d38007174068f305513f2e00d43cab5abfb108c16e39c41f6cd19d2ac91970867433db8e17be369ee72671a052ae556f8466aae55ae132d5b939b7c2848a6c884fc50cba5ff01a7e942355f825d8340bf000b202c2be17de0cf0bebac8b3f6dedd69c0640a7a8118a823210440739526302cb9c47706f50dce50934dcf4e5cff93c5e8b9043c6d9d9c18ee15e8431b4f12753f2557882fa29fb4e80d72d8db86877e4e17bb135f62fbb3fcf9539b0307ba32d1fdb14d561a464dde926e626261c9c63608303157b68143136213dbb413fb2d347e396f2f048c2be045b059c60dbb255171dce29e764bf8e961d12c4efd4d83365eeee69ca83635d7bdf185ca86af01fe972df4ee0ebf7fe2c84a98cd2d52994131ffbd34b39d8e5beb60312312743946e10dbfbd44c0aec1412fe265fd0a65743c52366c4989bdde2dba576777ce939bd132a6128cba211076a45c070b5f918942b7d5e0b9cfec2695eb6f8ef4cb36f98ffc4faef6a661a64787d9a9f2299d0f4003d375a29d527259a539292337adf7e389415ba9f73135e8416c589ce0477dd9bc5bfa92d3808fb5bcef1284ee3082c53efd4b3bfd2feeb99817637b8857f14a80dab7840ed30ab4584c087887806940d1e3d8e86201e9e97112cc9c7c110ccfda590bd825742733f437b9888f068a70fc23efbdb950930ab81f9992c341c47b73638827e0ee4cece8e3a1ad1a63414e0e854143102ea69dfd75ca1741496ef2bc9408541e1ad6f6e58b93217a3ca8541dbf4585e282b4b277e7154b9b805c43b33bee0468a650914f324feffca65063107d770b5f3e87fc931550b2918af665cc91d180b2f51910b969b2ac50562c16996c9fa0a160c22a19ad734759747afe6cce98b9ce9807b07601fd8fb05c51f4c55f46f2fc31bff122e712e51f4d5e25cf58b52d07e6a9e51cf1c1c28803d4a330bbc883a08d3840fbedbad55a1f0e4a89c25f42cdc8cf3a4a862eda5c0cdea2ba741e00c31f218c94231c64d475ff24038b85a09dbab0692342cb30685a5618a3eb5fa322e613b896aa3b90c9a57ac0ed2adcf4ac64a71132223222e5904a8cb391f1e1f297da3287cc276a054a4fa0cb2e24a1166f2be2ead1d03a55b84e49dd283c387f91c0528166dacc5231263173c48c6ddadc01f0e8aaa79dd00a2ac9c05ba432c2057ca72b9d51fda11038fbaf546d558ef17465bd32fa4dc1484e63006ae48b113c60c6a5f0a440af934349506a7b57e6c002493214713ef762b9b0c4dbe15f63115aaef3af893abb55591063996f41fce58167b74a303b0d5df7780d12d558ddd0ea7696b8bcb509b78e1bd8fa9302a5ba3943fa28d9ed46234e8c621174829e22c835e3fd34515e5e55d2b65a4075235543d58028c4c74a64f28491cb38ee45617fee85984c42776829f537c0be85b234974f6a3e8e7d613c0015b817eabf2ba2fdb93262bcd16f443c0ede0078550b362e849f31c4d7a3fe6420b6182177634c1dd57f3aa998a01651bfe33b0b81fc7a18c48515870c1a1ae88b4158b41b5244f89dd9b5159237a8123be905a36e8b40e5a1705ce35fb74df9f8919e1132b2fcef2458f05171082a0327818affad2fa20d0bce082b0305728a008c03a5990a1ba9b6bcea0792889c1d62c2890f4042330bc71a81c19be930b9faae1356287928f2351867c811ec40c82fcfe44ab8e5f94901edab3889cdeea6c9aeecfd5506af9e849d2f79cc765952fd6cbe79d9588ae3bb33b1ad6df653e0e9086d6a3dcb84fb6f2dc9a8637996684518f43e2672995b6424c0936a95b3e3dde2669353de7a2d140923018a452efc8e2f4c1fb4b6bfbea0150c701788c07600cc1442f73586dda14054a97bc2fa5b881d9014d8aa4971fa487da281e617020c0b68d4e2c48bb381965b63c5e0a695d5c58d0671cc496e430c787104e6fba2fe6f29d34f3b1fde236579f52ff44ce57f7149d8bdb7ed3f7870428ada5055c921dbb3b466adb907ec6a1b6a990aab0d7ac04e6e6ce6df49eabdaf7ca43b7b1913ca94e8dd1b9401205aa90c4b36822b391329320c9539478c1e071d77e8d011071c3becd8a10e1c39e668393038d7adef08be63c71d39748443c71d3be8808372e0d6a1fc3bccf22a388987f307072ede4a5f8e4df8e2cf5ee527baad4a855f9b59b98f7a82d4cf1756ae2955f16756096d056c75e1f012c1cb93e7d6e271044171d4e2a96d09c04545d23084a3152c267480532930ccaeac78766da09b0aa9159733ed4c092e7bc4e6c2054a1d9f2aca981eee39afa134596875af74774bb8d4ce720b594e5a73d6ac07eeca4a08adcd9a61915b49bb949519663cf0165b85b26ad61963ccd6d451d69d31cb8cbbb1325a2bb366bae456d22e656586190fbcc556a1ac9a75c618b33575947567cc32e36eac8cd6caac992eb95525a83c1a7048b33a1bcc50f975c53ea2710484f4fac26b5b69d5943d2a3f105ecc467fb9e913c3669e39254a7be09664257a951e954720ca3c00de277ae9b976411645e567df59ff5acd045eda356aacd8969bedb64b6c9a756dc5b4ee968bb56cd1ac552bd6fa719451d959f12542f0dae8d7a73b4ae59b87b22701e66a075f90242c2ec653ae791a9d224235fa72ca738273ee7261339b12c2afd6d63092bc9806aee44e00356d86b3772f6569b2e05219310f0872115a38928b10d4dae0e17ef053494dc4c5886c94901ec8213a50ba90a0b39afb1aca722edb1c801b9daa513fce47ab708f90c2aed1380f51b362a19c408cef9e9874b45376036ec1a2f11288c07ebde8948b57a4d2de8c5c019e18db290e1cd28e50123eb0fc2364b962b8745071da645ccc002b69a070c48e080d49601f1cefeff5fac933fcef1073cbb7b33b9a77ed0a83d1eaa8b6316622d4bde0cb1f03153adb0b1f4cf6cfc55d3e9c019112e55b38ac7e79ad21a95f930bcb651c0bbb24528c474aeb49eb00b2ec22fa981d676968a07b14c55cb54728d31e6d130142b838df9ffe0773354ea5816e40c96f5bddb6d0eacab6daa465ec3e911d378ef8d33a746ba2439badbf72dc0dfd020e980ef23496df2a0345b899921f73fe8cd7604be6751d89ece9a2f97bc57929c985633c7c3203f1b5fa81a056f8b952d0cfa80fb73c93a50e626335b61c70c40fc813ac5c1b1b8e68552e05e2e974b36c32add18447b2d2e177b1d14f05f3ed31042e8eb8dd186027b4ac3e2e4edf0d7bb2b2b84f45a5b51d9d1b0f0511bdecb33a88fca40ccf9bd601d2772319555e43858ae9794786a41c85f1ace26db60e4a73da45eca6d70ec50188855603818ee005100c3cef92308b8db5b70f11eb1e0f0ca0dc758992a783c8119affe8b87871040649c5902be2e2e4c860ff47b3f0e1e63bd38d9c40720139bcde1ded593f2bff48333edd8895abc437d7825be87b1976c0d15a813d4f22055293035db3e895038c1c31e143361404714eb59e27aa7813d3d2085f61e18c174c2260689f317ab3d912e5f0dda6e9bbd8985d3401a4059e4e5ba0f496c36008773ef3e4d3e2d298947882372b6b5cba7ee2a2709ee1b1a3672fb4a5a1bb124d4240fc64afbaaca3f0365acc1f8b03ffb723ddf4431bf3e7430b97092c2f7dc31876c101f114c3abc90f4d2f6252ce98149ecc5ed8acd140defa71dd636ca1455be13cb5e9cababc4def79878e231e33ff1d7fa33cdf18befab12f3191839a49dc568e4f3883ebf7b90d9b0b1d63a8b95c5b5b20afb6fa3b0cec9e160773cad9030412343bfb00b5ef33206a03e5d03b661e7ed88613431b2040eed0aefc126997e7336ee124fcdc86cd858e31d45caeadd590575bfd5d0b764fcb8839e56c0c02099a9dcdc16e83f6c40b35061946a6290149643b4578388b4ecfcba63701696bd947ea762ee6861bde1a765ad8f5272463887f756cb8b3e67dd97a5715df29a0e0c5d339a223f3d9d26af0b3b6bdfc5cf5be095eba5a84dd27928140ca026cfdb1065040138038fcc890b0cfb159dff8d76385cef2e880b7091d06da2810da3b9d68e30f4be18b8deb236b5d16918c458422d83c68bd878e9410a2fe3a4a76ca4709e7c62febdd8608748864c5e6a8c87f49e25193061881e7701527d99d4083633f1749b4a6d86baa84ce8bb79a48577b58b8f866b283c566230a3840b26a7150ace4181b8320e06c07bfc1b181cc8439aa33ab0cb9a890238d60a96bab9e0a1d157a152a09f17e4ea331a96ed1e031046450025809b16a26ec3c780a4eb9485aee49549e7a9d2bc505cd06de08b3dd0ee7d9a474bbead9791b69b68b64d0a23dde3b17d9a16bacf56ba96d857b561310c53ac43dae331958f2b2476ba0e0428ce6f3417c19b8258a512175b58fe9c75f79909bbd4ecbf0033479461f63dd19fe943dc395a0d6e5ca99c2b98f5ce3ce4f9f3a60da3ac0696bc84f04634c159501c5515f4eb2b7ec8b0e3091a739a0b8259673959de6cced29d11c561575e34588dba84c7a76665f90decdbc1f9d8d841705ff4a688e0d231ad4ecd6a1e8466744b1b4240a1c2f1fc4cb86e19a0ee2943d448a0a297ea7b27a9e96da16edb608246a4d5d3c1fc8a7a5349aa46163423eb0e15fa8554454d60846a3cf767a340fcd2f0b35b456c44282894150461685fea1cef0ea0f316fdadb6373b7e882e835b7025a236544b84e753d6a8c1abf1a60940dbf970be16f8cf7b5a67139d8adec08bf3dc1d4afdcce654b21a3ddc8fc4a9741cf9c29322507b176991554ef53a71ba7c6068f1acad74da87a6a47856174631ed7e5a20bb122055ba38eaf43fd69856bbe98d2fba8cb8cf45e649a08c3f767101cc014c46aceb07561c4c04a67a4017995aba4c3790325af2b52cddb4fd990aed8464981ccbe9c4483ffc9f121c579047ae82c9282ab67f83394ca0b2b013c5d010af4dc355770ce61750acc7240ae50e5c6eed0e64552951712ddec19e28f9907ee30612477136af386f61118d7dfb570de7c4c681f1a17cbcbe442e5640ae7627934cce10ecae6a60ee50db66f3adb8ae077af16e826774a726fff1d310353034603bbd91abffc38f9013491ad3faddd27ebb42e0a815ab25104e6c8c69b1841e3436badaf84d45b4a84c494f20daea8dca3b05a62389b43522d3ea7e8c72edbeceeee454bf596369d4f280845d13751c939e77c216eb5eb2cdcbae49c732e06d55b3a241a8fc8f7504cfeeb160114632a525e623a322358a5206f51e99218d7dbbfd8b1ddb54dab893df7fe5ddbb45a4b654282836539f671ec9680792cbb1a42d13ccf6ac2076868beef8e919022393c2e4f366b46f1e60d14026e7c26b97d77f7a757bda5c121d108e2e9f84074adebb60994b4ee09aead75dbaf623173aa4ac22c2feb68df5f4d0a526fa9101152fe208959b2b4c64d388e3c5e3d40215b8df242415b3846476f06a7d06050573713ac8cdad0ca2006f3ffbf4b918434501865e6bddb3e0b93c403bb9510dd21c32b47a7a9882964f4a5e4a4fa78d7366def7ffd9b2ddf61fcd4bebfceffff1fa0cd9cdb2521c396bd01f5c13313beaa6214a198f8ca5131817ccfeeee6e347c71eebcb603b1a123693161a59c734671aab7f409fd0f28d1dc1bfc0f29c3e4c7bc20cbf250396041e15ddbb4bd8bf07b767777a42c249c7b4fe7eebe33a1213a24472867e3c50b628e0b0a510dbe6727e672391c77777777f7202e45a2f1c4b907714076e7f9406f79efd96b3877770722aab7d4a839001db5f6271c9c3bace52ac6d58f7a25963688745f6cd88d301d399ad1e5ee633f50398ee4cca880445afa1191437d91c15ddbb4bd995eb6e9459a59bbd62517311185a42a2c9f2a1f8f9755c60739b2e433f4734b5c9beb2ae97a9a58aca666347d718506a31f2490e5a91f8447166fd9658097845112381fedd004dd4d582da26b83dd12d7e6ba0e5cd15a6b2049f5962a974de7f30408d42b70cf2f7067edc0427304deb54ddbfb573282918f530b41bc1c434b30a6b2dcfcfeffffcc1d1edc7fd631710861884168bdce05efdaa6edbdc232a237e3e07b76b5c5dddddddd3d884b959ac4e02f75bab2345592daad2e40b28ebc5ddbb49deeffbc5c89b95c4e664d9734904b66d48b5fce90231f4515d8e8124b2fbb62964400843a939503ab36b304cd8a22b49195861d58402c79027ee1220691e97892e1f3b58b8699392504b24d5b62ef481ccdf07bee6469ebdaa22accc2ad8fdd1a6e11b78c5bc72de456d24ddc8133eeee24c434ce4ee3c01a27d6383425232e30d6955b3ac4c6c7552583a9b5d33484daf9704319c673e7fdb825aecd759943ddcb4fadb5f6edd45b0ac734451e10bea09c73ce334cf5964a5165759dcc889dd0ec5ae5114f1844e697ecc17a1159660c3073d0d3c00a9c94183c3830ef4e366ab1b5c23291c31eafdfb3bbbb3ff5732765815dd05299624083d05411244c4d5490cce869986293dfffffff6f2cc5b890915b41d972c29b8246997fe55aa429168b3cc5a0a25091a88854646a560928eb55aa9135dbd1b0f1003272411f71244e73ec4312791ec1c4258466bc51878ff7eceeee4c285e9c7bf03dbbbbbbd18c13e7ce33519fef7a4bdb15b7c4b5b9ee9531c32c1c81abec98e80549015271e532637be0947307823005757757712084ef7d72090af311c3062a2689e297fdff3fb9ded20c9c7573ce43e0213bdffb493e7c21592e930b38764ca86b6b63e085e6d18326b2851d764b5c9beb12d9620f98bec1f596b659a78265310192e20aa9eae7ad1a3e65bc8899c96514a2ac788ebef0aa6924516e4c315b286dc9744f392ec664f411926819ffabbef5c4c9b80e69261ed30a0cd06ddf3f5725d55baa5c660e554dd7b9e00c9390fd40babbf3dc6cb5536f291ceb132b1aad81447cc35313fefff7b9998318d0dcfef37c81102dc6863a44468071d9d440aeb04a61ec040f32c566e728c4696cd8d5530ca291330386870ab6e20945e5e55f07f724393c1e8ec35ff332a5ab088bd34d915a109d56bf3361c38eac6b6bc788ebbfecdf2d716d25399bb43d77f7a41a1a9c3b2cab81758ddc32153b7ef944249d6822a1313d323306486fa6f4815f1519083da22dd39d791585553c4392a8de5263e6903cd60280ea322cd3911bea04800a0bf2518304588f1d3771115186020d4ec0e44a70d960690153ae40116080686c5ac134d9fc40be2c19309bd1110ad205f463e1844b8b1b0818f05a19723c423da990fd789249326aad354b53bda5ce27d4034b34e701f8aeed0666d2bdf5e9a6640a366af6fbffefad37c6a06cd8cd1ab6407ae4e55cf9cdb8d0ca11c118cd84181ab934c1a69c463f6c58cb2b513d97ee3f7548f4dd5f49885c386106754b9cedf45a1ea9c771a8b523f366b311ddc731eb04a3f9822175aa01cf02459c197ebb756678d7366d6fd7efd95b9d5b92ea2d55b61d5a96bb16c248840550aa0b860dd205fe2970fe42585860435081e637b10e25730f28c011fc6cd7a312523e7777f7b8c697c117ad91c5c1f596b62f3976b76b9bb61d8ed16affff4f51aab774d9747e90f2f4921b37d3188b6ac75a66c2ac20502df4cceccc3499c68c18728c6e896b735d1d31b3fcffbf2a12a45e51ad183b6ac4dc58a135c3bc514fa6920afc98a4bcb4442075df33d5e399a6ac66b4d65af7bcde13f49ea1f710bdc7e83d47ef417a4f32c984738f73ebeefe434abda554595d1d7e88ed3a54c15fc10a6cddf663fdcb56eb0bf4c05ddbb4bd31ac00b0ccf994002061c7468526a08f538c98b8c5c56d75feff0fa2516f699127731014e4debc0ea9e248584700f4065207e44a41e8e05ddbb4bde1155c7777e5abded2e0507fa0246a1d858348486444c72b16d1b2820aa8a753cc8a698d94a8962bbbb6697bc7231d4c0c77aa663a1440129dd24e13834ec693526f29555617089e18887717ab42761d08817db4708a95814b24b0495334e9da7819feb9b2a45c87a477fb1e4e617f20dd3cd98e3094268aac64ec70295dd860b1462c60a5bb3b8f8010402eaa601848979ca1e342e28576f4d3f56c555fee9085d46dfea924274bc6ffff1ed3d38e16ce3de21bbbdefbff07aecc2fa432e92b6c967da0146559d98b09d22763cf2f6719e6d3028d4c0c7725aa9bb66b9b5693edfd2b091203014530203a3e2b462ec213575f31173cd08d207aabb0686c5878666830069deeeeb323142b091316954284104aa68965450015cdf32034eeee4094989669c8e9be6bdf1febc50a6ea74eb3ac36dca25f1a172e71906a5e1362553f532b869e47096a6473584efcff2fd930e2fe338fe5a9649885d906a7d74bc3221ca524c1403183a973f4a29725fbffb96877241ca872ea0f1ff9c99261bd8481129f2d0f832e25a70b9c17e371a5015de6b480493acbd199cbe55ed4232e352221750c03ba25aecd75571ebc382ebe50311383d34c8704616c0af0a0e9d803babb2fed1071eebed4a38cdbf7d7f9ff7fb9ded256657bff40adb536a2516f6991274808841191bb3bef3dbbbb7b8ee77a4b5bf6cbab60a092fb3c1c5945474bae1b37b61e05ebdc1ded162c2a63d3966dd7a089caa45c6f01adbb7b902cf596767d0822b683e30c7e84e4eb5d5b12a77b5cdfa3891584172873f88efc766dd3f6ce3f150709a2a88c651485081d9c98c705ef02f72fc40264bde00b3c7ce01da11a3122d6236b66246548887ae755ed150b295750e7b925aecd7575bcff7f9f32c33107e36628e377241bf13462e7844c0ac2c5b8c2ed8861924437a42899c2ffff41f70e46a83becb2cb215459c3eeb8c6cc96505fce395329d55bba6c3a9fd00da8a239126954acec11ab2073a28627a6451126299e8f4ccc8acc8e64d218f62ca2a43453d48f180e50345b9ed25b2533072be5762e38c32939e79c6984d45b4a84c494a2cada40d38562b66b9bb6b78f75e69fce9945a2e085988ddde9ce5b89ab556ec5d7dbb54ddb7b85317410b582cc9325684515c49a31a26cd95d31c3da646d7a01bbb65d5e6979b1c97b4871746df091c8c26e896b737d85b58e987a4b77704c53f413238fbb5e79afd65ab740546fa9f1884c9eb4a074770756d07ece39db20a9b794294595d505828dd8575044f8ffaf9273ce5f39f596bec121d178f4f08564c36e9e96d4647c75199e81f550656042dac84e988830861eeba64caf67be20d9a35733f6a3455cabd81234bbb6697b8f2d6742d7bfde0ebe829bc54ce8738189e853b3719622f524d51d0a115b2a502d18797e85d602ebad0fa452503174f0f8111183215b412648cc1fb690d1e77f001b2e7d252f7cceaba98feeeebe96242aa6ded21ddc012cceee6e8d3578f0d414ba2619a880089d1c3b7ec2c246a4d0a79b212c95f79edddd1deb897307aaaf6b6389818ac26f23e9aea991109adc340d64793430674eef6c802e6bccffbf12972a091571ff4a9c056a9bb36fd7366d6f1a361e324052d21328b97b81ba7e5804edc080250cd103244aa80495a36a840a6631035385d09d64ace4ae6351d82e8851c70fa8488015b7c4b5b9ee53f0c52d716d6ed4f94e09470c39edfc8f58002f5b6eba444cc6bbb6697b67e07b76777727a025cebdc689c84aa70ed912aa3ac4a54ba1e7cf4ce5bde02a0b6c05a99899a13fc2c8604442a849e83e29022c5feecacbab97e37d6c6624651b881cddf3d1901808804a1e42b2b0cc6617785cbf614909b7bef7ecad9635b5866bd820789221634a450c142c1b303f6a52b462ffff19dec761e2d803b61d8ca2be357d6a0d7b5390f2a8342d9e46c5009d00331a041c41c3401cca12b9a6031480070d8890bc7888d02c1286c6c180480c0086024100180c0602018140202c8a817096ca62b805e646dbf3bd2e64f64fe4f004eb23ff0e699e3247d24b954b5088a40ecaa685d8258c2a3eb4ecfe165df5168aaf83b3641af522ff11f7da40c0a2cca02c46d2efcdcc6a1175a1daa9d70e2a750166303407f0b645b3fc83a82b1e4899184fb508d9357cefb368f6496662150a6f7e785018b411225e0e15f5890e2d8d344d1149d7f438da024305fadde9c440f6f31737f3568755bb2fe44eb98682b9ed86ba66f98ab4db8a862750ed262b4417862278d552ef5a1ee7874ac9ff53c3143d4951a8845e4981874b338fdb6644167f70da9070c9695afbc2886b3fb9fd8c545bb6e2da3c96ac914c53d3127a343d6fafc05c2dd69c4ce918a410957a367bd3c9241d7c1218cba1ccb4637b47115544336634360960ff0568b26be93a44a1a2d9f59b24d4d66695674084fdbd875a244b6e018a06c2095e2dd4ab8dc170c6fe37ba6bdbdbc1e8b152458909ab6d0d8a7ecbca1261aef5c8f04b1c3068a2b35b45a74db7b089e3dd78d2b48c6259262ccc5d1dad46da316394643eedd95a6410cd1e4fcd54fca74e1f6da5b8bb3250970d8d5cf4a4a195d4643556a2188b7bfd5559311193eef6871797c02bc2de8bc8834292b0731e924411129b9ca537a6ceae2e270dec2c56a22b96e463f562dd90156539a401cfda7ebb33e130c2b32ef4653f2413e0940f5b53b2c237b31677e5fd1a5ba367da9a8f52f3ba211cd0a86acd14aa4534574928ada454c5c91726a7a4cca5c9e68a194a25bdd2e1ff64f5ce58c21b4eaffe332f7dd0630929ead5abf96f88b98f4712bb4d25861070fa396f6c3f228aa769d1bef21e9e5f3ddee813d442ae61f6e8103da1331e1fa9e78d1736369bc1bb1251fb2176cbdf28b32e55ade7e471266c81a4dd06282c44d1aff58c1627dfb68302d90a51f44d311893b313a8307cd6fb1475788acc3457c7b4fd399f0880683d5c650b11cd9d249aff68132935cc4ed966f320996adad48ae4546194780947df9a4e180080b6741118468028346c2867ff5c8cb30a14e029c09e75d282ea573c268928293a1f81872649162790292cfc5167a458b89fc6f0fd6686b2a058e8390076939b60b212624324df61daca31cfee89ab31cb4570f2e01b2296c28f8a721385c653b853610477395dfa84c8bd4a47210579b988cb39a3a2c755a18cc1bd73f346275a053857a265e82b441021e8be4a6224d4d03359ca241f3d7c14887a47646ca2c411139ff02fd8d3318ad02125e321b6237dee5811d423c8a9a8510786e2f6c731a10a01da3d9a5796898a7ca49222908098242196da2adf276c85713d91c840af479be33dd44a5eb0e00c6ea0f66ace750ee1db88d1ed6f050d177a8d4d6c6088a44ce2b2a490949a94b4b2a527de01514f2f3a3301a46b8f2609de770961ca6bc649fd8aa25cdac6883f60893904bfeddb91fe918bdfef655f3c8e517069c457ef5e66a650f89c7757ddf4bd252eb8bdd1c0613bdade3b21caf239f0030c93d7aa99a04305b4a17589908f2b2fac28b7981b3ae9e762258d3f881e1aec599b58884cf5cc63bdb190a6736247b98d5cb9fcd2610614e180a3298dde507fbebd8deb27dc403ec12cd41cf3fd70695f9192f71dfbf654235c6e90353490315fd6c832bde9802d0853ba985356e9db8af0566a27858c95138b2db3035d7c7a3a75dba3b647d4c995ce53d2c5b4d91dc8ada94cac2660ae2d76e22ba90317ed99b94c64fd6e32287beb800bfca12f1d2a2218ad7d1db5ca5d3b15a28269a39f7cad6b19a4b66f7e239af7f89607a8a796e0afd971daf7767d82898e207218b3bc828092d7b227d770933e0ce683636435391513bab68dad1389cd709cfd3c40e78d02454f3c51050c97d335cb8a9278364abbbcaba81e076ad8261218b934eccc8c43dff240fab4aabaa8d5c6efdba7c461f7be65bb39cdccadab8549a5b52571d0cb81fd05257f52bc54670ca95a3f890155712e5ed711a3a30a6ddb7ff721dc7d60c33917ccde9916c22a0b4b04d0af2cf4d33c4e6e10b9e3dce44cc35e553ab56df458700e79afb0220d95858da2acac25d9fec14943b4a5a1fff0bfb26a4dd03fd1d0b18b36fe593955a56e6c0b044fb29e7ae1b62415fe0edb3738f03ddadf16285f195300a2f2ee76deb793c71105df2539ba939f5340d31ede2c94a4d025862142884f01f8b598b61adddd5408ab29283531086f384921340b5dd1eb61b37b68394340723ded2dae6516f96f14f7a417ab1907ef8f3d8d002807e59119c18490349de164614cf2a4d018c482df8a54fadff007d1eb27bd59e53fb0f0af55089995afded158869ab33264e0d9ec7bf7a2abfb5b2d0686615895ea0b03f339048da25177b97eb715f87d1b76e542097067eb609b821735cd01863e577b6046e6f6ab46eeb5e81bd192f6d9586dbe510289c53f0e68887b0360b42f22b057fc969c9d4526900a413ef5d1d03f08bfb46d36078b080c9db4de95ca92f557d53820708327b4cadc8b2892f67e0abd2f158e8c14f38877a6bc6b9c4f3276af85a56859bc1a55a67fd2bec14f8b438d341d5082006a530ba240c0df3f9c5422ddddca3933d61c22138dde9184ceb36a9cbf6fb9b5fef5e3ad28aea8c716ac000560b91113db931cc3057892624067762b3a6a9b0941a5a9c4c7ef8dc2f56ac24df912b4161ccd44b5ed0e896a88f89219c826ce8f87bde318ea29d098ca286bce340d0a3ea2b03a4dc786543814d0d7e91bbd61729a3651746d1fa26c0c61c4f34605d342b5c3ac9f66ac3c78bad3d11a88b7ddb2cd19c17b8dce701d600e729e31978ed283e17bd13975471a3cc41380f61b06e6398572c969e0a97c8f0e0e1ffc1e75de3e8ad321dc86edf9aa0ae222941c5ad99472e7b497fce170223b142e1d9d710f84883ec8f038cf50403ac8bfa5be213df902c8c309038fd2b8b108378a2f35bfbd9111e646f33569271d6b03fb15ccd2e646434a6bd7d12267fb3cff5d27d2e98334a71d985bcbabddebd1423a96cd10e7887b26343f81de4cabc0c072afa62e8c7cb05c6aeed6bd1769bf89179a93f1a6cc33976e5b49095f86a79dc57f7cd358d583071d03968b122cb8d09a05fc47adec2af778011f7c542ec21fc2ac4299c316b9b112b064e15331e6cac305901a167eefdd1defcaf6816b685ba73f8b3cbecee1f82bdd2b89654323073de92f0279361ddc40b851462f2bef68bf7c6c788e0b05565c089e13c681f12679ab7ef9ba9ff896d673ef47529ac26095eec0fe4123407ab6faa661484aebaa842b7201eb6dfb528c06d760a637fbae62f1d3bc14d90c54b814df5806b6921652d24ab8e6143eada637b0cd72fa85511925f5d25b5019bc983960a35c72aef5d1235a162eea205db3afa039ad0d2e604bf6e5f0aa5b5d8b602d54635bd41d408a472636a64855314e8282d9b4bbf573350423b6d42693728633f2df5fdea4fc962764d5f80192fe48a89bfd148273cb239add4821e82f9643abd542ec7632e379c8cea7bebd05e38fb9e072b7da4c52bf436734d31fba1ec750e77db919b597124bdfa5214b2c8ecdf37ee72fc8b79da76f87306ec947a989a549238b1e6af86b9577b39aa4d7f14d3acf0d74b922082611b0eba19c2f31d3580b2505c2c15283ef06b9132264df40f716c2c541561bac5bf141f24d724920545cceede2df3f42b39d5aa37946d4b5ed98f05e1fb0e30bee5a504e93f4498f0e111d342b496ad2f4e1f4ff849c982949182dbad8a5fa4c9801369e0f9fc5680685ac05030ad4c4241faf9eb0a0e17b0b25f92004ccf3f3f5ac6bc5d61ab9e36c80a5b3397a18d538253934ee2c38bc13353534c1106bfafb9dd6d6cb96c74f050444df427c6c0ae8fd0b2952172f5f981c4cd6d23cbd4789c704e0d6f09bc12e080065c7516174ac9d4a35b5035767f959234c16fa345d631204cd16fc04323b557bc95c8ccc5953e3abab2b23c449f7f2660da91a9d322a49ce4fb65751590f6623eef1398865d64680c9156e7910a949b7f4048c7010441292de7129ce5036b030541da3d701c3fce1c711ef2e44b0e8046bca4094dea630ed38264db66adaafdbbaa81a47cc44616ce544e1419ac089e82c1be936dd76769eece46f515713c1f02649320b810a4062230def881095b3f4937fe3b0e8c6dbe3ca7818253db8ed10c6d2eedaeeb1e1ab8f3be1ff8f77209a1a6e5c21860d572e8f0300173fc6c2a2347e456ba045efc66b1abf12b2d76760aba0ec363e19c1a04e44733a3ea7bc8ad605d8e9725d0d49fc0c25d494e0344c50b616f398b342edb8a1894229c75ecd67eb20a2d7687cae4c330d13435ee91c21c74aa81054cfd8170ac3306e3fb097327717c6a0cbdc5de3d921fd7ef7a56c2e839d01a4b883fe558446cf79df45115ae624eb16c1960813dd326f3cbf8594aa969d497a53f2030e1964eae09908068ffb047e7ffa76a9d4564c424e87b4d7e412f2dad17699342f204022683428ec9295c3ca27e0ddb0c2f6e11701e9cd20969fd2f6c41a10902704f0ac8769bd1a50d1832c23d4aa888bf3c5d6bcda86761f92709fcb0c60c26f20e1ab9a0955c7a446dc5a28e9e1e371b81126b7c9588b349d0642927c3c733ce462d4b41fa86eddb5f655e5ae883ce7799b4156466c33b15f4e0f4cdd142eae599fabe121b1cd09c5fbf759726074cb015a22dc7dd33f7e1dd1ee44b9b9999cf6b7afe8b95e1331cbc12822a14a6b76411b37f65ffbff06f45ad9a19d4f7b3dc8c2ab945aed68f4d6a80bdddb98040e8fabf9ea2e33939ed1f67f68f7711d1ba6b4090d8e1ad131584f88aa1b87b0d1794ae4e9eeffae272335d065c65885e150a41a0983350131a91f648dd8ed9750e39c62b72e532def6ea17e0bffd88aaa70451cede72200c471d3a5002c5e0f6fa24180d1471824492dbdde688bfa41fb4029e138da56dfeb755a3dc949d459cbbc5a31c0aaebfade577cb36c49acf1af887f6679dee08e0e36bfa2d64938bd418cebe8c1067b011ea30f7dbd88d884d65e340493895c03c835bc0ba48e1c402839721a7e20a414691b12ef4ca1ba04fa31f71ea6a357967a29919bc7e7fe5edb61ba0eb613ccec12d7779d4cf61a6380d3dec324e84529b72deeb6bf2ae9b31323744956ab86e8d7bc0a41493c245c0ca0ad88cfea98bf6a97582645ff908de9a238ceb9c1415b68eadeb2f8ab10624f72c6559612ba7fc1323dfeb15bea4a857a0f56ec1353ced24deb1172eefe871e56575a0bc12c3d50b90bca175f125b9a3da0bf442cd46a68e06a86a547ffe5c17cfa11b977d968e4a02fbd41d07ff9e4d54d866965af5736f497b826c02f6d9d3e1e9cbd13fab1286ad5c4965502d99cf32622d97a200ac8f446cd0a477a938c0c13c9703a4dd57eecbcbc742fa1944608a93744ce7051996ee05a4239cfda769080fa6744df4ff541f1d08e784b07876778caeb692bb9e788673d9b17bf49fc5dac918d70377f1c6c587b8ba233cc12320a303b55b31d2b34a115e96a5eafc5da000152a60c3294c4817b3077df6cf4f3b60db39983e05f13e7c66e084105d287db7ba5328224be105f81cf482361c6d34632366b58484e8d25ec257da93ff08871708b6dd9ea121730964a1b8ca3e88d1063efb192853e840942130a0669a653da7d2df75522648aa574bd3a29257594a111c53b7421b60b088916063356ccf5d84fd6432eebe295c3552803800da55593b9f378fc8ffe76e2371bd072d3193c91b24adf9ec7b751630309762c578eec13a747e353128e64daa4a423933ef1e90a451973330c923cdfee5d7712d0ac9426173e69ed3e21c4b2cbc82d5fda3292b2d9a5799380030ab75cc9f823bcabdfd466e66a4f8ef611c1c7583d93470ed5c1d64217769222423cf278a34bffe5e1c513f0fcd84146f85880f415c520cab65967690184994116c5216fc10793b5c5c415896083570e317e7d7ddeb3719e333f36ca82805985976c9e4b50f355f9f194840ac79abd232f7d7d32f9a6efbedbc36b661bb782ecabbfd9ce877b745b38e77ce3e681d601763490bacf0a99d8c177aee097ed7eec233aea98077c7ac2b979e385d474805fab5aa88bcd8a964ecd4957841b07361c04408e03909bdb6cf698070725ba56209131b194cb54404694c68f6c36a071ecc559dc54e5b87c7c05264aa022c965107a3ae4cb2f0c72bd56eb113534f7590d4dcfb928264ebfa28f548becd638e42fdd4cd72429abde6d3bf20c95220a5c6a481da5ea48ed54da96b1e8577c332d98bc5a6b6d73267ca80bce40cd021d4447ae98300aa46b93c2d31a2d2246d8c45411993f7cf9215b7624817d8779a3c2db8328d10db2204bbc787500fdbc5ebc9bcd71e28038a7da15324eedd453fb6a54e921c908e3694405019695788ecca1f3b46b20bf381b859732ddd868edd1a7237ade96a05a5cf12e093438f1ef7f3b33b5cc7436835a6db765cbb14643b682b0ff9dcd4e4ef8dbf1af4097881b93880b6456dad962ab116944774b732b3f1c45a0520ab8514a0e5700cf36510c31584b061f1836b699c521ffdce1e99c0e89b5dcfea76c532f34f0f92d811440128a9bdfe03e2f4d24683d7fe8f183977ea8f2d944bf544358e0918041d55223dc07b43685381e118c6a3ba1a4fa713d1c2a4a3a97839c994f20c3013ebdddb59b65bb0011f6051f586c24eaf547bac67197cbfb47e939d5e9b7dcde3c5d4ea20b1f7c060741c76b732e4bda7ff60d96ed4821e2b971b86bba909b6939b71f8608eb662e62914c0d4b538c147a086beee2d3dafe979001300568cf821027573870356c330c6e036badeb53df3d357b97f1c7f9d7d370119e77913b12bcd79dd62c0785216292327e3a6880af7b6d7807929cd3342eba9283427020456e980d1d643f21d73522a0cb0ad4482931688409d813baeeb6ee34f654c2cf8cbe81eab8dfbae134ec60deb1b3ead5e5eecfc8cf8c804c49a988d5bffa77054d3b6fbe58bd941948de3e200e1fc316a70edbb85925d469c5e2897465d7c3e5c010646c36e09f1593e3f51735adc6bee6f9fa557169481a8695dbadd30c6f2dee99e6513c54376ede961d573c1f3cb16db9bb8185c3b908e91bb54be0225aa6d51efe24857de5891a7709bc9eee680c756461af9753bbfb475daf342e6ebcc6fb748536c58fd5b7dae3d2d8abdae2af7f8a116bdad5cb00d4a8215a349bd917ff1d450cae6d3b975f40630270d820fb983a30d602c66dad4f0c1cad0ec3e58a3315bfe59bba5018e46b956bbba8c77281aa25360bc431f499e549e8f928ba59527ac5cdcf39c07d3042e86e39d6a6ae8ef0f70a08d1fde3f7ec1bf6f66b9dad0cf8ae90428b8444168a90c0580156220318e5bf2e8b5e70e2bc6ece9cb04fa0bbfae26f607b804aa5736168509658c609c86a0cce70ae5daa08b14feab81e48c9bb3c59c1b0f62ddf690d91db364ea3286cf219e29f0f005579897d1bd9a8a1c97a41b800825c44be6c736fe3bd7047d0a2bf3124d921b7254bfb9d5993a440c0954d4c6ec53301b96e1735344e1c425a189ef90c7293dca0312772189f5c57ca07e950dd954a766d5779a191922e19966174075facb6308c5726174b9510075770f7915f3b06f658ce2a5c7b60d86ebd88574fc55cc1c02b4ac3b4320748eeea6132dca3dc6f5ac179fe71d6bec523be767cd55a9f31f6289966041c98313d957871d67fd236e24cb549ee258f7fe3171f1b09ce4b8f4d696fea15fcd087c75248bc919c76e974643797a90056c9b6398a340bacebab26a790fac76ceec942170938318fd9cc51d85817315db8580f5e34d1a00c1af6d05a5cf14e76f8e84477425ec910a3dac1e6c098c1f147c127e95b3f4bad2e01dec8c35931dce2c7bee53598b6bde7973071a0a6955d9cb9972566a80cec26f0e8ed81e7951a4efbb575ad6610a864e58422045f40d1f252564ec548b5546695e831bfa1fde8b6c5f919eeb6c8ac9e52753d0a6c678609984a35f7b19cad9d965d343a2b71f34dc84040834cc3d4e2fcce21788c995a6662684ed2a4be0e04f9acac09651a0754727b7dbd694d2a53536b13af58c89bc8f73397012d16edaf370a3bdcf4a5328e898a1626611c9f10af07b53c1deda04033e1b81101daadf8ff6df92ee534e5c8c3bbaa20b44253fabea55b28d22d2391346911816d0d8cc248a2140fbfcd8f2d0fe273d0e462acfff6244408d2c5b54e63afe35b07bf388cf2d7daa7fdc18785549b578d659486d0fb1a18d1809526af40485a1a19d2139346285d54edaf80860de4d4ccaf17529a48a69c4e4122edc0994dcfb1a90fc88ee511332d5337d4508933a67a95d0dd4a23250ba18c0c1235783de853b9011daf25daaafb7eb80b34e1f5a26cc4d3512b453fa11825a5bebc5a20d0910fe038ad381bcfdd14243566610fb1b5a3352cfa6b5be72c1704e45c9c956ee598be33456ae20458f125abc95b84b80240f89842a3138b5ccc9822bf3179799844872390fb597743cd1aa9d2b44d4759fd48e2d162ed7fb41c0bc62122f892364cd6b72927fc6061d4cf26958e1ce168a1919b6d894173dc8d85412268b0d379eba4528ce085e30955786f12d57962fe451c2d523d51cb9baca878322bb7e297b4bd87e43b7f6801cc12245a7bb8d7cfd9ac8ccc44795035eed38ad0ed080afb4c3c5485a52ee4f5e620ba11240addda1868e97c3bdcd8a83282330f2597b97030d425ff6092396afb002591b82fd07892c47c68bf3f62e4081783b7a4d67486693a735b34f2eee3b1746714ed4125aceacc82d19c9b343f54535b23619509c2cd0420c1cb025183376bac82afa30eea09ab0c9ed51a644b4ae5e5a863a63f7654adb046b295240b0e88616e53cf40aa602bb033d908a5444e5a8b78adc19930591c01946db369fc3f6850c874119197ed6d45624fb2a56890498be906d1ce405ab12ff4ac82ce1e23002c7a366128a2f758c59bb3d6bd306e7f4e8efbbd3d244b555c0a5192564390d69a9711fafb7b379ee72889f1f74cf58806bdfde655bc93d6b07831bf75cb4c71033198f2e8058f188a297a486a32835104968cf14f3d755d9bdecec0f94035c8679618a245f22d81a0461ad0e024054dbe3016f1fcf2a879ac891fd5106608ffbdcf3d11f45ccee091dda2cb13f2aa44f20f1ab83914b7b0aa2ba97b88d928a4b8cc0290f25af77e643422aae968415e4bce91a313487745c8d3c0505cef3be10c1f036a336c9eecdb3d4a6cc3d0e51cc8d0cd274f0e7242fe5f3139b383ff3f9515d9c97c000128f1522679070c725ee9fc00736a3c7441915bbe9c3c6ea7bc38e42b1d2d6f17717519c1b81961ffe69773e700549e494b90ff1e010340a9d813f2eb6df8887acda12fb90000e0e505db744670a3208f4c0e7e920f7ce35834657f4ab8c0184cab5bf9f0232a88ac0051e5798174988806eeea46858b5ed68cae539ea970199c98b3207671c4c270452761cfdc2c7119139629d19215776be4531642195195a6abfe50b50abe36bd26ac4e9b72536890598f4ccea5b5bb026c21ba3eef3f14875f10b37d783f7120bfae425dce01f2323a04515a6c9ee957f91dea4811d11b7f188ff5a272d89bc507bc2eee213e03917cd2c8c8fc27cf6ac5fc6c89dd8b629ece1f6a754feb15d595bf71bd6efc3947040427ae02fdada3d6579900ad5d668c16804ea9309ec56a54bd70502cd7a8a787833923604a3565d7b5fe2ff4e17e53cae04ec8f7a783b4fff7744826a42f38d87fc31c88239e828ea71d96cec115c0fd62a611daf325c5b310ee38c6d306358bfd6c1c6943b37aa6463083c843acf5a56c29e8ad8a2b92972d33d2ad507858986e49f9d4b578d2d02bfd5bdf320bb32fca19adcfdf3a1ceb49f3b1066b5af0165e8d449fe64a3e206270fbea7495ee99a4abc3eed2d591e4067a1a5a47655eadf13388bdf7305abf9385585130b1136a61b853b6e18118905c18629862ef04ce1f9139aeec31c2b763aacea6371067789a8f58c305fef29f4f6f8cdc789e5d7755120169e858363d8ea82ed17da2381a03ba9a4d94a8ec3bad452f278bfffb40a2879205aef144deaaebe4bcf2ca13d15911cc682f0a0cbe43c023f742dad5ea478ab83d98aeb6ec983b57c0011f22db7a8cb99f2782e7d055ec5ee8288f62d240627c95521277bfe3d2e121ceb296baed42a2fbc8819e343492a39730a110977e7d1d8054f6fad40ed6dac8c31eddda1205b087243335b323b969591237811282f7e83e6639672f9ad9fc553c37d93d946de542851b058b3020664141533e76557d75ca8fc5b0ef810ec596079e81d1460f3091bbda7a7c1efa3aed6003185ca144617f87e3a7ede9f743e6e977786f6fe53b4fea9a3619261d783f946a13c3fb9114856aa06f18b8c3be73ed7e2866370ab06f7979a58c16f7af20ed76d2d6f91b0af738cc5264d6f2c6a786aafc1c01d598bb8fa84f6a7e454d0348b8bcd41f3ae1f7b028337faf664209272fc7ec0611a8172dcc269acd9f607e26acfa24ff16d8e772dfda4283a63a73a372ef55226ad58d19144a526ecbc8419646485e042106076b482d87c9648963d2368ade1b834caa97552b417043cb900136df1c242e3f7eb56d79ebaf56bdeb6e235090f971905b7f2e182548929e025697e2edb295f3bc57b63a16f9efa707c277dccbe9ba94087596c46f533dbbd05ce3a6d605f37f1d3358776ffa50d7228d4a5237d2ed02d77a834fcfa7fc44c1102aad4e244a6cf26724aeb15dda5981cf8177623f249b8b763ba4edad621d119c4b017ada842f58708e25a503f6a3b75858eda21f429f7aa0d80f9444ec0bf5ab0cac03d0c682caa3257748598db2963fb767ee8393d7c5f631bbd4b858b236b4ce4599c576b9d8801cc9dff2af3ee5d67be05e4a5137c263b04d64f6278490f802c202f70230305157835e2d6174702ea87ecc213b267e7070ca091e77e6726d5951d6937555e6f6ff3bb8c59c9f73ce990712a59949a5071e4b9b07a42e674ae95cb0544f6722bdc59c1e8e471d4986c04cced04526e48825672ccb4430a78fffff4d2ebe953f97b541d6065a98a7aaaaaaaaed8ffaaaae1106d0e6eb05aa295befc88f891210a6745865536c5cac54244229692549abb2964c2477944a301972b960cdb411c2216c8a563645f5c99868533389a46555d814b635eae3ff3f972e83e0eaad3f9a6be0040fae9a96872786232aa3a3af1ac618bfb428cd7c717a8084bad60e4d702bca7ab2ae555b582d0d8d20451897f91ad2605eee91f9d329019cf1d8da8367b0bbbb3dd1bec88a61e179c191fa6c01ecf88211c312e300ab0cc74156db5b51d693751dfbd1fdf021d5c2939c2140d61b74621372a222a25122e1c2ebe3c6a6a6f6bbbbbb3ba010629cfea829943526f115326b5dd30865d5b2a2ac27ebfab076002a143a70eb122f898b369b6dc5995c318b5043c9169d5bd489546fac0a9bc2b2972003ab13461ea28c32ae13c8140d63580153dddd352bca7ab2aeed29b5b505c4465c3f13292ea09e8fe3865b7777d48aa42e2b63570dae271ab8da08a9c4058e4b77b7cb6229182d3696dc9278dceec32e5ab66c5ddbffbb2af84ed830fd9284c0d29a5e52841d2fe5ad47940f175dd45392f4c678ac7954ddeef64c8110774337f6ffb18e28cd44263d60298b584b9c333fb843b537e79d4bce39b6d6387d0504f3ce30012e3039f4aa0ce994450301de8ab29eac2b0f2de608012128bbaaa1a94645950c4de4d443b49112e0032a9d4bb76b8ac061bb9935c3929715653d5957fc12d6c7ffff9e77e57fa744f0007d88ab592308930ddf970d163234323864f87f14c39c7d5a5c162e276fd99aa41bcc38b6c0a2cd669b494da72041e0180faebbdb4ddf0c052676400b30785cb07462109da8ce14c12dafeeee0f3d1dc61b5a93b6ff33862494663e19ad368861eb1f72b1f2e7bc588c802220b960ed9011290a6a1933b8009821769ab090d8de7f96ccb53bac509ab9d5e56187d82c67360d4d76dddd6d18aa4c69a6fabf10d562fbff4c4294660e3308a662ce6fc953b2f7df4ca621b6a47a6b8d6cb8f16289dd97354f0e8ec063d0e45804b3a2ac27ebca7b9b73ce594594661e91496587aca5ad8396eea58fffff3860702bbf0e1b2d8b8cd40c59fa4b793897125d379272c920998f1b215217f15694f5645d77217cb6a6b6e4a5bbbbc99029cd549f32fd60e175bfacf8733ea91411e3f0ff8150261ac4feff0dc00986d588592e07dd750c09142f70090d21239a351853b06c77f7900fa5993f6088a160568f6aae45edbe6aa4436966cff7fb6004bc0ac618639c5bbabbd95a46a1f63be3ee6e2b94666ee10e325d286ce35815368565310c4ecdb1350cb41a5be3bbb229dffd4a5ab56555d81496c5ed77523d9f6d5d328258b2c26b7ef9ffe70280e9f6ec51eeb8c4136d58fdffcbb91473d3b7b19aff1fcb86d24c5d4f032cdf8f76769e865c923bd2610fb2fb6079fbf8ff0f2534b4f2b7b8d6ddad944c69a69abee4803cb37703c09b84ec171b390caf16c22ba89996a797946606cf30ee8131c637cabe59368ead71748dd36b1c5fe3fc1a0728ecf7ee09fc727158f7d41dc7b52a97aed89d7b61cf20dd7ad2cbba36f310b6a42d8ec8e7f032e7bf55f3ff2be9509ad9f3fd3c5002fe3f6f841a5b6245239c747c332335f5cffdff3d6c28cdd4f57cbf103d805db37a8b31c61877dbf296addd880132ba8e242ec618d718a234b378442695226a2c557c9382e2c17b51067892b62bca7ab2aebc921b43160c94d01325b613b2947104caf7bb3141614609163bac5e7e3ace760ad8fbea1b3b4598c7aab0292c5b03005e77378ec40b39dc4995245b7c97430a9cab1897c5fdeeee6ea916dd4a37c61d6731631fbe106be707a29e9a33bb73e6f1ed8992b1f4f1ff9f461289e4089b9e8eb6d7474b12a511bba99c730e16519a794426952182cb1aa7deeec52da705590b8104494f46ab7bf06efd3d4f91c32c901b784f8b218e9a8c68a05c0cd13a8f3b7eb83a154c62329634f4248f43ad087684305ce398f0f471146488cd022bc8f811923b2292c3e3a846850efbff6f3184d24ce1f0438be2ff322b9ab44769113c76e1fcffc16a5cdc92654a33d5d95bb25c4f36e89eeabc227470569fab730855da6cb69a99596c912872dd66deff77e8c043aaeb5f1e6753532f898a2bc8c66206f9b1e85249810848d68b209e196228fa884ecc540437f0d2d5e9e888712372bb3efeff5f97338e8cad29221a6c36ba860d163d97a5006ecc38ba526c94f08731cf3d41f410b6d8a4694811efc61e308dfc5a862472445a384ee494d0f755c345219b825d5cd50659dc11917839a71042af8e28cd4482b84afe38ae942b3760e5baf45dced852300f0613cd6870bb181508993671ec97ec7e79250930206408955717d111e70c4eb930f2faffaa224a338f1eaa9039dc345ce668055f1ebeb12a6c0acb0a91f4b4d7dad16f7a8325af407a5891347700cdaaa189d1825a6e93156528cdc4b52f4e4f0816406d8117071a8c31c638aa09001a7528aba5458f251c48bd4444aa5154342d3ad478a4fd7f18d44be97be9eec6f86d0b3f2576ba96c8ae545c8105d970c09df8cd7a5cb09afbff9584509a5994f464eca0648577aaaaaaaa8a337bdf5a95daff1f86446966324cb9862d51c46cac984e45ac57b3402522449e488f9501820792373d2db723c1125a472d406ee648ea5815368565956adb4ef0eed4d0b8015b21c319b60454b26abfbbbb7b92509af96414d16385c2b6dd3e3b2990a2ce8ab29eac6b1490b21cd54562e66c81a7d301f3824caba8c914d21b3143c0d6d4955113d412a8e753c4cb811398b2b46010f278f05801416163fe08fe3fcf645194c143bedc691221bbe15b427edd30b6d2afd8c7477d39c77004df6e47621cb16952ca51559574238a2498d24cf56f4dafa4f9012a996b915d581536856571cbaab029ecdb4c5d6663d1c7ffff1cb61c22872e6723e4520c1d442f1518bc69acdc7835e49d36ec9e2716d030a88fffff01ef8fcecc06d23d4368853c3e4470158cbb0257e002a6c88b5b8fedc724e34176cd7a39d7c7ffffa82572e5ffdbffff3bf5509ae9fb013308a7a0caff12e0e4c379f14ceec9399b90455ecbaab029acfae69cb38f10a59943b5b81e51902c083e49959a8bae2ca6254b6e68d316f5e043974b956a50ef58153685655b75c74077edbcf08562c44c52d4901f27b058b28bc2b12a6c0acbe217dd993986b86555d814961debd66505807a594f742bca7ab29a6bdb8404d4ddad43820bb025b29b2043390da51563657adf740b57c3d5fad121ca41e4f6c562654a33d5decdff5fc48d62ce3fbefdbf4c12a5994a0f64966f115343195239bcd8755dbabbdd54f9b7c45bb0375bc21155228eea85ffffff15302436214a3387c52332790f6cca9fe4869f7ae07e1cd0bcf58aff8c4ca78fffffc5b0b295ffdd4035030fd44c6f85f24d81f5758e7530b662d724fd09d6201fe3a2635a35e6fc254df00e05feae0257316163238af8308a0103ceab86fa529aa97eb744db59dbc7ff7f61cea80957336e37398ad408eaa7e12e9733054d3e2762f070a167c609d70425263c7182f39bf5b8bcb5d4f8432cd5b5efb74f27889baf1baf28ebc9bace786b075e60415c42e38e19352a88cbb3bb73a8cb8b0b7c90a674c4909161a49b8080b93881bf9b09d9ef37c36abf33eeeefe4262115fc995ac8acc07b79393d14cfd55d653dec0dadb060e54b5fdff1fb72c0df81e9596924f3227118d12274a4b48079f8527231f1c28ca48109934f460d0c1579ffbff91921ae9a9918c8d64d5485b8dd4d548628d54968998ec54555555754bdda563099408c20092540449662868464cc786d5ddff3f0a08a5994220a28a5694af92165e50f514b946388854a72ea6c80cfa04b595ba6ef75b53fb9d7177b71630a599eadbeeee96b7cfee99931cc298d8e8b101b4aa6deb1a65a4ca5bce2df43ae59c734e12a599ca10394b9baee7fbff16530a08885b1c331bb639e79c5f21946616059020a8946ddee6c40079131a68040d0371248cd31863001400070c6a94b4787808311687c5c1a0480c0484026130180c040040a140182c0a82d068aeaad17800a9362d9b755087dcf8d252e1468564365bc5a23186ea284aae53a43daa469d13895e5178dc5b2b30f6db8c5b8ee015ec4a8f461befdb5090b46549080152a5f5c6c1719314fdc262e01b2f7cb846499bac1e5a5c8b5520cd8497002e3e611b62c8d6356057eee490bdaea48a573a2d93e28830caef4f278d631235b561e51fce0ed32674e53f5140a552cb7c0d081c6388e0e53a5effafcadb1e9bb7b2e6da0865e6d8d3fa48fdd8523785e51f71ea1a27128cee1c5d7b313a04ba1da2b55f9be41aedc5ca165f290751cf0590cd0d4fda27e79761ae35b87b26687011cf31c28ad9d213cb6344da3e3f74b2b3537c3c235bd069f7683ed20d21d4b088ed678cb5fa2a8b5490f1b7bf61818323e03ed030f223019ad1775bb4d2eb1c7b0de8168040063925f1d163b92332dc60a11e8fa243ab93c61fa4c3ddd46864a2d2308e8fc72fba05207a5cff261d3ce57fd7f153a8add024690786bf3c69bd9e960280f148bfdd347b2c4e8917a4c69317fbdbe47b65fe1897ca90aaf0343c7295c6066ae25db25a775eb1efc34f746a1c8bcbd876ca1a2cda61554b1aa040360a9311f60f9eb859eb6db7cc115a2a1a8a6941cbebcaf6f168f51d1ad31f04589a44a940b87979d0107e60ec29246a8ccc420d8fcb4e3ea5c9ad027bd880c3948e6b7159b4a8a37f4cd55e4911a95427b5d31f4d2e256e27bced380dd8d246cc8829b585e8f429a07f12dd81c90e4aef2cc53877cd856996c1478ea4231f03dbb9cde6d8de7297ec59b50b45e032049ebd53d24e41279dbfbc974d67b9938564044581bd86a8ef7d6cdc08a29870510420372809173a9fafcedcec4568d34eab4f895b5024e18176a716b453bba8d17c4aa98641e0ade052f9272f7b879a028af2df79c3a056ba73b0dcc0ab1dbfbb3ecf2a45e574a9214208b332241ef642a9b3a700c8f059c4882a07b51c53c0c4c948530ddf491f68f199e39d885c90506d27e3097393314eaf300cd5dc2bdd5d2f3e57a48999a80f83cbf9c362786b75587cc2c110b6df4957d4e698db840b57f3990871489c67d1bb9709db69cb1d53706044b9c4beb1b1adb6a704c44f90b01ba8672f30afb5ce0a199edd47bcb8e111e93344e453b4d2244f262a824b6193cf528a7639103ac8b8f2a9bf48c2343523120f50b2cd953e8adc09dcbbc14975bd51999a584ada2ca8feb61edad30207495f2dceb01a900e462e6039dc910c907c662c6d15f58cd2e8df6e596b650c42f533dd0d81d1c710855ed25db4128e89420b34545bcd5aa3e8d1c07cf9370547599d25c9fc3535068d70d49bf3178596ab1957e640d3c1c9ec30ab08cf814acf3bb05ca64ff945703c097977487372036f25de21d993cf004ee36e30c75fe07c8e237a9a01dbb35788df885ddc18fa956f48bfe02d9850367135038276ad7ac5cfdd5aeaa97facc69751b681d13c3fcf0f0452f8018b861cc8eb837bdb995d8d04681627cc7ad38588b3024e671d9ad1941ac2b52ff4a94ff9ec9119c77e26f4f16b2da84947bae7c04807e6d7896a4eb000169b8967d635e87bccbb421fdf28d726084833494e7f3dd1f6aa5243fb3ac63ed839d08a4bcdc162b3595e9d5ebf4459d602799f8bfbd5586690b47ed354eab043c80b429f3b4ca1c0e42edb66179c066fac66bde8536217815d0c77fee1a07f688191d7f3b54a0584cb0b21db23e415fe7ad635084a5e405de7c966d880a6746f69be38a57145cbc3f38f131b5b21e5bdf0498a9e2bb907d5aa73183bbd5e33089b4311958b675a65fc285b577710993c27a5231644a4e96ae90a487ee4b5f25548fd8b6d66f546e5ebf31b5b22d90630e8e9505e9479a09a0b589aeb9267946fb14fe12e4b5bf927e8662b339ca794bcebe7924a432b6b215078fc811dd261095648c9f765445061abd52791a68bd1ae7496b0272b2185476bc1989a6dba82cd1e6595ba632c3c2539e2cc4490fddc1983701b68a2790f7ff8a7b6f3504497669a34a6b5df26ac7103b1be2d273be43d06cfe8503da2511ac3b9093abf2e5a23c034eb8629158e83605bf704cea275cba29d285a1868e5d6848115adca25851956892766d702a8f8df05f238a80c2a402072804596d9116cd5da5f2fe3f834001ac6bb2609735f829a9729c75aace0d836b8065dbf5c8df4e036076bdbc0eec5596eb839aa9f283ab945c837d4e89aec18423f40e74d8cf50c31ff70db8457a528c77a3e540551713c65e776e3272224a12720a9b9e434ddd663f81bf7a6ee289d5fc5c00297698a96aba2e380fea4cb7fcbfc438db3b037c9112df4f081eff2c5bf86c1c8ca5e279d4970ce10ac5b53260a9c2fefd849d37021d84db480268086fe18e2e5b029c72a3852341224da2635397b4231b8fbd5efb58bf18e9920bae9463a4980e06a20cf274249c6005bbcfe7ce8dd18c24732cdb4ac1bf83d11b657c55bf551d7b85cc81352d7a7c53e89bb842e069f8b2c124a6af601f9b69bcef5e6740a0ce981c6c7714b376ac1ed6ca411b2609a0d4efddf50162a9a18c4213803c0ed22e26c04dce7b9032a2229a2c083b04df26a7f4c657e471792b80fb7e08dcdd5298ea718e1805344b41e197f95e6edea21c20a06b24c5f28922d3d784a3db550c565354db5df30631d0935751bcf76da87e0e9a011f121f4da51412404c9d533ea8f1b47c2a766ba97b8751079d3abc46d9e1afb396038767c27d5737cd76cfd19027c2517ace2a75d1f2d7da2387c4a568d9c5904311c9fef21808ab53b5830728ccff0c1a15829d66e8dc39a93d514b76b89e25e9d555cb043cb9d3a0e67a77c8ef637ae9e59c1be788c702cc609d62950454a5d9c578b09ceda25e6bf646822edea84c8e59816c400a69df0178f8bda50a373bfb87b442a100764cf27fa86762ddb6f1c5aa225543fb481039a155063cef8bb3ff2e592becc16f12b8f93d10ca7bd85a644beaf8ce26b7b20a3ca57a6780188e2f69f9d7eab8449aa11e447e81c35a2a2c7771cdb03c1d4f793c81db60088efa7525a972757d5d2eb1776feba731f8830be46903f5f1411464cfc60e10d96c79d2503bd6befe426afa55f50d91c298ecb41f2cc0f06dd7fb4a868b05a8a9ef77b074e8fba84274b104ce035f24e70b17b13a5dddc4b3ae4afb24ae106e84657b1ff6c49fa936154f1752f996f6ea52be089cb271a71c6f783c5997e91a0552fac57f96413a7df75af1f4f8a66abe2e4135ccbc3d8d8d6fca963f9f533e50307e01cc56d5bdf4feacc7a481144a30d3c7c55c6ab2a5c9ac38d13b0cb04ecc556f816d52db834b498546e7824764d532fc61e67023e4d178d2707147b0092326e06550ccb01985b2a541513973be2ddf77c2c98099f8990cf5b973b5286c9544566989fb38bc5247f2d5a1236d6beb0cb0f494e67b19d4dac0e73700df4781b55eaba76e47bf70066d446295b25417f50d0814e4b3530c7024fddb0944d737fced13c0d7468f2a1cae92ba079f3a212f1c0875d95c9f86399f8bc530c36c8a3da191668369fd1b569cb210f73b09820cf233bbe24d37d370caad446009b2e668b8ebf147e6fee3cac7025d0a2ead12c4e9e4d048658313f79ad5a630264c542096ffffcafc920a94d3ded10ef4a19a576f6e80444ec71712de5894aaf9d467b4a712365766e2347beb00c4b98017a2fd4955a3ab7285639dd392b77110c9c1c1b2d12b20a6db882c00473798ffe2d7b3ab67acdf9581ac9484a5000817f0b57a48b9ece8473f75d62ed4be91653391c90280e4be7b125992693464a0a244222174232851f3db684db69d822b1b8c75f36af99cd6babc646e9796a2a2e1551f9862c5df57abbcc8b6873a900b24ce7abea3c9078941bc4807f073d624a9514c8b2146fb8ed92221633ea1b5444cd927035792ae8e2c22a206cac941f7da4616aa0e32cb533bcfc704b421a5a676a2e93b0505c95b550d4c544e00267dbb6f72c08576e2350e1f469f3e98483749111862081de8772d4b56e7a49e96a234abe8eeea3e116b5c24746bdaef6b7d3493275a86ddaff53e254618fb4a19fb07b06e30ae735850e508df75c9f19de0ef29821309f3215956c124129bf0e4098b807229ce8086074b272accd3281655a57a501733a1da0399981da2ec635447792f9e548724a19f09c3fdbb2b78e747385b38d78a995c203d80254b4994420fdd4e01a32d812921ecc8b9c7d183ddad7d23d1f49477977a961f6ed52ee658fc49db2bead3b00d4445d8cb97b6af667936aac950647d04f7dec399d5bb2afa1d386b5c29a41583892242fac073acee0c7740470225faea9d56a87c6215b60c2c7ca9734afe6bf501ef2b16a25b8c64276475862d9a795aa5e5e334442f9a253d1aa5a930b88a83970585559b7ee75ca8a2fe119d85d7b8249c9ca40a079b1b873568e1b5551ca752b629be3e06ff7eb0faa4b490e11f169d15fc97c4dfa13f10fa031ae24e8080137e5b3690ed6ab8a7ecf87c7577fc2d8ad055c8214e103cc8920ec43fadb5e332b4e05261adaa0a2413b37b1ff24c2b81ef63b9bdad754cd1737d28904bb5670779d624f5bc1068cd0801e6001b8f0306d27a5957f15f60d1f3b443ec1b2d9802710178009518133e01a4fa23257e2302ff1ddff9750f6fc024a837c6af43b46a17aecf7bcc0a5d980bf7e91c36b631cab928e7652a3e5395289179e82399b02c978398c4e4796c2efa5a6cf4fd704ede56334970e33d447d6146bdbcdfeef36d319c0d40d3cadfe267a4bc688acbc30c9fc52689aaf22b132504da6328d3d259c692c8614c6f114c2136c651b2849ed57681cbce5d7ec868975d13f3b22e2bcb18c369a150158f43c588f848518a1c3503f525491444e881a8696f16b519af71ccdd9780c76e973e452fa293057a143030a0b4e6bd895823cf05a6dc82cb945740fa2e2e85dd61fcea1f0fa746c15674086a9839964f7382b9a0ffe83fa03816808fe035a21d6a7ca3675d7b1bb7c16eadd24b159d2d42ac8cfdc552389d1980bfda9ecf64ea08426a51851b7d24f05511f813af01fb2d15ec806d423e72ed88249a22b5c3428e0e51b9d1d6b3b180430513c2b90157403a533edc59300a243854217afd93138c291a9d91c861a66597f1c0a75708ce831bfe516e8a23f9eead92a0086d518d7da90b5e096652efffb956a443fa022a07dfd5aca652255b4bbfa4d6e7bb38778a0ecf9441718c9fd6e352c12b38112bb9575bfd5bafbfcc2bee0b8d36cbdaf4d8a279fb2f2c4688d7900602553a9d939afb7bded4c3c37a5d2fb7bd02ea964bd9a69a5c263234759936adf5f51f07cd2cdaeb75dd5ff76b4902adfc34dfa2ba87d1eb5bf0bb7d3aa9ea8308dc0156b5ee68c85c67cb39352aa13391e126a2308ca6a4d75e5110b0e9ae17cb0c50de55f41dc61f0cd5ca6e79715841d7bc10692cd9881858bc51c94e9229bf1992361e2e2bf02015ba3a9b1cb2f04f2ec93a44956c4af931d28f597f0c6ca20278ea4d5888d53971a147aea2cfa9aba84a0e82fed663cc3f65ee777e3e125eddc757ae872a6b7dc2560d07201882badc1fd2affe4b7775ef80d45ff2feb7cb12a9121ddd54807c1587bea92c8ec3bb40d154828071b6e417fbd5511957577aacf68db03863d4776bac2cafffeb84b7b9182131aabddc536355432bcf0f696a9aa126619489e1c2f837e56090a568740e2d036e1ad58ddc669f3eaeb25d781b0ca4a2309e5ffb034be64faccff6797b8a4fc845ba4f183033f1ab983220670ffc2231999ae83ffadb834c048dbb4d7fa5ccc3bd941084927cabb0c7ae5e10f7fdcd441232723b42a53c91c716cfd60bd1371d858f58b717353649911cd818916db570b2c071169ebb7653c9c590d438783eaab595ea2702f0ce7b618fb342fd2e44324ab75a30a4e6d5d41dd8d926328e96f99d871e4a368dbdd0b747bb8532b48be47f39a153c69b843532a8e93d7af5d643312d8e5b5a0c4a25f42219acb58f2a70185476e6e08384c5c6f49b77819579789c11ad80cc72568b6c9e9ca2dce874dabd6bba4de1b94886a49fec7cc5493534bee914bb968949d4e9831174104147cb09ecb22bc02aa12f5f38d0b5f26f0053046901c43f244c279943ba89b11e1f1c79b935d56d06f6bef29bb9aceaebb31884f5044cf3a013a91e663af156b02a26eb6f83c8cfabb0ba9646523a610d6fc98009973a394195fe11da460de87f866fe5573402d801d4f263ff9965a7280e28bbac1fb3a91532b116666f1014580a361bcd554368c3ca907f8255487d14c049ee329f36d1c965f0fb871c65390ce44bb2842a5678922df7aadef656b933226b0e5f49f1a87934e662483344f5b90192273be59a78d50521104002e0bb4d70665d566e48f7448cc15fea67bc89905dd64d560c9edc3772d7fd0fe79f04e1e16e153b4c198788d4958a48c5bf6907e77553abddebc4d936111042d296b4a8cc2094514829e441437056cd6627d8e24d3402595c750e0d6bdaccf61142b9eb40d792fc1263427c75c4804ff7a085386eb563553020d5a2d91f2b938c451d0e1e46a5e477f6fdf6230c4eafbddeb1e129692601de45a6c59a2902133e5f6a230745579e1ee33275b7949954beb877d6213b8f9e936bb6029697b62096eca3b90903a67767f7171721fad61db7398a629fc90e9e847224950390feb0d01424edb4a4e35b638e838aa595cb525d25225e5b021ec60f55019655ea536c72983be55d13bd4e96587c7ed40f3b4f505f0768d27f3233e3826a779b6da96ea128905ab30ae2dd9a9274f0d2b6d99e1d25bba5b08dce4414451e17b3fa4c6859ba8c4afc647dbedc69b6fc8b76d45f0224eba4fd5c40dba0b542bf719df330757f504b21a1aad7f1d401e2a5f83d2c6d2def10155855e5956be4409a483234b7c34f32756ffc36f090c50992fe760a384fe8b8b759e16c0e65b8ce2469aad7cc75aa3126b186eb7be7f494dac0d612e66872435f5ae50ab6971f21e6e8e22a4029135a61b7984c9f5f7c4e18a0410c3badf31e95fac7cfa3d154312c3a4682813c11462febbe9dab5402b434a4f05e49f052ff85a0d4f45bb7192106f45466f5b20c3c70847587331ac70b6d0f4bb56230fa6e66c50038cfb4624fac635162f6fb87cc1cec3726c00722b670a1efea68938df478446285c70505ffceb73aa508ecd914b96c4918556a269d38f495a8251b2b0be5adb91bfec46f849b060967363139e2d45f127b22b0f8439cea55ae51766bb3b92cfca3f4180bc8a1ef7f548bd86c4cc348b8544cb3db6ee5cffaf1929356d9288cb80407e847082711ea1d233184ae64a78a6a46ae59a4510ca760ab19d7d4e0ca3059ec005c0e864e5589b654150b015d2d314b519eafcc0b80c768df4e54836a95ea3ba878b035b0a05ac8826c5306e3659bd8126f5a261dae5b3851472b3cb8e118dab83603a556232584de2ab5d5cfac6d967120e469e0a249c2a84e7c2aa22391db067a3a275dc2a092b81d30f0fdcbc34faaf08bda5adca3346ec6454a80d366e899c2f7cadb8f4033ef6801f4ce7505fb9f5e9297932d4b73ff34b69074d344473edea2d1c4925f5c2b53c8436839466313c99b431c4a191275219dcca464842fd4a8352f4bc28ca6816e5564428a218d1396eb5f4fb77fd978bb38af36fb6e95a205e34cd60cfdc31d8d3139427e3707d7c278e09dc9b8a779e465269b1a008776d0858f259f86cb188578370b958c4bb8b76a169daeffc32533e6dd1c2de30d379e0bfb66a448b0f3060859cf1e061ee028af35bf19db4166d67846564c600ee1b32ed8ce2f2804d5646aad46f6f8777af521c4dd6a0bb77abcdb88c74ed3e9aa987517d220108b1a922ebe9bdd0598967c5d22003d678dfb92172a40a02c641e9346e75e2312cd96e7ac7691062d74ed5b2011007f14b9d6efae4e95b3ac039efac873f07191ce29a3a77aac664ae8246c66268b102f78c60330563d7a56c026214a8af6f2dab6207bcfa4f7edba740107d51fc2eb52afa264c2ddfe1827d1a1d7748cb4445b2f45b4bf953239bf7e60864399f74f5d24c1561c1176b8b564bfe086fe44fe158da0ec3a66ebcda0345bf73b5dc84a4698bc1c3b5bf5181f49cf3c818972d1d5b58802a4b7314b83be9d99ec89bb4015c386d96e87e99b3ced7eee25b9a7a22986e0843d77aef9caca912b5d0c88f55061380ea1529cdf84a222eff2e5864596c8cd9124646384f0cff8ce257aa2eee2dea3c3845c968e7b1c794963ab7e0908141a0d262886a99bb5fb9cc2ecd67c5574ffb4e7cef3e257c8aacc503f343ca9f02380b6e2726d982d1591818417dfa0ecca45fde0ed31a94b84e858415e52e22f5b9766a6daa8ec656da88c25c5c79700a6b9a107647fbfc45bd95232a2bdf60db1fb6bdf309bdb0ccccad1f11efb5dc1711d7cc3edc0caf0ca1909cc8283cf2a0042aec2a386cf7460c95d20944ab34213b702d777f31df7d266c3b12e63de1627802154a13eca949db37729d8d5ea9638b3e2706bcfdc5f20f2f822940ccc657083040464a9f93aba30924406880913b6f50cc7c28ca331d8d1d02f0e1def8a485517c0419fc11c39e23914fad2699e57923472d7145fd0f06afc16b379d8bb8a69cd0273254d470cf70030ce3fa02f1baa7213f2c34953515ac2e0ec98348f36fca03d91e8697cfd74614cfccd74c7e4798cb3d28bfc961136e2ac71ea2aebacb81bbb0829a0c07f672be14b67c03d8d9f31f0e2f079bc71de86b8b96a0d04e057fda6d35a7bdb49db820fd89817a7a9a28a5521eaa2d59858b96cb65a380b589ad04836f715661cd76a7eb5fa6c9f6d0a2d59634a960fc11538d24812af0cd6afc0d4b093f1801b6d001c24ce443e21590c524d303000805b45bdbb0e03447da1360ac21ad213a6027bc06c3e10587b4e26967b33564b96b530a58e6a5a8051ca179fbb5547e2e57a0d43287cd018565b6b75ee05ae07b8016948de2c4ca919a920991e025149b093a8c2fdc9ff78c7cc9406c25da988d7193b2bbe45cd379fed3a6ca7c322b05e4bbe017f1f2fdd3b2dff9d641e99a3d566d6134550196467e4326a20f8d1b090b8009c3633d80e776b2179d52854d461e1a8929d1e5096dc8743cdd1cfe7ca31ae14ad046ca127e58a3097e81c1dc164bf8e17d4829cd8de665a551a0b1de6c4d5e094ea71ee568863068de987841de2327e4b70d7b87d846fc1e05d1939bca72c93146344659f71332aa2166e1ff3417077cb28429b10d1c22da1a2ffe7c673ce6ce8fa1e66f22b1e28fbe63a915a507b095a8aab9bd16244cd369d39451dbb5db4145a583f48c2d2a7365424c4e77ad4999163905a029b4ae74f9a8720f310a7d4012a44aec6af7f92c71f53f5e9a9d92bb8329157068338468af607b2e87c5e3a455459dc62ecd7a00fc3a18cfc04b5e46c352bd863720b26a9369ca080274574e2766041555b8cc21515907e700c78a89e0f619a757e999b034773ba04951e3f7b70ddb668d91c8c0698815e16abb03d03ca9813aabf069f6ea2a1583eb4ef5288d43257e704ae86f80404db7822f605e894c5997382d6adf78ad1d86fec29589e76e887142ca7caf53df09fd1390b84365b0ba89bebaa1aca0fc5510538954961b137296bcfa152db73535223a74a4ebbf9d25eb30c726e450229ec2bf5a7d06026856c6281c0a62e534a486ea8f80fd2ccf5356a8e50f54fd2677db304d5220fbfcd29548d41b91a9971e84594ee5bef6577bec7127915eb0d24ac0c82b0d207e565d5b130d4bf2f1b50230b381934c79ef5cea9f8ec62c7344b17c91b3fbbf0f85753f70ebdd44d7629623304549ba870cb87bac1b9343d114855e38c4d9ada3d145541990aeb857eab77e2f70e400ff1a8bb12a429b3647749339e20a044d26bd685974d10be43e38266dc96e9c543670040e9443eda9b180d4a8a7d95f7d05ead92a4ac3d23723de7658e57e3d5693a945dac2d5962852c65fe9eb597ea9b06b3395f5d1132bc756c03a1b5da16d1e87705053bd9ce85a9d73412ee9aab365298c5cc7b0dc456282424934ed9746e084c088c62ce9467c5b0b06338b6dd9215b763372b481fafbabba955234d57fb24d9e93bd9e06afca8855a6b057f998b3e58f3d5902dd95cca4b81591a7bd3c8ce56b2915d27dcd51679cf75d43925efb841a040bf357f0d0cc86abcafe2456937483f7d5b58ddd0dac538fa3fe2342ae65669f760a288f9f523bbfd1e24dbc76b196aa82164a287a63a2970b881454a346aaa0dec14f963cc01bf266e801828d44584e73d3b94320fcaa79691c947539aca8a24bf6d9c9c693876e5f9cf7cc807051bb4d4c21b53bd5da722bf7f58a36b964d03786e4f165e04faf96b68a74e0f09a628f297cd9c348275c32d1dfe014aedbd76714faef4d670835d13d71bc14a868a5249d5c94c8f9a698afdca73b3a0b8808c4ed165f9a5552a9774963112457136bc5be16f2c70510dacccbe8a8dae3b917518f6af4a772d573e18b947a8af60a601823eb85ca0d83d429d7ef7cd186b6f555203a9729c067e422178ac293c12158962c6c03842f021ac12960562090d1930e50943f6b202ede345de177ed4ed3b36f485cc931ca5eb7bb0efe1be5bfa857a41381c089f7c31ab085328e55aaff6455cd76bdf74cec0ad2a706c47222ff2aaa7de08e034f88fdb6c9265b4a29a59452060f064f05e8056fe9929f4ff23cb951a8526506cdb77ea32d50a8e2350d30dfd61da62ebc4e6eb2a432f6d8715dc1376b49e5eba796c7d66bcfadaed88e55d08d22ac42d349a0c736271980c342bbea6cad5334dfac3fef37eb37fdeb60db21ea53fca9befb767e4c807dfa1011ccc62113037aede8fa0875db05e091c8f49f3a6680e9c8fa10127c18e2c310128c48301f307d82286c1c8eeed8b4b3761405c2911d7958a2322a53b59487274e4960c4a06f735d8ad7a4d2086b243e3b0ce86bff94e8db98f08baaa331e85f578200d37ba309f37712d276eb49d5f1f873c276eb2e36055d40a03abee3766fbe0c76bbddf62bc6a027d0d7fee3f9f5f99e6f9f3fde68c2f6ebb5ea288c18291ee79194c18cbf30e6d66ef7495777dd5eaf1e23e98e3f4a736b0783578192086b6b558cf17d0d773a9fafa3752c924915063d12104186e973249201a62318d62740ffdb19323d86b5adb5adddee2b1d79b0c9a0153fcd39270913ac3e4511767392f0ed38518281528abf5efdc784f9b583bd734ad5ed18e38e247debdfce6ece4942f50e6e9500d46f55013c6ab09b9384e954ed2f65e1ef18c3c4d7516b521b7c2c4c9f63d57427a4d2d26eb77bd2a25d8f419fc4fea3a4a9ff589faf02d3579faf441f8fa41d2140abbd38574defaedbbba1edbb51706e551d7a77ea2675e10d476ce709c9b945e2276047d269cfdcc20ea356af7834c13a75183a9f9f801d61d09fec30ee6e97f4934713b05787f143fdb6dbed7e97f809e01146dded766fc71feab8dd6ef7e16eb7fb3a9223d8ed76afa34ffed011c9d365afab4f479d12fd3b924c33fec77a0c134f3da9baf730ee6eb75b7bdd8f1d91ee6e8e2aa04e794cb79a3e7d822e9474da6eb77b3a6a65ea79a14a7053880b7bc2f0525532bc33be513c69664aa03ca7f9d9c0565a6b6dc38dbe23377e7829a648c1a1e6879427301a3b8ae8e0338315192bb12d3562778ee7799e1785a40a4d1db4a2744520ea4bc8961874e4889385871a58a21c3132b342738351394dd92f1b5821f6c2b2318354a13903121c7632c49adb9c1ee004e3032d8d0b61d6c4a0e5c0522bd346cc6c5d34ba72be72846c25192a6709c207f69ef09495f6d219e79c73c6b203c9e76c85735416d09c78a05f727659da861cb6160491fa9a210c980db46e121b1ee440eed54a6b1cd3ca87d5102bac2dc46bba57ceb060396d3569af1abb26298a95f31496016d870796730e2ffbb53515f62009db4c59e51ea2c072ce5987a5b185c5c985fc14e2c29e708642e4d01e58df7703dfd05c36ec9448648e95225934cc98c1e2a4c79490106c8cf1d8820108a719dcbc91e2c3cd072288e3a508950f1fd28cdca0851b865c2a62419a3cc881dca93cc881bccae9172cb2b04748539c1c3abc6e13d61286858700a283e389d5cd063872ce19890ecfcb996a4e7d4d894d8d4d954d9d4da5e170ca0ab03a6269c8c25b6bad776455a1b9c585e5c50eb01c84f7de7bef1d984ae692cab173e50712ec39799003b9df9cd6749855c656396e6c9db5d65aeb2f3055689299e10c7ca179d72d87f94e799ee7a1d1aa42334ad797d818129ab29c6f50ac0de5fb0a2cecd13da692d868c0f2c2ce9a929c73b6a17b6435e51db308980f6b15e2c29e30d4509e3170669f51f3a4425cd813864fb58a191f39e79c438be79c330e1daad0d48ae2bdc0d1e520543583f2eaaaf185c52c3b612a32990a4f210085302d64de10b1b1a6254d142968b059ce535e235a588295c52a889919179048299b52662fa4d0bc6c28d953daa3d20526c4ca856bb5ad9688588098f51045446dcdeac992303435ed2b2aecb1c156b69293af88e11757c6c23651c07ec0e94aeb41447b29e1f182f274b5d65aefc0aad004436676811d5a0ec218638cb1a8d010c5a13144091324374c512f4faed8b8e0799e6725aa0a4d1d3e866029c9ca19b0b2b51583b132ca0e0d8d0894a3acaf7cc656b87a54b3a979430e0f7220c7e15b67adb5d63e7455a1f9855ff820860b71614f185a5d1e39e73cc40acd9d33946faf365f61cf5c43c32c076160a69cb9b141a8a992b3508554716ab86b1ae7d9b5eb8aead2f1f365ea862e555e806839d124376429bb6d74641bb6daf03ccff3920ca942134b49d6169705926091e2f9408b0c8e140e4da684d1209f3d0ce41d75f5ef08f28497f0eff2b8bf8bb3847ff4e6e23cba5f0924eb493dbe9d82483dbe470bbe5081e98d88befd13fd8ea4ad033109e7b89194f1382fe15714a3fc48bc263cca8f4437218e4b23584186fbac215c17dde623d82b562775fc7a093149c9fe2091257cc745d1667331898fff884a1d8ce4895157bfc7af9b709b97487ee867a965f7624fdfc7c7250fdcdd472499dec74571e90317dd821d9081c293f8b8530a177d042b8a4f7ee45e41f71e9164fa1eff7c4423a2bbb8820c0f5c1c771eb8e8e2e89404b799dec5a524db93e0760a1fbf8e134d8ce4f5126f93d1236adf587cf2230fc62437e711939464bc55a2494936075d474c02475dd55510c484369f7f9de66c5e08a4aede4692c9366d22dee24cb28ee9cbc84cb8aad3e6b3bba7064d1ffa219c4fde7e7efed56fd4d5cf9f4f1029467decd99132fe3ce72ae2cff3a8ab3bfee9781ec9251df1c98f76becc32bd9e5d0b923ff1b3fcd2f2dffc6c37193b62f6273f5a41860374c61de83ba3d3ac21507ff2a31d9f479febaaf6efbbe988f3288b641593643d2e25a5907dfb1e5d909d8e3094ac2efca414b26bd7a30bb2ef11468cf0a92e7c3a82a54bffadade9eacf1a34f7d6596bd1a2e0a6aec1f036ab8a15412b705668c807ea4655450e22fa6e5a67d7d1c93fd6ab1d9a12e2b04854837c070d4109f5a894e2b5ef3197dd8eb80d4d09adcd37ef8f7e2ac8a3cd75f5ef6d86b7f91fcfed5655648cb348a9125dfbc93e9f29b7b5bbd8a31e993e8be4d267d72299fdf6e59b8bebd86d48b7ce4db36f6dc2fc3cdee8cf1984abcfb086b5d65a6b69a5420ce5a0eabed65df53beae8db71522f59ca1e849f6596acf7448d5d5749ecd5f55d7a6facd61393741583fe2dd9e6f644281156f0a044b0ad306b089e7b62f5db6f9deff883649dcaa84cbbd6b16fd4d5ab49fa4e3576edd397e8d2d31208aea75e7dfbd6d37c5bd259cf2fd0e9acdb3c46f53ccae0698ceab6915cca696f73bc455db535ebea6b9cd3da27282655a78e41a48ce9d674c4baaac017d709d66cc23c81aedda7a01e93aae7d18278d7a01f3cce5183f926d0f4eb79c612b02f62d4c7a3b52246ca4bd8b5679164fa3c7f89f41c8fba6ab361512242e8ddee0f21f6bb2f98cb9ec5189e5f18d975da2df644a5f95a544af176d4d5af172ca12255c7e30573d9b32761d7d5cfe3985d571ffb1ec9ea7be9eb579c382425ac0ebea83d385bebf883547dfcc17e6fd97707209ce59b45cf27b8f1c6f72798a95ff10af200f8595ea97aadb7f92dbd90bcf5ebdfce0ffd10da2add493afbd775f5c9eda0ef7182255ca4ebb691b479f5adab6ff36f484a9874c78b048a4950d8595b5b5bc339bb4dc4f7e623ec55242fb9f4365b92aeeaea83180841ffaa67723bde23597fbb57a3fc0824ef7f1ee547d701e0b8346b08365f9a3584ea37af3e82ad22769b98dd139564bc9d3f95c4a9777cd30066429bd5818b5e502e2d67470146418e0b6fd43eb2d38d58bfe3dd7fefbd3731d6628c2fa698e28bf1a423a65c18638c31c634bfd9b1d65a6b6dc5855f3dc6feea2754b7e35093903ecf4f33326d8ad0a8b1153c61da396647d2da91720de120fc7e9657a27e3a53a5b71cbe09e4d488d953aeb20a98a75c4fd1beb4a2e4c96dc5aca472f6d689e8eeff05e5fae9942ad13525a0a74e9d9e5ed15987b2c2595ad1a4a6547ebaf59b751c96b78ec2ab8a59768179eb406fb73c9559a4442d28012ae5afd73bd67a6bf5112a9d32595c914e9945601d95f653b7930575ccc23781b8688b4a43389d1a992c54a04e4f8dcca2e92c54a05366d1747a5576ed9e725d3de59a2c5498b3684af93b2a5d9172cda239d4249ccfc34565b2983f47af348474050a55b24c21aa02852a5c66d07cb2443f4b32459e0ca7e0286e4d787f966488fc0b7808cdfd2213e47159645ad0f2659f40b4524b2bad14db4aebc5bbde6a2badd4d24a2bfd284833ddd4a3975e5ae9a596567aa9a5955a5a69a5d8565a2fdef5aee096c5695500e66c0ac0dc5cc19caf259c787bcbb9bd53800230972911270073db04604e8f71a19edb24a802fded2498b3360198f35a94a08e718d4004604ed7b1253c2200735e084ebc70020463521f70d3e38131617a3ae0c5c381314e466c80c4cf72cc11129ea701132898f8598eb132918131347830b07381bdd366a72ab7b0402de1a54405c05c1633a5870245ec1056e5cd981a54da1ccd29b4ab5e7c5759c504ae18279f04c05cae62b04a44404c90db096272801e04c09cb63c7378906e6b6e1e3601cc691f311f17602ed7305478aa4ac881396db5741e400298cb340c92f0280c91efc3f4b079de083a57228491d2a9724003be2b068039af0518c209ab588039afc502324f199e2a05b0b02bb6f7c5236d2ac09ca76d08604e7bde170f84045c30595870002330a72f98ad112c30402d401198cb3e477c88866e7845000d064810cf95e709008c140fa90390d33784131e01c008e6740827bc126d0827243da7c9f4785ed61f8039ed0198cb148c44f103e6b415a2cab6b967f34e8039af0af1e46301e8f916e96b1325c09cae42e0f020096a16b807869e9e1c2484d8f1d8353b79841d03c32f60b71d9d9fe5172a3a399d45ca93c57305f2fc2cbf64f1dc2e7804ac9a5305b6d9b6ed67f98588cdfba263c4fe3263a785ae56cd56a9c837a3e52b15f866b47c47941961c190a0ae6739fc4892033956a094399a5368d35ba5955a5a6da5957e14a4996eead14b2fadf4524b2bbdb4e8467b80436442ec57af303ac28e9b2cf06ba2a220be7a5151d50f2222fdb3f4d2f57a0f81391d6a855a679de990171bb6b641606e5b2f572ee8bda900c0dca640800ca06616f20bdad620fbd9f8de3aad12a2ebd7165e6ab8c06f9de2aa21604ed32d04e6b4cf522c2dbff53a03055dd41643d54bf3be14b616f583efbbddbecf368bf22cca0e7af0ad9847da5180df9a2fff5c151de4b107abe63ec102b7efd58fbdb5ceb3487b9e45791669c7b328cfa2ec9e0952bf76b7534509d0451e730394313f67d0fde1d303e6b405261b1cb85c59d2a6c6d8d9d19c42db00604eff6774805b058180b9ed731655d0057d17d6d6eab9972fb5950073b69c776f60b75b09f8a9d7122d7c6ac8155ef580b94d02cce9902be41971afc29cb61f0f5fd501c19caea012f08ade28a8048401cccda2ecf7bb4734053df75e679db5cf599447bbb5beaab3287b9d457a1665a7b328fb9c457ab4d9abb61f90efa330dcc03c6e16dd3cfecf52ccc757c73f4bb12a1a0474819f7a16e70b600e8435e1ed672906f533df9eba531f6bbe17d605eda12092756c2faeb859441d378ba6634ad388cd781223e769ff2cc3da8461664d62c29cc48499691213d6252c882c61c2a4a6be84b130f5258c888d2f6147a4bedc301e5e07a91b0bb69f651891c79561476a7801ea92c5a52bec8bd70416c407e6a50bd7ee82a509acece2e6757e965dca3ce946f889cb962d624358b0167bbc25eda98aa5a23df8597249c24506babf608489ddb834e9b02a3a5c747e965c5830c285446e7b5c452969e28252a48b930b45ea7a9003b933c1ee41976aa77af47ba9950b632ebca1f1264d7339a27180727707b23f4b2e3c9e74231c85b9e8a0c1858a06d63f4b2e505a3603669415fba8dc5256966a4358f0254be811e40895314ca444d16052394790148c703831c61ed2788c4bb0a7c74d47f88e55762ec1d6bcf7b30423b36686accc6d8354e0b2f9da7bed9b28cbc6a986383acb9e565c7aefed962599bf77a82b9ca11df3cecfb22cdff6b32cbb7096212a5f52004291b5660c884a0a463e346839928291d84d6bbf9e97b35d6d133ded83745d7b76d6a09bf6fc529c8fe3dcc7e636dbbdf4ba09b789267c489be3fc2ee96a7d1f138e73138e53e1a3a5ebe95f2d5baec7b7b82392f7775c4724975ec74391a42a489453412848823ce15e0e020c10609ff6db7bb494bdcd7b2ee882e9716e13afcf6bc9d0b7dbdc8adfc5b93b6e0cd96755412fd5d9b75e7dee7105ed19037a9c56c80a51eab75e2919ec2d3390d82d631f080a7806ec50ef06fa8e488fbe0956a082db77443aadd075901e55318b7e459be79b45ed37f18a3de3d4592c5b763e2470bf7c73c6b85c732ac0569a53bbd3715352ae613d39c5f0b55bc7dbbf4058fdbb4048ddfaa66ef6d55c830098945d19fb414a199b1c46787864d4a2e6b8409416465504d60f31305c3655a9e6e3ef258a23809fa5da1335264ee4c08173f3195182e7629c091d520f4ee40e7676b5811fa4f8f974ac93f0504c5b7b6830a76a3787aac6d69c1d95cba91116e1b4d3ce9aae579a9a1a358d0cca2b2dcceb428b2a02088e0808341f3888aecc1e7eccc131258e952c376c1c695d706940e0f8a8d1dc1ac104fc00132210e44035688407a469a5657d0e923c693425f4668892064395b42a1fa8421ca449ed90e694b5c624ce12375c663a1041c31054c2d42096c3161c80e8c1ca13ae1bf8a0c4890d9868e98065c30d34fc10e222368478089220497c34b1dad2c1c3d4912828729ca4c8d975a53d6944e4240edacf6aadb571cede5a3b9f9c5b2b6e1dbd1de28c11051152a15cf587195fa3ccf8ea1fbe5dbf275010c484d6ad6b3047b30e9b3c59648c9da4d41bafabc0f4d7317d4ae10c29e3383db9b3d0b6beda6aadcef4aa6489b2d8fc6d60cedb1ef69c8e6412f6ebf9d314c479dcb388fabcde2c7a018b152b40568cea0aac2535d850264c0d607b6ac43d6dbd600398dd0b6bcedce00104b5e3e7aa488d16d09c9419b3c58685001421bcdcdc20062e3548dd70e81143181c9c68b88216150000881b6ac7d5e981c90e438c64e192b59f7a44e07186eccc17133332ec1aba0612235fa4685185d94e24ce3491e18c5a94263a84d84d3ce8931f3eb2667003856ac8a6915d20a64717acb118ca7cd93376806ca95135264a8d72ef78ec10e04401b91a0325e4c99a138979099b51840d5f566a1e600992034c4790afb1393c3e48116707355b7478128395b41461b45a984104d85a0c7276a000f2c4860f1d48ba1479128707cfd65690355a3b9098ed008747070d086288ac356072680305ad040a2e4dc2d8a80147899c227cde802468c264cc4a0e6590b81971f6a19064ca922142e03809d2c684561a1498304b98e4c06687b766876d6681c34406316084f8f2658699587821082a24438ad090a5e644106b80f08222c30d333748c3234cd3c30b674d5ac072068d0e9117998eb4af1b67dea8e932a22b4195cbd75a271065b26d88737c31c645583dbe3d38b28a7111548f2fc618bbc9222a52c4eebe41b3d68d9bc73f4b37664f863e2767a218c29c513833f33c22ced0c0d24d0d1c4432e833448c8800c10043d566ce72d04424c428c4b90715a0c9bd2900110539d33ad3218a5e7b56c313d190eb40672c9cdd78d28d6adc13fe555ab3ac01332b239a5aa39bf4106bc8f29a34529b524aa9d2b54e73e02caa3e8baa4fb1cdee6910ce928dd9d7323f59cc59e267c926cbe38a588326c566061b29363b9ed8f48022b2c126091b18b2d7b7066dc6962ad9ecd03f4b363d2e9ee19b75d61e280be41ac1b71cbe9f659b27f98631c6e2cc5d2bb6016b436593f859b621a36de46c9d1fa4fdd6ebdb919cc1dfa68fa8ca66d1c5b4379e9f659a1920ee6799a64a47fc59a639b293a6eb71651a227c843f4b35509ee7d93e355b267e966ab04010d4d9517306809fa51a2c5fcf8d8afeb334737adc8d8a297e966633f4dc48902041a2c7a73413c34d16277e96663e3cce6ff3fbdebe1d4915be7a6abe59777e6e21b3f138141f02ba6e10451901114519a1f1a25243d3c44a0d8d112b35ff59a2817af0675916a70c08b5322a6a6550d4ca70a05686835a190d6a65576a287e966536ca769ad2595429d2dded763b8cabcd741a00dfb7f43f7cbb31ea67a46b2bb53adaf588ddd65a9f1819ed8c88661035116146040d22a7b5126564b839738ce600cda13866bec8ccc0b9beefbdf7cd073fcb3354fefe2ccffcc0e5242fc1676a88ba6ece5c455937e31918a2dc9c6921cacd191e4e6e7269268d99312b381c1aae88331ceeececccec86eb41650ee4d8882dc847960324ab01e776ef55632b23d3579aeebd60ca64b995f172a30c9781722b73a5ac24f3fafcb3249bf2a41b8140d839555427edb573ce592b8cfabafab5c5bdf5ad935557bf7eb55043656988208208a3216ae08166082238d00c71e3bf9fe5103b3321ca6895917143e68ccc1632568e944132c496d9c5f7de2f7fc9b4fede92cc87bf40d59691d1e17702949ba8c4eb9a2a6a1022c50810000000c3170000200c0608244194244110835cf8011400095a924e543228a10444a130140c8581280a621808821004621004a3108603599e4379006f08f625a52f948835d9a91cf4e87e805b4d6f4df601d52d4ec33bcf3d2d3cb2ef4fa9b91f13e453a7286cfd7e8fdac537da566343a7491b1cc373e4b609d88932d64caf92684f9c1034e1d0a249b244afb01cd0faaf5e890543d89466a24a107bf452882f2f7655c21e63184f5a1211b5b7854fde71975188f7dfe82e7626de93b73ab7205a3e88db850b9ed2700fe052e8227d43892d0f9e0a890df5a8292dfcdd9c319a368becad0b221fe3d33c420a543c767b20ddfe5c764e092255a42feed35312f4bf3144d892cb770951a74d32648585e0da50e8ab43760ca2e7ce409b4da4706f4b8b06731862c939f45b5a5aa71b3e8867c6f5ac641db00cd6ce4e1b222e12dfebf302f45ee3e2d9ac0cc6ad6d7d4ab823b4b06a5fdef9ad22c8adee66d72d36d8ad786c782661414b245898c148db51440d011450f010ee8398131faff942ec5208f7e5ef2d1ccc21a262a20cb37a500841a3031097ad9f31483a2882124a7d18101198160045036a53e505710e7a3168e594c5dd7f64d1398afcdb0fdc23f5ba786357702997c9c5ddcd6d5dcffdded81ddeca7bbaf9bbbd6df7bfdf1bbb83b7724f377f376eeb7ef77b63eef0566e626a3f0e16c337fbaf1ffa39f18cee60f6c5246bbd2b22f01f85bfecebee5079eafebd571fff9aad298321a14848d670ec65890022d8cf7d4f62be8c0b3618661945fbb2a405c71d2c938fe25d95ba286e9d4f2331374906c68f5be2daa789e8528d054e053941107c14d5c678e05c3ead5a18ec07b3ec040230766313faa8069b20c3fa51d5e9eb27931cdba7796860e2f58cbbe8ecf560470f7310e3cdeb508a3d87de9a87aeca0e102834ab3e11b9296e0a3a9b298010e095f65f4ba53c2c2cf8600b69d2458dc159b07a96aba364a935308e1d0268d2e6f9bf189eb43cb4d61926a1c0073c3823cb6b7d376abd199cb3532de9876240c4c7401d9f8193c9b93ddd927f3807637c0cb07eb8e2639ddfd99c5bd22df986b29663626a20a30ec9ce7826e278953010f7f2300f5556f619473fcf97638470f9d64532c1b2e142876991e660667e5105037cfacab5670b835c418e009bd1fea3aadbc60b0118995b0b90fcd06d804e1eaa2005c4baa5e0ec0a7ea697e289f063f44252ae61e92d5069a44c3f3c0f2c192f8fa8edb0c10b20be72a73b5ef8c765af2c9941fc0a8db7d2d321d8214fe2c548ba653ec3cf7c25dba3ce1155eb54748f790bec9e87d2d11f41e83414c1a35d1a17c99e47ac3bac0a1b3757a0258a3aad9b1f0551b16ddf8498b0eb2715daee53d45e4772fb3dd9fee4368de2ea00fd45bf955bd2b4dca24bbd71975b113df686187fad43635358bf0fe976cb36f3cf86a3de28fc03cc35f141da38c9e6450a1f4081578f3f04301d68b7d5a2800960bb15471668714417bdb2039d7b2d2789f11ef588a2381ec7f122d7eebb1c3157087cf1e884ef48f14b7a032a4e607fb04706330273e0dabb033e68fa6725ebf0962426a4d04df6f55eab0db04f1c406dfefe849aba0c61ea22ffb307c79d75940ece2f8cea004b9826b80a72533d1a795a3244c3fcfe326120233d650a87a3b4900d8ee18e7b59a8f7ad35e513acafcdf96cc1a5283cea440c46a326f85bc4d489b05d0de1db35b54b76e4b31bc76b159c3f7ff51e1660e9e326cfea4e88e5e376b2152df47b7386967e694e57f1775a680f416f8bb63f83ae6219b423a1f5739e91e0f645fb4b84a2fba1039459fea0e70a618044bd52f66be2a7c6b2e2f8b9adf6b2a3fe8a3f2f3a7ed93d59eb3fa9eb137a246f69f18415f05ff76397fecb955367a248a54519099e6bbd81a0b21fa5270b0b85ff6e7d993e6f75b7f67aabd8f9ed41485f237278ade530d445bff18c75b85ff7fc2f9de27be68f78e665fae71601be0dccdb7ee91117f18fc46ee142690239f18177ad42eb53847210a930bff3a0d56d72547cd9fc03a30dbfb49dabf82fc7bed842ea0f92e9d0f90d41b320c2e329d4690cf682e8ae47866d63c0c00bcb07237ebe1a216ed20cd2e9570d3efa86ff968e2f962fa923e2b15671157ab70c8fdbaf07bb229e33c2d132922d035f529dfe292dfb8956c26c632bbc66fcb21e435e7409d3d27da04ed2aa043ab300a267fedcf7a96ee874bdf6ab1125ef22a33c8a36cdfaee5bc0305c94604e52f2a4da592a6a59c1f4ca2c583f0c87459c07c344b4a48de1dcfd77d0f08c464f42ae4e62002637cf83a0eccf104d644ec545c9582047d19b027738d00f2ed5510b93c27be604146f3d95e207f8dca8eed6cee43786779a57831fd86de207a99c683182ee11bb6e1acff97e521abdf913497f063ca2e616dddb6a2bfac013dc1a982ee576bf4565af01f4cefe7412c19ad9dd912fe737913110040c4de2d85ab80db42ccab34779d582a09e8522a70104c8d88d12751c020224d481dc7651f0bec65e745638835c539c06a90165d6def00526e1a641277fe3d17aad37c3229f345c2deee09107fd449ff066d17201a95e194cfcbed970359ecbd949f8a39a83fcebfc10b75d046603bbf8b83f6dade6e002116f63d82f71f9c3784abc1c3f2a252faeff43631d7818bfc486e057c117587713b4b5b11c6989e10ae4f565520ef49d5811721a5e2dc8033c90f31299b78b83721a3a39dff6dd94a441374635b66b3ca41fa23fc105447415c0e561e45bc2755ea714402b7e2e1bb4dd55a6866781b6dcf21d705221bc764621fdc95844111d660191010ae80eb3170c3a47aefae9de817d421010892f9af0af0086fe30884891fce2f9f14f4f8cea0edc00bc96bf4a3e32704131b6aba03055e1135c25687890a19cca4b8b63f20e7842048daa4534863b80e3d39a73c03d12f49e8f265262a256f36651730e8c4872ff782a1200097d92203e24e1156ff35937922443dfac89d4b6ec80164959c4373830417aaf5db1ad5df4b2561695b89b5dae157857c1f0b69635107800919e869959546152853edc074579282773d03043e8f9ae5d1e5f4163700e5441bb6fe4c9de9a663dd70d03e7b0915db4a6fa5c582c71db6b0a0948c4ab3b4bdf01d249a5cb5b38dec3da6f88c9e2186f95c3ad0425ffece3e04e380fcc166865285e67d20f4c6e4c4addf7c05fc1061f13841a2982ea494a8354d27827790d5589d111516ae393bd6087192577c8d57dc9969cb9825debdfdb12fe70b5134ea01b85b7f14ac0bdacc11adfefd5baa661de989898fc06e6592c00e29700e0b32ed9bde950fc166dda832ad7ba4331239a281e25a61337fd5feb61900e036470920aca9e2d67c2aad8cf4727f4e613dd3f02c7f802c19318df719d543fe6d3517ac181a6a347b4ebb2f9507367149ff3895d96740aedadbdbd2f44066c564a8036f731457f571b4c0fc706b476c29b772ab2aba1e8f62f9d43a716fc497b602f17cb4708555721f80ca5a46a001f17dde0fdb01c7b771e1f02d3cb73b833f601f8d5d108c43fc9479017dcf36f242a7c4ff8639b13585c9cff49e3d24fab2e47253d7f39cc9a57ad2546d5c53fc6f9516a2b14f1c31f832dee4196f1edc98d6402c949e3a1e7cee8bde2880bce3a582f209ff609c7f1e285ba2c60c6886b82d9b8558c6120451aeb7bc254adc7afa8ea87ac48a52f2b949173130f1eb32d208a10671872194d3cfd8d79fec66015f1ac3f384426c6396eb9eef3144e459c539b68e9fe79d8f0295c504e78d58a5e0377d513000b0d28dc92b67c765a906168544ce77bcdc3b5ccf06758c27c1641103c5b86f0f5483424d44cf614894a71e02801eb2fa757bbd5c0a661d40047c8752ad9087c3aa2e42ea5990d41a63efe3f40e15f44b2258e3adca0c7beb74b35873a70395eebb7b138ceef7e8c02f9e26536f1c4ee7234bf51034ce338f65c04fdc1c57f08f0a72a884b225e09833430f5d2565566edbf0f28f8d7a16097e31711f9859e7c9815c63f17e6f5e4c8b3ba1ffa74e64f602ce27fd408967b8d11264c8b0f283fbcaf3a4751981e45d2ede514808974f1599df6516e71ad2c8a0ede32a0350d1abdd6d238d537594124f384f6dc7bad8172ea026a376b5d4ce47b144f6b861249c80af9949c9807850ac769d6c7d57bb00960185c899fb79acd3dcd896756d5842fbd2937c437d3413d517f06d79df13d9d0a82a310577f76115cb7ce8f183a0488c29acfbb2270c5dbb873d63e651fc08a0a2ea50b9300430fa204f4d527c93bc13a78f8b181254304aec9919c15a1b27cf16e80fb954c301857b01e7f438effe7bd7d9f1d9b77dc9d3fe6ff58269d59e5df21f3bcf57f2cdbc4cc43bba61feaec9b6e5e360ecd3baec94f689ca7ff694bae5b1042127e91897e3842438bfb517b16cb48c9194b7d7785cd6354bc336d879323a2355751bf1d66eff21d7393752a040f2103d5635c1a8ae0c790ac8de30878b64ef22a5bbdc5fe652e9668de6c7744b258d21e2e7e9bcd199effd4858c2956fb182175e66c579809dc0b0abeac765d1b637818b6f4f32510c672220788b7a25b4e2bdd2e430f69d893881d4ca51d274e36514a3550436939f2a9c0bd90ec3c53fc63664a4c3038714a5ef0667cbf5b318b15ca28eca3c3c5cf206da3273f211cbf2e9f8dbf5bfc651ef5021145594a72cda05965ba0d5800692a8b220f104db55839af75c0ceaf16f4d499025f029762a8276271c3413a21ced80f784aed850c286ed166c69744c0bec04b0088202dd3f3cbe6a7ddab11bd9e4919eb08510d48d32638a3c97d01eccf7aff0d902d7935616a35392fd9ff1ff6c3d0b05bc362c63d466f0f087015abe01b838d07bb5ccda1a6c653a6d3d912098b8414c63a9bc263260a889259724a895f4623008181bee3bb060e97fb40e9a1c45f92876d28281e855352949800f2f41410638338aed668bff597401d05a4b7132d88b4494adea600b8e511fa8103bc62143fffc39ba50b69a32f1811fd4f05c3fb3f45e312e8aa374494acbdd5ebed202d3e5ad841e35568e081091c1ecca26a4fe73c74c644301117a3faf662b3dd8dd49055d05b1691958eef1a7cb3e95455d8712745743d274070b67654a0f242ba1e3c5b7d94333aeb1886256290e8b0383326fac8cf4d4f6855316046979c9c705c4f6d8f85dcae983952f8a5a37466220985a8db6c9c79c81308fb1603f8afa5f631d01bb6b1ed0910498fe369f44cfad48fa7338dbecfff4aacf5b4af05bb3ab2bd779c46c139175c39b00d03844580f37bbd0c3974170a42ff3a77781003b754ffcd2c21e82f7461f0522396e0d3592ed83ab75a7ddabd88ed66f08e5b48c6124963897a829c8792771e13b8ae9eb53f7d2d3b05188705678a5f4a432cb55a7674f5cf23d34994b377aea71cb9c5b570cdb2c60fd22103c79908875410eda70aa732f0b9f997feb18761c70c9362f0d8ba5294b580f534d3925f35b0e7d3d9a1250d7f05830894ef2e45d06db64355b1fe17b0a388429ad61e864c93b72a1ee94bb5c48c02941a578ef17a81c0c965375f333dce1d7af1b58a1899265dfd8d866268ed80ddb500f320475d38a06459d4879be976e8fda7f657846a8e822293dedb4e89a93c7a965e48e21b58df6d4f019480120112204db01082eadea8d3587279845f21e9fca1ff6ce0425adda94afe106f2b3089ef95e088eff329b3d69b1e68ae5c78836af78e2af38f7bf3cebbffc7ec138bb4cba69fb5fc3354438a394d721b5b2bb9218d98409ca79adeb7a8ad271abdc95e036a34de06410d5187e480ef7719a17902fdcc970e27903b58d10171efdb31067d98f72605021ca9ba6fe8316d59588e410edc4e21a5fd58687113823b94f49b6f8e67d06391640dde45ece52890794aeef96927d9c6f826c584b880d8b25c0702b888558a8896dbad6135035c70c2826bdce0f8aaee34beba7df23a229628c9487c9b814fbb34384bc14e0f9d1a8b25519c376017ea0522201a9002ec2f0ba8b1d98903c7ce8387106e0485fc0bf9a25dc0c3028ee35e65d53e7a0348892393e599761292b3b4589d231998ce01d7d70813711dd4e8543bdd9c631aa84d51462dd4c85dece81a6baf4791c0f0c74fd7673827b6e8068f4313b96f4006b7061fbd7e7bba679b3c6cf1a3984d9d318b2faeadc4db92dbda621a0f8fec3b8887fb4332ab5dc64aac7d0e9521cd3a3370c6867b3cc5846a21a1649a76734af2ba22a2852ce15b0ab53b6022d3f6f5c2c5d52f6d20299302e737ab6aa4f788b785c19fdf6284ab9bdec3d55ca22c9039e83a809b2cae9ca098013dbf489fc3b7e8a3fd68ad92a2a47ba26e478d49f9c55c0427a9e2bc970e8c80465b30ae794be41c338289ab6102a4d108059e03500fc88a65b5307f4efff528134fc3bf3ed0b3f6dda14faa9a5218e194d6d2beeef229795c8534313b9be8a29e56f3d0363cef8814a31a13b873615f56cc4c4ca0cca8013ea56a1632e52de396aa9dab565b15538221aeabdd3094e22f9554fb6d84e3e2d39fbefd30adc835b8d0b9b7b96ac0ae194b4e2612a466f1078bcc59e50bf17330882382284735daf404e55a5e710cb2f92e8e21269efacbfc9171798ed1a39ad5bc23a59613ede5be283750d64b3eb62cc2b49e8201a62a2a3f255668d4f75585913144c832becdccf64a1dba7494d94716e6f695e73185f0529457e7c967493cfa6fb365c50df115c33aef0eee52c07ffe50384a208a9662347cce083e28c48bd4ba36a9f185f4ef91a3bd85fbf97b6e1c96b10f9f59ce03468035899bd61f9753503a4d74105935ea8c2cbd206ddb97d5a1fc1f4d4558041f427a0c8219aef47a1e05109dceb79e3eccf4090d4520f599ed31346247c5aee8e09fcfdf8b4d84cbce98bf32def5a5c2c455c672ce30c1f31f2d3fdc21e5be3bd85555052d991f125e4509826ab9ff190ed51c7b959d636456f20111a569fa29075d44c58df552227a5bc2815abbca36f535b5ef380d14ac95826688542774e5b7bdd7f8675e6a0e4e9ba85368164a4f508023811c835df08c85fdf908c4f5f5c099ea6225c7a1380914a33c65c5287e392993afc3eab4a91baf82c4947ce631d09648998f534f2d2780d4f4e8b2464cdabdc7a5ad5995735a44b080ab6b82ddab0f4f36466665929a9ff34565ff06159becd0f696d7ac246c750e36d7a6f7854b9df58ca295dad97a2066af1ca4c706b341b8cd5d90c5c5dd3f85042707b66e47405c19ec9a37a7e9fce015207a761c932f11cc6aad441341f29dd6b6833d490d4c6437cd36947fabf40cf55ca5888498d774033adab5d92e766807896948cb1dd4029d3278370a24e8e28c8884117195254238d531f6ddf04d634f8239745707938c581eb95658582266563928be82482a1f22c86c4994a14c3c12a01d70d827703e090b0caabe13f34cee6e1bf6ce3747ed3835589e7b1a0e4d0207e3bf03baee1a4f88b1cd9b9f229ba0f47be70e85258a6759d36da31e27c1f017480295217f2a5f6af7b026246696c99a7f8bf49122ceaed3c258514ee00fba085f6a2bee10d69f2574c27be352b5389b1f7e1232c055d8fc5ecba40e36785dba784f59696f39dfaeb18fe6e738f2896b3849a3122cf36292fb9ffa108ee0a140b0a5ed177c06939de4ef1db3b6708707d16b094ef7ec3059a454d8d443da37d1ab0fee2bf4c0cd2c31cc6a667840df26d690dc65c78e14d956605ba29beef803b87e2bd550e101b0706cacf77832b56674d5bc429d5b9fea85a919e12f74d64ab2851f54821b9f84789b187dafcd813a4d73f9bb7a869ae048d031eacb48bee13485b910d88268bf068d753ed9b9bf62d2d2bbe9229186e82b3a24a3aa10cdf4045484ba4fd0b0c96119535c5835fbe17d821fa3e76e016d5a67755f9cf9d98010b50c95ebda505f2754c3ee2d7b38bc398dfa81e9d4b0dbb3a38c0cf2659db4ac786a216fabb604639ca7833e7d39011c742a12c7dee8cc14a3faf8b43d2a29a69c6bc3e1eeba9ac3469e4dc672b360dab155c84db6df08ef16b263f2ef264bc56092583431252e1bcd0c7e4b8b689535d6cfebadd0eb04998ab505d93e3c2713d4f74ba7fa12f429b674c3f3fd2b11369df79667840c09d0c53259edb1b9e99ed7c9da418b9ce3346b03b80d8d5ed68d36745c12339eb03bfa0f9f47581dcc67393091525429b08842a16d53c57211e606cfc9d2c64923932bb2560885f8ed8149b09ffc2837ac7f654ea49ea2a03fc457fa3c98e78cb4113763aa6cf85a6559f4842269fa96b19026a33e0a93f7fc4f42405eaae74f2f9b3de7582af42db3ad747c5ee6a72b28e36ad50bdb5ce98d2f9043b6e42de9954e15c8f4f1686ee2652273b9ec7527b800e4b2279dc242d4c653b7b8934d6bad3cb56fedfe5ff560f2328160d4ea4f30704026f3974125939392d595cc7624476ae9f66ee1997cf0d3e395e67d5baa43af7dbf596bb3380341314081a3d82a0726006ccc1f4c5ab85f70585d7eb402f2a13535776807fde8cec59141882cb347633c198cd31e6a60664c4e749f18443fcfcdbedd0e52c4d1276440c47d8ab9dfba245bce3681f83f552db95d4e9e95883d007032b2638ac1cc972e6a796f4852c5f3b69b7eaa6ebb26ca62b54bb181533fd6ee5ad331cdb711227589ad63b43254284f79fe478acdef813cd26b0f86b3b093325f2412e1bf68589c401080d833fb97113e741d0e427dda0af9721742e2ee89badd512d9effdb9cf8bbccc1db77103974f07ac4512ff07e39473de93d8593be55cdf78c88fc91575aca8e387dd5c46f152ea3fd14ca040e65e1d7e48e74716ec3a4df6ea7604b5dba0eabf15017cf221eb846a7e9545953906e3d868f366017f08f76d53dbdc550363c6ac6f57e19cb34d19acaa6e8adf510967a1ecfcfc00bfa2667a78103d3be1fccef7d0a61a66ebe4294c7563633f99eb50c38c4dee1f1fb9558e67478e072efbc257a454a716cb1fb7bb1b9905c2c55a9ce7e0f0110fd853793a1c8082feed4e65462e3b9e49eec511e0da82171b0baec5ec8073600c5abec0d3e1d482a71f73c42cfafa8f1dd0d63fa3ed483dc1b8a87698eee95e6b9323dbdb1f2bbde05f48d0d9c7e4e596e30da07422f458b3cdb8827b41d9c9d3089bd1cf1e9dcfa429c6dd5c2f8fe5f20d151761a73267e07ae3df15aa6ec951b0f65d69db94139fb9c76ac6ca00db0893dc880b8fe81e8e1f900787f90596aa97dd72acdcb00ef67438046e38096398c53349fb95a6919efac8d03d14c41b183205d5568cf86f7e36ad2ae17ebdd3abe6ddb00ab775047d3cc8807c21cff016025ff9f145ea3b2352e975cddd8bae00f08a0c123ec9cf2f31ac75f45d30ffcf9b5d65d7e7e338ff5f400e80b71ba45eda3f60be08d71c484c8268b26ebeef92ffb3baeccbbdbe0355bd5fab1220f29c08eaa40c96a8aeb53fcdf4ac84585dc372e95eb1e6060ab8c6730b4ec04d05690966679167e79862304a8fb717f4d05432a9ab6082f7d35e8646cdb3eb69a31bba7868870b7871ed44826d4fe400f1c5c43537f80173a49a1088f8abdbf171f16e41368d3dfbb8c7b1cce0a85232440e33dbae5f61fd7ddd17ebaafef2e5e06617880c0054e000b2030fbb5ba4a02073aca13eab276c1e874c376e2a2b76dc7d4923d6905b65245297165d41a55e95c30e623c0b2d8815b5c9986bcd801706f6b9261fa9b0d26c1ccdb8e283639600a9d283cc8e4bbc4b9564ef7df332bc4f9905797a26e05e5cd7af38fd655260c32ff83a26ef1746433d23dc61259ec835af1322767f06703f2e6548d858321e4ac4939f8c2c77bba97c91677b3607b231d0c774fcaeb9394dfdf96c9a899341421c90f4e14758c8a9a048d125aff20669fed7b0d474bd44caf74b52a336a671c493db06c7c92a8c1f379fbe2a8382bfac44d244fec0e84cc0d61a7c30798093b78c538158017f884aa3347092aa17ea04a0e3151fc40fa48543b01e00b85d8a71f6aefba7a299a49827fbe147f9ade3a0f052cec21a0b5de196599f4fda1f050e6633fbf267be3c63d997e12c00f9c84e322d22c6b94a226a31dff4823267a748cc81eb9ed25589685e524f629c5c69ea8a3fde99e60f68bc92739b5c6e76c6dc1adb3bbd7ecab4897e753241a8098f1c2b97dba8bdb0adca96f9ea5e608509c4d44dfcb60eb73f40254aa577c1bcec7eb270f9d07b4e5dde04b9cfb41df49120dac2efeddf431725c44bcabc887a98bc5d5bfb7e873e442bb1dee089a00b955970bcec608d2851637fa5d0c11c88b5727c11fd2becd04cbd493c666b77eef24949390b5df72ce0fadc30eccd3027f67a2363fecbd4285becabbba57688e361fc1822ab6d1046d67ec5c44ee785a1eeac309296fcfe39b33c275e7e502372bea67d7e4b8899a573198e0194ff835b19bdfc91ed42687dff87fcce6997338d735b1c019194e72f9efc8aa4a2141f45371790d2a6a4c9b5b9dfddd693f556cf28ebf758ea235268d712fd9a9f1ee0e7efbc51f7ea49e15ff3cc3a138c00ddd0559e6c9d93f649937516b4d630667a2fdc345c1bb1c1d218e5bb96f924271bfc2c359e6089f136c68330eec2d46c3afdea2ef18aaf9c35f5b12281635f88c8a6ba24b62dba60682027f826b3117365b3ac7b37da680a707a9f955f98fa417fdb1589e36a471c4b7c7f66f9cf73a619885618466a4db06782bacf095a564ee030959ea4a0c4e18f861e0a61c657c2afa8ee3a97b98e67bcca8bff16d76769cfddc16d37d163f74691e65e79b790ba4d3624cd1f3afa601b50cd72a52067077d31a24145638b9269ffae4ff9564d2388d3f63f917a95d3407850b3cc464737060a4bc6bd79937ce2498fc21a0f56963bcc95b34e578621b9246604a6eab683367bde78ecb4edb56aff1e3f11b71cc3d5bc75279babf9bf726c96ee469eb290793d075066e2142fe4d03c09f9e4da606077404f91b0382baebe1513a7c9e78fbdc9fe4d53bdd50ba2e3d8e2ad7039e61d23928247b29ed788c7fbbbf2748197c4dd173c5576c6443d630ba44f702429924ff2751666fe2d34e266eb3234fe3e9714c66aa2bfc16cd54bf02b827a6f16e41a67bb87c8a87ffe9233faaf8c79274eb1ba74fe85fbeb8c2619975e415e60df508bfe7e8c8f4cc26e34f0367aa1070505f414fd9897f828378f7993f380e0f7b2d672dd2fc5df4cf200607f63d5a4b0caf05a001a9932a53b00a8370802fa03830a95e4ce2578f304746103c5d9b605f0d6bc60793165b214dc65e507c31dee160af1f207ca541d98cc67776368152f50ca6fb84ab326283d00f220a93e7c931e615feff41bdc56f73a73be4ee12531407f25887fbe693b0a4b6aab279ee25858e139838c1ab0404cd9407597d45c833aefaa2771760946c16f1e3879a9b4f29dd8c95d8e713f11a3a49406bbd7d6d828e0bfc98bd62cf1d1bf8e36c4725fe19941dc9937e89e32f0cdba3b8946c7da54063260ed9df879c827c92a529796c412ab0c889999c50729d28f042e0112978e7811e2a5c42fffec9c68668d577d89fb78229fdd5d97238cb33259b33c700f8ca52a25209ec3e10c742618e219105eb9bb6735cf6f1fddbab1bfd0c8b05c6e9484ce5599a819779a6b81c386730a87e39ff12023df3427bb02522f80456bb8e2c7bb6d948b8810d8a80acba3a34ccfeff4e31bd1c2671b0e555abbe6b498deb0a0d7d07ea096fef8ce84e4986eb8b7004141642c85faae28193616c2fe7b76b9de48db86600b8981c5f6ef747df083382c2f47aef577cb4346547b7f43ac0f41a7372332f2f3234289daea64c95c769769895c7340c38596cc9f5e31bdb5526d9bb24917b5ce6d354c4186632a9d6299e0c8618b5a2fe36eec5e37f2801fd6d84e7ca462385a1ac58f486fc1c9d1832ebbbadc41a3fd0f82503eccf798388548c348210cf69f4dabcb6f3e70c332acdf7a5b54a022e98a81fadca535bc7440f4a6e2aa361d68e3cfc733f679cfb2120f07f63cdadf67f5bf748a71d19d664e555f76a3c7e4614c97555f232439625ab73c0d8feab4f534fa91354acc90dccfa886b3e71e3454a0ad183c0a486c219122dad0c7488d17c88f88f53d65ceab9834eaf8166a982539b69b8bb82bf0c3b30e9a2e61ca91202752277e207319a35691a4f347bf1d6fc56190a3e43cb59e447c41e2aaa2054d3fffcff323a42789e3f6218a4c4162bd1e574121b69294acb375c5da3b70b8b010bd8a629ae64054ed83d63802813bc8af9782146efca9565d7d32ef466cce972964afc1b6e1190708292ed48ba12085844f6b3a9d5a31b0b2641271378b5e5d216568db0e19c735932d15ddf7ec63e91a59de4e3797dcc628ddbbffa20af29563e64e78313e4f2656c6f57ac414730df464ff451e603e5bd2d2b8bc6ba62eb3b2e1e710f20faf2a0c232f4f4c2053dafdb14bd6e4fac6b212e81d23f510a4755e8dab7e8f543303a1494be1ed505b366f28eb0a93c476f02605e0ca082c928a91057112c11d02a602c7a37623cbd4d599da03434f1884fba8701b9323c642f0dcf983e39b5f682e014eca3ab06d1734aeb415a714dca15188dd88b473b5b06c985cc481f4e96ffc4d54f1774d75ffa9a7d58fa7bc53d5bc7fc4e465a9d8e105900ad074a46ad711521a3d4d5bf278acea9a887ef789d962b17d91dc082783d0314f67e4952dc5e0cd507af0d98cc92ad91f6e2d1b14b395c70f22494713ae3cb38ed9e6028e859bb379fddde512295d8220cd7d16968dc3d7db1e81f6575a7a63988839cca6ad3857f1198b2054c4a775f756d2c3fd60b922ab2b34fd3065cb487ca5b0f19a0ec198a45fb2b4b9efaf8dc82a260a741c148f22acb2aa7b6ef0909eed5f7292bdba20195ed81014e2582511b88c7c30b7a0334216555d712149fa73c7cf034a6363c3fe1e18687ccc22fa64160ea2165933a4a7a09033a2a4f71945ac18e70aa68be25493f37e19d9e2adbda64a9b3db6314c47461ef63c69d024d5d1c9bf5ed32a350ef6787b722bd483e131a1eee097f49508e45fc519b2c0780bc95f0caab77379de21097aeab9e2cfc5720f47fca642370e17de94b0830632b1ad3a28c98c76776a019d3708d0a6cf276777330385716cc014e04894fdf4c0b52cee7d30bda21a1dd22d4756847447b57975ad120205f30ccc1900a5a0b9b439e46428b168c2c05350ee1c4061e7c4de9284aaca9b0e2ad5f19fa3314c26ee93a79b560a91645ed7a6774a2af802865dcd6eb6ed4621f96ede841c6434803764c3bcd27cbf92ff7ea5b76d77a40246c274cd83f37d7f3ed70481a387e1fd6deb790004dea14dcb062f3f5975943ea801e12887f364a76a8a0ece689b2c1d589ad60fbf6b1e3105bcf3b111cbfa39f6b01af73e4cc51f2162631e79202452c805423938ff5c1685e26ba5e0882f6d9e1eff0c465a5f571f3a181a20dcaacb49078dfdb9bc9aaf63d25d46c9cc683c352e40d1e19a929bccdc4a6b5125d2a7929477d57756cbdc1e9a3e72655b5029aede61c395a29f566ee33bbe66b0217b04c2597e4cd0218b436abbbe6d024238d08e4cecda778d6e3e50a5754689d3bb4aa8668f1bfa0a101dcec9edbeb730c6dbc1e83264ab96b6ee75f7ca748c876f72e3bb75f053c879497bde09092dd653237a79515b4d856563482a13e969ccc9d37a8627d7227fa78a7f8a17939bf92574aede9e7658a80dae2439228f95b2e3e2d26e29583da6b80d3cdd3d23f025729a2322dcea557d531583ba9112dc0e061bda12a9dc07b420d6f7d9ed44e0f2eb8eef8fe34a96180e4ff7a3d51a365a2cdf8add5a7569f0e01a2398c1413d3bce43134b0a43db1dc09133ca6b7b4813b7bbe553aee80265f375a0e8b0219bc710255e9c52199b9de6547aa4da874aea2d5ed1552e3cd13102ec625861fd9c0d25c9b7908440c582613b4a061d8b19611b0b25eb7f1623a2584ee9f5a64fb9165047756f7edfdefb841b41844546f918e694e2c46b278f30801e370da56434239909ede42d6f5b61276759949c9f9ba347ac972de480de83d49d55b2c10749f41da528f1750508b263a956a5d3d3b35417881bd9044a97dbca8c956d3719e38f34a9767082a2eb3a299381ee90cb65485f76c76848bf3f47ba156fb9f9f2f0c869f163b54f84583fc84e74c1df5f0e5c708afaf324d24dc20ab3f8d0516f30df92f869c4a4100e318abba7540d5ca3bac2424cca56c053f0a5837810712f9462fa8ae765a5139f4005d0b460f318aabff72a651fd6b4700946804265eac12461b7703386c04fc3e4904925df87d8d7e35e9bebd192d8fc1c04854d81f9b94d4c3d2196e4498f85067fb1f97fe7030262991fbefd912909e6041cb7def18c7e8ae85aece40418ccee42cb1f1843327d60f1ff419316584a2a67771480e89334cbd1a6b33fafe419f10d55dc34c597003f2ba75043be6a725f83aed41ca91c8d709fe780145f4201a76a54bda0cbd22030350e89a3116da16a6a6ea7b763eee767206d057dd10216c39bc1a51dba4d007b23dbf2cd6325c8ad3aa82d6cae6a5287806447dc143273f500998b85400cc27b350c27c262e0e38f0a50033e5e4a9cc95587d6098fb1d2bcc104df3f1f5e8989c8dae1a48540532045e742987591e2bad48df05036d30f35ef3aee01c10d983dbeaa944ce5f3406a141ed59d5fcb1561397129c48323a965dcabd89127ee444b01ecc83aef5a2466dd2fdc4b59a5ca3abe50477f42bd881bb9abef562a7761f9eab54c04f6af33eeef4bf240d158b0488c4c19376ddad59c4c01e8d59bb022824539e7a00c67a8ebc97a3aa9f582c3ddfede0fb47db07f297a6340f0a8e9651bf416fd3ccabfc12f69ffa81ab0cb04817cb566ea7c6f2e98109d278cc6552492bbc8b6aa67b885e9f38694f970f7504cc35091f20a97ec324b8e912aa3af3d03701c0137826aac74c548dd55a05c75323a0f950efd6d29717d2ee7414725c5da0660791248fee222cd0b0c02dfb61597e0ee9e51b809586e01c1390c60564554f1b9d0f1ac86a74fa59834d0ccbf386a0cc6cf644fd97b4e795990e53a5cca75f7a86dff1ef33b8deb8be9290a7da49805921d3ad50db89d1a7b3ad1c7ae03e2ce9642f69993c144cd8e5965c9ada5c5360098dcb008d84bfb33e10002b73616e34cfc076ec826d8cc02879b42f6fc94e501723797dbb816627ad5c48f7e352794feda0cf77fc1c65e4dd6e4010efa061c09d56e7ed6e8e114676b50a14abbad14cf2a664127b9199d42c543e5ef4692b9ff5821da9f9b6891bc74880d07a0953d504ea3b5d27fcf6d062d1ecd58f495a60458a4061ee440dfb8713b34cb5065eb18392851c69c52420a5b0615ec80c0ad1e54b7297504273aae6a4c434b2b83ebca82f80870862959315e11292a5a8414c99d6b1bdbc7ae66ac0468a39ac90342357159307b1580b2883b6ff98b4e0caf6f8816f94e94a0390493629de113ee80cc56670866aba0ff70c43057b0921eaaa3a313cd090d8862b60ac688c16f2731051c1844eaa168335b6e884fbe093f1ddc0c707b714d750aa4909a91523a8cd9504a2e3a20c0bbffb753ba4212cbd3c3e0e0ebdb6a6be818a149e114c5fbaa9831ed830d80196a00c4be9ab8d4e2f3c75266288936cfd0b27fe1adfcf500f4d2cd736165e80b765598297a57f28ae75e54480c96d3b4a39206f9f900f993909c28697b553601a150d33fd921d36425483618e00d07b953ca7a5eec7b9e0cbf187b6be811a159d0d30bf94e3e03f209d3066dabc90a71c92ab37bf6c8b1726ebf32adaa58b8a9ec1ae9d3b0d5df3a504f2df55f72c2c4c7d24405b55f81430a339b74e40e4ba5adb599ac60b1934a785ddd2b7a8140896571ad23c2038464c8f087d4d3c81902a14b282695f3027ca72add8388c5d21b8257243d666eee44ddb1b36afb76c05361bbba9087ec58f3a9f5a993fe467d2b8fd674a66cf05264c09a52ed99342145c9615b3b6e2eb85a6e2ef96fbff37f0286fe2189325627e8d9338f4805d089edf52626d7be864964406fbd39ac2ba5e3125592a7a338d4a5808e9b3961de474701222ed554ad18bea31b4286b9d2f2f2a19e34f0f71ce6136cfa5849f05032660014660e830cd012dc1445ffe19ff4c158de1216496446ded1793c296578baebe6c4d2e07faf117cb0a52250589914f2da356311186b53bb6bc2a36f2e43cdbec8114489f9e1e128f0eaeed7b59a531fd45e91f423b7a26e3960ce64cdff14e48898f806366b1ffb6a00468e6095034103464d86b589ff2bca59d92467f245fdfc69b034df08ef5f56445abd9f50cbdc19e80f0e55c6dcfc6d19ac5bb598e5183ec69d7767f5666599eb295c1ac3bdf2e735d86f094955746592928aad4b2ef59cf815107248a3cb00d62141aaae8f9c3a84322e25f1802030ad5114f6b4c7f20ae4d70e1ca57b2725e2ea060e5a49fca82bad1a209e6508bbfe56607cd1ea35ceba58d02c45c036ab4ae8e5710400b398d01e149323e741ce94282775c1cbe664cd0cf78bc3d3e3038041707c220e96dc40f08e2196ce00e3a9c734bb965461c169cfc91795d7063c9ad56944c24484b530c129166c027bda4edbdf7de7b4b29a59401be0976083808ac9353cd9e9740ed11037f37087ed23e38a1f688859f341d4faa3d62e2ef1663e2276d76729eb1573e727cdea8f6b0f7d159a07a778e3c69201557b7b97570cbac0320ffb02ecb3f9975200bde9083fcf31d1dd6330e1c30182c76e3062c0683e1c071a29a33396e1c7ae7ac4c26dd9df31da24a61e10db7cf5d2e3dabcc759ac970bb7c5cb7d9e7f52a16b9ceba158b62076db893797ec5a29d83532c729da8c6ec9c7356ba52d9f890509c89e26c0bc5ccfa4c0c75e48c0306c3913fc5a29c43aa830bc3ccba8ed0d20c7e9073ce3860301c19fc3399e40330b3fe41fef9160efe65d669fe60b00ff67ddf7798e5e0cbac73907f7e7078457b9bb778f0d3e79c33ec200c070c8623e74c2679107a99750fb2d65cb805688bec9e58c4fd070cc5a22d003828166dffb1c71d2091615907aa1067d63bc0f63f99836fc9b1bacdb1caace7c85ae726a918ece02a1c6b0f1c27ed66c57cceb3a393734a4feb653528ca681f168002a954e32880cdadb3f278904e4ac18f7aad95ea8626996c1bda27cf99e78c757bbef29c2e9d3d653cf94746ea107aed613faeb85015ce5d69f5e34f0d975e6350e0ac330093a513b0b4e795bccc4f9a5417327016c648bffa9cb3e452250a971780a85d239aea140e58a26d57e2eec46927416c192597a62d658ce145470f863e51b1b0ac3d4b2c2eb858cec04e9b0cdc0e9d6a082f54e28b022c431688aa3d4b1cc850b5b09a325e61853eb488c81197d031b353f278d153e61003570e3678814eb0a8180d3e586cf070830b8e4d887360f297847e224727c50f7705076b3ad8ba0000f8464606101a1ee810e703271d51661b0c415c0d3bbe1c84b804a0fb22002ecc00c6f0d89e00c14c8f2a7c64f183734300170c6d6200c16414603bc30059d608c1298814224e866d032dcb01b61f10e079293242842d09214c8c5066081509e0b020c28502362f16805fc0806d8c226518d9c106475c20817bd28028231a1cb0617980c743095d906c4440e00813c444800909909980190aa0a9c01516d0e2026d30f045065ea0013cc606c8e0001a1de021ce094e1e8842c2705443920d870ff48002e60202292525588204d298149e4832130215a8508a60e362052f580869ee61043d8841821ed4e8818cae5645ca55f2a20564e28416319b3e5c4ac3e446dcb3d402a7052d3770e173d2c483a1e9b3c1c9d3f224e5c40828259e744f4091224a29650553c0a062c60b3eac11e504860f86186e90c1d352456a06303424514315ae89ce4a1457bc2a6cd8e2062fb0747b963f8081c30f64e4f0031a3a401967a9c5cd9ee50f37e8b2dc273b6c5378d8828593a187eb458b962a5f36a53ed8227eb8466ca94870b967800869a64fc6596e11b3c970d72d68367d1844b9e58a2e21cd5bd4d02e34080a04e542b7d01fa80f540bed81f24077a059a80e34078a03c5426fa036d02bd40aad81d24067a055a80c34060a038da22f502a740a9542a35028f40985a24ee81375a24db4097581b64099969828d5483002165610810a21484a0169891210a0f0812447a4074ee8000736a0810c60e00216a800052620810898000124253cc001460d20e18891220c588002882460c80842442842c001689b284808062800902102fcf0d103041e03104000847604cd747ce001908c7ae1e1059c75f686da4a3fc51e33d35d457a2a7a818728b168993f188b0ba071e88efa5b430a640b412eecb20a75c80debcc8bf16e3224aa219e43ddab8cdcce11118990606fc799c443ee3eda6e0f762156a1ee6e88bdd4aa30d64becee463bd61280d4623dafee7acc5927903a91e81eaaefe69c75d634f0efbd07f1ad9a5cdad75e9188266dfd148be6d0b5b4d2004e2a83fd5662a9b2377c70ac3db66bbf7dd364bd1e527f74496ae935d3e6c7062a6e6c90e2829b2b6b5ca141b7512d464bc616639581b5026705576220b45d79c10ee32fe3eaf1c5f89663b86779858b2cae5841668a1d5dae33ee4721acd4cba8ac041ab88ce5952c54289c999a2b51b212ae4071569e5869e25aa8426f996ddb368ee3b819a2700933581967e08267909a82c50c59f00c3e34c1a2099e5d51420d6f3a2c35c0296ba001951916698466694a19d29431b86056451a5f182a2aba1b64f8029732bc6046c5ce9e659518ca2a4d68b629a680e14dd40da228226c6226862e3786219a988941871007331886336270010733314811c312294881d099281bb80045d40c9e405146a9894243e687bc67f608c65946899965d4112fa0a1d2c5940b9a28f1829b5bbef0c54c89d59e651497282d4d4b44e5f0b4448e3dcb176cb0c73dcb17c0a863c488f91123342ba2a4c2460b9b4549c58a8dca1927a0d4134ebe259c7861ba22382fdb0f984a96a74bc586272a559ea85079a2d2c2940e0d318a31a24c61c113a9295c40494db1028a14b76739e54c9d22834ba3a9062e70cad2a40627dc7456baf8c270b20418181833c41a6160d0c50c42d4104319058fb809d700d54df9d24319a58c32ca9319988e8627700aa6e012b426103540e9f095529e3c990921658d2dee594ea161fb01bc1dbdb7c746ea78fa88fb778bf591fd7634bf4ca4de9b9b7ea9a3f489d9974a67523321b66a032f332f5e84bc04f113a5890da0b0186f9cbc3650d438e902a58aa72e50cc38e952425162df3d4b284868f9d12234fb014a540950ac64114b285252663ef4f024ea095409e504ca05a129a2c062b6eb02ca666bc289a7c56dc249699b70c255819b70e2546736a431830e0a0264bc18a18316694c896206275f6ca5131840cd6ed061fcf62c9d14b1c96719597b964e76d8e438db611cf72c9dc0d093c6c66620b15a40fdbcaec92c90fdb474d746210b641f8b19e14ec2a43560d2b8739ac802d96fd6dace02cd1891796d2fa5df178469f12908f668fede7655f6c5fd7473e380f6a5145cf66bcfd2ccd49c7a0b1313a918fd3c08f3415f8c731fdd237a3c841eeb9008fdd535b479fbbcdeb269265228cc4b5da1d8fcdcb121b7f4a1ae22117a1bda9c635b6246dbe79ea209760d18555aa06d5a69b440f3320b546f81de8c732bb92cd06c02aa8fc58c6c2761d236dd8049dbbee96981e683da4c9a1bdce68ad0951fa1d1f5cbf0b57736c30c66348c76cff22906fff9f62c9f58507d289fb4944e47ccaadcfb11cc0ed33483a17c9262877b964f4ccc62289fc438cd6098c9308bfa89aa325b69207419bef85219b93d4ba72f9bfc65253871f9716ab2f19e65d31a9bbcd0396e0665e4b8321568a229a149cd78abbce9a87432b8b965d3174db328a3d093262eb4000b16512e3811830b61a4b890830d38f62c5b88b3557b962dc8c00550dc38712a5b58d33473ead9b36ce189eded59b6204605b3a69f0a52f108f7edf786650b58c0883922617ba76bdd9ca25d1dadeb1ed3bad7365a775288a375277f4cd188a3795bb6dbbc853b087ebab644fbdee51aed4e8d7cba0947eb6a4e4b340e09f77a63f2aa71c47326db66d26efc4ae90de396b137af88771dee1b99549f54ad97c9ba79e0ec8d966ec62ca60a764ece324a28c7594c0fd2a9a9da23e73c94a3534aee47b0d336932fede9efdc3724d6078d7a3da6c91e982647f1ae1ead8647df05e05b4d0ec1c7b714883dd59eb524ec1bf73a1ed9f37c251609373ee5a2c6bf34d9b3d2a2ee71e9284bef82e915be4a14427fe469f122c523eef44bdbbb7af48ada8b21ceb2c1106fa1b5cff67787d9de7e3c6108c1675d27733959759ab7d71efb23aac7bb73a86bbd63fd870d7f58efc7eed9e48fa8f0944671e948a1ed79da1bb577f26e6f0c0a8414dab85672bae101c27888814f4feb022e3dbe97c9a4290b747b7ac6118ef72d098f1d9e4cc2638f5f9d14da5c7832a9b2b26bcee83b5148f8a35193747b07cf8945c21dbe262d816ebd3cb6f79516f51d8302093599c2d2f60e7e78db1d0b1b1f9cb4623c04dc9cbe63d01d9b5e72d17341c20b12511b5c81734271c76f1229081e6311c4182b31d97e1f625dfb8e7f2f88cfc4fbbde045503f714a4cbe5fcdf43d7ca89b9eb8dfc7eca1ba8334226bb311fc2f7bb9c9aac39f342e370942c3bf796efa096b16ee2d65f2d11a46100e73da16f62ca90ebfa1b3377416c71c42c281e3c61c42ba71c3c61c42b261c3670e21f9f8c4e610522c069b434830d86b0e21bd5eae39abef9943483d3d3c73088967ce26d2ce8ece1c42d299b339849493d39a4348ad166b0e21b190c639ab5fcd21a4d54a358790542a710e218962388790c2212410fce610d2f7797308c9f3ba39abdfcecd21248edbe610d2b6e1398484e76c22dd399b48d6d6398454e7acbeced91c42a273ceeab7d85b3d972c135a2f1990f6501adbb40c23a53c224b50963065182c5041584a1388d977cff2082c6ae89a103b6dca54bb9174ed490b9f73257c235a6dfb146b58d76ad3027137028fb7df1b8ddffe4d7d17f5953252bde36e24fe1ee37f376a1d1ffcb273f0463adf3e6a1ae57d3c4b8fbab675bac6b9f97eefc11b71bf1775cd5e4aa5299a9a94d178d55bbac6b4bdf51d4dbfe0e7e85a4bd754ba268affde690bd4a48cba83e7748dbbea2c4db35820fb51ff7ea56baa4fd76a9f91dab4405246dd435d0375add3a3127b0bc46481acb54016ce54944bc8cd97f11d1a8e66d9e074a3cb0da74734347c995a4bb4764d5c3f46a130b2ae9b6166ad79c86d7aa2d56eba6bb69bc8d24cf72b3709427b95814dc50e956fc38656a25fda75b777b0c87b2b9374b7be4cae003ba973925a391232b7f7bbc57b393956ef02e77e8864f4c76ea4e32f5d938addc675bc6643d79ad0383429fc987efdfb0d55dfe1519de7b121aa87573d3c19d3aebb32a94335c904c9e8f51b37fa5f52484636fefaf5d44a2f5d7bdd86a66a5e474b82ec7c09dd54c78680e739781eddfaf89dbc84b28680d7d1b24dc5a2159c39be79e99abd05b24216c88e87d16c82a6af9b60e33cda8c9306804f1accd69e4e833df65786caf1d89b6c5091083d08c66207ab88a4c9462cf69812130e0efb8d14f05eda266042f2d2359fbf0ecbb5251aec20169134bdcea483c360afacc4c4e730cde4f31bbfa19b9e72fcf598911c87fa39ec93168bdd464c3fe5386c72f0bbab26b98b26e8e72cd1a658046faa49d53d4d2f8e5a05bb49d93eaa43b62dfe836cc402d97b909158207ba06c010b642fcb2758207b00acb0c90e72931507fa29c7f57f72932034a51c9a05ad270dcc643da23ac96eee5527596ac58a15fa653fe5c75eb7b0db5328ebe3c6ed6fafcae48d5cbbf1a77c92aad9b406fb537eedf5a77c1baf0cf5bacf6119ea751bbf91a15e875dcc47cf50af4f0bf43c693e36b2a7c9240bd32a6c9bfe95a5ae5e1264537dd47d4e6daac6fa88b9b946d0a8b0ed7ab049109acf6d1c6bf0b0dff807e5a39570fce1b43e9e9a04a1e1b88f37e79c739ae08c09ae6cf086b73e9458a0d1fed833688791a46194582ce46e4f937649907dfd84e3361e821aa9eefa271c879df44e52355b3fe1f8eb9f263d9d6477d52a6cbbd35b7068166e5c93dde8d22a6ce44403b393898d87607da48fb6c07eb7bc8ef1abbe2ad3066f9e531b9659989985d7412a1a79e94e24616a4fb1c8c84b57a65d7596782a2c0a905ee602b3eb7dd4d8f53f3a8ed8f561ddc048bab6cb045e76bd8fcc882abb5ec79d4dc0596957e3f515895dbf6202d273f182a67a7963a5a0ae141a2c55c6568513d309f1c6abf20d21a682437c117e613262d75fcca22ab3fa0267acc222224ccb4d0e1167e858d929228c104f11687a8a28c38505cccb8912c08ad8f58f95e04c47c4aebf4f09c2a835f4e9421b3f6a0f72b442c75a6537ca6c602465bb04f366d7eba8a51729bbe6791e26b8d689ea14774e547b6253f43951c5b1e553b1e8a7a27ef7916635f9b32b185234c1449b4cfbf5a0a89174fdbcdee6f8eb53467afb23fbf0a7f6f8d1640e9d446853fd7ad594295f8b5a8d4d93aaacca6ed8c011e28073239f60238c18cce7f3d1590255460fcb6ebcfdfa2b1bf5f0b83a179a9e3c02cf199d9c1d6e47ebe49ccc1a5b5b4b68e4a1125778a563d31f51067ee10d35fd7c3aceb3455e38e293f786db8eb3cb41555e8461776b10942028425a64e0ac207532762fb08b19651735e6ec83336fc410420f82b5522b82dd5593b2a2dae96b6fc539a76d0a620d4ae9bd58b62ad65a8bf1ec02a68b178a8f29bddd5c24e8e244e57400679d73d24fd102f1660d1067765dc2da0fcc998228c38c2f3679d7ec3341a02008306a04a125082c4148d9358816bc33d000c128206e00820b07486a054a0a65a24db5246befbdae15949cc0711cd759dbdd7bb9241aa8b2eedafbce765df729165924dd08f75a6befbd5cc6c70aa8b28a801f171299cc474703fbfa24f1193b34ac74a3eb32a11f96c88e60c422b11a489254abb4494a558d098261245dbbf688e1df8df127ad8393e3f6bb37009cf4d931ee7773dc274d567bc4badfdd019de4b163deeff6bc4f9a071fa1f6887dbffbfb3e691c042a9fd5b1988f5c958d7cf46bf57195c4354e98365a693289cbba88f6bc975e3af2d49c12a441900983cc1764d69464d4b852261921c818b15d5546a689edaa32b1c85a7b2f1932656243ec26992ccdaff1043ece4beea990797baa91867c46363ed212da66e38b30db10d96a4fd28d978cd9b0bda4c3be22cc36334c2e3d41c6cbd681e76da6db6791abc95a4c84f94d54afb8648526175a60fad1bcd54b6a9bb47bda1e829c18a3904481c1519b4e61242b6c1c45a144d1a8bb46a98413a5182e3c6e18bbde314a3258ca27a22e1c7a4b409b435caaf0eb36a702d44981602057870c757e18bd93a110581098f1de2704a8d36a08f5aeeff8e0b66d0fa8174f42bda897b6973fef987ba7667b79d6183cc1b4b977f4c87e567104a23d750a74177520f8caf6ae6c9f936fde41b3b9c788dc73bf9af41e3b5704e3e9ba91bcf79c80b3b95b27dcecf017f69b7b6ef34a2ce285178570dfb99777deca4721197e7c4e0cf6b95d1deb5d8ec1fefa3c7830c788848f3d7c4cc7605a84a5adf31891d7592cfbed3ef73cefafac7357d6794f2655f7ce938f5a9fdc773419de7b8efef169e523eff9cb3fc2107bfa7b9753a0db1efcee0782ffe07c48df93b60dbaf9bc10b87692eb66701ba3c3fb262ea03b772b825095ddcfa9ee0a38c1dfed6e9be5acb55673f4cecae3c7be97ead4dfe625d4356773da30f15d749b4353cabbb5dafbf42ac5f976d786f0dde25ff6203123f93d29f528f5b890e46e3f02026a8feef63aacb5a30b88917e7a5d9559fb201fc6b9ef9c33341c131a384ab0eec2a9156a0f4ad636f7a9497b255c469a5465f5e1deb24e95e12b49f2a1da5565415323793457034ea2f10b51982f15e3cd23d41e56d7eef3642b1079199520203c3d39d11059fb638739d4138dcb5569d78dae5fb68530bef435c90f5a65ceea83881875aaac5231922ed797129cf48571962880736febb69dfb100410cd213a87e8a6dc11d7e31289454b689ceb537be053fced604eeede7ab77db1f16344ba6fd779eb5b26bb93db5597ecbed3d444191b0c37b1a8f52e8ff7597d3b9d7346ce59158b6c45c0779a5c0a7f445184a5cdba4fed71bbdf1355f137c75acff9d4f94efe740e5e47c75a8f11112fd2a0e60c00d9dd9e2727b3deca222c6dd6988f56faaa7c24ea4d35a867956ddbc34dc7865c2626bbbb734328d3eee8c6224c279898c02e2fa17190964c384c4c3ba9b5bfdba4707f4a7687b424c84edab687e43d692b6281dd1dc792209b8a0958d2c16972bbdd0e7ae208447b4e1de417525184edf76ee19cd15f1e73ce48d52e1a3267f44ce8924eed986e410f0c2d78ee734f8fbcf7265dfc39758380b43a317e155e0cedb55693dcf157994719e3eade571f3fc5d57857f7aeaeaa0b37f86111b8d77349b8d6a515b55c942870a3ea3ad5491d7cef05bf5d95799431aa1e923faaab4ab27baaf4e78c3eecf2b418d3d1b600ac32da755dd7755cd775f73ecf3b97bd9fcd6df73c6fdbb67b9bee964cf0cb28fce08cc24fd0970dcacf4f10f7feb85c5d5c231365302106136b9a687ae1327166cb6a8f0e0926c4f8a8341b54c558c97ba918708a609c251352f62ca7b26c01ec598e19635b4003dd2d0aaa629c5546492a72b4e6a02de3fded829a18f161468c6a8f4b373ebd32268c7d5f05382b7ee7bd83733749adb5f66a926a926e22916f7376ee3bc7b845b4cb0a1861eb98b36a64e69187919c6fc8a9a6ebc6f122b993562a543fef18368b9a33f6f72c91107382375b68cff20447ec316bf6077b964ba0d92092da63e277dd3924f748a2ba3c7af7529d1e46fa2934d74c09d41e36ebd833828cab7707df913e36fe23d341f270ed1177e1a827d7a9ee6a65ad95816098b9306fdbc3fbb56dde0eebc422efa0e775a0d779777361b661ae9b2a1106d9a031e3fdc765cfda5a67fd06054f2541bd7d77c73a3cdd778e431d34c448ca36d639c639cf39fe8f90475fb14887874727e11dde8a444810274e1c347bdcc93af9ee9cf0adf0ac1c7ecc2178fb2ed424f80d1cab6cb4e1528bda34c0ef344f3a3339dd6cfab3a9fdbe8368d22c99710eea2f1f71ef4e43f2d3a4d0feeaf45d587d8c3e58b2fa31cfbcaa3a1eea805f69f23b47bac60dea2fcf4d392d748500ed838c18c77b9ff60ad9b9432b1689a08eeb6777dbb98fe3b88dd3dd9220e3eebafcd34d9ab78d9261789ac9ef902e0972ebbd7462d5f689d0ed4de669f267671f8ed3a40edde8ddbe713f8fef62c662d1d6d11fe4ea0ebf1fd60785a25142412818e7c711bad1e5e2b237c5bbe81673901023495baff5ad30d41d9875aa6cc35e4ee2dadb7de80873733ae9120912274e9ced537bdc5d6b5556c7aeca683767219971aca2111c0d1262acf73e394c8ff8d1d212850c3f5c497eb424e19b8483b4586a6d9b5b83b4586a2bbddba7a236b80255d9674feba3155ec79539906afbed765b47df6da758f2d177269b66d2ee0da476bb1dbb23d0de6f47e03f91ac7583a326936ad781dbbdf86a122fd536ba6d14cb26f1bb7c64cf64df7c91d07724adb249bc7145c8baadcef656e049efdba6491a3541bd6992d3db266ef6dda59bce57c786d0df22f4f74828140572bf697b49d6712764fb15b7eeb2f4d86d611e3539d708e93eb1c803c13cf7ddc07cafddc11db72ee67095bd1359ba21494aaa6412ed3e7d74c9ac43a15020780d39d71cdd6fa7dfde515c414a528dbbe3cf7b2b4f0b744cce351b7f03bb7fc7502810aac9ef9eb7e1cd6df7debbb94d53287407be4ce892aa8e2640b3c34d4f8fb388b1b241d8b34cc24d125fb66ccf3209a89dc4d4067778fa338758dc75f66c82b067013a0ea60ff0cbf5f54862309705c1d0f33c2fcc47dfec3c2f0c5fa75f62f751f8af087da7c9babf8727aa96ce2cacb53f569aee8fb4567bfa2824bd935693176f4b35262b6cbc052c30e24c9318b65c41850aa2a8ae6c19d326aa0d531a4be8a06123031b19b059019b2deebd3b76c0dacc0e1a54e082cb1316fc0046091a3a2a90ec1a356bdc4cb1a9114cdc7174d924467aed9a3454054e382976c884146c9a9cac0973860b35d600b1c11cf6bc55765411da820b7c31be343466b0823245b0f1024a67868d102d3653556ce0650d2d35f0618935d6e852c0e6068e0d0f52ba30b808830ba61d3e44c1268d931d336cb1c69a1748b005182da0d831650b279aec88d2dab3dcc2cc1650ec90b203ca0e2818632c05638ca1f0ec596a41841634dc90051a38642186942cd66481e60325c66ffa510b5b4ab1e73f5862ac65137bfe0331e5127b7e0e81dc86b76ddbb66ddbb66d4bb3831b1a7cd12587285eca8889aa200c4e64740146142d5aa03853c375bcb8811733dabc81c1541764ca266219258506db0a153da8c1e50657b0a07b028b3328166840b14135c801c6932e6caca81203369d1358783143100d9ac61a039d2d60d8d1640cf72cd350b1c3290d133b9ed29c200d1120ad61677de0d1de90ce3bbbe9cd29ce1f0f4ca0fa273218b6d0aef5549f80c6483fc27d9d3540cc780e11374e614f7b2bb52a72697f01ebd7b4b36799064b53cf9e651a2718c400c60e4e51bcf083161460d1c5c3020cd4fd7f8ebb26ac7c3c3ce1eeb550601175b1a8d2744518ab2b6c3083156058b105973328b5e18a356964a046898506563c61c598d91560e4809ced79f2677b9003888ceea827b3d783f4117f58a07a12ef793a8118a13bea4998b38a4fde15c8790653b7da24655a9190c3364281502cdd28f3e06eb25b6d72b4fa225183825bbac5943161a140e814dd515fdba841ad78a18939ab27690ebb0a608d917e09bd00d61845a05e689b393465b95aeb69166b7b90581f9f40f6554d0f8ea9c3fee620538725daf653db32794d6698f16346694596b20a2382c8b0e2cb0b3228abb0a18a2a33801304a78a261ce26af18558bdb43359497a7f846f871c71f7fee17f07bf4ce3eced1fdd2038456b6b772ea9ba6ad326d58da92882e0e7ed4f18aa549fafaa9cc71849a14d647d048931f250a9c2f0f334488cff541f736aae3e7e3eac218c9ff3a178f04eaad811f1e08d446da4a2713658c322234da29126279553a8418dc6ab1d0cc02ff6f6895590666fc74b58c80d0fce1ac2ea24f74d2cb27d92f6e2b7af32d4694b35b216c24ad76aab33991584fa5941507de299c32e5bf1f75ec81d4caa966e5cee5ec5a2ee134f1d23b22f96520565ec1558ef9e3cca18aba55badf5081fbfca2024c4a6eb84c04e889b29352bbaea446e953b0be4ddb31b05d7de7412d70ec573a73a488b91fcc1719947191dd771b6be8a4482bcb12a166b6419b13ebe356aaa5b44c273b1d811d77b1ee3deddf66425969411eb3a571a5f93325a5d47d75a5fbd9673d57b726c7b4f6cd3b123e3ed1fc07a8f566a29f5dc7ed2d46cf19c5256ea79ec48cec79bd0eac95259c9953b0be4fde6696f6cb2a302873dbb14c447815ca8d2b5255a4d8aae9668abe9810ef62cd164d968ca6c3176c47ebc093d67bdb33e4656cc84d65937caf99863d43a4bd728ad4524dc44234daaaf94d493747347ec5937a1e7741cb7d7723e6a23d6afaeb5ced25624121ad9f9dc463cd7e9b119dfb36e643f3e288b31545a29f55ce52adaa4c0abb292ea3b42c4779abc9be3b873bb23855c737a625e42396f87ef9680d968751dae735920bc6d22110fae08e20a9ee7c87890314e1a8f96aadfd14a5246aaafae94f3d675b492eaab9332234d4e393ad6b5748c7352e9d8f758a78d8c629f3ec2fa65fdc61e30de7ebc655d95c757d15b8dbac611d9952ae9824b5e650d31c5384193b7674945952e69446931861a4c6a58d03101a6c9146fa6704393b2076b56aa9f349b4948816eac5370c0a435717772128456cf9da8727702c598fdf6bd1a71ffea3d13ea3d5da3b4dad43d8c1df13414a5c58e78ba064569debb1b7d6288892cd07d988dcc32e211a11ad4867b585f754d2a76a49ebb513da76b52f635ababeef4b440429b6bca75db0dd27a410c8149030f52bc55cede493b9513fd6afd1ac0e518be9320340feb23f49e56a29fb42526daa7d8804933526feb9644c5720488c65a29a6aa684489c93df7cdbaf0d138cd74bfbd8e31fa983edaa69598e0dfd18ed955335d3d2d90c5126693e3cd6ca9519aa7c4a4bbf70028136a5094d6bd09a57577a13b372f53a7a5ee39cd8426556b914d934b8e92e0578d023ebd127c7a229b56825f7f330a98da59af6a098d8302be1a85fa7a2676c9d6aa86d01938e0f77df105f7867b33a788b271e61451db942cdb942c47490cd034b5efed99333a4abe8d82019aa6b635f3e628c9ed42aa33b366571a7669146e17524c5b8893c14c83022e87a926db9ea51456ca28b49465c204855146b1840b416bca3371ce9c31069c3f9df5517f4fba40fa39c1b97acd3529a31004b591ea56d7a858f538f220e3fed34d55d7a48c787acef3daceeb29fdbd11fdbda7f7b491eb56d7ec5dda8805e24e754dc802713cba46a46bb740dc7534f855a86b52de6be1bf7bda687515f7d5e9a90e754d8905aaba46413d2d10ada7f5352923faaa6b4c54d72cf0da78d6d428c4faa44d375ceb9346395ab8cac9352923f02d5da334f0abb3b252f8ef635692320a35cd6295c2f368b3d29a7eb1403cc818b5524d8a8449c3df3e699f56c237d2544f53c0250553fb0fa0344c9b3fdc6ac9560e88a02dd86cb185150f82f7de7befbda0787aef1559e238de0b8aa2a8fa15c14f111441711445d678a20a8ee3388ee338b258add63bebe3f5d6c156265da35095b56eebf82f5d65e32852718e5a3cce2c16164f1031c6d8a51297c2f054960f2af1b67e652bacc9d541bccae291ead4b5319e26c05658a54ae2529565b8ecfb9db28c15d74ed8c3b3dae8576519a8bd7a584271c6bedf61a9be8a81ab71c43ac6d23150c7b491cf61f778cca408ae34fec6fa8db10eae56ac1b815ad4e409fb7e458ae756392a955e81fa28fcea44555cfd86e1d5a46ba7876747b55aa956ab202edebc11bf3a61b36e3beb03f6f1e098b15ea9ce3acea1e8da57f599335bfaa56577257189b48442cd06bf7a3de7ad1c4d8e2f55a71abf164bcce40946ad7c04a65de3a793b8c4d545708a4531f1ac079cf4a8542cb7953d4d32a56844000080048315002028140c88c40181482c4dc32c647e14800c8b904c6244154a22418ee32088814806a1184388318600630840082169ca46001418201158a2d577ecb846043cf14c7c438620918a066b84dc99b810adb5b4fd522608dab7562a9c3434482543684e2ae184f7720053e0fa25bbb099c630e86ea9e253d24e22cf2a5520fb06205a3b3072bea38bdff101383d761ce609962d3c15cb319fbe29163cfd34a72b841244ec1567e48281e58e78dedd6962e25c31f5d174f9984e107ef44b6d9597dfa579430bb81e119fd5e5ca611fb0048bdd20c01136cd6520cd1d5d2f7680965d00fc0dfb2ea7be4641e0fde1537a128c00e5a801cf37a823355a3366cfdfa1373c326ca6440f74b9ecdb7a7fa4cff0adf64c808f8d8e820dea28595f6a786a5019bdef8f85b0dd0b91d8ad6f2c15b117104d2e9800f1e4f54331d4ee7fb973f5dc16bb608988c721082dcb6c09157725a4d5ada288a1613cfad6864e2b49e5e6d61884974da39bb45d670f293140fde30e14e353c9c228dc34b30adb9e86469172b7108f28f01d92d6ad27832cf6c4bd1e7f026f380318cfa1f1ea6857111a25e84f96a5eb799640d1836f89bda1c3b99c4b4a188072fd52e4225eb2eebb54dba0bb4e5771a738717151e011e3e7822503212650da0f504e75b55b6d0672bf9b9e38684aa5d5780923fc4ffda11e942e141755b0d4c3db57c73aff42cbf65bddf4d9ea6226e14a93d5401862af123730a1d581ab5ab4540e6fa0a46e2ba4cf3e1ae5568aef82369a1505e04df7939b6f3a3a9ddcf5bba07370867aabb44bf228e799f37739456c8c5472c455441d03e73192f4679c9155d22dbad5bdc11690208bc3a31a55c2672d0bda8157957f8dbb8e178c961c6e803e4b1fa72f35a52243dfba9e6142873785c9643631bd9acd931d0598658d2f025e1ae4e36e6c6bf4afe3e3c0b4654e3361da24632834b6c04764095429bbad47d91ab1e92b163266d15577fb439948d46f0e6b55dce9a6c32dcde79c6521aed209409fe2bcdefc98b4cbdbc5b23c4cdadc6d1c3b8faa7ba3e387c6b1bf7f1193d675f9479417aca3d35c84145139815c5943950309f8b5767069cf5a6c828a2cfe29f5dec48261ed07d416bbb18931b4a70c3b98aa20924623461b92225dc71330e809ec9e420a6cc45abab3d36c9055b31d17ce2e59a1ec4f3fef3fdcddfbe8e784dc7a03318a3bc16f6965cebcabadc0f45734ba6c0a7828239a31d0d5e29b2c83ca48cbdf03a5c1c0dcc573cb47f073baec4a8579203466d78788264cdb333e353061ef40b0976bcf502fc2a95a18cd877b695c574000df50501315e9905e2a0e0d0eea9d868795231005a79b337d7e4c7bfc50de8315579b2ef2cf93c9feea000cf22632f0a3bdd2f7e7db25ac11a9f2b9520e7561eb6794217968bd43d754cae53266c9ba7a84cbe3e823e2d4ef9df0afa1d6b7fc9dc719a6933bc89a3ea6075dd69131473f3a15c54f8a59726ac4cd86ab6833b4c77f4a57ddd59ccacd97f8e81f52dae0a6feb685684bd4f798dd99eb0b492d364b22304da8f2fd6a6f342a3ee8cf2ce8959f6078cc9615537dae85888671579d11596cd552a32ee40982e86110cdbbd534333e5b4b0d4dd821d83fdb99434342e0d6a4220a5d991cd6ed3f1bd32355552cf0455d48161ec5eca4394e0d91c76b41c0f5e86cc5cc808471854f70a0e83bbc80176579824aaa1c05a121d56bbc80abfd80d42829f246270492f334d6590c0213fc29e1630bb7ae9d2169dca6a4e62624281c0c7cf88ab8d0c95b4e12ddcf76474c59a4cd54918fd262a38a67a4ff30278d39a4cc396b0773f2845a70d8dc884a7a4e94ab1f1699e044458b466b8f7926b6762e5cd44647bc7977d9600407386f4764cdd8d3fc5a6141246a6c1916c75713d117a8088d5c0911d5589e13a9f905d9691728878f3716430500992e97c55ecf3aaf48426eadf3816bd7015f66d469fc836fa6dbc8bc9763f9b34929ee790370359082575303bedae2ef7100ea15307c9124af2b487f4c36988dce6dc4c1110ff6cae36a44dfab582f39bae77ed0bffda5875a43d70b39df6e266c190b6664732cd8a59dd5cf99af8d22c50550ded7e01e467aec7174e46f0eb511706ec5bbc1dda545b963ae2be154d4867522a3ff6c4bde7ef707051ab4777b96d2e3796cc529c578f57007023492e112defce4105e17836e5dd9faf2392c9e152b364d24f29196bb3eadb04e26c8b120eb458e02d5570e745c8989a860cf2bae2d7c527fcd78fffa2a0ae4a0cbcc3e5dd689b4b15e4395bc90a990fe72c06c49d8d57a74a838c16f50a422c023201350c8e2eac4c65ee0b6ea579a611859be6da66b3a8ebe99366857c2cac83d6303b83a1beb989b578e79c505a0896315688a114a406c372fd4a36d40ad32c24d29f665b90db211a8b7311484049be543d6035c27f10754b1bfe2ef3dcc57923dab2819ce3c2de0002208ccce3a89c81f3ee8d88645bc2c3bfaefddb1c286269d6aaba2966de2f305a97b90c64bb67ac0e0933cc4cdd861d27f8c54df2e4d775d8d5ab7e48b825ac5aed491819c0a74168230109b7220a1ce231a59dc2c77149997806544932a2f59d4eeaeb15bbb1d4f064949f863e4ee640babec0d969ed3c9f51a1721015759d104e9b6f83bdd3f2f4eb557ccb8e9ed8afa8e211a48defde0c42e55bc44ad102611e5104370eca4a2b28bd1216debc0a0bb659fe6a8d4b40f2813c9aea27cf7c006386f049395bd50c77a0a83fcafbfc79600953a9626dd3ddf0e30ae36e7827ce8aa93aec9a146e04ce289177cb2acd8d38aa80d2e7da2f6e6bc688c46ff53b5494260bc9ac10ae3b9ad4bbdc0c2ee156e737dbead3861741e58f12b03402c1bda38ac4b9ae58b312b468cf7e03e7a3d0769724fd7a24c2b6c37026158e80ff0fcb65a31cb1031f471dce4f2719bd4cb56773b013326b18cc40e1b982a374ecf29673c75364da7445a747e6e2bdf2428c8e7137bc5ee923c60526eaac1d7d89e77c983a9469a43299272fa4662f8786957720f988e1e49071002f79c4536547ab25f50cd969ff643cb502b64b0a7e70668926d1b86d0193416498134febbeb97d571d89e79fcaf044908a129f82e9b0e8911ec39bb08061abe4e224f8487ff0394b22f2f46de9619bcb45042bdcd3396b0be0d337dfd1433444775e6c17be52892cd9d65428db381c5879bbcd9699cc0f16190c1ecdf217d3761136ca413878bb2a874f2c5a5ede8c4c1940aaa66946eac4789163c02dfa94e3245aad9b124897c8a9098e444e66e1aa93990f1437d62b2d95c62fbaca8615e7c0ee5ac76887f2eb9865b3dd9b837adf70c69bc516efa27db985e04bfc04944d5f1d81d6b270ad73cd80b2a72c4f96c243ad7c57014fced287e3055560118a88f8c4f07c266528686030f458f58dad06d2e6e5040b411213eaccd3a820bf7d82fb109b8af28b7b86361445f0488940b6f7ca48fb0fe93c716b6c3eb253888830e42681674514552f80242fb5d08dd0752374e9eae6ac68387d7296c62ad4340909c900f0c25bc84b6fa74884b502787256d75a6a74d780ea423fe456ae079f0da730ab43b0970d0e55514f9acadb6596ce46841effc8a0494421cd83d84da3d50952ddb4e9f3dd2cd4f7d13def6a6960b3948dfad36577137c589cf2240a95f60928676ac26b6f03c1a0771839728595c2bcd42e0c4b0d205f38d120e534a69e4dc4df04eab0a3160a6b81b598f620b8313bd4c660ca0480f4a5313b02c324a169b45a5bbf506fbd36b269bccfca182c9edd56139f1bb574c15569ffee7097b54de6cd526308db0392cdb9dcbe6586a013d4d54b0d800c1143cda812d4014206724322e23089c2cbb3dae362557b0d5fbe0db21a4b8cd069a6bb435313c514b6cf1bc984758b9054a5b741be6a67da1e3f13d3b2657633b216297ee20db866a7ca34ad6c9a011286b180d5e89d450854d21e6e26f06008ed6b486bd635e50f6a71a04467871806996965195405b05586ca45337cc5245210597b0770d6c9fb087f0841c896650604d4a5be54db55b682d726e0045e34888c6cb3f44ed21b78e5b7583dfabcf1ebc46138f6b59a30f816ce2ec9288f7d129591f422e1264018696828b2e5498d2738403ed8f280b071c74dafeb0ab27a5bc22b70c1214301cd0abe059225c572581aebe581c7b71ecf2cc7481f0acbdcd3e8ca0f02c829f2a9312c5bbf4573783cdee6df8aa512db5e418c11b9840b975859a9ac3bb962c74f92abac648af97556b435159b6f83a4cd98651fcf45633b749aaefe26ad15ba565d3b922c927538524f2e0686e6be7e3879f6a88436a4b798bdebaf461c335563335d7ec4d4ef810b524d4c883cddd8c1656fe480be8f63bb03569ddddfaf0c2880dc1d17530d9a832a5bef9ff729aa5cbe59c75372846a79ba3102d47cba719215c25652ee3ac264fc1b496ae668d85cb7083d4ddd77c79280f4f5cbc19c5c1dd39b1f92d3acb8d83d865927e873aea288941e04f51946ccce313c62eee9cfc26130ee18bfcc5a02f4ea19eb3c0f2f4f740366abb1fc199d0a603c90fef13c3b3ede3d4422b714dbc150ca278f50a2f7132e0b6c3d68dabcb3af5e2bd93ddd8c013ccb24e3e36cb483ab1f5fad65ae8a24a135aeb4516cc29349de02b2334fc42e92ad9e106674ce3d4d0287d80293b2897382b954f8f040e67279e4c1f116b6b5b777b51e2a0bc80438dd2406c2da00cb04dbaa2c3e9ea9cb7315022fe5bb03025fc85e4b853e5fd49f7ae0f83f83addf427630dafd03c5ab391734f255510e166c3adec2325989a51810d715e031979de12e289ec574c04536aa56cac1a1bbab7de94b918738cf103b427c5751e95da33b2a760d41148c411674cf6a0542954a44307ebd4bdc65a653af4f80165e60df92850dec7a84588959b929f99fc9432ea48df5a593fce625d3e2ef433243ece4230cc3d015d578b41f183e8d07f1e999aa09e8beaf6827df7cd003e430b11a8a89b2097b84662b77b1a24840537f1906c183a34f7e997689597db11e924fbe94c22e443fafcdf2050040fad4d9d8ff043643a136fadb908f8edede1bd265b7cfbd621eb9676d934917726cbad248a53a33caa5bcbede8cc2901136bcd575940e08b076b0ce328b516f9d496a21ec416c93249275e8db92d267eddf462c26b36caff620ec9ca86b48fdb624a6fa65c2b86b59345be98ef171ddc0927b6c6e009c42d0a32b06721b798e82b8ae916435f93fd95bcee28a8b64cbf8602d11f48bb5bf78f10e331701629ec2117bf278912667d8c628fbde47f0ded3068d6a5c4c575e7b581e920ab8341bd7c0d6c424059a490321185c70336757bdfe1df9c4ff85f4e2d9cc6dcd82c54375667da9f20bac3464386d65da88e5a709231f7115be4eec5059ae911adb158b5084448aa5fe3426e4a2e492af50ab050a146e7b89ded71c1d5938fe3fef170b84c08ddf2648905bd214df6dd94398980d2c6ef7ca0e8f35a3b4d2c78dd6b95fa31a7d9fabb35f215dfadcdef395905b1389aa782d163e49626fcbb8b8187ad981b3800d331f2a384198b98d4c6e095db5e76c31e0949667014c98efdc882d184551cc1af8f608d2c18aab8063491f0aa27206ddc796aa0891218c583e67588164e6ab23f3c18160c143ff67638d85bdfca873ea2b7a95262648cdb8a3b2cf64c0db22fb8c848d455c6f575d2e9af63795b44b10eb773e293757b14c4ed552517f9baacfe780932df19c18251201ef67d5a56666e4fe7e06c3d622fcf2c6331fbbe5790353ad622191c3145436e43e8b33b8c45c09db93f80b77b23ec31f25f6148c466f41e4d270b04d4c0beba7f6a7788f79c9e7f1b4ebcb06634dbdb20ca283ca8a8596b28053e56bdd4723943562e542c2c88d73689e50b096d78c74f04390e3eb10f54097a91ec29928a9207902b73b037408594195ae0b9658f3cac217002e5ab71e5b448a32175e4cd164e355f11ccd26441964dbc3db7eccfb27bbb65679789a10ec109edbc60a2e8793c842d7b0c0a2219ec550c8d9d04381a431a41e1d4e5c7f9f9f192be4b2f188a223bf0f9f109396eaf57f0c55a5e063b34114cc9df22d8ae2ddb49e0c360079a10bcbe59624c96bb6202a50bf6428c4363d516ca8b33e750614ca58e1bb72717060220fa2d2cf3a2d4e72de9173a9eab61f8f464a1e56edc1e1d0280a2f7594edd1abe3c6ee2c8ed41938d4feb4d50574d49b1168e2bff7d74d76e790016faba103c30900278d58d5ec2327bd980dca03c7211585f13d78f06df3a7f54beac95a8fed34d49db5a080ef5d4242236ef2208d0fa9e731b29c10e500972d776aa751db54ed50a79e232b253bc4652656eb74386e08c5931e016adbb3d46d735d1172eeec6ce23b15a4de1c318861f5621cefd514f798118b52766f7245f93bf269f7a6eb501837f38134c470a4fc591c54d0fcaad7984f767351bafcf222cc1916d1dec2bfa0f188b2e62586309ee71268d6e4a2c8307f44485419bd5e3e36a4737425d4ffa2078ec0366bc60bfa4e0d5179b05de949651af3ff17f593a07442d2f407353f0dea9154f620deb7927b5854cacb40566bf67c592d5896012f2b8395ee4cee2f65a723ed0c776a90c2c24ca457be678511ec67cd7a19410112c472848eac9d020e5bf6c0d88b2606806722dafcb323325703efb9b44ce6045132c3a5cf93b355d1d4762dd8cfb590df85e192b8d675d8e54b99446e915ab480321634036277003cbe49fe2606f5366955787a23ab085a59306b1f3d3aff61b5ea80a2095ba25936e8b6822253b0155ae797262ebbbf49253568035cf625925c07087d8494088f983d8a3b5ce31749d8e42ea0a01b4892c48a6224a17904ca21798c4ccb9f12b3cc39b9d8f756701c0d66aba6c60043a012b81f6bfe850ed993211a5df900b6a8f473d762b778680b7a049ff91ab97d520cf4924d5b01d6bb42c4466d4d2c63725f83ade648f3bea9aab74f96b58812ba31876f8d054f32d07ceb63c4127955087ed1b53b5f6b4d753d274d1790d3795b994a860002f97f369ce6042a8c434111caf0ec191b8b171e505abe32883419ca136ed99d77e3429cab897d5b2a46f77dddcf15e81e4c292fb8130e094a1b13158b4d315fac1cb56784f8bfa8cc4bac21793adfeaf43e3b72f3b458d8d81066fd9d636d490f4b733ef160cadc8d890592727e5fa6a393977b0c57696511bcb776ebd7f976f322db442186ce6fdded6097697a686535d09cd98c0f6a95f6885d761fc7f1f105d377f85584261f750591f1f94249139367836d1387dd25ec235c1d700ecfe4fadf44e911faf1df6bc5e12eae2961050a609f99fa4c3f66239bb980a2a492b5a64eae164324b5d7761b49aea69c8adb37d832e7032d0a041d402201e718e29fbfe3eb633185995e1e848da250b7686500c132733b40c41605077dece7c5fcebf10c1b83976f9dc912cba624a08b64cecf20df211a3490bed2f093edde5fc6d7e4957d9c74f09dc88626a6136bc3cc55f607909a1e9c5af38d4d9ef16ed6d92e2600ee55d130872db418fcbbe23a8d37bd4bac0e688f2d669858b4f5c258a5af97b26e5440b13f7ce517a9eedb4d6ad897403979644596a1d306f02a277e1c9c76d89e9353c1d7045ab90ab6197a0647a433a6c21218795b57bd0d2427962d057c1b013c2b03772ed100242fe40818444c4398293ffd87422fa2c9f83548d9169e9e7b578569a05c89b245e22f59f4c55758e942fee57c42db33d874993d496263fdd146162674343e5852e65136b23b98a46ab0c7a907e3c8d175e76fadf384bc60993bdd784fe919f585f6d105c39b299b80f39cf4a4b44decc421371c1db23d7cc5ba70043f73b4501a47e6e43e9cdd6853c182e69d57b657a370a80ce30ec4d81dba877bf005bade09d84f4e4ce24c3d47d180b4a1551b4eadab3ca8c0bcd111501c5ef9ffceb915adf368f364c0f4abc48e0e32325eda3e139b904a2b01293a88c8bf8da8b50b2bfe4da64433c66b50a7ba47d56882b81ebb733b8a4aa5d16ae8de623485ada78d5c87b2e001c783b8b84cb4b0c2b8964e985f04e0218c4e8da8fd5576ad25735fe70371e065101982f061e9197b75a5fb87bcf7871479166c1eb420f96985aec42e9f56c01acb10d7c091a188caaa7758449fef068c420ab9fa7299618899fc4d3a0dcd00b8d7537f400839e8e28408d55f9a99fe6d0050a5de6dcba337544c108e2ae71e883e3aee780b812f88edddf472073c377c5452969952a537e5de6372da1c2689c18fe038a472ab5e742ad61c7d4606b30d98d7ed0843d7ad4690f489d901fc333a893a3e8fa676dfb51494a94665d6e2f3f213b8c04f516704a216dd47c6cf2162085dacf9c06376fe60f9e688d35e4c97c8d20386185cc48f556f1cd395c7f3a492cc2e136959a4f05cb0be84708ac56e1aba75129f1456d874b74f1788db8c8d1da72183a5b24519d0264eb7a8ea863d96b2603c76e592c25a71cc0d22b7d0c142d047a867e43d4fe21b39216dd2a2d4ca4c8cba9f5a6bffb1799bcfbe3e6e5e41dab005d285e6a744d39e0425250b4528244b80eda2ddc4d2686dcdf4120d9027b14bb70ea2e03c32a68d71cb586feb421fb806ff089b90a9eb5a809b96ad9aa8ece3166c7f415c2dad714fa14c6f344155b567ebfeba835b82bbb06578a17959ec13189e44807354fd6eac811dc674ac748c28b3b6b20eec3a97d42d948f8456814512f440eb16344d79c5dacc02f9e5859afe90e051e8cfaca03218c6695845968181991f5869fd9d57fe7ecd53f5cb2c7141dd5ce9d9646954306d07efea29fce502535de8953d5ed681b1872241eb7589ca5c79f0d42ceb08794c56b7ddb869f75fcc8a28245ce3198d4875b4739b02ad28384c65b8c2740e43914d591d6eb064ce622f95feb007592082472c02a5b44ac2da580f5a4ca73485803f4e814ce40b65b71586231de1829694535980c02ba85566b9e54bfc34a81277f0bbef96e4df60546382f8a1dad379549136133da853646684e36bd9993cb6692668313700ebdedd683a65babf356e9436bcc67e513221dcafe34a092d113bb55223644eca266129da8990c3140bae2af9f6a452e28b04298d988139225646683112c64be939c2f7e5335eb328e265744103723aa3f30c0c4e1e1c929a6c96290177cd4e06d2b44a671c0d8b45357cd1134d57d81acd39bd0ebf62f3765038bf621448d10b0bdbd858b1073cab64a6c1bf7c39ed10ec1ad36c946bb09c71a66fae7a9fb5a013aa2f45e4c18d3a3e76d9ca9c381eac3325ec67f2eaadff6c01ce2fc0ee08744a34d447fd0a52467a8382d2ec745f8bc75cc57ccf53196000aa4f6da565cd8faa726d0f6dee6264bbe46400bdfd2f6ec23f1972ecdafe860d76f397bd135d3a74349767d5d7155dba54c409c15e6e3c71212225a1b0f2039acbaf8883a7d6bc0e09903a2b2bf518ea391e897e4426c454dc570946fa7440bb3ccb62e9225eed0ba25b35508f137627d46114fe3afb1091d85f7e5c1a2d50ea3d4993aeaeee101d7289e74b8b40716756b27ae4c9aa5e3519d059e303878a9cf7054222af30afdbe743ad99f53058152c24586b06133f836c6e16c0cadcb9ef41fe50ad84f7829f216e08a0aa25a3828c992d92da3c72a1eac348f9a136935711fc83913dbef91e4121f4037749868819045d4c97e9c8df1b348e8ad724dc0f160f7e9ac50b7546b45fe6d72cd91b88b1180b80e7e87b261c17cb4c3fd172dbf078f71cf1cd60114342dae02810f2c390f9cb920451438b811c93b68fb0d8dc2878833930d27172ab53ed1f6176e1bb20513727b5ae557f3adc57edf1b7800238aa988699de524570809d18397ba7ce4b30944a91490846d550d0ae8a762cdce2df65f7915191bd2f275245026867150a18a51223585513afafcf13481921fb3f61dddc35b4e5454d6d11762f2306e4c7e0838f05542207a1254bba376137115c24bb7a4399ee50e2f7dcc668fb888ae82f37e2d594ed567387abdaf284d7ae0e4e1c56fd75d8f5b24eadd3a94f107b02f02d37c226f679348cf3d3c0d7a42491d21d3f98171e75e0c208a47ab4b4a32050c3317757a4cca29fd0d8c7c672e94eb02c85696f8d985d79c8b21f624c31febab3153aabe275b1729248435e6438b9f7a8e2e424d5754d69b44fc73afa6b1d23a7f19617c1b5a7130a902a267740a5f7e5da973969ca48afa4516e34ce2e1ad9b4f52a6ef197030bf27663a34d673fa6ced37fc82a044af5f214149c2dcf99b10834866512b16db42ea2f93ed44376f88b0844583791ca04057545e66cbad13d2384b5ee738c47546b64c9c765ac6cbb626e52401da95f315a172a284a8e4eca5aaab700d9fbe90101144068ca09940837a1a5ab9f3f494801776bf5a9750230c98be899d98b6d8587f7e5e2915a161287170c9689b7da15d99a01a9a3eee6422deaefdc265cd65504531114fd30d800225efd3311195d0975b448cbf4928931ff70f1fc1fbfffb33f8937e2c85c0a241868329d434182959e123b420dc5004580d120fcd3c8eda29a1e98ce03e780881d06124c559fe0ba64058d82ebb831732dca707e54ee41bedf0d2f02823877d015d998818a3a63cc845f6afc6c82023ed95d8b90925c6f7a18edd906da0a5cab62c85ae9c04c209225948b3c4bcc5c53ebbd872fb3bf281e5b00721f9dd2344f0c0b5a344f0916d02e4ed0ce40a38e6af79f156083b35e1116223d5eadc98ccc9b3816b88257e6187a0372709f26f9f2256fe744b7a49885e41b434e0264b441aa1a98f0e4d915d89856d1af9179298a7654851da3b642d9cc4131c9a52efba9e1683e772a793e4d2edea95b20eeb2883d212fa42b4795be85e1580f71ee2eff8458e3ff2a1b49fcc1a0b4da76e04ea6ca9b90507104d5bcbcf62318b2877c62c24cc11eda5c1dc9c1179412a4054b4f2028193a67096d2095256e9589791fbe1edd128ecb805beb82a37639c6b0c243b351f93b0fb0a892061eeaace2fc0256c84ef0032e3a8951d27d1550897b07a21f5e2ed31e671fa198c76d5bf12ce1ff6f109c79cc48f8015af107f77f2b862a9a3a12e48e4a6b4bcb74968be534688958bf6cbf2f694aba2c0e50068d2dbc9978acaf21e33c2534a48ed044735b1a57fb75a2abc68a317f0beb8e799e3aecccc5198f7b39cfc1f330c66583ffa7c3f66122d40c11cdbe53818a97856daa051e6e2b03d221f9fec210822bc8705fe26e20c0433a41ea1082d8dcd79e0adb1b623c78257aeeb6c79abdfa428b436ed940c64f0e40ce61e20dcf14895f1c0cdd80a7ee22a09d3fa91316219b1ac3725c7559b18873be6c730d65e7e2ac1c2ea6c228920531adcd85e66daa411384fc76f780ed06837b331607c8d0d1e18d6363e6e5075eeba2212e985b6af168ecd439794c183d38cfa6b4142e04a877886f80a578642a1a55ee1573d5ffd61d682ab2cc57dbfeb234915dcd13bd5ed6a2d50a8022a2eabfb118135086a627c27016b1ca17475ec31fab5c73188e67bd9c1b540984bd4a70e46a62917a4500f0b5d058c995c74d5ff2676f897d837e0cfc11fa8a408061feac5a8724dce74cc41c91eab62a48e2be25195d66a7f841ab135a56a5bc9e64ce161c3c156cd9bf707055bde6cb889c28afab349a93832303c08b6f82b7a7572d80a0c0efb6edf9123a3c5a9513b53b13eebc8bfa5da07b2a5a72f7391849e472820bae446d0808d5bbe4613d4d8b1c98adc4e6206d90840ee460170a9cd28ebf41cc126b54227adda5dd26adba8fd874dde316852a6f27d7441a2a3221fe46ebd5f780f21d77abe0916a086e4968c964efa937f2f2486e014c3094dfaf186054babc7864af938623ed3c0be3602dd20e37b11bf5ec588c1e1e82707d9bdc922baab90d8ba78c96e0e45556a40425d639e3e4550ef3c0698e541046c47b85917b521ebc18c8398516c0da2ad35f0ffda6fb9abaf0b8b6f5ff2636e5b5086537a6f512a2137c5b209bb94f7b092102067e52426d02d87622c3a86d81fdcaa9b571fae25c5f50aa7f2111859b9bb6b200f838fe36486b935eaf20611f27381665a97afa43920ce3013b62f0160dbb52e64dc9bd31675567b4c8b97419fbcc1bbd80e342847de462911897583dc57898ddf4fe3f9d2fe6fb75187b1021ac35c2c10e4dcb3a5cc2b15911e1812b921d79b3e9d1f39d5833c9de929d0d06ac6c9b71bb0caea6ba90cec9f5b3977d83fcd0412289c800703161cf40b7c89740f7fe1f03e226d97a30474f851d402a88cbad3e16de4079f22e0baef28003cd11a8a82b8f489fd9df0c9c713fbc348202e48f3e24bfd4e8094701159a97f35d378c4f926f535a11c251c7372b0bc6b527fded5c4f3de11d6a120bc44f0525858d99ee036aa3062ef140ab6355000098c37c14e167713f485c28ed1be2e35df98fccc84805f15b74c262beb35c9c148656086a540e2b027f491b6e08ba409b070ca0386940c1cace44f2b4e4a81e4d38b404506adc094402b6beb329c24e578844e0b0913398bfa3741f64e371abf3bc30b737e6cdf1da88eae298f859b5d5937d55cd680bda55811f9f24731b4997168de5e896c1dc83032712044ce90294a54a5d703d40ba73523021214e29292fe4217c53ef313c286c0861ad0b424b76606c183cbfb0af1cfe945b0d117e58ad30bde837887171dd11801ec082574f8331e29ca3bd752582cf4e6559644af3808580304f0c2fd5343b69c9807705fc98db600d52c9cee43af5de176495ac7ee9abb7886f31a1ec5ee60321c4096bd7fa513d82d4de573ad6d91fb1dc8a57ca4d24509d20997618879a585f0a06ee639ca66ffa8a78e5fabed09cfc2042f5ab71e2960df79936d1346a4a1631ce44993bcc6fb53bd2efd5770853b081dfa6944879d822abc8984a6bf1d8b4b190663a001dfbb4dbd2379ec5c21a0b1309713c0a63ce8e0db91079c46525d0f27434e3be2dd52b9dbac8d9dbc5a0dd613d5a3fbf8bd279679fb019ba519fc7704766bc44d997eb98efce58bf02a2481eb83ddd23259b14a9a92bcfa0af23e4739264df77238e2c25a0a26c3fb564b2a6aafdbb514917559c7376c07c62c5aa3da013b9a001b7f19b0db3e6d8fc0727cfcd26be6929f721f204e40dbddfa2ffa45797b08f870f6a3f0ca2738507d98be8a80c2ffe0b8a07cfd80dabbb48b9b9ff9b7eb8ef113973307e8e2c5a50f261097d54c0e435f6418148c733281cc31bfc9ea53484ead400d4462927cc812c5bf2aa664bee315ee6b409900cc7e71baa640079768b7aeed6f41f22efed0792493dba054f7e43088ee9332c1887af7d4e2f5edb9511294f70c4a1f4ff82e3b5fdd0bb3666d92fb93b65590c7b068cfa378dfe5e653f8be329e0f86d60775bbe4fb665c6a20be4d0c995f0e1fa060d1328802fb0846baaaa88fc736bc6d73986c94f9234ec521ddf2fd9fc32aa851b38adcb575cca8b61bede1e81bc531ef2f194972bd712e8a3b807bda5175799b2f9693261316525a824f99b7b0bb95483213ad8c153ed0da04c353399c26f23cf90aaa2c0da4db07c1272c4db047acb8e39636a9dc0d61e5d2bb3b4ce8321146e823a6692c3609fc0b23ad060024c7c8301d99a05f7c418fd2202aeb1724ad969fa5ac66761b1a4e0dc0bdca8d5133f2a5275c4f6fa6362f428a18149a8e551fd49a90263665d82c88363c201e451f79906f5047ecdd1409f959c288f19a5170cd15a8265ae0e43a8c27f52811da31f5a4292ae01acb9e990e333976597e3324061ae3c258069a8bc1696b102014b27dc607222621c7c2c37d3a0185c555903dfcd69c12cf7768ca6643a59887417ff0cd9bf90fe8d3cdf14ae074e56cec4eabc51e723c51a35008124d0a4234a4240003701b3ea2d9639847f2b468a3324650f5a537071f70f05c3ade0bb071beb12c6cb7ca73b24bf4d5e6f4910a8225e62eafe155730cede643cd362247d42b5a200e23f7b6fe46492f911b01f910c05456c0b210c0e697e4a4ad432094599e1268a7088cc5ba9a6ef48b039e418ae512d86e96e86e7e50608d3bda774984e2faa22e2703fb2d1991c2a48c4da7b80dc28d722d83c3369a57ebd8a96c5d88deb65e40812872d43cdbc2707d0f70c67063f06c878010e11b7bb58f863cf545b81818dcb14d6171edb7e4a2f48ebc81d9d1113d95ac78be7aa964b53b0630e680307c42bc2c1fefe16b8e0e748685d9719368dd1b7ae53774e14bc11cb22e6152ceff88ec343e56462344d79785e60bad0a081ff058caac14814e8596b977c7f924260b502170e58d0a3c387b50861e4c615735f69da69301e48159cc60fb238ee2b378e51c2537781bc32d492a0f57aed8e12f296e20da5a001e9094b0e312dec8d0bcba0a60a0efe6044ad3a94553266559d86c1a3a8e4b451fc065aa24995ae40c5ee381ed82a580d983d865d83b9997bdd02c570f0a9879d1158ec059c0010569831e78eb3c482a77f2c1c8fcf227f0d7128a0ac460fa1c634e4e1d84cea337ae915392ca23d252d320cb611511d0c9febd06795c54e744f2c00227959a67029f340f8e8bc51837478f2c4aa5503a03774e03926419530cc3c372fb8249a7a2e5370b22cef2110712c2ba151dd6279a91a8386cbb435bd9392f22c508304b79fc0ee10b5497b4a28594bb697f01c4caedb62fc3f3be271b1c092dab0a4b8a3d9ef890bae7284a0a562b115c5ae8d86bb508878059ab170ac245ac291c1406a79c1edc7d233d20298fba9837868a42848540f6ebd8a06b04a1e91b07f4900a619d8012c4d1145edad88f1c07d49214dc5b75b516aff81fb237d2849890b5b3a711bc7c661e9635d44cb550ea8b883289ae737bcdc871e76dce438d2c415080d4eb8841c9ea3d72ba0d5a493f81574e256bffa7ae6848ac0e75aa0e0248ff4a28af4b49396290600a29a8dc88f4f47ebe2cfe06a2e2049a02f4e45dc4bb1801dc005347cb83ee469e32bd301f2144978a5a9018a0b6494e7cb6bc4918437cc82fdbde1139989cf7856ffa11e400901b009f45d150d020f5e74c15a2fd1a4f830e650225c31604b74afe17d662a568173590ba710edf45edd4769a5f42a709901a0d9132789c77a19069ae3f5e19aa37ab47cb5ee3a3047a6c36059a88e5012621737dd004639218ebb134c45bcf09da211e6dd592972bf3f44894be9ce4607014e4536dfb343898762436cc712947905cd7e8e725151bad273cc7e134bb53544855bd903e19b4e200cfbe4527594d5733937b02e171e311b2e2cdb5bc0989af370095f9cd03221dd0bbbc9933ac862f377dda023ebbe4d1e940875814da93074d84437018cad2abc1a484a26a187d5c126c2fdfe460b46c89976b02857e086aea2e61fba5eed0e4c4c0f1e843524aad3723f5d55180701bb94b87229e9753fee6d56b03e8966697e69b605b941574ecf0a733941d86861c16cf935a2a514f88ef40a870088789e811a43462a81e5c85208021086f6ca5fda9837051ecf0a337cb68ea3c136762b654279c8c54e590041f968e371b802038e36d8c5df3570141671b5cfeadbaffd7fb269b428db56d31174064b119508b971e7917ce6fb5497195a05ce5ac8975bdc266732b280638fe83968a65c7e88e62e97e0a9a17fa728824ca35084c55d88da80d7872caa71d091774707b2a8d3e93a2292db0151f5734402f0008db4a08b7c2d8be43859c006a62f0e7fb6537f6ac8fc43d09b88f122d7c5432d06460b30c2001e340fbb4a0f323c02b8b412a447181a116844e1e24e11887971cfba6638ed6d1bb13062e85f8623e6f6936415eea6fd264d9a8e3551712ef325d48560567a96c6ffe962d00f5a059d7bf33da7fe2279eeebde8433b00ad5f810d7fb625e6b8ff205ecc732434406f51a5b86a62a33b3c35a974df0d0e128f47e5d49c0d2b856718bc9a30451d148c5f51e77425fd6a1c37b0d797cd6cc029a8ddedc020518f7c2c102a34a8b416dd85aa7bfeeea400ec3eb47405c0d611547925780f6a67cf6ec26464b70d8927a20d1078cdc01909d1be1d52a77707355b61ade20b1177861d8ccd01c435d3910b85906c78e6879c02288d5921ee560d7906f18223ac797160110207082dbf5ba5faa0203332d3eac7534ef46162a25742a440b13a882838b091e2ef1eaa0ec1c6286eb15f18c57b346dcb058d93a085ca04d7b24460d148395efeb08993bb5a67c800752d4f2067a00798f67453a921e5672101ac6f0b3dcc15e6cbd97f3dbfefbe76e5e2768d2272ce7782ed67188bb5158f769771b323e4fe838e566a508e3f8bdc84d1475b449da6266a665c098e195ed38c7d54408c954e59b78ae1c0f2528d779380f6a502cac503f89c02f5d1f46a8c56867e5526b0e604dbc1a2195c980d61831ff9831b8647e20130c5f3c900259e15d1da5695fc89aa2a0b1f3302c3adb87f068f868465af72d2c264a28dea23538cbfdacae66038d525c9e6f5b4b1dcae87ae93635308431adb0f887b8494c650b89f5b33d25ce5f5604dcd87cfc4448ec077ce6a152d0c954489c8be4909575b0052fd516c5305cdd9e01d9294878a4e01ed1cc185dcd43f318c79cbce8d09f47e57e1da7fb1741035de0dd0e2f4fe8dcc184da5b4977dcb84f94bf6e3c5c1ad2850e413d075c1f59b376cb0bf9c3ba1aad0fb4870945c70a4f376f67e24b04a640d0c4504fe5f13a292a32e54df1e396046768c641766cd5bff9ba508fec52e54ae1b05a46090004a69995b01d1a754d3c2e4a5b686f413b5a92e2b62130f37f1dff12d29e9861366a1d379a08bcafe3b7665457c56508e642bce2c202256dcf200cd7488f3348fddfd88529b0ab754fa9dc12a5b545355fbfbc65dd206635f5f44009a1a6a4bfb99b0d5990f33dd67207c2f14b220012cebec72616ae02f60420ca6a6b861e9613d4413977f618590e4f5849a82a09657ecb51477076b1826a6861c21755b9e25111417c13aff1d109f3611102f514487b92700d19115c9d0a24593dea658c53a061cdebcc2f93445565d83a1eb2d8fb8e5a300a98af15b30618237416ea8f41902f6f9b496d31e8d6c24cd8f5e9e305e0141dba80c835802e8fd4a86ce0517b2b90ead1103ddf455a75e664aa3c13046eb53eae20d1f0ec2171e531245e571c25da123dc77e1b06063bc2d890c870fb227839556505a418331498820de7f84d0a7eadfc689f63095fcd0a9b96d80e20a96e04d79f109f59daa0dc831b4f31667a84feca68d2c9bcd0ec2df902f0232e05dfd8f80668f0d8863105171586d83e878d3ae9e87562e2e0be0df4a7540bb1f62d22b28975dcb143384c9ffb7051a7377fa848816a1a6165216f299ac9f0eb3c13379a9a65a37c29a08f7b5ca60e703388040ab2e0f9f9edecac72f4450fa95024c13532a6b7679e1444e62fff8a9f4382d198aa1c0e4e7d0913fd01dcaaeacec8411fe98e9772d2690ea211e8733b68e596295fe0bd30851e067f3d5df139d10e04f95182923dbc7a04d6c17de6a5f6c18103cb4ba19d0a5262f85faba3e9aca6cb5fd9b4d3ffb29ab2b45afad0a6d0124b57629d0c0b1e2b71e859fe745e9254dc898a282beed28c409adc68705812561e10ff93b62177f3a71620b2aebec38c32ef21cc0a76591b5d1a22674d002a87203ea46e237119404ed6ce8ae1b39b961bb33f6eea42d498ace063f1a1f2bc32a123d865c1ba36d0234e472b9a5f7bc7d37d40cd10b08742de7d0923ddad89ea3a503b838009acc9561881044293aae5cbbd4a19190f23c064e97eed720669da61f7c0752ac2a2cc7886e6ab17453299409a888059330ee742b6322734b89791f550bb40bb6cd9998ad51508bf2f47e660dc2b3f922d45e58b98c0528ede4515d416b711c7f4a12d30532aab07aed285075441aca0b029060f93b363fdd34e704ff392c5d88ebbdd9c93f34a06842252d65b63b1ec5ae10c3b6d76c35bd25596fe83515d2423c979cb01c199d2c657ffa60acd52b6dbbb5b5cd6a560155c79efee534d6b158c0a41811e292878cb2f01e257b200730a05c943054e2ae1726ab063ea6780f3838782f41d8cae302566cfe669a47ee88af71320e551e06332a6bd73038e08f24f55b0a01425b1a2ef917f3217846ef50b2dfc6ebfbd9f105c66568c5e5c7551da47065e5d659cd92415b739257a668c958701491ec3bb4266a9061dfbe8be448852f25d525debec0316cba2cb325d1fe09dadcbed33122953fed9b0fed4bf6319f810f45f6b1f58a5ab2dee38b6e777161af5b8ea60008d75154d7d7354ecbbb6b7d4de39877797def1affd8b7ed4d9f0fbf43e43c7bfb116b76ac33932fc27d4107fbc987e42fb8597d8c4bf8cb26af6418f2102cb245a9792760bbdecab359e43905034e646a4affada4f844e4536d3c411e9623ab415aee61f215922b004d98c18e71b74ec2cd92d58433287efbb9700ad523cf24aece6b30d8965c4aef6cc41972859d0be6473f5ed05f476295ee252b5ce5fceb6c932d3e2bf695ba16716b8507a87db37545359747b77426a969d7f10f2ca4d06fbc73bd752949be25b6a56f1829087827b2d715ae272b90d5bc20adf6475fe1aaec9cd74790df01e540f8fd3e93ed9441a09eaeb52c73dff7b71b3849b84ff893a0391c9f0085702b11f16aaba8ff0e3604fb50835b140af2a742b352179c89bfc0d4e013a98bc0d816f7d9c93f37b40b68d3b12835b3d1a759f50c8fece6258b5b11e2bf0bd0f9cf160c5d162b51755ee79d26218120c03909aee1633c3757a3eb91cb3a401a387ff8b24c18f6d31f6c92abff1b7969bbc4ad2d5b7d45c2cea1cfa1e622935c00539f6475204b12173b017887401e4be0ae67061c874d90b05495e68ea178adfcd1328ff7c08f01d61e4c389f1efbb1b462ff8e205bfe74f3c75362fdb5626e9f389455ae4caf39b00088fed13b1c3d43644eeb04f070d57e6b620a6c7cfebb6016c0897f4bd7568dc50cf105fbc9311391ed6bc3f9a93467a151c353986e030228e5d69068b9111dec876a91f4afc5c1c13ad3b90537f38bd235e915eb0b85168199f58b4c6474504bc562771f0833b41a632658b5bee28f371ca848f1636b73fd8dbe0fa1bcd66814b7843ed042d6743ebdd707dcdcd39bcb330774a616614f698a01f2617d236e2c8891d4860373f1917d3d4de40dbaa2076d69394033d8dfdb6caf37d1f53a030955cec1be6fc131cbe153cae0df6cc8646e5cf289d96c4e7f07bf035d10702e39742cb724f55299ab3509009c42934188929030682a837e984135e84bb8b08a481a948e63016477d93a377adc2a804cb3278fac40387bd6677205f9b3221b2ae8cbbd43ea3965b58c78be4f09c71ebaffc76e524aff609021074ef9b09a274b7ba62d601d05a50c31869fb23315d6c5d195aeee1171e15d20454eb4da390970222290fe81b0c9c795ab15a48da09ec80edf7067dcd1e488677b3546db280fac43a7d1cf00af8e7ba02538e711329d1623d925bff89b63829990a1e878c38994d687d46700e2417f18d087ea7ea9698c432e3101b16a0a4377a356ff10838e9c358a38ffae21e36865b199a215b9b2332bd7c920603e27367724c6c2df1292a9b13160282cfdda2518838b1098ab036b4f3b0b1a2fedb939fb6f3e4e5f01317da779f0e780538334fca2ea1bac5821f8385ec1f2ec32b19140c1c6b02860fdde082e5e446c2c08060bda3223c2e8b8d5d2648744dc435d2287c97e31d4ecc088fc2ce16bf4c05a8acd1d59071494793b80ee41d44432de6b8480b664df153a8020e6c140d182561b8dff0edae34acd750c18336bf9edbabff981c2ab4ef9b67d6e16ec5975b93575221e1a8054c811da5dda424dcb9a37c873d6d48c7b3c885fb395892390fb84e3a38fa142fe24f0ac0d434ab14c25072d2de9cad4943718fe1b228592bdd69964c789abf7390c69c1842ae08ec325b6422017d5d23bc69484b70815219f3077b966253dcf87cb17250b4ef00c621b25e1f5cd123c30f04a99516a831e3ade53cb3f224cefcb900d5207e26797d4a44844451c0d9b067485f68ac6fcc03db623dc99bd6395cde143f0d2a3744eeb1597435ff1ad5bd2b50e8a5ed591b170b35415414ce271129aabfe8fa9558876ee508f92e94eabcd2d755986d5793dbe36ef83b1117a7264cc4d741aa6135894c5f5cf751d4965fd55e3b2e17060d33f45a91583d9f08278e4adb71e0e26e864e4e079a064d3583d96871cb60053f611c0284eea9bbaae7202df7cb3bb10e8565aa827c05b307209c890f73dcb4ea156dce923d578fa16fd5db779597454264772701fe9e9f858758750102f7da75791a8a1294e206e0658efd6c26e8965652d4892b7514c70ac83f0b998d7024ea34d515ab93f85c82ee17e43d01f5b7c48cb13b687d1ca54b1640141200800a2f56911a8b8aa82853069ddaf66012cc3f6c1f8a340bff67ecccf45bfd6a9f031f6f37f87d6d963e7f2e93c557fd3f7b3b28f4a672c4ea00829584abfacc4efc1c1ff78574e5b02a8bf9ff229bf1e50bcdde0603e3cafdddb374f19a5dbf4cdc7ec994745951d71ef4f39946dedf04b483c4e8d9e39da357bfef40ee0914dafe5369b2ebef0cf18d4535cf0ee296ee3bfc6bbe9040f71cc361bb368b68e1f3b38a5d0f35b357d1f3e7a54792d9b1af5a84f94d3616e5b9c577d42072adf36e96d8ce1f56151f7845991e93cd2a5f023c42e254cad1be990a36396d0200a21116a7afbf10c308dcb202fe115a264f12084b31b32e1988e892556aa14b68c83d657cb9fd74d80fac6266c19b17aeccd579c48551421065f59f90b0eed6e51a8d381e3ebd2a5fac1e93edcc52ba959fe687dd0bf15a62d271691236bfa5614a2d4bd80a91900b91bce59b227ef8b8fbc2bb3c221b1c9d4afe1926d7fcb90a5193671d2c0bc7f0f9fade4a8c742d8e9a8252056f937a771d53cc75ae83824c404fdefb0dd6dd4ba93acb1c6fcce3b7e0770705d6cbf30c9cdd9a02a6158afa4d92043ac6a2b05dae97856fd0008e417d6345036829d8cd37be6322a20bca1cff5ae6fd08c525c8fda31a151fb1661080cdea5858a99f3a5e25552b194d025048441370bfd12bd187aea4f08d8d340512e61a7823723b48770c7fda02cd45101b1c276799180bc375a6910383f93b60e62789c3407e587322ff0258d8c25b5ca3800a59d5d61655c919dc3ec1d2cc3de6da90a483b23c0587dd8060f586c72d02525b67f6d3857eae8e80ff881660026376734314003ea52e3a3654ea6b3c8b0877266d6239421926fbd2d53dd87ab40df0c19e466c623534acfcdd593eb5f72af43b400712ab7799aadb6f6da7e95c97310aa43d9451097f077dd6cb601b6a4724410864696511d90ae181b71b23af5bb7a2d0129da6d43ab643a93748c6768b5f5e91128106a363e5e020342a7661e8455dacf528d5b876b59a711597cd26110a0175b8daecfc4c646b395342debe32b4028e4567b4d7533b4a5bd22a7eb48187b1257b53e49356e85058dbe0f02a1d4fd1508319bf588ad3e4bc77a04565a3e27353784a3469f0752ed1bc76b49bae667e9d6edc955c53ddca6e9bae21e56dd0f4128f38ce76875ebe3238044eb5668d0e0f730a5b9e1bc2ea5d57e226dba3dbbaedd866cb4ae57aec32633d5fd150cb1ddb84aa5b77d4a686f0a071abf1ea6b5b74e579274ed0fcf408150d359f55be735298df6b3274069c3edd1752e7d732bad8f8f808110b3d94fe1aae62789d6edc95522bdede3293020746ab6eef674ad7219d6738b9e31a7cfe01564f314eda535a6bd02c2d161d4a8d18df93344becfbec845f89fd4a3acb91f32e5f7ebdc5e2709f29f0cadf0bc7dfc0759f5707a7bf03fd90a0cd1dfdef8db5bcfff255bd090fee84dd827c9da6ed737f704e010c4e42ec41f7b77e82f320b1ea2d33fc92a70487f7ba7fff4be1f8028cdbe30b103431fbaa0ab7fbd88c6004fb9fd4af5e0c1be917cc85d73fc4163f909542ba244883507167566c96021699e0754e8d9fc0f5edac2c2d4046b4a192a2681e1430b18d11d2454965df7dbebe52e9c90fa5e0de7efa61f5576fc316a36a17166d84f674080348781eae1d840772156751734d28d90cfd8bdc2cc791f874dfd7afcb572f7bfa39b94fefa9aacbeb2e6d8b11fed667f56b07329463e306c5efff263ac4fe08deb47c963970032bb1160c1d422119b9ad2497ed8a37e040fb983ff5af2b1fb7f80bfabed6dc251e13015dd984f99769bbaed1ec83c941d7e880834c29eee585be12f8bab6978e8f5ee0ea216f27e9daff5079901da399756d327c192f6a48365d869880322e18c572370fe3a0f724bf22fb7abc157fefada15473cf55fca1653a56a0464150784821d6fba4b0b0cad77b38815423bde72eaa24b5eb38a67eb1549061309d134405e7b9fd1d8a27af697beebc6dd580c624a21d7acc42a5624a22ce972f16a4a7c9c401b73501a611e07f285f42747c157ae801b8a2de289924794f86779ce4725a62d91aead5948dccbdd752219682119b45bba2d0c6854b04919639c40074ab1907f894662c258b4c6268f2ce49acc42c9cd23a5c674591dcb8bf0476481d205f8dcc8e8d0f3c89f0c2b5fd1619be27f8accff0745c3f9525a6865b10885b359a4d42f1ad2ad821a1a64818cd3109047398d50be4a96e37b6f5e9262853ee67371d1f8fbfa4e4d0ea4c31cfe6bc85dee47fc7439fa2b78ce2803172d9c5b5962665b162b28422cb943cf1b5b9e78b5baef3a517a9a7dfb372b6a7b8685c5ef8fbfbb21e8000d7be14c738ccb66a631ef7584aaaf4860d0740bfe0fc21dde115d4374e8d5da5d58e96d319179a91168d93c79f1d621bae6d1b792bd9f90812053ca4ed4a90502cc2536cb80008f171fddf736df8a7a62986899c8fd7cad17028b0ba10d08dab614602261ae2b98f31d3f4c47d68de2abc3eb6a4656437eca6b205bea11d53e8142ae95be95b3da8cd18ef76ddec7cb851b7622d506a87aee324bf452277d932e4b7f795e41d434ef7058459d3d0eb7ec64ee8d4954ea0c4ac23a448a20d5794dc2c380d9bb3cd28561104a0bffa92c15436b516a7d459e265472d9540c1c849657fea4b25db5f08d377f8b0a1dda891a8f582d5a585bac33aef7026b17b73e43d8e1f540d990ebb9fdaa4399a9aa65fd4b406bef88025aa7a191dd2554c88ab39a93b696307d3656fa01474cdaa63fa00e04ef19ca1d428e60e2daaafec19b7b505fef43dc6731a6c9e3b8bde6953f40b7678c6970b825e62efd77987ac940706b21f5bc8b4e69a19b717a4bfc659f88d2579cf97781dbb9134bb82dd5ff48752606c331234c1a71bf3adb953b59c563fc752e0fb1e3982f83d01845e654fca040e700e69b193ec82fe3e38eb87f456078e88d5390f0b20cdee94b3ec55c343ff114e57efe2fc35ef73a7d62848ff7dd405f6c6b769349df166b12aea1338054674c358903cf8d8b48bf737394b7f744544d2feac34c37e72c9f5a59bc2d557d23962623bc62fd3efb72b6140e3abf81fb865ca7368ed6d46a7a85f224ee5e9f6884aa0d9164302b3f80510360bf169168ec1a5d8b38bcf19e32d84fcea3be09d1bfc7d701b3fb9ed1d0fd27d9286928501bfca543ef61ed20a1d4bb7631c925b9ac320c5830d2cd81df5f8e8e0bedbcee622a6ffd305a70de82a53b876859b3abebc5c901de69fea666d7e609a0891b7ff40f467483b87bd967f0c6cdab30795e5d715d559c9fb8fd95b789651ab5318a1b92cdd0db88b63736c3f12e009631799c125d08ea60d12ea03e806a438a3557d2fecc8dd28524555f863638676a8df56ec46e602e7122d517ab4cc876155f1fd07a70f50f71cf09a230f5c8864f3f8cd2325a822734953e5bd85aa3ed48d4772516d543e691a7c759ffbbc39d0375e4972e4a8173d7edb990a66e54fc1212888ba79c1581d7bd47e255084917dbf56f8d26058f929534ffb48ac8c558bfa9a8b9db2722c52df3085e1ac2a87660af55c4d5685d8c849c8634ea0cffda4d91ee1674e2018cab89a554a6f8a7d974ecb45ac30513631651af6660f9f45c7b1919bdcbe29fe62980ea659c28e58ef0f6440d2a59b764c30901cbf4afa9d72b9ed69d275310f02fecc99548619ba50de5d1252ceae54035be7437774dbeb7799901171b54ad0d6540098b1667e450fff2ab2e125998ee843e44e9a6ccbaf69aa42a7108ca0ad3db02fd1ce0ee376ed3d0300b7fcb421f11af3330032b4d9a7f22415f3cfc5761776e880566d7ebb32956d0d9a33534d1c3e326b9faa744da12c1a491fcaa50fb5271250a65ea70eb7a5d67523797dc0ac05b7593602a46634c29781b6325e36949c508e8af3e76d84f534a897ab4ec3c124abaa0e367cdf1d06b97780efac5528e477e88ba1b87ff8cc8901babf44e0b19d6f2f0e551212d12a7c995638ed8f86457e555586b1d89ded3506731853815a27fe195ab9dd25788de93121aeed1eb4bf8172ee91990d8b7c9b3dcc48e6ae6456b68386e3c91761d6bd0d43371515b4134bd8a59886633ffac12576c5f3a09d7424de3ffbbbf4793efc90446aaf3684ce09a50e73430aab60a5e6b588c99da6fbe825c7c9ff45449df600b20bf77ee9d039497d61e2d8ab6ed6ba045828635d4907ec5c7f580701c3049b80284817bcca4506eb12cc7b54e97e483c21ebacd67e2ca1b565e119d49c6e84813ffe9da21faddc3c4099a151cbc04f76f22472703e6ec03f218c3e5722c66d3e0988b2f49108a13f32f5445de7e68b10373eba433ddda86816c6bf2acdd40bc07d9cc31f4fb93e4f2c4c0c41d57daaa55b40b8eda685bfa3be43ef755d875e4150870f48268eeffa84e9f725ac38360fe6c036d711cd0d67cbf85522a2c3788fa84d802e485ecf7b241858c48097f055432227d19ad9b1d8a0046ff16f668c50a9961e4d69fe24f2eb0f0d8a215c99e104c785c4f26970e14a788c8ae84f3b3cf111f016610b17805e6bfc7509dbe5111a3f69f7281235e1e91ec8acd47d273ceb0b05740cde61c2c8120f0f110808bd24ac59d11dc3821aca83849cbf868118bf0d7d3f98633f4a407cc4ed7a43d3ead57bdaff4eb2e5bfeb932fba6af2f7bdd0bd4c60deb887a738fcc0dca647b4959d1ec76ed97f1e0b72edd5a63924e0119a1e0bda7706e1122d0d72c3b7e0802876cfca8714a0dd5fde04bdc655a8b8a984e063bb256ea33c6caf8017a2d3b6193a868f6494b506c944c51740c6e1fbc69be9c859daf3f16d2584e374f35fe6b8521828f6023f939c68842198291ec47d82d13c9355a837cb49d75475a6af0c81b1bdeb81c42ddd4b186ccea18a89ee699bf8c0bf77c626501dadd9e59c4ed5aa4d9b03b8e89121bc67dd8dd84ba0f3c18014b75d6a7d5f0eb0981546063bceb4fce36e1d4a869a4d35e10d9cf3b03a7ffce7e8dd94c45f83688e1fe1a4f8f0b3712865e2ebf17064cdc3dec5709d3a1a1b2b2426f4846fe4c19e7791b9b3116a2cdc3cd84cafc528a3bdd167a63b372f9721a46aef15663c7e7615d6023ec6f3a368c1c24661a128d0fb5f5ef0a34fb7a68339d0ad5a78bd3a1fcf0561291ada4fd1269709e02076abe9eb848fffce711b73ddd557f01aab18e773dd45825174035165107bdaba788abae04bd3b2bd56fe1b4107deff3e2e1eea6bfbbfac25e1a277c02d4eaa3f9788a02750468e6b09a77083a6a047e7945c50f979a82f21c49b4c537359682549599251ce618b011554411cfb1b244d6980da2a69a45ef3d1c0a708003e96e4de7e4796bc52ab1ea4a2104a50955d5cb989469db0f2d83230a7024c2be5108e72a04fdeefeddf883ebd6abbd52f757d6d7f25e51b7bf181ed348a838d86c4a54d208a2944326018cbb01fa3b254459404c31930e92f708f42ca7254892a7b48a3d650cda9c609b016bd8103ecf350f35795247f6966aa65ff1929d68ec07e65df15ee9a609331e46676e78508e2bf29a6564abb910a462d88c01fb43d329d436d964efbda59432c9e20370049f04f603021aca40426d32bede257ec8f48ab60a81aa4157d2ccdd0d10cb4ceff566b5e6b9905716cad83dc0e0d21ad9839858a2bf436640a637cf6a0d93600bf996dbeb02ac4405742d234975e5402412c50464504480cc5a6b2d50ad592f7119888307d50e90fb8e186480ec430681206dc82fa0404005f88024401e12db5af08548ab2e0d13bae60908b556fd839229dfe8960a7c7001103ac0554bca21df9c3dafcec16bb797dd25d28a446b06b6edec1b570f6cb01561db85a264ebe11066b6b62052a135b97a259feab4d43c2500fec1ed5e85cc64ece02c6b00aaf7822ea2d60a921c3292946f690ae2fa976908fae1af59e2065204c1592e69e41bf8a0830efa0c04414b53d15e10ec85e400f2e74852d8735fb200638c31c618037170dbf75a7b814a24510014cc8081174a5a59df2f94958562c837bfcdca0ae2b6c13718d61e5435e811fdb7a1efa5ea1544b523093b8ec837f06df50ac2da0dd5a94e6bf7f42fcdda06e1738c3fecded841f7f97dd8bf8afdd6b63e0bafab9318804c6f05d885dc640d35087f4023e4a96e8bea3178aadb92915dc8f549be799341ac576f1200f9067ead20da0b05d666da4276a8d6acd76acd0a69c9e550adb5bbde0cb97a45412cd19f33fdc412fd3fd95620529f8c2485c9183e02a86660cba50c456c2e324f7568bc7ee8a90e0dd5d3f184f74563165169108d8038d3695175104559a64e3d3104aad72b8ba73d05b22003183ef5b61d54b7ee8d2558fcf55bab5bc763071b209ff644d7eb4ff5c1edd55adbc482f6f5c8ca245f5a85aaf20c8492db6fa05fcf17935c2298e905bfc51f13f4afd3a00dd7e96f28d17fc90bbe4978d0cafdb70bbec1bf8086d000742f19e47311155ffb915f4692aa640c1f416b0637f0bb56514abdec81d8b5efaed59a50967cabd5a8b5f65e8bb3d50bf16624297b9d00e2aca621f25497060a83270106d5da750e252e3b10870aa2faad59c1187b4c53d1df1ec473ab1848ba3456df34aae3f27a3a5692b41949aa5a37d1dfe51ef770a5b49a91a4aec7f01152d891a4c09a81e79e974b39c8a3217646926a135da29f66fa095d095d39096146bfa4f0252a84995013dc2b70184c82de0a21279e8cb434835e07fefab58d2ff83cd208ff256f69895c8b73a5dd80fedeea1863bf98620dbe1066d62a5fb71a84e2e4b6d6f6f5be77f6445f3fb982f06eb55ab93a7decb5d6ea4454441a7433dc5a9b0999c94f240a29c9ed336befe7e16bab9610bf21e857129156db7d868b16d2ebce84fd6df6f5ccd6d75ab5745a37bc445aa5f840d2e5caaa2b57c78b935c560a4ecef4c89a5241770296d41a158ebc11d3e58c1126a9ac5c162e86317cabdd2ed06d696eadc5350bb0a4990293142142c40319c4636a6510ac54e30585cb26c34c149d39c296d284174a2d28a6aeea6f6e53a273e46f6559eae810512acb058cd1a93107690e4ec69c11c2847861533170d812dc0d9382b3615c706594b892c2bc4018be5e589a7d61cd10bfccc890993ab2b9954b1232ee4165c303abb284bd345d1b52eeac031b9351c360e0c8b026187276883aaef7f585f565c65a7bf157d8979a6fe6799ef7816036c090c2300c65229810b01e198c0aac0a98979f9f9f9f9cc1bcc0d0808dc1d0a04183860a464adb86e9086b12755f3f92bea270412878aafb52c266cd1bdb13dc8604dc068f0fdc26076e03f5c2060449f925c3502e99626392e304cb41222748154521ded49299941997b032615c1efeb4441b95af1f5f510f546b12f8baf1851bfb1b18f65427078d9c3272ba7cfbac922410c3e8cc419a830b81ad6a8a4d08d5234629cf17374ecc4c098788e001cdd5e71b449f398b111b3e18dd8782e0504dd0af510f35eaa1c120d9c7212888839d7d08b3f73c030db924914762cba5ab0a98fc817cab0501790909faf1d5f38826623fbdb42bab6bd745064806441b946c6b926f05b8304010e95714ba2e23d6b69567344457ab37f26c9c2ffade888271f6edb55b7c5104dec8fb69916948445addaf83f5da10883626b97d66abb61f41a5add65a35bcf55aed07272c6a42d040c66b3d14eb060b55cee6d14d74535a67ae0d9493ba99727572907b01038f4a8e474e890c3b27d8f9e5ac9c2470b016c02a1255c74a8f330e948f25a7184e30e70372755e9c7abaebca19811c97ad3337766e39c99cb95c97b37339b293f8e4a29c5f7250289e3a6387c971a08d0b4d6294f92145eca90d1593932cd725b40e387dd4545184349533399aa74d2873684ecac6022f098a4e812125e5f4713a97b301b90cb9761246bfb8fa044aa795a8988db38d20c06a03a60db927670b66fa85b3079133b73586926918b4502f37627a085503e6dc71622585c8751634e700725761de50aede42d784625f504c60319090ece82221e754e46c3a676ec9d94072d4ca996b1c58ce3267063406addd99cb79d13bfd8467860a678e3e69ab14ec60da0585734c379d39386067aeb3c6ce386797e91044a95c600024272dcc7d9d09c869c9d19d9cce33078637540addd3317427fdd24b754c8f8c335752acb042a72e1b3bba8a9e51e3e53c72fe6893739c233820c849bb7214a4f172774e30c7845ea15927f5b2878d99d30590294cce496cce49ab206970d234f77e3afe63932729cca163e3d52442209783a2d12ed66439c3a8983387651627eacc39e1ce38556270985c4c9933c2c3f19ee73645de9b31c2db21a7458d156c4128141b9053a4ae9433945983f554b726ca8f4adaaf9a286974e50d3b1998e2844c580dd6a8e60c53995b03e4c7a7ba354ed5b6ad55e55936954d69aadcbb01351580dd76c0c2097df29708e3ae569e7a74f0a07a49f5d587a27c78fe8d627d6dcf6f50ad559f40b68e1b9344d7f189ebd80357670f63a9b57660bdbaadb492ade5d75dbcddd7fb3a514731c1370dc4175f4cded103f286ffda296289fef60c3654d043105c41677fbdd28a0278b4c88ee8e08c5b688a02ee9ab01cd1d9d938c106d49c393638f8032fbabaec50129ba366840d97bcdd7a20fb74c794f5796a58d1c082038569c9c834e5851bcc0404000e2822c606cc489a1f7242aaa75b421213d3d10c0b4e06a61647f7de3434dc5c11588d45dd71fa121287ea6a6c097735c2d0b0b9710fda3181799fa73ba62a7ff35274022956a8844a035a98e244513903c74992375e5ebba5b1dd52938d4d8804a703e378e06c06e2ca1a720e8fe07078876b4ab271ed70562f80a73bdc1010bced374afd5a15d501df5ffdf12561bb9ba4fd2c6e5737698ea041a3956fb91a5df022b0d0a0dbc988b3938164cb1af2435503638cf1ed70ea94f1c0b5f8763392703632bb195ffee7e96ec694a4322cd8c6d8c6ec94bcc031afafcea12d50e37e754aeb0fdfda1fa291ad1be991d65a6dd0c7ba881abe25e9102e5bbb530af3e2d39d52162b0fa8c96262430718205be10a6d90feb651f29eee94aadceeeeeeeeeea63a6a8d3e25bbd80a6206d415a8167d6fbd679f375a073fafe14802246bed4d4713f5ad8bdfccd2ec539b01032e7a3cdd291d79513692189293c3d184b54e7a60146cf28215db7bdb12b5c57e6ba7b576f3a8607baddd293d398db0d65a6bed968c9fee9470947894722b28c9f091f7fcc5bb24342f7bba4b129382dbb2dc005b0ecaa15d1294b74f77494efe56ba90e46fa5ed04a932861f729ecca35c799524c3b694d4428d18d51b130757a9848c102fb61956d23ce14155fa50a19c03048a470a37cc183196cc3c315e64b1c3244e0a6aca2e664a295faeb0983daeecb460735ac1dc09f92ac17684a3ac8241030e0ca43978ca3a5f43d8985c593274e52e0b10296617931f53259714be4c305fd0b10389a9dc428a619a90472aac44a16b4c2b29cc912d245009d3c47603898985c8181fb67387c9e6a849c99152a9678f39858e0dca4d0b68ca27634aac2e495e306f58915162a351c47c8342c906aadc72be98612be1858b72471d17e0b84893a38c090396c9c295f20428659e25a610236282bc4082798e50da71812bb5b838ba72078a9c2f6bcca918cc2c30b61830d8784429a5aa4c24165018d2a3470c39b0d43099762d605c19b3f5009b6a23e74c29b6339b6831974c797281c891b284a812cc092f9c6cb83d364cab3d493ef4849993c5ab44b265961163eee11255a58472528a49a2470acc0fb127734dce84a1474639a6a785ad8598e9e4cd132e3364a47809b3624679526651c551c13403a424c3c336c20d332acf525925cf0b5b0e3b5de2984e6a82982959f8f294432c5e7278651aa932674c955ea24a273e969e909c34c696cc2263472ae0090266f2e82acf6cd99ec6bcf0a2bb6233e1aa6c5255de99ba1365d2f16112792a879c65f02cd5c073545ae1319bc06c4d5d65922daf315abc9463ae985e57260955361c53e59e28b3ca8789e7a954e1b4b9b8b364cbdd392aade03901ccacd2d5c25679648cb98217dc9512cd559baa335368a24c2c1f2d9e6c36ce387696ca37768ecc1c1e9b0e302a5d495b25d718938917b3ce95d2cd559b2a38536ba24c2b3ecaaea71a67589d251b8c3a475478cc12c04c2e5d2590ad126c8c69c38ba974a5c85549a76aca1495a812061f604fa69bd34c23b654fe103b3212ed9e5bdae798835aabe5bf0736509d12580d3a005aa7510fd5ab530fd53fccc822ec065f39f8aa0297b556bbc90e94be1d010d61bd7a394443d0c7b7471b4c82bcbae184e71774a72d4f773ad63c039eee743071acf7a7bb1d475ebc333be219fe661eed5e0ad0f71cf44b43d06f4f71ab8ba8200e7aef44fdea462060f1f445d4149e57cfbda741f6e2f0edba672f066b2de8b1cc2fedfb482b0b41ecd73dff2ee897e679d05f32c85aaa3abbbf5eabfcf5ddd31a11cf9a7641152b8a3eeb4645df5b3ca2c0d6abd75eff76704c7167753c71ab4822530fedf4b675f2b9f7f50718d93a55cad741bfde3444e8177c9987b4a29f6fda4d067afd79f8b6980e281db86ff7c6beddf37afa2c76fcf8023cdded40fa158d45b0bd968d24ba7be620f8854dde46bf79ee5303123978947a18fda3c93c9016f41f088e34702cd16e5d846d1c1a5ddc0dfa6d44e1b9d7f5236ab7fe91e2877b3cd1ee919e75fa91e8d0e4adc353a71f60e4a29f6feaa1dbc11c93173d0791a72f6281c23d7d1c632ff3d0739079d143bff9f82d8721a9211465b4998fa1e8216de6e38c06bdcc43da8d05d8e1cdfb79a3fb335f711f03cd380061fc83431f1f692038a290b948fed06e78863d4f45d1087e74a3eb9ee823f369998ba3e8230d4d84a4e83ea2288e331765b4cf7de8480b7a198dbacf38862842b0d6c21926c70e2e7bc1040791a7cfe28b3ace53fc2376a03416df23099ae74d54bdfd03699edfebb74a3159d46f9d08457bb56c70407d88a7bb11b27ee714e694f51d3aa8e8dbe79ed7cfbb794ec7122568d1a2858bf7c8d9075ceea7ee7d14d3a0ef403d50f77639afbf4ec35aefb8c147269bb94fb563079ecf3ae4b16d588915fd9f7f7091653ec296ff5c7683cc5ff1861ddc121b464a650ecedce83ea52e8e764421238dfa3b45ff8cbcb5254bb47b200d6560fd3c046927bc15fdb3b65cd7ed05afcfb07b8e6d4561dd5e9a11ee6641b463ef89e0f5d89b4c1396af1e3279bb3b897cf5d0c51fd0fb1b4d84dd32df50d44fdde87e7bd1cf37e9e2471a759346fd94bc591abd61577122bf08d543ff42af5eff0b7d457fe8962422896827784abb854e43af2e86e058f4f32250eae1665358f2d63145f5108734a3fefa3d82e486131f1149547d453f2eeabf41441a74fdc3f5757077425d10cc65592b55dcbf95290ef04d0e0de0c38d6cade592df62aa00a7d4baf776f616c4758f8487e997a2c5ea15df4a5e3a14f68d1eb0f803807e1d743c9e188bdaa81a358aea449804bd2c22ad208aaedf0bfe54500687d935cdb94d5d1f3edd35698979156a674349d3111b53029023a804cc983162e8146d800093160000180c08060422912446a250dba90f1480076ba22a604026a74a0261280a83180662188461000040300060100041188ac11854fc696ae111e10cd10d4adfbc73855d6c5157cacdaeffab8fd83d5225acdcdc68de077071832af5d2cdfabc90ca8e2f7f8c1279d154a6e33d9d7558cb590c132fc61a6a10901aa598ce0cc1f20c0ccb2640a9b6728ea42ba70bcbbf03fe651d285140cc105c091dacb07029941d5b2f1e33e25c8b669a1dfc76c6e6ac9840555cf00274f7292556e0b781ee185bca54e5e5559c2475ee2120161b6c648dd381deb760b75ee8d7b9eb6ad3e9a0d46f6f4b2f1cdee79429846ae5f5beaf9532df5bc74d7d3181fd89326ed2c0238d99ba2300cf3b1c8729d8563f61c925b8630918259a2b756a1069717ea2177a486599dad36d5b4743f8d45b02eccf814f269d4916990b8615c0150c1805a6a9cbe9367557b336dc615b3773ee07ec408d282987cdd98a249f89508a3bed15e2d030f1b7c65196289326d671f83f4c878ac08855dd3d15145450e449dcc2e46af93e83280e881ac1020d2cc3a45c96ef1714c1c9b4ce3e988238eb9141308294b8486afc40e39761217f810a6ce77e0eb6bd62d73bb0bb5e9de13343551cfaf0293203fc8ed9a3d3179c0fceae403a7d1ed6aba382889dd9c365da81c119667005bb2a6264678abb08f9c4f86c8377f47c0c10759f5adbf434f2d7a12ac4ba24b2c88528832468a6dd6d7603127a32bc643541a8053100f150193110540072110aa43d4d604e40eb86f280a677056eea8d98a8091b66bf68ac3d5bbfce958c2bc68ddf448399cb0e2736b27cbf2c090e7c3447f81609b8fa5236dd012b3b2e7092ec10984d1d100d3e4cbdfacc0a81f6b55b82fa622ad9fc8283971daacc47ac8a602cd2167804472ce35b200b78f860d56d07c8bf43cc5c36226dfe2e8603a3e007e1fd3ddf6f00b8a51595b6d6bcc8f6586c39f7f950014c6acf1d7ee5dfc5b21e7639f2faca85c490d85232a757185e1379443f4766b451b3978dcf28afe121259f5a428cfb9b8a05fd9dfa241b6f91df05bff4a848e24d692ed71484f1d701dbb6240c88174a71a434aad0b97aa508af2a69839902773466c15aa40a7e8ca38ec26fb4e9a88d3ef3543582d0950342440f1d07de537c36772a18692039a61e08724eca09b2e20a6bfe040f4c0cd8cc82f0e68cb5b8cb10f300857a0de483f3e358fafb7ca02f03c68657034be02aaf97dc25cbe11021142143908d6ff1517bbb0380726303058f17ea7a30baba110dafee98c9a78d0289b6ab0c425e5b131539ea8010898a0ccfda467de2acc708de1b9305bed8fee4859cc9b998872d7c3d40427dc96ccc69cd5f37ea15ab0c19ba41203c47439b7dca07b3e5849fd63221580870aa7f1b82d297dd3be103b97117fe3305da99aaa26500d855c84a1bd93cf9264cf7434dea47152942bc4684482632cc0d2a8da1d03804eb8638036b6985d590f6dc058877b64e9487a434499188dbbc8fcb1a8e226da167e70e075fbdf7c048916f998a9f18a96f32da0bf692e218396ae83dc27fa11a79077bb774e01c0526fdeb10ac2d3c9d01d230d23de224ab256f81d95cae2704eb805268241aef58b49834cfce937034b68750c284ef428d3655ebf60466ff44253edeae876ef04a7308533c65f3a2191604fe675815ef8ad254ae12403751020103a396798a16f409de6c177c113fb874b652893761f5aa8c06d4372431fc9c64b4394024a02263f7e842c4a28b36ec22ea43c877f561526c6d4223e0ccaaf6eab4b6d5a12e11af82674ebcdb3e5889b5ee4eb65b828ceb40c77c219825f6613dcff4ea2a0e0d16d1664db8be1aac149300db70f56bd3b7d8406a156b11107e30d626d10ad5fbb75bcca7bcd41f140fb3421d85e5103ea54945bd62d5749a7a8423c7360205160497a5d01cf00bbbb96cf0a03812aefa0931a6d6917321ea4591dd0b0511ecbff0c3d2f7b4c230ffb2ffff626608b94c6fa52a698bdb39feb55787a42fef2ae9f537adb7d501c308a5bdb9b989a9fe6b57f3b49ae23be0e1cf1cb01ddfce3921218a2dc91280dbd7b89357640a411a0b9f52a181364e7790298afa9213bde4ea2c53f71d4bec974d3e234dc72a791404ec71b1136e8c7613bdad0a6905f138d70b201d85633374c3f9731ef882e7a96f0939c5238d25c881cd8050ea74cf1a34c6df452c976e59fd4e40d99066c1ae90d6dd1352bc401759f0e42a8abf4adf5b6a0631ad27b030c6507a22a05c8971705026832d817aac4ea137775eebf5199d576358929b989bd6673f3287903d8509ff64299b3ef273ef634a9e55c20e7dc0bc7199779071513d208746ea4342d61b51297f052a79c589f141f6b48fb5885a62609d4de4aba808de60b2bea5497b2599df07bd949890766321d1fd058489cf8c6007b19694f57d25fcdb1a1742cb12875d87a381db63700d6f236b9dc7a2cee5c5e7f93ff13bb92852ce48c39ae53f3c1440ce67f81a7744082950d5d7e2a51a26fc946437189e0e40de978a6ab75ee422d02036efbb1b301b35b071867907547f39288f674ea7a324062ae8cd21a2f510d52a46d6ffa945b3991c109be2ec2d87bf52471c8f25b4c44964ac3864e66c12b6cc4b21198f8ddf31b33da55434e883a41ac67fa30a872049cd9cd3d8845b4de12aa4f25ff08c414f9e142d4bf7ccb32ec6b4830a392ee26f58b33cfd46426017271918797bed8d8f4bdd09569ce95cd8224c843345b67e4d1bc6643d39e1813bfeb1d249249c56e445d599ba67895a07c43fa7164723078dd1d15c1e9a6bdb2759666c06d0a48b9cd36ebcc7aaf844dbe2783cbcbaf3826f36b7bd63331829a9e5a261044adf67f1cc81a01331cc06ee82b106540203e234cc3e20d36c6c69d5ac98c930b87f633efcf8945b08d4a0c9a8a43c37d30eb00a4dbd7b61a925a5ac77bd835c4cd7e3ed79bf85bafc44ec9d609af201db1c6bccc60ce906ad489d9e9674a526cab6d1c23321b4c097054f62f65244e6c0c7b559d85a45a8030ea72505a4fdb5ad856177eaa9005d99a8b42a9885af4d202eb0bd029488a5019b0f31abac32b9376389d784f8d4375dec91a61cba3fda995a65e3d32adacb5ad33e1819f843c288e2cbc0dda463c69b0653cd530da60a1c59792b1ecf899bfa7a9d8fedbca79893e047a31e925855e70ef875be3d1eb4294eefcc6d1b38b092d854eb75036bc24bb5475a066ae517b0c869eb91caa8a24442f68899ac572c3a81c16eb4921d276afb4ce383f741f8086f2210e3f8797928702898b743a53c5b4d59d8141c420e221db033f651634ecf23cd438eddd1b3d9517f1ad3301b7d514b68d7876e6fb230092a1b5eab1f8c9dc942364eee66e1732b188514d13dfde661ae15713916075a818e245c694e46fbad8a73e80f074caee4ec23398a30f83b0e76731f2524a8e1893fbbb38cee05a0f159ff844817bb5e22801c6eb222bdd7b528476a6c1920008cdabace58c39f5035be4f5afcd1a294a801a6f74d42b20aea1440aad492cfe492a60c503f4eff54473b9a1bc1aededc5249cdc72c7d5bfa1440ab67ca8f334ea48c93f7616a9d4b9514357a2e55b32c4f63e698d22d754b10bfb81c97966f138222445ae6959923db6693ccd474dfa64767cdc863f20f2cd1682b1a82f03e652a9c5f080e660ff75e4549610143e1e35dfa75d5bdb1c1bd982873057734dbb6530894b52e6c9912c8b9d45182d89d03208974d0b8749a1099cd4a3c3317a5c8bed30eebaedb7dac9ef639f070642bd6013df7b5cd1e3b71685bb1297cc5853610912173779da50f3f5dc400d1b30f55208ef98e7e401fc5044421fefff76913d8779e11e93bfa38059a96cb755ef7878214bfa9d04526be9866ec0d1c136fdad2da0d20b60e4d5c5d73f35dd8684354afb2b4a44994f63846f3a0d3b5222caa64010772638ce33f271a7f03b649bd8ae339b5a2c18fa4f87398839c87ec7cb41dcda1fece1a80ef23c340593706486b07b1e18d80f827ceda83351477e8ed76d2375135df7626abda085130034f22880e054d6f84f18528d81c5adb32cd85275d11758c30ae049c7225ee1e0311d04db57dd4af396edd1bbd36be9ed649f12c82e1065393afe5f314c8db69cc2b4f8811ca4e63115843018ebdd64a6879c86fd4db45b5e452dd8c3b58490081cd7b08c9d02482c9c20c3d9bcdd15723bdef419732b5c417dbb7f9f63d471a287a80b8563e2c19692e596e5038abe631affae8b8866e02085530f33dc65ef6031ba69c318ee631cbc0515c723d82113835ef1d998c264b4909698caf265a53630897a2a495c5c716d5d8c542e4233ad5d542eb18eb04f0d00791e082b988b574bc3f128f9704ead41cd77a9426844103a98167d44d97ace544a52243e87c04e2d94d18cb89f0754e6b9a69b19b7c7bf4c58b3a37589bae0e8c8ac3e927a4b25190d030b0bed72c0ba734409e3b68097504ae3b1f8a48ae31e323b0fe4e2a4d7027d0ac60acda63a2df71d58b61c418ba08b0ae987e774c204c8ec405126d35e30b300a838fb01444b75f7fda0e2838a3c749c6b9c8cf04dd644420a278bd85a41d38b81376fd08300f263e09622509dde9e1d751835efe0d7d56559986d160d432021dd8df83f3e41e32a9058c54e60994f8cb24978289123316b9679a738c056994a4ca0b0aef3fac7013f7057a4bcedc14765d0ef7dc85013dec130b174e3c13e266cfe592d74496f1decd8598c8db4763abcf863c878c6cf804f4642f306171163a8ee22ac2d1ccbc1474467f20f508bdd7098f732c60c8f41b303fc6113cc74afdb0d8a8af79ca06ded9c1497f6b439bef2e08d0d36a6a03fc0888bd6574017c5c9bb845aa2723878d0857f7ad68bb4a9695c7ad8f94695d6d7e4a38e520ac37b7c7c1862419144a37df5c014bf1a6af88d38b2293b0b2792c52a82f7c90081a0dc47cb1760521b1e52259aa8452a46de052d92140987b1349d1c58dd979e0254d7f54ce0c772c3dc9f5364f3fdb2c89de47b390fe3c268438b06a516647b3aba8e9959401ed982bb16b901f496afa453e5d6b32bf9171c93f48cbb3a2acb7c85c2ff7989c71b011db0e9b6d61b62acf96b3f08619e84fb1a0a5cc13ce9aac1bbddef4f8ce4f285c1b975271cb9c422f93cd869019817d34a5eaa920faf2d4b24df84e4a0bfa8670911c6f3a2c42d6d46c198a021dbbde9d046e1451c5dd60c5b5bd27344f4a80799f54c7526c7f4b2746ce44bd45cbeeac757c26fb9660a3587353c0aad0633aee0e4964d08e25def8072bfe54b420b050d282a0c3aa32fb2b721e96d09bd1f9c48d66cf325de169cda579b32f3ce64c525c773d0f79d54b7e17e0b17eeb4ab505d72114f250d61c5645b96e7f612524deeeab54c6a0bd71bd661864fb08baa6e2a078df09d9c683f13249f2655f4d018a83bdf4562e57874e1e34323d47a49e67cfd546deda6ff61d1130b1da5694c65723f416081d3b6d89f2a7cfb4b0adcb46f6e4fff19877ae73cad32226ed0458479ac746d41a3c22b45f1dd622856eb457ea1e4a0d283276fa9d91131b4e4e02072a17cf9c2b6e5d4953de16e98e34052b61c3edc5efdd4a22989aef84692c3eec2171efac1a43d46c4804b506a4cc3f20efd2e1a8383cd313bdecb2840899b0c49d74f753eacd82fc3f1cb1ee71cc385a84837be940b9a5b16da816af903ffcece73d13f6e993c40d7e9b9190d917046adddec151a39315bc2f9550c75f0c34d67d42321da1b751fcdac4c4de99b907358a19584069f280ed63ae55f3dc88eb41bc1a75abc9490c5a8227dbd6a79ee2d481c4fdc1989d3c4f751a0ae5e14b9dbf4ed15de08ef136c73e517c36a28ff34f6b5e3a4c940e6f5c07990eaab578b23c8faf347eb4acc01177534c20596a8792fa5661ee71b96d0dc71419a2fa94b71f0641058859fc6273452ecaaae827f53be886484806f7d5764fe0c38ced1bec1763a8c6390b2563ab10bd05a245b66c9af386e6ca65d23ca45d8f8ace2fd12423e62e9152fee9079d7cae11ee0c46404c63f16ba36d3269c5da10f215e23e5cc3bb1bc26bedc6c97e77903caa6f4933c07629f00943aa6f11a79c443bef83a0bb521de7439a2e061cc09ba5d8739a15a5196e7d58c9a45f178c59dd9162efa08e0837dd0d3ffdb3f8dc0755158a8ebd9e7d482e1221b461966a1536855eb9333e1abc4a5ad08e5771fbab8389c10e5d13fe08f5502abc93735d579031df138cfd4655067855640cd072c7ac4b62673cfed9288feaa01a539c6e1c2d0783946eae08666b6efcf5ec235a83213855303ca62777f8a70dbd9588bd7b2c55f4702e113a1442f600ebf58410a41a685c4d8a99dcf81693aeb1d7fe9647aac1cc74fcd4f9d3a40047c4d99f562a720041283d6325943605fd7c171ddfa2bc8c82cb737beeb172c02b4ceb2bc618e63a86bd1c3d95cfc93ace95110ba10286d1830410fd85efc91f18a9cad9363b419e3a28f62fbedd09c648f5bd30095a7ac99ec7fe4e9ff83502a40a6581eedcf45a2d591bb0bfdba27f6b2f27486ce5a095102841bca9e1c09043f23b71d2aaec20dff05c63c222536acb6efa65c672062b23fb3f3f334108f6d36e2ec5fe0df601ebc87ec3a22a4944b6e0f34256bd081cb00673e0c6fbb9f47ef25965bb915629560cad0a42028f607b5905aff98c05a7e2ae8f57249a5040da96205f343ce035a89809c780b81e47aa17243d11083460aef2f99e399fca13aca616b53b2f895e37aa65efbf75a30277b8834fc5e873149fd7c666d2a6fa281806736265093ef5ee44c3ac18a198bd0e7b582d253388ec7a630ec1ee924b60721f0b48eec1851c2826900b68815eda050274b4f6dcc7c6dfd4f1e0cea735a12bddbab9a9b3d977907889782200a117f75b1b8778b816075e543571dbe5c96d11384bce3f971772bab81c616dbee9f29a78acfa3c5848b5837bad7bf192660a403dc88ac997c4e941c812dd4889402a349e02ee3f56ad1108e8c824c58f2b8ec01582ec8239e720f0ad16f10b5e14249364631e181e626ab5b04dfba6caec86a3f05f5027171c62acf2e1c2246e4487d39655f218faf1519a4b6aac9eeb5a2b1de13c2a8591c234a89fe2e04891ede138eb07296704451920370205497dab2db1055167210c6345eee3aef8045d2997921ef2a240d9fa8540b8c183c1ca36f44d5e8dee48a79a20a5a314609e767159808b47a4c2e2c0389ac983be28ada68a5be3db009d2e233058a0e9eb887203061f5b0b1a567ae91bebb30cd7a3dcc9b86782b838fc2509ad9ad6cec539bacb0970f19ee0d66d95ff0a3e7de0ac74037b8f9e73046e59f95bdb146499a176687bbc6f582dcfa49013d47a66a0a1a393c10cc2efe68854a1e66d3a25c4cf8854409dac16c0d82a44de006faf8133b9c1bf2ac77aacc6809707416b037a94ace98895a81e7f3b815a2d03bf08f6be3cb2a5799fe1d46fea7c61dbf9f74fd86549e24c686199fef9275c49ecae94726cc59238b2ada8beca99b882ed9c6b0b6ae9829ff8401b8d28edc4d3996bb17f209fb07f446e0821b00f1dd3b00c78c214c09d2aa3d769ee8539a846b1dce63d83e93ff6ef37b4e932b9fbdf5c5c807d02bb9f9e26ce61c44a3184f2754d61a5e791cf609813e68d498541ccac3e5a4fdc134e8fd5062fc075cecfead1b846be30f65e15a95619fdd85a11fff33eb5866150176209bb004aa0070190cb867409e6b01e969569b10aa9d9846f32209423de08368ec038fdd46d29217c11b408c08b003499c526c21eb776ae72370830e2c7ca05178141f819de12234413218bdf0fb2ede2e903ee0610af440143f41b30411f18e7609abf9dcdbec32dfaeed8cced654efe54bb2e828a2330709f3d3816703eab66bd880b27ac724df5108de342f9d13936c40a84de311a120854373bc648049c15579f3dbaf3e13ebcd62e703e6de78f8816e64f1a9712e2fd08ca699f1a6a17899f9a438b78ef5b01c1672e762ef253aa0e43f7332c07ade707610e2808fd8b66c29c115f81fa6a47418e0effaef627bf0e43fc33b5250594d6bb759fdde53eab960702882158e43f747456e07faedc73417faeedeadde2fcc039822196112f840888310501c1a7b97370d11fc372d02e458c7c2ca89bdd92d667b0bd25e8020d2ef19e789ff5ad0f4231021f041b44244255841e842322c5113f0df3cf9a2d0dcad266854014e4f35e0e63f629ddce20d4053a8ebb6875e9afbafbb2959bb2deb13039ee79d52811bb11e088c0207c76e05820f8d49aa54400fd7f5cdb2e9e3e076b2c849fa4db59c43bc4388269884d107f10e940203e0283fdd96c592128a09a7411a6407022d409c102e1134327b4f8437351237e1055bb5e7e6a49ebd6880b7d29979b870bdf02cbe7c78d22744238431c8b3081d08cf823d485c00f016c0486c8cf789d15621f89a344ac4e88a0cf4f7b4b4704a04f3e436f17a84f96ab4680475c422884f808210e61265c248dcfbf8b17741c250cc048264bd21dc6c2874edbf6574b3446a74892fd915f8731fa99de9e0262d16d5c68ffb88f352df89f8a70319da245d6c7f706a31118bacf263a16909f55e383501881f808b598fd17ec2673f70e2de957be63c06e932b281f8c5383c010e88a37ed6c8422e21191e35f3721fce4c2816a7fbeb462207420441719e14054a1502c84b70d32a2c5c347e39e42d4e9074dc999136707f904ba154658f14aff68b140cbb5ef2bfcd06e2915d1e2ff09b6abe2f919b7092116205e208e20cc204c1b01d4f7c96afb84a0c2f4415a3739ea936d6d1174b1baabd20bfbc7eb680c4a1f49bb5b5fe573afc98b70401446e023b622a0405040ec8350cf8816a34fcc5608840294d4900db0df68a55fbafc8c65cc02f5e43cc54d5b118213f14e0446d18706ce0a854fad43477c10aa362268fe73e0e221c48df093f823b841019416a6b9e1c4533e99561501200816970f953a6a9d3e15d92e923f2bd70da13804e0d715c924b9f94598223623a6b7be0844f976408d98a1dd828db8618c9cdfd743e1db1d73004ead119cc5fad16eac880ac4dd0807083128be19027a4b71258e1ff68759f0d66c994b3d18a323dcd18cd3fd406a67b04d11f9a6ba33f81fe1004676014597d65c88155df8aa582d9ccbe104f904bbc208e5106e448a44b460fad41c6a08f17db5444ceec813217e562e078218818f48d60f8a7db20ea351f273e5ba1157fc73551fef001839445f18f8bcd0e4a3d14d5431848ef013f80fd7883081ce1ad144b06810c67adc093bca4985829345bda9710f90e7d9e0b721cb61c9668aeb3366c6c2656071dfc0de396942d496aa8534524d91816a37785ea7b69e1632d42c2a8082f6c12f6023922e74ba70508c6c3d8dad4b0feabbd3855e720de3e7c033df67e219269e088187828f76292525dba9f2f02273c4fa3e72acaeb1f17d5d06ac51f942519e752883cc8c104a31ca6dbfb0d0ad27056cce2c74281dbabf04b164849eea78bb0d563a40e03af63efddf22790ec5ae19baeae5f51c9ac1cae8a9668937d4fa622593724a7cb20ba44965d7a2e73f0a75174dc61806c13c60756e02f90537bc085b4b5bc2f02329b9850037f6e4f22f9af210dde652fa91af1d5f35a972d2c2f29b3ff152ca6208cd670a662f7f9ce18c40877aab9f5a23f04a4b4e3013263b42d0be41490b6735c105bb62f59e221a3f7835e5a12cf6781d742643e8c94c4581d6ed1df6022d46aa8a570c44372f61d8473c759e464480cca582c34cab1a7341215aa45f418e9bd52486a3e347a6ead63944e7dac11010cc17783a52b2d843d0c56cc17d75cbf045e3773eb550c54a4d7b3ce7ca5f0c3b308e821abed32e312b104f1977cb2ae372e25ac8bb2bab65c1bfb128b14497321398e3de11c120044641a31b42fef43dff86cfe76fd9cebd7f39cb4d455496019d4b289f5da96e04d061397a11243a1cef3080f5e1a9c1e15da744691101c4795341f017cbe057837d3978085c2387a53d0c06528895e1e428fbea0f59518a7c0d26fb2674c41453445fe7e7beff06ea43a92e791cf61584c5adecaae6922ff22125a0eefe3fd6b102809473f59ee10b63178a7b177b358d86db064f65b867ca6e8bb5002a921841ead9742607aa4d03f7a8aa58b66c18066cb0e22572294f6ee02d45289e277b0ec81e36d3d36863c9566473e18689a202f15a576003f8ac00f240d1b0fdb6bcd0857a6e7b86eaa8d277b99e50c9399fd48a1cdaa10b63c57506a039eef84e4e922c267376159c66abaaffdbb186b6d4f691e88e01096f081af7add35a6ab5d5bd259549e9672d48f7b1c8be26f6de0cd6fd3eba1220dac1b416752d3a4b46ac7713fa55b3ee3f300c2df0f08eb5992ed682098e77128e86de69978032b80a0f26b909b04c3b546eef6e727836a12daea981ff85d0f6d3e385c7668be1d2e422a859ec0e921e7dd6bccf144ec4fa805fdd037905708732b7f5560810661d6678496bbdc706201ecd62c2b1a02302605dad60517727a20679aadc708d1023db52dac037851174654d5aee99c8c1c633e150c39a0cf06aa4dc5e2cb630f4d492616b288f3ba90cb38dbae6ccbdf9e038dee09d196ee63df81b309f644277cac67154cf54da4eb71fcd3c1f5789e73a8f9eb08d579e2b5bef842f0330ccaf29662ffa74787ce4fd8f1e29dc46133088960ec5cc62528f4dd0109f5720d5fb88d13a3415c1be9241085cc1bbb6c5e7e13cbcc1d5e340e91037b99f62001dc4288ca577e6586e5fc4861e3290fbc9baf51d78ef7f46720e16bd840c451e99ddcf172f27a7b35c6fef2e3c82535c9aa6f9d92384ecd130a49f6454c16060525529f68ee21c439ea9b1193f8a5cf7af1d0a09f4516a905b138283c05ec1c03aa4ed05d274155bbf5d5b7fad5b1ad1218788d6646543b7cf5d2b85cd366c53ce0e4fd7287047c7b2bf1d2a79e956f0af1d99ae73c92dbdee061f71e4f661646b1c8003c4cb356b5f25524ea1fe5ea07196b40c2221dd2abc4158059b9122be16b618c64d05a763106bc07882ddd768ce7bc0650ae0baacdb227a7514bffb8336b7783c048603927abc8201cc87214e24a7b0cffba678726b8d4dbbd590124811b1427c05fc205d37730a9914140ddf0cbf8573b05753da8b48dff27b6f7c7dd5679db2f1dddae9c7af267c218c62fb9a7729c846e2cf29a0f11140ecd658b5ac6e36b8ae8490ddb84a07214e22824bc1da031cb9fe4549ea348434b81c43c153a70ce1cbd08a8bab1c8cfe4b0c052d17ea21f209e1118525c287ae01a8dda41e658d16e8f4c015ba3fe94002a376311e901a18d15a199ab6e16c874089284775ce7594970a56836ca23ce68963c9fec58e96590a81b41b37f17486065e0e3f472549d33683d2ed59d6f968e08e311ed075b19590760400b20c23aca3d19ce1aeb9e844a68602b4515855e5f1b24ecb1c2d9aba5dae071fe50b4863e3e9723be9fcdcb60da082c68f3d7758b48333eff20fa89bc0aa46db3fe58df6a19f7d1d46ed781522c7cc0abfeed35736572dbb640fdb980e604b4ae5c6aedd02051adae4d77c9e3ee6985cd7542c50bed2aa89658e9f3522d7f47baa55e9f13ef23cd98b79447f27f1192ef038aa2bd2cbb70ff4c05e27dd8c645dea92bd070675cda7d7ad8bc0c2e3ce6193428815ebd698c6700de565f4ce8adb9812373582755924d124f5a8dcb9d81b2f44eb2acbb6d73c2b272bf310bb9e67acbdc84f8a6c260a85344ae80e3850c9a0cd28d2225f0bee6bb3023adf19fe1c224c16d3ad0c238b5472fe0cd50963c0140e592e9a25ae7489ac89c109492c885595f80b538264b2b04b96e74b57b9fade342c1c9b6b18c9149665edd7698c8e446493459060e618d80a9b8d6619a0b3c8b2d621f75c598de46004895960b53f09fa9d8cfc9d3d110f0deb8ec5521d51953ef6f5be2b1a2dcda9a5c4cd3452bf3f13190916eb4a5e1d104f1506bdc8e8cf770ae7a2bc2d6ac5b79eacbf4c6c05c45bae4f447058d4e1fc6e79769f0624ce03b8d267841ac2d2fa3bc7c7c62e1a634660ca15eacf306932c5462a6005e08aaacdb4fa24818b911629ce0294f3d5026c1f53a640ce2ecf177011235d0b119c3f957e07f1b41189a265c89d11c904ea69bf9c3ca62ad86a17d9ca1adac34d2da70756712e90dad7a4a66fd6bebd694088b53e77b6ac51a9396af2356a77c5e67a6c53abec0a6f8a0526332dd61942a4cad5bf7a9a8ab88aa5e5fdd9bec59f9a216d90162e1d64b5742ecff9ec71695a1ce4067978eecdfbe9e02a47137370bf21b931963b21002dcd74eb6d227419154b8ef69a70eaf013eeda25eae5e2137cb7e56337b32615bea5c5745d20da9013f264ee084af59f841b34cd65228fd7226611f2827be14ed1b0f5c84c56f3af448be1e6facb0a9dbfe1dd1c8160d56824dc12f5177861c7496cf06868e4106d7e14eedad125f216b6712818fe4ce48606fcb79d6f31a56606384d57d5429394dcde3da5c62259d35262b5c5e6f89c7694e03dff1adbd75687d829a46809679488135536786406d6dc269d4c0734f04f1478fbb1cf39facdc42bf87cb10450acd1c9fed1f5a10e56be65eeb4ccb19f4036de83023047dcc2de521a38ab690c6499c113c0751a8b09c73539c16030e9689d52bdbd0cd8c4e96cef17b8b7fbfed1f6bcbf61f9384aa415394febcc05b1522051710e4647fc027e8be625a2133c691e48a309e6f03fd81af657d13a0b243f5a37715b31d9af8d0e45d98122c0d1cc3f5371bcf25ab655a3ba0aafe770f0ea8d463f18220a522b0827f52685695ffb9d470335e896d8501313ed174b78bf98b3ca6bf0a0f1bd34a814c4153ecbc4db6f4835aa1302b2e41f15cf1d5604b730cc687f502f73dd15a84d490b298c8e9d77cf0d3e78199f63084760959e1ec7fe0158ce978e22e99714840f1f425ca2e3fadcd58b268eba294b89f5a6e799b71dc4a42b47376527678ec25558a98ce88fa1d0db7341bfcfcbb94e1c520e5c608e6417a4ac1dd03d6c6143097460de87e9c5a3d880b770a294140ccd9b4fd4ab73b3b4b31833a4350974b438378614420676ed08f09d0db01b8360f6d51a721ceb74d91bbadccd14c122612c3388942f7272515262179a08aa4d9ce0353c46ea7aa09c4609b7d4704106941a5687148bba795e1ffb2cf3e922ac1f3fcc448131cf3f9cb21b157d88fd6bdb633b8e216e4b3f3e6680d689f11124a8fdf78506f78682978c367354e234dc8dba6ac475e7ee6fb3c9878e62f9bf09bed28b7899423c99758fa49ef322b0851fbe24ebfd2314095c9ef755895b25439a5f7db90a99521d1e7947db30efe84c51b5983329e62f99dfac60327fea0790031d69e1f3fcbbd2b0598b9c6f2d318f26476e15627e26b0d6b27ad027a50a832a892f1abb7cf21d4bf9a6fcfa05a62fd4da6aad5ded61ddddf405196a55fc552a782d2ed840a065d0a925a1b626cc83f3d737e9d09f6af0f678609f301efd750755af7efdf383003f0d10df0322547aaa1cd2c0c19598951da7d35d1abeb3ad4b720f1dac250075b6fa5010573fb8efd79ce826e9c97cd73d78f088f4a13efca13751095d35d816235ac5ec0a324277032bc9034422e354cfb62c12218546c9896316b456f2473f0647aeb29aed0463389d1d98c92518d3081c49116005ed6d9011d45049c448fd8bcb6fdcdf94545df8683984a5c762654b391d629b68ab236b62d1c3a00e42eb673a2ffb48b0b36bba70dd2b1789431130b0bf3837e302d1dcc45c5bab0aac1204fa193ba45410380b4d3a958292b819245d14f8bac8c1917fc8f55059c341d6c367a511eee873a983b4bf2a3ed17923ad32d6439de64465637772e31287f89281863798f56d40659be0800f7dd3d79b10b9e5de726f296592329909670ac40937dba261d3d9a871dbdaf463fa7ed51fb5404a80e39c9a0a95e63eca79fa33cb856439389ee6e070a19c108643c7d400c7c775e792b0bf5973a1d152ed32d7856e48ef175e172d154887a8a492baaaeb615a6e1ced3beb51c93796f6c1b723576553ae0acd48f92dc65866abef77a16743997db9c71fe21be771f4bcd13734a8c72633aeca0bfff74fcb3876b1ab5cf66ef7d5a6a676f797d3b2ee3babf1d55ed85d3b2ae1b2749c032fb0fcec72bdcc433c39dd75e5b58069f4fa4e00ef9c57ca4efeb679dfcdb0e3244fd7fd94fa765dd8fda5434a1d97e4f518d49cbe2e7aafa79267be9cdfcddf5b379299aba352959f8bdecbdc79b7bbf7c7bb3fdfb230b54a2ec27200e923c92453503b842d6b59d66cec1fb54ab6b72114fb5b28af8b339425a994f2503a36896dfaf82505cc7621ce7b99658a6b997d0eb69549d9f7bd135bd68e58b3b3d0b6fc62cb9a14135b695f7de9f75866297dc251dc7648f7f73f5d44bfb189b8dddd9dda9724fa729571cfbd7beeee491c4f8b85116be6951bf1d453a5d0b55472e4fae34de2deea3185238a084ae26e085a0d8b02fd79eccfc3f982d18e76958523a02240ae6ee0b6dbc6e3658c87de997d12e028ad8aa82b1c7fb6cb8ff8228791fc9c1cdf2d6d8cf3321fc14ec04fea66521f078efbdee3f81aeaf891d2211e5248cf04627300ed6b0f6bdf56ac4039394d71266772da9a356ace9c3143864cd69831565bb64c59b102e5e43465324da64953523ac104139628519204638c43115ca445d2470810fc187e8b35d00fe06b6323aecd0487a00892c867cf2417381bdfb81096443e42a08b509268680ab94c336b9a914478d31d379bfe5ce342f8a9cfa6ef4c2e347bfa3e85be4349229c4d71a8f3de4b99d6f94ee31d7aa6af8b5d8ed7d1b2c739f04bb13e0f7d25cf9440ead7d7d1b3e994da5f28a54ff534ce773ae7b117a4c726df0f0e7e9806f1fbe3e8cf458cb5f7327bb77ab5de2d7313d7b6619023c0515a1d7121efe90dcceb91eb73817af4a94dffa547579edea6672e6e3a08c8082af777e40757bc53eb48c2c65ff147edc45f7bb0be17e4a005506e22225025bb3e09bb86586afcd3d34d7ef6fd9824badbb669201dc0ad7abf69ece9b1674cb26baddb05e201dc9eabffd551c9c63e5b126ddb5699cf86c02f7fc7f8af27a1c0b93d97f52bcd37942ee2f00ea15dbcafe0ed019c7b0e000fe0bb726f38d2edddafc3b3da1b5ec18fc318e5a143d208080bb83dbd1fb5c2dddb755dd775f75eaeebbadbddaeab33ee76dde5e4b66db7ebae54aab5c9acca29a59cdf757a84edae0b9dd039b76ddb6ed7dd6dab72e3b83be6a36e0451f472c582e50ea516fb47abb848ab1938366a6b9b61cbbbc3964584d9f793b90817e2efb3fab571feac9e3a838da9576aeb66b9ed726fa7784526c6e9c938c40fe7f85c39477ef0f1ec9bde6f3bdfd41fd6f9808800a5e8e6429ede42a4ba9dcc36738a0daff4f164432892f77263f19b1a96419e6fead92b16f3f14dbdf33c3f32d2f7d5c551a9aed9536fb0373dd6bdbd72527e309481cfc4beeb651bf77c5617b1a16ce328f97472d1a56fe4a31c7a6175d1f33104785dfcf14d1d04fbc13ff473f2910d83f4641b4e282b59407f11007065cb9c645db4e19c62c322cffbedc73905cc36248239f8a65602802418c8373509f9c88623d44c70912e01ba027a930c3030b5d28e137000bea9a1b8487f837c64c314c40db0074c216d0a7df4779aae80738f730aeef931978e8436f87c88b988ef219eef878f259f7ca423c88faf271ff5841ce8f80048073f40be00007d2b74908bf806e1e7f3f2277dbcc701f8bc2ccb49de6fa1ccfb9c2d807ce4e120200fbe39c585f2910df1feac96b522cad838d90bab6be3a16f4e11ca453ca33cc4f7379fe81be5232f9c4f2ed6a2a6eca9736c1ce483b2c7a27c64c3f9f461cff3ba7cefbd2e6eb337ea0d0e85e1f01c311d3ab2f9c18ed9ec0339a55c5b28a54f372a39256d3f43d9f6397be72967cb8ca4fbcfc52bb95bef379d7400e586dd0db65724833d36996d5b6d682483edf5f3e873ba0bc79fb16773494625db86b231ec579bc1a65af6499ffab216b5c496fbb5a996b5a82eb675b18636c97e8eac1151266733813fafdbbfbafe74004309e0323b8ab69d8816ec9752ddf5939c86b2ed9fb3e9d109e1092ed207c12631919ef084e65f7e1550ca70e3a8d4512ff67ece106807d0e5d2b15d86e30cd39ce459eff364cedbdfb8017e4cfadc07f5cbf5f77efaf3eccbbc05491f294baf69d57cdf7d1bbfc077bf7428632a298fddb8db79f8cbae1778e30607862327474c878e6cb6a3c7eb10003b1f978106df75218efbc73df9e8761f11b9bbf0473632dbb46953e41e4fdd7803f1e3348f8f1fdfa6710f8fb8810619ec0020d4dfd3c36d3db6d29e1e9fb2a7a703977db9c61e93a4fc15e692e75d15419c01222a0832fb67cb5a10426c22b0f68f2d6b4358ed4aa368a896a5965a6aa9a569aca5340dd572217a75110896ba58b508404080a3acb9bb13b9aa56abeac90ad3f660cb9a1058423c6d71cb5a106bb610521bef4f6be317de91b01b2fbfc78774bc0b71372fed4bbb727264fa755dd7510976ddf7e1f8d98121930fa46946f052ad3ddf8ef2ea7b6b434b6d38564aada59b7dca86e65f615b6ae948d5d8d1777e3a522dcefbd1c30f36a433431a8e124be7836c33e7b7e1927b414bd350ab471c618e5c84bea568a6106badd61e73502dfb99fee4be28165a5d2b1ca19ddde7e40871507a63c9a537cc09c710c78d90a6a94fd65a6badb539a4692690ede96fda7e1185e91b389a7bfbb582e04534cd8759a25813699a2c5114459aa6880e2da13cf563348d28ce5c9caf43bff32c916662a2199a86a6a15a340d0ed7314505c22116fb99b9bb3b9d651ce642561508876a95ea17f5b19444cf66cf9768b6dcb20675b5e57355f6ac01d1b4e78fdcf7c409b767524e09640338fedeef42236c4774a17dbf3a827ae4be43c23df732042592a64a6f3b241989fc2d23a13fff0b6b0d61341fc90956fbd3e624fa3017a23f5f3cef3bcffb8e8aca0a4b92d9f275bacb5926dd7b45bad0b3dd7f437c6fdbb99fb9c8e52e0ef7b9396673dbe6c2a03520f76e2b13ee6f112ebca18ccb479c6f6ba3ecdf2a5137d0e770b8dadcdf1a7dfb03d5b6bfe16cddd6c1703a9c9b0a62b910dd32270f99569b0bc7efd6fb7e7383c97dfb37b2915ce4de2bb77411fbfef417dbf901818892254d52609af214e5bb3ece61f317f5753776df9fc97dceb7ff26960bd56c64d67ea8dd5ce4825f918d7a9d925ad7b47a5599f2016acb5a0f637aa8b2ab13285c9b366dd66c7f2272bb162ceb102c1dcdf61f97760f4ddbff89cd7623f2e73be1b6943e54c909b7bbcd3db513c9f61e72db943f7fc2c07bb276ae7cabba03399807529a10a6cdc659898d4327af36fbca073dded21ff57b68199e5f0ffddfa34708f5df8308fde043207abc0cc77ad41e3ab1f04b1554b024152ba2bcb2658a45318abdcc0890463a51ae0bb1904a4ec223c849d8564145159f638d2063abf3bb15d8aff81c8b4cc2ec672f33093b7e470826ff949c646dc8491667e160430d5938d54083163748f7e123d320a50454a4f80c4ea6ea471650ba0ffbf6addea26ac76730339a9492006168b31f4880b39f99843034991f10022d480d58440218275537f0f8d9f3d060709e879ee160d72f6daecd0eed248dc81dbfe3f10e4d250c4d4a0250e1f13ba8ecf8998f2410e677682a3c2210829492003cc21b763c952aa49404a062444a49801da14ccaec67dfc6c63cf4ec77e85908267361b513fb1d58da198cfd6a3f87b222b2cd76fd93d1dbf997b62b63133871bd077a6cfb733a11c196d7f0678c35dda2d1b0c676db77854fb0abc853a0d16834fb3a44dc477d223323b28d8d671a8cb5386cec0a9fe4d8f604d73de882a33c3e831732cc204399186488e18ba6189ac080a10986305e80e105332ebce082184c2e30e5246cf318519cc9a3d88c8216d044692127657c06c7340bd3d34c775dd179aceb8e6969a413429946ce42b664d0622f298fb3e0b49c9471194bb1d7797b060296684b46b12f721dac6b2ccc4ecbd8a66085366da05161b6c1861950d8d84a23823342a005822d47432a85ad355c05521f58430d5f81d4133562e06aa43c100336ce022925363068810b3048c3054c69bc604d9417acb1f90527a8b1066317e4a46c711aaecf2ecd819b972e6e4d778d73dfe04c1758db829c84b385c1065c9fed962bbc925b7057c06ca43490df6e99915258dad98575dd32e7f08aa43c210b7252b63929631b831524e5c9af66056aa8b00215ac01c31bbdf04650548086ddca001b18f0362e205d44c3db54000d2d9a05fe7b54e0c31ea1a43fb472923d232759cc0205ce48d3820969cc8852821968982620e98ffc92fe40930217249082325ef8644b76fcec6558864309ec0867a1741f2e970be1327292252327590c0304c838d314813328888104148c21c303a4fbc82fddc71862cce00031cc48698099306818210c306a6000185fd8b0802fca4c5140192f46a0c48b2ea824a08b13dc808013d49c0e20290fe5a99900872492f2982087241370a18301b8d8a20a922dc890e0089912ec60a4045af050002db2782a9245560f44b2b0f001098b2b7e18225d0cafb0c24261399a5600414410578488b212d3d583ec635ac410f6b1cb155abdb4b17f33898b5c4ee262953792b8583f3f969e8b888bf57318640338b3c84778661181e509b847daa6cdb67f84cc45f0cc9a581c1185c511565c215584155255606131a20a24b0b2646b8ff86a7051918f6eb25c4d8184540d381f7531b3f1e3e029e4141629a6a28022892c502431e6092590b84f28e18418a025c0515e0de990479ccc540d60ddae2b464b2e62df158eaeb7a1554eca3fdfa56b189cbc25090fc2e423bb05cc124a80c94776892f390967259af8c2449516aaaa26bce4249ca996e8c00b972e3929632e4cfc74e9c2252765cc0490172ef9e8a60b5513df9d01a832c02472640ae926101da101260d47c9c5ae9ffde64e2154f9e8c64b133909e72a2e1d34f185899c9431123924529efa92a80322457d44fad4072285a414698844f2d42e57fecc3dde2b8998c049782e919332ee126609305bbc7860b5258c962aca23e6d69f5aac94f8e2123de8eb111b1209a201ac5b9c4a88c945ece770cc8f13ce2472120693434cc37c3a74acc8330637ae7141b3658dcbcf96352e519b880bd95dff48123a54d5d068b42b46b54af2c831170b242379e4bec20bc923f7d863d39f4ae423bac19619ebf81cfa4a8c0b9badc196352a339b4b95edd4a963225ba2327d22d3c79aa34bf9a955c66fb5efa598c662635aca5e17f3c774900f4486985319091124f21056b224b1fc9d452227d9c7e1a8c2c63fb34c2c5336768242f1053d05fd008ee2ae37378f6f6ebec8a16c8c839e408bb5d537373fd68d83c3e69ddf7600a9ee1c7ed207f64875db10c7fe9c19c97503f637b42ce7717cce37a166ef6c596b628a7d5d283fd012201d123de7cfd13623c1be1f2fd6370bcee320995bae8b593e9f8b29d68735ed410178e3c3cdd7b7f928e79b89251f49e558943dc2da27827c005f145db48fc371ee6f1e9191e0178dc8491c11172a221fe530c4633eabed7e72f71756176995d207052570d3ef2410fad3888cc4ed22425991fcf4732829a51308293eab7d06f181fa4aec5fb1cf3199b18ee9ab6ca372127e1b32718d4bdb85e9148fafe424fc396492dffe242227616bb3ae547c56fb967428f6ddc7f2db70d6a8a030cdfab0e6f6cc45ece330874cb6d436912d59bbfe91fa236c41b3b7ffbe9f511909fd2f1c71759ac5949b9d572af519e552aa45946a7b39bd7d150a5581ae50976075ae20065886a1dab2f6456b6f59fb5266d620a0a67489d6aacaec9b2d6b5557bb56455535a5a5caf6a3a5cd05cbd98ec82389ec960db1db7fe3426b61dbfbab412fa007023501facf5bb70fc93c8c19e1b7fafb5c8cb9582b8db65ddf4ecd8b43eefbdd9eb761e15e8a73595db57b8abda7f4066dfaa6b0c7ed95e81eb9f7be53a2bbf33617c445a0312067eff6e4f442ee6efaeb026a27773f99edab9da4b0bde7f413babdedfd7571ebac68b4cde94ba3ed4ddffd4387ae91bd4c8e65e3fe93443226f37dcf876d39cebacd761b4b1fefaaae9bfede76a48f2d22bb33dc913e1ee4a27fa7f78f2b70bcdd7cfaf631ddec36b739e76c739e73dd7bd76dd37a0145b5767d92e1d844d4a25a55d48698aa597112291a9aa6a6a5a996c416d5a25a5ab82ca022c0ed81b4803a404180e38c7dcee7bc0e3438723cfdb94676adec1817ea1e470eec6b3ef26ecd431cf6f6efbdcf7d3afefe876327e771fc38db76ecd9361cbde7381d1d9d7abf3ed2fd1a5a3dd6d9cb8c64ff5bda9e92ef998ea635176948cbb8e8e1c08123680d98f3f5bb2e27279cdbd373e7a836775716def8aa618fb7afd356eb6c998ddc8761acc70aa4051c41a70ac79f8df3e07f2106bf778c3d1fe5d70b17d1ac713cd6399f8b1f0dc7d9867d125a5354ec211374100c5f5f445f300b1ba2f3301b8ebfeda8e4f53daf8eb36d4358ce17b98e7d986b79ff3dd6361f61dc853223dc778fc47df74bfb8af9f3b7bfaf7adcc11ac77ff5084966d55c04847deda7759ac0b685ed1b8e4db6cd099bc070be623ba630e2502a0e6c00c759b3db47abaaa8a4a4a29e9eaa5029540a6ddada62a3a585a64c991a16d6555515959454d4d3531597e252bc696b8b8d96169a32d686b34c6de642937b202be0c855e1aa38f7e442e0d3e7a05ce8f5f4392b2e14c549f9d08ea7cf6d71aeca85acb8312e247bfadc1587e5423a4fffdeb7d6eb3acf52ab54b74c532c2b058d8bb4aaa96bea194f5b9a65b2525ca48fa3ed14eba46d156d9fb485d2d68ab65156ca4e511e5ab35476ca46d9a91b3b65a5ac0e930b8df639269db1fb6dcb458ec907d07ef73a9e4917724cb4b9e51c937352c66c66e88666d35243e96f6c249113a5592e44b35cb45496ca5a55b9500efbf629968b54774fb35cc866bde895d534cb458a44b13ab9eda5575859b6b3d862706ab9d06d92443852aaf8539453f995a37136be459ba8942af48946512a498463775c0ca0ff5d402d0c3261a009238c23aa6a5848dd1a16524e566a5838cd1c2cb91ba08b332b5844050d415f5a3b6b5830edda021a3a0c7c7a16f5c349a3dffd5e6e8519acac8dadadf2256baed7ebf57aab9dd03b34b73b739ab5da61ae2d9c5b538d9a352019e7a91fc6983d4edafdda69b1c3a8daf527533e723dc2c0dd645ba7ae5f7fb5cb0b5fa112359cf6a68a4fd87604f3169e3102c7993545d6aeb0b287a851a5bb3e91aa242ed465b1eb2b39c1ae3fcd58b9c806f4e6a472201880f42f1d22522489fcc798f8b3a590696602a93f694276f8ba726d210ec71f3353881751858cb1ebbbf628e953a79a1f57388aff0a69369c520ebd201a45996d8cb070415580726fdc1a1c7e21d32b1c63e36fe12882e1f853db4cb5a16a63d5e6ca6ad74b27d977e9fb8552896e1cd2bba51ac923ad607369924736491ee9ffb968b9ac8dc071aa715aad6d31edfa738d0fb9118dc9df3fc7d992726a8f5bd6b0ac6c9d1080b286e5b41d8b861a16d38e6d55b165cbda14517b0cb2eb1455f608ee3973af428bc27adc6546eccfa5cf6b54646d599b226b0aaa8d5fdf77b511388a9bca5a154f43d4883e08b4d61a7e77cbedefb63d2ce643f7b77fdfd95617b9589fe621419840b9e70701c185ec66b939e75f0bfe136c848282762af5f7e2a12cc0192c1d6389a574f7395f4ae91ece2c5f414fe058eb9cd405c614b425352cab3b9d56bb71f7ebe494f73a4d9973765d54b54229a59e67a9acb516e3acefe3388efbbe8d8bfc755dd7e56ccbb83e8c3176b9ae18af2fe79c5fafda9519afd70b046b5756b5ab346ee7f2170bae685bd6a4b032b4652d0aad8d5ff2af5700ac4541668f5f83c114ef9cd86e345f7e10bb85a00dafd89f3a0853d31bd970c779fc03c179fc7d0c326100e957bda38348008e4182b87b6d02120314e6fbc25550068dac7966bbd33403f40538cea63d2ad15d5fbefb9979668c33f30c972a141403388a206c2db0cf19fe7d5bb775e307acd8b4eb2cedbe7694d6bdc56d928edaabc5dabc7da79bdea8fb4d2fe0d5c58a28cd493a7bb56cfa553bf1dd81a57da5690046f73b2da3f7a3bcda307a611add67ba51b8f04b9ba512b828befaf241d8cc797e5c4cb3ebff0405b9d2f446f7cafd2d518c19b3062881ac00679248a604bc4f7feefbfe600dc7d8f62dc4740efdfc70027c62b713dac6cc9e396c10e6b37eb1988d7d92886e0973ebb9c8cc61d7a7da89ef273c7607969ee4d8f49d706ddab4b195e6a68f42a561559b072cbdcc24cc9fef5b14dc753da514767fdbb6bad5eae0cc1d080b1cc59f2049c4fdac2ff6d46a7d73f73bf7fcd86ff6b9cce51acaea2f6da4397fec21449440e68f3baa3f28615b76bfbe33f1eeca9a5f5e6e47fa6c9bbd57ec09b29bb538a410bfe36b6ff7b7c7d4e3aaacbb6a99fdedeb6452dff7116cd372dbdfd76df58ef4d9dccbbc50d43d4175c666dfcf07619228ffec7e736baf75ab5d2e5babb4dea7e7acc6661e7e0745d49834dbfb3eff700204bd2f3ba0d2c097f9e8fa3bf7d51f77daead82ff2a3ee6dd697bb1bf7f6feacefdfe9edafcecfe9fbdee7eebdef5d7bf937ddbdebfa786edbf6485ce8bf415142ba9ff3ff1803e6f979168b6dddcfffe12eb75dfc713636abb7ded8ec9f009df4d8575e7fa5c91abdbee7c7a9f72f50cb94bcfe755f19ca12a3d7cf4c41ad02f85830205dcc21942546e0cfec7f5d1a757afcc2d07bcf3dbf9e87c1ba3b5d77d01aef7bbff7f3ffb6cafdccfe557a2d0a2b1bdcb20605d5c6fe79cc4519c39b8fdf96b1ed5560100b402547ba1eba9c471658ee602969bd2ed211047dfb21e667d69d0f7fceeb2e0491793fb7bd3f2ee49bf7d4eb3acfebbcce9b92a86e32fc7333b1ef9f93b9f187d508feedc96b7f8939d7f7957c63efbbcf7fe622fe4b7b7ad37f8c01f1df4fd7a357de5e7e9288e32a955523db738fb47d0d47285fb5b908c65daef5b1add4529713baeb7363de4e5d36fca4cffc4ffa383ed38d9956b3d2799f60da9452f167df1e637b661b561ab0dca9d1f98db5c89da87242ca2e722149eba54377da5cebf4af19c9d29ebae62217fdc56c51316b36a55fca88d932375be9f41eae710321dd02cb2ac64a90f9b9e3ce29a55dd7751ded3a988b414f200a75dbcf5ad84be8c7c5faf25f624cccd39cbbfecc56ead405ba58ab0c226b566a86dca8fe111772d0b6b1c3ecf1ab5f3f4912dce5234abd7c4429ce479466bc6d5c7e24b97328733d931cc402902eed51696357e7d1a58d75936f7be11c832949fd0ffb7da2b6bdd6c07cb1a75fdac5bb74a1944efaa4c7eec0d2ddf32f165de817b098569a26e8f2055017d8bc617bfa056bd33bdee77ebc746f5eaf745456570da7d432f9db1f3901de97db6545c227a3127d3752e48677055fdadcc9c0f8e5e3a01ec0b1eeca84993d6bd8b2b685cdde9ed2bff47195d6c68fe3ea9edea7f46fa6d8d3f9257e9c70ecc01275590abed2ddafc79c4fc9ad808293d9667faf74f78dc7292022bd2ac80c084686f3f6f38391e184b58c04c80d7f0952011846963ff63a1f46e7eb62ffc2b139e76c6dce16678cb1cd365b6bede36cbd4c11e369cb9a99293355b6179a1a8b93858333b6cab8cbd4d660cb5a97a68d7f83dd54fb22b5ede32f4fdb7e96b2edbbd850d176065bd69ab0b263574e4ca8d9221a34b52f5b1bcb28282d5adbd2aaad9da9b2367efba5ca6ae3cf531bbfc501bb954f63fc1e95876cfb3106f595181157a28a30c28b741f477491e222290f16aa2c4d4817916042d21f534b24b145521e25b4685142bac8c316aa2a2e5c7838420a4b961f9000337dca9503ebd20587892e436cce63ea60e4a4d585f3765b2d613739385ebcb876c8593e243e15745e1a61397d4ae743269da598c69ec467b502965cef3e6424dff9259e5f7e25745c3ada6aba16595db0776b5d39195655758343e501972e60c48409e3250c145658803dac26d0e36f70aa5cd92a1f59d88d0d9580b09d93f3312ddd0358cc9f90d3ab0be775b434b25ac26e7270c488717db9e9dec5e423d71739d6d13257a8048412d32ac87eba4c014b46b247802c64922ded9856c092512cacee817d9a91dcf390b9f3c7ea7477e96c9996ee8195696984a54b31abac2ed74b23aced0e02421de18804172b4c1f49a295489ffa405bee85015d01ceb0deb6cc0f98dde0389820128459920990463a0a582241152e545c3eef522527611d7212b631adf3ee057bd5e75f72093dfeffc3303ab8870ee33ae4e0841039e0f0441038388d0142d21f3fb2d30d5040f90d4e258a0f7e4c8192fe90e2ff6325488944f645fe2309b0c7cf5c421835324f20043541628045b2843051be00a1b5d63d5ee6231d5991bf0e424a22f4837fa8306af43f54086a663eaa40987f0da5ff5f66134230a343203e94edd0e37b7c91b761a4a3230b7bfcebab305162efc29291ce13a11f40219d90244aec75429912ae8d91ec9ba064239d5f3292329d708afc61d404fe1e8e75bb7b38e7f436f0fc9f17631fbb41412e607777f79d9e0f8c92b57b827e071673ecee2478232c71f1e8494a915b6badb5d6a7136d322961c0c5265068d4cc336e45e4c80ee0085e38ceb6f759793e9a735a2f66f3519d765aaf42d1683423b46a5a66b4d00819414b8d04729565b1f5e1c393d9291380df0c7b5b5a4ea0d6534c8b494b4a9bfb094d2c52f4979edda6d068b422d068010d19d0a04234021a3b481fb94751ab055a6a481eb9399e3d33cff65c25a536d3b96d8865e7b6e196e88564382bcee30e05e55330169ee246bc9f4ebe23d2cf0a8fd70eb97ebc9e8fd9a69d52f9c80b4f00facc50f4846ba7f62b1fe3ad61e546bc87e2a27b3e6545a1fa6ccc7d77737ee5629a315b5e6d5933c3873464368f2d6b66d036fe3e97669a3fb5008d3389ed3fb148b712f233ac7462dc6fe68f227948e83fa19b89fd8c94df4ece1bbf90fb201d402617b0ff5bda198e998100fec044cff3685704841446d8534f2bd1ed791b80ed26b0ddbdd5f94bb3c6a6d9b26730d93362c860db4f73c6a6d1923cd2676357d46bcf252490d7e77aeb0a7d0ae509a758a1e16e755535c6cc1ebfed55533e45737733cdd2c52d33aa064a1771b76409a766842556b5ed242c51c3850e5506e8fdfc51a281ca5ce8563e46cb6ace3d4e2d2b9f34b5340a75e70f77958e4a3292b5f6b367ea0e2561560922c58726564f0f0dcdd0dc02bb7704c31915f533f18e985f31900235e5d12268115e28a5cfe7539268066d012671d15fa96a2ef4e69c33045d7a4a398ffb7bd46ef2cd4d697b3fe73767c6a15bb9e86fe4542e84b587dcc87dbb4f8d0ee5504d5c68eec7e1940b4df7749369bd30888b6eed2cd2b6ce992409c544927c01bd1fe5d591efb116c5fc9ee7fd8b5380dedf1dd145ff3078c10f9ccd84c6ebc16658a0f75d6ce66fa3820459017aef85452e42d9f6c799883dabe9ecf909fa71d1843ddf5a1be4a2f778fa0407aa021ce7cf2817921a251a6b59b027d6533799f9d4389c9eae7b84fdcf1e61890b49179241c41fe95947326c596accd4d04c810ad22148871a1a5a2d055653413904e11054058a4a5a535881f3524bc194329acaa8613f399dc97232d85032d46c4a51b0b5291952bbfed46345e228a594ba4615b6529d61a5563018e953ca29ba65ad0c2c9bb3e252ce329c8ef02d6b655839ad428e81e5639469e26063bad96f62ac2579e49a2bc616c814932279e4185434d8755a33341a2d8b917c9b8f26077bf470b4ef36dcdcbe2f06bccfc43ecd48740d9540a1fa371bf1df68341acde650060b4b8951b5b777a92d6b669a6c186cb4dca37fe6be0ea003c1796c102d37b2db7eec8d4017b228a8b2ed1ff1a16a44b7fd98b51f34b3f63d23b9e1f6b022efffb9906ff14f6efb757ff5eb827800ef57ed142b5502c980f49164fd5bad24b25512552a89a84b22aff5c8927c77a79bc317c6188763936f672028c0b933d52f7757f8737bf5c35f6c02f1ffbeef8b4d21b319def63b0912e19a91e8c63fbb8ee7f7481f7fa035c0ed69917b7abc3edb9fd317e62edfb66cdba6e461918f1ede6aa5a5096c4d1318f6a7be54270a58eecc2fe809b41873e198c2fe0b8e31eb2485cd8d2bece984dbdcb67163fd5a819e00e757f965297db52bce34f92e8dd66ddbb6edb73265f6b66dffdb6f1fb4d5f6c664fc1932b15f5fd8c9acf4058fbbde538ee3386e72f3bfc97d94523ddf6afad16f7ebb8eb0c96d8ee3b86ddb40342ca5da7e2b18d097f6f69b06b29a77537d7bc0f3fd3fd8fc7009969503e36ad39f4d341a7403385429f79de6ae7451d226b00f89d79cbeb052466b8b6d6cbfea4274e24e02d938fab8bae4b63d92dc8ad89f219322f3392ebc2bec51896e2e8d335bd6d638eded83b6aca531b5a50bc9dfe8f66c48916c3849369e646cab4d60347db1820d5650c8c64e2551ec2deea4101d1248fd106c01942e521ffa55fa50243982520a906e7a933e4b9b7e5b248fac926324962423cbc82fce482934c217670c7153341acd8b9114b265b6954a81c1a80206141851604c491ec964fecc74d2bf014ba01580b2e6c5d31ec52dfa9549840f41ad54216c101b101cd4fda1f3c1eb013f7d3ce41d5c2478550175b891c30d0e384eb01b7050c919418e29311b74d4a043834cca6c861d32f088a147d3c3a05f085d0000d34e940c5ad060b2b0c1a4896d78daf0c1c68fad9e357cd4e0200640d8fcc0a0833402f002a035412ef0a005422c18521364051fa880080d215a209c21803403302304344529d865189141803322a0e0688c2162209921124611300af085913247bc40d285014e90544b6282037081802d124046490914a0c502b26040d6085834e00a0758f1002c12aa80001511984202574ba49840142540418131263c5101272c802f6085811032308051004c4068224403441bf88003414e1872228482071d085202f240009e74f0819f14808080835d1f87c067d7c722e881f243051fbbfe0f5e816749dcb40d360b1ab49041941d2600b810bea061f8a61e31f09061c70c3329321a746ad061436c4a8e11e450c17103cc0907879b1c6ee800567991c06577701ebeb99f640fd9872f88cab77fc0501e107606918fb60f62012cb28209f105d1bedeb007a80d38deda15185bd6b8300387a53976fd118888ef471275df105d6c15c5ba58b3ebf704a92f42ad9dc069d75aaf50fbf381da502fa4587ae5036aa3678b3d3f364a04da026908c406387f02bd001cc51e203640a02d10280d50ea88202a178b67a9486c53d7fb6c46a2405be07c117ce886d579b65742895a6dcb176c59db62cdc69e91eaa661934fa422901ae0267d828c00fdcca7e59b5abebb059979b5658d8c947de9508fbbf291e8a2ddf26d81f948144ba02575d8b2a605995d14debac45767be5214a108680d90fb1da02cc051dc3bd37ead61b5e18e0b855a8cd9b2a6c5963db5d8b2966566772085dc90407a7e2491c51bef0f943e1f13f9888614480d900958133954312e3a5d66db66a9171e55559f8f6c28f6c400b4f38bf82504b353c36860258af1e144cf131c8cf9812200510449217415640a222a40a86200584556185d21021643b2886451002d8e94c00064926c8180cb8512132ca036c2091cd00509d38b08dc324bbe28010c13c2b080190c88318ed104051b387302192894a1948227685230230469a09cb182160d8d1654c0b48217d434b14086164871410d6ba6bc804a1a4e30c8814d9518eca0c6d31a3e6c41b111441b56661b2268512c18d18254942c4c532e28f1c216189868a28aa18b0c5533809162458313358cb1218a295723a0820ad60d573865e1a0450e6474e0a24a8d045dec508607309eccf430860f677e28030a0d106982d012420556d40cd10222d65c49238a4d116a18b175c46c438a86a5852c4c48bc30d594840c4a48d152c396294b5061c2a9891ca8aa70d9a1cb93171faaa0be0401c64a1822aca2c418e184d41359c64c41a144145ba460e28a6a8a2e5454550106cbca0a27ae1883451459575950a1055609ae2093b585165c90e9e1221fd1508c02e93bad76e36ee7e12fbb5ee08d1b1c188e9cd90e1e3d5e8700d8c940830d441e1f3f7a7c3800f2d3410080823c101a0af201911010043080108ab6110144381a8244a448018c1c416280a42407404002942860010c18a1010e78000910888004964ca0040a9850010b5c000319189934d1c00638708213143aa0e481271f480104211001141556589ab4c9c26c6146994cd385f9c2846136cd18a60c73862965d2306b9836cc29730493cabc613a4d1c660e538759659260ee3079984fb387e9c3fc61424d206610538869650e3189985766d42c621a21e71153cae5c40719fb0b03f2024a3046a9ad3e04969f9535b140b3e79c73ca39017caf5b05a4eca854ecd8e992562a9a110000001a5315000020140c088542a1509806622ee61e14800d86963e6644950844511aa3389261209a310600838c013023403052c200e2bc81b72899f9e7cd6fd94238a6202ef7316b79e56720c2df59f15d4193a3422d7f5c7fd6e72626066d5eae68c65d70846f165ad570db2644f984d2952ba1f4e0e586ca8c371cdb51c4f6f77d77b6616085a60f624cdc9e0dc6c06f929dc35e5b3213203a3748268a061ebb5924a00487d941f763060fc7d3ba613e0a555fbdfda1f2bd8633d15304cf0398122568d56bd3afce8293915f1dd891b9ec8eb639b13be4a9e945db66fa17a9b3bf4a9e6e04f2513a4d8b368716b6dc3fe600652f29387dbfab43bdd8c698d5a0cb29b303139af69d500d30ed69d5a0f3cc21a78306b43c8ee9eb42301d35d3f111b422b84340c03e52ce0800c03c5d1aadd1103ca840326ad89d14edae928aeddf06655fd8054580bf7fab038a354b85f296a9918481b5f28945d9dffa1c53f85bee953d5863a4601803ee49643661d45e041ff98531af7f5613b878f8d5d52e46a3e2865da20efa1102ca37fa4a4e02cec7d743f9475a8dcaf0e14e6fc3f4db09727d561b4b742c5a77bbacda1dc07866b5a3a32988de12b71c0b9b48dea7830b802e65f00dfc029ad1f82f5f7feda24371e01287d1db568c0255e39d00983baff1e7269ddd2618c5bb79c63a748679a82debd2c32c79b9ac3f2f755277b8fc2ef4a11311a5c8c0e2a0560a138217524d607c503ee1a4d9efd70ebc87c96655eb7040837e8ab04919e28a6c623b96b0b54313a53227d26357a8ceeaf5450a9699dc13a7d5bc691205c0716e5b6d42ba580d86ab6232670c5c8d1a06b48a0d346af5be24a4a5440b3e93278e1f1e152bdd4b198efd6f8cf45f53ad1aa69852b31c8d4881c38146c0b028b21603bf50a8f0cab564026c09f369ab3b91f7c962e517675f7c23f9f3c44b7c1574b2e6799a58d462330eab8c25dc34d6a9b2698575f9c379eccea95d9b3ee5c14cc0d3cdc078604a30c0aa075d0437c5c5d3c50504ef991ea190c5ee833435e538c176c606662cd193aacf527ee6cf4fe6a2852ff3d025d218a75801f149a5484cc8d703f25ccad9a19947fc4b56dc33cc3a60a2d88f42a0375cb49e7f4a18c5f6ddcde3c3b479fb9832bbde149554f6f0d7f1ebe1f3a32f3d722c90bfbfc9f25d95ee9fae61af2f68cf847731a078558e5f9858d84fc4628356dab389a8d38cb6d26c8fcf6311a43a8de227c46dba0d34b1daec67cb564618ecf124c93eff025b4955a2d3f738915c805796a65e3a6e0a7674ea6a89bcadd5a89b3be58fcd3d69de8f59370814fb7ea02cf7f1b00694e9b31fd00fa807b07d10fa4e9f0447df7e93033f2e0c3c36365993e1da49fba9173ab4eec947c54e6f0f2c184d855e9725ebf48be60afa19053011a43a0353fabd99c4b43676c5610a55ea1bfa35ba5325a750f315f2f13d06b113cc67a18a0d547a5e85b02a76b01b1da7c35eb0871af840d7b91f2c60b1ad80e5351a6a526f49115c3726f0ede861559fc900d65b5c675bd0e548220760d68d41e127c26a11e1aebe2c9628fb2735676dcd6e423d1303d46a2bcee761964ca712c3ef1b58f8b12b74fe0bbec74da5bfeef9416f90c34d028ddbef4c31a6a5a39e36fc311c9eebc68dc756398c1eac625070c1acfa8dfbd737ca4d600064b03ade029a51040f6d7efb1ad94241d662dca5776f80f9518c19b154c8b064b1b87fba8981f0bb3ba40fae8dd4c0c74c2c4c2baccd0d9c97446dc773b4d53cc9a60d72383a78acc78d4e598702bccc80dbe41e740e60ade3c209b57cfcee2a097d661a57f9788353118e2e6944f81a68a750c34635025b81047c3433d011b8ff9a7c262bc1f383761486ba3ad7cee4ffbac6ce04e405e454e9695045dcf28706c5fbfca4e6948cf41cb353b9d15b983130a1099f708e693f8e1add347df153023559984cee54ec537866262c8088731f39283370ef6c9cc245d2e4962e3f09646518c53bc3b61188f5c044e45e91260fcf9b7bcf6a06df0c35902601bbbcba0a0da24986afbd612de7f7720a8f1cd5145cc91358ddb0bef95df19f6dbeb02135836a1f405dcf40b85aa04e6ed39e907429dec5e1cdea3472e0b7ce4938b47012a8d0755857b8e80ad7632944e3f322ab2a7fb2d56160a9f3e1358f8584c399bdd8b103afc04ef958704f4eb73bc1ff53b89a2782dcf13efebe0ca17bf3957df2466148761880605472c82f24f3dc662575c9cd8dca3e65f68a713321d67177de77e55a965644712ee600d17a760e724c5da0da5d41a5a799449b9370c1281ff496e14dde1f5069be1799405be2554b72d4bbb836a9e5b06d31288b464ebc5a6c76569269ff06e52a409b6dca59a37fc7a102e8d9c359d447614a880409e8c5fbc5bc7c3c46536103e650ea0e0856a5aac4a5e1147c4fa46e9d7eec862e76ba00664cd79aa1944130162196065f914d019bcd1b55a00d5cc12efc0b9f1fbcbf48790ecd4c5ac4ebe89ad469c4bfa4479794b8114f1cd04db45ac61aece26bd43c51e1156b4c3c499faecec5349a97c9304edb9dfb44140dce5b07cbdfa8abe5fa7869ff93e38e09b24467a9970d43c77e62aa7d2020c6e613183d3ef7a630ef56446851267735e272af9fee95ec17c39b3e589b41ae20461847f342c8d22c4b3c28d6d1d723fc7d3c8d9ea04365266ca2f6dfaeeba9662e91c82d820bc157e222f70abe265dd3ffbb236990c8fe485e66860d81286a402ab310950e700f60b1f4ac262a068b292b3e3cd558bdf128a0643590b7aee983c538408edc7dccb1a8ca5791f9ba5212e63b6a3bf20e51151184497ada94a07f3c1c2b4d0aaa2422b4217cc9e1cf4eaa66a8bce14cd267bd6e60d13fc343f221852206855b9f71d7428936b37c0411d29eb12fe61da96cc93b5c4bfee701c875e6e79f4629f42ed817c38abfdeb87d6be6d82af3a342e3ed8b8b341776b23c5edc42fc1e9db4de12ce3d93c9159b9f6b6465e2de74a3d496662d0290d8d11efbc0a94a7da4b84d63838671389ae4aee356740782152d9565383ea3a22288649ef2b7045c9c5db760e1b05e9e112b6e4b50e0e9fdfa2cb9e79d7204a42778af7b0fbc061e16aa4ff9ec28dd39a248feb2d4dea6e84cb2b5c6d4ce19a453c1dc51d0f40c3065f7913f7323b0e79122243e8f6e481cc5058fbcaad7960870327cf722ff0947a260c8e5f71c7f72670f7883d64ec1a2fc45c88a2199f84e7c5f49be80d1c1392259b7580268f38fd5c41b06d0202454ba5e79d5f6a98bb412b6639ff57020da4b30d7a13a7b6d0d86685a55a629e10c940a8d2f58ba06403abafdb4e916c697dec40ad9b6c2c336a1676e88c0f00c65e445ba53614c3064658fe9c261781e36afccd7884808c97604bf4d485be8198d19e4ba3134092864bcaeb80f29cea2973c17e3d7873cdbfe54dd48ad7d311002e1c9365e0cd7bf4ed9d94620f6528c4c2cf3ffdc6dc82efc1a9a1cedcdfc230ca473f5fd7e83ff62834d36791115cba1e96a503af9d223eeca1c8ecc9f830348963098ab221fadf84c87c2a765a45570d4eb50d7f830a65ba0157e842a23a8f9abd0c9ff73348735d3ec253cac949a5eb40bb5ff23568191d0b6c02e2c8925eb976758de3e6fa4d73c2b409207bdcd096c1f76a6e06b30217eb22772b8ad39bcc819f97f91124240384ed84733141a4b54d5b96759bc4e90b3312c9b7771e8f535c8986d931a0a9b365b101920956af64c19f449ebcd678bcc7efc5c73a92197f5fa5629227d883c4dced4b2fbeb1ae49de71f6d6ff052c815d537f8b087b7c6b0cdd914b88cc104a10355ac69f383d3e3d0456c1cb22d3772a750b3c1626011eb3e36191baf8de2c459599cefecf5b8602917f15c8eb3596847b2f1f21b58b882995023a5e7cac2767dce1a8f9f16a5e8d95b8445b4e949ba84932f0b90cd15320fe3d237dfde415e6ab17d9f3a3afce9cca17b5ae3a2e706c0faecee3750f125cc104d5e95a16e6e481da1c7991cb9127801e43c3e0ee0280ed0e1f276d93da76783df2d360f54962d0ca421812e4269b2fe3b43f86debc6bbda8179326201011e62e6fc5fcf48ff268e83ec4cb3b1f44a6e0e4080bb7c3f1bea8720e7620f45f87cf35dd3e05e80f357f87f70db8b095b917b38df685a4bcf59a4686a3847828a571d019550116edcb2812f7e9a04f0d6267380542503804048a6ffd2b3b8f38c05db4ae9f462cc0da1a963ba847b0df8a0ec775f7817b3a7a24b86c7e57a0a4a10f19d9509415089557846623d1ddf938e1d72242743114aeb0e4c23afe0d7e56638747dea688a4431ae834284bda82f6cd161c620f6601ddff296d6c65c4a754e09f5ca02692d57705c944924b46aef351ee4bc2ca11bfae85e06c1dc4c59de534875e42a14c499a5a0a55f213adf2d4da62c1ecd55e0dafe9756133e86b3a038b7ecd0db0f32de7e3af94eeaa0d57653adf62e131b085c757585a7e0ba0be4a25a8a23df3de50d8dad786cef7142b2bdfb24d4b1fc205f8a450ed9e858d3f8240ae1972f3e906080f852a926bf25315031950d0f1f66720499f819ff31da02143f676a5318a04470038a9f3288bbadff3e00e028cbc9d1077b201bbe547be96ff810736205ce889171f2749ad182003d0ec8c8ee2a82b395a41b3e8c90b48a937605a0d90a3b8da2b575fc5496e2a24e04a4c2c8465d34c99ee11cd1c7d09b3b97dc65837547222c25eb5f8a9b87095da22870a2b1475c9306f7134a6a23e3893a42f69249cbdd3bbf97a0cd4bda7b64a8366971b6c215494d6fb841a4116a5b0f9c7c68cea28f1c973ff276566544fef557c389b13846d89d572094f8786e6d19858c4538697eed2dd0be18d2a14d581137ac04a21fef59a7697c6b37abdfd733a1c7f5c9aaa69d9e1e69b6b494ed95eb4f1a577683e94b9bb1631cb101284c2c4c9bc394824e1c3354a8215b9f512147e5bfdb71c723a7bdc60361c0aa41c676d00a2b7db66e93eaedc344839167dcbae76bb076d3d1beb383d8b5406233dcf0439af87f7e86bd73d42bd63bd86d47c2c4d8c7eb223f86c400b902ec0d55e3bb744eb2fbf8da782a49dced8137292f34623b034ed6c9da3588b1ec938cdd0b894407e1f811d5ad5d61b84ce5f9bdb8007cfb3520d857f9765f62d8ddda5f0973a9ac2cd0839190a434e5a62c7f67ac52560c47e2a2edbe56f6fa0660d8652691841966f69d88856ac048b93d1538e7ec7012eaf9d3af9cb716a1c13c9e20caf1c152ca5465a1be6df36b7b05d738c009f4dd60d720526d772375b058457cee3825413b021663aeb17fcc26b7759bd0f5e1f1022d7623bc47ef50c86ea07c5453cc44fb9452deb8c11ee8c535b52901513b031101c28efa7dd0fe62b3d53bb53f5a6a8a5ed680413c2e722bea9e935c6919fdbda6d5ed4bb8f9b891f8f045b60e77ad31dce4fd096011ec46a95f1ac1b7ffcf39184ddd4eb7bd82e49af45c054f568bc5f22626c512e397ddc93e023e7379d357ceb73a6447e5bea952f206553409643bc7bf357ff60860de76e6716306127e580df9e25ce2524115b0681bb4344bbeb76f49f7591f842b1ed698e26b480a78f6f0c5eee593ff2c5a8114018755abcfc5bbd4f11b3bbc5590882f8cb82c1e00f614db9e6b7773ffe1cb84d0141a6fcb85cd7101dddf7c211de38c05756ebd0b378884e28de1ee3101cf398010e5242a1f2d58fc81bdb937e76c28689e0c743ed976bf23de71ecdd6f501adf74ba9f0e4f00849b98371b3e330e49506bc13a37c5520a5bd2c3b78c3c9ff1ece4dbb7c87c99747627de3941dd0703a1c4c19c42503ecf6edabe189d8f2ba864fa9f052585fbd82fb9d863217421de006d2200b4377880232a199ba26e7c39627cb2fd2d1e16c81f96a5b044878a8319ec215b2182df011612e3bd1e3283997fd82725181bad0e48d7867d3ebf3312aaffc0fc9b8d48f61afbb590b197aec69df6c0968b90ccd11e45a560ec4aec522bd5440cd43d3542b37aac71db94355e8cea6583edeb465684b99178d30e2de6de19a45224584c49cd531e2d81d3bb95fa97569d2a56c39e38c9e89e46ce130e6de1867ffb2e5803f9e8805734a705a699666bcc0ade326b6236cbbb056289950494bdd34f0d2f6ec26f88ad67fcfe028954557a8a939c42484bfde452b644e63fd2dd404e6e172088810431525f89f7026e8f6bea92a27af34032955d78060083fd40e44bdd507c011c4e68eecf9a13ff40031b102d60a7abee8bba18a57076e3a3c9b070b03a6ca59684ef810ade6638bde1bb863bedc0a1da6a8278429f41e138a6766ae122f2ff014864d3d6ca0e17293d5baf400209a633227e9e824737576cace05089c6daba68a0600d23d4d72150bcedd66a158e2265a85445830b5532a67e9f000436edf6ec90a8d2a3554a1426c38ffc750418dcdcb5db40c1241bab2a1181c2b5cc243f4740e146aba55d3856f2a44a050928486596fa3f0a0ed9b058b242e1a54eab6b910102148cc87f67d0d0ed55ab050444d2bcae8e142a58c948f07100176f5bdb5a8522250e2aead060c1744689df83c0c0369b9d351c5ae2b0b212092344638cbedfe67840e0551151c5ee111b76faca9262327e697e398f59fe54fe1c3e196f39bf24df2cef2cff0c9f14bf9ca7bcf0c709e9d4a03d30f960487ac69389d2e20bb9cb21c9f288f2346fc273096c34f946438d861c0d3f183e26cc20b47168e390034347c38f84180a371c6e18e260f8d8f0815046a18d430d861c0d7f53031fbb670c01afa0760822d2aae28824b125904b23b04874faa18979ddf2aa5a31b7b392c7c9f1d406517e9ed0ca538ed43bd82b53a4e23010c6a8ed15ac7b5abdd874b0f7fa61cf9a1d267dc9025c633c5bc5855a93cb13c5bfbed84e9eb51c0ebb85fcb41ba980c40457629d764d09904b9800ddd7060ec6456c11384b3c06f4d4da0a22b942d551fabc8ebb6e6d0e7accd4168b6449114bfcab358eecdb0c0ab0a07af0e4c840a755152d8af1cc9fa9fafbe5040d191a1d04ee13664c132867aa8f079898dcfdc1db1e0f60d73aa542b75e860d72dc2df1020cd8652a6ec310cb6f143ee63b848df5ab40b254ffad4f3f2a33bfe7d88a3251630d93be51cb333c6ddf6edcc6a862c3e450da8ac972a306e23b74e8275117fad9d89b00420337c66ad01104f15bbb5824a4c4c608089730b4b0c9228075365139fcd0b9bedb38704fe1c7c28c4e80c7965d3751e6746038fc9409cbf32ee2f0d3fc911bc6da33ed04c7155800a800929c3763ea3f2deed7fc97fdd3f61686b14126a995f074949e622156fca4c88333ae414d1fc8e6b0ef9b1cafa978458d0174dadb79805743ad61ae0c068c5d1e7ed40f1767232ed7067f004ea14575b20ca0f04898a73b789e1301394b4b8b91989f38d36f6bf33725890bae0ee3994de5f87c60b6b68fc5df2999055468af7e00003c1a99682e2bf05b6ebb6815f67f27ad51976159dadeb8de690cf2635a9f8ea67d5ce848369a1941e00e2f815c8bc6199effc3c70b000b79917fb1a6107ee7e2489cf11d8446fa1ce223eb29698b484d47468e3f4a828ef49aa9277dbde84b6f0fe436f6d95bffaf40d592a58887b1c746a660df8a694d0ac050a9d01e1b38cc73e80b7ddf7aceac7c0139de9883ffbd9ed2ed57bcd4b91e6f24b0aaf15a6dc124b271a91371c862575ab3fe10f4b963211fbe877e7f6f09ee3d72fc000ee43370d138c5291ed3cbe4c73a4c3acb9c75145916cc3fa9ae775443c177584949c0c7940090525dda2343e937ddda34467563d703d0e30d8ee3a0b80e8af320380c80d360dc0dc671a0b8078a7b001c0cc06d70dc06e274509c07c539001c06e16e304e03e33a50dc03e2a807556c9ee940dead9fbb2b051206fc950220a85b2067c91b5b9d3e5fd100384de83a9aab7509608f2a5b54479e5d0aa28d47495720adc03482d00844151c5da0b402290aa6100c45306ac1a805a4149032055cf4c2921dab2f2af9fb202f833649ceaa9749ff7cc89351331927b5c5e4bf3df264a899d079cd12a97f8fb655fd42c9ff4ff9996849e4a8ba90f4e7b3fcac9a9338525924f9eb915f56ed449dab2c90fcf4c88b5d6b52c7b58b257e3ce0c5d42ed969d565a9bf0f7860684aeeacbea8ecef87bc0c342438575f26fdf7515e468d091cd42d93fff6cc2ba306d20a26e0a4b298fcb7679e0c35933aaf5920f5ef313fa686099deb2e4bfcf2c41b5b534287b5cb657f1fe1c3a42dd1a1ea52b9ff0f79b36892e4a87291fcdfa7bc4cb51371525948faef395f46cd491dd72c90f8f5cc1f5b63a2ce5597b5b487f05f3957a2e2bc3a19115fb4094434904e5513d1fcc07e9720f58bce8c56f56f9a127a3291a103a03fa19da6a481d1b667639227cb94274dcc3f9200ff85a5f316e5e2547fc8d7a281cadb2300401732b8b42a4f28d77d30731258b5b647e1639700835fd4683b59d99a50a28e5a8506e2133753073b8654689ed0dddd208f95f159f51caf8abda5cbad49180528bb7ff87bbe4df882a563ce084310b3b3e8b85d559ae817785064dfb9bee6ccc6f8b3965aac4f4fc5ffacc6b04bf82d5949d24ddc836a211d4a8bc5d6aefb50f9e3c058a910a429a5a5ebee014e60014fd62ca0e52b2657c051464d83270715eff06f62ed35be36f0d5b534eea3217368f4729b88ab505f70d821e26754b37f5e46241b30bceed67a401bacd48bbb2eab814d5601040e0123b3b23009e84f17a6931a59688cc6b20992d08210e88561646c34968f540c471894321444c60e53ff66f4caee184ed262684ae6ecb0bb45065b056c77c16eba925a13b11b582562521fbf94873d619eeab70531e24714acbe94356bb91915c0fac77c542a93b488724726e8d6fd9e1a49216a7631e54a89d4da83b200cc283bd4d5731180441606e3d7cc53ed285a6580eb22dc7c814bb801b0fd45c3a95f1d881aeb23c85cbb818bdc1267304b300fa1931a04c97265ced83100e11f14e58db4695f7c1c8f9154906181106d9835d501370c59e9948660ad847152050f176cf790761b770943a707586b658461134187b090bc5d141d0b490e01861f715c3c5723190abfe31685d8a2f60e098b82359419927ef08cfa9f1257c6a0c43e8a1e375b7a460c2084c5c8c69dc9315dc12a80a46e5eafe083b67a826015c0ad9d26a66fbdbc2035ae9cfb0c37387c1bf329c9827c7fe557029b6add91d76d70298e123ac84fcb22ea6ba6504c237bb872d875024238bcaffdc7da628e79d15d5b93620315093de0b9da45ab349c77125e0025d3e14192ffdddbd78c992ea16c449f177c70db36dc6ba90540e44ad7eaec08310b4eed30a3df91ac1d72625c5f80f1e1c68b700c63bc1472d7fac01e7b1e1e1d5cab15ea14c89bb6cd3f14a7e2074df41270dad480aecb3004e0041681fd598297d441085ee3104b634c22c2b123744afdcc0a9ad4e782f5e7edf042f138c6300dbcac674bcb1c1aea0445cdeaf7af129f5d9a11807c3999068be878336933957d889cd239c8a5d84869ac317676cb639f552d1ce6872a78a7c307e1282e4992e07d906961041e389fb11d767dc59235451f269a33781a175ca40d697112c4019f772636dbc157e396be82e5d36fd8ce34036fc3d0e34f1824c5206f6c0f7ad4623cff513d1ae8b997598678ee300ce48f30125de34e5ec7ffe71ad0a71b18c0b9a297fe0db5c3cd66c66b940823ca88e66194138a1c93d979f5c5497187c71a826d3789886a1e6723ba6f82a1c11cef5893ca3373868fe4625ca454c482d179f2d961b4724a0d372e84e8e47f24c2c08c32569dc1d69dc6e9f000d4939d93d25b814ed3b709af4f6e2132bbf7ee55157c27c9fe51f9bc8efea51a8bb93aec27ab903a9c277db20b8dde60a96d149e539fade01961f450c9521889251468649401d99e3538308dcd721a4092ff426d1dc4e52de7a05a902bb29c8e6cb4c6b400021a4be749c5117954894d4bc38d041c2e025eb89df769703c125d2fb449d3b9f825e20e0aa4cf309d77cbdef8d99d7d19fc8be3c44b942beab9e2dacc55fe5dcaa3cbe4402a6a29edeb54433a59c542172be559018c2b2cb972441f3078cf0f478c4b3ea98573cc54b9d39c7a69c7eb702ecd5ba52deaa59da39c4e6db914b92693c743facf9cab8481815aac13f7d9bd8cd655aaccf55654a1fa188a5167a1dd5c7da4214970dd09aeb67dbd7e6de7b9cc72a491c6d0e443f655c03fb3c9d27585162f326ca2bea75cba0676aaa1f7ec5661c3f898862cba4d0d6390992b98d475930ad4219128f516753fdec5e9f9a3261f88c3d61bf3ad11795fa5fd8d13bbed798f3ae5c2ab572aade07c861c7199fe5de3e246d6bcd7685c0c16cbee624bf8358efe934a0443d68be4c9be174e730b76c0261e92439a23dd8562f1e627c3a72067ace8fcc744fa54ffcf29a98ac765225a52e5c64f165bd3171e2256103ea07815e661cafc66621aafb037eb88be171d14db7b3fbf322f2ee8ccfc69e40cbb637fa6716fa5601922da82231017411fd955f291ff5b60f9e6aca056464fbc8ec546f582eca333af1de4f8be44004f5f49e37d8629824a304d5736822ee25d045c4a955c42cc154e267ae73830f73fb4400ca8662a96ccac90561a3651a6c19723c0b279ec9a6b10c600ffcf6f08802846d2358ec19624f369fe6c05a4f5c5fc70f1737911e444edfa7d1b5c79630f852ee8593381c1572ce2a01bfcca1b7d0d2760d39e25463f917a216217f95b7480f8c35d1ea78fcf2399c6e8cc74486bd29a4ec7aab838a5ddd2da8336f85dcdca54ef3e71ad737f8dfb02eb7cd92a0bd07e861bf766d8a1f898cfba50b5f9da3215224b78b2073b94e35e81557b6a420bec86ac754f18d25a279c6753a20e9cd8619cec2ed7c5e40f3fd0d91deb6d5b695c30839cef5afe5694ee893bd8c98ee16837e97ff8619d76678fae59038a343171f6e48881a14ded0777b8f31d467ddf88c7396e3c28b5a0c0b1130bdd357d4f57543cd76bce087367ddb90aac059bb9f7ad5b7b7864e05dcc0912e5e001fbb32cdae097e6f7dcb8f8ee8abc40d111d336e43d78600ceb1654c6ee7a2cf58a117111ee599ca301f8e51d390694c6852b1258436e3b04ae4dc61b19948414e7769919d74d76466c0c5f085272b4aa891b5615a2158fe04e2c0bcf9947c9d22d1e7c08a194ed6516285f5b22743f1b3219755b0ef53d2de56c62207b9865319c97aa71205eb1a538f1dcc31bf7d1acd549d4316199187d44f553d8f4ca4b7b37148ab57383e182e2fb1df4660fc5acf0218b81df436baee404be7a864e0456bec5e71e16de4a6da1e46a3db9692ae2cf9b3eef3be15c99c5d270273c2822b3fa32a769a55b1bcfe708df6e2bbf6b0da0711953c2b8f0c994d21a2b6a0141ecbdb3461eed3f8ec0d40fc4cd5f41728ed510676822062f80bd7b6b3303fc0b6abd4c540ebe99cbf3cae1c2406285d4d2d8e196fe5e32471e96ad92874b4617179ffb70175fc3faab89ba677b890e7b54eecd7b940de69829815257d0d18828705ecee8d1e1ada10e3c4ca96662d1987e879c69c5fa8ea3006da4a3acc9ad13b02cf6c9d79cb094ebcfd47826f4afcdbc443e6cba6e952acd52dcb85b5600fed6f06139ad32680b4552d272c4125d6f87e8d6a10aa2aeaaf64b83f21fbd4bf11b7135ae9e7160db71e7c092d171641ddd2210aeb44428167e1b1f474942481d646991391424788d606f8a12e0544bb11edf5e53413b556bda8acf173b43bf0a80d59a65678c5435a356746fe56990bdab94a57142e3d472623cfc1d71cbf21da931ac49dc89c53c667928155a945770d529bf1335a7869bc80588461ff00e7a4b7be008851b841f29c2050a0aed7bf5d9c8fafcc42baa72df290ad1460150a57c55699ea612977c7200c375657df1acdef3a79437858f541ac3d2dc8702ede5f19fab9913ab0983f77e0f4c5c0a7842fe316c6094f303cc84707f018ddb5fab080a201762fe80d824b7be5e314a8c0d071e20ea23f470162765fb29875637c24725d919eb3c9748025432e9d100f2ff89c44757c2511ec3fa40c4f2fd3f78bb6640696eddff515e7e79e9d2d2877505dc676e6d8f20375f7c126739b5d634082f53d68a29b1929f526bf701604dca66981f86a23af3e80e264f2750cb38731807453791178c54456fca431418662feddc54784cc29a18e5942485f609b4250c7a439553b91b4ac79397712b8c711e8dce38a6243495c741de7f4ee93b3022dd89e03c0ea25463854c1c6c11c6be59a07833e5b21d671838420c4a23d66dec9149024d0425e86718e431fa799261669ae56685a03c2b8c21199162637f1effbd81bc538df7cb13e204bd2470b042f2371b542231ff1db1437efbb1a7fa53dcb25a1213c96ce28db42568cca10984c75a1a8a2c27176572da05cf340fff011c729c307ce33bfdbde6d7b315393024c2282bc5ddfc46814a12d41760ec5f96df39c397d54adac182132eb666aa8766ae9f5f680128105f99410ec7f50859c95f61c5269a63cde2bdd02361958a9f1ba3bbdbe5197113579560252aff0a57119a638af448cdc2ea2fb021e9dd586c6b519b73d974044fc3d1619f30f3e28219e3efa78f54990ab470b95bb035c8e01a31421766157e5544f5c5d615890fa801adda41379d19b1c5a3cfcbe92128644abd19ba41779d93590e6492c8e906e7454805da0cd2679ebeaff1f941a278e3e34cd2cb76918dd238faf48b943d4eec898381394a41bc3328518124d8b3a954089d52c9088ae045065fd54058d9bb60516b11a76bc3c24389a0901f80747210278c631e381384edd8308b1c7f866b30852a49bcb74411cf8fb2c1901729206b55b077c3ea573a6ff8d26e6c808942ccb88c0222670bf09b3df601cd76e344a20d53feb9f016cd34d9394412dabbd1bd7fecc750dc6aef2a40230633318f76019b0e4c89b19a17d3c63b6c73b3ef5532f67942bb4a7f4a16c16a0d60c412b311501d0d51f3a5a0aa8d692539b87eceaded56ac132e2acf2d9738ec4944a45a44c40a1eabf38f1149be81277190664186be65eb12f61b027c3d3a0c842819830d212ab7635d58c976c14784e414aae792c9d283302a792809b2c02e5db13afd385c2e6625d9f79c07d58f6093bb4653d3d0c172a51c94a49c0756a9b7f8533499bbf3384a925b153d06169c6e02367f8d4ae0facbc659ffd89c3121efbee219445f61dd6eb9a057e199a973627288034013206dafa58b194eaf76090d801219e77cd01df6a1504d5f57ea58d351fdc20be8a9ad5ed4f2ec78320c47a754ee8b0ec4617a3935ac5139d188a575c3fc01f52334350e14d65891dfdd2615658da107bb3b5ef1bd177828c96c3d9df2cafd10487eca304507ef4ef022b157d4e2830eaab088f6e5151082f7f43b0dd0a983acd8d50862058db0c3fcc3fd5863bd0c7578144eb4e42431c2c4d6f435ce6f795adf34e919c367bae02b5241a32e451c8db62e7a1bf275780b85e7e0b8996a0127d920398a6ba60531d7ce9cab62e3d12c634f9cfb015cf027364827718d40891abec56e83e4ab53bcdd1da577583d8b2ead4380bba0ac41e8b817b310254a56957e14255320257693c97fa87266b1aaca70d561cb397bfda00dee61f0488c7e01295375aec4fa7483532aef4c6d1750f8b9e2f56d1816fb3aa83ec428485c02f2170249b52d0c24bd5854c8e3a46a92ba5410b709952e55c3673f58c7d166d5bc0bd547b7a17347ae9cae38e121b5c4f182a955e286be5ffec09f1032a063c7d48784518df844fbf46cda52aa51b1591514f4ebc0e1260219c372d5cde8c922ef99c5e5f5517c62d73d0591626287b34cd1ccaa6d35159c0ffa71b16e8eb13bc702168e33ba90185c946dde7a7a08c46f79d731d7a6a0ed0c1201094fba0f53faa6155be8053aa1b1a7dd85cf350332a20084b86c4482af597e17e3b3920fa2cce942185c9721636dec466f6f93660b7464c04f861d9aeea848617792ccaa7c5d520381bb1d360d38b2794b1ec9d9aaa44094ca90593e9ef3d7f15a0601477cb852a8294bcd4545727e98fa5d138ecf05f86c6f8723e886985c09fa9d6491975fa00577529f7b638f6d086ad051e3d952f215771cb4abab01758fa1711ee5313270165c8bcfdeb63c8317068d9268b0f7f6f22108a16bf38f02697b873309489b038c6c40280bd28bbaca0486a5adfc90dd0017ae736ab3bb0bdd306b8003c5d413fa2809168bc451b6b61c310af53f64b4d784bb43c532ee440d5409dd25c0303b4402ed7b67b94231a0a1d86afbf5398a48a2c024ce33238e93e27673f3526e87da6bcf9a16e991ad0d13c81611f4d5650d77366a17de0462de76d02b82db9357e23171c269c65dc92b215864b5b4e91ae6dc23e0bc3643a90103b06dc0c450083bf1767b2875fa0c7c3e264b91e3a5c0bd58727282493c2f87f4af126172e39992b8c331ed13e5048e8fb5eaa3efb74032fdd44e007273274d3662ab306bf8bebdff987815ab0156a6b8ffa0da1c7b79b86ab5192fd30972b1c2032eb2db38e0809c44c76538fe910e1cd1a4e785ac2f5150a0752d584b2bc658c8a01b524d339a4bb970bb5b6ed43e82e986a1fc048f9e2a491cd9bf2c78b08ef486aa02e3917217c8b671c7b45f8c8ba700299ed127c3d0fd3f12e8bffb7c03647876fa96552241c9eed3782df6315a43252a4508f12aa200cc080c7e3bb8ee8b8810b8def132f395fecee287250f6e7bef415ff10119afcbfa5ecd1be4add1ab234fa30b8fe5350c13d8c17908e6728bae1ba4fc1e1c072b8c94f42faf58efbbee59de4348271fac73e1dfe7d33ee46b7558f5c4d20bdfbcee3e82cb9f1618256d501a2e0e9a81b8d8f0d23c04dd23fb6990c884b9e026590f985b7b1d31d6cad366394c811a88fc52544147dafcf8a57bc068a26949fc0c26256b9fbc7c3f503fb9630a2dad9f2802495eb3b898cdc6aaf95c1c70bf3630edd9352a5faafdd8b59c78aa4de6a33af874ed960854ddad1495940564679810673f13cae7f9cf014664823e5d40ffd8fd6cf0f053f6d4fdb8a938c9b6784c72659ae660422036e822910a608c50087de16aa0243f3dc44511681a42bb82d9d608ec7b59f56da555af749f0f1a524d28e4610ecc15817b9f4da8370a5f98e3ae3911b0fb12bb3fb1ceb70323214537a74f0516aa8726468636e5302645dbec7b1fbec1f0006efc71af65f4c54d84bcf7b33f71ce6e233ee13c743f169279595000270ca94757f4f6a3f2f23f636b40bd317fecec2243fbad6db8ffb3dbf1a50eaba69872cfe5c2e5eeb6c29d2637faaf37aed8639fd19f8bdc51f9b1341b98ea34baeab3ea9689dbb02572dcfefea6efe9eba3ef0eee9d9c569472deca19cd46b1040753a4967e43b4e22243ace19a2c03e5d295f28df8435253d1f85abfd4dee5736a31ab10e155d39544596d82845fdf3aff5fd01e9a4ab2d3409ee730406192df3f389f53caed958614f1bc1e69361012689030b0ee149b52d508ffd7c21905d1a9050709f6efb9c53884318428c4858d1e84bfd64d10f1d6a601f320ef75dc27ef429e329a90884e58fba1f772fc0f5dd7c210f3bbdc3ef860851841fb59f2a26d249150129dffdcc5ba1fefeb7fa19dbc64b08bd8e4410b456ddc15b59862bfec4086dcafdf66f97f538585d9ade8b4735f8d084c9407525491555cc01a798c5cfd8d6915b653ba1421e095f9f36d36d9d54314e842dfd3e4845af1670a8b444320281f2100b47dcaa3cd6e88f414716585a23bcabe91afdc83aa9fbb4d781f7cf4a93931f424cf7ad41d3f7e9f84dc064ce7c3166bee18272e8d234196161b5f3700aa67c2cfc2473bf94adbbaca9a9a5e6d2768fa521fb6359db929bbe74eff0906b27e5654c0aa82ce381dfde34df49cb993be982fd633df33106db0ea409144e9d8af5099a657d6b3e7048111ef0a8856b7028255e375a118f55aa4c75ac2b912aa09fc79e8ffc4b9ec686b2b7c5022ba457fb392bab81e9ddf9cf7919a07dbda1f41c7ee671f4473deafdcfb01f24ec3d74992d38883508a31784d8eb87d995275d791bf8975626935584fb06f55c3fee2769115e970228f6b7f4d1c2c6428dcdee9083a82026346f49d6f21927895cdea9b7d85d8e79b9e044d38d72e1c925f6e1fbd26958299c4a6c2c84205cbd03a12a57526383052cc0c24c90f62dbacbcad10c44de686572c99702552f8b1b37a9bee72d7f2e7e20aecdd73046c95c818e66b66e6142a8523679822434c4221076fb208746202dc2f8abe131d096881c366668de033d150164ad7ba27ba1a3ae5eaaff0b994323413ab7198536fcbedf2ff627a7cac37bc1dbf624eae3f8b7e8a8805fd163144ff5b9356c87e379eec00102d365a4fe0fbfa650f0708340a39020d484505342dddb0f04658d637f106642c9b55fc6f26933468a51049b8ad3e59b05efe56c047357d553e9f428c4b44dac044f4485e5c85f42a394f96532c795071021e297290f51724e578b741882ca0d4832bbb48dc05ff6f542601d9414462538b97e3df592c901a4e754b7e4a4a76ffce0dfefcff0d54264302a83fff43d7ebade7d0930f5fb038945503c360d5bc206ff5ee18369bc7aed8c57d61fd12f04fe29c8a97c14bf6b434223105a7694cc71d795c315f3e37c936a20cfcc42600d05e0d0b936a2059ad9eab76815c6a938bba286fad6544e463b660065cf476d600ff0fe641cf3e1ecab36ab16e30892ee8ad8c18a724b8759a7b718ce9ae94728b2dbdad7198cc3ad36fbd4eeb8a1855e14d989888b6d65b34be223d6a152d3757723621886ba44e380f2ed0082086126310996e82ec742d3d52045bea78dbd8dc37c5303e583f18db09f8e075586237f08860662393fadc0fbc06afc49a57ad50a7fe9e7e9163566ff93850b988f75a1294bc1ac150be1f449883bc9590124193dd51410463aa68afe6c1b29f4509c660f86e75dffdaacb14f93188543f695f0ac49d11380853c84e2edf88bd83ed99dbf9012f91cc251a6856a240eabc5755dedbb71e30b8330b80b41a75f5c40bbf3929b7e99a8ed341cbe01bc1f824b8c0701e3c00795581cfc9bfd4b5f7de1ce533f9e60106009a1748f5e1798be5b3184dfd696dbd4249aa32e6846cb5817da8280d221e03288b93eadeafd768f4b0d2055ef2a32369e6f71eff7d8db951a88c2c2cec294842de1a62ac0a7c47ecc6f3c1f9eb1337935dab2fbb8e63637cfe067084ef586d862e2e9a48d1875f9b2df6bafa846d10810d6ed6422d8e3f3115f8168597f6f0d7d87bdbc378da3db6a32d2d162502a0f9eb7940ddcf532ab6182f57b7bb62317ec7cdb6ec463d6c802747482951a55bb7842247aa2e847af215ea81e93afb1095cd315b839e4073a97f717f9cf251374fc192ac190390c66451f1769f2b895a63fe6092ef8f8d9ec09a793857ac85684e0df92bfcb6a8fe11b69577b23b0addf2a6cb3806c7c643397de7228e16ff1b4fd8f3722d5450027b652fc7c48804c71ed239b773c48b72594db00576172d345b50f287abc1284ab52c28b818b1906429594439344c6a4e5585a229b40c51565751d52e659851fa1ab908d237e649808be24ea99b0405e8ababe1ca765307343531db4187335b096c689d668d582edac7047878825840ed90a00f8ef6681dd759f34462992265498c09e99f4f779829895e02041b45d43b525bcafaf8e600b33fa5b4f8012059284992b1bc86bbbea350597a498abdf3effd8d31ec6852fed4bde085665bef81ba98b8c9777450c473bc033efc8b7ce275868d1ab9517abbd105b9fc2504db4476eb44203a62aa451ff06f8c38697b7aebc416cf000bf6c17772f27122ab280afed2a2a81705c7fa12754d087973f7011c960e17fa3cf4df062a10882a923b035edc3893ba9d2a77126bf1ceab18b383c53e3f0f81b0caca25b0ec797312a8d57c1e02c096979b40d9e7e625a06c2b6884f990776698c2a391b8cdc50feb8773050fe4c8112f919d25b08647e972010000d2fe751f230b254e1c2e7162f552154ee96b0376523227ae1e8f3602405e3d0d0769043b35c76ec6ca95d9603ba2f8214038b98df3d3e65502f5f3105616d003b5d22e35a91563fd0b2630fbe67a14cc1c130240859c88d04e194c0db43c3cf40cb408ac76ee7e8a761c38c3e90272c712d1254a4f63d9dbb663c7e4b6b7c6ddcb6f9b45779f73fb6b748f1469e55c5970d2fe586e601b75ade37bebdae9fcde5cff7ed381d00f5c40d1876f5b79051c8c040aca7324ca7f83646348f48c1467e15e19cc18e4470b2d4c73acf9d72df9e3c8a329b951ae0da3d18da13229b40197f94e5aac6a58577c7be682b66955bec4f2a0c8aafa07ddf5efcdaec4f35b793f17395d791780630cbf6fc5fa5f1e5d15bc7baacac304111f49b7140c2733d98166e027945feae464ab690e085f60a729981d8975e68c2cdd5fec1ce27e964d8f7b5d8a0a9c23eea98c323b36287297a4bf55a67a6133a7ca4dfdb90d42c8b54f4a11f9e76e4ab3858a3828a9bddcdaa6552b7b64c2571f0464898c05b6f6a6b747b4b5d30c156e5abf1f956f6e26914dd8bb0f42cd8eee6e9c5f2529d9e66e27a61d76e4e0ed4a0196af29ba99ea099453bc7f5529d9676ed2d80f9f270feffd5505c99fbb99627f78de6cf8f75728257fd66d9ab2878c7c52597a1a983d52152027aabe702fde2ee6f65f1539d9e5b7a5da9dabb705fe7c1489e497bf9568f7bc9e1d78f3a12493bffc4652fb734d6fd84d8111480a44b634bf8ba2c214061c08c5c742db378beef95f8636321fff326c5b249c0efa1d682aff0dd9557bfac0739484e920afce4f1c01147ed3661e81413e6fc4c584a48ac7a54e9d3986cc87a81ae2edde442ea4632ce4d0a6929f5856a6af0f56eddbcd9ae7b8a668129fcd2d23a8c9bb8da47d4d16ae987099d1db582c719f7b87d02c20cce0ee19113ca715f61e08b0510174da6ff7d18f7956db67fb09d7987d98aad837189535117a8637c0f15d67009477cb2d6ae2c22e01c5d8d892456885dd30340a6e327eb032138d28c4fe50594e6c164419638a1d74c7afd4132b53b7772d8aeea61ce16159c97867544ace78921f2c1b4168eaf6506cd9514622a98eed4cd1ed3ad55269e2382448742a1c7689484db4c011bafad42dc73d5d64f93b03097a0f9ae5886745283616a789d2f1e5e0d88852acdfbb920581066f3d28336ba02dd0887a79f7ef3b2b055f9bada3d5541f4fc7cb708a3a03c112c19c3d868c525e4f9063946c7740195b7ca0a9e2ae213f4d720ea413b9a2e3abaae397ab33b06eaace27b8c3dadd840cbf5ba6d0dd6f19d8038ca627b818e3fb9d4951c7da80ed3bcfbc046910776a87389f367dfcf3b24c0c1312f8973796161ee298349cd2b5175cbab35f89372a179fcf2ddb5b798ec6f9f4f6f389c69bfe99a1394020321916afa277a4bbdf2486bd5f17d1babf8ebd59f4f2f8bb3bb7719ea973d7edf2d2871e6c796df39fa54cb17aa50e6a6872d4eb9eb8e8e8be4a6a24cb590ab1c5e517c7b18625a022387c174d22b6618d2f582ba289852224c9fc69cc3207ea084305cf5fc1301672e2a809331fa7ffefa04523a67b6fc43bd5b5319c4ec73d10cf44d74efacaf7939a755aa0a683a1aa5db6388174242194fb1bbc69602a23241a81cfe574e5245c556dbda03eac64ece5a5b19461225e3006aed1ea401a5137c07a50dde03604889e7880917cd7da84df57e9e70b41bb5e2007180489fa8bc11e4e8b5a407ed72ae35b15c0df7a0d3ae4a532504696e61ba6f9bda0166b2b8d7fa49ffdde1eb2414418e1df07ccba396dca45d2cbdcfd72ad66c54a74f9c87d2d8fa006e1ced177a8645d7b171f1ca95789a8413de4536d70eaa16e1c24cb1066947de1f78a3bc61c60d43a7a259c3fac2c88ab1acd05b89d7fca604c872103ecd34120ade48c48ec79b0f934c07e47b167163ea3fd0e07587cac6b01923b6ab899ad380eef4221f5b25d736e590f5e6754b8b526b3f3ef2b0f3607c3ff3e8ce465b32826e98132d27039d605b9dd9879f12692667763020c2f10976797c03cd1d17181f0966b1c28e3ecc02f21e5ed3c5e06af70544eb89ad87c4528a41142a17f64ebf53c37b596fe249c24c05a82089e627cfd0833878b6f0e42fa30154bad0e8e60d86d917d300a5813967eede2371672ac81cecfedb7fb665c905b4b82749747712bae563e28afd0464039f17d232d581f42e2d11d6fbb86ecd97e88c260eed466455c4509de45dff9b147036af7b13f2224bc02d95d399279ac5e4be329a76bbef6cacf5135988aad925d772a87af5a5edb0b4afd1250ad4a816ddfb33502d620cdf8af3cd12a99bac594440b70b449a5b9cc554a2d346a41f6a66573fddd506da59e98bcda9f3fdfa4f2e0f296c427f320db8f664ea695a14c39e5fc6ac557e06d6082f62a185e6b46028ca4cd3f5bfead0113ad9f5c5481ded52605c2253d698e7ea006260b63377ee59c46c62e8f88c628c09bbe306fe2d2976946b51eb0c6ff710e08db721f1385101ac163a52149970892eea45666c2b78e941ee62e6ec7d9a66828620fe053b607fb5bb1634a5f4a4890028f14b8b4a835ab988ccf2159ce73eea956810dcc221f6c88cc43f70a8724c6c748123940cc95ab39ad8d70e47aed04d303f3aa07d87e83528fa008618157ef03ed4dda648927cadc3ffcc0407f0b8d66c80a6b158115659586a5ecd8b68814d246a9fc4674578da4299a27eb1618fdb5bd4fa8d188b84116d4e4df7fad24b449f54d696d5344f4a3230b29e5db91af1d6f2c6249146b1f09444db30add7f8e88ff56644e834ca313fb7cb25e394af3bce32102f9b362d73aaa16b9cde0d4357fb3e5161b0b4ddb7c351321cd904626be85561da98739397c20339ec68289b5e58b83e0467a0ce8274e6832eb6e43650224bd2974c867ffcdad9440dca8c9fddbdc8b6fa701206ae776e55908691fd9a2842dd136482f139e1afbb4272de27e0b43df896a91e0fe088a4b2c2bf2d33f11c30c68a19e196cd3ca97331f742249d85e8a35c6fd685f28fa3e66afd842b8e28865035e071ccb12f62dc7100ef6952c032e1178f8db0958fd2b20fdce1b5ad8c04d65410646bef32a6b28709b5d8166e302a6e8e97742e158b353e26b0e9adbd6c951dcb4fb6155f24c93f5eccc17bf9f20b8751ada81f2a1d1d2489ecc3df5e8bb7c288fe91be75c22d6a4b3a33e58de84f6bc2b01a637ce05cab51484ed0a166bb966cc23ee56431200c1366c6f18f4fe64a382aeb357c7c9647c9340881f6ad95b6fb66b2d3e33e6aa1cb041ae66024b0e03ddb2fb17ee287be38977d06c267ec9025bdfcf9f347bb9f1490f2e492c788910cbf486a1b5e87588f4b4d6c31d4f140be49b8d0c689adb3adee6a82e89e9ef1b96b3f00a4b3a81853186140aa4cc599f61882a55ab5cb8a818acdb15a6e6037f85eb0e411a85ab26da0f994c16cacddbd562dd5d9c11b64e4d297bc70cf39c32c39e5b514f30442637573a2d5d5bc45367c74168e68a45e830e72b165b66288af8e19d8d2465a255c7d966a3ae693f92f20269ca9588f4ee5130c91f8cdb4820d022723fdf40b916b2d1c06cb2c9e5708e35c726644dfa2b90fe627befbb83b30a5a59cb119d0f6c663d7b69dd5b4bc410ce5050685387610f70f983f45e5d798b0bc6845c6998d7888412bf77967103b6e399099a41feb3166a887ae81b1b4e649341c9c9e51e6d6108f3bf4ad754598ff0821673ab777f87f861a09fa27096be0ee0b098377719fc331bce8bbfe02ce9e2b24f767a56402ab456f37e0eb21200575135286288306fc9c9dd4a10ef4572a7341cbeabf61d6d5ddaad70eaee1a23ddab6ef09b9c4d1d61807439282c37c798894d692030d16e8e98b9e18e1e7a28934b626b4d105e22494ce31642600badea37e18b34866762aba2c8f9dc4fe641e99c38045b426d6e40069e08378cdeb32d0abdaebe8851edf018661d4da4f875ba70ca42fe75b48cb0edb58e8952f04d181e5ab76413902e26fd1a0e93382b2e87da7a5aa1402b94ff02cc9d2a13d9b56b65feca5f5089f74598e42a5c91869c25c432482fa14f218b60dabb5f6bdfdec9cd2df10ad2d750570728fb69e244ef6734612630215ea29ae0c0c02fade927e1fd177ef2892b95fe9392f13550ffbe0900c9a6f7603e2cb13a77f70ff1fed2b4f4efc2396cd00dcc344809d8ac9f9b0517ef6b9839430a1ee307687a72e588fe8a926da4aff893636ca2f8ce337c7d8e30e7650868e440edf1e1f1a0efa9810626673372228e1350ab8179ea03b9dfa94e9995b3a3b6121418b48af77a4a2c087fdb014601fe736ae80cc26181978f466b221967a2ef7351d60c7878c2353c8141a334c6ce5521b8efc5a15a0b31e6152ebffb9dd5c3ccd35a5cc4d39979a1db6c296a171b5b4e62a97000ddc05b6f0a9e93590eaf8d09468900a2ba254a9dc21c8579009c427b485e96406b5ec6fe0d6ddfb165eb5714aa64036b1d99db667b8e66cc196c64827d6d967c693c8bbc9015506b93b05b317b76ec0eed64889fe618dff9aecbda004915fe88aaea7d9d06b4332245e660571f4fafe4da9e84d32261fb3216bf3c2355cfb18396844186eb8f55827beec0530812aed470a68ab3fb9442c9de9ef26b3a405bca2ad5e97e4c352b7c45cb32e890c498bf870804eb68013a0b3f8ee810182e4aad47d1d65213d3ce905b966726392ce69cf3955198bada521cdaebd77d538b3659c6ea428ad96d7918ee5b3d5d50289add16e33378f28653fda087a527ea08f33e8a1b7241a3e6770f32f0d9b78acab098f8eb1529553e88daa6d68619337a1651ec27659ee9683f36db19086fa73be70e04548dc10235a9a29c18c0fa48d6c04dc134dede492089619a1824587f1a9526397483f13dabae8f2b2172496b66b8c5d860d940216313742f3323a9e3c2b03e59dc7ececc679c49407b056d6c3806b9c8d0123913b6510314e2de36953533ae63e76a5d125dea4da9c5ea42e9f3a9e25599d958b216c2e035c13f04b2615aec119dcc812a6b17b1ee4a09340acb1846521fd056a366c9c7479b49c20731f886a56c21e0796d5ee19c0b6fa4547fd89d653c56e0cb5f3847c15b29eb1b9863982d94f20be6507823e57ac3e92ce3b10a5f7ec1398200a1fb9555ac267625f9868d5301a25969ae2a8d7bc0d19fe4fd8730eb7923e30c06e8fdacf345d2bfda7adfa2cc5652b8abd4ebef29f3190c3dc36f85248876fa2a3387d544ff00f64df30534458aa0381028baed1fda57a5b329ca2a628a30e834c6f7e09af9178fa2eaf2fc49348dceed4f9417717142be3019b94ea5a9feb4b2fd082e1b099ff8350ccbb653b8370b4f9ea4ee77cc01a4c9f4894453645944cd7019e4a09f647024e843e4a0a06f1b639470944c3e9b5f40e28d49858f86dbebc5db762bea9cddafd721e09b8762adbc1eb3f8c0a026636e1a943874b406804ade017f5fdf223a380321c5c98618afb3364209ac28d130f3471e4628473d2a3b23d6329bb11e2da10068d1d6b8374bb4f740919bd7f8cfd9a5de82236dd38332acc8e4440060f8be477c7209a745a4665b8bef4d7629a18813d7bd24ccbfdfed9021c0227a7fd1ac755f644eb46bc9d18c8ee4da56d2abe4595594fa68b54c09502fd59694cbae8dd33929c59fdf546020954bc63472b26f28b3e321f306c91256be8c02a7cdc99e6b43d350fba9d24df29fc8a93030f93776590a357e49ae0d03c40b5b300e499e90a2022cb8743b9e1af3834b633c8a8a6320f34c5d9ca0f298c6a17738ced89c2b4a1f826a3aaa76fa93303a979e3a04250ae7b211cebd2d262fb4533c9796e56d465e1a4f4db56c5027ecfec255186b21e31b5991f615164b2682d3706374d6caa680423159fea37b475770ec849f0534c9a516922989aeb2e61bd965ded4210a2b28e7fb21effe49ce119ac426e181f848bdf3fe6435bcdc9e114b5a6b0576adc87231ba064798107f311f292bde1e62a0f6f79c33bc7f61820d90d4ad01180a4a7096845f8ac9c2dd09c941843688cf3168216ea6e8bd5203853f6f6b5ab978950258a90b2bcb637ec844f9a96e8a0dc4ef08e4327e8e4a2ad493e1560b2da6645792b08d316c40bcc6c2f442727679eefd8fad4c19adb18e07f8bd74537f06eb9530330c0b992a91e0d95d6e62b3acb7be3bfa50ea9d83ad1d00a0b594a813ff505bd01f55381d386c0978bc589cb4028ecd7519d91144ca24b8b7e699c1975c5d5193d697d0240a382051943c2444c1a58f5867f364cb8927cb55b475c0b445f5a91821b175456bad3a4617d4e09ef4ef756179c06611eb4a49cdc0be82efeaaf5cdac56d3fa1507e285155d40212bb8af207b8bfde03c4956795f187a121cef8ae1750865d4e1914bca7710927441933b80c68ed16cd388ec6c8a132573a1e7abba1ad17e9f8e0b9a93c9d0db11e406c7983c42e394f500bf20bed9cfd781c9d57c2c3798e3b52722cbf8e603cd82c3b7692b38a02f42ad838a2ff4930ca63b8fe6cf37a56d9a48cf5878d23ef04178bab4855283bde449035a147bb4d108017f1aa777a72272aa7c389fc5a8db2170fd820991d8c5070834a17edf818828da398614b6aafc9629e4bab6c1547801a826dccdb79f78ccb38b8eec2872c5bc7d6a605831bb2c67a8c8052a65a19eb049a63606a0c1c2b67d82685dbfa6a9b3ab76dacf611c516c62fcfc8de84825393a6fb9d42ee38d3fc3c53da8557769b5a98c6528c5a50146c61927cea5089e9c4d596b529e74ddd3d9d13cee41bb744db68b753894486c6e897c2f5392e1baf303290dd72a530b8192e81c25c66cce8dbb0ba02196aa855bab08ab92774f8cd8262c3ef04f0658f30bf56142999d0f75997a18ace4045b5d1da4716ec64a3b3725e6f252df4134b2e405b41a06d669ed010ad204fb250861bddffe08f5486b81a01d95c5e5dbb01022cb05094c981e73a5c9cb5e9e5d03df8d04cb8129731b93d2f8f9916c2303010f75a17ba8f54f05a5508380159ff21084cda8d5a55e31ea9784b666c4306e82a2115d19f9ed4979b3774acdabfe5bfaff6874fb5c24e1053b42fd5892a9bffe38901c8ba110319cfeb39a03f769b67aca52710c7e88fd75738e1aaf37ed04b2b295326cadaaa6dd7346e530ef88484b1bfa769f50f672b3b82feb7d11e946dbe8c050cecb6ae9a441109ea7a17d7ca98694e4dd149d1e292123e28b31055f320b0f4dfee8d3e6e2520ff74245e1bfe344a8572c5b441172adc12a8f33b393bbeed8c0f7e2624b7bcb57b7da8a1f53fa5c8b599b7778bd85cb1e8b90cd987dea1170cc900c5e80db6450acc99fa4c8dabb159ceb1140a9d2aac75468400494e733781294e93b38273324cd3b9260fc7053b0ba0c69d78bcd230467a9a4ddc5d8c06fba4da7e2e4983aa63498dd69c04a5feae7a93f49c8d25bf83205a2cc0f6fd176d32656387f33c83ce4eb96275f532358b9e45bf6a2acfedf0147f17a310f8549884c3bfd80eb110ec8ce29cf41272220fe960ab2c59964e20a9d4d2186b84b560c40167412c0758c51503fd0ba4d3ba864308742c75b05dde782ef0432ac37deb30add13dac0e6021705649e82d2cb8e30b23143e04c643738ac69cdda9cd97f97cbfa1baae2b076fa78c3feccd32962bf2e9339893301b94f30fcb31e8564afb067320608bf2fc177624ceb4a1612a5ded969beec3a10e00b84db5e8180579da0abd40dcace57de8705d80ba468a365ccd0c8c29397fc10a58101a0b71c4524f8b8e3e85d6b720f08507542e71b29501daea58601a2f8c9ec9971cd07b38a18f3f2bc68ff3b6c7532d9de6c7f0a9a69637f427f2bc787eb8ff8e40bdcc9bf18ffad53c3610eba57a53abff388e44db0da5db1367e80b51fa709a30323c59ea2e0c4bb7c9b4ab335648d49149bd827e9d13fc7e7c977aa5d38dda79c7b9cb600b73a115989527e80f9759ce975fc544bf5e00454763bdbe29c47f2cc7d97aea1368fc44c3fc5d9115372a9e429188985911900c62fb737308e290cec5dd26a37a1d835414d620f17167cd15dfaf2c91c911c26ad604b79195bf96023745a32cff21320bd862cd4b8c382d92e8d1bd75e120e27905ee7e1748507fcd0fbd8cc395c46c641b4d881e1f4a7380a7abf9d64528ae1a0bd256c41baab928948172a5ea1c50862454782b70148575c771211488a495cc77e969c74b4fafe09711c6d7093ce993e1f190e4bc9645352354517c34bb8ca173ac6b7f6e91e56d16a6ed899020cdf524af9e93dd333b09b48764117ce6eceafa4a4a13702538e667f8b04e99ada0b28902161f7edd4f0aa5d13be4582d4553e409425091f71ea261820277a1f3b392e5e7bf6857c3aa5ea07f07211f31203572012654e67223fa74f351475492bfca950119b4a456c0d9a1938a56181b6ece68e5cb76509a6ff4ed0a797d5b55536190baab4be3855014104c153e9e00853e9596f5ba6e5fb6ba70a6c279c878609faa35744aeffcbcf3e230a0f945db6c042ca2fec4ba59e8eec387f50a2dbf815c10a229a659ec44b63b3f866979d17c97ab4d34f0e0819ae8f627bc5a03216b7c1738513aa8905c8763ea82fbf15d4a5b2e543a30a913880f81702e8531d9f9e3ba5a2aba1cc21a1c1201f9d6d3984d6be271c24567791a708e638ec311843eaa32c93b89971d0d0b948d414899597b7808d7360cd5cb10eac20be53dbfa3ccf25984240e3accb26ef25a55a3d4e40f3f83b978032d24a33a07c78b3973eb5ef8f7dd4c63c8c2fcad8cead4589323cdd8ad1a4ad21b9d087f2154d954c959ecf3377c2e3665e9adda15310fc12d38cc20ab519f7ae365737c9b6ff33512a8f82efc44c9b171fa73f85b7fb8241ad0a4d545ddd6c606cc18e70006e4e0d534815d66d7911161ba83add966935550e28e1d90841a64e494143b21c5ce32e664a6487df95e2aa585fc49fb8cbf32bc2be86957dab37855bd4c99c45799a1d39835a02f47f4bacb97aaaf3b6f19a82816636a2f80bea9e4942e18087dbe52b1ec92a8663ac03fecb21747e7b0d2da2cd2e9bb80cb5840c0c27960a577b4cda60e26dd948b112d9ae621d81e2a56f2ee0aae1a270146179a6593246baad2a5fe5e65d097c66e90eef4d04a0c2d4ca9f9863fcc54ac54d9065758b8609d958a5c65b7c49de60847170dce5e6edd6590943189853c27ea5d049dbb21ec523d46b5e0d14a8f528ad5c750ce35580c3a61b4a6e6ff68a6326b9677178fa67e84c60b15998e339492af73ad20005e7b0ae34c7e1146d7ecaf4874fa4ce97dc541b26aac593349b32020a8a6ba57cf188cf3607170fb101f86b4310221b0c20fa290d96e9c42111a286e64490c3dc45f2e8dbe1546fbede92aef6a51fa8480fa5b21785f59571792ad4ca1d7d6b3a5117b5d20c728eaf627ddaa20034a08e10b6538096375847427270c646ea1a797ba6880a0dd36e5d00490904022f9643f0b8fffb53ccc01546726428cfde3313d66d98468914c75230fbd51e112d38cc50a9c27e6da079282c651f9eacf760e907890bdd26f1838a9ff1915e20fd357008b0a166934f8bc4f83d8a71adb96ec23c6c25d95812a28d8924e8981bad767ae1e8e426b1af0dcb24f7306a4617d25598e3188525caef981c4dada077696cb01c2d3edaa301844ab3270a22addf3e2a8b59927e4faefe39db21ea7c8973ffe32ccfa1a245895c513d8f329c6a5d25126eb5e215f53554dfe601e5032be3b7725907d4c5b9c3f96995f5970c6a2e353535626c7e3d8a60b4f402efd6183a6cfee9139c5724dfe2bd5ea8e9c70c3f52b2e91a23bdea04675ff7651c06dcbc35215e797ab1df2a2ca2fd6f0c9aeed0700e01f5127578e807c3cc1d86d41f79f355b0124e0af71bef97f0b3bcbd17cb0078548b656eee0daa5cff37c2298827e7bd3b03050798b2517c069ca36c644bc8816d6c0875cab47d22fe0549d0bf73fbcfc44bd25020e502b0ddd32022b065a4b9f7daf4964d86fd3d8584856001e6c480cbb400da434149dc4b71f6b0d234497f840b36ff8c1da4638dad478c276773ce83ec65074ffc67ff750c22b449b4c40c040cb4966e9b7e56456f3cff643a34a5a135f976773473fdc3e159be69b6b87604e4b04385f9abe759f4b7a5859ce79531880c78018b2277113bec70c9fe48693c53402fd4c1f8cb8c4a371be0c46cb074312b2a2a1f601608bc56d09eb47c9010a0a0cb428865d521ff17b757f6c9cd25a9cfb45d0cd751bb4676869d73aced65105a1606d94c9a023731cf4c01e9dcfabb27a059678697ffd48937d81dad0bfa98590f977e248b39d17aa2d9fe2edabf51a2283f8583e17bdb0241992fd89a9007f0a923ba675320a45daf41b7f0b00490a107115362aa16f1570b9acefbf06645a41a3c868774c7249ae2b77375c94e93c4e9e2a29d8c43a60af2c1f9c3dfaa6a234810105db3795ede906dfc19b7e9eda26225e4eed4ce43e4a4e9d41a71556f507e78b55c018e6a6f6997e3051bda142d4b84c530181b93920c8e258c4991ecbcc8a06eea8408184b88def4fa906f59d2eb096532ea2ebac20f4cb79efae1814086516486f35de3459bdeeb8d9f12d5e95a08141638128c063bf2b52d044773427ef5dee7360270b4a507bc36d37c8881f5a86a99ef3abf51594c9bf079f391b59464c96fc2319644a5be30a1c009ef9c205b86ac903c21c11092daba944714d2d997e18b2e3502a7ab56661501c4c7cd210678f42b6ede3005168d7b55e3c5e70f8770243f9e1be5d489b090f30d9ec24a31eba25be0524fbe5b710306395bb930f7bd3ed4ffe0e2091be6495f4a40ed063bb2bd5ee21193836273069e9a82744d37c9d31b8d10d8b9eb4a87d6c8fa47b579519c85ff500f592df69984d18d40ecf2f3f593aae4493f84c69a6f3b6f09b4dd9bd81d3ea079234cf6ee08281cb5de7c6f1894c5d35757d598535a83aacf5352f447abbb3ed109c1d3601122ef7f6645bee1426f1039aebefb95737363a73999fde4655c093872dbfded9053c4752d364edc0a1be8668eb8278004bc7fada6e1f286512219da67f59ed3ee4562b4c3ebeed8c9522d32db4374feeb79dd4f9256ab82104d13267d0d5d05ad4de6c21ee569f310158116189063624cf8f687d8da80d2ecfcfb5390b568c8c941bd30b7d7d2ff1899dd792138601cda5046576ce52b82a112745d6948cde41b28493571dfa3b80b0ee792468bb009e9c9ea63c6397242dce0cc71666c25deb59e1b4f54ce16c610670b4343bdc5acf74c36b32b5a06f3e6cee020e8493935cadda985761b567cd3b394ea7a1a9c19cc3aa64fcf817e4a96a7e7fb7c81f6860d66213cf187bbc0dcacb429deaafdda5757a41d02918a122103cdaf0aa6558747fa4c32569e9ae490913828e10be0e6956c7e1317ce5e46823f9df6f275cd7eddde90f2ecc1ad638928e4f89d38beb5d7d661d44c3c099e22d5af1cacb7ceb3584d095a579600af5e8dcbe0aa166024377debdf49cc82cf03e2b786fea659f3e58c55917ee649b530caa93a3dc78abca9d0addce4d17bf5e74f34719e58249863107751ab8e964acc9749b568e811bc71c35d67faa6e904397d57165c09491ffb2bc69f7394c9923e83cd39337bdf7982a9ddb7adc1603da7e9b98b91a98d0f960386fe0dee54f01f3e8ff3af17690af8728ecbf7ad2baff247d9c9cedb8e07e04c7663cebdfe8f47d200e119d7a1b43d2e482ea8d9425f27fa32746a3a5cdf86fdb034d182e5ed8d6de535a8a16f27f361ffc852287fc1f8ea312737d35a0dac8ffbdd4b044ca5b84f3299c900854576290dbc266c830baa9966ae14b4f81260163ca8e9d0020bae9b32ee93aa93fbbb7a628e23782bc002c1846b87ccee32199a208c6bd33bc004c92a42a56640fafb6ddd2f34567dc5d606f117c5a6895aaa5708cc2909a761bf988c6e033be00accc897f2f0000c5a326d0771ec4008c649b4f25501305f7e2e6312c142ee4b47615bbd649479bc2be7d8572f091acf1358309109d61e47651738a4ff4d5d619cf0e6ae30989833ef2377ef907159caf89663eff8703c112fe00f10e93fcfe834addce21061a032aee988c762ecf6cc2a1014b9bdda2f7739425e0bc25a0818b2860b16ea7377aef064ad52e85f7ea3398ab808374d3e4efd9028028085ab7be4002b38a09266691bd868718505c36c11e13478ddc35c7b5691b09300c92ba25368fbe11030a2bb832adc916840d5069d92514c3cf50ca1b6083100c88e92b7cbf84051a7877033a754c4391a4d0316dc0f41308a79af4606db8bfa7aa8b00ee274b2b149cae04722bb7e0c701a088bff2d44399191901c69a394b2988f32b7e0e20fd1d0fa8c3772ea557c39c9e8fb553327e8bda430fa2aa3be8334156dbdddf01ad0ea21eb0b9a107e84070f1be01080394058be145811efe5a5d1502fd37c9082b369c40dccae3244282c08241d092872f204ae3aaf7b21fec48530f7b981f29875cf7d4a0ad91ed091ccd8266c4e45b93acfc37d34e81965d356ed50aa22bc7de55b26f49642248bdb744605deb38162d30fc2a0b24502df0c95d031fb3455f60964987088fc992d80bcc52f55c66421d3603ff9eb1555ee0e9ca4117ebff8adea3c2959c1ced5f0cb049613168fedb8aeead139b57284a1e5a62b56fa88ccdc54ca34fe7675d0bafb6831fac4f96869a717b688fe82f71f4117b846d1fd80eb692cff378cd599ddd4a3445fb898502a00abca687187461f2d34d8fc08ab5449785e395947e2ea5d6a817860afba6cfbf0723d100163adac3282cbbddde96d95cfeff4e85da9b4b6965bccdc1ce203c10f64a5fe6dc33a09439cbc5eafaf7d104c26d36912fbe55a7eb02aa0f260e9dd0f763d44753836033309bff29aab095be0fc70d944f494f170621abf4184f908d78fd945d44df28171fe43d50bbfc9cbfe7a7b45478e3d8c0712c9e6f8e509a5610cda471e6dbc1ebda75aa44ba0821262b16f9fe71f2a616940556b7d116ec7c0bbcb560be6c24add594b559094e0234e9302a6cfe8e38954615a3195ea7cdea8b36929506b793e50df0d3b98a89a6d823d0ea8123815e8f297250d33ac85ce0df2e55f01c338c547450abd85542382cec31a165241a29098ddae78129196488981e1b5e9995df3699f264e3470feab7656598ca52ae1ea71c6cd1c3f60491026bc4dc2bab9bd929fa5bfd00c1c893f6b7b4f04bcdcd808a619776144c89e308fd88681cfb309bd2dd7203da1ddeb6c08abdc051ad34e3adfc86539bee35d5a423ae301396736da34189d96982adbad2b031ece7ce3939af8dc4de689fd2aeb2e8a9ac6a2230034d6bacac920588eaad65a4ec5eb0e39891bec00a59b7cb957a0a49cfd0e2cb21fa43bf2ed23174592a41d33667ef5ddef028e86f899cbcd5b78873cfa6cf27c1a918cde36ff40d0ddf646c9f7d339e1a0ac0040ec096e5a64adad5b347fe40038bfcdf95d9a99d003dd8eb5185e0d9a7b31dd4decc53af4d2856649e62ea74e2f2ef373aee9d7cc15889473d724d809b2bbd45f7ae7a179ff682f29aafee556925d1c3080bb65f3db3388195d04958d674fef3b5528284231c95991735aa5d1b64f9300c8980c749d1cab0dee9f89b621299be67cc407da1e058d21e7df217ac41e2a559de995930b10342bcac95d02c7c2f981011cf505592aa2f9f4bcd1cb3028d1b2a82a79215daef167014ca99949638b3ca5903dc073ea50f486c695a35b43b98b6600a7cea88aa6ead88248013b7a48320c1bb1fbaadf40177dbfa50d2f32ac8f04bb85c2942e50f9a6a0e43d208616f32c26b98bed6a34ed8da24071facf8e199ca173602a6c233a40268bf9c9b4db9ac16d0580789f42cbd13331945f54bfb092aa2279e4f032e92cfabd04805a670ba89eb29349e015f36d34d3c9aff267f90f45db44489d070f39fc787de66dda5e6c32f371451af3c6a68417f6de7a4ff622ab3367dc64acf039266559628ea6a73935560b439d2750418678b18588647ec1c7a3cc4307c32f55ebf73480f7b5c43fb56d8c49871374d85a4f38c0fa2df8234b5056efb854814551030ed6a3a0c581bee38d40832fccd155c40f303b5048c0ca7d3e988fb81d36345d58afe29c46e29194d64174fa891b4bb45f88b4f249bce8df5e3f3b0b70b13abdff33aa42b5203fbcd31b4fd40c2ba096db2770a1216e814f9125e91b7f27c3c1b2fc7f3bc27de05dfcdcae5bd40eff33c98e7b52cf87a78e0e7b140cfc987e3adbe0bbcd5eafbc00ff49c7c9f17e4bbf16cbc17f8799e07f3887c37ae9507be40cff38aa8f703c90bca6a0396b7f26c3cf087676303c3f922e402af08e87d5feb73bd1756308463c5f33eeff33c2fc85d9ef30fc8786abca8e1d44b0f6778e185870c1174a96328b1458c303c8a47030ed5c3041eaa4ac09f7aa04287271e9c454b0f61d43855a229587ab8a00456ea9021273dfc107252751c5124868e91229e1baf89181e0a9accd6ecd084a6c0c7991c1704cd88f880c2100203d121241bf000b40606339a8301f5b1e33cf000e333560c4ec132bec17d5386b72c77ca8c6a7b8bbb23f98b9b1e87a1741eebaea5ac65e626832daa5c362e1b50c7ab89cb66452427ca84a69e974febe66504e6ecf0c09c960cd4ad74562298a6cc0d552d1d9fcb0604d22162a444d50d979c1204d261c2472484b505f45a50185015054b9258e6036f402c3f27a802c10948bc30c163c1440ca698f081415641398f470a6b832faa5a2d0c9ccc54b0e30885551513005005c4a64b4e8f9c1e2250a920f7d2376e5441d936556632842e9b950e4b0a54a105135ea08e16116fc71213ccf0c106c905ccbcde18808e0f873545743901affc17264ee0c1f2b9a172a3410b041089cbc90952f450e504235eb0201c32a3436259e18a2a9cb38643191d253b3c2e43564f5c409a9870e372d2ba79e958152d555911b9a1e246d58d6b4907ea65458812951b1b2b3950251429aa7c80404d6e5a301e3aad1b1ca59e1084a8ba7959b980c642156b15b2bc9696d60deb490b8994239cd3e6c8cb4aebc6054427c9c608d864e3a3c7100d825880e4b5c195270d4cb8798dae253a4b8a969c5c39a02b080bb66a6293031ea1535c36ae1b50887505349ae2b184ac7858160cd9bcc89513a5273f5e3716d8149980d48443f4f2018d80465a465421d10126b136605d6063041cb223c98ac80955a390b7aaad82c0156b849e10046005be4b28e1051a269630028815c89040a5a56a4fce4200e1030fb86c8172c2d2811598d1121f0d322842412c1cb0660d1198c181940c7a820071f110012e8610428b1207302215e4e0b4aea0220149103104103ff4c0830e5b7c8e088d38dc1005b5660e13d03e58430d05c8b028c30bb626e5c98d8b88186028b2c9409a2288803969e2a307cecdcb35440802a000e1cb2c4d1d2c5151da21002a0060270c26552ca1841164ba70296af2a30738012f4ac0454a942636ae56132924c0091f6a10000b231460871d5ec8d224e5c9911c4f8e551cdf1ba01aaac6770668c627062b0c4f031f06be0bd87c9163816f029f043e2abe26564b7c526018cf8887c18b086b880e90cfc75781d743e4c1daf9442f04757c38ac9bcfe6f5fa5c2ed6077a2bcf6bb9ce8e9590951555a00b5520961612eab9da302114a28ac5ca7169a00113c01e92803e728038a2b5421588c5c6829b213fca54d978013f585d80b35b392f2a2fa3d6cdeac98f1bd61655af28aa7a8060824dd14a073672c0a862ada962e504b94055ceeeb1a2cae6878ecff58425c49ae14c053840067002d842d50e9e1d3cab2051e8f5435c73026b8397910bca6ac70aca0b88aa155312a1d64d0b89aa154e2b0808849364e5813920d00d15d6062e2fad20ad9b56989c1e393d6c7ed858e0f2b242c109ad202b264e60655195411810476519100161393b5a22e8ad825648a0538e8fd6e7eae212e26a6255a0c36be1ac5860ce6ab5fa56aed56b657333045cb9b6b8767638dd88ae96cb5bb940225008f45e4056424cb0c1807544950e244c105ba09057d209201827f4c8a8af498119194833012f2090c569838a0106a5230ea214e1bb861a4247c21d2fd7970fb234ade9c20214c0e085211b0630e50630302081072800014b0c21346a50c3b95fd0b90d12a8e1c0171670c001c8941002081f7890a5a90a150c2ef061011553905942891248901119822f063ac0f080185cd59a149cc00d10bef8b040c4c003b0588002100045132f04400559085eba64695a9240175844a00a1bac6c4003127880031460851040b080421912a8c1c0170ab0820a27cc547db9a424eaa829830c3020e0802912f0441131b8f0a52c0410be7459527a02fb117524d0050474c02106335f86d0c11215a527301d3aa097418604bad0028b2912f0441345c8100033603a588af204564494e46747047d4d196478400b0860e1802912d0441132c4100017cc8c210303020742e31c7260b9b243470786c0d0020b1e7419f2c10516765449d8ac59a5e043014b8e2f8ed711a0115f11df109e922fc96ac81b7182561baca805187c433c21ae202b20de0fd08767810d8f9d9d5508eec8d111ea04c9018233e446b471bd5aaeafd562b1569e0771bf09739870779dc73769755f9b73425f62d2de9388bbe7ca31e32d0f73b884394d618ecf0ff5a1f44babafa5dad26de9935daeb9de485a2dc57103878d10870cf719b55dfb371dfda151a0509f2850e8b5b6a7e13c11e214e13ea3354cb5a57b4703338ee397252bad2043eeac273dac23ee8e818738465ce7f1e6dfbbe684f20641100457abefdbc0431b316cb8b876eb2f29ddf852fdb8a43f3e4fe613ebd046091b1bbcbcbf2bd5a1873654e5fdd0868a0d1135690d539a712dd7ade9db6ecd371b50e731df48dce3849eb4a6b639c1dd2f70b719e185e6b5596b7fe61f77f771f7235e194e92502934e79344e2c489919322274d9c307142e4648913254e92381972e2c4c8c8a8c8a88911132322a325464a8c92180d193929322a2a2a6a52c4a488a868499192a2244543454e9a1835296ad2a4099326444d963451d2244993a1264e9818312962d284091326444c963051c224099321264e888c888a889a10312122225a42a4842809d110919325464b8a963459c26409d192254b942c49b26468891325464a8a943451c244099192254a942849a2644889932446498a923449c2240951922549942449926428899321a3a1a2a126434c868886960c29194a323434441ba21a7a7717e2a10b059d47dc798536aef6199360dc5d03f0cb0d90cf8d0f0994043a02a54037403723504a2975f70cdcdd88bb17717790c7354461ae9c1908c29606b27077201eb69698cd28ec066836a3b05d7b93d29bd9cfbed96ca674d7def4995158f9a6ad355da34489c2a3ff46ee8aebe1095b3b2a0a74e408dd95962f45da5b732d2777582bc8dda9872d1da7daee9346a9b67fdbfb64d2e19cf151c83ac37d1cbb70779787ac07b072f01f0a050a4de243ff34eb149dfdc54d335ae9c574f6e393ab59774f18ec62bb735966b47cd3ac240cee3e86e01cac9355bafff8e4b735bbef974b9bfc30b42c0270f72e1e8273b8cd82977bf9b88c6b66c5d1a4a52c45ee2ee4ee50dcdd030fc1289d474de6ea641c0a2a2d0edafa62d2dd7b90b9923966b3471847913966a424c9eb7ae4ee3cdccd7a6eb296bfc9cf51296d6bb349b76dbb8f45933976b39df82a6ddcb47192ed5ad3d61cb5db399cd2cdb2317eda5f65dfdfdaea8bc9bbe4ee629871ce4a9ff1862a7fe7ce9c3192fea9fa584a6bd6a9bb9431951ac6d9e97e95ecee501eae80e83cd2acb933a65577dfe1ee3a3cc7dd71dcfdc693c1ddb778f899e177fb16e0ee14a6cb7b621aad61ba4f4cf196e93c0e8d49c62441faf78e26b4448911f94e68a513274a9a90e42709c26172a49db76d6dbbbcb5b57d16c2b65cc951a84a89a02d4ee871f82644a340a1fe7a1955e0e1477d5b33a7e96cd7d98e879e09dccd1a840f0fbd27dcbd87871e0f1e25bfbed6dd75dc5963bcadf358629c10f953a1e7c191bb5be0a107e4eef74d0a853e8d96e6896f9afe506d7d28d597d7d29fc2b8cfb25cd56977b771ff4a77ffe1a107ea3c6e5cade5ee9e679cf3d35b69f9379ffb33bdd8eebaefe3decce12cddb6e64d6dd7ee5d7119d768fd5aee3ec443a77277d1439fc1dd75d8ace59fc274b72d597395d479247f4aa6ab5988cc5a88c4a6598576b9669a35dd9db502ddfde3c0cc17073840151b1f6890f8410004c63875c08aa89a0488d0c831957c784060e4050fdd6b8cc3061134992a006163d4f35380245ef000b2c2b8cae924231c843983c20faf0a00a98a02c7d15455c57c05c48c0d38384467bcfc4b013473c6a3291085600d2b72de3e622c1ac63525c5a25e071e134355d5b3955a3d521db4284b0a4b6b4bb5a817fb5c3ddb8bd9ec10426506779c1d3478d4eb99c1a3cef3ad78563c5b8a45bd954dec6bf56c2f06ae89b1c01e2a7c7bb1af870a6f35021c213492080defcc19907ed4e3317306ec49420c07522b2ac6d174c159519c55cf151c5f8959992f332798e07df403bd038020084a7dd4061c33f55156cf5e51d62ae6d1970be49162f5881913b3e9916a51d69415eba32fa957cf981808ae562b70058220b85a510ff43ceaac2270dcf3bc559817b5b1a1ceca1ba4ada98fb6280be411f32326f5f578cce31163c58bbdc4ac3cda23664cccd52305d28fb65a3d62563129a71ea3ae7365471538424000234408e9f5c011a265b5e3078f7a3d3e780a30b3a26652203a62d13154ad332dea3a5bfc8845cb90a9aa02573cad9e174f1488b3c307779ccfd3f1c0a945573cad568be2b8ce961665f5ac7870583a4e2e123ebaead2a2df9702092dea1d7d2e176db97a52c869b5563c600a24b0a87704521c9c1565f18c2173c43a5af5a4907304d2291f4bc989453d58d1564f0aded18e35472cb0a70aef49c13bfa7aaaf04a687d200e38ab2216d107429042c1a1be2ad2e1f9705639383cded1475f3d551ff5e88bc78f7272a88deb06a4371ffdcc8034877a3c24d850efb3d1a17e94c343a6aaaa8a27050e8e56f486c7cc19ef684553e0e008a4ae23440b487568d4ea0887474787dee0d033ded10df5e88bc74c0ec5f17848b8a19e8d4749c0a15f4ec8a323848a8bb6a45c3d43ec3edaea1962b7a21cbccce0d033d48c0e4d811edd504fa7a76a453deaf59859d19b9e2a3329d0231dbad2f940878784125614a7a76a4575b4e844ade877c363c373c63bb2a1383c6652e0e00887e27c3c3a2b1d25215a40aa433f58d11cfae23163d385cc914e0f0994841b4a020eebc686278524c470106b51ef88888d508caf89b57aa486d87d74889d102d20fd68d48a7af4e5b4a274f5b5a4c0214a23fca84789ca086d70848000867aaf55d19831257c74454bf02848c72411e5a22d3ac6cc197a14654359b48417bda13e26057ac4ea1953428bdef49ca1472b6ad353c2ab87455d3d25b43ccaea29d3f26e06aa8858c3c31a1b5060460df0f33ed002de1c4f78ab700e1318f17e2001fe00636172629f8ff7792b2f470e325e46af550370d05cc941220e35719cc1c6cf8e385a8863863872880388389088e309c7f158211c73b88ee741ab1d8671a461f580ab1c560e1c5a787050c08343031e1c6378dee781ac9507470e7000010712703c010715703000fc5a28a0f15eafd70f9082a0d11b676220f8860dde8a7e3a5756d4a3204501e7fbc21ef405d27ae0f84794055116a0e7795e16edad413dd08d39dc308197e6042dc4da30b3a24f629ea6046956ab96c33cf6a238613eeaf2c0d8176bf57c445d84ad9694778515868c7f06d820063aac0d11ecf8d183c562adbc1ed08d1871d88f188b4533f0271e63d1230ef3d80cfee36de4f06a0388b00d247eb4f1046d638a232c26aaaaaa8e38720aea286d10c3017df5e908332616c67b85f9562c23282cb0e5020816b96898bd22dac24c122b6a26057ad4ea49e33908e6803daf2f8ad6ebd57ab53c25cf080a96b0c7aac56ab58c5a2ed7b76ad196165e822c3e1c56192008b672a07c3facb0022c232deab2f96c40b0f5d2c971b9e84b47e7f4540163383d2c0f02691530e6eab90163208e0dbde159c16c28ebd371b128c8638487d2d0c5fa7c86582c106c5110a42d90b66e22f0b2f93e9beffba80d0fd0f7b32a8aad98b810ebfbc0d647592da0cf670512f9a409d18055d8785ecf8fefb55af5f8b4284be7f54d59794e73404f07a43d3c90b27ae440f3796872c0f93e96fbc4b4cbf5ad58ac6fc5ea01f2201608aebef0c2c603592005592c10044116c862816a8a7c7c7c5e2478c3f5234c8f21b1154841230e6319b91c06d2211f209f17359263c40b968d0dcb8605d2cf676504054b0fb0e56ab568185713578b7a8cc562fde09902335005c3ca87e903af7c14a42c5087e5e2a161fcf359c57af8be8f8705027d31acbcd56a459b4cf97c5661c80611abd54b07908d19b13044b195b7c3615e0f140f5a515087c3be1ea75032107ab18fbedef83e8ac3e209c3a11378432c4a8d7846565febd3f97ac2901a617d4394d230fcc162b1a6f8a0184531f2fdb0582c168b0d13c4582c8ae5e5c35a7d3e465f8fd1e7c3a25f0fb562c4a250b084445f93152513db1ff5629f7b01c6c7a24ebf8f05ae562003beeff3becffb28a53f28b85a7dabefbb22c4f1becf410aead06a79200be4a2f5b558dff7b1be6fd5fabeaff57d9f1cacef6bb1582c568b25c4cae359ad56463cf40182e2b55a2d6aa4b55ab5807c82a8cfe7e3d35ac901ba3e10044110044190822008822005bfeffb7ad0ac84f0224aa91b3c0c7d4386b0f156dfe7f91a3455aed60742f1a0d52a8afb185d11be62af1e9607b97a7a8c7c3ee12aa4d4c8ea034d80b302f220162bc87d5854c7a31e0f088a7a7c3f2cca3a0ac3f8c45814e88302bebcd52a67f5d1950b9ee785a18a85d92b4fe7079c149c112312f33428382386f3e540f97e563a4a203562a4275c03430812690152d0e7c7eaeb6179d0e7638445874e80650804b1d547575f48519066e5a373586fe01039200c12c359812b6781617c629ed7628134e61ae2412bfa83e54d88b8cf7745e831d0d56a40f8d12ff662391112e147411e9607b128cecb49c00409a220011a17f298072420c27f5ce90b12033d88f5d9bc1810b25e37397ef4830436c45674489832622b8a839383b3001d1c34e1ab47478e8e520ece0e1d0a087758118a6115e18e4845c863678a1e3c1250410f292ca8208ad0870508087ff870203f5e41807c3150489055ec3544089121de054430b8c0631fc580877a3d3c457a3e234532300245e8c5400d32008f68f0f239f2c5c01f9f55ec85e4c7db0089c73ea00dbc20a06f0c3a40e8c5c098d0f8443824648030c9902b49e22d51f2112d71225c31216aa20993a22646454e8c604e9ec0a03c8902454a140ea4f8140e9a884d398a211d252129255151aa42c54a95252b1d2c79573ac07285094b13539626a72c9f16a7272d504f51505ba2b86c61225c75e1e241172f1e7ce0e5cb07207c01034208606421cc647546ab24ad24bfacbdad76b3b9bd85b152619630a570e6c5e19bc36272598cce5b9f7bead44d51e9765422ecbc114418330209634a20814c0955644ca83ac18432279829838299145000400a6700f0a9706605155858a105165c6821002ebc10802560782106186488410032cc20001a66a8810625c2d5006af06c1800016cf86e20000e37ac72c041871c7c071d0ab0c3c743017ae0c1871e7ef0c181f82108203c2182580d210411437811441851847784112b248ef0d89704125e6ca544125fcc975022897015f3623945433e6f091d252442228e083feac57c3e9f1f5f8f9107093124844e15108cb55820cb83be1e222342cf0b42e7eb212a22043d26dcf38cf08ef090f092f09af098f868921a38fe799fe7b570c6f3bcef5b83873572f82e80e31f0e0f26741a6081173b40b0461b62190b66f011f3346a8c50b3001e70887e48a3c61b3e9e6d0905c230ce819847b178e1feada07c3e1e1aa02120cf89ce84de43c641f0cbf11ea0c762008ee779dff7b97b40e0e0b80750f0267f8ad69f9bae5660b028baa3d1f2f77dfd39f7d98792368737adf4feebf6d3a8edda5cae32d1716b6bd299942828331cce358afbdba6da34edd6f42f7e1cd6f47525e9b574eb334c0d07d9e8c6970a1fd1719731ee7141d7d2b7e56a562ed8897e356bd7d2d75697ffb63149f712cdf46934ffd45ffa19d73eff6d97b7d27b526d29eeb78529456569a263f925d574a4589b95026dfd369b44c7dcecf7493ed5cfe88e46f743d1b17cad9fc439476dd73e8dfe6c4bf1d64774aee27c68ddb5a49a8efaf1a63a579980f2dff6dbf0a6fbcc99f547ffded1e8b52399716de3283a262de56a9ea4ddb9e668bd96ee7b6292acd434cf1afd5b147d5c6d223f07f5ba7e26ef128ed2e57f1395128e7a1c46dae6596b9f7471d3be2746aafd13ceffc1c54da6a5629a158965dd1d8b874dd870f7809cb9e97a7b7d52bc29fd1237a13005d3665398a64c99e264cad0142153804cf9e1394c7f32f0a1302a447f32a01428030acb610a9401f5a1140644c17cf912931c8c117290c58f4f95c1a8b62deac98baf0c06d3175b2dfb8c492d2b7feb33ef7bca7027ce5e8b334ffd7947deb7e5c7bd6cbfde16473bb5145969a6596b325b5050d0eb7acbc9ec364f9c4c26cb057d142ca25c41f1a67f96b4527a4f4a0d308002a8a1608a7c09a354b9e3bb7b29ba7b29d9a6fa1b46c1e2ee3f40bb97f259dd70d3d5ca0d06236dfefbb6fc657d2bdaeabf5f85fc1cd49317375d6c757e2e545152e4df90b4bb7ff1d06805771f8f9268ad96a5fc8cb73e738e7eaef4a7bcd527ffbd16484bd5cf694c5e4c526d6f9bfe131393fe9bae56e8f8e3f3b72d82d574dfcff944a2e3c6f8893e3131d1ad7f572cb4525d6f95eef24f298d74eba7d1bfedfcdaca68f9a59dbab6dec86be9d37de4e6bf45651c6eb4a3c6fdb61953fd53f5d26ba9ae375ac3389bb8aaadac56dfa465593fef5e4af6b65b6f24cee69c2cd737495892bbfff01006e44e6174574af1a6bb975aade1c4012ec3597cca82aeadfb9e1817f4a6547e5cc6e1642b94c18510c5c3221e34ce2f02b55dbb332fa6657d93e24df5b634baef5bd2d66aa7a6e5ef9abd69af8bbb971e36190a8baa0c2d094109bdf5b6a9d66fee6ea5fa71b9ea13dba9cf4ebb3e6de7fa379d475a509322dc71145f8a420e6348795cbd34474f283a8fe49231c9b82488fc1293413f65779db2f94b99aea65965baca6ee4ae34d99319d77010ce864cc6b853d89798a46fd2ea8dac9fef49cbcfbfef5398596ffe7dad69da9a7e5bcdc972f56fb2fd5a4b917f2365fbc45f6272bfa6b2b5cf3999695aa97d7fea65b76d7532a9ec01c0ddab42a14c0aee1e0965aaaacca040c68cbb37a68cbb7782bb47668c092578644a70f748f0c6d8b48a0cb183851934eeee1d8800cb147fd99866452a2de692df342bd2b5369bb3ecfb534a2f55b7be5bb6ae26762a5fead6276d62ec84c34d17db8d999ebcd59a666c6b6bfeb6b72eb66b37e662a72e4692ca15f74fb5bc9fbff64fa5696f4836cbf43647fdae1b6a6b8b25ffc6a7187bb76cd356d9e5df1b63c93826ad73364abfddf7c44736abdf5671f6b3537ef32cff4642d9b8fcd36ebf2531d46ee7ac49e5a74c8ca4f55f1c2e6f7d322b6933deda5ad14fdeafd5b2ecf24f6152dba4ddb67fad79b3e096707942e94dd6bc2f46dae553d7cf513557de9aab3c0df74cfa7f6f8bc361a41bf951a625ef89917664cd24c67d92dde6c94415b55febd8be8fdb55a728ad9fb4e55dcad99bcef8b6cf580e57b7a6d5a3ddb6a6dd5ba05aee1e0b74f756eedee7ee9ebbb7668e14b83b0ae658b366cd9a356bd6ac51e3811d41d07490f3317a18a2e6cb1743fec5131e8a5c98809167c1030748d8a20a0f9c8a2b2e807326e70c6f22072a649600c37d882132f8788115ba0e4faab0010d32ee0250535ac00010b0e22c2469428a32f3e0279c004a04d504463e8213aa31608059c0b59a2b72222079c271162c6dc1ba800baffd60860d178dfa4c86a812c86069c13fe04009ba0000f9866f21a10d1548f0a83be5a4e87abcb8c2af2ce14060e072e15598406181230120e1484e85788c0039073750a0044172e44f9caa8457c4c086177571802a3868428d139da06404272035e0496c38a091a901f27184391e20440a667c032a5e90522543e93f1a4041e29e1eae0102e698a3042430c28d5c1eab2f4178c07ba86c81238384294ea704e141024202fc020fc439c2a8220a1fd2c2075cfe00250fc281344e24b1011138102a1ec482a478c07d3c008c27b528a15b30fb3e1d01c2f00a74c24c816abe701e5d5c4089129070f8ce0f3e2230fb32858b2a8469962815e021990330a143180df88e146e74745140e83a70a0330001c305ae630510358cbcc0798e1a45e028536081aa1c243b6f728348154e0e618e38be38c36f1ca0c119392d3e54ddf400f5883aaa729b33150880074b44f8eb0d165a0841115ff82ba705193d607155b94810a2f000244bd0b8a83ee019c00808d0b85c5ef870ca41cd94960e26151376e4d0b49c3cd933709929ac0d14e172058f31ce3a018513725ab8d0b0848c24d1c1ce195560184dc810430b4f54813588a1c38e1826d0805a2e0f4e4a48e26068010d60304064ca8a0238802047192e61ac6c6040991fb43853b5a26db9917a5a4357421828e9e18703f44b811a2c3ab88d876f0237a87066800c0f9f106c48e0cc000c345f095ec430c48c32fcf3a2230401d040c1ec6392c20f09b373f6f5f8f184c36ecd14cf04407851c314aaf23090e3816c2799e24d41b48117b10d26bc1ebc0f5c5314a8f2ce7c30479014270c79627e7cd08d71a5cafbd265ca122c47428f8a042cf000a80683b784840278f174c6cce3712ae10c1a95175ed8442a031c68000f9e636004cc8d4995ab910304264dc8aa7c0c2a940082891639ff620b0c0930a2829167214512d59305d4a9d800174e78651879134d883184a7a5ca87180241075128e0e43a3479000910350b9fe1234de004151f67e18887324cdcc08497711d893064051e7c042b535ea43ce1e33a056084b89d271c572400739041430e5e63c283924106239fedc0438d15de08fd83333c2a2a6aa2f02d67beac41abf0c29d44708df0050b16f02b5130a9c1880788bc8a94595e8304261ce9450501243471c63910cdc05de08a0e7fd2a584264c200081177d41c68925e220c389ced470e4869b1c3c096e07270b8ce1858f2600f1443411c2375880181d3cd57082ff6c808010c4f18305ae01154e5c51039a13dc4836c1cc65c108efe9c00d0fa080c790d3a4d66e882e0bbfe00b03dc2813a5880f81010423527c013d481844620fe8d1c0812c4981104769ba0f2d1ae04511111db78096002f661b08f10a76c4c143842058701e13e08085a33796f84e1020284981dd719105256bbc1a21f0d0040490b141d7c37700600425eca0a1e33a7230233785180db88e021c608610379e3c670d288268c30584e76c500230644fe538ba015356d834f11b2ca6b2448004a5df14b111b1c11983dba83087084a700002fe82c30711e05c89c25f622680a68808d6b88b0d170604504214eeda6df1441ab013b8eb75844d50ad89b776805541f24410de82f58862c464c7591bc8c0136b5838c1596592fc80033480b384b0c0608ae6c241319676590c2b1c1c404e052b601839a8a50d204168910107431a84a4b921f45505766e5d2c5184af08a0040514e078e02b9a15b80700b1c65742277c51f2a307ffd630d930841948f8370136b42461060eff8650b23519f1c23f3217541942c60dfe79e172850f4e49f8c7448b36c41cac7f3dbce814c1f1807b2610634a097e28710f034a413ca00136f7a6085341014258e25e0f443d7007d8c1bd332b40a14651927b62b8ac50822139ee7d31c104213ca8dca3e20606d248d9b9b7e407d7132ad8dce3d14ca0f161cabdb08b0a42ca18c33d9782c50c104bdc49f00309317a38701f230d921305d871ff029b2957f0e29ec5049608634607ee54b08145911cda706fe20164f0e8c47d0825286e7c2b771d685ef8a2729fa1c72b19e1e1ce02540c60b2acdccbf85072021408e13e4297d3070514e1be73e4b0dd10c51d37f40517ae22dc6b54907152821ddc674558808b5c18f70f4a108ad0e4343194c6b9a66fe6ee4e1e1e4912439f949f4f9bad5d4c525ae94fd51bd594d58618fe73f34aa0e1f6e4062ddc2b4107a327554adcbc12361005ec880b508fcc4f1a2713f821c22303001b8ce038c0cd2333471646432870c6ab72c1a9484a4f149e09517e349931208d77828f344cc8a489c22bc34345c4030ad47866ac0d4bd07031f25090438d1230aca01e00cea049d6fcf0f25688319184522b9e0b47c218e240c9140f06285e42217441e3d1b0c3692c41270bef865a55900eb8303c1ed8b00244c5088c3c22e60863030ee8f0c273228d131239a060f0ac20c11b4882e03cf022a0059a1f27ba2a0f8c149ce1e3010f67786e6c21e288ce89303eb10a2b1ad470459a6fc9076832388006a2f840a02167c4026fdcbe17901051c4043aac7c1170322bc2834e5901f142448f122546ab290578c1a305ca6c8506541a9aa372063cc930c2e0052726583d51682e50e28334ac36c4f048a09aa2777fe562abf543d9f2ac17e3ecd32aedd66cb35d2b75f34fe12af96bfad61c7571d3eec6a4aed5f76fe4b6529fdb45eda87076fa421f23ee9ee3ee373e3d7c42164280c14f664139c2dd3d0f244001267e80f1450ceefe79c93d1df1458f352570f78f081f8a70e231451645eeee0dc101047a7a9082e2e6ee1e07327cc902830a3a50e1ee1e0356642ad0810544b8b9fb0780223d0af0810cb4d8c2dd3d032841731d2a84f0e1eeab3646108213483880002370f70f8b120765b070848513b8fbaa8217bc50630036504101776fdd40c31b9e05602998e2ee1e196dc430668e017ca0c8dd411c662e02dcb6080386fb97f8067d89afbbbb77640677271281f727376871b331ce3a8f34a12ff115ba96e6ee42a8c119552fafaaca84aa9b2af7aa2affaa7c55e52a54390b2cb8dfb88dbb9f715fa1ca6daaaa4ca8aa62a1cabdaa6a85aa133c03203cf0bcd048933baedda52f6bb6e5b66c5db1d86def9208d6acd75251da99b95c4cd79b53d4932ca71f57ef266b0e87916030f24b4c4e2959724a91e5cf51559c14894d5a36ebc65b4655715415475a7d6dde542f7b5d6952942c39a1e477a2aa387ca3703d61f23b69184c8ac4e69194f273399bb786e174d541c9e2218f936ff273c624ddf86a4a6b96526de9dfa2e893992c63d9acfc9bb6d7d668fed2b4e791cea3de16674ddc6fbd73f79e7c6bec846b776997f1aee5ad4c66cd9fcb62565cc64de5ae3ae9f7829b16e0ee57dc1decc06d75531b8662d179dcd7e2dc9271282809f9608ce813a3f38b14287a579dfe6b32bdab39adab89742377cd699ba47535c92efb66b3afabc2dd3ff010031a4c7bd2928c49462541b8766dd09b95d4d766b5beedeaa4f36856b382e0e105398ce37864bf09b4eb671bddb8898e9a9ab59a27695692deb6d551dbb5e53de9e74abf0bccfca9376555df9a374ce7f1a6ebeda6eb8dc81bee3be39ba618ef9bae370a7b9d7fea33752f7f2abffea7ff4c85d4160783e9fb5278c3605a9fbb6ea8276f35ebd1c556e7e702e5ee4b56623c5eb9b4df34ab130e43fdc54d51ee4ea99090d0ef9ab7a69d5a88bc3b1d94cb5517b4ffbea5e1b008414c868476dbe69a2bffa6ebed9e30d8ce38973bb5ec7135d7de5633de1a067b9cddf7cce1101e9cee4a7fd7ada9bb2be94479380448e7b1bcbfa9fe89bb87e0a1102afcb7fe2bcbbfad0c87734d467e4e0b913f25b4847c1a49d6222325342743b4a2225a7d2323263f4454abfdd00f91b526444e6aff4542e4d6671612c283bbc7dc5d5f6c37f9a692c6b926779fc241fed24ee1ec54774d72f72858e8f772f7206b0441836ac8c756a39a624a58b264397a52aaa214d5b4b47454a569e9290a8a4629452165c182654bd393d21295a5a826a5a4251a85a4d4c151162c31a5a724a5a8d89312d3962625232a515b94909a94b66851828a5282226d7edcd9e4c424b6f4381b8514b5e57136aa7c11ac59f3dfaff226cd6acbc5766dde504e4c47417ab8fb17da9465292a86b484c5c92906e40cf72f146989ca12929213545094074a514d59908044e08af23779e69fb2dbe26cce012102481021901cdcfdc78782f94295a2625c969e9c1e67a37ed7242af74dd97d53f6bfdfcce1307997cc4ada8b6f252f6e622a6d16772f2a2d2e6d16dbb5f9cb9c653f5496fc5359f297f59fbec44cb61af534dcd964ab51eedee4dd9dc9ef1dedeaf095ba5b6c35ca76edb515f7d9dd85ca2f31f965ddd5dd898c6a7b8bbb8fb6baff342b17775f72b1dd56e39cbb2b49e2eee5b5523f427717bab8c9ddc7a0c761285f4d0940081b511039c8c5b54309a50deec2401537ac983272af0cbe19c0121470971b3c2c8d300a59e36b44e0ac1a58285aa2c600f7a810d70ea008ff704f96e860e7e3ac1a560d58a20113677d6044d20898a8fb8f0b090b1b487197e2428b2d6a80e15e03c8c0e044cb8cbb801c81450f736471d0660133c81630e5ae14b280018438d6784b0b4e8d92c51a7757fd36151ef817022b63970a38714781115560a6a4c1a24dba18038a35ee728205c90394299c65860f330fcd8f7b44f83ca9e056e12b262d7878a1fac1bf29381d1c805be32dddc203a6ec74be9240129a55d593af9c9ca6907440046fe13083064e90c08b7f5128b102ce41c45d28d0204415961ddcb546083954913373ff2288395ef8a183b7841ce940070f4c38d0b559b3be0856ef13ef2a160ec29dedaea66ae62e9ccb4107a378eee2c12b59a2e7f21d1ecb024f87f7520216f96a06f002d7f77ab1c095e7b98f6ff4cf3d2d20079ebb9eb07c47cb73cff3582ca20fe773cff3569f15cf73799fe7ad5a227cdee7b93e0b9e3cafe5b9fcf374c6d5d76af9dc500ffc3e10060ff4bcefc66be3f36c9ce581dfea3d2fcce779df6bcb27e4f3be16f87921f83caff5795a3c1f9eb7fa5e0d60ad5c3a3c0b3caf82d7cad3c1fbbcd6e779df4ae67de08d0dd197e34979792c23ab289eebfbc024ab9beff37e7634f1460093e05059397d0efa178407ae7c40d6e7ad9c45833786e79f8761e89e7ba0f7796a78af0f89e77dacef5b79de124fc87b7939dff77d2d24efc8f7819f37b41a7180bc34f07476827c03f0581f100ff4569e7f4e1fbdf140ff6ccbe9cc7361e53c0df07c0a16dfca6b79a0cbd3f156367cdf0bb6f28c56def781f4cbb1f1f1589ee71a02936030e47d37add7e7f23c98f77d1b58b53c9b0f5c4d793ddfe979ab20cf06e7f35e2eef9bf25df05df01159f9cabd1d5eebfb3c1d305c811f90effbbc9607d63c1b231e0eebf3589e8e2221df920bc7e6f368af1cd7e769f15e9eb7fa3cd0b3e211f99c7c433e9ccff5b1bc95f7791fcee702bd156be50543421f3a3a3d425146868bb212b8285be3e26c878bb31f2ece885c9c39b9389bb938d3b9380b808bb302b83863c2c5191a1767127071c60117676a5c9ca5c0c56a818bb5888b55898b758a8bf58a8bb58b8b9574b16a176b0a2ed6195cac44b8589970b1a2213244489070274890ef0499e23b41b804a9b9fbcb46c78d8e17d0452f392e7af9e1a297222e7a0172d10bcc452f4a2e7a6972d18b072e7aa9b9e885ca452f29b8e8e50517bd10c0452f45b8e8050acfd90152e53b4074be03a405df013283ef00e9c1778024e1ee3a383b3b7038e3210e34788803101ee280000f7170000e5e7888431a0f7108818739b88739ec789843110f7320f230072477b7e0a54347c7cd6b473cc377c414f8ce8e10dfd929e23b3b3fbeb353e43b3b567c67678befecd07c67e7face4e09beb3d382efece0e03b3b41f8cece12beb32385efec2cc077762010eee84143141ed2e0000f69c88087348ce1210d6b7848031c1ed6c0f2b0061e1ed650c4c31a843cace1098e0d8f9d1c23dfc9a9e23b394fbe93637d2727fb4e8e19dfc91980efe420b1c3fdc78d0e1e54f4e10a226a4972510b948b5a4c17b59871518b005cd4a2838b5a9a70518b025cd4420117b594e1a296375c7ceae1e213918b4f4a2e3e7171f1e9baf884828b4f33b8f834848b4f50b8f874858b4f5db8f8f4858b4f1e70f129042e42b180fca88085325c64210e175bd871b105212eb630e4ee366278d3bac9e942878b5dfc70b18b222e7641e46217555ceca28b8b5d8071b10b9b8b5d8871b18b115cece28c8b5d04c0c52e04e062173ab8d8c5102e76f1848b5d38c0dd71c257053b3b3a628e4e8886150fd180f2100dd24334b68768a0e0211a347888c60e1ea2818487683ce1211a5a788806181ea231020fd158e3611a403c4c63030fd328f2308d240fd370f2308d99876988f1300d321ea6c1828769d8e0611a41789846123737e08e1cf10411b87842095c3c01052e9671b95886878b658ab85826c8c532442e963172b10c928b659e5c2c535d2c835d2ca373b14c1917cbb4e0621902b858c687968f17a8f0f0050778f8c2161ebe90c6c317d670771d3d6e76585e7c8765f31d96f61d16007c872583efb076f01d16112f177a78e802110f5df0f1d085200f5d60e212b7b8e2e216d5c52d762e6e11838b5bd8e0e21641b8b845133a3737ad1c7104352e8e00878b633e17c7ec70718c0f17c7f0b83806c8c5314d5c1c93e4e2982617c740b938c68b8b63662e8e315d1c73bae3d8bc76a060e03b5090f80e1426be0325e63b503af01d285b7c070a18df81f2ee9ec3c383c4a07818b3e261ac8b87b1301ec600e061ac079b1cb101402e3680898b0d90e26203aab8d8002d2e36008cbbbf5eee363a44295070510a175c9462002e4a510017a510c245299670518a2a5c94620b77efe13f2a403dac00918715e8c0c30ad05e2b8400063a81266a8490a8d2dc3059c08f9a963339f8f0717777cd016483bbfb8e009039e3ee3e840511d2ac59f317ffd7644a5e15544c910029bc6789300ad77934cd271100841705029e78e2092928b2701b28c078d0dbbc83b874a1a3edce92b22c3d2939c994aac49eb24441c9a2b06c8951514a82c1727a0645df56a5ee792369f974dcd12815a48d9bcad7fdfda7ba6bd2efba93cadfb8a98673c58271d4a6fa7d3152598f5c8c15039c711f67abf9960bd25e020c50827b5036cd7a84136fb048276208aa4eff547070e215549af646864d04e167d0d6b5f6fba4d9bc77accab479e8ee3226d494f8dec0040c486552f91b731162d49a56690d676ca7eaed69f4379eda3a67fe6dfcd9d17cca5c6b146baae968bb16db2ea6e34dd75b8c8eb7df980bc6517a772b1314b08912403ce58b60931841120a4802091f7f7ce88f0fd57d936f20092cf507210f930091c000121170172a4205891328d535a764c9d2eb5a0ddb5e23f1b27da6478441614fd69c3ec201eef4c17ca1528228982ff4733bbce9085ccd1141c4d027f74d992c4a141a8587de376532234e30a274f73781a8b6541bf1b9eb46fd9a6a7be2923eade633661bffbea675679a95ea53dfbfaff18da4f9c45ee8a8f5b96baeb95c4582a4eafe888e9a8a036d8b10f1fa4244263384156f8c33caef04429c719caeba7de456a41b1d6d9646f1aeb67c1cce527de44d5a8dca475493d8bc5f969696718d6a4bafc566ad7c3deafcfb7135d71cdddd8ad35b6c43667dadaf7d7dca64667d0dd31ac774e44869beadd1bf6d5cc6356d561a366db47c6d29dd991796c3597a71d67d6eb7ebc5b7f699ea2bdd6133f7a5ae369dc7cf35f7390783e9f0b087325f62a4f16963a67f23a9e829e69f70ed2ee174d5c1606f9e2566c2e9dac5490b1e8c0c50001378a9c10ca7ae9fb7b7410188dc33093b5c2067964a36ab754f5599469df1262b95aa6449794f9a3f77a464c9eea5663f3f148802f9f8d4f006944867d6b2acf4568ac9f29bb45963b849f754308eca5fe62cb52cfbcca2df66bceb52fef23e958d9b1e67a374180bc6510b88000e2f57c2d96a22c51e57c93f0af34fbba5376d0d0349e58abb91f78fe898df29a9ee9a34669cb33b7fee5a264a55cdaa318e665cabb4fc769c5d3ba3aa4c33fd3a6ce6cfe54e6a566cbf466d75df27f3e7e8ae4ed726e56878d35dae96b4b5bf4fc3367f8eeeaa3992d534fff6b7a829c6f2cbdfd18d6f4977369374fcb2e234dd35d1ec74972ed6f59fee16a47f7a2a4e4e9fcf5d719f9d76d54ae9706c9a066848a26599818c7a8ae12242d10c4453ae8305dcbd04016cffa41040e841210313ee3a94e18cbb8fe6b87ba90de8ac5cfa2b33fab7dd4b5d1dae7a26bb78762373fd6bf5a92dad371d2d77eea57e4aef5e4a1fd15d5e53dbadb79bdda4c5e18bc937f3974bbfab25b1d631dcb4fb2b7af75770d391f085ecb69b6f32a7e285efbe08f83315aa2fef520070eeeec2085c9861bc27ce9d52189bf46f51b18d9bf25f5d968d9b5e6fb94b1b37edfbb7e2f23bf5f0705a00c2dd6b184f27ca9701c0177a9f4f28d3ac485a7f2ecb98cbe1b3f37d2e2fa80a095fc28211cf8a15b058817a73783f4c48e107ef042e0498c0a4822f881745dc9dc943326276e009cfa8f11d15ceb91d6766d079a491e0eebbbf62cbb12b4e001881cee3eea58478f67ddcc50e819cced92d02a0072e4fed1545e1a6b5091d200510dc69d50be241e122582d82d594fe94dd41543b482827a3da55a6fbfb39056688c0e9aa23c778688647ccc657f7170663b2b979f2b4f1cdb3c43819add63ee746f2a97eeabe8c6a07bd2dd71b12aedd258d9d6edb76c93867a5ac24954529eae97fe3a9d2c432b36a5bca64af710ee7dc3d339695b9eaea2edb1cd5cb76b2d28410689bd54964b25c95e92a339fbc95a495517e69a768eefec3dde570f72cee1dc0ddbdf2e9cebc5d4ba38672756b9cddbb97ca670e67ab49fee75afeda8bf09f6bdae284486d7125249570848434db0b220c770aa871b754ee4454b80709c15d47c8033d9c2f4410a3830d170fc7784182061437e93c925fe26bf3f642afc7aec434fd4487cda751d9b57a6b6c45ffb53b87fb6b83e89fd7ee8b49fa64b773b820bacbfb3ecd616cd28bddc930c3dd87689428b403236cd179cc7fef99938c433058fefd391725ca58335fbb7b30fc7801f40260d2ea3e71ee9e0b345a4b0884225819afcd591d9a703747a5b82a76402cb14b9231fdfc53621c257d28addc36eb38e04e3ca4327f9f544b5419bc08f65a9c2e8cddb6a6d54de1ee473cd4cd4033aee9a0cf3937743aa478380543fe6b71e114964c472ae114f8fbcce130199e599c30c0f699dbe76ddbf0c41285d2b1fc6c4f3164a5b5b367cf41cb3769f53ea53b8c4dc5487321ec5b19f43947a376583fb35208676148c9994217a1612029108549a114262b479ba5e9253da4fc325752db9202510e804c327320cc298cb66b6fba9a9a0295f7c435aaf3088389a180bb0f7928c6875dcde69fa278973785c9caf277ae1bca842abf0c736ae8d717e7f4677a6d7e27aaca14f526ad72b15daaca346afa5275eff6b5414f5e0ca4f7f91b4f51dbddbba0fc4e6599abee88eaa7af51f356fb7c5e5b6d957ea678c360b32ff4fe943e546f186cf685d69668d55495a96add5fa02cbabf663dc53ccd585baaef53d9d6274e464fbc3be98977b4b644476db505ba4b74d457874baa3759f359526d6fa5c553555345e5bf96e969d44772b8dffb75ae9a4f3513ba757db33e0e88c99b395ca5aa7f8b2a4d7cd39f6f514723544ffebd9fd64375bdb6f6e514ce395c7d5d6f495f947136a3d54ed1fd1a898e6fd2acae5f2be9d36cddfbc891fc37f235dd996625ed2d57b30defdc2e93b4ee23f7c926bf56ab3463bac9cfe19b5f9f41789f95de5cc5ed5e0af61b5f4a85755174bcf8a4b66bdfb4371d9de959141df5dd42c75d29ce34cb5bc35f31b9ab398a3f1f79dd6f7b8ad15074ac7457d376ada6f5efec5a3a9b7d9efd0001f9cc806274fcfcb7b2fed677898e3a6c6a9bab4c3aff14a6dbeeaae9cecce1acde96026d5d73f4c97e4dcbaf541fd9f5b681663f3ef7cd71465f9ffb48173a0e01dd2c74dcf5c949abb634f7a4b65d8bc39b3e8de24df5e53df1d3ec0bd5968299cdbee89d79b3bc2dd75d7eb6fa934cb392b4bc95a4e3c5b9f3fc530c05ca1848cf28ae7ede3a77d25be9aeff64263f3f8eb45be36babb6a4362013e34d6b65d097e6597b7de65fa23b3357a52eb68bb354fd2e9f9d4cf3a4f2e79f5a9276d569e37b2b92d67fb7ed72234f268ca3a06a56b25d9cbb986645d2911bdf74ae5e28dbb55a5b268ba39de5ebb069c6366e32cd4a6586048ed27d9502c0c26cc954107931ed6ec9556762ec443ba1f643e5306eca65d16fe2271363a7fcf72e99183b955fe6aafba7ff4ca5bcf82848489b18e7645756c4dd7375e3ab7154b9a4dfc64c249d5faa6e285db352b984a3cad7b5cf4eba66a55a96adef92be18a966a5bb74d3d584cab896e5499b9d70bf9732a6a243305f5c6b96f54b0a547ea61bd3fc5219ebb014894da120770ff2108c096688decf61301f086c80c001770aabbb96753f8e0251204f05af052077cf04ad71eeca721aea6302fb86dcdd8b8720d8b8eb208d735748ef70b833a944dafd95fdfa9f742e577550faa9fcb2fc1975cd5220f2b9d0f281cafad98c6ddca4f56fcc0587f7ad3727d94fe92a1ba01ce10708f88008779fe2432fb696eed8aec4347acf1a0dbab8c9abc20f2c70f29e3526e3505090c5e9aafbf1d9ed1cee65da8e5264dde3a62af5e36a9396959fe57118aac4b88a69c6ca9fb24ffe53e885ee6836363637e5d32ff46f5136363637509cb68c5a9b39a08c6bdb6aac6b19db9c8b518fc9582bd578974b5c6652a432d6ed6f2abfbc273e82f2a7989acb923f97abb9cb8ce27ddb676c46cb5bebeb2850c654e858e9eb59fe5d8bcd3e9f24599fa65fe3dba6ba52a0197eda54df34fb5d7176eba75a7fb6e19cab74bf8de24d4d5b6bb4a4ed72d5fac98d2fcdbfab49ffb6819e3c4b9c73b6ea28ad5fdad22c4b8bdb9937db896ba7d5f47537b2daaebdd7da3e46475aded7146f2a85a93eb22dbd91f6a6a3f9776df757ac94bf2b69cddc9984e361d400a27451d89dc27c288551dbb54f140c857d110a1acb2fff2f7d1add55dcd66798b2d2181defeea5e8678cd3b66b6fae5dbec44d4bb67a0475a604a81c42dda066545bdd5f0a446d9546f1be96525a3e982f3487180aa0868271f75a70f758f054f0ce3ccde1ee545b2cda568fe8135ba595b6746f044f51dc7d2c5f0c1d6d954677556756baf589bb3f656d5b5baaff12d37490b6559ab6260cb6b53565da5669b2500b07dcb4b5b4f8a6a395da2e696dd8a4ee4ee5a11610f49f5adb1bf99beefababe99a34fee3fedf33965f5fdda97b4326182d5d21264ccb852a730ac1494131a77ff1a7d6262ca389c530e7ed3678e3e313189c185061e308ef93535eb7971497514e3306ed76ca92dd04c8ad109857c2e359cb1a69feb0e67b159ebef9a1f775e253a6e6c6afa38bb6979ad548c8e7a679cfbbc7b29aacb8cc9cf949626bee593ee72c5d99cb35d6bd66a1836654f310f7b5aa555006480bb931e4a796ac279c8e484dbd8d8dc8c363636373f423a484893b80cbab6e284b01d474de2524808a6737bdf7cc0e82f1487b73e916c6c6c6e64b251976f9a1569772b13c6519576ea5dce2c31ce44da412643132770318be2b5a23796c0506584a2260f9dc8b0883263de00983061019fa6ffbc946f9af68aee9bcadfb5cc6df9122369fd2479425dc9c07dec000519e7acb4e4610740b8fbb8a3d1a7d15b499a3f47f7ad36d729fa1723996645723262020535da4ab754c551bc69fe32637aed896995eaf095da965eaceb3fd191fc9cae26f925ddedfc399c73b467575cc6548c9868dd435633f7595b6ac4040a8a96bfebb559fde5a88fecaf426949e34be1a96be9ad24d575d712df74b5b275b6b5adbf34b10fcdfd4be128131d7127ce5255dca8b5ae340ad31ad02b7ca4175bfab7d9e7dbc6b5bb14dbf8d29aa53fa50f7d6d562a749c295972cea8b67436a3bbde36c59a96678ea263f9f773b97aa3e7d6b586e96c369b7dc61b8a8e5b63933e0d47f579db369bcd9b3e8d9aa6d5515bb31b5f8aa9feee8bc99abd7fdb74f6faa4afa3354b5f9f957c1a9dfd507d79978060b0289f19fddc6ed37adbfaf36f6bdec8fdb51ac6694b6dd74a9135efb77953fdb6fb536f5a930cda379b35a9d661d3ac54db5b141df17d129bf46d95b45bdb6b71f9f797a6190b578765b8fa5bb65fcb642fc3e5a9c5ec828725b744312110438628a614f3843940613f35a5bf335e1f10718ebb2ba1484a13e72a798af95246fe9490f65ef8bce4bc38e2fe49e02ab96f8b532a31d2d23be17e5b3a56303318ac66fe43d1516b4bf749a3d79eb65cb1e05dee44a8e498b3b129af54cd6fbb18cbb63636f8a62b6f2d1f77dad0efa269362a574ab1aeafabcddbb4b5963bf5b6f6da6de96c47abd1ad31d216b6eadd54fddb94121dcb92ea4a6b56a73f8916d1389395de1387c364d54d615aa51b5f3a96bb343fef4c2b423569f9fbcdba2b2d2fd171091de9a8848e48744c4261356c4d13933f4f5e7c295069653e375d6f96becd9b522448487bf1c617e39020a1556fa01d8dfe6d9bf55a9bb555b35631cd8a83aad5cea37de66e3bf749a65962a42f31924e2aa3f69bf6d625632afbccdd25a827d2e67094d2b5f586849b4cf3a4929431d25d2aa38ca84431d94eda27956fef273d796bdef7cf7aa352da1667b1ecfc53ff7497c6a0cf3224d76314121a4537a0982ee1ad31be91b4ac345a4fa09d69c713ef6805dae7111d3d8831c1604d929cf5f3b64d929c545b1caed666651d957c316eaba9d051ef74c6f93fd0549569e3a6376975e7f26fe4894dd36ea81d15cee52795d7e20e76a619d37d13aedc0ff5e6f9a4fba62e11e8c2c4c58d25d3ac485495699c5155a6d99b38e7cf69aaca649ab111cbd3165aa919baba6bb6d18bafc6fd97678ddedf516aa3f8a6fbdc6ee39deddff47d1cddddfae689f74f05fdc5d4acb67e50fedcb9f357f26be69969d2121285a2e2b4b4dfcbc64d3bd37cb25d5b2ad55d7395ab63e56f6db16cdca471bf97ccbcc5767f5b4dfb2ee58dedaa99d336a9c4b84a979bae56dea455bc9fcbc64db17a64bbf6fe94adb27153d393ce4f83884e1470c2c2c90ad1e9004e41884e40388d426140b4e695e194e41fbeaec99f326d4def6b6b5632eb59da29bba54cfa7878728011b35bf29e98fee2268c9f9c3c3756529e54053c046207aba52786942859a2ab4fe512d59757ebc72200bcdf5e5bde4ad3b67cf3dcf771b7caaec56176a65965bfebd49bffa4ddf8caf67d9ceca7acedb3dd52a4952acb2ad32736cfdc99497dcfb26233777e8949d3aca4aee5ef1b79e2299cade50b097959f0c690103b7811820086b20c93c8c8156478f192c6dd573a579c33775f5d40e5f396086854a102549859d02447142d2531a85a491c54dd88415e8460c498c921012bb45c85850e0cee5e1099fb1702980f0423d18a189d472128f2a764e5c3609f3129cb69a95c10ee06d5f29458850cf7efcb0b5e9a0fbc78f075f9b8b8fbce7a678854ae70779dc71c2e7285ea8b4d133b5524291263d9d6cc4195b996b76ea8df780a069371d992a4757512937444241744a4a224aaca34eeee9333faaff3efccfc5398de4a81b0366374acd5b08931d2182445d61cb575a5328e3b73df273fd37aa3d5762d05caddaac36128bc2feec4587e632ea369ebbe4f75b6625e5ff3ac690d54c33be3dbd36af8b18c6535ebcfaee17d1fb7c97a95c68a4dbcabfaa7ccd7b8bfed29bccdbdad492b7ddad20446f3d4a6b9edcfb63e7a8ae21cce4e4e331a4433a64f6633255dbb945b572c331a4461fb7158b775f97febb67fd3edcc52b7b3d570c6a4d604a81a233f7931b9b48fdc99121d69f7a4f71655ab54a540f43fd7be56f5eea528d0d7ea54141def163afef8e830962326282bb8a97cbc9f0beefc8b9b366ec24ddf943f97db62bb387779d24ea5d04b551a853d65797a52a2484b55b260d1e57d9ba938e1b5c0840c77a7957a669830e1f92032a1721f77884ca08ca5a5e9884473e0fcb9dc8fb8484445d21a221094b84844dd475bcee0640cdee2c5c50d606711387c8002359ec64712fb16a21206f82c6a466b67eee24e5d6ad3d6fd49356f2a25b39a6f052a3feed41723e576aff5934acf830ae28fa954774dc2b51b8583192949a2c3d72693ddf6cbf096555d92ffb6aaf5e364b693f6a59192244a5eaa9a34a94a922fd584891299927ad3b29baeb7276f95edd732bc652ffb8bb7a6e1f0d6e1f2b36cd7de94e96afbafc9f096ed9bcdbeae6299b632d9d5e19bae3799b6d9acaff799bbf677ddd56ed3ac3625667d9dc4acab28442053e7f149f9629ee81367b2e2e80cccd47dd99722b39b9cfe9d619f7341bb52b6db7667cc24139150e12fdb6d9b71988a93c9b6ae35b3de8cf74fe1cedfd5f6e697f7d45b5b538aac264de6791f8ffbb883e0e29137968c4a928c4341578733eda6ebcd027b3582149aaba44cf7d71b722f26664085bb5746ce4a337a8f84a399eb538ca340206ac085fb78b1d5a7495ebb6ded4247ba2bdd57d4c0080d78a074a741d5b559adc1cc5dd4c0c8dd450d76dc8dc62441e44f9966c569318359064614c8dd5b2e66e043cc20c7c81cee0e44a94a0ba39534e3702e178d84e114a6716f7ef95f9ad8caae8fcb8fcb1fa5fb262e195f9bee9e99aa32514d475cfea8f14b4caf05c2f94530cd9a7ba99adba273a76cc4fbc7a7bcf8c876edc65c46fd1b4f9176df6ab3365a77b4ba77ddd5f2e223a47147ea237f73a73e127480714675a54a546250b9f33449aaa740e5c5e443d1b1e24ead2bdd99db92f76f2533a6650efa916dfd3459c5b92d74fcd9da874add9a736790a634466177898ee5ffc65c70d3ee5626fd1b73d1612cd509476dc9475b9f4cb92d4f4875d7a4df98cbb54fe2902cc4214cb88f60be50994c1c8254fe99b740fd99a5b4d5a9441282852b45e97ded587e06434eee9b95866daef7494da1e89804a6ab619db18e3ead029d5a5bd95012ba35c6d1bd8792e0bda3d53069f7e36edbe659fe9959f5adb3fb393ca3b7da5d7310de417a2c2d3d62620c4ad9f2a76cfeb2b4d45a4b8fc44cb3e69f52a29d9afe8d02d5dc89b38ddec8aa44c7dc897395af3d0e9354dbfa64cdbafc396cea2fcf7b8e26c63d8fab3629dd436bf8cc659c4d8c73380cde26363176c251da76b1f9473bd33ca9ec6e0c1f4969fbb471d3c64db66b77386ffd49394bdeb8e97e2ecbc64d5a5355a6b7dd7a2bd24f552b1b37e9c7494a493b53eb37f33b55bb7375422abf2c632355652233fe146e5756243a8e74e3a6b734729ce9f09dcd92d00da89e0599f54baa93222b8db630eaba504d9d5edf6cd60ac651e597a749be49de2d4f92a73e731aa8fcfc3977d7f1c8f880eb74eeaee4ee11f1395ac3f4f5e7b28cd9ae2d317995caa5fcef4413738c728af889ffe29c9576db9af5d4a2c3587ed7a412e32a5787ef953769758b8e5155266d2bcf0ea82ad3c576d7a76d71164b69bea50283ed70ed2e5dc0bde8b1637f3ee428815781cf480aa23802538457c3cd8a1e2b7820031e2b42308128f643957fe57629bffc9c549a59ca2f6d75aa59497c69e1ee321955c56da1aa4cf9a576b72ad1f1a7ea0dcc175a67b66b67d91ac95ffba4fb53dbde13d37d62a09d59b37488e20db4a3d15d6ff868fc9a95f23be951876f9ace76eeccb42ab35d4b9ee5e719fd4a9f6649a819f95cca9ffd6c9631ae6adbadfdbe35d7d336bbeddc97b2202a85cec61f97aaf9e54ccbca1ff3dbcac70235a34033aa2fcdba7194ded7c2664034887e99594c858e3b7aed98f1e7988c3f3324549569e6437f664832a632f3a1fabeeeefd03834164d69bbefefcc7a2bb5edda7246e2fbd987eadca969add5309899ee2f0c96df566f6522ef4ed36b75a59d9896b6e66ee489d3959ae6ebea4d3fd151df9ad374ac396ffd379bbdd5fc407a06863e91d9ae7dd9971985697d32d18262f59e3f3e54e34e325bb2ccb8ee68b4ea6ebaceccf2d65b26f363a6a1a1da121d1f97bb7de4d6ac54f3436121fba3675787674d3e74d4d966697496df29e3a81998d9ec4b352dce6a3ae6af2d95745baa976efabef92595324f1ad561d3dcd12ad53847a544c719989a95806810ad59e9cb8ce6ff817dcd4f6756a29c9492645e9eb244412d59998d60661a067bb2d6f2ef2ff9e9583e59f3e7ba2d05ca785b0da5c337a09a9f966fd6fc3b303318cc342bd2eccbce2c7f77ebcedcba62a1637e5cc6545b186c46afc59f31131d731547b59dfdf88c3f3e7af75230d8cc9a399ceeb30dfa4c77401bdf5aed4b4ccb16e86737dbbd946c36f536efcfda666b3fd75c5a3033aafab76dd26ad0c537577137bd3381b22df76b8bc3e4c89cfb795abdb7ea7cae74a16399abed33c5b56b7be84ff9a70fbe14a8b65471b61587c3e4d32ea6e99e1e5abe6956bdff6efda4cd5b7fa6f9c4359d0f35eb8d3e79f3e77ea7ebd3cf47767fdb9a92cf65898e527467d22c494bbdbb313ae2ecc524d5fbd69c1d6fba6ea88d9b8eb2ad4e171fe9cf98093749ddf386244562f36ec14d547054cd4ab52ce58d416ddc74dbb94fdae95b7350b66b97be1e95f5c834ed0d496ba41da2c13ae38d6b29d57f061a7a4655d6569f0175869433a09861821faa2d50f93ef43735a30a3372a035bf19db8c29666c60061133723405d259e3dca5b4fc0d822940d082ebf0a59a4661b319bd5689cb1254931215a5a4b17e2e57631778088271acf9a16a7ed96b58195a5051861265cc8037fda1d7d26b6906e60f0fcb3075191c543347a3902187b364cc408600dc69143214400d05f3e5068b6fc903bed50616a020021068a08a3044f02b7a946002d896d21381980fc75c838b18b450830b2118101ae2bd207073772c4b3bb2da1e8bf6606e029dc7a0a08b4d0fc5f02f314e3ffed24e6d2757e3815b7805b4d8c0e3e113f0882ef00037c3cbc019303ace4330a090dd6ae66460fc70778f7a4b55996a98aa32d1c7d9a8f167b773b8af9bce481a4493cc7ce88c9cd16dbfd27476cae66d5a5aa5e1a7291dc58eea789652a4cd34ac292e631ae776e6d6d5047a9cdd77fc793d9b51bc4fbcf301ba38bf083b6d6f7f6aa1e3c5f4d637cb5b6bdef7b7a53a6c858eb9936e7c81a4347dda8d7cf25a283afee84cc378d3abebf8a3f5a1e553d91ad5554777399cf73531ee326b4a12d434a33b13a87c2dbb78f69a6afb43e5890bad741fb9b8f431cd1cdde55a5e4cbea65abf794ffaa479e6708e3e4ddbfb9f3f476b96ce1e87a16654ffec72cd3887fb283aeeaa14b6fdbeb6cea066411e64e91245c7d9d08ce27dab69d68bf5dfc8faf966a1e3cc4a549526252cb2a82625a62a4a50b2a62c4b51485b9ea2a09ab220c99e94929ab6e44e5ac3d706e52fefd9656b5babe1a02f6bdeb4d297aab88b2d6d22eb7daaad3573b94a475dbea9c3572ae85a4c06557a234f4df56b9ccb676e97abce3f55566d2b694dda99a3fa27e862fadabced97b2a60fd5f6b3aed476b1997fea75f84681b48949bc71ced16bbdc49870f937dd19dfb43eb125ad5971b492f74fb376aded5a9386ab369a712d2a4b138d82dac274920f458bd01109926cda7d4f3a54feced479d7abcbf2c5f01d61e9cc34add48c664c672f55f7ec46e29cd24780717fadea9bae99a4444d4e5ab3f4c95f4cd4e4bc9138f72ba92caa9800cf6c637363535fa5a7d5239d475aa5790165bc56e8d20c6e0850e1ae67d44966bb7647d6d296b792b227ef89efe729d997b25bdf24711859696526c639d9ef3771969517d3eac5b4f24f99aee6f2b6adeeff7f5773b2fd78bfb63299aef965f8ea376935ff35cfa96b65fbb5ace697e9fecacacff96b5fcaca8b699f6fba6e2dcbd5cf52a495d2329969da1b89c3a4ec5a9c6c67e672350246221024022fba7ba9f2a730131721e0228b17c1227151e5eeb66bafc597c2fe9e19c685c94554adbe49f16ee2a2888b0cdc9dee5e6a579aeb9b483a8f19870bb798dac26e11e5f4a6eb4db6efe79aa354e31c85edd7b98a93d9aebd67ce651caeac32fd26794fd97e9dc5e97ea58d33677c60c226c783591a16a248410a6e3e8454d0c3bae361a51ed6261e56260f2b081e56ec612de36125808795080feb023cac1c0022a651e4621a486980e0621a615c4c63bbfb4db86347f8c4ccc327c278f804091e3e0183874f14c0c3278cf0f0890478f8c21a1e3e8185874f7ce1e1136578f884093c3c802706c1710de1808b43d47071c81a1789ec7091088f8b4490b84824c945224f2e1209c14522d8452227b848c4051789e4e02211215c249200178960e1229108ecd0218e61c6c5316470718c1c5c1c430817d30071710c03b83846152e8e81c5cb25fee02efef072f1071e2efed0e3e20f485cfca1c8c51facb8f8c316177fa8fd70baf80309eeae73a4021dae1c20e2ceccc51d9c8b3b542eee14c0c51d225cdca9c2c51d0ab8b8f301177748e0e20e1c2ef270177954e0220f1e17798c2ef280b9c8e38a8b3c40709107ce451e23b8c86306177900e1220f285ce491051031bce262287331a472771d56887cc7ca91ef5861f21d2b5c7cc74ae93b56c4b8bb8ef08b91875fa878f8258bbbf31095d81e2a01000f95b8c143258cf05009273c54e20a0f959880874a6cc04325d2f0500939dcfd95138a3aca7051c7085cdce1b9b843c7c51d405cdca1818b3b9ab8bb053f441cb68b38ace0220e3bb88803142ee2e0007767f9d849dabe93b4f39d24169272707642f0c07742a8be1302ce7742d0f94e0825f84e082af84e0835f84e083cf84e0840f84e0848f84e0850dcd8bc5ca22836b9808b4dca70b189085c6c22878b45372e16edb85854c4c5a220178b602e165d71b10804178b6e2e16e55c2c1ac1c5a2165c2c22808b453fb858a4848b450a70b188022e167dc0c522365c34f27604a8c4a804f06da5999a744c213333321009000000931200304024180bc70312c16c9e86ab0314800372a67290521d8aa32849415219c20c0100000000000020981a02a5295a29c7c8d19282f33e01009b2b0265b1c6599152c7f19b177053c43555c0be14b1bf9c5fad8f1a6dea9b6020874aa802915f6811ad2cc131fe698eb2978a280d50a1ef92c4c70a46efe9525d1ac4e81034e235d5337003df3edf50b9ecdfb7fc52a17fd7f4086af45247e6af2f529cfe8e3149cd0db26bd903b6e488f4226b19e01250a3e9a2110a17132954b2729741f1642cb47251420a7add4522169a8e46a998080f4d3c70dbf53a0f36dd9ed1c8f0df14b9ebe397d2791b889d13924dd5ccfa3023e766edd6e5f676fa397900b4def30b070fc2477525eed178d3873c083c285cff25a8309d66ea8a70a0cda27360f908165e7a25aea728e39205ebc3182a9f66d740cdc774053a8fc169e04bd9730ba7ae045646414bb46fa4aab1c482844d99f544e36a4259f867339763fe05898bb9a20a5658329e25a8d15c75f9d01add8f8653879714a8aad6362c8b67c86edf38147d9b817573d83271a1192d830a836cba0e6fdba0230b64a236790111a66f81a5c10025160bf3b1c71baafe84642c27f24d5aa5b18e4a0d42349f848a78a8c5202d01ccbbc8193300d990b5dc5ef3a30dc7d2f8c94a8fb15806e435a5310fe768b2f226898bc334e1510b7a2d8832e01c3ad6a8577600183ffc3dc1aea0c6f80a6ea843ac6c2739af045a022eb631c4714cee200558fa4f71291f4ddc0f7c327e2b8899b4e1cdb3329b898df6cd3ab645eba7a92d95ec51ede37df57e99b801ed5c31978614f484bdf085cf2f9379c6af1120197c6cb5b66bd50fa4cc28e8bc48e48d19411a1545469298215a4902f6e8280b71a16f6ca743e3034371caff99d6ba142902ea7ea1086f52c049b0fc08ee310b25951c59f3b14f485ccc16fa5ff90fd808deeb3a1a08e59eac455db4ab051a1e400c887887a0bfb39a36a4e01da402a3c3a68f6a2efb681b4cecb44ec43a9ebffccc0595e83e47958328886dd0ee15aacd5d04cdba3deaab3a039a5dc52f0f519ce93515b2dc2513e911cc68f85a50fbc8fbb01215320a1f629f5a82146128b840010e72d8235bf803c66df8c2769a9b6728b807c3c830ccbce0954bc0b7a6c81a5479db1e6b6a1c1ab2054f8ddc9786ef7c608c6aac64feca2dc8299441eac3ec4006dee5b87a887605520c18f44abb9208536d5ff3a004775f8087e46a35398e9c9bd99239b8dd985493b305d7bc1dfc36a84680bb83712ea93ac6e77dc19b02843dc5658d2a48c3656cdee3e633a8652e69e51d218c104c913ba5229253f3b5f86fe348a62ac219d79ee8eb07221073e3671eb8a0e38b5b1be86b644f52ea8aede9db96da275c18687ce2625a8eaca81e37b2c1ea06d007a0eb32feb6e9ee7fa8ca87d8a12286ba76c42793dcb7842e72b0161d36b22fad1f79c893a5cfee9a3e5bdf39de13c96632e5a4dfa92d310fe400b42884e1bf8bc7d66877da31a00477e4e039009220603780f1dde98ee7f890819d0022e88a8ae4203cc01a21c1e19541288e058e01e7a016e78c7dd60600bce0e888096c3a436ff7ebe513b3f3a7cb90bd6b244751329e56b5e45f5930781b959a41239a2796118cb91708a260dafb8158d5bc416e3d8ad1a2e8eb9a4695851d5583db437d32eea0098e4efff1c8538d7b75b7b179ec8909901f5c4bd627463240404c14ac09ebb49dfa20f840094e90038886fcde1a7fcc3dc8ba721a727db6f1d62f32803a81673d13991381179cc736790a9155f57f35e2266486d9f7b1bca38de118a5c8eb9098f3c9de038e6af2da766307d48efae1b6e13f86d6ab2585d86dc3276cc781c28cf08a2ec7501620d10b0e2bd1bda1f7c9ec93531806e46d096a4521a3ef7fb00b084a6549150e5f2463db5db0e6da1a1c2d439b35f1c7b7062be2c5a844adeace61be787c05ebca890a291224cf00fbb807edcb6cb25f99ee38d82d40af621a3611f1685c7b2af18bb111591b4158ef6f0f334cb1e205439a8a88f00483b1421695df54f7fe4cb310dbc651faf56b3c6089113f87bc71e8011b0eb24cfeaa13e71c87319ac45469861e8ef0c66dd44eba1cdf368ef2a4a7fb53fee63260d5f839034786a9388b3d635b10174966d94df2d14686954b5e877c1bc53e2f96db90f8712979933cd632179ffc90b229d0bea9c5472297da974a00976f8de68b1da90c550fa7f98ae401e0ad26dfc0612ffaa83cd97de3432c98f8e8840dacedcd49d146b2de82944d8bb8ba11a581bc28573335f946148b0fd5aa7bb9162d183911dadefa20fdbb894b5578203e7524ca6d1869e0296931f0cce558f1431c54de2ce131f31149e4445db510120612a2a2ff227d3811547ca8f1aa21936d55b39b3ce73b42347802869f2287c36e9bd5e58c0b13e5473b2f08361a2e82357501170d42d7b3ad97a92ccde36342c70b4b442b8d351931650afa7340eb4088a34907604de457bc0bd4e77e585d152591cf9b366dc3dd46ba6b64777e2fdfc3e35e71e1b7cecf0730156c9c5c9ab70412c47c1be40be0da9e5dd53f4e357538d3d62570ada641da09a5f071f27c4aa9ee8f295d61b1aa2025a69a62468270ceb18b6def77924bdd6e97ee68d29cddea60a01cf9f529e77fa3498499ccc9dc7059a0bfa99d54fbb93fd9316266891df4f2429432624cb5530787f41792c433c1f2100fa8165b49d4ae8fe60fde9ed641140538a16078310cd2bfc96f5447273741d92b0eba157fccc94a8c22483acc34d222f5df2324e2dea7fb0367e354e8d76565969d2cb84dc91aee3a58d28ecdba617dddd6fe34f64deb4455192ec92b02fc8d757f90caed2538567840a37ab042fd0f91d221e0c22ee41025aa123f5a0a6703855edf03e4ec821f2a06ad04872b03046f0edc776d0035040448dcc7f29277cbb9ad186731b0ef6556859b9da7b5ae7651af672ec568a241597883a16f9a553d031a5426d87534edd71fc0d8c1de4be2c5630cb4781a1f40c770a345bc2e9d3cd23cc154028cf0f34efb0e84beebae9ff904d60ef88098bb49138caf8d30e15e2e8cbf035939a9ca1c1607bb793ad8efb3221f86c5a0e80f85e9ce1b5b36f69acfcb5890cee7b7043de4cd954f378b5c218a1a5cbd28585f7f7b527d303f92c92a5e2b7ca3496ff9cd2fa7fe91b3db65acdcc4df634e483fd35507818e0848bf0c69dde68d580e176f59aa23de20f1021f2eede580327e2963e955e0b57ee1b1bdf42cd74bba8149927cc17d43a69e12d0ae8ae63b550780397835ddaa317434d1eb604918909ad781231636d1140c1b3cfa67530fe761ef9b2a98ea0cde1c51f1769845824feccf0f9fd54f12871cfd878f0780fbf1d60f4ef606df7e0d4e16a36d6439c62a20a8a5cd7014a828e69af6a1800089a0671460b23438acd3796f99864be1b682eb30f5d50e90922a99a35049934a92238c8dce91cff51de3dfd934b783d8ccd7be13bd319551841047369a7d41671cedac2ff1c6da4b0f8922d4a394d442de5fa35c64cc6f8fcd322245a92cfe6a7b5b7fb10e81ef4e587994876fc98b3a2fb7c02863ec020dcd82ecde9650599cf0ff767e152b40d0b1cfd91b5007911aa8834467ab8048eae88771918c100245fb8d2c3a0e110169673a9b96c3fde2ffb930d2019db13224023e8a27f168e14d59166c8183710ead7229bc7a3e6b3f780111488e81897b0aae6c6116883ffc1192c84e6890a92148352b2c5d35466abe150e5bae7c34ccf91726ca13cb2e3f1e1c13af06f3aa7260736b08ef9fec83988549592c14a872ec98e69e05c11ef3e9564a6d90516ad899bd304b88d8b75a480ccd2e1c7a1cfaddc05a3f5ae3427d6079b01ffe349e67495e128abcf630ba66324532bacd578adb9cd99086dc15994f4d1f79a4bd85eb9359e6b0df118198f55d99d841e54f7fca270b7f48e927acf9a7daf36a5cac2ea0974045d4811f97e21a61c4d30177074876aad26316a95eaa476beaad9678bb64a326752da93c346c878c071edbd15f39636dc7da9621a8a6ca71973297c94afa2e5580bb27f5a3e5794f6be7c5dfa2a1f71477a0c5b8da0461d4183de6800c3724a4f023fbdfd1c70b9b7acee58d28cc2ec9c81996e13ad4e09c771ed94503fbe24b97f30215c7f1cc25315cc01b6d1e7bb2b28b8c6994561c4ba5fa605b35f358a0518b14159140c06934cfe69cbf0b86730630812fa559818e81608a55a02af318528ae8fe3d5c405708c9329bd78c36b00e3a2b45b31c4982513dedd629875a026822fc2e54697ac53b636ddb016519463e1924ba9640b02c1e42eace837c8b3892a7c0200d97d54de3ea9cf1c38d6e8b5695142abdafca574dce53086fdaaeb4bbf67690fe105df6319a1aa8d3acacf51c58a8b279faa6e7688613f822b87717733da453eb9ca6b52861d13699bc35d3a4de762515c1f0098218d6b8c82793f899343cde6823fa06f12a2bafe42185f8897a7b8e0f944cd0e510f3486504eb821cebbc22068640a3160d34c41f0976cbb3e710bf957012a322cf32e4e8ce574d1e4a2a404484d2f3ab355d144a703781422113c92238adfef0f48c356e9017455a77464921212c1cf496a528c66333d3c7804435da3d4b6fd8dc197fdb3b2f43908700d5f619ed33ae395a9925361f82a7df1bd1e8b154139c61cd3e8651d57b2cc48ea71a1411f29084c65ca89fff7661d0d2ad61a6de140e82448ca7997c066fec0eaa7b58387d7108a8c1bfafbf54e8bd1299e2608764891abf95f6eb6f7d5c31bff1a49c216b7ce8aa00773547cb592c57ed96ef8320ea846810ca8a5ef45e64ce028663af4fb2586f22cd354a86750cd9bee1b345ecb213e36ca183b3b538b928a54cddf5484742e46e920ccc42438580f71cb8cc9410e884c1e95191796b0ff55f07024941630d6ed2450a90c5cb8d3dbfc41b8e38126148635e3460901c2e9d2e3dcf22f3029c1b01a6fa8305524dbc8b9f52c3a87ceaeb3ed09a74221ecbd19fcc6e4c21d92855e936a902aa6a724cc817c08e5668ac0c7c10c2bc4278d8e57ab0c28094ba3ac20bb5692f4b7fb35c30aad25a952ebac0fd084cdc29a499d1b74dc2472f23089ea343465a12094566a9ae347fd5f38a78b31b62ad89ead323a884983d1bcd97328fc3d08081662bcbf0c021e7594624140058de19c854f9fc248aa069123e25218884fa4905dc1018f523c8e05c9ccc241f143a17b214d4a7099d7cd4b381c603b9cc94895d58970422c182626dc44197544388cd6b92a9b0612f683084a53b114c91094b2e5dedb992f2bf4de0005bf6deb0f0bdc143b9757f720778c692b474cb985d1022d2d5e7c9b639911bec47134fb36a3160449ff29823dec41d34c035476cc4406363d480de3e12220242b653421a15a5ed521f3d89e95da810e47e87a356a9c0837f19d72c092b2912b33a7bbfef0c6064828675706d9994ab3ae7dc235d9cafb852356300e951c8b662b1719382a78dd900856fb9d6b6a59557f38f7516ad15465e469e3ebb1707c97bfb060e48e71b39e2f5173985b27242d4c12a00d755a50f7336bd665bc125e8a756faede236086949c3d5ec911ea6a0b6dfd16e4fb2e4050686c38764a35275a0506f65a920254c173243675610d5b5e36404ec005e93e43a3482972e500fc9ffe124a0133690f08182e830069ca1310c66bf2dd407e8160034ec5098caab0c84a1297dd45d59d388093e9710b6fef01ec03556c745ebb103c72a805f058bad4de22772743a34a6d4c4d3b8a1116c7d4c06229ff4a5fb9d7e28dae5b4915c2268c0b9e8632a5bbe78913f569325ad9b329b6410a3cac52b8927548bdc64d00652796ede21570f3f2fc5c0cee8c0a2c2a3f90b051a11d7812b1d30b1bf8d544e381978b903f008cdbf3a0d13008bd1d80b0bc40cca00ee27d2fdf56a677b1bb9e757483e09a2df3de737c18286dd7813efba4d9525309b54d313ca9fc01779acf153291250225212a284eb69e5b521a11fa2ac38458338725ba40ba2dd9d7b7ecaf0efedeed42c03007458ca80f6185db70bf1d59b0faf906fd07a821fdddd4189a1cd360cf76fe4d8a46823d16726e2715b68c6c74f826cbec7b893f2ea5f48abf73109c2dd111cedb1816510885154d17d0935d62bde262898d45c5c1265a7bca14ac19d5d1a5ea251592828a246d17f9d90cb99ab4626480cc614a8812004f88ebe8849a830f6c29d754bfa2c732f14f3557f4060c2a4308b93536304d19626656af1622784cf0e78ee96bef16c465465c3d315e9055dfd49497c12f6228da394f56d95bc0f0644260eabdc14bf0a7ea4142b713113541880880405656484c378b00ea9bce23bfe17c4116ac23c0d8be3ae81138d83a533d45f311d0a10f8df7813dd3ddedae798d7243deb938ff57541e3625036effd654d855f8e459b31b83bcd6b08a6f3946899e113c9bd1f119318063906d6e2f0b3ae2bc9246e436073a20b3061e223cba9c51d8d7f7ef76e02e01e14faed7d77e2cc5652496d850520e96f86ccd3df7a03a946416e15e72de9fd83dc605516721de3767af2f9e518067105f4f87bb4572a7bf328fd390f1ed2b3ee51894deddc090188a1bcc2f363b2bb2f3d307254c0d8243056c789c395dcb1562c8b4addb53942970d4da5fae223045644c5fc6dd31697d648f048362059b5da8dfc6f652754ada18af960e30de9ca989bbd83c97d301256b37c92ee23bec863d9a7f9b07e28fc754c189a50bada349e56f95e326d75066dde76b855e16f792ed8c0178aa992cbbf7d0b14494d7e85ee60e9d05615d92c0e4b16f6ec8d9afdf610bf311c0a31f23db028c46296de47355db2653b57562f35a8e905c19c9e126a43a0e07adf810a5d66a12c9623ebec70a1d69a5ece3edab920b6360099a9df2f2088a1dbd2c8e0dcc9d0fd5e5949ad024d0d82c402a506ab8fc4d25290c5f20548818bf6683d12761d566adc07b26a6231f39ec1c5b1e26af7d594b17313101fa188fe718b009677dae0c8d53ae3e04142da5f6d3bd4076c54f3775c792d073cd84da7d7025903c5b908cac3456dc8c4a7c60a16af90159fd6ea02f0744b2bc702f1ea05646683a67648c7981da39354f4d258abc3aaee0abb458e39352c0e449282c57033d189305ab766fe04f79c35e02dba19dfb56fc3e6a75b3315c59430baa303324c0ccd8317482ca5842d23251bcbff6fe5b585b8762c5b906cbd60b16e0ca0ad2a837b7fdd86047b63e1b239fe2267bd4b61eddd6bd0da6d5c830a82d1035d1a30d9fe73cac1120e86f1fe8948764b9e73985de4b542c8ba75b98b275ca4878ca9025d8a3b40299849f41b7f01dd3f456c11fc919721b9c06c0dde4b6d9a22ad7abd2da1e99729bb383bef075e74ee91e41f76695a467f1596ca92900b6d3064edd5d3f33a7805935c02d98ea99efc922966d0d2d7bd6bf87fda18937316d5e5b7c73ef4978c34e4ad41b96fd4beba2507296ead3a778bfef7e1b4e1be6dc856dc3d9102304dfe139a2fa8680e5de887d3cac6418ab65f51f03b3e7c47f57320e3ea2a16d5b660270189cd275fea9d6386a7d5bf491c161bc28ec2f3663446fd0e4601e832257b976a08b631a4df8c9c4e6278c44038ab781e02ab1a43a91bfc2e6760464cea889a51f1970bbc07588a9908a7af5807963306ad4a57cbe6864d5d85e2598b9c8e5223e1ca1a1522f338edd78842ebc824699e8697f1f708252b028dfc4c7165e8a56b0f31da73ab71eb160569f8a5b71d8c101e79754d5d26230d80ab5d7a005ecdfdcca1c203b7f977dac8744901efc6069cb10674d2884baf10111157f76a10c3f623bff044a0d7f271b4d4e12c3590628806a43f3c2a88a87f84e9949369ccdbaf68a879740cf6f38e18b8e5247558f734a9ac52ae94d6fa159bcf5a3d193898c4349298146b8ade3cee785f7691027815cfa0690f7751e856517e1ad27ecb6fc44c4f48ccb1e6fe45b00b556f1f8170afddc15f31bca3cf78a23d8569ec74f8b2022f0700f7a62328a11945163121b79decdc5156ddb05e50e01c3aef189b61d1157386d4049098b5b94f04cb4046038145a6ac3fc1d144bf9877d9da82955461304ef72d9cc75ed5d81013f92461907c8979e11cb2f301250e0d1a05dbd317312b6711f344571ec461a3f7455af61413600390b751107c90c1f1affb88c68d3481071dec063cbca549223b6d34a1631fe1d2ee644cde5af17a06352bfe0fde4d7b2da0e3daf5ee2fa07f196c15974897bff81d61e435d489b27d2af986be6e297564e520c167617d323e94d1c6de1e859962a4b32074a63d8c8046fba8e3eccbde89c8c65a8fce93abf3db8bf2dd82a68f38744cd98c663a6c1e643b47b8ced4e8382f4f9232ef24801e6f0be047252cda4abb5d78bbba4145b2c6dd810fba1ebdd891ac38ecb7441ef62625bc5c86ef723965af821210f2ac7783e20ccff44fc0d60b258be4f3078499040b033918504eccfd647ca4f410a1c7eddc080e3421f4711933928d5af62f489dc09087393bdff1431ae54943b3d88a8882e9b1292ccbc506384b963915fc1610a1ecd41d36504b7cb8a14cd5ddbcedc487fc7600ee88249eea728ac6b8b78fe187aa05e8ed8216f9d107452a1cc0f05c0483074c5ff949301f9fe3c3942b6b80cd55ae5e1c7e18401809a5ce6b1ff47737540aadb96f106f7691e931709ebda44839852ef403659d1583f5390e5cf83280e0be6ee837d6b7566c919c95696ad77aeb91301587bab76b564f3088cea47caa69794445f5c2f74e4d1a034c3661a32ec8270d2d45b7d9bccc53204e57eb8874b932d0c4933535106e0e10593c95e13bbf42342209fe73ada9948470098aedf8ed810e607adfa7a7b37a25a17ec5dacf3fa4525d3f1a029b7ac08b64068cbcded6d7266ee2a550e8df04a1561e3ea2b1d9c0e7f1782f3838bb49441119ed74bfa7702e54a88354999ddd77af9325e073465fd0628a627dc0159a7391da9c322a6b15d802af107069d5ef217338767259adb17310c4cdaf9913d82d395dc7e827fcd0d27c493887247a9cc9a157c373f8ad9d76adfb503c03e44a795f499b823f7ff69b9c479c23a7f11f776436915cf735b96f07b2d63a52d7bc834f581db62c36a43346d7d4218025550935872da447019bc06232b34c1f710005988010cdec2eea65df145025e2c6b55c50b77a467b91901ad36056b203372be10fc682d64d7bc7fef30cfc0c0f9d20dbc14aef366739e3f9677c6e3c00c371de4e70dfff9369a230c530db6293c4fdfabd16895bfd64b44f703e9eefd42f8d3f165140316b529244787d0f11e321e4d840af54b0e2de66df5ed6eeff61b9825894d7dab9e9ef31b2a5b3afdbbd81e9ea7517154725317107ae2b530838061a34f0c546a1325cda3658f00fd7858e0c3a476796434d16f057d1188cc3dcc9b0341b253a19a2e8965e3f06f61ca9d3e8c9ee6c084ff5180536f3052eb38543076843e08fee0d3f62bb2d7bd3baeb27528bda8f39c927b2b2bfffcb9df83c96302ed5e82c4342e42cd9f734b8318aa69be2e9e201d47d78779840c179c8ec37a76d750e09dfe7093674021b4f55b708cff85a11388254d88830d4e6d1e8f63ac43b2610f483ad4bf95309d47e3583825bd10104a1ba3b5ce830e8c5808930ea274284c0941304ab6509c64e90f9aa8d8382d3c3bdc88ea2fd9486e38c93772665d353d2426e32e69778abbe50a342174d4b25ec58bfe550f375ca786e6c8f3d5661a1339ad41c227f8ca18f476bc457257d6ad6b6a9fcc564c6dd50aab81b2962ff5e3d034e1447059d00c4fa5d4936ca004aedec2fa03259317e05daa1e5d04b1f77063a4b314a937c0d04426cd991dc05f68dc37f99f151c6cd4ff7fab42ada690df2332724dc168ce9c5d33b6ef201b358b764b37c51f6ffaf884695caca94f556087d26e82fff1ba2434af893b9052aea6fd1d37f9cc490268535e6064f07b7682dc8f709b5bbab8867e940df8fadd940a8865de41ed839a63290e35dd577dc2a89ac58824e8cb9ce37a64243fe5447b68ec3a56a96202232e77196bee9f3a8db17f7b3854dcb871440b43855bce9d6e1fdc9485f59b2b33f8a8e1f8a8706aba83fc199317b8fbacb1f8b278c6a92558ab7b3c005a71c22fcdc766d71416c50e7e5905a02b4b90ed6350f22cd012007738df16b0d473c31b4676dc1f4a837d15993193be17cded6e673922f043bd2b455ce4807ee8e2ad64cbc45693182239433a83d44a8648120c66247c7a530c23b4c478600878b14c74686193f5382e921ed7c1d5b97d1bda96c1e2e852b5be654df1ff2a3ea0a84efee9c70b20909697a2e2a6ebb2200de5e82e8600b5b39261e9ac22b41706a02b0d371c344ed7e665bcf55dbfba1a78df805f1431059b499fcc9bbe0d835470bcc224458a89bdaefb2592531535f31b61ae10904f533be9890e0995d93590fbb4cf5dad08d3c16cf2a8c5b3eaf51b19e3b66331f55a2321e1158f985955991b794ce182d52a4fc450bf54ef735eb7c7d84f256979b6cb24b527877cc01ed758ae28850e3c514fbd9848f15135ae7feb59470336d008348c7b7f293611f6d3c439060297ae29016f12085057487388e8dc333b500d59a0cff3f2f3cf5ebcd07ab7414cabdf15406dd99e22c629cea505742622f121a21d679a40b559143edd23041c6866d33df1a1460b79853ee318666455ca8abe60c2a606b3a13f3be46d15d59ccbe4db48fbcd19ba517b3e9dec272fa6b200154117274da09a43d9ccc93730626ef9a6a40b89449660c03f8285bd03f16652884116e02b876ed62e183f5789a580763efd60fa8feb4aa6ada391b93c868089b4658c8a795fca8e4df7c20a5ec6bce3e63953df8a0a5b2593690d0f061fb9b0e8a13d4626ba5ce5f5a2a5a120c4e9f601762068c31295ac0c2206e6090f3758f163171fef3f1842c8e48ad21118ed83fca30a53388987fd77bfbf0461ca7be92fe4c77ddd27d3e381a87a8b3f93258be15e43481f43975df687af40b743d6c5e87766cec57a0d946a6f46fe9118f6cdeb68fd1650bc74948325fdb5de23901345b6d7958747c262e79249b88b3c423d5eabf767a3fcd6ed80060c1759707d24323f41fab51405edac29ed4ee103bf90c494c6ea381954a2f0c268f69aa394808472e0f5c64bccdecc7b87e8fc34a6cb81ea685140ace3d0eb36cb8f4692786da468aa84572b06655b1d5d488f4c35c958def19a31f7a3aea1fe5e3376f8238b79656b54a668808c7f043e42d4209f85a9d95029702e5ddc9f5ec38e4b09f8baa002809855e6c21c15883c8da6b95acbb99023ed0276975052022109844d216872252b3bf3a2dbac0b2d46deb08fad4fbde0d980c740147fa22b8dc88c8ac26ea98bae55e6215caad98a84646105982c15b879c83c5b6b6a8faaa4010f0e11244c8125e10aa0d6aa80d2b0c5bed83b554f813bf95ed2e54e6fd845ac6106b32c1921e06274280897936a262bf86f8634b023982f166a00a54fb4c3a23609327e2c02c00021fc19350fed96e111fa48912fb2a250b2f0f6c850fd698ef14c7ee9e764451e50ffdf2e17cf86cb1d4bfd56929639387e1459e3f3e4dcf0c2e0f7af233b0c90ce49f0a3d8b26b8ae43c4e2ddc4e59e3f9f27c759afc68c58956d3172c0967a3413a231430834807f85f734459b8552b33b45096803bcad2a1e04079fff6984667d0581ba0221032500c173da12f621606b564b00e5f5f57fa64cf0ed0c350b1357aacff45c35925f29476bb652b8fb606104c07245fa575a5fd00801a03361673721af9f2a0031cc4510a6488b910d985fe560062a65f8833277ecd0a9baeddec616cc5dd8334fd1778dcf4f9b66e71e69c96510f3cf0ee848dbd73d327092640187220e451df2da4c531a1022848296cedf69fcd50f6bab042bab36c68ddd0843d2612ee7c92fb517ac3b1ab37fb99c57d4bcc02d743d985380921cd4d8b0a78063026c720af59e05192c973d36463a5561db939423df2fc5999e89e863538df06fdd8a42fba346be291ba10b16b35a14ca539db0b4a0317a9527aafc05c147bf80f0f39387bd40b950c6b94e84216867f98e2c59e5b53e8c42141a0eb32016e1cb866a25451a0e33444f390a87babfbbc1784f54092a41685c0e78eb9d8413eacc21ffda28365bab4dc0023aa64e725a35d1698995aab2f268dc0f870650701717151bd860b4f962273e50936f6f2bc733a8091e4583d93da75b194b724b78146057eacac9c35f93df546c7e14bf3dde6464f85859d046faa98a437e8a136e10d0df5b95365939fe61038ca788038162c12053a60223e8cec033d986c11e02b17a56e5ed2d9cd7e6d0b45fefefe86a21af0a9f0e50e7afc8ecbafbf25c53f88264ceb4650790abc7b6a5f7cfdc8ed53643e16586f4125ca3cf7af1c88a9acc19e2951c78d72f2af47020c5b600cd8fac92f8a22cf9a270caadc88d1663a63e3289f304f3dffc26f1ee79af36ee4d6d5a5f05fe6d75ff65473d26386727715ca204da7eecc2453a25101afc33901258cea2a825223368c13db01a4135105899ee2a4a0c0b41b70cf2e4cc974c380401f49c30ea7b270aa0d922db7c72ef27ffd4c8bf2a10c9958422f7cbc2a7b94d0439d6a17157284c1e6725a338d38c1ffa4f6ceaba03c1774dbe7a3e0bc283c9b2e44c94ca1d16f1b7ed85cb1abb280b6bd82efb3020671b682e071e8cff8f38afdc68ed8470712fea2b908eab5433159f53314f28869f8751afb970bee9bb769db23d8f3b06a392e7bf5050adcf841c8ac1f702fe0ffc97e3a8ea77879e991765c2a20d19628dc69f6782c1d23ccd5f75ce1c8d81b4694894d56f30613ede0cb37262ffd109043945b9e6facc2238a5cc47f61ffa5ccd73988fa83629c6cac00cc7fb35728253405745c91a11380e476bd01618540e8443c3301ce825ee418ddcef67f09d70bc24f44b826f41db1c6698cfd4b8a046bea4450f0891565ec3b7efc550d01cbc8f300cd2dd9ce388b43a3fe94b0e85816c4b92f8c33f2b762a8521d962dece5df34e99a3ae686aea1f168d201c65c5cd273962ef517ad83c8cf6ea259c75b28299f3d9e9088847dd365240d0c0734b6bd91231d00b3f5776475ce9265a86ca4c13d747597ccc9dd0da897b14a3c5e46227d697a7ec1597d018b325e8fc93e14d1a2de9f4ff22066d7ebb8318713e3f4fd977f9ffe94b8c5305c8a2014fa309fa3f7e410d48b954e88fcff301ae85e1ba3e855458789d3b197495d069dcbe936324c46a5cf12507e2bebfcb98329c3f8f941bd2d8878f47438c00d5f879db370569e0f13740d3e1d798fde52a9a633af5e5168ffc88013dd2af1d397cc8408672a1ada8905a9d0d8f43412eff5a893fdb6a653d768199ff98020dda889ee9081c043db59e09e789622ac08b99c87d03407fa4bb6de3a7579a5d756014a710d591b516df34501135fa3195bcc6d6b198c86e44f54ba4738af34003c85ea49be5f70bc3f1c95296b6e049b8b88b7650b11665de106ceb6fb48ba77e81f07e0bd69a1a30f4d12278900db6d4cbed0a950addbfed611966407a91e0b7461c88332bb0225c2905ea7d2552b2727ac332268ad8038afd2d9685fa15bc6257f25c9423e3aa1c4b4b05db0f7b122599f2d4aa430957accbbe8a243246c78082da2211fa9073155e6e3e1bbd688058941d131c0e71cca84b24d41a9ce4476a2e290b02bb835e86f4cebe786a56429d71619dee7a0c04930af14e4bc4bf45dbb8b19e0a057e0d17469b566f450afb6dad06ad08cde0dd414c67b49bdd490925af05e1d5c08ca5d518957ce39354cfe2975a2803b6e949bd61ab16cd77db6a76c1579dac5e7a0c17165f7641277bf11b86ed5705bb66f1d53b2f40fbce1f4b3e55f8b0817c7125e4618c93b9469e8609fa82ae220e50c32b4322f0ace8bc800167498234a4633da9a717111f984f0719b405b6fe8a3ea66b181591baf4e6dd4187ee0555fddb0100484252ea8c8711728073c74dd47b45748edd9c0cb6ba028f79cab38d5c97d478745e73ee64b9a52c52ab1657a56c75cd312a9df548e5fb084b7db3585e0f0756415cae17b10c3060eb91889d66d84eb365c658c16d856991a33b2d26cae66a0e1367528297d40c93e77ec10425463c878289141df2661ad374005698e2544870302e0655a32f45007fa69cb3499964240c02658fe3735d4907a8cbfd17daa80e3afd991cad35748cd248ed4a973d3c74e716215833df7f4d130283269a48c9e662669c56e964be558c0d2d7bdddbd4734880e341acc2a2a2fc26f1bff619414ece0b6c247799d31bc6ad8cd7af42013d99eaf4cf7341580c909502559ebeed4463233df5606c6e8e169c3edf2a5410cbb0d13b5ebf02ddb823d7abf05e932e93dbee65c6aebef06db71442b8c1c4b0f1ac6098d32d017a05d3cdd837f7ffb335020fe2db8d0fd4073af82a3e40213b5421f9700fa50f747603a8e5fb7f82da1ed61cdf3d6a57bf1efe4e01f40ced79ba5426ce7ab5bd84aa783ff5623453afbf19028615c9610b09e4813b39bc662dde8d5f5f504cf7cf2b459a7f30c2ac81272904cd1ebe600ab92c0bd12b2883eb7164b4d505b2f27838b1d66398d9a10eeb9bd212736d555abae41bb441885f7a070a6ec6b68a951b37bc7f63eada6ffe696e460ced8d05e2bd6ec8a8186409e63b762c2f236e9e9c2b717e319d33a5c6c172d0e36b2baf0c677b868039bef68558d0ea381006215d09174a586def6f309a5d7d209f3ffe1685938043bcc2ca972ec7d4a1e418e706da36a1dbafdd4cbbc0b187b936af694f44962c38d8ffb3a8386dd50b44ac7dc2c7298cbf2219d94cd18019df32477eeb8f7b62dfe99f268b8616e7e7577db0c83b93f2771025280e86ecdd9ac94e940e99141778a53deeef584b99a7eda0e0def498a4bb9670fe149a97305e9c804055025720ca0821082141bec4589030148c093200d5ccd98e49409ce910b29b1821af64a1d473c42e17fa713576cb7a620ee32b3fdcfe3c3bb38c93090c77370547a5e330f368bcbe8d46e54918085506bd7c6ec03db423a7d60fe0db740796d211ecb51d640aaf1da43a753c7ba4d14666da9bdccee1b4379881776473bd994f762fcb4f211d0af5a3599f657408536ffafe15f666b3a4db544744e70f22fd63f446d3a375a77782aa2fae9c93db612bbf508e0212dc1025fd5b93f5865bdfb7fc48b7193399ce21dc97e1b3e839f39cb72d824337b1c926643e87ce835b1cff22dceb4a87874dc790df12b5bbd334f5a471b3ed70c9d44fc673156b727256c3ee0b961977936f068878fde313fb0e1e54bce3085ce62ab3cb4037bb3d57f51def027acc4c8ec5a2863d1fcededb5b38b2d94c322176edb135fbbc966f13fe2aa3e4eb4497df8684f75affc4765eb386969828de234775d3d9f203c60f81829f41cd66a1f1e523f53c702a5fe2e4d9ca33d022fd2bc09d2a517772cf978f3edb8b107ce37a00cd5fa31b67e7bc7a6a6fc1cf48fed7470b5d70d4c68fe4dde08dd4533bbfbc28bd725c3176663e1319e90792078e6b7b6672cf569f8bcd5603749053dec3b0c60ba9861f38cef523974018f38c52f7d7c3e2fae39151f5eedc5efc1b78916ff651cff13cce3da58b657774e2408ee20a74431bcd75ada8c51236e86e0c89f600d62fc1c0d81e6b983b8147fb5592c3401f0ec6a17be3969ba705785e6890c735dda9791b9d3115ebdbb77e13f13e5cd81345aed5d5d9a75ddf41ee8e17c48f9ef3c7e98c8ea57e24983283b868b6d44683ca8bc3bb347f4f6964887dbaf1aad183f2038ea4f6972ef2db371a470c8f40700ba284ed93dc75b7541c299694cdc976beab9b422a9b147a1cdeb716a26bead34ffaa7655379532637ce0aa6ef5905f9a5b229947a10c60d5efe6b51c0a5913cd40376036200da732f84f50952d1b507adbbfa489f58d49275e084cc165a62d3e3f7753a1dd2baab16536116cf8d9a73be3957498c471f407656b3e80a730a3ce280b2fe5f88242cf636e176dab073e0fae4e3e0eff8cc41b097b8225706a2ed68b355626c1c26f2f16bee2dd8f55080fdbfcab60d43d0a5683984e2d05eb88a773ec27d18bdaf3606f1d6eb9bfaf4ed973b40ce05236283cc90e50c98f0f94ce62675f0bef5d522441e03c0633a3e59aa681778b8c14672e7714886313a55ffd32dd99f9b9e7155d99a052b48b7441117581af151929d5c380ae0fa916596c716889514e6925ca2c2d739df4d4d8186d4daefef2d5add409eb980ff670166d286ffbcedff087ef85a2971f3bbf96ba315f9d50bac0c7fee089107e0cfa54abcfd8bd2092baff6ed93b621204b8edf9f3b39adde28cfca3bdcf40b2d06de1b1efe726a4d878171acd11f96c5f4d46ab9da20ec2040fc42a6d3d8ed1a7fe9821dedf2929e3c10f5590510699a2328a046d545c71d1b8aa9a953c046a8bca0115c3daf4707caaaede9c552515ecfb40e7690a7bcd10d70b435545248b87b957a74d8c4f1320c7bfdba0453ee320ad832b2a9b3d9da7215b584ad709469a89ad272663efb4b54c9b1ede8cd8977e7d9e3f581caac677e4189f441ea59f96bea003f8f7a5b22838e38786d7fab8b2a40c8ea29801637f7915ee6731535eee47acf4a88646274d3280edbb8e27706b9c92550e848662ec0daff0b1c5b274765223d376061f2328c817b6bc51c1115e809ed41e1edcd1e63c2c2a14dade148688a15b881ce83df9b4ab7d0149a3c8e2305f02fa4f8ef2e1b5492a8f97a0f82728a0c7bbf0cbfa8dcb4882658b950fda246fd78f77bbe7f1e626492f60ab6da1a02192bd4c814121cdf169af1247bcb0e4eb57280993ffad34213398eef69e547ce6a5fbb643fc658b618eabf3898b37d7a729168068c786049b9ababbbd4d964eb22adc3db0c78c514eb6360402687ac02ad42644b14d07da89f1d07f101f3a42ef5f5e02025ee41e4bbf0031ef283323d2257b3ef8eb6ab03c2eac79a2387126d5b9f4b1c8448131c169cbf3d9f814e5881991d6981750d7dbb5df57ed15da96d5b333a8a1f44d56b0b4325556c44f56111a95e193b7c713f21de7bf791cd82f09e0118b0d22132ff9a6ab406a27c82afc57678c33f41a36c019c952e4a8e0696a769bc0416667b7a839d7501864fa622639e645c764a1b9609f371cb2e18e59fbcbfe1f94b2c1dd66e62038a4188247a2d3d999fc99414b307c83d8121a80364597fb125187484e676fd793e69f9b9f93b480353b8335d7f7d8d3af8319e5ec694568e83799b2ffa553f2b8dd2ba1606a53bbab07a16b2d99431355320e81004f18c73d851504a19764c0fb9e00d860ef5ba38051f6cf9c5e3a9155b5e5fd240463cec544eeaa23f5a3b033faf9c05f2efe42f78ca17c3d63ee769c74b0dbcc8cbb10b199d4b250dcb15e1a6aa0f0772da15690f08097ef239b7492d8a1f698debb94e03cdb3c28369afa037149f8ef4bbba748bf3c47542a97cc6bee1f9182dc959e4a1d1f6cad492c8ea5a8509a0360984b01ccdd6650f8e56328c6b3ffc0c0da123e321fa79e017fd1ed75d84c446df576aa241e70dfaf73dcf8708e62bfb84ae18661daad9d9689e9c2aaf5c341b8a861072cd961f8024576615767c78f70bc63139d4f19f86e7adc0ec0c2339821441b74b9af4de5c1a93056140e5c3bac990e692a75b941b36a33404a069ef2a30db953041beed4c08f4da8046696574d7e16ec20792e87c885034ebc1c272bf7f70b5b3dbf0b6f4aec9b742f9ff569765300c9489192f01a9236798e51abeac7c5cc7aaccf4cfd142ccfdfb37ee800330ab03fe8e5df92b2c2ebf768a463040f8d234759f75f0f96b6555e161be384229cd65450961bcbc5f3ba0196283b1a2b7bc33312d396ef2466b515fdd3ae713bc7a5ea1a7b3f7e8657112109210fec788e5fd705799f8fa0b286c401ac754392d14e3eada14edf87ec881d5fc1e90e3b097a272a56001773c1b111003232aa31d44491e80d1424dc182998d79c3387b1d98e63fb804d8ac59a41b97261b2ca373ca784ab9186e9ac0cb6cffef6e283384d810e68afa646a1d528ded0da549e686940755a125b2f6488ef2a3a1d16628a31ba48a9d2788c519956598e695a983fc583011f136f64794719e7e11407e40d0c7362048550f8f2c49e4130373a2016ebda8eade3804f73c874fcd4d53a686ac7e2545c803340477034d120ef7b369b245221e924194d7f587bf62db6767f45df9613ff3363510db929f8aad83befc91e50335bb13dc8c3bc3baed84e10eed5e8d20c8d099ea33e7a79819e237ea46cb6c090cb120e8c62a59a9bafc45c69843d3f0e7cd6e22779455f2fef10f2a367abc72631e57084d20956a8217c0e0a97792105d830b85038883b0ed2d4886650afa0582e16b677c4267ba46bc3571ed7491a2ccb28621892af552c4425ad933d443e878ceaa7d1b70e16e0ddb0c78c10c63602d804ca208e3b348a987e44d36aae5f02c0a4a505ee5ca9d8c8bd5c631ba0ef37f4383aac774b6031d0fc0baac33b83e95b1854fdd261e0c45cf297ad9c931e4c04100a25b4289dc5959fd48ccbd4f426e0f8f7abbe16d32399f0a1c6325d3b6cda2ce53c73bb7f641542b0ef8bd7cbcb39c4c81831c987d7ab380b40e91813c83c561f098c6fcf7f0e97614476c763f0950a7448324e155e76d4c6f4b685583befd23575fb8684434e26c0edc04eedbfe6a8bf2e9a3b1307f29230005559742689b1aa1d6414d5b422e0c86332a9c5a857c6f1a8c5b911c85018d6b36ec6b5c83aa75f9a90c6c7c025e88d7081adceca07ab1613cb4611869e1d622f3b33d0a5d166fc4c3b4f7b42ec46b76c1e34305359f33268d43b3db5ff2800889d8f43b90380b22f19c07c7c38f199d859f41e470d4501c5e29c51dc9153b76964a2cf7c054d360e472260a363f5dc859ef68eddd7e9ec5c1cb127396a517be0b18370ee509558817a622035347efdb1935ea02cb9e654e1c1ecb08eafa78e2287c60c9f4a946be43f7d14adf8c303315983a86d7f4e4c1588a48064eb030cc05c2b66eaa3af6aa51b8f32e92f2e6b5fc55a2ead9fa72138e2c547cc18ab96ddf1794fd0bfe13306123fe54476b906d5423cd05f0dd72b90841afaa149861801cd2cfc0895d1bf2d0a2e65453a2d2ced8682e78e3d8a76255da354846227be9eb18a98b346ad7266fad0b70c9a1f7cca00484c79cbc383ae39c3c4aa1ea7992ae0e40b0c94718b95171c0c9c00273eaa24f81aa11a341e6210048bcaccb07b8c73b735ee8dbd0796706df803e2a5bb8b825991cc2dd4da543c110b6ddce16dcd2b81411f4f1a3b5f5dd1e5f7e8613e14dccdb32c215230d72a949b41e5eed74c1e2f330bc812cdb81211a5bc16b02d97a547bb3d5dc3b1521f1c308cc071144d6d6195c460c0080c54f561fdf70a5607f8a7090edab11e2dbdc60dad6d8ba940bd975438dbc1b6c0b595d1538ebae52b3860f569ea786b75cb7e4067754b2479d1ccbf9886dc2da6cfa6080d14efa3dd4a952d6fef83643ec807b383a9d65540e7f0252f8456e1095527ce440565152fdc2bae1bf1da201a4d2905021e33ac0692e300ce5acdc4cd316cf9296506fc0c3d1d9d1d0c9f936d9c0bbe7515309ce20411ef4ab77dfad988c38d96c74b1f0efab33fcabf7eba317c929b71704171e13a108714b4f45e09cc02406f961697747667d5db00adf870a115ad4366c96bd72bd009f6a1a194d205efe8adabda68d96a526d1d242856f28d6ba70b9fb7142f2a15ca1201ba572d6f61da6836c2071535accc9ffbbff37b71e5ee5e5edee8c941ec8482ce04f4c7fdafab9978fd0763d32888e9803641e18e78dafc0f89791dd08f4764140ddd6cf2855cd408c6dbbff117ecd2e82c05444805e57f703ac8222720321cbb4743efe56a76ccecfc226e4b287f75a0e58209f974a5da6a4e5d0eac8c74957dac09960ebb102b2b05ed6738adb4c24c14b24ecc2da436df960103bdc5d2d39e5d032fe162d205b7761cd49e966b83118f74bbf010cef8286790db3396ee24ade17720f2e2670b2083e1a069941b48de58a1872ab0116929b5bf1fcc9cbdfcb1d61f22a0634d91f48c056184f9c99a92d47c840469d32dca7c0bae9572c9d082604c761f0af30c1a45689de4dd4482653162324454e0d226407e1b8ec08d57ea9abe7eb3af3d5768c1967e091af01da1edb98c8ee581a6a2d3434328b5aecb9c66bff89b60d988ff9fbc9488e514e828fa6fcf1cf219f3d49ccf2805c09be8fe3a3da368f5319d4d16725733f812ee8b187621449b8a1ddacd7039d180022692aa95ada864c78994f97fc7220eb1ee1c762dc9e4910859c5d5fe7e133bab771740a063f9f71ac03d32c138b13d2872d569b58393b6cc5734201ca4a6820739df66ff041944444f4bee59ac051a33610f49f9ec1e857b61eea2ef39eb73425aaa73a69ff871be0d795f9efa9d52b7a8d40dd1cb2609f1e3b718c531f416de2d142ebede5edeedf53586e907aef3a54b333579c6b677ee1f6ea111aa616ac05d6892c9234c4f348de55abe4633f1ffd9fe1b55b59599d2f0eadef785cb0d419779b2e652d1ed6bdef3a9d57e2f4b98672ad88a3583a936e38580fc2dcd0ef8311f79ebf607c8d611d9554674dad6c27e3c05d8d318a1ce1f73188d9d327b10fce1a709c2368b6e1049d0bed51e2913dbc2de7d348a777449a5256cd1158d40ffbdbacd222073591f572df5f1ef1239254b17e50f0b7b0e88fef73a091f732733cc95d69d319241a70422e1a6525239ec872f0bf670b7337f5f785c8efad9636a666cc0046902eae8eb0e95d6e40f2c023d5a405726a77d1a7ad3ee9d6344ab4b48c2bd441c1b83410bcbf7da3a89fe3a26bdb079c9199a4067c9616c411af9cd97309b7122ef1e1fc7590268bda4837bff7b4e4d9a403b0cf78bd09ea63d5ae74df5954ea57d6d403cde7415d33cf365f921354f7243645b9de900480f177f983df3e6949b79668679552d1870c5968ab79bf751b1337c6eae8089ba8262367c4867d8ebcbfc3dc470f673408da133b67ea51bb93ea11abccd5f9e7735312454f604c2a692578ad619e8ba324dc5e849a3c8ab93c8466f0ff22caf67bb8b03f743af0e5830747c67be40c9c28ea584d52f69a869dc0dc14516a9a2b679244b5b70c1f186443f3257b6d146be78958decf68aa1b9d2de88bc908746c2d65a31a02dfa4ce02af64e38a295d83ecc49834e2f22df173c107213cd41f95e3e0453a6d536599b52f11941ef547b181e6136390ea8e8d4824321dac7fe143211af79e4903846767ee2f2d6a78433fb2af5ae29c8c930d2f16616d569d7824dbec08bb7108e9c621d364af3dd3f56bc7afaa03ecc232c0371532dc033fdda996a5d51069875623798dc94b4273ce6192e3a60bedbb3c0c7f2d487656edde1a2cad5a8ff7d34b27dfc579c8de7448bd2621ee1e47ac6d82d6b8eb90576477c209541c4f6067e7a0aafc1ac90035032d82dafe55f29264b4863ca5ccfd383357acc6b9a4c69792b4e14e30aa08f03854509e9040e5b1fc12e42ac6fa66c32324352195138f0880d86dd83d12b0852c75b5249b91bc339a5ed86f98330d064e11b449be44439a0529b556b76ad7c3405388971cbb083eeadd1b07b67c9fc660e852260e7c6bb686a2c095cd023a630a5bcf38a51cc86ac7920d3adbaf9c99a44b61033fb25e53366c67f1856aa6bd5c574c1b55f43f0df311df44b9e567a0350bc32fd8699f1ec5d2fc03600a2dce51917278f94f71e429fa273662ab5fc250af96b6854d99075458e225c1cc0d2fd5435e2126fca7aa6ba7ebf8e1a74f628ef71b98487bc11d4a3810492a14f09a113e6d191630d1eb4d44ba4d8380844e851e4881f208d21176c3d91509148958c6b5187b140afe3a8ce1380ad66c40f17b1b82a876c7d71cccf2b04b588de6fda296e84a71bad0c228d08ddd778a89bf075ed3326795343d7e0c046479c779d8013d217e559709f2d51a02024be9d861ef1bb072e973c62274c02aa6b6a49502537e90913c0e17c504fd6e6a586209b0452e6fb48ba97ff8cb162aade0f0d8542de017ad79d37979ca42e03c8ae5bc556faf2510661216cd6338e474481656d039c04d48eab98a09f7ab2c479718bbb6624236832defbe44cc122f5c36c1a178c1245b09c7bbe06ac468f18b085fd9fe21ab917d72c92f31e4a5be48bd2490750084eb4ed06a9a9d07ec6bcb4e34a903f013e7f429f25f71451659edd2f975ad0de32e05ae3364bc0979a6aafcba2692a36c79ea44041ec40d0059d5cf73466e174610de40335c9ad48167a0f7512d97a2b6cb335ee992d83b639c01d9a8fb01a9cb9598629172829f8989f70a365bddbb97d44aa990c5947a9ac07e671eefe3c8682017850d75f460afda209e387084ad8e11ed5cac5ec3eea25bd24443ae1869b030d6f41a6ff573048a19f45c463c7d122ec16bd7e32631af79e16359464da9380e800373dd4e5e844a5634bfa129e015663540ddfd8b4da3c5b9ca7f01131e151dba39a208cc56adad9cc70182205ceb56b9046ace1e2d6a244d548cfac5aece3a0077990b9915d3778b7f2441380f9509fcd89f0af3dfe54d44d05a31198716265637d75b4c5088be49930b08333469253f64dc15ccb9b995e15433d0087eb869b9e8d4dedd2bde5d1bb4eecea9b20c740f8c190f076dfafea718a3667afd9d8d9e2b2ce668ff6d346685a307d44584684982ba84cc3e8a213e005922b7777c50d8d3720fcc5649d9219d065e98d212ed5e989d10f96a7aa5921a5ca3f362c30c89d805e81f96922686377e4bcc5435b82ca75f3587758440af27687a408a0b6a15625424a9ed21c1ef58c7162d7a703bf5e36c061111adfee4c099351537b5d2a355cf4be00cb17832a03893de4543931d1f6d3ebcef84ef61f5f609ff7fb9f85d2793a787df83604b88b2ff7c6ad2f6598abd4d39596271b930005e23f602d042e4fdfbcef9174fe0c2b061f35472db3e97f10ab09a1f4dc3565231b48d39e51e002e5cd644a08e18db7a3be901b6f52571dfea13e6c7cfe179b52f8ef6423e3919905bd5e04daf08827c9bd13f6e1488cd0a04cfcd850443d5389c4ba251a3c06365e48cdc1ea5c2af27d262eab393745d1592c211b8dac952a930c3a2e24707537033da6f8d6c2e8fb07f3b0b0e6caf8aea09c8a105a8b99c2575ad3a1a4d7667e7344c1e6bc1d247c65f8e9770fe0c7a9951b645167c9cd1604abce2fcfb9b30dc15cd9993d5ece2203dc7a0a8666ce3dfe87c2ac8a6fa67a684e012f0a9bcc5ff25cb334f4fa9a76ad3514ff5114664557a32bc55643851f21ef644b0992d4f28e533b3ca43f8758cb88ea7f989d96dd91b965ef639ba60f14b892ab6de99bfba5c437dee44a6b5c485be7cc82d4a8ca08bb0de5c7987122a566589bc661e62792fdfc168c0fcbdacee2add9789f2e5ebc0ae92d0a235ecc7873ce1b40bcd74d1c3b6d5598aa0ed5b5f5007e293e395f2c2921a6e7f446a836155e4cafd075b2f3cfc60ea07893ef8eb40b9d59309b0601e3df57c2909340ce8089e9ed2325deffa7b310cab43ece4e4d0d27c773c10075228ab59e7f8182965abd0dcb6b652050b2d365e7b1d05f649b19ce7b62f47ff95a31d052ad4ee397b2cca64e292c6cb37dacb1aeb0f547ef44c998b4b1d7980441e01b7446e164fc643aee74afe9a6c5a8e69a0a34f1829750167641f1749da69f44809109a2a4c5d0312929049f38f9929fb7191ad69eb2da3e357757973d86362bc6c9511a347ce88106bce57e35c4dfe9a33d5d76a1a6d7cb74766356456b7a15a66b7d2e483647cb594768c48402704e09206985cd644a3e61a51bdf1c1f451a55910932e37e1d11e7e3d60929d96a29f93c7c382870d29deaf4666f9c6498becb1dca7a0f03a63998377b82d587aead568928700b483b71483f53a2543c1eed3b9b4bafaf2d45e10ff99da3943aa77ee5c2e1a84a6f0578654ed576171308d00096ab25c93f244ba3104662f94298bcb6a7fc1bbd7f3bcac219b574146ef64bcf0cd1feac4b74bc276102781f62ca04eb2c6d085012e0d06a2c2412ab1be32698f304d73b0a533c64920d8b33530b65e16fce14b4d615f1bfb236fab226c9c90b9448490db19bfe5d529963885ff0938a175e112d72c6c4327cef3f44702cdd7f83ba63ddea8565b001d6a23fe51eef3471f828f5568faed064ab3e2390c86882b5a6ee8782f0ec6c37d98acf968e5bd613da46c36bbcf9f9f0707590a19c28a509b27a8bfbdfb730032a64bbba14471ebea2c398a506612b785922597ee76139034cee2ff3e74a4d1eeb471cdd7f43068bad806a26c8d86412362793c7823e1e500fc4495399b0011a6988eb76f3be8047a849951eb253ab9bc2767db88e5cad1100b1fe331b68968198a2e033211de0c804009f95c409a4e13210a30cf12d725bae62b6f6ca513b8e7d9ca8eb0cb9b646bb178847fbd01b44b4fe1e6b15b0ab7c2962874d5fdf70a455f03d2e4454163e89b20e6a1d8033870e1e177cc6d856457c3624dd76227bf6b5d4f0c2243dadbc11235dd58a95a272903af1ee6671b636d8f47e90bc36d5c6e070d9067e7d81d504f566d040c3f193aee5b48195fc5910ecc4926d1ebb121c2d451d3e99a2386a69104bb5c15171ddad5caf8e09d7a051b33c1db342cc4ec3d81e59ff6f19983a44ca609a48d86a053d635ea49fd90b0bbe55be786c28205cbdaee73e6ed957f8e93b8f2a9209555609d3346a1b044750221bf76b3d1c10504ab8aabb28c0aeb89fbacce4dbc40afc27e0b3b9e86a3913cbcc9bdd343045e0ce24e72c6f52b6852683fd9a61533e5994c107ca65a0d81d4ee5322c0f7168e4c2b32eba8a7fd783eec9ef68d7f20950595988bf1f857bbd3e184aca1ee2e7f5f71fd30a1075e59ef1103345a8835806dfc6a8a246dd79b7551c26a9b16a7628dc65ea8c930abfc7a7cf04f1e475664e1373cfe6ca0396d4c750d114081f22d33d7981eb536e60ed2d3ea5fa72cd046c5fb110fddfb14466f0d8c35b2658eb69742505e7d1d4161f1d4c1b9af6e373fc984baa35f81392bbfb56c201ae31e2b6fe2a22680802d51d9ef98e7ea830eefa07667879bc93921d4bf4f117fe0d328d1586ad150b58685eaaf61e704a2fc6ec854d19ac27a9d236d88a1fc310c23255187c88a5e2f7684a02098fa671d68a592e2096466c5b87191efc3163193123feeaaac57b4fbb7d78352b01f5ddf29563946a45c325c74c70e2af45167619af91d10088f0699695decdea4b41d43be14e0b0fc95c150e122d56dcb90ced5efa1ec926bcb5eb55287c855f215bf7dd0159a7cfffab8b8f897ecef49764928f3792c5e100c8a3fa3044361276a2b987f57624a509b2a119c12a678d25791101d182af43f1d44749055116496fd0ad78598cfd78bb185d0a5b02fa302f3559a5f952b9ca6e639da088792470e04ce9d76c431d94f0633b7c9893c3a72e01289b8a7573e60cec814bd2e2a553eb1728a9f629cc9324f93f7e440a11a39a437bf3ed1ed4ae684904cdc4fa3546e583adcd55d48a8d0ad228e4eca534dfa0cfe35dddc7b817f9a01d9da79ea45cc49915a2935d6226b7e0b99417c55e29c070eca6c394f3994026fdffe5382a05ef7e348dfa260c790b9549d5ee560c7a83c1ef7f413a46885df2a15f14d81d83d4fa51c709d5ddd62a34b6a8d531e04c48920e525e98875cf188e8c800876a3186d081472c3e3c5180eb3f8b1dfe1b2bd18f271262211601f7b0a7ed0620c5dfdfcb981ba7a33b8b10af6995bf36b19889b9938a460659e2454ab63e1e0d423ad0d984d4d3c0874aba21623d301d12f606fc3296c427dd4aa1bd6dce71c0f8b31b1c2be774382b8db3f518ffa883b97da0dadd6dfee0a647ffaf1e89515ca8a6adeee729e35a3a3b43cbd4826397b4b7b627e41ca18eede322eada538090e4b924104dfa67909d1a4d4941ac4448d911e21c6068c8d094fe3359bc8a26ed66962bf618c6c93f9177d5f93527789b89ba3d68a9e1b467d3616e26af40dcf7e8e71e6fd1b88aa1340ebea1c0e8ed4400f13904be8e90cb4af01bb7be6b8843da9f878948cd705f2db20ff131ed1cfa4695d6352b78a2d9bee47e45f19a30cbfeeb561853cbb0ccd307a5c95c9824001f9e74ca4cbe5ea9448f3ad32cba1087603c3627ec1c11ce2d2a8692240d650735dd67199fcf92bfac80b38d535d4c40063632bb63ce185a3c5aa992b7a28b761f0683010d3a3c058a07d8dfcdf7e9714c9c639cfb4de8a8ee7bf4efff8c5fa8ded4d8d5bf9e00efe6edc2ffc87b886a071b6e65465192361c76ef37897f7eeb2d13fc3ed6fb02bf2b9b7dc973d4a5239cef90bf5e60fbf5d6fe601963d3d39fc92451d5fccfe61d8873bb2ec8e386d2752f7d3d64f3f01b90f6a8b13ec9fdef7842f7d7efeabb2e6dc7a2279860fb434b71fb32eb73f0f199ed35e4832a03f1409b38eb0b76df9f885aa7d741f777b24feac604b4dee56aa9412461c5784182c78129ade4459596463f7f53eac7e8eb8b15c2747a3dd1a848c6a5ce7974a54d6ded7b739ada83925ab0a1c7cf2cd2a1871513c77fc80f8ac1c8b12ee425bbbeaad522e8670902a42a597f04db17ce3394e0a1423ec869dc9de9f790da539d84cdf51c4b98c5803a02c6141d1b42c2fd896e4cdc9b9fc2854f5d67da69304f70bc3c4dbafa5354a0b896c60de031a0fceb8d8c1c2bebb7ebf1feb0d549dcaac1ed75ab7e4e6ca0842ba63a95fb17ec222dc836f37171981b6b15f6680a67bbead684b46ab654d35843f036b0a51c24a73d0ad34104b473c59cd7f6083cf94079024b5f18d50b9515dcfb63b4440189659718bd1e288348ecc7df7d80a9e8f65a8611049fd9d8ce67e831283a524fa8893c9d0d907c05fb8ea777c015a1b707008dc17fd1c2646fe9e85df960eb1e8c00e6dec6603ad15190860e1f1cf1f61a332f2df442b7a48e59fb5914ac307fcccd938ab4eceafd708bf0fde6d8017ac1d2e00cdc3c240978173f357d0f80847edc43d1498c1368e8251fe4ad885606a0078415e17dd3dd3ffd23d1385c5a02fea1688941bd1dd7e547001ae785bed2b7d02b117b4b665ce3306a37af2017009b41e56ea7b23e8a7c0f8ec0766a690f0d8dfb105156ef8042413af70ae21d1e75bbc6cf8df1017a144d736241c745774935344ee98b7c964c2e522ef4d2f71f7560704a505b14fb90e5b1fabe63b43a17c3c242dd49c46135d9cc8e1e118d401b64410fdb89d04b851870846e68db8351733ae52d52bac06fdb52efc13c8ff37187a755dabfc3018f6efc4fa1fd06aaf544f0f2333083af3dc6f335a957824187d3988ba57e605e43f68deca71724add64be8cfb852099ef7382343ffc9fd367e881f3b0aaf60f7c4d7d5c7b38f687be5027a7d675b827e4aab8856986bf77858fb039a83dc9cc4b10d281a01b026aa81cfd5ba674039c9cc6301ea3a7f32a4f28bfb059bc530d5ffaf4192a0a9eb0fd1137380a195ee1f3ffe308843862a6bf97e4a071f00791d7e7ad63f83ec2b22e3ddf41437fe96f1f32068481d3108e6b47849641eb7dc8e969a596fa374e1919517129d9d0d6d78056508c39e0df6b9eeb2982c2d98033193aeea3ebb47d7ca0663caddb4dcbd63fa8f6fe4e64427bf2ffdafdf4b89bc2625f4e9fb31e01e894321a337e3cd977aa1dc8fc5fe3fba2d504dff188d77e898ab92cf566377ff837fb106b8bf986c903053ec44f263acd65661423d30c33821061f32e594110ff80588f33315b06f6bb1893c25fc0a031cd0cbd3370f532c5572e06dd70ce7f3e9a1f0595c6ec10f5de3b2de433dd9c99e5cf1c6ee3762f30dca011f14be2629f56322724fb5f885e3785914a1bcbd017bef734471916ea0fc99cf8fe21fd6120ba7fcc1466ed1d7d570ae0e4e5dbc7602331de15d9ecdc821d65d79da065a8744cd47f37eec88287f9a1f3e8db1fcc7c88913afafdc66298b6f126fd1bee2fc3b0735baaaba2a324d607ba179b396e830e238d8d884e8d7bc018e1d731170dd447bca53a2b5a7bbaa8fbcee62bfaac97eaa96156d67395cd5140e54c2d2a2af27a7e2441758528d65e5ec7de319fcdab11ed2500de72962e81ea3d297683045dfcd54856393162bd9fd2a25313003e10d822011f3d30df0994a752c692c6233f60b2c8b3c0529bfcc878685bdfd1aeb6028971a0b16b86dfd40f6f34943cb19d1230e2ee8be4b346748377b4dab8de3a2456c22e06e0c0c72a54207fb0896fd02538d305e53d20b0ec8b7c8d506cfbace3c43a778f9e60b076ee3f6769cb070ddb077bce84044b24d69a8bdfd91738f48b62d1cdac43f20f7f56ec55794515eed0367dbac7d45f2afb47c04491455d41c5be1b78c410bdf11d4ad2a53b4c854f9b111babb072697727aa0ce0fb907f1d500f8436b57fae4511fb63eb9f84bb327cbdc939476cc577c11e6b4fb6c02f5c122e541003e2feef34b763424b3f66b9600dccd931e38d2475b0edb929f1288515b644abc3327e2136944d835814498caf7553c3f724d4c102922a772db3536562766d0b06b8453ad78d139d426ea5f882d11d24bdd728e1432ed77c77f3fd55b740c29187dd6f2a12d94a1a9f096f5cdbd00d754f24a23efa621338ff70c9aca84e4c8673e6c20c630d3e315c223fdf15ec03d1968a67b7593d1fd6676c5b586a40352270eef173badbc307a6be314255c84414134650469a960f0978dd09b711ad5d1dfedadfe916503e9c7d2b31b170012a7192916e54d541ac5ca57a4571c5aecdb0894084d0b95fd4673c630f7b5d55681174526928b8a9159fecd90c6d8e50c5f2285c1a10de52e5a3b8d273e075bdf8eeaceb75da6ad8120a90e252d9880271d9b61469d08c8fa02b4ce64a3379c1bbfe1fba817488ae9373e425e0f1974a9147efa9ead2d4105662eda3737edea4c9a63d17a8e567aac50897a0ecd72906c28dfc2e41a5df5dd61c17d7f6a60604fad402c8cab492d26f551585c095ce39c17e0fc598a3140f34aaeb6e486b2ac5d458a2f1cd1c54b503d34623dee4b93c9dc02fcfbab72f621cb0e90256ad537da4a4afdb38ef218922723d1551b8bd581027ac79c5578695975b096d0200d48b0ff1aa6548badd57fadbc6b60648a4f8f4ac2699d98343e7dd3d0632c2a0cf7a6b3813a0e21e8eccab9cda6a91dc71c3c42f3c2f564d9a998b107b93211ba01ef7abe7bd8e991bb15daa16745427db628ce4cb393599bde748c1731260609985c0e1b3dfa512a42f051a7510dc3e26a387ecdf236569ea6cb1b469a72336489fa5e9576c3d93fbb9d7e4b44216865aa75afd9c27c3fa497910acb90d1e36d3e958fad04fc2a4f33e25148ae183579c210fa8bed9aed5661943f52dbb362e25b036aee90ea2a23918228e466e645d878670c81e4b1f2669c1cacb0585afb9db3b64b7ca2f948a48d8204fbfdb2994e1e87a7d2a8a7bc49e553f844b86cefb2a414972f2a95b6b7dd650b18298de4122a258414464a5df39e162e4cd4d4de5aa5340605813ebe403367d7f157a93793f595f53aca8e2a4d7ee4074012a02cb5323a417d8eeb494eb0cc17033de1d08d65c4a4f9ddde4cbf28698699cc94163a910f1de124935da8a45019f05898fd4fc183863573b1f0d67572e29f8b97d6f2472f8b711b7cf173ad7f50d3a810e506a2ff93e270281a5ef40dde744ca6ca4b71e811c76d801457935455bdcd5f855c3d29d2a7d3b9d78b5c48b88df16362af28d795643c440b4be67229f7ba80c4bb4881cd168195b3a196bf2e5531c60d60dc6793fcf3866d691cf8cae131be330ac3c01830c027ccb88d1527d6425fc37f48b27e8afc958e277c4113910103c7d274b61f22b4a04f7b0c975385979fb794c20dc9b2ca5f8cd90be81aafc8448fe77ab128f429740b51918408ce4b4f3c05423e52a0347bf44ef670812a7a9c1a9bb93ad9854f1a5af49d0bff294229004042f513808a35fdc15d07533ec9f551ab32623d2dbfbe12029110a141e179e4d2efbbbd6e4212fa114b78ee6ad47d68534d195204d625040354bcfc573e98073d8bdf549a6d3485c382716bcfe1ac369898258ab299ab2c1d1ec2f3d79482903038841b46663e68ca4d6a4789f0ba25598530bdafd0783c2bbcff336a54a995f8f67d092546acc1150fcdc49b036bda364c1042cd0a88a19b9aa890001178a8b63edc7b773707e26ffca4bebd34c8cde6362a4afdf31eefb46bd79db3f49ade0b7a5a9e134ec2c5d0104d3848607b04818f2d42c7f07749c4d571d550c5023442af41bbb78512eab19f8f7674a126fd20467509033cd228564d178596f90d0c55260a20e153a6f5c6da7e1cdcdbc5a192200bfb1715311b7ce8f379c802673459710d3d2682b1ace45be05d605fed6552f7f77a6de7f6eeab7da6e7ce8f78a69d67a3fc478bfe9d7fece3df9f8a13e95e0cd73cbd49b3e371230cde67bf52a34799f978baf0b5ab12e5ffe67c2f027a8cb8d59e610e749a61eafd76f165cfc1649ef71f48647b7061e1669de833b89d8b5cf95e3384ec121a1b741b13b7430ed13e5307ac34fa1fdde82ed4f34bb3164292f40a57dba8d8a34fb76816e746a2c1b85197dc3081273fa7d23c6d296ab2218b76353f59388064cca506d4d95e486ebadab684e182f53a84d851e0facac28a7863c485c039e862ef22a152e74c17b250a9a10db26196755c0938a193ffbcc80e62d93468ea1998481dc5062a3d89ec69a2ebd7e3cc9d739145bad5a421896eb7db228eba4d5869885a212a382dec9184fb2bb12f43d4a175414e6eaf22f5c77ddb3488e539a920284462ead356142bcf3041cddcbeb22cf6a8f9c5261f769f22b5cee8f77b3a0580b44a8f0a72ffdf1251abc5ed4926ffc98851e150de81ff441238c21a8bae46611d933c3fbb94fc198502fc0d639b45bb04137fee531b1cf9ea4898b52fe3ac9f0ef9004831cd34490ba5b957070f302c8fcb117076f67ae27d846de2ebf9bd1ac7aba319d39f3b362c774a666225f58652f7dbede7de62e5d5d0858dbd5c90be6aa5dda51889584019af8a9ffdf3023f686ce85acf977a6e2cae426bfbc516c432f6cfe1bcaae638808e992e1bb47b3fcab9b00c75a8173c74f589730f38f4d6087b5440f413f12ca5612e095125ac4b300e424008c16f6fe99898d129bf596bd25b17060ffb061b3b00d5c43454bb21f063c7b03d062cbcd6be4ea4a86b8deab28c7bfeb87be73c8a8959890216864a6e34a58ee9ce02d5999ffc9decef9cfffefba7afaf3d92b490efd4a83c3483591a2748b66228cbdd1e7420fd46f1d26b0d8dbd83601e15a5d76087b89fddd684d211da4fc42a611ddac22dcb3cf6d6fea51dfc20f0cd3c3eba248ea9967fd84c248ef6b434b16e0b50447329e1ed4ad799b1a0e1e89dd434cecae57d6949670520c67c9398ec2220a77efa2e1893420bfd9afb9d50b2d8e5173236941285a45670292538054ee4fdc9effbad56206d54a78ff9d12916ea0f1a44f8169e209a0a3ee0fa71fa1153ab5ac683770a1d48e59da4ff59a8feb9c364f7a99d25aa57cbfa45b76a010cede3ec6219965f0550bc1443f8c6010a8298339343a0da30712d740cbc81d24fd937674451a1993bbd75aea251f0b43e76a4333aff96ac2b34df28ec2a9fcba1d5a87884ee61645558b3074812f4f53b0884ec568f5d8517cd01cade1e903f784c6e78869bce9e2093253f6407452ec3ecd9657efd68191d648124c2392f0597022c91ff866a946a2a1fe2cf37d61b99ec177a85efc6cda315b1b3050bd70186123a8d1695e5d927ac39733d84024910da51c09a72aaf082471980db826fa885d6aafad98aa269a65cab6b0b2f992940c0fc6fc1fb6ba1e1d79ca2bb15c0580bff044d6076722dcf7f8cf5fba79411e6319ac2686fa8d19298074af70b8bf8a241076ce88b093cdc27699b66127a3031be25b6d82f0543a5006033d02d5678a3870635f651351448ad649e90092cbbca12fa80262b42a9c2903454e30d56a1aa586d20f2494347a5738cbb5aecca0d6b226a7be8a595337738b70ffbf523f47c815732b0c02682e417c3bd3f3d5984cc04daee30c98b5d497234c12f598c79040054874b3ea8e01d91b50080a498c2025cb49d590dd207a6ccc7fe26321814095f28518458d7016925b4b39413882ea1fb1b2580e58fa7e69bd549e1b0a1648440ede71cca2d68f0fba44283f498c3c5acbbd885a187888050677f87728a62493270134ee7ab158ea1da10e82f243908e25e8908885a2746b8e448d3a02c9c3d0026f36780c81cf052efd83b1c9ffff815fad11688a308ce38e52c632eb9e4cb59c26e22e8a01d8cba3148c1f7af3ba17597cd95a3c9b78865fdff3ad553d340782be52f929d83f6f4d6044ae82731e51ddc9ef43bab1e4ae9a22bdae4e98c7bd3de47efaf2dfb54719408e404da99e5c834b5f3b8183fa553fefccb5f2bfaca3a4e5338a7810b4fc1d0f97a13403c7599a607bc7bd121beb627c83fd37283487df756ea7d38b8db9fe57ba7f9ebcc6cab3ecc7d70127a0f0e80a111b4309ee7a6118085cd548e8b797bfe2c4570a9ebdbfc2c44cc8852f45d3f7a7e6778b553f42a24c6c299b5fd959a111cb9c97b73c23a13dd7e22b980c645e40cdbe23d0ed56dbc18b95d03ae0e698162182c9f6ba881a4849681c3ada9fb6c906e7eecfa39e3d43780852e42121622f84235255fb3f7db690db4c3d1fb8d86e8b8c4eed38e05864fac37d926c0a29c4aaee6f316e37bdedaf8eb1fd3d957b9d0a24197a3539bc9bc76bb314bcff9e84db94bfded0c195e28254e6042e6a563e8bd12793134a919d48d012fce325c9ba590aaef758e70bd43757a60dc65a6a9138987008bc14718be687ba42bdb10654a00bc4a644f65e00a61238e892a70ee5d56d89b1345789a6f7e5000c82e5f9763385e62e1cb0864e1a2e89a7be3073adf92c4e8854a1b336c8c5414a768f3ab4a9eba29eeaefc1f221ef954297e597ba3615d3e3792a332ac892a0899fb259039fba984484cd435c1d8bb01d4bd3e63581dc277440eb28be7f1966315312ed1500e9b07a39ba5e6ad63ffc146f1fcda7aecb8645d2a29a7a4128243041bc1bef1618de2f9746160f47c28f6852e466e2558ec0f27607e9ace220347b6ee85d443c8865c1c782c88f2cee8556f6d37b7a1de249d3a3c52ad60b4c7fc83fb3124a6c7da2a1ecc2e9a1f0a17a5568287e0404c60c9b108cb381325606fc88043352579b5e3c11e84478e8ee72d9cd989e4ff6e3aa1234f7d01b6cdc03fc7c7e1ce17bee16878301c8d2de0f64de9bedddfa953e85570aabc00df6c5e8844c4ae92b82b2001c16a60d582f960e73514e19a1d7d97fb1cc82ebeb0acac2c1960c8144a571076c28caaed6cbf89f803a96254ee3588fb6c5169025046de87a04460be98b2f22da176a460464229239549091ff904654dac96fee466eccb16247b4bf75b0e4fd1feac1a67548d055705e75f82921562f76c5d3fe9823c76702c33a8b0dde91b4e9de9541882b6dccb1d4bc1fc8bca7d7bbf5e930f94caca5a7d455be1ff3a05b3d3b61d6c5736b9ee8451623d443bf977f558f425bd6b9ffd58cabef15e5f6e491df483d4e1fa493d5415ddfe79e1de7b0a0030038ce77a30822d93ff8605625319f6d363f81d237836a2ea2eef526c53c92d7a43100f0184195fe42e0636c0d9e7dcba9f69d905094cf23510a63003a30d874f7aa670566d89ecfadfd4622987d5e4ba5223828cbb662ec7c2fbc881f427c354261d028688879378dd18a404fd82784e63b983968f3a8af2d76ac10c66f8c8cf336bcb4292ae1bcf565d0ac5760f324bf0a78084515c034b32c8d71fa53f670d0cd479c43f16aabce9febb19edab9b60eed8de41cd5989a2ffbb5bbf1e32936f805e0e3845abeadb68c05ab6b8205c860b73f76572c45da3cccf247d89249ba60d3c72cde0ab3ff9ee1b025b3948adbc6e02179905eb6365be80ee3954ef3a69bdebee464ad0f1a49584dbc88c496ce703b18436259bee9eeba3596a13ffbdc222103788ab1d322749016a8879f4840f52841f018f87f09efa5dcecd0e34932d73fb92ba4b9580261d82c63eca0c56b0f1a6d25d01b70f661fc0f7d7ddc84f14d0addddb46d8cda3aaf5c2a47152135280cdc9bc45dcaccd52714e209f848bf84d1a43c37b8fdf9f834334f65e4ffd1f6f18bd3a0479d008bd179c9ef18c8baca0a2dd1e4d79d85858304dd3b61aa7d5a69b3910780cb355f8d01f33e13f4335a95a21a6729857bf1b2397d9e2ad270739354cf8c06a3137d6fb74b872ec25ed45534881cd5818e044ebf5b540210913abd90a0b29c28b69d1856f01e01eaea889ac3f67e058ea8d83d5395e3ca98a89da33eec58ef9ae016956c3c913a647632e87bc54810966d85442c0050325cc681b9122a2fc5b842860491fec9eb277a0dd3ad7958d2ecf91bca76bc0374bea8a1caef412040258e846f2ae86aae6edf2c96c7f6df29b9bbf1fe39249cc791304b4b8a886adcf68af96bf853c6df5a1c3d48289ea36041113896880178dcfaf39f10422de08a79af3272a95621dbe26231e5e5e9101d632291231d127fcc4481f6238640038bd525ba5dc0e18b57661569bee11712711cd0bc4a70394f55207e7464c7caad5888e680baffcb2810c7d1e95314e322b2dea7e024132565c788b293162ed4b586cf327b7c1f3684161d21186f0e3b87f160517884e9f2c9340a8f485ffef92129024c15cfc82226102e74560bd567fe2559b679526acf95f6b8a75a0601b81a91dc6382f59f912bb40211609d5d8cc201b177e7695dd2a8b5bc5fa7c19cd92c024107dce6a004d031f217d68d86fe4685c850abc2fd0f34a6b6bcc654317b0b125be78b863494ddbf6519b245f927a4673869f7213c1458717c6fda6b884862e74b6523de7af15634197513fa2b4706da848ab6bf8280de1fcf7dca7d7b127075bea38de190a33d7812ad6bb09f05dd500f75fa9a1d3eb76a31262f690d359d82e437d4b752c4c904872144c847f0c7cec02ceef18bbcffea4f7b79a966c6b566bd0d5278d48ba69a2e8e286422d8df8647a78755e743e06bbc19cec962033237b3134de52fbdb470be8c6f2de7fbcb0619fd679b4cffd9c6f830bf0f2fbe19fbedf0d8f9ce85187fe26d90b3af33de3c6b7d269c1a6b474088596834cedd819c29566442d925481809a5c6b4177062179634d4c22ae52cf659f28ce0b52d79ead2b242e74c2d7e4e30ed7839639a4222cd41b90e166592ca0659449e6a6634cdd459b24487757dd2c21c77f6df3ec3bf3ec2e2d387b0f9f7115e3e834e4b58fb3143e564a689acb3926e42062ad3d4a4e6b0a455dd81427059aeb8977ce9f16e3f1b51cca924d96924abacd385d081cc1435d724ac695957a0094ad3d1b2ab3ee3d0bace40117453a2998db18a357bca834bb394230b9b63192b760725a0399956ba348d452cd889640fe592d9a7794a91810db18c25bb831c109c4c539ac94ad6e92454a033859a6b0c2b5ad725d004d954b4540293ccf7109555739550b61be7fe4f4eba0919a84c53939ac3925675070a4137194d6c8e9558b333a880e69434a791acb24e17424750e3bc1aae00be0f86ccf0699a5264b349ac63c9ba5aa0074dcd764f39ded9f7248184fbc73575917b750977d619b7d44d6eaa8722a0a8ad3148bbdcdf5cafebdcab4bb8b3ceb8a56e7253dde1ca2a742c21ee650c6ecc1c6e9299b89629b83393887f64ade69b7fd83bc9e214912771c7ffc63f1eafe0086b5bc28f082e5ec50dff10d7e8bc8fdbfd092eb178074f585b126e05b0b615f7fe437ca3f33aeefb27e147a3e5a5f873c6c4fbb8ed5ff089897770cb7fe10743dee166c6ecd51490eddb390e4ace73c4fc1f6b8b8cf9827d49277cf18a93cdd959fde0010f925ded112bd606cf3044294d4948489649e5bb3486bd5ab11fa6877828302ed88ef0f3ea1012a9c89bf504ec3ac41e20554768931d9f4d430457f5ee328c897c4a044650281a3c60d1a0effd447f59460569a605c6fde96aa58ba462391e6281c55872fa8c1e5ea89deb10c3b21e8a41a09d52a1cb95c9bbc2b30fef0a0cde320669cee13566186bed2ec1385ac7208d6cdfebe27d0fee09dfa9e73bd6594a84a343f41b6369736d6285a7da9cb5c97bd1a77b56ddfeea0293658c6a7ab8a822d0d928237b5376fcb37fbec6101e2be50f2ce0dc4e9a390a62ec6793e8a3ddb5a52f6a04e5a24611d3526c86af495d23553a16564e4c47e0896825eff448b00616d7d47323d4cd928b92ca942754a2e3fa3e0025dc855e2cf29b51aba72f549d44c1f737bb9c2c5594a073c1673a9dc41777b3bea2e5b7e01f8cffc4dc2344dd65b5ee655a95a741f750c53c74b722e582528b03d3637f78f320a84c0eea6dfabc1b095776570d3546aa9f695138ee05aaac3ef8427320ea2d225e279fd407b68ba4e017de3b4957a877b1080c2f051a1c6ba5551048cb481dc419bc348900023f1a70d2ce4fdf84b8eb9df6510e60c22b079c4043120119812f49dc52926d915c2b2169114b646ed29e0609211eccead0076a416c002b2fa01770a7fa0615ac3aaa63748516f17f0adb09130a980a3838aeca18bc5dd77954a53e9a51be0a3df0aebace697fbfda8fe68b65ccbacddefdcf601da65de797beb5423e9a2f5d12d2757eed2c530fbcf9ffcc5b2bd4986cf0458d243576d4f8d11da57ddc9ae961c6872e70edd264ac65ecb3df0c2b8d308d6fbcb75b9155cc26b355893443a58b31a7f3a75599fb99e50db65579976c55da23a4afb6a85a6aab12098d1b62d2194d74b7b3a60b86c12a366798babdd9ea9756b42a9192eec3eeed06fbf0bdddcca042c50c0194e18332c69421a68c31baa3cfac4b57e1f06dfed9ec3ebf024ae424d10f61cf6bcd6a7f6cd17b20d2acf6a7525b43a544d622fdb5b224a5f740a42246943c8c2fd1bf50cefdbf507873ad94087bb652229c2dcad67befa3f7655f53de2532fb2db942352c3dfae3ca9268a88665139c9344951261fc9277c9d1e37fa1cfe10fbd4747f86d32fac2e13b9917dba39cfba29cfba2f09de0fc4993626c33d89add274a193fce0edd3fb22f2cef926cbd24fc7368ca6f72add03c4ac2e13bc9b92fc24119cb218cbf7e964393063d96b5a30c1acdbfd1bf59223bab2e9b4c5e5aa593ca3e4868565d299b31a234be343dc2bcd336627889a1274615e3bb6f6ee8cdf5fde6c669955aa14fe9055e3aea2cc16c86e52c4d01d304992e3bc4a0bd048004448aa040aed140fb73fbecca9f245bf993e623e54fba7d76c5f09dc4f06dd70a11a28ab7cfb7cfaed8c2dfbf13bf471eebf44be7579cc5940747acb2455569be4d6687f287def7dd3ebb3c9974abfc921e83eefaa4ee3d5ca64386b8cfac0bc98f85e0a77456892b4539ee1ebcb9f3786d4c4d95272b8d6294b31c83f2e806e247aad62659fb82b1f0537ce34cdaa4200d13001105036cd077809d04e80691d66b2608d513021d700446741b33ad0292259e4075d37ce145172a480117345b74d3a0a09b468b6e9a2c684e1047b5b30faa61d9048661f6fe1518be478ac49c556cce07fae8eba32fdc17b93efa8a2f843ffa8a1fcd9686b3f3a3af88ef7f1fcdbef4b42693f53f2b3f5ca9a4b53cca2c27bef199f7387bb1f7bf5dcad670ae4275f39344f8a32fffe86b562a44530023badba34cb24799cc479af4e768d21f2c148045cda4b14963b02b76982efa933dca247b9489962068a2e0497f729228d664927a3497feb119efe370a6b59fb53cdad9ec2988f112ae56a852a248672beb37f9615b338dc63e866996f28abd334cbdb791c6eced66675428769dad46422e2197f8c8eb0fe524518cb7af9428563b9b579542799486278d75391daed6c3980a7761ecda8c3f0fbdc7577ed867f6976492c7db673af384132350a17193fe5cfae596645bf4f466d86799edfdb2bdfdf43cfbc13e10663328619e857d36cb608fedfd037cf46fb5b7cf343f9616e67d1f8865f47eb0fc2118bb59fc38f9d10cfb8bfb0afb68fe6886658fd29e1863bee7655b675eb0712237be11e360ef8fc49cd50d4bdc8a0600432278234b1a5d9233b11fb8af3d941450a7a8544a7c94782a37292acf7e88c5ba4679f643eeee754a023c3729cc0727c0a287133a28f199bdd7c3014a7a9c086c7ad64b05783c691f61643c651713f9f06841135dfaa7ad364de41e22a0e32b25f169f38148691b1080b9e1e5026a1db580bcc7739336089e0d088874cb1b0e1675b4f083046614e008160d267cd122c7e647005f0837365b70c084b0e504590a5bba1b8709299070d1dd3925a460730c2055595c701b264ac0305aa5b78ba6b100cd966e1a22ba692ad0365e9eb0f1d28566886e1a217ed050a0bb939e38f9e40df67f73ec9344fff7f533dfc6cb0f9a0948404b10516880c8d29386668a8d07c8687ce377cbc9dbcdc603583acaa4cc03f3fe9267f1916e1b0ff858628d25ccb0b7bf36cb2a78b3ab70ae7f731a5fc2a73d4fcaf08d5dc2609b2e46d41061d3c547171edd3518982140960b588002361d38e24193a569f5d2257abf9f1fbe6dca58b6d5d2283163eae59957ad27417bffcaaadafa184bcf28ff0d53fe244182eeeed136493c914406922022891cba553e74f4721f7af272157695d2276f3e7fda6e9a1fba697ce8a6e981c70e56a620510211708056e5e5d1f11586f114a1cd87cdef217600432e3cd02aad34276f2e7f89cef8e89623061b24b2c81fd84356c59cd4d0028d378de7d96c4cba6964d348a16e9a8ea6a3194233e48e3b66ea98a923d2c0984b4bf3a4774b867e5a4d805a4b908a94b098a167ae68a1674a3053848117bef131b06383012246f4002f790a158d80626344ca8801747b9e04a2c99beb3d2a976455f23c095495b22dc22e4f0281718110ba3d49b34f4fb3c0025eb28d05ac74871ead66d95f1a14e463b3050536450c4002a12e79fe937830c5f773efb323f452eab1d9d2753b2be64be6d36832f648f7eb7ea8f32ca15099ff4ecf7e2aec2e7894e577954e11558e8e5feb39ee954a8cd155465c55c4553a523ac73b478a449dd0cbe5e4142982e9928d5d70becce7774790384dc63c2f85ca4f63b1304dfeac1ccb661da6c9d80a77f73fef6bb6ae4be938919cbcc5146c885341b912254e45c789b84d4a8755f865f4e6bfd9a7b9ccb79b95fd7579b514c85df06871b95a8bc32ae5833c5d94165152e7337bffa3defdafca5c65be5f6e89bbe091266319fcfad96796055bd1db6398df57cda75e71a6f826674c93d42b8d5641b779ba3068e9954b8f1dc3e2cc7b8fca8c3b9afce96832469331a79e57fad3d616ce49222966b2348bf58a81b8a6052e4d0071c40608158008a1fb87357e28e3872b9c855fe52c95b3f04c1126f460b32442f704faa186279512c5ae739bbd028e8b704e12e516ce0ee57e5617bec92b8f28ac064c0f45b8c70e363c84a184fba2595d93c6aa92cd606bd29f1a356c32571750c436991dca49a218b1e3ccfa5f52fce8ebfe0cf2585f56a98dde9c52c96b515e2d0dfa4993622871d7ca68fede869dfefc5969cc257e3a6325ced4c7424984729f955f9f954b998a27e6d743cfe3a4313086278da9306ad298e39b9c7bdcf288dd7966754c3df0b63c1e4df993946d912d9af68856e9a43fd916dd97df24dba21e3c39393aee13c3ed630a9a7b1f533cadbee7c99aac7da030df8af3dc3e671eac4489cfacebc4af16e623063ea414c9968c295048531540492fbb5628683e4ed65ef36ff25ff3ff8218bb80b0007145cfc66e21bec91a715f73046de8367b9c2fa34b5caa0a72f9b5b90b65337b7f26a3332afb0f4fcfd6bc3ace0e29d5bf62af90bd7f004ab4642f0dc2b6a85ef0677aa085a204ca0844402a105298a94112e166670e9b8f88951e423e5cf727bfc62ac015dc2cf2c4be9ea8c8128bb50a4960135e0943c77110c98300c346038a40e3072c68f01044b541b865279834e90493725fe494e86e3bc1242c617682303b416c27886d722f2cdd17d809da092675c4b15902c35953fed03c66a15736d9d780b08cfd9d5958aef6ce6095c232f8d1d8a4b10a56f0b35d9a15fcfc6110c39e36c12a39992bbdd50bc696a82761dfbf0d276b19276b394676565d33a3991146ba5608e36ae9fd59959e26f1cce893447866942b7efc1403fd3dc232cba099d1acd449f8836b5836c1ffa13cb2b1d6edd259b541322664ab980bbafb15b127976e577aad385f56d0339551efcb2df1886f3878cabf1ff83689cb5582367806eddfe82be2c7587e61ac52da0eb1cbc91b8bd5e1ce67f3bd866593297f3c0f149af2c706d9972daa4a3c623550f090000f20a850d12828b589ca2b7cdb6781800089b406fa570b622c73ef3b3a0e8379cc347604c9ec2f52473149c1d2f8c6088038df558332e078d5ba4d37a0d1dd9efde48dc562b16ef0a1bbc3b7b13e4b0f577973f7096e40e1da283ef8f4ec105170ba6f368946abfc759e1c0cd66082e2a5bb3114af4d5088f4943f4d4f74e81e8a0003e2928d659ccfa7343dd8bca691297de9e6a1bb7fd4ecd0d77e4a44aaa5d8a3b61b58270cf6d59a5e4768495ce01b33786b05212347072963420729734337120bdd311060862071e4749038987490388ae8207184d141e2f0410721a342072103d441c8c43a0899b08390e1d241c8c0e0841d4e50e60520657c20c34577f78905091c7577cfac208709a94b371bdd3c4052f57c7af38f0d5658ca03e887470f8f1d1e383c5ae0d1c3061e4348613ad28126073caa697c230e903146471adfd83e42cf65cd50778d931a665e5034c50d13d11bbdfa51d3240662d8877fe65f7bef1213518d690807d350adbbdb5947aaeebd9965ac1e7a354c3f21b92664e66bf8a1060538eb6f569641eb2a9f954aba8469f78c0b78504dbc709171d5c01586fdfbb96a7ecfa4a08689104f7525b9869ce50ad2a48d2667b8ca95a8f09b9a2ca0490e98fafd0f66330ccbfbb6080826466c214573400b031020f4c5fd25a3d09b42551a87358a889f1e59729b91c85064f57364c97d566e6429dab01cf258adcf8f859eb13caa2e5bf4483533f0aed29323a69878a2e8eec7e050d1ec322c18acc8c89584b4e4098cb56488204c3c4033409a0ed30c3998173cfa015b70b48ed841d2d5b06cd2b9aa4a243afe8519e59df4bafa1bcd4f73339b42c5ffc20cebaecd3229d4d1e80cacbdbceb7c663d3a69d30c5cba632a7c1bcac39cbca96cf689abd2ac4a33ef936c110c06833d71721f6662195d0a7ef56f13c66306043128306104129c2146890148e8ee26a10914ec8c5087aaf66303b2813811471620345657c1e5fc280304c48d12ccd8c93b2fdb4ece4e096d4aa2834e12268915d9da0bbbb71b976e8cdf839992f81026c9dda624af243da624deddb0ff599210baedac5258994ea3c3f49b9064e179d24b7723d9d2f829121dbcee4672d4b09acc7e4876ba1b89b70c74846f83c9904577c3bc744faaa5730d93618a0c418d6132a01acb4042f791326d3a32e648982360ba1b049a235b1a85361df1da6d9ef2a77b660440aebdd787139311312623b51e130c5a4c4654353324311999b2d35d93a4bb064977cd901a196a33b12504a2bbe6484e4ebebf54adecfb3a10ae9874dec03762d8fd0f859a15e8fc2fe4e972f2f682f7782a276f2fe0584179f4658ee356ba2f3362ac718236e56409ab94535a2ff43c82d276d718e9ae2952b30202681c60abcd1a0659acf91567f4d3167552d65da3d35d9353b3020d269c283d2606b18c68648a44daffb332ec1566938f930f85860634ab15cc8c11868a0a26a0d04256c159a6339f71c244a4892e6284fa1a3338009165a6015f835313bbbbeb98d4c033dffb98f45a33249850748861425d81da407763eaff85d883504add5d429b502d136ac7934b30130a05d3cd0f6ec62ce9ae5975d7a84c37b91a22606682689a134c336e74175d9051230210244c3144c9d7621a23189248a1ba6b8644dbb5b3b6810986ee5ead5635a91d7f9cab5ae1948f849348dd3528a1992a6880e8aeb999b688c55a329b19d51f2c6b4add9dff8ec3e057de7cfe632c7576925c480db1751454d44262626ac1089bc9c3e8d6c00c2a7423a04d0ed44d5cb7cfaef7645509bb8432b64df21d3c985800405b9af464ba323d2a6a12667a41138da9b1a4cdb4615ac1d5b44a6158d2ee2f59cfb348b95ef08756a9490535babb67f4e8a9a4d1bfbfa4bae04fbc602c85fa2b3f7c14b1ff1205f151b4c9646c7efebee5319625cecfb628d779a3fe5ece8f3178c516cdb7d9a5478a8149f395804ca09da5d32a55455a7c57e56e3949e431e7bf791ae1b8acc7209757e93d8d4fef7fab188823c6a0f739ad3732398b81385219c5f247ca6287531e9555d0ca3c59cb56455b1eebcdcce538532131100bf186c082863b31b299e66c8b5ec816853619cd493130e85a21a4a934b11dca180c9a8fb3b32e71e52451adff592d8a14799c55aa92bcae73f993e2ce31add2d9cc76dd0d0a70f7f1e9915906b9ca553e3d3d375a4bfa5c89bb7b029cc5727f8f7e372bb3b5eb3ac7995610574b1f29cc7452d00afd25eab5be7f27b44ae50761dba6005c117f263118fbd05501f0e96e619bcc0eb9db6432cb20a41e21f868757748e7675b27fda9c940fba4522793fef43099806820aec29bdd6b62e8ae81a1bb7fd4bcd05de342778d90a7f73e36fd48c3f4434c37f1e79c248aa177a9b4510ff765fb6149636e3d70da5b4d8637e36237a31eca6aff71e7f829feeb441eefcd4c1db9ab1ce5d1654d76c14fc96375cd9f7549c69e87e9129df2e6821936c4d4800e1edd261e6faab181a9264b4fe08c3156b0032d32d0404031470a4c8ce916c8d1ad563830d8473ffaaaff199966b484d79a663ad34c4e77e70fdd3523c2aca09ddd6861f3e7fcd8ed592cd887733636ab343592a96d30750ddd5d73c95af2a62680a97fd8dc5183ee2cbfbf77c880ba03053bcab4b3e67dcb627df8654a76987ae98232d0ae6677a9d2d5ec2e09213da961d94408e9c9acffe5c79e2761303a96ba8215fc8109dd1736a78c81ffb0fc55603110c3e694b1fa3110c33205adc84147cfc7a00b06ebaef1ee1a166a56e8eea0dab291e34877c7db67174c8e0c0bc118f63c09837d36db94a1dddd3d58404607dd99e2ccd01ca9834c945e7a2f16a320ac200e3a6ce2e002840d1c62e048011c5c781873ef32818e0247149b37c6d8bce145775fa11856c359c3d94d33821ace6e9a1674370f1a30fab3d9bede4801cba1ee4ed9b80fbc9ca8b3cad1dbea671247a08bb638d2dd5fa957a91b5984a159018f14ca0d2c1550c2c68d26ce7a18cc0d1368957ef1af6ca34c1b61b8bd6d08c10adf066b0347168bd5060bed4a3c7c1becb3d9bfef41998edf835c0fbebbdb59e13bc9580ed9d7910dcb97cd608b8d31366c4051f36a69fda1f09de424910f8eecbb2b499756ab95151c9c9b95457a85de98cc15276b38e270382124331c41e22c6751e956ce7a59d491c103a5c47469cad5fd259b3d59ff734ffeede6674f36e95c7a3e458e20d1d1c1e97156b543808e907c88bf52e851ea819fe5ac9f69ec7e92a8a893429318fc2bab367cdb12a2169290db5cde689cefd8560cda5a845d46b3bc59f7d9cd6db6f869357c2753fe446c33fea84ccac775df0d8cb9ca2679ccf5b1771fcdb8eb3ae74911711e1fe244fc7f0643b912ff6886793ca98f6694cc93329812cfef05b2e658d65a37a875772833fe25ba74418cbb01aa5b0d31dd1dd5006352234babd175c720d74b8d02d8000536f8bae36ae63db66e031ad22813d3e09246678bd2d8498384ee1abca03b66fc93c57a4d178bf59a140d2bd028020d20344ae8e28c069cd1a4fb263fe31be954761ec6fe2f36430733aa98d113432fa9a8e8f3ecbd32ae28434b370dc6a08107688044031766d0c50c8e98419319b4c860838c1b9021c4adb34a79a3cd64182143003220a33b7615c459cf6bc94028063fe81203a518dcc480070cbec0e00a0ca674c72e7f52b53486de4dd6ce57f1bd4bd5f762fc9bac281fe244fc314b7ae0edda99981b88d932eb1864c6d0c018750c14b410c38a5183182fbc00062ff0d21df14f1cc69818861017d8e18211b800e602a216906941981674a005575ad0d3dd75b250de640dd358579562e881a10318303062981c84f1120601617aba3bce2cadd24a6fb95222167cc10213b0a0b6c3821f2f1bab5bb522be76b602225680c30a4e5f50f1c5952fba2f72ba6705595dbd600c96a5175478a14377ec028e2e9ee822d645933854a0c4ec3a0f63f86bf95a9f5915ac5240c7ac52958214c890821e5c8ce1820a131755b828c0166d6c91832db66c81650b225bc8ce579d12c79dafba148e2b8f187f55e2b2ce572ce944fc73222e9335cf37e9995679f31bce411b82b3cffb9acb0367df85f86bd9ad2c625a05673eb3d251d04201102da2d0226b21d3c294451d597c208b2759d49c004c77c7d0fb259cc398bd559c8dff379bbf0fcf5c33eb5dbe16e75d8797c47ce5b7ba3f3b410a587081851558502c6cae40e38a1eae306245195680b1225b81002b7e7477e4e1f9190dbd5ca3516f5639b35765894c5001135013d06002ef8eddfc2bdf9385b55502232588a18a31aa6041153854714345185460a142670a1a4ce1c4143e4c219b42680aefee88333ff7a95ac6d94b7bcf6619b4c4abc4602dbfac93996669bd18abc39fcc94ba32066f61959daf705f3b5fddce579dd792628a9b36492184149f143048f123768f71dff92a1a01918008cc1d603e00468299218a39a24041146114a88eab0378c6f6f318fcef91f3ac32b647cec23f2d51f6308d753ff826bcd91bfbf953fe6cfd60896716090a16406105144140f103858f66c58ece269db4f3afe5fc18cb59c10bce1cd3a0fb572abd557a9b128669e8d303c3f46fb2ee80d893372afbe9c957adef7da55e75cd87fd05bf6b9f10d3fd04982770e82cc312f704932748e858cbb8af2d27c2b49ce812e67c4ee951aec526277e447c932b6d89c0daacf23c1164114127829d10a4417b8f2ed12b65f83d09e4c362bd90e8809e040a4100be60f1654b47fcc5a6892f9ac02156fb8519d6ddafb6891540c00508bc74c77ac1f94ca0c104154cd4989031410213ed65092f4a5e927c208d0f68f9c0079078604cab5498e68f41f198315805b4a177f706b4a12b794c752c5606bbbf494c5561eebdd92f61fbb5fb3356c37f672ebde2e497e481214b9cb1c40596b86189205dbce8027639d279f2afdb7a1fcb9faef3997d7545d1debff2d11aae76fe2cfe0533385bc90e88a0036007541c0883035dbafb63b055942914be3435511c686103606c4089fe9f3ea361ac2a2951a6af28d17a43031dd000150d0809230908242193084006ecc88017549b32a083acfd05bfdb79540ae5bef355adf3d52ba793208dc66e12d3e9f3bddbf92ae20b7e5d18f358e990213163ebd9d69021ce6252e42a426a418917fce487b9c4c1e5082e52b81c718981cb09486cd11d59ab18e66432f749ceea609dafa2c73a8a298cc2b1eb280da5f7352c6b9efc6b67d585c40e1226f4116558dd1161aad1115f3e893b02cb6c1d71a46593ca28988401336618d0a11d031d064830c2099311b9eeba6b8196c4dc1bb113bb9fbf7cc2b7791e8ddd3f9a5616be932348409f77d223fb271790e2025cbabb94ce055edf4dae7fabf6d2a5d8ed316ec51e8a05e6b0c0062cd000a13659a0c723b6b30815148183a9889dee8ea197a3e1db6220063d0f193264487c1bdeb2c496275b86b6f46c4161cb08dd6d439b88a882082b2622a274f4bc1bde0cc6727d1abb1410caa873d94f2bd3f1554cfd12c595c5b214f6e10ee55d2a49c7575d95b2cebba4eea795012539110742194d2b23e2c7ac550133ba3b7a1e755281fc49157040a6b7bf6f93444b7c5e8f65edc3f8de252cd62b8336acc13e9a8730a3bb7b882fdd1d6d6b88af3b0e41430f4142377e1a0dc42d21c07816220bceaca09d499c10b58f662148c0996fa280151d3f9a294081ee6e1f97ab6a58d62630c50488304de0278044026848c0879b1b9f59a44abbae8bf597b494400b125a685a9e680940104f04d10501640a0208103e00c20820baee9066b686e4eeac95cf6c87e4441ce9a379fe95ade21092d26a6725f45272e93c1fcd3e5d75edcc57b1be4d667c63abf3e0befadf2c931f3cf003961f8e7ca0c387287ce0a28afe61eb01f52066043d2ca0075b0f4d786883071af000040f3c3cf0d8e14b775d90afdcbb944e902ba6ba6c6b18fb68065d915669b7fa68f66b69961964b9c294e5872c48225046048488404f0472202006021a80c01104801ea0830708f180dc035ed0a14c77f833bd506241beeab08a85a77ca45890af62a7b37a75917a38d3eea3af2af35c255375afce67b6eb522f9451e7acd057b2ced67095f6368a3ffad12057d77d20ad6159eb7c15f363ef64a5511ca40314930e26981c40c6015238408b036c1dbb178bf5ea3c097aec5e9d7bec96c48c1fc4b8c562bd3a49143f9a5755d6b06ce283fa68f6ac8df9e0994f0f6c7ab6015da84c9132c5a3cdda56038e7832c5612a53eedb09622953fc6baf06c4d0dd3e2c960fcdb1f4574f4fcefe789e9455068460c262069621b034e978bd550c6dfe5aced622e9b46901255840071640846901411d73727254393a4ec493b2cea1f82aa6507eb3b7eb72c0410e3030e570450e52e4f0c59483027208731082d3e32efc04f957235f455fc5940ecac8573e3dee4284c1c2b7d909a63adcd70ee5b996c1d674bd600ad0a2805a6d29c08454f6280de513871e74475c0b073034f6c2414b96d3438943cd16e1e009a0a39b4902b848008d558ab39e5b9b31f5982901347cb5a62b7774479f57cfcca88811f04a92e98a90e98a4d38453833852818e47ac8f5e44ce88ea99cbca1a848c12b9a8b5da7137f62597339fe3ac7d9a3b43a3df4268df14c1aabd4840b010e02381bae8437565de7333be94a4ed312104b499608005e017a31af62f628cd56e9ade1eca53da67e671ec154764186c274f304bace57b1abf4365b5d5ccdacdb1a8e564bf3f568ae14b472ff684c0b6fe9ee9609d3206bcb8483442aafcdb92ff2f161b15e3d336b7b72f6a767d6b258af6b80394c564670adcc4c565c307d68983e2e114b5a938138d5a13c530fbd6ae3f43c8aa357be4f2bb321a6379c307f55be124cd60a4b3bcada376d2dff4d16258dcebaae5aff9877e473bf47f64f303662b1eeb5f72e995557c6f6a392536452296224f7b39aea923beea0a9b2a68a88dfb5428d89c796377c10be0dd642cd1d4a4b92d400d15df3c38f0661e8dafbd3d6f8d05dd3c30e5e6c65ba25ee8b90b051f1c4649bb1d5335376305549e3892a5d5a70531559054a15a52a475568f09945b9a9ca0f13f582461163a62dd8ea59fbd5d430d558505b8195dfb54238578a69f227633a24677d5a6b6684636052f8d1179e19e17fa1fa776674ff0393aafcae15c26096d70ad95975cd02b10afacc118fe9e98158e2686de12fddd486bb8c2f99abc4fd3aaa4229e912c694ca149594291e5b7707532ff2fbc38a98eef82d2b56b0745bc9e9c6d40a09dd31ffed6693be32f10b135ddf97eef881b64c77fc9bc5368b68bb3e591ababbadc7a46a46fd124ff5ab4e6e6522a6556a8b3730b1bb69e9be4589d35d372f4c4789ab96b63c2f318fc86687ad4b77bc56565b29980a63d6b6d45502cdfe7e458c803e3e3e9e47633e3d30d80dacf4a32fd4d0a8fd5073d57e9c685bd0be8ef16fde7558ba2a762c56a5d403679947e2c752f68a5e77adc7229176518765eb32066747713c6fa6c40cca2c8607e3c33732679065c6a60859c812203b8a5385bdcffee73659c436c7f94b3c761e3f36b33e640828cbc9592d0c56e9adf321d1b152ec8cd817f914c786ba5b4e40da709249240c9d19dd0aba06743bf16b39e71a8de29ae4a924949187d54eb759e2d0c3f8c30a23a33baa42ef334c0758d7ed081083001f2a6c5031e244c501548ca880709a42c51423a604650c4ec7d2f3d31e3683c1baff507edfa11c5bdc4fd0dfdacb5791a8eb62a68ee3ccfa077a0dfbeb24650a293e48497280340e20e60058ba63175699aa602765561b4351e966b5b14e8ad2077673b66e98e30631372871bac1deb0a372168eaba1d410ca08e9069b28248852eb686b38e950ea800206142f1eb5b9cd2ea3352cbd2416eb0514fd890e9ec8e0c9104f983c01a234859255a2e1c5c6ab03afdaeb3f2976b453d54fcd28956a531dea97ecad73cf935ffd512c963c253520099624c209490d24213a7bb6aac0d47cd9b5286fb9bc6fc318365c4002363cc08604d87073b281c7f48c705fa472564a07657474e5c87674c4480d232e464418796d8b7c151fcb5c88a1f799568afb7a8b70d10aa7a21188a42092111960684888a125a7a11f273f383961c3c91627312721505183d7ddf1710d37a337cfb6e2fb9fe36a7f2af5d5575bc39e9337efbce54358d7c80e61e5bfe1cef3680dbfadf2ab0d61d662f9d5d0f1da2c9333294b723dd11d5d374dd4e86e277d6a72812651dcfef82aa670b514e52f17916b88c56a6599cc52962a42659abb89f86d762d9838c164034c8c60626322c4440421129c847c6867392b7c9b1773b5d22848bbf26775f92aa630c558a23cf452ab47422d096249cf92108272109446d0114114089205bd10040290088066402afc74f19325623b31c5adee7ff26b47ee3185f2bfd253b44a510e942a4219396bbaaf52a8228c3262dde8cb5771465d55a58ca7d6c9fbdd953815be56deff501efd985a55b47e68b14e34a841030db918daecf8bb1139cbd62b71ab866596f7bd9f451a086080384e06f0a2bb23954e26c56c2dd24feaf2a1f2be8f8f8f0fae96e2f91f88e55d5229cc47f64f7c70765298cfbc4aca9c947451f275b712a39e32dded3d61bae74bf76cf57c7dffb6ea53cf4e0f093c5cdc2ccf96ce8fa94cc9c99b94293c94a784ee8ee04d4d965bac2d5897d259a507b91cdfbc268db1765077b6582674f70c635a3370d19156e90c5c66f8669801b553a63b565a74dad9d9a911edd0b0e3dd3149991693248916ac94e48bf3948486a64bd5d6561215e2949f93b78f666cbf8be408121264104386214e3230408624477870440547b074a78c3e85a967bb1667248d93112f46964e466a30c2a373f29693b7979111124ca7969344119f8ad08a149d8ac4a0b3860e17295fcd54ad3772aa38e53020474999138e08706e3845701cbf07ded96a76dfca5ac6740ac524e203a2778a1f495849715a6d49e95cd00ae1292deef5d57ab5b39bf29b74b56c631e58eb4995864a081592eae644040d22491099272241447a9c8684b1be9ad56dc67578d29faec3f6fb4963d77a0e7f2ebd4306302675c40e29a0532ac829d5a82650b7136aa85340734a2020a0506256f7f91483173160200629a7184e80410630100183100c51062f2c717a819e5e18800b57b8705d4841081742721d23b61983acbf85a00d6bb8d847f387b3074e6ab3ad97d230665b48727239dc8c938fe15abc8a13b90a2cb880852a58c8e1c402664185130b21ac208315905881ae50e4a44299930a635410e2a482014e2af038a510c529052c93c67c858d7c15696c0524023911ff4101d9225fbd8a948c806041ae1f589416d18ce2e0dc6f347f96651464f44279ea076584fb4a8432024afda08cdcf3242b0534692b56c1ce278d5589420e28c8503889713ac18b13ae9c4e507242905301d028c00f0590a7020831010c139030a1869309dda99f1f6cc46d264aa11ca3dc71a655fa9eb5316ff9cabbb04a15add2e92aa992b44a63b5140fa088d3001230801f804e10344e415e700ad24310a5ee1ea14f41989c4a80a3041594a0815309b8127c4e25fc3865713a8de0a4c3c97512c134839309042713ccc46363039b246c8a4e36454e2490712241cb4fac208dfdf8ca5771e20c5a8bcb11488a28d6f26330dbef6b407c15511e4595c293c67eae5d79b77258b514c368d2d2669593c66a93c662fe389aabfedad9941d15c0152701e4208029027861041d9c465062040498fa34c2d0083f4e22e440042544304284a153087474a7a238113f72224e44b39e1371229451ea0865e4310acac8a3e749998ee7c9d4518ac869d6431911a18c5247ae4a619413392b7c2711678ac336e34c6f3e3db3525b085d8a42c062429f42e86208a8b645a7008411becd6f96a8f74e70005800401a27004cd1dd51fa0400d909003e27206b9c8050e004c4e7042484c6ff85299d94a7308892d19b20975f2b3f96547f84a71f379c7ee89c4088e3044218107c388110e50402cac719271f5dba5993fae79dabba99d1745d8bc293c2c2b7b158387c2791669b6387c3b775298c0adf96947b1f47f9b1e7a1ea635b3bf9e858ebd4434c0bf34f3db8749f7ae45ee8538f26ddddaf530f7ae251a61b9f787ce9eea6a0bde1c4034b6ec9fec9a9a6cca9a689534ded54f34204fa19cdf2963fe9447381eeb6a14f34359c66e838cdbc4089cef2874439eb0f8919bcd663759d0f8956362476b74e9f664e38351ba7fec0a96ba7ee4ebdc21d34b8838a076de8aa2cfbfcd3edcb3d8a551f9db922ce14cb1a823f77cc3b64b0238eeeaee0fd3c7365f9df5f3bc0d881a5630ae51fe8f3df8e9d2057cb8e3ac2d4d1a58e1a4e1d293a78e8a8f9c11a3fc8c00ff00f52c8f5e947657f577f319da3ce3134470b73f890e38b1c5de488d2bdaab64a582d0b95b1658a9489a1cc0f3260c848323b644088e38b3872dd9d42a95878e56e957c1559dd6757b63aabc37d6af51705cbd622dd4c2f18bb51ef6b705c01c703e0288203d5ddb9cbfdacd2dfc06f746fbcdee87963006f88e0031df860091fbcdca8c30d319dc28e33e523b98eff04f92a56231df0f619676bebff0ab9c1a5adc56eb11b51badd50a10d32ba636afe12f5da48a20d0474c7d412f550f331283fcf37f5faf8b8aa86650f8ae881941eacc00619dd5fcbcec6b371840767f0c0071eecece08c1d04b183243a2843075a3a666b6f8d783aee2b6c66fcb10ef7b5bee761a69fe57de5e4e4e8d895ecda9f495ca3d1da4b9b5d95a53f6d4a9a7f2d873e3d19d3a1d0a7681665099b486428d2440724748fe99883ae65ca010362a5d6e69bbdb31cece4e0c71a62566b6869adf175afd1e4263fdfd648a12785753878a34b9cbfd461896be1e02885c201ea961913a67b4c97a431b93eeaee380635e6479c4937b0a23baf79a8e413d7fba0756a4600002028931000003020140bc62332b16c3ee9fd14800162b856b05ea1cae33cc821648c21c400000000000000461b004c9b09795e5624098c79f82d8f62a2db4da8cb9481beb753c7d4fbcc0011a86a0442ea728843db6e9ea28405b06369186c3adf84313ee780fc84c70dd954eafb8e16a8e4389d4f1da75f9f31a087b47002345f0c1bbfd168222388e873103723ea63ca1e609a996a569696e0a3f60d3a08c7bed33fe313dbb6cab83436bbd4b8b9952d20984220b5d43340e31c519134d91a32b30f0eb627444280abb4106955136c0a1596c7216f454370f684804fcbee4ac7a7682ffe0d3458cc1405c2943dbd27b3325f10f50d2f5aaea27f2d3b72e4adc5bd847ac9a6dfdc7c27041afe45d39257f942171e1a335331236d26797a7863c63e830af8a3e51cb410fa0ac629fd6f4a50cbcc48f437a1c08bf086cf3f58163f9cb40e3945e635adbc8350628b3b7b34966a4b2e01bf64ec1854e4a8e051e4bfe512fcdcced905a14b317ac6a40f5b2cbc00f80c190bd944b6bb630ba7f03118c8a4273cbd22cc8f9e6087bddb30ebf7a6b6ffc12d590f83dab58de83b9a3782789ca57a4e0fcc97bf2ede6fe54c018879a7dbac20827cd0cd8d97e935d4be20f409bf7581c2daa8bb29a1107bf20d7880db2d0f844e075c715f4eb36a621ebe4123aa00c065e400bfb096963198a776e239c4eb1efe551a5c82b0586a3f708b58a917a50281ed99a5f7e1e5e2939348ff6fafd01272f01f80fb315c175e3f219e0aa4f88ee3094e8e263e282c9b577ecb4e8a2d9d0496310523ed58a01061e5acee370cf5a07ae2c32029e430d5fa0cccd63b5089984902d232b511ff0eaf841fa90869876aab058e62c0870d821609caac5541eabbb8e42da37086971958920080bab497b46cb2b4b68a49260ff7573c5c9d89804227f2851aecad918ffea473d6ccc8985ab2d3797b4b868f9e5d6af03906a6027d77b8d71126b606831de9d2036ef4ddb4d2f4ffb2f3f5b5226bc027741a26d284f4251ada6b49e69f9378b523f9c12ad2b5288de3218940d0866c2fdf16cc6fae6b6c14deb20bab4735188e10b5dd66fba11123e901c016571bc6568980c9d96d06a1d3181a3a6ccff54eb129946118158fd231f2becaa3123e968f6fdf47ba0de7d2268d9c0903346c1cfa6df49ba212a7a520e919f5ba354cdf68a17b40caccfa6e7e030248d47b152b4c69a91594906cfc4e562844088dc11cdc1e242e82275d6da4b42adad609c6b36451a54abf7dcaf966c0c7a723f476e66e78f61e497f9bc700caf7dba1933ad0f604b6da4287284346d1e129fabafdbdd33bbb7a329a50bd8a029ca7472185f82b83e1e5e16d4a754b7fa3b3ce5f9761c0c7563518d204319a113d57f10c8c30d5714727695f60e7b8e66bf57a61b0b7b0f366c1791d5fbf3ee4fff9cb26c000aff73799c37f20ff7f192b7afd4edf03f814d57e358a5c53422421669ca69ce5550840b8475b1044c1d1c204a61b61af3ea82cf487e90bb4684b045599e9afb1bd551b2f6f1571255d2bea727d2cdeb2bc96045e717d3c866a2afe57b57e43f018e35c37a231220d8c2e3b74a2fd2bae8cc5cdf5f295a3ed21bbdb415af746739cd5a5afc47932751450118c85348455d352f8d61138536c4f6eac0829a3d7c85ae1dce77e8477a2180176e6dff21007ec543ba808a8ee9014fcc8953ae3228ded0297b856cb8babf4bccbcc238e5646c06c88061f154331648b9e51a5db10e04805b189393d592bf228a6764f3fc123a1f6bcb6a5c7a0b6aa078491fd3a65b78381de1687be99254ec0937347f9568980e70652b0fef6901549db3442fda73af177c3e07d5a6beee297f16a4fd0f942a58447b84fd2f8c1d8f721c126c6815bc626cb88eb2d44e92f2cb828aeb9b5f82120e6f7c5ac12ca49461ae18b69806e75305cddd443ebc832826b65fcbbc911366466fd5b8621399cadf3f5e59c04d0bb89475b7ef43ff753e0867516c47ccd4881d1921591c9c102a82371eec375745867e51916fa99dc2ef666257c8d665e05d9098a59788388babe2adf32103ec6661d728f40c7aecc52defd20a2a640107d9963c0abfe1497f9ddebf50b0fb74a79d9f683d5b094760ca50883e0b9f6ac473e7b17535ffd1b6f0e1991841f89a8253278c4953d68994ffff131bc4d17f5f3db01e74df94e0bbb7a21b7821b5d8ab51ce288be1a8cb9a6b6943d252bdc6535a151e6693030f5faecccc008e18042b78f14b4b082db325c21f58a5c85e18248ea611059641e32f41414727278122948112a198d05d14091e53d46074dc24c7ff3b3e3ef8246c8067eb55505655ce1ed4c27ba980a17d52fb6f41352802a9bb3c69248706bbc8f96cc7b5fa03c1686a9b24f82ca13a9491cb727baa70f123f5fe141e90cedd2b2e3c112cf6c86699d24c829ab3ccbe3a4d93b891e8bb57e3dab70076e508882aba4b2e0a0235922f89926e5a59bd352b65343e8c3e2682fab57b36cc73b18141ad8d69ac1149820456831eabc3dd96f787b163b4c5c1e7c5c4e4219c14760a74eddce611a3a7be33fd005236b1242c368becff57eaee707e31740bd999bc1afeabf6508294894d57b3eb7aac9f5222ab1b1b314731cbc2b38a914c266d9ac507850da4109eae721ae79ee1b2c222c20306ab08e04d7af322ee1382f3520da815a522ba98b7a3b82eb643363bfbbb2d4492da5980923f37153be92be0074007448856a67883d0044b52c135dd7ec6804f2777ab7eb848773adafab7f2eb8b143ea30cc60c772ed3d6c97f38ac89cecf23fc41b975080550e7b8bcfb0937643968804a77d67a1757e6d004bf122554b31cfae2e3e7afcd5226e5487be980deeb679523c47f5b715ff96c69ec96f56c5cf357b06ba36c2afc30df38c1f57417ec03ed40913d6c490e4cc3f70e21b20913007c888aa63a7b39bd732ca1be9c8482b151b7c2ccd78c1db6c7483d6c10f7bff1dfe091db70b4b1903695e0f56dcbadf44e072d3dd6262732ab6d0f75264f3d6c7e05533f3988b9599cbe3c4638ff120ee6d0859ad23d1295689043680d7892691fd6444ccea62717e8e11849571c493b2dab75e7b62c3cab656430ec5b6bdbc1363b7a5cefa14ce5a4abc73a2ba451b333158e906ce1129bd9bcdd1e5b524a8d35d43c6f44c633564bd7a2ec710cbe008e89f9baaf3cdd27b83306d68ff1f85598f4139212a1daf97a94d0c12b4d0a4fdfffdcb86cb3a4dfdc78911fdf2d661057422739c62781c2d0985d66a70e40df538c2566ad29af2c75c90aab6aa4f1b2244e2bd1ac5f9f17f857f34fa692e8a921e8bd5762c74db758e23555ffcd8c17acb49e3f6fa41d3ed2bc42b8b2711fc59d0f4b787416f30f18b05db9edd3faad4db22f21e400818c6ac4ff389c9acbf67242b0da4652ac9968d101d96e2a158fcfb819c7d6a0a44607448150a16d1b5a7c3d4f53b09f2174d7f1978512d3f7b1bbb8d3d73c28d627108b76cc98403cf6e52374c0b976c54001eb770d821c59586c4c3829a9bdc765c410316401df09282195f8e2cfa066a3bd912201e8423121ce11b38fcd9853d39991269b63d2d0920cbc629603b68639c8175808f3244162b5fbce135e046104264f16a336f290bf9b339e6ea99f0e9176d0c3eeb11635cab78bb81d04db82ccf3ceef2fc97ddefb3b8ea30bcff557f003c8a464687bac1ed9e4d251cdea62dfd71a2151bca4a6bad751afd2e36fb60d4f8f69409acb329b5e58a8418242130bcc76cd4ef2eca071dd23d1c053a50a6594057e1567f4ada5be2ada1f1e206c39f7b7f80402e3da83c594d87ccce9f0fb74a39f900aaf5d8c2db75db186d4a3f6a4394f80193d7139710b50a59bf463d213963afcdb5058605e454f6891ba1d6c6a3e1d1046b47b83537a0c44f3405e81cada1bd7dace161a3ed676abcfc717ce3ea444b70c194899ccc8d3854d2d2f9445f1b2d4b0aa98da0b0c6236c8a88d1e7b0d38222057aa45e223f3927064629209da4cea3e7c5c1478817588b20202c5d1bed513a0af75aab15e24d40c8ade1cc8c066517a460d5c65d137eedfca6f9a86449a200ec12cd4ca441a724e24eed47e21c414093faae6a9c8b6ad50eb7f297d646637a810cf7f92c0d3f2cf7e8a0df0b1aa7bf03aed13bae12fe6a58bf1947ece4c780918b3b7a926125b1610b56ffa57dca835baf1b3f54c82f33aebdb9f1f0c9840c83e52b87304bda75842a3f11007bef835e8c4fa3358910e54d7c1208fc2c750bdad7e36d0bb3d2a8d60a5defedfee6fa28ccf95d430085705e03f890b5b2aa871387b1e1ec19123a6fdb1e0d3c319625fb7829b804d957a0fbb5f7f926de6ac6ba994a8e857e5e8cadc3885a4a0f57d32e040511fc3dbd86a160765cc251aa9188b267a5225cf23b20ab391cf41a126d70b0867016a3122e3f971308aa40eb913be0750d3522f03e6f0642f503202a4706f973392abeb9f161b5da47a2d82eb47ba57f4110ff5fe78366feeec71fc9fb21195d8ff39228cf55f4c0c2fafc778e1ed5e6151ca79d71ef52ae0a87f77015615658d9f4915d35a5f28d2778bf43ced6c6415981bdaae586ad182137c92b1b65ddfc9cc0ca2fcce039fa81e6e5c9adaa7dee49f4996d696204042871355126cf3d6c6cbda28c33d91fc311d9b870b6ebacca7a96d6d9467e0d4b366a03c535c1b76c11418917969af3d5040807b4588f90868a4b018feeaf743cccf0e72001013396fd42102340639c8353a9381b9a2797224dc589ab87e6d184386814651341e8aa616742e8972eb20194156d2c6a0001100648761083c26fd712a3c8e0a9167a70c6b8da4bb00f1b7ec03d352d2a3ef1399cd5cf3e9d24f970f773aab39edd1e9f6f572203d272b2a361977c81856a0291e106a298399c6b6c342f1d661690a3fd7a4bb6d46c180a99ef183c254330c2e1b0398110e7f797ff868dc323c632afd0924f195c86965285315e907e92c7603535db1ef2a7ebbe6b31266df92478a7d9547246af57067757511f6340dc8e2819414add8970566ef7b231e9a860fece979579836775f3f27af5b0a106eed61c579fe37cf4e40fe09e5d1b3b9dc9dd8a344b3baf93b51b6622b4b94309f6710c0fa7a756a2aa4d90102e4cb31b21b89e5a24a8bc4a5b73bec3a56bdfb82101f80263a25b70f83068dd8d1e64cc98e63b3aeeccb78d6c9e3878b62a9c41abda9f32e3164453e971e6acdf7f29f55818e7dc5cf8d5c1a7bdb1896fba395692a30dee4dfdc509a42c658e854c1bdba8dddd1aec59e43b8a2c0a6d0fb8865c98d269cd04b978eefcf844f76d99251a999e2df85daa8352343c13bb49a0d681ea4c513829e8131c939ffa81a34aec3aae07773adadb9660b79ee1f063b8783e5f4a833a405deb1f5a7991f87d0bd131d8f8168600ddbd0058c3eb0017b83c1b05588996f8ca7ce0562878a9a8266d889a03b5cf0f2fb63be78735f9544ab4cec7ac59c16dda5e488b185b62bd528e9e19ffd4a52e5530df56d0f0a407be88f4de93a16986c0ed4e3e6433a8158e71c20d23c0bbfc107c79526e4557e05e681754b0571f8e8a5f7b03bdcad40d29fffbd6ea56a614b41cea3942dd73d6ba7c347ea9471caa6ebf7d7ab348fcb822b808929cf9dad5741f9556a6c73af196d4bf904222325a45a9e906976e93fe647b8d8adf09e5861e510a821b54adc469d9d3eac678229742a0312da848336eb6db59955c445d3f376f6874057af80d7dec8bcd18ccf140fd6b0831148c775656fd9fdea9c539f62adbfb21f3bd978e3926f4e64fdfc806779260b650e6d6cd0a0d534449e428a18620c98e070876f9a3daa5e5c5c8363ef1b6f4bacd049ae85b09707c1a5eccb2b26e5deb424523ca53d307b01855b4b62f416e2513eb84ef45f6a4f2f4d6d03edbbba4b05b8501561907c58cf8b106d6e2ef3b4bc1605a2ab601c36be51116a617b2c2eeed06e44027bc7b1f4cb023e3aa5de92803782256b75c5a0c7e9e30ae6c0812ece56e00b160d1a47562fbfd22db64204ea2657f713ff995cfec26972b056dd41671e17bd693c81feafbad81f73022d5f5e955f13a1de1a6b2f4fc4b975d0b1b21b4a213e4c67850abd75569df51a3c516d11577f2ba23d320b1b2e852469f02d762ef1684d514a8de7c7c7c4068f2475c52d2058964a6fe272491712c254e183cc293667605b9afe4c7151d6b79d3c4eb2f493e2fcb1afe4753e212fea6daf32293597b00035c4a0d08268ed71fb9deb84b5e5dceb2680026cedff5902994a259c44373cf7b15ec29e0893994772278f74280f5068023a0ee7b7b03393f0ef95f6acf13b6f4f3d3543124c867e5ea070a4fd85fdb7ff604b8ed13bc6a747abb9843f55de90478b66a21861d86efae0a8e53d0fb17fa9d055afe7a9e2c8c3f007c874fb6814077fc863f66f4141a48600ff7236b7602666a599ada2d22e6e0a968c803153acc98959906c20e6aab31be32554f4719a89b1a2680d12e9dbec0255699f3ea87214c999ce0c86fb1a23d7dd6d40c225bd449265bf500f6d6a01d7b50883eb7e4d32e0e657b50e39e36e1118274435dbbd6b30ce624509cd7894cb910836478f7fb2a15611ca792178d57f78984459496e97894409337b6fba4fa1d807f21a1d930801ec10608091e3fd4768f5f4b513906c11c750b15e72d4e6c55ecc9f87ce9f4100a29ed52fc29d936356e72a82f24966ea33213db9ed55439f90e7fc720c516a68e6a740d0c08cbc83f5aca4259cba5b2adce4b1fb689ebfab5ac149ca9957a6c801dd93b64fc75b4fa8f9ac3930145710c63f3e78ca0fbffd058d447b941815fc38ae182c1ae539b253bdf1d3b43829bce332157d12743c76e2a30826cb9de44a8415097f876b6822c22d094d35618045444bc515aa0ca28f3f14c24f0fdc1e2d3e0f6d1410f37c88e1057c35d679908e8f50e40c91e350472d468d34590ebd05a11b88587b8da6c8a2be46370a9bef2b2d42cb30e87904b5f6e345d335336bdac3f37781f8abfe29f85b9a4cb8d450a78cdda1be4a18b3f31908f2ce85805a0365dc7677793ab8d68b8c7af6438afbd211ff9109f0d322ed630f462f2f954b63d2408c0b2847113a23af6d434d0e746ff24299f9eeb1647e1fa4da63849f01379673dcec6875d470d284a24f9db9ff890a47b1fe0b55755fa998a6b32b88102dbc84f4c5796e7fd2334b6f15335baced92ff0a4cf253a6676c71983cf893eaabd3e93cfefadf56fa4da19a0bedcc46fc5b479fa7180307071475cc03d73cb686f2de4c9fcfb87d14d1cc2bf4d99fcca7b2a3127d1d0738579b8651cc32e3778afd3c698c10c4c1bf2d64a1e41fd4445b1cd10ad427cfd91d0630578aeab84ab548d00ad4a03d85d04edc9f4e8def432ad47ec3ef7ac9d20a44623a4aa3b87cc3a07b14fb0c07d313d02d1bfc704e01999139813ef1586549aabc0c1f984d3cf7df11b3e19ce06f67e36d4093110303fbf0f4668d8dce7a512ad94bc7f6008c98c3b6c036a0c7cb68d983a3c39a7e0d0d63c8a0ee75c70da24dd1d3484904804ad6e1755c92148c51b8d9e90cb9289cfad2180275a015408d83bc7ce12207bc48a61d1b9519839e081390850d51319855e220c5df296c52f1fdb01e25db2d048866b58de962590ce337cf77f986eac751857f1392a64f79707a3ad42bf6f1186414c7514cc5a5e2394c4ce8ecafa598f4f0740b7e06c982da5f7f6c866e4f12b07db104ff3f264504643826048cf83355b0323765b9330293837056746fa9cfbfc423e7eb7e96d0b784e53679e557bd2e24199f122a1c849de09a72aac58c58a18d1f44e116fa914c129b325f1c2e01cd00a4462d68f2d5765cd794064c37e278b90f351057fc2beec202c946bab29efd3693ca8fc6904c81a8ef85de40e3c3811ac6442ded8051ec73b2c8660982b8b271145b8d68477764362962880474e9765358c39295a8fbbfaa0c74cc2a2081888d02b6f094f9d72a9f722fb1ed0731a00ae9d41937ce9a420b850066b515d6a96e209c03433857fce0c51bed1a1cc8e8aadb4a60c999b8a894e7e351f5d470c74a5ce15c1617dacf4cd5ad97d738365df496fcabcf37998b52604ac87304a0ad52b5ed19b720b66216f59c48e8ecf3dbe906b1b271826f2c5872c55778ba6cd9a6ea1a42fab8ab515d39f6c23ad107179594ed09078d4ba3c8c7e104adc9881fce03190c68cad30b398d88c24f4f801f46252b6f12343084f844ada05d13e1b33c220904e913a2dc63d3dee26f15c4cf27533a8fa7f8e30d3da3950f93229f4da06748b773c07c24bd0d59a0ea502741418a980389a52ae296a3380219457e9493b46400291732e3fe7ca259a25e8c58aa173ef66abf170eeb4bf1f2e591b4952182315a9860a117c97c3ea7fce33a1a9334d1b7d7862fefdff14f68c0f1606f2c51524bfec7d4297fcb2d3100d1a7aedae7e05333a16448d3a7f0b4829c60b330e672dcb38c356804b8790c478ef74f61fb96e3c90cd01c19f0ae0a6094b7c3089c6e1cc396573d8c0783d561b072a6a3bac71d8a391e69be35442737055691335886d5bf2b264b7771892920140ab9c1ba4d7fd81c6f561e8e1344662c1769566d87101806eb9e1b9e5eb21a7b92c2e5ddc85d98b758e8935a37dc86dfb6ec9f460f80feb6ec7c2c5b929fd6faa2d7d692377f3b8e4bb33c898942c2c23e3a332f2796e88e22f720af86f8650e7710ecaccdc5879bad1d5e46c41ff96ede80bc0b69e64d3dd167915d149ae8e7c3bf8cb5fb0911f2794ce0bc68237a881231990eb324cbddb9b575f86cda0678d39c0aa054a20b2521396f363198fd1acffcff81585cc255115c2fbff2e3bc218afc2b4da254ae2d337c4e1faefb532ee53d8065161495441ac587cfd391717979bfc274924a39e4dcd2554ba1533a888da1cb52a47ea8e082b4a18b86e48cfe3acc54d2f4c64c82d22429eba88b1e9e663304b95df3e22509666551bf971dd3cb5fc054a82b2e0212600e549b476e726010037c6615cab92849bd247046008e9dca88207ddc5cc36310cc88bb284d0836a66cd231340f36f3ff6fce1e5bbd74991ae4364442d04635e6a9d8fcfa52a4425ae7c82df238a8be7e63217ffd6ac3104c988e2894caf1a12450da86b29599c4fb17097e4f9a8e7ee167d164d1990ad117a08469aedaabac3c919c301b5babc1fef4e135382f3849deb3aba67a045319c5b2d61d8427f138d741b8179bd8f6d36e73e4baabfef963e208ff419e65143c7a028394e227c53502eec93591522dae8726ecc0d5baa77e73f5ac39707c27fb1004ae16bf10fc565d31d4eb381c6cbeaea0e4f3b99ab9f6e30cb455a017996c0fa7ae1eace7dd644f8f6ed2e9d9171461403977559dea507539d8157e52a698a82dc88ff53678c3d0af010a441bb0107dfbdf19ba403412bb3a41bfb7468b6258a77f2d1e18434b97e09385bb74e90b03abf7a9a029d780ba2cf0efa68700a99343152dfa6adad5123f70c3d9eb4c85e3ecff798e54045b3dfe0fffe428bf31c611ab08257d3a75b296d2da6d7b94c2af28ebe1fa78b4cfa6a24762cee53b29b85cf10f3c42b401846fa1d800e6e549afc70e9884237f520da7a68a0bbf765872b57f26bf29425e10c0770dd192a94944d50d6a0654bd62e3513bcfa1648e339abcda083f8a522e3ddb0b4113c5b8e955f267a5065b64eed0c24c983cedf3a36e101afa0ddec9e7a2c607abab235b13f794d2bbe88e585dcd959693a93cb0118f8392a649b26f16ef1f93232a1fd95c522c740393310ec318d5a37dc382fc3ad1fe3fdb64cf44a71053f0ee0cb60b57efb47a683eec6ef4abff5fd41d8b055abc79364e2b960376d26ac7300ee4ea583dbfad6f2784362e8a9489aef24c4ab262b63df667dda2ae6d9c3eed0ff5a445d4f031369dabc861db4a74b0c5124f082e864e3531d483c780c009c2a66de1d0be999ad2deaa746500c2ba2e4c797ed4f57376ab2d2ba017af1ccdc1ff343105e4450dc9172bcaf03966a065669982f443f3cc572154758637eb7b02f3c396249699b59a461a74df339b3f967b1269d1f5551e78c8a40bcea004cd0fd216664868867f29524eb75efd9bb71e0f08f9f21314803697c583e9384ff5da01b7692606cb6c51356ab399e3a41130e782422102cfc5a095c3a918b06b1e2869730590f408d5d478367f5721e368d54e75d727594a778ac4a3e188a44305f0c611cf1c7ba90b0f284f52a245ac0e5667b3bfe9bfa32d077124189fca04c8fb7fecdb48c99d96d497c1fff7945c48c2a13a9c4ff0885a25d5fb843e7f80e21b7234335141d008ea78c3df60959c8467398beb19c997128ed67b122def88facf5c52f86f7aa1c65ef017ee387344a35c6e2bafccd256f35d5ca195cc43e88deec202bce1fcde419fd59d3abf12067be1d67d06c07adc87eff05ef3ebed3fa5b9621f0f3cba6b19d26009952968f7596f313dcdcc0ca6a423578720a1d430582ac2908a7bd295c8992353bb14a092dbddc4a2b9c6264a4dfcbf26f0e8fa4bd8d64e97081c7d1477365f97f79f950df70e9aae1224462120cb029c635b8cfb39b3653f13f795e3f2094937cfeffca4ccc8c09b8334ffaa1ae8750024ad9fb89fdded472fbc6ab425f20e96dd2aea6acb4f2d15830889a0531cf9dde2bcd713eacc09648bb7609be257521d59f2532de6198ee98cdecefde9a1751916c76494ad36020b95c6b8e0a83680eb4f44297ce15fdb21c6be70a170f6b3813f63e1eb0ddf1b239e80e95c1fc49f25672cfc0d90f849fdde9c3bf090e6da84e30e999500ee7337e691d71eff4df09e30c3bb222a55c1850df266e1f74c2af02c69bfc06c2f46d8656ab10151600a57737588e18e3ddaf228643cbcbe77487e3b9b5f14d4c8464e7e980d406efb926d465f5cd51d1c1dbbf12fc3d8cd4e43cc8eb91bb477679b47d7288e8f0c3ecbc2e52df50d882682b8911f6c5a05b27bae01988015d59ce3c3e032ba4ef2d7c2d9514318021404a9cb6475c559344fb1450b148bd8de464b2ac2e2b89cbb4b7ef079424a5b4705817ec876363262181dda41d8001a071411987a54eee566b1608ba445bad5ea61eb6fcfbb219dbc2c5ddb90a2c502cc9370288ac84e3e6d54ed60c690f1198778c213f9466fe8dfd7037a13744da90bca11633cb1e4c23776b90383b5ec52abac49558aa2e7c74d1bdbfc58e39531fb0c312705d4ead7e6f1ecf709a7173a8ab4e97cfe5ebf2644cd4738a9dba58f948316fc4dfa301186144c8a801ca7f889ef6091c811d108ddb5721b4684acad063fbf0a28c1a1b467ead6d45d7077af719219078843f3885a8e711b4be17123ace7a5f845b8fcb4da74ae5c847ca4dd3e49b65eb28877f1c89731902bef392605724ae61300a5f573f53a74f6bd9ee47ba098e2656df384a4a1a1d9b04df1d000a89ab229448d7bc6e62f9a399e30c89476593f5116b67484c6396dbfa9c863342f2af43cb0ed016852c07a1a6e94290fd82a901d2f25d0940a4df13a90a82d156a0c6db95e7ac70e622b829da16f6aa1e3d6d50d491d735a308de22af118d610934a3aa71189c5c3579f7d256755cc6379cabc02e5941225aa76a406fd3bfff7040381c01ba0fdd52395cc6567860ae2c47b31d62e9637471072611c886201253897644fbafbeee42b7512381d3bcb76d63bb465cf8b52c0bb3138ec68f3da34ef533edee7fd38877fe1dab45308da756d0a0d4dcf636d6cd5c09c61114a4cc28548121e9775b72e9fbc6ea6baf2ebf2e11a650ace454382e9ee75185a79e4e1e8cccb83f9987b3ffd946391d1724dee56532b60fc5e9c304dcffc8fd6d7c2638e87b8e0c89f227f28962fa9aba2ec7daeb5fc9a309d00ab4e8e0c4ab70bef20077f5d47794cef872f463a70f1c2cd99f50c6a176febcc741c9c1751e9892c73bf40be3b5471fb7d01fcb22397aae5dc2eb5f86bfb5d1ae5c85a384c362d1f9e58ad5840321e911bee8c449bd489bd07ff9c7442defde6ab9827fe8b20c4b105750d5be9fef585193b761faffb2a82ce4b535f8fe30c77b2ebf178dde7f0e484a4be4231e00a31dd514806505c1c46b3e6882fc31305073cf71b490a1e6eca614fee30c70485a97d470e1711e7759fedae6a25efc99d7a2c7dffe2fc7ffcd17be07d5ed178b2611152c82c69181fc751cf77d3b7fe8a93c7a9c04df6d7f1dd3d3e7fb2da6077bc637cf9b7c880e21e1cca517f0817da785997eb97c99bc08adccfa5610b78653c20a12888404470bfc896d4d03d2d9cf6396434126dd326a97733998f11e82ba88c456a1a897bf512aad9fca3500dcb2528128101a395e63b5bc6ffd24c069b8f5efc7de3710f5f458f48e279e9daf8011b60936c982df8733c5c275fec22222a7101f5c22c985ad1b890ba73a82fbaa697952833745d871d710b49bc5730a4189c90c14dbdcc1a0a49c3535a6cba9d394480ab004d2eed7acac25ec33c0eb3cecd59e98d8db11a1d84c15b03779ec0bcaabfbe04939211e48fc40244dd0499c3e075753e6159e0df8b6cdcdf595fde2531b193e435fe0fea9aec993d7f0b6d492c656904fc509f847516510e3109bef7f93e5c441845250ab4cb3b3d2cafb7c0d1ddc6990f33f94abd402c1755ea57a2996e1b774e5ab144b454742140c7243f8fbcaac21a2308baaf947f5971ded9372e0203b26b53c379d6fcc30e86de854320554b32e889bac7396b40561e7276de5c79d3c871f33878f984af500d76cc73229b39f2f6604cd5035d96dc396174d9d854461042fd80edd7ba511eb84f5bce64f05efebe22d3d274f4947b5a12a2002174ca5ccdcfbfff1064f612a49116e17d06b2332b310899e8e04c2ebc55e15523d411f7bc3249eab2d3d0ebb311dd86f9fcc5fe81ea109f8bdd57aa0030de1cfb89eb916cf9bd81e786e29bf627709d335a20bdfcb332a7bac7b5bed134b90e9e094ab1c2c654c7898a5ead3c352b313095b55ec91cde6aec6ba0d4643a65266cb22668dd9b8cd8bb333c8765ecad3a86bca291deeca48a15d7b24ebfa96954f699d41d1b624b03f55322c605b0d3f8f3066b79e53d2c43315e5cd14b0d8411a5378a7afc745c5974799a74e13c5500e2831a0e7353d91b0fb64a2e4f7cc3ca6d29f06f489827243b0299d19665a3fbc1e1a4e3922a7b83177e5cf012601c6c4bc460676ef8dbcc47ce367e4dcb2efd596f0ba98d688e198fdcf488c94f6fef27d368a419684b3aa1024f7c7c0d884aeae60f66996b998fa8b29dd71e46d7a2c6944426dcba89e9447d30afe444f69924c9cbf9986577d0b9929710928da1cff9a8b85cefdb79c1b21bb12c513119bf9694884c8eaefba81dd4893c93e0d97bb8b70ab0843e0d36a24d17747a7e7dc26db9bb61316f94113af354b21e46b608e7d6a57b3aaadb3402f68b8151cc740aa0eb10ee8da1e3003bfb004cf0132ed0289fe784d7c8af65ebce7d86ce1e12d438219b85389e7c67d727c9be6683a12871975e3785ed7ea43f3275a3b78b08c8ff8bd2cf4c2d3dbec2f39544dc726493ab3ef2536f313e6a77bb6d623d8e8e1b925035b53a66b429ef77111b22d3f9db082c9e24d5953a28d818bd47ff27b602ff680bf42f98461e12166a841f4e1227f83a97d0ba85f057257243dfec59ff6e8a16238188228f8d416be52ed655cb0f5b8d7ac508023a981cf238d385a66eb102647e6e2185bae0c4568c1efb09af0cea464cc2673eb0dd5263e473529a6b66e643a68bcbd5a15a0d817ca9a10997debfbc8bcd4bd0ccece7fed8b3d5ef0492dfe676c7bfbea2b52e792204566c96c39154b4a62f2c031cd0761a21ac84a8a9c694d53251b544315675a40e9b407f4807b8dcb229be9a54fdb4eb0a8e58ef6e83f64e60c5397ff2e62448ca933009c111b85c53b247456a8e0cfeb56f9f0f31db62cfddcb24cf35a54951a7724a5dea6139df116a6102239d2d6b2734e0b9762b3e0d11cbdb7ecdf3ddc8262504ac39e0fc33de223abea3e3bffff553220fd7c449afe7c0d88a5218d28b0ae7c597da4638503d427903917faaf9df0df0b526bbef8ca7427706644f8fa3e83610206378234a5605d68ab44f7549f7bc04bd3786f33948b60d25225c619da3fad7b76b38cde5bb24ffbc6f36eee4d57117037851707b10fd5b2345c786340c2156fb785fd1a24277bfb9a82f52be0c448104281cdf1dd4fc44bbc0ea535b918cebccba708f78637e2fc23e67849ca2da7055977fa38c8fbf2420b3d68df73d47f10afa87dcbe4315d8fca16bc62ec365f7ef8584d43be3cbadba65bbd11889596c90d8765e5f632487329acfd2192b74c4bbce73869f68da7e364b1d87cdeccc48547ee376fd39bfed6791e9df7fb7618b71342c74d4cf9706f9a4cc4c7daf4c59e5159eabde73f4db0c164ad5b5986d614bf8263ac728375e2a722c1db8ea82cb74aa312b5d85b66ea1fdf6bf2a6c8e781303f51d0d89995364e86d46b70f72baff39b3e822933376bfd511ff4fbd877ded65a629cb433e8cb1b313333bc0336ea17069d8c460c9dd54fbe16ecb198563e4aca3f98ed055befe295a58bfe05018819cb973a327ddc44c0536c1a8aa511ca8694549dcce404661bdbd14f915df2c6ebe782e73ef988a31b96a025608d021882b68244c841ef86217ed97146e3d59e84dbc61290cb312d4c20271f55f2a8931a4b1491113401ab6cbbb94e8a0151282eaf34eb423b31bff23745a752e1aed2fc57568ce222b8efec217ab499146b3741eb9433107137326b8c5d3411ce467fcb4fbad9971f5cab0334025f33a6d5eac4baf8caa953fd20418f3a08296ed1e9c69ad84f9f726c98465cfc0c440a3ea6b57fc0f8daf160dc557219709cab043432a9dc01de9f8bf4f551a1ab22d802d66793c887da0c079b3a2daf731cbaeb58cb648c6e350b3118bcb80b5be4fd7f2dee182271e7935c0466aad2d31a12f339c0d52029b5108d0702b9ee9aad2c1d0cda345408f90cdd2d60ae9bccceff4f921a8a323d3d5ac6af26e61db8cf7e8a0d8f00c907cedd730ed13a3182ed2871c1c9a2e49d40f5454eb101e9cd94b7a805120bd0e948d34bacac14f96d8e3dc6a262f3278cf3fdcb0e460618db29ce2df78e39e83d9c7773b3ee3f8e24f4e985e78ba3e307972d9fc277b0687365208ea4c1d38285bf1b1ebd6c386055c20145d8e6060d297c67962d049aca38828fcfe5bc8786c74cc5c2c21c0424839984708b7170cb78577aed3690e62041bd03748448f749d169cac92db3e24de44a5bf5f108c379599d42cd898235c907357437c2367167ca841ca4652ef32556f590475586821270b2cbded67fc0786905064d14c580608bce0255d33f21d2949fcf1de07eeb63ac3ecf8b9e8d632fe5baa3997d7c2233a9c37bce1c3052990fe6ec4f1a84fb037fb17a2f0ff6e90efdb52eaf07a0aedb8f3facda4d59fc12611e01a90f71f3657abdc33b0f7d3d02e772f32cc8037ee3935d6b32935830d69c034a1877bb73da3844a5e4a9f5fc6cc12692ba6eecae7c89bccdb462dc7c81edb0a65a97ab965777f8dd6bbed9d734cb36d2493d64012589bd6f529b157c893c866343f17bc87021110dac1ccdc560f257483b5a9f42ce5645f4b773fa84462d7227c85334834764c2e65d0c410a134b5c82e0aa4b35ebcd80987d907ed47ddc5fc9a3552e80bd0ab51a1201e2468e1455f3e7b1ca9b63c6f2dc1641065dfbfbda817b65e6553d74a42479739426c495dd81ad0ece43abd657f564f1ad5360222c8da00d1da0abd66c88176dd4e9ccfa113630606d7817883765665dd308e3ffb5a44a99f0561c2842e3b4e0cefb64b6b01a23f18e5f6b55c04d5b2202091eb47bf66bf19093e0392c6b0c16868cb8e698554ea7683c516a9e6ca7848de0018b77e31d86dd3f06256d0dac0312ab5bdcda836ab8e7cf663a01a2a1a2fd0cb7d5c5f1a8e462519e58642d1f4ceeb9afb76f59f7635fb051e116f555b1378a4432a0633ecf57368b993ffd94e14407e35f9711aa62fef293e824035ddfc3cd5354e21fc9576326ea79121ddd05e12a268064e07d0e023828f16fdb72920c5749765a32afe788067d0a16f8d9c09ae624b065d6cef8e79bcc44c02675fe54964a8236fce226ff020aa951bd64826571ea289017e424a53997be347341abfd865baab5c76fd44475f885329fc7457d2cd24c4bef6163c0b0d294905ca9f3569945a2bf191f72519a05948d7a60937c73628493b0afcb56e30bc0cb43a7eaf02f564dcc00b87a6f18d3372cf3d795b5082e9151e0854d067ecb439a02b17b352ec0374c31177da92308e8a294a00f2b70876d962f6fa30472e909aa6ca540627c651e453e8a3dc8be31fc86b78a76d527596768d9dc328ab584ba9c3a838b71683ccf914184f02c9b86595b556edc67e27d003ece8525105a4497b75b2afa1729b6b3cc5fbe8f03bc7adf08bea68d4f1d1f0691b3dccbc1dc52b44e9247326ac61ad3034e66d3cf1f648d0e1cb3cd89df5fa1dd0d1703be6c78093da98bad0c6f1a5632415cadb8ee7e146804d37f48136a81efe221432bde0a79a0b524c56db635c5dfe6220524a5e2028cd055397a26f85545c7eca12b78ca10faa0b2d88717032d7e816bfea16f0f16b589770f19b8fc850cd2e4e84f8717dfe2433fd774ff40c53f428eb7b89e4d52010334c1f9d27944070c42c64b59251c2eb6117f574bab20ae84404836b346d8391b25bf4236dad98b1b63a7e68ec0aef40502d4f8fc7261d7f63444b7622a10816899e8b8c770db00027133d1cf56716172b3f639b59a701b37af34dc76a7de4776ca77cf504ced0257c27a57e77f274532f4b217177aa9cf28b6bb5523adaea03985391a34f67f06edb10f13e83e7a38279b893db6647c8845a4c0259883577a83e4d3e1c945f044f3d1cf1e687369c3ad036ddddca3b6eeb42dab8ee7b9b81ac8f13750324d9583a1b8b5322b47cd4a040cc5d9f823fc517cc2e3e405aea619c281d02727987a7b134a15de2ff0b560c1d0791daf024011b7340df5da612c44e5eed676debec01f2080390883290a1ca257e103f15a8288c2db9e230f0b004600f6fcbc0b1755ceb073cafe3745497d4f8867d2d109856a73e8d16ed037e07fdeee6e3ab7c67e6a59713e8197ba7a7e8282b82e7a0f9d5ddb34e82c20a3bca7d42a3386c233825b5ecae0800d821066169f955c3effc34f0badefaca5cb16723644d00e4c3e3c564ee266c9c53a66a9d9c05dc2106b15f0e4876d42e342641401e4b8730f323aefc626b4af118df949e027c187f312f8240545fe6f7f14f15fb70388da8805f16d27abfae51cdc10071cbb678b26f6f4299ac1fc26a500c0e9c5827c737070880462100695918d3560ef30a3a41df5f9b433da349de06762e0507e14ddbbd0962c245dcc2b9a060bddd3f41aea6824e2a160b4ce4983e04ff88a1e524c56677d71305ebbea4387e46b28dcffbc20fc7db41a85ecb305fd5f204320f0182fe34bc02ff9100ffbac7e0a6a969b621b1486b9787d4e4ad0543bda6c5e43debc84408268df2b1828d14d0bcfcdab1bf52051ae32df0baef37ea77a0e311b0dc817146643c1b5eeffbe85ad49c757291895b08b65ddb39dae54bb1e0639fdc948440e1a792e7d12cc48bdc7f5bca4cc98f8ebf778de000e92bc5e805a709cd9cae0f9830be3597d545561d3ec418e3a8122188d250cccc578600b39b542ea3e1059c2b563486c897842a89b5196a1c35c480847eaea307fc1ea0ec38d904cb0224d2cb8f5d53afd32b917a4c7fea376030e6da56750540dcf6cb23d760149f7c16344a42f7607e097a3cd985e2b35fd77afe22e04fdc5b0f1c2e483e6b7a05b675c9f6035e29723934d60f050c43d381d328247a17829cf025431b8e7c803561508ebb35091b790b72fa5539927a21ad090e2df510662b897307a424cd380cd252f3f231326bcef276adb13f3d52e461ecfefa94ee89fb3473afbb62b0969f73ffb99d67b21444b644e207839278c6598a96dd5fbc1a185e1abb6395ff4927d14b707a2f1d3faf58f85ddf6ecf5329d8561f814c51de8f6c1f19e07f32bf9323ac5fe6f5bace5b476c4ae403085110bd2ad0585b891208a40b54c1fcb84d33d8cc3d9c47cdce5ae1595c4f80007cf4b1df3b644a123076d9adfe65f2d6a1b22393e3d01733a7185b04cc5f8b6204973269affa3494a963efb2dd603e7950d6056610685079e5d95db507a5c935cd306f02398d1564103613cfafc2a0ecdf7f793f0c21113d2686b6362a6e40f22773b24009ab6e91ab26964612cda4a36bd20cc1e9615cd0f73422a2148ab3116537ecb468e4371b3b65c2042d5b8778946d00c8ed0f8ec2bf70e329b66bf0fd1679d88e35d1c72361e3a30495efc0ee9712edfc27f0b6d6fe539bdecd1d2ed3f40e74792e74ef74ee3c8704ca4347af6e0f44d7a622aa6c1bba98f4d14643754156300cb84fff44f40b36835090dd16e719fc99e694b982988d8f24e9c3a8dcc088d95a7862d863c426fa48724bb0b90f8f78096b59735d7ffd708754e825fe405d3a71c2dc42eebd6099e514dccbdc75ac613c194ac9f0602280a83f98a7563bdb7ac498ea6d024d28719dc3ba132f4a5087a1b8d5d0dfb10d837a17150d1877b87eb3689fb6bd60d373111ddfc6a434983b6a5c0533ad4195359510df316f64046c7117e19b31685e6c60d4d875ce1f216280b00a546b19307ad0e381d007783e58b793a3b5b0e6406c992d0801d0df6c99ea6d6d771d9256ef949b507887a923bde54b2eef110861d33c1558870321d30100af179b872abb3c207d311b7759c32ad6d06daeef3280264afd14814569eb10fa9a18a25b78ef0e2aabfe2660403075a0c9a1c6fe3cf9fe82d8dad96ffd3f407cebc7ed4704c8092e5a8d95cc2e438cc606ac1e092d6ef72758c2d60017803caf0ad413bebd45eda701de08717c768da7b440b433d42d04dd0f6f973df16506a246b2032cf24e01e0826a0262da609b87914d4368bb16ab0c35c16c8cfe3a3cc738ef4e3a56a810c8c62cdc40bb121da1aae6c911907e75f42cd5e0a756212135650e0ead81f63ac5f8c521e522d86f0ce45eb8485f9281bb138b93430395f5e5e7db556b46dabfd0b15a9a47f75d65264f5123ab95422c8e5f8ccfbb55d481f8532eeacedc4f45d86da88a31ae93a0230cd3e45ea2e91624eaa5bc3b63d74f868be2fdedd83c1fdcd24f5c9407e7eecf780c5bc74701b792c788a146dd1107348c8f4cb69a39a93081361854d99546261afa9f2e7cdcea7e3e361063ec8f54e47bfb5cb382690b5036d20e8127437e17053ae7dd9ef5f302e3ac9dadcc197e37a346b3845d95e50e2f023fb184c9948a2bd441d02d840b3baa551082bc50f6c2f5591eb2f94ccf04e2e92aa970d2a53ec382f09c3841f15452f331062e3a5041d89eaca6464d24171c394f3f568962cb119a292da9d6d0ebc0836bc6a791260feedd878947863fc2f30bdb908a479091a50f70cb363740add9b19a26056101634e84226c971caab804dda3fc9475774245ba63453bfc01d3a1ea4771003fbac56a7d9ed25c1032ad0a72d71490e9c0f1eb888c04ca2446af89f6debaa211f1cba467c66f9b6a7f4f541587414fa11df2593eaec07e4ff0702e3716b723e172a41a4e58738019e2c0c22bb8b0daa92370a6c2533899dcda7685b4878e452d22c3a679a60e4e8be9e9c57eacd51d914a3dcd28aacc2b79b2e19173d3bfbc47347ad9f79b704e82b4bb1790546763ebcc0e79965aa6b207b86922d1b24279c28ba44742bee3892b74bad562fef0477547190f8af031c33a1a2a32dc4de3cbd3ba7fa0141ec0d55fe0ddc5f23d423488e13811d9b7b03356a9ee70d1e919252d542f4534ad0836817c53a76ed9dc4d45980654952305b73a36ee7964e7f94c7f33c22ae2e9d385505ea0b89fde8015c7a687840029af9eda6b109a4890a5a8ee18842210ba13602811fbaed726eea2d95cdd7834bc9df1db190db964d058b1f985ceb10b50f94fe1a7e65747bbd457b9dff8f80eb00539a7336d2b681619eedf33a09e5f4f96ed3fe12c6e93a7e259386865e6bb8d0778ede5c08c95939e6958adc40eafd8189cfffb2c65f99f4c9344bd7b29e470f32c874fd102b3dccd6bcca3e9c191ba38e3d2c91a0801a2032907f7c2c920085ba8a71b7b9939a0961dc9f796c0187cdbd07919eee538f47a6bddc982cd49c4ffd129e76933de8e158f44e1353c704c26e42891897f58cc8b2349a67859289c30e9852c974c4030d398932ff5a1cda80abaabba6ce93ef20d8d8392d4a0a3e6c7121c9cc24190ab68dcc762df4015eef827acccf11f554ceb6594ac7c2cb6e51ec7c03c3e163b942a750bfc7f4f1539c33073c142f0b1be9a69965399411dd3f6c4df9f5d9912eb3ed09e1191e3093dc1496e88ecd03654e65bc1ecb14ed14a60ebbc913cef32bff7f8f063f43a242e4b3402afca766719d56fd5325b3f1788d49b7fa3742d5e3d1b0c8c7a1ad9ef0100035f7d10a50ae442e4d2d9c6c8417fdd3cb3919b9a2bed815238e33b1161a69aec9ca393a875fd823e8ce9221a276e2b6c13b3427167c99f768b31db70f8f56648071e73e257eaed4756bcf9ef34286b3661a23f93f41eaff6e00b6070257eb736ef34aca3e06002ff8ebfe27ef0f3d65411087707822f40139e3223cc1cad7af9dd21afc0a6632e0e87e838fc3c112a695e1634eccf67dea9e761fcb4c24f0a7ffdf576b1b1c1d5c6734a50b3621a1768330275714d8ee24e91dc05f7e6871fbf2a20b1a7346fbcffb614e251bfd8fef687dfff77d06dea4d1e09ef2fcdbeebe6ffd56f4f9c84ea71e97255f819a5ce34d406435f24d75a1e1f2454410768a5a780d6cda24647a5f968b418c5739aea413e21c8739680824e1cb4f2e23feb5c30abe397e0e0da979fe79918f4bbecee5ebde3df7ec169ff1001f6c8a8410eb5c146d2caa3d36e11c7ae20a651ff4c49999c0c76e19991ef4ebb247fe84970837c9fef1752cf4da64df791adee734ccd1703b1967cda82c63dac5979609062423bac67a1707e7dee077330c40e557b5dfedcc785a3621cc2fd423cce8928a314575b0e3c4765335e778be730f55decab94424099b482cfc29def59c8a7dd88d6799a77390c2fa3af9a6d7d60461a26be36525d32ea93333af46bcd989f50878685f61081e87d42ef12d8c8572eac67ec459d29fdcb1c19ce4429163f726b4d86de1cea274d0084dad4b33d7b1c09541fc568b5444593207912ee3023feffecf97234473aba21b7232e6a497f003be931e5542ab8932dbb9450515ce2daee75b64cdc541981cc18baf1dfeedb6d3c76b00d84f9aaefab307b02334e24f24124432ba8ca8d32b6a51e62bcdaf707689bf170571f2e647c8e020d5a7b0584127a37f91bd0577dee6cd8ce19ca30d65a629937811977d423b849c5be4b3871194d13d1c0030bffd4091944b0a488022c9de8898e1aef743643b1f9913d2c2ab610e470fc6bb314b7a80763ed6ee8f8a585721fb1405f6d0c6472c96c81ed766bd466729178dbd1808002445f9ada8057f9a205ff6d03c2abc99b34f9afec32d14342f6343a02656981d58fb747a3b75b15ad7eb40ddf5d366e548869d231f900e85fd774feafe173e23977d2211692c3a9b67112808758cb1c5a6003548a0d1dfca9781e5a9086e9c53be47ae49a18d2bd0ca12306c2ace63d73dc5b9c2948992d06b900df6206930ba312049a632877b351eb4d9846f5de4c543aea061be8bc207885324a38547e7f3d59349d1ec99162d72b78372230daf2a88bd5458272240a729c737d4da7e4779e26221f1b77df5a7cec0b8b205dbff86f71732eab9423b990f2900a7f1d7420bcc7ad82fed3c1b131fac61c6aff72897c9d01cbc8e3e298a00e480e129cc344a236a38bc6e2616df6abae7c1523bc294e4853441792d57728aa18e234c195082b140f8b73d751f18e209a04b2d246df6e50e78c19e752146d54174a780414bfcd8ac2722d1b642df67df3126720a5e47f9f3749f790db51967dd570d05a50559f8f2308532720ed24d2da0840cdf964b575daf006cb5ed43f0f4d53c03f0962c7ee926d6dc18308d79b6956489fa64f7ecf84e123eeecd35f91fe55b3d8a62828db98ac44a27d72186deeee284d268d951fb1a5413bba5d9885737b54b19fb039a29b2e493bd6177cb8b8b6cffb5d130b4c9653f1ee3046de38b05db5966be41298d0179713bd666bdc720a4892d6656f8abf3d8b0f072d070649f09080f687f63c1ed34b7384c3e6b0bf6c18807109f1cf2fa67f3bef9d16c1ea1c6bff3498f6492b1267170f56c789b957ae4561f3d123af3600beafe857d945e7c8433463dc1e965b03ae85109ce253d331dfa4e3332bbf5d443c29d1936e7fd37c0bf41226c40c0d4c3f8d923f16cb9c57db5f1ebdcefcade110f8b40406d8e4f63d89b86ef0a199d8e21b224d3394322833c95ce1c12c20c08dfe018b4c1e5dd42c29f953a1f6734af19240f4632d01bd12c897ab7af67a58e7f75430a8a4fe6ecab10b4e8bf556e4c82f1bbfbf875fb5986293f516c9fecc4cec5bc439ebfd7e16eb935f111e5eb20012fd5b9f0f9033421c1b6836560065d44084758f3bebf9a3db94e3922fd9a1e4d3fe7f334225864bb23f7b9a8597bc0e627669a8e7a748c09b83ee7b26b630eebf43485b984f6fd7865ce6359f7623d119bf6e645d34e58e2fc7dfc1c1d4baf8c543a57ead500ce6d6a38657585975d34cdd9bfea4ea6b2b46243545f914f8f08d8c1e1e15d3b0a6884813e0947ce2a3a53c628b9fe87e509a0150f32cbe9d2e8b056c2429538326e4bfb499ddc79dbc203f1fff4492d53b02eeb9320ef3195dd7994e1f8c1f293c23a76a3fb13fce83dab58ec091e667b16cc1c557abfba1adbc852abdb1960476099d3b01adadcb883c1023492aae49404338730b75e4834e12c3a3573219da09d93a296ae4f6b7f5b127dcd245cf2549c714a24ba6f411373e1ed0be7516296514a96c6ee3c3ef0a4de11b38ba7c6cf9af282cc9c45b69803e45252a35c5c4cc950bdb4b1764a371a103a0454c7d43a1f60a2ae90b246f9023a2b642382bed9b0c17342974c85778f0fc67fe577bf8d1f944fb70d7fdbc589547c5ca4221772a83e7636c87e29b9445d1186e9b8ad585f1df53b2c92f788251689fe36e5564806ee450c36f1280720d6147c027f2fcc715ebc7ddacd1a016730b03f637d519b31a17d691d0470eae8bd36f944f21317e1bd2cf1c27a8b00bd7b9040b88341dcab28c085564b7a37b6f9e9faa9416db9d1e45f25056c49b8f81520f0382ba1ff8b564f2b0163221e13b54bbdb745c8081cbf9d5a6d94961862696e973f84a009a309e5b6c4dde339dca1df35a2d7d09273e32b59fab9863c03685cbd98454817f395cb899b8e4a0650990d3bd7585807853f12c26e50e1d04168efe08843b49fe8331c15fcb0b7df197be691182aab05bd0de73f9b45fe874654213e93079b68b5515a7db956066df092ecbdb50856aa976e3434e7e0c6f93b478202574555744ad7a67412f8205e6fb1fa7001d2b8a78fdfd01455303b797b450d895829a4d5a2ba62b02a1699a8853e8ceff64576084917b0b9bd90a708d8c22a469a245c03c9c4e8b4d608535eec1c0a8d28c9d379f8908c7a87c2e3792c55a697ceaa1530f66e05aacb55abd2c5e8c4ece658bcbc22a63e6378c3b129887dca929ae39155d9d2a9085ecd049f5514f8eaee2a50215fd10ad34070b4698b316dc88a65f651acaa023288aaf4644f456c886a896ad93a369334ca22e6370f1ed929d48417e0aad3612bc022e0ffb52a21d1fde6602e1f59da088ee4558519551150a59fb4baa4c05bc67222bea465a8cda8e81f897d27dd35dc091c96972e69f0e0744932bfa36816796d83262378ba47ceb4e25915c68eb21d1d56840d6fccc3c681035d0a16d31e1581e10ac338f0db408aa5b29fd4b0ad1b31536c5a0995a976bb165d6ac0f90be033ba95716b36a7482315a9cc79e97827b1abc28dd232c2156f70c4d1a3f1e7b18b5ed02ebffaf7073bb015020725a9e26fd291d43a3a18f2800f2e61b1f38e9b76f9f062a093674dc951eea14732d2d2ac93fe0ebbf79f5882a7aca7ba57e0290a1ff0a15c5a1cacaa78d6b2a56bae3b79a1becf7f837d8e4cf9ab559e08fd3c8ec1f34e48ff4376525defefbf46a85f2325c913adedc433e2e7a4078bc5e2fe9d90b6f62f781a914127744444b7ba0bd67e38b03f38eb4c50fd659e75f6c0983368ffece99a2392fc42e23e8f3b173d7922ef3c1eace06bb8748c0aa13adfc19b2953e196aab2b7834dfdd04f0520c03550bcf6df4ff5bdfb7ce30adbb27adfa0ccd0e1d6895745a21682d5fbe0ad39f5689ececa7d1bdfc8c1b1adb9286a6f0e9793671841244b76e723e94216e9a4ee6f8d2f42843eadcddf36912504bde40e683a38cbf970af2d4183f1c78f49d92b364324dc35b0c75c8cc00bcd02b8f818ec91e1f89df735f933e4ff81fd7c2cdbafdbdfefcb6d2467b0b5910aaa84a051780cbddf3d5fd52910d31be47256e5be39e40fbac5965af40d199210a9f1b7e81ce6c47a4f3b6427ded880db6007a2bedcf66b1ba6a7710dfcd079f5176a00fccc25b12c2a66c371a271710c3dc70cef254c0c341daccc062dc7800570be1c12b082bd63d4c1f2ad7cdb1f08b5a30e1b8973ff18040cbf1320f0d0e95b564fcc94dd68d97a455e464e69c1062b85679623266e3183c94e06eabfc4332d634e727a0038e59109ba347ddee28c068d74134992420d2caacc2c1bb8cf0d8f14dcf8c930d851b08ef59fd13e3ca3c2466cd912a0091d2bceae98f102f065a8566b5068b2b1f5da2edc7406d58ef240f780b45448d432d8c780d68f6d3e0b11a2c07fd6859804c8e28ad5342c666102510082c025e0238991920be52b21a3356aca954bd6eb9e39318701395325c5930271206a7b6871de2a5c37037e45e07ad5c55624f14416063c160012a0817da1134829299e3e370e3181a17c6054ffc56ccf902c36a8dae8d5c0fb6e9ce87d395963012805995e43275268ea440accf2617620e7f14573de637b27ecfd117cc1e1541bc859cbab0158238c5b54da9561aaba7d1875a62264b7650de83b32e588c3f0d0716acb3a1ce6e6cae2a080bbbd4b3e5b3609234c41de6681ccf7f04eef61c9030cb22f65473feb7fc878a5f7fd83475dd2f4b3ed77815ac595867cdcf9a9060b71672024ae3609cadd62d5cdc24483325c58e1ad90f42f012adeb74eacdc1e8021c7470fbf122618bad4c88876ecabe808d531a85de449a8271581be4de728f73f02db9adc53e64d674b90ad61994a4dc4eb16d5e3eb8c20e997247413a366156a7a4edafe662c3c3c0801fca05799c4f878301ab0e9c9fa6cd40b3e092b26788189c625e59e2f69273501502c1a886cb454180812a93f269addf13657a67e282b59e06c27a0618c129497386c99379edd48c6b8a8a8ffbe982ed66f201184e1fa0d8141168211ef4568c4c4720404c893fffe02f92879edc8ceca3bcc7fb6bd62cc4368fd2aeeee7f88f248694e8e7afc4a5c0f5bf8d61625ed227a1b1a0b9e9358b1dcf92f2138fd483127ea5046888b389201555cee98439f08df19745a69e9792057a21b1f4e75e447569916d1301505644f0a8510e970fcf3427cf22ce6f28471d88cd6bce768ca7f4d0d449316b9581221ba501aa5d9fb58fe4d84bb068c8f5f20af2e6fe3c0a3046199a5ec2ef5d6486d7355a76cb5f8790b3415c0931ca7b32ca065e36174280a6ce2ddc919951a7464ac6a4db61ff61de1f8e6c89eb23ded61bf7ddcd32a4fc7db45d0d9891684cb414f759961ad5a41ad3bb14186261fced6feda0479b05bd99a78d639a3066df1f5b08dbeb0c9c27da8f7744e3d98b9d4082b17b10a5f0593119e0cc63c3cb48e253636ee70b3a84faf0876ef0b387670e641b5fd2577fe838c920e2e9b9cb98ac698c832c9fd54f5fef3fff77c06c41cd73346751d4a7c70fe5a4e41a05cbf9bf8fa4edebe16a52c4c11b2416d30537691bfeac03b28c85341cff57c7fdb21bb1858d14aea4e4a0ebd69f1df88770e2dcfa40450ecf8fa3951eebbfec871d043295c0173ce751af4e0650e9842a69f58b0a1a0a1e795cace27e05a821cf4dcef531d31d0ad20f14c75352f6c4e1af3d57ad52fd4f57d52992e2ca6bedf1a7d7a8e97ce59fccfc40976264c844f881b0cfa9c107f351ef2968e53f8c84ec5db6e40adce48a63ea09bcdced80cdd57427f643e15e8f862bb02adf726031fa2653ddfa1a30f9af08abff25da4b45bb8a122dd3cde29cdbe1f6b0c24b32a94fe483420c91e8c130fffcef401fe8f9ef0451036638f6650a337da5bf11d1237f8216be2b09f3c233672c1f87a57ee27fbccd3e828b72172c5f2872dc487665538c96e1dd72ff394598f69e5896dd3b81946ccbd295032d9815f83a0d026cab3c541a1594bdd3e7818b743047817e7dc11d50b0d01751be0525324fe270d7e917acb042f3a35ccdcf27b9497a9a4218908c3ba264e88b02cd43e6b8938f3c13f03b02047125f5f327d0c6e2125eef895aa3d7e66013556a4c56cf3494f20a5a6160048de5ff8e33f605367c062c23f17ce7f489e6d517ece617e1883cac7730f69baba2760b71484a2723a5cf6aedbe68a33ddc3ef7791279d16b785e094d6ffbedb998f54fc060699a373c7dedaeccbaff5c696ee854b6556e04505bfa761079b2c0cad0ab2cafbac49774a7050348adce7584e07df446ee95aa46ef26a6138641b099895f97c90120d3320d098259e62c2ece5025322272071f92a95161fccba3b73d18f0485d3ac91bec90df3b30dbfa6410bf50aa7e74364bc4f71797cfbc681886eaa0621159c0707262a705c8f42cbbd165fe83d4aa3ef8686dc3a603e7c4d192587fa809a7c19cedf30cb51ee58875b508918bc411dc98ff163c9d7ab2f12403f440f876fc5d14ae2cb624a2e7f11c15fa9f49105af3694bc88fe1b3e49997df81e58fb997d339fbbad324e626a583282279cdb5daf409bbeccbc080f91cfb4c576722fed3bf574d918f7846d857245fc73457e6532a1cf991f0c9a41429c3cd33696396a092f4f5aa84ee710d89e9020cc064c670ec4186b427f2c1e6cb6555d4822578236e48d70ac0ac04ef7bdd330ace409a38843ea2e4ace31979df7eba9fc74c35c149c7c6a88b357b92c1b75d59d512013741b45969c54bfefb89f7cff1c35d858f0f1c2a2519b46e33937f56263f6b9ea349760dadf7993966e557cde75b29ee0cfba9d3d7bdc41aa9cf9541695808b3c7833d3aab16352fd8b749e9bd5c457edbac0f92d4cf71a8d96b47682a78edaa0d467ebb9f355e6ba5e65f9c7ae668e30b29dd089ded68f6b2df10fbbe472617596fdda6c8e00e664348a25d8ae7cc4af4c7fb7ff7368f3b1ec0cce33201ad74a300c39067802f3a7669db71d875bc3afe73d429f74eb2cde3d2029fc82e867610dcb487ad1df03d3a876e38c496bed99c4bfb9eb321ee7ca7c8590839b66fc3a4ec78c335bd79153afc23b0a0978f052beb25d714aa11caacf44d80d0b8b97741b5bb84406b7a69c8d57acb06f0f064f9aecc4de8a2c2b95f1d8b8b508e9da3ef637028582f5baa7411be43cd8b143887693c4d2b0c7ca28b3efbf27bcbdcf19be83a27921ad519a6e411e9970957d04374d9d60f8f65774d1a760a9c1eef61ae07a425e66ca735c7cd0ba663982e23600c8f8e287586cd41f1a886d5c21b03a283976332da9781a3ff87885cd539b0077701406a6d62e6515da9e2a048491f05c48a49f0d0436c6a10b36708bcfe0e2df91f851d7343b05ead9dcceefab81dc74432b84687ffcade5b3a5d3ba8744fa58d2fdcb4a366191ad292ae840b9a71855db2c1c3fc2a88ca0cffbcf11cc12ff71192b37b5ac15cb02a1b8247516c52ec9e7e1a0bb82aea480619518057c8ac85799c60c7ac8fd8ec3eb611a467c273ecd9108a56d6029db0420107618de084edc93d09c83b6232f5434949898ae9f826433eb3fbbed52b1509bb48cc084c5acad143b0d62c03953bb0f0a17b7e5f7e7c63e538cb505172b98fff2e166ceb5fcc525a9866879c87dae3be5ab65e3d8d5779da23cabe64ccdeec47d382475412552e0541d460bb19a65a2356f27acc394d441341416ffbf8572018183ac46cd1280022115bb1d51b776c61e005559738821c67226b73beccbdd4b6ef9eaa10df43f76d1d4489c59eac32c2c6977ef2157f84ff7a1d719fb681090cac6702e9d914d36aa8d6b5f0cd2e6378bd83d943bbe8376575b3cd78a7ff63b4424e9a1f7ae415048ecb6202aeb020011108fbebde7cf001c03300ca0135a56044f35a84502ad4e68082de90e6006ef0f5e8f0d1e6480d4025696375cc8dc4e9fed3799e21edd5138d627152ccf01e411dca1f8a83deac5df4ae736aedeb315b8cff43add3ebc97408300ef9c59d20277f77a5b023b79f6979c1f13f8090f613de7b6869cf0366d9cc7fa621b1ea57a83fd090ef76c3daea76c43dea3c9f91b78f84da99882f6db30dc984856055eabcc486a2a92919bf9c9e261a2ae020f53d35c8397e8b5d7fc5d3534f5aa68ce4de91dc068d8fee3898c95bf568b4eb06445d9e806805570ddf189d08211827e90559cb7d4d2dd2b9ed79a2363cc42c151f3077a339b3e2b5512316f6f3e4a30921af1d37ef4c42e1b9888b700fba6ebd4c7483dcbd6ff67fd50fecce49f1158149a069dbf459618efb2d401fa8109bc8a305dae68341ecd47146d2345df8f70dade6e8ac94f78d7b746e660a1f93fc6bd68b288970c507fec3cf080a66f8b7e45ce19bb579a6cd4ecbf97976770074c45be6f7b3c9fd32caff7bca21d921ea418cf19fecfd45d2ec28f8dd8bf4a4485e4e16f07635cc1ff84a0a0baf69aff2f6df0e27aaa28e13add852b72f69979171b47ecc62669807c24689ef34caa5e960c56b802be3338cd6f81b781918f17d670d4ed66358fcc0bf4341f8ac9327f340e67e400886ef9ba03330546d586b71068bcd17241d7270886caecdd8db48b953c1a2a9d4e25bc696684801413a57993883018f478c4838160f4b193bbb62b401cc4f9b35e8388aace39f82be8a9cd704033a7c68c657bb1034802ec60969e1c3f11963c37473c68a6eff74dbddb4e5bcd8bcd8b00f8b0f0e4b8feacbcf7b51bc5ab13675e636dfaacd39606b38f1c24cae8765a027b26dd44da7ef872c20bd0d36e8559f372c6dce3ad666c805258f92336b79cbd96340710e6b1916d0f391804c9846b8860eace1a39cde73784533ccddc1be5700c608f21165eff24fcafe7069f08fdaa371fa84508bc1ce1d89c1c2beeed807e77603e7716dd0cc9824d07c00c829d82eb0da413666f2e1b0eca2ec4ae1a36c2dc6672f0b2ef442e5c0b18ffaa917fdc17d56ceb3512cca352d659dbf9b8629d292cc1a7a630c2648b0998e1b3c3b9bc169a521a614138d89f579f4e7c2714a4f57f57e38730707ef9516f753130d44403af3a277cf413dc3f762aeadb0c918fb1896acfb4c189cec9c36b4671d8803c5be4f1cc12d1c6983e95d8f10509c1f9a61b491ae689195987e856931eb384db3e9688029d3229f7fdb2f27e092a098805cb6e1a2323a63ff6c58f370fbcaac70a1daaadde1c5bc1eb3feb0fd6e68e44fa0280a9897cda9798235bc188622bddeaa401af18f60e2e9525250db8c7e56dc54cf00f4abdbb9a71e00cec93505a1285fdbbc5187567f5acfd81e5cf8173532db56da124a29938b7a60aff8fed7f4bdff67148cb38c6ce416e21c36d0398a1455cd037f537fcae49fa79de829905732728bb1ce510cefc1cd6cb389fb3e35627ad3767e89c03bd2ab8da14c69f08d76e7ce7bb97d941dfdef5061746b857d9993f835f9e96075ef911d65d05cd3cd09419c0f2efb7d9f05ee94528b1cf6006f30158e70a751bac1fc0e9c60c03c231ca8f8f24e438d3a3f3e2b39e6795a452b6d870c0b1f114ed9f5c61c267c4a377600b301b50cd29d29c585b386f9f7439b375e6876d44814710c1e2961aea3e2d23f6bee6077d02b6494e67003cde03953666a98f259340f20c7bbda9d183eca7e0eccba974474b59f00fda4dc586bdf7c3f330fa1a60464adcf296a057e58d090a406253483762ffc07996fb9ac58672030d46deea411067d60afa0aa30082949d64497def516a58d0e490c5cbc86f11d3042938f47f85cbc7ab6fbdffb418fef709f5e52a25cd0ebc5552b1ee1fbc81d0dc764b3f87d06b02e49043395e7ce3fd95393038f3334b41dc55e0ccd7cbcd4d9af5932f58ca0c3ef9d34a670956596bfc06fa066b0a1f2514c4d2f8c228a17c7ae2001c967b200d1ad2dd1f96cffa2edd21836bb2d4a7effba7c99557e14e589f79d6679eca9682f1ad1d2a502b85e6a682f3baaf030bc79814dd5cfb23a65a6cf76895f992fbd935f4d3832a668799d9c55ff087c8f07cb4faa8446f164ba5868164d647f95818287bc120077f3704d6a92257ab6947f809c13bf407ea1f26423f41dd980630610e391b6463c8076c1474e267688f1dd068b5a8563bf7b465d39d8ec1ff8f3a04e0ffdb4fe1612ade3cf00abd10010af1570a6c690eefbfaf256ee7fe32d5c6489f9796bdc46ef0d5cbe7728e204a234d273060f61c74b0219cbe5f3d8da244412230276db2585e4839d71f58c2d0ae270c02b9503a1ddd54aded0afb711f866c0f46a4e62f184104eafa95e47872f3b482b3d35beb1f62fb1a83d35440b05395d0bed173b63fbe4b554f8ae7dedfaf9b0c4a415520446e8a6d93b55ec9c418a45dcc9ac5850b2105d813b8cb335e6419e2b2e1b70cb20c928cafe61c73da6d28ac82316c43db0cb004c52a833b51e6fac2a23c4f88ec53fbe0a4ad71e6e6729aad5070fdc393ed6058b627b4b42f407c07ecf72ab91c237b6345136849661a57ae89b3ca933c68dcb8c5bd0a549ed900c49c0086bd60c3ab7f5379ff5df1148f98e64ae1ad1c24cf0e6fae5ffd9eb852a718df05ee56dac13c675092d7c664d98641c83d45c39c913f9b063670b5dcc9c5adda2103bca43e3b2e36db3d3034056e672c5fd5325e193acd69dc82c58b366769484d6fc2efefa31733418de6b12c725d15277a975623540f84d409405441ceb02a3f84108e8b17712871e22c16243300b42462384f391027f3e03955f4cfd2dcdbad39464a647a90755dcca10644858434f2a12fba3855200a6d8ddee54fe960e70195f3b20f5107e4a1be91eb88f996167dc6e232031b7bcbc85aea537d5907c2c2ac0fb13037b96baae283f6e3577dec72e23adf2de724ac59f52d44ecddc1b6fdac900cfa7528c8371e88296364d2a02c585638f1c759d942493072717e875bd3accd7c5b431045a9ea9900b9db2f06d2a04bda0088f73817ed04b7be29370439d2da35708e2898bc5d1e8434a8b4b012d971087269393e6fd0945ba1ebcd4c687c8ca50eed0767707f7c8b979ec26d2eb1f05620381cc40c537248f49b2785f133cb86d397b8257640dffc276e9462cfd1dd4233f7a95cf01293460543bbb6342ae6c798b95c94838a0bf01ea961453bb899edb63f59e6aaccaadcd2bc98bc9fb30166786921e809f45be7fdded8f031efaf70caa77b06b6882868ae0474c4ffdf190f3b364e3ac4a6fd9f9c1bc2274bd7232c10e004bc03247390412130923c92e5c3dbbd13cd8f8d4598ea616448e8dd4f8195027c241ad34a23ce720e740fd702af0cab783832304b91f2c2ddd14d68cb07c56eb1384768cdf40fc68b55a8eda7e4c05d89475419402b1c3faa212fcb3dcaf9705f55717b88629d5bc7dc7ec3b4b82a734fb62eae974ea7ec1e939372d3fd6843bf3ae60c6fddcc7953a769f7c28766dd1a9039caa2b6fbc75d40b75d87c5c1fb91bbdb8db5000978ce03f7c78aea767600cdc74ea6ae8bb8899979a6b513ef5add17b2c4aef417bf8ef80527fb0cccfd8173f562c66603f99857a2d572bf5b38b7615900ff334b8c9f717c05a30a041b31bfacb9008957f44679bdf2e8de7a12c28739e0114fd40ba21db041860f5686f40a2817b86984f6095d4c63e513550fe0610ea3be5880c43d8c48740ec34b0389a0aa9507f10c7c5640a1e85c852ee202a3dc9546ea9531e90b25c14e3e0b16709497e9ecf5888ca573b30f9f4e5a4f4405fd47fd3a6cfe3410ce724d1baf3117a5b6c8ccee50aa282b8e1b745dfa940e07fc8a8af4d2107f3d808309822774a502a8c774d0ae71b19a077bd704211756babcda608e0d080da536d642428221ed66d949b4d390b44eecb73a7ddb30c66a11f7717f70800fbd11bda5db75cffd68c001d2e7b14fcbae6475142fb33ed76a699ae0c5c2ae54f8c2b25a125d1936e9d707b0c24dfbd62579750d0d1d3c0a92c991892c88caf91ee918e458fb27e1e2fe6b462c873d84e37983fb810cd76204e8d328759a1327456b38336c22e0f34b468807ca5fc79946337fafcb87b06ae8dd93f44bd37771d3eb805d997e9e66cffad20ec9390d31c7d9335c652fb9c195d8f7708b7d3c0f394f828e25f5a653f6ef00d3eac410f65523a9448c30b9f7c8a7752a078ea248be98036769a119fc97909180385d6dd0b431add4d463816ffbc5b72cc680d2b859491499cc680474ad490b7e030ad92e20bfa2003d6f2e5614304cbd4acff73a3565a6afc5e832f9c654a53c645eb08a7ef13a635d5402fc780ac0dc541f1c593a3ce01e5b09cf93d664215400d3fa3f153c44f47e50ef988c73b4abde12e46d3b7b9197b6353204f19d91a309444a528c9937361dbf0f4df64a1e2fbd65ee327cdf5a9bec94996d30700aa5ffb25d664569f736d85cedff8d52c01f623a3f08b6160a3c6ae77734a1a098aee24e2741c28e010788f0042dec0653dadf42e945ae4ad1a18a5b44eb0335deaab18c19d04060dc417ce632aec07f8c665d8c7f40cb0398b2ad685483051c50fd7c580003130af0f687528f83cad622f55ee82d20de0f0121d0eef55d3cf194d91c074fce47e1e9395e4741021b2218996ac9ff71d463a0f083d3a013d61fcc7eb3efb5f915caf4e7af380fa968448f2f00841d904ef2422db4794771c33aae3105f6c9c4176480313f6083cc9357d424af6e74cc213b8186314a3c6020ad52a825ce16027342e446f59e58c7055633d468e1c6d4d578af479390d9c4bb7707ff4cefe279125a3613fed160f8dcff7aa44776fcc6d3323e38842910ea3497af7e54884712f4fecdc356f63752ecb27aa6be4a6ec6380a2e659be18d4f68d4d9fed9e5a8789413c52171b4512be72c62b9d7ecffce452a63ce3dbb6ffe7274b4ac0732cd900e281cdcd95b5410f126a3f6b0bf1fac1661da073b5d55c5423b6f855ff562ce88c0e48b523dcae35f47ec573b5f4d9a168bd469eb9c5eacf9f6b05743ffc6d643082cccf52cc3a94a793a844fe40da8a768c240b82f78310b1a03c5bbf230ffe3646378690d4687e4f30fc06f5310a1027e570be311b8669987c9257ef5eb7e7bc6850fe0295315275e6a37aafa8b1e2e5f93dfb46dd10b43f4bbf9141b116275f01556668f6c3000d3456f49cec0d7fe65a1e113d5893f0848b0da91b3f1208608d0452362081c5dce062d3e7c303b0b40b26c67c1a64304e8e56e1b921f7557650bad38e59faa5c9d741ae8e1fbf504c067f8b1a4071169c77a23e610dee5d87e52e3f7f2cdc9889b928ef06e4e2a78a1785ce1c3d4fae09febdec70c1fde4bc45c1530a4d106cf83b7c7b31d8b7e1f318520ffab2d78b3a68d7f0d28721c373606be86b8ed81b8e7b0dc0b3d5e51bd3b9a10f1947e31ce1514c95753893f7dff997e8f1087993118763012ee3fbca81edb1d72c413a856f65eb13d7613b2be67efd60bee9022b52cbef3bfcfa3539c987d7232770f142df7bfc557b977dfc157cc3be421948cbd6c91fbff204404172481d9d8837f127e7b7da2eda72fb9fbc224b3f841aa948e2d07989b3035c12451be793239f192bd7718137cf4a065c5e3603687393704326dd4abce59986f9c74c59aa6524f6fb490549e8e9e9dec42894d4e5d7ec5de75a538d320461be86979a201264f33f251c39ed65ffa74c57f7bdc803f0fd7b09250c61be7796b41c5e17231fdd706fc5adab8eaca494cc5f06b205c105ea8fe923273db5bbdfea62c3babffe72e5f49b7939be7a9910c55c8e32dc7987ceaad2c40001d5d458728e6a3d676a4aef296d7c3c255ed79a7e56ac50e9c0a376210be388a8676e121a7bb7da61d5ef0c6fab88afed2bf02e33854c43e8f14f1b7811021777bef2cd3f5d965979040b6e09d9fe5501c1612892933f30d23d529de17ff9d4b4718b645eae623f96833ed5452c8ed039a50779bcc665439e7db8f59fbd1325b36fa741d0079c431c1c1db25530e8cba3a7ce0e1bf48776260e1425014cf9a86ae30fe6c5a3fd0144817d8066da3b393514d49d025afca0c356f3e2bebbf8599632b4df74e8e8c52350edc41cd72687ef939269764f6c45a45a3fdd73483778f22053a1d9fd82fcf549d308a201d8dd126347e405a63851cf5554dd6459b412b3e0abd19f9fc9bb42614f1ef7d328e919991d3dcbc8c62bf7971ac9c82ee101a7eaec4e40398b264f35109cab8514d18ec1add6e04f127ecbdb0e8f34014ea340b18302538d95b8a95566678bdfd03213b0138676c67693367012f0b520bb3113645b62502929a944445cb53b08d1915a850e0b18a2d05679cc5c2c80e6274b638d80bee3f1c67572ac9d4b3e6c6ea95606d4c3bb83ba1e4945c240f5a1913ec683e8e9cb4209e3108ebe46ad5b055274bba1752fc606c2bac2b0c6128ca910499571d3a0b6e4800e42404b5d8ce49128d14f5d402f7a25bf298bd6ded4f8cc1d17bbae658bb05a8b69d3fabc7ccf20e173e5b5fe41d3b55dee8ddccb15e65b40126fe786f84eb4b036acfb74311f884548179b0d88dd246306ee42df5ea5913dbac269594b8fe1a0d8f0c4a39cc402846ce941393a7e4e45b0e2173dc1495cbea2913c46467068f06516dafbc78653be054e8d772793582e80e5573e00339041e4788185530b4fa7747d1b236c25581ab3462a235f4c7ada43f5c032e1d63651a3c81bb45f3c7fdf2311e56fd6f2b2f5eba59daf453d338ef5024141ea92b94ae2e79043088880a099a45209e52dd812415c90debe3f1eaa2a3ee8accfd405b0c06c7057ac396f2f92381b338893405fd2b4be98a37a1a9d89c5df54c54e3e049c2b1f8a42af8a58f0cbc272d887e89816b21fbaf5898b8e2dddc58f0974c68f3248ed9f7bd30b566b478d5a96f127eee13c13b787673953e0713a76005fcaf35ea7d3da343da225496a3634f65c6b6a4c8b8a393c9425af20fed69df27f6650ceb5040cff7d997c3d7e722792722472af730b8f55791ee78de29414a1deeea4462be62f9022771d1c61d30739f6db1bd0ef78f0aba2db2131d4714f7f1760a5193b1ea823aba146ebbd1f88d43f90471e5278526966f79bf03a676a11839f4a83cd80eee6c2604723eeb1b4d4b95538c6fa0067993d4bf8d0e6168c414112698bd7b3a35ec98144f245a99aa827d9121c92745ed7ae8b61475f5dcf69bd21ca4bc90c0038b53d5d2bcac6dc8225a182c671c7a3efec9b7e1387aa14f56bc9561feb09a804797f08a42dee6dbb652e90878330701cab614b1efecc9a69204ab859be2826aacd9a27d579634ab888333cfd319354c7f58c6856b583c536a5f09638506b864146241246f2dcc884cb61fe0463229d78f6f0af3857d09c022a59f30b4beeaecccc0bff4f6663a0e48d7dedcc8ead42ec383557f91d86f1e08b3d42fe10605b22e0c7280c69c4ae670eb61c3cc5e7f6f15c5f9f03a07a71ae2511c7cbe54675926f6b96c06b1f8aed70724122b720203d6b18c6af7442ac29f87d33b666743521c1bf3fd36b5d0ff730aea22e5d664280116832f8e16fd4096f24ff6624571cce426066098d5af78d06da04050bca5b4a060faa42e0bd156557f1600ad9978f52c3cd8e4a879910e7c320b971e61b755a2b930f2f150d9f548377769808a5afee0b2051a677b8b0d4d0daec9bbb78cdbc4d623bee1e224585077c7eeb458aceb118ce1bd49e43c2c578c11e2d0c6421f57380d496442893077cc7f0db3b5421d784c86c45f4ade46ff8a008467e4681126f6e4c912778e0d10f9b7dc4bbc4bbe4a0674b1dd0fc83705171cbd12a9f6467806d10a03b7c887c943237333891c99b03d6eeb0466d608ddc9ba7792cfcdf5062f06be7b6191a6572e1a8195aa1bea7abb550969534f05b369a4e882898b79accf58443d5e62c476898c2dcb768f4f348d6cb36b9aacef65658d2aa0a1297b734990108d0ff144c06ea1e9d3a7a79ed58fa3e1745da88a00b4adf3da41ed247e8d61dd98dff68352a157fae7efa20c175eec2344b088a00e030cd14225b4a4c4fee992c1fa7c64647977ae93e2474945178c9765a649f8f8549305e0196068661061032a37093f304c80e11d44eff503e3473bb1ced4d820253f109972ea4794bd0c6bc76410c1be9429d62d360b8ca2b525bb573c591988ca65452ba3b249a03c7d5199ebcc3ba3f79f0306841bdccc34623b5ec71737d06ae1ad642ec13ee393f4741a33a667dab704be3c037fd20a512b11862a897a33813738693e7920a2484f0294ec43eeda8812b5af0b4418387c53144cdc4d9198b803e933dbf23f6355e9d372589108e12f4e6c3c32155469f5eb601fe8537a67dbff3b3a24155ec66c103aa2979cd852421ecd6da2468c03729fe06b587d949835d7a8d5020d62144657cbe1e8db1162206f1790d898a8946f5535820074afc2ae6d3e81c7c7de63ab55ce460c56c2fd3bd29a366f3979e4c6c1910e9d9c9e4931240f6e8873a63c786aea91d678cd96e2d2400d72dab983c2da1170bdeda68bd359dc2f098479a449a62ac3799fdfc188afd96f8cb74f4edc6ee227c0152dae700c436082842c265fdbe48dd5d43f0e99e8b0ac4c6ac640ff3b931a5db2705a3a1f4ba6efb1a15c649eac8230930abae799eb8e2044df54f474a6165c47953d5e9a0dbdec4aba69671f15c776902794dc8557fa7513a33751b3dfb4499342edea0e97d422d196afac73e35e03dc38e2652961dc4dd1d46273574ca5c4b3d00f5b4c71ff7471e4626673f8cb59a27b9c6c8292c5606f7333a539b7eeca3a7ef2a938220315bfa5bb8f5b882723fb7ccfc19250b8391d431f4d1778dadfa3666e65db2bc5deae4a2e02e28f07aad2764d272efe0a6fdc3c0a3cf3808810eeffb207bbac00b5c0870a07283065e6fbdffd7f7fae1ef12cc9fc1eabbef49f286c28cb2cbb3025e866de0448b8454b7e744648750ca065e95579cc1ba156891bd3cd3e8059d2b861f9485e25c186263956337ce10619aaf48aec5e20a5a43524d1971b6200718c18f9a73b25e56ef73f3fceeaea66a0d3c22260f4886714feea12b51e23995dbdde924e184f8d5544a613e2bf43b1ee263a594f70ca88b33059a1d04df485e573b6f37bce6f62adae609afba7c489b67436e5cf91b6936cfe350441439e074e6a7acb27fcf33bb7bece54650d601d3f3f7fe6637504e5ea989001eeede4d6bb988ae749aebab31a933df7bcf6fe32f450b11b76813c2785ca84399329697a06aba3a4d5c69ce27d3985ed318e51908dec231aa343afca754caa305b714f8df450381e2e9ef5d8a11329228775d7cfa59c5b065f36fb4cbad2c0e7282e0db0891ff35367f512b39308b5d25f4804487e40dd9a00cfd71d9c3bccd5597287ec39405dead1d50d6904ee96629b0a3756f30af27d9ecaa8c937f99a1d70391834e10317d8e00e6cc09b4a253eca8fe42e68e1098d4ec9eca411e015aff630791ba73035858b2d043246f0139fe535fb1baf51180d553939dcc56ff930e39c2bcf6abe5ed7cb15b4c6a13fc95b0475ce69896fe20c6ad987d89e5562804f1abb452f2d9dcd16b5b7a87eaf54411ee2c48058d08073a67b21a935840adaf02496c1ca2c3b618c2432f4ae1bbd3e66b47a516281cba014abd6f58cdb590238beb88544b8c21c8b6b6a0cbccb34715fc85cda581604ac8822a1ed680ba9a5f922850f12b2a6e51ec2da7d557e14d729322db62739129624d114ea15c16027bd9248cd706d73b984cc59be405b25677b91f60d61c3aab7867078390c6a0c7165e6cf1cae47f9a68046ec85d10748fe4cacc3662f60397e856042c68f391de94d02cf0b62b2af4eff67bcef61dbfe0b62f061dfaf74ac383ac6713b4c1657abcdf52467fc4bb1b8bfdc25af84f6286864e1f695fc433d2d40d7adf5fe5f55572304c16a20eac4aa45ed8dc1410f65464b82d20b8587e0eb023324cc7709cd39bfef1f9458ce0a4127fb441ae3a7dcadb5c41e834e2c50b49297bab7df75aa39a17ae37d7441915c82783ad0d8fed51ff672f2c54e77b0da6200ed46cd4bf377248a505066426a17eac38ccafbbd40603a88e4a48bc596858dca7631d4aaa02fcc964f60c46a72e9a9f649e90926a4738292fd77f27696de0eece6ea6e89075843613fd5c5d2a413795c6b646eb9ad866303c9e953a89712ec529a41abd9d105cb0e77fd951a7257d5f668546204b2f128799dc7e662c73138deda8e5dc53358a67044e256092a5445f23be2e7c9dfd856439861cdbfc25c1993d861cc0aa05a2bd1e1a924407d85fbdac9d6eab266aa4082a751bcab26887d146e5ed381fae7f7cea4eef8c619138d470dc2c6faff92a762bc1d3465f041e1ff32e1611b303b2f4e49ebdb04744f8c96793e69ae0d27a915a4d966e7977d33af21b425132ad6743f6657d4cd6a786a7b902bfa01c038af536dbb3b7f0e5dd210b29b3b0d3364d57446d131de5510c0fad9987c8d6e0e1d81ed2a46128d778eca411b49539eb548024a13e7477d9a6f1a6cc3dd879f3cb2c89211594b0645fab966b05188b2d34a5319682b1dfe544a9453dbf4d31f6cdf9c4c2ecc27ffadba746cc892f7d2d2080ed858629abce0ef50d4771b8570b79ac764a3ba03b81436a25f4ff4a9b8bc928855c63fed5cd8679a68268751cddfd823cb78f65d74373b2a70334760bee2748c3d55a0a683e00f7f263924afb67dad80156710d28527310609baccd156f6c99629ebd3006aa8559f63448908188386caf629a05306aad3a0fdfc5135858413a3b296a1f1a75a70e1873618bb23f639d267a00c0363046d1d0f6391499d4d8f03503c4debc0e6225a40f20747ce70d8f2b00ce6cb04bec57233433ac958a570759f7c43842bd0c8ba9fa4e798d373331108f074f319f2b5f2771cea7907e9b5a8d4469b9f8966c2b803b47f080fcb5318abe4a0050d08941f0fbf5e0a20ca4cf4731f7263a1a8b7ed32281303242694f007e9846c5fb368421272e06a4af0da5c452f21f9c10acff627e0f106cf1328030aee69789010b87f1db4796e57f69118c9e062d80ad3f06d65c1b6729f6eef17017521956af10e77d6cd26985e5c00ddd29db6cafbb6669199dafb158af4e34b1a46736994323c3e2c09ae7f9340f955494e2758e5e1098967b15cbd9f46058f3ada060ee40d7191ff0930371c6c8d9fa95d593f07f1c5fe1612cb11d00d4b26d343b5fc63548d41007f961f1434dcbb0b6b9562e67deb7b13e40cfe5f2df99c26f7ea7882cf71bbd092c9022231e52feca39781e50e03c8e08e760ff9d9a8efd41f82637e7f93dcf41ffaa7276dc09a91f4ff23c0fe2c1ed4bb5b387ec18809fe5908b283064db48a392f60e03b7eea7f0e12a6dcb5c38689a8b24fcb7eea8407b8aa97afd455cc1a4b9ddfd30dde064cf35ccfef77e8034d494847b305d9598337baf0a386c909e182e67f75bc9f57c58398201a794c4817d3837b580fd4101767ab197e8484e8875ced2d2373bfc30c1a1081cfb74b6dc68046d9cd784d688894cc8d5113b9d1196afa6cb8a28df82361c53300a003000a001600d000202a00800316e91e0f0a564ffd00da939301c9295966a752d0822ff881f14a664ac5b74fdd6f1ad272e38b9576c0b4bcb3f4fa1715eb7f21ef2e4bd77cc0ec89d302fde0a587e1ff9cd07a11de95afdb1b9acdfccce99f743c7765aaad2061437e72fec1559fbf84997b9d05a31708f52d674c775fc479f78485597be3d64d87668f771ea4f2ea9ed6e36783b110b3134f1e12c4bee6e186aaddd9509c5ae859f7affc40c4161df2678c50a5f8a3b43b5586aaea1200dff9e224c42442a9edd96b1302e7ea5f1284ba70357eb185c25963fa94823fc17609e66266a5707ae96df9025570d34c88cc0fcaf6abaef588bded6f29d3f22e03b579db8e1aa0bb317896db3c237893a0323d9c7d69d6f232e807bff04590be0a8fbd74486dd8be2468966ef68ae1117ae4003cff53facbea2eb97aed4c0dcf57b225ed0c3356be957983021d41c14bba73a785a8ca7ab3fe8f0c3889fb2c7a1c96cddced5e6040f2bedcfe41e98442a4683cd01550f49939b4048b432009d36ae8b4997b2bc783546bbc569d8ce64c761937b151fac08ca1a091da6e21a3ea69940c891facb6d6e7ecde2b55a439a56290e2efe33ad89a10dfc97197486f74e900861d0caa6e747a47f9224d33b9d6492d87f4bc42ffd9759247add2f39080e72e8e01ec567dbf83b708d59a351ebec73433a1a19b79e3f3662f3b8ba729afc4a57007e80f044bc4349a880616e71f1c16002b6eb08f9f01a61793b8c133e1f72f1195f30a8a7db4c037cdd850fa1f5014edbb0331863d1692d65bb4039d29d812373d4896f70420bc6a3744cb43d0aa2d5f4f643997ad4fd98cf81081545c2cbfbe90635dae8e75eef2b695d77578390b350fa1fa4b64f226b4be7c54b066db735e4bb027b6e95900091be946d33e0f37ce0337a01e0b001e202d80c8e6bd3d47d89f7585f0b668d5fcdb66a48c0ec63a76ed0766d576f695e1aa12725a40ba549b1bca02a5a9db5038407ecbfa2f05aa8e62f37bbec4ba2c60b43b29d5c3fed2c8ed617cd6165afb60f3696f04baa98647eed8efbb8687523deb0abbb48a85fc20047d12f629d84826dae0a30c7bbcb3bf3787d186d86d9c518718dfcb49cba91be9ce48fda10fec5a78d40037fc7078a23c59e32c8f5cdea85e02e24d989370ff2070ca087a1617fc81867bf855c986b26163deca5bc745f4a25295a061db6d4819d8047cd5545dc66e67ecc24af55fd00deca200ff46dd0c43aa9383ca05e924dff743af420182621c34a3b465cb7b5557d3cef8caa1a8827b1795c1267ada3f2f37a0ec884daccdeb1ee61d61edeb3677d2ebe59f502e99ce9ae652883786c1fe657887824aed13fa852c1e0ee5c4706d583a0d884b1b2ee26a030eb44e9863b5375823f4c12b980dae77dd7c448a0228aea726f4e5a8e11759554f8e6f72e7592acd47a1620dc3883d4af230ca975ca87f03ea13a7569f4aa63687eac28d6dcf83966a546487797c452aaf7d9915a649d01f690bafd8d8558566bad9abfed313e293023d1490207ce971d6d85742566568e1f08a802d70f4f2070acd5e2e8f691b955fce22b59fe94d49bf9817a29c58c74b91a16c5ee50ce7bcff5dd5be05bf250698626f290b9d943fe319d563bdfc712fab57ea2aac38ad57236ccfedc378eae9046b09527d02b5aa5ce8ea38b6b3586e6efa2d7224ab0de5b2f36cdc05d3bf5e6f9ad6921d1671918b8653033828fea71a9bdd92a4175f42c9f634055cc4a89d950e6809350dfe8940b137b3c832672ad4e5664f9ce7213e3848e3f7d5ee88be2e9fc17aed09feda48a3a3a1dc94c9ca45ba0e500f9dbe231e90bec78f91b89336eaf70a90adcca493b67b44c37f8fd6a7f21afd06d6164c8e8af28c726460fd46ef795727b8fb030e5230ba72312dd9abf5ffa5099c1d3d156e1ff43ee649857417fd628c53ee78aa6b8f7fe23fba21da1bebaeaf183803f4dbc7e4cbd9ac0f34a9fc1aa37ea20bf8e78348beadc665d08a469d3d40ed5c307a17140c418ece6fcfb70aa1e43feec6a49762c3504c7769f27679e5fc682a5ecc6749acc043fda3674956f67f1eedaf65b29da8bc899db6d48decb44278c3c0fe17de1b663f4dec396d5d5d1fd352ffdd5426bd2cfd4fe38a026c32314c11deaad8548ab284a6c20abc53952dff633f99fc6163e15778f72314984d5417106034b0a671ceca2ce9a2dba12559014c2039c19c399cc55a4849ab99c565b14b74c0564d2c49f04b910054af2c500516ec8f22538f1456e06a3f88e7ad5f3675bd422fefc03405d594171ed4f9684958f092a8d16c987c84c3862b900a46b92444dfcc108ea44e249a6568dd0b4567ea70f375a5d98c25f4b9ed900bd76eccaebd9c376ea35bd0e073ffb2b7260509f3fbdaa26dfc1c1ca92c0b6f581078d86ada9f1a539a5f36e7f587534fd73078eef37bcc1baa69253fc724d6336c7e261369ba076b2930f708615e32e6e52ee8258a0390d242506cb011c85766f1111b00eeb07a6900b9c6b44f1eed594386cc0301d223a919cec928f18de709dc7906cc6cd4ddda0bafc40e6147381413d96932e97f607c9067754bf0ba9578bb21363e445626ded6c67766f33deae67cdcdc97571deb4eaf1901deeb8f8460ce4e1830b6bd58035c1869862e5e3a55ae10387e61541eaea8d4d6b861e3d4d4b8aadaff30ced160074544f941648e41b72c165d3160538113e7d031de33d89c4aac68c714c13b32c5ac1a8673028090762cc6bb893853f5e2c5dfa13e9ecdd6cf990fad7067c60194b585a11a5e68a767bc8e2c0f0da692d2703e6bf1044a329210dc9335291db43d619a9f94589665dfaf5b59adfefe88004575dc67276a00cd40574ce6c608f0b963d53801030f0323bbef84767988951bf0075d5ae995f86c8affe0bc9898e33bf4496d10e00528e30d669095d0c0bb68ce281ff04fb968bdb2263e8458ed215dc3bb682c916b70531fc9c1e0c157859f4f8bfe18d65ca7676299d2a06a3aeb1e9829a67c904902eca0183f5aaacb1a14ee40898651aab968ef6b3a3a94a6b3e86b8ba60318c08721993225d72840d7e651f5f014d87d6d96e3817a3f9cf899a8a6f40fb39287c8802825df1d0e0cee488399646f1f78a266c8226a73111a6d60b32de2cbf0cba142a640496f90a72b44df20bb41a179ad6011af9bfad62f4f5681104eb31393280558fed38752617d6d43eb2b7a02eb3f50261f4262225a1c49b4bf6ff3f6ebd6abf3457862c8369ed1506f1715d2a901c633af4cf378f757747ed57ddf2c17c445b910d7f6cbf789cb609754c21beedc871aa5ded75ab19f994949d93d06b880788353d908854c21f7607480384b0878fe0d2d4bccfb9ac9d7f65d318f71d4524aa5adc74b49306d200cea4952d60af73b817151bb5119effb0c3bf9429b77c11b19087e89165a951b743e7a9688a7c5a04d813d414c90c78dbdc0425c0bfe9f1293052ae88df1b9a60bab5f7b883ba0c312e234eb026fc0c9869898d982a3ffb2a98da8be4b5308e94e1cf72938a5a7ca0034cf14833731a4959cd18aabb95177cf4c8a092609044b4dd5ccbd49760b6aac03edb8379d53283e0e47e5719b7596db74f6d946d72a6b2b523ad5162aab117132d50ba338c69be3ef4a1f62f50702c18eb62971b8fe5a746beec7b0582c8c127ae69b07f7e6a1f8f4621fb8c1b43b0d157d47f948c1a7b1250c776649ccc9b3310f26110ace85c76a04db80604b6dd06e40000bb691e6a3890966dc50301df01ef9b2c3d2fc4f419f7d72d711bfb9d68963a972859b7972e1a0db3e392b576ca6e23147a232284ecd9494a75bd0e3cdccf63bfc7bec32404e22524557ac751b2dc6aa33cc3929397ec75a8d290c2e0a82527eac5b62c43e3b384ce3eb5dfebeaf86b55fd457161df2004d4c8419a4b3d24becc1f17aa2e288db63b55a96b3416d4a3b2bfc9a6c6bb8c7c1f1cc0a94273161888d07a91227387c33d240b17fb27c8a8071ade1f11b4073e6e869efe27347e52aef54cd3d482767a30b846f6863c0ce6d6c026d835300db594635392134032552511f85b82150d57ab3ceb49c803916248c1ac1cff59c1cc29504c1017d1d7b6789eb8858c545c2f43f8493a4bfd3d9ee9894a5d6cf8e5400f8f97a69414e680891cb32823e8113adb154ad77f02ec3174456121aeb04d15046018c376791155f2e45f02f1c3aedcdb5dc9d3582a3487ccd9a4cc71ed0e22b41079b1b70cc380e5f47cd0d2e627368287346d0efc433084183be92fef49e0cfea93d7ad341f119dd2feec3d19156250b7a31133e812511f34dd00019c5205934c22527f2ada2e0f99d875e3a90a0ca489fa42ccbd732aa3c99939183dc541223fd1839c6601ef004f51495ce73e86b17cd991086d7969f2b2768c1bd5d72c79476d491067443438ec60548737cf538081a99ca9338353b5600db9d4a3ec8b9d0c568965908e8d44f3467aaf654f592c9b10ed32b65e690172fe34828afe285e994f115291396530f30c82e8c283dd8a8f1b60427a928fa3a756c19a676a519c079f0a573d58551edc3dcd2fe69c78cb735dab07decb3b2781e6c41feb573e1f823ee2c13dae7e46444e892cc49ab1808c3867bbd6ca0746be316138a0b7ce661a87d183b083b75b922006caa161c5c08dabc0da06a64a4edc96c4ebd47545f378e40831468b4dc659a272ea6ad15b7e891c090933ef3371d9166b7dd71b0c4281671ae24bce535ddfdb13e43d64d500b1c1ca476a362e189d34ac6ba856c5e6832fd003e6783fed439026c0d2eed3e0df85fed9bc6a4b7f1647f30047706e58dfeadae31d0ba81d5db7c2354bdb3dd4f4dc8c6448a9c3a054a93268f4e1010f08a3ae782dc87c35491ce8f784e11da89c83a80c5d90e3aa1a20cd9e38d46ecdefebd25838864d442d26409117168fc07a14d71813ca0313502a8f3f9935d3c0017e56a77edbd19147296020709ba08fc083f94c955b36539bb7bacb187167b80792442496a923d747b00fdbfa5bb9d3b7bd5e38b1e4ef45092071a792891072e8fa20f96ba8cfb69f2ed636eede3227367a7585b8bc7173c4cc0c3c42368cb8ead345bc02da557cf3d585e7ecf2b9deaec73d19e8414940321241588fa5026fa438788866a0734a6776672d5cc0cec3d5f2edb3b9d65747cc99cd0b1778e4d3303cdf2f27099c3c0325f1f9615e9cc7f1cf378e6ce5c46c7d7352f121daf79915c0900faff7a479cff577247d6d21d64eeb863c97fbd77d0ff9ae560fdbf1c2fff55ced4ffefe424fd57b2cb11b297ecd0c20eabff5bb5a3ea2b931dbf7f3b68a6ba3a12f0f55647ae0e10eac8311bc5af0fd37155e938a2038239103047d57fed73fcc431234e135f75712c90030f39ccc831460edbff5f5d1c69c471260eb2da0b871a38bafce01082838237aa78c3ea1fef468c7778c7bbba07b41456f91e73d58d2c37a6dcd0a00d30da30a18d0dd810830d16d8386283c87f25733f9dc6bc5c6692e293dcdae7eb3db4e7f25549dccfdcedd945eb14cfc0fd3b6919cc6d1228cf3d074d1d058e01e05c8143548d7047b27e6252ef9c797127896bc2916b94fff5b5c61035b27e4113d79d1a55bfa3064e0d9dbe4b6a9e9bea91a601e783b9591a61ea2b0daa3480bebefa0536bdd9fa7f73555fdb74d1a6375c7e466f92fe0d7d34e2fc1f41e38aa28146d2ffde261a05fcffe3805863cc773820d667d470c6ec8c0ecc78f335783985555377a798986165860a5f6fb51a53c5ba9c1913b8d17243839b10dc7c196dbe5a736f6e69cfd645310f962f6b5df456a332b294b15406080878a30e297d66afd2982f9b1b78e0c185b26420800c27c858818c236db4da00d1864a1b2063dc31069c31c08c011c2303366cd818c18604362f31ecf8af3e6c8444b7aed1a8e005c2f4595eb39f48b1d8cd325dbd63b1255deb144669b02471faea7031a64aa7348dc26ad944352eaf2e9b99eb74e5dbda915b2b064e0c08b4cad0eaa245b4c6cd9aab355cd64cad317280ac034c1da0270c337e08a5d5ec3c1b199dd0173eb9e9a22f17ce5d1d1d69595e1cacd67307c7cb474b751f3b0e97b94ba3741b0ac63b5dcf3e8cf92e5896b7e3feffc9ef8401465613ba4d30ac4a30a66660b8bed8fae2ea79367b5fd88efb1117ed5f50f3dc6ad0d06825d550a971a901e285d6bf17545e3cfdd71d2f78febf6661bdce9b84acaaac5e9652175b5f499ca37c971878bbb8aab60baa97eb76d105fdca05b9378f7281f55c503d142e92ec6c01e7ff2bd98d6c81f5ff556a8baaef37975b24556bb7e0f94f03e7d360a569e1abb532998c56b4ab15e9b053afdf1e59d68265794f4ee6232da6ba163c5968fda6ac3d77308b25b2b05f75a6dbe4bc2c807c182361610725710e8b3075ebe0a51a0baaaf583cfdff6f2c8ca071534ddca55434366041834343bfd64ef2bb737ad3717685d68cee4a7c8597285d7e7245ef8a0bac00e3bf623ca356dc6085b642c87f1d476b2d76aa028c2aa8fe2bdff49298ac42c97fede4ace451aaf8af5055a854a17a4685182a6cfaacba29d89822ccff578ec9dcf53ed2f593da296c53e85ce04c0a3752c4f0bf779a16852e8a09b0f2c052022b0b16396ba2e3d010144d401100282e140a3cd1e68584fa130738a184134027ac13449a98a309ad87a242c76ac926e8993767ae3843c3192c678aec1860ebffe9489b68ac7724744442ea2b65800898d062020526624cb8aec6b8c2ba0ae2aab6441f4b44b1b384124be09608a2841925a0fe5f08f338fea12f9779713566855e38a11ae47a9a29591ab34a3d738f98a7338f635fb7424196ee68fa1c7137a374bbecf962a9ab53827b26a9f1d8318f6325252a78592c762b9ada4637895c1240ae7e717ba769b1d8cd8c16334264202103124596a4658931797d348b7ba6be74ece9cc1b553b62ea88a32388bcf93b79df298059000facdeec58dd600582d50e01b42040553d3a72d52ceed72816bbbf608ef69e7b3717ad7c739d5dd4c6a8b975b9b9cfb74d23dc30228d115346d022ba28224c114f8a08abc5fd5aa1201f1b2f771b840b72535fe0b983e70e565cb38bee1eecd22eaf06f5264fdc7f9ad4b8a9e30ec4ba4c56193265a6ca2c512a83001158b59b3b445461222c113a4368e9f41056bf330497ff1f62082021dcfc5fed08c1e5ab105688255508325aff64ccfc3f991ac824fd7fbdc11c19d74e105a40bc1404d54e1049fe7f4c9cffdfe7183463c8e43154ff558f791ae31a03e4ff81c8faaf647680a07a2034c6393176ece0d4f5c962b11b8ec4411c259391b458ec46d27cd8a4c562371f36f300fe872d7e70e107a31f787e681047b94cdce4030b3e3cf940c364852153751800f4c0460f34f470f64079d88287137818daa18d1da8f87ffbca26ad1a197d3a20ee75cc77dd8773b02cc9cb31df1466764cf28e9976180213074c1260b28041327193ee0bdff982bf4ca043153ae8a0c3eddf87cd0cc47a27073239ec7278e500e49f6ed3d2a0e9c5031cf6c081091c64c041041cc627cf5cf0cce932effddae80d40dc3075c3941b10b0818d0d3fecd8e042b52f17f6ed8eebb9027db8675a8bb3e1470d65d400a686df7fb5380a47f14d69808306313450d150c00c59cce065062019f2e842063132ec6428ba3f5d2673ce52580d9e395cde7e06cf1cdd669510552d544955415545a90a12039a188c88414a0c406f7d96c2acb61416f3d11faa712e667bc71a0643171892bce0e685245ed02f8c6fed6e53174c178ab4a0a6053228b430a585a11682b0f086ef1d16645de2e8f244972532f89d2e5e9ecb175cb47009dae14264cb165bacfebb111f36f316ba821d2b58b1020b2b7cb002102d2c6861d2e2da518105159a54e84923052f290420052b296880821d2850f15f2d7f5d9792de0d0507042080140420446507950f54552a8969d5874d9c3b61eb8434279c7042d25f18660a809a9d009c09802e000fec98b08709624cb0b5f2d2ad29edf9eef26ed39789bb8b9ab8290b145978960c4a18a3041e4a482aa1032c6760c1fa7ccdab71b9db5876825004b30461c121536d4c113175c314d554d15712e782d707abbaeec3666ca6c4fab0992dc53025b0d8ee08a8052c03840262f0ff3158b5b6779c0f9b198731dfc9e898e49499e7c691f9fe2ec73829a0ffff73ebf4f2ffffeafd8c72fe2b812931b199f55f7914f36be4668e316d5f03663007c41a87cd608ea4e1cc6f64c6e1cccd7e4da86242583335b3c091254c35739991b29cd546963b4b922c40be92b8842d96c212aa4a48fa2f81ab81c5eaff93b0f0d059504d904bb0289cdafaaf98df5e96d77769309c9af2f23f65a78404734031802c84c0df3fd055cbf2fa3adddba4d966525a7c2b498579a9258ffb792475c05712632cb949e7738b93eabf9e40d59cc2d96cb3dba1994d093a9cb093397b972a77c7fc5696e7ae93df25e07038d6bb5bfef45f494c7b374eaff4ccac6d57b45c09fab9c9a56e9b94c4e5ee7aebb6e6b34a86bf2a0ed35bf378b7dc456d29fd4bf235092c5bca3b73bf7047b17f9df274e69b735c37d04c6bd59da69ae9f17d6c7c29f8824a389803758eaa1dd998e8cd5294ef5e3bc7529787250fe5d37f2d79f6521496e5dd7217d54394ad5abacd282015eb4d827944c209ffff34db8c9ae5ed32fc0bde623159bf49b25b51afdf244ceea3dc940be839d19ba147ebf1f0e4e0e9c0a3c20bdac5f9d1e2acb975596e3df21ca9716ef4a9758647a51d98ffdf25c16ce01db00e47109259ffbdeb8bb38f0fb526dff5ab336de4944e8ace486e8d9c0d39107249ee19d789f05eb943f787edc262b11ce0ce0871070871617022e08258d9c38a15cc0677f98399fcfa6ea71877fe7cb7d77b758cf57e6985b27ae3283466cdf276e0e554679f4ad22324e6714b7d6abf3c9ea53e40ec4387d47dea3649833a1fa94f235aa1ec0f85b2b7d7793a5b91b242046a0d9497af3f6cfab02e77a8a1ff7f4b75de65cc7f18a94a5905032a5c5099a24205c99433a6bc306584294323c019a1cc085446d879d2aa50169fdcf45d12fbf0ad665c4d9de92eeb4b2994d5653316b354f0e9828ac52c151d27b7a9bb519e76788222a58fffeaa27c5639d6c0ddb30fc9d7b30c93fb88c453b7c44c25e65b174ab1752914f0947a86e224c67f9d39dd9c8e38f544c9238a9830cacff24b61bb5cdb6d4ad238b6349334da8d707c7323bc8d71eb12de8cc29baca98da61a6aa7dceabddb556fbd7937172c390e9663c799efdba33d9316c7bb39730a6b29cc7fb1d88dbcb857e66bbe9ae8e8e42269a43e374fe291678ee3b2be92215398df6da6a9af4c400fdc5a0ad37f15818cc63f8ea5b69226119644789a8900544500f2a1cd46c35732e36c08d4d8d4ac086b586a4098ded3b684c412d5925e02fa587f0529bd51a2416904a520509480c2a5c248de84e39d6db216eb274b3cd13d59e0ff13f8f0c9014ece70428493149c3439095ea0595eba7b79c78a6b1e6dcf2151589fd919ee86b41e6859425aa6edfc7f0c86ebbb4cba4a7a4ad2811202560821b83e98e3bbc95613344daa824d9af03071f353d7c7c40bf63149fa0f320182e4e6bf6a1cb5790ec9cb77a4a719920e3dd23afaf2ff7db7cdbecb232323378cc2184d31d2998151cf1da43498d39bc463e79bc4313258f6d059389332a3397797785912b524b6040310b4fe6b4f4fcfad5663022129048101d91ab21e42991559051f50f1726d4ac30f46f80082a233455bc2a2a8a29ea2204a7aceb775bbb414d6d343af92590c8f308615cb12c66e1506f3000b0f82a107503c3820c913611215ea8be2dcc5598a73b90ee074504407be0e8088d80889b2422217be9eba7bea3ae6d61acd3808830314420ea6381832b4c5d0008644181a82440d922d2192a0ffeffdfe28ce71939e3b6871bb8d1b427da8b5f487da20ae772138a110d6bf9097ff1a0a3d09b978fc066585415e8292aed9cd73cf80f8d81a076f2800c180747e041e39e2083f82a4ee51771b977c9bd7d21ded0ceb0b35090cced7cef386e9de83fac25008614d962ecd926eb4898912ed469930d594e8528d22318102657644991835d1924899109293a7334fe711ebffe48d5575b43fd2ff89f3b5bf30df3e170deafb1366b77f7a0fc4bbf087672f853e702ae953f53ff3b17df5e1f97f655d20c7e42c7c51e5a8694467aa8486afa7af7c53a1dbebff9f977bcd850574bd50cd9e4b59d1d4f515d152c4a988920dead8a08c7003321b3411e183c812447e4490febfe3123635654a595efa439bec58e6a89a0db223ee6714dde39dfb0e29c09030e110010c5132a4811e37c21e227aaa843d409ef6b3b4514a8fa6d01f3ac555ab18766948efa057140c2d814285148130833032a0fa7f4a474b61c172f3607ad311030f3058e002362e18407881ed8208849021c4082150421c1823b4404d688196d002a6d0820bc20ab0082be8153c5500840224420ac6841448a180011e2e7882b3232a31ea437ff02e97b49b3956edaba9a976a4c9ba8a58ababb4c955b3e3d854962e9a7b367f2f17ed14c6b7edb69fe58f8ed6065118b5bb7cf99e1569dc03ea7c7de1046e3e9cc08bc98d7c38416f827e811f7c28419cff0f253042825e28c14cdc0ac5abffff99c8e57f168abf2ada44a09ba813c609432d8c9b8464be29b4ffe3a74eb7c390e73fa82fad4ae1ced6ffbf041fee68853b56e14ed5d71d9beb77be2902381170f155262b9ada463257eeecb9b343f0e667101ca0f326d429a383756ea18e90ce030fe8f1c098f0812af505d38d30cb64e469a781588fa10354a103b6d0010dc206daf87f007cd8401a0d50d1400b0d9cd04053d8001006900819a8aa2f1bc451b8586c577335bd6c94beba111285d50e8391e5a6d66673d55e40ac5db41b099a3d77769be33cdea541dd1788024cb840090b38850b1c102a7044a80009a102b250019d8741d9bdd3342ae4f599b6dac2203b0c32250c127ac0411092da010e81680981140199204c008e300123c204aa9ec952582e4c20294c80e7bfd69e3b7b8880508840901001044200688500480300600800a010003e0784718055b52f26fa439f5c354b71101dedab89c95a8bf1aed697cbc4bcfa72f5186c9be7a53897ef0fe3dd2ef3bd9bddd0003d20f8d080364203aa080d20131ad0141a208605c829404c580094f0c71e5f7b13fd9d662c76b33e6b4baac4c992fa863f7ae18f26e18f22e10f0ac28f23fc1dc2ef127e511f73fa78f34fbc3e7afaf83957735298639bb3644e057320e0e3007c70a99dfed0266b852c85551826b70e669f6024bfbd9e3b3bb54da40bc62d138c52db4403fcfae868fb2cce56128d8305d3671ca93849ffb5cab1f535cb81f5726cf9c7c921c611a7963b0e20e29012c70f38848083eaabe5b1d8367376b769af3c0783e5b9437a63cd1b27bce17a230337b2dc38c18d1f371668c34c1bbb366e6cf4c1061998f34c831948ea4b06e99847dfa8738977b4dab9c6baa7cb3b1aad5b6fbbcd5186b1e4a658ec46c7974c26bb15f1749eba4ae62e9bcc5d768ec98b7b38d90b4ed6c3a98263fbafc00ebcc1f935b4fed7a046746d8daaa5dfaf71fb7ff2aad1871a6dfe5f8dad46086af0fc63a9edfb5d60532c7623c96bd338401a574f92b358ec66e2591ab4341a78a3554d7dcd29bc4d9b0de228fabbc03755e11ba537ae8e0619684c8186feafb6fb2cedddc45b771c44c3e88c38ff729dd1cff0c08c2d1c745d9ece52179739ea3203cb0cfb66e8287193e5c6ea9fcc6e7a5fbbedbb7db91b9b797d3d2bb90152fb2ed19441a68c5e19495f06fd100173fc63c90878820010c868830c2c3254f851a23c9d6d647c1b356d826883dbdc360d8c71660c2fff97e6ce265a6f6cccb0d1c286890d0562a0214612627431686234a0e546cb072d520b8916903575ac19c01a14d620bd92d1aed63f60aa313149bad198c48c90826ccff66585e80732a1207d79eec5f7cb0ad122eaa2353c009230f608638e30be84f114c61130f800c30a306000e30a1844d27c31c517515f846a9a08d574351a7841871761bc7812666d3d45027bd9209b750951a35dcdba68474261f4655f41364b47fb52a231eba25d88c2846c76b7836c19ef603d93678d846cf48706d11f6ac44f3b443ff880be5cb1d86ee376e7b1d8cd5294d69ffa53492c952f90e29cee76bd33e6b9cb37a96f173c74a1d445045d24c005125cbc10858b0bb808c2c56fb1660b14b6b8a59993c68e304d99344f698ed21cd1420c2d7cd0c2a605d0ff636dad92ab666db6bc9472a099b9ab66e9685f4a945a1b106b6a97ac925da23fd4a6041b5279575f5fcfcc409d0e7613f3ca7387f9d541d96ea95033e39ec9bbdad2213558624ebbb6487a5792e29c35c546f4977b1d4b658143165ab258ca22812c7e6041c4ffaed669cca7fbf4a9ebb3d95c351af3a1584ce98cc592ffaf4634163c51d0c4f90fd160fda321533b1a9d06628dc656fb4e86e68a2bf20a2ef55783ed25aae48a5e7805fdaf405c2c760bada8590142156b54f1a58a5d154e55204085175464a18257ad893b8ee3f245a3ae198b59badb2e5a5f354bb3c1dc1dc912fb7254bfb7a87e4d199410122a781eeba6d8fa29acc229aa483c4592ff1bd5bb146ebe02b18eead794428aaaaf522491590a200fd35b875184717f19fbee5254bf375914bfbf611421d60b2b0b8bcc7f25b1a8b096604960a9d0a8ee0beaad6732ecbb4b396866992c16d365287e2114c127e0fcbf9ec07aa2ea770f183ef1abb42792c462b7279cb8aa79e704d557276c5f9d7055276e1356df9bf8fdd7739b4d2cf926787a3e03a7d228ddd2992b7e86ea4cd21903a0b906e08275ee66802524135b4c50e193d1e8c8040357695ca1f9aff6cabcfae08a678937d5363d29cbdc97a05aa20325e850828750092c4a24a94a5e58eff2528e8178079c254146125e92302109a1248a98c93223e6ab6dc2516b668a191090d8fa4ade1aad7d4b9133247a40a206246648547044968fe9887dc4ee88080ad04601c014e0cafed19ee9ad1b89d2f96cb2978bdff2cacaf21ef528dde5264e675911f6e59b6ca4a302231d473a8e244d26e36637bb912226dfbfdfd9713afb703afba4f879a4b38fa7b38fcb64b7225cfece5b910e3b9134dc35228ede4658fdcc88a96a499a35e2a9067194b9978c20229b6231d9ef37eb9792b422cc22ac14a153268d32539479a10c07968ea31d6db794c911264f9eb86ab632a92e6a7b103fb14f98d01ffac455b3380546d998e4ec5846c724671199711ce31fc744e8f4c221dcfcff0f613544d5104f43f07c0d85d8aa24e6098146882a2184709181f35fc9585532543adc69bf3d324f644232f4fa82082308aaaf63994d7de61ec4d3fff374ee4100d97a0c1add49eabdf518aaaf24dfbbdd1d637f0c2d331070f0145e02e2ea4320aa2a1053ff0fc4d3ff3b01e17a3170423157525ec4f4fe5f2726898ad991117120945496f7680a939af6dbdc3680cac60f667ea8e187da0faeaf967c59ebf281071f62f001c90707c2b8e1d4e9e5e472da2676da26760aa31406d6431ba49b73301896d23cb8e101061ea2f4b183103b60d9e1680720601000060d982b606c602cf8d2e6cbd5971cbe00bf98ff3e3e58aa0c5edfe5586ac3603152df1d4ddf5ab1b9a5b636cbb3c328df74dcd1be00d5ae83153a78d161b799e84b9b394891430e403958e0058d971fbc287929000702843854f5dbbb4cb72da56467bee948626b39c661c80d5aff7fc3ee06211be8b0c1cd5b5c2c26bb15c5629d7e407fbfd0869c0d3a358c514398b0862e350c551286f90f47031b210d6668508186dfff101a1a98018b19bacc50e5eb8839efd25e5ecdcb4d333020835628830ea10c31c850f4d5be8236d0d4550d5195a5ca15c318313011432e860d609803862560c0c1c0c0e5bb499020e5ed3d9ece96eece1cd69bc4658e5f1d0c162c83e50b48bc90e505272f087121cbdc3bbacf2b5bc9c6c18bebb962734bd9ede482052dc4d1c20d2d3461610e16c2b050020b1bb000a44b01c22e2774f1e1d2e675366229ac1bb13dd3b4a7a5e696c2fd2e792468660da3946faa2487b90b898b932d7a6c59638b9a2d02d8e264853a56c0aabbcc7167b2244fdf6a07ee1586b4bcd1c2464b172d4fb4e8a870c70f2a2c852a8090421cf54561fade9ee9a2f6f573d52cced158497176ec7987b9e5e97ca9de3b5a95c2e6b9353fcd8e83b707afc6e6760a96e535352eaf997f578724ebd8dc4eae221d7632b7d491ec6a1cbcb25b51efb25bd10e67f6dd1b22ca587267e7616ce24e5c96389eeb3e5cea868832df53434439c84d8d8590e4b31c22cafdf4613e44943970731edf4344d9d4badffe0d11e5ce7326ee57f01051c65a9bbc21a2dc4fb31c22ca389eeb9c24ef10513e8788f2ef72a010923c44944ddc71a5b9f91051c662ea8688f22e0fe1424872278788868832ae3c7d4344b93ca5323944944fdeeb4344b963de105136310f87f5ee976796b7e338fe01b7c6e1a86be27c9bd49793e5c63cde71e5d56133981bc27197eb2c15cc54a16c2c86cdcb75960ae5beb393fa52286ba990d804ce64b7a2a87e6f51fd9abf6dca8af4ce26c6923bc692bb4c96a4f3d89535aee47025caeff71be10764a3b165d84ab41b567a048d812fce9b66e6408ea536b6b493c1d2de0b84b2b15854bf375f50dfdc2fb0d3f166caf73571184be636aadfdbedb8c7cb308c77b01d895d514633e35c39a375ebdac4c489765b6272b444a32330cd6e4c966a4ab4b6d4ed91af26fa8a945c94c1b2272aceff88cb5fd6e9cc7fbb97f7776a5add3d58eadd336d6c46ab99e92f47f5cb6fcfccc09c33a770bf3a9d9b4499f9a8a7a82424504102d557acf78c840c721699cb07f57d41599b92a5e2a21c2be5a7cfaeef6d7deda1f9ef55fd7ab6b35f1dce057baedef3f8cdfa7f1e99caa3faffcab3ff95b7e4bf8a3c9dff17776f7ed7b41b773d580d9e0143f90a041494548d90783ae736ff515a7905527eb1ce5076bb475f2e2b927890498864183289fcff6a84448325cedcecd9c5dba58f1ebba575ea2ad99ec72051e7842e8c4ed44d904b53cddb67d602b1ee3adf7acdbb73622ace776adfa9c5dbe526b93f360c6b8275e1bec059e19e7042ac6461e58c951e30bfa8505a6969de71d439868456116a0050b52a7d8855e254d1a14a09558a50f182ca1154aa7cddbcebebb4badb8db8974ce8c94d6cc79e477d72ccad796e71ca11e21415c42948532818018dbeb8d4970c8eb080f894c49395a71f296048a9bf0e8542599cf93be98e4999f91e8fe0deed37ab525e4e7a38b989e2459420a230450921ca04e2ad0af12680db78b340bc01694aa2c98ad85484290b97386c6e1c2e868496a54f4aed3cfbf8dc6a4b3e3e4386d40d3429edb9ee97ab48879d38362fee4c404498238255b9f9a637dfdd4c04aaff1ad4358940e4ff83b960cebcb8d3992d8eed8bcd494d4e4dccd79e9981dbc49ad43bb779335aef14a6789b1788758d4b2d49b5966fba1467a9ccd20baa0a952a2e1fc7becd77afbdb4c4f3d55a7a2989315752bafaffaaf4fbda332731b72d51d2f9af50b2a090f99f9308a50765498502646b2d7d323d21f364ea959e24119fd0cab1b99da2f4e54eacb6e8848b139f131e7b2f2ea948eb342f2fd27e220db869409292acfe6b52af2cf72f842842582184104200a1091c4da2109bb8f05f5ffa02b18bdad7d4f5b96a96d298bd348a4da6262f2672884cb4b699b7be3491c91626529814bda2f4e5389d7d4858482820e99018f8af51faf2bc39c612a5af7991c423258eaa8eecefb652946874c68804233a93f3ff412fcea818ed2b88627ee998631607afa5b05b734a1d072f0ef39b9bd987aa32ee1e904a153ae35982f55f73bf4becff9913972cd9b6253a48342a82c0e6ff65b2de6f7924db42d68228db1fc08ade145151e4138b9a8afed25e9677ecf82a794154b24509d0ffd77d448c85896931e6daa2075b3c30c1830d92b4e1bb031fc40e70073a446210392112e54054428ea8894804fbdfbfda2d7596c26a59ee18a9effed5b2dc3f3af67bc4d3481c407971688c212e434890e481240b24412444840e206445ebf5e532854ea10cc4a03541565f839a7a262dcf6210d5ff2cc8f6ff391168ebdf5e8ead080444f55fe91581aa1c89e3089afffad219783919e4d7d467b9a5ee91a96d1e713a52b134ce2d8995cb57a0ad1689b03e6056db0ceaeb824dfdd77e05935784b96ab97754cf9c8ae31a2394ceb3d11c5db573acdbe2cfd6bf5c74f663f5ffe20f95167f6cfd3cf2e3f249f37a5d26a20f113e4fff7afb344f8b3e406ff3f9e7fbf562f28a4074a1a93c4d45579877f5a0acc65044174f2d6f9f1981639a7bf75f0d887591208a9c453610379043dca0890db46c30f424d67993a0f1af168b592a3e35d31f4a49736bead371cf14897041248b480436248c2154ffb5a7a7e3a82e45af7939e517d75766aab9781687040d59a027eb2b25b3a53ebb6dc92cf61cd1404b832fa20651a20656340842dff8ffba4dfac2e11c6e9bb8a89c897d9857a1b1dcfb578362d8bca645caa04d062f881910612007063a88184c61b0c3a047c4c0820bacf8ff0f5ebca0cb05572ea0a2103942d87411b2a3512c79dc3bf6c2bd3ca4f2285d8ea2243633def1bdbbd8d7bb49a3b51bb14214b0c08c68410dffb5dc9b52d102a50af0a8c0870a441029d8a35a8b710772dccf600efb76a74714740a9c8814bc441e3e78c21079b2441eaa0a65b1addcfbd7cbbd6d531737757d306aeecd34c19c09d64ca0459c60e8ffcbd24742594b652483b8b7f53612253842022ba20440a2688688a5b099cf2b9d16659769751cc7308e182a218655621882b8a3c70e13e24e0ce2ce0a3b48c41d0d2248f32486e1da35597d8ee890fa1a39d6510e411f22044188105481800251e78da86346d4b1a2ce4dd4f9213e50467cc0870754b0b81fae64d4b40a65a94f858ac52c15da7daaef42a13ebbd3dd7de810f10110c4079644076a70a0141db0406ca08fff11caf672ef1f2df7fe755c2779bfa54c762bba9c49cfcc527ab965b7a2cb316e6b8e4b1e6f9b38736f2e2b2a37c7e6353bc7220329880cc082b911e31dcd7626932d90c5f3e20256e20253ffe20274b6801515b8caa2025bea2d881931c896204d82182002c1128178f9aab798801e62024d245042024e0944202220c78c8840504420c97f0fd5992cd28f68de4bf580350e10e200de01444403f830e08c015844034ad100971a05882940271640452c80e7ff672ffe58f3238cf843ff18c57f437c23c4078acf81f83a5f3766d273fd9dc192674aea2b85f671c11c3ce6383107cb9c2a73329813f2a1c587152af061850f217b68fdbf6e6c528bd03eda6c2dbfb406617b04d1830c3d5808f540410f233d84e441471e0408f3a8210fa63c20c0830d1e5ff050c19cc23d3ddba419caeab214ce45a96327f5b9e34568b0dc5ab395668bcb5693ad5702da4840990470a9346629df774c71c70d77ac7007d21d3f42397bc8b9928345ce939c0be4e8d8f1851d63fe6bd05218ed99f5d06de619ad3db3a7278a6f60b6ed7293a0295360a4632c265ba2635291ec725c47b00ed7ffd77be940d32fc7744c753a9efee9006e4dc93a879939707324fd575a350eb135a8349545d458aa19000000500053100000181c24140dc8a462c1644cde3e14000051b47468dd9836d1649d54c81863600600004000400002775171a3e24156cadb10d96309df5fbd43f80c71507817fd707ca2c8e3c1d2c485cc87081f139026bb817ed313d887db583c563a9ebaeb5bb7465f92774d263f8d759f1c612a3d75c6e395969eef524e684d403039fded06032b9b8b89b1ad7039aab78d2d2f47692ba1e789b1137e6601a9be07bc8d895542b0971e36218b2f75be69489b84c1fe475eb70f9ee2f68d428f3f249d366b89df4583a6d4774b7559d03c9bdb48ed737f74ed6c625826a0006c7c21caf0724b86ad3fb229fceec5e1ccf3fd0df78cdd3e6eee6eedee483f8216b7e4a2dd6eeaaed2f7bd3bebe526a482e5357980d1cfe321c504e645716361f4761349d1818a174b657cc657a067877a3280ac2c82cf37b81a2e08cc74e7f20c4ebb55bda8aa05e39fb1f2864b60b424dfe96a000b7f94d84597095048a0101dd28cf37f4742b1717e4d0aa7bb14e47820446962155d27e3b9561af6014400add1ce74c2806852823a07782bd282522c52989188714c5fb60f17be64700c3be4e71ad3e92bd352738e569f5248fde93fbd02fbb45553ea760903b68a5da9b11740df2c9d7b33225a60b18279bc82351f7f7f974a1683920d4c981b42fe32395ec054b2949f6a39a3ace33cd21b2e356352a0a25343403a9037cc39166fedfce56c18b2b50eb9f6b8dbda5265a0e0bf4ce92e6aa0aa908736a8a57602b8a15f037d8171cc42a87db3094f7166539737a90b43a84344dc96d1377cfbc4f181761ebf30d4837fed1d28f2f0b81a23b59bce23fb8fa34a3fc048d61b171cf93ca840a4c69395ac7b4fad4e17b519e9ef94c1f3936f56fdff8441122b00ac6e16696e10909e7aa894156852d1bb91404fde7f1cd93c394617050641433236c309b9e31659f93dbaf9c143e3626036d248dc84a010620012796412a8d6661c6ca4a8a81a74b82e95e32a80f3d7694369ece556fe2148be8bcb1f3e2d4ee2f78501e83e229e331eae567489bfc48ead1b6133be1b837cc62c0e0de3a38a284ae8509a241e0ea0ca3d65b2d287c6e38d0ff6c5cfcba3375cd7cfc2f82f6f26596c900524ef851710d66d278b03d4903f76b00ddaa26ef7fcb507a889d598e915baa8ed2bd0fc63e68aa2cc46d96b8fb92625caa608a42be71154f9808222a06d62f4941b4907235e5e0cb6fc428297fa84e3914fcb8aa21f35eb1f4e3efa48d33287e4b1c525426070d5ecbf09e71ddd2051dd77b7b0d7dedda1b2cbcbb55ab504970ea21c04635b7f6d536c203f3d8a4cbead514548e382222dfd9723479271b35cf7887374495ba6a099ee386472ff770698215588c601b4dba6a8c981967ffbda66cc348bb3639bb1bc38bc1bdd7048808057c1bf480403ad0644329cec5701f92c861dc4ceae7755e8b3596465cfcc913fdfda9e5c348a921d980833cb0aabf0d0af2d233ac23c7f743e86033314c91709ba6756b364ed92bdc9d52003e54953eb85354500b251666f971fad0521fd20812e405fccd99035add92a61782ae43bb93141232aad6cfd8ad71087158ccae296b54447278c839e8536f0e86a55e2ad13e7c86df20524abe12cdccd9d45b144ef69afb4d6b1e0d50b99ddbd7187b808395f77aeb60e6f042c8fd21e501147273969bc6b4abc81744d90005d96c48a4b57bf18b91fe7c1d7a5258fa78b2879d15b9c6491b336d8b5b549573ee5c65930f4049f751bb77edb9bbf836980e34317c2314a1abcec9b11beb4209ee15943d8bff61b0b6ade42d640bd7ebe44ad29394855fc3fe6b19ac91b4d55002d62887bfe83fc7f431fbc3b5354f67e420a455fae7b4f572cd23e2d8a22cdce13765a36c309f4356977becf04e0cd9ebe9644c939131b62502b0676e4b20201db11e5fa8758c84a2f739c6ac1da4462c11ea5d729b9e3a3109166e6da97a247816fd0dfbc9a49a4f8996cb12f007c272c1dfe870ed836a4bf793e00ec2728fc7f1ed814d35f9384dbb6fcad0cb8eb2adfcc713b22b5b6f167a81ec187402bdb1ba080fe264942221a2b9067714f6e71dc0067b42e36b36ca7fb45cccb6739f75c0773b45bfcc395d0435eb8f8a125d7f1cdd1897982fb7c2b5a18919b3ee6e490276fcfee9631ed40c5ce0d822c663d996d823da258e0405d234af66b570e482f394e9590dc7a45afaff02e5bb4531429ab89aff67d69a376a83b935a9ca5b8157b7549994e1a09b8ab34bc5f63f2414f08829a599f4578deee8e044d68354970f442b13b9614a4ae3b7781411e13ad77fd496a91b72490e754019a7c78aa39782a073d3cb5efefa9d2f2d5905dc7873499e343c3e61aed628795593bbb4facec798bc7a4496508809e61e024b2b314f4fb35136312fad3a05e615c1b9eb706361f10d2bd919d7f1ba457288068e3db68386d44569b480dea4d8cb86702440cef39b136f09491398c313d2d8696d268582cadc5ad2df883eaec5d9a6c72eecac5fa2358745988923db4f7d585aec6ecafd99015b41fd0c2e393d81f081665b89158d5f39410969ae340685babfbfc2049d2fae3a3e76fcad774217616dc9d659dd46ea19b43661991db2d885eeca836e411f7ff34c034102160019910e831b48f54bc834c59e19962e952f6fc48077fcedcd2695dd280a687bfd30200ee1aa37c8448a0c56592691e48d459834139723e0c74c8bcb420a655a3e8d01f27b54ca76e627b8df283d809da70153c5483cb63e9801cad5057d7d1e846b512f6efcf1fd9b8a00210dd8cfb2af26287610d0e7096d6229e759c87545c77429723e4b9b1cdba6d30f74b67e46d8d73ecb0640e483c4007b1cca60ce7618a8bcfd7ca907090b16dd427fcfc114f471bfa1d20c8faa9c1d37bc9d01bc9e746a58ea6304698e5c5cc9faaefdb5e0af3de64831f63bf00451cc1bc4b68fcabfe1c62e029ccf3f9d82edafed7b461a2adfd28594cdc9a18e47af01d18fc6c6154cbf9acecec1d4d94be7769cc7f00cb771f49cf6463ce00169763628784172b58858c64f2ae55561ac55372d9c8ed559df71f0d0449495c81f12b77fb3391c31cc647d091c59c437387d3e0c54b4a1d3cc93572d6f4b942e41c83f67f8ef69f30fbf3216acf155facbed553df092374dd21211adf1331561c033774120c487b4f8880993e186ceb209eb0f2ac68b47612e1b83851d7c0ce61f90e669b2e3e364659c236871ff0ff5ac45d51904d0bb8515b40d6cd2c2f9acd54917957ac0dfbe845c9e9c915a753c5c33ce3b6ca9297faf3d6c8f896c91c1a58492b36934b3ad9d0e29898e4353a958e67a98c8c5a5d29c5db1f9f28ad797380010600a83d13176b3800a36f1776b94916e4d9b2b86448587a40c896b1e266c4648e2ba99176ba86e42b251df4d19ac48921d7283c834d02be558bf76b9c06ea22fcfaf6a8f7a3540c46f73a7c2d19dbde919c49c1f6f5ffb217fa421fe838393009cda0d358f2bc242293f1c0268eb2cc6a534196bdcee5c5358662e5ab1db400c9441768d050bd24ecbaa0f426f437e03b94ace7124ac2d667106dc9df2e05923249cd50e949efa52ce557ad99edef7ddc48831be8926dbb9d63299e09a350d4acdcf7034745fb19310180b52485c68306ef97d896f010ddc39012ed162bc5c07e5b47d2fa307974227a5cd3ea77b1351e0913563034fea7429e3f0aafe13a349e4ea1412db71df8200fd5fb4db617c34b842bc1b500a60c53153893bc8c74039ba79115da275b0d949c9f4c90521b9337972eaccc7b2c007aa5416e163665b51d3b22c405e61bbeb2465196277331caef2092e6f155e8b4ca1a8fcab8415f3d73096f305cc4502bbab3503cd0e90acebbffee6f1b5d5cb12c8c37cabe37e2ed497a4c9ca3475bb2a4c285638979b04adc41ea3405475cbfd9afb140bd7f899c855547b425dee813824694dde1038c6f22ab98cf4ae5923ec5709428eb27eaa863dbe40fc4ff665edfad82effbb1e811a7fd2141a9c46849f63063689aae5ade2d51bcdda66e335856cce2e66b1385d372393463290cc4e9a9490bf7843ab38953d2ff9437eb9d27690c0cc955b9ba451ca57a628ccf47709ae496133c905cd751494ee9a4e68ac14618c51c11cb1e6e0b83a90547542073e137bffb261c59008a99f9ed693070adebacb8409c5c4bdbd3d27303f4477e9e2f4a1cd4671b03836165a42d5a18b7855600ce7183eababb78327e1b097d06df400a421d9cb6afc5d5c9766e943f4f2c867d4761d840f4b4e09d6cbd0ee7ff11a93d81a7b4103dbcb8639c4e2bbc198667a3af4413f0fecf1b029d757b60d9da83476a2ae7d4a688b5c1b249e3b0ac94f3b97d71b690398ee64a46bda2edcb2981d1dcd227cf429693721c9efa560e9fea303ae39671d1df9132ad776aabecfb7866319c38cc495ae9568c30100ec09e02cc67353e868ae452f3f8683fb73a630ab79ae08dabb7ff4f65b683e4423ba5fa1abd67126c0346e2c80c77f0f634ac16539f8a994cce7ea77e7f3d21cf518b871277fe1923105b6bb9191e50595aa81c0604eb3c57bc109927363ee99f2c4db9ddb7af2e2bb166aeacd4857962b18ec4e1af6c5398b7e2c97edcd1853dd1798e86900a7406967194318f950c7115b2277443e2daa6d1c028af35fb91d7268857122687b0fe6a8b21c962fb1e371d6406b390313748dffac8394ef2be8e7a8a5409de1790880aba4d90b33f9974800c05cda41e21d43ac572d5d9dc1d3d301064d20acf204e6d44d8a6217b63a8c7b095cfb5088f12e2821d6d61719d13a82374022551b8f6bcc56c1b502b84eb9fa0deb0814eedc76308e83c3d2e493c2cbe96d7ebde5269f457f3511e7efe6aba1db8e6b1a106ef1f64c5845d9d7cf099e5872bfae2c9fb752a057057997ca3a0a203e12308d67fbfd4ae34dd9bd03c9fbc1184e3e866f7101569c4357808242985f5d793e9ad5cf91b69be5817c2f2d4c8f01757861d62f4bbef7bdd043f8f8fe9ee1fa8477ac2d2da62ee0cad16e9aa10ea8a989c909c7c5e48dfd7d5e500721d07a527f4f860ea3c92b3a65223646357bde4d1d111ac009c065ff50e68d6974e32227193e0c0dedad1e35853ef3761b1e029babd9cca9af399e0061643c11a65c42af84f2f8e3f38aa69d045a7f38cb18302b5817eabe5248a8b8a0d5d8a3950abe3ff237c4de42d16d2c614fafe6f3007bdca9ec0d2e57a4e82870a06bb56bbf3c1329535beb2c1773e0f347607daf93c2771108fe77073d8abf04379c17bdd89f3fa896df8890853ead950a3b40b1d200d72ae57b999796a75e3aea310c8a78e7533ce3b9467b9b0ccdef0c506464d5d1c46b7ea7a4d48d721375d5eb1b055dcd6c676562305f499efe83791985f600f54dc91ea511b0a93baa7e73b856ed206e6321a3df0386b1367e058292818868e4bea19f844bd6f6eaf38896e568190de16a487086bf3ac279e482b0913d5a2b4c7d0641bc48ce918d1ba6bb1c7e9c0d58a0eabad985efa2cfe7b04bb23f5d800d0de0ffa4c6c5e5061c192d4673fb5dcbee650739aecc817c64792f6ed9a97705d75d475b0a908aade2948910662f85acba260d617191717bd2f8326d92fb1728e93198d130b6006c25fda320d32351f912f832869a9a6c31af5d04a038160b194a0480f692195dd948f07b848ff42b3c378898d22b7e33d4f8e8f29a083ba70a5ba7be9372ae7acf753e42f5ab88762d25e0810f847d7b84e5f73506562bb5c6d815c74b84de897e8989dfef4330a7c0d06ab5a52fa8fad16913d2df9cea779553a35c2e7f41c6177108fb31fb5bf953128530674d1d37c8ad88b7c60a051af84d8437a9491fc8ca0311e78646af93fd18521f3e609387b117d4c0207c35d0efcdea697cc0ef4c96bc7cd639c9fd21619209f11cf635a92e17fe39df11cd2a0f68d87eacd8967e5a0feda6e7a7b18ebeebbd82e5521f98aa9f50763b981c3551b22762ae161805a1223a55c5e919f2f36b4272c0bc229fe64781a91a46e0e96256754f077e090855b316b7c336060cdea31c33433a5b1c6ca7fb66a2ed8ab44a8c6e5196458403d36aa07d1c7f0d678c632fa7993b20b0880d58e611b801154ded240fe3e649f264bfb04bf377d89d5da43e14b07e113b3770fbe69a3ffcc863133f826537c62f555f0ce22ffc9d84326de3592ff116399453711b6978da7dfa4105a5c2e7518740990d91f297002b88718ec311988a157922a7407476925ff325bffea886fe94e54bf5a993d0d9ea1c02c81682ee1d388a08579d75de603b53f57e78d5d53bf0c5927ad7891c9921482b5bf6892c995e6810109197b42db6f3e2e72f8563c989a865370f050b332209c40aa0b273d0c923bc440dd7c1708ddb98e1f1a3174e25ca082a96607728e86c97b666696c4e776430f37f5a754ea6f5a73648f2462bebaa5167c23ba80065d244cdb18b10fef334d91d1969d8ca27721b25e90b1233e8b44b8e4894912bb698b6d680d5f77dd81c4c02065586147f1be5384c36824d550cce5194cbf1c42d3925fd0cd2e816ea209b06bccbfa55dac3e78ca5a4be0e3f33181e3c6fd9300d9031608c73927e06285bb8075bd946a51785dd4a9c6d5d7e7e32768070797707b9a70d45d5d2c74f1f708d0a69eb50c231a501c6702639cca7f5c09da976f8d914230ab5c5ff788fc1e4a39481a49d737408d115a534c344c763d94b459879174a05bc8240b439153b372f0d516f89da1a804df2b65a78611da9d1ff922afccab36b82f6eb30e6f850998fd335afb9d29e4ece7709b55c7f7bf8f5413a0cd236e3edd0187dbcdc9455eb35bf0bc69d785d5141e92c219ca33d09d64b4c14ed0d58d9f02233dd4ced9a379993c0c8541c35c79c1af4e6c60982dd8cb55899a787534a69c72c00822bd0df36734805a65419fa87c7103fad03264e11307d06e614c1a34aa0884ad300dd5e5308000caa68e812df133ca6f14a8abaa185ede3ebb59041f6c566af611c46d5fb7d2b24b1e0b92d9ac577007b8489e6f41927a38fbd5b8690328c73b8a4e65b65c3c01c205eabdc3207c167e07b08b88a2b7b26b01fd1725cff7774df0920f5b76275d8fa2e0d9272494260db19a2304c01aa9ecbf699a21e7c3f6532cbd6ce926fbd4ba2c3a58be347304dc97f99783cd174f42e53eb8a9e2fee9dd2a995ba554d7d4e8ea475725390888cbb95119d9012b2eeb8e64f749d9783c902ea548d2bb17160b0e9c34ed05e1af04ae9403d7cba9588b0f8eb7684796e4b04883fb5580f6142338d970303248f4af43fcefeaa420f86b4630fcda9d6bef478c15dfc0fb2e733f16cc0848d3660bffc3443543c2c15ddd13e7202260bf07e6070f035cf4de1bc80a33ac174f870f8c009c64a57c4d4e34a3a62f5af16289c8a69550c1bbc7ece2631cac9a2001bc1400549b4138a051ce3c0f654e360fd2c0dabcd50b0b7da3bdc421fd7434b0f43cacc242138f5486a040a41b465cdee75ee1b27733260234e164e529d10e187ab413793dbc35b3a1979ecaf13528bc6e65e358dcb53c725de6e3d370aa58e04f6993298b87adb167187715659b2e85f755dd0648a3f3f5f009cffd81647764e134f8f32cbafdd79b00764ec24b02dc02c582b23fad89c39ac54d531bece98929bbfbce8c08f4adfc8ebc0911c5988cb0df10d8feb99ae89fa8f77e0fad3a8228d2299db807a695632a047f8457efb1e535990aeac15be2d6573cdaf0f0cea54c7f0baf0d5280815c605470119add45f0ba2cfe6af5c18ac63c75377891f458381eb3a14cb4ba9ccc397c67584e41a7ec17ee2207d48dfff7060125a1006fb1a2096e20e94d75eaaa0771c567ce85aec684b405ce200cf429c702508b899c74eecdc95ee08005d0fe2feee3b15b07728535421f9ca401a27336aec80bfceb6872f72865b07b0f343909ee7457d4a96142dceeb161a727d23811c0b71b986bcd54d17977f1996eb6b293b896232303aa8200c3f277cc5a79a465e127647e49134bd2b47b7c6fd1e2ff863dcd29d77363deb15f098ba98d8ab34060ee7b3ee1e16edb09f83953dc9d3202763e673a0653aae4a5006e39edc963045ecdbab1495c2e44b36dcab62694f35b99f3552ad5d3af077dc0f040ad48206eaaaaf22020dce7f33153a31f1f1e2cd3d6a85973b15f320ea047616cf67d2007e6d0e8b924fb660fef00f2451bcedaf860e5389474abdd8f06e40c1a7ffdeb8dc6c189c1fb6c74ee7a0c726b4f86cbc39ff1cdb88584be247c17e4bee8a1baeb82fff42c1fccc3efc857047e721870338954cc167473ecec22a7552e3b16b7d7da5b82189fdff58b3598b892907ffb496f919a471590b04106454b22e490a7027e449ae3379193e4670891575e9dc661796a7063ff789883ffe7b9962bb92f4ed55520a14acdfe49ee9c563fcb1cbc006097f2a2da17edc7a04e07d17137f3e483d29f0ea420143c9c43ed173f52a292aa941c611f9f579e0282501e701c5fdee386bfa7e5b12ed140bd15be54913c94d358d95405402762f0c4eab6e2f2c21baba3bb722887ef0ad7eb5157ff07b865ee2525f27263101adcfd8e7c9369304c8c2bfb4de777bff0387e31361c5e28a65ebd86ab835e89b22c67afab7c76e7be5fa8cc787e40348607c3e0b3cc394e1453d098fb14c9e8973f5501d72077cb3aa1f82178b461a087430fc62f06163ff6411eabd8d7dd19f4c6ba6c274b1b1b016edad5c87f6fd16ed7267d70777ef19b19d8d40ad560d5e1739eab8cae4792a7b5d89812ad88e7c475a8459d69262be10ec1f91c3af1d67fe77a6fbf7f0d4ebe6ef0bd166de7dee03761812e2b1858fb944d7cd5a22edb8fa5ff83fa1be9c5ba8b8e549cec2505023d195758713388d22c7035dcd4354d7aa33767aebb2a2c587b7f42f70e337791afd9547af8fc8c4bbb3f80d2f36a96502ed3e965fdcb566fea2c8a2253690b9f5a3801996887af6e44c10340469a7e4149407de51ee2e9eab83fc854b5612c13d0140c2e4d01afa309a353d007e0442283e07ad6fbbdf2507d9cf056ab1de56c919c71823a43ad718a1e45221dc2ebc43873db969d036e0950df683d9d3273c08647089cabac97e551e043fc87ee82edca133daf03c00070603a4fa91280d6c0366f347795597334fb68ea882d87ee1f87f4d1a9f638429c3a75637d78262143b10903ac4123bb1e8e36a56473c15d490fa19066d17e9c45aac5c838cf4c8ec5ca20208553c672184ab065802d4c959d3c778ab4c5d1bd93f5fab5fb0e5cd2d12dd21cffa1c1bee77e29327577669c64f005ef8fd06d8c3a44e0f032b233c7fa3fecc6bf2ecaaf87948e82476a97ff2ed5a830af9df585ce74a097dbf04e306ddda7926c2217eea6c8daaa92a33f95799daace88acc0b9aebf0f85cde627d9a58c003821ceaaa52245c59670bf8de4190600af0283af4d86cfe59a8c7f90edddfbd9ae15ea04021f3c0b8bf9259f6cb9a454847708755e370094511e715aea178c5d3ce2fb3afeb3456f891cebce1ea3e768a49afc4a7f6828d8036513cd1bbb5d07a327af24af4c7d8daa816a3c1a9be94ed60f70235f30ae3f3df0e469eddcce81bd2c8473c1f8d3ef02ee93f93367e53ecd005cf440cabf0203c08b06cc135c0e892ea47e571af10615223522013ea483b35137b6c8eb492810c6fc6d2c2dede45c22ffde58a3902cc5be61cd95100c3ac9ccebce100a3ec1c315640abbddae20eecdcb04ffbc9c58b7be1c60a40ddb15cd640b1b048b6cb462bb1c0b055d29a27d1391f7edb4264bcf52c7c9a9d4ee00e8da32a0b6876e82b11f41430552363e3eae4c4435218d95a09deb2f576df0efd71b34410df5a81ab656d6508814cb4702e1b0ede6fd08c03d1f1499ad31e046632a0472d03297d86444c3c6bfda8a4b8bdb748c683edd71551b1e28135637e064f00dd2720206e471813d9908fc5303d37916a54fe4509790419baebc00d33afa6aa037eee719b95f8eafe38f0f1267393fe60c9c8a1ed911a1443522edef65e21a9f4d90068a878b7855c1d50fad3ad9881bfc14ca70c4602352e27fc991ece95b7be797939d6f2e79e94c41bb70c2cc7e7433d907dd7ef882f38ceec0a43e648b072b19efafb84e60be3f5ee478c235385ee3fa59a1d6a324781a1b39fc67c9d1a956163e20c2fb873e057ca0703f6e1dde9acb60bcd2668b9b4a21763feac09557918ffc4f4eea0a4f0d9cc44eed83429381337c8712718eb9a927ce6cc0293bf836cae45d535a45159196d4839700f6cc604f3d2d8c584c0155e30cda8c8c01717fa0c7e5d9984c4c14856f7767a6f730538e669de833de781c1b271fb9a232d15700145b955f363550b57452a63da8dcbe91e46a1216106cbd184e90eee6ff0d15acc2b25ec79a74aa4f71d6b3a5005fedac263db7ec10f5071ab64bca6b59eeab8e7e035c4ee68396e79c28f6cd911798ed0d31fe99f342178078322a49077089b0b03864874150a5c689190c20ff20d2022679d1fa1c6d34f62e26ce115cdf2599e9cee7c1793f4dff71a43a40a56effee4d863233d7a6241d1fa82146042cca02ea20d2d1602c6eae8f158c5a0a60be1360dcfee05a38f682a99749ef3ddbacad74a9d813a1248a4bfca18e199e164b58a4e919862a287aa91a63fc07f7a07e88d0bee25109f496f98955ca29a89738fb5b3c33a96f1d3ad6b2ee027dc4170a339cc9b6e0713b9bd628f098fbbfbcb1a3ddb9436628998e592f72548ca331cc564ef923f4d834cccecf4595071a8c235c1fde16ed8e6823b9824be2b7f030fbe256b0dc35f76eabea2e804fee81c82dc47e262610a7697e2a5a4bce754320d4d44c30859d1f49b848b0403ac81841b9c660718ca144d3a039da6e17c39375be90011f2099cefaa288f46623856d77f6587688b8e38a1a8f5c204ae9c2d88ad622e89ba77061484eb283625d18aee09a88d852db82dec238b5803ba6a9309297e2a37ec457b29273b2be5218752f5f77c2b86e755a05613055ea2625b407018b5d088328b92e49408263f8bc8fe4ff2ac70b06d4006baf4c7afb1f389453574bd72162b12cc8e7f173226d165af8735e024371b730f4674135335e63f0b25d131294b529d9db250a9fb84b16c7373a116b8c16efc1ef63525e89a9063e09d8547781d7a24126d23bf138049d621daed9bf5b70e522760cf5816f23b2031adadd6ed6378beb1d596f3f7b6c509eb57dec36c6f78decc1c7b4c1eec68941ecf57ea3d5881ceb14220d00d948b310348ffdc03557fb6184df31324ff5504c56f22f8c056410f922c32bc1990d1ada45aea152e8a52aa58d591da4c0562c8aee15182408f5172f8f5a35675a6776610ea051930b52b39d65da2d341b02fbcd7e84508cfd7e0dcbb5b4054b936d41c91948b89c00194ac8f23d087ecdb4a508ac1265422edfdaae7bd768cc67fd19fe75b43f70a8bbd913895cd59899e4f020a1c64ef2ac2cbe46064637873425782790c2e5ced53bbe8e83ac5f56f15de66ece8a748f15402bb7d32bd70246106f97f728e36baeba596034846168b81921bf21f90e3ade509bf411c9576281979e61851f85e5afbb1b5f591b0269582223dd51b073ae5106852a4dfac27e953fbb4fb873668aa015113c7613d56bc3524fcf02918f95fbba16661198676028f3a0229a68883a6ac6c8d8c77e878f73fbf84f54c5ec37bfb9f25ff0aa00f76f9a96217d21a23a3d627edeff01e39000f644e6bfffd25fd1cee1f1bdc3de6bfd0010708781f28d2bb777de718c22a6c5e4c6189a11719d2f24a18b55fbd02b3db45270d4488aec686b5f6a7afdc2d132832f6b947cb6250a0e82204d31e3933ea780b8e90b4238a3ceb483b0ffe4760b0abb85931f74f3211c33cf486ad7c7b8cd71d6662479c8487b6b92bcbd9c81b3236b497911f132d8566d0a07de0f8e6cb0ee0c80bbce90dd211bd0439d123506de95391bdf26379c641d8e577281d7719aea805e5a0661576ab69740fdb5b5f578eb5ffa614b586c7bbacd7269afa70ee2abeb92ba1587c5c923aac7b87512589eb92d1bb1404c9d1bd2b4c20da610242f4043a7628c21827249f6ad51ec799c2018f0a6c3c0b501008f14ee6942152f843569b1ed03d866d0945e3b9fb819e4438006513695915a3035e1158dda51a6393f7be1ad08ef88673315be260c55a88e24a89dda96c308afa221e0a10d08d933006272088972d2dda687f27a873311c30a3de6573ae3561e996e4b0b688e29e6f40b32f9481d70fc4074c975633cfc71a966f0eae175e2e74e3026fe4c9bdb1ad0734061de6d7e0c52af17648faff0b7b861f19a8c50e6fee04514f4e4d2095157f5366ab71a00495ac353a5ac6f6b0b0c56baf80080356e16786042c5e72dd5e29da871dec73e6a1f68148c7117a84bf6cd00116143fc865b4d431edd449b5a2963e9748e6d88908f7909318cd48fbaa201dc64b87d518596ec00372cd3638f7fc326b623a1922db1a59d77be8148428281aeb063b60dc8e0a91df3f2a49d2304575a5f6d9c2cb8e7baaecbf6f5961d3117436a829a43620b859a8ac4de1f2e79f72e30d08122fd0ae2e3447e3ce626d4c71f1a7a7c126a4f55ad6fd380ba9e99cca42a759bae5304d26f4cf1b53d88cb112269b547d035d482990125688a3082401a8f1ce8e3d20ebc5517888c4d180d44c5108ab013f55106fe1c8eeb4f4ad70964ae6dcae3b82c73fcbddefe80dd4280ee3818bd4ae4bde751b8a3a0747d921577ad0f7936019f23378bf850a6501e50b19344e7734cbc462e0f492c2d36343c13785988e617429b96166108c12920791a3ef18b7f5e252631831a9bb7664391a998455aa7d742fa6b49fc52c7c759d63e36152ca18c6ab846148dcb351b07606333ad7668a6ed69f1d6acc9a6ecfaa8515845469a426d64dc7483d4d90b1e35e14386036d680bca3632e9403f385c2b463dca9799a3e57cc31fe40b633744bf5f7cb818c5af7a8f27c9a4d88b7daea99ba1db01bba02002d2bec3075796991db30ec1dc2f98929c0ef031b7446206c9454ad111226f19614f391eccad26ca805f039f6d3a4d712528a00408045172bf502b5a5c90488c4f2c6356061f01ef33fc04763c086600e37b65f581bd24a27c9b39a7f0c71b9cea5430e36e091998b19afed0741a66bc5c06089689e8111aefcece76e8a5c3ae27d1913ded3d60f17c989d019146871c37bfe619287d227453baae9b2020f46910b821c276fe3266707a64679050650a22e2133aa7a0f16b34345144c4ae87134dacd0e1ce3abfeab8a55a7f9827b2d0892a369d4051bb0c3cbac10d04f254f0215cd1cb4438293c497cd186130cf701ab42e94ff165ffc43310fcdcbbbe5fc60a25a8546e4274199d30d213708a60f739f2cad37ee467e370a3d517bd96ff405cfe44406081334a00ac618c80a681892d6c77852a57ea8ea3a0184b8891f25277d80e941b4fad9b3959fd37e1b4af560bc46c08c868fad56c0d58baf73e6466d959e7fa4047aac032ef09550d0c748b045fd1799dd0d5a3274c272c7291af54c621c1d35379f8b17b5ee8ccfbbe94e88ce136c3d990b9c0e2e7b2372080532e836a6340f730e95dfe9d74f031fde53835a19943bce7b52baeba50b8a2111fa65be1e97b5b46c3c0f2d16105a191dbb0ee22cd5820c28e8020bdc2cc92b0021f5bbb78e8d5b1045b43c482107b6cdf2d0dbf8f9ba124e761136e84a1ce9b0094d484fa620957fee615abcf8441348e477fcc64bb493316b0984de66e4d773e620a22dc8919621606c78ffe63b4d3db468688a05d2c5060305e203ce78059c49118577d4548c462680702fb76910eaff70e27419cdfc7b1054d1da93677efd4ca53a0becfea6f2d33880c4c117e2d057e322a7608f7ae3323eff09622bbe1430ae4eb25f090470ed5684ad9d119235ebcdb3e3c2724f2acb589d57fd55feb38c51f5ec2343e1305a75e0660c875c17f820675af3a382e2c3e47e5347f4172610855131b863296a1f0b887fea519a57bc76aa6df23d7fa723d3a749679d5f599c76d130c9f97a66f8d83313ee7c0083fdf5caa5fd459a72ccd671c3d54cdc681cc82f6982ae84989e663caa45ae7346adeb36bb7abcc2736b763c7d827a97c2f701992f11b90791307ea793daf7b20d0b57aee07b39270aa754d980a0b600946fda80db8432f6dd1b420ac08242ca0196960d12c2a00719c1ae439b94d43082d2624046a2fcdb36a93826956b827e1c2e6ee8aef4a5c5c2d5442252e5fded5a2fdb1715943b656dc2e84643bbd1d7e85a66d55d6678c1314461a71ec7635e8f94acf22c15f903c2fe3df71203d07a2bcb2b58f76d9b74f5ee302abd2a0cac12ae0abb0ad118db49ee5632a6e3afae38cb07831e5fd6243aba101d532e58c70c5f5c4e6f9a30a7600e75254ffd463fe55f947ca6d2af283cb5f3c4e7cf1afff93c707c4d037723a2be99b4bc39e9940d1247c9f48752772e23344cba813cc76b9ef7dadf50b7f51e76744be74741017857c9357cd9c09910f34ac55caa1b5a768163a6ebe8b289e315c090769dff8c983ec2d66e65a8b3131cc81812d8336c5170671867990015d7d66d12ef26c17c48d40d686fdd8bc8c7f07e87d4dbc7583a7c3fc85ad396adedb961bce0d497c2384fc8432ef0ae40df9b45d5b09e811a1aa5152035b26d4f396c54cfa6661389b37ec2a48711c33dc258a1f53ae0281633a98083bb118a7508d114fd003156cfab92284225f7c9f2c46db167386f730d7ed1e99508baa14c300e337013a6633fea98b4a52602153186d869acc0b44461b8face84c3be8e1856d51b71f38908bb1e57b09aabadc53ea2445fdca47913840bfcaf2d2854a0f6a18adcfdf0167d4ccf450e4a891e3485f6c58837e983a25d310392a5ba70acf99ad481f1f830a3b256ccbaee8b8227a35e8a58b28dc0d1da29a6be70ff16734d580b26606c1bdf3afbc7d2bc21ffa79928e43bbfe1ed7fb481db9d1b1cf91c7d7abda83ff750db30fc7e8bec7cbfb369cb36fa021e943b6b47ca28c9c56765e9f7c61e5d5110d898b05918bc778c726a64ccf68a60a4d446e104a32af659fe3eab134fbb3193f83b3a9fd39ccb32f2e2dea2da23cf9abbdc8f15f224983506056f87469511bff2f01b18f25c9228f152fc2310529a28c5553eb71a7a6801aab79a472f5800c4608be08b59f9e7152e3687309383a2d174abc57ba9e7267c834e657d741e73709fd77f76c0289d568a7adce14331bfad9a0f33a4ca976804efe23db5ced0182e968224ce30c924bcd082e995de57faf2573d4fda0ed66eb3ae0d759865d4b7741dedd3c69981fa17dcf3b8ba773bfbf75cd2445f642225fce3203d24f965ddda233fa41d66710b6f154cd4958f3a32a819881fc2ff1ca757d3386d408db447a20b68774b0820074fb97481611ec3bf3e264b01481fd107025c770081994c532457386e1dde683397b8f28d8307af81e240eacf4ca8a513044dee4ab9ae80e89c23cddde6ad871345553c3cf5a80cb29106d71839d1085a4b710fbdc5bc82c37f033d2be65661c56f33cb905bf0c12b4bd18c8e6f786430357e35daa5693099d67aa69c036416c37519b933c37ffd02a5f63e7090771abcd90f7d9e01bb9a3ec919a7cfa5fe38c82a80a59f5ad1ada62613959a2c1f3a7a0b7dcc2e5a2a32fee6e3a8f58eacd2d840b624199f7d1c640bacbf639708e3c9025d19c9bfc6794b5c0bd33aea9a67d79897e8c0e48f2854e44a3f0f6a9928c3ae400e01afc26acbd75282f76e5024b7af66fbd3097f6081cc020d62773e03438bf0d1dcff01f272f36ce1de013cd8e10b1279a375dcfc95bdb1fc8361cbe102636390cea7808793be4b2a13744110a504731e6dd06f0b740d556ef5891368763ffa4126389fcc256ab8cb9fe69d47493a615559a3cfbb059f7eb8e1d77859acee4b6c48a401b60123d4ef0296a888fb67afacb9cc5da7f09a912beca4a62b023f10b3b64bf9e28138d9c01f87c3757cc8b3cfbaac6358feb11cf8fcea8515b6268c34f672a3e83de3ddef7f2c5b5488546d26108b28e01074f50f180133bf2ab757ce0aaed3793727f2e987fca522f29e8ca35ae335544a7b9cde7b8013cb9992d660560b5e3a603f48907773a405e70f56685b9c36504e30181c096a0386a98a03aec70705033154efa3aace2c4f39474751e3d34b084f692fe2b0069179f0446d012fa9ad591608cd8da48a7d9c3eb06721fdd00e020618ca20c2e9ac66c59777c38088cd9ede70eec1ecf8ceda63d73edc792cd4414360d684bf57241b5d2dc6b81b5ee4956a6313fdbd41ad6d5e8edd070a21e755d6528af5865961676dd9f5940749f36c41fb8fd8e51b83e8af26d88358526b2ca4e1a2e1bdb7f9d361e6b33dc095d18ed43be423d466d004be044083623d22633eec7af79711f9bf9b8b18b47c4924fa9aed721ce2663a7dfa4bb13f9138e28f91c9d05cd88c698a00e34a80d0cbc402a7abd1f00457f2807404e5fea8e51103140ae88a2fa49d76bd4f72d6152104376652bbda6fa30dbab2c25a0e3417f61c985d7c90af74313fd1da67ce86adcee4955ff4fc502d24b0bc33cbce06ce002b7e5b367d9de5ad44f6b676cf27db35901071670afe22d54c9b1233db73836c4e6ac1cac0090b5c3a7f4b51db9de5d1734c631f49c18ded45dc2652548a659f19baa99a63d62f5cd9608b8661cf7fc88ec0ade0d13568d8cc4091e07c7d9d8544b4b521e616ef141187ddcb9f4caaec7be8d90cb66ec8ac2f78a19c48f7d18b55d596b7e6aeec7c3ec1222fad3d5bea16033b6ea9ff30f94e97d661e922ed23bfb9557fb1742bc36dca6b202f9218b2ff870b64c7aff4acd74513fcb8b1d456c917adcc57a88b77c978093edbdf8a5d4cbca0319f731c8b61253a77077ac2d575cc29c65290174ab6bf04860b8168737dfc9102903df24368f1f7b2e178eb3a0867537fbf301dd75b00070e5715cbbbef5f1164c30a0acaf78ea75b958af893f4cf76def228bc6ab77bb89d7977d26dd07a957c35321ebeeeb8e8b784947a4c5c44c85ee3dfbbcf8cd429f2cdc161c5203aab4b572b63f2e40759197311856661a94e1cc9cd9aca266af0489cfcbdd653a6ca84cd1b70175bd6ce932840f5f9dfba39dcca3b15b8bcc9d7a077cf38b4e43c2d0579de4186a7db488367c2afd8cc8732d7b3dde96a334335804c0bba48fd0465286160129e4481274a79aa46b54e93c2e6b557fb2d2e72de5f0f92079de6b46cbe80af70ddc05dbf944d01ef405129b75cfae13b113425d8444715edfb667ef8228415d7cecb2402405401583d9a714aaa3b8afb9b9b1626e82f85bd8d23c1677f9be212935ca19d341b726495f50d178a17db767ee7b105b922361938e6ef2420cf5572ab2cde3a05894170bb10df9a35a2e5a0d9d5a9078f169825924259a9ddd8cf0b7284105c4ac8453aea54056c6ace84413998ee6af9e2d8cdfe06af335164e90275613a357765f1c55c718d037941820d837b766264d093bbfdc7b703e589a9db324df79612fcef727e912acd2fbc12c395e98c7d8b1278d5a3facfb2093ba0a2cda2da673c300c8747da11574389142f859a588005ddb716964efe42cab10f97dd4a04a3260a5a6026825e1129294e92e7f63388d2923e31d8fc74a34a0a42857e41f811d3c74131ab73ceeba63417c3b902d4b962a476d8c8323527f6af03dd7aa2add82d9e5d21d4bd3b63f8d5508cc8ccd55c07a3e10328ba0c51bcbb616b001141ad6ccff3f3a52ae6bd1fd4ca26c6d2c219c7bf9e79d7a2e3c7ba9257c7b5092002ecd22082564eb9dc786681fe513752b2064882ce7dd52c19c32984ee445399c00e09bd31682a5f0d7b8268c65436ba0d4356018998a8dc55b108c85c25e42587866757b4341222cb7008dfdcfb23e80fe0352dff5687b3b98ef8289650de50556b045ccd304befccdb98564b82a096291f8cdf2760984f3a5290a44e3871e8295d4ce30812799d74142d12bd245dcf315f4b211384f454e489e87a80855f5edc06f7ba2ebd1219103f1ae4c0ece8e9e7b86b196566358b05cc4df733a2ca3e5cab2fdc14807f1aee61f8988252b09f975d591c82c0db757b294e16594f050824badd4fdc72bda7cc0988fd65817435a9cfc5ecf0ae843a427087ab7c2fe99ff5d4f65861a8bb8355a059593c638fecbf1e3a826ecba88b6706a738c63869960964139c3d0270f6aeb4a99ebbb0167d39f4efcbc8d84c7b0935899900a22b627eb81ea21dabe8162c59ef159e27d7df1fc13d46305e063c08e38fa1a2f902cf4a1ef9a9283f950a2b9ce2ef5120a77f313e7e5b123c64f0262a11e2327d243d216cc9c58fb1ef7b3994793308c3bd16c10a0d18170e663db168a09583b91ff6e79fed89629b3d856c6602382e5409d99925aa9c119ed429896044003f6012d99094afd538de684beba6b7652791a8a5cf3cc39ca1b042183b72a4339e9ae4c3196da559cc8660297bf7c499e329fb91e7279aa905c9257458f8b6d393ccb510c8b509b941841e1961a04bd5ae7bdad1b7132039f8d7582d268021d3a9ed91be2b17950d7a099dfe963834521e13ec9a009ef037c908b8fd40e854dd14a69eb2352ff34b3fc44cdd4cfdc9b2068c69794998649b60252d9ec53ce26c30323a7be0a1d9d2e8dcc9241d66c4f8baa1878a66b4c3d20318f7cb8119a5a146e839291b1a2dfb1c458b63f01f802ebb396276b7631605d285d631b0245bbb3efd7c7e23feb5c8456d6cee8430299591b9e3b0aafeae5fb0349ee5408ea192cbb605ca9957d1edeb73c077b7f08c421c4156c966017978faa5301bfeb8174e71731e1e08101ae94f23449880823d054c3666ee2df0d44641641d218e3c297868bb7b60d9d0a92abf6f012d403850546b74f4f85c1a0b4216084a12aee858dcb42edffbac874d5913fc4c19c893c06c9afb179fea443106df3a19bee90a03da1acb91ce8bb69102d4fa1c5c32eb3bbc478b459ab40428ea0d9c4381b988e037b5714621a2c733015a3240eb88844075a1807ab8be0318244ee29076f71d9f8a70c88e30f36c992efc24cf97666adf3d19bea51ee0ec446856ea36020bab08b7a543c33ac54794be993443b9eb60dfd9e55a112f64bd2ea993a220a46dca03c0d79634f6c63396940b1e7b052747d1651306971e7ef68338af2c5dddbcb20bab86bba3c2b43348c31284d9b759c7a62251a47203ade31ce59a9ad379f21f9b8279d35140f3b8c1b02a0fb61d1c10f7f5f8cf8fd72dbf29fe5c51026a557d536d2eeb105b53aea8897aa7a6f0670429f948c44e550a0d914072b73a8014b2010a6188e915f83981895bd3f5a0a3493aa1dc054fbd7f9d990dbefee196519f2ca6883d1118b85ebf42c4c50b655a7201d13516671a134d50284bff0ad0bdb09a642f3c149d889eb587d73424b1a32debfac2e237cc88176630518141aa95eff800710bbe87ba9ddfbb24defd95f2b706d96acb173bdb27c42d9b5a0198b2eabbc80641676ba36470a070db368460d3923af702771e00ec74270081b3a0bd4e043147b9479bab7ffc6c287bb0f5995a3a23f49393ee0dc99d4f9c6368b10a22322cc73741c13e90ad22260bb6e01ca9849e002338e225d1603c0f31949bc406f8a9f5594225739d39227158c362c3708b0ae5132b2224e2d300ee728f9917ced6901cac10590fedea57360968d08e0134e50abe98d3a12acfd393e93a526b6d6cdd88673aabfe7bdec8abd88bd6d07db79c2025e19661fbf91cfaf830f763b38f52a7448f1398926105ba8e4df2ec3e8b5089a60e6be3b649181c949eb2f9852670ad6ab8a9b538aa4b69d0ef48b3b10b06dbc8723b837ccb1d522a7ae506a04b72f50cfa0d8029744da6d3633f95df991d2dfe04842c66a06639cd166f741b5d9d5c794fe3761022f13ccda325af6e7a574a012bc766bd3f88ff20248afee366c2787572fd475d9f2a9ece7994603213016e52f93b13429d82d26d13b2bc0b584a4b19a5a664cc0bc5772d40f77cb956666e67125ffa396f8927a77bd2512bfec6ce210515b81ed8f56b4be8b677895b7e98d3ce2eb7959aceeb05926b0b2cf7c47c32c93cdd464445b4983eaab69ced1c1e33e60aebf28cec6e2f957aa635516e881ee6ef78862e828859161a6f2cedba7422d1f6b35d7c0e6be66e29510698b73d202c52dd1e043800fc32ef58e5b08312f240765450dec88fec10d5131b04d83cad60f921ebd85b7379cc879a4f33ff23ccedbc7787005f55e0cf19c39af55315289af8ae296630e85ffb7b3df5583ef8616a39011bf9e3008e02148d589c904ab567674b2c46ab30be054f9ae23201323e58848f789ee48d6d5f335941c3bc54de838887327dbd702d2bf7fa861dc1421bf8e76bbb4adf1207a43a155ed98cfbcee1cd6cebaf351d124c1bc1179d3eadcfde0f22a88c8989aa9db91cb79d54171d796877822c3bc2e1562a2443edb6ab0a2a7f37a14e76b028a6590d4eb80c30ccfb5bc114b4c4153b94e122fe565db7be43655d8b88053aec5eb9e2f65bdb00574971e4b59cfbe40db65204821fc04df783278f6e99e77e3888ea5591bbce12810546d759d278f5c90ff46e33d3f2ca3651533e0122c5e4135590d486ba75d4c6c8013cbeae0786b06c4aac200f828c8a6961c6cd8b538a82717996fe49da94f8233ad294faf9c3b24ac6737ac755b44be07c2fc96f6b688663dde191507238f2bceac46760f726fae51697c06e7ed9b5ce2cdb499388067a40388f59f7d87e37cb9053921ca5a26ac03b1f533367da375c4a86d21d7249a66257a9f6bfe3ddc0c35af0d945d7863fef070007f71c151e1e22bdfd4494841a7f405a87fe6214276c71bac5a6f959e7439650973e4072467a063cd51174a4373ee278e1eedc3b0525b8ba74abbe0a51bd950ee7a0b7f58503537e2931561179fd81f6620d96d05a1ce12a9588bd09bcbd0adba6a3b836432dd3950c29c582df42872e21225f9ac6c24cc0cc81add0518f518b0745207957b9fd8d4f974dbf1367bdfe6a757b33d6a5507c9ae0bd8483e4a5333d164d88fb4bba5d5280b4fed5edaeefcb198ff614ce7a3cb765dfd6a339b1d1a97f9a3e030d8c540eb64322bdfd77ab8493c5b1804716a94e973faa764e88fc59f9557ff259c8cdcebc62c6630904b0baab372ed174ebc92128aa5f1a316defeeb9768d8953f195a8a08e29185c56dd5624f975ba1c500d9e21e82ba46343579b241998baecd1d9d840bd48f094573a6064612bb4cf730c76199051b14fa2d882af6c2bccfc70d068deb1c24dc1fc5ced0c4f967b5b58408d1e0475d7cfec7395c6db77ef08abb88f7bf2aba975dd7f733362a3b61a1dd84d0af2fc069d688b404d460a4661767b7c6e6ba056ab141ffd59e5a39bb96a6adb350989016f8c6d3dbcabffc3958cd035aeedafbb0f1e6976eaf42cbd8110a3dd8b6871779a9b4d39618158b0876567b3306c12a1027ef9a5c4cf74f486c6e4d4f808d4656625e7c05754a54b499ff679b9a9e37d376f67b15f10001fe2faf3fd9f89a8df44ac7bfa64a7901fefc5a4232201eaf8d61ffd33814e7012e51a7bb1847a35849f522a00889dfb618038d4a35bca21f6a1292a921e0e7c6b87b77a73d00585df2a559aa3061a851f40c4d2d9af5e398a792f09bdd8b72dc03b4f648cd2b31ddc8610fda382040e8a8262ef3100d158888fbb2aca235482c1fd05fbf5f15ed8ee0e39bd643f3fd0963e77669a72f86f04157134a56a59404fccb4f288cdb5dd6182523db42524102b46662d011f34240237a017dfa56f857e732c8071e6ed4d9abf67ecee7a78162ad46393da94945bb9e91291b15d63871848a79122f652cd1311b5fb1d6e0d80b47c27e9179e7fc00651a8a4573a71ec348fa120d90f27041cfac1a3c3df5ca7fadd77b0c1f64f6bc62af40f5e47eabe93e4cbe0e25442b0043e3f55b12fbbef210827b03518f8401cf9f7d2090fe9c889bacf0c3b35bdcdda4e22a0c098a72fe06fada48220109f57d30a56a498c6b5060629f5c0859d98a5a6735067cca06c44e9351d531a26362006264bfc8c1bceec9111b157d582abcef55cb9be5241628dd22bbb92931ab09409f9d5e04f90250f9b4f16c648781d4abdc988716255429a068798c64497d20b22d0e380afe29ba2ffe570c9f2509c434964869e4800366b89bbd3950233276fb561e940276338d5f485953b494c32509e14b7b584002c889fc6cc68a92f262498fe9ec3288d2eea7a4288377af78e6f29a8e2f68501a57d0d9cdb246eaf32240cea76f93145b24a11289e0a143346f4f09285e8cb6d64799a83b307f8ff50d83c2de70e4d73ec80fa8bd6f689e53e57a6f6e5dad847d0c0a1168eaa546215fc45ecc8662427a15e44c356809791542719226eb21977f46c680c0bdef68f167b67af47b7d8bc8128e0d5b1a28e854d252f5b20b081af2a86369a710518a754092d1a3330205341c31279a96fe04a60c9abe2b97d9b953978cc7a12f30d2a0226f8898f7807285da2268f78cab075cba6b367af136caf5024d717a5cbd15f99e441c3afeed3c6f92130c2960ba487250a1538e7e1aeff17ae4451a27d51bc6943a6b1f56f41b27a56c8914944ea48cab098496f35ea1b8d44aa81615db4328fd9aafd9488c5fee59d2046401312dd60b3efebfd18f8f156168025c9a1bd64bd79303716913f754b8f8ed156f617c0bb6c28e83998f2414b0a0daee0f4ee3b0ca936616c638f3022ca543508ab108d4bbd342cc4845def43cb89beea0106eb8d748b6cf4c95c017e4c4a3ac25d17df8f525dcf903650e8eddf931554b6de7544e8f751ed159c2e2f5b82ac46240f60867cf508df4a693813f89ca9d0dc54851e27491527c16f83e5249e4b3f22c2433080ef379b5bcfdd5cbf44648dd9559b52a95dbf395aaec5ab17a56f213c2c69c2bed246f161dc1cda431d606573ddd67de005b2c9dd71c9d1a8f2da9bb7d928d76431b95f3e60fffc6c8a52f4c534489db616f207aef8ace4b05e8267287cc63357e603e2c377b98e2470a7f23c7fe7e86e80df2c4768e64ea4952c696606c15cb24cbc32a69866c524166c55d0f81e3e46fca39bd4e5651eb01c90935ab000ffad5d6735e85005b80a4cd24214a5d6018ea4b858a2e745c7552d999ee40dee0df7ef9a01208c0094b1794871dfb90ae984ab469038802991a76687e68800a764ff3123b3f0da7a4fca4540b379c45a779a0aa9f935336a453f87ec801d8b00063867ba8be5487ba668bc881a6a704154756625499248912dd347e642bfc949f7e801b158a3444cd9f06473cdc06faa139a002c3551667f22136dde5ea14fd273509d0ea69e2a14712b6f151357c87d1c558c75586f548c7b871d780a425c14ef869e8816993695663e226573700d9006aa4f4535aa75505f2a144e2ed4134376485125184b1f73a9da58a34b12226c12265a0ee0b4ccf682c1b3779af32bae8be28c10822e4a027948ac60f2b20d974c32afcafe314563a939ad2d1a6bdd1553685e0ea359defa12224e5eac09504edc2f99e3290860633f9e4b63bd8f6e6aadc1ef4cba681aaf996ec242c3519e4a2fd64d78c9c8de488e96853f347dbe9ccd45899765898c7b2e59ad29ce60d2b43c5309fb2a70446e1c0e13ce58bd58ec20a69911d7655e984ae43f120684b0f702d870c6a92c349d949e9b39fde5c9b62978d4eb8a43f6bd41a996b60af63218ae4403cf764210cbef154efdcf6df34debd58f1b66ea750079f0a97b9368e0a360d92df70e09365714acf2114971e912dd5777d1ccbf2d2a83d5c038001846bb18837b74ce525150e30bc0b079a353eb1b27183372b1ac0be01fa3e7cabd34f92318d3fb5d33e6e8936787da645c29c41fb3cc03a235a85dc4bcfd6b4e98073ba2d51f14a70b65f5e62bc007e76d90b3eb086e91b6bde38fdbe70fde2dde1272cc665b4677ff6f5b6da432aa221ae4217aa11be315f9391895f8c17ffacef7630d64537896d79abe4731db3dc2af978b478f43bc7bae44e06b61f9a528035598837062f7807e51108822fce16e1727566768a157565b7369c6151113804459f7495c46648bcebab6d8e187149d98a2e3360a0ecbfc0b607ac48160418bbcc1864f2845f26712844c931945e73fd3c819ddb145163bc851ce598770d4fc1f1f298d2f32d76709df7142bf3f29c5697e7c421b0baa043de67baa9e14043062b53ac425091b395a975447678fd136746f08f592427478487c1e99e52e9c75c2d362938bb478333b6a3a60d518f8f15222cc17690396145d0d6f8cff859aeb94371b12cbc0dbafe8e7be138020143c1444d0211f3aea1f861ef1922d8a15380ba9b46e141255c15e9e4aa08238d9039812855e3ac7bc5e9bb84dbd3016c94430de1a0d53ca5ce8c135db3fffe2a53e44e1b0f29b629bb4f52fea7c0ad3dcb59a72b569a43bfa804e05d07c20b7813f1902fd2b07983cf9a13fa8655fcfd937344779f21d62651b891d95ec9520a409d2eac6d3d22466c8be96b65512de6fa4f6bc0b50b6e6c48394bfbc4362d3334812f328ab4fb6b372949f6a89a23f8b2cf6a1e5447f9e9a8854f462853215981056e5ac11ad9384ee58cc6e3b0c79b72c800288a01ec4a0172092cba8cdf5df0787ebbb0830296ceb513f491f2cee7e01c5744800d66a7436f01106966c5d9ae21142efa1c065c260d18fafb302f3d46fd7a010c6c546318021e1ea4167b89c43689bb7ecd0e6f6cab5fc5fdc489233b6ca24a210eca212d9245d1edb0b80df7ea805d6564a3ba0271283dc611e72cabadc61848cbbedacfc66a08d84716c35080f97988d217223aca933289717ac1cb605a80f7e692225504f8951b3bb4bd4cb2a7f62459bf2b7c976f4044fcce3a76ac1f7d4bdc5bb0b6c5c2976fc84b5e1047cc41ba48093ccd7b6b23b43ab8812d90dad273891877f558444037165d04f67b00027340f337e0ffd68836ef72be029b6b089f8ac86f46f9403b40cc267b7edc5e2ddb7815bb72bc220bb09cf91bd00828a0c3cb79d11b50e9dfed861d15e38b6341957f32f5f19222a18435d9d02bd3eea26b622a74bea261164a8130d977000d9f7b855c4ac05f6d50d43b79336d5bf7ebccbc5fc42f9d5049035f92e095fef308da00045dd39c8ff63005e488b29f6f7683210412896e631445f1d7fced33075cd402215a67d31767fb5c0eb2edf1df30dfdf6b73c85b3ce93cab4ca9be8c67d9214073e821d9ba578f059ea87c4f921e4fb7e69110ecad840ea011e9bef87ad8de6eea178256ba846b0916e1eb12b724e04014598780899cad7fadd7505c3e55d10919c0e0613af22f526e42ffe9b8d149ed9b1b003587d2f46038100cb3f93b4f2eb618df9f49af6e4f322183db85644a1bd13f333c94d7b4a05745cbdd8ca45a613c6f6708a0d7d0ed603b03f98e95f33a923d2909804c77dbce2aad0e329603fb034ae7ecca9e006104d4650b3cd5f81886f219344af5d823712042a726a88b301d5784d40c67f20f8b1b2a8e4c93dfd5496581505204cb7fabc772f393bb4c25117b5f322247d585cad46044c9c3069904cf25f91af792840dc898a0e8c83df7039bb17c433d929a5919a80b974c4b1823d9140094c82cdc17a800ab6c1c85127f9b7b9accab494194f216763c21c1e1297dacf22fc8f2f8154a9acbb2f662d032964aad0c98de9320da00a936efcba3c934657f2903ba410718864d78d13fc9014307a74d05cdd6d77ca055831f94905073b51dcf0b571360728311f78ea3cdd3ac35dcbe453e28906f9dea726dc6181ef81eb513c993ac531138935a3c10856c9418accfb0314997413689337e22407cd0a4a188778d25a5b557e141cfd5cbd13f5d9dd114be4df070bb01dd30377ef16675defaa5b2634d0f9f97987d9a33c5167e3cf8226c9c2f57baa730d3ea8b3be75ff9c7f51929643a770c87150365b7a15bdad94f72a526ead36c52e26fff75dbb967b9eaa1161746e80c62192cec76a7d5538b65f15af7580513134284d11eaebc2c83f319e5475980b605d152f8b5c0a34be43317ef664f4f00841135a93f1336bc9240fe752d4564ab1d83bdb21aa396d925df00975963088900745b080a8f6ac7217839cc4c8bd65e9e862160a12dc36bed1a7e0191399839c92099c85cc943a8474c0e4f0bf8ea04a10b36bb9e65460cd9306dd48258cd62805136a6dd0b5cbb9def29852689e3b7aaccb20cc32d14225f67be7ec94a1b739ea941455cf04b96931dd1d410387b557f9949b18da4ca7531d311c75b5551b744f20181513e250034d67b528ef99023d58a2431a8e0ac195c3b38c6731b279eab0bda61e37c29974c14ef036c25629c674eededc587df5bbd40529f3ef9b98b7f889ff056904943b07b805479bb1c6714dc8fa83c87a16091107cc1f4a3cb187f15c074e071d96b3f5fac79af477aa3b8b1a8691cfce9784a0bd73eb8bbf9d8b881e44fcf9e8a86f1167a97bc54d2a7f7b447398e33be97fd2ece3f8ced7c835f2aa344dd2a74f6ec88b2b6e177875c74562ab6567182bfa4abeac052b6afd7ab7bdd2fc8d364a87afb6efefd2d7eb26227de664942bb6b6f0191c4df8ed93d3e5d5c1932b08f6234e3a62e1ed49ff07ab498e3417b7920e17eaddf159a7417e6ff63cb6f39eff3d4ff5ca89a21120611c5677c2c0efa2b78ed6b35a444797dcaae8539c45a2c83c843dcfc35f833f10091418bced14e3eb7fe4c7d2baec7ade52b2ea1ed93f351bfe02d4389f51ffede91f5c33f66eb2693d0e98bb59581da7cbe951747105682d232e78f46f578303436c2c6c078afcab31957af13d60c4c31155cc97894273366230e0bedf8963a423d48313e250b80270d828ffa5cc9b50a708a4be5bc2f0318b80d5fb5de2d8425d5de2dd5b90eb5127a8c2c9956388391387954b1047aa056b6c94b13bffced9075ab059ee96ab4614bdf341e80abd4efc7d122f28787ca53ccec0011deaaa704ccd2c4215347cc34da525b4f937188dbdd137df599754d246648e0bc791d0cb215ed9e88f70246779b7db2985270a09812a0c40d4fb92522b8b2155ef3f5fd4678bbd58767fb7d7a5a7b39bbbc7be735d04f61887bdda5492d3a9d645ad176b47cea41a26b120bf9e2c9f79c5d0faa7a164d383852d3fb7ae5171d8eb4f77898f1c82d1a244a3e2aedf7932d4588f267d9b10b85fa06dcc4473a8ddf1614b88445a2aca1cf7e9e9706bd5aeb9b000a0434fc835404421a97a938dd017a82c1826410b590f457b284bc1fe4de550c692b20a31223dcaf1447f70528630b14a19b85d4fb48458f75ca34b478435fb83e13edd79c1eec1de17313c867bf4e00b61b56f633540552c6f0b9ed45230eeccc4921719c470768c45e48c209bc6fb6bd4c38afad91fdbe308fdb24a5df4b28d739902a4a7094286fc968438657e99b1d7b621f0c7affddaf1c1938f18db5ab59907114e60c06a24b861be315bd0d15f5292d0d9ef43215a895f00bdb1caef75b614839221d5445966ac0d030d9a4233b4156d8f0e83aa7860ac7967e167b21bbd7586e4965ac9e6a4e650b0d9aedb944d9862afffc270b5c6792c84761ff155047291402ebfb7d26b906b65c371e07a4a065cca6f8bb7f1d4183244c0c606bdc9ce633cded1cceb6347b3670433a942f2c18a877c536f775072677e25ba9cb2dfe0642d7cf8a9db7d628a69e15d4c15a28e034c8a3f734046b3d09c57e364b0ec4b2ad7bc36dda91f0ae51b0545a1a8efc67d5c13936358bfa6971c14239db16d21aef2944785371bf53c47669fa39a30ab98865b0b007c6eb1095dbedc267a820ba9e56cc3b9ef24f7a440ea970e0899b57ea5258c43b2b4dc02ae620ff65f0c48cf0c044bd330fe86e80089976599c3d91aca0a6a08f5f33df86c8e10abd7ecc1850b3e7fb7946f2dc763d6fb362db58a970cb7dd82e9aa6b81f0fc2f873a204bd35b6d1fb8bd43cb79cce8c6590e1c19e14154b2becb426cb685a6b0b98ef9e56167374979120fc4493a4275863c52bc41033175cf4e94aaa6944722114712cf0f6a571e31cd8144866aa2602879659a307b675f0e5793877b32b6d6db7a2db3058b1471cd270fd99ac88cfc09996f18dda4f9bd73d08cc72d39d8e54bbef4509a2f758cff232611f0474e336a6c42ef9779de2adf6c8361048a39cff98ac3eb37ffddfff2e68d8f1387678d839be716c4af8abc66012702f504edd87b227dfcd4dad71c1edc236beb3308d4a237c990697e194a0aed0f8ec71c140e90540bada5e1c19629d76126b2c858ab6370914598e68c71b026865df9d6043d2c591a2fafa927212b69666cf539a47b3906747d9feac5fc6e91621454b08c0fdb43ed0c0899268e16597986216fc83c79e1b266cad42b32d324a0fbfcd501ec044b6fd181f3e7142969996d0b7f93e6149955e0b9309fbc3f0a4d70a1ae6389c6688453b4c4f2a85e85bd0130ffc169b8583d694d565e58330d125b22d0d961c8638919991084f6d9e96fad1cd844977596160083fe7814ea6d4456389982b24a0ce6a39e5df2c53d1f7162c93d8335bad25b36898ead329848e9b6c5325d4a8583bb3ff00495d4f138f7733816b208edbcabf7a5543fa1764a27995129494895d02de29a10f12db1a7c950de8d31c2a86149c1e0396430a1658ca220a6755333f9178b21af295fcc8f5474e081d83e47975d77374b325f68d8e276672783ef168238e7683c8222e1aa601108ac7edf415980faa1e9f9820dba28d4403e2d78767564a3231241206ca6d12496f30314253b19a1a477e314a16dc8c0223b60ed823606d2a0638b19178a8ae690bdae60c403c76e46d8c97b1e010a485c9f062f0cc4b88deaeacde714e84306296eb837140a8785f9dc6acbb879de001f2517801d7e0ece131774fbb692932c2c92be824928adf23c24a68e7240bad554aa12a44fd5d4efed2d96b4766b4902bb57ec0afe0fab1a2ee770b191efe87395fee284ed376ca7aab68ab2370a6b52e49e10614dea151465a99fd761f89f31392da2d55ee5675918b0c1b0493a83970e6238965149d3bf6d3c16bc093863db6e293f31678f18073938584531608ed6e5a1b11c3b00228af7def4593494e9b00bdb3390c955554a6874267852b4b3d5eb5547fea55f2f77f868bae4ff4b505913147da4f4aa125540f128f9cc9b2e557583e0b1511cd3d8d1a96ad4b6c5d90629780f618e6503356159ea1121702eacddf6094079bef8e1c792cf95fa2822cc46909bc4e6c2c70d4c0b1075e4d9aeaca18d2422c1bc5033c84a2f2911dd956b7298c26f1f17f41b0ec0ffdfa1b8dbde474d647b59ea60903f00c33b44a6d190f388bea577c344c753b47766327b9f7bcdb80bbdfd5b309ec5ae66917998478a3c116f60c389e00b380f9b6a80ba3ab5982be8ccef39e30c396517050890d877c72f816e541d00a7d7c070bdda59408ffd23875ec2a0ab036e8bb7090b7c7e08e83d32924d33d4ead57010e4024df5fe4b02961ca44117c246cb442071c95f664ce7692e4be280d625adc9d3ff73b846a6bd0c8f73ae0a417ee7204433b5f92bda4c93902e46d6349945a86ce54c2b3b96f3ece4d505d971c0d73bae610f82c6f3d7d61a3fb468b8386299edf0f5c7ff3bd3766bcbbc8ab09195a66ec34c41c251ebe3460aa3c1eda404d33d5e910ca065b363b8e5de961ba3ba00d74dd0d5943f23b1c55d2a45e657e9c63833c2ac3e5e80591770503957c9e2ecf8dea6bd3d2c56515a273ec8994cfea9b2a9cc8c27b764d3d230c9af37f03d5ab0a57fec6cf4913418d66a8a92629d34183be83f700749106a22c193416030072c9cd52656c8a15dce2bd12ad638d1d9148861aa9df8aa1b57996af1bd945e52379a333d1702b3ee9bd5e73e993ea99ca998aef496b4b1d2297d329490ad0773e89f5ab38c9f31ebd7d136ddc87f4183374e182d6dc633f9f28de847ba364213c905f323dc221ee8f060e99fb33be1d767afdaf25b084b012850a0c6117e2ad7dc803806a5d2a983bbd3b2a23c0199cca25af2b66dd9f4780f617aed3e8fd8f1b9d73ac8f59415db5e97f14c204f710ca44e42139bd39eb3971e13e9de3f48772220b2f1cc517abe155643f8ddce3bf437dbd5184655cd8f737047e88301ce1587d069dd7f0521e476f29a9856def84c282c3f87103e0a51b9dc997cda9e24890a496869e1c444626470ddef2dadc6a5a2bada4ad2b7d2cfaa7d539c6c738ccf82df2b1627c28e9d729e49ab071459e1fdc2cff09cf47bb8a77c2d7375ba2ca98aac738f18a55b372b122eb19dc42d29aa356fe18e0ece19ad052083ead5f1a17e996a40ecad1a68e683fc9b419b27d8c00439a1448d8482e1029e6302b525070b7b67b4e7aaf3cc6b9ce703c04671c52c98689b35ffeba2aefbb6d6279cd0b6dcc88b9180d2a8e0a663e451ce733850a38dbb278ba4fe9482b2508d9eb164fd37ef25964e9ea7fbc8446b6c4346d51eb234b08cc5fb4e57d49f737b9b6119e051c1b0ba3d6c19c40ce64b68ac04fc9f8a97ef972ebaa0ccf017399af2e0815d518b8ecb4d19ed7db30e99dd62064b136f2d96e66edfc55fa20f1cb3cb70a12868ee1e5c17722654c15e74da7641728005b2a138e9f4b930668ab5163d05081f18290e766d24a4e34609d8b235a4d420dd1b54bb58d90e3b8f4682250b8f4f66c1ddd8dad6cd992f6bf1854a8bfc3a72207c95dcdaccbd2a971d28ff0cf690387235f7203a1ed4febc7e8a69e4e73b58bb264b7c010139df84c80f6c8b63dd277d0ecbcfd8ff93d66d66583d29f778b81aed1c11092868a1bc72e4634889b65040830362cd2773fd2efc38bc9457c8c75bbd110a079130f38d0057fba390e750dbdcaa18ab8fcc679664cfb0345eeda3b2f90f2655e8592b95426e1a91c2a00b1e91e1478d618c3a75343489e00789b311aafd4989291a0f95b05b6c642e42eceb6be82e3df95e1b1725db9c3dc5d4206686cf390f1875bcca454b5118277196222cdf04c5d8cb1c8a23f35844aa329ac10753d02dda2ec5f2b0b6283c4c91125f2b64c9ccc000ed29f756128551caf52368aeca6465afa203550640fad21c79714a3d0704a13e2bec7a89efb63c57664343a3192d43caa2f04e49ee2022e85bce5bd810358fbf90487e8d4011227c199a9c483066e4fb317dd8af46c6187e55b70762e63bdae226802d20f3ba3f6055e197465aefa6537acd2c0dc78c0aebbdb2d4e8b34ff00070e12ffca9748dfc6764482b1f0937080e4111de8b9a400e03590c3ba718e1fb7568d627b16bb52603751f80af05a79024ffeadcb24879fa013d7210ec6b5985e63ece346c5e7ce9713fc40bba189d7cff44e5e228a01952785593b31469b3269f483e48a30f1d0ef2ca75aa2fc2b4ccf56fbc90df8ea4cde65494e49aa01748521a6763926ac71b1ec8c26f66b06fbda6e8b43e43bb8368588bc61ed09c5efa72b309ba37076c0a0a4e1b04ae2fa4c2140eebbf19953639284b67cfe6ee3e0ef1c82f154431071650620dfef846d2bad030e6624b8392fb2e55cb192c43d2f0e373f7c694d1416a3350ad63f58858e5935823efb44ec484c5db24c452080a90cb24c7bc9ec20851b4c1ab90edee04e973809be5f748cef2f0758cf95ba89a71ba13d27f13f2f1db1885a56447fb79e260c56b8131905e9cc36ca676df6b4f7ed31b0f3f7413da720b83161994d5137459b0a6d6f2193ef3717cd14bd349f8c9c873fd594e7c03543139071053086089904502e0e9a41eb1f7f5daea68212ea0d6e9e42e04c0542ec969c7631ba49f3e443aa5c7ea96c40c60bc2b175abbed4e0ceca35945210f22d773b15009d9f5a616dd92946eda518b4ea9094c22157bbe71d4b0371c88e8e9dc0a79fcd14e4ca484f1eb7521c0aee2053d83f0b47864252ee1e983dc92bf798490fb7f2149d5733ce3db3fea3c905ceda983833cc07f319e20eadc69351407965adeb381ba45d80d414d21fdef32d062233d4b1cea905ce29676e99cc79dcc002e70d380e60f388d51acad0c5f778107c23e500d47371c9ca5e596ecd715ec4baf0d630a23a4153af80891a4e3b4cea2342969a125457135710796961fbec09a93075171ca2a98ce2391f02d5c4bbecb530930aa5671ff732d6d330d42eb82dba70d7bd5799b888026d53c5ab0a5d63c97ebe2ee2ac6a7bf3d85c8bb84d481306364d7401f76ed5e040500b462780616bfeb441ede9055bab0e410d2f676e68d346a4e5297b8d3ed0d239ab155728d5e67fe5d722154bc1cdc60f8597d7799987c0b1021a4c82c9f826b7a7e0586079f36d3c184be6796956aeeeafc66a0e99fedf0b6fb5de52c42de6fdc1e6d5c013a43ed71be613ff6fcfbb2164dd16d0c0765cfa9319d7fd0382792d3eaa2f2fe778e949d62a8a1c9aecdfdee82baaffa125b5522a0ed833d06b20aaed71f446628125747db601d03c7314140f8aa2005e64314f522ac6d7c82e36f2a6265467827e2935ed017e610229c13b575f42b2866658a6c36374b975135a37e9fbe7db4404ebf810ef7066f7c62ac1cd8c8ff3c15805370bf3510f2fbc87b34b4c557b11db1804422f332fccbecf0c39fe8571a2be6f35692121d960c8d8bd8b76e2b2430c9990b4f818fdd60b00337ca18d4138dabc61a40d575ef55510215882ab47bcaa44d5a993a16da446173d044a06e9511c83c2dcb63fe08db0127759b4cdb011cf1cc5d68f902cad88424948ab067009ac9bc3ebb62151e3b9a5ef92c99243f1d795d8407f7de18354da2b8c9b7349cda0487e7118927ff53b2dcc54a776222d502092cf93c12ca50910cae16bc8d57bd42b489d87865961a7f769bd325c4a068c36be9505e65500e453d827ec9b6effe16901479d78b74a816df89abc9ca93ce477c3af117fb5975bb11deaf0fec06cef16b86b68ca3f13f7a60b1e4929178d35f5e645def10791c560c8f064e3b8c3bc01ca74bd809ea5b74dc685b42cd0bc8b3994778cd912511cd0850069afa8d23162dc8609c82743ffcec06969408df0452437deb35614db518556999ffdaa311586cf7173c55ab77db58570168c273b829072819ba2c2ae355484aa6fbcdf5a553bcaaf183d194fd8c6ce51df58e0e7746272561ab3478b01145c5dd6a3746551e69a5cb75361dbd184a6fe3b65f92bbba6988cacf130407e37c99c6d57fc276eff14c40b3045862e63e63b5b9fe81f583f58d03d02ea1ba19c849d429aa79787a56ce6e7a86322535aff634a644d359889f0475f8e6b79800471304cbab32f0f3ebb733b325f5edb8da95df78ef6ceed92377486a88ec81b0c37257ca3cd9fc769f23088c3ba4cd3605f77ba308e97f7fa6766dd4603c7738c356e1d7b36f56d41f3c25a083e72dfd969a852fc190891a74214349fb69562ffb68b36aa231915512658c3ac9f2a2c1377712b50cbcbfe52403268c1f401a565a0641c7bb1ced2b6fdc09e4cc722ad83a687eb995598f8af59720d3fa01bc85b4833563f096a0caa683741f4cbfde885dd89fb7b20aa2d7024987bd188e5416825301d86123bc0ef39135c7a3f0e28dad8de98f4e02f0240554d25b5ca6bd76bb6225fa5a08e49244dc9988be5d1965fbef9e94495a6747298d7f33b9b8a84e2a4c9ef6af4b802acac18526987619e09ce86e900b64e83d96ddc3ff6cd375ffdc58c9f346cfe26d2f7b48563c37796df6593b274ffa3dc35a4dba545f20ecd6b2e4874bc55bcda23ef12f39c2d1e7ae8015193df44460618157465b60f6c1c2c0fa5046920504bdc10ed654508c4bee9e00bbd325f6d5deed02c32a53f3296e5654372cee007721f13b916e43657b06bfa66ea1eec0e2afdbe0707a064bb731f5e5802ce3900d8c0603d1eb5ca11bebcafa0bdfd3ce04ddae776707f916b27e8224557f806e17745ae9df26b413d83013ca511e96027fec11412de148d4b673ceb0c5df0d8812c13890d2e3cb10ebd460f9c620e1a354d58a36fa9dd6218ed939b02cb23cc04b087a7d4aa6d601d36f2e6e1a03e5f497c969e1744af136b51761eb3423f91c20b35b9f02bfe6d0fc2af37f68aa7a494d86118295b40236dddfa892dae337cdd2bf1cb1e085deee0d256d723d979fc74fbb7bfd8eb2a2eb4364ce95c63f5b742fb20ff7992cef6f2a22defb1f747959718a0269faea870ab64408df838c4c3edc618e18af691445f64fc382f84bee2f8b46b6285669de8a5178fcbeae44cde5affd52197f54c8ccfcc8468a53f1d66024a870b6c71664584f600e83029839cb8284bb774019a173665ed29f11cebaa0b387c074d6803c6e52bf083a5d2a0715f7f2d370baff7b35de4f753582daf8c247962b1c85ffad6c891ad7d2d0e22daea491500a4cd5a0cb525ac656598dc4c18f8e27eb90f719f8c3f6e7844d2a477767f7b869ff1045f0e6e938810d02a1bc4103d7d8cc204e075e65c47881b10398a570b50961b4cfdac2769c6ac3d388ed4cfacfe9587e5c4e209549684760b9f7d78afd8fcf98ec27b63885ffd7bd74a329919a57a104109562df538d05bdc067cb4ba46ea178ecef47babf30677fbf34d273537726702d37a0f97fae6d17443908af94a4ea457002e89d9d1888a254bba1eb5b364f4c80da30050484b15bb7935a06056143f32895225ac77119d25b735c1cf6d71a71f101a0e0856443170c834b344c18ddf5323e305d9db55f7ec5939c711334dce1d64f44787aac03a04cdbb0156729b40b64ee7e3e570a709b175cc5b8a7078bdf6257a4d434fc332df57ae191e7239899fd77cd598ec0fdf31460d4b49885a68c97a1933aede95cca5614d5e34c4cbd26c372d82f883ae3cea8a31789941f696edfbd6c7525db9858e0f82de4d019ab06c2c7d89a52db13867b6723966029b6dccc12ecdba90843093845bfd5b4a5d859788fd1d7ce6e28cbe9a5b40a8c3d508cccf6361512f47878637af8a7810fe61f306dbcfbf6bb88ea8d7f16d2ed48133c8600660207f4525fa236fd107983127afc36dc24bec5649912fe65fec13941415b07ec3ad859b05a695e7b2791caef5e49d0f508bcfe4783cc251d8e1af023c236c10456058439025a342962b3ea7e763610cdfc6b3a7c96a2b945cf1ff2cd2c835485bff97672439f2a9fcedfced9f106c32b09b59bc60703f6470087f62dac55e77ef457b53cf326127491e571f026c2f8cde2d3604c52e2a45832eb7647a5e2039d0d1f509834ec6e9d60e26ec5f37a2f7053fa29f1de51e47d130e5169de4fd461cfb4b76b8f8595c36b7bfaa07a0896a5b6f466a79f6c5b4974750c7762a8c2213ec2176ecf59ab0cc2effa63b113caf753d405f610b415435aaa3da48d75b2da2bc2d1dc3dc3c7e9a63e3cd6375da722ac5a73c4dbb05ae8fb602e85c67ae8d393b3ef70b5f8eda7eb93ae4aa0f824d540de5e91a2fbc4d25bd07d721e5e629084f71a04f1d67416b7d7185c53fe39dd436ceef9d01241b4cca952c3cb46bc2e88744d153f34c0b591fece10640a87211a2785892114c0f1daa26e722b7ee39cdcfc1c147f76efa76a07a855f3c3f0955ff9cd65fce8e24e9c973db5887632ae7afec037a50e17b02a799f2bff9685c3f5ffeee702e99c4dfc984bb58f51d1658103acee5873bf82cc3bd516e2e85dfd7d3d755988223f79699b9eb3125c3fa95ff5fed1500ed2b8b0cad571dde47fd5feac1b9f776d5c9414ed8d26ec04b2651e1e1f0b10e48119f9d59ce38dac16b6b3a80fed6fee2cc7e474400abc0e5875da4d4c40277101ff9cb3d6564ca8f6f6b5d4dbc93eb17f586283a6c2c33f036bbeae61e8008c62e7fadd92d151a50697c1f23c697d7a8ef38a1809ce5a69f39ba69f017272e7d34e2ad7b7620fa1baaa9e764079928bfcecd5c4af617d4ce317d562ea232a23b1b19d479d083cd57e87f55053c4120317557b4ccda8e3b19f815b119226dfd7865bd680644aaf2cf33a47da526a0e81c78c20910fcb669efe452401c53b57356afd1229afccbb99c9331148439c93c643d72b861838efc8adf50006e88cc8be415b64739d55786d83f641c97b685426640deb180c454e1372228c6fc6167e80e01777b975a22e3c48356b74ccbb399994a6f8e4fc32bd91d26d8f0e78c91d4c853c6b6ff35c18ed93a3b40b71789d0b045299b29f37828daf43d3d1ae705526f0c3d3b42083e847471f66de3cb018c3f50489aed65ea2dda7f8e2511eb6aa12388fe80b68d897db7277644888d8f7e84e39ff78e03bed918b727ad35269335e68555d822eab7c7b38639a4139645f8205fe88349326c8faf2e7737b74c5d60de2aebffbccbcbacbb58df7a5a74cdcbb5ef90aaf1eaafd862cc67f42dab73855011c043c78873f3af0216ce1b2b8032b5c23b0a43e3160f9f0e6e3e8cdc07457c6fa3628dd72b5a150cf3fead105bbe9b841bd72c9d801227a29e7fcb7288f12289c730bc2a1ee4a6878e56c9f4bdf2516239026b88d4a5ab0817411aed08b12dfadbc76e53ddbea7b615b9d87a4cfba4f9ce62f594aff1a30721dc374c2299f390fd4e3e9108bdc4281f85f068b8a832fa9bd64e712544b2315b42d81c3e335f8e5759ca5865a1b45ea466a2a7efa82d7f4d421960fa6c53b11215839e20d65ac47468cfb7fb1f333b25292d54f7842290e8ab22c8363d3212f0b0a165237294ab91c6f58bfc88300d1b0baecea2cf5babc3b6ef0f973a234ec80a7a2f5b559b7d91c99f82e45252e7a7b63f69cb0d278269bc523e16ef2d7dec10883f6a2220b1c849dc731d13abb920d59fa4bfdbb18d8a9abe71e2a31f3ee7175388785d1e44a69fee27a820e5e7785031a05333878183a4168480256406890125fed87ca77a1fab4ef6583b4cbecf1e7b2ff2b604e3860bb679a11e2ddec7f993abf2905e2ffd5ecd9b5711f0ee042f22240af2101b5e29e62985b1a2ac0c51c7cef44b62476410e3976b326db1fae13c4ab4b5f5fa6bc1e20d14d2c83943386dfc4040db1bec83fdf3e7ba7e1840ba74738355ef57a8aaa2712822247c9e3aff77bf59425458445e4a0a92d6992a7d0c22b97564f83ee6ca33931389186f759faa395b644086654bb9affa5301604f708e5f0af2441b269131eaa518572a2272d148d9ad32f56b5ace8dc96093c4def4d2a91c33998e0b18e09cdb1c2a228946655f69277224fbffe10881dc344261664ab005d0224308ad77b84c5e9e7ee7b71cc40cabc7a201086572bdbdb6d7a5b60fd90e4daf25778c7da75408336e93e00dd5f206a2e2de0c24284fc1b0a5ffebb36b766c8298ce231601677bd04476a86efe144fe6e580f904020ac9d228061f22136a093a343c3cd442a54428f0e345849345af104f6c0a83cb44f1bf76dda9ec758a4623a120612097c74aead060778dd39629b6c4d772116b48bbc5c7ed4986eec15465201aff25ec63332beaefbf9235e2162e9cccd5c9ad9a08e58c96d4075488d5e383086d58f1c2dc002ca94e09339fb901c3fd6cb747486cb37fe1f20041f9c6b2ee6cc746d28590a2bcd01fe04a3a801f081d6d00769255e584d7af5b1a043e4d700b7560d405557c3af67f1838427c01648847cb29d05c1693d5ea04f4ec3bffcd8fa938cd6de857a49193dea3a1050ecf5a0bb94213abce7934f31bf644900e9465cf865868edffa4ef92bdba5a16dfd48a997cc6c4b2b6c4d616b4d074c74e166dec166c9a4af99ed5692aa419485cd3d7953e18698e139ec7307b74d8b84c9f94d86fac73a5dcf407a2b6456f4a7a111001d3a48b06a881e15f171e6f7eaf519c813a9264a86dc2a7d7d45c702101366752bf26ac066cd33a337c65c76c93f4e1ad7fc9bb0f0ca43a83ed7cf35fe9ad932d7bbfd79340c3fd8d61f84b8ad4c2cb605086ed891c5fc3da0381183866a179fc955b0cf88f1460e620b492de69d53a151c8d44e35c3d65bdc527f1855f13b07d45bc49a48362a2d64512432c362492671ab74b91337fa6590b739483e3a3484a2c8eeffca75b0461628471c25da07ccd4db3909b85e5a20df09d85ac01fb545625dc9cbdf78806796b5a38e21b812851dbbecd92e3b3594c4bd8f39e59085cc642e6b5a1b2356ae15f4a00ff9cba9e7c3ec742e760e0e4520d9c3c014b677cf5aac74c1c9500b94b02a98a106d0e8357ecc2f2ab363ae0d8c270c9a543bb257f33469b02384bf1a4843890ab329943bb10c43aae35e5d358f97d5a2a8f2ab8c36b86dba276f9fa4e607b04afdcc308850fff9c3eb46bde66026c08c89dedc7b6d96e91bf5fb3eb550182b39d5c89ac7554bb8fda0037d29f89f9392a2fb35c35b50efac2064f9f540fa8b78307c3d7db0a0d292c602f23f873220bbc5a34c2d3b6dad603b50b0934c05a6db27e46c0f85ce7493d98bb7ac56b24c54e94675d5517a5c73616e178eb40d5833d1f021fa8baa4e86160f1bdc8ce0d0ca102dc2e36008b27493dc0436c97d6e2976212f229713a2d33ccbd13921ce0decc6adc61bd398c989b4b37208cca4d57c9e524bb6976d7042811595439f4d58a85d98a36dad3f4112aa44b13601d13e0e97de50d4922c7d6f3508147c93e620cccd4225c750a539c3e482707112e5f8a79a89980a3ac6f993f7926f7ea959970a7c94d8a3b11e52658019ca09c0e7d8a0aadc2f322cff6707a65bae011430323053e7d3807a01f0cf0a1dfe6b2641a0d3e2e63111e29805f95cc3475ef3115dde93d3b0933b2de91a73d8df686730cebc7942549476e81a42bbad9c89a9e21a23c975f09d64bbf2f92fa5db19f2945f723c5e6d825ddbbd6ad9b96dfd7d510f3092755dfc7b759d08f8c37aeb1ab8bd445af960d8296961397e063418a41c36275670e65e10332b7a43088218bd836d5d3b702575a052f31d340034f64a2941f261e537a311c2c56ef4fd539915c0068d7f1ad0145acb88af7daf1c6ff510b76a405644c84babd7931bf1c09855705f2985beab880d6a30bc9e29317e3321726d4e10220cc70747369c4cf71a2fb6fe4c4c8efae276959a4ab33cb909a1ab307e6639cc65641a55badf6eb734199213c440289a37a1d936d0ec9c870e7514c6eb1cc3130ac659382816f6dbfdcda1bacb3b0799a61feae3be4ee21dded12048e4d5766a3ad9237d2aa62cc636a761a28868d1be495206466d1a99266bf9ba226ece9e8484b8c5676f1e1cc2986284aebb60c94b19c531931e2d0c23f09a471755ea49d3d53c4e3e4125db8cfdd7a8a09ee1ef9a7b61db2fe122cdcdfa9b750dedc7c2f329b574ff42d0934dd58db76f6796fe59b7312545fad99b929f4e29f4adf3f5c68827b446a87e28398789b9c98125baecbfbfac1b74a0103bae63d9ada8bd72c8291c22432db0935301e7cc2cecde1ca47b27e80f8677238210fc86a624c34042b68e1589c71df730c42a3bdfe2ac27d7ea7d15ab1249d07c6829bd2a9bfe710f3df6a8621675d990677b2f3381fe1bb132cf352a36b557b608bbb0bc13adaa04eb7c196393fc09f5339afbdc647e8b6de66672fcf9a9983191de3ba96133dc3bc2cdfe9c73e3e8c8cf133f7f46e7c3f2adb80197dc272ec44f95176580b6eabf159b6cf45776244f3e96c8c64825a6eadbd29e3851ee3ae106dfb0ea304b973cd4a136ccbd70dec7a5a6234fba70b1ed1b5a676b78fa5e187d8ffdcdbf9ef083fbf5f0d1e07028fc955efee2d7d1fb0f94716cada0a610c98e68ccf903a4ef5ac467173e8e0771d39e1a2267898171d47365f2c2000e6d93930dcade2c56d3cbfc620cdc2fa9fd29b960c2aca0295fb176b1618cc8352a9b6f160f80d29dc29a3c1a5138d39c97c36c9f0b59a1a5769ca450cbc24067dd65000898b6ff3dc41b19bb9a17548f2c9cfe2b30e4c8b2a1eda017e22f884e5697aa8d89640f0ce10dabb4132c001baf860f070dd2581e1b286c89fa8eb84563483ce08372c6cf1310218027c28e2272e927f46be9c444dbf78e27846f97bece201152380c2bf774aaf6d50f68721f1044f3e7837d864233c4db90b40163171986b574b2b258070b6e8b1284763613d792c257a12f5ccba391b6e26d06e7c5ca7009ec4837cc0f98192a9875cde1ac1d229e59a765260e8fa4807629311d01c4fb0316ba857fe05f70ebf8e0f260177d9168c8c03ba732f4214178f0f8df92a3f0fa73962e6ed2525dcb49768f51dbb442768824163d6fc7ffb059a75f8b8ca49eaab4a2aa3e03bf66f4ffd91307d75c6f1b09b53b29f2f2773c4641e4323296414a83d773913d15f593cc07c0c1bc4abe486aec3a48c1de23164f2e229ecc48a24cf20581ec64dccef38491511f79c852ac2d5457bf003e89662a48cb5dd23871aefe21f155fc9ed8bf6fffb6c9e613f7289c68b3dca1b0ba294ff6b0b1aebfbb05fdd8a65424cbcab8e11736776ca3b3aabd27044f949b970509b732cdfd4c9419e22f18c266172026148d51f6cba006608e035fa1b5cd74ad4666e463c87ffd0d58c173d02c2c9da43bd751415925df6cc2ba6f68d1894cd38e44d079e7f596d3a42d135b5f700188dbefb8e25dd83441e75d385006d239978968ee3c0d183bf9a60efee98fb78d1a50347d084674944f78781216ce77ea4f52a0cf0aa6c264507f34cfc54517b4e07a13197e3c6438a96d76571c93f0e040591e4d1ffed0f1c2807d2138269246da0cfde522f38edf7b370e03fe1885db5d3539aeb0444a6176f4f24f9e4c482aae8fc4546870b12f1b9e418abb48c41e71528a4474f881496cfa32d968522ac9acfbf35d9104338a2b2ac0387d6f44677dcd5d3453f318d89ae0abf4c88a724eb73a803aad84b3dbb4a355ddd1eca51e3968df81ac779318bfa61585f3c38c30c026a08e033c06955f1e4b743b38466b6b7200f8c9252de85ca491888fb5d8195e7d11d8596e4b583a4e63b576443f446b9f46d8f5bb4949c756164730496240a54f85e416a5552c9a93f38b5929706e2903f52604077f9623bc7927081cb9722a66b81389462b8acd7781e10a9880b41a3882060036acc5a371ee26f7e29f71857d73a257ae7b90c09ededd1044da2dbb2576052ab6a51dc44f00a6982a7b38a061c59ffd588498bdcba05853faa5d50cf4d03960c9344be7fdf68b44b56f65328e90972c10f748a35251b4812bc1b904d68e9d055a6d913860a1e2ab4a0e87cdf0bb89c67893cb8203784e2771183a3da68a319a39e15347b13af0b8d0392dbce9dcb6903a4f25b359131cd9e956c935b0494966438932bbbcaed34b374730e0050b5ca3f1dd82e8db25ae72db57d744c1741f18b7377e17c6e9186b6c71a9d46313fcfaa0026b0fb62b601f708e860742e567df188f44c1597ad8ea2fb0060346cebbcd0387c1f17b4711abb03f3ae1afaf0f59df867a4fb5767efd9f8cfa9259dd29f5bbc90cd7873cc076ec1f6c3540bfeb9d723929c4aeefc02f265d40f2ab9c35692d6cb3ad954cc7021cdc2cf875084e3dc548db3a0c774dbeb2315f3a9aa3221c33923fbad00b692bb984f67a437dcc4802d6e93a801442f5a13234f487b20bc40c5edb0d280878305bfb8370dbd5b170adfbc6392bc396106b3920bec0d3a63e2c2033c9fc41cd79282087d46019bd0bb17bee52c833d998db6b18100a551887b080b3ed9442ba30af4382a5406abd472328602b9f5bfdb65ddc37b6eb419bea9d9d3756f8d384820af18ffa02e32de964e0a5d3b1b75fd048da067390b5fdffed94e5a53099495c3d5d728d05cff30658ab80eb752a323b4b3d1f06677e858183d0a433c031451d9401a9afbb0bfa563ecf11cd2922513b52f79f0852a07daa5fe6941863a300160bbe07cfc5ea23d438fad2e4aef262ff687dfc376e850290e472ff55ee8107d4e8466d68c8654c9b9fa35e1fbf31e1865c5d1a5ed887d13b32076d49b83099286c420ab69043b9db3ed1810d97d372869ccb53d4e0458170aa6376c4126be983e4f3211e049619299c475e2852ac42daf960112153a46dab256f426463c17629a436362b00088a953ce04566d900a2a0cb62634d9bc22a05c84791fe1af05493bfe59243d8024ca91d7b0be5440343dca336a71fe205e02b3ca39b5efa0979f162addf292e995229142f627437e5882d92fb9d541538fdf9cf9f5ca790272e12f691da14ff1c3b5a63d44f8e3bc9c693e68c0cde53ebcb17b9e30fe44f4866f60e23632bdc692ee9cd6a8e4e0a00db836e89acc0e44aee9197261569cbb3766c6c619d376df36fec7a77f083e6343de3121c4276efed0c43340559604083e7e68d21b07f1349483918cb0e8c651e1711406e492e567cbc09e3b8ff7eb25de7f14cd2e20d1aa2ed42eccf34610a64d2fe3fe11b723a8e36e3a95036bbbd5b8ca76bf44764f657add728d678a598299e53ca7736ab1c1a39fca0b72c3f40fd74c6739f5caabfa60afa45f463d5ed7fe4b88fd92bb5a411de657efa3312b001f2edff252677969e19f3b19fc41eaf9951efff7144160968b7334f93241b6074ca902f16d780a143c294ecf0017b86d03a9bca96822c93b9dd085038196fb82e81bb4393c175cb2a559c92545c48d346b5974816a67c3017688439f9c1c6d1263b7481eb83ac581a88005559d73ccf6f68382cc7800ebfb65fb879b4b0334235195ad3e7c9c3c7f45bec6d044c54b3cd50e8512ca2bf71c10888baf14f4223d7455ee945b431e23b01ae22af99b58422731fe1cc4dbfe75a36da9b44c0cd1082e941580fcc7b6df20cea445ec9d5c8ff0f318f03c0506fd330d5db6cfbba23c73d296a4e49ed8b9226b631b7e5d8fed080cf5139a1f8842d25c35c5a5c23e34329fee4e64a12d79ad01697ae68596979b1016bd13d6cd40803c147a5224d2cbffda67902751a154ea2dc10ebc20df068d429472e697b60b67ac023d8ce6723f457c78e93ef87be2421df03fcb841f8d2ad5a5bb9e2ccf9d3032537fc9db16e1b27df119aa30713ea5962850213164d32c4175e934c56c5a00613488375c4e39ae1176606bf79e1733750fcd8aff65983642ac60d1271a9c4365af7d48b59bdc1e062eabf4904e181646d49eaca52d071d65c4bc436d00a7b94237404953b8b444933c3c5ee9b4d0e18de4813b507a58ae86a037aa94e81f4e02b6b5e01972ee68d6a711c85dca653a5799247a10471d5b0fb48dffd0f3caf5c90201262df96240f0848c02f5ce82dea42eacaf96882c58dcb4999c35753b733d6009ac80e9e49f00cbe633b7f4249e947bfd5618130e150d292b12e36c6b3b3fe8a0b8159cb5a2f160e3ea9ec271daf9d3ce3f82055384b3bfa081b78486cb6846601341db24867505cebc9a508214e07167bcf6877ea901102ff99b0a21f58c92aab856ee4e5bd579a34b026cdc24d09807177580afc0f5d5c210ed795707c6101d119c5e7ca334b4b3d7e7cf664464994f7d44e74ebd8d1d6e0166e75cf61df8a3bfeb605b059bccc8b0ca65a20a6cd62f9c9017e62a24bbc887753fab15f5198b1318c4318b57ff4f6ef39f8c622fd3491829350fd765e3268684d40510eaf26bf68b3e1da64e26e60dc1f402dac64f6e3517ef51b37073c321db4fb956c14adcd5f5620d565dd8e7ec916dd14ba60cb51ce861c55b7d31892a79a8e0c42ca9c32e0bb82a239ec55ed3113aaecf5172492f65d26c135b977a4f5c3bb396c4a2c33355918da88d80b852c39614db94a9a3b95d4d7b16c813911f5710c38fafb709966baa9ab6b2da64b8e83ca4dffb33ef12e818405686cbf32597c04e114191fea64c5b398c0901a17d0d540cdb23df83ce0d94cb8d2c1f3a24df6af2d18776114d16cd48a60bb674fafc53bab6ba2f75e1325f3148ac83c0c91d02d02bf81f86fc01ce554e7126966a937cc7597ce63f86ec46cecedc21f1e08d3f7992d834505bd0f1f9ef2c2e03b063feac80bb57da9b4650ba5eff7759df73f074a0a5f3b54630b080448845e4a90df898c4ff53d3c02b91e5dfa4d67acf9f589cfba25d377407b79b49cf7c787da3caa93f42cba758a78a42797f387394a118f87d9efccf2c19be11653275633fa849eba096c8886c845fe5f922a2001add80ac2d6bf306b55a8b15db4d0c1b1c39ff25ee7b8407aef21772e783e3bff3f20be2f7441c6e1bf1dc012cae1873f57389863dd240c335372605a187f05f0b51dd69678d452714e151eeb2dce75c330186ea3e0c9eaa87c632218457c4cd1cf2316e70717d81cf5df97421f6d3a41cff1916b89dc4f50668c665ff0e873254b417eef95a88066b2b0a1f1a2801890b5a78e117d3ae1450981454ae09c7c8b8fbfd1c8f92f839bbfa2f89d816ac57d12c97a677d8dbdacb261310099b5c319b00c49ca4d73afae45c12e30dc4d9dd39f0e5c5c7aecb3df1b9db88a07577d01ef7cd9ba172eb0bbe82cc97b1dfafc8d216984c7e24c3bd6ff2eaa7f3003b4abb3b689b43c81d423a1d80468ce64115487d9fb35098cfc4fc6547664a582bfe94a28a0b97c97a839b7f49f4fa3aba2e6adf8e38de90e46a7ae1f7a791cbdb318777264646f27cce7f8fe9c0c73bbef402bfc7234238dee234bb1d1119828359a5665cc715b511f9aad8d3810a925fff520615a6f687d68e20a7bf56cade375f389b700adc6ded373abc4a979fd23f54663213c91026245d1d814a9bd63888e3c78d0a44d00f6fcd0837f651e3cb3760ba021e151cf9825bb0608a637bc47663e06bf29bc3cdcfcd8b0f1ddef13f684cb859cd9af580b17b0c4485e82202d43e92cf8ad3116ac168562507a57c0d5789e525dc108160f8f20c43bae08fdae24594b8351f0705162d86ab3ae44d511eb11052db378c42b1df8c22ba92315d217cbfb95188d58bccdd13d62deeab55def673caae5271cbe55f020fb7993320054d2b4d27ac59334efd384de0c953f08be8d05d437a831aeaeadb1cfd02d49371000a8af56253f53877b1b353163a020c3f84a68218cbb6c23150b6bdd57da061720e3b70d26efa31884a5b627aec0fed84cbeae4ef97cde04cb5a207a96b6dd9c7fdc06e54ffaa9f737306dc943173f3d601c58fbf0f6d49152e4a6f346b67487bf6665c3104efa6ef4830ac353a9ae0bd9bc3f38e96cb60dccc99ef8efa64d43418736e5a54304b9f54eaef8c625cd8f5d46dca98fa81178cbd12eb52a2b74f4c9993bcaca369af876fdf36f64c717b0fb0364f27f3fefec4d9e44fa666209d5e21f24bb1bea1ff16d4d776fb35f9b731d8a5a981f0cd0a413ca41fb8f77479faa48d542889368251969951ba302a8883b511d3b5e37dbf8d713e579e4dc836781d3b9ef11f707b708e7839720fbb0b96d48b57fae034fdc875bc5f6682fee2cb87cda41c214b60ee573e9240071bd34b6817729c7ece5122ed824131b1c5b3f25a879c3aaed700addccbba69b3cc1c830462733d7e2f489d511766038c2a30b982c46676153b1d7d6e2470c8b7e90748f9fec97379f5b4e37f9bd3444f7e9565246f3ebf72e2cc45166ec2b4afa3b94fbe0edbae7e6cc19c5eb13112f864a28da29760e7831779b4af8c9f0e44d6dbec2368c3d1e3fb6a7cb31e3c3246fca7a6671080f355fa489f2b7a1e9c9e9e9ef17b909b3b7573e3c089bfcfe43395f5e35ceb1bd5e99a1c7226db1edb4ab89e450c49a29ce64707b2edf45123baa59ca9f9f95988bc289e3b8f549617321f055105a6d94f6faaf2164517b99c001dc9a1504aee55acfacfe4848951e81af6adb30bcf3d80aadaf1f17337df4aba7560f0787fcbf823c9bf9bb8b761f16df481d6a36e574c28a5786c7acc41ad994eb74584188f57290d01c1db457e4f49ffdf56acec90fb95737722fdc70cbf6e286b37c985f63e04bc1786f2793a929fe4ba9b7344cd1f47a61bfe4b8419884a42084c2bc6adac46ffe216ea2cc2b487ecec9c9caa2c4cb35b5dbc3b29882886452736b6536e9e973ef4d4bfce1ea3229f9442034d148be8b1d00099b505b74cec877a6d39082da9a35b96982d5d2d894388b42d4ecd0cc66bb03daddef08ecdfe4fe53eda98d70ae0a236c2038ff39e4bbef85a79fd1a75dc4aec1527484d31abc09829951d01876d9c777abce7dba14e04df89b3da386516e674b95bbedc8a48b6276476dcdce623da8fffa36dc95bb6d22b621f017d544404265c8a9d81912a6ace036db7d5ec43347005beb8097a434662f5f56aef1a6c717a9d98fd0d4ff958a8bb2ec7517b715901d4a9e22c66b150451682f3f1f52743eed71290ad60b41daccec84abfad4971c5a0a91b2d39ffdd199cc32f16161ba7978f447360257ed3fa6f01fb61836dcf9ddefebaebf003890d54173a07a2dd1d9d28d1a8fe2fbb1936e63687ed46a6cceb1610cc57006e48b58db5ca9d1e6df1259098702b692f7bc04b1e357f78920405a181f95f726e017849b17939a7ec6f494f288fd003ac2f430612e4fe0fa86cdf358228fc0c9cef4cd07759a54721c673c14fc220aa51a3ef9943422c88e7919580f75b6eb4dad912cda9781cc3f549caecb61c387d2cbacbc842c13a8a6a3cfa8f16c86cbecd3fe9a238992301a8c42024690b88ab85da58a1d5ac5861a7d7bfe786f3b8c190b202c3893c2a1f8d53606984964fa073d6731a241e7729d37bf301b063674fde91b5007dabe42e897041081184c4026feec0313873514d6a218d6df6c6f09356ac950f237a65bbf48c47d73a038f210a1f15ef1214f4accc5fdbc8bf1449c390697b12a9e3d9b99db6621a356ea273d833057ac2c58ae0ded3678c378eba5e4885b4266441fe9f82e3c119ad0118bb940082701f7dc057ebd9385a42cf58cda71d1266ddfae9a1d2e185274c7cc8c006ab160a9cc5d8a77e263bd8d98703daa52ec1080cf71251f70cd91efb74ed4c439721d8d7b0504ce0e221f2c98f6bd60e3d5a3f002f91c7588b5d20aa8d9f7f6fe25680c3563279d903ac8a27f69de517bd162a07ea64dc775940d1594c7fb642f8e258c62eb9ab176a8760c1511e67df24267084f1165c137aca9150b5adb093275d9a5978904f79eb638219568df090c4167dd67cabadc2a432625d5032648b2d7a225dd36a031612326cd45cad626255d2e6b66dcaa4204f8521b54ff25a91d29e5b64bf1400fe25f98fdf1476e1275ca024f811947886ba212108f63403151e4f5e6484c3230868390c45833821890c36432197a253c51918d26e4a3af8659abe29b807034a2fea248ee37db7dc064ba3295e4b626021fa79a16f124e16affa3be43d057ff8042da38d59258e50db158bc553707ddef8fd270a0d8fb431992203e768a174c81b58f96c9a61cf8eab72544ba42bfb0be70b8e93c0ef131315b12d0893d3982dfef0df5e80ec8c231546eb1c066a830840c7237097f307b3bafc85cc1a4fc92491f601af9eb9c3ed07d767b92c98ec53ee9f0f0e15698c05d985d06d3c022ff0a8a8f17a9b14747da009c1838901b2ca8aa4938baa8c8b037e6644150d4410a0b5491bc3300c268688858a0aa6e8608e02b668392d8b1f5b631b8d9a8da5db4aae6ceb002fa27907dfba4d782bbe000f8aecdeb4339254de1dbac0bbbdfc5687fd24eb0f9e0cf40b27b08d139806494279d00c8aad3a5c9c401e9c402128d5e4fc4099aaea6bf5f12112f31eb922faac502f1a3834831084a8a2b63011e232e19c70e288609ffa2071299274d2d438695438693a3871429c38cb89af13f62389ed54d01f585c1c0d93054ffa0b4f883ad6c409fbe184c120a1301038065c86c704d3b448304d2440a1003b610938d69a9ba1288f50441c8250c3f2801ffcb0871611c5a2a1c415419024141e705ce1c58b66103d7898cf0c555b68261045753279608200ca8ce763c5264eac70e3c40a2a7cde43c50e1ef645d5858d2124e1a48a227cf1a3d0cb5dd9802811e599a128204a745205c70d921bd5733fb40849b2c4668a0cb02469faf0c614202a64bf9811816250088045057a51e5630a4754a1e9640a3948523592240d1f2449e3461b7b58430f92468d3c744213094a4c07e573324514275340713285025078509101314e9e473a799474f242d2c91b4992c60e92a4a983544d219d48b106a90627526c7122451927527c21492c28410a20e210070d1d2449330749d2c8210e1faa23d2c0419224cd1b4033f422499a34dc20aaa82d4e30c0058d1b346d90240d1b2449b3068d1a502a7081345688b2271710802445218828d488020c2751f4800349664c9219731285e8240a21ede1c0c49e1c1440f9745072447182b206499242a00f553f1d29c78989154e50c43841f1e2048a1440bcc1861a7690431a6b38031a50cc2a34d5cf48e53d749e40f14ea0d88024492b404149018a67164922d1605f860a8528fa441c9e08c2133778c206663c918227a82772fc139a930a2441b20f060a16d5dce20b97203980f00372949828c2119a3224a20f6a98d0c1640e6e300943124ca660c203144c000092244d5fd8cf7f811213fa509dd9f2269c1309404992649c44401392f41272c14904825085a659759470128129aa1308b4a00a4d473e238ee8c867347d94884e1eb0054962142b8ed455f93839e18124893e584c4e12dbd9545888a88f2864ff379bca332b556931252b40312314847c3c68e6658a4fd5794bb180a80f16270db0815485a62433e68ad057f652568846d40903129172c2800e9c28208d0cfc60499258208303b420018628590423dc2841a3840c2709f080a4714333831304a821499f190d19d080a20331384180002449bac401ec19064822499a31942000094728421124c90c498a410c66408624955146a8c7013a1d901a450a94cf7bda09013c484a1620090e5042ba42152e70841f42c8010ea42152910e50e064001ac9ce0fb91b09400492d448363c78542702c81180499c04000e2a50785c8a0a7d4c47b4b91fdaf122430101557054bf48d501f9a83aa0e901c5740010872405917a9c00a0049274292af4c412de529f138d0f4e341e49a2b6902aeb99eff2a12133f43c78d4ce0cc9d65a6badb9bbbbbbbb33c618638c31d6ddddddddcdccccccccbc7af5ead5ab57af5ebd7a758c31c618638c104208218410bef7de7befbde79c73ce39e75c6badb5d65a6beeeeeeeeee8c31c618638c757777777733333333afb5d65a6badc531c618638c31420821841042f8de7befbdf79e73ce39e79c73adb5d65a6badb9bbbbbbbb33c618638c31d6ddddddddcdcccccccc8b237cae396be62266451a01269a2049d20cfd15b5633f44a8d01b99f9a105c5224379fe878609a1e78844d4e7a3c1424b45b1549a2b4892c60a92a4a98267cad0cf4c21148b2469a820499a29485290a459d92a2515a0cfca8746a2d1ed4c8a220a7528caf4f18caaa9fa0a0b4aec9024cd1992a4818224699e20e9a084e40449d2304192344b508224699220491a244892e60846308134b2e2b2d1426ad1051016b969e9a2a5456ea410225a74c1c5c60b1f5cf8f08c2cc5051cf58879d10a0ce5e901472bffe9c07c241049b44092248d0f7a603731a3ea3d33121c2a764892541201a9e40c48a8a00a4d3374535513a49141621f0c142c449ff9e9c4744231a3cf3f220d49b222029a91e4197926b505cca7230a51d407ca147a84171a2f44204992a429a221f2224992678aa68a23b4901a8105fba11e709445fd2226f0e69c113ad0c1082f6c872ab2f220a8cdb8a84494a772375a841792f474fe506929623f3e66423386f2c82402119224c95c217ff8f8214af2a32e3e2b2a2d459ece1f9588f2b8d8a7c2dd08a50a77a31df552d40d21516929b2b92124a1078d2a44b8808ba8b414516929f2e94ccf10974a543dcc10106856a3ea7308151068f2e0b1015552891f2428c40089219214620cb09988008c20499209241d847843920a1137f693746e10e2708424491e8f6322a11fc283c7065411c223499214253ae288e30d499274c43102a90b38dad0a1b079535d5143d515b523fa1836723c8223d83c723772d781636510660091248d073a20499e5048564d0f0ef0a7f2418940332120a24f871a8281900f04310641481a0ae808440fa27080243d118427cc084403a44a93058fd04bd20c208af007454892540249072056159a38a209ba62468485864715fa4e0b0a473441281e8f0f1e3c74fc21057e8843871f5c241d6fbc21bd91224992157cc8826bbd850034259274828d1b3d9024c944d2c1072aa4246b4dcdd3b2c20ae7064842e181d2c5152b6e0c91dc409124e93d9d3b61664c1b9a9024e943a40d38d440d1b186019ad0860aa436bc90daf000cc075aa1f242c48a0fc582d286244928f6d339c286212410c5c61924141e5c8409483ad84832a4191b3b24c91dca870d014892f459d983225078d88e1c244972d1b18726ec218924edd88310499276a07cdd438a24ed40d1b1870668828a1d6bb081c223f4301d6ac5435923079224893e6b8024141e6b7821556baccaae610022920e3dbc21e9d0c31f241d7a1084a4430f71d4cf4865e6e38362599124cd8e25499a2ba4c98a07cdbc4892a60a49d240f11e3ac3e854df22499a0d5492a4d140cc7bfe41332f92a4a16214b3a93a92a4d93185243d6846f4a099299a97925334b5d0a1468a068a0c4892a491423445530b22208a054451422449937257bef248fb91a11f7725f443923418780f9d2fa11f9fd04824aa1f0251212d5c8288dec5332b25e4ff25886752ca1344f42e2a2a2e10ba40e842c4b10b9166765242dcada8a8c0662bd0b1bb15cd05242e64a8501049d24481b222491a2844d547923416a88024aac20043365b7916214244414441840869b6e242e483345b09030ce96ee5598408110511051122c4dd8a0b910fe26e050cd94c4524a4998a2848339517d24ce58334530143ba5311e24e4514c49dca0b71a7f241dca984e101d2ac59b39595951517222b2e4462ecc747b3955017cd56429417cd563c2ecd563ccd56c2f00071b712860888bb9521ee565656565c88acb81089b11f1fee56425db85b09515eb85bf1b81009715cdcad784222aac5dd4a457d346bd6ac994ab366cd9a356bd6ac59457db85381f1741e883b9510457954dca9a888aa0fcd6771a7220a81e1e24ec55a1fee54e8c8c59d8a67c4853b15241d2ddca97c3a5cb8534932b970a7f281e9543320d00c89a059339715222e2a445cdca910a99f51e8c5dd8a8a16cd549aadb8ac107171b74204c810772acd5456dca9ac346ba6e26e45f421d0b7b85301b284396041b21398c3169224e99803cf410159a0a0f0f80284c24556111ff6635eb412a2427280220e3fe320461cd6e4c0a18283186cb3111c5400872924a99a28554c33ffe30d492469d38353cd2d50aa8992451a37e022312fea4892460211903e8c4e15f3a24eb3d187d1a9dc504992c4bc38c2e79ab3221f1fffa1649e45a5ba1f1ae2a1286abf873b2af4617ca8cf045513e4c28621fc70598321d63004697a149967594305663649dcadd84fd2510951a23aafa53aa1ca7efed38179eae97c0d5194e77244309f0f813af55b5ee4121a0199992c3fe3230d6974a1230d4310511e978fe9bcd84f0704f6d339928646431c68d041094494a7aac27e3a47485082890a2beca7736487fd748e5c6ac60382cfcad70972b1ff79501792a46180660167c8e20c28d2190a80c22326c60c1f141e9beac87cd006049a3c78446ead435519a620bda8806086783a33468aa84e0b7d117826cc0b7911757eb8d64766ad0f02d77a725c5c6b4ae6a599cc6c6126335b1693992db165660b6c99d9f25a66b6b896992dad65668bb7cc6c612d335bba6566cb6a99d9125966b64096992d8f65668b6399d9d25866b638cbcc16c632b3a55966b630cbcc9628335ba0cc6c7932b3c5c9cc9626335b5c66b63099d9d232b3856566cb929946c8e0802a34a181051d687840071a5248d218a820d98f1955a339a4fa8e8e31144092c4700669b262d8c124aa3a42445f8961b2341b8188e488e34554910f513294108a7aa97218a21092247dba683602c30a2429471c3e3e44e0a83e3464109294431081908e544a8865f91025aa428fc443b9f0e0f13c4413a5d90845542728e66d17782049d28b2824ae39eb242ce43f140b17c2f080debe67f36174aaea61266853553d9a8d389b23758ab6108298da114d198f6756fb9bcd666dd6a68baccdda7091ea5b3c1e1fb5ea70f1af22aa3a9ed07790c0cc1f1f335d3e2b228a85a5d9880a7d7079b11d205c641569c6a92687534d4e911e3da0cba2191177a3b754eda1630a389024984f67c6e3f141b550a224a5240a0a40a0128ad8c2195638a20a4d1faa138514e83843ea3863c8342945015285263aaa2469650a1d5090c3ed702a8903137540c1495568ba42f4e98c603a54f4e9c074a81531a34f35d7c44850b8d0c113b220bda07c3592410e9327c427a048f6613e2820aa330249059c8d740227882449ea694d8c44fee8a2e5c5e58b12a9e48c922a343da542a2aaadf8743ca18f59430f00804d384392a42fde43911ce984ac98f9238f279f9615309427871a9294230f9294030f928e2688710749929078286a088b085a26912042beaa7c803a2f9d992454a80865472e40aa17899ece1f445cb208514078f02080ed504578f0d86c389b0e686e4055d58335379bf6139a1155dc3df8916c1c3333f3e2089f6bce9ab5c86233b3983fb2783a29f5928252cd2c8aa05401820d920f81cab084244d2865a0a1a38c468624c870021949282af428a03ac880128a8e17c02149d214eabca0063a5e9044aa4414cba4e3053b2617a4f1a1444f47d7053990241d2ef8a2ba940be01896f850a11f238d313e44cd9719832349938e31c650c0141fdb411103109224e910430b301f2a242302205d7c18a11e3d7af4e8228b2c92503f363233546d92cc98169ca0058f0570b0e0062c60010ba658011e56f082158460053b2469a258a62355473402cd78aa98993228339f593b9f09f2783a321fd3114d199499cf7c99a8a876a06840031ad08087a240339ece8ce7fe87faa8600d1590a1024b89503ed6043c787c353943be2001ca4b0a38a1230569e8484111244a3483f29c2f5270002fe808630961804047180f987184247d159b8dcb0c0f663a90a410497ea023892889053e9d19125d41a1cc7c6638a2102523aa461765a68a992f3ef6333955f8c8a272a95ca8f8fc40a9c2435174478f1e2f59802811109922320298bef8e20b2aaa0051a21d4190b071a49a2324399024c98a1085c40b898241b29084466c48f3c7080cd38fd18f0020ea822846644575081d151a3c78d8f6565e2e4ee765bbf282992f5d94b8415af66e2fd6eae8fd67bf0d92e3747ce3a48fba4b091b9e2ffa6ebb3e1f7df72d1494ac414edb8eb60b19fab58e3afbe98000aa213216a35b2e3277ee3984ce756cb7b9da1546cb6ea64136aeac513bafc7dbde9a25689077756dbc286d4a2b7d7b06591fba7a6ba3fed331ea7ca5c40c3246e896ede6aa776dff6590933ebba6d768db65bf22192475d335b3e5a8bbf442ca7930f3659a60a6689a426f210b89406848469fad85cf698d77353a06c990c51bdfd106a97b3dc52097d7ee56effae6ebdf711e83f11b516d292f4152c0901fd37999a6f788e8a89aa669822c4636a39230c4e55c8bafdd5b33d36b9bf2b2b539eec7791ca2904ccfddc0743c9e779da4040cf241cadcf47adb85d0310a5d48c917647d4799473a632fbab8398fdfae1620912991e843a2aa138a2f255e90eddafa59bf1bc736db7bbec3f248a8d09069e2caf3968ad9346fa2a40b925dbfdd26b79f9cc7d64e6b7d7c3ad41039d97f420917e4b3f6b167df5e6f8c31dc826cef3d76ee55e8d6c6398a619e1117d304f150a205d92ab5f1d5d78feb43879cc7475a8602b52c48b7de366ef4beea4d9f711e77362130aa9ea67783122cc8cb6ea9f37a70c549a95322c8cd239d04255790cbdb9db596ddc62eab97f3787137e86ec4dcf3a2c40a72b6af715a5b5fb3ed68398f8fd409f2364dd3e46e344d9ed9097d354df6f347eaa4d3e4af648c922a48f8d5c6d870d6f88c4de63c7671a1e999b57247de33ed23098daa6316239b1e255490f1ba696f2fd666b3ed6f0ab2b276bfa953c6d7be8342a6490af2d2bb608d6f756bebc209af88484854b96331b231414914e4ebafb459c7d67dcbb4e40c16978d913176b4a785c2bc7632abed1032af469f10695bf79cb9eb6ea55de204595d43b69e9b9fb6d6604913a4dfc996564ae9b3bcde723762825cf37fbdb858ec5fffbe53b20439e17458bfbfceebbeee4809d22d8495ff45b7d6b976dc664912bee37af146e670f1bd8ff3d8dd03c574181224c7492b638f526699d796e4b708bd0c25a44f507204d99885d727bd9479d53a61e747094a8c2027bbed59c7f9f3fe6a91c8344d53cce8e3588c6c684911e45bfd1fd9b6ae0d3ad8bc8408d2b9e172d4dac7b859ee583204e9b8b1061f5dd5edba0d398f65fec342ef1212b930bf90a862254290d7d5fa2bae7819df662fe731bca251ac60485431561204c9ec91ef751c2be5c83c66f379cfe31910559b6da3949714da4629b1bf0408727d5df4daf92cbdb1236d404a7e20fb56a66d5fa41432ffd91e28f181bc77ce06a9e3c990d1c8af07f25f84cdb117df9a3c5db49ff71f253c90f72d7d1effc5d0260629d981ac4fd9eb59613773bbfc79cfa69b16253a90be7c460a99df3d2f6e939303c9d6d25ae9bd1cdd2e4a398f1d8744150ea4c3e8d0b6bab8365a5be3bc4dd5698e253790ce46c673c567c8ec98721ebb8ff9c6cd6fa9daf98cde074a6c2029f5eacbb1b3175a873124aacc90bf9cd6d6e0bbccbdd8d44351748b921a48e75864af51fad1b1edd53490aed93aed5ccb456b9b35b72e99818ccdadb9536e0ed7bc8bf3986d363023fad6b50c24bb9fd45b5cafad5d6c82d854120339db71f7e2777456e8cd79dc2a2530906fc61b9fc2f916b56b3dcee38ab2ce2d24aa5c4919d25a16abab75fd5defee9221636d7d2d6d2cd2551fbf921748c7b5f65ab0a3b3b3d92e71819cf6db3facf6ff17f7978c21ef7b5debfdcb1c63daae084ac490b741d89aba836f396cc779ec992198177d3a1b3b41cda1174551cc65b005eeb11dadbe2a33ea9cf318368f36a2980b250b2a8bcb276d934d7addfc7436ee461be798d18709598163754eafecf69d3777cee3e6a202e91c8cccdd9eb35ddb6a5d2990acadcfe82cf79b963dc679dc5c98a128e6b22cc2907efd51fbaca3fdda99398fed6f9c5d8b3392521629dbd6377ab3d4f9b073c83455143a16231b9824325af85c7de83ad6c9e064ec3e44d59691357e7bee2de60b23a32e3616231b2f9044760eeb7af4d535db659b91640fe16af5c5791bf2f5888548c6e5ffdc8496357bec17e77105b9923ca17b6cebf5ca666dcf79bc61dc42f2fdc256237deb9cd1c89cc7ad0a3024f7a3b76f8490b9b6064110bae7acdab5ea4706d9a4a4f78c7f67846ed95bb582623a8c7e248c77bdbf8c3efe5be9c7c8e6f7da2ef66f6aafb7158f7431b2b5b05d643c672fea7e566ae733874cd36331b2b9472473ccbafb4e069945c6603e9d2371a140b63867b7566db4b42ba48c29d71df93d59c3aebf5cfcd79a3916239b1270e4336ef7b95557a3d72d384d1ecfd769fa108c74b6eb55f6eb32e89e3ae7b1ed6c1e34237a1f1fd334f3998cc5c8465ee97445ff45ddd1e66c9df3b889626e065e72858f3257e383d3195bcd5609acacf7fa7adc7ad2ebd3b2247605e6335ba6e9612a10b5e1c76264632b7b6c113ad8cd1d8b8cdb6f33cbef4e4ae36ce6cb79fc222425f4a29569fa109069b2df0151759aaad08b40d3cea9178744a0122550099fd97b778deef176fd50f1eba78b8f8a831588e231253f7b93a17b945d74479d6331b2d97cc19c37165fec059941e8fe9c57637451e775b1a61fd98c3b8b914ddd480b1985cfc2a60e42fb28e7f14c4804ab1af2e1550d4d8f2c46367e02c79039e6e6cd7163e6a037c3d8683b1bf95deaed1c13c86fabbbfda573f27a7e4b20ff3d3285b63d7576d049201bd7faec3ae8aab769dd76a88d6331b2198111f9e89cacad5a997afbdb11c8f8b6314abb1d737a1715e285f479eb57766f74ccb4af08e4aaf7c5c87e9bb1d58ebdb4b318d904292299766cecececb3aebd4d53880a857e9adc6331b2e91071ad57ece7e05b8b6133638fddebf2e833c2c7cc3072de344d93f3900884821779a3d3396375adc6089d398fab23f3411bd1c344b7d9bce748e86336f4486dcd626403c4455ac8de7270dd672b6cdb388f31d022adc717fd3686cfb5785d0824e3d5b6a1bdb4bae7f035f3907f0f176d96d77cf53b86a00bdb5e7cddacae56af375b4bb5b02c06eb738b42beacc245570b1792553759b3fe8f596ad9e43c4ef5d80979104e7eeb7174cbc276efa113c4ed0202796773b4f536befdde6d9cc7202a64797d405e861fbb317e0621dfc979fc1fca5337cdbc22df3adae2bbfcdef557e63c863fb6801c39bef5da41f61673b39b6290783c9364bb38cee66efddddb9585d1a94621ea7a40319d6e31a30f13c55c9920b2ae8efcacdde9566bffeea53651888a7c11bac3d791c2f51cab52327b993a870dc6bf6d4db7a285b4d32b64ebae5b61b376711e6f18b3e3fa48581740e46448adbdbed8f3d3d99cc79b66278ab9ccfd903e9f8b753ddb45db5f1585a0077cc8666f3df36963a4efadc579bc79d003d21d3ebbfedad93e1d759cc7905f072483b3ced5ebde1827e4c9792c438560b87bc837eb73cbe6536eb0c5cb791c12551c90ebbbf56dcdb173cc59e43c16c5dc48240b79dd5cded0b98eedfa659cc71bfb991bca72bf116021a7d7472b37eb687b66c879cca946a04d88ba1be7230548ca4bca8b9094fa45ea23d9c8ccd06b2c46364278c87fb345c8a8e5efb72ce43c0e4d4eddac491473a7e9435415816814b3598dc5c846045142b771d186937a3be793f3e02845a52525e54548cae6d3791d1281d887a8ea2c46361c80b23e6be37d675ef9bab9388f43ff79922e08e7746fb5c5ed59ca795cd9ff6a237a98c6292f41aa99b27a94e2324d33e54548cac6238b914d890c5c6ba0d9d780f3142c02dd14159200531a5812b8c2025304aca04015bc6303ddb91f025d400313a082023ba498428a0c5c408a2b1aa5f0e6391b0a60c05d052e9084921159200a0ba040e15a5b80613307a502cce3e91c5914986202f3433b2430f347aa88c01410d850f10051688aa638690ce880e954513880ab993fb2d9d1002918d03154dd6cf8886b0daa5fbd056c7628000309d86ca440c026c98c81e20030946703f3e9c0c0509e081820c60205e0cd87ee2644892605083000dec44c118a00a80880fdaf36170040ca13950666478e8dfdcc8d9bf0460325bca93a9b8d28c96340f249b0195028f998f9d1b0197d304001a4365ee0081fd20e7490031cdcc00666d480063390410c605006192f70c11862b480052b50410ac298495285c000519f18cf1114743830f76da5f38bcd094c500212181981a4a30966483a9aa0891c602880d4861860f02179200090e8801d24a96a44079248928402820e3c213d128a7aa8da630d3d9a207a981e64f4b05af448e9e1000e48e2840376c082c4811c70400c69118a901c6892cce2115920e2d3a158baf359c902491643b2a0408924652161f1862461e1052ccec02208120a0f2c7220cd7c7c4892261188a82e92260c27583880872624942a78acc1c30c28222a08ca34adf048398421a4dae1804254cc8c87026d409468f347664c54c34934038507caa72324824ea2094ea2072449a26207ca099aa2a2024ea02002af979d8bcdb7f84d19c8da8b5a56d946763dd218c8c9f8dde7bd60b35f87815cad39cea6abf172ccbe0c19977bfc98838d23fc66c9901de17d089d6defb5f802c9eebbceefcdf68db2ea02492b6c18977d7863f71c4376743a2b74d4325ff7e51043daf6bede8790a3b3d16b27a475b4c2656f9bbcba3527248bf1cec88d2dbe90996e42b2c5fe99efbba76fba2664e4ebe65cb523a3f4ae9909c9973e65b7b7c18e7e3121ddaf576b74d3c2d96d5e423ef7cbfdb3eff64dee6809c9ff0c5a0717f51befad847c37ce76935aafedce2125249d8e272fea209b4cdf2464d759f9dfa22daefa4d1292f6578ed6c5b6bf6024e45d8db2e59a29bbafad07095923bceece603b65661f21a765cf7fbeb8e0a5d61192d5be7fd9e4c9b339d808f92cb3f1da767667d76b8c90d1bd3dda8f7b3d48d91721fd397be7cf672b5f5a1521dd178dabf93367b3c144c8cacdaeb5ec22651e9b2142b69bb536b798ad6ca33d8464af56dbcc3c9b568786906d1d5aefe6f6d9dbba101246d6737e74e8cd1242b2c81ddfe30b59838b3b0ef9b87937bef7d1d5ecc22163bc4ddfed7d2f3e1d846cc8b7c5b6e074ccad1784a4cf5ebfceceedeae61c0819db9b2c5e7ee88dad0a0849ed83af419e75c23be31f24f3361f7f74b4b9c86d711ea7bc04892c46362c30f1839cedb2f5b1ad7b591fa4c74b1bad9332b6be46ee37e46d9451f73042e66ed15a01f11d98f0c1dfd1775a1983f4d5673898b821979b96dee66e7d5f5d534f790992c20d0993362adf5ad9fe7dea1a3664c3ba76ddb9afbb6e03fb0c267b90ec8cd558638bd0aba56bc89f8b3e9cf3d2ba685d1c4df420dbc15f347a9bafad852f4a1335e465bcaaebc7deadea6e1cd20224c5ae4cd3102129ce358b918dc919267990af59e85875f6dea06d95f3382482292f4152aa0f202922aac8e763545a5266422faca182091e24eb55fbf1a4eed141fa9cc77e0749996de62284ce1ca59529133b48bed4ad66f0ef7ae89cd641ceaecc7e2f76fb68ad7490ef6e4f7e6ea616421add03267390fd60843edf84d6a77b4b0ed2a34fe66b9f3d52bf1e0709d74fdadc2f16ffd566e120e36cc6ccdab61a69ac363233b4ba0b9337488f90b6f8e6ab2f360b997f98a421edacbce663c691d947a90b17dd5b98b841faabd1328b3e277bf33658039336c858a3ffa38dcdd896b187619b206c901056c8bcdc5b5edb83eb6e8ed4190292029b47292f42a6a95a839cd5a37dcf986b0fdbbd1640305183e479eb6c0f2bb5d6d1c7d2209bbad66ebb471a29f5478364d5e37acc395a5985ebb9c919e4740cb6eb7a5adbbaf96e4ccc205fa5b6b93fc75665ee1e91212665903c394e37a9b3962f7ded8c98904132c71afb572dfcf518da24d48f69b29f84a2f0814cd0e0dbeeaf1fd20b6f739cc7ac81613206d7fcd88b8d357d7ecc793c93840a8136949da6bbb1764e5367865e9849224cc4305fb5b45f5bac3de77d6854519e3a4d53e83d9e182aa4b21e17c2240cef3a5e70ae581fb4d13d189c7d733ab53d2b6cfef00b72b1757d7673fd66a5de9cc72ee525488aa7a33245c1c40bdc5c65cdd256a985b1b92e3c1bdbd23abd4dca1ce33c4eb16f9412d3e154139214fa4629cb45265cf8371facb71db37651cb792c1ac540d1888b8f4adb026c6ef56aedb9c6dd1a64fce69bd746e79abb4e3d9e59fda3d22030d1826ccb1a3ac8fc9f7d6fb61504932c4867eae6643a2b6d079b731eb766662c46362e265890cdba069d4dcbcf98f6e43c66579071c2bb38be7bef627f3d04132bc8ffa737fae4e8f7f97cce635705f911367ae15f375d7beeaad935c82c46362a26549073567693f2c3087f7af4782610b8e13805792dc765dd84cdcd27749cc76b39becdb118d9a4984801f2eaf62284efc1d51a3bf77dcf2d8fb53637635b6d1205e96e8b7771bfb7cbac3e108b918d8cc91972b1e5a08dfe1e3e9bd78251b90f1328c8cb3f5b651446fec93a4ea59f201d65dc3d2f53187d42a6448e7a6113274886f6e73bfb8cb5fa2ae53c8636860aa938c1a40992bdcba67dac27b747df5db498a669f2314dffe9dc3b231bc184097245a78b31857cdfb4fe388f3715ce783cf34e936b7d642d41da67b638ce18e37cd52fe7b112a43b07aff3ba2abc0bc69504e93f9fddc5fc39caacd6161324c8f962534b5dacd4f9b109f31f47c4e408b24e678f56efbecdb6d08701999a1841b2b35add63336be6fa721e7f189de8854911e49dbf9a6bcfd1c5a87d8b08d2fdb2d141fa66753152e63ceec7ae932cde5c5eec5a1f7116231b6b3204e9bc5ccfe9edf2377bbd0c132148e766ff73778cf673b03d4803932048369fb2d71c8b6d326ceeabc919f2363c630204f99cbdaf6db40d726bb5b24cd334b118d9844c7e20abfbaf7eb698e3846f721e3b2f9a890fa45b3a9973ae9741d87f7b205b7cd545fb2e65d6c1f64c30e181b4363ed61ada7676f19dc90ee47aba28eb782174d7ec7520dd9dd3b665cf368ff152931c48777b2783eb31bb22e3e7e2c28184ce5f63ef39dbeab3fb8603931b48fad839d28ebe9ef5d9e00e4c6c20eb8c2ebef9dcc15ae77aedb118d9704ccc90efbeb7dada0bdfe4781b6e4c6a20df3167a753da9c451b8398d04052d88cddd2599ff31856cdae99c5c80688c90c6074ce9c6b7f10765cabad685babf1aee5fe276b9cc7d3544d5343622203596f7d75dd8ff73d378c233089819c7f9bf9c6c9e8746c2d0c644fc60ee374ad52669d97d1984318dd45778e5f5bcc316ef1cdf687acb137a7bb266448baeec3ba38b63ae37bd85108262f901c63cfc50dd6875cdda10f4c5c202f75edbbe7bafda86537fec0640c392b6dd4b67737da7cb69939649a360c6d6022863be7b55c73ed357c9039b8daba8d5aa72f42cee3fa5564b5a413322ee7b35576ca9abdbf9c57411e259c90ce36666e578d1f9aa3209e394dd32446c926243f1a1bf2b51f1dfb47ab91688aa6695abce15a7562dc394d48ea169deeba7b4e48d933212fbdb1cec66e7d7ed15ac79890942dac7fffc218ed9b7665c3979014d2e50e2ea74e7b5d670969af853e9d9dcdbe52d69590df78be77a947cbeebc8b12f2c50b639d8bd955198d91eb570d48ca8b9094990701e4c59bda11813a1ecffb24e4ac8bbd236b6c424948e7e9ecff47d79e832ffe480192e223e545488a5b33288984ecf6565df48ece7dba2889f4e1a20510394dd3344d90c5c8268c1248c855175cb0dd9ef436b695f338446d440fe30c1fe347445f0df9f973065fb7b51c33c7d5f4428ed4fab5f03942ae76b7e79ad3679bac9df398ba9fc842d983665e5e63414923248db0b1fb63f3dd1779aec0c808591b65f4d9e95eb7858e721ec7182aa4521fe4b2796c11b2d969335bb718b5cfa822646cebd9fbcf5bf516991b414922e465cf1d72bf35bf794f4448f7e5fc6f63361947f74a0eb19c47e8abf98aaef16bcc1e650cd665dfbdfd9ffe40506208f9d37943d86075866f7e2124acec99bfc5bad967e12384847f1dfeab1edb743ae390f317736eb96773f6b21eea8628d154490192b292f222240534b99826d08ce9324ae090fdeee9a3cb32c83aaee83fa41907258390fe587baf7d9dcc7fc21b75502208c93f21b4f7576366cee683665e88501208c95ffd7f51870d99afc8bca9420920249c175a667eaef7f99b4c09257f90b5698dceaeed175f73c779fc1eca42d4104af45999a699d0342d1794f841be65b66e9b8fceda16bb73913ec8ca13de1559a3b732636f2624fa4817672a94bc215d64fdf74e36d763cb66737c908de965efda581d8cad35b8dc90b5fa7dbfdab1c6ff1c4e9333926962deb03312e656286943ce0a61bfbf8bcd7e3d1925fa6c28d1a7232a61433eba383a6646e9622fd23dc8dad6dfadaf1f46d8ba398f535e82a480a89016d304a242769aaa69aa8f6495ac21efe2ff77bfac46dace2ede70e56644bd84123dc8051775d6ef5ecabed52f324dd334239aa6b678c3a2cf9b1135753f9d2794a8216d63f1babecc2a3f742b461894e441de6bd9a3ff36ceaef7effd16519dcb8c123cc8562be5fae0ba6e417fb889d3b4d9cc696290c5c80649c91d2483d646da5f27eb1669b483bc953ebfeb75ba66b7da3a48171964b8ae57ea3532ff50d304598c6cc028a1434718577bee45065d2f876f45c6b6319dccbd2ea8d292c24222d01c64335fac358badeb7cb0c941aec8d7c26e8bcde96f31ce6318070929bb93f6b4bc22abfd70906dd6196d8bebbdbeb0716331b20941c91ba4a55eb9b11aebbc0c574d43062f4252364d038d23649ddf3e46c7ae1fda081b21a3ede9bcfd2dbb191a46c8c8eea3b4c50b2df5e7e822a4ab8e99f7b20e6173c740a3084967b5fdeeb17395e1738990eeba375dadad5dbbd5102161eb0bafed09b9aec9da2124ff7dd3f5c7387dd96a08e922e5b7babeb5dc72ad0b21ad63466f7b3769a5712d186808e1bdea8bdcdc1ce1f78cc3c5d68dc1c8adb1e7eeb56efad6a5ee3dd8e87c4e82060ee9ea5bec5a7737725bf7721e6faa8dfd7cd556a019847c666dc1e7bebecd5717e7f1a713f3a4a011847c3376376bb0d90addb46ff10d348190ec56fabe3d63ffd673721e57b5534dda0c9da0018484b75ad7ec6c43e6f15dcee3c647429408182f012841f307f9f8adf8a2c3469dcfc63e0fa2366f0a1a3f48db9a2db7dceb56576bd5e480b81d15347d90adb2e50aadff7d96b5c9dd469a37e48b7ff9b6bbfe3d5d35721e579bc62548d0f081a7a57143bef59e1bb4f645ce63c647d0b4215bc3778fb6ab76cef63c76e5d3c5345547288ae3adb5d6dcdddddddd19638c31c618ebeeeeeeee66666666e6089f6bce9a81a4acf780462f294384a42c6631b211800e346c48f7f6359bf0d9e9cfd5f620e3e2bfcfd56b3d46ebb8d9e84dcd1a92ad2fee3a6f63ad3646f520ad3b9f163e74ecae7b5ba3c6f2e570b1079b7384f1c566462773eaaea3f63e7e1102aaf8bd409307d9d3be6e3cd9ecea98313c48c69eb7fb6bf6838e69c71f9a3bc837db337e34fea26ddd0eb23a735e8fe9a477cdf60e68ea20ed73cfc566975d66f05a3ac8fa3ddd5747e6bfdeb47390f15e66d4c27add5bfea61c66f3652cbaa6d4c541def637c2e53436beed3138c89eec208cb3ddf6e3c741346f906cfb7eecf726cfc830529f4d1af2b5b61c6cf3ad7aafabd70dd2adffd7cd93da36c87f7d216dcc3247a78b970d32b668a79bf4bed77adb5d8384cf2efbfcded76c9dedaa4146660bf6856cb548df6f1ae45d0c23a4ccbae69af58b06f996bb95ae696b3357d73d83a4b4f65b77c1cbf0f6bf19a4c7199b7de7e5e674fa6590917d652dda66f6b9854f06f96ebd75dac9dcc70ae1a3212b5cdffcf15d47eefe31c8f90e63abebc1d8dcdf8a4142eabca67f43ead1551b06d95c5c3fdfa37ea1756ac120affde6da8d6fbe38e9d72fc84b678c76c667de62acd50b923ecbb4f2ec1b99fd58bb206d6d8cb5eacb7573ec552ec88e76b1b5d3f67df55ddd82ac8f29336fac6a41b265c8bee9ab1f6d8c340b92cee83ef247cb20a38e6241ba1aa15738bf3d63cbd12b48f7e2bdf0557bd77b736a0549ed62a6edec73dbdecf2a4846db32ebd6b3d7cc7d5241be5358df7c5fac7ae3390519d775eea96b8fe9ec35a5209fadd459bcd4b5e7ed4641cef91d6775bde0d7f6ce9035fa85f0d508e1bbd7452848c8ce27bb6af92db72d3e41c6b710d6bf3dffb2d8a213a4bbcc42a6def4459e2b3641da47e97ad0ae09978b8f09d2eb8490f56d0f2e415a7f73ad1721bbf3de0695202fe409d9196de7983b4c82646eb3ce7ed6dfcfcb201264b3f9bcd9fa864790d1c5b68d56462773fd4690ce1bbbf894de7efab408d2dfb608e3c70799ad4904d9b53edbaaa5add9f8e21064b53ee76b8ed54b2f83429097b63b57d7b7af36c320c816ad5bfd2e7f9bec1d10e4ac90f9b6b37bcc20fb81bc6e3d325ff7e9a48bf94032e89ec1f72e75ffdc3d90f52bafb69c756c35ca8f07d2b5f6eeceb7dd4819bf1dc8f64ddf23adf6efbcebe9404ec636c6c9de0bfebd3990b679edba66a50d69b338900debb2eead577703d9ee3eb76d5a6add84cfd940fabb5f6ffd67f75b73ce8cda6fd1afd0b9d740c29fb0b27a978dec6f391ac8f6ae5f9fbf9beed29f81a4f02b6bcfb1177b95817c7ddfd7357945b89c8d8174cbd8ec4921bfad0e0319ebfc6f6fc50927645a86f4b71c4f47a3c775a92343fe5fbaa24f1a6d6d97db0b6465cdda36cbfc2d57ad0b248dee35bcfdcc3563c8bbd8aaae27ab1ce784ae1143fa5ddc225bff1af4e8bc13f231d6e072d6debcce35e7847cede8dbda70bd5ed57d1312b6ed78617f378cd35d1332b6d7ec3ad8d5bd789967423e6be3ebf6d31b42cb1c13f21d73f5fbcef64bc86967bd7e2f83cc685f4b4867e17ff7476baddf5a09f9f7bdbeeb21656e394a09b9dc3abd0e7a7bc70a27216f3fdb9a316ffd6d1f9384642e3a73cae6eafb5cb348c8fbb73e67f359e7e6650609e9bafb3aeb1f6b3767f608f9fffd6ddd9d73b62de608d9dc3f658d6ffb657b1b212d85ebed5a333257fa8c9090619dff6b45d61eed22e4735b8b5abecc5fe354846cfada6d77e337a77176222465eb229df0355eb3672342ae49ab6dd0a77de65cec43c8c5abf6834d27fbc9b00d215f5bd6d969d95b685f77212474b4ba181fe3f5e6432684b46db6dff65ab3f5b28f43d246dbbdccad166be387433eb62c9b0e5aff87d10e42366dad5d6bad20e473eef2f4e8de318d3110f2efdbaf8fa3f5c72820e48c6eba7f0b36cb6dc23fc876aeedaacd9b3af3e60759e16567ecf274f7f0f39efa48369173f441322f8f6ebab518f305b90b39de9073725f9eab3666bb32c879cc2c0d39f8209f3d5ede7aaee777bdc779bcfa0b39dc9097327bed2edb7541db57c8d1867c2eda6efc6fcd79a333a79a5b8462b828401672b021d7b42ed6d77cb97563b59cc7cc43c8b107e97f9fe1b4eded5ad5ddb5de629aaa14205ca4ea6ecc626463801de458433ea73f2bbbcfcf1b7cce79dcfc1239f4206bd7e598ffdb4ba9c3c979ccbac83475403e9ecea7936eeaeb3672a821e18dee28ad2bde08b945cee3694a22da7cfdfaa13e33a24e10d1344d53354d4080cc70e1a323aaaa8f21326d804cd334d5ce34b9223f3621ea6e3cf5ed34857ec30800478e3c48e71832ff1bdfbc8e617540c88107196df51a1f8b34b267ebba83b4de0e3aeaac33c86b393bc8e5ee9dbb8bd55e16610721471de4bc17d267635cfcdcbf4a07e9ef5683973d5cd6798b73905c9f33b57e7fdd385ddf20871c64ac77ddff07637d74d6fb221172c441fe6cb7cfaf9baf3ebf8ef378f3e01839e020ed8ab3e19dac2b85eb43a056418e3748d7adcddb207ddc2b726f380db95ae40bd7a4d429576b398fe1e3400e37c8656b75932f5dd4c55579866eba3f44a6c9c275841c6d9097c1fb1c63af45ebd41fe7c9e460836c7575f3e8b1b24a1b6d1bd1c33c167d9098630db2f1737e6b756bcec5feaa417eabefebfb6c0e7fd99b06b9a83b5ae3a37da1adeea241526e7459fe37fffff93d83e4659fa374da7663f4f56690cdb3f931b33ce7b3d396415a0bab63abebaa707a5b32485ef3dbd5699fa50ed9a221eb9ad3ad6d95f6dbbe750c92b5f77c7dde39fd2dad6290b12fdb7fb4b938b9d21a0669179bcb2984ccd6d6af8241ae3aadc73add3bceeaf50bd2b2ef091757e610ba55bd20ed74d4b2f7ac1bb37e6917a483b6ce7f2dde8e943ee582b45da3ffe2c5fafeb2740b32aec8625cf6368dd629d582b4afed6b5a5f73cbb549b320a38bfe91f2adac9f6b140bd27eeb369f3b579f2da35790fd2d7a5dde627c0b32b5825c6bba8eafddd51cfd45ab20179bb53e66deef61a4930a9299bf76e7699db519e714246d6daec6fe4ed6e6d32805b95e83d456d74ffd7bc628481a1d5b67bd315cb1bd78866cf76c2d7ece277db52314e43f87d7adc77139641c9f2027d308fbbd06676d6b4527488793c6f7decd9fa50f9b20e743f8d8f3e89c65944226483b6765cff432537e0f2e414ef7165f7b87b335e7500992bddeeb7132d88bdb7d49909399478e70fa74bdfa2141be175d656c99df11a4d3a68b3238e9f5690469d7a2ad394bfbc6d56811648c8c3a868d3173ab3a11243386cc9e5617d7a3ed86202fadd0b6a5d3df53674d0832bae560bb752dc3176310a48ddc6bc1bf0f3a770804d996a3cc2ba476adc6dc7f20fdf662d3ef5bee6f6b1fc8fbccd66b117275372ed6037919474bb93a7b7651ca03795f73436bdde78b0d7b07b21973e5c8e2ac1e2bd581846c9b356df3bde5eb9c0319efbd8e3fb275f7d98a0309e1f467b13d7803e993ffd6cbae8dbf9e17e7f1c7cc8faf20870de474c7663fb61665d3a319b2df556be7d7e991d25703f9dec5c9fc60b3fb5cbb349090adfa1de15fe89abd33901e9788a864f0aa959196a22086310010425949150063130030302c1e8d86a3f178a2287af203140004597e6a9a422e124983c1500ca3208a82180662100008208410628cf14a116e00c03ef6a440347b8ef61d6168e8db8d0df74bf5611d510b68ad2dc4e0fd4d8a705a5d0d20b5810f42cc59fd9f4544d406b19c83a5727210ac88d8bc7a22b7f22c74413e376766d43f788a5fac2fdf055a20aaed78093242b7db8e7c7791f20bbdc6d4e1d1c0af715c1647479b78593ce764b6f93fdf909a5f5470cd7fea27029f280eab52b3137df15661e3323b8ff7015830f651a7273da49283635c46bc941e5f330b5c53695aa4c414c740ac11cc8cf434f43e3b88e4e300cbcf1b5855b61443e3b7cf3ae2f58cbe3a857309bbf341814fac97189f5c7dbbd563afe96028de3f4d559c637775ef79a3917c321f061cf708f244ab71818e38d3693729bbadf51eb454afaaa0d78a3f4d96679d2e21ac2a4724c040e4260cf2b64988d8840a4f118c18df8bb57c4b12d0f1378c3da0aaf7845d991ff3d2e20506a60f0aa374a0c8efa7fca2a0a21527897b47f660b144cda256ae37b42d3e55cd014e24343b0245cc00d7683431844a4d024634b43b04256600d928b43186524d014344b43a0635a600ad515aa79145472ba4a62af3940685bac813d562c2a15454487a9b188e64b508086641d025fc6b50cfeb6ff590124f46d0febcbdae95a0e40be251b52f6d3c1b83e9328941be548d995566b1a4bacbc4fb17900195418442a82bab0fe602070a2030b4eed4f5c941dd598cb823f387efd4d4632b82e965e5d48ddeaf1cb73606e2728a1388010a05ff86fe03848fab7cf105a2e4006f4b5c860909ce6cb43b4223b61ad1179b067e396222d21b4b2fb206a21d49117b35622ed207421dbb22a26e4e92315b2af3bd8e0d743812230636e22eb60c9c3ab2a2440bdbb494cb10a390de587a252ed413d3d1fe6ff0381dd8e5b83a72928c8a309d4fe6985bc7bfc47c0397c5f1dbe276fa2f2b5ff4b24dac5c183104e9264bedc585d4cb8a6f1d058ca38db8ce6e276d68cbd03a55b24bd0f5d2245eb95cd7fc4bcf0aad93978332a153c81bf241fd5a11d38da48bbd066e1cb1474aeaa8c08413c8ccb8a5ff1bcd97b5b4daf0a490ab1173b17d4c28bf2cb7e87f9bb272156230d209961ab214a29b2415dbcb2d9a5f38cb4feb8525bd6b510ddf74b7417f656659966b0d9b666a9e068e85db46721620ba2f4a001204182f961cef46f5396b295ef6f0725dcc37df84e951d1da2c706a31db74f290f1fde9e2a18c31dc6c1ca3fd8cd71ea7da9dbbdcddb6d970c5a861734295122e6558f85afbaa0ced3d0e494ddca948262bb01a15bd7ba69d12db681ba49b30cbdb7d19f28eb2710b7b85237b6b0e9d4bde82f1c80913ca03e9e787d9c605cec4ea6c6783853117b6c7ce70855075dd0ab7eca674514177509eea1601f155d06c868f7e9ac0a2bb4a93744b2c62e552a7df82c7c80e9410c6568f1a106f5926ebb53c43f68cca8287dd6264cde7ba3e28ed5506c217ce7c270e662b2b5907a87fe8cbf965efb3b7b4b5c7729ea531371476482df40841102bfaf61c052b0f0f36752491b2b48b4d352190a2dbc7847ac805d697dac9d4db56be954d37ef10cef6614f290e60e834e594ac79483a807ecc9167e8b4e7fc17e64d6a7197a7ffb60324d2c0f265701d05829a8c5336af89c889c2e384a5052572bc0366cc4b3f92f636866a4a0ba2bb4e41041b08b68d12286dc13911d2ed884c9befd5c8c24c76df134c28b0aefdbe99986f8071a010630bccc416981aba14c7171b16bdf4baa4b93303585488bca03c33f1fe37cec4ed5e7db1cd7835346c12ffd18a84c2146237de06cdcdc199f64778ebcd2534020bf1c675f868d73e0457b31e2ec063f3fb0a85487dd6f5fb2fd7689e767eed5744420be03cd8cc05d25fc961271803032f9c728593fcde6332a54317018b5a471ad5e0677b35288e62d90ee373d126c2e93a29f3d340ac41f68f323ae6e2f80e81b27bcb68aada9e470c4716f437ef848369151d5cf6d460e9a38c27532573379c0dfc3517c428f52d4c94ae18c3bc42254650002d2c6493ba240c163a89265f3d0fe4f44eb282f3933c701949a201f1c217b46b28d8f5f9340f6559debd6f3a3d304a6926664c1c7740d4ebe62c7e155015dcba450bd716f65abdc3fadd02458bd856f5b550c362b9c58c56695bf06b51864573ab2e5ad8b6b8d7e28755e416315ae8b650d7ea1a16d32d68b4e06db55c8b362c9c5bd868f5b6c55f0b342ca25b55475d0368f1440ef9b59d3bde22f31d0369abd85d6897557dec455c4cc6a0f8559e314a7dd11cc36957b5cb6c70c7015b75b281a61ea2d4062f8d92666d82865b3a2cbf715deb6b0cd46144d7a1ffad2adf582b639a0c6ab5f23da3b046c3335cbed52e8d6b32de6aa03d6be437b4d3509f63115927af415d07ff1a85606d26c3d91b16695c36eb171bc86dc4df0d3dbdaa93b17e8d9977d0a5959b8c626fd8908db0ce78dfdc349ff6e9ba2abdbc22ab74781919c3ce111c1ef12dfe652bec7b42cb849dc1fa7340d3d0f77f6d6337f7df82cc9804a31b7468715d4016c709787d4f16e4065c7fdb19eaa279bfa83073765a6739bf1351e54f40e22a2ed8f7640d0d477fa262f489c1ae543fa3dad1213ec7a51a841cd666717e315c756d879077f10f392723212f29cee423df9a0c0bc3faca117b65bf562bac05247f0d95d89e1da5722ffc705194fa79afadfc08b0004faca5e3497d63ae05195f38e2262756700962671bde531c050685e24b445c7a0a995f26d17990d010f188d9b926e1d70e778b0f1e1411ccbe087cbf73c6a8274169ba76a8ed86ea20f28f3d7f27e94f2ec26f5cc5086c13f48d54e9f2bb5f0e7aac40cdc85e5c5522d0d07c8f135a0d67d9ef80b87cb7c8ef882c1dfd379e4b1ca17ff286936d98fb4fcbfd43a428c3b888510f14cef3f8a1228446e62f3ebfbf801a18e91203712601f84ebdd7b4c8d53ee143988c3ba2e7cf07f0de2e122141d06a40c9bdaea3c5d667edada6624e0edd34b520922ba36ff7db796b15cd379c03b7eb0cb5923ea410a9d47b0e2f223fa4fbd6e450354e7f2504f4df5cf4e1ac89b8eb197ca51d44e6c78fe0d066e627ec8ba4549b6f0a72cd04ebbfe59cf1eebb1e294fc75bedce8f02c3c5ce6769e661f1af1366453ffaea09e3e2c3dfb8dcfbb9def19990f05124a4d3bd87cfa9959ca9249122ee17e94c077ba424750a2a93e1fbaeada94959aab5b77616f436a9c6f788db4ad2b58c1a6d0e684530461ea6ec69e43b661f939b7b3cb02792844409aee219971f726fc7e7d87c8991a18a7adac404bb843238f551c28e41c55f69e772ac4eb54eb212708e75e70f176c0addba40d31567ed46f177816bc26d2282a95b7ef80148e8d3b689cc47ce52f679a1435fca2503b85ef17607876b7f92923f06f74b9908c0cc0730b031422c631b3e7a26ad511bbebfe0a908d334737b839333df9933a4b779edcf934dc68fd7432a623579ebe5cd3188f5d1aab6bf1ce093dd198020139c92dba6a4850e0596c1f317978aa487884803257c71fb8e8bbfcb2566fc88572d71082992bff27a380da0e51382d7f438f4070dd56fa239e89f7e4888d5c9ed7685e2290dcdf23aa6a8c02fde2cd94903d347eb7033a77246c998f064b19f922b17855903e69d553d04a0f6713a78de139d6d1ceb4694ce727a5c27ea06a3249a2e2a559a6da78357142b20e0089356cc31a9083ae55380fa68403147bd78ece1123224cc9f5dbfa4b07e09f8bd21a114249896b4df49dae845a4cb3cbecef597936000d8be25cd19e5b88bef4a557c398606e21965771450f4a5aa10597598a6fd4bf570190c308bc353d738c6f7891c4f12ca7b93a81fbc00505211291fffb4fef73b01f66eaac5a1bd1756c0818ea8abdee109d333e504cfa007d240142d0039dc1dfde81437d3e7add96ce88716644aaa3e275acd46d28fd9dc73f345f6b3f66ab40446a8c05e06ddd0845d07bc27f6b7cad87d00408eae632c5022bc42de5f160def1dc433bb5fe55d7b31e80aaa249219f58926c5970b2ab480bb6f8faf43ca4d833d97708dd997e0897c4ffe2efcb8f305b23c2015a9f70502c42bc0e5242403c3c90272dba7f8fd2538604a5e6221148eba4566f9af324ef844bee428366f32b279beabe6d0ab7e9c63c7dfc2e59e9281e8305eb71f0391a8aab77a1fb73db179e58d100ad2b09be65dddae58f344dca000f71200e27b63e0e7f9563481aa3dd2143e80d118a5aca32c02782db66e6439c9cd38c4fba064de9bc0de147522bc701f2e00f04212ef34ed702e017b623e53f9e48fd659da91e073b3ae75d2861cb3b41a77770d3627fb83aa75a2e88907482fd8586f69c8acce86d35a3b515a06c59c3e1e16c5944bf4e1718d6261d46e2fec908b569dbee34e195b6d751e188d3c60822849889cde55ad4c92d74111e0ac2b65a50683789c797e0d99f3b8b9398b744d2cc17c366868104f1b9f9db742325431149ff2546b7a51514829021be68331d8dd47b31d3799476ea3020419016cdb2c37e6a0a96dd19bc7e99a554f2a2ca1227f5db47b7e749526c9d65fee40e3fa2d6c0a6311e014c430a0f3220de787861ea4478eae17993b2ed31ec8fdd1ca7884d399f2e31fc8c9fe12c6c38890fd6b190bfa1341e63dd6f167abe9986a0853e59c434b30c1582a5385524445e2d7beb7176add1b8ff3d1a26b790c03697bc14646b4429f71eb20ae4db9a8e6b2d5d05e33fdb4e71caa9d35f692746242f49b6ccf5d44df5fd1011df591a66e3b9ce474156ac66113d8332499af1a49a1bea188fed2952c70de93d1b7779edbcb4c5e51b5c3816a728bf0308616e637cef76fa6d26ce824c5930dcb0dc1782df32613e8c29dd89461967585c0073f204507682b1cfee09e7cd246e0259b780afbf3fb8e297b2df2898245b5ff37a816a148cb1c185a76798c4209ea1a6cb3bb71fedf267553e622a49767e724aa594ffe57652577ca2036b1429cc9e7a528185d4302b9dd17fb3ef69c66a59620a9ead454d36ba99a88a8b94b1ed22a5677ae3fba95d37a179571f3d4ff693c1de9a1a36bba217ac15f026aca5ec0e28188eaf2cc243f89bb9591c44da6b52e9d773d17112fd1eb4b9df655206a6b87a074a0c55fdf375e319590e62e4969c93b0e254a792ee253a25c9dcff4d506ed53961066aaa304f2b18d2b4f965137a6f668f9e2914cb8b78f8590d852023ef7afb80f030d5659ea1613b2dbecb41277da0def3deba0051b1f5e71c93259b7dedb64d844c61cedd5a8c377739bcf408afc50546cab65551eb3d8615e6f1a500fa5bad569a772507b12a557abbfef016b4e869298811cee56683b7be466088f2050cfbed4cd922dc70c3753a04dc841acbf06d11da42057d57e45f57fc304edf0d22a84a55d982864e8c754e09c40aa1fc9e134d83b965702b8a48bd9075ee7108fe36a68d18034e3f5bf1997d1bf273880807d32fcd6487bac28315d286ed401814f921de50198bc57604ef4674175d442492f921d0630d261ab364cb8057aaae69a6b334aa85d99754146b59264b6cf27be1b87cf894fa7fec72f3d4be3dba0344647c0dcd4fad9a0dae4e20a12947f02c2f33c9ee5110e8a83a04871538980d9dca4b797ecdc32a735a53528123741455be5d05e27968fdfdd2cb8f81e75d2d902be426a9ce9e718a14bf41134e6e93b4e3e0ae32dd9e1bd8cc355dc6c58095a4e90d8b3169fb0ca5cf2c76dd4b0cc5bc19b54665370d63e51191cf0c7863d68ebbc1f22335fbd4247b004a43ff3e5e398e32b2b5b00fe91668af55a94639d340bb836564cc5503e18b7423fbeb9204554b9b41987bbcd82afff1362d666b76baaa3beebd58451579bfe256c66c5291132383fe50a489c041394b6fa2501b98b8d9ad5cfdc79a3a7172817c0be07f91154af6125638cdfa772e5390a4014952440686d30e572d1242c68d4fa8e1e4c381e1c461badaeb023523944d8d49a3599240faa8fa8462137b89c17a6117f2b3a9114421b9a1df747148b22681bbe9617c0a6647584499be813f8474cb31fbcdca8572c269770c1fb721ed75c3be1d0bf36bccc99d533b007ba7f80ea2035f5c5587f28bc08da9185a7e80d62ae65e90440ea2df604b2fd2b747feb45eee25eeedff5ff7228f4823e108e7506d4b0b8a864065686a2fda4f6b056480ad750c41e436abef1444eb1201061109633e14a99f081d0df7ae3ed84a69f8ff8095191e9f35e7a936588e3bb6e518b1c8dd5520ad87c6662381c920a44b1368709cc922e0763574ad0f8a5e106b4ddf2cf90331013318ce0698922771336c3e778b6f92f8298132ed5519b82bc9354544ccc3d8413997b4e641973c296e87ace7f9d26cd58a13461fe902626f4972106d7c1d4b87e6d33ef76f8a840572bd0762a0273f4beb07e74e48e481c7d61f3c6c54e758dab93d8525966583625153c95e472d537b64b9a4f532a830b43043700aaa39c8a7f6e54bb1f3185200f12e9e24e31a827493a4bd3e44849844d0a617b77304829c986729ec4b6c0b0fd58e2703e6fe4d990328d6c30f0ca073a0c8da671939601005ce50221ba2c4a5375e525649a12d86d8d6b67dd4dae83d82f2d4e519410a4b7285480feb5919d995fe3bd95752841aad49190b4d809316bc0b658fc75b9979931c9eae19279e5eb6fdfca417fb9a9f6ea5efe4ef1a370e67c68f2e98a3695be1d099f8731f5aa5f5a14b534368a4c2b4c7b5b6b542709b4becfcafbb8e73e6ce0f7e61edaeed2dd28736ebedf03e8132c3cb8f3c917e0f95cb08c28b3c93fa4e1a468a4e967e8058ed173fff9bc1135503c50e7f6aa0b6a80cf1941a4bb1216db06d8a5d9387c8451f889420a5b9d78485512e496d262e2c170c11a5fb88abfe294daae3615c6234a3b443ce6b7ccf98abe848e7cde138095329f9bf2f591a577b1954dd07d5a278048dc3eb1a1ede406bb26b7b8def94b67fa1e91a49291c11225936b163cb38a1b24b1b2504ae35ed4afd2010d96493f0a2e8c791a596fad4dba977ade6be75e6b32d8592363b0936cd8f9e47c9e3a6addcfa17fce0df7b885d27a64dfd6d8b2ab779470afb259403799c9e50a4e2024d09b92b43ce18776002c5799925932a561ea3512179400436170d10ef6866a5f2cc22b97c81cb495ee77379ab21e4c2c4b5d150fe7c5327dd6bb1ddb9275bd95cbfbd760462a798f00a2787c4366d2942fa8c2a779441dfa3a40387e1b5831698a9b4148380d157dc25f9186455146cd767dbbf4b858576b03dae235e5e9bd54039e34f55a7e26c60b1ce8a51b4de9c0d82fc766a2d032de07011ea0732a90431bac4dd5abed3e11979e3ec6614d12041bdfbcbe16e01f370e9e2c3887385e0ea7f50cbc3cf6e4f2dad01c243cb7bc6267e100b6c01ab62b2f0f0367287fee581ccde8adf52ef81fa2a5eadebbdbc21888550bbbf25b110b3e8f17720570f2421e5ccb58b3c687f050a20eb9f853c9d23bc9e2a2c6a79994de238040d1dc7a0f266158d08a800eacef02346932bc301f712801f068d24a095192310014fb0d1723eff46c802169607eb100908fc48247546758569e9f109b1ef79c5c4a72cce6c4e8c841a88e3b278426c307c76872285f3a058df5271786c874c2afb1b2f8b1fc73bf7d72d1b341c6585f8f9fade1b6e5d6bdf442ae84a7de9d14c82a49bcaa16aa217dd2a1b625812c352cc0ad60a958382702c2f6903eba36872d22582cffec8d4885a1f7ea2a8c21083effbad3cf83d14b75e746c67a69c74fbe61d8c6be7e5455a24f92c671b98117011c1ac04dd9afb756cf440606a1ac349509f3bdc171f51fd526b06fa21d41a74176fc92029899cbdd311876cb419644facd1d5765fe24e06926bf1c2a3c5549383c287d49bb9340eafd09642634eef18504e04ddf0ccf62b06bfc0455f1c52e2978cbc105507d43c5d391fd6e60e243005886e9082a488c80f09564067f9329d546ce0b47435484e53bfb8a3010bdd463c8d4901bee7d2d21222f618e5714580eacbffe81fbef2739c0713a880e8ba7111650da432a158a6ce78f77644c1ecba2cf34915f50ce62d35dbc9103e0aede0442700e43935d1732f89e9816ddf920a10589d0502ff690d3e25663d2e84f49ed758909865c01fc44c568d0b8bba6e1f9bf59e56a146f1dcdf4e4d458e841d5836a6a57c2ae2e04f2f195093c09372dadf73ec1ef940daa4603f770d4ac65338e0f90cd03d758184879c4d17767de5108b0d4f22db99048f10f46f0d321284058a158a716c077093ca5215b380644d1d922e1145a7dddf716015dfd7499a381be17f4ab2ab9fae43d5db30973aaafcc5223883940d0d3b0a7833903c90904293c4b7b88c7e6a8fd734f5428f0a29c4648c418a6e0357f2ee9c883daa3135e28eca0a75e06b18b51f8081c452114027f1b64006c59047e96c200505405f048f82d108130e593f0190a0241d0178123e0b64200c7a9f2fb40a87ccf1755ebcbb25c509d595394aaae116e3932d53b538c88877f023f9863bf09f61898f179bc670cc5efec43c1f319c1ec5d8d737aac1a2286c1787242140145936f5397db79dc31f8626dfedff3101993725363c3246bbb538d2c454bd0a25cdb69cffb77f6130391dc204e6d7f6fd2bd7aaf37f649bcb48f6ebfb5533becf4bef2e5e4530a49a088f88fb1581d153fb0200621229d9f3b6f87b6d007c589f3e4b8241b5549fdeca443fbf6fdb5f3ca34f45abf8368f47e269ce28e1091d392f91a755e647abcedaf931fc270206837028b605727b0649f35f92ff79edfef7f31971628892ded4412ffe68702577d8c0a008cca2b21dbbdf19ab264a423fe5105c80880bfefb1b04635a45ceed05040a342edb74ab7298c817ec3a69fce4c638ef407b43a4c022839aa1542ef34c57aaa6f86ed755e9199adc08ec0cca900b9f9055148b23d931eb70a9594e72389e1e639be4641befb49b6283b53a6fa2b48a27bbc90dce3cb532319a6fbfbb9c132e1ed0e52ebd1d627472098d895c0fa10cebf8d7f3a3911e0e5def01884ceed6d2bd854ab07808e83942d3b37b0feeaef0f36f0a87abde0620696634cbc1466917b0d2ed67e70bfe1e5e0512cfcb27c80e8d7537cda2a9d93649fa61e2fc705df0b6ad3f520bd8faa12140f6b52398b8b0c503f11a6eda3977e60cbcbb8fa55b389668d5f6e258d8123608a591d9cd52dc24a7f7f8debf662dfe958de04526bd4a9c8c37b8c44b1b7ca7bbfff6357afdf6edf047f13988dbc4cb4641bb9003658e1c763c8fd206b96821d1281d2fee0be074c3b4b56a48850e09a8eb9c165631d805d85f6d238b847a676428dc9b04b3b742021d7dd890972be0a32abbc913558a4f417fbfcfb396dd189dde5623fecf9af4dda686518cbd2db55081fe335ad8081db398c83421cdcf230ffd96721e7d8d921092d617cac5a8bf4dc3380c0d83ae6f739318fe3936f4f021b45bf1a112c9167a48a04079b8422ab4e70bece405eed0cc0626fc4bb1e5a1cfedd31c74abfc41b64ec5b6a9419a002fd88959e72a605ed59206ae936b79ec0a9743f981e128e05f709a83521d048c3fc2fd7f9607042476c06ef5fabc2332c583f68de3c4bd884da90996ff53012dbd7e66ed4ae4ca24c7e5461b4221fc0e77752678ee914ec852658452bac7c7320bcd5c11f32b09bdcfa49f714cacb9a2076eaed96c46b1b95806c65e154516a08832d769fea12ed0504340d1f8799d77757b00f3a568fc137fd06346bde0d06ae1f50856b6c0d79c1ae930ae85c9b9ce4d3d83f6bed66187a6a6703346b27bfd6bbcb0daa3801ea1cec5af7b85a76c7ba94a3752ff3d6083e5f4ced826068453092c869d74847ed76ff96f6b8258b2f752d1041431af1d6847f51ad9911ced22d2c5ba38aa970f63c7bc28aa647caacf1c0db3a612a35d5fa9b74efc917b9cd8d727ecda576f0fcd0f92fe45e0be1fbcdeebf68f460d09511647b6448a2a791fe7dd2a392defcb3d7e461f68b0b42ad999d645549e2411ffba6f120fbac7af9c24e72d818e96a8884a75b72eff36d0e081ae6b030de0c3037d1fa22e8a99b29616cc7924b0319346d756f3ce9eb78f62d9fb0a6319845546cff6f395d16e19e0f370241eabb1cc453170fdeafbe019f0130e28814890900510e15cc9d3bf124b28bd4eb0018a8aad49acc320cf08d58f7d32f486ca56ffaa2c83b4b394cd1d5d9e39cb303ea2de75b2a3f5c7e3261a345f2a3919d2ebb0e1a873e9a76d568bcf8eee7649b5973acf71bfea9e1be04c6e36f387bdbcfb65e5efe2d1a73c70e79c9569724cc3fcbd7ced46ca039b2140a46307f86a172b558eac56da7922d72378db41c14ba8b0d02f70c436c623a01828d724342d000c5d6dc9e70f40013035e4d1c9a5559ef39bea42c5cdc001c6e735390bb9370ec05e99fd364b6b5068be035e66edbaa08b38db961fa35dbd2ab754f1f8dae74c8d07cd36520447eb6d52e78981a22dde389761af78e72d7bfa7ede68cc5cd4f175b5b6817119e9db4c71f2d4298bcd5223f37d85d72e5dedd8466ce5c0679e85ec930bc8da509be3654062107f0dbd5789fed93a1e2ff2398ad48317786135b7b10d3b8081bf62b3bf4e26f338bc7a38b8727e083d4ab3839bf8427135efd0d82895bbc9f9e5397b117beabcbdd403fc0c9f13006e2a699819352b73a9627ece9df07df6b4e93e8f8a3bb9ed5baff4915f9987dacf7a409549f77ba0f8e58b5354921994b0bf061a32ed41e3dfcf4d534caac4356eccae07c98a338af9245ae7e1addd5dd6c0c534431875f09cb334c344966eb19066d6b150b8198f40a6d66afe827fcf8cef3f3c3b2f3a31c992e11fc1fab3f4d802e4071ff7f1dda64cf41867347a4d25d98fd5557a34bfd07b77efd1796d92ffbf28bcdfbd3b8ebb38ae393879a8c44d60b8de1095c7462fdf67077bacc80117e78ad2c4cc86081f24fcfd1238d23d1d018e194e50f287ed4bcbc51aa836cff51729b9a019fba6ebdf979dfb7656ac33a5ebf12f9524af9d68ee00f30a1500ab688edcf2e495afaf7504a8e340e5bd8f9de33878933691f04c72feced32bbe92e301d7550b2217708cffbbe632094beb5a9bf23cfdbf5aff71d9d8556ecfefbd326ded2d331e1ad67f25f966e604c89445dd307500817c9c5f9d5fab86d44fa7ed2737c43d3782e759da40ad9e8418cbcfe50cf36ce4de3e479a4ac5e23c690b73b69f0d27c5983ba79f37d4d97ac3dcca5ed0dfcf65f11b6a7862decce17ed67689dda38a4df71563a9329991b1db0887b720a30f28a74ece4e1a96ccac07988f462854e67f9380c242ef09a8efe95a6be4c02706f8a767765b67a7bad4e8bb479482e163264db6521dbaf70ed6bff9820e3c1f850a06e9b37b2eb3ef95956ca3677c0c84ff827c61cd492197eb3d2e0f8910ffc73639e9fcc2978aacdbf453d307f5788445cd48e339a0bcd69e4693bbb078598b3370fc9a99ebcf8217dcbaf1e6df993c58d2450c4747bc637db8d7d6fda1a3beccc7b28ebc28e5638da8f94a997f6aae02aee6953dac94fe83a89800394ca57f00c68c63dadfc0476428cd7ae79ae796f362a21dacbeafe232d827ea9b47b8d88cb18f9ce661148c2dcb03e7aa80730bbf4b12c9b38e77db696593c1b9916ef633bd1bf164a9e70353d5d73bf6d4ba405b24700917aaa4076f11d10e9ef21268077620b0c9fd4075feb4d4c298bd85913b18d854e909371b241a2b4cb7b6bade9fb7fbc8dcb67f631955134197d30f13b7a8fae12b7307426f55ffe6c477d4bf90aa352da52402608ad4e91f14d414b0fda2cb9567643c8f6994a6a0d1704e7bbb38e9007cb4c52748e7b575960bd572b1cd338a900d8dc2f4b95a2029c99579767e666e17b98f2ae3e438f99c46a420404039b0d0cc2f151fd5359a1ce6290169a330b9f5c73b7fc705ec9831fe2b949869b74ec5e83adc3101a7a6886a72fe89a748eee48d4f270dd00f1e982fbe3da37c00062b8bccfef710dc6a81764d66f5d05906166d02da05b041e7fd4e890bd5fb63d717f5e03f6f8271f8e32fa46e753c073c878a0fc3d2041f4b1233e3f077e6e22b99265becd40641939794df96b46c6c78810fc45949b6054245f53ca2f71e2dc14f97b32007710852f07930f0b2cd3403c85cfb83e58e073719f05728cedd3bb2b3d194f96d3f0bdaac5fc67f3d782be3c84c7fba177c6ca61f307addeaf3931510fc45d31b9504ecb6baa7c2dcfe637eebd6d6203863f3fe95d91a5010dae7950ff0b6c14675dd77f8e2bd9b37f727af36be013e00dfcec11044c80db44288f783507e69878ce26e0a9c6e29ad5c8e0a181ee9ed023824f12035680596bb80758461dd835597f05605ef5756d2edfb8f1ede05351ffbc2752e1f3b016ad321a362abcd28e251fcbb663d246d1402f1e10990faf604733ddf1ecae3a66649f9dd3a1b9ffbd132d4bb1af11ccc174106ba9df3dff558c03489ec2446776e2e52190492e3677fbc865a4dec930d5a14d185ab7bc0284581a4b32fae82e1b384cce3317d7e8409fcc7201be49c10488e2288694d029070641f57a0f8142b559a5622366c4f91f8f41f315b905711d18a3fb5b310107d5d000dcd57a641e325a7aaa283301becbaee001fd693f2626aed0ddd517d39048fc4abb656841ed2e669be012e160271bb44479cd8dfc83ab08427e845060c849ad94db01bd5156a8de42c76f236cf1920e56b8f7798c61d1fef9a4588147b4dad0d3ddff7afc5bb02f4157ca808cfff53b0dd86a760db56cac048ee18e3b6d0887aec975dcf9c1aed39ba265ed82ae74101403e46784fc96f9a7af9444a96897f7a73e2d8718abfd497ec01215e841d0055022443f0d9ad14a05e097e12380a508e89c760496aa059c03ef8104419aa3f0292f801b06e1fe6c81832d45054316c108901d5428463b35885f8a87009726a1b3da1078ea367016ac071a0c6b8ec45154b369f48538087e65089ea88a4147eed153813ae0dca8722812429f1ac56f4503e04bf3d041650468761b3a8b56ab3bec12c0960d73d3631b9cb6c664d30b1b886b0d58535a0d22d42a2890e4319a7e519017c1c320f662000729470184aac04f835c000b8bd09f0518a0141500be123e0562210c7c927e0640a012f420f00ab85408c571e0097a9900c0cba003402be2d02329c68025ea6107c2780a84746a541044e419b9839fe63a538285e0e1ce0686965d0606c5e0fa05f9317632c0ec2a7f75871c9b7ff2569e640323df9a8af16a107e6382da6bfc5e59533c6f14cf03a726b0ff07358e2aa814a3fc686a78aef0fcaed790115fa9eb3264d024e82abd80d0f7a74acc55c46a8cdb3c593cf95fd08a08b6a659bf02883543418f71d2607bae5fed5207952f5efb13ee73cf597cb8c58306bb16d4c7f59d25c23ced72a6bd04b0ed87e2534233e2aaacdb04e9c0c77ff20235d952b1d9e69c8c7abbcad49ee595ead1070fbc4a5938bc1bb1b4ed431185dcd7b92dfb8d04d4fd0ebfc0aff2f17faee4309abdd8b1e6f2a995208112a5ba83d4fda2cd1491bc9e199bdca4223522bb30dbe198844c06cac52414a4b7f46c8bb4e74c9d4fc90483b53c348ffcf9ed89ff800ac23b2957a711031638dd9b21751184fb3b7c3924499647a200cf88888c0ecda7d14584a7eb5dbc02d64bcfc80eaa3d826c087a67e6c4885939f74f23cd37808172a3ae9b79134c040da756d6da5372617d339c8b5fcece04e71cd32cf605d7cb84fd98a3f5e10c6c844207c88f2ed27e838d0d243af92d9e7aae63909863d5493ce0e0ef45560a0eb9ae0243cbc74da16d171fdd1bee46a23f07c300cb726c60dfc23e271b623f185f69049fcd4921e50defe37c4ca777bccc8174fe80797015468743fa65c57f7937ed54214694d69028287e7c7552e976a23bd5c7c46f7f52d1b3473333e136048abd60f26d47fb65d7ed16814a7eeec98e44274b5229637ab96295fe0a579da178f26631d94cb012e0e1fa37facc309a51be243292a89d42412680d2329ec4b901747be18fbbb520f9a4f6e6c181881ddc5bd3f773658c9a160475b9b520a8cc5fc6c470c55e364bfe6263a07d44c8a7ed0a045456992116ba411c0caca952377d9b58b27d6758c597cc89ee5835f0848af387dbc8de13765e2dadce1fc03fec394a6d5b747e8040e08010ecb31ca4db31c7d985e7d054823549a65cee90d3d9afd64ff61b97eb7c079fc453a55c4d97379bc2bea3b92c6496a265b012a3d3f35ab0fb09ba21d3422896065612374eaa805ccc417c6c2f8673b9c33c8b5717b042d9e0db14b067ca06c4ad2f42c00ca7ee9faf87c7b6ec446f8243a85f218f4fbf77410c8d741d3b0463046684fb8e1af3991fa593d1693ac60d1ad5ab4e6b0982a20abb6796f9acd62ddc323d76d24f03bd37cec28fbda6430494361afd74eb3dac0c9bb227509b51b0cd5e4a4303844c641e091976e1bdf707114ecfcf919b0688038a73a1cfa39c050a4a4fe8c1403fefde5d778714353f6dc412f727c54a2c4a9180944588883af17b55f6644e906f7c5de55da56464604c647175a2e28a290ce1b284090410b8f990650c1da1771adf39d831f2cede93121b745fcb95b8a20d428103ff73d7578cd646f65c869b86b44f0b2be734b387fcb464ba2c3fc7b59f8cb0eff2c6e92e05f6cf5dcb173df2c5084ee3ca5606abf07222b057178d722d3fbe2e4f20e277b6f9fb3b4de253680b48adb05a8bde23242d1270b66989e17f365d2d3cbf7c22a1b11b52d023f1ea4119fb2aeefebe5bf7b7d949e8abd0e57048dee8979fa8f9a923689f5399e2691e91dfda84737a3957358218f174566e5a07857b28656c36f624bf23d917ecdb60b68fa859d0b0fcaf511b0deb591e137131542ccb16436dbbf1a3aacd7008e7237e8d58f9d026932331668169d0ddf7ab3a9c8d73c1fd305e7513bc7f12f2182f9b58bfdc36a56c6a6679f3ad8875b493b2c5bec3aa380788a6d35c4ce754139e74f2627efcba8b838ac86085f3ef65b12df9145656a71bef88ecca6ee97a02b79e2691e0e9036be9d6a3b10441186b426bd7338ce79e806733087a7b8f37e22bfb3247ba09399f6d696c85bea41b139e723c22f918fab56ac96075961f4b787ac1d0a70bee3736d882b95246ed29075db870b758b8e07e7e87e6c4852e3d9b45ead8383c59a08ac2851b403557dbc3b2237556e211e8f50affd7bd30c6203da89b9f022e4b267c037bbd31ca665aed9eb1ac7dc62769928695cf1556b17d16ed57ecf342bd483fff7f4e80db65973fda918844498c6fd469154941a01bb734d950e6b590129eb34626b0e3b2f6079ab3c41d6ce99f330d782e76499e23e6fdc18535eb0889759789ddd6b3a7af0a74a96a5fb37bd9a3c6c040ab2441f66a4d0ed1f14d1dedfc59af3f68d8fc3c98596a859033d7bd3c167e4313fb2d12dfbcc7067cd2308f02e73bbed98e412059b129f5a73fc6f8785c1708654789d09d28b46c747021d65f592833b9a7768bf3e2df0a397128f9f090b3011f5b5eedf548c04acca020192319d4c3f77d95bfd5f82ef1b2f96b37471c2fa0dc4a5a7c1cfa211e378e223b495d0f9cab91d85a2614bd1d6614dee8a37d496ab68538f788d73d28c9cc3cb1eed4a5b76b0f335c9fca8e68f37ea8d85783e7a935248f05bea224f1522797347a3ce77445a3434d5dde8e119f4fda400cbb37d91e6fd6bdbb6cbd441afaa21c1149b5fd04fedc83bcd6caf7b9421462761a29187c126ec80c68bf04de83339e9ab521fa28750d5bd8add669ba83d2fdec9a1e0cd0823f263e7fa25a3ae301731c4aa98bdea0d95bd4eae0e0630b73f315007b71ef4ef344d7ad62ff171abaaef55dfc82abf1d53f136cb859108cfab933036d3372c1e5b90d022737efe30c27f2e1c833fa655ee2ad5fa0cbfcf895e60dab807e3fcd3861b0467e3fb6f007658af778aa47a66a5b18ef77897989756c0c99461874aea86bce804951f47f86cc8e33da5f59f5565806f18066aff4ceeeccadb52e530849838132516863e7c44c6138f4f428cefd85952202805b7df9cff2fc7a9d502ffa304763b8ff578efc5ab580dc98b4b99fe5f090ec1c58983e340075253120916f10e6e496142b1f4d6627434094f714a40fcf3f8524de0ad21584b982bc3d74b3982e3c0647d59b471906934a7820f8e65a48214948b4b3f818b5af0b451b610cfac76ca0c2d301aa7eb92000a894793a057eb8020883764718075e0e2761cb025eb0b91f5387eb73c44c800038c182604cc096949dd392206804592ece1bf5ce6f195d83aeff758142cb7a8d19bccc43b4366ab5834638b1db7c2ba783db2722bc811b1ca4c61d0b14deb70fc48d8ab896aa50a18581f37c38dd83254d6510694daa145052c84b78a53020b2117168deaf9663b72d18e6adc5306662f1005a338e0a04020598bdf848894e1687f356fad082532d63e4fda3f5c796c836a1f2441b498767a52cae94b92207349714b4a7d3693e8b6f0bf7fab665db7ddb0fdab158c4141a7781c8a4c672f57838789925b812de7aee0f053ca88232ad582e98af92bac36f3943110cf07f96c288d3df98d8c515a29777ecc10c7aa2b976b2490df83365a5ddbf1994991e9ce856958325024411c9f7f78d02b50bfd9e73038af47bb1480d10c2729cea20cf4df1979f3535f3ba04f0b63c352d62230ee4e14c7032078026815295d3f8014b0bd366f2bbf5f91101fb2388f7217b072e05b41f270739d5bef78bb8a304265a9f32b153feb9dbf16be6046a15c917445ee7eb310b12b2871e156e0fc5d0c9c26b6e571caf9618b819e42c33a82b583fbb44c150ff333737b1439479f12b51352983688060b7c29cc260962432318a955ef92b2e811b2e89f6e75f20e1708b2022414f8aa5995ea3a15b13c25c6d4fe327aa2654b2798670ea8752c07fb5a47c6592fc2bf5a9a52487afcf7a2051d3bd53ff175527a0015553335aca6c03c55c177d9f94c88dbcfd3efee47bee84d36bb7c282354c7c0f84716084b9e754c3ebee02f4d027df4b08131311d05504f5c426d961a24e72e3b8bc0d717f6c3dd9a3991bfa53f4f2c448a18701cef19701eef285d252a85edbdb9b502b196ea77c5a95567de216097a34ceae75aef3c1360a84a8244381cdf0edfa73b0fc76958cbc2394c54c11417bf479dd86577dd4a8cf4bb52848bb9997263cca7bc9dd599ccee7d0aec1adfad55aae38cd38c5eb40dec8ae2518f48851129d3d7e38bd9d767b43158c59e3bdceec2fb327857ca6780227ff3937d393272989a76592999db2ac03af9261a0ae45b6627872a0e528b6ce6921c0e974678d446887821ae38a8798bcba3706348f6f0ab780b6c77f50f2dfb0ffdd2874a30b7a3ea6cfe38b75105bb34a7fbf39b482e9fb1eeeb700bd1a9316f6acdcd3ebaf6349460924e130856920974aa020d9c6295f11a6b1ed8dedfade8653233aebe4e2c0399aeef49169b6da154cc2471694a613ef60bf7cfbfd636dd1da0b5bb05b259715543710af6126a5242a6f7d4d7e324887a08578eaea5c8938cab7c5e3e4317122e7d08aade36614c01a1f5d36a54ba51abb90a433add9247384874e7d2e001d86c6600b85b2343b0f690e310b825873f91141921d9ca266afe4c63a244023150a57accce96947b3bcd3ac39125d4ee472e75bc831becc3c7c651aba627976598f72bb75834ab83ec878012c8355abe7ad876a2ef96c630fad84c96f710c1ae2f59613d3c52d38f054667c0d2a9259ba576ca828c9fd632178973386afb6e845c8a2e1e3194de0af1a16a4b04349c9d154a4ca39a3f8d8c4f138249e41d77179a99da09f9e4a73b64041ac16073472fdfa89d1ce7c15946595f0db3f9972484f290a9a91fdffbc3c114eeea4106dd91b89bb5f5f99d01323385ed83d1b5693733a5140b06d832977036e2d03721c7002425845bdff156c3f519d064e1df2873fe72a8375a50c6d5bf290249fa7a4dea6b840f0a6fd5a8536ab3238eea474bf74ced4771158a8c7ba1f32401cb8481bb0fe5d259a16abffea8f8ff1d15b0542122741c32088b7a705e96178daf28379ee9bc3df3ebf3e624962493f6750cf6e82009636c24f15cfdaa8620dbd945875664ce01688cbf318c2500003e9246495a6cbe91a0e0a41399b4d9d6c26509ace35442075ccf188d29dae494da195ae388e3a6c8bb29a1dba574a1130845468714d97f91b879ee28d2768960740bd49d43c94b0c002e93a52e3d07e0a447b26193ebffe2a10ebe0cd518d0221a2b118b3f6c170b0f185780880d7a2f324ae4e207539dbeb167b6b840281de93191ddc5d9afd9ea50838d8c3c64671047c4fad289d5b887889ab42e50731d16cdc1e630742bb263bffa6a56cd445766b26d1f7640f296a4bbac8404307cca0176f0a51f0d8983a0a7560f38095ae39b4f588d0de5ab01f419454c424064854ca8845cd36464300e277180bc74933ff8b15e0d4d47344e9dac182d686a1b4390bbb68b10ad57394f83cd480c4c50510e3c9038f56bd4d061e82b60681ee5fcf9a1c722a4e39c7c01d7ace184b9f2c38c8bfd5bd99682ffe893650c6c0f83178d0064a1bc2ee449e3ef2e71490b473eb80ec1efb95d5c3ccbf35fc755932528351aa6c50b38c9ae5eb58e8fa009b47be9279b5c3fd1bad68b95960841197d52ae062e0c4c865701f26f59ffb419571fc3c056cc86dc3607e4caf2406fd5154c064118a3482dca517d7dc6f6aca2acbeca999a3e5ad0df9cde74b1e9e728791ac3180d9fbe230c5ce73ebc309d457532e1d519a20b491f3c8282cfe2ca6765117c4c92de8c08ff9fd11abd2e5e1b186dcec0372c8ef3d1542a7cfc6a5344b15a56d13b06fbbcf2a8f9d416c98ddfe04d96a5d9f90d8c8e9e575d51b772302c41b3b16b9bc2ee9f198863f8f5ba4cd7603135dbc961cebfb34b473ed4a367666adf2b07e44ab1fcb10d4217441fbabea1eb428bc7045f6f1ea9e8aff9db94971de26ff960e4226aa964e21b8804d5536cdb05ba46acf8689183624aa0ef0465c2b963d1ee809379cbfd6a98831af3dd9d6629e3de56a084277f132b67c17717f385cda1566f9dd9a1daa4def780d35d5827dc0f6ac2639ab78f7f08a480cf18bef0e69e34ffe825884ea2a015fa5c5ad34d1f623f0822e9a15450cc367dd8078bd75b71002969a06734dbc47bf613a4c744006e8aa37e01eae1070041b5a119fc7e0d822e04660b21a16af8c077c59ec97d98f75350bcdbeaa548c3006da4ef08918ab26f16e1f8bb5bb88638a899514e0009573196ffbf510dd0981f02c61c569aafba7f025602aaaf5cbe2c517cef47a219feb00eb44119ba8b2df1109b655f1eeba3c4e84b80acbb2c7b5df040c303f311758e22928fa2ade189f1eb232d4940ac1361d17645ddee7fd893a1095d866e0d461201c08d3562b32ec556b2bbc2fb01db08c671fd1ff9a64d33d082889a0ad53af4d7ac0f02e01fc703a1baa7145e2e9123f903c5a185fe094233cf3bf18521960b11932b412bde418e556843bab311212ae173b6f0c1e11e2192d86b89ebe484df2f7c56215151f96afee4eef2eb1f225af644dc578821727cb4f28e19046c0a0d1be5c1bfa490fccb8ae8478d2bc424df6d34d6dc9ed8387d41702720df1c382c0d44bc3fd423cd4be54281e88a6da4192870c43c1f2eb7fa711fa4442a66543ac4f81e90483fc3b1bc5351c11557552732ebb7ef0f4022ac4d17ad720b3975029daf394684242fe4a03e94421608fecd0e51a0ecaa5d6e82e08485352503305ac470adc8bc90cae9820008abd270a8368871721f487a6c518603b7a5adf1d1111b2fb34196d35286003d19dd652f979e137d79ac4932d541ab2a0fc05855515bf0a132f6d5b1a3d2a21bdba1e6732c65f9d5304853839942e90184c5993db5c4a4a22a86cd323a89becb26a4a6de39b09ee77b798957db5a105c1212514d3470fe412d64979222d99c49e6114b1b7bbcf2a2531f5cded156292d56923e7e673d475040bdfc54c4b6b95bbeff75c686dc8f57d2cb7d496686e896635a38627e83c8de3abc2787f0b4e801ffbfbcf33628e816baed975bf2c60987ea3c6babc4c723c0f9c8cb91514deee9e6947246f573e4c7d773901e0ef79f91796abd65e0d5e732a3dff06a842fb4d2c9d8b8a7629190936c3fcf779fcf36f1451d55ca24194ce40fb5472cfb10cd51c69dd9a17dbb6ea4e1ed34f668e20ddb50a1142bfe01bba81df274a3855aaac96101f9ca0ddff95549483c6ff9abf6960f94b206c1caca4d548acd3f97588806bbf432f73147ea954bbd07f457292bca089de8040a0e69277e07e69a1cc9af124c1ec0318372cb8045ec7a52953c346eb8728acb1e2117f7c85401f322834281cfb982f24af2431b447f5f27ee579185f6e7c6e34579bb27d13f53b894f9fd9933ed8d1318bb06ccda1221af2236f9ef573e7ad68d6309f988a028ff863c275386c425812a24e18a80b07df91b9a316228a92e2da39a3e9f48213cadf61dc25647a16a2141a996a69d755cc458c321aba0c748f666112400d473d4c11617e70765e82832b0869b98528a33ef8ace312d96f3f4d25be8f2c1c66d07dbebfede4169174be0153cbfd9568eaac4f9ba065095786a87e5004f07fc71c085e2f5740698113dcef8f07738ebfed0dd736530d3931dccadcb8b772f68be37aac959a3ce9dff6180941f5ce55665c13324a037185720764f3737eb0030294b91ce519c05f3467e76f8164cb9dbd287e034b6b012f93816d221ad8f9cd68a03c2e3a8ca14bd40d79bdb1842e52e7cd094c7f329efe79e02981def22f01d1117b0650b0e04a2be79ff942c6bc751309fe40f7b7fbade6585f772c617e3c890c2ec07f980b16027a68b46c926bc8f205613c4f1acd35dc9158a4a6b136f745cda0901ea9624cfec022b8f034c55ce20a3b1a3badaefdd5e2602731221807a2ef05c68dfca3c88caeaeced8f973ea59828fc9b50b997d27caab83936ffac0de02e87b25b9e1133f12a90341c7df3917d21fa7ad18eb89f7b300c75f10fd712e6fb217bf36d3be4d8cab614ea644c026ec29e7f087a1e93e19bfd371fc035c519289a1004ba914541b5ff63d786680f7da09139a6397226c705bc6279239afba6c7f53a6416556abe8680eefddefe3795158054039e9c1095d23da86022bc49b07d2abfd97a94574d6626026768b21148068095d7669e8031e242a81582f8597aaf31325312bc2b8c975020743d0e22c9c47846e3c42d65d4bc26580d1ce392f629568d11d74456aa8609ddb3af0d9f72be147300a636c97b0aff027282e449361fb3c3d5f8f26978d09eaddcfd37327684eedda2970b8bc13608a547a473fefa09a2b242cfe106b75ce3c64e6c34cf1c6ca183c19e4fb92e146f50496a4764c443b8e7b2365b7a912454b50b02015d7244a0f66c5bbaa9a50377524a0b11e4a349f3720c2f4ad2e64a749d66aa9ba0eda7194e4bcd391ebc9977855fe2c9cdf41bc630180861a18f308727dcbd0d39b976d37a1dfdf904f77a6a40ed06dcd94738374389027d9018b1943c5b713325dc8b5de53e34db7cf819a55ea2fa52b11b05b2f06f31084fc2a47a1f72d6098df6e66181ceb8d40135120f055587a63e793dc731c3439b83d9ad34d6c234c11b5e368983e17679ed558a5ea7a3ad33d5b9ebe300778ef8b8f578f6e30d7363c82cd9f03e1d780087c4c182d72e0319acec822f2de2a32f24733f57413f6d2e693c7de3ded77e48fed03176d03e7629c68662b9410a68580f98cd4c0ade2e5d113f8d72379e78ac6038525b81ef549b934f85e4714425e6990805ea4f011f7e62088d86b11de93ae990135dfda335ba4d6899d2cecc2c7cd8497f5226b3c59af0264c537de2ee237fdaa594788747be37d35c4755475ddb9647ceb63b2066cd4ffd3500d1c8e023e5a04220b3760b46439330f0f0f0f0f0f0f0f6f4337426a6b9f908494a454aa976679010b644a29c99492d81dbc0b9c99f87466e2d31546ea6e34e301030b400bd30a89305b754ea153cc4f17311a1a68000d2d6854c0c3c3c3c38bbc0c801a6220c214d28388d6a39e7fa625c4388441e5edce5e2284ea63058d011b39ba7880214c3a9430d9298b440b63214c21c78b914df249fe104218b465c813f91f15620cc21871e5d6434b9e902208e3440b19a91e545479a2102310264f59952647c8881a157284188030a5e777f438191b6b016084187f30968e74f988efb9a75363edc3c647c12d4b31fc6076b7083243e465059386161e1e5588d1077357fef6f47137b6f3c1246eb35ebf9237ddefa26b68c06fd898c0923d186de28afa0e1d3d18e5524823aa3a7f3a711ecc5f174b955267a972120f8697a4b4aca5548086062440e3430b1ced12c891000b2851438c3b986ad27c74ad38f91b362002e50a31ec60be0c7df524667bb5af83792dced6c4fa09da6e3a986e5baf64752ef5e139183ce54ccb19a24a29530e26a13e57b8a89e9519d6588b83f14a456cb56ec2292538184ef6d8c9d0918488a637e8337975ebd52f23c70d068ba6bba5847e25f3b4c1782a629b087a7ad5c26c3089f59c82129d3c8851d7b09af89d69d3fbfb5d0dc6d1f62762470e252d4d83316757528ea8f360123418f542e3924e6a44fcc81990e79e7592d8f0dd88194c9fafebc329b7951896c134e23e23f4d998fa6430bd560e39a29ab0a4d9180cf2246987284292490cc69ff9d4ad94264cbe6aac1962848131b7d9ae20536c3430587a3cfe09791771fc4272a23de2880929cfc70bac96e87069d927e98241e9d349674cdc0575e242a272ac3d2f919152bd05decf52e447e9f4c1d58229e72454dae4f24ad5c982c94212972fe88d05632491b3d1174a4551b942fa4b5e9f1a1d4f3c620593aafcdb1dea296787ab7067cb13dbd46a6255a86052e6de267ddd4444740c31a660c48e14d192429784670d0f69267f4761d7125365924b5ff250307b2425df15c2ab3e9e438c2798cebc4dc6e52427182d8f7c87f2fc155d9b9078710fa1cc4c2618c4b6044942924b583ca565c7d2217fca9460b6317defb0d57f214930f68dca496adb87f00e09c6f8ddf3aaba54b61ec1d319b135ce74881ac1b8af27c1be6e2c9f72885104e34a34a14f45869e1e11c1f41971d72dd4ef538660505921e5e715e517662198aeb346eaa80ad2471b0483e855f79c4a6dafac4030999950b9206db573f20786f7efec4e7af744f6d00d317c9068a6965ddd0373b6c41c939397fb82789007af3e53a24f9c24edc024277c56ba206f92b6bbd8a26f241d982aabd675f47091d29203c385e7eb087bed220eec0992b642527cd9788353fc38ba446f820ef2183630ba6e8b6e0fdb298aceb521460d887f49f4d7280f950662d0c02ce6e13cae598ae4a1b121c60c8c5e3aa5a81246eeb8be8618323069cefde76f856889c5ba9f53d8cfb8d2aec1c254276ef73aebe597e91546fdb4edca31b57923572073ca9369bf4a2b0ce7a3d4bdc8c6fdafac30dba7baec905ff2bd5d85c1e444e5e6fcc83cb9c69aab1960a8a2ce761792852429684f2accf196653997fa4d1f15261d523855d7317e3a790a5418cd4ea2744c5863ad057e820fbe1b3672743185b13b6591f11c23966534b4a0d1821c5ea0c07451011a5ab4e0867f71011a5ad0f02fb8680ed0d082c69db5c02340430b1a76c39d8bf3850d2df3a251f05186c3bd68418e2c85414f7a0f8b2426297b5218d56cd4a8f4f1f6b98fc26c71d2cf88c5eed35714c6d1e965fdc36fe49ba130cfbc8f288f7b8b2c0185617f3b4be7fe2cefdf270c2e4946d0155a3ea25d066078c2a04694e5ed59d7fabf138614f22c56a8958afbd4d80d745181b3829c30870d911e72e6dfb29cb809e39c271d99a142de4713c60a7af1223444ae8533611049c5fbe69e4bae0f26cc79c5de7b74ec10a2a55cc214b45c4d9f92aa22644b98d46595136182ead866f2004625d491cfcfbb1682caa2008312e6a0ad2797ee5b93e1f8c8f3008c49186553c4055d59e46449560086244c1529ec8e55d808ebdcb8617608302261aaca9ef8b521b2eef187106040c21ce36e73278b47109700c6234c6d415f0e42bba9578405301c61d8b7aa2ecfb7b0145463edc373d8e8e24e05301a81d0191e3e6444790306238c713f62d1e43efdeb35d63e10522f602cc2544ae26e9b84a4425a6aacdd5084a954764cf86c3fe67101231126b566592e665c46b4cb4c000311066d912da851fe41a4d3210c7f61db43caa5b9681bc29ce467e498a51121a51026e5392e9f449810061d134a790ae141982508f5385721447a2c087329ebef2f5526e60f8439ce6ea464656af2640161b69446be8d8a21e4db3f987d62593c6bedec52fac164f7df69fb631f4c29ee6e65adff50b3f1c16049eb6666df8331458ed029b2249f5735d672b4e0468eb5ced10bf0e223c905400c30f460bcb4f1faa542ce53aac6da471d0d0d34600b30f2600a6982a4b82e5539b45c808107f3e81e93b318dec1a4646858588a4e96658db5b230ec608e26579b3ee26bfe5263ed830d07a30047af200130ea60103bc23f8556eef5c3737c617e18061dcca924a54fd2f75ba489e760d64939b722bf65cfa68f3b030c399844d8a9a0ff63df851e0783a58689a7541bfe4170308e507955fa6358f5fd06931033ea6bb47583f1d37376b8d5aff8691b0c1adace3e87f8b922369882fa4cf652daf4e49035183f2d98fb051d6f92d460887339fc7327b17f8d8b56810d143806baa8000d2d380dc6d02222d553f5ee99ae00030da60cfbf57af7703eca3318b7be26ee8752224c806106f359678b37eea9457b30ca60f2cad24946844f8da700830c067517ed83b4fe1ba53406e35ad871cbd7e3b29be50186188c5a5b37bbb67d9d3d6130a7883fda42ae99f6d100030ca6b3b00b914275ea60d6ad01c6174c9d5444af9b8100c30b86f43b97bffd9e7459140230ba60ead4157ac7cc264b8ad987a11c6070c16cdd162752f27a1bf9ecc3181030b6609049317a1e52d809920f3336c0d08229291d26ce8fc9979033fb30b5d2038c2c98f7e2f3558a8afee75830a8591ecb3d59bd3aba82f9564b7b5cefaaf3b582e9b7a3e413d23e29bd55c1f4c9b28856bb5890142a9854e764a53fbedbea3b05534d2c7d77aae2e7775230a9a06137d2ac24465214cc7d1a298d2c75d9520e0a062d93b297d095ad84fb0473cdbfa5abb658eed209c6d5b4504ae57cf6779a601a6d61ff45878ffa2513cc6992b07fff8ba054b40453ec0bd3d6ad3fd7394a30789add480bffd22d4a8239e8a860fb5fc94bad483089bb9f117942749b0fc6114c49d99a488bb011cc11840a2a87d1cfdeba08e6ad6c6a3f4b53438f4430682f11b211f3b22f3f028c21984bece28afc8a259df6f0281f8607430826ed4eb1743e136f97140473bea978d6ecd68d05046377f5886b7a7779f903c3488ab964a13a9f181d0e183e30d75d075d6e32ebb33d30a8b9a43d7479903d2e0fcc155ad41d988358499ae02af945d68131e4c73ebb49c2c4e57360743b717eee57a16aa3a1c58729da62cb60e0c03c16225cccc98c8ad40dcc1f44880525f46f5ad60626fd172d47dc9aeceed6c0702a3e8a4eb942be80410393b4483fc2d7e4251d9d81712b23a7bbd58fd41d18323005a97dff932a8ec9321646d3f2380f23a2bb25b0305df06afbbbecc9f4fb0ac39f4732f3d167b1a72b4c62a284dc5e893551d28286161690000d6d81005a6148fadada644c92159b5ab10b08801546133af5abd492d72cf00f1b393ef05620805598c2da6ee7d3a810376320005518e4e7be3ecd5f68130502488529ed2911adb40987aba09d8b0f1514c31b282801a0c294ee84ae4bcb97eb2fd2028f403985c9c427ff298b98c26057396e9696ecd1430194c2204566e6ff7bc8be202408801426f7bc6769a476d2e6e8628b1a450b0f8f519852f8879265f7a62ca6111e672887243dfc2e5f7c7461833b8ad0610643d075973fa67a8f9a40e828c32a2a3ce928a24e7e51e82003ee5f5e9d25954612133ac65072bb2f31cdd0b30b5c4287188ebb9611cf7f346ec1f9280b833945131efaf24608dae90083214938713af79c599a5f3086e917ada2aae7c4e4dbb9282fe8f082e15bc4bd54e42e186f74ce695ebac73fc905d3e4169973514af6f45174d0b105939294f522df4d9cc65a3098ce2945c991d4a0230ba634f12a4b92e4ce6663c114f428a56c47f44b7e35d6cc6868a0010ea0a10109d0f0f09041c7158c3a493c699153b357a264830225d9e8a2eca4a500083e0cd0610573a4ac9491a89d26710f0f5e0a80e003004ee8a8824175ca972e6fc99354d5584bbbe139fc861766aa800e2a18640979f398e421775330a470175b17b4e335cd8f0e29184777ac185636f3f9d482060768584002343aa260f41c6f25c5fd8ad599066868416303342c20011a1d502874864861fccc3f5d634d058e010f0f15f80db41b39bcc043c7138cdf5f51527f36d52d7e31812e18e0e1e1e18163071d4e309c502297969610c4af8e269844926a0f777e6a7eac4da18309e6642a590ea1b53721a9c6dadbf8e0251872a86441f95a12d26a724a30ce4fda14f14f27d54c82797420c1f82bea25071d9f4ec5fad071044350cf11092a4a90df8d604ed1a5478f96fbe6a4a308a6ce26259d8aa076f5c2367410c1e861c4e517216774ea5e740cc11442cea3152d76ca2d4bd02104934a95e6d564769c488d0e1d4130c7121533b2e59ce3b36573e80082b12ac6071ff57ac2439258213a7e608a9d8492d9fe8a7caad436b8f0f020f6611b880e1f18d447f47fc7fa5356730f0ce2a942a57c499bafc63c3047c822c67284a9b2c80ecc29fbe46025569e832e9fd0a103b3e7fc1232faa774e7e4c01cf793f3466a383084dcc93a25f5ff0df50d4ca9ca7476dc49133a6c60b29bd1f7afb14b538aa1a306660f22f9626db8458e7ea18306e6206b92a3ed857ee5ac858e1918420a7bd723c553493a6460d0f5c1f452ca1efb7d2c0cefb13be446fc8bc8c2c214b73d6ae7707e2987bcc27841ee5225a929617b579872aa3d15272e88e7a915e6d6cf9654e58ffb5cb3c21037437755ffa2e4945598ca3ebf8f885615a6cd946839e59c0f6aa258c82215a6cbbcb99c13ef0a59a0c274ebf6e154485b3e39a730c7ca4a4a23ec1b3958604c61f0109552ca1f254afea5308ff04ff18d70fe1eaab19611c88214a6109479ce3e7d7a71bf1b4116a330e58e7b1a4134925b4a8d355118c54f951eb57f2af13d01b2c1c586c270e2262d9bb4acd0528db58f0485215e4acac38ea8c6da65208b4f18546d3dcd495acff2d558bb40169e3065ae97764f1225bcacb1c614c8a21346fd9113ec52a6fd7d1865c1095359fc4fe2d69ddb6235d69c8bd37622c86213a65431d789fb6ec9ae1aab09e3ed44f5b62dd3fba61a6ba90b1ba78b2f361326bf8a1f275d5f5ca45a70234762c26041a50b2b571344446aacb5e0460eb2812c2e61fa9c3e2e2ad5d60879324b98455987b058c23ec4a2812c2a6108b2697fa6b273ccd696035950c22074ec7394093126ea933086850bd1ba6a24ae92306beaa591266143422261bcb738a2539daac41224cca2428c70df0f6a52e711a6ab18177cf257bec91106d331e4771aedf183dd0893f214e18410c16cd28c30e78f9dae5f21f5b96511e65329fb9cc9274f9e2ac238ee3da3edb7f2fc441862a7a0ec65e554658908c366cdac8dc9da499243982cce9ccd07194bdd19c2b0ef49cbe6c2e4d9ad1006d51ac22d564ce6a93c3c70b8172dc8714701107c0400085910c214a367e4d6764b8a21b40fbb2c0661bc783d31fa395996bc200c49de09f123b1cc4e0d8461ce65948e8a1ff40f0863a898dc172d79c59559fcc1fc1366accc52fe3c310b3f185fd2986f044bd9c9f7c1105b2f2595a4d3635e0f0f3164c107b3af873455d11e4c41c8d1f1e446bf4bab078369dddffd8fe855963c184eb52b5be8feed13c18361bbf3fa95f60ee6ca932d9cecb0371766610753aa121242aace33f70c1059d4c1d439e88837fbe5a9743a1826c6554ab24d5cead11c8c6f66a3abd255e4242407d39aa5aca7a7d42774e2605c0f7796173a7030ae99d9870bf274c4ce1b4c25cbb446abf55da5dd602c714b4145a9ba384b1b0c1bdb299dc50a1bcced3b22ffd55e94145d83b14ee48aa74feab35435183f452a593339c8b7d360cc095ff91192a48b241a4cf9447eca10e6198c6ddaaf636c9abf04cd608aee22eb352c9a50aa2a64510693ba1b212f7e4f0653ccb17062d26ca6c8c76036212df34b2589c17429a87e1ded15742585c190d3d6efa4ead494243098b33e77309bcf174cd9c4a28a27715e757bc190824a3255933f7ba574c1ec7f9def42902729cb5c30968e6f2642b21ecf780b86a81f2584b0ea13e3d582694dad72fcceaa77370b463951a5f379b29b5ab1601cd5599613a24d4af30aa6b0fd59478d6905934cf68f3b4a8ee79454c1b835794d7627557d122a98ceab3f2b9a369192640aa63d75bd5f4ac63d77523056866817f92267b68bc2b1c32585d1eba0603cad94ee53e8cc0bb227183e4e9e30fa932cf79813b4b2cf394284ad09c66d131e572a74d29d09269d3e2c89c6e5d32fc1b027df4dbd64cd1229c12446477f3ea1524c4b12cca9a76a5fb3c2642498365436cbda826b5716904216473075e990f354e794e36a239846082d22d4cbcd7f8a60d056ada0e324f5e7b03040430b1a75011a1690000d2ebc40c1166a4430afa7d8b6cfebaa1492c30607ee3e90c5108c3732d64dc7ee3295f5f01082498e65af74a3ab1e4e48c82208c68cd1d9a16a9ea51d0f0f0058210b2018eed273ec4bf331e12106b2f881219ad6aca4e2f4f42a3e30778970abafb6d037d758c3f1e1c517391cc771163d3077deceb58dce4ab68d1c669b050f4ce13f7f6d9b8b0ed9da813925fd6b5e39393e6f4ac84207a6246e23f3126543c63930e851973c6f527d4bd60b59e0c064f5a542b05c69a7a31b18b4424f87da883a216f210b1b98438e962bfa05a5b4493c90450dccdf9d45c4cef7d1b28d42163430880ba7d353d6f0ad9c8442163330c44b5de92da84f56a2608b1b5e98690bb2908131c3b5d4d743462ad5be102316a620d1935cb45426b65b2ec480854925c7d3f5ab6b4ac5f415860b2a26bab64711f95d61cacd4a4a08f1126df256182396f8925e49cd66b816831506959c4e091d4ebfa4508d3557c1163752a22ebe78d2858d2db640018e5e0189b10ab3255dd3adf5d5afcb3eec0f315461ba3c2b39ba92f2a7570b1a34b4a0a1050d2d68380a9a021e1e681f568718a930867c864ef19239f10dff40157cd8c8f171e3867f78d12858bb618018a8307f2775dac6235e7ec8294ca2d627a414e6bd448708314c618813d383e4b7fc214f928518a530a88dacc84ff13c7c0e298ceb4195cf8fdd859895e9284cfea984509d5fc4a5105198a49afe05a11e4e3ccf408c50985c4b948c999d94da9a82c21c44d0cad974fc42d0ca270cda542cff7896212fa29e30c514d33457b7c61a0bbee80f1c5be017313a71c8a6ad478f87306d08313861cc104965dc566aacbd9f0b000e626cc23cbaaccf36de1aeb802e2ae0e161ae88a10963eca7c8eecec494adc69a2f51c19503c4c88429eb7b4ae1930af3c13a25c4c084b13be7e87ac1930c317b78e4c0b105171e1e1f312e61d4f6bb0a8babae33046258c2786f229ef77fc66a8f5109b39a9a4e5ac3ccbc932861d0e72762446848b10b8e2d100bdc930d0a4cc210627f98999af02177bab0b1c547310ec4908461562b89bc7d593ad901312261300db38ed725499bb68504562161160f13df7212de1344ec1e508256805a0e1c5b70413a10e311a6bc2345655bc8b11c2a00f010c311c61f75df31ae5de72a1f311a6150dfeb104ae9deab1703311861fe523e267f2b4a387b11a6ee7c29fdc65c6dcd0f1c5b281b6228c2a49f133f8450d7d93e0163b06b542449d1830c311823a41c429a2d7d1f2936920d1961309d460e22d7c608e1078e2dccc820030ce6141d11f4b94ef81a71f105938c116df11452e507820c2f18fbeed674f67f4f3b5d156474c138f21e724bbbc3f7cc05639cf7288b2d5241c6164c414372f658bb5acb6ac1706739548a3769cb436464c1b43d49697dcfb7a17a1958308f34ede929ea46907105e39c1c5da645a78ecd56307c96be28afff6cc184b6c8d1393290041955c827b5d5cdfc766190410563ffc80e1d65259ca59ce046a3c06f988c2998d74cf252302421dac3bccf838a7714cc637fb1f6c2733e8f0d20030a86744a6a990433e1697f8239ccc5eb15a1ca3b742798723aa19d3dcb92ce5213cc7d715c46a911b1549860b48ab5adeb4b1eb46709c6ff5db7121f3c5ebc4a30e7d332d5ac78398ff20b2f92606ecf2d39c6073569511948309e8e246549e49bbf1a20e308a68b37799b2ef2846f04e36f4bfe2c7f8b6711ccffb13e92ea49189d08269d3121f2c63f04839c5d8a13a24230574e9ffbd485ad6406c1a0276a9927395a8940306d9747f8c85eeafc812927a1b4cec49095d8fbc06413a4a48b1727e1ef81219dcd5dbe9ede34f1c0785abd25f72ca47c7660d8fdfe55af9589b60e0c96a735442cadbf951c18e4ab465c9771604a29172e37b981a9cf45b72d5be77236305a4842a5ebce6b60aabbb3b3f78ff697cba081e9f63c47ca5f19e272193330859a9d9e58c182da65c8c06842627c7e512c0a69a74aecd30916862065724e69a7571873d5b63582d29bbf2b8cabd7a9b5a6e4b8a91506a5ea2fc590eb131756989359a7ca4dd6d3d9559824971e95f2f9a4e0aac294525a8b7ab721ac4d8551542f5c695d2935418539dae81021a354c7083a85c9545a5c9e780c292253985b2624a16c4f98cea15298f2670f2aa69228f9218571ad757f3b72eedca3309f49cb232f8bc2581d3af2e321556c4361bed355ca666ebfce939fc87e9e13b3f309c3856cb933e2d7f9c713a620d16f27db9d30f78ccae1479eb4b339611c3f933549ba095376bf2d9de029775213a648e17c6e24ebca9809b3cc5c7a8753553a870973d4eaa4bb737d0973c8a7ce5a2679b4ad2d61ce96ee44c5889c9b75254c7b41b99d122bb25953829cd47d98e92761cafe9096462d4f58256110d671a2e935ad279648182bc951dbda175b59818441ebe8d121afe7cbfe11e638aa6639976fbec511e6942645e5c4c8e26a238c9246a5b1b29326228c305f2e616245a87b087911865827743eed5811e68bebd039f57d3e281106af78ed517911612e4bfd126631b6c73d8439480c15a1d22d4eb88630453c3121d9a38414dc42984c77c87b77a5d7c32584a9e4984ad162e5e4dc0ec2143a65975feb69782b08e3e7efa7916d0361cad0102994a97aef0161d0b19444134a5abdfe07e3cec4cb0e29723ec90f66391d7eef7592eeba0fc60b25d5bc2f760a5a3e187e2e74a5e0374a64750f6611a52d29554e4f52d583c1c7bc52ce97e6c16012827e7d13d5764a3c18fd4556843e1d3f72f20ee61aa5ef2ccd6907e3e98513b93baad696753097ee7ca53da659793a18b4a50a573274b2d8cfc1ac716159576ff1477230d7249b5119119205c5c168a64ca8fcb1a363070e86fbb871153335b6bec1f8c1e3578a923b65d50da65c7a674ae9ae0a4ad20643caf993bd7472b6246c30ad5bb8e59b4ee126640de69a942729495e0de65441271db75fe43f9206530e42a913d16bdb7244835135d3eb3ad8095bf10c8637a1bbbd3da2f58666309bb4d116452b8341a8532989d1cb7e2a2483c1cbd446b8f14aed8fc1bcd75eb27ff296c4c560d24baea5544da91c0a83b92be8d23679bd94c0601ad393e2cdb466eb2f9845ad83c872ab1cd50be62de91ff183e75eba601053ad8b13b96098a0a4e54bb9db82415bdcee24cf23f93a2d18f5ec27dd5e9705d3e44fada15d39873c164c5db2464e5e8d35f915cc296f217dac3d9492158cfa15b154073597ee2a98e6d449b5f8ad242e5430b7685321f2650a06bd9552ca69a1cf220573300f3337d9a260b0f568d95c8382d962786544b9f330da134c41c48f7d2a6d04cb9913ccde25545b5049c653d60443d637cfbf9ebd6f6782c97eb4ab5eec4e3f5982e9edcb7427794ac98812cc27d62992b44f72912418336d6fd5ec73f61009261521a84d2b1dc13c5acc549424a22719c16ca67eafcbdd4254044390977366d224c98c08061d41ac7efcda11a91a8239e6c4ea24a2e71195178221659985e510776196060c2008e6fdcea346628dfd2801c15c39e4fa32747ed07d095d42dfd828aff8c0246fe16ff969db43ac0703e8814196840927c663a97d82ce417630001eb8225a3d5ef54d773430801d68413582ba3ef5531778662e18800ecc152c7f0ab2b4f7d44bc630801c1854687c9e5c153d49968401e0c060276458fefd907be1220ce006a5a553594e8c906766060660039365b913ff3c9e44258930801a18238e4cb83c5e0106400383b6163f378b1eb4245be011c0f5a251d00511c2006660f814b157d953ae08fb00646098d892b3e85d64b13716e652da7c929cbd4ab1030b738510c2bbea5252b3fc6f91f6bae315e6385b11827b52f1f3b7f3b000d0a0c315469dd176399c9599b66ed8c0f131015c0f74b4c2a04ce850b245e67b973a58619e1ba533f12ec9885b598549479f12c24e52d05176a14315a66842c768951f9dac4d854962a90baf734ad829e585a10315e42c3eda6ada276d5c1a10011a5ad0708087470bfc0486868e5318d2861a5f516df9c46f0a73e84fe91e762d8579cf65ec53ae3c499f5ce8208561a4f5a5edbc7aa98238bcd822070e2fb6c8310ab3e9edeb1055e31f3f36d217386ca42f7088c2f09f3b848e3bcac1c51625c8c1c516250885d9b3529061a7ce521a14a65425b98298c849253f61dcb1742aa9cb4a2192c40a1d9e30ae6556d76aa5147fd40953ecee70499b862ccb55a18313a64b6da9fb713d04d111063c3cd00d12746cc22827a731c2df83ce1a0f0fe42cf0227468c2149a963aeced99484c18ae3ae4ab8aa2924aacb1f6710963f5966ecd975029a325cca6e47ad2a66b47e95f09730cd36952ca497815d558434a943aaec4728667cb4551cb4fea63b44e5de77f564e051d93309879b614725ee949649230e812b2fa431821b1bb8c844977c88927c47dd01ff6a00312c611b1b3b7a542627798071d5af8cd9fb7c311c6399d45ed9aaf97bd1d8d30fb8cc821653f31c290e298bc93ba16473bad60e8588421a94b48563271f72b1d8a30c7b3fc20b612ce4247228c1d45f4e6a868a3bbef408471648a3839d96bd9e24a42c7210c3f5252929b9763fa39011a5a78785c87210c9ee22eff25154eda1d8530bf5e24ed22272f84141a5a94a183100629a3a346ec5bcad5a20047afc0c30305387a056410c69c18395cfecaa7a60bc22841b74cfef4d1d080046804c2ace2b936449dd5870410a6ce1dd15ab1c6d5f407d3c8fe68932bc70fe61479da4542fa60ec0fdda253ed7c307827a184b49c4e5edb7b30c90cdd2e916b7e62ebc174f9913b87388d3cca3c184fdcc9951362c2e50c0fe6dc503a6cab750753a40bea2145b285f8d9c1ec21ea46f588141d3b753005a9262aa2891d7430d8c955cea542e660d4d3d972b59a6e179283219e69b7bf98f99cd7389827ce5d7b4a952d7fdc0107a3f587d0e9fbeb7883d15484f82f67ca725248e87083a9b3b9c90921049316521d6d306b4891756a724e1c42071b8c23f4b9a4fecdfd0ad0b10673be7b48296adea7c4c343081d6a30da450e56b9fbc34b5a63cd16e0e19106537ebdcf16561ae72b1acc957209f510cf3f6ed6582b868b2f7038063c024320c0118c1dce577eb535ac7335d60a4d312010c008e6740bd1907d93f6322305018a70acdf9b134135d66a060420827962c65c14496241da359653172671f1858d1a19f0f050f3d3c7120438a4d1129773dcf25e40002130d97ce7b2778a1408100453c4c9aaa7957b963c35d63e706c0104536ddaa6c80b277bb25c70f1c59fa96941801f3cfa6dd573f09c6404475a00f5cb81003e58b4859121ba3dc90e6d81a38b2d6e786a77400e82003d30083d96a654fdae530a1608c003e3a57e1aa154ce65fadf81c94d52c8d949d781396c7c85b86f93accd81d192d01b42c6a4981207c648f941282182b211961b18dd2dc6842023cdc93420800dcc791d22972c754ab849011e1e384a170850037396c7fbe42b42bf9b6860b0da89faa193e9f119025120c00c8cd9a7eb525b3dbe3402c8c09456d2c5504ad5079dcd8885416b4cb58734a977e219b028686f31939fa4bbaf4862c7965ac4b4f60a2965862b4c25f94cac3a74098b7e71c38b3b2d683c400b0f8f1b284001eb0f66b4c2f82571acebc4f6c7ae3061062bcc15752429d5a37b3f5aab30e5709e52b2bce7742f0933546130ad8ff73948b7a4c244c28c5498f75dc38490ab919e438419a830887deed02927a475afc6da47b261a3041f38ba066f91805232cc3885299b8821c26e5e3efd1a6be8c3b9485d740db4a1811c5b24bfa18587070540f0118055cc3085b94d564e720a95752a2508334a61906b5a5a1f7e56749881308314062df1bf54e5745d4af72fb8680e8cc2e0b1bb4327468a284cf1f65772b04fa1e357426150e2f4e99fb662300314a63065a1174f277ebe19f88451c6434fcd44519d843c61566f730d99e3cee884a93c5aa4582a48eaf2ac31274c17c73fd207314956ca26cc9dc27c5d8eb6260c3f6e41e57abd9f0433615a7f397539ed56ce1f264ca523a83c9d439f50e94b9854c6b8664d48726fb18429a730e51bebae61d14a183e68d16e71d348caabb1f6c10517fdb11f357278e18905332861b034361e33cf547d28d38c4918c485e420fcd4b6fe481286b5fa8c74fa481845a724f14cc84bd69119903049ed097f2ab47a9a6bc6238c59fa51aebb43f423331c611e376634228dab8f90bd749fb6c61ad96206238e9e949794d1293fc48b22331661d2f0d1c82ade9e29a24b6a62673b2dcab22bcc48844124c49b0da12d9de820c224fa41c49ed8ea0ef321cc21c4eab54a13dc3f8630c4cbfec82ba33aa46c214c6ace62d5fb87ff132184494e777bc8f191a3c8660cc210d4098f587922fea28d98210853e8f5f8c17357ce1c91dbc38c4098b48ce714237eefc68285198030e77fd3d5bc325d769236ccf883e95a457c7ffc770b397e30a62761f1473c7f64990d33fa60d6dd970f337a3e98c7a45c9e442d0d33f66010aea53c6bdbde776f01175e78d1650333f4606e13af1fff5973d619c18c3c9c2b54e9cb18dfc030030fa694ee1e543813415dbc83b1b453e70e9f676a5a543b98e5834417651e4f82e4f20e33ea609891d5ad20f3437b8c0ec64fe95325516225a56c0ea69ce3277a2521621e948339bcf7a99b7822c8ea92e461461c8cfefb123cd672bfc739cc80834967ad9cbbbbc68bf4e30c33de6090ba1ecdde34bb196e30674b2929a5f4a53af56a6983c1e44d8f7eaf173d6283a9e3e547ec3416ee396b30f5e82aaf48a5238d5a0d268b1fd352750d6d350d06b127d4d5040d0d660fb338a9973f652d04cc38c30c3318923e09162b46cee69d32185b82969482d0ea53693298743cb9fa57650ce6d8ad11f546e66973c56050ad7c51e24388d96130a5759ff0b62518f0ed9359f51232e30be6f7d98a97e45dde0fa9c20c2f98438ee36d2945081eda195d309a1097c9e15752fde68249bc24b595976405af6cc130b952c5113bd24ab45d70266668c160a2257e4e938967264f624616cc9b577e73dab31f52f81133b060b6d2f37e21be2e9a0d1b37881633ae7045b2deaaad9067d5580fd7c2bf7174b1013531ccb082d9459e4ade39fe96622412985105c3d749f556b1e449785430078b71b361af12664cc160da258267b887ba902fcc90825154e5d55139a419a5ce8882e146aa8d6da90e95d70c2898f7edf4c7c64497bf673cc174419fe9a0ea7f37c6194e308c9ae751e1cc53ec74130ceb26f6d7a2a9347799607ed32df12f397ef2dc8c2598cf530e167b7a12523843090613d367128c3aea3c7f98f03f2b418229ce4d90f5249a71046368b5af390bd2427f8c60ace4d9a9ae7253f45904f38f989f50a7afa31f36127f31830886e855317b524b3afd0fc1204baa8948faa6d46f2118a4e4594f25bb73c26843051f36d2e69811049376f80f6159cbb72540306957123331e5a5c4f603c38b49d28bab3835a98fd445670e66f8c028294e6be59ce6b39e7a60d059462387d1f4d12e0f0cd73a314bed8a4e4ed948773698b103f39f8e45d62b91b4bd3a3049d9bdd0c9ddea7fcd81415d794ed73d75ea331c184e828c982af777756f6010bb11271baa849cd00606f3db53e9f35ba5e86aac7dd8486506336a60320b0f6926b95a142d0d4c6aae22da08f5fce799310383eeb0ac9c77a13b5f3364601259fd2c87285af9cc5818bc732e1fd7de6ef5790d3260610e336184901ecb40c62b4cb51a6af53f25774bb36980d440862bcce1d923495e6798c4c8b6c2f4162dc952ff64a6a2066e68218315a6decbf5679ea6626833a0058d08d4c0d10ee0f3a25180850220f878808c5518649f24990f931a6bfa0719aa307eb07c75a227e1625f63ad0aa981a36b905418dcde372ec70e16b373c3c6ef7d51010f8f1a38da013570740d09f8163734208174c3e3865742062acca2557a45c9ca2c55d758ebc286c93885d9920841a514bf7462de43c830852958b63f616b6ed9ef52987bb393474ba9d4682e831406e9177ca2ac6d895491310a43eaa0b46acd9808f9230219a23028eb683149e8b32482a130dfc5ea4f3c29aab2ffa10419a030041b4941ded7d3e4e41326eded53ffd6371bb9278c92fd846a9b14d13ea9138611caca7276b9cb71e38449e4544984d39d4d94d3bd7388b264d5adba0c4d182fe4c497efece51241cd8439f6e9a03bdba6cb24e5c9c084b92ce7afec98923c65370d322e61f034d244551239794e3901f21a5ae04186250c415b2bcb8b76391369250c7a4f9ed74bb4d0e651c298a15ea2a85c8892a449983bdeaafd841589b949c2a4567e31c5437b1991309fc895b311ae23d117820c48184b5cc9d1e6e31e43081f619c147bbb43a538c21467fc83887b712bc55690d108a3e58ab6f9113a5e486284a93a8c2ab91c3ac8b86f0a321661c86ef292ac07f3b858086428c2242c94fc7c0a41fd53321261b820395775fa3071224106228c1727e976bcec9e2dafb156ba90710893c5d0115e2d5d3ccb8d761c1f072d20c310c64e592f7a59b6c46cb990510873c81d2689d029abc70961f8339dd5889eab84103918c81884b1439cd50fe5b1c2bd9a2a9021088396edcbba957e3ccc390619813029b1772d3934d34c650908a3e8ac9dd35a589c5f760b32fe604a26f258a7dbfc60aa0f594aff6ca873530b32fa60c8dad1d2980ef3c1202c8eea76d0f649d92bc8d883e1e36513225c8a5631f221430f26257f2e6c6e555b8c0332f260cef693e38308614cecd9041978305ed6f3964b09a2fdc30419773029bbbf102c9a0aca4576300839313546e6a9520b7274f1059aae40461d4c215a58cde94ff16cd3c12444ecadea8fde1964ccc1a0bba154a7c98a8fca0153461ccc167496cfeddde229d37c830c38987b25560ad59fb3dcf806e3b9beaec7d3718351444e7a4433de93966d30d74f7a75ef9c9316b1c041061bcca2f4baa9f5f7e764ca32c858833174e4cfe78e3ce2924e95c544728f3a4a83597d3f9dbd550e6a3b1a8c9a753a9728ff0cbdcf600a71d1d76fa10bc8308339766ad3dff1fdf288cb601a3917226ad4ba332383e1e4255987ec1faedf1a6b1f3612a640468d87a8449165d2581c0a8542a130280c8360f97514c3130000000c1e144763f1589e29bbb20114000442343056343c1a261e141c180d04e3703014068403623028100883c1a04028748ea6700c8b0f2515e935d557e99e1353aeb200d9fcc6754ce80c44c8119e6eca14f2955f0f1c331dc4d506d130fd1664da9c86913a19b432400ec18bb911457805b235891c4adeb651768091eab5d77e70eb293d81c4e3c2663444d433d431c64abd4c5e2ac4d1c74d6a65fd83cc3375796e80d929b7b27a360695d2efaa2e71a4927e3b85bf4b25079595fbd2e12d5ce34315756e9604bdbcf2447447949e31e3d015327d4ce6ff8eec4b19a3a68e3a2824240fec1a0c4a29cd8fb6e60e69df702c238fdf5a221c2e4854653009cfbb492309094f03eaf9fe9a44aef6c32dd154193276cd51fd88a713bc8bbb72614d62280f0dcb61821b33646137b0ed5c93179a1cec5d49039ba3d9b0fda804b3e9f375fff67495c531f413d2479b2969aceb4e308b44c3595f73e813bb039d68c5d33d15d074468af96cdc2007853353c5e872a516d2328d89ebea6ff34492bfb54746e9263e4f46a88595c6eb656166e4b4ff48995183760f133699db9bd3f91713e84bb02dc6f0280d3e028b4cb443aae45f1c59f868e386af9883444a0c3313163316ca65789f5ea051f15275dba98b19f039901ed51a26979dcee3cc0057f7ce0115f98c7c50561c4c70dd3a131d688e4dc0c8dbf95b9318d566b8c1a7f13a1820aad3e997bddc246f0501819d6dbe2124d360abe4e6f8b9d368b0e6c9650340fa75193d3f6165c390a5645f63a4630ccf23d0e988b646e2c50832237d45d706f09fd133460c2820c85317b4b310e3f2236f200911d6195baf9b946e95aec8046f4bc1f070cb369f9d994f47d747526de2682ce100b47127ff8a3d2a827fdb6947e9232edde09dc9d118655613024789b870a8c4c4a9023cfda92f006b7e5c2e9d26fce8d3531917d86936c09666eeb5d85105f5d96a1285d0cdc6088b5a9ce6545550fc62a55a82a94c5285fea0553886d36acb8394807da585bc695904589de91399533c582c41d09282f086e43284ed66f127a2d58407d58c66b9c3921c44d3fcd24a15ae568a5ebe6f550257005784a41641645c8feea284388cb28047a9670165e2f8fb11a03a18ace39a114bd716a330bd6276af016d6933466fd716a0dcb83e56b4553be0fa08563cc701c9322b365491d6fe6e067f4ba7832e5027bb66a42fbf982ccc6768fc7dc748ef8e74372037cd9c2e33969a5a8ba4340cca6fee1aac57efee90f26fbc8d5fed521609bde34a2c38edbe02fea1995c710f46cd8926f3ee054665cdef666013642696a1346dce3d9b935fa5dd876d522b5059bc58d8f7019d0b133494c18577e1ade092c4b7e1b12250b93e882fcc097e2ae27503b3d2c0545f0c15adc5328f93e951e631230d6579f7ee5aa358ed8e6ebb9f50ef288a543c45723ff414f08891a6362b4a7c585477a951373813a589b3513eb6ddff4d1dc76fbea8e4b03563d4f4bf6943bedc84aeb862c66254a72fc70a4f997d631840619285488e43d4e4b0618555bf6ff7993cd9c8e83d4507d42df8ac79ecbe7cf2cd1c8d51ef005c319d1b591c3dcaedeee1909129f14831e8e934bd575423155c6daca0b333ac0a6288eff7190aa94d26df0fdcf706f610be82a7eb81c69d36165f0f97435d6808c0b1cb38c91ef6680f65f2e8219ef2f12c2412c80db41909203cb5da2bf76d21f0a6edf92ef1be0a0dc7415ae763989a43686280f82c90a64bafda406d829e67911fbce7e50f8c9d9e4886e2a7f0ae954326d3c32b98d18ea3780d645642a76850a5eb633d09e8062181b846d2463553631a11bde2cb0b24489d5c41f0e67fb1e1e37159e99ea2a66f93fdec382ed9b60121641223d50946ac1edcf085e577a3607d2305510bc6127b38b6ce897021a09a554ad83c3d3d47a05f281ba95037af91c7229f145b624c8e36600b5adef16bcfb3e1760774c91ec83d9675d492ff9d7f424f813ec8f343d935f6c7aa7cfc9c9ad4a26408f147452bee24bf1154bc1421e669da917700f30d08c8414dc3d346bba0a73dd70d13a03c2c17d109ed09a71b79f24fdb04b7e9f589a33452ea6200b3c60c75e108fb01d33f2326022f2babacee5cdd3a9dcd48a8142f5dbb74c2bae7f146779f26c070527dadc04e5142a12d06ac44d69c68bf20ab902b3411ca990c250ab4a8295f5cc92e01c46c6f8313e0730889f94103c04a271a1a9668810665cbd920688daa2ab0ac9089d20193eca01b8c49e910e2df46f68e6512ad5385b1363d016da0c30f6def5453d35149ea2f30c5454043b06f36702f4f07841ed2c652a2d80f84f250e051e9685d1b9bf4710af4ddd3b1d58fa546fbb26549d5cff4339a3fe2537e46cd1a727a1f3f31cace2767cf447b6a6c2b2cd19c2803d01efa9f731c22a779f5235b4e70027e715161c209e23408ee15fe61c60367185730afa1e881b4be630e3034af70f8f12a7a902977fa47676b95d68889364acb145d639177c06c402624e91f0de01b5dc7d81f6f3157d71c7eaa54ed09b7247420260af12fa8d1892c80b00edbbf50cff96ad8f070f160ba02ccb6cdc5422419fe282f4a314fc05b20ce8d96f4f17d56882b6ebf66059e8d107135521051db202c099b7307e57c67fdc9b27b44e03c49d1c0c37b7104c0a645017d4c3bbf39d81951e3fd03ba90de3ac1ec34e460461009e16a010e9b2fbf61e8843fea3b97269bd44ddcfcef2e4f50978aede1bcb4735261489dcb44ede40c69ab926d5ab441563a5cb5cd513c0f480d8247ae1b730a9ca315ebd32be660f6efd4c762259ef8d71dd7b3c4ccd7b401479be91147834f9d154b8f4bfd1783a4174d4dbe951736a5e4549c86cf4313a4b6b52a8645720a692995df1f2ddafc3fca341e4ef76ba08b57f15a397087c02db6ab1caa3c75426fd433828c9d4dff765c57a22196fac2487ea9d1ec49c876ce273a353ff85278af8ab87510bd80ccd5a2a3672c6a1cb965cc4b0ace8757a1d06370430b48829dc1d645c47c30e91d02628f193ebaaaeedfc51f1bda6474eadade3e208cee33da6295565679256c4d188b64fd6f31b0614a508f9efe35e025317eac65e6f1b12ff2ace24a92b0a39e8e280de735f5e47a8ea2a9cd582c7c9f913def21a62c0d9708ac19216f7f90ec15018c5730f95e1f3b416bff1787514842ab6e6242c89073f69b261dd381c169785b0928962393eb211141e728da5a1147b02fdc6cf000f60b8adde605862ca16e03b1bf6e64e4f14ce7584274415967a248abb91498aad5e26818ae60c8a3985822946614154bf53ec087e4a9f42de02d4853b0b5020a2650ef0c9a8866091ddb41163b0f292e0dfa48426251b06f839e40f4b681606e5e4991057489c916c23a1a10f111120ab4a0eea4af2f70dddbfec18ac75d8058ad40d59ef704ab045c8e0506e67794163844b9efd8016364da9804ac9febbadd75aff27748af82661223f915301a21dcc370238d0a602024bd1fd430247b53534b3682fc35b9613ebe0830be262ba420825ba247918cb8c481a0ee359042660b38e7d2380f61c534dd182473045b738b3bd88d0f7cee823bf926103a40ecf63ea4bd14bba392e0725d3e2de186a6ed7d2dd18c0184147882d7d74f20a07f02b5e7c63e49b7d6586fc4b740f60a502dc94fd264c5691ed44e71655069eaa4c6a162a7f9d272abc898c52f2ad1c7f8a443fa2a18d66d8e95035cab372cb177a34618be41c976fec7648352223915586f21a5d968298ae628298b34cc729542169ad6216c156184b117d152582cd571ac306c5c6660a165f72e05a864c8b45e53dd71d6e8f2ead82e65944f5b7e0a3d16f1b608bb280a4b308d129e041a9c05d1260d01661bba70b3bd1596006a0c0e61dce18377031308211085a10ce0fff7f2d175e34669d839a773b2ee70f4e5ac544f1096d2479c1c3d1e8a42363e4511da8a34528dcd5a5986636ac1f1e55b5597d2fb1c7e13d4884e80a663246dba34bad54f32c81aa4d1a664651e8ab850c73c754189b59218b021d5a99db2c9cfd4eda91acac26cab18ad5c587f90ea981b8b1105e91d4b568ba85fbeee8fa609f2542566d22726436032c6f448b381725f00d7f6da63a51e2e5bb3f2080587eb64acd05a38f7b5faa830ccf81e6d83f6050098080b0a6e49c80709e02b988b6e97c2361c40a28eb5bc1f3cc321f7b2dcfd0d10510144060a3d04a1375e0e0825c87bfc2fc3cad2be668e87590abb907db333a2fc263766775c14e4c38ac3f41d5effc1410dcf315b1eece3416c9780ee738e6d0855aeffe1097e9329fc55d3e9ca9087c6df6b80a17e541c786e827099ce4b58a149e602dc906d8922365610ddb843ae98151c14a236db415ee677135d1b7075275f7097a2c7db3723e3d758d21e5462c54bf262b17e835eb50eb854909cddb05de2a3a42e75a28776ce6f754706652b4c3cefe11a91deb97fe26dd998a738d10a1fcfa3090139df3e1792db3d3792fa1a799d5734fe19a0ed81c15a46af7498e80f9e7f4dc8631d6f358b4fb7ce6d8ef496d391fab6b460156a256ac6030b05a1b43bfa89002589276a70e0e265de40dc84a84e5c84865a088ac1bee1ec06abf228b313a4ebfbbf9dcf8943699c0804b3d9fd09db19451f95616d378139a8d9e406c494208525791223aeb81cf08efd360eae8862706d403ae2817bbfe4490fc935d1bb4936a7d0c9544246d4d18beb20606739bb92e84044a44f27a1510d425446305293c1ae2b314d6feffc1b34a3638c94be379af27d12542d4045a5dfb6c7b559947740d5a75e6c831d8220cd4cf8a7e00e3812dd86d3fffdd6d5fe91cdcc08177ebd8e7c15948781be697d412d29e519ede69afd26dbe7d7d40ab6ba565eea80e62448f634b9b4d3ec6d36086214007381ce5e45158e66f6c7617970635580749fbe6003ee96cc3aa74de57ea131aca128ed9258365d8c49e1ee9bebad8baea4ea045a1dd445eb9aa551bff1f35282303aaab55f3159c040cf6999ccc99b2c93d965f3a952315162c2efaeb5d8ba5ab5142e77a35ed59e91f440cfe965d6baa7c729cf219e87ddcea44aab19f5662da7aea85642e55cae1cac810e8ce49c94c99ccc2dc588be5b20033a670bad09ea292df6aed65a28001fb8419a0bfa913f9782bba69d9c96ee5889373a889929155af5a87cd6e6dc1f13309c0064880edea01dda712c0691a2bcdc7a8dd32fd9d35ca9da2a44f5592f67f7b44a519e663a2d9c5b17032bd5cdbeaa0d0a7d36e035512c2eb62b309c35cd4b9408d1eb36395c47f42b69baa83781988d9f9af68c9693d0a2cfb19685467f9358aec464b1a400e3e90b4d15b63f6c618fb20b0e7bfca8b3d223538cbe49551a50f524d8696eaa54bdecccda325b59721ad7040b6dbd9576c28307109f07c6a45f02ada4021f4c27c70ad3fdd457f540fcd71ed041b90b96e85629e021e26b91fb357836a29e1b315ff8a662ceaa88cbc2dae08ab4cab5781264a89cf863656dd54a781afef003aff17b00b649223c61b3fc4ed93210d4083df7f2054ad5f8916a11250776bb474afcde8070a03ac3ab4642a82fd0d8b21d44f9e76c5f7b4306a0afba43828c8f86006948b2a39793e2c5fb67cd36e357a3ffaa4b5257f13d519c84c7e16c014db804ae7b16153b2ab5159a22ee0a8e47d2fcdc0c58a6f5bf55b235a4d367064e0e4dc820982ec17c53e9e09d18cea18a9b89ed4cc921459958cc60da9cd53225ff0e63ed03076fc4a041e6dc7b4e4a14fac99986f362dd8951d8eb7b95d7a28611de36663c2ebd3653358ca005f881c3d9897f0a16e74072eacd5f118d9b2a5efdb9b7b9e891cc2303021a86e3a6c8a1e43f0838d29c226cf57ff04dec33e016d6a36252c36ea35849c8b21a9763f5cfa7921011dab0f91be0ad109e2b39683674bf07674f3dad160c776503f680490ccbce93eb4cfde05655613ba1a611f364a06e2c4a0adef6d9cb79d12ba577a44d7295a8af828c9cc08b0db413592262d83227468524b572695a32bb50bb6910c25f221d1e459e6ed04a760fa838d2590b68433940f58691bdd1f17e25022389e0ea0ca70c8f94b603dae629bccf5a3dd7fafa071d093a0b6d97fc204a4c3ff45e90b1cab00874ad7d756880c480951be64e1ebaca40f0d107a5da0f1d81d059d59379131bb2288c1dcc769827490f4395a5248b4d40e0a1738c6c7df960866c8818bf2f167307a65a474d0e4e7f121d42dae258bd8e368c5f2520a4508a530495d3ac908ef6073ff0c535069c532deb887e8605b2867889a39b28730467b1df045fe000e47e3989990ba1981973806ad4085165a4bc1593924bf2b67ee49a022238f35b57b614c78c50f3931289fbcca9cdcb914d25302c994c1975870e2564a21ce049701d4afadc798e713ade09bd7411a40a316586aa3726e33c138cac22a532ee7c0a93fc9aff14bd712bc8ac13544d8efdfef2e7843779aae61ce72de0f97e7088bb782d4c6e9896a9a7632a536222338323a231b66e690cf92f64e8bbb466abee417ee2713178169814ce3f3cab878fa7828da4eb68c204976587778f0215358ff93d86c9f1da7f5c1a562049cc6a3435ba8543f69b84b781a58a98b04a45c9bf1f81e90db6a5a88153d7df27f23b4aa50662c433b04c5b20103079344120d91c52b119c1bb22f9100ef26cc7d746f92798e276ff8e7ca09fd068f4be423fbf992c0f99d10f7766b89b22c683c64dc34cc33b35d65871eb3f821d063403ed749c9bc0d400fea5c9ac30075cf431c69a462b1a7b219f68ba782255c7e683e988dea42343b4deada812efc2515b95025b3c5dfbd1e36217cb6fd280f0ea49fc22e81368b2a4fc6950ca1ead6c41c756b5cae6fda17481f4cd02a363b2c0518ccb650065be36a855cfb91c4d72196970e151c9429e25dae3d601bcbdea7a8468b85b3b2dfcd06e1a4d8f62a5f9ba3c8de9dd1429530265b37467ac74b3bd920d6b3e86f06b758f4fdc869a213da35b2971ae65609c05d6d6084e0d06e1c838a1dfeb6e0e9981011a7c0e427f88380cc0c2cacdd5752df7ad611a0f182d975ce17712a9cc292b30aa502c2ee3732fa41b2645d9eb76b7d081b0a24508b99c398440d7745229514a28e27a06002167b822982287535039c5f900163da00abc06453a610cbc71752de78db24f47e2841492a81119999032364964a5acf9aec81ee548df6ab3843717447163c286d6a084cfcd2b9f4dc1449111b2b9368afbc09e623171271f8f9ae165710844a9f0f6990e8a43c38f90d9b11560ca380ffe0eb9b59b411e0f65e1c8c6e28f2a1e8049692e181536899aa314129127804e3cbcbb56df21fd5be2c03c036039669bb355c3162a2d55eb00a0c9ee55fdc4e397f151504888d76721fb5d70e156d8a1258c6b39e6bf19bfb5130b57122f4b3b31b9d227e542b7e08768b3ddfc906067efb8909062ae0341bb0bad6e9bba5ed97ed8236beb408a1c2934f37a12f3feb891a1600f14ce07c2e6a83553293ff1441a2ad5e526a9a1cc1bfaa2e0a0097797cc20903967660c36109c602819029fc977350b10d505799971085720cb2c3d0cbb9cd37ba15ebeed57a3444fb18a2c4a10f80bd3b80240124d00086ba8f8576700a84c17239c5732c7a5725b5a22133aa23f7a9d9de905924c9c82c19adb4ea2c5575e61bc497c11f0c04cc23a32fa9a003cecc551d9ea042384a5f201ad5cadcae108a6f41aa960b032dbbaa1a7911ac62da0d819b7e744fa4ae22652b694bcd044772a323281d90205c5d5ee210a6b82251577c6ae0d70c99148ada5170d36751954b0bca23d7de4e8d8a033919278656d6e21f25c700041b0d6296e629f5bb8405c4ff6710ee00e56c1f7a4763b50ca5f061362ceef80e1904b2c69529064cc6b7c5c548fb3b64f259dacf03b36d9ddf5429993ae44100a51d35c2596505a5c040501a0f17751d00d8588369aac0cb8094d3e8b7ae995e87a88d9a3154c393762ef11323a406759431b868e3836867b8756c5dfefc509d8b75ba9614bb62e242becc15a7e25a13b623c0906d6a7a563835424a72c5f0f24e9e428b113c6901459832a3faa68543122575a27282e598e4acb2094be296b260f68461de88f59a22f600c0d4faaef59df66ba38876544c45fbcba2a6fca748dea1c57eb3c297f76d2004cd7a6d2b1001d19559189f29df22407539e9d4a396221bde703d8a83f2aa3c7650da8986bf9018711c782343210861750e0a1ba40ff641ee85635ca4642a6950fe3542eaa1fe3fd05ebee38f56d829c4bb9774623c4aaa54368ddc6509a01ed3334701e80e6774965fd7ab1199de4f99261b602e0d6549df6895d56053b1a492eefe45a0f23c9e58b5eb4af03fa7d6d9ef477a23754125a9b0a8e48f0253de535443e94eb0d9603118d0079697ab395ca1f16c9160c73600dc4bce18130aa31073abbcc1853ebabd656e8d6b432b42cd0597b70f674ca63111b6a2ce57ce8a60fe24597b02aa58fed7bdb80f5343cdfc92a225e8b02fb39eab7c6ef4e5f3cfbbef25b67bf053f58fa5fdab7c4ef565f2c7d4ffaa6a45f91a57df278f53447bbd75979c211925976126a1b251a27ffafa7fb836955d0e6f734b63f4ee894414c595b994e62f69f5dfc09093d7a5a1b410e66c398bc6f4b47a5a07eb14f0cef5a8ecc660f3f7dbc9226d7409b5368f9eff0b0b0c6bc9ccccb0347cf5c992bb49e631458b127ef44c6eb62acd7b203d62621f2d79834a481646816d50cf5669330dbb8d911dff6730373b8ff0674dbd82b6d95485bbf93ae338754ac7d72adc3897e2c41f29bc42a124704c92725e30bc7044937127d24963712a3a2929a8442e22bc9d625924d8c4625518955ca5383447c24aa2bed158073893be9c9b8b4a6a3edb07970af3dde535c082d078f661e3eeec771f892a7c89c475d1e2d3d08f5f8eb61d543aa87411eee95c77615349bc7c523a687821e1e3decf410cee3fd75b7ab207afcec71d68fed4d21c73a7b1fcb800ced88ae215601f185c8a9718ca8e8fea2304402136852e773ef5cc6dc38154709d11ba8328f2ef69ba23cd8f38e0917f7fa4d3b17ab02d6d936067d42722c0d223844530d6951c4dbaf4996653eef3684b379659624809d510afd6d024c57b6b4c4f39aa96ab5c3f991a6838adcf05bd98c7e00db019324c72d133e925ecab8105380e606e7c17f6d8a48295206ef1a84518b7de68e2e209810874e1c2343320a40f1b4dbc21222d3592f062ed80ae8c9a5e8611c534ddf0bacc3d815371278144dc15602ca81bca77d12b599654bb48d3530dfa0894c2a0cec0a33f31ce4b295491e9a716dd2b44043f846b544cc29aa5b420353b830475b0ad4b1d921f2742b8475a9a468637eb2c9724e430dd83247386e389c7a2d01701a0b6127b160a955e938c289cf05c7b3e2973a37ce871adbbdce2e1ab2114a9165a43179437663c6b010db77abcc2786499a1254e337a76a58360c54210ac9fc503d6965dd62437cf0db39b438b5e38219f22413635d0cd2dad7ebb4f8f680eafc362daa48e534991ee59ff25e409cc2097a5bccfdbdd82d9a0af8053c796d80d2482e28b3e47db119aaf2e005942160600ade7379ecacbb61b786d23e501ce9966c9715392a9d0c443b8730c07e787bab84968c58414d7026386141914f631fdbf871078f5baf3e6d6c3d48e16f255407b8e434084640a7c4716e1215323c2666ff88b68b6bd9b11a482cec660cb8586519420036266ed50e4a46870e6a49be064bb1b2fe617a189964cc13a7b6f55350c9e47a48efd563925ba6b746bf34499f85b1ff15f89f6e9148fd39c4839b8f5635a0226184a7aa63ee8d26ee9b4522bf0612846a6fa71cf5a4e7e95cb70bb944e8f0a2083ceed422ca8bf291d12eadd76a283194730311534b83d63c31940547b61049726078751186f9f6808515936e46c375436d78272173d80a20eb96efe242572ba38394724d3b7affe1894e34c4a46804be6ae3a2ab85007f400f4d00ab092d0c802ee0f9f1936b154aa37814cfa7de1542c0e2e67328d7387b3b7615ac044b68e4871e358000f4eeb2736a2abbb01501f26812c729f5cfc034b281e89c10709c5000e29e3ac5c4e65a59f09e34a7257560d1493dc1669ed86e005e7c7c2eed258ffa9cca61f7ae1d1cdb600b5bdb86d501c78206f056b279093c4bf34f53a9f7b40f8065ac623c7389285355f30ae06b429715bbe542a81fb1db278e316c68bd5818da16cd9d2ef063ba5026008fe0acc34c156710c480da7fb0e34668e5876c504a10e8fb7c4e6f07238189ee2d273f5b785ef929d876f94422645f08290457f9b1233676e2b6d51c6525448b06c9988d009923c72398bf297d971300f41a14f2951fdb95a06c4961c8ada0df257e68371bd16c010e43fdc3789c5f671e770f36a86440c45758b44034ff1b16454adf482ba65c0f93c26af075296796c02ff744904ef533db4090cd329522b2053bc24489a4ce527f9c783c227482d9110368caf03081ed464811e98626af381b718793196e6a3439e036c48d52360bec0432f046263ca3e706345dd7c283151ac431b06a5d9bb21278077bb5be32ad756c55b166646b427c3b6a6adad3b7dd5225b3b9af5a103a7d6e99d328fa5b986427b6484f5c5b1a92390a2607ae0a540a68a1f5e8d9193a4fd969267aa04b919c53642753ffe937704d27d1237467a8bb68d66c881de86f74dab694b0cc64ca809fe4a20bb3b4433a4e6be4a3e31d41d3fcac39078512da528f71927d7dc0494c51c15a490fdb2b8eb667cf9e5898d82f57384295f5aa0d761a55f0915048f53ada6d1515c04f93a579fa1d761a47a3639708c398914f465a8e4c3061367ad1368a6cb4da48f46070460b041ff58eb43d232355da918aeb9cc26f9cab1ccee9352a83eafc84869b782abf711c145aff6ce44d10b77ec1ef51193420ced8dfc141387e2c201fda4046f30455b2ab0ddb4036c4541a4a690e27247c29e9e5bd67e90c1627d3e7302ada05801bc118252935b9d6fd729c58552b9d376586f1308bfcccef22092febbd8ed82b390135e3154ea3e7e0fae5fb6a088f70c5c0f2f1d711ed60598fb8e9f5bd388644d7b493591821bcda8165c9ca8d95185676b71ace0a438e9585b482291764a89f3a65e8d499d080b48c851b94e44a410f8d8c0407daa6485209474185cb1711ee3a1cf3ea0dfc4645478157512e0433e4256a180698ce52c6e88255648aff76ee29943c60257aed1187b9a5be03a71ad645440c5c22a8a4542ea834f2f1362820b55135788acba4ba50956084a7ef114a81f87eea84e022f79cb9e30175a4804c444969a55df25710177434ea8a4fb48337c90f0dd289c71f3d0f00214229f0e9a381ce1d38bdef8056cd6e2a67e19850308a02b5743f285e818c56861ea407b2313bf1e9cdf8ab7193622de702fa0e09ee882b84e3c2c085d42f326fc4c423f783fb2a93b223540823bdf4f3762589803485210cdc40243ca219683c6a0a372b6b32ad5fcc174375c931adb1a6d58574d697e45a66fb79181559c8b71f816a90eaad50be42f3f741fdc7057f5e9544c8b8e4d94acda85b543398d3038c13f3de1697219b3407b3519b8d266024ecbcca858d4c3d2788c22b0ddb80641b18ed807b5081df10982f55b10c4cc49ea976c3cff91c73449f665d5134702930e091782ff2f88d7e5ad6582a0d0492edc0f9c3a52f57c00fb20f08e607104f2d0b7b96e92f97211632e90998c85d0fe722d2adb6524728f97f6802c85ea002f3b884379fdf4f23f8dadf5c0582ddce2ef23de637d3bcf6fe6e7b6b495e266b758f847d9d83dd179e38705a9ab87fd8fefb850bb4038a460987e2e52746597357b121ba6ece14ad9c14dcc082aa3d8a5320ec01bca340dc06cd1269c3bbf151efff71bd48901bed4d84905f411f3baf9166d0ab7cd4fb7fd40b20f4cac7bdf161bda88f355d7706d8eb7d4ceff8b8f11a2fb87a852037dce3d5c5bb25d156d5c92020d886c6b87290b213a4308548b3ba0cf6de6190751fc72032ad26acdd500fc1a720eaa4a762a274048c70c3b8cc2c3ed7b7deeeeffd78ffca3dbeb3f8ab9ab7579653a85aac3ff87e421a62fb19b6d99adf42cf146c9967a0e52381cd40bc2d0b75b7098c37d644725581eb609e8cc5c044ec81dd044c49389bf0a85165ff8a24e593f4fff04477fc0c5bb2de8c423ea20969dfc5d95a4db48b8a18bdcb601bc2a6d66c0700d63790155d884e9b4fbad5242e16906233635d2d8d453fef428faffac90deeb00840d88de0dc270024710739a621fc6ac206054925b84a81d3e89f10961b21482f37482a0fe20d0842ef222aca9c29825469a7d5bdf6bff881e13124dc0c6e5402750450015da19672fcc76340c634d8037cccb65a58caedaf501b047c3c69b794a256b5857c0881648784ef3e1517033a6d15e33111774898956608481597398027af7cab65075a5ea87f8909b13ee98a0cf1a40c443a51fa3c0bdb119a11815c7ca9f7ef86f13a1c6fb4c8038c7961c2320aeeb4e758895cab3cddece684873ad1cba72cd9aa3a40283c117722a0d197dfc71833ba3b1bb164a52f4fc7a1266b8a840937a33eb338f33360d475859b1d0dfff8dc3f88190fc4a014cb31b55748203c6ab6fca35a1b1e64c1a3eb2217454abf630c48495fadcf049f13e3306f652bfd225de84581b01bbee778bec44af16e551a87014bf6a1037c61f558233492dd320cabd87ea73802b3237cc792d2e520fd46380fc17e089cab21a84e3aec1e561646071b01731ed38f298e59c784c6a4625ac65c1123505716eb5e22e8ce81d03a7019465d22849273208a9b5b722f77bd37353bb48349da92b91bae90a610fa435d58f7b4ada1e16909c43de3fc97e094c3de8843355c5c101c60a0767679c823b7d6b3b7bde87ac1f262c0196de7c755e705b049e05096ca9a6cdeb141029844fe645fe976a0553c32ece269c82370576322f4ab1d4d8858dcdbef59f6e2ec0370d2ba9f39b8ae1e30766c2cae199eefd86c44759c75f43a2eeafc5fa4092f909c967278f689a8384cf8b0dd3e040fe03c2598811955d1301ebf2c6985e70ed978b83e131afa13c6af2b5cc25ec6e97733292be305b9a537430c2a6ccffcee4904c813933dfa228373af89f71aa0d6d216dc6d2ffff748a2bc0c527ddf106149a52584fbf05a780b8f179782300377280716d916ac67813ac52964e22bf1f453b7595487f3fc078e24c4f35cfac6c27ad708ccdab1bf84a8969bcb8243482399106f3b0a3d280e4187136b8e65811cf974eb94ab2fcd433aac47ddcb36e61d4c0f79f2cf17269290f1f3159e2f75b1f0dee813eca4021e89848e0b3660b46439330f0f0f0f0f0f0f0f8f3121b5b54f48424a524a4aabd75247e420a524a54c2989b7483b7a3a33f129a6c9de6498f8040402c20bc70b970ba529194ac5532a28a5c7a80127ee5f214f5a8e783a3168c07a4a297878ca32d5b663164c8ed729a9f85bf27ae3396c6c60c60ccf614305336698a143166c66448d9d4468e4d7c4823fedaff9a34760c189ee1077731c9d745baf489ecac9cdb74757703a42ca15730a19947dad605f82662425ace3dbc70acecdc3d44790ef216dabe0934a4a664a4e1e3cffaae0a444492b62a954b09a76a742aca8bd6799252a785bcb1d59a994498c769c82ffa484d211377595af29f83af9a33f9b8f1252540a6ee2a65df797284953527016f4925c3f4fdb3419052f2612c54f6645c1f9c5dc94dbaf34e8e0e1e80805abab13420e25bede9b147480824d136356ebd99fe0d4fd57f637992df6da800b68514ed0e1095ebb2477ddc43bc1c41c925f98162dbe419c603d922e696b494d66cf2698e469a1e67e5737d2046fcaf467d7f6c7c8e94c70494fd9e40ea57dbfc504aba5c77b83ada714d24b30392c55292d1ef27f8a25f8ad0c169e1daa76639560547559b885790a756180c60942072598bc41529c1c3ad4e23e6346c724b8b5f8e31b31eb3eac1a6934eaa6d021094ef848c8e1679d69523f414f60c60c2f3a22c1d786082a9a6b4ec999ea80049783526d2288fe11bc8ed021c7ecd31bb2c8118cd60ccbef49d4434f7e8398024e021d8de034e4dff43da943ca0d6211e86004abc12b8bcceb9e47c72c82efec5082418722d8efec7927294b29c9b023119cea94dd4bc6122ef22e0e175d74d1ef051765800e44f01526d3c4cfd095cf6c41c721ceebcba2eb4e372ae83004fb1ad2b43f3c2479ea1bdc51082e67e57491a5ec20042ba23db5ad8e490a5dc0050e1a9e6c98391737726cc720f00b49a530e5a2a26e0c3a04c1994ab595f54d67aadf11085627e5b2720b992de21d8060628d797b55a9945448c71f38a1ffa305b788ada1593fb06fb62629546366d3fbc05fafb7794bb0ccb4f9c07e8c6cb2d4b4072eaa78aa4efa3cbd5c3d30da79a2e7f4f595369a072ebf267597206944060f5c063d12ef2f596a767760b4268d3177ec16f5abc30e33e8a8c349765042c7545a0ac90e3af03958c88a215f4ea2b21d73b0191d72603fc9d131258fef9713904003a0868e38701b2c8d5c1711b225b57ff1451b1278c1c50d0a748e66c0052420811933686400ced00107f672f2159d624cea94ae60a1e30d8caba958a752c8775d631b3adcc0d7c7e049d3db36f023838aa0a116717b3674b081754b225685a05e035b6eaf6ea2a63ffda506d663cea1be7e3f8f9b062684a42fee6890adf92fde810636e7e5a4824cb3b45981a0e30cecae8ae6bd3bbfb69c02860e337071623ecd1c3aa59c45eb858e32707f994d591695e4c46fd0485e943b420719b84b4dc143b2181c5c181f748c814d31668b90f24bed88e4b0a182d221063ef2fa8dd96ec4be48018d30b041481229e4244fe434707071050c5c98fa4d41a62b499e44838e2fb09147d4d94775f111aa91c44a0076d0e10526ad28d15841684613e902a7b5b784a4bb50a1830b8cb6eefc93906369e8d802a74bea5f67ffeef4592d30aafbb3d783e7deb4d0d09105ce72d04188125a648c3916b811faaf6a21bd4d4cf10aec5a0c1dc945a9521347d46105365db2fe0ec2bf62765805f6ddf4e7385eeb163aa8c0bf7d324b093a22f7d33105c6826e0da9e33987d0b09156061d52e0af920ceaed453fa64a0abe880257a36e528aa8a3aff324b0fb4107143ccf5fb5fa136dd0501e743c81f7495a993a7a9ac72cdde81518740263df1aa4c5b1bca63d4d60438f6bf64d4a3d05bf461adea083099c1cfba469540c9a7a61435b80bca0000ae00e1d4b6092d6e49a827e97b549097cad779654913faba808858e24702ad47b2d54590ee16f193a90c0e71044c8bdb1f65dcd11b864392d57cc15b91742860e23f0b529c4226e4811f8c937713787e7583a18860e2270c94a9d48d14e770c818d1fb1b5e4256971371a2dd00f740881fb4fc24e488aa03cfb0e7404815359a966f235d79368aed001045e34770a399ba44e3a2b56e8f80117fc3d04b52153238d469d0e3a7cc076a4944a074fdd7b658db416acf5800d21966bcc53513dc303fe92f6ca1b32d4b10326e6a6354f162fa7d420a043077c090922ea256f8624e580af983daee4b30bcf260eb8bca8a34fc449bd7f75dc805352d3fe7609ad4ad7068c52e33b4144936be91b1d35e03c09fd697f6b9dc65423cd4632d322030ec841070d18b7affeffb190aacf8213622a88adbe27adb194051bb7bf2bc62ad3696e0660c4824d69539e64ab1efd9297b0e0bdd7df630c39e60418afe043bcb451ff25e84b2379d1e45cc16669ab6822061932556d048c56f0371e36415465d18c16197080b10183158c655325a3dadd5b560b2360ac821dbd92ae2fa7a42a7acf8dee95ed2e239b0418a96054a4c9c9f2078931a660a082d5089e9d95a2ed22458b2db4d8420bf30818a7e093d2eb2d49957809cd14bc4f4e5bfae40499925a0abe45e69d2521318690cad17e72dc80410a368b7efd90745809114f41c01805ebd9eb7df1828aba9fc11005fbaf41dfeb4b67356d8d2c2c1a80110a2ec4fbced39b2b928ae2e8030c50f0ad31c7d4aaaf9553e4e200e3137caea67753be9a2fe8a400c31368cf76b24dda453db5000010303a91a7eeed0ac13c5e3f80c109f6433669e5c1e2a9bce826b86c3a98ca21f754a4cf8dbe40299a6033fe691f9591f2f51f061899e0da6fbf52abe4fbab6082d3bfa395426b525a62b904ef19724c97a24e12ffa025f810b47defc40ede2eaa042754c794bc36e9a98a53820932fe645162b973266b128cf726a96ff142352b0926ae7ebeedbcf4b596014624f85361a75b7df6714220c1a5b6f4a4b324791e458f60f3ed72cc19b9bf73c411e40fc1bd73f746b0a63ba3a6902445513a23d82a4b5dea679d37ca4570327da9a4529922d8a094f64f113dc97037115c5e6f48c132e76bf8886025e62b7dd63985db7b08ae93e98ca9534ba5983704db9382f9067d39f7ad8560ef93daf2b28d105c3013135372b389b006c187875022b778cafb7bc31004bf195ff3dd0895589a0ec0080497f306cf3c75a1f29a040b3000c1e48ea5cc2649f78ca32bc0f803fb9927e9896b69681f0330fcc06898876c17327ddabc0f9ca5b6564ca67225e52f1060f0810b9195d734e7db905335d26ca4f4018c3df0b962e6deca9962d10327a964f2daf423b7926aa4a5d4346c24d30318796062aac98a936e6cadad9176c34990bc0bd4010c3cd89ff95fb91e52793968b4e0468e25598071076e82d4d518d592aeb809fa0476605c84ceb7119279bc8fe100461dd8d2a419aa555474a7d448ab1bc0a0032b1a24a49cb2eaea8e36ca66ccc0d145172968c0161478038c39f071640ae197b264f2a01a69280032c090c3b61be32565eabb730088028c3870494d44dfa4a275f90b07f6b3a62447ff7f48ad1a09da8b968041018801c61bb8f83d312ff807bd34ddb08132100b186ee0b754a760992f681c2260b481d32f4fb596db647c370301830de5a997875f673c598db4b741e3d0c05803a7329e92372a4e022fb830247f80a1063ec4cfb94d6ee6268ba681ab89f599a496d22112c3051868e0feb285b28d24e35ab600e30c9c45aad211a692d000c30c8cfd071962d41ad174712307a2d18243a30cfc7b99672b4d3949ca910c30c8c0e6fb243379cebf51df301b03373ad2bd2e26494a4462e044040f7d15d1a46a65038c30f09541c8b6104769a81b0c7c753279426e48a9319906185f60fb5fbc62975a47fc6b24046078e11113c9fef9ffaa3287d105b6d428d51f5754d0ae6aa4599a4ee003341200830b8c48d7a98269ee18ca13dcb8a10005cc98817c035d74d127c0c08c195be03d87de9e28e1e96987a105f64cc7d041ec3e30c0c802e721079545971a4d8f1d16d81c796326216f185740e74c1db28bfd56e02a66f68a0ec96973ea0930aac06bce6221a6f206993354e0aa468b0aadf89a9d62028c297039a4d32a414bff27111a0f6048814b49640ed31b31e8e93900230a9c087a2fc4d39ca43d9f000c28f06a6a44ccc94d5d502a3304184fe02ba69096f49350e67921c070022342321d794253232d078c2630f9c72af37ba8a568aca1000613187915d4af36a95cf5daf8c2d1043096c08e96fa9873df35d26ac050029faf3fad093d31a5bbd448c3190148f068059bf52d66ef901923bf1eace06aaf764210b9c72a188f9ff4c5948c9a6378e0a10ac62a77084a4491f719d3399a0137f04805e321b2c6b0efaed31954b06dea962789a6b47c993123070e270117094fc16a8af92586a89a6448c1c0c3144cce7275f3a8ae79548f52f06ada31a4d51f7539b413f8000d16789082bffd0e3dd31e09ccf01805eb39da26ed639d5b4913f8008d2f3c44c1a68bf729df42279d6a90808b1b34be7037c1bd4728f8ecde762a4ba06072e61a75f22d9fe0f45bea88dc9954d248199e073c3cc165ab77d027833c61f94eb0773a832cab0921c939c1b8baa88852f24df0b9e2080daa214df0216c7754b724ef0c658293a63ab2a6ce23f53e98e04ab9e48b1ad44ab29c4bb02151c342ecd38b765b82c9a92a497ecaa2c6dd4a30394d7e68087aeddba504374a2d26097253fc5d27c17f8dd08ea0a5e67f4a82cfa8adf7613196dc4d24b88ffeff9699ef7e3190e0e4782c31cf1174102a8f60d7f3a71ba5c4930c298e6035d46628651db61d6c04971db7da649fe7df8e119c4a4149b3d32f82ff68317ca32711324811dc774e7921672d119c8e57e90c4ac8eab210c1a9a484d4f862a534bc1a695e3c0dcfd13772e038880bf03804aba1f7c1c79432dd202f52d080b3f430041b736f8e9c4699f6da0bc1e656cb1d25d64ab6122118f91d6f7d62e6cfb11e04eb112be9d19f20b80c49738f504b1de225106c929982b0af511b6904045f7921f7e9789327e80f8c6adb68c7eab7d1cec30fbc67045922aa059dd85d7af4e13cf8e0b1079b31060f3d9c7aa33fa5e47469c005b420c7068f3c9c071e583d3df244526d2a6f907fe1450abe01382640812db4d8a2015a64200236328064021fa021804a78dc81bf0d6e5b25a2259196871dd8fdd7f50e0f41e3df1e7560cb5377ba9c3f5552e2c276e0410746e926d55deabf23a95c0088e03107ded42c4ecc7d3284ea75f09003ab6a31d364c7a0db937160d399507949b5396c64408b2de0c05bcee94ba998ea2f21273cdec0e7ce23fc94d64d88f90624e1e1063eb5e670ef5c9a438ab581bd931f6a4c4653a173b4d8821cc2830d5c9a103fe4f4e59f7d6468f0580397b32521c57cf2070f35b0d92e53f576877c927273f048039323270d41b99fb7bf72f04003939406952f23581eef68b4c1e30cbc66cb6baa63c94b9d3703139210adf71d595a82cac0ae07e193840613912032f09d95425afd6360f2e4cd21aae7564c550c9c309df933b7835fb084810bb5b2d21002031b9a2f495745be53ff17d8531aa4b5e6eceb96e405ee5255b6d6dcd0340f011e5de0367b68470f1616e20227d2eddc37d85b6074eedc9c72b25a60ec46d5e999ba9c72cd0223ccf46de5a6e9742616f80f5a91b3d66fced75c811f11f57e5267d660b202a355edfd29248f6d972a7059416d95ec8c1a3c4205ced6f2b628d3794c810f3993f6bc9162324f57800a1e52e04b480b3d5513a4f5ed110576f3e514c735a45d4e99c0030a7c861063984930eb9026e4c2e3099c9b4e22688eceaafa3b81dba429a7984a9dab83155080210ef36802579b635df44d954ce916e1c1043ea46c9aa563e6b10446dfaaa6bf4a15aca246f050023b4282dede5df90725d982471258f7fe2816af3ddd5624703bdea7bfedf4678c68c1e3089cd064fb7d2d2286c9088c29c91a52d4eb0a1e45e0236e6886c7495a821c041e4460834c49176c73fe7beb31044ea60a91738a71250979088111312747b5adcc23084c122aa44cf22a0f20f02121c7b6cf4954f7a6465a0b6ee45063c3e307ec7dda34fe39a66e30053ee0dd83728baf21dd644b8db413a4007909bce0225be0d1035e350615834e212c49be465a5981070f98aca24b34da6ae51e3be07a5dff4ab958238d460b6ee428393c74c0bd8f10aab27257ea9f032e5db598a794e57a4133669475c10307bcc6fe2e3d6ec07e5433559bf2353da7461a0d1b393c6cc0267d6f955c9e46b68b9c056e47c3a306dc45ec51a5ac2d66b088c08306fcf7a6a74ee9e324b8d135d02c181d3529ffa859324991460e1c292841eaca400c59b0f9a2b3a59be853da353162c1c64cd66964ff38a41003169c46ba9c41ad826e88f10a2627156a375fd4158cf4aaec20820ac973e7857371a3015a6cd182193368588c56c46005e36b1152455256a95b05d7d93dfb3e6570f71055704aa64bb13685f869cc18a960c7dc3666f7a9fd9ca382dd08c94e6737113b055f6661f984c590738818c314b9aa55e52c8dd1d42ca34ed618d26dd6766aa499c0868d1a34ba485cdce1214629b8bebc3751ea79498514c4f4be979a6246c19b50eaf52b8735d2708b1a39b8e0008e2eba5080165b68a1c5165a68b1851618d0220311d0824999ab808b220a46a407b5cba6a2878c8682cf2721265332573140c1e51845e5ec4d9a945e7d88f10946342519ef3bd4b37ec4137c0ac9b736d6a89887189de064ce75fa3ce48f5613ac430c4eb07e9e3668d9654e21493818b07088b1093ed3636a11a62e52e50a1b626882d7789692a9a568b14506228003c71a62648295e456ee27caf276d4628b2e1a139caa84549a218f5ec9b900a315625c828d25d4a5b78cf55a1e4b1435a9d363414670e4701c38ba125cb692b13b6f55de2053236d8d023128c176fab84954526692a449b0976152d46411de16920497432af9313b4511033122c1a9bb2074eea0b682ed376cd0b03b400c4870d952ac8b56e3997edc0208311ec1a70f96a643e893f96b4770324cae5725a9d9444412a3114c6c537aad47a6f4d931825127db2f4af61c82ed050d37bb8bb10836e91c159328fd0e221e85188a60cc738a693fe2798960f74d88a4d01ef48b880836289d79b2e8e468216bc1a1c145dd03ee109c8a95b7c4daab9166086e4da84ea9757c73eac210a310dca53549323b48fa3d1182f114abb64f445cd42fc41804af6bde71b437444e108c972a59225e786bcc6ba4adc0861781e0be53d49ecaa2e91ebf91022fc40004bb9e556ff1b56bf207fec2bbd2c8bdb30c215088e1074e864ed0aa8c90009f10a30f5caab547d172ad97748d5c420c3e303a6811e11b74759a7a0facb85568868c9ea3c50fc4d003a3217bd6504d4b22796083f0902e3f2fe95c1762e081dfd35c53c29412ca3bf09691ded36f8e88fad8e18b22aa73fdf31a69756077e455363b9d0e5c5fd4117aae29a84cb939f0f6197244cfb9dc532907ee2a6dc516370b1762c48133f5a733f7a4706064ceafb42b421be30ddcc4cefe65b981bbe0be9e326d884fbe0d7c1c25b24ab610830d7cee0a524f6de7b57e6aa4ad81fffbecff4ce376e5500397634bae1d93c68d1b9e062e9d4efa13cfa0611349f7ca83e40c7c9410724e976fd4c5941a696660e4e94b2252ccad0c6cbcbe9c734ceb924a9aa3b9487e821b9ea39c200619585189227d6d53236d0c671e59694a2d0656638ab9c9ae114134b00431c2c089b098f64352cc3e18f88f16169479ab4d8e91408c2f302aef87d2ccb92d6e9404de8517f80aa9dee3b9f1235d606c94e609e5f5e29ae4029b73cd6d4cd828114f13630bdca9f10c95a216626881510b651d923784329d2cb0164310125c628658e0748a3997a8a0235ffd735760b29fda6ef2743926252b701f2aed2c998a355e57818da59134354becd1392a303a07d3f9da3b2429b11a6953e0c2c7ff3a6a6ecaa954234d0a9c950c49a7ccbc4446a2c0059d114385b4af13d51a696b218801052ed365ccb81e47984fe0b2b86aba31218244538e14d810410c27703a66a769319926b0a33d3f54d289099c6b6b277dea2cc325303176895e9126253022b609ed96df22799e04fe235b4e503b2652be91c0a5da65151162e63ca523f0f6499d5263954da79206621881cd74559335bc7b3f5223cdb010a3086c5ace7fb7691a3452fb8d3b33821844e04352a9e933aa246b085c4a7731e9979043525c084cfed1e29152a74d9fad915670e4c061e30c023182c06afddff5be8554c2d222030ec84004baf8e2040f68c08c19ef89860abc701578c176851840e02387b5c6d5fed1efb161e302c609317ec0a59b6c95b4e9bc9bef183ee0eabff7278d27460f38d339692d57a8a044bb80183ce04d73e59113a4694b290d2b7a88b103463d3b2fc92b0fbb910ef84c32e68831b988a63a07fc6bce5477fb49e4d662e080338f9c5493f73760e409adced33f1862d880039c08cf9b25e97bec3e158cecf15477f5a5af4605233f6ad67442648af6145c060dd994b6ce501353b01edbc264d2e9631d96825196ddad4a65fff6470a3e68d2ae4e3712832419551b05ef31d7c79052ca8f1aab91562307172b30d645a30c5170a9628c1d42893a335d8db44caa38b6033242c1574a224529710d3223a0e03ca449572363b02ffd27f810ddd5d77c927d9072514c8b0c38c0bbf8220519b8fb820c4fb0994b748a87529f773a199d6092f0fba821d489dcd5066470821beda5bdffe287fd65a12063138cfab497fd2fc752d76568824d21fd6eb5780e299a8c4cb041bbc44bb2490626f8bf20e4e4d23b694bc4041997e0fc3b8752d7cfb5ce58a212ec45d7915ae973ccdfcba0047b27c4d742f2c89804fbaa27d126e73224c17f8dbd28cfcf2163908c48305a2a5f8f4e823e2a03125cacf348224ddc2ec87804bb7efb5927e9e4b9ef0826fa9b66cbbe89a7f346706bd9e79a274670275f456d1cb9d79d5d04f717ab4aa915c16529a5cc3b79ca5ad944f049e93a11dbdc537244f05555715b63a52c113d04679f4fd4784ac92b260dc19e7a89ff1d3b3db68560624413797dc44ea247083e272539550461f69a41702129e5a9b7b1bf4e10bc650a2a684fd5039c2023105c7894689faaad363f37640082af3e15f33af687468e147c91e60f6cd75a249d5367b3f2981fb8cc1941c4d5f4411fa5566b5bf36b5c1c4f34bef01b5fe05824c8e0039f2b55ae05197b40aded84f25e53da480603197a60edc5f4b49d87a4cf3379487b9bb4ef3c92aea3810c3c305a53e4a9ac216e6db0469a17ed5d2075818c3bf096d3856429febb586d59906107f66a74529d3585a424c70b1975e03ce4f3b428f21a8932e8c0765f2a33515a3f9ad648f3c2067216b8c998039719d6d9e46a726074f342551c292a6e70780964c48153aa72678e1fd93c66ec0a32e0c09a0875a5335310163926e374c173bdafe3062e89147c9372977c226d603de22515c911e375cf062ec8f83942eef1d0a0b30626f88e760941d6e566d5c09d4649232ff4594cc934f05d2aa297ba0822f468e05cd2441749f2abd233b0e9af36f456e4aa57ccc0e7a9feab495f414e481978d33962b628f53e3224039b33e62c495a8b0ce518380d316ed5e8ee754a254186183820230cec6d8b16111fa920030c9cd20d79a695a1fd5f20c8f80217f2b95712ea933686d0f0027b1a3e3182b264e0ae0b8c12215510dae45c60359dc817af94b6c0e8a79c1bb5d4f77aa405de5cdb74446ada484159e0765fc732af57e70e6181bbfb492b5a934e10cf15d8d4ea262ae5ea50aab502174be68d21a8282ae25a054e0615d5be4f757fe7cc9821830a7ca84fc1c44598104a3a05b65b35f6a4cea14d4c2970e3253b8ddb8b484a13053642b45819dc4424cb4081dfcc1e2a8ebb2425234fb82f67ee04eead83762a4fd9bc824d6024e75869344529e5392694efb3658d29a42c81db10aa4fb608b5053294c0d6ededa72f51d1b93256909104fe5350a1a35208a9420709ac67b869485abaceeb2338d691d35ea669047ed4ffc9319d9c31e32c0e328ac0b85f36ddd490085c7f705bdfdd5279913104fee45e0e35bdb0b31b0d3284c069845c55d922230849ad749dec723287175c68e0466f607b200308ecc4aca53f758a3925f90363704b63e6dd1753b620c30736c368c8e841c9e0017bf162d555b56ffea406942063079c576b281d7453788f3366b4e0460e2f3c083274c06a66cc3984a0e1a6fa1164e4a0dc7e3175ff8e051938b0b345634e704d31fb1b6c29659b670649deaeb962c84f8b20c49b820c1bf09ab531638990242765041935e0b209194b8aa56c70c181e43366e0281cc8a001972a7808edaca79de41fb3e084243522869cee8490f990056b23729b50e1971c7cc482512958127d13359b5748830f58a0ef6a820aaa57d493b49a3ccb1e4d57b062a7720a3ab5db0a45957a48c242061964057b3a66cc1fdfa4986a6f7cc102fec286aee224355228212fbeaf0a540a75de49fb099954e03f298f28212accb415c93ae8ebd66e9080d8ad59093e4ec1a78ed0a31282d0112153707b766934c54e29188f144b7e1c99b4a73429b80dcb2958688ba697320a46e9fc60f92a9ed3591fa2e094c79f9433fb72d3130a56744e4a59e6a0d1e20414dc79a83e0fda8f4f1462b28db1fcdbdaac91863a840f4fdcd9ad734d35937a1df8e8c47d7082ed3ed11925d5fbbbffb10956c5f24788e62e2ab626d89cda749490d68f4cf031a78da619417aeeeb295070021fa021801b7c6082d3a172723b9d3ab1342e6ed820c11962fab804671da3c6eca492363dd6489b3163c68c0e68b1851612c08002dc1b90fc4af161092e5432f5ddd6a07f3c3492175cbcb1c0d3096cdc6840f2828b06ac81e2a3124c3aaf9843997f8e9bfda0046ff6edfaabd19304f524f8714dfde9dd2aa693241811c5837787de3d8f44824d31b9566ae7cfbaf003126c2ea5520ee54978883e8271cf9e2cd3bf594efa8723b832fff8fed9f4d108f6745a8d765c8b91941f8ce07227b73f09f93a7ef063119c8668ca4c89a24ead0f45b031f55b5626a5f9d6fc48041b64c829e59cb4acaf43b6f0810846e555d08fa1ea53c80fc16e4e272187e8c3106cade68e8a26f4c4d41f85e0b3a6ca9244559b90dd072158cd49f976f613fa921f8360b527dae9d54b3db9fa1004db16d4494c8baffdf98f40f0e1c9e4269deb0720186dadbd1d524c117ddb2f3efec0a80d322c5e103d513f303e29650e1d7699bcac83c1471fb8b8d7975797e927311a7ea38fe10337d69de4988a8468e11e78afa0df752ff8a107ae23951069554bfde9e0f8c8036f1f2b92f094f4c64e1b5d9032047ce081efca6b394dcfc23bfd710756cb4d6f527f69418ee6c30e5c52634adde8e8764ca903636d52cf723a912fda0f3af0312499f39afe1f7360443a2d3f21ed36c6fc871cf8afa064b2ace79dcef2110776829d483929992a09990f38302a26a1e3e8c9b13ac67cbc8151dd793ae712a279ff0f37f021ae96c689e2973c79818f36b062ff914c722af92967cb123ed8c0fe27fd1b542acb7c9f123ed6c0c9d8a984d20c491c5cac171f6ae0fa4d997e0abdcf7da6c166d4f840032f9a9521585ac82dffe30cdcc99824050fd10f33701e296f44cdf6471958eda02455068f9653f0830caca4d8c9d5c61f037e8881099af268efcd787dfb4718d89c967b9f2fb5ed8a3ec0c0e7a0524a8a9b4654ce7d7c81cfec761df32e5161faf0026feafea22eb21f5d60cc3f075315838841eb35d2f04a0d3eb890a6a45649e70d8eae912ff8d802efef9a4ce87e2c65f91a6938b8282df8d00267e95e35d384605b1678ddcb11fa29c898597917366ed0c002ab959b4b42eeed3ca181830bc2828f2b7039989652d32935d2f0c30a8cb0cbfadb552724c96ba4e1e81af751052e26f389969ade23bd393ea8c0a99c838be7f4a9c24a16828f295c7d4881539ffe63786f28f01105c6b5cefb92e9943bfe8002e7aba669924ccbf59c65c2c713780972926f50c92685c8096ca520d4468914dc6296081f4de0ececedcc474a0e8f0be183097ce50b3afd268b153f3880f0b1044e54b99907e996dbb4317c288153f25ce28d6b08258307868f24f01394298d6216eb24db850f24704974344fc1f25d2afbe3089c9d7b56a8a7f248b9113849933798e5ca471118a51db47eae8e296e0c143e88c0462e2d42771aad1ffd6bc2c7103895835d8ed61b5397324008fcf7557592a3a2dc844a193e82c0e8ed52f23d8af85b3a0c1f40606f54cec1e266d3d3e7fd80310f26477f1041552f1f70935f538af8d9470f88de1953cd552cab32b6c7f01c644a2aad91f67ee3cee40a3e78c0beb678a50ea6c55fb4032e551295830c2a4a2cb50ed8108fa2b565c9d19e02143803906f60c68c1933707861e32307bc85a45719f69124c4940b1f386063d6179d379fcc6a9d0ca4143e6ec0fa96fe98a23fb796f861035ea4a80fe22afaa8011f16aae3ba994c42947af8a0011b928520ae51fc63d299055fe7aa5e2a043bb1943b78c88211a637c87a3b8b6beaf400128b42a98d31e8178f153c60c177e8535afe1921063d7905a752b44eca21befe8ece156c0e52fbce621c25540c034660b246ea4d3ddfd6eb8bc0d9e438923de514ab9e08dc55bceb9359a6213f04467b7fc8dcf974d0bb10124a973e08bcd65f32ede974aa4060358a12aad631acfc01db5bd9da366cb3877cc0dd081935633c1573ba075c44d752625a76223c60bbdb2bfba885d276c0be08116c475d94d4ea8037e91fff4348b12d25079c1275e341e898f7c5019baafdb5d2ed4e94dc80094a8688faa7367fd006fc8e8b0879a38abed48051a35bd9399632b402d080514987fc591b29f7b3e072c71169b34f845616acd768659094c782334d4987da0e0bde4d4f92a04fc96bd32bd8db20fb3a23858b5cc1c65115720e21d3d256306e4944922521c81c6205ff12ad5acf4c4d735661b2e0aaa9fe2655f09e7f6df487a454b0112fa994dd3c882c49a86054cc1e32675db749d22998ece1a7b326b72c319982f5b8a9a28fe54bafa352302a640549dbe2dd3a22053fcaf49b0a32e42073340aced33f9b3ca5ee4b098982b3e0b14a864877a38442c149d09031e974b92642a0e0c736c5fc63a15f1ff409eed426a6679ac674234f70597db5bcfb62451a3bc185a8ee649ba29e082758f3ee64ff7b3a68bd092ee55431b5e8e4f94d4db019fdd3645e6a4f4d2638f59758ba2ca9fd10136c0e6e962aa86a3ad9253879273f830a5132a7902538b7aae41f9a45f44ab09f16646fc85322bd9634b7ae3e097ee3faebe9cffb133f9260527e3a2d6a234acc23c175d61c2dcfb4165a487015761f43c8a052c4a047f0174476915b11a3ba8e6037e6760d2286598c368293f43ee249533a9711ac9e5a456c11a96d2e82ff4a4205957e2ad75404a74ac6dd74ffa85f2682913104d1a33aa2990c22f8daa04ee792f9c6c2738833ea7bc7102891b1f772af5308c6ef53e9484944ca09c1760c4aa8d1f126c02018a55df42475775abd092008cee4673a61fe23e4a809100836bf490d299dd4baa0260020b83eef0d162d2c784e13e00f9c68eec578e9cb33dd04f00313f226dfa46356fa7a1d40803e70fdaae555793d8a960f7ca89c83c8a7ddbfee1ed8533a2664ff27c9ab1e182b8d225cbf4d4c9a07269e59b020647b87140f8c502a478a3596fdd33bb0218ae6ffdcf4aba71df87fdb10849e75607469124ae7ad9c7d3af0a92798a64f4977690e5cd0294ab6502b21c6c8811bdb507a648d3e691cf851b5a3e3a83c2584032333d3a95fe40d6c599239ed836ee054ccf27b450c53b10d8c46cfa4bb535e8e1f1bf8f4c9a37e1b9244afd7c0ad5e4e509e1af8b48dbdbb9252779706ae425c2de88b896b8d06fef365c59c381e72aacfc086dc78d994a87863b51958fd98eb4fbf5344be0c9c9b4e4fe6fd92813753e331df6fde7d770c8ce7a9241649589eec8a81c99fe65a22dd30f07e2295debed62475c1c07632f97f7fba5d93fb052e6e9eaea02c45af5c2f70be25bf53ba0ddd97ed026fa6f7d2225ab0bb2c17b8b4e69daa73251d25bb0526b59b97855467fead16b8cccc9723699294b4cd02af31fa885930192fb558e073e8eb9ca87fbafd15b8ac29079dc5ad2e7b2b30229e43b036e9fdf12af0df1dec6490ac224a546033849482f9a46c6a4a3d8d9b72ab921478d39bb3461b09ea465160db4fd53ed8a649395060b37c54f0c8392ba69fc089144aec4bc809ecba68f8abfdff649bc09d90e857f1e4df4799c0a88adfbde5934a2f4be0fc42e5de88d257224a606cd773b0d34147962481cb4f2aa2aa4dc5844860f4a5dff020fcb67447e0f45a963693a4533d3502e7172632fb7cb3e6b4084cd0542d2aaffba54d89f07b4abca0623f0436598aa2eb34a488bb10b8917ac1f4aa53043d089c85a85dc27320b0eb5b17cd6bb3b9e807ecaaa94b0cdeff29f201df22a3c9c8d9267fa807bc5e92d57f5726f38707ac8a4e9a4209ff08393be0f488a42dd557c8bf75c004616aa7195295da39e0324b1635ca2cb969098003d6c6a4e8e9ec66eb12e0066c90b4b6b6173b882c016cc056b0983ea5a8854509500376cc2f5945ca909f24000df824c382e6537b92ca59709ddfa53b424a7e1759b076a6b641c60c522bb160537373b5a5dab44ac28271ef60b28469935992af602bfa75bafd75c82d5dc19767325532877c3995ade064a41cfa3cd5534a252bd82832e56e92af828ff77f27732d784852056726fdad3e948e3f4a05639bf756648aa71ea182cde5162258c58b203a059f47f209a5644a326f53b057693de7c71cdee952b041e5181e942865272505ab19644753fb9c951c05ab9e7b629be40e188028f813e969292d9a90985070f9b369b3112aba33a0605df3080de9ad82b27c820d9ea2acbcc4ed2a9ee044e3998a1576824ba52767df585fae71823b4def29a538b6fb26386df17b4f838d95ca6882179d420a3287ce142d93894e49ddf7cd31c18810fd4bfee8a5892ec14634f330f75882d5887942eeb7128c58048fda796b2f4b09d64b42889663b77b26c1f6ada5e7ae24f5488251da368904275cafa4e45ff59c16487035bad56b928f607f37a7183db9a4be388213b2bbc472d48c498de0f2ef5a2df3525c0923389d2ac4f4b499b4bd4570a579d3798cd1f46e8ae0bf2fc6cfd024a94f04134f5d4cc92cf305218249e199cba2e6113987e0437f4fcadbcf905531047f52624816c5358d5e08c69274fdcf55999a44083e95a70f593364af67105ce6da82e0b296ce9cd492403021e8da8b360920d820f9435dfa482195e40fac961a651994702d11e2076e74aa3269e5153b47fac08a12cacf54be897d113e70faea6a748708d1f13d70da293394e4e49a263d70d9572b4d06397ea53cf0ba397a7b42dea04a78e0255be5a6e5fd7fe80e4c7c5f4d13f3b8396407fef692a759882d1eaa03ab55c2237be8c046fdfb1c648890b4670e5cfaece6e37127e7550e5c921d446853d58b6b1cb8c929489cb89722513870912708cd19a2e4ade01bf894e9bfb265ee0626a8a50b12b462d0126c03972a752911dcad830ed9c0af7f3c0f31e5f59ce11ab8ec987b29c343c8ba1a38fdb739bf47358ba932810fd020c100d2c09659ba9037d9b77fd0c0a88c1c84ec4dc163e70c6cbacba944e47676d70c4cfcfc94acc192d4b60c5cbccdf849cc92a62819d8bdec185449ddbb730c6c4a691e1273c8184d31704a2b881034ab4ac78481ddea949426ffd5b380810b1e3d8bc48e6842f805be4b822a617b810d6d3a5a43e78917ec029bd449cd1e6348ae8f0b6cc564a62fb40546a50b6943c94f0b40184016d858395c6428a1165387055eaf45555cd7d45777052697c7ee4f1983bb6f0546a89b8a14325ee8be0a5c341d4beaca2df26e546034d9d88754973aee53e0b54308b9a69b774752e03c6ccbe2e6f5e09e28f0d1ca74a6fa483a7aa0603372004fe0b3ed56d079438a41ea047e937abcba4e96f45e9ac04f2e254547caa55e6502e7d9efd746dbac93b6047e4350358f9272168b2981c9196a2f51f34a12b124dc5929a8a44c6848602c990613f61ad2373b029fafd6f92a42cc296404f63b6e124ae494497e8ac05f87b2e021a6a63d4418c0106c86090620044647b030192369d6741058fb1e151d2d6e9206022f4a74fc983b6e08fb078c48e2f53d9a6f93d6075cfe911ab3d268d5b607bc9a0c5db595079caa0afe41f6968cef809131bcdd2c7e854cea80ed986e25541c5d269303de2f8ffe18623a6d161cb039fde37a5ad0a32637e0f7b73f834a9d43fa6cc0c9f7cd394ac6b425ab01b79b7a5574a6d8e901d08011ebb4ff2131df320b269d5abf0c9a6a4177a11690210b26554822a5309142751f0bb6ededaa72c5b0711d169cdf7755f06841a8ca79057ba2927e4ac2e30a3e7de6f2fe2b916de956b063aa6962bcb4b7cab082f532939e2d5d7bcaaf82932cc1335a44ffdb8a2a028daea8b4b065e2481c0e0643c150300c86e193d305f31308001838268e4582c188a0c9c27c140005462c344e3c2c121c2222101a87832261181c08048461302818080302c140201c0c0fcb0a3d0f70ba8f5f491016d864f976f89f9f6cc6117429941c168278c0b9b07d0815e404de0c45821520e670e1e5139aceb8b6510afd64fcfb39e4ce9fbb2013ec291e18f7c24987cb2b154ec964de2daae97b54239ed0ad7351dc81fbde55ba856e92bb72ffbb4b17c79a275646910142c82f341eaa41b97b68e27ac682828f1c8ed83a29f60620933f7c98077ff8c5c23660953125fc191e84fbe020fecf5a5be93f0b2486d02df86a78cc77b6b8e483bdd94b2bd69876c18ea9c3e9b8bfba31ecae906f3034c80c7a060782f402fb1d7c662be5a09df06fa80eac0bcd3aae9906d46562c1d45d0c3f2365681b6c0181b3efa37c48116e0115b0e65eb8022fc6863fe4a0d763f8b5de50f777e8caca8096f7719c8de7cc137b751e9237f21e3cb55f4d48255409658606a28d3c6a5412880d5143821c3e4bbafbc486aec342c3dd306a78126e0943c014bfdf2fd9ffbc768945ee80761076b837d7b9864e17dc05fc42e2a17a082bb419ea09417942cfc88b78ac3db41025e402cd790bef83b7f570dd4f45ca0b35c1c20e81b9503d647a987a15f4198c099742e804a3b7063ce5b68c772b397239073d8303417a81d3ce2f0b9484a6c08f50cbb5f9557c4a2e5edb70cee08a250e1e1d374c4933347bc6402890220472ac522af9fdd060527b71f1474ca16e3143847d0023a34a28333400f989c245b4c8f72f13320909325cc1b101a820efbc43c2d5a4655adf62fdfc53d0f5b676af1c79cfd00bfe584299a141e82fa41eaa87cc1aeccf08436b9da1e03067d8273c02a7287f9a631cf4bf3f725e3cf5cfc5a076eaac93f035292c16b610ca441f2f119c84a661ab00cc102774121209354308a15dc876c2bf01dc48c5f7512f285ee09a81af08882f2eb120a570cf3f5ac4e9a94703e96d4c5ff2c32cec270550797e4294904b8893a0065426c1af2b1c83ec1fb8460349ff27e0a12b72a9f95304a5fbc2d961f4a20629415cc068e654e214fdb546c9c891cee1cca69d54c4a07118669813ce09e1de0915941c0ce00fc382eba0d3a06cb01a44014e82766a5c03693bfcd7112c0272d12f62eea86ff4ba7b6fbec6b15e309a31356a6562f1ae8badfb56acadcd8aacd5cc747f2f97081490c712fa1c5f8a39ee7d7220591a2265feb4b715eb5f0e2ab1021add3c48f29fa4b4f451ff77bb3c8e8c08701c73b9772e720a97b8b690712a86b69c3875324825807cf72b681be8888ad73b25e053ec152aa72a4f20447dd9e25f5c4f910f5f588d9d391373a491bd0f4807514725378a640fb1cd88b9917cf0329a302a1ba8b535dba013232201cf5a5b87e2974edb1eed80a2aad8f699e8aee1773c94cf5df2063acc00c022b9b900db54fb2fb96be32f8bc82d66c77e572182a8c777095db6e84879f0c1c4b91fe6443a4ad5e4722d66fce13534d8d5ca091de539a65b59985e316c2a8cae81fbcd2ab326f80100310aafd155cb3bdcb99ad4ed9a9cc445b593f849c592be9de4ad3ae91a3ce030e74ad4a5e55c39d6b5faf9597614b79322e58f91828ee657da92d9531ffd93648bbd4a812cbfe527ba142e6b4ed819d968642400a1d9e8150b031e7653e983d2209e94f8ca91f889e33ff6f624ae3989c830eeed45ef2dba9d90422194841513e6a2d06942a515724111cab1d812ff6057560d02cf3f4a90b1ec6bb134bf5bd0732520061c29e3113b1bc40f61607a7a08c1848c4aa153b27c708c8aba0d9dbc9f713e81d7ca9032d8af3396d032ac59ec61a1340280c58d192117ea89176d1b7b498168928e093ce7eba743e3ddbadb95acadfb5ed98da9af6ef7a3db279ce88a6a7e6af10cc06cdd5f2c32456c144ece54c0cc9190028d80926471a24623796b91389ed04f6c6f566d0e16ddcc8959a5fe8e509032ed539b38d83c9c803d6dd24db586f08fa8f2eafdacc79eae9d06860c42e295e0d05bae40b3e46b314daf094539bf80180c0ba573ba1835ce2964cac961a85e3c580c5feda6dbcaa94b5ef2850c357302fc11dcffec3860800fca504e407b72fd923b7cb1da25148ac503fc90d4b3b4e0464ff9ea0dcfd58dce9ee043c6f49b1ee0c1e9239c8c5a547805f3d4504601493944bcf9307907d60182d40802b9a1feb9638a14165650c081d046848e0811270465a18a423908f9115236217d0a9cde4f16ff327c68710f33dcbbd31c94af58edd4686cefffe637aefe4b6a405483c7499cc2e07035820a26473d083cee6b561c953d1a211529e8d3ebe7407ad73fd316328e48918d144de870ac3221ba37b63165834b3125ffeef762e3434340140c7273b808311b62dd835191475fcf0f3aa7c5aef663dbf6b955b3308e298e85e3acea2ec7bd46a2f949d805b6492bfc63818d05a83342614185ae81061a9a299a2851a5aa490088d80cae64deaffe05217fe3b47893f8664bb16c2835e803e8e9d1f3927aa60a5aae012d3c5751a50295019481192141219ca4ae09b6469bcb85f67ade63210000e10b4c56ad48c66aec4a5b1575b37196a23dceccd8811d41571ec328ae81eca57a7dabe1a4f635b5a10905ac8b32611af6ec7c027d574a090559633b95de2ece656234bf422f2f9621e535a6e3940b322791f5f99c4ada6ea2e1ec3e5b4e715a660a646a68faf9cdb92f5b36dd7d602bcbe6cf4390bd87626a1618c7d9751a3f40a926835c23d525905d5d5be3b9ad2c6d8d02256d755f6692f0f710c054064598e0df5d47e94192eda34b7c1603c8732d6deeed3e9efc0ffbaea61e78ecfd22a2214e25ce8150096d90ca5296849ab31629926554339c101dd6f88160be726314416170260887ee0f4834dd18684c104d2fdaaa53e351d64c034a730af7c3d3c8ba64a11d6c121aaab4919fa90994ae1d7443dc4b69dbd7daa9054592532b53c10e36207650e0630c1776d9fde6ed60a97a248e40f4a42ee555341d860e64a3d13955da00c5b9eb23d732a908474ad49d80f2b0d767f813add37042b30ce9dcf8eaac7d7f82f1100cbc123cc06206fd97e78d155decae172ae58a8f6decc3103587d4d0cdbc87722ad7f9129bb66ba0954f4649f4e224c362b9e31fa9f88538d8c39d3051d2b68475da531fc0094ebd60c52ac2e38170526fc4464d64cd387fcbd677f3ad0cf71031c179b0a5a1ca049b86bdfc1b55b8d926340e1e42c7e6d3f9c345f84ea7e75d7f9247f8e116d9099db5cb9d53ad727af78fe0347643149152c5e665b8b402a76cb87ece60107201bcccfea7e5df35d6ae7f075186a3531c667295af6ed3fad1e528325c56f5dab99cbb470d78c502bc7c43a63199b0b8c573ba3a3b6669dd25074bfd4e3e6b6241135cf710f0a496b9d9fa1f89d68504cf65da483262183aa10a9080a7f95c62ab7743b55754495ca2361141f35b27d13b898d4fe498819789574301584fff2be37d434f7dbe30ab11d8f603c4648e2a1c5e36ba86d0252a504ce2408cba2e9338bf0791b6d2c2a9af4da5d051c906d5b2f9e86cfe91abdb7ff281adf8f188dc48c15624d70f908f33d9d7e288797b41b5846f0dafa65b4bc8d81653346ebfa19f3cfec6e3c743c8306255eb6b4addecd55feb25392f55597f20db544e1dfd3260d71cb5d44563c657a365e580bf8df1f9fb3383ff4d1923012272d67427be0d275922c2da74581c7ca846600397a2e58ac1548343cb0b75d07a946ce2ca9f2cd5fcb7d3c642b1bbc4a9890a6e16093d3cc641443b7464584612baf3bc824341458ad8e02dab48a833d4b6bc32822a4c17e03ed5c4b0fc9cbb95968acadf06880ac2c6b14492faefa1769b704c89b202b27f93d3d2c675951c6f32f07d9f96718d55285f25be7973aa2adc73aa46587cd51353b1f17b3f2f5279aa86210b5a9c3b18bd4fc878020f0d2ded14f6011188453b857bff2161ba5a6c73040350dcac56f6a0611917619bd9ad03a4ab53ac8e737b327a2fcb86e38ada87f115058f64b4fcf2798fc10e690bdb636c2adcf0355b28b9b09110c19455d8aa6d7121b28d76797d2cc6ea797dab4b87c376127b7167d51d2dea67d7f288b4d10442a9a817140106ae9e3ad25041c94e40cabd467172548b8e5190b67346aaae4ab45253f2aa68cf3104d3982c2912e086d4681bc55984be9b8d2e578e69a8b2364dc8c56a038cc7d7783b5f67493afa521eaea6092d4b764854f9946100ddf67b775b42cc84245dfd1152893d2d11a3a28c42d52a72fcb1a833654a8a548d5854e725d4c09611b9f77b0356fbf4cd4aabe061134a0247667b231855219b21d394e66a3a8fc3b8d330aa1c60fab3379f1a93d3c2323c2369da8493e746af60547391ad642ca084c4cf179cadf35ea3495c2694ddb220395bfda006f6e31119c7e02d0d66cada4dade822b09ee8601c3a8d0867b09b7a3155749df05fa874d12ce557e3c9f9fb2518c31a1e86686e597e20a72b5a3931883fe62671244b3ebba5f291dbefb72fc9190ccb37016c40dcb635ceb0587a3758a6a3cd6543d5182f1982f0347fc3da6c69bde2b636f27cea1a4fe6d8cca77e0a54e961bb4a01164223862dd4181010e353d3ac76c414c3d2ba574f8a12e4d0da148bc0fbdf07f41f85b2cb699ea24c5ce5e8e9d0ec10cdcefae347e3c4f2dc7e1d36e182f5c3539a68c01c94a2d2616c626236b221ff9280f9840b299b1dbddfce77080029fccecdc0ca27826ecf4a2d2463ba44f33e3ab6069f4420ef133784a51e4c966cc107274824dd62d0caccb80b936b01dc483035a216c6c4a3c88274d5a2179f93c3c06b42c1a44249a90c60de23bc4314f3b316a0b0fa55568f668a8aecf609d501e29e9277aec0df93c809f9638c40d766a7efa69528bc9d140d52a9b453c939f6571c095113098ac0f2001c41968da1529510d14f915c25bb1a416e5de4fc818d5769f94a55746ce3b499e2199309f965543ea3a25cc87d35d8aa2e8528e878f0ab7bf9eb488947eb87551dee5515f45554a98d2edca78186a4127ff35ffe5b4650e75d940c2efa3f9da2572afac1bd884f1a87a6ca08cef4d44a065392a0264612ff45c229b3818c49a86d28f9ed3acc37400a2aa010450f186d58b103029dfc21d456be086c0f4d8aa5c8f75d79209c419c3a92dba7af37604205779f82885c043791c7ab58cfc4e5686fe831e62cc821d84a7a992d3dfd1f5528c0be028cc66a8d13b58b59a959639e428cf79b244e13b0143ca6c568e55000a3eab6220ae32552799f898ba569dafbfca371507e0799f2a873f1b8590dbfe9104d72f481b53e1264eaf7d617691560a823feb120806f0c38bd6f81d6b029e9fb0fcf1be4c6e8cb494f8ee4894ae4de48857a17a64ef09a06160b6a3cfd373f8b0564f6e364625a9f698e29c4770d7e58aca888c1d351af4496ecfb33ce83a385656ab9cfd8250d6171474f91b92a3a9f57312493ee2f895f6d2b591cb849ca9c4ddd2ea73e29dfc7a3cd7e70a9b08a601ca7f4efc11b1ee83965cfd819e3323459c45ee23bfb0914bf361928412b0956a130d3faff8a0a135eb985c1f0c2847f1a0dc1160072b506076f8c347a7381852e0083ae2989217dc6b735946d5e6bc029041e780d9d72b757e506cd4e08f5c7640c65c997ff331ca9a0585f63b76c38715f5dd4f15c82ad2e68e1e450d5ce7ac2df7d175fc65a0158dcd02dff4565d8ac24ceeaf885458782c7cdbe78407d742c099b77d4c3a3405b58223959807db53f9a3e62d9c1ecbe31fad605cfdd4778bddf4a4a8cc8eb5b4bfcd18880d8407bc56ed43367b6e37332ec8b9b293d5abd92aed8ecb341c526874dfb6d3ada44b409caa6924df96d72daa46893cfa61d9b3cec66cc096d72e42e2721e7ccc2ab7d88e336333af546f03374c357f152153c391abc353c518c94055d0fa1c072bc965cefc95e1c6471578def335f1a371d63f62217f7423ffa45e36d678c97c265598ee00701a19636308103c6bfb6bd220e5d7b71bcf61d3e83f1efc7cf9169ba9330c7a6330cfdc88404af186a05be6e90e38524a116786b4585acbd4026c64ccd092acdcad81640469df7fb0c38d690a107e1cf7a305e41fbfda779e4aa5a3cf11d3f0cf208d4a2d4676e2d123be85a9b62dfc6205ee359cc382ab5dde4ed6dc08fd39666181df734747610c207b2d71158fe8e75b64ac8de9528ef107d27ee5bdb83d88d6c328de948c0d92b9949b6c8e4b0ddd6662041da419b333240515dd66718226336a9728fb205414515bacda8e0e8888833465108b42a7da409b4faa1f4da78b611c31ea4d42fcb76736363e651c0ec1a097d47561b581ac3f580378ac39db31f9eb50cc7978e8a95c76dc702a4f83032a80f3721119e1a5c15aaac7379272073e52cc7079aa5638e3b0eb673c46c6031a58323be060cc195b388f0e45b1afc45e0df96f3ea6e2a955d97a47343e62ad193f6391301541db3ba6301b3faa16466351582d9444e695a5d178ce842a6bd6f7a92507c2f9243a3425df218082be8ec18f288384d2e073ecb93a87212bcacc7f4bd470f2ff7a4aa70597f52b4812cdb4ce79298246b2a6ac9b1114db1674b65f44012c6e204b51476eeb1879683190667d6e73a00158102033024595516da4def680cc36dda08f18113e6abf6124ca84915a7a810125d4bd0b78316ce44c95200b0f154699820411dcaf534c49b214ba6a218b991be40ab3b5e383db51972fa382deb818902d46f16ccaa034dbd26601fc97e33b5b536570db41eb00dea66509be6dbf65fddccb36194bf20b4cc371e0a080969f0fd65060bf0e64ffa3928e36ef5fd246cbce35539384836efd3d5ca23c473ebcdae16a36878f3cb06abe378975d565e0390c76bb50065d890dbd386d07a044f6354f9272812b4eca08bd9365b47b1be49de0e3b3886f16cf314641ffc15fc508f46efa923a094f3a8bc375bef412450298879b4d748677208e45769e5c8992e75a1f5642b2aad4d544bf02a72efd5d55e7ddd022f8b0909962a9b16600607cb0edfdbaa4b005b6a2468d51549d2cc3ae5764747baf8fa223eefb5e73fb886bb6b4137f7368b34a78fd16ac34eea55d574c339c0b9b48e37acb522f50dd37859a2573afffdd9664864ad496e8bdba7da1b36bfc3b626c5d212210360872760727ef30da783335fe8b1737c41017bb00ee45401ca59b5cc4eb9e92153326314b4469b3556eab840fd0c21e8ed94afc1585c2b84d973d007ac707ccfa198b0e02a4f1858a10a54a08fe0c67c9d61c280cb6a0b72649f15b6ba258e1b2ca093042dea9c5f46394541633b2ec86a17014d230bc6ecd105b753cbb8cbee3c07b59bb7c800fc0ebaa46f9dc0335ab5c13546de116806b87a2bddac8e24c609c0b6f5f9304197a0db82d6a3a4eb675212685b89d1a64972b656dc9c6b691f30713708628147ecddefc1a18aa860a8adae579c01463f9a362976d069aba9ef7580866639c7481b9ca9933445abfcdc445678839157645b6f9949b0dbedf07447f3b78b9352915dcbdf74ad882ef2c6054bf4d017e90383a1817fe7c9c5bbeb3c7a1976b22874570436d64332500b67a511d6308ccf9f1230493dfd1cd4cd03d3a6cc3ac93e14145b7e368d87ad4fa8b21436071b910215b571658a16647bc7b64e2758ac084821ed9f00122b45dcf4bac0039020299be99987d90443e68be7def628975479732951dcc4ad6b315e19519b3f7eeb329adb56f0af64168e669a8d7ffbf51d49a5e20c3a1abd676e73ea6c0ea9ac04f7cbe3efbc8007f219f69d05deb114d617d0ad815833ba716b12c16467222189bd1102ff13ffc759ead670b5b18868dbdac8a85750fde785e1a23def49794d5621f06f9826b78c9de596cacbffa02fc41a3e0797a160bcac175a710e61ef9e5fa8e3df44590bb2951fe048140cc9afc38a1db64005f3c8bf8006694eb8abaaea883a72ec2b002eb82d5d394c87e29754bd29403913b45c39169d5817400a1f924614cf8573904e5185fb575d2f4ced6d452fb7e8d5086676cb48efac17063a740666f0a2993ae9a816535792355a989eeb3265a1c62dc22de1a4a7648672edff76dac6724b005471ab3f62cb282f46b975eb4097ec61a16b15491a77c17fbd01163f5f219c1df6b953e4ea807edfb3813c1fb4ce69caaebd4693e26089392e6ba5b6ce4c8173220bdb8762ca36d53170f2f1ebc4cea5e71a82a1ae95f4ad34e81d1b01d1484fc24f4e9df436d0c73a204297ec1f716922e77e7d8769c61e94cf51c2ec5da082290d98c83304fb0060bbf7b33abc96cab0ab3117b1bf6b125671e7bf5a6bdcc532752be94c66d0c0090750151f90bdeb24ee63c26f540fe6020cdfc12fe2f9eae2af22a68d70b15ebdc4fe626a6a0de792d8a375e826f45a848181888b855b1b73b213ee52e0843550179e1c0a68c6b44b0ff3c07f309406e75fbe33d904d2c3c940c24281a6a46aced01dff8ff905128a46165688380e0c2d209a4a109b1bda1614a5fe380d4101eaa14780a43602c14358b6567ad16b58007a1a23d433124b0d888c6ca6fb8fb083f403010f3911c06a034c033b82162f797a4f99b7ea3b6a41c00053b4df0b803d0d99132ca704882dd4d20ee014e0de7e708f83e974657f0f6da0f8c8adc6455792fd900e69ecb115f9185c626d200a45851c6ee269deef68858dc0f5309ca795fd5806d6aa533e1d03383b27e1d6b300040f2be852349237d1ac4fe182cd00eb1a5c73155c35ee949e4846f8d95a89c7d556d082427b686b4fa1e5ee01da1a961ea52b7588836b10e6101145db80d327d0584393592bff00c37d0c7b0f6cd9805d1ce70bbdaaaf68c1753477dc7a175ae0a0254471ea334755e8f07104d2733614802d63b2772c7727e22a3d2e369b53f5a8eaff865a68f90844a65f474e0ffed6b9848286a93331f8b57a515b1aac94f4b1c4b75e99a7c5140efdfb2e82d2a4a08adc40b01779ccdedda1a5fe6a4727829a79a5d082742a0771ec88b82813559635d0e758ffe82c80991473f724bc61ab29665c8480e53e4d4bb24ec1da62984b4b7799a3c10a2c9bab4d2be89bd0b971d8af469aacd0673280eab61fef85d8119337f68795f02571822c5606e764a197534e24140636ee8299a2c66b4bc1f019f9aef0a91619cf8258f972182f4f0032c9dbf71834c41905879c655c06dbdc0b4f166f62b38f711c86952943947da12603096f5c51573db48947358515143519087ba37c1c07d6be56312e29414379b8c4e1882f82fc2da19e509e400167febf68daf17409795f045f1b7aa9a09a5c25f7f21e0074921f1fd0d0f7a35dcb91a0e1640aac10c004c131175f4e93fe877897378ee476b417b1d9a682edb8b454f803d681e7df350bf4bd9e082b48ad60e02a032df1586a11a4b4916e19803ac6a0e9b2f2ec24a1e0010f0b3e12d8cc7a97ac360c586bfda0b4487e1ac1f08601acffbc4f291016d0f510368a51eba8b8574ec2184e4eec92c311c486bc1188fce8027434708a46c2c3f21e23c47e5d5a49e9c20448ffe258c98258ca7895d89905580a01ab089161b1942121c3d2d154492e6500c30032b7f1f0734b2f007f97e089e18f657d045c830b8c63b159a62c0e2360a3081bf0668c8ad6004dd9ace0c15601571b14e954c64e65133f07cc87497d7548b2f2f0e484e2e7f795cd067c464686548668f8d81723b8427d8cf85d74ade7e3a1a36cc6d140f73cfba4fa88c2c7df0548762eca7ec398889d69e9440bfd278419e7bf81350c4ccf000f2e83a5e069e2839a6fae4f8faf1f1f24be217e5438456928a1835a9f5d02df7973421512e1c3a6f7712b583ebaf2c02764d7faab2971645037b17731bb2f3d408e4cbe348a730714c7942f01ea9e8187ac4b320e20c24199ed9b549900952562fbd7434579645c1788b96ee5ed4be32339a3135f52b209c90ec0fff9e1e26a908642c74a17b79081190970517153859d2029c148c457c04fe99d3dd1bac1961faf4316f2f30c221a26846cd1b0486802e63df3143f6144555c09349abe3b8521638cc37993c48555ea5f60de1f857bc366d711f17f6890ca5a22fd6ac4f332cbb5ff5ca6a9c1e77c98c06741a34499f44d8c6ae074715a0909283a28637c1f24f5e7381a1293fa8e753d36ed198e9ea70023c3cb8be0e7f7046382b1d38d61b4bbade954f907d3c420066a9cc37c5906bc702693d6f7e9d0666e00cf7d66aaa58d5097c1b63b20e192e11214076b048b7b23c765f3b379a00b0471a5a260aab879057cd630cf0acdaac222a53a9866da61c97841ea67050addf463d95efb1b46b06a21c717624864a23aa2c512c1087530c60549623a53df694afa694df24e9ad93fb6a2b5637a187d9bea30ea90cc0a245215d26bf8cce53497bd00441e1970918924562eaf68b547b0ab63d760205927ba5451acd96d80c51edfc163247c3f0d7fe939c793bcc06601dfa1ddb2274448c3a6279076df8b779753685122d2794a99a2598b14bf2c65b7a1645aaa157a8d002eb3304a59e0412cf8d3f8a08c283ffd9ed82409897e26f5c4828772659ab347e22d7e921a3237b51b16ea134909f332474f7cbb3658a9f57bd4f5e45812aa9767b7683102993db0616192740fab0809566d6fbeec361733b792e475d96b7b26bd2553d603da20f78400fcdb5965fd0505473174ef239cf39407c7fabae2f6662ac2e3ed5f07184584dd223bc8fe908a4ef10182ed367f32da45153e78851d45175cd954598b5263540bc9bc4dd2c14ff169b1d5aab148f0d0777c1c321776f0d5dea17437a111371e9e61bad0aac889c7a93f09693fb519c96b452a7e486fe9184ea4e906a35619ac5fa45ec82e07870f7090cc049ecc624f37516cd9107920635d45641b65b45b4a1ef581807774a49f31104e6971d4c71413156b29b14f39d5fac2180d2e6de38004296f63410232d95ca1c11dc9f5b546423f6e9dd8c6e4bb659b254bcc2482ad9328d1c44384237390af69c2b65413d703c9c9e78d588adc82415b55933a0d42d1dc4e4232039f2d369bb16ab214b2869ef1ff231d7f26ce8456fde1e559af494db7d3df30e3beeca0eee54c180e6c9397894c6afe93330ba25821e23aa9edb29aa939cf10eca3754da50d4c6038edb04adbc05d7638680318f5183cbed609baaf7e3c5bed654fb335ecfd76482a56b98005c10206fd665ab4407a525087a29b3d42e122a45c9e3f743ba6ceedc466a3e86305a39808ca56c04cae69a7a205ee907b72092d4fd889c33e105ed56e485e14bea958ba6f6cecc7cee673cbc84bccddc662c2bdd334752d9d5b1f0ecd19f8e3a01e69f44a27a7ea05e16ca234905d243840303498212a83f9615a984abb1309bc07eb64ca98943818b9de52ecdba481e46d4b64f61d471af7e0c7b0e054be389a8b1b7635c284000085d81684e831b977f0a18532dec98d1883d7561293bb43949408d057815d420fa1462d3b16f417dbd0d94474016c3187d406a14dd9cf2700f21ce0c4dc7d44e8ba2d66c911484b059e29392c845c795f5e319ae10bd6fe2815d6f15787f08118fd6047ce993441f85648e3e44fb802848429e33eb08096d46aaab8807f48ef8e3f79d602445b4c5816b9942fd7075b7336709e2232cda8415e9e224dd891441bf4849f9678362744983b0e2348669bda4206986721d6649afb7817dcc1f6a50f7a411a2241984425887dcc03b83ae5f7ee320f4844dbab088553f4058b2771226037ce7faf4073f0f6800ef4a8d69f73256cb707b152bba4e470d57ce9c142d9f288fecb1e41418f2ddcd5e9e5e4d3bab4a23833d5086bcb4d97e6b549e465cf603643e3a523b48e83b7ea2f3a2d1fa015f2779fe271c6e7efd34ff100048dd842571ab924add6256e142d5ff9f192349151ad215129946e8ac62263165f27cb58d0fce9771b92fac71305d48e56a627c91dd530e6dd2d8dcd4c2a8ce0ffdb1038e75d33e7cfaf85ee3fe31e21ccd5789d53c9c9c8ac0e58456e81ef08203088b04656a2f6c1772158a21602fb5ea06f5b9a85e3d033d9e616343ce928487d5fbb87aacebc0323bcac3b41faadb610aec92a3777686a4f7e9b72d358e7c388055975afdf31f59935d8f17d9019d41cd52a4da3755bcd07dee3829ad370808726e96a7689b34f59f2b93b0331bb068990770b5b7a74abcf79241788ae04de0a3b1225763ceb094535841f5e22a9f26efe845601e7f0fedf8c0fc8c4dcaba9c98a06b8369132df4254de30e5e641ba45ea43acf7c410001e92a8dd1017c4ce3bc09fc4f7ac11769b14e0a86626c7106ec6c498ea7bf3e975eb3d090bea00ea65dd7c91808b0af15221fe364a398b81bc02c4fa6c5976088717eb70603163870be2e2010359a1b18472194128c47782a80255c8b1eb3486a8122aa1a2c80a870b1d24842ed7367245a1177a0a670dc2e9195354056fce67b608ac6dcd930e007c873bd9a3b950b9cb0b634b7fd8ebf2027fbb1e8eece5b82580edc5fe1fb5be43fad4d1c4c235f6b8376124423c2b2ada5cbc80b0a23a3f571d6e9f1dc132c3a6f0c5bf03c5be074ca18c266c9ebcc9da170bbcdbeab38ae09d061c7060f1886d5c6fd292ab2ff6b0724683b17211393e8832ba08d6544a4094ddabffd05cae4206813246f5c6c20d134680dd3a46285810fde053033d8eec23708a709b17218338e15af105d5dc938c2d4c52bcdd903815630bd56ab09e79a1c0b437343d4dab09e282a56f8ca297a8fb409e3eb22c561ca4b9a30e5aa490f90811c5b2718c290d9b4f040df8a3d01e70d4d8a0581103cb713db0d670efbe41ae8dacb2408d2d1987938651a2c2e850f523a642df26a789abe881ae21d07fb17059c355cb0a945840866309e783c5b7590829ebb1363f7d38d0cee8f05c27e102e268d47c7b52f737e0a8f942846c1f1abc1a9ef4a099dc2893f1ca01a0458735765c8c3f08970e59a4a33c3f41b870d23d9d772956e00aac8276152022d503d578927b9a4d0618425d3de94bb6ff87601e68630b21ac07eef95c708b0ce07d90a80dfca2ddf3c7213140cc1568a30596d1bb093fc64f85ee6e68ea7292d435e11ee041e13407c11015a6a07386ff668ef2bc26a7af9467f672845016982dbf37d55f368487ec60853ae288ec3037bbde789fd0102a4b25d120210fee66d60370fa2c5cb6b03832094ca8b7c5db58695a0f55a0e8b80dd9cf61ad05abe543af922d094e8f9bbace9a66b18e8185a2717ba8f94cb303dced1e55cd0ce2740a822a44a71fb5625ed980872cd5af1f126f16f7dee4d591b142ecfc77ee26d8f89b7aa5eb9794dc1b98c7e3e473a04ca094ddc8f92abf9147b9dfc9939a32441ddb816c551eff16163beb5ac283990d0eaede71a5b27803c4e21a3fa87c633242ec80af7d21883296180f29751338d08a21072cf812ad73e699ec72b1f5d7e2c62d44ebd65a7540a0da1c514da27e5ac6d3cf13ff5499c161d86876f49659e7c90043b2324730db637430337939a52f5fc28fa2b870066e3b1053fcc6b80dea7b5a179233b810443514a2bf0b5eeb1f533ce1c9c3397cee5b0f5a3cde27d6db953bdf87a7c99d10d165ebe381fe6829f61f2c60890eb7956218a0d0d6922033f802638d5076bb9489a376b6aa8ac67f25c4280922dcad9819583756eb7714b40b86bb8adfc21bc4268a4f8a1cdf12708080b7b98456eea30a55a6ff8bc5097b9e586382c47db412e438de5bfad90266ee2639c3dc2bedb3a94f9a84dc0b8859014486015382105ae040fc2514ec7802fe4044df0a3760b46439330f0f0f0f0f0f0f0f6f706ba4b6d6368024a49424a9adf153f8ee9029a594648a8433d417ce4cdc86362184d1863fda080d02010bf40ac50ac9f499f2b5ab325cc1873eb19c2fda07c868051b529a92123cf3a59820b00219ac6064bd6b472a993a476d6ce001362820011b5bd880c0183256c1a43e4f3166e855c1c61acb9f53da53c19f680d31c8fc7ef9265430f92ce750ff21afa77b0a268e8a96c73bd8b6ada6e07a77f46be99c25eb2d059362481a6aea99de1e29b8ed9027e4cadd28f8205a9265d09e29658b28f88faf7fb6d9d3a67c2818d3f8666a440c146ceee8b952b0de0b1df904bf25748af61bd2a8c83dc1260b59c53f923e25f24ef0f9647a8db69fa4fecd093ed8a866ad64294a3a6d825162c9dfe228799a9334c197902c5a24277bf55226b88a215a44537f25e208136ce4d0f71f73e275e55c82495a21e85e907973722cc1badec678997542094d25d81d913975ca5ea276a504b739a9c99e96d6f58293e034b7492b957eefc59304a373d25ff59e48f06d25421242de9f881448705192529f839074df23189521287d9e2a6d8a992378492a85a44935b6ed8d606c5c536806d5604284119c34d3bd2d79a47fde8be0840a26b2e45c5322a22a824f1354aede4ba52e272611ec560a22654919e97b47049b738a0abefb15aed14370c13268bbff6032a225c3109c14d1993d665536e11582cfcb9f9d2ea7641082dd2cfa73cca064705707c155f610e99a5434b5a80c41302a7b6be39f84a4ab77b1c3e8588055faa2053bee003202c1081193fbf9aa3db72203106cfa9317539ac4913193f107ee4a4726c30f4c12eb517a55374ef4f481534ae8535dcf49883ac4088380a12351061fbe14f5141a5e3a4765ece1f275d3b496255af0764d20430f2729fa2495b6cf6a870e301cf0001c376e84c1011d1798808dcb01cc41461e4e061e4c9b335a1aef0e8c48cbaf1284251d499b63c781c0160c68c08d1ba87164f941861d72edba183a090bfabd066edcd8a1038c3176dcb8b163c78d1b3a5c0c2efc04376e7419c3860d6263d84036c6172d6807e0d0e16274c18518a70b07dcb8f1858b21c6e9e24b11400c32eac06fd22554acab15931ecf72d482430162635879e15e14d70146ea800c3a3041dae44f8d7539863e073ed6c64b6152f3c80fc981f59c444c1b458e4c37f9e313e8a28b311c1007d6439d44cf312c37e370e0369ed2759d296508a63770c2bf4f3cb6ae471cc97003b7f77f9db263ee48a78c36b0c17c63f9a70f2d1dae2081a12090c1067662b59f8c41d449f30332d6c026e9d95c443019fd35db21430d69cdc135a5e995430b87abe0ec28c5011969606c4dfb6e64730c32d0c05d4a2633a325b520e30c8c9af2717dcde61b649881cb9644fd5f1acbc0c9143f5bfecccb5d2237c820039beede4698f24befa731f039a434e919ba83369535c81003e3be9e3f8fba06adc130f07d26ec5e82fbc43791db820c30f0d69fb55792f294542c878c2ff0232baff6f208870c2f30c1d4b485f4503131c8e802bb49a8532143e9a867c220830b5cf4283107a53c684b627761811b374c05376ee028db838c2df0d9f71b3d564add6b818f29f7c40a53da3cd959e0e249cd8c604158d0278b50be279e2bb0fa95449f2e09c9feb50297525636f7f414f42a70f1541236ba1a29c5a9c0aea9905e9ffadd53700a8cf29ca2c4b558c890023f4a5f27939f4d57d089b1838b09686087efe080b9848c28705e22483b9d37275a1e0aac5b9ff6e54cda4dc99fc0e62611c72d74c6de9dc087bc632da2e926b0aa96eb25242526302a3285ab9bcee8c9b40446869434428852c93fa4045652c81bed6d97174349e02b67b4b43e993de206097cbc48e3e621e608fc85749aa2c734b333023978deb6089c58a848a9b359f24e128111a6eec992a8f5dcfd10f820737da759c960260aa1282a276da7c552818c2070f6616363397dcc07029b2b22ed86d2b92ffb03c6f622e5ec5bdd26293ee0c23f72fc1b0f41a67bc0e7f8554a1649a23b3ce04df379695bab8f15db01373af39bdde4a4a242142043074b126f2d99262707bcfb6637355183034e729217e468ac0e326ec06b72b7aab497954d9561032ea5bc9a9625dd0695caa841b6412b92d438914103aec7473b0b4e7eedc8d49bf290052bde954f23668dec522c18bffc94549f62400a1eb0e0a44790f69af335ad690b1bc40236b6b0412a60630b1b840236b6b0412660630b1b4402362e30011b71f078059354c8316b4816cb84af06011eae60bcb5caf2ae294f9e6d05a739ad24d3525975b783218616f560c517e25b5269d15d8f55f02571729694d23278a8825dcf6717d306a5673b20031db871a30b47810e1d607c9123edb871e375a800061ea9e082ce6f2a29e615edcc0e555470ff1949b54474d4a46a233c4ec1abee6866f28e872918ebd4fbf020ed8292799482bf0a0dba5ba204bdfc48c1c90e161a3125798c82cfd5a33e652d3d9aa31ea2e0f562a5fa1c52a964268f507032db574590b955bdf40005a78334117358baefec797c820d795355ec8b1e4ac9c313ec8590d247f1d31325280f101e9d605490da994da8bcb93225ede0c109369552d1941d3d356463f0d804bb492413dbfc1f3bed9a6025d9e59dd8a273867960f0c804eb6bc18205d1a14665c5e081095427a9f157c97e31868e9580c725f88c3e22c326059d7181c723e47d06cb4be5183a2af15bd8bd9f679b128c8d92b9baae3777d4bf1843076ac063127c0e91458a5bbfee3872ec18230cc22848470c0d6c2567815f053c24c1061f69226ccd4830ae39a4a037dc8404a3e2263565ccce27fcfd82c7231889c1435bef7604b71f6a6b6ff75386c9a3119c4efdaefba57a30820beeda9b97443ce0b108268888a87f168c828722d8a4f4c42da12af7c41c143c12c17d9b56e9b859a445cb0311ac046d77cfdf158eca83c721b890f2cba2ffb628bffa0d1e86e0a4d999f87757082e87c6ce924e242f21941e8460d5d3a59844dac9fb111b049ba2c6cf79d46c33d382e094509bc54ac4f2897904824f4127a154f4e7c8db01c1d7a63a9d628e1172c5a6e0f1072e0909aef9727f52e843e0e107ae3704d11b5f1bf5ad471fd8a0db69d48be9b4343df8c04b0ed3bccb252478ec81cd173be8d254e5d0c2d17d881d142430bab00b00103cf4c0468e6629b45f27ab5efce09107fe93c633bb94c9e2c8f0c0597253bfd1be6c7d2167048f3bf0716d2d2d640e4916ca2d78d881cf509d2ce5300d95d781d321655656cb972548b4e04107ce7474bd749df4e50dcd811f75dde65532d6b8eb21073eaf280bb2627c8fe92e81471cb8bc9e665f59d4697239e001073ebf9a8e1435291e6fe06356341942f28d091e6ee05bbd72fe0db24c9989a305270c331978b481cb394951cfbfb1aa325f78183bc6d871e5c10626c9ec5e4a94aa1ceabec0630d8ca757f430b563297335f03149fb8e96df64d27f0b113cd2c0f765fecffb3d61d2c62c78a081c9299a9e2382d23a4967606db227a146d89ec528163cccc0b82921e26e2c9f1cdb32b0c92f467190819139e93791e4e7381a2a24f018039b338410d67b31256d1bf01003fbaa498a5d503a3b84b6048f3070a66c930c1d47b55f0a0cc7943456d25d2bc1e30b6cdde8cde9b1cb74ee385aa0430cbd828717380f6a7dbfcad3877ebbc085d7a9884c4a7bd0e102a3694925e854b7c0f9980e52e2297f53d10a1e5ac0721e0d2ae446aae091053e6fa8648d1d1ad444565df0c08297aa479859fc0abc84a851cb46895edb0a7c90dfde2e32fea9a90adc066d7df24ab8fa54e03e43f57966bacb4e81f7493172aacc4ba18ba5722995321f055e3325896aa5172bf350e04db3f376d929a1db7f02a73a7947c545855cdf09ac5eea076dcda263f49bc004cf5144aaccd39f3e133855f12c4b0aa1f2cc5f0223dcf472c9cddf48be12b8142237affe78d6f093c0968e65bdc89b62d23d1238b9e329c935f99ef547603f256bf650933ea57e47a5c949d34a70e71d84ca9643095633b86bc8ec24f88c9a63e79f940497512d491db7d4798491e083ccd9d245de8ed53e0d4864aade848aa351748f821d670336091a8f60848c5b413c54e7c71dc195345de7666a04bbaee7495e75868a0a23f8d0ab20624417c1e7a9ba20661d73f614c1e54d0db6b9f636b49208b6d2e9688f31b6f588d84c6434134a7608c6538a489fc97208779b8b2d0c0d43f0d9b549ff540aca275508464e4a8e11062118cf214cc5d1bdafef0f824fbdfb510b7241b01e96dd3546dc1f650a04772a846c49f99eb6090204ebc14699aa49273de9fc81f3bd1391ef3c7ee07774e3d5fb875cbbe9032f31644a9bc6bccc357ce0fd5753cb93660f5cec8951ebdf54e8bb7ae0aba2a8542a836ef6681e8cdc12cfd7e28907ce92103d31787ee91eefc0c6ad1c4c5abed8818b39cc3e3de705cfd78157cf9f8489c6b4392b3af04175ca7819a4258d990397530a49454c264a47090b68c8819598c13e84150736554a4ab27a8d5b88c3814daf9cfbe1f71bb84b4ae78edcddc089decda0cbbaf74edd0636a6ca2fbe9577da64d8c075ea5222d89fda5e740dacc8f6d49b37a806de7f84083958c839669706ae2496d03946fe247434f09b4262d299fb5eac7206ae84f6cf6f1e4a249399810f22e554d9eb32b06e19926d940e19f8902c54ee8da977947a0cac78796bce9253a5b41818bb3ae175a623e78ce068810e31c2c0ae47fbcd29497eb01218b8cd67a9fd93f70556f32af57684c5909917d83ae59d25a9c9415845031a5d602ba5a6cf6a4ae988991d6870818f9c45e8df36dd10475e70b181a5b105ce6dd369519a94e8a4a3052ee5e7fdd5dc1d92a259603746caa0eea7e244110b9c5b6acfea96bf026312526aaa7117216334acc048099ef267a5142f48a30a5ca5bfdbafbdf5b594a5025fb16c83690795ad73f431ba382ac017d098c2e291228aa8a454d19002b71f4443d787a8161b1b78c016c50b34a2c0a9260bd1b41e9e46690c1b1798800d30d08002175fad339b526a39b883c613381135bff42e7a8aa71750aa8481861358df4f0bdaf55354d57194c181461318b5cde7fe1a732c956101183ac240030d2670da83c48c6e4a62eab30c3496c029ef13eaa9367b4990d15002a7dff25f3bd2e4895d0e2d1c6178914a79b145175f58804612b8d4eb4a492b8a042e289534ea0633a55febe31928a510a071043676964ef622358268530a348cc0adc44b7a22e6b459544da051044e5409cf215b9e38a944042ec35a74d774567c1110680c81afca49bf52c4abcc7aa9020d217039ba74090b324fe62a08ec290926c1454408518106109890e495e89646aaa0fe80afd69c534b8714ffb328d0f001574aa594f4ea95e9b422a0d103ae57af92a6d2ec3b960cd0e001db63a3b761c98249d61c81c60e78136197ee62e80fa937020d1d70e2ff3175ac0b3adf99432b0c2ec45893018d1c70390691d73dd3f512061762e0d811061762744103078cf63bcdba1464a040e3068c77648d314516c976db804f4b216b9b29dfb7c91368d480dfb6d23ebf4d3d7dd1a0011fa459fc6c153263169cdd9bb6dadf376139b2e0a4de8e48f2cf34cc8805ffaa9236d7f2657fdb033360c1495131534fa65598f18a728b4dcad2d9aec00c57b063dfa52b2c58cc21cb21cc68059be49769d0bfe725439615ac66b4ccd851447432550366ac824f5971efb23e6dda76862ab8a483074bd974275d71093352c1be86fa4dffb9fd928f0a46435747e750b9b5834ec16d52da1d4d57bcccd514769e1434799fc508334ac189ec7699b71bc2724a0ade54667c932034e576678c82db6891fed385cc1005a73972758a9332a599a8302314dcc8bc4d2a5eefa5e08282179dd926a9ef6b62ceccf80497530eb641095d5a3ff7049784befc38d2e4a77d3ac15f5bf747b335c78e0381d3199ce0b46565fe379dbced83a3ca143163137c648dfc9eb7ffda6a08d8d8c2c603b6b0c136b6b0d1802d34c1675226f72f7dbe3023135cda10845ee650113bba0516666082b56c11746307675c820b41648af9f653841cb28019966062daaeafa0aeda2cb4b1c5186654824f7192501339c434da86125ccaf190439b9981044617ae6312dc067da6a794d6955f39b4ba0b303e083324c196de0d495e3a1b21ea48b0935da2e64c419060b2281d31974ee2a6848f6025fe577a9852e121770413728aa5f8e9d35a4b663482d31bd916538f8e3083117c74cdd74e593daa25bdf02202691b8043cc58045bd1ef2aa9529e79438ae03557f2aec816edb42711fc5a0ed9d6e2410463216ed01f2166d6c839041f84c4cc546117ed5a43703e7a3a53e45821b8d0e3993cab4fd54d08ae8450bde412f39f84e81003479587d1820d2462c62098a4b1d2d5f34316e90b82abd49bd9ed8329b33b10dcdf6e0ebab29724150182fd78edede611f278f40f8c69ab3f75b671d32a40c1e62366f881f5ebeb11d2ea2c5abe0ffc55c7cafece5515743eb0669182f0f4901df2b3072ee5a818214e1296ffd3039b4c3f72929a5ef3a57268a9000538fe781738ae3a2001731580e185eb08402066e481d39a1154d2a022a6d5f1c05d06559363d21a9edf81ffdb20313ceae474db0e7c2cf1d7b2cb1dbda375e03705b5187445f5e9920e6cbabe9873fbd69412e7c0279945e65dcf4cc927a6fd8b15580000aa98210776426e491294478ec98f0327b2e385507582039bd386beab3db7d1ef1b1855c942afc8f7b6f204ed08c60c37f0b59752c5bcb95deb6f0393763d5f48b55945c6b0819359b2fea8fd2079b26b60b744e8babaae8d9b570372848c41e8e86f1a1899befdf2539e986488063ef6e556aefc9693b2cfc08714da64c87631490d320397829222476b4f2caa6560944ad31084480c79f46460cdabb35e8292a5427e0c6cfb65a618835c0c8c25193a657dc8b1b31e0636a7dad0621a4212afc1c09eeddda8d2a72ff079eaa3a36e4a2add78814d7709a61642aebaa60bbc78784efda6e102a37394741fbf32627e0b6c0c4942c98c76fad1d50223536df69f8e27c966814fea937ecd251618cd88a9be976f17b91c5a27f8828b1d3ac648ae03479da0991414665c81314f2999e5106b7df3de0596cfb002a736a7ca88a12be860e238c1175ca0209d40877b5186821955e0728e223d847ecf2552ba382ec60e1c28e8620c946563030f6080316f30beb89f41056e83dc8865a332ef1de98b8303477f7170b0808baff2850e0bfcf109883106056edcd0e128d071bc281670f10503c0831953e04678091169d3bfa2648614b8b4416dc40b966d6b93436bfbc60d0e9828b0af395993ccd2983a0a057e948aa62a3fbf3c98f1044e099154b9b27437955608339cc0bbea086d79a46e507130a3095c08491e6b27fead884ce0a3ed77e7cededb9212011da7033798b1042645ae98aa4c6707515202e79f747d103a1dcc48023b69b494bedc9954f410099c52724379d01dcaab37338ec086c474ee1743974660527a8a418847af084c5caffe4a3146df9815e30b2e3870e346210263fd357a3b9dffc5b0cc60c61038916b4cc4d19f35e9940b6608818b7d2e4a853ecf82c0a6aafa87851ac78e436ac7026a3003086c28c949691fd359321983193fe03e65f41cfc7447440f0b66f880519372fabc37cd49e66c1166f4804fca247aba8a179ec61d3ce0c7bba36fe48ad88e2f8e0e318a0161c60e184f6a21aaae9f04e1660e66984eaa246da9949e03be72c774e1a9ce269970c097dd56ff58325def8a0d66dc80112965b1a0aeed554b1b705a7931e36a8ec9d3ad01e76a75f913626d0ce50c1ab09ade5a33a485560b0319b3b0c3b36f5398c9dac5f8e2a4d3012bb2d08245b5bb78569b2423167cde18740e1a3b5870a79dbf6486e0173b5d84e185eb0b64bc828fb12f0184e025c5531a565223bac6c60626604307c1ba9f106db59932725210e64caa83d0fb2924ff77081f81e053df5396a067396777820f40f0f9bde6e33105b533b1e1e30f9c773495f75250093efcc0c7902fa5595bd9c79429193efac0a7d7575aabe8aea0c307c6fddc4a3d85e41e58d3b4906741add6d71f7ae0cc3a06f724624a4247ff9107c6266ba747dcc9a22d1f78604c44fecf154d738595430b8cff820ba2838f3b70aaeee65e5ffa473d36b610400e3eecf0f9a638d16dc4b31c5a2b383a70b8bfd58193c147a452f1e4093dd1814d2e6abb746ce7c0244d49f7a27b7268e506bc0b14e8700a9c073ee4c0a8512f21670b922cf42ffc04a6031f71e084ce6bff4da1b36f0a072e2328ab0a96477aec38f0f1066efbdbdb424e11512c6ee0bddb46787814d16fdcb831838f36f0e6c9d2fac95117526e470e1d384e7050290a6480021420a6c30b2f8a083ed8c0e68a14a93dfff4d28f3570b5d9be59faa5e5fb871ab8d6f02c916b64d221fa9106bef7bf9392b42f42d51f6860474566919474d37bf6e30cbc89a6cc6a29a6f4261f666063652d4d32bd9652df4719d8a4845f977a503a499e434b4df041065efbcc1c03dfab66427e4e36494d7268a1e08ba303c78718d84b217ed9b985d8df8ae1230c6c6b2e4fc1c3b4cfd361f80003b7a75f728ed61633828f2f90f369ce21626e8ba60221c0d11f5ee02bac56c453e66f497268e1c8808d2dc84717b8d2bd110b1d65ee1d2e702a9ab698d47e47af6c0c1f5be0a2a5b8a9152adfb82106185decd80f2df07ea3465e8be6230b6ca51c44b4ba5ae4a4fdc0022337d3b78eaedaef908f2bf0315f658ba57b52d2b815f809b2cb3dfbf85105c63ce43abbbdd2967e50810b5a2c988f58f89e3ea6c075468f9e3a434a7c488193626a9d7a2df2c75013cf131f51f880427e31eea952761727c761e0e309fcf9dba64ebaf7e39999171f4e602d87aadcdf4a11d9a2253e9ac0240b21656b089120a41f4ce04784452dd31c423c1502bb858f3bc894d2561c9d600ce48de304607461f0001f4ae0aea35958974aba52b4c24712dc16d3bb112a6e60023992188701376e4ce103094cd011a39a7dae12253f026b2e4994c80db5592123f09573cab896828e6b8ac0a9acf02836e61584ba880f22f06d2a78d6d05be1ba6b213e86c08798be1f2a3c4d16c78381c330c013172ad0e11a2895237d7174a0cc0d7c08c13d7d6abef7dba1a4021d636c91868f20703ab3b957a94060af445bd03b293d7d82838f1f305a216d52952e59d5ee0336a88a646eb71d64090350838f1ef0f93de7dcc9d6d5d7c4032604f53cff705bf1b1032e8390a20e387d4164c93622fb8765630b1b5bd8e8557ce4809718ed3bb73c53c50f1c70c2f4a4511d947e52495ff8b8019354445f93b89fab83884de0c306ac4d7a2d21847077cd7ed480fd125943ca8bf9e18306dce8186a84ccd8c13212851ab3e0a2272931c82c416551d240b1430d59702986d6abfcf70c41e9c51874a8110b4e459219a9d75cf72758a8010b6e75344c52a6e41eabc62b38e1f527b45e7ccb9e0b430d5770414da9c896bf2b06b7157c6f1659fa9e55f28face0e257084144ea5bf09c55b03569432c846de88b2ab8eca0294216eba81b4a051b64c648769a6dfc34d77109811aa8e0f5b44e8ac1cff2f9478c8370eca9710a7645c6cd8ba233342e7c8c1494aa610a3e7752dee57c8b399dc610354ac1e6502a8927350bcac73cd42005df159a6388aea87aba35d41805efaeea2198f47cf92d68a8210a26ed56a5e5e46d691dd60805e3aaa6f9d53e3540c166f178d27cdcdda2c62798bce973507ad74ba9c7136c9e7cd283dcd4e804e71233aa44bfd0a12ca8c109fe6d3c27fdfb20121cc46a6c828de6f76d3aed4454870b1d61580d4db07dffb9419b094e78d69ea9742931b939b42a063530c17a301df3c70fea4daf4bb021d8764848a633420d4b70aaae9e63142537422cb750a312bca8f98ba81af364419460ac430ea62fae5aa831092ea4cb9433955fccadd790047b4ae8f04832640bc2ab1109c673ed8b9ca06cd4cf1c5acb831a90e0afbb228f0e41dd9258e311bcd9b8aa988b0993780d47f0d94386beccd22c4ad70836dc4f07651d32a10623b8fc20ef42d59563c721e6801a8be03ae7c5494a868fba48166a2882cdcf5a9b58969e16fc070347f72916811a89602c2421d2d4acaf236e705003115cd22023c70c22631138e3a2c621f8ce7b4994d68a212b65085e23778f2cddd933a61405d42884f9cd27082183493381d15b83108cdc284ae4f4bb210779d526a0c62018c929df7e754a923e6b420d41f029c2bef2b90969a5d608049b3428a549281b108c5ac664b5ead6f803dfa731dbe990fbc1ec5e55bb27cb1a7de0b49bee7ade4e1042abc10746b48894d56a4165f76aec81b37613ab7f6b7d8d1c126ae881ad4a6f13cfa6b684d40535f2c0a778a523a2f7d608ef0635f0c0ad69932631ff8d3af91dd8eecc3156d96d07264b0eddcfd014a1461dd8607282bc92acf59dcba1656450830e7cd6c5a45d42e4dc9e9f0397eb94ac499e9d9bcb814b9b344aee7890691407b6ec4dd7f78dfa2c7138b051d34949195266c4dfc095e63d91e2686d44ddc06778528d1ce936f8b731d69a8f121bd86a1d393a5f7bbd92d6c049c8912bc4a44d7c4b6ae0e32569a93508a1cb4a6960359d8bf6efe7cb104203b7eb163347d252223f67602c47d2bfdb1c3330e66e5b1dd275828897812b2522932599f44b78c8c0776513ca3f6dfc0d9931b0daf9b2978f0eb14e2306565f5d6f57fc523313064e2591d7bf3ed7791c0c9ccabbe165ba52b4e80b4cfc1b61315a1ce99ff50297d466536eb92ef0a7dff6c13ec7acd4728193d183f9a515a13f64b7c086eda5c62879d2a6b5c0698aa2524fa259e0b76b6d62c8799983140b6c348f9f4765afc07af6fc31c7d3a52cb4029fd3f44893a0a24d50abc004212ca7ec954ac94da9c0bec88d39a81016c934054e66bc1249e74b152229f0e51a4183c8a54382320aac9b8514445fb9a832a1c06da860aa2c9d89d69fc09932adaba43b81df51ba62cce1e9d3a8097c85901acd6702a3a642be3caafde359021b2fc6603906d9b7a612f811b58ff9fa25940476336af85eccff202430a24c9608d9edb45a47606d2f7e0eeaa1e349d008dca60da57ff222b0317f478e9913811f573f9554fa29350e813555710f293c21307a27679f9c267b8c5d1058d5ca9072b4030267ef218b12964564d00fd898e29d2afb33a7d0075c6ecf65b2ca2fa3567ac0e9602a7fe2a4f080c9a93b9a49ba3c95db0ef818546dd7064df144a603c6bec2444595d4ebb11cb095cb4a72f6ce66711c7041cf7c736faddda56bdc805327b2a434211bf09fa7314f87906fda1ab0935b47ecd574f4b4060d38f513aa2f79c5b59c053b6a21efddc9a8db952c180f12e26de6c7b87e2c1811d2858a9be9939081052f31497c2f9d4235f90a36bbb3baafe94a52bd2bd8a0932e765d48a14c6b059393ca9a83b5ac60fd4cbd0a3e4b08376d49a7cca2a30a4ec5dc935372489b924d055b7d49988e39890a36861092734eedac693c051ba92208d19ef89f33145c0b6898820fd26209095ae3dbc74bc1fee668427207d34c2229f8d2f9d1cc64879c9a8d8253dd88792354be4314fc6810c9724d3779c943c18b44fd4e32dea0e0a2c5db20ba235d2bfd092e7708393c8614c26ae409763be4ce58163a69e67482ab144bef7258999887138c6a93d9e4ae4896acd9049b2fa6ee3e32a5c78c26f85839ebb3c61e69419960a4efe51482f4d2d7c18449249172df622ec1c9143cb3a6a5aaac5a821149a925510a82e07d726b5ef2afa0f94070266408f393f963ed80e02f89a0a1f4d286eefc819164eba15ba134c8f88109f69e3a338d7eae7de0542da7de562b9129c6074eb4a63d95bb228910db03233fc7de4fdaf4938e1eb84c5a73c84fefa0993cb02ad613634af1c069c72da59eb9acbf3bb0f97c82767fc60eec06491b5ca3d8491201831675e03a8a75e79c2157254d07c63206a5936c9115f4670e8ca7ca206388460eecd686cc263c64d17be3c0dfa8e6e63af9164385031b24e80f2a47c9667dbe81b549b9574fd44c65ee88e106f3fb6fe7f70b2e8e18ae23dbc06ae44c3ea2d3a7feb46003934efb95fefabf3f79166bb1063e8b07f3ed77b38fab811321e58a1213d1917e1a98e42243772cb9a7bfa381b7092149db889a75e93370417bd0d4694f3b7333b041a8bc1a2f8bd44b3965e064875b2acd8999364306fe4ec99222bdbbbcdb31f0b931ad7c6442a08518388f563fc294302d790d037b22af629b0c4174a7e4d04a2dc0905a7c818d18a225a8e4926397fa85165ec01468d1852b560c92cb2aa5985482a50517d2a5ca936184716e145a6c814dba6b9fbe628f086e0e2d1c8866630313b0b1636c60021cb05068a185d3220ba605160a2981165760b466cfdaeaea6b8bb50019066861054ed6d85dee5e5125ea2ab0de952e89f85a323df4002da8c0569508caebf2efd42b052da6c0ebfb69a5dfd96b74a5c008b541837e8f16b4a951e0b3e429b5dd5947d4f5042da0c0572af51aba792d9ec009a54330a1326f94667368556d2079181ab891650c5a3881b1caeda7164f4de49bc07a0c399e3909372162029bdd2445123a889ae812b8512926124f25707d2bb12cc34f021b39078bb1d4048fda2381efcf9e11d7fa2370595a7a1f9407f5593702ffaf49e974bf6b99ee2270359aca6dbcb75a6b22f0515f84a5ec8b7eff10f8d29f6ba38a84c0c6b21d592f9a93dc04812b619bd12a757e3281c09d4c3a7b24d30f98a0397ff04a412b7dc9077c8e7977cf54520fb8f748f5fd67a1829e079c1e57b318f1be436807fc4911ef5c121d305a2cde955273c06e0a1952c896d702075cf95edc4b934ce710a4c50df8ab7c93b694bc95dcd1c2065cfef71ffd8a17f276b4a80193269824cd7ac9bb375ad0800bc1268594de654a6d66c107ab7849c8989105dfd1ba946c9360e9df587097b935686adefebdb0604f8b8b77d03b4f7b5fc1267da3b39ff0cb5b5a57b01a74db238af58ad0b682cda3fa94d0e21f27baac60b3630e65c164ac28d255b0e1a643f2dc54f1185505576ba7b3aa8d7e8d9a0a36e29dae1ed724ed525470273db55fe490ad969e82b118628c94276a0a2ead56cfbb735ff452701e528a112dc7cbf9430a2e4dd4d39eb37b8898a3e02a2fe535756ab52b290a2ea58f299d122ae2d6a1e0ae4774c49c82f60c0205234a63f013fc089946a8969e94a3e8095682870ca242ec049b3f2775a2e3a7d61c7282cb7173b668fa4e63ea36c1778908955384741e2f9a50d2c84efe37964cf06b9d930c15b1eaf498e0db43ec4b37e61fb376093e76c8912442fccaad5982d1c8ba5582df929a9ac3cc7d45a3042742c42cd974c658a29a04a34aa62043ed2da8b52451b220e3a75e5224b8d6984bcb74a9535a48f059e47be8603e828f29b2950cd13cfae8087e35457d75e27b758de0933c53afdd63ed298c60a4879c91b2bc736364116cac521a74288b7944882238cf9932af3289cade26825395af6a3bc9a415728a08ce377656804330c9e42695f431c5c43704972ea69cbadb7527e71482136b112253660eb23d842863b0b89a9b6206c146755d13a1a729a95410fce994d74d9d8e869d81e08465aee6d1699f441010ac59778cf92b850afdfec07936d7bffb2a15acf30393d44573d3362de84b1f3899f4f5f8ed5e755af8c0b5bad5e40bd97e54ca1e38bfd431b5edb607ade881310bd3e6eb77af21250f7cda969cf8e9747a53e181abde9cce844a4d975377e06ceb742b857765b4ecc09a4850d1939cd4b2aa0337d1dd4a3bdd4a448a0e6cb699aefd909a03a327eb5637269996037feda6e63147f41ac5817135dfcd6295f47be0c009fd953d6955eccbbe814f4a081f0b4ae77817379823c970cbd136f01d5b37828a101014800dbc29fd418479148976af81b111af0a3ae389f4d4c08a0c7da79a9a543594063ef44ee6cd29b134b268e0f55465ce9ef9b7ef33b03af2ba479decae1833b0d53157363dd2b72b65e02b68d357593793c4c8c07846091e54ea1bbf740c5c9fea335da23fec1403a7424ffe5c4a448b2ac3c046cd1959ccfe4566c0c068d0567b4104bfc07586e0f182bcc02599428a88f9eb02bf751593d2f47181b3a4fbb2ea2d85e5650b5c65fd20d3a4ef85a4a205bee295d41331bb4c2959e083e5f62fb10d8b55c102232c8ba5ce26bb0227b3d4fdd52651619a15384d1fcbdcb2d9e8d1aac08d4833952fc92a591915d8da167df7a4a64c3d054e7f571231674b0afcb6bd8898c98927ad28f0f9233306f118a3490b0a9c485c09b9d3e94bb39ec0f5c79c325dccf3f5ca09ec579b664b3781b5d12d66723386f299c0a9f79026ba2a33be043ef8a4281a456c728e12b898ff944e891f1e9249e0a3889853c7cb413f8804b637447e5fff09ea1d813b5da739067d79296604764c453ce6a0725e844ca000456037d4c9899e2775d7446093d0bdf5214534290e8191e32124a4f6244d6542e0b373d404d3d0be292e70b818a71e508020a0955a52ca2ac1c3ddd328fdace06b4105000277a2471c42017ec096674ada92bf55aed1d1a0003ee04e64d0a1f35e6efd0d0705e801e7a22663c7f1b8800b0dbca0003c602cc80c936f1253e5ba450e0ab0034e9dc64b29b5c69c357643074cbc8b41df69ddf353b7a00039e02e549b524205c001ff1d430711537c741670e1050e34c60e6501175ee0f03f0628c00db88b1eb3fb4325e8e5779c85c059060a6003ee227e964eeb9492fd05a8011be2e94f5a2359f20d0b4003aead455e8a36d3eb3139b494371815b8fd9805db29e6383abd6e0ed5f9172b00030718626091057cc8828b933d66f4ca3e69f7c1b1e3c610e368a0051fb1b0ac7478081e3432f880051f4b6b8a93ce7292267a059f49a72821c6f6c3157ca5c66c6923ed06f9b582bf2b1d2a241f3f58c1e6a86f4274b86afed22af88f3c42574cf1c775f4a10afefa46a78e54f57ffb2315ecb95d7896d2ec6b3f2a18ddac9b60ca7d349a4e510ea6378a6ade146ca90f1643bacd91d4a8146c5b881ba6695dba37a4e026b5f9dec56e14fc8d9dcedd561105973ce8cce9db534c950a056f6a5f5782bec9a0ef0728182147fe5f0eea4f70797793fc623e3fa1798289924d4bc7ddceecaa13dc7a2475f31141098f7c7082cd223429996983d2b13e36f1a109bca13a3e32513e30c1c5a08386c4bc5832dac5c725b864ba7372fb6b89d1cba159a47c5882bbfa90548a64f5163f8756a9faa8045721b46b497dfba0e91c5aa4b6bcc1f8e21af04109ce638c28d174ee9849e863129cde04914d968e24d88a112346bf10178f5d043e22c1eaa411adb316f7ff3e20c195da7595eca08f47f0df1b838cf963b6baa00f47b031e45831a51311a34a1bc1bafb687dbc5c9bc6c2850f46b0934c5dbca4758c41868be02ce4adb4bd493fdfae08fe43ab55501ac2e123119ce6fc1ad48990d32d09116c12c1f7538d8cd4f71e828dd949dbfd53cc0e1f86e0b4585a2abb0d19ca367c1482495ebebe6fbba5806fdc08c38b84868f8c7da8a4f024e25824100883a1703810808102e603e3130000000c201486429160248db465fc1480034b2824443e2c16281c2014161a8744c24028140608038160180c0884c2e15048201ccf84bcfc23fccdd9b69cdbc999e79ce7382bda9ccdcd90cd990f73c6dcce96250f9f0356c899d94abb0c693383abc7709596ce29ca2e9d82b9731b616f895c47837bfccc3d8f7b0ed169fade7f1c99303dde814deb1166c45d17335dcd2866080662750208a22d4acfbd8604ee0af7cbdeac53946a23355256678910c3f65c9854a1168be89b326a1661224fd6afd2d834fa7f6ba163cc780669085c05be215e24f785c3c2091c82a5b011009d7eb9d6810d19965687ffc01b79050cb0f5b5b7672bd90d49735ed176c4c29d8d26ff6656b1e3c5e68d6ccf32d42c88053d878cb4d89b356121c6e908fcc0d1bd5cad382fb3b985f4189e1093ff24a0eae6b9fdfaa5c7a996959b0743986eb3e77bfe4605f12f85557bcef57a853fb8c2e504163bad26ee3c3ea29dc52ec3ff66161d54e2d4b1c5b3e2b1d8a8fa2dc1c74d655e42884f4d4810f3bc45686720a124b49317bc4b00dd21d03b6a1336613f500a90229a4311fc3d17d50eb0280a5da010519193d28dfbc28a775be808433e704c21984d39b0c669aad8aca0c5806e182d8d867bbadb9df3cc3f86b525e4119e3efb0c8d706a78dfc143abb1fe5c0be0c2c521203af53ca677c9ba39e3cbeca9f2bebc27be75013e16e90f2092a199c3f5820ba5d5bac5913d05fd3d76a36e59f99f62c3158687dd53c9fd0d0f09e2b431be040f1436264a3ab96e5837d71dee86d59bb134156ffae571f766bcf11e8cf7cbbbf24c79a93c40de9537d1bdcf1cfd78a3c48f9d5008e8e819fc591a6ada7061db859d298fb06cbd5afe4de88881a8bb791ade8ab79f6fc28c1d2a15f31502527a13e44de07ae7b742f73c0bb357ef11f662e12d4432e6e2d6e105279c8059942ec486ca86b68539070ff4f306dbbcfb8c7f6469779a9ad6d6e460e0f52feb163274ec32f5c5b8c9815381b6604c5444de1d710bba30f9860b3a6929b90bcd9de75673efdc656e3f37b43bd4ad706fdde56e6f37843bc48d7add0ade9271a6ee3e7ea8e28d8a169d272a257e744752c67b9c5f0aee9cdb39a6a5d6a90aa9876c593a757dfb6dfecde67b6c4b5627db17d51a7852e9d76d7a612591324a962f1a4ac820d435cb2b47c6a3885148b1210d1152344927471f21a5202279479bd1ecae196a8e968b5c85bba4161d4103d0b8457b982332b1d19553c8189acb7927775e74317ac0cea48f51a9c552f9a8b1e799c1364f4e29153cc4d252a0a897a4a537a33a6f15869f05fb91614864694b76b2e641ce1cb30551477508c0e4932148e488940265835ca018c424be145e26d16c32e43082fb265165683c125a0171f9de345d0d14722bf73ccf4b5eef8122d7d0dd48bb5130da3845b20b0ce1fa21a9263f386e59ae48006dbd0dd2fb4101030163b313ad0e806b7b9135c8d4e8b36d2784b8b4ecba2f7e6fbcccb7bc7e71d0cb1288cf4d76b2f0555c40df0435082727b1ed7296cd0a83ba6c4df8d4210763e4ffece9e133f723b60a90efc57503079ee3f01ea559081746cad4dca70c00ea7d8b58dd8bb06ee401d05e25a05eb73dd78d934ea15db7a1745097603af90d5070b4aea9f052948fb361c7552134e496f19f0c34dbb77ce8c0d557251e7cf83215a122f935e5bc50db6d668269bcaab06e8297114998b432c92ce1d823e6783c1aae200af5ef57218fa4fdbf9dcbb015d3dec5fa2e8ab104889334ca906cf1b43a385ea9c07b2c09dfba501a262c88e36d4460cf7c4c3d4c0552c389c1010e92b78295a6b1e5d9495c0afa9a342b588eddf8989866462f8b5b2440cd9061b5c69132b7c48b483c7767d28780369438019d780586ca75b854e7d910baa21e6ba3e173eea11140c9b570b904fd41ecc560a217958c710becbd45d5389aded202876af974244a67c73952ad23619c2359f59b6dcfe3bf27b20851dad1a8b476a1b437443670d596c9630e547ff648a3749d2e00722ef2c6299394c8e993409bcd1d51553acfe093925723dea2900c7a55f6702e5f1f0a5cb3a2e8c8da7eaf2b330320861109db08ddc8add9f8b2359bb21ad000cf634ac2f598b19572b5d7708f19919632f6ae6ee4c0193252aba1ef3f8d4c441fb35297b165a611137747194e85e0883819076371a71099cc6adf9bdf4987f02ef182fae849bcddee61fa210009f1bcf999142eb03226982cee916ab5b02d44c8638000b246e30d3df95dbfa1be68858ae49e3fd0867190ea866edc860df2691ead54994a8555a2810f9e03a87b8adb40b4b81bb791cf86d3baad762f010aeed10190c80f89f19d2021873ef935831249264f3377a1dc9c5696c5c95484ec51fae7c0ed7a521bd037d182153ddbb0943d6f5440c1bd0ceca4fa4256974d0162b8b551462b1798ef7f3d5d5f44ca9d8686cc723e80a2c24496afa0f1d15133b6cc24fe824cfcb0e117cfea3abf962e31cb05af36e1be6dda2c07ec38d240c0761465fa1274c1a449b078c7b17401a5866d7a3468687e756852de462442d1c01cffab5d7f9e8b21c98e0b29fb214d56d44b4e6d41485d8d840ea2496a5dd51c30814c6f83c87ada6c8dd6980db039807197050b388d3433f6c9168949cd2d6bd8e0a70f29b7535694a600fee9b95fe98d8f1a6058cf8907852b3ef7ce25afaf81217188683c5459a21db11b15543cfeb47038fe752987062bd70956d0fa79660bfe538c4d10506ce825ca1ec9f18ecfa36c6a13045040410b2442bd5599307717502e0e697eb016517d8b090b497808392dc5c5a9bc8bb9d83fbe2f26606ab7520f9aa8cab5345cef62ea4796f45b325e6350c351528a86e3341311be125464182f4c566fbee8a3685c6452dec82941eb71c65412a74d56baadff13ab9b36d9c4a1ee4ab0575c83e8b488d15d9d3da1728f98bf1c840d621ffefdc294422da4424ba5e55013bcca5d07a3841724605c56df971d060567a16871405fcd63ae10619c3b8a9cc4f2eb4f6cd9182de961267e1278c9d59e06d00f5ad3a38fc3f19846635b4ac57707981c1b374094bb306cd73a02b7ed97a5d36822429e2c784579fda9809789b0e06ae0114ffd2da224e36f20126057b42f015905e4e28c09a4c915f4e2cd73f5ae06e0c45fe7bfd04b68f4267c235863e814c442c77631c9f9a34274e0b1655836d63fd7febf448e5ecb4e9aa1f103b0aa1bd456b3727e60278f5587faeec1aef32fe58362324bd29f6e4d061b7a9535998d0965b54089746c243fc63d7214d999f9a7f864c94e08ad517a298a654263eca4912262adee08a1b85a85cee0b35e8b67ab9c8e60216e5a5b67aef7004410477468d6126bbc8a81240518a7332a8a205f5dada0225f270174a03284325868ff7e2e03d05ba1b6f23533bf0a2aa8b73ed36dcc197ef27d2842010caa5538c60eaa81338aa1a559043f5658963ee5da999ab2847181ec470666b9ddc796797f29e3ab2270833f833991556e4b030611163d0ec60baac74a6faa4fcc27c226b87b2700c9e5a6cb4379bd3aa6b8cc9254b43eddb05e61c43ee4a91a1311891fe33f358e8da3178d6b49eed1ce3ca810fc8f4675039a7e6af4340a0e8440a270e14efdde9276a19776a26df890ee0ae41030858a7bbb4db02d4ea274cd846b7151ba7449874a4c410dfd89112d21f9cd127049c80c59dbdc98e8a95e8d72bfed25cac77c01ffb338001e970f2beb1e1a1c812977ff27238001b4d8522051521641e1e23e3480896fcfe198f6855ba8f995bf1a80e8bad7f4adc6143967bb1806abcf8e590abf26801b2244ed42b22fc25a3f248712961bece57c951a7e6485e4e4553c6ca8e61dabaf409bab6bb65cccf867e69054d0f621b84066e0f219d3f34702d9aa420139d0e421509e577c275e59fcf874c6acdbe1a741a6102e9f9464c478da4f748e9e83c6c3853edbcddaadc405b6e3a0bb8cc7f1d1dea915fc142bb8868bd9366b852fd7918f263e359a32d118704358481daf2149749c8e0003034d731cc498f0963b52301352e8d97f3528518e120c98f967812fdb5e7f95c63f57ee74bcf85af6a46e4d019e8a4b4318db5023c221cc603934afb720f8d4dd6fb2ed54700339a87fdf43379ddb237eb207ae32695bfdd68bfbc8fddec44cb117b95a286d37e49eb5ae809417641b0e7ca3fcfe6c6eb8ff424da114e99c39f4674c7c55376e0864a7e7ed14fec299d727f223e655b7caec63ab0535a3d14e349cd31247c70b4f472f4577851691f627052e77b25932965753d54abbb43e051ee0082c9026c74c450ae42203b2b47bd9c6880c284a0530edba2796dc8962b62155ad3dd2d6f16cd0e7036dbf80976396180a58f54e25c63a46b57cea14db74d96ab12d3c5e754a7e3991a0f3081a5105e3ded0cc4f3e83e9522a11daf3d8876f3b1eb4da137463fac6b2858bdfc14b1dcb80d0cc2dc3ea1e6c4c21fb0db448df5116580b6e05c40590d9240cf3521a4e8c2352f837302892e1a94c834369f51057c6bd385d786d3c97cfa524254632d407bf81cab69648308f9bb6c81c8b1daffecdcbc1a04c040d53b12e167491343c9244bd10ff11e5f2049c6a3621a5dae536c88de633c4556d5253f9d170516d98e0d5b654e72527d520aa0f16ad7903bfd25a5b1837c20d7ee24bb6e640e5cf09d0f98883787fb0cae54ca35f87d3bceb2f08857d634e990ff8b2a32daff820fda3a9423459f74c0e662ec0ec29b68fd39ea8c840160a94ce98cf1dcb405cceccea4317f8c473c0ea007198e6880ed9a8fcf4a83c2fab7ebc7be473aa0136eec07269d701849a0563825409352a3b0104a167275254581b92f503b8c2ea8518f386c8b19623ac78d146d58447b1d32fc08a355c93a9e77e16e99a9ccbff2593a2afcd7911958e9c2a3aee748522a3927e5e8712f11214ee84a11aa37e3a19365e9fe1746c86a377a96207a4615932a55eb100ef6ecde046f73e6a2a5b309e53ddcef26ebc6eff80d1e1935d93590974c0f1464dadf78ac48c95ed67f996f064bb784496ccc348cbf448aa313222be76bf78f292e4b81c1759dce6bb36adc3548e6825e20dee8fa622b0991e17915b8f8c1fdac02257dccc73dd8f002ad3061af9497b795b4d80b0084f9db04fe7247c9c0ffa97804feea0a05bd04ef0a0d7a6287c003033e40aab411300e60405b63ce460cbb452481bbc0e7c4461c193649fcab96ccb365aec8185e03c7c7cd79c094ca87856ea12ddc224fe4a8652c8a4b7126d55c0a6b7d70d25dd3b9e0711489252245dc9bda42d29c1290e7d5744b9225d4b01246aa98074f3b4c08a8adad3d23eae3cb180425d25d24e5ba7fa1392e3c45e92c7298e5a96ca3a719510ea523a78bab45a4c5d484f9ce679f5c7e26339f24ab053759973a37cce2bfecacb5361c0c0bd66a9fd3105b61f8e6837a87f8a2254a290ea10a9fe2d1aa7f228595dd2fe6f670b2389c9baea04359da53f024271ef25fb93fa9aa5be2662a96fff3e7696a2686435b2fa4a152f89a0e49a7cada4b30ad8c48fb003fc8158cfe90d24b314a0efee034d51f831a85f8c61e2a596954d4d70803ab3f3ec1b4d73a4bf8e55ceff43120e5c184d88d16054f6790590ff38ebf95f2201ec106305819f1beec2b43288995be639f3cd3cdcece819ead019ed9c7ef93eb51cd0d6f8f755420932c72769ce1c4fe8f14356b5973fc67714335cb4f3ec88ec299de90970f5dd73418865d253dada3aed3f96b829bf2284bc8cebe52c673a8f426b1888e493ff4cca36103a1009f3ee2c537e14fbb89d81313347fe8370035d514c86d40bcd159683b6053302ff9c96d679a30d68f33e669c78a1dccb4f0320df894e9a9b54f462d27ec08834efe3e400d221869df9cd1c220c1d7e235636327b4cdcc1d085beaf1c2113c30cd4e495f32e2bc5cc99d1bc637da41ebacdb543a2660bc70f20e9df33a1ad3566dd64a21b5475efa082e88b0bdf3721601ecee0025e3dc4deb67907de0c53efef0de38b020d7a42e71d4c8898673d0e1125f36859e1f51c1c6c185c7eca1c289c5848350a435c048cafb790486545e2c1e61d0c5e7071b13e7363184aba2434849911e806b327f01c4b58117ad9a256c56112184b25ff1187f54210d93ce74256f0f48ef5393044dfafb6751e71d80bd8822b506472b54caa1199a8817f15dcb0165e31a1a9039a00f9797536944cfbffb99801671d38f2e91e39a4efd422a11d0d8715c17562f42613a7461f90e6c42f9a74d86309d63c1c4e4877bf145f5a7a25256d64268cedbaf2c7661ff060d8207405e31db6c642717a6316b8cc16c27e944218dfabdcff02df4ebe2e7e7165934937e983215e16314a0a8d79cdcc05286cb6cb894de0d24c0069a9d852e14bcbffc6077234a2366823ffecb7f598eeb98c6ee7039c5a890baab20df2a49e4b2a59766d26480ac8330726356198778953cdd4b3eabb5400e8ba341271c30578f3f7a18a7a7d6dc6837beb0659bbf598dc4109112b7251148c97a06ec0dc844dc50f234e5258b828d78a6f364ac3261e2d2a60ba478c32af82743548901490f42eead5dd515a1f97d7a11704265f15fb8b7af19608aa9fe8509069d66c172e09f8291af272c3effcbcab6ab9fca97076e60628f93afe921a0b7e52b3748f14d5e1e3491281a5621d096f04a066f9fc2e306481aa260acdbf4067db93ca7a3f06be8e6a61deb5a681befc1d310b60a86c2c443a03c720aae06a260ab51bae780a53bd0222ba3cb4f927769fc084178f13aef04b12f5d1f74e43c118a49a0d519508a115f5541c00fc904813f3300135cb35c21c806ae3ee9111634d7f9d8f3c5750c4f84a06b5f3c9e8744444e590137f527afc65c7a02750d0a08028c3321594737515e0235dc67f10339f949467c24a7c3d7e21eb99a524dc37867bfc1af616ae3613652010d5cd4d05b67e0b2165a472b8e07e0f35a4914234747f81c67fb88684cd24e66ef858f545da8249b63525d37ffa641c20c5d6bc0c7b14e0d3155cb7ac6c0c5bd7955de2430101f3daed09c603d7350df9f4c09a813579cf234f9feb00117b9507bffa46135451bd260b384aef457b1bfc377943099bf87753ba518e0a2795d583b017f217ad58e18ab08ef3c2757d81348959b1630a97cac9c233790d84ddcbd94a404001295a34115cd63ee9b6201c79d720014110c08f40664d240566c2bda1b5c7bfd148953a56a4f16fe1fad1a26eae501b49962a50157555bcced0460fe98e3ec22c20ad98b7c8aeee7c284df811bd5e36d021a8defa91af1177e25391ebd5e27a6946184ecb8845aaa2951f2370586cd6cfa5fb55a6b6f9539fec900388af9224beda6a9c2c8bd12d56f7431dbf5a701948eee12f1a36fee9997f7d1067ef4accef88a92088a254f5a39287927a0af24c43f9d9d54bd043c404182d8a7eb26a7d6c5406cb700b7b47ee9d0f21d5bb3fea7dabd72a92a41f5b877318f729aac74abe9160a25d123c13af47541a53479e17158cbccdab65970878ced3a0ec1bea7c997ba7e9f174d73bede04133368b3719b3da7b199f52df3696e6f7498992c79b6561aef1ca30198f2338862f1df0a60a61c10156025dc54297d3ce78d848d3209c8f49b24dd8a036f7e6f96b1755a8a19802e735a6fcac53c7fb899137b083b22e5edfcf46521b0e6530995ee7ae497010c462ac6d2ebb119a04487be53dba42083180fea1454b32bf2dc165dd439301729c7d0761e49dea2717f64673411f439057300b270c39fb61596b13d0c10ac48a4cbaad4a80c7ce6e4f80ecfb72a8504071bff29f75dba42709c43424583f4f57a6390c7ff28c4dd06b91eda67e497bfe01a8edce4f93f612149436c2368c82bdf9b7426716ac4fa1cc5e176126f9a76516720f119d6637f51bf27e1efe978aee0b513920d151fa2928031df16644c42b622dd6158f8274e2512872bbfd6feec1e0f4215e0995db5c179d4924bd25543a7bf9906fca12504fa3a394d413a56ea2c47a4d492c343f1e5b2f90241e66455d70d44a01b214061f6f862689c75bf0d80b1ed54b150fd5be1ef1757fddffc72716ba1fcce9a4f62872cbda99d3a80cb7f213ca5356ee6f36c016c52259fffd302f28b13cb23173f0aa0030abd1412f6d972ff5590f8d67e45fc7bdbb6ef9850e9b93b40caffdf968b97165dcf725c360df884d2810084e85584c8374c4b5c6f59b75c4362bd01d2ce02d2e8c9d662b640b0c0bf76641ea4d0b637b0a97b2e958f0160bdb7b17062151805156602f7013067b7541e85119467240c9124e239861246fc75108cc77596c5d5e63b143916f5e221175ee1295ceda8ba483f321bc5c275aed647182b655a0311b7fc4da579f939bb29e154340e7468adc46f198c96c64ba9e3914954704dfd6f831cdc13da1f1281a46879db31a3a5a9afcd38ab73d52521ed4a191a7df8d845c3b2b4fbc06585c322c4e4e0a2c48fe3833cdc6818b6f02ea9cadb61619c8525302055b594db7de4db4ded5b1e8442bdbe73a756c65d56d089c9535301867813d5c8efce87f78eb745981415a0963208730d204e2b912d1627c7a48e4163aec994d160e678a7bdaa9ea4e8659b924114cc5d9270d57a6e4ed1f34dc5889846260fb2b16420688ecd0408268014ebe2600eab0f03a790612183687b195f9f6975fec47c3146a7f816d1d1b23dd610a23acbbdf419c90f19c8f7028fb0f3b1c9a64a25cc2a7944d9bfd29f76aa05473cdb075de04f6a1ef2b809d816080d885c6036c25f7d26f9e903e1c18d9a2c690f2648d8bb050da8c4a2e310a61b3e61f9cb08f7fc46528ee248d68174c490fe837129014ca4e0ec3506b9f0efbdc38cd5b39be743d4a8e65d5063c1a880685899f465b4784a730b496863443775f0351153267d71300d5c79013346b800889fba4d8ee1512c6f92b317e50d753d76e4c373c4cc2e10cca8ea7c2c120471e93a32de5842ed50479e062816ac6769f781a2a47fd5d25b9dd7fed580f473052298b8770e50d566d2f9c0c8ff2aa036f7d6a48a1a538a6258e581a5f0e2cbd3fa9a0249c8d6122b60b6aebc811d2797b44cb80ff27825e2120ceb43e045140449c346dceedfd4f5ccfbc488d65ed8e282522b6b2946f00fb59979609db58ea6d03c2569ef1a1340719cf51190368b557ba40fe7e21711349b696b1dc0012241c428b9420b7c8811f71c35648c9da23ae92f952f8226a848ed611deeb90a5e209ec843d614df82dbc0a3fc2acf05fb8164e0837c2c21ba24cad43042d08b6824f43da41fe44ce9a6bd66a111c7ecc8a84100c0990f481cfb0b0754382a2fee9bdae163e7f2c24072fa4ce9450782f33fa58c63eb75bf7e2c420476291243c88091a2908a405e1bb17f54f675d08ba7c96204fb097dc26bae259b41ae333a5ecb4be0415020b24eaa09301498f69898642326b1d2aec9755f26846ee8cd210e5bd491d26f8cd808656e44eca690ae33e9b6882188fb299327dc88753a326de4eec2913dc8e5095d7dcd963872dd4e95cd56468a83bf42586b56803cb0063cef42b41c5c863e691d22102acb329ea2d47f5018fff59caf96ef219e525abd6a29599aec65dc650b04c327c1f454af352beda3a5e22ba32eb0fd7e44d34fd07b5d2b311def030f7caeede5acc3eb5536a2242406faa2ef235099680394da385e27887c3265959f760f80980c611fd3a9566627a32ebbe6a165d2c00d84aba57944f1ea4cef4d592179623fad97d2880e600e635311233b973952902bb62b658a7c5184a9b21b370b8fe60d56c3236b2a00327f4dc556746a4323b0d17559d6fa49878230f58eb4d01f3faf44d67e5009c7f33dc416c018a58c551848797444988cfc275a8bd2da85a363b0a366d9a52086722cfec3b418f8d4702f636938caaa574259fea6148382440c79c528fc09190b0edbb0b9cd02c8dec1fa66797405aba8d05a58328e3ce3b37804b24300a9f3b875a2d8345be2d0c30d9e2e40a55a5e0760de9f02a66299116412797f21adc770ee9c3e5edea62d19306284a0b9fb72c65f5c1d14b54ec9cfc9a5080a5c162be5c52eb15930cb3faae303323fdc3ed1780bab1721fa05c9b72dc1e01a1c55dc7bf16a804b31c75b800dd1c6df8ca914b40022f0b26130c1dd8083c79fc546fd6f8eec49113e4ace29fe1dd1b40a255c412c0986827e8ead4a25d0b36f993f9e187574e9167adc002ccb28fdbf0f1643a3a91621fdfc0d7e7de909600e8d9cea1b92abde5460f34b0d313c219a13d62137338ce96cf2c3dd6c07601270d178d1d95e15d042d8ac35a5f2f0aa294aecf4c2a681fcd1e92da2e6b5081f766f281bfc4d27af3152b82f1b1427a608da3dd2751b35b1c6f9ec44bd57036974ca64ea777ca0e7c14fcdb91942455d7dd46300c973166ce03631fe6bc8cb7b801a0a171ea0c086b474bf6786d7462ce501a4161b1cfec274839c29599c99eb10b2542a10f52fbecb082e9ad4b52657afdd8670043a599568836db4903b1f1b225dac8686c7fcaec5c47dfdbacf94954e506fb6013f8decf2620b111829b3902b0b1b5035b2d77c3d79ec9661378b51b25d8016c670a4cd0e68813d9933f8d024e4d4eec4ea895fdd6966ab3817a726cbaadd321f029015a4f65bf482190de98a213feb9815a65caec141e687189d56712608243c6982c7eb0109894967865003a63b1f83f84f39fb1031a1662b3dcee42e2162940d082a25bd3b3513a31b20c2530e9477a4fe9c056a49f9f5ef36461daaa946f289485470061560fc4b7bc110253332e90621105bca9d8d9b386a7ad1a675b15206daaa00a2887a7558d5e9e3656bbe83bf25e8964558dbdd2344a0d7c7ac3ce03750bd054a46fc29e8bc11d97c13cc71aae8cf9fcd03d8c784aaf62f39f438689035ef0f96ff406b4e4b98473cce6b9579eb16ec327bca6bfbb6499da22364a10312ca2bdc5b08344e0e1838797d282b8043aefdf2611f84e3d717e06bbe1f6a6357fa453852d4a6407f4f52ddd4537c6982a9e2af7c5901d2c43b1092f0b3819ef564f37a6a04a8d4d81a1fa7a346187a5ce904d719ffc6efb74deea9ff6106e4907577022cb1868ee833b23c5cb608cd7b0fd308f207e4b9491538069991c3d1e00861801efa834f6a89de69b647fcb9e648c231ae80cc31147fadb619e1b480dcdcb43b58c1cdd65e0f8a25cb4e25cea6123bd5ca4b60eca7b0a56a92c4bce58463ce48223e21de84747f308097df3686e91605f7971e1e108eb7b974b29e48a93d903d65bfca9557523a3140b35d7e12bb234064d7dd704e9e6df68785545f580356d1cbc54e2e53ada37445e24b173370a360ade6dd16cb994b1cc358c9eae0e1a2b26361b66ca45216dd374f8f9d13f6b8f871bdbb9de2445afb3b04104b479fad1779449a092b9f154d4302cdc0b02ac5f660fde041baa3162988bdbcc002de380e0bedc3323d07050045dd3c6beb68208850196fa08e75719335321bef6d8bd7a22b784f4e1712167cee0e471223c23a5c776ddc9249a5bcf4a71090dd04e188f7949481e21f33ef96cbc8c2b96db23b55f6f6358347108e185d2e4f93f0f1120aaaad6664dc4079e945f02553df450e07a40e5f8ce3ddca2ac00b6fef4e44e6a805d241a167ec797b702a0880220491597fff8dc17b098f00bbd13516c9469b39182610e92e02899852cbff53c19325697d34d573cfc48c76771155b178a3cc8e56de086fdb830923674d9707a3186b617b29e04466c919a8e40dff20c41baf878c79bb1b11c7ad855de0864a0d5b7200fddc769a6364a32d9c922c56242609419430db85a12518c273ae4f42d96cde2c90d7ce90f47b92d44821743f443ebcda91c62048588b59c67db69e7d45355e3727cf0e42ee7a87382c09f94631427b910681c5330aa82c01cdc0767ae4c9cfae5467371bdd3aeb85b2ad2ce4f864a9db95ce6d71ce22d22188cbe5b4132374ff52f40495c1e914d66e03ab65cf49f79dae419102e5c47305c04e98ca4da7c03ad1adc0ef4e3f841068dc861f24aeddb62b85bb83884f1aae70fa0d6100b6a087a25ae0098821562d46db8bac21b4c62a9d093abeaa546543429f02ef404f1a7d32a343cf94f468bc9798a594756c889aaa314beeff83a9a44de5efcf9ec528b738c7ff559be327244aadb8b67bf8868ea7a808a9767929634c99556563cbf7a72813e570ddcca3b8b6ae791702e38d793270b2426dabf358627e4d78f777969adbe8af345a845d211b3a44fb070cd139ca575ddf27f2d25f23b67d48444357ff888f60008015f90336a8d59969c005e0cbff7686203a95207121f3ec5f691dae75e29a5fb83a82d9fce81cc6e1f641d445380deb97657089c741218ddaf56d3b1c91493041bd1aa3386feef390d8f724f0c070da501787f361ea0be9914f7b08de820ce6d645199cd232cfdfd5df43f76d37ded55b4c512dead744f18755f300aa1676cf627a08ebb10e0b5645493d57ff93381ee7efa7eabca6410d49666e884f89ddb65ce67eae91725133a9cba5ccae5f4ff8c3ddd9374e14e9be46e510c54cd9abe842384b8973010117474ea30c673f0e0d6928b5ab803de511a18d851dfe4253c6ba6182d9398c2443fd5d26954fc1c60ef59aac3f7b9ba9bab19796e229b00dd517d61ba51a1ec230af124a97fd046ab2e9282a8d14915145020663b0634bb8f8b29c0a0e86c23145514597781bea48cf03f300daa13dc0c5256806f8beb40b65fa3f8503a59af32ba7fe79939ecbc315fce4f73ae7d539fc51df5c81f208094012c89023e1bc4920a3150b46439fcffffffffffffffc2836884b6196b5f2699a4d43fb65e9f93292599524aea8a507fdb7bb1adce6bb700705002370ab70a2a0b6783f633402006064ec07808a3a48a09795f762b7b3b7018c25829438599f9948102331e8d11b081a310e628ae57faf7251fe28430560a3955f2e8312999580d1c8330b9a85c29994ed23e98046112426bde9d754e218a0261d07d7969a132cd4407104693e521f7d357d7e40fe60ba2e53fb473d4b2f8c1a0f7df345674b793d70763e86041041737efed2c1f0c6bd97abda71bd6e93d184497ae9efc5c8c9f9881430f063993f263296112dd1603471e100d0e3c1872492a49b12d6b2a5d068e3b20871d8c132f3b826ea7856a1403001638ea6078ad98aedfd9a225a7834955a4eb9a373122c77d1b9cbe2570ccc12c794be95eb864acd982430e5d8bfa49b2f3ccf19a0c573150b0813478607860666046197130fe7552e3a1974fdfaf070e389842ee11d52945d7f7eb0e1c6f306e8dbe9896f466a204898101316c6c1b38dc60125f5ab6e106071bcc7d7593ef53487a13101070acc1bc9ae57741d7a5d21b047567dc020e3598d5c45354f6e3ed48c958ab71e36f50461a36520d1b67a41a957fa38c1dbc7f192420f63ab091032788230de61093bb64954b86771a69f49a064ca08292010e3498b387c52461225f83be41195380e30c061dfe9e2fa4b012a5b4c1e9b7810dfa0635920d1db0251b3ac0097098c17055f24d25a70b950f9571018e3218ff928509db5056bb93c13022fe95bca4c492c818cca9bbb2b7544c072c050e3198a3e536e1f14708cb3a0c869c336554cd4704638ca154e00083e16db4d5271d9f274f38be60f894945f9dd6923eb91a26070e2f985267c7e40f2a2718630ce50347170cbbebefa72b574fff655c000b1c5c3057906a7f41733150000213ac81630b465739bf1b09deb5d7c0cf000187160c2178fac64d9e4923e1c8827135ecc297b84ce0c082c12ec7df8591db298538ae604a5a44856eed2748638c31ac803c930bf1c55392048e2a18c73e575e388d3d1351c1246fb174ef6939a6604a634244106627cb13a0148c56aa74a9724f0d237044c16416f1da547fc4fd13148c21737f36436f434d4f3007a1baa7f3236278de09c6ebeba4d7e72618f29d0863ea7cc276ce04d35dfce533a14e657909a67abdaf0f2b17613d4a302515d45e5e11d2c328098657fb71fb2072b86023c1d43eb69eb49e490e3a828d911c46e02882f9b292522907217663250229824ee710cce152cbbe49eef0d86e091c423059ecfb750ed7dd49b5040504c3a419174f9d4812820c0cc35f28ebd2ff22ed41c55cd0fac258226fe4dd30f5c2242b2cee93887861eaf91369e3ad257476615041d72bf2a90b53c8ad203ba48d94839d0bb27857c8d6a6ed1e63d973f4c5195b3109e38db791831a4b06a100bc26cc7b5d8d7c0b835249453ce7d71686fc513c4c8749a6c5ad85717f84cc979b1626d9ff9d90d35c3ca9b33059c8b8f0105516c6f8adc94959c82657120b73b00ea33fe8242c0c3ff163c40e93d542f015a60e5a34b55baebfe40a536e919ebf9f43c9cab5c260c9266dc6dd5cd28a025861d0cabe52d12ec53dab30a8d9114ac7fe51492e551844a6bd455c3f1559292d3fe975428521dfa7a97e855c21994e610a23fb22a27fa776c9146657b3acbb5ca6564ba530a5ad0cd1331e24a94f0a43f851ba4cedcd24ef4761f2944d5d52e5a5f14561cab75a290579288c7212dd84b8bd8bb183c2e435c2528c2c132be29f30bdec7dee2f1d2996ee09d37e6f558ca4d309e3a5668d50677db23c9c30c7a9d23fcf3e56a9b30993d25b39450a61f683ad09739a8a093a6974084225135ad70861c23023f1b2043ba9e1954b98c56554f6c92c215ac268651523e71257c20c5921e694982961708965563a65ad09f224cc7e966c7410af2a2749984f6915356b3d267a244c324ab456f81bbfc842c22897bccff28ac7fff61166d1eea0ac3ea7a4e408e3248addd908437e4f759e57216c4698e4979658f2751127a1bc3c8408524598724a1059eceee74b4d84513f449c7017f4e85111611eb9172e589ce8f9218730cebd5d9e53223f7c8821ea1b359284b4904298e25fd8ab6f5d8e242184d145dac5f828a195e7208c25f47da49935152a8230d998aa88b6a022693110a6549e4ad47f29b32002c21841cc6bffff07c3ae78ab5ebeaf1ff9a130eda7f4b3de0793e88fd65fdac34b870fc6d221f7e2a9f76048fe313c62877f5b4f0fa65879a62f25793089ffb7d3e21659abc38321d7e4ce509d456e7f07838ef2cc0e66754f2289b7eb60f4a03da4b42cdd4ae12328800ea6ec10dffad91ead3207b387d6940fa2a5c4dca2003998fbf24452c943e26048dedba17f3412a4a100381872342de35b6fb9737a83f9822ef5f0e979544e6e30ac6ec9a888ccf5d1b7c1a443bcefbd9899be3e1b0c56c235363cc6f885d660c8b9f9e94ca538b1e36a308d4895eb2fea6930aee47cf1a9ffd3480e1a4c419c9ff9aa256db13e83d9a468c93035aa92d56630ccc752132929cb099532982607bb6b13e299a3420663878430a6372a5a5dc660f4dc29463c93c560f211b978fd881bb286c1385b51422a3d35b925188ea12a1b694f5f3077aa7fb76a7fc88f17cc4976bd85a958296dec82b992fab64acf3f9ec305a35795aa0bf5313ebd05e38d57e70fb95c49755a305e3a799eb3ea3afd62331490057387e4b69792d2e94fc282b1ce3ac9f8f824e2e8af609219aaa532defcceb702e2773c96fe1155c17013f594d4ff3c21712a9884d6c4b4d27fe94b5330e80af627642b05937cedd25e9d4c27d95130bb752cb3ef0a14be74332f215ee509865b8f717146b632632798f774cc12fd9eac83b609667935ed977a32c12cd721844b30b5b2e112cce925d6de3a68195109061d52e6bcd905e1d725c170fed1c727f9aa9690604ad53152f8ed9e9c1752c01130533119c170a942d07d9db37d9e8a6048c27a72ca257be3f40a208241a28ca88a91ec29e7153004a3a96895537f4a59880284604a9e7a3ec5d472134ac13088a50b297e47c0305d4af2c182d07809fe2f0cd739d4e979331dfefac224b353a530b7f6c278313232744f5e9842faecc5d83995f3db85715de5e6f279498c5917866c15c53a56f8503a940b53ef4e8aee2192880be2c214645e97e81423a8945b983dd6fb920ed726c01606196d73f772511e24a016c66eddbae461e634946861f0cefb984bf75039cdc2a04c58ce963c5bca7564611cabfa4c11722c0c631fe729fc75953861619411ca530435aff6ed1506f9f3a554541235b62bcc2dc122a41ccd3071b5c290a3479a5821ebfb618549fddbdd53bb7fd87e1506cdb8930f2a5bfa5d15c64c4d0941881cfa74a93045319d5efc42a830e9b85fa9273f8541f25cc85cd85870dd14a618e1d44ebf530a8350572e661b290cd1f6dd763dcde8708fc2144edc4589708bfdb6284c7a31bba183426190dfa1e6d2749e561914e9c4cbded922fc09935dce8e16b395728a3d614efd6a3bf2e2f5aed2099356779ccbe179d3b39c3049d4ce92266fc298b7d6313ff5cb6435618aa73aaf6d24874f66c294a447b1d4b09c53b5983025b30ed94a5bf457f412c6dc52625da3a3a65ac2e09f442e91c4f38e48254c395da570e96927344209e37dd09fb2e53909e34bfe78a6e22909d32789332af983a57889846946470d4f199e119c10f7d596c118caf4f2ba875fa64a06c3ac794839e1ef434cc760fe9338b23ea204f5a71850296c961695c530983774de5fe5c748f20383d1d2b8cee7ff0be62496e339a8a4eb6e73720ae2b36c85e5d105a3c950932ea9d86c2b3db860b6d149c731d3cdf46f0bd97552ab164cb26eaa652b5ee66264aca14fc306b2db814716d0f1f3224c23076714d3838207164c65256e94e7b42d3cae602e65639ea2468ab896580d53567858c194f74a4df8ab2c964c457854c1f8d1ffe2ab04ddce122a98cbd2c80efba78318a76010b2ffca76c7837b09111e52307e89119b76f9fcab838228182325fd9b955216f0808239c78b9e9f72f48f952798e5ddb479d0179961999d8387130c3329cae51cd63bc96f341924f06842422fcf621c030f26982485cacf7b48a3a3843c96607a5753b31234069f87124c51547c3cddbc637cc85813030362dce06d604c108210f095f64882073c9060be8e707b3a3df668c97dc1e308c6fc7cdb17ebb81c3f848711ccd142463df582ae24d2078f2218dcf334846bac6f8ef2e0410453e7aa4a975b1a824988bb4e6ff11082e1a4ee894a21f4c54e308c7dbb9643b9db48f081618a37b12e59857e61cc53162d5b12b71c725f186b3ed552c3fc92e5bc0614111dbd30ca8b0e49bd041d7288f0c2fcb7b26f21780a964cbb30d90911b4a4a02da8ef7591e75cd92b9872a1e5647fb612c7854105b311b9c27912b2dfa21c31f2a70eb3a0c316e6be9c5417fc24574a1203033d18630c5344472dcc9d35dbce9456684f6961d02968a8b78549299a85c15625260b53ce49a7d873652c4c3ae5ca93ccbaed14c2c2e069da74ce64e5f4b98e5718bbdacf7792fe77571dae30699af4371d2a3ce7dad10a434cffb8dc69647f7d32f6d3384304638cd1c10ad3f864356bdb5c0997d3b10aa3e5fba0eea49e19e85085e174e8f939c041a331023c0f74a4c2e4329f7b2c8ad0b1827fe84085a923567708ba7c63c5e544c7290c9ee6f24254ccc841aa91c68d33c8404d7498c29436fa417c45aacf3db071c6096eec253a4a614ec173e62d78e578925d1f3a4861eebf35f959234ffe2cd101d1c1758cc2a4c39d48e695547aa92c0af328e195b2495d0c1da130689c27bbcff2f711ae403b40610a955eecf3488aa1b78e4f1824071d545937de0639b041b6c3132695b835264f85d1a771e34590fa848e4e985e23453f51fe196798e0d4071d9c305dcbaec7db0f196bc4522a2303d9b10983f6a94b8a569d674732d68e8d336e9cd6343e043b681390232de8d08439f27ff220642713863989f712a29fd26562c2f4c94eb2dae9507fed1206dd79424a8f9c3aaab584aa23e62b4db850072a61d2da2ed692844cd94dad83128618579683b02c49e19540c7244c62419c4823e37fca27634d67604619356ef40cce6a7448c224af575db2bb3fde8f84e1841ed562112b749f206188233ebea894479867c4430425b28e30c6964e12b2cc8d3027dd2108310bf3fa3123cc5d2b41ae04a1e5aa2dc2a4de2ddc27e6841cd48a30b6c77f92e93a237212619ee41255b54584b94aa5646f7934d0061d87304dfe9027e6892779ad210cca2f0511b9301b3b29842959ff7e8ed157f33c210c9ee3e792131984399a668c87b06d7d16411864e4a598b33810a653eff944673e7c5e0161bc4e3aac94bef422437f30be75886a79b0cde81bd4b071460d2074f8c13cd79ff695ef1d731f4c3a7ae3734c5d7c9b3af8601eb153224da7875adfd0b10793698951e93f7e435ec618a30c1d7a30bb8952ba9245ca65e7c110d79385c8e94e2733e1c1bcf93d16376542cc10093aee602eab8a15254f7630e959f96c48899192b6a30e86a0b23fc71ef5cb693a982559306de95547a890be3107d365f5f021e7b782fa7230460e21fff563bca6280ea6b9601eb7930eda3c380231306028820e3898fbb44d77fa88625f7983b9e3267c7b753adc604aeaed6404a196efe28e3618741cf16f3a5eacc975b0c15c322a5b6a0f95f8411d6b305d57c8cbc147fb5dd5a106534e1777429851c971471acc29b376245af09c67d4810693b89265f1e2d67106731e0f3ab23aad7b3a7598a1a30ce6da8e961ef9e62fcf64302755af9274cb8ba5948e319894a5d457d9573d9a5087184ca6e25e59f2bebeb07784c17cc97b84ea297580c1dc9e6309d9d1449e24ecf8823154dab0681ee75e6387170c42f99ce890e30a7474c12caa62c988ab7570c16ce15497752a756cc124776fbc453fc2850e2d18af5ef74d05fb3897ecc882d9c4086175fa43b0bc93b156b2091d583078593ce541e92041d664dc681bdc48cb29745cc120b664bd8fb0a07492c6df60247458c1249e9752be824856e111dbbe362263ed460dfc8c8b4207154c4ae7f34a7491ef9b2103c10180091d5330c9deee284b21edd26a850e2998d2547ab31ca794fe3f0a86ddf2c841c72c31f291a1030a26a12a28efef70161d4f30d6571e7d227a6adc103a9c60f6d4a347848409b9e464ac1513424713ccee275e4b54aa850992b176b68b0e26984daaff4eb0cba3bb97e139406f63cd3a96607cf5908210da11a14309e692ffd68cdd8f5a0d6446d748c3df868d331c2f0523400108c6188334a22309df46d01e420551714400f0840e249842fc3ec9ed18255f54888e2398c37b12570949449f91fdd0610493d23616ef2f8fd277923d7414c194ac2e2bfdd9b67ae8120f1d44308b4851b27c5e8e4a7a1d3a8660f8d7c8edd194086b4f87108c592167f4ffb94bce81812318c6eb30c2e2538255489bc0010c773e8ee46f512612387e61b60a539dd86eca26cbe10b47cb9caab16ad4c0cb40a30c397a61baadf06217c6a485928c355e9894f6961c612732d65e0767d84083ecc2fc966cb764f9cea582347270460f1a0417c8c097610305638c91460e6e705217e6fd78b23d89989eefb3326ca060066694a183336c90a0ae56c0910bb3e849cbeef87061f25c953c67d3e9d3ad5b98635bf0cbbfda41cdcd610ba3951ed39da487ad7a6a610acbf38e60e1bb744c0bf3b55e165521b48fa924143866610ec26b525239fd39aae39085d9de544bf4b2da4a411cb130e8b855faf6179f4212072ccc398654911b59626285e315a612ad4ed656b6256b0e5798f4a7f411b4b3f5c511472b0c2ff973be37915cf671b0c26c2f42eca8a45444876315e66d13fa626dd35694f4c68d37430f8d326c906abc0eca4011b8a0060018c1a10ad3b6c9a7f6df6eddd2e04885f127d68358c5b67d97a83064b94f9f2646d0959392e31486590f49e280c314e6f46b4a59104ff1692e85397ad22108f70bf9107c3446200606cc18811818e8c018637090c2f8f964a8a8898ec214d4d57a5f885887958619efa2c83cd6fe509834b6d4723c670f7080c2587ad243d076291f1232d6d0b6031c9f307b780c612d2f7a47ed9e30a5bb1c1fbd7119a70c393a618e3197191ec2bde3be64a0208b15383861ba60e931c7b38854934d18437877140fe1ff276263e0d084b9e4e64f503365c2144786b22bd3bfc08109c32753b1d2449aabc0710963aa9ff097fc1de32e352c6132a1449f0877f996304725cc5f9574ce7f2ea38451ee2eb6fb6dd44426b1fa9998ee08faf693b1468ac02109e388ddd115f73f1a9130868cb8723a1f27fdcd0109a3e9f0ccfa0d353a35ce40c6f10843d2ce12ea16ff53ce7a60e3735002fc0087238cf1d9b2875ce2137034c27c65daa5df7eeafcba4119c8c1089350a224690ba14347ed171c8b30c8336d51fab4894990220c23f52585ca3825a3cd011ac57024c274255b95c389c958eb341a751a9d81b3438439c4d39c471fc958db47b7349694868d336ed80dc26883594250dbe1c43ae80f1b4c6147aa4593abf1c1b20653f64b951f5613c7623518bee3dce28abc9d531a4c924288cad0a2c198163d480b5b9fc12022e6b283f97d4a9ac110abd2fd7bd3329854dda4d86d12321852f27ca3151e4f98c6600e537fcdcf5a621783b9de47fe23c9ffcd1806f37cfe9f705142550583d1de4b46f768651208e30ba6204743ab68ef05c3c758b270739bbf6417b0ce26d404317a4789b96012c9ea2b56ae101e4f1b67e409630be6533284058fe4215ed1824988faf82d162b744a66c11027cb4e106e95ddf5c0461a663c89411858305e5b95eafa3afbabac208c2b983a3c5e88e65ba1d5b182f1f397d896ac963ba5aa60aa160b299274cba57c2a1854851439cfc147dd3305d3dd7b1493659182f9530a2e63428d82e9f4d9aa7cdfc51625148cb17f925372fb1df5134cbdd96155c24b92f085e104539ae7f5b0939d208c2618648616e126526ecb1e0cc26002f6de273bff787f7210c612b09453c4f7ca49fd26c377108612cc7d236e7e157ebc2c1784910493fca9d3eb9d173f289d9186191d20411848205dd6da35753a0c8871c836d240037b10c611380c23a8f9e93a240f855104d34e6e65ec056da4814618443098dac9a93a23faff52e36d80c60dca40038d36e30c33126da481068631041286104c31a2f5f3920e1f3a45c69a06c6182318a6687d6e23929c6c42fc018c740827dc7d2f4670f0f10b435061ed93529523a4f6c317c6f413c9d94ea6ff5b7a61ceb7f0218f5e0f0b3f2fcc25ce639998eff0b6efc25421897cdd7186c3872e4cb32729ffc80e2f415d7261f6eb38aa53e592f4d4bee10317862826afec736b753bb730974549410715a4a6986c61aad634fdf079265abcd4c2ec914ad6a79fe546190b820f5a9874d8b8dc7df92c0c2a7fbf1fe7e9e2c8edf0210bf37cd995ca444b2cccb61e210513172c4c25b994b6607dbcc2b415f9b5a4e7ae305ef0fce941eb34444a2b8c559b16174197a710b3c21455a26bcf9fac45c9c72a8cb2f19fb2a8bea99c25636d35f0a10a735f9a9790162d7a0eb1c0472a0ceed9f49da77b8d7f64a4518619638c199851061d3e5061a7305d4e397448994fe2ae0f5318258e38f9a92b87b7df818f52900f529852860a9d6db370d9761406d7d1511db449a9f0210a539e3d95f2b89e1825e64728cc215c298b1eb2a030b75558fb089553840a0d1f9f30ad87917849a924af2f9e309b6993eda4e2de32a265f8e884794543355efb635cee8313660f3e3a8470f98f4d98ba93c8ac905532d66a70a3d3a8516ae34313261d43cbeba578e1b3f6e02313e63d19c1d2363624e8c607264cba7d9dc289741f3e87c6c7254c29e5cb49930ddecde81b669c618605c618037530c618a800c0c587250cf249a9eb590f495755ad84c96425bba4bf38418614111f9430ede8a5511d2d859c3a0e1f933024cf8ff6f24149bc21b14f99928cad8183bf71fc1109d3c70f22debb95c6dfb861010c70400c0c8821821168a007e4111f903048cf8e2621761e611295b91a164e7bb54a8b0f4718ed3bd88e078f7a154d679c6183046cbbf868842145f21073f11da45a186110f727721e7b89f7e5224c4129ad7f31354518feab5a23774c909927c2a4cbe646cfafb347bef081088367f7202c99de05391dc2982ad142fe4ba4da785cf830c47d14c2a4a56321f444de9e9d091f84307fae3c158bba222ae4c2f0310853b84bb5753da7eaf282308a7653e13c53d72a1bc147204c2d9e1fc94b8aecf00c3e00610a6d12dc428c94feb7910334ce061f7f30ab8974fa6247c6a9948cb51ef0a08c5484061f7e3045494269fe763efa60922c626fe9bc2284341fccaaa6246509eb88f51e0c1f64549c9fb01ecc67b222f2e7c98339c99e252d953db6bc2a7ce0c174f59323c7506175d28f3b98b3a5eb10dba10f3b1896e245855d4cc6da1563c1471d8c15cf4c7c96243a986c52994d1a1532d66e2033fa0c4f061f73302595836f9c0e231ac21ea45106213ee4600eae5931b392ce103a7571c074459cffb87e95ac81c68d3a7cc0e1f5eb9873667d51926f3042ce7c3593967a4fe30469860f376479e27ba54c64d369433733f14f48bc78c992870f3620ff392c8d1cf93da99e1a3ed690b2a85a97730a4a203ed4905645f0f865aa19c23490beb6f78325870f34a0426cbce362e9ec1952a1ef74e912bd916f0d1f6628ccb9fccb778847e7f0518666b7829ad193c2a8c4c08018221003052010030377f82043aa6a219e923de1630ce82efdb394b23664031b29e0c387183c73dd0b27bb33d20b43aa2f1792b42fbe3330986639463b2baa46cc8ad9ed21044be1e1e30b065162559e23e9875fcaf80037e1c30b0695b3e4eaca5df615ea8239a8357517a16142ee5c307ae9f270a65aa9287c6cc19cba2d651bedf92ab5160c9264f68d05350be63c31dfca7a7bed2c5830298df89aee6123c6750573be8e2ea2a276df3d2b186c4bad2aac5527cf84955f86f041059350495dcea65bef43ff988229e74a9db746968241626b8a897a11d1520b10a2828f28782962425a8da806cc28a36d6440a16008ba744cbace4eec0b0a1f4f309dae382295b897f0e104939abd0c611e84c930d9f86882c707136ef4e06b50238c8f2530e0430908f84842033e9090808f23dce00602f830c28d1b6f038e8f2214e08308370881013e86501f42b0810d1a0310f00886033c8051a30c342c40820f8f5ff8e2d1195e2307bd3880072f6c6083f60178ec82c3431765a06181303c72413c702186c72d08e0618b5a24c08316350ce0318b1a65a061811b3638e30c122cc043160ef088057bc0a2461a08f078c58d2fa30c342cb0810e0f57d428030d0bd8f81ad83863056178b402fd0c66d0288880072b6eace2c3431509f048450d0578a062001ea73080872908e0518a007890c21c2ce6e7be2c29d6ef0a048f51182f646ea5e4c87fe692b1766383e0210ac34910d533b146e68743612efd1a4943e5010a939795bea825f4f8842188fd91952304356a2a62a06003c80c0b8ca145f0f08441447a4bdd0a69545f88e0d10973ed6b856fcf17365f74c605dc8c1c68608c1f7870c29055b4e38ea4cf61271e9b30d7759ce84e5ae5c08d31c6f0d084a95b2e4fe4f4f1eb7c076760608c3170e0910983b25d55cb63c00313864b52dc7c3b889f1cbe81c7250c49dec48a914535f0b08431aec4884e1da37b66b5107854c298a5433db59f2861aa39cfa5b233099387081e1f4aa83cc2968479c4c4c68275f49461240ce7f9644e529ed35307097358f12e91bbec3995c7234c62f27eec43ac7a3db081027f1d98230cf9449a96f9eed108c35c3c7d532fad6e71469894322daa1ed4a5057711a6bb0fbeef29238ff03c1461b2e8e2315f65e75d7924c2b4399ea59727951ccd0311e6e46e2a4832a14584ef3d018f439836e5c3488d943394da109efaa8daee17c274263f8f28bbbd9315214c725ff9fa3482463f195c1e83f0f36c49ed3c046188752a0e84498a560c08737b96f18963c2e61a68dcfdc1a43b82be9b14fea94a7e30e8181f6fd4c99cfbc4a30f06655afcd26ae8755ba306fd364eda7af0c17cbd22136b2f1278ec616d78e881a453120b0f313e66f8028f3cb89664a747ad8ebefd0a3cf0606338c2e30ee6203ee94f6ea2ab82871d4c7bb22fb6f809cdcfa981460e6ad4e08c336cb0251003036280400c1480a0e8c0a30ee630d76e6b13a2e731d1c17c67d7af1e3c8f39182f088ba24c720a49a1871c4cf2f9ab3a2996a59c338f38a4071ccc39b669b57791c71bcc7daf6e2a2fe8f627b3031e6e387d8affb63b95b6e191a4d54b2663cd6dd4e881196d34f06003713f69d3b6ce93dca0460fcce81a37ba3230c618376cd448e346bb193b3803a1c71a4c6fb9748732a9c1aca743ce97143cbae9a4c13c729d2a4c84892829683097aa8f92e44b1471ee194caab2ddd26a78bfb966305f4dae907a30a9bcf72123e6e1bab0248456c933e1c19c435b78cf967758558488d2d9c15cb2ab73964f12ecc63a98828758212b6685db74308baabf8e16f2dce53998e279793cc92feeaf1cb8582faa447fe26090951622fad4a8b41d1c4c4905d7fbfe10cd4c6f400303dc601cbd922d0989b5c1f4e5397c2fc60643983753d3f521a4656b30ae88ce3ad594d3613598dbd4bec47f7acf621a18800693d07be94756673044cd0d8b55fb494290016678bf52366de16bff736528cf579678f82af7c9603c393975f544977cfa184c97ef3987cac8adff88c1c9f1b63dd49f9b1e065318e97a39444f0c910306639d99327f516ae4ec2fa47223e547574b222fbca572178c3e422871cb664a81015c684f655d4656ce16ecf3a0f447bab72d5d0ba5f39c6654d6d6fecdc2215bd6c8cd8b61420103b080a7d71c193978fa5ca1ec17747c39252b14d143845827a2df2a5c1e7794120b217fa860921842bd6be9cebdff144e7edfdad1df3a2978c1647b4a416707191085435ab38a58595a3b28607f3259d4e49ff8099f095f1d8fd59d7342365676a31d235e450c6802327475989409e414ecd4bcbdc29b4b40bde3ed56deecaa90014af0d2884a27843a71332009a59633292a0c4002f2e3c595fa08c6d1972c45eca4b4b2114cd1f524c50929025a548a949245b1141b110c42c9f814bd7df259870143b83d82bccecb16b34d0c10824107d321b32b899fddc140e959f809d3253960984388da294bf40b436eed911dd717e6f41c948efc25556a2f8c1bdaa176262fcc1f734df4574ef1bbdd85af615226e88aab31e922bdf1a32d5a59bab97023e9911b5e41f85db8f092ef9f0a8d6fe155ce3cb3493b3a5b90e7f5926ab530d8a828c172e4f7f8d0223b1d2a84d12c0c415285121e4c59a43a480b1553fa7b2c529193fe38963b395868a63eec45ae3a855f61d2397c8ed45859dd15caa46829e47a044b2bf8be5049c9911c2b5afb4e6a3f8818afc289a9754a45d57454e1f75bfee55829ea5498c2e6a4921d0b3d294385c14743a7687f293f7d0a934a21757eb1cb7e2f0a0b30853959c69c8dd2fb29924a610e93e396fd8c07ad3f298c7edf4994b83841c43f0ab3950896c34b4dc4f84551bec88c89cb6b288c236eb3a22561541228cc412b451555a14f1892cab7b9e81f12f5e3098350d9bbde743e7afa74c214cf6d5bf2af085d36278ea434bfbf4cc90d954d18cd752d9c12b226cca73b2cb4d794fe8b33618871134e998e1f36c5c47a1d2c7c76a77bb92f61d44d3d6521a7a4476a0bb0844949cb4105f949859754c2146a65f2c84b29615e8b2264a77021494a27815097f36479fa699230473bcf22e6bafd4a9130e48e94cc2f04a57d26244cd5e7c1eb7de7477f8471c259289323c62b4447742179b776c5d04a23383bcb95ad14762246182ea2c7bcd32dc29c6d5bde4f8a307f9555b8f6dd5b3711a63f53df9e3e879e1043c42bf1b4f34e0e6a3b4431a9bb5f24ba7c0c61f48a704a843f1d6654089334bb4f2a2949f22d5563c1b0004218c2e85c219b31263b6510c64ba373d2058f2823fdc2020491cea8c9d9de06820f12a2e7ea7ad30362dbeb2c1ee1dcc72e7f5075745ec9048ffac12054bc4f1f9e758f9b741525870f86a0e452b22e8fd41dc28505ec61ad2d9110947a3858d03e696363ed3c984f279d922aad9d85090fe80c2dfe3d498864f13b20d2da32353b989386fa89abd317aeaf83a9374f74a8d27fca79d405cdc188223b25650d9197433237794b88fba97148a86ca9f0fb210d07934edb177c674d5aed6f604288a6748aee92f2c80da653428a9c644adb5cde0663a968699122365c2aaa04b9db1accf9469efad8cb97ac06c39f48a583103969b83a42b85cf30a42868682cf758844abaad319ca67deb1b47274a66d06a3e5b0f859d75b6997c154414b87d2ebc89029b12be93194b52fa6a9899dcec2627075c6b32aa4340a83414e6acba9d34c4f70c1706c91ffa6fe73aaacbef004b112c7d2f45e30e55877e99d4a871d912e6031c4ca88a813ff5f2e9c75733f29fdf3d942e761f611625eda73b5902e2fbfb2c05fee4fdee69d16164c61299994246bd7737905254553a3c368d10d1d2b982d455d2e76a4492b56613797943ae8a95088262c23a94e5f9a42e2af33e3ea2c2d05d3e94b252feb8b422259758ab8bd408124bb4edba40fea53fe09a674314b926c277095527487f0f14b13cc2656742cd6ae5a9609860b1aaa4f65848fb3b6b0802598c3cb271de4eb93ec4a30bee59b28426c88d1a62474399ea1e90290505297bc69c9439ab5802318f3928909cfed93928c6038b3f8cff98b6048dda5eb927b2298820a226b5c12b1da1e8249567cc9e593ead287162004931e35af95b907031193456e74c0309d9874e661ffc220bc4e47febca4ea7c61b6cb23ed428d900b61f4c29cce4a5744cdca5e7861ee8bd61d17f35df8f15794c812d68549a84baa77252717a60b49b2246dc28529277b95ba5ecea2ea5b9892127fded52962a98a2dccab7a9a922b5c0bb34dec54c14dbc63480b438e53114b446761d2799de593c3b996b228ba08eb148e852a13643c448717c1c2bc13b322aec809dbf815a60f4946da89743922ea0a5365bb9c9cf89c2bc55a61aa5211b34e1d46c594156978bc8c972454d7ab30e54ed172c98dc892a20a9398e0ed274723473415c6f6cad3a67f54186b52fa58e74e61b214bd6db9f4fd2a628af7de53bcc25218e5ef629e5d69e47c92c2789f5ac9e36514e6ec14bd7f3d8ac294963f8c94a82a59140a7d4ba48fe381c268ee6945825be8b57c828b5f732967957cf27ae21e2d173d24ffaaf0e984499f595b291155173d4e1884458be623b409936e957a50353bdfad268c575244c676eadc936782ff2a516d499830a9bb49f95a5498fc12bf889b0ec94410a9f49628ae47bddd5abba412c6f932955a8424fdcc28717cd3218e9787f52661d05177bbe32e6f7e4920ae3e4685302281c93ecb275de6d49030fba85239151fdd6e91b1f60843bec8a62e7e658c46df00c370049eea6147dcad2935824932e691bdab2a8597a0a1e24f55901f7ee5a61d86c10893a7702742bc24f36a2fc2e83977989a7db310175b43188a30277d229e68b1a04350224cc9f3bc696d57080311064f41a9e77ab50baf1cc2f4621e57c3574318249d909594c8dd33b24218b3439dc97a09cbde12c2242c5bbb6ea73cb9a04198b2754f6586ba76d205611256a35f94481372cc0361943c4997d5a5957705100639a264d49af40fc6d1b553f14ca77799f8c1f8b9f6e1aa651f4c91e25f25f93a1f4c49a848496c3c5c2e59187b305ce94e6a4bdc30f470505be16ae4e9f82935100d61e4c1702ef36f957e9382e4cbb081827c4018783068939fcc4324a5aa5abf096e9c51469211c61d0cb1f77cf34cbb8248dbc1a0643c3b9c97e585b80e26ebed1cba5e9e1cdc58d4811f844107931239e9fc217ba553a13998fb23cb049192eef33a0c399874df53437785187799a9851107a3e6884923adee924e8283713635df82ee1094fc6f3024cb101e1e73371843a7f0ba038d5ea8f4af6652612012070402711c045248f51e00c3130010404078441a8bc462d13c0e85e1071480035228245836301a241e18161808842351201404844382502010088541814028240a27e196ec03ab41f74a5cbda0cf38737cb323ed8a86cfd25657810116da0600aa70ce296e6ae67566a0e70b7654604720f737c5c02e0d64724730741c6dd034c8fc50bdd6880191268b4923507cf74d766582231df89f0599770a1a4c373db28b2b0e747984ad00cdafcf08c0997b5e6e6eea267b805f181beeb6aac9539bb444f24f37fc683c9ca949faf447fea535fe479cd290c5f455fae73b6e1d5cb06d98220fc824eb376fd0c1de1d4480b743ac6e74a47b0f15e183e4091e968a808de6f2541c8e584911c341ca0bb86b6c938d8b7c3c2b5b544b4461523983f31de5922592fc69c79a4524c8671d92de4c7e09eead39f5d4bfe1a94df4278e6c79a33ca999541f6dbce7ee7fb86a418d54ffd00120f8140dbc9d22f28d7ebb9f1dee3f4a15f72cbe0681c61d3aeb4ed422a08aff1d39bc1c530481076fad49d9cbd92fe58118611efcd5e88ef6c36e3b08c946c14b908e148a6dc8692dcdeb6d7b5af9ff140f940d20c69f84ff2d9748fc199f7c0bb77bbf8d53bdbeaf305628eb7dd3512db1809933c2bbff7a5fda6e21c36a472e0fb4d899ab41175cdde6bf844c934671899fafe9b6045225aa6d60af4015ccc7662a87ee9f1d9487cfe553ed082d1c63fd550089f109f0a6476ec7a7ad90111def3be9d273a26aa725beb92225aeee3fdc6b4808250dcc5ef550e2b79094d8a6a18a5a039dc6d8357c3774190f03370365a7a63c1c251171ae9748682c174f23718da31b7e8203a5cb808e5808638d4d6dcc72b807b6a18fc51b26e5a233c7511c35f57d8d463b36ca40ebd4c484661f9c80837d1b25c6513ac446e73ed07f0e9d13fd339a4114886b7d702ba65328781a479cb5bf8ce1ec300d47a91f363af189a59d4e56ea9f7b9ab99c439bd905f5c0513afead53f1b3046c811da319a4ac96a56eb9ed2007c14672098d6710e0e0debf6e209b3fad0c9146ff7e6189d501df8bdd8147ca7b8f21e8e05ea2633757f4e6f3966859bab60e8bb5c1be05cd7c762000b61b38b6124703725a8808cc2d040efdcba015185262701af9e67ad7d2d63104284feb64d6eb5f0993002109aaaac1112dd71c4e6e0b4bb5e4d97cd9d90ceb3f0e98260ce2bae69033045f53409dfbba11a06654e95522090e53da0559ce056640975de35c9600f50932ddd94450109a84a94701587bffa21592dfb9e65012a0fa4773ae11140ebaafebe8fd28132685d21eca13d6a10f9ae18ec94421dc56084c35c66e1d1eca59547ad0fc0ec170bca1abe70d078bd5c17ed7772e7effbd63e4f37c520dc8aa5b2a5dd5887f3a93080e6504827ece1014f80622f0586fd0d16ab76c4055f7ffbba49c96edef3a47c98e35851308cc6ac01b602cc3fa2f23a0a7e6a87f02ed28826339280daa37f1d8ef6e28012ac3b7992e2db11c3c4767b0fcd54f9a2def88673a7a85ad3d44afb14ac087e5771d3c87903115f818a8250e062f6d1ad0383886173cf08a56cfa2c142da31174c58dd48e3914fd2ed80b49b531898070f7670907e822dc10d19421bb4d67440104da63b2a891a3ca4d51acf651f3c71e361870a357836b71da9ee74a069a5b6fe107877373c9b81ac41405283634e106755661a13990f1ee43a58befc278558c50436c5fdb45d569720729a7cd112c1206b628641d3171a19641d5baabba99dff00902c5ce031d27cee7732841421211974f0002e3e1cb08387e50c1a123dd7dc2192f560b40032b1c1f30413780ae0e0715db9d5c76af008ef83c6ed0f548e6a0d9ee7a387811d6507cb7d0d40fdab60c7a3f11fc20d9ec428864318099b40e6b307b4583b067722f1f9925eb156d5cb4058ea76f8be871624460c1a0669aa32683c0155cc4212c68ee001f6e97a29fa702c27bb2822a855719d837524ec18bb7678848d649a3dfd5dbbb5ff0073e0de55a38c9edb7b04a6dd12d71b34ae2dde6aac54b5f57a3d1efb775e284666143f458a510dce73dfbbec702304ab4c344334181886046dc4a1c66408a01c8b2d70ae21424e16835246a5346d0dae1894169478c33b565351cc4ca7e176a8e929d2614cc0e98350313f9e1584987a8375820e80054cd8f0c08b0e06505803113633f98021e3e088628c88c30ad93daa20163c484fc40afd50a4bb448f3255450e5a401a0ccca1b83c4e32bd7500e94f16a58d3b472e6c8135694c26de69913c7710d4a8ca034d91f673434fd44fb3e5691d2add2003467379045a5d75f175d3db4231ae012afab4ff57c033658c6d6d4f6eb167658f7e374eeff55ed2110f629d4a028503cb647c662edf598abc8f49fe9b384c8d9fd8c05cd5af0d549d3c550297945fd5da01e83faf6967c602eef7ba0baa36279709254d0da59235a64a31b69feddba8ab7b6a2354f20fc11ebab08f3e441faf066b10ad9b25ac15ca5516837a0861300f507c4e244389afa32cdffd7e37eb3294eedd42b1644ccbc68a20f37635b74cb661cf4e9445865d99cbe342c009b91a06000b63ff24116ce487b11a992c81c9b9db81761434f949930bdaba7bbd6c038d55283df3271dd4e7520c73008b4737df2c31aa1888f3b0e1878b1cf0b921327884844bee5a714bccac1ea25bd7f0f11e1b6e82f1d96dbe6a0d516fe8d1912c35f05a0e75b787ed813de8600d653d9c6b17aef7d2fbf5809de265ff366719869ee80311899639a26019e509f8151c866ae27e19840b2463f1408e11784a253050c4c141771070e9670e5cadc8b03d1c743106f610bc51c4fb0a2262485030b4fe61fa81a9fcdffce8654d55a8bf96213db4db24e8f92428c50414d5f7ea1db0927440a7dc31df51da2554386a7a54a906b88bc36eae965fdd8d8657d007f771fb405e35798557e9a6009aef56e2fa71caa281d2d71190a7f09990632fd0a90bd39bf0d50cf8b1a02981f8f9c18c838a061083a9012486c106702d84a56ae81d3e989721f1561cb282b4b0546640a1ea5e6d8e9deb6e2e06331afcc76b697620892e0bbe5e4b2457166de73ab573f8611a1f80b5d6c422c073900b3116aad24de0f3a0acbf719c3ea3988b7180b8014c160535c3871bc6433615e2ece25ae9c9197d090c624b1fd1c0c0dc0a8286d070801706b12c6e587ff95a8150da4896b50d079916720ae98d2bef454ed81c969944bc4257c8bc372dd3d215fca33f816fbabd579cd2d0d56a60667ef624413aa08a31415638ea0526713b34d30661cb537620f9b9eca9e0ca09059b34e11691a16421408d55bfd206f0b868ebbe6e9524a87530e7eac8c8f0a3b3d3c0bb8ec320c000eb4b950a0f5a89df0e3def45b0507e33fc65716c7f25654279a5fc2bbb791669c662cd9ee4aa39ce62389a39c175a76af872761a0d7d6ba436037aa1d7973c62eda5b1aba73eda03bc29ad35bc4e73cd0d34fcc2344ae4f6ea2aa4ceae9b1271ca760f1dbc0a03bcb7fcf552b02ae762167f9c545a6a41dc9e7235f35e42152451c14d5d2e2473e2bb1a7663b038cf79f831fbf1a41399f39950df4cfe176f8f416ac5a09f7c098a38c98b3c927aa2fbb697f0b31de0df2935f1839ad316e184e6e2be53b26e8ecdd88875969f73193c263885ec0f809f6c4fb0f29ccddc163e0a369d4e211774edd66eca0ba7a4c3ed95a8ae40cb70c1c693aca14c43ed386b24c54a524893515afc1fe2048b2c806b04fe8bb54d320e34542fd88ba4066eb37e8d2dc3d1c5c0eb4aac5923d9a76f3f610fbace67f550b5203e31a6e93cf4aa2ceb2eb429338628bb8c8d74bde9079364008916d853126280f980d9dd74e40d3449a65c58bb6e46b691fb52791582cfc56098ab40016e046131a182c29043533120706c40423b3d7a72b4dd417623d49548ae078f503e39425e044db78c0b65a8d5c12b5968e9c4897ce33b75f273e1bcb07ba86b3680161be25abeb05cb2cc30ea5db9a3ae57f41bbe72e94f6d8cc3bab49f93700c6dee1444990c542a8153af88f10494ee60e068957e8b5f945f483b67ebadbff389931e049939a0f6dca66cdbcc92fc7af95ad9d400f09e415a5ddfaa0ab5b495c9848644c8e68e964b84bcd453f28e142b58ac7795d12f3f0f47f20d966f0252cbe851e5e4eb152a546cb880600923287414314b9bc651bf76675cb6ad8129fb192e57bd2a386935e1352ee250d3c45bc5b02d53f201f0dd3199001ac0c98be3486af99261294008cbf83dfcf5f828e8867b750a5a3f6199b715c2a3b2e9fc78cf446b11896e53a15d74145014079aef2c1db5058166d1039dae12685e5f4e9caa0f973d08ff0af43e3310cc9a5e573052ff7610ee045b505e49106ee9dba0a4070bb03f007f417c967e3c455356bbfadf7ec49e47a40c2852004a5ddb1ca97bdc04e43cf650f8ea68bacfd829b8c90f0c9b24186e76fae090eb90a0007ce265734afa1281e43bc97fd59f05333e36138d5b1e2f802f83d18091015291935b2a23e02553970a05e55fa032c6cd4580f27fbe48db17a7788e5ee6f4074a331de655c63453a71d691f68a42db119e9c977de2b076dea2d63df8373c0090794bc017fd689b3bd7bb3205c9c8b9b60ae44a9c961ecb7a156be601ea334a873a870dd16fde4c2239bb8ee4788ca3b839c18cefa2c59b21f019f0b37e30471098be5daf339f81e07688ebea1e0a691e6851d422d3b74aac8d33de2ec6894006daddeb1b0448d6165971ee04a4bbbb7465093ab6950bcf93a930e7c00f8356e9d1bc67da851e07b79e39a579b39caddf4bda6333dd9c46c2a72cb2b034b261e209c301231cdf434b7e828f2c7f4464fd6cde242445cfc43c77ffb02800603bbe3c6fa133f04203b8a7d5bd1cec0efee9dd082435a3fc13bda89336040fa736b11e51fe7aa5ccfc20a6507c42bdf69fab2221e1e382593c02adcbf45b5add7a506c92e9ac02f51e620d37209ad315b59ef012ad22d3b3bb85ae67a4ed1f1a4a12c901c2549273db085365ce1f769958c7b0f1bc64a66dbe8318deabdb8986dda60f4b6e648a3dbc21263225b8b325402b39f406b7d23937360fa309a5bb68c60d1beeb67800a3100047ab552c63c5f777bcb8160ed2d0bcf74bd604723d4fa42f45b13874e9e95186c43835b3b80b5b1028acec69d0f71325de08d5327e9d8e0009896f340190fc7232b2991e1bfd1ff4133eed2cb74ee46c98f7b2a170847355a911f9cdd4c6c13ce38cddf9f9da12caac149f750c72238ede31641f0183f2e2bdc266a4f1823b01a888fa2f31316897220b27bc7461daa80cf6fb489f53d9f93ff6482e016258325523d4ea4d421566ed4384a3db5f5d987aa9401250734f5b7352f0d87befc1dbe41c92a4101e73a0b485923ccf99520071d634a14a8ae50d44d118de7a11743a78e936444da33f07ce3fe6a5bac02c14ee24de0752df349db8d0b2c2ac6960b8c58d3338be231e3a0a641c3a8326240b4593cde9804adafed63a74f0fd12b1a9ebefe57a445a814301addd9afe8522aa3f6f7206153ab1e480d043dbf52f9057adc890c5942f3801b6852d1c845a1a404a83efa945e3860990f826ed5a85574fe5182748320a55046810e52e0494a23c9f83c18c71a462c071b3903cd222be6baa84c8b9e44de1be90a54b6ddec20ee637e4e31337b734f05942b1e473d587bf3a711b1ef22391f2f6601cc8ebc6a92d684e72b04a1c99113ba37d665d60d8969bc13a5ab1da250b79960f23c0eaeb799deb659c22b917ec462a4f3b1a2b332cb16885033f106b17d04d12d2821d354305e6d04ad0b3bd3fe31488089727e858e118a5882e59628975ef7ad0529ad1d58b22b32c00a852d7d66b26225fae6fd03791dbe0992d2079d71b5e93972423cc1c3b2c4750307e12b136b6826583a11450877eae119c3ca6d26d6660276bb2a2d51445e14743b1465846471ebc9a8820750ecdd4133e7956a89034b7b6b427c53840f5ba764501366f91bf26cfcd4f040c261466dbbdf1880781125f3c2a946a936a61697763341490cd65e0ebd9c712e71224408a6210b7762fafd5faef3a9a5871585a6e94033c199d77f8e7989771fee7191990da6b5afacf4c3f5c67e0fa39af96315f44d15a02fd8e7cfdb37831e87e930a81e882b293284689ba1a5c3e7126bcdb4498c5b045ea120e4abbff1b4eb03c1799ab56e1155ae0fbad636244d1a9323b50fbe84836e19a98e52b5a490432a88d2a294441f4d16d1ced6ac6e02040fc82a20cd1b63b2a87f13c12441a199da27b8da08a9822f645096078ab13d8ba83e78a970596418829f786a24274aaac14ce13bb6909a26a42ef5ca50e4af0810e51f85df0ae9e7e0f9a9e749fca9f2a7cf816abced80cb722490ce22b75e441342ef96ca933641dd02cb38aacf8820ddfd85b9385822e5bba7ae972a817df8a66f96db2666e915ae768423ec88f188968a321d62a8178964af08cd2e104d774a34a87c4d4c00fbbb3834cd3a8b2626b0a015b393137efc39fd82249d0b67ad09043473ed2316bc27c142f254b0edde9f1805ccfb2986eacb51f67499b124b08405fe7f824b6b39651a4f9d9ba8753a5b525b5a8ac00b4ee70f035ccd38751480f8833a71680278183e8aec9d776283fdcf445b71abbbd05a6896653bc7d651ba5c680841eedc27a3266ccc67411c0b458d67f63d5a6daa13f31b62eb8b55f5c155ac30873801bcda2c0c6726a64f54527511838329578edde956aa40ca0d8db018d20f5a86401b8f2f8d5daaf7edad1667e97da463b3451f9e66606912225bf228fdc820ea3db5d6baad7c2905e8c22a22ab237645cdaef6db8b36dc9dab536a4edb4b8fdb24f3f250daa0e47cf7924e1a51b890ba5d81fba2d363dfefd2e90bc52a74320796f53465c2683f8be470ab5b2739c76cd445a8f2004b672115ecb8a44c7e29e2a04b4b5c07a8201c512357b4297056ba1eb08f706e259408c3fe2778bfe47e5cfdb356dbee57a0b07a26938e43e3c81147328375778c26e7706c74920e3f8c416dc7fe525b4b781f7de7cdcfd38649ffc9e71914596cc2a1a8a9b1ca11d31346982a5e898880c5dc092585f19bd2d171811440a85995b8fde6b4b1646a1e6557e3f4c95479690c1357fda02fc43e872074bdde2f020ab9647e6c9210bd745e1fd1f98974459fbd8cf1eacef6fa9b5513f524b8e203631c4d520f7da9f0f27153f976a125374edcabb5ee2b6024c33b19fc9fe2bdde45f3619a50912b174cb0603c186e61e065092a62f25757e7a7512276899aeea41c12eae45a019dcf612222d2c1b0d273a91d172cb93288c354e1c76293fcc7d6058169a804abd08557db0a5ab1086082fc9a4b7a74bc324dc109486c8778003825dc43babf0f8f04e2df4c69863747907ce3acf49944c82032de235bdb5a32fd364e9f13812a59aa92c1471b97eb3374791cce52a1e011231eda1f1b87bfd4b192eee36f40b89ac4525f0803108f2738964fd711cc844025c304b5d48020616223bdf31aa4dd557ca1931068551223374dbe4f2668037d05c35847884055e3ab5c152ce466865d15a01d3d5c7b02f2b1c42db858cb49d39143c96426b9a6551b5b90949f2eb87631757679534d21a64ddc36db3dd172c3ab28e378646efab7b6562cb76fe7e54c62ad2d6f12e008c49df8e2525a89169d3f409075e6221e99a93a6a7f463960fd47524e9954df4f609c1ecbf7f23e546e6c04dc4144778635ba1794c04b00af52d6d32684898e9317bf3b460627abab17cd42a055b28fd6e2d58f5a9c6df5b70d09596a29272329197c07b0433454bdfc25c02934e00115eddbd462e4577f2ceb67c44982d2c2b84eca7652f46466548bcd9fb28a60eb0f2941fbb67b2bbfc6d21be3379eb37bcf56c6b44ef24f50861b00de64cb3d6b0c060d955a50f5582222eb2802b3ed1de51bb8af2867d5989c45a92e7c7ddaca24fa404690d4bf5dfacfac2a22c0b7252f2e57fa74e02eea5a1b9797490ce100e487ba3bb892dc693cc60c27720aabc9e8057dd093b5d4d20505918635a1af736eada7b781254afbbd4a94c720f1f73e786d85e86d327affc96c1ceec4e1b28c70b113a61d5a5d15cf859471f435ec632113db6421abb55c6dc95fc8740acdfbaca88f5f52cb5bc31314b791509b1598e3773dae0ed3df6e13fbb43d6b91a1609c5d2447dfd4c8032d083b921e4939953e954a1c63393416d3a1d83708a9cabdd1e34b7bc53c4983f97742da9345aeccf5ee4f454e77c883d2314b1c6c65c2a926b63776e5f2b2c95f4d47ffba37c9b6f722cce51252cb2db3d87c35d2e5d25f778fbd950aa35a99f94556eeeabe5e60212c8484b072b5881cf2791bb6e618d4a407ac5841d1d84ea0053f32eb4d4e4abcf8dd8adb4b8f7d8e4122b4ded650b64245d8363663f109ed85315872e1c3c94dd2fbc6841a0845564b617d80697d51267c3827b588a48754838bd51abb13825cd36b931d0aac8503dc661e99c20946f185361dddab351e32385fa2ceee6c618b20a4d58cac8efd71478dc3821f1b44ad685a1a1d05bfe0087ca31db53adb69e9a4373a72901da6b761b2d5b04a470d90d312607eaf6189a71e1bcf7f79b9a58cd4a763a225197c3578f2f79646cc8b05c435740658e9065bc7343a21c4accf676c40cee25ac331941db3d2b6e27b3a44f56a9019e9e3586225ddd1bc29dd9b1a29a384e151a30ead38fb03236ca6dce87d46081ac9c54ae9254f70d22773c86f2b8a151e89f9c1fcd37dae479dac3207c03324a6dd0a65bbbbd76482a02eba30b02f58699f2cae7246e94b5e2a98c206435dc03cbd31989c0a83292745c8b5c57ff0749402fc3ca04d964d99a6fd5797b90ad30eb9b7b31f30b9fe80e2e666475596f17709dbbfdb54212d0d1a99f1209dbf446610e7b7f15370c45d8af465fd70c690045e0540c0500a3b81f489fa60bc869957c5f51f10e2e3d38beb1f8cce010c5b01ba2422421045219cd85c8ff667c460c49a519b94da79332ae6af53c562859499f8be6ed3353721e334b5087eb2ebe2c1114d9180e9779a9d3f1ca20477a6ec856c423be0232afd67689ba661cc549e08f75ffbf24fc42d234994e66470d1ccf7c48f86a1b48a81c4d61181019518afefcc281180f5d19c45e3f59d138f45c6ad546715851dfb6b8def5c350c277d8af1b072bba022bf1b1f7e1f8806df8ed2d6f6dcc4b30fb6e1700ffea230b5874bc89e9102d1629c0056438c1dd1e08c00abe1c62cd1e48c001535326ec0727683cf4b60bdfaaa56b9f5ba5064c2973f1fc833b148588970712a192edd4ee483f698fbf81a6fac471423c4b97aac52119ae5af7846a74f314cf587c0d12466d756890513df5c7fa9fc18330832df9f8473bd3ad7c1bfb6e6207ed183e4d015c58b5fdccdcdaa1fe1e0dc8b9792fe1c8c5933d91811967c0fbb31678d3fc578f5546f90389e232861b30088774d8a459628238c8554700599994923bbcdb7137eedcb76244b70f044c59f7e105a3822bfbd42e8e8b73b93f2c54cda5835738b51af0782c0b50fd6464177b85e414aa2b50071e2949954e43b0d24711abf56d6e800ae6cf8231d20a8e9ef672128b1fd670cede931905f65c8840b4c0c99d70ddef68663272021b8bb387ff5a0d7ae1b24ba65ab0783ea0235f20b54bff568acf1ec016e7f6e4cf6babb5914c03d55299e6c6b84bba1e92d4fe9254b982bc3f76b53c2bf3a007a6be2e3d18c0b3c860392acbbfdeba93aae1d1957a59f1a809784e3a791f428a3fdf6183f99039506c64624ed6e74f263aa7c19e14d1dccd51635f5e004343aef20ac11ec979936715701a820f9b34733b456e29e0aa83e6d540ccd037f7eb10c9620686ff5a27ac04f2a71271908e01c6f6a07bdb7cb16d84d8c1c7a18dbed310c2610bf5695c3e95dcdda912cacc075c44714d4bd0a775f65d6a69ffca7a7e3977890c910ed3f27fdb2cc51605f7446d9fe5a7e13c48c921b2f34d70f8e84469e6d9b43b4ab2854a1caccd81ff6c2e0d963dea992902e5144288d16d0f8188d01ebf147849a7b1e9b2ebb155f8f2902cf5a7f4cadd768c25fb907b97319fd7e897ae89caa42d9b6a8c066fa17e3b3235587a0376fbdc7bac3afc35c8e16cc58e5311ac5beae69e8ca7e94100268553f4f76a5619f0c8fdfa18eb468af8d51b8928dd351ae37813c47afe73c7cbcf928c808df3ed395a0e7e0cafe003dce4eb74dd71cee51574eaeda133b1fb0a3442e710a6f06ab29e7f33c0b31ca3e3b41094bd4c48548b8cc1b4259c8330dc00a3dcd8ae70d0a77a6669348ca8638c116ba91e9658d3e85866f77bcc16400438b68a58707ab1fd4b02e53814a3c7e2ad4542224d5c597e5842224290b9ea7a9edd8978a8c8fb94f85f837ed90d075b7c04992a167b3fd3e1795b97d87c3a225961b1f4de9d41b6b81f11ee6963a14bc8c048e9e54260adbef3537cbadc8df12b7441ae6e1aa85a58130094f186aaea06607c1cc3d4bfa06ce304b5c268977b03d6416a6748ad3a5d9d4ec8fe94ded80c0a2f0d0cd3d052a69b9129b217819fc2c4150192bc729b5edc0f7609d31a936365ad1f306a6aef0d892ec27834b9ab217dcab7b3a82fbb2dc5c530dd7018b2e102b7ea288afd850f1aca3927042afb6c69937ba552121f5b2c9a78fa21321eb629054e83eccbcfa490ab27717d435126ef5c9eead9964cc3376221e000aebeba8c9d3b3b041be98e9073aa21758b5ea04d0832f04fb99377872248c54a67ee7bcbe82db24a0edf465d8654d0c3ab5c41aca66a2533c05496426e11d3c658e0a773ef5358348c3526acf586ed06d857a2b2b19044522f2811db6f5e35f22f0a1edca8c8d49ddb32fd47443d2394f556ac9710c510ba4d793013f3063c7e78973dd0681cd02a6209a0b4202b596720e93945e4ed1ccdfd9490327a9a90d7fbc23832472af6e420b18759fced10ab618baf16c4043e94d84e296d3e5295fdeb09fc8ccba2dcb41274cc62b9af00f95a0885d51521fd9727c9a24ced543ab38e436ae80ccf88c4fd2ab1f58046132470bb8058387e098aba5b9361a140c824c8ef3ff12dbb787c9d6b612eae4c248319c3c865dc3c913a47efddb5d202d61f45f921ec60513803fc70afb50bd64777b10f7d649554eec1335b980054a1beb72416d78a871fc323589a6aa87e89d07b6f282de5190cc753336c96126820326dc6755b92e70ec41ffc6a47856c204223924c42f7d67ffd792fcc3889e63f5c600258311b93510ee600a2636b2579357ddb745b8b6489dc1ef29703ea877eb23994ce8afcd7f6e66999f30a06431f46e14e3e5c1417918ed5464d2b723fd0c527ae1e8b04e8e6f1dcf5e2b03cc89088f7271ff5317d2239d87f25df731f2c829d2c8c5e57912ebb159b72827ee8389b35f75f29a6ad16fe6e16c44b555aa9944dbc96ae0b1604d59038216957ef4fa29f452b5b27657431526f66125cbb6c2a03610ec9b82d0147c6cc12643f1143a270b9dd52d57335adf404945093315295d7f489ff562949a17b3bf97e1c08ea044dc581cf06d94c156f831e137e0c928ec018772da783813678286d8a0089c0a3317bc723dbe8bd8610a045cf614309e0257014c5b4cfc82688b70127d68400c8a3305523bf276903dd471a6a6da0faefaf07f25d0d97c713c8c1770ff55602d7dac5ab097b26206133af8bb155783333144b45dcbfc574900268996e2477bb7d7fc3b8171a2ea12d04a465af84e82a42f53a555cfecdb13fe2526bffaac5de2197c3a5dc993ebd7c9c77f14b3e86bca1579f2eb38a490b700e7db049e685b4bf6ec9e23fe9910db357521408aa0978d43b66ad8d80d075f49f89147287d0c3089df397e27dcf21f70f82567237c0dcfce6b85f3e3333d4eeef15f53931641e927830e7a0cc89c5d11008edbe92f904218d371beeb1b4f9136828205f1cb710e29b8115da70396a815cd9112791a240742ceaea4caa9a962e5cdc1a7f753c20cc7e89026850a342758d04ee47b4814b43ceb5236fffd5cf328758afbb723f92557fdf70bc16b3cea036f2deca4f4aa2bf7a1576b33d79b110a09f6b292885bccf7c6805e21b0748488ab60025184a53a47bbee1fda045ce314cef2e9067044434ef088a12b3d6c1ce270f2b378ce9436736e21b38c92ca8244ef3ac14a3af6e5803cc8d4c81b0f3fd412f3ef668e34ed585b62603322cef5bd8fa79aba174a447c8f9498ebb8a951545a2a735e0662bdf7fd29cac541eaffde43b21c429ffa4b86ec1725d6e832116c3f6d979641778a698848cb70ae22b03b26abee697fea238f8f6c61649aaf73a199e9d72fd3e4d4f126a17c802a286803884131fc5d0b14e93fe56586d542ab511f6d0e762e83560a930361e55fd88e1a18a7cd2120fb875bdd120b73f3161908119fa0d709f304f9d87efc53a2ecab3f9055bba5a70524a91cd3e0ee610e55bf8be531d90db4d7d949ad615151ae345f0fa522bc393c02a9796d7bcab3fedf26f1e1662e319c12173b200c6f72cfec3913c7cfc58c395d3b025a6ae4a8135baddcacb538e195a2b5750f1cf7e90227273684425e01d8fc67c35dfc8ea2f3d768c3122bff90187d207738ee4d758b776e53cd68da3118d063a1d0f5bf2a2234969fe0d76416fb69693b1e6badc9160d6b36dc69121fe2661911e704be85a8ee1c6d30bed5ddc3398bd76e0180674c9aac92531dc4ccc3c3c1ae721c152258507a92cb3dce4c6668fca56ccc6348c7cd6dac295010453725ee9694c2ed040525f66690b823115f13838bf5031d7827480bba37a936e151d4a45215c147655c01b5ea6b2cc3928c21dea76594baf491c37ab402416b2a244c99b8ca18046c01d22a03828946c15246708e70106ad758347c2f6728d04028a278c5bb2fa491b30737aa950fb2482bba68b5c12a7435a515a8e890088c4aa2a615a804cb91d968af8a7a82ca2c455794fc53b357193a46b1ea1adfd640a53250b7255d2eeaba76095e6744c7463c031de7330c3d83434d8553522cf484a1c3a19750c5a17a5147a51e88f5c49183cd373afa0afd1ceaa9a3b094f7afcb701488a8655431d4b9a827ee08ed15531e869fca16a84cb08cff9f241f4ba8f0285f65c42f346ba943ab6fab32d1a244b1652b6c987374c8dc11c732ec5ad6f2fea1b02efb1dd8cbd1cad184519ce80fd09c1b9db7ef07ea3f7432a999aa46d44d422bf2c4f9ade8553db582f75f8fb2e47566af15f565b95b560d37a9a72e109848ac3633f5bb2a63d00c882c1a059c18ca30c54ba7284465a04e75cb4a8c8e4695416dcc018d169f8a942168a6d486701d30f79b58279cb5db3c09a632c18b06369a218be336273cad4b0fa10a9dc27d41bc0386ace2214127f248d3a4f32149e19d6e89dc6af5f07cb95bec3cdcf3b884982df87ad8609e354a6c08ca6bc63dc526c36e88adc6c68645d2d8ea6192838fc62780eb764ee5cdf44f346d2f41cf5ed6b0dbf0b46dc734563e5d6730a2d92ce4bb2a5c2a8e601923ae4604a3e05c13e81eeb227c5a918498e897caae8a611a735141f7b59ca22138fce786949d91d9c831b418506c1ca03fc8bc5c0c63da50c17a462d56fd724401c0d66e5c85d05a5e48ca310c2b4ff902402288e3a3f6030b26694086c9ff4c1f0d4e066ec3024aa10591d94008b37af412a40d7a0c9814b8095871b0d817a845a4831f3af5dd66be611c05b01d7977c159a1431f0dc1763b774f348c8326176d47460d8c9014bfc7263c1f32a0284e12c6a2b17e64a36932d79cecbdb41a4feb715524f2011b14790be7073739ccc10e38335c4566fc709bb14a447a85e0444b9b597196626524361376c9ef1038ba6cae039b315e6ca9711067e837c3661bfe0a721bd86d2cb61191d80cb6c5d5b9bd91136c399ee3d8b691d98d65e51887534f6c6677d6be0b9dd88cc9a128cdae8d7af166dc144cc86ae5c8c6b46caa02beb045f90d3660b0a4900330333333333333333333e3ca4bfde37ddc1ff7de8d60c232aa45279a9292921209ac35aebce01de7e01dbc8377f0d67401ed0da10d1f0e4d52abe0757486b10e62c41ca48223a94327bb321b1fa7e055a63ce1d2e660724e0a6e8ebfe737785c565f141c4b1e13738c50991e149c94426d5585f6a5ee098ea47c5b29c7098edda4077297396c821f2ed492e698473a98e0b57d479bedef79094e698ae918f197b1129ccd6695ebd2243829e68b15296548706a3e6bf050691b2d3b821f3ebb9d49eab09fcc08cec713724cc9f4712c5911fcee30daf6690c11bc4f93de1ee45552ce109c24b143ffe8393cfe08c10f6311d467d6233d4170e3fb6e36eb2b3b0304d7b3cac52c5de59a1fb831ba6a5f7ce085cba91a626726b7f4c0b188eed1d5b47a5978e0a4c6e6cb13d9819344ea6732248f611db8793a3e87b4505a7e0ebcf6d0217ad8e3c0cb4813d66e3c546ee06d9eb7cb1f04b081ab5d9eaed2b33adab5f082d87f94ef83acb569e1b6c725211d3c0baf652e4731480eb46659781b24180b2779e6c95154d58c312cbc489a7f2bb2fb8faff09225c9a1f9871c6deb0abfe3284a9fc754af6d2b1cf97854438ea7565b56f81a3de4f918415388aec2bf64112d4398e081aa0ae762aeb8acfee1a334156e69baef49bf7df944859f3a948ea297a7f02579a648ee5c1fc4148e678f9e2d867cab580a2ad4c986258f144e942011fd330a5f2ddfa71ccdc7cc88c2df509a156982c71d0a377687f7e8e0592d28dccc21dada625dea3ee1f49d947ac8924b9927fc8ea12558b020695727fca05eb3a74cc509672285e718de849325a7d4d392ae929af0439248513535d57932e1a71c4ff89c35740e0f263cf7499b263269adb984f763ee36d1e953ca58c2dfd80c7fdf1e5fa412fe86ac1e49ce9a630f4a38496ab2cf5c26e1ada698aa6221ea2b92f067b3860f5f8984ebc9936d65b5ed0f020947cee6db72103d6df2083f847f2c094f911e71847329dc86d481a7a46984532187240b33c2bff0d03767c851c72ec20b29592ffb304554116e064dcfaf19bacf4f841f7bf0a0437920c217b90b73c1e3104e6a5bd6beb74a1343787fa163f3cb66e1e342f8d32621dd29ff84f0c2079d6254f6993708af3abe93f1141fa515841b358636cf5aaa3981f0ca3c27bff1f3ce00c233ff20d774567cf40fce775027a942747cfac1f50fa66346abd14efbe0fde5caefb1458b1c3ef871920d8f7b0f5eb7e414ba23f5e0556bd01a3bf3e066a4d57469ed2d9c787043dc6f23fcc776c13bf81f77297898e2b6038d29d9071d07621dfc4f39cec17d460acdd1c1f19caa3e883707377c10739a433e084f0e7eaa34ed992da5b7581c9c34ab9eb482e58b191c9ccf9c2db25f8c31526f707cb2ed322d37b83982abfbaa4fcc698333f39f4288f6d92d1b3cbf98c2aaf755e6881220630d6efb848fc963560d4e48993e30b7ec3fcd64a4c19b481552485ff5c6340c178421030d4ef504dfd8b0ac40c619fced38168fdfcdbd449366011966f0524e89acd441a357b803168601a30c4ea4cc1f59c425bd5eac066490212f937073e943c618bcb4b8decc95a1ff3b2eb6bef0a28b2d3220430c95e6b0fea3142eb68c8c30f8e21ea4b4a9089721cc850c3010c3fb2455fd525f30a656c6e688be1788e497e6735e0b97404617dc0e1b724c4939d892b8e057e7cae361477af1e82df8ad193faf355ae1046468c1ffb19c3286adc6908f0c0332b2e08cb77a78cd1d7e230b032fb20232b0e08590c1be821ba92e68f274d1257fc8b08293c26a32976da4bb8e2fbcd8c2aca08b14aca00ba4808c2a781f89a7d45e953cbe80046450c1df4e9273e8925ce00432a650351620430a2d230ace5cd0147a26c3c5568d1a99749001053fe23f3e5189b858be31c87882d31756db2d212d4b8e2623c87042d540818c26f89299cf238fc2cc4dc6c542c074f1850714d72083094e6dee4de7d31a1daf8c25f821cdfc440c2a5143274309e590638979a2e3586720230947e6f6c163acb83a073290e06dfe9c25a40d1f117304c773f81023a6c4b88a11a86ed5f4f4be087ea8b6cf1fcfa9559808debb89440ec9330427cf769c329a840bb1230427b84b47f3b17e529d20b895dded953d40f03d677498f0d19c477ee04555e9fc99c423f73ef05faa8349ead1d7647be0bd664fd61ee450226878e0a4c8a5327b074e86f71073c4e69a4a077e900d39c8a164fb2293037f656cc35598780f0ebcaa8c0d9afd22e3065e4a15edfd4b82e71c45860d1c8d1e5f4ff239f8e8520b377264c4bcb1ce63b2d0c2b9f6d68aba6916cec9c7b45923a1a52bb2f07290104453864f6d2516de7c8e3b280d8fa25705168efdff6726af8e1e79857f96a5239f9493d4872bbc1e4d4dfb186a3d6e8567993e9ccfd979b4125678eddee5a1a9526125abf003adcc9a93d554481255f8697d36e498c35a8224155ebbc75a1d9ed9c1ffa8f04c730c7b4df6e6fe9fc25b93e41d95b973646f0a7f2cdbecc77394c20fb12395f0b1a884b449e19ca71ca588ee8d3b7b14defd871134ea3ffc220a3f720eed22c77328fc10ed339c87b1fb9941711c99c7c19f70433e881e8ba6d58678c28df6618794365c6ad209d7cc2549ce0ed207ff72c28b5531df99d4a3fcbb09d74396ca13a2ab09a7ec2a64dd0489566d26fca0fe3ce68f35cb6a30e1d9bb745f889472b0f5126e1e0d9fa36bb58417251ecbc420e991a795f0dfaade3e085f29524a09a723db7d32fa78949293f0dca26886895312fe69ae0c1e1d44a66846c215d90ed70e2b64c925249c1829ddbb33a5922e1fe1a51c87312186565c948e70a23e78e9c923252936c271cd718a5ad4a41c898cf07d653a74e416633b5c843749b3e414b25d21a1225c4b216ca203a99839897025367ddc610e39db7388f02a5d468a9eaab4ce1dc2ebb40e54428721bc1c237d20e139469314c29b4a3f214751199226841fd65fab669f2c293908af2e0495a0412a624e10defdcf0709afd61e7781702b4d88b163f848313a40782672f75761d2a4cc1fbcdf902b85c5f62d8b1f5c8ddc954f34d607ff438a629b35ab6ccef8e0c6584915d6d91efc389e1cba87b3ec74991e9c98825d5a87fec9c195073f84e8108b1dc777b6f0e0e794356f26bf15c6ba83ebf669726059b3a65776702d6cc2255955072ff769c7b9a347e242073fd688ec40dad7d3630e5eceee961e678b62b71cbc4a1a25a925264b8c83f3f663f963ea8bebe0e04cdf5f86fb4fd5aa4911e30d6e05cfa8e571109f330911c30d8ebce6ded0b8b4c19f2ca99307f5fd5f151bbe10ce53071d522cb9585d839ba14722db5c4c88a106bf7c443ab6b7480d49831fe608319a79ec65f5e130c44083a795455624bf60887106e72fa9484bcc47b61dc30cde799aa7e89872989ac528831f2d7325cdfeb125916290c10f324d6fad3706bf277ffa24993e77c7108317a1e53c36c86676334618bcf940ae03cd124cd3c4781c31bee066180b2ea576c966e20557d5524564bef34f7e17dccc79429c489ca70c73b1759683185cf0da5375852017184c83185bf02ace3f36cdac11fed1829bb53abedab6919c3fb64819c4c8821fa2e2be3d858ea7432c3897f264df1837358f71b1750557d42c64a4325bcbf62186159c1c6677dfacf6f5e657c1dbd8398e3368baf78de162cb84e1c50b900831a8e0df98faddfb7de0999c8217db248449a99e66f2c59182638b300c181d460c29f8fd3972d49c3c59c48882575953d7696da9fd5070d26a44e592cfeb63f182055b1ce58a184fe8b25648bbe49ce0d5f747e9552fd61a89d104275eed82cfa4907e7ba18156c46082779b43878f30cff0314bf0a254f5775039281b318612fc3084075feef9c24d6c8f102309fe4fba0ade59eab23b48f0d6fe55a5031569d31cc17f995eef0c8911344611300611fca822fb3f6a6d086eb7c79184c41cb9c4b5841842e8da73bfa46304c18f4655e5644323463e06100c125307296ac80fbcdc71322dedf8e08e37a6c5b85c7a40e6efcec14cf43cf02a25252ace63077edcdf9922bad681a329f2479be53843c639f0b3e6385eadf78eeb4371e057faa0b6de73032f8b86908378897677c6b0814925e7ca746731520ba746e2dd2c2b5af8173dad66e224327766e1d4473ff389b62c6e93bc19258e85f7e95aaeb18485571da444b779b5c89157b831d53be6945f336c5ce1a470999c337bc8f05be1c7d6d829bade53dacf0a37a510555931ab36c7b10ab7831c72982c5bc9660f55f83163f9b6844db726a7c29c474af2c72e7563a2c2f73c1fd541d3fc3f7b0a377dac1e3d336b8a536ed55c653e61624729fc6c39bf5d7497983325851762dea8f48e2c878f1c459646f2460ea273bc280c8b312387394a6ff443e1791023e4b01550381b3165a3867cc2c9f1519e34d2e4709527fc888f91d6f368ca612736fb73959c533bc6092fee4f5bc262ea33da8411368410c4e4628b0c03d08413d22f7d1061fd539e4c381f7afa1c652dd9670c261295d26097bf84f3398a9d27ceea52d2125ed234c135bbd587a152096f43fa8fde424ca97228e1e7d618553e3aae8f3209e73aad87906f3b7f1c92f0b27d881ac3a5657723e18739bd234374dc390909673407a17a62e411841b4d6e12e308d77ebd3e8a4eef5d69849f2ba78df0b072dc3d23fc8bd5dae571ec5c2ec24f7f4babab15f1796ccca525c2d97c215b9e17d91c8a08ef3f6b4c1faf5fe6104e84b7dca14c5b6df20de16be5cc8a9d42782a1d45d4ea3808e1f6dc6f068d109db3c7208e209e839298d22505e15fae79fbab74200a89946eeb3e8e2640387193ed347bf41fbc8f43e71cc9a3fd4084f475b91493c7edf5c1b5e47f29a7cd714735f3e178fb38b6700fae87afee20c5d5839f83d89a87b3bb8418427454f93e78f0ef53761c5479e41e7707bf2c2c7c799437c729b583339a3bb68cf920eaa30e7c8c8a31e530c71da3832ff6ff9dbeedd5b49c83511573dc217b8614b61c3c2fadd70a9e38781f793c34724f761e0e84a87cc125f75418dfe0cabd44ccb176f5c92c089552f02ca4bacc32a131c22878193af41c778c1de51c14fc8ce91d85f4b149774ff0c3d08aec0e7382975324f6f6868ba135c1174d299364d487d162821b7294a3e4b496e049fba87c903257564af05245c8d2ecefb72a097e10527aba8b69ec4307129cba0f59f5417290d271042faf5fba8c7418c10d1da607ddf3299d53043745998c670fa34d0e11bc645d15dc21b81e955d730826590bc1cd1965b662d9cc1b0427be83ba9f9b6513089eac445947da4af0fcc0f95c1f7da776b3cf077e84a76fca6678cbf4c077b94f159172ff8407de5f8e63794739c00efca8e3ad4992538c8e72001d385ed6215d8b79b8ca0172e0845039ccd9c73f29e40038f03dca41c2a6567b0939c00dbc288fa255d286f2200938800d7cd91c2b74476ae1d846b9ca10ecc3e769e19dd684c7f9cd3d3c66e14713424c394e9bdab42c9c9e0876962b7786742c9cc91bf75148f9c9372c9c35efe0ad738ae9ef573817c3c71b7c57f8693ac5a887a487dd0a279d44e720e5ce97352bbcdb8ad6395ac50a5985f31f4a6d6c8d4aad0a37668aa7cc4a332ea7c2f76023a36999dfcaa87063b6edaccf1fc7fa148ea57bc8a19885aa4de18d67a57043fbdcb3fca3284941858cc20df691d78c2b0ab7deb447c35068bf390812ab8282abb168159a7ec2f598bbaa247b2a0f4f381a835cf8d8eaf46527bc28293ec55776f992137ee8f7d6482321addc849b3caadf9837849b50135e8478554e294cf62f139e4d5d761c478bd51b269ca834d9a1b2be8413a2dd87d1375eea6a4bf8513a97927b9f94a7ae84eb2396ae634a53c20f52ca42e6ca2c1bf524fcd414434e1d95fa7b24e1a5d4603967ef38b427126e0e326f4bf44f8b1e4838993654f6795f34cf233cc93efed31ec5fa8e23bc10b52e6a348494368df02bb52a4c76480b1b46b8151a953ea3c2ad6611aef4864647b5390c1945f82942fecd914984137a2a6787c84abe20c273b7b69aced4f09743f861b0581fc28518b518c20fe672fc9bb3570a2185f0ad627658dfa7f21342f8311a72c60aa61d4c06e10762ad599f20fcee50bff271a1251208afde526c594b5c0f083f8e393a8f473a4dfd07a7cc3ca60a17c362ef07afdc36c264fae065c8c79afae083a7c9c6638cedc1f114317f242322293d38f741d24abfec6a1d79f0623c6aba089ac3e8c08397af4e43dbb22ce60ebec4beede0fb658ec3b5c73373d781d90ea483db95b263344799369e831f74bc695210e5e0c6d439fabcc6c1dfa4b943f1150eae654e92f9dc342a7d839721d9f12de5414abac10d1d87d9632b5cfb6c83671a39c741d2d431996cf0ac5243541fd7e07465956c1ec658caa9c10fdb614e558fe9bc4b83ff7190c3b8d5d67cd0e087f07392dd3378bdedd1a5ac0e0f33381bdd7bc3bc6570bd83f5b05346062f25e6495932ba778cc17b4bb9376214afaec4e09d057b0f6518bcecc8476390180ccefdbf77c871bee0877e29671b8f17bc145273f061da2c962ef85a23bd31fabbf35cf06354262651f1efb7e0a5ec142cc3460b4e6bc654a9e262684d16885e1d7c482958f0b5dd6247989bf82857d8ae6445836a0527749810217c7b1456c14bde6973850a61b64205e754623a4cade1a932055742beec41ecaceb102938a15fbd3af351705cbeec3f780ebee3a1e07b0e3b753a9fe05cd01056511b6639c10f2ebae5ac9247e99be06594778f3f8c0e1a2678b933640a1faf5b64095e84d09b11568267f769f1ef9104a73e7f1c7ae88104e7fa7344f5f4b1cfe3084e0e3a42bc4c99dd6d044722653bb06c566a17c10f513307496622f82769a93ea423cdd921f892751fe628c71c9b2b0437e58e62f28c06c1f730735467962e4305821f27c96129da64f8c81ff822b612c2f47a10a50f1c33fbc91b246687600fbc4c3158a69b8f5b451ef87d1a6fb9fb8314b20327d9c7a1e7f9dbf6381db831776ba596f9162f075eb4ec100f217b640c07aeab4fe6685bb63206b8819b5fca26967d5c6f001b781df97a35c7e553d7c20bda21244d7972eecaf058c93ccc5acdc2f98aa134e7cd70175938123d3bfe2894e68b36165e7ce8133d473e2cdcb056a1736d7988cf2b9c303194cb755ce16a85bef4c85208dfb4c28ff6917fda9e70b16185d71f555cfe2c4a8e55f8d7b1c74345b0e05154e1ab767c3908396ab44a2a9c9e994b97b7a35454b8f5a9c25a8edc29494ee1e49bdc418839c8111253f8ef963c8e42be147e8c9ddd36ea34073d298a985635cb1fa370bd3ecc3c7fc4ce1ea2f073ecb952ce23147ed0724b33d11dc530289c1ccea3f9c935a7f127fc1017347bc7ed61c69e703e481eb6aadc0937b9698e6cd2478d2c27fc568f327290183ede4de09303a9f50fd584dbe9cd639294cc5ccd8493e67148ee9a63d78909ff35c2574a6dbd6dea25bc99bb54b163094f428eeea38e2cf66325fc28b6e3d764172585126ebabece7c7196fd49f8c1d29b6f4f648c92f0d652847f0f6be922e1479914113465c57490f043aca6f031e5e0ed23dcbca5da97426f089a23bc28a61d474937b3aa11fe878c9d3c3a9ec830c2f30e3e9c644c49c3a48b7025b2cfa25fc44c114ee694e1eb2b89f02d3a8ec73c06117e0c3955d33c840e630ee14a6ad792397b558d219c7416ca3fe410b92b85702b7518c27f74ccac10c20da95f4f7910aea5cc9c42737f50124178919e6adff1658e914038e3b1fa67f324361140f871d47879349dfff3073f6c9c5ffe2d898e1fdc10cd41a3c61c65f4fbe0c72c6ad71d84d2f0f9e0e5a9081297ce93f57bf07269d80e2b7f90cf430fde86ca520dc9fb3f79f093bf44a494c6833f371e9d64b21bb3efe0aaa7e710edae1df51f695e8f3267b90e6eb7664df1618e89321dfcbba43ed391de4a9e83172cfbfc6a2c073fd2ae58173193e5c4c10be396fe29c2fa0f073fb4ed896e1e43a76f7025888a7bfe4e9aad1b9c546fed39d536f86e1ee788930d6e6cb986e6c91b9daec18f3247fd1e199d326af0a312ef8e47ab7325d3e0fbe5b0535a5b0f3e687025ddc392cd61a9e50c8e4d6a0e22df9ce4308367f159b56337ff0ecbe0498cc86f6bca9a0c9eca4756f48cc14d93261e3a2ec570598ebd30b8b93e0a9ed181c18f88ff5af7dc51e60b7e468de778096abf17fcb0a93f66c4f4a1ed821bf37b5cfa7555d2b8e07768161beb3129b305af42a37cc428b5e0474c512aeec982df9192da771c2cf861e63c76472186d4b9829fa3beebb11cbaf35638086fabe0a73877f31012fba6829f72ec9b704ec189704b69a191829f3b9889cb11053f7b700b4bf93ca40b147cad309adda33cc1cfc93d4c158ba810e204a7530869823716b3b2e4ac262d61825b2949aae6ef9827bf045f353a7b234b18f195e066f449bb764bc93992e07de68f526c4ac99303097eb2aeb5f18ad27e1fc17f9ff6a8e41d7dd846f0c27806499ddbaec345703bd88e93c6f441083311dc9a8ab89b5893cf1d82f3eed2df9999735e85e05884c672d70e490d829fb286c98a09047f237bfa851ca4cff2077e58e40c8b613eaef481272947c991e981abed9653a2689685077ed0d1367fb13f0eb2033f567c681b3d126975e0ffe63953150b90032f6cfec366bfb2fc1500077e249d9d255d3e89ae0037f023bf5c3612726d8a15c0067ed8d7f93cad3286ad165e6cb41c2a365af8519a986d9259a7c92c9cbc621d694bcef943167e858995e314652bb1f0d45f2be7e8520561e1b84792263d5fe5fa157ef0dfd3ada66d63b9c2d9f48186fe68ec2aadf0d62b47b0b14829cb0ab7630f2b7d24e12adc8c728b2947a80abfdea227582c9b8e3015be5fd545e5303a8e0851e104fb0efaaa62adc7398537f641ba2bc7b1bcc7145e6dc4d4ea94c2ed305ad424e37711527895434f72f5d1dd3c0a3f4fca986286cdde8ac271f30b17257d6a86c2eb3a3593cd80c29fa9d7f8cc7cc20fedb183af142a2d9ef05288b38b3df127e984177f412c956685ac70c2ebb1f338a6ca26fc186e42c2868c29af09dffeb2df8924136e6a8851e22398f0256d5427e98ea27309cf434b59f5bf25fcf451c75399551ec757c2491f6d78743c259c143cca3a940dd932092f3c580a9e9364f99084ff31855812b6634a1f91f082a58b1e3cb49608094fb3624e533fc289fefb0f153bc24d1edb46f8514cc5a7d258b95e4638eea369c5738e83f02ec29f0ed3be43c7b1ab5584efa16a089dd22a443411ae660e55d4a453f78a0827c4b4f92b26a3c27a083fea682bb93cb5c7aa21dc786bf5ac4d9e2f2d8497aa766df3b9ce4d42f8a9b9d36b3a085f543d8a09f2d6a320bc694ddd51bb2731108eb8e4b8de83b4660908c77fe5d4a492471effe074a8e17fd38c4f871f9c4a135bfbc32746fbe0044f95cc32ed933c3e387ee1de7bed324bf6e078b40ea2a64eafad1efc73efeee8687bcd3cb81edfe6af110f7e0cefce76d91d0ca9af52f6783b90e6b73ab81e5ad6e0db35b92a3ab81d8748afcc1d2e85c8c12b8b2995dd2671703d54ef8f573a38781fcaebfa63c8aa746f703a7a0e2ef391f345e70657d2628769a80f2ca60dce46878e1e877414346c7072868f6369bf64cb1a7ceb0f79de72f5fd6a703d7be4a04572be701a5ccb7739c75f4183bf2134a4671a0b5e398313a33d9121a6ceaa98c18fead0d724a40c8e89a7c5ecfe4af927836f39ce399aabf1a8ff3178926e2ec4f42858ff6270c2fc6d75dcbacc1f066f2a849ef09863c607839f525ef320390cf71c5ff04337d5140f29217d78c18f3653b8ea4bd1bfa30b6e48b19c2485b372990bce59f684a40f72d0f1161ca91cbedfbde318b35af08367faccc741d566b3e046bb1cabc574d074b1e0d55b78c755dd26ed153c099b434d9f90c9572b3861fba543e47ca779f1b0a3b4c20d99a952adfb2353cb0a672efdba8ac52cac5556c5baff63ac3437d31db3a10a2ff664ffcf9b6e1e7ede48859f2de95108d73aef3750e1c5ca1aa9627b8698be53f827d33d99f2fba5e698c28bbba41eb2f3c4985429fca0f597a23b59be5092c299bed8162dd9a370a3e40fda91dce5ba4c149c654578b95876677cc7a1ba22caebe650b829ddff7564c7b61cb2010abf446c638aea486df9849b428ed581470a911896c28627fc8f5bcd42a8eb550b373ae19c78960e82b1c50a0e521d48c20627fc2862c71d346724e0c5c6265c0f1bce43e227c7686bd4d8a270b0a109b7f307edd8983f7a8f63055e8071180e6c511b99f083905c6d5372112d4c50e92932965d1313193652f89770babb2445788dd259870146172940b584bfb221b572b08401461717d8a8847fd9f5b17b4e295157b4997d887a7a109d7b42cbbbfc4938eefeb9225473f6201e614312cef976678e241d093e4e2675f9e28684973aec3a5d5269afec1187f1b87338c29678abb0b70ef70a79aff1289bd036c2550be92b98472184ba1b8cf0e37c1693a6cfb1087f725853eb137b091b8af0673d7c18d357527f4d02612311fe9a7af9c7f9d307416344d84084af6934c2a52c1b61e310ce8c4c276d172f4def8621908fb78314a23c0b001b6c14c2db681e2ce6d01d734cae0e3608e17b1c678cae0c51a9a941f821a4b76c99b3e5941e82f0831c66cc71777ebd06a292abcdaaacaeac7c5e51228df87ff600e1af44358b31440c6697fdc10feeda2b751cf7e4982fb65081f9628b177451aa0a3b60c30f4e4ecb24b12f52c7aa45b0d1072f870813d9fbaa2ae40d3e2053a7eeb61aa6d26de961f4506334dfaefed88d3d781163aaec9f8fb1adc2c596bd0bc0c0aa056ce8c1ff402cb43a0cbfc8835f21e4683347cfc596a5800b30b6b00ae374c10518c9800d3cf871b9a475de1cc3a4f9c25841171f3841170fa851a3460dde2d54e08215d0c61dbe08030c177cb1c51602d8b083a7f59623dfd47182159814a4e0e08264d5c129b79c3938952437aa0ba81eb0410727786be6f76b71f54e7080018651c1165812d8988313527ef3205c7a6ffa2a0c1674f1052939f076112f2257259135356f96b3db448c1e0bbce00d6cc4c12fd390d992c1a3a6145b75a0cd7bf1451860e80aba48c11746058a81116c711b70f0f387db0c39763ce98336dee07faab75f8c1eb9e106ada32eee4ecb23d4253eaf8a791c39ecb68f8160a30dbe7a6c99f6d1c63cd9dba20b161c5b18166cb1050646b0458d0d36f89f39a5c89363b61e8b8b2d2ec070410a4e5a60630d6ea6314f79324586ac1729b80d3538d61dfc88bc5e5ce02eb091062dadd3ba34c35633cdb6e66290b953b58f49738213787101167881811a354ee0450af2be0883051b68702c9ac6a0622f7e1ee4622b055d187206ef425b7cf6278fe09a2f5a00066e6c98c1f7d850219fd4d25c9e8bad93822e0c29832713730af3fa4bea09e38b1680915c8471a80055f05da4003130822d686c90c1dba4314721746757c7e08ac66cfa7d58a11d31f8315b8e223950cb09831f7f0ea2b6e251ee3060f06cc6265708ff3959bee05784201ff786f178c10f7334ef318dfb8574c149e96f51e9a639940b6ece9ec1453ad58c640b4eca665b16ee344cb4e08b5d6a0a92d2a5f6f70e26fbdd7b2c389d992ed9edea9d2b38b235bfa1d6a3d86105e72a778ef139b09c1d557033648d930ace9b7cb470e9297819fee73cdb43b1b414fc9118b2759028b8b6a93f8378471681821f89c6a658988fb59fe07ab86fada8589ced044f52da48f1f19a857013fcd0c346abc87124394cf02d36422563489163096e481fc12347555a2bc10bd1c166869cd2c649f03227b3489535d521c1f5207fdcae1259b53d82e3a5213ab5467053e5e8e314db577711b4cb9ed006113c3b931ca6979cd9d3b3310427a70c95b4729c3aa4674308ceca7fe4f164f74fc9b3110437f465cae1a291f3793680e06d0e391ef994424ef36cfcc08b6079e22323692acf860ffce875de4198e46dc1b3d1833f7bdc23d1e581131e9f63348c45b703e762b4f7adeaa0a203bf62088dd530078e7814e9adbe0d1c789fea714ef213a6be8d1b782aee5d975ed299b7610327b79a4711e9e31baf165e8a0923293b8ed26b87167e471b169ebd269c7666e1857d1c449ab2f02a3c76670a1b2967b1f0259a8ca51c62d607165e0e136b3ec7ce9257f817f239ca945aa9e50a27e714d3e5dd61c76985b72efd59c3c692301d56b85146e3fa833a4f59859bb54d3ac5b8146355f84126c5d87452e15f7d6b06f3a0c20f16730aafc7dd6352f630a9620a5f632bd67df4518a29851bf31e2ba490c2b3f0968c12320abf26b4c207d1ef3f88289c4d3d69fa0c853715bd4dd3dfc620289cb6912c62295f0a924f7829115390a858a9239e707ab3739035b30c914eb81aae1e568c8e909f134e5a86ec3064aba0fe26fc38720fb1f3cd4bea356125bf9cda1f4726fc54291fa61ef1f83c30e1a6ed914b96dcc2765cc2e94b1f65d7b425dc0e72b678f88e1ea42be1db7d18d971e71c7253c2d39c695b622b33d793f07360725922857f9925e149c664f69fce718c23e1c61434e7ce3239430c09275e24856675966b1f4184fbf3924d1de17d14c226767dd49a36c215f54f6da119c62319e1a8c744d5ca1e4de722fc8f467324e36d174e45f841d2491eef12e16f4c1aa53ffa87194484f7e92d857d203165f0107e040b734136fca268083723e51842f028c28485f0936407a9912384ff39b3cd86078f633708df0397bbedc958a320bc8f2aaad53eacc50a849783b07eb36eeb6105083f9c995fd6fcc1fba01a2ac37399871f9ca416aa434da60f7e289363f48997d0c8f0c10932397d58397bf0a37a771817a207ffe8c129cb9d3a79270f9ec6589f6c62f0bae0c1afdcd9730cffe023e60e5e7b7cb183539a3b2454eae0873972f4317d70c1a583ef992a31690ae123998363f9a3935c297db372f03de54aee7d1c9c742ba6ea3d1c9c90439979a455abbcc153f5a0b28accb4ef063774fac852eed82dc7d106ef5d3eb00ff9f38d071bbc8f4e6a9dd3327af41afc8ee73ebe540d4eda8a9d95638f2ac569702673e821cd46839f912c26979cc149e7a3d616dac3bc197cb3dff064d3e797c1495531f75493c1b3b33149511d8393c94672faa468a38ac1491be722a1d3a34bc3e0c9e4e06d29f64a8e04832bee41ff57a4aa07bfe0f95a88d029e8052f7b9691986ace65ec829f6ae1e319f34873b8e0e7cd9888892db2b92d78b93fb5848a18fd3a2d78136361426c89e7c8826f79f278967df96b58f0d275fc5a26623969577022222bf67c58e295150ec248feee5855c1894924a6145eb93a54f083c9db1e3705254f8e9143450a5e6a5289e935240a6e482ef2713c1628b8c96da225a67f7c79821fc6c58ccb92db3e27b8e1710ed5e2728cd56982bf39ce379b63cd39c304bf54ec249c4bc8d6c743865109558ccffa7c26094e8e2a4729a305099e851ca61c5cf9d7468ee0bb472166e690b152c4085e08398e6899c2f5e58be0a73c29c7131e4470f37d184663de48d13104b743c81d875e087e5c21c79572e430dd41f0e3102ec7dbea1db440702d8450267f3167f3074eea891dc5ec286dd83ef07e26bc6358c90c750fd61c2a5a2c0d0ffcb2b90e3a8ea6fb8377e0e6aaeb491e1df8a6ea1f07570edc8eab3ca590c581f315be56ed0dfc1c269329f769481060033f3e0a59f2abb570724c4134a6ce725269e1c76130d114d159f8df79629ab01256230b3ff020f7e6138bbac4c20d19636bbab78f21b0f027d8b5759a0c96bdc2f1d86453b694ef2a5de15a8a11e71f6c851fa6ac3c6b6485133bf038b29854307115dee638248f1682670855e19bc731a46473ee38970abf5a3e920f2544a643856b1e473139fa3cfad829fcaebc21a5c542d29829bc4a2e5b29973f47560a6fc42f420ab7ad4b7286ef706a915178122b872963f7077922a2f0abb327c4431f0adfc3467b8efe79c20714be450a0bb93d5e8d9e4fb89a3656e4303a5a763ce1dc8da758673ef1309df0443458b0bc2177a4e1842fd9999673d4ea39b309b77275889af346b2144df8914afa8e3a997574c9846fffd92c5b65e5ab60c27331b32c0f3999e6124e4ae7ccad29470cb18413738c1243ae849761fad206cfd9b194f0d64cb352ead6ecc824bcf4edb61d7e49f869528cc9b28f849f72ba9c3e9258110f48b81d2654943693db8e47f89e82aa457438c20d29738e432c6af67423fc38fa2883947b349a66846b729eb2868ae93e7a11ae67d9e09f61430ab5229cea286bca5227c28b219484b31c45af20c2b394fca14b88d6371fc22d93ec3996cdaa8a21bc0ff5d01f47918b6c219c1c4426757c84f06bdc73902a1d8493d7c3741b9ded422a08ffdd53e64eed953b32108e66ef9421de2ad70908cf23654df0f30f5bfec1d7709f29b2e32d1ffde0888ba528967a7cbe3e78a9352b92d1dfb6e3831ba135dd6a5f9c670fde64694bada93175f4e098650ec5c62f36260f4e5cdd5a0ea3078f030f5ea61c6bee204436b63b7875de1f840caff0cc0e5eb40a390ec283c831ab83df1263989842072f4a4a39889123c65b3f072f7d98e39e88c90aebe5e04627390e6e4e6917f5beeecc818393c7db3f9387cfe50d4e270b6e91376ef0ede5235aa749744d1bbccb1c25a2648397c390cf18d5e39e5983e3817f320feb715d8a1a1c1b19f1acb1b672d2e0fa892509963b98074183932ae7e6317557cc193ce94e131e7d33a02165703c89aac5e8f155f964706ce63c8cc1f2e6c818dc48313c3226710d8bc10bf9d80e3eabc5360cbe44c8299face4283bc0e085c9e123491e31a45ff03fec0e2486da94587bc195902991a84f92d3053f4afa63c2528ec25cf02a7d18973d795bdd2d38e9fd2b47f7214b460b5e856745084133250bfea754b9b3ad58f0b4cfa34a41bd8297572b86902243f2482bf8d27188ce548b746615bc8e9db3974905ef3a96d95c15ea564ec1cfa27541baa30b0335d6e04fce29a79c3e31c73fd5508313323b7a98bd37c7d2a7c14b52eba1e71c26b9bfa0c17bcb29575a98902c6c6a9cc10fd45c2c977c7e50c30c4eb5a492d58eb5366519dc4c1a1d7358ab99f385b9e200c7e00bae4106ef3dc8df352b1d440f1a83ff95917cb3e5387fe41083ffb16dff88ca61f0cb6d523078b162eedb58096a577dc1691993bce0c714d27f7c1c540cf9d305b727d347b221d6e0829f43b68fffac3b47c6d4d80256eda66a9fb121993a72ca9152430b4e287f0f5972eef5ecb2e07dc584a5a5160029d4c082d71e76567d566feae4158c2dd917b493a68615fc1cc40edb516d35aae0dda58739f8daa648550d2a781d9322f685cad86b4dc133f1b39f4b661f41ab21854a225cbdc4b3db3f45c761f25ca79428f81efc6f76924f179f5f64208c2e9e6a40c189317956091ead553abb45d1a0c613bc0c691f9a48ac66ab38c195892cff0c25175b2970810ab01650a3095eead452dede71b155bc50c1162fe8a2aca67d00b7c81a4cc0446d6525cd3d6ea4da530ea15e61420ebd1a4bc0c3ab3a66a4bd1a4af0a3e418d523bf6b24c1ff782e33410d2478c95cca23357bb8ce41358ee07cd011933a0acdea670d23b839cdb6f2dc45bf0b1d1f6a14c1cdad31720ec254938670c0053588e044f5285ba7ef188217a3d4f26d9ba7206b0d21789b377e7387641070950bad2f0f0f912daf48d95463f0fce7670d20b8f943baa5af508d1f78317d1c8597dc686c54c3075eb28a3c217610f56bf4c08b1dd39e03ffe0f3b13578e0d6467d798efe0ebc4ff2d7b93e7fecb8d6812f2556fea1c8f9a6a9460efc157b8f21fca4f848db410d1c78221f85b49023dd6adca069cb3ad5f07899f56ad8c0e9f4183643566ae157a7e4db964fe7a9a685174d93254b9b5938d1cc276f92ee78a3280b37326bc5dbe5dbbdf3a20b1ab1f0b5bd43f4f54fb1013460e17c14ab932f890abcf8420229f0e29c8374e0cd0a345ee10a67a4a245394b5be1c874960929fa8b4a8815a0c10a3707d6410aef1e1e73ce2afca02124e4281d55f82d39e88b1239346f4c2a9c50cb7d11613c5f5950e17cb04a1a73189e39f23885e313293964ba47e9834de19da4cb5c67bf1e79b0145e5aaa0b69aa228597f2f45cc8d1cf7ab246e1895864b5dbf049461285e7bd1d9235191de51e0323d8a20b1aa120bcbb2ea6e6ccba5c3a68a59453d88e06289c641d2264dfe827f6ac4ef35a8f9334f3ce41e5f65852746c3ce1b4af64acfc49245cccd3e8841f29a7f021f6458f5f2a3438e15ae80ed3d6e6686cc2f18f5972e4f46868c2bb0966131fb287d9c74cb895d583a68eee474303c384118307c48006263009198d93b4cf6040e312cec73fd541ce1c96a024625cc2e34443e6b633ca448e9b5425dc4822f9bd2e4c0947aa7e23c3497e406312ae6a76da761b25e175745e1725e6bca69a48f8a1e55053884820e1a58491508f5a2585f8115e24f7ff984c39d2d83ac2f7d0d73c8e36a68fc735c2cf41960d29d46784f7b92ba5c71d5c4461e6716791f1e63dc9c358af082f04092a398eee72611a89f043aa7b54f76977c88108673de6f83dc474eeef1cc2d99088507eb51ed6c410ce673b0fcb3b3afdef42e4b6a22a59ef6521de5539a8ca1e2ca5c8488f107e1c7b5699746d15680cc2f3bb10fe628809c297ae18a5a7c3e88f628158a542522542d6ace63ebe903420fc384b984e9321c337f8072f49769c2b578c4f1de407277fce2629c4e8e9238f3e34652d27ef51976a5e26d197eda5154172f0c1fb38233eaeb2ecc1b1b4f133db512fa0a107d73bb67e992a4d1eb677061a7970ad2622bbe51c68a08107278878184248be71e3d1b883375152d49e790fddb71dbc8be930b2265407ff553ec8418e2a74f0a34d26edb183e409cfc192ad16abd6146f49096b8d918a395a0ece07a13f556d44230e7ed2ec5959b4c39472c0c1ab8fb6159115491de40b2f24805b031a6ff0b2e5ec9d3199774cef063f98921c42da1c297ae6f8c2ab0d7e1ccb79ccae90d35684061bdc482a41c634668af28a69acc1cf1e39b45384d5e05ca808b229d633a6541af2940fb9cbe9a3c1cd39a38f7a449be990c6191c09e571ec2853766c9bc15b7ff140727f06b9b60c7e871c7a90c10fb2cdf585bf1c61b531705fa2219231657116eb115b44424aa798187c390ffad42a0b4356b1769e325612369f11338520f6c126248a60f03587f8ccb3e182b8c00b10f080c617dc54b38f1eede8b56337a0e1053ff9df588748a769ac9d018d2ef8bd1e7c5bce2c122b840b4eff871ea22593c61614abaea9913497d4d8b6df88f513a9a6a105377518bdcef3a65c9366c18f5268cf97333b738ea48105bf2d6a7aceafb973ecb98213ca254be890ade0a5a70eb36c39c8c6a80a6e5db8e49155f0cec1a854f0e353796c6c7aceb1e262eb042bd805d098829fcddd33cdc4b8d88ac1910253321540430aaed445394b9675952e5170c58309e91edd52b98602776b5b25325257e3a7bd91557c825f79c343a8faa8734e2f136838c1ed28933be6b553f9c409349ae06a872d1afdeb3bf630c19199edde90f925f8e9f279f4b14b3494e067ea4ce96147a6393322a09104ff25bb47c1e3be889e41829b7b735839a87d84466dd553bc624decbb3607afacb9e6e3a36104b7d3ed338fa56814c1cff1f44732398a06117c8fe9e3991ccf07991c34a03104ec3e4aa6ee89da808610bc770d5e1ec60cb1262708defc4848fe7cf141f00061ab1b95956c2dab8de84afe33c973c77624971f387296d2c5687e631e4cc3075e0ee222a5b1e84d6147a00b347ae04a38891e476a8e83845790041a3cf0d64224a4740bc933b883c2d42a3ac6cb5536694c7a69e860cbccb8cb2e29bbcce8aa8c14c22b648ec3252eb668e4c0f9d06f1d7ab686988368e0c0b9f671f1ec48534e1b1a3770fdfbc4a3d9102eff84860d1ceb9cd13e6ebeac4f2eb6bc08630b3050701816a05560462dbc943752c59c6bb2f7dc8119b4702d3349aa68698d1a555f80b13366e1a5cdd41dbc86b270227c74f5314962e1a47c9329c33278871558d4a215dbd52255ee362f390e8f36f2fb0a3fb4d0719a438e2bbcfa9446f36d8c291fd30a6f4a63ca9d31acf05346d8a8b461269255f89dee293586c7fc5155781333bf59678af4b1920a673aecd248539f6c54385d696424b8f97d4d4ee106af0991a9d9716a4ce19987ac3158cab210520a3fc8ca07673e299cdad05bb79d517877122dbb32224f8828dc1c07eb21797684c2f758631e73ea008553214a92b3530f72e8f8849f2f8f6f867464966a4ff8416ffed0622abadf9d70343dc6b2c709bfc62b4fb466e4ab78139ea598796e6e4d38e79fae836c33416b68ef50fe03137e0a2657de1ea690f5125e4a0f35f96b7dea534bb8e13dc8c16f07aa15530967d5633bda9794f03ab68fcba1949370726945cf1463dab428093f8c65f9bd031ff1c922e105f7b0963fbe20e1fd47e4d4563fc2e98e93da54d48e2b48331ce17534b39e7e723ca311be79d49683f530a964b88cf03b70e9e8e55e04d9a723781ca33314e18b847ccb895ae78c6724c2c951da76d0b1bb72cc20c2894f95b3d2d9f57bee105e0eeff5ca1355529a0ce107b7f12ab318f3854e219cba0b3174744f88b32c4dcb3be32ea55bac374d06f3c8caa4c283f03b44f1118bc8917546108e66fed01dc2a7e5c01208af62d68890feb2ab2a80f0eb62b68f273a3089fcc1f5c966b13d9ef8c1c9e01fa3f45dfab0923e38a5d1b3797ff0c18fd44335cdc27bfa7f0fde8f45cb79fcdbbf7d3df851a4bf27f67fc5c89107ef3d0e9d2b4bee8c4be3c1eb309447d25cdfc1ad30f93e779ebef1d90e07d9265b07e7435d75103ff2331ddc181ea6e093d2d46673703cba972441e33f2296831fc4b4f153afc9cddc3878722fe629f7a4dc3170f06efb93f4ff779027fa066f2d438ee4a7e330f36ef0ff7d6dc2e5c891c56df063dfc810739633d8e047464ab9af424ed98233d6e0686c984b31c786f7c0196a288b787cb2b5310dbe475f479d91ef230dd1e084b449a288f765ca9fc1cf72c93c58c80c8e7daa9ca9528644580667d663c911aadc543a32f89d345888cb6163f0358568c65c89c1f14054b335fb6c0e5918bcaeebacbee4e69a0383ebae5e31878acb53d517fc943c0a1d741879c1cdd453c9c3aa762fcb8c2e78ee1b62b5fa9f7a79580833b8e0c7305ff9349b2db82eb2c12635a5091e99a10537cc7868a5edde285f169ca9c98e3e87cb2fdb61e1b2aa78cd4e891a29ab37b96e91f20aae45becc71b48c153c559f8f3fa70b39e5ac0a4db47c4aa5c7cac7bbf95f7d67474a05cfd3d7490efb7328dd14bc34bbd9f00831a637430a9e7b581dbb07761f75a4e1408d1a4e9811052755858d51161dcf57a0e047592343d966b7cf3cc1bfd41922d3d638cc70829783ce1f623af72c95ecc0173498d104472c46df768f8a89640613fc38b630591fc7db12aa194bd02b2eb6eab2264e666653c7a8b4fe511382194af0725dfada0cd28c24f4b35951ca2f8404cf2ab8a85a08d6a8b10500dc30e308acc86c744ad6c59667a894657694a24db2314930c308cea44a9875190bb57946115ca9243ed9fb23bfed10c14f512de5b29bc71e3d660cc1b35c29b7577d9c334709c1cda1c3346bbad4586d10bc105d913768464bf00082ef71f420da27e9f3b366fca0ecb2aff77439f5d841d4af48ca9fc2337ce0c7fa383b6bf7356a7c61460ffc9aa88f1d59c87970171566f0c01b9f0fe5993eca5d31e2c18c1d3839fd85e4b4195386ac03bf2ea4106be55353c766e4c00f36513296c77bcc51b89881033f4d4ae49f1ce5067e2c19daba932c821936f02c4c6c6b8e8a149d530ba7430ef28dc84f0bacbcd2eba3a3dc453c347314a29d2db3f0e3e389d948933b458981116cc1820d5938dd414cb5a33f547446868d58381d33425c7f59f48e030bd7facffb7e62c45ce52b7cbbf2f90f993762785ce1755de8988ad8a874e903e3e10182c161c16824128642c1cd7e23006315080010541a0c45721c0792381c7e1480015d1e1428281c1010120e101210080a120a060806060008060606000006080685414276608e65301f113ffb4f02b53e38081a6d1e2e448eefe4e0fb5cc5a118bde5a418ef40a7a3ff30dfdc617d9b34ffd7f073d12f7e1bb37969b31c27467445e227f755a721f8aaf4ed82f77e9665f5bdba1d93731f72fa089045db88560ebb5199a4d834c95ed3e0c3d8e404d1a98cdaa2134f16942e68ba9fba41b2ba300222fd6a06b1c1ca6a896b6ccfdc63360f18c3951a5ac915597f4aedadcef6e00fc63a94a3a3b4606bbf1e2970253b672a21a18e88f40dbbad6a3435a3816bde8308bdcfcb169b680e54db13f5408b1acb24ca84317ee7365b9dbc93794b5579120d7a4ae5240048fbc521b26c423e8706e73d5f85f5ac1c5afa60d3a589fa8152aa14171dd0cfd013d14c91443aa1ce2f0943e1a836035a3a983c7980437517be3861a1f8f79b8c1b1f927fafd06f66e40a472275af5edc8473ad22bf37e0afda5492f7681368876d3003b81786e5f64530fec6c8e0351b39ae5ce166f2c92c2e4f8d4fd982f223b601fc623f544a3904486588ffa2f4609c33ecec7c0752a2af78c9e50cae72365db4ffd4d9d5f034c4951e28cf8a206bc3158b8034ff1d147bd080f7bb7c5215e1bf86aa9ef40ebca6dc46c27dcf35d31a2dfed9e13d1ce94590fa7dea84d510c01c78a5e7e03ea7262b79991f097b16d45de0bc047f6bf565f0d5bd5466c0150d689bd21e2d4b011cf4ce4d925ee8b33a8c9d29b4da52c74554706903e0f8fc281d6b396f1f8c7a4b0b1c7cfe80e15baf1acb1670945e9f36ab648e2ae2c6d954997c2cc80ddee4ee6cb41a4e12ede533a4097a029fa4a4ec773ec05976c55a48b8f09349043b5b4a28a671479ba5b3069e22dc94788a66345e7fb8cad240ac505a4a328a82ff007dccce8d4ab68283ef9412e3b125435a8180fa0a4a56afb162ed4be7443bd5c403962e29574c00cb41c01e849dbb75a9b68cf96f89d63dd92d6eed27aaeca953f48c9963ea2c04db3bbe3d7f183d25a25d32a480d55f84827834a980560455393d3e25adda443cc509046da84f6a044407c91208f7a3f80a52b9c0cca6f2890cdd31822bc35c105bcbce2f53bf4d765625b1393ed2d44b9268cd2bc06ea4e09b5bcd5bac084fed0034fb21abf6115ab06e62168ddbf0feb95e4f7a4ce9cde2074d78a9d21c6d57f7b5cafbd44dfc3f328e2e5b5ee76589391d0fd824bbd2c3b7d43c9e8a2ad048888d77a5745e48aa7f2d7e3a12101ba7a136ec898891e432fcdabccf66ea0f52ae4d4dcc70754345454b8a8052b684ffff4a5f26add98134ee9460064916abf75c718583de2c9ceb02e2b4e15afca12711fe70cba5fb1bc39e9e95e39764a8cbcc907b0dc5c5486c44c9ca42be1102f402ba5b95234f000fe40158a79905ffbc14f40d2525f74f40a85166555322f1f70d2f4c06fb2b339a1b2af326ab74f181a4ebcce5d6e6b32fb9051a7e9cc2341be933e18cdf05087ece950e94975163b55431635214680eb1e45e63900ed1901c956df73349cc845b2a216ab50ef40049e2a0fc6b9bb803e146d5aedb7e4fdc789983c9ed8817ce44849c0ca78be6c68b159b3b8a97609dc37edcd8158226241d48b004d8f039933a65a25fa0236cb4cd74d06c94966ecad561f4a198f8487c8518669a09c76cc6ab824819b89d942325ca44e8dd2f9795174188ccc62a4d2ea26b5656cf15d7b2eae7a0bca35a67ae7e83d26ef945f036f900b1030d8f107ec1700caa943234993983d18a22a49650d76d20897aecbc70e29c154e2578275b2af301cd9257af42bda9126b6a1b51d3cc92457abbf8a38e9985799d8b2d951ba41710f283d174e059d883163a0ba2b624bc6ed34d99ce504e31b2c173a342ffb6f102b49e09585ad229b0cb2bed38bff2f439d37a65995dbae0abbc1048961f62ee362f04b4d213c22eb7ac8b7342784be7ad77a30a41233bf7b46ecb290f83833f9bc307696ea4777580c982a941c4f715fc34589d90f834a4adbccef9fe469290344b86a7dbbea28281f0561a5fbca2408e420ea552337eac8227057a935e8a52d892e0334c9ce596c635652108f790a16cbd412e96f3a9631fa5b76cdcd1d096178a1bca5a55a454cef8f0f51949590312af52fd24695dab7da521e9811855046b01d728180095e577b1c659665fd3208243b8f42903c07959e8901640a990bb89bc9cf2b1b4b0a014182183ea944e1013da0aa376dedf002b4136c0533c1ba5ef98054da57ff75b7a8ba7f0905690241fbebabec72460bbe53b34434e4158a7a4c3bf7172ab95a54de9030704f411f2e3560e193d60d7a90b8a68fe143a8300f0acaa5600cb64c89291f98d8fee99156c19c26cb4a4c86c005c5b4c74286f9e05416ed8adc9b0443dabcd45031a54a44c719b5c5a3f1d93b47208fd96a81c9eeec29d02c5bfb7d31cc52c95b380ce2b6ba652f96cdbd52d64d609064a090f33b5bf85ac07c2019eaee010202013b6c352bb2ada2e5dbe4661697ff80a0678af24fda14cada154ad109d768a34502f1ba57b035dd4df1e3662e40725b987da53ee41685d6fde29cc4b342adc9b43efd6690cfa5860dedef1a4361a948e62504cde6d35ba2d5a49d758aa21ec1439e477e9424faf023dda2409af5aec88c2b99ef188836c7cc52ba3de648ab5b38515a91687abe5cbc924935d37f1407150cd2345a7b90f4f2e6af4e259950ee6a07676a7f2301b1c4df9ebf65ec7e7ad5133889599596d0595e355e213ea6e7bf67101aceae57912a7985c82d11e8475c5e4aac4c3f01d09cb25441a6adb32a478309590a6e8a47d3a1c16a3c61608f78e70e7b7dc2dc45af4983f1c94cccf2669dd08f98f5563319a15505053770e6f11298d706013bcf3c60e3c727feaf918fe988819a1a215ecaf25eecb1cfe29232477c21f97a611945678d33728766099f9a14ab62dd78cc888b346b0709f917598638607ca9305263612d850c308be4401402ec908f0454546af35427ec40a97580069739498b124c803d968a10f1b8a7afa46ab84ddeb2511df72a696ca1b55be0bd0ecd58ec06909711c7b5a46a28d5547ee7cf1daaffc286401a45201e09ad4cec8b8c0513b6d0f097de3e6358420431f80bba358630827fa5459c551b535731f80e59c2cde40c25e39b763f82009b4f293383d5ea81074fda72bbc32106e688a10450914041825764d7fe7f58f2e0081c24e56152e6e8e475250be06c6d984c32752011dbcc593b5fdffbfeeaf99c5022f40395dbe3bec2e11dc014c3c3a2311c13d063a2f0fbad1447b00f87c80490824da5260aa5c85ca450b745158e263cab2ce3196d4056012db99b102a3100c6a3f99e76a64bac0e628ae133b3aa59006bd2d43959391a90cdacc87ac62a02ee4288121dc11159330b63de8a333fc1d77968bb7faa4b0166a25258b4e4310767b7a0ae651928a396b91d6d7048fc6fc437a0ef7237ccd4d4e66b00dd59f29ab01b4c9373985b515a7d989d8d5c8afad9b9b72a3054e9f8e195ca45e01c234ecb5d4994779a860d15374497bdee5f84618095df991e2744ae8a492ae497b846f48d88e4b58ac7ab46dd8912832d97873e79925ef0151a2d5a415c4b0de7a664f6a342d0ee6b501e22044b6513ca105ee3ca45117bee4e33cb01d461e78ed9c4204f99127636cd27ad2995adfe6206925d63354a8ce1679490e0f7895f46a9384f28f8c4a9cea12b48b675492948cd1c96aa7a9bfd9cb71adf730b7d83b4d41c28781d44e55213cfca21db544ed4b01a96fa24c8bc80f16b34abd5dd1b6899832e75082d3261a560aef9aee4651f5a150498e30e4fa30acb318fe21e917892ff3621c4646ad88b2cfa491a410c4a19df7c6091657125e3f49297b7a29809c2f7812f1e64a04c27dc801b6248c043de9bd5094749de19cd6007d97af0837aa29414e5148890be1f44c0550d3c8259770c19462f8b426bc3daa66ec46d72955555e0daf4245bc289eb0c5213e4353d5014c141575761f954003e3d0381c8e60a9a3fbe47607feab92f4dc8c66a6edad89ef52645c7d3f5570a112f49ec6a26e92761f6242c5ff7634567ca4fc4754e64e5dc591501639fd3c03633e8a2c63ede1316ff31e4988257ef77ffbcdf7a1690f58f47c9c42d73bbde0e289a73074cea6149252022552b3fdb1f9229034ea5747a56744e6707b8d03ec9245596b9a45173a2e48c1e24a0e1c0a6c41201584a458099c7f64a85d894fd7c98d51e352810e725f2a163144a8d3750888740a5e9439186063ba8a88209cd34aa2f4e11e91e0eb79f4ddba3e334eb5128b6cc825536940f9114ab0de49509212767c01867d7b918bd325894adfa7fab8669db630a03f7f3ea91182dc083cee7c83b1e644a082ebb1ad0b8ce949f2a433e7986f08c20120b1651fdc53667b0d20fb9a07bd532eae5700d443a401ba89f34502ed9f5477b62a52c0c666ae6daa0a4c659fdca3d28aa184d1994b09d9ed5661c919d488dd708f5cb11803e6132da66803d121633adb0b90039cf3170e0b37e65862bfca93611503c61074734b1535dabe239326746a2902cd32a92a0ad1aa9dab303e5c74bb4b2713989cee1cdaca26c402c1c868eaa0249d7ad4af0d6795e3d3680d09b79dfae20410ca217cda3c1760ff686ac454c08548961c5996541617154f0b87333c72a254de1e097bb386516a314600e041c444a7699478e5b34b5385e3f226ae00461af8b234efbf4b22d1e89710095321397a22a98179e92936eb336ba64d1bd35f7f30d84d07f344595035b30978e9b6c9311cd1f7723ed5346591f1188be49540c62932a08be7228441999a9d7a9075efd56ce0034a8c000928ca8416f91dec4a7433f24562e75db5632be999334f2a6726b557845a773768d8c9b8495dcdd4e474c6913676198968f139478a3f7e4da5a1821e8d25c52de7dfb4358ab744c8e44ed8a2e70a3a749341c53b230937dfde8cade31f4db385b80239c1e65f29b74681c5d8f5e876f113aac87ddaeaf0da31c1ef83695c3253864d4d8329a37741aba91c3e8a664a83f0b7eaf34b87b879b1757469a62410d51059f44711276347a1c5a3c7c7678d2f3a75368ba8c0174a1f834c1dce04c7c4fb5455f438e008cc656046e1ce7ff5c44b86bb6ac6fb3438021ecfa34b8e70ae7718788987121100e52f5b6300cba7ae0f7e0aa7d9326479bd643658ffd181b0c1f01042f5029cdc15d051113fd001a253c10c78b3f10357907dc7407ce136c8ce71052a0370a826f2a24443da59a7a38c2807410f999029f05be30586edd3b7c76dcdb8cf23e5c88df94e1ef26c93f972c6cc04283f90b5cc8f3afe258b0f4f9c19d1791ae707eaf9df318fdbf526fa68cdb9756d9f0ff85c2b923ef549a5ec073d4ad22f2904404ec439f7fb5898e27ac347a2b0b1a1500eb7f6f5635118d18852ac24ebeb50868c9efa0ae0cc5d007a401778f2e11cc6877d98036bf02fec3dfaeb801338993300e53cdb670634730fc83c9e28b1e80f620745123475ea5a4252ff5d807aa8542fb0c6f03bdb04e8525d45e9e91a3ec93c55016a322d8a7f02e8aad2b2be3d708ddd5d779dd63b89385111d5d8367e74d0f44be72d9280c1cc985debc2eced4503d3f7878fcc9b1bd1904df9d9f7eea4bd11db68b4f84df69ec13e23c66896b206517b34ebb6a6faeb6aba287327fb50c167388ca8f4cbb17044f47e952efcd10cb1e9d56c017fc51dc959d88c5bd7fdaf374f10fc9dfa2b812aa11ff6a9280e32e91b4a558c522727a8faee1a7ed56d7f00d2debcbbd3d9f15524c4491ce740c818957da3f17700e6f4d2deb0a37628284503368c8ad4b4a753eae0a4d637eb130700519400d800ea3c0c686825aef012d8b8fd9c8ed0b896918621602d239a05e24b81cbf602b9d0fd0b50000d3c38c7af7b035c6b9d8b56f782f5957386eb766d713d478c5f23e3e2507444eb57a78817369d02eed898104002d7ab2bf811f05f0bf1ada8770030925b691310db3640f63a41718a91e4b5d5a811222daf022e668e0cf15b5f4c1f40f4a14d36c3c7a7cc897444652ea15844500d1bda8c6fdb8c9946f094d1a96906f6970711a21cd58598c5d391bbfa0da0d26207503a85844ef6c57bf8683cc2400b9cb0df71e41fcd2ee2263fe17adaa5ef808f106af4cbb2a01c25b09da9e166c64c1749a1a04edecb6ee4285d50607d1a546040e8f2671d9a63500dc6a8577bdae4e8dbb37371dd292589c2163477b47401eacbb169348e6f2f1d141bc0ca8d7d2aa6246e56a4949c6e45f2ea7a064eb745193fd209a9c2fa0f38a01437e719a862ad0dcf6e347ad359e0685f6c6f138a069fd5dcc685f5d50031d0f9607636e61910b61e9e17ddc846dcc89508ad55a9045e1b13b70a17097c4022216d2102e80c3c17b6772cdd19298762b73ebbade239b2146a8db532eaf6d378ff39acc89550a640a46bf1fc8d04f7105280a6858c3e9100aa50b2f32b205fda164ed2faa9613b8b34b6ac1f1fb26e684c67f17ab955bc686244bd6d2e4124e669db06470e9c2f1a9804ce35a3eb54d1b3137bad0f8cb6d1140f8c235c56955be911004ca25d810472a90df4b6d1d0cc026440b77f83d2da8f0a17e009b6286dfb5d3f32e22bbce92081572c018b5839740794c965b8586434577dd6b4ddb3b36c6a77ef30745dbad89608b3ffd70f06d442ec0da09164087dba36f038c2820d3e6088079a6821e09bbea05c14801a2e787160dd9db28b0e2414990c6affd7ad95ee64fda22f1e1c8d6134e2054b4a7956ac8d46f5bf2813e45ecba3690cc10991684333e92900dd4fc9aa2980a385e63174ff12f998cdb4b39dd3cd4a9aa56d61e93c5113eb3473ec4d9a4c3b55d865d770c1dc69a5b6a8810e91c955d32f3208a86098500cbeb1628c9a93aa33a9b4eb22af1f7e33e77822d73b0fc3059bf9ba5f0f0726fdc4f4b639dd30a748eb8ea9e93e55cc35969d6d4b6c70345c5d16588c8233799272522d2725a20f106f60950a3eac8fc60dacbbf0e0e270a38f44f1820697be78ff8630b20a7386fb94a5ea3c5d11a0cdb9b79a743bf6f7f7de689ce18a6eabc4cfdbc4062011cb263a198ad9f06dc8364a2997469db87f15c8814167893b3c7b649e7c27ec59825a18a57a6c71852b23968563e12e22de09ac620a5db2036cb0f2706a4b579c523cf402a5b41fba1bb72953e281c457604453293ea7001e1b9147763d2a8ec587c2563f7ffb65c8f217c7395b56d648a779bbd6170c0e9b99337bbecd9ac8a82ec1b880eb4b33a5ee01484550b3a2456a02715a5b77c2c3207c6c158a69c578a549a82c495e5aabd192f10566b7a9c85941d39c1c580a6883081eb744b320304d88213f5fe64b0012f0e665dd7d62d9be9c345334a2fa71305ce4e2964071a768b7506f17b670a94ece1ecdf2e17691168d6c3ac277e2347525738196b25356f602a42400e3682b33f497062515a4bf4fed6db51d3933d5f4643451866922918cb67fef684d5022948a3515f854ae1d8e0530e84e7f274041d60005b25faa0f7b9e6137c68ac301c8dd56771048f7a4ab331d60a333053a139c4e21eb48a94dbd80872461441c324a515d0e0fa6c52e5d70e7d7e1ff1bbf41ab3d5b778e0e8c355e323b6fcec0eef53063b366676e23a35971d3510999cd83d27721f01e6ad1bb7b26d37ab5f8826089200e8fbb587294f18deb220b75a1b437dc747e26912ec11934b95e1551ff8b22e060eac8c09ae15d0b4b6be9afc75dda0deaae5e190305338f758410ce49ad9b9b75787b61a42e5dc2cb6a147a351df04e35d38c992bf985dc1cb8e87808ad4e54012de7ba0d2a593f142807ca71dbd6c5706194d3be79c0c6c11e99a2190391dd1970c88e76ed7dba93a5913e8bee33e0b6b32af9ba6f62399a6649ab915e1d6381083dea087d142d8171496ca623808337a0e0ebde307554e19b96ec224d0e9fdbc74834bd0a4a5f8dd8d93582a7634660a9a11252200046da4066c5bd4298b9669ee185d029c790179a43fc08b2ee170beecb6d3f57b19ef4e9e14720867500f83ece013679e5bc5ed613b8cbbbc4d5c9664aa790984b227b2d8df330200f0cc0a16c167a0225d6e1c1bbf3623e19077a6fb8fd20941a0b9309196968477e8c9a12e6cdf7c8ab8498509b2e7baab63fa76c25c4a5cd06b5069e952157203c83654f51f5a2b2ad1a434ed5ba2842e875d78d06dc8f595d91cb28b81a0bdff4da939462c9e045f8e914be8d359d3eed869d42da1694bc64ca56acf6000486c8e844982ca2f8ef43139f6e93d76016772d40177d16d7c457651ae4ae45dd2cd16a30f8b8f2dbf30e942c9011d8a2ae5d2a2dcf237e24e84445b37dd8435f4eeca89af80e7f6c0386824180445586f6ec821d866ac93da463624e075f1772cec40b134eb44786f78a96fff28e09468c81594d4c71260676f3110589e879aa0731a888f3b14428a4d5422d63f4076c15a77c2862b420ab1fae43b6e5f0c2f831379bf3af7fe9748aac1842d262487139e3550d54e1801c63445ce6602a56b4998b828a0c49a5485a24d2fe624e86b88d66051cc1a01b960f1cbdbe3cfdb50290400132a07819de3ae92c500584fa09beff22efd3cc9f6d7db49e5516f0d70b15b4168441806c818284fa3b031d5c5251a70e21e28e4a6ab554bed883d617c2418cab0310a7e6aabe1ff60e9ef71c54cf7c51e99d4ebdd9b48744321d5d1bbaa2ed6e2f6de673a1d97bec65d8abc57b7a749727fb5fa28cdf46bc475dd2fcb79e907491f6b935b90eeae631bb3f9576722ca14b48b7be2ee3aeb1d7bed76e5e5ddd6fba1f5dde7441754de9fa55bacb8751de8913bab1ba82bb94d37b5e0c1d5cc7baf6d3ede5bc2a0b435a4e2bf2eeb0372daf015d36b5bbfc43963ac8d635dcade75d23bacbdf7895d9ab6e48dd1ababf5c776b650691c7e9c2d415ac4b52d74e177a5d64dd8abaca5d8d783dea8ab3dd42e87011d2eeddf4d6f476e9f5f0f2d405ed9aeaf5ddbde744cfe0f9583720d17dada1678d5974ebe93ed4fdd7fdd55d10bbaff990675408ede6f4727a7d7a817a35ebadfbeaafe2a66b9be1facc689bf8c930abca77684f8956c0b8e719c67893cbcf07acd96a53f5706355fe36225188880a23fa090a0983b42efd80622050158e645920a3a3e79efacc0535e24664cb277d86a2b1fef7660e7f141ad76eb950045eb3a80522ad1dc22b8ab5b73c6c58ac4cbf9b9b927bb5045957a867ff01ed2017181711feca5a8f8696be0879c9662ba0fd6f2b3215cbedb600ebce62638facd876494f9e84ed5107e8e6d857f580f4dda4797c5757f5cc8de220280f2e4dda454c90ad1cb649e5d9b0d7d09af97b2e89b99a867dbb64a904208b51fca950279fd0046d09cd38f5ee40d794bdca940b38025a5181532d6c071840baabd90215e000569667e851533f098d91226053424ecc8565812c46ba5997b570300abb2970f659d5a6d528fa2578736588e78d00ed9a2555573bf7ac19bae4736776cebb85ef1df6f67cccd87173c51671ffeb0b2a98163707103cb76c5f70a4a6f42e04897f5d591c2bfc5ede80097d1e43b30ee56f59ff5a4fcab15fdd6cd74f8927b0eea5398ef55fe7d3f44d6bd641fff3c20beecee4ec0903f129e187add46db60bbd1da525e3033eec967aabcf936b6c2e49fa8003dd1574f501219874cedb2632f573b05c430c4b21e2471ff5086a4e74c6934d3f9b8368e66a687fb288eca34891b8448e8e2cc1b5c8e438694800864e62d8bb3d1cdd1b9f2ee83b8a2798a4a75dae39b5d0fdb0f59b374aa7e72ff32137519b284623602b02a7755a09f82ee10b290d1be4ad3d814fa6db0ccc198eda902a1181439a20f48686f5f016d9334c4c375937569b7ffd5523c106436c2fd8c75bb943e57a0c54429001ab84a78230814c789c1732e94046e8c4c017a30399598114fa5581e2126808ea8e405601b80c6418e6bff97423c83457052f37c1effc7dacfedd74108147102fd5fa380bf3ed070668e82ba913204d78e6272d5ffab557d7347489406e20b7e00a411a0532ed422048bfc0af00a0b1a80be0815509bd41ba5ee0270aa55ec546810cbf0722e39a7fd5ffc005aea5af11c90288bc48f03209ebf526023c0f64b247505134a600e5d7a8e7194f18a3d485c363d1b58e491b807a3bfc3748fc143b25120b08c5999247fcef837a74fc149423b1c2485860e00632697ac8ab9eb3c1aa39f64b0b029001c102d902b6026481a4106432498381eb0f049169b06924441db2e7ec6b6ac12881c31a647cae7bb34108826c1f85c3707edc54d8f600ad48d08d505c0632f9a6f40035952023490215d22cd0eb60a01e373c18580c2ebb02610f4d0913f8410135124ab856bbd78c8f1a972a8155098d446776e00d44a7a92750511cb095f42fd205d9ab573352e50bd60dac46cdfbf659e1d2c7807d94fb0ef2360932c11d28838bc08f1235000187ab2ba806eaadba654f65ef868daa2029c195d1347b68a1c87aeaad0b028ab53b972f4074904207f003fc003fc00f20db0889adb5de499429c9f2a95e21e722534a29a59412c3d7751fce38df70a4d134079709030935092849abb65d984491a3fee424a6e2a73fd8564f1746d50dbd3b9fb4051d2acb8569cee2bca8a43f8ee75de8c00597d4c6926c49cadda2f0b4af6ab999afc3166693740853f7512dcc277ff20875afca26b409c0600436669420081f1011392cf01a20e03043072dba55adbba8662db216c654740a22f24255981db3308aee1953e2d9202965094420821a23344af0e8a4ea90c58c1a353c7410e2e181808e5898836753caf4336ad4400974c0c268723ed9548b5f613a59a7962b2a115718bba40e2f4abea9e9a81506b93f71fb16962459b3c268b296ebe8f419f1d32acc419930419892df249d9781d44e154e03e407346e38a02315954e6a54ad96f11e21353c6c9c19666a830e54e8f2d9a6b16919e3a5599f3f5e44ce969119a9e314a652f9920a6d4ba2b63264809c8083c314a610a679b2c80f35cbf9606b187494c220bedddc454cd0771529cc7ae55f41f4543d3474002272a330a6dc29b92d1fd5ea1685d94de9c99f243b140695a49473d4149d3a897fb0257a07288c2e6245895ad3232ffa602b9f30594a1f269dd88e12c4f484a99389df9315d64f8c3ed8d63a612eeba4dd7992d6a5241f6c8513a6b53bef52ea3927c71f6c3a3661ca3b2a558a73fdea8cd584c92efe255325ac8e124a5948d09109f3ff870902e19d0688475a0a3a30619244d733bdbea47b4c973069359ddb36276809e21f7458c224b99f08ed163b23229530a7493a8a50514c5aac3ed8da2861ba50a92f9ea75caaf5c1662be89884d154c7bc18714ad8820e49984e662f947685f3794522615272ca387d79623d27618384593fdd95595ee41e61d0caf124b784913dd20fb6e208636f9a6625a1a4dc973fd8ce4464d89801f27b35403c6c887434c29cbda2ab6ea92ff7920e4698edaea477d30f223b7e4de85884a9c4f1f867e1977c4c14613ad1392de82ceae78e44986cc484e9a65a07718208533a5954f81cb7435cf77176b9adab62a525cf8ea13f091ac27c27ae5fe5523a9e2d84693e9c924d90760721cc5616b4bd9f18b24feb1884c184ba98af5d259bccd621089312ba3a84b0a04018554b892245ff75923f40184b527be6268a8fdd3312aa20082724e4e81f0ab36929c7cd9c5bae5c8c396b3bfc6012dd52a85a1377f4c1e4256a46f498d09d8422aa821a78c4a0830f26f13e42cdc9792fe5eb83bb6f64c8888d8e3d98b34bc9b65e930439793d98af32cb3a85f3141ec22c74e421f5c935b4db1380c1086ac08083e30735424254d0810783ca89a73b18b6949ae06f723c39be7630db6a9f60a5e44fcb50471dd00c2b4bd72a97b36c2ce4f88f2a41caec4e07f3dde75d0e6929f44c47c4d1eb113ae6605e7d0df5bfe35e6b92834909ea5f64b8dd5f34fde360f44ee2cd3e880d07e3096af4fb83e90dc650928e39a69d6e2fd5e106d37d3c21f465bb0de64bef954ac5b4adc36c30fe8d09195f4b0d5f91d0b10663854b265a54e6684b01e149c0c10184ffe85083f9d6f32fc813e75d4f3ad2601a17bdcc4b9ec3554783712c8993cb44cb9a1b9dc1d42d26754bbcd196630683ca9757fff94cee313bca604a2f222da7920e3298540e65c9dc741a135f0d19cce81883297fe7fc8d0e3118467aa83269fd92d8274e4247180c3aad5ce5e9f99ca7c4c376091dde9c86cee9c4afbf600af1966eeef582f9c58210e7e9a4527717ae7ab313b7994dad98756fd17392439570c1a44dc53cb1e537efa28e2d984d7afb8fa6e374bdd81d5a30ed7d527ae6dd3fef25c4fd7cc8143ab280a990915dead21d583049a635cf4787c99620918e2b98326d2d3ea592d74e4ac60b38389a091d5630763895b3b37c324c4a47158c1754c5d7621d543029c9566684c7765653c714f28ef3ba9495d7935f171f1374523ba460cab1f4e7a81b2a5ce88882c953b0f6b8b5143aa060b279cf13f3781e9c196a19e8788271942499605234f931718269b404dd1e4c124ac95213cc3177fceeb3f466e799604e41899730af6309e6a09e942cda2525983a9cb8f87e9a76720a868e249884db074f7e695b4307124c723577e4ee925462551b388e619254924cad9cfc388c61b439658276ecb929f972068e6298b4f4092bb292fbe89318a6f333311fbd3bfe05710cc334b7a2ba392ac9deaa55814318a693175efc4d46048e60184c67c9057d9ae3b10103d31d3c484be62f4ce2e2d45ce9926f2ff4456ec9526d56854b8b7535f2b282f7961ca6ed854910f9568fa6b2534962c3c6c13b0e5e98cf3e872d41d8c6077b17297da5dd84fd521766f99225d989df0825cec59ae95ad1dbce62c75b5792df4f52427333345c98bce5c63ea5a758da988170057de6020e8e5b984ee85293db45877f12c400872d4c7262e1653f6ab8273fd86c80848c88c858ae85b18332d554911686cff6ea9372b8291316c72c4c26e7e027a87d979c9418b42cccd9a4a44b905ac99249e2e00003472c4c9296539694c8115a270fffdc12b4b980031606a54774897657c2c0f10a634813b30f0e5798cbedb35af34c5a61bbdaca96b6654b75cf3ccdeece25439f943870b0c23c6641fbd4662e5c3ee158857176f4a792649978b104324315264d0f4ad250f231482e70a4c2b4ed39c4ce84bac0810aa307cf3ed87c00e21882d2672f23b951c34b1a9ec224dc67c9ab25c94a6599c2ec1dbef2f7e875f1bc14c6b724e50b7d5143059b145bae2eabb4bb751d9e3da51c1e85d1475b4e59beb38e2a0a8385eb9653ff3842612e25fe277f89bb711d14a6ca72594cbcb44bd18280e313be8f4eda4c505d042e9880274c27b7569cf8160c383a61545d51d144ab50ed45e0820924270cfa4d7bd28fe979d2de84f16af446b343cb9e18248980b489c80019b9a109639d0927c73b7b763765c22cfb6796e34149e0c084a95285ef94175fc2f4a6cade74ee78be74b1c16109c3e79874262c8921c408a4122629dbaf99f820b231250c26464428256f1abf4dc2b4b26179b115d44d2a09d348936276e364ad9f6bc9038e48987a2c6c54ec29c9b40477c00109c359b0923fc1843c1765d4a891c8e07884415e520aa9e15102b6906f157038c224267928f996653fe97cb089fc071a39333c6680848c74c88848238c96529ef49dd6f296bc0c3818611e7195f7d361fa10bc8d20c0c0071c8b30474fea55d7ab83072545184b94a45b4f8e2311a68c7867a87aa8572f5372124ed7111019365ec08108639e24fa872d9d43986a4457f024491bc29c946423f3528927d7c85108e37bed5a901bba73bf1c84307a0c7593d5ef20cce339f24e0ce5f971148449a92027ad053d9167b22aa881c7e1088479d4847eccabd97ad00d191f62839b0310a6d8d9d3e7fc273d6a7d8c1c16e4c7c8b1914118b9e4f80356b1ec6a634cbd5bb37cac73107e69a2fe317258c0c1f13132c2c1a17e305f366972beae9bc5f203ac0a93f6492ac928413ebfa930bd68115969c162afa830d8a7480b699652509ec2a0e24f990a52f468690a83dcc53b154f5c44a530e5ae20eaba39290c361f74bcaaae52988cc21cd6a669aa4b4461f435dd925e234a6a4928cc967368adb1d4410a0a63c5d2f1e3efafcaf409835dda2755923c6192c4c4ce897fe9a64e182f48d1b024cf0983c79ccfeb1f59d9df84b9a468116abce25aaf09d3499fb9519e4c18f6b26e9c7c4225318409839e494ae91111a7722e61b293827a7ac5e7e558c2e4392a8ad2719ea25c09838a0aafcb2f254c6fb735df97c4f1741226f5f9fbbe939230a53f490811ad2261bedd5d4be13a90308993d352546d8ab6ce23cc335b7ada29b47a92234caf7b4932370b96fd469894f849a8934c18614e25c9b13bd48a5ece224c175774db3d5bd88b220c625e45ceec449872927e6f225dc562441877f4ca2cff9e68da4318845736c9f7358441e4986c117ee9e52c84494a55c1e5469f1426218c6d3909ba94386f826c10a67c26eaa912cca365451026d94356c6c711e656098439fb870061b6bffe2cffa46256fe80074f1955dd0fe6fa792b15b7b5d3ee83c92e8e0e9bd712223e984e3a0be1fe274c76f760d029087562c57ac57a305f8b1e1d6b1ecc2e7ad4f9a5783099ec15bff6bb8339c7495a449576305556f2ce72296bb93a183fc95972796c74481042c8f3cf5acfc1f84969a8d5fa3442d57230c9a8feea8dd697521ccc696d9f544576551c0e462f9d4bd408bdc130ef234225533d4ae406937dbc29b96b0f0fb5c17019fa3f8657149d840d2651c7732baf3598048f3e7b6aab4e76d4605092da2739c53b7785d3609273eace1f677f5e643498a4554ad94f9413d9f1198c9fcc44d39db1190ca7f38c302fd9affc32984ed465a98eb7e1276430783c75d24236bb4dc6603a7949145d256230e5d35af154faf76c87c1204b67f3e3c67ad082c15c2697d2299a4c4ba25f30765730c94b5e30ca999e57f4e4ffc92e18ed635fb7ecc5ff920b66bf4ae2762ab7600e7d1d4a27cfa99d168ca2738e995fa7f27559308a2ad9e7795b2c9884efe027bbed15cc2ba78458e8c5d69315cc41df8ba59baa6052ded9d3b253d03351c19caaa37988eea8ea4fc1d427e90bbd242779232918ece4caae2ec9841645c1dc37faf7f6de2a28818271ee5a4d499a6ae9f20483bafaebce75ae753bc19c3c44aa5eba09a6607f1f3d9f5bd033138c6a32c593bb4b30d78f4a09a61b694a2979b424985c2d0927f2c63d8a86048392d23e8eeef079bd631877cf4ae82842c6620ca3afa969db8a613e41cd7897f061b4a6c43088948f32ae0dc36c5eda73ca63e8662a0c734e1f2b6997eb9e4a83612a532a0973a6835e1230cc298791a7f3bf308d6c8c7a2f6194ecfb829d7dcffff47b613ae195f37249d0d6f3c218ab5aa12e8db9eabb30fdffeb29f9dd924e7461d86ded24654f2ecc23f37bdbcbc4380f2e4c2a9e3b4e7dd2fa975b18fc527c7f4ecac2a5d8c264e94185c9762d4c6a61f2c930a13e575a18d552f6f924ad5baeb33096bc54a7722a0b9370e287fd598a99672c8cff7ad2c68dde37818559c5da4d5d2e5f613893f2f44f922b18b968af1ea65698479aa5ed9c7e84fbac3097a68a7dc719b39c5518ce7e2df4e4ad68a20a93a47167b25352618e514f4a33541843c9d36bda97baa44f915222fc047db229cc39a6e9f025a514e6901e3474b2f029aea4305f92426d864661364918dd1f11da9e8ac2dca33b4ee8bc1439148651da4de78a7cba101486731925cf7d8a957cc22016432825c7d013a68bdbc104a5c24e184fce29e72f53c1c7424e98e3bd5cbabf8739a54d98d5e4fd88993ea9e49a30c82bdd75c29e09839fbd27956f553909268c71a5f774782e618a919febbea48f53b184397e99c99dfaab84f9bfe4fcaf4b09f39e64e296ba9c525027618e3f5acdd3f98f1825615215524f4c353bc945c298f2a9c4c95d694d3b481854904f9d5a2b9cccee1126d5f93d7ad6aaef758e30e82c3541da9b6c5e5d234cf9f49274ae7e57d531c2e426a7ff1599351b5a84b9b2945cea278a307c8ad7e9de245549893056aa4ef52375748a0883c9a57b74c58a501ec2a0a4943f076d6782aa18c29c93bd5ab6ba10a6de17b724ec57384b7ff1c38330d7985c2e72bfab654198f2a4104a4e6a5a9403613e91f1e649de2f95058429f8772595a42f53d23f982d4992a0e412f4c48ffac1bcf9bb21d45c929df6c124d42939db9412cc523e184f8af638a54a1247b907a3a9f423dea2be45d3f460ce4fb597d3cc83d96d47b6bec9fb56e2c16079754dafab787f7607934ecfad346d3da9991d0c3bea92f4252c8a685607835a4bb24952d492974407c3bb9fa0533acdc1242e49a1bfe29efe921ccc9adb41e9949224d57130557b9f54c2c16469fed2c28434417f83e164f9fc2eba1bcc7e552a4ec5d0d1416d30578d8e2174101b8c57733d622d073fd11a8c9f4b2853f293ba6851832997905d49fec84a953498b37db455caa2c19c4cea6798588207f70c86ef4a65a7543318e4fa49eb6b49977019cce9aa372cc5899592c1fcd94c6754f2b4dc8dc1a0c45f0c79366bb75589c1247f0c154d8979f5255961307dca5652f894625fcad7402f984281c1b836d23a97dcbf605dc6bbbd785ac8c5eaf86c51f289ac4982ffc1565e30499d8332fb924baeb5aa0be6926925593e8f6122545c48aaa7aff821ac2d187dc6e74eb9a985bdb2775da6c6abd7ebc5d3f569a9da56160c2346794ef9ce55410d3c6a5058306a48efe05a5fc154826acddeee18ff90154c67294ec6e560150cead57639c2945052904851c114dac376baf2d3693b3505c35eae79de393fd8a4600e1b65926c4af688b61f6c782021231905c3b5883a412e37c6836c302828982bcd9224c90a5a6e4e912718f54a3a4ff2f555e96bd47082b93dc6a68d58dca86e06d504c3253968cb6ef557ca144131c19cf27a4b92a4be874e9ba09690a4c52a2c2518c3ed7c734dbe888e6f25c1dce7a6e494d57bb70b09c66cebb174c24d10fa3e3b86495909fd1e5c94bc26c518265982bef0dd9e2d86717b33440cd3a9ecbadb6d7ec8304cc2e30459329e1fc46cc230ca49f15db9aea4124f1f6c3ed0609843094af283add3c88d326098e4fb13c424fffc5c930fb682444066e42f8ca162414bd6764b612e41872f4c62e1b405ab245b762fcc76268a67bf796198bdb45f8613afe3a81ecf56124901e2217d1684ec5bd73ed8fcef5806780793a4bc4a76bcdbb8bc201a37928709d00ee6b0aff77bb2223550d7c1b0196332342f1b403a982dcc7f4e594bbe2e3938076349fa4e89e19e1fb3837230d7971c95837e1de360f0a482d041ac2465c3c124a527a9f49c341584928d1a6f307792f44dc5995cd51c037483418f29a57298c90949aa65886d305b3ca9233f55de6ba0e7410d1fd0280107870818816c30aa992c39467e7efa6b0d66d39ef4a8c5a806b34793b55cb2c8fe5b300d064fdafddf4af2d1602a9db486e797eeec9c3318deabeae7e33efea56630088f23f65bff83924f1a60194cdadc73d6de3edd514206939ce3def3d7640ca69cf3c8d28ffd95223198fc3b89bde25fa353270c0659420a06a3b598b0a1bfc42f98dd84aa28fb9f7126e805c3c45ec3c552b06daf14b4546fb6dc74494bd205f3dcbbe9d91dd11d6711b151c3a3900b66ad68d5237fadde1d8d238305885b3076f05379f1839ed3e1c7a1164c999697fb3e6300b39055d66856cc5bbaac7026a79cdf4b59c482c9d34e094ab89c2b18be6409bae72dade2bf080216a040042e98809a26d00a7cb977785d6d886c85d1258daead94c42a2c77a544f9091da9603cf9ea94ec789eaf94e0140c4add892daae45c4b270d11d0484f402998c410b95ee27a2b58ea83cd460d8f432460140c3aacadb3cefbc14603a1602aebf58a71293f07133ec1d8714d977f3d22726494ed009d60fc142cdef67e12bd0f0ac22698ca2413cd32edb4ad432f036482410997bd8ff9f62f7a1f888c849c11912598367dafa42474b76cab1aa804a3f89f244c8c8b93ea43a3c68c1935108660124cea5795df7f1dd038211e6a238804e3a86579f224aaaeab814064bc40051c1cf908448688d9cb4812101a770c63a95c6277d06fd501a146e2c103746424e5658c243744560535f0a8c0196359ed12844a7e128262182fdd9e891a9d2742ec32561084238651de2c98ba4f0dc33c6362c9134bc7eca84e1826614de5557ad4b5985f304c96f2626aa2c5c1c1c131850386490e7d27c99b17edabe417c6fc53dbf9a2993b8dbb3ab116eff255d3f13b7e9e9ccdbb5e1876adde4b12345e183cfdbbdededc85712d49e275094a5d1894d29f4d10a57d827a2f1706d5d034b58f7f4a3e8b0b732c3ff1e27b720b83e7ac7897bee6399dd8c2942eeff5d80515cb502d38d178f9acbaa07a5bb93c7a4f0be3e7f50adb4fa5fe4274b859983edb28397d9770b230f889a6ae73f0b8658a85d1cf47ffc84fbb9d5f5898ce4407b7bbec15461bebca15a6f30da9a2f7d30ac42e2cca8ce5504b277a95b4b2fbb7362b0cb282ca13254fee746815d65636bb9b4ba3f19d756fe1ec842c13cfa20a838c097f429c1c97479c0ae3792a49e7d36e264e438559dcae4b924c7a8a4259123f5318ecb7cc47c7afc4b74b61ce65ee152f67cb49795214b5bb3aee2bd7a76dad658892b398d5a33075da553979432913af1385295dd8863eb19d47edd9830b85c153570afaea2bea754440e1ba5b8a5a49ad4f982fe9bf699fd21f4dda13065b3dbd2b4149272849d7097357b8a09fa4ead239bf5e384e18d46bc7b84ba10f3619c7ecdce881b94d98d2b7a5aa9cdb7388f35d5034613aadfde741492f13c6aaffa417ec04214a4988e1e038210f72983098a5d56c0f51f273b62f61f4b10f4afea44a091a42219c258c9f4227259c9c4feeb815e12a61f8b060a9c3dc892fdaad0a6ae06183a384a9848659c951547616651c25dc24cc2f4ac57512164a9c931cc249c26c52c5933f6ab288ae46b848942b5cca974ebcc141c2a04baf07a5fd5dcdef7b8441eb99de7aadf4f88f239284d59ff8a88db811e5fa12b9ee107b7b59cd3ce11a77a58212de3946982ddde52aed27d494d8224c9e54f80a72564ded451179892faac43bf3126152feaf972daf890afa21c2f425871357f62fa9b97708c355db7fceb69e214cdb77ba5784acfcd10049f60a61ec38d144b124e57ac9470873e6b789bf3519fbfe06612e3be526990ef5d3f69f208c26331fd5e402618e3ab25f8210f5b59d0e0e10a9a552b1512bfb0aed4e69f13c07d3ae87bc0e745043c62d10ee0f6ec8b9bff6d12b91c1f9c1fce147e4ca8c2cf1751f148bb714626e25df16d54a506a3c4e759658f1f8603c133de588aab894f3116e0fa63ad94ecb98d827057170e8800648c88888c78dd343fa29492d0b7342270f57b2bf92d5925f94c6e121edb157d24299279d34031b77874cc35a5ebbb3dae325b19e46bff4ea23221e36446670eee0ec603ab7ec7152086509ae0ee6ea4f82b613db5309277430aa7b8e65793ee751627330b7c94a9e2773474c2707f3f625f18adac5c1249ed2d5c1c1e849e9e93149c91b4c49861026ba17dd3de706838652fa96a349137f5d1bcef8545bb939ab4b66d244ad6851d7e4d860165929cec7d21a8c76764950693f4689abc1a4be453c76c54e17940663ef2549c9374283a99327c9c4efcae549ce603a25bdc74fd946891e3318e647c7d22e6530ec08919e7193c1d41a97b28dc1fc39aec991264a3ea518ccd7e361e6bc8292c63018cdb4fcdb6779972e81c1204dbb2f1844ebe44ef67bc1b027ac855c3bbfbb0b26a5d484e90b71c11cd482103b275b309d64668210134f44470b06b9962a3c56b260d0f9d35b5d8d05a3e737256cc65730fa5bba7072ba24955ac124447a6ead4fd258f2ab60ec92fa79a194b426f6543048b91735da340583b070c19485f2517a2918f6635ce7fb5130eaa8d86f224ab47728983ba885dc18f917fd09269d24bd52b932490e39c1e8490aed67254d304965951e6b4cae799860104ab4a52429f7a02f4b30a7a6aaf6f77c4a3089b85df83709a696d71a1d91f2be1e124c49990996963c865174cc536951725bd08d61b494214edbb675febc18c613f6c4b3b29c180635af1794cacfdaf961182f9a7af219cf345d18c633f5f3e8a76098ff656c642bc030a8feeb906f3a55aafcc214dae49c4bb6a074dabe30a8d0e14e16a1f2a8b917c68bd6a2836b658d14f1c2a4ca42dd785dca268a7661146149ed6249b2a514e9c26c99a7848b622ecce19df359958f38e1c2b4fde14d56ad3a93bb85592dd693203d4e3c6d618e596257b9a96ecd502d4cf5be7ae2b9cc2749b4302729c5ca836cd7d02c4ce13c78ee139dbd735998449ed83f268a85295b49f23142b030456dcf35695ea94a5e6110aad54a1631492eed0a63bf9eacdeba15464be993480baf92c40a838725f511b29d6f5e85b184d01f5a7c76b316d8ba80d905eeea22f0a103101a17280e5e0ea34001021084e402fe22228f6a84d858000046446eb8800001781d9c1b3aa0716420400022218f6e788d101b09880100020000000040000b00000000a080f71a342e20d2ef35683480012b0262e32c20008900808848c24100019c91e31c0508c019395e2384e300001800041210f21e0c0040001e708020d8e005828cf800c477812023323e448e87470252173666a05c24af3123152071615cf53c13363d086dd25b00e1cc4804485b1c206b812023211f22323c3c1290b430c5afe8a973bdb3307d2749127a61f2a7bd6561aa3e0b2ab7eccd95508d19337e06cff8199bb1c8aa64f9bb1cb38166fc8c9df1335013168906c88c54807c050d90198900e90a933039efe53fce2e5e6346fa1839337203d90a0419f11a336e7878242059617259339959b26398f083fbecc69987bf1040641c10f436448a8dd00041111a202332406e241e212dc8558cbcc88c9f61805485d798910890a94840383352011215083222e3c60c0f0f04e4294c996b623fc8c714e67eef20634adaf81db314064f5be2fdb32895a693a41885716c8ac2943a7b10f2f4e85bf364288c9e2dc8bbd7b7fe17144611622354e446e315e4274cd2579f9f245e8ff484493095bf53fc2a41cb101b40f84e9892bc8e4f52d65f7a13274cbda6b43de8b44f3a64426ec2e8a62b3c090fa6e2b7d4c4952aa558a92e7d651bcd36794866c258f964dc73ce0942942270c1041213e664b2c7eedb4a55335ec264f52727597c63d52a6909e3765ae94f59a98451fdc4932ecdfd9f7a29611c4fd13357ee244c954f98d60f3296ed9384e1d35c0a3e62dedeb48c44f2f5ae2297d6522be4b28dd07ba71adad9848439bfcfc4550ba33dc224687a16154a6bfae97070a4238c955f6ed1ac64bb20fe60f3b05163cf04d908f3a8df761125c60873caa8ee9ce453d7cf2fc2f4ab57823a71f74b5a146192f784caa23d904c8449ae54ce9ba1eb732d8c08539e7ac9a3a64b16cfa143983aa7e792f25677bc3b6908e30533adabb2562a540883ca1bdba5122184f94bdb9b0e2ad7c120cc7f5549befdb5fc1c09c270f2e93022fe48e3200361d6bea43b7a98db5c8e0e006170cb5b51a2a585ca655243860e3c465ea4d81f8c6392e82728a52ecc637e309ca04a92f298c925057d1fccf94f2a4916bdd926a7201f4c3a66265f540e22eb0f6a84e8600fe6dd3693c3789204bbfd834d0fa62ccb97041f59e447b4069907a3c55392924eec9c04b58c0fc183c984efb2587ba972971b7807b358e9854e2e27fd441a20891d4c1e4caf6ea7e8880f505a1d4c9220ed9467e9d7ce061d0c7736d25b3cb6ce723f0793a404d9498e92fb602b72304949dd79cebb566a486226838c8371b6f333c7a46839367e4424657088c68d942a483898f20815d3c193f20daaa8979c87a757fecfbd56da04991d0e0e37184bca33f7bf62b6e19465477f967daacc68241b4cd963625e0304366c9c909155410d3c6e906b3065c4c2dd67cc254ba5de56f24dd492d4e239483598d693f89877d134985d3cefa9ac9dd4c8190da60c75722c693c4b797f06c37a9c1394ecde0cc63329995c921cce949c530673573ce9697d2383612ffcd8889534f623442e30432167390663f52561f721db90111b2906d3e7effc24491eb530988338c94b54f23269a604832673c962ddad5adec5ed5a56944eda7112e4174c3254099e37cdf482c13bb848f5f4c92e98db243769bba28dff13a8a0061e2e482e98542c754bc7452fc73fd86cac6dc1a467ba3d94ec95fd93c8d91101c1d4827188c0059d055350c2633cde050ba6a454a509f369547f2eaf60b090a3f27cc765f52aad6036314ae6b3831ac82a982ca6c71331f53962ccc54052a1b94aa55ea72d6259ede5144ca17aefe24af61c264f2998af3ca5d352b28a783ca360ce3115fcb2bb75be100aa69caff760a97c82c9478967f1b2934e30951244454d5213d7441f6c2320890648c88708da07b209869393eeb3133da88f950e24138ceb2979c96df15c82179eabe7243d359e0f360fa3412ac1e8a59f6295ee83d13c904930894b7fba6e3a5b094a9e4622c1bc2545ff1e773fd8f818a61b517aa55f9d52461f6c42e8c17b84241e232033decc18e6fb64d9d1c35a9f30fee0699462a0426c8ab4301a0f6880bc203d80c43056ffc9e1243fdb123e1f6cc330d8a7cf262bba73e3000ac3a43fa4cbfb97efbafec1e6f13e001939323ea42e18d6ac59b433710fb54ad1732895a4e4e2df0829d6c030f8a8784e2a5b481715d1b8210210fcc2e47174cae7259ed2657c726478388d2f6f230830f819274404692f03847d61d269eb63ae27a47fb017869357c4ecaeafa8517961be8ba6d2a9b57117a6feb292e2093a8a757461182594b01667920bd3769f24fb4fb034b9425c187c2feba756d589ad6ec1c69bab5a0adfa51dd75ef25e50137eb0d53822201c1c323e3928e0e07819203666d4401c1c2c40c1a22d0ce22bf7c2dce42446570bc3d5c591abf849848ed1c29cfec4ec5de66fba6916e6184b4a897f0e29a69785399824a8fc21be047142b1306a7ce509164d4ed21f58184c5578b4e4c19368e32b4c9dd4ce6d4cec0a53692dc93636bcdeeeda56186dacc489134dada88f082b4c925ab14f4ae9e0a75d5c853989e96c71848926070668daa80a9368e6a2ae63d2dabfa9309992b257befc537e212acc16a746cfe675d78d33c0536061561d6fb39d366aa77da0298cfd5be779f6a4507e82a530b577f04b625ddf4ea79014e620c65198c3a5d47759944461300bf5ef24e93db92ca130697a0963a269e75853c9fdb48f50e169003ff103f44410b013e911a7656aefe43349c809c3b48285db8ba5ec953a4775f1e0260cdb167af5834c13c6ad784947e4a5f5e83013869d5382dcd88c983086502a7e5749f2323b9730ffecd58e7f32a5e7ab21a3aca025ccf296e3f2f9c70e0faa0496bf4af5c196dc10c112e880064872e3053b05a484d1eca4a9f211da4eca380993b0f8d1c46e64953c3ed0c899718792304d89956a374c3ed8426c00e13d641c1f7c62244c76af5fb515e4724148ce1ed1382322344a900609b369114ff3a21f7e1f3e42b170e9dd6d2e887a59c54fb2ffef9ca90374844168d7b21cd637c274c19364d7297950254698e452be2df33f96b4651186932d5b8a3028d3237af47789308baa8b735751829039228c95e4bcfc5582fcf2d0210cbab492fca8723f416c08a3aa0725cb4e8cebfd0a6174cfa1795a374218439ab60f2dd5208ecfda56595171d30ad71022ae65dcca4f4198468bd82dd11d1716d141c8f1b00b84c1646a494a673f893c68dc08f1a8e108085332d1d3abb5ac05ff60fc2d495e4ada154ae68a7e30e9132e9fe8174fa50941807d30f6de9d9ede356444d33c66dca071c807f3788f2511d332a2f4b80783b0b21cc6b41bf22325b002eac1246fa851f2a8fc1425f6c126e2a1c6031a373e46540598878951a8642c858342d27030168c44025130105236cb0100e312080020601c8ac502c2509ecab9aa071400037044263e3c242220180705428138200a06c3602028100604018140301004851e12b5466aec6dd202d642c7d1043a3303790457422b52b1483765c50ec603e390758149ef1a47ccd51a256ad7a2e30d23725ebd5c390a40dda5cabbb9717f88fa83d8b896bc0928eac4fa97dd102efab30dfb58fa3bded1b9d10e8546d76a118e1c7db2e8731f9f7d1d4d1ccaa4110e4e65f18d10bd829455e32ffae1b30f91a700bc1ca8a529d8343d6a8c7151890a723baa76852b405a0c5136421b3b0652fa88f6dfc192d60c7b43bffdebbab681df7f89f73aea123ce3b6576a6073f0fc6250e4f2cb84ccc00f8aced3ac643766987c360ba84482a1b0f5c1aa89f0bf35e10272e09a962168652212740c44ce96238fbd12658eda8941beef21a08cd2a481450f73a0818bc4417dd0255067cf95fa01007124cea80f88831e7652235a0a50afb1d7e731cf341e044ae71b71316280a05e5c349e3fa2d75c7f7a3f2d8db63885800b15fbad77d2f0671046049a64c10145aa098011d16299e65000abd35f9542496231ea457845d2a067cad9e46a030ccbbbb8ed374887fe5c083bd8fc8e6cc4ebccc5cb17862b9da243a72582a8118a599d8b36ba711a87d89898b4002a655995ca2be404f2a23bdf430e88093b2a0690be06977f38b56e30d0fab96c7ea6cc82c62cff16440f2171544c2d025c61f1925ad00fb72917faa9302493f43b14ee2a6f4e310a7bbcef9458daa0e7863a7c43752e0fe720907224f53870c716e0a3225ffb68efb1cd035717e80f26283493f19f6d3b39b8414abe59f047bc24ef9d6d088edc2de906c7843cdd04319a535bfd982e4459fd26ca2b9b1228e28e41497eeedbaf08a387f5a87a5e51bfa44cb2b9465972c196215d675b0f2e6260dcd11756f37f755e2c86b95d9a01d8102b782d16da29d22b8ae7b4e6f8883ad1f322e26fa57c80bcae8b747476d411b7adac62c233c2619ed943a4b876ea232ad1861471462392ef62494bf68e048d312d54568079b57794281c91f827e3c0a18f157c5b0e1c65d24a58a827e17c1a5378c930ffd84f3238cd837c11b905fcd88eb61f864b6079f339f45faddd987b29f6f8072eaaec4800ddb11689b7ecd78fb5204973113050a121e0fac233b40a106490989d6fff2515f0da8486682c5b705cf471df6279ec4965f206ca8896e32b9c34d589a659f18aa264672d106e0e19b5d3b1c66f6390c4519a8cd6d17f805b2f8677b6a7a8bb647356f9bf3effacac6914789ef01a39d5d775d634ec2c8921437e56501c775ea6f98e4ef902b0adf5ee88f9aa49c5f7010e6b16e6efebe134896b0c5d3c43afdfc09ae7f0588987216b055276cabb102522c103b7badfc9c42befd4e2deef1f42548e55c7de9985927e5a47be46ce1ddece4bd331a29b5a9d035deab7216ddc26c9261fe9920ea204740d41889a950cc5561d63b0070a4f8848e66172d69fb4f4a9ef5ad9a29ac9fb3ac05e14932e6ecae241ff586980da5d5d4a733f2f2a57d089ef538953137aa0883dbbd042f48f1de869728dcb57129f478199153eb1a7fd9760b4d585c6c808a537107d605516310bec2e7388d483190439d129e099ad6b04d5548a42ce1982aba0223972b107efb78e2568732db94ee9bee544b10f31adb6b1f9d8867460ac1bb5c450e40a5985c0c316ff80aa34138a361bfb291b466255a3210c72f296335e37c5073a314e7775f146eaf05ee224dc4393f28a7e8ca114448643bc0083899467574d3303e26854d5aa238a4786530804fb26961674882cf1a3f164063260b83eaa32e434b781cfd15f4a93c3bf8358b63dee87d00e9828574a92a5d539b45c37f24bd7a8c5d683da32b2f45e6859b6bca23221cb529d871ad042bda4cadf28ea4ba5bf07521e0cb0089868bbac1be6d46010ff54b331c81164211d7baa4711a898b9b49a27257f7e4017886c659e9aa19e4f9bc9bdda25c66d0fecde1dd224c7b9eab77faf1fc35dddf7aac41fb3b8102a30b9442c76cb10dd6b614bf1e3e692041d902e9b4e035a1d82665a484b778bd1bbebfb73897f9e8e0f23423eacc2d750314760364849fc49bfe1496c7f5671daec006a8f4b8305a75c00b937b20c78b4a94605cb0ae9324c8529847636b603f7ad512d5e02c681621a52f767082127b737acebb3b5b11fd93d8039027f1a47afda0ee071645304ce4bd77e458ee384159e6b5b587efef9df2066adc1e2932155486c8ab88e3a39f5616307c6ecaa44b573ebc61c2081d89d8428e997d17d016ef43d30b788b71182ab1e471588c1cced97288a4640029a6f51a74a070490db2c59403c751c0aafbe6102aa00dc361b6bdec27aee50f94a7be8695ece5ec5dcb98a80a8e18d4dd63c68bfd2bc9e14d42ff2ceefa39cef1e11084f0f1a99495a9d4c9f412748abb5e2fd1e0f45c9bd0608118b0a4460278b3723903530dd94d965419d70ee3a751e3e04a9e15008f8e51223fd921cd8a55f2ca5702231a0f64920d6b8679e79eb2c9ae29045d1bb37d4905abbafa59cbd9c5b197790ba6fce4a497be58a6a2f7a1cf12591b29226dfb22d392429adb9abc66b59f03ee64fd6d081af2197e63f971f24841804c03b129090293e14dc23bdf2f50bcd29f3e25e29e31f0b9ea46ef955319c7d788e140e97cca1ad466a0785adee2a000653f7b5b09b13463c8368dcefebbb4e761c2941bf36b6dc215e57731fd5c6633297dd722db240eacc4c98632c89e6a23d3e925db23fa3c0d4b176cd1cbc307bd7b22f6081302011e1eed53f45c63cd3d845e220701a9600d2670f78b802e9fc65c602827741b57fa7653382338de1e8f7d485d20a0bcc46f2472c9fa2bebf602c1e04ccc41210268a32699e42e3b906e50bcfba8837ca9235d17958ce868c2615f02ef8e811ae58cd7ddb196f550b521519713a543e5f8a62024e558258d37082aa6938d7e701d01b83d938945a8c84b4d1cd167b00ba7dd9edfe07c50e653f2844167133d42fd970dfacb889930514cc0581bc948ef89fcf0bd66b7968021791b468518ab65870c72a1ba2ce420d3bb897c5a55d275278d0fa7f67e638e742e83e872b2302b4b5f7bbe0a70d290cac1ac56c52d24fe589f3e1d3afcb49127ddae7004546bff062c62ca2dd8885450a3219cfd50fd84e4da6fe0fac56bcf6f9c6bcf64278b465a209adfed5c614a057ededcb7bff2c0088965aa85afcfc4d04273366da26af227c9971d84092bebdbffd14a074121d1ba617910216d1bf8edb6371c10b601340450413381867dc080cc733a50fffefebfafb7f80b51b00fdb7cdd170e0f13237e0679bac452723101dc83234b5bb1196f5165dc2aabc208994c186295fbf700b7d18e255965977a86f0eef1a2fca416265cdc114473f318f992231e0982fc26a1f35c3f8f7f5a43736b3dbddb3d1056673b6da7f83a3b609a38a86d8abb86a566bdda4413ffadaa1d6551aa6a0317812f3fc1c7769a3b8417da10e8a08cad44af99a7a8b45329702d65d234dc41b0d419d5e12c5abbb88b95e9f8161b439610ea18a474f62c40284c81380bcdf8c038a89ae78c34098f036c5047fa69d3dd1b878c53dfe695b5f8864d32d390a5d7ac2f38cb4d087e5984056ea6afcfa9ee0234576a10a784af94d92fdc6f56543da896a18e9d798f36a8506ea22f48f3eb5c22052a76de41527395f18b92e0b41ce1e4f41026061715a73fd0ec0eed3ffc31e1fc66525340bae443a40628a57f349ed51beda8ae2359c5f76249fe3f9f8429858fa18208315a9a298333d2380014232466f68e3d545191ccb7ab62e2a2984d5bc7ea28cf47c366a6218b6e0a8f67ec25ed86fb8b580b2cc49d5d9fa7647a0ad14fdb25e430260a5c28218c6e48745e3c70a16aacb1e4f074503a254cceb27b9cc0fe3cc191a1c72d1771522c51ec0a18d9cd7b6d9991028474346be9c31ccc2cf988bd23c0ee7c4cc1f4f6ab499061df36abf8824cd42b292014f9be97db9a9331eeef10ee40cc8561cfcbe8e4d364cf0cd954ff8d7ef613bb4be68fc195bc2ef2477dc962cc25551bb74b22d0477100727b0964eb70bbc1ac0baae647db86ddc9b4ab7cc4d0e12f150e764f73ab808b767bf438e3a5d42f9fa298dc7abaa9639303301689d189b64235f0eb415965d1ab3d466d6c6d1b07d4baf6075793f83dc77e41e28cfb80885827f8a506d32265c5918d036c3b23798a08f4b8268671e8435a73d7d9b09eaf040dba1459bb5d3375286baa334784e1864f848bcaeaca8607d2d18571c48938125c65eb8dfec2fd33904df9d443641eea5c250f71caddca2882c2824851a965b2751e525cef9efdddc11c54158d7dcf74f83f29fd681d17852d9d57f3948befa84fbec052cfb8109234973ca65d8d9e6bcef4f9854e5803b3aba0f2e8abad37568cc5464bde14ca3c5e76839ae278c151449cf0bb104080756b907292fe9ca1f72a631ad64e02e3066e31aa73d1b795b1c0ac4939a7314e94416dad496d5fb159fe49f9a1e5eb428c573b8aa35b47385f21441503d741872fd1730b2cbe066093f3d511c0dbe264f381361cb6f93e62da6e55c6445320de65a10040c8cfba98f908752c813f049a27450466a0517d21ce714b064cff6992cb05c330ad441f9b7862a904439ac5ecbc22b8e72375c6fe8d7c955391cdb338bff23904a681f7176fc53f05aaa07bf301b23ee5bbae34a9354369c25aafb7a39a7767509f09f5a364eb3ef5918d91ec179b9b594392f67a8fa435de527bc133ad6b489b2cc523252e7101ef287191f1f1b9854e4d2b16034c533418f616e6c3a96d426c1e246a90e70b8edb2bcd8e6e21fba0dbf250ba4d465dc788d6b750c00cbfba7e2477bf29fc19015786a729b9e3058c35d4a87b0236f7c74341f05766b4a6c51b7f990ce6736332bb7fa53b9e2882e5ee4ed3cdd0379cc9711b47fb751849d1f75f8bc1b060da4c1fadce78177c2f5c4daa6ff1c6d23eb9d9aa9b6e71369f96e243fb31702478756c77a7bebb81d6d48d478dcc6f9b44f43f9b8f29626f7d994b2fbfdb7c55d4f231dda56dcb0a04bfae52a949e6222815543d7c8a555e8241b5bb7173f9dadb2bf16c6d359273bda357b1ad603dc39140a0c02de290e0ab967f7d379854037bb712fee010c1b6e6b09d8e791fa9f9cb3bc5e60486070ab8986d4b3c480dde0e139601c63c3db6e80381975661f74cf32d8af7b38a2c15aa16710675ffa66547743fedadcdad5306fd14dd7813f249c0ecd44af802d327629e3f81be6b1e6010e004cf56a4faf4880a5e88267aa3a6143b4023ba0ed8f2d6bae6b3be370c09e5b89816926aa207db24e6c87cc073a506722c5a2d12d164a4fc0b025df68d9a52341d4142cf498c1505cbd386eea446a0dc7d8882e70b3adaac404fb45050d1eafc23d4576b21188fec0d7a55ccfc5c0b11104abb3bef167a6e10db4168d7bcd61d62c2df5106c33f57ce2cd51f9c26a0010e084986ec05be05b01c67d8e24fa75201be42b8ad29d07e5531891819b74cb2e78aa619632a0569c3b08210530dca661705a0b594a0f7b21cf172b7ae737aa68d87521b74265216d15274714d8592723b617e08ac5b7080ff010818583fa4619a6327d301130e484633028ec95fdb9c1e4906da575af185d373bdb36a85b4544b350418102531123f04398b8476dea4aa34d8c916dc5766f20dc60760d6fa2cd0aa41b9241ce69291ae44cb7ff4c2570c5b68a30001c1dd0fa442f211b1033453a6a1d3dde5b2298cc981ef9156de0659c54ab5fe378236de6c201e347b168210166de6508e669563220711a4702d104c0553efbb62bed3c724155ee6b7833365d579124d058ef11269c5f0f9eeee6ee19ed91bd1bd456d8ee55ef52f6673fc3bdc53f5d15d61e617c144c35d3752333791a4327592d30f0bb0da70f402e6e2790a3fbf842fdaf8da4b15611049a6b1f4a10f5446041f13edc03c0ffdb413a5ffde64d99e149fd68d044bc15b2c549f6ca4ebb5a80e1a4f9123eee4d989aaf079c113557af7f72a2af066bb5f58bb64e75792814005e2040221f6560e26ba7f67e8f86d98916a0442bc6a16464423454616b05976c11325b58510740ab5b4e222030173489cd49ebc29db438166d9a4dc29c8dd41a9c909833e22a67e56fdd3ea909ec3134f92edd68f6fa546e32e9803d93be02884671a1bea34854efde78ec6ecbc2487b5e2e6e48ab7731f0463cebb7bb9f6705b7651e911ab10027e22a19c9dfa324bf79f58f9550a965bda60f8fa030a6b25d7066f22df78ab82c01273d5ef08059ac93da83b522fc007601385e234f9207022f1bf4d96ca922b3d0fbf056b0aa5917e05a89962c79944fa505135c0339cb9c0a628096b65abb3fe79304a144fb142a8e0eddbbd63220c0f5420e1245927826e4124f7c2df0c75c9d6bc512680fb4bb91bdb0ef343ca5ff242152ab8f9c9d92af3b9913036e290d36d60ed53254d15ab979b5a2069914a0bc11fae5477c133419a3f144dd01704a3e7394026ec52d8f0dac21633949149988a4313cf04aa59ab45a70e03cbd269034fa25297cd3f4cf0185e94cf02cf8def2d91642c560bb061377f9ac56471eb2e908e0717acf103b1987701ba470dcba4c3147be0a26cc1915c99eefc75186ff1252abec10e15a52c67179ec0a4ba586ea31b0642303260191e6e2d1d19deda9d37e4cacde5ca9526068caaf02b6233613aa1d21b1473d9ce2e5d95ce5fae69681356248550d7eb45ce136b8028cbe1df541cad7953c25b197ed3adf32d3f9dd3442552f7767fc5c25f445c1a7ea7461007a2e3c30d76123307ac379982cd193ec6cb1d2a109ec509f0588a1b70a4fb0def95285a750f55987fd7460a90a46fc30c4dce33ff4b000f0e63bb1298c4681830dcdaf23c8a67db30e028f07db816a5ea9606b94f235838a5aed97c9fd322b9d37e887aa7596c4d79b6c5ef6715f28c44bbc4abfa191fed1d3e4527f0e0ca7865daba8858234f57140e3cb1e754f5c78370c587dff4c6e5d8f2418142ab553573f18979b05f95c489377cfa275a50118d20c6a33bcb519bb26b5e2c495b9a3a6749b6b4f921db042f860729ba77af44107b6a1d676c4a7c99b86565d489f1b302186761f4bbb386773373ad5839b53dc23655a6bb4d20cdce7d4dd7c0ab8e90211b3cc0cf6a2308ebfc83fc0c1e834d6dde20581862b576c5179b4ecb5f6a04a3f784bb73543a44b59408ebdc6a1ac8031710cf5c31171493c14ac4c3f9abb283cadb04a5adafc9bedd363e5fbeba67692caa69abe260c0d791cfa6d37e1055381dec62006db84d9f47421ef5e7268e5f2a85b3cded468531775db7d6c33763add8c7f2b89682527c30070e44b4d54102b476757c037d26d21613222918291bd762089bfe886d8172676723bd8c176f67a69663d59d06d2ca0babc54bcabf570a740b848f8987c959eed4a236bbc73ab7ca7138cd3962e80565749aff806cebe8bb2168c44b8d2d3c1c2c7fe26078956a5e887925ec48289f394a19ad789321abd6205972db2e6144671c9ad757a31db7fd97091db7e875762db7c01b601e4862242eea8ba4d980107701b795616499789361055ea7da88d4b1ff4c0455740b9cb2290e2d6c69268f7596bd5889b86f0b92823b0e43c4955236ef6f26c6dcd4adb9917de652216aa62b551a55af86dab96f4263fed1278db316990c2ffc914b2fe6f424254cfde29d37699582021d6708ff2ab76f21ed6a39b13054b6b3fa60e9ed2b681b050dd4b0af3efaa0ec45a912e549b4b682d289b1df507464d66ff2ba8f2e45e9d3bb6ec63c10fbd82dd9a6e49c945233587e82da87eaaee4490390263344fa1660982dc1959f12574ffde37845983cca07922fc0f75319ab217e664ebdc79b194e02ac958ab816519587e1acca4fecb0bd963aba110cc0a754e3b1413448113ce9cc9dec2b2c9880ab7fb3fc4098a8d445926786c6669651713894f8ba69b0698d636d372b785030a76773c2ba0a11dadacb9cc33f18f76e9134898c88705e007f12d45c3f696de4481a13c4486fcd568b47437371ceaeb5c3bbb211b4f9aaef4c1e3a0f96683ef45aec90f51bf23e2dc2dfb9ed2d2cb7fb80c7520b9dca4032174de30e58bc7f9d9eaf40e869664e87d170c6953c16d12b4758d79324d47c9c34f97aad2aae7eb61c798f9af34c2b96625e0536c5b0931fdceedec387b929fb164a0d5715f16f3d2de3bdd5f7d282223f65dc46e093632d9e08cedb10ed5d3554c263aecdea0540a43a5d83c29314bad4497d3e7f1c1edde729ec51d853d29c15977801fd36064ec15ac8fbbd59c7114f4dde54835c9ecedef3255a250cbbbbcc45151c92a692a04141c321052343bd200faea101ee8c72d9e605146904c45061c7a3acf1d34627048a871c6deba7dd1a8e9801162eb2b0540608481cb0e7bee262d2b89f93e462ce078802405eb63f2695d4edc9d3cd5c02a22b6c7bd95d37407b29e2a113da40679f1304aaa5ca92aec08acdc985f77f232a0b0f9de32c0fed3bb13b859e65913248b6bc2b71c186f5ac48375fd05bf7f45ceece8ca65b4ce327e75264d1d12486b1b6e709726058d8a0068a1107ac1e01a1b6cba60b1ca0054543059e9b5da1ba58686329ec3245355cf99e2d04e27d07f2446e8fab54a0ee41cd453004aae1b66c5d69e7a2a8a9f87dd546f7321d027a2c7aa358d0405fec0eb110622567ce455278607f05c1b032c04f3f1220deb220e2fd5f5552769bcde517a988ce1354fc0425935c8d220ea3c853bef1109994bebc66f2c26c29614bd832f0d890382d35814224e0c173d2e83b37cc3d8c8779e6a272c324ff5297d09e2f234b3f3c256219690a43d4c2d585a94460249e5c0c09d9448e457cdd9921bcef82f63ff8c0c8ca4b410345011c01f28db20a6d39865840299fa90757222b5f0da0331ec443241d43b115a342ef2a6c5c3395ee0b243d2bb52c3b9a82fda19439d382d48894b31eb3a24fa1cd85f42983a9c3dc992a52230a8d91e0e4badd33f5fe7471d01ba4b7ae89b7ee66e220b4288403e51640a34a984a3367834bb2ac8db6bce2341b144808087bf0cc3de51b9b0abb71f75d34f1b124c4a6b5b1c95897b20d828842804c2141cda623d4a2ca134e219d7dfd0f2754e25900a3dd8a30f1fdc87e27f58958cd7af7d8446a7fb3d96ade5e1bcb3f015de47e3d24db8508579347befe9324125afada274e2981d0358d5248a18122e124b615985a6c0eaeb99689270c2626c2868649c5ba7f6f17a0c7438e648f89d0cc57e7463b43a9262f489b0e650b9fa04306300b20632a90e1b6f4e3d69b3a4417cead386a6ad8bac776f04447afe5c4d6868fdaa95000ad5e1ba60af4460e710147baf586fb7a8816adfc98bd6d43932cd16b56e1d04d9d5d8bb032f57e89cca12d3cbf259ce0a8b4e00f8341494a94aeae4915a8f8bf7a202a3ca1291fc211451a6326810a12e25b1e4f9b2b41b44eac41bb016ac6c0d8c19cb8558052632c3892187a008f60b18d9471c356e8082187c6c16af703249cb6ada558ae264398b686694036bfd2e64d93506574dfac010bda8652fa7792b4a1032fa3b77e7db3e9a9a9d665b50ec1491e483b6b93959870cfb8b9a3e2c5d724ab616f69b970a425ac3aba6fe3677558506eae0262bc934d8a1ebde696c56230e5b55ba283e9c44c117a9e745f38e26cf98c39a435e1254db2813ed291394a19e866139934a3623652fc44808d60891689b3d2a35be87ad5ebd891bdf0c03d1bdf495c5604e5461b57736aa4b802a43d9b406ca00adcd9f337f13b8c64a7e58700aece3d08afe38918b9e9bacbcc02e67a94d16abba965ec0c53090747b6e93864c03897375fbb6ed9cce93bf84511dbab07a8cbd75abfdcadd7b0e099b19bf371dfd0a", - "0x3a65787472696e7369635f696e646578": "0x00000000", - "0x3a6772616e6470615f617574686f726974696573": "0x010888dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee0100000000000000d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690100000000000000", - "0x3db7a24cfdc9de785974746c14a99df94e7b9012096b41c4eb3aaf947f6ea429": "0x0300", - "0x3f1467a096bcd71a5b6a0c8155e20810308ce9615de0775a82f8a94dc3d285a1": "0x01", - "0x3f1467a096bcd71a5b6a0c8155e208103f2edf3bdf381debe331ab7446addfdc": "0x000064a7b3b6e00d0000000000000000", - "0x3f1467a096bcd71a5b6a0c8155e208104e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x426e15054d267946093858132eb537f105fe52c2045750c3c492ccdcf62e2b9c": "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d", - "0x426e15054d267946093858132eb537f14e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x426e15054d267946093858132eb537f195999521c6c89cd80b677e53ce20f98c": "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d", - "0x426e15054d267946093858132eb537f1a47a9ff5cd5bf4d848a80a0b1a947dc3": "0x00000000000000000000000000000000", - "0x426e15054d267946093858132eb537f1ba7fb8745735dc3be2a2c61a72c39e78": "0x181cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc208eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a4890b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27de659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e", - "0x426e15054d267946093858132eb537f1d0b4a3f7631f0c0e761898fe198211de": "0xe7030000", - "0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429": "0x0900", - "0x4a83351006488ef6369cb758091f878c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x4ff3897794d496d78686afcfe760a1144e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x5c0d1176a568c1f92944340dbfed9e9c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x5c0d1176a568c1f92944340dbfed9e9c530ebca703c85910e7164cb7d1c9e47b": "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d", - "0x5e8a19e3cd1b7c148b33880c479c02814e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x5f27b51b5ec208ee9cb25b55d8728243308ce9615de0775a82f8a94dc3d285a1": "0x01", - "0x5f27b51b5ec208ee9cb25b55d87282434e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x5f3e4907f716ac89b6347d15ececedca0b6a45321efae92aea15e0740ec7afe7": "0x00000000", - "0x5f3e4907f716ac89b6347d15ececedca138e71612491192d68deab7e6f563fe1": "0x02000000", - "0x5f3e4907f716ac89b6347d15ececedca28dccb559b95c40168a1b2696581b5a7": "0x00000000000000000000000000000000", - "0x5f3e4907f716ac89b6347d15ececedca308ce9615de0775a82f8a94dc3d285a1": "0x06", - "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe700e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", - "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe70e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d", - "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc44f9aea1afa791265fae359272badc1cf8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e13000064a7b3b6e00d13000064a7b3b6e00d0000", - "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc4de1e86a9a8c739864cf3cc5ec2bea59fd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f13000064a7b3b6e00d13000064a7b3b6e00d0000", - "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a000000000e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x13d4fe63a7b3b6e00d13d4fe63a7b3b6e00d00", - "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a00000000e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x13d4fe63a7b3b6e00d13d4fe63a7b3b6e00d00", - "0x5f3e4907f716ac89b6347d15ececedca487df464e44a534ba6b0cbb32407b587": "0x0000000000", - "0x5f3e4907f716ac89b6347d15ececedca4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x5f3e4907f716ac89b6347d15ececedca5579297f4dfb9609e7e4c2ebab9ce40a": "0x00", - "0x5f3e4907f716ac89b6347d15ececedca666fdcbb473985b3ac933d13f4acff8d": "0x00000000000000000000000000000000", - "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a000000000e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x0000", - "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a00000000e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x0000", - "0x5f3e4907f716ac89b6347d15ececedca6ddc7809c6da9bb6093ee22e0fda4ba8": "0x02000000", - "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e169030e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x0000", - "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e16903e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x0000", - "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a000000000e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x13d4fe63a7b3b6e00d13d4fe63a7b3b6e00d00", - "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a00000000e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x13d4fe63a7b3b6e00d13d4fe63a7b3b6e00d00", - "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade980e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x00", - "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade98e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x00", - "0x5f3e4907f716ac89b6347d15ececedcaa141c4fe67c2d11f4a10c6aca7a79a04b4def25cfda6ef3a00000000": "0xa8fdc74e676dc11b0000000000000000", - "0x5f3e4907f716ac89b6347d15ececedcaad811cd65a470ddc5f1d628ff0550982b4def25cfda6ef3a00000000": "0x00000000", - "0x5f3e4907f716ac89b6347d15ececedcab49a2738eeb30896aacb8b3fb46471bd": "0x02000000", - "0x5f3e4907f716ac89b6347d15ececedcac0d39ff577af2cc6b67ac3641fa9c4e7": "0x01000000", - "0x5f3e4907f716ac89b6347d15ececedcac29a0310e1bb45d20cace77ccb62c97d": "0x00e1f505", - "0x5f3e4907f716ac89b6347d15ececedcaea07de2b8f010516dca3f7ef52f7ac5a": "0x040000000000000000", - "0x5f3e4907f716ac89b6347d15ececedcaed441ceb81326c56263efbb60c95c2e4": "0x00000000000000000000000000000000", - "0x5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3": "0x00", - "0x5f9cc45b7a00c5899361e1c6099678dc4e7b9012096b41c4eb3aaf947f6ea429": "0x0400", - "0x5f9cc45b7a00c5899361e1c6099678dc8a2d09463effcc78a22d75b9cb87dffc": "0x0000000000000000", - "0x5f9cc45b7a00c5899361e1c6099678dcd47cb8f5328af743ddfb361e7180e7fcbb1bdbcacd6ac9340000000000000000": "0x00000000", - "0x6441fb391296410bd2f14381bb7494334e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x6786c4cec8d628b6598d7a70ace7acd44e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x682a59d51ab9e48a8c8cc418ff9708d24e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x6c63e84bfc5a0d62149aaab70897685c4ba24bcd9ac206424105f255ae95a355": "0xb104000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x6c63e84bfc5a0d62149aaab70897685c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x7474449cca95dc5d0c00e71735a6d17d4e7b9012096b41c4eb3aaf947f6ea429": "0x0100", - "0x74dd702da46f77d7acf77f5a48d4af7d4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x74dd702da46f77d7acf77f5a48d4af7d62556a85fcb7c61b2c6c750924846b150e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e01be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f00b304f91831830500622780fd38770500", - "0x74dd702da46f77d7acf77f5a48d4af7d62556a85fcb7c61b2c6c750924846b15e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f0001fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860eb304f91831830500622780fd38770500", - "0x74dd702da46f77d7acf77f5a48d4af7d7a6dc62e324093ba1331bf49fdb2f24a": "0x02000000", - "0x74dd702da46f77d7acf77f5a48d4af7de5c03730c8f59f00941607850b6633d81fad1867486365c5b304f91831830500": "0x01be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f01fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", - "0x7a6d38deaa01cb6e76ee69889f1696272be9a4e88368a2188d2b9100a9f3cd43": "0x00407a10f35a00000000000000000000", - "0x7a6d38deaa01cb6e76ee69889f16962730256ea2c545a3e5e3744665ffb2ed28": "0x00020000", - "0x7a6d38deaa01cb6e76ee69889f1696273f0d64e1907361c689834a9c1cb0fbe0": "0x20000000", - "0x7a6d38deaa01cb6e76ee69889f16962749d67997de33812a1cc37310f765b82e": "0x0080c6a47e8d03000000000000000000", - "0x7a6d38deaa01cb6e76ee69889f1696274e7b9012096b41c4eb3aaf947f6ea429": "0x0300", - "0x7a6d38deaa01cb6e76ee69889f169627ba93302f3b868c50785e6ade45c6a1d8": "0x10000000", - "0x7cda3cfa86b349fdafce4979b197118f4e7b9012096b41c4eb3aaf947f6ea429": "0x0400", - "0x7cda3cfa86b349fdafce4979b197118f71cd3068e6118bfb392b798317f63a8910c174c55fd2c633e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e": "0x04e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e000064a7b3b6e00d000000000000000000000000000000000000000000000000", - "0x7cda3cfa86b349fdafce4979b197118f71cd3068e6118bfb392b798317f63a893e73123ebcdee9161cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c": "0x041cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c000064a7b3b6e00d000000000000000000000000000000000000000000000000", - "0x7cda3cfa86b349fdafce4979b197118f71cd3068e6118bfb392b798317f63a894f58b588ac077bd5306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20": "0x04306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20000064a7b3b6e00d000000000000000000000000000000000000000000000000", - "0x7cda3cfa86b349fdafce4979b197118f71cd3068e6118bfb392b798317f63a89518366b5b1bc7c99d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0x04d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d000064a7b3b6e00d000000000000000000000000000000000000000000000000", - "0x7cda3cfa86b349fdafce4979b197118f71cd3068e6118bfb392b798317f63a89a647e755c30521d38eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0x048eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48000064a7b3b6e00d000000000000000000000000000000000000000000000000", - "0x7cda3cfa86b349fdafce4979b197118f71cd3068e6118bfb392b798317f63a89dd4e3f25f5378a6d90b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22": "0x0490b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22000064a7b3b6e00d000000000000000000000000000000000000000000000000", - "0x7cda3cfa86b349fdafce4979b197118fba7fb8745735dc3be2a2c61a72c39e78": "0x181cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c000064a7b3b6e00d000000000000000000000000000000000000000000000000306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20000064a7b3b6e00d0000000000000000000000000000000000000000000000008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48000064a7b3b6e00d00000000000000000000000000000000000000000000000090b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22000064a7b3b6e00d000000000000000000000000000000000000000000000000d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d000064a7b3b6e00d000000000000000000000000000000000000000000000000e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e000064a7b3b6e00d000000000000000000000000000000000000000000000000", - "0x89d139e01a5eb2256f222e5fc5dbe6b34e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x913b40454eb582a66ab74c86f6137db94e7b9012096b41c4eb3aaf947f6ea429": "0x0400", - "0xa0eb495036d368196a2b6c51d9d788814e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xa2ce73642c549ae79c14f0a671cf45f94e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xa37f719efab16103103a0c8c2c784ce14e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xa42f90c8b47838c3a5332d85ee9aa5c34e7b9012096b41c4eb3aaf947f6ea429": "0x0100", - "0xa8c65209d47ee80f56b0011e8fd91f504e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xaebd463ed9925c488c112434d61debc04e7b9012096b41c4eb3aaf947f6ea429": "0x0400", - "0xaebd463ed9925c488c112434d61debc0ba7fb8745735dc3be2a2c61a72c39e78": "0x18d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a4890b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c", - "0xbd2a529379475088d3e29a918cd478724e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc632a5935f6edc617ae178fef9eb1e211fbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x047374616b696e6720000064a7b3b6e00d000000000000000002", - "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc66f2e33376834a63c86a195bcf685aebbfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0x047374616b696e6720000064a7b3b6e00d000000000000000002", - "0xc2261276cc9d1f8598ea4b6a74b15c2f308ce9615de0775a82f8a94dc3d285a1": "0x01", - "0xc2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x0040fa7f398074858a02000000000000", - "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb30e5be00fbc2e15b5fe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e": "0xd17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae698eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a488eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a488eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", - "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb3e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f": "0x88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eed43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d", - "0xcec5070d609dd3497f72bde07fc96ba04e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19500e3a507571a62417696d6f6e808eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19505905fe216cc5924c6772616e80d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae69": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195066b8d48da86b869b6261626580d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa19509d4a4cfe1c2ef0b961756469808eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950c9b0c13125732d276175646980d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950d62c40514b41f31962616265808eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950ed43a85541921049696d6f6e80d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950f5537bdb2a1f626b6772616e8088dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee": "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f", - "0xcec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903": "0x08be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25ffe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e", - "0xcec5070d609dd3497f72bde07fc96ba0e0cdd062e6eaf24295ad4ccfc41d4609": "0x08be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eed43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860ed17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae698eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a488eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a488eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", - "0xd57bce545fb382c34570e5dfbf338f5e4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xd5c41b52a371aa36c9254ce34324f2a54e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xd5e1a2fa16732ce6906189438c0a82c64e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xd8f314b7f4e6b095f0f8ee4656a448254e7b9012096b41c4eb3aaf947f6ea429": "0x0100", - "0xed25f63942de25ac5253ba64b5eb64d14e7b9012096b41c4eb3aaf947f6ea429": "0x0400", - "0xed25f63942de25ac5253ba64b5eb64d1ba7fb8745735dc3be2a2c61a72c39e78": "0x18d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a4890b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20e659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c", - "0xede8e4fdc3c8b556f0ce2f77fc2575e34e7b9012096b41c4eb3aaf947f6ea429": "0x0100", - "0xedfb05b766f199ce00df85317e33050e4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xf0c365c3cf59d671eb72da0e7a4113c44e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xf2794c22e353e9a839f12faab03a911b4e7b9012096b41c4eb3aaf947f6ea429": "0x0100", - "0xf2794c22e353e9a839f12faab03a911b7f17cdfbfa73331856cca0acddd7842e": "0x00000000", - "0xf2794c22e353e9a839f12faab03a911bbdcb0c5143a8617ed38ae3810dd45bc6": "0x00000000", - "0xf2794c22e353e9a839f12faab03a911be2f6cb0456905c189bcb0458f9440f13": "0x00000000", - "0xf5a4963e4efb097983d7a693b0c1ee454e7b9012096b41c4eb3aaf947f6ea429": "0x0100", - "0xfbc9f53700f75f681f234e70fb7241eb4e7b9012096b41c4eb3aaf947f6ea429": "0x0000" - }, - "childrenDefault": {} - } - } -} \ No newline at end of file diff --git a/substrate/zombienet/0003-block-building-warp-sync/chain-spec.json b/substrate/zombienet/0003-block-building-warp-sync/chain-spec.json new file mode 120000 index 00000000000..a7964c0cf14 --- /dev/null +++ b/substrate/zombienet/0003-block-building-warp-sync/chain-spec.json @@ -0,0 +1 @@ +../0001-basic-warp-sync/chain-spec.json \ No newline at end of file diff --git a/substrate/zombienet/0003-block-building-warp-sync/test-block-building-warp-sync.toml b/substrate/zombienet/0003-block-building-warp-sync/test-block-building-warp-sync.toml index 7fe9b0f065d..2b29a42e423 100644 --- a/substrate/zombienet/0003-block-building-warp-sync/test-block-building-warp-sync.toml +++ b/substrate/zombienet/0003-block-building-warp-sync/test-block-building-warp-sync.toml @@ -5,24 +5,24 @@ enable_tracing = false default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" default_command = "substrate" -chain = "gen-db" +chain = "local" chain_spec_path = "chain-spec.json" #we need at least 3 nodes for warp sync [[relaychain.nodes]] name = "alice" validator = true - db_snapshot="https://storage.googleapis.com/zombienet-db-snaps/substrate/0001-basic-warp-sync/chains-a233bbacff650aac6bcb56b4e4ef7db7dc143cfb.tgz" + db_snapshot="{{DB_SNAPSHOT}}" [[relaychain.nodes]] name = "bob" validator = true - db_snapshot="https://storage.googleapis.com/zombienet-db-snaps/substrate/0001-basic-warp-sync/chains-a233bbacff650aac6bcb56b4e4ef7db7dc143cfb.tgz" + db_snapshot="{{DB_SNAPSHOT}}" [[relaychain.nodes]] name = "charlie" validator = false - db_snapshot="https://storage.googleapis.com/zombienet-db-snaps/substrate/0001-basic-warp-sync/chains-a233bbacff650aac6bcb56b4e4ef7db7dc143cfb.tgz" + db_snapshot="{{DB_SNAPSHOT}}" [[relaychain.nodes]] name = "dave" diff --git a/substrate/zombienet/0003-block-building-warp-sync/test-block-building-warp-sync.zndsl b/substrate/zombienet/0003-block-building-warp-sync/test-block-building-warp-sync.zndsl index a4ba46017a3..1d8650b5d69 100644 --- a/substrate/zombienet/0003-block-building-warp-sync/test-block-building-warp-sync.zndsl +++ b/substrate/zombienet/0003-block-building-warp-sync/test-block-building-warp-sync.zndsl @@ -13,18 +13,24 @@ charlie: reports peers count is at least 3 within 60 seconds dave: reports peers count is at least 3 within 60 seconds -# db snapshot has 12133 blocks -dave: reports block height is at least 1 within 60 seconds -dave: reports block height is at least 12132 within 60 seconds -dave: reports block height is at least 12133 within 60 seconds +# db snapshot has {{DB_BLOCK_HEIGHT}} blocks +alice: reports block height is at least {{DB_BLOCK_HEIGHT}} within 60 seconds +bob: reports block height is at least {{DB_BLOCK_HEIGHT}} within 60 seconds +charlie: reports block height is at least {{DB_BLOCK_HEIGHT}} within 60 seconds + +alice: reports block height is greater than {{DB_BLOCK_HEIGHT}} within 60 seconds +bob: reports block height is greater than {{DB_BLOCK_HEIGHT}} within 60 seconds +charlie: reports block height is greater than {{DB_BLOCK_HEIGHT}} within 60 seconds -alice: reports block height is at least 12133 within 60 seconds -bob: reports block height is at least 12133 within 60 seconds -charlie: reports block height is at least 12133 within 60 seconds +dave: reports block height is at least 1 within 60 seconds +dave: reports block height is at least {{DB_BLOCK_HEIGHT}} within 60 seconds +dave: reports block height is greater than {{DB_BLOCK_HEIGHT}} within 60 seconds dave: log line matches "Warp sync is complete" within 60 seconds -# workaround for: https://github.com/paritytech/zombienet/issues/580 -dave: count of log lines containing "Block history download is complete" is 1 within 10 seconds +dave: log line matches "Block history download is complete" within 10 seconds + +dave: reports substrate_beefy_best_block is at least {{DB_BLOCK_HEIGHT}} within 180 seconds +dave: reports substrate_beefy_best_block is greater than {{DB_BLOCK_HEIGHT}} within 60 seconds dave: count of log lines containing "error" is 0 within 10 seconds dave: count of log lines containing "verification failed" is 0 within 10 seconds -- GitLab From fc749fa7a0d45c74e2e575dc39ec16418efed902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=20Vilhelm=20=C3=81sgeirsson?= Date: Thu, 11 Jan 2024 11:44:09 +0000 Subject: [PATCH 034/392] Fix coretime migration (#2905) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The XCM instruction limit of 100 was being hit by the 1 large message before. The weight ref time also needed to be bumped for these extrinsics. --------- Co-authored-by: Bastian Köcher --- .../parachains/src/coretime/migration.rs | 44 +++++++++++-------- .../runtime/parachains/src/coretime/mod.rs | 2 +- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/polkadot/runtime/parachains/src/coretime/migration.rs b/polkadot/runtime/parachains/src/coretime/migration.rs index 64c10f73198..c720cf0617a 100644 --- a/polkadot/runtime/parachains/src/coretime/migration.rs +++ b/polkadot/runtime/parachains/src/coretime/migration.rs @@ -142,8 +142,8 @@ mod v_coretime { let new_core_count = assigner_coretime::Pallet::::session_core_count(); ensure!(new_core_count == prev_core_count, "Total number of cores need to not change."); ensure!( - dmp_queue_size == prev_dmp_queue_size + 1, - "There should have been enqueued one DMP message." + dmp_queue_size > prev_dmp_queue_size, + "There should have been enqueued at least one DMP messages." ); Ok(()) @@ -264,22 +264,30 @@ mod v_coretime { let message_content = iter::once(Instruction::UnpaidExecution { weight_limit: WeightLimit::Unlimited, check_origin: None, - }) - .chain(reservations) - .chain(pool) - .chain(leases) - .chain(set_core_count) - .collect(); - - let message = Xcm(message_content); - - send_xcm::( - MultiLocation { - parents: 0, - interior: Junctions::X1(Junction::Parachain(T::BrokerId::get())), - }, - message, - )?; + }); + + let reservation_content = message_content.clone().chain(reservations).collect(); + let pool_content = message_content.clone().chain(pool).collect(); + let leases_content = message_content.clone().chain(leases).collect(); + let set_core_count_content = message_content.clone().chain(set_core_count).collect(); + + let messages = vec![ + Xcm(reservation_content), + Xcm(pool_content), + Xcm(leases_content), + Xcm(set_core_count_content), + ]; + + for message in messages { + send_xcm::( + MultiLocation { + parents: 0, + interior: Junctions::X1(Junction::Parachain(T::BrokerId::get())), + }, + message, + )?; + } + Ok(()) } } diff --git a/polkadot/runtime/parachains/src/coretime/mod.rs b/polkadot/runtime/parachains/src/coretime/mod.rs index 60bd8f81193..aa074a293c9 100644 --- a/polkadot/runtime/parachains/src/coretime/mod.rs +++ b/polkadot/runtime/parachains/src/coretime/mod.rs @@ -252,7 +252,7 @@ fn mk_coretime_call(call: crate::coretime::CoretimeCalls) -> Instruction<()> { origin_kind: OriginKind::Superuser, // Largest call is set_lease with 1526 byte: // Longest call is reserve() with 31_000_000 - require_weight_at_most: Weight::from_parts(110_000_000, 20_000), + require_weight_at_most: Weight::from_parts(170_000_000, 20_000), call: BrokerRuntimePallets::Broker(call).encode().into(), } } -- GitLab From 2bdf5dca67a914bfaa6a10a51a5ec85afd3e3c0b Mon Sep 17 00:00:00 2001 From: Alexander Samusev <41779041+alvicsam@users.noreply.github.com> Date: Thu, 11 Jan 2024 12:30:17 +0100 Subject: [PATCH 035/392] [ci] Remove unused jobs (#2502) PR custom review is deprecated. Now `review-bot` performs these functions. PR removes unused ci jobs and adjusts zombienet jobs for merge queues cc @Bullrich --- .github/workflows/review-trigger.yml | 1 - .gitlab-ci.yml | 10 ------- .gitlab/pipeline/publish.yml | 3 +- .gitlab/pipeline/test.yml | 38 ------------------------ .gitlab/pipeline/zombienet/cumulus.yml | 8 +++-- .gitlab/pipeline/zombienet/polkadot.yml | 14 ++++++++- .gitlab/pipeline/zombienet/substrate.yml | 5 +++- 7 files changed, 24 insertions(+), 55 deletions(-) diff --git a/.github/workflows/review-trigger.yml b/.github/workflows/review-trigger.yml index e5fcb434fd3..8b23dd30bb2 100644 --- a/.github/workflows/review-trigger.yml +++ b/.github/workflows/review-trigger.yml @@ -10,7 +10,6 @@ on: - review_request_removed - ready_for_review pull_request_review: - merge_group: jobs: trigger-review-bot: diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dc4b3cf162e..5e01feb8479 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -275,16 +275,6 @@ cancel-pipeline-test-linux-stable3: needs: - job: "test-linux-stable 3/3" -cancel-pipeline-test-linux-stable-additional-tests: - extends: .cancel-pipeline-template - needs: - - job: "test-linux-stable-additional-tests" - -cancel-pipeline-test-linux-stable-slow: - extends: .cancel-pipeline-template - needs: - - job: "test-linux-stable-slow" - cancel-pipeline-cargo-check-benches1: extends: .cancel-pipeline-template needs: diff --git a/.gitlab/pipeline/publish.yml b/.gitlab/pipeline/publish.yml index 92ebc9eea1f..3b77f5363f6 100644 --- a/.gitlab/pipeline/publish.yml +++ b/.gitlab/pipeline/publish.yml @@ -71,8 +71,7 @@ publish-rustdoc: IMAGE_NAME: "" # docker.io/paritypr/image_name script: # Dockertag should differ in a merge queue - # TODO: test this - # - if [[ $CI_COMMIT_REF_NAME == *"gh-readonly-queue"* ]]; export DOCKER_IMAGES_VERSION="${CI_COMMIT_SHORT_SHA}"; fi + - if [[ $CI_COMMIT_REF_NAME == *"gh-readonly-queue"* ]]; then export DOCKER_IMAGES_VERSION="${CI_COMMIT_SHORT_SHA}"; fi - $BUILDAH_COMMAND build --format=docker --build-arg VCS_REF="${CI_COMMIT_SHA}" diff --git a/.gitlab/pipeline/test.yml b/.gitlab/pipeline/test.yml index 00d2b22c810..e75700ffddc 100644 --- a/.gitlab/pipeline/test.yml +++ b/.gitlab/pipeline/test.yml @@ -96,44 +96,6 @@ test-linux-stable-runtime-benchmarks: # --partition count:${CI_NODE_INDEX}/${CI_NODE_TOTAL} # # todo: add flacky-test collector -# TODO: remove me -test-linux-stable-additional-tests: - stage: test - extends: - - .docker-env - - .common-refs - - .run-immediately - - .pipeline-stopper-artifacts - variables: - RUST_TOOLCHAIN: stable - # Enable debug assertions since we are running optimized builds for testing - # but still want to have debug assertions. - RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" - script: - # tests were moved to test-linux-stable - # the jobs should be removed - - exit 0 - -# TODO: remove me -test-linux-stable-slow: - stage: test - # remove after cache is setup - timeout: 2h - extends: - - .docker-env - - .common-refs - - .run-immediately - - .pipeline-stopper-artifacts - variables: - RUST_TOOLCHAIN: stable - # Enable debug assertions since we are running optimized builds for testing - # but still want to have debug assertions. - RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" - script: - # tests were moved to test-linux-stable - # the jobs should be removed - - exit 0 - # takes about 1,5h without cache # can be used to check that nextest works correctly # test-linux-stable-polkadot: diff --git a/.gitlab/pipeline/zombienet/cumulus.yml b/.gitlab/pipeline/zombienet/cumulus.yml index 409c0aba68e..c473f5c5fed 100644 --- a/.gitlab/pipeline/zombienet/cumulus.yml +++ b/.gitlab/pipeline/zombienet/cumulus.yml @@ -5,6 +5,10 @@ before_script: # Exit if the job is not merge queue # - if [[ $CI_COMMIT_REF_NAME != *"gh-readonly-queue"* ]]; then echo "I will run only in a merge queue"; exit 0; fi + # Docker images have different tag in merge queues + - if [[ $CI_COMMIT_REF_NAME == *"gh-readonly-queue"* ]]; then export DOCKER_IMAGES_VERSION="${CI_COMMIT_SHORT_SHA}"; fi + - export POLKADOT_IMAGE="docker.io/paritypr/polkadot-debug:${DOCKER_IMAGES_VERSION}" + - export COL_IMAGE="docker.io/paritypr/test-parachain:${DOCKER_IMAGES_VERSION}" - echo "Zombie-net Tests Config" - echo "${ZOMBIENET_IMAGE}" - echo "${POLKADOT_IMAGE}" @@ -30,10 +34,10 @@ - job: build-push-image-polkadot-debug artifacts: true variables: - POLKADOT_IMAGE: "docker.io/paritypr/polkadot-debug:${DOCKER_IMAGES_VERSION}" + # POLKADOT_IMAGE: "docker.io/paritypr/polkadot-debug:${DOCKER_IMAGES_VERSION}" GH_DIR: "https://github.com/paritytech/cumulus/tree/${CI_COMMIT_SHORT_SHA}/zombienet/tests" LOCAL_DIR: "/builds/parity/mirrors/polkadot-sdk/cumulus/zombienet/tests" - COL_IMAGE: "docker.io/paritypr/test-parachain:${DOCKER_IMAGES_VERSION}" + # COL_IMAGE: "docker.io/paritypr/test-parachain:${DOCKER_IMAGES_VERSION}" FF_DISABLE_UMASK_FOR_DOCKER_EXECUTOR: 1 RUN_IN_CONTAINER: "1" artifacts: diff --git a/.gitlab/pipeline/zombienet/polkadot.yml b/.gitlab/pipeline/zombienet/polkadot.yml index 4112096a2ed..7f5d424ec1b 100644 --- a/.gitlab/pipeline/zombienet/polkadot.yml +++ b/.gitlab/pipeline/zombienet/polkadot.yml @@ -6,6 +6,9 @@ before_script: # Exit if the job is not merge queue # - if [[ $CI_COMMIT_REF_NAME != *"gh-readonly-queue"* ]]; then echo "I will run only in a merge queue"; exit 0; fi + # Docker images have different tag in merge queues + - if [[ $CI_COMMIT_REF_NAME == *"gh-readonly-queue"* ]]; then export DOCKER_IMAGES_VERSION="${CI_COMMIT_SHORT_SHA}"; fi + - export PIPELINE_IMAGE_TAG=${DOCKER_IMAGES_VERSION} - export BUILD_RELEASE_VERSION="$(cat ./artifacts/BUILD_RELEASE_VERSION)" # from build-linux-stable job - export DEBUG=zombie,zombie::network-node - export ZOMBIENET_INTEGRATION_TEST_IMAGE="${POLKADOT_IMAGE}":${PIPELINE_IMAGE_TAG} @@ -46,7 +49,7 @@ - .kubernetes-env - .zombienet-refs variables: - PIPELINE_IMAGE_TAG: ${DOCKER_IMAGES_VERSION} + # PIPELINE_IMAGE_TAG: ${DOCKER_IMAGES_VERSION} POLKADOT_IMAGE: "docker.io/paritypr/polkadot-debug" COLANDER_IMAGE: "docker.io/paritypr/colander" MALUS_IMAGE: "docker.io/paritypr/malus" @@ -153,6 +156,9 @@ zombienet-polkadot-smoke-0001-parachains-smoke-test: before_script: # Exit if the job is not merge queue # - if [[ $CI_COMMIT_REF_NAME != *"gh-readonly-queue"* ]]; then echo "I will run only in a merge queue"; exit 0; fi + # Docker images have different tag in merge queues + - if [[ $CI_COMMIT_REF_NAME == *"gh-readonly-queue"* ]]; then export DOCKER_IMAGES_VERSION="${CI_COMMIT_SHORT_SHA}"; fi + - export PIPELINE_IMAGE_TAG=${DOCKER_IMAGES_VERSION} - export ZOMBIENET_INTEGRATION_TEST_IMAGE="${POLKADOT_IMAGE}":${PIPELINE_IMAGE_TAG} - export COL_IMAGE="${COLANDER_IMAGE}":${PIPELINE_IMAGE_TAG} - echo "Zombienet Tests Config" @@ -172,6 +178,9 @@ zombienet-polkadot-smoke-0002-parachains-parachains-upgrade-smoke: before_script: # Exit if the job is not merge queue # - if [[ $CI_COMMIT_REF_NAME != *"gh-readonly-queue"* ]]; then echo "I will run only in a merge queue"; exit 0; fi + # Docker images have different tag in merge queues + - if [[ $CI_COMMIT_REF_NAME == *"gh-readonly-queue"* ]]; then export DOCKER_IMAGES_VERSION="${CI_COMMIT_SHORT_SHA}"; fi + - export PIPELINE_IMAGE_TAG=${DOCKER_IMAGES_VERSION} - export ZOMBIENET_INTEGRATION_TEST_IMAGE="${POLKADOT_IMAGE}":${PIPELINE_IMAGE_TAG} - export CUMULUS_IMAGE="docker.io/paritypr/polkadot-parachain-debug:${DOCKER_IMAGES_VERSION}" - echo "Zombienet Tests Config" @@ -224,6 +233,9 @@ zombienet-polkadot-misc-0002-upgrade-node: before_script: # Exit if the job is not merge queue # - if [[ $CI_COMMIT_REF_NAME != *"gh-readonly-queue"* ]]; then echo "I will run only in a merge queue"; exit 0; fi + # Docker images have different tag in merge queues + - if [[ $CI_COMMIT_REF_NAME == *"gh-readonly-queue"* ]]; then export DOCKER_IMAGES_VERSION="${CI_COMMIT_SHORT_SHA}"; fi + - export PIPELINE_IMAGE_TAG=${DOCKER_IMAGES_VERSION} - export ZOMBIENET_INTEGRATION_TEST_IMAGE="docker.io/parity/polkadot:latest" - echo "Overrided polkadot image ${ZOMBIENET_INTEGRATION_TEST_IMAGE}" - export COL_IMAGE="${COLANDER_IMAGE}":${PIPELINE_IMAGE_TAG} diff --git a/.gitlab/pipeline/zombienet/substrate.yml b/.gitlab/pipeline/zombienet/substrate.yml index ca4daa01871..23630fcc6c0 100644 --- a/.gitlab/pipeline/zombienet/substrate.yml +++ b/.gitlab/pipeline/zombienet/substrate.yml @@ -6,6 +6,9 @@ before_script: # Exit if the job is not merge queue # - if [[ $CI_COMMIT_REF_NAME != *"gh-readonly-queue"* ]]; then echo "I will run only in a merge queue"; exit 0; fi + # Docker images have different tag in merge queues + - if [[ $CI_COMMIT_REF_NAME == *"gh-readonly-queue"* ]]; then export DOCKER_IMAGES_VERSION="${CI_COMMIT_SHORT_SHA}"; fi + - export SUBSTRATE_IMAGE_TAG=${DOCKER_IMAGES_VERSION} - echo "Zombienet Tests Config" - echo "${ZOMBIENET_IMAGE}" - echo "${GH_DIR}" @@ -21,7 +24,7 @@ - .kubernetes-env - .zombienet-refs variables: - SUBSTRATE_IMAGE_TAG: ${DOCKER_IMAGES_VERSION} + # SUBSTRATE_IMAGE_TAG: ${DOCKER_IMAGES_VERSION} SUBSTRATE_IMAGE: "docker.io/paritypr/substrate" GH_DIR: "https://github.com/paritytech/substrate/tree/${CI_COMMIT_SHA}/zombienet" LOCAL_DIR: "/builds/parity/mirrors/polkadot-sdk/substrate/zombienet" -- GitLab From f270b08a486d8e4ec85434ce13a060408d66e761 Mon Sep 17 00:00:00 2001 From: Nazar Mokrynskyi Date: Thu, 11 Jan 2024 13:41:59 +0200 Subject: [PATCH 036/392] Move Cors data structure into reachable place (#2898) Trivial refactoring, fixes https://github.com/paritytech/polkadot-sdk/issues/2885 --- substrate/client/cli/src/arg_enums.rs | 45 ++++++++++++++++++++ substrate/client/cli/src/commands/run_cmd.rs | 45 +------------------- 2 files changed, 47 insertions(+), 43 deletions(-) diff --git a/substrate/client/cli/src/arg_enums.rs b/substrate/client/cli/src/arg_enums.rs index d4a4b7cfdf6..d436673cb9d 100644 --- a/substrate/client/cli/src/arg_enums.rs +++ b/substrate/client/cli/src/arg_enums.rs @@ -19,6 +19,7 @@ //! Definitions of [`ValueEnum`] types. use clap::ValueEnum; +use std::str::FromStr; /// The instantiation strategy to use in compiled mode. #[derive(Debug, Clone, Copy, ValueEnum)] @@ -177,6 +178,50 @@ impl Into for RpcMethods { } } +/// CORS setting +/// +/// The type is introduced to overcome `Option>` handling of `clap`. +#[derive(Clone, Debug)] +pub enum Cors { + /// All hosts allowed. + All, + /// Only hosts on the list are allowed. + List(Vec), +} + +impl From for Option> { + fn from(cors: Cors) -> Self { + match cors { + Cors::All => None, + Cors::List(list) => Some(list), + } + } +} + +impl FromStr for Cors { + type Err = crate::Error; + + fn from_str(s: &str) -> Result { + let mut is_all = false; + let mut origins = Vec::new(); + for part in s.split(',') { + match part { + "all" | "*" => { + is_all = true; + break + }, + other => origins.push(other.to_owned()), + } + } + + if is_all { + Ok(Cors::All) + } else { + Ok(Cors::List(origins)) + } + } +} + /// Database backend #[derive(Debug, Clone, PartialEq, Copy, clap::ValueEnum)] #[value(rename_all = "lower")] diff --git a/substrate/client/cli/src/commands/run_cmd.rs b/substrate/client/cli/src/commands/run_cmd.rs index bc62dc3324e..4ac10a03cd4 100644 --- a/substrate/client/cli/src/commands/run_cmd.rs +++ b/substrate/client/cli/src/commands/run_cmd.rs @@ -17,7 +17,7 @@ // along with this program. If not, see . use crate::{ - arg_enums::RpcMethods, + arg_enums::{Cors, RpcMethods}, error::{Error, Result}, params::{ ImportParams, KeystoreParams, NetworkParams, OffchainWorkerParams, SharedParams, @@ -108,7 +108,7 @@ pub struct RunCmd { /// value). Value of `all` will disable origin validation. Default is to /// allow localhost and origins. When running in /// `--dev` mode the default is to allow all origins. - #[arg(long, value_name = "ORIGINS", value_parser = parse_cors)] + #[arg(long, value_name = "ORIGINS")] pub rpc_cors: Option, /// The human-readable name for this node. @@ -470,47 +470,6 @@ fn rpc_interface( } } -/// CORS setting -/// -/// The type is introduced to overcome `Option>` handling of `clap`. -#[derive(Clone, Debug)] -pub enum Cors { - /// All hosts allowed. - All, - /// Only hosts on the list are allowed. - List(Vec), -} - -impl From for Option> { - fn from(cors: Cors) -> Self { - match cors { - Cors::All => None, - Cors::List(list) => Some(list), - } - } -} - -/// Parse cors origins. -fn parse_cors(s: &str) -> Result { - let mut is_all = false; - let mut origins = Vec::new(); - for part in s.split(',') { - match part { - "all" | "*" => { - is_all = true; - break - }, - other => origins.push(other.to_owned()), - } - } - - if is_all { - Ok(Cors::All) - } else { - Ok(Cors::List(origins)) - } -} - #[cfg(test)] mod tests { use super::*; -- GitLab From c93f5aba8ad19f6b9ebc45714ad4fc61d1a3eae2 Mon Sep 17 00:00:00 2001 From: Sebastian Kunert Date: Thu, 11 Jan 2024 17:44:03 +0100 Subject: [PATCH 037/392] Cumulus test service cleanup (#2887) closes #2567 Followup for https://github.com/paritytech/polkadot-sdk/pull/2331 This PR contains multiple internal cleanups: 1. This gets rid of the functionality in `generate_genesis_block` which was only used in one benchmark 2. Fixed `transaction_pool` and `transaction_throughput` benchmarks failing since they require a tokio runtime now. 3. Removed `parachain_id` CLI option from the test parachain 4. Removed `expect` call from `RuntimeResolver` --- cumulus/client/cli/src/lib.rs | 36 ++++++---- cumulus/polkadot-parachain/src/command.rs | 32 ++++----- .../service/benches/transaction_throughput.rs | 26 +++---- cumulus/test/service/src/cli.rs | 8 +-- cumulus/test/service/src/genesis.rs | 69 ------------------- cumulus/test/service/src/lib.rs | 10 ++- cumulus/test/service/src/main.rs | 18 ++--- .../bin/node/cli/benches/transaction_pool.rs | 6 +- 8 files changed, 70 insertions(+), 135 deletions(-) delete mode 100644 cumulus/test/service/src/genesis.rs diff --git a/cumulus/client/cli/src/lib.rs b/cumulus/client/cli/src/lib.rs index 1cebecb0043..1807b8a1718 100644 --- a/cumulus/client/cli/src/lib.rs +++ b/cumulus/client/cli/src/lib.rs @@ -127,6 +127,27 @@ impl sc_cli::CliConfiguration for PurgeChainCmd { } } +/// Get the SCALE encoded genesis header of the parachain. +pub fn get_raw_genesis_header(client: Arc) -> sc_cli::Result> +where + B: BlockT, + C: HeaderBackend + 'static, +{ + let genesis_hash = + client + .hash(Zero::zero())? + .ok_or(sc_cli::Error::Client(sp_blockchain::Error::Backend( + "Failed to lookup genesis block hash when exporting genesis head data.".into(), + )))?; + let genesis_header = client.header(genesis_hash)?.ok_or(sc_cli::Error::Client( + sp_blockchain::Error::Backend( + "Failed to lookup genesis header by hash when exporting genesis head data.".into(), + ), + ))?; + + Ok(genesis_header.encode()) +} + /// Command for exporting the genesis head data of the parachain #[derive(Debug, clap::Parser)] pub struct ExportGenesisHeadCommand { @@ -150,22 +171,11 @@ impl ExportGenesisHeadCommand { B: BlockT, C: HeaderBackend + 'static, { - let genesis_hash = client.hash(Zero::zero())?.ok_or(sc_cli::Error::Client( - sp_blockchain::Error::Backend( - "Failed to lookup genesis block hash when exporting genesis head data.".into(), - ), - ))?; - let genesis_header = client.header(genesis_hash)?.ok_or(sc_cli::Error::Client( - sp_blockchain::Error::Backend( - "Failed to lookup genesis header by hash when exporting genesis head data.".into(), - ), - ))?; - - let raw_header = genesis_header.encode(); + let raw_header = get_raw_genesis_header(client)?; let output_buf = if self.raw { raw_header } else { - format!("0x{:?}", HexDisplay::from(&genesis_header.encode())).into_bytes() + format!("0x{:?}", HexDisplay::from(&raw_header)).into_bytes() }; if let Some(output) = &self.output { diff --git a/cumulus/polkadot-parachain/src/command.rs b/cumulus/polkadot-parachain/src/command.rs index 516bdb76852..04d618f66c7 100644 --- a/cumulus/polkadot-parachain/src/command.rs +++ b/cumulus/polkadot-parachain/src/command.rs @@ -60,29 +60,29 @@ enum Runtime { } trait RuntimeResolver { - fn runtime(&self) -> Runtime; + fn runtime(&self) -> Result; } impl RuntimeResolver for dyn ChainSpec { - fn runtime(&self) -> Runtime { - runtime(self.id()) + fn runtime(&self) -> Result { + Ok(runtime(self.id())) } } /// Implementation, that can resolve [`Runtime`] from any json configuration file impl RuntimeResolver for PathBuf { - fn runtime(&self) -> Runtime { + fn runtime(&self) -> Result { #[derive(Debug, serde::Deserialize)] struct EmptyChainSpecWithId { id: String, } - let file = std::fs::File::open(self).expect("Failed to open file"); + let file = std::fs::File::open(self)?; let reader = std::io::BufReader::new(file); - let chain_spec: EmptyChainSpecWithId = serde_json::from_reader(reader) - .expect("Failed to read 'json' file with ChainSpec configuration"); + let chain_spec: EmptyChainSpecWithId = + serde_json::from_reader(reader).map_err(|e| sc_cli::Error::Application(Box::new(e)))?; - runtime(&chain_spec.id) + Ok(runtime(&chain_spec.id)) } } @@ -394,7 +394,7 @@ impl SubstrateCli for RelayChainCli { /// Creates partial components for the runtimes that are supported by the benchmarks. macro_rules! construct_partials { ($config:expr, |$partials:ident| $code:expr) => { - match $config.chain_spec.runtime() { + match $config.chain_spec.runtime()? { Runtime::AssetHubPolkadot => { let $partials = new_partial::( &$config, @@ -444,7 +444,7 @@ macro_rules! construct_partials { macro_rules! construct_async_run { (|$components:ident, $cli:ident, $cmd:ident, $config:ident| $( $code:tt )* ) => {{ let runner = $cli.create_runner($cmd)?; - match runner.config().chain_spec.runtime() { + match runner.config().chain_spec.runtime()? { Runtime::AssetHubPolkadot => { runner.async_run(|$config| { let $components = new_partial::( @@ -686,7 +686,7 @@ pub fn run() -> Result<()> { info!("Parachain Account: {}", parachain_account); info!("Is collating: {}", if config.role.is_authority() { "yes" } else { "no" }); - match config.chain_spec.runtime() { + match config.chain_spec.runtime()? { AssetHubPolkadot => crate::service::start_asset_hub_node::< AssetHubPolkadotRuntimeApi, AssetHubPolkadotAuraId, @@ -1032,30 +1032,30 @@ mod tests { &temp_dir, Box::new(create_default_with_extensions("shell-1", Extensions1::default())), ); - assert_eq!(Runtime::Shell, path.runtime()); + assert_eq!(Runtime::Shell, path.runtime().unwrap()); let path = store_configuration( &temp_dir, Box::new(create_default_with_extensions("shell-2", Extensions2::default())), ); - assert_eq!(Runtime::Shell, path.runtime()); + assert_eq!(Runtime::Shell, path.runtime().unwrap()); let path = store_configuration( &temp_dir, Box::new(create_default_with_extensions("seedling", Extensions2::default())), ); - assert_eq!(Runtime::Seedling, path.runtime()); + assert_eq!(Runtime::Seedling, path.runtime().unwrap()); let path = store_configuration( &temp_dir, Box::new(crate::chain_spec::rococo_parachain::rococo_parachain_local_config()), ); - assert_eq!(Runtime::Default, path.runtime()); + assert_eq!(Runtime::Default, path.runtime().unwrap()); let path = store_configuration( &temp_dir, Box::new(crate::chain_spec::contracts::contracts_rococo_local_config()), ); - assert_eq!(Runtime::ContractsRococo, path.runtime()); + assert_eq!(Runtime::ContractsRococo, path.runtime().unwrap()); } } diff --git a/cumulus/test/service/benches/transaction_throughput.rs b/cumulus/test/service/benches/transaction_throughput.rs index 81ecc84db7b..011eb4c7d50 100644 --- a/cumulus/test/service/benches/transaction_throughput.rs +++ b/cumulus/test/service/benches/transaction_throughput.rs @@ -17,6 +17,7 @@ // along with this program. If not, see . use criterion::{criterion_group, criterion_main, BatchSize, Criterion, Throughput}; +use cumulus_client_cli::get_raw_genesis_header; use cumulus_test_runtime::{AccountId, BalancesCall, ExistentialDeposit, SudoCall}; use futures::{future, StreamExt}; use sc_transaction_pool_api::{TransactionPool as _, TransactionSource, TransactionStatus}; @@ -24,9 +25,8 @@ use sp_core::{crypto::Pair, sr25519}; use sp_runtime::OpaqueExtrinsic; use cumulus_primitives_core::ParaId; -use cumulus_test_service::{ - construct_extrinsic, fetch_nonce, initial_head_data, Client, Keyring::*, TransactionPool, -}; +use cumulus_test_service::{construct_extrinsic, fetch_nonce, Client, Keyring::*, TransactionPool}; +use polkadot_primitives::HeadData; fn create_accounts(num: usize) -> Vec { (0..num) @@ -159,6 +159,13 @@ fn transaction_throughput_benchmarks(c: &mut Criterion) { None, ); + // Run charlie as parachain collator + let charlie = runtime.block_on( + cumulus_test_service::TestNodeBuilder::new(para_id, tokio_handle.clone(), Charlie) + .enable_collator() + .connect_to_relay_chain_nodes(vec![&alice, &bob]) + .build(), + ); // Register parachain runtime .block_on( @@ -167,19 +174,14 @@ fn transaction_throughput_benchmarks(c: &mut Criterion) { cumulus_test_service::runtime::WASM_BINARY .expect("You need to build the WASM binary to run this test!") .to_vec(), - initial_head_data(para_id), + HeadData( + get_raw_genesis_header(charlie.client.clone()) + .expect("Unable to get genesis HeadData."), + ), ), ) .unwrap(); - // Run charlie as parachain collator - let charlie = runtime.block_on( - cumulus_test_service::TestNodeBuilder::new(para_id, tokio_handle.clone(), Charlie) - .enable_collator() - .connect_to_relay_chain_nodes(vec![&alice, &bob]) - .build(), - ); - // Run dave as parachain collator let dave = runtime.block_on( cumulus_test_service::TestNodeBuilder::new(para_id, tokio_handle.clone(), Dave) diff --git a/cumulus/test/service/src/cli.rs b/cumulus/test/service/src/cli.rs index 3dc5b8e3101..87d1d4af8a9 100644 --- a/cumulus/test/service/src/cli.rs +++ b/cumulus/test/service/src/cli.rs @@ -38,9 +38,6 @@ pub struct TestCollatorCli { #[command(flatten)] pub run: cumulus_client_cli::RunCmd, - #[arg(default_value_t = 2000u32)] - pub parachain_id: u32, - /// Relay chain arguments #[arg(raw = true)] pub relaychain_args: Vec, @@ -256,9 +253,8 @@ impl SubstrateCli for TestCollatorCli { fn load_spec(&self, id: &str) -> std::result::Result, String> { Ok(match id { - "" => Box::new(cumulus_test_service::get_chain_spec(Some(ParaId::from( - self.parachain_id, - )))) as Box<_>, + "" => + Box::new(cumulus_test_service::get_chain_spec(Some(ParaId::from(2000)))) as Box<_>, path => { let chain_spec = cumulus_test_service::chain_spec::ChainSpec::from_json_file(path.into())?; diff --git a/cumulus/test/service/src/genesis.rs b/cumulus/test/service/src/genesis.rs deleted file mode 100644 index be4b0427b2e..00000000000 --- a/cumulus/test/service/src/genesis.rs +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -use codec::Encode; -use cumulus_primitives_core::ParaId; -use cumulus_test_runtime::Block; -use polkadot_primitives::HeadData; -use sc_chain_spec::ChainSpec; -use sp_runtime::{ - traits::{Block as BlockT, Hash as HashT, Header as HeaderT, Zero}, - StateVersion, -}; - -/// Generate a simple test genesis block from a given ChainSpec. -pub fn generate_genesis_block( - chain_spec: &dyn ChainSpec, - genesis_state_version: StateVersion, -) -> Result { - let storage = chain_spec.build_storage()?; - - let child_roots = storage.children_default.iter().map(|(sk, child_content)| { - let state_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( - child_content.data.clone().into_iter().collect(), - genesis_state_version, - ); - (sk.clone(), state_root.encode()) - }); - let state_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( - storage.top.clone().into_iter().chain(child_roots).collect(), - genesis_state_version, - ); - - let extrinsics_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( - Vec::new(), - genesis_state_version, - ); - - Ok(Block::new( - <::Header as HeaderT>::new( - Zero::zero(), - extrinsics_root, - state_root, - Default::default(), - Default::default(), - ), - Default::default(), - )) -} - -/// Returns the initial head data for a parachain ID. -pub fn initial_head_data(para_id: ParaId) -> HeadData { - let spec = crate::chain_spec::get_chain_spec(Some(para_id)); - let block: Block = generate_genesis_block(&spec, sp_runtime::StateVersion::V1).unwrap(); - let genesis_state = block.header().encode(); - genesis_state.into() -} diff --git a/cumulus/test/service/src/lib.rs b/cumulus/test/service/src/lib.rs index 1de3af1bc9d..37ea984ac87 100644 --- a/cumulus/test/service/src/lib.rs +++ b/cumulus/test/service/src/lib.rs @@ -23,9 +23,6 @@ pub mod bench_utils; pub mod chain_spec; -/// Utilities for creating test genesis block and head data -pub mod genesis; - use runtime::AccountId; use sc_executor::{HeapAllocStrategy, WasmExecutor, DEFAULT_HEAP_ALLOC_STRATEGY}; use std::{ @@ -88,7 +85,6 @@ use substrate_test_client::{ pub use chain_spec::*; pub use cumulus_test_runtime as runtime; -pub use genesis::*; pub use sp_keyring::Sr25519Keyring as Keyring; const LOG_TARGET: &str = "cumulus-test-service"; @@ -922,7 +918,7 @@ pub fn run_relay_chain_validator_node( ) -> polkadot_test_service::PolkadotTestNode { let mut config = polkadot_test_service::node_config( storage_update_func, - tokio_handle, + tokio_handle.clone(), key, boot_nodes, true, @@ -936,5 +932,7 @@ pub fn run_relay_chain_validator_node( workers_path.pop(); workers_path.pop(); - polkadot_test_service::run_validator_node(config, Some(workers_path)) + tokio_handle.block_on(async move { + polkadot_test_service::run_validator_node(config, Some(workers_path)) + }) } diff --git a/cumulus/test/service/src/main.rs b/cumulus/test/service/src/main.rs index aace92ca965..69a71a15389 100644 --- a/cumulus/test/service/src/main.rs +++ b/cumulus/test/service/src/main.rs @@ -19,9 +19,8 @@ mod cli; use std::sync::Arc; use cli::{RelayChainCli, Subcommand, TestCollatorCli}; -use cumulus_primitives_core::{relay_chain::CollatorPair, ParaId}; -use cumulus_test_service::{new_partial, AnnounceBlockFn}; -use polkadot_service::runtime_traits::AccountIdConversion; +use cumulus_primitives_core::relay_chain::CollatorPair; +use cumulus_test_service::{chain_spec, new_partial, AnnounceBlockFn}; use sc_cli::{CliConfiguration, SubstrateCli}; use sp_core::Pair; @@ -68,24 +67,21 @@ fn main() -> Result<(), sc_cli::Error> { .create_configuration(&cli, tokio_handle.clone()) .expect("Should be able to generate config"); - let parachain_id = ParaId::from(cli.parachain_id); let polkadot_cli = RelayChainCli::new( &config, [RelayChainCli::executable_name()].iter().chain(cli.relaychain_args.iter()), ); - let parachain_account = - AccountIdConversion::::into_account_truncating( - ¶chain_id, - ); - let tokio_handle = config.tokio_handle.clone(); let polkadot_config = SubstrateCli::create_configuration(&polkadot_cli, &polkadot_cli, tokio_handle) .map_err(|err| format!("Relay chain argument error: {}", err))?; + let parachain_id = chain_spec::Extensions::try_get(&*config.chain_spec) + .map(|e| e.para_id) + .ok_or("Could not find parachain extension in chain-spec.")?; + tracing::info!("Parachain id: {:?}", parachain_id); - tracing::info!("Parachain Account: {}", parachain_account); tracing::info!( "Is collating: {}", if config.role.is_authority() { "yes" } else { "no" } @@ -109,7 +105,7 @@ fn main() -> Result<(), sc_cli::Error> { config, collator_key, polkadot_config, - parachain_id, + parachain_id.into(), cli.disable_block_announcements.then(wrap_announce_block), cli.fail_pov_recovery, |_| Ok(jsonrpsee::RpcModule::new(())), diff --git a/substrate/bin/node/cli/benches/transaction_pool.rs b/substrate/bin/node/cli/benches/transaction_pool.rs index dd6c237d4dd..1cf71f8872f 100644 --- a/substrate/bin/node/cli/benches/transaction_pool.rs +++ b/substrate/bin/node/cli/benches/transaction_pool.rs @@ -55,7 +55,7 @@ fn new_node(tokio_handle: Handle) -> node_cli::service::NewFullBase { impl_name: "BenchmarkImpl".into(), impl_version: "1.0".into(), role: Role::Authority, - tokio_handle, + tokio_handle: tokio_handle.clone(), transaction_pool: TransactionPoolOptions { ready: PoolLimit { count: 100_000, total_bytes: 100 * 1024 * 1024 }, future: PoolLimit { count: 100_000, total_bytes: 100 * 1024 * 1024 }, @@ -97,7 +97,9 @@ fn new_node(tokio_handle: Handle) -> node_cli::service::NewFullBase { wasm_runtime_overrides: None, }; - node_cli::service::new_full_base(config, None, false, |_, _| ()).expect("Creates node") + tokio_handle.block_on(async move { + node_cli::service::new_full_base(config, None, false, |_, _| ()).expect("Creates node") + }) } fn create_accounts(num: usize) -> Vec { -- GitLab From c45732d18b31d4cf307be13818f97a5dc07da015 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 17:44:31 +0100 Subject: [PATCH 038/392] Bump Swatinem/rust-cache from 2.7.1 to 2.7.2 (#2909) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [Swatinem/rust-cache](https://github.com/swatinem/rust-cache) from 2.7.1 to 2.7.2.
Release notes

Sourced from Swatinem/rust-cache's releases.

v2.7.2

What's Changed

New Contributors

Full Changelog: https://github.com/Swatinem/rust-cache/compare/v2.7.1...v2.7.2

Changelog

Sourced from Swatinem/rust-cache's changelog.

Changelog

2.7.2

  • Only key by Cargo.toml and Cargo.lock files of workspace members.

2.7.1

  • Update toml parser to fix parsing errors.

2.7.0

  • Properly cache trybuild tests.

2.6.2

  • Fix toml parsing.

2.6.1

  • Fix hash contributions of Cargo.lock/Cargo.toml files.

2.6.0

  • Add "buildjet" as a second cache-provider backend.
  • Clean up sparse registry index.
  • Do not clean up src of -sys crates.
  • Remove .cargo/credentials.toml before saving.

2.5.1

  • Fix hash contribution of Cargo.lock.

2.5.0

  • feat: Rm workspace crates version before caching.
  • feat: Add hash of .cargo/config.toml to key.

2.4.0

  • Fix cache key stability.
  • Use 8 character hash components to reduce the key length, making it more readable.

2.3.0

  • Add cache-all-crates option, which enables caching of crates installed by workflows.
  • Add installed packages to cache key, so changes to workflows that install rust tools are detected and cached properly.
  • Fix cache restore failures due to upstream bug.
  • Fix EISDIR error due to globed directories.
  • Update runtime @actions/cache, @actions/io and dev typescript dependencies.

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=Swatinem/rust-cache&package-manager=github_actions&previous-version=2.7.1&new-version=2.7.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/check-publish.yml | 2 +- .github/workflows/claim-crates.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check-publish.yml b/.github/workflows/check-publish.yml index 1941bd98167..398cb732585 100644 --- a/.github/workflows/check-publish.yml +++ b/.github/workflows/check-publish.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Rust Cache - uses: Swatinem/rust-cache@3cf7f8cc28d1b4e7d01e3783be10a97d55d483c8 # v2.7.1 + uses: Swatinem/rust-cache@a22603398250b864f7190077025cf752307154dc # v2.7.2 with: cache-on-failure: true diff --git a/.github/workflows/claim-crates.yml b/.github/workflows/claim-crates.yml index 9e272266201..038ea213123 100644 --- a/.github/workflows/claim-crates.yml +++ b/.github/workflows/claim-crates.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Rust Cache - uses: Swatinem/rust-cache@3cf7f8cc28d1b4e7d01e3783be10a97d55d483c8 # v2.7.1 + uses: Swatinem/rust-cache@a22603398250b864f7190077025cf752307154dc # v2.7.2 with: cache-on-failure: true -- GitLab From c4380d6e074bc54612841d654c9e85ef773d983c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 10:32:07 +0100 Subject: [PATCH 039/392] Bump indexmap from 1.9.3 to 2.0.0 (#2911) Bumps [indexmap](https://github.com/bluss/indexmap) from 1.9.3 to 2.0.0.
Changelog

Sourced from indexmap's changelog.

  • 2.0.0

    • MSRV: Rust 1.64.0 or later is now required.

    • The "std" feature is no longer auto-detected. It is included in the default feature set, or else can be enabled like any other Cargo feature.

    • The "serde-1" feature has been removed, leaving just the optional "serde" dependency to be enabled like a feature itself.

    • IndexMap::get_index_mut now returns Option<(&K, &mut V)>, changing the key part from &mut K to &K. There is also a new alternative MutableKeys::get_index_mut2 to access the former behavior.

    • The new map::Slice<K, V> and set::Slice<T> offer a linear view of maps and sets, behaving a lot like normal [(K, V)] and [T] slices. Notably, comparison traits like Eq only consider items in order, rather than hash lookups, and slices even implement Hash.

    • IndexMap and IndexSet now have sort_by_cached_key and par_sort_by_cached_key methods which perform stable sorts in place using a key extraction function.

    • IndexMap and IndexSet now have reserve_exact, try_reserve, and try_reserve_exact methods that correspond to the same methods on Vec. However, exactness only applies to the direct capacity for items, while the raw hash table still follows its own rules for capacity and load factor.

    • The Equivalent trait is now re-exported from the equivalent crate, intended as a common base to allow types to work with multiple map types.

    • The hashbrown dependency has been updated to version 0.14.

    • The serde_seq module has been moved from the crate root to below the map module.

Commits
  • 8e47be8 Merge pull request #267 from cuviper/release-2.0.0
  • ad694fb Release 2.0.0
  • b5b2814 Merge pull request #266 from cuviper/doc-capacity
  • d3ea289 Document the lower-bound semantics of capacity
  • 74e14da Merge pull request #264 from cuviper/equivalent
  • 677c605 Add a relnote for Equivalent
  • 6d83bc1 pub use equivalent::Equivalent;
  • bb48357 Merge pull request #263 from cuviper/insert_in_slot
  • c37dae6 Use hashbrown's new single-lookup insertion
  • ee71507 Merge pull request #262 from daxpedda/hashbrown-v0.14
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=indexmap&package-manager=cargo&previous-version=1.9.3&new-version=2.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- polkadot/node/network/dispute-distribution/Cargo.toml | 2 +- polkadot/node/network/statement-distribution/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 13b90eafa75..217288702ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12277,7 +12277,7 @@ dependencies = [ "fatality", "futures", "futures-timer", - "indexmap 1.9.3", + "indexmap 2.0.0", "lazy_static", "parity-scale-codec", "polkadot-erasure-coding", @@ -13515,7 +13515,7 @@ dependencies = [ "fatality", "futures", "futures-timer", - "indexmap 1.9.3", + "indexmap 2.0.0", "parity-scale-codec", "polkadot-node-network-protocol", "polkadot-node-primitives", diff --git a/polkadot/node/network/dispute-distribution/Cargo.toml b/polkadot/node/network/dispute-distribution/Cargo.toml index 6b494c65336..f892616107a 100644 --- a/polkadot/node/network/dispute-distribution/Cargo.toml +++ b/polkadot/node/network/dispute-distribution/Cargo.toml @@ -27,7 +27,7 @@ sp-keystore = { path = "../../../../substrate/primitives/keystore" } thiserror = "1.0.48" fatality = "0.0.6" schnellru = "0.2.1" -indexmap = "1.9.1" +indexmap = "2.0.0" [dev-dependencies] async-channel = "1.8.0" diff --git a/polkadot/node/network/statement-distribution/Cargo.toml b/polkadot/node/network/statement-distribution/Cargo.toml index 85d2c75aa79..7a502436bb5 100644 --- a/polkadot/node/network/statement-distribution/Cargo.toml +++ b/polkadot/node/network/statement-distribution/Cargo.toml @@ -21,7 +21,7 @@ polkadot-node-primitives = { path = "../../primitives" } polkadot-node-subsystem-util = { path = "../../subsystem-util" } polkadot-node-network-protocol = { path = "../protocol" } arrayvec = "0.7.4" -indexmap = "1.9.1" +indexmap = "2.0.0" parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } thiserror = "1.0.48" fatality = "0.0.6" -- GitLab From f7306d327e0eee0a641ac43628ab525b0096ba7c Mon Sep 17 00:00:00 2001 From: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Date: Fri, 12 Jan 2024 10:42:17 +0100 Subject: [PATCH 040/392] Add More HRMP Channel Opening Tests (#2915) A recent referendum failed because the parachain's sovereign account had enough funds for the deposit (the runtime at the time required a deposit) but not enough left over for the existential deposit, which must remain free. The current logic does not require a deposit for channels with system chains, and the current tests check that none is taken. This new test simply ensures that even without any balance in a parachain's sovereign account, opening a channel with a system chain will be successful. --- polkadot/runtime/parachains/src/hrmp/tests.rs | 63 ++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/polkadot/runtime/parachains/src/hrmp/tests.rs b/polkadot/runtime/parachains/src/hrmp/tests.rs index 4fc0b0b448a..7e7b67c8059 100644 --- a/polkadot/runtime/parachains/src/hrmp/tests.rs +++ b/polkadot/runtime/parachains/src/hrmp/tests.rs @@ -185,11 +185,14 @@ fn force_open_channel_works() { register_parachain(para_a); register_parachain(para_b); + let para_a_free_balance = + ::Currency::free_balance(¶_a.into_account_truncating()); let para_b_free_balance = ::Currency::free_balance(¶_b.into_account_truncating()); run_to_block(5, Some(vec![4, 5])); Hrmp::force_open_hrmp_channel(RuntimeOrigin::root(), para_a, para_b, 2, 8).unwrap(); + Hrmp::force_open_hrmp_channel(RuntimeOrigin::root(), para_b, para_a, 2, 8).unwrap(); Hrmp::assert_storage_consistency_exhaustive(); assert!(System::events().iter().any(|record| record.event == MockEvent::Hrmp(Event::HrmpChannelForceOpened { @@ -198,17 +201,30 @@ fn force_open_channel_works() { proposed_max_capacity: 2, proposed_max_message_size: 8 }))); + assert!(System::events().iter().any(|record| record.event == + MockEvent::Hrmp(Event::HrmpChannelForceOpened { + sender: para_b, + recipient: para_a, + proposed_max_capacity: 2, + proposed_max_message_size: 8 + }))); // Advance to a block 6, but without session change. That means that the channel has // not been created yet. run_to_block(6, None); assert!(!channel_exists(para_a, para_b)); + assert!(!channel_exists(para_b, para_a)); Hrmp::assert_storage_consistency_exhaustive(); // Now let the session change happen and thus open the channel. run_to_block(8, Some(vec![8])); assert!(channel_exists(para_a, para_b)); - // Because para_a is a system chain, para_b's free balance should not have changed. + assert!(channel_exists(para_b, para_a)); + // Because para_a is a system chain, their free balances should not have changed. + assert_eq!( + ::Currency::free_balance(¶_a.into_account_truncating()), + para_a_free_balance + ); assert_eq!( ::Currency::free_balance(¶_b.into_account_truncating()), para_b_free_balance @@ -216,6 +232,51 @@ fn force_open_channel_works() { }); } +#[test] +fn force_open_channel_without_free_balance_works() { + let para_a = 1.into(); + let para_b = 2003.into(); + + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + // We need both A & B to be registered and live parachains, but they should not have any + // balance in their sovereign accounts. Even without any balance, the channel opening should + // still be successful. + register_parachain_with_balance(para_a, 0); + register_parachain_with_balance(para_b, 0); + + run_to_block(5, Some(vec![4, 5])); + Hrmp::force_open_hrmp_channel(RuntimeOrigin::root(), para_a, para_b, 2, 8).unwrap(); + Hrmp::force_open_hrmp_channel(RuntimeOrigin::root(), para_b, para_a, 2, 8).unwrap(); + Hrmp::assert_storage_consistency_exhaustive(); + assert!(System::events().iter().any(|record| record.event == + MockEvent::Hrmp(Event::HrmpChannelForceOpened { + sender: para_a, + recipient: para_b, + proposed_max_capacity: 2, + proposed_max_message_size: 8 + }))); + assert!(System::events().iter().any(|record| record.event == + MockEvent::Hrmp(Event::HrmpChannelForceOpened { + sender: para_b, + recipient: para_a, + proposed_max_capacity: 2, + proposed_max_message_size: 8 + }))); + + // Advance to a block 6, but without session change. That means that the channel has + // not been created yet. + run_to_block(6, None); + assert!(!channel_exists(para_a, para_b)); + assert!(!channel_exists(para_b, para_a)); + Hrmp::assert_storage_consistency_exhaustive(); + + // Now let the session change happen and thus open the channel. + run_to_block(8, Some(vec![8])); + assert!(channel_exists(para_a, para_b)); + assert!(channel_exists(para_b, para_a)); + }); +} + #[test] fn force_open_channel_works_with_existing_request() { let para_a = 2001.into(); -- GitLab From 868788a5bff3ef94869bd36432726703fe3b4e96 Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Fri, 12 Jan 2024 12:22:07 +0100 Subject: [PATCH 041/392] Kitchensink: Fix pallet_mmr config (#2919) Related to https://github.com/paritytech/polkadot-sdk/issues/2787 Fixes `pallet_mmr::Config` for the kitchensink runtime --- substrate/bin/node/cli/tests/basic.rs | 2 +- substrate/bin/node/runtime/src/lib.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/substrate/bin/node/cli/tests/basic.rs b/substrate/bin/node/cli/tests/basic.rs index e5a8a397254..525ab2e39c1 100644 --- a/substrate/bin/node/cli/tests/basic.rs +++ b/substrate/bin/node/cli/tests/basic.rs @@ -154,7 +154,7 @@ fn blocks() -> ((Vec, Hash), (Vec, Hash)) { // session change => consensus authorities change => authorities change digest item appears let digest = Header::decode(&mut &block2.0[..]).unwrap().digest; - assert_eq!(digest.logs().len(), 1 /* Just babe slot */); + assert_eq!(digest.logs().len(), 2 /* Just babe and BEEFY slots */); (block1, block2) } diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index ec1601929fc..1043e5017dc 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -879,7 +879,7 @@ parameter_types! { pub const MaxPointsToBalance: u8 = 10; } -use sp_runtime::traits::Convert; +use sp_runtime::traits::{Convert, Keccak256}; pub struct BalanceToU256; impl Convert for BalanceToU256 { fn convert(balance: Balance) -> sp_core::U256 { @@ -1578,9 +1578,9 @@ impl pallet_vesting::Config for Runtime { impl pallet_mmr::Config for Runtime { const INDEXING_PREFIX: &'static [u8] = b"mmr"; - type Hashing = ::Hashing; + type Hashing = Keccak256; type LeafData = pallet_mmr::ParentNumberAndHash; - type OnNewRoot = (); + type OnNewRoot = pallet_beefy_mmr::DepositBeefyDigest; type WeightInfo = (); } -- GitLab From 6579d6cce6dea8f2d9c5b39110fc393334363957 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 13:24:50 +0100 Subject: [PATCH 042/392] Bump actions/cache from 3.3.2 to 3.3.3 (#2918) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/cache](https://github.com/actions/cache) from 3.3.2 to 3.3.3.
Release notes

Sourced from actions/cache's releases.

v3.3.3

What's Changed

New Contributors

Full Changelog: https://github.com/actions/cache/compare/v3...v3.3.3

Changelog

Sourced from actions/cache's changelog.

Releases

3.0.0

  • Updated minimum runner version support from node 12 -> node 16

3.0.1

  • Added support for caching from GHES 3.5.
  • Fixed download issue for files > 2GB during restore.

3.0.2

  • Added support for dynamic cache size cap on GHES.

3.0.3

  • Fixed avoiding empty cache save when no files are available for caching. (issue)

3.0.4

  • Fixed tar creation error while trying to create tar with path as ~/ home folder on ubuntu-latest. (issue)

3.0.5

  • Removed error handling by consuming actions/cache 3.0 toolkit, Now cache server error handling will be done by toolkit. (PR)

3.0.6

  • Fixed #809 - zstd -d: no such file or directory error
  • Fixed #833 - cache doesn't work with github workspace directory

3.0.7

  • Fixed #810 - download stuck issue. A new timeout is introduced in the download process to abort the download if it gets stuck and doesn't finish within an hour.

3.0.8

  • Fix zstd not working for windows on gnu tar in issues #888 and #891.
  • Allowing users to provide a custom timeout as input for aborting download of a cache segment using an environment variable SEGMENT_DOWNLOAD_TIMEOUT_MINS. Default is 60 minutes.

3.0.9

  • Enhanced the warning message for cache unavailablity in case of GHES.

3.0.10

  • Fix a bug with sorting inputs.
  • Update definition for restore-keys in README.md

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/cache&package-manager=github_actions&previous-version=3.3.2&new-version=3.3.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/check-links.yml | 2 +- .github/workflows/release-50_publish-docker.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/check-links.yml b/.github/workflows/check-links.yml index 14941efce24..d3865335c09 100644 --- a/.github/workflows/check-links.yml +++ b/.github/workflows/check-links.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Restore lychee cache - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 (7. Sep 2023) + uses: actions/cache@e12d46a63a90f2fae62d114769bbf2a179198b5c # v3.3.2 (7. Sep 2023) with: path: .lycheecache key: cache-lychee-${{ github.sha }} diff --git a/.github/workflows/release-50_publish-docker.yml b/.github/workflows/release-50_publish-docker.yml index f74fb6a0ad1..ecbac01cd3a 100644 --- a/.github/workflows/release-50_publish-docker.yml +++ b/.github/workflows/release-50_publish-docker.yml @@ -104,7 +104,7 @@ jobs: fetch_release_artifacts - name: Cache the artifacts - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 + uses: actions/cache@e12d46a63a90f2fae62d114769bbf2a179198b5c # v3.3.3 with: key: artifacts-${{ env.BINARY }}-${{ github.sha }} path: | @@ -121,7 +121,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Get artifacts from cache - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 + uses: actions/cache@e12d46a63a90f2fae62d114769bbf2a179198b5c # v3.3.3 with: key: artifacts-${{ env.BINARY }}-${{ github.sha }} fail-on-cache-miss: true @@ -250,7 +250,7 @@ jobs: uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 - name: Cache Docker layers - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 + uses: actions/cache@e12d46a63a90f2fae62d114769bbf2a179198b5c # v3.3.3 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ github.sha }} -- GitLab From 5ed0a75fcdefdb0016c7998f33dff91dbc084095 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 12 Jan 2024 16:49:16 +0300 Subject: [PATCH 043/392] Run bridges zombienet tests on CI (#2439) Brridges zombienet tests are non-standard - zombienet currently missing multiple relay chains support (see e.g. https://github.com/paritytech/zombienet/pull/796), so we need to go live with two relay networks, their parachains + custom test runner (which e.g. doesn't shutdown net when its tests are finished and instead waits for both networks tests to complete). So we are stuck with native zombienet provider => this PR is an attempt to gather everything in a single docker container and run tests there ~Draft, because it is far from finishing - what I want now is to see how it works on CI~ --- .gitlab/pipeline/build.yml | 18 ++++++ .gitlab/pipeline/publish.yml | 22 +++++++ .gitlab/pipeline/zombienet.yml | 2 + .gitlab/pipeline/zombienet/bridges.yml | 54 +++++++++++++++++ bridges/zombienet/run-tests.sh | 50 +++++++++++++--- cumulus/scripts/bridges_common.sh | 24 +++----- cumulus/scripts/bridges_rococo_westend.sh | 12 ++-- ...ridges_zombienet_tests_injected.Dockerfile | 60 +++++++++++++++++++ 8 files changed, 214 insertions(+), 28 deletions(-) create mode 100644 .gitlab/pipeline/zombienet/bridges.yml create mode 100644 docker/dockerfiles/bridges_zombienet_tests_injected.Dockerfile diff --git a/.gitlab/pipeline/build.yml b/.gitlab/pipeline/build.yml index 20aa4a5c2a2..d998b62c899 100644 --- a/.gitlab/pipeline/build.yml +++ b/.gitlab/pipeline/build.yml @@ -382,3 +382,21 @@ build-subkey-linux: # after_script: [""] # tags: # - osx + +# bridges + +# we need some non-binary artifacts in our bridges+zombienet image +prepare-bridges-zombienet-artifacts: + stage: build + extends: + - .docker-env + - .common-refs + - .run-immediately + - .collect-artifacts + before_script: + - mkdir -p ./artifacts/bridges-polkadot-sdk/bridges + - mkdir -p ./artifacts/bridges-polkadot-sdk/cumulus/zombienet + script: + - cp -r bridges/zombienet ./artifacts/bridges-polkadot-sdk/bridges/zombienet + - cp -r cumulus/scripts ./artifacts/bridges-polkadot-sdk/cumulus/scripts + - cp -r cumulus/zombienet/bridge-hubs ./artifacts/bridges-polkadot-sdk/cumulus/zombienet/bridge-hubs diff --git a/.gitlab/pipeline/publish.yml b/.gitlab/pipeline/publish.yml index 3b77f5363f6..b73acb560f6 100644 --- a/.gitlab/pipeline/publish.yml +++ b/.gitlab/pipeline/publish.yml @@ -66,6 +66,8 @@ publish-rustdoc: # note: images are used not only in zombienet but also in rococo, wococo and versi .build-push-image: image: $BUILDAH_IMAGE + extends: + - .zombienet-refs variables: DOCKERFILE: "" # docker/path-to.Dockerfile IMAGE_NAME: "" # docker.io/paritypr/image_name @@ -77,6 +79,7 @@ publish-rustdoc: --build-arg VCS_REF="${CI_COMMIT_SHA}" --build-arg BUILD_DATE="$(date -u '+%Y-%m-%dT%H:%M:%SZ')" --build-arg IMAGE_NAME="${IMAGE_NAME}" + --build-arg ZOMBIENET_IMAGE="${ZOMBIENET_IMAGE}" --tag "$IMAGE_NAME:${DOCKER_IMAGES_VERSION}" --file ${DOCKERFILE} . - echo "$PARITYPR_PASS" | @@ -163,3 +166,22 @@ build-push-image-substrate-pr: variables: DOCKERFILE: "docker/dockerfiles/substrate_injected.Dockerfile" IMAGE_NAME: "docker.io/paritypr/substrate" + +# unlike other images, bridges+zombienet image is based on Zombienet image that pulls required binaries +# from other fresh images (polkadot and cumulus) +build-push-image-bridges-zombienet-tests: + stage: publish + extends: + - .kubernetes-env + - .common-refs + - .build-push-image + needs: + - job: build-linux-stable + artifacts: true + - job: build-linux-stable-cumulus + artifacts: true + - job: prepare-bridges-zombienet-artifacts + artifacts: true + variables: + DOCKERFILE: "docker/dockerfiles/bridges_zombienet_tests_injected.Dockerfile" + IMAGE_NAME: "docker.io/paritypr/bridges-zombienet-tests" diff --git a/.gitlab/pipeline/zombienet.yml b/.gitlab/pipeline/zombienet.yml index d5845611c60..4b95c86c3c4 100644 --- a/.gitlab/pipeline/zombienet.yml +++ b/.gitlab/pipeline/zombienet.yml @@ -10,3 +10,5 @@ include: - .gitlab/pipeline/zombienet/cumulus.yml # polkadot tests - .gitlab/pipeline/zombienet/polkadot.yml + # bridges tests + - .gitlab/pipeline/zombienet/bridges.yml diff --git a/.gitlab/pipeline/zombienet/bridges.yml b/.gitlab/pipeline/zombienet/bridges.yml new file mode 100644 index 00000000000..9414207a3bb --- /dev/null +++ b/.gitlab/pipeline/zombienet/bridges.yml @@ -0,0 +1,54 @@ +# This file is part of .gitlab-ci.yml +# Here are all jobs that are executed during "zombienet" stage for bridges + +# common settings for all zombienet jobs +.zombienet-bridges-common: + before_script: + # Exit if the job is not merge queue + # - if [[ $CI_COMMIT_REF_NAME != *"gh-readonly-queue"* ]]; then echo "I will run only in a merge queue"; exit 0; fi + - echo "Zombienet Tests Config" + - echo "${ZOMBIENET_IMAGE}" + - echo "${GH_DIR}" + - echo "${LOCAL_DIR}" + - ls "${LOCAL_DIR}" + - export DEBUG=zombie,zombie::network-node + - export ZOMBIENET_INTEGRATION_TEST_IMAGE="${BRIDGES_ZOMBIENET_TESTS_IMAGE}":${BRIDGES_ZOMBIENET_TESTS_IMAGE_TAG} + - echo "${ZOMBIENET_INTEGRATION_TEST_IMAGE}" + stage: zombienet + image: "${BRIDGES_ZOMBIENET_TESTS_IMAGE}:${BRIDGES_ZOMBIENET_TESTS_IMAGE_TAG}" + needs: + - job: build-push-image-bridges-zombienet-tests + artifacts: true + extends: + - .kubernetes-env + - .zombienet-refs + variables: + BRIDGES_ZOMBIENET_TESTS_IMAGE_TAG: ${DOCKER_IMAGES_VERSION} + BRIDGES_ZOMBIENET_TESTS_IMAGE: "docker.io/paritypr/bridges-zombienet-tests" + GH_DIR: "https://github.com/paritytech/polkadot-sdk/tree/${CI_COMMIT_SHA}/bridges/zombienet" + LOCAL_DIR: "/builds/parity/mirrors/polkadot-sdk/bridges/zombienet" + FF_DISABLE_UMASK_FOR_DOCKER_EXECUTOR: 1 + RUN_IN_CONTAINER: "1" + artifacts: + name: "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}_zombienet_bridge_tests" + when: always + expire_in: 2 days + paths: + - ./zombienet-logs + after_script: + - mkdir -p ./zombienet-logs + # copy logs of tests runner (run-tests.sh) + - cp -r /tmp/bridges-zombienet-tests.*/tmp.*/tmp.* ./zombienet-logs/ + # copy logs of all nodes + - cp /tmp/zombie*/logs/* ./zombienet-logs/ +# following lines are causing spurious test failures ("At least one of the nodes fails to start") +# retry: 2 +# tags: +# - zombienet-polkadot-integration-test + +zombienet-bridges-0001-asset-transfer-works: + extends: + - .zombienet-bridges-common + script: + - /home/nonroot/bridges-polkadot-sdk/bridges/zombienet/run-tests.sh --docker + - echo "Done" diff --git a/bridges/zombienet/run-tests.sh b/bridges/zombienet/run-tests.sh index 4f80e06650e..34487e13261 100755 --- a/bridges/zombienet/run-tests.sh +++ b/bridges/zombienet/run-tests.sh @@ -1,18 +1,49 @@ #!/bin/bash #set -eu +set -x shopt -s nullglob -trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT +trap "trap - SIGINT SIGTERM EXIT && kill -- -$$" SIGINT SIGTERM EXIT + +# whether to use paths for zombienet+bridges tests container or for local testing +ZOMBIENET_DOCKER_PATHS=0 +while [ $# -ne 0 ] +do + arg="$1" + case "$arg" in + --docker) + ZOMBIENET_DOCKER_PATHS=1 + ;; + esac + shift +done # assuming that we'll be using native provide && all processes will be executing locally # (we need absolute paths here, because they're used when scripts are called by zombienet from tmp folders) export POLKADOT_SDK_FOLDER=`realpath $(dirname "$0")/../..` export BRIDGE_TESTS_FOLDER=$POLKADOT_SDK_FOLDER/bridges/zombienet/tests -export POLKADOT_BINARY_PATH=$POLKADOT_SDK_FOLDER/target/release/polkadot -export POLKADOT_PARACHAIN_BINARY_PATH=$POLKADOT_SDK_FOLDER/target/release/polkadot-parachain -export POLKADOT_PARACHAIN_BINARY_PATH_FOR_ASSET_HUB_ROCOCO=$POLKADOT_PARACHAIN_BINARY_PATH -export POLKADOT_PARACHAIN_BINARY_PATH_FOR_ASSET_HUB_WESTEND=$POLKADOT_PARACHAIN_BINARY_PATH -export ZOMBIENET_BINARY_PATH=~/local_bridge_testing/bin/zombienet-linux + +# set pathc to binaries +if [ "$ZOMBIENET_DOCKER_PATHS" -eq 1 ]; then + export POLKADOT_BINARY_PATH=/usr/local/bin/polkadot + export POLKADOT_PARACHAIN_BINARY_PATH=/usr/local/bin/polkadot-parachain + export POLKADOT_PARACHAIN_BINARY_PATH_FOR_ASSET_HUB_ROCOCO=/usr/local/bin/polkadot-parachain + export POLKADOT_PARACHAIN_BINARY_PATH_FOR_ASSET_HUB_WESTEND=/usr/local/bin/polkadot-parachain + + export SUBSTRATE_RELAY_PATH=/usr/local/bin/substrate-relay + export ZOMBIENET_BINARY_PATH=/usr/local/bin/zombie +else + export POLKADOT_BINARY_PATH=$POLKADOT_SDK_FOLDER/target/release/polkadot + export POLKADOT_PARACHAIN_BINARY_PATH=$POLKADOT_SDK_FOLDER/target/release/polkadot-parachain + export POLKADOT_PARACHAIN_BINARY_PATH_FOR_ASSET_HUB_ROCOCO=$POLKADOT_PARACHAIN_BINARY_PATH + export POLKADOT_PARACHAIN_BINARY_PATH_FOR_ASSET_HUB_WESTEND=$POLKADOT_PARACHAIN_BINARY_PATH + + export SUBSTRATE_RELAY_PATH=~/local_bridge_testing/bin/substrate-relay + export ZOMBIENET_BINARY_PATH=~/local_bridge_testing/bin/zombienet-linux +fi + +# check if `wait` supports -p flag +if [ `printf "$BASH_VERSION\n5.1" | sort -V | head -n 1` = "5.1" ]; then IS_BASH_5_1=1; else IS_BASH_5_1=0; fi # check if `wait` supports -p flag if [ `printf "$BASH_VERSION\n5.1" | sort -V | head -n 1` = "5.1" ]; then IS_BASH_5_1=1; else IS_BASH_5_1=0; fi @@ -21,13 +52,17 @@ if [ `printf "$BASH_VERSION\n5.1" | sort -V | head -n 1` = "5.1" ]; then IS_BASH export LANE_ID="00000002" # tests configuration -ALL_TESTS_FOLDER=`mktemp -d` +ALL_TESTS_FOLDER=`mktemp -d /tmp/bridges-zombienet-tests.XXXXX` function start_coproc() { local command=$1 local name=$2 local coproc_log=`mktemp -p $TEST_FOLDER` coproc COPROC { + # otherwise zombienet uses some hardcoded paths + unset RUN_IN_CONTAINER + unset ZOMBIENET_IMAGE + $command >$coproc_log 2>&1 } TEST_COPROCS[$COPROC_PID, 0]=$name @@ -90,6 +125,7 @@ do echo "=== Shutting down. Log of failed process below ===" echo "=====================================================================" echo $coproc_stdout + exit 1 fi diff --git a/cumulus/scripts/bridges_common.sh b/cumulus/scripts/bridges_common.sh index 97ef8aa1259..5d5b7b7a482 100755 --- a/cumulus/scripts/bridges_common.sh +++ b/cumulus/scripts/bridges_common.sh @@ -1,27 +1,21 @@ #!/bin/bash -function ensure_binaries() { - if [[ ! -f ~/local_bridge_testing/bin/polkadot ]]; then - echo " Required polkadot binary '~/local_bridge_testing/bin/polkadot' does not exist!" - echo " You need to build it and copy to this location!" - echo " Please, check ./parachains/runtimes/bridge-hubs/README.md (Prepare/Build/Deploy)" - exit 1 - fi - if [[ ! -f ~/local_bridge_testing/bin/polkadot-parachain ]]; then - echo " Required polkadot-parachain binary '~/local_bridge_testing/bin/polkadot-parachain' does not exist!" - echo " You need to build it and copy to this location!" - echo " Please, check ./parachains/runtimes/bridge-hubs/README.md (Prepare/Build/Deploy)" - exit 1 - fi +function relayer_path() { + local default_path=~/local_bridge_testing/bin/substrate-relay + local path="${SUBSTRATE_RELAY_PATH:-$default_path}" + echo "$path" } function ensure_relayer() { - if [[ ! -f ~/local_bridge_testing/bin/substrate-relay ]]; then - echo " Required substrate-relay binary '~/local_bridge_testing/bin/substrate-relay' does not exist!" + local path=$(relayer_path) + if [[ ! -f "$path" ]]; then + echo " Required substrate-relay binary '$path' does not exist!" echo " You need to build it and copy to this location!" echo " Please, check ./parachains/runtimes/bridge-hubs/README.md (Prepare/Build/Deploy)" exit 1 fi + + echo $path } function ensure_polkadot_js_api() { diff --git a/cumulus/scripts/bridges_rococo_westend.sh b/cumulus/scripts/bridges_rococo_westend.sh index c52b72e51fc..3b6f8e89285 100755 --- a/cumulus/scripts/bridges_rococo_westend.sh +++ b/cumulus/scripts/bridges_rococo_westend.sh @@ -132,10 +132,10 @@ LANE_ID="00000002" XCM_VERSION=3 function init_ro_wnd() { - ensure_relayer + local relayer_path=$(ensure_relayer) RUST_LOG=runtime=trace,rpc=trace,bridge=trace \ - ~/local_bridge_testing/bin/substrate-relay init-bridge rococo-to-bridge-hub-westend \ + $relayer_path init-bridge rococo-to-bridge-hub-westend \ --source-host localhost \ --source-port 9942 \ --source-version-mode Auto \ @@ -146,10 +146,10 @@ function init_ro_wnd() { } function init_wnd_ro() { - ensure_relayer + local relayer_path=$(ensure_relayer) RUST_LOG=runtime=trace,rpc=trace,bridge=trace \ - ~/local_bridge_testing/bin/substrate-relay init-bridge westend-to-bridge-hub-rococo \ + $relayer_path init-bridge westend-to-bridge-hub-rococo \ --source-host localhost \ --source-port 9945 \ --source-version-mode Auto \ @@ -160,10 +160,10 @@ function init_wnd_ro() { } function run_relay() { - ensure_relayer + local relayer_path=$(ensure_relayer) RUST_LOG=runtime=trace,rpc=trace,bridge=trace \ - ~/local_bridge_testing/bin/substrate-relay relay-headers-and-messages bridge-hub-rococo-bridge-hub-westend \ + $relayer_path relay-headers-and-messages bridge-hub-rococo-bridge-hub-westend \ --rococo-host localhost \ --rococo-port 9942 \ --rococo-version-mode Auto \ diff --git a/docker/dockerfiles/bridges_zombienet_tests_injected.Dockerfile b/docker/dockerfiles/bridges_zombienet_tests_injected.Dockerfile new file mode 100644 index 00000000000..ebad4046d26 --- /dev/null +++ b/docker/dockerfiles/bridges_zombienet_tests_injected.Dockerfile @@ -0,0 +1,60 @@ +# this image is built on top of existing Zombienet image +ARG ZOMBIENET_IMAGE +# this image uses substrate-relay image built elsewhere +ARG SUBSTRATE_RELAY_IMAGE=docker.io/paritytech/substrate-relay:v2023-11-07-rococo-westend-initial-relayer + +# metadata +ARG VCS_REF +ARG BUILD_DATE +ARG IMAGE_NAME + +# we need `substrate-relay` binary, built elsewhere +FROM ${SUBSTRATE_RELAY_IMAGE} as relay-builder + +# the base image is the zombienet image - we are planning to run zombienet tests using native +# provider here +FROM ${ZOMBIENET_IMAGE} + +LABEL io.parity.image.authors="devops-team@parity.io" \ + io.parity.image.vendor="Parity Technologies" \ + io.parity.image.title="${IMAGE_NAME}" \ + io.parity.image.description="Bridges Zombienet tests." \ + io.parity.image.source="https://github.com/paritytech/polkadot-sdk/blob/${VCS_REF}/docker/dockerfiles/bridges_zombienet_tests_injected.Dockerfile" \ + io.parity.image.revision="${VCS_REF}" \ + io.parity.image.created="${BUILD_DATE}" \ + io.parity.image.documentation="https://github.com/paritytech/polkadot-sdk/bridges/zombienet" + +# show backtraces +ENV RUST_BACKTRACE 1 +USER root + +# for native provider to work (TODO: fix in zn docker?) +RUN apt-get update && apt-get install -y procps sudo +RUN yarn global add @polkadot/api-cli + +# add polkadot binary to the docker image +COPY ./artifacts/polkadot /usr/local/bin/ +COPY ./artifacts/polkadot-execute-worker /usr/local/bin/ +COPY ./artifacts/polkadot-prepare-worker /usr/local/bin/ +# add polkadot-parachain binary to the docker image +COPY ./artifacts/polkadot-parachain /usr/local/bin +# copy substrate-relay to the docker image +COPY --from=relay-builder /home/user/substrate-relay /usr/local/bin/ +# we need bridges zombienet runner and tests +RUN mkdir -p /home/nonroot/bridges-polkadot-sdk +COPY ./artifacts/bridges-polkadot-sdk /home/nonroot/bridges-polkadot-sdk +# also prepare `generate_hex_encoded_call` for running +RUN set -eux; \ + cd /home/nonroot/bridges-polkadot-sdk/cumulus/scripts/generate_hex_encoded_call; \ + npm install + +# check if executable works in this container +USER nonroot +RUN /usr/local/bin/polkadot --version +RUN /usr/local/bin/polkadot-parachain --version +RUN /usr/local/bin/substrate-relay --version + +# https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:{PORT}#/explorer +EXPOSE 9942 9910 8943 9945 9010 8945 + +ENTRYPOINT ["/bin/bash", "-c", "/home/nonroot/bridges-polkadot-sdk/bridges/zombienet/run-tests.sh"] -- GitLab From 5208bed7d2d2a9de556289ecde12875ba62739ad Mon Sep 17 00:00:00 2001 From: Dmitry Markin Date: Fri, 12 Jan 2024 17:17:15 +0200 Subject: [PATCH 044/392] Extract warp sync strategy from `ChainSync` (#2467) Extract `WarpSync` (and `StateSync` as part of warp sync) from `ChainSync` as independent syncing strategy called by `SyncingEngine`. Introduce `SyncingStrategy` enum as a proxy between `SyncingEngine` and specific syncing strategies. ## Limitations Gap sync is kept in `ChainSync` for now because it shares the same set of peers as block syncing implementation in `ChainSync`. Extraction of a common context responsible for peer management in syncing strategies able to run in parallel is planned for a follow-up PR. ## Further improvements A possibility of conversion of `SyncingStartegy` into a trait should be evaluated. The main stopper for this is that different strategies need to communicate different actions to `SyncingEngine` and respond to different events / provide different APIs (e.g., requesting justifications is only possible via `ChainSync` and not through `WarpSync`; `SendWarpProofRequest` action is only relevant to `WarpSync`, etc.) --------- Co-authored-by: Aaro Altonen <48052676+altonen@users.noreply.github.com> --- polkadot/node/service/src/lib.rs | 2 +- prdoc/pr_2467.prdoc | 15 + substrate/bin/node/cli/src/service.rs | 2 +- .../consensus/grandpa/src/warp_proof.rs | 2 +- substrate/client/informant/src/display.rs | 10 +- substrate/client/network/sync/Cargo.toml | 2 +- .../sync/src/block_announce_validator.rs | 5 +- .../network/sync/src/block_request_handler.rs | 2 +- substrate/client/network/sync/src/blocks.rs | 13 +- substrate/client/network/sync/src/engine.rs | 353 ++-- .../client/network/sync/src/extra_requests.rs | 17 +- substrate/client/network/sync/src/lib.rs | 8 +- .../network/sync/src/pending_responses.rs | 5 +- .../network/sync/src/state_request_handler.rs | 6 +- substrate/client/network/sync/src/strategy.rs | 489 ++++++ .../sync/src/{ => strategy}/chain_sync.rs | 458 ++---- .../src/{ => strategy}/chain_sync/test.rs | 52 +- .../client/network/sync/src/strategy/state.rs | 754 +++++++++ .../src/{state.rs => strategy/state_sync.rs} | 113 +- .../client/network/sync/src/strategy/warp.rs | 1443 +++++++++++++++++ substrate/client/network/sync/src/types.rs | 22 +- substrate/client/network/sync/src/warp.rs | 405 ----- .../network/sync/src/warp_request_handler.rs | 9 +- substrate/client/network/test/src/lib.rs | 8 +- substrate/client/network/test/src/sync.rs | 35 +- substrate/client/service/src/builder.rs | 4 +- substrate/client/service/src/lib.rs | 2 +- .../0001-basic-warp-sync/test-warp-sync.zndsl | 2 + .../test-validators-warp-sync.zndsl | 3 + .../test-block-building-warp-sync.zndsl | 2 + 30 files changed, 3227 insertions(+), 1016 deletions(-) create mode 100644 prdoc/pr_2467.prdoc create mode 100644 substrate/client/network/sync/src/strategy.rs rename substrate/client/network/sync/src/{ => strategy}/chain_sync.rs (85%) rename substrate/client/network/sync/src/{ => strategy}/chain_sync/test.rs (94%) create mode 100644 substrate/client/network/sync/src/strategy/state.rs rename substrate/client/network/sync/src/{state.rs => strategy/state_sync.rs} (74%) create mode 100644 substrate/client/network/sync/src/strategy/warp.rs delete mode 100644 substrate/client/network/sync/src/warp.rs diff --git a/polkadot/node/service/src/lib.rs b/polkadot/node/service/src/lib.rs index ff70dbde734..1aadef03ce7 100644 --- a/polkadot/node/service/src/lib.rs +++ b/polkadot/node/service/src/lib.rs @@ -734,7 +734,7 @@ pub fn new_full( }: NewFullParams, ) -> Result { use polkadot_node_network_protocol::request_response::IncomingRequest; - use sc_network_sync::warp::WarpSyncParams; + use sc_network_sync::WarpSyncParams; let is_offchain_indexing_enabled = config.offchain_worker.indexing_enabled; let role = config.role.clone(); diff --git a/prdoc/pr_2467.prdoc b/prdoc/pr_2467.prdoc new file mode 100644 index 00000000000..db88ff1fa57 --- /dev/null +++ b/prdoc/pr_2467.prdoc @@ -0,0 +1,15 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Extract warp sync strategy from `ChainSync` + +doc: + - audience: Node Dev + description: | + `WarpSync`, and `StateSync` as the logical part of warp sync, are extracted from `ChainSync` + as independent syncing strategies. `SyncingStrategy` enum is introduced as a proxy between + `SyncingEngine` and specific strategies. `SyncingStrategy` may be replaced by a trait in a + follow-up PRs. + +crates: + - name: sc-network-sync diff --git a/substrate/bin/node/cli/src/service.rs b/substrate/bin/node/cli/src/service.rs index 67d21ee69ed..8f2aba6b44c 100644 --- a/substrate/bin/node/cli/src/service.rs +++ b/substrate/bin/node/cli/src/service.rs @@ -30,7 +30,7 @@ use node_primitives::Block; use sc_client_api::{Backend, BlockBackend}; use sc_consensus_babe::{self, SlotProportion}; use sc_network::{event::Event, NetworkEventStream, NetworkService}; -use sc_network_sync::{warp::WarpSyncParams, SyncingService}; +use sc_network_sync::{strategy::warp::WarpSyncParams, SyncingService}; use sc_service::{config::Configuration, error::Error as ServiceError, RpcHandlers, TaskManager}; use sc_statement_store::Store as StatementStore; use sc_telemetry::{Telemetry, TelemetryWorker}; diff --git a/substrate/client/consensus/grandpa/src/warp_proof.rs b/substrate/client/consensus/grandpa/src/warp_proof.rs index a0fae6998f5..29111712ec3 100644 --- a/substrate/client/consensus/grandpa/src/warp_proof.rs +++ b/substrate/client/consensus/grandpa/src/warp_proof.rs @@ -23,7 +23,7 @@ use crate::{ BlockNumberOps, GrandpaJustification, SharedAuthoritySet, }; use sc_client_api::Backend as ClientBackend; -use sc_network_sync::warp::{EncodedProof, VerificationResult, WarpSyncProvider}; +use sc_network_sync::strategy::warp::{EncodedProof, VerificationResult, WarpSyncProvider}; use sp_blockchain::{Backend as BlockchainBackend, HeaderBackend}; use sp_consensus_grandpa::{AuthorityList, SetId, GRANDPA_ENGINE_ID}; use sp_runtime::{ diff --git a/substrate/client/informant/src/display.rs b/substrate/client/informant/src/display.rs index 64ddb71d572..bcf3794032f 100644 --- a/substrate/client/informant/src/display.rs +++ b/substrate/client/informant/src/display.rs @@ -21,10 +21,7 @@ use ansi_term::Colour; use log::info; use sc_client_api::ClientInfo; use sc_network::NetworkStatus; -use sc_network_sync::{ - warp::{WarpSyncPhase, WarpSyncProgress}, - SyncState, SyncStatus, -}; +use sc_network_sync::{SyncState, SyncStatus, WarpSyncPhase, WarpSyncProgress}; use sp_runtime::traits::{Block as BlockT, CheckedDiv, NumberFor, Saturating, Zero}; use std::{fmt, time::Instant}; @@ -130,9 +127,10 @@ impl InformantDisplay { ), (_, Some(state), _) => ( "⚙️ ", - "Downloading state".into(), + "State sync".into(), format!( - ", {}%, {:.2} Mib", + ", {}, {}%, {:.2} Mib", + state.phase, state.percentage, (state.size as f32) / (1024f32 * 1024f32) ), diff --git a/substrate/client/network/sync/Cargo.toml b/substrate/client/network/sync/Cargo.toml index cb19e1adbe5..dd993e7a3df 100644 --- a/substrate/client/network/sync/Cargo.toml +++ b/substrate/client/network/sync/Cargo.toml @@ -49,7 +49,7 @@ sp-consensus-grandpa = { path = "../../../primitives/consensus/grandpa" } sp-runtime = { path = "../../../primitives/runtime" } [dev-dependencies] -tokio = { version = "1.22.0", features = ["macros"] } +mockall = "0.11.3" quickcheck = { version = "1.0.3", default-features = false } sc-block-builder = { path = "../../block-builder" } sp-test-primitives = { path = "../../../primitives/test-primitives" } diff --git a/substrate/client/network/sync/src/block_announce_validator.rs b/substrate/client/network/sync/src/block_announce_validator.rs index 961b581cddc..62c0d1c16e2 100644 --- a/substrate/client/network/sync/src/block_announce_validator.rs +++ b/substrate/client/network/sync/src/block_announce_validator.rs @@ -19,7 +19,7 @@ //! [`BlockAnnounceValidator`] is responsible for async validation of block announcements. //! [`Stream`] implemented by [`BlockAnnounceValidator`] never terminates. -use crate::futures_stream::FuturesStream; +use crate::{futures_stream::FuturesStream, LOG_TARGET}; use futures::{stream::FusedStream, Future, FutureExt, Stream, StreamExt}; use libp2p::PeerId; use log::{debug, error, trace, warn}; @@ -33,9 +33,6 @@ use std::{ task::{Context, Poll}, }; -/// Log target for this file. -const LOG_TARGET: &str = "sync"; - /// Maximum number of concurrent block announce validations. /// /// If the queue reaches the maximum, we drop any new block diff --git a/substrate/client/network/sync/src/block_request_handler.rs b/substrate/client/network/sync/src/block_request_handler.rs index f669a22cd2e..f2af7d21786 100644 --- a/substrate/client/network/sync/src/block_request_handler.rs +++ b/substrate/client/network/sync/src/block_request_handler.rs @@ -24,6 +24,7 @@ use crate::{ BlockResponse as BlockResponseSchema, BlockResponse, Direction, }, service::network::NetworkServiceHandle, + LOG_TARGET, }; use codec::{Decode, DecodeAll, Encode}; @@ -56,7 +57,6 @@ use std::{ /// Maximum blocks per response. pub(crate) const MAX_BLOCKS_IN_RESPONSE: usize = 128; -const LOG_TARGET: &str = "sync"; const MAX_BODY_BYTES: usize = 8 * 1024 * 1024; const MAX_NUMBER_OF_SAME_REQUESTS_PER_PEER: usize = 2; diff --git a/substrate/client/network/sync/src/blocks.rs b/substrate/client/network/sync/src/blocks.rs index 539a8a5d612..4988045a478 100644 --- a/substrate/client/network/sync/src/blocks.rs +++ b/substrate/client/network/sync/src/blocks.rs @@ -16,6 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +use crate::LOG_TARGET; use libp2p::PeerId; use log::trace; use sc_network_common::sync::message; @@ -87,10 +88,10 @@ impl BlockCollection { match self.blocks.get(&start) { Some(&BlockRangeState::Downloading { .. }) => { - trace!(target: "sync", "Inserting block data still marked as being downloaded: {}", start); + trace!(target: LOG_TARGET, "Inserting block data still marked as being downloaded: {}", start); }, Some(BlockRangeState::Complete(existing)) if existing.len() >= blocks.len() => { - trace!(target: "sync", "Ignored block data already downloaded: {}", start); + trace!(target: LOG_TARGET, "Ignored block data already downloaded: {}", start); return }, _ => (), @@ -162,7 +163,7 @@ impl BlockCollection { }; // crop to peers best if range.start > peer_best { - trace!(target: "sync", "Out of range for peer {} ({} vs {})", who, range.start, peer_best); + trace!(target: LOG_TARGET, "Out of range for peer {} ({} vs {})", who, range.start, peer_best); return None } range.end = cmp::min(peer_best + One::one(), range.end); @@ -173,7 +174,7 @@ impl BlockCollection { .next() .map_or(false, |(n, _)| range.start > *n + max_ahead.into()) { - trace!(target: "sync", "Too far ahead for peer {} ({})", who, range.start); + trace!(target: LOG_TARGET, "Too far ahead for peer {} ({})", who, range.start); return None } @@ -224,7 +225,7 @@ impl BlockCollection { }; *range_data = BlockRangeState::Queued { len }; } - trace!(target: "sync", "{} blocks ready for import", ready.len()); + trace!(target: LOG_TARGET, "{} blocks ready for import", ready.len()); ready } @@ -235,7 +236,7 @@ impl BlockCollection { self.blocks.remove(&block_num); block_num += One::one(); } - trace!(target: "sync", "Cleared blocks from {:?} to {:?}", from, to); + trace!(target: LOG_TARGET, "Cleared blocks from {:?} to {:?}", from, to); } } diff --git a/substrate/client/network/sync/src/engine.rs b/substrate/client/network/sync/src/engine.rs index 952300a14d8..7486c091ebf 100644 --- a/substrate/client/network/sync/src/engine.rs +++ b/substrate/client/network/sync/src/engine.rs @@ -25,17 +25,20 @@ use crate::{ }, block_relay_protocol::{BlockDownloader, BlockResponseError}, block_request_handler::MAX_BLOCKS_IN_RESPONSE, - chain_sync::{ChainSync, ChainSyncAction}, pending_responses::{PendingResponses, ResponseEvent}, schema::v1::{StateRequest, StateResponse}, service::{ self, syncing_service::{SyncingService, ToServiceCommand}, }, + strategy::{ + warp::{EncodedProof, WarpProofRequest, WarpSyncParams}, + SyncingAction, SyncingConfig, SyncingStrategy, + }, types::{ BadPeer, ExtendedPeerInfo, OpaqueStateRequest, OpaqueStateResponse, PeerRequest, SyncEvent, }, - warp::{EncodedProof, WarpProofRequest, WarpSyncParams}, + LOG_TARGET, }; use codec::{Decode, DecodeAll, Encode}; @@ -45,10 +48,9 @@ use futures::{ FutureExt, StreamExt, }; use libp2p::{request_response::OutboundFailure, PeerId}; -use log::{debug, trace}; +use log::{debug, error, trace}; use prometheus_endpoint::{ - register, Counter, Gauge, GaugeVec, MetricSource, Opts, PrometheusError, Registry, - SourcedGauge, U64, + register, Counter, Gauge, MetricSource, Opts, PrometheusError, Registry, SourcedGauge, U64, }; use prost::Message; use schnellru::{ByLength, LruMap}; @@ -97,9 +99,6 @@ const TICK_TIMEOUT: std::time::Duration = std::time::Duration::from_millis(1100) /// Maximum number of known block hashes to keep for a peer. const MAX_KNOWN_BLOCKS: usize = 1024; // ~32kb per peer + LruHashSet overhead -/// Logging target for the file. -const LOG_TARGET: &str = "sync"; - /// If the block announces stream to peer has been inactive for 30 seconds meaning local node /// has not sent or received block announcements to/from the peer, report the node for inactivity, /// disconnect it and attempt to establish connection to some other peer. @@ -140,9 +139,6 @@ mod rep { struct Metrics { peers: Gauge, - queued_blocks: Gauge, - fork_targets: Gauge, - justifications: GaugeVec, import_queue_blocks_submitted: Counter, import_queue_justifications_submitted: Counter, } @@ -155,25 +151,6 @@ impl Metrics { let g = Gauge::new("substrate_sync_peers", "Number of peers we sync with")?; register(g, r)? }, - queued_blocks: { - let g = - Gauge::new("substrate_sync_queued_blocks", "Number of blocks in import queue")?; - register(g, r)? - }, - fork_targets: { - let g = Gauge::new("substrate_sync_fork_targets", "Number of fork sync targets")?; - register(g, r)? - }, - justifications: { - let g = GaugeVec::new( - Opts::new( - "substrate_sync_extra_justifications", - "Number of extra justifications requests", - ), - &["status"], - )?; - register(g, r)? - }, import_queue_blocks_submitted: { let c = Counter::new( "substrate_sync_import_queue_blocks_submitted", @@ -234,9 +211,11 @@ pub struct Peer { } pub struct SyncingEngine { - /// State machine that handles the list of in-progress requests. Only full node peers are - /// registered. - chain_sync: ChainSync, + /// Syncing strategy. + strategy: SyncingStrategy, + + /// Syncing configuration for startegies. + syncing_config: SyncingConfig, /// Blockchain client. client: Arc, @@ -381,6 +360,12 @@ where } else { net_config.network_config.max_blocks_per_request }; + let syncing_config = SyncingConfig { + mode, + max_parallel_downloads, + max_blocks_per_request, + metrics_registry: metrics_registry.cloned(), + }; let cache_capacity = (net_config.network_config.default_peers_set.in_peers + net_config.network_config.default_peers_set.out_peers) .max(1); @@ -429,19 +414,6 @@ where total.saturating_sub(net_config.network_config.default_peers_set_num_full) as usize }; - // Split warp sync params into warp sync config and a channel to retreive target block - // header. - let (warp_sync_config, warp_sync_target_block_header_rx) = - warp_sync_params.map_or((None, None), |params| { - let (config, target_block_rx) = params.split(); - (Some(config), target_block_rx) - }); - - // Make sure polling of the target block channel is a no-op if there is no block to - // retrieve. - let warp_sync_target_block_header_rx_fused = warp_sync_target_block_header_rx - .map_or(futures::future::pending().boxed().fuse(), |rx| rx.boxed().fuse()); - let (block_announce_config, notification_service) = Self::get_block_announce_proto_config( protocol_id, fork_id, @@ -455,13 +427,22 @@ where .expect("Genesis block exists; qed"), ); - let chain_sync = ChainSync::new( - mode, - client.clone(), - max_parallel_downloads, - max_blocks_per_request, - warp_sync_config, - )?; + // Split warp sync params into warp sync config and a channel to retreive target block + // header. + let (warp_sync_config, warp_sync_target_block_header_rx) = + warp_sync_params.map_or((None, None), |params| { + let (config, target_block_rx) = params.split(); + (Some(config), target_block_rx) + }); + + // Make sure polling of the target block channel is a no-op if there is no block to + // retrieve. + let warp_sync_target_block_header_rx_fused = warp_sync_target_block_header_rx + .map_or(futures::future::pending().boxed().fuse(), |rx| rx.boxed().fuse()); + + // Initialize syncing strategy. + let strategy = + SyncingStrategy::new(syncing_config.clone(), client.clone(), warp_sync_config)?; let block_announce_protocol_name = block_announce_config.protocol_name().clone(); let (tx, service_rx) = tracing_unbounded("mpsc_chain_sync", 100_000); @@ -489,7 +470,8 @@ where Self { roles, client, - chain_sync, + strategy, + syncing_config, network_service, peers: HashMap::new(), block_announce_data_cache: LruMap::new(ByLength::new(cache_capacity)), @@ -543,37 +525,19 @@ where if let Some(metrics) = &self.metrics { let n = u64::try_from(self.peers.len()).unwrap_or(std::u64::MAX); metrics.peers.set(n); - - let m = self.chain_sync.metrics(); - - metrics.fork_targets.set(m.fork_targets.into()); - metrics.queued_blocks.set(m.queued_blocks.into()); - - metrics - .justifications - .with_label_values(&["pending"]) - .set(m.justifications.pending_requests.into()); - metrics - .justifications - .with_label_values(&["active"]) - .set(m.justifications.active_requests.into()); - metrics - .justifications - .with_label_values(&["failed"]) - .set(m.justifications.failed_requests.into()); - metrics - .justifications - .with_label_values(&["importing"]) - .set(m.justifications.importing_requests.into()); } + self.strategy.report_metrics(); } - fn update_peer_info(&mut self, peer_id: &PeerId) { - if let Some(info) = self.chain_sync.peer_info(peer_id) { - if let Some(ref mut peer) = self.peers.get_mut(peer_id) { - peer.info.best_hash = info.best_hash; - peer.info.best_number = info.best_number; - } + fn update_peer_info( + &mut self, + peer_id: &PeerId, + best_hash: B::Hash, + best_number: NumberFor, + ) { + if let Some(ref mut peer) = self.peers.get_mut(peer_id) { + peer.info.best_hash = best_hash; + peer.info.best_number = best_number; } } @@ -585,9 +549,11 @@ where match validation_result { BlockAnnounceValidationResult::Skip { peer_id: _ } => {}, BlockAnnounceValidationResult::Process { is_new_best, peer_id, announce } => { - self.chain_sync.on_validated_block_announce(is_new_best, peer_id, &announce); - - self.update_peer_info(&peer_id); + if let Some((best_hash, best_number)) = + self.strategy.on_validated_block_announce(is_new_best, peer_id, &announce) + { + self.update_peer_info(&peer_id, best_hash, best_number); + } if let Some(data) = announce.data { if !data.is_empty() { @@ -705,83 +671,106 @@ where // Update atomic variables self.num_connected.store(self.peers.len(), Ordering::Relaxed); - self.is_major_syncing - .store(self.chain_sync.status().state.is_major_syncing(), Ordering::Relaxed); + self.is_major_syncing.store(self.strategy.is_major_syncing(), Ordering::Relaxed); - // Process actions requested by `ChainSync`. - self.process_chain_sync_actions(); + // Process actions requested by a syncing strategy. + if let Err(e) = self.process_strategy_actions() { + error!("Terminating `SyncingEngine` due to fatal error: {e:?}"); + return + } } } - fn process_chain_sync_actions(&mut self) { - self.chain_sync.actions().for_each(|action| match action { - ChainSyncAction::SendBlockRequest { peer_id, request } => { - // Sending block request implies dropping obsolete pending response as we are not - // interested in it anymore (see [`ChainSyncAction::SendBlockRequest`]). - // Furthermore, only one request at a time is allowed to any peer. - let removed = self.pending_responses.remove(&peer_id); - self.send_block_request(peer_id, request.clone()); + fn process_strategy_actions(&mut self) -> Result<(), ClientError> { + for action in self.strategy.actions() { + match action { + SyncingAction::SendBlockRequest { peer_id, request } => { + // Sending block request implies dropping obsolete pending response as we are + // not interested in it anymore (see [`SyncingAction::SendBlockRequest`]). + // Furthermore, only one request at a time is allowed to any peer. + let removed = self.pending_responses.remove(&peer_id); + self.send_block_request(peer_id, request.clone()); + + trace!( + target: LOG_TARGET, + "Processed `ChainSyncAction::SendBlockRequest` to {} with {:?}, stale response removed: {}.", + peer_id, + request, + removed, + ) + }, + SyncingAction::CancelBlockRequest { peer_id } => { + let removed = self.pending_responses.remove(&peer_id); - trace!( - target: LOG_TARGET, - "Processed `ChainSyncAction::SendBlockRequest` to {} with {:?}, stale response removed: {}.", - peer_id, - request, - removed, - ) - }, - ChainSyncAction::CancelBlockRequest { peer_id } => { - let removed = self.pending_responses.remove(&peer_id); + trace!( + target: LOG_TARGET, + "Processed {action:?}, response removed: {removed}.", + ); + }, + SyncingAction::SendStateRequest { peer_id, request } => { + self.send_state_request(peer_id, request); - trace!(target: LOG_TARGET, "Processed {action:?}, response removed: {removed}."); - }, - ChainSyncAction::SendStateRequest { peer_id, request } => { - self.send_state_request(peer_id, request); + trace!( + target: LOG_TARGET, + "Processed `ChainSyncAction::SendBlockRequest` to {peer_id}.", + ); + }, + SyncingAction::SendWarpProofRequest { peer_id, request } => { + self.send_warp_proof_request(peer_id, request.clone()); - trace!( - target: LOG_TARGET, - "Processed `ChainSyncAction::SendBlockRequest` to {peer_id}.", - ); - }, - ChainSyncAction::SendWarpProofRequest { peer_id, request } => { - self.send_warp_proof_request(peer_id, request.clone()); + trace!( + target: LOG_TARGET, + "Processed `ChainSyncAction::SendWarpProofRequest` to {}, request: {:?}.", + peer_id, + request, + ); + }, + SyncingAction::DropPeer(BadPeer(peer_id, rep)) => { + self.pending_responses.remove(&peer_id); + self.network_service + .disconnect_peer(peer_id, self.block_announce_protocol_name.clone()); + self.network_service.report_peer(peer_id, rep); - trace!( - target: LOG_TARGET, - "Processed `ChainSyncAction::SendWarpProofRequest` to {}, request: {:?}.", - peer_id, - request, - ); - }, - ChainSyncAction::DropPeer(BadPeer(peer_id, rep)) => { - self.pending_responses.remove(&peer_id); - self.network_service - .disconnect_peer(peer_id, self.block_announce_protocol_name.clone()); - self.network_service.report_peer(peer_id, rep); + trace!(target: LOG_TARGET, "{peer_id:?} dropped: {rep:?}."); + }, + SyncingAction::ImportBlocks { origin, blocks } => { + let count = blocks.len(); + self.import_blocks(origin, blocks); - trace!(target: LOG_TARGET, "Processed {action:?}."); - }, - ChainSyncAction::ImportBlocks { origin, blocks } => { - let count = blocks.len(); - self.import_blocks(origin, blocks); + trace!( + target: LOG_TARGET, + "Processed `ChainSyncAction::ImportBlocks` with {count} blocks.", + ); + }, + SyncingAction::ImportJustifications { peer_id, hash, number, justifications } => { + self.import_justifications(peer_id, hash, number, justifications); - trace!( - target: LOG_TARGET, - "Processed `ChainSyncAction::ImportBlocks` with {count} blocks.", - ); - }, - ChainSyncAction::ImportJustifications { peer_id, hash, number, justifications } => { - self.import_justifications(peer_id, hash, number, justifications); + trace!( + target: LOG_TARGET, + "Processed `ChainSyncAction::ImportJustifications` from peer {} for block {} ({}).", + peer_id, + hash, + number, + ) + }, + SyncingAction::Finished => { + let connected_peers = self.peers.iter().filter_map(|(peer_id, peer)| { + peer.info.roles.is_full().then_some(( + *peer_id, + peer.info.best_hash, + peer.info.best_number, + )) + }); + self.strategy.switch_to_next( + self.syncing_config.clone(), + self.client.clone(), + connected_peers, + )?; + }, + } + } - trace!( - target: LOG_TARGET, - "Processed `ChainSyncAction::ImportJustifications` from peer {} for block {} ({}).", - peer_id, - hash, - number, - ) - }, - }); + Ok(()) } fn perform_periodic_actions(&mut self) { @@ -824,18 +813,18 @@ where fn process_service_command(&mut self, command: ToServiceCommand) { match command { ToServiceCommand::SetSyncForkRequest(peers, hash, number) => { - self.chain_sync.set_sync_fork_request(peers, &hash, number); + self.strategy.set_sync_fork_request(peers, &hash, number); }, ToServiceCommand::EventStream(tx) => self.event_streams.push(tx), ToServiceCommand::RequestJustification(hash, number) => - self.chain_sync.request_justification(&hash, number), + self.strategy.request_justification(&hash, number), ToServiceCommand::ClearJustificationRequests => - self.chain_sync.clear_justification_requests(), + self.strategy.clear_justification_requests(), ToServiceCommand::BlocksProcessed(imported, count, results) => { - self.chain_sync.on_blocks_processed(imported, count, results); + self.strategy.on_blocks_processed(imported, count, results); }, ToServiceCommand::JustificationImported(peer_id, hash, number, success) => { - self.chain_sync.on_justification_import(hash, number, success); + self.strategy.on_justification_import(hash, number, success); if !success { log::info!( target: LOG_TARGET, @@ -849,9 +838,9 @@ where }, ToServiceCommand::AnnounceBlock(hash, data) => self.announce_block(hash, data), ToServiceCommand::NewBestBlockImported(hash, number) => { - log::debug!(target: "sync", "New best block imported {:?}/#{}", hash, number); + log::debug!(target: LOG_TARGET, "New best block imported {:?}/#{}", hash, number); - self.chain_sync.update_chain_info(&hash, number); + self.strategy.update_chain_info(&hash, number); let _ = self.notification_service.try_set_handshake( BlockAnnouncesHandshake::::build( self.roles, @@ -863,7 +852,7 @@ where ); }, ToServiceCommand::Status(tx) => { - let mut status = self.chain_sync.status(); + let mut status = self.strategy.status(); status.num_connected_peers = self.peers.len() as u32; let _ = tx.send(status); }, @@ -871,22 +860,22 @@ where let _ = tx.send(self.num_active_peers()); }, ToServiceCommand::SyncState(tx) => { - let _ = tx.send(self.chain_sync.status()); + let _ = tx.send(self.strategy.status()); }, ToServiceCommand::BestSeenBlock(tx) => { - let _ = tx.send(self.chain_sync.status().best_seen_block); + let _ = tx.send(self.strategy.status().best_seen_block); }, ToServiceCommand::NumSyncPeers(tx) => { - let _ = tx.send(self.chain_sync.status().num_peers); + let _ = tx.send(self.strategy.status().num_peers); }, ToServiceCommand::NumQueuedBlocks(tx) => { - let _ = tx.send(self.chain_sync.status().queued_blocks); + let _ = tx.send(self.strategy.status().queued_blocks); }, ToServiceCommand::NumDownloadedBlocks(tx) => { - let _ = tx.send(self.chain_sync.num_downloaded_blocks()); + let _ = tx.send(self.strategy.num_downloaded_blocks()); }, ToServiceCommand::NumSyncRequests(tx) => { - let _ = tx.send(self.chain_sync.num_sync_requests()); + let _ = tx.send(self.strategy.num_sync_requests()); }, ToServiceCommand::PeersInfo(tx) => { let peers_info = self @@ -897,7 +886,7 @@ where let _ = tx.send(peers_info); }, ToServiceCommand::OnBlockFinalized(hash, header) => - self.chain_sync.on_block_finalized(&hash, *header.number()), + self.strategy.on_block_finalized(&hash, *header.number()), } } @@ -961,11 +950,18 @@ where fn pass_warp_sync_target_block_header(&mut self, header: Result) { match header { - Ok(header) => { - self.chain_sync.set_warp_sync_target_block(header); - }, + Ok(header) => + if let SyncingStrategy::WarpSyncStrategy(warp_sync) = &mut self.strategy { + warp_sync.set_target_block(header); + } else { + error!( + target: LOG_TARGET, + "Cannot set warp sync target block: no warp sync strategy is active." + ); + debug_assert!(false); + }, Err(err) => { - log::error!( + error!( target: LOG_TARGET, "Failed to get target block for warp sync. Error: {err:?}", ); @@ -1005,7 +1001,7 @@ where } } - self.chain_sync.peer_disconnected(&peer_id); + self.strategy.remove_peer(&peer_id); self.pending_responses.remove(&peer_id); self.event_streams .retain(|stream| stream.unbounded_send(SyncEvent::PeerDisconnected(peer_id)).is_ok()); @@ -1091,7 +1087,7 @@ where let this_peer_reserved_slot: usize = if no_slot_peer { 1 } else { 0 }; if handshake.roles.is_full() && - self.chain_sync.num_peers() >= + self.strategy.num_peers() >= self.default_peers_set_num_full + self.default_peers_set_no_slot_connected_peers.len() + this_peer_reserved_slot @@ -1115,7 +1111,7 @@ where // `ChainSync` only accepts full peers whereas `SyncingEngine` accepts both full and light // peers. Verify that there is a slot in `SyncingEngine` for the inbound light peer if handshake.roles.is_light() && - (self.peers.len() - self.chain_sync.num_peers()) >= self.default_peers_set_num_light + (self.peers.len() - self.strategy.num_peers()) >= self.default_peers_set_num_light { log::debug!(target: LOG_TARGET, "Too many light nodes, rejecting {peer_id}"); return Err(false) @@ -1149,7 +1145,10 @@ where inbound: direction.is_inbound(), }; - self.chain_sync.new_peer(peer_id, peer.info.best_hash, peer.info.best_number); + // Only forward full peers to syncing strategy. + if status.roles.is_full() { + self.strategy.add_peer(peer_id, peer.info.best_hash, peer.info.best_number); + } log::debug!(target: LOG_TARGET, "Connected {peer_id}"); @@ -1267,7 +1266,7 @@ where PeerRequest::Block(req) => { match self.block_downloader.block_response_into_blocks(&req, resp) { Ok(blocks) => { - self.chain_sync.on_block_response(peer_id, req, blocks); + self.strategy.on_block_response(peer_id, req, blocks); }, Err(BlockResponseError::DecodeFailed(e)) => { debug!( @@ -1312,10 +1311,10 @@ where }, }; - self.chain_sync.on_state_response(peer_id, response); + self.strategy.on_state_response(peer_id, response); }, PeerRequest::WarpProof => { - self.chain_sync.on_warp_sync_response(&peer_id, EncodedProof(resp)); + self.strategy.on_warp_proof_response(&peer_id, EncodedProof(resp)); }, }, Ok(Err(e)) => { diff --git a/substrate/client/network/sync/src/extra_requests.rs b/substrate/client/network/sync/src/extra_requests.rs index 8edd1a772e2..cd3008d270b 100644 --- a/substrate/client/network/sync/src/extra_requests.rs +++ b/substrate/client/network/sync/src/extra_requests.rs @@ -17,8 +17,9 @@ // along with this program. If not, see . use crate::{ - chain_sync::{PeerSync, PeerSyncState}, request_metrics::Metrics, + strategy::chain_sync::{PeerSync, PeerSyncState}, + LOG_TARGET, }; use fork_tree::ForkTree; use libp2p::PeerId; @@ -102,7 +103,7 @@ impl ExtraRequests { // ignore the `Revert` error. }, Err(err) => { - debug!(target: "sync", "Failed to insert request {:?} into tree: {}", request, err); + debug!(target: LOG_TARGET, "Failed to insert request {:?} into tree: {}", request, err); }, _ => (), } @@ -126,7 +127,7 @@ impl ExtraRequests { // messages to chain sync. if let Some(request) = self.active_requests.remove(&who) { if let Some(r) = resp { - trace!(target: "sync", + trace!(target: LOG_TARGET, "Queuing import of {} from {:?} for {:?}", self.request_type_name, who, request, ); @@ -134,7 +135,7 @@ impl ExtraRequests { self.importing_requests.insert(request); return Some((who, request.0, request.1, r)) } else { - trace!(target: "sync", + trace!(target: LOG_TARGET, "Empty {} response from {:?} for {:?}", self.request_type_name, who, request, ); @@ -142,7 +143,7 @@ impl ExtraRequests { self.failed_requests.entry(request).or_default().push((who, Instant::now())); self.pending_requests.push_front(request); } else { - trace!(target: "sync", + trace!(target: LOG_TARGET, "No active {} request to {:?}", self.request_type_name, who, ); @@ -217,7 +218,7 @@ impl ExtraRequests { }; if self.tree.finalize_root(&finalized_hash).is_none() { - warn!(target: "sync", + warn!(target: LOG_TARGET, "‼️ Imported {:?} {:?} which isn't a root in the tree: {:?}", finalized_hash, finalized_number, self.tree.roots().collect::>() ); @@ -322,7 +323,7 @@ impl<'a, B: BlockT> Matcher<'a, B> { } self.extras.active_requests.insert(*peer, request); - trace!(target: "sync", + trace!(target: LOG_TARGET, "Sending {} request to {:?} for {:?}", self.extras.request_type_name, peer, request, ); @@ -345,7 +346,7 @@ impl<'a, B: BlockT> Matcher<'a, B> { #[cfg(test)] mod tests { use super::*; - use crate::chain_sync::PeerSync; + use crate::strategy::chain_sync::PeerSync; use quickcheck::{Arbitrary, Gen, QuickCheck}; use sp_blockchain::Error as ClientError; use sp_test_primitives::{Block, BlockNumber, Hash}; diff --git a/substrate/client/network/sync/src/lib.rs b/substrate/client/network/sync/src/lib.rs index 1a7e773c95f..494e3b87aa9 100644 --- a/substrate/client/network/sync/src/lib.rs +++ b/substrate/client/network/sync/src/lib.rs @@ -19,10 +19,10 @@ //! Blockchain syncing implementation in Substrate. pub use service::syncing_service::SyncingService; +pub use strategy::warp::{WarpSyncParams, WarpSyncPhase, WarpSyncProgress}; pub use types::{SyncEvent, SyncEventStream, SyncState, SyncStatus, SyncStatusProvider}; mod block_announce_validator; -mod chain_sync; mod extra_requests; mod futures_stream; mod pending_responses; @@ -36,7 +36,9 @@ pub mod blocks; pub mod engine; pub mod mock; pub mod service; -pub mod state; pub mod state_request_handler; -pub mod warp; +pub mod strategy; pub mod warp_request_handler; + +/// Log target for this crate. +const LOG_TARGET: &str = "sync"; diff --git a/substrate/client/network/sync/src/pending_responses.rs b/substrate/client/network/sync/src/pending_responses.rs index e21a5763225..21e409eb847 100644 --- a/substrate/client/network/sync/src/pending_responses.rs +++ b/substrate/client/network/sync/src/pending_responses.rs @@ -19,7 +19,7 @@ //! [`PendingResponses`] is responsible for keeping track of pending responses and //! polling them. [`Stream`] implemented by [`PendingResponses`] never terminates. -use crate::types::PeerRequest; +use crate::{types::PeerRequest, LOG_TARGET}; use futures::{ channel::oneshot, future::BoxFuture, @@ -33,9 +33,6 @@ use sp_runtime::traits::Block as BlockT; use std::task::{Context, Poll, Waker}; use tokio_stream::StreamMap; -/// Log target for this file. -const LOG_TARGET: &'static str = "sync"; - /// Response result. type ResponseResult = Result, ProtocolName), RequestFailure>, oneshot::Canceled>; diff --git a/substrate/client/network/sync/src/state_request_handler.rs b/substrate/client/network/sync/src/state_request_handler.rs index f78fadccc2d..6bd2389fb5d 100644 --- a/substrate/client/network/sync/src/state_request_handler.rs +++ b/substrate/client/network/sync/src/state_request_handler.rs @@ -17,7 +17,10 @@ //! Helper for handling (i.e. answering) state requests from a remote peer via the //! `crate::request_responses::RequestResponsesBehaviour`. -use crate::schema::v1::{KeyValueStateEntry, StateEntry, StateRequest, StateResponse}; +use crate::{ + schema::v1::{KeyValueStateEntry, StateEntry, StateRequest, StateResponse}, + LOG_TARGET, +}; use codec::{Decode, Encode}; use futures::{channel::oneshot, stream::StreamExt}; @@ -39,7 +42,6 @@ use std::{ time::Duration, }; -const LOG_TARGET: &str = "sync"; const MAX_RESPONSE_BYTES: usize = 2 * 1024 * 1024; // Actual reponse may be bigger. const MAX_NUMBER_OF_SAME_REQUESTS_PER_PEER: usize = 2; diff --git a/substrate/client/network/sync/src/strategy.rs b/substrate/client/network/sync/src/strategy.rs new file mode 100644 index 00000000000..ee99252fc91 --- /dev/null +++ b/substrate/client/network/sync/src/strategy.rs @@ -0,0 +1,489 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! [`SyncingStrategy`] is a proxy between [`crate::engine::SyncingEngine`] +//! and specific syncing algorithms. + +pub mod chain_sync; +mod state; +pub mod state_sync; +pub mod warp; + +use crate::{ + types::{BadPeer, OpaqueStateRequest, OpaqueStateResponse, SyncStatus}, + LOG_TARGET, +}; +use chain_sync::{ChainSync, ChainSyncAction, ChainSyncMode}; +use libp2p::PeerId; +use log::{error, info}; +use prometheus_endpoint::Registry; +use sc_client_api::{BlockBackend, ProofProvider}; +use sc_consensus::{BlockImportError, BlockImportStatus, IncomingBlock}; +use sc_network_common::sync::{ + message::{BlockAnnounce, BlockData, BlockRequest}, + SyncMode, +}; +use sp_blockchain::{Error as ClientError, HeaderBackend, HeaderMetadata}; +use sp_consensus::BlockOrigin; +use sp_runtime::{ + traits::{Block as BlockT, NumberFor}, + Justifications, +}; +use state::{StateStrategy, StateStrategyAction}; +use std::sync::Arc; +use warp::{EncodedProof, WarpProofRequest, WarpSync, WarpSyncAction, WarpSyncConfig}; + +/// Corresponding `ChainSync` mode. +fn chain_sync_mode(sync_mode: SyncMode) -> ChainSyncMode { + match sync_mode { + SyncMode::Full => ChainSyncMode::Full, + SyncMode::LightState { skip_proofs, storage_chain_mode } => + ChainSyncMode::LightState { skip_proofs, storage_chain_mode }, + SyncMode::Warp => ChainSyncMode::Full, + } +} + +/// Syncing configuration containing data for all strategies. +#[derive(Clone, Debug)] +pub struct SyncingConfig { + /// Syncing mode. + pub mode: SyncMode, + /// The number of parallel downloads to guard against slow peers. + pub max_parallel_downloads: u32, + /// Maximum number of blocks to request. + pub max_blocks_per_request: u32, + /// Prometheus metrics registry. + pub metrics_registry: Option, +} + +#[derive(Debug)] +pub enum SyncingAction { + /// Send block request to peer. Always implies dropping a stale block request to the same peer. + SendBlockRequest { peer_id: PeerId, request: BlockRequest }, + /// Drop stale block request. + CancelBlockRequest { peer_id: PeerId }, + /// Send state request to peer. + SendStateRequest { peer_id: PeerId, request: OpaqueStateRequest }, + /// Send warp proof request to peer. + SendWarpProofRequest { peer_id: PeerId, request: WarpProofRequest }, + /// Peer misbehaved. Disconnect, report it and cancel any requests to it. + DropPeer(BadPeer), + /// Import blocks. + ImportBlocks { origin: BlockOrigin, blocks: Vec> }, + /// Import justifications. + ImportJustifications { + peer_id: PeerId, + hash: B::Hash, + number: NumberFor, + justifications: Justifications, + }, + /// Syncing strategy has finished. + Finished, +} + +/// Proxy to specific syncing strategies. +pub enum SyncingStrategy { + WarpSyncStrategy(WarpSync), + StateSyncStrategy(StateStrategy), + ChainSyncStrategy(ChainSync), +} + +impl SyncingStrategy +where + B: BlockT, + Client: HeaderBackend + + BlockBackend + + HeaderMetadata + + ProofProvider + + Send + + Sync + + 'static, +{ + /// Initialize a new syncing startegy. + pub fn new( + config: SyncingConfig, + client: Arc, + warp_sync_config: Option>, + ) -> Result { + if let SyncMode::Warp = config.mode { + let warp_sync_config = warp_sync_config + .expect("Warp sync configuration must be supplied in warp sync mode."); + Ok(Self::WarpSyncStrategy(WarpSync::new(client.clone(), warp_sync_config))) + } else { + Ok(Self::ChainSyncStrategy(ChainSync::new( + chain_sync_mode(config.mode), + client.clone(), + config.max_parallel_downloads, + config.max_blocks_per_request, + config.metrics_registry, + )?)) + } + } + + /// Notify that a new peer has connected. + pub fn add_peer(&mut self, peer_id: PeerId, best_hash: B::Hash, best_number: NumberFor) { + match self { + SyncingStrategy::WarpSyncStrategy(strategy) => + strategy.add_peer(peer_id, best_hash, best_number), + SyncingStrategy::StateSyncStrategy(strategy) => + strategy.add_peer(peer_id, best_hash, best_number), + SyncingStrategy::ChainSyncStrategy(strategy) => + strategy.add_peer(peer_id, best_hash, best_number), + } + } + + /// Notify that a peer has disconnected. + pub fn remove_peer(&mut self, peer_id: &PeerId) { + match self { + SyncingStrategy::WarpSyncStrategy(strategy) => strategy.remove_peer(peer_id), + SyncingStrategy::StateSyncStrategy(strategy) => strategy.remove_peer(peer_id), + SyncingStrategy::ChainSyncStrategy(strategy) => strategy.remove_peer(peer_id), + } + } + + /// Submit a validated block announcement. + /// + /// Returns new best hash & best number of the peer if they are updated. + pub fn on_validated_block_announce( + &mut self, + is_best: bool, + peer_id: PeerId, + announce: &BlockAnnounce, + ) -> Option<(B::Hash, NumberFor)> { + match self { + SyncingStrategy::WarpSyncStrategy(strategy) => + strategy.on_validated_block_announce(is_best, peer_id, announce), + SyncingStrategy::StateSyncStrategy(strategy) => + strategy.on_validated_block_announce(is_best, peer_id, announce), + SyncingStrategy::ChainSyncStrategy(strategy) => + strategy.on_validated_block_announce(is_best, peer_id, announce), + } + } + + /// Configure an explicit fork sync request in case external code has detected that there is a + /// stale fork missing. + pub fn set_sync_fork_request( + &mut self, + peers: Vec, + hash: &B::Hash, + number: NumberFor, + ) { + match self { + SyncingStrategy::WarpSyncStrategy(_) => {}, + SyncingStrategy::StateSyncStrategy(_) => {}, + SyncingStrategy::ChainSyncStrategy(strategy) => + strategy.set_sync_fork_request(peers, hash, number), + } + } + + /// Request extra justification. + pub fn request_justification(&mut self, hash: &B::Hash, number: NumberFor) { + match self { + SyncingStrategy::WarpSyncStrategy(_) => {}, + SyncingStrategy::StateSyncStrategy(_) => {}, + SyncingStrategy::ChainSyncStrategy(strategy) => + strategy.request_justification(hash, number), + } + } + + /// Clear extra justification requests. + pub fn clear_justification_requests(&mut self) { + match self { + SyncingStrategy::WarpSyncStrategy(_) => {}, + SyncingStrategy::StateSyncStrategy(_) => {}, + SyncingStrategy::ChainSyncStrategy(strategy) => strategy.clear_justification_requests(), + } + } + + /// Report a justification import (successful or not). + pub fn on_justification_import(&mut self, hash: B::Hash, number: NumberFor, success: bool) { + match self { + SyncingStrategy::WarpSyncStrategy(_) => {}, + SyncingStrategy::StateSyncStrategy(_) => {}, + SyncingStrategy::ChainSyncStrategy(strategy) => + strategy.on_justification_import(hash, number, success), + } + } + + /// Process block response. + pub fn on_block_response( + &mut self, + peer_id: PeerId, + request: BlockRequest, + blocks: Vec>, + ) { + match self { + SyncingStrategy::WarpSyncStrategy(strategy) => + strategy.on_block_response(peer_id, request, blocks), + SyncingStrategy::StateSyncStrategy(_) => {}, + SyncingStrategy::ChainSyncStrategy(strategy) => + strategy.on_block_response(peer_id, request, blocks), + } + } + + /// Process state response. + pub fn on_state_response(&mut self, peer_id: PeerId, response: OpaqueStateResponse) { + match self { + SyncingStrategy::WarpSyncStrategy(_) => {}, + SyncingStrategy::StateSyncStrategy(strategy) => + strategy.on_state_response(peer_id, response), + SyncingStrategy::ChainSyncStrategy(strategy) => + strategy.on_state_response(peer_id, response), + } + } + + /// Process warp proof response. + pub fn on_warp_proof_response(&mut self, peer_id: &PeerId, response: EncodedProof) { + match self { + SyncingStrategy::WarpSyncStrategy(strategy) => + strategy.on_warp_proof_response(peer_id, response), + SyncingStrategy::StateSyncStrategy(_) => {}, + SyncingStrategy::ChainSyncStrategy(_) => {}, + } + } + + /// A batch of blocks have been processed, with or without errors. + pub fn on_blocks_processed( + &mut self, + imported: usize, + count: usize, + results: Vec<(Result>, BlockImportError>, B::Hash)>, + ) { + match self { + SyncingStrategy::WarpSyncStrategy(_) => {}, + SyncingStrategy::StateSyncStrategy(strategy) => + strategy.on_blocks_processed(imported, count, results), + SyncingStrategy::ChainSyncStrategy(strategy) => + strategy.on_blocks_processed(imported, count, results), + } + } + + /// Notify a syncing strategy that a block has been finalized. + pub fn on_block_finalized(&mut self, hash: &B::Hash, number: NumberFor) { + match self { + SyncingStrategy::WarpSyncStrategy(_) => {}, + SyncingStrategy::StateSyncStrategy(_) => {}, + SyncingStrategy::ChainSyncStrategy(strategy) => + strategy.on_block_finalized(hash, number), + } + } + + /// Inform sync about a new best imported block. + pub fn update_chain_info(&mut self, best_hash: &B::Hash, best_number: NumberFor) { + match self { + SyncingStrategy::WarpSyncStrategy(_) => {}, + SyncingStrategy::StateSyncStrategy(_) => {}, + SyncingStrategy::ChainSyncStrategy(strategy) => + strategy.update_chain_info(best_hash, best_number), + } + } + + // Are we in major sync mode? + pub fn is_major_syncing(&self) -> bool { + match self { + SyncingStrategy::WarpSyncStrategy(_) => true, + SyncingStrategy::StateSyncStrategy(_) => true, + SyncingStrategy::ChainSyncStrategy(strategy) => + strategy.status().state.is_major_syncing(), + } + } + + /// Get the number of peers known to the syncing strategy. + pub fn num_peers(&self) -> usize { + match self { + SyncingStrategy::WarpSyncStrategy(strategy) => strategy.num_peers(), + SyncingStrategy::StateSyncStrategy(strategy) => strategy.num_peers(), + SyncingStrategy::ChainSyncStrategy(strategy) => strategy.num_peers(), + } + } + + /// Returns the current sync status. + pub fn status(&self) -> SyncStatus { + match self { + SyncingStrategy::WarpSyncStrategy(strategy) => strategy.status(), + SyncingStrategy::StateSyncStrategy(strategy) => strategy.status(), + SyncingStrategy::ChainSyncStrategy(strategy) => strategy.status(), + } + } + + /// Get the total number of downloaded blocks. + pub fn num_downloaded_blocks(&self) -> usize { + match self { + SyncingStrategy::WarpSyncStrategy(_) => 0, + SyncingStrategy::StateSyncStrategy(_) => 0, + SyncingStrategy::ChainSyncStrategy(strategy) => strategy.num_downloaded_blocks(), + } + } + + /// Get an estimate of the number of parallel sync requests. + pub fn num_sync_requests(&self) -> usize { + match self { + SyncingStrategy::WarpSyncStrategy(_) => 0, + SyncingStrategy::StateSyncStrategy(_) => 0, + SyncingStrategy::ChainSyncStrategy(strategy) => strategy.num_sync_requests(), + } + } + + /// Report Prometheus metrics + pub fn report_metrics(&self) { + match self { + SyncingStrategy::WarpSyncStrategy(_) => {}, + SyncingStrategy::StateSyncStrategy(_) => {}, + SyncingStrategy::ChainSyncStrategy(strategy) => strategy.report_metrics(), + } + } + + /// Get actions that should be performed by the owner on the strategy's behalf + #[must_use] + pub fn actions(&mut self) -> Box>> { + match self { + SyncingStrategy::WarpSyncStrategy(strategy) => + Box::new(strategy.actions().map(|action| match action { + WarpSyncAction::SendWarpProofRequest { peer_id, request } => + SyncingAction::SendWarpProofRequest { peer_id, request }, + WarpSyncAction::SendBlockRequest { peer_id, request } => + SyncingAction::SendBlockRequest { peer_id, request }, + WarpSyncAction::DropPeer(bad_peer) => SyncingAction::DropPeer(bad_peer), + WarpSyncAction::Finished => SyncingAction::Finished, + })), + SyncingStrategy::StateSyncStrategy(strategy) => + Box::new(strategy.actions().map(|action| match action { + StateStrategyAction::SendStateRequest { peer_id, request } => + SyncingAction::SendStateRequest { peer_id, request }, + StateStrategyAction::DropPeer(bad_peer) => SyncingAction::DropPeer(bad_peer), + StateStrategyAction::ImportBlocks { origin, blocks } => + SyncingAction::ImportBlocks { origin, blocks }, + StateStrategyAction::Finished => SyncingAction::Finished, + })), + SyncingStrategy::ChainSyncStrategy(strategy) => + Box::new(strategy.actions().map(|action| match action { + ChainSyncAction::SendBlockRequest { peer_id, request } => + SyncingAction::SendBlockRequest { peer_id, request }, + ChainSyncAction::CancelBlockRequest { peer_id } => + SyncingAction::CancelBlockRequest { peer_id }, + ChainSyncAction::SendStateRequest { peer_id, request } => + SyncingAction::SendStateRequest { peer_id, request }, + ChainSyncAction::DropPeer(bad_peer) => SyncingAction::DropPeer(bad_peer), + ChainSyncAction::ImportBlocks { origin, blocks } => + SyncingAction::ImportBlocks { origin, blocks }, + ChainSyncAction::ImportJustifications { + peer_id, + hash, + number, + justifications, + } => SyncingAction::ImportJustifications { + peer_id, + hash, + number, + justifications, + }, + })), + } + } + + /// Switch to next strategy if the active one finished. + pub fn switch_to_next( + &mut self, + config: SyncingConfig, + client: Arc, + connected_peers: impl Iterator)>, + ) -> Result<(), ClientError> { + match self { + Self::WarpSyncStrategy(warp_sync) => { + match warp_sync.take_result() { + Some(res) => { + info!( + target: LOG_TARGET, + "Warp sync is complete, continuing with state sync." + ); + let state_sync = StateStrategy::new( + client, + res.target_header, + res.target_body, + res.target_justifications, + // skip proofs, only set to `true` in `FastUnsafe` sync mode + false, + connected_peers + .map(|(peer_id, _best_hash, best_number)| (peer_id, best_number)), + ); + + *self = Self::StateSyncStrategy(state_sync); + }, + None => { + error!( + target: LOG_TARGET, + "Warp sync failed. Falling back to full sync." + ); + let mut chain_sync = match ChainSync::new( + chain_sync_mode(config.mode), + client, + config.max_parallel_downloads, + config.max_blocks_per_request, + config.metrics_registry, + ) { + Ok(chain_sync) => chain_sync, + Err(e) => { + error!(target: LOG_TARGET, "Failed to start `ChainSync`."); + return Err(e) + }, + }; + // Let `ChainSync` know about connected peers. + connected_peers.into_iter().for_each( + |(peer_id, best_hash, best_number)| { + chain_sync.add_peer(peer_id, best_hash, best_number) + }, + ); + + *self = Self::ChainSyncStrategy(chain_sync); + }, + } + }, + Self::StateSyncStrategy(state_sync) => { + if state_sync.is_succeded() { + info!(target: LOG_TARGET, "State sync is complete, continuing with block sync."); + } else { + error!(target: LOG_TARGET, "State sync failed. Falling back to full sync."); + } + let mut chain_sync = match ChainSync::new( + chain_sync_mode(config.mode), + client, + config.max_parallel_downloads, + config.max_blocks_per_request, + config.metrics_registry, + ) { + Ok(chain_sync) => chain_sync, + Err(e) => { + error!(target: LOG_TARGET, "Failed to start `ChainSync`."); + return Err(e); + }, + }; + // Let `ChainSync` know about connected peers. + connected_peers.into_iter().for_each(|(peer_id, best_hash, best_number)| { + chain_sync.add_peer(peer_id, best_hash, best_number) + }); + + *self = Self::ChainSyncStrategy(chain_sync); + }, + Self::ChainSyncStrategy(_) => { + error!(target: LOG_TARGET, "`ChainSyncStrategy` is final startegy, cannot switch to next."); + debug_assert!(false); + }, + } + Ok(()) + } +} diff --git a/substrate/client/network/sync/src/chain_sync.rs b/substrate/client/network/sync/src/strategy/chain_sync.rs similarity index 85% rename from substrate/client/network/sync/src/chain_sync.rs rename to substrate/client/network/sync/src/strategy/chain_sync.rs index 3825cfa33f7..62c260d582b 100644 --- a/substrate/client/network/sync/src/chain_sync.rs +++ b/substrate/client/network/sync/src/strategy/chain_sync.rs @@ -32,21 +32,18 @@ use crate::{ blocks::BlockCollection, extra_requests::ExtraRequests, schema::v1::StateResponse, - state::{ImportResult, StateSync}, - types::{ - BadPeer, Metrics, OpaqueStateRequest, OpaqueStateResponse, PeerInfo, SyncMode, SyncState, - SyncStatus, - }, - warp::{ - self, EncodedProof, WarpProofImportResult, WarpProofRequest, WarpSync, WarpSyncConfig, - WarpSyncPhase, WarpSyncProgress, + strategy::{ + state_sync::{ImportResult, StateSync, StateSyncProvider}, + warp::{WarpSyncPhase, WarpSyncProgress}, }, + types::{BadPeer, OpaqueStateRequest, OpaqueStateResponse, SyncState, SyncStatus}, + LOG_TARGET, }; use codec::Encode; use libp2p::PeerId; use log::{debug, error, info, trace, warn}; - +use prometheus_endpoint::{register, Gauge, GaugeVec, Opts, PrometheusError, Registry, U64}; use sc_client_api::{BlockBackend, ProofProvider}; use sc_consensus::{BlockImportError, BlockImportStatus, IncomingBlock}; use sc_network_common::sync::message::{ @@ -72,9 +69,6 @@ use std::{ #[cfg(test)] mod test; -/// Log target for this file. -const LOG_TARGET: &'static str = "sync"; - /// Maximum blocks to store in the import queue. const MAX_IMPORTING_BLOCKS: usize = 2048; @@ -95,9 +89,6 @@ const STATE_SYNC_FINALITY_THRESHOLD: u32 = 8; /// so far behind. const MAJOR_SYNC_BLOCKS: u8 = 5; -/// Number of peers that need to be connected before warp sync is started. -const MIN_PEERS_TO_START_WARP_SYNC: usize = 3; - mod rep { use sc_network::ReputationChange as Rep; /// Reputation change when a peer sent us a message that led to a @@ -133,6 +124,38 @@ mod rep { pub const BAD_RESPONSE: Rep = Rep::new(-(1 << 12), "Incomplete response"); } +struct Metrics { + queued_blocks: Gauge, + fork_targets: Gauge, + justifications: GaugeVec, +} + +impl Metrics { + fn register(r: &Registry) -> Result { + Ok(Self { + queued_blocks: { + let g = + Gauge::new("substrate_sync_queued_blocks", "Number of blocks in import queue")?; + register(g, r)? + }, + fork_targets: { + let g = Gauge::new("substrate_sync_fork_targets", "Number of fork sync targets")?; + register(g, r)? + }, + justifications: { + let g = GaugeVec::new( + Opts::new( + "substrate_sync_extra_justifications", + "Number of extra justifications requests", + ), + &["status"], + )?; + register(g, r)? + }, + }) + } +} + enum AllowedRequests { Some(HashSet), All, @@ -193,8 +216,6 @@ pub enum ChainSyncAction { CancelBlockRequest { peer_id: PeerId }, /// Send state request to peer. SendStateRequest { peer_id: PeerId, request: OpaqueStateRequest }, - /// Send warp proof request to peer. - SendWarpProofRequest { peer_id: PeerId, request: WarpProofRequest }, /// Peer misbehaved. Disconnect, report it and cancel the block request to it. DropPeer(BadPeer), /// Import blocks. @@ -208,6 +229,20 @@ pub enum ChainSyncAction { }, } +/// Sync operation mode. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum ChainSyncMode { + /// Full block download and verification. + Full, + /// Download blocks and the latest state. + LightState { + /// Skip state proof download and verification. + skip_proofs: bool, + /// Download indexed transactions for recent blocks. + storage_chain_mode: bool, + }, +} + /// The main data structure which contains all the state for a chains /// active syncing strategy. pub struct ChainSync { @@ -222,7 +257,7 @@ pub struct ChainSync { /// The best block hash in our queue of blocks to import best_queued_hash: B::Hash, /// Current mode (full/light) - mode: SyncMode, + mode: ChainSyncMode, /// Any extra justification requests. extra_justifications: ExtraRequests, /// A set of hashes of blocks that are being downloaded or have been @@ -240,14 +275,6 @@ pub struct ChainSync { downloaded_blocks: usize, /// State sync in progress, if any. state_sync: Option>, - /// Warp sync in progress, if any. - warp_sync: Option>, - /// Warp sync configuration. - /// - /// Will be `None` after `self.warp_sync` is `Some(_)`. - warp_sync_config: Option>, - /// A temporary storage for warp sync target block until warp sync is initialized. - warp_sync_target_block_header: Option, /// Enable importing existing blocks. This is used used after the state download to /// catch up to the latest state while re-importing blocks. import_existing: bool, @@ -255,6 +282,8 @@ pub struct ChainSync { gap_sync: Option>, /// Pending actions. actions: Vec>, + /// Prometheus metrics. + metrics: Option, } /// All the data we have about a Peer that we are trying to sync with @@ -316,10 +345,6 @@ pub(crate) enum PeerSyncState { DownloadingJustification(B::Hash), /// Downloading state. DownloadingState, - /// Downloading warp proof. - DownloadingWarpProof, - /// Downloading warp sync target block. - DownloadingWarpTargetBlock, /// Actively downloading block history after warp sync. DownloadingGap(NumberFor), } @@ -343,11 +368,11 @@ where { /// Create a new instance. pub fn new( - mode: SyncMode, + mode: ChainSyncMode, client: Arc, max_parallel_downloads: u32, max_blocks_per_request: u32, - warp_sync_config: Option>, + metrics_registry: Option, ) -> Result { let mut sync = Self { client, @@ -364,25 +389,25 @@ where max_blocks_per_request, downloaded_blocks: 0, state_sync: None, - warp_sync: None, import_existing: false, gap_sync: None, - warp_sync_config, - warp_sync_target_block_header: None, actions: Vec::new(), + metrics: metrics_registry.and_then(|r| match Metrics::register(&r) { + Ok(metrics) => Some(metrics), + Err(err) => { + log::error!( + target: LOG_TARGET, + "Failed to register `ChainSync` metrics {err:?}", + ); + None + }, + }), }; sync.reset_sync_start_point()?; Ok(sync) } - /// Get peer's best hash & number. - pub fn peer_info(&self, peer_id: &PeerId) -> Option> { - self.peers - .get(peer_id) - .map(|p| PeerInfo { best_hash: p.best_hash, best_number: p.best_number }) - } - /// Returns the current sync status. pub fn status(&self) -> SyncStatus { let median_seen = self.median_seen(); @@ -407,20 +432,10 @@ where SyncState::Idle }; - let warp_sync_progress = match (&self.warp_sync, &self.mode, &self.gap_sync) { - (_, _, Some(gap_sync)) => Some(WarpSyncProgress { - phase: WarpSyncPhase::DownloadingBlocks(gap_sync.best_queued_number), - total_bytes: 0, - }), - (None, SyncMode::Warp, _) => Some(WarpSyncProgress { - phase: WarpSyncPhase::AwaitingPeers { - required_peers: MIN_PEERS_TO_START_WARP_SYNC, - }, - total_bytes: 0, - }), - (Some(sync), _, _) => Some(sync.progress()), - _ => None, - }; + let warp_sync_progress = self.gap_sync.as_ref().map(|gap_sync| WarpSyncProgress { + phase: WarpSyncPhase::DownloadingBlocks(gap_sync.best_queued_number), + total_bytes: 0, + }); SyncStatus { state: sync_state, @@ -452,8 +467,8 @@ where } /// Notify syncing state machine that a new sync peer has connected. - pub fn new_peer(&mut self, peer_id: PeerId, best_hash: B::Hash, best_number: NumberFor) { - match self.new_peer_inner(peer_id, best_hash, best_number) { + pub fn add_peer(&mut self, peer_id: PeerId, best_hash: B::Hash, best_number: NumberFor) { + match self.add_peer_inner(peer_id, best_hash, best_number) { Ok(Some(request)) => self.actions.push(ChainSyncAction::SendBlockRequest { peer_id, request }), Ok(None) => {}, @@ -462,7 +477,7 @@ where } #[must_use] - fn new_peer_inner( + fn add_peer_inner( &mut self, peer_id: PeerId, best_hash: B::Hash, @@ -471,7 +486,7 @@ where // There is nothing sync can get from the node that has no blockchain data. match self.block_status(&best_hash) { Err(e) => { - debug!(target:LOG_TARGET, "Error reading blockchain: {e}"); + debug!(target: LOG_TARGET, "Error reading blockchain: {e}"); Err(BadPeer(peer_id, rep::BLOCKCHAIN_READ_ERROR)) }, Ok(BlockStatus::KnownBad) => { @@ -494,7 +509,7 @@ where // an ancestor search, which is what we do in the next match case below. if self.queue_blocks.len() > MAJOR_SYNC_BLOCKS.into() { debug!( - target:LOG_TARGET, + target: LOG_TARGET, "New peer {} with unknown best hash {} ({}), assuming common block.", peer_id, self.best_queued_hash, @@ -516,7 +531,7 @@ where // If we are at genesis, just start downloading. let (state, req) = if self.best_queued_number.is_zero() { debug!( - target:LOG_TARGET, + target: LOG_TARGET, "New peer {peer_id} with best hash {best_hash} ({best_number}).", ); @@ -525,7 +540,7 @@ where let common_best = std::cmp::min(self.best_queued_number, best_number); debug!( - target:LOG_TARGET, + target: LOG_TARGET, "New peer {} with unknown best hash {} ({}), searching for common ancestor.", peer_id, best_hash, @@ -554,20 +569,6 @@ where }, ); - if let SyncMode::Warp = self.mode { - if self.peers.len() >= MIN_PEERS_TO_START_WARP_SYNC && self.warp_sync.is_none() - { - log::debug!(target: LOG_TARGET, "Starting warp state sync."); - - if let Some(config) = self.warp_sync_config.take() { - let mut warp_sync = WarpSync::new(self.client.clone(), config); - if let Some(header) = self.warp_sync_target_block_header.take() { - warp_sync.set_target_block(header); - } - self.warp_sync = Some(warp_sync); - } - } - } Ok(req) }, Ok(BlockStatus::Queued) | @@ -831,7 +832,7 @@ where } if matching_hash.is_none() && current.is_zero() { trace!( - target:LOG_TARGET, + target: LOG_TARGET, "Ancestry search: genesis mismatch for peer {peer_id}", ); return Err(BadPeer(*peer_id, rep::GENESIS_MISMATCH)) @@ -886,43 +887,9 @@ where return Ok(()) } }, - PeerSyncState::DownloadingWarpTargetBlock => { - peer.state = PeerSyncState::Available; - if let Some(warp_sync) = &mut self.warp_sync { - if blocks.len() == 1 { - validate_blocks::(&blocks, peer_id, Some(request))?; - match warp_sync.import_target_block( - blocks.pop().expect("`blocks` len checked above."), - ) { - warp::TargetBlockImportResult::Success => return Ok(()), - warp::TargetBlockImportResult::BadResponse => - return Err(BadPeer(*peer_id, rep::VERIFICATION_FAIL)), - } - } else if blocks.is_empty() { - debug!(target: LOG_TARGET, "Empty block response from {peer_id}"); - return Err(BadPeer(*peer_id, rep::NO_BLOCK)) - } else { - debug!( - target: LOG_TARGET, - "Too many blocks ({}) in warp target block response from {}", - blocks.len(), - peer_id, - ); - return Err(BadPeer(*peer_id, rep::NOT_REQUESTED)) - } - } else { - debug!( - target: LOG_TARGET, - "Logic error: we think we are downloading warp target block from {}, but no warp sync is happening.", - peer_id, - ); - return Ok(()) - } - }, PeerSyncState::Available | PeerSyncState::DownloadingJustification(..) | - PeerSyncState::DownloadingState | - PeerSyncState::DownloadingWarpProof => Vec::new(), + PeerSyncState::DownloadingState => Vec::new(), } } else { // When request.is_none() this is a block announcement. Just accept blocks. @@ -1037,7 +1004,7 @@ where is_descendent_of(&**client, base, block) }); - if let SyncMode::LightState { skip_proofs, .. } = &self.mode { + if let ChainSyncMode::LightState { skip_proofs, .. } = &self.mode { if self.state_sync.is_none() && !self.peers.is_empty() && self.queue_blocks.is_empty() { // Finalized a recent block. let mut heads: Vec<_> = self.peers.values().map(|peer| peer.best_number).collect(); @@ -1071,12 +1038,15 @@ where } /// Submit a validated block announcement. + /// + /// Returns new best hash & best number of the peer if they are updated. + #[must_use] pub fn on_validated_block_announce( &mut self, is_best: bool, peer_id: PeerId, announce: &BlockAnnounce, - ) { + ) -> Option<(B::Hash, NumberFor)> { let number = *announce.header.number(); let hash = announce.header.hash(); let parent_status = @@ -1089,19 +1059,21 @@ where peer } else { error!(target: LOG_TARGET, "💔 Called `on_validated_block_announce` with a bad peer ID"); - return + return Some((hash, number)) }; if let PeerSyncState::AncestorSearch { .. } = peer.state { trace!(target: LOG_TARGET, "Peer {} is in the ancestor search state.", peer_id); - return + return None } - if is_best { + let peer_info = is_best.then(|| { // update their best block peer.best_number = number; peer.best_hash = hash; - } + + (hash, number) + }); // If the announced block is the best they have and is not ahead of us, our common number // is either one further ahead or it's the one they just announced, if we know about it. @@ -1118,27 +1090,27 @@ where // known block case if known || self.is_already_downloading(&hash) { - trace!(target: "sync", "Known block announce from {}: {}", peer_id, hash); + trace!(target: LOG_TARGET, "Known block announce from {}: {}", peer_id, hash); if let Some(target) = self.fork_targets.get_mut(&hash) { target.peers.insert(peer_id); } - return + return peer_info } if ancient_parent { trace!( - target: "sync", + target: LOG_TARGET, "Ignored ancient block announced from {}: {} {:?}", peer_id, hash, announce.header, ); - return + return peer_info } if self.status().state == SyncState::Idle { trace!( - target: "sync", + target: LOG_TARGET, "Added sync target for block announced from {}: {} {:?}", peer_id, hash, @@ -1154,10 +1126,12 @@ where .peers .insert(peer_id); } + + peer_info } /// Notify that a sync peer has disconnected. - pub fn peer_disconnected(&mut self, peer_id: &PeerId) { + pub fn remove_peer(&mut self, peer_id: &PeerId) { self.blocks.clear_peer_download(peer_id); if let Some(gap_sync) = &mut self.gap_sync { gap_sync.blocks.clear_peer_download(peer_id) @@ -1177,12 +1151,33 @@ where } } - /// Get prometheus metrics. - pub fn metrics(&self) -> Metrics { - Metrics { - queued_blocks: self.queue_blocks.len().try_into().unwrap_or(std::u32::MAX), - fork_targets: self.fork_targets.len().try_into().unwrap_or(std::u32::MAX), - justifications: self.extra_justifications.metrics(), + /// Report prometheus metrics. + pub fn report_metrics(&self) { + if let Some(metrics) = &self.metrics { + metrics + .fork_targets + .set(self.fork_targets.len().try_into().unwrap_or(std::u64::MAX)); + metrics + .queued_blocks + .set(self.queue_blocks.len().try_into().unwrap_or(std::u64::MAX)); + + let justifications_metrics = self.extra_justifications.metrics(); + metrics + .justifications + .with_label_values(&["pending"]) + .set(justifications_metrics.pending_requests.into()); + metrics + .justifications + .with_label_values(&["active"]) + .set(justifications_metrics.active_requests.into()); + metrics + .justifications + .with_label_values(&["failed"]) + .set(justifications_metrics.failed_requests.into()); + metrics + .justifications + .with_label_values(&["importing"]) + .set(justifications_metrics.importing_requests.into()); } } @@ -1202,11 +1197,11 @@ where fn required_block_attributes(&self) -> BlockAttributes { match self.mode { - SyncMode::Full => + ChainSyncMode::Full => BlockAttributes::HEADER | BlockAttributes::JUSTIFICATION | BlockAttributes::BODY, - SyncMode::LightState { storage_chain_mode: false, .. } | SyncMode::Warp => + ChainSyncMode::LightState { storage_chain_mode: false, .. } => BlockAttributes::HEADER | BlockAttributes::JUSTIFICATION | BlockAttributes::BODY, - SyncMode::LightState { storage_chain_mode: true, .. } => + ChainSyncMode::LightState { storage_chain_mode: true, .. } => BlockAttributes::HEADER | BlockAttributes::JUSTIFICATION | BlockAttributes::INDEXED_BODY, @@ -1215,9 +1210,8 @@ where fn skip_execution(&self) -> bool { match self.mode { - SyncMode::Full => false, - SyncMode::LightState { .. } => true, - SyncMode::Warp => true, + ChainSyncMode::Full => false, + ChainSyncMode::LightState { .. } => true, } } @@ -1243,7 +1237,7 @@ where .and_then(|b| b.header.as_ref().map(|h| (&b.hash, *h.number()))) { trace!( - target:LOG_TARGET, + target: LOG_TARGET, "Accepted {} blocks ({:?}) with origin {:?}", new_blocks.len(), h, @@ -1336,7 +1330,7 @@ where } // handle peers that were in other states. - let action = match self.new_peer_inner(peer_id, p.best_hash, p.best_number) { + let action = match self.add_peer_inner(peer_id, p.best_hash, p.best_number) { // since the request is not a justification, remove it from pending responses Ok(None) => ChainSyncAction::CancelBlockRequest { peer_id }, // update the request if the new one is available @@ -1353,25 +1347,19 @@ where /// state for. fn reset_sync_start_point(&mut self) -> Result<(), ClientError> { let info = self.client.info(); - if matches!(self.mode, SyncMode::LightState { .. }) && info.finalized_state.is_some() { + if matches!(self.mode, ChainSyncMode::LightState { .. }) && info.finalized_state.is_some() { warn!( target: LOG_TARGET, "Can't use fast sync mode with a partially synced database. Reverting to full sync mode." ); - self.mode = SyncMode::Full; - } - if matches!(self.mode, SyncMode::Warp) && info.finalized_state.is_some() { - warn!( - target: LOG_TARGET, - "Can't use warp sync mode with a partially synced database. Reverting to full sync mode." - ); - self.mode = SyncMode::Full; + self.mode = ChainSyncMode::Full; } + self.import_existing = false; self.best_queued_hash = info.best_hash; self.best_queued_number = info.best_number; - if self.mode == SyncMode::Full && + if self.mode == ChainSyncMode::Full && self.client.block_status(info.best_hash)? != BlockStatus::InChainWithState { self.import_existing = true; @@ -1450,44 +1438,6 @@ where .collect() } - /// Set the warp sync target block externally in case we skip warp proofs downloading. - pub fn set_warp_sync_target_block(&mut self, header: B::Header) { - if let Some(ref mut warp_sync) = self.warp_sync { - warp_sync.set_target_block(header); - } else { - self.warp_sync_target_block_header = Some(header); - } - } - - /// Generate block request for downloading of the target block body during warp sync. - fn warp_target_block_request(&mut self) -> Option<(PeerId, BlockRequest)> { - let sync = &self.warp_sync.as_ref()?; - - if self.allowed_requests.is_empty() || - sync.is_complete() || - self.peers - .iter() - .any(|(_, peer)| peer.state == PeerSyncState::DownloadingWarpTargetBlock) - { - // Only one pending warp target block request is allowed. - return None - } - - if let Some((target_number, request)) = sync.next_target_block_request() { - // Find a random peer that has a block with the target number. - for (id, peer) in self.peers.iter_mut() { - if peer.state.is_available() && peer.best_number >= target_number { - trace!(target: LOG_TARGET, "New warp target block request for {id}"); - peer.state = PeerSyncState::DownloadingWarpTargetBlock; - self.allowed_requests.clear(); - return Some((*id, request)) - } - } - } - - None - } - /// Submit blocks received in a response. pub fn on_block_response( &mut self, @@ -1564,12 +1514,6 @@ where /// Get block requests scheduled by sync to be sent out. fn block_requests(&mut self) -> Vec<(PeerId, BlockRequest)> { - if self.mode == SyncMode::Warp { - return self - .warp_target_block_request() - .map_or_else(|| Vec::new(), |req| Vec::from([req])) - } - if self.allowed_requests.is_empty() || self.state_sync.is_some() { return Vec::new() } @@ -1694,7 +1638,7 @@ where if self.allowed_requests.is_empty() { return None } - if (self.state_sync.is_some() || self.warp_sync.is_some()) && + if self.state_sync.is_some() && self.peers.iter().any(|(_, peer)| peer.state == PeerSyncState::DownloadingState) { // Only one pending state request is allowed. @@ -1706,7 +1650,7 @@ where } for (id, peer) in self.peers.iter_mut() { - if peer.state.is_available() && peer.common_number >= sync.target_block_num() { + if peer.state.is_available() && peer.common_number >= sync.target_number() { peer.state = PeerSyncState::DownloadingState; let request = sync.next_request(); trace!(target: LOG_TARGET, "New StateRequest for {}: {:?}", id, request); @@ -1715,55 +1659,6 @@ where } } } - if let Some(sync) = &self.warp_sync { - if sync.is_complete() { - return None - } - if let (Some(request), Some(target)) = - (sync.next_state_request(), sync.target_block_number()) - { - for (id, peer) in self.peers.iter_mut() { - if peer.state.is_available() && peer.best_number >= target { - trace!(target: LOG_TARGET, "New StateRequest for {id}: {request:?}"); - peer.state = PeerSyncState::DownloadingState; - self.allowed_requests.clear(); - return Some((*id, OpaqueStateRequest(Box::new(request)))) - } - } - } - } - None - } - - /// Get a warp proof request scheduled by sync to be sent out (if any). - fn warp_sync_request(&mut self) -> Option<(PeerId, WarpProofRequest)> { - if let Some(sync) = &self.warp_sync { - if self.allowed_requests.is_empty() || - sync.is_complete() || - self.peers - .iter() - .any(|(_, peer)| peer.state == PeerSyncState::DownloadingWarpProof) - { - // Only one pending state request is allowed. - return None - } - if let Some(request) = sync.next_warp_proof_request() { - let mut targets: Vec<_> = self.peers.values().map(|p| p.best_number).collect(); - if !targets.is_empty() { - targets.sort(); - let median = targets[targets.len() / 2]; - // Find a random peer that is synced as much as peer majority. - for (id, peer) in self.peers.iter_mut() { - if peer.state.is_available() && peer.best_number >= median { - trace!(target: LOG_TARGET, "New WarpProofRequest for {id}"); - peer.state = PeerSyncState::DownloadingWarpProof; - self.allowed_requests.clear(); - return Some((*id, request)) - } - } - } - } - } None } @@ -1797,15 +1692,6 @@ where response.proof.len(), ); sync.import(*response) - } else if let Some(sync) = &mut self.warp_sync { - debug!( - target: LOG_TARGET, - "Importing state data from {} with {} keys, {} proof nodes.", - peer_id, - response.entries.len(), - response.proof.len(), - ); - sync.import_state(*response) } else { debug!(target: LOG_TARGET, "Ignored obsolete state response from {peer_id}"); return Err(BadPeer(*peer_id, rep::NOT_REQUESTED)) @@ -1838,43 +1724,10 @@ where } } - /// Submit a warp proof response received. - pub fn on_warp_sync_response(&mut self, peer_id: &PeerId, response: EncodedProof) { - if let Some(peer) = self.peers.get_mut(peer_id) { - if let PeerSyncState::DownloadingWarpProof = peer.state { - peer.state = PeerSyncState::Available; - self.allowed_requests.set_all(); - } - } - let import_result = if let Some(sync) = &mut self.warp_sync { - debug!( - target: LOG_TARGET, - "Importing warp proof data from {}, {} bytes.", - peer_id, - response.0.len(), - ); - sync.import_warp_proof(response) - } else { - debug!(target: LOG_TARGET, "Ignored obsolete warp sync response from {peer_id}"); - self.actions - .push(ChainSyncAction::DropPeer(BadPeer(*peer_id, rep::NOT_REQUESTED))); - return - }; - - match import_result { - WarpProofImportResult::Success => {}, - WarpProofImportResult::BadResponse => { - debug!(target: LOG_TARGET, "Bad proof data received from {peer_id}"); - self.actions.push(ChainSyncAction::DropPeer(BadPeer(*peer_id, rep::BAD_BLOCK))); - }, - } - } - /// A batch of blocks have been processed, with or without errors. /// /// Call this when a batch of blocks have been processed by the import - /// queue, with or without errors. If an error is returned, the pending response - /// from the peer must be dropped. + /// queue, with or without errors. pub fn on_blocks_processed( &mut self, imported: usize, @@ -1934,7 +1787,7 @@ where self.update_peer_common_number(&peer, number); } let state_sync_complete = - self.state_sync.as_ref().map_or(false, |s| s.target() == hash); + self.state_sync.as_ref().map_or(false, |s| s.target_hash() == hash); if state_sync_complete { info!( target: LOG_TARGET, @@ -1942,21 +1795,7 @@ where self.state_sync.as_ref().map_or(0, |s| s.progress().size / (1024 * 1024)), ); self.state_sync = None; - self.mode = SyncMode::Full; - self.restart(); - } - let warp_sync_complete = self - .warp_sync - .as_ref() - .map_or(false, |s| s.target_block_hash() == Some(hash)); - if warp_sync_complete { - info!( - target: LOG_TARGET, - "Warp sync is complete ({} MiB), restarting block sync.", - self.warp_sync.as_ref().map_or(0, |s| s.progress().total_bytes / (1024 * 1024)), - ); - self.warp_sync = None; - self.mode = SyncMode::Full; + self.mode = ChainSyncMode::Full; self.restart(); } let gap_sync_complete = @@ -2012,7 +1851,6 @@ where e @ Err(BlockImportError::UnknownParent) | e @ Err(BlockImportError::Other(_)) => { warn!(target: LOG_TARGET, "💔 Error importing block {hash:?}: {}", e.unwrap_err()); self.state_sync = None; - self.warp_sync = None; self.restart(); }, Err(BlockImportError::Cancelled) => {}, @@ -2043,12 +1881,6 @@ where .map(|(peer_id, request)| ChainSyncAction::SendStateRequest { peer_id, request }); self.actions.extend(state_request); - let warp_proof_request = self - .warp_sync_request() - .into_iter() - .map(|(peer_id, request)| ChainSyncAction::SendWarpProofRequest { peer_id, request }); - self.actions.extend(warp_proof_request); - std::mem::take(&mut self.actions).into_iter() } @@ -2324,7 +2156,7 @@ where /// Returns the number of the first block in the sequence. /// /// It is expected that `blocks` are in ascending order. -fn validate_blocks( +pub fn validate_blocks( blocks: &Vec>, peer_id: &PeerId, request: Option>, @@ -2389,7 +2221,7 @@ fn validate_blocks( let hash = header.hash(); if hash != b.hash { debug!( - target:LOG_TARGET, + target: LOG_TARGET, "Bad header received from {}. Expected hash {:?}, got {:?}", peer_id, b.hash, @@ -2406,7 +2238,7 @@ fn validate_blocks( ); if expected != got { debug!( - target:LOG_TARGET, + target: LOG_TARGET, "Bad extrinsic root for a block {} received from {}. Expected {:?}, got {:?}", b.hash, peer_id, diff --git a/substrate/client/network/sync/src/chain_sync/test.rs b/substrate/client/network/sync/src/strategy/chain_sync/test.rs similarity index 94% rename from substrate/client/network/sync/src/chain_sync/test.rs rename to substrate/client/network/sync/src/strategy/chain_sync/test.rs index 15b2a95a07c..c89096bc6c9 100644 --- a/substrate/client/network/sync/src/chain_sync/test.rs +++ b/substrate/client/network/sync/src/strategy/chain_sync/test.rs @@ -38,7 +38,7 @@ fn processes_empty_response_on_justification_request_for_unknown_block() { let client = Arc::new(TestClientBuilder::new().build()); let peer_id = PeerId::random(); - let mut sync = ChainSync::new(SyncMode::Full, client.clone(), 1, 64, None).unwrap(); + let mut sync = ChainSync::new(ChainSyncMode::Full, client.clone(), 1, 64, None).unwrap(); let (a1_hash, a1_number) = { let a1 = BlockBuilderBuilder::new(&*client) @@ -53,7 +53,7 @@ fn processes_empty_response_on_justification_request_for_unknown_block() { }; // add a new peer with the same best block - sync.new_peer(peer_id, a1_hash, a1_number); + sync.add_peer(peer_id, a1_hash, a1_number); // and request a justification for the block sync.request_justification(&a1_hash, a1_number); @@ -91,7 +91,7 @@ fn processes_empty_response_on_justification_request_for_unknown_block() { fn restart_doesnt_affect_peers_downloading_finality_data() { let mut client = Arc::new(TestClientBuilder::new().build()); - let mut sync = ChainSync::new(SyncMode::Full, client.clone(), 1, 64, None).unwrap(); + let mut sync = ChainSync::new(ChainSyncMode::Full, client.clone(), 1, 64, None).unwrap(); let peer_id1 = PeerId::random(); let peer_id2 = PeerId::random(); @@ -117,8 +117,8 @@ fn restart_doesnt_affect_peers_downloading_finality_data() { let (b1_hash, b1_number) = new_blocks(50); // add 2 peers at blocks that we don't have locally - sync.new_peer(peer_id1, Hash::random(), 42); - sync.new_peer(peer_id2, Hash::random(), 10); + sync.add_peer(peer_id1, Hash::random(), 42); + sync.add_peer(peer_id2, Hash::random(), 10); // we wil send block requests to these peers // for these blocks we don't know about @@ -128,7 +128,7 @@ fn restart_doesnt_affect_peers_downloading_finality_data() { .all(|(p, _)| { p == peer_id1 || p == peer_id2 })); // add a new peer at a known block - sync.new_peer(peer_id3, b1_hash, b1_number); + sync.add_peer(peer_id3, b1_hash, b1_number); // we request a justification for a block we have locally sync.request_justification(&b1_hash, b1_number); @@ -181,7 +181,7 @@ fn send_block_announce(header: Header, peer_id: PeerId, sync: &mut ChainSync>(); - let mut sync = ChainSync::new(SyncMode::Full, client.clone(), 1, 64, None).unwrap(); + let mut sync = ChainSync::new(ChainSyncMode::Full, client.clone(), 1, 64, None).unwrap(); let peer_id1 = PeerId::random(); let common_block = blocks[1].clone(); // Connect the node we will sync from - sync.new_peer(peer_id1, common_block.hash(), *common_block.header().number()); + sync.add_peer(peer_id1, common_block.hash(), *common_block.header().number()); // Create a "new" header and announce it let mut header = blocks[0].header().clone(); @@ -702,7 +702,7 @@ fn removes_target_fork_on_disconnect() { send_block_announce(header, peer_id1, &mut sync); assert!(sync.fork_targets.len() == 1); - let _ = sync.peer_disconnected(&peer_id1); + let _ = sync.remove_peer(&peer_id1); assert!(sync.fork_targets.len() == 0); } @@ -714,11 +714,11 @@ fn can_import_response_with_missing_blocks() { let empty_client = Arc::new(TestClientBuilder::new().build()); - let mut sync = ChainSync::new(SyncMode::Full, empty_client.clone(), 1, 64, None).unwrap(); + let mut sync = ChainSync::new(ChainSyncMode::Full, empty_client.clone(), 1, 64, None).unwrap(); let peer_id1 = PeerId::random(); let best_block = blocks[3].clone(); - sync.new_peer(peer_id1, best_block.hash(), *best_block.header().number()); + sync.add_peer(peer_id1, best_block.hash(), *best_block.header().number()); sync.peers.get_mut(&peer_id1).unwrap().state = PeerSyncState::Available; sync.peers.get_mut(&peer_id1).unwrap().common_number = 0; @@ -745,7 +745,7 @@ fn ancestor_search_repeat() { #[test] fn sync_restart_removes_block_but_not_justification_requests() { let mut client = Arc::new(TestClientBuilder::new().build()); - let mut sync = ChainSync::new(SyncMode::Full, client.clone(), 1, 64, None).unwrap(); + let mut sync = ChainSync::new(ChainSyncMode::Full, client.clone(), 1, 64, None).unwrap(); let peers = vec![PeerId::random(), PeerId::random()]; @@ -769,7 +769,7 @@ fn sync_restart_removes_block_but_not_justification_requests() { let (b1_hash, b1_number) = new_blocks(50); // add new peer and request blocks from them - sync.new_peer(peers[0], Hash::random(), 42); + sync.add_peer(peers[0], Hash::random(), 42); // we don't actually perform any requests, just keep track of peers waiting for a response let mut pending_responses = HashSet::new(); @@ -782,7 +782,7 @@ fn sync_restart_removes_block_but_not_justification_requests() { } // add a new peer at a known block - sync.new_peer(peers[1], b1_hash, b1_number); + sync.add_peer(peers[1], b1_hash, b1_number); // we request a justification for a block we have locally sync.request_justification(&b1_hash, b1_number); @@ -837,7 +837,7 @@ fn sync_restart_removes_block_but_not_justification_requests() { sync.peers.get(&peers[1]).unwrap().state, PeerSyncState::DownloadingJustification(b1_hash), ); - let _ = sync.peer_disconnected(&peers[1]); + let _ = sync.remove_peer(&peers[1]); pending_responses.remove(&peers[1]); assert_eq!(pending_responses.len(), 0); } @@ -887,14 +887,14 @@ fn request_across_forks() { fork_blocks }; - let mut sync = ChainSync::new(SyncMode::Full, client.clone(), 5, 64, None).unwrap(); + let mut sync = ChainSync::new(ChainSyncMode::Full, client.clone(), 5, 64, None).unwrap(); // Add the peers, all at the common ancestor 100. let common_block = blocks.last().unwrap(); let peer_id1 = PeerId::random(); - sync.new_peer(peer_id1, common_block.hash(), *common_block.header().number()); + sync.add_peer(peer_id1, common_block.hash(), *common_block.header().number()); let peer_id2 = PeerId::random(); - sync.new_peer(peer_id2, common_block.hash(), *common_block.header().number()); + sync.add_peer(peer_id2, common_block.hash(), *common_block.header().number()); // Peer 1 announces 107 from fork 1, 100-107 get downloaded. { diff --git a/substrate/client/network/sync/src/strategy/state.rs b/substrate/client/network/sync/src/strategy/state.rs new file mode 100644 index 00000000000..ae3f7b60055 --- /dev/null +++ b/substrate/client/network/sync/src/strategy/state.rs @@ -0,0 +1,754 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! State sync strategy. + +use crate::{ + schema::v1::StateResponse, + strategy::state_sync::{ImportResult, StateSync, StateSyncProvider}, + types::{BadPeer, OpaqueStateRequest, OpaqueStateResponse, SyncState, SyncStatus}, + LOG_TARGET, +}; +use libp2p::PeerId; +use log::{debug, error, trace}; +use sc_client_api::ProofProvider; +use sc_consensus::{BlockImportError, BlockImportStatus, IncomingBlock}; +use sc_network_common::sync::message::BlockAnnounce; +use sp_consensus::BlockOrigin; +use sp_runtime::{ + traits::{Block as BlockT, Header, NumberFor}, + Justifications, SaturatedConversion, +}; +use std::{collections::HashMap, sync::Arc}; + +mod rep { + use sc_network::ReputationChange as Rep; + + /// Peer response data does not have requested bits. + pub const BAD_RESPONSE: Rep = Rep::new(-(1 << 12), "Incomplete response"); + + /// Reputation change for peers which send us a known bad state. + pub const BAD_STATE: Rep = Rep::new(-(1 << 29), "Bad state"); +} + +/// Action that should be performed on [`StateStrategy`]'s behalf. +pub enum StateStrategyAction { + /// Send state request to peer. + SendStateRequest { peer_id: PeerId, request: OpaqueStateRequest }, + /// Disconnect and report peer. + DropPeer(BadPeer), + /// Import blocks. + ImportBlocks { origin: BlockOrigin, blocks: Vec> }, + /// State sync has finished. + Finished, +} + +enum PeerState { + Available, + DownloadingState, +} + +impl PeerState { + fn is_available(&self) -> bool { + matches!(self, PeerState::Available) + } +} + +struct Peer { + best_number: NumberFor, + state: PeerState, +} + +/// Syncing strategy that downloads and imports a recent state directly. +pub struct StateStrategy { + state_sync: Box>, + peers: HashMap>, + actions: Vec>, + succeded: bool, +} + +impl StateStrategy { + /// Create a new instance. + pub fn new( + client: Arc, + target_header: B::Header, + target_body: Option>, + target_justifications: Option, + skip_proof: bool, + initial_peers: impl Iterator)>, + ) -> Self + where + Client: ProofProvider + Send + Sync + 'static, + { + let peers = initial_peers + .map(|(peer_id, best_number)| { + (peer_id, Peer { best_number, state: PeerState::Available }) + }) + .collect(); + Self { + state_sync: Box::new(StateSync::new( + client, + target_header, + target_body, + target_justifications, + skip_proof, + )), + peers, + actions: Vec::new(), + succeded: false, + } + } + + // Create a new instance with a custom state sync provider. + // Used in tests. + #[cfg(test)] + fn new_with_provider( + state_sync_provider: Box>, + initial_peers: impl Iterator)>, + ) -> Self { + Self { + state_sync: state_sync_provider, + peers: initial_peers + .map(|(peer_id, best_number)| { + (peer_id, Peer { best_number, state: PeerState::Available }) + }) + .collect(), + actions: Vec::new(), + succeded: false, + } + } + + /// Notify that a new peer has connected. + pub fn add_peer(&mut self, peer_id: PeerId, _best_hash: B::Hash, best_number: NumberFor) { + self.peers.insert(peer_id, Peer { best_number, state: PeerState::Available }); + } + + /// Notify that a peer has disconnected. + pub fn remove_peer(&mut self, peer_id: &PeerId) { + self.peers.remove(peer_id); + } + + /// Submit a validated block announcement. + /// + /// Returns new best hash & best number of the peer if they are updated. + #[must_use] + pub fn on_validated_block_announce( + &mut self, + is_best: bool, + peer_id: PeerId, + announce: &BlockAnnounce, + ) -> Option<(B::Hash, NumberFor)> { + is_best.then_some({ + let best_number = *announce.header.number(); + let best_hash = announce.header.hash(); + if let Some(ref mut peer) = self.peers.get_mut(&peer_id) { + peer.best_number = best_number; + } + // Let `SyncingEngine` know that we should update the peer info. + (best_hash, best_number) + }) + } + + /// Process state response. + pub fn on_state_response(&mut self, peer_id: PeerId, response: OpaqueStateResponse) { + if let Err(bad_peer) = self.on_state_response_inner(peer_id, response) { + self.actions.push(StateStrategyAction::DropPeer(bad_peer)); + } + } + + fn on_state_response_inner( + &mut self, + peer_id: PeerId, + response: OpaqueStateResponse, + ) -> Result<(), BadPeer> { + if let Some(peer) = self.peers.get_mut(&peer_id) { + peer.state = PeerState::Available; + } + + let response: Box = response.0.downcast().map_err(|_error| { + error!( + target: LOG_TARGET, + "Failed to downcast opaque state response, this is an implementation bug." + ); + debug_assert!(false); + + BadPeer(peer_id, rep::BAD_RESPONSE) + })?; + + debug!( + target: LOG_TARGET, + "Importing state data from {} with {} keys, {} proof nodes.", + peer_id, + response.entries.len(), + response.proof.len(), + ); + + match self.state_sync.import(*response) { + ImportResult::Import(hash, header, state, body, justifications) => { + let origin = BlockOrigin::NetworkInitialSync; + let block = IncomingBlock { + hash, + header: Some(header), + body, + indexed_body: None, + justifications, + origin: None, + allow_missing_state: true, + import_existing: true, + skip_execution: true, + state: Some(state), + }; + debug!(target: LOG_TARGET, "State download is complete. Import is queued"); + self.actions + .push(StateStrategyAction::ImportBlocks { origin, blocks: vec![block] }); + Ok(()) + }, + ImportResult::Continue => Ok(()), + ImportResult::BadResponse => { + debug!(target: LOG_TARGET, "Bad state data received from {peer_id}"); + Err(BadPeer(peer_id, rep::BAD_STATE)) + }, + } + } + + /// A batch of blocks have been processed, with or without errors. + /// + /// Normally this should be called when target block with state is imported. + pub fn on_blocks_processed( + &mut self, + imported: usize, + count: usize, + results: Vec<(Result>, BlockImportError>, B::Hash)>, + ) { + trace!(target: LOG_TARGET, "State sync: imported {imported} of {count}."); + + let results = results + .into_iter() + .filter_map(|(result, hash)| { + if hash == self.state_sync.target_hash() { + Some(result) + } else { + debug!( + target: LOG_TARGET, + "Unexpected block processed: {hash} with result {result:?}.", + ); + None + } + }) + .collect::>(); + + if !results.is_empty() { + // We processed the target block + results.iter().filter_map(|result| result.as_ref().err()).for_each(|e| { + error!( + target: LOG_TARGET, + "Failed to import target block with state: {e:?}." + ); + }); + self.succeded |= results.into_iter().any(|result| result.is_ok()); + self.actions.push(StateStrategyAction::Finished); + } + } + + /// Produce state request. + fn state_request(&mut self) -> Option<(PeerId, OpaqueStateRequest)> { + if self.state_sync.is_complete() { + return None + } + + if self + .peers + .values() + .any(|peer| matches!(peer.state, PeerState::DownloadingState)) + { + // Only one state request at a time is possible. + return None + } + + let peer_id = + self.schedule_next_peer(PeerState::DownloadingState, self.state_sync.target_number())?; + let request = self.state_sync.next_request(); + trace!( + target: LOG_TARGET, + "New state request to {peer_id}: {request:?}.", + ); + Some((peer_id, OpaqueStateRequest(Box::new(request)))) + } + + fn schedule_next_peer( + &mut self, + new_state: PeerState, + min_best_number: NumberFor, + ) -> Option { + let mut targets: Vec<_> = self.peers.values().map(|p| p.best_number).collect(); + if targets.is_empty() { + return None + } + targets.sort(); + let median = targets[targets.len() / 2]; + let threshold = std::cmp::max(median, min_best_number); + // Find a random peer that is synced as much as peer majority and is above + // `min_best_number`. + for (peer_id, peer) in self.peers.iter_mut() { + if peer.state.is_available() && peer.best_number >= threshold { + peer.state = new_state; + return Some(*peer_id) + } + } + None + } + + /// Returns the current sync status. + pub fn status(&self) -> SyncStatus { + SyncStatus { + state: if self.state_sync.is_complete() { + SyncState::Idle + } else { + SyncState::Downloading { target: self.state_sync.target_number() } + }, + best_seen_block: Some(self.state_sync.target_number()), + num_peers: self.peers.len().saturated_into(), + num_connected_peers: self.peers.len().saturated_into(), + queued_blocks: 0, + state_sync: Some(self.state_sync.progress()), + warp_sync: None, + } + } + + /// Get the number of peers known to syncing. + pub fn num_peers(&self) -> usize { + self.peers.len() + } + + /// Get actions that should be performed by the owner on [`WarpSync`]'s behalf + #[must_use] + pub fn actions(&mut self) -> impl Iterator> { + let state_request = self + .state_request() + .into_iter() + .map(|(peer_id, request)| StateStrategyAction::SendStateRequest { peer_id, request }); + self.actions.extend(state_request); + + std::mem::take(&mut self.actions).into_iter() + } + + /// Check if state sync has succeded. + #[must_use] + pub fn is_succeded(&self) -> bool { + self.succeded + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::{ + schema::v1::{StateRequest, StateResponse}, + strategy::state_sync::{ImportResult, StateSyncProgress, StateSyncProvider}, + }; + use codec::Decode; + use sc_block_builder::BlockBuilderBuilder; + use sc_client_api::KeyValueStates; + use sc_consensus::{ImportedAux, ImportedState}; + use sp_runtime::traits::Zero; + use substrate_test_runtime_client::{ + runtime::{Block, Hash}, + BlockBuilderExt, DefaultTestClientBuilderExt, TestClientBuilder, TestClientBuilderExt, + }; + + mockall::mock! { + pub StateSync {} + + impl StateSyncProvider for StateSync { + fn import(&mut self, response: StateResponse) -> ImportResult; + fn next_request(&self) -> StateRequest; + fn is_complete(&self) -> bool; + fn target_number(&self) -> NumberFor; + fn target_hash(&self) -> B::Hash; + fn progress(&self) -> StateSyncProgress; + } + } + + #[test] + fn no_peer_is_scheduled_if_no_peers_connected() { + let client = Arc::new(TestClientBuilder::new().set_no_genesis().build()); + let target_block = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().best_hash) + .with_parent_block_number(client.chain_info().best_number) + .build() + .unwrap() + .build() + .unwrap() + .block; + let target_header = target_block.header().clone(); + + let mut state_strategy = + StateStrategy::new(client, target_header, None, None, false, std::iter::empty()); + + assert!(state_strategy + .schedule_next_peer(PeerState::DownloadingState, Zero::zero()) + .is_none()); + } + + #[test] + fn at_least_median_synced_peer_is_scheduled() { + let client = Arc::new(TestClientBuilder::new().set_no_genesis().build()); + let target_block = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().best_hash) + .with_parent_block_number(client.chain_info().best_number) + .build() + .unwrap() + .build() + .unwrap() + .block; + + for _ in 0..100 { + let peers = (1..=10) + .map(|best_number| (PeerId::random(), best_number)) + .collect::>(); + let initial_peers = peers.iter().map(|(p, n)| (*p, *n)); + + let mut state_strategy = StateStrategy::new( + client.clone(), + target_block.header().clone(), + None, + None, + false, + initial_peers, + ); + + let peer_id = + state_strategy.schedule_next_peer(PeerState::DownloadingState, Zero::zero()); + assert!(*peers.get(&peer_id.unwrap()).unwrap() >= 6); + } + } + + #[test] + fn min_best_number_peer_is_scheduled() { + let client = Arc::new(TestClientBuilder::new().set_no_genesis().build()); + let target_block = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().best_hash) + .with_parent_block_number(client.chain_info().best_number) + .build() + .unwrap() + .build() + .unwrap() + .block; + + for _ in 0..10 { + let peers = (1..=10) + .map(|best_number| (PeerId::random(), best_number)) + .collect::>(); + let initial_peers = peers.iter().map(|(p, n)| (*p, *n)); + + let mut state_strategy = StateStrategy::new( + client.clone(), + target_block.header().clone(), + None, + None, + false, + initial_peers, + ); + + let peer_id = state_strategy.schedule_next_peer(PeerState::DownloadingState, 10); + assert!(*peers.get(&peer_id.unwrap()).unwrap() == 10); + } + } + + #[test] + fn state_request_contains_correct_hash() { + let client = Arc::new(TestClientBuilder::new().set_no_genesis().build()); + let target_block = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().best_hash) + .with_parent_block_number(client.chain_info().best_number) + .build() + .unwrap() + .build() + .unwrap() + .block; + + let initial_peers = (1..=10).map(|best_number| (PeerId::random(), best_number)); + + let mut state_strategy = StateStrategy::new( + client.clone(), + target_block.header().clone(), + None, + None, + false, + initial_peers, + ); + + let (_peer_id, mut opaque_request) = state_strategy.state_request().unwrap(); + let request: &mut StateRequest = opaque_request.0.downcast_mut().unwrap(); + let hash = Hash::decode(&mut &*request.block).unwrap(); + + assert_eq!(hash, target_block.header().hash()); + } + + #[test] + fn no_parallel_state_requests() { + let client = Arc::new(TestClientBuilder::new().set_no_genesis().build()); + let target_block = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().best_hash) + .with_parent_block_number(client.chain_info().best_number) + .build() + .unwrap() + .build() + .unwrap() + .block; + + let initial_peers = (1..=10).map(|best_number| (PeerId::random(), best_number)); + + let mut state_strategy = StateStrategy::new( + client.clone(), + target_block.header().clone(), + None, + None, + false, + initial_peers, + ); + + // First request is sent. + assert!(state_strategy.state_request().is_some()); + + // No parallel request is sent. + assert!(state_strategy.state_request().is_none()); + } + + #[test] + fn received_state_response_makes_peer_available_again() { + let mut state_sync_provider = MockStateSync::::new(); + state_sync_provider.expect_import().return_once(|_| ImportResult::Continue); + let peer_id = PeerId::random(); + let initial_peers = std::iter::once((peer_id, 10)); + let mut state_strategy = + StateStrategy::new_with_provider(Box::new(state_sync_provider), initial_peers); + // Manually set the peer's state. + state_strategy.peers.get_mut(&peer_id).unwrap().state = PeerState::DownloadingState; + + let dummy_response = OpaqueStateResponse(Box::new(StateResponse::default())); + state_strategy.on_state_response(peer_id, dummy_response); + + assert!(state_strategy.peers.get(&peer_id).unwrap().state.is_available()); + } + + #[test] + fn bad_state_response_drops_peer() { + let mut state_sync_provider = MockStateSync::::new(); + // Provider says that state response is bad. + state_sync_provider.expect_import().return_once(|_| ImportResult::BadResponse); + let peer_id = PeerId::random(); + let initial_peers = std::iter::once((peer_id, 10)); + let mut state_strategy = + StateStrategy::new_with_provider(Box::new(state_sync_provider), initial_peers); + // Manually set the peer's state. + state_strategy.peers.get_mut(&peer_id).unwrap().state = PeerState::DownloadingState; + let dummy_response = OpaqueStateResponse(Box::new(StateResponse::default())); + // Receiving response drops the peer. + assert!(matches!( + state_strategy.on_state_response_inner(peer_id, dummy_response), + Err(BadPeer(id, _rep)) if id == peer_id, + )); + } + + #[test] + fn partial_state_response_doesnt_generate_actions() { + let mut state_sync_provider = MockStateSync::::new(); + // Sync provider says that the response is partial. + state_sync_provider.expect_import().return_once(|_| ImportResult::Continue); + let peer_id = PeerId::random(); + let initial_peers = std::iter::once((peer_id, 10)); + let mut state_strategy = + StateStrategy::new_with_provider(Box::new(state_sync_provider), initial_peers); + // Manually set the peer's state . + state_strategy.peers.get_mut(&peer_id).unwrap().state = PeerState::DownloadingState; + + let dummy_response = OpaqueStateResponse(Box::new(StateResponse::default())); + state_strategy.on_state_response(peer_id, dummy_response); + + // No actions generated. + assert_eq!(state_strategy.actions.len(), 0) + } + + #[test] + fn complete_state_response_leads_to_block_import() { + // Build block to use for checks. + let client = Arc::new(TestClientBuilder::new().set_no_genesis().build()); + let mut block_builder = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().best_hash) + .with_parent_block_number(client.chain_info().best_number) + .build() + .unwrap(); + block_builder.push_storage_change(vec![1, 2, 3], Some(vec![4, 5, 6])).unwrap(); + let block = block_builder.build().unwrap().block; + let header = block.header().clone(); + let hash = header.hash(); + let body = Some(block.extrinsics().iter().cloned().collect::>()); + let state = ImportedState { block: hash, state: KeyValueStates(Vec::new()) }; + let justifications = Some(Justifications::from((*b"FRNK", Vec::new()))); + + // Prepare `StateSync` + let mut state_sync_provider = MockStateSync::::new(); + let import = ImportResult::Import( + hash, + header.clone(), + state.clone(), + body.clone(), + justifications.clone(), + ); + state_sync_provider.expect_import().return_once(move |_| import); + + // Reference values to check against. + let expected_origin = BlockOrigin::NetworkInitialSync; + let expected_block = IncomingBlock { + hash, + header: Some(header), + body, + indexed_body: None, + justifications, + origin: None, + allow_missing_state: true, + import_existing: true, + skip_execution: true, + state: Some(state), + }; + let expected_blocks = vec![expected_block]; + + // Prepare `StateStrategy`. + let peer_id = PeerId::random(); + let initial_peers = std::iter::once((peer_id, 10)); + let mut state_strategy = + StateStrategy::new_with_provider(Box::new(state_sync_provider), initial_peers); + // Manually set the peer's state . + state_strategy.peers.get_mut(&peer_id).unwrap().state = PeerState::DownloadingState; + + // Receive response. + let dummy_response = OpaqueStateResponse(Box::new(StateResponse::default())); + state_strategy.on_state_response(peer_id, dummy_response); + + assert_eq!(state_strategy.actions.len(), 1); + assert!(matches!( + &state_strategy.actions[0], + StateStrategyAction::ImportBlocks { origin, blocks } + if *origin == expected_origin && *blocks == expected_blocks, + )); + } + + #[test] + fn importing_unknown_block_doesnt_finish_strategy() { + let target_hash = Hash::random(); + let unknown_hash = Hash::random(); + let mut state_sync_provider = MockStateSync::::new(); + state_sync_provider.expect_target_hash().return_const(target_hash); + + let mut state_strategy = + StateStrategy::new_with_provider(Box::new(state_sync_provider), std::iter::empty()); + + // Unknown block imported. + state_strategy.on_blocks_processed( + 1, + 1, + vec![( + Ok(BlockImportStatus::ImportedUnknown(1, ImportedAux::default(), None)), + unknown_hash, + )], + ); + + // No actions generated. + assert_eq!(state_strategy.actions.len(), 0); + } + + #[test] + fn succesfully_importing_target_block_finishes_strategy() { + let target_hash = Hash::random(); + let mut state_sync_provider = MockStateSync::::new(); + state_sync_provider.expect_target_hash().return_const(target_hash); + + let mut state_strategy = + StateStrategy::new_with_provider(Box::new(state_sync_provider), std::iter::empty()); + + // Target block imported. + state_strategy.on_blocks_processed( + 1, + 1, + vec![( + Ok(BlockImportStatus::ImportedUnknown(1, ImportedAux::default(), None)), + target_hash, + )], + ); + + // Strategy finishes. + assert_eq!(state_strategy.actions.len(), 1); + assert!(matches!(&state_strategy.actions[0], StateStrategyAction::Finished)); + } + + #[test] + fn failure_to_import_target_block_finishes_strategy() { + let target_hash = Hash::random(); + let mut state_sync_provider = MockStateSync::::new(); + state_sync_provider.expect_target_hash().return_const(target_hash); + + let mut state_strategy = + StateStrategy::new_with_provider(Box::new(state_sync_provider), std::iter::empty()); + + // Target block import failed. + state_strategy.on_blocks_processed( + 1, + 1, + vec![( + Err(BlockImportError::VerificationFailed(None, String::from("test-error"))), + target_hash, + )], + ); + + // Strategy finishes. + assert_eq!(state_strategy.actions.len(), 1); + assert!(matches!(&state_strategy.actions[0], StateStrategyAction::Finished)); + } + + #[test] + fn finished_strategy_doesnt_generate_more_actions() { + let target_hash = Hash::random(); + let mut state_sync_provider = MockStateSync::::new(); + state_sync_provider.expect_target_hash().return_const(target_hash); + state_sync_provider.expect_is_complete().return_const(true); + + // Get enough peers for possible spurious requests. + let initial_peers = (1..=10).map(|best_number| (PeerId::random(), best_number)); + + let mut state_strategy = + StateStrategy::new_with_provider(Box::new(state_sync_provider), initial_peers); + + state_strategy.on_blocks_processed( + 1, + 1, + vec![( + Ok(BlockImportStatus::ImportedUnknown(1, ImportedAux::default(), None)), + target_hash, + )], + ); + + // Strategy finishes. + let actions = state_strategy.actions().collect::>(); + assert_eq!(actions.len(), 1); + assert!(matches!(&actions[0], StateStrategyAction::Finished)); + + // No more actions generated. + assert_eq!(state_strategy.actions().count(), 0); + } +} diff --git a/substrate/client/network/sync/src/state.rs b/substrate/client/network/sync/src/strategy/state_sync.rs similarity index 74% rename from substrate/client/network/sync/src/state.rs rename to substrate/client/network/sync/src/strategy/state_sync.rs index 5d34613d1c5..1ed1de7c8ef 100644 --- a/substrate/client/network/sync/src/state.rs +++ b/substrate/client/network/sync/src/strategy/state_sync.rs @@ -20,7 +20,7 @@ use crate::{ schema::v1::{StateEntry, StateRequest, StateResponse}, - types::StateDownloadProgress, + LOG_TARGET, }; use codec::{Decode, Encode}; use log::debug; @@ -32,7 +32,62 @@ use sp_runtime::{ traits::{Block as BlockT, Header, NumberFor}, Justifications, }; -use std::{collections::HashMap, sync::Arc}; +use std::{collections::HashMap, fmt, sync::Arc}; + +/// Generic state sync provider. Used for mocking in tests. +pub trait StateSyncProvider: Send + Sync { + /// Validate and import a state response. + fn import(&mut self, response: StateResponse) -> ImportResult; + /// Produce next state request. + fn next_request(&self) -> StateRequest; + /// Check if the state is complete. + fn is_complete(&self) -> bool; + /// Returns target block number. + fn target_number(&self) -> NumberFor; + /// Returns target block hash. + fn target_hash(&self) -> B::Hash; + /// Returns state sync estimated progress. + fn progress(&self) -> StateSyncProgress; +} + +// Reported state sync phase. +#[derive(Clone, Eq, PartialEq, Debug)] +pub enum StateSyncPhase { + // State download in progress. + DownloadingState, + // Download is complete, state is being imported. + ImportingState, +} + +impl fmt::Display for StateSyncPhase { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::DownloadingState => write!(f, "Downloading state"), + Self::ImportingState => write!(f, "Importing state"), + } + } +} + +/// Reported state download progress. +#[derive(Clone, Eq, PartialEq, Debug)] +pub struct StateSyncProgress { + /// Estimated download percentage. + pub percentage: u32, + /// Total state size in bytes downloaded so far. + pub size: u64, + /// Current state sync phase. + pub phase: StateSyncPhase, +} + +/// Import state chunk result. +pub enum ImportResult { + /// State is complete and ready for import. + Import(B::Hash, B::Header, ImportedState, Option>, Option), + /// Continue downloading. + Continue, + /// Bad state chunk. + BadResponse, +} /// State sync state machine. Accumulates partial state data until it /// is ready to be imported. @@ -50,16 +105,6 @@ pub struct StateSync { skip_proof: bool, } -/// Import state chunk result. -pub enum ImportResult { - /// State is complete and ready for import. - Import(B::Hash, B::Header, ImportedState, Option>, Option), - /// Continue downloading. - Continue, - /// Bad state chunk. - BadResponse, -} - impl StateSync where B: BlockT, @@ -87,24 +132,30 @@ where skip_proof, } } +} +impl StateSyncProvider for StateSync +where + B: BlockT, + Client: ProofProvider + Send + Sync + 'static, +{ /// Validate and import a state response. - pub fn import(&mut self, response: StateResponse) -> ImportResult { + fn import(&mut self, response: StateResponse) -> ImportResult { if response.entries.is_empty() && response.proof.is_empty() { - debug!(target: "sync", "Bad state response"); + debug!(target: LOG_TARGET, "Bad state response"); return ImportResult::BadResponse } if !self.skip_proof && response.proof.is_empty() { - debug!(target: "sync", "Missing proof"); + debug!(target: LOG_TARGET, "Missing proof"); return ImportResult::BadResponse } let complete = if !self.skip_proof { - debug!(target: "sync", "Importing state from {} trie nodes", response.proof.len()); + debug!(target: LOG_TARGET, "Importing state from {} trie nodes", response.proof.len()); let proof_size = response.proof.len() as u64; let proof = match CompactProof::decode(&mut response.proof.as_ref()) { Ok(proof) => proof, Err(e) => { - debug!(target: "sync", "Error decoding proof: {:?}", e); + debug!(target: LOG_TARGET, "Error decoding proof: {:?}", e); return ImportResult::BadResponse }, }; @@ -115,7 +166,7 @@ where ) { Err(e) => { debug!( - target: "sync", + target: LOG_TARGET, "StateResponse failed proof verification: {}", e, ); @@ -123,11 +174,11 @@ where }, Ok(values) => values, }; - debug!(target: "sync", "Imported with {} keys", values.len()); + debug!(target: LOG_TARGET, "Imported with {} keys", values.len()); let complete = completed == 0; if !complete && !values.update_last_key(completed, &mut self.last_key) { - debug!(target: "sync", "Error updating key cursor, depth: {}", completed); + debug!(target: LOG_TARGET, "Error updating key cursor, depth: {}", completed); }; for values in values.0 { @@ -185,7 +236,7 @@ where } for state in response.entries { debug!( - target: "sync", + target: LOG_TARGET, "Importing state from {:?} to {:?}", state.entries.last().map(|e| sp_core::hexdisplay::HexDisplay::from(&e.key)), state.entries.first().map(|e| sp_core::hexdisplay::HexDisplay::from(&e.key)), @@ -237,7 +288,7 @@ where } /// Produce next state request. - pub fn next_request(&self) -> StateRequest { + fn next_request(&self) -> StateRequest { StateRequest { block: self.target_block.encode(), start: self.last_key.clone().into_vec(), @@ -246,24 +297,32 @@ where } /// Check if the state is complete. - pub fn is_complete(&self) -> bool { + fn is_complete(&self) -> bool { self.complete } /// Returns target block number. - pub fn target_block_num(&self) -> NumberFor { + fn target_number(&self) -> NumberFor { *self.target_header.number() } /// Returns target block hash. - pub fn target(&self) -> B::Hash { + fn target_hash(&self) -> B::Hash { self.target_block } /// Returns state sync estimated progress. - pub fn progress(&self) -> StateDownloadProgress { + fn progress(&self) -> StateSyncProgress { let cursor = *self.last_key.get(0).and_then(|last| last.get(0)).unwrap_or(&0u8); let percent_done = cursor as u32 * 100 / 256; - StateDownloadProgress { percentage: percent_done, size: self.imported_bytes } + StateSyncProgress { + percentage: percent_done, + size: self.imported_bytes, + phase: if self.complete { + StateSyncPhase::ImportingState + } else { + StateSyncPhase::DownloadingState + }, + } } } diff --git a/substrate/client/network/sync/src/strategy/warp.rs b/substrate/client/network/sync/src/strategy/warp.rs new file mode 100644 index 00000000000..7935b5f29b6 --- /dev/null +++ b/substrate/client/network/sync/src/strategy/warp.rs @@ -0,0 +1,1443 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Warp syncing strategy. Bootstraps chain by downloading warp proofs and state. + +pub use sp_consensus_grandpa::{AuthorityList, SetId}; + +use crate::{ + strategy::chain_sync::validate_blocks, + types::{BadPeer, SyncState, SyncStatus}, + LOG_TARGET, +}; +use codec::{Decode, Encode}; +use futures::channel::oneshot; +use libp2p::PeerId; +use log::{debug, error, trace}; +use sc_network_common::sync::message::{ + BlockAnnounce, BlockAttributes, BlockData, BlockRequest, Direction, FromBlock, +}; +use sp_blockchain::HeaderBackend; +use sp_runtime::{ + traits::{Block as BlockT, Header, NumberFor, Zero}, + Justifications, SaturatedConversion, +}; +use std::{collections::HashMap, fmt, sync::Arc}; + +/// Number of peers that need to be connected before warp sync is started. +const MIN_PEERS_TO_START_WARP_SYNC: usize = 3; + +/// Scale-encoded warp sync proof response. +pub struct EncodedProof(pub Vec); + +/// Warp sync request +#[derive(Encode, Decode, Debug, Clone)] +pub struct WarpProofRequest { + /// Start collecting proofs from this block. + pub begin: B::Hash, +} + +/// Proof verification result. +pub enum VerificationResult { + /// Proof is valid, but the target was not reached. + Partial(SetId, AuthorityList, Block::Hash), + /// Target finality is proved. + Complete(SetId, AuthorityList, Block::Header), +} + +/// Warp sync backend. Handles retrieving and verifying warp sync proofs. +pub trait WarpSyncProvider: Send + Sync { + /// Generate proof starting at given block hash. The proof is accumulated until maximum proof + /// size is reached. + fn generate( + &self, + start: Block::Hash, + ) -> Result>; + /// Verify warp proof against current set of authorities. + fn verify( + &self, + proof: &EncodedProof, + set_id: SetId, + authorities: AuthorityList, + ) -> Result, Box>; + /// Get current list of authorities. This is supposed to be genesis authorities when starting + /// sync. + fn current_authorities(&self) -> AuthorityList; +} + +mod rep { + use sc_network::ReputationChange as Rep; + + /// Unexpected response received form a peer + pub const UNEXPECTED_RESPONSE: Rep = Rep::new(-(1 << 29), "Unexpected response"); + + /// Peer provided invalid warp proof data + pub const BAD_WARP_PROOF: Rep = Rep::new(-(1 << 29), "Bad warp proof"); + + /// Peer did not provide us with advertised block data. + pub const NO_BLOCK: Rep = Rep::new(-(1 << 29), "No requested block data"); + + /// Reputation change for peers which send us non-requested block data. + pub const NOT_REQUESTED: Rep = Rep::new(-(1 << 29), "Not requested block data"); + + /// Reputation change for peers which send us a block which we fail to verify. + pub const VERIFICATION_FAIL: Rep = Rep::new(-(1 << 29), "Block verification failed"); +} + +/// Reported warp sync phase. +#[derive(Clone, Eq, PartialEq, Debug)] +pub enum WarpSyncPhase { + /// Waiting for peers to connect. + AwaitingPeers { required_peers: usize }, + /// Waiting for target block to be received. + AwaitingTargetBlock, + /// Downloading and verifying grandpa warp proofs. + DownloadingWarpProofs, + /// Downloading target block. + DownloadingTargetBlock, + /// Downloading state data. + DownloadingState, + /// Importing state. + ImportingState, + /// Downloading block history. + DownloadingBlocks(NumberFor), + /// Warp sync is complete. + Complete, +} + +impl fmt::Display for WarpSyncPhase { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::AwaitingPeers { required_peers } => + write!(f, "Waiting for {required_peers} peers to be connected"), + Self::AwaitingTargetBlock => write!(f, "Waiting for target block to be received"), + Self::DownloadingWarpProofs => write!(f, "Downloading finality proofs"), + Self::DownloadingTargetBlock => write!(f, "Downloading target block"), + Self::DownloadingState => write!(f, "Downloading state"), + Self::ImportingState => write!(f, "Importing state"), + Self::DownloadingBlocks(n) => write!(f, "Downloading block history (#{})", n), + Self::Complete => write!(f, "Warp sync is complete"), + } + } +} + +/// Reported warp sync progress. +#[derive(Clone, Eq, PartialEq, Debug)] +pub struct WarpSyncProgress { + /// Estimated download percentage. + pub phase: WarpSyncPhase, + /// Total bytes downloaded so far. + pub total_bytes: u64, +} + +/// The different types of warp syncing, passed to `build_network`. +pub enum WarpSyncParams { + /// Standard warp sync for the chain. + WithProvider(Arc>), + /// Skip downloading proofs and wait for a header of the state that should be downloaded. + /// + /// It is expected that the header provider ensures that the header is trusted. + WaitForTarget(oneshot::Receiver<::Header>), +} + +/// Warp sync configuration as accepted by [`WarpSync`]. +pub enum WarpSyncConfig { + /// Standard warp sync for the chain. + WithProvider(Arc>), + /// Skip downloading proofs and wait for a header of the state that should be downloaded. + /// + /// It is expected that the header provider ensures that the header is trusted. + WaitForTarget, +} + +impl WarpSyncParams { + /// Split `WarpSyncParams` into `WarpSyncConfig` and warp sync target block header receiver. + pub fn split( + self, + ) -> (WarpSyncConfig, Option::Header>>) { + match self { + WarpSyncParams::WithProvider(provider) => + (WarpSyncConfig::WithProvider(provider), None), + WarpSyncParams::WaitForTarget(rx) => (WarpSyncConfig::WaitForTarget, Some(rx)), + } + } +} + +/// Warp sync phase used by warp sync state machine. +enum Phase { + /// Waiting for enough peers to connect. + WaitingForPeers { warp_sync_provider: Arc> }, + /// Downloading warp proofs. + WarpProof { + set_id: SetId, + authorities: AuthorityList, + last_hash: B::Hash, + warp_sync_provider: Arc>, + }, + /// Waiting for target block to be set externally if we skip warp proofs downloading, + /// and start straight from the target block (used by parachains warp sync). + PendingTargetBlock, + /// Downloading target block. + TargetBlock(B::Header), + /// Warp sync is complete. + Complete, +} + +enum PeerState { + Available, + DownloadingProofs, + DownloadingTargetBlock, +} + +impl PeerState { + fn is_available(&self) -> bool { + matches!(self, PeerState::Available) + } +} + +struct Peer { + best_number: NumberFor, + state: PeerState, +} + +/// Action that should be performed on [`WarpSync`]'s behalf. +pub enum WarpSyncAction { + /// Send warp proof request to peer. + SendWarpProofRequest { peer_id: PeerId, request: WarpProofRequest }, + /// Send block request to peer. Always implies dropping a stale block request to the same peer. + SendBlockRequest { peer_id: PeerId, request: BlockRequest }, + /// Disconnect and report peer. + DropPeer(BadPeer), + /// Warp sync has finished. + Finished, +} + +pub struct WarpSyncResult { + pub target_header: B::Header, + pub target_body: Option>, + pub target_justifications: Option, +} + +/// Warp sync state machine. Accumulates warp proofs and state. +pub struct WarpSync { + phase: Phase, + client: Arc, + total_proof_bytes: u64, + total_state_bytes: u64, + peers: HashMap>, + actions: Vec>, + result: Option>, +} + +impl WarpSync +where + B: BlockT, + Client: HeaderBackend + 'static, +{ + /// Create a new instance. When passing a warp sync provider we will be checking for proof and + /// authorities. Alternatively we can pass a target block when we want to skip downloading + /// proofs, in this case we will continue polling until the target block is known. + pub fn new(client: Arc, warp_sync_config: WarpSyncConfig) -> Self { + if client.info().finalized_state.is_some() { + error!( + target: LOG_TARGET, + "Can't use warp sync mode with a partially synced database. Reverting to full sync mode." + ); + return Self { + client, + phase: Phase::Complete, + total_proof_bytes: 0, + total_state_bytes: 0, + peers: HashMap::new(), + actions: vec![WarpSyncAction::Finished], + result: None, + } + } + + let phase = match warp_sync_config { + WarpSyncConfig::WithProvider(warp_sync_provider) => + Phase::WaitingForPeers { warp_sync_provider }, + WarpSyncConfig::WaitForTarget => Phase::PendingTargetBlock, + }; + + Self { + client, + phase, + total_proof_bytes: 0, + total_state_bytes: 0, + peers: HashMap::new(), + actions: Vec::new(), + result: None, + } + } + + /// Set target block externally in case we skip warp proof downloading. + pub fn set_target_block(&mut self, header: B::Header) { + let Phase::PendingTargetBlock = self.phase else { + error!( + target: LOG_TARGET, + "Attempt to set warp sync target block in invalid phase.", + ); + debug_assert!(false); + return + }; + + self.phase = Phase::TargetBlock(header); + } + + /// Notify that a new peer has connected. + pub fn add_peer(&mut self, peer_id: PeerId, _best_hash: B::Hash, best_number: NumberFor) { + self.peers.insert(peer_id, Peer { best_number, state: PeerState::Available }); + + self.try_to_start_warp_sync(); + } + + /// Notify that a peer has disconnected. + pub fn remove_peer(&mut self, peer_id: &PeerId) { + self.peers.remove(peer_id); + } + + /// Submit a validated block announcement. + /// + /// Returns new best hash & best number of the peer if they are updated. + #[must_use] + pub fn on_validated_block_announce( + &mut self, + is_best: bool, + peer_id: PeerId, + announce: &BlockAnnounce, + ) -> Option<(B::Hash, NumberFor)> { + is_best.then_some({ + let best_number = *announce.header.number(); + let best_hash = announce.header.hash(); + if let Some(ref mut peer) = self.peers.get_mut(&peer_id) { + peer.best_number = best_number; + } + // Let `SyncingEngine` know that we should update the peer info. + (best_hash, best_number) + }) + } + + /// Start warp sync as soon as we have enough peers. + fn try_to_start_warp_sync(&mut self) { + let Phase::WaitingForPeers { warp_sync_provider } = &self.phase else { return }; + + if self.peers.len() < MIN_PEERS_TO_START_WARP_SYNC { + return + } + + self.phase = Phase::WarpProof { + set_id: 0, + authorities: warp_sync_provider.current_authorities(), + last_hash: self.client.info().genesis_hash, + warp_sync_provider: Arc::clone(warp_sync_provider), + }; + trace!(target: LOG_TARGET, "Started warp sync with {} peers.", self.peers.len()); + } + + /// Process warp proof response. + pub fn on_warp_proof_response(&mut self, peer_id: &PeerId, response: EncodedProof) { + if let Some(peer) = self.peers.get_mut(peer_id) { + peer.state = PeerState::Available; + } + + let Phase::WarpProof { set_id, authorities, last_hash, warp_sync_provider } = + &mut self.phase + else { + debug!(target: LOG_TARGET, "Unexpected warp proof response"); + self.actions + .push(WarpSyncAction::DropPeer(BadPeer(*peer_id, rep::UNEXPECTED_RESPONSE))); + return + }; + + match warp_sync_provider.verify(&response, *set_id, authorities.clone()) { + Err(e) => { + debug!(target: LOG_TARGET, "Bad warp proof response: {}", e); + self.actions + .push(WarpSyncAction::DropPeer(BadPeer(*peer_id, rep::BAD_WARP_PROOF))) + }, + Ok(VerificationResult::Partial(new_set_id, new_authorities, new_last_hash)) => { + log::debug!(target: LOG_TARGET, "Verified partial proof, set_id={:?}", new_set_id); + *set_id = new_set_id; + *authorities = new_authorities; + *last_hash = new_last_hash; + self.total_proof_bytes += response.0.len() as u64; + }, + Ok(VerificationResult::Complete(new_set_id, _, header)) => { + log::debug!( + target: LOG_TARGET, + "Verified complete proof, set_id={:?}. Continuing with target block download: {} ({}).", + new_set_id, + header.hash(), + header.number(), + ); + self.total_proof_bytes += response.0.len() as u64; + self.phase = Phase::TargetBlock(header); + }, + } + } + + /// Process (target) block response. + pub fn on_block_response( + &mut self, + peer_id: PeerId, + request: BlockRequest, + blocks: Vec>, + ) { + if let Err(bad_peer) = self.on_block_response_inner(peer_id, request, blocks) { + self.actions.push(WarpSyncAction::DropPeer(bad_peer)); + } + } + + fn on_block_response_inner( + &mut self, + peer_id: PeerId, + request: BlockRequest, + mut blocks: Vec>, + ) -> Result<(), BadPeer> { + if let Some(peer) = self.peers.get_mut(&peer_id) { + peer.state = PeerState::Available; + } + + let Phase::TargetBlock(header) = &mut self.phase else { + debug!(target: LOG_TARGET, "Unexpected target block response from {peer_id}"); + return Err(BadPeer(peer_id, rep::UNEXPECTED_RESPONSE)) + }; + + if blocks.is_empty() { + debug!( + target: LOG_TARGET, + "Downloading target block failed: empty block response from {peer_id}", + ); + return Err(BadPeer(peer_id, rep::NO_BLOCK)) + } + + if blocks.len() > 1 { + debug!( + target: LOG_TARGET, + "Too many blocks ({}) in warp target block response from {peer_id}", + blocks.len(), + ); + return Err(BadPeer(peer_id, rep::NOT_REQUESTED)) + } + + validate_blocks::(&blocks, &peer_id, Some(request))?; + + let block = blocks.pop().expect("`blocks` len checked above; qed"); + + let Some(block_header) = &block.header else { + debug!( + target: LOG_TARGET, + "Downloading target block failed: missing header in response from {peer_id}.", + ); + return Err(BadPeer(peer_id, rep::VERIFICATION_FAIL)) + }; + + if block_header != header { + debug!( + target: LOG_TARGET, + "Downloading target block failed: different header in response from {peer_id}.", + ); + return Err(BadPeer(peer_id, rep::VERIFICATION_FAIL)) + } + + if block.body.is_none() { + debug!( + target: LOG_TARGET, + "Downloading target block failed: missing body in response from {peer_id}.", + ); + return Err(BadPeer(peer_id, rep::VERIFICATION_FAIL)) + } + + self.result = Some(WarpSyncResult { + target_header: header.clone(), + target_body: block.body, + target_justifications: block.justifications, + }); + self.phase = Phase::Complete; + self.actions.push(WarpSyncAction::Finished); + Ok(()) + } + + /// Reserve a peer for a request assigning `new_state`. + fn schedule_next_peer( + &mut self, + new_state: PeerState, + min_best_number: Option>, + ) -> Option { + let mut targets: Vec<_> = self.peers.values().map(|p| p.best_number).collect(); + if targets.is_empty() { + return None + } + targets.sort(); + let median = targets[targets.len() / 2]; + let threshold = std::cmp::max(median, min_best_number.unwrap_or(Zero::zero())); + // Find a random peer that is synced as much as peer majority and is above + // `min_best_number`. + for (peer_id, peer) in self.peers.iter_mut() { + if peer.state.is_available() && peer.best_number >= threshold { + peer.state = new_state; + return Some(*peer_id) + } + } + None + } + + /// Produce warp proof request. + fn warp_proof_request(&mut self) -> Option<(PeerId, WarpProofRequest)> { + let Phase::WarpProof { last_hash, .. } = &self.phase else { return None }; + + // Copy `last_hash` early to cut the borrowing tie. + let begin = *last_hash; + + if self + .peers + .values() + .any(|peer| matches!(peer.state, PeerState::DownloadingProofs)) + { + // Only one warp proof request at a time is possible. + return None + } + + let peer_id = self.schedule_next_peer(PeerState::DownloadingProofs, None)?; + trace!(target: LOG_TARGET, "New WarpProofRequest to {peer_id}, begin hash: {begin}."); + + Some((peer_id, WarpProofRequest { begin })) + } + + /// Produce target block request. + fn target_block_request(&mut self) -> Option<(PeerId, BlockRequest)> { + let Phase::TargetBlock(target_header) = &self.phase else { return None }; + + if self + .peers + .values() + .any(|peer| matches!(peer.state, PeerState::DownloadingTargetBlock)) + { + // Only one target block request at a time is possible. + return None + } + + // Cut the borrowing tie. + let target_hash = target_header.hash(); + let target_number = *target_header.number(); + + let peer_id = + self.schedule_next_peer(PeerState::DownloadingTargetBlock, Some(target_number))?; + + trace!( + target: LOG_TARGET, + "New target block request to {peer_id}, target: {} ({}).", + target_hash, + target_number, + ); + + Some(( + peer_id, + BlockRequest:: { + id: 0, + fields: BlockAttributes::HEADER | + BlockAttributes::BODY | + BlockAttributes::JUSTIFICATION, + from: FromBlock::Hash(target_hash), + direction: Direction::Ascending, + max: Some(1), + }, + )) + } + + /// Returns warp sync estimated progress (stage, bytes received). + pub fn progress(&self) -> WarpSyncProgress { + match &self.phase { + Phase::WaitingForPeers { .. } => WarpSyncProgress { + phase: WarpSyncPhase::AwaitingPeers { + required_peers: MIN_PEERS_TO_START_WARP_SYNC, + }, + total_bytes: self.total_proof_bytes, + }, + Phase::WarpProof { .. } => WarpSyncProgress { + phase: WarpSyncPhase::DownloadingWarpProofs, + total_bytes: self.total_proof_bytes, + }, + Phase::TargetBlock(_) => WarpSyncProgress { + phase: WarpSyncPhase::DownloadingTargetBlock, + total_bytes: self.total_proof_bytes, + }, + Phase::PendingTargetBlock { .. } => WarpSyncProgress { + phase: WarpSyncPhase::AwaitingTargetBlock, + total_bytes: self.total_proof_bytes, + }, + Phase::Complete => WarpSyncProgress { + phase: WarpSyncPhase::Complete, + total_bytes: self.total_proof_bytes + self.total_state_bytes, + }, + } + } + + /// Get the number of peers known to warp sync. + pub fn num_peers(&self) -> usize { + self.peers.len() + } + + /// Returns the current sync status. + pub fn status(&self) -> SyncStatus { + SyncStatus { + state: match &self.phase { + Phase::WaitingForPeers { .. } => SyncState::Downloading { target: Zero::zero() }, + Phase::WarpProof { .. } => SyncState::Downloading { target: Zero::zero() }, + Phase::PendingTargetBlock => SyncState::Downloading { target: Zero::zero() }, + Phase::TargetBlock(header) => SyncState::Downloading { target: *header.number() }, + Phase::Complete => SyncState::Idle, + }, + best_seen_block: match &self.phase { + Phase::WaitingForPeers { .. } => None, + Phase::WarpProof { .. } => None, + Phase::PendingTargetBlock => None, + Phase::TargetBlock(header) => Some(*header.number()), + Phase::Complete => None, + }, + num_peers: self.peers.len().saturated_into(), + num_connected_peers: self.peers.len().saturated_into(), + queued_blocks: 0, + state_sync: None, + warp_sync: Some(self.progress()), + } + } + + /// Get actions that should be performed by the owner on [`WarpSync`]'s behalf + #[must_use] + pub fn actions(&mut self) -> impl Iterator> { + let warp_proof_request = self + .warp_proof_request() + .into_iter() + .map(|(peer_id, request)| WarpSyncAction::SendWarpProofRequest { peer_id, request }); + self.actions.extend(warp_proof_request); + + let target_block_request = self + .target_block_request() + .into_iter() + .map(|(peer_id, request)| WarpSyncAction::SendBlockRequest { peer_id, request }); + self.actions.extend(target_block_request); + + std::mem::take(&mut self.actions).into_iter() + } + + /// Take the result of finished warp sync, returning `None` if the sync was unsuccessful. + #[must_use] + pub fn take_result(&mut self) -> Option> { + self.result.take() + } +} + +#[cfg(test)] +mod test { + use super::*; + use sc_block_builder::BlockBuilderBuilder; + use sp_blockchain::{BlockStatus, Error as BlockchainError, HeaderBackend, Info}; + use sp_consensus_grandpa::{AuthorityList, SetId}; + use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; + use std::{io::ErrorKind, sync::Arc}; + use substrate_test_runtime_client::{ + runtime::{Block, Hash}, + BlockBuilderExt, DefaultTestClientBuilderExt, TestClientBuilder, TestClientBuilderExt, + }; + + mockall::mock! { + pub Client {} + + impl HeaderBackend for Client { + fn header(&self, hash: B::Hash) -> Result, BlockchainError>; + fn info(&self) -> Info; + fn status(&self, hash: B::Hash) -> Result; + fn number( + &self, + hash: B::Hash, + ) -> Result::Header as HeaderT>::Number>, BlockchainError>; + fn hash(&self, number: NumberFor) -> Result, BlockchainError>; + } + } + + mockall::mock! { + pub WarpSyncProvider {} + + impl super::WarpSyncProvider for WarpSyncProvider { + fn generate( + &self, + start: B::Hash, + ) -> Result>; + fn verify( + &self, + proof: &EncodedProof, + set_id: SetId, + authorities: AuthorityList, + ) -> Result, Box>; + fn current_authorities(&self) -> AuthorityList; + } + } + + fn mock_client_with_state() -> MockClient { + let mut client = MockClient::::new(); + let genesis_hash = Hash::random(); + client.expect_info().return_once(move || Info { + best_hash: genesis_hash, + best_number: 0, + genesis_hash, + finalized_hash: genesis_hash, + finalized_number: 0, + // We need some finalized state to render warp sync impossible. + finalized_state: Some((genesis_hash, 0)), + number_leaves: 0, + block_gap: None, + }); + + client + } + + fn mock_client_without_state() -> MockClient { + let mut client = MockClient::::new(); + let genesis_hash = Hash::random(); + client.expect_info().returning(move || Info { + best_hash: genesis_hash, + best_number: 0, + genesis_hash, + finalized_hash: genesis_hash, + finalized_number: 0, + finalized_state: None, + number_leaves: 0, + block_gap: None, + }); + + client + } + + #[test] + fn warp_sync_with_provider_for_db_with_finalized_state_is_noop() { + let client = mock_client_with_state(); + let provider = MockWarpSyncProvider::::new(); + let config = WarpSyncConfig::WithProvider(Arc::new(provider)); + let mut warp_sync = WarpSync::new(Arc::new(client), config); + + // Warp sync instantly finishes + let actions = warp_sync.actions().collect::>(); + assert_eq!(actions.len(), 1); + assert!(matches!(actions[0], WarpSyncAction::Finished)); + + // ... with no result. + assert!(warp_sync.take_result().is_none()); + } + + #[test] + fn warp_sync_to_target_for_db_with_finalized_state_is_noop() { + let client = mock_client_with_state(); + let config = WarpSyncConfig::WaitForTarget; + let mut warp_sync = WarpSync::new(Arc::new(client), config); + + // Warp sync instantly finishes + let actions = warp_sync.actions().collect::>(); + assert_eq!(actions.len(), 1); + assert!(matches!(actions[0], WarpSyncAction::Finished)); + + // ... with no result. + assert!(warp_sync.take_result().is_none()); + } + + #[test] + fn warp_sync_with_provider_for_empty_db_doesnt_finish_instantly() { + let client = mock_client_without_state(); + let provider = MockWarpSyncProvider::::new(); + let config = WarpSyncConfig::WithProvider(Arc::new(provider)); + let mut warp_sync = WarpSync::new(Arc::new(client), config); + + // No actions are emitted. + assert_eq!(warp_sync.actions().count(), 0) + } + + #[test] + fn warp_sync_to_target_for_empty_db_doesnt_finish_instantly() { + let client = mock_client_without_state(); + let config = WarpSyncConfig::WaitForTarget; + let mut warp_sync = WarpSync::new(Arc::new(client), config); + + // No actions are emitted. + assert_eq!(warp_sync.actions().count(), 0) + } + + #[test] + fn warp_sync_is_started_only_when_there_is_enough_peers() { + let client = mock_client_without_state(); + let mut provider = MockWarpSyncProvider::::new(); + provider + .expect_current_authorities() + .once() + .return_const(AuthorityList::default()); + let config = WarpSyncConfig::WithProvider(Arc::new(provider)); + let mut warp_sync = WarpSync::new(Arc::new(client), config); + + // Warp sync is not started when there is not enough peers. + for _ in 0..(MIN_PEERS_TO_START_WARP_SYNC - 1) { + warp_sync.add_peer(PeerId::random(), Hash::random(), 10); + assert!(matches!(warp_sync.phase, Phase::WaitingForPeers { .. })) + } + + // Now we have enough peers and warp sync is started. + warp_sync.add_peer(PeerId::random(), Hash::random(), 10); + assert!(matches!(warp_sync.phase, Phase::WarpProof { .. })) + } + + #[test] + fn no_peer_is_scheduled_if_no_peers_connected() { + let client = mock_client_without_state(); + let provider = MockWarpSyncProvider::::new(); + let config = WarpSyncConfig::WithProvider(Arc::new(provider)); + let mut warp_sync = WarpSync::new(Arc::new(client), config); + + assert!(warp_sync.schedule_next_peer(PeerState::DownloadingProofs, None).is_none()); + } + + #[test] + fn enough_peers_are_used_in_tests() { + // Tests below use 10 peers. Fail early if it's less than a threshold for warp sync. + assert!( + 10 >= MIN_PEERS_TO_START_WARP_SYNC, + "Tests must be updated to use that many initial peers.", + ); + } + + #[test] + fn at_least_median_synced_peer_is_scheduled() { + for _ in 0..100 { + let client = mock_client_without_state(); + let mut provider = MockWarpSyncProvider::::new(); + provider + .expect_current_authorities() + .once() + .return_const(AuthorityList::default()); + let config = WarpSyncConfig::WithProvider(Arc::new(provider)); + let mut warp_sync = WarpSync::new(Arc::new(client), config); + + for best_number in 1..11 { + warp_sync.add_peer(PeerId::random(), Hash::random(), best_number); + } + + let peer_id = warp_sync.schedule_next_peer(PeerState::DownloadingProofs, None); + assert!(warp_sync.peers.get(&peer_id.unwrap()).unwrap().best_number >= 6); + } + } + + #[test] + fn min_best_number_peer_is_scheduled() { + for _ in 0..10 { + let client = mock_client_without_state(); + let mut provider = MockWarpSyncProvider::::new(); + provider + .expect_current_authorities() + .once() + .return_const(AuthorityList::default()); + let config = WarpSyncConfig::WithProvider(Arc::new(provider)); + let mut warp_sync = WarpSync::new(Arc::new(client), config); + + for best_number in 1..11 { + warp_sync.add_peer(PeerId::random(), Hash::random(), best_number); + } + + let peer_id = warp_sync.schedule_next_peer(PeerState::DownloadingProofs, Some(10)); + assert!(warp_sync.peers.get(&peer_id.unwrap()).unwrap().best_number == 10); + } + } + + #[test] + fn no_warp_proof_request_in_another_phase() { + let client = mock_client_without_state(); + let mut provider = MockWarpSyncProvider::::new(); + provider + .expect_current_authorities() + .once() + .return_const(AuthorityList::default()); + let config = WarpSyncConfig::WithProvider(Arc::new(provider)); + let mut warp_sync = WarpSync::new(Arc::new(client), config); + + // Make sure we have enough peers to make a request. + for best_number in 1..11 { + warp_sync.add_peer(PeerId::random(), Hash::random(), best_number); + } + + // Manually set to another phase. + warp_sync.phase = Phase::PendingTargetBlock; + + // No request is made. + assert!(warp_sync.warp_proof_request().is_none()); + } + + #[test] + fn warp_proof_request_starts_at_last_hash() { + let client = mock_client_without_state(); + let mut provider = MockWarpSyncProvider::::new(); + provider + .expect_current_authorities() + .once() + .return_const(AuthorityList::default()); + let config = WarpSyncConfig::WithProvider(Arc::new(provider)); + let mut warp_sync = WarpSync::new(Arc::new(client), config); + + // Make sure we have enough peers to make a request. + for best_number in 1..11 { + warp_sync.add_peer(PeerId::random(), Hash::random(), best_number); + } + assert!(matches!(warp_sync.phase, Phase::WarpProof { .. })); + + let known_last_hash = Hash::random(); + + // Manually set last hash to known value. + match &mut warp_sync.phase { + Phase::WarpProof { last_hash, .. } => { + *last_hash = known_last_hash; + }, + _ => panic!("Invalid phase."), + } + + let (_peer_id, request) = warp_sync.warp_proof_request().unwrap(); + assert_eq!(request.begin, known_last_hash); + } + + #[test] + fn no_parallel_warp_proof_requests() { + let client = mock_client_without_state(); + let mut provider = MockWarpSyncProvider::::new(); + provider + .expect_current_authorities() + .once() + .return_const(AuthorityList::default()); + let config = WarpSyncConfig::WithProvider(Arc::new(provider)); + let mut warp_sync = WarpSync::new(Arc::new(client), config); + + // Make sure we have enough peers to make requests. + for best_number in 1..11 { + warp_sync.add_peer(PeerId::random(), Hash::random(), best_number); + } + assert!(matches!(warp_sync.phase, Phase::WarpProof { .. })); + + // First request is made. + assert!(warp_sync.warp_proof_request().is_some()); + // Second request is not made. + assert!(warp_sync.warp_proof_request().is_none()); + } + + #[test] + fn bad_warp_proof_response_drops_peer() { + let client = mock_client_without_state(); + let mut provider = MockWarpSyncProvider::::new(); + provider + .expect_current_authorities() + .once() + .return_const(AuthorityList::default()); + // Warp proof verification fails. + provider.expect_verify().return_once(|_proof, _set_id, _authorities| { + Err(Box::new(std::io::Error::new(ErrorKind::Other, "test-verification-failure"))) + }); + let config = WarpSyncConfig::WithProvider(Arc::new(provider)); + let mut warp_sync = WarpSync::new(Arc::new(client), config); + + // Make sure we have enough peers to make a request. + for best_number in 1..11 { + warp_sync.add_peer(PeerId::random(), Hash::random(), best_number); + } + assert!(matches!(warp_sync.phase, Phase::WarpProof { .. })); + + // Consume `SendWarpProofRequest` action. + let actions = warp_sync.actions().collect::>(); + assert_eq!(actions.len(), 1); + let WarpSyncAction::SendWarpProofRequest { peer_id: request_peer_id, .. } = actions[0] + else { + panic!("Invalid action"); + }; + + warp_sync.on_warp_proof_response(&request_peer_id, EncodedProof(Vec::new())); + + // We only interested in alredy generated actions, not new requests. + let actions = std::mem::take(&mut warp_sync.actions); + assert_eq!(actions.len(), 1); + assert!(matches!( + actions[0], + WarpSyncAction::DropPeer(BadPeer(peer_id, _rep)) if peer_id == request_peer_id + )); + assert!(matches!(warp_sync.phase, Phase::WarpProof { .. })); + } + + #[test] + fn partial_warp_proof_doesnt_advance_phase() { + let client = mock_client_without_state(); + let mut provider = MockWarpSyncProvider::::new(); + provider + .expect_current_authorities() + .once() + .return_const(AuthorityList::default()); + // Warp proof is partial. + provider.expect_verify().return_once(|_proof, set_id, authorities| { + Ok(VerificationResult::Partial(set_id, authorities, Hash::random())) + }); + let config = WarpSyncConfig::WithProvider(Arc::new(provider)); + let mut warp_sync = WarpSync::new(Arc::new(client), config); + + // Make sure we have enough peers to make a request. + for best_number in 1..11 { + warp_sync.add_peer(PeerId::random(), Hash::random(), best_number); + } + assert!(matches!(warp_sync.phase, Phase::WarpProof { .. })); + + // Consume `SendWarpProofRequest` action. + let actions = warp_sync.actions().collect::>(); + assert_eq!(actions.len(), 1); + let WarpSyncAction::SendWarpProofRequest { peer_id: request_peer_id, .. } = actions[0] + else { + panic!("Invalid action"); + }; + + warp_sync.on_warp_proof_response(&request_peer_id, EncodedProof(Vec::new())); + + assert!(warp_sync.actions.is_empty(), "No extra actions generated"); + assert!(matches!(warp_sync.phase, Phase::WarpProof { .. })); + } + + #[test] + fn complete_warp_proof_advances_phase() { + let client = Arc::new(TestClientBuilder::new().set_no_genesis().build()); + let mut provider = MockWarpSyncProvider::::new(); + provider + .expect_current_authorities() + .once() + .return_const(AuthorityList::default()); + let target_block = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().best_hash) + .with_parent_block_number(client.chain_info().best_number) + .build() + .unwrap() + .build() + .unwrap() + .block; + let target_header = target_block.header().clone(); + // Warp proof is complete. + provider.expect_verify().return_once(move |_proof, set_id, authorities| { + Ok(VerificationResult::Complete(set_id, authorities, target_header)) + }); + let config = WarpSyncConfig::WithProvider(Arc::new(provider)); + let mut warp_sync = WarpSync::new(client, config); + + // Make sure we have enough peers to make a request. + for best_number in 1..11 { + warp_sync.add_peer(PeerId::random(), Hash::random(), best_number); + } + assert!(matches!(warp_sync.phase, Phase::WarpProof { .. })); + + // Consume `SendWarpProofRequest` action. + let actions = warp_sync.actions().collect::>(); + assert_eq!(actions.len(), 1); + let WarpSyncAction::SendWarpProofRequest { peer_id: request_peer_id, .. } = actions[0] + else { + panic!("Invalid action."); + }; + + warp_sync.on_warp_proof_response(&request_peer_id, EncodedProof(Vec::new())); + + assert!(warp_sync.actions.is_empty(), "No extra actions generated."); + assert!( + matches!(warp_sync.phase, Phase::TargetBlock(header) if header == *target_block.header()) + ); + } + + #[test] + fn no_target_block_requests_in_another_phase() { + let client = mock_client_without_state(); + let mut provider = MockWarpSyncProvider::::new(); + provider + .expect_current_authorities() + .once() + .return_const(AuthorityList::default()); + let config = WarpSyncConfig::WithProvider(Arc::new(provider)); + let mut warp_sync = WarpSync::new(Arc::new(client), config); + + // Make sure we have enough peers to make a request. + for best_number in 1..11 { + warp_sync.add_peer(PeerId::random(), Hash::random(), best_number); + } + // We are not in `Phase::TargetBlock` + assert!(matches!(warp_sync.phase, Phase::WarpProof { .. })); + + // No request is made. + assert!(warp_sync.target_block_request().is_none()); + } + + #[test] + fn target_block_request_is_correct() { + let client = Arc::new(TestClientBuilder::new().set_no_genesis().build()); + let mut provider = MockWarpSyncProvider::::new(); + provider + .expect_current_authorities() + .once() + .return_const(AuthorityList::default()); + let target_block = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().best_hash) + .with_parent_block_number(client.chain_info().best_number) + .build() + .unwrap() + .build() + .unwrap() + .block; + let target_header = target_block.header().clone(); + // Warp proof is complete. + provider.expect_verify().return_once(move |_proof, set_id, authorities| { + Ok(VerificationResult::Complete(set_id, authorities, target_header)) + }); + let config = WarpSyncConfig::WithProvider(Arc::new(provider)); + let mut warp_sync = WarpSync::new(client, config); + + // Make sure we have enough peers to make a request. + for best_number in 1..11 { + warp_sync.add_peer(PeerId::random(), Hash::random(), best_number); + } + + // Manually set `TargetBlock` phase. + warp_sync.phase = Phase::TargetBlock(target_block.header().clone()); + + let (_peer_id, request) = warp_sync.target_block_request().unwrap(); + assert_eq!(request.from, FromBlock::Hash(target_block.header().hash())); + assert_eq!( + request.fields, + BlockAttributes::HEADER | BlockAttributes::BODY | BlockAttributes::JUSTIFICATION + ); + assert_eq!(request.max, Some(1)); + } + + #[test] + fn externally_set_target_block_is_requested() { + let client = Arc::new(TestClientBuilder::new().set_no_genesis().build()); + let target_block = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().best_hash) + .with_parent_block_number(client.chain_info().best_number) + .build() + .unwrap() + .build() + .unwrap() + .block; + let target_header = target_block.header().clone(); + let config = WarpSyncConfig::WaitForTarget; + let mut warp_sync = WarpSync::new(client, config); + + // Make sure we have enough peers to make a request. + for best_number in 1..11 { + warp_sync.add_peer(PeerId::random(), Hash::random(), best_number); + } + + // No actions generated so far. + assert_eq!(warp_sync.actions().count(), 0); + + warp_sync.set_target_block(target_header); + assert!(matches!(warp_sync.phase, Phase::TargetBlock(_))); + + let (_peer_id, request) = warp_sync.target_block_request().unwrap(); + assert_eq!(request.from, FromBlock::Hash(target_block.header().hash())); + assert_eq!( + request.fields, + BlockAttributes::HEADER | BlockAttributes::BODY | BlockAttributes::JUSTIFICATION + ); + assert_eq!(request.max, Some(1)); + } + + #[test] + fn no_parallel_target_block_requests() { + let client = Arc::new(TestClientBuilder::new().set_no_genesis().build()); + let mut provider = MockWarpSyncProvider::::new(); + provider + .expect_current_authorities() + .once() + .return_const(AuthorityList::default()); + let target_block = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().best_hash) + .with_parent_block_number(client.chain_info().best_number) + .build() + .unwrap() + .build() + .unwrap() + .block; + let target_header = target_block.header().clone(); + // Warp proof is complete. + provider.expect_verify().return_once(move |_proof, set_id, authorities| { + Ok(VerificationResult::Complete(set_id, authorities, target_header)) + }); + let config = WarpSyncConfig::WithProvider(Arc::new(provider)); + let mut warp_sync = WarpSync::new(client, config); + + // Make sure we have enough peers to make a request. + for best_number in 1..11 { + warp_sync.add_peer(PeerId::random(), Hash::random(), best_number); + } + + // Manually set `TargetBlock` phase. + warp_sync.phase = Phase::TargetBlock(target_block.header().clone()); + + // First target block request is made. + assert!(warp_sync.target_block_request().is_some()); + // No parallel request is made. + assert!(warp_sync.target_block_request().is_none()); + } + + #[test] + fn target_block_response_with_no_blocks_drops_peer() { + let client = Arc::new(TestClientBuilder::new().set_no_genesis().build()); + let mut provider = MockWarpSyncProvider::::new(); + provider + .expect_current_authorities() + .once() + .return_const(AuthorityList::default()); + let target_block = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().best_hash) + .with_parent_block_number(client.chain_info().best_number) + .build() + .unwrap() + .build() + .unwrap() + .block; + let target_header = target_block.header().clone(); + // Warp proof is complete. + provider.expect_verify().return_once(move |_proof, set_id, authorities| { + Ok(VerificationResult::Complete(set_id, authorities, target_header)) + }); + let config = WarpSyncConfig::WithProvider(Arc::new(provider)); + let mut warp_sync = WarpSync::new(client, config); + + // Make sure we have enough peers to make a request. + for best_number in 1..11 { + warp_sync.add_peer(PeerId::random(), Hash::random(), best_number); + } + + // Manually set `TargetBlock` phase. + warp_sync.phase = Phase::TargetBlock(target_block.header().clone()); + + let (peer_id, request) = warp_sync.target_block_request().unwrap(); + + // Empty block response received. + let response = Vec::new(); + // Peer is dropped. + assert!(matches!( + warp_sync.on_block_response_inner(peer_id, request, response), + Err(BadPeer(id, _rep)) if id == peer_id, + )); + } + + #[test] + fn target_block_response_with_extra_blocks_drops_peer() { + let client = Arc::new(TestClientBuilder::new().set_no_genesis().build()); + let mut provider = MockWarpSyncProvider::::new(); + provider + .expect_current_authorities() + .once() + .return_const(AuthorityList::default()); + let target_block = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().best_hash) + .with_parent_block_number(client.chain_info().best_number) + .build() + .unwrap() + .build() + .unwrap() + .block; + + let mut extra_block_builder = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().best_hash) + .with_parent_block_number(client.chain_info().best_number) + .build() + .unwrap(); + extra_block_builder + .push_storage_change(vec![1, 2, 3], Some(vec![4, 5, 6])) + .unwrap(); + let extra_block = extra_block_builder.build().unwrap().block; + + let target_header = target_block.header().clone(); + // Warp proof is complete. + provider.expect_verify().return_once(move |_proof, set_id, authorities| { + Ok(VerificationResult::Complete(set_id, authorities, target_header)) + }); + let config = WarpSyncConfig::WithProvider(Arc::new(provider)); + let mut warp_sync = WarpSync::new(client, config); + + // Make sure we have enough peers to make a request. + for best_number in 1..11 { + warp_sync.add_peer(PeerId::random(), Hash::random(), best_number); + } + + // Manually set `TargetBlock` phase. + warp_sync.phase = Phase::TargetBlock(target_block.header().clone()); + + let (peer_id, request) = warp_sync.target_block_request().unwrap(); + + // Block response with extra blocks received. + let response = vec![ + BlockData:: { + hash: target_block.header().hash(), + header: Some(target_block.header().clone()), + body: Some(target_block.extrinsics().iter().cloned().collect::>()), + indexed_body: None, + receipt: None, + message_queue: None, + justification: None, + justifications: None, + }, + BlockData:: { + hash: extra_block.header().hash(), + header: Some(extra_block.header().clone()), + body: Some(extra_block.extrinsics().iter().cloned().collect::>()), + indexed_body: None, + receipt: None, + message_queue: None, + justification: None, + justifications: None, + }, + ]; + // Peer is dropped. + assert!(matches!( + warp_sync.on_block_response_inner(peer_id, request, response), + Err(BadPeer(id, _rep)) if id == peer_id, + )); + } + + #[test] + fn target_block_response_with_wrong_block_drops_peer() { + sp_tracing::try_init_simple(); + + let client = Arc::new(TestClientBuilder::new().set_no_genesis().build()); + let mut provider = MockWarpSyncProvider::::new(); + provider + .expect_current_authorities() + .once() + .return_const(AuthorityList::default()); + let target_block = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().best_hash) + .with_parent_block_number(client.chain_info().best_number) + .build() + .unwrap() + .build() + .unwrap() + .block; + + let mut wrong_block_builder = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().best_hash) + .with_parent_block_number(client.chain_info().best_number) + .build() + .unwrap(); + wrong_block_builder + .push_storage_change(vec![1, 2, 3], Some(vec![4, 5, 6])) + .unwrap(); + let wrong_block = wrong_block_builder.build().unwrap().block; + + let target_header = target_block.header().clone(); + // Warp proof is complete. + provider.expect_verify().return_once(move |_proof, set_id, authorities| { + Ok(VerificationResult::Complete(set_id, authorities, target_header)) + }); + let config = WarpSyncConfig::WithProvider(Arc::new(provider)); + let mut warp_sync = WarpSync::new(client, config); + + // Make sure we have enough peers to make a request. + for best_number in 1..11 { + warp_sync.add_peer(PeerId::random(), Hash::random(), best_number); + } + + // Manually set `TargetBlock` phase. + warp_sync.phase = Phase::TargetBlock(target_block.header().clone()); + + let (peer_id, request) = warp_sync.target_block_request().unwrap(); + + // Wrong block received. + let response = vec![BlockData:: { + hash: wrong_block.header().hash(), + header: Some(wrong_block.header().clone()), + body: Some(wrong_block.extrinsics().iter().cloned().collect::>()), + indexed_body: None, + receipt: None, + message_queue: None, + justification: None, + justifications: None, + }]; + // Peer is dropped. + assert!(matches!( + warp_sync.on_block_response_inner(peer_id, request, response), + Err(BadPeer(id, _rep)) if id == peer_id, + )); + } + + #[test] + fn correct_target_block_response_sets_strategy_result() { + let client = Arc::new(TestClientBuilder::new().set_no_genesis().build()); + let mut provider = MockWarpSyncProvider::::new(); + provider + .expect_current_authorities() + .once() + .return_const(AuthorityList::default()); + let mut target_block_builder = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().best_hash) + .with_parent_block_number(client.chain_info().best_number) + .build() + .unwrap(); + target_block_builder + .push_storage_change(vec![1, 2, 3], Some(vec![4, 5, 6])) + .unwrap(); + let target_block = target_block_builder.build().unwrap().block; + let target_header = target_block.header().clone(); + // Warp proof is complete. + provider.expect_verify().return_once(move |_proof, set_id, authorities| { + Ok(VerificationResult::Complete(set_id, authorities, target_header)) + }); + let config = WarpSyncConfig::WithProvider(Arc::new(provider)); + let mut warp_sync = WarpSync::new(client, config); + + // Make sure we have enough peers to make a request. + for best_number in 1..11 { + warp_sync.add_peer(PeerId::random(), Hash::random(), best_number); + } + + // Manually set `TargetBlock` phase. + warp_sync.phase = Phase::TargetBlock(target_block.header().clone()); + + let (peer_id, request) = warp_sync.target_block_request().unwrap(); + + // Correct block received. + let body = Some(target_block.extrinsics().iter().cloned().collect::>()); + let justifications = Some(Justifications::from((*b"FRNK", Vec::new()))); + let response = vec![BlockData:: { + hash: target_block.header().hash(), + header: Some(target_block.header().clone()), + body: body.clone(), + indexed_body: None, + receipt: None, + message_queue: None, + justification: None, + justifications: justifications.clone(), + }]; + + assert!(warp_sync.on_block_response_inner(peer_id, request, response).is_ok()); + + // Strategy finishes. + let actions = warp_sync.actions().collect::>(); + assert_eq!(actions.len(), 1); + assert!(matches!(actions[0], WarpSyncAction::Finished)); + + // With correct result. + let result = warp_sync.take_result().unwrap(); + assert_eq!(result.target_header, *target_block.header()); + assert_eq!(result.target_body, body); + assert_eq!(result.target_justifications, justifications); + } +} diff --git a/substrate/client/network/sync/src/types.rs b/substrate/client/network/sync/src/types.rs index 5931cf47b28..4074b33eee1 100644 --- a/substrate/client/network/sync/src/types.rs +++ b/substrate/client/network/sync/src/types.rs @@ -23,14 +23,12 @@ use sc_network_common::{role::Roles, types::ReputationChange}; use libp2p::PeerId; -use crate::warp::WarpSyncProgress; +use crate::strategy::{state_sync::StateSyncProgress, warp::WarpSyncProgress}; use sc_network_common::sync::message::BlockRequest; use sp_runtime::traits::{Block as BlockT, NumberFor}; use std::{any::Any, fmt, fmt::Formatter, pin::Pin, sync::Arc}; -pub use sc_network_common::sync::SyncMode; - /// The sync status of a peer we are trying to sync with #[derive(Debug)] pub struct PeerInfo { @@ -69,15 +67,6 @@ impl SyncState { } } -/// Reported state download progress. -#[derive(Clone, Eq, PartialEq, Debug)] -pub struct StateDownloadProgress { - /// Estimated download percentage. - pub percentage: u32, - /// Total state size in bytes downloaded so far. - pub size: u64, -} - /// Syncing status and statistics. #[derive(Debug, Clone)] pub struct SyncStatus { @@ -92,7 +81,7 @@ pub struct SyncStatus { /// Number of blocks queued for import pub queued_blocks: u32, /// State sync status in progress, if any. - pub state_sync: Option, + pub state_sync: Option, /// Warp sync in progress, if any. pub warp_sync: Option>, } @@ -109,13 +98,6 @@ impl fmt::Display for BadPeer { impl std::error::Error for BadPeer {} -#[derive(Debug)] -pub struct Metrics { - pub queued_blocks: u32, - pub fork_targets: u32, - pub justifications: crate::request_metrics::Metrics, -} - #[derive(Debug)] pub enum PeerRequest { Block(BlockRequest), diff --git a/substrate/client/network/sync/src/warp.rs b/substrate/client/network/sync/src/warp.rs deleted file mode 100644 index 169b3de35aa..00000000000 --- a/substrate/client/network/sync/src/warp.rs +++ /dev/null @@ -1,405 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -//! Warp sync support. - -pub use sp_consensus_grandpa::{AuthorityList, SetId}; - -use crate::{ - schema::v1::{StateRequest, StateResponse}, - state::{ImportResult, StateSync}, -}; -use codec::{Decode, Encode}; -use futures::channel::oneshot; -use log::error; -use sc_client_api::ProofProvider; -use sc_network_common::sync::message::{ - BlockAttributes, BlockData, BlockRequest, Direction, FromBlock, -}; -use sp_blockchain::HeaderBackend; -use sp_runtime::traits::{Block as BlockT, Header, NumberFor, Zero}; -use std::{fmt, sync::Arc}; - -/// Log target for this file. -const LOG_TARGET: &'static str = "sync"; - -/// Scale-encoded warp sync proof response. -pub struct EncodedProof(pub Vec); - -/// Warp sync request -#[derive(Encode, Decode, Debug, Clone)] -pub struct WarpProofRequest { - /// Start collecting proofs from this block. - pub begin: B::Hash, -} - -/// Proof verification result. -pub enum VerificationResult { - /// Proof is valid, but the target was not reached. - Partial(SetId, AuthorityList, Block::Hash), - /// Target finality is proved. - Complete(SetId, AuthorityList, Block::Header), -} - -/// Warp sync backend. Handles retrieving and verifying warp sync proofs. -pub trait WarpSyncProvider: Send + Sync { - /// Generate proof starting at given block hash. The proof is accumulated until maximum proof - /// size is reached. - fn generate( - &self, - start: Block::Hash, - ) -> Result>; - /// Verify warp proof against current set of authorities. - fn verify( - &self, - proof: &EncodedProof, - set_id: SetId, - authorities: AuthorityList, - ) -> Result, Box>; - /// Get current list of authorities. This is supposed to be genesis authorities when starting - /// sync. - fn current_authorities(&self) -> AuthorityList; -} - -/// Reported warp sync phase. -#[derive(Clone, Eq, PartialEq, Debug)] -pub enum WarpSyncPhase { - /// Waiting for peers to connect. - AwaitingPeers { required_peers: usize }, - /// Waiting for target block to be received. - AwaitingTargetBlock, - /// Downloading and verifying grandpa warp proofs. - DownloadingWarpProofs, - /// Downloading target block. - DownloadingTargetBlock, - /// Downloading state data. - DownloadingState, - /// Importing state. - ImportingState, - /// Downloading block history. - DownloadingBlocks(NumberFor), -} - -impl fmt::Display for WarpSyncPhase { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::AwaitingPeers { required_peers } => - write!(f, "Waiting for {required_peers} peers to be connected"), - Self::AwaitingTargetBlock => write!(f, "Waiting for target block to be received"), - Self::DownloadingWarpProofs => write!(f, "Downloading finality proofs"), - Self::DownloadingTargetBlock => write!(f, "Downloading target block"), - Self::DownloadingState => write!(f, "Downloading state"), - Self::ImportingState => write!(f, "Importing state"), - Self::DownloadingBlocks(n) => write!(f, "Downloading block history (#{})", n), - } - } -} - -/// Reported warp sync progress. -#[derive(Clone, Eq, PartialEq, Debug)] -pub struct WarpSyncProgress { - /// Estimated download percentage. - pub phase: WarpSyncPhase, - /// Total bytes downloaded so far. - pub total_bytes: u64, -} - -/// The different types of warp syncing, passed to `build_network`. -pub enum WarpSyncParams { - /// Standard warp sync for the chain. - WithProvider(Arc>), - /// Skip downloading proofs and wait for a header of the state that should be downloaded. - /// - /// It is expected that the header provider ensures that the header is trusted. - WaitForTarget(oneshot::Receiver<::Header>), -} - -/// Warp sync configuration as accepted by [`WarpSync`]. -pub enum WarpSyncConfig { - /// Standard warp sync for the chain. - WithProvider(Arc>), - /// Skip downloading proofs and wait for a header of the state that should be downloaded. - /// - /// It is expected that the header provider ensures that the header is trusted. - WaitForTarget, -} - -impl WarpSyncParams { - /// Split `WarpSyncParams` into `WarpSyncConfig` and warp sync target block header receiver. - pub fn split( - self, - ) -> (WarpSyncConfig, Option::Header>>) { - match self { - WarpSyncParams::WithProvider(provider) => - (WarpSyncConfig::WithProvider(provider), None), - WarpSyncParams::WaitForTarget(rx) => (WarpSyncConfig::WaitForTarget, Some(rx)), - } - } -} - -/// Warp sync phase. -enum Phase { - /// Downloading warp proofs. - WarpProof { - set_id: SetId, - authorities: AuthorityList, - last_hash: B::Hash, - warp_sync_provider: Arc>, - }, - /// Waiting for target block to be set externally if we skip warp proofs downloading, - /// and start straight from the target block (used by parachains warp sync). - PendingTargetBlock, - /// Downloading target block. - TargetBlock(B::Header), - /// Downloading state. - State(StateSync), -} - -/// Import warp proof result. -pub enum WarpProofImportResult { - /// Import was successful. - Success, - /// Bad proof. - BadResponse, -} - -/// Import target block result. -pub enum TargetBlockImportResult { - /// Import was successful. - Success, - /// Invalid block. - BadResponse, -} - -/// Warp sync state machine. Accumulates warp proofs and state. -pub struct WarpSync { - phase: Phase, - client: Arc, - total_proof_bytes: u64, -} - -impl WarpSync -where - B: BlockT, - Client: HeaderBackend + ProofProvider + 'static, -{ - /// Create a new instance. When passing a warp sync provider we will be checking for proof and - /// authorities. Alternatively we can pass a target block when we want to skip downloading - /// proofs, in this case we will continue polling until the target block is known. - pub fn new(client: Arc, warp_sync_config: WarpSyncConfig) -> Self { - let last_hash = client.hash(Zero::zero()).unwrap().expect("Genesis header always exists"); - match warp_sync_config { - WarpSyncConfig::WithProvider(warp_sync_provider) => { - let phase = Phase::WarpProof { - set_id: 0, - authorities: warp_sync_provider.current_authorities(), - last_hash, - warp_sync_provider: warp_sync_provider.clone(), - }; - Self { client, phase, total_proof_bytes: 0 } - }, - WarpSyncConfig::WaitForTarget => - Self { client, phase: Phase::PendingTargetBlock, total_proof_bytes: 0 }, - } - } - - /// Set target block externally in case we skip warp proof downloading. - pub fn set_target_block(&mut self, header: B::Header) { - let Phase::PendingTargetBlock = self.phase else { - error!( - target: LOG_TARGET, - "Attempt to set warp sync target block in invalid phase.", - ); - debug_assert!(false); - return - }; - - self.phase = Phase::TargetBlock(header); - } - - /// Validate and import a state response. - pub fn import_state(&mut self, response: StateResponse) -> ImportResult { - match &mut self.phase { - Phase::WarpProof { .. } | Phase::TargetBlock(_) | Phase::PendingTargetBlock { .. } => { - log::debug!(target: "sync", "Unexpected state response"); - ImportResult::BadResponse - }, - Phase::State(sync) => sync.import(response), - } - } - - /// Validate and import a warp proof response. - pub fn import_warp_proof(&mut self, response: EncodedProof) -> WarpProofImportResult { - match &mut self.phase { - Phase::State(_) | Phase::TargetBlock(_) | Phase::PendingTargetBlock { .. } => { - log::debug!(target: "sync", "Unexpected warp proof response"); - WarpProofImportResult::BadResponse - }, - Phase::WarpProof { set_id, authorities, last_hash, warp_sync_provider } => - match warp_sync_provider.verify(&response, *set_id, authorities.clone()) { - Err(e) => { - log::debug!(target: "sync", "Bad warp proof response: {}", e); - WarpProofImportResult::BadResponse - }, - Ok(VerificationResult::Partial(new_set_id, new_authorities, new_last_hash)) => { - log::debug!(target: "sync", "Verified partial proof, set_id={:?}", new_set_id); - *set_id = new_set_id; - *authorities = new_authorities; - *last_hash = new_last_hash; - self.total_proof_bytes += response.0.len() as u64; - WarpProofImportResult::Success - }, - Ok(VerificationResult::Complete(new_set_id, _, header)) => { - log::debug!(target: "sync", "Verified complete proof, set_id={:?}", new_set_id); - self.total_proof_bytes += response.0.len() as u64; - self.phase = Phase::TargetBlock(header); - WarpProofImportResult::Success - }, - }, - } - } - - /// Import the target block body. - pub fn import_target_block(&mut self, block: BlockData) -> TargetBlockImportResult { - match &mut self.phase { - Phase::WarpProof { .. } | Phase::State(_) | Phase::PendingTargetBlock { .. } => { - log::debug!(target: "sync", "Unexpected target block response"); - TargetBlockImportResult::BadResponse - }, - Phase::TargetBlock(header) => - if let Some(block_header) = &block.header { - if block_header == header { - if block.body.is_some() { - let state_sync = StateSync::new( - self.client.clone(), - header.clone(), - block.body, - block.justifications, - false, - ); - self.phase = Phase::State(state_sync); - TargetBlockImportResult::Success - } else { - log::debug!( - target: "sync", - "Importing target block failed: missing body.", - ); - TargetBlockImportResult::BadResponse - } - } else { - log::debug!( - target: "sync", - "Importing target block failed: different header.", - ); - TargetBlockImportResult::BadResponse - } - } else { - log::debug!(target: "sync", "Importing target block failed: missing header."); - TargetBlockImportResult::BadResponse - }, - } - } - - /// Produce next state request. - pub fn next_state_request(&self) -> Option { - match &self.phase { - Phase::WarpProof { .. } | Phase::TargetBlock(_) | Phase::PendingTargetBlock { .. } => - None, - Phase::State(sync) => Some(sync.next_request()), - } - } - - /// Produce next warp proof request. - pub fn next_warp_proof_request(&self) -> Option> { - match &self.phase { - Phase::WarpProof { last_hash, .. } => Some(WarpProofRequest { begin: *last_hash }), - Phase::TargetBlock(_) | Phase::State(_) | Phase::PendingTargetBlock { .. } => None, - } - } - - /// Produce next target block request. - pub fn next_target_block_request(&self) -> Option<(NumberFor, BlockRequest)> { - match &self.phase { - Phase::WarpProof { .. } | Phase::State(_) | Phase::PendingTargetBlock { .. } => None, - Phase::TargetBlock(header) => { - let request = BlockRequest:: { - id: 0, - fields: BlockAttributes::HEADER | - BlockAttributes::BODY | BlockAttributes::JUSTIFICATION, - from: FromBlock::Hash(header.hash()), - direction: Direction::Ascending, - max: Some(1), - }; - Some((*header.number(), request)) - }, - } - } - - /// Return target block hash if it is known. - pub fn target_block_hash(&self) -> Option { - match &self.phase { - Phase::WarpProof { .. } | Phase::TargetBlock(_) | Phase::PendingTargetBlock { .. } => - None, - Phase::State(s) => Some(s.target()), - } - } - - /// Return target block number if it is known. - pub fn target_block_number(&self) -> Option> { - match &self.phase { - Phase::WarpProof { .. } | Phase::PendingTargetBlock { .. } => None, - Phase::TargetBlock(header) => Some(*header.number()), - Phase::State(s) => Some(s.target_block_num()), - } - } - - /// Check if the state is complete. - pub fn is_complete(&self) -> bool { - match &self.phase { - Phase::WarpProof { .. } | Phase::TargetBlock(_) | Phase::PendingTargetBlock { .. } => - false, - Phase::State(sync) => sync.is_complete(), - } - } - - /// Returns state sync estimated progress (percentage, bytes) - pub fn progress(&self) -> WarpSyncProgress { - match &self.phase { - Phase::WarpProof { .. } => WarpSyncProgress { - phase: WarpSyncPhase::DownloadingWarpProofs, - total_bytes: self.total_proof_bytes, - }, - Phase::TargetBlock(_) => WarpSyncProgress { - phase: WarpSyncPhase::DownloadingTargetBlock, - total_bytes: self.total_proof_bytes, - }, - Phase::PendingTargetBlock { .. } => WarpSyncProgress { - phase: WarpSyncPhase::AwaitingTargetBlock, - total_bytes: self.total_proof_bytes, - }, - Phase::State(sync) => WarpSyncProgress { - phase: if self.is_complete() { - WarpSyncPhase::ImportingState - } else { - WarpSyncPhase::DownloadingState - }, - total_bytes: self.total_proof_bytes + sync.progress().size, - }, - } - } -} diff --git a/substrate/client/network/sync/src/warp_request_handler.rs b/substrate/client/network/sync/src/warp_request_handler.rs index b23f30c50dd..39cf1c5d806 100644 --- a/substrate/client/network/sync/src/warp_request_handler.rs +++ b/substrate/client/network/sync/src/warp_request_handler.rs @@ -20,7 +20,10 @@ use codec::Decode; use futures::{channel::oneshot, stream::StreamExt}; use log::debug; -use crate::warp::{EncodedProof, WarpProofRequest, WarpSyncProvider}; +use crate::{ + strategy::warp::{EncodedProof, WarpProofRequest, WarpSyncProvider}, + LOG_TARGET, +}; use sc_network::{ config::ProtocolId, request_responses::{ @@ -120,10 +123,10 @@ impl RequestHandler { match self.handle_request(payload, pending_response) { Ok(()) => { - debug!(target: "sync", "Handled grandpa warp sync request from {}.", peer) + debug!(target: LOG_TARGET, "Handled grandpa warp sync request from {}.", peer) }, Err(e) => debug!( - target: "sync", + target: LOG_TARGET, "Failed to handle grandpa warp sync request from {}: {}", peer, e, ), diff --git a/substrate/client/network/test/src/lib.rs b/substrate/client/network/test/src/lib.rs index 71f13b74a53..aeed2985ace 100644 --- a/substrate/client/network/test/src/lib.rs +++ b/substrate/client/network/test/src/lib.rs @@ -66,7 +66,7 @@ use sc_network_sync::{ block_request_handler::BlockRequestHandler, service::{network::NetworkServiceProvider, syncing_service::SyncingService}, state_request_handler::StateRequestHandler, - warp::{ + strategy::warp::{ AuthorityList, EncodedProof, SetId, VerificationResult, WarpSyncParams, WarpSyncProvider, }, warp_request_handler, @@ -699,6 +699,8 @@ pub struct FullPeerConfig { pub storage_chain: bool, /// Optional target block header to sync to pub target_block: Option<::Header>, + /// Force genesis even in case of warp & light state sync. + pub force_genesis: bool, } #[async_trait::async_trait] @@ -758,7 +760,9 @@ pub trait TestNetFactory: Default + Sized + Send { *genesis_extra_storage = storage; } - if matches!(config.sync_mode, SyncMode::LightState { .. } | SyncMode::Warp) { + if !config.force_genesis && + matches!(config.sync_mode, SyncMode::LightState { .. } | SyncMode::Warp) + { test_client_builder = test_client_builder.set_no_genesis(); } let backend = test_client_builder.backend(); diff --git a/substrate/client/network/test/src/sync.rs b/substrate/client/network/test/src/sync.rs index f2be662ada1..c025a8262f0 100644 --- a/substrate/client/network/test/src/sync.rs +++ b/substrate/client/network/test/src/sync.rs @@ -1232,12 +1232,14 @@ async fn warp_sync() { let target = net.peer(0).push_blocks(1, false).pop().unwrap(); net.peer(1).push_blocks(64, false); net.peer(2).push_blocks(64, false); - // Wait for peer 1 to sync state. + // Wait for peer 3 to sync state. net.run_until_sync().await; + // Make sure it was not a full sync. assert!(!net.peer(3).client().has_state_at(&BlockId::Number(1))); + // Make sure warp sync was successful. assert!(net.peer(3).client().has_state_at(&BlockId::Number(64))); - // Wait for peer 1 download block history + // Wait for peer 3 to download block history (gap sync). futures::future::poll_fn::<(), _>(|cx| { net.poll(cx); if net.peer(3).has_body(gap_end) && net.peer(3).has_body(target) { @@ -1249,6 +1251,35 @@ async fn warp_sync() { .await; } +/// If there is a finalized state in the DB, warp sync falls back to full sync. +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn warp_sync_failover_to_full_sync() { + sp_tracing::try_init_simple(); + let mut net = TestNet::new(0); + // Create 3 synced peers and 1 peer trying to warp sync. + net.add_full_peer_with_config(Default::default()); + net.add_full_peer_with_config(Default::default()); + net.add_full_peer_with_config(Default::default()); + net.add_full_peer_with_config(FullPeerConfig { + sync_mode: SyncMode::Warp, + // We want some finalized state in the DB to make warp sync impossible. + force_genesis: true, + ..Default::default() + }); + net.peer(0).push_blocks(64, false); + net.peer(1).push_blocks(64, false); + net.peer(2).push_blocks(64, false); + // Even though we requested peer 3 to warp sync, it'll fall back to full sync if there is + // a finalized state in the DB. + assert!(net.peer(3).client().info().finalized_state.is_some()); + // Wait for peer 3 to sync. + net.run_until_sync().await; + // Make sure it was a full sync (peer 3 has state for all blocks). + (1..65) + .into_iter() + .for_each(|i| assert!(net.peer(3).client().has_state_at(&BlockId::Number(i as u64)))); +} + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn warp_sync_to_target_block() { sp_tracing::try_init_simple(); diff --git a/substrate/client/service/src/builder.rs b/substrate/client/service/src/builder.rs index 1a3a679c519..0b8c86be92b 100644 --- a/substrate/client/service/src/builder.rs +++ b/substrate/client/service/src/builder.rs @@ -52,8 +52,8 @@ use sc_network_light::light_client_requests::handler::LightClientRequestHandler; use sc_network_sync::{ block_relay_protocol::BlockRelayParams, block_request_handler::BlockRequestHandler, engine::SyncingEngine, service::network::NetworkServiceProvider, - state_request_handler::StateRequestHandler, warp::WarpSyncParams, - warp_request_handler::RequestHandler as WarpSyncRequestHandler, SyncingService, + state_request_handler::StateRequestHandler, + warp_request_handler::RequestHandler as WarpSyncRequestHandler, SyncingService, WarpSyncParams, }; use sc_rpc::{ author::AuthorApiServer, diff --git a/substrate/client/service/src/lib.rs b/substrate/client/service/src/lib.rs index 0c7e138ce90..bec1044daab 100644 --- a/substrate/client/service/src/lib.rs +++ b/substrate/client/service/src/lib.rs @@ -77,7 +77,7 @@ pub use sc_chain_spec::{ pub use sc_consensus::ImportQueue; pub use sc_executor::NativeExecutionDispatch; -pub use sc_network_sync::warp::WarpSyncParams; +pub use sc_network_sync::WarpSyncParams; #[doc(hidden)] pub use sc_network_transactions::config::{TransactionImport, TransactionImportFuture}; pub use sc_rpc::{ diff --git a/substrate/zombienet/0001-basic-warp-sync/test-warp-sync.zndsl b/substrate/zombienet/0001-basic-warp-sync/test-warp-sync.zndsl index bafdb7d72bb..c5644797321 100644 --- a/substrate/zombienet/0001-basic-warp-sync/test-warp-sync.zndsl +++ b/substrate/zombienet/0001-basic-warp-sync/test-warp-sync.zndsl @@ -22,6 +22,8 @@ dave: reports block height is at least 1 within 60 seconds dave: reports block height is at least {{DB_BLOCK_HEIGHT}} within 60 seconds dave: log line matches "Warp sync is complete" within 60 seconds +# State sync is logically part of warp sync +dave: log line matches "State sync is complete" within 60 seconds dave: log line matches "Block history download is complete" within 10 seconds dave: count of log lines containing "error" is 0 within 10 seconds diff --git a/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.zndsl b/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.zndsl index 3977eb6788a..6e733580d6d 100644 --- a/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.zndsl +++ b/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.zndsl @@ -21,6 +21,9 @@ eve: reports block height is at least {{DB_BLOCK_HEIGHT}} within 60 seconds alice: log line matches "Warp sync is complete" within 60 seconds bob: log line matches "Warp sync is complete" within 60 seconds +# State sync is logically part of warp sync +alice: log line matches "State sync is complete" within 60 seconds +bob: log line matches "State sync is complete" within 60 seconds alice: log line matches "Block history download is complete" within 120 seconds bob: log line matches "Block history download is complete" within 120 seconds diff --git a/substrate/zombienet/0003-block-building-warp-sync/test-block-building-warp-sync.zndsl b/substrate/zombienet/0003-block-building-warp-sync/test-block-building-warp-sync.zndsl index 1d8650b5d69..a9a0ce442f1 100644 --- a/substrate/zombienet/0003-block-building-warp-sync/test-block-building-warp-sync.zndsl +++ b/substrate/zombienet/0003-block-building-warp-sync/test-block-building-warp-sync.zndsl @@ -27,6 +27,8 @@ dave: reports block height is at least {{DB_BLOCK_HEIGHT}} within 60 seconds dave: reports block height is greater than {{DB_BLOCK_HEIGHT}} within 60 seconds dave: log line matches "Warp sync is complete" within 60 seconds +# State sync is logically part of warp sync +dave: log line matches "State sync is complete" within 60 seconds dave: log line matches "Block history download is complete" within 10 seconds dave: reports substrate_beefy_best_block is at least {{DB_BLOCK_HEIGHT}} within 180 seconds -- GitLab From c421b87978404954dec4555895d50ef028b73cf0 Mon Sep 17 00:00:00 2001 From: Javier Viola Date: Fri, 12 Jan 2024 14:33:32 -0300 Subject: [PATCH 045/392] Bump zombienet version `v1.3.91` (#2912) This version includes - Performance improvements. - Minor fixes. --- .gitlab/pipeline/zombienet.yml | 2 +- .../zombienet_tests/functional/0002-parachains-disputes.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab/pipeline/zombienet.yml b/.gitlab/pipeline/zombienet.yml index 4b95c86c3c4..55120e66d0e 100644 --- a/.gitlab/pipeline/zombienet.yml +++ b/.gitlab/pipeline/zombienet.yml @@ -1,7 +1,7 @@ .zombienet-refs: extends: .build-refs variables: - ZOMBIENET_IMAGE: "docker.io/paritytech/zombienet:v1.3.86" + ZOMBIENET_IMAGE: "docker.io/paritytech/zombienet:v1.3.91" include: # substrate tests diff --git a/polkadot/zombienet_tests/functional/0002-parachains-disputes.toml b/polkadot/zombienet_tests/functional/0002-parachains-disputes.toml index 27cd81dface..f6bdfeb4877 100644 --- a/polkadot/zombienet_tests/functional/0002-parachains-disputes.toml +++ b/polkadot/zombienet_tests/functional/0002-parachains-disputes.toml @@ -5,7 +5,7 @@ timeout = 1000 max_validators_per_core = 5 needed_approvals = 8 -[relaychain.genesis.runtime.runtime_genesis_config.configuration.config.approval_voting_params] +[relaychain.genesis.runtimeGenesis.patch.configuration.config.approval_voting_params] max_approval_coalesce_count = 5 -- GitLab From bd80dcf6858a0ec9e61b5aceab933979f7258d2b Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Fri, 12 Jan 2024 21:10:54 +0100 Subject: [PATCH 046/392] Contracts: Translate .wat fixtures to rust (#2654) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Translate all pallet-contracts fixtures from `wat` to Rust files. - Fix read_sandbox_memory_as to not use MaxEncodedLen as this could break if used with types with a non-fixed encoded len. --------- Co-authored-by: alvicsam Co-authored-by: Alexander Samusev <41779041+alvicsam@users.noreply.github.com> Co-authored-by: Alexander Theißen Co-authored-by: command-bot <> --- .../account_reentrance_count_call.rs | 39 +++ .../add_remove_delegate_dependency.rs | 70 +++++ .../contracts/fixtures/contracts/balance.rs | 36 +++ .../contracts/fixtures/contracts/call.rs | 25 +- .../fixtures/contracts/call_return_code.rs | 54 ++++ .../fixtures/contracts/call_runtime.rs | 42 +++ .../contracts/call_runtime_and_call.rs | 51 ++++ .../fixtures/contracts/call_with_limit.rs | 51 ++++ .../fixtures/contracts/caller_contract.rs | 153 ++++++++++ .../fixtures/contracts/chain_extension.rs | 42 +++ .../contracts/chain_extension_temp_storage.rs | 63 ++++ .../fixtures/contracts/common/Cargo.toml | 3 + .../fixtures/contracts/common/src/lib.rs | 122 +++++++- .../contracts/create_storage_and_call.rs | 59 ++++ .../create_storage_and_instantiate.rs | 59 ++++ .../fixtures/contracts/crypto_hashes.rs | 84 +++++ .../contracts/debug_message_invalid_utf8.rs | 33 ++ .../debug_message_logging_disabled.rs | 33 ++ .../fixtures/contracts/debug_message_works.rs | 33 ++ .../fixtures/contracts/delegate_call.rs | 49 +++ .../fixtures/contracts/delegate_call_lib.rs | 49 +++ .../contracts/delegate_call_simple.rs | 36 +++ .../contracts/destroy_and_transfer.rs | 89 ++++++ .../contracts/fixtures/contracts/drain.rs | 44 +++ .../fixtures/contracts/ecdsa_recover.rs | 44 +++ .../contracts/event_and_return_on_deploy.rs | 36 +++ .../fixtures/contracts/event_size.rs | 37 +++ .../fixtures/contracts/float_instruction.rs | 34 +++ .../contracts/instantiate_return_code.rs | 53 ++++ .../contracts/invalid_contract_no_call.rs | 25 ++ .../fixtures/contracts/multi_store.rs | 43 +++ .../contracts/new_set_code_hash_contract.rs | 32 ++ .../fixtures/contracts/ok_trap_revert.rs | 44 +++ .../contracts/reentrance_count_call.rs | 55 ++++ .../reentrance_count_delegated_call.rs | 53 ++++ .../fixtures/contracts/return_with_data.rs | 43 +++ .../fixtures/contracts/run_out_of_gas.rs | 32 ++ .../fixtures/contracts/self_destruct.rs | 53 ++++ .../contracts/self_destructing_constructor.rs | 32 ++ .../fixtures/contracts/set_code_hash.rs | 37 +++ .../fixtures/contracts/set_empty_storage.rs | 32 ++ .../fixtures/contracts/sr25519_verify.rs | 48 +++ .../fixtures/contracts/storage_size.rs | 45 +++ .../fixtures/contracts/store_call.rs | 41 +++ .../fixtures/contracts/store_deploy.rs | 41 +++ .../contracts/transfer_return_code.rs | 38 +++ .../fixtures/contracts/xcm_execute.rs | 39 +++ .../contracts/fixtures/contracts/xcm_send.rs | 42 +++ .../data/account_reentrance_count_call.wat | 37 --- .../data/add_remove_delegate_dependency.wat | 111 ------- .../frame/contracts/fixtures/data/balance.wat | 42 --- .../fixtures/data/call_return_code.wat | 42 --- .../contracts/fixtures/data/call_runtime.wat | 33 -- .../fixtures/data/call_runtime_and_call.wat | 56 ---- .../fixtures/data/call_with_limit.wat | 38 --- .../fixtures/data/caller_contract.wat | 286 ------------------ .../fixtures/data/chain_extension.wat | 46 --- .../data/chain_extension_temp_storage.wat | 85 ------ .../fixtures/data/create_storage_and_call.wat | 60 ---- .../data/create_storage_and_instantiate.wat | 66 ---- .../contracts/fixtures/data/crypto_hashes.wat | 83 ----- .../data/debug_message_invalid_utf8.wat | 28 -- .../data/debug_message_logging_disabled.wat | 28 -- .../fixtures/data/debug_message_works.wat | 28 -- .../contracts/fixtures/data/delegate_call.wat | 111 ------- .../fixtures/data/delegate_call_lib.wat | 79 ----- .../fixtures/data/delegate_call_simple.wat | 50 --- .../fixtures/data/destroy_and_transfer.wat | 161 ---------- .../frame/contracts/fixtures/data/drain.wat | 75 ----- .../contracts/fixtures/data/ecdsa_recover.wat | 55 ---- .../data/event_and_return_on_deploy.wat | 26 -- .../contracts/fixtures/data/event_size.wat | 39 --- .../fixtures/data/float_instruction.wat | 12 - .../fixtures/data/instantiate_return_code.wat | 47 --- .../data/invalid_contract_no_call.wat | 5 - .../contracts/fixtures/data/multi_store.wat | 54 ---- .../data/new_set_code_hash_contract.wat | 13 - .../fixtures/data/ok_trap_revert.wat | 35 --- .../fixtures/data/reentrance_count_call.wat | 76 ----- .../data/reentrance_count_delegated_call.wat | 71 ----- .../fixtures/data/return_with_data.wat | 33 -- .../fixtures/data/run_out_of_gas.wat | 8 - .../contracts/fixtures/data/self_destruct.wat | 83 ----- .../data/self_destructing_constructor.wat | 23 -- .../contracts/fixtures/data/set_code_hash.wat | 43 --- .../fixtures/data/set_empty_storage.wat | 15 - .../fixtures/data/sr25519_verify.wat | 55 ---- .../contracts/fixtures/data/storage_size.wat | 68 ----- .../contracts/fixtures/data/store_call.wat | 45 --- .../contracts/fixtures/data/store_deploy.wat | 45 --- .../fixtures/data/transfer_return_code.wat | 34 --- .../contracts/fixtures/data/xcm_execute.wat | 52 ---- .../contracts/fixtures/data/xcm_send.wat | 59 ---- substrate/frame/contracts/fixtures/src/lib.rs | 5 +- substrate/frame/contracts/src/tests.rs | 17 +- substrate/frame/contracts/src/wasm/mod.rs | 18 +- substrate/frame/contracts/src/wasm/runtime.rs | 5 +- substrate/frame/contracts/uapi/src/host.rs | 23 +- .../frame/contracts/uapi/src/host/riscv32.rs | 18 +- .../frame/contracts/uapi/src/host/wasm32.rs | 27 +- substrate/frame/contracts/uapi/src/lib.rs | 2 +- 101 files changed, 2352 insertions(+), 2602 deletions(-) create mode 100644 substrate/frame/contracts/fixtures/contracts/account_reentrance_count_call.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/add_remove_delegate_dependency.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/balance.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/call_return_code.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/call_runtime.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/call_runtime_and_call.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/call_with_limit.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/caller_contract.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/chain_extension.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/chain_extension_temp_storage.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/create_storage_and_call.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/create_storage_and_instantiate.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/crypto_hashes.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/debug_message_invalid_utf8.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/debug_message_logging_disabled.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/debug_message_works.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/delegate_call.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/delegate_call_lib.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/delegate_call_simple.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/destroy_and_transfer.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/drain.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/ecdsa_recover.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/event_and_return_on_deploy.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/event_size.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/float_instruction.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/instantiate_return_code.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/invalid_contract_no_call.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/multi_store.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/new_set_code_hash_contract.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/ok_trap_revert.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/reentrance_count_call.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/reentrance_count_delegated_call.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/return_with_data.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/run_out_of_gas.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/self_destruct.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/self_destructing_constructor.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/set_code_hash.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/set_empty_storage.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/sr25519_verify.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/storage_size.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/store_call.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/store_deploy.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/transfer_return_code.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/xcm_execute.rs create mode 100644 substrate/frame/contracts/fixtures/contracts/xcm_send.rs delete mode 100644 substrate/frame/contracts/fixtures/data/account_reentrance_count_call.wat delete mode 100644 substrate/frame/contracts/fixtures/data/add_remove_delegate_dependency.wat delete mode 100644 substrate/frame/contracts/fixtures/data/balance.wat delete mode 100644 substrate/frame/contracts/fixtures/data/call_return_code.wat delete mode 100644 substrate/frame/contracts/fixtures/data/call_runtime.wat delete mode 100644 substrate/frame/contracts/fixtures/data/call_runtime_and_call.wat delete mode 100644 substrate/frame/contracts/fixtures/data/call_with_limit.wat delete mode 100644 substrate/frame/contracts/fixtures/data/caller_contract.wat delete mode 100644 substrate/frame/contracts/fixtures/data/chain_extension.wat delete mode 100644 substrate/frame/contracts/fixtures/data/chain_extension_temp_storage.wat delete mode 100644 substrate/frame/contracts/fixtures/data/create_storage_and_call.wat delete mode 100644 substrate/frame/contracts/fixtures/data/create_storage_and_instantiate.wat delete mode 100644 substrate/frame/contracts/fixtures/data/crypto_hashes.wat delete mode 100644 substrate/frame/contracts/fixtures/data/debug_message_invalid_utf8.wat delete mode 100644 substrate/frame/contracts/fixtures/data/debug_message_logging_disabled.wat delete mode 100644 substrate/frame/contracts/fixtures/data/debug_message_works.wat delete mode 100644 substrate/frame/contracts/fixtures/data/delegate_call.wat delete mode 100644 substrate/frame/contracts/fixtures/data/delegate_call_lib.wat delete mode 100644 substrate/frame/contracts/fixtures/data/delegate_call_simple.wat delete mode 100644 substrate/frame/contracts/fixtures/data/destroy_and_transfer.wat delete mode 100644 substrate/frame/contracts/fixtures/data/drain.wat delete mode 100644 substrate/frame/contracts/fixtures/data/ecdsa_recover.wat delete mode 100644 substrate/frame/contracts/fixtures/data/event_and_return_on_deploy.wat delete mode 100644 substrate/frame/contracts/fixtures/data/event_size.wat delete mode 100644 substrate/frame/contracts/fixtures/data/float_instruction.wat delete mode 100644 substrate/frame/contracts/fixtures/data/instantiate_return_code.wat delete mode 100644 substrate/frame/contracts/fixtures/data/invalid_contract_no_call.wat delete mode 100644 substrate/frame/contracts/fixtures/data/multi_store.wat delete mode 100644 substrate/frame/contracts/fixtures/data/new_set_code_hash_contract.wat delete mode 100644 substrate/frame/contracts/fixtures/data/ok_trap_revert.wat delete mode 100644 substrate/frame/contracts/fixtures/data/reentrance_count_call.wat delete mode 100644 substrate/frame/contracts/fixtures/data/reentrance_count_delegated_call.wat delete mode 100644 substrate/frame/contracts/fixtures/data/return_with_data.wat delete mode 100644 substrate/frame/contracts/fixtures/data/run_out_of_gas.wat delete mode 100644 substrate/frame/contracts/fixtures/data/self_destruct.wat delete mode 100644 substrate/frame/contracts/fixtures/data/self_destructing_constructor.wat delete mode 100644 substrate/frame/contracts/fixtures/data/set_code_hash.wat delete mode 100644 substrate/frame/contracts/fixtures/data/set_empty_storage.wat delete mode 100644 substrate/frame/contracts/fixtures/data/sr25519_verify.wat delete mode 100644 substrate/frame/contracts/fixtures/data/storage_size.wat delete mode 100644 substrate/frame/contracts/fixtures/data/store_call.wat delete mode 100644 substrate/frame/contracts/fixtures/data/store_deploy.wat delete mode 100644 substrate/frame/contracts/fixtures/data/transfer_return_code.wat delete mode 100644 substrate/frame/contracts/fixtures/data/xcm_execute.wat delete mode 100644 substrate/frame/contracts/fixtures/data/xcm_send.wat diff --git a/substrate/frame/contracts/fixtures/contracts/account_reentrance_count_call.rs b/substrate/frame/contracts/fixtures/contracts/account_reentrance_count_call.rs new file mode 100644 index 00000000000..9da4eb6d538 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/account_reentrance_count_call.rs @@ -0,0 +1,39 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! This fixture tests if account_reentrance_count works as expected. +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!(callee: [u8; 32],); + + #[allow(deprecated)] + let reentrance_count = api::account_reentrance_count(callee); + + // Return the reentrance count. + api::return_value(uapi::ReturnFlags::empty(), &reentrance_count.to_le_bytes()); +} diff --git a/substrate/frame/contracts/fixtures/contracts/add_remove_delegate_dependency.rs b/substrate/frame/contracts/fixtures/contracts/add_remove_delegate_dependency.rs new file mode 100644 index 00000000000..759ff799374 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/add_remove_delegate_dependency.rs @@ -0,0 +1,70 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! This contract tests the behavior of adding / removing delegate_dependencies when delegate +//! calling into a contract. +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +const ALICE: [u8; 32] = [1u8; 32]; + +/// Load input data and perform the action specified by the input. +/// If `delegate_call` is true, then delegate call into the contract. +fn load_input(delegate_call: bool) { + input!( + action: u32, + code_hash: [u8; 32], + ); + + match action { + // 1 = Add delegate dependency + 1 => { + #[allow(deprecated)] + api::add_delegate_dependency(code_hash); + }, + // 2 = Remove delegate dependency + 2 => { + #[allow(deprecated)] + api::remove_delegate_dependency(code_hash); + }, + // 3 = Terminate + 3 => { + api::terminate_v1(&ALICE); + }, + // Everything else is a noop + _ => {}, + } + + if delegate_call { + api::delegate_call(uapi::CallFlags::empty(), code_hash, &[], None).unwrap(); + } +} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() { + load_input(false); +} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + load_input(true); +} diff --git a/substrate/frame/contracts/fixtures/contracts/balance.rs b/substrate/frame/contracts/fixtures/contracts/balance.rs new file mode 100644 index 00000000000..4011b8379cb --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/balance.rs @@ -0,0 +1,36 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::output; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + // Initialize buffer with 1s so that we can check that it is overwritten. + output!(balance, [1u8; 8], api::balance,); + + // Assert that the balance is 0. + assert_eq!(&[0u8; 8], balance); +} diff --git a/substrate/frame/contracts/fixtures/contracts/call.rs b/substrate/frame/contracts/fixtures/contracts/call.rs index 0e5f4fbd2dd..f7d9d862d74 100644 --- a/substrate/frame/contracts/fixtures/contracts/call.rs +++ b/substrate/frame/contracts/fixtures/contracts/call.rs @@ -19,8 +19,8 @@ #![no_std] #![no_main] -extern crate common; -use uapi::{CallFlags, HostFn, HostFnImpl as api}; +use common::input; +use uapi::{HostFn, HostFnImpl as api}; #[no_mangle] #[polkavm_derive::polkavm_export] @@ -29,21 +29,18 @@ pub extern "C" fn deploy() {} #[no_mangle] #[polkavm_derive::polkavm_export] pub extern "C" fn call() { - let mut buffer = [0u8; 40]; - let callee_input = 0..4; - let callee_addr = 4..36; - let value = 36..40; - - // Read the input data. - api::input(&mut &mut buffer[..]); + input!( + callee_input: [u8; 4], + callee_addr: [u8; 32], + ); // Call the callee api::call_v1( - CallFlags::empty(), - &buffer[callee_addr], - 0u64, // How much gas to devote for the execution. 0 = all. - &buffer[value], - &buffer[callee_input], + uapi::CallFlags::empty(), + callee_addr, + 0u64, // How much gas to devote for the execution. 0 = all. + &0u64.to_le_bytes(), // value transferred to the contract. + callee_input, None, ) .unwrap(); diff --git a/substrate/frame/contracts/fixtures/contracts/call_return_code.rs b/substrate/frame/contracts/fixtures/contracts/call_return_code.rs new file mode 100644 index 00000000000..1256588d3b5 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/call_return_code.rs @@ -0,0 +1,54 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! This calls the supplied dest and transfers 100 balance during this call and copies +//! the return code of this call to the output buffer. +//! It also forwards its input to the callee. +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!( + 100, + callee_addr: [u8; 32], + input: [u8], + ); + + // Call the callee + let err_code = match api::call_v1( + uapi::CallFlags::empty(), + callee_addr, + 0u64, // How much gas to devote for the execution. 0 = all. + &100u64.to_le_bytes(), // value transferred to the contract. + input, + None, + ) { + Ok(_) => 0u32, + Err(code) => code as u32, + }; + + api::return_value(uapi::ReturnFlags::empty(), &err_code.to_le_bytes()); +} diff --git a/substrate/frame/contracts/fixtures/contracts/call_runtime.rs b/substrate/frame/contracts/fixtures/contracts/call_runtime.rs new file mode 100644 index 00000000000..2b132398fb6 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/call_runtime.rs @@ -0,0 +1,42 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! This passes its input to `call_runtime` and returns the return value to its caller. +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + // Fixture calls should fit into 100 bytes. + input!(100, call: [u8], ); + + // Use the call passed as input to call the runtime. + let err_code = match api::call_runtime(call) { + Ok(_) => 0u32, + Err(code) => code as u32, + }; + + api::return_value(uapi::ReturnFlags::empty(), &err_code.to_le_bytes()); +} diff --git a/substrate/frame/contracts/fixtures/contracts/call_runtime_and_call.rs b/substrate/frame/contracts/fixtures/contracts/call_runtime_and_call.rs new file mode 100644 index 00000000000..fdeb6097e73 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/call_runtime_and_call.rs @@ -0,0 +1,51 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!( + 512, + callee_input: [u8; 4], + callee_addr: [u8; 32], + call: [u8], + ); + + // Use the call passed as input to call the runtime. + api::call_runtime(call).unwrap(); + + // Call the callee + api::call_v1( + uapi::CallFlags::empty(), + callee_addr, + 0u64, // How much gas to devote for the execution. 0 = all. + &0u64.to_le_bytes(), // value transferred to the contract. + callee_input, + None, + ) + .unwrap(); +} diff --git a/substrate/frame/contracts/fixtures/contracts/call_with_limit.rs b/substrate/frame/contracts/fixtures/contracts/call_with_limit.rs new file mode 100644 index 00000000000..5e98aa614e9 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/call_with_limit.rs @@ -0,0 +1,51 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! This fixture calls the account_id with the 2D Weight limit. +//! It returns the result of the call as output data. +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!( + callee_addr: [u8; 32], + ref_time: u64, + proof_size: u64, + ); + + #[allow(deprecated)] + api::call_v2( + uapi::CallFlags::empty(), + callee_addr, + ref_time, + proof_size, + None, // No deposit limit. + &0u64.to_le_bytes(), // value transferred to the contract. + &[0u8; 0], // input data. + None, + ) + .unwrap(); +} diff --git a/substrate/frame/contracts/fixtures/contracts/caller_contract.rs b/substrate/frame/contracts/fixtures/contracts/caller_contract.rs new file mode 100644 index 00000000000..c2629e9fa19 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/caller_contract.rs @@ -0,0 +1,153 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api, ReturnErrorCode}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!(code_hash: [u8; 32],); + + // The value to transfer on instantiation and calls. Chosen to be greater than existential + // deposit. + let value = 32768u64.to_le_bytes(); + let salt = [0u8; 0]; + + // Callee will use the first 4 bytes of the input to return an exit status. + let input = [0u8, 1, 34, 51, 68, 85, 102, 119]; + let reverted_input = [1u8, 34, 51, 68, 85, 102, 119]; + + // Fail to deploy the contract since it returns a non-zero exit status. + #[allow(deprecated)] + let res = api::instantiate_v2( + code_hash, + 0u64, // How much ref_time weight to devote for the execution. 0 = all. + 0u64, // How much proof_size weight to devote for the execution. 0 = all. + None, // No deposit limit. + &value, + &reverted_input, + None, + None, + &salt, + ); + assert!(matches!(res, Err(ReturnErrorCode::CalleeReverted))); + + // Fail to deploy the contract due to insufficient ref_time weight. + #[allow(deprecated)] + let res = api::instantiate_v2( + code_hash, 1u64, // too little ref_time weight + 0u64, // How much proof_size weight to devote for the execution. 0 = all. + None, // No deposit limit. + &value, &input, None, None, &salt, + ); + assert!(matches!(res, Err(ReturnErrorCode::CalleeTrapped))); + + // Fail to deploy the contract due to insufficient proof_size weight. + #[allow(deprecated)] + let res = api::instantiate_v2( + code_hash, 0u64, // How much ref_time weight to devote for the execution. 0 = all. + 1u64, // Too little proof_size weight + None, // No deposit limit. + &value, &input, None, None, &salt, + ); + assert!(matches!(res, Err(ReturnErrorCode::CalleeTrapped))); + + // Deploy the contract successfully. + let mut callee = [0u8; 32]; + let callee = &mut &mut callee[..]; + + #[allow(deprecated)] + api::instantiate_v2( + code_hash, + 0u64, // How much ref_time weight to devote for the execution. 0 = all. + 0u64, // How much proof_size weight to devote for the execution. 0 = all. + None, // No deposit limit. + &value, + &input, + Some(callee), + None, + &salt, + ) + .unwrap(); + assert_eq!(callee.len(), 32); + + // Call the new contract and expect it to return failing exit code. + #[allow(deprecated)] + let res = api::call_v2( + uapi::CallFlags::empty(), + callee, + 0u64, // How much ref_time weight to devote for the execution. 0 = all. + 0u64, // How much proof_size weight to devote for the execution. 0 = all. + None, // No deposit limit. + &value, + &reverted_input, + None, + ); + assert!(matches!(res, Err(ReturnErrorCode::CalleeReverted))); + + // Fail to call the contract due to insufficient ref_time weight. + #[allow(deprecated)] + let res = api::call_v2( + uapi::CallFlags::empty(), + callee, + 1u64, // too little ref_time weight + 0u64, // How much proof_size weight to devote for the execution. 0 = all. + None, // No deposit limit. + &value, + &input, + None, + ); + assert!(matches!(res, Err(ReturnErrorCode::CalleeTrapped))); + + // Fail to call the contract due to insufficient proof_size weight. + #[allow(deprecated)] + let res = api::call_v2( + uapi::CallFlags::empty(), + callee, + 0u64, // How much ref_time weight to devote for the execution. 0 = all. + 1u64, // too little proof_size weight + None, // No deposit limit. + &value, + &input, + None, + ); + assert!(matches!(res, Err(ReturnErrorCode::CalleeTrapped))); + + // Call the contract successfully. + let mut output = [0u8; 4]; + #[allow(deprecated)] + api::call_v2( + uapi::CallFlags::empty(), + callee, + 0u64, // How much ref_time weight to devote for the execution. 0 = all. + 0u64, // How much proof_size weight to devote for the execution. 0 = all. + None, // No deposit limit. + &value, + &input, + Some(&mut &mut output[..]), + ) + .unwrap(); + assert_eq!(&output, &input[4..]) +} diff --git a/substrate/frame/contracts/fixtures/contracts/chain_extension.rs b/substrate/frame/contracts/fixtures/contracts/chain_extension.rs new file mode 100644 index 00000000000..474df00d691 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/chain_extension.rs @@ -0,0 +1,42 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Call chain extension by passing through input and output of this contract. +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!(input, 8, func_id: u32,); + + // the chain extension passes through the input and returns it as output + let mut output_buffer = [0u8; 32]; + let output = &mut &mut output_buffer[0..input.len()]; + + let ret_id = api::call_chain_extension(func_id, input, Some(output)); + assert_eq!(ret_id, func_id); + + api::return_value(uapi::ReturnFlags::empty(), output); +} diff --git a/substrate/frame/contracts/fixtures/contracts/chain_extension_temp_storage.rs b/substrate/frame/contracts/fixtures/contracts/chain_extension_temp_storage.rs new file mode 100644 index 00000000000..1ab08efb3c7 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/chain_extension_temp_storage.rs @@ -0,0 +1,63 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Call chain extension two times with the specified func_ids +//! It then calls itself once +#![no_std] +#![no_main] + +use common::{input, output}; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!( + input, + func_id1: u32, + func_id2: u32, + stop_recurse: u8, + ); + + api::call_chain_extension(func_id1, input, None); + api::call_chain_extension(func_id2, input, None); + + if stop_recurse == 0 { + // Setup next call + input[0..4].copy_from_slice(&((3 << 16) | 2u32).to_le_bytes()); + input[4..8].copy_from_slice(&((3 << 16) | 3u32).to_le_bytes()); + input[8] = 1u8; + + // Read the contract address. + output!(addr, [0u8; 32], api::address,); + + // call self + api::call_v1( + uapi::CallFlags::ALLOW_REENTRY, + addr, + 0u64, // How much gas to devote for the execution. 0 = all. + &0u64.to_le_bytes(), // value transferred to the contract. + input, + None, + ) + .unwrap(); + } +} diff --git a/substrate/frame/contracts/fixtures/contracts/common/Cargo.toml b/substrate/frame/contracts/fixtures/contracts/common/Cargo.toml index 127bb575088..296f408d011 100644 --- a/substrate/frame/contracts/fixtures/contracts/common/Cargo.toml +++ b/substrate/frame/contracts/fixtures/contracts/common/Cargo.toml @@ -6,3 +6,6 @@ authors.workspace = true edition.workspace = true license.workspace = true description = "Common utilities for pallet-contracts-fixtures." + +[dependencies] +uapi = { package = 'pallet-contracts-uapi', path = "../../../uapi", default-features = false } diff --git a/substrate/frame/contracts/fixtures/contracts/common/src/lib.rs b/substrate/frame/contracts/fixtures/contracts/common/src/lib.rs index 29bdbfbb042..6904ab2f504 100644 --- a/substrate/frame/contracts/fixtures/contracts/common/src/lib.rs +++ b/substrate/frame/contracts/fixtures/contracts/common/src/lib.rs @@ -15,7 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. #![no_std] -#![cfg(any(target_arch = "wasm32", target_arch = "riscv32"))] + +pub use uapi::{HostFn, HostFnImpl as api}; #[panic_handler] fn panic(_info: &core::panic::PanicInfo) -> ! { @@ -29,3 +30,122 @@ fn panic(_info: &core::panic::PanicInfo) -> ! { core::hint::unreachable_unchecked(); } } + +/// Utility macro to read input passed to a contract. +/// +/// Example: +/// +/// ``` +/// input$!( +/// var1: u32, // [0, 4) var1 decoded as u32 +/// var2: [u8; 32], // [4, 36) var2 decoded as a [u8] slice +/// var3: u8, // [36, 37) var3 decoded as a u8 +/// ); +/// +/// // Input and size can be specified as well: +/// input$!( +/// input, // input buffer (optional) +/// 512, // input size (optional) +/// var4: u32, // [0, 4) var4 decoded as u32 +/// var5: [u8], // [4, ..) var5 decoded as a [u8] slice +/// ); +/// ``` +#[macro_export] +macro_rules! input { + (@inner $input:expr, $cursor:expr,) => {}; + (@size $size:expr, ) => { $size }; + + // Match a u8 variable. + // e.g input!(var1: u8, ); + (@inner $input:expr, $cursor:expr, $var:ident: u8, $($rest:tt)*) => { + let $var = $input[$cursor]; + input!(@inner $input, $cursor + 1, $($rest)*); + }; + + // Size of u8 variable. + (@size $size:expr, $var:ident: u8, $($rest:tt)*) => { + input!(@size $size + 1, $($rest)*) + }; + + // Match a u64 variable. + // e.g input!(var1: u64, ); + (@inner $input:expr, $cursor:expr, $var:ident: u64, $($rest:tt)*) => { + let $var = u64::from_le_bytes($input[$cursor..$cursor + 8].try_into().unwrap()); + input!(@inner $input, $cursor + 8, $($rest)*); + }; + + // Size of u64 variable. + (@size $size:expr, $var:ident: u64, $($rest:tt)*) => { + input!(@size $size + 8, $($rest)*) + }; + + // Match a u32 variable. + // e.g input!(var1: u32, ); + (@inner $input:expr, $cursor:expr, $var:ident: u32, $($rest:tt)*) => { + let $var = u32::from_le_bytes($input[$cursor..$cursor + 4].try_into().unwrap()); + input!(@inner $input, $cursor + 4, $($rest)*); + }; + + // Size of u32 variable. + (@size $size:expr, $var:ident: u32, $($rest:tt)*) => { + input!(@size $size + 4, $($rest)*) + }; + + // Match a u8 slice with the remaining bytes. + // e.g input!(512, var1: [u8; 32], var2: [u8], ); + (@inner $input:expr, $cursor:expr, $var:ident: [u8],) => { + let $var = &$input[$cursor..]; + }; + + // Match a u8 slice of the given size. + // e.g input!(var1: [u8; 32], ); + (@inner $input:expr, $cursor:expr, $var:ident: [u8; $n:expr], $($rest:tt)*) => { + let $var = &$input[$cursor..$cursor+$n]; + input!(@inner $input, $cursor + $n, $($rest)*); + }; + + // Size of a u8 slice. + (@size $size:expr, $var:ident: [u8; $n:expr], $($rest:tt)*) => { + input!(@size $size + $n, $($rest)*) + }; + + // Entry point, with the buffer and it's size specified first. + // e.g input!(buffer, 512, var1: u32, var2: [u8], ); + ($buffer:ident, $size:expr, $($rest:tt)*) => { + let mut $buffer = [0u8; $size]; + let $buffer = &mut &mut $buffer[..]; + $crate::api::input($buffer); + input!(@inner $buffer, 0, $($rest)*); + }; + + // Entry point, with the name of the buffer specified and size of the input buffer computed. + // e.g input!(buffer, var1: u32, var2: u64, ); + ($buffer: ident, $($rest:tt)*) => { + input!($buffer, input!(@size 0, $($rest)*), $($rest)*); + }; + + // Entry point, with the size of the input buffer computed. + // e.g input!(var1: u32, var2: u64, ); + ($($rest:tt)*) => { + input!(buffer, $($rest)*); + }; +} + +/// Utility macro to invoke a host function that expect a `output: &mut &mut [u8]` as last argument. +/// +/// Example: +/// ``` +/// // call `api::caller` and store the output in `caller` +/// output!(caller, [0u8; 32], api::caller,); +/// +/// // call `api::get_storage` and store the output in `address` +/// output!(address, [0u8; 32], api::get_storage, &[1u8; 32]); +/// ``` +#[macro_export] +macro_rules! output { + ($output: ident, $buffer: expr, $host_fn:path, $($arg:expr),*) => { + let mut $output = $buffer; + let $output = &mut &mut $output[..]; + $host_fn($($arg,)* $output); + }; +} diff --git a/substrate/frame/contracts/fixtures/contracts/create_storage_and_call.rs b/substrate/frame/contracts/fixtures/contracts/create_storage_and_call.rs new file mode 100644 index 00000000000..8b79dd87dff --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/create_storage_and_call.rs @@ -0,0 +1,59 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! This calls another contract as passed as its account id. It also creates some storage. +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!( + buffer, + input: [u8; 4], + callee: [u8; 32], + deposit_limit: [u8; 8], + ); + + // create 4 byte of storage before calling + api::set_storage(buffer, &[1u8; 4]); + + // Call the callee + #[allow(deprecated)] + api::call_v2( + uapi::CallFlags::empty(), + callee, + 0u64, // How much ref_time weight to devote for the execution. 0 = all. + 0u64, // How much proof_size weight to devote for the execution. 0 = all. + Some(deposit_limit), + &0u64.to_le_bytes(), // value transferred to the contract. + input, + None, + ) + .unwrap(); + + // create 8 byte of storage after calling + // item of 12 bytes because we override 4 bytes + api::set_storage(buffer, &[1u8; 12]); +} diff --git a/substrate/frame/contracts/fixtures/contracts/create_storage_and_instantiate.rs b/substrate/frame/contracts/fixtures/contracts/create_storage_and_instantiate.rs new file mode 100644 index 00000000000..c68d99eff82 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/create_storage_and_instantiate.rs @@ -0,0 +1,59 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! This instantiates another contract and passes some input to its constructor. +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!( + input: [u8; 4], + code_hash: [u8; 32], + deposit_limit: [u8; 8], + ); + + let value = 10_000u64.to_le_bytes(); + let salt = [0u8; 0]; + let mut address = [0u8; 32]; + let address = &mut &mut address[..]; + + #[allow(deprecated)] + api::instantiate_v2( + code_hash, + 0u64, // How much ref_time weight to devote for the execution. 0 = all. + 0u64, // How much proof_size weight to devote for the execution. 0 = all. + Some(deposit_limit), + &value, + input, + Some(address), + None, + &salt, + ) + .unwrap(); + + // Return the deployed contract address. + api::return_value(uapi::ReturnFlags::empty(), address); +} diff --git a/substrate/frame/contracts/fixtures/contracts/crypto_hashes.rs b/substrate/frame/contracts/fixtures/contracts/crypto_hashes.rs new file mode 100644 index 00000000000..35cc03f1e72 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/crypto_hashes.rs @@ -0,0 +1,84 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +/// Called by the tests. +/// +/// The `call` function expects data in a certain format in the input buffer. +/// +/// 1. The first byte encodes an identifier for the crypto hash function under test. (*) +/// 2. The rest encodes the input data that is directly fed into the crypto hash function chosen in +/// 1. +/// +/// The `deploy` function then computes the chosen crypto hash function +/// given the input and puts the result into the output buffer. +/// After contract execution the test driver then asserts that the returned +/// values are equal to the expected bytes for the input and chosen hash +/// function. +/// +/// (*) The possible value for the crypto hash identifiers can be found below: +/// +/// | value | Algorithm | Bit Width | +/// |-------|-----------|-----------| +/// | 0 | SHA2 | 256 | +/// | 1 | KECCAK | 256 | +/// | 2 | BLAKE2 | 256 | +/// | 3 | BLAKE2 | 128 | +/// --------------------------------- + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!( + 256, + chosen_hash_fn: u8, + input: [u8], + ); + + match chosen_hash_fn { + 1 => { + let mut output = [0u8; 32]; + api::hash_sha2_256(input, &mut output); + api::return_value(uapi::ReturnFlags::empty(), &output); + }, + 2 => { + let mut output = [0u8; 32]; + api::hash_keccak_256(input, &mut output); + api::return_value(uapi::ReturnFlags::empty(), &output); + }, + 3 => { + let mut output = [0u8; 32]; + api::hash_blake2_256(input, &mut output); + api::return_value(uapi::ReturnFlags::empty(), &output); + }, + 4 => { + let mut output = [0u8; 16]; + api::hash_blake2_128(input, &mut output); + api::return_value(uapi::ReturnFlags::empty(), &output); + }, + _ => panic!("unknown crypto hash function identifier"), + } +} diff --git a/substrate/frame/contracts/fixtures/contracts/debug_message_invalid_utf8.rs b/substrate/frame/contracts/fixtures/contracts/debug_message_invalid_utf8.rs new file mode 100644 index 00000000000..6c850a9ec66 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/debug_message_invalid_utf8.rs @@ -0,0 +1,33 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Emit a debug message with an invalid utf-8 code. +#![no_std] +#![no_main] + +extern crate common; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + api::debug_message(b"\xFC").unwrap(); +} diff --git a/substrate/frame/contracts/fixtures/contracts/debug_message_logging_disabled.rs b/substrate/frame/contracts/fixtures/contracts/debug_message_logging_disabled.rs new file mode 100644 index 00000000000..b9f62adbfff --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/debug_message_logging_disabled.rs @@ -0,0 +1,33 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Emit a "Hello World!" debug message but assume that logging is disabled. +#![no_std] +#![no_main] + +extern crate common; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + api::debug_message(b"Hello World!").unwrap(); +} diff --git a/substrate/frame/contracts/fixtures/contracts/debug_message_works.rs b/substrate/frame/contracts/fixtures/contracts/debug_message_works.rs new file mode 100644 index 00000000000..3a2509509d8 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/debug_message_works.rs @@ -0,0 +1,33 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Emit a "Hello World!" debug message. +#![no_std] +#![no_main] + +extern crate common; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + api::debug_message(b"Hello World!").unwrap(); +} diff --git a/substrate/frame/contracts/fixtures/contracts/delegate_call.rs b/substrate/frame/contracts/fixtures/contracts/delegate_call.rs new file mode 100644 index 00000000000..f109e8a63a3 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/delegate_call.rs @@ -0,0 +1,49 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!(code_hash: [u8; 32],); + + let mut key = [0u8; 32]; + key[0] = 1u8; + + let mut value = [0u8; 32]; + let value = &mut &mut value[..]; + value[0] = 2u8; + + api::set_storage(&key, value); + api::get_storage(&key, value).unwrap(); + assert!(value[0] == 2u8); + + let input = [0u8; 0]; + api::delegate_call(uapi::CallFlags::empty(), code_hash, &input, None).unwrap(); + + api::get_storage(&[1u8], value).unwrap(); + assert!(value[0] == 1u8); +} diff --git a/substrate/frame/contracts/fixtures/contracts/delegate_call_lib.rs b/substrate/frame/contracts/fixtures/contracts/delegate_call_lib.rs new file mode 100644 index 00000000000..197b396ce4f --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/delegate_call_lib.rs @@ -0,0 +1,49 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::output; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + let mut key = [0u8; 32]; + key[0] = 1u8; + + // Place a value in storage. + let mut value = [0u8; 32]; + let value = &mut &mut value[..]; + value[0] = 1u8; + api::set_storage(&key, value); + + // Assert that `value_transferred` is equal to the value + // passed to the `caller` contract: 1337. + output!(value_transferred, [0u8; 8], api::value_transferred,); + let value_transferred = u64::from_le_bytes(value_transferred[..].try_into().unwrap()); + assert_eq!(value_transferred, 1337); + + // Assert that ALICE is the caller of the contract. + output!(caller, [0u8; 32], api::caller,); + assert_eq!(&caller[..], &[1u8; 32]); +} diff --git a/substrate/frame/contracts/fixtures/contracts/delegate_call_simple.rs b/substrate/frame/contracts/fixtures/contracts/delegate_call_simple.rs new file mode 100644 index 00000000000..cf3351c52fd --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/delegate_call_simple.rs @@ -0,0 +1,36 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!(code_hash: [u8; 32],); + + // Delegate call into passed code hash. + let input = [0u8; 0]; + api::delegate_call(uapi::CallFlags::empty(), code_hash, &input, None).unwrap(); +} diff --git a/substrate/frame/contracts/fixtures/contracts/destroy_and_transfer.rs b/substrate/frame/contracts/fixtures/contracts/destroy_and_transfer.rs new file mode 100644 index 00000000000..cfcfd60f21e --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/destroy_and_transfer.rs @@ -0,0 +1,89 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +const ADDRESS_KEY: [u8; 32] = [0u8; 32]; +const VALUE: [u8; 8] = [0, 0, 1u8, 0, 0, 0, 0, 0]; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() { + input!(code_hash: [u8; 32],); + + let input = [0u8; 0]; + let mut address = [0u8; 32]; + let address = &mut &mut address[..]; + let salt = [71u8, 17u8]; + + #[allow(deprecated)] + api::instantiate_v2( + code_hash, + 0u64, // How much ref_time weight to devote for the execution. 0 = all. + 0u64, // How much proof_size weight to devote for the execution. 0 = all. + None, // No deposit limit. + &VALUE, + &input, + Some(address), + None, + &salt, + ) + .unwrap(); + + // Return the deployed contract address. + api::set_storage(&ADDRESS_KEY, address); +} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + let mut callee_addr = [0u8; 32]; + let callee_addr = &mut &mut callee_addr[..]; + api::get_storage(&ADDRESS_KEY, callee_addr).unwrap(); + + // Calling the destination contract with non-empty input data should fail. + #[allow(deprecated)] + let res = api::call_v2( + uapi::CallFlags::empty(), + callee_addr, + 0u64, // How much ref_time weight to devote for the execution. 0 = all. + 0u64, // How much proof_size weight to devote for the execution. 0 = all. + None, // No deposit limit. + &VALUE, + &[0u8; 1], + None, + ); + assert!(matches!(res, Err(uapi::ReturnErrorCode::CalleeTrapped))); + + // Call the destination contract regularly, forcing it to self-destruct. + #[allow(deprecated)] + api::call_v2( + uapi::CallFlags::empty(), + callee_addr, + 0u64, // How much ref_time weight to devote for the execution. 0 = all. + 0u64, // How much proof_size weight to devote for the execution. 0 = all. + None, // No deposit limit. + &VALUE, + &[0u8; 0], + None, + ) + .unwrap(); +} diff --git a/substrate/frame/contracts/fixtures/contracts/drain.rs b/substrate/frame/contracts/fixtures/contracts/drain.rs new file mode 100644 index 00000000000..f5c8681c938 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/drain.rs @@ -0,0 +1,44 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::output; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + output!(balance, [0u8; 8], api::balance,); + let balance = u64::from_le_bytes(balance[..].try_into().unwrap()); + + output!(minimum_balance, [0u8; 8], api::minimum_balance,); + let minimum_balance = u64::from_le_bytes(minimum_balance[..].try_into().unwrap()); + + // Make the transferred value exceed the balance by adding the minimum balance. + let balance = balance + minimum_balance; + + // Try to self-destruct by sending more balance to the 0 address. + // The call will fail because a contract transfer has a keep alive requirement. + let res = api::transfer(&[0u8; 32], &balance.to_le_bytes()); + assert!(matches!(res, Err(uapi::ReturnErrorCode::TransferFailed))); +} diff --git a/substrate/frame/contracts/fixtures/contracts/ecdsa_recover.rs b/substrate/frame/contracts/fixtures/contracts/ecdsa_recover.rs new file mode 100644 index 00000000000..0f28ca2c819 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/ecdsa_recover.rs @@ -0,0 +1,44 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!( + signature: [u8; 65], + hash: [u8; 32], + ); + + let mut output = [0u8; 33]; + api::ecdsa_recover( + &signature[..].try_into().unwrap(), + &hash[..].try_into().unwrap(), + &mut output, + ) + .unwrap(); + api::return_value(uapi::ReturnFlags::empty(), &output); +} diff --git a/substrate/frame/contracts/fixtures/contracts/event_and_return_on_deploy.rs b/substrate/frame/contracts/fixtures/contracts/event_and_return_on_deploy.rs new file mode 100644 index 00000000000..9186835d291 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/event_and_return_on_deploy.rs @@ -0,0 +1,36 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +extern crate common; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() { + let buffer = [1u8, 2, 3, 4]; + api::deposit_event(&[0u8; 0], &buffer); + api::return_value(uapi::ReturnFlags::empty(), &buffer); +} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + unreachable!() +} diff --git a/substrate/frame/contracts/fixtures/contracts/event_size.rs b/substrate/frame/contracts/fixtures/contracts/event_size.rs new file mode 100644 index 00000000000..e95130d3083 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/event_size.rs @@ -0,0 +1,37 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!(len: u32,); + + let buffer = [0u8; 16 * 1024 + 1]; + let data = &buffer[..len as usize]; + + api::deposit_event(&[0u8; 0], data); +} diff --git a/substrate/frame/contracts/fixtures/contracts/float_instruction.rs b/substrate/frame/contracts/fixtures/contracts/float_instruction.rs new file mode 100644 index 00000000000..b1eaaf8543c --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/float_instruction.rs @@ -0,0 +1,34 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +extern crate common; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() {} + +#[no_mangle] +pub extern "C" fn add(a: f32, b: f32) -> f32 { + a + b +} diff --git a/substrate/frame/contracts/fixtures/contracts/instantiate_return_code.rs b/substrate/frame/contracts/fixtures/contracts/instantiate_return_code.rs new file mode 100644 index 00000000000..67cd739d85a --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/instantiate_return_code.rs @@ -0,0 +1,53 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!(buffer, 36, code_hash: [u8; 32],); + let input = &buffer[32..]; + + #[allow(deprecated)] + let err_code = match api::instantiate_v2( + code_hash, + 0u64, // How much ref_time weight to devote for the execution. 0 = all. + 0u64, /* How much proof_size weight to devote for the execution. 0 = + * all. */ + None, // No deposit limit. + &10_000u64.to_le_bytes(), // Value to transfer. + input, + None, + None, + &[0u8; 0], // Empty salt. + ) { + Ok(_) => 0u32, + Err(code) => code as u32, + }; + + // Exit with success and take transfer return code to the output buffer. + api::return_value(uapi::ReturnFlags::empty(), &err_code.to_le_bytes()); +} diff --git a/substrate/frame/contracts/fixtures/contracts/invalid_contract_no_call.rs b/substrate/frame/contracts/fixtures/contracts/invalid_contract_no_call.rs new file mode 100644 index 00000000000..13af3eb22b1 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/invalid_contract_no_call.rs @@ -0,0 +1,25 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. +//! Valid module but missing the call function +#![no_std] +#![no_main] + +extern crate common; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} diff --git a/substrate/frame/contracts/fixtures/contracts/multi_store.rs b/substrate/frame/contracts/fixtures/contracts/multi_store.rs new file mode 100644 index 00000000000..b83f3995a42 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/multi_store.rs @@ -0,0 +1,43 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Does two stores to two seperate storage items +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!( + size1: u32, + size2: u32, + ); + + let buffer = [0u8; 16 * 1024]; + + // Place a values in storage sizes are specified in the input buffer. + // We don't care about the contents of the storage item. + api::set_storage(&[1u8; 32], &buffer[0..size1 as _]); + api::set_storage(&[2u8; 32], &buffer[0..size2 as _]); +} diff --git a/substrate/frame/contracts/fixtures/contracts/new_set_code_hash_contract.rs b/substrate/frame/contracts/fixtures/contracts/new_set_code_hash_contract.rs new file mode 100644 index 00000000000..2a59b6e33d8 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/new_set_code_hash_contract.rs @@ -0,0 +1,32 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +extern crate common; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + api::return_value(uapi::ReturnFlags::empty(), &2u32.to_le_bytes()); +} diff --git a/substrate/frame/contracts/fixtures/contracts/ok_trap_revert.rs b/substrate/frame/contracts/fixtures/contracts/ok_trap_revert.rs new file mode 100644 index 00000000000..55115f8642f --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/ok_trap_revert.rs @@ -0,0 +1,44 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() { + ok_trap_revert(); +} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + ok_trap_revert(); +} + +#[no_mangle] +fn ok_trap_revert() { + input!(buffer, 4,); + match buffer.first().unwrap_or(&0) { + 1 => api::return_value(uapi::ReturnFlags::REVERT, &[0u8; 0]), + 2 => panic!(), + _ => {}, + }; +} diff --git a/substrate/frame/contracts/fixtures/contracts/reentrance_count_call.rs b/substrate/frame/contracts/fixtures/contracts/reentrance_count_call.rs new file mode 100644 index 00000000000..9812dce2e81 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/reentrance_count_call.rs @@ -0,0 +1,55 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +// This fixture tests if account_reentrance_count works as expected. +#![no_std] +#![no_main] + +use common::{input, output}; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!(expected_reentrance_count: u32,); + + // Read the contract address. + output!(addr, [0u8; 32], api::address,); + + #[allow(deprecated)] + let reentrance_count = api::reentrance_count(); + assert_eq!(reentrance_count, expected_reentrance_count); + + // Re-enter 5 times in a row and assert that the reentrant counter works as expected. + if expected_reentrance_count != 5 { + let count = (expected_reentrance_count + 1).to_le_bytes(); + + api::call_v1( + uapi::CallFlags::ALLOW_REENTRY, + addr, + 0u64, // How much gas to devote for the execution. 0 = all. + &0u64.to_le_bytes(), // value transferred to the contract. + &count, + None, + ) + .unwrap(); + } +} diff --git a/substrate/frame/contracts/fixtures/contracts/reentrance_count_delegated_call.rs b/substrate/frame/contracts/fixtures/contracts/reentrance_count_delegated_call.rs new file mode 100644 index 00000000000..9baf9503808 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/reentrance_count_delegated_call.rs @@ -0,0 +1,53 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +// This fixture tests if account_reentrance_count works as expected. +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!( + input, + code_hash: [u8; 32], + call_stack_height: u32, + ); + + let call_stack_height = call_stack_height + 1; + + #[allow(deprecated)] + let reentrance_count = api::reentrance_count(); + + // Reentrance count stays 0. + assert_eq!(reentrance_count, 0); + + // Re-enter 5 times in a row and assert that the reentrant counter works as expected. + if call_stack_height != 5 { + let mut input = [0u8; 36]; + input[0..32].copy_from_slice(code_hash); + input[32..36].copy_from_slice(&call_stack_height.to_le_bytes()); + api::delegate_call(uapi::CallFlags::empty(), code_hash, &input, None).unwrap(); + } +} diff --git a/substrate/frame/contracts/fixtures/contracts/return_with_data.rs b/substrate/frame/contracts/fixtures/contracts/return_with_data.rs new file mode 100644 index 00000000000..5340f86fbfc --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/return_with_data.rs @@ -0,0 +1,43 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() { + call(); +} + +/// Reads the first byte as the exit status and copy all but the first 4 bytes of the input as +/// output data. +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!( + input, 128, + exit_status: [u8; 4], + output: [u8], + ); + + let exit_status = uapi::ReturnFlags::from_bits(exit_status[0] as u32).unwrap(); + api::return_value(exit_status, output); +} diff --git a/substrate/frame/contracts/fixtures/contracts/run_out_of_gas.rs b/substrate/frame/contracts/fixtures/contracts/run_out_of_gas.rs new file mode 100644 index 00000000000..11eaaa7c862 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/run_out_of_gas.rs @@ -0,0 +1,32 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +extern crate common; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + #[allow(clippy::empty_loop)] + loop {} +} diff --git a/substrate/frame/contracts/fixtures/contracts/self_destruct.rs b/substrate/frame/contracts/fixtures/contracts/self_destruct.rs new file mode 100644 index 00000000000..94c3ac387a0 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/self_destruct.rs @@ -0,0 +1,53 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::{input, output}; +use uapi::{HostFn, HostFnImpl as api}; + +const DJANGO: [u8; 32] = [4u8; 32]; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + // If the input data is not empty, then recursively call self with empty input data. + // This should trap instead of self-destructing since a contract cannot be removed, while it's + // in the execution stack. If the recursive call traps, then trap here as well. + input!(input, 4,); + + if !input.is_empty() { + output!(addr, [0u8; 32], api::address,); + api::call_v1( + uapi::CallFlags::ALLOW_REENTRY, + addr, + 0u64, // How much gas to devote for the execution. 0 = all. + &0u64.to_le_bytes(), // Value to transfer. + &[0u8; 0], + None, + ) + .unwrap(); + } else { + // Try to terminate and give balance to django. + api::terminate_v1(&DJANGO); + } +} diff --git a/substrate/frame/contracts/fixtures/contracts/self_destructing_constructor.rs b/substrate/frame/contracts/fixtures/contracts/self_destructing_constructor.rs new file mode 100644 index 00000000000..97b6759b3a6 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/self_destructing_constructor.rs @@ -0,0 +1,32 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +extern crate common; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() { + api::terminate_v1(&[0u8; 32]); +} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() {} diff --git a/substrate/frame/contracts/fixtures/contracts/set_code_hash.rs b/substrate/frame/contracts/fixtures/contracts/set_code_hash.rs new file mode 100644 index 00000000000..e3cf4becfb9 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/set_code_hash.rs @@ -0,0 +1,37 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!(addr: [u8; 32],); + api::set_code_hash(addr).unwrap(); + + // we return 1 after setting new code_hash + // next `call` will NOT return this value, because contract code has been changed + api::return_value(uapi::ReturnFlags::empty(), &1u32.to_le_bytes()); +} diff --git a/substrate/frame/contracts/fixtures/contracts/set_empty_storage.rs b/substrate/frame/contracts/fixtures/contracts/set_empty_storage.rs new file mode 100644 index 00000000000..e7366630e8f --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/set_empty_storage.rs @@ -0,0 +1,32 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +extern crate common; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + api::set_storage(&[0u8; 32], &[0u8; 4]); +} diff --git a/substrate/frame/contracts/fixtures/contracts/sr25519_verify.rs b/substrate/frame/contracts/fixtures/contracts/sr25519_verify.rs new file mode 100644 index 00000000000..8920ce0d4f6 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/sr25519_verify.rs @@ -0,0 +1,48 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!( + signature: [u8; 64], + pub_key: [u8; 32], + msg: [u8; 11], + ); + + let exit_status = match api::sr25519_verify( + &signature.try_into().unwrap(), + msg, + &pub_key.try_into().unwrap(), + ) { + Ok(_) => 0u32, + Err(code) => code as u32, + }; + + // Exit with success and take transfer return code to the output buffer. + api::return_value(uapi::ReturnFlags::empty(), &exit_status.to_le_bytes()); +} diff --git a/substrate/frame/contracts/fixtures/contracts/storage_size.rs b/substrate/frame/contracts/fixtures/contracts/storage_size.rs new file mode 100644 index 00000000000..744ffe8503e --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/storage_size.rs @@ -0,0 +1,45 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!(len: u32, ); + + let mut buffer = [0u8; 16 * 1024 + 1]; + let data = &buffer[..len as usize]; + + // Place a garbage value in storage, the size of which is specified by the call input. + let mut key = [0u8; 32]; + key[0] = 1; + + api::set_storage(&key, data); + + let data = &mut &mut buffer[..]; + api::get_storage(&key, data).unwrap(); + assert_eq!(data.len(), len as usize); +} diff --git a/substrate/frame/contracts/fixtures/contracts/store_call.rs b/substrate/frame/contracts/fixtures/contracts/store_call.rs new file mode 100644 index 00000000000..d20d811c294 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/store_call.rs @@ -0,0 +1,41 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!(len: u32, ); + + let buffer = [0u8; 16 * 1024 + 1]; + let data = &buffer[..len as usize]; + + // Place a garbage value in storage, the size of which is specified by the call input. + let mut key = [0u8; 32]; + key[0] = 1; + + api::set_storage(&key, data); +} diff --git a/substrate/frame/contracts/fixtures/contracts/store_deploy.rs b/substrate/frame/contracts/fixtures/contracts/store_deploy.rs new file mode 100644 index 00000000000..26f3b86baff --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/store_deploy.rs @@ -0,0 +1,41 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() { + input!(len: u32, ); + + let buffer = [0u8; 16 * 1024 + 1]; + let data = &buffer[..len as usize]; + + // place a garbage value in storage, the size of which is specified by the call input. + let mut key = [0u8; 32]; + key[0] = 1; + + api::set_storage(&key, data); +} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() {} diff --git a/substrate/frame/contracts/fixtures/contracts/transfer_return_code.rs b/substrate/frame/contracts/fixtures/contracts/transfer_return_code.rs new file mode 100644 index 00000000000..d3f6a1dd3a0 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/transfer_return_code.rs @@ -0,0 +1,38 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +extern crate common; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + let ret_code = match api::transfer(&[0u8; 32], &100u64.to_le_bytes()) { + Ok(_) => 0u32, + Err(code) => code as u32, + }; + + // Exit with success and take transfer return code to the output buffer. + api::return_value(uapi::ReturnFlags::empty(), &ret_code.to_le_bytes()); +} diff --git a/substrate/frame/contracts/fixtures/contracts/xcm_execute.rs b/substrate/frame/contracts/fixtures/contracts/xcm_execute.rs new file mode 100644 index 00000000000..09d0b6cf972 --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/xcm_execute.rs @@ -0,0 +1,39 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!(512, msg: [u8],); + + let mut outcome = [0u8; 512]; + let outcome = &mut &mut outcome[..]; + + #[allow(deprecated)] + api::xcm_execute(msg, outcome).unwrap(); + api::return_value(uapi::ReturnFlags::empty(), outcome); +} diff --git a/substrate/frame/contracts/fixtures/contracts/xcm_send.rs b/substrate/frame/contracts/fixtures/contracts/xcm_send.rs new file mode 100644 index 00000000000..6d4629e748a --- /dev/null +++ b/substrate/frame/contracts/fixtures/contracts/xcm_send.rs @@ -0,0 +1,42 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![no_std] +#![no_main] + +use common::input; +use uapi::{HostFn, HostFnImpl as api}; + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!( + 512, + dest: [u8; 3], + msg: [u8], + ); + + let mut message_id = [0u8; 32]; + + #[allow(deprecated)] + api::xcm_send(dest, msg, &mut message_id).unwrap(); + api::return_value(uapi::ReturnFlags::empty(), &message_id); +} diff --git a/substrate/frame/contracts/fixtures/data/account_reentrance_count_call.wat b/substrate/frame/contracts/fixtures/data/account_reentrance_count_call.wat deleted file mode 100644 index e6d6ba8bb81..00000000000 --- a/substrate/frame/contracts/fixtures/data/account_reentrance_count_call.wat +++ /dev/null @@ -1,37 +0,0 @@ -;; This fixture tests if account_reentrance_count works as expected -;; testing it with 2 different addresses -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_caller" (func $seal_caller (param i32 i32))) - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "seal0" "account_reentrance_count" (func $account_reentrance_count (param i32) (result i32))) - (import "env" "memory" (memory 1 1)) - - ;; [0, 32) buffer where input is copied - ;; [32, 36) size of the input buffer - (data (i32.const 32) "\20") - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "call") - ;; Reading "callee" input address - (call $seal_input (i32.const 0) (i32.const 32)) - - (i32.store - (i32.const 36) - (call $account_reentrance_count (i32.const 0)) - ) - - (call $seal_return (i32.const 0) (i32.const 36) (i32.const 4)) - ) - - (func (export "deploy")) - -) \ No newline at end of file diff --git a/substrate/frame/contracts/fixtures/data/add_remove_delegate_dependency.wat b/substrate/frame/contracts/fixtures/data/add_remove_delegate_dependency.wat deleted file mode 100644 index dac7736244d..00000000000 --- a/substrate/frame/contracts/fixtures/data/add_remove_delegate_dependency.wat +++ /dev/null @@ -1,111 +0,0 @@ -;; This contract tests the behavior of adding / removing delegate_dependencies when delegate calling into a contract. -(module - (import "seal0" "add_delegate_dependency" (func $add_delegate_dependency (param i32))) - (import "seal0" "remove_delegate_dependency" (func $remove_delegate_dependency (param i32))) - (import "seal0" "input" (func $input (param i32 i32))) - (import "seal1" "terminate" (func $terminate (param i32))) - (import "seal0" "delegate_call" (func $delegate_call (param i32 i32 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - - ;; [100, 132) Address of Alice - (data (i32.const 100) - "\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01" - "\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01" - ) - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - ;; This function loads input data and performs the action specified. - ;; The first 4 bytes of the input specify the action to perform. - ;; The next 32 bytes specify the code hash to use when calling add_delegate_dependency or remove_delegate_dependency. - ;; Actions are: - ;; 1: call add_delegate_dependency - ;; 2: call remove_delegate_dependency. - ;; 3: call terminate. - ;; Any other value is a no-op. - (func $load_input - (local $action i32) - (local $code_hash_ptr i32) - - ;; Store available input size at offset 0. - (i32.store (i32.const 0) (i32.const 512)) - - ;; Read input data. - (call $input (i32.const 4) (i32.const 0)) - - ;; Input data layout. - ;; [0..4) - size of the call - ;; [4..8) - action to perform - ;; [8..42) - code hash of the callee - (local.set $action (i32.load (i32.const 4))) - (local.set $code_hash_ptr (i32.const 8)) - - ;; Assert input size == 36 (4 for action + 32 for code_hash). - (call $assert - (i32.eq - (i32.load (i32.const 0)) - (i32.const 36) - ) - ) - - ;; Call add_delegate_dependency when action == 1. - (if (i32.eq (local.get $action) (i32.const 1)) - (then - (call $add_delegate_dependency (local.get $code_hash_ptr)) - ) - (else) - ) - - ;; Call remove_delegate_dependency when action == 2. - (if (i32.eq (local.get $action) (i32.const 2)) - (then - (call $remove_delegate_dependency - (local.get $code_hash_ptr) - ) - ) - (else) - ) - - ;; Call terminate when action == 3. - (if (i32.eq (local.get $action) (i32.const 3)) - (then - (call $terminate - (i32.const 100) ;; Pointer to beneficiary address - ) - (unreachable) ;; terminate never returns - ) - (else) - ) - ) - - (func (export "deploy") - (call $load_input) - ) - - (func (export "call") - (call $load_input) - - ;; Delegate call into passed code hash. - (call $assert - (i32.eq - (call $delegate_call - (i32.const 0) ;; Set no call flags. - (i32.const 8) ;; Pointer to "callee" code_hash. - (i32.const 0) ;; Input is ignored. - (i32.const 0) ;; Length of the input. - (i32.const 4294967295) ;; u32 max sentinel value: do not copy output. - (i32.const 0) ;; Length is ignored in this case. - ) - (i32.const 0) - ) - ) - ) - -) diff --git a/substrate/frame/contracts/fixtures/data/balance.wat b/substrate/frame/contracts/fixtures/data/balance.wat deleted file mode 100644 index d7970c92e41..00000000000 --- a/substrate/frame/contracts/fixtures/data/balance.wat +++ /dev/null @@ -1,42 +0,0 @@ -(module - (import "seal0" "seal_balance" (func $seal_balance (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; [0, 8) reserved for $seal_balance output - - ;; [8, 16) length of the buffer for $seal_balance - (data (i32.const 8) "\08") - - ;; [16, inf) zero initialized - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "deploy")) - - (func (export "call") - (call $seal_balance (i32.const 0) (i32.const 8)) - - ;; Balance should be encoded as a u64. - (call $assert - (i32.eq - (i32.load (i32.const 8)) - (i32.const 8) - ) - ) - - ;; Assert the free balance to be zero. - (call $assert - (i64.eq - (i64.load (i32.const 0)) - (i64.const 0) - ) - ) - ) -) diff --git a/substrate/frame/contracts/fixtures/data/call_return_code.wat b/substrate/frame/contracts/fixtures/data/call_return_code.wat deleted file mode 100644 index 4e9ab4dd77c..00000000000 --- a/substrate/frame/contracts/fixtures/data/call_return_code.wat +++ /dev/null @@ -1,42 +0,0 @@ -;; This calls the supplied dest and transfers 100 balance during this call and copies -;; the return code of this call to the output buffer. -;; It also forwards its input to the callee. -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32))) - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; [0, 8) 100 balance - (data (i32.const 0) "\64\00\00\00\00\00\00\00") - - ;; [8, 12) here we store the return code of the transfer - - ;; [12, 16) size of the input data - (data (i32.const 12) "\24") - - ;; [16, inf) here we store the input data - ;; 32 byte dest + 4 byte forward - - (func (export "deploy")) - - (func (export "call") - (call $seal_input (i32.const 16) (i32.const 12)) - (i32.store - (i32.const 8) - (call $seal_call - (i32.const 16) ;; Pointer to "callee" address. - (i32.const 32) ;; Length of "callee" address. - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 48) ;; Pointer to input data buffer address - (i32.const 4) ;; Length of input data buffer - (i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; Ptr to output buffer len - ) - ) - ;; exit with success and take transfer return code to the output buffer - (call $seal_return (i32.const 0) (i32.const 8) (i32.const 4)) - ) -) diff --git a/substrate/frame/contracts/fixtures/data/call_runtime.wat b/substrate/frame/contracts/fixtures/data/call_runtime.wat deleted file mode 100644 index d3d08ee2454..00000000000 --- a/substrate/frame/contracts/fixtures/data/call_runtime.wat +++ /dev/null @@ -1,33 +0,0 @@ -;; This passes its input to `seal_call_runtime` and returns the return value to its caller. -(module - (import "seal0" "call_runtime" (func $call_runtime (param i32 i32) (result i32))) - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; 0x1000 = 4k in little endian - ;; size of input buffer - (data (i32.const 0) "\00\10") - - (func (export "call") - ;; Receive the encoded call - (call $seal_input - (i32.const 4) ;; Pointer to the input buffer - (i32.const 0) ;; Size of the length buffer - ) - ;; Just use the call passed as input and store result to memory - (i32.store (i32.const 0) - (call $call_runtime - (i32.const 4) ;; Pointer where the call is stored - (i32.load (i32.const 0)) ;; Size of the call - ) - ) - (call $seal_return - (i32.const 0) ;; flags - (i32.const 0) ;; returned value - (i32.const 4) ;; length of returned value - ) - ) - - (func (export "deploy")) -) diff --git a/substrate/frame/contracts/fixtures/data/call_runtime_and_call.wat b/substrate/frame/contracts/fixtures/data/call_runtime_and_call.wat deleted file mode 100644 index 5d76e19a74c..00000000000 --- a/substrate/frame/contracts/fixtures/data/call_runtime_and_call.wat +++ /dev/null @@ -1,56 +0,0 @@ -(module - (import "seal0" "call_runtime" (func $call_runtime (param i32 i32) (result i32))) - (import "seal1" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32) (result i32))) - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok (local.get 0)) - (unreachable) - ) - ) - - (func (export "call") - ;; Store available input size at offset 0. - (i32.store (i32.const 0) (i32.const 512)) - - ;; read input data - (call $seal_input (i32.const 4) (i32.const 0)) - - ;; Input data layout. - ;; [0..4) - size of the call - ;; [4..8) - how many bytes to add to storage - ;; [8..40) - address of the callee - ;; [40..n) - encoded runtime call - - ;; Invoke call_runtime with the encoded call passed to this contract. - (call $assert (i32.eqz - (call $call_runtime - (i32.const 40) ;; Pointer where the call is stored - (i32.sub - (i32.load (i32.const 0)) ;; Size of the call - (i32.const 36) ;; Subtract size of the subcall-related part: 4 bytes for storage length to add + 32 bytes of the callee address - ) - ) - )) - - ;; call passed contract - (call $assert (i32.eqz - (call $seal_call - (i32.const 0) ;; No flags - (i32.const 8) ;; Pointer to "callee" address. - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 512) ;; Pointer to the buffer with value to transfer - (i32.const 4) ;; Pointer to input data buffer address - (i32.const 4) ;; Length of input data buffer - (i32.const 4294967295) ;; u32 max value is the sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this case - ) - )) - ) - - (func (export "deploy")) -) - diff --git a/substrate/frame/contracts/fixtures/data/call_with_limit.wat b/substrate/frame/contracts/fixtures/data/call_with_limit.wat deleted file mode 100644 index 04da59551a8..00000000000 --- a/substrate/frame/contracts/fixtures/data/call_with_limit.wat +++ /dev/null @@ -1,38 +0,0 @@ -;; This expects [account_id, ref_time, proof_size] as input and calls the account_id with the supplied 2D Weight limit. -;; It returns the result of the call as output data. -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal2" "call" (func $seal_call (param i32 i32 i64 i64 i32 i32 i32 i32 i32 i32) (result i32))) - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; 0x1000 = 4k in little endian - ;; size of input buffer - (data (i32.const 0) "\00\10") - - (func (export "deploy")) - - (func (export "call") - ;; Receive the encoded account_id, ref_time, proof_size - (call $seal_input - (i32.const 4) ;; Pointer to the input buffer - (i32.const 0) ;; Pointer to the length of the input buffer - ) - (i32.store - (i32.const 0) - (call $seal_call - (i32.const 0) ;; Set no flag. - (i32.const 4) ;; Pointer to "callee" address. - (i64.load (i32.const 36)) ;; How much ref_time to devote for the execution. - (i64.load (i32.const 44)) ;; How much proof_size to devote for the execution. - (i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 0) ;; Length of input data buffer - (i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this case - ) - ) - (call $seal_return (i32.const 0) (i32.const 0) (i32.const 4)) - ) -) diff --git a/substrate/frame/contracts/fixtures/data/caller_contract.wat b/substrate/frame/contracts/fixtures/data/caller_contract.wat deleted file mode 100644 index 43eb8ccfd54..00000000000 --- a/substrate/frame/contracts/fixtures/data/caller_contract.wat +++ /dev/null @@ -1,286 +0,0 @@ -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_balance" (func $seal_balance (param i32 i32))) - (import "seal2" "call" (func $seal_call (param i32 i32 i64 i64 i32 i32 i32 i32 i32 i32) (result i32))) - (import "seal2" "instantiate" (func $seal_instantiate - (param i32 i64 i64 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32) - )) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "deploy")) - - (func (export "call") - (local $sp i32) - (local $exit_code i32) - - ;; Length of the buffer - (i32.store (i32.const 20) (i32.const 32)) - - ;; Copy input to this contracts memory - (call $seal_input (i32.const 24) (i32.const 20)) - - ;; Input data is the code hash of the contract to be deployed. - (call $assert - (i32.eq - (i32.load (i32.const 20)) - (i32.const 32) - ) - ) - - ;; Read current balance into local variable. - (local.set $sp (i32.const 1024)) - - ;; Fail to deploy the contract since it returns a non-zero exit status. - (local.set $exit_code - (call $seal_instantiate - (i32.const 24) ;; Pointer to the code hash. - (i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all. - (i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all. - (i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 9) ;; Pointer to input data buffer address - (i32.const 7) ;; Length of input data buffer - (i32.const 4294967295) ;; u32 max sentinel value: do not copy address - (i32.const 0) ;; Length is ignored in this case - (i32.const 4294967295) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this case - (i32.const 0) ;; salt_ptr - (i32.const 0) ;; salt_le - ) - ) - - ;; Check non-zero exit status. - (call $assert - (i32.eq (local.get $exit_code) (i32.const 2)) ;; ReturnCode::CalleeReverted - ) - - ;; Fail to deploy the contract due to insufficient ref_time weight. - (local.set $exit_code - (call $seal_instantiate - (i32.const 24) ;; Pointer to the code hash. - (i64.const 1) ;; Supply too little ref_time weight - (i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all. - (i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Pointer to input data buffer address - (i32.const 8) ;; Length of input data buffer - (i32.const 4294967295) ;; u32 max sentinel value: do not copy address - (i32.const 0) ;; Length is ignored in this case - (i32.const 4294967295) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this case - (i32.const 0) ;; salt_ptr - (i32.const 0) ;; salt_le - - ) - ) - - ;; Check for special trap exit status. - (call $assert - (i32.eq (local.get $exit_code) (i32.const 1)) ;; ReturnCode::CalleeTrapped - ) - - ;; Fail to deploy the contract due to insufficient ref_time weight. - (local.set $exit_code - (call $seal_instantiate - (i32.const 24) ;; Pointer to the code hash. - (i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all. - (i64.const 1) ;; Supply too little proof_size weight - (i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Pointer to input data buffer address - (i32.const 8) ;; Length of input data buffer - (i32.const 4294967295) ;; u32 max sentinel value: do not copy address - (i32.const 0) ;; Length is ignored in this case - (i32.const 4294967295) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this case - (i32.const 0) ;; salt_ptr - (i32.const 0) ;; salt_le - - ) - ) - - ;; Check for special trap exit status. - (call $assert - (i32.eq (local.get $exit_code) (i32.const 1)) ;; ReturnCode::CalleeTrapped - ) - - ;; Length of the output buffer - (i32.store - (i32.sub (local.get $sp) (i32.const 4)) - (i32.const 256) - ) - - ;; Deploy the contract successfully. - (local.set $exit_code - (call $seal_instantiate - (i32.const 24) ;; Pointer to the code hash. - (i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all. - (i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all. - (i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Pointer to input data buffer address - (i32.const 8) ;; Length of input data buffer - (i32.const 16) ;; Pointer to the address output buffer - (i32.sub (local.get $sp) (i32.const 4)) ;; Pointer to the address buffer length - (i32.const 4294967295) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this case - (i32.const 0) ;; salt_ptr - (i32.const 0) ;; salt_le - - ) - ) - - ;; Check for success exit status. - (call $assert - (i32.eq (local.get $exit_code) (i32.const 0)) ;; ReturnCode::Success - ) - - ;; Check that address has the expected length - (call $assert - (i32.eq (i32.load (i32.sub (local.get $sp) (i32.const 4))) (i32.const 32)) - ) - - ;; Zero out destination buffer of output - (i32.store - (i32.sub (local.get $sp) (i32.const 4)) - (i32.const 0) - ) - - ;; Length of the output buffer - (i32.store - (i32.sub (local.get $sp) (i32.const 8)) - (i32.const 4) - ) - - ;; Call the new contract and expect it to return failing exit code. - (local.set $exit_code - (call $seal_call - (i32.const 0) ;; Set no flag - (i32.const 16) ;; Pointer to "callee" address. - (i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all. - (i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all. - (i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 9) ;; Pointer to input data buffer address - (i32.const 7) ;; Length of input data buffer - (i32.sub (local.get $sp) (i32.const 4)) ;; Ptr to output buffer - (i32.sub (local.get $sp) (i32.const 8)) ;; Ptr to output buffer len - ) - ) - - ;; Check non-zero exit status. - (call $assert - (i32.eq (local.get $exit_code) (i32.const 2)) ;; ReturnCode::CalleeReverted - ) - - ;; Check that output buffer contains the expected return data. - (call $assert - (i32.eq (i32.load (i32.sub (local.get $sp) (i32.const 8))) (i32.const 3)) - ) - (call $assert - (i32.eq - (i32.load (i32.sub (local.get $sp) (i32.const 4))) - (i32.const 0x00776655) - ) - ) - - ;; Fail to call the contract due to insufficient ref_time weight. - (local.set $exit_code - (call $seal_call - (i32.const 0) ;; Set no flag - (i32.const 16) ;; Pointer to "callee" address. - (i64.const 1) ;; Supply too little ref_time weight - (i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all. - (i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Pointer to input data buffer address - (i32.const 8) ;; Length of input data buffer - (i32.const 4294967295) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this cas - ) - ) - - ;; Check for special trap exit status. - (call $assert - (i32.eq (local.get $exit_code) (i32.const 1)) ;; ReturnCode::CalleeTrapped - ) - - ;; Fail to call the contract due to insufficient proof_size weight. - (local.set $exit_code - (call $seal_call - (i32.const 0) ;; Set no flag - (i32.const 16) ;; Pointer to "callee" address. - (i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all. - (i64.const 1) ;; Supply too little proof_size weight - (i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Pointer to input data buffer address - (i32.const 8) ;; Length of input data buffer - (i32.const 4294967295) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this cas - ) - ) - - ;; Check for special trap exit status. - (call $assert - (i32.eq (local.get $exit_code) (i32.const 1)) ;; ReturnCode::CalleeTrapped - ) - - ;; Zero out destination buffer of output - (i32.store - (i32.sub (local.get $sp) (i32.const 4)) - (i32.const 0) - ) - - ;; Length of the output buffer - (i32.store - (i32.sub (local.get $sp) (i32.const 8)) - (i32.const 4) - ) - - ;; Call the contract successfully. - (local.set $exit_code - (call $seal_call - (i32.const 0) ;; Set no flag - (i32.const 16) ;; Pointer to "callee" address. - (i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all. - (i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all. - (i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Pointer to input data buffer address - (i32.const 8) ;; Length of input data buffer - (i32.sub (local.get $sp) (i32.const 4)) ;; Ptr to output buffer - (i32.sub (local.get $sp) (i32.const 8)) ;; Ptr to output buffer len - ) - ) - - ;; Check for success exit status. - (call $assert - (i32.eq (local.get $exit_code) (i32.const 0)) ;; ReturnCode::Success - ) - - ;; Check that the output buffer contains the expected return data. - (call $assert - (i32.eq (i32.load (i32.sub (local.get $sp) (i32.const 8))) (i32.const 4)) - ) - (call $assert - (i32.eq - (i32.load (i32.sub (local.get $sp) (i32.const 4))) - (i32.const 0x77665544) - ) - ) - ) - - (data (i32.const 0) "\00\80") ;; The value to transfer on instantiation and calls. - ;; Chosen to be greater than existential deposit. - (data (i32.const 8) "\00\01\22\33\44\55\66\77") ;; The input data to instantiations and calls. -) diff --git a/substrate/frame/contracts/fixtures/data/chain_extension.wat b/substrate/frame/contracts/fixtures/data/chain_extension.wat deleted file mode 100644 index c24ca286ff8..00000000000 --- a/substrate/frame/contracts/fixtures/data/chain_extension.wat +++ /dev/null @@ -1,46 +0,0 @@ -;; Call chain extension by passing through input and output of this contract -(module - (import "seal0" "call_chain_extension" - (func $call_chain_extension (param i32 i32 i32 i32 i32) (result i32)) - ) - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "env" "memory" (memory 16 16)) - - (func $assert (param i32) - (block $ok - (br_if $ok (local.get 0)) - (unreachable) - ) - ) - - ;; [0, 4) len of input output - (data (i32.const 0) "\08") - - ;; [4, 12) buffer for input - - ;; [12, 48) len of output buffer - (data (i32.const 12) "\20") - - ;; [16, inf) buffer for output - - (func (export "deploy")) - - (func (export "call") - (call $seal_input (i32.const 4) (i32.const 0)) - - ;; the chain extension passes through the input and returns it as output - (call $call_chain_extension - (i32.load (i32.const 4)) ;; id - (i32.const 4) ;; input_ptr - (i32.load (i32.const 0)) ;; input_len - (i32.const 16) ;; output_ptr - (i32.const 12) ;; output_len_ptr - ) - - ;; the chain extension passes through the id - (call $assert (i32.eq (i32.load (i32.const 4)))) - - (call $seal_return (i32.const 0) (i32.const 16) (i32.load (i32.const 12))) - ) -) diff --git a/substrate/frame/contracts/fixtures/data/chain_extension_temp_storage.wat b/substrate/frame/contracts/fixtures/data/chain_extension_temp_storage.wat deleted file mode 100644 index 504646df1b0..00000000000 --- a/substrate/frame/contracts/fixtures/data/chain_extension_temp_storage.wat +++ /dev/null @@ -1,85 +0,0 @@ -;; Call chain extension two times with the specified func_ids -;; It then calls itself once -(module - (import "seal0" "seal_call_chain_extension" - (func $seal_call_chain_extension (param i32 i32 i32 i32 i32) (result i32)) - ) - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_address" (func $seal_address (param i32 i32))) - (import "seal1" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 16 16)) - - (func $assert (param i32) - (block $ok - (br_if $ok (local.get 0)) - (unreachable) - ) - ) - - ;; [0, 4) len of input buffer: 8 byte (func_ids) + 1byte (stop_recurse) - (data (i32.const 0) "\09") - - ;; [4, 16) buffer for input - - ;; [16, 48] buffer for self address - - ;; [48, 52] len of self address buffer - (data (i32.const 48) "\20") - - (func (export "deploy")) - - (func (export "call") - ;; input: (func_id1: i32, func_id2: i32, stop_recurse: i8) - (call $seal_input (i32.const 4) (i32.const 0)) - - (call $seal_call_chain_extension - (i32.load (i32.const 4)) ;; id - (i32.const 0) ;; input_ptr - (i32.const 0) ;; input_len - (i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; output_len_ptr - ) - drop - - (call $seal_call_chain_extension - (i32.load (i32.const 8)) ;; _id - (i32.const 0) ;; input_ptr - (i32.const 0) ;; input_len - (i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; output_len_ptr - ) - drop - - (if (i32.eqz (i32.load8_u (i32.const 12))) - (then - ;; stop recursion - (i32.store8 (i32.const 12) (i32.const 1)) - - ;; load own address into buffer - (call $seal_address (i32.const 16) (i32.const 48)) - - ;; call function 2 + 3 of chainext 3 next time - ;; (3 << 16) | 2 - ;; (3 << 16) | 3 - (i32.store (i32.const 4) (i32.const 196610)) - (i32.store (i32.const 8) (i32.const 196611)) - - ;; call self - (call $seal_call - (i32.const 8) ;; Set ALLOW_REENTRY - (i32.const 16) ;; Pointer to "callee" address. - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 512) ;; Pointer to the buffer with value to transfer - (i32.const 4) ;; Pointer to input data buffer address - (i32.load (i32.const 0)) ;; Length of input data buffer - (i32.const 4294967295) ;; u32 max value is the sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this case - ) - - ;; check that call succeeded of call - (call $assert (i32.eqz)) - ) - (else) - ) - ) -) diff --git a/substrate/frame/contracts/fixtures/data/create_storage_and_call.wat b/substrate/frame/contracts/fixtures/data/create_storage_and_call.wat deleted file mode 100644 index 2bff53b638f..00000000000 --- a/substrate/frame/contracts/fixtures/data/create_storage_and_call.wat +++ /dev/null @@ -1,60 +0,0 @@ -;; This calls another contract as passed as its account id. It also creates some storage. -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) - (import "seal2" "call" (func $seal_call (param i32 i32 i64 i64 i32 i32 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "deploy")) - - (func (export "call") - ;; store length of input buffer - (i32.store (i32.const 0) (i32.const 512)) - - ;; copy input at address 4: - ;; first 4 bytes for the size of the storage to be created in callee - ;; next 32 bytes are for the callee address - ;; next bytes for the encoded deposit limit - (call $seal_input (i32.const 4) (i32.const 0)) - - ;; create 4 byte of storage before calling - (call $seal_set_storage - (i32.const 0) ;; Pointer to storage key - (i32.const 0) ;; Pointer to value - (i32.const 4) ;; Size of value - ) - - ;; call passed contract - (call $assert (i32.eqz - (call $seal_call - (i32.const 0) ;; No flags - (i32.const 8) ;; Pointer to "callee" address - (i64.const 0) ;; How much ref_time to devote for the execution. 0 = all - (i64.const 0) ;; How much proof_limit to devote for the execution. 0 = all - (i32.const 40) ;; Pointer to the storage deposit limit - (i32.const 512) ;; Pointer to the buffer with value to transfer - (i32.const 4) ;; Pointer to input data buffer address - (i32.const 4) ;; Length of input data buffer - (i32.const 4294967295) ;; u32 max value is the sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this case - ) - )) - - ;; create 8 byte of storage after calling - ;; item of 12 bytes because we override 4 bytes - (call $seal_set_storage - (i32.const 0) ;; Pointer to storage key - (i32.const 0) ;; Pointer to value - (i32.const 12) ;; Size of value - ) - ) -) diff --git a/substrate/frame/contracts/fixtures/data/create_storage_and_instantiate.wat b/substrate/frame/contracts/fixtures/data/create_storage_and_instantiate.wat deleted file mode 100644 index 00c9a657f39..00000000000 --- a/substrate/frame/contracts/fixtures/data/create_storage_and_instantiate.wat +++ /dev/null @@ -1,66 +0,0 @@ -;; This instantiates another contract and passes some input to its constructor. -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) - (import "seal2" "instantiate" (func $seal_instantiate - (param i32 i64 i64 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32) - )) - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; [0, 8) send 10_000 balance - (data (i32.const 48) "\10\27\00\00\00\00\00\00") - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "deploy")) - - (func (export "call") - ;; store length of input buffer - (i32.store (i32.const 0) (i32.const 512)) - ;; store length of contract address - (i32.store (i32.const 84) (i32.const 32)) - - ;; copy input at address 4 - (call $seal_input (i32.const 4) (i32.const 0)) - - ;; memory layout is: - ;; [0,4): size of input buffer - ;; [4,8): size of the storage to be created in callee - ;; [8,40): the code hash of the contract to instantiate - ;; [40,48): for the encoded deposit limit - ;; [48,52): value to transfer - ;; [52,84): address of the deployed contract - ;; [84,88): len of the address - - ;; instantiate a contract - (call $assert (i32.eqz -;; (i32.store -;; (i32.const 64) - (call $seal_instantiate - (i32.const 8) ;; Pointer to the code hash. - (i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all. - (i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all. - (i32.const 40) ;; Pointer to the storage deposit limit - (i32.const 48) ;; Pointer to the buffer with value to transfer - (i32.const 4) ;; Pointer to input data buffer address - (i32.const 4) ;; Length of input data buffer - (i32.const 52) ;; Pointer to where to copy address - (i32.const 84) ;; Pointer to address len ptr - (i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this case - (i32.const 0) ;; salt_ptr - (i32.const 0) ;; salt_len - ) - )) - ;; return the deployed contract address - (call $seal_return (i32.const 0) (i32.const 52) (i32.const 32)) - ) -) diff --git a/substrate/frame/contracts/fixtures/data/crypto_hashes.wat b/substrate/frame/contracts/fixtures/data/crypto_hashes.wat deleted file mode 100644 index 9d86b02f419..00000000000 --- a/substrate/frame/contracts/fixtures/data/crypto_hashes.wat +++ /dev/null @@ -1,83 +0,0 @@ -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - - (import "seal0" "seal_hash_sha2_256" (func $seal_hash_sha2_256 (param i32 i32 i32))) - (import "seal0" "seal_hash_keccak_256" (func $seal_hash_keccak_256 (param i32 i32 i32))) - (import "seal0" "seal_hash_blake2_256" (func $seal_hash_blake2_256 (param i32 i32 i32))) - (import "seal0" "seal_hash_blake2_128" (func $seal_hash_blake2_128 (param i32 i32 i32))) - - (import "env" "memory" (memory 1 1)) - - (type $hash_fn_sig (func (param i32 i32 i32))) - (table 8 funcref) - (elem (i32.const 1) - $seal_hash_sha2_256 - $seal_hash_keccak_256 - $seal_hash_blake2_256 - $seal_hash_blake2_128 - ) - (data (i32.const 1) "20202010201008") ;; Output sizes of the hashes in order in hex. - - ;; Not in use by the tests besides instantiating the contract. - (func (export "deploy")) - - ;; Called by the tests. - ;; - ;; The `call` function expects data in a certain format in the input buffer. - ;; - ;; 1. The first byte encodes an identifier for the crypto hash function - ;; under test. (*) - ;; 2. The rest encodes the input data that is directly fed into the - ;; crypto hash function chosen in 1. - ;; - ;; The `deploy` function then computes the chosen crypto hash function - ;; given the input and puts the result into the output buffer. - ;; After contract execution the test driver then asserts that the returned - ;; values are equal to the expected bytes for the input and chosen hash - ;; function. - ;; - ;; (*) The possible value for the crypto hash identifiers can be found below: - ;; - ;; | value | Algorithm | Bit Width | - ;; |-------|-----------|-----------| - ;; | 0 | SHA2 | 256 | - ;; | 1 | KECCAK | 256 | - ;; | 2 | BLAKE2 | 256 | - ;; | 3 | BLAKE2 | 128 | - ;; --------------------------------- - (func (export "call") - (local $chosen_hash_fn i32) - (local $input_len_ptr i32) - (local $input_ptr i32) - (local $input_len i32) - (local $output_ptr i32) - (local $output_len i32) - (local.set $input_len_ptr (i32.const 256)) - (local.set $input_ptr (i32.const 10)) - (i32.store (local.get $input_len_ptr) (i32.const 246)) - (call $seal_input (local.get $input_ptr) (local.get $input_len_ptr)) - (local.set $chosen_hash_fn (i32.load8_u (local.get $input_ptr))) - (if (i32.gt_u (local.get $chosen_hash_fn) (i32.const 7)) - (then - ;; We check that the chosen hash fn identifier is within bounds: [0,7] - (unreachable) - ) - ) - (local.set $input_ptr (i32.add (local.get $input_ptr) (i32.const 1))) - (local.set $input_len (i32.sub (i32.load (local.get $input_len_ptr)) (i32.const 1))) - (local.set $output_len (i32.load8_u (local.get $chosen_hash_fn))) - (call_indirect (type $hash_fn_sig) - (local.get $input_ptr) - (local.get $input_len) - (local.get $input_ptr) - (local.get $chosen_hash_fn) ;; Which crypto hash function to execute. - ) - (call $seal_return - (i32.const 0) - (local.get $input_ptr) ;; Linear memory location of the output buffer. - (local.get $output_len) ;; Number of output buffer bytes. - ) - (unreachable) - ) -) diff --git a/substrate/frame/contracts/fixtures/data/debug_message_invalid_utf8.wat b/substrate/frame/contracts/fixtures/data/debug_message_invalid_utf8.wat deleted file mode 100644 index dae0de88418..00000000000 --- a/substrate/frame/contracts/fixtures/data/debug_message_invalid_utf8.wat +++ /dev/null @@ -1,28 +0,0 @@ -;; Emit a debug message with an invalid utf-8 code -(module - (import "seal0" "seal_debug_message" (func $seal_debug_message (param i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - - (data (i32.const 0) "\fc") - - (func $assert_eq (param i32 i32) - (block $ok - (br_if $ok - (i32.eq (local.get 0) (local.get 1)) - ) - (unreachable) - ) - ) - - (func (export "call") - (call $assert_eq - (call $seal_debug_message - (i32.const 0) ;; Pointer to the text buffer - (i32.const 12) ;; The size of the buffer - ) - (i32.const 0) ;; Success return code - ) - ) - - (func (export "deploy")) -) diff --git a/substrate/frame/contracts/fixtures/data/debug_message_logging_disabled.wat b/substrate/frame/contracts/fixtures/data/debug_message_logging_disabled.wat deleted file mode 100644 index e9ce20ba42b..00000000000 --- a/substrate/frame/contracts/fixtures/data/debug_message_logging_disabled.wat +++ /dev/null @@ -1,28 +0,0 @@ -;; Emit a "Hello World!" debug message but assume that logging is disabled. -(module - (import "seal0" "seal_debug_message" (func $seal_debug_message (param i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - - (data (i32.const 0) "Hello World!") - - (func $assert_eq (param i32 i32) - (block $ok - (br_if $ok - (i32.eq (local.get 0) (local.get 1)) - ) - (unreachable) - ) - ) - - (func (export "call") - (call $assert_eq - (call $seal_debug_message - (i32.const 0) ;; Pointer to the text buffer - (i32.const 12) ;; The size of the buffer - ) - (i32.const 0) ;; Success return code - ) - ) - - (func (export "deploy")) -) diff --git a/substrate/frame/contracts/fixtures/data/debug_message_works.wat b/substrate/frame/contracts/fixtures/data/debug_message_works.wat deleted file mode 100644 index 44a7b6db1be..00000000000 --- a/substrate/frame/contracts/fixtures/data/debug_message_works.wat +++ /dev/null @@ -1,28 +0,0 @@ -;; Emit a "Hello World!" debug message -(module - (import "seal0" "seal_debug_message" (func $seal_debug_message (param i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - - (data (i32.const 0) "Hello World!") - - (func $assert_eq (param i32 i32) - (block $ok - (br_if $ok - (i32.eq (local.get 0) (local.get 1)) - ) - (unreachable) - ) - ) - - (func (export "call") - (call $assert_eq - (call $seal_debug_message - (i32.const 0) ;; Pointer to the text buffer - (i32.const 12) ;; The size of the buffer - ) - (i32.const 0) ;; success return code - ) - ) - - (func (export "deploy")) -) diff --git a/substrate/frame/contracts/fixtures/data/delegate_call.wat b/substrate/frame/contracts/fixtures/data/delegate_call.wat deleted file mode 100644 index b8d4f0d47f0..00000000000 --- a/substrate/frame/contracts/fixtures/data/delegate_call.wat +++ /dev/null @@ -1,111 +0,0 @@ -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_get_storage" (func $seal_get_storage (param i32 i32 i32) (result i32))) - (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) - (import "seal0" "seal_delegate_call" (func $seal_delegate_call (param i32 i32 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 3 3)) - - ;; [0, 32) storage key - (data (i32.const 0) "\01") - - ;; [32, 64) storage key - (data (i32.const 32) "\02") - - ;; [64, 96) buffer where input is copied - - ;; [96, 100) size of the input buffer - (data (i32.const 96) "\20") - - ;; [100, 104) size of buffer for seal_get_storage - (data (i32.const 100) "\20") - - ;; [104, 136) seal_get_storage buffer - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "call") - (local $exit_code i32) - - ;; Reading "callee" code_hash - (call $seal_input (i32.const 64) (i32.const 96)) - - ;; assert input size == 32 - (call $assert - (i32.eq - (i32.load (i32.const 96)) - (i32.const 32) - ) - ) - - ;; place a value in storage, the size of which is specified by the call input. - (call $seal_set_storage - (i32.const 0) ;; Pointer to storage key - (i32.const 32) ;; Pointer to initial value - (i32.load (i32.const 100)) ;; Size of value - ) - - (call $assert - (i32.eq - (call $seal_get_storage - (i32.const 0) ;; Pointer to storage key - (i32.const 104) ;; buffer where to copy result - (i32.const 100) ;; pointer to size of buffer - ) - (i32.const 0) ;; ReturnCode::Success - ) - ) - - (call $assert - (i32.eq - (i32.load (i32.const 104)) ;; value received from storage - (i32.load (i32.const 32)) ;; initial value - ) - ) - - ;; Call deployed library contract code. - (local.set $exit_code - (call $seal_delegate_call - (i32.const 0) ;; Set no call flags - (i32.const 64) ;; Pointer to "callee" code_hash. - (i32.const 0) ;; Input is ignored - (i32.const 0) ;; Length of the input - (i32.const 4294967295) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this case - ) - ) - - ;; Check for success exit status. - (call $assert - (i32.eq (local.get $exit_code) (i32.const 0)) ;; ReturnCode::Success - ) - - (call $assert - (i32.eq - (call $seal_get_storage - (i32.const 0) ;; Pointer to storage key - (i32.const 104) ;; buffer where to copy result - (i32.const 100) ;; pointer to size of buffer - ) - (i32.const 0) ;; ReturnCode::Success - ) - ) - - ;; Make sure that 'callee' code changed the value - (call $assert - (i32.eq - (i32.load (i32.const 104)) - (i32.const 1) - ) - ) - ) - - (func (export "deploy")) - -) diff --git a/substrate/frame/contracts/fixtures/data/delegate_call_lib.wat b/substrate/frame/contracts/fixtures/data/delegate_call_lib.wat deleted file mode 100644 index 62eea32800a..00000000000 --- a/substrate/frame/contracts/fixtures/data/delegate_call_lib.wat +++ /dev/null @@ -1,79 +0,0 @@ -(module - (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) - (import "seal0" "seal_caller" (func $seal_caller (param i32 i32))) - (import "seal0" "seal_value_transferred" (func $seal_value_transferred (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; [0, 32) storage key - (data (i32.const 0) "\01") - - ;; [32, 64) buffer for transferred value - - ;; [64, 96) size of the buffer for transferred value - (data (i32.const 64) "\20") - - ;; [96, 128) buffer for the caller - - ;; [128, 160) size of the buffer for caller - (data (i32.const 128) "\20") - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "call") - ;; place a value in storage - (call $seal_set_storage - (i32.const 0) ;; Pointer to storage key - (i32.const 0) ;; Pointer to value - (i32.const 32) ;; Size of value - ) - - ;; This stores the value transferred in the buffer - (call $seal_value_transferred (i32.const 32) (i32.const 64)) - - ;; assert len == 8 - (call $assert - (i32.eq - (i32.load (i32.const 64)) - (i32.const 8) - ) - ) - - ;; assert that contents of the buffer is equal to the value - ;; passed to the `caller` contract: 1337 - (call $assert - (i64.eq - (i64.load (i32.const 32)) - (i64.const 1337) - ) - ) - - ;; fill the buffer with the caller. - (call $seal_caller (i32.const 96) (i32.const 128)) - - ;; assert len == 32 - (call $assert - (i32.eq - (i32.load (i32.const 128)) - (i32.const 32) - ) - ) - - ;; assert that the first 64 byte are the beginning of "ALICE", - ;; who is the caller of the `caller` contract - (call $assert - (i64.eq - (i64.load (i32.const 96)) - (i64.const 0x0101010101010101) - ) - ) - ) - - (func (export "deploy")) -) diff --git a/substrate/frame/contracts/fixtures/data/delegate_call_simple.wat b/substrate/frame/contracts/fixtures/data/delegate_call_simple.wat deleted file mode 100644 index ba0a8fcc8ae..00000000000 --- a/substrate/frame/contracts/fixtures/data/delegate_call_simple.wat +++ /dev/null @@ -1,50 +0,0 @@ -;; Just delegate call into the passed code hash and assert success. -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_delegate_call" (func $seal_delegate_call (param i32 i32 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 3 3)) - - ;; [0, 32) buffer where input is copied - - ;; [32, 36) size of the input buffer - (data (i32.const 32) "\20") - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "call") - ;; Reading "callee" code_hash - (call $seal_input (i32.const 0) (i32.const 32)) - - ;; assert input size == 32 - (call $assert - (i32.eq - (i32.load (i32.const 32)) - (i32.const 32) - ) - ) - - ;; Delegate call into passed code hash - (call $assert - (i32.eq - (call $seal_delegate_call - (i32.const 0) ;; Set no call flags - (i32.const 0) ;; Pointer to "callee" code_hash. - (i32.const 0) ;; Input is ignored - (i32.const 0) ;; Length of the input - (i32.const 4294967295) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this case - ) - (i32.const 0) - ) - ) - ) - - (func (export "deploy")) -) diff --git a/substrate/frame/contracts/fixtures/data/destroy_and_transfer.wat b/substrate/frame/contracts/fixtures/data/destroy_and_transfer.wat deleted file mode 100644 index 2afd3b2fbac..00000000000 --- a/substrate/frame/contracts/fixtures/data/destroy_and_transfer.wat +++ /dev/null @@ -1,161 +0,0 @@ -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_get_storage" (func $seal_get_storage (param i32 i32 i32) (result i32))) - (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) - (import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32))) - (import "seal0" "seal_transfer" (func $seal_transfer (param i32 i32 i32 i32) (result i32))) - (import "seal0" "seal_instantiate" (func $seal_instantiate - (param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32) - )) - (import "env" "memory" (memory 1 1)) - - ;; [0, 8) value to send when creating contract. - (data (i32.const 0) "\00\00\01") - - ;; [8, 16) Value to send when calling contract. - - ;; [16, 48) The key to store the contract address under. - - ;; [48, 80) Buffer where to store the input to the contract - - ;; [88, 96) Size of the buffer - (data (i32.const 88) "\FF") - - ;; [96, 100) Size of the input buffer - (data (i32.const 96) "\20") - - ;; [100, 132) Buffer where to store the address of the instantiated contract - - ;; [132, 134) Salt - (data (i32.const 132) "\47\11") - - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "deploy") - ;; Input data is the code hash of the contract to be deployed. - (call $seal_input (i32.const 48) (i32.const 96)) - (call $assert - (i32.eq - (i32.load (i32.const 96)) - (i32.const 32) - ) - ) - - ;; Deploy the contract with the provided code hash. - (call $assert - (i32.eq - (call $seal_instantiate - (i32.const 48) ;; Pointer to the code hash. - (i32.const 32) ;; Length of the code hash. - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer. - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 0) ;; Length of input data buffer - (i32.const 100) ;; Buffer where to store address of new contract - (i32.const 88) ;; Pointer to the length of the buffer - (i32.const 4294967295) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this case - (i32.const 132) ;; salt_ptr - (i32.const 2) ;; salt_len - ) - (i32.const 0) - ) - ) - - ;; Check that address has expected length - (call $assert - (i32.eq - (i32.load (i32.const 88)) - (i32.const 32) - ) - ) - - ;; Store the return address. - (call $seal_set_storage - (i32.const 16) ;; Pointer to the key - (i32.const 100) ;; Pointer to the value - (i32.const 32) ;; Length of the value - ) - ) - - (func (export "call") - ;; Read address of destination contract from storage. - (call $assert - (i32.eq - (call $seal_get_storage - (i32.const 16) ;; Pointer to the key - (i32.const 100) ;; Pointer to the value - (i32.const 88) ;; Pointer to the len of the value - ) - (i32.const 0) - ) - ) - (call $assert - (i32.eq - (i32.load (i32.const 88)) - (i32.const 32) - ) - ) - - ;; Calling the destination contract with non-empty input data should fail. - (call $assert - (i32.eq - (call $seal_call - (i32.const 100) ;; Pointer to destination address - (i32.const 32) ;; Length of destination address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 1) ;; Length of input data buffer - (i32.const 4294967295) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this case - - ) - (i32.const 0x1) - ) - ) - - ;; Call the destination contract regularly, forcing it to self-destruct. - (call $assert - (i32.eq - (call $seal_call - (i32.const 100) ;; Pointer to destination address - (i32.const 32) ;; Length of destination address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 8) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 0) ;; Length of input data buffer - (i32.const 4294967295) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this case - ) - (i32.const 0) - ) - ) - - ;; Calling the destination address with non-empty input data should now work since the - ;; contract has been removed. Also transfer a balance to the address so we can ensure this - ;; does not hinder the contract from being removed. - (call $assert - (i32.eq - (call $seal_transfer - (i32.const 100) ;; Pointer to destination address - (i32.const 32) ;; Length of destination address - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - ) - (i32.const 0) - ) - ) - ) -) diff --git a/substrate/frame/contracts/fixtures/data/drain.wat b/substrate/frame/contracts/fixtures/data/drain.wat deleted file mode 100644 index 18a21cca803..00000000000 --- a/substrate/frame/contracts/fixtures/data/drain.wat +++ /dev/null @@ -1,75 +0,0 @@ -(module - (import "seal0" "seal_balance" (func $seal_balance (param i32 i32))) - (import "seal0" "seal_minimum_balance" (func $seal_minimum_balance (param i32 i32))) - (import "seal0" "seal_transfer" (func $seal_transfer (param i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - - ;; [0, 8) reserved for $seal_balance output - - ;; [8, 16) length of the buffer for $seal_balance - (data (i32.const 8) "\08") - - ;; [16, 24) reserved for $seal_minimum_balance - - ;; [24, 32) length of the buffer for $seal_minimum_balance - (data (i32.const 24) "\08") - - ;; [32, inf) zero initialized - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "deploy")) - - (func (export "call") - ;; Send entire remaining balance to the 0 address. - (call $seal_balance (i32.const 0) (i32.const 8)) - - ;; Balance should be encoded as a u64. - (call $assert - (i32.eq - (i32.load (i32.const 8)) - (i32.const 8) - ) - ) - - ;; Get the minimum balance. - (call $seal_minimum_balance (i32.const 16) (i32.const 24)) - - ;; Minimum balance should be encoded as a u64. - (call $assert - (i32.eq - (i32.load (i32.const 24)) - (i32.const 8) - ) - ) - - ;; Make the transferred value exceed the balance by adding the minimum balance. - (i64.store (i32.const 0) - (i64.add - (i64.load (i32.const 0)) - (i64.load (i32.const 16)) - ) - ) - - ;; Try to self-destruct by sending more balance to the 0 address. - ;; The call will fail because a contract transfer has a keep alive requirement - (call $assert - (i32.eq - (call $seal_transfer - (i32.const 32) ;; Pointer to destination address - (i32.const 48) ;; Length of destination address - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - ) - (i32.const 5) ;; ReturnCode::TransferFailed - ) - ) - ) -) diff --git a/substrate/frame/contracts/fixtures/data/ecdsa_recover.wat b/substrate/frame/contracts/fixtures/data/ecdsa_recover.wat deleted file mode 100644 index 4910e706069..00000000000 --- a/substrate/frame/contracts/fixtures/data/ecdsa_recover.wat +++ /dev/null @@ -1,55 +0,0 @@ -;; This contract: -;; 1) Reads signature and message hash from the input -;; 2) Calls ecdsa_recover -;; 3) Validates that result is Success -;; 4) Returns recovered compressed public key -(module - (import "seal0" "seal_ecdsa_recover" (func $seal_ecdsa_recover (param i32 i32 i32) (result i32))) - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "deploy")) - - ;; [4, 8) len of signature + message hash - 65 bytes + 32 byte = 97 bytes - (data (i32.const 4) "\61") - - ;; Memory layout during `call` - ;; [10, 75) signature - ;; [75, 107) message hash - (func (export "call") - (local $signature_ptr i32) - (local $message_hash_ptr i32) - (local $result i32) - (local.set $signature_ptr (i32.const 10)) - (local.set $message_hash_ptr (i32.const 75)) - ;; Read signature and message hash - 97 bytes - (call $seal_input (local.get $signature_ptr) (i32.const 4)) - (local.set - $result - (call $seal_ecdsa_recover - (local.get $signature_ptr) - (local.get $message_hash_ptr) - (local.get $signature_ptr) ;; Store output into message signature ptr, because we don't need it anymore - ) - ) - (call $assert - (i32.eq - (local.get $result) ;; The result of recovery execution - (i32.const 0x0) ;; 0x0 - Success result - ) - ) - - ;; exit with success and return recovered public key - (call $seal_return (i32.const 0) (local.get $signature_ptr) (i32.const 33)) - ) -) diff --git a/substrate/frame/contracts/fixtures/data/event_and_return_on_deploy.wat b/substrate/frame/contracts/fixtures/data/event_and_return_on_deploy.wat deleted file mode 100644 index 809cfe13545..00000000000 --- a/substrate/frame/contracts/fixtures/data/event_and_return_on_deploy.wat +++ /dev/null @@ -1,26 +0,0 @@ -(module - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "seal0" "seal_deposit_event" (func $seal_deposit_event (param i32 i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func (export "deploy") - (call $seal_deposit_event - (i32.const 0) ;; The topics buffer - (i32.const 0) ;; The topics buffer's length - (i32.const 8) ;; The data buffer - (i32.const 4) ;; The data buffer's length - ) - (call $seal_return - (i32.const 0) - (i32.const 8) - (i32.const 4) - ) - (unreachable) - ) - - (func (export "call") - (unreachable) - ) - - (data (i32.const 8) "\01\02\03\04") -) diff --git a/substrate/frame/contracts/fixtures/data/event_size.wat b/substrate/frame/contracts/fixtures/data/event_size.wat deleted file mode 100644 index 1c1f34b24d7..00000000000 --- a/substrate/frame/contracts/fixtures/data/event_size.wat +++ /dev/null @@ -1,39 +0,0 @@ -(module - (import "seal0" "seal_deposit_event" (func $seal_deposit_event (param i32 i32 i32 i32))) - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "env" "memory" (memory 16 16)) - - ;; [0, 4) size of the input buffer - (data (i32.const 0) "\04") - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "call") - (call $seal_input (i32.const 4) (i32.const 0)) - - ;; assert input size == 4 - (call $assert - (i32.eq - (i32.load (i32.const 0)) - (i32.const 4) - ) - ) - - ;; place a garbage value in storage, the size of which is specified by the call input. - (call $seal_deposit_event - (i32.const 0) ;; topics_ptr - (i32.const 0) ;; topics_len - (i32.const 0) ;; data_ptr - (i32.load (i32.const 4)) ;; data_len - ) - ) - - (func (export "deploy")) -) diff --git a/substrate/frame/contracts/fixtures/data/float_instruction.wat b/substrate/frame/contracts/fixtures/data/float_instruction.wat deleted file mode 100644 index efa6b9de52d..00000000000 --- a/substrate/frame/contracts/fixtures/data/float_instruction.wat +++ /dev/null @@ -1,12 +0,0 @@ -;; Module that contains a float instruction which is illegal in deterministic mode -(module - (import "env" "memory" (memory 1 1)) - (func (export "call") - f32.const 1 - drop - ) - (func (export "deploy") - f32.const 2 - drop - ) -) diff --git a/substrate/frame/contracts/fixtures/data/instantiate_return_code.wat b/substrate/frame/contracts/fixtures/data/instantiate_return_code.wat deleted file mode 100644 index 6a8654520f1..00000000000 --- a/substrate/frame/contracts/fixtures/data/instantiate_return_code.wat +++ /dev/null @@ -1,47 +0,0 @@ -;; This instantiats a contract and transfers 100 balance during this call and copies the return code -;; of this call to the output buffer. -;; The first 32 byte of input is the code hash to instantiate -;; The rest of the input is forwarded to the constructor of the callee -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal1" "seal_instantiate" (func $seal_instantiate - (param i32 i64 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32) - )) - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; [0, 8) 10_000 balance - (data (i32.const 0) "\10\27\00\00\00\00\00\00") - - ;; [8, 12) here we store the return code of the transfer - - ;; [12, 16) size of the input buffer - (data (i32.const 12) "\24") - - ;; [16, inf) input buffer - ;; 32 bye code hash + 4 byte forward - - (func (export "deploy")) - - (func (export "call") - (call $seal_input (i32.const 16) (i32.const 12)) - (i32.store - (i32.const 8) - (call $seal_instantiate - (i32.const 16) ;; Pointer to the code hash. - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 48) ;; Pointer to input data buffer address - (i32.const 4) ;; Length of input data buffer - (i32.const 0xffffffff) ;; u32 max sentinel value: do not copy address - (i32.const 0) ;; Length is ignored in this case - (i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this case - (i32.const 0) ;; salt_ptr - (i32.const 0) ;; salt_len - ) - ) - ;; exit with success and take transfer return code to the output buffer - (call $seal_return (i32.const 0) (i32.const 8) (i32.const 4)) - ) -) diff --git a/substrate/frame/contracts/fixtures/data/invalid_contract_no_call.wat b/substrate/frame/contracts/fixtures/data/invalid_contract_no_call.wat deleted file mode 100644 index 34f7c99ba85..00000000000 --- a/substrate/frame/contracts/fixtures/data/invalid_contract_no_call.wat +++ /dev/null @@ -1,5 +0,0 @@ -;; Valid module but missing the call function -(module - (import "env" "memory" (memory 1 1)) - (func (export "deploy")) -) diff --git a/substrate/frame/contracts/fixtures/data/multi_store.wat b/substrate/frame/contracts/fixtures/data/multi_store.wat deleted file mode 100644 index c334ed54c4e..00000000000 --- a/substrate/frame/contracts/fixtures/data/multi_store.wat +++ /dev/null @@ -1,54 +0,0 @@ -;; Does two stores to two seperate storage items -;; Expects (len0, len1) as input. -(module - (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "env" "memory" (memory 16 16)) - - ;; [0, 32) storage key 0 - (data (i32.const 0) "\01") - - ;; [32, 64) storage key 1 - (data (i32.const 32) "\02") - - ;; [64, 72) buffer where input is copied (expected sizes of storage items) - - ;; [72, 76) size of the input buffer - (data (i32.const 72) "\08") - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "call") - (call $seal_input (i32.const 64) (i32.const 72)) - - ;; assert input size == 8 - (call $assert - (i32.eq - (i32.load (i32.const 72)) - (i32.const 8) - ) - ) - - ;; place a values in storage sizes are specified in the input buffer - ;; we don't care about the contents of the storage item - (call $seal_set_storage - (i32.const 0) ;; Pointer to storage key - (i32.const 0) ;; Pointer to value - (i32.load (i32.const 64)) ;; Size of value - ) - (call $seal_set_storage - (i32.const 32) ;; Pointer to storage key - (i32.const 0) ;; Pointer to value - (i32.load (i32.const 68)) ;; Size of value - ) - ) - - (func (export "deploy")) -) diff --git a/substrate/frame/contracts/fixtures/data/new_set_code_hash_contract.wat b/substrate/frame/contracts/fixtures/data/new_set_code_hash_contract.wat deleted file mode 100644 index 86ab2737be4..00000000000 --- a/substrate/frame/contracts/fixtures/data/new_set_code_hash_contract.wat +++ /dev/null @@ -1,13 +0,0 @@ -(module - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; [0, 32) return value - (data (i32.const 0) "\02") - - (func (export "deploy")) - - (func (export "call") - (call $seal_return (i32.const 0) (i32.const 0) (i32.const 4)) - ) -) diff --git a/substrate/frame/contracts/fixtures/data/ok_trap_revert.wat b/substrate/frame/contracts/fixtures/data/ok_trap_revert.wat deleted file mode 100644 index b7eaa9b700a..00000000000 --- a/substrate/frame/contracts/fixtures/data/ok_trap_revert.wat +++ /dev/null @@ -1,35 +0,0 @@ -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func (export "deploy") - (call $ok_trap_revert) - ) - - (func (export "call") - (call $ok_trap_revert) - ) - - (func $ok_trap_revert - (i32.store (i32.const 4) (i32.const 4)) - (call $seal_input (i32.const 0) (i32.const 4)) - (block $IF_2 - (block $IF_1 - (block $IF_0 - (br_table $IF_0 $IF_1 $IF_2 - (i32.load8_u (i32.const 0)) - ) - (unreachable) - ) - ;; 0 = return with success - return - ) - ;; 1 = revert - (call $seal_return (i32.const 1) (i32.const 0) (i32.const 0)) - (unreachable) - ) - ;; 2 = trap - (unreachable) - ) -) diff --git a/substrate/frame/contracts/fixtures/data/reentrance_count_call.wat b/substrate/frame/contracts/fixtures/data/reentrance_count_call.wat deleted file mode 100644 index 44db8d041b1..00000000000 --- a/substrate/frame/contracts/fixtures/data/reentrance_count_call.wat +++ /dev/null @@ -1,76 +0,0 @@ -;; This fixture recursively tests if reentrance_count returns correct reentrant count value when -;; using seal_call to make caller contract call to itself -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_address" (func $seal_address (param i32 i32))) - (import "seal1" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32) (result i32))) - (import "seal0" "reentrance_count" (func $reentrance_count (result i32))) - (import "env" "memory" (memory 1 1)) - - ;; [0, 32) reserved for $seal_address output - - ;; [32, 36) buffer for the call stack height - - ;; [36, 40) size of the input buffer - (data (i32.const 36) "\04") - - ;; [40, 44) length of the buffer for $seal_address - (data (i32.const 40) "\20") - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - (func (export "call") - (local $expected_reentrance_count i32) - (local $seal_call_exit_code i32) - - ;; reading current contract address - (call $seal_address (i32.const 0) (i32.const 40)) - - ;; reading passed input - (call $seal_input (i32.const 32) (i32.const 36)) - - ;; reading manually passed reentrant count - (local.set $expected_reentrance_count (i32.load (i32.const 32))) - - ;; reentrance count is calculated correctly - (call $assert - (i32.eq (call $reentrance_count) (local.get $expected_reentrance_count)) - ) - - ;; re-enter 5 times in a row and assert that the reentrant counter works as expected - (i32.eq (call $reentrance_count) (i32.const 5)) - (if - (then) ;; recursion exit case - (else - ;; incrementing $expected_reentrance_count passed to the contract - (i32.store (i32.const 32) (i32.add (i32.load (i32.const 32)) (i32.const 1))) - - ;; Call to itself - (local.set $seal_call_exit_code - (call $seal_call - (i32.const 8) ;; Allow reentrancy flag set - (i32.const 0) ;; Pointer to "callee" address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 0) ;; Pointer to the buffer with value to transfer - (i32.const 32) ;; Pointer to input data buffer address - (i32.const 4) ;; Length of input data buffer - (i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; Ptr to output buffer len - ) - ) - - (call $assert - (i32.eq (local.get $seal_call_exit_code) (i32.const 0)) - ) - ) - ) - ) - - (func (export "deploy")) -) \ No newline at end of file diff --git a/substrate/frame/contracts/fixtures/data/reentrance_count_delegated_call.wat b/substrate/frame/contracts/fixtures/data/reentrance_count_delegated_call.wat deleted file mode 100644 index 49e0193bcdb..00000000000 --- a/substrate/frame/contracts/fixtures/data/reentrance_count_delegated_call.wat +++ /dev/null @@ -1,71 +0,0 @@ -;; This fixture recursively tests if reentrance_count returns correct reentrant count value when -;; using seal_delegate_call to make caller contract delegate call to itself -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) - (import "seal0" "seal_delegate_call" (func $seal_delegate_call (param i32 i32 i32 i32 i32 i32) (result i32))) - (import "seal0" "reentrance_count" (func $reentrance_count (result i32))) - (import "env" "memory" (memory 1 1)) - - ;; [0, 32) buffer where code hash is copied - - ;; [32, 36) buffer for the call stack height - - ;; [36, 40) size of the input buffer - (data (i32.const 36) "\24") - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - (func (export "call") - (local $callstack_height i32) - (local $delegate_call_exit_code i32) - - ;; Reading input - (call $seal_input (i32.const 0) (i32.const 36)) - - ;; reading passed callstack height - (local.set $callstack_height (i32.load (i32.const 32))) - - ;; incrementing callstack height - (i32.store (i32.const 32) (i32.add (i32.load (i32.const 32)) (i32.const 1))) - - ;; reentrance count stays 0 - (call $assert - (i32.eq (call $reentrance_count) (i32.const 0)) - ) - - (i32.eq (local.get $callstack_height) (i32.const 5)) - (if - (then) ;; exit recursion case - (else - ;; Call to itself - (local.set $delegate_call_exit_code - (call $seal_delegate_call - (i32.const 0) ;; Set no call flags - (i32.const 0) ;; Pointer to "callee" code_hash. - (i32.const 0) ;; Pointer to the input data - (i32.const 36) ;; Length of the input - (i32.const 4294967295) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this case - ) - ) - - (call $assert - (i32.eq (local.get $delegate_call_exit_code) (i32.const 0)) - ) - ) - ) - - (call $assert - (i32.le_s (local.get $callstack_height) (i32.const 5)) - ) - ) - - (func (export "deploy")) -) \ No newline at end of file diff --git a/substrate/frame/contracts/fixtures/data/return_with_data.wat b/substrate/frame/contracts/fixtures/data/return_with_data.wat deleted file mode 100644 index 93b9daa07a3..00000000000 --- a/substrate/frame/contracts/fixtures/data/return_with_data.wat +++ /dev/null @@ -1,33 +0,0 @@ -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; [0, 128) buffer where input is copied - - ;; [128, 132) length of the input buffer - (data (i32.const 128) "\80") - - ;; Deploy routine is the same as call. - (func (export "deploy") - (call $call) - ) - - ;; Call reads the first 4 bytes (LE) as the exit status and returns the rest as output data. - (func $call (export "call") - ;; Copy input into this contracts memory. - (call $seal_input (i32.const 0) (i32.const 128)) - - ;; Copy all but the first 4 bytes of the input data as the output data. - ;; Use the first byte as exit status - (call $seal_return - (i32.load8_u (i32.const 0)) ;; Exit status - (i32.const 4) ;; Pointer to the data to return. - (i32.sub ;; Count of bytes to copy. - (i32.load (i32.const 128)) - (i32.const 4) - ) - ) - (unreachable) - ) -) diff --git a/substrate/frame/contracts/fixtures/data/run_out_of_gas.wat b/substrate/frame/contracts/fixtures/data/run_out_of_gas.wat deleted file mode 100644 index fe53e92c4fa..00000000000 --- a/substrate/frame/contracts/fixtures/data/run_out_of_gas.wat +++ /dev/null @@ -1,8 +0,0 @@ -(module - (import "env" "memory" (memory 1 1)) - (func (export "call") - (loop $inf (br $inf)) ;; just run out of gas - (unreachable) - ) - (func (export "deploy")) -) diff --git a/substrate/frame/contracts/fixtures/data/self_destruct.wat b/substrate/frame/contracts/fixtures/data/self_destruct.wat deleted file mode 100644 index 00c3895fdde..00000000000 --- a/substrate/frame/contracts/fixtures/data/self_destruct.wat +++ /dev/null @@ -1,83 +0,0 @@ -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_address" (func $seal_address (param i32 i32))) - (import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32))) - (import "seal0" "seal_terminate" (func $seal_terminate (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; [0, 32) reserved for $seal_address output - - ;; [32, 36) length of the buffer - (data (i32.const 32) "\20") - - ;; [36, 68) Address of django - (data (i32.const 36) - "\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04" - "\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04" - ) - - ;; [68, 72) reserved for output of $seal_input - - ;; [72, 76) length of the buffer - (data (i32.const 72) "\04") - - ;; [76, inf) zero initialized - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "deploy")) - - (func (export "call") - ;; If the input data is not empty, then recursively call self with empty input data. - ;; This should trap instead of self-destructing since a contract cannot be removed live in - ;; the execution stack cannot be removed. If the recursive call traps, then trap here as - ;; well. - (call $seal_input (i32.const 68) (i32.const 72)) - (if (i32.load (i32.const 72)) - (then - (call $seal_address (i32.const 0) (i32.const 32)) - - ;; Expect address to be 8 bytes. - (call $assert - (i32.eq - (i32.load (i32.const 32)) - (i32.const 32) - ) - ) - - ;; Recursively call self with empty input data. - (call $assert - (i32.eq - (call $seal_call - (i32.const 0) ;; Pointer to own address - (i32.const 32) ;; Length of own address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 76) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 0) ;; Length of input data buffer - (i32.const 4294967295) ;; u32 max sentinel value: do not copy output - (i32.const 0) ;; Length is ignored in this case - ) - (i32.const 0) - ) - ) - ) - (else - ;; Try to terminate and give balance to django. - (call $seal_terminate - (i32.const 36) ;; Pointer to beneficiary address - (i32.const 32) ;; Length of beneficiary address - ) - (unreachable) ;; seal_terminate never returns - ) - ) - ) -) diff --git a/substrate/frame/contracts/fixtures/data/self_destructing_constructor.wat b/substrate/frame/contracts/fixtures/data/self_destructing_constructor.wat deleted file mode 100644 index 628f283a19f..00000000000 --- a/substrate/frame/contracts/fixtures/data/self_destructing_constructor.wat +++ /dev/null @@ -1,23 +0,0 @@ -(module - (import "seal0" "seal_terminate" (func $seal_terminate (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "deploy") - ;; Self-destruct by sending full balance to the 0 address. - (call $seal_terminate - (i32.const 0) ;; Pointer to destination address - (i32.const 32) ;; Length of destination address - ) - ) - - (func (export "call")) -) diff --git a/substrate/frame/contracts/fixtures/data/set_code_hash.wat b/substrate/frame/contracts/fixtures/data/set_code_hash.wat deleted file mode 100644 index c0a9557b4d0..00000000000 --- a/substrate/frame/contracts/fixtures/data/set_code_hash.wat +++ /dev/null @@ -1,43 +0,0 @@ -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "seal0" "seal_set_code_hash" (func $seal_set_code_hash (param i32) (result i32))) - - (import "env" "memory" (memory 1 1)) - - ;; [0, 32) here we store input - - ;; [32, 36) input size - (data (i32.const 32) "\20") - - ;; [36, 40) return value - (data (i32.const 36) "\01") - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "call") - (local $exit_code i32) - - (call $seal_input (i32.const 0) (i32.const 32)) - - (local.set $exit_code - (call $seal_set_code_hash (i32.const 0)) ;; Pointer to the input data. - ) - (call $assert - (i32.eq (local.get $exit_code) (i32.const 0)) ;; ReturnCode::Success - ) - - ;; we return 1 after setting new code_hash - ;; next `call` will NOT return this value, because contract code has been changed - (call $seal_return (i32.const 0) (i32.const 36) (i32.const 4)) - ) - - (func (export "deploy")) -) diff --git a/substrate/frame/contracts/fixtures/data/set_empty_storage.wat b/substrate/frame/contracts/fixtures/data/set_empty_storage.wat deleted file mode 100644 index dbcd3a1326a..00000000000 --- a/substrate/frame/contracts/fixtures/data/set_empty_storage.wat +++ /dev/null @@ -1,15 +0,0 @@ -;; This module stores a KV pair into the storage -(module - (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) - (import "env" "memory" (memory 16 16)) - - (func (export "call") - ) - (func (export "deploy") - (call $seal_set_storage - (i32.const 0) ;; Pointer to storage key - (i32.const 0) ;; Pointer to value - (i32.load (i32.const 0)) ;; Size of value - ) - ) -) diff --git a/substrate/frame/contracts/fixtures/data/sr25519_verify.wat b/substrate/frame/contracts/fixtures/data/sr25519_verify.wat deleted file mode 100644 index 2da1ceb87ea..00000000000 --- a/substrate/frame/contracts/fixtures/data/sr25519_verify.wat +++ /dev/null @@ -1,55 +0,0 @@ -;; This contract: -;; 1) Reads signature, message and public key from the input -;; 2) Calls and return the result of sr25519_verify - -(module - ;; import the host functions from the seal0 module - (import "seal0" "sr25519_verify" (func $sr25519_verify (param i32 i32 i32 i32) (result i32))) - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - - ;; give the program 1 page of memory - (import "env" "memory" (memory 1 1)) - - ;; [0, 4) length of signature + message + public key - 64 + 11 + 32 = 107 bytes - ;; write the length of the input (6b = 107) bytes at offset 0 - (data (i32.const 0) "\6b") - - (func (export "deploy")) - - (func (export "call") - ;; define local variables - (local $signature_ptr i32) - (local $pub_key_ptr i32) - (local $message_len i32) - (local $message_ptr i32) - - ;; set the pointers to the memory locations - ;; Memory layout during `call` - ;; [10, 74) signature - ;; [74, 106) public key - ;; [106, 117) message (11 bytes) - (local.set $signature_ptr (i32.const 10)) - (local.set $pub_key_ptr (i32.const 74)) - (local.set $message_ptr (i32.const 106)) - - ;; store the input into the memory, starting at the signature and - ;; up to 107 bytes stored at offset 0 - (call $seal_input (local.get $signature_ptr) (i32.const 0)) - - ;; call sr25519_verify and store the return code - (i32.store - (i32.const 0) - (call $sr25519_verify - (local.get $signature_ptr) - (local.get $pub_key_ptr) - (i32.const 11) - (local.get $message_ptr) - ) - ) - - ;; exit with success and take transfer return code to the output buffer - (call $seal_return (i32.const 0) (i32.const 0) (i32.const 4)) - ) -) - diff --git a/substrate/frame/contracts/fixtures/data/storage_size.wat b/substrate/frame/contracts/fixtures/data/storage_size.wat deleted file mode 100644 index 728bb4fcf3c..00000000000 --- a/substrate/frame/contracts/fixtures/data/storage_size.wat +++ /dev/null @@ -1,68 +0,0 @@ -(module - (import "seal0" "seal_get_storage" (func $seal_get_storage (param i32 i32 i32) (result i32))) - (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "env" "memory" (memory 16 16)) - - ;; [0, 32) storage key - (data (i32.const 0) "\01") - - ;; [32, 36) buffer where input is copied (expected size of storage item) - - ;; [36, 40) size of the input buffer - (data (i32.const 36) "\04") - - ;; [40, 44) size of buffer for seal_get_storage set to max - (data (i32.const 40) "\FF\FF\FF\FF") - - ;; [44, inf) seal_get_storage buffer - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "call") - (call $seal_input (i32.const 32) (i32.const 36)) - - ;; assert input size == 4 - (call $assert - (i32.eq - (i32.load (i32.const 36)) - (i32.const 4) - ) - ) - - ;; place a garbage value in storage, the size of which is specified by the call input. - (call $seal_set_storage - (i32.const 0) ;; Pointer to storage key - (i32.const 0) ;; Pointer to value - (i32.load (i32.const 32)) ;; Size of value - ) - - (call $assert - (i32.eq - (call $seal_get_storage - (i32.const 0) ;; Pointer to storage key - (i32.const 44) ;; buffer where to copy result - (i32.const 40) ;; pointer to size of buffer - ) - (i32.const 0) - ) - ) - - (call $assert - (i32.eq - (i32.load (i32.const 40)) - (i32.load (i32.const 32)) - ) - ) - ) - - (func (export "deploy")) - -) diff --git a/substrate/frame/contracts/fixtures/data/store_call.wat b/substrate/frame/contracts/fixtures/data/store_call.wat deleted file mode 100644 index 746b7a48b55..00000000000 --- a/substrate/frame/contracts/fixtures/data/store_call.wat +++ /dev/null @@ -1,45 +0,0 @@ -;; Stores a value of the passed size. -(module - (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "env" "memory" (memory 16 16)) - - ;; [0, 32) storage key - (data (i32.const 0) "\01") - - ;; [32, 36) buffer where input is copied (expected size of storage item) - - ;; [36, 40) size of the input buffer - (data (i32.const 36) "\04") - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "call") - (call $seal_input (i32.const 32) (i32.const 36)) - - ;; assert input size == 4 - (call $assert - (i32.eq - (i32.load (i32.const 36)) - (i32.const 4) - ) - ) - - ;; place a value in storage, the size of which is specified by the call input. - ;; we don't care about the contents of the storage item - (call $seal_set_storage - (i32.const 0) ;; Pointer to storage key - (i32.const 0) ;; Pointer to value - (i32.load (i32.const 32)) ;; Size of value - ) - ) - - (func (export "deploy")) -) diff --git a/substrate/frame/contracts/fixtures/data/store_deploy.wat b/substrate/frame/contracts/fixtures/data/store_deploy.wat deleted file mode 100644 index 7f115cba977..00000000000 --- a/substrate/frame/contracts/fixtures/data/store_deploy.wat +++ /dev/null @@ -1,45 +0,0 @@ -;; Stores a value of the passed size in constructor. -(module - (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "env" "memory" (memory 16 16)) - - ;; [0, 32) storage key - (data (i32.const 0) "\01") - - ;; [32, 36) buffer where input is copied (expected size of storage item) - - ;; [36, 40) size of the input buffer - (data (i32.const 36) "\04") - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "deploy") - (call $seal_input (i32.const 32) (i32.const 36)) - - ;; assert input size == 4 - (call $assert - (i32.eq - (i32.load (i32.const 36)) - (i32.const 4) - ) - ) - - ;; place a value in storage, the size of which is specified by the call input. - ;; we don't care about the contents of the storage item - (call $seal_set_storage - (i32.const 0) ;; Pointer to storage key - (i32.const 0) ;; Pointer to value - (i32.load (i32.const 32)) ;; Size of value - ) - ) - - (func (export "call")) -) diff --git a/substrate/frame/contracts/fixtures/data/transfer_return_code.wat b/substrate/frame/contracts/fixtures/data/transfer_return_code.wat deleted file mode 100644 index 50098851dcf..00000000000 --- a/substrate/frame/contracts/fixtures/data/transfer_return_code.wat +++ /dev/null @@ -1,34 +0,0 @@ -;; This transfers 100 balance to the zero account and copies the return code -;; of this transfer to the output buffer. -(module - (import "seal0" "seal_transfer" (func $seal_transfer (param i32 i32 i32 i32) (result i32))) - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; [0, 32) zero-adress - (data (i32.const 0) - "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" - "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" - ) - - ;; [32, 40) 100 balance - (data (i32.const 32) "\64\00\00\00\00\00\00\00") - - ;; [40, 44) here we store the return code of the transfer - - (func (export "deploy")) - - (func (export "call") - (i32.store - (i32.const 40) - (call $seal_transfer - (i32.const 0) ;; ptr to destination address - (i32.const 32) ;; length of destination address - (i32.const 32) ;; ptr to value to transfer - (i32.const 8) ;; length of value to transfer - ) - ) - ;; exit with success and take transfer return code to the output buffer - (call $seal_return (i32.const 0) (i32.const 40) (i32.const 4)) - ) -) diff --git a/substrate/frame/contracts/fixtures/data/xcm_execute.wat b/substrate/frame/contracts/fixtures/data/xcm_execute.wat deleted file mode 100644 index 72ef14ed82c..00000000000 --- a/substrate/frame/contracts/fixtures/data/xcm_execute.wat +++ /dev/null @@ -1,52 +0,0 @@ -;; This passes its input to `seal_xcm_execute` and returns the return value to its caller. -(module - (import "seal0" "xcm_execute" (func $xcm_execute (param i32 i32 i32) (result i32))) - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; 0x1000 = 4k in little endian - ;; Size of input buffer - (data (i32.const 0) "\00\10") - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "call") - ;; Receive the encoded call - (call $seal_input - (i32.const 4) ;; Pointer to the input buffer - (i32.const 0) ;; Pointer to the buffer length (before call) and to the copied data length (after call) - ) - ;; Input data layout. - ;; [0..4) - size of the call - ;; [4..) - message - - ;; Call xcm_execute with provided input. - (call $assert - (i32.eq - (call $xcm_execute - (i32.const 4) ;; Pointer where the message is stored - (i32.load (i32.const 0)) ;; Size of the message - (i32.const 100) ;; Pointer to the where the outcome is stored - ) - (i32.const 0) - ) - ) - - (call $seal_return - (i32.const 0) ;; flags - (i32.const 100) ;; Pointer to returned value - (i32.const 10) ;; length of returned value - ) - ) - - (func (export "deploy")) -) - diff --git a/substrate/frame/contracts/fixtures/data/xcm_send.wat b/substrate/frame/contracts/fixtures/data/xcm_send.wat deleted file mode 100644 index fe29ddf0f14..00000000000 --- a/substrate/frame/contracts/fixtures/data/xcm_send.wat +++ /dev/null @@ -1,59 +0,0 @@ -;; This passes its input to `seal_xcm_send` and returns the return value to its caller. -(module - (import "seal0" "xcm_send" (func $xcm_send (param i32 i32 i32 i32) (result i32))) - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; 0x1000 = 4k in little endian - ;; size of input buffer - (data (i32.const 0) "\00\10") - - (func $assert (param i32) - (block $ok - (br_if $ok - (local.get 0) - ) - (unreachable) - ) - ) - - (func (export "call") - - ;; Receive the encoded call - (call $seal_input - (i32.const 4) ;; Pointer to the input buffer - (i32.const 0) ;; Size of the length buffer - ) - - ;; Input data layout. - ;; [0..4) - size of the call - ;; [4..7) - dest - ;; [7..) - message - - ;; Call xcm_send with provided input. - (call $assert - (i32.eq - (call $xcm_send - (i32.const 4) ;; Pointer where the dest is stored - (i32.const 7) ;; Pointer where the message is stored - (i32.sub - (i32.load (i32.const 0)) ;; length of the input buffer - (i32.const 3) ;; Size of the XCM dest - ) - (i32.const 100) ;; Pointer to the where the message_id is stored - ) - (i32.const 0) - ) - ) - - ;; Return the the message_id - (call $seal_return - (i32.const 0) ;; flags - (i32.const 100) ;; Pointer to returned value - (i32.const 32) ;; length of returned value - ) - ) - - (func (export "deploy")) -) diff --git a/substrate/frame/contracts/fixtures/src/lib.rs b/substrate/frame/contracts/fixtures/src/lib.rs index fbc2647709d..4d850d75624 100644 --- a/substrate/frame/contracts/fixtures/src/lib.rs +++ b/substrate/frame/contracts/fixtures/src/lib.rs @@ -69,8 +69,7 @@ mod test { #[test] fn out_dir_should_have_compiled_mocks() { let out_dir: std::path::PathBuf = env!("OUT_DIR").into(); - let dummy_wasm = out_dir.join("dummy.wasm"); - println!("dummy_wasm: {:?}", dummy_wasm); - assert!(dummy_wasm.exists()); + assert!(out_dir.join("dummy.wasm").exists()); + assert!(out_dir.join("dummy.polkavm").exists()); } } diff --git a/substrate/frame/contracts/src/tests.rs b/substrate/frame/contracts/src/tests.rs index 4f63104ef26..28fe3c2af49 100644 --- a/substrate/frame/contracts/src/tests.rs +++ b/substrate/frame/contracts/src/tests.rs @@ -178,7 +178,7 @@ parameter_types! { pub struct TestExtension { enabled: bool, last_seen_buffer: Vec, - last_seen_inputs: (u32, u32, u32, u32), + last_seen_input_len: u32, } #[derive(Default)] @@ -201,14 +201,14 @@ impl TestExtension { TestExtensionTestValue::get().last_seen_buffer.clone() } - fn last_seen_inputs() -> (u32, u32, u32, u32) { - TestExtensionTestValue::get().last_seen_inputs + fn last_seen_input_len() -> u32 { + TestExtensionTestValue::get().last_seen_input_len } } impl Default for TestExtension { fn default() -> Self { - Self { enabled: true, last_seen_buffer: vec![], last_seen_inputs: (0, 0, 0, 0) } + Self { enabled: true, last_seen_buffer: vec![], last_seen_input_len: 0 } } } @@ -231,9 +231,7 @@ impl ChainExtension for TestExtension { }, 1 => { let env = env.only_in(); - TestExtensionTestValue::mutate(|e| { - e.last_seen_inputs = (env.val0(), env.val1(), env.val2(), env.val3()) - }); + TestExtensionTestValue::mutate(|e| e.last_seen_input_len = env.val1()); Ok(RetVal::Converging(id)) }, 2 => { @@ -2154,8 +2152,7 @@ fn chain_extension_works() { ) .result .unwrap(); - // those values passed in the fixture - assert_eq!(TestExtension::last_seen_inputs(), (4, 4, 16, 12)); + assert_eq!(TestExtension::last_seen_input_len(), 4); // 2 = charge some extra weight (amount supplied in the fifth byte) let result = Contracts::bare_call( @@ -3511,7 +3508,7 @@ fn failed_deposit_charge_should_roll_back_call() { let result = execute().unwrap(); // Bump the deposit per byte to a high value to trigger a FundsUnavailable error. - DEPOSIT_PER_BYTE.with(|c| *c.borrow_mut() = ED); + DEPOSIT_PER_BYTE.with(|c| *c.borrow_mut() = 20); assert_err_with_weight!(execute(), TokenError::FundsUnavailable, result.actual_weight); } diff --git a/substrate/frame/contracts/src/wasm/mod.rs b/substrate/frame/contracts/src/wasm/mod.rs index 4650a9bc79a..d00ec2e4752 100644 --- a/substrate/frame/contracts/src/wasm/mod.rs +++ b/substrate/frame/contracts/src/wasm/mod.rs @@ -2460,7 +2460,7 @@ mod tests { assert_eq!( result, Err(ExecError { - error: Error::::OutOfBounds.into(), + error: Error::::DecodingFailed.into(), origin: ErrorOrigin::Caller, }) ); @@ -3428,4 +3428,20 @@ mod tests { assert_eq!(delegate_dependencies.len(), 1); assert_eq!(delegate_dependencies[0].as_bytes(), [1; 32]); } + + // This test checks that [`Runtime::read_sandbox_memory_as`] works, when the decoded type has a + // max_len greater than the memory size, but the decoded data fits into the memory. + #[test] + fn read_sandbox_memory_as_works_with_max_len_out_of_bounds_but_fitting_actual_data() { + use frame_support::BoundedVec; + use sp_core::ConstU32; + + let mut ext = MockExt::default(); + let runtime = Runtime::new(&mut ext, vec![]); + let data = vec![1u8, 2, 3]; + let memory = data.encode(); + let decoded: BoundedVec> = + runtime.read_sandbox_memory_as(&memory, 0u32).unwrap(); + assert_eq!(decoded.into_inner(), data); + } } diff --git a/substrate/frame/contracts/src/wasm/runtime.rs b/substrate/frame/contracts/src/wasm/runtime.rs index 871ef05c37e..7b1e35ee1ad 100644 --- a/substrate/frame/contracts/src/wasm/runtime.rs +++ b/substrate/frame/contracts/src/wasm/runtime.rs @@ -583,9 +583,8 @@ impl<'a, E: Ext + 'a> Runtime<'a, E> { ptr: u32, ) -> Result { let ptr = ptr as usize; - let mut bound_checked = memory - .get(ptr..ptr + D::max_encoded_len() as usize) - .ok_or_else(|| Error::::OutOfBounds)?; + let mut bound_checked = memory.get(ptr..).ok_or_else(|| Error::::OutOfBounds)?; + let decoded = D::decode_with_depth_limit(MAX_DECODE_NESTING, &mut bound_checked) .map_err(|_| DispatchError::from(Error::::DecodingFailed))?; Ok(decoded) diff --git a/substrate/frame/contracts/uapi/src/host.rs b/substrate/frame/contracts/uapi/src/host.rs index 8f76b21ec9f..21350bc4eb3 100644 --- a/substrate/frame/contracts/uapi/src/host.rs +++ b/substrate/frame/contracts/uapi/src/host.rs @@ -38,6 +38,7 @@ macro_rules! hash_fn { // TODO remove cfg once used by all targets #[cfg(target_arch = "wasm32")] +#[inline(always)] fn extract_from_slice(output: &mut &mut [u8], new_len: usize) { debug_assert!(new_len <= output.len()); let tmp = core::mem::take(output); @@ -45,7 +46,8 @@ fn extract_from_slice(output: &mut &mut [u8], new_len: usize) { } #[cfg(target_arch = "wasm32")] -fn ptr_len_or_sentinel(data: &mut Option<&mut [u8]>) -> (*mut u8, u32) { +#[inline(always)] +fn ptr_len_or_sentinel(data: &mut Option<&mut &mut [u8]>) -> (*mut u8, u32) { match data { Some(ref mut data) => (data.as_mut_ptr(), data.len() as _), None => (crate::SENTINEL as _, 0), @@ -53,6 +55,7 @@ fn ptr_len_or_sentinel(data: &mut Option<&mut [u8]>) -> (*mut u8, u32) { } #[cfg(target_arch = "wasm32")] +#[inline(always)] fn ptr_or_sentinel(data: &Option<&[u8]>) -> *const u8 { match data { Some(ref data) => data.as_ptr(), @@ -132,7 +135,7 @@ pub trait HostFn { gas: u64, value: &[u8], input_data: &[u8], - output: Option<&mut [u8]>, + output: Option<&mut &mut [u8]>, ) -> Result; /// Make a call to another contract. @@ -145,7 +148,7 @@ pub trait HostFn { gas: u64, value: &[u8], input_data: &[u8], - output: Option<&mut [u8]>, + output: Option<&mut &mut [u8]>, ) -> Result; /// Call (possibly transferring some amount of funds) into the specified account. @@ -186,7 +189,7 @@ pub trait HostFn { deposit: Option<&[u8]>, value: &[u8], input_data: &[u8], - output: Option<&mut [u8]>, + output: Option<&mut &mut [u8]>, ) -> Result; /// Call into the chain extension provided by the chain if any. @@ -211,7 +214,7 @@ pub trait HostFn { /// # Return /// /// The chain extension returned value, if executed successfully. - fn call_chain_extension(func_id: u32, input: &[u8], output: Option<&mut [u8]>) -> u32; + fn call_chain_extension(func_id: u32, input: &[u8], output: Option<&mut &mut [u8]>) -> u32; /// Call some dispatchable of the runtime. /// @@ -374,7 +377,7 @@ pub trait HostFn { flags: CallFlags, code_hash: &[u8], input_data: &[u8], - output: Option<&mut [u8]>, + output: Option<&mut &mut [u8]>, ) -> Result; /// Deposit a contract event with the data buffer and optional list of topics. There is a limit @@ -485,8 +488,8 @@ pub trait HostFn { gas: u64, value: &[u8], input: &[u8], - address: Option<&mut [u8]>, - output: Option<&mut [u8]>, + address: Option<&mut &mut [u8]>, + output: Option<&mut &mut [u8]>, salt: &[u8], ) -> Result; @@ -534,8 +537,8 @@ pub trait HostFn { deposit: Option<&[u8]>, value: &[u8], input: &[u8], - address: Option<&mut [u8]>, - output: Option<&mut [u8]>, + address: Option<&mut &mut [u8]>, + output: Option<&mut &mut [u8]>, salt: &[u8], ) -> Result; diff --git a/substrate/frame/contracts/uapi/src/host/riscv32.rs b/substrate/frame/contracts/uapi/src/host/riscv32.rs index 4132768abc2..b1934cc469e 100644 --- a/substrate/frame/contracts/uapi/src/host/riscv32.rs +++ b/substrate/frame/contracts/uapi/src/host/riscv32.rs @@ -84,8 +84,8 @@ impl HostFn for HostFnImpl { gas: u64, value: &[u8], input: &[u8], - mut address: Option<&mut [u8]>, - mut output: Option<&mut [u8]>, + mut address: Option<&mut &mut [u8]>, + mut output: Option<&mut &mut [u8]>, salt: &[u8], ) -> Result { todo!() @@ -98,8 +98,8 @@ impl HostFn for HostFnImpl { deposit: Option<&[u8]>, value: &[u8], input: &[u8], - mut address: Option<&mut [u8]>, - mut output: Option<&mut [u8]>, + mut address: Option<&mut &mut [u8]>, + mut output: Option<&mut &mut [u8]>, salt: &[u8], ) -> Result { todo!() @@ -110,7 +110,7 @@ impl HostFn for HostFnImpl { gas: u64, value: &[u8], input_data: &[u8], - mut output: Option<&mut [u8]>, + mut output: Option<&mut &mut [u8]>, ) -> Result { todo!() } @@ -121,7 +121,7 @@ impl HostFn for HostFnImpl { gas: u64, value: &[u8], input_data: &[u8], - mut output: Option<&mut [u8]>, + mut output: Option<&mut &mut [u8]>, ) -> Result { todo!() } @@ -134,7 +134,7 @@ impl HostFn for HostFnImpl { deposit: Option<&[u8]>, value: &[u8], input_data: &[u8], - mut output: Option<&mut [u8]>, + mut output: Option<&mut &mut [u8]>, ) -> Result { todo!() } @@ -147,7 +147,7 @@ impl HostFn for HostFnImpl { flags: CallFlags, code_hash: &[u8], input: &[u8], - mut output: Option<&mut [u8]>, + mut output: Option<&mut &mut [u8]>, ) -> Result { todo!() } @@ -203,7 +203,7 @@ impl HostFn for HostFnImpl { todo!() } - fn call_chain_extension(func_id: u32, input: &[u8], output: Option<&mut [u8]>) -> u32 { + fn call_chain_extension(func_id: u32, input: &[u8], output: Option<&mut &mut [u8]>) -> u32 { todo!() } diff --git a/substrate/frame/contracts/uapi/src/host/wasm32.rs b/substrate/frame/contracts/uapi/src/host/wasm32.rs index 29fa1706a84..77cf22891e2 100644 --- a/substrate/frame/contracts/uapi/src/host/wasm32.rs +++ b/substrate/frame/contracts/uapi/src/host/wasm32.rs @@ -336,13 +336,14 @@ macro_rules! impl_hash_fn { } impl HostFn for HostFnImpl { + #[inline(always)] fn instantiate_v1( code_hash: &[u8], gas: u64, value: &[u8], input: &[u8], - mut address: Option<&mut [u8]>, - mut output: Option<&mut [u8]>, + mut address: Option<&mut &mut [u8]>, + mut output: Option<&mut &mut [u8]>, salt: &[u8], ) -> Result { let (address_ptr, mut address_len) = ptr_len_or_sentinel(&mut address); @@ -379,8 +380,8 @@ impl HostFn for HostFnImpl { deposit: Option<&[u8]>, value: &[u8], input: &[u8], - mut address: Option<&mut [u8]>, - mut output: Option<&mut [u8]>, + mut address: Option<&mut &mut [u8]>, + mut output: Option<&mut &mut [u8]>, salt: &[u8], ) -> Result { let (address_ptr, mut address_len) = ptr_len_or_sentinel(&mut address); @@ -418,12 +419,13 @@ impl HostFn for HostFnImpl { ret_code.into() } + #[inline(always)] fn call( callee: &[u8], gas: u64, value: &[u8], input_data: &[u8], - mut output: Option<&mut [u8]>, + mut output: Option<&mut &mut [u8]>, ) -> Result { let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output); let ret_code = { @@ -449,13 +451,14 @@ impl HostFn for HostFnImpl { ret_code.into() } + #[inline(always)] fn call_v1( flags: CallFlags, callee: &[u8], gas: u64, value: &[u8], input_data: &[u8], - mut output: Option<&mut [u8]>, + mut output: Option<&mut &mut [u8]>, ) -> Result { let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output); let ret_code = { @@ -488,7 +491,7 @@ impl HostFn for HostFnImpl { deposit: Option<&[u8]>, value: &[u8], input_data: &[u8], - mut output: Option<&mut [u8]>, + mut output: Option<&mut &mut [u8]>, ) -> Result { let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output); let deposit_ptr = ptr_or_sentinel(&deposit); @@ -520,11 +523,12 @@ impl HostFn for HostFnImpl { unsafe { sys::caller_is_root() }.into_u32() } + #[inline(always)] fn delegate_call( flags: CallFlags, code_hash: &[u8], input: &[u8], - mut output: Option<&mut [u8]>, + mut output: Option<&mut &mut [u8]>, ) -> Result { let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output); let ret_code = { @@ -602,6 +606,7 @@ impl HostFn for HostFnImpl { ret_code.into() } + #[inline(always)] fn get_storage(key: &[u8], output: &mut &mut [u8]) -> Result { let mut output_len = output.len() as u32; let ret_code = @@ -610,6 +615,7 @@ impl HostFn for HostFnImpl { ret_code.into() } + #[inline(always)] fn get_storage_v1(key: &[u8], output: &mut &mut [u8]) -> Result { let mut output_len = output.len() as u32; let ret_code = { @@ -626,6 +632,7 @@ impl HostFn for HostFnImpl { ret_code.into() } + #[inline(always)] fn take_storage(key: &[u8], output: &mut &mut [u8]) -> Result { let mut output_len = output.len() as u32; let ret_code = { @@ -665,7 +672,7 @@ impl HostFn for HostFnImpl { unsafe { sys::v1::terminate(beneficiary.as_ptr()) } } - fn call_chain_extension(func_id: u32, input: &[u8], mut output: Option<&mut [u8]>) -> u32 { + fn call_chain_extension(func_id: u32, input: &[u8], mut output: Option<&mut &mut [u8]>) -> u32 { let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output); let ret_code = { unsafe { @@ -685,6 +692,7 @@ impl HostFn for HostFnImpl { ret_code.into_u32() } + #[inline(always)] fn input(output: &mut &mut [u8]) { let mut output_len = output.len() as u32; { @@ -707,6 +715,7 @@ impl HostFn for HostFnImpl { (v1) => [gas_left], } + #[inline(always)] fn weight_to_fee(gas: u64, output: &mut &mut [u8]) { let mut output_len = output.len() as u32; { diff --git a/substrate/frame/contracts/uapi/src/lib.rs b/substrate/frame/contracts/uapi/src/lib.rs index 99d77f504ed..83877c6efd4 100644 --- a/substrate/frame/contracts/uapi/src/lib.rs +++ b/substrate/frame/contracts/uapi/src/lib.rs @@ -36,7 +36,7 @@ macro_rules! define_error_codes { ) => { /// Every error that can be returned to a contract when it calls any of the host functions. #[derive(Debug, PartialEq, Eq)] - #[repr(u32)] + #[repr(u8)] pub enum ReturnErrorCode { /// API call successful. Success = 0, -- GitLab From 38a0ac0012c6f2dfc37b46af1b015ed3a5e296a3 Mon Sep 17 00:00:00 2001 From: Jun Jiang Date: Sat, 13 Jan 2024 16:00:52 +0800 Subject: [PATCH 047/392] Upgrade aquamarine to v0.5.0, v0.4.0 has yanked (#2921) aquamarine v0.4.0 has yanked, see https://crates.io/crates/aquamarine/0.4.0 --- Cargo.lock | 4 ++-- substrate/frame/bags-list/Cargo.toml | 2 +- substrate/frame/support/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 217288702ae..0452f04908f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -333,9 +333,9 @@ dependencies = [ [[package]] name = "aquamarine" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "074b80d14d0240b6ce94d68f059a2d26a5d77280ae142662365a21ef6e2594ef" +checksum = "21cc1548309245035eb18aa7f0967da6bc65587005170c56e6ef2788a4cf3f4e" dependencies = [ "include_dir", "itertools 0.10.5", diff --git a/substrate/frame/bags-list/Cargo.toml b/substrate/frame/bags-list/Cargo.toml index 7fab47a20e1..bd0d4884b4e 100644 --- a/substrate/frame/bags-list/Cargo.toml +++ b/substrate/frame/bags-list/Cargo.toml @@ -35,7 +35,7 @@ frame-election-provider-support = { path = "../election-provider-support", defau # third party log = { version = "0.4.17", default-features = false } docify = "0.2.6" -aquamarine = { version = "0.4.0" } +aquamarine = { version = "0.5.0" } # Optional imports for benchmarking frame-benchmarking = { path = "../benchmarking", default-features = false, optional = true } diff --git a/substrate/frame/support/Cargo.toml b/substrate/frame/support/Cargo.toml index 04717c012f4..dafb86bd660 100644 --- a/substrate/frame/support/Cargo.toml +++ b/substrate/frame/support/Cargo.toml @@ -50,7 +50,7 @@ serde_json = { version = "1.0.111", default-features = false, features = ["alloc docify = "0.2.6" static_assertions = "1.1.0" -aquamarine = { version = "0.4.0" } +aquamarine = { version = "0.5.0" } [dev-dependencies] assert_matches = "1.3.0" -- GitLab From 127b9bec15f8a83964ef6049209df75da47b1479 Mon Sep 17 00:00:00 2001 From: maksimryndin Date: Sat, 13 Jan 2024 09:53:09 +0100 Subject: [PATCH 048/392] wasm-builder: bump toml from 0.8.2 to 0.8.8; replace ansi_term (#2914) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hi folks! Thank for the well organized codebase and an outstanding engineering! I am trying to compile a substrate node template from source (https://github.com/paritytech/polkadot-sdk) and encountered a dependency conflict ![Screenshot 2024-01-11 at 12 22 16](https://github.com/paritytech/polkadot-sdk/assets/16288656/b630773f-9d58-4abc-a15c-45f0e6b96b48) and a deprecation warning from advisory db for `ansi_term` (I see you replace it with some alternatives in other crates). While for `ansi_term` there is an adopted fork (https://github.com/rustadopt/ansiterm-rs) and it was my first commit in the PR, I've decided to use https://github.com/console-rs/console as you already use it to reduce dependencies (as I believe other substrate crates will remove ansi_term eventually) --------- Co-authored-by: Bastian Köcher --- Cargo.lock | 99 ++++++++++++++----- substrate/utils/wasm-builder/Cargo.toml | 4 +- .../utils/wasm-builder/src/prerequisites.rs | 11 +-- .../utils/wasm-builder/src/wasm_project.rs | 3 +- 4 files changed, 86 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0452f04908f..b20adebf963 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2922,15 +2922,15 @@ dependencies = [ [[package]] name = "console" -version = "0.15.7" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" dependencies = [ "encode_unicode", "lazy_static", "libc", "unicode-width", - "windows-sys 0.45.0", + "windows-sys 0.52.0", ] [[package]] @@ -9625,7 +9625,7 @@ dependencies = [ "polkavm-linker", "sp-runtime", "tempfile", - "toml 0.8.2", + "toml 0.8.8", "twox-hash", "wat", ] @@ -19632,15 +19632,15 @@ dependencies = [ name = "substrate-wasm-builder" version = "5.0.0-dev" dependencies = [ - "ansi_term", "build-helper", "cargo_metadata", + "console", "filetime", "parity-wasm", "sp-maybe-compressed-blob", "strum", "tempfile", - "toml 0.8.2", + "toml 0.8.8", "walkdir", "wasm-opt", ] @@ -20296,14 +20296,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.2" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.20.2", + "toml_edit 0.21.0", ] [[package]] @@ -20328,19 +20328,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "toml_edit" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" -dependencies = [ - "indexmap 2.0.0", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", -] - [[package]] name = "toml_edit" version = "0.21.0" @@ -20348,6 +20335,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ "indexmap 2.0.0", + "serde", + "serde_spanned", "toml_datetime", "winnow", ] @@ -21710,6 +21699,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -21740,6 +21738,21 @@ dependencies = [ "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -21752,6 +21765,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.34.0" @@ -21770,6 +21789,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.34.0" @@ -21788,6 +21813,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.34.0" @@ -21806,6 +21837,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.34.0" @@ -21824,6 +21861,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -21836,6 +21879,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.34.0" @@ -21854,6 +21903,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "winnow" version = "0.5.15" diff --git a/substrate/utils/wasm-builder/Cargo.toml b/substrate/utils/wasm-builder/Cargo.toml index 2154cfca177..ffe95994c65 100644 --- a/substrate/utils/wasm-builder/Cargo.toml +++ b/substrate/utils/wasm-builder/Cargo.toml @@ -15,12 +15,12 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -ansi_term = "0.12.1" build-helper = "0.1.1" cargo_metadata = "0.15.4" +console = "0.15.8" strum = { version = "0.24.1", features = ["derive"] } tempfile = "3.1.0" -toml = "0.8.2" +toml = "0.8.8" walkdir = "2.3.2" sp-maybe-compressed-blob = { path = "../../primitives/maybe-compressed-blob" } filetime = "0.2.16" diff --git a/substrate/utils/wasm-builder/src/prerequisites.rs b/substrate/utils/wasm-builder/src/prerequisites.rs index 2cdbdd2798e..99eb6ee1f18 100644 --- a/substrate/utils/wasm-builder/src/prerequisites.rs +++ b/substrate/utils/wasm-builder/src/prerequisites.rs @@ -17,15 +17,14 @@ use crate::{write_file_if_changed, CargoCommand, CargoCommandVersioned}; +use console::style; use std::{fs, path::Path}; - -use ansi_term::Color; use tempfile::tempdir; /// Print an error message. fn print_error_message(message: &str) -> String { if super::color_output_enabled() { - Color::Red.bold().paint(message).to_string() + style(message).red().bold().to_string() } else { message.into() } @@ -117,10 +116,10 @@ fn check_wasm_toolchain_installed( Ok(ref err) => Err(format!( "{}\n\n{}\n{}\n{}{}\n", err_msg, - Color::Yellow.bold().paint("Further error information:"), - Color::Yellow.bold().paint("-".repeat(60)), + style("Further error information:").yellow().bold(), + style("-".repeat(60)).yellow().bold(), err, - Color::Yellow.bold().paint("-".repeat(60)), + style("-".repeat(60)).yellow().bold(), )), Err(_) => Err(err_msg), diff --git a/substrate/utils/wasm-builder/src/wasm_project.rs b/substrate/utils/wasm-builder/src/wasm_project.rs index 2126a49bd7f..ded6b2188b0 100644 --- a/substrate/utils/wasm-builder/src/wasm_project.rs +++ b/substrate/utils/wasm-builder/src/wasm_project.rs @@ -19,6 +19,7 @@ use crate::{write_file_if_changed, CargoCommandVersioned, OFFLINE}; use build_helper::rerun_if_changed; use cargo_metadata::{DependencyKind, Metadata, MetadataCommand}; +use console::style; use parity_wasm::elements::{deserialize_buffer, Module}; use std::{ borrow::ToOwned, @@ -38,7 +39,7 @@ use walkdir::WalkDir; /// Returns the colorized message. fn colorize_info_message(message: &str) -> String { if super::color_output_enabled() { - ansi_term::Color::Yellow.bold().paint(message).to_string() + style(message).yellow().bold().to_string() } else { message.into() } -- GitLab From e879c484735c73cf77edf45e17fcd11665585162 Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Mon, 15 Jan 2024 11:55:27 +0100 Subject: [PATCH 049/392] Warp sync zombienet tests: update DB snapshot (#2928) Closes https://github.com/paritytech/polkadot-sdk/issues/2787 Regenerating the DB snapshot after fixing: https://github.com/paritytech/polkadot-sdk/pull/2919 Now we can add some BEEFY checks to `0002-validators-warp-sync` --- .gitlab/pipeline/zombienet/substrate.yml | 6 +++--- .../zombienet/0001-basic-warp-sync/chain-spec.json | 10 +++++----- .../test-validators-warp-sync.zndsl | 6 ++++++ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.gitlab/pipeline/zombienet/substrate.yml b/.gitlab/pipeline/zombienet/substrate.yml index 23630fcc6c0..8a627c454f9 100644 --- a/.gitlab/pipeline/zombienet/substrate.yml +++ b/.gitlab/pipeline/zombienet/substrate.yml @@ -47,11 +47,11 @@ extends: - .zombienet-substrate-common variables: - # DB generated from commit: https://github.com/paritytech/polkadot-sdk/commit/2e4b8996c4924fc39f85198019039cf0987f89ec + # DB generated from commit: https://github.com/paritytech/polkadot-sdk/commit/868788a5bff3ef94869bd36432726703fe3b4e96 # TODO: As a workaround for https://github.com/paritytech/polkadot-sdk/issues/2568 the DB was generated in archive mode. # After the issue is fixed, we should replace it with a pruned version of the DB. - DB_SNAPSHOT: "https://storage.googleapis.com/zombienet-db-snaps/substrate/0001-basic-warp-sync/chains-510ac1c891afe26bad6fcd6d74185917b3fb1b4f.tgz" - DB_BLOCK_HEIGHT: 47222 + DB_SNAPSHOT: "https://storage.googleapis.com/zombienet-db-snaps/substrate/0001-basic-warp-sync/chains-9677807d738b951e9f6c82e5fd15518eb0ae0419.tgz" + DB_BLOCK_HEIGHT: 56687 zombienet-substrate-0000-block-building: extends: diff --git a/substrate/zombienet/0001-basic-warp-sync/chain-spec.json b/substrate/zombienet/0001-basic-warp-sync/chain-spec.json index ab0c5bd0898..f92a968652a 100644 --- a/substrate/zombienet/0001-basic-warp-sync/chain-spec.json +++ b/substrate/zombienet/0001-basic-warp-sync/chain-spec.json @@ -3,7 +3,7 @@ "id": "local_testnet", "chainType": "Local", "bootNodes": [ - "/ip4/127.0.0.1/tcp/36639/ws/p2p/12D3KooWQCkBm1BYtkHpocxCwMgR8yjitEeHGx8spzcDLGt2gkBm" + "/ip4/127.0.0.1/tcp/44693/ws/p2p/12D3KooWQCkBm1BYtkHpocxCwMgR8yjitEeHGx8spzcDLGt2gkBm" ], "telemetryEndpoints": null, "protocolId": null, @@ -59,7 +59,7 @@ "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9f3f619a1c2956443880db9cc9a13d058e860f1b1c7227f7c22602f53f15af80747814dffd839719731ee3bba6edc126c": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080", "0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0x3104106e6f6465", "0x275bb9277673f20fc2801bcda9e63d2e4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0x2aeddc77fe58c98d50bd37f1b90840f94e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x2aeddc77fe58c98d50bd37f1b90840f94e7b9012096b41c4eb3aaf947f6ea429": "0x0100", "0x2b06af9719ac64d755623cda8ddd9b944e7b9012096b41c4eb3aaf947f6ea429": "0x0100", "0x2b06af9719ac64d755623cda8ddd9b949f99a2ce711f3a31b2fc05604c93f179": "0x08d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", "0x2c5de123c468aef7f3ac2ab3a76f87ce4e7b9012096b41c4eb3aaf947f6ea429": "0x0400", @@ -72,7 +72,7 @@ "0x3a0e22bc6b9ec8129f8b37b4779576b24e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0x3a2d6c9353500637d8f8e3e0fa0bb1c54e7b9012096b41c4eb3aaf947f6ea429": "0x0400", "0x3a2d6c9353500637d8f8e3e0fa0bb1c5ba7fb8745735dc3be2a2c61a72c39e78": "0x00", - "0x3a636f6465": "0x52bc537646db8e0528b52ffd0058f4e905beef87021a5410300c4d3af80cb5f7d3877f3b7940cf0d2f1287c7b999c7b71af4e246461b7d5599548d4040702298488e5fd3e3493c7f067db80064bfc2f3f4c3243f4d7288212f8d10013a79838636217bef4df6965bca2453dc1e7417711899fe1cab8054a7d56f2233fd397ad0997e8f40da69a598e72f7918f6d8e1522b77efddf2cbded35bd26fa779bf44bd5bd65cd6c7a2d97e8f40ba5ff230ec5188c565cdf6bff76ef9d97b7acbb22ce9b7d34a12b2f7edb4124af6be9d569e90bd6fa779bf44eded4c6fe7ef56dd327def9642b97e38457b3bd3dbb9472235d35ff225ef6e15cdf4eb6da7cdef1108c5d569f3977cc9977cc9977cc9bbc8311599fb869637690c61d89d83002e6d9cd6b99dd6df2390eab4fe256fa1b01d09113507460b104916244420a101490d48b8209900121b90e880e406245a90f480c40b922090fc800408105070240d109c40f2054917244220e1010916242e801007841420d90282991b085120c901090e204071048a2320386206840f1c89e28814487c3842c491228ee860240447b41ce172a487233c1829e2481723143832c4111f8e803182869123a4663802c3911d8efc70248623588ec870648622671851c1481c292b8cac60a48a112a4658905263648ad416524448a529720223664871c0081c29278c0851440d290d4859400a8b5405a4c248252125462a06a90d482921b584d418a926a46c9022436a0c292c8ec091d2e2480a52203892938ae2880a5254489d40aacc9115a43e70040529111c6141aa0aa92e8e48919a420a055221904a819414525c48ad2105c5112a524f48c5914223e5c5912d290f1c992265e64815a933526ba4c8485d2155841120a46e9042422a8b23491c41e2c81147c41ca9c09130488a301284940e525aa47290da62e48d940b45e018a941aa062930475e3872c5c809a4ba8ca0400a03463660640d2324305202292b473060440d236918a98054068c98a0081a52341cc1c1c80c46ce30f2c508155270a4c090ba8014135223286202235b462c602409234a184102490b485e383201235348652992c6911c8c0c11c508d7910b48c9307f288282226b489d51e4cb91101cd9728402478038c244111ea4de18d18011334526204502a91248a9216586541a524748e1f0810e1fd8f0010d1f54f94085a8353e48e183dc0728449d20ea4d541a5170a2d0887213654614185161448d208a8b282ca2ba885213b54554165157444911a545549a2834515d511888ba401413514b44291195449498280b44d51085258a88282e513244fd10e543140d5140441511d525ca4bd40b513344658972216a02514344e110f5250a09a733a25a8812224a0bd418506ea0c8802a03ea0ba82ba0ac80d2022a0d14135016804a024a0c14125015803a022a0c94115059a06a80a2016a06282c503240c5000503d415a817a05c806a014a08a820a08080f202d505ea07281fa0b840f500c503d404a0b640ed00a503540e505d504d4071417d815a024a09a815a03a0045064a0b140e503740d90055041411501c80da009406a0c6406500ca0928159ed6784ac193194f267842c1d3194f27787af3548227123c3df124c6939aa72a9eb678cae229044f523c41f1a4c513164f1c7822f3d4c49399a7289eba78e2e2298927249ec43c31f174c313d7130e4f3c3cf5f03481a7219ebe3c51f1b4839318a7319cc87012c3a98d53184e669cc0700a81d31927103861e1248513154e1f70f2805307260c53874901a70d3871c0c909a70c387571b28013979317a7179cae0c59630809869031048b21590cd162089a21658688604815439c1892012734864c60c896215886c430e48521568654698a3324370485a6143c4df174a6898ca6334d633491a0a98aa61134b1699aa2098ca6364d5a3471d1f44553089aa4685ad394a6494dd3154d5e3465d184a6698b261134b969b2a2a98c26319aba68a2a2c98c262c9ac26802a22988a61c9a5a68a2a1c985262c4d579a5e68aaa1c98a076c3c58c2831378d001214608a9801022848c1102468818214208e9125284102784700959420810429810f24548134228200403427e109284902084202164082117101246480684f8204409215d841c21c48b100b08d180101784c8e084849017829820081a41e0043923c89b20630421030241c4081246103082b0b161b1d560a3c196c53603931a52463091c154c6056608e00b06390c5840d2e2821200b9b9200c0ca65c80820bd0b8200da22f17c4c1a00a065b179c806905a52d18a4104ba3a703240f179cf193010cac3049a0870348634085d141194c3108bdd001063a70a2032590c4000283080c5019486000b121a2c00660845810da62c241088b504ea8850da8cce26c40c40d1a6626b0c1b9a105e90c1b163e636ee8c081161c6c4144848e25846418b2011e208886c845642384a4200485250c2c31b1a4c492180eb878ca00076a8c7010e6f6e054c606650c49d9c00c0e88b8376cc0c4061dd8c08d13955a151b7031dd406484100c348d0d80604a934403d21add0e1a64a181161e7ce183020dccfc502133b0f3c40e14482910aaa201056a53ccb40c9161480590a810009700841000172aa02a04e0c2cf163dd8e44022471039c4905f7ce0e44862e70c8e24845c18c2854482191a4a3efc30c123c48c4b69859e3637b06850463e02680dd30c3c9a506241001498a500488d4f0680bec8c106488c190a36a8005018b333c822482e9b0988b8fcac305b4303373c52927c087202a1187accf87182a807a1157430415404d0183960c8617058408705341862a7072137ecf080b4c50e1721597626b0e383101b84a610b5c100060c5ac0400218ac80810a1850c1400a06285c90820bd6b8408d0be05c60820bde5c30c6052478aa72011917b421dae1022fe6179e106c7001210de468c3630608173b34b083cc8f313f36b02303433f0cf9b063033bc6ece8dac10123617a6c71e4cb094257788ab8008ca72598ac0849d1c088212798a5c16466489a214f0c89228718b510ccd4d09104d311b313085901b226a9890d309004469213443c200581248491979a144340f80a1e64e18116d7870a66b83fdc2d1707a41e765ce0da9053c35006728c91038d1c6018e99023430e161e321b70d9a0871d47f440f333a60336af868703394690034e8d0a272943d8f0049123034376c841258714a434922490e34b0e2190da2095c103821c5bb13631326261c4c440aac2070d1c4ae0c881848194e10615ff222a8e8be1a30157b3a3650706ae0e1f48b901450f181d0ae80ca10346e78b0ed70d2e9d1c6e7cb921036de1d290230c1e28789ea056762cd1c1183b94d860090e86e040881c1a84c6f044c1c117a10c70d0c5e98a11dac0d5722770bf5c36170c0ebc383dc101180e7eb86a88a8b85b105971bb204273b92012c1f582688abbe66a41740551151708273417090e82e000080eb86e059eaeb849dc301c50e01ee10485900a40d834d9d0340354099a70982e409db1c1970b6eb88086f7c2084c53960d50403483ed061b0e4e55107911c5e55426071943343063e2c90dd1046e0e97cb065d426478a4b83cdc2c4363807421d401a127862630b4656887211e867418e232d483d00784a0b83b087140a80c101a3b62e021622704443f0c9901c8044a2a10e9909150da220a62c818242b74e440e44307636edcd0c1123e39a411107921128264a2078c1e374c3d901460c2c2544647134c5c76ca107131e930a40d93160eb0600a418f05989000228369cb05653055210407a6304c572071c154012157986a601202a90b26313d2660ea62c2401215a6313b6498984082c394c34e0798ba208980c906a62590d2308161dac00d1c98a440f24287991997190fb32d331d82d60471c1d401261f80daf494c18426c90aa01130ed902402a02d80ac904121cbfdc4013a23c3800749e4d8908343ce0d395a3cb0802c043e5bb2257ca09011d1b3852c099f2e3f61f46021bbc1470559971e2b645d3e1390a1d02385ac081f2f3f6d7cccc85af0a942a6824f086432f81821fbc1a7cd0f097c58f859c3c70619191f0fc834e0634516838f143f27f0b1806c8b0f1719959f1b7ecef0e941c6811e2d6446f8842113e3834566c5a7851f337c6a9039e153c40f193f36c880f0b9806c033e42c858e8e942c6840f18590d3e67644df80cf13386cf0b3f6c7aa6f8f1c2e707190c3d6b642ff874c93ee0f34556c68703320ff8c420cbe2c384ac071f2ab2ad1e2e7ec4f03942e6c24f0d32217caac824e073e5c78dcf086438f8949175c0e70b19057cc09079e9b94236011f0afc80e1030219169f0ac852f009239be22386ac8a8f0464637c7490cdd0a3468684cf123f26e8492353c207899f14f8d020cbc107881f357cd8c82ce0d301190f3e3efc7ce1a3e5270d9f0fc8b4f49cf941a3270b59057c64f881e3b3453684cf0ab2237ca29081f181e167043e63c8b87c9e90d1e093c4cf1b1f1e6441f8b8f083021f256419f8c922fbe24384cc071f1c6436f4a0915df1d9e1a70c9f29642bf8dc200be393e5a7043e33c8b8f8e42093e28301d90e3e64643af850f1b3c6478cec02b22780d2005d019405101632105c216e105163c8a4780281141a469e907a414a0246402035841129a4603072c6881146a0f8c962881717d8f0e381282b724c893ae247ca4f0a3f28fce47ce2f8a4400815d76267033e5c43aef49cd123468e147ac2182201a3208c86e81181d11723341889c2c816479630124208961b597ac4f420b183099e293a2083a70a1e2a7abe3cc1e139f344c6066a209d8009881d0ee800c1c365c70b4f186002811117d30f4c4dec90b1d38674a176a95e84a880648690ad1a0884d4c014844e1033384f609250d02943670c1d0d448189ea014a8c9c38395b72509033819c1972aab85fe40c01c40ba92b395c522dc4a600a226e70a236d72c07c30c3d318461400b2c590970fa8d4ce001901921a2e820e68b8200b1906c81717d4101b432805a119c82c640d3533640c445af8190104419403121aa22d3762b86183530b73889c188068416403531243a0b069f1034cce0b4c17e879c3e42566c68d2090beb065c1a482072388a131840231384d5a86c01073d341134c2ef0a4102be3c98ba6294c30109519c244531a437288da01c90443b2e4886188195125d0c08c0d841802c4d30f485734498029cb4f144f2af4b04152c3d303141743a8f48c207682a81c784c80c788271f86b090a3081fa323448f17405c08a912448d1e0f084940833186681962c68646930e3f668674c1f4e5894ad2147762c8123766806a63bb22c905f202b11230f100e4c5101d925a8891a0a94ad41a261a868c8184051397901d84ccc0e4449417e40e3b39100141d48507051d5d8e262a033113245511a282f48627c77486a985242b3d2948522107101a9091b4958405898c242d4d37f8ac31a485a41b76ba24a5d0242547981c46e4a840130a34e04208057a0654163a74f00c20adb1a5e941a3830d30158194c5930490dc749081a715989e807aa30109a228d0f385075b0c7121c71149599c4ec0044507669272c0e005243482a4310487a41938c8c20335495784d000d405062e0c59e3411c1d5ae8c842871a1d585ce0e6860f740ca7349844107b938388a69c93113c96b09dd14425a646d20b49316050c48d1a62675c2046558162a12ed017e815aa434581ce50733406ba434d81c240b7c8ced4192a962ac30d21a28248927283872416a0d4dcf8016a8b1b3ddc00e2c6961b13e0b1c2b495944342c15317cf0f486c926a400aa3c680540227227ac8e45cc971c1a6c6b6c50d2f37ba78c0856d4d920c493830b1c0f401a6179e28f05444120c4f44f07879fac053194c5124d990b482d3114f6372a87063872811447d7123072717a274b8c145c70b139927359ed2b091c3d31aa4384c5344a9e194844e971b436ce0c30e123b66e051030f1b7864f9a1e107d78f217e5060a78b1d2f76d6f4b8a2479a1d3eece8b2e307b20cd20cd24d8e04725ac8b1b2810d1be0b0c10d3f6af881430e3439acc821020d84d0804b832f3fc4f8e1e6b9fc0fefc3062b6c20810d58e01982070c0f1d786ce1b1c38f2c3f6ef861c353f168be8a9f323f50fc3c81030d0e2b70886047103bbeec1082c7023c4bf02881a3061c36e0c8f26c3e8c07c307133e30e0e30236a2b001021b667a98e8c140cf05707cc141011c5c194e5623a3914f90d3c0a0070c7cc0800b8f303c2ac0e3081b706ca861238d222f45411401a1810634e080061bd859a289871d267e34f123033f9c50ca416907251d7e8597c0b3603bc28684ad024a46281da11466480f3b67eca0b163021f60f810c347181a5ca101161aa4c1b1058e2e707081a303383e80c303368468fa62e34b075d3a00a2032f1d8ca0832b3ab0e247183fcaf8d1e607193fc6e860ab03163a5841c711432ea0a30249522485402905a5294a52ee0a570297851e59fc74e55863a3c256856d0a1b49d850c286057652a043029d12e0a8c09033701c5144435196a21a9c2ac03401262b98ae306980490926199828c0440513114c16601a8229034c58307980c908260e3c5d000a8b27189ad678daf2e484a3c047e05d38167e8567116584a771309cc278144e859b71103815e14f384d7122e317702bbccb9bf8608aabe0557c6bbe711422e053260a669cb986e7660a261ab3049ec23c63aa314f30d398269842389933cc29e60e938a999b58e698a981b981d9354330939817981898344c1ee6959965d630659852cc32f303b809a604ab26501a3082082130406a8992240b48c0019080706466e0c9b634a42948063263e0c1a4818f1e938bfc219cb9e703f1723a75b5840149a02c99222149927052119c4c2549022625d1722234616202036646717a0a6bc9945508428a8c5220c29310a644b0618482be7ac014d5d503a69c0c708dd668ab29ac2b26234c59259962c00396947082202335fa6a4a84274e4e60524292ac292b283f4669f49509584bb0aeaea6aea69c9cc0044a6604a7afaea69a0c19a1d13b4626e8331ab064aa498fd19bb62aa18412a0624625c06144829a91198d3575e5a6af985c3da00153530c68c0d494cdc7a80c212332a6b0ae1e703546094fb0ae4c68d35358263080891516d6921c2331a69a34791282cc288c6e0001462330948cd83469b22484264d96743082be9acab29aba9ab24a823535820da32fda8bb67ad28024574ea6a89e6025c10a61c9095349a64260620525c914d613274f3aa819ad21016b0427534dbae8a9a90624798295048b8411984c39e0c8888bbe6ac26409d6940849a6a61a6064b4453f69801326491e6035654255122650329693a9121eb024ea8dd4f4d4085af494084f424822c292274da09890454f612d6182e56409d695132632232cba4993252184b0c40acbc9930e728cd2f4d515d6d4d5550e32baa2a74270f2c4499225213879428010f29091154ca0e4075c31617a40be46220880119a22a32afa8429273a4654f4144d42084fa04ccd8cceb4950923306980932721246102254f316089adc728048de5c484272124991a61099424575653544bb0ae925c2db19ac24652f412ac27265425b972928409943c821326544bb00c206404827e8295c44c4f85e0644993250c48f2042bc9159613264f8a8ca2e82b11ac963860ca2ac9084e9888e0640a4a122650f25593274fa29c3029e10901b011140d8509095756534e1cf024c903a6a88c8c9e6811a69c8cc0e4ca8909584b427892c5c484aaa92458564fa04c59f5302ad32230498235756565420840461fe8ab2926584cac9e908065c2922423246102252f81228293255642888c3cd00e6002255b4d51593d3942e41a75a00d20556444a6a7a64c9832e18322224c8d30c29222161871a0afa842982221840df415969329ab29129c3079230d3861d28099d1980e81c99513265658274c2579401328509624b19a12a10913136c54213c69621332ca405f051939d14b92081935d125245982b544842558535039465d1060d26409132c264e98f41861a0a94278d2840149a6b04c0861ea84291da30bb4d5930ec49e534d18b004cb89090d488215c2941513119c30499204c8031d33bcae2bba88c9ad1576572e97a71605b26417b2cb8432bd2a34341312229a753321a24e88244592ec194799ac671c67e3d2d2d06c68886826349b117544d6daa6149cd65a4bbfb6d6ebda75b603bbed8c815d8e570ce8158bc562d52dd84020d8fd81df676de71ff8596bedbde36cdb54a7d25ab18f3b9011add5edd75dfdb3eeb65a6aed4749a71e250682b6a9d7afada59456ec76faf87413b49df5cfc7a7da39bfeebaee4647a9b56d5fdf4b00d6be6c37ad9d9ded3a6b6747e7e79f9d5dd7f9581fdb75734edb59d04e3badb5b37ad74a2d3867db6eda55dad66777dbaeadaddeb6bbc3ef7bfd7c1f6d4b3af50a7e5e2b58ab06d5db67e398fd51a01abe7bd4bd57add6fbbc92d529bd21d93ad411e8a1deb19d6d5b9d4eb76137a7b536ecacedeeac7f6d29ec735badd5f9aca53bbc3ab5ddb6765e2bb5edd46db7a5d59d524adda9b594765b4a7b6cdb766aadb594fa4f7fd6d6b6d49d7e5f75daf6d56e1b020fa8b55677ff28eddcbdfa095d9d75d2cf0175ce59bdceecccb6b53ddd61ed3dddbbadb54d41af1ed4594e4dc0baeadab579e88e0daf3672603098d5e4c9b11366a3bb3f4abf2f2787030e68b45a8360412f4ac1a0201d3abac85f4141eea1c37a76bb37ddcee9cdd03b0c3bec0e1b47d8dd1d76bbc3a6bb7fdeed74cef9757b87cdc3636367a78816d1a2a200c0603930182dcad9e931001b7600393b393b7a7a603d33b6e3a5d44a4de7dc60ce0d6aa5f47b7dd3bb5f95c76bb5b6baadb576add56b5ba72f9a9d3939dff7edecec74b4ca7693fe50f7ef03419fb3ead40ae5899312bc7aed9c39c31ad2d7f7a2b356779d8f7eb4564a7dd420774a015041132afaaab4a494c98b7eeedf0dfa53756a53a74e93ba52db1dd5ea3ea7d7170995eeb8fba4b58215f45a7dc8bd52dac19cc268b5d64ab6db5a6975fbe347f5eef1dadd64ad95d25a29a5d569ad74844a69252b59c91e9fd5a73b0fffbc01d3bb9a0324c129074110b4d682d66141d577babbaed66ac13727add5bb5a58d7d7d1740f6bfdbe76afb6daafceb65d6bf774f7cf1dac3cced3d6456f5815c176f7ec10aa3b0c66ab57fa39037a090c96a3545dc9ac14569de6395e679d496addddaf6eeab1179e7501b59ba7bac3aadb5a3baf7e747a6edbbd5a2ba5b6d6aed57aa5f6f57abd5eb1e93ee7f7f297c762fe7ab9bf1cb41d383b5b6ded5a6d7bed9ebbcfb62f6f874d1b4ebbd2a60af04aa90e1f5f10ed9eddfef2def176ffba6df5eeb676daae7e7302a01a191919d5ce76d63bb74d29ad3401df473f0b3e2a80ef45bf9c1edf475fb66953ef1e770c003a79c410406b8d595b3beade55fa51ead63fafd66ba5d646eddaf5a3947aa5dfecaac37cce0354efdee9ea48fcebbcabb556aff6f3cf29fdbecf5afb555a6ba59552fa514abd27a882d0ddd63ab5dfcb8f7c3fdf0fa594ba03e9fc586fdb4d18acbbd657ada03aad5ebdbe6a4deae9ead378d6e95d7767bbeeae9b9db7bb4fea6ebd565b2b9d75c260eed37d5277eff65aab75b7b6bbed7c79fed9ee9e73ba775bf7b66dddbfe973ceeeee9edeeddddef36bf73a678dbdbadbbe62edb34e6addddce7e35d5d1a1fef2fad1afd64a3f4b69db5aa9b5356abfb6d6b63b7de9b8c36036697a0068051564f0caa076d74642fa26adfe49bd5e377ebca98ece0dff3172e3c64ba70ed5eef66f4eeb0e6b6b4183b4d26aadb757eff69d39bfaf52fa35ed3afa7d9876dd1da5b5564abbdaeee96da9adb488016cd73a6b75ebeed6daf6eeea5ead7bf7ec6e9fedd6d297cfcea75b771ef7ae5ea9d759ab3bedd9d3b67bbbdbae6bdbd6d6eaee94d2eeeef6ae757a75ef59809a53dddd6b7b77bb7ba5b5db5aeb6eddbdba7badd5ab579dafd6eaddd3daaeab5dcc765fedb6b6adb5b5f6071fc500039d99c3467dd4daefabfd59b79db54408603b9b2306f5e494a3b35d0c8876b60eb14d94526abdadb5d6924edb7a95d217ad94b67dc19c56cfbdadedaa77dbce5aebd5dd76de8d84082446d09ff607583d2961aa042b9b723255c214d612ac2b0084bd632a6baa4992139694606384274d928ce084c908233c6902844193264ca8943c3012421b9146231e119a3021218424584d4c58d28029118e78de1d30e564ca0a473d614a04274c705c7023c8084caeeed103a6a89284c0a409034c8042b3bac221f60557575356504a78124212aba9ac27214c59eda0aa05e00228214c5df1b8e0860076042000178880c3076b89d59493a911922cb9122184a9244fb0a03cc02a841b401af0e4891594240f680013aba9ac0a984498b29a12c1ea49925a002e9862628555c12ca17bc79455034278d2a4c912211c504a58827535550213acbf0c30e1ea289c9aba4a52c213119c2cb1c23d57b40e6836119c2c493265b5044a094f32209b2c09e149930ac227584b4460d2644956922b26499c30594242080d68c0931b19d486884e78e2002ca225245c11512d09218429aa5a002e78d9053b925c3045b5a40903928ce0840909574b48f8a91298603931c10a7f8f066099305482094e84fe842912926039616205254908574c4ab05a827565c4730574d4173c7962154415c212063469f2c4aa82bc64ca2ae801535449b04e98724274b1a64600925d615d3139614ac8eb1d4e9e30c10a61c9959325565849b0989450c213dad8179cc0a401535650f05b2d996a12c22ccbc914e5e91d499c3c6172653595954404275350a02c493235c212ab27585749b04e9812ca7232457be86471ad899b4aa2cc28534b54d222c569e1604a5a4b4bebb3d66a85394a5a2b54d25a53eba6456f5a5589d6dc8985b84a9534ae6a511c0ea7e538ad8aa34a70530be72f9ce3b4b43c255a13a785036f5a382dda381c0e87c3e17038ad899b8dc3bd94344e4b8b2ac1e1a656a7e4366f37af4aa2cc28515c49e370389c969696d6c44d25ada5f529d19a382daaa4713857d29da7a4b570381c0ea7a55595e0260ee74a70ad446b5aad4e49b712ad4995b49696965655d25a5aae446b6a4d25ad3595e05e556677cf12ae967499feeccaf4edfd6e96e7faa1fb6ca4d7dbeeedadbae5fa5f39e7fd597e54ee7db8acf9fb79a9bf70f97dffa4b9bcd2cafdeee120fdb5622afa1453f53baebae592e67e1b27f4a7ef6d2687216bcec965f6a7df45e5d795ebd33bab90e50726d7ef9f479035975f2ed7a7e507e6ebcab4761dadb5565a3d00fd73f42e1ba664ff2c6b64ff2a667a27ad5de723905abbda35d5aeabd5695d144ecb092715d27377657193e7378c521ef56e555b7d7a8b90b64a29ae8ae52eb5e991bb8ba06d8ee8b4eab47e9e300b099e0ad93f3fec5bf398a5131bb3d83eba1b3612a9b95cee9ffd2d02b1fadebd18e5eadd49f6ebcfebbdbd6390f9fd60fbf0f07f33a7f9decff7f07c304f0c761215bbb0fde7ad4e73fb5e7792ed07472221063bc9672edb5b7ed9bf3bc91d856c942ba677666fba1366f27c9cbb194e1f9fc4f73b5fbc542ec47ffe7ce7427657163519fc34623298c50f432ace51c8f7afa70a1ffcd06f09de5953cde5f2f835d3dc631399cbe3fb9db93cfe92bb187627c5be7bbfb08fddd2eb18c41f86e9fb18c49ffc254ade99933fecfd61f8ce9cc0ec0f66c7419d443d92f2681b7d8f3d4c7c6f240266f183da07fd6e2432eb24fa220e82c1eecce51e85cc5c979c5f7292f2c8c1315c7ed93e953ff8a57f3f6961000441d0e71864be7b933f4805eb24fab14ea2b95cb5c89a43218f1fbec211c7be3be935c61e269634870f0b1fcb66d878ad6031f1973c263e2c1cc57f8522ee460af1eb977cc9fbfddbe7b7cdf130e9348b71ee300f6e6ac1dcd3124e2a64cddd95a503930ad9e5eeca322677120ecff33ccff3bcef22af8c70ba77f3735af7b3fbbe130ab27ed7fdd83e80f877dd8beda3fb2eead8ececece87cce931ffb9d9d9d9d9d3062b118ecc7173ffc582c168b69118621e87d18866178266cefc3eeeeee9eedde153bc9fb79e713a4f5de7bb17df87bdefbf53a10766f7129fad71ba4fcf205bffb72667f286006b113d06f89cbf5f52155133077d809e8f9f5e52b0b97dce5d7eb7b2462f30bb7d3ca2abe3a7f51f1d575d8cb2ffbf77e7deab01fd6f965fbd569d6fdbbab86354edd951d974bd93f7c89dde574df5db9bb6a5893bb9bc88eabd3acf56ed944cc5d07a4e26f5635c2ae23bdf685dd6daa1f765d776bf775aa603f9c0ee4f5f67d04b244ede5995d58b366aeddad1d48359f3efd25afb8c4caf5e7ed6e29e6eec335397c9a3d876fefccb3a686e24a0ebfcb35f7d8e4b1c921eea9a3f4ee43176df7614f6f0aeba9a3a3f5361173bd33274a956978336fe7d755ca0fde99e768bb3b5520e7f3380dbcdebfeef7f3da9f63d5f7e1c6157fa558d7089bbcaf1fd65b6ae5faf57af5bd25afdfeb97bcde99bfb7ff2ab5b2fd6ae8795f6fd6cc9ee77de8fe9d3442d5ef7ec9bf5befd7f2f5d3be5eef7dfdbeef3f5cbe7e7ecd55b7ec9dab7f15cd5e270e5d6377567f7e7dbfb3fafede87f57ab0e4fd0c5d9c63107fef6b93bfe77dd58c638525e62a0ef2ecb1094a9392fcfdd7efddf27baafade87df2d6bae4f5fd8aaaadde472194b277f4f2996983f2250c06b55c541f64eaa8f6533f8a5e7faaf6b053e96cddff7e89424bf7ec9bf5b65a38a833c3ba97e38c5d7ebebbf703752f53148f7f5e708c4e27abfef4eebb4ceaae24feb9b9e98b0bb1cf16937c7d905e931b630d664dfbe15bf131f14fff520785f97bc376be679b366b6f3da0fbd677b854dfc9dd4bfe4f652d97f915e0bbdd8cc618f40dae6904e035f298b3f4720f3963353d97f79f73b4929f78797745a7fd973b2ffc231f0bbaf2ffe1ce794ef412c735abf88dbfe7ce1522bbf5ebcf38ab704ff05e2b266f0c39f977a39b3f8e5102d0ce46e241197e0d3f056ddc0db9948cdb48ae68903499f14fd760eed2dbb9fffddd9c455337bd8821c4ef1bb49d9bb424eebb7b79cf36d0a613b8ff6a3c9e3f3a3f9a58cfcf6f19d34bf5fc86b3c7e34df9f0749387fde114875da7ca7d5cff63f1fdbe654a7e1128be6f9afe7f15ae8851e08e212fcd7839ee8350f7cfaa177670ec1dbe2cf514851ae4e7bbd773b8b178b66f0c3e93d29ac9dd6793ecd6b484279fec4a50de99cf6767edd8f833871e2e4ef627579f264b7b83c21dbef5b7eb9bfb639ed34efdf691eeedbe5cc55334e9c387172a995fbedc5a2b97f8a1d269df6b47a3b0b79ed337da4f64133fda20cce8e4b385120fb7978c2345c3208b60f1f60eea9a3fc72699b879d47f497d254a035584a13a675742e6d0ef3c4252e67791ec16ae6f92f1e900c45f11bb32aacecae2b7ac855b13c9f7eac7d340a327d3b35e84c4bcfa515bb7dccdc2c829c1fce719e21fd971c8a5c8f01525573b95653c57469ec9a9e1a4c366972bf4f1e6deb07a70635977b0cd269f2fcb0bdeffb3eebdf47674783cdf7a484ed944269993a74c821c4b226cf3c7fc97d56cd4c7fc610763fa59054dd1be5b2ebdc5d34a4c9de79aa7d5829e52efd5afdc5cfefc6164fa99264b3bfb5639b3cb97e10122ac8b249ee5e29973cb96c2f3e68db14fb735a715a7d0790e5b492eb97ed45ae7feb27e9d1195a90d80109306a72399bfdf9f6b66dde5c15c2851e52e08109db942a49b6f95b3bb62955dce6fdd6006cf3eddd1a80edc65564fe2d8a1ed59f666e5c45963c7ce32a627fe2db63a5cfe597cbeeea9a5fb69936810a1de8328615416c21c56bcd5086091d7468024d1125b0b5ad7f2cf2b99c6d5af19a5176af3b840f20e9510f0d65b250ee2e1a28909572d58a756d02eb3be93525c5b35b932bee6c7d0f3bb198aa0976f2f64b8acb5bae3fdf3ebdf57b24d2505cc91677f9befb1297cbee5235e935d9fbce49437125775f42205b0f3be935b9fbf2962d2ee753271b4ce9ca1dee1205a7a30a277454e1042e4fc8f4e7edaf07d05185135da2e07a8dedf55d45e3c4c95d72432df880658b158e2d4390c96141e935b94b4e47154ee4b23698d27542aea1b862eb2f2190bb147a8ded8573bdc6d65fde7287cba941b78eb2bbb07c91b166ee92f3c982082960e472b6c651701fcef5975eabb88492c722395b64f1430aa640ed648a1be75a9d5b21c22e2ae795a63c5e5f92b9ff41dbd90e2c629b1e755cf45fffb93ef8df1709fff5161701ffab21be85ff7d01daf6eabeb39dedc0db831ed50f2fade991f7afab448f6a0f3a3b40f8df1701ff05bec54542fb2106c1aac8f720be79809b1e755f80b64559b0d1e48ab9e8b7edf55fabc9f5af9b5c7f6e79adec362778ad9c5bd30a14ac359acc2b55abba978299af7e9ff75fd7b6afebbaeefb0ef0fa0fdfb8ba7f61193daa0568db5befdbf67db76d39dee5a2af94917a907952cae0079219ea1d0b611795ade6a33c5eb4ebba2eecd06f5cdde3c07fd18ed6ef7b03ccaffbb0bbf37bf45e97bc1f3d8aca16fc727d3a02f1d76d9b779bc24c3f9c6313999d042f177daf55ecb1ebdcbabb77b7d40abbd78dc2d53deefb97b594feebc3afebdebeed6c675ff7e9517df0cae85195e5fa16c89501c07fe128af07df48db5e98abfb02a8c0810dc4347a545f891ed5ff3a242220dbf6bd0a1cd85eff7aef75db9693a9ffe5a2b4bb727d10bc56fef0c06b65a349c0125397f9d16a72dfc051adea1f11f5bb7d4ceab52eac6513fadddbb08ab37d78ee0fc31ace9a4aad1db27def3d5c6a01912db6faecbd56eeb109cc1e764ac4fb0e97f63ddce5f57e4badecdd28a47397adb7bd30ee7baeeeed4884bec565541d81f82fd18e0bccf4c7a6971399292e7d0c32b37fe8ed93c24a23b93b69ca60a6d6aff56b8d014dae33d7faa18b738e377289cbb47e17554ca554db849486b9bb62b8426390e21605b48353bb1a762e9cb12418bdf04ea45e16f495bb0b8629e827526fa49f48e76c18c4649abb0b0629ba2f0c64727b1fac3b494a3726d6d30ab2bb5e38933b77f60fa9d8b9a190b95c0e05db746a34e8cf11887f8f4468d9dbc7ccfd57dc64a34ced6c1f1d91fa1497f44d90652c995555c7c9fe585eb61fd2d129d654fd762795f4bf0fad58db87775f85d0f768397349bfbe77674eddfb3ba6aadf7db6a39351ee7077127d7a3fa74d27b44c671d9d1a8d4cdfaf135aa6787692bf1d81d09f23115aa6b83bc9f1e7cd0a266c0f63f6bba8ecaeec34af75970b6b1a4c9e2311faf3e708a47fde59ff9c2890e5f7f05a29947bfc40721ed3d65d3070c9fe455ee3726699d3fcfdbd4b739a1739cdbbcb737b945d9992bbeb8537b9ec91fd8535b907e551e440ca99e9fb08a4c869fe4ef32af2b37fee2e9a44f824ece6416903a9df37abe6fe7a9bc8dc4f69537a3b7b00a65821f4b1bb977cba0b645c0686fae4ee72e186ea82954eac2390adcce3b4da5f472055334eaea390f9593aef8482ecae16d6c80e9651d6d0e664e189f3b660a66d57a9cff6601d96b08baa7fd3ffeec37a6ffdb20af9a4ece3522bd3c7d9e8080404ef2dbe69d96ef4dd46bd7bd3b2cdeadf9487fd128be68a3b5c9de6cf84ec22385b15ae2a0e72f7d3562fc5e5ccf5bb5bd25cdf5eef9768bd9dbdebb61e8b50dbec6c6fdbaaf3f86cfe2299fb06ceb5aa3b1324d4ef84bc864533fd7277b1686e9ab95c2e97e7d78b456b9e5feb9c5484fd947e38bbee29ed6e8bf45291def95a3ebdca0be47c1a50d853046477b5d095bbdc5d56d4e4d619332bfe7017d1134205904e8b85738aec718856ae556b4e26253a4832260c8d79fb3b7eaac655b8dc5ffacfc6edb426bbc29e1e20bbcbca98dc5d56b8e43296eb5b90bb4b0270720d678f4f5ab99d56d6ac95674847209d8f4f5a59b4dddf2a6466fb796d166466fb167f797e57dd875001936a7e49dfe7451266ce0e12f694986b0e63f61dd3af9df5f7da2c883f7d6abf7b2a6ab315f3922fb9d69c934cd8536418b3529fb426fe9c56bf7e184340152ed79e793e03c2761aa37e912c41565ae954d85eeb2e099cc9f4fbc5be617b08cbddc5021b2132b9bee5d16372395b7f2efcfe3056bd66bf5f4aee0fbb7dc03e0cb5c487ddee24119721902acf42425c7a0e7fbe784b5c1667869557b81c7e7df0bb7dbc1ed649305c864f7ffcd7ed4e1a71293eed3c6f9517274e9c14e4fae22db5b2fd1e83cc5c7fc9c3db19bc541567cd6cbfb44d9eedd3d1a9bee3522bfb770e7fde72e6f9740c621ff6e19d35e5d23efd390a11bf3b69fe125d72f156cd38f97bd89d8d42bc7fe172e6d783b79c19fcd0de7266fbe3d791487dfb3d02117fc9c39e4a90ddc5029a5cdf7ed8a18b3d0a193fc465cd21f5ac2fc31e86e7d854b3fd30ec11864bad0c7bf1667d59fcf0963387dfed43c4a5f84d7ce4eea4f0c35fa2e10d2ffd1e61b88a66fb40ec8fb7b45fdf8ec9a59043f0fbe72864c6c922ee4e2ac3f0bbefd183ce21ee467a3d056fe7d79ddf9db94eeadebba5ffb4b7b55ed34e099ff2a012fbfff69e8acfdb4ff2a702f4b007007d2a2bcc97bd8e6fca830a10bee93c0d7a2a363efcfe8ff2a0a244e5e781be5f467950f1c1379f8fc51e28e763f77dfee6836f39450ff4379f173ff65428be7ddf93f846be47ff46f1edc32bccbf7d4ff4393f7e3f49795001f10d7cf70f81f00dbf77e38ddebd07fa9b3f10be75dd93f8063ef937a00f9f4afd207ce3e1791d7ca3ffc2b7d7dff06ff7437ca3f46fe1cf7e87245fc4b7ae7b10df28be0d3df8247df26fe293f8d6edfcadfba3c7f137f271e01b0fcff7e05bcf7bde13e11b0fd1f7783d8fe36fdee3c037a21725fadbab08af40dbc1b79defe9f9d94e4f0ffe1b20f84443201882afdb03e4934349cf5fa00ffdc29e2e763bd13fa09c987fd72329097a3d6127fa00f97c3796d381af170d49af2747247d5e22508ee79f83b1dbf5d0ae07887e461590a1c76ef816e4e0008d8c768042fa3a3afa9bffd1d1cbc7073f8dfc9e265650c1dfc0afa082eb79b1c77f24827fd4d1687fbb4f33a27db11ef2f1570094f315bc057ff3790b8e8efe16fe118ea3b7e06fafcec828bc8f9fd6f53ccd8d8c8c2af89bf715e09b91510e7d0b70e018fa9bf843afc77f44f443377c2cf8a3bf01fd118d96e371e01bed6fe0f8a3bf817fe36f242efa9d1d077afc4643437f8388e8673f74e387fe96f343df1b3dd2df628f349584de82bfc5de8259f4372c78a4bff9fc8dbf7d7f441312c22f74f4427fbb2f34ff16bed0e398cdfe0611be0de1dbd0dff819d1cffe26fe6cfead7b1c4ffb1bf9b499c3e86fde1be15b0ea3c7f896e389889ef637faf86faf47c2b70a2af8227c9be1dbec77765e08df82827e866f42bfb3f3b3bff5fc0cdf82661ff437112ff5d1fca2b7e086a8f343f816846f413ff4a2f8f86fe0637cd3b9f1f86f2186d247f375de82bf81f8843e9a6f01be5580579847e1e3c037107c1e7ce3f910c7877f7b6110427c03c317c237f0c5d78b7fbb38aa8fe60bfdad077bd047f369f866d4f339f00de31b7e1cf78bf0edc63fc6b70e634a1a65e2e4508218b66c17042a6089428d326ea002021b95fb4b40f8eba3f917df1ebf0fee3e9a6f03373dea271a027a217c9bc93e08dfb49430420c33687e08020a256c405a38a460050c4e88200d343bd880fe9683657d341f08df64b8e9910e5cd272ff2d86c93e9aff833f7ad4eff3378a49e8a3f93ef8d6835798362a39cf836fb1dfc12b28d9a8d0d7c1b71cd8c7f04dcb872e28e8e2039c37639861a37d851b237a800107384ea461a3423ff63712f7e8a3f9317c83e1a64700c0658fdc7ff3b0521fcd1fb18c1ef5df1c2be9a3f922be8578059a8d8a7d10df7e20b1041943bc09811b216c2fbcc2dba8d868c2044760c08a2a6a8861a3e2effdedc3b43e9aefe19bc54d8f9270a994fb6f1dfe3e9a5f31498ffafbb528eec893e238a5944eff25a7ee3fdd9dbed339ffcb13cf9ce6d79f14c8c4e5cc4fa667ee0f63edb5f6afe11c81cc708a93d6a73f9f8e4026ee9983002e6f9c46c57967f6d1bfc78adb694b4e671961173514d94e9b3fc72027e4723914f2fcd045ffe60764c993e9fbd72fbf7e9990d7e6cbbcd6f566d9c8575ad9f1ccc9bfbe7fc558334f5c9be63b2efde77b608534b9fc726f99c9bdc299dc2f7a6db6ade4c9fd5dd498ea97c20ee205d93fbfc1b00940ceefefd7a72073da3423a5c7aa9a853a69e29e7766219dab669cdcdfe3d849fe6227f9d3abc2945cd6ec6be4f904d95d55dae4fe2e775795359fd83ee8fb8ffe74fe98bbab4a1599c769f36bbfff7443af70d79a9329eca252c96bf3cb2f77eeaf5eabdf1f3614e93f73d844c8908aedb5765af9897e44bf3f0cc3ffcefded876efd4b3153dc5d24a7c964cea3fa117dfa34b78f0f2f55a1a2933a979ee7776be0e1a52a675a47e7894b7f8b45bf3c34fb3b79a6f2279d467fc979bce6b89c6f9fd62fed771fdacbe334fadd159d463b9722943f297aad7bfa3c5eeb4cdfdece9dfb8753eceecc3dfa8f40909c467fde22a7d10fa7386fe77ac78adf69743241969f3fafb99d354d9531130dd95d55c2e4ce2599c52cf35a4943f2daccdd45254cf6e7f19a4f5b2994fd7b4440171f3aa9f3928b5eeb19c408a4b650d81e4e14c8f9dd35054eee6f58589f7e587b4be6715ae3eab4192777bfe46177bf4ea21ff63871a995e7f72d67ee9f5190dd35854d2ec54c5f5ca23d0299bfe4d56bfef4bff6d13dfd57fbe84cbfbbdde5884e6ba795b2ec3f737799b192799ce65fefcc5d443115398b086713e4fc167b5a80ec2e2c67f2cc65fa61acbf8bca99cbfe218f29f69d5248aafecee5cc79ee2e19d4e499e7fbe8347399e272e6727fd8231132d7a737abe68aab669c4cbf6fa995cbfab32630575c15cbf4bb8aac94cb8e93cb7eff25da9dd41fbad8770641ce9fb97b47ff1cab3ed3efb18acc140b396dfe92f76da7f5cce5bea145a7571176409253d04ce9f22fbf4ce953fa94d2295732a59452fa5d44afda483933ab20bb4b4a96f71acd6b6525bde65fe4b599fd3faf75570a56b2bfe8355a9bf979b8ad1473f965fff65abf7ff5da7cff2e724ca594fb86d69c5961e7f083902c41ce2fc5ec73ceebb92b67d93174f1f35a39737fb78f0290f4fb7b14529dd6bfe4a18bf3d62cbac9555eced219b3c43cdf1f166b1f563397ab38c8f3fd432ace4bf3d83eac662e577190b36c9eef2fb60faba926678979be3fac7d58cd5caee220cff7ef9148cde5f2fc259f631399cbf345af75f6efb169e6f2fc255ff2255ff22e724c45e6bea1e5d3b3083b7f5e2bfde9f707215982f49f5fd26fa7f587f47e4eeb8f22fde9f7f748c49f8ae2cf69fdd569fd4bae352753d8452599fddb6bedb4f2cbfee597fbdb79b41ff9f7870d45d29f396c2264d8d3036477a150267757ae4c2e63d91f83dc5db92cd947201305727e77e572d9bfbde6bd7ff51a7dffcf6b9dfd431f8178b8670e02b8bc715a67fa4108e8c2a5933acff1492bd30fa7486f67efce1cce917e482fd60cf53f58810cd29d54ce2cc8990509275b33d64ba3f1b678a63cbc2d7e44fffb485226cb9f4b6f4b69e15833168e35d36b726973d68bcd5d90cb0e4c87a60353d5745b6a787259af5431f50a984bdac5a62bd39f5c905d2edd0dcde264dc4da6ef64bc8cb771349ec6d9f8195fe3665c8d6ff1e078f1692637e19839f346cd5c33ddcc34b3cd4433d958385ebccc2fb3cc14339798646698396682995d33572ae59943a3547e99ce2d48ffd2c2c9d4c2b16bfcf8ec68f15a556c07df3c3641b69ead9da7ef59f101f0fc4d8a8d2d209b2c8bd7aa6c786ae811fd2d205bcf1499ec3d3158bc5615eb790f4d4ef6e383bd2d5ec07857bcd6836f5b40361e7cdb0ab2ed60af8b0c3da2ef99a1530de95f7a5b3c37b96fe03e2dd2f115a1104f9e8f656d54c5dce47243ed23cb89da4716b803d43eacaa6239ab27838f5583da47569db58f2c51c7a77d58557939eb27cfc7a23f321097393bedc3aa6ae62c590e1f6bb68f2cafa77d64c5f2c425f9594039ed23ebd3691f59a4d83eacaa38c8593b197c2c4bc6c6f691e5b0f69105c6da47960eecd53eacaa6ce4ac9e3c1fabcb6016cd605698415c8e9f1564db8755964fae82e572b90c3e16f5da47569767d698272ec5cf02cae0f7d3f661554573962ccfcfb219cc82651097e16705cdf691f579fbc822f3fcc625f84d76f28ea763737055ac236b8c3acc7dc45531d103303ff1c3b7effb2ca05c86b8cb4d4aec56bfdf0ab2bd3e2b28973b19c45536e2c48993bbbcf04d8a8d3871e2d83e8cdbb16d01d93c7c2bb2f8f61dbe09557c9301d928bef17800e66f05d91c931e80f9fd5a20ee733b454d18fa1e4499a93dced4a73cbcaffbecbd7dd992d7ca8f54e235ef7f78ad82ec3d085eeb2e2db464ef13e0359abd4693bda31ed9eb324b2ee435bfde9ac945f63ccbd4905ea3ef3d8fd7ea7b5ebba141843dd390f569571666724f2705f0597435edffaa07940a0db58f2061430d418a58ac213435981cb898dc5591e787b1aa99bb8acb89cb29cae45a4bad99535745ae4f8194575ab9feadea3871e2b856f6ae4c9e67bce49b6feeaac87e6de4390af9ac9ecffe97ca9de259d37cfa42e6538c15e633643296e70e97fe5933d3d7ca37d37bb36385b95fab9b9e86534a29754acd5ce112822d99c769d4b98460cbb68f5af44ea3528091c28b7dfa4842f5e9dbaeebbab102b1d49d89b0b36d1f9367ec02019bcc239a6193e993b24c9f8e9487f7f49184683cede57e5a94e97bd55af7ce76b69394e80f21adf5763fa7d775f6e97b5dd7d52bc48277b3bec542b5ba8780d249bfa7f6a97dea3dfdcfd2a7f629a5a1ad52dbda9ff667f567f63cabdf5d66a8d8ef2caeb5deaf93fabb0b8cb0bffbda3eecf777ed63e60c9cd699c965255a8a1f50e2017ef73fbeefbec7d1f7455f3913bfef32c8ddcfdac7ccddeb0a39ed7b8a02efbfa79fbb2b0a355936c7ef67deccc3dd15059cdc5d519c20f3dcf9c2424efb6ed7499dd433d32142fff941c0ecb4f147dd2791d07e68e708047c71fceec3f00601737752a9954bf141efdbfb7ef1d228dee4da495d5ffff17afedff7e3fde687cbefc50f1d871fba285e3083210dc76f3c45b1ea4a2bbfbe74c0095010275fb5192f5858c82f2ce2b21ffc251af60939bc1e7e0dadf85da7119727e4f0fbbf1b838019a402bf1b83df63d397434cf5bd7ff939f9bfbcdb572b9c550959ee3a522983ee656bb2d78eb28c677651a1798d3ea551a0c994d2ffc40404c0cc1779add49167ad2ccaf333c8f3c528bee4f9e42c9a0408a360210e146fd674599456d833148a3162321458727f98bb0b0a2e0a0597cce3269cdf45a5528994fd657d91bc4642bf9207c664cf8e75c89468e886a2b934f079adac4f559ffeecde9f7ebdf5c37a9d525c7a583b6babe88d04e8c46f24c0f7bd4621943aa574826215ab6657ee4e9a35f977df5d505cc9e558e64ab65fbf5620cae4ca5cd10f7cc9d433a51ed2faad253b9495ec4f3df025fbd35805fff5757ceabe7efd7aeb2b65903e3841da81147c2abe481f049f86773e58523b4a7d1fe5c351beb7ef8d4e9f3847a9ef0055a6edfb2855a6cdda8f62df1b41f83eca07c2f75e9d544b5e23d3bfd9b103dd836f737ee29cb757ca87036ddd77fbf0de621c68b3515bafef9eab8a83298604bf8af75ce1e7405bf7f563dfb903d70998c3176f1308fb3a0699aff3e29797aa49f8e28f4fc720d749f8e3ebdc522be7cc8fc59ebc55344e9ca7896354f36177168e1de04266890e60c945b9bbc8b821a3a613c33b838da31d3d31bcb3107667e1d88ddee8347e07c0642c77020bd0368ba57cf8a665037115efa7ad1b6f972d4fc4e12fe50edf6cf7decb625cd7bdfd1bee7b8bb7de661f6fbdadc355b638b051d1b2591a622a235addcfc28a23bf1b79428767e177ddcf89676187b5b664ef3adcf40867fd03a3bac71e07828d941a1fc7e3b2173fcaf8b2efb188ec457cdbf9d17e8f208c2fbbe2872eced7f78370c3d97011b791bfe43d168912f4e247213fe87b2c12f4225ef2110492035a327d0e58c9f4bbb1c8cee7bc78c787dd283b0ffb6e3c00d08f6f6f919dcfc137d8f77cb78f0f3bf16dfc0d06f423beedbcf86dd3b951c4077a1b370ad0ef7ccf8d72137fe7bd5b6ae534192877d706dce4ee3a0173f7de6d0273f73d1f86733c00ec7b3e76a3c03ef639f706fb9c27ef0df6e4f778809d07fa25efb9b7d8db78f16a654fec6ee2016e393ffe2df63adf63919d07c237f2471b37caed363ef9b3779bce8d72bb896d8bdd1bd1dfeedffe873ee746b91fe53fcad0df7051845ee77bfe26fb9bcfdf789eecc622b0cff96e0481fc1d7cd3b2c53ee8dea62d86bb5b04d67d0e8e427e8e94f84038caf8b0f7468b8bec7c14f1632fbbb7f1611817e5e76d80206229402f7e0ce3405bce8f1707da481f1d2e9572972dd88b1807dac4b79f73634fdef197e878a74dc89422f14dfc1157813d97c5544dba9c5ff210974ad97b109733c87cfade754263570ad0e7e09bdb308e32c3b7a0bfe57c2f5e29406fe37fee4df63f1fda16b6e486e28a6d614bb663c6e406419e5790dd85459bfc25591f8b3469c86c60035af206ac68200d07d670e00b992f1c78a381321a00a3812d1ac88d7133e64c0e45b1bbb30f3bbdb2fd99c1ecb1c9bdc663936dafc97683295d950bae5cb6ef659b4398d8dd59f7df9d75b829db7fe52ff7d8a4a30a2772e2d8b4c194ae6ca1b8027b1bf8366d23be5d6c83fcdbdb20c238a1eff92112e384b8bc277fb4409e9f73b7de96f3b3bbf536f1631717fb9e0fc238f17b72302ef6b11f1fe8deb46c3bb80a0c73557190a9ca9e3acaee4a424cced326bb5b6fbb7d3729b1dbd6db70e2db76fee7de7c304e14bfe76f389defc15b6f833d0fde7adb0ec6e9e0adb789b84a0e96c2812de7c51fb19458d95d4980c91363d506419eb804128a5c765dc0e4266d26bfd696fc12c5877dfda63cbefe374ac13ef624e52125f630bc9583b9ec6bd9ea7be39356b61da6f2b0112d1be936d8571cf9dd662e479ed05db3ee615fe56db0b75f42c916cf3a5c849c5f2ac9f3e737e511c351c617bffe373598f8ed7880cf8d2f3e1d8b880fc337d88bb051fcd1fa9cac224c424bc6f166cdeb49fc17569a00f87ec98120c57f4d244811cf9a3c97cbf471b95ca6a2dff9e5d493b36a6ef2fa99079d5fe277192b879576619a497d52d8188e3090dcc9d92149722727a6a303cb2161b0188c8969dd6b21fc5e5f8ae2875ccc6cc59411a3258bb162adb5afeb39aca2169d285ebf6dd364fb9fd768b61f5ad1ded7ad4efb7e1a417a4a53c7f7484efb9ee6b4efbf0f699447067ef4fd9741fe3e2fb40c9cf65580ecbe2f3368ea14566ae570e69fe5e5aa99cbe04ff1cefc67af9fbdf010ad0ce22e2a70601bbfbbc4a890bb4bcc56ee114888674d34bf9ee617c6e5d7e3f6f1faef7b92f298b6ef659487ce7fff5303f1bf0fc19fbdde0165b2033e9075eeecf5d3e6b6d89dbdf0075fecab4c5bec3f9ca2ce9db6d78d225fbca5039ec860cd21f5d9b4c24aad3c8b82fd2cfc9a699e7d90f3b31047e560291d07cef8357b9e79c96926af94698be11988ab62717297ad0c6ce34b89a5c05665dac69ff2e572391896e2c5b18d4be6cff132317f8e5064a6d9fb0f53b5d5eabc53e34dc666ba90d08284957c737755804deefed64ccbdd1709bde71e2b953ffd92fcd2bebf63a7988aac543c37957f7d3a4239cd62a6e492e429857287a9e877ff89b289e9ccf4a7069e299452ee4ea260c24904e943e4ee32a289ec3be4ee2282874ccbdd05468a262c296e72a9b584cda509306c20f7c726112475227717d7953cc7e4ee12a24c46cadd15c49b390a019f5093ab94806e74c85538582eb1b8c842b6432eb1bcec1072914b2c0970d1e5f24a044758600133b9bc126326f77fb9dcd81427f77feef719c2aa99bd898584df7df7debd9ad903711067b20556585faeea3879fceeba8f13772775d96f29a4c1db1fded27e577f0c624d1e1ffcb0031d08e8547ffc1e9dc6ff5efc79c507eff83e3abd82bc7e968e6727cd075fbca5e709667db98aa62097fbbf5b62cdace54d4a250c5bd4a2411d1ad1b2f947a14f85621538b0f93bcee78713836a944b20be745a4d60d77d5971f9ea2e7287bb7cddf7fdbebb523aaa68228eadbf765da2e01a8a2bb60fe7ea97af4c8dfa7b3c8051569a5a9d7b08bca4c9f441db953bb00c1541500497c8f4e7100f9b40e6b2e672190b04c15ff2f97d3933d57cf0f3f9d88e40aa80cc0fed87d3cd74f3d5bdbaafebfc9bafd7ebf52e8677e607fa71e6658d4c1ffcd98f5eda64faa228be288e60501070040283c18688be293644149b6060234c1c7fc967a437cefef5b3d9b733e4678666b3d96c768774baa1f7f9a12f5e1b1a81f0d8985138331be2983334fecf8f1f8e77f6c56bb3ef3ed4a19aaf9427d61983801ff47574a20fce311445a1110f89d7aa49247a31f64db0ff5e24c2624c84cd66bfe4e3ed2c74ab669ebd387b1f8978b62f743b8bb90b675f67e3cb7efcd056a05bce1cf43d1239ca63d0050292fddc2e8bd3baf7b9f48dd3ba7fdd9c5bdeb2ce2d6fe42d6f140e8593bbefb278cdcdf899dc3d7de3b5d777209e35d1a7b23f9f7e8f1ed8fa5fbc367ef7e1388eefe3cf0bfb39cbdd75030680b00284162f5fbc68f16285dc7adb8b1f0eb481f8f1edbf35c2397e288ae3f84b1e8eafd7c3fef5b0b74b780df6dd873018ec050b41508c89e293e0b56a02c1f0bf07413014e705ab7019f69d4158ec56cd0c83fd48e428c3f0cc69fcf9239e5f9cd6fdff3de11fffc538f77fefbd6d9b53bcdf5f2efba0f8cdd98d40ba8b875c3eca13db259cd6bd8f50af0ce2d20119fcb07d00b90fe72d71e50979fedf2a6f8b82bbff9fa369c4c092b33d9ed21e80efabbcedffc3657dfbb76d65a7c5fe87ab689cd783977e78cb13f2eb7b84a2e517a565a725776f9770334eebbeeb2698dc4d2dddbb9909a69b6172c793bb27ff3b773fbf7cf7a20fe0bfab6391fbff742cf27fc3fff8beed9a390d03614f25da805b72fda0efffa606dea7c9f4836ee979f6b00ffa259fbd522ea75256ca3dce7ec9bb7decc8be23f7181484840ad2be529e2391a02f3d8f73e2721c83082077277d5a1ec45ead3cefec61b70c7a877ad8dbb061c306b561e3432adab0f14b4e924444441f4e91bc4444ef231022184c1445f18732423fc5a15850eeae1bb6721824027d2fc4e2efb5f2bcb01f1f46db88b6b332836a2c161b8164f2760e67e21ce70b8d04e846024cec41f7b16f0d50e87f5ee87f8484848440a11f1a1212fa257f2121a14f08cf9c6cbcf836c4586c72097a8fe8c5271285be9cbd7f3806a13f9b59e83fda66a81b891cfdfcd0fffc50e94376478c7557624343e2d0d0d08d81434f4722477908cf9c641f7bd9c73e14ba56350b7dacf288368c188bc562bfe4b06c5fb18fe19913d0c31ee8611fc2aef842f7cb738bd7c4af1f7acf9087a6fe78678689b0db79e856cd2cfe283acd6c5fe876b638147f76837e8906ddce40d73be3b4fab26bc138adfecfed420f4d79cb6077c58996453c73f279d8fbe00f8ed3eac36a0fcda587c64393eb7f70783c97368c0d93eb7b67bcd659d9b9530b3973d95dc9f52d18afc1be7e48d9782d27070441365e03bfba3b19f07d0402be8ff1dafcfa244992dfe39293212d27974c3e1d819039b733897d8cd3ea87afd77c7d7ddd9fd7f65422fc1f96c849b9bb7eb0d2254ce691bbeb8735baac916bb9bbba8c59434df6c18c0f60b20f5b7c9892439d30146ff76ebded8adfd6dbf0ed3e0eb4b507e0fb3e0cc55bdf7e3314c5d7cb83eeedcfe677d6ca33a7efed0bf9689b89cb5b9eaf9527c5f23cff1b891c850ffbf061b8b3e2b4f0eb87e1373a19e570da9fe3cff913637986c13e66ef78ad9ac6ffbe49e7c76faf7db8b46afa3ee79bc8ff7ed4c1edb4f1475cd69c83cbaa99c7ff7049c24a273356e160b7f318ce1c76b62391a31ce29913a66c9c56fff541e5b746ae0f6af1da0bcf2d41b30bf95dba742127f6be73f57ec9b59054df772e691b271334b590f3eb87e79b40662c325bdc65eb6d370fb3e58909e46cb8caa6891b9cb04579c04dcb56f42a28d9aa28d9b8e67756bc46db786d662db97349dd642793eb7b991b94cd0d27e303b8514e2eb9fef4827d0c9e5c7c007866c99dcb2fd7af5db6de76bf67161721ef7bf6015cd9d431bfbb418d34bf1ba18ae0bf4fc7227fdfc70fda760393f468fe1c3f681bc61f3d9a17373d9a0f6e19721d61c4fa67b9bb7ac0e2b0dc5d3ca4c99df3babaab82f9a099030f5e3299ddfbbaf5364ff43c7cf31ee7799dada06d99a1dfee96c9adb77de2b7f536fb169775001fbe7d8ff3be3d005ed7c8b5ffa35d156d0f40d95d134093b13cfb164ae428535ce5e589c6ec390132b1dc5d13109379ded49fafc39b3c012fd93efd441094e870a6d6594114085bb6d00ad2d099fdfaa552ee3eca6b65114d89d74a9204af95b2dc7dd77df74f5e9bb97b25af75d70e6a72f71978ad43caa598cb2663412e3bcd9a0a72d96d72d729e5ee91bc56d277fadd9cf3e7b44fed77cfc7b2d9efcc455eab9a71acfab16cb63f47a724d9dffaf7744cbf81cc0fe7a5a2fff43d0671a23fe92de97b1f7ab78c40b67f8b1205f7e13c883f7dfa706983d8a74e1647f9f79a5ffaee44df62a7f9fedd0b794d4bcfefbebb74f892eded32c9e3b5898214a420f718a791faed9d71728fb946ea5f727b3d87429e5dbb795120ece903195221a3079dbb919cc714f0a7707d18be6e77b9872eb69a5c373ed59108cdf4c1db366fcf7488d60bf923a2d46e08b094bfa7a393c7b2f7e1ec6025ee4ab6bfe4a3074bf97b1f8538c955b8ec7d8f4d6269237b43b476c8df8754ac6310ad2db94a49fe3ef459e2b664db8d547e6f47ef13c1ef2582b76d6393bfc521e8b329acc4652d5fb27df2753f97cbe572368ae95875c2941450c865ab769a7d8b4bea23915a453315f5b0c593ce9f39950fc8fe9d7b0462bd8313b66bd192eb835aace4fa2f25eadb25da64fba1126972fd11873572fdf0bffc11fbf1fb7964425f44f39a7d7bebeb25be44f13d5114c30f63b76d3d865433a7efbbffbe0ff63d42851f08fbdefbf0057ee717888378fffa97f8de9df9d56310b0fb40f03512a90f62aaeecbfa5723912bad2c3e95fdfa1f2eed8bf8f59e56eeeef8e0d59a39bd7efcd78f1f6a65f1ed8d5d7b45aaf1ebeb6377ca942953625fa57bc7f46c7fdaaa74ef2869b678da9668d52d76db16de2a8ac40a727cfa746c0adfe272fc10cfc2ffbe7b1f9b463c0bb193f7f6bdb70ffee77d541e14f5bea6fa2f5cda0f3f0c6f29feecf53d7be120dd871fe22c86ffa2023fc4e5cca52512e2ee24dc49e5eb2991fa212ec1b77766f07567e70cca1f9f38357014723f4ca987d7286e6a812eaa10521a35854a942ca898b942850359acb1353da2924150840c65d8a4814613b6a647feedd869d969f4cb252db71f9564bee18b5cbb5941f657f25af9f5f01ae90135d99f87f68392627739168b4eebb098bbeb062b72c53cb39bae46d894c7911b133851468e034ea4b159294890c21a3464f8c014b6be81f4a76f03f9d369d4827ebf5533dfa6d6f40d42ba25d7d7538c6409726ec9f5db0aaa04f86127c2c0ce5f04fd6f20f881e015df5ecf7e08de0edb1bdeaf1b838c0f3ebddf8b37fc25fa85ffe1ed3c5ed8f52e96679ffffdebf513bf7ede0f83deabc579c77fbd9ebe3ea4d7ab4fcbeec32ee42f39bddd873d8ab8bc6511a4e4dd7a1bf9ed0320f10d17fbf600807f6b0f007df2e9d791082dcfff79c317af3f79db16bb5ce287f38ef87ee07d8d412cf821784b2ccfdf47e42877df21a1829c5b72cf2da25b17b4b28755bf9b3a3c9fdef296adb2beb718abbe7d1f89d07289cb5d79422efbbf5b658348f71397f4a708867277ddc0432eb57249df6d809369b9fbb013bd12cb73f7fd0d84e2ac0f53cdef6cb1dcbbddd3d1c928531ceb9f5bbcd6d55ff22d4148a820b13ccf9ca6ffe7596523cf5bb6df9d93512ea92dfde977b7bce5b21fcbe9e844c3738bd33a8b0898cbf32919e1fc2aa1f9e1eb853fa7bdbceab4d78731d7cadfdfd91f7d9f73ce7ef7aa5b9e2f22950a99d9fb79e70b97589eabe61aa1dfd23f8bcc4d6a0e855cbebeca5b03853839ebeba8ead3ef9fb824f3fcd72dcbb27cd5aa6f4a0a2864ab2c9bbfcff2f29556fef0bcf65fb773dfb2ca7393bbb72f2ccff53d3c6b9a5d01648f9cdb39a45ee42424c68c2ea262b4a74720569a19f64a4f79e83c7d1a7d9ddb94470f3064d96398bc263e7d0f9ebc167e5f93669341a5f0e9d3f1492b8bb8498f0c3e1d9d74b87420860c82f8f312e0b459db4ccc3d09840d458a3fbbb27da49287c7ccc99c8707f4c87e3b7d21c507c169097012822c7b4db6efb403d9de1413c2c9f62797305e736c3b7f9960bad40c02e551e447f6bf8f2cc98adb8bb245e3a404e901e531adf8917dd1be1b41968d264bb60f82d7c4b79f00255ef362b3806fed4f2ed68ad7e68bd84ab622c6aaa3e3765a5127f97757e65f26415a9b7da41ecea36df6bfa28ebe7d92f2a86fbf8b2ca69a5ddd06c4dc4dc4279a524a3bdb5dd7858d147ead1dfe994127b5cd7d0fe47c3fd3df75d7f577fd545d7777ada40b11f6d7d329ae947ea5dffda4ea2aee9982b08b405c6ad5cfb94123261be5ee32e34a36638d19647248c58e4bdd42b57896ec79d9622c19fb15a7796ecb9ab1bc746cbda73c6f7109d3f9f2fbce79fb3b1f8f9db7cf834bacfa511e3bffe393bf73db8f62af73db8f481cbefda63c7270ec8564091286b16af6c4bf4896203f8c45b327fe888550cdafd9c35422f66ac6aa4148c290583463e17282e9f20b53f97b4d8ea9e677d9eb425c6ad1914897a75fc9202d721aa589b2ecfdec9a845c9be4da56964b1272fd25f7aa66b6d8892c574c35bf62fa152fb91b32f9737795e125dbf9768e2391ae5c330feb7d9d60f22c67983c71e9796fdfad789e7defeb08c4eb5aa27504325db0d56b1d2ea76fb995a94167efdbfbfadee5dd2612e6ceb7c2ece1fb037cfa0d7e9bc93d9ca6852c7b64fa1fa5d16ed9fb7a71e7c2d451bf7ab7aba2b9eb68d58239f925dceaeeeb574a2dffbed3bbd6dcb597bdeedab9e7f7773f6f5b69ec5beec2d431e7f4eb57fa7afdee7eb5bb1a44d2798cdf1ffaebfa7bb73e08c4ff15c4c56fe701fbd07bfab0eb7d91d73c327f99be3ef0923c3e22b182b4ff12527be1a69e7d81e36d3f02df6fdfef965f299664ae5fe4351097b249ffbbde2d499efa4538d70abd967125f7bc3c4e93bdeb409642ff6389a989acba3035e85cafe4ee8a4b90f43b8aecefd3694e3f19c8f2dfffcd54af7575bee7bd5e9ef7f2aaad59ec775d195b64b069918e4d9586a9a37bfa7ebbaf65c502a4c34ec3d4e121a595de1148d7bddf7ae5849a857e186ad5aed26fbe5fbba544f3a6cddd3eeacf4eeaaa2341d25abf5a7d9a3315ad1453cf25f5125094a54951ae6f67f8894a5e4c57ffa39442296b20e753ac9a6b511852fc79f64bcff3bcaf5aea76864ed8afb8fc72ed9e7ed9dfddf74faaae2516cddd57211ea7f5771d2e95e4eeeb7531e4ec2e56f739cdbb499b08db47e7b28675d6afecbeef901490541dfeeae72c9001a78c2cd982dc5d6354203b96b55efe70b9f42bde7b17d2afb8a70efb7ee9db5bba15df7217a60effdab613ae347dd9faf52b4e73fbb6cacb56a4b76a550d34de819c5ff6c8b5eb470359f2d0fa140b695ad759be1509727ec993fd79f0b74508c3745a3bcf812c1bcd0fa7cd2eff5abbaefb9cd6d9ae0ae5f93c57c8f618c8c665cdd383952764b70039bfb340fda2b065b9e27266fbfae961e55936c9df97502a399baf95957a7420765282a49f81d37c8ee277ef7d3f71d968f2fc1197ade61371d96c405cb61bfafaf9dff7c233e734b74899def2234992ccee6fc9f079bce67df89ff320e9917f187ef59a8f40c25af31c6bc54d64154c11c41499d2af99e2197dadfc4e23cb2f3b29419e50361c385f311c0c27dbf77f8aa2f885cb56437eb86c36320f37998acb86d3646a87f1cc515c36a1e5a83902a1d803a7f9f7094ef31bc8f965c399e20455a021d5d7779dfd423114adc56593a2dc3d08beea7b1e2e3d7bff7df77751edbeab66c5e2ec0ed69d545fc869a4d32a2e9bf410675744ffc800698ca31186a152372ebf287737962cbfd3ead372edba0f43adda2778df2390164b9edc40baab87d32a2e9bb4994cdfdd8610fc6aadb52eb952ae4e7ae4f0eb2d7bd01eb916e519f6a047feb3c7ec51f6989fcb1ef3bd0b29be7fd923fbbbf8f19042b2a25c91727dd8b7d7ea8ff5bbd8bce0c3ee784ba5dc61ab5a7a90bba72310307c914ecb216e52946f62cce8c24bee6a7eddeab41eb059d184595da6b2effdbf64a1d3425c7ee12d7be4f06f4b1e42c9a1d34aac1c86b754ca9fd35e647ee112abcbe277625697a9baafcfa3dae67fcea3bb72b9dc14dbfc30fc70f9397cef962fe4b5ee9d1ef97bff794d1c9ffc52963d7af4f217c8d72379ed837def4d7ae4d87f35f0fd6397745af8dffd9c163e2c7cf2cafc280cbfbb3c4e0b7f8e4044fcfd127df092f53f8bbb629156aeeeab678f20fdc3cf6bf4d65af6988c6409b2c7e4726eb90fe4f725b995c17e93cb3a4720205ea2563503f1badb7976b8498f71c2bda0821370725773f8f5fd45fad75e270d277798aae28fe269e6e55e854b802c793ada449667cd4d154c1104154d64144dd8b824738bdf7d69bfed1d920272be7da7b2d89120fd71576e600c2f93d259c549c7c83286953a02a194d6aecd1a6dc69835792e1f504220535cb554342d6009d94c31c67cd9eb2e31b6642c9ae97b4711c61b28bcf6313bc93ba93fa42f34f503dd12368c23c2f832c3d0210c18e60d2385703c43a42418bf3060a09a1848052905184dcc0b0613130c2266979e2d3ee204c3069f1e9e1fa5cf8bd0a97ccda590c8d3c379d8fc979cc7dbfc3d786a1f34fb47b5d9ca748bad6c35d99b8debf0f7d7d13eea3f914b592e934b31d76b45df2aebcbfd559fb3c23bbb722e8754ac97288755ac3728879d58af2c8756acf7c727879f586f4f0e5f62bd3c792787a158af4e0e45b1de1d391cc57a95720813eb15731813eb0573488af5be729823d66b73a823d6dbe57047acb7e69047ac97e6b047acd773e8c3b3d3e3f303c3565864d6d1df956b0ca14b610347c84fee1d9a20c59e606cbd996cdc50ead3d9a099734e1f29ed664386cd185a6965a3049b306cbcd4ae766cb2646783850d0b9ded2c9b29f94d2e67ee30462cc8273c18063e9bc40b1c02fcba8422bd23d0228ee0ca081b6123c8a901ba8189744d8c8c91221a52a4931cc31c32d9bf70e27b750e99bbeb8b2f3a3b3a3bafef0b2dd9bfb8f245ce8b37f97b512fc2c83c3b22bd5eace111699a1d9d1c32061bc5107c7d1e0f4c27e745995cd6eef2628c176172f979c1e585979ecd46cd174ba0f15e1b80175bb28b79c9063060a9da925dcdf42e0787f2a062ccf87f39724b76258bb1593e34a41a191b7a54be9bcc835ef1a31ce5e16cfcc8ffc9c8ba4831f40a9b2ec7a6cbb1e9726cbadc9cb76ace7c85f268db47e692aae9c45ce9b26285cbd6d69629539c46739acbb2c61a58e0c0b9f2e68d15376e9c46736fe3349a5f751d76365daecb399b2cce26fb77b99e52b73e2be215120b4f169916a12ddf71e9725d64e0b8f12c6e288f6e4a67c54d87c54da7c54dc7c54d97eb24355d6e0b55b3858c1a31540d5d63a6bbd6c0c9251593fde7162e73cc0433c3ccaef9652e31bd4c310de784d7fbdfc2f79f39af95de9c32b7fca79579c56b6537b1cc2c5e2bebd4e2b5b2c803a1259e1e2212f8fa6a67671734a4201f209ff77feac804f578ff1f3e1e78adca46974197851e7562e85197dbbab2d46de9bc7460ba9c193fea3568be356ac8356c646bdcfc161ee771e3a3fa93a28c47a828f7d7a84ef2a7943afd3e2bace8371cda1397b7aae7cc93d695fd67165bb25338fd659ba9b8a4515cd2f2546325eca2928a41960ea69b8d83f180f2f83e9a4ffb94f26c323d261964f95e90fee5777729a366b008bba8b4b9ecffdf976de6f3ca7aa5aaa13cdc8d1ff97f6c4837b20a27e7b27fb7e5b5726627e3b42b944707c68ffcff653292bc52c6ca192c69b4acf123ffb2e392bd4df72593b992cb7ac54b2e7dcb16fe1d9a3467d4806bd2b079b559e3c66b58df1b38dfade1b532dec6d1781a67738688c8d7cc666e866848c8d5cc8280ccacc9e5d2dd7ceee6760296d7daa456116a4d40ad2040a9247461a8c4fe7cf3c6b588a267996dda3896b9c6adcc34338d4f9967e699b9861933138e28fa1551f4ad9cd3fc8315c81087ef5ab464c98205cb952b56ac6c6d4d99e239cf5d89229e6b5c89229e702e1c332036f3c2663e6c26bcf54a277909f2c28c1e32084e73fb84175372029ce6b229b060222b719a532f585cc82238cdbd1c109904a77938021064c94d9ce643b93494c8509ce6b024bac892b19ce63f2c8c11279fe03407b7e0604476375d80c9a5bb4193cb7aa55e11bf568e350bf8b592fc9caf953afffa5ab953bd7c5f2b7dfee76ba5ecc3b8ec9ee0342c284c4d48f82182920c12a07441b81f78e716a4bbf13743404240ef4fb100cd72405382808088de9f5e99cddedfd72022a25666338743342444b76641404a94c7121757fca8b380b8fcb6bc70497af970296b304b5c88f1a3eeb2b8fcc874b824cdf851e7252ed0f851679bfbf19f33c22e2aab9a6cc54a98ad2d3053a6d49c9735d6e00207ce96376fb4b87193c5694edb5c791ea66c9cb271329e57c354304f5f9898b8fcf8a1c5bfaf62f93eac54afcceae503c1bae5456b96b9862c95ea15cac6dbb459133e5513beaf599386a211dfd3a4a167a899f1fdcc9932b0a7649c56a6cc1827e364ba8a14c142af78fff464856e7dcfc444a7bc9ee65effe387afe170c0cf2083374a4a6e9ce6579462a4255a8cd3fcaa565c148682a92f24f48587878b286ab9ea3a4cb3b8fdaaf95716b717f2ab26a6ea7c45e2de72299b2cea952eb67239cd742965c9ce859aec64288f09c78ffc3f182e3f72c425291371296b3ae164ffd0c994be253b86337370fca717caa362f1237f2d1f17f28bac86c93ebd64ffa905d95d6adee42ea1594513640b0292c97e0bc8365465a39aa147fe5b40b6a0a1a1af5ee89157c52a197ae44342335caf64d9428fbc8211438ffc6b179d6ac892b2f19f5d90315cb6993cfd291baf955d847ee7fd691b7feac66b6597d98bef4fdff4bc3f85e3b5b24b105dc3e7fd6bce6b6517a027dfbf4ef979ffbae5b5b28bec75debf5a7993e717f9b94f97c969fe3df74706516ef2fc9c36793ec926cf8fadc9f3616af2fc314d467326cf57a23c8430cd8fe6cf405c7e41b8fde8854b1208b71fe152964b25196e3ff270f9f9fb3a5c92b9fc70299b4f7155e3e33d197093fd7b665ad75cce59a6939e808204a47f39cb5895e924fff9c434e347fe6e9e8d4c4df68926fb4f33c8f9e52ce36eea7415baf2fcfa659ba9b86c5cd272e3b2e1643ac320cbb9650b36b96c38707844f9913f1a346ad4b0c95ece2de5f42f69e5dc522bebf4427f7ee92969fe3b577673ee8ddd6f74777777f7aedc37b476664d21eca2d2b7642f3dfdc72ffb4cee6f58eccb4e93fb9bfcb2d5e4fecef9b2d7e4fed6f9b2d9e4fedef9b2dbe4fee6f9b2dde4fe9e65dee42633c774cd25c4cc3060e6172f4e1b5ffcd8c3be44ca79f24ba59dd7297b9ee7cb1e3feff3e50fa0977dd95db30ffab2c70cbdd0974d26f78d8bd3e8975d26f70fdd139c465fe8ce2d4ea33fbb584ea31f74a716a7d107ba509c465f766716a7d1ffb94d9c46dfe74e2c4ea3df7349701a7d9e3baf388dfece15c169f475eeb4e234fa3957c99d5b4ea31fbb09701a7dd89d539c467fbc20388dbe7867ce69e5cc69f15af8268bd7403758bcf66a73c56b1f1b2b5ef3d66c79cdaa99e2b52e8de7bc56d1ace1353fe334385e9b669c46df8c19330d27fb970d27cf2fa79752e9eb2ec8f9252d4f717cfa24eca9fd98f764f97dced3d7eb3c057fe7c3e7792a7e0f8d7ecfe5b97f75aeec929784dd4f2c93e78764c6e4f9df8f3cdfeb91e7db0cf2fc4e29cfaf4879fa96dc37b466f3a340d84565bbc9fef30bb2a4cd1190ddb585167f12debf890f606bc826fa8b000bdf5f890ff8fe09f0fe367e151edbf7fe206c0dc97e3ecace177905c9c2d74feca3dc448ce360f65141a22c0cfaf928307cc3719013b3e1bdff5317994c0c43f0e7a38cf8d6f343cf13838dde47b95f85c7260b451104bfd7df7670941bd0ef845e0cf651fe475014bf4fe815f4b7198e02846f44dfd3e38121eca300fdf889dff77a0509c95e7c7d414142b2bf21f8b7d7db8266427fb3c9fec1d77f7fc3f91336a1bf8d1f25e86de028444398cbbe177ee0dfaaf0d884660c20580307db0cdfb6866cb720fc7a9c4df63720fcfaef71b50c1152d86458cac4d138b6d7df70340454be48c1f683b9caeeeb47f1c1371c0771e2d87a30177d1e7cdbd1c15cf373306e62ae8a8bfc046e6490802d86b9cafa137f182e5c7c618361ae723ec54223e62ae9db2822bee1260b4894600c9bf737dc0c01952fa4d842ccd561b24fe046062b36f0869b71cef00019b617e6a2b84e23d6703102db87b926fe280b4894a08dcdc33c930d39bfac3dd3ea5c4413d6212befad60d98ab48fa593adea07650f63c9f2f758365bbdfe275bbd301699c3c79265f0b15ed94a2479b29588b1c80c7b2c591e1f4bcc56b117bf9fc72a2b275bc5301699751e4b96731e2b96ad488cf565f263565961b6dac1585fe6792b2c59f6792c32f73c564fdef9ae9a707258b20cf456586496fd8f1516996d74d2fca1d6716927cd97dd9fdbad63becf9d75d2fc9e1bd449f3792e5027cddfb9429d345fe7ea74d2fc9cbbd349f3c9dbd349f36397a793e6c32eac93e68f37d649f3c54bb68ef9e1056fd849f35f576c1df3bfeb75d27cef7ead63bebd3f9d34bfbb3e9d34bf5e5927cda7d7d6d6315f4b36e914e17bcd76def7afef17eaae5cce1f045fafef7b7fc2fb0e0a3534d0bd2d438b1834d8afb50c1152e4326b28cf2fe708aae83246a6e1537dad9a71e28021f85442422ff0f5dfeb7b2a1e1eeff39e8a243baf7b2ab16a76b834c146ae98aa9a6023534c45f5bd66cd85b47d5865c9327dacce2a6b96e76339f83d9697bdef2ca0ec3d56cdd62a4b28dbc79ab9b3cafac9dd63d9ec5941d91f8be64ae90cb376fef5cdec65bdb297933d2c3a2d66bf9fb43cd962d2693b3c1de6f1f9f1ef97399639ad8e42ed23ab27572c44e464f6f7269d21ac309bff14aeaca01cf455ac8dbe14988fedfb7e59cc567f0a5716509e5fc5b3752f452897cbd9aafcd874beffb39ff7526c84b6d74fd9ea6ce157a136f0a5c4d4e472b62a3bb6d800a654d1b1893fc6fa85461bf953b6a84de7ab74b69c9712cbf5d87abeff45dbce4fd9aab69eaf526d3c2fc546572e67abc263031ac094295540dbcf4fd9b236a0afe236d94b89b9c9e56c557482be9f6762b269b79b361fe80af58ef9b23bd43be6ff5ca2de31dfe7dae81df37b2e50ef98cf73837ac7fc9d3beb1df375ae4fef989f737f7ac77cf2ca7ac7fcd8157bc77cd81d7bc7fcf1c27ac77cf1c67ac7fcf0be7ac77cf082bd63feeb86bd63fe776def98ef5daf77ccb7f7eb1df3bbcbd33be6d7dbd33be6d35b7bc77cbf5def98af357132a76adc7ae75ee4d4ddab4ffb454ff4be5f48a87ab6ab94878b8aecc7d9e962845d7b727872bebf28877e25fb797472727e0b88766f7f0b48f4f1dee7f560ffe713bed8333eecb7826c3c98aba48a394d07dfb8cac9e3b41ccc5552914ebbb10bbbf58af7bbe015badf159d36dfbbb7bb5f7471560be6748bb08bbe8f2465b2ef3fa54ffcaa579f3e52c5b713e811a52fd4d5fa5b40b657950d28f6ab621e1459fb2490afcfc34af4887e0f7a447fe9bd866f51f4883e08f488be92f9a5d2cc4defcc84edb5febae3b7826c3225d90dd793b3030023d0c6d00c88bcf1fd3c48372cf82d20db8defff9f24fc444241de9303801df1c6057fc35530fbe929fa2b33ca81e37137fee8fb859292fe86fbe9c9d9c9f1777c99d1118ec70d7dd1f77f17ec50c2379c920eda0dd907800a7e6600a860f683a34729f6467fc3e9f81c458fa3fdd1df703a60b41b1700d54605efc3a3f3b89f279390f06d2bc86601bee16837ae8d0a3e48e6c3a3f3b81efc7fc3f5e41c612eefefdf703b2ffb1b8e16be11e612ff86bbf13930d7eb6fb8a1c781b9bac7d9f822cc45ff86bbe118e3bff8b1cc06e68a1161d2033084b9609814c2df6cc4424ef30f127191d36688654ef397dd703f453e2f2cd483b93eccb383b92ce6d1e970cdc15c1593f486d6e85f0da192d0c778489dc7854b4342447fc3fd3ca9f3b8598f40cfd564277b8ffbf99dbfe1661fc35cf471b2eff97e92fc91f1f8fcf838f161dfff41e4d4f91b0ef6b0c73d8d08fc18d0df70e1cf1e37becef7f7c0e5bcd0df70e207f1fc0da7f33f8f9b794079dc70e20f61aeef6fb8f1853097fd1b6e86b9823017f8371c10e6f25ef67adccff37cffa7f33b8f837dcedf703ffeb1bfe17c30577df171e4f7cc5b9569bbe17830d7c4b21d100be960ae1726733e5c44622e1ea7cd8f61ae263bd9e277dafc1b0e86b93a3c569c88b91a7339161fc7a3f5f2ca157651e9b9e161bdf811fdfaa568bfe4c9a550ee27bf2cfa6005d2aafbd8f755d8135e89e2cecf1508025d8d5d6e5b41b6a01fff0a06f3f9af8ae9fc3c9df3bf7e7bed838040d9ec09452936febf6faf5de57cb0025935b385d349f43b5fe5fc0fbe7151e5f8e01b1715ec357ae4cf2c483865bca683af7474b02d33e62a2707b7d3c8f7ba485c5a3299be1de33518be82c1b01db3c488afc611db25c278f19a88af44115b2f5bbe782dc4576188ed172e368cd7407c0582d886711a8dfe0b5fbd5ed813e334dae5e12befabfcaf3cec81719a1593e9d5fc2ac7545533ce557dcf0b2e2d18abd8fbcf2d48cf7568e074979a32f93fe76df1b8780df6b3c56be318afcd9da2305e137117305e0bbbbc06e22a1b3d4f816c3d5fbcf692894b78edc3429e17af79b2efa77251350acc64fa9e18af59cc4525e3a2e2995c54649c3871dc7cb002593f3b2e6755a6aaa884c9940ba4a99e2441a7109a299226003400d3146030482c1a0dc80382284aba07140011a5a2505ea0c9c32447524a19630c02869011010118009819802000a06437b3b88b06ca113af6e79862e7c185e6e24ef73a68c1908215ee40ee9f424725ce944890ff64131ba712105589b985180339966aad0d4de1852fae8208fe3e822614da9a080a2a43e90f76d244d4b11122ba88ba80ba7ccf79676208ed3e891802dbd010f2bf010da1366e975ebc426f382cb040e4d1cdc52c56686d7800d52148012818163ed4f59180faf03851f820257890ba7533266a8b191fab97c02c04bf85d1380863df59dcd75aafcc1e7b93feb777db5b0f479d7cc04424274331989143855f401580ba0bec1ac6de17090612f4dbc147e10fae016bb2e27524ba3c4575980275b75051c1156235e0b1b8805b7e5e933cc03ffee3777921ab734c37959e48d8ef5c7b5ade88f74c398535f322cd15bad440c6b3ea3c900d0589cfb94c388f1a1bcd3ec62eafd290bd4358cc7cf2d988af1f1c456c7c11ddf0d9a84f9079ad364c7da002bbdcc5f748641ca04f480784ce9b14dd54bec09eae53965062765ca8eaf151746da5166ae34b53e764aec2638a1b15e8a8de0403ac7aab25819ee61f15208908c3f3a0c98c76a55a53b4a2c73485b1720ef4a13fd862cb9d8da5456dc1c900ad5497686f4fcc25a267a884a0a2e5964bfc34d8694aef7023ccbb0d29ba04a1cc34bd1f04222d07bb2fdea4c31de932cd847358677d443ff753cf1c5e9feb182f888051afb9ac75735b5c3de2f7422c27853284a5171c10e6750a41e04b3d74b04191512f53e9bc36251fee3d1c58ceb12446461b06d48344396c2392a2ded3548a09c8672fd0f70d7d3705bc4ffa476469c44a5f9c9902172a6741c6a02284e9bcea3999c939a30d2a8517234a8737e6dca3172a51290b15a1be5d2e28714c1702ec11a90672b8f7cdfa569a2ea70e03436cad2d77a79a4f309ebc066050f08af6d6ea9ab00384751ecc6089da78b413b286cfa494baa894e7c271a0a103528b318152b337df6cca18c717f1a4914c68216a945aef297715e1ee23e0b66669f16407c089d1b661b106c95c84a6f0d09e644e29360250c7e7e4910793a97e7421be451f22a6243fe1f95adf1ceae0d558f23262151e3e83fb83aa1a676bb5616341050e0298e27ba6e0b7dcc9100788c9854fd94305a6a9bb0e057659223e99a5e37014a319b54a8bc1b8fcb818b2d145544f9116d1c7c7507ed941486ff88f1a1327ab7d5f0ec2610cb0c65b8d1fdd4032e9125e2be979a6f8bc54cb5309c83822fb1b46ec48fc46e2043d118f0478cd03c1bc2e10322252f41f245f2548f17e6d5b27c89e10d1d8b3fdfa4f1b0c8497e268418968515db5e705478405cc9c4cae1e1cbbb8eccc5432f64b5e67464fc1641f4f58ea7a9fbe40263f3ad5ec803c3fd02d16684a96238e7973cbbc9323793c1b1ddafaab2f444d4e201de7e4a0d4af90454e16993bea525549d5a3c2898187c533c5dc116bca764fc166cd2df22e8237455a0e54a456be563345f6cf44604c1d033049d67b0fb5b5a987dd6a43745187cbd0ece938a43d647c4774fc4c74084a0aaa7609a6ee8a8e8e9004ba37f518d778b78c74bf4859d03efc4a30db89eb57e4040457d8c75464ace76704d0d77c724eaba29e4cf7bdefe1ccd8dba4cbf5ce154ea11a3c3ae89cd669d1d21364fc7a7a7ad9f3a26bd876e6f047d720a3014eb93d20d08872b352e135828c9347518e0134db6c49b8ac8b263d46f6b86380d81ed57643a39222b390b29a9012f610a712a31ea400dd80ac1d0abc679001385f637c826e712e734c8da0d0f9e550846c4a1392cb084a83151337e0ce02b9d52bc2148c3c96535dc0808fba594073e3ae49919be2d7c543fc366061ccbaebd3a9262b001789b92cc5de4c0b4d9944b906028db1a55329c15da7f0c65886495430cfc762111152986e26cbf1e68c209989812733d04b8c96d3e498a57d628673fc8d633a1f6475c40c38643db0b24232e7b70ba7b9ee274876db00d03a76c8c6b1765902a0f099f9fbf9c23fdcf0716ce1381555fb44b5753ce9f50435ad69338cd57be9849c5862b033924a53aff3f770b5b82882a27da553e0367746368edbca1451105a40d6c771b81530708ac3a44dc83f0d8e0024a285d2cc60a95937c9186e758fbb8b8e3e000c8df2c2cfa7dda07e016aebf68146bf2f50ebb9d9f384cbd07a0c605b4df0d02536e898af7355872d3484cb63283235bf0de9904ec546067ce4a7730349b4b231117a73406158625d8cc8100a68c1a00977d0b74a2b3b71d5f3731c5923a8f6f4e3c4a68614ed26b5af5e52ff121d5011fba57a24a00cda962222022dd5843dd9e26e7511557b34dbc532d7e9fce175e11e1ef70e53759f315d165476408ea10bf9f4ddfe8955dcfadfe337cf5e69cdd167e3a4684543289a4b7a143733960b3fdae72e8754c8d9d914b67a742edd71ea7eb723dbdc29b352cd05cebc34f6809aa9b11aae8aa243052f155ad5a30e6780d0720def7ff88f2b1b1485e35aa13df472e5b80a0a201df5f30eab2104e864ea2839bb8013d711fb377ffffd43eca8d4093e69fab6973fcb17092a1ae4f50370a9c55b0b33063714340f227f0c388a70cff78726920cef5e237ffac950055c0561ed693349537e0a91f67f0b4b42b699074693c455d94710ca5c3685f8162afed875f308c03f21ec3333114c5951461e93d27233899ad4e6598f4f3ba5ca02ef83f19b8483883296b8b4b844f4da4af689ac309a6964cd1c0bb5dcac33d7a23d8d24e0512dd81fc4213336525b109b698c249f67cc8cbcfb9d06b31a8092c07547dbfb84ce60c9decdbaa0fcf1389a718d3d3b98479d04fe0e6919898b1ce0007b136e28c2bc4e2d2976969cde80a98c2a3b9675d75809c22ba5f48aac4736926033e1d22287bf40c13114084d384b08472487efe0971fb073eb1494613c323d1342184dabf4c80f381eec9caeed51fe002c5f4866d685b4666ba0936abac5124b51e70b9da59388b14322169bee25791878f86d469969c5592197b88d5d837503b39566e80859d523117c181355006d86b4db69c80e1859c2458e929ac991a86f46e9be88242822dc9a9c9ad5195a21227cf1e442f0712038c79534ce0080933cc82ad1c54f30e42f1892d240a75613289ef7a18bed291c99289ada3594e633351cfd390b9282d8d07e0a3cdb9722472b2e7c7b23c8200d7ca3dec7945036e4c39fc486331231f0349a50d7815750e235e80ceddac37f98c4490e3bb2eea9382bad9c1321c0be33ba55f486782edab4571dda3038bafc724242bc82cb8855cfe95d127a481c8ef2fe17b5501591f69b7ccec4d61895567119ec680618c9438f69e44416d54889a8fb8f50a904102b00de27b6755ce331a375ab651fe42ba45be13ceb169f1c77f4d16542ce9a682ca06f941d896fa1a656d17093baa3ce527f76383c7921206022d9c5073e3c1f0ab1db64c6444cec44ecf4339d9aee9a117f23aad230321fe91e634f405c871103a6425cfa20862b2c4b5626dbbdea8b19a608fbae91323864016b463fbfae5539768e7435d093e0d0d3a9b19f4cb9f82d59df738334401aa6230eb599bd3310ef6c955ad49cf15678255a9901567a4451b0356c7b248aad7468482fa531e936cab9e00f2fd11f30a938d98804a5bb5a6b5209c997b4342871a6174a87ce9fdff6bfde8dbe39dfbef22845d30039ac1a913488be56a39327121342e069f3164a1b1b14eb5eff180e6201f013eb635f8cd1c666e3321c81db8285659625261031d34cba4d2172a0c8c26705517a11a2404403e81084b4830da83eb1b20ad12a41537aa426f574822ad583f027abe7f922edd8471db6a6c739b7369f7a077019e14708c21280f33bf0cc4be343c9a9b3692ffffb76ec87378e33f84c6a9719124909e9f7832334f23379763a135375b5018fdff8f26d66f9600d79d770aeb7541707c500ad970e26b55127e6a3a40ca2fc5045567be4094ed5277df674c5b04ba59bfa5360b6eeba5802b60e43c96f68a33f9db2bceff8b1aa0f2906b0486e7623184aabbb4329aa85fd5db76205fd0de6393a669677a0ad8ad477a22a750be83465d6d213f6b0296218d4eea32110d68bd2347ae3319815ff4d509906cf784f1ef91f00b57d7e5f78043d2fc211bc756e037b7f984abbad52831f8d6b8deadac65b096db275c89fac56f4b5055b638acba39831db86ce2def983c199a9fe896712141e15afbb7e3db5906da355d04608dbba91bb44be74174007b37c0fd1ebef81d0727b492fca256a7abb3a99aa7ceff8b06e06f01f32ff8274831365267cba8bce93a17226310af477b61584bfb59dbf0cc68022445c9e382844377ff586c463b7a9bc30746ca66b87c1d7354999a951ed3038e56bb4446653d24a8a21799c5d08a79f3901187f80f9c8ec7ffb3dfe1ae04b52d8d953032325b824806eada4662c7626cb34b0453fe475f86684b0f8477f0cdf49e66830c56b040e832d879e5f92eb74167f21d06e7f00e990eb207027a43ac8ff12b1266cca6c1520e560c1eae3e13311897e2c7b48da5349e0ec93d3331c4abcfe51efd1b1f372bd419b5df1cfd8dc7048aee18054eccb1ce1345286b0cb4b2b254a0d8ee79668685a5472c25253ecd57f9de378549b1099f5513bd6588eee4e9587928faaa9577b1689c10ab973aa7a3030967e95400b14e1401ee21b6bc1d5770f14f23dfbec69b0f99cbb86e0b627e22618b8ae0f5995d1ec788c88d7da2db6c25feb917465fb3087c7c63d6bb7ac4de70404f5a63c4a11b52d8a39340ae7046d0560bce522b55496fd724111e037fe99374381b870cb878f2a30aa6d9b6a2854b7c620022fe045e1f9a441e65b3d29a0604ac983f681fe9696fa11309150877981eb92d1e08ec24cb999f8211d955e85bc0641ebe60a9950380e251053c3704734774c31fe2b3c950be2562d881fdbde3bc69a26ee5962dbc31e8fd52a108ff4575c5173c092d210c5c87dff750d5c23a2e150a045fdbf4d34194163f8bc1faf5ec41c82f3faa7b2196d45ded7c3ad4d7d8b49af18baa9a801582ce917587cfae831258c12fddeb2deeba5a3628dc7164b0a08b771568f97173e959dfed4f1eb9311763842e49116dca48360a343ba4f75a28d6ecdf5f7ff52d0258b86eb5df72a928bd0f32004981d154c7f576793c7bf7d0a436670d5408357aff4d24e8f54a47ffe077a2f8d75fb06f13c33a771ede8012060dcfb792fa3dd9c4d308f67be25cf91158a5eb35da18e34da4ba54bac375ad3ad6ca9f38e7b87f65f3039df98f9704fb2ab602ec5fc13f7d63a5b517d128298360f2c76287afbdc6f13df7e15bd86dc7f5d8a9a63973e81eeb0e322918f6d297bfe54b3dec6773ea58f596a111100f4ece1de560836bc9c83e30846befb0bad501e5ac15f681f0b29ceed312f5bb05dacf2c08624560a15862cc31988187dd1ea064e855d8dbe4c3b80d2b7f5c166e166cbb84b8c966260557501b456df1c27b9cc2a26eee6a55cdf11d8e56127b8570131973b2d4e1bb0cf77557b3b46a6287ec693c44e64f362c2dc1947c0a67d327afaa547c279d770dce4cb91ffe548062f7da0d80e9ff4a09daf4e044e5c47610b7a23f61e30aab2636d3b349cf94a23c0a46ca8fee08f3fde38e3d710c5d61e77a949f5dd2c3a00b24344dcbcc3e6b516aab89ac68dd28fd540028e99367ea479a8a3fdd701f79bdcbede694b9bdc52d883dc52619a4c7f4b5b15f26c6ddf4b39406d7d7fd2822f333a0bb9265f53fa279517f131b707a4f78d95b2a6256ce2d13d0e284db7b1b48c815f5765a176a52f656fe7b13d92370139a3829b39975f7dbf464855f4e81c68962f4799713e2ba3482d27157690afe465cd809ad85b7e675dd26f20e27e084678da8109a15ce648d3a9f10fb9d20ecb767d2a934de2ddcb495ff5635a27a1d2a6a052b904874946b247d591fa96f0b53bf1650e84bc0c286b2b707f020e6c04e84fd93b80b853b6330b4e2ba83572e254cc0cb896cfbc9970c773c31109386d454f1d45f2da9b01a5807cd7eb6650d0c805c600bc2ae922cd15a74029f8b6c225e4d2fb00e4d5b9c47c61d0c6042bc52fe893f303986473587a6c21626d8cc65b5e6c6182581a054e9482c39dcf1f88376753f16d59b749b8c703c6f1beb559e0614dddbca13a5fb6c0b0257c2c0d585a23b3be49b391269a04d33ff12d5e191160e954c5cb120db982dc170ecc753677dae1a94d291eeb542e068ad204937d2e7627295507f03ece6b7e18ecb770a8ae1828073a470147109e3c9bf1ba99364555d1ce891b094a79e91689c7c5a1fbe2c610139245b94dd1992a44a4ebea8593d1fff217b2ed45b1962141837ce21dd9a41158e017f545881aebcb928c809e61c90488744546f0628df6eb1f617412095a9b96898a7b2974539616ae55684b7b2233cdd0433311855ec25625349ad54df4b614deb7dae2a3e441380e4bdc4b127dc40c41c708ad7de763b1978d2b6fceda0fa560df597bb1beefce1b6fd533add2c558807f2e87b9ab7e380ae6dd5457e920d59ca405a24df416ec9dc65fa7bd9edde2ff080e81b588773b1819b173a146845224783275713cf477498624c24f59fb0902f061d5aedca94f53e8b0304ffce44eafc8f4e2b2cb51d845bba3ea3e7947c0bf456ad9de331d8e9680676610d52bb289f55ee118d9854b18fa13cb0880cef4299616077f6c49e507930021df64719a8f1313d374c2ae2121d56ba80950e4bec4874e87085db2b50e02031be314ab0214a5ce328011abd1233769f2056c0b820cacf93e92bebbc6365992270c78ee595e97bb2e3552b74251a15cb4fa0f22f489132b3820b98f00d3c4dc8b104df9130008f43b6a408c2043c54f4135ae162d30b8fec9a61ad0449a7d871187eab6b55f1066bd8ffed4ea1d8ddb0454ede1b53eb0c56036030449dfcb19e9cf4c58874bb7c7e99c3ba5dd036bd7d2155c786d66abf2ac0da938c869cf386ed2f0603ed6f3665c52c5b75e26e3ecf8e2378e7c1091618e38aa6e43f2354e892b9c43e27e00fc07d1acf6e10a0a3920642e0e95671ece36d29ee0932a71d73842df1512f4b645fff8dc1c4ffec189e62d32544ec9f2d71e11afbc975a861c267434a56e84b866ec7e2ad61b89e14e4ff0e06c9c1d081445d4f5c4b32ac7135634cc3f3ec5de5f982a319f5f857907c1d229f7868b05c380aced9f758a76065d83b12587b034405936b500553158f5ac1bdf633abe996960d73e16b7cffc69124203bb4eb6db37fd2d3ae6a23c7e0ccbc92eaf9e9993f5bede73a4d8191080b69c247031c2da591004a892d9dd62f3ff3e163c63ecd41907480b15f291bd9f15921db85d919b12093c009d49f0c041bc40a31828ee468557e16298c179e804baa23df6754cb07fd06e32f3419d153398a992ef3244cb33635d8908a0e2a0428a0581c07b082b824ea70f04e74fc881139210ca4424d17bbe9e2f05ea59222e890472b90fa9e1e20fdde6d00e61498cb2a981348989d8d5a72f3b404eae6dceaea4d53c6fda6c21923647922d326cc01868c267b68e00c0e4aee7a1f32028855a3f0bf9fae2a4d0f027d9824c0240c9ab37ae6cec21a3658ba1c3825caa7fd93a2b6f9fd6dbadb9b5ca4f40877271e64a3ddabc24b78260415def55ed37ba950802777d12be92fece18ad8e1153fb09de81ac0ad0abd28ae751f6a90a99d106ca5b75839f0264188dd98daa69b063be3308981d5e6642ed37049c0a72430ae97865e5cc5400eb7a0b34a51d0c7bc9c5e8a99dacf36caa9dc19c055aa08f173cfc4973e3a082b06053116e2cee8598d401207497606617fb053a6d8a364dba3f74137864c0f07e4ed37e2747407f22b608662ffe9948853334292fa8e78122a2542eff20cb598c0c9e55049d3381b8431017ce970ea528fcc3262905bebc85aa442d283fdfd615acad81156c4841f5e8405fef0cbbd0d9c9c964650a0b162f44a00338c35fd5f48bb06a3fb3d96a358b5dc473e645d2c14e629d24f2cd9f7c507fd6999160684240312907666bb19de17cef4d75868a232a384330e3582df19a9c9c7c0288d2bbedd6ae409edb2876d1db6aedb34a63dc064da96bd4b1c031b9b00099b706d318a262d6db1696fba193e3d8db380794107b00a2c293aac7f108e057aa2e0a60a1118bf99db227c46aa84df21350238afac5264d230a0eb0da91abd6dd33b1c8d4f4242a3a1adbb5ac54c4d4a9f3ded0989549db94f9cb40cf1da78a9cffdabe4c2dc270c59d5001a26ee99539263c0335b2b6105cf5e1c040cd37965d635b100ec86d70e41d01dc0e8b8a114f0197afb574e36ccdf86c625469c4ed4ce668a4bd4838d45d08be3590c84f96c658898c88890d3545abaeae7e92ae7e1daee86e953a8525ae9b43345183dca5640c5b9a7638f91efeccbba388039bddea3bf10df4a0e4afffa390e9f227ff18f814fc29d4298da78f1aa44c541d986e2b564a733cd758e0e5278aefd7d197b3425fde355453fb3f286d7c7aa725f9f1dadba101cdaf6cdaf340de3cae5d9997e8049205cda2da82d18229c8450b04168029d4c2b154242d89126bb60addf8e8aa3ead6fc151c1090a1e9451f40946bce5d0e875f059f3b6a662cb3840644c9f3b1bcbfee4134bb023313e73d6e087ade5280c594ebb8f692c6a1fa149054e91f3556f87f69e6fc714907e63d0e5c790e3988e155542b369559815d15eec6e9bbcf3135209eab32744139047c4a4b8a099f13532792bd43070e6b2106c72d9600445f09bc10620141b954a1584fdec7777852bd1a65b0920bcd3e9c7354b1d26c4181f1138bb8141bc5731fb50060de7e24569f49dfd382d3cb88e899e4e747be59f90051c8bd0760eb8107aa830d287756a13e64d633baac61dd8e781e681c8ad6691dea5589c53e5332971568e4bcb292a6f01ffef7f54e17a728348f68fb0ecd0825680a10d790ad00611ade2c209b217001ee66d85f10b9862506faa36100b25e101cf8c245a3a1c62cf61f17baefa16a3474bd725daa9854317cc07beaad1eb6747f1b3a3b1db6d00c34f5438124ac63128d0c4acd357f4e39fa54bb2649f4edb86eeb9d6b6b374d51cfb22df38555244518aab32e6247582845aeb82a8a57c77956a36806aa310e1084cd6a4ca861d4383968d90c6a49f98fd8c35f50e39bc0c7e4643e385b9cb165b3330bd86f06ae3182c6cfa9db4164703c40dc5bc73bc63dd53b9b0127d51270d6e2cb47e729c4c61e6743c70cbe074a40819d9a5cccfdeb3803e5c70088e1baf0dabd4bd66b34b4015f3c1a590cbd461a71f7ccc95051e623fe831ab2aceeb028d38da9bb8e8256e74f8d6af2dc6e95813214740bbc61c0d7e725de04c565a0181a5216183eef0dc92719f0001bf9cf5d7b0fcee822f6d8b32107e0b1cc0aaf8fcc6203cd48c5a9328fad74f82b139deeb0b01e9d1955ea1ffc5fa1579756d813fd22637986758d91b703510fe8d9d522f76edfb90ae3d322b9fbf5d5e75ee58ff9b79559c1319322e5cd8f88d2932575cc720dcc873616e28cbe5d20324ff3cf64f274388885a9070d6f73cd2efbae3b29c006131658ebdb49e14e1ecf24c77694ca8c50026896af4fbe908e9841a777c0261613339e75b8a034bec23b45424dbbf89e15c761a8219b5bebaad083531ea640ab031fcdc1eba622301a919bfe907ce3b9450903333def5022f13e33e87a89c12147199a263f59932e8f6142bcc8cb51fef3b8cbb0cca06494ef94dfa49b4ef0154369589c3d8948108ec887d62e2626b545d3375aa1eb552bc04603f136bf47c6176c42c81024f04a7ce0fce747fbf4b76697972e12b60acbcea7b43885b1aebb4c19839099b2a977aa3f4aa32c27a839b1e801fbf6113f94b6bd2b77428d4efb4bd8617e8c0fa8e05d3b1ce54cdcceb1d8799472389094feb0b4f7124aba95cb0cf970f3ba9f7011e0ff115f04cb4a6d37ccb8d2785276c3f24b1a9afb92b6546f44725d1541850ae5ddf58460b6c2a02ed94178b706112b12e0ed2f0abe30fd30d9129424203e1233289b10370478381cf1f088fb2472b097ac70b9c405f8ba220bdc5a8c501b2aee8a6fda415682c06b3b3d027a46006b1604c0a780f45c36c5792e55c1309fbf26ad619eec3efc8399e618ac9806cca0d7bb88dc4a88342101de4363aaff9ff8ea85939f34465bf7900aa4774b24325130ab183f58bb36ede6642932f247bd2e382b7836c03270d8c1ddfe6eb12e90e6cf7a84c0100c62c1e1270c0dbaa15924a4e10c6525511d7f16fc6708b0a6bd9a0405ec6f21b971c05e38b16d662a486e062862ce56effb3dc4370efeb7e0e31604a1f1b12b76b421de885c282eaa5f5d125f273be52c5edbfbc248ae0e13253ae3285aec87e5eee5d91b1b78d2b5215658be5e10c7a124ac6e30146ee88d844a7875fa1162650a52024a5afb1fb5a278b99b03df4d2d010ad7b1d670c8f28dedbe4be87eb4682650f5e63c9f3ae4909ef2f6c88b2604583dd366d8000670105c3be0b119c17bd7ae7db9c569c34b455232bdcd1ad65db6def6e605049d11b5fb597f45a1dc2f173a96b0b1ecda1736c13a516355816c95506e387aa8d79351478e94ade363ed5d4d5a2b4989e1af8d578b932f826bcfa5c4206b5971c9e77131050800025e15b3eb2be5cb1f511f2b16274882a481b13d85827e46aeed120a90d58c36f2892bae716ec741e66ad4b8850cc258a147f7bcf4255b18abbd60772dc0fe909a55272225ab690df2c75dc100a6c456d8ae1705e7ff4a69fd106e50f148f7fc7fe4446a982ebeaa580b07807305b00789e38dc68ca5c8da3f52ee9d92dbd468e157899140e654e502cb742af1f31577b76ecd30893bd08c6373aea343896364a1eef94ab79c00773a855e848cf6dd8adaa2d0982e2c9d91595d1986df402903cbd01774306432752bd2eb80742b4b92a7f5fd9d7bb358a5d3d08d38f98aa0128bc914cb7135cbc6cd3d218d19077a9b6f270be8452ce58551d79f206aafbffea74ba3c72d82660ae14d37ccf71e796619f248cc2864759e2f9720960b6b2918706a1b8cb4d72d7294f91499d23f794dc52836444831f69ed921becc6a65ae36f0376cdf22f251f1addf39879e47cabf53ac5dd34f32ba7f9076778704f3fbc6b0485fcbd022d4173efdbc5d9497d42d370d9d9f9bf9e1fbfe037adb997eef80ae2ad0bc0d34fa9dba87a23143390b02d513174106e9fa07cdceaf75e22dc0d44e89844d2558f397e2014e66e24dba57dc09664102c92da95cda239b5a981234f6305c164c8f6e711102ca4c5fd76cb4947e896913c169d98380fecaa33229ef0bc9737c0635fd93b9a7c104e1e54a86693ec567606ae8a918db1748e72705d1f9954af9ecc7cfe40d755b77030fd7deb67d6ab6ed95b6e7b7fbd5565dc7a4dd3681106d7f1008ccdf7a3af052b2fa594399a14647a9a53325fe3677da4c157320d85d5913c20fcbcecb823d9e60869f642298f0f8878aa10a2dd7cd5c9bdf60951c2ca331ad77bdb4e1c79daa1f7b33008068d1938ce7760804b54a38731364de9d45082aad816ed4bec8924dad5cf0e00d16405248bc09ce590b3d6818b2ff5220024285bee6e2d8f6b0c7aa9a837dcc8f926e09825cf5427b013eadaa823eea9d31269542c61f344bb1c606e1624e09553225e4564ca80325048c70cb38af521d8707a723faee0469c6516c56c24a4309b83210f80e00f8d153c53d3a18a8400f9402348875a548a92a05b052da260eb6702aed8e2be40466222019bfd585e9e94c32bdad487d426c8947f6db2b60fba0e22319cf0fec4d05be78555abb9861648cef8bae2f58895a5f7a9a1d14c38d4a8def5fd4850dc3c267c013cf31da5b9d4132cf8da93d1c14fe3253f614d2543408f137d73c141fa083629ecf05a03672c8212d4f3129cdb0652f24030d99ab0644c18c24124c53e8574dcb36d433918bafdd59da5b250d14db97c0e5d50c200950273f02297a4199142cac65d8da18e846c7e61be8eefb2360b67934383b81dc9f8b68b935a09a9f91e5fc0b43f96a97d67bc71fc883e998d8497e4ba5e1d9de8197101410642f2769ce08c7f445c88cdbf3ca3f26ceabba1af6abddcb1fcbe3b29bd40d3cae926d8e5324ad70d9f63ee508365d0d2067d3d45a55bd58bb1b955dfb23289da0e684d2690381a87dc2abc1be33ff32efb738b76fdf70315958015e2461dfa90fdcfdc7e59da840b0be5f26f3c789d09d60ef93f18703e54eac86075a6eee64cf49ca3e977081f9707711a96f33bfcb42e09cb340b0999d1998cbf2b251cbfe0f9ac977ee4a3e8a8884d634f35f18559b03f0f7a65ac8de241d6c3de80cb5f9c8c652bf1939151eb4bd91357d25fc31059406b884461a8d7030066e45b3805163cb4fac61dda176d6203180e9bfa4b2f9990454c92ac4ce82885e808a60ff2850f4e181f17ad6dcc82900bdc9356d4753d9a0481bcaa2329295e05cf0e8834f09f480aa0ed42ab6ecf4078c92ef623a9d38e9ce846b109c7426287d832e29e66121451a0ea1ca9974f4eaf216718dc5bc855f608002850b513d5e0983b8d2b388c59772948520b7fde56690c66015d8ed9ccc061978a0a5ae88a1aba0348aa5da98d8ca68d074f1798735d13f4fb14f9032b8e95580c410883d4cd087ab0a5f272905a07d6e7191295f49a14a3e87c94b86a3e4a1120ecaf72ac287272b5011b17455a5843d1a5fe18fbf585c489ae7389b9d4f64170735add806980c31b0422d03329faa097d85e5b8f95b6081af512f0615766d90937fff9fbb342180bdde34997ad7c275993a41660be04ce388a7351fee14d8d94383cb125ba257997a05972de67d633f062758e5d6ca02f923ec12004206bad5762538ab45da29f3d71c8a6b58c36a9afc824bc1583e4b9d04d2451632ae02fba62e056e8d6267daa1850e999bafaf699a3baa01030e7e17d26dd1e1d4b90fca914949e4530f36a32c48754382b02af18c601b1f8b5d8f20dd26213215f0b3457bb0c3abc7000a89360f25d0891bd6c9ce1f34b541945389d1205cdf81250062926e64702518f4d50a87b5c0f7c153fc4e6b2de0f70341aeea83345b0ea2b18ee21d427a71048f43e67fde21b881a3bb62e5343ac4bf5942491bcb638080fff4e5ef2e209aafd031c0b4abe34cd96f040b45c6231a20ccc25f2015ad208b3973e3e0d0a45134675d8877f74318135df48bd4b51691c524bc61f4b45f3f4662aa21c2415fb81f6ca8aa52a4c91fc12fe6c8e43ea8db615e6e340009705d7a61c0190abb102eb55d3bf054bef3371be79b1466d8e788e567cd5838817d83daa0774178f4391224d662fcf081e267d669a8b788aeb013a0b5cdbc82261760add291c42b16e4e500966c1e0f7a03b0f58af0b61ebc4e77808c5af4c68c41cd56c27f11cddac3959be3f8248ca0061d3d8ea36b957e3da81793afa4e29b3d170ac70099f40ce880dd7a8080f085b1f368f1da0a076b838f36413d9e5218fdf6f7532d771c3e4d8e90e6f06c7031e9be8585c3fac41a6029599d80419dd5b893d64f2a88c19ccaf4531ce13b33d060fb6d9fc07a0406d864dc08eb6a01f64a68b9f2f51458fe50d4411858f59e441fbe1cc2d68b8928a57579c858933e51bc717349a1be842ee5488c2899588154b58ba75a95a42b265633b1252996606e2d3fc4a81cec6976ca3cd5968f88af28fe2d6135a6734997806dbe338a497bab83f064c17385da75007986ab1462bd380eaa515b8260a5be49e000d5f5fa5003fae4803a4d08a015940e7fa16be740e3601d7f61bf8a2f8cd07ac89acdf67b7468c0136f50ad8947a62b7a5ffdd35e001be051b087f470e34da30b3b7c5823942882e4f7ccc74bbb086b22eacd4cdfc13d551580a365e51b835065261429458d06fd8fab8b1b5ea360f76c5114af3323ba1fe2a1458504a8532aa00ae431ff3ca5b0cfd42e4fc85809f20d4eed0c7f05bc019cdebb0bc15ece85e1f3d5d5508827df7ab1a8eb9ed27a2ed3f7f355f45420df5e73fa393a7148f6a40e625cccebf5c4ce22098920bd14692b218c844017f8438a8378c8ab10ad18dfbd76df58c56d0f33ce90618599781f8bc53ee897788d210cfb2fe286df55b15690347073727ff544134914269bffc1919ef2319f02362289c00cdc1c91b564a4bf4122245c9b5b3ff21056898bd556ea13221bccd545d2c811e5d8e27b9240c8cd08c86eb65df9fdbc9aa878024443c861a2d348a36c63841947c016de714326cb4a12cf811c9cefe4de0dc4642d8d6699a37fe88e961bf03af88c264116a43c41278d5f98fbbc984fa4dcb876ef3cf2086aa2ec811e1e9e106591de45fa09e6c82d483ab739882616fbd23314e7f7ac73df0e86b6768f47597c76eea13517828eb09a5b4ce5829a73aedbdd7b0024e4f1741299453823121dca3ed66fe24a577c21c027421a35db30b302e4e50704f7ed22306e5787d12db50ed0ab88b8de663b80b44ebc199bdbcdaf86e7daa5bad4489d1d2aba53498b4267ff1ec9cb60906f6a54491d0533d7a0b602fb5a00420ad1805355eb5d7c9bc7b975b9abcfb0688df3acd848a37962b39bce80391564cf8acea654801853ad55d0e9a35e83be6adcf1f7b2b8ee4efd348b08e407fc7fd8bed2afa0fec8c5e6f88c9fe5255d2ed0b090d33a718684d7102fcee45df4e80d3a79e1350e495d2393a4fd121e7d608df71e606bf59a5402aaf786e127e0483f0ca9ed099ca967fe9b65aa27bb1ddf18d2ccd02580d62b2e2a7cb6c59ee502cbee7201a018ab9e0809d21a30d9077b22bd2fa7b87e583a9b10ca244419c98ace225b7f0dfdee5cbec03d89879d7af8c814f9479e01dde25259f87d8a38107b19ce427b2cc03b438927251dc0dcdbedf3264a89f4723ef8280639905af863e04d0e48762628c1ce2eca39a97e7aa7810c42befff4ceedc203a8f1c2ea818b87f056496b0087d94d2ab89c72dc3686f6c1fb7f0e13c96c129483660e142bcab5bcf671bee90b3ed95d4ecacbcd967d635f2e5311ff2c12437955030670318370801a2cd1879070530194cfa4c8a214a0d372af60144eaf90f5b16f61463124e0853396c211f73703232f54113b9b5c537c00028b6beffe1de27d9c77463d7815e04fdf07e80bd2c8b490ecbb05f9616a0d164dd66f8024aded6b97b100c4eab7f10674bbc6699d5326dfced3a8972a43dc9f0428d00d56aca91b349b64dc4f942fa0b18d04ebd6b58ea26a0786a6371883d66821b995bfb94751d88fa70700b9b908798fb93828ad4825a6a477137c218c53cafade1c24fa68a320e863b6e58af3669d914dbfb18a4ad5e1108f27d173a3a131e2a00a017044be7a8515670241fb1d4a258addf698cd74e6f72da771363b0e88b4ddc64e0bdbd192e16a7cf58738410e434e821e8510b17de267581150619e8e59c6d421b798dd7385aac61692d23e7b22b5c74852fe59af38f9fa4872867de534533bcd8d612a5755b4b44a65fc51528aa1fabf076444d92084bac2d05c0ff1669feffa326069ff3e178d951d87d8a6dcf93f4982b8e382842b3f6ab34d155b44d3eb91ee5d4cf802ff25292f6ed22d229d4c54e8f47c74c0664fdb5d64e9ba0cdd9ffea4f233296377bad104ef191f710a4f7645b9f8e2e908ed871c737e519d6147a20a44e287b4e8177014b734103e12c1f34ba4a0f997337a9c0ec4989dff7f11efb4ce1ee68c5dbe0269133c118230f9c198ca558c8830665c22951d3bc8dff37a1d767312a181825ae221b0f5e192ad1f13835306e84fb055d209ba8a769c7a8a8d91326b869dec9b20bea154fd370e1e490c16adf6236611dba398234130824cd71a30b4bb347942fa31a4e10635a447b9668c59252288f557818825a8e7844633218c435ec350f5d31eccd27f254d88ef1fc66fb297779309e815b09efc89ae0c8861c95f087863318f9b30a0950084bc201d1588a8cbc116104451408428118320de4a414b23258d055b87a331d9039a050c3d1dbffe319d8692b220d0be8facefef82b57fc173270b3625edf0b00a2456367c9071e8e9895f8359e3363c011e8a5075076b1f43a7ee5a6ae84c4a9a563d62db75af0ea10909f950e43132717b0c2e437ac50da0b1fed7f183eee49e55d2f0f448e5a00e44d194023e81a5838e6802f758e74532e28f7da43dabe92b9773ee64efee38df188885a52a9558aa8dc42163d46b1000ba87472e9e61d8fb4619c5ba96aac16f4c4df731260b8ff0988effaed3d06ebd10b3862a3fe5a7ba57ade0b93ecde13f39901b71948f98579b487a1079321494fe42f47bca7a6b178619fc55ad1294150b3c2de93560b5c711a1d81b44d752046d1ee314c3520e31606983a46adc7749e06a6a760a353bcb8775bde2ecff511daf85dc3267af07dc73963db5a89b9dfd892b98001cb5b9d51810e5100a3bf72392587ad3f389c8e470f2479911d42aa6dbd605504e522401120eef5e716656d3e66b83cd54ba0ce07142d0f1c97abc8c435d72de48c0a1f1d5170cf5cc9afc7ecf346f0992ab61c173d0873cc9a1304b834176e824b68153d56b3bd4f333c78ae26a9bb41658d77cae8cf09bf56d726d1a07df16d3a92f1798540e6606b23609f803413d403f6aaccb7edbf08bffbc16edcb571d6608d0ebd395b86d9a39bb26f150ee77a3a1e1c3f989b1b9be78fa705660ea1556aa3e152db91509d039756050161afd41bb4b18012a09cc20297bd97d2974f36dd27f0458565f3607ee192fc43274826147084eb79fdd5c2dba8de2a4f24b837b07a3c52ea74ad725fe9760bb9bc5d2093d39080dea92b8d8e0dfa4c15a0b271fcbb0d9364405d216ab7f07861f3e544a88e65c8d5a452b10705b9bf3333f637cc2667e1d89e873870265125f5e8660f26afc3231bf8fa8200b9e387e18bb0d51919300b7fe3d4cba25e38e20dcc3b4f095ae4270190bde45a51211206c1624f44180645ea29342f181a21b7521e815eb09cb1082ba453a51a27a511bd40858232e89de8f88393cba94dbb77adf1827b73de86a554ae8537dae61af57a82a8636daa6cef0cf19c04edd6001d95232af5df5b5cf25edcbcfc09a08f278458890b4d6a6f5328f73f91f0b3cff502f1850e9b207084f59486ad1c6ab1a9a36bd847f09e1d562e30c580681385a440508864afd9290b03088212480f737b3c14fac20d31b59f1dae9c50e301ea6cd9077e13f46d36acd1b1c3e3d782c1a750e71bd37ea66094f4871f142b2946bd1a0b4e7b40801b96b8fabd650929f40a7b10b7982ece6c566c6985bd845be6bbc2bdc844c04003b7e840cf46398ea9e8c863fcc3e8a33716bc863add63cfb753dbf1da4551a704bf526ad5148db191e348ad737b15c44fcd80a65321c671f08c1a5a617d6750e05e3a2eb075a1f5cc24462cd13f11678afcac86aa523095b8f5855961cb8f2e1172e0ec7664cdb5ddcf07759b1757008b13961358c0e191db77d1f1b6c1e787fe9336fbee3e74977fbe740de5ecbcc3130aab8fd24314cca984658d12551afc260256fcadb4d790dd9ce68ad124d8d479e802060510cbe2785d520ff87b770a5efc0c1a5f338ff32c0ffdd6e6e8ee4ca0ffda9ee35fa3117f0ce7cdada323a824466af58e494103cd2a22a6daedc9c5341abad37dddc4ea0ba626b0f4f2558d1a6d4b2c86b856d373e741d1d120744e3aaddbadb9955c41c7f58b31edfcc61b4a258d36695d75488dbb47e85bb1bf520d55a60a16c79c3ceabc4e782a91e72dea496138c4140d2cb562da741c34bc8350a0f106ece16101fa593884adf51bda6f7bbe79c1ba4ca697f0373443b71c5607628a41d041611eb7879f9f52eb7e976eab16bcb40a7c2bd4853571a87cd66cb6ff39d37a4481ef2d47f5d0c153487b7898d882325f3fdb075985495a7ee1cedb768cd09aa3206a8604e67a5a3f292e6525baee4aa201e934760815f95e6451967e2c9e7bed1aa272c04da422ae233b510371c0de836a66780028ba2dad60dbf634c67547cbe06fc9f62377ffb8895b51aa98df42f9615094680053c60287da0d445e8e23077e94122d6189f217bd47003b3a68ad906cdb35f8ae58959026abf14f7fce489f7e5d739a4437210d716ea377bd43ad2419f023eda4809812f5f4046c024115511a500fbf9ce552d20cb6fa77f67b33e8461136f11b31da156c9f000c8aca37a06a2c7df43c71d607ba5d4db33b0271386976bf4e487a129e8a2d19f4fc866512207d789b47e983347786a278d544cab4d094fa66b1e7a93c30a37683e7307899b8f08ad1c3596a921e7c5308ff7b51dba094e6c8b22364a4c037e5978beaf0e5f4646f8cd9917af5cea29f3132a915266f10b1aab2dd1dea556f437145af0eba60e9b3dc190fbf41978088471ffa6e84c64c46018894315933bdcee474c3fc0c3b1d81fc140c75d041f0ca361ef1e163eb1c826517d9a43c8731458f8bc47b45050fb90838572c09eed612a6c4172ca6f03d9facd0b2b8b27c227aac59f1f8c45e9399c0b29b3cf323e101ec41c1938cbed58e3c51890aeb166bb83a2cdc1d889b01f569827eff38bb93db16d942e690a7210d38b0072ca0e37e96c0a2bdae85550bb7d16228c5e2e88f8a71d35ec0c196f46fd8ee7a9800e79f44a8a9263485a7c0f1e688140460813ae0a2116719e4d2cb0b6da83e2b9dc9ea833026dcf67674452bf6aae334500f5a30843729b340f31d6e614152a4a18c03c7a7ea9b8bb5f32dc817ca105713a90e31b42fbb0ed014c06835837189ff72031b10555bc575f297bf7e66fb984d1c93ad796493b4961e9393b5d2d4320f85cfca01799e7c76c0785c406add50f15e328c7909b8fd2b8f3f8d58e04337a07638eb3db7f01e70f00008028e2f5367ea23f236a31d85a602fe0a02eaec593b5700c39eb12a138e4262d37ce06c8755ae88b657fc084880f8b195c8610c911ab14444301d794a99cb11aa4a2eb90def070bc2c25427b1e8706c0a397c7973602d3b6b06359d6e704ce029f0cb0b920951de901329539a9607a9edc1928f5e67db870a901a497dbd87a5ab0187541822b46386343e81dd50a60bff83ea101e9c8374304c6a721568d6a6600f299041ba91a04efb848a5895adabd6a74101bb21272784c8a30f33c833ec99146433639d507e2ffb81084dc3708e09b7c93a013cfbb636247cd5641cab8ab75f38b9d651c7d03f0340a3ca06f18bc5303a2d7006192c098d6fc1e40edb846f2ad1b7b61b9dae53b23e02656bd39d002f46fd52153ae86b54059bb6f878398ebfde6c8be70567102215e582613b2a3212082e2793480bb9a8926f90135bfd978a251e6ec857686c9a0a8611b59e0eb250f5b7c308e68e20cdbb873f6c6a5db8d4c37b1d4c5ddbd8f1a964a2b77b1722df9b0e90b7c61074f87ead9bcb281d5c9980406fd1327ab20673bdc1d2f1c7e58d9e51513ea23f28aa9235ca9a6361288c6e3213c3c9f1b4787ab91b9a97c1f54b089bc9536042eebec9ae9e343a5d00d59c3410f2248860b6e432121eb5cdde68fa0da90c85c91317e8c97e09c5574bda6aa3de9ea78b174800458935842b271f1b2bf9ebf78e70df2f01047cb16735c16b51d629d626367eb80ba31bf247a9a586faeae4c72a58e3ee9b14f1f9f59e633ac25873f5027aaa6c3dfc9b4c2d0a01494493d7d71fd4bc8923d84237999c8b137a28e0d443f2465cd2f509e28c02ba1e1736a6ebfb26796d8cb9537653b0f71dfebcae825179c352e04286924083f6e0342cfaa10369c0fed7a9f6b5d1b85c520bc17fc1dfd7b6f19e01328cfe33a1524eb7769bc48a19c90123da8119ef5a9ba54239483e8e04dda18ed38675164a2674b174f8d80ca5e158fbbaa6e8d4166b732b1670833c4835abbde657e8d366b7ed2063bac598a64253ee0890e84ca074d233dc8843c87dec5a5a31c3b29649a6bcf75f92bc1db6320e281b5608a5217718f3361293c68b2cbd9ae24643704d78e210fc6beba7f94c92788aa943d418ac7215d0421b4716204644e57ffd099c4ff892ed6e3abee84429c2bfaf4c12ab170dec3a932ca8cc3d20c3f35ec4c50e30d2b6cdb977c0f23af2e497ddde0ac31d5ad909ddbff3c7274885c68ec1c4805834c70a250d69bfa6676788c328448bed3170ba681a745f9872468be888f9731879eeb9684d82e6f23e0f449528ac828b83400dc1c0f138948e93793383472ff89ead3a908db8caef5392004613faddfd604a8657c31fedbce34066546a6ee2d8b64a66542196aefe2d7236ea41eaa6e4cd49880f00fa555943d09138d7122e318e25f77bd29dd6f1da0305cb5664e8e09e8a3a7241bf6572399d05adfadfbd22010b29677c30db53f60547014053f4116059dda96a6d5133a0d37ec6dcb1fc18f5905ff7f82eeeb2a9983a8735210d0cc3be3d19e17a543c31f2911f3f915e8285540d8004e8fd5b9f14c7458b35b9409aa005e61f04503f90d59591e2e737e3043cfe9cf7b8a02c61e228c80b71b88d7e590733ce25f38c44ba3dc4d223b3be22c9b5857ffcbc15395e74879fd603b3ab14745d74a7260bc78c30cee9e0e6694e7e0213deeb7b8c812187ad44e1d3a9bcdddfb509c604a2e957b122fd08aaef1c5f0f2efdaacce0e7b353f6e9671193193c1f64fd2e0da0f6e3075d6ee31bedd7b670d6ca8ec1f9a563300f8db8ece3faee1d1f94867b364e0bf0f2310ac137859e80989729a360d7a7dbbbb2b7e5cede627b296aeaeba9b3fa4b379cb5d4476b403001cd4fbcab99b2b78bb6f5ce05084457c91040b837b7e9a684906b8606d39b35f8f0327720b6e49c095e322978e756466630b1de94325724fd53caba7aed2d9a3dd5bc377910925fd0882e62d30e74e90704c8ef0dd0d3e27db16c3b583b4a3beafef563898e86182169eab7251e077edd5ba525cee6e763360c174677cb34ea125d6cbcda0c424c8b735defec7b86e1c7f6bd53e1787793016b1a22c270b7856da9a3b33d84673a87e0046e910104086b12b581f80c00fc00541190b967151fb4b4e6886c93abc531a38c15852e40f3c3f99c1712bd665b9bb752e81df4ae160251592bce515ec2082a1c8407a81039d656dbdb2d19a696d90fef8b478d0ce2068317ff9db22aab09586b0e88c1e2e32978c0c25f0d4bcd1d7ab4614a6b195cb91642cbc943e18a0f4e849615679e3baac05fa584a9dae72da7f545094f6b80d263719d034bb5a5a1545f3547e44deaf449fe325e3d8deb08ed80f058b3dff6ae85ad46230d8cb82671814f40bd35761a00ced66bebf33b70fe11b1dc20b25b3c285c6f66f5b840c002dbe3b8eb05f7a6a1a0fab6580816150bd8fd8edb96a33d338074d015b42c13a3c240cf19078d3fbfc7f68209564f767dc2eace636cfe4008d1f22d2b2c889ad846dfd32da9f5e2606ee86b54fb39a05695bfacd81abedfa919b600bcaede581c9b49f7387c8e65ea5675440dccb98f136b34fa5661b41730ff89c98d06f8737b64623953ab2bf4e4cec419a8cad2588f084eca713103bb02cb81f268ed343dc7666e78b50c5aace070b80e1fb6bb15329100d0fbc4540bdc0681cf5e8869cc7498291c0ce58eb180b5f94880bd2946322773cb15a006e58cac03bba9eae5ade3ec5363547b59da41b38741a70d94d6d887bca98e7622242c14dbfbd0cb89387f26a407ad27c82e907c3a333c12010681f195e9e6a84478b04bd094e1555b448bbaf6189023710cba82165ecc6303e5f725ca92009237d1ca09fd85d794094790e2e609c045e2db4e209a8210231fc67f9ab2f2d5578563356fbaed603e09d1ac57c919a1f756dc671148c19ea5da30f8503262e256f1ff96594469a08e8fd5cc5d4d96f0bfbf443df9bcb3f69ff36defc58913a1b9dfc55e294c0ff227c4a4cb463acd91261a69d79ef8b48149dbd7a9f243bf44cce3bc3f1e74b67e28a9b49ee7c4599f347a0143b74459544379d3e383cdaac5978c06682c25d260f35be62e25b2ad183df0ca2caee69852bac9a617289b4013d490065a822e83a872cfcb509d52b1172e1925f06274964fbfad5bded804040497db6bd7e2cf975a1676be0f180f041f97e158c14251c3773fa1e8bcb14182e0faa4ed7a3d158dda7de3e83ab3ba291211549361567470d335f0eb4d04dd59811cf6c29c18931ee6d3e52458eeab5f7b58663b05e6d835a240b8eb6e2238d009ba7c67156f9dd2842d36b566139db447c240195273a8834190be92df25ba04f66b32c2af393b1028248bdb367c69ca42c5971bd04ca02a63e3dbb7dd5438d4561086853089e531c01a20f345f7ab27582b0125617df8613c958a4ece6148300281bcdd4ad4cd54832b66270d630fdd388fb33f83302ead1d7567836dd18de928d5f9e7e07d92c4232e6ba669e20f714e27b11a51e2db1368ba5b8c8a4ce41b6277e98e382549a262bf84d4a2bf8b5ba94bcf8342a1a307eb6dab855e9f23859d3d4290ee2f4d97d56aa2a4dc83ec43bf200613270198c924ef62fbbcd3d84d458d9789a0772da808643ee0ebe43590e2be19a850e55a559ea0dfeb6240e679ff3409d49da3855be5618b65c913e96349f54e44864af14e2e9d95d568be58d1441807d45dbc02e5c615c8c66f7176092dff94a1941b833c6ce071ca70c8bdeddc8bf242f1999241f5985248a0bc559db7aa30ea8495f0b58ff1eacc1eb492681dae1c9801f39c8a6bbdcbd6576a009586e9765b40d61d460b594ad94939e89691101511396ac4a7f781fe2bb46b4fff20afe1501244782911fc55012792f4b99c00b46d9b44587f9732e455959cde1967d69aa6b25466ff42949e31ce1149da13555789ea31953dffff28571a748a32486c6ad9d2556199b66c5e522b9d9f78e346028eed29d84fbd0c483333db167f0a5ebd9684c8439208819b29b243f153d0145bd872942cd077533a82ae7af69d0662fa3992b475f7846b52e596ca44721f4b675c0fbfcb093ffeb2a5d1a7bdebe49f57de01849215b0fd6d4d302e0014aad0d80026060292c2f95255eb1024666cfee5e1cedd5ea855ece52b9ce24bcc0bd0617debfb4a5f4c63b7690c002072d3b50c81577b94fbae3c61dc642a445a8d1dcca3446586105f896ae4c39ca70a3455ffa924cd0f365ca4c495a998009628274be236baf7eb12c75657ec1ca30d4f82f95257cb29505aa67ef9f4a3984d38320660bda2b03f3c789d7e100438902953eba0fc441fc548ac34baf9c8366a616bd2a8dc6ad632b7079983d3d532efdcaefda60378819ca7291ebc703765caf63eea88153ebb622319fab9455e2f79fc34788a88ba3cb0f42c95d76ff402e1119a308e8fe442987febdac0562c56c759126a153b6e733a7434490f8243cd38e11282247d58156af416c6de81cb15d2b8e4309d6b84d945b1c31274009a64dd8282be032ee49569b20a703404845ea6f91a19372c2c4eea12cc6f7d4e2c364901c583c3f2cd935eeb09f02f4bd04b3e9551ee257bb20ce3956b71146a539041f03c6c58e8bb47e5f9f4f43c8772702074ef9e6cfea60ef3112b6893c58b015c4beb79b7d8e2cca05fc97fed126fc28e11fb2a692c10861a4409d6a733098310f04829dae620ea37e64c01e823bab9ffa8b78622402ddd6217d18362eaf670238c2c0d229acc340de8d1d2ca352d88ecb576cf3e8382f72dd699ba3574723e0d18e0325754b15cbb6ba0baeaca33cc29e30507d03f3887f26d8b24225761960a51bc8281453253a1ca8fa75eb07be7f2e4fea0f9135147b7767b2934425ceb35181ace1ed88bdba4e0581032ae60d626af9c3cdaa39aea9c0a70c5ed7343cff7033523038a906e25539fddad011d4d06b093a613f808fee6b3b4804cd8086e1a45163bb84e516e5720f48a11a22fe97a8aef03f38b88064f18b34237273d9397f8f432e33187e62c068af7a35b6c109e221305231a325dba6489ebb36eca130f6c070b758e37a561ca125b05c310463a4f50e1962759905a4035a9f31d19cbddc7ecb734be4ec2a897641a541891f227202a5e979899bd6350ea97836eb526231f318ca9d3cd8eb78129d752be5f31c5d7b3458ceec3977db2d793d4081538bb9569764b7116384e31eba692d5e7f5faf071dfa0af256fc513ac56bd28c2b1a944b67b56a1e3473e0f5fd605528cd818715070fa7831e75c6e544b0d6c2c8b90b7b3ee522a4cefbd1eb4e841e81966c30cf0c88319a7165bf58d90975eb31c48055f0f425a1b3d024ca29f984af8546230fa9f89a20654aadae0ff997054e042c15728a6a2a00e0f673e8335cdfb040499b87ff8e9837f810d3d6085aa83611d05eec1cbc4b0b47a3b6f0ad11b9a0943b86b10883b4ed2659f43b13421565f72015bfccd9cf5a1d3ca137c43fc926439395a83fd9b51fcbe313e9049c7b4509605c129461c962cec9d7f9bf7dee7e6695cd75954f14b737dbeda412980cac25d411d5a5c7da81bdd5cba3648f2d6250d9c76da6a1e30003bc908338fa2e909b401e5ac70d2ed82b7898807968e6f985f9cb84626a44242a162417e8446c5097c904370a3971353bbc7ab4717dbc452660c5239ba7c8ad4f295e41b106efa8f3227dfdd2f3c4aec9fbcaa5ddfbbc8aa0dd9560aef413c2748e28a13e40c3ae665774b45efd3654c96e2101666dc85d8341501c5719ad29a393669816a2acba9aa1882490a970692fff683293b748e212ea6116321d798ca4784fa2d0d40f97ddc8aa1d22cd20e11d050874e4444342e0fa4bb1b624463134c2ccdec8348591074728da088f00d79765e1eb9aa3b3c3f41ea1b38f1cdaf17309fb8aea391047b5ae7a122c809f1d603e78be3d0cbceb368811c2b5f0010d51621738badbbc08b1d9c74d7a4f6fba0ee63de8f0324bc2331eb147506b77cf5c13af2125ec676bb5c7d68d24e18226372e5c601a1cbbd3aaad3319475aa764431c0ec3f9c3e03b2289bf501cfebb028352f13a06fac4affd1c51a2b3098547278105e2eef35fe89060c542c4743f71ee66d8dd8d24dcb157d8b1ae4727a1ce7cd09844f9da0249c2ef9e27a10b7dd8c64c8daf8b98a691c592d3b03d98a35dc0e14568c24ecebd8976b5ec4731b3a55cc837cb1cfe4c3e550a080b957914741329206d912ee54909840cea93e6b990bee1a5960f2f920c83e63c694d2c5df53eb001cba457c85b54e214cd8612ff6d6434673ea8097ba7a44b79831ef45cd41f19d0bb128f78ecfa0b45712e68ce90ecba60d800eb9debb2404c579d86f95081830872890ff4e871e490901ef45231ee9651cbc4f5faa787365daca9bf168688f8007c8caaa40cd9d8b2a8588a49f189acef093c5cd7e98322666617a54a3b35469abdd4ad3a1078eaebbb4224bb9ab35800bc2f5af33feb2394bf870f5ec5d56dd45f101ca3843f79a6f3e298cd285b708ea4aba51c1049d01bdb4a50d1c8c481b363f647a0a6bb192ffd982a59932a209a43f3ad12e92e4d2b6006bc080c97a4cdb0a5fbf254e3e6c5d2e5e6e904ef6a8551dfe81a557287074e102bc09e578bf4ed478c59de07324baf88c60f925576c3894dca88de96ef03532a21ddb86ca3bf88ed809e9d51221da309cb2eecf7cef91194bd46fb0808d144a2e606a41f12f1aff2737586503961d6cecf490dd15f50af18834a2832336a8745d55eb8562333519a0699b8732b45cbb1d7dc926e59fd3cef2883c52d14049465c282e49ef651ef2122df77608438199ded4d02384384e048ff19df41ebecc342758fabf78619d7c506462f5801e2fc4e64ee259c7eac72a98b143ef06fe9062da4f9ed964473200a8e9b5b21456f5a70da45d4f1260648d2fd168c461145be6103297aa765a1a747916ed04092df6f59742a51851b999166775b10ed7a1471830624c88d164e971a75dcbc1d09bab185d0a2a2ce3765458a6e6fe1742b5150b8991d2976634bd12f4715972c142e7ff96d2d14ca5cfdd36850bf049f46d90e6c3b7106cc5c61db8acd2cd7bedda75dbb6e414975e03ac027701ec6fb4db9ba0a07c68d5e6022e27373bde5ac2b22d05ee31ff7f420e7c1752e075d1d04e230102d3b524c97e97510405741d0b3dff500212c9d06da7c53ff9c46b6799f9c34fb0da0b077a6f705d603af16db7904ac989e3adb7ccb0a0588fd993d09b014a46e7ccfada5726baadb75ced71b94c3dabe2ca59be6b1b6284f64a30f6130f1a4862e1bdef44e9971dd5be11d1aa807f45bec755dc8a77a1fe74aa5a2048a8cc2669c3cc6e2553dc6218beb2c16a72d438787c8cfaf69b6f5103d00f473cb7a34c5b033e8821da41395db2bfd0fd94de607b158cd9716ca6cca6642b0b4feda61871dce070cc63f88b39d217c35230afd874413e2b54490e4bc8ada683a1a79625816a22d11c4a233f66e42b3e54f7ef80a61152b5d0b5a683e4f3beb80b3d9b6edbd67335874f7b47383c4a213303788dea655ae39f7338ad7b83d9c013556fc00ab774253dff1acc2df31af29020327bb6de424d339b541d898aa7356dd846e23b8dd08ce9f3a47ee4d4ed7c8991789fc2f66450c3ceb64aca724c5b64931715e6bd59b54a39961cc8f8b14f95715663ac711a0c05ab738d2e8a8e82b87ef97e7fa9dbc3904744542625fab8ea78b156b3fe9de561ac16f968c52a5469e2e22430f6dae9abb92be2873a5e13d50404552278589d35a3c901ed1ef85a0c152c8b991391f977bf5ee4a6a2b3e0b1713baef40a56f5ad212ac7a701b98acf3975eff207d89477f50b7422608a9740564df8690043500ee8383b774c3ffdf7e25189cfc989d0e000266fbe57d8b1fbffc2a129dbafcb4195accb62ce540cbb7fd581d6165aebaffddbc5e80e96e7e64fbf7ebfc0f2ee726a6b8d284bbcbd26b365487f4cf1d05e4427260dbbd32b51e70481334a06dc94a0466fd12606b4aad972b35c55baa52b760a8b064dd41fa49d4f242e78fed6d1405ce45722569bd8f3cb08023b0f866e93ee01d04892b22e27516695b582ed19e1d804c82fb2ca6c31682fdbb54a858bea83231167750dae5f5fd0e977be879774b62d49e9bce2df52954b88c19bc075bd20a8ead98259d8f59c8838735afe4de3eb93a9e7fdeed425ba630cf91facd5ca6f6a7e01f92aca8a03f3ae9bfc06bda15fd370b963d9f8c107439021555ddbbf0b48b09d328388a85b6639181bdd310b95c1a6cfbaded746baac56d413a436ce40a0d741f560eadac3a6b0fee2b986931049b1b5f6605f91009885f0c92bcecb08d9fbb7d2e0a43d9dd19be1a42bb659d63b9d49c12273924067a6c3811916d323ade3cb2002d4f66a754dd3f261c10b110043d1d60f53a3724b07ffc65b514e59a54795f67b1d17e28049b306d007ce27f240a081f6e5ba1020986dd0b2a06d0f1d7086b73d9d81663b306dbf2148188803cbd51d8cd9c5361b417c0b4f2bfed1d00034df3a37b804da007cbc4cee6830bddc9fff0c2f8a0707faf0ada1e74aa7b19d9c3969bf5650b47631eb582edf67e79c0b4f7dde76a1be1c92a5f442b92f9a20a25a5d52bbede8820db2cf4f398be970b8d39a8b97f1b101a049409d01b3a71cf346cfef91008437504ab78a233f81785474025cd81dfeb1137cfedbce7677597a51954197d18a6921cd664572ee25d32020c2b07c67a0d0b6fb87fbc0402ed0b0470bf600f57c01ca388bbc0685a19cb472022def02f5f03fe66a5f51269b7c3c56ef08315e7738017f42991d66efb39102e1b74e765aab836117aab117c42bb172db312a64076ecd1406362292e6e97cc0636dfefbe25ec05e5af45084785db6a0f7b9b5cc758770cce367ee76f7d9e1a4ddd6c088c1f3b208828a5997c7db1808d7b3a1397097a47f4d44009f3bff006de961460f112e0d551002cbc418b108beb8561b0b9488f435742c6aa04147b6d8ef99cfcb5566ee442e1937df465de269c18372d6856bfc52b29eb3acb14938174481c3382006fa58184e2edc1b790addf92d3d3ceed06b98cedc398b43f0932376fe475ad03bbdb443bd530dd8f3b715dc13cc35161b04f572c0b9c65a64cd1a514a43ed5c507bab87afd56c8c172a29d99477c3f2ea457f7cb68f70c1ffe5df6ec0a6fc4312d819ec7d1220f084b471e99ff422ee02cff3e0403303279b832749dfd62161f7af73410a2ef2409d54baca169ead532c631ce21b03fe12164ae4b5510819cf011a25dcb395cb1a44ac0029ab5ee546aeae6c45c556f3ef473a8a13709f981f969dd42d3827bc815099dda3c15282a2a71812b031ba3aabebc7a2fb7442a8604eea8b5b8e1a7c50347a23252af7e557cecb9cf492821b0c3c28e3799952c5c91b3ff7bfc3e5357e8fcc44785bdd95a8fc975674b10e51990ed8f37fb9e2ebe08147d8f2eb0e74ed796e8482ee9e7490d371c4918e851f4f7476babf5d4f3c646b09376035ffa9ae1bcf392874a8815b46dd746ef8721527612f2b11a38e43f4120d6344d3a8ea05aeb026f5a20c74410f64b3505d1d62fc73d2396de316ae4a6227cc5f4f76bbb5a9e46eec050efb2280071c8a5ca6396e02510e0fb151e0b2f4d439b903a610387b393e316c07e8d734c70f5dd372ee9f58e9ab8cf186ef360049d82c1dcf21be27cfb8c7865d785a1f0de5fb4bde5213eec76f30f936850b9c1e0d752b7f5f66bfc8290d47f02689e8f0a5be6f85ae2c657bf80c7402c3a554c9f4a93320794255e293801d7b8ded6c4e6017b873340efaab0f7ad56bc94891c6f3f412672dcf69314651a503c069defded9738ff83d866947c5ae4c4fe1080548c2fdd6a51118eb9e84ce0010dec0b0a817567a7765f9b4f28e95e40a346a5be11a7e1f80a067f22de266f9d3252030d5c6f8a05f7c5187d97793a2469f1d467d6a1a5a4bdc2f5065646c6f10dd645c098fa4ddacdc0755bdb07d0c412f5df7c6621190f23f04a3734d565871239525e9220f8f6c879711d815ce7c8a8e40dff69ef62b96b347ddda1195b6fb9854015b7aa830af36947f5e60ed896f59fce0b117b7e75b58c83d41b0844addce2a3a1e6595056e4d99e68afd5abc468024f372fd5b123a3d13ca9363410830ad5e89979930f159a9a58b1d96687ecfcfe74f328cb29003a444708dac83575f158521aaaa2e161d7508248a40d5a37464bf5ee1ecbe1ab9f8aeb06e549c875b7d826fab3b4937e81da398c7e84a6c563c6cf280c0637845cd77317176e84218dc166e10aae6920d1620e09a0e88fb68e7d5ea87073bac93bb1d3b8f1fd200b100c4bc43f78ae9aef0d54780ba7a87130364053c6b993357d6842ef9fba681e83dc1fbea5a49736f9cd7de205127b2edc7e2980a79eb67b21dd82b91dc80f4742e911df89cb7a3cbdf0a476d9c01f4212f9b453cc2f774da0c0ed8fcaf1a2c117197696a4e601a7ddc31a74889e04f777ffef4e730738a7361c871ad677141974e005a9ee09886c02d449b28c7ea26689c9e55948334ed7eec32f590afab481b282473c58789d1a333e343146e0a5d6669747c2d40841f6a1812691002d904f74ad7871c1c1e7ef481c84798998178c109a4e3a4b88e23524abf37138696cc11f8f84f6100f7f9b4fac3f01e087f912b9757275e2e62927b676bc66d165b219347db9b9e872fad2a1658c1b42cd7ab9ed12f95600c4d69047ea80ff79b8c51ec76ee8afabf31fd03803eb81ef86eb8c2adcdfd26f271a414e7d7af600a4a77ab75936f72fa8bf735f7b847943ea5162371c67c55bcab0f2f45551970d5a553498d892f733b52ade5d1a204b01dda43a4735a04b9c7c9ade543409e2364774172f8b0c64ce50f0c778f6e90570ebeb1cfde1e61e7d4fa6030a42f3eeeb5f22442f8542eae3407a6d6a5a3461b942755705419d7cd7217bc8106570b56278c00e04b598b5cb0019386214cb792daaac06fbdf67411022cd44b83179fb2e077173f300bf14ba71c05c5f5c12d794b598fceab411c1e9d6000b85d072fe453e4ff520cd5702861b1afd1ca35e4acc209653b2b7fae3712dbf8c16853a3821a4fa1fba1089bd9159758cfafc168252b8471cb0da8a12af9af69fa1ba6da1126c0d14f9a020d6f05b28de356441c9e2d3319818fffa48bb5efd75c2dc508b8d39fe946e8fdb83b37dbe6eccd3f92146a304ac63129690e22178e5f1bb24493cf15778ef7c938d55a777cead4c1cd579753d0252e85a2d6056ef0cfd95b1900ab86b447214b7c55bcdc35e4da8b36bc3f0ddadbca0bfe0cd2138a422cca0cdc78ced35c9aad0b109394619ff2c799bcd8364a81e9f746af19579e1fa801d1a1343b6f9ed172e23269d54bcbaf61115073defe5f83000fcb96b9a5ef59b86bba2bbc7283140c63dbe24ca8f1e3ce418f7be8e6f0a0ddf3d15cff05e16a3989400c9289f468af2a131b660b6210559ef93494dda87912640c14486465357c6b21857b1f44cb3e430923e5d6992822b2a9ae85b22d2f571e00589b369915515c4964ec8d2c2d07d5a9a8cf8a0d9476bd8892594cad064390e92d9f8a6ad4601e3914698360107150a2e49e6d59ab05d8fe2394f7fa8224260012aad497918bf96e2a474a580b78cf84a803555bb597b06994f520c3a21eb64c874a1b510e200346a8807f86a5e85503139d6d938fe36575c98a264492ae2caf7f01dfd9a112e4a8c5549be02e9739d192a4e97f6c1c044e12843e0d5a2090ba9a0ea11192324c77fa04b8f9c6ad75b802461d4e34ce88c4150f27401a4c4801e9ec3f8d1aab3860ee462522c1dc950b95ea14c0da54b1bf54ed23af400da20f8db364a3726d44d1fbbf9fb490b677b7bdf7de52269902cd0cdf0c130d47848104982c59c8e82ab068114506133040034a0bbe2c6e7c01c6036afc10430d0d1d9210c2080a0c8ae042046658f1050f44844f4a5466bc005383fb29490d0bb0c6e3b1397d6bd10bfb19666178342206b7e318d665e98cc79f92fc80e9121aa594f2f8d0cf3c3d3e655815eea7244c70b6b34ad329bd10f753922578c3fd94c4059ccb1a44545454d4155c999cf1e575ed3ae8c2e6719c0fcbf406f5e0df5c20f38dbf29017f84504a394bbf67c0f42909e929a51b98edf25452e6d1bf1986bbc0464a4e28e125044e5b0c31c5154630e410c4194e96380a230698ebd8e07e421206dba8b17361a6ca105fd4a0929278e1a246d8c206173cc9b0822c59d0fa1b034f2e7c7952b2c6b4c1f37b667ba6673f1e9b9f5f787a61ad6b0c82611f1e8eec31630b8fedb04832866d6cad4e8973050ecc0516aa1a017609f6b187c115fdec638f8e8e4240cb8da5abdb7bc891767b7fc256dc4f485680392892709cb7d53bab78c273ffd14970b21cee272435eac56bd71b4739d2862eda3160228b0d59b62841e14403c060e2e405455491860b6855061d17b1f68b4408ece17e423245c6b957d143d213121d927480fba9053258c4fdd40219b0dc509405811faee0d05910f0818c978d410fabffab56ff8e5cdfc3a54285a04b18f5d48212ce303c9f42d00567190e9c79f09c65aa54ea2075ec1fc4b1833edb557ebd057606f7d3d1173ca3c05a7f8f73cc1c33c9348ff96940e1aea551c3d9a5c0fe20ee5a1a486097c2a19ac77c7f3af3241df3ef8ee50ff7fb6716ae2c08f8b0a456c6091ef2314213ab2002a6a202b82ba475fc9d8c6d9c2713fe313f17e1799b49f338325f08883a9630bde3efdebb1a96de29a677acc0fdf4020dd8d9984c34e69f6d1e4bfc59d6937ada3bb8efde7f32d199101af33a993699aca7e7bb4c1d47d22ee7bbd7b1d9c39f023d6b9aff68ad1a322803bb0e1ea23f718b246c983a3dea6a284343992462f0caf3c8c6df3d09e4c457b0f75d0da460eebb0769e8914e45573fc5e5fadf6fefea3e755f43b8ff9ee32e50f72e0ee9de738014db5da0d0cbeeb9a76209dcedfee28cf409c8fde83bbe065d70fdad0656e00e70d7da10028334e4c8c6e3f640f2c5f1f28662908f05811fa0dcf10271efbf7d382fd076bd06b0bde700b400b5cca3c6b2ad20ca0c52b400031830685be0eea1b34a6b160c91c30c56ae98218b2d68fdad01907ec3c02e2bcbf31286fd8765bd7c5dc1f4d51788e3fec60209173c5f88cf68cd9f480452184ac2ae43a61e0581738893844b47474747b4285d231305ce1d45e6069c3bcc18083c692221d0431309811e747c47f6c19ea70cbd450b1decef52581f204613d387c013285e36deee130e8772377b5d5910f8a18997edcda5343c05d8e97555a1e2faaf21930957ef1a991b708dc26e4fb9cf21a62bb0dc6fdc036d5fbde4c48ac515f794724fbf9b1b02d6ca7595eb8c74dc7795db6a6498e0ae75dbb2e3210e0550ac606609ea6939c942821e28dc1d86e9bb539c2965740982cd1cc0e66ed7d07778cf711cc5dce47ed6ca711cc771dc76432feb7b16dbb87ed8b0dab4460e48d5556053b86b6bd08073d766238dada1f4c21a2db800c3a2861a4a302c3507774d8d2d7806774d0d287096b5a0d63cb21e2b5e14f58a9e2c464960518230ae5001420c2ecca8e20927238a500285a905e2162a2c7ab27861096bab4458130154f57ac3195f024c514c1105c6941d8090800896f890e4021a9cd184152f8a7a454f169d349c90f400c5175bf800802db8c0610622d2b0010ca70d09d18a9e2ca5103118c1a466040d656896ce1a8c19a468a10224969260a0d56f27b87e6523085cabc0f54b2af31d8d7bb27821ee9a1a42e03ce23c6e434059ef471c1e947cfc1167a4b31ffa6ad8f0c28f90aef9988d578d19948c238fcc1371d7d44882b30caa2231b9cf3e447a7cf8cca3f56f648f8ca76716db353668c02cdcb5357ac061b430abb4fa38df3c26acece1f172cae82cf4d89cb2315d66f3e8e8e80809ad7e88eb8f3e6b5a6d2cb6710ee9a54d1288b08d6d70d7c680c115776d8c0c7086a180db2858bd3f6284e9bc40f4bdffa175fe1652ea98c3dc77f3cd538808730f9279fb0e0d297c8c15f8698005fb8f34a8617f1c87617f908a0aa038cf4f9142147317a802993fea831be90a7d05f6fb56c0f7dcfff814876cdbcf07a2ef7d27fea8a17575e28f8ee3b8edb99b81e86f0f447ffb29d2df48a0fa35f4d9a4f94f119c1c18b069d0040b00774dcc170cae1a36829eeff052f0c97d47e6116f95cec4d9277eb7fbed957aa0efbd4f7deffd77bdb2bb3905bc3d779b08cefd4123f6b729a73b1cadaaa7c04e3c4b98789e11460c17314b675cc12038c30d0469fe2327ce478cb287c517bf6ffc7803c4fa16c82255ff91763e4b0a667de8e40c1aa8194b989a918429e5c21687a8deaa9083c1b7cf890a683d8bf51f9947fc7ddfea1ec008832cfbf659ffb15e4566d7f71fa0e6572c92f52d2660e29aff71d67f5f39b104d5b79e45e61430eb39b184efadebb38759aecf16bbeeeb0046d8f576f5f65b478cf0ea762007bbee0b7ca0d5bb1e5cbdeb57ab77dd7275730aa5ebe61470eb5bcffa1fca22b3eb39d66fa290896bbe45e6d6abae03aad8d65540cdb32e50cdaf2e50e8228346cc7a4be6d60d1a71cdfdc2efbf2173c5e3539184f9ac77714878ab97e2fded5937dfb8ede5f8d5cbd196606f9ed8e667bec5126c7ec686cc4578c63eeb411649f1cc835bf891333fc51272eb59286017a5788a2564fbad67516c73330b78e6b7dfc4121ccffc5782fdd675ddbcfd10c5339f2dcdcd4678e6d2fc46f33ffe91342cd665fdf62cd20155ec10657d8a1c9a98f5a5c0be4898b8f513b7de5ef1fdbe86ccb73fdfde9cc22010f85e0ab73c3162983038c512c0f73c126c91aaf9de1949b0f7e08857ef22730ad8e5c2f6db77d8fcc862bdfdd778b3c5f66bde866c2f6b6eb698f53324ebdb67afafa9b9d9c3ac3bf32fb23d3673b387edcde1affe5d24f734640e1a71ebc357912a4cdcfa2a0e71dcfa299230a4f5decde0b75aa46a8a07306a918e5b374fdc7ad5afc899b7a4eb59641e31ebe9ea81ecbb7e65dff5f65db7bd64fdea672eeb7f688b74cc2273f8ddbb08c4b1ea5b421abf5a0fc47afbadeb802df63584f5f659577c2bfe4afc1f575d20f0677883460c5e0f679e9cc28fed08078d5885398406cf1f7df503989b7428761aa1dff735a43ba8afe0fa1bae2d9b78233d85bf8ec34ee6108f4eebc6854de68ab7e964b84759016173a872918615dc52dcd7852edf917388e975d91c8ed371a61f529c43ecd87ae915bb7c47c5dd3b2c60e97d0da15fbfde5c31bd4ec5ce37c2a917380cb67f1ce312e86e9c71d6dfea0c371fc0ee1db552efe18efb2790918979f8e79ee490f70effdcdffdf5765fcfa73864d6dc884eeac21635260c4ec1cb0ed777153a0ce44f8073ce9965988897dbc67173ce39a7d75e6e410ec429905f2ff4f207d093b0fedc11de1a0a0ae7b9849b6cb734c9608f3654c73df9fec7fbbbedb1ece1ce67193dd60b7578e66aa83a191fe256914045355d3833db3c623015be38bd045dd775ddf7f4f4c0783ce63e5e7a2a7bcf2249a062c1ffbc6e76b37b5537bb17bb0f27fd711599c75c62199ed7480553647e0cb3b3d6c075a4155ab0749dd701d1407bc9eda57adf756f5d388f61ebf33f497a1acdcc671d2ce3f1cf5e7d42f3ac1992042af64bd9bcbf8cce6adedfd2998bf533df22ab975df729b2c7cbee6dc8d263ddd790edb1c6a95246672ed6fb977446f3fe2c72f4b27b4bfe78d9fd8af4e165f72ab288975df72119012fbb0749147aa77b1ad2f358d77426c463dd8ece71cacb41168877bbebb57ce3b26ddbb64308ba9b723c3a5e22a0a7c78ba1063bddb110d1e3655f29613cb89da08680aa4780fd3d5471dff672deec7dbe1b4efdbcaf21e0cf9f37bf7ca8e2edb3bf1106ef6b48f820f8e1355271500f0edf08839ee88950b8274ea542d20339107c2e77cd23c1cef3bef3ae90eac3cbe6b8df38ecde1bae5eb193af21f5e8e8e8683ba235ec77928e8dc459d7c842703b0f767e500feeeefee91dd756b76db311803105c1f0b6bd97fda157ab1076fe967570bfcec86d7111d01f29ad25f62a7d2588bee20a85f498a007572d08681e9324ea9d9979baa6e3b308786cf68cf912464c0a50c086b97ca63349a0627d56dd089b61987eae11c7fbede97feaa6bee216bfd40d0ab1f779a537dd07b04bb0e2573c8bf86cd668ecfb84f8f01de04763dfdf80bfcfb31e9349e7f83eebc09d6158f5b9d4b199e7fbb6effb9e041d5a1441d1fbbe39bfefdb3eef9e6056f99aa6804e4eec7d15ca74ea3a16479240c576ef31d83c97e00dcff7ffbc89dfef37b2829f90234096832f8a77a8a2e06f1bcb4a36e254d0119dcd9ac7becfdef72ee5fbe67fdfa3f0fdf77ddf5087c5dffe13fffb59f31de17fb386bf70ce1bd45058fc167f88158364c5a9effbaee0efbfeffb867d46df4cc1809638fbe0fe9fe6c181de99df2b1c2cc3acef7f2aaabedf1b7558e4c4ee75ad2755440e2cc009ab141b8475051c84358a9cb066f9b06221c30ac50deb131d8455051616d62b38c2ea846d2f3d08ab150084f5c99661adc5c2da4400c2cac407614d816d2f75c25a6527ac5404105614e408eb12b2b04e0121ac4a8410d6240610562478c22a4547588fd8310b6f1c50c54e289c3f471176cec26a444f588b2040589d788495881e611dc227ece6419fc31e7dd234e6336c5811c21a6584b042b10508ab1076fe84dd3c7e0af033c28f083e3d7810a067b64307cf004200419643003b3a1f04205602c0031cb00e2ef9391c6c80f3bab931dad4fcfcfcfcd0b87e7e3eaffbf9f9e1b69f4a7d92409f5e2760c3c01a965ae79cb37ed3c6a7313a76992e63f18ca2b317fd7e2f74f6a2f7b580f9db9b50bf2f0bfdf5b7cb429422fd757b16e8376d7ed38410a1311a130014f6719e35030461f3ace124512988446098b363fe494c93c9941f46bde3ffe3df647397c13ebf3f8c0f4f324881fb09f7930c4a185c814d67371b6cdfcf013aab7486f3fdb346670ece52df9f029d01e0fbe7129de57cff9c42672ffbabef4781ceeef7cf243a13bfc9a7f9ee3f81ce66be3df866dd78d8f7af406736df1d7c8f24ec7ef002789daf213bb848b00e1ec7b7480f2e52cc832f5f45de8b24809daff990242f128efbe47f24002ed24ecdebbc47e65ca412001f80efc8d745bae4c39e2337b8482fee298973910010808ffd0d89b4c1739f339f26e7719ebb4a3a340ede92483957e9031a92ea7370fef52089847395686848dee35c2515ed7f838b74f3f66f9048e0eb69de4522bd687e835f9148345789d290c6b71bfcea53ab077f83abb4b39148abab24020d29fc1cf02ae1fceb2ab96848dbbf7e8644fa400057e9060de97b9cdfb94a1e0d89feeb2b895473955a34a49ab73a5769d290687e83ffe02a7134a4155200aed28b86c4fd2b76956034a41b6fdf8317cbabb4a221899ff300b84a3d34a4ee71de83ab94a221cdfc06cf22913a78244846341c57090034a4faafbf57294643b2797b91ee2b4d5aea9d4442826444835da5116848f673723e7591681ec9f548338fc4fad67770956634a4d4e3dc8bc43dd2f648f5919ebc4a4e4362fd06ff2492ffeb22e55c24f091528ff43d52f7de2b4ddaeb3920915cbfc145529a349c8b641f69f548aa470a5ffcd745ba79a41b8f343e52cddbfc0fbd216f90258df58f24111aebb72157a0b1fe1a7232d1583f0de92267c81368acbf45ce231aeb6791b389c6fa2db9227b68ac5f45a24063fd22399368ac3f24a7138df583648afca1b1fe8f4c81c6fa3d722ed1587f47ce2934d6cf914f63fd1b59490ed018131aeb7772d668ac7f92404f3138e1dc4f4bc2e0218a81e68f782cda991e17e59851f5f967f842a915adffc3c86a352790d79e03f22a381b904f19c3d403b914570ac89dac07e4508c743703799311faf5d29b339033ad6eeefc0accc7b0dedf9bf9ee2b65b15cf7b6ae77245eee9b86a926ceebc29aa25faad3c1501fb78529afabdfa7bab616a894d7d5a609e59489db421ddcd4d4d4d4348f9ae6d13c9a47f3a8b5cca313bcec69913916ce93c9643299ecc1ff3c8fb3db58c7d0997d7b1d8b7dd57df1e631b429cfdef65847dfc7d8ec4ccee44ccee44cce1446e53ca0c0f6a727b3731348f3e8dee1563b40f31b13e99dd94fb8653d9b4bb667530b8d51ff118b9d4b3d63496364c57389ce38d031fa6196c22c85119ad87f2e4d2d7446a463f4c7d15afa4e4e197a87d2528ccd530bd4a45cf4c4e00c89348fa677d6bf71346ca663ba700203d56f016d3f73c4bd2b49f73449e1d72c11df6649f5230dabbfd165ecdf00b1fef5fe148ace5c8bc7fc3fccd835d7a245cb8b9c37e4bc418efe36e46c3299cc255a582495c24b7f4b522cf40aadd12a249d42a550270ac5b5d0cf4e8fb4607f7ae447584747c79b9a74bcc99bba77a61f1df909fe9e67ed38d2d6527566d6c173fe7ca1e9649b3393783e54eff8773797d869d34c724aa1fc6993bfd399e465e94ebcf4d9c44b17ca5ee90f6492302794336cfd3c93d6b05f7f0dbb0025dbb86e980acd1a60fa4f4bb8e07e5a2205ceb4e969c913a64dbe034af3a0f566aaa038c2f48b348ff932ace3507a6726d1a3e6d1988236357e9ecc8ff8cfcf548b93ef009a976ae9a28a142e6d4c89aad2a5e6e5ca172c61a4100344c700513265ca90c1f49d063653aac5a1f40ea594524a6b60f3e49204d39f5c645efa8cc7673e1ea3efc363330478ac8897f49d3c0d9b6792ab4129fde944674df3eca439cdeb5a7a873e7d57c3769fdd494667ddbea96b691edded9ebe3bd199cc63f4c19b3d3b36f5ae1309b99b82070877f32360f4e1a5156a2f7dbca44fc22c72463df270007bfbfadb91f7c04f3d287ef8a2ea57acb7cf9af9d6cfb89ec6fdc268c87797cbdad0336a4d3fc2ad5395d33668a23ba535e986e65f035af84a5234fafd5fe9f54b54c43df72bfa5eb72ffadefb7e1caf1efda2efb7d1df5fc9a415715fbbf7e8f7bbeafb1779cffdd67d51eae92b49d9d6aa7aef5fb43dc7fabefb22b0658bc007554a5234f122c9515d2439a92ffabe75954c1ac8a2cfd52fda7ef5444a268da808fcee95a468f6ae5497e8ebdebd2fa25f3fe986268617bc9dfabe12156dbfa5beeb3d51117def8bbaafde1d278da8a8e32e6cbbb588fa7dd7c19a1d0ac04a4748baa1d14b249453d44d41a39748898a463fa9a66e485665926e68f48990e42849fd56e9252a12bfe691ac926e6837ae965581ac7085e3aa69591538b3628d352d97558134ac19578dcbb654e0b77d11cd53a19c1a574bf545e1db2752924a7995e6b72fe2c2d78d1fb71fc74b54e4a55e372e5151aa7abdc6120da7c6d5b220919214ed7591e494295386766373898a525fe36a5915f875db17854f9fa8c8fb1a57cbaac08f7e51f8dd131555ceaa9ea868f560f745e17f3517e63adcba8ef9aefbaec35dad8bc3baa3bde3eae2a8ae4bbcb02f0aef83d7a66e7f37f46e751df3bbebb90e7fa222ee86ae63fe5654afe73ae6d35b5d877f7fd16b7e58c005285923fd42df0b792fd4bd10f742db0bd5173ac2c191d0910e0afb1fe91aa6ffc348bf91bef9bf37f2dd8ce3bd11efe6b17b23ddcd2eee8d7037dbed8d6c3787f58dd436e24fbdddaf0a35785e9897930bb08fd4f7fec8f6df1fa10ffefc23e2abfe885d3debc84ceb5d7fa486e66d8edc18ffe608ce0bcd2b9473e4f51b080901990f44e8f542e30bd5bc50eb85562f443f7c12be27619629335f68ce9b85e66b839b715e37ff7873f38df1661c1a9b9b6b686e1e5bae9b675a37bb56ac9bedea661baa6e16c39b43fa2adc60f0e614bd59851bfcdddc359c55b8c1decddd14b813ca51e106d79bbb9b02d3cf431ca657851aec178633eb0ba0cf2f157e2b8f72422bac420dde8ccc0ba35c97ba3829f0bba3a8f22c6de12e45d35d6ffbfed7766bfd268502767d234375eb38cf4b7daaef0fc150257ebf65bd11d7f7bb54b8e5fa210ecffc500d165a619bef1f434cf34654a8d8e6872aaef92117162a007e0db5f0f8468652f8c61b5181c3af1f727c6364c8620edec8908737789c1f1ab110c539468654d8880a8e73aecfde2129597b673e0eb9f5cefc17f9dd905eefccbf41765cd83b606aa5122dab5543e3ea9d991b63efd8e0f4ceeb66030e7a67be93461c4c3a660c301c37060705d3283041c0bef4502d5f605f7a1a8a0b133ee400c58b207630726a42468b367a288152134a2d28bd4082a1c69702ae0a32524f4ac6780d994eaf21ee5eac5ff762fb8db0119ed708839452a65a2b933937dfae276581b2d5ebcdc78f102f67185e0f180a830f4a15831e304e8850aa1880214295825a471e99c705b705ccfd997eae9f3d6fcf3dc8715c8ddbb6ad31385bfc414456524a898cdb666b6aab24f51ccf09a402c54f3cd0fd875b2c528f8e8acca3235af75ea46bb4ee0aa1b1fe1ff7892bd49312a7035499c14b0f486cf832c427c6089aa02081d19446920d34e9069a2e605cb89f94ac0083b89f94d4b838617fef62b387e7143ae3666d62e1382d9e14d5b43905853f9a4e341468cca3b39156492234c602576e64d358bd2f132a0bde575ad368443caefbad7e778bb8afdb6fef9144514c98632011c511cdfbfa4445dc77efdd22eebbfad599e8ac89ceeabb0eaa258af4262f1d0a9e7fd43466c2f6dc6fcfbd4ca8cf11791a73676ac2fed973c2dd41d166e4ce8d017acd633aad1f5c35e1135a3ce1c7676d4e994e136a8c1f4d2c5ac2447969da341664da37a281afbaaffae298d9542f11ef8639b29349129e4b2610819f7ad69b40b4faf0b937227402ebbb3f817bf17f3cf11ea4a411faf637fb2d9e10fef646848e4c2c24c480a6a99e014d6bbdd0092f13bed47fdf34d5092f13543ff33397055aeb06712634369f455af2e5cfbd110da424039a9644f5df83533421f5dfd313c413c01356d793686cbeeabee88b4f0af1a5ec4c502f7a897877a4b1f9dd2d39f2e597888cc6660f9e6f442b5a1951efd400db61b030b5c2e89462390df46020fa210dbdf7fa39a8077bff3de8916125c3d6cdc38da7a80015667735d0b3b9bf00d666c28ecd642db3e9c2e610cf7a653d5e4e1e287e08759b39fa9d0810f4497a94deecd87f0badcfdf9cd23c8676cecd0b39f14ba5523345a9f03b04b67b5debd65c539f5cc7040457fe63455560b377e50627ac9ce0c97ae2908abddea9a56eb0b936c184095250c5e64ac5660f054b4cb1d963c2c4664f099bbd2490907284cdd5089b6b114e44d8ec0d11c5660f8a10367b41e0607305e204367b4d573ec082fb3f1083cc2736d71f4ae083139b2ba63df04077e0117f0485d89dcc23767777fa1b2954847d368f8e01e8d0a143878e0e2ea943870e1dd4e708f34e8f09b0890d4bf187b7794fda0070f68fda8e73891b7bd9edd387789ed84180e7854d28e09cee94d6ba6d1cd989411c0ff54e13e9bcb049ef0b9b4c89411c13e99d4e8160188a4daac4208e757aa75bb55a59cb62b55a3333ae2669c4208ebd76cdd4d4d4d488352198aaa9f9bc9a9a9a1a9f39aa6c843b1940b0bbbbbb57201384420be9eeee6e2e40e7b89b8738bcbd6fdbd3e7388ee3b8a26a83f5ebd19eb48b6cb4f98ef3c44fe6252aa2154df711808dbbe97c019cb82b786462208eeb4a686215fa3dc99823dca2026cc09511203db81f4887fb7eb841ae568ee32a57e95565223cbd695519cd39c7a0b4524a521250f7908a40b6179a6530b7e1f960a5d5676faa5c846befcc20399436f67c07adb7f64e18a0df66cd9b8d8c04a1d89b39e607a9d8e5a5cfd93493859d3e4dec349ab385fbe94b94176e2b226862da513d56bfa57899fa2628ab264c76c9cb1f4fa25a814c2b284c874297af88979e9096f1ccc04a178d97137451ba7122a5948adb8722d998db489bea68ae70fe9cca5d2c168ba562b2d9a11ccab53897198ff5d98eadcfdff5fcd0f76eeef92e6d5dd5655d7b67c8ece32e6e9b22a5575d7b62f3acd5b0487165033b7e29f3e9d900c7da71fc2f653d38fbd210e704a58945b6f5f9c1e6e9e434a58a94b28747f6e2c1d997ba9011e5e384a9898a6c564f1419674445457d1146143d8a8a7262b34735417182f3baf9924786f3ba1927549e505eeb42c617367a98d0b0d4225bc5c383cd73698949131a5e5fca744a1d9e2533692669c974b0791ecda3da4cf2b2e3eb945ed217bda1d68ee3ff181999153a1d1f6cee301c588168681cbfecfb38a32bf460384f284fe54b3a62c204752f511a82704f2f1456871ee8128d5510ec0659afa258ac93a077d02e6de859d731d19d668f2346d886b355c75adf6afd6cddd0cb2906a165ca607b7f668e4ae4fa929795c8eaebeaed05c00e168514822cf073f3373e7b236ce6a09f22df4b7a436fd01f3f32cf30b8d280ab0eb83e8b6c2f7b135c1f24b30b81eb73640e2abd7441c1a337c3301545511445511445511445511445511445511445511445511445511445b18bd166e9670efa20c5192914c5c1d99782605cb41469ffa8a8a8a8a828256cf6a830d997bc7ce972e36d3e7b38a397e20d1bf1bd6968839242c80cd98da3851d3b143fdb304fa8c6c1f437eae322bb1f36a6c2061019c358d708d2d9a7c2b24c851deb23f2e5c3ca8f451e31c22c223961178621eb723073d47f3a23d22ffb2152c44bba54a34b53345d9a50365fdf357388e27b149dd9dcf698f8d56b2e630f8f8c866c978b032a38e0c0ce1ce2578f89d963c2f53d59904ba784d1906dbb78e1e432547fdb6a5213ff78592bc885530c3223fe387ed0c1cca263f57387e9bf667a36524a5d2358b1057ff5ad164b00850809b30da6ddfb128d55d6f8f47bf698503347fd5bcdb0b40a61fde84b74b6ea189d3d424a9ff5dfcd8ef3843a628453df5e862210fa3347fd1f3a9b50adab02b7f19b2ed1d97889d0255c1f84f2b25a4184ce3cca63f5ebc51e0584099b2794efc81e9565f99b380dbec3fbfa1ee53b3a5cff678fc6d54b91f4660e71fb905c5a91ede57086cc4121ad214bb0173be69e869cd8454e3c434edcad8959e4c4969c78454e0c4e3cfbbe63fe008bf67307581c41efd4cf2a2cfeab671e4557bd43f5e2cff4cce6c50f670fba3473d4175ffc2a8a6f45d215c68ab5be78478fa2b3094563f5abbdd95b45e1fa7404acaf4f97660f22ffb3072d5306d39c33feaa67379e3eed1dada7dff5ec467cfa3764d731f15b24ed52fc1be4aa63e28fa4f856fc9528feea7df52e9620feea865ed28b89cc1eabaf3fa1e86c7cfbac0bc57ad08695437f24571da3bf22bb73d0b721bb8ed15791b4cbeec512e8fdfe8786e4f62059ff23bd3ced18d2ce68c6a7120e9c8eac7a3fa90f50561ad1b2a5f5836e6f89edf75bd287c7643c1c157ff48360f6edc707de848a3a0cfe9e149af9559fcbd56799f783eb6f64c87a239a28befd2262f8ac4bc4faf089ec8b6f444b816fbf48ea590fbe7d15f99adf7a23da8a7ccdfb5ac0ea555f64f5aa9fafba4451e62da2fad6257acdb734c6bd114df544af798d1469fdcc33a069493c1ae3defecc25229af999db32a2adde88f64d637db69863dda6d9ab229b26924d0b8d6829d288f67d2587b81f7e85902f2a96be777d7859fe1096bebf8cce7c788cfb10ff78c9fd0bf61bc6a58caa7b4de08c942876a0e161f179529f9879415541cf0be615107470c2cec00a2bc993083ad45a013c9862841e4e44f0791c7a882083c7c33504016637f4f82ca9b37781b7c3e60a1d38a8e001818801b86a35041c344c107e0c198f12e4c8814200344eece078a2f3012623000368129b452973c27800800de1418f5ac531e3c17c50503b9031f1ee23a9242dcacb84f07266ea0d8f326ef4b0627c810d0e2b5e4dce139a1daacb00332d9f28960142e0d923ecfcd54e1635ccc106f849a4682cf0b89c23ea364386b6d8701c464cd809ec7c1f606c8f20824f0f1e1f06974070924bb86f50b8238d2114e70fe0f870068189b290986cae1e5461b3d7c387d7c1664f84259bbdba611f186cae3f854d1636571c56d85c4128c2c5e18949fc64f0b021270bcd151c4db80c9bbd01e4301b22a70c181136d7279bebc41e7e7138857da8d85c4df0496844c8a2f4143ccce87185cdde0b08c53478c338aed8ece500d183cdd5005df8786180165e4372c52ac02d05ee37c23c629089856619bca3c5e69a830c1903cd053948d85ceba7308f0df3e051af4763ad32388eb0d9cb13c370b0d913c1a7078f11685c055009cd32f835a4001fa637b380fd52ffa4349dfe98fe70c016fb4b640a74863b463f4b9829706b41e2dc352f3fbd43ff8b979dc4cbc6ff64498a05811fba78d9fed4a977cd8fe80fe9c34bfa3e65d8dcb524dc8fe38bcd5d53b23bbce73ceef578c3997b31a069a927ea1acd03df7b20f5ac7a7454bff1f7dccbbb4452b769acf1376e244db2f5e61edc4eb83bf890f06aad542582abcd7eacae35e3a2a9b1196fdcbc7036e020e7c9dbc1b7f803f63f1efe78952b5dc24f91417dc50b8f60ad5c70c20b297da5ca4fd7c8e880837530846d1ae29c7cf88841fa5c12ca8a9574a587263e4e84f480c9e9f99c24542d275948b0d43399208027cc063c1c6c808438a3a5055f60ee67129e25446461bc64382fa79026882b845841368f8ae88c7143e7e6c612a00d0f628808d2117342e9c5a61c6da2a46e48018614cc3d0a41a59708c0664003aba191f2715f2408c605858fc1cca7c8a1cd35c38427c44b280be080d17d8a739cb18acdb04f7dea611e86dc839df823f4605946e003e6aa4f100ee66e0a6319dfa758acd15a97abfb58cf893f3e19eb63f504b964b07d8a0c72616b2d576bea7bebc216360013481106b69bd5e1803503fc143954f16ae58521b8fa2afe00872a5e8dab59f150f845f5293228c4a208a6de9b3dbc9983537d23e65cae1ce2946afbc4a7e20f555088c5f74205f415415c21041655e25d01a7665738b2d210ba80d1ca85de6f0fde8fcb1e0e439cfa1ca6c29bb9df1a7345980a4d4cef10c594de0ee67502ec9f1e4995d8fe5cf1d6643bc176c3668239679d73d68dc994c166c35682ad868d868d04db08b619b6254a67944d862d860d866dc9f6c226824d69045bd2e6c2a66443da926c48b616b6106c47656ad00619cbc61a6a8c49030d4b0331679851461832c600f3c5498c19c8c04b1873ce35c0884197995a027ad033c7f460feed1ddedb9ed9397feb1eb099c37fcef7d923f5134825299e75ba532a06f1c1dc83ab897dc70340f0960d83cf1e2e533a64295a39ae6ea94b3a76cf77f098a5bfbf8f11b0ff1401bc4d63e5f6d52b686a5fa9d4dbb8edb7ba7d00d3219ccfa69c85cd1ee5cce1338757e214e99d63fb8facbdb395db7b64d8e5f642e8cc766c7bff72f6d83ac7961f6f5b87b7cf01d8bebdfae0b77df5493dcfeb1915b76d401df5b95803574db76eebbcdb28f5addbbaaddb38aeababafebb6be750f9d99c37febaf4bb163dcfbeb78ef3798fb4c836930f7d966c7596702432eaecf75c9a55420bd4bee3b0e731fe0707dd0fbbc8deb9b16ee14eef7f6be1fc7ece53b812124de1ef4664faaea3e4efcb13dd86d9552d57767ef708e8b3af1c7f69d18c487bae7759ee7cd19557773357212489692e20b3bbfbdb0f33bcace6e1e22e0fec97d90c6f3872606328566193c67e5a2eb81e38d760c2b0cbeb0be2015562e6058b708c3ba450cab16aab06a5985350b1b76f30801832c17143b9f15562c5a61bd6226ac56b8c25a054d58a9a809eb143661851a6f84dd3c0250ca6ee06ef23b86830437c2ea829bb0b6e015d6435c93930faecfb90fa6d4098fed994b4c382f9f0753ba44e7652bcc231d5c9f2b7582a818d81854a2e0c5614528178ae355a8fa9c5b2f08c7c7cb49bd51e6e5ac3d412e4c8986b0c5b02097ad3f1466221c7a1962ba02ae4fc91b5617db3307a59eacc60450fcb4017a26f3d87c227ef3889be65e01fdf1210401d4eb0f5b90584102289c80c96c58e9418ca62780604117a5aecc1526a8a481c3d1910d4a22a8818a2a74486a214a8d2e2dd4c0880a0e58701142063246ec500494116d00519b41195bd868c32887364ab085072d57b6ecb001199e5843cb0978a83121a623e3e5c8298d249e88e20b961a6ab8c2c6981f62784113301d1b5fd050420449b4f862e90c231f8000638633b648a2420518dd1a5b64a982098a123f00214308da78a2862f4b4e90a104179d1a186a0c2f3ab4302509227a4b1222b85469620b1762a0c5985a122c90b8628b982e82384208306630e30c1bd0c8a28a34587042aad180c5162f513c4c49c388358a908196315880c64d1518aa70693a22883112e0c2861940f15005186c4041032e59a4c10219d668e201872616d0a0848518463831c393189f1a99284230e589175f6400861490b18410480431069533fcba30c50c111c514697219418c3a012430d497820a30524ccf81122a36b90202a0820a8380a0387b642072e3b303145130e30105186cccb1e4a7f9cde76c20998da18643c21a2096ad4c210484a4c29c38b3374a0d12f80a085e9d045c2105685fb898c2a502e2e6ed861061b9ac45043932d2368b1e5045b72d812658b0cb670b1a58d2d666c81d1ba719df7a5c05054ad5808209242509224262755bcf49a57ce4b852adb1a452d5efa8be28fc905276c315ece31b5a7587c36c58881c2b37905fb53279fcd2a1ef39f4d268ff9cf66129fa5e031ff2a5398a0cc244c5e68c052d02477e23b9a5cefef507cc714bfe23b3ee7e23bc415ebb97729d8bd4acd67afd97c7629b0bb15a347ddf02f37ef63b0bf3e3b19ecffa38acdbe6405de9183facaa461693a13901798b062f08e3cc479121f01c793a60e546c9e5db484f1f1d2e5cb6a6905364f2c55ace891020b948a0717d83ca1304de171822245645ac2e6b99404fbcf26b249838f8033132e6181cd2d661ee9ac3044048a3f66ae3399c0fe4081b580efc841257e92f4349c08f80838ef7f020abe63e6fd7152e28f9911aad89a12fbc9eb43d0e2f5893f580588c1869ff8e4e6c6137fac9caccb13ed931b373af187c8c4e274e2f864fc10b418c116581827fe139b0f410b9b4dfcf129617536b17c52532385e5a9a2ec090dcd1686f5e9219fb83e042d5ca43b19e10ceb233b53085ad8a896b3b03c910105ebc0fd348618fc3281a848055154d468f49bd658688dd2eb39b4173d3d5a94d8c2e405302c19a22b411333d8020640d46086195b1a2190d19344bb80ca0ca02c4d11a5948522810249061394008718bc5882f3a289018cd193041049a4581af384b4850a2a708419334cb1459313800963668d0280e94902c360450ca2105306136472ace1d402a8a62c3ca4a00b20be2e8cd0f1a52709271b5a8852c10ba89c40050d7802ca142f544125042a1053c7e00e04dc8981bbae4bc2688917a0d1440dac3c95718566e96ce64a173ec0e00b166401035af7bd04ee3adc6189aae18e077733c05dd7938437821aa4b2009f923eca2405afbbe4defb3c8fc6789f3bcc1865b5749f1bca93e59edcb5fa58c69a9de2f4d40489534c455147de66c4f4b3d19fdb0b6077f7e7cfb592b8fe04aaeecef9cddc77cd71bfcd23dcb57e77fbb7ad6b1ce538fadccdb5f6385adb9be7e5e760207abd5bbd9c69803d374cdf7fe23adf015bec6c1eee802d76368f19a4dbe956dbaa3211f6ff827ec3b2fd71849db89f64e082db4b215a83234cb3b07932512e36cfa316ec0ceea72f3290c0c58690c4e6ae3d7d51426960f33f89f105ce9e830003dbb3871f616f3670ae68d889eb572f2910e45c3a3a3ada8136e79c7336394d99b567dac8246fc91e552f61c6a040b17850ade5c7ebad5eca7a7e862153bd3447b6e97c4a3f244fb82e1d1d85e089d6b539c5a969fb99348f50e8f6d261462d162a3796b1c7cacab63f3debae7ddffa848fe8ccafa04067ee643259bae279b14ee86c76e979a563fea3160be549b08c3d5696cbd15aecdcb5c2cbc6d9bb607fee881aa2f0026f374fa62ebe63ab5e9733baa0020cce7ea55bc10c33e8026777c29d91822d32c0d9936c628450b2e205ceb34be5c29d81d4250c9ce7155abd56710add2ef7db13d5e7bc8d2a4b47b46ae4bead017e2d8567a5490a66e1b6f2a4865bdcfec77d70d1fd7c58777f84f8f0928b0bf44748d75121021f9f8302775dd73dce378f89bbfff15248d775deed9ec4b882bbaeebba9b83605c4b4ce5be6d8e301f5d5821efb3aeb52f8dc133b89fc428027fb89fc468c259e639f71a52efaa77e60fafc24e9c5778feaa79f490a6f4b250442bfd16ea13254d5abd5fb46d5a686c83a2b159448ddc372f60c3f21685672b61c2fd94444b47e17e426202d3a5e6416bbd3319e0343ac56360bfa4b30faa4803064e4734a326cad0e6afc0e386289a6a47b469449b3f97e8644267aa27a88862e988d6b5f9ee4467db1a63988efcb31f254d14e810a5469bef4c1c0a6a8c172d74e651515178fe840ae3130b9e3f9b9ce69414e88c4ea1b1f9f389d0590f20a09c68f34f40c1a7583aa34bb4f93d74366953fc4ec1dedca2ea17f3e9f7fb379e5f8294acefd1594963f3674fbd4f63b41c3258fbd333a3274b644ef0430ba2663883365f48cf8c9878228d20c808e1431333681e05ecd9436862232a087578e2208ddb670f1c20908e016ea181593258a9c43038045362e08f0becf58e190d06decea0bdd36e869833701703cc7d81b73170a55fb0778167efb415dcbd33833dec4dcf029cf35ffddb376dbefabe16c0bdf72674bf5d16b6efdebb2c4429b27d775fcd42f7dc7df5378dfba6719e3dc273eb9e38cdfb1f1f6189ed9e7b1c2dd88f248a5224f5db25da3ef544df87cf912f7ff08d681dd93df7459ebb4451fc16e11ebc442ca41e7cee8958885224755ffee2830f3e0baf05849ffa22e27df9ff801fde975f2345c217cb5aea53dfbd114d9c1fc6529f1ffc2c4ba53cb269535c80d3527774da9872ffa639ed5960214a91edbeea7bcf3df72c7cf755ef6b01dd6f5fc4bbaffa1ca0b1f9e51a61a6a041173d886185c67d775ff51a29d29d40630e451648320c21821cb8386009dbb4ee42f32e11111a9bdfa1d0611a8ad634eec1920193b6fd48a77bad64d2a210d916e0b4ed7e46d5b9329e106ca0d1859ddf6a030430ecfc146e2b2e7801810ca72f6660a104cc154849408879fac243084becfc8adb4a121bc4b056926e08e1053bbf63811776fe0c6e2b2e3001a10c10dab0f339dc565cf0020433b888c13e7d690a412969042120b1f33b30a2ecfc4f862decfc16152bac15252c2063e7775b8c61e77bb8adb870040831b0f355b8ad24250921c98a0b56e06e57bbf08faf4078817d12a30cee12c0192476d0c0f369aa3330a80e420e75b2908890830754f4e8c1fb1c44886176a6dfde8e29e9f3427d28cf068b8aa30a109caaab896a650463f0903f181e35e460a1b182e3071c6600387833283964c0a2d41e4d50f159a2ca6cf8162a6d081994a68247981e55781987135e4e130fd5005cf874618023cf083b7f078b9a438d97426b819723a5ceb4dac05104ac892a89ff39eb79cdb0d683744a5718eb5fdddd6975d56debbcea793efb46958d3019dc5fc7d4cd7d4811ce20f070b82f3553a994f7892e6fd24a694f5a715c6188e3e588b3d5d56ab55a519f0daa5e45441af7b588e6d1987765623bc330ec4de539092b837860188aa24ac6b3d5a83207425154b5af2cab55a9b766ab3b551612552a277fb856629015f656967392e5ad9b83ea461a391949c13ee712aeb3ba8e8c62cfc3eaa5933fac57d362d5d89a9a1ab0a6a6a6265553f37935351d57b3d5545ae33535b3a607a0ca47703fc55430da9c45023a7d239dcc435e6d48849d529f55958d78f03c9f5349ad0db52140475686d6f3bccdeb509589a810a58ebbfbdc3617d7b9acf8c3f57d5e0782dc0656eae0047bb599316e009cee1770cdd19bd3e79c734e9f734ed7e84d9c2013bbbce454af211cce2ce0f9eec515bafb48a7fb0dddcd18009b6368fd5ac04b4b435a43d70fcb755d59c4cb49f2340882e124ed2455aa49ae56d6b258ac563833e3aa93a4a19935eeeeee16f0b2278d8d8d8dcb66c6c6c6c6a665636303a66c3eafb3b1b1e1369b4a6d7c7ae08901411b4e77ea1a378e0badd7759de77d1f91540a0c43fb2354a99a5cfdb02b168ba562b1582cd656a9b366dfe0964cfa3ed2b0f4e7ad5eb60fb96676d9dee96f126c74db7c9bde90cc4b1e5be75655afa7d7c7a9d481c14a1dd8166eb6ebb8aeb35e8afafc640041a794ceeaa3cba69b6f3302d3abb46ed4e7b611e12e2bbdb0d6ba893f388e36b17d3defeb388feed0f561384e37dfb66d6efda9320b4080d6bddb499e20b33d27ab935b0fc711ad807389bd72c1fe5da7a577fca75491e24ce652183141427460de6428a57436edde21e3a57b1227bf2f95a2a9542ae5b3552bdafc94078aa67758c0bca494faecba61ff5a0438b520e0e78a77f939c18797587abcf4e901bf8edbead7d4e797a2cdff8ae6a44c80ddb3bdf43a6b6d4ed534dfe79c5e299d32f0c24a696f12f0a63baddec475e24c3c7a9cb7795ef53c8ffaf43caf2d155d83388ee3b8f9ce558e9b73c95c6aee665a9de39c6e1b0fee1e0cd79fb4d65227c3b0bbd7c9d5aeeb68d779d775b3ebbaaec3a92ef0c24aa917561d59d93bfddd5cedbaca7151c24927750058ebcd4121e5ac3f470a15e14a6bc51cf07272c0cbe92e5c2b587390eb876ef4f6ad4028e6665dc29d6e7942e1f93ed2b03ec91ca406a8048bd82aa320648ca1190106000800f3150030381c0e0b85c2b130cd43710f14800d88aa4a604c9b8aa32488619831c4204288310000000003423053db000d68f126976ec454fc4be728212e748966cca6e1750febf1589ed3339cd995d6a655b618244586e8a9faf4ece9fefdbaddaae6cd1ead174dc32f37b8ff972374da382f5be1ee5824efd15658e9272e387b207dcb59add9cd1354e813f3ff148968b8ad926323e2244338e04c39e85545797696637c70c3d175e09adad295fa1e0129a27ced00a6f77a33d0dcd8e1ef50d2270f17147b00a0169319d883b9c8ab208266a0840ba2ca15e0aaf5ddf20aeffe446096fde519456e83fc3efc7978399384c5b773603057065c3c7f0c8282836f88dd92e3ebf8fd82482da5b2ab299403030ec994d330b81550e689fbe400af1bc62efa22aa33d4060af584c338212c52476bdc4c5576d4e0c804c5db419c66176b8b884b7003920fd0a102ea658419252667004b839ed4ee8fa08209c00e1fb6d4c8ff3fb8c45a0db630314f581951a8ed9f507555b13f671cd90b031deda5d181742f5b0c66a4d75feef13b14a0b21dba24d7282945c179616d30dfc93604fdc5476f7fd5e4101555ca678acb8cb75247efda3218b84367a547a8dc56355821bab905fa75438e887d256e17d77f98770d73ac2377926c27b91196cf2467fb0980ca86265bc728727f47212ac9824a9d4021c3ca6d4e5d700537589c591289ab34ab42bf6d0d9081d1c9ef13a7506363a15c40dfe75460f43d0d4ca4017d71a7cd37854888ca8ed3963ff606dca4ca04ffd045b992cd206dacbfd4e3bf8964b801b6d6b2ad51ce47872557a05e93c73d83bcf0afdb289c6351c1dcade1ad5f5a44f103a326aee14415b7f02dfea6c9838f4e320799e4888ca947933aa4678835628fd8e7d8337630f6a1839b7f17b703c78540700b6cdc038b9b407039705c07f844d78c2ce41ccdb43f94c4a5ed97785a7f6470bd522454debc82929ae08eed93199d2b61e5a4d9399f30ead5f5695b80d2d4fc03b7a1b603dad443a55186e4656350b488303c5dd5a22bae5766493bcb0aab345bc7fa9e41c4deccc5c4dc2642c2feaea53fbb1185bcf4840ea7f8ffd942df655bd6892415fd703f828afb014cf66d90e3810cf18da5b578bd6b6850a1a3803b156a26ef55a89495d91b8654f71b13ba3584b0667c9f90801f7d6c3a57cc29530e0fdea10337206aa5ddd1797b3a5e6947ea50ba9b3e0b86952584c78ee91cd97980d5cc347c750afdba70f9985e587d758df04f3529a4c6cac966f4abf7453a70671f52d40e1a3fef8b52eb4dd92335a16868f34f9df43a4aca9e6ece70c2bce73b7a0a157e8894868c6f8d839d25ab7f169012691a4c9ffca35ecb7eaf20dad982d4321c775d0a4a5904a0e7f4157d2cec559c10665346a8d45bf8a68f15ca4043947008934c7374d1339c1bfeb200b452cff7218b8910fb49da07ba2c17e07d67a02eb32579d4b13c3f61727102061b61a6a9fdbf827bd70d20c310074288bd9fe0914951c98b28295b87eee8d6c6782e1c917c741213932bb4a2f478f8f0616de440b88d9802b771d8a41ea096fd98b2b1f08e48be5f1442b795be4fce3a8c17d47c43fc55d8cac8c2fdbcc127e56d2c383007b75dee8a66945d9019e11882780bf11ea874891324547d6671533fe431c0d625b348a641ec7b217dd6b34cf6d8122582592fdcf6a34afd24119981e18f0b06bfedda9791dee3c80fdcd6a7f7239d30cd91ceb9665fc6cbd571ea3c482285fb5f92c85f317fc02b81330a958f664213e053fe2be3347a41e6903dd768d540e22ba2d9db9ae4248291f6e8999f2e02963f7fe738e759aad07945f5fdc429b9f1415057e78807f45904ff5f2379a755e00d40b78135cbe9d0064b99c5051117b8f735adde25e3e0b3adf9013ac3402583a0b552e547320cd870f0a0ffbc027a3773436ba266d11074a8bd92868e19e962e0f1d33906233abd8fc976ffe5e05b49595a2a364f7887ce6f1d99675b1b3ec0895007f695d690a10681473e8930fe9e60750eb629c193779f23701d3bdb55bd3792192607ab1ecb5e84eba3e4ebd0996facfb5f837aae5aaad2eec97956854d1b420b4682c92c991569a2fab2e0812143906a36d44b54b0b912360e2cef083c6ff12164a465b994b5ffa325c80cac947b740fe0c6b7e51d1c36377a3680359ce930b80417234c3fb9cdfbec66147fab8adae5c2fb3ac18d80a88c93470c600e90ce1c4aa6bc076a91d2cf52cf6051355ab4f65b1e95081f264fe654e1c37beb55421369b05a6ceb2db03d3ba4cdf21e292ad5e0b9587d1b9ed395e1df9d05bc2379cbc03d98568b1dfe3e6f45f2f65047a177adc37011cb384644fdeb488735e6c29292e9a349f4c22e5539bc0fdf91a3a6e65c6188b55b6c7f18aed0697e29a92159ae701129f9608145c5ef0bacc9efb20bed3c4d27d98171adb9b4718af5e6fbc5de4cd8865e44ec19a929141caf545eb88d45d8c969e8002075088bd05c52dc893d268447c1e009f116bd6ccb4c4fd8eaf6010e40cca062a1100fa355928a9a1dcb3c0ef3a9d37f765e97a41604d11c95f1827ebb8c9edd5af7f2c4d3b0429680bb2f2f23604452100cafea2bd9ff1e3b5b7b16f2039755f47d17eeb5cf86c5439c961c4a1454592a4c40ae353b4718e893de8db9625d09232983e6f9c81f2715b5b006928d85d265711627569862b8dcd865a9cc9302038d548c961aacbd846798c6a7a2eb0b4776614fde6b99a3fd9fd1a80047aec720ba55fd54ae706cfc5f463339b8c1e40c9bbdd9925f6d0ac4272bd12a77f8ba006c97b49a83801ca0aea461a1b269e563422709c3fb6a0a1b6244599f964d131a0a2be09f7169bd2c7327231bf0541a281e371cea5d8e0c1641b51d2670575a74c2ce454b7394a690622ce4d0fb50293ba4617a71045cf0a46ae619e61a0e3f236dbbeee543556acc0e773438cc9dadb73c8a015c282b17c9de7b99f1cd1498349e9cebb24b34d41e9b88ec1560fc6d7de5e61cbf7b994862f5d239ddca24e7ab93cf083681e1783bd3366d3917d7f90bbcc4d14a1a20b09d79b571cc71b04508f718e8cf077c7c23bc897375612cd4fc085a3b3225b03a959cb880b20ff007937dc0c994f1805780de930f449dcd1c69e006d92591e7fc1c706d1de10a2bd1725913d4e8b56b4c34d842b8268538580586d0bbd4aaa28ddae7c3e697c261f34a71f8ae2d15e4410df20186d4f41f2acfe984e4d126e37d0c78d8afa425dad682af7973cd6e938a50a05e15c64636639226ab35d4a2aa9bdcec129ec39ead083f533fd4e59a0153c4dce4b4b953b57746b6c85a6b58f53aa130e50b736843edc886144cf9cd47b19ceaba40a88add1a00796193750f2db4419db345f78eed1d4a2fdc355f2c51f537d14af1c9a0527737ddeb090d4a6770e99af0ec22cf660e55259e2051e96823733f83162a7804d5dfcdc4ea1aa513b15cd53b902a3e403d1b1c89851a9e162188e2e294dcf4b69b6916bc0891cb6ec87ecc221ca8657b174c5b424baba2b4bd3ad5f4de2bcde8c53bed6f48e5aa6ab56ea3fbf01b8d85249321e0d39c1494fff7f8371f0d41d31573fe6ec41086064fabc356b41dd37be78d926fb29ee80d3ad524e18afd9df351dfbe524f8d274245695770d3522850f5f4eb5228cfc4ffcf53255afa339d077a5aa69535cfded179149e2c5440706044cd4abf9d841241d9175166ff82b53b28af25284d7d50186bd09822817af6c5af9f9924311f0df9b2d827c52465451026bd5674b92749278f40f2372a56aac36527147a836c504b2b18a770802509bb7acc667192ba6ff2b1e653d839ce573fd92ceb44a8fc7db8fc40a06bcd873c69e5690f0d36c3cab850b5e9e1888b4a020244e2e8083c2bc95ed8bcf00579c1291ccc3ab685f26c2e19e359261562c9a0ba58a0811aa9236329aa5a47da665514f27fb7ff39f1fcb5957da470c70a3a6d212910f6cacacc0275ae4e0c5f585409f4c33602cad99f9fd42e50551f95dcb551c9cf342879898edd65c06c4f05879b548bb313737ea3c8ee65b17a38cfa4218de81e10b7cd544eef0f1d88c016592b62b9546f2a9308122a3c87e0ff7361aea0ec7e25effcd58f0a1079a580e9c4ae796482bf72eb8a378d6e57b280a4c144d61825fe59f5d85db29b84f60a9209a66e3f095ee0d5dcc2fc67052dfdbc12af7cbdd07bc37d4bf2ef9bb15c44936e5f9eaec801a797f6633343a296108183aa601dda2d24ba7a5dd2d3e4787340376126aaca7fb8ba3178694048a15a22165589855db62d682066a1d8c4d6aa007c70d79182139896dac5a834a890b2d85a9da2bc96d647147681df81589b9d13b57fd084231fde834fe83ccd6c04f75199b486483152381cd4402e6eaf273c25eb7089b2c6aeccd943eddbba1688c908b41df8b082d66f0e91f4c675a5a73ad392c3cc629a1f7506a98b033d00136dbc1f9e54b6a9a410cedc895f6fac0ad895e01a6391e70ac406178ed02ba48c03320ede11cf63888f6ec1f63b8587da5c2b3e82286db4f98065a77fa145f21bd002a33133da3090766c2922e2fe1bae7e7097ae09117093e411ea5c43f5798d766845a95c3c8860eca1840e560b2bde73547d91d42196664df154ce70a729e7daa281c5336fdef55ae6373917d4e231f71f9103562ca328c9ebcec0efb4e781990634710348190d68ef596c22ca671b41909b21374629a064c012e93c4d5c7713c9e99c1d9fca8c820f85a9709edb1f4034efaf8001fcfc270ad14676cc6fa08fa285c9b1206d3601bd677d8f2b2c4565b1094c08f4bb347ba40360c07458fbe6645a0ab824036f79a496b7e002fca0116660457a383de2eed9170c14006934cc86bb28592c81c9a2ca97f53b61933c29d08f99b939e8827bea5d69f4490a3efc039ba400560a2db75fcad8d35630c1d79c820f392d9e28c3969a5e8a84593756718fa35217cc536f15f7e873ac007542b0251fc411bb37d7f211cb49245687f4494260ddfd0fa1664954c1285895cc1447de9165ef7ac34c2c631e28144c6b3b5d07691e1721ff1ad2936714f906a83bd3c351692dd0763f5d144c4fde745ffde1dbe743cee94f8a4c6d39836773652930b3602707e299a0b4a0bd07f7b1e5bdbff8dfde42bc4b1506c46953530fed25d45d66e437ee172c0dd35ec2552eb584fceeae6e68a9852e84dcd3dc0588a4f888a6b4eab4dcbc1b0e975539a5b88b13dbc5495eb4941c3de43f4543eed59ddbc54cc707885fa079ec1a16fce21cfc8c8c2e213ac687776cccd0e56a412ab497ef07d056731ed77f081392c689c0bc23600dc06ecee6b84fe6b16cbbe400e02ff23327d15638d07edd8e3887534e81a405f11df4fe828f6a43336306b58a7151f97b9be526d2c2484425f9171df557152d7bb2bc81bc2c6435d10db1a11e8189420fb9753b3dbeab43712cc75ee353e2202db23010ea297a7fb5b1cf789e6c5ea0d93d3a7fbf1f4e2a1a663f312e0734fe1f4ca4f221cfa3b83d67cc091e7e409508b76bf0fb81ff131f6895f71a29c3b64112cf608d0017104d0d2ed781b5f60b760779c1bb36775cc6fef9f40ab215e092b0f96cead71dc2f0635cac1651233af39204faa5f030e3d6d028261815d96e420ae6441e1fd45105d112aab7205de3e2be8dcc865f8c1f9ca05b95b865060b5f681315f2791073fd20496bcd6ea5b241b54210b4e62434958ed01bd60a25fa91221a112bfc193726350d9291534cc340db639dd5050a4534a15bd43e7f867aa1b669f9c3c5e2a2d1cce8b64bc3a8675181574f2cd6129ba9b9012b9586c1eeec2f1933e6f90ef7b5a87ba745b2e4ed85f7a35a5ca8fbc8782cc4a7ece4425db228f1d0c0f204809785eb9e11cb327e07b82ed454d0a25993b266333aa6067c715fc1a57f8701ec6a3ffbada26f1e10a75dbae509832d34b7a8f6227a3c1145ac464976400283da89fafa4a723d521ea1c56c1be46132ae45075ee40e20244ba2feda129e52926070e4499b68ea326d744c875e1857c9a049088113302611637839a20e4d5fb2d5e68b5ee2e493383b80765b76fab0e326c37aa117ed309af6cae61717560fbfca90d223025bba39064137340a3d278b0ccce9c0ac64e8783dd05c4ea1e4ab0713f57c8913701a8a53a60258091c0152987ea71a4701c94e1126c14fc40b3faacf84fac05b46cbb63019e3b9b3d84c4c353c9775eaa0025c32830c69f23506977a9ac649b8d675e5647f226614173c412bb0c4251bba6251a140c6830405f21f941bd20cdc18fa2cd21f0837e8df999b2102e198b0e95681f2b7fc87c922483e663d0b06052ea0d33d8878f780c3de983f66e02250df470a05c263ac510e68edef13f69a0f915a066cb571df0798b9963b8611350ece09b973ebeb3ae1e15f64a8d8182b8662aa2e2277c1b3846a2acc6a715c1f585999c200055c3409ff07e52113ae526ab42831d41923d736df7835569398b12885519ecddd58f9201843d7ad8a135a9925a36c09536aff9502bc432bb8fb5ceb67db2ab0d4067411f12e81275a29bdf855f728ccfd5a0e6338df50bc8d988fc7c5ecebf7df9aa368e5c735e04271654156ad0d9fcb118f1142abe025334d90bd7b79dd67fff33c15819f8d03b49af23cf47084956d2bf6e51f0bc0590e84a11409297c639ba7659e9eda6e2e9395284b1155d337fe263f3352482f2d584de1e4f4d08d83cbbf84bb8d45edfe2b064dd54c44eca332de8464b1d6ab6fbec72d02d34c5c33ecbf33a8357e27f10d4b7b26c55372506c98cbf3b555dd01b4ba2eebb027ab919f1864d886faa41f688b305140979326dda15dd15e2dbf925a95d9f15f51267d6fe623c9b0198398035224b844e6903887da58c4dbce4709235e91280d0c6ea1fa1275704980574e0fc68b260f14af3d539aab1f592ed013bfbfad50cc36dee9b9caf42f8c97e6f2f30a017b8564e530f72c0c68420381212369cfaeb3eba78836461d811be6f953c0cee6638bce4da5f824c832265fc3039cfe1edda55d00e4e0d845be5a5eca87c74b4444d98cb3e4ea50bc8e3b139c7e11c625de5c0b975fc1f5f909a701f9f85db2229a8633cb15ae5037ceb887ecf78a37a3390e3e0dba5d4a103621c59044a1105acb7be82546117d941774f68f1919d2404085e75d4a6332d79e70a71fd360d7b7592e3a52618302693418803fe42fdf5d2b69d6fed5b8fed568f45729aa8ec882a280fcf41b82766d2c74b64a09f405c88d082dc7cc60cb001ccd46b828e25bb6d4327344332e523013f7c17a53ebe7c8a33ebf429c134a63cd307d0e991cd11c32c9379dc40c26020df1ba85f850c197e3816c88cfe4cf1a889db984ceccfe6499fa21323d6e2d596e4d936e938a05b9db03859462cd5f6457d31d2e85a3fb924e16187cb385bb79f1fcb3a6b5cf469af59330e4d218fa11c4688b886a7d868c04a9aae58fec621cc75d3cef3e2e08e5d71e1a0d720a9e5d651ce9048a6b74c550fcb4cfc545108ff3654e58d1040221da5107eacda3904bed49d3b76fd017e7e79a1f6511f40c054f4cf9bd1642d74c4023de8460e4570dae9c67f9fc95eb8bb2a80d982232df570556d9dbed93c110a1c5f363b0c0bd7bf9500ed14be8252e991b4c76d4a16621e2854889f21f3eba14ebc1dd3842d1ca8600db2926d2790925608e690b42be557317610efbbf4e3247fd82ce9f6f7927b64f7b228efb08d24d93d0115c6565d6ffe4f5dbe2a88282303a6153c279af6355a4dbc8bcfab75cdd28ad43d9170ae21d8ff3bb8c709baba58627837eee0986187fbf6a2e5deea1ee559c173bafe6c09bdab8b7aeba01d34a6bb20c85d41d7ad97b377b203c7eb05c333e7aaecb8fcec47ef51135c5625fc3c7c1ecefdd554e7caa1a409f007ace72e982f1f4c1a3469b394cab9a1740bec9c50c287230c941b6320564811a0fa249781fecad4d816d975db7e1160890176d219e4c834bc6aac82e618cf65a890aee703039183175cfbce670ffcb6516c9423053b2f6ee004afd70982a0ca4789093db71c18cb1070cf36dd2b6eab70dd13d22c3fd010085866137fba8d469c47e6a02f2bf6bf47b8add51a7cb014bf0ab4a407043061f8e00857dd2d15bc5d3407a1a730862e191a927561785b015dba55a0c71a30d63bdbe98654a72df620fb9dbf05f38ad7d45bfa7f0f063c0aeedfa0e77a375c940523058ba32212d31cb4c71caff2f078b115ef4f1a7db94f1d34f78a018ff00332702a63cf638fcc145916972b9ee12b8d9f93fa63df69c13aee75cc9f8937c0f5b960e81938e81a8718ec7ff6a5d34659daad07eb184bf407f5045adac3e340b75cdaa54428ad0dd4e5c6ce67c5027b9ac818c5689d1ddadebec42aaf2a16c907c2f332e572885603ea0104ccc88320a4ad69e315e24d4ec08630d81841e3e02be6d4400e5faf1c43c85345ca0d8c35518650d16373daa16ff7b87577bea3a90c032283666afbfd71976cf7fa2b5d271fe2ed31c269c9aa13d79aecf46d47b0a1ba7ed59b68601ddfd9a202074057866d9c29d5956191129a3f191bdad9fcf31fce63d01bd0699e5d1a8da55e152f38d285ce1b90bf289cd16fa4cd17acbe2e4432f83e022d27daf49ed8afdbc01a60e10d186d8d2473ad224eb5ef52b5592cb34f1e889efa5367709a1adc8b13412bebb6fe3b9ab160fc87f56992ec0effb1138bbbd6c58b247bcb20492181dac6340528f6424d197d4a079b1733514cd7f8aa9dde531334a114b499521bf3d0e7fecbba3896524a76fc53d93cb485fd8d08a71aa09c3da2d2c1446f30dfd25bee456119cfec5c121ade66850a0bc100933e3cb1552e4a0ef02d848c1d1906e94818936c95c570340c0321670891044baafbb10f9009a808962b18b71aa1572dd11bc0bc981e8f7915a5dc83bc13152ed196abba3eed80c46360b7a32984100c5b230f4532d92c9968a689339feeba29053947a0d149db69d416060205205bd07a57758580bf176b520552d1cda7b48a05a7aa4d5f145e50afd0bd3d745af80c26263725306455c9150341201e4cb415a8097f16d3ec439a8eb771e09b0c1f5b815af88c2e9678e815a5770b05dab3008031d83656a4cd31df79460d6c4e9a480162d1c2d7233cb339e7ff0eda6e65d6e1a35a304b8946dd63979d55c0298c44ff3954cdc3d5e801715591812125099bd6da205dcb4d8b1d0648b5fd515a569a6d3392b9f24f03baf7f14a20512803b4251784f1b53180cfeeb524f8b5c7aca682503d214d42f563d48e99f5f0ff85a7baeb07291bf6f5d2079a5e2f5dc525ce8f1c4339b3958e7980a932a096371c556f40b43bd2499ebf6e946f66a5591da6bd85328e20bdbc529ccce3bebda08340af7f842cd9312c2e6da2e05a412929edac85f4678f1a65a326345c5a7c9711e997c8998554e305fec92ce575c74284f6c6ff857358e7959e95c1f4b215acf92faf459ae91e566dc8f64ecb2e53f4fd567b9cb84825e91438b5dc6b44dd9dadd539e4e522787fa2c41e32e8507722981993bd288e06decce25548670124f5a59f695f109e772caf10e4ff5527cbff80fbe482e7ea1e07143240c87dc221af5a81ef9fa3440bd56111ec2699420bacd9cd8894e31662971ce20eaa4c68bafc9cf41154a77056ea0467132a14e983eb1a1fab1765d21fbd4275846b9f7c1f90dcb7d357a47b2bda79a96c0ccc996ad7337e4741ee3f2527b2d05c2aeabe080779826754ea2d30858498d4c5a8f4aac0452aa5e5424af9559aa25170941d4d7f8eebe6a218f57161d0fc22569dba27feb061c89e58af2f7a824796ce148b9407468537d18d58445c530ada13e09d0ebf33a7d7c6323bd32cfae5c9b9d45d6f77c23f000606abfa3b26b9aab8a368e1a28fb8c334a93b05c61c4c248a6476bb7407a31bbc18bd1ce9f7f36df27b0f69cef1e2fd6d0ebc75228c06dcc113dfebf133ef9b0e10942f08325ff58f82cd1348ab2c04e335f1317c683fa15ab6a69c3aaee84b84672429dee91e9865ec5c41a9de2d785acaa866f37a3695d25190e6bf8ceeb6cee885999b52c8d25e8d50bb26c38cf829e4649c41286e27835668d2f5d285a0a074f14967060817134fc5f9ed08c84fe6830bdbd9c919a33a4d5de4d554a100bec6f3b881cc36d92f1d8707aef60ca2a49b490e73209ce38a3ff6b1301eac873f41c1f988a32cadb81f4aa2712ca5181959b27d0e57755fd798181f65ae07255ca10528984bf8e7fe3cfad8b70efadeb76eadc1f77ccadbb4bed9ab7ad1618c1fd98278bcc9f4f7f533e77904dbb09788d6a874820108081a508f076184623620bd8990cf15cdcb8aee67479d9a03414014c3dfb7217bc0092e4a75fc1125872df46b75a3a2f6b58fe223e147dd64093a4fc5a588a016fc5605917e3805bc6e3800e8c9465bd5f0bb6fec2f5f63c7bc41900ad11be7400aeb530fec482af28605bf9b668b8e44c91b92cc6cb7b57112b104d02794af18535b4bf4c1270c3c4383c16aa59c500bd44d1bbd0904ad785158ab2b808619d14f703ab8048473eacf3b334b2adec9d6bfa883a142a68f4eafd1b121b4dbe69f40e9a31eedd5c8269bf36bbdc69f8e9f4880b2b9e9532b77785a51e303684f1ad7ac463cea28353c049f89bd5ca501eb2c0fdbaf15ca6f9dcea37130fb40678d0f50bc4f4ef4ad0a6612b0bc5aac069ee1bf17cbb8ed6e4446e4d2dd53baff2b69f05274cd0066614325a5b0ccaafdcf01c8bdf4ed8b6ef21d3ac3a5118ec25a21e8d162e13761acc3f8c3e00b7e109d038bc77c1a5eda5b38c6f0af2d939bb7277501179532c2dbad4ec48679eb768b36ad6d98faf7981da4f21c55e6a19a4ecb21fc819df3ee856dd55e11bcb420868a86199faa1ab41795ed3b01dd825fcec6b85b5c9d507a54eed6b58f5a4dc7426227efa9b1c50d83d5324b6821ac0d2916324ee563a98f2154a9b07763c90ecb52094356412e36eb0fde257f20f111e90b5242aeae56b30a28a02022953201890c0d1655bf0d59a747d283b23fed14c0cfc6b2148f4dc78f79f7c094f3d0db3a454c00930dde76fcaabc5127ec70114237d8249319ce45914025a4f4cc76afb24974ece205d5e299c9d1e3aa63da2f1b7700c1f062e96270ed2ef710c80193dd874745e656e93ef35495d944c3628b4d1aca4e66748b06f0a1bb6fdf06f969db5322a0e512dc5f2068677f3b5332236b64b5480d929438c9c47cc3ddafa5122f6075f114df81d76e1ecc9fe44bd94dbe75bda9c49f4bfddd3825fdcae6f74a934416026093dcff749d08d0aa6a4f21e02d2f7d908d6da117552b7b3ccb991851dbf3b9431b1c02de276a4f7e72607eaf2f3bb550619b3531a7eef88c118166c573a6715701e024ee7dfc646bed7314ae021f172a27b565a75fd6b4422f4fb8d648dfc00f747fa59f4e0f306bcd268a33e99a4c42b4d31b72d64daebb0682f64e9c864d8c5dea8acf9417ae5ddc661212627523d6a0716f627e8a921f23fa4d49c40852a29ad7430d7d1581f8fb2f3a3fd212618f9ad01686a430b33cd0296f86a1a0f161ca423f78e0c2971912b9e48d977a34d387a0786fa534a2dab951cbe13a5af4e830e213bf181a057a3896ebfd1040847f7cae968a8efb22748cf46d1247a5cd4d0e155a7a315dbd104d9208de9c18ab3cf067c703ea1c989dede581f35e62a74b5a18ee3cc8c21c7dec62680e795f9d77a690bda38ed6780e9a733307a3d5c5f562f501ab81cfc66bb2c3a31ce4430120458a558bf28f5f4148d2caa7a9a6551f622e8e93a00e58e202d62459ad15b77f45f9798c9a2478d7a6f18a1f62c35788408eec8b788e85112f108903a41056c7590fcefd643a7c32e7aa2e512dc0635eac41710b0603ca2550ecc0fb8e5b24219d7989854ea5380f7addb06217b6352a3aaa257c6bace1031b261c2702b4a8bae3ed41f6a554d6027d10502562048c25e6568f2de0a16d14a9ddd19d686f4ceb83ef836e3ef1eaad049be8c08d4f8c104c04b6d8322f0d133920a9dd4a85e5c8c0d8a529004063234dfc16b4a4861d71c6aaa905c86a373686bbd76a0a82bb02a2ee6a0572e4348f9bae2211ca9793c543f15d8f902e76eaa9634c4dd69436d270df53c551ba1d1203d28ac641b7427b3b134f3a3467f2be52b09b9988d8aada8ab0550fff9808b07a4638a8e04c4b355b2de3d896ff359399d5202ee8c402262815d3cfbd8aeaa2b8d47a5ee889232db93adbf539eb3abd9df41d931f861055a677cee6c32cd65955094feca8a7c286dbc3f9af637d67d35b45ff810dda5e78eceaf3970641aee6af803be11c980f0bbdec70f37e768eb5d363dcd443f59c7a27195e9d52bfca2d1159a5cb87ea86e8d6ce61c28857f308e9b67c261a083ef7c7b646d501cd55ed2da93fe9869e587e88d88897803dcbed79a1973e178b8e16fffb1dbace94290421e020beb84f2b46f38b613e93ad13948c38d6ffb263fedd9e44f08d5b9e2c1a402dd0ef73a5697c079f83c36f2f1a958df3d17afb86b9020eecbe3834622d6538e1757c8377c9bd18bb54b011f26f47123a1840801db5c4141d3ef4e78322538ba155bae3904e18be31499120691ea47a942d58fae58daa6822ece3443773cb33444f01b4b03a883e0a3dfa7b9131a130589d23ce6393f92a999a12df04cdb27b3848b8e2640c9f6ac0da42170e083b45c809fda8aaa1113163a0161ab3ad0f143a187702255d1241dbf71d248a40953c5e4edcf1bfc3c03f16fe30e8fecc23fc1c761f94b57e4cc3454be49b10ee66612f408346c8315a7be46a9eb2016952724be39009d04daed3b48b8f957d132ae2c63b061bcd2eefd5cd6898b53e560aadfe02f4e010eaee044d5a1eac2f1448af1a5d19cc1e35fe669fbcaa1fcc27cdcb1cd840bfa740763830e8acccd69c65dc040436ff5823c91c5920e644ee2355e1fb463c142373dfd1fac51b0d3ee2f26682c6774a779498009e87f0408a485ef2d8b31ea6f823806b8d788f19997bc9445bf20d9e23d80471be32fb3b31b393a882e7cb7ce2b5209f4b494f8d29a4d5da028c44948742def6af28272a1b60a2b90d4e5fe758240092e828d9f5d6b2370973bb9ed383ff8af4340019bc5f980a7fbd48ea6f17d5097ea25b53c004bfca04b11730cbf754939d08ca97397521ee5246c6a0a7b20f705e8da103c32ca32114ba4e353f473449c67995ab2f67f29a35c0de40950ecad4c73d1dbf2337a3772d44c4dec0956c5118bcf7bbca0379ad18c543ee0eb80bbfd554f4817d63dc1df5863c442b431f9ef8d27a2624e27a5fcf7b8db9d29660c46db2c573de3beb91c01e840ec01509ae8f0648631d595fbd55989de4e2aeeb776e16f532f2b6f430e24f6f1201b42f7a42a70bdd8485c1ac0c921f03de55c2de2383c7428c825a60b50199d088e0391ba2bef2c9d8e7eb709856440ea1eaf0d44d23c203d8c219ff24a17b4389519805c099b48aee6d1bf0178f55bd74fe779bf88f637ebfb39a61fe9886a825e30a85d7aee5919dcc99e9f5c2af4c2512fea8ddff2ef766a42933986226ad85f723baeec43a8289caf28c5c77103eb722a83ecb6f4d166441e79ca7f97f312c54f566ce9344aa078f16927b2d5ce539e285aad6aa0bbb9f6ca3bd430b24645e19b4999e1ffcff6b0f607eb17f9c63dd633ae9b36df0a277dd2a80ad6b4894974d1ebc68545f5c91dc427a7d65df12f74f3913cb1dda7793d075cfae347e76162c81bd59f6447b2ba8bbe308435784db5c0e1e7c7d4960d1093f968211df27f8464a045e743a9ea3b07398d4fec75bc28df0c291da8912e1edca340f65b3b6053ed28c38081696d1483c1c093766803e001a9f6948181c0e96ca3f77499370f1445efe01c9509c831269dfb365e29250388daa4137ff60fa6cc1a22518a1bb759d201658c87aa9885b0fd5c779c21e487357fdb28bd10776ee3272f1186f051df672fe3da3679eb930c1103fcc17edf755deabb980c1617e090790ac7edcab57bf7919d6d782747e3d9c73043f821ec43097f3d7f3e68e1cef92780bbdb473fa31619beb480c7cc1300374bed7e4498ddbf2b0e00350719407e3cce4d68241a7ac0e89f35f38842fa298adb60fe0e354a534246d9f629a1d4fc70a6b245da8dc4a355267514bad0fd26a5ded880fc847f301403d13fe8340228e9d41104e20cbbf7747889ed5ba4cbf7b18c8f592d0b7af8a8e888af4c35ebbf566e9b04807f2addd75d0fe6a4426eb6c9705e0380b1c9f2b830467257b03f88c62d418954d0fbbfc3cc1a6007c8222e1e98ef7c09ec01950a4d1ce33e6f9ca82ff354bb18cb262426833614d2c0ac50e18d24e10ff90b6403474a02ca9a7482e4c0163a9fb356a862bc33da3060e279a86461c00cba977feedbba177e016ec664ee372243f207124d9f34d9443f2b2f9a60ea4024c8d73330ea60501aaa3f7e07fe8bd847f52bb951272b408bc128a12fe2a44bd776af47d04875c50a6075af542155a194fe50c778789c0498c548eec7b1f74317005086932de2a1ab65310965e76406af9e5f6ada46bbed84d503c78526d36a0f5c0e639243c1746900a51cdc6d15b77eb5b94cd6a7c7e3f02882b1528519b3d5844608c71e5b9d1babc2150a6e6036669cb3fd58a16cfc0ffb5c32cb62d895f5e777ce360e4c02d3c45a9705b95f238a46326ba988c518c5cefacd5032dd3ad7fd096025937a212475feb0e08fd5081dafeabb01fc9731424fb12a0a0975680d995a341f80075e85f6032331b2a025c6a7670740e8a392871a4cb8d45fee99dd29fc65d60c5c729ab2afb7ac03f0acb079aac3ec017f0f132aeeaa741c381329cd79def27075d70582e932db78a82ec2b73d810266ae4d7cc82c5daccb2a2c0a2d0a3272e29d8494faa97267dec983c1f4c94a3e6aa18304eefa6e151786a3f70da5f62b8dcceedc5ee426f1e34cc02eda2a4e80bba1078d17fad76c6d972b0771f35e5ee1970d046d2423a00c4c4f3299c02c8f81723f520fa4ee62198e4d66a00e6141a9c8a9899d2f40ec31623efa0af9a420b687807caa97b231c9901e8ba8153dcabce71e62fb47c37ceac3f3f0813aa1345140deadd0600eaf18dd7449138de8d0e81f6d700fc1d9428c383870c84456e866b9b6672d2fbac6d5b2c17231c5dc3e7bde8085e5089d10589182faf45009282bd8a888998b428ed619e7b89cca7a0151c6d368fa0230212f0af403502c7e8e489b8f0d09a573cc3dee679e0da20380ccc350638320e6c69e71237d0c20e9521e2d045872a84e5c4ee6f51dbc5116e448f0392b1c8ad63925a48281ce06a0e6d79d36ab120a52d8e14ba678bb3301414cc7f0aaa2fcd499fe47051a508417d95fd60d14cccbf6c69025d67923309c6d01c7ea07d162e231e746e0384b24e217a26e0df220b1718b0346bb4c2ed19b1e5b064b406461e05aedd7e8b4e6320c76039cee280c90a64e487a2515cd9bf6057e060c320677e78138b63911c83213356274a1a460a38af13a3ebeed506dd71af644b328d5060ed989f0e0956b9300589bc6109bcd4db934221b2bdde2a93d0ab2035b246c46ecdcd0eee68c65fc01334f647b7de7e8a7197f0394dc27bacd8778e1db7c072ceeac757e4bb050e64e57e0898eaa199b17fa6e2544437bb9b0ff63ca590264376f90b4c3af0c004923cf3829761fe29d52fec11945284c89bbd472f133207d6abbd6aafc7e7c978443bb48d77ff5f5aeff0a7e69a085a5cec5e74ef4a48bdbc92300116364ecb418fb29f74d495ca682de56ebd59daa0423abc20648f0afa30a4d20de2f07fe980bdcaeffad3a383e4f0d8cc1219bf64cbb95c84e286223f0e2205803d7dccbcc772014f619a4157c0602eedc7caa966449bd170a50eb1f1c5e8125952f8ccea4b24c56587ebbfb7b283c112e1b6a0866e78ae0a5b0b4bc7628a28715494f55adfb86f57a23c5783016972c492665d23203ddf9ad8e18c54dd3bbcc606af23d9995e2d78132a284288749c826106b499aeacc34b859010ee2ef53147797d07470c740020fe110bd08728d436b46ed375e94055b950f976ef0d292fcc26f3fba4a92b28b105b5a46323a1b3a029260c5fa9b811b48cc256670e100f4dbef45f6bd10996d703c1914540eb549c599803edca3a1e55ea25b0f4c792c069751181f74aff49bd42c41e440e9b2dae767340cf317cdd66a7cd3a988acee59707b6f41daf969499e509315380db2824eaf81959fb150a3b96209f5bb6539756ffd6058ea297ef32c6be638d59e2ae73feaf8d1ef6df510a7645bcd1c2a689e8e95e0c474e34933715cb371d7e6397a4da66e5a344f1f3a4b837e49d08d25798c06ad88c3e973d05e2591b0fa6c71c8beb759af02f4606c8403bd614b0ee783ab2a175a1cc9f09e79ff20f023af876efa54aae3df989a56fb8f90fe51635f1785befd416b87843943ffab6ba9e947f79938feb32e029ec8dc1db805a0d7ac0d03509e81f66a975c21930fae949d7052419928d7e93541071dc0fe01e90f1e7b653e7c9ef573babe101cc831d4b75851b906aa2eeae3b8da0c15d2209ada404fc24c6ac4fbde916d3be16afdd9cb1f954a523acf609a34a4cd5afa3b3eae50e987d3b5d2f4fa9b46539176031256eb27ab85df80da0833ff0cabd42af081a9626ab16dae4ccc7d2048510106873853c3a5e10327d04d5c1e6486d9bc342c0657dee19e7bb99484b3d8be09788519ffda8b0cd1c8a90e8e8e83644fc9e529a1ab664944fa83cea157e282f5ba7ddcdfd870441df3e81dee9d226fa3ee8025808382125f8232a023bcc8ea76470b99af57332619c5295be1d9c0365af6b5616f03b6731a8071f4d9d74d7051e1d899a448be3515fb73bb30fb61760ce368255e1c4bbb5d108dff54d5e86c57647a961f56aac5748e97a837b98cefa75c6414b35c9cb12f17bf37064a09f435e234a87f3cab647fc5f7750c6570ff28d7cdd094fcb995103948a45669f90d93e3ba779ac4bbac2e3debc0dd30abe9a4f3bee079aa9a32e9fe4b237de5c08bd78b13e0bc3ed6a359adb2d7f2b630f8e8cd153f9f6c690b5d8edda554305a3d0e8073831483de92c2d59b5ac25bc764badaa1ec0f8e3ddcaaaa05bc65d8e7b8a7e442e69cd8193feac9cfe8d719cc40ac5b027e8edfbb2d035c35df4267284d1bed682e31c43b0fcf150c584a0126ff520c51bec4b6c0a08d6f6b9caa8e6183e3a3b7bdd13e9e590af3708ea47c21b780ef30f16381e36018e25e6302f17ecbb1aae024cc97fa8a7c439ca6134a652a927bf4fa679ab5d82358e063b29c2f515002a9543705dbc09e93790a6276aee8bd9e8246a3247534c916d575644b6a04b2a5d7fcd8e252a2d8273e268c8c99126b6c66a1fe324c6a28387ca390e55db06a90a8c752217447119301a629259fd90517f4255a9d6670e766305831669f7193ed3063a41b2044385737c956ab824780f80c2752139798ef5633cf377c71999b2bd77753878714463b04dfd622df331f1f4cabfb25d53a35954597fb80bb86332a1ea9d62fd8740ffeee4fd9f1c27250d36652bc13bbe7d910b31829b5025ba50ebf0320a74cc23a00f5ded2c607c89853cf63eccb02e74cbb9cd8c60c2a41cd23c3476036ca6d214f01e19233819a7377388e6fd80312edb4a3f1f708061c2e9e4514af2a7b50c5555cffbb16ede38827fe8d15ae8b8d82139dc58697baee6777f8e1712320ce8072e957706b5620a9ec4321b8a175b19ea8e950bd7faf6e26c858d572b6bbf795060a2c6a71c63a51ba3a1119a410d6d2fd9e41b167b0bdb5342c9a080f91db597025ca17970778bc5fd9e09d775c570461c9beb62d199a0d500812f476655ba4f07a678e6d072d5f8bed7a0ca31300f911f0ca007432eaf99928eba781209ba2639ba0ef516968519faf571789b11c34f381980d552fe43525b277e5da3bc20693b53c1a9ab1e257818978c42b59c91f4ad4e3a02a26e97678a4360d6eb3abfefca2199c8556cf7c4de848946bad8730db9553c2867c12077173ed6a1d675c0ce7b23b6ec0f443caf596630293a82d553406265f9e47bab1cc8f8b95700381895ffeb1c9a220cd30c1a249167fd9b72073112063518b44c0d5afb4cbf9a415e135335b85597678da70cc95e84a28840369699af01052a9008643bc4b04760fddf5aadd97c6511cb568f846dc56f0821cd29c7e4f48eed4885b301c61e6a22d0bc864ed9495579c18bac789e8040f118581bf09f4bd8b1a6a012610801674872af95580cecf9853e2d7b431e2abfd5c787ea84827fa861d00890ea5abc78e2567072393d860cacf390d16d06d08469b4c65c8bb7733aa56538f2f61342b936d348f50d37890cc95dbcaa700e4ef1aadc3fcc4a82604d9e7544daa8852c24db201ad492df7802f010b629dde3f508c1b642e1ef2d99b4d7abfb9e91a90245adf2da2704eadbec5a3a30f7b112d2e7a5329777b09e5bd9ec013def476d625477792e0475d6fb0d48218a17dadd18ba37c5a82408527781058939be7d2eaa2190bcc7a757d410eec028449cdb3eb1f862bf4a68f7941e77264d5928e5c973d41f45864fa207329ec4b5a4f988455094bc74c10d4cf30442375b45c0e3377356f7eca488102fe544a163370b706b5c2e95a6973accc9012df61ee196790309751d683f4434a669f22e490121b76815e6087ef8e7a8c68bd88ee208bacb88c3470110ac3aa2e07a9c8b56390cfdcabe3016efebdf1ba50a66aec0e9f1f3a47d991302b589cbdd4dea1c9cbff7fce35824d3c8b0b350ca2049fe0d3727a16f5628631486d00f1cfaaa9b7072037a40095e679d5a332be7183bcb6e2b5edeac1f34e6dcf5f50ec2a8e283856d7edba1821aa270983223e1865e83e09e8ab843fb5f93e3c5ef164f1bf4e673c690351a9020c8087cb238062571c53f5a454cd4fe0651e321283abc019d6daafdfff4412cbcf7edc6f7804867671ee8bbfe4c76e84a9e36023a08ae1636e888888b91c24c3bf0b386bd6c5c5281fcdd78ba5e5ef81a6c5548576c3da4bcad44f36e136ac4573955507c8fde1875e2cd3cbd21371f4bae309cc128dae4ea3d0d9bc5c27af7786048853b78b85057a3116cdc77ee461dbef022f544ce70395fad391fb5cfaad56856fde39537fd0d4ecde484aec91417bc728a1074f410bd5a7a76b8925a58f4a4c60a4f8355155fda686267e7cd2c2258fba6bc9d9fec696372a39b679a99652b8be18ff6b4c642569013cd8c11f695699dcb2679ed5185ffc8c51b55e8d7014599b864f130fa8d1e6726f9fda85bfebc64d699231c0b5994ffff63300f54389f52bcd427979b51c21d164752e0ef79c1f0352ecc8b1777ff46d74633a78dc7b47c6773dd01506f528d0a7d5430270adfa0918748b518d9115c08746f12c930f002e193bf1b4780e04a622bc62ce35d49d2ede4ea50bd42b7112bb42611bfa48036e1bf959b155cd8b27dc585e1931de2914667c65c0f43e1c5c6d2e7233caac25b6b0519d3ffedae520a6f9e851e10a92ca6d19302c20d1f6f73f1e74fb08c482822b723c645ee07884a2321c61ad28df1960e113b9512051eff788523b49dff03bb265a4de49838c9c116e351a413cdf6d2529f684815e32b92396ff920601ebc162466eb2ca10926abe11018222336fe947d47ac2fc91b4d52e79e18e78de201dd1a51fb1706ca440c222550f92c40824c5f423ba6b45f239183257243f2608728fa8531c6247ede3c772f0c8bb646f22fb3022afb921fd2df0759dc27a29ca81d11e61825cf5852fc73ed39f47ecbfe811e49fd5c3c241561a909c174abf15be4b110688ce43f416ede8ed327ef967211681fb4e174a3bdbfd7f797401b6a3c55c7a786f825be13ca0d3086f159eb9e242a5332e5a41be949778cf5606af05061a11368675fd2c06e73fb05909d9dab7e1d56517ae792594541b76adb5c97570a6542afebfab6695a46bee10ab3fe597d2c9b69a9842fffbdbf32fc768f41687f4823234e8a6a887d50ff8a9b4d8a1c2a770604b2eb8fec4832a5aaca14b862ce696d106e789fcce72cd13a59c14107871a43e909dd357a3eb0720916c840cd6fb97ddd11a45b910257b601074d41a17bb505e6c3e42a2996ee81108fb6c42162388f1ae2f7c3f34f9812bec9013932d111e03d20f29468c08ba635060bba4d1e4b8f834a16de23bfe8e284a859664747038f0ab76fcc1cfe3d0f1e4c71abac02d1ff877024828fa262102e6282d678473f8a7ca721494ee76c58164e064b580262a82f299d06c17b1cabfc6e78bb5e5fc31f026a24c03dc777e71c04660e0b6c65f3b1369307f88d9a23b66cf7e0107ff2f525f7c8048512132dba7ba6b36fafe8fcaaeaa43a59c99e254831738c54da53909f79be6f32fcc561c8910623bd5fd5319e4f8f595e95784c78fe94c192f9f3f2cf60d58715e6572453fa032bca5d77d004e96bcf423ec446c0046e4d8cd4e587c9424f34ca306aa39d41ea9615ac5a47769cfcfd233634cb9c22f54ceb2f77f1cd1c6647bc6e91b73b16c72a273f6e02ab198b8fed5590fca8e5a4aefff4707bf4397e37eb93ff3cf4ee7a3cd93f2e4a15340ac600f77736923c3dbec85b8eb8aaf21d62a9a187750f8f2fdd8846cc3f51f95ac8ca7e015880c9e76007dbcd8ebd4bf14fc4bc9978c22db0eae72a9332aeac7abc434b4fd3794fe7a0345e13c0052f625b8d0e31bebf395675daa00c63b4386ecee3c3fc8a84e040fb0fa49bfa3fd4f10b99f6eedc9a3cc4684161145ae7c9c215aae4a25a888a4c57e0b660e81666222077b2879385d5a905560feec764ffe3b9d92b36f6e25730d223bd2eafb1213f43c946edc65507ff5381df2da7300b37ad5d23df6949572ceb9c365b949623e51c1f541e88edcebdb2b378222461185a3c6d7abdf65c60c3d99eca299683258947ef1e32ba580f08bac98b325d07efb6843ce641301b6f9ab2b0d248afdbae6041a25496f3a993df475b1be5ae96f2032e17e040b4bc944295d131d6901247a6f9b77bf10696a81cd639d12a587af5778d52e2cc1cae3430c9369b1115d4cfa4b6e1e3f8c605fefc44ed2cf4f2ba36f44f2ed826eb75b699788ffc2484892776e270f7161eb6b294a251810df8221965f7e7536dcb28f39b9b197be5309338933c0b983627d126dad98c37ba9471862126b03616c62cc9e90f6439881f98b01209d538650085b1af062ca24b76e12df0a4f653cb88dc5ea92b1196118c2bfd9746d2333f9128c5c390cce7631feacd9826508ae63e014fc69cd1591ff3d78200eb35e79f5a6489cc57f287383a1636d305432fd7a00a1eb832b07c240aaf0f74021f14816879e292f0caaf3c1e0abacba1bbc6342c090c5caaf49e1254aaedb31ab6a56137ebd7af617507ac34feca8fd034a06e217c4417531afc4d45b334b54f22846fb1a13817ba407380b05746d3326f6a9c3cdf9efb28d59a25811d01e6796101d84c4ab1ae658d53c4958354ef32a8b22d63824fb8201c7073605e838c47ef4c20fa440353e9105439be41af44afc5c1592edb47fdf0d2edd33da0e59893b0444a951d1b17036971360dd86722c8c74c9e843b43be002e8bf1666724af161c2a7e5c67a7d983075bbbca7e3a45c9774f2e7ceaa151cad114be4d68e4c73f018f4453d3d63772d3056b8fc8d9a7b631ce843f1f506a2736e10118894212c48e60d4c3813487616c48290639ffb1761973076daddf00d6f0206362f976847c4dd06ed153c3608bbe8701f4844c7752788df3af33661f0a955ee03592748b68f55ea64e736d94b34d3bd288a003ecefe7a4d4899f7b458b5bd7ff3ce0053c5e592060e52503586dc51f51e382685aad3485fae686ee407c652da9a5a74ef221f0429cc646ec387570c7b5ec0e22f5c6aa4fa1521877a6536b2a0902a7e218505516f05b2e9af83bf008a04b9c765f7addfc05d8155231a04ca01930490d0044637f33a390c8af51c346c71046f4c2cf5e6246a986d74957b989336ff88fd33f12ca3916cd1d493202785fe3b92e3a59aaaa927f77a830de0609316f91e207ab4393daa0e8e6647a2d6fad4cf38f085c30ff6507685f63891c0f983a46b3fbd1137a49a03c1bc57f1de132c2660655e97e12550712ca087ae46bf5d5d4ec80f39dce597c212aa868afe68df4730a8e8075169e26827f2ce5c06544e07ae80ac9f047f42ecf32e9bd4d6c3b69dba9608dd5a3223e348d278d26ffdfde668bedf1c71704b7b631b43bd22258ab15da6edece1c1c1a18fd35bb3a71e594b06b4c187e0ff16ed34e3f13947677ada95585134e7ee4dd4b971be88a1a6676d8071237152ce5788c4b0116656b28ebcaee308d876fe7653ac194708661e9c216d38e7fb1f6cc5f582eccddb5e4579f320a5f0b8c381457097638c05d00203c8080749065dd4e18a89409cbe2d43fe40d91ff2c9715c4739e62c1cb5e548847115d9ccfa417c837239e0911196d94890325c9a42be1989e60039ea85f8e2e05e73f8288ee73214f26db5a691f5355d116aa044379a53d978ac56a8ec8298db173f975baf99668cd8b4dcde695bf4d9de9d2652d4d8923b72acc0cb7f79880e96a60a5829d05e937f231c5cf6a84a7c3be20a500d742745859bc36714f3c2b6698853390bc77e297d16c76ef0fa3a6180f36fe85ad27a8577f1689c590b380c335857cd8f6cefa3543eee831d440472726696061673c6b543353b654095b8c1203feb162bf7530e3f8508c3bdbf2eab2a0bdad4056c0e4843791e23738a62ae26ac0ff7595c92b23ff2c9c60acad3a19f042634836932e203bdc95b96de3e6e5b8fc7893273936e39df9e7fbb55000ddca966cf6291e2a9695af9d88eab64c85f52a7fcfcb1063b582b25974ac0fd683fff06501476c2883684084003ac53616b880e75640821fc702b13649b325d5f2f10cc0ff20ae1ca1819baf44e0a86f522f2fac77f3b9920cea3ef92122cf4a982121e42cb5931a003e6308a0770ed44e323d63fa58477d5e26bc9be5cb260231aaeb25744ce02a427c2c807fb8a843d4646253a86e02d0f3694787204f91d8071fceb81578d353ea0f43d601cae583bf51d1d1d11abcf105ae21c76e05f55d0c9ecde434f6bc12ea51d89c8e339d53a49ef1e3993e95a1eadf0f73189f93970f5fd9d2be74c13d1ae83b8174f55eca4fba017be8250733ba840255830320f2e4292508e07ebe2f12067a850ef5cffb9dbbd0a494881110d78c72ddc4a77669660406c1c3c0442c495cf58bd872a0c67c9b0435ea284218a16fdd9c3426b263c76d19a265bd312e45fe103df6ff5c463bc9caf29dd8bac1209f58625045c3166fccda6350c9a7b8b8111baf1f9b143a0da1179f884f82aba9ef53898b1d00323455d8dd1c6c8fc5f31fe84898525987ac6bee417e7fd6856c23b105944c8a4f104e525697c3096e7558638459c7215db1185df3145a2d8b2fad47e11acb91fed5f5750ac3ea564a83174549f805dcb99de930ed5a769a36735d705a54312d3d3949d5b4ab22de5d93a95c786d00b476b6a82ff6141437446708dcb99f290185eeb2ee9ab53abb0859d58751f1184babe12fa3fa648968b606dc32d8bea618b0689b56d87e9f14762b9cc6598b34e3dc8c34dc12ea37d24d10f23e090e65cbe2dec66ca9595bbea4c7326d11c2c16e17ce7ec8875301f9825a9494727107dd4fb00878c929dbe85f53a095ff107930416d8a443e990442b6804799d6df27fdab56ea2e1d51ffdeaf52b4e4ed81047100b2352bce053889f423372d8c7c779bdd0ce6543b1da5d877fbe71c749df3300503f02587825663f223bb7d758ee91c905eb29b872894cbda8905a345bb05ea779e1860a59dc62f4e897199e082d097a9680d5f79a8c87292301b3f6ec3a782c5d8ae263755c35aca539a5a9e208c85099ee767816a8bc57a30e4270c358c98e4d783f871303a693fbc6bb6e00afc71156b3251262ee5c14f9e26b0d0853f631c0576224665f48b03418ecec132a8343b1038d73cd4de5c06bccf2ce48f708d085f9338960e96203838d5fd06182781d6340ba2fb63d0e2ea8e1650df02201c3c6dcd3f4d05bb9388c2347ecebccac2adeac4df79b0852d27890b0f24ec3eabfb7f7f81191a1d0042e447d1252552f5738434c4b06b5a078c1ed51dbc10678dd13f48c6b5ddbff73d89dcf9a949503b9e602b1eab6a27a30bc776d440a9433960a3032bf3bce912b986ad185a6f6dfb64ffc138dd00658e30d7593c5448dce63af9289e1614c13ddcc87dd42bd567e4d10036874d0427da71fc5d77b2c6feb770dc3b05df8136b80d305422abd0006d601fe08634c4bbb4bde06fa740cd66b74cb1c6a6048accab5154c1423a1373bd5670d5745d6e2864917b19dd4b31040de64bf66418a19d520b6402c3369b5dfc3ebf88a6c524dcb41a10fc2ebaa06eca3091f4ca5c8f69d7f4087e7f2f5f06803a32eb86a57bccf92081a56a8ac0ea22cc48c16a4bb8c0efba02e170a03939ee5f3f588dda77797b9bd34a85964fd8b932685cd3ad5371cc5b1990fa5b6c1c7d5c66c572385d646f91a56cbf468e963a3d65cc416e3de6a886f1a4e680b4c2be1c8c0de6b55c7f6fedad4d344b9b3033efceaa71ea2bb29aca97fb069efc4b459660a222acb7deeef46b225f05718b88c83d47613fd14417e868913401d7a34004c75631ba585c791cb708c975940f6ff23a666cc698c42c54b704cc553464e2b93785e3759877dd4892233c00428ad8b88cc5bed56e4205721e325f40e0fa14c1adb1daee6f8c2be66317c05ccc12b40d2bd069f10d6be53d9b9ca86c92b0392d04d679b09b22d93509355c6cf38010b6269f544d028d228bb50b92e64f0acd40e326a29fd44084da1d5281dbd7e50b3669454b7105a23b28d27bbee6775b28cafdb73e0d524cb0491cc4ee19d38dc1384930eef9b9c6bbd073ee442affc0d90c755c250f073c0cca26a03ed936d941216f763df7d5c58872c3d64b43f5afcb3e75713dbc9ea28eeceedfc7e927a0ad4eb6d803d2a3a94b4aa8f7f691230f33b9ef4332006e3ef9321385ef935b2c49211f9426c861ab0a2d32c2de6322e42c116746f52d8ec6e48b2326b91eadfd11db390c6d65870994dc091c8a01972665dd1c5d525047221e24d65b765078718916b5f8bbbdbc08f89c8f395b1ae6dd3423c8b4d833712164aef89fce2898ac65edd6601404ec593a0d9b104bcf88ac81bd8dd1ec1fd2a6ff788e3775d744066393bd8e22e24839c0231f63b0fb41929a363009bf46def57111e5150041fbb6fb13f30b672fc414399b189bb65db63907752676059354b17e415fa5caa7f228ee87b7572c17e542f945ae2b4051f2ebaaaa4faa13ffdc11ca55370e6c6c85f9428aad26eec77b94d433dced1ac0921c68178609b45249c7867b10afe94f8447279da9b8bb0cabc81601a58b67866aa8a558318a7f02d37edf2e0b7fea12c6b659a788ece52847ac05c5f4e865d71a7cd48dd7d872d0e44498ead3612637ae39e6165fc6ec5937461ece08f0fc58320b7e08a4900ba40963d80149b5817c93f243d246135a398c9636001d80419e5f185c79b06ba4e77d0f474874e4f7f68347483ae1d1d326c01d788ae336b783bb801d9b57c3f9b5dee943ccda447070f0e6056c35ead58ba9cafe67aee3723876313ac06aa4a73dcdf7b9e1e8626d784b7259378faa57feac5edfea71060bb9871aacc116bd4325c158d8af44703e15e8d50a288d4804836907bbdd9680b9fa4e250ac201d523cd458e0fa4257f2dda7e844b3ddf44f93008363ad2fedb178dcdeee144f6cbc74df3da7d3935ac5902c74eea1e2576394f08a75078c217cd911f705b2e57be7d0e6f14dee9ef7cf5d3ffd5d92db03734e1d7c076f1013908388915eb44085d5746932c4de8e9cb3c5e4921b0409e7fa21dc918a1c783f0322e19f487202a50e75d14224b78744d7a982416e731866f410f826345fe0c09d19d1a6c7d14eeac4b11ef73928bae7d022e730237b02b8ae697ae9329c3121e77943e29331ba8c58533b364cb94a653ccadd37c8a055af4bdd338e8091bf755bfac3bcc0935ef975ecbaa19abf015c12cbdc54f64173b121cc24e4d6ff1a2b5bae372e423ce944d11648536a1f9d1bf87982add073db84e09ccd98d78bf76e4965ffb4744d615bc5a2098ab4b88bddc94a6e46c05d0803499388f035302ba408afcec24b36203a5e150347a0960a56ce8797c323501add0e85f93f028d603278203d0e67215d2bf31298df8c9b152cde22e69bfc06939d2703f891d3add337ba1425ce50de8e32870b7fce581e7d194bec4b4bba8d4b9e1461c7d04c1719ccfb1c3707e517645ee7794dedcc4a8c1f2285962c2a1f5d257886b2d432800d1b977d44d3fac92e856df2a752e6d2095243969f7e5ace93488b3dac79fecde8d1aa47cee70c1a500296ab56ca24ecdb720b9f315e87841e22619622616c242854fa118142ef3de983c807f3971eed213433d5f63911d013e8fb14c1417f55317c1709841977be7608ebe128eecece2d18c21825930b96dd2fcf8272db56e2578bf9217dabd6a5161a3591e4801ef5200d2274501affe9ca461561d56c5494da56e6e8ec3d193b153ea18f320800a10a6beb3c54a23296c37c454dbab3ec46c60bcdd706f50fc1ca008ba05aa0837bd8c819476905aeadcdeadebf8df9688a11c2672477e5d72bc5a97975f60a75be7531eaad991d3d61485e13c7a01d47f77bc7ec32cccbcd4190b945443084ab9dffd38210bbdeaf744b7581bb99ef40a41f0908ba41e5c45057aae9c25a22a634ab050a1493ba9a8275b10fdd83085fb708b09663fa11484889fbfb6d9fb9736097b07b0d2116fc9c6548ece74fcc9ed44e48c44bbcb34e05ec9f5b8da7056e34c5d36915d1f79024fa5171141744930b4bfa2640fcfd6e593fb961f68efad768dfb057604a6104544756818226df3baba724033bd3f86b3731d61b0b40140b64a030204a156ea708849eb1ea1386d0e50f7a27b1a2fe73c83f1719157e4a6954923cda208026f642d0b0e2385da7c6e0477f4c562e16541afea1cf94314a8e45c6743f531310a718b234c26a9514143b46fed2a76a51a7ffd7f6d016122ee504528f8fc4a80781bcf893737f3110265efae09add52c59eb03a8a293663f08733d01bee9c29adf093d0e6653bea888276bc406c5a6503c13c491479a7a3049179f872d4036e21c6e0b4030342fa0586db367c4d1b391fcba54dbfa2b472ad3c9828b0a50bf24fdb4749d2357fae91e4aa437159d7a240c294f6f5b1a906476998ba16f53fa9cf404e906656d8cf9f217b41f8469e5c77af0da8fe70b47415c66e4d4aad911ef43efb582e8ab10fdaa450d7ddf489b5a4666ca7500202714ccdda787205425842ed90a6bfeeb3cb2c0c14d8226d3ac15258c647b3adad14db452c89d8a7f322ed21bfffbeb5288032c707e0f21ce13eaae1a409ecb5662f05a2b6a7b73b2f1200855f7b80a10166ef667b0c8bd43e531dc57ba72bb83dd5f3f78a96048ed26753031517d161906c573601e08374f93a322c450d241102e321a469464770f64f48eda690bb8ca60b4d0cd210c504b36482fdd8168943e0c35f45b519aa27f7f58142ffe5df73132545b0742280bab6044d9ab9d82c716ecfd006a25af30caebd0b4de87e5e05ea76f41b8c225a304255fc878c4dc76ab5297f410543602d3cc8b20590ab682d3c8aac1864b13079946495412251a3228a114300a36f2122195dc8da3f4883319fe03e2c8466d14098d67208d34a4362b41a197e27b7d47bf16c6feca97a4abe11b313a52163ae8a120c96833e8d9ebb335009c1c13a41027bc0ff45a34b8496c4a9bfad4d723c67ed8478537b248ca71166cfa7c5e8d4da105720fcfe077e8977c90d5ad75e5673c361bbc2a2fff9eb735da16297e45561dfd708157ee8636370fa5eedc0b1bcad3475bd57ab69710df2eaf148f4790a8d806ef716a7d0eabe3dc2273da57fcb6185be523824713965cc2d93a7d84f8e2a956cbae13a6821d99031cd1eb6384e788233616ab798774d50361da50a39c264fcb687a001d27c9b9ade8277463808c22c8d2521ced81afb066dc6669c01584d7d41e0fc4ddc2b5393c8e1e2210d65bf6f25d2d92f96d39ce22fc375be4504c294cd5a193f8d51c64f9991e7f11db2cb1a1a06f6f7923dc6cfec224910ac71cd7c0888e118fe20565af157efd10801c14f931872a3c52560682e3793c0e266082f86397ccfcc09046c7814e80c5499048e7cc59f134d1040b2743a0ee7421b6a58f3896b518f3ef8575bc2c226396aa8176ac38e1e0b6d5826d57fce28d5b94f42c52c776194ea3f0995c4052bf401e001892835eb1032f0b6acd863d3c8de7bcb2d032313c0145413377eef5c3259c8bc7d71ad5103d37ba74c5d9a9239afb9275df4de5946604b95267761a2ac88d37b87a93a537015b972c2acd37be7ab006bac30879cf10262a6f74e9308ec4dad0aeeadce4aef1de7997c26e7dfd92fa77e39f5cb3967370ca55ea9573953d565e6ef6ce377aef13b2bbf002e79b2c5c7e645ef7ce56f875b1127e011237ae7144b2f4d333b96d0e0d23b3385ba4ef08d3561eb5145effc45a3048f392e307adcd03b676131c22b451b8ea699ded9ca65b212f83a783a783a783a3a5a7468fcd6e1faad33e3b78e8e8e0ede08da00b11aa11c9b72466f1d2b2ac6aa701489d1b6a6b7ce3205377e5059316685ca4b6f1d6606362d1628e278bc68a2b7ce57076ba88858020407dc9dde3acd0d6d34448cdd200b3ba1b78e73ed32ad057ece33e799f3ccc9f992939393939393137699c2029f2846142312c9a4bf89555b442291889792b84c2989c0f677fbf7d8aa4daddad4aa6ddbd60d43a55c2957db52f5adbf5b19bfdbadc7317eb7cfa51637caf0908091f2a7770ba20c101155b4801cf9a2775b1508e4ab8d8e89da9dde6d332ec51a352f826411f9a2776be5325909fc21de106f88371c0e876e180af7eda1dc631f2a875bbf87307e0f5ffc1e829db953f35a92814bd37b6815224decca96892c48a2e83d5c0eb9991883060813237f7a0fc754296534c78c9440a3f710c5ba03c2268f051618bd87415a5e2fbc38a350fdd07b487699c8021fe70f3771f41e37717070ec70f21e3b8e1bea6e38728f1d874acdcf6f9c2aaddf385b59bf715cfcc67946c1f8f2248d1798df0abd71ac8e445099e993bb818489de385f84cc283342ee041817bd7198cb216bc25ced6581d31be72b014276803943c349df98de38cd0dfc41c9915622cadf9ede38ce1b97e946e0df74dd74dddcb8f0f97d7383f5fbe6e6e6e6e626eb9d383182c519b0207adf301f6fbda8fb11e3cbc9a6f70d567199b08ac017fe2d857b78d9f7d8853e727e0bab5afc160a8542bcc77a4d2f66ecc85240b933d35bb862cf8c2d506fee050bbd855f5b82805b023ff8a717d40beaf905edf21e7bf06f07e5cc583316d0c93a59a7df6367e5362bf780352d1a6323c8aa28d13bf8e5686d32b4aa7c9960a17790b9fc1d140b167f0783469efd63edc202c35640b175af7e8f9d2fc7981728d8aad4d09bb502c15d8db2b32d5758fef466974a5c7cb900b3f2922589de2cf345901d49d65c185912446ff66b0645dec89401db6282466fb6b94110401a65ae048e20a337eb64f19b7daef8cdaaf8cd6e3dfecd563d7656899fb0eff5efb1afcaaaabdfeb568adf2b8adfebf3b1af6feb6ab7e6ed556fddb383b1460811b4a5de2b93865913cc951c42c2f45e979f34d186ab4dd3ed8916bd57e699e598963432828ce9bd7e4500b02ccb8d13cd2a707aafcd3628d29a68b69861f45e9d8fb52e13aa15f8d8b7fa876ea5477c5badc3f9ad566d89a9cfc7aebea52a5d0a759d2a1e092e5398c0f404295fca97a676790f8556a57937bfd313bfd32db1f4a943ed2e490b2836cadce99d5abd881e6d26a298ad25e9a177ba4c62c0b5c0c7588fcf0fdb3d5407f808f58de5300462b84ca86f1470a37b61d4dfb8caea37dec2267e63302dcaccb169eb0146a5372e92e5448a355d41b4f4c6cbf700c7b797e2ad048a347ae3e6e3112444d8a0ab52c24b6fec7c8c6770a5d6cb84ba53963e2a342c44c4b0e83b16488aa8d1c1e6a7c3c0013951c6064895dee857028c2cb590a515492306ef3061a446959736217aa3ce67b28655e56a065c5f97de68536fd42ef512bfd1278947ab7ea35b1ffc8d569179ec32b81d846907184ad517fb013094633ce209158152d5c0c80a2a39bbac2b3c111a2b876c694ad982c28c16bdf3df6759173360726b3ece6060089c99738c14392c3a2a854ac014316b28f6c0dc35d1180ddc082537baf6c8e8699e21768f3a8f908c212b3f95e1e17ad49ff8f2e6b17ad425b8e87bd4a7724ce1c8bb5857ec7ad48b5b43c5ad471d4a0ddb840fcdd2b39e434cb251757917958f3a86193b7b8f3a061979efd03dea99cb8edaa39eb7e4bd23f6a867bf1dae473d9fc97bc7ea45de99af44def9f9a813b58d3dea444df2cecc475dca46be7ad4a56ae4ade3a793f7a84fd5e5adf3f6a8eb38759c8f7a541994fac62386a1841e74c01e750f25f2d6d97ad4a74c90c83be7f9a8bbdbd8a3ee6d79e7301f7509cf9cab475dc292bc897e50f21e750b4ff226be3dea18bef226361f6d5b71447557555555db54b07916c4b34e24265954a9fca0b7c464909854a37a8ce44d643eea165810af1e750b2bf26efd1e75e792f7a8b7742ddda31ed5f584cab9f6aae37058a2f6a87360cbbb157bd48d692dd7a36e44cbbbb57ad42118e97bd42110c97b88f7a85bc8e1f6a85bc091f7b039ec4292f770f9a8bfd9dfa3fe6579e3e83dea1a62c83dea1ab6f2c6713eea503c70c01e75a8afbc71b61e75e31e4ed5a37ee377e3f7a807e1509db48db1f0aadf089138f21e75e48dbc6fde1e75a9b2bc6f9a8f3a8f91bc6f988ffa14919bab477d8a2c6fa1dfa3de9495f7a83761e52d7c7bd48d81658fbab14ddec2af475df310663deafa2b6fa1f2516fda11dc7bd49b74e41da47bd48f5f79079d8f7a5392bc83cb479d08759e31798f3a4f98bcd9b747bdc396bcd9e6a32e0585ed7ad4a59ee4cd2e1f7556c92a1ff5a835b549a9548e685fed79150dded35df22a14a5deab50d2ec78d585c4a4ea6341c9dea36e2149de2bdda36eec527bd48d39f25ec568e4bd6e3dea1b5059ab1ef50de8f256f9ec1ef5292a79abcf477dca4e1d7bd4a7aae4ad321f750da85e3deafa2fefd4ef516702827a843579a7cf47bde895772af6a82fbda55c8ffa1294bc53ab479dc9aeef5167aacb471279aba81fab329196bf479d284bdea8dea3ae9f728fba663bf3eb8a2a7f5d1d89a1b052a9542ef5ea4a4dab0b53a818703dc1eaf18405972c7a65c3e62dc75c123a135ef4cebf367936e9590f12932c5484bb2023bc28955a75e185ba5a7596985489c9354a2c85e211e311830acc9b47ec51df3ccf479de7899f56479dc7cdc98fafa15f5de511e369f2c83c6af25651e7f1cb45be6bf7a817c564c04f1d99ba521394b838a45fefd39deb9154d3a847b6c85b7de4f2ba29bf47f9b7420d30a0298c1568c831c837be542fc54be9d2b7b445c2f9a82df2cbda2297f8b02dd249b0455e699152f66e5a0b4ae4dc9758d3f97cb31ab6c8326d8bdc8b22b6c829392d128c4e8b64935b64959d16e9f780bfbebd3cbba0628bf4c2d322a97000efe13efc87abaed49e1699e609a1459e89d022d3f624b44839f4deecf8b4c8b8092dd2cef97ca3c3d363feb4c8284de7f38d0e6f0ba845921906b548409f2ca4d022e9845a2497e71b1d9e1e1ffa656c917820e0535a2d9fde22d78e2d526fa8453279abd0229bb4723d764179c83d648bccb3d0229fdb917b4a7d4e7f442df26e8bf925d674fa15b5483323b87df7af2acbcda8456a396a9175482db2ed2da945b265a14f761f23576a916d965bcc2fb126df528b44e3175ae41f538b5cd3d422b708853ecfdfaa1b861619460f8feecd33b448351a5a2416a71609c5032ba51f9fde8ddad02203f930f6c3185b61bcf5a9ff3cb5c8be29ace23c6c87e5b09b5a2becc93e502db2cb09fc9456cbadb7a816998503a51f9f1e5e9351541387166905ef3bb448373f00dacaa129eab74faa45f21dc07d38d522c584f0c9429fec3e1e5ae493283cba37a3e18716a99637f6942f0b7d729a62a6046e0c2f72a82e33f60994e5d4f1d0565f55551fa13699fded2940ef1246dfb0ac4db6b4fc7a14be8c1fa27476609f618eee4d0e1009871a6f69c15f3f3d06ab967fd1aa52fc50056cf2e9315551b42a137fd14600fe700574f2e9b1bdf9e25b9babbf6f6db47ec80252f9f438c4c2c3da0b02e67d7ad4c16a62b90901cd7c7acc5858374fb7119f1e874f1ca7da8a4f8f3a5fa188b359d686c67360a2cdd6ebd3630e1d1f7148f39953f6e9315b31dd3e3d0e77d046b0fd451b51f6c32c3666e539dcc85b15db69c3e5d32371f9b6dc2b7e81b53103012e6f15fde241995d24bec2326ff5873ded8a4f8fc56573a906618b8bf9e931e78b4a86117e2c954b2e54c2d8a7c71ee2af422728f4fe3a4171e6873ecbac2707194b2b372119790b873f6ddca7c794c593451e90944f8f41165fcda0963da24a6c84ad7c7ac47910732885963dba40065d1e8494a150bbc28fc5d2d8b2c7137c40e633e8f179cb1e413082b340352ff442efd8b2470f38a0a4aa5095b78ad796f8f4287ccbabb0624573851ab24db55658adb0a05441a7828fa8658f1c28bd8486452d7b5c0036c2d8956120a818b5ec710007508ebd92dc7d1eb5427e55fa3d52cb1e4360238c9d4af941c430296aaaea39ccc85b18a5b41ed957e1f61fe0172eb5ecb1c9e9c55760d1f4c30b353e3d06558ca97032b5ecd148c9ebd323cf83b0cb5b1d36355554a9e0c270f6e9b19881aa055d0b3ea10647d63d08b9bc85efa4653d02a92e7c9c678ff70d4dd9df37346a3fdc40d5f7e971bddaf3539f5af6e8137406c66ea947de42f6987ba8d47c7afc79a1bfa8b64f8fc2b1372187b84f8fc1ab2be6ab431f7468d3e3cdb3c7db6406925f8fe9e7fd502acca747b5ef4a39d592f9f4187cf698c2eed5a10ff0d043cba289f0fb0a23f2167eb87961106d44915f8febabc77bd666caa747f625b00d33c4e978081cde5b824316071879ab6900503618554b7dd1d8b85969230d7d7fe7e10af4005606688db81d7e9af5598f400f5865a0ce30a257b40516a0985e8fea0c235a789729be1e1dfa200db63a5d842d87310e342aace010a31572c161884e5b64e6ad66f5aac452d300078abe78c3e5c095b75a6c85b62040a970b5e4a36844425be144168afba014ca9a40a5a88c02083863cb412b6fe167d092b7f02b28f3167ed1072a640b4148dec2e7b045c4aee85c9817117a886629d1a66d2c097ca2d963d3988ed24206981eaaed7a44b5c64e64e915bd2caac58c8a4bb3470b5c7a58d456a0ca5b7d1051f2167e0639a4f6a6503240aff052f8d034c04188e895070a144d032216bd0e5dbcc1439bbc85cfe1c5527b532834147eff41fa6117da0a29f216fe509bbcd507312583a8924143cb01c45bdec2bf291410eaf8cd4a17a6c631d6f0e901a14301c0792bf4919516a6502bebc77b14c055be8fd7e3d5972880f455a856692eaa15e2cb5bf820e2f216fe5060deeadf14eabaa5c5e1e9e19cbe9e5129fc108278688bccf2167ed1917cf3ead09ec1a7432d91141f1fe39d9b7b84557555d55555d3344d2fd4c54ae90c9f2c34c21dd2955d57765d5555555114458fe8df140abd47a8dfec4c78d4b70ffe4bf43406bef8c8d94f1195c2ca160bd1b9185f7c445174156223badfeda7970f67154d9943ec6178ffe75ee39098e234250a000d40ea2a7a8df0509b53a862541d4ad3af4fd3db0175555585298aabf2abaffef00e758c52544dd37cf6b7ccd848455140617ac34ab0fe8e7b05489552afa85f85a17d82af30dc407f86101840347d60f270616a494aa9431207a4a82328a3a7a20d8ebd032a45e4e4d83f84182bf3cbd8db66d906fa8faab0cd3d3e418e34526a728a9aca8021a718e147688808e94286a70eea87c0f0c1c39454070e51504f1b9c9ea2a650a90c1fb05f625e32762298d887007154856deef10972a4915293531486a69c62841fa12122a40b199e72407cf0d034c52475a1c31207a5a82428a4a7a30d464e451a1c7b06548a2883637f8a42a5304c717569c9d875985d203e7838aac236f7f80439d248a9c9a98929a718e147688808e94286d5c31453070e51504f1b9c3464b8d0e4844a35452db7fa32f69cb5e5614aeaa80adbdce313e44823a526a60b39c5083f424344481776a43a70b810b504a5f494b401c9e948835186220c8e1d0995226a72ec179a502926a7c78e565d99c9d88b5657521d381c55619b7b7c821c69a4746129a718e147688808091f590e514b4f1b9c3464c0d0c4849f90179a1ebb0bb051aa6c93b1f3c800557288823aaac236f7f80439d2684929a718e1476888a807ea698392539206a40c47188c9a8a981cfb102a4574c1b113a152169646808dd20fb0510ae1041f403d6d38aac236f7f80439522929a718e1476828d8e26370835352060c4d4c17841c89dd0310f480c9d8237000041b9c341c55619b7b7c823c0929a718e1474882860c18909a8e988c2e142d39f61f548a48c9b10b39f6077450eccbd87d38e84043060c4755d8e61e9f20a4a39c62841f7c1462683abab0a414c12708fb00161026639f7080056068623aaac236f7f81c19e51423e0b4f8f8c37461c948a928c9b1177b22f8a05247418f7d0a006b3276a0100060bab07454856dee312aca29de2c291521e5e41e54caa829ea4bc61ee414b5a4947454856d2e22cac1470a49488e5d88834a111939f69c8c4a158da0e7b123957ace64ec42464a4948474755d812e13cb1c5471cbfa8d49163c7a894910b5b548ac8c72128337663901f19151d55e1459936fb5ee4d859548ac8b10b51290b3dc5bc8cfd987b8a8e1765c24e74c42813760b471565c243437ef113d2b1aba89405c743b8674cc678c8c211464e95c59d9c0ac7a1e3d18d47a1238563d011e8f873dc137c5297907a842384e3be7b9f7acfd1798ec5e346ab367af5a9e7d4758e1be5fad4738e1bedfad489c78d7e7deaed71a36368d95f61ea3e4d03f0c0054bf40b43a93ae3dc0ced28e7be6f74c1a17df52e1f3bb451a5d546b7ae3ab45131b4f9a8d27378910170cb414a1939a4aabee2a8a6115c35742c2d9b6af28f01000035bcba354d9e7f677ae87dd5ac769401cb528365c70dbdafdad28b5697162f55d088e87dd5981c2079db4262ef6e6f4befabf63597369796f6fba6d1a5d1a5d1a5a5a56db0b797b68193f6f74de3f1fba67dfdbe693b7edfb4a22c3034e8da68e540a1f74d2300992e6e5b6c646ceef4be6914b6c288fd5595115345ef9be6010a297a6cd2ac6192d0fba63dc182030c95091d6df4be697f5ec064a4d9f5c950ea7dd3c2d0c2d0d07e5f343134313431343434ada686a601a95c341dbf2f9ad7ef8bd6f5fba23d9357e89ec0dd00b47bea7dd1acfc7ea420d3b6c5c644ef8bb61c7ac362e64a58913c3dbd2f1a73a9881917e58b1b48fcf4be685f28b081e44a859f8a244ebd2f5a738c15bd1844bcb014d1fba2ed9038db217176f6fb9eed589ded589ded58dd33bbc767ef86a176b876b8ce1e30ef9ee5f87dcf70fcbe67377edfb3dfd311658f849b1f9adef7cc00564d4a307932468896def70c08151bb618388290e97dcf98543d4ceca92d09b3a2f73dfb4a53c4cb0f6e6deb4def7b96a3869725952f459e38f4be67612e53980f7cecfc7d9d7ce911dffb3df61080669cccdfd769e3f775d6f87d9d214238f19c38dd90545d5169e97d9d5626f6b4945535b2d0f4bece347f56cd234400d9d6303d380366a2c616b7b92ebdaff3cb67eb19a306b30719277a5f679308165a5e138c0f31bdaf3383c82040fc06914164101904081020dc3054ce7620e41e3b88112068fc06c1f51b0488670d50cc402b32438415135f7a83b0b203abdb42e7e3cca93788250d32a6159d972d737a83a8f282469d980e269fde20963a9e5ca9f051f72389de209644d1eaf2b163adc611bd41641a1f328d0f1f7e7fc8cc0f99f921333f7cf8f0616cecc387153abf3fccf8fd41c6ef0f317e7f784ea0c618b44013cb6699de1fe890ec3841f7a4ca050abd3f2ca514510bab62b7bcd2fb0333ce69a2aeb962059cde1fbe9ca418d3e2c81617bd3f345f3083c9e5c894bb1a61f4fea073c683ce190fdb838e9f071d3f0f3a7e1e3c78f0e086a1f255bef2e0a10d0d0f5bbf3dc0f8ede1c56f0fcf1e30ccba946c59c2a54c6f0f56cf38b232bc2b4f5ee8ed010139f6fa8ecc51fd91e9ed01cb5759d80a2b7b56e0f4f63002af0d983d1d5deef6f4f670b960a97142c572c691217a7b7032e5646aeaf7d4dbd4dbd4dbd4d4d4545ede94dc639f6ae33585b57e4fe1acdf5353cf5d848e448e32384674e93d6545a24aeb2c071a3256f49e5a6e5093e5c50989156070e83dc5cc61468514b91d702af49efae2a24163ad49163b127a4f35a7e485613987f8a5d17b4ac74c4ac74c6a4be938a5b694df639752baf82d85f55baac56f29292929bc2da527b577c5485b5e1c0b1f687a4badb10d218347c6452e4c6fa9250f2d5f4f7c9079b1a5b7949831bc147132628cc0d35beaab063702a9c04023a6aa2a4d6fa9a61d092a3241e45ae4e92da5a3d54147ab4387df1d74b63ae86c75d0d9ead0c1ae43de63efe086a17474c03ac83df60e651d96bf3bb0f8dd61c5ef0e549a7409516322ad8612bd3b58c150aad0ab2207c44fef0ecbb8327b6a5647d698d1bb03734c951e54d228b9daa27787af164e8efc782ef1fad3bb43d3868e357c69b2eeccf4eee0d4a1e2a043c581c36f0e3a551c74aa3870701bfee6a0e23787abdf1cc43870e0c041cf4895135678259c7ce9cdc1ca4e0bdb1e999c93287a73a0bac31136232e0b5d11bd39cc5d5173e6069534bd397ce58489ca091315f53b2a872f6aef73f8a2fa1e7b549b295138c5ef288ce277143ef13b2a2a2a0a2f4aafc88cb32134dec49c7a4759519599d155858b1033bda3829450916665a68aad4cef28bdbcab2d5bccaec234d13beaebce4b9018264618b1d33baac977c60998998d659dde51396b50396b5050bfa1729e50394fa89c27141414941b86cab1cbb183826a6305caea379489df50257e433d817071d19d28a202506f28144d48c839adecdae80d75fb86b8e89aa17c6b43a53714d0893aab3226b0006ad11bcac918122d32469c6952426fa8bd232faaeef284a008d31b2a87c6530e8da7a7df4f39cca71ce6530ef3e9e9e9696c3fc93df627257ec2be9f48fc7eaafafd34e2f7d3532daccfa9034a153fbd9fcab6fcbac838e34ccce9fdc462ac8a188f29294698d1fb89d917a806055c0c28617a3f7df9609324cb18112ac8f47e7a22f7f52c2377b68686de4f67369cd9b0e1f706bf0d7e1bfc366cd8b0c10d43e55ce55c6d907bec1bda98d95025e2f7862daadf1bc45ef97bc3138996ba381c32d27cd17b435712295b682eb2f481d17bc31249a44d4b123f205062e8bd61abea6f0c0bbe2c47f4def08506c6913c2a6e7543f4ded0c49b91e60460913d167a6f203a71223a7172faed447c7322be3911df9c9c9c9cf2f29ce41ebb1309a7c0df4e6d7e3b01fe767a5e25e942c50c8a2c36bd9dac9c655a927811a1c64c6f27342cd2f0f98db0da91a6b75305f0e0b0d096805e777a3b55d191c5a38b5f1734817a3b356370b6a34c8b08970a127a3b916920d3a0e1b786a686a686a6060d2b34fcfdd6c0e6b78635bf3568d0a0018f026d5934ce8c31d708d15b8395945fdb90bd2e6b6d70e8ad41af6959e559a5d9b8a1b70621582ca0a0b081234917bd3520e02c0a590b17656c70e9ada10640b0687cd108d392e68bde1a883432106964d81988cc0c4466869dc1efb167503233a8f99dc1ef778634bf333c1f7b86b70c1932e411e35e849961e39976a7778634b63436dec8bc40e3d43b0300cabcccf485d912d3a177061363d05858d9f8e2c24aef0c5f506268cde9205bd33b43132d6c4513e797b8167a6768cf6068cf60c0f01b43eb87a1f5c3d0fa61c08001831b86225e11af3060f88101cd6f0c677e63e8fb8da10525f4d0ac5152997de98de10eee05141b4368c8d01bc3720278cf3eb62a38bf1f7a63609ac9c2f6e32ecc1b9bde18be1e90c24dad84891b68c2e88da119011d566d5662ecf061466f0ced5c533bd7d4f4bba9a56b6a6a6ada4d7a7b8fbd292fafa969ace7779399df4d657e3791f9dd54002f5fb0588961a54553efa63d2655606065f568c1d4bb6979d5b490d262cb4b4d5710bd9b9850c0c424015bc1438bde4d5f6757702c4953c3e744efa626142c28e658709961e9ddd48631b5614c4cbf995a31a6568ca9156362626272c350ad5aabc6c4f464e2fbcd34e6379398df4c47556b2852dc617d6de9cd04854995ad1f3aec5a98d09b69f9588cb9b7e42cc8113abd99987b4bb2136e4eae70d19be9cb0d88df8a13735daee8cd74e16e9081c3e36b61c64a6fa696c48596c4850bbf2fb456175aab0badd5850b172eb861a896abe5ba70c1ed4298df17f67e5f00f3fbc273865e893068496894d0fb425a19b03546a8d09de97d61b9249202cb95671710bd2fa86012b825c91619214dbd2f7cb125b14332e6695743ef0b3d9a4ed66c91b3a23ba3f7052b4b5696967e2fe12de12de12d2d2d2df5f52d2dc52d7df9bde4e5f792deef2536195c4162a00993a6f7929502c2c05cd92ad3626d4defa51a90d0d371a5756359824def2500dc7129c3a5075b170bbd97b088b88de0a3638236a6f7d2598d324aeee69a8ce9bd44a644a6a4f45ba9a9d4546a2a292929b9b929294951eaf25b89cb6fa52dbf952c881de98321a444569ade4a6d26e2acbea0404ba1b7d2128d8799aab5bb1c3ff456628a65b1c04203068ec799de4a5f2a2823654b89305d9e51f4566a22e1c1832eae8615187a2b0d55240d552425fd4e1a2e9386cba4e132292929c90d430dbb865d49495692f27e2769f99d94f43c53e4cb9f1519185a7a275931a1d2412347608d3cbd93c2a039f204475693152df44e625650421687e249e40999de495f315e00b98322c6a977528c3c1a4f36235e6e6cd13b690bd21624a4df487a487a487a484848487f7f48485dd8df48597e2361f98d84f71be989064b18961526d2d4e98d6475820617176e6940aae88db44cdb113824088e222cf4469a11e3c591b122645a80e98df4e57f7e6adaf485f1b8a1375273cdea8b8a29229e64f446323b323b3afa7de43c721e398f8e8e8ee4e48e8ec21c5df97d74f7fbc8caefa367d7981936276b549cd0fba8ad840d1445d27801dad0fb68b9f57c7341c6e71746ef230f6382644dcc9236617a1f95a0ae455b0bbe1b65b6e87df4030d9709b824725e7a1fe16819e1681919fd36c2d932c2d932c2d9323232ca7bec466060728fdd4849c6c8eeb75195df4675bf8d3668a3226b424439c58ade467e34b48494218b71a7b7918d162e74acb95131d3db68cc2acd189f98320c85de465fc7bf1b2aaca4010e59d3dba8d9c5c688b3b7224166e86d7473a6e8e64c51d1efa21bbf22bf2f2ada457a7b8fbdc80d43e154e15415159d05aa29a2f2bb88ee77d194df453f6edcc0e2d5c5e4cb0abd8bac7820892ba2832d860c267a172d7db848b88929d3d70688de45cc1570d56d4df90165c618bd8bbef0b6a29400eb5b2146efa2e6e3265b39ae7eacd5a0d2bbc879e384e8c60911d16fa29b37a29b37a29b3722222222370c759377934744a4a42292f29b68ee3791dc6fa20c4188bc209306cd0c0cbd899a2c39c3b291f5c4b2d39b888b890d20695c4cde00f5262a4277420c11314e173ff426faaa408c16765ba428cfc0f4266a965873638c99bc2f30f42622b34066c1c26f0b4d0b4d0b4d0b7e8fdd42090b71bf2d44f96d01eeb7050b162ce019b15bee20b2a412446f0b484698c96a5e5179a2b785a5918c4910b1225190acd1db02f38a122661d8846901d1db828f3546b2e4784ed93ba1b78504d4c51519a337038a99de166e68206f682091bf91374ce40d1379c344fa3d76a47205f2ed3712ca6fe493df4824128977efa85ccc48e2440d1abd9156284e80cdf883e1c4a237b2c6da902a5db88ca9a9d21be904cd12cf05191962717a23bfc8b86d055619b165426f2409ced694411126eb6c4b6fa4f04c05e1990a157e5710fa5510fa5510fa55a850a1821b86bab9bab9aa5041a955c1c9ef0a6ebf2bb4fdaef0244127e5eccc6f19a677052b16786474ecf0925142ef0acb1b4abf2560a06c21a37705d4cdc7db98abad3b34bd2b68317b40816bd2ecdad2bb4213053ff4465481c9cd00a27705a19321a193a1a1df436f436f436f434343437979434335869afc1e62f27be8f97b284a19ac228130bad6b8f41eb2aa0199561bad244dc0048ad07b6889e4d763c78d3aaf336b7a0f31bbd4d5b5d07a8a28d37be86b2bc6dc8a2a304e33bd87b2e0ed588a1803a48a84de4342afa3d0eb78fc7d147e1d855f47e1d7f1783cba61286199b0ec78f43a2ef97d64fb7d5cfb7d2c916287599891194afef43e5a5d333458c0b5b5e8ab1144efe3528493a7141557754dbd8f21aedae0845491a372a7f751eec489b635262c7e30f53e5e2928ca6411b30282a6d4fb1804f420a0fb6f172a5da874a1d2dddd0d4309b38459eeca3057fbed69bf1dedb7af51a364d2c449978d337abb0fb02eaa1358b2c0a0a2b72f8deaee6a1c8951e5058cdece0c8115d713167746bee0e9ed5f11d0b069c2e4a92402a7b7f3fdedc0aa119724ca9bde1e9c3306e78cc6dfc6209d3148670cd2198d76c6bcc76e74c350c13d7c84fa9e51eeb11bc78c67bf8dcedf4625bf8d4f199460e39117c4ce871abd8d5641c6d0399172c48a8bdec6255497138bc58814752ff436d2e004132576737845d8e86d5c63f3c2871f561992137a1b9b674c196941a034afe86d749a09990909fd16720a39859c427e8f5d4859262424242424248417e44121c8830285df148260f808f54d61ef836014fa1e3b05a51c85aa2d0a142850c0a3a017541114541114f43b28b80c0a2e8382cb20bfc71ea4bc0baa4af23b2828282808af99f64604881a9a2ebd83982dc6988d68e1a24d8dde415f6780ce0001fd06f203f203f203f27bec404a2e40555b624040404078ac931fd6c9cfcfef1ff6ed877dfb61df7e7e7e7edc30149bc7e6fdfc28fd7ecc7eff94fdfe41f2fbc7035964a80d99f1c2c918bd7faccc90a9e9437215634cef9fbc39195fb84859cb7143ef1fa601fc02abc448cb82c688de3f5f1c404b4395628b8cb51b7aff9811b92293858facd943ef1fb209641326fc9ed09cd09cd09ce0f7d8275029271cf93dc1c8ef09cddf13264c98807745c6a54c13b3282af0f49ee0054917345df0eac25ce83d61c9854f8c0f154f2434f49ec04c12e38a98932a369e0cd17bc2979429629e3ae0a898d17bc205bc6000a9cbf217a386de1358153eac0a1f9fdf3eecd2875dfab04b1f1f1f1f370cc57675f9c83d769f2a9f22bf7d88fcf621fbedf344d36382d702cc8a0bbd7db4b488e2428816ab352abd7d961cb4b2a81c9151a60512bd7d980da0a38b62a22ac81e1abd7d0e60462bcdd38b9595357afb14a985990b444227234b6f9f1550c20a2841c26f09ac5282df6397a01cfb2d61c86f09427e4b90204102de96a02761efca8832bb3537d6b0e92d21d7bd408147a707064f6f0946c4e0dd88ab61668d96de1248c0c50b498b355cb4d8e92de1cfa8189357656f0497de129e3cc5d8b07d4103466f09eb5c84752e4284df1156ba082b5d84952e42840811dc30d4bab7ee4588f0224290df11c47e4700f23bc233839ad58e305724c28cd03b82550d6c98b5b991d1c0729144ef084b225b7d3d6ea018ebd33b02f371190a13724ed49208d13bc257d109341766784459a37784665ae012269c963f40bd23ac6110d63008107e4358c520ac621056310810204050538320f7d821d480f0e33784b0df10c07e4378dec0295edad48ce838a3466f0856c1355b9a58c09e00b6d11b828b1b386af8705184f9a637041888e09125c9953c306af486f095630620d5173eb018647a43683ee6d1a6c7922f49942cf486b06af5ac5a3d3dbf7bd6ad9e75ab67ddeae9f1e2f9dde3e3774f8fdf3d3c7ef7f4f4f4e091103347e2b91caba1778f150bca9454ce32594c6cd1bb67a98165991f70814b8438f5ee615a2952c6844c1637347af7a87f32cefce85371d644ef1e09f85833dbbb7a01844eef1e350c8f1a8687e7378fcac7a3f2f1a87c3c3c763c798fd7aab58a87a7c9f3f59b67c76f1e1dbf79c28450cd7921f382c2466f1e2b193499e255c7e4cd4410bd799667aab072949dbd69d5e9cdc31481160a1250a67471dad09be76b4bc496195f4cccb5d09ba7e9c6a38d4990bce717bd79d4b5a2ba562cfe2eaacfa2fa2caacf62b158b4b32b16cf8a5ebf8b5dbf8bc56797135f589630f55244d1bb689554c20bd6522d0d1086dec5e5882f434e14b951b646ef2213034a6695bdaf2fb1147a17bfd0b4f0c861f6638d4aef221b98911f3dc25481a9d2bba8d2d85169ececfcde51993b2a734765eeececec8c8dedc83df69db89d1cbf7770fcde095c5965cabf2146a3b1f5d94e197e4fbdbbb5f9b57bcf9be213fc0a94f72b81efee8337f7ee8ee5ebdd8d9ab038df3d2acb8b770f31802ccf775f008b77e7003fdd332d75efee0108f0d33dcbf3f1ee27d822e2ddd118c4a4fb05d37480881413cf4029537618a141658609163e26579e57903c92a35bc42452d35d9b6f72140631d9a47497f64a8ebe2026959aee4868651193c6e35f0832e52f38ea8298bce043c4b32c9a6759f682b3ac8fe6b339ec1996659958364cebd91cb68f4572966d6259b111cfb6ac1936c959568965839c3d1b8135c3b28eab5867fd7640c5952e3b2e1759579a55a285cf598309644eef0c234857922a33cca6e8ab1b27a07ca9a1daa2f77d2ae08893c5171a1e50aaf4be7e9aef4697be36bd205df44695620d5002611b11430ed0076b02ae8c951a5f75ac8308527a771273f1ee71efee83f5ee6ee4dee48e621193ce9259cb18ddc7e86ef41046171ac558bcd1d116c4a4116ff754f91d84e537f2959494c2c0bcd28f25af040447d88f577274494c2aad49657e477df021024b4f4a941a3dbae4eefe7aa080f29794bcc104b04adc1122584949643e298cc72709b1b09c114365e26c854e0acbf1498eb2202693da6f72b5094ced9bfc7ef926475710934d12909090dc07c93dee915c88e483ed911c55414c2231f940f14c8e5e11934c177a5cf90b8ea620262fa02026d9ad253222bfe4e8096272498892177221f71112124a722121216b5e8828c42724f4424a42427e02212121cf320a0939fa2524344608c98584582121170ac9608d891625aa7c0521137a92a6468bba2051b4848452ec4003c67955830f89901c9c8a277d489c4f21675996655996655996655996655996655947ad884916690c12121212121292a326884924a3d168341a8d46a3d168341a8d46474b1093461d2ce6b815b8a626c71a250d3c2e44da7688407344eb86b28a952a3f27ee61debd8a6a8d133540b43c38edee280962d29584b8bd92a355c4a492f02c489b4f72740431992414414c0a41b9f2aabae7ae3a52c9290a4adeeffb96e4aa77a0aa2a94be576f54f5ab4a7553d5b7ac57b30a4635baeab8ea2aebd5b7ae577b54302a92ab8ecb54b557dd5e283c6164cc136615e71abdefb3c8c6cc081a0e113df0f4be4ee5f56b8aa17caa02c47a5499f0f202f0854ae6cc061a1f3170586924474242424242722192fb2021394a454c2219f117a3d1e833b8ac785c395333fa092d27745f2898a4301a8d46a3d168343aaa24268d483565f982ac8760dd039665bd0642422f242424242424242424e4218484849c06c4a4505252525292cf80984c72d5ddddddddabbc3b14b877970131e9312026d529575f2c168b8e54c24fee456f9af2fc6284625eb1e81d14918ac5a2505652b1582c168d5e2c2a158bc562b1582c16e96abc922b390c884925a1d168341afd05c4a431e9ee93dc05c464925048484848c85b803465c623390b88492496655996655996f5151093acfb3df2ee1f1849e34782f9c22b8dea4500804fd2ae4881e22287565d751510936a0a88c9225efb477ee4c21c7ff4a4ca1f390a88c9a3ec66e58bbcc87d8a8a1c59e44d4ec07c518522bba222efa0c85854f404ca17b54558afa8a8c88b8a5c98bfa8a8e8c80b3053d2f4b822a6a8c4162348ac9420fba237aa7cb2e2dd55f71310932e2c168bc562b1587413109345a351c968341a9d2879a313e51bbd04c4a4916559966559966559966559966559d649404cb2ca274120daf25ec87ddc84bc509bd70bf90888492167311776d8e5f7f54bfa6372b1d5f1c590a2aaea90bf3544a8c2d48eb4d1fbea7d70238558dd0d16555b7a5f3e2e6d2bdab2da643c149a35223172e8a8d245ab6d56afba088849751393457374bfb383b7fcce8e23953094aa77dc093fdddf99cbf23b3b3b793b3b77c74f30a766a798c5f53b77470ad6eff0ecec08f98ea36e3b72bfe3a8dd9d836b6137e6ed0c0d8c1d59803cb79c64806bf48e565918c0366548ace97d9f7b4f04132538a238e1b2b3b3b3b323e5ea858484843c04c4a450b1e83ec5e29c992f3a0888c922cbb22ccbb22ccbfa078849368d6a4a9d7373afba509d8bf2aa7b8098543b404cee18c590f146ce0162d2486ba9e5b37b76647625fc64f4ec4d596bcbe761ce929d03fca47af60e30d4e5cb372fbfb8fb3ccc587276342b17e51c83c5e761c6cb45cf8eba65a1fca6542a49e88dd26d00eb0bdd12357269d4e8aca602cfac0eeb0e88def9339f0e266a48e09991d1fb3a37e0e7a50d9b36620275641560a1c225a73604065fae810ca7990f33544aaa30c96456b4418355a4459bdea85807ba82fc1842d67535978584e87e07bd10f285fc9a7921a61712f20c03c70bb90f8c332fe4bee5e4857c03c4a490515a2c168bc5e0178bee2ff8be58f4fbc2cb175d03c464b1a8a8c31715bd20fb22365fe41920268bd42a3b3bc39d2b3bbeb3b3b3ba99c55549a3652dc6ce98391269dc485099edececb8ef78881df780ef777676dc03627247e9471ef4ee5a65ef5acc77c70031e9eb8d1515826aa7aaea9daaaaaaaaaaaa4a67c30e480f6696a7ea609c5e549a48f6a854557dbecabaea2154f74099f5aaa34cd55127d705884975e877cf1bdd68f42ce68d7e83bcd12d404c1a7d54965d59ba67f3acfcbe7e107ea355768f763d5be537da7cd659966559bf2c8b80b2ba352e33e682406175b6e8bdb5f97df9c2d41b5d3e4b822b8c99164cb12e7aa35f9f012860c2b6ae88b468ea8d8ab958c3baf2590f51f5ac7b704289f5ec3dcbdad10131c93a2b404ce6fc44b8ee89888888bc89c8f9020692b1215d639a48090b2b270e2e7341aa88f47a3c5117ba67a33ceb14980031a93a07c4245194bf8528ceb7e01220262d209148472291c8218f1cd1f4ac4780986455d5afea102026d5071093c828b90a45bf83be0285af508189df5768e2f615aa7c0577003159c187a8fcd0d0d0d0500eb01ecde596b12b237a088f2c90c49312557ee89ddf7e88098a57d95ef50610932a0388c9a1a80b7fecd1e38fbe0062f24863ccaf2bddafab10ae11f62bcf1ab73a071e18d7d54f5083ccafb7cf6ab9e5eb6a63ee579c75caba3afab6fa5d1dc55bd1bc5fa5fc46fd7ecdbe3aae5af1d5afabe3ad1573fd8ac57e75dcc44f3bbe3a2e5bd57ec5cf1788a5b5e092a20d1c9b2672028ec13a53a60891fbbc7e2386c41531e3f292d35cd2ecf951fd3d997aa3cd03b8b511eb8332630716bd51bd5f9d2f0a9b1e6862b05ce88df2fd8a99bfe2af5f9d6559966559966559966559d615404cb24e1d3c07630d055c179899153b3c58b81c09a3eb6262c44e0f122633b2a475d91dd9d991fb9d9d658d355770ec1db193a277763c01c4e44e9ba6a6aa2a9aeaa4aa2a33c8abaaaae2287b15479b57550fd135e2551f409792577d0154af3a02e8da0be677d4672245c4dc4c1ca15393e33e671422cec8f6aab82831a2b38d2b9ffd00c4646ebf587461922fb6f9a21b80982c66afe17cf70210938ee18d34fedee80420268d42211a6e2fe4032026850480df769e82fb50a0e048250ade44c1a3b248f83df5142850f00e28640a14283805bf14ee13c553a8f1d9b3078098cc411ca5e9d7758502f82bdc8c5f3d494cae4e96ed59070031c90ab3aabe2979d5372026554d4c52e0fbf04173223ec89f980c8a53f2400ee43e40408e54c24fd981bc09c8a3e4b61e680a687520a01d202039320f040404e4681650110808c8090404e457c8178b1e82982cdea8aaaaaaaa2ac7e355557510c4a4ea21aecaeff8076272874595c18b1737f7eb1af7e457f7404caeb9cc679f222673a00c2f1c7048d4aaa23c2b97030d470c3e1b63bc341b65ccb32e454cb2de8198046afaf909fa1fe4ff2871f8edf43ffff3e33f2e64abfa1fcf3e6c63ffe3cea6e67fdc6849d9ff78d3d3ea7f3ceac7433ccffec7ef9adaff380762f2472dc9b73cdfc27ddbb6ad3761a88bd7f200fc76a97d6b9d03fc94bdf50ed4d66feb45f66d500ba5ddf1d6d1ac766dc5944a658a768dc8b739ed93d6d1670a25d4ada36dfb49b0e4984a2f3165ba1dd392f3a166481e1bbdb313963624d2808ded50d3fb3a21f098db7a969de8da6bb7b050e3e3860b294a70b435d811064646d591368081addfb65d5b127dd1a388c9a21044d055739afaf5aab909fdbe7236c6fceaeaeac2212a7ef5ccecfbd57dc87e75bfe1f7ab1b0d71fbd59bd4e07ef5a81cce5f3dc4f2d7b3b1b95f7d01645bbf3a1431b9d221ffcbefa8dfa9b1c7067882c595950b7db7d1efecec3cf91d1b5a7ec7852994929d0cac1a3eb478f1d23b434cfc8e3f11933b1f40fcee095afb8d44fbade4f4ead4ab6aafea20f2aa8ebe57770c797547dfab5f465efd62f32a8fb257fd7a9579d5371093aa53273bf91d95801f746bb2bace9cbcd03b9b008b189036714d7ae0d0dbe8f38c1b7a3976289330f56efaecd9edb39796cf41405830b901462f8a199dbde03ebb13319997fc6e9fbd77239f655de8e359cf2c5a9967d3943cabb6e2cfec9e750d4d1988c976828bb79fe01888c9093eeee3e3e3481f1f17fae4b3f771c1e2d50caf7a1331a9aeebbaaece444cae1788491fa59750c6e525f8123129a1f811da3e823b7e5a3d82232344f0a6087655ecb2686c29b3c2a7238479f3eada2106c898de59ee23f82d7bf555572226d59b2617bcc0d0b3b2b186a68a0a131855289830c04ce86df4eb8927614c72ac20c3c232291bf22bd4963731c0314168ace975f524246232421404330fc18f884908c29eef797e4f8f237b7abc0943a14ba5527942f7744df1e2b79555a6248aeec992d1d6220d89246465fa5ef91eef09fad5f85be957b8df5347bfaf9a19901f3326bfba4f121cbfba2731f3ab1bb1fdea4d4ab6fcea219c447e752362727daa7e77d4abea9217a277448ccc8a393fa6de4d185c982013e3f7ac3245a3d162c2d97576044beffbc6f6aa7b8e573d8499d7ab0188512666454b99858456cbc25ef5226252c52322267bec9e872bef79dc0231c923a3ee833a1f5cfba03b52a929e85133467cf08358ed3948a1843ae81ee4607086de07798269c1d683c19d60d0d12faeb90fa2601f440b3afac44f6e18ca83a8dc07e93e78c48e0415366435c8a468079c495137468894263c74d0830b586306450988c64633a8468c52ce0f4cb92248d6a6a5068db2b1327aa3621f7c9af1016444a0de0dbdd12697f28bae161d494c1691bffadd51bf7ad399d656056272bdce9d18bfe343c4e40e5a0f1935969c99c10ad33b7fdb9e7d8b0706cd90bbb1235d73ba9dd1e25b3f1293edcf67bf32bc7c762726b3f0098f0af4aa1a43cdab3296bc1ae3ee553712936a54111e5a7c3848a8f0c13a9fa5528249db921331f4aa341b63ee5917222659a7404c06f19caf63c5ec753c8898d4a923f339c2cf51f239393941cfc9b1737e0e4f4e921cd67372d61cbf3956c03e6727c72cc7d1650a25d4398e6ee1a7fb396a8edf1c17a6501a4d18ba332848ba94d13964fc4c3c7951b7a24eeffc3971678a1c09032317964346c598560d1c2f98e4f0d8e3cac1bc02cb9163e54c3330ac4c94bb9ca6df3d7671afaaaa67bbbf571d8898547d7ef7fc6ae577d0d1af2ec44fab671cbf9e55d1f2ab9a5ffd87985c9d6559d6599f404cb2153e58f7e483ee434c0625109339f7f9c43a114ff408c42471c60f87653f744fa1847a3874a5a6282a487e38c54107374fef877e022a657ed8f74324434797f849f5a1a35943ae1ffadd28f3872e4ca1ee1a38351e66866071e9a18747c88c715de968e2e99d9d432c4e44387132660d4eefebf743adbc2c2eb8c69a70e98d2a7ff8fcb67508c464ab4549092e34849cf0a2773ef22a90932752d2d2d4408245ab2e4ebcea3dc4a43ae18354707cd07988c9e09b92345f543472681d598dfcfaa5e2ccdf0b21279a7a9dc1e6572f1293eb13f259ba34cffa0e31c9666272887ee91093291ece91c7ede6b8faf012d3a13d804f6f1c252643a4373b1de279c346a87088e7898d50b7f025f38469e309d3d6f6fbb6fdf1f0e1a3bde7eb7bec0600b4ba6d6dcddfb74dcc000668c36bd34b231346c8df08165ff4be6d4c0b04011423a635860d1abd6fdbd75a93b5264d7edf26cf26cf26cf264d9a14c0ceae4901643429b225d6e4d9464791197d55e454e87d9b58fd8d81538145cec7159edeb7c9328c49181326bf2f13b1f448ef321163e2f7d809c06cabb69810f97d991080004cf0766431333332c40d4fefcba49927a6f657c30c092fbd2f13270f89270f89e7f3f77df2583d79ac9e3c564fbb67de631f801b86e2e1c247a8f370c93df6010082dd27d9effb1cfb7d9f437edfe7f3003daaead0a6cc8803a2f77d9a79a27786e28a9b11bdef33ce079e153c30cb2052f4be4f246829b09a6cf44c8cd0fb3ebf92e4b5019304cc8a157adfa7b2858e2a176244b459d3fb3e8b589614b12c59f2fb2ef97b9c878ff63e6f49df922502e8eb5b22002155427edf25624b9e6802abde766c91a1b78439802eb4146dfeac8c09a3f75df25524632b92b1b1fdbe6c4db6265b938d2defb107e0ed8d2d0080482e5b90df974decf76503f2fbb2fd64ad31430286450a2cbd2f1b9a081b5ccaba1cd173a2f7657372f93126cced860fbd2f1bd30048c87c8c65696919a3f765fb6a5ba1a5c744adcba9f765cb59e103cc47d599950cbd2f5b516bada8b5b6f6fbae6da5477c8fefda9adddabe6b7a7b8f3de986a18a5dc5aeb52460da5dfbf1fbae85fdbe6b60bfefda3398620a5c9a2f35d0cc591da0cf8a5a0e122f9420d1fbae2dd37479530e5161a644efbb8643879f9935cf30b3167adfb52f2053c0c05c39b5a0e97dd79a455850bcb070d1e6454befbbe60454035453fb7dd58a4ab5a252ada854f37bec00006c72d57cfcbe6a3d7e5f35b1681b940be153429670c9540f361ebc351c7b4213385a08e776e4a937b0500084c9f7512e746a1927818a14e190b48c7a060b2f303899a60e46988c6d1720b02d59e8a194f4669034308fa0c48446463345c82e95482a0db5a044889c32abd03463c84ba0471dc481088d4d4a8278ccfc74e89b2035c5c7c2150916d884118c612a840dbcd09e0db4f0a8c5a93c756783aaccd4646a231c1e973851783712940889b808831a8e351651d7a6ea2204880f1ea6a43a345dfc3d5d9489fd07182a2b6f211d861c394cdec21dabbc85fffc0ff0031120fdebe9dfa14d8357b1d1940b2229525f535df2568bc8768811c05a883e7a767cacbc85dfc4465f0b10a647d78f1ec31b00fdf5d157cb595b1e7ee93b1cc95b6874cb5bb8f77d790b513083df3478142a8811e9e502efa792e4ad62f8e36b214d623d7f8752b02ea14b37cd513b9cc95b95a2b3b02405eb8fc0e87f83bcbc855ca6b6e4ad6e40226fe1fa4c81790b8f2dd67e0708ed2fdbdf331da5007d79ab5951504f1b9c3c7898f220210204a91e9ee24ed6e99043f4c001bd9f53038cdebce5cc4051f73be7f0600bbcb9ca4f4a0ca78a3d55ea8e0e0f133bf6311ca2b8eb3f4073b1f543f7c7ca06d3344dd3344dd355180c06831e02abc160905d6db030a3c38e8b8ac689371c57b854a0e88726294e388902f723c9de9835a7d79429327c8801336b6a297df4180357c5e965e3eeca953672589c8d5b103562c818f7ec55fcc406dba8aca62b23b4cafffaee5e07f73a432483aaca0a57945d51145ce7ab37cf036cd40113534c8d719d699aa669fad40762caeb034f95290c3452141d321fdf5dda11d1022587755dd7354d879a30c6187be0628bfa344585d9474d4d0dc5290f2894c56f14a3cbad25119425f349eac6960d4e3e4383872b0c8ffdf6a8c8c40c75195d7de8fe72aa89483c4e201289d90500b8cea82623f7c16a580dab6135aca606802914596cad01c6290f26a6f7277a17d02b7c9f57373f006c2441eef9b614b4f0a684212ca9c7ecc8c1b020e533daf1fb06bf65e61b07266269116a033751266e32ef92918d99beb58008c299050b5dc80a28104c878a613ab1bbf44ac454e510aa61060b8e503d7ccaef9b00b08f72612363981718e37e13c53c40fac0532a859c48241233074e4e4e4e4e52499c860c29bc50e8c714bff088dea39b167c7af36915aa4bb866ef06d5715870559cb3de25d575f088fec54f9b85814a24c0ba8e05fdbaaeebbaae18638c31be4b53458cf00105fe46fd847e4a6cd4f482af0528df0f14b4ab8b0394c9a9e8f82668309f08fa04e951d3970b243c0006708005e0a71bbf9ef69bf85c57a3eb775fb85781dc1c89d748bdf1bb6302e1f186a8824fd79b167cead748f5bbbe1a83f553d5c5227408838607210d1faae46b35aa4c8fa4a2a04afc821e6c6427c6f3681a02555736281406d9554d2d9ca5cde2a7698a1a7520f10077da7eafe8d613dd0a40fb1f6cc07481926e6da2cbbf8195b7a82623d7f97da3f37a395377e81b7149be50a9e3746801514d46eef3862edfd0e51bba7c4397e8720181197514e32d176f07f98448a1d421243ec2fe94aaebfad8d1e3f0914e24d2895c9a43e22995385350b18b27e60153183c25baa39a30181d1d6fde0529943a14223dc2def46c5078e33bdf0885c29c8343373df263afd3cfe977fd823a447a74bccaa818c6e991a1f06f97df3797ef04ba2da3cbe02b3d5ed7755dd374c8091f61273cec84879df0b0d37632fa7df19cee92518813ba54bdf0adef373737377901eb9bfa96be61a3621a3e146314c328f7c9aa303bca640148467d3bae018ad128c38b4cff318a620e522875a8293dc29efa36527dfbeadb078af59d59a170cd591dda4de9d06e6a423629518c9dc38bfeed80d9bf1d827f857f89e8ed908f60b2d05f34abe6df0ec5476f879d96c25fc7ecaf7fcff6be7282feba2aa603f4d7571ef967c7e7af078b13fe7a6a85f5a8df1093435af476883081ba8cf317cd845e8f84bf8e83ba9098440201c25f17a23e8cd0a2b703cfdf9ebf1e245679d4afdc13934e1ef51c62f20c4ca0049dbf4eac8211009f9c065c354668fc2092422baf0f029101d78c10ba305c520441cba287135af476682750977f867f3d9b60f1a8f3a03e04c2f9eb2cea12826ed03cea1188492e8ffa90428b5ef92126275097511ff2a4280f4f3be4e1e1b9c1ea0deaac7b7779ab4f2c79a35f56f256cbeaf2be7a7179a3746e79ab627879e3af2c79ab5752f24ef59ee48d976d79a77654f2c6ca372779a76a55f256e5b664b549de69932eef140c4e4bde69565edea9d595ac46c91bffc9e58ddfe63294bc51be12c2bf6825d6dae48df3fe2649bfe48d8a619092d5124d392e99c72b05220108879985486e7ce4e28af62af78c119790b1e225b254ae21eaecaaeaa47f893ac11faec4648a1e813cf8c37bbc8fffe21fb26bcab2984599723608fede25554dd16350c770886ac04de912c62ac6aadaeeebe9bdd8538c558c55ecfb0aafa71e02abbe0a80cd0122c0fad7efa5818ab238521fb2474f1fef19bcea2c010c200220e1fd760868fd10983ddee771912d90c8dbffb86424fb1f515951ba5883a2458693c4c80e352d5fb0f4265065050a217a6b24c0aa3ce192c33363a62f0da7e8418b3832ced8a7c767c27d6ab1117ed2b946b807003ac227c01d0036c27f8736b84b49b9bc7ddfb4c72df60d6e071cf5e2bff47668ef92ea4d2531e457d0163e52fda25c186a0a1fa9deb63d3d413be8d1f651abd4035a465d15b6e8966f1f0f52a81ce2c56b87433eeaeaf878c302fc5b06ff011e013299b2c2e38d4aa17a825e0d1e5b6ca43a7b548b3972eac27706f15a6488aacbe1caa2c79515aa007d085f79eb077305217d72ee59a986689ad3a3b4e92eedf0003fed9603e7c0ed60a53a364ad50b73d9030eb091938cbcdb252e32bcc8640bc5810bee128f9c7d6e07f4559f22c03d4397e991ea7988fd2ea91e027770c148f66088036ca4fa0f33eff6555598629489a2986ee8526d40ad3a74a0565587c3a10f87c3e170381c0e87c3e170d80e87c3a1e3ada1de70381c0e1dfd42c5d0e170381c0e873e1c0e87c3613b1c0e87c8218e4b39c9f7efdfbf7121d0d06f7a44971ee138d07075617ab4fafa961ee1b88a83e33838383838383838383838383838431c1c1c1cc75b387a38383838388e7ea162280e0e0e0e0e0e8ee3e0e0e0e0e00c7170707070fc22718644b0e2a18ed97b026c7455351da6699aa6e81e414f712fef9c7b304ea65046f8083bb28258de514f2976d56a781190832efce155401eeaa46a129ae853e7f8ea43bf3e3c0a62087278d42fd4f11ea141a2dfa50b58f9081474ec4127baaa738e40c1a100a4ada33aa75042669a5429440411b1a60c1820377a04e191c7a651bfc2e0711b7dd06f8edbe86ffca650c36030f5f9e17068dff8ea39474f8f828e120370e3c2d4718eaadf0c5362725d8fc2e0d0088c5e75946880096e5c86089f3ddebf60a58dd3f1b677a3eaea8e42892c5468e47df913413c0ad3a334df25d497fcb23faae5c6d50a327456a6d899608bcd581c1a215e68daaddc3975a479b2c715581576e3868a29365ae82166510c0190266347e56ecf63bfebbaae2bc6ebbdead0c546a8ce5dc60e020adbb028a43866642e35c95b15ca2b66293292b7f0afd1ed80ef5daf7a53344b0a50800a5f75d4874186e4adf658c92ae6c247aaabaae32ffc947a524c4e7d265096b1f2f1d010938ca64b4cf256ffa620f81f081f2800e95fbfffa80072fe0a69c9b70157af8eb1aad72119d040df60601be5e3a1225edec2bff8b1fbfcbd4728f1de1093b8adf023b344010c5576c5c160100d5efc586c1d33bcc81257288a92a0bb6efbbee18b2f8aa6d777509a620fc25078041fb2e9511f40dea33d6f586c1be1f07121f1557dbf83baa5f81e2b9003ec09154114001af85788e29be6603c960d7db8126e7fe14a94bd84bf7025723c1229968bceeb43550a0709206b5b90e0b0719b6895408323b3044b181a236ea419e9d1a288191100fab579a1c2ab0b96465d3d7e61a3b6bcd5b2bf5e014cee8026775093b72af657c5cf2cb8f94e3dfc85c5fe3aea4b5732082d79ab577f1d4497bc53bdbf5e54cb4b43f24eed9e83352fd45c01033cd3b541922d2398743dde9e1a652b63c2e4ed6bce0e0d0533c278619181c777022b89ecf24edffe7ad12d5f6cb453b7bf9eaaf9dc5fb722dcf2d7777e550d9354a5b0f2ce8fca55e092b10bd95d075126ef14ecaf83389377cafceb1dfef24eb3fe7a8735f747170a3c1d40c264e131016743cbe902c60c9f18768140eec67e045e40236353b765c49614b58dd8172b32ab2130cc021076868a8ec50aad388df6c9fd09c10a62a60cd0f3891414704ab218d1a82f01c93b4499bcf1db52d8f52567be8ebaa38ebaa7502258f1648699bb3f3b251d8c01f3d5c50b4c8b16944f55dd7fe7f714ead621f14b2185858e2d318dba510a55831b687d746361769011f103660cd697115c5f4a7255b3099d5510b92a1a75107b7963be4fd3271959551d75e4ed701ff5ec3302e4a7ae1e711e36ba78ef48ae7024e3a1ad9ef9eb17890ec18476b965a2c92c18cedaaa67a7b5822b490ce609355b36bca089b1c6c58510be2a1a25ce8ec4398fd8386382cc5e9cf32d850bae208c7c5375a3a5e2664d16bec0999183356eaa328fd75049be69b261b97886e3968371375ff9a68ea5cb412d375af2dad762b875c395856dab961c8c63f9b21a268836bc71f7dbc845d0452e5ab133c0d20085ac1842e5ca9532457cacd8b1a3058daabd35246cc40129e227e4ca6a840c24cc2a5e7c6d40c40036396346b5e34e58a44513e2c089428463a1b45ac41e6d0ae1d9b0c67088971e38cbecf3174d848b1b2839c74730492e1ad1cac2b61caf1c8c1302c1e9d2fe4543f125b771b6c12b214b4ff06884ecc9ad8f4705ffa2a140f31b39667891c1bf99475d2f9b0e7f675618140a879c82c728c0cc3e512eb3605859882428978369ec8b9c362106e6d6c90a402a4200f35a2380664ce4e108f649d6598153250b69049539c78bd5916f86b04b722ecb09cc43b7a05e66a7dc70c9375672c232f1ef591b2e4bda98c1c1cb37245a34b9b8a2bdcb394c962ab33fd636b9672c7897d527bb74c3a192d3bf6781716002a510f132cedfb3402bc11e99fd7b16d8252823ab7fcf02c3a420a3d3e32c504dbb23af54c4ae2c2c41545b2124936fb470c06a0c5128bd8623946142b731a219a5df302fab4af62edf54b538f28d8a1bbd2c7c4164cbc11a2c9bcce3d5eee59b26995c3c5bede26ec4e49bba9b1768545a845af2da17b492837fcfc0d8e960e59fbf68546a886559d88697837156f9266fa592d53043b41c7c225866ffa289f0fb9d5f091ff960a3b4e777cea8671f341469bf8d887051aa4f94d02fea1ae12d3a6116fa3542953e3ece17ba930ebff1d1399bf09c4fbc17465de70bf15ee8fe42f4eb852b9eea9385e847bdf0ba295fd8a37cd45112578ae7c9d3c4c4df09c45161024347172950f44db3ac2b41c2491530da51e6e52303e306d8e41944b7c1e851256726044ba3d85241d523099e526ff4ed6f9d55608faf153d00eb6e4af51bc5fbabfc1b785d78fd5e3a243f00b3a4c9c5699f144a47499838b62b3f6448d1b7e94641a205844a19316550b0c4c993be1251d4f6f46de1a76537268c334c0d94f0b5f9a3a145489b377d1dadba1d94f8a904512f02a10cf0138e5f77c109f0136ef3d739c04f18f0af87c04fd80bfefbebf93a954aa5db7554af8f4fa954c2d04d3e1d7aea6dea3d3e6e05d048e953271ace2be7c119dba737afc7f7d5bb7b107cdfbeeba734c3aa8ae01bb5da68d6d6a78e325d78f914edf2f18d7e814df08d8e35959fe2a44fd4edd39fd4ef46e79c28d0dea7a952cda78eab28f8c6561863dc832ec518ece81b8f359b98c16a43bef1d3ad826f2c87e93e758c87f7a94ebab1de9e05dfb80ffb7deaa9f2c8a744be53abab4fb3524f9931987c9a767d9a7ea56046bed3b1b4f9a9a74eaf4f53b54fd367eaf6a9dca7769f7a8aa7e4d3629aa67b47bed3bed4ef535795779faa559faa56579faa599faa5c9fbaca6c7eaa767daa6e15ec5375ecd3b24f5d759249f95455fb547daa6e4bbe5539ba4f5dc50be2f7a99af7a9aaf7a9ba77c1b7daa7fa7deaab72cbdfa7e96af5e97af5e99ab5f5a9af4cac369fae5d9fae5f609f62f0bd8e7d9afaea2cb3f169ba3e3f5ddd3e5de53e5de93e45b2a7e1931cf52226938a8479242424242457c24f4a8ee44d4848f01ea9456283848484e41709098900cb38b12a1a665659481fd67e7c598179f3210229094c9297a4a42ebf9d9a253ea94a13cb27b98f11b74f7227fb24376a3aa2a62b4a6d8ac8b17b5e29e895d288dc28a2e2c9ee70dc2026913060e53d064799c424861674ef10de95dc1da9849f90dcbdc9b1e0de797c8d37b97b92bbbbd791717931e30c471a9ff182879a1a675de61cea77cf27b5e8fba4a424cf58323ec9511bc464924ffea626f7697261538b30dfe4680d62b2c9db47ea792424252424a7477215c9853a1ec9b3de23b98f23b5e87a242c8fe4280d6212294a49c97d945ca8c4c2ca2b39ca454c2af90c62d299b6f07826476510934c77646fcc79a39a371a8d46e31d993772e081f18a8f3766a39fd168341ab7cc78638eb18b11c98d4637a27c4aa59285d1445c591e892f2ff2c2b4116b0dc95b99122b25f4cecefb7c42f6b6e5efcaac8c0fbdafdfc583d30ba3cda804c75a0c139a18c3a072549206005318000805e3409865619274ce7b0314801a5aae5e645017c8437a92c41832c000830c00000000000000402007a9222f0642de3d507adda33eab22c21347a5fdc104374dc685c48c93927bfc95109fdfe2af281e6f7107947b095d4219ea528e4511c04342d6f6f604eab31502a52b9a085dcba049ded914cd91501cff25cabf8398e0a40dea6af890d175ec12d3ea4512a66829e9b4632703627d75ab093d180381bc6868c2beaf6c09c78d8a7b6682c1fb7c85bc5322d6c03faf592d6295ff210ef71011b0fb5a8a20d617d4a79393329820fa8ada48f2cafa89ca1c0281d46c4f4132d8d9096b85f473ce8ae4172886e3cb5befdd82b5e49ea0816ca513cfa4cced9b1c9856b4a03ce5ede07a31d952ed69384a50de98ff281269d93bf1011283aed89e83ff751f024b33261238de17bf797f9b8e54e898223af4b619d43db9e5e41e7c18bdaba04a9b809a5620151528a8a9623d2b2d45c17dc57dfef70040ec8e414f6c4892a1631834202ac00ee787306e16387bd3ec4f1931f31abd7963050dcb2a4b37ac7db797576a24f2478d3c73216fcff961c8af50d7c3d084edf359edefa4ce8d2e62398e120b2ae923899f16a51101a2fa9ceb371115b68ecaaa3b486d5176598038d5f952145169538e8faf14e297b0b968667101aa508ea5981e80bc22997faa0ca833cb2072449de066918d88f4408bbc05b7b37201f55f923bba18e73063fd6ec215b377f800fcf291e2251518230eb526963e98113cb8b88384b4fb67e2f60b4ca1a3c16d4f6878efbb10fb2f2eae2f5ddc6c8b89f059fd601740bb748074248e9fe2ff32e2fc94088a1e6b24999558c1b29303f81cff7d846ff5190647dccb87aeb3de227af76e22ec61a117a2d7b4decb4d30bdc7f4b6d56b6c2f0cf782a6f4f3845207380c7ce73d4f8fb32862fc79f02729e142a49a6e633dcce8c1ddea95f26fc6e8add1d1eee895ce3710f658f429f77925583d99fb69c50bbdd8657fb99d564ceed5caf0b283bb39d1afedc11ffb72c3b37799dec6f41ad3fb1fbb727b5abd16fa327a20d403cd37d07f9eef2915db1bb7e28e639b061972a5fbc117429d115d8c1bb9bf2c6417829ec6184b6110c2bfe57243549843cbe54ca21d52262a4fee4d8e81b21c341d457adefaad4f45bfd1162852e428d32504af49bd4d6879c18692150a4b09d4789fad7c8d8fa364005fc451fe0e139f6a35fdc00f00abf6c12c40a951843f2503c4c112edfee754759008345af859c8dfa457ee59e72a532bdc1ce417f2c4161b802bcb525940748e9b4f1803fd3c98a998a7e10e30d40d892016a3207b7bff9d574ed32805f353229b59e31e19cc5a568b53c2d78387ef43137a80ae45fc56668ebb84ee1412339bb2d9282ed8425c5a71409961b645b694ba0c6d2f6a7947ef2a66a16e576f4e0b01d5c24f415c6f8bf26644b6ebd17e823de649d6b81bd77aaefd878bb1a64a77fce865de62be148aa69701108bd86141cfb1a1e91a8096186268097a43f66420d2c6eb9976117c3534e6885dd982be026bf2bbf3dcb6fcafe2efd8c4ebeb1650048826bb588446c28850cc2e26c6d4433418d1e80c7615bdd73bff39009bdf150eb9b671923e453a2bdd67e3eb5e25004851365ed72b0ad5a90f905750a60bf3bdd2a287dd2c48e95a49386cbc709b701f2ca6c5da4a7d65be04f969a6d88947e3b6c15ddcbd4bd0187059fd8cc88df02e478915a5b88df9aa3ff4eff95cb8c61f313786db40859b0ff2031d1fcc94c4121de0e559826336d01ea0d0d3f66865c3cc4997f2a58e1e571d5a6b000126c23f2e23d6f8d34c3d24901ca35b7501b1562e6e609f74bd553f101d05ef96529436b3aa3ea43b14117cbcdb88d9449d4ee76d2414f85fbdcbcfc9f67003d153bfcb67b40bc9fa9512f307ebfeb6dc9942508a5d21051ae903a49c811b592447c79136694e4f37f308a4f65b15d5c369e3cb6f8dece3ffee5d8e13e09c0308bfda461d0883fff1a76c333ff9aa68a806fb84a5034e6fb6632a5bb982490e9f08621ebff05d7a68bbe308e065193679eacfe6d1aea60cf7c574283ad1299b8311abc4ef8288c1b082493195f76f132a53f17087fdf026f5b727111eedcce1f08bf174ae81ba49177d18a4709a96753d6e89d3ec79bfa4eabe352e99b0ce8d9dc806fe34a99d9db2e2f62eb0c13339ade8bf0331aca2362407b9b18121a2cd443c4bd32ab94b94d0710fa822f8b7ee22a3f7442cc22e45b9fb2362311424a8db7c50be7e822c8b11dd7bc4a24fc686c88e6e7db883ee38dc3a41031b346a997552ab3cb6cb0997429102b5a32fce44e15dbe46803320b06502cb727302d3313e8103384c7bb43ea7d3d1d0b7dac5cd0b390fec0ffc9c3a84faabb9cff4b331cfc431ef3871e5f914b07fe2644287ddaf4834b0b73b6b7540c418b96425b1f9a66a89187b1c79277ab808bb8ab3669a851bab96fff23d512528f3cd6dcbc1e2d02f81f97f36490283a6d7faeac500e24aa22bb8353ada69a44c602f9e092bee9960ab5174efdb264424a92872093aa157bd20ea2a4a2c2807891757ac343d08f5e184800ebe5ad95e663b015b9c92cd36005f34b8e479a04141cbb3dcb3867c352fe9857264b4e5b89dd33b45a01e078f4ebf6dbfb487ce38308fca111d98f7eea2232b28b4715616db8feb62ee97b8bc1ffad6bef9035ba017b557c8b759cea63d70c6fad2ba9359d9f0e0954645a1d15e9ea483eabca69933663b4ba84a675abb7fb6859e506b07e7ea2441c5c6405ca842661d2152ca045f2fbb219098c087174e1dcffb683a5f385936bb8cebe40e13647a4c3e56520cd5bea49af13ff84d9a07799421cd5335f350ff172d49ca42a43422e2acdcb04e5cbd43667728db46dab8e098df0f16d3ee7467d8a96fc18ad45cad520caba268bc8910c2dbb6e539614aa82e25f0b18d670463ff9082e2fe531103aa7b1e08930301b2ddf616fb91ad4220d42d82bf95c92ef7fd49998e685444cf5bd6c433d29d0fa47e3dafaa1993f8e3e8c405ddcf8ab70faf211c41cc5fd87ced624b402ae5f8af6ee009ebe4e5f5714bc6437a5665ef065f1496f2e70bd3a0d81d2866d427f68d1ade70492b952ea88373a3776630cf6db67f5e0f7156da65abc3718517688f96af26cb5400ae670985556466080fa5faaa5398d90e45e2644ea7ab5184a98754f73fa0e57e1ab7eff7ddd6b126a226259858702311618a9ea1676ff9818a3e6bee664a9a88bacdb2f8ed068ea4a1c67f7812e4b5efb0ab0c79aba785778bebdd8a70e16e2676abc773d40a0176460444a0db672153f6e4b752d7a5dcc0182cad4b81efa9ad519c7c81c4b33574abd80234765abfbe8bb1d5b99b52e8dcabc4915dea087604220a933219604c58f42a82f5f7dac9516be105b40207cbc20f762fe59ada694bcf255e791a5d8a74d8a4f002269abad09c58b25f551038e50b788de26abb0a047039c1fba69ccba523870bf288eb9a583f2dd87a86b2b1e59b0bdfdfe122629528b4348c7bb5b53e9c3eef1b06711514b29291c9cb484f2b114c89595709a77d0131823f44c7ed9a0d4fa604ae89ee5a96d61292bfee909e731fd8808a00f5730fcedcad7e4fe8ccdc94b9911af440b8b8568b444af862ccaf3afad0cb19605564c8eab67d6be81cfd0fcae833fdd3b975b5476e7e4634438e4e0645ac84b54c026879c374c265bb14a43a1a575f71de494909b4888a4acd890b2ed6f3d5008775733654611d34022c112aac0aa0851a50962382fa5750ce3753588d63d02ae3d5a514b4f386ba4658b53dbcf4e8b3343710b4f4c6cbd2b97396996e082f91f5f6cdbbe0c0b2e9319885208f283e85207d165b8abb61d30c78d124f0e8c282136ea95834a9c000530c59a97e95a90c03aaae82e930d075c006a6946e8fcb3ce15c762b3f413edb82f9b57fdfe7a969ee0a04af1cd4a3091a57e0b70e7b7a384650ff6944a369273cf18a797d8a05b2305f548a90b23207dd84c33f20a3128ea5a6c8990e40e4c49f91704e1468770d10ec947827a92bf22e78e68b0a8c68481133024da4abde37c31bf462120d2875df034a99f760a9969f5f95b3e1b175ccf35f3b2abaff194e8722343a764a77ce394b521ce3beb20d9856bbaa5f9229a1d640992749c5960941f7bef3a8bf4314496fb037771df5ee35d8b778237dbc970be4661542b517248869d065e62eb47f8e209f0d08520c32ae4cbda0d22c6b50eda8a6e4ca020f289de7208f93d83343f86abd20dd03916a0d049e8a38290aa1a808edb5b4a14786b23c82019d17e56ecd8b1d16334a499388b790139c7101a77ba928b4b96a235750d8341e6d83cef99f7a769d02d5f8670a78d8a6c2cd6ee28cc0ec93dbcba0e5470a2c410cbdcaa7fb0d6f54cb1606f7bf1ff1c0dedb4a738ebdea02a34726d3820b255c5a0d6b3af99ed14076896f20492f1156241227ca66c34e6e16cb1e622c97f4a865f86c9bf9873848ed654fae118336cad34387876fc8535da91bb7bd52b4140b0a61a6ee02696023abac29d5f7ccec77c3ec82fcb6376c050c872583d7b022a5afd89aa7511bca88ee966fbcd5c2990840300118d11f68bc2ae5f0f4bb662164ee1f6490a6642c3e2cc91e24b6ff51edaedf2fb40e0c2678b5bf5e8cd0b3fb4cbeed8468982e8c20c29949b8d637b313a551534c6628e42f8c9070ef1e2903df73efba449be9039658986d3ea275b1e3ddb023c640a904410209f798c2095eca1a9b58ccb1fda26d359ca81731bcd7bfa8543f4352f5c817fcb5bbd6c6006c64993f56d534c3fb69917224b16df692eee8efce0c84238b2184fb7914fd3a53b5e06940f10230ae562a8af34b31d0c45e3ffc537a549a06dc4872d4adfdaa4d51d685de7d45a83f4a0105c90c17c696c3721441bfb2f07481ed81f8cedd6a80491d22653b1a838df2404de9923973f2664e03ae4a82bdee2076319e39572c20ba546a5b14d3f7e039f003412ee6896fcf0b17de9c38620a2f4243346d4f503cfa9651c69f4a2ffc72b53cce849f9bad5cd13c5c74e93356d0c0c6586aca3e993461276e542a06a94bcc041a24c92b35eeea055b5b402a8a49afec3684f74958a2279e3c7f775d09481651546445a22b43eed0fbfdfba5f20f3c1a57cbea7f234d9837fe53ace71333d86d98a341bac6409e0c09dfe9a8439382e26bed61e485971ad708782a902e821a885d058e40b978098ac8d57c92e08c5f6c34d71d710e5e54f042d4be65af0bb0a1d23792e176cae708411a1f10e4dd17473aadf6568acc1dcfe48b7da0d22b209dc3f4a4f52506e603a3309096eae1403d1d67a9b599289630e7c14cbcf5d22e999eb26566948d80e54b10cc8413bdec30b4c13ab405f9d5db9b51e36341ebbd4a933c7a42a675628d91591a4b075d2a521334b8bc74c892d19c88df1ac54934940f0f6a89f84b3aa804b185f1cf18adf6a753bb262567969d562e1a9e27c96875474a66c67492474007abd056fc9796bb434d8d25d5b12b1aad266007d768fa05b677fb21babd52165fe9b5055d0d8b5376279ebd2f9bee19d6c6bcddd3d98821868993d0569d16734175cf838cfca2e1a1b31fc616142eb73889c245e6693ad780de0b19f44a6341fa5bdc7e65e196220c599410727b9bb9d987d746997c15aad7463c3217e6be029f38c57c11ce1e5023013dc0c0e096f28ee1d94349a36b0a6e75cc30d741602cc00ed1f5926a60df1d93f3c6515c0073ac043ac2dc8233295b41499d11aad18d43f6443d9e8be244b490e356963b72e158219ab117f4e1fec97d6d41dce8074c97fcc4d1574759de76814a4058c979d2fba09809fc0a9a3e7bc1006a7a43ea54c77e06a4821838aecea4407f8402c7448a59bd0889f201396774fdfc6fcfba91705caa320977575bb616874c81dd00028c63bd812244a459612ed7ac0985a78ed82274789bacc962e2c4c685b91e9f2ec22ce5211a94893aa47ddeaa228a1c1a02531e8bd17a302c635aa996f84bfbdce21582e93c15d284897777ba9db35d3e6d9e7a0a0c1163d57d85761638cb2207d2dc871b41753f8c24029b6775cf14623c7ab0707ce9fa8b0583b91633169fbb8854229025d86111684280181fb7a3312ecd53272ec3b42fee3d99104f711bb52f13a6dd205e8a46894e7b20109d18ed168a5d314092ee9afffea6a43f8131f18e3b83b1552c6e6fdf5dd375a01ed36f6f36ba5a443794846ef850ebd2a92c1f84ddd341a6f78abe6800dcb98b05ecc252074afc29b06bf04f0b8eb66a792d3662473668f55e82e040b5eb435387b9de22bf0b8d147babe4ce62dca14497dc252a6344a57904d70b82acb9f8b808a02a74e0310bea1b14a6ac99977a7619fcee43c390241d332bfad6b05cf1a0257e1fefb8c4e733085a1be8182639f15b927ac6bbe8af8a3f57bb4aae031ee769fdcda96b0d0584798889b4de9c0bf01937baa60480428c51b4bbfda3449d2b84fae66f5057358e1a797a8a01a0be050bda88614d33282e29885dfa819500406de2c0c5c6f2427d4b766c6200cc8e42228be5814f27147c07c78178e6781c06bbb740ecd68c37852f5a1e83680f95c11e448d4fa9da1fbc1a3f8d37cdbf315ee646c65df85c468b3e7ee8f42606dacd969a35eae36713234dcc603e2d7f06699e4719aceb29ec92c9cc109c4af3ef15b4f1cedeb1d05ec93577149b8747f002967a89d612b28786ea0eaf376db769e29c1d3478cea1b799169df3a02d715f78f117105c5a2e858b778d25ddaab8e0eb9bb7f27e72533c50e6c75b3af8f7c16d05a8f9a9b8cf654ce22954436d221f58a4f3c277590b4acddcf991d2e511e9e7546683d59ed4a21ca875725716efe8d4e4373494281495682965ab21e5cedde7b984f34f4ef0482d835b8aa0910297f02446fcc801cd27c7ef12de7aa4458c2a0a6e7c8c8eddac535853afff5659feef2ae7986bea78b3733b8ebfc76ed9a64af60a8a167eea00afe217878eceeb0ee13ecd598ba46e4c1527c1040dc50d88ce9a02f214d3b8a26e4a8a132a8dd60151d937cd18a0a3659a9cd1e1450e72c218b98c44c4d7352338a6fd0fa69f83cf3dac8138260fd620f2fb06e86a71ec5b0e1dffa9a4ce2dbdcdbb6dfdcf88258917b8b42acf0947081786f073d8dace8655c14b6c5a1eb0ef371031ab093291bf6795c2529b5174680e1da6d0766af7e160338bd683ec6fb59f06d3f509ca23af59b8e896d55e46075fa143bc90815447c33b65203d707ce849f82657b9462fd9f329adae517d5f88370026469b3b448a9049bb267365384f8bc275c30cb48d95430b9375d42f0ec7dd00992720ff41b68a3f2037082619ff2e1e63272028875fe04300f1d68ac08ab22c040920b4ddc70de08f35705f9f9395a7c35130683ee4965b8951c6104e6f169e0a0c2290c2bdd26a36b1057d6559682958121a62900ee6cb49690c6d752a7c0ad88812198268a2e6ab6dd5a62c0d4e012e1912c591d560f0ad5575a7c780576125a92b75883c66ce5d3555efb31bbc0fbc89400e796aabfc63394d8913e114b024a8cb5cb46fe4310b21078c79fae216afdab60df85193173fe0f3bd0c3cdfee31d07c717f81c307b05f093fa7b558fa0b3d39d1db4280c0abd46801dc36308f12f266ddc550e143e2479005ebe89ee664dcde528e2efdda39aa71f0b47f3a99fda38b0d734c4c7dd63a6901ef1b243ae8b519cbb4d82d34509b9fb51608f1cc5c57eeabc8b5438a7f291e59b656c7860d3150d790ef03913f02b00f4a07401faf54bd56d4f84163a198bcf49c4fb33b1e4e59d9b0ddd44d74bb3f58ba6d809091572382a3df0edce5ae107390620bb87771195641c210d8055ef7de54d3dedca92dd7654a3a68c4ef818d6d0c7de59c0ec7e43535c29394a7904940dca55805b7e6c544c1aaf60c12bd1715fa06c7cfae7c3d695f1d52d6c021ff001ce1f08f7ce03dc9da63823557272ae93404add62b8bb3a468c0b3055502a48567ab4d9b4b8aa0b183c2f251aac11bd8b933bc64c55072c1bd9ba115b34bb087a014f41b0d59ebc4950fc79d607c179025910033bb31dcb958f9a72e465efd0c1aeee956b74f1b80e711e919cdea2879dad3e6f0bdb00e5c7ea8b217e286b404ec8d9b55af9aee76f1c6b3a4d80cdbdb8b25dfcdfabef9b478640fe0d68418699110ad67b4edb605b37c57909b7fa20f0be1a6b2a738a6468572d850623386d1a0415f4a59ad4c7512c6c8c0b9c5766b906979af8c53b2cb120eeb337901d92980dea62a328ce2d0a9f1ff184b28b1144f589ddbf43f7ed4d94fee27710a80bea5b0db9aac69580923dd080c07a49a047b6f76b5ec02e2916468a4792fa4e529149a4a5d5a1bc5c3063c7e64b6c69e9a6c13555d6d0f76e2d9f6d3db1bbbebb95fc7b1730e14db144534520311c4c6e1322c62bed1bd334e13fab7e3d3ade7f3867a287c9d051ddfc54f158d1dddcc671c74d87e693719d063b35f35668597bbb5eeb4f258b98812e6f7cf64beef197d85172b38abd4ee5395a835144405a0b7421c4ef15b2276ac78527df679b8efe91ed62784b2786404c9f8a4054182b19f7d19f76288d1a28537c2ef8c460fbebd018905cc80163935fc28fd2d8c40b3018e8ddfac214b6ef611cc990baeb9cf41d1fa55c2d279800e2e1abd8d41acebc9f49b70aade164128b9f7bb7ffaa7029b9605765bd2cdab95d80a33fbc38e9ac77709e53197a2c5ca63059d657c82d5b6b0353e3f616377db2559357c0e87696f509d10be74d3be4e9f59ab6e2fba953c5745d433cb78e60211b1d03a5cd8fcfd71121d9b75788984293d6851410bd8d6924d1577cd940661e14a343d6f9b036b9febbbb96e208ede8e6926ed2d589d8b7fb81b4c84f0c6ac74804f9939b6ce1c899087f1a4dc3026adac9f4c4d5843931c599ea4aac62a9134060009229be98945ba9d7f4c9e70e1c968315395a8ca3c00d5f61876306f61dfac00103a601498d1ed2a0c8ceaae2b5109a3e09b8dee3f3b678f0cb1795954ab00c041114dd2d6827f7a046cd51094ffd5941270dd7cac20d8bc78145dd93380f815cbabcf7ce57a8bf88aa9ec0c91a863278bb19de056e9444222038ba6eceaa00d8668b54576a870316403d61222c29592d6cc321916e34aac956a54b321f386b45a236beac9354f4331c359f4d9aae7685673e5e11111c812c825fb13906d0635c7715171a48caf5dae41bbd13102e6acf5d40613245f5c31cc280000b92e8152766ae6013b92d6825469894b80eb4ee4184757fa1f27672d9ccfc4b19116aa2a634e8e1221f1d6c949dd1ec02c2fe5c7dff0917eade49f84302c9b24f47124efb993e85c628247dc27fd062de828097e5cedf077115c0c3a8030b51e441fe25964ce1e09bee8114a68805198152e07ed84c3b64f616de6c2c19fbb2c94fb453db38545413f640440dbbefa9c60b3e131206583ae8cc5a501ab02a4a45f4dd22c92fa04941f85948243489ac4013098cf2ac60ecbcd57b80036c4764de72a3c353657056c06f2db161b6a50ab0241872a9fb3f4c861c4f4cddfa450e146c3019e9f8e5387de281192c1f96d0a56c07d5a648227ff1407965ed0c8bccc2e45afc62a34dfe6359c02b5237a6b7096e574038984d1c6c120166b62ab4511d54509db9020eeea9782f8fce054a87cc0b41a78e0c252647070881072fb197cf88fd935ac2e304d58de9dc1941174532a9b77c1117478bccd1f78c8b87bf304bccccd3f453afdba9b324be797e32ac5b7080291ef9080aa8243d6c5a52723cac1909c1a33c64d8a4b0b1f43d63005027d09a741edd536437e8190d94aa2f487ca395d812980b20e88c10f6b747e25e7f00c5339e4439a619964630805fba195c75d95a9106e59432b473ed9914c22aab0e8d6ffbaae4e7e81b2c4b59c23124769cae7ef58c5bbf8deedba22e4048053b8e08368390ac47884cef1c173f9f08a6d2f0eb97468c0a91df309006c6a1a2646bbe8b4b51b9812177849fe6d67281dc67746fff8e2b14146b4b87d5bcb8707004bab3bac8c3f9cdeec773fff17b942822c1d7b2dbe1ae796fd8a033fbe0f118d56d22ad5536bb00de8bab6b0de89f5515ca68c1993b5a06bfb87950f068265046bbd408ead1fbf8c85bff5cd87a7012bd3f5302a8c7fb4763eb5183e1dbf8ec121a9f66ae54a4df68dcc72c3314b990246dd653d3459ce6cb8c1207dd3f25008c17dd480237de4fdc35f26cf55ea65bb3d54464790e02f375db0870a1b14e88e5f9aa5dcb43f0fef70ef80f20b167a12ca21c3cf1d3a4bd93880b678a6f025343824eb14c778e5666270655ae11c6cf6b38a4f0870705bbd0bc96cdc1b52d367cc9cd229c119ed6e988450d12d60cca370d08695918a18b3a91478732ea6deffd31e02b20362c11e9ce24c0648bd9853142c7f76bd37b35ed828a412384eac36e0b454e1bdd327bccd63960a5c53ba8bb2976af7b9c5442054441695be40584665709e157f121afa2fbf201fee4c97881c966237dd02c2ec3a8009d6188b23434567e66cf7a902e5832eff9c26adf9e36b1185efd1abba0002ec01d3115bfce4692003c158930b27379c39702f07c11fec017bec4cf438d29331583d5cb9dc639ff206d9c91fabf2f148bff2b4ff1907b9a0864e640931b19510c225c55f14c007bc8cbae3920dea4804b3811b7a01c294e532e157b87f4040ba1e0a8a0a2b1f499b43e219f48979b160776183898545ef521d1da9f0633f03e9cc351bc1a87096be6d8a315234c27d4dea2291765b80db0a7698cfff070cb4d4c2e6c59fbaa34987eea7685925990005d1acf276bd70c8b0cb81f89c1d32cbb6df4d1facc82032221aabc467a20c3e0e5d3e6d0d75a1156e910ae1461bc274357ad0beabe08b3bb05609bfda00c5aaef3c106332a3bfb2ab3f9e75791985c7fc83ce344762f25e64fcd29aedcec4f97494a8d74c7bc758e3721fa5bf70458a2ea0e8920ac540783adc93efa423b7044f51b84910a0a07486dc92124e2fb333b798e0288aebe053811788c2e325d3bb5c1d462e4027b610792e37389ab53caebe6f62af3cbdce37b9af3cb4d63700df6ce3f88d1ff5eab7463b59d8b8fb4d0450d3a1202699041ccc5f2a4503caaab09003c57b31d7e37daec8737f62a5106eceab07b971d0d6c4c5c1e882b5118d9317ba1a32ab26c9cd02b2ab080851496ec731fa9666fbeecd0b76af5fa4e189e4ccb5f7d11088c8468425162d9962da8d823093952a85dd165b2759f811a862c1f2485914c337d2e9aeb54ee02f8f49e61d48128213b2368259b9ea2e5f2ec18fef363bd80657f975ea9dd50bb34fb1808f016346db8b23814ced722776f47dbc207de4db503c057046f47f49bf21703fc5a53d271d208eabb72f30792f2f0ed8ff48149aab3c19e15c60201000ca3a6d7b6e45ab48c89bc1e833f74cb03663fe09bc807f14f1129a1d964d597d68d2dcf7660f92b64b52c47c4a3192a7c0ad91079753d9c0c434b0d665d69370c6770b1c18acfe968d6fe2ca949261d7815957d3a4927a867d3319c35ea4b67bdabd4c9b2f3068a71de7f7aa74f7443de6429d50a62d962983440e65e28cec3c4878c9db79559f87784f0ab10e20edf9bb3b3b69cd03f3151d39bf4f267bf8c90bd591d777357b38c4864d39d7be3d6191bd874dd013f4ca065b3d74811e006c831f8c369bfe1606d173a419e2f8958cb80ca89c7f7eeb63aacbe298a5c978af8820e5cb7ec66ca9092406b65fcc4df2fbabc02d560549f921e124b24352e0e0417a90dac49890a6a51d2316ebef9061224621b0407b7c1da9f2078fe368e9952fd781e3a155829672021cdc08e666db3b3b41ce85d130a888f422eb24e55def4e615993a495f19b607d39e2620d34949911e4f9cdb43079f4ce5866b374f0c80f358698869f32a47794d7c1f672596090f3fbf00b8a624bb52e41e5efd1a1695d269551ed7e62133428704498ee4e6cc9f53081f86233eb6887118b2448840cc7d4a84e962b2aa354ef779307e73b22a91d7bb6c05f05e318b24dee7824a06ec98112c85b2a7e4638f71a4be3bb44201069584913e503883016740f176dbc8827d86030b2f1a5167652241cdc01b9dddd27a2b6e0aa4a59c3eff0c12f0c48f63fa11a0afb6e6b66a7f6f2be5e625884e56741b888f8a691671320e52738c7caa30a0378096041e2aa78b1e53dd8ddcc12c0fae1293eaa3e2834db11d4d803e744d86e922921d6789a19c3c52e58d9bf19ca59ff9727c1bde2079d07d38453ff43f4dcf779fee18390dfbd981298bf9acbc4a2d53634f36e1eaf4d8fecb4df053712b758920e76ce94dc3dc1c0b7fbc7ece310cf3f44cac588d63d35ac1b6d9bf84a00f4d10881d8119152d2906b85cb0100692322a0dcb76a3a6033577fb6c5b99c33aa76952b490572e01f178e79e01de2790a58080796fa1848fb71c737153b1f8812f080ab7844f2ea8a4cf0a2a8aeb3562c950d38a664ff2caa37fc8c0523da2b14af03e46ed691402ecf39bce2019476a02fd5536f3389a35e6ca7cc75e9a3f0ce3a31f0e89f3f75b307bd05588170f7cff65287a0c8e091540fef3f232c1063bfa0a3b29f9d78a420c1388ab18b6af14f9389d743cbf0f25b12bbdc0756143cdaf7bbc42c8d6b561df8ace66363c431e27b3c75648bbc7ef993c378fe5cea8bf29398bdf6d2ba1a85e7c143f5dfe2dadb1b5d271fcee984f9330e9c3b6ec4461f798f46f08abc7c601f4b7e183043371f38e3a7cf055f38413dc13d846cf5319c475710992671b5f571c625c679f243bfc85f25ae655ce205534caf0dea724803078ea51c0630cee3d093bd2f02bc21f4fee2580ee38afcfd5feac2dd54025c938b0f0d773a4e23d5d6862188dadb3dce9b6f3e125f9adb36b656a3bacbfe212b799de2a5e6c84b39b3f03c97712b3fe30932eacc32a944fef7f4d2811247b520222e4fcb97c2c7675e161995ac9e8be7e1e0e455daa2285539f36c0ec4feae2953f480b6eb4145e40b7290037c9aec222ec27e1921a5046172774cc49d8ccb27e6b5e737fac4c7b8eb71a48e8bc1e6bb764dbb705838d75c74191920b8b03d7f360896bd16e8a5c485d4a804bbce7ac77965c1c03546b9694d6feee9eaa441cab0c786709ae6695b42f203e15aa1d37e1ddb37cc34422d23a684892bba05991b08ced036c749a38e583727043afe3fbbe5f8bba7f2371bed4c647a31749e9800565116e5601d33294d12acfe2a9814d5754218bf7b6a9752065e6ef831de101266d108f9a3cdabbb26a7955b724b8efeb07efc1c2655795dc704384025ae8540c80c6142a80e89c36049eb6c46a468772da4dc8cc2a4618e06b5d8055338c3d5c35057515ead491dacb420b88bca51d5e9d489a1c3918b41f3a00c4680631d3854fff7c2c45a2559fa44b4d75e06761ed4b6c6c6a1dc15f7eb50264ac56bc98fa1e814a3ed725cddf162f69d9a7155cb6e775fad6f3706444287db67733169966712cc276e9b8a11e20f82b73c83e9fc543a73b86e0c9357bbdbb8d34cbe4062ad3c5572c376913628ed706073e72a66fe8e0a246e001a0187a8214ff8c79c84a4910fa2e6743a1d9a0e1a02482361a0c48b0bb164b194239b91ad955c28b7028e7b29dbfed663362fcfd982b2be213e29f0997f0199b527a400a4e313ef2fa6c47da8972134009c09d18bda1216d28a7c19c16aeaf065310d4862b7f28e4c62812ce9c49140ed25c1b2e9d9aab0945a9922021bccbd4083a166bf3d6969532972c96bdc3e663e8b712b777b56f6220ad50d7cc79e25dc8d447670c44d2773b3247d575e13ced21a76840a31fb081cd9174fb7ef315ebb28e4f7ead01a3c7879992f030b2da5a73447f894140ac9394dfb888c4368670b5a2fbb9e7a077111f1e4acb674f326ed49527557d81e480275153c340f53ea642bc8b57300197bfcfe8d0c5fd879a18bff052d7a3baa2a4ea8b8314502e99bd494b478e91985d9f6cb2d3112ff3d72ef206eb155f4ebea9c1e93768108689d80051f4db7dc9b72f649cf8e8bc9f651bb25e5e0acd9af5fa65652db7c3519163cc2f7b7d2f0bc38076037bac332f9b2221040f0044ec0244f631f990424c62b9613d3821bcfb8d47d12dd7a4147cdc5d5f497008ee76c6427b2d5c523ec75983d80739f018763e7514f3e23f9e228429d7f095ccd34d6e3bb1db6e68d1e857e07486caa06f3dd9af15e6e4ed3b6baf04470eba09c8563d91f8368fe6b16794f8d266de3d17f8000957df756f2a61aed09794c05d81335283c2dd11606bc1154a2bbc0bc4143e5b645ca4124c60c991cba028e6cbbf9b7d9af4dcb14eb4c8591b3e90b5e21619e9d97ff9e84d5fb4ec72b7577ce3865626db803a4b8d876dce7b236163e48570a21b74d19d29789438558a7b82b72a43ec460c8ce439a3ad97856ca7c1211fd5b515c16a1b05c3d77ed2012a87c2ed02a4ef6188e387e6a29f7e3100423d5fef8d2a9f2e0cfca1db41fee0a6688ef06debc36b9c5d3f50c355901eb661a580609f828015176025a68cddb695f810ade7a91bfc552f3e936ca45d1953b34fd32ef20f15964bb1e1b36ef92a54396bc11b100036659f40177eaa7049571043581e0dedd9eec1470c2cdb01a8a47049bf4a4924dec454ba429321b655214d6deb282820f563c4b54a0b1dd625d8b35f787e2f678e57fb945cf1f14b509f295a5c5ba11bdd4baca32d0600d89c559dc789bddb1ebf204ef02f95529359ee7c99d354111b9853e3589fc19f4b8d32383b65ff0c23bf529ae22cdb69defbf8c8b7e1e16b223150e4f1f20840889b0f9ac1057904b139079fc073c3474e44ed1e1c51e834d18d3fc92cf99de16ab674a5c7e6bfe1fcf58e1db1f3c6309b5bf6b515864c1cdbb77ce4bd83db8085d3640e50db760553ecb698d74d05fe4fbae176eb74a225a3fc067b7279de640b3055f2d3b791f17cf68a3dd89eb5489e39ebcc06e466efe1ef12ce70d6e676c36e6da9c35d6b14be95d48545475b8d8ccb02a75268dd40838bc1bd69930013edfa7fd5798d2f2be9fdc7edfebb343d3a56c58b02e2c620bc78cf4ccda83d83ae94adca5accdf57d0536eff02080a0ea4a1c2e03c0f68d3afc12c4c752a23f5c346df83784fa8b69b5325757608f723e34b2dd408c74574b564f9b1eca69a8921b1a6bcd2415517f280d2b0ca492521695543395a6bbdc47988e06c7ab05458b02ad9ccf0188434156d6b38275160a0b7bf103aceb5288ab4becbc8f1741bb2c8c49b1da826d01083e83b962b4418de57467ca8df46f4c72362518b4e3375adf7762a6455ff73ec2446e93d225edfec1c6cd6cf2b17d83586297e543b5c65adb9b5d6f466f8598248a7053ef52ee31ddaa20582a3a24970434604364c5a6c4727477b4cf9af55d8dd3e6caa6b50cd02a8cca2278d1f987bf403b9893a2978f730c5c9b52abd976951b9ad6b6f8cea8230ef4a1e44005539bbe44290fbf279112a07fb4358efbc17212ebc475272d0db183e2fa570cca5d547a6287e82ee1f0d2ff02a6b6f01628a38884f6f39cbf479b890df5f777477e2bae184fd256063db935bf9a2a1920e103ad3f17d6b592e7c898f2dc70416f8b2cf901b5127578b5700904b4400a1cc24f5e465a38532dd1aefb01e7752aa7dc1ffd2657e8458923ba07de6ba824b264531d9338f55010f770e9fcf89025b8ec02d6f0e2f5971147b9299e37a70544c72ca8b388ac551f0eb63ce79752496cd925f08c4dd2b63a796c66023618e2ed6431735104f4d6940c6423957105acccc4236e98e1237a6a4b2302ec650d836ef4c30c4c149c8c4b76ee67a15961270e3ae1140ada2d23182ecea35aa384d57085e8c9fda3d2f6740fff763289f71a831e8c099fcfe4a0d8273b28d4e2be82967f19e86f0c2ca9ab4f10aa2fec15039689e95fb569cde292335ba471867c0f6be2bae08361c485a9c841c4ebe0f0a6d9569227e8a986bbf677fe25e6fb8d14d180c0a69ed48c02529bedab06aa752875a553df6f01ccea29cb2374b41ffdd90f4469672b32548c283ac9c287cc0ab22e0b0feabd3dba9fd90d56fa6c1f62a3f9e2896f4dd1cf42493e9cad4990081a27c88caef9661dfbbf4b6c663dbdc12121f2a39734b4715e92473c098ad7aa2893096dc23aa33be2c1993959710fa7395ac23bbc2809003926ebebcd4049c6040bb088c4423485c2f76c809f1726596c646bdb8366667d1691fe7dd59f46aa684ab6c8c31ed3ca15e2a5255f3d294997cb3e219b35ff27bbaff071c8ba88ebacbb69ee51e99119a6b8c67911293abf4a4053bcb090ee14ef7b60583274d2f4b41a30d73a92c3fad96dbfe33d53887e3cbdcd0711e8c9993b5adfc8712102bb468a4a1f674e00312664395e898150a39e8ca0e666113e1b36ae0602fb5dd7d8a44b9b18f5bbbb65c310b28b72caabc97eb3b2e700d4bf59c4b553dc37b2b62265ff316173e40f4fdfc68608c772927c5fbfe49679825dd1b3a8dee9852f70680457e741101964bba578b051066719b863caa12c38cb293d76ce5503d42fe7b2ba0ffebfe0d4c22bea059ef022a151bbb55c0c28cf35fdf7ba22004c6e33abfaf9527dece12588df388f12a5c41c0c72e7fd1657d39ff62b0ad844fe12f5483655d1c47c3d6a2853cbe45811421b43d6dc43dbde2e3cd618450008e62f6a7f3fde8ba2c820aad7c0dcef0fb8b7fce956f4159e3b6ace61736d6ade6300a32084eea0490d3f13d92b7c3390783a29747254eb2aa0addfb10026f7ebcf027333c0608909c2664ee3e4546f8e0a44ccb0abe3a1484b0ac80e51beb2ff0e5b93bab5b498f693154179fbf6c10d257ce2319bc946c56d3c8789df4ad78639e49b7907088a99a0bab7b4ced2b72682165a09bbdd6506cd3b6fb7d4cef87ac39b685603a714f737fdba4a3dffbb168a73a4bc5300d170c5cb2826b843b088773114754614e510056fe7af95799a0ecdd285e3d6824287ca0726e54754ff16b2d30ed23d09fb21e8e92129dac75dfcc1ed459cf2fbf0b25ca9057fdf9f2ae01c129735d7755d53c97ff2af9c24ffd993b9b3db2641c2c237237df269d6c22bb8c91be4120944afb2120526166507f6ddc1cbb31ce6417a932334d0dd59a49af178519259b7a845ba2f07e447b909d23138ac057dca3c0471647c1d69ca7e28a04c9fc229f9ab94889de1b2b3fe13421b9f1d5eea29737953daaca4b3706fe954ac3d25e191081a065066595266945950a6a8c25b26a2805ef245eaf5581995d21b03ad269e332172147cb135c4ab81bdbc5697ef19022a47651469fc96c0770a9e70329677ee916ee878fff5b50b70432b4aabcb99387272238d61c20ee550216e0d93cc8c3673dee9848c239923ea58beed14b451b3fc4496752d4bf1bcef73040868a7abaa6268eefc3728d14c7d18070c2bdc8474c423c3cf4473e10bcf1a321364656595d3776e34de4de4880a1899bfdfb65cc7809f8901e190156798b9acdd3474391871c9cc04f98b3bf24ef7c4d587747fdc05eee40429d56f1251461cac6d64ca897338cddb56f61dc37a6ed648e508fb157163c00714de27312229e24736bc1e962933143521218bc1009072e06b3712e0d30606ca129343110eb68073faf8fd655cb16f82e8bd1634e4204776f66755979d4e25a0c93d714cfe9099dc6a958da426419033b377b8361129bf8589c5bedfa188eaca859bee42b4ea86f9a670fa5cb780fa36ce71a2949883c1ae740cafa15dffd8e9c44b88c7fa3ead280d9c623e0ef30f38dc9b0b09106bdf9f7c2447df741bd37d020400eacbd2e25c52d09566cb92f22405df1468cd0410d28dbc48bd1e2b3151fa9d6dd5b93ce27ecd35b9b6f977f6facaf70fce4f1bdc803596fc15a60dd37246ea140bf10ec05ae275223d3597c5aa19d4f0ce957000e886b4940c711c948e5b66f21dcb7472d340e0887ff04029f22fd2d8e9b404294b0915e54a30a5c996ef3a0eecde6f060cc38d1727292620b6fe2fa32cd71a935104c21230d8d1320df0bb9a78f56c6d35f7cdc3112f00472be526d12adebd3f0349dbec7128aedd917716c7ec92b5aba47f52207545ba2522c614ad462c660861f58bc235224969a9dc07b85adc193ba1a3373c0c0572a62d47b8fd57e1fa257d512a59d55fc883b076bbf8fcfeaee45b3c09312bb2cdc52755729eacc292924019acd6ff73064a9c6d4c497690cec0d763fe47cac8b9b6dee088ca0d0ef0607a4a7476556924a8dfbe42f52dfd7b41058bbe563c50d6184f3671562c564687844a460d5729c38d4050ac0428421f8f7e9b604d3d0942db4f89257b7aa93ce2bb2996cb34991543268f980d42532c9b84b75988406055f7a041ef001b8b79d0bce8563870f6fa193d03d4167026a74f5f6fad2f154d5fae917eb1a5d890688ff4f075f7996d3e967fea5b7c93350025dc356087dd97c727558a55403aff75a5a725a8ae4ccc38e2af21dc2ab9625ccb21d84d99105196acd49dca2faa1e648320dd8d7fc8e4212327ee54a83f91c22fc2e945b02430a66c08091451effe08f513e021268704fb2350f28464743c8bb86bda70e20d616a7dd891c3df1a0a73239a7a39a19e19104cdd7a3166019fd677384d71be0d107ef72ea0973b47d76f0bf4ac7e94e1bbe7dfbf9fd967e2cffdaae66552d955d4573e907c125d944c55a9f0bb5dcf833d96556947209125bf4c45c655bdb69bc0639d481093c5b97c0d7401b83cd6e6e603b3ff0058d36f3ae6ef087e6019be08cf87e8a55f56ef6351fa703f40b34430a890de383aede166547daadf6c7ed9d9b593efaed9212cdcea0026472fdfc1a8827506b32d0460d25156c4c583247f7f591aeb3423a7d362880d32e370868cdd83ebf1003b931575e673c700aa3e0b1532d0807489c062529f2c3937ca668a8a6c071387bca35bd305539b5c3b02c671e80519c4f2f4c32893c123574606ce8b0569dd3350c97350230f5c3218131158706856e9f8bfa8a7e7e3b7dbd0dc30784a49d9cd9ccd947b1b4756e9835c91f964314116589ab89816394e65709d43f71acfab06578408c3969fde6eabd0a05d0d5ce6e04a79761de023d4d1609498df71250c7049ea4c1fbc5254fbf6b6c7e8a7323c53d65ee5921722c367e27bf0de2d6fe3c147f46f7d90f78fa143533666693cb560e3415e365a3564100cfab98a014052bdae9c71cafeb221c58e98409f0f924cdb44484d6546a7a32fd0b6cf570a815387d48a59dee49dfa9918710edb05861dcbfc96a8a22106df4278fdb84a0482ec26487f1ed8320ade328de839f50855134a63062275c1b93990f15409fd6dd60e956e7fe23ecf69f7bba5aa94144df1387cbf4d4f447ab7f8d8630170f45d21aa19727157e19bb02074595d57b598d05d73c3bf468f1eeae732d2eb262f24a3039219c9c4071a2acc1dc61802bd815e7c03d6ae74417e0379e3a8575c625bf5eb42adfac8e6ca33d8ca386afc14357da0173730de4049af446035a3883a9f10c4efc6548b4200fe742c476945a23dba6d3737c40a0e02aa44ba4fda821c73ade36cc02c6fbf10aac577b7b0263441261379e3a4d782bb177f67dfaf568f92b336772d7707a809a7d3aa875857ce1a89c9ae6adcb0d010d9c01d02fd6b7c38c580c0a927ded4a20e020240118689ef0e228e6a84ab7cb5d88b7058fc2eb9e8f67f77a285c4d341e143515e11e8f9219866dabf30a09e7ba3de1cbbd05b1cee9acbfd825eaa0145988d5a8877abf20c207ef323c0d8a746ae3588589d62519dfd2bc2ebafc9d1175267dc1aa58b10cd085c1f17b730ea6f1142cfd284156671f088cbbe183bb36566e626c3384ff517a1428afaf5a08368b8dc3bb0c05b410f0d5d05b1126196ba6b76361366f7177efdd68257201286fc9477bcf6fa7d24d25afbae46ce3e3f37a5e7b0aa55fd54028dd344a0ae4c890cfd4924193cfc6fae4d0cfb8af38e2878b756c47a2ed26201ef471ae46c73bdc4c312f3e9b8460a2a4ac26162dda25ebfb7d3f09a96097ab71b9537b2e28b4328c94d29b91225eeac3349a1a47d1a10dde2a23857d7d7f9ba6c48169811dc902291ba6bb36f6933e17605cbb4e30a3dd34a15754fa9859d995100482f75db689e9d982e4534d5ea08f66911a7b0c229839ce69c7dfffc2497ff79da209741d4774d03fdb0f2c885ebc6fca90395bdab29888d54d414c8e600a754af666a0ad49cb978eff608104dcc73f4c830e1327736f12d4aca4b8d8523e7f624ba51701ebeaa973100e241d14d05418d929a5d1d801761abf1185690716a2ae681afd6457923f2967c864c70159bd126436a005b197fc9217212d81a91ec80ce075dbe12455e88764ec08ac72f04679fa698fda34caaf60d07b49e49380ddd4441458541ee134214e3a5fff705128987c88d16dc25772fd9cb19612b82109609a47b894d03eb3d2340572e013a245607aeba5e975e73612a44888a88da3e903fbf9895bb3237344ef2aa9d86b82eb9ecf6ef118e43b49658c2771a9d11f229b856b3300fed00dd3fb0de2bf4d7b1dc577712056d17f2d71717ff7a0196528687f540e7fd1f0627a61be6f4a58b8bb3244d39beb808c279cab6c370e2e149165d119124f4d9e0577998e56154516eb075dfdba4242f0a35c3f081c886337734649a04dc9848c42baaa06d712227ec888888c87a1aceab18ba4df215171499224f06cabc2389368bd928842e68c0776b41e0dc3febfa00c20fd2e379f26fff27e68240b301bcb21c9fc129f7249a66f1ccdac22402620163b5e3cba1b90f5802b320cdf687168e48b428861c82f75c3af613ba24e2a540ef1f7182269f524d22d648f5d2b81b3ad5646507e671493b4bb3cac8183dd411db242add2ab32a6e70b69353f32352e86b3bcf131b8b7f41d7d14751249904add705998f284ef3792eb76b5ba22d4d33ee2636a2644fe67d168462ca6388d0324263aafbe3875ac57cde24b7357caaf830f5f837305d8669ac385c0900eea170660b75a4accd6bd7a9fb59ccfd8ed985402ca2e3545f5fe8613582eb3bbb4a914fc51e17f76f1646264b82bdaf148187499df00df8bc182ec06bdfbdee56e8cd754adc5fa7556c426320b22ca1da379f68a0a7c5077e61bade03a29f001406ac6f86d88f165d680c6bf565d33a69309d3d3987f79355eb48811f4153758ce8c2cd030edbc65eba1454f567557be3ab98283699bb3a3bf38c9bba05e31e7700d2bef0456aedacddef05716d4027392325057842793c244a76c8d14e062b0fadeb838a19dbbe83c6bfe4ac5a1691b92e3fa9b9617a210c193672a4be2ce6d74cd35c0f33922c16c3d8aa1e18248c4d9fd1422d8b616bff15a781013f42d0cb3f991073aef4a808a9db34d297804c32cfa4fc04f3ae14c5fa6577ac18a6d8000f09e292eff33f3d0b3239ae334f97119e84112904485328efbe95d69a67ff5c2f659bde1c88be6e6a7ae90facede514732f736763cde4d8b4253a0638b0063703d062957dd154d496c7a7713df14441afae47bb4763947075bc9aaef9df92b69d967ddb073de59d11de21cc44cd8647c600e78096031a216d64e1949295633ebeedf1901cde3f300c49b228c76efc2aadb1dbae929112635aea7633025b55713b4fd1666fd8382e2365037544d22b3d81e0230a0324b0089262404e3effb62bb03c662166688f0aef12283da5db12e67df46b0049a2e1349ea74d859fbd43274f2db6fd76505c86c8ddd8e776fc796abf7841f780449308f65165cc34024b7c33aa75f7797bba077cb1428c495c75f1b91e340a2416c75cff1972ab5fc1b49de2b0f2ea8e0319b6edbe1a56f2e9faeb750a0fbbb5d95fd65a212c7df4b7b9b59e0ff5c081346ecbae9e588e673d0319d76272c3802e515f444d3d5ab4648897487397992f6d26bca4071bbaa677c5cef3a986d629cfa4e05f76e5655852898859e8ecf33aee9d9591824867cd12068031fe9f551dd9d1cf67d604b473d940f9700846fed2b33667b0c510188e11ea53f62e5150b72f9318799b4185d454d882cdceb8bcf9e86b1d6783286bbe83ff40c808ac2a073b61f80c0d72a326815671012c8a6a9a5ed456915bf04450f3fb7f106760a923a68165c5ce921ec8476baafb1dad62642b0d9d1b9e4f5312872a398b168ba568ad918fa4b7daf2ecf64895282dc20e2d151be036d82e8acc2f514a263b92df5a0261a201af7d7b71a2104a7a29f5095a4c0ec6c8bf43c2131d924fe58ca97f53edc4be6d20b777ebb2c64e0829d9c32bdae54b4282573a82e322a5f07b20adef06928a64e141fb4dc40009c48a55f4fc03d2d36906a47a6d2b43a7e70a619198c83211c55c38c742b99492f74897244645f8ab741afc8b671047f4c214ac881f0193df1e1964b4475c2cf668e76a3cbb211aabda17049ff7488120f8f3e5186de8da70bd2574c05276b5b3b2162a8a7d751bd71ff2667565a6e8a5031a5a8f2e7e2d084ad612351f33529affd35926f083440ed4d036744338c7d64766c2f5296590da6fffb6c32e8792fdde0267442769490f856aa7886863585009423fdb21a9769c6c7abf367cca2786b677f4eeceeabdc85c24a84dd336e084d0866bd08513b4addb4ee6824e5bdb3024ceaa083c3788b11f0fcc9a5a0164bb6f6939e96d351e18d0799afbe2f312b5293f2b21cbedd8dafb93b992eb2d47e0f3a6fde963344b4b8b77cf465404058458f21495d952e225d09f25ae716794d2dadd88ab8d3d4651b032e60d297fe89c9049bb552f712e7a8cc0cbae2c4a4b5d061a5e7502699686a5b1dd986a662254752ba91d6884cc68d5871a666def3275d35b3928f32d6e93a56a5a22ec0ea2e1fb8822122d555825424eb2f4a0859b906029e5c37442e174c092acfc6f4829a5239fab290bb24f4ce59a65fd4e80151ffb0817aca794759ed52803987d2fa060e4c9939a179765ab04e8e5d1ed4c0afd3a4cac34d5ab93eb93e0964666a9975b9026bd47bfdb1a3aa0081b989cc81d31c3e3ce0fa35d408f41f8417e2f787c40c29296b8582cb2a5e45e3fcf524fad9397ff9717b72f828e4589de08d50d1b73038d600b0c096f668c862674ea6c10bc068ee2016d093c2248a0c30fb26b5ba5e850d115f98077f61744cc5b4a1888930bfe2b9e30d4cdb096c7a1e31f3f0492e7b5158ac075d3027d04bc07840b56f9e768f95573a3a4afcb9911e4c8893cf4243b4fb8634998e2cb6b9a2c9da0f7d695a0f2c83b119e6dd962ff722275bda7726a85449dc789b4d16b5801f30474b76ff03647e8a2d71dde22b5d33bc74124ddf5e0a2976e8950d6117a5c2561464ae028668962775d890e1bbb49567e482a4c30ef247141456549fcb8d7b9aa23c75e74369367a5d0610c515479460ad39119cc9db96856fc1dde8517105d386157b2f6c23ed5502c2c2a6500df5f3db6267633032d18c0eb706a9e28ab79414e547e20fc482d0c470babad11d2265c160f0acc798ef6993467f5a161911991c25aa705bcf7d73eb50742e6553b24e0df7f6dc11727cdbe5dc9b0fbea24db182f5767ebbf0ff49107f436d0bd2170c8ce8d688ab796584f46d0d5c4703e825b4cdcbba5dd64ce9da831152ed92fdfaaa8abf468dee51dcdc7cdc23e13d0b546a25b609f49dc5af5d0bb12c8b892dbe5408570e4982ef7f69557db83b382f2c314f0b6926d829ce6020a68990e9870995cdb8cd58e8d841d9c552b0cb7cec39ff4db8e714ed40e0fd649feaf46d08c1ca17d40531e8fa2210bfae44e7e02917bb77d7c30529617c72ca3ea573bac6d78d9d094bd8e0fd200a856337aa600d70f2fb3d17079dcc227131c6e7abf42b4cbfc7859382bc9d4d790ad9f62f7be15ceddb28f240beec53cf3c6cd0e058ca4d70dcfc972c6d51420ba84de5d963e06b4fa420e2ff2be12cc2070cf8e72effeb186b318f056f4626d3d1af844c58ae63c622467cdbc482bd3901b1d128a7fd71e2250b122535df514425a402a8291538b3fc7396c81a7eca9863ddccc6303e521292f1d203027b0997e9e623d5c5a472fc450dc02772276cbd5189ec5026bc79493f0c53fb84c6e3c4b18bd974de29d00e1a6a9ab5c0cb24eb112a896e8628bf12b0f17257f6f4e48f9f5178a393e0858f3b5f2e3ed90dac118cc568e5cc68902a46a50d2e3eef41c70105e2ebfe00030c7d259efb46806b77d64be5ef547cd43c4e3c3b64829f8f0eff9675066be247cd744e3f1205333f7789206becc8d924594d2880b1a4c4f5928ac206f90b01a0e842fa7da8f119c7f02303e5f1bb62fc4f91aebc45d5e439df51774b3ecbd299ca5afdba7822f6b30975e786a6e9126273c8d091a14d6ec8a2a634fd6d58132459aa3cb6c71a90e85c9548aafdc9b4dc0936878ebb2faba02ce7ce8128acce570a6390abaa096aafb260e3abb5c02922576a502cae3ac1ba0a390a2a7524858ebb7290455356280809069921de0b2ff8ffbd8f91be0097855911c1f4c6e1b2dc622a5c6c9fc240bcdb96c4174d45622547a8c69ebfb617d43be519b152588c96bdc0024cd820a682de20493928b1d88914f92035316ca40b38a20bffc407f0e24221c633b2f3caee427c701f15cb3eca914d61b57ab567b6585e85a7a5683daa9deb1e6aa4d7aa3c793c2cd620a684644ed430ef101e5fee403d74a29b7a3960e9452041dbcc434f8e6fb000399b6681517500a50bfd3a46cb9013a56894e5750ca58ab03266dfb11d5eb65a82e695acdcdc876a7319d3203b56d5b8eef9075294f50a25b5d23e8351a18475888c3280204401200811c4a41b059d28a7f9984cf87861e50a1105d165fcfb9265acb922d654a49262965b004d304e50457ad1a435974d8f715be47326f86eab2bae0e08e7ee37cef3d6da48bdc060ea6464cd9134877011637746534686ab2475f4b03517cefa96838dffb6de27bef5d39a64deccc24475051b584007195348ac6b53889003bfada9da39e017e1fe1fb9befbda7699affc42a6546697e9acdc6755c82480724175473ce39e79c73eef139e79c1fa99243d9f8a139731c1a7d83ff6ab987d0bd46ca3507b88b2065ce6b57fb39fc799487c6e7209f6f9bcf798d61021a7e172916e33a9691e7babb262a606c9bc4fdb3f177771ab6fd1d6a94fdbd1ed2301afce6f6fe813723fa7b3d8433b8702fcc8714d216850f81f742063e257f5abf0c6778d3fe13866bbeec16d6c2f0d5b740fc913bf98aece44eb26d939d8c61b60fd76f1741cac9388edd13f7f327ac5695371c51f72b013cb226011bcc2255807ce4609358f0d38ceebdf7de6e091d77b59f509d8f9ce126ad6cbe4ca20bf39981a6160cc3300c73804734f861c1c17b61030d9c01b22b1fff835b32c1d8f6b981c7f1c326c98048830e3628801f21b0496a66071aaef4fff05ed850b37d4d4c7e8ca591214296001c3609d905b1851c0be6bdf7de7bef7acb8681de6e273859b25dc84ef81f2a706d9f0278302d892d1c55b0a540e6e35b31fe37e9967cbb2d0602c007e083c1821112922ffc1ce01193153b391208b7bc302d2f8c1d4c120300785fafd8d57aadf01f01b74482206d07163e3dcf34865dd76e0956fd645e61188661188639704b365c4510f3ee65d9771e6f0c29ac42e4acf3d854d6410c4c7b57f86ebd432a7cd73de13512825e231ff03592825c2327cc35d281608d94608cc051232174d4c807df2dd23512a4467e144f40ea62481126816903c8d0430e1924e42384e896c03531e4c32d816b3a04c42d81e1ba23e4815b02d71c2110dc12b81e864408098648704be07a0e71c02d816b396442088590072008a940d3c66dc241bb25704dd3ee89fb01efa924c720c660638001889dd4f581f87b704b4eee3a7852a07bb3da8f74b71f3228db3e27ecbdb785175107dcebb2e373008f58985ed9ea18ceb06578176112b82eca2a1b88d1b19ba5df2d522c16dd13b7ae761f21c2f7286e5810b60fb2420d704b36c04816e96b1345c407f102601383052324758851024d247e0e6e498d15ad61cd8303782402d6fb8e6c135fbb1ab6c95cbbf52c87d0ae892c8b70b049e03a380745dc4d32639031f8901e42c31c6c930f9b04aee5fac336718f5c0429c7225be4c3fbc13d7195311cefc04a8eb58f7c5fa79cfd48976de5c13f5e951d0c31c02315a4281835d430c847f2188657407eed964cb5b17505912f076e8904371a78e79948942081c8edfabbe600675d9491d16f9f8ed16fdd827e6b172b760d03fbf2f2a033d0d2c086260e5df7e484f83174dd9302cc1f699c914622d2280169441a9146a4b100124c76bab8b6ac1030f85b84b6c0898ec0f791c61f2c1a87bc4abfb54b9d4aa350ad6716166741f32b095cf76402a206a34b02d73b0328b7e2559c6ac4754f44da3ed2f861633d827eb9934f71291ec5a1f81377e24dbc491bffeb9ebc284274d7170e60c8577026be44bf3557a24d86203f86330cbbfe85299ec491f81137e245f45bbb9c880f71211e44ffa15b0bffff10feffffff0fbf07e8d82246a3d13d71395e841a2003584e39432cd4d9d64f0c9c16a6192589d95423479b74826e8a8b9154e78636093efe6c65ef879ba90235da0a2ad15e474eeaecc51320979c9f1d58b4ef8c076acd88cf632a7d91e0ef253f8d3abf277e4ff4999b7ba7f6d9b903545bb5721b6ea1c0d6809b360aebf4262616400b975c0dce39e783317e3e6bdedde7f59086c1360d556b44ddec587332c543b34fedbdf75bce9f431ba31cf823bd5163ae86580a85d0698999738f12f411cbb975e4bd87d2f1a859ddc99e3b2ab6a2ea45a3135eb690a34e28e618c52f49bb2ee86ed2767c6ea8384bf162939685f104c32a395bc5c84ab4912e1a516e686113b9ee616fca9db383d0b931c184b444430305045340322f25d662d4a436947b274d38beb1f5ee91e10ac702dce2aac86da775da8e40191c255b544f075eb8200a0ae6871354a634acdd5393f7de0fd3a846d0485d97a8c78db4a92f629eeebd07b191b2e06519f7ea1dd5533ca59ca19f1971c11452787b37a258e93e5221e49c73ce39e79c730d547d5989b8d134a69644d3a75305f5fa3b46c988b751bdd1306cb9f8f4bd77ef91ffd85fe3f88aab103155d808851052acd6278c73c707e76f7a441a3f984b07184e95d55b180c4016324eec2206b861e5e1445ba2da1233fc58987bcd33b3ae190f1e22d1170dc7d0dee0c26793a4a415613372f7f7971dea623a5b02e97a720c791dc17009275595c4130da609e85864f14ee81de549bbf63ea45e3110846a792e56094a7ac0605711322a4afedea74531bff7fef67a20b2a250f139e7bdf7de374d6c66f5f0de7befed949bc4e5b2ecedac50bb16df7b5f8f54100fe3383ede29b9bc99549eac53a923ce39e742cca11c819d3fbaa39ec02ce51169c4528ad53ee75e2f98a0d8dc62d6943bc86866d1e4d15b0c6defcad056ccb4b9663c3c3bc9379f1b2180805e233f6b5b510d9e8b1f0b27b8154332da20a5fde303bf29335ab4b0ea0d91938cd2988b97d2ccc85e0686530bac9a2baacddc1d64b61be8419a7e91c928e155a5a9f352ac100f2cf92cadf5a198426d1fb8034b721ac326389d31b57bdca35f13ea8725e7c9556b79f646de3fe79cf3362d4ce26ee5363e3ac52d0993b81f69fcbdd74399af2f5f70efbdf7d2a719afe32b77e50e266ad5e44365c4df7bef1cbff7de7b8adf558e7346f4fe2703a4839df5f731dfb4f472b6648e48e3af914298370780cf5398bd5cfbecba58a4b68aaadbb23a47fddc9d6e317dfd0e2b1d0d57bab454167a9f732a56f2735ed39c53c3969f73ce8bf18c7b8cb12dd29ed738e1839c43ac9333083de1f1ae506563d7e7fd7d5f0fe90d6cc48eaca04d68583466d05a5f51579296073a3406abb8dc8865b76339447549eb4b1da012958b9d18df5b77e038f60edd9d5dda3a122e475a4329816d51a13597b9b4a3d41797c2a6a05d00db46983df15c945d783b639121e385ee284a4e488dda2b6e147bc509b53dab5b18de540073332e245ee4a84e527541aa945ff02fa32a967a0ecc0c63736a789c1bfe4dfaa12d1f1d084814791527986dd0fee1d3286b078a8c331943b72d5ba72c2d7ae5c20bad668e6887eb8cc7044cd5cc131d9d89164f781f8de1fade7b4f7326874b21c365efbd9779080d8fc4ce19eae425fc308d270e5da26d97cd08aa2ec6ce4e588db10b60b48d1d796163dcb486d3afaf0939751ce7bdafbdf772ede7da17bdf7defb153323cee7103944a68d668a267644bff7ceed9e78491d5d8a678d00b6827bfe26bc140955984ece839bab2c398532fc4a55b24863c5701001393498fd0e93f0de7b1f0f6379d8e701cd7a597decde7bef432c0f64d2a560a17c9a7136b192d1389aac72d0e09a62eea40142ab30757f4f6733422e9c22fc81d5200541bda0d458a6e3388ee3f885b7361ea56cd6a29c2959f6cbbc722167fcd6dcdaaad6e9f15c7500758a116246da0ccd899aa096704fe3e390726f3e6d271e89983c8768780c6ad633dec909c0a427e591900b0408cdb92071534de12785538a9e81db837bc0bbf8b700a896c60fd3cfdb8ab4351b412d6f29ae76882ed851f738c7d6bb0eca8dd57b4ff46e411575336c423b1bad794e53300ed3de310ed65cefacdb81c6b9e9a564481f189388b5a1ade8069052c038f9a46a4ad009d4ae1a418f2d26148277c7ad337a204d722072c6d03dffa8a423f6d78f0408482fac80652662f6b616e79c7b1073ceb30d91736b0b96cff9998c5ccc0f5314892a4e8f5f94f5ac050c98a70f8d13abf5b60cf4c3c3c6e0caf33292e6bc9115c1d8594b2f8a14dfd4b8e6e79cd87befbda75869e5586a14a277ec8c9aaf48f71a63109c88e439acce140fcd0fb6a0921e2c6d7073c58377faa660387d484dd41ce29e5d5920159a0c130bc4792dd26d320063f4d0d9b979aef5bdc8cf5294930e8c08e818226944518a3e2f9a04d0f94059a5cc177f531a7b5a2309448c0d144326f658b6417dcb18349dab9e57d293d24c9dfb7eb3804afb825120a2f7134c655178c9942daca05c4159802484f68e9e9472491bb32ba0e28ae52ed2c62f2dd20ef97c5f0f697806878daf9ed4cce4c14a0e9413bd83bcbd2a61da3c6d0ce1a8a52dd248203d420a316a5c2962285586785d44987ac600f369cb5a9b4e3da34f3e5a5501048f0aa112796241352c56b2ecbdf7dedf3137894b24dc796d1c55596fd120bd24599819cc8d3919541657296ce8dd90f39a20ec2aefbb1552efbda76c357bef9dc3f1c9284be6ccb987dca12a49a73895f14fe79cf839e79cb30d65332da09f3f2d8ab7173da60eb9b50a38352cfeca9a2566b85171ce39e79c1fa39e43b9026bd71033ba2cea338aab2c4a338fb3610398b4a5ba6c27e7c49e12205aa4eeb65e404b58191044386d805b2d5c5497a96756d0888ff00b06e6c1e9496ad9818615a06caccf48ed25284bcacc72ea9b55eafb7aa48221bd32c37b8f2285a291c2cadbb34821f94671bedea44a96d9fcf23b4566c9a533311e3c8455e5065ff3c63f402c2e6b7b3581b3c207fec4c072c22d916e1e14591025013815645929b1161b209c6d220097777b445c81d3c09819ca232d7938ae3d594f1961b530c57cb146ef0ad8b3d9e4871df3c74f9601de1fa337c785107e72bc0d57aeb4fe58959c39e79cd3b5f7defbb8ed314ea663772a42f643acf59db1b60c335086983391d48184326ac2060f04f455ce39779b672f0fec14c67358e31e9749ce37e7fced2a227872c3da83e2da82110624b41362ea042095ac2582fd441dabe961ae8a924fc2d35658979cdbf629b0edf7c011765d7765726667394ebdf7de7bef50e79ce7342e17604a48537c417a39bff7aa9ecfef0ed07ac2d1c3a923abd1b48f5230b1fbc3071386fd49b2f2aa4641ab5adf67f83e6f4b5545f34bc2896946d73c533c343b83273cea3ee57eb525ce9e4b1e762fded1a3f042b9f849af5d70637b4550d0ca734394b14e1f80a1909a2ebf1771149d39c3ec02f2d5c7543eb4de7bef5de8b9495c79069d62e3da82637740b2567f72e60e49cb5e0502fbe8d064dd473c66dedd8c147beffd947693b8b2d0cfd9ab4e23a1f7c20e0f4b6b0711563118783f375b39c1231031335acb3abd24a9991ae71df6a095b442af43b6d8aa05a33aaf70f179cee1ab7b88ed489953f6ee21437e5bf2b76d500397dd175b0f2ff89230ca25d36be0caa12ccbb24c75e1d2a5d9222c07d75de9dc5c6d68e1c039a0fd934bea2bdb361dbdb75e4978ec341b6fcf0b085c1e586e109b0f14a6222df3e0a662d3f3db37ad02f02ae5b9d7c6de7b17ba82495ca9ec458f19d3ea1823dfaf08c961f8de6ba01635e5ce3917a1e19178c5a863402336f506164796c7226feee9b953c70444dae9483ff34643b2d6fc05e79cab449b439973ce7d8a5a4e3e43411190095befbd57d3e60ed518f4a661bde0f18a8d87684aebb46635642795e3784af18181a4a75c20754a6ac63ee3dce382b4095ebeed1b9615c7aa62c9eb9af6bb152ba777a6340404a506156736a3f7a09d54938b32d59cfbc14382e28da9e85659442b7444348c088c86d5cece2b43ce0e63a83251c16b47f33829a0f0b0e5a008720e62333fb52acf2ded875acf18debc094631c156a4c1662507ce92fb2190f1c8226b412c8e8f4f04092da91611effba49c8f4b8ca934ed76d134c6ab7b11d2bcf7f046402cb6984e9817232a40b97a35a2a34e6be964a29af6e29574812f4a43865ddbaa267589b8e2fc3c3d6d58cdd9c5bb4c580733bc49139a836a8165f17ae000be31a6a66b131ecd91ac4551fae324e418db15a0de24f5d830418535576c1d79dd28cbe3d863263c00ef926f2454d4c41d201030069e4b17975975cf8503c26e41cbdb00b0f0c4bd6e2b3096de872957ae03b0610713c8d61342e76abdf07915fa92a4037cbbda581ba8d38d134022de40d8e848c97883abc1dca25ef766aa58928218df5266e5789e1204d37beff5b08f4cd9a8f0a249851c9f30b08d333aa9bb169a3c6b566c8d02e08a2b46ac4ccc472aeada8f80d9b0cd93553df9fc3c983265f3f2d93313cc2c8300567014c02cbdf7de7b57cef3dcc3ec718126cf5459dbb0622009b9746356adcd8b155411471e4b7bae7e87c53ad961bcb6e5de1a350149f209ee5df360d50e3b96569020e91b55c453b6305b22ce39e79cbb292ccfbee9dd8d3519ac14d16cc580b317e7544b96881e3798c80c19616a28e8fe98185c615aa0d7258b17cbd950caf2f6b1bfa85a33025bf8f950403a5393d3838566bd7ebab4dc28809d473be8492884bd9f6bb8ed28b86df6a694e0f3e0436c6ddc0eb8a2ddec77ad3a571c60993f5f6c69d68c5c8d23e1bdef5dade38b0d1eca36330a60b3731518ce21dffa2a311bbbde07b7dcb1b0f774afda6c440f34da21e71d8689ddec4683fe41cd69c2ea8639522dd3cd2a505b21a64d41ce1962355a4833d0a5ab2732b32b2939a9bc08bbabc351651d2488bce68ef2ceee56448015f563a2c5a905569bfac03697d2eed320a58e7db252ceb3fcfcbd1e9a88d992428f8e66028c8cbc6ac8a668d4a04a353a540b30e408e8a76f868e2c6c6f71be617b07e7c82851cb689576f650c1d67bb02769df64071918ba0b16d2deba85bb2af3c5fd5bd15a77c7f726995c51d5f04b702546564785925b53f3eba9a84ecbebfab3b42367ad790879a5ad296fa5a3963936748d3d3a55efbdf76a149cb2dc529ca7073f9e60eb7df8aa6ca701919ea8b48c38e6194360da000000b3180000030018c5912c4e34b9ec0114800620caa0c094403c168c45c37020100084418190181806000000100006822088a78838c4f5c60acd1301250a43bc1ad85ed64131715b0d999a1a5759224299a31c443d5685c06ae47e79089ea6f42f2b18d9cd7b88e3548c8048bdc68eb9e9828391c1b0599d64c0c07da1f21e3e0f1879597a857d91e7a21d9b001cb4ec41666a211b767e5817dfa2ac5aaa1240df4ed97943d92e1dffb819324854fcbaf808e2adbdda524e12f7d6913192ad0df0017a6a421e5fcfb42f6a4a876c03cf490dd50adec10eb7aabc543be9eb6443d4fa1716104c1d7302a7b3c349ea4e02c644f18300ae5b67b0afb0ba56c80d553c07bbcead28c02bc33eb7c6c4829ec6284d5c947ffe9217291e5c89040824df8937e39875f9fd798e5571556749788364c8624750026650b670e06040268c79256157523f075fedc201e3312fa14ed561cd31ee4fa550a0692c5eddb16d3add875097c5ab5c47d4d38885a9f816d33c19963e3f23b3d6d4e0952f89ee1235d15c91dfee3e1c7aa9ec6556c3450452d3d783f0523cf4e6ea389dd658c46e04ed84c8ee0b7435dd729e84e901a8736e3b240496bc3810832d5bf13f69a90fbcd7448769df23fbf56d8009801c8fb51bde25c8d867078549b24fc2847038d616a9d1b15643e377274c66c6f301002f714cb29e08ddb634ed4680d7ea2bdc2c5dd422f2f3c42557d4e125b9f7ef436df72eaed57510d1147e58c9759e448ee88fcdaf2377f7215051c8376c4dd0b09cfd53f005f37d87345078255d4bd39b742d235ae9685b6baf3f4aa0f64c65cabd122c0c83653d10709d04f390454e248718e60ad8d7195ef4ddefe7c70e0330792b967df4f358a3c27fe7cb5bb3c950a330c896eadf59c7b349acce2bede82ee72780cdfa8a35a6368aa94131f5885fe375c64ac55a1430da10f4001b3c2d1773d3b1cc0623cb4b7691ccf66fb2ae0abad2ac7886350594ab429c3296f3a6e8be17e1058e8489c0c9c27aa3df97902e68a1b7046b96e522c8c02c949f5749c2a659a5d4f03840ba4b39801ee6a6955d443350a4c92ca0a0daa6376205a865fe0f2528f213058a194df7b05d028440b36c25090bcbca6494465e30a8b82cb372f7948f93b9130795804862e3d866bdc41f86ace7b884f5baf5cc91a75eef00dc2fc51bcbd024f2ff316bf550b02b07999b31f2dd82e92f0e2759730a39160cf4832f96b99174a339610dd580fb311a199e9dd29813f182b92becf2f589ce55627c079eac5384838f969658fc9647f2ecfe5b8d2e84b1a6bbf4c1998908089b9c3362fc0992f8c17610217cb11c8dcd8b5b1d2f56c2ca621c64d92ac8488d5c938c63933b84eab32d9f008e06481052da75780a14e068330f450ea3056568a211e52297533053c2131b1d80537412ffb87d17dc9618ab2c140c0c18f8d4f56b94a2230744180b9612f24ad9d0df605ecf789f9deedbbb3b07b3123235f44015ff06f378a3ecc0797a3a0925c8839fdcf6373b9da2321621b718d19704a8f5e6fdbe019ab96179a9b51fb7d4235b6a90643b1d2140a21e58cc908d19deda4efd6b7eb22f70c2c9b4b83cc5021895969aaa04aeeb864d9592f906ecfcbe9acd9663d5acb6f8a4fb36ba88f902450299b103ba9cfc4a721b4342b8229297d9bed837ca3916d18fd1f3367459842e133030008bdd01ccb21db3dbe63911ccb35f14aeb20e10e3a98f5e77b27e44b7129e2e0ed5113587f333b01daa19e300e836537151d0e1b5e49d0a4ccb3dc98c630438f08b9365b73b8d7f487cf1d0c0f50848ff46dc931a3abe77613ba2980b77536cff04d67c62e6b17dbff09a1de9f4ebd5fbb1e5a27a81ce93a5603eea61e05a33376524ee0fc7de32b22ba8644a372a87437fe053b8d3c7e7a4fd56e3045954c52258d39e71b98ab25f22f8a50f1fba47910781e2b342a1426edb8061b57f2adacda876d6fc253630d3453302c269d417f489cb91b1e782abf29deabefbf32ebe1da9fbf90ff0cf694e75fce83d0d64d0ce0acd6905fe4f4e79f3311309e43a00c758cfccc9354201fc3a60afcb3d81c7a0210e410df4006ac7b898b60faea62a96e602def71a37aa214945e1bc5f8a326ed9c17a253d65dee3e8b1c9391407b38e81c88575fb71070a01134b2c72b94c2eb20e6cbcd9a66143c5e3fdf0a5855100bd4accabd14e0c3152abe3cf745e665ec57bb37628377311336a184d82f9b4fa7236102addd90dde097038760de283648d6332806ed65490202e24a802a718fa3d6e39cdba0fdf4a8ab26d35917fa4a59d92ba1c6e7e904d3f7b6407baddc9936b1694bcad16d7525ab9f46684fc250ec952c140d67591e459601b95229a85064ca4c1be2d96ec0641950f78df36cdd01cf0d5b08232184f1ce3632fa1b8558790992bf2037280a41f677045bc29665297cc6d7a35cc1fa929d31718279707532c518511c50bdc8bf4b78530d421acc194df3769d9429bf790cfe6a8c165569edc88d65368c0866616f8cf3cf710f947128bcd8e72a52a23438cf2baee3d02e2e3454118ef51db662550f7e7ce2b078ec012c3eda4c8a926bb04ea0cf2f3f3733cfce960cc5e2787042b19ced39f86a4cf6c939dd7db833c2a5fa7e55f7b113e34e2080a384a2802987f6794fa2104b5d7e311456f687e4c6ab7a6d7f939dc541bc48abad4158d588a6cab55a0b5f920c18a1e77e79d086599f9358b28c9a04931b9f901e976821a686889bf4999cdff5e82c5a55830165a37274f329438e101bf7392a00a4c7ff99aa4dedb8473929385f2321cb8ff4f78b4b24eba86795b406981d7203d61b3992c3a4932290105e3a658dde612aeb9abe138eb86b477c01335a542f3bb21e5357a64a37b802071805eaddcb35759b69ccf1dbb70e5feba1cfb5fbd5293f9d12a719defd1c9948d3177fcfa32c73c6d3114eccddf7ca3585c9f03ea0ec49c0aa66a6e8f1e2e504ed605338f2cb90c29feb13530da7fcf9955427ef3d98dadeec46fa40ed418023009a2fada18235eba3f9c445332144274beb9b2e8e0e5b982bafc3862304df329e56c88b219a7045ecdb762736f34a9525300dfcde69bf716a08687861d63cf48bc632b71d6e838f014165efd2209fb19dbfd183b3774c863f6e9f68d65909053e44cfdc900df5aa331181456dcf7372c720f7d6d3f83fbc5e8cc119ed7bf115a2b90b092cb22937ded5c600a716382b0144ba52b9986178d8caac830f178e1af23492f0f606307fddfd353580988a692bba72c8a51ac991329920aabc3e2e6f55c46ca78fe2c265d42a3b883a323bf458514c7da115e2f8470389426b69bbf5170d6b45e31a121023f31057cad989816d0070b5a919b7c4cdfa7456e9be50b68694b1636d1417068c828b8c77aa3b95d5895c859813ff3858bf4348dcf8afd133579623b3b4c9b6ff9b2f5da44e7908fc4e79de2308aea9477653d76603a928f1a57aea61a4fa28477c622bc91a61633a7f7274290736cd9cb3e905324fd823b286f5d13ae52aa290a1e5ee4f5d7ec26b78bb87db2f003fd087fe2a420981c81b07e4c848b1432386cf6ddb1acbd951c4310daa833633302af68f9d3af4ea3f64badf65dac4cdbb14e1bca4d6af8ca752c789a555a19d6460fb95fc11449f96d3313480c8c65d3d9425af2c1ce99f1f4a7083220518b4dce51f84b512d45c7893225000b34ba7c06c45c5b8424dceb47ecc9620d6f4cf056a32221afefc8c5a35f6f2656346b968c84fd0b138b2057a474ae7236334169b32a31460c822399b93662fa809594a00ee35ae7f484b2645c13d5d700d50a9217bc9d1806643e862d85918d3f3de599e0c9ed010b2d5e6d324f0df81622a3b83eabac6602530cbd4617af47995c10066ce6a04ec131ff5d798ba761393fdcf10c09b5186a12675332a1a04e6bdef8a715cec1b5ef585277db8609a26b8286366b7bb09a4b71945224f4235f570e4525354acd59163d9b22075f5200cfa6f563d46386d3e0d0014d0332e1a3b121219e8ba163e0fe198711d2cf74e09ece57fcc7820f9cba11ccb20469162b94705960fc4564fc9c9ff13639b331603d7e7f183b4ad48e40923f99aba84c3e622b5872eef04c40398db4e87892f22f5f0f38a38ca655297d2c0033231b06f11bec2864501071001b8068a790747b84620507d08e0248d0fc7b9c96f914120c7cd92de55d59994f36c1f7a345d8587b2228e14d0f2f82f695a6fc6edc482daa891349cc22e0a8e2479de842dbc4635ca5112238e3d74741b5eb22073f55ddd30ad2631822c6019665e15055c03ee4a75123b17dbb34ab3f3e68e23ba6d78d9978727d3a27efddf0c6794a55f5ed74b82d5e341c5071bbd4f37be2a83bb11f46b19bf492ea71b51522b8f8f222de83f33a06c1b1f9c91c2e8f15b4a7e806068a2bd436666d06d3933dd037822ce93caa6316da8641eb829ec099f78698756440eeca4515cfcf24528c84b80d22f1865ecd932237b3e2a98c45953516ddf7e2e822ac882f5a451f7541399965e31b7e52fb98467825d9c4a03f249285a3754543bc4b4ed34174d20f48b2f28064abd68a1c9aafa2b02a29c30889f763236a2fb074945cafa2c4f5502c024e2079180e7d0b460c16cca98015155daca2fd43a0de01988450312f23b4a711050b9939e7f2e815c880864bbc8c26576c01cd992b2c9d32e1b70c25aa76ae71e427de69ab02c3410072c74ff4c72a66daf499a174d4511ace44fbb2355e5129d0b26ac647739686161c239db40bd1cff98acfea42af376faea51264626a2ffbcf66c2604691a5357f09fe1f15afab9d55960a99c6786c3f1b0b7194a8cf533d27332f517e9090067f84f6bc37ec1e60354df0cd4d2c28d55380577314c2bb76302afc88329d2ec8971db79cbf291b69e16f1295e68361a7149c9410983f95381f2672e897ada5bffbebb001e6182d0d63939b3adabbeb169586f1dc49495a25f11039a803192040fd5fc03aa95df1d4677eacb9fe0c1d4b3d2d4b77249515b342d2b06b742e5405ac864127d9e1ec7b986858596112b9aa9e21ebc692f17e57be7fcb1ee3fd3a16a3f36e3e679183140efa80b168647f7bbf6f3b39c96ff6adcd4144ced58198da0d6820823a0e667a6ec4f4d963e6d187640a011c24508d24d3b0f23a752d303b4b49cc9c12fede5110f9174edca78e0cdb89a2b08877463da16762c8c432164f1f708c532b0f0a184b29b8e2b214bd71a4996c5b3294917c094dad125707d721a06266357c563621fe4abaf2462342b5012c30da1544dbd9d50daadf4b97532f2a8f0f1f40eacb9121af72c4c8cf39fcb105d22898a3ae5e45ca29f547912c3511c94fb44c5218902bbbf00e27a0d684ef8c209f8aac90a67c26c1c14d3389cb8b5bbc15a928279041b4c7f563b2554a71dcf1e805b6c76da52905c29296b164692e19b6b80d3856a4d3721f86a7d8eb703c71eee413751a638a3a0d2eaaeb6f466f6a7e8e01141a56388bf7731447a13559b31034d13242897b52a77a1e326306a837df87cec419d892f2bc6548d8ac2ca3d5b46e254a322ea8a6bc4884291a43947e4bca5df9e988f62f99d225ed4122537eadd1e1f03180819a05a99d920a02405c84e6329aa19fe206879adf91c09110e9e65d9b90350205e7062a9aeb29a69f1e63a0be5c5f1df7b9f8aac9ca881fa3592398b3d122d4797c41f98a0c6c763f0d4524778f51405e8c2c1a13b4276fb808a710c7b3cffaf103bd096b1ac73881a9b568096e13e1c1aa1c17123ac88ff30b41787785753f92630d9b30294deeebf644d3f29209991328ce81c728996d5621bd035e8740fc9543b0d9d372ddba5fe3dc3b7e5c806dd94328975db5526b95f947b24e5c2a4701bd48eef8d451943853cbb00ea3c0c9c1950480725f360685379f4943ada65b211ea0206afaf76b856287ace74251053eefdc0e286e363aaeb6579980508fd1f8272f299261f1baa452a15ad55add9e1075f4ec01c0492905423d7fa322e87e22724bd1e7c497c88e8aec277e89e38b77e47ae9698ba5a8d44eaca1633d1338ab9a864294587cea9be830bb11f89638223d7111785e000480b97724064f2fd5854b6d18d167ffa8242ccf0fb150f4b9a44175f95bf76734e2d8b81539ac177357f1ebfe72db349579d4f2aa4c4a3f2f6a1acd53bcbc156899792271b6c336929c01b2ef13a00069857bf83e293db15c4934f7bb98c07e02692b91fcc1456943a7e80796cd17bc1b4a18fc109058f04112a80e0df6040fa024cc626c90f43f67f75b90a21f278e2be846d3ff3176288ae8a12f1556ca110c6a822f6be86193ec53732cdfafeeef2408c2d7989617a3a08827ef96baf75b303872b26a78feee79ee70230dc24f976c481aea0d6a700b33a05225353b9aaa1a35bb0eb4ad4acbd54494d966c15b9cd3526dfae0ba5b097936e82923db9168af403a587cd91f51d2b68798b76fec618f70ce99dc0220f4b1f70642d27fa43da5a071cf0e3997140a9b88a6861579b2d716e328f98a00dc379a405b33d0881b29ed48c280ca01d3e072276a6ad298c69e602f19468965b92ca7d4368eb4eeb18e1f6763f7c254d630ac74ac6cec7b66a647110a4cf97f447c9f312dfbc8d71d3c8c4532cc188e9dfe88b01f28aac70ecacf02a53dab352a585d48c906902283d6435b83abb341cb5ade3810111aab9ca0ba89dc910f8715ebdf0aae8bbf696e57931077bc5d96dc283031a688a3a26716c7bf3a52fa06c603d022231c614f42199e17c464ffccbcbdb5d944d997b4ee6c62ad10bb9008dc2c5060eac57782d2619138a926e6c9671b7c013be227ea331e4925130a144f856b03cd6d40658f19bffc3395ca9c2dd688d0458b908a733cc609c9601a0927863e7f10a6c07dae11a828fb52d29b809ce67838ee5f50ac0f89c1f1e9bc19ffc30035fbe7747aa05f4cbf06b32c8434d225b4c33acf45633285ce388e0229cbbb7cad2cc03333434cf315d9bfa2d3bb5c8d99532f895e6e591c187117a5c4a950e3922563919fad8843a5a000f6b89e70a57c1f15c6ba78b0469c2076e685826847bc5015f40a0877392c9272115de16fb2fd89be8b88f0b5899ff8b4240ab6d73b9cd0e2fe810e680d533ac7541bf8d4f2c283c9663dbb5c2c74754c07f9f30d774ad10abd7e34f8045956aba14fdbc85a67a8a058a28a4a017185fcb97c6ce0f26dbfbb889405c925d59d4fcfc55104a65bb24fcf8cdef4cb75932387259c852de1a29efdb0f8646c450b017b35e66709cfe2219a73fcb9f54daff665ea720397ac182b577f33add929d75de41281c56547bd427449a09999e7c6376f5dd2276639fb4cc41b3a23ad521c16727477748604d06e56c08d4a9369f9a3941578807f5bfb17e80a054137db124a8e98e31ef9b18f1f2ab1921cb3eeb650aaaaa64b639e2e9c555f52eb237b8a335394c13efcdda6150bb5a26cbc74dca01197524d5a2d461432ca898451ac8d9a675c5dc00bd82d951e8a4a64749769eb971dcb0e9e7f1c6a8b04416878ffd73a3ee7f50a4f1b46639eb32930538c9e88625125aa15447c3c8b9a6c838e11c0dc8870db8a11ae1f7c64436f0ee1dbd35a5b0fc8866920dda713721034c77b075e41ddc2319bc1db025084ca638ef06f3f692657e9498bfc21c29ec5e77f7760631b99c7a4e4ed8ef97f3cefa5565ef499ed93100110dff7bc9a9eb9f359ce255c62e9d1f48015d38db08cb4cac532897d51453c97e66e1ded88ec0c2e7c8573d2086d0989daac7ec08adcf505719128bb42f0e89715b08f86be0d4e143a7a4fea83207ff9c69f57b2cbc4c77814ca0c18bddf34fc68261caab714103868355d69aeeb561263575ef73685d443760860a4c4c43559f98993e9d388c96ac914e055b09dcdd2cd110fa4b29b2cf2179d831793e37b22ba1c9770e672b9338a14182d2c7309f630655653eb2e7d226783b4665b913d3542659268ced1c4db68928cd1d3b3c11094c23cae00053f7ea8f99938ee96c181640d3ad6827c652b244893127ddaca96e4fbe1dea68a24198db75aed33f5d34b49575bbb289b980f5deaa0941ce8dd3bc30b6cec0968653cf28d5eb61524c857e6b936757cf4128d40186565bb9bfe3c4d39f1ba0f6077325c3642013b7c10314c88524857fb3e1f8df306a83a9514b72592ac58f5494586826cdc652adaa17ad29a5e8405d84fc1e9ec3d5cd3b2e9329d885216190a8c59f7f8be43347ec50f9af8e1c9476ee2e8a471b7abe8b1a8e923110fd7da67ad3083e622e5a776e098ea04c7b9fdb2a066203e691785c59acda15fd30bf9d4b9b13c634b1e1f09139e4796268e56547a2af654a0c6b3b4f94494757ed72003f813a158a4af59b858630ac13f9731744781bc7019e9f139de9e684a3b6a8c75f7d804248812b9c15371f92b2c1151fb8c03363c2070eb5cf99fd033498a9ef22ff349460f62833bf967cba64432cccfc09192423c379329a1c0c56c6768f828b9cc6db10570fc580f41e77aec6a05061f257cf1fab7987933eb841382b4848efa2b5ad18e63da6099ec4f3a87838dffdf1141627e054414d5ed80d1d0a7c7fd449b8bd1b1485c74c292222c9ae122deb5db958574517cc0471c45d9ded8d383531271ffa66ee679d2b9aa002aace2cd0dcad2152521cd971fbeba9e5589ea6cb4d5e82441f20e2d3e66ced2540504d39101464e4900f475af90a6f821e746cf7660c78464a408b507bcee0640e324529d02a8866a55d0161328ba81ada389ff5e41b244e974e4883b1eaf2b53b1c905d3c8c476280769acac36a72a4178eb9f8d9fcbebac6e1d1933190e821029cb20c3e14a0479a8b5cdc92f3bbed29cc7567b7342ab76e9a40f5d1d1884563d538b678350491357cd617ae16fc45b09d6b038472fc4e6acc0020405825a9133af04d07632a9402ad7e80716d96a8865da909157c07f6d00a67ca6c9f7af151644e43666b2419b1cbafd5ea6e516747da59bc0d6274326b1691d921779c6266ec89d2198e3b498ce9fb58bb6eb1335f6cb58ccca628675ee2ad6592a7fb4b0c63dac22fd53080eca5175a528ed7fe268072efd9f323e2f06e52088787bf18b3d735aeebb03dd29c400bd57be604b4dc071e14e81c8806b1a75069019791a56951be189d3a7411ea5699c32ae4312607dcccb189ba71bfb35424f1bab6364c4bb543537a80290412766e22a03dbbaa43e29800c0c26ccf458f307811747df8d2903bb8b8c6c2bd293ace08661ce3d6a36d669015cc1456ad95ac930fdf20c65011f2b73a51aa3501094a625d528f7b1ae0c5f0944a1c9e847797e3319563cdfc20c9e853d04616580a1e318142e955d59313b4bd149d8fceb85d846c956952d3d7a9d8a64fc0704297c7c01cc506a0c59fff4133247858f9f2cc20c338f1df1112f916b8e2da12c8069a38837ef561d627c3b239f7c71721af5d8acde8f4cc794e10ad332ac63046a689a2c035d76dfb8cea5d48d1a1b2942972941e8db279d1a73b3d422e9ec7cd451b38d1bed4206292ef3ac8bc520651d14a4debbccf992c5ec0c3eb90b822edf640c46a9d686a43c0cb811a6d94b97e156402dd0e550672cc0a8e57039481cfa32849121138f6a90f0d1d8881e2e37de87b6062307a908579f41afaa4f2a42123ab133f472860455a08c502dfc9599df6669cc115752778374d4e63ff53fe7ac4ba549cf78978e9abbbb6107a0b3eb2898156848ec554a7b5c17428f36c90c4bda149c2e0603c3f9e8a1a03e1077632d1dad6a771adc1aad8a492796e02163da460e8cba51af575b01a31ea198132337521bc918320a8d8666f4915ea633cc0fc79dc5b1996ad59c76e270fc269f848a85e9713818f452c7caf385ee67fad17fe48dd4e0e25997b9812b5c3e3f7f6c3141d4a572f37847a345dd86bd367ca6d7254e8b6e66295f03db85481b2e1ebe9e5d48cfa4166b5a32bce2780901396fe43898e75213ec441940e089c8d28e44cb4ce103cc3d86b2d12c19dff85d64c3e8e957a0d6dd3c2942806362569bdaa77ebaf31c92a478af33cdc5e656db284a37d3c5e68f19107ea34ae72f47dff3ce698ba538599fb8852488e792678a273c83c18b921b2be294c70e527430b1019fe14a3eb1676ae83b05fc738687122d614f79351ba3380f5c29654710bd664030b6cacd13393d1572c0407e8c3c42a0a7a2ae272f0cc820b00fcb5609ef185b194cd22695d2953c0bf12dd8ce18fa469e906204660c4912166e666b6e22acc0bd0dabf14e670ca6ebeca481cd86a749de45645744e19dcdcec5be96655b9a42c39de84dba9036fc1c174751a98e68a7bcc92f1a7439df71e2e045e4103f3a2256b7753045f8c991253365989cf4984e6954d62c9174ce0ad444965321b66c654135440c1b2f0e3d807f003b2282cab63a9190e3c8f53f792e6043ac9dc5c1fec3915495473e3ccf9a356276622433e2c5f3ad79d22309acee05adec447d28c07ae2d5c49f71a7baf657535941b8780de3c1a42fb677c8168a699b1a66a8ba5fab99392e8a0fefddcc07fbd32df105bd897c3c58011d7bfed2a19266a79b7fbc64f7121092949a208d5af14699a7ec2dbc8aaefbeda2cdeee1ad220f0ecb41d7bd0571d6ce3de2cd0ede63a00071106dda976babd76878b6755eef5f7a1084f4ef3c61d1821d44b4bda9ea71a8e7b45e088eb3f6867ec3803bddb6813fa3d8ed177a9fcda807374468e117f0bd58621e8e6afc4595343fb28fbe67f59f22ff07c5906a2f16eb756beb57abaddc8a0f34f0437f63d6555af147720e25a6048c1282996086ee6d0ba73fa651634aa221509095152b2b6b85738f6ff4e73b10744740673e36a718c98a2271eea2411384e8d1f6f05523395bde5fb48f712cadbd2f6870bc73aa2278ea089e8b6c28a60f80a0fd61dc16dbe642b1efa466e7c716c17b583fc9191ce39f29a4c9a6c033860327fa6aafc3b2927be29bb62aea001e936edc2ab935c78ccca26e01fd899f637322b8a28541c9fcb0d4cadaaaa505eb45b51175f7c022041a5688424f61835d76473223c2e4f68063b503394edc2f1582d64a386544b7dee917c2bb2fce4b2bdf5f35c39cc8551243920d4ee8dec12332403bb7fee1cefc3054da9d6b74c0c1fdbcdd2f0c0532eb380c7157d1f976587eb94cf6d8f573d6fab78bd85ab0fe68139e957267ab4c0c856cc0f163624c4db462c2c8566eccc707f4cbb5082ab80a2f99f0a5c6db1ae564bd754f3b09aa24519e4426e2e13c97d0abb20a56f13afb1b00f1fb0992c687490952cf41898a0a153d9423bc09181a1cfd8bf08da32b843cc8b71c7ff8641de52b56d6ac637532f101ee7aa2794bd605b0f6a798c9b31d6ad57336ba184364799ab5176485599ae91040bd64ca4a4df37bf51771bfe86e4a201fc5f5f34a957011d5baf8a3ecf1a25bfa06dcd54337a5ee127d23176f8feed3a6f961908640996d5ec775b31e30ef4f2f453b81a0483375a825391777212584982e0338d02127b8d4f3e32e3d2b6ddc5bb915f1be2873a44a61acb928c95f8c6c13c953fd6167e61003ffb88e1864805599445550a55b61709b5c831dfcbe2bc03730a3a86c1925c407a91ab32f0b6a8212e0bdfbdef058309781195764807dd01b00a5787fe040c03019a36f991f2bc545282296ba40830e77706d89f9a3e3b80076e8e3e12ea6936a6a58741c79618b152f3d38563773f30fe6a0246b50dbdd5e5b0ed86cf979a289e08181c762aa5387043e3b107ccbbd7fd4f62058bddc5f7f86c40d553b9f1fef5c2d3fc84d44ad1df515fb44912268ce7a515c6c774fbf1994d64c2a55754c5990768f146010a052d1107130da23aeb0121bd6eae61ff8f3a5fc299bd6fa188a00ede4570455926b44f08ae260cfffd9715acf9b67286328acec9319e39e72ed0be56c3c83f6e5570748b8bdf141c708025d0e64c03df5c97f30cf29a4cc0e2ab4a261cc6113570c52d584875069d5b1762f76b4752e073dd79258bf427c921181f2e2040197e26fff16eee1f0520177c83fa9ebb4ab23eed22e02266b868ef4585f420acc9b35dfb7765ad00a04fc6a91e335070925f8ced094a62b11bd511c32f93e6d3be7401541db28271275a8a7ad4fc65881375b7af5412e959350630c867ece26f35aa7830a04a855a28107d3be9fc9c84f0c4635b38e927cb0da86c79e4e81792300b20780bf9910b0e13f008f20663b428b852062c5cbd658b4d9d5c47be4cbf523b16698937242fb01bba8dac77d951c9c1f899b9fcb3d57f81b27ddf9fe0f35a4cbfa6caa8cecdc913afa94c5d66cad0a6b04ccdebcc54f31d65ba8811f5189cfe7c5e3606e65993edb03deb3209d3608420ddb9e9914a32326e8a161b141d6088f1c96172a6a746f1ef3f7dc88b1093577ef7341c637287c23bde3a2413da10260973128d3391322c3771ea160abb7d551e3636c5657d8b210afd7dd30855bcc45f4f7b362b688c3a36ee7bc6ed23ce6a2e190ec11ab43ee3e2957d6d1a9e4a80fd616a8a43bea3c81076c809aec46b64fe919681cdd304ae9beddd8968ebdc0d181ea5f437d8e002979d31d446afa3bfcaf5cf9b1e9e86b150018e0b2d92dccb82c59566aa762c81cafb3a5b6ad4129043d37034432daa7880ab35f212ae528de91a9738bf504253c30eeed30ed8a4d1117c1117411c2ed19004f47ac5b0eba24092ffa2d6b0d1600cb12c3e4a42ec22c2403d2871f03968edbf293047de25ef7c8e17fc81649ff1dd3524b668430835723cbd0248f743001faac9c2756608e69758b4736519a09c810e612dddd4be8ee0ccfdfa84404dcd562bf8be6a4b144225358969921f917dcc13b3ef2494411c58c929fce2435f0dcc438a48e3aa9916419a695ad5492fd8ec8277adbbda54c5beebd03640264026602d6fff87f9e1a1ac1c1f5b97072b416fde6ff1c869e1fbe266e9489400d362b6c441ec5a3e1a1f7279e75d82bf01a8caf38aed59b549fefde6e065435322f218d187305189c9baaaa91978aa2146b046c31df5b466f5056bf8c6062a6a25a4733ba98a8ac707206109add94ad5a6b176fad65b740a8ba41442595b9a913cbfed3b978d4c06eae3639c51c32a518511950881a114520edfc3c16c4d5b1b6528b9765433b9977ddf098cec9afbee0fa4a6d5763b588741bbc2979e198e3d995f53ec36f58f07d59b896eea8d3ddc2f91cb3f4f8ef83899b37d9942b69cc22080b6377a526eee80b4c017bf6111420e12ec2ccc4688ea5f600755dc649fe8fb03048304e2f1bcbbbf71090eee3cbf6d80cf34161958a9b9a51d9b09470a712ee42862bed85f444ce0eab7615d76cb04899b560012563a9af3848609c73ce53d082f03bbf4a59f077ba0decc02ae386569699892ce1911626473e80614e8d3d63c5b5fdfcd7b15935b29435be4a383f03d65dc559e47c4660896b8373abc001c75a16c1be5df68849d4f33fe6c0993f38bef6aab891f2bfdc32395f569601e15d7b1f9980e9825ac2dd111f4a1899b9319c4adac61a39dd56faffffff3958e766f9b6f2fd92c6285f54baeae706c2f2a26363738aef00d345898c2ad7666aadb03d29fe7268eff69e43e2b45f45b8c979ae838998f33d2121fce3f055aad2b53798ad4584e5a2228361fa8111d6301a72368df0f9d182922d45887081ada3ed6a07fd814662c69b0a135b1a1c4d8d418552e1d0a4bbca362a787fb5fd771213148eb943202a50e43e127b9c060693af238faefae03355cc9f26b5a1bb93b0a8f8755188fbe40b4162346a8c5ff5b2c0262b1bd165ede912e427469319b199f7146ed6654d7f311ad12c03f1152422707ef8974937b2cf074ac394fbafcb3fd0ffff4f24ba246cf1884cd62ac466ff20ab08516103ae2a41226802746ca87bb4b552af751e391a594bb84f37ec44c29844f285e5b7a2c8047139ac6c367490332a6d4c1c4a6a2c6d70396a253cb9a56c8a11c8b93cb5367de9f684cf0923fdb23fdeaeb9daa50801a72051d2d95db3c6c37a1fd919c5c8804744e9658166292ac84ffc0e9b34b914a135b73b8ad8937f9c2684f2900fc33ee21e0d42c89ccd3c00f2e53f3af2b63f0c494dad5317e64e829a619bc5ee3d971c7b9140873f46ea8a9176c4486731125b8c742d93792eb96a78e92c5b84253c89ac020596ae643157cd1ece1da577cfeb4495aa0ad921c79688ec828b1b85d46d0eec3d8b7ebeb98c9c0b89f312a2d7b81da2998d9009646365543338a9142ceff24b1ab2c7e81ecdebe9b0f2151d9cd33286b9b0e012cb2ccef17a5dee52065c870ac79abd5ccd3f79f4564cf72dbea3d9ef9608ea39e0910f98731c56ce872669410292b80068a15ab8e0fe29752e1a8661a59392863f5c4df14c95b2de44a070832b0ac6c285db917983f92543ad8aefb2aee13db4f6de7b4892eebdf7de59f8855798c976af58d5bd9c0bdda3d1754263c7d3543b84fd64471d9fb83983ffff67451d5c25c599ff417a493f9f92abd2435506c9c0409d1b7b80215dce6401c5443c17ce759ab91d6949992dc1c0fca0432f72b0049d26af1238c0def1219801069e12399fa13113309e4180ec8a0df5ffbfc9a90aa6ab9eacb9155062392128516455b4caf993821709b833bb26623f0b3d566e842dca228e8e55978d8f7327aa6585f5b3b6ab2821826f8b02ad3bd73d395185102b3a833182551a587539ecf2f1e6d8b0d97ef38782d0f4ad1549660f549a508deac509a67639e209cb49b19640fd43396dbb66e0c3bdc743e1495a33c544adf676a899c0767c96aed63804b188b692493e506abcc8b9eeff7fc719ef3ce9ff5cd7e16185d6a495b1188b9cba9061c5e1e6c163f2b4c8a00d6275bddfb8f1e69c73ce8965b41befbdf7941fe23fda76b17befb40cb34938ceb1b78eeed1bcdef4e79e5ca5ed3e79ee0a483a429943c3aace4ad575295365a3e362b4a9ad0a19928392990f2b43d8737736e7e60ec7ef15dc242cfcffb95f3ca338591f801195a15a342049ca94ca5441913224a15919a65bd688ccae94473fefbac286d65581216d7393b0223e9ef4ffff28cbffb7a2cebad74936c61cde8a6832823848d293a4e5050c0cb6ea8e2ca824dec4138184d65751784323b6d3dc15ea930f5386463a8438a1ace8b596e1657242afa446a407c844a729a23a234787c964a3eddcebe34c782a8d99d5a6e6d7dafbff9fc999f131f6fe3f8bf35e219959a456c26f7a6f8f8637cecd3b1a4e54d457d6c4184c037b412b1194516312ce2d680f9cacb6b0802f2f3cf6d4b824626476d8679b45f1ddb929cf9a63cdaeae47579f7d95b52a54a011c64061ac827b618c2be19623cd89d66cb31db99e77bb8224caf2fbe4d1dc95d914a85076c1240aeaa0f4f61669f10e6aad9b8485872ba0b48c561db7ea173c0683c0c5a387da55c62cdb65300acf71f8cbd9b99f72f2763b3c75fb0fe408cc4177f26d9d377b68c05bcde1f9b264f08e051f1a4e3898ae7c30a11c3851c4053132bb010d3fefbd771bc04dc2f229cdffffaf6c9c9602774ab4944a83130dfab8570b42a94e3231e0ba880a610605086e2a2411bb671cd3c4fffff1508226e305712c88241185ac251f2592e0a8925269255ceaed474bb485a71b489af737033937c250045a1a7ef2d20224ee4ec8de737b644786217c3f86a9ffff44322e095b930382c887fb74bcf7de7bec8103af5c79cb70206bf58ec760414001774f81b79c324354e69aba4dd3b5a980ce92df3f38e75c854dca39b7aa5930d1c343299873626dc645c4958c19f2c8450cad09b2e37e9b8485bf858409d42ce15e700a4f72a7c0630489b1a3b8a7b50f5e94a2714f6934621b8ee8f2e8d995f76fefef3166b0f078b4398a8fa13d7112e1035048995000b19cd5f842e1f6a3c4d15a350c980b3bc1e1faa4825a2fb0f00b8f355be31b0fc37eff3ddefca4dfbffc28229c72940989c294a45bfcbca5fb286948ff8fd9e2eb74284bcf377afced46849734f0ffffffffe70dfca1f727ee7d6e7974c7815be4925d69091665bac779cfcb1150c0a28757adf454026110b502e72588aa6953435d3cecb7161e926c4855cdd48847c526a29d2c61f045c676dbe9d726fdf4b53bfcffff578ce3ff5fbeed1117b5051c32251224e88458c2289f66b8f8d89163184108869c472f354a45310f63ca9eeddc086199884273da56f939fd4afed0d48a5793137a2568701b1a97d1100a660787c9ee6134f3bdf70e1b2f14e7ff7fa10e8e41a356f2efa39f67809ada0d1469ccf88aa40d263420ffe3ff39c63d1edf2937ab1fcca52b341bf18ca52b2c6271096cb7050077a1d25c4feb562728809e9e028cbe8250b4018d9da864b0977c30005900d3180804150461280e3441b8071400040eb470d0803c342c3c2c280a06420130001808080081300000068381e150380c24088c0979d90015d8dd487812943343c8407f4f9d81c48cd7ee5b57095dbc46099ddf635d62bea10157584ac7c03a9578b059982c0fe34f1d98d62f344a2645624cb893382c017a6488ec84600a4eddba5d20fde291cd459b5c2e297e4eb88bdb09342e20b0a23da3e2a9ebc102d7db33755e8bddd4ce247b78e54967b180dc09344927165d49cacd4cf450b0c0c72a96ac84a8682821756d7651d9fdffd52ceb758d424c93234da2a703cc1b10b0059a2377651ffbb7d620fa63fdd08c3892447d03e46efc81c109aab6f4eb67dc337632a061a155cd2aac6960c2bc6d312e0ad22347020366e3fe220bda5bef53c41fa10f3dfb046577e0a6dac18d73c80f783abef2c911a7971e890d2d35383b4bc5fe91aadd1e26d1b1b4b68dc3866398c3f95623857582afc7d12792b89569b269629c7438a5b6e993661363d0f49694e7d6f193d9bc23e5565f359480daf9c428a55110b7e554466b1de0f5f9afd4a96e06bd8fccbf2b8c0b772a8f0ac5df49ecc115132c4fb2f92fc0612b214df03e6a6f1c614545a2a5ad287b9dbdea6b791711799c80e017c0ea91e6448071321426c1dcb1ebc0aebc04462cb952dfdad96b29733a4aeecdb80e3c3c5148c8e7ecb49294b2b424e4aff73a22aab48645025c315d0706e2faa0fc7c3a3810865171895193b440196874ac76b92535c96b156b0245c82de60012d7af63f91ec294bbad6b9131fb21f6531f2a185826e91bc626bae941a6dc5a4ef0b3cdca5f0e78ead1dc2206b27f5f22065f1543bc589ef8eda47111a9d43600a859de67e79a1e6fbaacf99ce77daa8dd35f896ce2dbae4c36088d3ca45aa997005e187b7f493193ff97589d6ab5fad208bddafa194600a8676d48800ea8ab7818e11e88d41215be8f713b34dc7c237e3d814f58bb8a1961758a22405d50e085c8e3ffe0ee7ca424c7deeff38e429c4e82f9c2ac85043dbd2e3ead3b918388ba15087463ae2bef1cd9008aa4294911c02fa5167d21b07d5a829cca143583bc78160f39ff873a51cdf44bc7f7a28e55a98c839f65c64a8b28876f161b135b760f06fdd7088a16f6d95e0b64f978386bb0161430368d4f0c38053dcd32d01430e8bce4b9011362459ee9b63404a118ba98ee57cd11b51d894f18fc4cac5d9d7cae6e1f5e44842609f8cf845294578da628d4da8a3c50085796541241327fd4fc05224522013d72cebcfe548104808d759805d2d3cb7e16a4437612a12569b9a1412aa9ac259e0f48c120530bdb4e91f2421d8d545c7da769e192fce1764bc8a530eeb4efc5aac945d2a08fc9d630503a4898aa19749223e1144dbcb8e900159a18d0f1bc6f47cedede121b6bd6a245fd3cac0fd5df45a6d937464682f7d104fba8353285e6c90c9b5815295874a4f1915846ad374a9bbfe6979f65b60ae16a767bc9c07604a8bca2096d2cde252d1e0cd8510f545e7b70987419cf0000c2c45cfb0ad4c19a15c060f7df6527ff0f03004f8806ece9db6c10759c988de25609168f00166805241fb4053b07f9df2e046163a2c6128fdb3813826a978a2e1047749e0771fb96ef2f80c98becf6a28b31f228840ce1ab3e7d1f4b2ad5821ce5e4202a18c6a12a966bc15866c048c14a65f758babc8c518dcb7a3df4b9b09b6e2054df4ca8342e5a95e1cc5ebe2569db3425b32a45d58a78988169ff1a5b22914f2c1d128b8f7537ee54f2b86114c42c35ff11e297386d9645f00991e4a109064e0cd61e98d8f6f1898fea38c95e427d4e34b9a2e83d82fee3f5e837582325c3de26fe238b44b0da14e00c9843144ca275167ccc85d088c52061ccb21b5c595a6510708e5868d652a22f59d5d81e766443fd94e0d0e40e8c943027ccaefd45b4d2e581147eb34c8b1848aa54d84a6afd888bb2d49361ed1dc219ac7f9a596286d57bc1bb4feb6b519a1fc60359db3d67fb61117ecceb1cb5b88f32f7bff125e7312db0a5d1f94a07818482d14dd2ca0976c0fd79392a6eb9538fccf4601ade8d3a991d4a8e144d13f098528d49fc4b33fa2ca300d30e52f33e031f19191c671928e30eef18e4b8c03060f2320151b7c961ba11ac71a552226c99a4a65e259b5352a5bd714caf34254a746e3f584bba1bb3c560ecd737b1ec45821c32db9d480ec144b3d9c388927952d1f4f57e2ee3ccff9b5534bda15ae89a73200b6b6e1f8b77d1d30d99087d43b551caa120fa3f2ef593c7808cf17d3276322c047ccb488c5a4482e72d6d8202c8f8c450e00227e2e074568b5dec82a3040f41dfafb9328355ad1dbaf018eb5082f0282541b58c4f8bb36ba56e8403d8239c688d5c1362f8cdaf81529fb115d1f9ed88dcb1241c86a61e85be2c83b5cdc3a6692a57ebdd42b72d23e65c566ad6858d01d958425f57dfc493460bfc4600e4c73ec2b9a5a3900e27a504e739c2ae5b15070111b8c0d9453e1b5cc7e3f3a8b64374b9d328c48829edb7739aab753b1b13d51874afa8b8f29c421aa78e5c9109e45d7265b451edabccc3702cb70a0c254be2790aa2917318224e07c69842975650478fe063cc31eaaa32ca9441a0cf731ef9838d85e95a638c7fa23584198266530bd763551424a8333d1ab7eabe63752dec37f755e181ee6bf9df11c9939b772bfda8ca4217788a72f647b11c840196e4eb49649c7d1b28307c105ebc301688c8a45ea10d31925cb1a0df0ebc4237f0a023206701205911f9dac99cb5519b8c2caa03aee476e202fec5fcb60c641b79c98b45c493d396ee8be2827de002aaec90d467fd09632ea26867f1ec8a7c9906984b24921e65a93355005e4c632f98a648fc86833999e2c863e580449f32dad5a86cac9c0a000e40a90ea6abb6868183a703739c78f95c2cf30a68c8f9711415f22e66af33d0b276e53f5c159ba16e57c170a232c1e0229cd0bf4b9471ff886db544c3285c5b83479cac358f62d99114d59e91c883920c554c371d142c55ae8c3129a98d65924e07af402e08c19276af0f69012403df5a1414c2cd7501775e4b0689890b6512a598418b9b50798cf2842d5c1e316e586590a105f90219ab1efa885caa8a14bb2a54c4f66445c95016d266565a01c9547a2409f05dc4b206b0b643e58c930bd2fc211c0ea4893c0f1a87b9e88d0fafe5c8a169100298ceb921043aabf1d659f60a472813860cdeef22bf1db703f6f238980e0364014cf6dfe1366eaef2b127232b0a4a3ba504f9feeedd9392225a2026af6872cbd44a2b05dbcdc6cf099c8b2ed9417d9a88e00ae045ea0ac99aa256081beb00443712da8361eaf585049d53770fc8c435b797d6756035eb7be3eda4150c6568146ee935517a476ecb726225070d258b155d624d5b371f335dc6a414bb5510a5dba7e140da046a00b82b34209b523fa578a7a48d8a03936ac8261a97ddfec38e445800f03d0e576f0d3c28ef40cb060e6532b7cd20c4b26a0e55fe92231d86cfce008695ec35bbef70630a15da8d04326d8524e8a63ccf2039324975139dd7e2010837216e46917163e167a90025874e468351f148e805aa7bc0ea2fa1735e908d1c838467e233529c9a02080ce53b8a991bf477f253074434a32d0bb08eddca985146a720e1c07f823cc28486aa81863d6850dc6b4f4299f90d17b3183f519432139e4eda6482517b8d0b279d3c9d5414dae2515db261c9813ad61d37f1e8286cf4161b66f6d4d12c7be94dcc92ffd413c6a1ae9a59b63f50d5b94a400591aac2c3c5e74fc807fe68bed7d5c17ee2b25f8b03519c6137aaa902e575b47ac3c6a8c3e42a8d3788d7a657e1e974d53da2ccbc0ac0c05e4dac02f29c98486055d0c4206412937e864e84c66398ecafba65fe948d89eec025f5d3e184d73305272ca0c36e7c3edc4d96d907335f103f49258ef6df8fef595d55cfb9501a24b02785bee00b1661cede505d5cef7da47d0987c087fbc450f1387f3288b0a9d8d409807f651b2e2223060348064f78da0c37fb38e19ecfd41ef1987b73fda1c1c5f4c231191dd8de4811c6fec8d1b317e7db58484a59542d0c5528d7d10b57d7dda7195310e9700683dafc771080fb010f77383809f36d8f700f4a00d7cbf51427af9cc28d0f74ac0ae0b7a372cdd7256aa764cbbf3172f8a975049e20624cfefe313f375ba5d6d6abc72562c19366c3b34a7049d25716ab50536edbee08e26acd489e14e39df9558252951d98874b334d088b869bc0cafbdc48313045eb5bb8da94cd2e49b04c3e5994a0423673384b0c2857ff45dc0da981729c32d871083b12cf16817d828dafacc6f0560baa97bda1d4fcfb0d1a7c01a93cd8e2512a0b13e56c266a7ab0b87d8d600f07a81874c8f2f49c9118a6ad0843cc62124ccd9e4634f2b91a209c18cec846768c615457080218323ae3bb20b8ad09d6c4082d4f75729aab4b279b26458720236c68245c3113eba23253166789097f94358924a3575056e086fa9067955047bed83ced5162dbab84c6b790a133d18879e30d24c0924a588b520c28daa030ee0ca5aabddd26638f961eb3efa229f6f4df03903f00662e980c20da39092e9f60c0c23453cd0d282e5d52c5f91dba2dfe6867e14a1573f1415c2e7e37ca020fe4333bdf2052d2ac9a5980e1a3447e64e1960517a442ed0b59711bb11bf286f0f0ab2c785e3253054e0d896047851711cb95d54c727452248af4953214c1c74c44dc573022ec226df6964e274e6e0e05d9db9487e18c8e424f89914a2b1efbd4710287204224b6147cc96584a07c3c2e42a46b9a9aa535c87175168c81c4613fdb633059c7e277cccc2b7a32a209a1e7b516b1d490847413d5450bf0cca91fbb6efa2e5f872a36d506757538501cb60333da2964d03ff6315d0f01ac0f529d42f7af4e826377ccd8fcdba182639267c4b48be50319a6d0589bd393582e055b166f073a396eedb725019ae5309b8690b407b059fada9116c974932bfbb8d24420e76acc26548a9419f42b076556cc70535f72acc809178c587250bca7d3e41e5013ca7aafdc7f39569c00b5d23a503efc767b9e7955821f76009d2ac56948d4a11a86602f447454099d3581eb969c833b2921ab5f3347b8607844888eb64d7e30e361d2fc0b838a5c894ae856be6847fd32d3e9c01e2f189b9f8580786200638bcf1d344ba25b55f2607f38807199f5c28cfe452bc888c6d5cc34ca19db0e030b9c0b767fbb89516962ca204813bda12109d9ad05bdebe76b3d431040fe8c71fcdd53b73bbf05a0766a1f28f5c67f98005532ccff3b27112ef4a6af55df76e09fe42cd4459e8690fcf34839d324773a4a4c17e9e92f113675db81b371567829c8f316a8c96c6e1ee616e4a576cc623430eba010b80e5e23e08a4461a53843619bb8add4264b7f34e6ad8630f3eec44b20af4d2a45392da96c43d46c278b8d595764f100b8b84e303be8a653a3f18d28e780a2fff5f4b0f85d6981b81e28c1ec38c017c0000f9293131b505b9883ae5cec59794a85e0d15bb971954b78c7a810351f8d3e24410617ef837aa284678141f9f6912d9c3c6f40e645cf36d595e5358eba1760dcebebcc57a220beee8d643c3df049f47617e7ca224a290adc4dab51f53a86d2b70613d071c72d0e4d735c2524fc286551d2b9ce98cfcba69162c6357472f87b5314ed97f03312866078da80b58b1c9403eec8f26a941db90c5b8301637945d7afcf7e3c0fcbcf380b39a37ea7730952b49101dd1b6feb83f15d4f93a85a1393b7860c258bdb31f9933880a77c460e564d055a6a6f10bd6f79c9aa2c003398c976709b3f101636625a456c7e8155145144c1b4323ca36299cd60d03f176f3aade833067ec3d924d36f1346329de0c55a914d500ed7d81ca74299105c8f1ae32647f0438a70586a94cf0882a5780ffb8f650cc9ade2fe6fafa832a118d792e087818df877a1e3dae84d39c749d4fe07ca0d8081c6e842c3fa5cb77c2331f8ee7335db3c07bcb6b08cc0fbbfb04eb39102c4d7cf20c701e0dd95244e29e15c6e2122bc41d49de3aedd82b599c9d9a189da12d4e7e4e2242ae51a16809ad9b6588caf4d907beb8a5a5580b25714c9dee3433b01c1864e6f88353af006a8593c89fc840244068deb421335484ba6ed22960f6f73d593fc6b2bb2a9c315b0a9e494d55b3f66a376bef3810eebc42c260fa09e3ad311909c209e2493d1c9753043bb7e7482b6c4c5fae9b09db590a620464a591a943afeb1472af24777e6eb0d30e3f03a6a08d0d4da4c5d5ff823871242bd2ab2008e4c36ee352f0f7a10b03da72a684bf48f69b52d01dc1ea9be8a83e828c67e96b0229cbd82459de695fec37fa34e59fc1e646bf7fda52d5972419ea803d402cd84c2cffe3a2405000ab211b4eeecca9c6c44cec030045511890ebffbf2de70f205c83f04638f8fb0aa0ff3adb72f74c28e02630d143181c57bf1873971747041f79c7a8209a04438ca41fa7406fccc0c2dd93010197396c27782c41d4a335c4e10748bdcdda106f62a8b5344b512188ae86b056ed38bb7c894c8ca5a860166767ef4219026c3221090ff5b068d084d5cba993764179e2a4c0c327faae89ac9a757b8e858736a3406bb142b132f94471c2e027279d242c7b419ad7764545ce0a611231944679fdf0e563997b264916b2a7b01fe97107bfb6b04192681a5b6197c0cc8253140ec3438672162e9070130d4857dc8a24013d77c2e1ac5ce560edec630ea699c3115bc2470495dde3d0d3fc42b405cf71091e5f1ee48f37a9fd9a8e413f227df7da4ca0de8821e8db89909ee78af7c1215bb3d4641a0f8a69feaa100305bc992ea878d706752276a14986defdfcd93a084944447b0f8c252aec1243bbc9ee6c1d090813d4c394c85899a7a0a80d3727ae47928b2ecaea3ad88df7365a62b6987aaac263431ee6e0a1f9abb771f13683cf29e26a50d8826cb17803c104e3a7cdf63d204032109666f6252ab5d4f6750839a6e37b7d37035cd35adc24a19cf958c20962c50d6734067fb374d964c0e8d18c1b83b903334606926bc094022c0bb049342a3d2d3306702916c929933e8e31771b7cea7fc3f046cfc466fd3b35d4df05e3d72d090917f42cf6b92154f90dac3aa83e7b2437b51401489b99596dd0a6a009dd7c745393475204513d27f3ee411b47e3fb191998c0960117796c023ad208a6a148924f483c9940b538e35480612f01aef3410049eae4b1616ed2cd6584a87e3205b5b5d488d64548b40bc75ff8ee2ce7c57b159c91860018ccd96034888386e690006fc336c8ccdd8cba18f97b552416d2ee62fd901ecfbdb4f13516fd7073bd5c91f6f4467b84ab689bbcc04d9fc8f8bea1dea73e5a9ddf74c1303c414d25fc5ac7e50c24803c25f84771b1c0e2260e14ea65d569c770b090a5673e88c84e01bdcbdaeed55cdb7662e10d05aa274f37374c10e69785c77cff4e1bfb897d5b7dd3b013508495794323edcd9e34bd8a33cd80bea1440dd5dbaa021a5265e188419bae3fb26e752e8f9868bdffc82508023ae79003a0c828fd55e94309ebc8d0871c3afc9dcad5a432edbc98137bc6fc1da810a9dbf95083ed73b7fc70e3c9467aa098d54771114d2f0b867892fe324da85a26a531d9e288c502d12c20745efb5a6fa78ef982f4611f8a07e709fb6b2962465048931a28027e8fecb260dfb9fea0725694928d228c247a621b2db5736fbeb9b9f3868ab43e1f1e59d2ffd3503ef9af8e5e26cba69088971f1a9923778bc587198959373e6366b1a97910891e9e46c6097bd8cda184613864428ac6476796984680152886e0eb3186244e4b7b480e81e20032137bcbba04acc13e7664e0a88441410310d25fa217d55d4f2d8419f44adef936a1246edb804f0012284ffa8524047772565e915f9415b4cc987ace1631014acec01edf1af03ddc8194609ad042faacc80e5d7dd12cdcdf8c680b710d86761b2879ce572c80ad12e8f5db6e46f6c85685fd9598744e71915e044e05662697ec8d4b26c246b26ae5fc6fb06641189131bdf00da9f36f2c57649a8cf1d937b8a8caa060d4980e5397b0afe156f22e0cd01082642beaef3b7bd4fc56442c3f319fa36469fbac7b70c4667c729a4b046cfafb71175dd4c510d88d3378777a74b680798ba0aca08634ede431f2b581eed62f773c976894668ba247e57ddd27291a0024c1f1a0fb121683c5f651a3c498add6b53b8994dd615402ca7c0a81a91fb7dbd4b0e6322a467b269e187aba09b66095ab172372f56b42c627dea452b5626aa12dfb03b871e22c05ad9a242fe2d719bd445bed8155d47a3c26011e07e4895855fb10df6f7ca0f3d60269380d3dc5942b454258370b9e20d6f2912299230529d55be718c0f2ac0d0378eade02dcd081091a4faf008436e8fa910a998bf09a46a474c6406d29f874d64018e6d1056ec4fc700847d4d7d8b3598944560718f4ebc588451c27373e68f55403286290300c6b80843b1add9196383cfef120cc4521a616325e41dbca3bd57a6e23716bc10c65197eeab0285d1e44e51885c379f2543e032631c975e7ba09936324cd3aa0c8a09a913a162c87c97216493bb5ad17f81b330468d708134f5bbe9783541ad2cc0723b741464e0d4d1c5145d2c857a1a9eb456890ea7b88cf3b74287a77ac6016f975209f9c3e1ca4eb5cc7911a182e79bf719d89d90a0b5b41e4e0352c6d28beba3c2ec202d1616cd91c169e3f071dd8a5adf48d1053d00cda6cd166bc9e281db6e89fc581d5a2ce67565c4e9a0b46d649cd248752fb9d526420d2046c68950aeebada097e9510f0c0d7c7139d61e0544cfb48ee1c00030b8cec4ceaac763fcdfb02279e1850136b177e060609022fbefc4a526745fd95582058b699c470ea372f2669cc53cd01581db3a88996c1cfaf591f0e76135975f9c88df3b36aaf52669882c6bb92a20c73adadf45351bb6552afebe668a13516082a508d19116f8e6266c7637cf242ef4443b7a310f0256f82368a2b8c11c805f0af61ee0eb7520acc2d1b9c065286c2644cb9bc64399d8d541582d463c08975af65ac05f2e06adb805a3561473cc471cdc60f2a3dec058522bea44a7e8cc2369626a5ccd5c181000ea17e33151d441ef524e9b710e1f9dd4cb691a58e93131b6ab8dd4f8d2561473ebe218373cd8a668a81bd054862fba1fb5ea32ff3744f64a8a27d8f5d539c2b6512b90e421217f8a68ca4a6ec1c93b328154b8cce331affd22ac375a5e73f323efe258c1b6c991d37c88c6db89ed1a46d46997ae9a401c42be04b1d083b8832317d669f055fcbf14ffefc79a37d20aa601714f44aed59ca2cd47a58e6e65323457b7f51766a2f734931ab7f6ada3fae82a56dc2ce951d8c48beeeef1b576213d092035dd481268d7515dcc4a7a17ed2bb892b379ed03e6fb1c8f9e19731f696a5c1aa3bc4f4c31eb4bb8145beb6fa5f4e5f804daeb60b1b9f651a9ab9d138265b3cc2e16dc32a29da1e2d35fdbc3ad5dbd5be1bce5b24b254a0e17281ac1e5ec165b80c00d6dcc204a72a1c48382ac687611f4fc2dd01c00e75227b3f023de097fd479d1a431938264d94dad05ed1a34b890136841f76b6dc4fdf52c005f5fa5c0023281667bc334179d13a9824ce67613941b34e01c2b9e107e68a90e206849e6e8f2ed70110fd2e800df3da4320aea49373104de2e86575b6138bb89a162f98a4d92d8287d503943709fe5bec7c6d594912a627c66f8bda06a3251d0687ed53b608f18f61bbd9f6b1010976c66a536ee90b9b114bd12084ee6b250e2769b435cdccacd46eccc99f7a97c03fd2ad2972e48ef68278d525767cf96a2348ba70d014c97b5d865e928510c7a191371aec50815fb4279485ea2dbb7ebdc023b9a4b3202a825bad144942c5ac04998e98855083c68c28d410544cf8252a44b658dca937a108744e78c27e34a45e80d6036fc2f8e82413d8082601ef61f7face77b50cc57e4aaf61e7fa54f49d374bc527d626a7b752f75bc8c223d2bc661a2ccb8e1b99f96b16e4ea47f9a252c103c3cfdda5e4ebe5d63026f66be9aa4c8bdd235c0c63744d747a7abf2e4e0e2479025c973a26e716431a6eb39066372f76909241a018a9e542456704c317517283c880a4ecde828601882869fec8bc21606b368c014ce90a730cf020d0c5780a5ddb78b3b28591b285998c8c91a6c83cdf2c2c97220855c4faaf9b99ec7ec276bfff589b585760977db7b4b99a42c21012a022e02330236ba109e4c36afe0db1908217ea488a6c760da3eb119a1c9c60955276a54343057464630e2e74ada06ae3392c7f8dfb1ec9d33823d609fc7bfc7cdb32f3b9412410bc7088ef0bf5de1e081be2524a66158ed3f6761016542c628652c468c2627851943746c4a1225e73de247151122c308e0780e986a38f758396ac5a3d33de252747241b6cfefd0b683649a895a491ff50a496ac884941a0ad516f1ffd4166750426aa3b1a46dd0d86501789bb3cb75c011ae3e2eabca5cbb3a0751f7defbff4dd7ec56b9cb02836f8fcc6ad82db29a21a79c99cd921668d7b073ffff6eef9cc33d841abb4862d13a296b724127a41b5952765d81a6b873bbb6f3de3b7654119ba2cd8dd76db28972756409ecbdf7deb570fd681b4acda03929dbf18811156432520e5170a8625d6c59d821d8aef5ffffffff2574d7ffff0fd32b2430863b57b6d3309852261dfa8cd78af5debbaef8ba4c2c5ea8391494d215351e1f02425e4043b69a6c48dc9c237981f40011e34b24df26b092ac4857cccd3ed86507ef78379823379a707b965b9bb2fdd880abdb5b911a32e72f3b92326f00921211a14571bebe096e2e20c52c45959016cd5a8a0d020033aca17766556dc669ecf6a363510095d204d441e7b710bfe0343db448b123c7cb154e184cf59028fb59826bdad81fdc628f0519fde3bca3f7de85c2ffb0defb536639e79c8b80968890c2226c119958021d6575a1ccbd099c3680384a251a2c3c8475589bfff573b0ca597557658fb54aa20285ae44793e6c484cf104973978ea09de67deea46bea44e361e06502c5e63ea90fbe0dd032068e8c27cf60a6687120ab685dd5519b2c8546b50ca5bbfa4386b5da3c31140910c0c3a14eb1b73abbbf75d325e3e4900d98c888311432606e14d324a3450d0c418b98039cdec95674fc44daac6bd2cc6db7b8f07c4f9e95f978e0674c705fc00428ec510fa5f658569e212f1e65390d8872aa4cec097e51fdeb124997888742e86f10b568d7d24683fce79eedb66bb6580f07fb62d99f9d507f7ded7de7947d8948c08ff77846415571fcc77701d3686da75fbefd8b2f6807a2974096f2ad4606a0ecf9f0ffeded9f7c547d529c982a2b5bd72ea49feff2d95035cfcc27722514396fd60c72904d12668eb4393bf70968042c97566c34d6975b655e0a5ac7df0c73af5694a6ea7a01ebcea4de8f550a903946c4962ba28bd865469879636b8ac232566e3da6a9628a71cb26a08704602e11f9b63235390e03108e7df7bef254be97fdf518dfd72aa976dbde9d3bb5bd9a45a0a27621b8ba5259822525ad5938ecc0c56899da20b11316c711105040a99b820e3408207080c4fc76d80caec4a66e8e8e92d08048aa94ca013856a5121ea71f319ab114bba7263f1026461a354e06a16400050dbfb1bc0ebff97fdff67ea0cb935ae0427a6751e4db3428ef368742007843b27f82936a0fe343cd7f928396ff6ff37595360178f1a35c3d0ce02483755834e060d77bc2a88993cd1dc6bb45521ab71569d268f535e58476a9dd324394a610a2427982a4990f0630dc0f6ffd51d6c48ddae9750be242bf369adf7ffe5af938b9ecfedcd7d4945bea6f0d38b75a11e60577d5ab1ebc707ddb4b0e0018881b88802dd8c01445c00f74fd35e5f970a26e2d1112b509259402541c15dd39effffcf6365cf95358f550aa8323d2dd16a43895d063483be672a5edd65ac602b91068382143aaf6c28b9aea6509c058d84186c182947d65c5879e17ebea9b8f7f518e205f5409223dcb9b8a75ba5bf7f907b142c5062fa505b562559e76630f5bcd5429982d4764c069fba9a64c531b6e8da7e215ed80ada3cac1ab7302fff915a98f11b3be918d6a6c6921768a41d1a7a243b498007cb84a10feec53dadd6d3b685400884937d28a762ba2657044e9993a5bc9dca9b1ee0ffcd754813f6cea122077d7e494a9373ae1a9547612caf1c52e85188e75def2ffba320eb4412958f96d4545408f2c9e8cb4fb81452cbf91d6d977fae6b43ea7f0e9d14b3188c822e3cc132640f849eceabe2922de909b59fcbdc728d2d0a486cc590d3d6b1ce905b3952c3ab0920fdc30d5b7b679fbbd8bb7ede7beb0393df1a4853ad1064652f662598689db005d19890424f47291a768bf19fe3ff04c8bf3e625e90528336e4596b1a11b7b4cab8a6fd60069057d46a07ad6bb3c8734d4fd833167d8863718b3302a33a5111672e471cb65c658b1fde16065de78ef3a82b21cab0caa502dfa5850f2ed88f1571229fcd45094ba2867007335114e28a2152b04721610f62d6646431cd0c396d1240af552348effaa8ceba43cce4ff3c18431f77c3c918992e2eea091c2d4798dafbdb8131c9497825138bbd006f541131c52c9176f1e6a5a662c87788a67fd8318819bf48c95591649560cb559c7cb4f90ea565b51407620ccd8589c326febf9f62c8f65ce63fbb814dcb4d4b8d181ec07258305b5152593a449f9b8fe7b91fa3d600ce64e6484b69470601b21b264ff0490686f1f949a062c7b6f1791ce5a3f2381f63feb1f95b979d65d39fb6da05ea486e66fe263c661fbcbeeea977c5fde4a590ff3bfef90e997f6231453b606a4f2e95a01b369b22e78d299ab48706e7db3569b1182fe46ca846d59134a353dab4ab9df49d314eea98d2adcd062f10fef64dc618fa0593aaeeeac4d299181d30916500183007c657122ad536733562c689891714e7a6b9e9c081cbd0d3a7bdf3fed1ab9e8484942d1142bbcb1b887a1987ecd3b89ffd357fb5f7b70daa33e7af8e246bee4fe90b8df997f19dcca771f364f3d736e727b4e7d6bd3a873a4df2d5843d3e78325ce6bc0776062ddb122e2541d762b322eb64e6b304421bf19c0993b16774d3b9f7defb5067c8ad9cbf44c20a35713d019aff2c003ba77b7f2540fac0401be79ccb3a436e4dc614d72d45ae3c73236af20c1ba5256953a7a9745253b2fc0b462d791c8ba26c1958ddda6cc837e20b885f8c3515661d2ead0735653ab16242b1421b3ee1e73832e73d5f1d7ab638bcfac82d30ac554c46cd6b724bd9e32a5ab98e7057ec76353f387813ca39d6248b6a8cb435c58ada5a4680e0d03b0d22bb63bc6412af98c3bd0b097bac4b2a9273de0035028c6fa87450379540124300b31800004000500c84813011f438f71400030bc064c06c4028343c3028140c8401600030001482c160000000060303a2602054109894e26a0340782386c18219b1ba0d8f9ed13f9a226e9ceb5ceb91e21e0087d849ae95ce2340e269503c041807e4acb5486f8eb9c9ff36d20957d2e2dbfe3c0285ee0343ef7628473c83168fdb04909216c60072740076efb3c45dc219aa69a35e56fe0a409638cff71529cc779b8b5ec93fa989c8166eaba458fa878f03d55608c93796867d31b25f36a476a26f2cd94659c56bf8500edc701c93698c5717cf0c546d5c2037150fe0a3b01cd811f13a39decf2d74edc826caf29de0af7212ae60c5801985247503538c89b00cd2e357a2f5d267bb88b62de66a31805bff9bb26913b0c9be09cfd4be1b082ffec7cccbf7d37bf422049e1dc01a723ef9f51e6768804a72373394371cf5acd03672e7496360c0149bff543b076aca2759c34bc07ad45ff803c9c7e7131bf2f8ecc4f2c05c2bb2abe8e679a201d4b6e3aac6bc8449ba69288381c31311e894d5cd5533640fccd2c1f67fc3673adb59cfc78a9240cf1597e7e4bc1f212e7f0d8f85b0dd79adc99c924cd35f3dd762dc9d55081bdb542871595ffea4e786b40c9e09e3baf00e343edf63a864f410b48ddd4fcbe22c620b160def781f1a5c308a8d13e31fbd4043dcf1d25279a212172704c0f0d4e9fcca2e04a1f239028cc11a033d620cf4d1f2172e00413f2bc86981539a067a33b92a0a7f6c559216a3af5dd397012d752e1b9f8412795c68d83a010f61edd3e75323023fae6e210266205eb1c708002c64f01a0fe0fcd44ea4f4a3eded1c0b85d50242b5396da6c90e0b67c8f92dacdd9c8126290ae00a60d75818e865e5186bbc87102805a2f69b4305028e8e005ed28f72e053f55777054359ee9001f0a72200a29a246faac710e5364b446b04a9aba9a53baf4de41dc8b96faeb8becc9650739ac77cf4126afea2a4eaf37230221cd064642a8fd11e7a32d7c5636fde6f1765686d4172ba85b36e3444d1d422219fc47c261017f0dda1f32626fb9c5922cc571ca7aa910f74fd9301a2ec6fa4851480e7c7df369b8e016da3063666743abd2be5bca208dcb984690714916664f61ff872b1017c2892ec11954133a819fc96298f9a4a26068b628159c573dc812a260ee860cbb461634850063ab4be487f299205b822629b22a6a3503404f1c927eb0876015b59a5671d8bd8af39fead519134490f85307ec527e9f124d1e490ce4612f6f2e64088e49e5738f70edce1484a28df5039bed079ec0b5012322da8414b0beb28cfbfccd8bdabf6b9385c7f08a25673c4bba3deba44f7bb09afca64db1640d3f5f98e92804ff02098fb44e8e3aa591b44e124fb4fb8d7033c0e36e9b8ef8f4e1a7a88b62edd5ae34c4557b8fa8c367070e24f6ce8748afb2c37ac6092e3311881e99f3e981a275bc8bbe802b2a90a684396198c7a8eae73a61d236b2257eea9fba23bcce8537aa449d7a1acac80a5121fd97d676cbbaa946160430f8126f64a077992f95805290ac2f916dbd5edfb3a812344730a3dd2b81e62f9b1b9fbec2e3476caee42fd2b25771d2116947ef696e14b4a0e382630423ea68b1606649a9beae125a76449a030008ec8905a2644568330c426b868bca988eb0f769bd6b85cfc78919db8c75184d11d02df61855d19a27d0290888acc4ff8fa27b452c32f4104ac5c0cd0228bc96e9da3756ba301b22120eea877636480924ab8cbf90a0ba5d9dbed17d516d179809cbad1924796ee4aaee921faf981a31abf06647a9259fe4d112d1dc139cf4aeab0514d336902619d73046abdb1dc1abc8de50b0e4c24223ba3350e6272d9c1a2f0c75b1f171becc1eb108262a01cca7f2640dc55f66fca9ae309788be4a53dca0811db504c1258f81db02242a5091451927255239a80257adee733275d201e32b27651f70912ffe3b94d2177b1270d67941ecf200f08d14e31fc44640c1da20178168a553144a1c2d6043cc2d8264913768dcbdc73a2bb716f8dedc1ccfa334548c839acb73bb182a5b8554eea51128f2f4b5c65cfc0acc17edc7c02f2f6ad45f9d6d6c8c146695cdc93680638b53f54fa0b567468a3a051e0fd44e54d9627412c03e25864684649e2fbe58f6a1c4da4cd5161c6fc5171e0f6e77628ab6190f3c0b4b6f2d85082d9637c7b6487a0017533d5f08864dcda81969be0a613a657ad102f900f9e924a23f3f2060e8e42eacdd62cbc04a2413de0ff5fb99c8d6ec4ac4e27231b55d43650276d4b6c4d211235c6e0c18c549b68aad19a44c10bf92f7d701d30a5ba3f6c2bc4b2320ac3ce3d8203658187374e26833e11308c7cccd71503fdcce50a1bfa91e586a999a585dea2789c86af17e05eab45c35297e63f73c2634fb0db2623246e9b7b64b69df221e27cad435b5e98298bbc9fe89e862d1fa4813c27e44449402424c079230fb806b150c0724dbb382f3386e0b072d1bd3403ccf3f6716f02a3b94eaa15111667f012f64ad91b61cff8426a48861a610070409a31e21c8b4b1aef8d997d47219a121100840b264e88a62259ab8e03a7336c77d581a4d76bfe5ab4e8aaa1425dff5b95c19236a17debbf98a130c362908c51bad8ab505a82bd64b27624da97c8f8dc4ae6dcf24d3d97b14f6ae2bad4b792bea96bc7843fb6b3c9692141b97b57ed19600b6eb4f5e0e45e640059a4c6a99eb34885a731c94dc57ae10fbe95217144c83b4d0a7883fd0f22a1a572f43eb52ed1eb18a60d260a818fd766ac60071224f1cfdf61db40dcbe149c1fef744aaca60e1c9e0d1af7d9c4c40c8828752eb83fed9523626d32a1f53531cca5229db392b91c2c89934af8bebd6e160b58103c6d20d773098f6f9ae15fb044339911e32dbd26fe6e4a4e7c5b04048240b2cabd796bae1aab24b89d1b65cd1c9dcc7589a88d326d5901b425aa04a1d08b75f9372861ce4c5ebb9a122064e43ebf1fd438de4654bd6c49997b44bfa43f78d353fe1fefa388573261a4b3f6eba84761d55574ba42f08d23f019ad95abbba1fd18e9f042c22bf21b34c7540555ccf924f916917f3f39e9254636d686d7d7412d95be0a1ca3458e7aba91cbaa411098292e67835df12f1381800012ddaa9459e7964529370e3a864d2a1079b0560348ba6a35e5df252985d3541f03b17271fb9123b7a01c1fcd8a855699141545a737206aee858a55c59698b1b43f9af126c788aa4d69d2993cfff667345d4fa128bf6909281a1d431fcf34808a08554c06b044435427d4f3a1a2435214e648e1e5c148e046490260cc81d6b561cf676d41933412e6b381d39be081be89b00543568e5e5d8fa130b017d44c193e8acb3246c52852e1799095c117c3e71461109baf8f71674fadc5545318b7a3f8af866cc088a0b0acfa6d395e629edde040e5679251e5266e226d8ff059224cbb68144e42ce7ccb8dcdcec5768cb94c57e0a28c9e28bbac20143150ec51a8066df0218ca693c2b0db8a5cf8c50438c83ae34578d598c908ea458016880e836c0bf54b9cc1658cb1be72b1fda5ebcb9336c86a374ed8c97ccaabb226e084440afe106d7c0dd0a0e3ed9546ca643056070f6fcfbb3bc4e9901886531fe5880c198879a2f1b64bf09d6904eaaaa97189171bb9795dbd661c3eba2d5841661222951dc0fed8cca961fc89e0b0e2265325501199fa80368f8893c0a345436d9a76769e21730aaeb06cf32e30d0ed009264a6295748e22fa6f0bb54082cb566a3098a1605067e44c4b80b0e305db4115fb00815b4851174b64f36ef0b9c78c9d2e499e3a709fb1e3b19fc7c8be1160b3695dd4f006f5c4675f073db25e404128dcb0c595bd46bcd04578161713a987012068361fae8a9e05270e3394f3b6cbd559fc8a0242e0afff0b6cf991a8c2735fae90768ec76b46fa1194239731d2b919c90d357a2c1b3e89cc43f37b5755a6ce8a5ee361bf7cc5033aee2b1b27f5ed43c9507ba410af558b914fb942394eea5ed2620978668bf96140e47724417dd1dab3b9ac62474629039acf584a58f2a83c96686490855d74bcdd22784f8ee89a5fff04f6872970c613e27df4520705a8f8ca1db5efb9e307d324326ab5298f7f5072d10dbf2eecc170187b9fc825eb8fc88eb695740499b51cc23694c9428f25e6e2607172025701b1b2264a9190e3f5bd0f1b0c3c02611f09b449650f276465c13a87aa55740d59fed03c67007f9a8a308d88d958c8327abc8d689e5c26d9078be1889804859f58111bf252cf4c677d776f0d3010436413ae00f28bbc0c142035cc7fc893037fae648e1c0c203a3ee91e8db30e7f9c1ae8bba6307f99ad0716d0fb5e1e383ba37bf5181182e912f951f630323a73c24533346d6eaa32a23567cedac1202eec5b0a39a43ff3063a5c18da009f3dce12295978a6554e20eaaecc68c23d3584337799de7c1f3db644c9c6658c0327abfcd7963de8791f783db5c915b68b99a79ba35306351c4f4c204123c395d1d74acd502c1474f1111904d891c294c179dd83f79f7f3089dabd323d9b14f8b7f972b78db6c299b52a6e14d903911a60034bebf7281a7ae1fd324dafc983ba32d0112b5769caae83769b08e8cce92bb9627d720cb578d4923b3579828037591d1fb49b44c7bbce13e89b08e7f9b38eb2131aedbabd863f86818a291715ed4e98074cc581a945d0a2897e77a7c646303c61b0f48c9435c260394a7a8e9685a9fd1ffd5487ed5bcabc00023917162ce12ffc8e0384d7b58db56a3f41ef4d63575833eb1201d91d90a29b74efdff735223ac0c8911da9cd7ed5f32314fdd087954c40fc1c3bed4f879d7baf3e56080594322d988383f516d7a810d761b60701107c7f0ae9ce4f9ab90ba46297c3aa4e1df59d29f4f50c0f24955d05692254b615c21372c963f564e6f7a995de0108792f85634953fc68fe89ba11a390521fcd3b1a684b916f73c0be5290d1a329f07d128acf823286f82c5c5a295ced72342e8c87c6d03cea5d2a01a88a6cb2a3fac8f07d1dca151b033a955ab222f458d0bc3555748b7e51cf7a72df90361269db034969978b154ef85448fef4066fa0fa003235280cf217c33af4ac206d7125b9785c811e63bce125c7bf48f42abcd2309c75ea760c615db16682215f4a5ce0eff18640f2bfeb5ff9ef51229dcb518de2921bc21db7b2f1eec2d515a9ac069399cce9e756b4e0b52c113ba020c16ab9e2292b8179496b28ad1824c9173f12585c181b0d9a6f8fa64c128e022680a64e6c21425aeb2fd2cc709d6adc88ca51d2a3de0192839ed40432542079a437f078dfa999e018902ff47a20110f14a514d4b6eb0ce3b2b65607e064fe0bbfcfbc01d5f84708dbc5b17d89a5085e1abbdfbc6bc4b0afcd3aa7dd3c143e5afd61a3528587c67640e0a457ac06479177bb71f09d683ecf968342b8a61bb812210c8ab6806412d861e9960516a9d1fb4c9807221e708352c2afe650932eb3178ff0fe6c60364fc86fe8d9651a7ad88756a5661ce742e32689c6eccb8d4f116596c189bc201860179ba758b592a8c2594e78711134d9a357ae9552ca2082af722a68923f6dc5b6c51e34c02f972f0e14daa02a9990a83dd80b571d0f1fc45d7854c12ea86412846ac1f9f1f4fe9fb69de4ab066e3e550233e4c251c0fc684618ef93f2a6492ca8e0341478c8bbbdb234d4831ffe26af20732fa4998560e2551dd26551fc7b52a459d8faba87f5b09299b855388838680f33314803f86b4deb942e84c2645c54da49c25976fd000fbe59ebb7d317ca2b402810db6c54118aa24aba136347608f5cde19cec8ca6b824f7a89e1871afa92142a54547522c40d2483f5b39785273949179c64de01903544bfccf7bccda193c660da229109b249d4d645bfbfc630649649bdbb914b9d189d41239a7487081d60aaf6ad2eac424fc5b4aa9f225cee899439a411dd01270fba5b26f520fc72f938313bb11db2df13d8280f9ae067f029c4f2009a19e352fc83688d71267811c10eb309864390261f2f64a773e00b754392dad8ebc03332ba5575ffdda44018589065fef782f9153c0149db0cef634743254720a6cea7f2da8c311e48bf4d859300d8162411c10b1175212704705b36b8a73e3b647320caa76c474a6c711593f1dbba9bbf35848fd2102e695a04137e26579d310011323741763a8253408ce89b66bcc7345bef56e05d48f89d3bd7b8ee20a9a59e47889b915f399d530824a94013955da13b1b398a0a6ac69d11357cdf6992bf8c3e0abacbbd7af69522331666076bdbaf91db906a1e4a275eed1b4dab7a4886a610d7c416b20802eda14fa84330dfe1394275358761863713a3887e8666e5df8fb301beaf0cceba806ac264a467105837367542221b4502878cec1483d81143f708791213ea8c44508aefcade4f7b60864f3eee460dd04c02509a38074b8fe721ae2e047185f3503b943b8701549070977cbe7452e7ec910b0fade778b0f922412382ba31b0ff54784963fcc632504e5dfefcd3b549e4cf0d07abc48f70d0f83b321f304d7c3a8d99e746ef8b4094daffb4ef1bdcbafc0f17c2d77ed252e4aa4737256548fc10762ca78646f2eda140e8b16148e007248016a1a4527899cd4941c38164ab5d3000bb46ba0141babd00283be5c34427201244940c11040180004fb12028659cc7ba2d69ef18f204bc4875c6640cfedfa7cc14a3c6a848d218c3f4630e19c543b2ef4435c9c4f7a90e027673e4c44b0fb14a05fd2c5b5518d5f80809f45e63ed2899a3765b2dead8898a1a5e990fcd030efe3c70ab96c5a122d70691a107704a032b8434a64e6bf29584351a64d8e2516cce6f3395bc57acfc1815962e9c5d8ce650c07b90fc03c54e2c0f1200a3c505c119c3f654d426dbed169d6eb943c1f4663495d21360aa3447ab6bc2043007dff2265ed1a02ee696f24512e19110f22f21d521c7e65f1ce265b4048a84eec47244a74f047a0b6babcdaf2e27efd2263da81cf3854b7453b377e6c7c5e83a2dd6c22d5c1199823b8139ad0c0a123196e6c6b05908d22d1d7c68b325f9edfa4e94c869c07de5688161542fc5bc8d4053e821c42ca149f637c0084c98025e310520849a48b009d81d8690483b3a4f93d86b406f24724bc1f4f0130f2ff046292488cd7236cf29268a64087ccca6cf7ea2c61a2c914d5c1ea79c2ec329a4fa0671c14cf759c31c999469f20ba09697ae9cb22bc19ddfa8021038f9618c777c533dafc2c09701b80b8d57c7ef404450cbb25ef1f7325b152eb260c831100c2e55e3f5c11e0ddb897759053902e23e29c7c8c09646af54b1a7c87ec7069d5e648ccf4f484434580b9ce48782272e00f4a7c0ac15aa87041965c8edc3ce7b074dc84e926e1395d6eee88a5c345cd3585be319e26db89c760b9505838fe68357376a94969956881964539861c92ca7954df69d6bb97b8c8a923ee76c9fe4466b41bd953927cf8b34fd5db9087f849751677f7fe59fbe62d4dd424dbfa116397d688d5fdeb854609a8b8a820c7c8c96ff97c929d6d0667a15cb05ef46e8c2bde416f049258649c1727a8dd5610fd481d36677a82c3e9029c1100b5bd1945add5647b971e2714996d3be3b98cad176f078f15a8e8a739d0182fbd3035ff3834420d2ec83b9a6f6ebf36545315b8aca4718546b8fd7ac97904bda6188260881e31b3c63c9879e3f4c3b0d4642b3e088fde605993529300d00be88e1ad25ed96beadc43b97e70aeb824a5269c77aa636c5888f480a21669bc0a76b2811740e8d36f56c57837858279f825ca918388b3a8e7537ac00d583d615cae45fb59c30094f35be8cd1820118a87ef4ee0cbf6e01e726b863cbbbf0d382edb90667f77b6775ae00cb26fd841941cc11bfd7ab2722235947317c5eb29b1528318bdfd630b0f7456262934bc5ac1dbdce1774dcc72c907e8a28cb1600565bac3f076e041dc94afdd68cdb35cb5b75989d522b75ac9a92e4949a5206e7400b0cc6277470b438806747ab005efe1aaddbeb4345fa910d8e2f38f8f3f85b0e60d4122a7a52904b902480386171ed3cb885f28684dfa2b02882e829d44e6edcb3e438be907b9a1536d1e421142115700f727177a5db059206fb1f2900ecdd094ed94d86da04e36a7b01a766a5712dc40d105d24d013657c705eca5755896dc4d74eb141f9265cddc6df95020a39936f0089db919be93e7f2959d8d401b11c8f31de79a40739cbef182ba647e2162c37a1d6ec039bb0238a807f3db90b5830816f1096078106937ed86e615b8d864c71bce23c5ae45348f66117775cb9dbb9a4c7f89e5bd595c539aa6903053473c9d84775b087780289a97da6a5b51c213a190b5eef69a865038ef05d2b32151db5cbc3ccfc795577a9bb5294e15d14325a42bb1e23a23a4063ee5ea8adca0a52c6f0c1a3ff2eee0138a2a4d83c93aa27bd6a4f7b295ca28379fdea90b3c02f0701a3e881e6c8ce2f3a3e86883e25b1f1fc296a05f3febe3a8d8fa66a8fed577b5472241e80e0b098ed8b6b2712d51a47e689e39545e32721f04afb00076e14606cd5322b6c390b3b6cd162ee1299e1b5a095d62294068e5c551a0f27f597030afcb923df0565e3687d46592cfe15b2ec63d73c56f9feef5cc776d591bb64041e403170e96c3ce4504ae12a998d71a8bd90131b49ebf0ae1832a07c8df41002aefcfe3231dc30a893e015ad1f1f32424235b037a141c33d323615f19133cbd9ffb7ee7448e93066514decc86ece6666683fd2ee11c1fb3fbf664c250433e6267acba5641c5ca2566054b77d3f02089b0f11261a92f5fe75ef4ff891b3d541d0941080e7c2020a2e8a0d1e0ef47e4c641dd3bef89b0a00cdea46f1907a1d1d88ebdb76b66bd425be7ae468b0a71d77a776418af0658945d900f3b44ea3848f4af13b330139bd83736f6aa9addb49a35fe007a70405bee44bff78ae04d29d36c0dc888704080817661e5fbd8c7a1e6fdaa3966a34a0dc306dda7e86008ac075e25067258c5d5124f618b0b5702a1da9e453da0970030dabf135014984598200f27565f7e5318c6e648336322064e3d598881dacc54a2baa9775d6eac434d528770307a046385a2d417a34432f1c83d48e339519727ec7e28f4942ae3d432452769068f5eb42a14e82a6fb86368dc5c37294704efb4d276aa16060d4d15c15f4b5977082e6448b148ec52d75e88857ae43c496e9590aaf40371c799f383627619dd684723482759d7124c2c4e5b22b6fe8292d140346f96581773089725c639cb538cdae6dc74dc275df269186829217145688c1f880d707d1c7f8237430aea8e4ecc6329e066148c48e3b79b4eb07c10dc846866ce1c22cd10b69ab5799933209ca727f4a3999ecdd5737b96cfd2472e8c07742071303a38c42647d6f6e916ede0962f6117dc170d4c19011a90f4205780cc61750e899a83ddfd834158032e0273300190836b612cee1a51ede660ac7340741c1820b67307562f980bfe3f09a5faae6a1bc35099eef7124a50410298a554a13f59bbf8f41b7fdc94c0eaf6bfffb7943249b9f70e0402f701ec015a7f41b91219b4f84e932b5e8f0210a3d06a54d9596374b1804275dd40b2ead041ee890550850f8b4f8e7e7140ce4b06550ab885f0ffb737978c7b61909b73374f699dfb15b5dfa25dad56bb00288893081e4194154ec81ea34a8a8c202d1a58d38290d9fd6f130c1849712981853da9a45c3f9888f9e204cb8efe3d29507568d1bd8f2fcc5ec8d15acffad3aefb53f99dcaa48ab7b2ea1a837d732f2e6732e57c7324bd05f7c1abed189a35e7b5fb3e87214d0ba61391ea45024dc2673328696329ee518580ce1111aa5080f3cb0009ab06b4c5cf45a74307b91e12256cac046386dad71a97ab5911f7c2233798820833b751a560bdc0af040bce15ca36d71398dedecc9c02664564600e5dbd31ae25e94dbf796f723724370870a8fd80b9432f7cf2c73388262738fd60333cda147fbb1662e211ce3927069f28f4e6762ba95d7f60c4ec30e7094b219b690fdd7bc405021d1136a4a4d1ffa97775683d1da2d3ac5d60f0b1435a8c4bf2934bd2eee2ba3514ae8ab8b76b9673d78603d049012f9161031a4743910900903c78e4a0e2010999509aa8b0332ee6b346d045e6c99c6d19216986985f25f4af330538f001f493612585e5a56ff6de0efc547854784e205d14bd44217b8a9e4a405b84c47bbbe9f05f448f0165da0a61b0168c9666f7ff2734ee356a51d534cdad51777e342895c66c4d355a1fbb042312e32eb1c620d75503cd1ba6e20b1f502c3294341a1e6c013841642874b6ba80da278f88e852817969e125e84b65c790458f652a32aa51e18264f1292a43ea9e7f773d59f2daaaad46b3089cd916de74d298dda9b88fe05ce69c3a31ebf1a60f516ea8669334927e14b0fa76295faad856eaf9fdffeb766ffb347aa801128ab21c9a14411dd84692b5248e64e0c4cf14201ccd33a2ea18ad3ac69776937bd7d3b4543168ff6ec1d392e7d428a7d6a997323f3bd3715e132f989d6b4db678ea6a621525e9479b4817645ddcbb5b760fef729b932bb2ba59d4a89973ce9dab9105caf3766bef36d2794700110d0c4d3f15aa259384122415c40a93716c5f105e94c4192db05208403a589439e72f5665ef9d789a11023b5bea9071b670c143ea7531e1db91d9c3f58e92e72a232bdd956eca8853edae76fc0a2bfaa3164ddfdccdf940d3cad41a62ed7ded9d5dc3006bd524e72d54f1abf78c73b1c2101c00d19641ec883e378082d2f2b32818936004f7c5aa8a530352770061845698b68a80d3d7f99873ce39538b0d5940b2ca5e9dbe0c01f298ee690609185d4b5925247c312bc44210c51d48a061732ae05a4713a32c03c03001800c75051abbbc037a9b1a3a6d584375d53addaee938e79cbb5fbb1569d8909a12ac334076efbdbbde7b67dd2cda0c88cd7c6ca9512b566cdb7bdf7e2d5af5e6969672f71fc067ee649871138655fb95275e3aaf1d6bf47279f9ff6ffbebe35e7922535987b067499603972272dcdfb78dfae9396c5a3f3cbf90c52bd6a38b516d9b87fd8a40eb5196a8ca5a92be5998d4b223c43a0a1355662520ca5a0b44b175259584432660ce94c40d61833eb9d414a419cf929832c333b319155f622c8b5e2bc211a15289fa5b99b1ada982a811c0deac0fde505ec6dc6016e246b2f7638a1eb4ffcd02753ac562f508a9d1b8651738ce5bce695f13e7dff0e59c69475701e7fc58ec6feec5e5a26f6e4399dc5041d3adee2d13ca23a296a53a7efba7b5b44f65d8ffffd3525e3e9e3ca3afd3c745fae7c7ef43dbb129a29eac18eeeda6ba5c92e2debcdb744be5c3160befc89e48a685e41da7389cb5e8daf6bed5dfdebe27ba9d9a711770b90bd05c92f60b282bcf26839ad4c27bd3525e4b92c96a0c997e56325359716fde3ffbef66b2a72532a9da08111885b100dbffffff0fc930e455fce90f42686de7725ee32e43daff040aad5a13f39fbddd9a0a063737106f0f59d50cd81e5ea0ea4f7f130eecc2d4b23f82b26cbcb7cb39e7702e4979641cebbac111f34b4a08b4527a8261a309c8f784b2a5e311a2391d64e32187de902e9b25ce6eaec054c0187caabca2768c9e38820168209c0cd4655d82401494237985c2e919dcc12f5c31c899538fd952e84cff40799e890636164a9070841365b334f88835f88e15762aa84d67f5681fdbf7de7befbe378d7fed9fd6a240989ad50a413148d231a312d5b13cf5d2cf8ad6c91d14284629c65a740c35f7dba623debbbfbd7db98c5c4f5c463bb7bf7a1738e77c984bd26eecedb23e2845c8da4e200250ce93140ad8a7e5418fd30ad58e0e27e551c300f67f9d8d2babe930164242f20467e79ce5dc55412079489d5645814d842051c1f6a1f6f8ffb7800bd8f610feb3a76e1e6c74390dd2639f246c34c3aac8aeb498c0ac4a20c67811779ad8f2fc525beabfdd663f147e2c356bb543a141b121ce27311b8d11fdbf9b680a2169e8ff5900a48a3d38064f2866507fd2df73ce69ebf2ffff7fffb0a0b478624a4c513da94e2021fd4a68c25141a4988bc4b16759126786d107378c3f48a872e9f9c8eae9ac99570f9dba5d15c7b4a6e4dec7a6ee7003fc1ef7c57ab71d7e435c2eda37e76dca82fdff2345dbfeeeedd3e2f3b2d98a4fd2cc4994a25496b3a34b0ceac493b3c771822e02e007574f0eb2c81aca6292e907a3d2b712a5b4d4d59452b38f4df10d849b102e4e333c9bab119aa88f45f7de9bc6b996a4d00f34511d49ce2906a05a624f9cceafded19310f13028edad112dee8e279efa0a2277b7f66586900d160b53530ffdbb5ac4da80ca0b221ba20bb82a262e2964a043048fb9c38a11a485467ad111975b528ce39c0d8cbca85431794d41c201c31800040001003110c6c1408fd35c3b1400030bb474bc70382c284430241c0a85816000300c1202024130000c0603c3c260283c149655f2f201c8c38e10313010752dfbdc08ae25764370085f4c91742149d5635a4c3b274d5222c790192e44ce2b451e34796564b6ff3432d26c1810b506ef095dfa8d1286f21eea36136d1b8ceeed8e481657bf018cf14e9307f40d612aa1fc663f4855cceebfa0e8686f5a5de955e10b538a90f55079375ec18028dcd95799ecc318e75d13f797a283f6b41168227f2f52e7cf2600276ec03a4e9b1c87a98ffa83b2ae03539fdea23e87044f422df9e79b8af654053910a7e4be979c1dfaf6d2cca350d394ee28add9372cc78a73ca149d1b4982b7725a0a766c682663d6444099a43fcecdd25c441c065939cdc34301e9a9ada4aaeaadc6b6f786a24bed4d1232189371499214ef400783c55d9870edc6bafb233c0177c1c4e7db2e112e3346b2173b05a4096af06f14a8a4c4f3c61609bdd349f94fa998b7e1303bca8326f67fa839ce037aac01c0d3e081aa869a07dd68b4c900a009e1d90b9b97e7a0fe6e0f7a5137b70a057c77a76b511f9c5374f83af399c0d871d44f1e8c7bf02674d5133d4b91e7c11c76ebee229833a296f8c8d6030ff104035d00bc8fb4cb3f8088de725a74f4c6e39992f36638134446b9dc73651604eabc393b1d48615dceb767ea12c6ca68eddaca3adc7c16dfc591b300fa6820513898543f336970ce16e756b628c270759b1eb9fadea75aee78e33be6bfcea6227aa7ef719628b53ca038d9d61ea529b0f3dc34aaa3ea8ea8cdb1bd626cb6aa343b908495bdda45536a39c8a8237c4ce007a81c93bb609ea08633f8383a11a90c4aeb31082552d21ca7ad121414efae02e661d12f1da851565faed8a232a02fb3c9acf85b70632af0a2486ab4d5bf01b0881a23f2b94f70d764698fad0f1d097206b1815fe3ba3f8c188c2b6412d4e22e4a38282851147999a39ed1e34c85a53f5a80bd9c758cacc7ee50cf79acefe0841978ad1eac4861ae6bc11755045098d52314f67fd002bb113fa1987bcdaa25b95a010d65e400d4d862ea3f155d75b68caef1a889ee5025a587a5a2cbe7c20232d61d2f1b68703a901a23b600597a4194c24a52b2c0a72daf3ec0252e830e99f086e828b19e77d18a5cb7f4d8e1efb029a2b8bdde6c651cf274370ea7ca59149f7dd261706e52935612231477a988f33447606147c53b4e08e3641be4cc0c535562fe4d3a6e18ff85b029c4751f5883caa67f582eb037ce9a1a951f59d903e580c4094073dbbe377a0f2f7058587a5cdff5bcf989f4380210dd26388b32b27fc4ae70e92d511a982a200be7ef6858753b62723c57325acca13ccb0ecd4fab302402f615e01261ca6eb7a45fac9ab5b3d4c8bb209effec56d62c65a721c6340ebf448dad09ea6b02e924dff7b64a775b0600ec77b5ad6cf652c609528ffb23ac04aa4466e2bb33b06825d03923fa2c115a8a0831df50b26d8bf3738fe6ef09da5097729008b91f81bbd1f45df7ce9ee106941c873e4369306b7c4c96ae4cc067ae5d0ad7a2bc8e93e05445fcec231f54fde7246a4ba20ced996931919f26981584626320e708f5c7584f9fb8ea33a9b2053465ea1a788388db989e377b2ea14b7c98d01689f9f4743f080e535728b4352a1635cf73e50ebda5378611416e4dddb9d0f1140b5810cfe6bdd282d36f09936ab2b7f771e0957ec0967cced4da44426309f1b716693b013ddbfc9109782466b848845ce4851eedc17a2b225fe56a97867a72f51f312f74174da9f46ec0ee5c8efba3efc5679ebd9607aed14c3f5702b618da4b2e3c512a78da4c338c904b92fc1c813042dec33b8d062411d01859c91e5864b86e2ca50c98f229405046d3ec8ae477727ea8d6cf9548f8c82eb372d39da5d0450cbc2af940dce3ff0e646770e0b499384926e2489deec8213983ad861a0f2daf8fa69912008980c73b967055a5a7a5e3b18ecd5b6a336a16ea34546a9dbc24fbe278aa8081c3cf02be8870600568f496696e7b934a62874d1595a20b250e8827ce40b089103190b29461a78879322988ff6e278d73f92629e0447ae50a523f10997614267d4c8e1940a29c04012478acf64574348bf430e805473a608ddf88ba9ee6a102371a5869cc681af7102fb3c033a148fa38a1422ba82b74a81416fdd8495c3d8dcbdea77b519098d566b94fbd3ef04786241f4c4c73ad67e26deff63b284db54193c851bb5025df010085a0596c503d4bf846875dada6c9c9101a1141627cf318565cf8cd438ee7097f29559b5b677ba7189aa5b665e62edeab7b147ef02a05c3a58ef85d097431c3123692535972ee6d44f14162b4d99e9da40265303843009e609532d4840f038301a990c6c051ad38b30bf449db03489d7e5b2761c600e1cad919476a2428056574ad4a039756a324f1eea34f8fa9aca252efe8e168a2d97e6b22232261d176b8fd1cf2f9af0bac91703b0fd27be333cb9beb873acd4f591db1c22f663e5b84a926ab52764981920dd20b66e83e80d5b551a2dc1d25dc8ad0058ba28528cbe2fce1897b68696d649880c97550cecab41e2289901b9a7020c46980562cfb036537a080caf7663560a5697f70d472bc07a5572df45ef3d3f24f307422a6fc2a6513e1d5499c31bb4021398a99f496d9c40ec860013bf2928d5bfefabe6b3edad21f75d2dc15a9ce83de73ca40150ebee66d8f40e2604f75e279058dd94447a4f552750276fb4d1578ee5f64eae8ce1464da0084bf35bd5216c3560249a621bc0bfc95f663971bc17e44e22c7106750d1175592f5503ef4276a11dbf5b546cc1250839413ef94887c2a39ac37f0082e6e83bf46f13b83147d0a694c9a6d7743e50d7b9800c05222854f46bdcb8e30ade958f7f0988acd9211411e0707d5e3dc088583edd10aac88d56eeaaf077183a4767bb8e478483871e6654191bd4e8534642b331445829110f3d61c40a721bcbd67db78dba0782f2d5c69b41998e76994c405c0315383cf5fe4295cd099427cf92eae12e04e58901e8b21d72886c7113d3cd46613ef68cdb3c53e567ad7c219c3611c7646f799681b8604172960de93b152d2debffcf0686bdf6cf907cfcb32e3e48dd10f900f1eeea96ef41095b044042fd05bfd170abe39010619a4b75ab075ece5b339dd394f01c15cc02e2fd0997196036e1c24998c10b7aa50702c913bac978082e54b7448379ec605ba856d6db69f8785a184d4db18d0262d197022e47e8dc3506d09035b37145f85238c1231593dc64faecc0e417465cc358708990d9144cf140325e5dd4e32d93c7b2b285d0300bcb16efdd87f7ca1acb37d0e514986fddfa6e2f7c0061a4ad705b1f4d4a71fb54fdda932a236940a643933ded760126fd43a469b04e973eb5a4983ae02096a8ced6b4c624950f3e4a3908306083e2fff1a7678bd3090d0d8420cc2cb9f23b6536699cf876252c2eb7aa480d3d90b878d6f41bd2e762b8d08332f72aac01cbac89e3305ef58a25db0361d0eedc75ca4b1bfd7851f7ae2903281d2c21f6f1478f5e18bcebb8469808bedcb6b0ab6b1d9220694b7aaea355857c654e9fc1ece982d4e4dfe37534143fddcb2f19545d447222f0eb9b1e11215052fbbd5a152d485dcc0c5024a265f9164b4744f0d7b4c27ad53bd2fdd063224836bc3834a658cf52d73131b53ae27908e60caa8ffc7b2e0e4c4d2fc70f380151ac469d547a226c5769a9a3fa349dcdc32b5da1e56ead0c5a0e439b7622473f13e64d6aeb78cc6d1185e558266b7acb6099a6d44f3ade47105e9b66db345fbe2dda1512247ce56aec3a64a6a124c0f928c2300024c5f1448fca9cd95e1d804d71606321cfbd2fe08be392c9e51c79ddc65d7e90ca268dbb95c274c2211805e3708d26a192000351de8bf59bca88ca644a5a186ebb4bc032c2821e73005a47ecc345ed60c4a08e790c4424d257227c769ee8bdf290f6e40922c2d183655590e9221db3a603d78dabe500604041fc122c759cfba846961b5e119958b2dd7d033085442bd3dad50d2c0d5ad2c77c4d3bb89c444be23c34c8f0689d74f860891e09ede1645a21ad3440de7926d872c10fc3580a8e02091db5ccab43b18430f69b2f15901e772fa09991525f7e0c27cc83826f2cccfd84997e2d9e57137f07f9c4e6b3ddf97ca8ba6f57061d87c68f9a0fd874382783108d1c1117ebd58d0d0c312a2628dce562ae7a5567c9af58228c2010f49238d03452a5ff87c33db1dd74ed9d3cc663cfc72b6f1672f1117a0e54da46c91e31db3faf0ce6929b2dc76fb5e992c18c4355463e2686a39f96a5ad89df9a096f9862ae561341f8d1b15beeb3e5d1306024d408fba13b1a7154682dfd7e2617d3cd352b0769045d3df2e4ec5d772c02ccd98ea83b5ee169f2185dc4de3523db47d5d44fa96cdf9cc8bacacdbc432a1fb065266324477cd6c2a61daed1d4d3591ba88d63dc11ec07e0b8157fc93d4a03aa71116ccda0281244cd5552936bcbaa45aaf16da65f6464de12663ca128cf78e46914bfdf357c0d4d33f2bbef967363c69b7e95d723ba0eceb38286d8a1fab0fa8c54453cfaa33101fc19a9dc81976f8cd76097944cf88815ce1d4764b7c9ed58252b41382a2ef55f97b0f8ea14305c8bf7d54700865740bcbdf2e992014ea4659b11580ba0a6349146720b1099429175ce6ddcf728cd1361a405e58a9b1e4bd34afe3a54db6fb205899d525b24a93aee852570b416114164b05d44714457894ba6c3fbec10ccd1e1185cdc5bf639c3ae7709af57dcd947cf7721d6eee3efb5a95429110a25655f5c2eb997548cca39c4ffbec1cf921e6d6f813ba49718233c113e03205de3f8dc5317557f5cc72364f5c7488aeb0ca411ae3384001b4611f9fd0102436899d573048b169770badecdea71a2303590db4145af027e077d132497af7b8748ac7f9a4160c4fddbfc97dc3760a14c31fa44a3d537b27073a5c542897f2e74d230e3419b21ec0c16386e7c1e7b71996c0afe4843303d31bf67073a4b72a3287ab46c1888ba4a6327467b2da9a4bc02c03d47ac1006b99e15b01658df5cb0313fadc9d6c96a60cb8879d25b44a13fd9245d348ed20ae8e981657f7314f9a21dc7acecfecea63525aa37b86b40ddb5cdda5a7754917c10785fcab5bc1b792ce75533f1b521b9c4106c6b1a2c3190f9308615d33b10c7bc2843cd21c069d0d9b23e68d37ea5cc607b025dd235ac21824f2637fea87367b954fbb76a7a63eda055116b70ed279304e846da0d58a08d6d03764d4354ee3b4610433e6051bd27147c004841814b866c3a6ad0bdf2e8115483f329d4da411398343bd0e9d31d847b1e857501de40526cb8eb5338b62984e1917a464470f2643f0403911e58876b1377833af5757df83c895b197e0124a231b914bf268e0ec61e03030cfa1253c371b7dda36eccc4f62a9b2ae759ef62dc78924426e61ad01ede640075c43c826a234607a64b4b9794ad4b432455f24f775f382ae60a89613088a4f4db4e4ae10e8129a1981b04575e9163a76d3f44b3c3cc67f4cba3e4db8d004443d3c8e88f478ef05b313d20f86c8d0ddce8a1d86c7e6b00854c9b3fe16d2edeaab95d5adc47afe0a0a7e6d58f6d3cf851bdaa8d411e5ced8ac574a8fe95384f550544b86a0c1259ff456fb63d56836d85f2738259035dfb0738413bb46a888283d8117ab32e84ab437a81ba8ab75dc9a3e2430ef7a7ddb98cb9b639d34403c90896da7c92abd173199799160566bd84acc4603f1626bca8c971758f7d02f1ac8878eda34a4366cebd11924820ca23a2d14338009b2140fd19f416b9bcc8b308061551e993651ee90819917f7fc98ba4f9a1218402255322406a32f156d53d5270d868542e52bfb1dad29ff750b1e9a911a5719e58c85510ac42d270159fbd5f425738975ad8a62c88c3a62cddacf32970b6eb19d6345c8c1f2161d2e49e779de3ae7db2878faca9c19688a2b4ed1a1ddec6f3793c08cc3f6d77e9369e140f5b4581136b3a5104e3b8d9fd38a7007c70a92998fa55ed00229c28b7024e556cb0a6bc51b8695a4329c3bb2d59752cfc341e2becaa09d1f91b94b784b340d419e4cb893030a763a24e009629c809c2d89621c2bbf760cb41e027924e4a97dbe68137262d824cb2f8c27d040f1df0f8b9572ce19c97453be39285b0411159429ce92466a3b9a1bb32e6de0b1ae4f0eefc0c75809dc3be818b345a18a1fc03b88de32a715ce57290aadc00a4fdf7b20a1282e2c403003a7bd01720cf4473014a1aa108497385a4d722a302314d17f7fad05c7cee17168d8b3571910a6182c9a0fd80cfd5f4579e518b0661053a2cc5b53892f844e343fcf19b99978005d6cd3e002987e34163610b5e22fa462e23f235f9d7050e030933a44fceac299a59fc32a48211bc91467b77f1037f83982a1ef42ae0048007a68340ff34c320d8ed89574d33e348557808a5f229eb2b71ad6033491eee35b764966353f039fb434cc6ef3072fa6f5921678656ad83ce4dce0c291512c6be0aa445263aecd781d89ac8f970b3ff0d78967c41f7a9c39c42068248488ce5111bc3d920e3da435f44066c06c917b7e862e596429d12ea28950074ecd2804102b81adb8b4ec2b931d1c4d1808236f21b6b16918f80ec4bd386b5497ce495fd447870b684c5835ac93af3a7cf5bb4f2346e9162670448fca58658d7d80c159f70d73b0c139fa619bc9ed38a194f012f30a554520c335730de9a415ada6d350c5bee050d560431e33a84b9098236e9054112637ea4ae08b229aeab55a19fb3ff8e207123c80a71e7a6f7e699c45181c1e203ff77c7b7b57e344c748d0ad33e9dcd7c1743e40fe867e252bee286def1756df3e12e26aee29a1d6740c009ea99c3709f00587f401e67425162da57b2e2b2f7a8864c7f29913192301226a6febc7a8ffa223f8aa150b233f4fd4fcaf451f965014a5421feba92128395606106532910d3d1db729aa57175b2339aef5466dfc618e1f24c23da38e713380ea4c4080c2d97bfb8aba8fae1684df51544d78c87031e604aa8bc87fd45793e7695a8d318014b278c6fd5156609601f64415cd2b820ed79340eae54d535b4231073e616e116380d185281f3c3466151a51b450360965ad8638beefbce41913bb2a89e91738179cf3295379933a73c19b2f99e4e806236481bb69ab1579d5374a12186b627b4ac60b9b21fc542af84c4bbee7f4bd011637c2acf39a46841f0bf35265f64552cb132d21ba302f2a3057c8fef1233dc189282f309c7bd2f8fde49b53171796b9c5e817ad278d3603dec388ea8b56a5deb466eab7057c9615244032986f10c53a224d23bd7b721fe857eabda0e817fe48ff6390e5e341175cc8d959f93ecd3063f42689c89efe88cc2d1a4603426839b201fdaa107392f8082e87f7ef9a37a333983cd7be9c0212727e32e12bd130f395a92482f096fb1317b5dd31c0ac54416c5e9f3fbab617d0ccfdf24f225f206c153ed393f9f6887f518e7eba40e3f48b33748f0b0816f5535655aea989bdc722d3466525ac88b8812207ec99f68cb42becfd9372b67c176390a8dde026d2f7a7224ae995e546a3651453e2e0ba2e2aaa8d515fe5d9ff33d2497ea46e85c0f954ec459b050870c6e6f9055913232227e78951ce650204c1b8d5984e2521e6e8a79b120a980b535717beceb15fe20306c5e6aae09515aaa5870bd424811a0e7b87d33e95c23706f212be8b1e0dfa37d1bcf0297a09458e2e0408cc5db3829cd6a61b8737f1b47b900e7dc1f349bf63eea12cbd177c50a793abdf0081660b26275c484399e27884e7b8e464c26772f146f9893084520cf332a936d143aedce43577a8532237f295d424a62371aeb1f59abffc012927519cb7a30d132d62f30a178b6e7b41521d62fc0643f8535955d012e7739babd2f5ae9f089b8e38a5c0649c322d5e117865750f36a379820a3a18cfe122b3ff6d9eaa81311f03ec6ceb6efdf46c86324d965e8a50e18bb30e2ef5c84306c1a30cb1ddc3240604b5802c1b996584d0f266c03e1644aa3c6e78938d992bc1f5884e45b488bf93499cd8162db4d68709425858098210edf79ff8d11f958233c18d2ebaeb42da525683965cd3c48e8a3f80b0146466dc581df6c1b6b8a48f68836f04725bdc4e3d67620c72a5c3920007d712b94684b91362668e99a74e7321c457d5c94f6f040f0f111d7a6de974d52e3fac392d34bbae9306f29ac382916ecf1dcca171e33bf9e06bb58d6a57013cfb47bbe9f05e3121f0612479e980049cef865e0ce5c93f1d969f57a6c372781d4fb7eb93264f1a8c1ffc9b408530ee9e06b898c463d043ba8cef57c950e16346149b33614a5e664cc444d5ddb80cadbf5f392d3692fa923ac3b328ac7842823a2349e6bc43a965dfe9820cd3896e9c5a777231a8cb0f15cc90d84e7885ba34214a36a941eed34122bb5a9ce8e08084eec99630839a9359d72b757cc807d0f143918df14d1aad1eabe5d46c3a10746bced1a35c89e8edde5164fa2269876e307deaf00f4c264a6f2aef99fd034601b242f47b1654689e0265bcb406343b1830cae34a5b0a6846e1b2bc142eacf82c10edd12d176158eab6d1ffabea19fec10652f0747ac676d63966d69c22245684ad1a5e92d24c149cd8eb4c1e65cb54c012453be4a806bb49c82e4128d08083631a7b5df70548a9c5b5c3e52136ac2a8297ba2a5ec0f0bbe19d00c5da1c047306850bba85504a603f2047f788b8533be99c8375e86fe298e6f60aa24808f48228c5da161d95b0f6924b9d5f21272f6f9b9e236a8ad5fe7a0e34d30e3b93d81f4054b64077af1603b8655b20ab5d2b7c90ba2d7d8cfa4265cb4c4748cf5341b403d3c452b68b10cae3bde8b97ab9a6e46ffeba6362048ac7373f45cf024c5d015d62d71ccab6eef06946819590da2b49be5e22265300c0c41e28cd078bb05be4350ddd128d2028f21c3832c624680f547d980690ed45535d6260a227a33c896cb30cb2b9e986abaa301551ad570ee1ce51259deaa12a5a1454b1bcb638b6c9b14e527aca7938c123281d2b35eeb81fba70f778656230ab203d7f420a54d99af848be2a37f4305a70d16183749e1bdd5fc03117ae51d6aa90c2cdb93338430106e07dc5026eedf7e48b8cd500774ec3df090d4cb5ea29d9197f3ab3570673592ebd13e8c8b94b64519806502c778f4f08d9960c137d9023b80ca3191e52e7a9c10cf8a76a1241d4f1dcca1779a7d98a8095723c06a202dc663551f3d1250385718f8c06d818267e979bbcbd7086672c081840a3ce6d0e0ea5fe0bb64ff36df2a966324ddfbef9fa817cb08981ae47071893ef6254bf5291bc9771322b52924b92f49bf09d72fa8b36c53f0fca7690dd41b281cca1801e8e2e2b7290a3435de797266a4bc223722c6a64ef16c1250d43e3d5cc5cd037792f41248888073e5ade7a6266f446deb336426cb22ea57a9d6e61ca1b3d0f377d65a023afd9fe4d446e3366c26ca2cec1e429183e43263d94c70cee9a57ef0579c427a6a6a5c1572c909d389468cf52b5863809d6bbd91a4f035bc70850df3313e8bf5a603117e79a91dc84bc281f2707575c33242073b2927082da9483687705d2256467917a23c3d108119f7d91c1d05ce34aac3d56b44c2191ab1d2974c541002cab8b95d5e300a4adb1c25930cb5a8f45028bc49d35cff99f7cbcd5f96509d551d3557c5b3ecba88aa2635e6bfaebb4e8a8a07c33a081ba140ad544a562eaea1b8d4adf71e545b1bfb0b714c60ae08d40942ff6eed0e35b32666bb6bbb7b4b29a594016a066f056f0543189de19386e8ead3c3fff061bf8a56c6d1307c335dc574e53dfc325d79b729990ee5173ac2f0b612f9f9aa8f0a1541413e6a06401a6058b431ce018257e4e7cecec9314e5575d1c6374aabe8e1f8ab7efd5a92bfd6ca5f75cc5f77ee5fa19baee16f186a71895a8c1b519cae61b882e905547410ecdfcf2a7a7e8b91ecce822572c80109461235094c86041104a949052d3056228f0eae69210b9730bd2845e82a100441106cb23536e9e260052a6a3883979e4caebdf7c661eb28292f66ccd7de7b1b95e2de7b6f5063ade08185836b87c40e22bcec29d8cf2a86234ba640e001301a07bb0b8d76a00e5fb6f0a0848519b69c5c89d2aad2e1684a14256e3077db460a04410c46295412451d3246edc2700cb2830fc66b129b4a10044150d44bf0d092e58b1a1b92b8a25b4f1e378a680d8182e2a4c7bca05bccb01b2b38014eed25bac80802791a6f1293687be42e47d9ec86979a357785a7252e748559b2821110566c0fbd215aa03202ad294234150ec2b6441719b1016c00810540f60d5c610fd7ed8a20f3c055f6c84a19abc65f4a4c7df9011b311698346350a821882c4750804a91a72b4b8c41f2d35e6edc68311fe6100029646ed60bdc7b6fdd13ad52bc223366479223627ed0ad67c7c15cd2f797db0a1a20309cf0054c939e8a592670dc3f2b4e46a55985fb403d85a5012b214a538668ca9143cc2e1413e57644126874984a81cc152474181e3b9e5e31fc9cb842ac03c7b2be352f500d972c141af3b803611886be8cb3a2b62f35e48d1e6aa91a92d7103c3a1177e1de6405458cd0a1b2467bc770ace4bd63d848eb1d0892e3de7b37f98d239326d04cdf5c361a282e78391364aa0a1407dce064cd0790ae108143b7b518f9fad660f6de3bd4927b2199853528a20826241e8630610709206559eab243882630543aa8bf38914d78390cc3102be36c18cb380da87d7a8ad62d0c6378ca1e9172c145a28cedbdb7a82b22872952be5f5593dd0b57447046091f5d6bb4175549990f04d10312321811c4088f2c245a58424735e51f1ab780a129f37863ecca0a1dc44f4f9a6bdc2f942709643e1046045c4b3878baf55c9365c81516988460044a1dd45dee14a62934cd85eba62ce28bc7de69067492f96e17242c6411522a7b81f2cadabd7a4ca054ce342f0cc330fc91f1b6f5f61e633a4030bcc0c80f9a2cf2d4a2c88e6f323d8492cfa400c32ec9499424312756e04109263fa2a67a3aed3322a5b7c872de911b06f245d513d528ddbc46496b659c1597c2292e1e6a31797b8349a20ead163ab87a612d4b8f4fe78f9771560cc3f1856b43f0826ec21425291c61492310a58b34a2c95a64e6618b872e9e264b0cd31cc1554e2da100ca6f64525382c8096160c861f505073321d071a647970a4f6b90f8788cbe1f39da675b484929b5c0f31185458d0f49425f18ae1ba133459272f0c014d1a2b5ecbd411004b5440d822008a2e1524568d93d7cda46019bf4302cc3100435d20c41a47004192351c618d9b223a74c00099613902053266ba7d35972786ae51d035243c8430e3315961c5a38a20b07943544ca1d8a04f85872c488334754dda0b104e90da9d25a86588120d78f2c345a53ca4c71f2a1e8052c2c44a6f8807503920f48121dd45047f4e6e2a14046f9e55ad32b8f4f3a66957298a4a7dc78d2044a0b2c7ce006176658424306c7cf8abe627b54f84b98499fce09403aa686c03790e0de6b07a972160382ff546c19d9610744105844e8d613cb6f07de1019a8bab8a0add478992656001b9a4ee01f4f4f509bc9123aaed2d512b59a5f0a637c6052050a1325616e41bf291f63968af448a3ab80b0bdf7de184a5794230e468c9505788259c022f8856118e223252f26666259fa8aa755d830b30503913057698a82d860e30a88941417315b5c1842f78eec64f1b8554ce3b88414a882110882208879380c4b1fc8b0078fe98bd20850b8a2001dac54f8712de1a307ad4160058220a885276a1004d1685e19be94c6d88ed9dedbcc4be0271528e1c3c80f205e70d848a2a1ecb80cb1e28509979f09da862a4accc090b42d52bebc4cd37af1d8bd337ab6f7de31bcc300972e5e64f8d2c5c9d63ee28424a682a870c4a56b70a19c0a9f5400731ef7d641b6d8c194551582577eec10e2c8de7bb310415529ee0c720982044791a1965f20088220086a208496a8a77a0451c18732589c10918608a95711131aba44216395c40b5134153461cfd44936031b4c369a4a281b494c9005961c430241264926b013bb140bc3300c4391dc1f0fc3e6636f7b5137bf446d37d3dbedc5ec610fe3e68f6ecc1ef6376e3ef6457d085f73c5edc5ec691f6396decc9fbdd5d1d25b19e326bd99b38f21fb595a43098cd9f3af417bd9c7e07ff337698dd9f35b99de5ec8bef630645f4b8994944f94c2e05ffb5a4a347bfe453a6bba38a2a5444a60d07ef6444a56a7d937c0ea6a9430fb595a420dfeb5a7a536e36aa9c518844f7b400eb459fa198771b6fa61c948274b9962b06b6a70fff53230d0838f571a3a68f501614c2d5685d0b8220a02f8fb43f41a61d5ee74081b75fbab4f8977103a3dd4ba2c6bb5f3d4d1419283c5f197f6df5e70830f3fcff05967f8f430dd00abf933b0d1c1ef87bf5a2827a4d7c51e84f051a758fa01c6e5c7b2fbabed1ac3bfbbad3b8ef789704ec7e8084969095f214d449e923c19c34b63847bef15bb08a632b09a878af0d5764901119558cd6106f7febd415835d153cdb8fce4cbc7c5101cf742bc87c836e75cb6e6ded74675fd1f6020fdf76f2fcc877d0cf361690cd807655c7ef1d7f15de41cecf393af5b49ae36eb5596af1f01e77276d7e828ff4dba4a4c42663dff25b2cb5f92af19f943c8266a75b0d7eb757b7dec958a503ef9b02fd211613597280cf361a999bed55da48ccbbf7233bd4618838c4b477885e003a7f14a6758ae9eff078ae70fcab9e7437944575bd5cfbe065dc0467dce61ca6f7e61b008143dd4654d67475551a000f1fd9d19e3f2aafacc1e06ff21ecd3f7d36ebe4857ab3ded61d49ef6e0d35222253729d1cdd7be4847cad01bf8e717e966e80d4c6f2f666ff330666ff3e0dba4444ac01486eccf9408e7654f74f3b30d3090f8f957b183e0cd7fcee13cf836f4b4416dc69919971f4cd7193e5d4437a87571f1570bc542446fe07fc6e52fd2dda037301501c6cde388d000ab3b332e3f0662df00abb3799c9488e826b51957a40b21e7f2ed7abed59de967dc7eabc3f97c93de5ce0fc2d9636c0ea70529b715777f3b7185777f3577793fae86c529b8b7436e3322e96bad89fcd94a7af743dfb88ae337c5a60a01d8a35d4ea64a8d5658081c49ebfc50662bf66087e888a3dcff051800d9231489c786a336e27bf8a4c1c6691637fcd5e9491bfaadd661cf936a89b335486dacc519b7131d466b20481560d8265edfc1d143e3f412a3200b50833cb27ad09fe45cb74f52167f8a062a8b16a49acc904fdfc0405815b3f287c7c2ef033e3e76eeddcabb377768af6bd3440c57efd51d16f0f67a12c1488310c5bbe306db9b2ebd9cbaee72fc9d85ebf636b73e4dbd102b5c057f1f3ab28c8cf7fbe4ad3444b7e57b1e7be8383bfeadb8bf15f0f8131b519f74a6f1602e0df6cea82fcd75b5d16332eff0b1d519e27dca61f6035ff4f12b75a46073f3fbf804f07c13e8dad5aab05625d45ec4b9d739b7fc4d22d8a73c705c6597bf3ab68f32bef64edc9dbe33c794b31758155fc26a238ff272489fff51ae7b8b5391312fcca4ffc7a926fff046a2d4e02d45a9c09d45a1cbec2bfece30add1576a9db9c048f9fc6083867e2f1bbc040af9f79808164287227cc1426416a310ef6e69316c57913288ed729b94f92b7c4419770fe44d7a27e9a2b3070d7749ddb75d25b0bdb759e85ed3aa9ce17757b4357dd6f3ae86a1fe7495c5ed496f343b8a8df50fccb4169ec6e4bb38fdb83f343f94435565f6fcd1538784693fd4dba8a36e9ca6b696971e1c76ab10f9f866aab863f43ad55c397a1d6f218baa230add4bad3572b25551b8bf8a040a1aa3e3ebb68e3fbcb6279f2a7fd1ad4ad6cf6365d6980249659fc37984539566fb05403dc611be09c8e110c0e70ee28ef9c749c3b227b5352be74fc3330d0ed38cc93a78e9f06069a75fc2360203b450354c74f748f70eeeaf0c32e900de3a4d7f1b7c0403a878e9fbc34d4ea66a8d5d150fb3334841e7bd29ab0bf682c85a10f20c3df45b73f9403f9b9b53d617e32e685671ba222dcbed6785f6b442c7807d39ae5d127d6c138fd361f5fad0f0556efb7c8392b9a1a800e80e2f7f5e7232ba92f18f85834a5cda956b440e1076ace89f9832bb4737bb4d9cdbeaaa2b65739575a1cf8fa77c0d7e0af36e0af1cfcb58210edb100b0ea002c4ebfd66fd3b550d7fa02cc81e5d16f01317c0656f5ebff31bab219c3ee0f616d55f04354b42a985acb03be88bb969024a4ddc1e88a42147316dfe2551c57e4c0b7adeafbf78cb4f397fd7e0e722ee7f7cb981102069afd7e1a1848f6fb67a80ffa93837ec6ad3382b05a7b6b3240c46aed6f68e75ad46d1e9b2b6c9ebc369bed59d86efba23e43d7efb3e7e82aa3f3bf4157dd6ffe44d7dbcfb7a1b3f24471de9afc87f00ca5fd8916758e43fb1b74c5bf4efba16c836aaccebe86f2d4627596835a1dff187f187fb37ccb9ffc6bae90a5228ace533086c24cb44c575deeb4bc4636781f21ed0e693fc06a06f7d3d32502e22b64c60757c8de6248f6aec0adb518e6ab327dbd47492c6c016cf0f5eeae80ec962c5e80721f7f28e3f29973aea281d521df902edf5d007cf0117ea4f01b0256a71b8cf15d94ef748311b35da739f348112d18292544c8c0030797138a9254999272640a4b9518194c2b942122041a2a231a48c3820fa91ea42875a919f783d58cd5dce3916cab2c841c42cedd2616975f4aaf62d4f3ddd273be523dc0f4ee2c0f0fbe5e21fa5bec219b651d1489ba32bdffee706efc5928290ca42d971cbcf55e652323777764366dd16243dea245a9af972a8368074e4f6807313ca11dc4900468fd1130d0aaf6bcfed0c040da4a87be969d4cacdfbb46eb67a1bbfe09c2b9dbcb7fad1002b278b13db623200b98dcf56b9bc3af635d254714e9eac6fc04ab99e8f23006f9c75ff998d6783dfef5ee5ebcd21b07d0bd1e7f89728c417e123d332eff8d22ddf844386a9030fe017445baf18732794d0d9c4818dfe99572a006fe1274d67431a6445717c5736e02a72d463e6c31418909ba6ce2aa4c921041b48c54d1e5d8d60b647a5cbaec78d2e5bfbc9cb3523d8c682284168edf0dbafc9f73f8653bee16c5f4c4322b6211e35e663448db8b616b099b5b1efdb12c5cdc32dbb3f9565cb73874fdab4fd7415ac8e6b4c5dd2b5dc474bda34318a64e35c617fffee6401c47510c6d587db151be272247463f2b2a3ca6a52d2da9a8244f484757bf1e15214c5c5b5452dd070599b597f0dfd48a5251499e34923ebafaf5a8642199896b8b4a6a9704276124ac2ba8de6dba42bab8aebdaba5eaf66357384e63b12bdca6a2b63c2a87e2fafe60d5e23a0a0ec5578ddfe254679d7586f95cd0661c6efcbae3544acc0ab74f62abf54d57229d73865d27527cf2354abe88ae3b5d7c91fffaa29871a2b54216b83df9d7db45317685cb52f1495d8a18c892312b5c7cf25e5c62f1498b6fce7a779dae44dd5a1e51e4c223aaf31e3e8933ce62f843b845ce8916b8423bb727f3743dbbe833531f59a23c7fe63b1763d85a42e7e90ccb130256f3ab39c3d2f534559d66dc6d52bc24d3b5ecfaad087744b3ca9b0278079f7750a73676419f4db15fc3bafe3577fb359ce319a785cadba351dc6d9ed269980a083bd79f5f7f50ce8529bf3dfac3cc7f4a4e00dba3df72cb85bafe1528c8f2e8c7c08a879f79ce05fde83f4ffed36fbfa8b5eaaafb15bab6e7fe0dca7fda206b79eefe6c2e60a74ef7afc941f8444a6e4a5a138698eebfe96a817e3f7c6caeb8223ae3ec1cd5a0d4198766487b85eedbc75728bffdd1e6c4b79f5ea1fd680afd362766dc057aac6a8bbb2a56f5c72ccf7d9c05ca56bde94a6377f06fb72a06c25debbeaa5ddf05807f43405eb3a6879fb7bd3d2188dadbb3df6a00824fd28b22e73a3a19d834365fd19577f285ec610f01feb1bf321997f1db0bdac33e86cdc79ecc6589de6e2f680f0b60288e2fb23461312e9bd16a363738a72de7a6634282138fa613ec505081052aee020000a0bc00f76477238407542abc1e6c53f65b00d533abceac0aa27c599aaeafefa7e0525da91f0d3c22eecebdbf222e4c70afeeefa7026f85fbebfbd39b75b17e37a0a077eb6a150182bf5d97cb8c9a13cd097c848dccfcbab0511292cf260523e125ac6466ca4644a9efd711c274028199883499b1020437257932b33b79787ab2f3d9a8e01da68279669cce1f30afefc7c150b86706c809b8d7f7dfe028ec33938367cbb1df864aca779ad95fb3aab2d9e2d9d84fbbfaf96c47fb675958fc8a770681d5f7cbb6b47c31ece7b80b73cda678b62afb6347465e4e218cfa7e5812928f05a4bedf5c52e25692f6974298684c6c20d2540b625bd2d4f7bf923cf11862fff864b78309b620bbbe5fa4c22b8b387de0f5fd2154cfc41ad2ebfbc1285f8dca86c3d7f76f2a292ce7d67e6d5505c5e6a3aaef7c957f659c4e2532cec2025226df9ccbf0b075206be5aecc55c604247c9d315d9cf50643717c91a5098b71d98c56b3b9c1396d39371d13129c78d4921694afb7c05ca15f446742508bd51d0a28303538328211c1d3d2464948b3335cfb2758529a9db1a2d4f7a742985e38f8ce1130f5fd2891a6170e365e53dfff499e64596c4e9e2ab040bd45d914f9f76b34e7468573395818e7c50ae59cb13dfbf7dfc0d8143921b03cfbb78faafe9fe72daa6f333fd9c5a2f0b0767d3fa6c2cb4fce1f0faa072ef19de9f5fd37ca072eb13df9fa7e4bfe092a29990ba711527dbf045655562c9c6b7455df6f425fe99f158f9dced2585626a880d5f7dfb6b442247a5a7d7f8eeed25c5c8d6d4973f5fdb62323b3cca966ff99843452d99890fa7e9c252572cb69a5d4f7df086102af3831f5fd36449a489e2d85a6bebf96e4693be19d4b3cf5fdb4273b1f0dbbbe7f46853722e1d994787dbf0caae73b77d8cfa37ce40b3df6c7a8a44c1f3c23a9be1f6655e543aaeafbcdab9fe6619be1d7f797595862b75b74c071a6c1eafbc92dad12099e8d8756dfffda5d9bcb7726b17f3c32e26a783f8cfa7e318a834958dd0f226175bfad0852df1f9266945050eafb4173cac7240353dfbfcd295e130c4d7dbff6f294e4a9efcf62baea20f9baded974ecc29ed39c9fe5d93f846d5df8aa63d4b78e11cef9c0748c62a4c0c96eb790a9a1ebcf688c14f8ee760b195ed7e99a4305e465dcfeb3070ef2fafe1c5e0e159cd3ba1ca8bed71c5ecfb1caa9a5ed664f66bb59120cf4fafdb3a7199119138d97735ab77b7d7f074e4f30d07a3b707a32f345f54d6575d56759b3ad59d75152df4b7dbf5d6942faa611e99b96a4ef19afef07d3581556f7c37eb02b9c83fd5e61bfbe1f86ce8460dccee98c09abfb6362f89af3033ffc75c6d4f79368ce0fe7b8119291916e15fb9af37ba15ab43c423fbe823d193a4af70c12a40736c5fbe0e3cdf1117d1f3c7711f4fbe0637f0e3cb029f4db97f1814d115ad04cb71f012ba46f4f7efba815715c002b01d42a5bbacdf5fc6479f25bfb15b040f788c5e60a8c8f8ae017e907095f6defde7bcf9cab313ef9f8f5e290e5c97f4d18e393298c575a028e02846e4c95ec74047d856ad89efc794dcfda6ae57c585551a74496e789c7087e93fc2ce1f9af5116c590856bcff165aa7e126c6e4c39b8272745135e3c47d7a9bdb8f5bc1db05dbabe226471fa49b038fd1d90ca6142d74f9ee8719bbeda2e0cdc7e6b58d53d28f0730058f86aab886c8adbb73559e05d5a736ff02fbaca58712f4a63770fae50064409580eae10f8fa29603370eed0f5776053ecd755f6878e25675384290656084cf9edd15f643960556dc3e2f408b7476b1d7d03f809f440060758ddbfdaaa206e7bb36b312cfc2d8677b77148b5c58683539bf56e7ef6341aed3ccff38b3a0e4e0dbdb9f913e706b599fd8d4d9a6db83db3afa12baeeab31fca34546395bf3557d87c6a78dfb04fc62e8bdcadbd1b639243f19cae258bddf5b518b616751d8b8de1f6495d5ef3ee2d8e24f4fc2437bec5a503a0f8888a4fee72a3bae7f0d7dc039230a8742cd8f5380d2ae5cc0c0000000103170000180c088582e1a0781ce5380ee40714800b5ca038604c208b0463a1600c08830201188402180081008601208e81000c63a9cac5071effcab56a5f71569aab549c4e260fb072adda57392bed6a79955ba1ae9e56d715d16abc82baf2afba566cabce6a6ba55ccdad5257a6d5e58ab012ad4259f95777396106a67d25bf0259fd7a657738e23dcf025b08a564bdc823bf36e0c1cde50c961e000fd7e9dc79518de94b8da08bbac7838a7a94b8fb745ea87f0a6c3a97625eb1f802b4e0240c27af54b846fa84cf7a5e1c2af2685c0912d5d27991879d028c13b8c5771179b94fd03599223d933e5ff4ce91c5c00dd2ac83fbffccf309b6c8141d29d81ba92d77a9efbfd00c8eba03fddfc487b5bc2cfb4a24371b310f89e91c2079df079475c2594c8ddd68e30907304c3fb852b42d80d1203a3669a53f7b82461ea3759ac3aed706681e8281d3286ccfe3b0ad2fffdb8ff84eb3f9e0ff712f448a3082d9e855951dd49d5b08b0cbc6c798fd53a1a8fd1079f93c0941302c08f35e25792909564151a46a357dc8f99c9aa0d7360829e9a93ab222418e74238b16400e7d8ff9af45a38221190ccfb66f1a31a41ab467a7bc21e19d3f0c9709c6b034527ba04233eaeb9b8405ba90bae58e17bd1f8abc4f49b6a81f2a9b9999a69fb9b27b3deb5e3efe8aa2b9a13d6b59e557d02bf3d56555bc12afa057fd56ae55dbaab3d2ae2eaf722b94d569655d11ae8a57d057ffd56bc5b6da596dae14ab833f85a58dafcae5f459635fcdaf0e1456eefd7329dfa00c5dbbf71b38be69d39cabd09c1c4a4bf7929293fb60042353e321fa7c0f0dd336dc9a326ba9d24522588d4ca9da1b640886a81b2171ff310f25d2d25004834345951eb4f25e69f6ba255bde884dab15f7d020d785088fafe73ed00bc2ae66428206e5ffdaa0d3760819dc7b1ecdd174fa2c231ce97214cf8cc992a76c36280f36522e5cad108548980ca3dfa1c9794637a12d8e1c90a7d470d40afd03d0c1843ebe0900efa9edc34b03109cbdd96d60f68f4ae06deef3aec3789eda9e8721e072611924db7b0659a19fb92b0c2b2221afc39c41b7f8cd16064b83da0c5ebdacaf1d0ff30d48af8ed92916ffb2c367ba26123b3e61acddc8f5d42cbe78548767e68996feb537ad5df1381f1653f8ed8a48fcf5798b833c2627b1f8cb0e11ff48af1f7591b3e1542a5411175290086b1430beeeffc2c24e33b146161795537256319b4009beffa47cd40a3bdb805a18754ff1cd212ce1dcb3fab793373738e1bfd011cecf9541150b5389bf0b0b4391014ab43068ae7752a26a36ee4e1d7d49f7d266ce2da3f71fdfe6585539ae1013dd85bbe6e1651c215739e7ff80f59683f2af23d353ae33e8f22c1fd4d0390034d9bd42df2338c1bec9732c54b919b3fb70ae4e4b9cd76d0b41b434dfc788f5c008474e4f23832ed93508ef00f30aa0384926fd8eb090174ec04afd3c0ba85e7c29f7851af9c55586314d3647c1c19db1beb5a4ccf517af5322fa7b3706f633ea4af471f620af8a439c63ea460bdab3b7d6bf2eb98504865b8fad9bedd5d7c56ebbc7bf5bbcd4986350afbdeb59104baa3e769c2125e545a498796f4620d70a6c356c3611435f68010e5fb4f0589ab1d09b5a30463333e7bae4e4767d534f60e5cfb5b89245872eca4a16ddd70890463511f2b248adb3aa4eafd6426fb45456822b1cca90a85d86e312aca594c4e91d1ba4b6a693970a19e7acf39b59f4ffa8bff2cc6a011d8b0662a810d0a80e3f2331f60596e5971dfe3e3ef8f0a9870c08455daeec508682a0b93897accdbf477516e34e0103b55cc08ab5711a2d697860196a3d6eb0e4b6344520c1f26ab45c2a024bf9730e0cd17ff604188587114609155874ad00ac7f617d1dc86d4fca199b33500633fe1ff862969b5ea8459d933dccc2427f70852c77aadaa6b47859f6b681dc80fa43fc61f015e68c3063dce1394a83a3076212dfdfc2850be0c19d2bcde998050943e832b7690a7d383ac70d465afab8061aca7e52ec9555784ee651dca67b87698b3063aa6d90ebe21a4786878896d1fe26ced244315a6eaad699e81327da47a0cb9b9e946d8a27c7702224dfb72887a3908ad705335d422a48aa7dcc3edacf418d2c7364072ee796b1c8ed8e0f436f1a8b0b120d70e0d6c8bf65d1855e52914973811cddb6d394d81fac4214defcfceab2c46949926283875b8a4fad8d1a701b3c92db0959e6dc503f36ef7fe0d3e22af5041acd45c19a01e6cf707105d60d050992d7e11105e1367e029ab6e939db4b4739bed56a537afb937e48914d12e74d12f573891500d6ab0088a943d1a371d5de0de042330925d68f6389a0795f9f19f40c814f58666de58d8f788c79c63fd5854fa0e34f7ffbd5a3b860865254262a184c1faea0c0d5b1d08e032b3736ba6642888f86c08e1a62b20914dfc976b61a8935d0175cb3a282675089937dbe92b27a97e55e635582ba9d13e08c5c310d4b34cfc9c1919c292d5f34ad0047ee221c7b0d1fb280e383c90224165213088e47d9c89edad370fe676faae88d3c6c27cc9cec61b3a26df0282dc60344119704df52c015a7e350d666d3dbcc860d96c77abc9e4c98657f92ed53eecc6b5b3ef582c809e1cc7b21ca6a10ed239dbcb334c1c4582681ea5932cc4b88490c02722e6e9415daca71ad6933b209838865801e6d5a95f22ac15098b09ebcee5dd5e9a6693a2864e207371fe6fb606ecad1942f24f53dea01761542c38aa8c392ea4d677a82a672134c720503d10288eab9fa4bfbe5763d3c66e175e04592d6c6a6151198a82f927e0e74a00e81724390219a2bbab8b12cac780a553c32b01880cc60b31f813c40e4bd027377c5234e834c265763e4a55d82c1dc7b48b9340a2db316be98d1e4be30f20d35cd0d2887a3e5ab7add8f9502b0c42ed9ef863ccdfc136c676c176e6847019aca5d2058701067241a15432398cf32e5412ecbac90211dba53ba1dfde52c403cceee1d3c06ec6182351e58226e113384276033f45843a79fab2672a9de09cf9f5b36c59d72a101858a2b9f61c3932f20a5b08c7355d67ef95fb9f2e40ae808096454f2935c010d00c4238ed766ec6f856492586f7ecefc7b9b36cd5f92ade17a6df4f71dec4b09427862168f1a3d674c05b2873bb227300de60269c3abe06bcd3b1258e6387c94cb859fa58fcdb8ad80667bfc0fdf04c60f500fb16cdee5e7080f9babd46d72a5bc2f44d4c84d05e06b6585e9be34d36dbfcc1c85996b14eef8a101e24d70a405c954742e65088da8e7fa32b0faaa598bfa4930ceb0c1438ee048d748f85eb0f44cfb6a1a92576e3c9868dc5ab8222f106a7fd90ac015f6d1c023bd1c27c13bf4c10abb48bcd1d37d72a6f43637cd9ac5297a23d1ce919ca5ac91e43bf438ae5f372c46b8448d3aea85bc279e94060d31c163a7ce244bb6bf58ae713184a06e91993721da51743906257b513d38073790e56ac2f31883221db6727ab8e20fb5bd54a7889f258669b7b6100bd33839a67dc629023230dcb98952fdb1978c2358021e52dc6c8c2b4560c4652f547364c1b2cd7f76077c16442cdccc916b45903726888a48dd5be867bb7ab81f2bb67d19435fb2371636c184b6cfc2f86d89e7b3e7bde1ede64a7d4d9514f981d47a68595073794b722082a0d1c3d765ee3e44f13fb6bf843d47a7a02464378a6f618b571856e2565452ea00cc97bdeb24a024b693c77053e5f032f03c6e3714765696dba62799ec84ce8d64ef9ef2ae2708eaedf89a7a598b4485262c2a39f8c84dd5bd6cc2aa9362d1937e1c9c89bba1a611e17aa38b8051b5b9c4392422b5da4b7ffa97c86e3452e552c015d5c8d17fe98cb9cdfc90f1dd823d42a736d8d4c9b77478c1c7ba80b8f0a4ac5e2ad4d87c1805617bdd03500f0f371c3a1a7d2147996f3e46a284d4d4b5571ea9776ca2a299a644a84324f1ce8726c4ad9aaf92e6dd98427a018da8c3935f6ab897ad8ff477ec1c7997b4bb854a44bd72b3cd02d9ad741266f78c65bc4bf94f9a298c9e1476392e21ee5a567cae21183a37ff05409c7291f0fd7da9f8a13df72b8c23025801e1a56e084a5c2e88e2c1a2cbf6c835b45f3f348f90ba155d749e3d6e765b552cfbc65214427102a92942e564992e2eda50fe4e467a86b8e298df853e1a9068d83d416c1b0cb4e73885cc44de21cf7a468280f5275239bceb64f7139df23d90b8d1b9d8228a06ebe4628b8a7cc8287f7988940aa1b53ec7c84ccfa668d1c638221fe266bd3a42eda546edd018884922f3ebce884fe29e965e2217b804ec861d152b692fbad91bc42cf1ce8b99ce210de946e84ef47f27a09595450dae4cb26c92f5c91793bf9cd472b295c92d4dbe9cccf26457932e4d42970ed5bb0d56ae00fda9b8dd1546795983575ca76a878a1560e93a9664dc85fbd10619ab73b73735651793ad08d95a4c763d79892dfbd2a40b932d4d4e0265bf98e4e5e42356160b6a526e4d88700b78b9da62dddbe919e29c883b2a1ff8267339fd79eca76c539a4f78934e7851cca74f3e66c7375f9f132e4ec56bb3b6ef7f668d438a1f143e650932f0410e679e367c763d392d4262a660dae65d7e30e1e597b248ef9113b985a994c82e3fb247570b6c11d93f08c71eb2abf264fbe73e52dec0b38eb660e162611c534c604653919466316eb49c41011465bb9beccc8435750f98bd173aab5b25d8b5722e8f6a765db3befca0f95b1d46142dc364c9a3be9cef7e2a66188039348074e240db7848f99039c7c8d03a48c03013fe8a4e6d783a4a2843a5d30466bd0941b3ea2a988cca78bbab40670c6e371e1e21643ac704801ae82217e66b08e8a0a0c7cf5dc84fbe859e2e71ab282ba6e8d2ca7cdd57ed08fd4e12b11f6c3c8ebf21d1479a1cc634638568b7c58bd09631025e508607f5840732962e1617ec2cc23dd7979f1b5797f8714cd2635ed856db8a1d22fc09ed25bc5b1ac38d416f0e2555244c1e8218937f389384b8ac5b4ffdc184a8d92c6659d41e98c9eac56c1d0fcede5b463d93c866994c69ba9bf7c1a711e85ea1790080cd254487144a3c7a0ce2cc8025b9dabe2f02f591416c322be9766def6255ff6a47d1cb40a617fd72a2c3be7e828e6a9f3c831d97ff907d4edd3debd7078d68d045cc48c8fb7116af8bd7152637b6100e4ad94f94fa83984048343d8aae9c6c151f4341b5dd8c8dbe3f7fc2c4e7c3ed2979a2d3da995b3a3f5bf6476b2b9edeaf6f8f333b95cfc608da32323927cea54a773114fda12d35c8f20d4749a7ac22b91771a197752d9155442e011b68e6ef5b20c80c9f88490b8ce2d024427b23fb25150ea0e7ab2a44f9a14bde9901d013cc58cc5df95cf759a7bca9d323bf622684d06a395d058190ab4e9b5be130c8d2376324bd529b10d5fac876ca396315d43697e880551127516762e46bc95e126b36366ce04ef0d5843b9cdfac8bd70b9e5ed7077df4352184e783881a7bc55162997657d2cbfe84b2585c40436f92fd378d2441c7385c7d5e3eb5072475bda8342f40a03b61c5d0f3333b010f8b68c5a660f0e1b49237d4374f6c4a62e9bcde10623b161130c111f5e59f6548c558b46d08a73154542fc2453edfc2cb2f69a031ee6f18781e43bbec31136cda157665b96e1c308a47e1356c4dcf204f0ea6cdf1c418cebb6cf70e9247c9d37f973442becfa35ff7bb4a1239df961f30dfe3cf85c77d521cce6265d2e13e0b43f51d727555a8f0e261f3d59e21d8995bb94660b5332bbc3486a217d31cfb99ade345460db2aa31da86377f58ff393fc479afccfc12de46ce1ebcdd2a35946cd6f7d370f7437864a71b8a30963998268cb96a1470046d7c7f57c86196ff6c9e2e6b8f8ff11d3ee0b699cbb5b975fc250d81d091e131d5467689c49a7ec88b054f13876a17a04455922516b278ee1c8c4bc6540f73959a82a434732cc0db81647ff90caa2e88e522746bb6461014d5f19e84f3be84958b990e1ea51534ee1f85f289633f5ce168d02e21b0017c0f7463d0b65500c50f675c81445b6ccb0639e88ce5d493a5cdbe71621a2df6245838bb66162f88cf4304fbf4753496d0ecb8b93ca92f8e6e837a14104ac7da1f4e2c57008a79095431f416d2c6ff0a72c918ecd8a8031a2468367a68f19a8fea12752879561caa666a0537693a6618de8beac3f50fb4cd0e8872651f987da8808ddacaea2be8e3892ae03fa6c26927a0ca8907a132c85e828d8208f4f0131e04c42c78750874d6960ff17ede62dc4b9f36004508fbcccb74ea7cd2222aac57e4c015a5ca327ce70fccf1304af971f61e031d2ba6027235b5a5632e632564859800a92cbbacfc34eb438c6c7036c11eb7291efa085b24cec60e845b4c8314924937c95585c6042aeea441bb47b8027a307ea38b3e360d80dac1f7b1176f4b8eb5005621bbbc4c1e334e2fd8abaa86bf6ed8b75dd4cb4ebc14347ab5a8409a34af9035d2a30df2022681e18b7d40f00b409caaee596f9cac3f670843d8ff95cce18b27b984ea2daa457316de510312d65329e38af1203dc017d7fa0d0437d371b296d083f868d46ce160255bf3d22aa50155bb2575ecb4bee4dcb7b1b95a054c086ca504a4b54e12262094aecae4040be5416dc84431b74ed2cd33b5a0ce09736211ab58ba4d691c7b64447e704635a641c25ba777863c0aa7f2b29f4807ba1ed235adc2bd009e430ee89f2173579be6ea2948f83be25ae11ccbad03cdf601dae3ff39a64e45b5a07e506d77426a00118457e13d335bd929e9248f79f31de538efbae4f73b80b0c62636cab992d9a2c71f67f7dedbc74fc37e0a0cd68735833c1073324983e45bf921a69b084fd492f48b725d3a35a6489b6738a8238a6eb82f952275966a24cf21a8885323fd9ab998331a21ecfc8ae546f4c425d2fb287c5009b6d27ad8a9a31790a999d2e1e67594a4260e172e5d9b29b94976135cab32176ae1f6970af6eab04597bf24315fbf965584463aae7fffe022cb76eb15d91eb60852e6d2122a63514c5db1e41b2e21a9f3c4d5945268891d2c71eab9b5d4024cb19352be4de4e5d2953a44a4116a78a3ab31e3ee6cc6c1b57b6d41fbd3eb931ac98f6cd6cc8279ef750f1ed17b30e55a1c22d173735152a3227de2dfceba296a0023fbfae8151c8889c7745c81ed63582c67c36c6a485b425d501df531c30d12c4dec50371e708fe4da9a24dec0434e47f21d0ede83c94e3e3928e37dd425eef3072b9120108b5cf2ed8178052332f44e2baecd607412658e4053a5afdbcc712b113590d619b7afb2b9cb5ed4d4df6b8dc9c117e2f6456dba99ad14ae3d341493ea5ca22d52af9dc4aead3b90375c02fafd27fcef3ecd183abc88bbd647d441b4d7aa4cac99c4e0c0a27fedffa10e572302c3b51ebedbf7e9ad01e6e099489e7b2cd057f729a44a3848e785ba07880cd3088383e03a87bd51f908207820e5e52bfa03ae2fa2e5b3eb5003c263fe891f3a0f630def46c59431f55ea59f2aa9c0520fbbb31a68980d94b56258cec9e0970d772792083303fca1b86a6d2bfb133633006fccf702492ac410fdc01d26614ae339c3ae3fe01aa4482e3bf95c6bf312acb5b52e888d9e2446971ebb8ac95b4815b7712ebb890a123c011edf22cc9c0ce4a83f50182ffaefd2315ce66ab3771a0a28e5c446778e939eb57ddb8cac909a32194489979fe9f8adcf178d03ba6ae9b50626ff44e4fe9ea3e324e0877d923d5320135bf60538a12ec30fe477d00985b2ec13a3ccd15317ed42b26933ef6f05151b7dae06965770a393d785d6cbef665d89a5695803ea612b61c637d303e12158c7425cac5f01ecbc27b00e6ce9caea18b8b61d8c79189dc59c9d773e00a5ae5caba8f742d9ad321b5d83d286cd3995ed83d37e3f30c78d845dd80279fe9d91651472d4216f5a089d83a435b1267c6d23f23232f9a260bde4af562b95c7ac6b28289e21839b5b2d5e63b349df8b874add251286998cd4ac70ecbf0c8958e392aae16de9a44f2ac8dbf9c288ff5257da6e4113f048c33a0d69e4383ccfc38c9226c7f90b1ec4f1e527dec90f014cc46f239e0dece0f5dbbe78c6d7fb84ef49f7e3f4ab070ceb9395ecbde4893bda5100a39e4f322b907531a512e1d7792e38f90232388fef0a63594fa2275bf9f272bc544b16bff8095397c407b3ff0bd2765e11f093d9b0c4fe5d967120a3ffcc5f50b81b7ae2d80a875d6c33096b4fcf91050da44e14c074f383275333a908a54027bdd0fcf88a7a47f6e336dbb2616babbd67510008ca2b2fbd788300d455261de0515b84f97eca7b5b9c75dca0291a9f246e8f0f107e2c1f49f4d97611f09fb0cc8f2724f5d60fb92b2ab139ad202fdc37f53fdbc32ad392792ee441f46893263e903fa5ed7487c4c7feea090c4c5f22b24308a656fe8b954837579acfa13755e220171831e700f10d0593ecd7ab8deee06b6897882b81b62564440d38b2b199d78429a757b72042407510ebe6faf12a0c34109804e10b6092d5cacfbdb094831b7881f7c5bcc595055e753c04c9a32659eaf62076ab66e72f6e741a34bcc6ac465ff37f340e5801f57001d0cf7fbacd4e33b898636fb45f55c5eac110ce6f523ce98e2ba91477c8c112299621a03f7680ad5726b9dbbe0f695d09a5d0d53555635eea67efbb3ba62e81de0bc899f35273042e6ebcc111446192952be3ecc5f3a77312d2b2f502f929bebdba89c4d2ca5a7e0eed5c91686fbbe0f9cbf6b7822dba67e18925193563487bdf9d48cda5f7b867fd0d9e946c2c3b65d8c7f5ef74efb2d94434fdc8f5353a358a7a81b88e7ecf2cda143d30aca5939693f79589131cdb8c9a333e04b61b200658f96319e4a0edb904be861eda5eb5ab798d15e3de869c79b8658d2d3bb508cc9678ce88510c52719244fe27d3cd09bfb55ed033099a157757e67fd4eb38709c5570763c05b9601d165f73edf3a8a571a6a9ed9c0319602f4348f5bc7e7ff9f835b63e8f24e30f48ef387cbd32f19e128f75973b0abde544209f4761a150059d1a88fea7c7f8e5032b608f79576a423b8b550071ad0d4e85f4a97476ad917c448d42c399d138ffd04615ced25c8d4c0d137dc1f151318c5730fbdb4036f11edfcf0b69f86dc6861ecb8f1eda7e9e6988f82ada026269f82b10fbec52b6bfc8527695a9787267cfccab8b82498f2d6ba781a0ec47061f39faa320d281f29963d54c5d535ba5a3466622610b69afe88d0b05dc21774ac75d893ae0e4805aeb66e9a44a6a6204518d1b08db5c75ca733e76d4d9f0e8ab5ee19b8690dc983a43cb38d935611efcff99a8ac060e300496ac0a4caca743afe923e1fa553f25f20202a5556b6d42502b0bc03fa11eaaa9c14ba6d4a91413647cb3ba5e8aa0d5445893a8bc251704cb550dbafd5464a533873af6e640804f1484818b564ffd8b11df2378ac995bf5e810af366771c3625d1e3890fab8f39ac566ed3d3a118ed95c8955469457961aa7c3cc96a055c6ae63df4491a4b2f6ab0533c6eaa2ad031ff262f4e30b373150a219746dae2e4c0657cdbd5b323238eeaa7c8a16e3cdce3f368a922e0629a8fc4459930304310991f738bfcaa572e2fc9e04e50d80111272f126d8bd04601fc3af8cd8cdc5822d22b34375ca195430eb8581ed48a68a6dfe5d89c08c463dfa18ac3ea864a38eb388fb7eae77e4a8bbba631694862a165e018b486a7c4206aca6aea3458916174efbefcadfc3e48ed11406877659c632645879b0ea30d15c9754d08d3000f90d84788118a502fcaa540107b5cda2aa5474478231cd77a43156a07a07276ed0aa98261bd31863689c09cb30986afefcf98937536c6de1cc0ececec5cb3c8da1a5e9fec806b025dc8f992aec8bdb49c12ec48212d815f40e71179cb1347b37eca4c30fc6e70be3ad3541eb8733de7f58a05f1768e648cd7d4fe29e9164690eb1c0b254a626ef4928bb6ac7c12c0d1773fb80a25fdf526b9317ee0e5d04c278cc2cc34c4b20be1615b413f80c4d234a36b4aa937ea8161a7b0e5b0eaa891794705562c4dccdcb415c0eca596c522238aefe72019f6e0ea32bc42337e82a3c312ecb8e300985359d2358ee5a018460e76ab0415319189af6339548b160c8e8b788c2cc11ef1039afafec2a84a2600c7f54bcde86354ead1d7e235146355e528a218fba43e483febc1b146db345ebc086430cf3c20afbbb46ffb713f85ed468fd82508899768943497996b5f00e582a4cf1f0948f2bef99cd5f07ecaf1e19f1a33940040164e7ee6b1b815071c7393b788ee67568158815d1570ea3023af81230e7c657e342d408d12275d3e56b807cf28e3f435f288fa91ff24627f6d6562903e36373e16a2889bd9bae8a019d6698b71e3712908ab5e2335406ca5470090087ab49bd9368b7bc012a8c095d4f2d241c03a541266f85d670eda83d04eb67e844372a63fa9a5c70d43920cd2afe8ec906421b92934a6abf61b97e92d912914996b769dcc5196ae0bbb7c7acfc86073c05347e62f9a42bc43b3f14e625fabcb9851d08f54b25da14d0c789739a57970cfb250e03404b726259dccf340be31aa0d4afd5d8ea0d4cb6bf99a747b12994b099056d1c22ed13e019fa12b61a83b20a061ddde88885810ba3e0e88557094baad1b60856c19dc32361b685345e3799cebd3baf1669e9b3168282bdb3ce07a631df91cd3fbc1da4e6afe23de9b5a22276a563ea6891380f4afc423f32954e163c50b100245e190c8265dde3363a9c9d39ec7dc0ffd621f834043df020e7a2947093459ba77279d6408d4208e917e3751c1638dd28a317426db0c959918101f70ca6a564a8551a37ae4f5cd0a326b8cfa221e204ee408ad8825595fb53391af493fa218611f47bf72e6c98a864dcdff110945bc75c389c07d30282dac36bac27580daf3c8c53311ffbbbb196d29ead7bf09e2de4cc66acb913c1f0e28878f1c7bb204ca7124b0d9e18d88f910e568ef3791c660c2d24cd3852d63c8b23f25846c548eddf3357904f21e89ee0e245b58a5c226e3947ba1b077e00a9e0cc87db02c3b8b11652b18471702747a67954a207385603b5efe59f1e52eda8ca9298fbb9afda4717a56909134603a589c3fe6383f46391f89403b369298fdb62e401800687ba92cce3b9951efe81814ff6cef68489c65b04b1f212d2a4a6b74c64e6ce52e8c032378626bca92a8b480bf1c7465c0115c0958810a060e7409e070885a54768648855c232471291b0794e5c44512bc4573a9f19d4adf83766ea9eff42bc9bca4ffd394693c0ff0c01a9004cca525d9d15bebcb120e57182904424d7a6d878e03e7ec310e7cff3248738cf77d0431688e84c2a01667a38278a0e863cdf115b5732c80d4aa71877e2c10d664f4d5a4800acf386d24343d34f0b2864ac702525b0c1590601e6e337b3718a0ece9c784295b82e2542cd9083d326bf0cc9330cff08ac9886c446ff377f66a4d462bd6c7df031a0364d62cc4a907e8d31855fa3d47e1ecc8eb24b574c23e8af4d918a82603f8a03f526f9fe14e7885a50c5463231f5b899983ad69a392b4179b01d2065bebaaeacc442b9f1eb42c187ccb1e25400a9cb79437b4dd61386a88ed98255590ffe125c074d05e16c8e0ef14d40bdbc960da37f98e7d31a5bdd96a63b3ed47aac9f02e293376a88302a7112d1b99b15a1c24df82c650647c7d389c48baf87cc3157daa4c5230292d25ef90d7d9362765d33cbe8d8857f8e2f765440cbd46fb811d4345a1ef3e8dcb773699a669a9f0cb5299b835206a6a4c6706839bb28779bb4970cd1430d6d804e656fe8b38b689a4e126d9135453d98b4663a22144b4c766708b355e83e74c2971fe5a4232a4f8ab9a6558f6fd84546af1f98214b559268beed78c724dc94bd89b31550eaf821d27f6c0e54d41ab79921494713dc4780b22668c70608d697f162896544d4e8d7446aca8b4c8e0668a5dc254d7a96b0537a4af6993181f224c109fea99275182e6a909b8127d4c47aca903e60be85ab2d8692dd60542c984c3712563cfa35eb9bdc88498654c63c590d0243e5e753e0f7c84c871e6d207ecd11200aff32060841a5661b0912587e5c6c8e48b4bee3447e5673d0e99574b469610b8f2254db8dc206372a514084bd9027b2f2e47936faf51cb39cf7cc349e4602bc920e3fef341cbc06e41b0430c000cc60b2bba7ba3c65f5becf1cb0c68fb5df6c62f1e4270e2912b37f6b83dcd18d849fded60d063baad10c62ab8d8063b9338983959baaca0dc45942bf80f935739c69d8e108b001df08073f11b0809bfeb59ecbba6dcbe1ad75c2324a6331c15624572f753d958d449de08269309ccde968a10b000549cdb8e4c8a8fcaadbc0378fac7b06dc8a916c7f683465f22857b7122a55f8b651f9fe20b8afb9633e5a5bef63349bd2968d6a9d1edf7c79810c378b0e309ca5d2f75131ed75972759ac416d17a17fcee881300f2b4f725ccfa2b8d8f4d293e6c4763a925a7b944b27554accf7aaff3692f7d809d8b03fa20221b20f4d8d783449c250675e98d11946b1dfaf8023aa97e7fd94d20d91a337a739542450aeb236137c9535e2bac22967e3a0b998520be9f1a46e15cd0d26f1b3873877b320724bd8362b38bfd63ebf503d1d5d59b71f614f344abc602467819c5870ecd44e28d9bbf292b8a867508214c1529b4c24a23b18c5d77b559348007f8cd74df6d0cb257c02f818722deeb48b8261adfa9bc3131f984deee0c523d00e7a39ab4babcfe2f816dca7e5ab80bfed4da417fe063094ef0290629561750055b606752fe4208e48d7e74f76ad7e6d4ec61efe9eb47031ead3d2f6004ff636eb03b9ddba88082a919f488dc68829fc692c8d6fbc2c3eb1330cb704c0efda0580a281c054ce261952db7d47da1df0e20a1bc80c0b795c9c69d9181a28b509d455926768f7dd84fc81e54bc114976f76f07438af2cfcfb4bc9fd19a07d0a26d3edf4e7a5c33befc2f253f6d68890c9a485e977944425c3ec9bdd11af95eee990ec410e0d6672bb9364d20d61a1a9c83914d19952a14b7caee21158e5a7e9811bc1d2722e6a4646e101cc057118c83ab9191622c524f7ad3011708cfa35d0c19d84d70e076331a6beae3c6242c3a08939edc1d50a2b9b31cb1def100ca59d28c049c74e00029a6524438c04100000d3cf23040ff3ee53c6215281e87e9946bb664c8f8d685f00321368913568ffd48acfeda45946610c2ef9b53e629973d5e7eecf95d70519a367ff8bca7933d7520b39fee25337a6ba46fb69c345b5bbd27b0ad4724a62e4deac3705739bc14ca60724df094bacb279f05b610e0957d64e72b1f8d2f8abcebaf251fbee41c1745587c155e63957d742a6936693fc532a69810b36c97f7c5497d7666bb7c210085570ba01eb08fa5ae556598bb01bf2bae5141e0690ecbef80cb0afdeb86464cde864c6a09e06607015701b1a66b3bd0f2bf5c5ed45749c2d81bbeadbf9cf038c272aad0b8f533c9e76a87ab4e50202ade356a5fe602caaef188149f8f313ea5f1a14dd03a8c3f3379ff5dcba5cfb2ba54dfa61963f09aeaa5e6cb7291de7a4696053b5a7c3f602c08d65339264026d595d5b5f212e95992261bc55a90e42e28c67babb2d5f40204f2afcdd3867e0a64785af8191b8f897475c212d6884d8e9b68bc75764899a5bbc5a798d251b86062697105a2686668a83ffb2c5f66786557b2810c11a51ef207d4317f3a5ba33ae454c9df254bc5f40824c4898145b5d3e9d7a71d8f4e7585ce310498de0c3e363ce58c3562a5095dc1a7baaccd48ccd280f9d948f8cf8e255c582824a3a4ccb0e98ecac359128a40cb1eb18c7cd2515a7f659eca6a9ab0b6ddc06f594ea2c74e594236483291e5ba6c8e495458e4405e98e9166983f378c74cc25cb5d83cea4d2e90f5ec31d344801e235a6ca040ef378aef0810460cf225d822f8488699e6cd8a905a9c0e0a1f8249ad5063b421cf5cd5029d01a66bd4bdc0cf408002eb02e9e76bea85529d43125467e4968a42c6fee658d478ad3c4cc20b7c28f40edad0efc31ef7b3b94dab0276618467e87f4aae3652340adbbc52ba39499c781700063026a9d3990ce839429198b5c638301b1083a7cbb9cd5e24c32ad8f98df6c3b4dad9999562a7f7c3bc49d986f98d0cd0074adb533074ca6761a65ab229eb350cb2324e70944b8e84b300f8f734f351de5ee366a33ca1d76b0d15dbd64517ea89269ba3d8b6a6efcf1ae43a31326ce7a9ec43b6af9cd3e05f4b1e3f814002d9e4d44b7f84f912c95e858d3221dde0ec33f2f53c6f6950d34898582329606ac732e7d92aa3a2d11bf39963bb17776cd2e8a557159b12691c827889946a1384db0957d56dda8180b0d31b132616f8597849558dbfd0573da12b5741ec09cc22e8221a6d60292a6d9966676f9075db21e322f0cc468d41959ade2c37a561291e82022b18b7cb0c597246043a481569ca22fcc20806cc4234fcb7086e197e59929c51da1baa18ca985a9637dde0b0a316f3c4dec9d69e4db4c61ec5d46ac2987822fc017d4dcd011cd8f7ed530c25bde1e6132fdd7380f1bccc8c8541ecdba7c4fc88178a4bd04ceb526bac0281c2848c37978ce785d1bfa7e9ddf048d5404692f554c6006a66fc63424707b79f37137120b4f76534e55b1aa17a2711fb8d88226c59730bb8cf3ad23f72bfaa46f755f414fd22a23c0f9050a96b0976da6dc0fc3e080d29e5e526ea80c6f1bd056a92a5f179904260eee2d418750b577c3a142ea4a617e5bd3d89e356fa7e17245df1222796e8e84f9a86c648e329c8c049a244ff5e4d6a43f17edb821c38e3695e92f8687a46d62d5511330e33d248cc9cb08b2f92a9a828fdd041048158cb9caa4783d2fbb1d35baa535cfc0c3ae5534f427729317d0237d1c301602f72dc9c4a5d6dc08d83b18be9f780ead36d315e3c1d95d17ba81eca859739952ca5efe1acaf3a43b192094f4c6228d8c1b408856ac71b2d652e0133fc847006581b5d03d73aa71c090ccdecffcbe3588de95604f9d1679bd7f59c0830f1c029d71979fae30df6046c45a753888eae500fffd042c41c9e86521c1f755603222e15f93446c4b81cd78d9126a9cb0a4e93583148071f61e679d9a3a514220298a882e431272094ab41f5e13201f968e83f7da9f3232eff6556f86c05ca7331ff49b25f6681d5662cd35436d36760bef9f5b1c63fc8f091a20aede7f2b041541a00833240166a8a46c1c95bc5009c84740c145b4de478914d9488c3e6f8fa8000115b1b2a519887346f9ceb76d487090f010d93ddc4e20c95d8cd43cd4fbd1af246bde638bd9194ec041ce4045e4004630d5720da55493af52067a71a78dc3711c3c2688383727e6d9c1214c8f572d68c2620d7b4d3e2785dfb55590e6d444d3a000e2a29685723e83fe874e809670f2d30beb87cf2a79b10f17e36b1ad6dbb354208217b93bdb7dc3bff0d330df90c6028e10b4baf3ed7c1963c4afe50b1e27ecf91064dec22c7dfb056b684ae1ebe804412a07802095376f0eaa7a00b872359240103114f5870f4ea43d8b750059380902ed40abe6003224ca4c089a457bc10e9f231061c5cc1082c9074b1e415bbb005511348c080e2440c014881882aa63ce1c8933026d17db26db65bd0357f4f344a371e768658d269e38fa872fa35dfaf2965aff0aa57f028e89d6ed984532aa5ca26b5109300e8da1dd3ab222f2a18630547aa127941edeeeebac566a3a3bb2e55276ca5e94ee9e091b4354ceada468a484a3d8544ea6813d262eb53b5edb63ab85986465438a15e71876e868b90bbbbdbaa48a1b1ea55ca06870e1e32357745534f745357cbd0888a23f95b1d513092686a6a7c81074f6890e4451117589103090ea280c1128c20cae2d541c0a678c93db9c8ddddddcd754442ee25958332a9365277f7d1146568541491fb3654f82475191a4df1856ccad0688a28550918c80191192089220757d4006e9104861327a0f085a52c5ce86a40d00c9298202105328870ed18998114b0f00517465062c90b1e42780be1618e3c19c5eaacb6bb9f502407b9234f56313a259e912776f79429920e25f76db2309a428bdc3c4410408646532021a332349a828836317fb25d2aa3c7057c748066fa4c1acc9f30bce084a523326a6ed8e04845a12da8083a2a4286ce32312ca9229c18f7fbade5aed097fc64cbc2dd31dc8fa5af83074e0e0b773b09899ff9c5fd522908a7adc24d3521a90cf25166392497100386d66189a425f2364f96ee19a6dc8f45e674ebabf4fd92d781d3ad7aeeca21b9849803cc2d89b0b859d82e5ddae73b0f7f40565ab44bf028af38a4a2a2d996f336efedd5634130a08c32ca906bf2a723d7c640563b4e6003265c04e539734410d4e4897f884f9a99869b768cfb712bfbfafe6f8c0c978198038c8172ed7743eef7f719b1a95d7adb3faef3f68f053bfd376f655296f3d1abc78260c04e10325b3c029a231e41e7887f989734e698b3091f1e31877efc4aba7840567c64b2922bc864253113261e0df186f8c9a35d1c508e0f20464cbcc8f170298a272093232896f207a32c413222111adead538ea7d1adb9c54a4af91c324b1a620e39078707649223133348e2e382a31f299a08c2074a9a5cc1c40544a4f834216298b785612907298c40d4bf117388393e255d37e077a325c32a9844c98dbf0b27ca024a18c99b6ace1bed5239c28113ff2395a510146ee4b8f9184189464239be3e28c5024796686d393ea65b738b1ca52025c728a956ed90b99f43e6be99d10727f7661cbd8ab7e9554c228f814819b4a08514274661784528c420e4441139c0011154f08a3c34c88baf6e286928c24a2be57536cc5d6eb8fbcecb62db2b79d3a54b65b18a87eda6e76cda75b08673b69b6ec23a1b8692957de795e109258bf36c3ddd20d051a4cfd649db761bb96d306b0a6583321fcd3479f105a5adf803227ff5d8b708e7eb63922814b38839c45c5f5f334c71bf99a94ce69a45cf9dd25f0cbbb5b6fbb6a3df3d47bfab9da77de3bc9d5c83ccac61d86da4f594b2cdb1ab4a99464ee1c5d76d1a1a60703f4845433c557051bfb7d7dedf6eb3e2b976c117cda292b55886594ca946d15324c32858904456408651aca08b9cfa6a83dcb6718ff3f4ed84553bec4fcf6133ef9b39bbf43e9d6c5a99bceeb093266f274b2f48e70ec72ce20ddbb3ed3692db62af348cca328b639215b4f6d5dba6c551e81eb9b791d783cdba509a1a33a2b9e8289dd449525a4a8d1a38d0e050a3468d7a54a7a84c6a519da216d5a37a448b2814e8124a44a1408968112d7aac35cb6aab6ea0fa8151ea551f464905e4bdd6acd647c122762885fcb48b2d002c9848b82c6929230048b004d11d6844ecf8b9f1d066606b2962f9c18c0a14802407262e3cac324784c080c51168e085d113ace8b9820747a841115d681185204031baf8018317be3003273bd8410291249e40062c3431862fb2e86e2140893c405001138eae40c20dc810050c8d450e80e003196cc10761242d1157728cb6c5926accb1d41d453a00c2174414a103325e5f4a850831a280832294780106affecc42ee6e15272cd7b846b73ac7d7dce856c442ee328e9061440bc8403ad22d584119bea0411251e8c14b28679864545484dcb74dc4c2d90c8d8a8238221a1484b65247e9a4e6a2955a8907dbe983f122f729ad94561a5540f9ebad2f71f4543f39de34865192f1b08380ea06f186b809a12aa05eed643a3d2f1e76117f2ab141e992ef27142971832f54e10a1d49e4a405442f14741132f04879c9b7a753b1f042c12a8b97e472cc98f0c414449b109890029e577b108b1ebcb6494ddf4ed6bc90440a3caff60c80f44241c7c8846600296e7c9d94e28fbe06db2dd94272b649a22ccb344d5b82cd32ef934ae4d012ac954496c85a6bbdc951a0683f7b5b9eb4b85f4ccc655634686ad4dcf87a72d4fba894334a9e6cda7f73ce890394869fcdb4e61fe8fc8070b99ed6536badb536a333abf6d48b493446b1962ae10b32e7cf2c327de6cf498b1b5f3869f1d5d4404992bf201d93a250548a4a44968372bfd4bc85aefa893f78ec9ef20f50b2ec84f018862cf704e5a6622eb3a24153a3060728f7c60ddabdd464db6cf8a2a3e42f48db4c835af560a63ff5d61e7633c3f5d683804422de005f319db8937a452512f106faeac13cab8d0ca242af5e4aec305a3dcccb01718072e33f8ecbe23cd283520a9fe418f10784cb344689516216dddd40dc2366112546c9418c32831835376c70b0c42c6294982be8c004a22dfef4ed158430c677378c3056b1a1b0b8356a206459cad2d6c7ad1eeb6eec0e9d83a07442148629cc6e358f837261c68ca010ca33646804854fde324e9bd35eeb6e2c8e3ff1ce6eca6d373c39338ece896198e2d93b74deb0cab1400cdb340ef36677a3418e9326d8e990e50867e8b796b3631422c76e67a80c5104e18b2448b1e4f322e2002fb8010da47ce103259ebc6063f817357b45e334413843f13ce5792af3163b4269fa4c903386bf12c4e44d639931fe501a817a1563508edfb70e92aef9d8e56c581501f8a2912cf91587a792aa07eedb373c643b77f8ca41bab8cfc3ae021c1e72c98adf70519e98527acaf52a16b14bb6392c4c11d22bf8df2552764069956394120820f45bb7a3b3c4f802282777464a27e681a3e806518d1a1a5d777723bb8ed22431cb8642ba1ff7d95cc7b005f1431fe6afe60fc21884902c822d48af209d18abb29bd2885d4e4a9730ef47afe02f90c4a18a70812838db6633a593e2f40a4987212e85bf41735968d4a0d12b784ae7a3ec40a63fb29c41a0207fab5e65f85eb1a4766ab43a98737e3b30533aa3306249142d284229a594ce49e99cf1d36bd410ee373384f48a6d83b1df2bf8b16428693784f84bd1cc72e93d6190066d50c6c6f91bf2f436b9a2850f32f55af2268732f558b2924c3fb130c264b31c176564990cbbb580fcd90ca316c2c8f0db0d94524aba6ddcf454f3d0480b486468d40513cc03a537e41ab2d6e5d8b6cd6479d07a1f9cdc1a31d30784eb72c88d93a6fa5a1f7395d71e6ad70ebb1c34c72eb890a907ab90b14f0f1a293921530f1e65d83d00c32aedfdecd96107a17511a061083f18a38928be781159c15f101ee09b08c03a1d68ec74c0b20f4e348f877c874d0f1a69a109997a386f1bd43669a2b7698a553bcc4c1f33c51f0a72c447b873b8464b39738dc774cb5e5ea65bf433537ca35740587295799eb20489197b8671c488eda03430696bc106653ecb03053cc43048af2834da42920cf3498afb4132e6c705e9153d76e8459ea2d32c2aa45774698a101d68838b4bbd62c0d06da50910dd0f4a998011f7b31b863ea4ab795ef43f3c0073e82132bdbda9c7173d4d8db4912e48f4a2d7215d36f2f0bc280f4f0f0fb53cb1a5143eb25aba455286465b1c4191a1d1164564d5d13cbde4822743a32d96322c4386465152903539bd80596a18295e64fa189f4cefe4ce94152eccd0748bdc1f15a04c558cf44a072f2e3dccb206191a2d9992a30a5051a65731d2ad98448c9d0e32cf89557e66487155f3589e593531bcc2094b195ee18430f2674aba539a45ffc40af783618136e00d0364d1c3988d9618c9376468f4049eacf2036dc09393fba9fc40a1fc9992568aa4eb4a6916fd25e3480ad21149459432451959caa82432fdb73245879b1970846bca135f2970861e01445c951f0a557e269085cb8364def4efc49369c4e224052687a4fba9fc046515f6213df953c97fd2a757f3407a4ac6b04ae21d34cba394f2bc2cd2ab894d5e98a29894268c52b7b067df95c272246e4c86f22a3fed9a3952015a62486549b7a011144a9db4240bba093d81287f2a42992e39ca9f8a924c5588325539ca549a92bad59a584c98249828dd9390a2f2a302d42b9ae18f2b92e91bc3e27ea6a9b2045609ea15bd925ed1e97d16e9460c4f6f65a85794e854858bfd74c5dda0c8d5c3219fa4b81f4c94ce13c32445e17ea6246caa98d47f30432a2654d54485d4430b2e96a1d1162ac8536668b4054f9edfb02e87cd152fe5289ee6a91425a924d92e6beda657fc0189c9f52a48d553c989c195ff549054245649f260a278304a1e8c171ecc52af60a4580c933481187c2a263144e644dd6f2549a6975f11ea155531e9565435a9dd8ec9c393eba5576fc40550ae9e0df964c55549cf3e760f983c3cd9be3b98a4868902a394e94f4dae89a857f41f4c526c3929566da66d3a7076861290642c57083bb899dec6a46ce0822a732d589004a3b19ad10520d01a344e66fc60dea8814218240e1b16238ca179e8c802480b5894d32b7a9c2c60a0047874811e2a64985104a4d872524c870ef48adec7ca168652516012901f4529316410205eaa183a027debf48a5e48911128119ed3929417788ee87119c2103d2d3bc622d107ca0d8c441f233f16892122fcc4d62109a0222222d0124150586083a0969346094b5bb0227f100946814a7049cb2245ea568c45d929928703f64a5a1e8a24d32b7a1d5bdc8f22d127ed3a11b1e8a14dafe8bbc8beb66036e5886de00cbdf578e8c0d12b174ecba3984386dda248361a00673ae71c898bc493ed0c5be8c29d191a5951247d7062451272bcf1c1c9d53234b202a8a5911546901180623042154caec0811116a0f0829015852081104a69219c73ce998a12bbc4df9c73d639e79c730989a5b20c8db4180311ba76d7204a5012062950b8f084300020c5155ee0028b1d2c2d618bac0a00d4da1d46ee9e9127e38c6c5a7c91fb560b2c649ba1911657684dd4474ae98c73c6f854ca5a5965ad12ab7690afaf405279ceef64ba93278a4e3abda635345366f625c86e802933eda58733ec5413e36418e61c48f4b25ea646d8e03bc31ce352afa21426b48a6e27196a219a5713ee175be8d2449a1b85a08d7e7cf7401b4540572c02b2e2a140d18216c00043882844843311c79e38d4abf89b2fb4118b8082462b27e4f8448e357a156b304daf8894d8faf13c8e3c987b35e7552243a35771da00670290e31510d32a408effba1cbfd90021fc3703ff21e053408e2d444e84ba65e04c44caf13ef48036a0850221528f76adf0402231c6295b473c8f781ca4a31cbb7bbc9c706be8215d67c20a52d0c00a442881e1158fd1f63ab7c43d7a1581b2186cb1bbc9de7de2faa0e4f68c31c68800316e073194057e5004be2f8184e455730269174ae8886ec56e82943f2e2f2175a18be436923b89dc9f4bb4be53eef7e85f008b29b97b294b0e0148f7a3c97d21ab5f038bba9bd311fadf29f73f0004da88198601922112911ba660bcd0c4c276046d442f661e22f1089f5ec12354db4856c71f38d32f62b284e82b9a3c23f60b80c4d56153e389db521ec91c6cd80725977b8e3c877590e4dc6fd7e16e7a4edf6f874390e4dca33ec4747b8fc22e7c993c55c51dbe58c7e93af684752eee308dacb5d6c95d6f88c91b62fae52e5f81cde421c9d9debfde10ee2a1ee4ef7be89b6ed3264f556f5255fcfaeda746559596cd574dab304273ce39e79c73ce6b599d58d4e788b9aa78e07e9fc3fd621d24f527acf38a3bfc237f36a98eb52b17a250548a4add1d857a15a392154a472f872e4ddc003c715fb00afb0b4efde53da466a4dec38c212ef892957dc6e1ebeb282c1ac9ca9e5d47b77ed8de3de32c6681fcc8dbb12f4600be8860b7f9017bf7ee1be66d5ecc5b7738445818cc59c6708663945ea1be82bf9957a4cb61dec3cb251e22ff7218e972f8dab0676fa50a736c3b8661c77aa957b597fadb25918aca3f5b9fbd05b3ec2c2c2cd6dae7d86ebf9331abb560efba96ec5a761bc9e2b552af2ab654b72ec3bd79b757d861b4c3c0bc877ebf0798f71b0f9187d1de30f2da25d641a235d6913016838181c12ed8a1c42a4df51c97ab24566958c5435f3e07e6aac360dfa4e77295f77218afa5fc1028696868ae64d5d74b7c79980f1922b18d64d5c3fc3b0e11121ad36ed35c6c327295455462d430896118b6720ce31071f9cbe92ade0b7cb978f22fefa1fb2fb83f447579f84279a7fee955bd4d5faf8bb44fafea3b8a17d85f0e5fa65fba5ede03cc0f83a16499700f2f87390c1ee2f217fc970a3bcc775e2aefd85d620e83755c1e731dd55fbef3d24ed3a978a07f7905e6635eb0bcea30d7f057138387b8c8ab9e23afc22aec7dd5fb2a98bb3c47f597c76f2e9ebccaebbf78301ee7e2e920c989b90aebe82089007c111982244775171a3e44857d4856bdcb6b780c8e3e9255eff398abfe451f2c6ac04024218106ec8223cf52ae33e0ee91acfa214886c07c880b8e409255fff22ff260118355380a49563dcc0ba6912c1c97d7bb78cd2359d562568354f8f840a32a20e57a9844aeb22757a49ea52a81b0d7278372bdd5b04f1229515a4206936e7d314a93273c92a85baa48d4ab7a98e392f750ed245f1779217f7dd485fcc9e42fea6790702f79ea654f7d2fd56f1153ed98197b8e99b1f691ae5e6a567dad6f1ee972797df748d7cbeb371dae70bf36926b1b69a06e7149b878f105bbc5d56f2f1e7cf5d2940d7f3b9aa6ed64ec9be6fdc01d66ccfbb85b9dccbdd38e8239246bff74b2863feef61f973bef872074b23dccbfe6c1bc7d722f5e3c922c9c9b58d4ab7a1e3e176697bfc057b784e48a2792e0c3c3532f3b150ff22ecf9177c1aa9cfe0b566158c5c3cb5d9ef37217ac8304bb8ecb5f700ecc5ffe82755e0e83775e1bec72d8edc5536d87d9b08a0797bf7cfb0bd641b2e19c97c3609d97ad76974974ebeb24b9be7edbde4bed9a01a8a73419f59288ecf129522f7feaa5911a73bd0c6a577cd567ddd649eac462dbb66d8776cbddc583af170fbe66ee2eebcc9b3906b1ff9135cefbe2c60149657bccb351ed805dbb863f0a94b1efccf09e7ab9dce0109164c428dd8aaffd2ae5d1a99f8518a0c8a2074820638926a03819834f931ab820092642f042230ae3d38b2688a06c3435374e38602263e84489947376b6dd9a373108aa7898553ac41c71e7983b6f70a6addd219f70a1084f8e37489108ef96b46274ca58732375850f56041f08a1090b9ea8410f1712d8020b3790a202288ea001d18f0bd1106c985c3002136480052ba8a044921fb834852130618b264e58e10555644f6ecc2d548135d1dddc152a1802665153d346b387c8ddb6c6092eaaa024ca0f92201186962a90f88cb102294828c3ab2b138ce4ee1a27ec1529f826869a24fba4b7124a2d40f920164b8e385833356a7a7cf7f041c9b5afd7be592fbbec6eb42ceb996b2aa732d5347cf262a7037d95a7405293da746ac700ac08821536c34e16751e4dd654686ba3086dd84332e439376a24b3d9ed7899d91737ebc9dc9d654f0f66da498cbfb8f5362d310d4537be6f527026c231322669b7ba45c3116eee59313aa789c299beec269ce963dbe59891eb6117c4e4e191410e521fb34dd76ec78c5cf147828c617a1b396da44194524a69a6f73dcf39e794524a2ae78d1237ce3be7e7256bc2895fc31c828847b7a0e4c1a35b10c372ba957dd3b81a089b0291ede3cd2c9e3540b8b3df359cb8dcfb9045af7910d2e064b9c3957d22db9368b3565218fb831042484d50d02cf30c484d124327644665083d0de4ad238c3152536348f3ce8cb1089d34a92c12632c021f6fe8d82d8bf42ad28e73824184bd8b6c095b30c91d3801086480018cdc5de38411648d13dd7d0e870e1e991548685fc44fca8983749ee7d12b781ca04c6c8343173874d1d2051b94d9624bae07b4d13c707ad0d46478a50eed369bf7a30697ee804d32c553d3bc1fcdea053c81519e25e652f61eb9d5a339b292ac3e0e493692484a1f720ee114b3202363c50b884c19294656b0800c2d909132257777777777932fac4046ca3c156e132de4eedb2a9c68826479b6f90b6766a69753c289edf39cf30135e41f62103aa1dc3e7a39e23773c4f5107a41da7e66fb54af26d72b8b2dccb7c640cc62e3eba9f783b5f0f439e0a9c55ffc08e24ea658a4ad6483328dd1e636d8e5e06efa16ed76e9758f1e341d7be705e9acca0e3f8c7aaaec3367dfa66657b3005a5c8961826e3f7e62125b6badb5f21f4bb6b735265b8b5d0ac9f4df8efcccb0c3ceb5bc7df57e90b7dfe4657d56b16a87f8fa1cf1f8931f41dcc9f5920784c09db93bf9209d6919659441e7cc1d0e118a67b722cc146e43a223d418fb987645247860fe8d6ec5263f5c4c0d15d9c44eeeb23439e2388c0135b831737665f162cecff979ac625e90ce5472cd15408b2b13d32b7998a01b2fdf2d6939cf0667fa90305cdcbe74d9673419fe322d1cf077255d5c0ee6558ff33a0cbea46773e328313d95fc76f8ca3c95e43cf8d20922a45bd4abf16ef42af3e6ed6bba05737723847ce478664b306cb23185f3edb58fdc1d040af27cdfa608f783443d7cc0568c10668cfb5dd83dda1567e0633405a2588513489a51154baa4842cad83645591e871115c8c8d2a80a23dc079b74778fc0e6781e8f480f5b2f96a2f333a6dce6c9dfbdf77e95b74aafaa157b0f1f40ba0523919ba53c841f24e355317ab1c892524a6107015a46a678054463b68353ecf9091fbb1d5bbba04dbb54d821911efbb2cf5ebd1efbaa87de87829ce679d967de0a6a5e750433d3ab76884099e2206219994afc752a0ce3d4c39c735f1f76d50e5ac67010a70cab9069f2b793e5234f861e6b36d103da88398291a316728492e37d802e0b59fd0859128cfcc1a254fe605117b91f231093276e3c2a3a401837ba629164f58f66e4ce42ee1e11cec4ce7146165490b41c77288a2237942c38a142ee7ff148079ce938a50048dc484694d2ab7e8d27eeb7ca0d21fe62bfe924ca11055b1896885e48540ed851ed8083c42dc9b592f4231e41c64f919974842489133aaa227f70ca5191187fe44fb7baf5c5e4a06e4595e5a4916e4d2de4a8943fb9448e07225e48bc8ff81fdddd1248bab4a2222d924092021346f820750329b0b8425112a220f414e9d21edf4bd2b53d9e47cca18324a7ebaea31dbe3a4c669759e7c9a1968f75c24cfecc1c581be35603d1953f70265e8899bf5e6a32d424c3264718cadf64428e2f40864d8e50945118a779f0b579f045834606e3b0eea68fd42bf94446914a9ed4e4120dee378de4f86964e600bae4546222c9713691e3678793e43e7ff227c778f91325508e3228c75eca981631c0c217b93fa10b82c109232e0823f35746ace3b193230e42333dd6ed98700440a766a122b3394057862fb0d127d6bb417d802cfa1e708688fba552d8532988c5eddab10d5fc9a2423919b6185655ac46a41e53061a07a4571aac016d681e802cad5b1c4793ef15b7a657da29a6e995f6ecd60bf907fc01ba686eb7b86bda39ef46af346e721e0e38a37d8b474e513b8f7825209a9ca81b7740174abb76b57f5b8e9aa67dc3b80690e172aed3a30fd5200dc2e68943057704320761f36c39cb57aea25d47b7b86be7d13fac85127fddfb4a5ca7a357da6fd18da7216b2d98059b4ca66f2b9e8a47df973b4290a9edd58d5d87e7f6961dc61d897bb9d3398f47afb49f34cd0677f8eb02a259dae169f484f44ad334ce03d22b4de3b47a4cc32c06b503e956bdf61fbfe14e1e91d357f0d70923e9ba8d7637dc67c76327773165a2297a390d480d597b7737b757cd712bc9d238ed270eab4c5c778e336155d7bde3b873da7f744bb53d26cf108568abc0608332267b8b57cdc2fec96c2b1a19db2ef6025918f6171bbad301fb91b8d811fbc65835bdc2be0026ee57f3c12538ba855d87e5e0516741813216b16770287fa9940759d8b1978c4d0c333f7b425776c8e2cab00c7459bcd2a2f853658cbb91bb046dd063918a2c44cc42c42c89e00c769b9643dc8f16c918765aa45bd8b1d39f769d07c328900cca6c96655936b32c9bda9c33cbb22ccbacb536b39cc5aa6dcbb2ec3456ab4c36edb1f23451421d66628e193b5369501a13523a69d49898d261c6ec72cca05d8e19580a4bd11c2938d3f37685657739b22c65976372b2cb41e14c8ecacd2e479703c299fcdd1c324b6c6a26799bce117f246ecd1f8d2c7f33632ed8b6538eb8a1aeb89fb5e27e13084dee67ab405101350520dc6f1eddcf5211348514f79b4ca4108511ea08aa08150514145050a096a09e807202aa0928221413504b402941c9fd6c128470bff9042a082824a08650474025817202d5042a098a09941166932bbbf96e66b7ef6f59111a00658937b924cb4731032fb2c4f36688b4032d50162bb0aea8ae3461b1df905b59851d22e1e0880c91709084cc071a9721d20e6a80b40322727fe354f42cb95e450f917400c6d6691922e9a08bdcdf4c1c0c8e14dc7aaa65b662dc46a7ecd8419349becbd683483a70926170a4e0aa6468e48550ee14e88033f3d1d332068df23c9d47dd35ed3484d336dc1d56e56cefde75a6ed46eddb35224a4d9e9d3fa6a7cad9ce5dde74ee9aa7cad17e2fcf61168e4a621efac59dc3266cd31306b793a4ab93d89bfa3a499eb28c3b89b8df2a892b2a354f4e40c55a1631409ef297ac99a2af18fea44feea6ddfd43ba367c1f56b2a43665eee4a8619886411b33eff6aad6e318e2de1426a57626db6120a65aad16d6745b6faa5b779b6eaab54a59b149adf530dbd99bb02aa7bbe9a621a8ee84fbc77493e92a57c143546ed2567ed2ec5730b45d667fcaac8a87aad66633f3b0ac1ef3b0faad70e26bf78a235d1df64056b55aab96d5fa16ca4cef9e9d32537d97619576ce66dfacd5b02acb9ed9cb22d981641673ff117dec13e8ba280940d7c54050508a15c8d0226737757737da715c1480ac4c48afb253c00390951d951d95ade04c860ad2acecf0280f48b3b22c7b76acbb59c1994cdb34af8bdfc9f7ae0c61f9cae1eb7ee76555505895a372d451a8b7bc050f6939eaf0a5f29d17a77297ab702e98bb57f9b52a98fbc9de64ed6d8b6759bc6bb7f6b6ee5b47d8d28481f42a7b9735808c0bbf15906665e7b2ec515cfbba8236b8676741d77de4695676b10756ddeacb94b290b3cce11f7026fb0ef6dcca5550bf2bf82a289cbadd4fa64ee947b75c727620dde29e1d886ed967e73cad88ed5a7163109d83c0d8d2c40267e23bb0598d46af2c01e08ca5699665c11bacb5366631468ca39c8da79b1ebb73277b5387b94dd3b46bf6b75b315b7bed36bd695eafe08c5d65ab6576f624036577006750318966a11e73006f40fd885ea1a00d157bd43b1aa1e27ed148467d5bdd80363aa38ef86a64d4a30a5e4d7151bf37bd53d16aea458500d095c240e0b7c1960aea5f0e19b5d99a4ce3321021e6b6ad7ceb6eb41720fde2056916ea10daf801cea0fec91c3c006fd0565890855ac12b38838af91965edbdda21d4326e255d3f9a853a0ab5655cec6e828845320ac79e5ea1c6b8f7f1309ff1d45f8e9d7ed5ad95a34e83a65bf5a8c77b0be3fd69c503d22b140bfea0948cfafc016750bf515ced998e95a356502ba815fcd92c776820cf6f347c86afc45c751af09d41763931d8aaac9751871d0e11183c034368edb7940721ebc58390b582bf1b825cbf751cec96ca0bbc8a47a357a8bfa02e040abe5e72ece40af3195f49fde52b30f89285fa8c95144e4916ea2f2b58c5729595b760151516ac5a59f98a8aca5550ffd1ad67d481744b3bea4074eb1e752883c23f4421ac4d51b66c66279666651dbc217b9665ffe85b9339cbeab17a8bbff9fa23716786b7bf36cba88685d841bfe304b9dbc9a4125bf68dbbe6ddc8628cb35b326e5bdce28655313eda2b44ba66bc32d7e99003d075c23a7d316cd6178970a1a5e1ec1f0443cebe4d2efbcc3ebb9b1a3893459be64c59bb4ceeed6b767f3aa90c799dbef342e1fe912ced17ab7250bfbf5847d5c3101614ea2d47696fd14e47fd84691a56d19bb0771a8677d08c1dc328a55e69da59bc9464655ff12e599996da56d939af03bdca7cf42a7b03c4b85af61a68233e7b02a0ebf4ec38ed8a3eed43ba4eb80490953d8399ccb20d7fd00b39130267b2dbb4d15439eadbfd294705a3b68b579295fdb46115a76defb0a67158b56ddfb4cb22170a77cbaee393378c5aea95863921dd9a9181b0d69640b178b1c3c9c1198ccbdf7c3fd657181fae881406b919f6ea321bacb7ce1c1e6fa894eb7903470272c03c7ca359f5d453ed883c39e2ceb006ce4471e9b13a5dab6655563d8439d8006fa8ffa800e04cfd5733fc6603742500b2ea6b0657d57e7ad9a957f3faaef45fc3d5dce0ea0459f3f53275bef177edac5d8ee748bdced35bf5aacac8c4ee729832c53570a6fe48dc2d7f35b93e534a29fefe3d63f6d2ee66c61b3ecb93514bbde27a15e7e15185427e334321e9b2123b7dbcad423918a611ab66ec18275675bfe3659188b91bad98d96d865539998eaa87bebdc543b0f7ce4bc6db47dc3f5895a3a3ea21d6c7c397fdce8bda6bb7b88332bc86a164f550cec96e9f618b21fe9a2843aca210420a2f8b60de85c2452df50ae2db94274b5a9394e21152131549a1a1dcb5d2a529b93d49248b727fab71ceca3367eda93fb3fa4c8d9b1e968429211d1115111521111d1d7143424041404143404242ddfc993e18cfec993c584f6e6c62d3346589262925294d495a92ac96a7f4ca22492491e41105924352480649201a8424648f88b27c11109164b5fc86e2680f8ffcf1912c497f240ff5913e599e87f6ac2c4d614952cafd793491727f7399b224a49434549444b4f48274347d8a88e64f1011d0516a4868290868caec019a3c4233fa47caa3ee691e89249b47b60f8c52d29425e983745444247f86a40c8a441248b2a6372414043485a6d7c3137f7c8824abbff31202c40f1ffd9dd7cecb221d49567f9b819b5e0b49560fe5fe460337e9560337b1633d709a47b25a47870dee2425ef08091315014068480628c8069f9fdc5ee491acee991e10edf9f0709006c04dcf8600dcf4686a6870d3fb6a869bdedd0ac0cd1b56afa1894b92d5164e4f1501f84aedbc0efb27f784aff691acbe014c1446061b77e7946149cd24f8240a94dd4352b66c6edaa15e4d8bc921299d48029d8843b27ba8a57c5d925e28e128f27af46af6218413fbc4da277f147ab305f186f93e85b127c3f7e8158c2d88374021d1676293ce530fce896b728c346cec82b06d5beed9518754cc65528fc9c276771f4ec9fd296592ca3585628c2d985c32345a9205176228e273ca9a5edd8033f03870611bc906653e8b235df0655daa080f71503f1dbe3e58447329a98d8f0efce8963dd4f0f715cabb9e952cfa93e71abab0a5dac13e3ee24f01d97e27d3e3e0c18d20ae563e51dbe84ababaa8e9138a245da79f304da2485d6485ee228ad414a99b22b5eb4434c98b6e4dc1887021c97c821d41a3d0254a06c683f5747cd2ad6d8b5986e9138a843d893162485852568b6a9174d522cda2b7f6de54ea5fd5a25a24d35a548b6a5165528fba054f5f9b20757d92bd26d906a05ab4d23a572b5d1449b2a83c8a37d093156efc766dc90d19eea90a37bb0d8e78149b44a498795df4c9a3c6e29eaeb8197d42917a559b64caa459f45be5340f87bc55261cae45bd82c2fde613cc0b5a248a0ff3a2cb61b3869196b01eeddddd9b7b6fefd3bb3dac27128918eba94cea516d8274f2ea130dd7223b54c40e29e9563f15433f8c22d522f5a75bdae9ab916e6da7b7daa3a77d3bc4ba5ab47995c95773d45c8be00cbd8e245c9861fe302f302fb0a576cdd794d48779a16918129614b34891a81499fc51242247449e224692582209a6045b8231c9f419ce32dae4c94c9a4fe893a6b516d5a24cbf454f88ed416c1622c85d49973ca2cf3c1c5e7b0d8033a6bce9d0f0511735935e5daab96658d291e3c3c88ba0cc0525f9834c025f5ccaf35ba4733e12ed60c12da2c7ae43bab4dbb98a4392353f6daa264f383f31c4774e6c4e20a40bfbbc10e9e29973690960f8e1be719b96f560b35be62189df6e30af7bae94bb9d7ad1c321d23f3e9265bf8305f783473f2db563f6da0b892e0d673665eda34dc2912eedf63da42bbbbd0f6bb9db6d2929dbc722fb48641f8f2c51c521925ddbb86d729bed1ec9b211374fafecb53d0464d917616390ed6ddb20db7fb0a879e08cfdd73cd97e654fc3fef632f650c6e21f9a08039a3cb193a1e101e014839f58c44a4bec2102923e457eba966b484745561b3ae1d8137b7ad4d3f7c0de724b4366f51a352bff9e638e45b478170c37f51977f9cb5b4e6f746b65656565656565a5573c9bb719a9abf2174fb5f2e82359da0a8e3d3da8eb7295ee0f682316713a9d4eb127296befa1dd87cab577a05bf7da519c4cbb6a7c34b2f66f27776f8f5b51e156f0675dac0a3ebdc5ebef47feb477de08e28d1b2d2ab7c68d1a3537725c154fc876158ffb6d39795f6c41d7d4b8117b58268fd6a6302650b784e87f7694dd2e96cdc53bb2f219afd766e076f1a2126f49c66aba63dbbfb8e2f16816f61aec8993cbb2c5ee01f2147f3bc853084821e485e86387485ecded5d9eac711b07bfbd407157cef22814836a70e959bc9523362e98ff6cac9d0e9dbbb7782c5ff15c4ebdedd1eb58dee2b9bc40715bbe72faf895dbf426f197ca35b228a98fb05c070bf691f4e2230937f648d706200bbb162cf631f4f8785152338e47b7826a7713836c5e6063c4edbc7296940f8ee3be556e45286367692f0814f004a1c3c39329de28a7794760de7947667cf362122f2ed12bec2e1e7616af46ba62916461d2857d56e2d941a0a98d414292458ba42bf64016767b67e7ac53f1b07297e7ac3c87e52f2f33524fe12133b00ac7c505aba2aa87cfc0aa88553cccb80b929cd45d3e44f519efc1e5318fc111e625a5729901e3c197ca83af944b64f156bc3bb9b1e845c9ed9b54f0d799f6401b110870063b86c2dfcbcbc5dfbd27fcd96c63109cc10e241583202087644a8fac60b7ded7f98b419b77a4e7af955f66b5695ecc2d5e84c10580945b843d063d0e49d7cab12368c3660cc370d08a27bb1844e4e695b33c6af636dd972753afe695b73c87e52edf6250afb0c71c5f55598ba7cab08a0798b7bc871977c1435c3ee32d7808921c17acc269b92a02f0d57217acca667c480b5665a9d47b68f90b1ef2f296a75edef2212998c357077a35033b8c07252b85bdc5c3ee82e4c1d70c0fbe521e7cb5c4a09924f707f6d12b0c7b8d23aeaddeca049a1104ed5c8c5d3763d36896f6cfd6d0fe5102d4096d5ced5fa741ed1fbd93ab420120e5c2e823b50bd11e79a00d99b54722b1a7bbf678245df2da639274bd3c557489be38647fb216354dbb6374efc77afa0a607fb9b70f2495bbd3eea64fbb9b0e6bda394f6bbc8233da6d369bbe93ab7d437928af047046a3de8b77a55c98ab9efa8cbf9cbe05e57d2d2d2d384460ae7a773844529f719467f3a68259517916c65a6e9be1a9508f3c92a51dbe529e0a85a5a6c2cdf05292a53de5695f8aa507b4510238a35dbbff5e7277ffdddcddfbeeb1130267b4bf28b91f3c2a9a9203669696cab5e3e4746b056be73cd8abd9dd984ea35bdabf1a59fb86e3a5df29ad0b57d3de1847afb41ca7f737160ff60a75156ff60a857aec74381d75ee2adecadb43713fe7c98cf2b65fef836264ed9df7c57ce2bedd463b8e6ec1eea6bbb76773c771edd96cf26687858471396cb5d708c4970b46e56f6af80789ed70dd39d9a04cd4d931f2b287afcf6477835375765ed4a675765e18769bcebc9dd726b9ccc3b478591c897a47cfb53810d5d3571c91a2c01a7f29e8842c0fa38be2cf461c922c79236e1c020a12225dd8e9e5638f8c4961b077da1e788894e3634d1939f6b8001058e418a34f2c12a311a020237274895308914916e363d2528ef1b079ba4564fbd747f8fcf4a08de4a16e718f6f25b19774518eefa3a51cf3d74d72fc42fe5ac9149b8c1c254f8eb711c67878f8334549142b0461498cd7d748392a95610c45a8a0220562787d9d942313f9f4d92d05e4d34dddcda90b4740ea82134528e10b4b2fd3bbeec6643b22787277aebbe966e6be7537dc46840779bbd6dd6c515eda2dccba1bed7a3953c1167276dbdd64b3aac0886a23e24caf40ed6c9202222d99674f3e458e064343434e2471626828cfbcf59ddceab5e46d72570cf79b59da6f34bd929fa1c9a56d5d4ec41ce29b255f8ff26eea50aedf2eb34bf91addaa288f251593d32b7994d7a359f27de569f0b92c33d5ad0cabb2731a5665ef7eba7c0bcc610436d7cb5f1668a35e7e9378d37ef2eaaf17b3c9d36eba3a745ebdc9eb139626af73ec76745efcc6793960cebe759e76aeb36f9db7cdcb51af698fdd4df6437698e194d49bde74725932cc5d59706f94d3b55328c309fe602620cb5b296439440a98c092b932b0c8dd51f03091fbf0458f39421b999551487ab18868070b2ece9474bb4d6f4031689b9dfdf4b06358a7ed6fb04facc31d6b4f07893d921cf969fb39f312ebc44f1d24da91e050ac135ff448b4c32e477ec33adb25b64739f214ebf4259672eab0d85700211f7aec4048d7f67a21d2c5137ba48bc3f1280e49568d5108270ae9c0f98a467e3e2e61601ce5fa2db68a54993107d3101f42658898492192556d7a471131d3284631a665d81157e9764faeb46ef1aa8ff14787740d394e8fd9dde04c22765e9e0e121efad891e434929c3e76e90de90044d7c44296968e0344557ad5c7a56a33eef39fd5417471382e4956fd869d90a938845c0fa36b4653fee20f4e5492acfa1d46dc2fc621e96aa2f6e91fe902f2d9a1b3fda68a403cb558d5431f7b04fa588743043b9d977de4022f4a179659fbccb379cbecb4f6aae27dbc304f15710fc9822f9b18dc9464519b9e1a68c38704407a308eb690298559640a675e94dc8f86a6467fda15ee94491999319226c7c25d16233ddd35618c2ab2090997cbd0688c28e48fdba8188328d72c8c31943f8e63115ac9b05c8e1ba3070bf66437ad62b62f0b4d4d8d5ef9e00534a8fe18316bb08479010645c81b504be385215ed0f6c61b34bb1b4b2359f1564ad3d4d4f42afe244916cc9646ba6c675de8c205a9fe33fc596b83226b83236b03a466c1dcdd8dc530a2faa96cef183cb56a9ecc2f67ed4d89714526e282400425167bcb114716eeb41c0d996d0862509121210614f9a3c938b82d191a8921345f3b881124332fa659f1ede180724f53a3e606b457956786466348ca5f8aa8075b8d696dc8f0917e36e43893638d29b96fd4c3e8ccd29bdcbfa24975195bfc163d9ab7d34773903640de4e4be4203a9832c4d1c3799b3156404a28f10f50c6883f29656a723450713f19194ae99492c90665be2d36276d7ad5b305673700bab063d84aa1952ce5a04dfd5b65cfe64a3a2fe9c4aa0cb4217f574683aa99b101e686472d310d53dc785386d1664a4a6443446483623670a60f89a00db864b371cad9ab86df4eee222dd8206dea45b8a227c82d1bc68e300080949b21153c4a79e6fe6968028a12474a54610b265e9d85143cf1040e8a30c60d5efdcbfe4ab6bc942e04ac6c7874d7c02512467b5962b451dc5883458e7f3c0d9a18b92947d98e0108b75bc6bec1cc29080f23670514ba907b253724cae9d1f7d1dd304b1193a5a491e50d008481832c8dc250caf25f1d91a59118b6c8f235dd8246539484614acd147745434e21c5c85286210859a6588ec0052665305902832f5e56ba14c044148cb0842fba5083315ecfe9e14347946064d8448c1e64791cf8030295b2a7f2837b5968ac68b4b8df6a1545fe58a4f0d04811ca5d9310a18b3e62d82d59b1bbfb70261e072e6ee3c0859456b2224ccb0a55c950a6650c36db2d083bce79e5e92d7435a5135bd93b1305dd4d834b27c5f08310c209655a4a3f3b431929c60621709b542f63992deddbecbae1b63695b2d730673d16db16b3f4aafbeb28538b731e76345a8fd238279df331d248699fbbd4e6898374967827b716b12e5c0a2784725e4e49a594523ecb54ca5a8a514a23593057ec25a86fb1b04f4f001562f801c893474eec8b99de46ccf4f4c2198961d8b173bd82a9d4c41f16846252ca2c07a179526146162ee802e1ce398140a41ce3e7163e723dc412c326a6f42c41689e52a6a057f3bdd6facabd86dbb47c760b5d9ac59c87490c7bc5b7571aa672ce1c844e9e196b6118156266faddc81407a179e2dab486171af81374f590d0856ac91c68e20d280fbeb62328d46d1ac2170ef9316fb0fb9d5eccfb2929ef7bc4777b284f42d6bcfc7c9c3e7176284d87d25e763a9c1e71432424a41ef131ef4ea3f22fb5f2efb2d043f8ed107693c5da15ac825f79eadb842d4ef5aaeb3ada755dd7bd7ad8af376f234f1e868fa03ebdeea9981884e6884750469e5835bf93279e18d78326e64023ded0a914cde936dd593ae7ec4ebd2062195f100c022e4ffc43f7ce8b191573bc9dddcd0942564ad2d0884f451a9d473f71f7bbc979e79452767733533c789b1e4b1477e698a9d4bd19770837cdf4ccfef4db9da44d9bce1d411de9f90b8567b3e64fb7e9e9611f4dee771ec6e1cf6ef8bb1afe525fd17c35d9de7239aa66a8442cd695558e2aa56866000100d314003028140c88046391603c522515d10f14800f8bb6466c4a17c99320c8510a19648831060880008000806024a800107a5ace6a002d651d532c20b0280d987dfc21fe6f577a97f34dc492f25c0ce21e49dd8a0e52e439a98c5e1ae4904ae53a9e34aa02367b6486701ff5a8bf5183c936d4c9dae0160a8680a5c71838ea30b8e2120114289b9bfc07ef482e8ae16d61838e69d4654097b9fd196264bd93ce426a9577028dd5604a099d99d72155b1cf494df93841b13181cec23bca41951fe9639f59499153354de76f5c7b5fc92e8d0dd1700539a58cfb244013db498a76261112a8eb05fbd65d5f6ae2ba782a5e5dab57e1c2eab78e277422bd460a15306db5fcdaef505f6c9cfe46c9351a0f41e76404a30cbc212172c8749811c74a822a0013f3229edfc65c6256d1a31e553781b896ab39c4ff2490a8c4c9e678437c0b06ff7a3ed6462374ddba6eb002462f33ea9f82d7c3cb4d0cb9c6d60f8d95d6dca4bab0ba3bff7b23428b8c75f82316ee69c3f136ddd43c341cc24a6acce4d620f0bdcbd8237a2738afb9bd02f6012950d09ee135a86e4f7b14317fc8a0ec874b381c6f714520bea498cf197442858521c23fdfdfeed71d1367c850bc0919346758a5d96125b4d1364d3dc4e7b54742f83dc3bc49b3072c041298303705284842b87b46247000f00c6af197f00b5590415abb2bb90f29c57d620246689934943cf0f2be3dda8cbbf41ac58439a6c25c08537e27818311371f8748c2f958682705f83c023f4439d295dd6b1dc00a563076a83e80f97386465840d7b4e508d1ac90d555d845b3e8c19c2a037e7d610d78f886f67e3f2d770bf7a91a55b210cd135bedf94f1ed850c55d438ac8a63d0e82b42b75b826a4e20971d47b32a90d628596b047c79f292725674414f9b44e6f890df14190f046ed8d4bf46204471ba1d6e6efc76a306c4a413d0c50ad235473bd2e2adc227471e04125f681154806f4fa61db181d0e9d62c010f8f7b9690774226d4bb8efae0762c5e16b478338669fb1ce08020f042fc6b9be0ce2ecfba084e7767104f095f036ad77ae19126bd43542ba8956493f97fa61b6f8313f78b247d730ca61c43c6326ab6e2e1b2976cca76985ae5476102f895463682cf55d50900c08fdca0cddbc9af7067e1566533a735fcfb7d9242612bcd31a2947eacd81abbc58830a51ffa4bb60e374ed071661113331107fbbd634a820daff54cd00092412c9a4e71df2dc7cfb1a7e863af431ccd17e86b3370c0a85c244a6da9d8fa26c8551bb046bfbb69262abd7b7946b768808f9b6ae5d326d07084620202c063a2fa34f48b021b4d4e0341f373803ff466017e85459c05d803ccd2c74a6d4322d4842de8e626fb157a2b296386d38065d59ac3e2f2dd22ba8a123edb64434d44670ac7fbb1c17889fd331e832f359c6d64a77d800c41c3890683e9da1573e5c3cbff06467eede2d317d913e73a8eb2dfc9e6de26efa1b0a364dcf1cb7b3df49fb6dea4c92c1f18e16641acca2612d25883d25bbbb3f01f1ac73ae453a89a70fdb544dc4087530cc3a1f08480f76f091f1d0d0b8a4ef70c7f78f7231a7d3cdff2839885334b5b59a36e5e0caf706152c5e29dd2b288b1396f5b917406e3f300ae0ebe063c543fb3eee1b7515e1918d1cc869c7cd441fd366018f2dd6ae006789c3a1867880dc19ec914db1a1f43887a391b3beb6e99e847983d5c38571be16dc21aae7d227931e8197fb2b25b2bf0a926d3ad7f6580a6f81fdecad569fa7310d9f81824a7772c8528e1f09b62b563f49a4abc4a492c19b74f7b59e4f64621e3371f6fd563f80324d142aecbf188127aad7885d07d29cec716009715f86c3018a9bd527bbc1c84565f67a7a92b94c35a29f1c70b7837e359b5e67773b115d67e5c5e4a82e03ebd7c2f569cec302aaac6e2a3ab394da869b6c9b2b60ad5e8d86310753b02bbef19ed84a5c04eb830ac8f47ba64b812a1b443814b0deffcf62d20542d3360df1c628da95e06a947893abdfeccad4439d7b47a55e7abad8a5ea2a20a75ae248fc93bd57d24fce5b9f1bcd89e0d5f07e28d01e5890554ebb014288e5bee25d9577ffec0044c54d8f2c9d56fe0a30e500581ca61827449149c5a519784c6af5797a10ee1cd5f269ae95cec25275b791a83b0206d0a3366bfbc9c900887bd017321f1f910aea187ee3659a543bdaa708a3c1fed6d0e0f18175025a4a8e88475ea45d1c490d9128679a65df93b24e1c48247735429969cd750f0ba9d290b9350c76cbf30eefd838493fc088b7280ccc5f0c92fe0388d789dd1164424af73e2283636b665280c520e346776922fa592cb5fa952ceddd89d7412f2c8fb2ce9cc079b7a04d33041dc0588710e553dbe510f5386311543eb45dfb5ab9096adf8598992ab1a791363be37f112c33cd11f63b04336ffa62c80ea5dbb8cd0a621cf817e301671ae108afe1441d6e401bebc31a9e4365af8419dae016a66cef51470ebfa64c56f76bad516d22a48ace528beeef58400f67e9bdea97cd10da1666258295c21bec1af045c1e48062bc6238d907c014a418bad39aeafc9a85700c0db7be96b63f1488e0d9aae259d317a17c6e2437b61b4f89258619165620ab458d4d0dd72134cfc9be37849c76a925318fe72ad6a730cd4061920684a53c673b9456ae651a9920e748d5e2948f9330b98313b47c81114f1efa6400d3da4ca14068d5b975d1bc5ff8ef5d8914b9756ba577d0d17e2fa874864acf9ec7b813ffb11f72ac5dc8b16333b739d89ffa5e138b5172011f6294defa2a491a6a5bdf7e40a3b9ce0836ece145d3fe38a9f677271321a71693505846bc9168dbb3c860c121297c7f3586bbf6954a5f704e0be3f4bfd7b1a3c5cde7134070b209d81b000298cc133ac3006b2a4473f03cdd8883deb616086012bcb8a0ebbe29dec5d47f169bd9ae1f03d77714edd452e9a7e03808d0012950bc2696d605cacb603b09753afa244b9b42d70029ba84c919ab261c11c225af0eff8d50ecfb7b57445d994ba29b201d8b033b8869e29efde72fb5c38c6456531229bcc8874d0914e4426a39a55713a538f100bd20764c1b1a34259f933ff83eaffeae374813a3759e8b3530c82814863c5fd8cb9339da36100513452b8d8270a0db5982512dc4f88e2bb72c232e1fbb9351786976d5d015381134e7453c2ca30b2a8f0417cfc87b6b82e241384e136f265d770dfa869dba9412d38723cdc79ce5b5a251faa7a7a0dd99aa161593c9c734db787d8fad866f325315af99e550a02852c117b2d5fad79dce481a39821134ef3e31e594f3b65e7d1e38ac1bd22008c0a6980478e3b475696390aa7cd83f40338cd2400b3c99c62d79d45888b5cfee1a63a99d613abb378e5af8e2b5c8d7b8e56db6a5454643567981757b4eef3232a49bc1f3147fdeae44784248ae6b19a9a6278323ceffb4aa31fe7745dbbfd0f30da8315d39d6ab0521fedc9f829e4e35281aac7c96ecb7cb549726397e36fcc4e786d30f9bbba54b433401296629fe4f7361a1efa3a1bd8d7dfcbf3178d513c635ac2d087a65d06569d1d23d3c2f7b0c49b540db1e3bd0957bb1115c1b2a34fa0d1d5ed5a18acde6fefc5f1bbde67ed83f023df07731c95cfe8767fa40fd5778aac76f20e1c2b0fc75469b03f05b41b28b1b727e26d3d4f9b41472feabd0b73abba982680d0208214839db2023f6d912718357bbb30d66120b97f048c49a30032a2942a4e89eb8244de159d7ebb31f92e10bb9caea60fcf8423d6dd5052bfba173e99db24c45636fb70d684468290342c32303c86d9d8c3f58596425275f56175a67f92ba575c452a795a6e64062dcc21b86ba5ff05851c527c8f0192a284010cdcfac06b6dc645941f7af6564c549e9cd053f814479ea7625fa6b78697533c544ff7518400e5476765c85eb041d26f2578712ff3573c11e97bb7a23c272a22c6b760e52b6b6a7fd07e49b32077ee8f0c1cf77ce23e9489998dc9376d6f4d575075fd49670465c10d31ee162419ae3517024c7cfa972281f32ee74d63592d7f44f278bace307d688ff430689d5d933ff0255052ca0865104089d5539b900e597fb1847a9f47f9183b482712d80c5ebe8d29f398e4cbab87cfbc24d176026ca8608b4584223192301e0e0067623a1d3c36a0a1ad87472e845f8c31dd8ac08111b27c3f10b3ce39d6ea8cd5196dace06743db450b424883ae4d9f6872fe794485a406359a61645c0747ad76c0bdaf5623a5cd350f6f5b101a3050dcde79905429941ebaf714ca5737d04f07d3c0378bc8b640b466f7a4da8350b3f62645345b635e37abccace74311d63074d9461c6b27073caac4f83a3cd1988c62b63dbe3971bc994b15652a43c39ad3cd5a292c495d2dd5d57434eaebd0ee5ed1f0c2abf93d075b0d70337f2ef773a498275b08050b0a77a5246230045603370c2533647682d2c989c27931a46b11d55ccc643e27f9e9451a22b05c9a4ea96abcd37b34f2c0bba39e033992f2e522e7f5b6bb2d66b1acd14618f18dca860cb940ddfdc20036de3f5d90d46122f0549dc55bf43cccb8258c068f2b69d0cc35306095d481b24d478e1e562408c8671a270dfee49249e58b2cfa6dbef5e6e2366a6b17f303eb0863add3d5510f9c847bbc13cea1b0957b67be051a07ad6f8c47fdf11b4ef801babe9ac7d23e8e58d0ae1f4b3767e297c84e579d2db1f69335c3dc5e52d61af93e79fb8550112717471e5241074e01a2d1e63b0cf0fed63d65225509c3bf7d84d876976f7ce72ff2ea1daef9418efa7cbbc2528e5d4842c6a706e49273dec0ad877c8922a2ae4e5567e01e5c44f4f12668c31d4e720d32ce5d7ba59110de940fb028b6a03fe2178491dda80c96f310118cf4edc5505dfbfc3e639debd813c56478e04a18e14f820e4f3754fac7f57ab0681fcf817e7f41f9fca9510a5aa30f6e15f20b65f783c895d04f81ed0cce82d5f9d1326dab4bc49fcf17f42d8c8c1b83b32df6923c4756f9300b9a8ab84473c2b88ec606f309731efa241daa1a57acffe97dc51a49db491731bbfaa2515dd8b5ad28d57a664795b55cb87f7005752d5ea18d17d1beebdf41ef6621de53e260341972560a24dd48c80b4778c12c11542b5a2b72bc07e032288d0a888f478a9445981cd8d78751a609ad0f1deb57f70a3c8fb96dc7022776db4d6b0b21d7487432168e4c627bc64730ad9b8c54313f880f8ff0abfe7694f2d24c64416698a599545510e2eb843036d56d9ed72e2364024ca77059109ce40c1b05ee7245c35aedcbde1d8b6308e8d814ce4c3963828fc361f2f8a12313103fda2ab1859022a60514f507ea2da9c91564f79e4fff5214cffa31a332310f869df139bbffe72db1c642ff05b5ae104ac1b81f9600c207ab71df841d9034177dad18fc446f2de9acb8f8f0304fa8b700ddefbb8ffba1bbdba8aabc9370365e8fc0d14a9eb0f2166112e6abfb38eefc025e9578ca2fb70436003c307fa2508fc1f1774411460b20aef7e9cc1e6bf4a897098fbc9c477eba44f0c3f14cb107cb00b75675a0edcb8d35e9d3daaaf45fbe6643204224608c660ca119aafea0f64437378b893e4531b0a31cd11efe6a8551807307bccb601de850b24517e808f5090045cf21a7a86fbda882ac972c35d0c0938375fb970b6d19e6b53f49c10f1292072f858637433b9e785168747dcc76924398788bce18763c462619e8d555f07c1c79a4c3304e99d53c575cbdb5cc08decd004b0da28f317ee7ed0a1e85e532fa5d62ceba12d9725cf3268474d245e361dc424130ff0b5afb134681b06914ded60e878551ef13d6cd8fabe6bbed881c168c89014d244d9dda8747d7b77d308fa1f8115d6ab3216d829670b7051d8c36353876605e5beb8e65d896006668c918610518dd32bb4e20a52e08481d19b7682be2615fcba2b418fb980dce72a3f2d85aca4802ff6ad861b200b6652553819ed307fb2cf3c4b66ce2d81febb0716dc3f7882191a4dfa3a1a59ddf8df1bbb8ce375bb4b3b6b60de6f0492ff2f4b0423849fc3237164c033fb3687eac77c58a300e5bc0a909338fcfe2b0bd298ea0323ec406c04c20acea0d9e0eb7ca3003b69783a825fa4e99d67a0d7747f7897d84d54efa558a4264ae14abeb4fe9b52694956b72dd740947e004cde7bdf5ecbbd764cd1b5bf18e8b99d4827b6278209b24268a240a1b78c2f710b0a033921bdc31d1f89904badb8b40edc5ef4e7d8041679a1841699e7193e7523c1c0948ac46b195a9e2c8e308ffae0fe5898c951d8d25f14b9455093210bc155ff4c00c4287fffd9bb3d7ef2e06419694faef69200e7563145491d736e26d397036afc76254c7fbc5123480bb8d40b850c79eb7638a9289099cd730d303c9841ac4925fe6d4b0e8e84bb44dce5f526f61c914062f19898fbce8654a58cb82e5161e7684165eb46a54328d0f83a311d98f7835fafda7ae3d449032cbb7981824e4e8200c781fc6e88741c613b856cd927761ffb4d679dc31a483beeb288610b32c5ccc42c3dff0f9e65ec7ec4aced5c9b115b2f15d216b0829d86cb5c29a5c401611ba8371bb9a8309b40df69412e3c982f1572c3bbb52cce924e4418097de1247b9db7182488e8d8924e07832f36f77a82d8a49fc5ba484e6286737c458d48f0c140c7048749193d2172033e0dce65d15463eab78b6191cd1d37488aae14fee60daa8d2d27ed007f004a94feb383de2919a6ba3377be2177e57957a8209d03c757da4a1274397e606df95f5e3e827fe1b7a943467223a3cab09f74967bb826c1ffb80e32497716a70020b8dd2c3da3c68f9c86ffc01c14d0b26f62a564848e263730e3513248f1a249ae9dec100c4871175de2a17547201d4d82f0945724eda3295e0a37154d81610586430612e365dd7342232ee0b7ad136d1b56f4499d81c4da12542cba8230a48ae6c29e5aad7700f7005769b05b1fdbbffc7c561c6c04cde566fd995f22bad951259da397d3d4f073cf9285a7b26c290426d07d53a758d883225c40bd7ed993fd3e91809e4c87d468fce3bf38bf205e4680883f52c0d329d37fe45236be202346532671d0461ac48a7cf1382b00f1f09d1bbc71bf3ef102e0501484800c27380c4e72422c9788b61a4d2bda8abf1363fb75b7293cdca2213c5dd5a29a4cc5d99cbfb666d81e88064ad129e1020980a3b7e7ef9c4c4253f1e16086ec05a1cb6ddd77c0e74184a4db2ef3c37b48a2aea016683e4929e165a045063525e5f6f7350729e7e9e699861dc84d81ddd6ceed10a3b5e0770ae672fa96e59ca90d599b314249bd530599121e4da7618438c6c78ab286f0810717ac26f572764e931e1e3375814f6fa530f3f37e05517a8ce5dc4d3778645d167397e476821dc7efdaf74f7d6ad6afd2ac70f07dbfa083f478acff99fa028722d2cfec4dce2a40fe289a6402e3232317bd5643ad3ae22e92053401b221e9ded74508ae7091acc9554b70e0c6577037d74f71619a2df5f1095b7e4c58dcc805e47a9d1110c7145841bb9b849ac03ca2ad243572eb2e21ba76c021522bec736260be63e56867d02190030531bb53d28614a03d1ac277df14ac0804a5c0c4ac893ddea2fdcf990f97590b993cceaec9759e4846ca9c29129f84edd50b51f67660cb9d29b5db884b22bf3e5d892deeea16ab93b1fc267d34fdc4d491f315e9e228ca0ed43567606d36b9bdcfc61f34afce8a4ef267c93143b6471818ec5db54129169dad331a752fe8169ae1918ff8579828ee3c7a255cc781615719443fbd46f675623795a3f6ca5bccd4f66f5c723710018b4b1745e2b4d3549dc78b0eb33e534d7c821ee2394c683f0507a6dd0132792fc3b02b57bb098f00a4c76cb8a8f6010d9c82ede3c20f3323bd44919124f24e7ad6e27b2f595c0ec696544cff94d1a2bbdff18191e291a40d14d08dec208728b0a7542746fdcf0fc476e2d66cb7b7a0514d110f949bbac09ecacf33c9d93edd7440eca91f15aab1e656de94e3a28d73bd4822e164394a470445a9f3e35c09483addf31fd41245add9cddd3bcef51d3caa2533465761c8c1b9f03bd148cbb5c1a9a7ba2e4eee9790b47e56b5375f06e8e4f8582661655be3cbc14a779c85f942439712c4260bcbd0d03bcb033eb57dc0505395094bc0fc35254d005571c639bee019a62bd45cfc22c37c837e997c3b0faccb445593e566966e3051a52362be0f06ec428138ec2901a6a27f8059fb55232d4efdf0dd5a56c417fb97daecbff63bb2e69e3e26a3137947767c3802745ed066a6536dbdc8a73f59aae683716fc1d6f2de8b9754466c564e90d2028a204a2da7a8afcf280d7d716973e6e12d7d1bba86fa44ff81a92985cbb598aba69017d41b64ffb7bb16b4fc20f986649324e09221de714e756030435ac3a29260aa61d9fff5a73fda7b9faa25d0c7d798cb37d9353c99d1f83e25fbc44a14465287dc94a11b82448be8b03a19824baca5079884d4818c468a0b36cc297e81882d226131c7a4e552b6367bbfaca99f320422286eff423528ae6517e60252435d7ed930c4740a9049ee48d5ff9cfe42c34000ff7275117327f96161845b3ce9d7cdcb5d0c163f5c2839c83fbfc6d8e101435ceba567c90772cf0e2690b43b4c24f551a267e98d9432666c5d4246428944c932f5204c8cdb4775dccaee38cc7b2e8d65d7e95c1ea4c4a962bcc0e32c178c7803a82852a536088653dc0371da26cc5ba20adea112542bae4e9e944b5976ace90018aa48442f7e07e1322f734b72eabe548645d1fa70573202447fdf99ffa256ad0eca14c58f9faba076e11f95d7daf1407d0cc4a3d89c50fb8e1be3b325c2c1e765fbc7719a0279e954984c16e603d9bade8959e1df187af9b9e269dc1ff80ce25006a5b18a0c809520ee5044fa023a369cf80ff1adcbfe1c8ed48bf0cd8320e9e03541cb30a1bc21ff42ad12af031a3c66c10932075f3ec35d8c7235f73430304ba658e344fb0c7d5e2d74390df0ce287b7d845ded229ded69e370b30a6629d0aa5e300c66fdfd9240397ff7081d0b2d7558c885b6d450336ff722334bc6f096bd1d84aecee9404e06b53f26d028a3d8353493024c609a3751fcf66e6b1f18943b7b82a28a0290d6e31227f02514bacd92ec4b0b92631b72254935de03113cae69bb11d2237eb86e5b3881005009ae8a43823d549885f972ea91334724221cd7c6f9181936f47f1585a4eca0e8f86a4f61c25ef5a35cacedbbc06ed00ca4c2d454050845c55501bab194382536abbd3e20ed8730d07ed01f30305716812de81ab9bc908dadce3d7aeef357baf679784840000fc16dae8bfe1dc535bec61c522e59c1d583f03b77f3037c1e2cbfe45a269ff8ff6c12205f926edd6763f4db4822d1c064fe27a762fd508acba0f0013d6957c435a449408a015fd51f0a2308aa1c10cb3bc178531707ec8800ae1d13d10680d07dc9b3e289ccf66acf0e4471bb66ef504c815bf68ddb4a378001ac61290ceecbedbe4a1454e83f59e8a8ed626a210a232e708149c0465bb0803f4cf5caa6f89d45a966093938d255bf63d1cc1510e1290011fd71b0550f017a7bb199803565368a54781d21d47d15ced604827db6b0b02ad0dd54401ac645288c3c549e14568e353e15f79fb4c64e7e869f2074833302c0400c03e8820517832fa2b4bf825af38d730d0e60d3502d39f7d22f86e077bf5b4718f792b1edee19a121ec7994d7829438809734a5cc54f84d9f584698e70f7374c334759b42fa87f3575b8a0f75ca3fcaf63e603e3521909f513258f243c3e21d290bddcad00c87fd716aefbdf0acc2c5e5b059a4eef27685460b4f384bb3ba245f16d842afa3a8edb2f8664ae057c492b662cbda5f4c5c5bc178f6dca69212c4dad57d2ff2535ad6509d7f5c080da1d9086ddc3c2ff4cdd1b154c6ffe3e88388e3ef7b185f7827d86c3118ca939e697d8ffa8682bba39f2f6174723bd9278a8cc2d0353d1bc2c6c013e8de8efb7cf2e6bbc4ce47ff7ae92888ead07d8079e45b10edb4321310c4cb2e32077a83f2fa4859f382df9c0933c77858ec55069dd0bac4dc3d33486bc197f52353a92110a402042566f9b9a21b278b99ad320df7ebd895d1ef886e13b8f7cea6d5f804df290d69abb26f3fa01445d810ab6c984aca7b99e38b32ccbf69117a07bde3917b451f4810e2c324e5ae7cebfb30b05af6da96431140336e2875dc7cde7f65f7e9908ed6ed7d13afe6e32b0975a68dfd9018b5c1bb97921a1bace3530a960ac77d968e79cff8269b4108c5a1d9f057c1d5852625b0f797b704a803679e4a86c1e4d6411050534bd1fa5fc53d56a05bb992c23a9d5d8bb0a1e50b0c9117a1538b1610444af91d05082b0040477213a77c2eedb5b5f069d241c5ef02187919d72f2ec6a33a11f5456bd123b8b21cb774bd5626dd3010c05999e3dd6549480f0ca2f26b872984bf9192205c94a41a38dccadd139f526cb47cb573dfd2c9298b8cafd9e40b6d1aa72dc46b1cb5546edaff9d4e2f6f55f03f428b9e8521602745bc5e72b860620555c3adb605080fa202929553cf1299fcee12e479c75f6d6f3c2f1fe2eb036f323676de4e291e97e0a1c5e6e1c92002631e91e2030b9ae32b933a990516856fc2c2398078a3d0b51ee753fd8f5fb9d9a44f7c2cc36e396ee338fe7a9738ad871a4dc6ba5ec26c527da007f6f3cefc76c6e204dab9f361721bd6d204ba1b70bfb45a0762c8395de35d1dff5ffe457a23e8c69afb979cc88bf5b85f2ef93eacd9514c6255e94d2d0f4c8b3bb16c029d03957ff8ea35808e6a4245ebfa004f95eb122d3da58548875f9765033c5e52a8ad25b3f5eb1d0310f8d1374a0271a91a34736148beaa4f49112f7ff0d54b3d1b65833d114b28294665552730c4255248a1660356f26829e88f50eae7152105c042a87a8c69417c1b02140cdc183e7672861e7e67b934510880d3acac4021c420dd02488c369e0636133d4ff521884927d06b7a33a6427860f8884ad8d73f56edf66462cb3913e683bc37ba38705a2c8f594432850044750f5a2ef342eb94203dc2192c19f35abf5bab61e0ea8986b41fd8ac98d47280a1ce0d802abe2b2e2815fdbbbc35b340b4f3db26483502864e6c15d42803c3575a64109991ccfef6846cdd8fda95b517c7874ae998a6a320a3ccd3e29c2d37415841ec1c5d2b20a1389b4a820a1a8e068bec8c5182ed60314375c6675058542223628cfc30c906d44be16e4e0dc87e1ce3a1a0aed480ef2dbcd2276221c8fc090f7ccd06bd34214e36d4d11119f15e8fa1ff9fac668f4766ead8b83deff3c7f8fa6c4ba56f8de2bdfc8979df6cd20a9fcb908133e6dfa5bc9766f67c95e2c4af040105a4850389ec990cef55dce3c833352aa11ff9f06d089094b778fa84fd918f1f53ce1902152910240f8519b0d5787c3ae9fd96f72a4524b6b85f0dd1fedd3db005e4922d2060dd287022800c3cf8ed2ce578f20bb2630e49674e34c1eaefcc875b87c3dc53736114507e0611e8f7932dfb5f9b35898fa01b541362f84d329fa0ee4c1b6933a05cc040f78d06526ae999ffcefc80ef18cee9df275830b6fa54ae93e5414e69a29cce6402be5dad1b0ac59fb3ab01a8b585936d920417efdb771b249fcf2b01d3e572de5e8223eb2ecd39bed5f3ff96961609569d59b2115ecf2269122c9108027553189acb6a4e40fb58b166fe9f2c8400a0d47fd13ada33437b74a310cdb91d23eaec9fc5a8351432c695560c780dcf7638ebb8a3410f292cd2b8b639b0de218e978ab1738a50821b6c195947e427cf1ae062fc0ecc30001f6edda63020bdb33a36093e4900253476f07e70132c30397abaf159cf910019f1e04ccae0145611858278e88d5f67c0916707f7375be868b4faa1e9791a4a6cdecf400c6644b8294324a1af66ff8a5a9842aff1755b241e34806ae14e27cdc84a491652531e079ece22cefc814881b92feb96e4621bcda96e8b52e139762443c7333058cbe748a57d38307153fa6f1eb5f0c78936a4a052e98c9a6d3290d203204acc81bcdf267fb7892c09aa4cf5cf696d02648edc5f3a2b2d1134749396a660014c635cf39e54b73d552180b9fe22e40534a8e320a0cc1ed36b10485bc69c678c1f529fcad2072998bf8d5d3c520dac540e360d8cf9138939725f7a23ce9c76cc933e2f76c3895a162f41797f52eede007d53c9a5f0e621737d1941107169281c6a5489af3b5473bcbdf96fca898ed3549e335d940a4f960b3069afca8ddcdcfae27a1fbb3f625e62b39703329ec6a4ce135b5eed6964ae98a3d98551c563ef296ced1bc672d677ab2f3b4901e4a9d4139c5cd72bfb9694803b0341b32f84d101cd409b4db02ba285f8174b0fe35e51d35bba4526be087dd11636ec1646408db2050c29338c31f88d8b1aab0d6140a42dbb7cf21ee89b7354b22b99ff275688a8e41fe0bdc275e9c68419f95f5df045b286c36f6b74cffcef4a148ebf1fda2c942f46d0d7a3d7b034a82dd5cc910d22828fb065c1ecc45ceae6cbcdde80a501eb63c5737d91d34e6b339a22d9ac9dcd396ac3d54fe0b5e1f9bc7cf5259d67391ddd11fb6391381b14bfb918ade53c4c5535ccc82006e4c7b02fb7f6474ac7c84c6f4d15465ffc05f0b9144f50a623a19099e071997bdf183e4b141ad54f038419dac3055b162b02201c9035e9e494253b97071ba9b279c5d6b8e39beeb2721cf59f432df7a3a15d7713f81850679149e02753938f6909e092f598ac5d93d9d9f85855e00fde40b6d40eb6f924a45770d004aeb64d6110258a0b787cb4a3a0eff08da85c764253a154caeb724b0bb6c2cd4011a311b556027927e282d0c00739ab6735b13da59b94d51ecb2816c886ad7d509ef8e7365f09598cc20660e5ccf36ca0c1920acbc7e68503bb16ba51132810ca71febea223553ffa61b18acb064e7e56a81eb67ed131209642827cafe8a8e17c606474a8a728a68ed524a821aa973a3a461cc738040261c8a2112598830e19d177b932d077fffdc6ffe1bd1a0056b93ca314ec48f9b718382f2de381a03c7e895d6291a7f536c139f60b380eb19652006ca0681f7cd3994c29c8af6d2bddc808ddbf54c4c1e4a731508ee2984ec313347b53ac3f436bfee27435073af58177559769af7f651415f8bedbf46b9f50a29cf869ba4af49f89b8f700b6f96e6ee8bf8c3ab9cd70d039c8fc2e1706b633a05c10a1504c4537b7d0f1f1103810b92885c0f630e0d98ebc9b67b0f0a206b78eadf8de013c4e34b479bc334637a100226185b469f1c29c48dedc7878c3c7f1493b0dfbd467c282b6de695854a8dd8d0085d7231d446a068622d64998de18c947ea6a9142fa91aab1204cf3620c1995fd07ba1e4e45358c922d43465898fff6990ec023ea38e85e812a808c60cd3ad1f220080e96c33189aeab075038d44ed08cd7ab81e5fb7661986a98f3233af6478f872115339860802271fb2265c80ca992076878d75dac39098625e84756c2ceb1117271d566e89a3659993f04209e7e9bce80f998f5d8a211673f45abb630202e8485eeb13c9eee22e8d6e38e08b64a3c22fe5f37a63ae5409b4592c20e1bb80ff34a8403c118dd5e4f8adf9644d7b16d470e1829e54af45d639226c72d1a29b7149c09d0733aedb16407b4aba566b32e0040436d39000f574a459e931a26330b7c2f66d7710ff0e0c118e201b9569ba110b1377cfa80a5083a1414f23df67cb4c982259d7e472170bd9258370f0ccffe472b06ddad359066da030bb8515f59b7a5ec06a18014b4d4297c49960f329616035f98103e6442c13721d6cb11e706f5b3bc840e51020fd8d15c7c03e017ed5718d4a1693a8d9617422d725d8c9cd734481fc8d80634604858702b8c85afa945a75e0054ababc6218c8651223cb3644afb55455e24ab9a3fd5e237f1ca84a6bcfeca2e29f998943d416f960183bd3ea20fed9c6d8c4fe9525889c0d362533a6b56b9f8a0099c1c0d39811f2c9fccfa095cdbfae109a96d3369fe6f74329d711179a2b9e101e8de5be7ee3017751e9126b3c1c07d312ff323705de24d0b9b0ae95a485a54443232df5150ac22e021419f20d96d5e577a895918e5d952b517994246319c7c9317978818f9e60df6d381cfa87e2ee9f493fa5d710b6246f26bf4714aabf0957f7948d4a2aa6b56771e3e5e60ae6646e3f2219cfacf0b0ab344707e046030bf9c7ef3232736102adc1db4761ca62670c663c8453c7132c9f9ee8195d39e1db9bf6f7160c9a14f9febdbd4a81ceab1066db6777c1bd967182aa0df725d2a32f711817ed30724be76923e94cfa09e3cc46c1bba5518cc5960d1126c24aa402c86a6762aa3a7938561d0dde9304145d45ace88facd90ffec0909881a6a3eec09ba716b1069ba34cb95d6447013dfb5b1f5e83909dc9d3a4648c4acedafeb07913aafa932839099043ffe4d45e8bfb78db805ed33e9d1d61719e90ced01035a0ad3213bf77f3ddbad48689acca843d32f8fb7d5d7cd114f5f67a74db27e1f00479c46c98faffe756eea4ffc8eeaa938727eea51577c07a9041f8728e12906b8c577cb537d31e066a8917faa2fa1bd99fdee39e7fd4bed110a5800b66cf55a82b85ed323e5db0198e3d836a80797a4a96188587542087af93873751b3411fc55d415067c3b9aa4392564e3a8f4bef99a4f4bd42995ecc38c1892bcd6853c7b8f772679fc473dd23c642f740b4f33315a203e7a5361ee27bf27c1f11a1bfa875647ee6f479f52ef477e2e646b043eae8e99d0b906623f00c9e2dac7ae89560e69d79c220350cb01e250b9b5c2ca9767b80fad11f4060d412490b2fc10d599ad39936fa05b22a5e9b23e661aad16518f70c3511139653da9f926c81d7fc1b79fe521f7fbf64705aa07b5e866981e2b7d395f9ee1f1582d6019ece8bdeae0ad744adf8c4bfef6ece6a3bd80619719cfe216c4053a6e12965e9b8ee3c64ec1f87344915fa259e3f52cb24fc3be699a06e68ea01006a12ad188aebf68b6187eea698c2769ae16cfae83e16c62d7b7e7145830de10a9bc91cef9bd3c0b0b4a51a40c6faaf8da299d221bb0fcd1d0ec12664fc5714dc7bba89b78f70be19bef52506a8d515c7a9e6d8490dcfc02d63a332cf07ecfb89b6f91df9c0f406400fdb5041cf3bbb4da8a1b87bffdc9db3cf1fa666f05c848fdbb3c49023f09942335c416d8a8aa4bb7ad38d049c0d3892495677f3798d62e0b5622f9eeb70b334ade61ec2f565098a006d460d8432879f8c855a13b4eedace4338bec18035d2e1bf48ac898b7672152cb7d1401b6118a9683bf693a19ad11d69b0d3696572abc8df1db2d18b8eace131ba73a7eb619dd3106c066db9776ebfa8044b618e26d8cb17632932a2dfce61cfbc5326fec1ebf06368076ec176f288533a69c28b3fc0a0d0fdd1febc36c7e8f51c6183c88c1b1b0216c7477160f53430874399ce3046de86f40504874781cc3a436432cbb11762d82135ce93c5033f9cab93fbd86d6b7e74487616b5944bafcf0e69c166967bcdf9b921310578cbf9a0eb83c0723d6116d67bc538a0bd2a1f5ca621c1f742466f61c3ef5c8773c4123fa6463bb9329cc9fb978b23ee8d431caa290c0d8161f01ec1316e2c68c03c8751b39a1a56d882f6a53587615b8473ff3503f4cc320d6b17626bcfc5a9160ee5c8c2781210e67da40f95cc4aad7be09a043ffd8a28d6d517ebd7df89c75dcdf63cf955d74e5e3b462f5c54b9a95403c793649a5bec6a8e59f930eb1bc09c271a350a9c77b911ad160251bd15e45023f8c3482ce04e72cc06f4b109531e02513903880f8f2b545c367e4f23d7e7da05af523eb7c9594723e51963216ac66e2183a9c6ec55492ad626a8a0a8e8b18cf7db8950c0d9b7d8b63e0a057da0c2d90bab222774f37a6709f8ec8fdc94c72befaf39b9a7b2b3a49234e61e7778f87edffd3e6e7ccf6ee07534330681e077fdfcaea8272134783ed2703cd792d78e4ab34db7fb0840b910c40cdbb08d0b20bc0cf161c2404d07ace3c3431210ecb147d7eff1a0314764fbd5ee7cecbd199998fcc193d496d96e23ed6dee054913ac8585aa3ecff4f73e62ae07c1d40bb40d62d5dd9ea3745025fdd3e76aa047c5a27d9dbc3c42c9feb1a42832a4c4a2184ffce6be0117dd93e5d9074577f668a633f32e1c544b9fef28251658a536b6320684b6a8549115a99b4b1fdbe0befc78b487e5fc35742363822639579300dfc072589f83a1579416c0f5e770f0258985ae7a15471ee083dca7292fa6ed3bdc8fb831d38d555d84fa77fcfe682cf42058ec0f3cfddfe7bbe9ef5bc00a17162b93b4c06a0e9408a259f3d1f5341134d1aaf81a3e8de301ab7be9238e9edd1f64a29866aebe476fe4b1f14376dee1ae82f04508f7cb4fe8a6613cc8bb4794adc43784545b5f27b39a1c5c040433e054c7880567bd6665a8bf2ac650aadddfd2419ba88ef8d426f77ce3b3d3d97809510af688c483753e9028be26015eb5a52ff78c0615150b75bfb1b146f66d98d0e8b4604497893d75661d18f38010f9209e473516a1cdc4173fff6c86a9dc00a8f000e2827c88c59d0c30024f4aa6d376519e1c92c9da8a2090381197b819ebab781037770565d79e855811588358f59a9939872270063a20c7b9acbdec8d85bc77ff045470538f00109a61520aecf209c02bc4d1bb23d2ac061948f3aee73a7cfae2600b7f09dcae22a00475db6ae5792b92151a566f80e20757af11ba9cf37aa675fc956728acbcd2835215f9bf4756987f4eb2550a33b643df494e5ba1cdb869b21060321adb902b579a37bd51c11e1432e0a3f28eb48ba0a231ad3c5409aead6a6d1176e54c61bd8a260e6cf9e0c6e07908ce88b11e12b51e5c84fa7a0304c5baae23b00ed0b9704ac4877d29eed554882f2ede2886338355aa4269101828e46cd3642b2b18f12c9488567513b96f6a0b7306d178330d2ff348eba9ad37accf43657adcd86c76c3023bcf9397f8eb918ce97cf36b95e9132dc5b795e70d5074c5427843c51bb45be5fce571cb495695605a975155793e8ed26e5df0389d1b33db759d64be785c01f0040f097193a9ecb598dcb5918bbb7fade605dc36265dae8a25abf31af4e52a0b2cd0ab2120e0f45c3721150d8e49ab4c3ad132f2a9141fcb5580b51c0e012009023b33eafe04091730063c2818f6dfc9c439e9fccacd50d11e8b1928bc0d4e7bb1e3fc152df44b08b1842261dbdf704e87a8ed2d2ed21bac3996a807916953883a260e33aa3ce02ff58fbfe58ed95ad9500f67d375e308b0a049969fea3b3ed3e04b234a76a647793f1d9df54e7b64179df3eb24f289b1c564df1ae1241d3f6d091d4b307c71b64892c7204e846f880fe936f3b22e2c84d84ecf433bd0e78ce5e8b8c7bc6c3af8697a87309fb6702ab92226ec234bc941436cf2dfeeccdf6da819c21bb17c4f7c91df64cbdb706e4ad074e82e16343648344682355d3f8395b6c1b21cc572687e574fba61ba6695d518772a3910d93681ccc108986b237f5a3b4dc9474cb5b47b9527e90bd00b80516909999585b9d3761435c880d41994910e2a71ec1b47f89359d1acae0cdec3506378c5067807cfb5705ec9c818213b72e48d071ef098f2fff5a3ef31c1c532173eb26b93ceb1a3644803e329563717d1bcc09e0feefd5676cb0176e55ef06aadb363404149645162c6820be0d7b7b20ebd638a8538f4fe8d01ae8f56d68e7a6a18a6078ec4b59b9f394d3a35ae071b9f76df0caf22c7c7783534c081f34d03384c29e05ba82f304338574202cba366c6d3f2b6a0eb583fbe929f6d080409e1a64362276364c11bfda483182c7a1d0940f665e26691c69570d4d2d6f9f891de28016a73e11092680ca4396b2abc65482b8ed3ace351774e05e3654f25908bdb465190813264a148c460b2e372032e57d49863d872de3a2c021391cf5aff3aa447446c673953ab0bb84416d3c972015601e1dee302bd2724b7d297c78b4e406ef6c809a7674ea651fe61d3631337da87142282d6ba40ceb5d4018744699cff62c1e60ff4340bc04606e08ad36cb005ebd259966c3dba05e91119563d56efffa2f5b786cabdc98aa4550d07519841c6874698add9c2b3f20a560df5d060f2f9d8dd15ad07886ab12990877b38b7c9c35b04017a6c40884d48906c0e48ecf26fc0c6fa9244d0c54aa3475389f70f38b058c9584be3b3169920b8cb71490acdced7736d22e0c1eb84cb2cec54be0de70dd2261e7155e9f9fdfda61c10575018c84b86e06f86eafdbb72c0c3172146cf3238db780e667b2e750fa17776a6e324dcb04a818e9f8d1487ee74649bc8a554365ca357534d2cfb287de78bfb83194c421a9536ab69733834ed3bd2574dc3d7d0c0bba0e0cf4b67da61d527c3d3841f5b3cf5154eb2441f5b8928ca583215ecfa2f5123fad4ad3d0753ddb6abc89496fe569fd264564c41da9586565fc1e24ae69c2cad203ecfe3d6c94074cdbd7fc5675e64ac1c6b20ddbc602e132859da7f057be5f519a7db2c2f273d7462521b017156763d2ae2e3e5e4fa63cc3d0f4b3b292dc84ceee4477479d3cb448176557f57c53042234ce7a85d6cb45e1ab10dfef097ad0829c91442032a960ee764ebe53147bcd3ec38a097c6ff96e473329169a0aa93f166b056072a2a5e4b4baa5dc9a4e5bc7b7e3c459067d58f392f7aa7338c2c94605a859c6434e0be3f1cf4a9cbe20d249bab942d74195930aea81d68ee2bfb1a963f00cc6105a6775753815a5531be30c5d01b1ba0797df1027875fd30d3082739d22755f64642fa39a0a8e5764926a012e7764659a5e8a17de069be59a836ec9ac92c2f212213e60ee8132abc285865ba0e3151aa800de5e9a85fa6adaf6d7078958229ac63dc0b47653ee80f06bd2907798bfdea8db7b56d970a26cdfc7fafe0f1b93a8a1cc5d798218893d2242301f6582c653a13963edc64173fad4bd4434ba97bb18791d1d31478506526bcfea179132b58c967be1e3b345946eda63c0f867b45452dd003cc0bddc4a8808f16cdfdec00c23e1fb76a55d662b59596936666463ed62df415ef0cacc14c0538ec936b02a602cd52c5cffcf1cedc8ef6a5beb6586550b1351fbf2cefdf9cdd36ee1c4dfd32c3b0cb629b5e49f19e048789556225f972812e4d5e639164daf7b57f8597adb200ebb5355839afab2c0fa85f6bdfd02b8545715815f64bafd379c63ba112d8a639ba91e00fb9d3c866668acdde1d6f99dba0de53ac4aa968f81469bd187a57ce6d51584e4c641620d79545c84792bc9a9d9cb5d5051739f7e90c9893baa4b2088eb728cfa3be674d9e3a5f136d448d8a96b27a33e33b26a0c14fcaaf59a9cca845e004d4b0be56e6b7c9a0f3a119f091ca00bbc47a2c8496749189528c8a1a3cf2705485c7d92d53e6f1e6ee3f2777f72bb00ecbad2998a39e9507376a0f79d8d91dcfdb8a663ba9e947c04b4e99cfe55734ed79b94fc08b72789a2e32da94022c7fd17ed8d8b6f16e9c11118f5cc0ab2a4645aab014b2b65dd52e357d7882f54d371d84789edbf8c18ea859d7ece8721d4fe0faa92d48cb8ff52f3d35acd8063d8f33a55c437fccff7347d40108a1834749841c162f1a934f7753217746141010063c395f230b5bad92c1f2aa299a74deb4547df9c608333674fab08666c9b06036956dfa1acbc2aed0ffc61db988b4c276e802a28fe30e2c4a4aa3e755e18abb29e6e97ab1444cfc91bbfc2f46b0816a96023458ab1f7d4cb5056e24fa7940b06ee03955d0ab2792718774ae52a9d47724a870d07fbaf0514d0010e2d563ec6801d111fc5079aa58aea3493a979e6a550f3c4e6f30d3425a6789ede6b268bd0c118962b1c8c2955c54cd2d4bb50ca2ff6005d5c5bcb712eaeba9cf14653bf74941ab0642fdf1a42453c339987baecb5c63ca57eb65154c1d57f477b3d0d72b1be7adfe06412ba60c1df23ebe708f2c953eba65c46a51731d17ec4a4cd62dda6d5dfb0825817fadb4f6d27f51a91b445b462f6185858f1fc36778ddcd8680445595f0fce76025225d830745c6ac6ff759c5d9010852c540c36efbb6faf8995a5ad2f1318525665984a14377ad855e5f6a7ede6568babef1b3c918ef7189036d0405f0b5cda7f8c3b028b3740ada00e54ae6ceed5790e523aa5df903880e79a751124f95e50037eec82312d4efccf28dbebcbdd27bd6d8566679093c17f9c7e06c8630df870acc9c4917dd05cf9d04d5cf79250b310046c55d1aced1b0c6c957330d3a84fb0cda72310ae166a57eb67c2153a0ff5851111dda43b5c12783964dc50db82b6cc68f82d9d2e6bbf0408a2321f97c3f61db4e47840f8f20f4622318b1dd073139a5c7ed029063a82a064685116ba67edcb5854bf476139ee87c33fc66d620499d720a63c705eef8b33808906ac47183ed80c1896a6c7da160d380eb24fd9ad73c4841588386c4d6d11f8b0c0b63f7adaab24fba47a9131d444365c950b4f9f88054fe0ad3316449695a0a94bfd65c723f8121f51b13b04342858f828a29e029faf505d77eb988e66e839a05f3a6f54e91a35df00bded656ba0d7fc8f8455df8851024af36f116b8e7fcff4850cc1e8bf47db1f102b8b6f9466a39e3d668aab657e7e8470212e0343862284e1ded227bea48714c4d0358c2f76b4e51e0e030b35ee844e2db70209b068ab87c4823537428dbc0a70b601000b4c39b9156a7e9de944f5ea76bac25ca3f06cd45bf29a53234144a0c8f030e9797eb8b9b3983408ff77a0fa7bd6a8fd3135f5d3468c2e632d9574d666173b02d119fa73e1715c3279f66f36e4d46259563422ab82dffe336d11ea59ef8f826217891d7aff3540f4a2e8e30750f62c7c4a6e2a73499fc3a99b873fe06b42ae7910eec7c2f13f9cc63d8afe76bd0822fab10dd07d753c1f0c4c3a6ffd5cbf8f5bcbe3bff1a38dff86c1300dc01632ab49ef11a914ce38044a47dab8780871132d00d782198b8181770b00ebd74c8062405417c18f5c76aebfabed352c6f002d4b9e28c04306c9f21850b480e0f9cd94872a2e12e18f099758718f974906f02b6f280bc498b316d6076e15029545404782df676c97c95a9d408e2fa8bed3872d6e330558a04124e999d677a41c6fc7d23405bd39584dd6a7e25a42d79bf5102423f96407c82ec8655014f7e8b18a4719a94194729030dd60fdade00e1b7cfdb234f1e0647d8dbdb973520871881311926daa6114a26e18b7d2125d37eea0507e7d69a2b09a67cd6c974d708c385be280cb401f3c546af243a66f67bb33c0e54f4d326fc07739ab960508905216061f154ac0c5d2a67b8cc3767c5b502ab75a92cf294e0daf372523ffa648341d2e4f3af0d26b4251ba1b0e00fd6f99fafe925068420db9eaea124fc859d9de13ccff17bf661bed4f2e73a917cb236d54c876b584a288a3772196a5e69fb6e00e52e4ec2da149ddc87d06f3bb067fca2b6c2bd037514d388e790eaa2a27635303fa77001cfa8120013b8cc0b6f88b160277a3f01f8faa63b2285e009b8ba8ec14ad739e569d40eb8f09c2a02df8522bdb4240cee4ed98cc49dc532dcc409e464d840cf97f4ab6a89154c33268e8a36d08daf347b98d9ff114d7501ec23f1c94fe3aee022093d45c5d1e92d183c168c881924f3250e42d50f6fe0a52040a18c9b7db97f2cbc50814495bc476062febb7d40a5005f9f789033fde98fa8850e41feae9e09fe7928fba962486d380aa56eda82f97994785b5c003f4d32a92b5630d3ca043b881cbda84f8c1b7a7bd918ec0b47dae0675d7d03c55f409f52404eca5f59b023b96e87f062557ebbb91a22041f892f352c7c5fb3bd26425e0fb6d7ac16075af92bc24663e74925d9260acfbc6b202bb890e74dbc4f3b2227818c30922ca1f1c4d51c264a55f2e05be353ffe933965579287268fe7cb01cd4a48f792cc2ffea82642d7e8cb381b01e1e1ecb268aaf273ef3a3e27e92105e7a771de7ab3c9411537e9889743111a6a3f1b39a75811c94568e2998e7f9750fbf80a43f62b3e9c0d7a82e24b3938c3f9b39b5a2e88ba36083940a8343e6cbd811410d0455d63024fc51b3e16e014fbfde8355e9808c74f2581f22d9c052f631296334ed98c455d5fa7080235775816cc90ea93d1621c675d11d9a8d847506d5814c547347c54086a70051956c22a68cf0d87d86218e018eca3979b68eb97c794e0d567def8452b1e2f834506353d5bf25421ec445154a472c7a76fc5cd4cb24cd169eab5687ce00d53bea055bbe21c3cf9e354532f83491be8912e1ad0ac9ad80e55952d659d62295bb04234e71c39e4754361fb12b5e17fe599b91281030f562adf1288835cc822dce2d7f61ddf5690c89e694cfcef90816402dfb30167e21f8c1d9088d567bc22ecf1fc2eb3243afbf10aad20116e1cc8c468a5c2b7027597a186bb358dcfa6387ac3f75060db38e76e8cce7e79ad932cffc5a019eecb8b54fad5a82a891bb43c67b5be3af934ccc30bb4be0ee5fcc5751f8dd2c58460320dda434116743b191d5c2a421d72efe38a9021b3674ce47b133b12685ab7a7ee36e584d6bb508137ad4ff6d9dbba82ba8a626ee59ceec9e191e03bfc17890641e03de4562f25a1cced6d924c28784396ca0c3b953399eb03cbea6c21b4284f87b9c24a6d722e4b390282da7ad7c0d8bf7a501e53601fc653fe62b0da2503054bca3c6fd75f9a327f0cac18821c3bbd26a200798598b02e5e31f5051cae73a934eb3cc3737ea3c1fc7e85a61ad1d01fe8ad29f44124ba2495a8e5daa38b244e8d32094f36764b353bc4a736912638030715d98c964b5d325cd55229fb4d771b9a5a023363fccef7eb4723fb17d745568a0fcc9e8b9c3b318a651e2781929f47593d8ad64cdad3491592aa45eb4da42842329169bc73e3fa8f6685ce304d577df84e8564249cdba2ba66cb18c3762983596d471152c34fe065912cc9bba1923edb1dc8c677c9bb8c9d2ab127d04ec380010f28d5bdb6551ba136a4756c96d050055ddf08aad0dec4a65304a433b7c529ed5594f47e5c04716f7d30124a888f847b92180285efc6317a7c862dd87ada8ed82864d76fc2e35e8b43497a0f35c0e4f92a489dbfd4bde888a2bf9db9d79f28c3628d645cef19e007c333b2d9dffb60b7c1e3617f7704a1964630f3f383b9243fb594f844121883fa6a3f163e818605221e020d402a28b6bc8437c9c9ea468940483d032bd4237c547e78032f1a00e818a5d8576bc3125faeed164a2e21efa1f9bade8cfdf69610115e22b3ee66732d1f5965e572b3ba62f6075c050f49b6ae1a31eb55087fc3c61a05d380f31dd5f249668da23543504769c0d5129b2f33e56a3bd8b195c92bfe49dfdcd287a6fef457dcd8376e9db99fd607130f503d466c1c4f6c1f388fe6e637645e7d5014b42671c8a0f2f248b22f9dd606ffd710d9bc50482e54b912f631f97f4b067858169b2023b4c233ddcf6e65c7ad94b10f8ba8ecbd32ed2212f3889a23b332014d9214d450d0d032d209299f4f1c37795f0a7a960307e4df33a65a0b75cd9b3b20191fe08c169b57d073b4a421f2a5f6c4cfe067d131eeef336ac4bef9f33a7eacefd39a5470c0a74fda68c9c5714180a2276980333a1f886b1c8a54858bf1a3a285f9da6e942b5351cf1f11f7ed2322b1fe2751740fc74b744cab83e456cbbe3dfc9e36cc7b4d516e26f995e44a857db274c08bc849f4dae970818fe3df46820775c40ae81a975dd8da2d84dd3febff009a1f34509ca33cc683463eca8d1fbf1bd6dae9b1c40010b01f192f591c2f02292661a259d8a907e999741e28a600e8d31d4c5cd0fce3f3e1a29a43d36d76c104aa7496f6a603606b19103c0e940bdc022939504c1e047a8b7e3b262628f25add2d14e4b0fa56886a2bab61896ed83ad22d2318187a82782b1608762932c74be32568562444654527db8756f112c911a421f797aa85af160ba7d762819f2d16de4ab9ee41d5bfab18eaf48a577a4fafd056c40ebd2cc299213459506d0044ab3961509f809bd52eee2289ab7416cf22ce02fd20c49653e2669069fa098e17d61d33a74df11b881a678d37bbc79f49fb3518829ae43ba7b1bd6cf4278331f70d315c375ba459c1afdf591891dcec6161b1ae8a3f08cf486a8d5b0b49a09cc925908803003ac0f2bd5ee66dcadea745fb1b688912e10c428c1f81fde301b553b454c3c1ce9a156889e920fa76ef295249c9f144053a111b847fc9886d83704539769ff63e3d8002030068c9b0d5a65a90acd44fc799b6b4a31de302a44b9a762b4b5296e11c04f44e07b888c01d8024a222d9bcb7eed193d30128efb37438d7a90a9732ccc590b25406ea57d074bffe1670efbc48c78c38c7b1500a78cd75a5991d5327cd919e7564a5efdad022d9c508f2992cd3953556534d8abffe377565d7f2cd5f503c169dfcac534bed7d8344fc2b2f25295692e7869e03418ca5ff2e46b4771795dc3c1cf36b1aff4a11ef5d2f8d65a099a133abf2601652a6d73fa499c4f824b802c12d8e1159e11f4613d61d430a6d6bac977b9e97b4d3cc3dc75ee79e2313be81602489cdd48ed06aff3eb71e0f5b8096050fad9b0450f6eb60b04c003a3adcd70acc3a5c79e3175037991976155c824942c4a2f493a2a391d77aa34d29c4b7b32de9b0e2328c3373301080a7d0bc90930e0f070479c4b1a017e1ff560cb0420f684ed0947c40ba7391c9a49459bc8bf90f98ce5d8e2dae952139ca66d2c723acaa9b9e2cfa55ad1aaea84313b5ab87798b73faf15ff9fe31d6c4ee95bbebf96144bc4fd7a72697dc4b6812573fe7785e5b12cfd10e8f499477769e52b141a1927114d21694c0f4fa61a9cadbd96c90ab418ae6f453f93536490f26cecffbeda662b4d520bb73457991b80a824aa0501eda72dec8dc1c13cd47dd0fc9450bcdaeecdcfb0a58578e04007e2de8480114b24a5304637c20db7c80afa04844e66c27fb1eb4a848fc181fdad4ae5aa9a33a2fbb4d9f621955d3699345c2830a8f5e514a946fcf2c2ffa7f97c154a2bc80e905e43fe57731378af169c8553c6e952e02e21d23dab29e051a3eb6ffa7d8456a186049e7ce9b9f760a1c0426dcbddd69973d55e900064b83e995ea9114c4feee05f44c812f3391b8f14f05f241a67cd358cfc243adb56d01c3dba7e6584f331129cce22dc2603432be59c9c7c666efa8a9c4dc4c9f1958341b2313f652156f86036c9e4a4160de4ac5114e92acf0fbd91ad0c627e901b638a1ff6dbec3ca05c24c363e658dee4e9b3364f53e49c59f60c15f7adfb5c68890738943204c2ff8c166b14f2a62252bc4310aec07e0429e6231799a017ad793cf6e1e0af1e796adbaa457c10cdfe19d05c03bad6b211a9b9176b72b09cf2cc28bca2b7f28933f5068eb30da1afa49f36c8777498e001340e0848b3002266006d226d355fd11dd9bd8c04b1834ac8abbeabf24b0401de578dafc84166559666443683156835444c32a7b3d75ee4da6177c00f52e81884d5dd1a55464c38b9ac0da46a5a48109b617f65d95c0d0a76c0268e26ff6976768b256a12d2506320e18e222493ba20c4727712aa84fef939e01f4a9a9f80ccf328b007388a1357a3417f68999dbbd7c8924a29fc94d9b0b0ac25c858e88b623e783c2878742718f4dbff296c1fa8ca350b22502a8dad1eed5d1868c0947369fa3a4425cf2d49a28c5676d05ac33fdfb6711aedf57a7d0c5769301d4c87862bf10a3f0eb43fb8da2096eb4020a599e9a8752214b12b7bef52317b6e368da43786b62343fb401f29710c8f8ea3e5cdb3769464d6e4a6c3261e1df2d8c2ac9171fea184340e6652f3f12f654435b52cf98e562760a012b177f539084f9b6cff9e690a0dd31b8b56b83c67175492d2ac9247532c619e8ae9c1063d0c0644d593c3a5cea15f458a1fa5a897c31cb47e5311ff7d15f8cd40472d7f78f1b9baae4cbfcd02e1afc12c83bd665f4ca898584bdc73285aaa2a1aae2a4c7d554157d908bd5ab5ba2271b5c40e3df2548aed39b651dd198735315b0a166d234201bc718ad6748b5d1541b8c61f06ee2fd7df38d65f0e97b32e790b48e9199d59af0cace481d1b7d47136a8d04a1c6758696405b6be2d50d7980f752e91d8cb9a53d4e069369f4d34e9a8ef5c326f483ba5ee4ed41261c8657408b9537b045760ee81aff027c0a845760037e9186b5a047ff92c79042793be1154d877f9a54ec85a78e2165da84bb9959d074773061d2ebd7aa0d58ffaf8208fdd240e2d0487486a59a40add747d697150bbcca41bf12aa6497af52971a8b005da5d60738a9f179670929589733add5684485ea15a34a7fb10f1fbd54a31f699f6ad2a874430d9c1479e4680f28dd383b7a5d97f8a5a39969fc1ebe4af9f9ae4bd489c316cefc8df05ead1bfc43762dbb7af18e04029b00e9e25e442e737623704e6ae31fd4d6bf749c06a99cc87dc8792d221e7cc3b23c4905934945b94e021be63964032d732252582224cb5191ce0e95afc1f633935831424d4a3b742b9e40ee74482fb526ea42c46db5fd47fd45ef37dd77435fb5768c3c6f405ec0f1656cd845e2dd5452ea2e9260b024e8e245ba9f83a351abae2b98ae13d9bc1c3b5e349951dbeebeab85bca77b901854ecd94586307f7580ccebb3851329e9cc097808789bbb491def95eeb33c05da1245f2317e455b51f2eb18fa513c650124738ccb02e81807e861e3a30950413865ff496c45289c5b97be36141bb0330b2e193d55063bd86549fbc796d96f5d7aa21f8f3b8f9d7eb63c9655172d63bf6274ccc7f244ecdb65e7638938656ff2bce007a778c554a00f11013447f00c73c21f3fba4ec714d806c568861d883088ca424273fc27f026a980a80ce61d8cbaca2df5f889de65d345b885543b943187b3e97e6a036bbddeb6864e6c156718ac744d036792265d952d6f18e1ce4c68dca4fad96867401e4e82528ad9a12305ae44a4d4e4d43287448b5679af9b0a98bf8d7698b58e0ea0381662451a64a7d4a3a91359d44cfbf62431ac4d1d5c5220fbe0ed6a9a3cf054a3179f469cecfcf051aa86c0dc6e688612b4146689ac1fc3f0c5b01b94a1327d1c493dd39e7213e5f41e2a7191de878688b16fe1bf8d518d6f7c8a5ed99823417b1a04712e9a7ae8384cd45d278f633c3b2b08cc2248b38d4263734224f157264b393e7fcaba027e1e840d96636bdc2fab2c33190dd14a48540003caf31b7fa3d3b269765ab6be4168c9ca529da6c8aa41a3f8a8645b31e3484c1495313ffa51fc60d18e487fe87737676d6048060d4d24a3b58e64149c24632b0f21b14a4a4125d2f08fe301a090651c974996889c32abeff7017df5dee40b406be55ac73ac942a6330da723223aff72ae96364f1e40bf169bafe50517c536b0b7b3947f0aa1a74ba36c20b1cd44618f455310ce5e461802d1f1d7ba893c2b5b19633cf9466addf3103826e48f11b3583ef10f9a9fbd645b545f1df79e2a694c369eeb907cab8427909e773819b21f118bb2dc78edb9e89aeeed102fb950d6fb2debd880e765c5c7d4b19bc8ccb459a9ab5bfc04aefd7bfdef826f950dd748e99f54588dbab10dd99960fb40a64884cde16560811f045e370a2d7ddb2e41ad35e34822e5caf04b6f2d5e01c887e58c9d32e144d51cbd3cf1d1877e7c3e3b40be8c9ad1ab8a29c1171e29914fc20e425c81e51353ca1e58937829a686df3cc841fe0721ccbee78a3e7a2ca794f959931c56a8a6bcfbb0b035804d7c3555746d9cb4a617e81a98302d211c1ba3f5552bf671605c1a3caade16683fc4a6cf6b50dd94427fb666edf11ae7b04a8c43c67c4a251f506ffcd54d9fefe5f63f5b175009ce0c0856ad39797f9fed8c253b2727dc7723fd84e5cf55bd9744f32dfca776abde03bb0d2fa6db2ddc1e986a3ced7ee792ea8b68e5ed09469f0e1568edbccca6c7358fb450749e38c6f2f0a42581d65a02fda2ed923cbbc94152c5d658018c6ffecbcb92cacb66267da468d2f4e25fc6d3ff4e87d82c6db9be401cccaf22ade27f9fbbe114d8d56675f342222c2d82c57e5d6a8bb9b354cd89ceb409102cac53db3d2e80d74e5260e2352d993caaf78a1606835a0959c6415489cd8dfc4bb2ab29d54fcf0ac1b6596c4c1cd352e647b3fad588a415ec4e6b7c11216e1634e61b29a2e7aad574e68488a0c238a86acfb9d4e3651873ce9f91fed3ed08f5c60846d5875ab0bf98bbf2836f419d299c012def7f2be26721d9522230420927ea6bd7f0b9648e0509cb214bcba4be33cf5b4c29c27cc6631e606f725987e200f9cfda80e570fb61b86a753c6e2bb8ca496c3a71ccf86dd927d57afb30fdd3b260d56c19f92230eae1f3a1437fb9f0fe16975c6bfd94746f7354388d6bc761e7390b194112219821e53caa806c50843c8c35639ddd6c9831fa3f0ea7b00c0a38e870e3e6bd4633b306791897db6b65a0648d77c68ab059d821bf4a77f93f6ceacfba692daa7c5169de9a40f9ed123b253886b177cf4e13b43118cefdfeda99643de0a6166e02d2fe707e1dfaf7ea6fd662a28ce79c58104dc4475f53d11f24ed18a65dab13698422e7f67c5c2f3d40c5f29424c9c782055154484e1f301556c226d1b991ebeb9b46e86e4b63e41589c0cc92b6257a4fe22975273c3f634a31fcadb6f38d123545be82cf756aa8b845f54a64e248e0e5510a5dc3e051f09a6bac04d20ce6f081877a1a00df4b8f516002c0f46bbde37dee338d1523aef9fbbc70c4162db6232a6af6e50d364c61f7d5c4e2fe2b56ed3adb91fe35e704567a2746e6a3e94dcc906ce14c952dd6cf0978081a6c2d2f89e17f4e183242db7131bb6467975dbc255cbfc4a0db5639022ee48339313b9708f89ad2e7bd9d3c2696eac9d4d9f690361e902fcaed9060d85d23be5db2bea937ffa6924b804857c0367ae8634c147b6883cbbbf95aa4f81ca4874bb5df02d8428ce090ec13d30ea5f0a0e687aed2a271034bea2ab622465905cb29a07c5e4c48ba6b27201b25adbeb149548d577c633e7247a3b401a53855cb87b15adc63a89fceb78f544322dbfc9a35da5464cbe838bdd9e3a69c4212282400c252fdd7d1293a9668286c4d9af9672f7b206be6c5046abf2eb6ac8a390991a41eedf4f84ff4d933f68aa40e0654c8cd43520b02f803268742b09876af493508c821b63844144466b4f16ed348feb651bf28afbab0d6b77e1bf8ef7fe0c2a1e92459b1b285c544d1a731b94fbdc0a17777bf20610446ca10d7732deecddc7bd71b4d6ef99e8598dbeab563e9bd1a94c64a576b9016032a1ee4fdbf61ca9652e76acf37cd7db8ecae525af53fb70c74fc692f9d72c4975e2547165e34ddf7caa65e73171c2f4c2d7bd70de576197da2fe41f49a776f2fe37fbd239304acb1c8414df096d047ec407ca6dd325113bbd716b73498f9a80d82e16c97a5d75a2faf52e92521997e4aad5a82352f178cdf456c657d8bf720c128e784e414e8093aba737ab9db9f220fcd70a92324decadd50c7e2cd4ab5850335468af1e3f3c7bd20040ed6d28514fb6f9a5b8c8f70653e36a353dac8426b5ce01a78618dd60bce88fe10492dadcd3100dc0c60a81c7debed7d8f3467783c8bd1facc446ad67c05153010d3a946f23702eb4ed372223f02daf7b8fed6cf60d3eb9aa7f6c00c71c7669692450fc4cfe4896bde89e188e0062e1e2328484deab95906c8c58ebad6c2fc6aacc62f5d4f1f72e7b3598cd2d67670b659de8ddc2bb4b0b8ec8fdb9300b526dc0c81781421d6cb4bc0994d0e0dfbb0bb94b1013e66118a416a403b5e4daedb1032c91f31945b946191f30f164e798ee48c605fd3667e1e471f57ac1e7c0811d9af093497eb55bbbcd9ed599598dea1dbcac5e2e6a0202ebe206572e7949b88b3362ea6c183d10b650891c5bcbb2b16a01bc1e4d32b42282e572c8064140beae57da7c6ea4dab9037e3b13a582f247f6ad54aa7a6e5c399ad9294e01c4c4b432a4a0cd06c66c996567d861656cfd905f1e7e973bad6e401186219b74a36a8e9f2266e6e650e60bb7a3735b316bee51a1386e10f471bd974ab8ee57abf65fe2ca264550a6d731f3874fb2df3204bc9411a18663e725cf6ca14efd7ced544f7c17d95e62dd2839a86ea12d7016cf600641484a5e8a938389e652b2a7c6298cc9b16ac66a5d234e5fb3242edf0b373304ff3ed5ae3e04d22fb09a6f0e2a78a5f16bcc6806f4b538eb9ed07fdb2fcd20769e2e58379ede0f31f5fc27a09ac41f0647f4a5e2b081df350ec53b10756485b9e36d34f7c666c36e834d358ad9444093c41a260b8329b1c1fc3c9135238f7102f303b17302814859c3649ace912c93e0004b8ed4f4777cbcae13f21423fa2c0f27d677305195ca47d26ac4d45ef0f51225ac41e1f7a4bfd59ea6b021c4efaf7fee7b6ec6d2abb71f17e3a5ba3134db237c28b3273658e1de0d193d55af51f94c089cf725c4341bf9f4bb19fe08b10bf2ee90cde3ae55538da262472db607f0782800f28cf4490c9e5b25a78c73b39163aa32eeadf7ab2860c99f0d5831c8240df9c9f318701e6ca3735331b8eb51f4aa206e579a937a356ad79f9d18fb101ac65fcd4026b79115d179447cb22ba265cc2786b8c3c4af347ac7ce639750501093133ec4b074def9d0a06e74686e7ab7967bde6c0867b99da9d04d830ba68457bbc13bd7a71bbb5c86c73a6811b6294a0465bc458032fd2ff12b84a948d507bac86f5f07a9265279def70db86aae515a83e55850a6a93f0d8a0346ddb3557c9787ef804d799010c5b69bd13f6ae9e51f18dc57b73079065e43dbfc279e259da29a3563915125e6e0b0a5d4507fe48cacc32776c194bb5d556b16ef3d13aff925c5cdd8887c3e3946c2e02b292fb71f5fac7722a5dbf6e1ef885701094d61a241d4e47bf368dadcf21af0f900329fb2b78780e84fa14991becf35b24d0c458e5dd3f05717fa27fec95feff3016d5d7fdcd99943a772d6d118dbed6275e2bdd5d26cceda99e3daa450946937d098715b8518e40d90e508995149a755c3914199ebd257f214900d3bf9715e44ade9f07f436b113d14de642fd21f6e3a1fb4921c98ff0c5dee81bafb4bf7fcc84f937c93c51a6017da1fe9050a0acdb10e9b2be39bf1b14ad4b83ccb780dbbecf583114387d6ae5fbb1017deb849e85fa40e6c73371993fe18bd511b70169f9b9a355ccbdd8df0ee8db27f426d40fd23f9289cafc085fac47dc08488be72663c5691896cad826c1833d7210bcec649a268bdbbea04c0f004aeb04cd292270b2c043077607f6cda8a1b39c80997b5e07ababa65dbde77f3ebf841fb11ad9831bf52656a5e469d44c71e663d4d0a14f9983566672e01a346dd2f16e51ad7e8a1abfaad66c9a99512031a3834e3ca7a195f2133d11182d191d7470231df428fcc193f0a4dd74d0fedea2f6c534d3e7d1bed2e786db0876d0163d4ddae359ef17bf4feea06d4507dd414f7a0d8007bef00ed4f9de7b57e9516088703031de06972fe5f2ebe2c60f83fbab6c2a7a1539598e41b84aa5abf0949211e8217e80a43f0828f2719371550e0be26c621140b7d5fcfb5f047c8de3933d007a208e2a064b83cad7e900f65493a47641e64f51c30b4599f3b8027d40e8b55d45b791b6de977cb471749fc2a6772b3ad57a433d61c5557fd424d456a20f043a742c154e03300590c3469fb9dd674dda82c6f3aaeb97be369c794d2c640cea95e2dee7f0dd265cb341bd2bd8808a309ea0d5e8849dcc2f4132dc78f45e818f00816c632564f5a7591b9b3807945ddb980c3348743927cb182388100ae4fc02d3cde4884cc582209a68308c45723e29b8b1b6ac505f12ffd65863d34a5e4c371ec141006c8854a1c6adb13bbc50f3378ca368148ddf612443afd0f4c6ab1c3a4aaee30b959d557ce3ea65fcb92718743159ddb79858b436b795051609b01fddf3994edf906f3014f3052fc69459bd58cef09da5c404f9556cec0cbde0728595ecd79a16d4b7793971acf473bfb1aea8c87dec1c841112000c7a6706dbf1f439d1465dbe5d45c4c279a8e0d222f9300b8f05e73a106937d4d5eb5bd93c2c38272a3497cfe03f0fc8e25bc8610450df3ad785dc438d7516340967eaf3360e7147547c94dfdbb6f7c8fff1e0313361570c48d72ae087139708c237efae4c5274d5145a353c68ec75f0bbaa4df9b4d0a444408053a7fd051e09fd3810d36cb7253f75866b84d1d4f890ebe58830c4d31454653f9e19c1fa8c8486a8a397991160112feafc598189691759f4eafa2ec9b517ab13568fe61ab77870b6a28fd5606391daf45841cf5eea6107d6d8d7602a44de2c4280b0294c1c5032cc306d0e95cdb58fb71e4d82dd9fb42d3a102b309cac960564e217e86f4bc3bd7161d4aa60ce18d4b9e7a85c3dca3249c455816a6e6004f14d0f5513d324cb16c2ccff513ee96d730c9952a24e80fc0f8f673262acd6aac7e2050c4cc005d14eb7ace9f8526b995eaaa8b2a8255f4adcc3e5cfecc25ca221fab6f6c12b2445a6796a1af5aa6fb400902fde3b109d798509a10db794d628c216542f570b4b03395518bfe19c0546c777d85565d1ef5ddd7d1ab6c1ec1a09072ed38aa5e9a250863ae3b0f772faef2f75f3c9b85ca3116a168e99072576d8d4e3f7af13ca1c67e7e5b2d192976e25914e6a3f2575da5cb516b6deee59b84e0d424e32bbd7f11cccde616be12e184de75524e210bdfc1c13b14354b9a40fa7debf0efd0159814ba50cf1c98cfb1073404bec43c999fe2021ef15b7a91fe71bd127567b4053e0b26265d7742608349a6ed7cce47eeceb7a66f661a6db3c73722ed538b66e23949c89106d0b6167ddb661cf448bbc7569566b0c035ba9df555a81cbceae8e2459fab52604cdadcf4d2ea9de95fedcb3d5c6e4cdaacd5f2d55a53189d8c00eb6ad6aed24d1f99b42a6929378f3bc8a68893e522fa37b42fe36563b472d38c6c36d019d96a19cd69d3f6fbbc945cf1d6b6d581e87c7243bccafe462863ad7adc974334e1bf9fa7434a216d9a5f7de3ec69de9e69a6f34c7a4a996e10522d78988eac4dedc9a87e865794c12746414dc6585569d04a8d700793866e9f8e87c6b1622dbb97fefcebef72cf7bcf6177fd379295e779237d517be353b96999e1f0dd006e0d6e5e84a169e8b5b0a4e5fbcdb9709d8d2ba3ecb256848adf79f0f1a83b3f652d18d52a22ce7418cf3a925a5eda3e7729ba815cd9cad3d1ae24d60e91eff38891208e181b877e2951c815d3997d02f37a6adbe36364357c71d433ae4ca42bdc87b91b60bdefaa11f470a77af35d42ae2000952d2262633452aca5b727f55eeada6d5f34afafc35ae5c298e8bd4f29b92fd7bff39f368e3ca1227f944afe1aa8005c62c2f149116eb28b58ba7eb4fcbaec6376619bca3d7604dcc2088e257e1cbe55dd54640403cc3963fcf7a4f1d408ff1702262a82a94c8d258e40903ef1328b182faa11badca20e70250e49d7107b92d58c994ea6b8bcf0b0e7a1f8ab65c242acec4b1d25c92f7348c2f3be680a4233802c0f1127cfd469902d0a23faf7c6ea1bcc145c273018704269957bfd5ec6db0f2669edab7bbd9aec174efcf423c6db2811289a8f994d6a823e0bfa70710ea01d5ef65f012a6a28ab3b4cf1c27e95a5d2d7082535eaf0e36e3ba155e7a556b4692279ec0f15608dcd017c1d2ad5ab23359e3dfdbd68f3aef3adb0449d29b63f84dcc09015950bd56312d8ec772e1ed2109ecf443abf95bab7755e0c644174c90d6db240691cc3a1797256e5b4c5c986c51a7d543ad67cb7b7cc68c7a63f362e2729bfacf7347144efec4a09ba89f6330ab270aa78bce1b8a4ba29f914610e27f1ef0477345dac12e5ac84b0701a4ce221824fc42b72bf79c3d23352dca429e09e447e68ee96e32cf912c937369aa4f06eb4d83bf88b6146e5c81e6df3a12758b546029d41a903289eb2b8f575f75da9106256e95725643ce183d5a43cb67b935a6d5c4edaeb3f9fbf041549d2cc82aea1d9e68d661da0add7cbd450857a56263452601f5c43fb7b30f2f6fdba7dedb96934f433a7f09d7eb862697fd66bfa239af5871cf9fdf0a6036914a88dd10d327f8e9c91ee54b1f6817eb68a451085c34ac0d6a0753a45e66c20014740a60a4d2a11c3a67ace67f92333991ea2dea5ab2dd07d777a70c588d8efc0e8b037c5ddc6b43b85c04acf254f092bcbcce41f8e4f19f8d1234370432bb4c1b7b0e73e090093923e09710df084a980eecf6dcad24b64d0dab675f4b97203ed601a51a9a781e3239f209fb8bf3e2a8783a964bd4205bfadc2e061806380f03434bd0ef22ab5ae71c7054588fff6206c27d5e3bd9229571bda0d324c3e20f24a4bb4e2a8b1a92c17772597e2065ab7329f864a26a07db71c436e912cee02ac9edcab7237e0494013533a1f9b23bcbbd999e8abc7dc7e0fc3c3f3daa2f4aca423e9eca38ad1644273fd6e2f6ceeeeb53c41d9611d9da7fce35816611cbd3088d0e854db8befbd8509db69532947da1276c69930f041a2c46ac673d1a047e6db11e52f42738593cca1a716f3c8c8bd8609313308c78919e52c08e6a5d8b887d80e366f2e00cee99e81fc0ef4c2852562a5b9a576252670d6f1908702d98f00153d17daf4ecce1641692561d52bc64236f21f51ff1d223250a39322411a687decd1736afb9be8c152e4e3396db5695c6e924c758f0299f0d7b2b52c90796a4b14d69d0b786a45a2a3d2c0347d93c62f34820c97b1e065ec0c2c9d1f52bb511387e9742d673cecb03e0882fce73104e6325febcb4d49b0c9cc959793c7c3e3202c82318bd6edd657e18f88d4421b7f673b20b62ad031ed17c43a80b6b1d5d3035bcb1e97079250730e6bc2e37017f86e5ec4fcda6548f574a029ed67094d412771a24b225281e828dc0628d90b932d35d4893c957b8cf06431aa5b9ded2908e18cb7f0d2bf61d8c521d1bbac1a5aa172de8c77ed5ab3058b7c0cb8773fceddb5baa9f3a6c937c9f6d3f910e46f6f54418d6ff57f782f912c09e70d9cc58c0cacfd763e50806f5570b129cedf4106c6c2cf43bfe485ce3c22cf642e8b80835c429a7347aee71efa9caf548db7303e065894dd10dcfb88f5471cd6008aed0a20f18c88a23d67ab0e610d404aa5efaa63d5454b08ff9f67f568043167b933a3fbde974e5ff1e0fca806b3a1d227b3b81fdef5dfca26a49b7138fbe116d3a02c1f0d849e04a71a3df7db10c00dabee72e65f2516770fbb2f8d39e8280becea6b18f379e92721c710087947361a0d504619245e21d5a846eae856123b9afad4fba372991737ef04a65c590207eb6fa981e97ee222d4d4e25c2810779f800f862b1bbcc85dc4d746c6c1aece6c45c47dabfbe11d4d8fdfe3a65bea2fbf91b88e2f4e8d154cbf08983c6d511cb18051be67143270a8e540a89c94e56cb107d0a436a840298fef40166943314827c6ce0f0ed531e897f116ae7221505c6446e75d66827c3330297c7b5e1068ffe299d06b5868b4bf56102d62e87142a9f7dd21d6650fbbc563f0894fa6997d0f9778a6285f601bd71d61a708ae6e1cfd9affee83a426779b89b909c8f9227d256d3c22a4824f1dae50d7163bece5e37ed323f0faf91e2af694ec6b2d81d7f8b872cb5f7ff73515ae88283ea8bb451bbd7685417a7a0ff19856a1fcb4d36231ea2403064c0e756d3915d1d9a2012b8cb8b66096d7566643768f949823a1d5306ead83bfab27baa73b4336ef22818c190b85af2cc9d663e743438862c0427309c79bb5a696404929d7f385833b4788708b6476a6ca0710405cdcee9d6cf56e723150da8304c6adf030482f42b21591a7389419d7f8dbf3db85567f61f221aa9b2250f6219f892104dc549d8beafd5d9e5b5d5b1973d6b377a23d45e650b5cc22d59ae0a1a328893df3b92d0928510a42cacd924075dbc4552d0f3f19e5e5bae97beb757a45d09e88f951981fc8bd7ebe1da96ee18c01892137132e75bbd83d8e03db828dc2522c53b632304ecd68a3851364dbe011b05fa836b17a7891db89b9854936c246b15ac23eee028e04af203c2b07751936f1bd104e6bb56596cd1475d925878cf64c1208055a3ac82a27ad54409b2cfab04fb7f1324f57e4f3eb44c2c6b097a0b7cd9596a9cd1785a04a98e3397a627eb4fb613cd61f53b2d57a34c87af70135d4b28c6141f5259af12e72679a60a7ed2c7ae75cafe958a4cbe4b388cfaaefab8bdc7d1a812f1ac11a0ec77f62635094dc29161456d7285cb4685e39c11eeaa113a73551bfd0a0d591256ed0ac74d77ca8d2f75064f4056c78acca6275e234ad83918693d7822cd9296a7622b2c05d1376555ec2b2ea685e5c4a548007a6efb0a233b5b475fa6b045165ee3ae6ef4fa77b79ad465d6229e9e532c4b2f8a182a4e47965583e45a81994cff154cb5d2ed883b94f251fca1f5c369576d50ebabfce6813480af9d298249124310a2533864e219ec121fa5d729dd94693773255c0c9dfdcb5b6d6ed504844e7e9e082d57ae2cbdf5c4cfeacd07d15bcca153d27b5d2197b9ba4f5c0f865219eacc24812e32e4e6f9cb1c281673407c2dfc5d63da29ab66df81fa4adb6fe8c25e3eb8a6629625268f2cb98ff4f2cb3481f421efc86f9fd86234597c1832fb8a2199b329a50a0a088d4afcf27154e43947165cca8d4ac041e993a5658b2db11be8709cae3da39afcffb7a486b9aa7795de2bb756f7acaade935b574f57f6aed463e566757a9ebc0cb9c66286c655dae830a03cf01b9080cf06d1063de0db0b783905f3ba939c86c2b15471c0d360df0d42467878f1a035965dff3d29af1d4ec15277c582a6a7c16ee20e0c6206648ee1f78603973f8f6dbd1c474b88b9bc0908cbd86d4310ef5ad8df775be13fb7c5afc1187ab6b267a5de2bb7abd3eb244b0fd54e52f2fd6b358173feab53feff07f1e712898eca80ec8a7d004ad38e200c9a73d939a96d943ca2d0b71587a8e66eadcfdaafddd620a6ff16d96b783e582cadada7977ddaca091de85b00d5f3ac4e0e5df89c9ad34891ae1b5229e9f5bb9a83bf643ae07945f59ccae6b7bf94a40ac129be2062a0cd7812bbd7f19184a673ebeaed95bd2bb4e591700484b9033a34dba257205e554d07a9de84bde500e1b5cf69f6f36bc3d2bb0dda4b59ba8f6bf2be6222ae19e9b19fef323818187effb0010f580ce2fe47595234d501d25276537f70abf41ddc5fe5227e76428f69a3c96e7befbda5dc52ca24655e0ad109930a27ef9ff2a6b0888b37428719d79ee303a85cc87acb27c6d06477d3b3a1bc81644d986cc2ae3f952059b3c655b5068a5dff4616f2e83aac227c56ed7f112ed696af468b7202fc455cdcc2bab51e5606fbe7d78395c146f1b00fea12fe6dd370386b5cacda3c42069dd5964f14156d27fdc5182b291ac3925a71cdb3cc86deadb5b6c8575722615fed3b241c55e471ea4c0fc98eafb8af454ededf14ba76c2fb2474d7ef5a74328cb2ebc818a90410f49afa25504a16f85216e55ce4aafa79fb48ef42dbf76d4ce049f282fd54942557c882621f69abf1d5e83947c659b43d77d533ac6a1618d583eeed75d0bd7121c7d8f2892b926cf9f9a851d525647fd38f13d6a284a25da78ee9b1a6c77cf5789aaef35445a70ead785bacc77cda96fb1c8e748f5e73835dbf148efec4aedfc27b6ee6c8c0c8d0c493f8d44155b7f62494618514b09927aec8d9f20932d86c185b3e418623ae933f4431ffa154a766d7aff3888b559ced710a8956d3e6115f594dc47790d2acf155e9eb4f97aff2d7ef36d2931ebf168e559bb408196e6f5b2ed6d26f61e9c1d2cb9d212ed692769d1c3a9227e471dae868abefebcf6ac4be75f72069d257a40f32649c3d90b4bc61109bc376180c82df3ee9e5d783f45a10fb5b11da6bdbdff0b9e5d6e3b4e158a58b362c02d5e3eb00d1fe5eee1bead9c2281717ebd71a56c8aee3ac1d8a5aadd6113dbe92b02535d55fbb1625d93a0eb4470f62d9fa57b3305f8d5ea3238de48c68fef8aa76010563c3c5fade1432c31ee75019f6c8b261eceba8db1651c4bedc759f8446c838a107b019273c39e3dd5a3b8c3f1cddcfcf7bfaf590b0ede9093461618e587624bed25e739dd17b76c5628feeb3abc36416628041098c80e0e33ac38c5502abc2114ac0c1194480c58c7d29ed6369df7e382ce79f0edf434c34ec1bb246fd93b0450a4968d56812430579749d1ffc8ba0ec9fa03c7d145d64968027c80433467815a830ebc1ccc9535dc4086d892bc2e0737100051682668a1881f2464c255dd0c9994179f9fd401ff5c3e953feb4628499934fd1455ce82230509831425a61c50c8a76427b23749839d14e5c3c8196a076a078c0f484592000443161b5861579749d1353286786f8ca6a14105b02ce53df5ff55da7beefd407f2295fb0c2ea804e43367190e7cf3d452759baee9b38bc97beca726aff92a501112f10ca9a4452551fa5626db7a462043d9b6e998423c6b0c7d9c4c7f8ed1f13a5be74d2e2353d8a5bfb5458c4091ca9f7b0c89cf1ef6a6de2e6edcf1f1fe9a51495d3fb0d504a985d44a9e81cbe555252885aadd6114d6c30675ee3f2958bd9aeef368ee32c3a535fe594328178826c62be1aa7cf5c527f0ad59f43beaa55ec9a929292e2b3eb4fa24a65362aa7d34485934938653398e4711201edfa7389afee5759002464f9f21b624e22674d1ecaf2c72a7ac4f9a4c79ca24320b2467d18a1cfac6eb25314d3af84e1cbef4708239c335d178692aabae71e462867ba2660fc0d0fc395efa617862b2f3f207c06c6039131d6c58f315052ae84d1de85f628daa7dca0375c0b4bef221c63a0c0e02d435338d693b096b43c51d6b442aaea77e1c7b0b3d8f54797779944bf8550960674d003263e60c2092220c10c0f5194018a190bb0701161a63e90fa41d4ff304638657416b9581f0ca7d19cb9589f14ce2317ebc3a8bf124aaafabc1be922e739bb7e0240908bf83b61dfff3fe081d4233167521a3593e79e45b3fa93a86a0ea46ea86d237216a8336546be6af991a33a829a3d7acdaeeedab53aceaebf5d0da6be0d5f55a35d1f480682788c89be9b44f54ea2fb44f709b043747f0bed6b21d6d610812692dc2d3fabb1f39c1c650a093ba1b03c0961049dbb3dfaa4906b54384ca342892b0cdb1f9f6ca9c44505245838c1a20a7c63070fa73f795b2a7145b1c753d0b5c2fdce5601561005212871c4073f2b8040139858c30c9a18418934f07c4558a957845b2a71e960735b2a7121215121b7d852091250c049b2b7a512249ef08094202184ee95495b2a412207dd0d9420a18331ce39ab60ec6513ce4e38e2828ad74908372851c452d690c404a6298a5cac4106253881020e8a1a5a481164a2020d4aad13294890a398b5f83101282b61971bc0808433f6b250c66a3041ce2785175561172f7838632f935c701368d0b9c0b8bcc07cd8a5090e67ec654feb88c2cb73c1694842677381717981e9b40e219bee680d2e1c84c31d5d71e442613bca828d1614c32ef88917581718971798285c51d85cecc2838a33f6b2968f5c8043a748e22a39450fce4749280105181ad24002a1181ac06023850d55c9cf1ec69bb33c01d6a00ce00872aa0aa39cb77c024809290654844d0cb9dbf209a01e2400099c185b3ea164083f1cdef524e6afeef92b90f1b43950827ae4be7b9a83fbcf7b4e88d3f63a8e9b61e5a8873710aa9a6f61604491659fb2ee6c51d6b6851387407c08a1aa29f3297fb60d1b2f2f26534a3e0d67d1f082a01a104550167e1c1611024155f3b57047105435bffa848111294b44808bd3dfc31d54350940001d7450a942a99a5233027b378585c15c70a021d3582c280808e874ba9acb180c8c28fa9837a8cbcc5435352b65cc748a5dbc57208285082dc4c9355b596c9986ddd1d92a028b2db3d8e1a2dc5074724b3d0691c2449e4f85384920d4256f5929a58e5d14320322f311a3e105b1aa4f8120da11546bad152360627c3a7d8c9425f234a9604ea7d56a176f5ce77d2430975a9c98505ca478dcfbd536cc692128a62c672927cf815095ff88da9ef18d8cf3090865097195ffd4395060d24e5a944e2a3e8008913f36a429355bceca3424eb867743a96690f4799dca0e2082905f048c8825976947b78cf588f17d49b53f1120eb0053f9561a3fdce1425cac5bc80bb15508cde15b484e165224a4a8a80825a468daa8fca0e32197b0a51ee2db83a837432224d11e2bee6c14aa7c97da75d461d5e79c1f546fb8c0504a5fac5567507311cbf329a594661f749df49544c2a6528f791cb5701c626938527983cad02b8ac7d4b6dd74d3afbaf329b68cc21e51d24589852db7b0bb8a51d245cd1ac1adb576eb3eb0721e296770dace729b66adb5d4c5923e3bbdce4a95d556d36abdf62fa5bace3944915d6be54c9f0beb75d52ec15501a6d8ca6d5e37e97c205e77af94dcc5f4b78a3f1c76895c5d74593ab9f0bccd8587f2d1e4ade96ae485d76115cfc599a21f8e1419641cb4624d7bcac34acddafbe1a83db08b73beb0565f7fc105f7dc8d8c75d4d6a3d5da7008ba6d37b56a37dc7d1ed802c56b91624b19f4c0539db67317ff8b847d8fb0618c613736bdef85dbffbe1be542100b217d3cf2a6ba9ebe0f4735c02cd7ef932e7ae7422516748306f190448dbfee2379dce98527a50fa93dabf4b2ea944217a9aa9f432931d6e30d307c92e8e2e30bb377fa7a5f56fbd3725f0a0d32d76df785a769f24ba141a63f7150ec52b4af75007f3cb44dbfdbe474d2d5d31ab1298e8a92d3057b4a12b7ab532627415190efdbf0facadfd62b52969458c67cfbfe29cb180c733fac3d9d13a57da81ff6b7f72153d545e1e748bffd0fdf73fa03dc7fbf691fdba37e784ea3f0772f673eac513fb8f7fe876d7b4f7fc0091fbadffe03de732f67482f67a8cbc58f1472a19cd930555d7ac4c5fbf8be1cc9f4475a339fda683fe8244b2f21df9f0b8b71700fc6c1381807f76cfb14a57a3c5c78377dddd86cb1fff2763c249ecbabf16094e51d89e504793740b78a6dbf44833ce2199ee12367e1f03a9038ebc6a8cafe8c1f6b121b7eac3d37fc587d36e9ab8eafc4277d5d42ca5c23961f2b139bf43547c6c878d2d796b3ee4e75d9ec1cf9eab390321708080d3319a3879c755d2e264d8c62be0aa120652e122452109231315eced26432980c4816d4e3ab140fa4ccada9f1018f8c81f1a4a737ced28080680e1012a0249bb4f2a4a72690321a132614059bf4f4888c4115394bdb99b59af8ead40529a3fdfc7c4126635e2c7196e6121a22a92c41ca684890781336e9fd47c6a43ce97dc7595626731e99bf48a627bdcb40ca68354e834d7ad791312e9ef45ee32c0b04e44780fc06286793509ef4330d52c632992d769c4732e6e449766747b653446a310529637f7ea8109331251f6759d7cf12d24fd2cf1f48198b64b6582441d8a49f3d32263fe9278eb3aa4c47b643e254b0493f5320656ccd10675520aab28f8f6af6112662d8a4d78094a94ca68d8c019ff4427c359ff442c8182acb44a4f7e1acba435596f43ca44cfd992df6e58f8df165939e86b3aa8bf43b640c7ed28bbeba4f1a6fd8a497359bf45f48f70c295391b0c898faa4c7cea232aab24f22fd9432b566b6d8273de9533e1c24d8beb16b74838ed9a06f6c86be31166db4edcb289521837f7780eecedf9dbb73a249e1755d24d7f5d7755d17c9b6df22c69792dd1a594a26bb35db7e0986b702c4042805049451dd49dbf9d1764eda8eb6a3fd6cfbe00b4e25f46a34249aeba4b934978664db27a56c2699562333c93e9956b3ed7f2e300a101312900908c83bb92d767e487af474b6ddd9d9f9d9f6bb92e6591792d3a7ad8ba4ad0bc9b6cf65cb5599ada9b22aab325b433758865cf778975420264040404cb6fd8e86f4e746297dd9f9d9d9d9f9f1ef30a5d485a4baaaabba906cfb38ac7fb7d6b57a4ce1f0f150edeeb950db1e9e4c4db87e46f51487b23c187d51564a68ca944e9446b62fb4ed4b9d4b58648f0e6dfbad56ab0b61b20946590ea31a4687281165e23b35c33777766777866f54eef62c1c52db3e8d703271957f3a64948567b4d64c99ee689e72ee8eecd7945733a32ccfe5aaa329e31da1733a651b824e0ddb3ee7b5640dfb252c727d0f86b1941e0ffe2576df201a16a9dedaff2f9cdb0ba914b5f7f04ab1f360daca89d57ef43d7ab06d7ff3bc2d8dcf9b353c6f729e43f8e22a9b5d651fffc8c96313aac78f616af8a4b28625d1c7219c3157591a2617edabc293abecdff0adcbf46c5a9465fa53aab52da5ef1e118b0f11834e6ec9c2324539658db9a76f10c703aa70d1eb7449834e2e57cbd5aa71495fcd9d9db9e3e27c931872d5518df82402062ef7711f1f82bfdce543701ff7e9e9248b17992dfa56f31d4ae9634b1fb6a4f6a8ce9aa22ceb6428ab6c5212431e65d1c7d2ca734b2c7162434b825e60441aee5fc8546aaac779b35d2410494401773924290004c8145d37e7d42530e431b5a5961928812177394090e7cfda244b3ce99c4fe87cbba7e99cf4b9f0c58504790477f000529f176fd408f5b5d00671a1be7699b4fe304e90c7bbdd1fc6c6bddc5f6d765dd77597c3f76fd06b75752a589b4ddfc34ebe9059ab513a7e849e3dfa92d06198208f7e04ec653f02c6369489255f70ed70cb255e6022e917ce99bc49b823a2382e564dd6a0463e248523de14c6913cde8d9f878b7ddaf75e877d4f4b178d6c0fc7ba7df4770fe5e6c221beb7fa37d474b57246b250ce690e5e687afc00d01eb5b73f7db2bf5e34792143bd60cacc955abbda7df572f7f6efbdd5f3bcd7e1efbd91ad85a3bfb6e66dcf19d99abff6a6512f982d2f9a5c948e86d2b195dac065f7debc12e4eeef033b76ecf7fdba4bc975a72ee47c0b2edbd8b9779a3befb84b6baddbb66ddbcf37b2311ef153fb1a36b235df42a5326dcacc6d1f4f99196321f1334ed87f4dd3a81ef7b9d7719fd39c73781b3237d6da6ca1f3ffb7e96ab89a66a5d66d6f434c59dd5b3d02d99d908db56df3ed3365d9dfe4cca6ab8bf757a890effd4d9a8ef1731c0782e0ebf007ebefadf3be6d88dd1efe0eff0dcacd0f67ba54266eb8e7bedbde76dfe9ec62cddb07ad5ded6a57b9af9c1e5f76ad737e1b6903b7ed41d2b76d1b17b2d4aab37cf9be565225751f676f344df33ccff3ba700b39eebd70ecde729d91bd854eb4f1b57f836ad6da25bafa92656efb32005366da1525eeeeb34e8f86f4354ddb368dea317f7b1df3372d5d34b26b38d6b13ebd8fff861bd97588efab03305be8dfa0dacbae7b7ef62574713050d0fbbed07776d1fe8a1479cc3ea8fdec673ffb373c3dbe6cfb9fc7ca9ef7a5f003c38fc9f6de3d6f6e0ff6b1380b943a4bd50b4cfe91c6b6ba033d1289f43ae426e9f1033b9bf4fe46f6178ebf3f4c0ac7efbfcfc8ee382d36b4b5bf41af55027d519f49611436ba6cbba5f7defb46b6a6ddf00155e4ea6f7d0bb3c5f5dc4167bfb394ce70ac45b6bc37d4a81240aa11bafa5d0de5768cf1eb90371c1fc85837be2f3ff9d7c896e110bbada64a8475be5ef2caabbd2c10aced01c2eb059d94524a3987508bd37563b787501e5d27a52a0b65a12c9485b2902c62ccd5059d7459710de7b4b6565baba65dedc89c2f3f6d563be72c62ceb7a1e3e8ba39379085a6d3e93478a83615ed745295210b8b369d343f07ddf35fb6ac9584e23116d9535751aa01cb986b276715b27c2209459bfe6f980bb6252c09182c899bb9e7c78470b68c09b9760e5bc6a818da75d76fbe376db7e9df35ac610d58ec90f2ab5e846e4e774affb6b6e36caa4405355b26614b254ac076579a419e321d58458a8c639beab1d6a927131777f0c995c96d0da1f3e494f24b8091aaa7087e346d87b9c10310be9abb7e066834d9b50eed2abb9aa5e182e744d9e7dec80c0e51f6b73732a3d93811e103a6aafa582f40ce64aa7a39b343dff001d49733302e56ebe2627da1e1e2cb4f1669ecea7509efa7f7d3fbd9a295e54fedf338fbd2c5aba1483f7f7b1449f710f77c7ffcddffa73da7c7d3ecf0f6f5b567d1e6bb46f9ab7a98efb9a3ba779fef6954d77de7de8544e6ee340d175d73e1e69afeb8c99245d341240cd6c959c54fcfee9e7ecc094876f75d8b569e2fbdd2962a5bfe4841d67e7e490d797cfaf8519fee216eea9e1e31eef498455c4ab988c7bfff2ca28ce9c2b9a58c1962166d4ea37a88fbbefd7aa0dfa138917e278a9b233237a769f8903f6eb2f60f5b422a2141cd962f4f3ac9327e449a941287b424a32a7f4e8f63102124d16ef11ba07b3ef723dec0e611ed925e6922d33d72ef72a1392d84a2606cd2aefcb9b6bf8d2cf2f8056dfffc5f4cc674efff0d7d419f90f7ee7de75f0ed96de167e9c7715c083e87834c8de2c1fd7ceea72662f7f7a4c721e9b7f0e3f2b783ed0f92f4a76b0a87d79379324fb6dd23da727f4425b765888213302924f102ca7a1976b9ca5ae33a098b0452490a6a36fddbc45773d36bb4e9d35dbffa3f98c8636d92010c5ce05a8005480528104e404b200210f807c800c2013fac3400860f0c5840ea470c1f340a50e9e1050f3d1270e281daa123070a0e170838c08c69a7dcd8c100a502b4b0211393097002c35a7d030880005e742079a04b0b006ae090038d8dc32af1061b667462063070010b00a900052620810840e0014038e08706f8c08005fcf041a3801e78e891001e3b74e4c0818003ccec1b3b18a0003664620800c35a0de0450001d0c1a505003568e480834abcc186192cf7de7beff59bc347c372ef8c67f9192c7a9cfb6a79ef129670eebb24e80919510c8a1933807010d1bdf7e2f0d15cfdf7f5ddd94952831f9f9e26ee45a243df2caafbe1df9a1ad7113a38362108c396484499d02ad0236a449bd02bf89671838f0f4c08b1202022acacbc6cc0c1c959414f12242d48a56e5e84be630cc160b0a1194646b331d8b85a57a8a814f9e8e8e8f8b004050939c19b38131f8ac2374a4692243c370082bd728082b2a35dae23224092739384c954d322f49d320483c18642264c6456b46645592895887c7474747c1e06fb29c21c125a7204df27317272745cf0e2d981c1f7e1c098cde4111637476acce079465ce81b5c11128a49512423a262db82521f0dc62e9acb4b8d253f365a68c81a1efd2a12c982c1c08f35c9057eac3d16f0f0dd0720ae250b880afc585d14f8b1da4cc07d8804dc9f0e49561111f8913281c08fb4c9037ce57dde00e1305e9235711cf02385fdf023056a80fbecf1c1256bbe18f023cd59c08f14c90f57799f423efc459164cd18cd8f3e53c08fb4d583fb34e2c19748d69cf5f8d18512f0a30ff1709477bfd9f1a337e147c6b8d8912cc7d1f1a3f3e4f8d15f38dcf4ee3d08707faf912c7f1de0473f32f3a3df6c2fbdbbd08d1fe71a5a104996c776f871ca0cf0e32c2a80e77737b2e13e92e533991fe74fcc8f730901fce78bdecc160ae33f7b640c49b2280eebc7a9b3fa71ee0cc0bd7f71da3344b2a80e3fcaa30008c0e5472906192ae45ccb8f5206801f25518df7215934465594863f0f29438d660b7dd58ff207871f6de44043b2e88c871d32a6137fbce186bcddffe2b0c818ed5d466bce6ca1eff7fd4f1f0ea718d017b080f661ca5c2640f4e81b088a2ba0474c013de609e82153e61249408fbe8ba0ac0b8b801e3104346cd37f809cdd4c993b04841e9dea3800e7079c06e0f44c99ebe343cfa6b7c580d7025e3f5e4253e6e6f8108a51964644135340ac073d8da68c76c4831e5d83f598b304cc198f39bb9932dad08e9b4d351d1d38397070e0f44c19cd07013d2fcad25a0778cdbcf64b68ca683937f4e8f43d46599688aa7688192056003d9eb6d194b136b4d1a696de4c196b69cf94b1323e8bf119017c0673c3d22b3d00fdd2b3a96dd99cd912a3ac4a448da64c3d9a2df405a0c753005e3abc5c748b1e4f19007acc356234f48cb22a0c67cad4a1d922a3acaa933365aacf6ca19f039de1a0672a3d13f5e837e8f1946dd06396b1e89c20265386ce828282e88c4918866118861ea23e1a1d862caf9f4587e1876118a4c3b9c320213a734213264351d033b0b0e8798930c64432feffff3f0cc30fc37ff1d184ff323e7c19e1ffff7f1219e1dc9f84e70640b0570ec250cb087deb7befbd17c6cacacacacacacaffffff8aca47f32b2be1ff87bfb2f22b2b2b30c2b957aaab1ea922d8f391d49c7a5393f8d757e7fa5c9dab7375ae4f8c542a954aa5522b2b2bbfb2923a7d342ba9d4ffcaff4a2af5a9548a498c70ee14654265d48ada9a15d12cacac50a218a16f18a1efeeb66ece6dddd66ddd9c172a2a2a2a2a2a2aa954ea532995948f26a5a2b2f2a95f49a9a8bc8a8a0a6c6e15fa438b3024b4841e2195a23e444744444447a8d3e9743a9d4e2a2a2aafa27272f1d1a89c4ea957f9948a1ee73e9d4ea7b94f3487ea5017d017e5a13b14062a2a140715fa7e01d386349806d360da900b14141414141494d3e9f4a7130aca4773424151f9d3ab9c50501e0505653637caec088b1b7a84d698e174d2467beaf8e8e8e8f8a4984c2693c96442414179141493e9a34131994e8ff227143dce6dd2269349686e930b79cca5f022973991538182e24129a16f17a1ef4e6b69395a4b6b692d2da745a9542a954a2593c9f42653e9e4a331954a263dce5dd2a5528967ee52e83deec412ff711fdf81c9e449888e8888888e4e72ce39e75c2a95be54ca2d3e9a52cea62fbda9a4c7b9b3ce79673fe2363e821dd7711c2f41a9a44f42df2d604330186c88f47ddff77d5fcef973fe4a1f4dfebed2e72fe5effbeffb64737fb2263547465cc8595b1d1f1d1d1d1fd0f33ccff3bceffbfefbbc97349fe7e5ff3e7f7a9cdbd39ee7fd80e1dcdefc994013099368c66690123e30f44db22d9b6373b86ddbb66ddb3ccff3b69734deb67deffde7e96d9b7b433297d8f37d66cf4c3299f0bc99437444444474d4618c31c678dbb6df364cfa68368cbddfdedbf43837d6181fcd8d8f662b0b9c69335d68d8362d658dd037071b82c160f43badd65a6bad18e3c7f5250dae15eb5a353924a160d484891430d6427bea50d695559f298383e64947c7bb6badb5d6da5aebd76abd8fa65a5b1f4f6b5fe6b62f302d2098005c648de95b0b7d7739782c3965ba32aaa2da76c118c82528489ceeee3eb330b7bfd3588dbd5a77a2fb854dbf34cbfe41a3ddf359708bde19be536cfa83893c8a7b3e0def24e620160ea22a6add7217c364d809e8659bce16faa3dd937565aea232720729cec741947500a99a4f1fdba78fabb02914b14d5bbcf925c0c8ae3f98b832fb75e3d95286910bcc19853210a1a068e70e6f7afaf7640d2a5d74195d32a531eea2bf2361123d8c5d7fa49e9a2df5fda6664fac31d6429e4fb167855dad949943b3a5fe953136c8a81c78cb3b3f9aa9b11683a078e0f79fe266199a32a16ca92f630ee16df5978c32adb5ba67e96ec3b93d3565e449fb31532db5ab8bf6eef6cbf1eefe44765eef7bf92ebe22812f5fbee775ac1cfeb404c746f6d7e9c5591487aaecd317b552860acd965868377d5156f660ad4c29c5a1db5ff3bc6ab58b37aef33e12984b2d60282e524e2a2f50a91518313ed43ec33b792daab24f5fb129e3f1609c736cdb3abd9d23ae1a59c33e672302d9e2f1e878496cfb1ecf8ddd3be42c1aa2f739841e124fc76bb9ca3e86ede024b1da03daf02038e3c12e168bc5409607bbd90c94f160f77abd5ea07eb0131202c3073b1c1004ffc1aea7078cf120379bcd66208c07bb1b70e5412e168bc5c0d4839c9111887a907bbd5e2ff0c5839c9010a8f2208743550e82e0e941aea7074c79709bcd6633d0c583dc0d08a23cb8c562b118687a703332024f1edc5eafd70b6cf1e026345bac10587a70c30141109c0ff6805b0f8863b158cc08c446607ef085f86a7bf0859031ddebf502df87b3f08baaac108885401cf0a5e3801807fc1ea40ff680337006ce40f039dc03827706823fa50cbe992df6c197a4191f0ed086d8cf3043065962b3582c36dbf6431924ddbd84ba57f712daf63ffcbec3e97a3a9c0ea7c3e97ab6fd18313c18b3ee66369b7537db3e8c952e15338ac56246dbfe0a8a7bc1bd84b817f7e25e42db7e4a653b71385c0f87c3e1f46cfba814ec629b7137e036e3b6d98cbbd9f65fa05cd316db8cc02dc66db198d1b6af72a2b5d85e9b10b8bdb6d7f6da84b6fd53c90cd9eef12ed970b69e0d67c3d970b69e10fc79024109bb11338ac56246db7eeec2eeb794aeebf4f8f2f2127abd02f7e5167a4f7747374da3ce337978268fdd6447c38fc629a51ce8244e0b9f6a185f0f7f92263237a847f0b55ff968fcb9ef56475cbcbffa78a8762d25c9fed55feb5cb6f8d72fd4668bb7ddd669bd185f8f3abbaef334128dd120201ecaa3859e4729e5a13c9487f2681e4782f1f5d0b08bd87b5268bf5b0204e322847f942077ffe9d8f4d8bda65d7bee89d44d7f0870d3f7be7b77f1f3c7ad56ab156e57d95eda3e9da4fd7f349fd6fc6fb838b5ff343d4e776ca9709b852f6cf73ccff33ccff33ccff33cef492b1f0e6f3699452d6fb63e0ff5f5f8343d829af4ddf548a17d6c81342286e40d7efe8e0b89e05dff0b89e4202936eaa3e91efb0abff87a748fbfb006994d280f64cb7d30a43e90352e877fec1e7338a5a33c379cf6f88a87bedc533e7f9020d3aefb3a7fe612babf3f7f648cf72a2aa552f7e376dfbdae46f7e1a7efa53e1a4e7bdd6717bdefbe9b5f8e209ea783903add3d11b51ea93d345c2e1567a77be92615daf79d0ab978a5d42f1e0eef9e21e5a13ca03da03df44583a8108db9b883b2a80f5d725fde774c29fd8f12edc474f67d0a43b19491abfa424f3e1a8a297e6f52ea69db53edf356de6d11823c56d7b6797ffa634dc1fe68b67797af6c3e7f3d36bd1199a52b328f059a32726fbbc457f5efdba00ee6aebab762a0010424df4a960592aafbf22d1458bce2bf60b360a960a998924e1a82400e4d40b2a694808c7915955269949fff16a288d4bdfd10e0debe7becab2d7cece27d4f1399aebdb156cf74bf0b5da60dda848c609aecfba38b38546bad75ac75d66a1fcf5a7f9420e31f72bd4cf6b5c9f6f7ad8daf8698fbfb3fb2afadd9b71eed6b34da9b7df5885ff6586519c9c926d9572eb9d6c77bffb17be7f4688bbcef3491b93f3dcaf0bad01e6da19d59a3d016d92059e33e175a29648dfb5f68a7982d42361612c11b6bbbc445adb583b2ec90abeebbb04dc6d174b41d166999845f0edf47c898bbefd7573d2263e8a62c0be4aed97249ef7a148265a388d4edfd10e02685727736e6db7071eaa83caca013501e6158d5d56239ad64142bf6fdf1dbfe56b2a8153246e33e8ef4dc93e4e6e49c9bf41e8e2f7b3e6572bfd69c8eb2d1fdeac238e77fd7c7815f8fef394d646e921ee70681284b56d70664b7ffe83708a867d1b743089b9ed83cd2f971d9111e213aab391f0e8c7fca68bcc79ac8dcdd6b5f8e191e0eb5ed8538fcb7d002d9255bd0f87fca19d34e8fb668df9f53f6f5c07a36d144e6deb48c2f876fd77689ac71bf8616c8c5fb2d40307fb44023d611a4fbeff1170e99dbd3b3090ea76c9bb2d9840eedfb4d94fefe2c7203b4f8fba4906ba1c59286c18082826cf0667c395c07f1ee0f99bbdbf48f2379f49bb1ee150affa789a8b40785750f71e3c79af2b878fd3d6ccaa9d3d3e0a12c1758063a053dcfbedfada6dd5d38c4dc18c855f731cef974b240db69df17ef73f5eb31b5a789cc8d7576f1bebfc6c339078ef8beef691536b30a9b9b4dabcdaedf6d5b49c5df06d95512bb8e8b536eb684863cdf8f7cd5f21557857c76fad98cda549b2c8410f35d7b8e8b9e531963a9f529ecfadfd703fdcfda771ef43f8db2f6ada5d68425cb8362a720f37fcb3dce1f3d28c7c53ab523e9a41da90f1dda010979ac3541fc87ccbdd1b1c2b61da98beacc36235f7947b52563beaf5f8f903124f049a4f7c21124692a9b9bfb68b6eda7dc1e956dee455b489b509b1b57c96c8af0925f65485fd4c7551ee4dbe953196de2ab4d6fb4c8574ebd8ff12795922662ee71e26c9b7e1db489fc6e34f395cdda837680e52043e6ae2e175dbb8eb566571923f70f13e4b1d6b0305515208b2c95d8b4f690f7ab981f1965dc5d4fe8e3a1da44d4e9e3220b1d72b1d297ac51ff2707a13f646effd1735641707264cc1232c6fbef3def6d387edad3b56667596be90c79a4ae5af332daf56b8daf50a307b97c859aba87b8635f8fd0214ae43990aafa3ec044d8b52a61d7772884e4d1aeb3ce3ae439be9acfca12fc70ccb9b7af7ba33fc371ba7c359ae8913a81602e5659a34e177c0c955329fbcc835cac2e64f44d4e4c72c7857ee462fd1f2ac8d4c757e3d3978cc15f9f0a41c66c5fe9fb1020fe687c0e21cb1814aded3fc3f95b0ffff994a2e88f28eadd28ee71e284e304aa53564b42f1d813e7c8579ca6e141f531ce99be3c48dcdedf6eba8748abb847fa126dbdd9c55af778c2d181f7a9ee97530ffe54f3c04310140fba7940808bf36128a1635693afaa8de72f848e659aa6572d919005a1bd10da676d6e0dd446bc354cfde7dfcfff5292ac1b54a57d4c35867b54d91acc0b7205920117b5ed6d587f0b75d8aff6eb573dce6d0488afe46b9f811b30aaf1b0859fd4befdf8f242a75b69372d6badb556ba6dd5242ed5974a5470b34729d33e084bb5f75e6cdb6b1afebafddb30f5365cebdf229c821b3e5dae23f47dd0f781caa14d51ddf44a47799441defba02ce9e2534c8fd2e24ff297c0ffbee5c5ca962e2f35a48c0fd9e2425534854249d9a2a49721f7248e7b6edbfece96afb6273dfd4a0aa58ba9f0013e19f528f9f4b7277d573f1c2494a348288d92ba8776a1ac177a3ca9e8319ff4e4f4f43e1c1c178e2f2fd4e3bcefac746aa7fdf08712593e9d4db65767955eb91f36b97b4ac3573424fd143d62177ac4287acc263de6935349ff286e4a7af91bf722177a1cb61fa7a5ac21f5c8b2ef97a3fe767fab9f77154709b8a7d170a1533aa5f5ebae7a3462bf98dcac932ce3acf293df494a3539a776f12ddf9fca773d7a4ffa4eca1d3038bb789f7bfadafb9031f2bb93952dbf4529835c88abf6640dd27be8fd49d8221cf3ee7ebc61779a88294392360901b3a956ed1d2e1e65fc457c3531ce599441228f28ee25953fce9618ee608951e1335dbeb23f5f3edbfef4f15545c3b63236c5cfb63f6b8e70d54bc9668c2b23cacb27593e68c7c937c9306594e58fa6934eb9f8e305799c3cdb4a1df2690ef9f4290f4672f0cc1ef9009fcc3d4a723c883b5cb4cf3277cadb11a3a4682955f25d682bad9c13bb57ab871f66e3b7b1f1cb978dbffa575dc4a1f6e1a8d74e79fdcaaf544bea6153fefaf547916e2971587149be54a244923d7d48a3ad3d1828854a6badb5d64a29adf56badb5d64a6badf569a55f2906b9d65a6bad550bd6530004440a60dbbe04e60e7ffb5422678fe256a2c4cdb65f45fb32476ecf162f44aafaa6485953aaec5b0bb3ad85c925f28fe2b64f83c5c5f9e2f3e043c6c86d279544940b9ddc783665f9fbd7ea0fc3ffff95954fa55e45e54fa747417993e94ba5cff9bfef3defb7ed317e2bc33bb1a43c3a036ab3a9ccd5711ca433652e2c08a6333bf044aae60df827ae52ca245c692b4cbad40e07c1407922c5995259b050cd7ac39442964a527064df225ff94a2ab109daf4b1d095f92aa2e3a8248bd9eb92a05444330000004316002028100c864482b12c08236172f214800e79a2445a589c4bc4510a2421c618a49422861043004006066064c401002734d31a47229058ce311731501086d20b13c9c76d18ea9c890f8268b4be475c3317d907ae2d9d1087f6db120fc76bb9380c158a180a44f484f817f12610816a12851f08ad4aa304986000f8dc661292e986be11250280729e4d403802a99062624723372b871511e0fa9fcede35816a6b56a99e6a927bfbfdc01bb9191cb62298490bdc046300211a96ed2cc6b7ec755dfb8caf800cf34afea323353413d6129dc77def4cb6a9f5dbd8d83a71e128a03915a2b83a543399f10b6fd24c261d1e715d8cb20824c4db44ef4e2d7a39a4f533a0d101e7d3af79a4320123fdd2bde7643999e95b865c13cdc39392841c055c960bcdffdd92b3564d13baeb41fec9ddc8feeebb7e619928208409abc609f9b9b7ff93de8fb382dd476fe1dde785b4c9663afc11670f454ee13868897b7ab915002289e2f4bf2abace12abee638531b84569609dac86b3d9ef1763fb25a784991eac43045f767052377435323eee37a1a638f999b201f07432b351d0f964ce763a72ac4307a1448242fd1f12dec0553e1ffe21b0c7a5efb838e77ae0b478e2929e5e7dd32673fe19044548dc0c928a2b5401af70f9272725a152863469a88b009a9904bb388fc71a418ab957512a62bd3728c4f774ff68408869c0514b66d780064f6e64036f39cd3921020ab6420fd897753c0b2d101b915601f999ef89b9011de16410a1a23c79a351a507efd7d888d4234ab64906d87babad51c20c07a42c8528a28908ea014a5c94810c79ebe4ed4dc6f2a84a5ceae66166e4165dec1082a6e4166dd932d095ed660b07a83679d8d9b35253a105c0179cd0338a13ea1acc17b0acdcb1002cbe89ec2db5758742905d5f01281308fe0d4b8773114cac9c30f202926100f2904af58af9de71a52f886fe6a2e28a0d53c001f766025c27d87108825f730ee2e8074a9dba16d2571dd75c627e672a35a31651e3106d633317f6f08d2478c02665df744343e69d804ed481cbc3693d009d9798e10280473fa8b92c01a57b78666282b45460a815bb4976734269aedcdeb79a38991aa89183ff95de3f490fb6d1a5866db68bea27e89fa39fa756d87c54a31f6d9f4900800afdfce63ffc5d82461f54b500baea3731b314fbea61295e655c0a4fb0ccc510387a54920639835a1fbb5a952dc524494f7e0e2df3f4594a3273f088ffc84c05545cc84f10ab6ef463a88851115aac789e0177fa87fe505ea9040f38f64e150c0bd587da6995e930de890e16f53a20c69ef5e434c95d5051247d8c200310a31207a081b132909565e96cb6379701a41ce80726d9f49059784206dea762e37a9c9bd025a8389bc58e249da7f3a54500b3930cd45f6f3289d9dc62e31f3190062b3b9d815bc13e133ad66e30e601272771a8e1df13bd98243a2f156b97d4b3cc3569e992d5a31ae6ae653d355f5d7b4d744843741bde96e31a059181b47ce0a47b4e38214605b1e790ef7638de507d6a7c049bfc0d350306b44c0980409556d88b1c5af2141a134d555964bc16bebcad055883c16c6d487a261449a8fced7d38d97acdf1bca66e528ba78a28ff857289668ceeaefc0604ead9e6f24457dea683ebeb89ddbf85d6e3bc56d11760044725cdd18fa26339f14b5bce315a7e209e90e4580b7a24c7d3c4cb6ec09f96ba89002922edf52efeac7867c122b22ebbff5ee9cfddcd4c251479508546ec88a99a0cbf03a199a00de496d13156f14f50f4f834f400e53c726a7d0fe20896693aefc14c056b2569904b1ff60be51e4f55ea3883e5a71c2f498eb8358a13163e12e3e093e3628d63ab8e561c9765789c226417e8484bc0becc4beaf6ee1e62066593042f339da68ea45f1f0a5a0557190f63ef3c231cf4669568d3af8682371813149dc84232158462916e3794702e2ad6d53add0cfbbe491e67ffe65e1c07ad6f9da9b8807d35f710eddc206a98fab7a404869e4a9a91bbd5b7cce21a2c4231f1316ed125391500504031ff7e02fab71a6a1203f3fd6d6a45297d7eb0655bb0764b2daca42f7d9f53d06b9423c4dcd1161e8baf37c5fdea98de510d4378f76aeb014e8728007992e2993725fcdb26a7915ceed045cb7dbf1862f5e0ab8e369366a0f5367063b13b73a16c38fa878b94879a1f4b140319bf3b55f3273467e35898a285763df84145f044ad46e9b23659b72711d6cc9e0710549596fe27e996b0932e4284bc519ee315e2dce64d4271b5583445f3150e39046c47749be942849723ba0a9115f12530a1483b0e0a2361e20a701d4c34c8685d64beb0045e61230176a438fb9408be1840f85f344e89af4894e719fa170fefbe034acb484798843ac7ee97d727bd50cbaf7a26e0f0bc8143eac3e647332d8ccadca044890767defb529e003e8e9dc53f09d5c76af77d124c55c5f7812ee84c626b90a618114427e44011cba836f1a6a04e06a09d7012522dd2171c6eb4fb449eecef264e860de918663fccd02324890907eb4e598ddc653f663f1d2e14812381a68ecceccbb1167d72fca12a5100961da1fe08567d1e574d1dc491f6c386ca25e9991f149c68a7bd3380eafefa80bbae9f3e738e3b7b410395f1376596b01a399bee72ce10d416a72af0ebd9429fcc08afffa93610eb20ad19ed906e22cdf00bbf2414677e0cc22dfae955620143731eb792c4b2fd223e509581e31c12da080eac7240957e9b787b28e94b5daf054c62c75c8f00c03aa5e7d09b8433a20c808830bca067bb480ed5514671f90610b3e2741503927ee622c969104b672e2925912f625a4fa61f26c7893d04be95035773930ed75aaab7ff02b16cd8f4571b8dea100064f4b91071b72d8f8a92b7239e56e51ddd33dc27f685d47b6c5ebdeaea01aea0f2f2b9e98debdffdb7dbda642b0ac2eda4ea429da118f52030ca4f466e3baa794f18b6de00e3240725f5ba1cc977d6a1402a87de4f6862a4d4b0257704ef539ab350394c8c8a6ba4d3689e258120249d684c84d8bcd7b4123e9c92eb4abcd617b41c9efe67e19c222e63f84a2bc5346a02ac965ba21d26d0d15efa8880245a72086ddaaff328a67ea55ff4204e71e601e78a17a96a33e67ddceaa09e65e556fd0994dd7c1189f8e1e926ca0852f9a1452b5e513167f352d8497af28788f9bb42b3392e8635a53aa47ec0925c1fc6fe8b2375d26cfcff1b24f2d27c6dd4178361bb2dd4c877e31f1c8a770179272e3ca5a68adf2d6120d7b210d11d4b183b3d3441e4fe1c24050c924bc0deb335d7aea2c5d997a48ad49b8da35a3330122d31a42213ae262317190ac17796c41a0a9b43188c6db5991042664299e48a199bc2b881349fea8349bf286b12ab340fe267c40667a0957dbee235c0340359b136893c073417773350543b08a119e8147339d883fd34ab5bbae066f44fa4b0b7fc2892cec30f291850834880286b7630d60a20d71d65ff45181f02569da5cec2f83bf5e49ac24c23ca4fe9bd1d96d6ea4b77c0b9451607c9d7a7d7eca38688272b5f850dfd27b8e30c762a82e41ea830d86ff53911f946da887e64c6249b7d832632ea064261b756ce7ccec43950d9b8423958c620b8824e4dddfd2d326364b5a26922db2681424e0ae616bfad088752c3a8e89b48b53087adba77e72a35cd8389f6bc8cdc5335c6aa9d2e9ef0993a16259f483cf257c38a630926680f4bc8506df942bae5dec7837cc02131eae452a37c00ca59c039542e82e7a6f786dbebdaefef6e73e1f28c37ec6dd2b3bc280fd338a9a170cb9e31984fa19edb82a6cb409f04bf2de614ff52124c2c16cca22fee20b85a3f7ad092043618ae8bde6bb5d0408402e233618e8d2d9e04b8970aabaf9cfc215d5d8882611b1a2427ed2d125427c0166361f512459182ab636a2a3b215117c718cc364efe7a3ce116e35cc32f258ad8bf9ce88a45245d5a5767e5ae3a4ef527560b9c529341267ed20119d13f21acbeea1c3b8491404a07a8aa5b6faca78458cfc9dc670add1d17227b2cf83bbf58c982702177d59f730d183412519cc7ec54c5c3e6b485e31f1c5f167fa96b8ef74610a988b975dbf8a508db86434809604baa5f4d4809a5c2cb340d6aa44014e887b31f4f3201939f4533dd266b16916f16aab99fbbe0ca98a6c46f29132e5c0d14d82d08ab961ec67f1feb8dee6a9c0ae8c5797e500922c6e314a090c3fe54b63e00e17930108eb14f18dcb5fd62215752bed33eec27de480444ea2ec2c34f2573933515a244d87371e157180f9df1153ccf2609e401c18b7317da9f445f23e506a0ed1958560d5987300a1d2c9c1a30b09f77f54c932687e955583f229b5b3325d3442d3dd97818f60672b96aacf6669980f88dd22fe2ec9cc5e7181d71ecff903a36b0e844253bd4a4af04c588f5b2a0697fc59ce02c91ba1eea17be12c457665aed2a60c0c6b010dd96c32f5aebc00f5ee44bca6111dda98b70b949fbac5d193301626ed63404e1f9f69945ab394e4e8d024073e009246036d49e55ef8d0c9d00cd02c060c3128e45aa24a052f5d1093a5bd5bd11fddcb3e1f14a884edb260fa0d079e3d1b0c92a5ee6057e7e018d32c1d8ca341da4d6d6b6d6beb2bb7f83913c3ebdb5c901ca556bee230e0ee393ecde70cfb617d5f0011608407b3966ddbbc6a2fee1456a19b697aaeed9ef7006a39301b6f149ea94d1fa4cb9c34911e98a551a25c8f4913d3622a1a466f2ccf60878ebdc779599be8c625c6e4df3c0bdc361c413f2eb05a2a89a22d40e35e80df50d53d3d29ea35a23ab6d163fe7bee8bcd3ffb4c2820171f180a56490e96d319aaacf4970fc388cc69b1c95ac15471c95566c3531e307de717ecfb44d9875c434d03ddb9d8b8050a9fc204cb23fd0cc366365e8703e5532bf9c96cef68ec8058a46218b7c52be85c818e1a2e06dbd6f769d0a39fe29d0d9c1bc43becb205950688589def26889f466b58b574c1a22b73704e653f344a8432494b595254814815e87000ca34ef7a90b90478afe915aa39002e7161f0d40604b1703a246d0a86703652d14002e4b0d0100ec1c6440a4ea53e294dac3d81c2921831001fd5eea82e5162d8065e91a927e8287744567a1426945471409f05d3df71e923b450a82dae0bff916ddf8a78201b66d15ca4e8107514123821c1aac0ab0abf11294516c031ef1466e332e3fc54412ffd5f070aa0fb8012cc2ed7e0e50c06244d6a70d6d7f32a2263204e5ec2dd5ed1e03fc7797e66e4bd7c4bea455c432c7fe88ffc2aa9735448df0f0a4454bfbcb60177873cf2144fdf7af1fa1dbc5fa2c0bab24d044ed1c29bf4e3d50850fc2b28c0827e79ec3f989c261fc7b36d804c8b18861c45accc19cf37b4ebd220e4ee0db093b6c73cde5d422973f50f2df7b3b91937276a1a3e5ee8039941df2966d97fdce064680a93512ffddff3420d6ba9ee840601014ea22c895213abdf1b9a007532e50d45bbbc0d4823aceeabc429923ccf578f64b0102f9133c41f0656f43f629856a516a5cd7a352c2a3bf5ba94440cdc4101f178352ea676aa22d3e520af34bb7b3e21540cdbf125a403d550aaa63558dfa759b7bb947842ffd0d8eb2116eb84b123525784584d1e4a1231c4d18efa498c8089084cc15f78a00a9525c03fe5618fae9dd35c3410c72c524deeefdcce546ce08ba341c092defaa44ca3ed0255516d06d79c4d8b7a667d462aa7fcc68a20840bb75c9130a02467e390390722352a801f7c865f60cae1e068d4630883e22f3b0b7082011beb3f8fa93c8cc1b8acf74744c1e698703c0608b4fd15bd2fd36801e073b0a906f8afa08b2ccc89318e91109098b06576a0510e50c72687db41e2918f87210204b6fcbd203c8f763576518c4acae3f28a0b700619a01663ae873f8fdd5a59a33aa0362b41ebbcb34a7b1803869c9e63828a5077ea67b75628081abe9453a265cfb0ac6a2fd07d2ae2ac4bca92e1a0d9d40c1202b8bb6f53a08f857606d40543f0128fa1e9712a523d919d171782c8883e10d0c25c0e084200cb9894c2dd2c80620cf086230d1ce7d52662efeabba22e2e3fe4f7476a09538c5286430e9b308e86df374391d52dc456c44aad4240973f845654a4fc8121585fcb559c7229928259886e24640e24db825a91595a1ac3904c76465302fe23d75640474fb18641348554649a1cd534fb77140e441a70413509a904fe4124632e5b778385209625841658003da3914f44305ac653d007bdbca7d4fec3fa360a7ddcc530449fbc2c0eb81eaa0379df30d002e9653013e8e39fa4fd99b62e047e4f91e8c96b1622629460506162339d8ca8c1a4550887d46636d3c0e811faee41e861ddc8be4d3737901b8ed134057b152517afe19136b91938b21e4b162f7d14f5cb3a80036334ba5abdd5324a52234c67ab9a7bb4c6ca5ab755f88558c413e9ece20e419ed3a81c65f0de64c9cbd5d53d39138302009cc95131cbe0078ee0d96264fc630fba19e0aa055f2cec0d323279b4e81621744a3a847ef3288c9cb32389848ee68f17917ee50d1ca4077e86fa852832aa3e891307e23d326cdebe2ecb97afb2bd92aeb06030fc7cdf5b1245e3963d5fb177bc2432c412b205f7b6314b519241ea64f4f695f803ddf99a26606354c047cd034b8b93233387e4a85559c8aa9d31fa4b9cd916470e7a7b5ea455477b3cc29666377b52e00588d01a0cea046b712b9aaf5209de754b2827975798583bdeb4db99f0e24b2e38fe865ba98c3873ab7fbd6a3c52acc924b063e0e9014085dc56c66bbca00b2769311a9cc572a02b0e00cbb3213691de710e1505ccda82ab6a552a5ad27f06c943118ea483ab061424474413292239481df3ca98610447b35899eb0f8db86815cb09843f7decf229b03da75ee440b5fd59504a118c49681b0fbd1daccbc28b1b845382dcd54f965e7acb6eb4a36e458cd3eb2845ed02fcbc5430463888ff55d32bd354535534a0aa493cc03c1a498fdaf82eb2a6fd94087d517f22d7ba3109af8eef23aad6299b9692f4e62d54cfc1bd34df621fd0972e7fbf93895b3f590b03e009466672ae4bc8f813b65f2d08f2a06134da32c136242f01c159ab19a155145f2a822b8fb2654918552d7227c8eeebe797a942768a0c85620c3a8487fd8eb02113524be99754df9c0b179a2942fac348d082495cf280e58369f1c08f54195f6a6785572a598f84ae7f2e8f38bc37156fc038d7ff00b220c94debebb24767f59a21974bd3f3f61ff6570c2fc5066c2a8f9dbe3a94a22fd50b2e7f7e5fcfd65f3f76c76411b9ac4a1034609118033e14a0b7abb19343eb707b62933c23cacc5f13735a9a158f64fee7dd9346906234dc64bbdbae8f1f53d8ada045f44f4ec64ece63c5acf26485260dddaa31f58c5d6ad3d8ac0bc6ce89ca755d548ee745e22615e1872ce6ba96a847b3a6f91302f0c39e6b15625d22d9597689817061df35aab1ae996ce5b14cc4b03c76968419d0d1dd9161fe82ce87107be663c3e183336348c0f83dcae29781064128a9d262d415f7f10411b7443fbde7b277222d9323911936595c1844e2a4326277292cc323981c96595c9844e2a4326277082ec3238d1a0fde69bf7df7df3f63b13ddfbefbe7bfbdd77ef5974dfbd7debbbb7ef7c1fa00fa8edafd717692d837468496b90d74606648bd75485ea5c954f78e6a0e45432f254462fad32c8343ee4360e9193578b1c972dc0303b1b675d5ec475110987e9c0ba91137ab571c9902449304707c7ed9b137b398dce72d371c82285c55d95aa6abec5168f3d51ef36e896419924e53001d50087e167801a4d651272cff248db5d24436ddf9cecbd41ac8e7b8a830b5e0c090f1a796058fa13bdb7c40bb96f2128c1cb9021c141c75a5206c93cf35097dd759dd4bbc1ca11a5cfe8b8ff22b8d897d09001b119500641e5c1a1ae5ded32d173c7f64669cdc230566ad409397cf2c867803907d9e94ff6be2daee37c8aa0045e43860a463d609cdec45e97c7849c6f1944dc4b7898a1d04b312e83643e7fa06b5dba4ef6de6645448967e9b8af18a4e065a8d0d098172c83a3e77d5077ddbb4eec79c5bea462b9e889d33a2de418e491eb881d8065c53649cfa5771d379f3ba26df0f6d4f3726389cb20b14fe869823ea4c43384dc577065c99424a4b48cd6e9887573b2c715623aee2b0d2e7a352c346ce48162e9648e7e8ac9a41884dcbecfeddac9ae48225b5006d9620106399fbae75f6689e4262bd420ae0d61df98a5c9a1649542bc288632c0f8e0f88c1c164253a0c11f6aa8350c63103123a3216f883f98e23498fc69cd8d59c01bd91012e31c6cc5e07a0f2ec936725f612cd480435b8ea8f57008ef89ec8111c6d41ed73aee39076e1eaf6239a6534bcfd8e018d0e86304c31d4e34fc667e078d6a0cece18e77c419f500cd3a035cc4682fe248a3a3c10fff1e610bf6fd00287e2b76b4d1c19cb26ff348103d8cd0b308dc4bd988d7cb432120692c882f844334666a03c6281b66b3ea51028c88f8f022461a331b87ca3cb5c5b1af16508211442845fda9195c8b7a3036d7b2783ea75e47100944e323e6d533224e384c4f628a339b41229111ced93c3a2fa3e21ca2566cf92bc930243c9bd3b1b0373c5d5180b14f103d7c4bcc9273272b01d7cbde7a4e4c5b350c4c7c3fe0a82f74e9ba8ce975c833340eb8831506e650e31b0256aa189f786a863694e369c0268d5d5c8f3e58be1692813c7103b88b82bbe9b9ba95e1e3993100a9fa130c00061d77cd0231ce8f5d2ac32fd048ae0d80fa75a769588214c076a529a67218afdfa951810391ad0b68518a065a1c6a18ccf4a82580b3d17fb06a866b53d20ad38d43367dc76c1cb20cfa4c949e3c3ea00d2ff184e07073ebe857cbeab83eb3ce7607f46957e56aeb09a125834841c6eb809b2030a0c7550c973de0688560cc16f2cb178b0a79615e440c34d81f5176f972ac935900b63d22ff80af10d6091dd203e9da81ce092a719b296a8fa09053f89f117e5f954af9529d5ae733ea8434d4071ccb4ecd0e2e9866b820276dfddcedb4fd6443f15ae74e53e4d2a6e8d9a4e96d779fdd6e0c61324bb4ecc6e06438079cb29ce2515e56878b94eb210c6e62c761fc6bb8fbb5c5d4a516f4456d1e30aad70a94ff09d5fdd35957242465d12e1b90a9fecd3de05c91109ff6541dfb79b85767e19d01090b5ee4c5aa9bbf1b0bfbf0f5d3e7627797df283abe8edd197433c9f45a6beedf1706a0bdf4beb846bd1a2da12c6be829f4c9c24aee881f9b74b2f462f1ed2729c9ceb31e9a0d6fc871de85150327d0e5c143d718f20ba40c249b4a0f787914c8e053d343a6e3d7bf185c82e126c1ae47b8eca3098fe48c8795498edfd972d2bc1634798f669176d69023e0ec7076b636e2057d1403234e31a32288bdd6fb45bb13d97a392188746246f144c77d4ec36cc9528f81b6ff8dc197444fef8b343d683a993b517e68d934a96464b175a1714b5f831b682025346bea7231b1b482de1e6eff1b832f899ede17697ad07462f136a5ae4d79f513eb9d171b632509a6fc27cccb9d3f6720c6224654e5882551061e2df0b387fdc326f5caf06bf6a13d1cd876320ab94b5f5389ba2236b62e911ec6543e4b59dd8910d539624b94815703fcec69ffb18bfd32f88e1d783b07b6f386993889ac9f8e62f5ab82e2f9c1c45ec34f9abcf3f040d72e366e4343cb66bf81aedfadc199451e2bbd8ba241a24abcfc3b917303c1e4037e869a2698c800977198b2d0762b0ae7ad61e28c3ac7b6916403d10abd7bbabe6d267526786b2faee740d769de1cbfbc1b50dadaa6ab78a418266110827406adf407c7232ecc87baeca6e534169538f9187c7dd50eb538f005d3eb2ec84e028e31c9d1c55c8a70b44bc23140f60f80330aab14dbb5caa2d5a7247a51e2f05b4a5634ecc0afa7eb8b7668c1812f6fc45de876664247e45b8f87932612ff0415d1683720b807bc95c9c0016a04993ae9c21ba0128d1a54a60195fff57a525dbf5b83338b3cb6bd1b85878020e1b2ee408f8d28371aab3c2b49b8e38cc76cb21171c1bb6637f4220ae79e95a84133d52420f14f574bcaed6333f166d16bfb223d0e9a4e66c6e8640feeaa6842f7fab54b2f9684d8b0603d6d22bdecf5adab530cb038d065b79dbfd1d085d9db80e3e766b25c9cbb2cc1406fd0be7731d8251a6090b30b7988bc531db5119a8c7f3eb1c1ff8926786066ad2dd1c8b77a41c05de8baa1148c0336ba8380fd351c181f7eebe6084d08331dcccff5814af051f4367d14d7116bdf2640545f24df960d457b1385645b87416698dbcc6f793aa1eb9b308accd581311e5e95dc1d85ac8195d5a421651630d947af25d5f1b433d8b2c093abd75d28be5a7bb1761c35a9ee9764d4973506d3de2b2d20d62475719d4a9e7f0dcebb5559390daeb1091eb858588546fdd3d79372db472ed1ce93d25db8e9808af0c917562ed0f998e868b03cd297e60959b9ec6b1f5c4272967405fc79e15b8ea12d6aeeafae2242b3ec90651422cd882d0ff96b3d9d0dc720f9f3f1078998eddb17e8f781eb1bd4f4810e3df0c59c85ec0c6e4e23ee28801c9faf47faf84f1bf5a0e0dbbd796063e942f4311c0d1595fb9dca09396482ed332c5dad0ed435fbe5a069d7bb94b495a70fdad26cd03b2c5d289a18064d1502c966c22e6a4df257bf4613accec6ed3deef817a726e1a229d941cabdf10bf0d5c3d16aba7208d038812102f54381d87b731d3a830396624b8abab6d911a787c7cd90e22e6965b9fb275c5109cb8ffbfacb9c0e78ca214afc432d987dea631f8c16cf4ee8d3714a5b363b826abac31ba6b3c94e2d73620237525ebde3ee9ca3ca58b307c790c6744d3d55dc1c8c4c7eff1137d233239db31c47f055b6b7dd1d28a7d32b340e3d251750c9dee130a9808a378c824af0becb78c3cda96b00e51948da3a9b81f77fda993599a35c9a8bce2a43e26b952b4586f56184e23f95dd4a750f4fdfd7de33343f7d29ca42fdefc35efc61c9a3144070d49af541eee0ffc13915853545b7d7c4644ecd008ba2a1171f5e9ccb361c3372d56fd917000007431200679c5716032869a8f7bbd422b341b9ded8747d371b3a33e5f48d51499c5d9dff22527989b8e5f3c7df856f3dea243526beace94de14c4bbcbe7ea0567fb97874cd342f17a76bbcafdac38a775b696484f8ca0f856bb36563f26299b293984f93c2d5655bdb5c969b6977a1746a53f5eb1256d99e2da3e4fdb5886328a35f92789f33cda690662e68f2bf180de99b57f7f28fbf48a0d84ab96244e395bfe5cfe64071ea2acdfeac3d8cf6960fe67f37ce40e3c90553c330bca5d3092869e48c1299013962e18c356814bfcc5ae8d6fd43dd1238e8930e391a18a6825546b88bc2cb520f2dc41dc5bdc39d466e0b855c40919048eefcf5d717e819427206095a0c43c2e7323cf16067d0bf2e837ad89ee32fe2f2016911d3002bfa225b029532fdf9130c920c69a899b039b3be5d74b81c650dbad99c99c44f997519fb78b46442753f692a5d6f3892e4bc8cfa25b446e2d44cdacdb828ae7dbc211eec43f359fe1b956b057e54302f189f4979adb2627c267e57a83c08d20b6a63bc5c54234e30166c8246cececb8f8cbe6ec59d0455cd734e2b6bb7aa8532a571b80154fe8373749e7702e3561a5d308f21f63bd10192cf33b7edbcbb67f1673b57f2259a34b88ed07db8c875e9b7d6d4b8b86df774448e9204aa816f723faeda05e5273e1f8f234ef87f21afd9b036c8b65fc83a302ce9b5132df600c0fb4d8f8271bd3504cdefddbf754fe60f2b03efa502339216e2a717a4bb33c901a0e4bcb05435aad8a102e76d7adaa12064cd0efa71d52274d01d8c772059a5f0c0e8de7abc5ba09d4bbd1116e42900f60577863d2424b6bc6a3ac88244fd227ec64006011284a04082101468d0820229a0075190b21f320c462b89b5094c98309d29d3263561d2b4a64c16d35c4d17f09244444f85d0ffe98b8d252e0b3c68f593a980c73015668cc87ce077597a02b04ca193f941af787e06aeadf1cd221a1d71a6c6cc8d62a5d7f7b40651e8639c1a9d6b57365e929db71fd3a3080440437b6a1e7196f2e3fbde92db84c25a0c767c05635c160b018c0a09734b8ff3ae395744ee210756e4b10d9f054d4e34afc6beb67346129ef36433afbbe1fa5ee425252949697bdcd2752a428a31c4fe94748f8153fd130af73dd84b39f479a515f5408a1dc2cac53fd64dc6d297bb435efc47219ba9683f5edb8cfebd6e16553fffc9eefb63d4fdc39cac282a87fe439e0c1695fbfe7b54fad348fff398ec282a27ff739aac8acab9f945141dcd18c24e80ca97c7ffdf2f545199c88f3628635199d34f76bf3fa2ae3fe46755540ee657454fc92a8216559cfacb3afaa3a6fbc32f27151585f643e7071615f5fdbda6fc138df6f39567151525f773e3a75c54a439d45008692eb9853954d92b226090872a2ae3f613ce4b2c2a83fe41fdfc3748f26729ad75d00237acc73916d500f8dfbaf4538df6f335e7141525fff3a3a72c2acaf3cb66f2434de1b76f8eb9a8a8d56cfdefd92b83f71856609531edbae984170d45d549b6474f7b1976b71112f1c8c679fbedd4a0d2807de555d22c2a4da42db5ae650d0bab925054b11460b7d5ef4cd270655199ba7bde2e8e5554035b1707fe121f6943684ca78bca086aff5f54e33ff9f477a4fa7b6db3781bd1c47f26a3cd0c50544915d089130011f65a0eea298a7ed7e50c3d6e57549fb8041515de6b28d5e5ce99d9a0cf54e59d2c86aebefb2e9ed817525809252c90b4d02f9e862bdfcb632793ceb14cc85c4e0b8eacc45e130432ba59adbaebc6fb9aefded017f7460b21c103e65de25371121f52e3d6a332e91007534191f9a1b151b52706e2e34adea42e7c9842031b4d8cf1861e96abd95e4569a3a53d4dd4f08c09269749cf15154edd6455abaee8af7c8ec94c84a82d8e54fab5ed2077da58243384312b47c2eafc24e6a9a4068d4d81b99bd31f33146306a7fce9a1b21a46e3e68a0facfa6ae386a90a1ac33ebc1071c81d8b1c7e5a4414358ea72c37e4a14d8fca2611f1fe3195dc2356c0d879a28ff47644eaf77d155aa2c74872295ad193255278d4812207abd4618daf7306f2d7ec7fc2fa297ff95fc227232c358479ca926b33a40b0aa86e57123668d1cc7025ee99d0e8e955d307fc39333c6b7605a9ae78209973716bcf801fd83afe054468878fe1174c89b579d1c06a953ee2af2e4ab431ad5780990d9bbfe06130c30a8e98b1167d49e72708d32f34dfd02272cd2be0a295d55fd9316f103585e7be385e4f798f00283ef5575c014c31a179e90ed902594031764870f8e83088c8ff4165f04174fe4731f232aa3fddfce058422d4cbc873b0a25ada91acfa0504c71a196d8c8d54f32cc73cfe97133e9922ca2726d731d6097be8ca4d04a3893a108feebdd01d2861236bcdae68845fb7b3a84b8610327ad1855f38731f12d5af14da5d78982eeac5ccbea11b18df9a7c326a013a22e0f02a34e046efec2103623c26e2dbc51c2839f3bac1827a28ba75a7b8c828a288fcab14fadb36de3198a55c106acf385c7a32e1d60ad7fd6d2b61ae9e933976dea24a62c3a92af9560cbd677f22e5950197642f23f62b939a018d1b13805085c46d26ed9ac5bc0cd577928ff47afd7d47b26f4ff81fb2b2aaebf62be43b611a9f57eacb72899a329e8177a5b534ef3a666c7c50280717276ece6b7ef132aae74eb991863dfece0cb71921676814cb72a0dfee76275feeeea58de14c5c884544585cf624c39c5c6558e5de958793d31d79595357bfef76e39f397c445028243a2f2ab19330f513bdc91f7c2a702dbe280c99baa3889627ba79cba5d3658639dbfe401b36919e2f4819bde9b38843db067226ffe33b657a943bab51bdcc23ee016badbd022e29117931f5746d008ba6229691c4ccc31840c9648ae29ba088cd90024cdde78551d80566caac9d9133d38c45db3cea06d9146b9e6d2c453d6d03acfff41899d68870ca31493b01fda6dba4e2e492797d47494dd8845304799fce00d3747046a55f53fb3448c62e38873ad31d970132df5ea064e7d919c4d2449bd76b17edf731a789171be1803593e07240dbd2359436c52a4148c32b54f9d3a05b1b742dea153027fa023350d8f38c5e9277fbe6376a35a1685a9719b323b96149656b4a1a7ae4c205c1706b34b448b270ab2a56b8582cfa8071b0e44e27bcc97c067dd35da4b1751a5b74d935d26a147915acc0b94baff07d4d7f1d7c6b929496b56ae2096c21068df0181fa2f92d972527447a22421c6a8e2085a1c2021a127127a7740f312a113f3e421c19fe641f3cc47abb42610a914b76762a4168fca0c6862447f1388667512dcc0ed33126d3305f7521e0dd36e32e962eae4c5cc0c2f22ca4e8607baf441b2ebf83b3f7fbadcfd7542f1e9ea1b502efb08020d4e0cc3d0e69a2b60632bfe4a7c6abc12c5158e3c438d008202399179108a80512300bfbd81442aec91b38eb8bd6b4e8ae7b274a8c28c33fcb3eafb3f8cd68ff726c1ca565f66a53ab40cbe9eb8b582d291f21923c573eea1c84148f2078247898823a8317a47d6b9115115f16391e5e1b4ebe8babeb9e57b370b696285bd72d623a0e41acfd73525e4aafc95c4fb5de24d99edc1e34207f177de4b5719d2f1374c7381185cbd3094fc229b2b5795b3c321cbc9b6721311175a2c85c291d89064448dad65be4a92969ae2085904ff16ba604a1a1e690bf09277b250bd7f03399080d2ee807b919d87f41650684f06ff8d2ab27239cf7aabadf508ce80b3142e53cbd21a9d03b36a74dd7fbba0eae5ebafc7b9bd3b2a5ea15c48b343d92a157254ebc2b70b750266f338626f3e3afab528c4d81656ce5c4b313e2d04bf6ff5d10379c236c23e775702b6a9b05361057eb58d1d2b924f7e2e31b3198b25a90655f6b3e2669e699c1d98905e18b692aa713e3c5645378967e7bf3c2e4da3c42b31360cdc8061f05cc402ce188cb37f809b44e7e68c64b81a0597d2968aae826a84a219daddf153c20687851ceed8821b4d6444205b241dca75b16da6013726f1737e1d2accd8c2d5b1c71cb1e1a03581d563a237be1aefc3f4c15c230e972986272e21a682343dd01f5807b7207ec1273acb6e513c83dc0eacb338788e4b735178ffebcffd3bb579d6d428e19ed91bf681dce4fbf0e9f395b5c692ea0cbbf64bea54334f62fc602d2fb43400febb176086aa6df3d1a7c0a163b165c1500c63318948e36932e75464256c713fabbb4bbd0dab01e8c699a1ec4d9d173c668367a6c17c49aa9a4944e784184167b2371941def8e371af2410b7489ae53e7ee34c0079abbbe6070706b0b0d1104c8178658c3910132b1c7c122e17ce748cf5cc525fa79595c1012d4c550b86178d257e17b0e2647f35c3cc40719e845bab92846f2a95312dc5139223b6739429ecb1c34fb675d0225aadc5e72a6e64e10cc4094a85f15f3066df8277260c3a3bfdc1e4cce3e0bd149ed996f93007b33c3e416af4a03bd84b79f05e891f3124ad71951461df327d7d5cff862c917bed9201c2bb05c792ea870cd9cb64a25a3fbd15af4b68e62f42eaa16684240fabd47b6cc3f236d8ba517c0c7c2a028aeb5d1ca3bf4df9ddc10eab951a7cc6f3f192ae3eb9e322012104f521d712c48b19c40b318f42d4afb1a06ba5aaf270b5871499be3c815cc750a4555c010c2973487635b09cc8a0c8888906a11c756a4387dc7de78ed41b8e9681040b555ea250a9cb8a52bf09072344f540dc6e86737a8987b9c88552421b58590504283b48f300ad341060f49489447a7e93a42ff97546ae20768eb9ecec9c6bdb5d891914b6df854347b3d7a1ba6bd9c581ec03a7e7c9690d423104400a1bb73c0b735b894a4dc90aa1dcae71ec22411393a4b4470b6cb2fee58802f10837f3de661b1d0fa10d266797a9ec5afd4664e10f7fad172f5c29969f423bb85affc6f8c62280c9c34c8fc2c7c95f77e44e7109b92123585b06f9f59345c90ea879e47be4018a725c88204217359255b9b905997944950eae8bc7108467c63a353b7394eca8e3de6a6e994687eb71816589a216cea0979e0e7635e82d2f6a500b9aec8b4d83294a05dd5570661ddbf6357ab6225a921d438ae0f19c58d37f9e357a8022fc4813faec9c2c48d939ff9c357ff68a22e9fa67ec5a07c1440a963dca6cfe11e1666016d5401297816ea759c9d30923732764c1c8710fd02a6cc5297c88cec656e8f221d2ef3f50e45725b944ccee0274771ff86e50b4df7d8abd9b0f73d0b0a1c39a0797a2afb9415837815fde56222f6a791a8c27e787c64ca8473309a710cac6186d68970d662a2bff2681b2fef425258353b122306fae571294cd9f089cab99cab44fb1e0609fd710170fbea019f522dff9ec23d323de5ffd8bd89dceb3fb5a41dd5cb80751daea4d9b171d3251fe84902090836c96593335afb9a3786dda6d37aab2b254072368e3718d50af144de0122c1f2effe93cac289a45194aecc2733ec818007e9476c0c51b41edae4d0ce970ef1ef7128f62e38d62f958b07b08c99c9ad0ac8a8f744c97a72af91a62a899a4fdb89d134afecfe1fd60488947d5cd2450b25ad414762120059e7f2ea3921f318eed03bffe6388c969c1e4c245ec490053ac7e55da1422765c08945722be38c67724861f5c7fa4f7fa7cb1a1eeb8cce0cd8cc7488d9864eef3894c28a312a8f7b2d2fb121b27fb1cf91b1d7595afbcf6a0b2d6dbbe71f566ced1f8d602c20a8fe249b7472fd15367e339b2867da390c5294ac945ea01878028cd764ec2a2715cb619166dd993b8100404880d0544360bae934a84fe63c36a1a0dc6d4f037dee0ed421cb4140ebe1953b9739ce5206b584f718872ed65ecbf9d43ac850b86768e919ab45d94ca2dc1ee9222ff0b6a97886854c921da3eebb52f8731aa11d0edc534da44d47148a0b106de67b900b80a79471acc11b0c84174b0a933ac57c806b679cde6bef69de048f37107bbc081b46c40c44a09f29b16ac680d9a0b8f9591ebf38a5ce7fca09ac05d2a29e2535a2901dc2fc7165be31410140e1a70126ef345aeda9633b2978fb4ca3191a24094ce8d30a831357249a1274b43a1010b418c6eecfa5576ccd876c13e66b616f70f2d55f9bae00db86a2031541aa85a74da869d52599f742625d7ca804e38766a6be430564061968509dd9a0fb8a5079e36dc6336dd1c32caaa26ac265b3f56e592085087077615529962e3455538d30e5a3e300cdc75da24b37d44c1e211e20d69f080fa8173f4d255684dbae1fa45d84c6e3cc6a103c39e1bedea8508e8bb830f1c8148192e8704cf0774d789437733927a2155dc7770bba934e2bf183955fd5e17b3fceb879a85dc9aec42db445b7a1a17d38d3872e96e02a6508825684b899ba94f927bc9113797725e0397d9d18c274d7f92d2fa9d6dab5344f7114fc1d902605f27d4b16874523c824624100f3a4c1b3980251a36486aaf7275befa22201673ce5daecb7c45d92b2984247b70500cbe228fafbea2775e1f7a3551626974e109a227f5464ad590e7beadc1c1d4ecb8dbc45b8304f31d8f141817d4589a13c45c796a18ca7d38781745ed20d6983e337342dfd4b72334b1a979d03ba760323aff94dd2ffda83dbaef828e01bdc8b9fca951347b968d7a2af9c50981fd4e5628b0c96ca2a72f764c60b792929c3305521226271c5a3494048f0507fa81f9b8d1043ef43bd2c061bd2897c36ed5befb56e28a2d133de0c52d4a868b3749a6a1370507dede040809ba30ce5222cc8f50c48eced8a8e88e3243b3f13b29e2b150ab5fd706a24a7f6dcb9ac3d06c5403ad281d75981089486275476b970061cfa4ebfb8f87004af26724f8d45472e0bea73784cbab0755ab26f70282f6769b809710fdbe8431c1dd2431ada78916c7ba11599e2f64dc58140c36c3870c52780a08208306efbe6c2442dcbb9fd2a62b8ded6d55077f0fb678b2920d6310ca89fd7ff38107ddea4fec4d9ed8c19aeb11c05db57c0e749b4099ced823c3af9304ab6a7fa70b3089e58fb031f70d759ac046728a0cbd7d1c48ecdfac1b3e3528be8ba3a5bacf332d9d4d35ffa5e4a1f5cbbd03550f5d4893329308df529608c434a567672719745d5566e1dff642d87dfb4b1e81ae7db96c95d53f42be941a2ecedf977b432473e8f9ab83f8ff0377329677ba17dba7598ad10dad0b2248fb3a0a6a041f64a0776f953a5d5029b7f7708788d746d0acdd70dac39a5d65072e97e800fb5abecd01c31a3a5de29b23d6613457888aadc71eaca5222b78fb082c58ce2998c4774a9c4442340e7871c8939f2ddbc6e30b92152e39dd4d1128e9850e9fcfb8bb2044d8de8be2613dc70e932d314eeb6ca0139121cb6e6dec483112abfc16bb83c17cbbc9366a1ed687c686416bfea907ff92935939844d594088c4c80165675cd2bf586eaccf2c72c6c8855bca9a10ad30192f14451bfec7cb7d8403da2ee1da832c3663e4144ffb73038811af0b8452e331e0d4ab115f6bc79381a954a263fa7c3b4c0eb88ad07edce03c1ee02296f051377e8ed61c2491ea36138fcdb38d465fe217f9429f4fbcab323947e708b7e92f33d0af8b5319427d4021413a3ce79a5262c6667761edc37dc740cfee67d4d87d6ce6924aabacb64663fded4762eb53b66f005ca3adb5015bad2212a7ee00c4e1e49e4336c1cf407e386c10f50d596aa54b45a95e535c8e4d0fd6b4486a213cf23e1c18d7c69f77157d8affdae88c2c627789c1615abd8cbdd91018aa0a7cff97652a0d66a61ca415ff7eb0f89e1a2034ee974f313c4a3efbef45afd267474c9f144362401fbe42d713158ec3f7ca80f36298350c8793769ee435dd89229689006424984c4583c93275c7590ef3445330a62c11b72b2943e5b14e160714e58554c45ad2b010abf0e70f59775697645434afb6c8e6d9903bc704d75b7493aa79bc3ac7f6917c92102b9e144cddb7000d59c7c6b089b5905a2738a41dc6f6bc1d8aecf9fd0fe0e7809da04a372f789405a574e6bd16cdfed2e7f5c34c90a7a1e79960e2281a90263bfb1466cacf54c44123691a0eb73c44a5643383e64a0d556adaa71348fe476433fc536166b89d87471baa2a6aa7802c557c8421cb99a8dda7dc7303a0a84d4d6a29f4489cfe70f42c37112a51bdfc4f6f47844a7c0edbea8f86a5db5dda9b94ab3477e12f9b143c50daf8f2d5aa943f38dbaa251164e4ada96c25f08ec58e0f715e83a70cc84d6e398ae4b369ba30730272cac99abc530a6177f6c723b11c696810a1c426f08bf22f95908787d027c16e4db820a1a86f90d72d7ec2e0900f51fd595eb4a35621e68f2c0df87303c55bfbe8a5a6afb4774c703c1534522e12de8e14c9ea13db874bf4aeb027c4da4603e18f5d08a2615e0e7b51019650a4ce50bd38b4251642fdc1180de27409e5296ec9ede1bf2af1227902f6f0cc90a832c1a3a81d2e8bfa01c646bdd7666235f2329af4fbb815ce45f08d8ae01e92b7edc1fd8678e39a1698353b375c3b1bf16db9c9f14a1fff5c8c2dc48bbfc79589000e12cc6445aea4e8f009f2ff7a4c39a5e34c6699fc17811444432de19ee1087b92f9c6137707ff5076a3e922f2c6d8858eb27838b9e84264418670d2d908e5f7b87dc609c9c9fa84d4446a00f791168bb96ce69bdfcb8b2d5a104af57a4ba4c243de1befbb3f43e544199fd045677217201165c14dd4ea3ab942d18485c2d1633478dd4e21804f481b8585382dc034069094b2e1652d728391653f27cb244f18a639adec243b88d9f5494e36747bdd0c21982e44bb964ab1ec09f290f6e0e343328e793a3d0800e6fc91f022a31ec179a9a1f0112ff3e720815f6e9eccf815226e487454d66ee307cf49b160be0f51637c82cdf2e4410b33dfa3ced560fc97061ad0413c48e016016e98d41414e0ef5542bc89f9ad7b1b57089c9cf576fc453a0cfea21e3fadbf4e415842ecc7b378767213bd7ce20141c11c41180bdc4c82e75866b08e0dea3e52caa09faee9cbfcfbcb1ee5703521c5f77b9f354b4cd6b8214df19fb9374bb7e282c39857a8aaf24ceac15ff1f9c2db912bb1e9cbc232d68834d34c38e3f9c28e5215e75eab54dbbf7c6215a27137872cd475c140a81b26dd5f478b9d93d569b7e6c6b948668207c7f72954526899aa674ca13ce3cace8d7ee870a7f85f96d40a848cdfbc0e18d6dc9799bc6943d76eb6445a49d9ec8d8e672eb7f6baebc23e2aba1e2046eadd0d02fd84203c4e1498fe499898a8674e32d5132005882b0682f4d3c4bd8dea30882864c35916f70bea98ac3e86c7982c5fa62509ca20d7f7f26d5f881053ec6698cecf790112f1e327c74d6c784f463a444289706f115f61cb33e2ee2d3c1e4f12d8aa98f460f4a763190e6c2bae731762e27761526a6f5bfc129e1cfee7084d3319994952c54ead9c8875d985eb32f49993a8a970372aa8407db350909b05c1b1e6cc94394c1ad3769687c8c082ddd08914207829f62ecd9ffde3e36fe33b1b96b50c15b5d809c854d02f9456c390a59c4ae32ed6e0fecd252eec9e58dbbd571d213ff848ae5b7a48d97e895286018129a6e59390ba4c4fa0651e41a2b48c1698f723f61449b1fb22268bae8fec9e0dbb602d53a0b632886e262b0ae8c5e35cbed87d0e373d6bc15851498856af54f258be40844bd53809b541e7c40945300d0a6897cc916949ef4b2213c8f2a73d23a8cf48c2476867aaaa2ea60dcbf88cc52fbfeeb359c5db9b35530ed9376cdd73d1ed285cba02a4dd14ec4d356c19b8e58fa0f020e2d2a1020bacfb86b3fff36432a68efe593d34aec302aa87fcdf1752f35e6964648224eaac74d357d58d57139f80eae2c09c2c4a01d4175afb2c53c40fe08a1c23a63fb381ac0249fa202e65c3bbbe2427d002c5b5b99fae242e2570cdbe671fe3339da8a7979651ee7603a24e7a2142677c2a488d284e201a931b90cd60695e43dc5256608b071aeba6c322fb19431dba07fae4209b072963e99d29b8467a412ad52474ce2011787291086a4c055673b6639def33298070bc9e188ddbd5921194757821d37302d90554fdc371306e668cc333ea470f336e3af4d707ee8ca4751d645320df60fc812456113f6a08d6b12332bd25bb4237fcba8db4ab37dfb84b2ce670f905d4c78008a262a494eebe7c0bd8b8f5cd2c7862053c9377385295311abd639b2d74e4748ccf5bed8b0a94ba4673866e23f9835d6c2d8d6611b85382702bcbb4182da6b5fa44b5fe20cdc92d50d86e27347454732198a142f0853ce1b6c6fd659bf2597c652db8309456984987234c49114d188cddc100259f6e99e131448b1a919a64785a23e05888373cf9dbf3de62da473342ba03e38071610d4e5aa8d5e2123096eb07827e5788f5324ef327984e5f1244a0f230f8c1a5fa5568e59c1c4bd800a72e485ab3fc9b5b71c546d84e3fb7dc2392f6d33faba2836eed2f97b9797151cce1024f3486d96ace3928dbf954a59a57ed4afbafbf7dd6953a5064d8d116a4b793b08244948b92a07f6252a6f0a757309d6248b8c50a72a956dd0383463b61d0ee89b80afc11cb336a3d2a8b58189e9eddaeb759cded0c6aa6d84f23e26691ab344a4597699a5380ae4cac33532267117dfad12799e2fe9b3cbeeeec3f3f4386b1164d9f8c14eebfabd77b28d254c7c63eb6f29518620aa6df2022b40a302bfe003da23175430b6645d135195a1f302430bf900695e0ee83781c991268a4ac9b0cbc05075c74288234d9e4d835c467c52335adbf1d9c26172e50d7b2e17f33f4b2bac14e9c062ba27432644d4c62a4a1a2ba2ce1489f0b8de8f4476a8d2c57eb0028bd90b7b1212b0d19625fb7a56616c3bfc8a9e090a15d0a9bf14cce5c1d12b3065f4580e67b997f76110e6a46e3f8b305b4d3a185a2249175a160dbed76e7de7ba98ecb7c187fcb1c4b8a8b55bb47c97cfd69e42473d820d37b6a1ae4c52c42b71251afe9e981f8f6f8c6e5b7e0f7a4b60e6bcd0c2bc09f55686e66d05d0ad3a240613e2e817c866bc214e998b2b361cf4c23a2acd92f44883cf1ff6a2b4472c4b0e71a0e2fe552a860962b6fca9d9e5316d416f6e487b2d6001570129a7ebd7e71c154c7fc4ea8978d50fe1afb60e9ffee25170f37f3e77d831e7e288bfe88e144cb9621e52eb28a80e5d5584e2e11b771a5ef841f2253f867625f2407237ba939be39874b1647d97aef74e1a7befd5a6cb82521a0f0cd00d11d12a2ede1e7096ebb10d1fb20fe6812e98bed3283de911c83da4f139d79fa54019848edbf78390dfa4c541ba5f36233fb7aad2e24ca3a6447c3d8f7f84fe85c0e39463b38fc96f016fdafe6c2bacd01c92c06084511e96904990dab092e66841a4baabbea453000f2a9da98b35d370278eec9ab1eace640f40c68b7b5a9efd46912409b01f55273c52ba46c0a2be24b45264b3ec54dd5193f87eca2146a2ee5431297f61661726db16262f99db89028716ea642bb9521ebee086cd2c9ab47328fbf8aa3a85ddc8a74322295fd8db81d8b5ed9c4e0b2291206b804e90e1466e9c107f109db91658d9e5e1a9f5a82ceb563e5936a52127167df98b2722cf9194e05ae9be3ce6601026a4367c4dea1cc6ec8938200cf4e8eaaff65e44149d5356866b72c93a4a3f4b203bd2695ab2c12c103a791a773b54ab3ed52f27af5c7abae03396369c6ac517353c9bca94bded091d3a37cd3688ed4e01c0650d382efc74f8297db6a2e897d43b909c8f22133b954daf036cedc2d03a0bf9d69d5258756792035dc7cba2bbf0e861f9758980c9e7d8ed829a55d52c0cef59b907de99b869f56c190e772f90ad7f40793c9a321a6fb59fc9fc1cf3eadef7f56eb53d874c6715a74b8b13c1be333cf810699570f8a9d7faf735dc4ab80d06850b6706d4fe25aae6fecd45426b1848df7ffdf311e380a846dcb701caeba460f43afeb7104b1e2473043ecf4d4a7623785256ebd4ab2a11ecae93bb507b566ad9a7c865988df3a2711b8ea68e51fd9c6c4ed298a89994d814bbf02f4d30a523b99bfe44080188a0d98354197394e563458aadba190e1fecf46f649e564d8bb0e4dafcca059e8a93fa61a6775337624dc17d4bef79ddf1f5b6cceac4c48e4946f00afba88dc2e959cecf3a5d01a0d31894a2c8ddbc3bf80992d7ade9a7369cfbbf1074197e4cb83d41b435f3d628d1c543d1b115828365922b141b89a401d8e46936ce0cb4d81108fc2c32803134324afdf59cb9073d4a5a0d179180c95e0ae563c2570717aafad3b0d60b763fc614258c60dfdcb195f171e0e8abfc8d71af0e26952c92abc6fb8327aa75a506ab3e3a93f285a51bf817a0a3dee951a389a0268510e8d0df7662571d6aa5d5bc905485fda337f25c151c5ba3953517d9093d6682f981eb3e9fd096bff4378af9492a6ee29c8fced3484979d769bbb9e9370ce897519efe9e8c54f0a7b4077b80ee2bf349b7edee1cb51d97bc3d4282349348c847c1f805c6dea15c94254ec8cb2ed695244235e94dff13d71bfea1a6bfe5559d7b5d44f494a9dc83eb73d757a264a6aaa9c4602e275c11396ffa16500f88ba3ccd93bd50e3d59e10c72ed320720c6d878b37165bb6aabed37b69caeefc2ed34beceaeaff276365e6e972ae86a61e3c876cd16db6d744ed75ebbbdc6e8d99595dbb7f16c757d6ba072acb52a65b6d5d563ea1787d9c9d7904770a887d835edad4f910611656009b411d85333da4ca802356d19672c0299c42c5555f28d259753a573d53470aa0728ceab04c74a9b713711c74c32b3d681ca71627a5ecddaa59a8718d8e176757b8da8aeab546d3b8dea9741abbebd8d24dfae2928039dc4ec555bf21a253b2b2fa5b5b655f24b09889158a372a619087cf886659e12e428573ae1a4a4ce66204cf62bf7876751d1e419b356dae72edc9cae8649e1d60fc69c1409893aea9b48ec5745623018acb629520eae8aacbc0b4712623bb34041d76ff34383333e60828ff9b3e6b97baa672274133fcd44e4f706156c6711282d22b88236c2aa27b9d78848e2897e996fc94f4714d212414d7c98b4e4867925fac6271f5ad98f96237a7d24b2c912e13cb5b88e385ad18a5eb35b27ca43789592c2996934ee72c414f53a175ca161c4a24f0ac650d9b376c757fa43ebda69b6a914104169f2ee561c8c10a40c559fa6e1a18963d6e64be0990a3f154180a699d26d0701830841419042f1e02736c1e9ef11e5af3fe08b0e2008f99c8a37ba38daeae56297ba21a58f85c485fe927bb8407651f156e27e871350ecdd1111f7b8c15a53622a96b80de613ca81fc395d5c0947b708d913ca6251e8dba14b3815e8df03d754bd690b108c88da7c438e863a297b94f8bc99339c70c520169980b3f159004d6d01da0db06f0750d035cca29d1a06487fccb634a51a5aa22ff2013ff3f962fbc5c332ed27da6f16b16f33df37dc0b9be566796d81d0569c3670bc6e880255959cc62325c8d9f7dd6ef64fa277cb9c8161c053c4ce3d149ecefb2418fe1406e7d4de1c96bffe50b31b6ba36e1a71eacc33d5e10795c4fe21c2a2c2b52a7ce05bea615ee69c125be3544d94ffd7235a6a7c8ea3cce5d5caa93f97be5f8b812a5f2cd28729383158d266248624c24108167fb60b5a2410936b25842031fa6224fc8f5eed1e936bf25dce59bd984b3490c9706d6236620d2f2d65e8737b8867d9c45c5ba5a614afd61105db8164d06e35d26a3c6d09edc12fc59b36d57b4f93b6e91e1cfa85fd8ee9a38fd3ecdcd0ebfff1c78033e250212ece2cc8860c3888be1e8e272ebaa6fa5e6096f390627eef8e06cb0b3829cf6df4ce4b7a7e4492735a0e7ff87d13a40757ed645aba85d3b107bf2294fb7d7a2d67fd35cfffd566f5238447f4e9c695563829003e103cd57f2586e34b3101850b70ded20f34be3cd0a7d3f2e9abcfd544a526ab0d6ba008a01626985742d524202c9456701329ce72f8c1d5a1805ea9168ea6ae28eb428c3ac85200590ca3c8eaefd0e7099bf312f2980ddca67f9a3ecf492bf2c79c22631e111341370bf085f7159a38587a3df88c3b53d20283bafcdbfcf45b1cc9117b815383af7c95582c5b0ad9cbf69b424e6993d139f865afa2feb52a212a4242074fdd6de66d1199d00d7faf587cb04d8f47df1884332684e772313a8d66ee95b07923868f2286ab6ec29d9e7cc7961e436c442a78613c70012d71f97e1e571dce880b052ac58f9a3411f1ddc98eba2c15b1d6c9614d117e764c12c15a1d43600960c0126e497e3f50bcf857d859e2f4ef384f10488b3ea920df2fbd76be4daa255faf1f0b794e505f1017b049ec81869d1c1cb0aac2610729abc9b568bb9b9473059143c9e6bbd6801e0277c0b89b0dc3a0064b816c64a0ed73fd8a44a66c065baf1e976524f8b2751fc15d287ac3dc79bcec9bb01f6f234aebd52b91a6c7bd63082e79c9e2ba6b7afea38dcc5203da405f916fc0495e526b7a81c8e2fe50b504db50113701bac2023716e76f3c79dcc24933b7702e6aa9286b67ac2c678da19a8aa680befa57cce26d406fd6cea6bde77bafcd6528ae000c3f26f8116c23ad2995e6505bd601683317e13720c14be989bcd03e101ccf0e843909f500bf5b8ea6db5adef0f1e8c1093c056b6898c470d00d056fe794a5b95beaa4f3fdd8ee3a50d0e046bd00c286099b41680185364e014f0ae15ca7e2f55633e1821ed88c5a182d3b57298568b847da56fed2ba2a0e71f21a5782d6d80d5b8807c2a2713249002df5164c378c6f5680f8a7bda68c5ac3ff80483eb3a89cc046abee251d4a6db545816d50ac4b72dbf6fd3e2e3a89d198d1ee3fadddb979503b40b714407034fcd88a9092b1197946d05723fc74f8699dcb17f9b1a9f09f3c129bf7e254dd7aede69a2360e724cc39001236ff16de998c8ce19b63945123dee68a12bef84a660eb773de60ef1383eb3f471ec4b3ff68998523fc67dff8a639a63a7ddc4b011bf3c090f86c580e4ecce1c8dbd6822434c41741b0405f8b661d40448a4b3b795742883b157e4ea1b2af3a5ef851d9d707d6b025748fe3231ae75c2252410e2bcc320f4ea40e8e9e8844e02ee3492e9645fb4804379722905b341241c8b4854f571c8d8543c9cd90bcd3d0024fd8c512dd055d6288ba0b3c594c2b9bfb09951d296f31e8a9fce2057605920d4416291b6bafa0b5aee30393420e2055eaa44caeef58abad66b296fcb538c09e48e415b5a7d3640e4a3e968fba7ab9b5bfce72234c2668b656e6d222a6ef823b513a9a512c387b3ad4a9060e03c2d87e44da682682a2186934dd4c081cdf12ab7a4653e120915108790028046482a93adb3478eefda81c33087cd159346c22bc3d262dce8b8564c0a3a02742153f062dc247dfcfa0227a51b8faa5283479d677015a52b0e7d37b46c83ee5c64e303dd291a9b0bc1d2f7a1ae4f4526853a43e9dde7ca443725b0e39ea21f28c3a2ef682c2f7945334afdc7c3407d95a9c6210fc8a1b4cdb7ed7668804cee4abd2cf799aced619581b653cb2fe80c735ce6cb784410513a04788d65e26f035f737661025d470395d3a7053dba87591984cbcf78317401776291d994968e5073ff6c89515e9d0df6985336c5d8d04f4c82e3c8c3bf9cf1f12b3d54f0c0c89f8ebd9e71ea2a1c9cd93440efcace76e6613a5af2c244fa9b21dcec55c3a9f9514d74f80238429d9728772e2eecb856b4403371b2645dfd6de9004fd17cba724484738bb3f8aa9ff2f8d9b34fe134942f9439903254090fb8d15b0aa7e094cbb5a6b89e0324e52321f28ef079e20cd2a91519ff0171b3da36cddc642db4d51de3cc45e811d4183372847209ea30f666f9cc263c446357252fd99838585cd3f12f1edff94e83f3f3b00c90adf7d9338c60911db51d142c5d3441c1b739e3a5005ca612a973d90727a35cc657f08068868a046511b224f281f73296a2529452fd34172bc90abe620f50d0b74c4a60cc691841227b6ed2e9167a8bf9d72675f938da5a9739be8349a927441f9f7e2eea2c53ac635129a0fbf071e08ee0e413dd4221efbbcbd0554b7ce17c74d08dac4291dc791617ad77fe267ede3788e6459eabafc2baec024cf78c1b8cec0e41762a5951695ae9e77c69ebc595e1b60e461644c6a6259e188a9b7911277982c018b7168d0a765a8df5cb6fc814d3d45755cfd540c41d6e60f180358e41288f6c0decff364b977c5990f7fbc2540a87fd35a718df8b868492c2fd55dd329017f998e044e27f4edb41cbb47e4f2f2f7551324bffd7c28db57a7f6cd7bfab190556e20bf21b078643d1c44aa661f372e8024b21732ceba24d273819017730e68fee3b4c2249d0003be46803b6b264275b32dbc0e6431452d0ce374e398f1ce7370c5da080411d69dbcdbe45476573612884698bbb27db7998fc55a26aaabb715b3972a518aeb75e484f0d90319442788e73295aa44fcf2f954b4800bb9c6058eb8000f1fd7c2ec03ef1430d81927655d80d16d8b3e7474d7b11e4438c78cc16a68ec708afc1f219d412ab154afead89312b7debe9ad50c8515cb67673eb30613edd3951a83a3c28ec50226ea7941059e0f1280e70e45451360628b08da608075020b24b0d791bd388c6bfdfe19796a2c887302ff9ad3b68e03112cd790b5aca750ae5b24e8f85abf546ca3f8064490a05dc49c78f74686b6975d0199c25c1f0c6cc1289bebb851fde86775e64c2e45a4cc60617097990e7680672ea4dd5ec92ba05f9f62a33a8068ac3903f642fd400f5966f9a27924fd5954facaeddc379789096aee86f44eaa54df11f28a4ac4188f90691497d02a89f6331d340d57dc3a32120124cb4275e3c0d1bbacc7e3cf30cb714e81a4e7b2cf9844a5a01195e6cb6ab35057f5cb6409fd7b0c1608e805080740bfd6ebd3dca712a1403e1873c53a2aac885b198daddec1646453839de784bbadda79b25b75205490697bb64e61c7b12173d6512013c2da100813da32a676dfa881cbef46bff749644d0109768a47f43cf5b6c684d71195326eeeedc35b92c8dcc22498c2442061e745d9ae071eb1f1846892260846689d94459f1136f2a37c09363d933e679a9c3332fe2ba51d704c3d55e2ed7d5e4a590ffc929e9357e3a3fd28dbde855009d06637f0d0cc81bbd4bc80da9d7c026c5862874a815e1c5c3394bce12331d72574c103dabaf28e5a2050c29a0eb79634e1cd25cd1d1d75869fa9f0e31a646f5c1e2f67e1472af8653274276a9b2fe5d669f553b91342db870e4c197103a1ab23988644ed4c9f539eac7a6ad2e9179c996776ed97125fc61074dbddb6dc5bca94640a5a080a091309b51a90c1620b59738b7489d2152fdb96d4ae6dc9d365db12a68b73d94604c6edafe1d86b0ad1105c7230e28933b2ae25b7c63a16b9b2eb6c445b5ccefdbb16d0952d227eb9505a2175f0ed7a5dbb0e9f03cc587eee28a5ddc42399d0888866702227cac99139dddd9d73fbb8c6073b0ae92937c78ee368f106563e57e629b536ab5135aa3fd426b5567fa846d56868682889509221da91378da35118281d1282a16947fdd44f59b453377516fdd44f3657ec085ea091487b8df31a15e12582d7bc96e4c5a44da2a964d22651d2249a4a29ae4eda54d27534688d59336dcc690347bfa72a0850dab481f274ac558b7ef3dc2208daa85113ca075bf62b1a27d1fd5293d6b04ff2a0117ddf54ba3362b0aa49346df8beef390f0499c1702442a70d92c7283be0a0fbc26983d4c19c628fd54ddd346d98b469438dae387c8ca3862668ccdcd7e52532562e9927f72f2f3d0d5daeb6cb67841cf7f629f5bebd07e79c5f555e7d4e75c2776728ad504160fef7df6cb15af4a3956ddd3caf68f45c2a5f25cd8cf2e9569857c9836f7fad2f9f1ad64f74bf5685c1a6c21148ac20ecced1deeab19aaff5b99ad6776b283bf91cb542ea90bfd354c543fb3fcacbdddd1b87c9ab8b8f7f36f8f5ed988853be7475694bce861869b1c86a06cbbfd312caa17c3c018be3ce1708b6bc1c823835cb8fe3b5c5a1bebf4a99945077ec994c16c6f257c6f14cc074f287d3a19ef48c867cd54a062b9f65cf644ba09645fa76e8413b2d5b02c99bbff4bfc12f6ff206847b77bf0c01eba6d0402ee510c7fdeb72af162573e2831cb53f1887fb9f16b9afb1821dc1cbbd0c7a192485e45007180c0a1c601e3ea40eeeb907c23bbae7deb274749c7b1f2f1b525c4e4aaecf4ddcd4d5aea3a0a45131aa3b4174eb77de3bd495fda4c1b428bf9b5cd75bd73db87edd9f466b464bd5aa21c3caaf59692224d6131bfeb0584ef3c2760a5b4c8b7e5d806ad77521aac5ea5c34ad4ca20664b1e3744ac17b22f2d61f27981953bdecbaa72be54f26300d4bbdfc2966368de11d1ff8dff7a9d60886a39c4af5bdbeb352f5e66d2e39949f994a5097c8cf744c35896651bb46a74da5a586d5f0d6308f772ca90fc2b33c70ef5df58ea40a53786ab1c605d69fef389dae748a5577b9922257e2440df3dead20d9fa75a095165598b2a8adb4282711e3c814ba2722a1640af5251ade315fbedfe053ad11d0f8da1ab930154ea71667f8d7d37f3ab528bdfb9d7e0aa79916e5d78861c7553f719a60aefce9d4301bffd1953c35ccc69d689ab132932691c77a0b76c907a33619d691b0fc852b2791f4deadb83711d3b026958ac753bf74a554ea5a528b4c7a92efd51aeb1e8c20dcb19faefc06f3c9288f39ad5df26bb5362aca6914a0599b12ccdbfd0868dc2efc13ea776109a48d04ae17a6e0dffd6cd97c3f1291b7d6f7f7291d6359ab6b799f924cba5236acbee51d7c6badb53ee7546eb102e1187375e71daa13dcbf56fed473785326f8c836c8b9ce65d4164cc02ef95db8a24e534f553c435a5cb528532dff799d0b2511e348cffd9ddf0bddfbeebdef9edf632fecbc6519078586d908e96e09fc0209429b670d8e16c1ff6c522f898e1ac6452d1ac13be49646025b3e5a3e2d8ecd4346491d4432f5b55acb62492fa479adac2ba3240f492475c8976038b6f466bce785468064aad4efb4aa8544f54680642a22f672bd974e5cef3f222f1c818eee28846f1705aae7eb3eaa50f55eab0bc77abd14cc3a557f6d8d7f9100cd926a34a1a0158ecc642c009231d71ae5962b570d633a5b3f1ac660bc30fd68912714d804a049f9d2fff3969cfd3746406259f498c76a2883befad59ab2d663fdf360c1d2e7bcd6c9bab325e3f47f13e81e7541e37327727777777777777777f7affa684ff540a1639266a6fb1b9b1b1e3c0b001d70b07af9391a66a346cd5b1ab0192fe5f798e0d330faf27dfc742c7cf9401aa692ae3a41f604e03ff80084247c60428b2a7cf0de479226699dea5df55e5f82f0aa96f7b31580fab5b89fd1fa9e466bc6db168daf69d9afd1aa791bad1abf6ad9e8a0c5c103a0d5c1b35a00780f5aac0ffa76df8efce87e14bc6981f036ad9bbfd1b2790f5a371e6cc91bb682a004e0597859f837464062e54ba48ef5cd5d1d6bc96ab1f23f4a34ad1fe50d6e67a65ddd5bcb62990147f182e1286fa0783f68f15585fffd08865cf0a9ea04950454efaa577df00108ad3e138526002dd7a28402bbfabbcacd686effd84fb753415ef083d6072dbe0dd5ea3336adbed1bd072d9fb53ca8e5422d76df41cb873868f9aae54a5a4ed4f2a2f65a93168dfc09929516935aec3e6cb996762d41a0cdbc1c5292800aa4c50e6bf5bc5a3dabc5caeef6267882d79d7aef531e4fd39aa8bbd66d74bb36c33ba0cc48242e988724827574c13b64bd35943567ec98f372af9db35edfa75e1e49a486253578d4b79a283be65c33b7fb6fd680f2481ef10e300d238263d6d952b99dbc72bb974cdcae7ed7effaccb16ee4983d73678b5c2cdb6870ba1d4ba4ae55f2d5a13c6ab15bb5e8d3217335ac167b488b92a9d6d05527d4efbeb1046acb3aebdda63ff0e1631c23a7d33196bbbaefba8be924ed28815dcdeaa5240fd5f3f38cffbeef5373721c5d6a912752c3fabd9f53eef7b504f3a67e04346eeafbab3adff77dfd9a6aadb5956aef507b87da3bd4dea13ee558ef50555feba73a61c6f77d217f9faa9bf4526b69a47e72bb57a96c4a15b6924f9e901abdefefbd0eecf11857fb812d7941d0f3ccd4be75dec48bda95dcce876ef7dc37ffeec5ffdad5ae7677777777777787aaf00bbdf0f354ada4c5efbdef542534e8551b4ef5b2e5627c8a2375f7add430ae25e07d09e4147a626b6d80365425b8ae8b69b19bfd33be3f355f82dc83f5bda61efcbe7e5fbfaf9f7ff5be52917474bdef2eb5eb7dbff7607d3ac1ff522a1b0d60ae012edb6830bab70b7eb5d13e11c0d99af189014288708071a28a18291255242a49cb8b7734d78044f9f981c28b73401c5c57ac1773bc7426cf3af9e8090d07efe81eafea1499edc4a0d38304560ee358cbd74602dd7bef858c434509a7c9f61869d8687d08e9f1f90124c810227665428bd6041f137a5889e66571934256a25a885654333a424aaa9d74a28811190445012a13dd25853a176ad89014ba75e9b2a86a502e20e2e602a52c5d0d27275eaa8c112a820190942a3e0c41c60e33b881c999da65db191a1863eeea0cd3b5676eb77f7543c36606ddcd4dc8d02ab0863084fddbdddd05104f2edb8028ba205cb619a1b99377f0fbfd6804b9fd0af8c24a9ee9139c393558762d2cff278425bdf85420526f37ab977a4c6dac9607b7e6d2ef386c00949d4fbf65cf70529fb38094d5d0881199cfa4985a592c8f51197fd7b043fb35c82c4a1e2c75703f1ae0321677b471b91f0f70f9bbc6953cacd4a1a2c0947d616d000d6c118fd5ca7dcaf3c2dab5660bacff0c721bd0a0d58a90006b454e1cf1c2af70504d5024e54006cb0c860e0b77f9ca0d70e06076cb218923221a0e5c09cede0ae8266657fe09d0d0e0ca1658be88a106202857e010c50b45849184c80ad26c48be7c16ba9236934666ee5885eaac616c3372baf26b50c3e4ad4357feac95b50001050a94175e5ac0042f0d91040e5e384dd18599e9e32b30805a14a5998c6ba5790c004f33ecb004083337fc20935f893cb633831452d06c4103961864f2ebcc63ec4506a831c4e8d043145864f2ab90c758cb1526c2a09141922c4932f9dfe735a8ebbad9e55a755613d064fdc73abb33c480155b6757b66a6dc2bde438aed6d9ecf2f4094e06996b679d12df02becfa9f472546d3c59c4d41109d231f9026d881129d43009eb806d4128b9fdb2e6d50e36ca283f50904134b9f5592dca14baaf3f76abcffdc7daf193af72b850b3372f6f07976d403cc5a4ac9feb60f32715eeade2dc5f3a49812df60f45a9f7f6d404dd2d38ab124eac5c69738274e5ad91c5d6c08234724540170bde8862fbf9fa0861f6315bbc6247bedd1863f98e7c8322e263a62bbf0b0e485786440cf0752fc17bd3b0ceb2beef9f6123d09d2a9e0f9cb75ba9ffbcd84c9acd664d64dd3fc352ef799ee77938c012bed0c6fbca3c2aa4fe7b56791d27c6a7ba8bc341b242c6da3fb2134371f954904fa45eee19c7276d24c0df7d5fbf175664479d225c67413a1eabb55acb6231d4a5ddefb40aa9f77ea7a5246ab16bd1f72848bf5a96d5d1b9b47a409529a53aee62190e929545a154d222fd9c212b6b330bc6b20217aa26db0f487dd4448a66c3618c0d87295856e0624a27dbbff364fb39b60228f2fbfd2b92d1651b12d11d75dc7ed672d9560498fbb98a222189b9fd13bccd585c29bebbf8c7ff2944747797eff2a54afc166d3fab9ffb6bdff0f1046ccd95d787a2fbc1655b1334f7a3c138b8e6c51a552cab457e2ea30a21a8208992e596854c364143c54603165f60a84126dfb25e4c7c5cebb2e4e9ca908833026a65210c8b65ad3be7eece85328cdba7493ed6930f2bf6621c2febae2e42a405f699b7d7ebf5a23ce79c73be4f1da4980da062fb29df6657dbebb819be08633e567dee3f9e5f188ef6ba873cfef35fc8ead210e8e69097b3813fd789a916cb5dee77bae6f7e8d12e7fb107f7634e8fe98029d6aec497ce8ed5e1cabc9bc13b52adeaa776328cc2e67b0f328c7bef99bda72a1ecf725c68c33d5f1bee5b365ce823842110e0821668501446922298c85c8c2827324bcc6e1043ca05a4088164091256868450e2c50644c8e08b175aa290f94bd51215608e8e8c31f385cc5ff4d8075e70c31393a32b62a09139192d9ecc9e98bcd0840ca866c41751d2b0200ca73264feacb2b1859d21b784c4a3725fd949c77ffce020ede387939daf9f1f2d3aeb3a808a1df9cc13ccbf48c3e6d73355c8bdcb92a1eb2b90f9ef780cc8c77f1c08ef78ae355bc9afce2b8aa53f4a04b0cb7f017cc5fd47f1ba02a4b0f4abd3a5a18fc9cd2ebf380259c67c08509f16fb81ee6bc7bfc7ffe5afe3356e069f0afcb5b66a8b48bdcc7272f3bdfa717d8e992bf71ef3b35a5c7d8b528ae5e7a7c18ac1025cb63d51e5825fb2b4015eb833b22475dddfe00acc71d9068511d716e159c858a20ec0869b02a24baa7af5bf384162431945b8808c1819194d780c404324714a33c41047d2605985a91c9d1eb727d275d9f6841577c6655b0f39dc257fe24fb6b87214affc2ba7cc4af9553e4bd6cb5c52b582d1810a22ce7891060a9313515018ac70c117525e904203941ab25abc49a2e141a43ccff362c08de1eaefc85a81d0e2030269da9aeaa469eb214d93a0db36976d3d5c71b9cbb61e64907af2d5305a35f19367c6891421fc2499e4952f59af0ba4c763d667fde6d24f82155f5dd8f1e6ca9bf95376d131ab1dba6ee3610a32d71b26bb092e5c664c907e0dc11cd791b85e1d8083bdf91d9cdcfed99cc4297d9277dc02304e4bb9d3e3038890179f496262277e6228396163016eff28e6bc0a208ee05052f097ef21092dee304ecb6c6692cfcf4ecfbc69b17dfa7ffa77fa7ba6181fe3f851c1cebb5f4184743702f903640140d831870a52509f0529ab5f432352062585f9401a96e3c53bfae72380613a2df26071fedc218171e6f380f1b03865879209e350617f7c7c348c09ef485dc98471267d9f8e25e0f683c21023d3e92899f4346cd4216132993a0de3a5a62fee08a18f16270518c787713e40b2364b4082f8fcd016eb86750312c4e78755354fe9f3ff58f670ce7153879bfe4ae20dc79c73f6f87471756e0eeea594524a66f1d562e3f403e958026e434ab79be6a4a1ba0439750962ba5248d29ca54fc346e6f2435b0001de41e9ed6918db6a4cb7df8486012075656b042390b7b63cc6e95f800f76e42620b27d580529e89e052993f5bf7c4001fa310224eb9ee5aec6591ad25fa41f487f90feae258f68834942d6acd1c00f4d6c4cccdcee47d67c1338aea7617dfb71f4889235e478d998c070fb75761ad6c16d9b0e4fb7dfa7b9d9d9868d5cc5ed0ed37514f496bc3285f9608b25ccb0ae5a948c5363f5e5dbee3efc16fb06e47ad2800b5740c3aef92c63c73a5b0172b2ac65938d05c2d4b38ca37010aad5abd571f86c2c6044963992a53e0336f23f3132239f18d9f7decbfbe12cd93f210ba6195c3152a20413a02a696ea8797901972b41b2f6620b1ba8a0c9e18616a06424b8708b12362a9eb64a65ea8dc95bb4e48069b9b285852d362d2f5cfa1e2cb174c6a550374bc5e395aea498028b10961660a9228b115788e0a1e264a14b171bb203158f8fe0ea893bdedceea425b73ba98adb4a80b9fd1ca878faa948d9c18559134f432c88401193344fcca0850a20280d4a367c2b255a908497db6fc3eaac60c79a84d0a55bb6d440a7f59c73d6a8787c8e9074c79b01dc11470e1e77ccb9b4c7a5205419638589952a9008424289248e5cfa5c05cba56f95be38d1a0512588db3328a5947629fd1efa3e7ea8572beb57a978fa015085069e398f6c2cb0e89c73ba4b261854b9fda97e562b0dddfeda6c364be2eeeea978e6df717533c21d73e4dcb187165e3a220c5808977eb53d5cfa2cfa3fc4a52fbea08b4bff05e5d2d799f2c5a5bff3824b9f4ad4a5372896d8f275475828be54f92a38c21156d2dcfe69794823268d0b3b7c510609a0222aba101384d0932534d019b63cb9f449e8f1584e8e0863ec989323a3f78adbd54efa2c1ac51458ead2ef7913e8fba054ce1f2b3843eb1c18d144b506c8f24916d8bedc458619344820aface59801e9768ef432fa4cc3a80c52dacc59435b39779921e836785bbc9d33dd2f3f04fc35e0048499edffc0b4d84c2df68d71baa7b8ab658d067c706a916f00cab0536c05d95bbed33edbc28a8d13ee59567b64111f9d13d6bbcb5ddd8ff5b2bad6cb5df2458eb674c448797259e9b28d08a74b0498cb5d5cb61d61713f1a1ca564a54fbdfd362c81742f9564fcdfabce3cd6e3f78771e4e34429ed44bd8030d4134371d410f94580040982420b088fc1450b35e8a2848449104c9260b183930b5f66902a1fdc771c7d191a913229e551cd42f27f3625cca75146196594219ba10a3240431bae524936bbff87fe0c8dd8387999185a7735cb9f65338432fd3fde7ae9b8abbb7fa7a7c9c57c8ce3bb47c097dfa75efe377b041beea5cc8894cd78d5b38c8696a8246148295a0209900e52a0043911031cca406246abbaabcc8c7b96947668e6317944befc2533279a318eac36dc73f7f29ba85ba8672d06b5283f0419f4ac67aaf761b94bda3c405e275e0865ecefb4735cf7755dd7751cd735d7eaff40f95f4b42b94b3e4d0ab94b7eaca2e128645ca92ae0322fd441831d7bd6d58ee35677ce50c4d1a2cb4248b2954b99295794a185134b6412e7072e2bdc1075c3186764f2e54c0ab1aa0253b6d33afee5312024bc6072040818c6f0610cd9a5018b282b96aa78824926ffc55a6d908b29be3873798ccb5378116501c945666381f9fe1eaa80fe0c6df859e6cf32a9f2319d5877c95749a92463d97c1ff93f2de22cf9e8b84b7e08657ce4ffc8dfe9a9f164d975f8faa8a774ad8d664d06098b4d048b4818490711d013a8a3a72496ecd0c20bb02a90d0caec60032f6835df3d9b6af4b98f1887fe4ee34459fef2c48c192398829802872bb4b8c1921a94b8410c941b530d2cec286f37301d4b49314753cc5caa84260cf254ef936e89d4d24acb27dd12a9a595965aa6d48cee90dd71b2233fb9ec9abbdada6e2a6b52363ddd78c112a9d7a61fe8766823a518bef3c654bbe631f9855df4c3188db9f4c9d43cc632237a631c5a8613504cd1e58a2534533cf680249adc92c2c0e2072c35a322b45c66e2b24d0a1997553c3ea9d088941571571a8e7eeaa5488bb88bfe7d626d3a2aa4453ad9966493f2248f6c52a082d86773775720f5365266e3f3fd171a913296bbe803c97096ec0a5c18c940061947564ce9400bba28f3058ba3a4208a782c15cea492ccc602291b9689eea29f0a6d26cb8060a0c5105b7021b4040c5ac828535184185d92c050a52666b65ea9968ebbe88750e6e501a73239d0608599205800c1135ac8f002449a2d6482782cf5f487346ceeb448e9e350b9c926faf289bebc55afb5ab9d8701e5ee3e43202dd21f774d1b2f7c40df5bc73aa02f99a0241a2d97762d68de58c882ce386a2106b40530940a5d5a8b3274e9cb26344cd7750f81be5d873e2dd29e1629fd072061fb3be9868b97f20ad919581074e4cab9fa5e57ecb8ba370de35fb528c7d5654d795f49765cdd8c372bbee32a2665f23f9ece3ec3e7cffe968dfbf109b671dc0e8588eca10de42882884208708a07c75abbae763785f99ce82ef9abf6efacb787ed4f69385b6449e5631c1fb74d772735acafdf38725fd2e2b4305eb341f9c26d50965ce553ca87405f3941c93c4a506f530414cdb88ddc35bb9fb997966aed9a4f5b4b8b73c9c9d20f7b6964f5973bbfc615763ea5358c12cde8946a59e1289b7a4a27792bd99e5431bb66efecb0c6183b7fa769d3b8e9ddd3e96e854a77e9d2a54b972e5dbaf4b9c40386954fa5fca7a7a626262666d7d159ad6e1a47275dba74e92db0e953817b7e6ed6755c8beb6c0e69513e7fddddcddcfe514abf69d34e6a919fb65ccbcb8a1d7b2679d097ef49aea5637da69778c95790b196225df253a91a356edc08430318400411ae8ecf8ea06c5cb1a3cf867c68f4590b29e16ffea6754c36f550c338215cc062459411949421bf7cbf815a846ee566b7c618db2fe4b1ae75cf7ab915521ab53232148d362525d56851c79825d34d2a4da13479e4463a41ab214a7bda953f9778c0b039a03ce673f3d86b3ee918c8aefea7a7a626262625a524d7d159ad6ec659eb59ebd9cc63f2e9090a2aeab60b5d8e23f35140caea33d45551c06535d441839d41b8b00296cbb9bd92ef4c36e139d598e96044d30d30f0a240a82dcd5c906ab2d9e014556d42882161a7470f272cded1cf38f50af39cadc93873ce3ae79cb39d5b4f8f558e6a6f5e7ce5e8ec80f548899a4ec3f832fdfcf861fa61aa3949e25a93a3214a04114284dd1555c44891a822519c54a5a925d19252132b44b527475392b4dc6a57851222a22222222249045ab0562fa2e8d51f205db06e7054c6a9a2c8ca31417cf5d8e9f1f1c1bac9d1228b25b258395e394451ac591aaa36acafb52da6616313355323f5521fb5954e6aa5be3598b1bb68a2a26ed24277b42ca30120b1d6b6d14d8e65e1105f3a3d767a3a37ea27d6636d64d4462bd6ca5a280fca4acc91e33715ac5567a645ed87694849a8c82c88e6d363820f6b59ac7ff17559cee363ddc5c464697664a61f2639d4b0d1a260e4078890211dd07efc30fd00f283e9a72634d3d1d111830ce132c41c39e0ea865bd4d121e187ce8e093e3f405008328427f7d8e9a1a3a3337b4ac200efe8a8274f464145456844b52647439408125c1027c4cdb827e724eec963cd3bf84a0ef368741a62726ca67e6a28b067ae648ac72611eceaa79274e5b61213f2f6e5f677e12899c2c8a631b7ff0b2799db50d3491051387293448ae56897ecd1232707078e6e2035f753727ba71f00c68ef3480878bff7243093693635ccf2fc7c22f977238a9d3fce23212d7ecd3965c05198a1db4e733a9a4d3d9de644fdcda3ef9b471d1b41cbbc4d31f2260514772a49a1e58e13cc649a4dd3693af771a04fa4da3716cb7e29f8f707fef785a37ff740d7dfeb3b2df5b5a6523ffe8ea75ae3eca9e2a9efad795404080a468434ccdd093b76516e7f0de7942e9c4713a946033fa00163cc135cdc71ae006554c1f5779abbfac9388fe6142874de6e770af43d9c4847642cb591004dc186abca431bbb7a1c2af36826f54fa5fe79e4fd738af7b3ba2310b2a05d95b2d509e1a54b7f82ec21f8002f76b463d04461260aa71a59b86b282c899defe3b5b68334ec9deefa045d72fb5f3926f0f7b01498420ba6228c6061852764fe2c8e81800b1d8cc21c198389309567172a7ba74559d3c192d8f12fe5388ed6742158eb1077511eaed668e087a016e51de2b11d76d1af955a960f450cc511312e17de5862a73baee072efe395524ae9f7d0ee592d521ffa3ff477e8f7d0b4f8665ce6d8c5dc7f73ce771e5cbbd43127996fba08362b9f5716f42f9345f0a5979aaa905904c12f1c8d5cefe5a7bc701661595cd921d79f4590c804a57321dbbbbbef4dc398457fa6dff3cfeab9e466c82ca652332575f473aa12e64d8555eae81741cc164a8e5c0f99c5e9cdea5dcb6964ce291f330f671e41eae051bfc78ee6d15247eac869f1d522fd9edf395ae49f5978ac6523f8b3fc44fe578e8ee4917afe1d92c77cfe1e92873f8b46f7a5a18a022d538575082b71b00e0264e07ad8e178d6419f0b3770c3227daa2a81c522fd7983c2f5ca2efa9f2d61b2825c9f2cd26f5509f6be9c771a99130c24322ba41c402427366050838517d105162b3c15d20bf643ea3203298ced24fbfa8ec026337e1072fd67ab03272b7fbe6566e67a995329efa6c08d3e393a03cf1322b5238b8041c54a5268908a4295838df21cbaa496784528011e517d451891fa525fd32b8a2551bc60b52833690d42de135af812afb29e0596c1bad5195215c71260942a6888e161f5040747d8d44e8f09ac6775408675eb9460a05c16294b3c6e3aa2a66a4c613429e79c57bd2b61cca019c3439a325a9c496521c252221d63607146061e5c304248d6ad1cdaa91bb802addcd5651b18239073d20f82646626be26ee869246fd12618b0859c8f8abcfcab5c5b2e2bfceab478418d81f273eee6a990831b05246799376609a04750dad0f96bb6c03a3030e41608d33b3bd974e0f303278e00af42edbc07c11c66be2632e5ea44d59d6b300e005146358b7aecbc738be8671e6f41fe79cd35611b2a8f28824bd855222f2ce17e2b7cb043c9092cef7d9523d60de99c472eca5e2e0f60793713eb8f26938b21207aae974ce3965cb19b4e5e3ee6e669e4f442a7dfd1cc7f1e4b870865cc3b850f580395db0630e1dad83c3e1485f39391a265f558210bff389f4a5f376f78cc30c04d449ef0244e586a318a4a0bd608588156a4e14c1050f49a034d180cff20e6bb184925a0db214550106688717dc6e685244142ca86202293f105154eba1872a4744505164a0c4182dc8f899f92bf3f30eeb457b630293949c5260bad9ac093103a8273330a90b84e9818534312c91248a0c498a23304863268c29b31f6a6e4d4120253141338386184534b002092c8e7012820e624451f444832358f8e6ddcdfd7add1a4f9f06a55c38d6e7ec8c56f55af3eb54f138e55a4de7f79cf5aa5aaf157840b5fd0a261fcc5c0f2e33f970d3f1a0b66ef7d7b0ab5fca1e614e8b9d9a5dfec9caa1623d7462e363b446b857c10af4b9d0c6021df75d08c5a6b6c885d647c62f5a96b79749b3e44d849af47025cdd23763e8c8072329bc0803894c42014412659ac08286265a5299a131869a90618916b4196a43e94dc73aa0754f8339b7bbeb96fd74baed09daed67d976774f00177edffc6055ec2fd4b89f04bdc7b9ba2e5e07ba5f330de7e72d99cac98206544952ba31c9fe2af325d9cbe5255b0e66e27a37f4b5fbb7ffe74ec1eb945b23d8754fbb1080d7c391088f9c4f1eca81b3357ad7db6ba4b17139c52d93946e4cb466743465ca51165dfee60f1a52e20da062e533353df9f4a4f441d049527ac91c94526666071d4643e9eeeeb57ae62ee747e2fb5e57eed8928600a458f9686a77dfe0e397ee54dd05e52ea594524ea91295b4d89236c5f28f92f6eca22ffe5c7ffa3cb3e193edcd715dadc138d4c60882eb2976d560172d81641cfa744e6e524addddddb9df71e6269ddc5c81a0ac31869d2f79666a494b2ae59c73cec94f67f2b9268e057157ff53f333cf180a9467a25aec97502fb0925db37a90a7a7a7a61983962d7d7efc2c09f495610de374356e1702afe5b1ab4604d79f5d5dedbcebec724e90d2212d526e752533f3286475fdbb2ee44ac1db5500447450f5b0465929bd699fcd9b64bdfdd565971b8051160c0490b1976d5f9e6e1138eac7a51a064afcd5ca498542b4890d5d5fb68236ca91bb8c182292b22190ce10c9a03045e04bd367fb4225d5de11b00b5be3b2ed8b931938d89bcbb62f2f64616d5cb6dda2227083aa93b95a1b775eb6dd8c7868f276c9ce5ee4ef493534edeeee3aab1b1e30ac7fcc875dfe2f76f9c7407777d759b973feb2c9bdbdfdbde9ccac53ac2c1abcf4a4bad2091f6aa490134c336e39a8e41427b2b8decf86292069864e1ce174b9096211af7839c2cb184d5469e2064b618800985295eeb8e2d1858aa55a1726d7bf591c934ab2eac94e0c1d3b9859e18a2c4c5092a0b981bb81b7386281142e6ce1a18b1ad00a42551071b105113f44918dd686dbff2fd0c002490c7ac0c1cb161b645d58c8a20b0b4c4931cc24696715e5549a5fe5df6ab55332df9420c3850a16325190c8464b25cb5d97d6e0c40eaa2bc2146230a501830b141599d8cd9a3c3dd831a75fc5d3e26bc94b8e4b737a701173e94faaf4c3a54a589880818918d880b081c1439fa881460076542e3c2c31c5edffc002d982240931312c81818a1e658488a1061eae94115212866f543c2e999668624b0d6e7fa26fa8a4ed9585390a95a91900000050001315002020100a870482a15830524471ac1e14000c7b9e44724e180b645992a3300822c618840c21c61043108111a12129034ae877b3aae3b6b03b24fc3a7c3b146de6e4085afd7972abc1c0192808ea55e091ea6cf53d4c35799378d8f543f05ccd67c68f3d75b70a7fbf45512155be294400c3b40b15d92d7fb1bfbfb09b9f1c0eed21e408cde766ca9caaa578d3839e6ad5c559daa721063bf3cdd0fa330be09f09bcc60b487cfffaabbbc5f205cb08eaf4c00d9384093c4888f7ff369907196fbd125a8c5d06e6f07df65540170e52070940f64b0077a5e3c1bd429d7f3f59277d2cbc9454f7048f7f9c2a1d5497b6715c7a9884edec7d2feefe9ea7bcf4291c433a24d43b856e45fc7378a34af00b3bd0ce349335b6cac7da9eb113bd502402b2d802652cb77581056fcb7269dc00f45fd8c3aa17b2befebc687ac974c90e333524538c4e57220218a59b3d32304dec03e6199f48ba811a5b941c4df64d19e5b5b838569f5c803d15a094847c5506997d5806a6cad35e0a69b7e7879854fb9875e48d892fb9c334eac0a8161b22680b7f273812a932485f21ac52a998f0164d7de89c06543a129c344ba54e15826c3ff7a86a469aa2ff54d3d67864d20b141e34b32c7ee481d8b6547040b3fc7e9a8e8ad0806be2b17fbf26769e6d567460b4728a0aba730ba77fcc3503fdfd8d078f1fc9914c803dfdfd915445754074f3d3c665cfef76e3a94b353c1e00f2c17e9a8bbce0a21375c6df69a9b59a7f4de31e3594a6ba4e4bc8dc0f68c894bc0d90b5f6b53f351a8f60fe15013bd3cde30369cb04581950e281fe95ca3d0c4fb30958fa04adf525444e86603272f8a16320e5402bfec2f6b696f325400b1c8b68d1105bbefcc6884304daa79a86d18ec03f38ec768bfad705b72a153e55b1d2877f8468fb491d168eba08fd5b9077948afc7340e8aa726126b3b94becdd9a0fe6d1c6c268c7861db6b82c2c87c634a40b9df810ffd5d1462987060557f27490589c181bfb0a4375686f02fa5445ec817e71a36b93102012e13993b81afc2f508ecf517910e3d1b088c7d005802f17baf7f714d8ef7c0482fd614b180f677fbd75b88f75edeb3c1b81553f6d186fffe0e701814756bedd10dbdeb8b9ef89c78d39c7a651d3db26c9133b8eca380f2042be71318c9cb5158c31d622d70b0702edfb84ea0dfb4ae57720d020fa18e330082bebcb8b1baae7330eddb0b3f2552f90b24f8856ca09b2bfa687b5a3dcead0becb3ac2b93b6661a831fc15674e75426ab4d72914206b4625316168539f2fff62b9b832630ade8dadf26c80ddcaf907046e21540412e4b9639de27dd2ed9938b90ff24e8660268564be4c58bc0b33e282fdbb0c9a57d5a38d5e55ab955047464532fce0fc1fcd749537bec64512010d77a613b3a752737e1abbc14089303105ae37ea29de92b0bf7d26d502e72f063f7acc30bec9a8cc0fa55283a80e596056122e7a8cc7ae8c85f5acf24b1241f8ec8e5fa9f4a252c7bc911d91ce0e030eced20c1e23133121334e991dc5d0318f4d55a0dedac923239b40461b866919746d88f6e2678d6ebb18fc209c605f227dab119b1f84d2684fb4fe9dd63d264d0fb29bb8cc71588bddb9297c899878605fe177ca1280c97ceaf0eba14df272d848bcb78ceeb648e2478ba6d7fde46eec8efd232009a230d1764a1a95d6c64b1c0f2b8422c554908c296ad1ce1a87c273f0ced44ba30df197d87280240caaaedabc40b85bb73f9362671f1ead25640ae6e8021d24d66c100a6ee6317dc45c10970222b91c04253dd904ddc860908818a308bffd5bf3c3015eb329b4e2d44e6ad30b0f7cee49ba4dc132a311d59599e3ac3febad0b615833e7c1cc923821a9795210bf4b14ed2214b3d02ffc2d47f9027b04f67d1811f1d382e4e375af4821e7ffdefe308711412ea93621bd126266be82fc6d8f0b4c77899218ad4b3c726d8f3741b0f1d9c9d3a067a8143c3e10383ced91294734de3e4003e302aa123e6f9f69b3326c2eadd7e69b58a600bd7857687f45ac0cf296748b636a0640b01f1cae3c91d1041aca206e2de7a41540cad9cb028e438419db585fdc4df9120d38af697a1413862578d2dfd79d028b3224992b662e70b9dcf85f76481ef4ff55707708d4654f79b1f8add10b4f5cc2545d464fff2269cdfa4d884f1dc5999bee715ac81dc380c68581d883d9147b606eec41383af680cc9642dfadac14d8edc734d8494e9df3ca37c61e948cd2419b3dce0730583054e9c05d6dbc56400fb30869c084f71c1a4c669a9987b88ec4d68fe8aec5086e050fd452613856be5254c7c32b259ac3d75c0f6589cbee66b6cdf8dcb112dbd91709abd4ac893ca098d3fc7ba7833ccd7899ae5393655196014dab28fed4450c829b7edb379a95863221b234f180ddd396a623abff50f61ba3a8c08d47cda360256432f7b089b2828eca15286ac1c82bdfbbfc837023abfa8b2261e4f58b47aee62e48a9eb00fab61842cd69601effe996169b55ddd9f193ebec8743efb3c539f8629e444e77d328c93f903de2f98ff7fa17d11952ffff2811267d584f702509238010339cdbe12a66099c2a4fb76e84472c76858d447f03bdb26ee1eb70e80991ec9b91911d987cd3f4fbcedd5f084ea60d59038529e3464da8a44ba13e3699762ee80732d7cd53e59e3e3a34b10b21fb2537aa024584ecc57621f4129e65aa33743df0f88b3e9fd79821da0141ce764b775a84a2b8008452d4a312f98a476e92b1c17e76431f6be7c8e975c0d3b49e8dcfd981cbb8aed3531b1c12779a14ae89e9dfa28e2b9edf8fed6a5dec89526a8d4ccb4935548d858b5b89545a181e7203f98fa52e730339c0fe4a8132259ca82899e449177e9990a60bb0fd83c4a12ae1fba0bd98141372d2db228640f31baccd48198199b5b78cad0879d9f7137e67a86b9f98b1849bc9dafdf627ce42a6e45786af4ff3dc93790e5f3c8f23c1b5bc67487f70f4afbf1d673039091237bc3f090183659705fc55a590436124b925cf11baca469248bc50f235beb60f508da34e859faca4cd857734e06c6c60d6ca8d3bc6dc1b8669814783e0a1aa709b05f6d90890cd99d97e7c0b893830095b7ec9a4c954bdbb8604b366be68906ad65f9d550bef90a52dd9f71b85d031cc36fe289691653b347743541ffdd75a1830bb96abc47f1efd892e9944a9f8a97c0b50dc0fa133678e1a528f52123e72f65baaf9e6dce1bd0af6562a4d67305cc4e328eb955d87e3f75b98b86a2328b3dfcb889bdea21dace76c0ad8e3ab3ffa85a3b8687526fe22ce71f9d115e705630f1e06fe4bf59c688175110d1550ce93c36ee410507e035b8d798f82ace860f4af71afcb04c4a3ea0180d305af217041a423f7825ce3d5f64296d214b9017c3ceede6bb48813b3f0600229de3e02a4911d52e46f2057842427658cc0f7c52c81897989e371b4b1a09bb27acf687a8a98676f13c0ad7cefd14cd6d04b76786528dd560a093d0e8ed15a15321fe40fc63336aa5f5b7afd81457523b4c76db058814d9712cdbf64d9b662a9cd3679bf45c54c9dfb77aabc6f5ac2aa5269913259a55b9feff9b00cbe12532bfe613aa1a5fc6efc8e1d684c153a0db502c8060550bf049b3b6fc457ef99eaf7723c7054cb1e2e9ea91f30d0f4081c57a69c6188b01bc52c05cc4ed4f55f27896be61df54c2970824a329245516e8854a1af1bd5d624bbcc554a43ad4f71e51b8206abc2482419fad18365b97ec79634e6bbc8cb683eb477d56c911108580898c0643b25010fe7078f467cc7135dbadf338167c615d720864d74ba12337b59c3ee4294c52b113473891d09dcd64b7996d47016f67f805361e211477767523ce88589eb266443076a4875a8d40cb1fc68ff2954a11f40d1721d10a76eec69eec654a5ad8bfebd205595e690f505b9c9077338e758cb8e0689fdfb28762f5b3e15f6e9b2cdc89350a5cd69488ed59348d2706eba59053779f37d6e943baa9825045c16b8d75ab45016ff5714a606e369786afe6cd4c987289deb54f5cd0fce23a673ce67ff6e137fee66bf0092d69afd2dc3c6f2f4455f4d63f2ddf524bd1c9b14a91f7d67d3b38a1419a7943d75efa7a25c200dc92aae4ea71fbacf41655a15ffc900545860c127250bd01f12613f14c179e32da2110f7a6588871b40f7118f84eef0a51cd8b9463eec897531a843a86cef3094d03539a863c49ea1d116e5d923ef610f32ef7756c6cd41174f0d2e223d1587b1d9b6ead26074f3542761767bbd3d2c18f3ac4297b5ad1e8b2dcceb2cdf3e3f7800b358155b19822577c608216993c82cadbe86ac4fa2d2c09729577510837345dd0067afafb297534256b5b3428b09fab27ab130fe38cd0a419869bba5da09cbcf85dacdde922ee80644ba3e5016774400c21a4feb81feee191c86736850037beca71b3292f17b7cb96bebf6457550e1200fe258ac71c7ef5990f83ff3c0a05acb4e5b4cf68b0a8923310cc267ea78ae59927b2533d2923b3249b6440d7f4dd566bc9524f224e4a240fde7fd6ec66b0b442f121ec7fad5eff6810549c22a87695c131c0765fd41961eef87ebfb4617aa824a9b2e1f35cd09bd66d0694b15d4c8fd4d26a25a33b7243625eb67368c204aab85007b7fc4b9d07a9bd6bb294515fad45a89e33ff006097867fbe58ab1c79b605c19339852dc2ec1dbe47ad15d6e9263c39fe6dbfd9935cb27c60b93b4ffc3c2ac0ef159f1b80c414305d14c69cbb4ff341cd33a419285053063119cf06a5708ea4b00ea932b8c018e53c16a2af43007208860d08e63344c52333e25cbc1c6c12a30485c63f4c31498d8f7a121d16d85c1a342da6543c49080653dac0e0de402367022e06bdd8d8009dd73cbaf0da9c17504b7071248e4d04e59e4558504603e881e91cfcd926ca80a9cdd2b76a9e4648bf065279faf27673a188b4694a51bd68a1cbe647f263a3c5a21c08539833faa9e9aa9d5b525a03fcf1d4a6a7cb875cff412d90167d04c81400547cd8897a9e167a261ac59ac276fa96916741586eeeb84050a1a7446e181597310d3aaaf596a1d4e318d45bfec63f7ce18de2686d7098a6cc52980ba9f76cbc06819eb833e9649465d73c086af649e50261a368fe3e60e60cae4af4c70a23f32b9fe246fa6ef2bb959fe959e6d8d1f9a7ce09122b0659940eda4d1827d92e0c2b9d780c1559ce3fabc5280141b8a0863fc3ab0e7a15fc22544843141e081c9ea49c135bd000f02e6b46b9d830dc474663c6c9b57634bf2142fc68f4465c318227cda3bc7559a21acbf65aa07fa4ceab8ceaac62b7f5a32eacd814a209efdc89d82182b7dec194dc20dd43aec75a2467e490afc9e1c310fe39ec9e6c5e179dba313fa1102a7958e6fa900541dfa542f75a0a0e8f85a6f648288ad688cade4a6f974fe18a7de6debaca40e58c040a2057c858f51fcff04201383b3a4f0ffd0ea43c590e41f9e480b70ce897c842818200d0450412bb79642834d45b5bfab412439fa4ea03f7f70a3a47ca1053772e3f92654da01b11f4cd21396845fb1a288bf6f50247ff0817d4010c8fccf67c4010092ec0f3e900e7c88dc47e144de89daef90757e67431b09b141817d226c3b8ba1b0d5ce9a7a05084de319b46d56ce36d9ad77286abb34400d4fa690e4b6bbed13bbf5dcae61b75be652b8144760fa6b6d9b38c9ada06f30b37a4ac505d9d5dbc7dd13c080e5792fa06753b1f3af8931dfa07f2dd6718e2adf26c3deee184b4d34d2710000f80cb330512d38f319391c45a72950d22c6d6cdbf84d5bd389f17e5f433bbf523fe1118cfa3dfce9d7695cecf43e50c5905a434a23f3af0ecbcea7e644287d08bea650fc75220f93562e56f35a026fc9b236b09cf8deb1d8ab8f373b79bb2c5ef399d6fafdba5d8a5d74b33b40af1dd3dfb47311d216aaa342a140701c89a59e5f46d3da9835875f2d086add94d83f281da2c4961e0c2cdc6a3ed022d01741f47f4f7a200bd8f484fa50edd32941d517fac9719801a08509600c1060e80d30aed47261199074c39080c318944311002454a26340d869efb473877dd898b33db6b2f51464eb6eb74547e3e2a2ea22d1bce844cf1f430c9fb485ec03cd29febc6e6b65f70f98b1ac6e42ec89b7956027964540c5dc95771de28da73b633cb926f1f9c8b7d252259853e9b35d73e27f1f03ea2ec268a0445a522400485a17fbb6e34b4d46cde054e54155e9f33e413639db0e40d285077ca0b23ef1198766202d0caab6e87733011cbb32e625e92420599f1bf6505edb5a394d23c253140a39cf858b8d2e5dacd2ca3deae00c82d9597cf0e80a944bbb0882348172d8fbd368615f49c10494d2ad8c1b7c924d0db0a22c4e053d892062b6f8c1e56ba58c3f28d119039b1bf3eabb0e666635b2fbccbef1bf8b386a86dd6d80dde65f67b3fb140984b058078549474c6ea2c883844849536ab1952e13450a2cce7394b243022986cd95bcc166f68573358dd44886b500b3124cd3d4176593bfad59d626eb852b7a031f9031e24cc7f58f2db61c5b0e3b511c6fa7cc84df2e580ac187d82282467564116bd5ef7281f6bfaf0f80ff82a4dab22025f80d9299567328dae72f4dff4141180bdcd4a2f541bd4447c58d8ce9817c016175133618d9b99c19f6a5bd1570c378f7b4f829bd68e506495a6cf02221c0d8930490ddffc7f3bf47446ea228eb14978d9e54f0e14f067cb6375a832d65fe98ffeafe99f4f64f9617843dc8102a2f0fff91aedfa1c4a7beaa1c99a28c1eca7d6f7269107009f137dcc632ad1e4f79954be5ef0574e595b26e135f97e8e180ff90c34251d63639df9388f446055830cd3f39b635084f6c03b29df9b4fe0d310182c9662c91e1ce51113d2acdcf6ca3ec4ee62d66c06bec871876b68e73eaa4374aedab8c7fee3968eeec0d4e401e8ef14e03a6e76dbf611b146279a2227fd931e38ddc9059910b2f9cc36dfa4ab9063638100df62974d5b430a94d5aa40d82286aa3795777e247d0f59cf1a28c659a8bb98e91aa145e9e7ef0a87d0370f1f9fd3b791c98ec72da876911644bf1441dc12921354af46936cffc8e071f523b215d3a055075836d8f0c65bbe1dcaedcee3c26789cecdd82580cc1bc21cb6f25495e84cb85e4c6ba15aeaf50e889b4add80cdf0e0195574d3f15513b0ea61db89afb47f1135e6c132df0c1e20cb0fa25ed35fc00411fdc2014eeec173f9f50e09747b6a8452720cd5793b25789437fecfa51f1a7f63fb2aa178f10ff3715da9d883f4f4a709d4d7d730f2336d08361473ee9e8c2b883227d8b107b962f845d7962ef3f254de3567f926357e3cb4d5eddc70ae5f5b4b8427e0e3e3c956a665d1f206a95bf78da9297fafc7dcc5a2167f546a5227c8983c0483c29b71498b3f955eefcc08deeb9a51010ec3d03a100c5d1d579239889d9ee712bf29758e629c767105ea46d5457ece415b1289dbe1781d99cce48c9c1d5b30341c77fea90bc3d73495560d52df59e853f02cbe95cd4894cdd32411cd3be8ea0f3c549df04d872fed82a5bc099eb8177c836ceaaa6b215923b53f1212ef378c0ecd1fec6a4079fe43946d6809a005bc54b2bece76322415963df1aab7eaa81ef15c1bec3302d18b902275a66a2d42c517869350ce88d0a878f4c0d0135dbc62ac20602c52c165412a317bc59bed4c93f16909d0af4d461d4ffc8fe9908e37510e5de94a360e1348b26eeec1be43c6ac05806a2832877346a74dd731d6acebe14692e625f4d79e01d704b831f1d6cd2a011120012b134d03bb3d24f797001fae7eec9723ccc62d3052ff1e8d2c4348e4be310610d969559a915eab8708a4c82564efc48149742dc2273ae25aef3552fa4ead7244bd6c63f553920625fb578c62f158e9efe19082dd9eb8ec22f496990c5306507b45ce4ff6202dc65c1463c46d05ce6a8eb47b870b1f06427bddc30fc97ec66fb3f89d8dccd609358e74498f43707df42a9974ef74cecdaf1c6acc23f66e82ac30ff60e55bc541543ed507f7772fb5410f82636a936cd7eedd86418f93ce705cf03199ff5c89bb83d632ea468c2082514355118ead978514cec215bea6651271968e2ec51977a8984d2c102762b9c7232e2010a2eb5838645eee9893f1dd4fe0dcf7b711c01534af19438c019b1c99304d023139d1574a12c21eb0abdca8e32da7b667127aaf34aaebaf715c574ba8fd1a86619064edf603741517a3a32ad9a83ee4401a630669d658772f34dfc031e5d27a83b9a23510c1455e4f57b908e0f46b4603989a2876d45284d67d2d60e858178364ac48497e372878c3a10ea4edf8c2f1efffa0bb22be86fc3df928527e40f610c2e2651f6f97d171a32758e384ce65367aa4fb6e4d313e3f0e5dd7376aac958ab64d73e65ceeab0e9e19746c167484746c1f1f802a65f61f60264324df12cd40b4f6eb924afadedf140e4c374c960e8268e93f9c1f26b272488ff1dec469815a8d1b14081c7086231e3a2add0737789443e920862deec480c31e57fdc470b825d854500cb85566250246ee1b54f15894ba8559b3b5badb0f0144f130ee49d620110eec7b0453cc538782d8a1f835ca9aab203b19c31c5237acf149fda65bc23a3af3812238ac3197238b417c56ee883ae6531af7db5ab447f7e681204d8f964a60dda8102c571700702bae326f155cc7e0b2e4a266ceb3911edad6eb2a3b03df716ec078b4c8081f1aca63bb26bd160184ea6708bc887c04f79c366155c162bf890871dc1e0585bc1558631ce7d7b5e03e0b1f07dfe04d3ceed41a195e471a63a11978286b2218292026a0127e7b0f493f85c62c31125223719430520e1553de464d641d4913fcfc0fdab742a97784f3caf5ce748fc1f46dace495595d00ef034c88a6b8bf8f64eaea880fc7efe6a5e1c3403df05a90cf88ac78a514098338e320df52526cb0f0b218527378d977a655745a0ad0ab707d33863fa6c23838e7791b3b0acdd414be868c506dbbda8536cf2e14a3e1e30b5890b1f6fadf79300b3baa2ca934e0906d640cb922b00000007cda4126643054f8edd5ac3b9b1b80a65684b6f62a7af47892235c8349a17d4418e9f6ad2c3f6de30a4e3d5b54578162153d64e27a2066781d4f12cd31474a7bd0beaa7e4bd21950b93603e88d1f30b3e8fcff501a46044476aa1aba12aa41bc56951ae348fbc4d0bf09d1382ccbcc785f4c1397221b44ca0a5877c2a562b060f839022d9b081f42b7b4d2839ccc40dcdd7253187af6a924828d57669e780499bd52631ad5a0edcc06a8e93cb3196de20e4907678862216478763944e45229ae67a12087ac2ca73d1cf2bb1a6492c0879bde8edeae2d66de7d2bb03c5c6d97c7228693f5ba7b616cbf0121209a7833d57b72f783870936f07fa66dbe2dc91c4382507d2d1f5d85a4be841877ee15a591ee44665f0bfed76a889d59a4304d2876d0a76b5359026010fef5043804abc16f8e720ceb7e80f9c02972ab2c1cd43573b305cf5b33828f91ddc7204019ebded908e9031bd0765dfc6bcee23b9eeb7f082be7f511f07146f378e09d6d80a8ab471299fe1e4c90a14ab456cbb90d8a6cb4b7abb20210fd947793489c0e2ef70bf1a9c581d7b76ab27f3ed815880355382de0d1c45fe090e42de97ec959d66ed38ee27420ce8068641c62c67c39fa6e18770bbccd2e09e9bddc1b1aafecf4d48c2630db7c0bc7b1476a74929e87ec319699cebe389a2c2afd36654460bef26cec01270235effe0c849ebad0594c0980a560b2897ba5b3a69e0cb5ca291f3b9512c7355aeb7485a47ba2e743959ee6488fc72bd081a667c9118e23925d4e11c4943ce7464c8a040e153dd191b70e7a95f4bc171c95b1bdd206974bd82a4871a45dae2529a5935743849c7725ccb13d9b20750878c941ae2bda7dd38c4fc67bcc2638a9a44c5302576096e1aa98a855c3cf3338508e220965008bb99beddcab8942fedaf19f7bdef2d036812e592c365944914d9509c49eea9ba49d3a2de6e3c2658e126ea2c6f2b7951401d2527f54ff55371df00394f8d45931c6272e6dabb14ff4b2ed0d85748beeebc98c02ceb02b584b94409c2e35f190f6f3e943f78787305e795fd1c0413bacc8fd6cea5c113151c47715445c5e98f0d21a2f3c553b91a2ece7c75666b9e005ee743ca8175ad3a22145679f26f9b0b9e3378a37d5cc5e5a397172140b6d3c50dfac3083ae241aecb0865549b8ad13c735ced77ce85db12449d41e4f4b4dfd1c856c5009c5945c36e24e9bb1b20ef3876a2bad70e5a53de858312753203119e27e17d3dbfb1f806d9b4522404c0c4fad1fa4144c369bd5b9c0d0c829504b0931d35031a58c7cc9bc1cc79b05b488c111f326c98c8373f34e4071d2b2608f49bb79c945545357d706d7c2f95cf835fbc40ef8feefd2fd1d272852ff3d324d5ba50067b10db4255ae51f8e52845fde3bcd82c6c0a3a3eacd60fee3aaa42c3d6b63f6fff2df631688cc82b4290a0bdbad0bc40ae258e9846e2a287fb3199fc8890319dc5f31a914adb4c3583d3281c84a6642c436354aaacb04f65545fdc5ab4487c83f75645501c20942b7cec09070b7ef9eced879453be9858c2b01954c1c2bb278964f7e81862eb8c9168744a22d507a422936813675e646dfdb7cbcafe8700e8c35f9b5b44c96ef26a979eabd4b6b4e9e1398089f50575463348ab21663637f747120812cf6912aee84f032a494eab8ae6cbe838bda3fdbc144d106c7901b8c37a3217057c05ada9d8ef81a5f6b20d8355aaf65735cc667a4a349ddefb339a1c67e2c1c6cd2d2beee943a1b9f252b50b0a542b631986343ec55c836f3c3687dea0c5e2b2fa45953b40fbb679cc5af739156075e269ee2754508e8b086759a76dfbbf871a96653140cfd13164291e2e42460e4739a1e21045aca8412c4584cb4ad07c4c47482307581a6d130049f3d1dd744a9ec73fbc81a8f3728d6912f3f118fd5fde3144b2290ee6194a1f4d199e3ae57880cc523431af31fbccfcd946e2723a6f9875ef796f6cc7c532e10071b8a4aee9926b1f06dd9c9f95fe79a1d47fdfb72f49392dc76b16a7d81e92b3a044d910ab0e4398f60e646ce3490b0ef36bdae7348c8dcacb2071802cd8b5010cc32494ffe327575e6177ed3f656b78f12e8d5904a0d941630acbaffd496ba42809a22175872413c3f0680daec25a3cbdea7e4f35df294c5dcfd7f4227db9ed13e5c21c89c9d3d886f47e115638f65cc2d5ed3b8dccad13112f69db2c9649611d76b62a95dc9e8315a25d00052be82d14f151660fde8511b58d456c8a913be54a9ef44cf5f95286085499906aa7a0530c30e419e3ff462e194ee52cabfb29e1949edc2edf86146741324549872456ade0c2ecf6f319a998fe3450d0980cb2f242c43b133ad952dfe17e046d5029935a81b57ef09951b719cd30bef3dcfa9fce1ee322cbd4bd320cea149b358b296e05e58728bc6e413e0b1daa194ce4bb66c5356a51dd27dec8b84a88c1f57acd494edb321202bc96115ef0ed3ef3c45ccdb136737f57bf974581edcbb804d33bad0e02549ad600b9d26bc68880d8c9eb93039c0ba10e84b409404f7b7f06c2ef9f3848184bcf03acffe174d88d2b76a3531f7ef597c82a930f1bf4eeacd65f05d61a3df2d049fc13c09a267b7c5a20af0502d62e99ac35a3b86fc7fdc4845baa0b1e4b44ce882e1c303724c7ab30a96e485ecaa826d05063f0f2c109fff18d7f4917686ac1ce44ed4bf7312ba727f52e0e07f8d40031cd163e6a6f10b23d28e942f1727746d0e124409b69dd76cc9069779292c006e4ad6ef0be08ffb74f8f9464b13fd0116bf4cd478c601e6437dd09af2c322b70edfa5f7d914a0b693dc267da7b9d04bd34304dfe88c808e86eddd9aa62c5bee3f4147476925397d650273d6a0c849cbe7c98bf32ca23b0a519336fc51386290e71c56502fc8888120427fa441b888896297e2bdf6d6a0631e1327d1ce99d42fb840be7e71b4fec45aa09f7e5b5d81c003797ed458e44887f2b4713b00825f1f9b65da8d497cb4bfca8d8e1e80be4138e3ee75dfb559b8f16655109dee3621b9760673d6c9d339e100a7b4a62a45fed5087dbf502128e3588a45b41b5e330a1d23579a540a7baca86359eb5aa08bcff569d5d032dc2d128d5748cb5bf12405ecd368fbe1bcc33a919e4faadc79507d682d3de19fef300ef7736c68185a03960a17ad81b4cf6c357ff734c93bedaa338a6cececa067ec0c816e2d62cc742e1544d6d2ca04d14777732595fd9da6fb3f2148c525bf1a418b2a16c11b2ae7400754ff1becbc2b8ebcded8aff89f73b22b671454a7ddf483faacb42c98a3e0355b1bdc88b5003a059a8f5e48d5d9118b0f962795a526d05bc872b8e6d8176b7fef91e1baac83d76d7a95b968e80adf92a3f3f6d952b9d8ca14871dbf9e64b45595f00942e4c4f1ba824923fa204c1cfa21484a3089b8f51e64bdf87377c250bc1dde26446e3931fa0a506a4e2c5640901313e104379c67c15b8bdb10b689f87a7a21bb5edfd787b9d48b89e8d39561b8afc63b61c2eb428ae0c1d1ae0d7ba0c744341408438404dd082b3c0c40487639e531be166d22169ecaec36b85fd6107a30660ce4d139d11a6c9ae4b9325cb219426533d19fef953f3c369cfa17618fd274152ac92c3f5b26a4eb2c23d07c0bbc772bdd9404199bc71fa8f34541e8850d6469000979281f08c5222f6466f7df71b4aa7fac549664bcce1585c47f2cafa45c826912f9a760675c02289b2a90503754b214369b40cef34b9d3ba15871811a633147a8d71310eb41ba775e55bd9c20a62050c424df110ce9a931527e7ccbe88646aab1682ce3ab08085cce487391f862b075fc8c73f69332f09e7ad44a79c9459804208e82996cc923d2b1196a37ae5ad9f8f9f89054aa4c4280d7adc19cb53da411842ca6f96e74ff264ee7013c3d1d7414e65a42c7378b99686aec4fa37282eed814814d3897b5a96caadccebd9f3104f24eed79877a796cb44896aedbd5260f0b61607c7651b0f60b38949f9e48a739633ae0954716e3e6e20d6ca31d0afce53ac7749f5cca8d4c10f44d706981644774ed4a19517a16987047bea685386295847f5176fd812c5cf5ea2973edccee0a9feaea9f38e1592c86f409c7a41101410b851ebc2daec579f99c4ae9f483985585a2675d4c87d60b8dafc8623cb2ceace40b7e366c0f00a1e1a1e69c0277f4cbbfc69039d3ffc8acbc491789f5138fd1ebf8ca70f914b7209b1d9e7495be883eb2467462c10b20da19296cdaddb9e137069931a760e664f50e32ad27dd7ffa9aacf66b6f758d434fedf05754516cbedfe6596b97305b6422005ccbf19611ef195558f64545dce429821be42e3e1d446e0052e44fca1983a2edf7baf128080333f5b220602007132c7903eb99ffee155101ec5e7c7b9056102c1877f83bdffc1e2d58bc6158f5f92dc090781c1d2fcc54a70a7de7d9ac8ddfe85a80062ca75127949cfa501e15acb33ed7f97a9f41ee340ec92564db58727c1bbf9b682684d4f5e050667eacba1c0546855e03465a14018afe2a615ef49afa0b62e2849e3111cdbb01eae290a4aa73f75c72f54dba38cf05b0c4ebc309fa2b647efcf4f9482439b8db7e7fa27bea89521a1906c9ce6436bedcca9d5ae311710f7111ca23333dd09a329786f5fada27c62153c370a5e25a6b7e437048bf3959452a1eb36a57cc3ab596a04679c4f0c11899256cf17adfd9538a529c32238aedd18dea7463e7d9d806982edbde3b15fda6fe703fc3df02efa490640d932375568437a81f5f1d6ff673d125184a53e382375223409ceb8114cf7b38ab051f99da427b4495fd3ab705f2d8ba38d3297deb736cbb8bec186a32e4e1556c5cf1c50e8140b1ca745eecd1d061f5626dd71448176a6e4f0aa5e04f91827358b70918aaed97e866c599cca7d87faf665c7f6efd5188781243c31d1b9c750c63d75d97bf1b6345ee41a8498080af6548d6722b686cf9efc41ddc23bc348750406d46faa0cfe608a77206fe46402990cee7af086669a766f7488b180f21f5b949c6aca74a578117479ea436e9dac749fafe3e2a8c4c8babec6ce0819ec82baa8f356d2ef2da4f5ae0a48b6d145cb0a8947aba04f5903ac30b12c0fde84d0ffdcdcd6951992e1ddb0a3bd4cdde831901450ec64215a8a362a8b762a558c01cc8fc037cc02e18406e0ca22caec0aa509b590d4dce506cc282599b65673c79822e6b8fb8347f8fa9f2837f58916b4fbb26936d14fc3f80871485a94ed4113dada3481acfa1c6713c9438c0a5d74c1bc9bbd07d6c2da26db3ac588b7c3204427aa13c2f9485606bfded0bfe0223deccf763948de4bde3f97ca510d60f37601cbbc569c52fa005629080ac5be95e187c42936a6088ec6c5e6a80db30a429808fa58e953fbaec39f93091fd2943becf378dd38513ff05537d24c637991feef5a7fc8e9163d693dffb830b46e72704dc92a44e2bde89b2ed9c00525d3e7a864f18ce2963f704d2134ab617347e8559a1a56d369bddccaff7920916f6d3f15ecb294d432cff9f6755e92c11e8caa6fe7e901fbb3dd3eee4fbee78f9b329f6647f04a87d3d50e95334e36e5d905add9f309b3a82bd6a860339401a28a3e35f08c189a40efff5c2a7eee2f526485ee48098b9fcf26862261a2a64fbea37588151fd707d4286275541376a0a102a1e5beb6a3fbd03adc618d22d4211daf414b0ce83735fd3ef314132d1e923b0fb54a5d98b709fbc4dcdca1e79061fcb9ab70b12863d46b3def952c4dd99bd3c831c821d3dee8b88b8b87834136d2b302f2a481b43eacd0d46b0702be4ff99610b953aee84f22a78cc5acfc7d7b9a77e83a7d32f0d58fe56dd050c43fef53115ab4ec60783849062c5f3fc04ac00f2e876a9efd54c4f073b030d3e4198a7ba13b244d676df3b025cec1bd28f1fa523a7e40cf5404c4ba7ff5b19722833ee2da85c63ed53f22c0f9dea790c9a65eacc150a8d1f9244216c5037a112fc58abef5929de9bc1cbac0d427da804b3199a14b65bb0cd7464ad3d494bf4e0e82a00df13435f087ae2bf38efac7a28e1897b8f045d5e843300058f1b96f786cdde57bb7d8307694fe9d5152b0fb905f037a2176ef9ee73feb1efa35e30d0cb7cb20c11d53851554aa9fd02b9f9ad8229265b32959034d72654d0592d8f42a9e96f060e0727e71c55afae97d4fa918a45822707c067d12ca25fe5e1df3b50adf28a728028ba86c1f519253b9900e58e95282383a7d226c29bdea407f561f02184cdb3cb80d695db10c5a13f34fde279f2d59d226734195bc0f41a39a7fd466fdcc12c94f8b21ca945402d0457113a6f34ff7c2be5e07f5f28af50fac02914effd2280482a25408a45678e551785dd95e065006b97a2da838465fc10b1b97f142dcc2b3c47dd5a7e8d9574e3c2f13efbce767134930b1ff984fa158c1523df14955326b30cc0b627824ee02292e6f0eef0d78ca803de584b07d5149b6f13884d81fc9638373cdae0bfd5a8835a95c9ba3125fbf5dba1df7bd9f8e3c584132fda3849182a8018a49fed85ed37d1d698fdf341c7ae05a0307bcd102ccb9990a86d01f94ab2f1d1ddaba0769d4cb108a4299f52e94401443253b1580916485ac6baac7f5389731100abbb80cdf00a4cd4c4f16a155a04f50db4b2e0574c298852c97031f63d403be200b8efd414373b489978fda6256298bd846a3f1f38c5be6c8806506b9f20142433dfe5f735809ecc8c73ab1f47ff4853cc9a3a4b119545494ca419720b9571975cfbecb28d63fc837398c0d275a603ca4ba9c0bd7a4b8ee12f018da5f28701b528a9406d3a18f93f5c039cab37c1f3d0f4e29a6d9dcb93441795d58468b0d7a4e35492ee03dd8048d87ef51986019720e7700dd566754cd5baa97e6db546657da31fc67906c294b5de6af020fd443068cf1d3ddd511e35d80d6d320a3d5346e62ffeaff349b5b5449b01fdc30db0165eb79c64e71bf1a0f9cc3a557ab0d09bacecd176633eb704d437c133e44fe0911c1c9d76268237a2286f2029deb2f1d664302623dd5ad590e04cf29069a78768b3c729aae149e6b7970d260a213423df95b5842f589a89878e4b53db237d4d94db673eb329b54db23b6d9fdb533e8924c7a88a2568f3e28b1e6a61f47e56a764e40309ca45ad5a413cdaf9314b437f35585389a367bf3a538df094378f23386b9bb37e95b87d1e4873e7644d80ff72aaeffedffb2062462f48c2fe742d87d4726432861436beca5bc7afe120fa975113284e36bac18c3a5fef7eb2277c25f6b9559590f51937a51a7dee92b181605bd1bc98f0947ec983dee97f57ea20eded3d04096c76b07bdbff34d1ae97da9c5f25ca9005e4d83e2118b1f228ac76162ffae5eef049de01a91de294ac024de69408115c0992a4634ada0b9b25ab69695f661656aac72c1828830550eacbefe3705bae6a8b8b53439dc72d53184fd6f48680f51fba94c528b2d4d91f85975a88c150ba1aad814174322185c97efaa85aaad227e778be954b9df3964d728f82a0b8367aae5f0a2079029656b42877e3042ac91454f7c37a71c00e8d269cb207300d4d0ac8ad3c378aa1a7fe057afeae6d903613d04ca3021bba6950ef6be66f2b599b6b87f924e9cb4ac90d3102bd27e9a07e6959d0d7fcb630d0b1820a7cd0ab5509e0af9bb52a356f9c1a9e24b42508d5f12df36af4c990db50e550a42a2554ad054342f15667995c58184a71e43b675f46a75ddbd4c553f543cb433dc25dec5612af2068a6d59e8fdc4860c549ad0133b3123415e39000891033a0a1a873c027ef0c37463afc6dc510941c2db315e4970a5203766f7573b334a653bacd32e9faf9e5bf8e1099d57ec2c3a467ca5ccac7ae91cc9181ec015dc7d636b023b503805cdefe15300a9c9b7ae1bbc953f35679a976d31e2964d85f82e95117bbde38f8f9a5b8b07cbb077878a8408e8c0d41e3181e09d5401215ea05e236dfceb67a8735eb7339f7c6b035b17482fcffa28d6daaa5997253bf5764e107d9041d4c12dcf0fa1d5450729c86f3bc1123dfe19874c7616863b56eb508bafb45b7072411c695d020cdfbec42abacb5e89a1c44cf793649d3274d333cc8d0b3cf741098dd58140f5999a778527c9cfdcbd3e81667d277ccb61748f2f3c16549c5a17868413366653f3ba0153c2da4204061dba97c3c0bc4287fadfe1c8e6c10c0e9d56a5d06a99d9822f19c0f011e616e964e0055597dc9dcde9dbc7098513ba5b6b728ecf301aba598fddb41ea8f2f187a3df15b0a00def9a8f39dd6529c58f979a00154bd15ce8908a44759b53912370b12790e509d93a536e5158de91353c7ddbf2b74100dc3c28683b6077dc78482f02ef67ed68088519cdc149bb1c08d9461e217079cedc2fc6d9624d91cadfe14f9aa41a122f02696c93922fa3369fb693399247162177eb6612fd5919b3820551cda2fcd05060d4101f5144d61841e4b8b11fe4c470eeccc7cbbecb9dcf97571c3f4714491185c88be13d1e5c1429654a68883c3a34bf73d0b110c6fb00bae07b5ea3f82abba236164d7d8fed51fbc4207f12a577e0fe43d9ef96f37f8efef6cae611da25d182781e0f55fb68914e59981b38b35290e2ac1ef172c296006b1a134a8f0538f5d89b41a2c5de67ead415d254043793a0a36b5c7a084c895dccdce8a886472442823bf092274438fd70ba7d1e2f48634385414ec3c4265e9b15e8a9cfa34a2a6d3e111aa0338ac0f51f37786704c1e09c7743e5bef432c021014dcacb1688120012a979f1aa9538b83b6c94b10293b863f70596ac03c3ee95e73a7437e6993e058108565be8c50953b9a6e87921ec28700b29a02b2a50287bc3bdf0e07ec34522b7d429af558575d1619025feb94b6588c34d562374c3fc378dbeb1b8beeb837aed5e2d1dbc3f7f9c72b1f893fc327c4446d30f94d638c5b2e7c90aa4ce5958d5b5cca70d7abc873f3889a3b0cf6daa739d44dc71d9c550cbf0722498d534f35cfc1264e4b1014c68228a4728e340dcc4fd3f195a2ef83bbc2f4c9b27839c9f43997002f7d2bc189b68a08eadcfc12f520205af12124b70551d398ee7596314d90bdd7f03d5a3cc28fce9ced723a04a21a2b81d5f71a70b688f1b2791610df8d8102d32f5897b934549632c0f21f17b4cc011f993412fc30d3ac826301bf306eddc014af5ce58d97aada25990487ca2c17f777cf38c20b7cf2b525b0a482b9c6c7c5850cb85445af7593d055109b75a3e3766d5867ca1e1560cd7bee25036274355e2a87765b367526e78c0ced003392051e43a004f420995ed6bca2564c1f6e7200a70bf146dc69163c26f52535ec52c4a125baf18b25c2670d3c5f3047740bd07878b4605c906007131bf0173e7181d47d1d1399eeaf6257e96ec2dbadc331c56429fafdf440ffd1a7096ac11e09983581da7390a0a5d51dee3e4dc828a5fb0a2280d54ec8b54f9a33544fd298fa2bce0727de2400c8fac3b6140204222420a7d15c3cf99c6d11645daee623aa0c87213e6c728bda0ca8db2a8b3275eb3d9757f58a54333e7e6ebc48da780385c663f0f37f8cfb81b5d782e2e50a727e52fcbe198278016f06c5faadad5a5d9e4e4463a77091e1acbfaec8f379eb8b3af35635b34c2338457792aae361c44ee49296a74519f8dceec526610e3b231f07d1c306c05f110e6191cfa7a0d823c75ec60e526f2d6a5d8134c3dd7ba983a59f39f19fd6da826487d592571f803eb1196892e4083bf359033110713d8c43b1581cc9908936e267fbe23e7279293484db065a065ba297435703d3cf4961e2b0a97d5a296359d4c3ff262b35164e0e8d260a852f33463a99738b3d72fa64962c7795e96ddf9321cbd455e31f5e23888de7d8a2dd21291676c270e2f28900c47dff8e9258cfcafd6bdce92dc05a089ec7cd002a0ac06b7c6b1837301746af43cec035cdca7170ea58e3209e1cb3100a367bc27b5d731f6f1ce8f7418fc74861cca56a521d433ff55b956372047f4ac99b824adae710e4c8ee7c6de20964b82da622e5e0d587aeacadba3bd1499f002bdd47046fc6ef304914d1a228cce9d12e6f62ca902c662762244af442f2a54cf653aff62f6053d59b75feee1d48d4c845932aa5b9c582e9cea4e0ed1f1ecd025114a0133c3121d4594471321bd7a9cb9cc65663bf899ec41000df84cd9e8d1c211b8c28824f11522ea174b129679302b82a70745882cc11f3fe25c7f92fe0e661a478da243d61b40cfa4feae64a72a689c04cb5cc47f1ab692cc66ba2876979317fc0246a2ca1ac2cf178934c54b982fb11a6619efe72ed2a5b6abcb89ed9ec265945b6973264d9984a0480a4576800c0d43417648676efce6100e8106320e75845c1dfdeda2673bd5029c7b6b1fc4330f17809d1cb0a38574c9f17f5d2939f3dc784708965f7be08ce70fad56cecbf7a0b2100664e4b59463f5ac946a39983536d335b236cc811b1e5152ba375ad3bde12ac83350a1008ca0d3678c205ae4a8bf831ec3d717c44b8073074b6b7acb139e039526352d85617b68f8572e776d0a291e604e3499a52091880f60e67c7841ae35a7c7eced99d99bf9c87c70c72e6bb04059c96b1a777ec69f82800477d551c3e9816d978c197498b3e7b8770382431eea1b2e6a5dfaccfc3de945ed6ba313ae07a1647afff28b42c12bca23df1fdc9cca3363062db0e8dd08d3f26b19b45dae2cd0fbad617411af5e5466c3fed82cc7d21ce2a048c9c4f4ad3b9e78fe3bc02978cc1bfd092de80c08bb47a316f092f03139819646bbe44694ee6e5af448de64aef1b9d34926f277936f37d4b47639db2072f89514153fc62c6252bb5dfc9a5e0bc1e613ba764c491183e240ebf28db263e1d1ca6b5578b4314d1c2c3b35cfdf9131ed88015e27a71214ca7882138818851fd0ff11f76f4bb38922c48494f4537c46b63ddd80963a9ef9c92774a553b2a03042905412c7cda91564f1dc00de4100bd6fce8b63aab3e857b7228bf5720bc0fd4ea2a147aaf6a12b4597a24edfef19f9c8a037a700f9f629a6bd8670f8b8f662946becff547bd4fa799c1711f3b26066be0f5072698d937eba4c077260d31b0eef89aafb3f4307892eee769be14312f83f1681480047d1a6e0efb30ae97ce1aa1c27af2410329fee61d0ac052e80c8836da568791316e44f033decc76d78e5a83381a3cab7788ad8230a9f02509e56039872e1b31725e8e6fcdffa3abc3fab9292c93c1d5f49448b21ed483ba6bba2a4e03a5df2e012231c5be1fa52d685171cadac2e32144be09633ddfcfa90381d2c72f5e4488d56cdc991deb5c5a91d9b54858727af1f3bf3c3aa7db02b317fd38ef1cddcebc9195be677feee7b13a8e02b5684d2d492d3e00b91d9aa38846120810195e42712ab81e21e769a22b97504bc31f6cff869bffe0f8c1ca0a00b4e3007c3061b096442202fd89375d00327b5e5e73e81bee2dc3969fd5e04f235ece2a27177b54c0d8b3070b362433f0e1dd4811a7cc1ea2f4e2cdb43803c41b5d80946a5abe29003f6b34e681589d5172d1a11b6a69ca7dccbce279801b5ab4f12b2b1efe01618aea39c36193260cec3af87209f5b61a186040aff4fe4790140261d690e5328b28cc423e921898f952159edd98125a8025081ca6245eeb68e9cc5df13f9df54b1160fb402d1e47ed223f18284b2cebcd71473875b4655c8480184b0160ab952e333cad117f6467bee2e2450982817809803ea0e2beb3c3e24af8f354ece8c96bc60625148ef3d130e18e9f24dc77e00c4b804a7b864e65a22b96ef2f1c1843f15488213b8c47406ebfdf8a0731d70f68704a3bd38e36676cb20bacb61cd926ee420099590f5f02a62f8890949d922178ea4f8aa2f4c8d463cf9b4373c9e3c2f64a66e984991689d8a4d057300e4a177c1ddadbc24e864884d4ba2e53eb316260c3e9cd5f0900dd6f5fafb2ddcee7c1e9077e7854ee989accf70d37c0080c24ffd8470971f4297f804685289ea1a600be3fefaf6bbdc5f84d3e58e1c26e9580ab8223992bb8fff0a2f2b02d1ba13b4a164061c377569d9c4a77bb8bf99de13bb7a4e733da5b91dadc43637dc8fd0e361492c135ddff382dc95af8fbc4333cb292ecfa227a11b8a4aa73f93df94596632e8aba4547313b9b6cc37915c84bd2d4222478959cd88d8f8c23348dcbe4524c7f3bbb05b30216bed8e0d7c3ef57d2c012948ac762170c7110008a47d44bb04828a442db55dc2de3f1ec1d83da12d4030714717074468941facb522b18b06aa4888cc62d44b727e2e5eba82fe3d7b0e39990472295ae18295bf25fdfdd435661a68c6d6b184117069d26b1bc784466c60d5a6caffa241f872bf394576e906e357844f7b6e1acc33658f596093a8c908d0a46568e00fbca34185506e36c7ec3c7ed61f26eadd3284b490037c1c77a5f687dcf958a0845c2caa975c034a85cd9b5aa0d891492b7d9681a26dd2a429dcd6ce962a3adf37bae2e9448725d070859cb28e4bec4ddc983f997683b5ac44352aaa941089c3a7a8ec420919bb734643e81dcee402e4141544cf42d813621d13ffd5839cc6f4a19fb292232415eeb5fcdb4c750091a57d5599cef414c4ac64ab5900a0ce595eb025c5d874e53a9f3140b67d320ecfefc6e6b1791505b101579725f373885ba24cf2eb1897f6d8cb6cfcec676a2c1250f06a94eba42382728866b4d63cedf50f015262274ddb274467842454e2b80d426bd501d37f71fcc0b80b2a0009db33e1c6d2a00938b93209ce4b12f47c7ba46f260fce28a10d48d491acea8875eae60c5e5a7a2fc9b796615926e7c1e536ee1f116a0a623357a059afe7cf304a6b638c80dfc2d29d3646cf60129856a5185b22f533af39c8cded9aad971ed3614835cdde5687995cad8092e02b4f7dba78838e7cb66fb315cc20d2cd3fda2bd15a53b40c3ff4932f040bbc8a2b78f3d8357db140bdc4071c1758e5a1be41b99c3ebe7197d290fa9ce3dc36bb4356014234dc4bcada5ebbe2229e8fe5329d8245e3c38609ea40394e7d9434e750bc786662297a0080945b2bbb2096c75a0883894c493e5ff0da3c8a17fe6f9aef87449ac080aaa34d87128c42ce86daeee5b48f5f9ea3e4f2f924f3ef604d4be6a214e4f40d0a50f0255271e341992215e22ded8bd2dd1cb6a7bdd513bd060c6303e45206972727279c9ec8b6a753b56c6f0062dbbd77e5bd72d6f9c63c203cb501f06e1be0e4b701568be0fe5858dad85539866b69b742ab94f2b7dd717b5c5bbeee230f1c3ff2e202c9cfdbaf729773a0b1e8be4fd798fc50e739b63fae76482243c811973d3c71be065def90d031ce19028a6964ac380366012247165b5854506cc60730077bea26b4149e5fdddd54c1244f24052efd9d97e12842608d55b68cfe7a01e9c5b5c3889454bd580420f789a1c6622750a10b5702c0d6cf3827bcc027b9dd8aed88c4adbb97576c1280c21ba1072903b581319ea6a362c6fef7d7e04b4f65638eddb196130f656d7655c6d45677b037943ee1f1f5ae2e17d6dea9a067116c3fa612dd5f48f8969b077ff22d98c609f72b24b76399e2fe5a4c66f9e1494b07ada99480f2b918a9e4a5c2044d6d1965bca499f1460114bf856f7e93d96ffcf6b182ea8b1a31746227f10d78c046427e85089db3e0a9a96ff42347dbf2d85a9518e74b4ce708f87f8cac25d85109e2e2ea35f2a47dee43e67d409f04841a0c1178fd1097ce9b93a9ce9b81815efa18c98b94eae6acf2cc0239da33e34fe32d53c42618ea367156822254b4da0ec629750f4bc3052d23f69a164d566ece92f160e16c61beb09221ac50f758a7930d1f2dd36c504ec4660079dd03ff445e56ec8eb052a2185c34d96450a1debf0c968d295634392b294ea2e9a03fd67b6a33d82cdec2fe0729b37125b216a12a505651fe1ad68d7546bbc0001d7e8a25d7e67c80a1e72f1a15b925ddff91501686af1800b181a51ca0779b2815ef1d89deb4296d78e146510780b4bd0b8c00ff219a937be7c9516256c00ed3dbd7082d7d08bfca909cf1ac7ed26a59b8dda8812327ead849520f5720ca61fe7687b1897cc8bca41ecff590311a520fe4323245efe370bd9ea6e014484dc10e181d04075624e874e932c318926e61d38f460fae45b7002bd7901bcde28800398723d044e368c21d8b131771d557c5f962b9e9e4fbf80eb4a32bf2f9733e9947ff6a3ab770fcbf592abee82b6c1d07ff2408354e357e2cab1be25bfabf900ca0479776eb0d4a96a8f3e481ce8aec5f41af2ab7d807514e706255855841734e3c5a602b5ccd410652e0cca0ad5f82e9a0c5b36c32e897bf047f6a750f7333270bf334207ee0f4f6c3244198b9d02ec176fd128236ff6c16dcb9de35854b40cd8c405db80ff081d32e27194c5581037bbd530b135c534c15177aad35463335f4f504d1c02493b07e99d24c05b92ea310e1abbfca85ac6baa56000a5aaf3c918239f444253886c0f2dae2ba2918eab790febedc8e92127573dc5ea29ee1bf23bd81467d8a1e822218f483f7ad695e54b59b72cc665df4c4cdee4c69bdaa0b6f5122f2d76eefb4b0cd9881abe631c9131ce46cd1094c62f90c68aa16591749e8ea786942a6233ccbe307581aeea4d464a5dcf3e73f8464984e798ce4879b099c3d5971d1fadbe17eeef41efc6a10c75a977ab4fd8492d31ee12cc3cec3d69affde441ef80a57f7854dbe0599f7e58ea8d8a8dba79117271ad5384fd94328c5436710d83bcdd13bbab7bc713856a5f56febd9e4af33aa0eda684adf2b0ed62b9ed451ef9888afe71795f10c61fb606b5bf673274251814e5d3b945feae0fc9816629ee8a2bbe328bc24b835523d281faed3c41340ddc5114e76db12388b0ade5f6083528115f3a07b3151e9a6a24ce8b71a595ff9ea224fd1435870827e81488bd1209c73ea887d66984074cbeb64c2f114037fd768933a5f531261002dfb6ea3af2cded96c06777f99754b1c916cb6db285e93bc74d017cb11202d47b2d9b1724d177c4a3e0272393af4101896a50f216a1a1d92d3e56b812dd49515415991d073f08fbebd067f68048d1cbf1830729d653fa084222a520eeef2726496ce65d485074b2b12c6916e6b5b5d0fc6b2b1d3b1d368afa2f4ee157daa4925c1b0bb40800b1f5e13c0a38ffb599584a3d96e83908cbf40c61199ddeb7d2d5901ef8826968e068158af5c086a8b23d83a48442ac1fc1a27cda9a5584c83b214c0900bc0eb0aa4cf503d7a436cf18ec1bab98535e72943bb26416aa9fd1c9b8382652db452dde8f33b6d464e8a8b730d33b4e7ab2d8739500b141fe36afe1aab1f57024e67f40180e5d8c13c9b3e8145b664280354a653e1b0ea74df361b0dfad9c5d66cf536f0f789c624171bd36f36b1ba60c543d94c47e03136272dc51a271e65d754a2fe41277bb2b76636839cbfce6cf73fc2adc3d33983e50aff6c5e97b2b3a577e19ca9fda510a92ef0aeb66d737a95cf28e468ee15bb2ea15c9c7d0882218bb73921cfa851e819c81707feefd7df59d4cb3d5ff47ced582e457acb145f314f5f053282c4399477fdb1b2083fc3689de10104e8ad67b837751703e20ea1f41fd31d73dc9a31aefbae4166be6134a1a2fd8f95888635751919efbce21548c7d09dec4201ce3422f9b571caa845b58f17e96668530317ae453fe7eca0ac129047e7e19964615038eede3f0006fcedba5c5db475d385739c5c9dee924664d383c8ab3baa3cf6db394a0168f27f8c261a88f1fa8de346d69fae58bd2983de20ba0e533793dd5de80f4e4f9e24887a1795566619f45e30dbb843462990ec3f3dd98012271d33dba87d4bb438a9acc274168c527bbad499f44d47512cf98ffac93a273fb7fa654e2020ef064ea66636d4558179bafd5522baa106b7673491a0620b52f486c60eb1876e1ba071561cfd904657f592d00caa7bc34625af8aeda52e2796a29b3d81c30e819d964016ba102317fa520b53a2e169a30174ed70d2494c0d6b5194c468065654de36580225370ba6bd4e908f87db97deb4d7aef3cb5e7a46e11fb0edf432863447792970030e5c434c31935d8ae379942ac6b40c6c16f0c24cc9f25d8a6f92defc969323e71f43c74a7ac7a205fb704f0be676c1d8799b1be3c1885495635b31a6370e403f9e2a81a440eba3831395745f92740b57ae21a377da0d709bcfd2d9d4cc11b6dc7d22e92e99fd46d8a2ad383fd433b70b511e8a38f8b1959fbfe79009e09830eb87f3a885da7f6c1ef5e3aac2af2640559496ae4f0392988000442705b4c511315b835b76c1b2c8451d5d13161542688a8316b3067dc11dc5e3e8e2f82eaf3ad2bc0ed66617227299809170653b969317904dbb435360f40e18fc71d14c16476ac0f31ee50e72c90e6a4ea25a99b53d6114e1f9621bd463e0915d11c14dcc392d296f254f8b7ba5bfe0fcf9cd42fb5153b15577743b79dc387586e5044c3937bb5033d97632054c62eb0a262f2d2101a6fa1ca718716cc693e5ee3ac5c9c17c5061de1cb78245ac6427972587114acbf26e05218674e6cf0d3b30fea5afac23db7226c9e2088161bac1f97761c2e049eecda93f5292a42cef728d6508f08874c84632943babe90d8d8bf85f64c19558fc3d7fee5f3b91abb6bd3ac1842bf4942562341eb56f5cc1cb36aee554c5eb75fd7afb97c0aabd903e2396431271b36369f188e4f2c223775e0ffcbfe1d6aa020404e66033e8ae9540aa029de496f355fac16ca6c40a2e741fbc588c504705d2f170e71b2356c8b857984be814d003ba17afcb158ba9336f9301b537560e97315802e64d4593a6dcf503226be2a15be046b93878240556933cf980e3d8ec0284d0a4e60b80dcebf007ecb306105f4767a14fca3833d746ff7d62bfcfec08a79b9164631125fe2933bc6a404dc02475fb35c734300852a9dbe365cef44637049a48f37188baa767b1c08cc206696bf20394400c92770013d533a133843db37506b2d85c9e9545fa106454c364dacecb63b94e46d438209fa09ddecd0337789b5413ec87d374041b50efa93f2ed030adf517157ce9dc5f0d876d5943a593009f0ee78421ad55205646fa1b3ed312f0f10e15d39b741473c07e200eb27ac38212b361f6ca9dc6a79b62f99c4ef379ea89c34f81e05e1205500855d821ca17beb9135d7cd739d5e0cce940f1b3d08cff3a58030323dc2696b8833b05b4f8274275c8b1226a56e149537511e7e8e35c212d0d4776c660187a077afcd3d088ef03820b98b5108fef9743713d9f07c59fb31cab9b8ece1a6a0cfff5d16381cc080a8fbee9eaa07bb36b824ec1cbace6f8954a20ebea4539d48fd06d6354ce9bcec480a6292a37ddd355c10c6fac303a649d36b48c4bae21e93c79ad9032dd33c73fdd8890134364baf51eed9701e4f44d2b7006fa683953d8fc6fc8e8c015bd8ebafbaba44b483ebc68c81434da3a1e8c7be31d75b1553e93f56fb468a4a64b6c782f6d8c010fdfa986e1543da0fe66094ea912c5109fd5096f611958b1f5e6c7bc1c30bd5ef849b55f989bc4b7e6db019ab75f34bd7c61535dd331d9ce64d26f8a0d1abb21bde3a1c01ed9cbe0b915f301ea25e601b83f2cc7e43c37e24c5620c4cf06ff37a3569fcb9b77fb68012ba5a2c7576dfb64c937da127d0d30bde274029dcaa2d34d371a4466a633022130bd00816a7558e721d9b6a842daee193bd391c73a87fa3ff9c24034f6d8998eadefb30321b9c8f0299ebb729f5d2a6c30eff58bad69fe069ded4d7ca9a3374d97eb42e4e6682f9400f71b4b7a54b3ec6508fad275afb5f3a9e6c20d13a4643358420c6ba5da609c387c18c850a4f9676f599b21978db476336ef8ac5e1194947c12ca4d45271f41979b2c46a8845a715278675d068ee1db6ef47ce5927a904df8682611d9c8a426a85e30ca50f7101ca8cbb10f1cd450cb4acd6342d503ddbfd876d4e874fc8c587f0a83b4ef5673efc13ffba497b5d8d60806c81041506ad52445a24713a301a2860c15edf81f80ea95a1af5b27d0b37da363596473513bc1bc90c50c42d0888c1e0c07a8b48a97c27a5fcda09ab0aa281426f127b7a51c7c3bef6f5db6c63d25cd8fa64dc997406dac4c761a37ff27c1a0c3634255089e99ddc575f5944c5ba75868dd26110ea777d451dbe15ec2bc0dc013d2597db6ecf68103c836bed798f7ae0fe366ba11a20007d070b20febebf315862232072d717a86ece1f6120b9d03b87209d4173e5137a30b8144b921a5274047d1b50c584b581d8ebf2aa43e9d431b844f686d262157b5494bacd70b770b9067e9c5267d4299c66e26a9e1e80097b886c0812f4a1c37611c19e415c761e610de1ce5e3326da531cfa37d66a2aebc751b48f5186684f39a9faa3a82e2413e3e5c8ec23bf8ebb81631b92dc68e51d0001d2e2bb376435d87698086ed120c5389432b879c4d7a3f9f08ba3a66ad840973ec7fee32fb294ea237e9969c9198f8d78fec78b151d673450f91f8533018256d123644406da0156d30a42ac3d4e417ae443c24c1238d49eb7f0951331475b6960669dac25d2e3535f8b8247a8970487444e87c202f20caa97acc55ae96f9b07aa882c7b0f0f7bdcf8ef451b1313f0a8c3edd9f0ae2017656c8785573c6128e59823aa265cc6ad95a9435b5d6c1f644e490f086a408306a7ce352a26a0f282c46cbef0d600f488e066742f3d960d0484e1227f21d2a70b132728d65d4984a28d5f34cb19a098463606edc292ad0d0c48e35428ac66fbb518c5d8d4d108856e5f7728598a7f71e4e910ad32a7bb76721d1d11ac7de5bce2529658a1c6fe91838cffd1d0f5407652cfa8fefb7e2c8b7ace97a61cb04b4cf3c481b74a84ded1b9b29f077515f8025f3ae5ea1279100ea1b48ebf076ec12c692be4ee64b58bf504b6bd1ae098d283562eb95a4bcb051c8b540fae2a92ab8b4de707ac4b1e37999cfb1ddc3ba472fa39e8036e6a5490fbe40aeb13b4aaaed94c77890a5722848b648742752c5c83372768be145a24652e4d489b98d29fdfc18c2cbf0623650a234a0cc7640fb403b608848e75b8b7b6cc56406f98ccfe2191774a43d68c77c2d6c32d06d16b2849af2783573494b71843cfc413b42880e179217815f3987086984330e830959af84095cd0c071a2956bfc711f3e0a906a0faf73d6ab9fd2efd4c06c2155d461e4517d47b2417de36186c7a1a6d228fc7bb9548a26d648afc9be300b18ccc7817ea1cd4855699e3b34e16777dd41ced6b6f81c3a67fefab0283f4587e0662afacefba47264239080d9e7feaa8595cc68c7f1a1d8adb9579e5f19e6ad4d232bd04cc9e39fbeadeb2d9407f2571d667a6f7a3f91cfa69d2c1dae5ba7b0c226ec5698cdbf56e9277fc980234fbc28c38c5ed6e98f30ba18fea06166adec319de2f8cd6977a74401d60f9e2f1265b65fda2a47010c7f0a90db84e46a8cf5abbe5e9efcdb9f60464c981d56bd84b352298eade0df26c436368962988425d01c8bcf8cc7663c8041b5d659c53f1bfcf95516abed1c12b5e5ce59a84bcc33a5a7a085d49c96cfc5904535d52118ebe93d01a3c163ddd2aeca952ef1abdf4ea8ff9ed0b49bea90d50473323177133e0eb835530337f29ea6b897ac0abaea7fe405febd91ff4b605384dc7939a635c508c32277c61ab0d4ace857069737e5e39f1936b5fb40d6b2a1b65cfcdef4af5c2b919d9ac012a3512b2f5f4f5fa7e67245334c68fc5edf08be31d8e0cbefd6eb00fb6fcb762cdb006791ac7d18ffa0a007598a3f7c9fc8fb679add714265f5042c5449017ae73337c19818818de7304e30be96c85b73a0728aa24c24ff486ff49c2d49e9972c1a8d7684b7325a9b7088e3fff849d6dbf519ca0ea0da3c817d91146c2623615881811e53304f39c57d47d750751141c06a41432adf84cd7360ea5dc9945684cc18bf96e61b9107bc8af9ec8f31fe37d522eaa99a920c2d19d6e283eef98152565be0d6a84a2c39ebd542935aa096da9ea147376533324b5f4283a61164a1fa42dee436be456d4b226ebaf0ac50424ebace3b591456afb181f8b9f71192ac9ae1e0ec0e4d8a67973aad3caa988698a5eccaf7691cf70c78108a0f2a1f31e3673a30b6f9c06b4087c4d531491abe2510f32772879a4c51ec3d253e2e6df3b5f1642f3832553a15777fef83ad00ca265b1ca2fffb12a8a5971daa01e67feecabbbcf3ce1898a5f375a46876ebbab7a0e26142e7a712a5477d93d7b6cb24b33e0a564089b0dac45f7dc39ff328b3b60d6033d11350933108dbab24b5b0a9fe9532c0df5c85ef1bde89059b241dc6c818c6169907556247c9b1f6e81b2f42f1edade5c92531d2280a3e92e88d74d2654803a38eb6c068254f09ad55b6211edc6f29df67198c7603ca2d20de6723f043eebd762211caf74c940e0c740826a7e0ce48d641b4eda9480163b53fc9ac8dc3908b3fc93e08397b79ac6aa267bd55e1beb683f702348cf1bd5e4603b02435a90647b67d4f38062c0d4209c11840caf4f80ca6f935b4bd5e56d0a7d0884635210723f6d280c2a972eb1ac544e18a1dbe629c5e47398c95320fa0c841f3063489f5fc8dc63811a39ce24dc4ff38218eff2d1133a3a169451ee52dbba96bae11e887f51e9d49bcbeef55633de9bf6afb38124e638454c6b8f557430a23cf36a29f78369a55b17abb2860fb1540acaf56edc38e35e31ca5767a4d492746863c0b2b933405aeb89b143170b3a44ad4a5c05e53d3bea7908d6aa7c211153595263f08459a2865f84f11128d8d25f4bf9bfdb13b36712b319ff7af651a88785ff7afe0fb4a86abee64f471881a81580a248573c8180efa0461b5b10442b247c5306da23237c3aeca8da4336610ae973d0361a13dceacab1a686855172df6dc337ad316cb00a368943252e0e9847b313b354098b69efa89435053046f0c2a07b102a9c8151f68f695ca2b8debdbea506cba55a9dc5bcef09a2f31a2fa341afc58265fad571445a56a6df5ba8b33e4c4ca42672a615d59bf086a55297e8fc9b7ebac8a53db53256b915578834608eee0f0a9c0d84c40cdf2544da5e981050c95c3a496a5a2f02b93be9bdcbfa03194db4ba449e72aec4159b98795bd801b5ace93625a155af90deca25eb6bbd8b720558e43c088dc2742c37a3b2672bbdf612fca783fe5d1abe59e3fef208e085c048edbda89e434b4e3ab927987f955c8dbe1e8bc110c6679a1c6e7face6b6fc8f8b609dd21c12063d3a5f160150ce6b88dc00c102aa7c00c681009e1147e432c395e086fbb08704928e98d110ae8f9994c423f19f2fbb7091394e091f8652fbcd7baea800097485282c249b63a32fb81b64e595c66fe2c15f6c271df746f9079cf3cb6eecf85d0d6d9d05dbb66c4abcd9c308406634d658fa722ac4a033a4a1e785a304e4a4e07bbfeff03cc58ad44e9324ccc88960ff89e1790b30c3dc539d7d825228e8aaaf2f2cbd687ac8f3f40bb0a184f0b5401742b65987d29fd1992572fe76f2070f938b82f45bbe979bdfa5816f2a8edb626b79432a52403970729079e071f553fab573be13e547d0da5931aa4dff3c6caeb439f4b6a271d73253a1583e2ad2ac00d9c18146f8c430a70332782f186322ee7735d30b0b07d2d9d473aada344ed469ff91cf93ecf049c08e1393229fcf3465b114b6ed7dece8db6228c5c3a0127567826e0c44ab41521e4f24b1585e857a3507c5815cb3abac8ebb812638c14836a114706bc821b6bae2f568a189f93c418053a287e6d62a3b8a6443146dc1d6b6ca8e3461a5c5c3fd645c38b8d1faf0fd8600477346175dcf82670128742074b901a8cafa4032018297ebf601c159f6df1b9169f9b64ad6a319d6d83dd629e9f0af2fe98d75f02f9935ad42b00f97e340863ca865f347f84f9e08481c0830253476c8a5b641c65373fe4dc49e6ce079accccfdb9ec92edfffba3877ce89729f258d3b4dca0a2705a2206998c206e80c288cdac0828d97cd87c22afc28a468011f13c43c6c6a7373ab549f2bcb05e1b22ec6aaa8d9495795343ab755557b59689c14574a452ddc0c4b0c38dd22d0bcd02bdf56aadd6556b130b09cbdde8d466881bc2ba2c76dee8d44649872090f8d39eeddefd523adf46e2e9d9968bb69ccdceda21bf7b36c8be4303b888ad882dda1050c4061485fabb8180a08432f675f72092f985cea7c9c6077cf9f2e5004e5f984a1781985b56caefc745b9593b9ef07c8140f27bc63a514a5815976c73c34a00376cb169721d0b9b34ae9e5dc943d731deb885a9e6eddd354c5fb6fc956d74b6b57a932e32c0c6e74be95306f48cee0039881f5058c3cab34b53b0626574ff49fd65e3cb9bc1c60fab67f9703edb7097ad5ce5a4bb752a315abb13e5906cb0df48753be7754c2a381c1728388e092e356eb500a92fb2c079a2868c942635c8c288c4060b345c7c101275240b6394d3ed88db5237206e4960605c88ba8ba0e0a1d8dc5db9eeeee76253ea725dfaf3fb1a5f58afc7e86c3aa21eaaf3b95f75f33523285f2502ae9f8c42923e8312c8a5cfd4d5af7ab1ac7b7d3168fe4a0077feff001a70fd995ae08bdc3a1c85e64e74590f2238bf00255c7f56bd62d09cd20307d897c7bcb97bc41a05c2d6222a23eced6888853169644e5a2aacea46a7db90dbf560e3d8b9c30d89d02871838d4d1921968248e93247088dc919229058f3c6ba766e745a73e6b26e745a03e68660940b48f024b941a4630d169e99a443c21585a4dda995d17431c6bc297d559807c56ffa4989668903ae900983e50b0e462c2d0932248a8b0c608eb268f1a6998ca2f4d4814ee9378874443051b008e304931a0c48d658e9a9034f14331cb1e60531489864f546a73554b0a83502495061e64b1422a46052e256c04d255dbe1061459a327374605202091c2553cd446726410107850a0884214920b18648134fbc90e1c8ea0434244f5f6e4b38718491234a68e55aaea9e176373aada1a179d96e1c24b1521dd49f82e759ff4c79439ec9990d2856eaf6ef58b2a12bfc312fcc67cee73b3fb08325b2fb19a99f67fd4c637abdea0e9128a9a4723a11acf3765c443adfe7d5da59fbc5c8ae8a41fcf18df216b6354839aac10e9604e04a0e28c0b2a40555684e054e116bce4c19a10649237950116b7e7dd4a0ff8e1136e428d01f8ad092fdeb2f6426ca63309fb20d9a90c4869e8d28f66fc84a3cdcdf956491948e6ab5a1eb1f8c1d7f18ec60afc070bb7c6337611b1945a89a95cb7da12bd6068b7a28da88428e028f06fd6fcc60c37aeb21f97f276b073395cccc2ffaf1f50116ee07f8ab43ac106c83267490bf98a532b52630d627f26f80070a2c3d77b9accdd681c3ba2e736af2c2cdc256c161bd6198e5858dcfdde8a466cb125dc76895cf5d3d88717447281dab77cd5f146a568d42fd7ebd827149cfb32d971a2c44b8e639a959c1113720cc10070423465eabf35a3f1e6562a5f4c3bca9e1a16bc1f2dce8a4e628891655e85363b256ae7a102ceceefebabb1d49acd5afcf69094287b276b8cca28adb3fab125380110346079a2582d0a4b9a2092c9a60f1459a2f773e511653b270a7a92e3c698b135c0df3f59938535ece50b9dd2a2a9d7f04e28f92a5fcc4d8f8f546a7334d2e17ce065b6f7442220314e346a72448c8993f7f5028740c850ee297929a9abadd0827c2991d45edd8020805a2a2a2a2a2a24c689083f893d674b1876214d777c487a2a58859b83648b9d97447443418cfc0f02b0a5fd81f6f0f1b3c58fe28c7d6774929a5548a4287055317dc500715446480444a0719635aa031664c8b8c129f192d891771283d649fdf7fe0e1f71a9bcbcee4b6cb3dcfef65607ce8696ed7e90cd2f53897a55412e343e9e4f2c75042b9cc0c67a6b4c4537c4b826293f2230fbde94649bbecdd181f5db831627c3533c58df12dd68e187688bbad87c1dad19230aca072617c0f6b078c180bb29ee761ede8a9dee5f9d6e5b93c2f7be883cb43e67679ca287179aca8e1f29059c1e579cbdac1f3f677583bec8ece0d5b77a7e9ee5471c4dd2133c3ddd9c2d5c498244f4851912a2ab610b1408ecdc10229574a1b53c8b92d59e9c6609e37f6e94f14d612027110c6e84b9829ee1413839829a610e2c29a7081a102004f6a5c53829932e7e492c39cd20037f4bebcf9a2e476532f3a4ee98280af6360030df66701a2c88d59a4c4b17163162950b7c83de9ee719df79d74ef1511002539d66c4651ba34d214421a79c38d4e5da4ae931727b7d90a474590d799e55f6316034054e1d26b54d3871004c3449919ba7881d6021844c66cf1c5cc911358210b63142d42bafd55caf5aeeec6a717647045552d5d83159dfa714a6cb623e240d5ce88a9a1ccca891ad4d8d9c30e1c8a2063060b1a6a51d0291d46a4c375db3ebd6082da73e3930bb7ebddf8e442199a021b85ea7792a5cb552b8c721c477934c80fbeeb095b1c7777b96aedeeee15c85ac17eaebdbfbf5a5dae7eeeebfef9f5bbbb0ff076c7d0ea21f935a67bb7adf496bcc09deff229953e5ed23d96cd97a5eeafe95dff7cbcee941f1692a5df68b07ad0ebcef9ea31a7f5e016a937e25429c202a2104b97ab562ae79c5fbf9bf5e5cdaed5e59a5fe7fc6451839e7c3abf5aebfdc00af5aa5ed58354f87c80d7bfa622b8e7e694523e27a594936b59d70f14b1655dcaebd5659518dc1ab7a83f02b90cc2cacad518ad03a8d950de1e929ef44f36f8d3ddf22c061700b7a8ed0d727e12366543795dcaeb555ef9faf1f83e3ce8cfb8aa4bd3c4b9ea8eacfaa1eac3b0d6bafa42f0aa54aa4ec5b79b7332a5ee2ebbee65f7450fb261a46d6f6f672929a594a33f0db28bd2293f15bcfb634e203ac77cb641e99c94523ae79cf4656dfd19aaeaf51887288dfb6376e1d21d03309e6c949e853f3333ffb8ac27bbe59dde0c5dd7bf8891be627d58f7e10737aab9f5c8a5cf57eeeaabf70945e0521983aa77ebf317feb8f419acf49d999999329dac12b8cb558e525b55602565eae27bcccac9f3fc4ceb3efca0be8b5760283acc4b5798fb22f731762aa694aa2853ea5cdcd161ad56cfe3adbafefe1556e195eb7db873dbfba2f73cb9157cf5c1517d70e80787fba87dade041fdb5391a696cc4330f8e6cfc4e880b6e7ccee0c62f5ccd29a794cdad3be59c73e5f4c6771bb36ce5a01fba38165737f6dcc87df8dd48e3468eda06a5af9c73b08dbea1bd9c235a6b7b28fe18f0dbd5c18511c1fe1068c836d8ce01dbe85cf2c1fb5e04a594cfc1fc6695f0ac1d3282fc0e833188207fbfcb43f04900bad2f5651ae9e247a01dfe5d14eaef1f20988e117eca782d3d76d6891771c48732b3504929b5d511275543f11a62cb9b34337019f28516cf892354e83439011c24b2dca67803c584347ac2a4c6d8798ddc17ba62fc1f7355e75ccd39fdcaef31a5ad3e555beda93ea029d6eb181441202e6c4fe9e473ec39552ad5bb9cafcab4011f3d4394112182fddd4996314a1dfa45cdacda3a3b2a150c54bdf7ea56205011dae3e817a390fc3c462e486deaa40bcbbaf1c9c88633f6c90849f395917b332ee5a453ba198e1a31a5735277fa9452779752bacc74ccd5e7a8648ea24056e94ae2d760ff297b4a970dc629566ea689155c21757c87ee39c70ad6bcf1c9c8c8ea091f7ac6d61b9f8c86dcd03e19b5609b58eec627215ec45a1108232c404817b7bf5a97e5b9f149c81418d5c66f7c1212d53e373e0919c2bbf149481167a500c66270e39310a4285b728f4ef8e3f62b610db16ec4104228b0310b134937ccc274b33081948529eaf64cd6233ecff6289b1f8da8610eca9f2f2ed25cb2f9e27ebee88d342b9befac10b81b3ffaa255d9fce6c83221d61a4ee7450b4c4ae7142c9732117411e82545047716cb5480cd6169c962e360b684063333d7dfd54295ebff44ae3f99800cac133386cbdc18cf3cb1e4d2078152eb51ea5ca4189aa3c39c3672ce5017ede2524ae99b8042c72c06e6e7c978ab9c242c1c8ecaea7100b433934305d672a40c611811ec0651085aa0682147c98fabca5833a2ca81a106db1773429062c983627dc241492284eb46a7253af4ddb18699637c216294bf3cc618dd99741c633002b47284b103b0f98db08735d195deec3a30182ce288eda6232282c1408e39c6586e4119ebf40599af5f68b195d9fd274e0f57479c31d7dff5850f1fa412e18018aa843912450f4a67e864a2e388a726988620ad40ce0d221d1cd3c860658d4ed86b01104cb4408b6b5560430f081c73fb65bfd7564483c54919db1b2f698e8eb09960063169d41c0184ac270fb79f3872db6b49185336048ab18caf17526edcf9dd6a424287bd96675b432cbbb174133774dc8e4c71cb16729c78c3c41b286eff7381c3ed07b92873fb6129b8fd444570b6dcfe119844a72eb2b8dddc94d317b7eed25063c31f737e64d1eb4014fc9e898d3f3fa12ad5e3ffc8d612183f11ff4f516e557926d0c31690fe3748ffa741fa320ec5abfa4a6f64dd1a33eb6e1aa40ea741eab72844a5cd83329863a5cd632da35aae0a7c29eda48ec528a428ad359415dbb32dd4dc1e6f0b319775756e270b89a4f3114dea213abda31bb6926ef8e37399f945f0cb37887eac0084465f47c73aa98398441c337412e7e0226c63488cb59e1281b0075d6f5da1ed263136e36947b9e0c39e72691b71692f71693fc198f2d88c8f8f3c88be4be7c397f1b9bcf27c21c8f330be50e8863cd5f385de0b496cc4399a8768833efd72e9f37ca190fdc2de7269435dfa3a5ff8cd74e97b5fe8fae968ab3feee5b793a2107d1987bcd856d5a9bcca5a3df7e2a041faddca53b156dfafcb3dd820fd400536fcb9f46915ea32151a62ac0e1183f8992ebfcce1b252839cc62a29d91bbdb0a1b15ad0c6d61bfa2d7ab9dd426063e58d5e6e696e5895eeca633edc4799ea6d75b96aeda692c76a103188bfcad295da652c97953c16654b77d66653558a423ec00ea6d2accda63965ed608a5aab4d55a92e49d60358a6ea227df5e8fa4eeb53fa22f8d3fe10f0a5742e4d2a0dc6a9f44267ec173294cb4dbb4f540f2221a922abbeaad4d5a23a5b57eb9a9c757441112fc93e4f8b6895e441f2e7c77801d1612507199018cf022582265b2579ac4b527d21118d6f7d216c46cf17be8ca65fd2951f0c747de1afa4eeb74af218118c2f2482f17c210cecf942d0d5257549577e046c940591d10f23ad9bcfb31b6f389fce9a2e1029f38b5188c3caf33d5fc8b7e7574811078cb74166b3c8b9970ff73cbbdcc37885f4fbc1ddd6d76307f77d20ceb9f443c05dfa13c6abe8d208d8288b320b846732d59107c9973cbbf543fa56c7e5817712cd2fa46f69cf8be77be25fd435ca63f10aa32ea0e6d8c0c5912699fc6af398fc2ae531f975ca63f2ebcd6352be6ae631f92a9ac76298db9426342481a3441732f9aa23b7af14ba586ee1c69d2fac3a5f68595fe8baf5c1d55765916502258236a344d08024608933b2fe7c4e28418cef8fb228e3b62461ab2daa41024845dd27fe315e406a4cc1822e321662fc05329a64313e211298e98469218ecce784068201263ca440d69f0f0fa320321f1e9107902032ff7c7818c9f8193e3c5cbf52e3054a881db63892cd6434c97c4e70202b3029ea181ad0e1899bac3fca7cbe41d9c115351efee2e141f267b83e195f581760c446599401f911c50726ebe00afb3ce4a320bf48fe08928b0917bc3a2eb2182f1a55087124f39278dace1c369f034adda9bf9a73491dc72b0af5108da3864a5346cc16a5a55a13d2ad06bedd647cb1337374caeb79cd36a6eca9a906b9993a88f9cb88e1b0424181a2a4b454e3b8cad1a9525dfaa6d3e0c2d8467cbe7ef9f3212194970370f9dbf93e3aa5cf395b04d27d004e96e5fc504af92c9d03a006230e599b39a7524e29a93be71d5f5128fe74295db2b7810d96dddd57aacad129573d4eb85d4ed54bca393847fdb9e21db8f6224e8be31bdcd04f396e831b2c739556d554adbc96d3d8463b8d73c4dbabce3bcf697ee4489ee4b170f0377f0820c23aed9de634a7396dc5059571fb69389df5063558fed069ab956aa5e334a7d1228e586f3d4874fc9d4ffc20774783dbedf4ed763a8bdbedbc6e5735d0c5186374f9a1bb47f91c859c6bea53baccd1cdcd365c36e76d60438d1cd9dddda3bbbbaa3d19fa3be72e95b75ffd720de46b6ac079f11576163736f88a2a36d3797556e726a592cea9aa9c06773e57e0fa73955fa9aad65a29e56f28052bb66f77c5a3fa0648a4a494ce545760b75679c46167d15d4ae9527293523ab9e61cb17563b32063cc7a5f69ed74efaa5f8e3898d93fc07398fb02408df5bfc995378387d9537532d460c4861bc26a0f56e7c62723435870ce1869a163b29c1750b4e1aad8d514376706a995125a584b58d68d4f33345144b5d576b57ab6956648add6ab4a24adaa8881bb42536931428f7072c40fd53a3161950826424d8933a28814e10838548988c32a11ecc664065b3d9b84511245da2a79e18a0d094d842b4a6f9358796284fbc1eedce8f464568d6c85d379c106ca522cb8247c28e3b900468c0f512b3956dee8e403d40d221d9cc18d4e29a0e243a7f1990ed1102af0181736f47e6ca071dd6b4b12816546856ab39909d2f4541c8a65ca8811b3a5a1a0ae7f33c5588be94ee2870225742dd56ee8e2a31bf2d1974217cb4737cd4da18beda9fb54448bdb3335ae2b7f7a46c4315f3e8d113847bf7c05700e57c451afbc6164e220ce1f1b39d877dd8862e387ae334f44dcdc7eeea7458c2e7ddee96c8ff9cc2ebb841184f3ce9f2cc9de834968225de7ea211f123e1f127c5e6f19d145b662e3139132977bf9d3f6a0df9f2da16ffc199b5542973082705ec997afa45f28e3d7437e3e24b4d7c6d275d3e7940298758d26270906247a5afa8b48134b4925a593e8c63120e160c3410b22513d74caf84424e90987a8d96cd6c2bc2109ae7cfe7c4890ef0cf871b19131c69f9633f31166a418168c4887d7f256373ec140c5ab51274c67b6904b589e050c192b6f909420c34314cb8311aff943144958e1059a2bb3283c30f1c414955b4153b954373ec1b0c415d5f9d031dd88345d91831210495aa497007894299a30496202324ce64c45216752ade361888e4c92a37222e949ae8a4018610115862312861b5cef7aa2c9b9f2c6279a17aea8ee4a5d797da2a1a1a1d5a09744f3a058db4881402deb79ad1fefa6e3c4f2dcf844b33dd1a08039a1d51863951ea368e8e22dc14bb8f4e3084ada7df906117c690367ca93244af410050268982cb9b14521cd74d4b80372a4cc388963648a9099020f3461a58a175b2cb1218b0c5fb2386a294e9852a68a27495394e430511004e9c88a23cc58a142cc16185837782828429bc98616a41336b8205b8b97da583416dd533453ed052180e8b8ca8d8cd41f5e89b5f0839794f2f51ed060f95d081bc5008621cc2c39d2029b1ab6786236f9a0a810e50d95255cc802871fe8947e834887d7f25ee0c1aba9a0e32895afd7df1ed3c7ebcaaec2840faa13a8a60f1a2cf9a10d933654d08491b3720209ad673ea1401a232544ac0891d2504685f185d5f67ca1e5f942579f1972fd2f78795407b943d9f9c277b93c6e929472ab157528efe650d5a1faccf577281e9347ef72590be5aebae6754da76b3b5db31ff21c6b2955ad388e53712b8e6bbba3e3ad62b0565ca792471e934b95e70f8ebbbb9b5b7294f26de94397754e2e5de70bb45e72c983dc996f0d7a936492b5063de49b5cbab11b8623c5d31754d1b42ed21ef8b1020d24a97ae2d5223774a3eb61234192481de4dff19cb1d65a6be5b85a5fd6d5279134e81c07c900c07491571fc579f9cce1d890e35cff304ecf8c82f8d25ebaf9cbed8813a71b1877f79e02e35fdcdd419bbb7b83e959ddf5795fdcdd3dd6e4174ea25372788293e6d3963f9865dbdcdd9b8bbb7b83a1b6b675777f691bac6dd3871f39e1e5051f7ee460dcddbd9d4bdfbacc0d4cfa26a59492caffc12c058fe131b20926a860e128f9a6862f1c65836259894a03656b2fdd42b7e0725a987181f978f978d510724b420b2c460ab8448149ada294ed0708cb911e7cfc74a9de856967c812553051a69767b3999628cfcc941344d95a04c801ea4c4b76971b306c5090b9f1355f1232303284e9eb129b74942cb569b2f9e0400613372ae0c079e65eaa77cf66b3d98ff602ce80324305f4e1924d2ded227f485b2745114836db0fae72f3c7d4c143636aa2a38b941fa5b39855c20c283353e4e56e1a2974b1fcf1f63b730c01f7483133f30db6ccdcfcdcdddddc13c5ccec35a82eeac8d40d5d47acb065be21bd9f99398339967fc9637d7928fc49c18a9dcd34b20613cbddf8cf57a58a55f5f5f501166ead3598585a8389adc1c4fac38ab0a12f71f3adb5f97e35a290bfc7583d449b228ed53b177276eb628a8d141adb98a82fd7bb498aeb2f8be874cd83fc43c7c200d5d3874094794f9fbdead5972e54c58e5074e3c9020922f3de63da8b8d8a6a70b8607343333546ea8b4d8aa8a6eb4e66d7df8943f11f5ca9872815a38ed5f6197b7b17d96006bbe431ef5d7e91c7a26fc063acf7da7d2efebe468d1a356a5c07fb55af9e19c164528744a7427ff72b46232c1f7154cc9f7f048fc967368a353ec23159acf151acf151acf151acf151acf151acf15151e5e841f13ff6ac83e2532d5c2873e6726c581fd1a4a410534af95ee84d224a79705f000ff2c1c70565a4f4966cd0b6e83b8d3c6107ee943c3cd7461cd1eba1187dae0f09e1bc31c68d9f8f9677d1c5558cd50e8ab6e7f6dca266e6001ba9ebdd5555bf63ce008d9556644d5a514135a85231775dd7755d77c7bcfab65c476375fcfbe51746840d5b2a84216c6859ca97e47be850508842fefe491e780e411ebc8266bc7866449b920ef2964a2106794b5d8771c54ea959a687a67a887b9f3f2463441ec41425e5b6ebbeea3e9f137680942076017af53fe4ed0657af273e26ec7cd7aceed1b10826ec7ccf4360e77b7ec8db7d61aff8d561a0417f14c4d830da747ee777be121475b13a1f651d4ea9160cb6691493f7ac8f2c08f83c80653d6f3fb220603f9f07b06ce73dc89b1aec91561af4e779cd290ff267bde6ed459b6854832e99ae77ef7c73014e2c95b9e4a375a11a7c9b982d52ab59a6419f5353aa41ef19c2aa3e9c52d77ffe40a9b81e6faa9733f590bf37f550d8b3abf3fe34fc89faa778542a3b03caac690d366d248d44a5baee39d26fac78e1c209738c31b21785fa6978f1828abcd18b174a6fb47883c18d5edc2c69ddf8f4025317bdd83c5bb800513f2c3113db3ad6329a94142933d043ed3caf787b5e3c2f593b78deeb1181837185ddf9f83a8f815abbf6982582fd1ecd7d2980a1dc7bfd623df762bd7392c7663cc7f8c2dafa420be34b8a41aa6715cf222b04fbaa9e22ef91dfd9977fbcaa679fdf79f9d48f977e1496f531948f931a74d22073121bf18c691d00c133feea2db161b52deb9c0fc7f51033cfcb34cc2ef316fee132f77033d762d8c8590c68369a91c0d12ef79167023d886930de10b0cf0918c8d00392a4994cc6cbf85890f132de0046b5db710630aa5d7f0318d52efbf7646600a39a8c05199f14fa52b80f7265bca4d0bff4f311009a035ab704dee1f6f744c633eb046e92c93841c65ff0177c2570bd8cef828f32679920e35da08ccfe541323ab802944134c2052f1ecccf4abcc4490ca5e399400f454d811e8a7f8bd1360d0b39b2e24856dfe517b6bbbbbbf44944e316c55ba2bb17f3918202d543f1e968899798a97f4a9f3204893848f0398104aaafeed5955cf54db399ea832716043ff0c182a0c74aa08aa9be1f4634e433a514b7bf9d046febe4f6d71709549f8f777024be605bd6f5acc44bce506eac2d7e4c9e24fc6c366b2d5d040a5947b5688d0d6b104a11077d1b96a82b97bba62a97bf436a70c7d3d1ec2259ea21a51e8a4f466e547aa8addc340d2a3538a9f8844943a5b62b0d06443aa9ab7535aeab819ce4645b49099d54a920796c2a4d246fa506b90337b62e35a8d4e00d276ce8533eb12ad51cc983aae4a6cb7de1bc1cdf2e72ae66f3aad445b9aa6bbafc0730b2306e7c3a3ae23bbb61a57200176cd8d55834560c1107f7dc74c3ee5e5e854bb10d7ebf451c53290a1d451c6c626c0611839887279c4a019ed7a8e4cd76453d08d194080000040053150000280c0a8803028148281eecb2ec1e14800d74943e6e50329807834990a2280a628c3186180008004419420c414e8d19002b6ffe96dd366308b7e0542bea00911b6f4a9d2a721caad2a02ca8931ab28a17b8520b958855a51a0c0889dbc7cc05e52407378edea7700f5446d8dcf6726242147f173f4bb72710a0783875a5618fa06553a6e9e68cb8e1f95ffc13e0de5152efb9bc48b703294ca44718f9804289730af3561d31f6fafca85f049a979ccea4130470a8a72384226c83519a9379ff962613dffba8cb0032a9cb871582288843a64b71d6edbbed61c90cd2715a32029dab2dc14581a71d2b4a7286949ced4d7d98be86bc8c23ffc36c53c62182ac190120921218a0cb3ed553f38863f9434c34ccd0f3d7595ac5a0666d61c6a709ae25161145478eea5fcff02ef99b443d8de2450477c089a62f1edfd76d7701433ea3ad3c509851d5c013dc3a32c52125149fbf27d4b8aa0be73fa23b9cfc028b781089a51e3913d89fc790732c1a0633fc4e839164b4032f797cf40a34e5ce31402f279d8b6d85e32d6a68efc00c8b4ba1896fb669801ab1e07a917f99a91a64ff4fc8bd73d3e863fa4de335c7c7856f14737f8892cfdea535c5b7e7b528b7bf6472ad1e8eb37813fe995957a41a0ededae4f8f5103446e05e1415508f0f7f5cd703554246ee3bf1b278192ef728ff5e81472febaa9d8882a77661e77dbe3d688772ec01808f280bc40497581e20431f67ca5361589f252e0c21845b97f13e8bd521d563471d94c1a2d7d3074a11151f1e714731a0bdb7e0eb2d9c9dc45d584bbea2c09a138f356efa38b0c3e07dd65e5e383154f13076a99d6fb55f75e0b650dc4c5a8a8b260b3243f44c42e2686edd49d8194ca63913d8e71a540bb4b7d5015fce312d4658e80bd78cafe86e56b9ae7731dc50eecb28d7edf8cbb20711d19a4bf691b8b705bf967c9ba8749d896c6a0ea87b93e7a55e927b1b4424c3c29d96da881ac72d2b9ebb65ed00e3f6ab218921582f92c9a32ee0735b83dbfe89543c030831f3d92c9bdd7c477934f280cb05e435c823f88c35cd6b7bbca76302be556261cb4078f1e1bf0e4abf4b155d0648d7db4ea2106ea3ba418896c60d3e7d2fce39ba77e825737d33755ca203a3160f504e5e735129f919ab7eecdcb56eee67ce26753c40b4205f594098c2d3df2aca420e8c8b8df2888642939e068dbdf39e5f1b1c7330102303f92ee3448712bce11bb49a879b1776bf52190788f8b50322049a34a57791f558e96a94c7453be9e2ab28c0aae630108752be724c1919104d993cbf3a29232773f75059d444ab3bfd545b86b8d3e5b350a6efe2b953dec4a7adc7d5b58f345aa412293082d8a1c9aaf5570e48abf28e3f87260d57b332cd1f75bbc08646ce8a82c89674a99101115eed65e3060a6441b81e503ecfa54fdd18363bd2e43876c9ca70166fed2d5f0f2c67a81b9fe2e749863fa44db694159e1e56569c09ed311411753577dcb968140b24a64192287ba961f95cf64ac458840f52bd7c5339434ad5ad45f3b13982e128a338fca3c827221ac96237181bd7fc7894167b24ac751725b652c7526e0d6bc279e38014b34550636ae4765802ac6f113e342b8b89b4356cf22116dbd8b107223840929557f5583a642d597c70b4fa8f32b455113057f7c5d8e31b530fdf2d3fd6b61e0a0e2574899465a0b688a36e7bea870995e043c56a6a4da97f54eceeb13eb389445dcdcde6a606158159c9034ae0160e5062639af61db38ba6a3486cb39305d9e4466ff473dad28e2532fadf231b916e75030242106c79ed00265bde556f67caf2cd2de85cbf527c90ad8bcf322a854384e159b29ef225c55aa9bfa25b8f83a7157fb682fbda26d27f6c655496a9f594f350f0a05a9267b54514a9db7cda94d553e44013c7bc80e37e82584736b50bf2654956ba640e7007aeb6b3e7db161a89f3fc1a973fb105a28f45faebbb3302a286b8108423d79b19d96231001a8f91d5214eeb7a9b1db703209e18456287fc457b10b940dc810e98624a37355296d0be7caf41a0f1edd5f74bcc21c2398b6479cd7078bb3230cb419d1165418d1304dbe386ddd61f996cdbc061a4c41cb4b1934fc500a8cb3ec2042b1b53be17d325e628e6289a0809022e0687d6a5a2e9ee5e5619cfe96a0f46c9eae1428d122c1915c51cb80f2e7e89485834ea09554cdf522a186b7fdde65a8a92b55ed219d3367a010c1ccc054e9e23a959943b7b73cf6b32f80229845f95dd9d7ee4da322917fb543a630c675b3d3f5b70d4328631350d1c3b89b467e5d9843d9dc6d813034ae5b74dfaec2e2da651d8b1cd4016da9d010d3ccf682f9d3868403d52ce689a182ece2f87e30c0ddb8fe3e71ec17a1f31d3783877d6e02cca69c77fe1f38d77e079d210b44a9bfa18a7fe7d8e18381d51e1ef126b6f843a5291095d4f978a1a64716b30d85f6af528fbf2fa3c76087d371ad84cd9331e1bb8759536ee6d5466605ff61b52a21b7722cb84f737816f153b696509458c07058015e910763af3de3c44e2c12e475e19e3a2b8cca0643bcb9fe9355de035c09e7a96316331c27208b8c4024f12d41187722ae264467e9c07a054ab6451a82c8242602af397031754fb09afd78eb5b4ee5d49a1271f0273d40ed39abf6a67c3ce32149a181226716ec741dc6acfa4d928038c67a0bec1eb219e13b7640b17723ab02f14906a988d43cab1449977bc181a98012cfb445a801fa77b98e5e800b81f472fa89547c18c9e8e1f39f64767d09073f9972b1b19b6146792e418756b8249d941708a494b2010553f04220a5a4ce8362870e3a9ffe068a631a2a60b2cfd1ccc0ffc88ef9d0177fe79a73569a01c8e9fca29ff09c391b27690f0744b20088243894d5a71549553ac5e15c503c170625e60ab9ce6360ff19513006234e41daae9d0875b41366cdfa7b979b428644e353ab3c3f246d1644633c2db4eba3e852c4aed1a7acfd287ad0f79f01207896f8f442f7f3a8fc23ddc76ee71429aa4a11c1cc16a1f5e551164f6aa204f2283debb9eebd85d3d3a7cd37c163bac559ef50e85b252e3e6287b308b0c3dd038897293d2a9268f2e9993389475e4afc45b1cb231248f5823356e50901049d5fe82a8e19d36cf40bb155344ec4d8e15dcfbb0a5951bb8adb16e3cee0c7d663c83dad3b53c2a6bdd7f698a541ba6e353b4c5d36835143ffd3d0d58f59d79075b18cff7e13db86d12d0c2e1a75a70eebc206ced5f21af8f82682aa45fcd5d32fae54501b1a13c99d2991f8bf76d5908927f35bd3b245b09f9a1dce48071a9437fd557568600bfe9437cf97b5dfef6f8cfa76683741bad84d5c0a34b74bd6648cd7c3a42d9529b782add61bb6c5c04f05b5ef39d41e3e0f9cf8d7b0f7891d8015c38b7ff951e9af614bb2ce51bcaeb058d0228790922a39f5db685162891582da6a79e95e38c9c6a94b8cfa21581cb8849d8b253ef64be50387666d753a1a96f007040b4eb52a4b10f0e75deea8ea7468a322e57887c818367423a6542ea2eb4d08afcb8e173ebea1c14eef57881a6ce796537e4b45d60390dc9d73f4a5b66cbda214b26b3792dde1c64b74dcd55934a41d2d42eb12ec24b5bb37bc72ee4ae1646e109fc43367183b2c2f967974f96b8ebad1f0ad020d94129c41db8ae055acf85f334cfaa571ce61780ef09af57b875831f485cf1708e4ef8d1befd9055ab509cd96623a6df7ce5ee901d44177cb0cc0f433c9098d680029db5402675a29b9504f58f6a8603457530be70f40ad26c6b5a13314bfcd344dcdced5327022d133bccc9859480f09375c2a1f12c9f5e8afe45a5f4362fb985c4c2939a288d7f992e8e36f0221028c2a09666264fe8ea004e48167fdd932800fe915258d0249441c61471808f0ba7b830e3943fc5e905daa2379d4f0582963fe4802b4661fb1ca14092a8335d26e40289ad81a43707cadcbe3a6ad0a0f0f352a482186628c13065df25b73d28986130a1d35733f9510d57fe540be232c23de91fb76db2ba4f85d456c2487080604f74e3fddd7c955e1f5353f41a30ecaa3a6bd8126b29605f749178a290b94548b35c0af93110ed3cbc5bbb4870115b6af7f7bf4a768be2de97ab3951aee9fdb78bc615deb5b10b792872aa74074c286e20e33f901d33c03e9305d17698040e379e4487f228a75c241e58648038483569bcf5910fb923403310a39cef236740ce07c87105ec26f7d13113de2103d48f85570252a4fae88667030618f15283d26fcbdef3a6417597895eb88b789db58d091c764bcfab0ad377e6fa558e19df125c4322058377c8ca82307068485bd4f6d790497b6f512b487db18249ce3b41cc8c656ee4f774d1470634102a6fc3261875701c4f04390c14cac4d6422ddc7e23a4c4b23151d1850e1ced1173d913898d4bc234f068d6a964e2e2b0a852039ee09072919ec733eeb3f79e452b9b94dc3ba817a747d46aefb0a7ee6946dc2c12b149f1d056dbfbf8b3b108b0f52af1390d3a86c4e5df60c7172f089580a8d45b933ea6e63c9896d965528112b6cca690ecdc6dc4eb46cd627354bdab7def42f45f8f2ad9e6adf4d5c5a493697b5793ff09256493f9730840d63b38e744346b48f1f1a996d7c9dc3b99560ec9811768f9e4b35b050165aece14673e26534bfb194494fe0eb2c679441482e9d7dcdf70e4ad538a54c20b2219afcaa504027c82d9959e6c0ae9d853148a725129908a8fb79cd1882a157bc9826ba1a646c51366cc9eff3b9b4e5652f3827b710cac3cae0b09713d5fe439deae3a91b731b888fb72328c38047d8d1b025fcd5409135c663bd11a823f879c639054ee204347b557646e840d294948472e5f909dffe1e35e7072c4a89e5326391e9daae7764b25ddd255a64de30c3b884487f81555c4df4f6036c90d09942dbe8a88affe175b2c84386eb764ecf4b52dbf587bed8dff3fd61da7fd8b4627462ce2c6aa9a179938071759e4722592333790e93820278b50817627710184e7652c97b74e8f6df5f1f12077ee67e632fe775ef1847e5de9446251f95a8d2d0a621ce165905eeee83109c1178ea413049fd2192ff99c89e2d4eac357103952892459092e7f51369e5c53192811b37c9f917beac07b83f2bdbb765b584305603702bd32473c175d49e914f16b64cb18ce7650b7c24a8df26c848b607d2f9b5254f8ace4f85ae63c62608609cdc853b9dd567f82034c3475bbf56b48d2a457bde05ec962e545030d17e6a822cf5ed0360e53da0c18b46c145f55cace37b6419001c7a769fc8191889b32a1f3344c9503781d20435219cb740c254519c1bbb9a28cc73d4e109c69956b32bc83ee7dbe1095ecb58c58c3ec4584a69bad8d50baeaca2e33a895b71ba334e8aceca0e1ab69beb31c14356baf492c8a6f2bb3f8de475d851231140c98f2493cd333602a35076e88d812c860ee48a00c22005bbf8dd5a6cd8cfa8af51ddcc9a658370ddb117aa29e722ecd1f632c24880f07e0cda0c14ffa88b212e0ae1326adf05bd6698a43f18a211ba60c00f5929ec5fd4fab264398a20b2d4f2fdadef1f91e6766c299e95709a01438f46bb68000bf8cb0c926a3170a8032b3384ed7811816f35614451faee63faa539c1b4f719478a03f366c23e6445a0c823a5a605661912a2fc4f3460ac5c5cb8497a6a028e20441f6e67300ceb16762934552429ff632739ffb3598042dd42749b6b6302564bc2cc6fca45b5705d618ab4cccb1b24137bd0ca9d3184dcc8daddfcba25f4b1dfa9e6889d53cf527213d39c7223cb186f9930896cc711330e3653710baf72be854e558f694b79b371b191616275a347109cc9cc2f7a0564c0637c14a6885aa0868fcf4c1cd695ce26fab2844b37e9449081dab3afc6a2d41239a69f4a9e7662c26fb89bee61d70875fff535e54529b8bef447d7b31ed10a4a81a41de6b26319e8ed5d6b890be38a6a5337ff147b46ee24323c00cf1ae97bbf6c859e334261f99d40901266524fc5c460f0263a80317948a73f5444174cadb63e121c8ab99afa0a22878f2be100a27a9e5a995aa4bd0595afc9362abb2e667da4839e8793e5cc992f31fbef97f514e976777851c66c341a1d979f254e6d9dc61701c5a71c249f7a196eb78cb5cdf23615e6c8048a43211219f72821939a4a5b13ce1e664a82d1586af1627c57611c085cdb6443691cb25f8600d7b3a8c129826dfa32aa4a342def976c29496c68b2abfc72e4338ff41a20ddc01084999ecf08f8324b51da06ecb745f32d48460d613b15de86d0efcb46a8da0f7aded379279d6780cf797207ac3b7a99043586b02969aae45196587181053f31a2cdf2786101943a748dab337ead0b11456704041e20dbfa4a46d4f7604f2c6531c111f42e88d098edf1c2200400d13713c57dc48666c4ca700fc16b4fdc55d2ad004d1aca68930e0eae1f6d11c59d497fbb20ea7228630f78522a44f14dfd275d902d3ab6675d85b944e9ecbd55c0a7c8c019fadbfbc130abb18d7b1870038593d95aeb643841cf30ccce555709e18bf557a1f9594dea329eebd1845e9be06d6369b3e41b12500875a7b6fb059ebffae523a56646ca18258e54a741e421ce3c072fc7d0b26daa72aa19328dd18d0d588ded39d2a43422edf2be80394033328604647892d24fc904539d4c9a8dc2f49603730228b8363ff36e5890cdf5963350aaef9304b35ca0020137cd92043b20c9359f023f06b846b0443a47e7c6294c32287941865356ae99c1438af40d46e9ced229b54670a909fa244999788d34c54c3fa59a6a9c5fcc0b0ba6d9a9b725f0ae568bfcd7997c031f1ad5d87678d4e46083402428a2e215db47380e2e1b5c3648d54b334cb8dafd6bcd43d2a99e9f2f2588ccd2551acb947ce58a1ba1d89b2c644a23808a691c010d896f728bc8d04218542879750e07ee2063769de0e60d8759e5a721667c1f5e403e61ce181e1338159f0cde78e5cf209501b01c8a00cbefcbd1351c6a056c9ac6826a9a746e7918a642f801d8d58228712fff43b4430dd5a9c93297b7868b10eff9609283e83b913b46a45490786e5b5e2cc895c3961c2079db6ad2cdb0679437446abe7129c123b1e8513eabc9f611e337cd6a601ac205c94b646b26683364b7d1a68ee0e61919a950b10af2a61ac07aafba21764685638501366194aa5c93c394f239cf9e122485ce0cbb6369e85ba5093ab1ac769daf3e59b08b53611d39b51e80382688163eb5fb4237a8f6af1f56d62734609ec087eeb7fada50890e150ea20220745a6d0d8e80361400bc2edb42a518873e49fbc49fa1e7e981547c0ee12822b4b5873ae53d681d661b11f09e15ed8a14a4779c037f670012e05fb6e68aadae34ec3562962b5601e1024ef011b77c10ade384739aa8debe19fc651728d68017dd6b88e13396e1c819f992122bdf3571fadcbadbc4eebe7e3abcc7b3b215fa6e37c1383c226f1530f7be2dc42e144c03109fb161ac46e8808204c3566a7321a9de1d3cfe8f4bd6ac8fffd4c06f5b5df8b2b79e7fd638d41b2bc5232643e23dad50b1d68a3e78e9373537f74b428cf062e7a8127777f0fac4f38cf4c5c7dbabe9062598960d7c310e9f730beafb9c38159ca9ce2d052d6c33a05c32f9015807743a978e58b000940e92405325f44a77df78cbcd715d28c9bd3c27b120f27e32d0c434658588ea61686ef22573022643ea32264800814655a8f90f9f8c6275c4fa7b6bb30747cc8afe0a534d7ce6f5c77246d0802fc7d2309d4a2b660ecb529aab3c6682bee9428b07a52b7b0d4b77a415aaca53ae84e89ac28a5d512efbf3c045a699b44293dbf043e45bb18d517154c25824a87f38ac413511c0e5bd321db836c18637777436147b20e066eefb8f137c602478271e90d32c10c9d32764dc9d249628efe5ca13dc1446f683d920700a584a44c7ea601f9960315ad3223086b184fbbdb212f95565861a515540695155bdee0a03651e8f668a4bc67067a75eaff6312b0d3d8f483703ce93f7e20907174d0f01ef2f12c55925a78a5036eef6b6130817ef46c96e93a11e483e59a1b4c5c20ea5da579db0387ed2fbd520595c7340ad2904d60d901f4c5c4dce31c9fc5c314834a31602af3f2bc2c00e791a1239540752698a2b7e5f7fdaf8376bb9563fc26acf68e3efcaa5a90f5a0cd32a92334107cb4fed38a23d1e395e6b4ebc14f85ea3d6dfe31157a6f853a5a11932fd81154225a422cc59f9a6a49f59042452ae669b0d1a766fda5ba922d494a5f0527024a07aba889a5b9df0fa13e5b73440da1110f3bccdc532f6e281acc9d1c3bb92db8a74658de3838854582aab148772337e0a85fe8f02caf12207b9526a9ca883ff5ad1371cb12bdb18ba721d9cf18493241e0305751add0c2fc496de57e7b8bd74d7170055a1c9ddac2a0bf19c3ba2de8143a43c7eb8ed38697d166586f1238a12b80aa7760fa0b585cf43bff6eb6de70cede5acbea68fdb8c18277b7e8930787da8d4ef848c59c8e5735e2f6bb68aa84cfecc98d629e58a19d6108913cb00716c75be6bfe0008c59faeda71a46fdbfc739e529fc24c72b742c5b447c4c33508f8770afbaecf1de6753c6f7acfebf367995487e579feb8ee23b26909fc7f8a86d42c387cb48510cdd2f2a0a071e8ad89a084834e496e4a9a7c4349bffe221ba2916a2cf1846024c401b54993cf5e84efa39302ea73055e05a88b80412702cd4c2efd76a90c9d9317e0092146c8d558efbb1bbe32836009ea5889b82ca488599c19131985c6a5ff6860d32bc370ab8c644b618c5443910f89f8cc8caa6b0767afb4fbf78bc1b5ff4b3d1d5aa2fa12bc5f65fc4541015ee49c716b3a264661fca78764f06d5c8a764f03c43a9e7d24f754209bfe6abec5c61130b2f101c1bf61495933fd092ae20ff2b442d5a424c937db6a1a77a790a86188bebc9c0eeab58c48740ebe59837c0ffa69d384d2647800373015e8f8451291042177adaba9db68aef15d70c1f3836428f75f99024398afb597ccc95b15b4aa424a35d9a930471def1bf9f1252f1e9410095ef581d0b733856b2edc26af1995fdfc97e1505ffae5f8cdd6aba800e98b6c445d979119b4d9f57340a70fe8ef6d0d1f3eee13bcf67a7196174bd72f424145dcb8449a76f01d12f4ba07b4a8b018f1164e470148a5fd49bae69dbeeb13dd944a03c8dc3342976eb0b695dc613d1a871e5cc72b5bd9476e5d438d82d78b377ea7ad3e7654a4bf53749379664e5d3434a8de87987ab5b4614cef84cacd4cadde07293676b8f33cd27742ed3c01c6f414b0ec538d3e11963e2dce9ac1ea25f705e9385b6a95b93fb2142dbbb0c6a912263c2bb5bae11b4a1c74a25da2c589ef37aa949bca8c73fa04466e17f1430395dcc3b79e523304a6b4646c5b80784a745102fba2031b81f6fc6966bea82aa5fe38ce5fca8bf7233002f138d81f721a363819e42b8f938a2c2d1af698bcc4832624c49c37ece1140ca79004f9554fe61827ab4c2ae9eb096927f9eef915bd929777fd80f5b107122ced0ead8b2ab00713cc9c02564959a482ee69d9b4da61d8c97b87f2dc43fdd117f21638ab12199d8857f93f738d20dcc164f5fbd60ac1f0595ff9e5999950bcfaab583a1ff7f4899aa500664a219540f3206b7d3f48328520406e93bd4885bd13c18f2d3849a934082344767d9a3841e52d52a052191c6cc33ec560d6d657461f488e011297ef4175559894d5bba8a292b2b6374de315cc2822120886e03f2be469dacf9d4c7bd2e6b77c3768bbdc8300005413974a6ab5f97166a9c05dd7bdb08da8180d62af6b611a10fbf6b406c50c20636a1c9fdff8fa46bde080640021c3fc064b0275b84bc56b59d4575d746469f3279d8fd1c43a5e7ca2fa4cbdabd87657223a6e810d4339ce9f170799812904fb307b611144679bc7ec94d84563c8989361fd27afdf13b5b338273684c655bbd5a55a1a02de94673c811a7ec5be2f72e27d8dc8ae037175fb62e7b4a045c6fc6c76d958b2225abfcc8bc362a20a52d8d6f2a5789e34c288fb531bac4eec7aa096290d5a941f01b2d10fb5734cffc037ab0c7af9ae4522c7fa7e101348ddf9989c79a3bf6fea4559202c30c36de64908e8ade04b734b83af4c4b220e182b23e518124290515987553ba340f660af9ad26ed49c891a245828cedbb34652f491e10f400818239a96dd3309acebed7b5f40ce8e39339fe8bfda6255c088543bdd833560cdd3df6e6b72eebec6d239409372ab8ee9466be0af8d34a062602c4d9b1f7f40a57e380e582ccaafc9dd9440e83a7eb3e782887280439e47089e6c96ae51e9706939e6e791951f2609a96c5e68a276c65d3497cbff2e95bf043ce2dcac9de256d53ccc1c461fa1b95b6c0cfe4c1c2984373b9313553fcb740ef60403d56fa397a890a393031655e41eb5a659a082e2d544bc02292aa2166e0282c18b7df7e31413ec4dbf7f2a9f7f7dd9d65d57145ee3626f5f5344153c7168a58aaea03e0be4908b79e9e841634d5514ff31d8bd7d46597e16eca8346b939118002cd1efc5a9c56c45858851c3c3701592eadad23a685f354c7222920115873ce281daa85fe28014fbb0d5e2edc60bb111698b50e70c025cbe0f0134ebd1e8af4c49796787f945c5ae369d6450b8d6efcfed75c23287e1ca411e64e0589766ea50a87ddda36b5e06782d830ccb5086c3b6c0abb0e1a888fe8706a8577108b981e33f7e1fe131bcdbc0a01868dacd5aaab9d80438085fa09bad6413a57608db69bf223541fc3570bb79d2d1a6b9a9df61439afc58eedfcc5e45d6195ac340f0a9913680c159ba99c15668c48fe85c4ac225d0db95f853b1efac337e5f495d5d1fcb7bb0644ef84d51ce585355a2ab0f9a46d3ee94760143b4e56dceb8b82bd081382489590cbad298306ac3a268127e2825723088d171356e06d1759a92b8ca56a9a3e1dc6f23f8b672c8a593115b4ff380cd7c7569f78759bf2c09433c7ebab42331d24441a1aee860d7c2d6575bdf4981ff472769c7a39c416e60772845e14135bc1ad7414dd2f2858e94335780b4dfcef927ea8589a276c13174d5c189d441045377aa37565c201684ccfb87f61feb2036f7bf0694396aec3fcf10b288afeeda663328a025d8ade1db83af919104a8c965e109d7c639cf74b15ea1ccc8f68bca64cab2597bc8152fea044d19318544719e25e85f68b7e36234fe8513bba44362429c787d25174d4b9e207794bc79d4fa413def4508d58a51ef075f720850e45abc0ab362ad8849c93508d5d1d0cd24c78fa3e2614122d7178b0496fc467683679aff787022c7b0f9e27033d297c414aa2fe8319dcc89a75608a5e9a4e4c1cdb81ab4b2779f41d0de5f191639dd87add8a3a752c010870a0e137d9ccab1d056e4aa6945627ba498bed3c0ec31dd63879d0b36045840b327a6803cc513358511bd7345911877c7c75e1618ba28c2f0745df3a248b568854b413e12c949aacbc7801a1e23850dffd4689a59fbd1bb359638f48cd63f16a0c2221d68df512cbfe46508b3b76b31f979fd9be47722923525744640e3b1b68bc661ce2766ab36dff90a64d849576109d2dc8a39fa5f7f40f93818f7fafdd07d4e93f8b169023498dd6ff8dee9b7853a71eb452dfc83b91faa1d5ed0a72d253a395a706aa0ecdc1441e6a6dbcef306823132d0ac11e354759ae373f7e7cfb3b2ea8d3c28a3d061d618fae39420255bfef9653ea62dd6f511b89ae33319c1875f4a4c02b94843e222bba6c2980cfcfd88de734facbe060b03b7a3092c2e295ba3677a5d5f80575c939108197872d86bdb208e63333588f8603b0587cb5e77e8799b2d5ba774e12435e0adb9e560fd85469ef3d54a6dba0439b0f10bfb9b7627a272e48d5774a8b04b9540bb3c1752b81afb77fde6900922c8f317b70a5b84b70568b9634b8f0dd3cda8e8d79e8a8291e91c462cfbc9626b9a006f49a7e65437c6797e54426cdc97408327fd60fd6a82e7e5605393225ebd9a58acc8f8f05bc57473326855020bc392f572f32e92d5a913fc199056785db7a691691fd14bdd201025964b758790148f7401a238a022fe0cdfda3e9e88ed2a1c3d314bec8724974ee38027bcf672e4f1c09ddc28ea5f93141f7c9f9e67c11dbdafb64f0e3cc3e1885ae47ed5aee202b06a3709066efb4e2916838195e19bb25c928a59555a4d1ea4417ce0979d30ab237e1d305e89997ad9a550742f42550d7968c952728287c30def7dd255039a275438cbf103e12e319a3595211e9106dcc5deba482231662c2e9ba112d992cff6be7db01ae1c226eb62b9061f5357b677d4ae7a96b8a0b1ac683cc6e06f350d66b9c5cecf3e4810e38e0e5ec8e2850dbcda0a9608e4c36011020955ca87d2b9b68e6ce354a2dbc1c7883c8de0bbbc574efd896df50d2db22f8a60135102592c1dca8a21ed6c55341e361d55996f45befc28b3db5f7fdd49c1ebb53177706d2934992a7a1fb1eb6f76ded7b1c3d457cc54072457cd287aba206d26707423099cbb54f299b23582a3548ac5e2fd24d944b6c1c94609a52839c9ee1b5e35250319270c6d0e70a34c2f18f2e8d570cd8354c7199c32f8ee12dda25dcfb570b3bc6ef6d9be93a9530b9406b5e022563596e88d2bdddd4a6e7dddd8c79366f55ed53ac61a9da7132592ec62af9742bc41d094b5913c8dc94956229972591121f0169357d541c702809e49e3854780a8bcd8b6cbe974fc95cc9ad8a57fba907bfbf20288c8f6ebb26953a5058467cc039d334a9efcd32664b52a18939f5e934a4c765e8e947749ba1f9493f3fa65fed1e8ba941de773e34987c3ebaf636b965bf48c5ccf9cc36fdcedfa62ac2694d91646703bf1df585a7bcc9df5e69d282f41aeee2ffb811776e871a6d49a7bb3a1876008e81a9b7ad43a8e8575bf10608cf4790d92255485da3c00d420be4b8d26e1f31c10f98d9526d555f2d2b98e6abbd1a4f91c545dbc2390ecc0df569907f4207dab4b9c7c6c8a54e72aeb568c43a20f91e7575ea612b2dfb5652c2f26f9d22547189b99312751122b00526ca5aa36c05e9f3783a0f0ade44437347fda1c2f303728c706de0f68b26f7ecb47c5714788e4360645fe92124e2503a18d382ab42ae586ef1c20fbebc8230814998493284f18f41e7f08039f26da494ad9add42d0719c549ce704cb4a6c7149068d1de6bce994c32579053e846354a2a7c70faece448ffe0eeef68fd65f6a35eeaa88eac4a234c079990bdb48de76936ae23706344a89992988fdb6bb240aee2a81e5f00ce1b69b2d04048eaedbd22fea7798c400d0e3098b69c21da644ef94b1c92be1f181362e410bea71470beefe1253f735971a1a332ece0c5330bf70efcbc8707c59193202436278c9e1fd3825bd97a655583642ab3d7a3b965bdc2e04788cea1b5fa025a83f9f72efadeb92bd3ea0194b53acc7ea9c72fb0596ba08a451f6c746802e1c4291f6b62d9c8a2a93343b5d7f5a18d6a95efa60f61c03bcaa983437a1ee1921c89e9b6e8acd7cd6b3075cc7d9d1c49b8378d21de953205faf6d2b6764703194936e8484451d3312dc9eeaf6b0041660dbc607af189c900e445b1d2261a20d47bfc034dd3f651b44bd84e73f78ed456437b8cf9f96d7e343bd6057c5c1f343358b2a28264dbeb260d22b7d0acea85e2335b40a60fba7d215e1ce9344ac0770cb113b3c913e567f058e5aec3f91c08a5a4bf2fac42e1a5e3e30d78ee6ba49cd2fb8aa887b416ac1a8ae392bceb6160640b05d0c8f3b3c07895eafd24064a40974e31a7336f8f9ab56d740993fca443a2538f732f1d3b43ba77e4e379bf51d98303cb9a4e3085cd3ef6295ff174e73e3875901415293233266a6d7aede7b0f5b684f15d629cbddf975785d996946da52f46c328a1dd2a8e871691947f8269ed4b06ed589eb9c4741486a84c59ed90499a60be71d8db0244f2533fbc331922d67f264270a6c232d0cac549a31b123dfc9ae8d5a67083ef0202889ead91f470864226ea23fc1b9b849e4ee727db0c79b09aa951b4228da859e128d1455387e82262b16844cb2620adf74fb21f95a75286c93fec6dcb3a1f9f28cfe56c56057f003c61aa7b24552132895597e0252205645f002850b8e77528790cbc3650267ce0a9420ad877dff3c71e05a4b99fe07f9eaac69087b76e0ca2786becf7a7090a964b3a8ae73db9c7cbeac0c67c1007896d1fc4e1fba7ae446aaaa33d54caf3efa4da83b3da64e0831fb4faffecd98d4b5a8bc2d0d55d2b7bf50823d43197eba916cf3e13d4120f636c52566b462017ecdbf04f6c3ac796ca9074016e0836f33554f788e27f914223d77b554ad3f15eeb2f26a480c2da9b53a0138d9ac129f267a4917ad7a977bda912270c224dc0075b628616ffae92e07bb59d4b8d7915b033252552aeb0dc244c9ac78db41ec54a7ab348a6e263b26862547474da8850818947756de4b0158f286c9316a9721a953070a93c78c847c171bfe4634d8d1fe3b424b90a0f204b1404cbba8dc2f932692582ef49c912239b194a3d288a288afe5588744b60063bdb9c93ca7a979f64424e5590b5a283eb85d9a4a73b8c6752836d1391afac8dce1d63299d491107618f7e4a9063d899c6a93c097dea625e4f93382e4297b48fd1b20c2a69ae3913d21c3674fb505ab5a9900d316deb8ea82bb8d4a8d7925cdae4450f646e3e84ee1a785e3b23952694194aa2aa4e677eb45ea9d592de0c65cc4fc9de2c27fef8a90294a46bc54a43704e7fb9961cc004f25730f19d5bf9f62bbdd4d9779b93bf313438d54f11354832cd7ee30ffd5bb08a74a2b8dab648fbdc1840e07f5a4af3018ff70f390237a186f22b0d669e534bff33730e33c0da34ce307e0929fd600d95f186588e9a2309aa6d572a87c2a9e8584da00b23505b9206508d26f920241795e18a488f4044f1e82028e090915dac4f5e9908cc724eacc0f84f3029831da7bfcb8270ac5e2755b5b6b9c0c39beeee8020ea5912bfb127171e9dde6f571f63fdb986e4dfd398d4ae41ca99a7b5fda32b26b2937d73cbe2d68c652d7df52f041bbbcc7c6ae91314bed7d7d164270e18344cb461516ce013da444c86bc15be6b8466bbe639d830e8d287f87eb0f8c999685d8cbdf761ab9b416e883de5654535cca292aa284e2eff5214ff3db88e9e8b0aff79494c12b21154f6d3deed1a2b29657853ae2e8aab627072627277851c4e071729641587a4558669ab09578dc30a53802ff6c21106ad0f434a29030c2336c58471ea6108784d6d7cbd567e0a87ac250fa27c71526ea5f4e79d4fa8cb6bead5dc8a5ab4bec3c019c63acc90acc700eac1321926e124b4f7f0f7a83f967e8a31a793d30d4ab698a81f9f4d016b4c4869f31471c9788c053b249f42a624587708a1522b942767b0175c9562312300cbe7afc9aca8d25cc54288561770ca95490a6c291c868f1b02f08b097160d633436120ca615edfdbbbc8493b2d4131cd85b99d51cef061e92b29ad9d033760de5a88b525450aeb5ee5470c5d0fbb6077131d258bde410f81a9c7ba8eb91ff61e11cfc8f4063baffd0bfd3898930c0c9a52b2579b0eb35d40fb001e2bf10cb05bec6b675105a57aee3e1bb34deb1bbfd64d6c03fe102b725b0fb06fa4547e967e1f96804b1fe566f9985efc1f32a56072e8f1d411a21e01a130f6ecc1542f631b391c5f8ec8646139255c6b769b9a3edac2871c2f23dda81a8e812f3f84e742a73fd4956309738653bc116800e3b6b9d3eb0a1528168f59fa6a4823f2492fa1aca4790d5da73e3ce2a6a2e9c1151fd1645236be90eb041fc3d69e1ac43add3399a5820a01456dbe4cc61f9bc3b50f966e337655884796d3810a87a9c3dd83496db64785f0ff84003cd1e0e72561b4a225a51e2c0a2c2974e09524390879c4efa1c2a093c6538b5aad22a1f443a5d6a2486308aa7de43cfc050b055d009694630d963c70029d970085c53c982ca3661b72a8ea4101af3657483783d4de932779d4eaf9fad3a56f7b179c1c9b083f2c73ca158b9da46ccbe1531ede9591aa82509da72437493e4444a4c1afe3fd49dc3693bdefa79bb76ea80bc681743e1c50cf23f3bde0db75dc0e0ec4314e70696290b29e77830948918c87a269f0dbb2015de453af47ba473fef46814089e199a8718b7c6471601466f7a5228d8486b4d8b18e1c38b6188b21157b41f65a329918d74cb34f3308e9882e0ae4214548a6a2e8b26e8a710827b95a258b6a795f0f77d627f05a3b8613ac276b515f61d4a7cd02726611f93a37cada83c8d3889f814fcde1d6129c5b2154672cc39e3afe925a499022730169f3045859ae8b397324dfe6a930f0188b0dbcb21851ce3b15143bea2e2d45aaaf9632c61896d7595c33702ca6f4aea9921f0f397e49c3f7f8cc65fe6639486bb7aa76ab2393bd606e7207bf120032094ce0eb5bdaf415c9fc3c311fe5b339b08cf428a9a58774462f231b4cf8c69bca281b26c14e96114cac34bd4f42250fca18093b0d1ccd9688037ca9143fc6430ef46732b4e430fa487195b306d9f1ea104e9b52ce441f5790d5a8e707d4faa76e952ea7128b241a0eef3a2f26b520d964e38e6ac44a1d6e25ac288d136904fcc883fa54317b8d37a8de57a2e50ba078c705b46edc06a2014d44449422a26e898c362c1ce287dc0c49e2aed7ce12adbdf1fccb7d9dad1905a938f5365cd095f911b6b34e55285c296e612df72c7fc409f9152a88ef425b0f6fbbbf5ed28087c0001d5f28967b3869c86e986fb71ed3660329668c8166e89fd4020c14a4670a2e9e20abe2f3a4f0e638ff459609eab49a021761cd781e378ae1c4677d589a7748008275278e863885499a38ce2007319994523874940062d3faac21691d8b9f08c0a472df0cea43061a1ce755d55df790030d5a329eb1430063955bd3e34815fd0249d25540519665cf424da448158d250e66a123e31a6281840e6aaa08e1f9279038556fafb882bbaf41ac1980bc56debfff1f24c2d1d67e22a31458c4c76150d609e567fde92cca8e7a689a1f64d13602cf09dc4582d5a09002f64ad19795a97ae771749ca9739af2816514ebea9c96ce819e3a5f23941dc91fe1866e5036ab510a170122ad4b090d2cad7f76ce5839f56332abe98ced53f912c5549b2fe59ea09b404cf42cddde02657736dd5f629b50f9805172577678e87911b739664f214fff1edb0fe3aec27681434c85401754e98d98e07614b4ef29bdc28503698cb3314c5e44bad5868788e5d74e6e6da47f3dbfdbeeea7a53e2cae52032f3852c6c824164d6a940c428037f36de42b4f21788b32378ccc55c2c96d900242a13561f4bba6e6207de286dd428680c7c82f9ce0a8cc28f4bc5579bcafc5b9da1e07f217b0bfcd27221cebcba0d5bab1ecebd3a80da40e7459a790815dad016c1e5170d66b28601cb6dbb24ef20ae95068efe9fefcecc7045e0628370c7e87d221c25d64a9c8b21ede583e76533ea5a6cf9cae7f28a0da71b051803349edfb1e8353556d6d22e5bcb9f924c600753c7a455a7964ee6402d185a871663c60d8c56a656e46ea113f89f894daeef6ed62c24ef4db472627f2ced6be049e57cc4d9802fee38d391e70b45b886bef4a44e6def21d4a7320de7c6375dfa04dc01d4193990db7235ae33bdd8a6d2aeffa089a36ecea957307f267264c599b3bfe1258e21d7df78eb40feadfed28436a22615d8a6046473da1c04e7da58f29f0773c753475776a3313cf52a9146dd5697052b6a2b171da57cf3fe2a8954efd6152b4957dd9284a1a25290b085b9ff38ae850e49dea97297bb55808b58d9dd1f161f02718f9734eef01b5265101cdf25ca0bee1f366c3ebef4d044328e590d106a4924d026b55f31f6520dac7ae9371084f8209e64402ac21877960aac8bcde7aacbe82877d52b64713cc5e63132de863f2ffe5d029afb273c1f4a65e0ea9299d6094b000aa8a65777158158ed17a16ecbf37db80112c732fcd5c77a7bc11b5e36453ec04803e92c0260ae4d81b839d0a7ba5116e092dbb90ed35880f7aeebb62d6302c67a35490e3b959c89325f996cf92b553d09e00ae322c48456f8d8884e4768527a9251ef95d0f400e02edeb8caa673742ea034c2f94412aba6a2c914a8410db04a9d14d1e8e70782ee2e9b9c20eac2f9f5dddf8de40a4391488bc1d6042185e924fb5be1ded13a8cc87e979a849eaa8b5a732a256a0d5721e17ff03706add6c6bfb92dfc5e501363b4f82173a4b55f24ff9e7688caec18c13e63dd23d7fa8df60dbadde0343bd9d967d3305363fe2c970a61c14601bb562b9fa1deb634fee13ebf8f8d25f2e09eb1454e5a9922babcdb2f5929ce6e5a18512dff2dc96921d6918f8b5010545f87c535668131e9122d503f1ea4f891aa123d9b891abd705b404e8cd95bc4786ae634d28b9c10d93a5cab3f0cf129314c0665924056e0cf0580e2124bb1e3649b29535ece1befc48cdd2c1746ad497d2b27657705e540ba186880ba7735a02f482be5563b1b83af3cc44cac33ecd7a8b52053eff2e459951fe61cae2a58d649aa4195ca50c3378873cad6e109c893f037de668d42091963365d04301614f82d6d1bc2506506ccd1aea1e7b5a69462c4474b605155e302fbe545b8b0aa2d19e4f76928742d2db37ce4022c159d9b729c879e6aff870ddc9ca6b49e5e4c5352af602fd7068401ba27c3935d2d8d9cff19e7203b293f895124058ec0072dbf9254538636a8e40528a703f284c245f0bd494e0cc357131ebe7a9c6ba5b1e89754df0262da478b245bd411da397f02d064868fceb99adeb449d3926d3e4f68b6cee58e80a941dd0e022f8242c49c7af7dd04110ab9423178f79bb7574faed3c16de90138cdf5391ae2c5ecfc553012678b183fc2aa67073df259ea5676dcb532e4d79f6f0d028f35c4ae302216eca16dc30a6db83e5e960e8ab848ca3da63896e5a115659c1b597213f75dabf9ac2cca1c7486b35d7e5bec0888f34b2994cfe76ab3c1dfafd4d3653a45a6d176815bebc6ab89f115fcd16161ad82b8ac1b809951ea4ad7a60c5c0bb6dfc2935a8a533c321751c7fd01d9881d41ce104dc21b279602db7c1ff7afaabe5aeb8c71fb7936f865b01c13f8b3752ebeb270022e3dedb1a0188f2a1ccafe55131f2c4f40e4f341c7231ec45f474c543f18481efb7c5211ff9200519cdaaec782f8c5d1b7e1f0b28cd72b23153c865295294f9ec9041f28143d10512257beccf8303731569c8e858fd04f81b184c037f986e334da4ea015d3b670d744d8a1fb3facfdfa6cafea536e76c396f4626cc27d6c61bccf14b8cda111fb8cfa0f7ff23cf347e0082ef08c80e4a1fb8e8267da24cf67dfaa316e4c005151f7614ce1190fafea76b22455c8d6a7ac9dcf9f505d33ab42e087a75e050489d7859f294a76808bf4b61ee617a9bc09cd40934809a0674c0b1493b2d573103b21096ec8bb691dd344f5fc239560e0cb18f22fb9ea25815aff645345d505aabe10348d39451e3410835b07df9a018f8591ead3112042c5292256e4931c7bb58e2f0831bd75d9dac77adf0ee806b88d7da8a94127673056652a0c92a5d6c6da868a9000f88457eeeabb0a49f1527355708500f25b65682e1a41241d0000030c4077dab9787927dacc3ea15504584f4d6b456ceff844592e4557d2719b40a47c30e841abc58c0abd9791ed3524caeaa71769ae3d2e32221aaa1c7afe734f20b9ebbc66da58af223284f51018a4547c952b93b4353226e20c5098e5cb5a787d3d48c70c2a7015746b9a99c921e2594db6d12ad70415d4cbea901883f0603be916e63bc873cc14e2d35cbb9535ee409ffeec9235e60eac2ca1305dba10778c13703ed0d22a853953615e54609ecb66616b756d6135729e93f927875d669506452aebff574c20bd81b7dcacfe2a7fa217efae286dd5fcfdf0ad08217bb7fd49b547617c2d16455277a0c3a246b687568e4af98fb9d96b80ab591d575d3465e140a0f638cd3a6a48c0540c7095a0f132ad18acb708aca6aa21348f41562ad58f8341064dcc425d74b6a688a57f8a69976eb78433544cde0e2cfa24e2d090282d425780f1d6fb075a83702cb745d0a89ac7f890d03a84ce7c872e90d8549a0e66e47e40a73d2049522102d5855f1e3d8743a09b468cda377bd845c9fbb0630a37bed53838e5e0b42ca01a42559d0a42d414af37d226276b206e232ce5307fca2f8d0c12bc1ae5ef85dbeb6d40cd02f5e8322a3d981f522af3d39c84dde2a580e468a9abbd4607c4c8b918ce91399fb09fbdba6e8c8a9bb816b20930c8fe94a92e24ff36466d9811433f24f696b404a72c6309419489790c3bdfb1c45d933a0a951b1e69c71b43974a68fad89b867134615ae95ec83707a349e1f730cc0954501fca1942fd32747ea7dbe2d99c7dfeba23533ec6a8f1e8ca7e24a3123554aa103d569b50f69eef636c204122a9255a76face1c85d3248e9e2e1f714f6cf0438d08518c6320c52331bf1034e7552da89f333dc537fa4d445c1166cc1071625d3e9bd6d958ef9c56f31acf61e7c9fca63e4c53b2f15bd3ded20aefb8a4a645009b9d9ee7c7f61313c68fdc787146d32955e581e55e7cb07ed67b88b9d99db1c6930429ef2d34c45a929170c2604ece68fb48d8fb23f398363174c79492ad7d7be182af74828b23f504687f1734a746b0d7f47d7237cae13306ac8643282ca45b615da4ebea8cbd039507b1d84d889bb8ca558579fa357b13d2d39b36c69a5c82813c4fca68f42381f3e8cc10d6a003f620bdadde5f8b420f2646eb0065beb3f0dad0735dc59a8d5d6042f96170c2c0d1c6aa6cda6304924939abf07dba2d4e4741cbbadbc23f39fc286505c7dc5387e72b94d2b2efb2c8c69059cefbc1e69e33ef0b2e94264a1eadd5e815577bd5f72656f128d4f635a8bbd7376c1e428e234dd2f2ca41b49b7c7f0f797c78ab4d4abd50a42dc5af97a1e4ba59806f1df78894f2701120e468f213c7336c125b423a909b81e614359485bd472e6d8c59573fca0b4a8265019d513673eb0e3f4ca465baf50ac764d5e2bccbc1d20416b26e12196d3808a001873fcf3f7a87c21123ff58d699879c6bb4c71c2ccccc39822c201e33f50e362c3ad7b49a8b9acdc15267ea100dcb249c62cf0e24f5999d02375a2091f25c128aa7aebc433cf35d422cb456e4e87a634bcc38f317d8d8dec619b12a444fb820a4c0a142eaecef47b0ba8f53d1e2c63aaa1c1e4c1e5c00bec09f791396d1c946be44eecc57ed873c5421eabd2e2000373ab9ba216f6e2ff5fef5158bc25b2f83480f6fc09f3d9795811e86604dc4ab6091c253a6b4d50b346620fb42cac4fa5b300c3ae3bbf01932f5eae5131517890991c1e4b3d571bb2d3176cd2b78e7b439825371402b7cdb27ee4303159fa8392271aa46e8b59641485ed126a95a1ba068221fd6567823788b88e70d8ac5f691e5350e194d2471a444777a1f972862336ce65153d328530a221d8f6e5afc4479aae44229700d476d725f331058a59ab7a349950d8ed21d87a78a63d40873e3f26526be892c0bac11f418882c67f64e11be2ae5767e0ec471003ca6a86f2e69ff865123020993d99916e5c13904e527dcb191382a74c66c9cd5ba649c2f6a79a845353cd8882528b523d559ae0c992744a282491e2283c7306cace00a16177676cdf550e08b64f9829511d8133f7c17965605ff734b15200b012dfcdb69a77c5d03ce2afab2f986a09face460656b8e052b1b3edbbfe1755efcc580e9472c7bb942fb3ad7546b8402fe2a6668c3146828b0454627ca35ef2d1732ba81eb65b0417cbc9c50c33f414982e756e862575aac98a007d4f7b6d9d261b5c90447008ad51bccd305a00b537b7fbe60c32d690b9a7491b84d37fabc550199351c25a8832a9a3ebd5361a8988482967b410330927404e21b9fe7134d5092948a7ce9eb54446ee5f7283a5fec02c5267618e666132555fc8ba8a0e61848379dddb3799f7488167f409ba3d08933399ae83c9a843e5e9469eb535a8876e8d581519a8695f6b59a6fb18e5bf96c9d717b10900be7e9fcf2bc62b2f7df2b44da360d4d798e377c0266acda1dedb97d2be962e4ee4801aa850f43e07f2bc0f830369c1aa36c5b540bb3e70a59b4048102b7cdbbf1149f7d9a2bad2e1fdcc3558eb2a382fd975bb076ff5f4434a60e3b9788ca36172e8afb6857fbfa8d9d992f2dcd661bc3b8b13e3797da4736ccc6cd0436337583f7f2498886271584c0aea6b2f6d5eab1351f63abb56dc8191218ba5b4a2157fe51dd1821041efbb5eeba9a755c06d68ceff9bf16e41dda493f578d2ba3d462d2a5ccb51c7f86ea7c02a0012839d11eb8b7d46905c84a86327ba882ad7e8975549c23d9a327dd4cc1a99b883bbe2e126234c840148920c54414d287d3e4798b9f9a6ce82f762024b7b0afea72ccdb0c63000f5021927b013b8537ba85e7410fdbf92da9e5ec2eb8262e0a484ec4d6856effeaabc6c402b0bc2e4708a03b4e7d1efb1339f60a7eccc5d6db0d8b7e896543178c6dcd8b82ac6b36b5123514aa6e3eedbd6d02e8a592b3531582f515fd802d3c8a781803fc7e18e02b44b7169367733c0f122cc4968c2fac69d65b8bda99e27a0cb6d6f6e9ec22319ed41647b1f126776044d25b01f118bab0cbf9fcb91f4a144f549e4220e2d188d06977e7a8197ba839ff641b7d27fd6584c246d10f9bffd64108fb187c7410b7362d0e32b312c94c9306daea7828f00236208b9ecc93c1a938e9ba7ee8b14709310dd990b43a5b05ef934ae79fcf9d7aa27f03e1d8489e00b84b6a26867a844a9f19951cf73ea760176e08191774dac302c8a0d2b7bb406b8b5da26ee2aeec02cba3e21c43f27337cbb64c55ee2d84a32fabedf1927333fb5d06c3febd784467f0328acc6775d52ac30fe17a2ab3e32139b74a0c65b949e7ed39e67d0d81a383dce69e21bf75b0490484c8d888254bdd55f9121745b5665ba45e216d88ae60e0c7fda0d4d5e906a3784dbb7d93387f5f439e353fc13bd1b99fc918d160888abaa24f24e58dd3cc6e17e9d4b2401ab45af7bf7276a8881bdadecdc271fd7ef080016e766f1b4d7d38a103118ac0e9593cb35d08603a7bac08e16765575b616af29029de62a2cb98d4418df688643c629a4342eba40f38719af4d1985f092c05bc7f3c751a1401a3de61887324983cdb9bb0ef581cd85b61ddd5cdd2f4deb02b17e6a6258323f065543e366a142a4c2ba0e2a5448e4a96b2002d68be831522d5f43fbc1f4838f3b115c086ac824b8e1bf8c3a2c8ba2a69eeee816cfecf3f9590815cffef9872d61f1e4a6ef13d8dd4d81bb56613c82b559a5cf31885ceb882ee217de3cb4d14d1ec569fd197c4348b3ad25ad14cb94caf0565eeb285119e3550325fd58a4c1d3ea2d1e04d7ef46805b9b030fddb874cd3c946426e7631f8ee10b2170de82950dd080f51114c09bac70c68922e09aaa906ef44f81255370c4c649e0a85c330c56883e1be152cb08cc7c01f05da383f1accb1ca4be42b44b79924da94ef5b5ea12c7df2a1841fb3422525655da9aebb0c3dbd59ae1af79840b5f3f15a67738b8703732f2024bdc563b833d4f706150311f756b7a1936b43534232cc4555f1fdc281510d3fe053df740388823dc8734b28123b07564d552657dc6871447b84922b062284f143fd3acdd35ca6ecc097d07a2c07854ad60f9361b844ee389239ef15af898467dd0d21704ce97ec30ea1bb53bd3e2e2ea3e0b740c6c1b77e85c67287020c07f456f5fa8521c6b087cda597219c8d4894419a1510be0e3846ce406fb6727e854904d3b7dc1f442d619d158962530eeb4fb882f7c9d4c784195d58c0b699de41908eab00b5291436ce364cd41c36a055e27f711ac668452b8a23c5f2da0486c3e3eec9a6119b476aa6ae555ff1ce83b1d13e88fc73a96c731fa18c572edda6d108284dbfb0f49320501525a437947a1a599f9fb1e11e0198800d774ab874d7dc08cbc411de26d0acb9dd2516868089e25483e7bc5c4e4d345c0bcd5d987927ef879f782ea8dcd00e44d29432e03cdd006961dae23e81fee633062eda216ab43660f694e1593a7a1cfa81b1efd0dad0b53f1e111668dd5e51f37a9d285556dcd071912e8418a5c7aa0087b92a012d10d2f6c4348a8e13870222a25016d486fe0d98ecfbdd41c374b459f813ea65daaf74ceb9ae04dfb5f219637bf9610a58cf728badc28da22a3e9d55361464b3f0092feed90f38ed65cc8eca11c43df61086dae51901210028c3406bf5d8ada3b065e4eae470fe901d3134e4cb9a54b5364ab0a0ef7993cb53aeddb98100d534e2c5b849bd39ee3c16bb6ef8002ccd7bf4a262d000384adedff4182c60dae4cceb96df766551841d2ff7d0c66526c56d7f2a21245a38a85c5643aab2adc40e9c867a1a670d63479b0559ca9fe0665c4d21b1b2e5e7adeb45f685078d0d505897c2e0687bd3dd9b1c441678380b14dae9638ba0641529e07b42ab01c91c6d105e8c1063586cdceec54c824b9d15e0b72aa763daa00694fd3b34aec69f0346e03b267a01527aaa51450075302d27c9faae6e39d1cd3504640da00b5ec108b11b709e6209fd7c002e9d36a63bbdcd8641e0ed9809a4dd76b2f49d99c62e5a83bd2ea16a85e28cd51f8d5108a864b726e2d835f3848b573f5d35825a706a700c6487c541d3f986003eac6838de66fed091a0ba90369e136c888beb0205936ee446892960984d8da0c32d008065133e9509630bf6e2ff69d83e4206854a4c05f3bdeab9f75c6c3d78cdb20ba7262dcb1e1c088e1be299d2932181390429dea043e315830e9c0d54955d47adac77158156e807b978f4be0d3507a836c4fbf4a2048f5bb4e338f804516999ae9ce6f79d79aacef5edbae33c51439f58a816c34352195e11eb3a3c694b5d2ed6f4b0020a67203020160f8b27384914a309d153172836b78d2b63a7a92c84d0ef1fc28876cd84105d92e4502d9e960ec63d06cfa01599560f4db04cb44bddd4a5b127bb8f695e2da1c5dd0ba351561e2cc0a47ed60e123e226a9963ca2626d3c5ca4125d7647330d8ab4b1e6c73736cf75500184c8203e53a081464de5ec3868ed75b122773ca7d4162e4ab305329436c6ea0380a3ba3821979d858d651ca16fa72fdb218f4e85c59279bee12321899fc095ed8eb2323c08089c92ab6a9edf3c4303014a6a686df1049d386d61b8786a4d168c17b3f5cdc895bda5cbead3b2f72f82ac49382839e6424ba83d3cf274fa3d2b47be5b9d2f454130d8bd4497a83c348839fc7d969564760a23b72028198ecc48be9a5a0ff1dbd3f5c80ca3026e8a17bb7baaed9119915c7051f35fc3a5048cfa316fee843f82854fe18a1087ab7784098259be7515b080d98d1ad3518d19f789f31fd5f50703570af3c873075aa473a3363b056a7f003d317f3d0ea01e10601697ddbbfce979e449d765dfae3faeaaacc67bdcc8f8f5cff5b4b88ee3f1529942407621357b72fc44af7b6b41c2ba533371a2cb79212e0857642e4df6d2d278fe7b34f746d7444cb51d4614fa1c29e579b8706252ae769751aa09245694c2102424f9ee1c7166646405c6cbc58416799ae44db4152122caf9c14af78dfb226bbae048ebe458fd1c6ccb60985ea581635f4dfa3b8df2f57a05e5b3f371c075aad3986348ddc949cbb1a8d1e0fb38b33b6c619302599fada07fc3a39b7dc75a7c9c3d5cf56f8860f3c9673bd2098e863e81cfe223a2b147b4f888a02edc057fb0e06e7c44461d23adc6e43707c230cd98db1594ec029cdba5c650270ac312980c0afbd000db25e01a4b6396d5c0e3c0e77697369383e06ac594f7de038f0378115d5d2ed4c938e5308a6a73061eac8bbaa2de3521db12ca1837231dcfb6c50f1fb4a41a87634c64f6eb074b1d4a70ff1fe4729c1564c4df9a738813a4c2d6a616c30be84897003432ce577d2b2595507c98c2d963c6b4c71cce1e13923d48c43db721a097dcb0ebfc7fd90fca94df7e48c967b9506a53d8b9a30f5a45ac310403abb1160c3177f897ac068b15849618f4352c828edc8cd3c0380b92a5b007f96073ebdac5c899075042535ccaaebc5a747db4135c1002006904ff807c88f5f60ae683328ea401dae1f32260bb9fa96025d7487d1c7535dce5e08e0870e3df36cc49368adaafa165babe45296e3cf11cf2e5b67ebf86638dfb95cab5ead1aa5e6d96f0c001b9baf272147978d708d7af412d71e46098b4f2b70ab32a33e14dbe7cfb982686b66f3e7a07ea38aca420daf130439297ae4ec7c1038263daab1a8cb18a6e2706cd373d944de86db3e5e181c2553cb07da372b7afb6a3e4f22712976b7db06e576696489c4d67ba74df7ad0220c243a5e679c86ba56d741c154aaa94c5601ac58556835077f9403db6d87d7cb439e6ca9db0ac54e28d1ea4683b5053ed63883685830c6f48db29537f7bfa68001d21f8175e1717673dfb9392bf26d2d4b83ac4a180f078b3c82961855ffef1cefcce093bc403443b0342393646239ed8a3534831cc8715d9a61478650d7f30e13b970aa465d8c1b1ae653f786358a05dd78ba4629ef9d18b5bc2cbcf05a5a10d7590af26bf908cb2b76aa527b0d03200842217702cb93691c870416a8b087b5589a410db73da2175b00ba4a2964d73ba2c544a1aa025516d16c16f0547ab8696d482fb8e17ad51b9cea4e08765062b22bbc441c86ad4a49625b4f8e884dfda0c30a783b64ab3cc8f8bb47442f0793be5b2f088624929b3a5e9c266624acdf3cdc41d6c21fab25b00c5f9f3c37cd4e101fbd0c011a5d6f9fa830f8b3561fb1b95bcf5911215bd745e77396d47cc05d23c152a5f486a35d472da364310886bd4491499537a4a5d089053399e56aa18e6c6c836b8e5ec456066115b3e828434b4c3ab0c46b6d45016ecc9a726c0434b52575b3beae2ad4ea88058accd1875aa2d48d10574fa1c39d90c7b8f08c31c65cbcb5678c88486dd2ce98993b79053b288ef31c249cb434a0f5e0c9f236e97148adc398656a59e4a4df70532c144d7167baff1dba55cf525fd5a2e246d5e675c15af13e85a0ccd44c9c34249db24eaf5acc5f18aa81810daf7b3ef92f1f9510ffaa55f504145f022ab96d5c5e300cd29a0e92f1a4f4f2bf49137f26536fa6b54a016604fc12e89f60f323601678e37e808f50170146036c59c3e251986e43c100703c7e59f0fc36fecc6ff871147a9299a53755d687661ca9bdba030fc2b626adedbdf7967b4b2993940193059f05f5054f6bd824ca38865a4fbea9534d1d0778fffd0bef3fd3a88928fff7463af7690dac2f3ea36cea5c5389f8993ad554929fd6be2a45d5c4b411b029172db84d492297a93dc513ed66dc81e84a55ab402a2a1d28a4c12141a24264481108f440b28688238e44692197f5ca12208bfe7dba8d4ee14a3002352e80b981a9d977253bd3614b82a44c932753b058d5ecbb2d0451599ca6b658a9a99061890c377461c283528dd4613d3422521e5b69cedf8a9c49a16e4a7a15773bdc61cd422a1bbb1f82a130116ce4ed6f6952b6827fb9a805f4b3e8da29694d2c6907747b1494b5564bba5b2f42fd2c565052f0af72479722f8d7355b87571c7643a9f1bdbc40defacb50eac892327c4253dcd7658873d8fd104c2825dcd95978c563379c81c6eedf50cbbebfc3f91f17451f719815a6d9f75f25f598483dd09e0e1cd58125dd1684583b355482a6b81f224155b4b636c31d4d715f839b3e69bb521bb3a07c3d25bf771b335402774a10ea04c120fbbe78c79d92d628286b8d9260109ae2863787ddc729c3240b4a5aab91d1e07f3ffe295aedfb3a6fc1df3f41a733dc5159794fbd12cd780f0ebf62bc856e9071550595f7dcfc7df18bf7e0fc7db14ad44259d8e416442ee12ec40ad38454f6c49f3a876adf079d4028eff1bf0f4af1d9057f1fbce2330cfeee6cd069dfc7a0148f2ef032cc72d8dd31c39d8dcda2b48e496dcc02130c1284b2a813986756c2e598e70b07a67d9f8252acb2b1fb38a5f8e5a614a9707503718bc8a585533cda57d44253dc70e7b0fb1594219687693c76dfb583b67f6633fbfe19eef67dd0e633ead98cf7e8bf9f773eabe0efe72c9fbdfefe09226df26fcad6db94ae174bba33ee9a270562d7c7ed2bfe998fecfb94dcb8acbb8a1be8b4bf4a571983a6a8df2a8b64ccb0311a4120d6e923ee705c031135d04206a926ee50b3a5ce0b1c1cb4d043522d878c052c46d4ecbb898386404d9211b51c2b96825852b366934ed6a007139c6a5ed25a0eaf75041c744c08d094b1d5728460946a4d3a2ea8d5ae668e5aeb0e917e597f689a534ab3412536cd295d6d9a53aada39252ee7df56ab553645799ebbe7ee79ee799ee77989a91406f9c3b5873a06b5e29a3ffc7ae1fcf9058ff15902c05b421c9266d3270224470391f29c94aa6e50731ed8a24dc005b4092cec2e40022e5c5515747b13b43c7a5e160e40d227ad1be46cba7952b0cfec28282e2d558169ac7e06db7640a98afc94aa00a13eb6d9940999d1d514e1f7f7be0002ec1a748d9aed3dd9c169ee4f841a75cd16e102dece6fc36b246067f32b7d8b76ace5dd16786d1bafedfd8f5359dd308759d13ebd621b61b7000281161a7342aca83e9b68ab29a5e92340f760199276dbbf85acf6e80af3f756abe5a2ad1331e8a0d6767f1306ed49b2386dfa250b6e0f60d32f37606d215fb6bfeffab06a52d13427c46a9fb47d81ba4feb4383c164fe622d4bcfd96940dd6e0a99d1f54dfb7a69cd847e162250a97d01df356a9a9a7d7be5fdbabdb26e4aba48c0c6660dba668dbd51726ead1c1b0a563814d0382525a160a62562ea61af467d31831dda6efa19ecd09ec10e5d71b8e22a130ff66ead0fb332287dda2cbff7de7b7dc9deeb4b5976e67afbd7e63d5fd50fa0d48dba4ff7856be4aa60ed5f2ddb5eaaeb63d7f78ebc5a246bd36004daf5a7b5d5a8ef63adf50a48a4b25776676d34857d33bb1d80987198d5dded5d001efa7c5979405e7201d7245bdfaa2aea3f6e5bba49f30155e92bd9c192d2c986a5bd626d76078dd927d90bfb74296b6dafc2b6d6041fdbbe953aefeeeed2dc1d8af265df7ef199ccc6ecff6b5b6b66dbf385855bf2255ff2255f7ae1dbe839534411ee3b10effb3ceff33efa7e6ddbbbdeb5eeee6efd5aea5f6453ace7388cfe5415d56645cf5ef4e573ae40c193450ee8d0d41ead66d377db91cf26a0204aff59a12a138c0cd49e6aab30fb6a363df194d62412dcc7599dca99e07f9cd2439ccc00d2e08adc2066a7420f3788a2b5dee9eeeeeeee321a2c5fc7eeeee1d3ddc660db5eebeed62f7db7ee375662757b3f29daff53139b6efffefdabb33aaccbbae8fb340b194dbf329dfd607af5d2d7e26bf18733189e2fa315d9988dd90040e9fafe7d185f30f450ac1ff81ab6ab5eb74817d92f2aa2ba22cf6f861029adb552a76eabdf7bf1584b10ae7d0cdc3fb171ded8dbd79a9ecd7915db93524aa901a81840886bef4929a514574a29a537042346e266837055a0d1b4cb0d599b76b9e16a9ff9b5f33c3a43e0d34de4b65af83faeb345ca35f07379d4835603cdef91722d3445afcc0f9648b45afeb03cea916bf9916835f045b7dfb66228d292525a9e277efb3a43e0dea0287e1e15c9f1c6fe4a5a034bef73f9d5786dfca26ba4e589b77dd13556d2836f57c055e3d39b7aa44eb5913a54671ba3afc71b0f5f4bbd7eb9ca5a2bc65a2bc65a2b06dffbb6beadf762319f3f2c885adfd620a6d44f2868cabd163f785feff17118cd610608a3ef58c9179e59690c630bd21a96392c8cf7f9c35ed77efd3c9dce637e213739a9e23a8a42e6b4378367e584891027488c70a2027973727382a4cbd9c64b075a2bd8f49520e40a4cae283ec625a556131f62912a1249b8826e5c010954128ddc4ac84b55a1911e3f3e2254609a1f1e0b53190b09ab8064bf4ce60e71f27040f8b0329a6c056d88e652630157a503b5224ab8a75b6dc8958b265561d6af264e76053b1e2401060fab8991af489324ac2648559ed28c4d6871d3dc13125e0b1adc34f774e5e249977b4a21f774021951ebd70bdfffd7cbd2683219cceb097bd1af45690a7c46f42afd5a64340f2ba3c956785f96ada0f980b41306c4576d5676d39c9398ac3cea2cd3faf5d2d9ed0f3ed31eab6fc554c60a1215242c2eb5f3226d27a304191ec69449c20891da796ddb9f9e97c96755ca3dca477f9ba5c3762444bcfc9f07858c96648c0f8c189ed3c082556f358956a6a8ed75aa6aa9ba17a6aa55cdb2798f08c495d6781187f21ef2fd5d8afbe954446c0ffde9e93b7f8ba464fbe86ef3ee37ee6fa5ceb875777777777feaeea79db24cd2ec137f4f3c0e09742267da83778e140ecca0830e56365b2de76f48a09c7176c1e0e03c75b2717098206d1c26416c9cb72181705e0540d2a7c66548f800ce56ab400b19272a6821e344855afd9ba767cecdd333fbe6e6e675d3957df32f1988ec9bd724d0cd87dbe65d2490cd05f55ffd798998ad97f0d8fa5b2490d6ae274920573ec7ddcad9ad16cf6ea1d8ad160c43760b862476eb5fad184ad8ad18c8ecd60b5d76eb4712a825233f8b2410a935d8e7b8c71784ec9109cb1e3f248146bd0204b62d3e48028961f8370c5f339db0c3a7543bfc4c02852fac0dfe470281375bb0cf9c9d735612c3ce4f8fd8f975b5bfc724d007002f97c4caf644b0bdbf2490a7976c8cef45b2c2b636fb899a63830ebc32022bb16389f014828454563fba271e26e824355fb57d437849469d0b69225a2cd461a04b394ce68446cc3901912b0245a4874d6e9a733a53a67a193d06323fd8aa9c3922a276ca30a0048609169090208732b5fbb2186a0434dbdfdddd655ff40983d999d7b6ecfbf7ce386822c40f2a38d870c309b5534bb972c410344aa48025047f60cbd4876d369b8da99633c28e18a16571a18c029450541f0eb04f1e2342446d2f02956b218c0b4f7efcc777b689e87bd7bb4c1c389a74865cff005a7399464d44ae17f5bff0b25210c10a2b4cd96c352397f96ff39fa96dcc7a3f3e6d3d298bd23f32d71b351189ff856f249a4336663f4ccb2cb2b1a8ef03f1bf270a9f347134d50f4d1d7ff275d4aa4924e2c0a13364f33a6afa9b74868c9a886e3e7ca3d6d7fd010ea45afb7e845afbdee8c6acb617c5274d1cf401b4964faa13ffa43b5a23df4647b570156763464d44e17b6f04be51687a7f56dcf7a42955a56cec338d5c0fd29af73df82fbe07bd371a4d1d7ff075d4beef69ed85e7a68e03f283df847f0c42aaf400731e6822891f3fc8906182625bc24cd4982da2f56afde8cb375ea890c02e5150b29ca8b4b67c5fa2b0b47036cd4119e2314187a0d1dc53d0f9ac38417d188b28060d094c2504c9cd503b7514d387b14431a9208c92a41d3d6c403326aa88e7a506c1c31305e456c531513bf639661fa825463d0603e12174fdc0c488904956cb8b5841f3810ac21337cd417dc1022ff66cfe53c73f5f411303b5659f54eae78a0ffdc2d2397a86203c581a8ac9f7811ebeb6c54f90d04bbf34d40a5a080a20301c59414112b2f439c0c0850710486a00c2040a6452a585af30e1e24179c01b7346281e1f50e2a989253a2d5e8a485d31e18e2cc1e170383a2514146467317e582193c982280b1b0e9bdd6000dda0065561dfbe0bcaa2023485fda9a0234f96ec234cb8234b7e60c21dc10509118163120954956a111434d90a2b5a6c9015016fbe60510cca42dba04153d8d73ce89602d6689975e1e98c13400c996c45fe17d40b87022763c21da94ba4bc1c51e40b94d3bdb7d67b6f7d29f7566f3014d58489303bf3f181f950d918da51eda8ec6c805f6f3b98f7d84091b56237f4914044b7a47aa33a797c7636686e88a31d8ca1ef764b52ba9fcf4f4db26f7f05154d6a6f9564e9e6991f56013a13cd9a24eeb3263500fcf35d506067261b963e3e5443442fcda4eb8d874655dad9a8b79a548b38d9285dc5705d5a2b8d1d8d9d142e958026cc63f6ad140ca9aa1830a4aa627c1785cf62c0aa6055b0dde2bb413f52b0aa18647eb05215f4e3e10f7b30a7f1c77bdc8cd142275455458e2278edec8407fef8f69cb00f86c27bb05bbde380dad8ad8a41c3461acf5b58ac056227d2ecac4847a32cf42ed23be88feaaaac965cdbb63add8c22196674338a64e8bed123bd27f1df12870f3a09845f74f283f0c16b6baa9fbf6cea7cdf7fe1d39a58c77bbfa85e25e0ff78919d81b4221957a77bdaf3142151b5edcbb0b2631051dd5724e3ab3ee8ef2fc6f7e2bfffe60d419dc39ce507b0a111f8a12e0cc30bdefb5ddd8c2219666c1bb8f7d67aefbdf2a9d68746a3f9d02f3e200d04414fbccf534d25e2d3684f7b22183188beec6cfb965665e78440b23188a8eea2f718c20efe4b7a70df9fe8567b9f4827f3eb9eceb9665309b5b1af9e4ff369002663f86c4b362cf9d004a46a92583343d698222390d1d181214ed81951a5a9089b951d45884e2cf0a063e14c119f0edbd206a820c1c08304626a15c8972f57cef8b0420e3d40dd6aadf7d67ad55469d0dd092fda61ba54223ecdce44f3fd693c3e237aaaa77a2a2a37a88860d0b041775443346cd034791cca2410110d87d9b7016388eee86e86d4b6584fb67d1b3086f28e66659ea72cca16364df39e6b12f9d899a6ca94ee68788f37e3fce77969244d77b7960e63ce6b9981698f3f1e44c44f794eb056af57b5565c1a8d2f3e7ed1e28a4d11c617cd6a6bcaaff3620c41f0c1ace430d93ee1454fc9b07f521dd5d1a930326465510923832ecc92ac1af2875932356e3c659f630d523b57436e8a934de52548d52ed2c9f01e2cc54b07ae6a15a98dffd64d96341bb39f4925a2196463f6a7a64617f40c87d92f7298057587a6392a66902c8e427362ccf88ca2d1613a55a7d65c0d486c9bcdb3de20efa15b7cfba268ea5087d9b7ddec6c001f805a2287115ae88144cdfee0a00b420211d09002919a55c3830f6550d88d39b2a166bf22d9990c862686f050a247142c353747177f85f7c89051f20397f9b231eb4c6fdb9600dbbe477ae07fff86e31bb28d1d5f3c9afe19f60e2a7db5f9681abd8de1174d9deaf74d1778dfbf36572450989db4b1e9a40bfc9e39dea7a40b6c5e1097dd6546a4575aa450d5afbb9aa7d1a60e9b5559e30527f7e40bae87d0962372952322e5c566b0430e3e10c1d2c2d20974b754c684201cf022268b141712743baf4a9b4262f2438f38644d382a9033496c351c39b21235377ffc00f573503fc0e963bdd6a963eb30c0f37de6d85747cde15eab6af5ead56bad23d8ec43ffe8d522e9a75ad66dddddbddcb62cb7d790f3ebf58f03cb09db18caae4c80316283922049744092c3aa8b112b6670e051a456ff1582a36d4ad30a253d746e0aae009be6a41c91932284a6c201229072aab5de5b6bbdba0ac12d79f31be90e7e8833c620f62ad582fc1f3b234da22f215c5d7935e12675bb0ae12a842b108602835806abb72ba5937ea1714b9a018227db7e0837190cc4a07956a58b416d1110a331fb620e081b465358713b0ffaac37fb396b5d6fff911ddc688a9bb5d6822ffe55f867e962021bb4368c312531c6b701101185ee8e3f93442426c771247f7cfb3c23ec2a841ca56cc5963368e3c3862be4e3bf57f4db10d15fa80a4d4d4d09f9080dc9d04de52277bf1e86e6fffbfcdcdbc267cae7b573fe904e46901aac6d5f4847b1accfbdf7deebee733dd481170cefdd091272263f58518ac6aacb95a3085455c1a8d2b9f8339db95cad274d23f25ba4a93334be8ece8b274d9dfbda6824dfe65f8ce3db98464d44fac737b27992d674abbc6153de6c4a5ad343349e5ced1047862b5ceb5dad77b55ad536e5fa203b739932d994cc65e87453483a19b62320483a19336c47365d900ca12ba220a1fbdd2087e9509cb2a3223445b67d19d596648782f2c51549164459dc59dd516d5353d5f6bb62118fd8fe17ddd18a6635ddcb265f14c720ca82dcf66f496ed1c77bdef0b839a22946f33442dae37b179a823475f0d7d13c4553a7de1b53db64570d0af29e53265bd172fdab755ddf7ab55a2d17acf5ddd695e194a0cf38691d3ac22ca2388e9a0925bd311eb768d76b974bebcf394c55ceadaff835b62a79c77b2f8d1b0a50a32fce8d8dc61783f8627769974bbfcbe57269976bf49b1da2dff0f7e17af5ffaf454be8ee22769acf48b3b3d1fca73d4d6808674c24a4e5b5f35a8e481109517cf3c574637c855eb6dd5ef774c619638c31c6f8abfa182e06fc10fc1004c3f02b8192adbaf7de1bde7befbdd7ef9dbadfc5170cc1f0431004430e400e40379379909237928de5d65895330e5539c3280b7db757daa471d8c8445eeb9fdf74ceddef7577f14717ddfdfa55328ea0dfeb55344e582e0920db7e8c7a64ab6ec5d73b613fde73cd182d744255e10f6571dffea6b31a544a0aa6739cd2d060341d4d1c3ef8f7325dd7db5e0ff0dfffa91886c2ba7847f18a3ffe681a8d2f8a7fc5ebe3bdf7beff8b6f4d25d9c6eee87ed33b9ac3de5e6befdbfb20d86bffb5426695d80ab6356df5b3defb9ab16d8b2274b565082f3ce4cbdf97bd8b47b0dc741c455016861f3e958526183ef84e32e077086210e3fc71e0258bd156acf84cf5ae775f94c5f814261660d31815c1af5fc18f6b590eb5accca2288ae50e29b073b973adb73586758760bd0e9325e0870ce32b193f2901035b66cad87a12c3cdb54d70894441b2892508c1e0769ee7f53bae1f9eec187d049ffb807159f568bb5245aa371b8edcb990b21324b23be864860bec94d049170aae0df90aca150e0f5962ade68931c618634c3f839e7b2d08c44ce995e9a04514ee3e6e989fa1417ced7ceb835c739994c6eef5bc290c6b60dbc73804198077aeb5ca4a63f8c992d298cdc66e63698dd6d2f787f7d5c076af52b75747e8f749bcf77e062e32dabd0b68abbd35b17c1acbaf4cc3e629bb91ed10fe1b9f9d91b74d10faacb8ba4453f86b1ffa680987f7d025ca82e6ec206ba7ec94574702866c624580dbc48ae8e4841b2b060a16af49922cc36dd2c473ea31d22a6a9575b51b7f8a6cdfa639283588a1c01ba29bec153f36ca921e5192c05e395a0be54d73515828a20b01071a96806022468a9020487ae4c0448b0e2e6469c2e344932123c6a1097cc2417ca201073f85213fc0e95e58a28bd4084d3a7e6c69e2081d98d00041f544067c3a62023c055a9d78a5cadda14461284d4ffa6a9787656174a59a450064b1d286e6e333220e72d096ca9a57d3d8f7beccce86a89cca14bdd2fed0abee6e1200f8e7fe3442689d9a1887b42c56f2c13e9540b66458a0f8184df87096a7e1b5f3721a033a1901de40a3e185c10f67b9619fb4ea860e4928a9c1696784045652188286245c8c30e16906275b7e7009962ea8c4cc996a5ac74cd5080000000033160000180c0a06c301716828cb645dd50e14000d64903e6c4e30958743915094a32808a3288a318000430841c41864185345b7015586ccbdc0c1ef6f85786aaf1e69dba69904e1e83bbd7004bd3afca149f1e349a8323b1dd05d5028f56c74d5b606383407423197d4aedb49269e4a76bdb0a4e7b895da9554a28173c9bfe6ed1177087732222487d2d595be9de00ecbfa5c95fb9c40253baf5e9a1d8c3a16586d788f2c80d18fc45a890188601acc7f1bd9fdb68fcdea738ff2665d806303435ca346ca0178bdbc2d6e6c45c208448d09a81ea8cd6e9463d9b0718ccc8003a068d71f53b2feaaafdb288a2f83cfb9418abb9a9d606900a71fcad19d358783fea8eafd9254f2ce529318e2bbc169cff1f28953118d034d809fde1105ba29ea1085cfe8bba022c77360a83db6475f0e8c538f5a89ae874bf447fd1e2b99a6a0f4481e9f2e04c2839fcb07863abcfb84d2870025d211f7242d40742c89d3418673ca176432955ed8200977db29f9b49f4d5a102cf5eaacc40667cc24ce0208f6d3341968f0167e24758002659bc284a447402408f3b49051038a62832f5fc738cd983aa1118028d213d83ccd6e1e3d500773914ee8a41d2c7de82eafe15f828b87ab1a5b6e8fd28708178ed22e23af414ce6662fcce11edcec3a8f7834faf5362f6bf65eb9b1bcd26ab4e1bbda1d3fbf69f2865fc4e6c647d7ef3ef8ab0ee90d9da4b0cd0af7b676e90d6f4b4fdfe6be5ad7da5dad6dc11b04d1633f6c4f218a9a2b5f9932c7db5bdf8dd5a127909b30f4728bbe9074431404f37a25583d553ed91fa8cfa415b4a0d73868fd67faf3f298618c4d64517be57bc0d1b705bb7d944efce482f724689dc93608ea840408e6b97dbe0cdff0cc988136fd9be76369bfbf48482a5f833b1fe6f3c1267e3b68e812b71c627c32f9a1a090a511245bc5f9c8df31c1d0a084122155b56aa0ce026142885688cc060c40ba9a24760bedf29a92c64b34d87af3b173cbfc4f7bf31d1bfd830a499d2332a8b1591a6ac0f57f20d81f921c59decf4a02a2c0e35af0785b65217c49d7ea1c908fbca4c29628bb19413e7e4c89414b4abb64444c34e87b99e3c2c3d7c2b5aef1fd862829cfff84f8786f6f30b5b65fa67d13e180fe70122425ee4cec0df7f55d30161ab993de71b0ffb552ad83841057a1815515c261d226497cb4f70e81a1406be4feb13e6aa01db7b877622840d80538bca1779658c6b7425c999a8535fb0990fdbaeaf25096738ef363ffec655f81910fad163e6e64a2ca9f29e02c500af066f51290688d8e40b4f6787c420e5be491cf04d52b220f19ad7ed3f060793c876421fd0f25a35b2242b0debf9d5467980e7915a7b63ad8849583e0416b9b69ee9c608ebdb584286c108ef9f48878facfa94167fbdf1c6ddebc0cef8d946d442516290b842e489ea020ca68a6d359594734921f3521b1937d5c858f505c64862937bb606ec3d1371ce16ad01a9d1d2abf482bffdbc8371ba5e3291c63c42de405dd3a1b743cc3f22567a5cc535050078719220ef54da684c66ffa1e119fb98ff6aa4db39038ff48568dfc632e922bdeb00c9aab971c15f1b331b2df63fcd9aa9487414d2762b3cf3c0ef5e208b698c7fbc5ede7270346fa3398375bf9c8a1f4618035bd55d413fc4231bfdcf3898c508c7e6b380ca19d91a3a4aee0f70f81acaa03d38606469cd343701fdb1deba654161157a2e2d298ee76c2cb09b8cd99def1ef88e56a5189b016ce854e9e9833cfc718288361297b71c25e18a43489c206326c93fa7164c8317c0142199a09cd46ffe7d0bc0c5cacbe33db0c3cb69a43f4b939e0c15e214ea47a1fe0e73e9f68b40afe0067351c44d19ec6dbdb704873f8c0e76c0ec74e2144c57ae06318f4ec36bd9076837e42d4f83fa9948be8f37320314df6cb225a20b6f63c146e759bde565260ac334d5a90bd07afdace17d8440c920c6e9e4c05d3872aeb57b59770f2e3f8446c2ee821722c2da032a07528c4094820b2b6bc14763ba1f3bfb0381b91db71f683989e4d64af9ac6b9d8567ec00d015c8b9ba018ba28825124b4f111266064631736f61b287d467e866138672511db8372ea9a363890e21fc4b3dd2b39c190595441beccee35b3345e0be00e04100737d0ae9fd7e2224fbe1b670e285abb4fbc9cbb404fa3fe5b2732864b24a1bf68899c2a4bf3bf9cfb4affa2ca9292f8080a538113ce27b9586f71ee27d6ce3a41dab2837e34b5cc63d36f1a4e4a54c177b10296243764957c4a9f28205f450b98e4312fba71f4ddc32e11434c237bf86ace59c9223f67e14931f45cbf4002bdc05cb7cc1b239ab84647d9e4fd06fd4dbcc88b235bfa4bea49faa4fcb76bb424b2c807680c4f49386e339a97a66eb5153c1292a943296d0bd9ce869e1c1a2ea8e211f4f87f3a26043e70560f8fa4545d707d9c809077d3cfc0a086c82b34e26bdef08674935d5221efba53ee93a7a436e3df8eb7ee03e8b5c958dbdf9b3eb550886c4b5c80da00e7901de4fe006f29e42eb3ff35b82428e166ea729f0f99c250329a831c1ae1c1320abb706b16de680165c512e54c94a0070602c909c3020065830df776aa7627bbca3c354c0f74f25b4ba26d9390c7f2411d366f7fc43471612f8027335f91900719324d560fd93b71eee3249a08432fdc8e9b088182dcd8e074c93e202e88092f3058cc7d28a819e650b1dccb14bde46f436b917107096aa5387e455e5fb966e193434948817418912af486ff8243d3a1e312885c8edb09ca80b7462b90ab427889f7754823881b108bfe0769dba302972f225f9baabd612c303ed4e9e8159dc38427cf8ea19d1b7264f88fbcfd2e88e8ee20630879b854ccaa87e4733b28b35850901237bb3b6cd1b9fee31cae773217b78d13aceb2e0744f186d588c6457fbdcc9dd69582e4fedcacd2bbc0baae083ed498f28a647820554f19db783eaaae4dd6ffc6d478bba035172db8794281584541b88984064a47512d8a31e7eca862587063b83df7cb55b6e27d27417ba037ffe8f28946fa2faf960b9b36046053deb5d2227de6c38576ad5b6202086cfe65fb7eac962dbf059b09d0b99a2a445cf1c4e1aa2f1cc9af97da036c5a3f079c429c5c07de970db3b87a592a0dfdda913213e86f6607faa54fb453a0b8f7dc86cc276a6017052d1ee069c059a926d18ee1c386b70f9c7468d43454aa163c1c2edb9fd0e5b95e70ca37cc6b352da8fba9c4c9c32f7c48fc3d555c837f4cdf3f1a9dd190dec9ea532848efaa47743fc1f7cbb806336e4d04ee726ebb935a2752a79294aba98aaec1fdbee8e77d7d3b1ba83a1e3a2808c91baa09fc2fa0be51f82208fb54699a190992087f5dff61b142d9fa0c5f2020d555ff6e5a4f0487e4dc2f77e374af101810348faf88cff0c3f9477c45c92a2a3c699abae58006ad47936dc0db4f0c017e9293e887cc06702dd81a23f41ed0e41d57b0be89046b8f2f276d424de8a56eeb957fa562729986b25148d5a4d7e02c94a3c54e90b7c343e36c81b5075bece1de9d6189772b00326eb82d8bbe959c1ac9c5425f2a68b443c9d616b6bd3abd58cfa85ca5ee7fa804111726ba5a688ca7368088848e345a5dc34e50c86d05797578e06c5cc336ff12f84645c129da21e93f927cb210fa3882e991048e5d3f30eae50329b5311817e27204a757f1add7d333f2b8fe19dc0a4e369120245e98ef8d471104e68a074cf051a78b8a61a7df36050097370e07a0d23caa471dd59ea78205b48a000c90d54a325d8581e3cf05668bd4d8bf568e1f82393f7b59f90d8a0d79e8084312137b5ebf957fea1b13797e63a6ee4f4295ccc33641fae98ec1545e31b3ed5bbf2418b804e98a642654b373213a54d0a80aadfedaec416b345315bcb551fc145b551809c232d70dc294672475b2322cc30d087d59aed1614a069132941bbad24b95e2c2214f746352af41903d13ce5193dba59450997633efb14f420cb2e4e20132b3b25128236a1778806adf43f5582196cc79b06bd9504e04432e1556fe7e57bf920c56a0a008eb3ab52c2a64bb62fab337a5ab81da2714a09035ecfd6680debb66854dd4b707435ff2e57b3e042cd37a385b13fe8ef882b31b5ec07458279c6b6b524b8f8deb78aaa405e0f3acc7ebe46a7a14f6e2f04b5999c90b945ec49c2005e83115f7862f521378e089ca2c40b40628b5688ebfc4b26dae68cf81b591d40c939845f2f828bcc05b59e045e21d58833b6b87e02d2cf1737c16a3557f72cd8214f081c3fa7e2b1bdc5059fa141feef5f8d8110dc73a962f9454ea2f1ab093f857c7fea5a2fe71b86aa8ed00bb14432d615701086696d9b54b0c514f085527f6fb6a1b590e7d184a7b4ed6fccadf5926494f0eb7089aef87243ee4073faa7bb797ad1213495c7de4a8cad615438f4178513c6a6bc4d05a1606def9823526895b8c7a119acbea78c515e7d6a23e5ea05d7720089d9ed003f30cfd487f72ad62390ac98e46e8a35f890ff4e85f0417e89e33cbe1eb3a2bf8d673d65a7c408d16bd5330e270877d9cebd4f093d4f41a092ae15cb9f3cc217bc38e526ffb78a6368a77d317a7a78d766496dce5c184c3eb8a751213b67629152dfb0571d50ec936b824b57cde8d8eec6fc7f6d33fb4700f12ac5dc3b456cddf0569d7f637b33a1b9c04335db97b538087e582a1fddbb25673497be9d1514336c571b2702fcb50d46cf9d96a51ab8ad6ba9426d02b8db3cf066464fb342aba7cb72ba58149a9eaa4eed6f69f57defd1a4852984492075b74ced56ca5473b675d764ed5588e02d6ae5c1b23b81529f5594a76f158dc4a1bf2a7ef7e4ccffb806758ce7ce6f66fc0874ee0caec765452ea818a83b79e29f0be6eb698ad560a92493a26deb8593b4d46545c2481cab6bb9fa8dc88431f6c77a306e0a689c21bab8a6d365d2a6dac1960b213b0c4f85cbf43a8455017499d2f0e00262a904d06a64929391e9eb4af215995149bbe29f69dd106e12993ea814788f8f37bb04143aaadb4b9798707c51bbbc1764439528be29535d4f07ec9c71baca165581aef2a0a5b83301df3101487e1c60e201c48e15e1b46fd4b33b369526218799abc456431555524037174e3fbaa69cc24b61ff3abcb509b4bcc0f584d6f30f866b5d265085dcf42d6763e56b7c8b7755a346ec1679f12c5718d9eb0d977398db328917c4716011a2700d287747e20c8516f8fd31923b0de0aa136eed421460e2f0aca95cc0d6630b8fb7475be59c62b722f1dd31a2757c741f0cd333b2f0410f100e7e79456d01b598c64f84635c85509d40718c54633ec55fa83b279af7e3750e794ffb1cf10d382026ec22eba4daca7d4d805b476ac8b25b08bb09bb95b066377540bb29ef93d323a20bd6e55b0ee6b75a25db9cac0abc613182a275a9d3a7808cf0aefc1860f448d721f9d1140f53603fd8918f5a2684a5a628376bab4d2ca558197e97537deec9b345705850a416b3778c7ad2140a33eaccd8330314b2418e4aac015efcc0724a5c7c4abc514fa207e51d133621aed63b9dd2408f0727c438aa3ea60558b53865ae46642c7fc10d80244431cde2061f3d31203b313663bc26cdc0d82df014741e2843204cde331c25fd108750382ab265293725a956dbbbdaa10cce61e065608601d18e34bd1da9552c7ed884d7a8d5bc1fca3c5416bc38879ac3f8b1359d067750f916b7fb308ecce26ba0bc46040e914e1b33fb440bbed97dd79eff4d8b1d439974f5ae1206c55c61d18ea7fda3e35972e389de6757a429deafc0a990acdb7762b461eadc837c03cfaab1a73fba20771a2ea264a1f8a76e3ef6902d69725d7b2e1dd4db45bed7536f4cf8b10a62767bdc5cec4f163d61e42ff395391356de6186c2b685db0332edf2d718e48c371b9c0861dc03917c8511381954ce89b53a5763aa95c76d44911a9074e5ea15e985dd93a4b511d4f5d36117d11497228176f136f1763ee52f08f8b1086492487db2f7e5cc3243965235c8791f9947df413042d53e6deb58ddf18e71ceff4c2920dc284e330ae419a20e3f8d33d2e64409ffb2dd92677867bd20893ed4bda273cb61f9360a568de645b4534d9ae324f6413a67cb81bb99a848d359be675d6515e736616efa6bc1ec74be20f16a9cc4b1e0ac36956e9af4ced3e6bbe0a46152ca4e97d5b233ae996a80b8fa52ade01ade461e52c046a75792d82a4de986411d45aefed7b9b3710a1a6c2484d424a217ad996d2ea250c442f44abcbaf5c22083ca35c484e15846a85a396383a266b9b112b6e92eba62c092fd936df116cc9b8810154a141eeca8c2ef6a67dc17b033bfcf0b10676aff736c3e96e375ee57f78b107b80dd7981d935cba9af68be8a4b486e2aa33a7f41c489d86c389d9746b66e61641c1104f85d271ed866602f76e190e56a2554b907edf4d9493b2e9b8bee922ededffa4f9e0a4840096fdc78bf64f34541f187a4132f1ccf1fdaf2e610d2df06453d8545ef061802cf152f9be71531f6e8f44f232a76a7c5ccee9e94d668f2b67216b4a4ab2e946793a56c7be4847fa2c4a7078107913bfd4cb502a1d879a1bd9b2c5e06d9885501fb597d97062fb2135cd73dad087209bd9cf4652f3833ce8ccf4fd09c02ab0e6ae91a97a308f3bcc07755c6467570bb562fd0bebc74705db75328b89527b200cdd6aed9611599607e434b840595168ac306627008170b5be7a1cfe6703b4bd66a0281a2ddb0091b5f5c50334aa811fb845eddd2f38b41e691979467c76a6a3cc486a49426155a6472113901d65d0236710e034972207db8410a4e95d55515d9a07112d41d611ff082fa51846bd366b936c497a6227d82e9acb6072ec9bfcbc6f1c37b477d7872fb74f8237279eb3cca53aba5f51b50fbe6acb6f2d484cd2ac45811e8c46018c3137b49f1e090c4feef15a445e44abaa1be69e7119cd92f41f06bdce487ac77a592fe480c06138eaf7d42abca5675b6ab407b0b86b5ab59c817ce14155ca7cf24665273ed14109c981541ec700ba81fea8488b32f9fa77b4cd562d78c63b4d64c0060631fbd28fdbcd16150b28ed1b6bd318059282170015f717a77cc717ec12c06dfa4355052a01c3397d252be1c1bca7f847fb94539b08fd2a4e650844c1af54cb7817316e6de936e3814e5b4c2afe1d15ce194f0cd3ea45b068624146b6b34980c1375d681b1f384e79196aeb32cc5ee55941cdbf97dcd77bef71975ec9c2997ba12fa6bf07b07107350f13662eecee6290469bbec7da6e8c35bb34a10af2672b98b0c137d228c2748aa9285d610a3b18c6f1e649485525c4e825eca3094c7bcce61a2a7ff03b00416447cf35ba9f36115042dee6bd6f613d3a14394a616baaf0144fd81d760fde81eef81a9bec74eff86af4cd0a1e96d77641d8bb0fd6ae091de49e828519534d4ec7d8b041e9bc278c1ff42ad53e1e59819752d32639aaf9b1a2fcb25e64d4a87d9cf8da6973f07471b93e7e812acec58785cfa47f9a237c48505f5297a779dd4d9835d97bacc77e56128e966e710f3eab1c1e68272ee065a77da561b04c3b2d6f28c0d2b15a8e33eb9be8d1bd3ab2433b09bc10b2c6911668266babcc80d234cfc70432f1f84b517714b9b0a9231d5f5c2c0a54b7d3c922258079aeaec013f28073f65fba2fa682a04978ea84efb582efef8cbbdf7fbb51cf455fab38534d024a10ba944cd6c4424801ab2be87dd40511a8e67a4181f8185ce1e087c4456f265e36eb00277a81ecea29328e931323b6b7b24d8288527326a9d0f01b69af006d02cf4e26ba020869fc8ae19556e201afd5a36c1f7b12414f8c2cf2a54fd2c3f997a2567319454420cfb222c98513f3b85cf616e4090602c4f68d3dfaabd1b72c1743e0baa4e25a4c8a960950d0b6b8c44132075810cc149e64d34a47fc439002328945395962e27363e269d845c0c1352ecc1a08263f4012c4890e0f98ead9ea32ad8cb25e935771795764158b542a1a49f4b8a2ee36cf16a0471f9433ef4bc3032a81528d39c84a758995840fbb71c603933d44b99e973cfd85b1c48112e7805eced75dc448c6b375d50301060225832fe06432091159f42ea80606d8f7453fda9ec15f0653b92dc008cde0c6b2e5b3906097a03f197f7dd9ef41706482196e150272d3f302635806ba08685ad21f0276a0f31d7a0a506f065006fe062b9d65650120fe7250d5e7816ca83ecff36c5f11959b89c0fbb52d6bfb3f07e58fbbae408b302374f566127738f3242adb53e465940e4f4fa704d8560c35cfc101d386c4263239cdfac1dc1078c5b126d9d3e47ed1096a08c3aae84df404cb24464528277586ff228515238674a8ff2cf266141f973cf340d6a1ce789823b36d248a1c24c46191d51c837cf0a067d31801a26ce85173225e5e19ca2487d3f0e43c944671b00d3e100a60751b70df78b6e903ae0b203a0494cdf3e9ced1551de8381f78791c19ec1ca20da2d51bef9f8fb5b3e3f8110421940f52b17c17660fdf16c900cbaf4f73d95fdecb67e8f369562301d2e2de5e735b2a7e91c23afc8f714d5b70868f09eba9dbc16fec4cf5e62597288e7124503656183ac13efadfadf61276a82ef00ccb1f443841304a4cde1d64228fbf20ed5bcbb4d4c36618f4c6f40ec4fe9597c184968a6027a828676bb4e4080d08f135f7f54118011103e6cb31500d67411dc1f8d0436417db2ff308fe5f42bb2a1cd9267e96dfe7ed4a1b6c144fc5901228136b0330605e5dadfc1b58eac2ff25a55483793ff6a91d87bb9f86abc4e3da476245a2d0f85ffcceee26024d8de8d202858af2aa2133800b03d7eb2487a806e8563cc0e8bc1675fc8ce0a41ee54fb5825062d150fb3cac0d4da463757d2054486691088527ff81fe7f041026243211e61d6d8c3300a8ebc11808a6e0555386a255c11f5606f166d47fb986101a389b0ccc3fcd1a00e3e3917dc524e03f1d758caab4cb73137438478f5d59948ee8dd8738173c3e8cc4a71465aaba9669ca98c95b9a690fc058fc893335fa89448bc8709591f65ed233418d11632a9e144e54d2d482c6b4c828292e7967d152232c8120b035b5e84a2819142d21425a02b1b42420b21515237eba448b0c5ef4c2a49486869f7a6b7cceac968fa6b2076c147f5eab9c3936cfe45a7a3a4f794fd69d7ab48ef56eadc3e08ca656324d6ebb96d7bf7e7755d8693ad0703429d9b797808ec1237acb0f3bcea1f1d7c87874f41504866f2a49c70546f4d26a83358ca6fd7346b3eac6a5e47c0475dc86b8a2152c3e099491c1beefbf40ea823f90a87d44e706bf211e3bab535eada90c71ad2747bc3e5ccfe6d4080bdfc7cc2aa9bde5d97fd1118f9d1eaa0a1950b73df7c97be78bb5f9dab101723ab48cf55e3d08b93c2230c3c33f91eaf4890e35db7790fd359c9a76ae0a1990416813c8bf096f024bef4773b42d172ce93e7503cec217ba8436e14af1c125fc0e882f271ef5d2f67f18a099701f21a2c2dfe2a4057af0d2c2af1f3f88cc4e9f97be219920930d83d2a51c50e15ec438b507b1aeab766e5cd4158ecbe5f5f1ae691c6e85187907f99ea0e42e5ac2e17473609ebc735d5a1ee5e0a7653c55395d9b083b469ce724ae09786859b2459fc9d76499b35a6df241e423a6dbae3361fef5474087d743dc634e0f596c8d926058aa8fabd7fc95d40a28f959587de0f31444fdf12b1df6778ffda0e010fc1cb15ee6610196d2c064f20b826798d318b13d8c8c3cc31c3d3f03eb59d03ec8822f87872710e2647401a8ff4c604f0ca60c4345124198767b161f14ad3b125b4387b067721d9826024bacb1fdd5f11d2cffbcc3a4c2e12ea754a2c192058d99a22125f0e138b02560ef11f895548eda5d70cd7dce266689e5f2a190d483162f6c10f6d64d833a987357388b3b84999507a1011958b9ced301cb1c0330cd4eaee821530e5bac80e0af3b2d354cc505062320f5ccafdb2115d5039e23a63ecc543e66508093d5c1a90cf935a1f9149e49c2b4d389591cd7cecd2f40d110103572c5a43e9b211fa77fcf5fcdfc24cefa9ac055c7d421d5514a04d5e7ca60e607c54e9e51b76dfd7113d9365a5901a9b97069085982cce1d50d79497016c4f3b664ac51f9d582e86da236e02311af405b23451b8a56eadf6efc11f466dd2e34020b1930e976dd4a9d028286153913d3603f8cdbf78197717f897832656e5d8b7ec7c6dea98c6571768f51df77b62b0127294638148f123310cd57aacbac9efabb2193886e9a0355af30d92f2a7d3c6bdbbf866ca1fdb804bf805b45e9c30f75654f6d70a613538490fde26f9c99f664dfcff38d4815c462d600b2517b86fe6a5517bd84faa3cf0fa897161e07931746db9e0d09e8249a031f1493315c8e2d3848cd0bb1475cb05183538c8d4b109c1936baad158747e2f14c007c2cd2c6298682fc702b554886cf299e75279e2eb02edf3ea6af61bf32411a8d45dc0fea2a6063f26bc5d399cb8ea19a017e720ea824d685ee532b832fa26a803f20b4c0a6b7c868783b2d830e5af05fbbd42adf052dabd17db8b520016091fa6ab62f8739952b67f020df9b1d4727f3bcb05d98b43dd1c8c6b4d677d5a3528e9f74ccfac32c65ad95b0940965837fc5754a94fa6810952251723277e03cd14e5ea3e370f59f09a0988b3c43433d89958d5d647a73d4081dfe138ca813ec58d784c8dc4cfd8dbc4d9ba046a9fa4445a72764cc553c9cabc13a2a9fbdd23c679468e649d97de525fa8ea1408b23efebac00c7d2f4493962f4e46d36de64ee3c2addcf655e6b3ad41f22de3dc016554dc4f507fc7a18a888cf2fb566dc666aa34fd66a68283f05c126f3afb93638e94bac95ed9c954cde3ee0b7b1f127efb0c2ab6f05188173f2a0ecb468513f5ff8f3e1dad08e0b182138697b00eae4006a7f075377c5d782874243ccb977adbc4c6bbe528374da96a17331b3cecfb930c0a3a78fe3595af9e548ac6bf29450a98e8e2048d3b80112df060cd74ad0c9c23c5145cb80dd595ae69bd54bacd28a40134e8e8d9687f1b09448e60318e503a5eb459e311b1ac59611f0e3f09cc3cfe3ea529e3d5c26eb6484a626e626e4ea7e89d6ed8c8f5483b32afdaaea80dd741e19e06ce60fe710fde477167902b5c0429688220f636376f551b1b9c29ae700d6f5cb6a4d075543bfb5e6777cd008c04ef99f9619133089b4baef00d0131fa17c1d15a138b30582518a03d456b7e1918a88e309ce39d4f14aeba99d29b2d1923dc607f5153af20c75532f710f83f5e819b2d170b2574a22546d2d467ab0501989f2fa17eb38387170d291f5a9287953800568832f82cbee5a1f4936e5bc8f4126a68136484e0bbc31beb2bcb8c34f9400e264ab852d0285d451ba42f8d36f8a31ea5310a98cc152d776a69ca3c9052284f6465149e8506020c818470d17d80c259feac3cd689c97d4cdaaac033df66609a003bd04ba70a4c3c3930ff431658ddee4a5d989b5392655bfb42c8af1697b38e4255d892cfff43aa4b7a022e847347890333a88b7429966f42b6e002eafcc3659d9a602005fd53e7dee28c7b5d0b4ef9ff72c892f3878683799cf048d4796ac486b9679c29febedc5ae1f17a54e63d77f452105823f7d75438a9c524a8e2561aa374d03208d7a24db0e8c89a469058d0fbcd08dd8c51c0b79a7eab120fd26045219ff4f56dd8d9f8adaca19c8750ff6d17313d778a5bd1cf88faaf830aa5802a2b3e55f1dccede12d8bcfb0ba8dda8948f223cf76bfcec4f14d0f40deab4ed572a14429c9a74dd5345c3b8777da29d99c7f3cdc7f0d2fcb3992f03f2f7a646293e0d64ec0fcffe6f170ae9a4964e4ed1e66802b580215404850d54fc5986c0a4098df8b9eb018f570640f35d923518837e3d167d1e15e241b3aecd3b0bebeed7c0d8f6ff661f2c53090fa3e7861b2ec784001c8b5fff63543ab3e0b92ef7675669a6bff419bd629d6929f43de9592e8bec8871d0338536b5f1a08606cb14a9deb72e0ce2086ea6cb381ec2f0fa953873b7542a4919ed4e83f44b2dff0f1fae9dac4ff07f02b76bb1e649efaa2dfdac7d381b28007658c740d0b61e52a2f2d41d9e8a64c7aa7461f355c9435fff163413baeeff1f22a431f50705d733b847e605aa5e2e43820483034fcc8f7a6b517cf150b3d0840bcd94a071735bf8df3efcba3bc07b285ee47cb792d8dbd976d5ca5d4b0f0863b3edb834930212a08f707887af0d35c07076919a566f3322dc4fe7959c88570ff8b1cc781294d518d61c2e2a93d43d8defd69bb36628860261d0f6e431b98689751bb0c7851fff9ef6ffa914500ac2ada05aac6d54b49c96a04fd25e38546164818dfd72eac6c4c77d6eb0701e0242db1b670b82ea613600323985c379df292298519bbce9f47e9eebdbba487fbb8fe423c5204d7d821ee8aea693442a146e20880ca445beb0703f8c45b0498f9ec91acadc9c48fd966578c3643d6a465379194dfd11f70f1562a8ffaef8990bb34c4a03827a85e55aaed4b0124c966f9d72464764b176cc3ecd1abe874c7ddeaecb90638027288cceebe9ddaf05edb6018c244e5b87d6e4ec06326f712c2eaf3db196d032380d36c93554b48c08d49837a29be7ac53e8489ab40e125f7c240d6b4876a80707931e0840aac1a47c0b572a27887b5765431eb435aa4c54bcfc06950bc8f5d31525ad8ad0fc0b12b7f82b12135a3cc9e8905da61c43e23a6aa786dba22146cc63884ed8720de5b0c1e983df7bb03ea31023330022b28a81e9d4b5f6fd0ac40491062341e8de69423df9da6edb8c422cd6b5af0f157938b0b77f573c3f695287698db44288f08e43a7b508301c9041c1d07895bf047d3c4936a591714edce30bba755d9fd8e151637812eebe9e91ea9159260f245816fbb75ea5313d2c839258b3cd9c00b950d182cd43f3a83837f7f95dda8dd3d06434f9dbb95aa21e959619c652268883feb34118d17b355d65dc6105e751ba451d9dd6360c842ca29cceb157819906a4f31b82b377bdc6eda5261c1abd283bb5266c3ee5e1b49175c1d34a69ca961bbd73271c1ad481f8e8a99df58ddb4a9d1022bd3056fe1e6f6409b03dab62acabead90c2ae2b34141499acd61b8a96601fa8d5363b5a3c7da81ffb66801f7aaec5c49769eb1ad07a8a43bd8646d7cd74fa606d67ca11e8e5613c3a4278e84c9ad13659403f029a9274e04f49edc7569d543788e2b454fff3994e801f3c37dfc053cabba8317d083c4ac60a22904a0c31122e01363a02bd4c26b71e145d74a287107320e81949b39d0952a0a83590f3a45ac0f8ad1ece13520511581af0a818a0cd14d09c79ef128aa4651b1fbddff0a1f0b945801b811cc44323d60964f0223b0f26548aa081a76df31729d28925d3f6f989eb61ed4d9ee0a64ca18b83ce3e5e8f35de4f50b1e5311f9baa0595a7d426205d4308d640b1460f096031bbcfa25795ea00b46f022fd92a7afa4a0b4f6a1d6345345afa133f2783c339c00042b112be51a90ba26c7b0c4648349150235f4d1c949b0c53a1939e41c4e5eda983dd65568c45e8beba26b3dd8efaf9beb2e288f6493f5418f3b8be3e0aa72a8b573f4be9410e0b0359ff80a4ed23232a70bd9d7a691677ca627e547ca8017fa1e6511087c87ae513447d8c2bc35ce6d046f7ad717bf22e87e2507590f20e162aff8b10d25258225b524850a4606061a65e964380608bba6d5e3980f953b7d77d99203f4511fff386debf55dbdca113c607626ffeff678f19d71d31cb77902edef1f5cf0326d274cea6b9a35fb372f66b871d5f3fda20c6d17670fedc09828a9773751f6f9c92514ea0a2db0707b159126d4f7b7bf3449a1d8e53b39152e0591a9ccea84a0407bc060d1643332ddcec95b93627cad454c7996d91739da05819fa5095de7e3beebd982928791103b7acd83295a6952db30e54c814c4c66cf444bbf84c7731268d619e51b79bb4c1f811aea23782f1269235b58b1c4e6c85b5a945c856c23872bc7ffeb8d5d0b67a9885b5ab384c525c8687cc36b29a51f7b3cc3867039f9e9c87147115abfe7fb731cb4705c4de735675bb8ac3149e39ca4c56c223d8214b7a91430fc49bb6a77873ac72cd9d416bee15486d25c7f13212027026c2e5169b547220c54822ba5572f42c88445805e34fc9d18cb91adb3d8e46429533ba977b053f21a75416c424af4638f72b67aa20d27b87d3af122577c6f940e3ac3f1132d031cf2f1fcbad76c6125c444765c09d1d24d15561841b5b98911f616110cfdf71e699ac6cf4cadf483641937f5d0e569e480787a5168acbc5a752bb231337c5f46e79d3293a8802d5e74a638c1a0b9ed0a6721f9c062b5f155314caec5afb6ef358ff25fddd5b5702428596e845281058a1366e2db573d7ab8460cd1e2f928c8acb01bc65a7608c6275f1e1b4b6764c196665ed58400937461652a9e72d82a0a2b040821987a97aa46598550bc0a86020aed149325091e70ad081b02b4b54546fdf23c6082a9c852b83935466fc34de472a816e751f0858340a4e7e3d28ae11cc2e700891a6ff1f5971ca8d1231ee2054fc0a313ff5ed44d606e22c488d4be862fd6d29a483f7233f69edd40501d08db82f3d08145a2176b8146b297aa2cbfce29412364765eaa91cda91f9f4bca41001c739c0d2f316d0270b2facf0578f5ba21fc77a2b9c07ea784fa923f1e0554fe1ac40ee65fc044f1974471f9968ca4c80c32484097f98a2d237a8ae241e4459f13ccfb193c15fc0c857290f7ffdd41e7ecee079ce0e040854fdba9078ba352527883c34f3ae5a477515841291234fcf468aba74e4fcbdcc1c9919054b80bb07b371fd9ed7ed32068b2717574b70c47990a39bf5197643e07f03ff488b929b06923384967bcee4544bef32fc1960ef9c41c792234432f35fd72a49da66d61faf198eb0ebb9268f2594329356043914027360436fc189d160a8fde9c126a1977133f3a6d8606d09ac0b38381b6cf6c709041cf0f1926e31109ad9ad1b1d7a642464a6df3e730252a9f1fd3907f6bb5bca8db9236be2dcdafd2efd27b38d50a8ed040381ce510b13572e292fb702be19ea78739036d75bcef92f660f718b4b4760de8449c22db76ff0b9fb454b61f75c95dd226c096a8531059aab6edd95156f5bb6772967a9d6237f1756812fb0e256f7aefe8ef7a32f2742a89252aec81d0e67d5651636df5ca6bb0311376d00be9ca541fcb950db0736339627b2e1ad5110a30cef22a040e0e7d90abd368848190672b6396ba9ab1b7c256b250137d5985eb595d996999f692acde3219d72b0454c30974e34b6a0f1c433dfb42c0d286b7be6efe041f0b7c9fbff3e66b1fef4674993ba060104299088290428af438f07ff688ebc8f3169371441b0c979af68203f6212e23bdbb9a0aea3d9319d2b026602a6740950283fea0d2b174712580710811b09626354d30894dcd81237a4288adc42cb70429c8848587154961ff0cd1fcbc4464931664c69405bcedc3c342c5aaf7cff1d60f7a5cf1aea9ad38faecd08370a7a1913a617635a1cf6db6777509b894832ed1e25e0aa5b703665905ea81b057717ab349d384a73830450ca8d0d131e59f8c37d165c07fb94082cf6d9d36abed1d5ac5b2f87928b008c6fb4f5ad87948c1c0798bd836a3cd2adffd6a740bfd958d69f512c7f4d83a89ff1423ed42c99ef982199c352826338d72aa11c2cd0920cc388592767b7893f960f9a8be01889b4893ef31457a3a7b86cfe25987be0c1df8abc36c982362750273d4029d28a40b23a890ad545f5665b88eafc60b3391f7e3465d1b1b345a817342250a6062e4b0c7687105b6750335fd8caad42437449d4c40e966e92d1f0d4e12cfa6581a5a43878fc3280a178017a3ccc35eda2ab026aa64125967f9868880ed8ccdf2add06241ba2a0e27af29681a6d820f41de9d9747049c0ae2766c898ebe43fe388eb8240fa9142d0cef186bdea2e9d73b8fcc6e194bfb694cef93aa93a101488014043c55bfd94a8edf50b816c286e855aa18cf549a59b0876ae0bcea75476aa2e8ef712021fc251321fa05fa7fddd246a3aaee37e80f12f4303368cbcf3753026d85e9d520260d896ff63fa6676e6471deb7343f046bfdbf2d44035f3132b78c0a9649210c6ef7c5171c9990a9124706179a0cd9d7020c5ea9fac30d54c7af23be473f821af4e2f5e5ad8964a0225fee3916431d6bcb1b473f4c53b98da56c463d52307346795a5fa7c7b9285113ab71eb6e9f6120aa5fbbc1272662e3afb961a22e5ec3b8f2fdab76b336ca101945f86c0753a22cd9456984d071bded3a5c0b4688213a8269231d753df6835b8adfe0861b766f2e326b5be0345acb544e7011d692c4173e4f11e225bacf78ca31261a03f13b9f85756382d75fb9962917dd49af0e73403ad6155c9514ceb3b441f1ec3ba306d543a0050823e9a60ce7a9585eaec2fd8690bbed11f2a1fac39eb3ea852eb796695963c188f0afc15095110f2767ef1cc9f28f21fc6b73f00eb665917283300ba7c480c2dae5dcdb2a38dbf5c8c22d62fad21633fa38402a29942160ea965a4d5d2886fea46e27e3bc935bafbb8b17d99a8a06a4e8e6043ab07dbf37d7d4df30f74be79e2964e9955802eabc2bc404d9818cbcbdf0b94a6c3870ed9a22c0d95e1f5de9baf73c51e77ba45301efdfe2f554e2f49cc343bab02a3c954b6bcd4143ecd12b96ec413148558c261fdbed28956b7a6089898f7dc31f387fb5e6d21b81211a4cab8d3af94200e080ee796122bd6e9222fb369973102f61d2b25bda5a2d082f8c6557d4cdc4da2b6bac68f879ba994e2a90b8682deae2bf5e7451e4686da7208d100539b369e271f5dda65f94559423a8a2077e6a1f06f8d38877ba8d780bfb6c7c618fccd416e44bdee261bb0ef637103ace8e3857d7ae7c8d50b579bf90a97d68050852b9927a04056ee82615f382fcd319c2e01a3b69112fbb8d3f2fd73c13ae9c91d75af646a0e1d2fe2de92794649528f11c30e801ee92a8bcbaaa98153696827da235ec74ce6fabb89c33aca65a83df95c325e63a703fac104dbba6f14143e1b9fc4c77553ac37917e3512ed1fb63e95db1676636528906a29fe2c98aff98ad9e2148b568e664c1d676a4a19e1fc6cf49c804de3ab60606436cdbe66580b9a68648c402cd29629868a6fb50dc9ba955c543eb7f4de9ec57637dda5f439f348ba6d4cd5f8f3af063e70f553bd0081d59a7860ba8a2211b3c1a69fa9b80801d8ed662e1366788ccc0578acd3e52cde64fcb79990678ee0a5f1175a394f1448e4758efae71d436512ab5fc0eca30c1153b149a587348f03447e633ef0a90de0b138cadd68ff1e53898692ee88deb1e22628090338c5c4457ce1ba3bffc2cc6231f07374817dd6dfa6933f6ff195ad2d583d258d2060e0c691b48b053083c73ad2fec5157e9d79fbe00c09bf6a83a520270ecf361e91d056a0b56cd5dcc1d290f560ee75d6635deab9fa174b44659101fe66b34a4a4d155c0b482039a27aeedb142d02dca2fe8fc34294d87aac22b2f95bd671ab6339449e5d5ce73c99a3d53790f2475678893dca9d073017a30fe4690ad538898fae52edd9c1ebbb057f04567d3f45d2017faf1b9685ac1e248f0ac6800be8823dd9d1dbd1393ba46d695fd96bb4df7a92ada7b3c69ba1399d883191a2b420b6b3224673fddd5d01aba9d121d921e6170f8af7c07a1dec99d6624d3568af40a232f22b48b071f5cdd50675bd3b87f720bba11b32a7bd7df1072eb7ad54c2d7e68fb927dc96f13b841c81d544375682dae50b65415c0622cda543568c4847d7f6e9048490132fe25035823f2e282d996e128a7d639efd0ad0b475428e9759350d6210074dd286629608f6e0087799d7bac38f7efdf47eb4dc4fda075f70ece4cde8c9aa3b80010a57d75f9a59f5e97218011178706be3315da145881bfe63b0d057a1b0fa89909a7ec24651fd842e875b801750462cbc4b176c7727ac676b044ea731a84b0b9fc10ff996810db4839db0acc2cc9b11f75f7ef7e00d3d4352acb951ecde288a0da03967e7b092135fa2d5b0b8db8c375898289f2a267e2e88c1e34cf6576a75fb9dcde364d7ccf9be20679604df797b8f64078c791e298e28bae08282bfee8e798dd3b0400c9794e89757157c294fecacfd7551863c8610101fcf62c9cfa7b1c074c573e1315fb57e8187798fa7dc4b48f574b889aeb5278329edf999cc624f5b375b21b9ae34a4750802441494ef32c29ab62df67f763f4e2c350b3efd562c24ff1f8bbe847982d12bf520227df4c24f31cfdea4d92a11f98af50850b658bcbaad50ac013ea976477b8e24161bc4543337fc01d98641d7e5617af22b3469b58278aeb072eac5f7ec41f4dab75c1256883d3c260110c54e21b06ea5b3a998cf361544efaa6e37ef022c0f901a6ebe0b9cc88d99a5586b0f1eb6ab7dc6c71ddbb230006939527092ff537a66f23a57bfc70f0dc5520f045e3566128bc664fe9c318dc86501d22d6b60205acd7321e7042b99b6907a1b8875ffccb3346638a00242eed73c40713dfe4c8d0ef02c7227d8ec381c1f02e6d754de53445ae5dc84b2a30a58556e7090f2eec00679d3967838f17bc86e9a6ab0544bb5d03df18dd21767d6d1f23594a4ed88eaf0d3c5b4fb958edd1d4e4ec6160ab835e35b6dbeef929025e1c56ac621ec9cbd753c9b014c2c5b0c9a8c2afaeb4752fc8dc9c8a4283827ba7061a53f583ba6578e48f5f4143f5d17bf639bfd482022d1f1640c045e99cc188843d1feff0f5deb8fe9b7325c980e5f9078d37d89415e265d871426cbf298c0b3822666596819097c8d07f7802997b68234490129068afca0724822b2697dad134a4bdf8aed1f06be417c8f83105b277294613829309305a5c9403a702a2eb8d4f488b4e6f418b3f6ed0b666f5b6f0b994295050ea987f80de3d9f07a23683f405545080b4f854b102489aa2bbc7b157f94e5900d9d0ac524f8702d478de883b0d847212b3d2da1931e340501caa9b4235580581575098d4c402780485d57331d014168bf81d5d08ec18db16dc8f8d794caae6373fb5a128e81f21a3b8e0560466368ad7b267dcc7e7d21be6d9400232ff6f02afa64e77f590a1fff6eb2e5965246be945226191f02160241023bf48469f4c563316123f3148a1f8bd96c1a168399680ca6e112933a3b18f6311dea82c9b1de2253a8c89882fd0f90c5a40ece0fcbf961b1fc16e3b83165c0544d69cff3f603cf4d09ccd39b504d208cc4331f791ce38e24e252c464d7e5b0e51893a54aed3af584494c623287494cf6d81814e0cba80b0c93291c8483684cc8ebca4a09734f63ccc2575856ac4a68ad85d952b639f3e73bb2d6d97950e420e4bb260467200f7928721072f061200886d95a9bad157d425eb90bc82b9701d6978b494cd260b1efa979b62900236c2222a0279fab060f3e1b2f22461f439c80e20205511c31a28a1b5448220bf2889b12b41e3d96bcc07c84890cc9cf1436a2d791971037560d8888a2fd9148dcd6a96c54b8385167ad1561bcdda28e9be2d525aa8420a9fbbe8ff47d214d0a25499c10d97a289275134f67b57a2f67f636994cdfa22fcf7a1fff83091395cd8d8a496725e9fd75a3ea7a67f1743002dce8009cd4e59f0590d59180ba030f24dd6fffbd578b307a4f59fe023fbf5cf5cf5538ff8f3c1b0e2e4748be8d4617472949c9dbdd7b2fbed4046332554e693413fdf9d166a231300b8cbc91fe544a521aa523256d2b175aa331ab49a324a5edd8a249aa721525a992198d9923f2ff8ec021c01525299f36db0257d336c13cd1b1ee9832975722a94a8b542ada60aa274a53324449ae79e660b7efbdf85e9df10d8cb9e537f0cfce364a7ad7db18dfebfdc81b515ada54944687f22d74c2c4ab948501188f3f232e61c8a1daf8533e49558e877e0ca2e172fcc97fb156609eb00fb844e11235f3f5d65b6f1d714f8f46d887f95279129e254ae01297b8b4b9ddbc9bb6791197b844d19817f110ae95a95a4e992f5557bf7568be9a455298ffd6d16387149e45c67bef784703eebdd7e6fb8fc81ff7dedfbdf75edc7d7b4cf5593934fe3c502502e047d65ead18e80c11dd09a5c82e602de79cd7e6cd76535bedfd5bdb12c3d6bf998dd61a200a145c132088e86480410e0f0b7026ce565e01012b3f7039dfe6dfdebdcfdac769eae9abe5a06a359a1a95b53b686a324c30281c5baaf29cfe8ad148c01ff308268d9bd75e2ebdabf4ade7a12eac9fabd944ddf76a54c719813a2e488d7a8a5af3350892c4eec3d85acb0bd098e6a270462d70f7b7edc7f7defbc358060cdf16d5592d59a62a4afcbfb5ff9fb5cd238cbdd17f167df6beb7666688a52506b7e275592d9b73fe517e217054f9cc59730252bac9e35d6fdf7befbd2c9b57de12637baa8ae9f7a30b819b0105d5663ffbfebd9e3c11a7c351dce963383896195010911d6640b3ef34a6c2fab34633209e3e7bd8f7996d364955dc45129bd186e66c064404a74f191fb00eeb2e9f3e1fef6163f3afd495c0fa32e3023f650346cde61edf622df9e6302cff994b891f50c3ac0016681b20a1f68c74bfe3e46c1a1cda965aff4c6bbd77d8dc586d67b82732030aaa35952166f78af63fe760b11e18ec6690873018c843d0d3a0fdcf0135fb7ad7db18dffbd5a8f16d6f94f5fc90435c51c2723bae576ce672b95c347346a5a9a79d5c4ef5a22ff5459808d41f61cea89c86c668cc81802aa9d5ace51a6b65e3ec899e941fa09bcbfb816c07800276dcc648d5dac57ca97c8399f9ea7f100579212524555f84e19990fa17fddf3a46449e2dfd6b43002e01b9e694efd5acd1ae347f777cee1ccf43a210ac217d39b36870535dce39eb6eeffde5ec42e275b790be5207da5caf989db138a1e7d33945af9b93d4e19600267dfaddfb4f9928f2d92da860a993167cc5132f464b6a0a05f91082082925a41479708b5c5f7b0e1cc8299a481105872d38e802862328140df1f9a02885a215eed0d3232b97f26bd721888db284be4251b2d0451d24c1467451a2b851aab82d30261ea3a56ba1a4164aad502e4b8068f11272ebe2c7c6ca0584198c00e5d081ec6063650a92e106d11014248804279f623b3b571ce36e9452796aa9f620b5d65a6badb6d65a6bb548b0cbce864ce1b96c006285ca90570d4b5a58006939a929e2862b8efc78e284253f0035c16344e8092e4a0f49bec42c9ebcc42788b81897a0b506082247d67460b91dd72b36f34623cfe5da28fab293cbb95eb1ee7ab9723bdf73b987bdebe5cab96032d74b87075aaaf21d57cf4f6e845d18bb5e78a4c03cf1982f1595334fff9a312811cc934e9d2f95f798a739ab08f3a572d7c85ad076185b6b5fe7d1e579de36790fcbedb85eb13a0b8128e76c6dce1997b9e55ff3f823d67ae34b73f6f938aa9e3e716668a89ef0107da92c63799b9543e30fd058de66e5506dfc19cb1c73cbbf050431c6b9865743e71a98f35c025b6ca84ba2a228480951114d8c085971332224d3dcd459addeadfe3cefc397feeb7b6f544c98b019b9514d7db57eade74c0e1d4c98781d8b47e398323727031e16688e63ca5ccde7ed262e07c77bcf334d19f008a8c2499c729c7a12c046e539103850043e573d8d161f35a5451f905f507c167da93ce56eee79fd723ade2e049fbfb83dadb5f6fedeeffb48f782a40f247d3693ec851029ba11b11c111e5c4e67b5642157e93de42a61d87b0e0e876bb124b0b55a8da646b583a6e622c30483c242c90e9a9c1fe5799b66cadc130f5c0dc401f9db524dfe48a0384922addceeee056779c1b2a2f2ffafc31a95300c7b18862aff59f459e1550566452544c93eca12030f2ea7b35ab2deb5eebdc481a39e3810304cad66d94b9ece6af592477756c7e510e17018635ce7719161aaa24c89f55cdcb5d806dc0fd850978b63ca605e790e1c16716e54d485011658f2012fe63965e7c0bc959add9cffd6aea42af7b40906d63f6f9ba9b35a4d684f6f2dfa7c1fc8c2e3424296d27a5dadb57eadb5f6be7bb5be37f32f064dffdfdaffc737cc69e95f26eb3a2ca250f5743b3dcba6dffa0d35652e3ffda8c0a4f141684c996761ce90d51e19cdb26ef42eebf9193b2bcb7a64fd7fccd32ec97c653d54d66fb25b4488520694b10c6359cf679a99caf1cbfa9cc1818037f5f1fdb2aebb34ac4f9cf3458f6cea697f3752e92bdd3b5e0a43cfccd8dc3cde018b36a834ac9ec9109230800263180400c230144371180a8351326f14800e4e7c3a704e3a300c4943914824475114044118c42018630c30c010632442089d980332ea7ad87d158396cbf221604e3599f71aa8a2c0a0ca0d7b6b1ac084d57bdb86969eb4502c690ba6b4dc4d8d891cbb929b6d050a8172a2e3ded93998dc2c6d88b387c83a13402fd19073bc22d98a41409d46418e5ea8589f93a08f97892f7492f9278b49c09d982086398e55cd5c1f84be977bb1e3079f5937731a991d113378942306d6ba46035bee4f1455c94ef20bb29b43766ae38c332210c09a745bbd69263ba34e23a57aa37b3318b489758799fb0e0102886f23279f83c087eb9344dc3cb13a184460d0768f192259fe1e506713dc95ff67d99ea8320a40d9aa95d53e2d23095b8ebdafe6519075a9fcf5b6271fab0f895fe0439903688a9b40e8aeaf1177709229e34dca964fe263c1a6e884cb369741f00876e6dff9d1062edc2094849f81441df75f07214a86d237709c54d8226d57eb312f1b25c71148a1f030502afae886210b6ee9bb4f8b1223e8d323c7cd42e47c465662a2815548f1e1d573ec2c14d990b6be88cbce4a37472e36ccdf5a42adca9f910580821b2f533da4baa2f8ddf1df067c76c25cb97a0915892f80cfa046d2db7444874a61006fe9c0346392499ac68ba7e53afc5e7736f5781407a055b31e7a034d07c9e21ad7242b1d53e8f8b069a8c92eba68121a8d8e589a04b4744316ab3763b752aa5cce650ef68043de418b260848b7c3c61d86c168ba77d62280d8c231bf969ec2476c57d119f201cecd39521aeab0c7b60831c00201f98a3ee3f412ea264090147e5ac91b298a1a427fc4432cb3d5b9a2c25ccb3487b5ddc861e19610ca6a3f4178a8b60750622101d9c0b6d44527da21c071831939abd4c409280a1d1f0a833f22009109b7847675a77a8a42a0bb4292a8efab7ab4dfcaa4b75d61954df9eafc1337ab060d4a5782682351176d54106e785f17645b5333971ebab6a5dd81cbb8eeaa3e61597a2f853ba59fb16d5151013d528ed1a3b238fd67d2feed6a7354e654ab489d7e05b31ace1cd3baf80dcfc7ba08e30372bdac2578676de18f1f9073c080abe734e315d2d010759685f4c1ed252e4fea412009ab0cd96f1f518013ace2be938f2af508812d2ed9f6b3e630cbaed9456b967c8821a5961c1b7c6afa93c936e2388535828ed81c719bc077f055cc8f0ffc08c26ee6a788ebe7bb675873cf9cbb1205f9fc577dd72048bae8369dd465c8ac30a2c5ebbf3479fada90e52f894c9ff5a18819dacf5128746b07e702f89e37a8e00a0b45a2bcea004f794ef7c72f59b545bbe62795ea6500a7ba09a23bcd65103a8599c3544272c94b2265c631643d321912e488dc7a67760edac29c30c3d2e18dd0e9394c6213a55a978307d844b5dae2a3487c7a9d54c37bdddf3203c136c47434419d651506135be77d8158773b6742e638a7f30e286420c417a2d7320df2b6e89ff7b43eb21021f919d9de2d1d5b94f9c300e0fdf3a890ff7b2e54b915beab0a2d07e81a8033c92b1abb05bc0d9ab101f20ef772263cd156795125452ed8040c8a5233a43879ea2a8181c0b6a0559e34805a29a12fb65843a36a624c795c6b12d76b0774676222d7305d1ebcd206eab748429474e96a2ae862a4d158525d7bd814c8ed10473487c373551bd2ba0e485bda31c1466c0471ee8efdd50b42ebee20ce2dc0a578d002b9cbd37fcb6587dbd5265484355cf949b19c5f0a0191338c09ccc6ac9083b166b156d0e8b05b89cb902f98cd1ba09a2e372fa1765eccd353ff4689d45543c984fb8744f427779089c242084fb460b364c654a60aa61a84bb313e28bd7cef4b02acc7777f3ae918d59635089c76461c262e934a188143b0833bcf8fac4184e044c9e40a2502d33619c5fb4d4140e0e36ea92af21774957d12d75c902700a43e73c0534cfc49a4b201d6b2136317748451d6cef22aa34c5a7d72f03f7781927cbf4cc53828ee21a8f5884a13f23a577af7054ca0982cd14c5113c8d98bb0e1d03a830e7ed5412b6d0640273aeb00f4c8d7f162fd1d446c2f561eeb36aa52d87d053735bca33d9fc46ec294cf0bcd7e8c8903f4c53855f949693e32316935a9d06d68c89f91c6d7a3bfb107e6d7177d51bb6cd3381a79b7192393a47354fc5d8c0faf1d23dbb0512ca5680c013466a3f4ef603602338231e6a814018b12730cd35e865c774912ba60adc98406394b558c1068b391dc64532eaa06a2039fade2466a2c4628e5108266b399185e44e27a3b378915dfba8dd4dd36818d868345bc2ce23ffa5ff73ab578b630a542a90a4d3528bd5858e201683b01dcc6fd015b4e9c6302dcb7a6cd318d80c551c4f6707f57ca2b2438db17871b8158d5ab811382aa43b0c72834eecdbcf36af9dee3c156da1b64f4faf6d8ce355cbd1ec096cde5778f5a572a1197d5008e487cc3842d3f3567737b5a955295db760dbd7172685f05c3c8e909a0b105101474ea9624af627ca734af82cacfd70ec9f376f3037d4fa3fcffb599b08d6be8ece191d3da15e7b6d872ba330b8c6afa1c4f0b3054a079c6d54d09577626d4353f3c198d71243d3ba4a207f6f827253ff6e6820578007dd08276ac44482af403d11b583547dc463c3a72843404ee62f8b97adc2c82ec2bf48be80a928513e18f1f8e35b74340a93c450a7e0d7e4b011a414c4b539580fe767f95b6f9e7e6975b102865d72aa2c46a625658ebc00ed5f93e59e6cfffca74de58a59325370601e1bccf1c35b1578b47f7d7353140ddf05fabe2353643acfbd6b8cd39c7e85ca6db83a6c5d9e78cc28fad72964bcb31305b9b0623bdccf5f4ee3b51190df8695d27592005ce7ad7b5893b671299ff23a1bf747e75000426c7e14a5106e87cae5cfe01e51cfb5c790f72a2a86f4e1859e281416bae98004327235a6e2b3c87326a0a2aeb8067057d3965f158af6f7d218f77a46d22a893e317ec815c3140dde04c9160422733c09328dbc95af6e72865eff56324c5614a523e6e026ce280226070a0c049df3e6b001450dadc776b4add1dd0f68099d4f2d887ea0d7ba16d9d1a6721b7d527e667d578b214ed21eb1eb672fff0f74e8403286424584c097a7ca601db90e933115b50bffb22be126e81e95634036852b814bd3b37fddbd2fec426f2323403087a5ecb190a551896c7d10c4a19ca8058b37890ec4118489b751ef7a1763214548cfe566076da6f82a902e1f42695a4703b2d11c648969881035adad5002e42e32706045acb4512cbff0dd4a681cd6bbe880cf1c99c41caae95218ef234796580ba73f746216e340ea4515eba8c82ec776304b5307485d7b0d040290311f1d91a0819681882b5b4545ce5ff68887ec13dbfc97ddf23faf81b9415a323f49c03494d663f3d09af1ce00b04ba40b2e9f0903eea87d2b60783583f4dfe542b3afdbdd68cfb35c8d4490060ceca13fda748cbc32d86c8796c1eda0b0173e85433157fcc582351bee071ae08c67a4cce961b7b4767c5d422e7482d47f17bc313311819a940d77c70555de5cf8c5cc83d32827e10ab95d3419907d52d94d2b3e98aa1f70bf53428af557910a2b0cc0b7b34f8ae13d5a3496fe0eff95e5dc45bad5acb7b61af06df75270e227cf828bf58e440eec1484964a27638d4676845119ffd1b7f01a7ec6f34818d7db276a8f69022b33b5410562f6037525013a3a49e9828989c942dfb0e03e186060fe8a6bc48c90a10e2883cbf2625822e0586e19824a0ac574a65e0089e0b9a0e96eaf0c200710748dae138e5b8f902c381c903117e9b3fddfba688f6712d8b92d80cd07b01ab9ddff0fbc5fc66af6e15e1155a95414a2822d3a36a826f2b864b3e458b3b856c3ab24b5a4519e4cdd413829601ff173ceea17ce1e19f2e7253d1c9b60e2d6dda98afd3eaf64de2f8790cecb3ed635174961956a9bc3ffbbe0e4b6a686a1c2a6cd2547a7548be38a064b93a9100bebfc916bc0af9b6223a1d6540e71f03a234acc8a129b9e5261ef94b64129d38e26bad4222b0154b9cc95c8d31e906b8cbf5b6de19da4ee01c20254f2ee3e6fc6b3151d9ac922ab9dda6642f482b8efaf0429991f06848c9731fbbdf08266aec37b24e45b0a0b0d5153706831c00a091939822e776c404adea44e220cfdccdcd8cffb2fdbd97cc165e3c6703fcdb4b131204fab3f73739186cf0f6825db13c18999627970efcc20293ec474045a3a8610b91786aa69951ed659d49dc4348717a281722cffa813181efd1b4da3c377b9b84596d9e3d003113ed47e62045abe1b50112ccf598005df9fa795ec0a66026d574875c250e41b37204d57693490785c69920a669ee74c9a75c1a27f7574130bb69c27deaa6ef49d8c29180c74e3afba08e6818277989a824ed6d618ddf51be052e6c2ed87df840d9fe476f5a52ceea75f99afc1241c82440edc52cb1931da3454f754c76c49220e111fc0efd271038841777c47d7d84a4ed5b10be216ea11fac384a3d027969d4671fc920e906bf1cd3ca6cfdf18650de34ea2cd87215f653c5db84c67a26a0893aac0c07b1f2e92ad5fe90367c272e478e9c5a35b292da5207391c7e3d2edbca99245042c10a9e261fda88b7a769ee89e5a64e5b2cd88d1c6e11af74f3d11672afd3d635357eedb20bb992e3e9d17497a2a13cdadf6f318283b4ed6afcc423909a2695290a69bd9c3bb48627ac954db1c237e2524a71a40135ba519938fa859c48e8add698adf7b99e525840133916c136e2c471894c64a7671aba0f5026d9a021b15ab61f3c20321bc5895d8540c0c7022291674dc65120e25e3f605f0bec0836a865bca500c19665b5f70ad00728c587e892a7f58d019bea41a83353c4122f44d380b306c19c00cd121c47f505e80330be2f8b98af12c34931c22ea608c608b3312569e218013e14a680e11fb36aa133f51d74bc550cf29c2a192d01e329d661a88843794861441754ca25a4d670a79d127f984579bc5fa04e654862e1aa9b0de2376a0acfdbd5cad3f82fc0e5a854c52cb8a035100ed970d35a21c58a28b39d65dd7e1bfa7d6602d48e833b9c3bb2b2e151c8a1f5e820a8b241938b8c0131b16a5e375d7b691ff49dadfb52d22b6c29cd435faddb48ebb2a85ae470d043d253f7fecbc3a1ca2fa3e57e806fa36783a9c18659e0641718f3994828da676740bb28e7565d1da1694af36d5960059490fef5d2e2090bf181f371af802a9e6c80f942e55300e7df3664cccfbf1a079520d82d4fda4bd8cffe2eafa3dc985af7b636c74e26c6427896ad807cba114929e972c26fd59faa4c6e84956775b9ae5196b891584c363124ca44d9f8845811dd99656217812eb30b6e50d9d945c1be1d675c1fb3c1588dd68a359e15e3fb35228030bed570973582d08cf5ed8cbf3b7be71a9a2005736cfb8fb7f22a3e9b089c1c83b6192b6e08fc4148c96a3504b757ab5102c63b434185ee0682d923c2a9da124ed2042e965f83064314509829bb58395b21805805fca607de7b97eea93875cf44ae6813654dfb79e14c26509b2e53c5f69c4785a14c6b9a783f01eb62d45e4dcd7db5e412aa5f36f204e8242842179bb7b206f999870d80ae2d5d40976c7595d7f95df4535ba5df7ea7bd482ecb5ce2c7dd635a917034e5dc22a42a25033648d5449573e9a8d6cdc8a012420771f88e70fb8cf47624a882d4c10ae4643d242eaa3d032f50ccaaaa18687a4ccfac27f6a368367fd42f5e1b3862748a6d0712ed6807dd43851b48113bf78468961bacc3328b789c3c0f572dc2b3b2c098d3a9336758382107b01930291daeb8460a134f0d36df37cfea15c1a7fe57abbb7281c329520a4d597d0903e500a3cc9489430f6b0a624c6c122fa34c8c7ce1789a2ba42353844bcbe186d3ccf9951a6e9001f5d08a1a694ac9b00074197f9ad06bb0f8025abad288748db0341c91a9cae4bdc581354a4b95a6dbb840794ac323c7add0655167b4ae6fe328a6375c00c92ca2c8f460f241c14fc36f2d30c068d1806b75a7c7b74060708053104ca7aae2b0dac8d37c3929e2909f5bb5926063e9aa994e0bc43e17d287ceae677b88b8174a61ce2de2a08f72a22d79c0a083cc203a72ad8ba7ad1cfb31efa38b8b5dc9a4a532d5bcbac856b7e639c641be739d98e3c3c6ca67d174cfe68b828e0c2c3ac89e93bd58a11b632d49d3655ac933df79858e15418392ec2215317bdb1125664f5f08672b0a24a322e23bc698cc6a56e17484e41663a52702704798a381c8791b52aae62ea79a1df0050cc8a9e68a3f3719e01c999c01533ed644210d5549d530300a25723fd41b9e6a728397974fb152a152d0ef4b58c30d7a1fa4d85c04013fd4820194a0c94edb6359acce1606ff16a14f4b354022972273a8274d53cd0c4f3d0070df7860653f663adf4ef397b3403491102aeb99ef2cbb531ae16d688e7c9921dfdf220b81c4d2b883c26676369d6767a5d169259dde7c7ea3f780c5ec115f62e1793b21e6288594a606c31a751ac2e71775d395bf20359686c912e55108f3376496e68d275a3cfa65cb47e5e38785d35eb3314c28eaf1a5022b175116ded9653de3b8fc3c155f674ce447468ab6b4a36d1495f5042bdb457ed5e10313d3c188eb6d1586239551924380aec34dee2769104fefe4b9b2ec9c7331ee609726074fdeacfc5666b018924c0fcaad3013cdf44dc6f9330e2c9a50abaa61562ecd139d0d38a4587da33b9e280129e2276ae2fec8426e2d2d73bcc109542dcf468cb39b80d0442ca1cc0eb7f34a6bdf8feb3b0d1d1f863fd36c65dc7c4a7befa6c4662212a8970f05712952fb786cf59d83ceb856e864131e68f351ae631e3d8f735391dd1a78c83ac0ed0b7c28d23e66de4edeac53bd1fc8ce7ed2569dd41ceeaf6717f4e38b9cd97b39dd2d96c83fa9a51590880c89d4ac91e72dc57602a384e5dde04fadb27f7b124f4f4029b417577902f2cfe20912f14507b3ec40013122c2971c2be2511df90cb37396850fb65b470a89b9d457b79baf2a716a275047cba73e225f73c61312f36782495b7746e1efb25388737e3a417bb6e344df1fe5b40cf7b9a88fd793b30a5f6c86f2df6f29cf4895de7eba2f0b0dc4484697564d1c8552a5e48c681c8ad8355896ae2219bb7a5189c61b6c9db41a0f694dbe7de4e95847601493f624248af36b2f904fff9bcdc17467fcece8c301bd703a6917c7845938a0d8e40c0961f66ca70d1b258613932e94fd407b3f0105f4147b7d1d3fd08bedc7e85a60d6e8c542e9b742cfd5b7fbb2cb29a3016f94aefc3ebfdd2788c901bd4402fabb05446dc59c08a4d2351277853e888d64919876550ecaa036f3cb4d4e64671e58e8f4df797f0e0c298b60a8f1ea53459aca7f3a2940788c1d5dd9406dca209ccf3ad9a83151520ce4f6b4718b5bf55b73e548d99050bbf10358dc29e2e393ad9d93afe925a75a033d4d86e053780ad254f8928b570da80ff10941aadfbe6444ee67baa8810638ee8bdd45937812ebc281eae0c11fd5c901d0654cfaace3cb9e5db73f7b71b3908576fe492ecfd9987845f16da1ddaf059b180bb0f003093722982ec9763d2591b9f818dd966f14a4a1b1485261059ee4e808bac1bcc788b77b0c05fcfceea8b427219d17c7ac630452b9339578a6e7664bc0537676d19aab8b13e079d352fabdcfbc0c988d96f5b036c29440a02567232b3ccf4ef19404470fade1a3445da1c2a8ec9a26624805f0ea24489b9838eb80b99f48f45f674e7d7be03ba6951b9e163d0f4dcde59799586d2f3aeb2f7382024fde80d6d468355b62f43e8e229667c032f504f94c55670e90c413401db8253f32cc07156220b0a2dc2da4097684279612dad15e28b0ce18252185be01d337feecdfee40d7baa256b3c3de5c27096e2a7e9c4d060d8d427a47819a4f86070d15ac1f9a35763208d370403cb8bcf37e118589b58c6df35a6c40011884756c93411e950b544b03cb16fef98c7c8a328cdea4e25c0b81eedb001f48260461a8a74145ae2b3565a7d4df682bb613590935179534318d83c676c2dabc322c1d3c8dc71304aee7f50876d68cc99028a06f8d419aca0f4d4cf49bd06f398c410e6d27b3023b25613a09db22085fe843158517e73a277960e96fa915a690800f2d4e09fa6ad25b80c8a84eba7c7322b34a38304010ff9f7736b4e5d394e12df6145978c5bba022bd0501ae148d939ef3f61f9e0fc0628b24bbfd1e73d36fd06b111b09109a06f1a9fa62735caaa8b09641cddeab8267caf465f592f482d91a7ac9f30c8e67a9d2781c12cf14e8e1221228cbc2b45d3f622c42546e17c84011a03c05c1e595369654e278a2897e2851b87ca694a5e83aa6f314dad752965810acf5bdcbd468d0e48d7ecda6105a60bec5db37f7f96039b198bf65e840006e0f0f9f87450ab2302c763e8097010c0289b8342c853c3ce44e216747c8e92129c4a8ea2ffc79f02b9a604889d75c39c87ecb4921f5421283c2b6201ad2cd1d722235afcfa7b7dd8383bd863e08770e847603aa4ab6765a3090424a0749d6e825be83b9acf47091530314da5738d52f8d8baba09a1caf5eff515f32f10fcd983c71d892bc80b21800a150e6c485703ac846f1cbdbab177fa83eb1c2a647b26a1f467be1acfc964842f6de64cb2da54c49a66e07ac071507499e6cfe7d3739c133dd679288c46e77cb008b35c16ecbe9ddb108927e3043615ca273c33844a5b5c4660882063d842923a8790b195158f0858a34644610d40fb022060d146244a1023441cd666431060d46ae3803065182fa85c49698624aedfec55883f163ec96115f0d8864f0cf7c158063cc1f8c31f0e74704cfb3610354e16b314fc778263eff9420e6606b4805fe01139598a75b6083fd5be64382e64bcf05ff70e8fb871f0efd78c49732225dffd260548a8d8045ecc68f6d4ab6aec23f2cbf76984886fa873db404bfe214f0b92f64b13ed6ae70d5c26d05c77ac5f2731cb23e630737e425f6a202f38cd0c53618fef1cc6b97115d3ee4877d831b6b98189f4c1897b54de18ffc4737225d157cb42b3e897263194eb6b8786ae2f481f8fa20ee38d57a40f1f32382e7d9b0a1a2df0ef3f8cbaf9e3c8e81f5af1b0754d26ed983631f882f8e10600ff04fd5b2efa08895c4d670bd12618e013318d7b90852e79cf30ac50f43268c4c052fde8933273d8301211e8b5cf71a9f54fa4b8f01cd7529a51412f218e3d71c3bcc73b3f083eb3fbda8456e0ce6fad3af07f36c61474063b5f7a802f3b49867842ed6ddbd01da9f3e68e30e05f9f4a7e782fc703e9cece3d17f0506b1fb82dff91b8848777a1149f3407fe9384a8cad5fde8d3b6634367b970e36ec2124f86766fce31f3be880c592943f392b108edd266a3086da079d3ac38676639773df085f7ebabb9b02dac66245dee11eaaf50bf90a50683fb83b1e0072b061ebf69276b5780c1bda1b81982752807ff86bb5367ed8c1ed2f64324343feea3071273e19a2306e8c2d831b9b88b8b1c1304f7424315ebf487ac889b61b36fffea4189a5c102e27c16670b7c8b5c7c03faa2d31de808945c6869145f0ab878aa491bf4efce3f35957ec12cd2cb0aa2fac5d6ce84db01f2e1daca6fd94807f88c41882882f37414c72bb061144f8f9817993371531c43cfdae2e56fbe290ef7c3164a6183253a49908f38b620ffc3391408a26883506e14c4b3b7cb8fddb085dacd4c23fd1615eeb13975cf8b5436ee19f30a2cb65c0023256cced2b6ed3806970436fb28279aab0fea1c3be30f670fbbb04b7df8bb8fd8cc4ed97ccd3fe0df98b657ff0cf12fca382d85fa1b05bae97db4f82c47ec23cfd524abe71b40513326e28bb2533f713d7d13296e9275ea678982a9de57690e83232c5a5d82f01486e620626a3ece04d5d8820714349d48548911bca25d2483eb91d97881cd62eee1243112a6ec8b992b8c43ffe9d817846124ccbfd80c60c6cfcee7a84c0c5f287c0c5c6ef1aa0bdc38ae09d0e3a60b1ac75d815d612b791b8bd14c6a59091ba9134d8307f492f358c95646e3b4c3a10d2a889795a3ef11d7f39194847ac2ab60634dcfe251983fc6413f550fcb0878a482dccd35f3d59e43bfd2088b13e0473fed061f20c8e92adaa58de4fbccc5345f8e19dd6c23ff1ffbfb7c40e23ba625183fd2c321d267ab97149bf40a703feea2d71a7df0b2ccc909321eab88315378cad050431161c010b1b7ed02374b161346a2315f887b5f0156ef14f93c7a696b189190c8caf8b2313ad74436e3be305376c22264937ec256dd44f2447e6c204cb6d09e68c0f2e47f7ff769887dfe3c90929254bf9cce3dd4fd06c652d5bdfa9d53f6b6d1cf3cf3ffeaa9ac7ea9d5ead18cbf58f03a3a92e90510e6872766ce212658aa332ad5b6d5a4760f5a96e98946cf52b4dcbbacfc9aa87bf561f06ac38da4ee08d568f0f0ea5a32d5f5e00c29decba4ed6db75a954ca761da700d0a6466553400fb68eb43a846b9b4597225362ecfe8848c91222a26e4544b442ad7e552b4a2ab1d07d3d7af80ba8760940474766cca4806000f5021033603461e5fc8d568f0f8ea32d51bc00a423ea3a2225a8afebfe681bb2fa2728a5ee811a080af5f1811ca1524025a89e10596b552854f739a1f1fe3937effffe5a6da71e1f1c3e346e56361e4be5d979d4b53d422ac354d4248448c99229444444444b3b907c69894809519390a6a6261f2d48e622c5d13d5d0f0ab9568f0f8e23a418c392e4ffc307119192a21d3e5a00d2d464ebc9878f1d293ceb098b2885ea38056c0a38294053808f653dd8422a6a1242a46449b567d02c7193eb3ac9b55aad31635094a3b293f5b260a849142a190b9483711cac48c74549c3d8ec6b1861ade86d55caaeeb50d116a55229db75dce7c466fb9cd4bcabc01ba0efcc1aaffa0eab458d52536c2870d0cc39b8a473d2e9eed2dddd5dfa74ea4e9dce499d7febee76293b3a783b9457ce8f83f8d75f943bb43ea8b556adc6d7546ce3b67f41e2928ebfcce15ca72352fad56aed9c4936ef18424704f819675871295d4a24fec2befcfce1079723139feeb3baec1d2ebe3a7e1c7050d3f1c3d31d12342468be0c1beb7c13fc9a43b8fdfdad10f8677ef351fb503aa32fc17c6300f1f5c59df8fd81d461c48631c6e6a0e63482cdf26bc8113cc4e0cc1061aa98822488a310028a0cb014d10289893b4311222940c3a4091652b0e0c4121d62673c495383f4c80d6699325f4aa6692d68c127c26ac6ae583b5240b23b906c6e08b699eabdf51252b4e08d1d297c99f58c760326a3582c03c2c424c423eb2114830d9929922d6912850a519fca83056e3b4909138a99f45337f1e74dbcb9b9f978136fbe18638c4c4b38bdfb83fead94557d11a9418f58e251642256a1e2d978519e3498e4c558fca2d4e00170b0fdb62dd2175f8e628c3146d5506c08498c4343699e485363d4c4280ea970dec6c808e76d706c1ee7716c9880a83e2738389f508cc9a84911214671280d73c9a2caedae07855cce4fa9728414535a623ad394f4654c193368d208619554a954920a6bffd43dea875c0ec2f9d40b892ad5c717d260cd27c423daac6caaac7e65646363b352a9ece7c426f539c9c1417d4e38b0c1aa712a61f5fe3b76e4e0706083558386d7f20112f29d39f404895193289b6d150d3758ee72520d63e890200ad946114dc734cda49de09fcc8818f1919062b1cb4a4a97bff28fc3ee6d9612d708222e7f03c1af864533b81ab122681d2e1b11c3606bec2ad2fd0c1fd47d52a46cb9c9eda4790d23c288265222deb8648449045787863528865d2d0383fddd311f11bcc426d36178b9fd48b7bbc6d860cbc0dc85f5abbc9d02dc7e30575afe5799c788cb32b37761be0badc0f2e52ccbbe707a1f5d960d4595b6f93989ae6750a5dcb88a33581d91f222558313b77b189854c3910a4ba2e1ca49849bd980ca020c4121ad008688eaabbb78b2b2497ee71c41fc8b67e2990639c2ae134e300fbff4747003d140349366c23cdd41208c19377e18cdc811d3300fa7619ee83b3186bc65cbe5ef2beeda8d1f6a7c74c39dcb9d8e7efffe3a13a4accc2351b0b14e588dae339acd66ca1125f274e59f2c0a1576e557d8c3aefc875df939c11162d75efb1a4d146262b020ed4f4f630b246400439eb62f0dba0fef87eff819aa44634b4fbf23022295944ed5129658141b1aa2339b59466f888e94894a323a7dce39a5f7fea256f08e3f18900b0ac676e23822205e7e1aa3b17ead60b40c3d43d31c8942c750268a863665b0acc8f56ce8fad329b331d7b331fdaac9ca9cc9d2d4a1a68c29435361b548451256a2eb4aae7fcdb413f72cf7a31a496c7f5625abe2afcca8ca13a4ebd994ce8466bae154f27c2976e7972c16e9ba12f3f8cb662ed7870e0dd67e8bc6fc450107832a9171fd43ca14f31707292d5dcae483799cc696fc29933ff5a7fe5ba431e6f117cae2a5ba4868ecfacfe045cc0c47354e44678c7e69d75cc17529a534aad185900c41e4e7980fd419adde95de15b0341784a1b9f475b64d6aaa159a2051ad208419f9a9971fcb13ba90fbee1be2c23901f5dda33e9d1bedc239c186a8b7df902b71787450cd7750cd272404419dc7d7b994e742fdd445797c3bcf85d4d714cae3cb79f1a6521edfed3b0f677b8fe9ab3c9dd6c1777edf20a5f4cb59354827a574470aeda24d29a532abb505ba75c5416ed4ab5c4e647d6b470a35542b3429e2ffff1f869cdf5f3f615bfe5c552b0881a6562b3b0269a141370178a57b0b3f9c956248ef833f89bdb91cbbf8cfaf7e0ad2af23986175a47bb1b14ed779380e8821e83e3e07711e8e033a049c25a8fba46859d7d9534ffb7050a02e684f9f6fe6a1a03dfdceb2ff1bbecbab0d56d50a4d94c49bfde98300135af68021419c967dacdef1aa0342180b7edf604f172bdd098cb374df7d42343004f7c170fcd04393201c07c4e79efb8404f942095150941f8efc5697d5f2f7f17ff088f6c02cd915c6951696d5d3c5fa87d3cff1eb7ccadc4283fcd25b62ff0e61f2822d3c1c01e28a1b98098a5d90d0c04917494d68088a6fe3b3c26cac538704c5089c5e7bfa5af6e1d053f6f579645f9f7efd8448a1dfe9eb8743bf3e070911228587f6a7d337804fa73f7d2180e1f4dac7d987433f216d48d0101c66c8020be27e7b7f0880e13ef60d024b685eeb5525c9c54283b05417363e0be1ac2c2a79c9899a05942f35184119828aede10b192a4842850b26566e62b7a7c002ca1359a4f0b0e2a228e9dc886eeb2e41f68496b02305d683dce5a41976608d41c54c085e9f9b09f1f81a1cec981b9ff668302e09f1f8cd6b695e65676767778f2dd021b37d042932f6a4013152cb47d6f7260f39dde7ac92c592734ed98216b15dce16da55b5e76fe107907659b66c1ff53e2ffba9ee09c00b6c7cebede02797faf0d1902a9c07f28e4f9f1d3ab23bc1823daef70cfa3bb390bdb5d6faf84b3fe9e4f4f5f48ed799459419b24069421589713aa5f7f8e0b07139c98819777539c90818356cb55dce44707451458f0f8ef9e54a3355c210d344082b33084105352421c5152fe052441738bce81e1f1c2c6ec5a52e271909c37dc12e40e208aca88ba22488b4a06c91658a1530636cc0027b01d7f4cd2b323051d0a411234c12518f16681143040928497429e30aad8c3139d3cb0a63383962840c9a1cf170450c53725012028951156514d1328030c0b4a28c232440c1174fb8e01a74a952832196b018630728c66092c2063e883063f186218888c1428b27c620a2041718385102c6858628747041360600b3cb901330499285891670f132c50b37f0014a0d96b06287335234597192820c323ca842636d97938c7481822a62b5241991a2c81936dacb494692b8f4729291238aa4e49fbef5646b1a36465d000f5d4489dbfdd58ab9cd5ac00daca42237dc7e26f2ed18ebeff3e2c008a805a54e92e10637e462676ec863788999e874853a37c01cf433ee8277669e7ff4e4ff0d39ef461d22b0a18ffff42410eefa579d2f8a6183198636c60cba0a2f9a2b61470aac07e5e52419763891608b959931c8482c4a2b1f1d2e8deb97936408ac2a2cc6c11db25aed9755e30a96d6dda98149350e4c39db25db956594c179dac0f5fe008dcc33b5bb751cff465147b6fead3d14fc25733195a3025caa863558a0a323c550a3a9c289a2141c9159c5a171ab9ca22356a06543da72a4495f82eaeeee2451093b52603dd85d4e2a0ae286acd80976caa877edaedb19965e4e2a5ad2dad74a2a3aa2035759a7f460b3cb4945b032b65e4ee2a129051ece9cacf0a92b4032b3267a9059280a6a7024d81ce2869e8248fe706badbf3a536badf5c3d6eda99f8f144abdc34b95c99e6149d1f4b0dee12c43bdc3ed8304090e3ba6a8a2f396abad1e1f1cd5b250508fb82f4e6268711ac2de5ce6a204d2905d5de6a204956c0a5b73998b124168b1f632172592685e2c8dcb5c92481380cb5c948081d2c61e59b694a4269404008d0dff46fe71ddf820fff88dbfc33f1bf3c47f55153728a185097890a188111136a8419a1bb0c0224550fc07b7f8623188c01ea0149a70fcc5e7461ea8dc90b100e07a73fc1c1bb3b821f73e0fb2d10f92cbd03a0683c17408bae147ee1ce2b88e85bff098323e378c4896441cace0c1e106d79f6582ebff44615c7f3087a3ebdff24992c3f5074ac2c5f5df2154829b340231aebf8f26aeff0f0c6871fd3ba0c40c1812493ab4a0e887eb9fb48394ebfe0476e51c821523f373edf7226268582c797c706862e6ba95b02e319c6234c0f5b729b8fe7c0391eb4ed43948c8ac90d0e0769208a8a027d858e7e78920e9c51c6628e3491008455a58f142c599334b58090a62022a452841c922c491a0eed3c541fe660023ac7c1c965ffd85c31f8e0af3e93bc0bf3f183e18a4f0e8f70f873fc26060f9523e4bfe22969e252c3782b0ce3116856ba72d9ab0322422be985937ca4990b5b4b0418a3b2f27d97014c4d651065d198bba9c64c3093cb8cc858a995615dd3ed323d3dd96354550a2d56af94edbd66cb55aad56ab25db6d2a73758a2d4a9b0d4e6e777039c9061a6ebd9c64430c93868d75543638c69e9efe421bf6b050e307eb5fb3d7de9fab1fab77e747ed8c5be79f3cf99a0ebeb17e7d653faddefc8cf665eae9903f9f597a641eff1e17d8d095dc7685dd74db15769aebef9204261be7eca676c5bf118485410a8fece9c3507f3e0c194700250b8394f830ccaf0f03fdac3e8f8f07fdccc8fcfa46bcbe014063fdbdbbd9f5af60cb81887cb71b757b998de2c8ffa0ccc3911f0701e5607530ab020dd9569118bbfe9571620c9a5e13cce31f8d825c892fd9fe2e7e8c2dd9806e00b2c166ffc16c974797fc39c3c6cc0cfaf0cbc777e2f3abc26030d85110bf102c579db23de7d7ed2bea5fd3a6fdb6e99c3a577e2f4cb069405b4c76ce3957edca3e9c218e1b7f94108605c2ba92f54de9ad5e4f83b7f59c1552dd8883e37a737e4058577e37a4d28dd76a327e383d59ddfb9c66f5f471da27e79cec69e6aca0efd417ad99efb0159299ed0d71e47b97af5c4f8596937193a6554598bd67926f286b0d71e80c8223545f75e335a16ff60db60f3f65e5be6a5de0cfae8490ac502062c355952e783969cca4c7cdf940ad55faf50bb3979fcd7e7e56ab9fcbcc5b651f7299cc68166475a7ce9ddf0b1387e7522da58c5ca4d423b7e22c8f159d73caaf96654b29e70c5f9877fe0bf2ce0fc7f52177c8fd8c089ad1effa85f2a9cc80f8f329a79cf3935cad5c4d79e152fe6549e99717dcbbb8587a4f8352ca77b70df2bb4b7777777777b753a49435a2d8505e97f6c331219c960b3aed75fa734ebabab299482a1d09a01a45587e81be406f9464e6536ef5ccdf6aae269dd36b1672d7e909f3e9d3f9e1a86e01c88857da7c3b806241edcd654a595d92b9aa83c5fe4b973537deee02350f91cd9f7562dbdbf11dd62f1fea9d762975e6a434cb217b684e4a59594e8eac4321de10867a23d34ef1743a69dae964c2111b7e8be3ba0e85ca5e5e27d927240441dea9d3116f372b86d0bff5705cc775adaa99353534502106ba0e85e294b5e055a150a84e472a956a96b5b6d3412f4ba5aa61a6cccccc91a83b1d7d57363872d8743afcb256ab55b76af0a663314ff3ef5cfec20ddcd8f9d015cb29cd202cbf0f49979f0f3985d55019c24d9a659911a9d4775dcadbdebba809dced79ebf8b9ed936084c030f8cc9472d2e6bf799c2c3f8e45367f57697fea3e7eebe3db7c642c6e6c517163c74f40cee3e01ffbf16d6aa2a41da4fa4438c2f2c66d9b90b358a947fdc6fdc6d98f9907f5409dfac27851dfd6793db69390ce3f8f061b14bad120c740fe29a964996acab4317f503666044877af3104fead5b36953de7176377cb6e325b6d17c75adbe53de77bfcea6dffba3bc9c63aa16dc9d4e3386e7edbb6c928fd738f5438e56218a573d987fe54ca3be30f9535c471d93e04194822a559466956e9cfa795dafc4d6d239bbfe9b6b9799bb7d9fee6396876396aa434fb9cd8d8c41acb9849a1721e3c428a292d319d69da8225e9cb983266d0a4e9228d248b59466b462355bdfdcde6b58fcf31e0f4f1859c381ddc9fb8533cc54ddaa86169c62855a11289ce00d9a1c38ad96965e38e723445520f42d070628b0d5678f872134676eccb65a52e5f6e68bb3cb95b2a46eeca8d7e8ddfaeba92e5d7a0ca4d0b86c630dd7011c6cdd2cd1634d0f0e18605375eaae862e4850b6a14d5e0814610357a00e3080a90d0a1092d376254f004d20e5cbeb8d1e2872453a800c20a1a5720a141c48dd24d9924624a66808285111a5988d1840a13256894404aede54bad4e3f8ac532bdd30f3ecbccedd78e6c7419733b2e91c084951f55d25fde1c5e5c9a4c1dc1b8dacba57665cfc43facddfa9a273710b38f32b1b160564bc10d35782962098d11dc7ca1c1440d1f962832230222129ce0081a4f6ec8383102871c680c7183457cd6099fc60a6c68dfbac7d823920085cd1139d9a0133664dd9843ca771ce93efdc68df32b3273e393f0840d59d286172b3912a4b0a18c39e277fc7a6e06e295fd3a39d9ecc853045a520a86aef67fb754fd2dc26c84aa583f6a9f6551defee17593dac72e47d6a530447a17e9ffe09f46d2ae220bd4af51c98d4b8e6210321931d0f67c34583f7a2d34583f165c15ae6efdd0e7d631b7be4fadde3e3afe6a99f65bff0ffef15b1f489639e17ed5f5bf5dfeb57eebe3de895fb52fd4b9f5c68d4666804982058c922ccedcce3c0e129253851005182dc1822a930f21f535178212f32567f2982bd9b05acb62fd87a0ce2028fbea6d11012cf4ab4700d05821fe71ddfe1e52fc372a297b01eb6ebfbd844a7783618405d1296329f897f0431d3056e676fbf821d4c3af7c1d7ea54f1ba0dfbdd656438bada185bdd65f42bdd35fabb52cd6bf6d755fa127f6ef085944b1440a92132a9812d40ffa4b02464384210393a2055150bf65390848d847ff8f7ea1fe1e67b6a50abbf1b718962f7299a36a05274b1c29fe3c72257ffddb70b13ebec7f8a7c687ac5b437bab071fd6fb0383f143bf9a92efc4cf9a8a7e7b4f8afdcca872109fc6673f8419981bff66553ae03b1918d6cdaadae47c0d003a780f7ecbaa745fabb5dd57f1170755eb6156c5919827664b48f1b3a6f8d952c654e3819a1ef9ab997c273ece737044e30b6d7caae42f87d1267fb991effcc02e8f82c1a276f9d1cd17b26e6c946eacf94256cdabbe260f68938def8077f08515005f6873be90759bc9b7c7f9c2da1c7c363c7fcf97fc8b2b45c1aef80e73fff87e847ad60ac6bdcd17b26adc48e54648b584af04204f79a15fd4173a98cb79e1dfd091ae1c0ae593501e51a2d0ad085917164aa32bab9050032bb1ece897f539f34c510988890d1dc991922cbfb80b145c09a28b33362802f6803263a0188232030d4c303b9223f50b15f3d89876319a22459ec6bfdce866a237875c5cc2550fda16b50eee386fc3a259b971f9650aea11292326886ef8494cc4906425c98a5f4eb2c2b4f2ba8b2dfe9c9397fa87223c26b2ec468179fc99397a701499e0c85cec2a0bdb396244817fb6d8e5e86e8ceddf5a26f5f0a48618db3fe7e48ffd50a67bb28e57d7216f7b72487cfe7a26fffc6ef46ff363b0416700ce09f18b43ee77839b39766024a4e93a2c76920f0e2b27cc0db93bc1dc980fff1ffe423d98c114169665a5944e00a21ecc48a73a3a19fd7c7a5aad956d174b297d8748ba0f45b33341d3d873a23d77ed446b3518575e438ba537b44058a3062b5da9e27277428ddbb1898d3f3273cb6db766d317a52526d939ed0a6fd8cabd52ce8e960fd82ef9fe812e1cff21d75faa6a83ad063f27f4e7d7d3604eefe448faab7ed1d60b84293e2508b1c0444e995664a525bf39f13fa907a31b7364777bf1da7e45cf09fdeeda097d3e41c6707d7a7aa7a3a3a26614bb72943665adea6fb4cb513b5e5a65bf6496d3ae1cca55da3265db6573bce0fbf5dd2fb0775ade5b8e0f10ad94d2d63e5b9f7e8eec6b263b13a20f50c85d9ef214331cb6c83cdeeeded46bd6ddeefd85ee93455d4a29a59452c629a5c7d914f9e7c68fa5ac16749fd2a7949c6b0b388194ed6289924fac5edaf8f117ca0b8463357f40b8cdb9e8e19cc01f3f7e3827c40fc784789b935cf43696b3fbe37a8774ec285bca7f736f29bde5877393d2bdfdb673fc146797cad9e5e09f54b6e7b5cbd1d30be96d996267e61cb6b935367551b7fdfb931a8da72d2eafdd1cdbbddd679572669e799665994baf21815c842ed1fd4b419194be748d63f94ba775e6b7cdf7be9ec92ab51ab3bad5e72dcbb44d4eaf34db324a6fac6416dddd5d3e9f32cf6e803924093158c93ded2a1cd337548ac19adfb6e95f53b243c12f176b6a9e7b95eab9865371cfa99e5371a82e5e6953a88f99877ba0e63a2f5e194fa08e0d33744e71480e9ed9dcb29981e0c6f7483f9edadd38aa8aaa166c4172d49fbfc5d805c9d1bdd6d3aeca60ea39f5c2954e6b767a0ee26b25832954aa0316954249c9f7e4c5db719b74f9f1e9a43957cf89ea250a12d635d572054bde2eb52ceb82e4909f7de5f82715f29d13ab65b3fbacac192cb7a3e6179967d6764d39655635595f52aa519aa3f15c6934e3b266adac9c4e5fdb387b2b17a0aba8b44d786435756848000080001315000020100a0604029148241ccee2a8fa14800c76944478581a8c835112e3308a31c620640801c01800068888cc106e00301c327e6fc923fdfb2db72405b28af7b174bcdeb7182ed36371b3dcbeffc8904215dbb9969d8295dcb9022de9ce4dd0a458b3d62c9941c522d94653d57a8d29bfb57b2d9d5e17b1e5bb7297b2722dd2b110d0c8cc4f3c91c0afda3bc5690bb9f6445f6b795f55291b21b2e0c82029aa0db11a6f7d4c862fa151240d1cdb7dfaed4090040cca5d9256dc93e42caf4183d09bd9f7e48049a13ab051a5a1c1ef9e768ad5ab748d38e3d1e00b59702250f35a831cb3c7652508c1555104301f7483390d60d5041c25726109dc51c9cf0a5d8d388bd05aea68483b78c03ace8c9671c841f175f3657feaaacacbba8c0df92deed325d0eb1a63fa33c27d5252ad4b6cf951ba4ac9f48a742ce827b4bb282fab2ab67c97eeb2a4ac4bc7d49fea5a978ab51253f1031b329f05f567e5aae5e5aa8ea9dfd3ae45e9645d2a46f251bacad2b2aa63eaafeaaa4b25d64b4cf5292e65b95c997c2cace2829da704606f67b9f094c884e458b19f5ee38a357c40c792836495c6ab241f90ba40857ce954a4e88beb2e93bef9aff843412e9da57c1f5b61b894b15ac29b343aa8e880457c9919ad69e9642ab3c2ef63024e84c6504fbd7290c4fcf327de83c944731feecc889444f7d343c1346e6d4e7dc2d5341a3a5cf6502e43da39ea9beae662badbebcbea0d8aedd46b5c6efa03797bd7dc78b9a4d385df359d2543dbcd6e3a9be3e29fcc4bac0b562e5676d86d8dd10c4737e22eab4a370f39b12ee50616f8ce2132c2f740b1ef794a3bf105557209f4f0cc8a44e5341b90ba53a1a7e60dd77e5f56456b66a92c8ef3b511752f89218528169685b55010af33b99ed4ef46db6c65d987b2764e4dbd9d525765ecfa5bdd7589c47a2406d407c45d9694ab12abfed4ae5a5eaf8b58920f2957292d5765ecf231ed92be123bb9ca0a7f41776a03cf8f27f87da1663ba28824182276bab9da3cd558836370e6e1222219eef5f3e77764741750052a845fba2a43f0be24426b1c0e78e5252921e469d90a49724762048a1743887edb2a4d759def3e89b4a9685f7a43a892be83065f517f8fde12d2a961ed37fb962d652bc62db02c0901187c020dd3b0b981eb87c2228dd5f344da8c6075625a6757752f587b8bb9621efe23b1a356dbb7f7e9466efcbc9f68504be454950642cb76742df9af4f86e7843bcbb548d43640e9f9e67349fe06b43ee32c924f185d4e6c59333504f79816c63cf2bcb8c030946859b7d2635c91894cc037d0a6c22b5491f6488c9d1d33865f44f0cab2ed5509995f84e0ac75d477fbc1c295ef375f7a8e0c2e5d4daae590b7dac8557f8dfba438dd744388173498886b6a7f6992496d09896e2f88f4a0984bb4493c920a268f67a988b77e753767bb4067c88d770d0ae46c4785bd4c5cda438142d41e8eacb3dd7eebd603ced4fe195a951527f081ee902e44f623e1b0180e7793cc9c91ae4505895b266744296a91c36c1f10393c2d8308254eda95c9ab7cd653e56cada99a5c605b173d017e93f7f10a2dc0e3f2170424ad9e38870c09613d9034b6bd0c31d824c44d80ab46853b8dbdafeeb1e90db6d9486a645ae56e3ade67a4a62b5d57ceffd80d54f8d1c4fee520ab0d618da6a7211aeabe362836e5888af4f60dcb0d700cc9155ddade27ff986900a32b80f489f7d4bc1ef742b07fbae7dea4166b470226175553bd6bbf6e7f2746aa4dd27b916f4375c9b72dcc9bdf1a0d1323aa091876e751053362ce46faa48470442bbd9416b22c430a69640899ada547b950f07fbb86789a40711bbad2a72aeea782bf3d0f55a7a7b0fd62225487595bbc5c3de6271a89b54678f47fc50cd70860f30c4a29f8f7c6d4cf1fe7edd758bafa633a463c742269c72975cd39dccc6b2b9b85621c13ad48c90a20c4564ea14117b9b7fe4f2ca348497f5cafed0c8851ddaf0077c3a2f5a675965480a7f82e5ebe6924e2dc122a2997ba847df4cf5d4d3bbda922cea5eb3dee80751d9ac045c365bbb52afc7cf68e10cffd943831dd835588a07a4d8dafd75c8cbd264cdb6bd64ce7d67d3f6f725c83e52fcce9bc9757219a0100379cd519a6b905e2c24cf7ae0bcb625d16bebf23aab8eeb90f9973ef4b187876cfcfb77cc404e7433690b2aa003187a5e8cb2639e181fd4919806132a3e6b08574e4a4790b0d8146df3702b8637fae67c8a1d2e63c55161524fd0c4d751c29ccbf9be1d67970729bbe9c820f89242d0b549478100514c275a4fcc7128fa6461f6f8d0ae875fe70a47bd520fdbd1819ffb7b025c0872367b0e6e0215f61d0c48cca309aa4775984627eb6c4d3cca5b551c86e4a7a18de94d7847dbf320d8a58fafab8297ced95cdb0222e95156e1721381cbe69fb3b3d5a5f807988b52cb5234ac18b9e4342732d8e53da89c162d278cee1a704e4833b0d4536e115270b4711bfa026795141cc393a096421567273beacebc1f2a8719998a7e0f6880bf70dc8413195a41d546d4234732856380931fa3e5109d141f1296c24768ab3e6c9eff9cb2bdd41ee808a463a8d5aac17b1f794a453912c29789101552edbea4f14cca033185048e6a3e01364933166a72653cd1ef05b3807674b68d21b0578b037a94b3fbfaec0e909dd93484eb4d410eccc5f4f731f68d49c9e2d59a4e3fd361331aae84280389b8985fe379d565cb305ca672c903279ac4617b3f175c15148edc21cbd9d0cc2624ba0401c27cc9fe8b33f9d05bfc8eca888fe914201020cf6802e8d317fa971484967536ae85ff6eb025e7593060323434d4ceed59b245c23e0b9995674c629ef4a76e90ea69a6a80d381952fcccc2f2a93a7bb90fb69e3290d7f7b0372aded703e84b1f5db3b650ade41a2f4a320cb7b16c8fadbc410b6b5529028306e1f58fff3b2849254cf18976252504c0e8bf9b1cc9db245aae1dbd295bd15b1ef18408afbafecad2eb6edad67789e47aaaf82bb90533a4e25436c583395446cae79deabd1ee338f332b49d24c5cd100ac148bf2a998d849ba0326276a92da9f8dc6dae74a8ca8d6500180da4d03320b41634712486613116942bf4ff93e7645c61b668d9782bec6b00c78a4277362d80c667fb96e2a811041d1288b248a818efe58e99c18c18b557662cf2431185b2e230572ae39e735f313379c493e2f63fe766aafee71cee0983e10c80ced84bbf2c1ed85239187cb2587680611a3ad55f33c03dde73ad1c5b57a953c0ff1cc37f5369e99f070dd4ef29ce60036075373ff4fb725d2d7f5b42c89d8c7d5437e70027eff08418128e1218ee50b7891f05750d59b1ec137ed36dc39d3c0d964859a427df7da53d0ae56eb40cbdac16a12d9ed4e964e055e4f64db5d06ca3680e5b962d55d86fb9589093b27b4d5fa92ebfeb3fbf6cf23e3ae23db8b9d311f6579939368d61d0b764d52d7f8c8e29bda41d7d341c4cc770ab8270ae398a2eb9a63bf0c3ee2c58a265697c9e6b6be7c650a05aeafb3021c50c4251214563f68fc0914473a0fb7b7c93a66cb487519c84e179af9c31e6842b1d2b3a0952b5a217710d8f59c6f485a86691d6b48fbad3d85b74cf9978abe3714d4c83044a9a1fc47c080818418e965282fb820aac8335ae0102effd317661af23137440291116b15b1f72fd11171415b89b85dfb1cd25a401b6dfe50f9215c73dee82dff8437835a6e26d4c6400433eccde35e550dd5cf9506caddb392651541fde529c99c9c5f515324725ba8398a28faa79c20715211326ecc1b5ccff411734dff2d0243a6be5e79b205b6c32a40dcdaf0a35d7756ad117daa58683b26c3f422e7765ba3f4aea52063c97b217ee54fae149288360f23d981431892e445c1863a1244d565fb89f30cb1cdb721fac9f880e6fcd2f5ca9c576f7590e366b48d3ad8640303c3941e400c441673976d3a4f57eb1dbe6d14728f1e3605854f5b4239c86480d7d80607d812582b02ea97a6368e15191c9f55d4b981ae0255ff035fcbdc2da534fa0dfb30f1439b7a8833a6c1b87910b41a3c01a211d1cec7acc5d73a05dc8fc1fb7093aa157fffcf028a018c433c60e552126bfeeb1ab2a2226b7cc7f14dfb84e524cbad687ad7ba000deb0b1ae7f15ed457598fb587bf000a8dd634eeda0729c48fc5b44fb0844ec05ef2181fd8ab0864df4e0276b6331ee5a469db523ff668220a31d9ea59696bd4b8ca7b9462cb83652f3a1c23be5dc702a93894746d32788523279863e58725f500fc055abbcda3b0003388d44f0b21c1b300cb53e33580cfe82c60441c00b0a9841cb4131452120be00e9fadc1b91b9d39940fd977e0c45f8a81b980ad6ca013d45122a7be7b3040a006896b682d73a4757955cf321b485f62c19d585bd5fe0eb830dddbb4d055c845d510e95d31f1b6a3e05e17e7903a9b9efff05614e3e851ee7e762c2e533261d758e7e4c6a8e708f663e97e291bd90c1048c909922c19831e75dc8254683a1536eb8fd86d756d2dbf9fbb1ad598fc8887fe5b07625f723028af23b49f90d74ac4dfbe2fd64dd0ebd1bbf50625c44833d40fde5edde21b8d9abe5325d8f9676c8fe26a20e24a23ecb5afdd23c84c9abdae03bc4ccb819b6a3d9be07ff1511b83fb401df4f5673cc6ba746d7ac880f05c7bb3618068b06f62b682f141263b565db72579cfc289e5d29785b18c5e301e0ba8c9e788e8f9d2184f83b6dff6356d0abf6f356409ee7e5400abb42fdc2ad235c9408a5fdb7fd1f32a0ff497eca0da1a4a11841947600ba43a3d3947a53d8bbed0a01012653aa135f55f31e152a5b1882bdf393a9b21e71ab6afcf83a9d13aed082412e837bfb2ca3e0a8729f0737a282396c4b351bf1705fd74cb1721911698e6d271abdc053a831864203f7e06f7d3a03f878993daad1e04f828d023606f181de7686f186ef58e88dd1425f18f8e33b1993525fb1738e33812e65f7b421d5fcd924cfb73708e6b1d78ef7f01b99027923570561310372a1ba9c1135836a1da60e06485e4cbf847832d02394ceb8804d53cb9fbf94e1f12f7d8365d1dbaa96d11806adb8b9de3ed00828c68ec4dcdc67bca835dfd0ce23517aa5b0d93b004c4c91641b281672824366a471f80a5bf98d75dc3fb0f23119baec9295cf0ab7e025adf6ca1930411ec0495c6d74ee6e40894167ddfbd291dd2b9aa4146aa5133ca7c4021dbf0c00b1373c433a434cf68b0c9c03ab48325116672cd5c5b75597bb56e8d545fd9c84e7ab9129afa33be8003663baf5435becd8afd2a5eea4cac420fcaa26b1fbe0c596d9e55412ed37b1105c65319ebd5ce5810d61b11f45c0310483045f962af3a5b001d2a25ea50e010b6623a44eb6c8116a505b29bcec44880a077ec75499c2da010c9538d83438d3351c57ab8385b60ffcdc1d4158cf4019c2a69d5aa1a76608e2632853b9817fb46109d75388c28a88160cbac846432ddc14603e78190531653a60358b726abe0a77333082ef7525ae0221b980c99547d3860c8f1b1bcf1f5e684170b9a630c287b95847262ffeefb3e2e62900034f6142942f715628712c6eda816ca85a007642b702e4ae4514bc99f5ded2f95d168498bd04f0c0cb29b3d2212b373c42e31707f629ecc9d88bc053a46fe9191f8a5f01c80e9b640b2871420652e52f9d348d3145c1de2c3f307d932c25ec27225568f8045cc3f43c7d67632e5d6e7f9fb0080e7aa5601652882df0598093652d89edc313225d9f5a5911bafa06aee181750b3aa69c65d8f7be7ac2706e3e2367e3443ad6f727b49ddfeddfb567e1f72e082419b5c0ad3ebde9c229e91acb04ffc47972370e9305984238919862463da484b098de355fbd7425e222ee7fd66da18e0aae5962a5323c87c0ca2aa6c92e9de47d2444380247781f14ae8eb08cc0c74577589335167ea5112c3109ff1b13d33c5e6ce31f14116e815f27b3acc5e7e1d283676a9da26b2bb9e1105e19b289f738916dc5d283c4a32e5ecaeeeb1a701d3b426366d895cfcaccbce1c892ec73a103c5c39e6ddc09b05aaf7c78dfd6aef740167c16e165e318b9fe5d557f5981e6a3f33b653155374a6a536b0d694f2ac39926d1921dfabae9892161b55f2e43b05422341d0b78a148582ddf37015d2422c69427fd39b8c5f78b20fe40e37a541fb260885a5b596b2968daa6ec130de97d3f655c3152b91c4ad60dab17b57603f3cb7a232748f87f0469a10ab441f68fb7a1221fc9d1257900fb682a2cc2b4405f345fe7c89877da19707d4eff3c91ea6fe57acc9a38cd9c2eada13760a2205fb32400ee092999d24c79542585c326ae3d2c0380b0be11fa1ab01b7420c582aac8390890b9b643ac2f3cc701318cccc628765343cf9273d1db2dfe536844236ab87b1e71f1b155d435af88f857dadeabe53505df61da70ea7ef46112330ec9c4485c0e5c011a23d7d1303873df1981ea1cb34d23ef13b2170c8e9549acb9a836fd81cfb11931a19e128f78600e7622ef79fac3c1a8551f41aacac0f1ca6a030100671d79a32c9b1ad0900245234d944e3bdb80e949e5018676eb67541f9f8be673dcb3ee9f5b77addfbd07437efd3a0433a44617972cbfe99210563031de5d993e36db8139009c11a1bfcf47924a10725d4d8a2fbfe93bebbda376e2219eae391b7a5f55699af7b4ccc78381292f1898f623bbf4dd7f372cf5945f489dbaeeae9f77a8c4a4770fd0fa18e4b8c3218b421588aba2506119d1e1c8e3ab5602e4166d09a304e6105f6c2fde3c2409383f7e0a319ddc7fa4b6e12996c04d37391899aaa3e42534e6de53303a6693b744c52844dc223d9a4102619e59d77705d3eed7185589fb398401526eabfc303ee3446605671fd0c012bfbb248689a2e44b0e3d974af3af6745c6cd46987ce8ab8b982f9013892210ce5e3b109e318d8675c875c5f42d3f04431ca16a40a77f821ac2b421eba11641738cdf5537a2738a4d98b44bac3b86dc4d1f436a5120e01300b68a62e0ed8a5c561044b661eeed670f16822e5be5d2e47d1fe413a304db21b1bfd270cd3869c93544e34068d0710b2af14039f09759698e7bef3d59f4041295a8898ef0edb65aac6c0f5e903b8901ec97ce1e7d3d63939baba7a9c58aa64cb09ad530dec7c892099625762efdcd78c96b1f1d3aea974871f07e2f6b91eae0702e221b3237d9e1a51455f681891bdca04b004d126e761b39a84a3ca089e413fbc7e41bf0cef8590e61f171b57517f4806bcbb9bdf8aacc402a60216bf5f3dc06a3f548f947426b4b3fa32be8251801725c9f289781589a05161437df5fbeb80b4888bcc7de477fc79e4a15842f12be41e7e25d2365ada47492271928c02db5bf1a74850381d7e4ab90802b70ae21c7c6a0323590b01006ac420b482896d9b49c4a5269246ec3c4e11507075015e63cbfc7f620a36b236b6c960d983039b1895ff5d06f4238d8146ff21845f3927e734ecf6fc24377cf8c6575a28463ad75ab529baf0ac6c512271ae5badb669bc628318159158c1bee328bfcc5723f027cf10c3b2eb1e951415728fc42b404dc0d95ad75f412b76eae21bef6c31b485b3ee8ad32d06f4d150b77ad0c80cd637aa62e440abdd8245e418149c4bddfa03362e3b1f244ab3de4f16a1ee87d64d592567bfe1465a79fb834466407231bcd4313ac00ea367aca39fd176fd628bb7ee89ef35faa02f14e94b25b452089b4371f1d45bfccd939379f5d64537f293c2967f5f7c75aa220363dde89b9cd2501443a0daf34a4b50b5487b08de096f54a5e30421ae4150a0e1e4de46ce60c2d37b3c632a7a0cd6bf0f03c6bca23f974833223386d510070b2e815f31b931ed48074c169d6a10c96b661cc0cc55bcf6ca7848e399964f542a5e800bed707380fd90684d5237264b739512110a485a749756d0cde032af7a3d285540c519a8a4d708feb2628f1ae02ee982ca409a987f8b746897e8922547da32ddf650faf38e7f6f6bc50c8343e94efa76a53166f11b3860320f7dc184ffa692567844d56e3c5d1ecb9d4d5ba42f286d54aebfbb0e99a706efb7e856428f5ac2b3c43cc95d831beaf684e5ac1bc5116e8454b24a6d1edc5161ae0cfe5a6badc023dc003efc5f88e6efac8e4152e63b57e877133ac938b78b976d77b65cf5784a45df4202e2027f39f3ac4f9aaa47f23e6c1eea4a74cfb46059dcd9fa32576256e0c90137a53bf5578636bf4f4a5f4cdd54d52fec6d7d1f9de475ccb1ba7e356feb7b787298438eed4a04d8c31ab998821408914d2015ee854a8af99f077fb1b85ba88d3a0b500ccc17160152499f12189f7b63f04490904a13609747e2bd48a21977fe79a4d1db6cdb6d3c4c9270ef1b34884388967e0fc0eb15e5269269ca973a7d041340fc64665dd3cd348a6a0d9dec4cf3641691bae92b91ba13bd734f4297df7d7a444157582b5087f204b3c02cf06667f17791993b649ef548dfe2234a84fa6e12537d0d2e346a1c10eb61213ccb009c4213b7722a4ed215369152c79b36acdf651f16d943e815532ba95403d6e0db8f5e54a34efa22b83ab16b086a13e678bc2327924e5234c3d2b032012e14f64cb89709a0cfb6a825dd9db83b41e26eecd96930331643a051f00a396a0860691deceb453cde7751cb0439993f85a1139ad3c69abd4a65c7f83363529c36079e6b7390b9eb3c427b97cc966e71e136a5e9f91c690ed2143ef2dada92570083181713b877c97c6199f071e57de4d520af5ff361c6d16813245260a2320da217287bf97ab71ca6b82b016fa1bec95b7a5a18d0427eef10a612581287d7759a1386d6bc1fa64a4e3513c92ecafd5071e41439d74b7834157f1068831e867cd0ae561530106fcb278ad6c25fd97831aba73c7cb305f2f059577a7dbc7a34a38d4dca9b00fe405da7f73363bf7692858dbdaaef289a997ef65de37ddf24f013ba47009b5ba161da95d1612030c60b02a948b32b50a2a521fa07001bc5037237330885a1d6b8adec71049a3bf98225e029d0be4db93a356b7f2057da3beb161c0fc28703a79d343e062084c3c075a870e38df2a3262093f77893ffe927785fe547738b8a5673421158156d10ae31e5ee0114000e247cc6f60a75c8fd24c72bb2a041318a1f7dea781fe98a404d0da9b66f9f387ebb64b0dce632cbbb86c0124b698aebe5e497c54f3763969771a8817a4b04c6d85c459496935e6a95e43860da7cfc51d7b5da1b907ed34e9d18165d0df44e1e98093ec5c45ef0f4fa559896d07bf1b8bcd1a10d028ada9fde79a2a24a4083db9cba0a6c54841ba60f9eb5388fbb58e48db0667a7149657aa9021b2934ffd42d82da928eb8eeff8f6bcb8f86193e41afd71e435441c5466c8c14d26bf2d51295f3fde86effa3c92d2c01364b7229b75e9c923f9a65b1f648ef85782fdd5385c5cd64e82d0d19a4317ebc013f1b3ef428d8ee5398c17626c119925708635daa227cb38a7547b533908935a96fe9b0174c97d805c1ee6eee5cac62945a123e84fc68b3a90c41014a79fb92ab4eef2eab02226345d3b52ea3b7a969f4f635493b9fabacfdf940a5b079d3847751346f451cd19437b5764a620368c2b51c832d2996cb78d72d5dca1d9808ee6f62a1749fb2069aa955f59fe0c09b9f369d3c0b7334c389c040239eaa21d9d1c4a2e06c869f31c69620764061f0a09e0167b920cbbf6cba2e93ddde140aa77bdc802c7fd556638849abf6db6f11ab1211e3de3a7d39915bd797d3dabe9c5ad18733789ff8d34a358eadf3b49bca45ccb96fe0646aeb64c65ea5de70783271ea021ae54efc2081ed24108021c0ae04b6a82c7040133f3e656ee7c4c011eabbb01020f3e4207f16a68ed1c423fd4ce43670c2bd1ea24dc15e17887a0db7cf43fc0a40993ccc5defb899dd01d3fc815abe1dab1e97e3df01050cfda494040298dfe5cb2c04c74beef0f43fb6d15210bf0f0a1dcf15562169d1e04ba7b53fbace227d42cf50535ff70ca6b2656e20330e540548520266142428c749e113ee6175b11d869f6d87c5e324a81712ee7a490d1a00bb32bb2cd1507f569f2a4aacac888e0c9b2ff679ac812ec17859cdf3626cb588651c4ce5f2bbac7937c5fe9a2e2079112a20f80591cedda7530caed04b4908f24fa7920468cdcf26944586a8ad1ed4cb95ce03d32453e33d54cb5cd75fb09f382c55bbac0658adb37e277c185ea3df26a82cb80a454a2c4bcd519de95a68e68b78f88f785fb055d28926f198e87ec16c1c054a2b2a1c628d5be9b6c35c5ce7cbfc51097cbac7aff9ac51c2edb61db9bd34b5306a959c8924293fa06a13450215fd296db13ee662a8ca608db7818b5b136bb322ba4024442eb76d1ceba5d59d876f3965e2f03353884e4c015d316dd5e42652e53ba8c6d37609981bdfb60d2903f05e2d1d4f6cdfe1146064381879919f7d4b36ce788efbec62b37283ba0e0cf23900ae9575051143ef40ab0ebc84d89f514a5303787aab6a477b625920cac38e239e936a6dc4665c674c1e84ace7044f2f02f76f075aaa6d823d70303b67dbd3c09885da834b14e251bd0dd708ea49368f30cbbe6ed4c4bba1ba7743cc5cb71a748859b5a44909c3b74948b7da89f9a8afce55d2e989f1fe301b9b80182d6862140b2f32be495a5e9514e3fb322ebb885f50568c48d3c601bde35f36a3248d01e8f04b5f4f4d2fd7c1a944730f32c4409eabb2d896cc4d77938ce59c01a546015fbe27b19b4c82198c72e822b4952f29b7fcf3464252ec1e0d3643f90a325dd813dc44ca8806146b61bf794acb04066a9fc4f88c4185a98b778a8b4cdfc59ed309861e7e4774d27bcdd49cf323d49a5738bf230ea3954100791ada3dc8677539790c1e11bc46f564fe194ba40bb6a4aa221fcea5d5f4ee672163c65cb9449f10fd14777d1efc2bdffe69cb18243fb0160fc4e2af3b48e6008c92020ec957b0e4f9f515d454c19663ed8b04ed7ebe6191f0824dc591e842c03e6aa7b171210eb980d49442fb61ff138ce00df1cd6c7c4c0d5a4a97844a32d4435eaf9033a7ee76bb10ee10285a05df6ac1fc41916b09ba74fc55f1311c14acd231c27a0a02abaf029cc17cafe328142c81d625a94cec3993bb0b45cb02ad9594fb2b3ec348f72865c8afcd71b9c3c91d3a8c4553fb6dbac0fc8a9d29abd00cee2e0c8c6feb9ae8bdd43169610885a50d1983466d4fe4f144cd461a4de1b188a590667580b4008caf5e8490018cb9d8d048941517f7600f4be628ae95926588da20fe8b996975d4af69a5e82d70968b2d450a93ec250d5e392aa950774e141157f37d19e5167519296b4afb6f7379b80c6b174669791726a0cf79afea1283fdffa56e01a02e2e5ebbc9a5f2d4767f98d8db783eb61480f75b400ca90462ec48696308bd2cb7b6ebe471295351fe7efc723e968ba2561683bb4cd835e2608ca632bc0295594d7c16055ef8bd0bbb38f3dc434af95380216559cb6527b0f35e206ea472686d1ea3f5520250386abf8c880d1a9dc01f63bc4070b24cbd3af724b3e6330590527127816efb5c9ef1c699775e5a8ca134388d5229127c8728137909434cfcd7554577991f5cbe52990a76a998aee8b0a37454ffd2dc840a18415e56fe79fb2306d8a7306f5ffc9989b91642417aa992d51fbc659709211a8214b00e40d152533d95a10f8a7562d3b67f2cf6d2fee8daff954bf322f1d57e9ce535646e1782bc3dcace98cc9d060b06f79eaaef012652b2a6c0cb6ccdb2a17ee6659352deefde10d19040881398d2c36a5341805548283354f8dc78ecdc03951f9c4c140d8ec7dac513df2a06211039233066f541c85e79b9911996858229a45188dc7878f00b6c7d768538e7b0193c10cf24b195d2c46e76ce38852177b20aa438c98bea57cd55fea7fa6d9d7376d85bbe5505d45f65c5d40bb3732e4419b94df4cc5c23418e7e28e5fd414e5bc7fb35a20ac443c54efa901640e2f509532114ab54395201548f56a45122eb6b27d5cb1c75fe9ace209cc01179c528fc2899ab67eebc5c8da5eb4af1f5ce91bb977556c74d993802723d3d795024b60acebb23ac292c1360eb196612f8b8f0f95fb675f648f38e1b9f0b20dc51d49b26725da2fcae71e22e23fda8f1c4302a1719312d0b978ef31d3c3b2f5c3186bf4678510393f090e307e7c2a6e85f70910ce6f37d78c756a9a19c2e85afdc562159d9f0a1c5eb7c20458a05583ae547f3a0e98581d97bc6185248b68137707ffebf4835b447452b9d008ae610d660263870e614b1f8a649d104b463afa2c0e9d1e5e6fea84a8a8e3300d4e482c013a26b000702d45dfd39127650c1da6fb13044d8866c28d2355bc53cb7fd6957f8345163a6a016ce39270bce033c2749b9d99dd8f6b9361712cc9ca3055a651dff241cf4ba4bd9d58b0adfa9ce5fd94f5666a70d20d7c16cd0d97979421f2e9bbeceb72763e99626236f5cc21ef151bcdc4e136d9f9ab145c5855a1afe50d6fe21322f2419f5d8e5a85624a33b52f206a8a70270a1b14468aa0d0a7a6790f61f9678ef7ec722b4715c6092b2880cea109d333de031e1e4b7c74d0ab4ba847d6b05100818269bee3638f24624684cc8b1197ea8283bb44c8fa068ece4469623951758d5b67569733a583d111cb9d836d415ddb92e10f9c050600076106e8ba553a253534ed2e9b67f49db9bc595a4bdc41e9b46c487f0f9a2446d34da4138175a50734389edfb45e8b9d7581aa68b702ece5d62643831251809cd1a98c22f02ec140cdd205aab0c797e39b099a938e46d4569ac727182a55a891184456b594d8a4376b1bf1c3fa6e75c0e41f78b22c8f89e1dae6769dfada4cd12cf2a7778b84f72f69ce48b073201c038c7b0802b99628495053fc14710cbc5e0e8abfd12cce07cea9c083d8c7d46b2cc1d9dbc86135ed6844b794979a9c520d90413f40ea01e4619c0235e81ace7add26941322de08284aca4ccfadd059964d9859cbf329493a895078683c8616408576719c849824321fcf0c3423166fd0c2584628af259204719a118348dc86b69f0b00b6da0be8fce982409d86dd9db0ccc037ef214b881ab47ee5fe85b054c54cc72b4974bd2cca7f6b9f0050c2c999639c179e9fd4503d8364848351c3fb7c744fc35938fb87390e511405c1bbc1a182c9ca4fe876bc590c87fd214238555f800ba5738814065463c21eb8a7bf82bfb30bdd0d9fd6265367f25551e481d9e1f54c4961f1e888f840f036f05db9359b1c43450f67b3a4b31b2c84b759a68e108d7026b22c458e415bae02899481a1747f06505007278b2c3be7fd50b3c2ae9d64a23a265fcbe0a44bd79007e0fd1605a4e08a7df7df3b1ccb4faa038eebe4d77659e986f62856bb5ff2437bc2fd258187f5a05f958e6cd1f20fc3e9170fd2146ce3696198fc88961e850d2e10114a8ea2aec052345e8363f87bb985822b924c5b152378890e9bf3215f0467c3770748c3a2e5935050db2552290f6cdb21f361549dc992ac69fa0ea507137bb32e9b94a1a8ce77056b529ee3852bb489ab53b5450a8955aa8378f2326922bb3463a77f68681c690b692a515ab767526c6d2d15f391974e4b22f752101ef88334862ede3602b7376e1fc426da2f30807381a76ae787de97c33c09e0ecd82b87c30fe500b0a233ef7ef883961ea4292a0eb97ccaa47a82628f49e6f38335a040bea5c58e3e0b232351bd0d3a0c6ef8177bf57f169bfce6fbf2f580297a88efdcc9a53121b72dd1eada87f38d2b686b4523d76b3d68290f93ac72c0c0481a9ae849c2485381c0a80beee10aa1b8dd2076f9caa93474e4d3b90262317b77546c767dda5ec71648ede2ad8e83ffeebf80ffbd72f8ccc5b60e8b8796f0de2c9c329c8171537ac31de099ba44c58edb7ab9cc24eb291af9e322e3c42a29a865ced5b7b71c3939083dabca8f2137d75e58d7b08819df0b73142f3e2de7c25f016c96ff363a8011264e79ea28e81541776db0e7d65cfbac2b04f2e0707ff3aaf0955e181bd224b7030141071bfd570e735b994350b7d95cde3610b3e16df0e82a57bd8847c9088bfdb1385ef48f52ae024257a47302db1fbad5232d2cc733b4d2b112124ccaf5e4d29b1643f05b8c7aef02b90d5afa1007de4b82807ca3612d83e4fc8b2f272fe6b652bcde5659e3a739b39f54f96a0de2fca4062f7d54d6aca815b5c405cfb21dc1740f9d386657f4fc7b9bf87f923a917f0bca75e1a65b7bdb5b9dc96ac0737efb22038dfc33dd999165444391bcbddbe13250bfaefa1d9ae97dd7a0de188a294068f09518664f7862507a7002163ccb9ca47248dad022c4081d030f6fc75b93722f8624fcc6ffaffc05d2e53190ba8bc570fdcd480ccb8e35350e831db2371488eac6d21d8fd93ae779d913a931dda767069759e5eb96d1bef211c991b4381628cb9226d3a44e8c6f6a92f8b945df922adc5fff729f0f4937a8b3c47e90b1f65dd7e4a2b8a4a1cf13fb88118101a9d2fd60bc063c6740f0b1e560ebbeced176dc6fae3500f60031a6ff9fd6a61e3a0b44794ffbdfc2f0bb3e7595fe332d6997555dc3c93e19647b3b4005de1c43378bcaf37de93ba71d8f80ef46221518ea32c3da349052a7c9a8bbc93dde49375c874f0d14b6e9a9704e2ed511179cd465a92097c1390a383357c8c13f6a6b2e33735691f8dc6a6464e4a32589202577c6a0b95e2e98374f64ade65757450e592a31305286406e444c989f6c71c36a2a59aab84f5528bf0adabd34484886d773916cad68861f0353b443d00b30ed28d59d8add28b7123ec1b56d173a35b27d82053da08298d59e50cb27d13572cb9e28572aa5b070bfdbc66411653fcc9025b0394e214f2cdbc51bbbdd6a1f51fe76878d432420b27e209f1aa6749bebc6e7c51bc010d0ee63d0e87af02f7231066c52882b91daeeedc0a82bf33e17fbdc8568cb9a512dee9c98802a24ac5be1b7aa3b4ae9041e1f8cd11cd16f314aa746e5987776d4b4252bf88b840e93e96d43b836977d69d7dfbca2f8d2604f15c313dfc6879c2977dcb100af7c63b5d000cd4e57928a4426c48fd9e62a5eb4d3061268d21ee1c450376e113730855951c14b8e19d4a1e32e7ca9cca997d65b4752cd32088bc3af831091bd1d724f8cd1289e690c66abe3110ce2bb07db2228f4cf1f77a6434ba0e0593dcdb1f1a66588297c00c0e69b3b494f6b479a629a142013435e079eadb02a11a3fe0c2f1a58dd0c485c8cf4e952bd97bb83e1ca310940d5b5995e6c130849997c3655f2952aa435c0040ff708eff95f3031cefa7085cd0199c609ecfabdb305a42e7d671c198f6cd303d42c1b7102b39e674565e30fb0e132b80b4bd129bf084854369b071dfbf5e916c33c1202774d43ea1076589438d5640c04a4ac4e31190e463d471fbeea094b6a04c11b409302cd33ffe0a373b6f9f0bc7ce93df867f082550b627bdadbb2761ba4f00ae4e9c1ee6af8923e00838cac6fbb218c3baf985bada4f770155337d58d369d47f68b75480e0078e2847d5916f524b05247a452bcd835db02316ac82fd7ed1547b82bd81abb8a429ab943e6e65b92ff9c74fd026713e30d8eb8cadc2120e28a01e493f8c3242efc5b035bedb32271cb9f9a6f6fb731c71c976dbd8851ed2fb7ef8ee0ba34eb694898f4b1c6bd44cb65162fd717ffaf3ef8ff8fa2792f0b72fe449f5142c8a4a63d7e0653b204a552d3a3bee006da17bc4d29f8230a31850945435f61f4b5a74e1c3733f42c9116743a760a9c714095bd60b8388552b93d404ad4f74fd5458cc7bafed551eb203a09c94c302a2198f2314361da627221ec4869a5430ddff265f1ffb3356d29613fc72b293cad7b86348c01f42a30da64d7e2544671256164dc222d80d40b3b8301aa81f124c75b085b48f77de34149426ec540f091c8cefd38291cec4cad5494152d8269c42c1f87d5dff47538287561e718aa57bbd7eac045d48bfde19ffc9d75782eb0d43deab1a01df55fc11bcaf75bf4d2c34e267fdf3c4b8252c3a033b87f71a4b0ef74c7ab31ba9ad3160e285e9ceaab23359d9f6e34dcb3f5b6d6a3f19931b53fcf4ba63ef4daa15c20e6bfd50b6751d70f63811f5abd0b5778e7f39b9756fb3c97dd3c19fb3b7a02a91c40847a777745eecbfad3a09e17f0faae0fdc99c5b781b826c0996ad031039b682bed54f6f67b6778c06711956fa26bac33cfdc56434e60d58692d50b7e94c362776238261e4dbb67ac5e8d5da4f6f510e8061f7046090c63b0a75d0f56841855eea59b92fa80de449eaa4bb8a20dab36042e631bb5ae1dea6e89cafa67c04646d045101436755468dd580ce4833a02a8b1b9215f90d46137869104b25c57706d449ba4c098144e3441512b4efc9a449bdd59ef4d83ab238a2d7ea2f05563ac8e1e4fd3904c0200a7cdde6c0f372f01f1479865cea0c357c65478173c60b1316fe930d48d0d4b1cb9fde2141e387558d572342d9af20b801b50abce4a212b79f5b0cb44abb9ecccfa20a701f498bba01dbab1d9a55395e1734131218b260d867c0752cb1a4e38090f0cfb51a65686f6b0f5e24189111dcbd34706a91dfaf385c422aaca3d03ad642e558035d6d5f5b4f048942cd077682e5ebefe61fe1e3c8db33d7ae68ed3b3605f9ecd8425382127240c4eb96a397c3ae038b6a146c5298139d002794107fde035d7e81a72255a10411216f33ada1854b41c87bb70081988b64f283ce194f960f5b58d0f6bc69d829990569ea8f68d82e3c19b4b87d91a2b6b2f1b237147397941b66b02cc56ac082f694e431688e04bd19ee2fea26a93e5096a5f82c93a67444b5a1184ef42eb4c58d4a16a82ef5b2d636d93582dfde01a129c11f50b119e74e45808a3913e20c3983c30d5809b30187ebb8b5513273268ea0c104870b074228467e608fa4ded99cca9003a62b4eb99d211d934da1626d45419aa9488b8487bbb6e04619ea521dc44c404b9eaba31a2e1956bbab008bd0fba2a7fdae3f170bc000b2abf1f0938d903e785aa8909c922eb5f1164d8a8d4370d129a737e77e9c5a879c87814c26b71ca070d3800bc1a65e7e929bbb77bd26da29bcbef7b849382084907060c04a0c425cd4f7d218afdfb3abfe6d15c31ecd34943bded1b2e2612f2361a80edca4b363164baebf9d90b893c08d5869c30ca21540ebc5b1a8c795e2f68d02c1135455bead8dbc6eab947e1d04259963277cf926599e43ed70b7d0e074c6df322694d5927478ca20ded75ad42ef537e12caf70a3db5e5b237d25224add879a55f4735c663c57d405d4829920b6202b3b4c321124d71c81c1ceddc0e9e75c298f20c65bf24f268a263e2a2e1621cfc5675ad67ecf3479d8a237cbf20a6d7940e1002bd03ff64273d2757ed4276e0c03b845778e71388dc127238d698c08f85087674f70e7d749e386804c9698809349e695f386e10fdc3eff0b369245260b1c183718c011480a82810200d93d25c3676b195904b0630d01a0425e71face394da1da86ccb8bf9458822420323c880304a141f3b576737c1c573e57ef093369ee84ddc2dedb36ce62694d4ab59b8417b8b28222345cf4f02ac90c5872c23e2912e1001cdfc9c1078eaf43c274a5f46c324be9f797c10b0bf3165d974d3d1ce5d35db6c9f2df5d2bccbe4ffdfd04e062e62fff7bba3ef01cdb6a4f9245304a080b5ed68662c1c8b54f8d40c6be25fd7eea66b1e8abb00a33af714bfe3286b41fe6b92e7eb8c2e5340ce102385c506d49762ca42f17406cf3dc7956c76f768191ec82edf625b37d4650b356be28e496e9b566265919eb9cafdd39d5c200d94801f2c14549d4955d9550c322c1f44b33942ab0da139a343a4dffe85dc9f4520cb826380ba58c9b6f2037565ff3edae465ea9adb22263f8d6783e9cdf4b4e91b23744a5d52dbfae044260ed96942ed9e7c108cc801b69f0cf415bc3abc0e9ad96cf4dd6bde72640a8637321384d6c47d8b21bf7b6b15f8def3b8f9def425331eda18d8a58b94ab52e7496d675d6863c3b95efca64d347bc3594ed4d510ed618fe94fe59bf9d7e186668a8ae8a21b79582e5fafa3e5e605d7c6accbffabeb7f5ed6a9819a3802951e5e9460691398744b055705d503b555a7bdef82f674e6190a02f6764464d9de24ad2feccc48f6480986ab86bdeace2dcc4e756b3089cf23033bb17b5b8894ba6f05b3dcc21a6784851a39ee8b029ef1956a4926b774d9b3a6bb5346a5045c44bb716e36407936d87788beb8ef75402b47e77c784d478c5bb97e4394d163a9c2fd41b50fdef42f7ee952e81705e21b8b962191c91df5e04a399d507ba3e1b1cc80eb27fb1947ea3907ff51022ad4e61b62fa75dcd53ae11b1db3b151be88d5aab08a2da46c2b898f01236d3f51108e47a7cc8e66a8162af442afa979da902acbcb79763fcc71e1da568c4e7f14c7e689546a4e9cba71759e281b34fa593c8711c522cbd520080300e5223d2851e92b019c820eb4cd72bc8cd654195ba92754992f7e168171cb9f0f601b44b1ba28bf316864f9f4c0086057860369b9ad8b98b37248bb3dd0d464bc43beaba8bcbf3e9acf636de110e45e16c792754f0172f0b7d65760aefd2f2c42a41087f6c201d47ede259450345113462e560e01b873d9b8042ec7e276fe5ad8ad7c464a6680aa758d5a6d4aae98ffd0abe07b76a2c5ee394b898fa62d40da744cc6380525edad1546a7d3c185a45abad5645b99eecb3fcb0bdd25c4cb7c6af105c1cc5ce1a94e6e5692f010318508c22e85a17cdde74659849e55962a4aecd09b2c1275584006cc4f25411f03fa866e11a7b9badd9e6e5ea93be83b5a48f9eca04cae28aa4ee1e9b73cdb9133257a4c7ea84a3c6743a8fe18bee5ac868a3b07b144259202803561607879d5917a710785dc00897c7346d47dccf08c104d8cf8cfd699718213c69786fc719d3b4a17658fd94d88896656d44eb2d6809268fb15322f2e2ef0c3ceee0083406a8d49061006664c382660acbf69ddffd1d2abafb47f67098945f1688864ff5852881ac71b2babcbe9c2c4953659ba564727f44f646d850b967d12ac61e2a284dc27f45b05ed25229bf6679d77f11146b472c0cf1efb0f2de94376032d0829c2d44fcae0e0a6616e1ea61eca525616f4d460180e4501c6d6b4ba9289a9de8f4a66f64e5e8a899077796566052b2bc80b406d4c34f2e26323ee105c386898bad5c2d48a0b0127c8cbec549a6ae74a8e9a02968db2d694f8a68608a819a710c7795932f274edd016664d3428e222f3424525a85018a44518d95a9a3faff4505294aff58ded2c3a41d67f154596d3fb6a09bb2d71b31b7788a58cafd1b2b75e988934dce03560e5c596d311b93bbe9ec878340e1219c5fb8601b9882b92bcc339aec82465c323751328f1c6a35329c26c3eacc368457c9270a5697cac5803c649b047809a87abd49f578adeedcb1192ab30a2790197ac80ae409e868dae1cba59bd163fc1d83807632309340a4211a0e093e9ea3d6f2d906c6097d402d631863120d25320ca04903f4bf9f030cbe600724063be494f25ef2777b1802469528496ba62007057b2525142b92ed5a9ce3aa1cfac875a2cb24ec1ea29f5d27482ec4d502b466b04d5f33e4746f6aae43cbf2898f86bafc12e8c401d54268d693b9cdfa734176a18bd00456890384e0941251e6beb23db2255fe4f1002c7ec343bb23d870c9273642504d84e997958751457000c3a753a3a9a30401a4bdb3fc38c4606b2219c4f300c7a31a74fa23b1cac1e83f0c29ce42c97b6e25919cce381c91eee66e44db09c9b3086c088e2c45b7f564edef16bd85df3d903a888543316cb86ddc37296d7eedc1d7d48d5ee0582c23604a2fed22956d973331fb0b43efb7e21a82a7f87d485064153ed13222d28282c5eedfc77187ea96bb28e9c94dce891c61cba4a55e6d673fd533b116455838b9186b6c4e2979d290f3a433295a4b9443d35545cf256e6dd029840b7f17be831984ba48b857d4070da6f595a047dfd0a9918513158adcf32db591324f4bbc3d4900c899f1bd901c9f1e5195c39dd74c42f2fee224042f67f43ee7b0ac688a612ee651a96af157e36084b2547e3224ac122d7b8e23618494270879041566960ea9edf69c08a983b4853abfda6524b5617dc315249b3548bf5bbb43fdbe626ea59dfb20d7e486ad237749fe296965b3e7ab57ca29b32d4ddfa774643ec991de75579c4fe9044ba70031b8a20f117669935801553184e55ba90a30a691892b6a2547a828ff4954a7a6ea7e4e27ae4cd1cf07c29c92b47c5c863595057d4e6df0713e5797d59272094556c29ca71ea32b918761a68a6a638d247f0bdcd3aa7b8890a1cba0423ae3549d9b421d179c3e000bd8b45751960cc768221f4fd4e1a308f707e02aaf7db6089d15fdc360ff72b4efe54c5fc8c09824604d94e86c9aa444a07d78474eda9fd08c6c1a7c222014236aa49072492e48eaf6477778edb2a42abe5165aaec262dce8272454f6961290e019c1fce1e7b8e4348a1607b68293e42495560336017259420cbd8612e3e81f3c932c96b89b9cad6874427008b78f82a6527a6a27675d291e6ce06057fb4915a8896a0f598996eb1ae3b19ebd263459dfa8a82c8b1ee0e1eb30b47c898b4504528414fa8b24c6cdd39757e4fb48f14128f79d75258343196d8c2fa4cd3f72c7802abe9dda08fa4b5bad474c8fdbfeb938ee17513a1bde96fb34cae3ea617c892b780088dc0d21afda2c08bda6cee3c538055b290f599d71bf83481e6172d521f2a38b4a4e864482e82901969c054076d8af44a5e6442db0b5f8fb8f4c2481df5df038682a128478f07c264d42d39e3d899807f326f1f9ee882da2a3d29d391e4f5f12e2b333eddc18e26c73f93b7fe7a2f367340cbf0b72b6fdf15403d4d71e7856dd4535ac1b6c4881d31b6ab32ad047a667913a13674f8fc72332e75cdcc760bdd9fc0f6ee12a2e31de18bc3f27378b06d55842ce8eccb0611c26645c7bee294bb7ba05f8462f563cdde3147974fec10b2cbc4dd36d9e0b6a09b9ee17fa6c7141dc18953bd309414651b6f71eed17f842ee541d3c7f6248d5924e81970a33ef794ba97f511acc168bc3d031840cbabf5560eaa7f5cff8b1f2ef935f494f4547945e73c56aec01cd984cc3b90dc89d80fa31a5d285b549a9207e1d89993bc057f00aa52fff88e7405c11fa8bea7e62dee3b792e356fae14e435263f543af67c472a2b5877da8caee828ca53dd396fef6c0df803d2d02a53945c0dc83105638c53ceca64226db30553450b24c7dd5a29f34b19385622833229efbb0baec2e5e08cc5608add4416c3cf2c737f674c1c0a83cb46750f5274b1f55aeb8b589367604f9bea6d5282d343051c2aa6400196600216bb765365d8eabc519baaaf53c443393a8ce590ed943f0855cb15e271610020c17a3d0e582c5a592e38430616257ad3d35521369ec7f2c4cf573bce82cf7628fd17b650041de2bcbe72b5df591695065851dc27e21a00a0f6bf93df7c597e9e44c47e6f10f95d89fbc58c4c6bcb91aa3f1f870e2c98ec04b52e8b0bada9138805b5c4e09580fde727357d3c591f9869fa5bb9e20ca38b899b92bdec5166a0de883229adf4d0bb088246e15d5b364fe198c3b6222958075309a84092279454c2d9652d7b7ea526faa7e419cae28c9c3668d957a98291d707005ee9591f94532c0ac578f084acf3489cd1f8096080678ca1267a0dbd00e5478062e504f020b95e3891059febfa551670a7abd507a25ac38f34e92acd248ba3d6a0ca82de0bcd2c24b44719be15a30f9dd7ddfe9491dd7240bb730b0f6a2d78b3cf49e99fc475d43ae9ed60a94c49cb39031c2a9e9065aa5520f5a20490a44a738d15881f4a6b89d9f09aa56749a7394bc3e081169b0051ca2917a257171f70968f8ece38c5d529fb80c505d66319bc1e93c41e90775fb30e2f3dc3414bc2b8c306fa48686ae46e042fe37860fefdc573215723b70a1c64ec1caecbbf687c95c8b3aa69fc8f8fcb8e70272e9a14bd6b708ad4ab35452c807dbf3a886c92d5e78755de040a798cb5918fcec58f7a914c6b014125f1e5b766b64ee380c7e0a158de404727073d68d1eebf10d423b164bc78ff19780900ef7e57a70516b75f2f7101ad7f9b34a7ffa02259c27cf8b5f1a8d14ba19ea9fca7eb119a0e34941ea8e21407e1147d3deb2f579ac0ec0a6e0074ea91b218950e4278ff152a5acd1bc7603343c2e5487d5f6a401fde16bb047af60c9ef6fa0de0750dbcf2dbec3919b4cbb42801f5a948f71e86758bdef60dd65fd3330588a11a0e2d162eb7b061eaa05f699924b52f2d72f0fb18d2ca1895bd2ac2b0704928d00547ca28fa1e14f9035e5640a1189ab0d099a4cb182b39d1c481958dd35d93f7fe4f453718f66b9cce32298e3ff210e550110e71e13b381e2417a78c8771f0cbff2b2b29354128fa77eac7c6c44df8470feadf15640d69e91096a955ac201477bf85eb8c3924009656833822a1241ace5b8df6e862c32166e2e2c642b77a831382edf25dc3756a743f1d83167718c43edf6d4faaa4a98dc4cdbed03d9567474d9b2d9094f5315ba76ee01ab49429f0bed539e5a37096d31c8790149a9fed0fc5eb85447ede78439da77af11f901246a4f049c0d4a0a1d58f1f6146378a3cf2d169af3d01f3d3fe1821eb4db82122e2dbf17bdcd147ffa5b611108b5122cd74acd15f7b32d37e03ac6d1d9b5d1225b8686b6088d00bc20f6d86d086fea0cbc3a6a361c0985c0df8cc86a016db00521fa3d8fc1d943292f66d63cfe4b4534d86851ca54a5993602255905bd4fad32970fe95206238121567b94d24aaabf71c475b1e25c0ac699dd32cf73f0c3ffba857c43c632de14d76362c2071aabe12f1549f7e601a9bc40c6878695aa23e355466b694409274a333085ee5d8244da90655e9f2aaaae170ea550a82ca43e7c8c2aa5b23a20ced1ca845e23cb6ae088399a7d376a9cc8d34e9dc07eb0f349e661c2d412f137d22f9f5f0ca538ccab70eaf04508bd75e320ffcbc43f2c0ed252d10c100c24ce3cd007015c0565a880d516f4c49dca1a0dd2ebaa16d190f0707dcb1e79993a9b23b018231e07f790aa4cfc67f7ffe770fbbfe2865dd44a516c7776a00ff255121b0edb0f3d4d1038773e83b8269509a0c6d65e61eaf2f8245d9883873ca4f0308201367b486bfba21a9ff73dcc8662758a2ef3d549e9f8d247db8d5e7b987a7c432f58f62d8ae53a6e4921b333b5c60fd458f20a28b96e90acee4bb30a3d0998121267028b27f9b1b55f2e684b8c0a90965121720d31187555c4d259fc94bafc0dd81eb1cbd01b4f759eb2845434e99c9af611b80f0b0a826c6d345b5264a22c0453d102de9e573897d734e3b75890d85bf7d3adbe99ef0a7be2da75134c6eba5e4163236a2c92a7891385379f80ff015d7bb99d00f2aee976638373ef8a94c11ca4d672c71db98391398bdf9ed99f9549bffe032d2ea8d88969858cb548cd59c13de4110f9c4100106c66ffb4b6fd93aa64abf2c8ea6f465fd7d2c8030b77f55e8f3f1ea4746f8491d3b894c7a4c1788a423b78242f8a048d57feea4650c42e87a5e870f093be737bb29e113487cd42a0ac88d677256dfa67b1554f8b906abf99a40d0263b70b6b018a4d89d404db80fad2326dea26987fc725d3ec36331736e4a7928e6a70d610f469d33dca207db3d9ee246559d2d3c8b4caf4e01abb8264262224c4854717ae3ea693297863c1b62b0ce62104f4e330ad9239f4e373dabe56b8184b202912960c1b9b6eb254dc97304f18b121ff30db0fb0d169c74d31c71e480ec95e76d5d7c42a53371c7e226e3d91577cd123734facc8c4c9b2830fe83ae4b9fc1af3946171bbe8c49685e6c54703a9f3b0e37c70b75856681153e85dc2ee182143ceb42bd316c61b430633af807b535652943d91b9dead6b47755f8d039c022886dd48d462cda6fd0604953e05417c9b3ae6c85a21da063cfddd04565aa01d31965dc5e14f47eee2c29587068d8f4a591d92b1dce16015f2a4a1107a0e46b76e16b7010d8c6ed24fe1edbc853f0688f3b7a95b61a979728a50ad7828241deb5bf72840287311cd02536e7a696dfab92b1b47fca0f0f8ec1147f4f0afd935cb2dcac30480f4e54079aa874a72c62b7128f890a63d5104dd4b19eafa7a99db530940ee9ec8c93e882e89f198bc1d2af5d42340ebc34998d329e081978c71ae0642fa937f95e0191f1a4a344e53c99f504c6bebf826f8f99b4c45900d445078af7c3fd10ad2a7d5dd6b9b5624854605fb81208111e78bd1a0f241f5931520fa48766233eda9fa0292a8ec2a1ac873016e142d865240f360c5e61e5e8be1b316e46b84ca63c118c05e0977932a999903b608f285a16c75332451b183f0bab2d0df53b24429740787ad315a1489976665b15013584df90f013f8f6a56b36c88b80e68e800669279dfa3d15fe3d17caedae2f0fd01ae5871ae632c465387d9ae0cf14a003e218481e6e295b5a99a36ff3a17ab7764e07350b4edf3799b64caac855ce54564f4ab718888f52456737f2b0de9683036d755efce2f47a56e921a24c8c266de600855099367f2f2361582ae7919e184b6e8163351fb69b8460b40a1ce458727a19cf4b83e5b631f35f8a65c78653cd050e73d7ed608209c1389fcfc73f703842d8d6dc499d1a8bb5570c09410faba4050248b5931e178ca87cc451cb0c9dcb1c3f7c0993ca445ebfe8e5f3eb2258fed21cd6ba069dc0f1886b3255997898f603d9d03fbf09afff8c476dc0c384ef419643a1fb55ed0ff680e39df598c6d8b16f6c1728a14b32da5125b3250b788a22739ce82598746f675145b18e0d4c9833642263395d8214ce027f6b0c6d83fa6e8ace23aeb68197b429bf5c10b680a03945a7b907a2c2a0c409de4703af0c0601686ef17ef004a9b500244654b00548405f2033cbee918fc020eeab49010b8c1f4198a2328e59cdd161aeff64d7afd102639c81c41207eb78a3bd78769e8577aeb4f41773b25ab52f569b2d1933a627003a59235a0362c749b23f617ddc5914639e06c0b431c2819c01f6c2fe918e1a60a1574f98055576c25843a31284949dccfb46c7ca3e58dd46c9080c2f63b3b4574f53f2a715e53d4fb86023d79dc8c082c261a771b247faa2831e2600d33c84e0804270e77427194eb996c7f3cc7e7781691c28835b9bcdadf1dbd44aed61a99bf207938d8b173bd9208172ab61fb07dc0c51b93ad4338564bac7dd10aff25603261ed74ae5e53c68c901f5e44818a41a43a2325276b1e90a2ea2c9d8a2cc4ce98bcf00f888bd4092c5e2c0b70abf44eb18a79f1830a869563f3bebc94ffc2344480351c8457554c9141e5f1e4327939e090900c74813b1ad03215d8eb25939dfa67a899e17cd7013a425964f22c239d79a2bee564675243c96b0a0902aec4e29bf30f550b083a975a9119cc4c6664e0a41b8b51a51cff941c44a7889c00100204e3d35396cf9f7aca4cf7464c54ab09624bfef657fb9481d078e5aba53826a738780956a8cf6457611532db49b389d3e4270d679579f5bba2ff2d2acbca1506736714af720cd2f7c6a27f0059670daa04feb60f283231a57b9385e89643cc2fe7426220ba1260c23ea96b9ea2c81c04b8a59249abb93099a04b2e07f7873ea95c225ce678af3dd6a7819a4ce4167614ef28b8f676e643895b39a1397b87acfc9a22b8fdf64dde7d1b555da6406b74d8a076a01c64256ec307a1166e448ec65015a4903d78e69c9abb35c5a86d90a9daa6da3387e19e18d25ddc45fdac787e7d6e2b03c2f5196d9be4dccd9aa5340d463c281a909c77399c02211fe94a790509671deb12438ce075125b36b618d1c5f4292553c0fe0cfcaf4318564e9f077ccdd1e31c7520b42e4babc6dedfbaa4e28e1422532934fa2f5c4473281c64c2bc1535882959cb97d7c49d647abeec27fa03f5f2f4a3d92cde843b5187f6f4563e3694a9d00e939e2a9a632d304bf6cb5ce9b7e29bfa0772ae61daa7c321342c5c8fbe1b06ec1359e1efe8e4b5bffb26e7fbde38b84eb90c5e5ccf282f783d69b95ccdf4ccbe63ef41f782b3936a5f0667765cb6a82c38d05da47e0792f577838eef0e403a1fb276a65faa4151220eb1f548f32abfdb1187a8fd2c8b9ebeecfc8f6ba831bb44e27e60f5429dd166daf091a53627e2affbbc10949979ccd539b3e2ea1da1c1df366c69443c4b160dc078d51dae87a38ae4404808c0be1ef3ad1586e8acfed39e86193fc56164842e5ee70c5ab7b6dd06d0b99f1203f37b8102dc454d5cfd1679af0d6ce16f41a76c0017157bf4504ada77f3e3596f325742cf84beceeebfcee8777bd3410f03590ff29bfb464587de0ec780341a29deb2ac761c15858ffe11c85e5ef32c88edbaa8bbe094a3e0bcc3618236cbd482facb7997d5fb3c4e25c42ea4332dcbf2c01c480c5ac1635ba59df9ab7d091332542198099b8d9156712a60f127414b134f5587d5ab3ef895351894ef313266fab9afead951200e4122e3822c264cd4e6d1dbd4e90c048982d40ccb364a6234c01ddb605c6b9fc7fee213f5e14212ac4f0bcc69e4d755b45cdcd8f212880457e57381978eee238a54573796def13d2f4daf87ee10c3339a9c445e1ef6941af7164660bedac556eb77cc12ea8266f74138e81309b8028028d230b4388394edcf0ff0a0273e06b6d8f4deeb2c59a5b933167ffdfbdf88f9a5048a2b0a47fd5ef47de18859290bb4073ca473cbbe0b19d52834d5f1043b212cce9d47681fb310014032d50009ac1156d562113d869a0b9e89b51696802077225d330ccc03441ee33f2c832d3a7247c57d948428fbd7f95330133f611704bbc943fab7347e007c086ebf8fc3bcee70e88e06d0e3c0d1037942aa0b69a4cbe845e663ce6474a1d468f789eebab88cd9f7a4c1bf724f3bfe37481cb3433769b79f913414c4f10f2f8782ed0fa60d8624449b752004653ed8381cf91a3d946838d4258e074c6ec80f60b9a4320365a44f11767bd4c0c38c0f877030fa3185153f8ca25f44d90804f59c2938757ef3095db54bcb8b1cfc2c497d6d67cf15f7b401d06138b0c715c9fae3f777932457c4a71aa58d33a1a4f6f609ecd879a9b705fc1535aaff2ac6118de31e4c6f76e43bfa4cacc52f511eeac8be72fdf630e3b95dfcd778e7aafc4b532e735d66407835fb00472031e64e703bcc3e1c8094e54a62999059cc886a38a863933baee8ef4f5955f0af65d1fe42aab058f41e10799f9f37bd0cbaf3d0a888e6e8298bb23e8a301527647e9366ab8473d4df3e969b013c7aeb190a3202845ce2c4c8b908fa019eff0a9802425c1d49ca128971b43bcf88a95ef3ab0845796cd198aabdb1530ec7f4b299757cbb49349309be1d7e45e2f217cb917d5871c4dfc2206e4d0ce155eecbf867e6ce275d9a940a39e814f02152f4ced30b3df312f154f681f080e8d0add3db2433ab8431ca1e72d26cc49c4df72904e872678de2f13850428bcad8054815c5bbc9ae94fb5aa8966b05279ca4687476f0a06e0a27ecbea418ae11a28ffc16dcc535954e72d782ca246d3a5e301c55a261c8cf00b1297bc55ed8b193604881e69e8e12b18cbd384a65c1f8a3808e38109eb9fa0b08a7c1ba397fddb2e178b99a082cc8fcaa7ea477b859160016090b806abbd8d2f3749f8df5d6f69a58bf995317e6eeb31157e0306b326323817afbedeb6f472489e0889ec9d8ddaf0fd59a2a73be9d8bfe898e8fa6903184cc34a7802fa0d56a42cba5168dda1bab3d3f45b9cb157790182407a7952896a3dc42bea409f80e06723d38b08275cec54f550a217c4116acd51ac9b0c5b23eb9029f95589019460a0463e46c651273f6abf6e7e1c25bf08e2ebb1581050161be1af35577883200ba0a880d66cd264a6ac5f9c6727d1a309ce1c9acb4de48abf2b5f34f3aaf0a5b7b1b435a1d134d45dd9de9199f8c03c5415e4cb5c1f8e1124a03850aa52e86332a3ed1a744d05b569a8e2316c7caecd8e378dfcc2b335b012c82ab5b58473be7b6885f764bbdaf1858a1e747daa33e74b8595a4cd9e2ae9e05d42ee6bbdd006997f91ad35da59670935cdce26839e607dc10148831b9d23580ca4738066e85405536dc8ca485fdb1d82f80c5438fd9f8fd3cfdeea8cbe20cbe9750659e786472c7b6ff9734d6721cc777c4c35f39b17b73707b011a87ee1856e4ca99d0462640bdad6f7df7c181a723d1b9a0c5770b332b39cd9c9d6475433c777e96fb12581befea092bcdc134c469e3f79b2b46690cda110c351d47a54304cea560eb58146434f7f9b6f972b33855eff6d41838a8c40ca2c1900c6e18954576419f40b64d322d0cb6eca158c7fb2605b3f2bf858d8f2ef1b3f561a09da75cd5a66e37738673a70d24c64fd841fdb6a2e5ecec1938b9f3561de7b660b245b0c3c1f7bace71f54beb463f1acaf31e5a69a0b6dbf14073bbd932f7a786e8cf30c4aeac6e03872e84e08e87d1bc74589d9d92dd36d0757963f0c41691f066b17a37339c0266f33f5f835a1576240b38cb62a1da85f67d1935b1714184899360d6cc09e4f44af3ac1216c19e09860ef2488c84442687174b08e9298ccad0fbb66e9969f1e421426f3e9729a8f087a4c66a62f9799823022ac536f3c4dbc861c18688b98ac6986e63b7d812ee4b7c7fce141403c1edc90b369228ddcbd472da6cc132ffef7bff3f72650f0df787b1e2fa080949830134750706b4f4e3eb35719a9844bd331c2fbd53998f00f33bf54e558271d7ffca78092dd16f18bb54aacea2790eb781d6631a3b2342a379119056139acd68c929036fce70c3c7f2e80f74db3c4e1038ce5773374e62f0170975c6db31d935f648ae2ad494eff245833d5681325108fe94dc6404750464a1a36eb6a90f8f042b66be27d5c091b4962c60cec61127ea57cc5c09fc7e6e5b9f259a5a127a1d34a005f6e2adba585fe698f5833de53344d30fcad79fdc7951d5cd75c038f0ff7b7fb0458be60cd46cd9c54c0acf32694829dbfe823e31b28510b4e7f37c14adbb3acc3e7a6a02934136e4cb718bc5e738bea40bdfd6fc09a435f643f63e4c660da4c19825f37c06de36569024ad5b265a1555eec02e796792fdb329a158c1a4d24d7d8252897cc6c1498a88e86a813dd3dd197c59b3da52da92f46df1b469a7aaeb1f9595ae25070c88cb7fff71a0af7ce2098dca13aaceff18e70a41a70aa93a5c16075511daa02fc3302ca879d4e5d40d499490745175f300d82eb03b138101d22c9220e5fadafb5dc92da5f6fc99727e0db4132525627ba82dec7c1865ad1d51e87ee09db7ba93971fdac10ab1bd36e3023765cd4eeb8095152c154c3727f234412b2f7de5bee2d934c52060805a4049b04eebfa35d2bef1f3b6251bb457b5511acfd7ed5a3b05ae1d82a16ffee7f652bf8a8ec5f58ddd8a07b34337b63f76eacbebff1eaa54793fddb8f991dd6ec37ac59b5ba396a0b4d03aa628040b7ec3b866d706e78bc5071f82e1f2a4291fd398b64a30c6ad05df0619d24905657545c7412c8ffe352e8dc63408f4c8106fdedcaa3a108e0b121cb520c07e0c18635b33418a168dc00ba185f50a10b685dde1fcefc1248aae0d267d7906514b68932fcb5bba3c19b6e71592303510517f09d9c361065c820d9df0511d8ad79b09bd95fdd1027af5ebba1cddaa541bd7de9e140bd7d1c2aafc27166f53133af5a07a9c2f67d433994b7d76eb8236fb141d48d3db361960625c671a8ec51d9af3e437d55ddd0b30ab561af6dd8abb0d820cabbaaf7bebb618fdc3d2757abd5d3c4bcc22f54be66f5daab6018a0b02f6eac5efb95ca6fdf23e364fba81b7a46bdeaaadc989a31adba3db2bd3733a7b0cc41aae03dea86d149f63e667a17fbee7258a39f5dda20cb906d1932584aa28715ca19295e982ef9d33ff5c7e8a5829d1c5f39be8a600a69f63721ba74c416f71931da85d53f5bdc8174fc74e1340bd38581d8e2ef3ef9bf26ef156c6e7c8128c37f851bd85016c9616cf2974399dfccecdcfb8d67edb9f79748ddea6cbabcc95778233326952e105f6cf6f7ae0d98190dcea395391f9b184a13d39783dcff7577afb814dd1d811bec9c53877c9d2b5d8e8a50ca2f727c1551948d3c61d86330dd924f8c38499f547deedae9c2106c7c32c5528e4f929c7091ebae669d24d987e06592640dc830fa2aa2c86b68e8c69f0c69df37b45c8ede8df98d5f68387e8d7c4dc334356339c35c3a0b7a82f40821117a914e4338290da1d4031142d289a021413d487a7e4859811404528dee11d2f3229788587a91484190aa93122727234e3f828082524f489e86ecd4e81f203f3b40ecb47c4890a527229e5e475e3e483922454948c9c709c8e945e4d5f2214f459e78082b1096842c311d61aad14788629050900f1211482d0408207c202242d4428286087a914c4c464a8c7a701272f2e125c40b0825a5214a3f7e8efc5801a444e4e7079097d2103b3f9224412a8264021bb33b218588146964c488080811901192a513b8a28cca2bc9cbe788ce53104f7389d0ce8f57d02b49129fa0a01f5ea40449f9f1f3c4439091200f62f23162a407254a3e414a825ac8d3131020355a8814292d240911119da520967c50b22385fc2cc99e223d2fd2d2244cd4c24419c7a12b20cad0173001610222652e31b25344c86988530f403b3e4a4246b60a11b2750810413f82e8f911e227c9cf4f7c91ad983b4c5911e40908271f828208f920410a229a4b88e809424808120a6a38109c89a99b314d8734754add9d0aa1f3b1aab790224b3e0c31eab111dca247a101f3ac1833cbd9cd39a7cf3967aacf3969d01cc228f7af7c6efaa0cc13830dd2a7b28715bdbed448e94be73ce9929ea1fcc5273f98e49e11d64c6dbe4c7f4683300dca87c00f4b4399a9a4f12504519681478ec010ac471fec1608c6137ab0a0527ca9599665599685b5eb96cdb2ccfb2d1236fc72860f5002fb31fdd58a0fb083ad61cd1a9e9f659fb174f4c85a162b76563689c0c2fa867896f293211f79b26a141fcb3723a083fdb29ca183ba4b0779748fefb166dd4a6757b26e25ecc21ed9ca4719d4bd4590d31863ac09c85e93529c3de0e68c4079a5c19a61d4673361e38b092987dd8bdcc92b0d3689cd71a93823b1ec962d2595ef4670313a90ff48c1c28912d1d0e4993b4e4d4c90beaa169fba3348ec51b7023c3ba6abc696f958583f9b29807d0cdd9a8fcda41e820102eeb9c8c92e46ee431bb9afd106e746747db3857bee63fc9a009f64ce658acc7dacdc53ccb2acc82747a71c5f2d10ca9cf42af6063dbbe1a45d3663caa6f53dd78e7bee6355adbc5ae0934398cc7d1899c0702dee6db0c0c56fba3cb6c8e7ba9ae170c5c6c992e5f765eefb6b90fb5e6eaf65ee73702cddcafecb9ee33eb2385c2373b0292cf0910190e36b054ef931ecf2b3265061bd41d97511182891d4042bdc78e62bc1b8684e0e8d18f663e9d9b9ac4eb7bcbba395239623568c5cfd29529d487b727c776a9727cd963e9a2ead496b3a3a3a3ad29c361d4d8a92f694fba7d3d70fb5285d7592e557a55c2b8e0d569b94e449cd021fad69d2540dac4ca25ad36ce9d7a234694d34476b9a2e4fea967efaffdfe749aeb9923b3913135f52ca9c6407f8d8a31cda8f099a9442b2a16b4d3bddf2249a23917c742bc9ce882fcd03084936ed0c2935163f4793c9870bc597de36ef464ba63a5ce732fb08d333a84e83376499fa686a4354c1c51236b43954a75bfabb4a7372680e2d42851aecd7284d4775bae94fc7c621ddc9fd99d694dbf3a84475547a95b6414973680ecda1393487521ad21c1df3334cc3cc459aba8c4d511b8f8b22a2e4fe9f25f9d393c35a973212e693ce0e9b47de2d248fa666ef77c1840d2553ee67aa61a59d6b9491f3c3cf71cecea28cd25f562f0af6c3834c29a5f49928a59446af4c57e2172c44fca2fb1af9defd0c71c22e4beea3877dc5eecdcc1c963b902ad4df6eccd46844263ab06f17cae444e711384d53a95cb8b82e39747179b1a57ea4b88b32aa0b256c188f3a974bad4fefd4e122cb3bdf366fab5dc36064a737e375fd6edb384a29a515534a9fd2a79452ef467d6fd6ad4e5a67adb5d6776fa662fffe94aeb4b4a718a75dcefbed863879f32ecd7ccfc3eec5b47765ee34ec2b867d64514d6638f0648f4eeb9f9084a5815429a62fc3af4f5f0eb58fd641d69099f270ed7aecebc70859565ade57cfbba8cf3aeadd4d29f539dd5137de4c8d0828879f6b7db07e7d16ba45a9c895c827d76755ef468fbc7df4747838d9514f6f5833cd86638be989a33f85e38c690fb70ef4867288c32ee4a07dfdbe2ee4a0e1d0b38c4956b84071b283b5f6b543f70e4f841d76a0c1503f27e56a07537c7ccede952c630d972acc195fecab568ffaec637bb7ca5bb5390dcd34f6a596b5b7b746191a0e6fdca73df24d05a5cab495bd356b33beea274b1065961c9fd8a0088a0e56dd4aabb46581315ce2cbf6766557a9d56a53b92abf5a75aa7ba562fda537837acc9bb10dce2eca981fa78743f51aeaeba20cfbaaebad43fbb6bf7a6b5fbbf633bbea5ec517958fab8f2855a6d915b2acb242a9320d5b89838f2720f0f10114b5d5cb4c4493bf8dff0e77f225aaf7b771ae842e5c69acbcba605e59851e5756f5f13395cf5ed35450170623bb7ad46bdecc0aaf8075d2c33167548fddd0e13936488bddc3e139316d7168c392573aecaffab59740f8627f0aac565ebb445670ec97ed63b05856b42e87d61fb79b1d0de688118f5834b2bbace49a351cc625faa567ed47054bb90039be542094b9134ec8516dbac5dfdfc6051cc2169d45b22d549f737440b061740af8c50dd99886996b6283514a174ebe0f127905ec41eeaf4740c9fd5ddfca8494f2092e1679b9004a8339d92b57d4a01b35e8ff8a32dc05ca27bdf06a684f5205ff588becd1276945327b0bd90d7b00e50cca1665bcab2d758b7f773525ed49d6d09a68126a56e4a46e2d09755399f6f4ceb061c97341176e76de8d32dd9532d18bda953ee4ce8d323255589a98357fefbbf7a4a2ecaf3d75abb1d0a4742bebce322d496b22ba5c53b9d635468e335a778951867f0d2860f68f69aff3a781c596eea61c7f1d71b47952bb58ac5b032b62c1ba49b6c769906e5f5fca6d93db4bed9dbc10039207bd42f7711f1c1e54c7bb4571b64e72afbdacbee334f2ab94d2779ca703d165250e29b9d9e972a06ea14f9b7e0abb8b2616fbe972c9d8927aaae9a87652383cf07720d2c7892f3ffdd5068b43a62d2850100eeb0c376ede30d860eaeff6f2d60daf20bf7ec59a96531a6635987a6e769dec6ea2e48d3707874783f45d3c61b9c73e6c27d24be148555d83dccf6f19e4941ca9ca36b893299ec19808ebef95d9739cd46aad13271dc376f27dfd3e5935147030cc9bf9e7a4fcdc67b6d0972f7dbcc8fc361c82d6a77e75012e1ff869b57eeda6b011c6bb37f3ff82acb13d7d09c417ede94f20b6f053d687d595c287f665155beaaf1edf19c1fadbf55b3f851b630bebc6d812a6727ded7e76edb9dfb454560390420026c65fb16b9aa6611a64761cd6af5fb3ddaf2dd4432bf76e01b8cda441fa29dce6d17a76767c5af85daca7ef435ee4471ee4446e2494e9e3fa7ee57665761fff71200ddb74f269f05c5f8654aed8844fbdfd987ea9b3d338d3e539b385fefdb072deb5d02d89c3ed534f9fd36aeedfc88c7fc30ed8b1a1e7c4f4bdf8ba4efc6970a3eed32df44dd881cd9ee54ff8f9fd3c27b878fabd7c07ecd83032a9917f2373ea6bdc478354274a9ae9f3c8b1d120c5b78d6e1f750b2d925b7cd84e78e40e7dcfc1fee21c146e28330a1b7e180f807ff1383c288ca72f755025782594f03196f0d77f1ca841ea1ece74bd305be857adc2c0eed3207d960f2316f143f7b1a13e4eb75c481ddfd7c73c1c1f4eb75c441cdfd70fb9577dcc44e1c67c02cb8b0b801b1b7471bfeb44585fc20d2d76c350f6849dca0d3ffaab3b4396c3e8c4de1b9953384783f45f98d4c3a1ed5898d26a352a2905bbe5305a00538632f6dcbcdeed982e131eeb3813ae8c2df34bb8f35b5ce9237f8cb88852d95779cfbef38e9b0631efb32bdfbb34d9cb15b2972fb14bdfd1ad897aece514d1f5fde08990b12c32f6b2d6ecb9ec66ecbf4fe55f470c65ef27e78e4956ed5658986c717b49698c15151515154c83cc2b38cc5ed6b8bb13a519cab6f4c2bfb10817e1a222ae089c45475c37bdcb92a7412c633874c9a10d2bbfa0c1b37c195259e2b7d3d3e1658fe2c1fe029987e96043107b97e99247dd82fd7f982c9a450d62efa2897579f9d84bc15e3a75eb493679d8c32fc862d88733349fd982613422385f690809e8953b2f478fec7d8c78469695008a11464ddd0a6551514ec65e1a614610cd8c66ec259386fdcc700c51529f1db129555e42892f3add9aa92e959212c7d02016ca793bd5c75751911ccaa28cbd2c5a328a7284843d267b32f6d80e0cfb568ffdeac61cf163b7c2ec3df3ecbdc6bbdddda7b7634c230646592e2e2eaf26ce844e31416c860ba65b28eda73136e4c3c86b03a65b72c6282557af0d989806274cc601237f0763a35b11d360612e9e23943927a5945218982572b2e3d0c244893f279dd44e171a0f3e20cae8f4cb98d43f7071aab2afdcec54ef75debfbc58e3d9bd77c39a3b2ed4b81b9db7ac86f97dc316b8c79ec32f6e6c8f75efddd3ee5560f756f5f4daef1b5e2087d9db7c79aaaebfbdf4e5ddee8b1b9ac49ee338eee9ad365a4b1cd6a0d23e0b7ba06e9d2d19a621006020b2365faee9c73efbf06b4087361fd7e2072b33f6d87479f879fd9529674148ae714d987af9dc954e7178333da670cca85b133fbe7fc4355e1d7be918f61aec63ae2163dfbd5fcefbd8ad2e3b0e6b76adbb5b23430db96b62de3cebee8b1bdd536f85ee35c735f1fdbdc76e75efb9e89c2633f56e74ee3ed2df30efe90dfbb5f7a7de8d0d62fe953ed718f712d7dccced6af766e626cabe5ed9800e317c3373e39b99e3abf20bc737fae3f797c3d8395e57272eeab0d89c38ece4d7d49a55f88b777b7facfe86ba44fabd1bded04cc4c7cbf4fb4fec59e816eca38cdb68102bc093a53806d36810c37e060dec8c6e551da9b71fd3d493b1b9696f4cd9063f9667611f4a5933265f62b55a5bb3ce6fc53a0ccc21983d99e5c05957947911fb27f600f6401208440fc42813edcba721ffe583f26777114a1e2426e53c79423e517a990425a080e20ae952e2f8274dbc73be15052081c3f6e81973133b9f62186e60a77f7b37e6e3a8f9af733225c6f9f1b1f98ec5f971864ec7150b2eb25831ce239e399390f29c73c6df3638aba5a065b274ce9fae15ef5bc07058557ebaec67bf7255eeeac6e9fad962e392b30cbb2c2b522c46f3611e49b2e7a1fad4671802a85f611ef651ffd3de6f25acd9fbd75caf8d4bbf7f57eaaa3215ab58c53714078c2953a6e42ca489b9c6e633ac815b33bdcf7576440c0b368e18b1213993d4d4be1c968916409a0d1246ed14cc15541b2ce4f8fe7b81cf97548d705b12b65f6e5dd536cc31df640e567e9ca8fa32da0756be8c38a2b0d1065510e5b80412449ecf79516881ed971f27758c4e94c43ec090e0e2ca0a6c0027acbf8c2f33ce183d46234ca939e178c2b637230388f51c5f4b9ab28c4660cd6af47df863c4a1cd5b1ca8e6c4ea065744200852182104274648d1032a8e40128210001df18323a460473e4080ac4911b67964060d982533d09630b1c428775816479f69c8aff23f1726b9e6e8492656cc00851451a4d4008a2110c89c28a50850601103156491948405823ef0044812529278b2414210a61c1129694282cc09577282ac891b42414e80c44f134842e831e4a88aa51f113411028a7f204be2c9a28a21243e44c043133d7e6eb8c2082aa2140d210826303049c10a94d020c8117816e083044e3c190194a723644cfc200b242190a0040e9ae4b0840a9017200d21c40b8ad2096c6080278edc400454032444e10411512081c1153b086a01982b12318a896422d1aa984284233f20c11241b8618612274545a2a460474706cb5e55cb66f0812962c0832336a04226b43d9099122f257ce044153c88e0064320e5e008dd4af75a32943fc797123350c2a843410db2e4010c7e08620a2490646412394ccc600a164198082123ffab0db64b2709f6dc6bdc77da7337e64e862a6bf633c348ac97e36b0950fee8e9883cc81477f80a2b9f939d042e4650c6691afb0a9ccc4c94f16e35aeb999f9c5c4ee1ce06abae666e60e935fa8b48e7465390ad514491080200063140000200c0e8543439138281a074693f403148009909e40624c954623310ac2180a81188aa210040000010600001020c8186db016a248c313788d86471435803c6f1a08211c4cc225803949730c0320c7a6101fd81d8e670c5070b9650d77b2b4f33c4efb41d5e10ecc484f4812e3300946a9b94a7b5ceb48436088b20e4c789e630e4c614029887e4490744a9e7fdfdd0ccb90032b55fa24835888b6f8a5f8cb300a9532c309cb005eee2a0f0c07345395dc4c8ef07034c4846d6ee9ca3226fa0ee701295fe9b5cc7645e30d0a6dc9e59b2a0bbe054d800d5129aa2c86d05cc1365c945ba0e423ca429c9378b000c248217d663cb9a49af4bb0181822e17178a8f59893fd02bef4327259ea263d76de4e2b09bc30c344fdfa0c54be773ec0e239bffde5ba0cff9d2910bfc2682364c54517d18025e928b4600280e9e09e00404cf41f144112de0ffe225c3904a6f6549f2b2c9f6f0cc6c24a3bd24fd3430be4a88f12d6cdec727209d9dfcd2c53cce5797028d79a3d8e511669be93662c9fd11db1f06d6f6daf031cd2820df1045b6b217391dba6dc5c205e32e2bfb3b3fd96db0bca74f1ab5954796907db2d569a9bb18a6c93b3be44c53bcbfa160eef2234777f991df5d7ee44acbcf7e4f86b694c099fa1e65c476a844315b71490bc72aa815496767295b5831b3d8046de660cae2bc3e06d68003b118e948bffc19bd6e694408002b3b025683d13b630ba717864a3a6a87359b7eef691e67d6e896796d89e8b8d852724e555d02ef48e8c958496d7008af28a1b9e7d1ef64cb96a9e5d30a8e6930dcbcf992ab09f515140c16b49da69a81bbdd5a1636e9cf9ff2b37725db26493c4e588e483526f1619a99b624edb50438e567b76814a14fec4e58fe8c8f68f1ea40f69a5be7f916c4900d121bdcb1294535ac60995b4742c0d64e958a2dc21fcdcd8c915d7b4b468485fc9d0a60893be9c2bf2626dd731a41c5265af687e1218ebab51b6ea36117efd806149e01c612e8ad3837736f358caa0093c54cc4af20721709bcf4372ea97fd2a04b945071300a3feaa2ba7a74719c3df8bdb2ae61215d621ae3485863fe4b2e267747355cfd50e8e53ad32abf3db55a04edf15d8873ea8ba75ff17db103ca02433a62e6122bfb7a281eaa86dd80ab336c864d14d95ed8ae2b0ea1acdea44dba28beeab53827455cdea2b4cf12197e339f6fa16d5808079b198150d69db10d4c0647253ce6596590f6d8cfe8b264c348df2d83a240b2db0580188a3742095dc095fd7066f9f4b6a7013ea4227694e9087c15df761c0a286b19ef53674ab2b5d13f706a50834470e8d51d1dd9c3325ba4b6ce52bf16aab8ad8b50ddfb824e884632463ca9ad4aa1427911d15b6b4b1f5dc9d2e7692ba8a507ff5ee09a80dae6c16034bb8498148750415259ea61d69b920ce21bb425d8332024005a4a12c73f7beead50aecd3627b692a50f3d3758c187322bce2d2630d10041fb67755ae4ed9fa799ecd0358c70db75cdbbd9077aae68744d48a4114c34ec9fc17ffefd89baeda5f460162a4f991acf1796e427115f604bd7023dfbe3e5ed3b48ab41ca4e9130dc9731e6e22e3f9be4de055d562b191c1c3342869832c248d3b811ff04c6c95d3f204a2f08bab874caeaa504bb5e423ebc24a249a13887937f033dd5c5dc5c4e8ee5f72808eb862fdce2944216910d96e438318713b6425064a8b45f0ef630b5548464426922a6c9dd4cb8a02e153f0827284a30f96c7b170e671b0806e3855d207dd32c4ed4dd9a125c6f31eb32e872a3282d9a95d69e3aa35955041f6c61014258506cf08ac2f72b9ecff82fc260951271c7a14db48f8ed53279d9e8932a0298cb88f792c6a0e73e6119c9e1268caa2574d89925d7dce25981700f543ed7781f0e3e02061d644ebc0ca1b12fac94c2c1f6690fd8324141498c4281835a99095809a3eac8bb9b82adee80debaa86e1bb90608fbd8337231e74ba0755b1dd09c49950d3572001e4d83986cd79b5e1f53be552c009729a797bdde01d2ab6a6eeb633e927925e791a1884a4a728395b2b47627044cbe4a0cb72b516049a573ade66145a90afb4152e099686dad463528dc0f4e8b7ef7e9bd23473d2c5251052c7c31357fe4d74d7fe3c9d1987d23bd8b85f6310be9de78d082f76ea3c3a1dc2a45749a76e422081c2b392c86745466dd416ab981b90a04a12638d2f1f0794a9ef6babbefa9d1bbefa81d78df51cb3fdff9a12e2a43ffb6792bf14d3b0469172e1e45bf91b0c6df27060d9f2ff937a2262619ce2667993e40243ef09a1fc04eee735149584bd9ed88618f5925ae403da6d8452130ba7a24d09dd4d35f205c8f7c061ae2435a26d4e7d4590f9fc4816c1eb67d11690228620ce18c33a02a4846f5ce38f535acf56a8f73699a50e0d19423ef1c8e95fbf6dd4cd009f8f2ae7a61fcc003dc2762a170ce1079c58310009472fd94ded890704054b6e8675544d8ab408da0f2a2b9199c3da8982d84828b6cf3a727dc6916a614ce74f4017bdfd3b62d6cb28c85a33fa1bef847505d6cba840a237da8180b846a02bb7c22e213e8ee0a0a981f298929ec4b9b6d50f40c478e7c42661f259da3a08fa076feda0c86be1db4268573e3e26b30ee561bdfce983344db32c6a4082d85ef270942231b936640b2e7b12651b19f5e357f4aa745b20c088385a7f4a71da9be25a08dc5bacf8879656fffd32d718304a70a6b077cd27e6fc884aa3458a3c41fa0f6b253bbb353bc668748139bdd5206b315c1635c99a62bb08d2f9cdd351b5304e57109c976caa8006c1802eb2fad473da87dbef2499a7665711fb61d86462290be9b8155a3db9792325a7785052aeb58efa9626f21a10ff082e93087f831d4e59e94ff303d6404a5c44a10c65453719c4b728033c437fcf0e7236e62446d17ec42092e66acb3900200bef6ba3972e6f91640cc27af5bba2ca050ac59e68f75ddfb30b43b6d5894bbe08f6d3477332e39f8bd4b4fe0b6a6a5a6acf2f8deb7fdcc6234c715ec9468481cc83dc55a7c0319648cdf1ec00de43ceb9d90f72d8fcd4a17dac3575e83465387a225c371e1a04942e66b126a93c38c94234855cb4d308e2c78484c89897add412b8e23150035b16f0a79f6a5f1932a3c8875aa148a70c507faf8e0079c959a269185641e0f5a6850003a6d07779939616b8abbd4560844c6a92580b1222cd263a3ced0b16956fde46ae36b968e5d821c0bb83a44d6f61157ab1f32c746bad10a682f04d0732cb30061f2c543d009b340a88b4e7bb5d1304b5171d2c5d8eb3a7ccfe8d22844560fb727825eab5953d0027f4c4a3098dd41482244f0ce9ee2659605882bb29e2e54c77a4f939d7f7902ac82a1cbe2dc03fad038dbd267aa58b72c42751dc2728a49962914890b0e9a32c3121b30f931291b1a4127390146c5a4082db0e6fc47a8dc3fdbef5951201fa2554caba6b9f42c6aa20afff7483706b924cdc9f1c64b4221570cd44511fd7bbbd563f52df80612d2d8cfe5d8b13108dc8bafa7a0aed25ac584f0adf9911dd0f92970865cdb83e35ab860913abf967c06f18312be39213007681b8ff1a5b02aee67c85419b720cd618ba63f1bbe93e282289bbd070831ec9d781bbe59bc811f860be286f6079a0810f53b9c0c916389b6d08c695792a9b8c5d39dc40f9af0edbc9ce44ff2921d24b8a50f619610d4754d14bea70cf306142a25d91e8898300e8c64e1e051daa65bdd5031025238eb13faf978988353ae62b66c5132124717b50d9f987ff540861a9ad1e9873ff4282c955b01be9feb8b4d5aadb7d35c8947de0069f70322f443fb77248c9809163b654906f5ef323a6a1abd0800025c5a653abd27146e0d08e381246a327c778a7d6a0fe677cda308065cd41cf69a4707200e3a2b4c1610d1a8e2b44cccc3014f58f0402f7a35c69d57d714d369de80eacc96a47b031bd27be4ee3cf986741d011dd2cf06058a7839e4828041038c538bc3fd8acae8a3d7fb0c447cb6b58e9cae9b31f0e4f49486912abbe0a0ad06b7039b2fad938e7b0ddf1e60c5a4e33bb599e59cfa19e9c2532743775d522e60aa88f8e3540a68f9d57ebbd49622cd2acf44d0c6bbe4afd12f7c7a52c1261335f1db93c592a6688827b3ef8e24a7befa3a310a0b5b9d565c96d97a9d138157d8eff79e88a658515c1095d3e78430e8866735bbc2c2b31426f6b2be391b2bef0e54ac7a4da7dfe98c4b7aa612452f204ca2be5ca75e6bc2a9eecd01a16349c110d8ab91f938f8502b39f5e728f9cc97eb54321f6cdc18f1cf51927f3357f7728c1484b85d09599b8d45b623dcae64d021032b3ee42b8312b1eb52f5635501ef83ef381e203d9d91b37c5e4d2d2c11bfb846f6450ba622965113f334618d7cea8baf466dfbc4978abedca3a16582d019ebe5e6ad97d13bb9eb36da5bc48664465036d16cc4dabe325f6cf99549d89c35ee6584efb08ed14d0596e5e7355bd9f49a0df3224ebeeb52695dcbd3ddec9ca58d99577e264124a6011a3cdd13c1d4b272cccaf9c4b45919912bf1bad2569863cb6d915c6de2cc40d0a9f2644de357ec31de7336dc8089bbe99630add5899faceb2d64bb656adce9736175eea58b2509d62bcee6187103cbae43440c0785d022f726bc538e2129025039420ac61635ccabeb3630d68fb85b8363307cfca487fba4c954649d2aa587c12c4f3ee5f303322807878f97ed141943c701f87af556520175d026e471a3c9df30104013487a6fa9b0a648b13299ff12a1b4c9780a91f7382af05530e93f937be6f51574c6f6c27d99e0ffcd1936f05ebf388464da49915ca8fbc500234cf2aa08b530848ecb0d954f8476d898c8d60ec941ab1b5a60732fea72005350407d4805adcbc2fb19fd673e7d2d504b30da43501047538a14c7f7289d4aebb0aec42e17245433aa41c43eaec88f577de4861f09fc4e39fbb011a2ba759c9e13bba2a3fafe1f7d457dfaf3ee1b4085b1b670a24003a21f6500477826a69c377a25cd13588e8075a2cccd0cef7b5f9748ea9b00a128f1beef2d47cd052bcdb425c7e3cd9080df017ac5dc2378c8f0a524ad320257d57d5ca81e05276f33ad3ad0a0c98c2212a3591805b03f67feecd8430682bd1326f4a6e131088b0fe01a219724e276ce609be8b38fee18aa69476ff366d8223c935e7d22d57df40738c119a37722d5a673d00973514c2dbb515b5b4dda88bf19ee610bd65f0d3452ff4a61bcacb485da60dae12f12b9f9112b67701ee2fa5d795f602fc4425cfee9f8eebb176d78eda0ddf931927d03d60af6fe214b76182bc8c392965a9b04066ccfc8cb551f812b7afd874045588ed61dae8027badfe8407b473c0644c87bcb4b4a2b28611f057c94b5b874fb3df31e93b14e0bc6ebea0da854208f7656bc484cb0caf50457c404887da67ecf986191a8b83edc5fe40bfd51d7e72778cb165a23fc1369badf3134d6ea5b047291e3829a97666633a867d879c6a6dc1a5e98a7775ee479b8f04755eaa18fa921224563d3f50203be0310c180974f6483edf47d49e5f777b48d68187b790c4d66b618406984ce6ea0f784c8d0f687bdaf16c51080970f05f1f9470952ccb4c00e175200deecf33f4a4f6cc37896158be0d759ebfe917bf7d973f05bcf005e20961afadd84b6c05633c0a32104d0ce3c52c7163dd9618a4fd937d4e1dae1161f2c079296ea9f7542c010dc423de84cd176acbc01403eb7385c4e974e773d0a011dcf9c19a76600abea0feec60aeae7d69396860801b8fa690f0dc72e536fa6825b54755685dc03259f83e92e255c7cfddaf7da9faafbd48304f7c860f5c79590196a255c5168786884c012614a8ae8634b23b3955153e4b2ce48c1426c8f19c43c99a3f451434a5f80c9e6822c51147f8bd9666d9e360ef8737ebe3d386bf4fa8371c07f9eaf720a951d07a5acb60030dfe341540a6309e79668bcfd1ddfb8b0fdd472dd1c91dfe617ce100e99e48ed8aa1d7fe65bf8d060d307672af082453a953b1c3b64dc5f3b90f73ea4f7d279136b971e7d0af1db69b2efd28dbad0a8ca2d49c214c011449c2a1e89016f3eac2fceaef671424c10a239f8a8ca6690209b78042dda166a61745d1fd6dc008a600800d74023250dd22ba1cd4a0592d467a0b592600ed98d2fd8bd84c3f72e2d2cef75016d2c0f29827520204fbe4212b2eed432ab3f5b26586b9fc5841d83e58409bc43844eb4eb3ca4ab516d905ebcd9bc467ac96a759912f3b39735042baf60d6b4af70b767ba156b8d20040b74b6a5fde5b9304ef6f6b09776ab4b31065ca350a366d478c608cd2a66deff7a8e9f54ddf3d1efee72fb26b39f369766f21294cbcb34d2fc6fa90aab0fb369e0bfdd1424acea08265505482f3a3e58152e17cdde0acc3632f6b47b81012c6711a8a86dbcef8de29d84b47319da128e077a7446fad55eb6c0b4c1202bc45d5480f786364fb3b6549cf8b7f4c035dd96e99a4a1c05105c9fb384bce07b04d88e0a7a64e4e4900ec8a2cfda1aed6919fe75ed8890cf401313fcd6a21e48487d63a4142b94d91296a52c7716afe893975589a22589d7f7c45e1d6f8b22277b7c6c08b7d2fbea5dc7d4cee1c2464d8170958b3c5601907802f2ac270ccc4901d36589e2aa030617dff0fb850fe54dd8eb6581ae2e00f5a102be51388db7ef07ae80bffc3cf189b675a9bf83c68c9de6b34757767b36a2ae5a9a97bb2318586602015215d092ea0b9d5b4b0e2971dd6c9b880c87ba279b9c4cc8a33bf52d3e0e0de8e63f62abb6698c4c12e041c15f822503e4e186586a0e97f344471e31cbe1c13d9081aca47cc83a59c9898bc7014a581c9fd028ecf74a5778cea0b644b1331423738f3c4b2af0d7ff5d9cd3a2e69753d794554f5be541c04e39a34b4fea80b665cc36c552823fec3849c13221c842406de0cf2a0bc43f472dfd9c5b94aed95461a63da4f4bdfd7a5e5005983f46311c28d00d7df1ad4937382867bbdf086818ace7a323d5557d029c2175a0bfb59d5867190f5dc5e51a5db39239dcbe95d751e9c1ac5f2c4e882b384dc7b96f79b99b85be812d98cdc1f13eb39088683b2ea9b51da7a423e041d5ffae52feb95cabc2b21cbd4a3be060380d6dbf1add2592e97e9d80dd9df74a7dabe3655f4ca467334e82ca6779742018ed459466b6e813f20c915585848d80beb1d6c6057dec1c7807c7bdae113d9bfd2a16ea1e4d1b185db99441d459c4f6e0a05e41f4d81fa899ace98dbd829a850c31f68ec1da28f2b916e3cc57f689e377cb6e66480392073603f0dddc44c9dd80b4a4025f98b66d9612db2c8ac1f5fc870d6895d97bd74964d1eeec08aba88252d29dbdae1024ce63d304cb7cd867e6386414b759c21423165068910180beb442e7fc5b5d3e88da387272a403bad8aec719f76298ed860efdae665fd0d8461a253a0ccb9b6f53b4d4172670da886776d711859d7a8fac1867246a6a8f029d3dda30731e70034738708fca1f59872207e5a8d5233f6ad52f1e19d62eb97a5c8510ebdf03875e25987f31e256dba899a323a44c4730be0d1382315ba304eca342438b324114b03136567ddb9248dd3432943af0f8e44938cc20c6baba2fdfb1cdeb1e518485c69eaff49eb1a30b3041c85d2d7a98b5b02bb4f1809f11f95b0c10b2ce0faefb6c42b14d50ac7cdeb7e005c0d131260ab08c24cf31eb4adead01057e0c04923c8bb0c1be66d6bbaa1841849a0b5ab54d52c6775f74cb2db16c9ee411b6aa2a4728d0a8f210ca5cbb8a9325af32bcd27fcfc9c0688eb1602c2c6bea5f7a3947ca40f7ec0903caa418628a5e5319a76e9a867bb66cbb0f9124b4c7933db048326bb0f8786daba79079a6064ad5ad72f249ff39c64fd56d3351e3cd29a489e71a29a2cb6f5c03f644ffc45575362c3684199f9cb569a1f461101fdecf9453f8e42d028c7ae1709c13fdb3acd69f5c70bb261f7263ac138d5f6c3bea6cd7fa536f7d7fb918cbfa2a7c63ac32f3c13614755ca1a5a99c59617eb707076fbe6bafcfdd5381dba2502286f1f31f0d0f236950b30b2760f12a5ec1f15c2771db96f8ccb70b7a43ca187fa3276776b5b9a9d4978aa7a154af84fdd8878b3a3217bebc0825364202206d9e320051f761da58a05a9dd3aca57be5a64b7d5598111b34aeb0bcb43a9c60b42aaa343f3297e5ba0e39ee07b52bc5a52e5ea4a681b411e55472cf8f92bc8067f4a92564d308065d265d663589aa6ea2eeecaea63e21e985077572e1e04c9085fbb943a11891d1ab15fbf9c834f1fe6ef5da6634ae59d431393d7e2991e67f064597217245c981e03d717646376aaaaeeda4c66ffb5c0817edbed511ca070ef8a635cabc43d718f716af6cc0d3d5c93e6633d0a890a2297e1b3e2012eaa83eafd37706b63f9b28fda5aa931b9cfeb587461751e70295596bf4ed5b1a85b334b3a6ac8a670f2d89df6d44cf46bea7c6ce90ecdc7cb113727b4f6248d73157f7cf01392cb9fb37ef7990684d7a4861d90a6c5f23b66dc38187d2e4300366c2f105be1143f6b5eeaf42e6400299b16c86111aba336bd9da422bc7774e98e250b3fb6bc2b699535981dde1c5caa3c8f0976ff7f1b5ce37625c097bafc5d5f5fe5aa25dc4e745bad3add2c09eebe740ce68d8e7388fed6d1fe99305d227d3db9c5e4e94601e569a09162ee28e1ffa782eca1399d99346861d10f61d7ba345b06f7eac794cce498bb6a15a0da653764f7391357f2f7fd3eba423cde2a99f4da76a84e4f25d7c31785dca562f2d8ddc1d154168e42eda906c14c22648994c3ba6041edec6e2c1ea404c70021edc0209eb13366f82a34b81de24c7ec97a3e1a5071e3e27b7b5a36a6027ed8060073d1af51515bf75d6a0fef4efe6ab8451e9231d328fed2f01ec5ab1e83b643d0e0430dbea4556f7643fb4cd6d76eebe91ba0e7a32c58325d1a1f0a637873dd952062a17e1ee830fcbe75e3398059fd2055bbfcd894fb7401222487ae91741b7cd75a7959b7f1c401ccf4e065b3932a7ea0b4ea58f575b6bd6b1407d4030ba7ed7a466b09804c322b5485748d1a434107d2f1ee85f3bffd2e6a440453c032bce93bb003ca630f4b2e09540cbf123bc10f7b968b74e1b3315c354f6c6cdf76e98c3f813976604ec61e6e4aa1cb15a3da34d69b4e7d6b051468b6b0a1d2396eb2217c16a5933f99ed25f673c00753062409f18b08e88f7aa095d60be8c010de47d3fa77b6de88a3b00e5a264aee5896858a19e3b5f416ab3aac7899e480306a3a4007a358e4471d942572476270127ace6072643308a3a5ad135914c53c2bac98039ac25829c8c7b346a300b4a6318e598776448495bd8bf28b44edbc503da095ece690422de478c5809164d8e933f5e58729bc3345d17810d537512bda326a8f8f1060180a77251ad57b385d91ded0ac6fc2960685186c85ca13c565923e8a9c81727cc0184b709792d59a3ff8847002bb7369225315f219a46fbd1aa6397b95eaa8d20a9cfc26c28a44c89357a40721e52873a80c06804c4512bd2a3f3a5815b593ef28d539b69810dfc366a4435eed1d820a6fd11501eff4db9e91dd9c693d279084dc6c4c74da0779e4bfe2ad27ec93d564a77360a0f3d0d1d40203f3f94978ec061ced8644fbd4af9a8b5bfcfeb00f35b5143e2752fe16076ee78e68d971162d327c81993e587fac45a2d9a39a3341bfc28b3900f72e346bdda2df77004bff393f9a5f9c21c2e20e79e580c36534923a83e33da381f4f0b9bf2bc0bc24e9863a907070ad80510067f23f3fcc0d2235eac2a7372655ca266ac3605e9833b864acfc09c09fa1be0a12d777f3f828f7f91d833a482e125231bc5a99314cf37e4c402990d37b3c5892a334b2c657a2273d17c712b7f4ccbfefd6b93bbee893ab225fc2b0bbd6951fc4f406a9381ab722c5c50f0737034d7fc2604834b6b374645452ae4fd4448b8cabe2b4d1a1f137ad5196a1ab2b6cebe728daf684fc7a54c2416dda134e33ab1a88864c2350f387205306309b06d9100eef93d6ed0d5d89a5049a44cd91f5735e8c39c370ef626b5419da1db9cca3fc9233c430da77ef0ab96c46a6e651ffd3dfc0750391e0f4541af77ed52ed12b25f270381b9a3e4b55f25ee124c1a148d94ed57e9cd06614f853b423d35f16f88004f5ab57974d0faa2af564ba3889bb21a35fa988d498ff17e220373b1811cb316068eb41859864c3d127c773411e84d21b7acac2780c786d88347e77e427ac78daafd001f1894c33b8143a3a1ddf5d35c9713f9bd8ea439f93a3a206069528eff6006349344f9b743a275e9a1c9ffb477fd7e41e427c0a6e01e8fa13a21dcf4c8c49645df65ab2a0f3d69809b271a42e6f9d9a3d912e0024fb8e791c2e551114a018f93b6cde55007c6ef5797a65c7ab9fa6667c5feb204bde580df5014febdbf8b0a52bfae7034225989b85c8df813a30901beb8f03c2e5cf1668181abe48c45be705857467cd4b562fe92bff34467bfc8a83d583b5f1c9c0b16bfd8b0c0c7a1b01d85960c3e069a00287bfda3240753a5e3fce24228f17b0ca6719bad148e5b78e05bbb705a33899be8f53ad0a9c5119a1b5aac9e355302d079d355ae69b8ef55b8d4e8047826c8d8fd29215dbfa350af3aafee198860c1d7c5fd4a122e7490cc2bda31009e6969503d6d75e88a1fd65ff9e5317139f7317ff0e586c6870c4728c26c077696470edb5024df53b5fe419fef1146dfbb0a528feb0adfd4e42d62ecbd0dc72d1ef209cbda57978a7caf11ba74b40c8d8ff9be1fe1e20dd02b644c0df662bb7b505c25f2bd9e729619df1b2134c3039616a23fc1a1fa7cae77f55e56085d7a643eb015878af23e4ccd25cbaa90ffe4ead5a83374f10839aef5d6d07d076b10ead3f47abb3a2ea421f0b20e5244f3cb17db46f2a9133deabf675c7563d83c474e0d264d12250fde8243ddb9f0098027cdfc6583cf9e3fbf016a1d79e0411ce532e9075f3294e1373409c08191fbd51b287840248416c1cd3ff1f8f610c443653de77b9514f1ea3fd021d92413be63dad38f1c7b95b1dc6a53802055bd13f1d2907c5b8ca021f24c659d98dcef6ec1b91b79e650fd82bba0c846b5e19721be70b1d2986b002726ef8b4321fd998589170b79979516efd5ec41922ad4ccc3e57587d1aa5930cbaa9cc679821a6a3394b69fddba74f66d66b147a3b66d1f3f219f0dff65a1074fc47fb93e54976c555845c6bdf80cb1cb732ed6a2e174412a35ec81de75cdea6bc0f364ae174380bab43e644a6e226665e89766be36a37b931e58c0300b617fb64cb0cfdd60ec829d33bb0e2af411faaa22cfd9dcb82ee0cac9d3576db1b3bdc85f94e1fc4b7e961705b562eb6ba91eaa7a6b7503ce2e375a5914447eb6e7e099de9e31eac2e714cf1cbb6ac6b5b1233e8350e465356cca85d5642bb1124278b739c3702bf7bf8c358d857424c9b974b34a74f70712758105f2f5129b2441df0de07a4cea490831abf4a82ed4991954c6bad424ef4e07cb8b099d8637c723164c133a319857591c807a5cda0adb1048c1c41dce477c06d430418cb206162eb9532d847ba86f45078c7c5aa48beb90eed035c7988c4ec17efa07bb996f84d7001b6365c5ebf320cf99dbbe70e761a33f13e73b0e8e293c2f5cd677dfc8b041bf3cb12a443e7b0b7e87b30a089ea4b90b64432997b58add0a94557257ba1a826a31212544cd5bfc491c4e8377e9e0d85ee95c356c7c7e835fa2836399142390f6026abb7bf18afba94bc31300bfc2418125baa0216a5165098cd4bd65f06a003a0faf0e36dc1a85edd2b40de03070cb83ca386e4e63703121b1bced37d834da8165a83cd6a677992fb398e738b26df96405a1283884b2ef538b9cafdcd351e5129faff2e4c71821b27aa93e0939688a5a93458671427324102bedb7cf1c00de7c482c477651c109c6266faa3425e4f22913ca0c176d8d71b8db644e2f8275458ad2bac3f0411d5620ce1cc7f8d6b5bdb4def75ca4933bb2054c484eeafa5d920d0f71d5cc40507b88429f7f54af240c740066e48059607678548301b096d2de72bd257cfdba6ec6d996497149c472e1b3b89214652138dc53125111b8386bf8dcc0bab5b4817877e414b39cfb134476e70d73986d95fb0343f6f415ca84eb56ee0adf76bf9b5729dbbed1027f08711ee5d3012f699239cf22caf43c4a331bfa6713236dfb26ccbfe4db6f626f272f352400695fcf856d6443954d7adb2b047736de754b59005ea128990ca85ead257101b76a48146788b18dafe87b607d5f7c01e266a570b4aa9138e441b2a9432e414112a11269b6ccf50da5f137a1e50ecd2742266e34e56e2552465823581c0e1b426a30c38f93437a412b9d39c00b185ca62567c10d17e95b57b14090d75420498089afccc4b2d9997d2824f71c9e54786df64275825057cf691262e91d8b4218a96073ede460781cc219218ce8aafb2d74a5c57acbdc27746b7143c2bcbe6017ae2576c428035106f2eade65fd04abe14ca931a713bb2494583738809fcde4ca05423588145d050466845cc8cb9684c15e0a17714c017245a9cd53912143ae88e9568190505410eec2a8dc888fb15ac35f0412ed4f0291e01a802fd96c7e7fed50855458872c0587a0d39b07b0ad8a90c151d633ba285c2ab9036cabcfd9126e741bf16cc50212548f38580e58a8ff0a098ddffd854c40322e938f7fad8a3468bfcccf904e76c3c2c4f6a818067aa728d12e4466370aa3544fd72bfe06d61ad34fcacef62490eb19e873e94013c671ae6667aae6098985c9754a8135c00f816829376b4308f3b7596787aeb917365df41d6610ae3efa7fc94edff8a4bc0609a48b1133a295645c3c8ce57b05b6765553606838cf84f777ca5cc9d34cfa1002ee5fb0ee4f06df6984ff67795815863149130847c288bda86030fb7450c126886a936270f9c185548921cb88bf7e04320bdae03f63ad0bbed511ff5bebd4aa8028e77fa20aa2dc73a8a3ce0bd5a58c6f67900ac47845595645b56d68a80c08a662276b83fe5b0d7b6ab764a43e783032c8ffc2509293303d51cdc17931c1fe4048cbc2b6727a8c70b465c4d227066c4d7b9bbb8b22d1c6c2e23c879d50b15981d29b5651b8df040569269650579727098c4f9c3b73fd88c5c30b1ed125add2177724a8f894fb9364f2b466dfa626ae329f33173cb4ce50e0f0a497ce3a484b844e8d5ea606ca362dead5b63423f9ff395504f72e577c3cc64f57edf6f9ed98c475eb29da21bb5df432aa33667209caef10f19373c85b5182c6a7058d1d60395b7ed30fe63ec257347bcef0d850ecea95e5213ea492ed422d93e24fc51baf9ebaa196c07ecccbef397538e5d85fbbccc99d66342c38084faf94d36b0acb334c46a208f58ab3a4f7d0f705039aaec096fdd6992502d594bf597a115687c00f0c0bfa70c06f5cb8ebc040cd5fddb0c0d70da66a0100ca7b8e405b452af03cc1587089e78648c5d6c346b1a18102fb33a75419e8ca818ec1297e20497597d999ce50da5068e0807b9277ead96ee075a5c0cdeede3df17fc32f089665d129e091ce5f7d90ea6aaf73a94eb7717ac17c62118c30ac9cc2582eb7c53962840a1a393ab3338ad80a63e6d3154fb25a161a7f17046de8c63dc4ac8c92162760166b42824abade51dda4006d960d42a459f0efafd65967e6d213d11173c1925e35c6ce4f383ac067f2a800080fbe81725d329e762b1360042b3d5ebc65e9b4c722ddc5ca702ff0f9d7d5518adcd70fd6334d0f0eb5a65ec0e7b8ceae56c1f78da9914f80fba4b45489b45b6d48ed52d937acb7817bee94e77932d7e32e7a9fa38338631de76e8c05d989ac3c8da3cf3cec92644e65ba5cae71488fbd6b6e72d3c62f795c0c42f08dcdcb730cb50ada173ef76f0fc3921be95930f4db10e786bb08c463acf3416f1c55d0eaf67567aec58fa3280a9bda95db8b658df161e52d2f432541dade8fb17219c01a515126e95685a173afcea19118c5b402197374cc45119770363199ce8b21832cf444810ba7e0cbd6a375a41dcef2d9fd3f64f56054aadbd46a83d07ffb67256f57cb8f8421f8d66178fef69d476a31a0c345846889c03033c4802966a76588867fc069d79c9a4222d0e9cb8478b3ee774162c74667106a9018469a9de2ec2a0fc7988937a3b18cf34b13ee71dbb518dd39fc204dd1cc950d6744d7fa0abc3e87121a2660b38dcb9551b7ed304a8751dd87700d8c5e9e0c266b6417b4ca2cff3c3755a1cf9a47e2b5e2574875d744ee5758b6cde0d343c7d4d8e17080a27b70a78a76d59a6c5265c7dbb87fa07b39bca0ac907f059bea5615329622e3209b753b40cfdceda510ed35ad4ae0146dbf0f7928ed8931aae46116694a6fdafe2a2b23282a29476c74670db86ba99e3bcfd74ec31f42a13dad378b48074558f28dddc1f32ed9e669496995ce4949288125f3879344a15b7dc282858ed442d9bb1951a89c230aaccf75723f49c19612226a3eb46d746a9c828f37051eb0f0f9766a515db7c5cdf2a9080b0d1cc0e4ff0f0015f1d1d031a53dd13bb46de1da8b14bd4d88eb6cdb76668c27a0137e1814e1b672b86aed44bbb41ca2c9c94530746e43849b2b6fee13cf96ded02adf7d8a2ec13ad6c40806d3a130bd596c7d4739c19bc89cc5bb93909ea9e85fc83e83f71b81248b244540be6a815b55e874746029a3b2fa1a58c04429273fe24a2228fe424c6f854bc6068213b1513f8024059cd8399eb59e65dd076b3523d80528a4a821c79f66425f193e12a2c88a62a917f2c010f71a86a04ba35ad49a062cbd77a49033eb3e78ebe8d7da0ca50a2c0577b41c6e693e8092ffb3e1c4a0c6afa08400c47b2dcfbd254b24565be6011c538080b1ae9e53d2db87139fcf04f2c37ee64ab3b715d673655e48c422cd7d918a20b5a6d513104bd31266663d251f5ee9aed9e026fc2baef95e1a1fb0d95a51ff5f58cd0d0caee49c14ed9ad10ca3ba284aec806d936dcf8beb95c172e6a0bfa53fc101ae691587efd2a8e057073cdf3a00aa6f9d05e7f4c3c79634b4f7f23c01ec34c60bfdf49d8e5b14f328a6993feb007e6fad591ae99f9755eaa1ab904537f55b4dcc102f6bf3f636e2b34658454dd9f7a8811f9b415fbb8f2a95788b386e5183a993601ef59f78be52b7c4e13e6bb0210df4d5bed98d43d98a841d8fc9c1c2ff4100de51dc2cd3ffe25f73294c17c5245f8f58e3d36e382d4e2068cec2d7b5f2bffb6b90b637239c5bfce57cecbc3d83c3b72a3e663a9a8fb44638257d5a13d89a3acd6b071415ec07ee5f38df5c3e8dfb420350f5743c7cdb8d7f004074962c15ffe025d8141dbef47964fe5e09532cd3e1e7c32c09a8a28689650fe8573b471aac47d87a4003c2cbe1e3eab3a3048b295dfccf505a9363b47fc42f1d99c8cc2cf02744a80f2801e865dd4c9daaa2fd4f7ff84770ab553eeba4e7985f637c7c45f6368f4537febf8c528706c83ff1a888747f1059fe705be114c915c406cb4cd9c799ae663c5b29bfff89fed2b3e9dea770573bcf9c2e8ed5eb27e6d3700eed5a914302d41e4fa5015d67743f15b1281f5efe464a7898c5542c794fceef4529102b5b482c1ea5627edbf53a0ce50db0d3865ebaf0a206bdfb032f61b38817a4f753f3e9be27aadcf47286fbf71210202f4e6a9c31f8dea521cea2e404cd73cf5fafd69505e2132781ce223f9a12f6ad49d43b70035e1d61f01dea7b0bde9274c276f1efa2b4195c50748d1fc8581b34acdfcc7739014fffb3193587591e4db6a39f2880e1f1be9949fb44a502f649867f54eac012d76b9ba3a7a2cc2c85649dcf55d2bd2cc9277f9cbbfd7dfd32aa248f2e3a9e5f3d3855af14ae3c3d313e8df3524be0f09c4137d3f2e9112363b29e59e936a8329d40d1f858d14d40c554e043bf8332dd58dcceed8f96aa3571a84f52768ef8b54bfbc8699a514c801160bf7d453501b92ca0395efcfea4b633d46fa4f4492477a0ba4902b3fc3c813a89efa74be17ac8aa078b488a7e348fbe9b48579db1e0164cdd2adc18dcc90da015480d2ab0b4c4d1241ec58096fd861be5bd479ef1246f90bf7da04f61759af11d00189ae5885cfc834a5563fb4bbe8971d2f7e74da956c4b38bb839e5fcf307d31d1758b205f6f42ff480f76694abec71b5cee65aee618a683bf0acea8fce030b651f13f91fff0a829ecae99cf82deab103afd4fcd3cc7154f1f40703a00233374367313ca4c1581dae5deb7403f91cdf5f2aa3bdacbfa93b6bea630760f55965f995febdec524065f971027512cf4f971ad9ac7117dee838ebf3f10da0210b10b862fbe804f08fe68fc730afc176632359a28a262c3edb428a4b9ea07f7c41a5da4042cf201f5eb66e861178fe9db81f75001c67751277b2c26f967ae2aad09f55b82d3a92cef7e115c99b4c9c5f6315b9cf327fa3d2380488ea8d081950e78ab39db3ff91d279304eeb1b954f63bd6801d4fabf41e91ce12fcdd895f21147c89ba0677f1f8200fe9473a3e5ecd74370c6d1734eb49e7d7e4025dcae9028a02e576d6ada379b63d29cf5126380810646d6ab34ef3aa3a42c0b39ed55258fde70c0c8db26b14690a3d8b385461a99866984a715919bdc5e46bd2cfe35a7b8e63d1f73decba9c4a479fa940734da5816916872abfa799b5dc6596aee2e350e5836e8d8892be1d6df5ae1bc959ecabe86f8e2dcc162e2933c317afafd829558e3e2492723cfba3e7c63a926914fbc7171434914bff431cf60aa38b9fd1be4dec30cf19a4a66d2c20a0ef47d2a0efbcb6f8bae81bd38eb3a02339b262c28014e4b112519cf25c2cf3a81d269dc1c465fb36ab7d4cfccc1bbdec4152c2911f6360b8be211e3ebd263eb27f96bf01db1bda2cbc8c19616102a9bccda90598382a8cc91d419e2f9c3e2c03769568c1843ba96c7e1544a9037c52849a1b65991576ba5f6825c7df25315b7e84c94f41d50cf83114157b3322fc6445e3103a5e8939404d1f5f59badcdaae0ea6742f47ff40fa268cc26075616c259b030de7d4337a57b91aa1408b44ab6880022fb8012d8ce171cce14edb703e3ee64ec479088939d59af47ebc82a2002462dc764593345b9ff5fe24b987ebb878bb9846d6aed8c3cfa0fb944b1346acce84f1f087dd3f76bfbff4912619beba646242bc803de3fc99b7cf3a260aa320fd3b914820a6ee179cf7c791809227b9f6bbcb0a4fad121cd949964068486231c14132740ecf6e73bdf76c8757cb7f891ffe67cd481724f1e58ce138cccb03720f9395e4e7f93bf912cfd80ae0213de325500fa0393d4137510efdef1d820b821480f16013b1f11d0123e4a464abcde7490f4010d7cb8c4f85deb114bab28f5c1280bc70e6d208b2504175ee36c9dd8813a2a9d7ff33c7084f143fd6d3b7e9bce1b3c6abf732927c82fe86c617186741afffd54183f151ae5671f2ac0d835c1d044aad954e472336fc2f0ac86036eff8ee31e1d669be804b7e2c0db765c998a193fcf95e0a98a3e4e20a80ebbd0530a3271a3188b0d586a5f851ded326efc74cd9b85db32bf04ab6354cb725346d2d6082828f158352be57f677e4797820ae1210119c0ee9af368e365be1d54631de4f4d385858893b110157b55999ea1450a6fc90ae9332d754d1466406ccc026b44588ec45a8059e552ab17358addefe95a138e2b2729204e2f9fa0a6ad9b2866930a3d290f625b18a4b67dbe1cfc3a07e9deac8a9eca66333f7f7ccf3077a1d116fc69cd960c6426067cca66b6c933abe1cce89ec797d1693cec426234d6447253755badad8f57e8dbfcdbf4a7c6af72c34f36b87896159414333db8ac60514c1b605872415aba978d7fb338b3dbc891e2784d75b0d22857218132c6db7e572fab91fd307479b77b4afcef10d3cb8d18384ba98d336338a014a57b339b7506ce72d7f6488033a36633d19ee8b81c28c85d0e9a9970feb3fb6bc7c0c4d058ef8337702865613e86a25ddb7bbcb777f29ef1fe4fa3a88441d701e7a05ff656fb273af3063fbc7641edfabea2e66d2bfb75e542199aafab74667b1736012379aa498db2d5babd119ffa24e8355875d6022141508269ce8466e6696282162668678276e668618206e634609a36266860863633b466cad3c89964fa0507cb2b57b57699af900e83e830b02e83eb36800e03e81e8cce03e930880e037519b06e03e83280ee01aaae64001a388a3630c605f73598f13533180052689f072b07695e4e100a014c410a1de7d155ff0191422b33e6ee3d28084302844b98b025bcfe344c08121c4222ca537201acb5038aca5a8c59305a554d3aa949d641ed4014089c69c68c5c23b027d7066f034ffdb611bb2748c708cb6803ffe328601c19101e3def015c03500c0fa261cdc6289cad5a897045d5ab4364036aeb6646895adc92afbfdf12a2d60821646f2977d5089b08c8083918169badd1e48ed288a98c182e3dc9c37ba2bc206873708b3e46028a1bedaea182072f2fe99ee97bad64697adad27ca729dd86d6b7c5ee82b6c63cb345b214fcac41b106fb88373811c757cac13c3670a9440335328272ed6de1afd78b73bc1b9ead61431adda861a38886b15c2fee8eaf17e7300fe9e2e2b38e7441797c44fdf1cd88504b27bdfbe8c9e0944ef241360b26a65954d5076f432b89aadee1d1a22a46e9244b433a0ded695b231db434ece39f389b34e61fc9424d86d4e816bde709318e74095247cea174877499ab1e1519b0e052904f70e953255ba89d1d5913c645f40ed74a8573e8d6241434ad26a8b3588bb266d10be00a758c5d3a8bc96c0e7afb3266340c35bfb2d19d5e8674715d7a1ad245c5a5078276b4e3544916aa8c098bd198890956abd54ab2d0afe04255dd7175691b7d2c8ea7711b143fef3ab65bb2ad05d6c153691645358bfe74fb1336a389189d5206092ab711b9e00c9356e152229969ba403f417e8c807e8274692bdd902e2c5d38ca38c069186ae290b0d8dcd1a8228c70e98188aaf96f7e9e64697aa6a5014f3acd67bad396c48d26d3dd7c2789208b3724cb4872c7d8fd2129d91a770db5f4d2e5f568a9c381a4a7f49cc83e92859ec51bcc83d3b109c3217714618433c4522f684251e3e4f00ddf14d1d28479b4eebe34ebf4141b3a47d23ada890da2a49544794f2f52bd1451c517556c55314e9efa4cca557ef2d453883d6d553ed8223a57475f8f7ea7e722364211715057f19388a37a8adb20e29c8e72907da044d455620fe92944224eb3e1282211a7a97e12734eb361a779083151176922e1c1a2e699309c1e921371dae9f46c346136c54da76f1e2d245deae9fb08b2857df867b686882cc6f62104f4f333a4737430f48f7c44c2dc443539174d2b984cd349fe3158452e41b949ec816249c41e2dbe12734e73f11422ca67564749f19a155fd992f7983e93e2abaf6c0d8a0babea9f2e6939a7b5b0ab9f3eb3faa9c56b4ebefa4c8b94b7b82421b13d5a5c14556ded577c463c8aad41b9f815b6a6a78672f1352b6e2f692c4455ff864bdac5dfc56758fc065b93721677c1e23527ff256db5fa69f59cd35af09b872985285a51ecee4a7c0bb17974d047689fd9a23943ac2869a2286917258d85286925dd251992826d0b9942cb3f40cb47144dce997c93728ab2e2e429aa5e21aadae6a89d8e82723a5dd2524eb6c7bba49d78fd1e7e8d093bfde4f4541e75d77b8ac8454f74ef88cd436c9e063a41e923fa24ca99a209a042e4c08d9b9b9b1b1acab6ced01152444963f19eee89675be816159d6c48bac40c3c371ee2a0a03b87b6ed05bd7c550f8e729ff50dfee124260c355bf3b5a250bf348232228da04e64901992659ec54e6dc9326770f6c66ccd9f70903b3f9390ace9138bb95c2cd68f9a393051a91db206fa1a03440d4ba359e2690f1515155ef3f411dd4252f27254ea3056f40152e8a7429434942869df8bd42dfc8b54ee8e7248862684aaba2d6e3f25143da0c2125a488308c4608446dfd2a38e0c54ed690b4ba76872d4acfee920b681348b2640077564a0be99309c9ed389388de5f42c74c3e9f928c551dec23abcc330173839a7b19c88d358d487d73b3e6cd4c226902cfa190f4e309010e972fbe26df09da883bb2700dc85b8f21662eb560cc051c4ee2df24d018a3dac55f55bdc8676127be0f01b44fb16afd9b758dd5a1c224eeb49f11ef00617bfe13634abeadbdbd0724ec3c1b26e5f639da6c5596f5bc3e1f6d6d2d8e3701bdad7a793ed81c35db8b80d6d0580af5e03c057efaf56eec2d2b8f8ca695607c06d685654f573b80dad85a86aab8ad1ba7dad75fbbeb5343d6d6b01780e96c63e00a769f1d66d682cd65958cf390d8773143788bc120011005e4b94b3852276978583d86c82d6d9d94921ca8b2276f724cacb3ef406d1bb3918514f2c176119a7be577771fa1b13665b7c44b9103df18724aaa495682d6e3f7ad785a8eace5a89aacee6a8adeee20f9034179606355bf42b6b43bba4d98fac95e5001fa1f57497b4161f51b6c54bde4254b915c59b3eeb4e4a966ac55f6421aa882b441b44069a2d7acf081f352b8abe113b2572d16cd1ab4439e94b620f95a78839a7a9384ac421e2341544973ee73415cb3064ffb8f41409c9a2a7dd95378512254d852869b27de46044e5ec2cc6402c8835cae6a44d72b86bb368cc647a91af0feac84080f04fb7cc53d58b1ee14daebd5289db1b8d090bb902927726ecfbc320cf80804b3fb24e8c64a10fc58dc662a7f6dd6831d2c5e4f974967d065082da99fe89f531d2c574e93f09a65e466af7ee0ce4a47b9681348bfb64ca726ea61e21c94d870089f5a1ea6ebaa4418079668bb356d559558cd24d9f29dd649af9b8d0d2982dca3e660dc9b223670ba583800f5c4a3fba2ecd8189bad9934da5a03610b7055ec15638ee2b2f9332d479eee30af7ea166ece395f2b34eefc8aebd5dcf6e21642ed958e59e9d90d833bed582912434b10810a0d55a19b7958820494aea8fcb7534a65873d50d699690bfdbfc4077e67934105ddd0c995434b78a1282889a2954b368bcd62cccccc4c29534a69534a245b99bdacd021254c4106778c1575284882177aee182b12628468280d4542288dc5624af041ac0b45ee182b0a1a2a0211452b572c368bc966b159aca5bb25f38bf5158ecd5e88f82b442b2f44cc432c16230d1509195ae2c71111cc1199ae1c4ac21ab84d0946b629d05a4429a5cc4c29a5945246c009aad7ac7ebde8eb4ecfab3320a0144500156d60d002cc28b5400131ac21c81d655015869280062a54a2423724e40815ee288198f012f312d3ddddddccdccdcd4c8db62e0851c3127794411f98c1cc609899999952ca4c29a54d816ad800ea6ea059d14b114c4c119d01010d0d150174e40c779440dd0e983023169bc5641c9bf12c268bcd3a36a3c1b13b8d64b31769d4dd4d149b311ad588c562434a78c2a5760a51c318ee186b0275c95e5e6260625e62829839e6052608e62586ce9798d96b4e6934ca267ed0a01ba32d314a29a52f4141434ac84150509195d88c6730fc97664deecf5a84e9f37b7a30b3170904d3cc331896b1b61733b3805eaf570b7f265bf34053020d2d11844b8138252c01856ee8b301b73dd3c79d3e3f0870276d178b262a6936853aff756077d3377dc3edd4eb430e01c1be912e7dbbc887cf0fd02df248eccc9963ff7414f347b338d02b7de64c3b7f90ba892742908de8b4231bb9ad37aa44aa3839379e473bcb7d6018fe2085ea63c2484e29a97b37d13012db3fb345ef512ba1b8f43381ddc496731f94e3b80a1e09956fd10b3a7dec58bdfeb13f6ca70fc942cf83650db579e85f32a8a69913eaa0ec5c6a0a7ba09265fe233195246ae2b3e59b3e820ea94e700c0808e83cb6773a014078740349968d81a48ba9777a47bac0ee36efe663e67dec1da2efe067cd41bd038acdc34240bd730474e401f54e13cc40e46e6f1e473cf8888fe64927cdce36cfcea6da54d3ce800f435b53da685bdff051b3b6bfaa50e9473ee292d8da9e83ef2881989a9a7aa29ce53054392bb32f09f4da743c23943564c890497f363a29fdc174b63cc3a5434877884bbad09707eafc4887301d424f87748b4a6e2c4954ce32d190d7102af7a321d205c6d57b3777dbe8f7eff594aabccb004fba8cf0a52aaae8277eb310547949fedd470687e49f2a06e9f533a4574b6255277d9ead81af3d3c6d4684ba63c7582872ce6c6d27b26d2c402a25a2ec6380a33af290217209321c71b733916e2192674882c7177abc00086230427bc9abc2453c8489e6587339eb922cdb57562b5a449ba4856d136ac27291666d456e916d7ea3734e21c9b2b1907499dfce479030a6821017612116922ea6e622b40e54ef5d91ab9ab94c7755ed343d638f1ca6759f59a1040f6d032b94e0a175b6a63bc97ab3b5ad5082875662a26459b3b519000788b6bdb3cc335b9e2869349b83afa42618c9b2bdb0118e065c79f0e0c1d3b24fb3eebcf87375f4e56f30e813786c77641e3ce419ae4ab7a8a4156eeec856b8b994877431cdeb0324e4f3339b28a27a3ac31c3c87b86c519b3d8128702b02ad1111c99071c44548171da44bc9a5670d4817eeb4cb6994ca47e78d102dd21c0941336de850b930b553ec8720f59b610fdde43acef670a7016ba5ef25cb3744327e90b00c705608c9424feb40ade9a9211d7c4d8908b5a6a7063ce99ff9ae8a413af8999e1af8ef33252cdc800b3350c1cd0d0db43f30219b006395b48f07087e263c68c1d7901ef66740bea135ed238992b6c3e6723b62b5af038988e865745d7badc4568c6c5dba828f4fb72865a10400a923070d096daa17f36e974fb8f20cf76b9012e0d21046d73e4dd4964fb83b48d36539296521957712ff4c98cab3b5efa57b9e2d59954753fa67559ef5e8733042ed2c0f590eaa420dfa5e3a043e7b23670b024258c9734eb99936eb922cf44395edcaca75c46a73e2eb165c59f8a2ef8b64a19e0b0995c5928590dad117a60b2359e8590881d1e19a5ca6c1ae1054f660dc021a6dc1156700d12cfa17082a0892febda67470e623fdb37c4371587207d24b224e4e8c46b22dd9a227c2a3e110e0d213e1a249b9c30823c08b74e94b553e70efce59dec1f645b2d007d5cdae545836e0d2606408bc156dcc2ce94a6c64deeceb75a927f33ccf93bd288dc9b64db6518e523aa39452ba514a79ee665f1b1160c8cb7574d6aceddeb7b395358b8e32f628f53c4f9451ba5d46a9d7511a6b96ab5994524a69dde810a8d09cac395f332b6bd68b6c7ef672f996bd34aba5fc94534e39bb9729ce64f3b397d953f632632b2b57bf8550db0544bbba6777cf4683dcc491bb744db652cacb9a35cf5bf7ec29bbbbbbaebba57cf7f0296333c9d9d3989497524af9eed90b11918c586c361664326e33e204176d5352972c368bcd3ccff36631592c269bd1199b6ddccadd1e9bbd10c562b1cde8725b11278429ac2e83ddc2f29f37caae5b5dee1cc771dcaa4e98cbe5e2ece6a21b58c2073836c2cc1cc771dcc6fd356b16c7c95e3819f720482fb5d6fa229bc9b8cb662fccb217e66cccd52c598d6e01629b2133d2c412787089e348b04f648f4997cf778544ba675f245136beee4692750bc923914827fdf3441969e3bf623252bf646c5daf16596cb67dab4dd8eb75b76f6147a6e008123b29688902235060043da3502814ca1d5135264c553a0ea595ac0a071fa769df7b948e924635a48bebd2dfc091438710dd3269b3268bacb3a50307ea76a6dedb63bb79df1ec4761bcda21bed1a2cde2843a57da35bd852cf43591bcda23748a2bc5d83fe06f5accc8b4c84699614224284c8a54290cd00820ad5902dba196d561a15793d8ea46013e2a7593d045ddacd39190ae962bae3bce99c282e7d973a67c24ca7ff58b3c534aaaeeb6c6836b4300c69ea43b09aa4e9a1173eb4aa4ed559103c68696c682db29164a19dd3d7c45df78f39f4404be39a2d0a92bc5d33065fab072b0950ad3eac257d1982d5d2986c188a34644844558c302479f8ce961c7cd783b51efc28871491945efa27ace4fd19aa62984ce14d242fb134a64e1cab2a06f8f035f0613d68c187b6ce5627caea85375d55faaba82ad91cb57a90a656d6f85a1aeb6dc9c29285e94111355bfc10a85b7a10f3d9c1478b47dc29e9944e92b0ceb9f4a4cbf7d2bf205a0219a092de279d34eae06edffb87a253f9924e4356053d06ab680a65f899fad0d6f4d4c29b5e037a5dad243755d6e5cf985e5f6d0d89651d06191443ef424199870420a176ce84550f558f629d1b5d97422159e85fa432a5e18b7919308f5cc9c2b2c5ae1eb47c441f293c946969faf0bd3b8c4f07774b76ec63a02b89a4770f24db968db6db390cd4dde8ecd07cda8864a1a76916edeba4a061d2746bbb146a56c77136013a08ffd14896ed1f0f46b5df4574cbe8e1744b4eeb8c1e8ce99b0eee8e17b0b9a49b74b6592b0af5b358ae8e7568a48b097c91dad7072e085a225d960ea35fb23ab84bb22347ba673a49349d9b356b9bf50dc9b26d13e6ddeddee66de723c9b23dfcd7a4731bf7cf72a4730f827ba7764adfb66d2bf10eeb346bdb389eacd3300e4792651cdb45346b6b9c4e4661c4d646dc6d7b1bc13cf4b7b710eab663e3be711bc7711cc73ab2b57ddbb86de3ec585987273443739109976032b345b9b9e69a6baebb6d0f9041b073e1bcaf1442ff8aba48a88b848426ac8f8e848ee6cf0c32814c9fe97374346f7ae614d145338a7963fba8593ca3e099b5929b9c4645ba6c134ba322d91e2a2e692617fb68de348baa106164c41251357f724943114d8ef299929fd89a93971cc5d6f4d44e5ef21a9a9e1aca4f6e4eec10297e72148bb2343d27b686355b969683116af3a47a2a1fbcc94b4c5ef211c5848995b3c4c658499c589de6d1437a28da705d072504955926a2a4f1d1a4d1e68e6e99a5cf23bae5fbfc215db6279aa1e816b9235d60c8cbdb07449f6a504d5ef292059989b6cedb69c2a8a885843c8edbde79deb97796a6a766f292a7f808c24a4e8e72937b9ed789bd8383baeda86850ef8e3af6918e8a0e4aa833070c793b48b2f41720857a6a1e9d386f60f4eda366f56de8a9a5c900ee77ee74cb267b9cee7d3cddc963f27e8f9297dace1fb7df39ddc259b0590c44e8a788b66c41d2455e9889eda393bd399ab0a9d3adfed4399ab0dee956bfd6225448d4d6c9e1a3a6b47ef3f4a6e329519b67005ca81355d446dd3e90ac4aa6e4dee5a53bb3798eeaec6c3f8583ba710ad1441462b6ba03353d3064076a7a363bf6287949c94b7c5cd26acc568b37439c5ec32547f9c94769c404ca89e51f1f499834b5de4d3eca23264e2cefccd60f499458ca3b453420925651c1c7713797e3b81650d49c69225dfa729c0f2347448c8c9e9893a3b81ca5f443405528c0e54ec5ea83eafa4a33e04bb6f4cfca49daba0d7ced3b686bdf67e56cd1128906048eedab0eea76be4bbae448970f48580b912dee56b0c216b61086308cf228077b620bae5c0207742e7311277e88c82568200aa22570c0c7e538ae930213914e481736922c5c034916ce883ab20fe380f392a8422ec747a045b33d2c7c32c8c506ea76157d48bdd7bed3f4505beb1e5a1aef9dad219d3b4df78f7b4de9db6d68345e13de7b277aaf31bd3b028eaac9aaf8dfbb87f6de69e99e487ac7e8d87ae876ef24ab9a5615837b772232389dcc9da72275dd29553d5ad2355bf2ed9a4d4950a2c26ce679a3377b6997ac5b31256a3fd63974a0f3d2eed001f4e6e6e6e6b665c9da3607d03bff358e79240a06f0918b631e3972dbe698d7e15d962cf4ae6ec140df395dd4bac4eda8d9da469710320cb3984c0675aed786029e4c304f66e6e6a67d35d7dc27b7719cecd5cd71739bb2f97ac5baf69afd02c2276cfbe8badeb729699f2800973bb76d7335ed134be2b4c0a54cfbb6d92ce9662ae1c4d1e4965c7adb56c9326bddee490a76531c107541e09cd87e902e1dfb81b5426d2895096eb2514cd8640124cc355b1bb5520125975ddba78d1064e6e44b962901ee27b0a2361f44a11b4249179474d936a1d113b243015a3bb4b614094b91aded128522862a59f5e2a0b9fdf94d0e69344061f2cab5f25a79795e95af15d7ca8aeb357be51503899222f7e209f6c095426e885c063a12e46e373f77e3af391f486e1ff9910212ecbcc008c92bb19719cc0bcc4c4a0fa65f66301b9dc1c85c5b770d1b73ce8a5e8a6062e69c737677cf1e3202970ce625a6bbbbbbebba615e6266bfc4ac34eba5099806a25bba633ac63c0491481074440e548004033e12ed3c9bdb954adc5bcc01a7922ebdd7487a77b3eeee39ca962529654976b7945dea26b1d77577737373777ba8eea6242621a1f2eec83c2ffa6e977d4eb674efde6e5b1bfda641783afaf6b0e58053392b6950f9de6af60f3ae7ecd938cdd2c1a1de177ea644fa2ccb86f49d742fbcf799efa473254b135aee25ee7b2d3c4d0f67694aa38c1b82228d1bb747d795d1ac39fb98adaaff3ec7c33e6e5e743747b2cc791a399fa7cd3937abc3029d2b5b74445600741493552aa0e0b4821a4cc004489c4f26a87d963b2a9046f8fc997491524a299999999999594ac92ca59452ca34240088942c470c4941778e65cf187694e75fdca1004284dcb100e215c0954db8a9125c01a423a87c593382048d82424f07486e51d6b159ec323a76973c2f002762b2192dd9e846c5de50fc959e81ef29e0956189743959b33a2ba56466666639e79cb2a483921da47491dd2577134beec7607f6c5dee9748170963cbdfe16ee20e57863d802aa87cd9415e505285ca2a7a2a98e251f932061293a2fa8492b3965e7d81c751a0a492ec31bd3a8b91519b4144c68cda0c22335028146a464d06911974d2da0c2a238321523b9a01858c231a5040a183484d4886d00c1a42a809ab1141a188a08810e994989303b1179998da904c2da636549bb3d6866298368da95198d7134f3c61c3c80d2180e83863a49c74cea1a11b2e88113a7c40ae5c323a8b3829b074a19d034ee5d3a6134686524a29a594524abbb9b9594629a552e80b2c6328018ef364996741c34aec857906d3ddddddccdc3c99290331d07c8501908e547197574a797ecd62606464c3c83437cbc0740c8c0c8ccc4bcc258391a9492118995ad31addb37bb6140201f540fe6b16032323142303232324536bad3230314231303230322f2e9818999a91904c8cac2613aa734aa11d3578b4e90c7803df8b3e45793a78a0aa9c523d4e18d061033cda63a2821486dbf36a45a17ed922bd47a1c64c837ad4939ee772b95c1e959ef480902133637aa09110ea3c68e472d14e0cdde285943576a7af663bb91f9e30d209254554b73624481e0aaa86e7d9134a10975eb6e649e2b4714305d43bd25cda3a98fd842b2fe726fe10a46e93e3d8c666b15973cd79b3982c1693cde88ccd5e73f69c734e4ee7932b2aa32b12b61d8008957e3cf9502ffd476f6e2eb539bae7d0e1dd2b7598d7811ac29d0f0a728f81e629a909c7bc9d9d4996f9510ab9f4e3ecfee2a071e99d58ad9a8e282297822ad26575cacd3927a5f497d38e75066d33153d2a7776c18ee9c2e82b43b250fa43bab8fa88f6d1405474c03bbb55f0a07611bdc30ab5b3a8222e3dcd81f98f427596b4d1c92afe3e43f2cfd6f4d4944e6255fcdd64556c49482c4d0fb3add18037855db33e0ebf14bce076ef7ce16b3ea15913bef49185545c53b18d510a3ff34923a309f33c2323232323169a05289a3b10cd7b95443489f6606859b3457fba1347955112254dd25eddf2c281f9416e41461295b32f322119c8369d300a9f5c8d5488bee99b39ef337d342ba9542a15843cdf8f419f1f1f203fe310b7718282524182820005a5c40bf04dbd7f7ede3ecdfa61203fcde20bcc9bb238b8713a284876108b3b48e30409f2e99f1735a863efb8fc711ee15ce6e1d13e8ee81fdd82d32d47f466c26c68fcafc5ed6f58a5dc350d7046a5ac6eb038e0605b5c4e3bd6bbb236c58676645d9601565c5a2eb242e6a6f44db7a02c23e0a3379b30037c64ddd43f610778ea579c21206557fc43897dd32cfe0a918fa2a8288ea2597cd4677d0051ce9601441bae9bba4c598f8fba65c5f91c45c39ab62284d1969b78e1843ab2d1e58f5ce4f2d948b7301d6db86ecae539254439ea2931c58e2b37759438c66a577697e29692923a4a14f9ca9428af441147d45978cd2a7121aecea10dff569cfa971247be284789e32fea29e2c837e55f4a84216feadf045762ca65d800150f53a9940a3bcab378f8427ec5514415291bcf5521da5ca983bb2bebcd807560711b58b0b0a08aca9b68c228cf6cb11c5129618b69814c47b1a3e7a5d8b15ed3812eea9acef394b53c47d91175512a576147cf4bd9b15e153ba2ae8aca4d2c96cba5f231a622aa2e8affe92bae228e3657e536a4a4a8b0235f15529ec57211a9b8ea9f0af122ea6486aae2b36e22d439ac370c51a8975047b1232afc6ca6882a4f89361c259fe23274c0e92bec8af137c551dda24a9d7f153da8e49bbba9774ac4005fc5aa44be271576b4b92a9e12c7bbae4ca552a951c776514f71893a8a0a14ea294fa56e7c1cf118d9b9a9a7642a954aa5521f59a9d4c7d84da5521f513775f9d94c892897628aa370d0dc130ac7bca71412a5449e4e9ff5c97a9368c240d92af9891dbd5a62471b2bb79e3bc967738e28138a876ea989bcdae5ac8d95db53a85be43531c2036991ac790443f8a464967982288a209dfb49bacdb9cd59c1c997dd22a48e60c33c5609a99c286daef7710803071f299d8a23cdb52189de0f52a81ee9dcc35872a74a77e4c891355cb6fcd994610f3dd893cafc7842a9d43f51e51d3df6bc273ec946a8724889a1fb4916aa7248892726886215cf8e9268ac17acb5929c6dad84a64486a0c9aa629cbce433272fb135355268a6c4c44a0924a9cde557922da4e7f005e9a5bf9044a384821eb9d47627a9785d5f14d5cd8e3624d1a5f3d3ca348b3f7ad487093ac0854074622b41194894f881124074f0f56cf1051fb9dccca717432a78799949bbb3ce16f3cdf4c08b2254ba62dd13b0592b972f74bdfbbd6451a891355129de2e7a8ae294421441f026d9c9f0e472c250509ac48eac149606e51b756c273fb16fd60f1b9e50c78f7cc4f5bc1bb3085629ea68a2a8e822a0ad08cc035f4aaf424c812244e2d16464909caee2f32b0d431d25c5b9a344d66ccdab103f5b29acec56f7794952c5d1e6d67f131ce94f629fc3fa8f4f4e4e0e43de137b729b7b228ef424252636976eb7c46e45601d483e9b95c4d2667d9aba101447b02483fa92fa9488fa7e243d652e57fa48f3c891fb71253bcadcd277e6816d8ba16e1f5f3159d803677b9098eccc3c728446626fc8f0019286d3eac78ca086074ff292f7d4ea4da6cdd64c2fa9d6f4b1ce234768924632e37d063c897d1f39726713263d9227ce97c21e6232af6dd81523f0c0102efd6cae8be338eeb3e9b948f7bc9b3c99d24d9f1d6d78aef7d0aa4aa592ad8137591a700823d77b781bda6c92fa5249e3248d43078838a6c7a5fe6ce0895e09fcc4b1de8f74e6d249a20e7ac1667120f5018a3aeff26ec375bdb3f7ce8e541c19e87e67d1f513f3f9f7ef1f3f14bb735c47af0cb94a856e110cb72f02b787207967510793c4f136acf72206751e39d2b28d6d2fe936ece5ce9c73496771f49808ae894b52e292789ec50d07cda538e6e55ae2340cef1bd7dddd6deae69a3625913cd0640ac36651d2f9f254fae4994c281aa8269355b15183c65c2e56c76d45cd9a458a7c3c0d7ca7d309d5836c09b271c5ed14b74db7cf491ebcf75bb6743ab613120ec03acc77e2cc01b2091c7c0d2059e63f654b90f10472109ca73e7842e100586f6edb534a4ab2a8a024cbbc65421d69ff9c7aeb934a0fae3f6ea9a8308c7bcfee7a7b72a21daa23786a18a54db04a1717dd8095b34fa580eeca77575a29593acac397a36fae7ce99f14e5a5d1dd86246dcd7b6769e63dab9234d28626df95786aa1c6e64b4c9bafe9ee1db42af9edf3d2aa6270f31cd13741d5577a8d09eb3e3f43ba676b6c4d4fedabf924ed1351cd2a7d964ab3d2614a77951e2b7d86329d4a5e075f55f85a77d24de7eb892af99a9eef35a477afe931d91abdf79a4e25ad2ab435d2e56c81d6d6bcd3d750ab92d6d5acd263b355a205a9aa4ff559550cd2bbcf90de79afa1277dc69bf746d72d752fd92024183eb9e26848a489ba9274187c49f7c42048df8b27d8095736c1073f2edf796f4599b8f360137c1074b9542a1d06df5210a46fef441ddd2b2f24eafcb87ab7d0397b005c6001544daea441a51694d6db245d59adb81d48a64a90c0ebf826c828059de78ac950570e011901080839d83c4fca4dd233338c38f6e747eed4bec47031cc1c73cc31ccfd179818e6b6177e0cb79dcccccc7c3e8acfcd32a8b404f744b3b67b5f897b13697a6a20789aefa6836d559a65aaf534f335e0e9dbaafa24f61eda1ad3e7bdfaf0db7f60a2da2448accab3aa1824243592870f5f5fc3300c1fda21c29358d7e59cb992009ac234599a1e10fc10a0adb9115a1a611113a195734b42d5266b327d35d3c1cb0982e0413b440df3ccf0a6ed1b4b870993651fe691c1e90078fa0e980e9e7e06b42aefe18cc9aa3c9577d0f37a67bb496423b3b5e570539b47ef68d6b6fd8544ed1d1b906c892cd420900d3db5fbd83b8cd8c88847b2f4e4f54defe896fea7854fae3c242aaa593c002ef499f20b893ad6cbcc559c730153a82ba096029573ce39e59c734e39e5374a634e2f398dc9e5ec6ddb58b527bad54c64694a7eb22c74642273c3331473acd3e473c78e365cac3e4311c513978d3014cdeaded9691f35a8253779898f72b8f3843aa1f7a8046d7844412a15a2114000008000c314002028100c06c342d1582ca029829e3e14800f89aa46684c17cac320c8714e1964883144000400000000224d900e182e553f85e58589a4d4a92ca8fea7d3145959a8a15636115673e65b9ce198f7884d49b83388af8e6048f2db548277a03590c2b898e8fc5d838330bea9a7a82aeef2cd72c04f281f8c50030e9fd354c1a52f04540e01a811db5aa010e9010fe3e08c79af6beac2e5c66af93e98059f3d0057944d22e2805c220bf6536f4f6e9d0ff0f1e1c3f0c26e334f9101e8fcbfbff831f8dc897f045f7bf863019385f8cf2b7e18785a0698bd273bd795f973fccd24d5ba753e0167a76f7fa48a8d1ab63a5e3d3f2984899926e3dd14c6961007fae3adb4b0534e744e3c066238eb406bba09c6efa8596ef5384d71956961ae2d46c9db487580907100b3ec65e5767f3a16aa44c6db5436d130fe48e7b584c7253753b9de562e15c53501bbdadc8433a3a0ade4401779bf594e091398c72dc82117817e4c6598d1e3ae2929dc0578f4225305e977aeb6f627fc056a8dac4a5c2618d1ac279ea552a5941714f8048620d405f970613197ff5e6de025638bfdcceb5ceba7fa6e29226897060a04cae1dbb0b7e4b2516de291f00e31ce14583882ac8b1953a5a824683092d5886583deb2d95e83b0d8a033793a20c7b761919f6f8374209379feeaa13e44c6262f565079f401603a2f928ce09606197f06438b1c90c67009335d77f5c6a1223deded015731069563c803493d914a89fef970be454649525868a300b94d84bf47dc8c9c0a254c36e5bee04dcacd5233031a8d77097966b02a543ae3e7d66ae96d92436ac5648723ab3219d94cc1c9e6694632efcfcfcbbf43dd335600463cd54a6cbf377b253a24bf824f2b18f6e7d18921e436ecbf0025cf31c53bbe60771356022eb18b88e3af0c7804430f0d2adb0e2b43e4207184038d98388c1906e633b13955c487f653e0528ffcb19490218e616572db7cc8b599007248a53fdd49f66761a9ea453d4677938d94001407ec0c0524dca168b375c8faf9231200054673b6ae7dc19394809c4c3b49e68d78940f4ea1efabb60deb553eaf9194807545825b41a1ccd1e459197750b76183ebf61b9fa87f112b33bf904750c8617ef69dc63779f96906a06e71cbcf1684f1cd8d9df86d66d56978622db7abc72529d4649187ebf03d531d670c40ceaa2d953d8e13c9ee3e104f53ae4dc610dc2721c233d09f5a1b1810f14a7d07635b6fda4b10ec5e8cbe8af242fff2640872aaba0d04f73d635b9b957abde1f29db30d99998adbf86028f210862519fe5926793525a3919aa7c310865d0258cf3f4db2da751c170ab531b8f32d2c82eab4d9953c2ce63512d0194445981d75ad5e2c070ca833f97e72d87b662660d7ee0cc54ada90326482e086f233dad05c0b5b345a25836c2d154684ba3fe0be51963f4bdfcc7ed2117a4ced6bafebeb8c5e4107e04bd87093e590ed6381fa1a28e6711e037082dfa00516275890e70d6a02060a7251ff57f0e8feb6b16b8ec64fe2994ab870f21f965a91cf3e550af3f4bfa192a2ed61e00e4354959b6f0f41e3fdf3b1d454d1ec4feb503a7df3ea2fe04f6a3402847e09ee500c99ead6eb395b881f079fb08ac139907641c49a5825d376ba9e43245279d4187831fc19940c74640e5a5988271b8a51c5d1907c69f3fba5309e1385486d6989ddef6e9bc96473d4440780c9c0a161e014c5aebb7e1858bd2e7c4b042c35b0fef97d2964c3035db9c7fce3e0484804d77fd3e4c9c9ea580d0f014a565fe6667755df874c0024164e804b330771588d708e8be72ddd1af254f358ca897c85d46ffb8a9fe043249f62425792cf689d915c694ef12140f2beedee97a0664e3c701b038f2a57fffa8939d0b1893807b902e9310f0bb460a57fbdaade9169b8102a589ac53456096d2d732dc3e16bca86e90f9dcac9474db72e4269c1aa7809b9ece49897ff94d8dae2e6934b56a1501639d347a355107ea1bd5a8973761f685311a87f72a08a36782841fbf8777b2aef03ea65e1ac9addbc9e63dfc58120d53184664d4c93be4364f51fbef817bd1ae8cc4c4d24b382d1beca8320a1d0cfac1d5e8f7ce55bf45b9694fd9241971ab17f8ba3d6578dbc9090a45c3e49785aad41c1e5db2a88a29af586df02b9b511abd789aa834e15314870f4ae950d1cbb3048f4aaca24a743e7b7a6341d828620b2dc09d247877328b9d80971646a13f8dcb1c0e60b51129a228a51a779140ec4058d388d17f3e984f53224aa484482e46cc926388c407bb0ac1846c9668044143e4bf4332e966854595882e0cf2b17938bc8f20aa7f7b0a6e3ec7d19db9778178f4d3e648725ff245ad8ed80e9b7de27ada147f57d8f1ef6ad4b694aa84ba634d7225f00b3bbe44b7e7260529a6383558a053c70f13928e4cd56466b15ac5900f097829f6a716e847e7cdbc478d1e8aba2f3c209607d4373e5819965f8e37d4d75f2922350f008b471a5b37da5111851aec5b50b2eab89157e54eba4a59f5532fd12c2fb493ff84791f293525a729916f53e4522800a00c6c194b460d96bedf78e2ee066050af95c77e0a249ef0b435d62546a2e923c94f74fa35430412bb0280906985842b0903a807d8d04437dbd4aa055afe31ddb4a51b19142e2906183c758df76bf1d0a68b8264d78918df6bf42009c3c2120d683b1ac7aa0d1620c96ac7aa0013be8a34f027908f22f8dc3a8f626d38d554c700484baa34e415861de8fb03278c6310f0650ea27e9c3ed917aefb4820a0fc7f27860f8cab7359db682c126f68eefd3282253e312e0bfb1f80e3496eeda73c3e6281ef9f59a3779626e2e3ba4f0fb13d23e57c79562f78b0e4a01f7e43e51ed17257f940bcd8b0835c44b5c35354533d834bd02fc539fc38c67363b136d796cf42d918d910b2e3038a9a650f05722dde3eb26414bb18f1990a431410f9db810cd297a5f47395951e26554b099c0a9a93bfff5c47708065fa2cbe37af2f0f90e3c36eae2cedcef28bd61799cd32e219f377cc03e749a04d34a055c6542fd154e8ca2de8e570a0e40ed3082c7a7b333e9dcb5713b77f11c26135e1687196724d76414dcfd3187df7f85add5eec053e90eb94e8494a4090bcb5cabfb363561a14f49c66081cc607aeed977c02b88a3e901da7b384f922cacbde0ee11255ce2f16b4ad3468a8b5f397c07d0f743f461cd494c341dbc467dc6921f6b0af5eda64f4c1b33cf24cae6a3213e51575a9683e6a6c6bfea0c78264fc7edeb6d646dbd1213475232fa41dfa17f8509c14f855fe6d5bfacb3d6b1163fd5ef7ebd17b73f33862d1d6312fb27df1c122c63e3985a8194aff8e39d58e1797aa658395cc4168e9b9ebc3877fcd4d8a6926ca30732a53f642659956026e6020d98674fdd4f9e2c952fc184c08501b113c4eb02c4e93149f9f29808387d997f30d6ef2b8ed9a1b1e5594f2183ffc72b68260bf96235f885c276c96d09f16c2ea24d737c4a9f9e44e1a98e9cf173257c7a15931577d94eb3bb4fadf9c0af6cd9018beeff4ddab86cc0860fbd8ef702466fbb5348e9c442bbb858bd97251931e9940471091cde119b542fb52f2e009c92afbad61a42fb44e1eaba75331bb84c5cea8fb10028350cefa8ddc929c6b79288c4ccfe96f37c5ac7a6d12f7f7cba4fc4e68da056b4814a3274eac3035a8e73c1df7865eb2622c48552e414efb9fffe19e0df03baabc9172718ada79b6f130f44f755eabd56cb3513de43bc32112133bf3b8835805c002b460cee6c9b1a9b18f31c5c00ea4a80f42ea56a00f3e6cabac83c8902cd2fcdceff849bb428e45c86583905529cc0027db7b6d7fee7dab04f5478c5560d15aca9a34fe42323472f0e20db5bed39cb36175ce6a14c84e7ba01d6d3671e60bb592fe4ae2933219fc7451b04decc37152848706034a3797e1c2dfc2c2a828b48a5fabddf43419cd0004394f2aea70f39b22ecc414c0b3c0923248527fe229e5d97840aa10780abeef3b3053fb476780ead94a09c8816e36a88256e492fb5829115e4f2af40e6fb41b8359cf86a6c1cd4c481a310995ee241ffb99958a2d9ab84a61a7a962b112561398c440b1226744103cf2f3e327b6f6dacf3bc0b408d8ea4f709e91f7f8079fdc8b588cdc38a57efc812b99dcee57e2ee86a8aa7cf7e17444ec19720e5fa6fa7528f82089ac427867011cb22c99c546857247db888558452bbd9a223c341597712a710ee8ddee471aa9abe1254cf03ac10c06de6e6adaeaec1561d507c3836bf0cf2590df6ce0b78c6769156e6ddbb280042363f58b1497b994a6ce200d100227585960ef06e6067c1691b7a20b31f6e627b9b8154a71f5e92b0ac36cba36d344b137c7f8b5647c2aa79807550a905fd1f722b403d887fc47edd7b32a1065d458fd493798f04a32724a8b0b245e14814e0415dab40632dd44bac5221246b10ec2602afd52073d013a93cd469d68dd22356d350e2b60017ff6b0c10b18b0b75613d1f6c3171094b94be51138234d32342f3c0293f4e3fb6cc0c42320b75eeedcb331c80c0505381f044b59533da750535d829be40325943f128fe2d4c961964c2e31c2cd153f480fbb11fe37b087cb3ee1fed396f02f87e4c519198d95ecc2f4d0dcc70afc72a4598975df11167c8430719ab9994889ea1e07bac69d82ea219dd4d4de8d67a63b499cb95da99cb11cefb815747fcf05e173951eba05683449fa2dec5ebe4cfac6b41ed5f933d89c3a7bda3a1b700ab5c1a07dc00d2d4a734935f8156fe1c3578f620f58c20ca7343876bbf34b6fdeb928309fa831b89564dd410b482855610825d506ac04f1de2333b099910e42449c8f8af664d300f4131878e451d2dd8233e9ef84aa916cd8d7f7712a5a3f233c2ac4331bf0fc11440f06869b33e00b355424fd00fbff90d3f08e43081934e2632b737bb74070984903eecd4621dcd19f2e94d319f030b4a1b5703ab88e74cc52744100630418110da978e3ef2d2339a6d664e9f25171e7551c2b1a4484eedc9a186ba656800a44a39d26f5a0fad78f4e699117eb4db6348f861e302f751f30040d2c9fced5c8fb6519dc31ab991060ca78242220d465a2d8217cb1f7a5a2ae4759c3220cabcb80ca870c594be3819098d16c000fb7de95d3cdfbd1595939df3c3fd459ea8495c7f9d9ca9ecd894c884cedb9cc238cd01c19ad7d09c837e8bc1a025ad839d052235a3b9cd4cb0228b1123aea94b18c1299fd9cf60e66ad5e34aaa7d10fb1701e995296be5511cf6ad0849d7667d8c99769cfdde40544744d586988a2c45cc4332d02540453c7c64965a0e1c683005ad53a005f40baf809a16c82ba93f5f0837f823bb2776ca35381c296c44a0f70425be48c61c529a8d6827bc119156901f8cbfefb6b1a303848eaab90977c53fc3a379ff6aa33c54f0c5c1e0b0a72deacaa74a821b5a8be4b492adf94ea82bdabb0ed0a1903dc4fb5eca36a9213d60d1f23d61e7727ca9550e2a7d0a5cfbd2d98d034525b43a840fb8d32de8702e3c80f4e545f4f58dba177f1e0b0cdda42ebfe70167ba68d30a10a58bbf4288490f2c242591ed4fa36f4364682391e11f304c94a239e85861068514472a3640d3d351484fe0719a84f0e0d67a156b5be682c658eb440d7daa43d99abe4a93103ab99783679797ed62484702611fdd9a81d6648100f44144939f3a6f7e29035e6324afe0a2eeb2a7b5047ef326d50bc635db150a099b787de2e76cab0019554164ceb747d7f90fcd2485bb7f9e0646b902815a214a5a0319d9d88469518d6121e87ef3a98290fac4a81a5b5c004ba716509147c5c6e96f58a5290aea51d13a0332aa9574185be4fa07fd7979c759c7c1743f044e2e470007afbf4e10e81bc010cb3fff06af3ee771c47b581fee0b5a05edbfd762fb214a015219a358468b14e9f940d02b633ea36b12515909c785356aa6648e31020b7735615ece73b02bd75fca6ae942d9629c59c43de9436e67662b7bed21ff17ffdc65a8a776b4e9e39fa29ceaa8a8846918718c2999e0a3dc5bc7dbd898b140e667fb604d02335b4e3081de03517d620e3f404daec7efc58892408bfaf3127a02d3492d43deff4f5e9720f87d4d6ff0b2b3288cf1d8ec44b7dbf7be7412372b1f162dac71ed7b60b76061515011fd0a6a0af41ec1c79118577c698a6aa966e8a15067df8aab7d6d73719931a79e5192a07b9c7ab00875e28929288ea26d7d50f5140a8a2314317bef16f30c262ce0b96ece38e37fa5d1a174cc4de252392e746af63feae6424c3bc34f91638d46cbdbe960e7ab0d80b00e6231049531934c8fc26603afa6df8deaafa9c330e73d532117d14e2acc6ccab7348a0cd79f56f7d5192b758cf95c7c17fa6434661ba0d124471f5319a6788ce5ad5fcc8af8fb0743f65ee3c896d431062e4ca6f478f28ad8847e1bf11fa0a6d192a65840de7b4da4b3d0ac3289688b5e1b8d0178f71b2ef19a7773ba8f9fd77ba670b3897b31841a325a6e55d536c1d623be00465a6e005f032243003ca16debdd72b79b10e93c9f8db78db13a0873592e01fd3d4cb3f1e4b5b876928b5e21af51b9808f4b05596048b51ab7d270ae31df5c6420523534c950a6c8da2f7a654ab12e4a46c4d47a531b21ce75a90b7eaa26023d5254874b21c875a785414cfde32cae2df0d64b6f6951615fd456a7a70634b806a4bf4e156a8b5819fcb94c22c949d106a222b94332c99cc918143f6d083e2d85c553c6e66afd0285d65bea3f5ca31f0945719a190dac6011a3d6c8822632b380163b7a33c21dfbde73873a6267549f0b7be35857ac052ab16a24378791aab04a823c5c09f08c54924169ec7300c23433a201421772a1290fe00a49a43d0ea6c3e1411307b11ecc21194b9df1c7bbb9b7e1a7f6a826af6d76ae35ffde2f2f6255bb1c71576d1530c744ba01e3bf5edd13a705f5270392a37ec6567e18cb03e4d1a81cf1318e1c40792710b59df4315d01073c1c3901ea6ff1f50e6ce67eaff148408e02c1cedd1cbd3eccca5e3d2d828cb66cdb18a85658fda0740b77500e3e698212351c1be6f268f526c602608a0b704dee0a17ab6c8b633d88a31a667db276f289b602c7eb01e56cb4d3e65f5f293e69e52b2284c759dd129ff73a28a046a607d6ca110430f0e54d9c69b7d5630b0264e8f9a973348c8e18eb4c6779d886a912ed04d30ebfd62ee09006b39bd0b03b58076311c8ae4280f660e30f7d08206a818fb9b121fc9e78f5318456b7b5a82bb98f4551080938df007abdea52a80e42245ce4112cc66d239fcfc8cdf8a7cd97e69a37cd360044e05bc7a6766cd8109507f5bf22c7955516205344943be7ab60507488cf5a3eef09b76127a0848fe0e9bf867264889f690b6a6c4222585d0c10d0c6284af135c727ce36ca09c35a433276c222ee923081c29938619350d927269e337c4c4920e4b2cb364af6194acdd5ba82f3b8150ec5be781e00405e1f44182d26306aaef06725a1bf0d16bb43932bfcf8e10db02ebb309e351f105ec0859a0df87d2f17489a8c0e4382ce19593cffad00881577130d836b0a3cf14957f92a22780bed73a46152e67f9610417c8ef60a223ca386921ac127545ac2553a21a02b1e0f876808c4298d86264b37a1c3c189a96f87e25dd4f5eb0c349bd51149e29dd5334042053eadede323844f62823ab14253fe7bdcc5b09ee09bd0b6222499ae3997325fc81dcc4a46cc1c91dc8697eacb8e4292f4781c2eb7e3196cabaf3ead29410cdf1d61bd2b5da654bf45ee9917ae47f864fb55a30db29a65c179483c2765683876a30c65ee96221a627b77750969314de2f2ce8f5eab32cc793d5df880771e31dd8b81c09370cbd23c1e2e859a8d0750355e77f2201d1b41d99d3e6b16b579861a93ed66fbe496e7d06472d2fe736f557f8d10319d1bfa933f69fdd385a0c967f58628f24721dffd75af13b4f57f2f5e01eafb7bd62701fa557bfdbe9253f632d7808f8e489e77486995bd9da23affb1f9ce121c8c3d6c9bc096111bf5f499328b11aa070a30dfcb14ae8d831a72f75c9ff6ac7ddbe5007780047387e1d2230307f5ebceeea5d85af17d2228b02786c8c5ff3d3c6eaa40a60f746b7f886f84dda05d10fd640fe0ff573bedbea0d09a5ec36908f02b397a949cdd5ab00429a8cd7cf990b012d3f326850b3a81658f7d85652ac023e49e6b37d90cc407f2a86705d2eb44afb5f5cbd524845f5f939975efcb410a6ed45fb23fa80b475bba83dd5ac48c59fba6b00f3f9710cd557f70f662bf94547ceacb4fac6385e4651345cb44d7f4e872439b1875ed929804940bcc50cefefa7ed1d8f9ce19fbeef96784aa7087438c27badc2e9ce8970c77d614668048e5a5607f1fd3546fd1f7e58a3051b95c38405cfdee28f536072a3d62009503b242b2119ca0d70441d6da104b0adac65f1b12b38b11a5e676ca6e52394c34c31838dbc927e8646c1f04ec6b834412a160e3263f0f5c42cd30fa601440fcba744ca2059cd828a7916540f5c52102025bdfb0dcefb1e84d61835644c556df2e4a880336fd644a934d69ea07fb11db0c9d104fcd02f96ef9ab02feec167e1be8132cd32f76cbe4150d581d92ae04baea88b147d2b3399b2b6b5d650bd80f13361d23d27a54d50d22cdba956dc856b52503d8be0b6147b393fe4644f4c40ec743a2779e709ecb7d98147048d01f557c58ed114b8ec1a4ad64a36b99277c153ff37d6a01c233b3a3f53ac7ea898d510a90bc9e93b2a582f70aee9eedc10a1f321780f55e2436032d1484f76e198a408c47ac9597cfbecb24d5d24db9e14bb4cd104b113386f9b6fee01add5cda1579d002c7b11b566327d3d3826ced64db0c8adc9e229d7b332664c252126e77bb973109cd52f41174b7f67e1ed782622ff81a840e7214890c3707d02ee000672ea1cf9c9d01b41733dbe1d4cc10fc2e6ede5149a1bfe17c64e024364932b0b0a36a1df1856331962e24527386c5027f5a3dd48462418e1bbdf14cb8841e26395ed179b607b625d6e755ffaf7d8f99b8a36e0b7af46e6bea4ca0f2983f49eab688b7cc55c59b0f59fe9f7b7d491198720b5759b4cd2e86d647393da3b08147d14f5fbb36fdfe5a666c8423c265aa09aa59134b5654983d1b15a56de2698b5f7c527d16c8650f525735644e5089e73df7e03bc178d68202491cac29c880e3c554e74cb6a327f316fa7726f18993436d4cfb0776884ac56fa78eb56cc633e24c550c2fdf60cb389eae14651dda77f58c04f40ce9aceb8fbe0f09b699a3f10254f6e86a7cd3aa30160f0a188ac4ef27e935e8944f3eacdb73e83cc2de3834b951fd4c4aa852c61381cb3f536440646135fc73a04384aea4c0c6ffdc27e358402933ccac26f4417197495aea9676f8f8a48e455a3adb9aa7471f5b68f4f50cc899e0d1a8e0a338c3253761236fe9bda9bda4df3879439c1802ec403d89dbf05e27a4d411643cb1893f97b54567d90828660bc3179bfa90e537013659b968b87cee07211b330e138d0a057154970dcb3ad453efc5d3bed0420835401a444632c7d50ba74ea928b579e7483d3e2086d2d44a12b27aa9683eb9c632903f3c6c41e4484136b359b577492c6b269afcc506a5f9410fd708e92a708198ecd2a2fc97a2f234e496671ca1014239523bbfa6fb0006fa1c801ae68df4d952870f172879da16e5be91eca275116fb7b936267584e56a9ab8999ecef10c12bef3e4f24d2aee47757a392ab6682a119f50dc59a6d911b106d421803c9afd8e346aef54f068bebfb21ad4f4c41c91c1f5e33d1f22be3f429d57d666b7843033c7068f2197fcf939d5e683c496ffa7ad0566a0008cb2c62dd3badd050291f7c885da06713d77691ba147831e3570411c7fcc66c152910d36b6147097306c0ce42a4897c4048b37adc2a36297ff9c52c51a9c9066fa247979da761264cd2050680ab924073d571632c8bb7dc08a0be337d0a2ce22f5a8b632bd8b5d1bc0ccbc0b4016920f4db0e529ccf4192fc6433aea758ae2c99ab9682041321731c19856be635e569c305fce05316b6a4a47e776c461604800766a0e19f91cc0fef949af04f69c8a56a0ffbdc8ea6b299a28e10902d686a19f739e4db7c0fb529609dc16be0855598a12fe1b41a7ed1d8539d6936a635035cb09b013a680d0c6f2b5410c475017bfda5bad529743461aed414f81bf97f8b13c160fbc6f612628448e5604a306ea0388520eb640cbcd63375ffdd2b09269eb73636fce8b681cb57024b01fd61918b9fc4c06f3f10876c6c8e1414c1acdf78dfc98ea109b0e1fe34e863da6460bbd8c53472cc3d4837fb7300eaf9cede3569281b2e8cf032e3a2ed3951995862143ef93f7a1d04eb187bb3e6fecd35b03a9a4044f92e29f163142ed0d53f288643a564429a3fbd8a0a5f090fa93e32339146a7fc31a64f12fae24e4c6fc58d17d67dbdd5fb8c0109514f877481f0e8d10e98a18e0e1f90acb7bf98de413c97b461c19dafcc7519f50d173e15b94a1bc22f04239d7ad48c748715ab83c2c664732b3ea880afdbaa93642607a868a0eb3633fc41c07b86efb4f5660cc7a8c8fc19c792b7d5e52453c32e052afc57e8d2cde952c267f43c12b4d3c79186235ba2a7a0d9d26e88d1eb024f608740ac86cee0207423cfaf41398ce4a71f6b5acc758462508d37c20799d1ed3a010865ab27eaea59f51142774eb9b04ba095034a68ec9d48030225de2ecedad229be756af29d6740cc31841c00484f39c9c0e398f6c190a4d0bdde336b77e3fae1a0bd7ba220322a5eafa34ca975b9d66ddb3d86a84ccdcffcb2a84d1d2aadeec34bcd632bb5fbc1443428dd0506e2ed885513244f262751a8374dc26fcf8d9b253b14e304f86c48e14a9c4003122d22fb5216e77bf44aa0c62dc2d8ebabe4eb7ec43e4edb356833e8dcf5aabce1e9d6203ddd8e3a2d9f9dbb4eebe1c9b275fe75895987db92c54c28ccb8f588b65f2afb827c8abe6f8e55debbfb280c1b68d5de113c52b3768381f94b77514d4d794a39dfae81bc1a28bf286586645be53108b74b6fa295b597b738ab06a0fc0bfc505b7580d7dc5e847e2c0cdcdae1c7b141883e8bed520e200c29189db54bcc0271dd5b0ae40cdc7a9c2b7325cf4353b318c3b1bc8fba0b42f86d80ce2ba8603255f64694156184be9261faf04450d3d6a967696f8cd9710cf754b4c74b825f6a42a9ac73ea6d7ec457921de3d1aebb0757a9be750db92b00f5e1891e88f6b6a4c7d29e3af57cd6c0790bccb3469bb009d0374ea31258d4f581be71df76c0c382d3ba98288ad5aff5591d7feb6e55722208f70af0a02a8e1c0b7e63fe59bcdb50521234df93b7ec04de003ef87b4a2567a9d0c04358905a32d02755169ce2ee1785115c1af92cad152913c0b05c192e7e4b3d78c53a14ebd5f6ce0a09220ece28abf2273ef2d0dc5eb7d83acdf2da069c33157f9578302d86b642208e254c81d988af1426482a8191bbc8d6ae4e7a699e440ad967659bc553a352f8c4251e8797ed5c0ef4856f8880d84c7c769b81b082e682ce2c8115840940784f5a1050c2c7beb57cde951feee6c66ac367cc84cd7ac2ccec8480c6e6df9e73352261311133fc8ebb23c09e7fb2c6270ab77dac4782d96108a67ec59ffd32e8939f62d006d24ca8a371475299f377d3652f8ae2bb7397cb5cb78f29893386d8480a086ddeb176be8b67b1532b03085d148a5d5f20bf42aa84d2e24ec455fc33cce8f1f28c86d40a236591b32a7e71b846533a650a28707743f8fa64c5e7fd1356e342fb2993b0afca8a22ee34aca15f5e4f84fb54cd81e57593ad34470aafd5ddef9bc883d21e9a679fe6d2bb03917883b3c3d6d5adfd27087d77c3c803c119c746837da3f233bc8034c71a3ea95345855c3aca315f4deb1be807afa9983340dbead683ff9f7d3dd7f3cc815c74c0a210d2e07804ce9c4c6c46b2e1265ee30b68d6b7df6773f7de3f11f42d7b372621c68265705c741f1142d2b6bedbd58bf8b4ac4b8b4333685653c3758089a6e2a342de63ba7db9fe72315ff754a7ff721c49b6b3f158bcaf1805988dd4bb1116fc6182d823b7366c58b0b843f7f03cf68e931bd491e3b1f38c903b88b6056ad2ff524fb947f9bb2d2f48f5dc0773699e7004757df1b25c25f0692370c94238ce7b9804c66c3a01adcc48852180f1454c3cb846a65b3a1e60dc46bc9641f2ab3bd7ddbfe2902b38eb3cc4329e8832103a427c3173155378bfc7bde9b8eb0bcf2441def5807b91ca8b76257aadadc0b1c58e80ccf5b80a2445f3ac147039a24baef8cded35100e387813a52354fe58831e4224f89363b249e41e35374d59c88280b0e7538c077cf1636dba4234fdcc1eb4722da167ed86e99583cb9ca81cac9ef707823dda5ee9c6552a04420a7203fb68d673f53fe581ddee5bb6bbb3556bfd19fa5a59a0fed65ac6eac54914adf58ddccc0adb8790ba2defc7901f30f9d103d4886a125bc7252976af94d38464b7e5a4f581bdc8e00dde0e6a9112a23ea5158f748c3d4062041265890dfa708c10dc74ca00883a7722a936285bef48713c1636d79284e6d659b3cb5e2be3c85db62f8e5a55e7f158ae345fa1c35471ea1f1549d5c7b3406620a8a6f57b81ead2ff712d0ba1a222fc127e03c924c08075a381ec9569b35173b20696dbc352928b4cb161133cd76415998d0036ac18d729a3849d6b0a2aadadaa0c6327dc7a52f4de3109164147bfe058b17a739c804224c9863ec5cac3c43159f44c1ec4a6c2041fd9e04106ed66307b59b0677af5e310fcc2a4e422d10c5d2a2f23f68d886f043897947eb763576e62c7eb19cdd7a13f3f4d89dc38b91ee775428dd59e75122355822ae1911cc0432f1b9d6b7d2701a2cd4d021bf434007fe0cf0ca1aae1a0c860acc270d9af1c0d57b255697a1683d9418b2938255f3b025eb16bb25f51600396ecf8f8deb4aa4f642adfd0e62451fed213947e1d7a952dd0d7bf21896a758fb4738d311f5fa326bb158a1598b046d33b6336bd9ee16bfa4da5194ada978c2019d1869be930255555df21b6cf05d2b141e4b8691f7d20c5954c5a25f21410c822dd3c6a079cd1b6172934c0707e4ea234d8a46ae9724cd05993b5d453392b14eac94d90d49add399b107b4aedc7b5fb0995097a7a8f5a0384c70ccf5f8f256e832606a39fc13312097dcdd5d1ad5b71f65579ef8d93abc3bc0c7c49dba964ec4626858668a807483a009beac43684ba2edbe2b92b30ee45a2db31af1f1a9328d7d635a4e421ca717acb5c67cde5313cb929368d7104aede24764f4f494edc506a2d654a0529e02fd49d8f2f2addbbcb5967c1294a17ca8d6d08541c34d87322795fa45e9f34d71496d807e1e7ba6e28bb28391c8d924ea8585626d094d8e8ba7a6b5e42d0869f5b63b0811feb9d9a3ee530ef903c8d9669412d7cd83d378c3fb40921c563f03c05b0b6ec93947ba5b0dc0ab6e1a6cab682880005ef3016895275dea3e031f96983ac83e0ef053ff7613f0443ace576be6958f13fe4bd435d09e3927c9ac0f1fee7c1bce2aa2c6fdd7c4d95099a286d4ee91aba45d5f920edc3e990647f9a4558c3aa94bdd970545d63be9e84e0a9d177f2735697f4d2a5c7753e8421f7630f6a26ea18bb2044c6d2ff19cae54e927ec9066c814e9a89a43cb843b961d46987c35e4fc0ec1d46c9093341dd4fd8dcf7766aff52582a1beae30cea7ac32c3db9e1b9d2a75627706dc059dea859caa4221da6749256fc7f060e6846f17a0a10454918a2b1c8dba0f001bc75f760c5f3998911ff092950b8a64181c0c082f205715a24c6e50aa0c7bcf636ffba0321c6360a19894171421f8f1456167ea6375b58454d66d5ffde963dde99827c846df8179eca366268c5b9d482dce779e1040a889a7d96320cb1fd34cbf6d635f0bb699105367365408cba7c529535600add81aa13933f3a8f8d19613cafe869549aaedce6676056742a04ac15daf665d47d24a675682be10f9106ca2fc27678671ac20fcff616b3a73aa9c6f20700da0ce3eabb74687e46d8e7a77c40e2e574a8f1b2ac978c85b67ef0773e82193d26773fc3abbe9efe4f20452ea9a0849d791b7eb4abab1883d576655e2ac26c065cd4d64494d32783dca43e89cfffb7509bce2a2fc382b833de5c895a502fabfc1d976c18b1a3ef61adbcf7fd9ba61475b5dfc864fea5009d6fc554447caa83c9c89a90523430a30fbca64b6723aab45e58eeef2bfae51af39117dec40596ade92a1dc01c5a40d8b99d82d9287c3993c46c64418921245e75ec8f5f1792e39237bcf2f11dc9da7b659d85e35563851537dceb323bd4d59bf5a1b305bf4f1ce38eea0e724a265efa9b5b31f3ecdb37f47aea80301864b25502b6c708c2170f89ef790a79c3a9e97df843f0426d4080539ef5d5ee5de187bc824796a48628d0d9992e7fb9a25634d66ba1f1ba2597b0c6a1a8c3a225d9473988e1f8ea182189f2e82e49c983c086e5b3f8bd1122b06986c616fea7f194d29c37e2ce6f75f4de168418af083491a08498fa2448435432656023218764359d82df2e3ce570ab61d86c0eaf3b7fa68f848e337b79d3b7019878e29cdc7fb22b66f45de9edb48539427f24adeb7dbc8057a5854dfb1fcb79d086fa7b939e4c8ffce09a4148d6a6dfb017d345f82de1f8d40192964b3d42e687e63926276a0b1d53a143d1ae1317c0d8ca4e69712e3c34c319ce45c2efd34c46b3c4f4316c21f66e5fd94ba000cd3594b501fe0471f1d74797a6c37fd6e0c6e9a2f0fef63fc76f0fc4355c269c9347e5b112977eb19ea5a2e976cc9431458ba4040e341f87f2de42e3143798e7a05e878f564a026271117e00c741decae67c140b48c4ec8841a69a1d54d3c07059018cdee036700f01fba4299a367948f953a4bb6407ef53be9a2224913b4b4a4d54923300c25c59fcb18cd6b488f032ef06f7ed627c3d9bb185f8006281d2f3e504ba261a45a2cb5afbe28e48afda0a2bc6e5b4d7c3638ea875fe01afc292ee172d0c0e386b89184bab21e5c4e27affd68a81424b9140440c012ec38516793c523105ca27c0d9d588856352940109ebe2b13392bf388965c2b516f57dec035a898520ed7414db1d3fc425c5eddf574f4d389844b87a9c104012e1ee08a8e114d017edc13de9255736ddb69f023de24087550da540120ed5b3651e777728ade0f814f25a2dd325be2a21ff5e0cd30a3d93d74ca32b697347cb8d945e945a28626395b31f69bc7c0dab07e6b7d38f85ae1c703adcbf494292051d38f80ddc93a8cb968802a6d3f5fbf317f48cfc4e9ab7388fa01649cbc1464bd11527e4115eb2d72a3cda5798ce16686e58f0b2095c6cf4fdb4ebfc566592e426ba65c50058659333f27bc6ae88a7a005cc935e8ff6d204c1be8bc3ee34010e35620b2661e42889cb611f71e629ff747d446c06d36f9f9dd9e0c74ec78e2fbc2a73b43dc1ec1cfe79204ba334041c1788270e72db20bdd94af73f9c3d462527af03e47f77a0a7d6e76207a679e3bf0f68bb29e4c3cdfd3f00b35958795c474a96623e5959c0abe5d2b5e8dc6ec462138eb3e7ae573b0f370f24fa93032ee1ef8a74f0ea16136e7bcbb6ca309b5c01092fda8344a441b7e95a40c19084e33a5d9c57d607df72258a4323672ec9214ba1306812bf71860ca088c823ff667d34a0521f874d42e127bdbc308313896f03baa58934daec9dd402a0f2d8d9e8f599d7e8e70bea3e2b5bdbc5205c543efc1642ce0d9eed950674c4c7da956af342338b43155384734fcf32444939b72b244f82429b987b153a46f85a7d6074216630c5faa37c43eb72c77d8bba1b68c4816f4ab1e93d52567783aa8dea657a48aa8a432f62754ae3713ee978e67a56ab39ad60f66f690059d5d5012e39b4a1d89ca90640274c02cd442a7c1e255d5f4f9085116e3880970a4c332d072f9a1fceb20e8c95c38c4e464054bd54aeb3140b20be498e5f17828770ee877b7c8ac79bb66ff207b4930d594ea395fabcf66b0a732528792df0993415007d62a76aae583616a597d1d5dc5f76d321d5fe1c9214113064928a2f8e5f8b561e5bdd7e5f1600a7af1740b72ac017cafd4e229c67530a0c2dfa8812daec0c6cd9385bfceaf139a978b2ba8279c542d76f649320949d5e207823ca46e5c74d3b4716d4ba24bcd2e453fbdd1ede7b4a975186ac588de6fc2269915c5800c9ba311d1eec2892297934c9417c29f679ec99788451d016980a847c2522e6e20d4bb809fb842f6a090cdd0b3df014d0eccd7faad9bd635852687cde0283587a6ee3fae2964957413ee7a590cbf1da4e01e0ac66f98667e75a1bce60bbd1d6c49769ce6085af284d245c9ee5f6f162c6e7fb8ec3ad71ce20a04d97fab95898e5fed0c97674e518202cc3f8be02e3178bfc7ebe5a2d3d60aacde8de6cc348ee4d0b1aec406a417938597702182c5660598b07b9e56ca3c61d76a2c482ca9878aefb510326ae9ca1411ff25687cf86c56e3d4943c3cc4b7e09ea688dd7bea039cc6cf5d0ef77b135d0a861cc2b5e3f1a9bc7b57325d64ab7f6de0e7008f3fb6bd7daf8e80e7cb8795947b99d049a5c2beee63d8b13ce29c7c4ab9d1278cfc08c31293ba85c0a67658341ae12bf4066f54f367c0906e4fe1bc1193016d74e72177eb0680e8b2d5e5cf1dd96db6642169f96d3351a5c8daa6bd666d5ff705844e1afc63260b2be45d28307a68ef24ef58aedac893361d1a2aa36287d18b2059730d54e867440365e6e1ff6c420bc77b885cc8b7d2a2541ea4fd48688ca7fa18f27dfb03cb7d91546d3cce0a3bb756a5064aeef50cc64952ef0245a3a2101c6332c95f65d805bef3b6645c7d4707be888e6dbd554a5c40c3d97df53bb420d6aab2a1387eb242faceaeacc9f060ef4b319e84dda4eaa8da547d6f985a878301f40e8ee1f64344f5d3230c002e8b45e8ca1f467c4ac49a783da8277d03c27a7f34c5728b1c9adb4800d2bb123f9b38f1bee21ccfb943a39f8fb9ca7b4faf149d7685f7d14a93b412870c6233c2a08f4ce33eb45d94144a8caf8cab28c8d9514eb9ef0a36c4eadc58ca387df13a37860a559cbf6562da6ae132ae63cbe0a70154f2b32be9888369bd8eabf6ef7eded0e3f0e61f5a76e99cd8871c10c113a6f810c5083513d9e65d57ca775b9abb44640b5d09a477235a86e1299f10efb8176549a8d8a4acf15c715fe1e5a4f52f758493dabf743e1d49c9082784101aec0eb44439a0820d1d6dfda45f3f424062e39a881d68c8570fc05bc64b9178722f15fd041bcf23489d41e323ead5686c6e712cd748ef5cdff878f700cc020cda431a1f7b89ae0fc2c6bd71abfca9390ac2b3e82105ddf246118881c2f7998bf063fa6a1ddb4db5e727523924766ca2946a5691e73a57c8f34c8cabda14f1d17fd8c13ee602e5eab54c3c6db532e8062061d861a6a135c357e0cb10c2483d452fc3f8e0d2b04701b80691914c48fd019ec3b2e47960d5264819cc7fe6f101868e9f278280a3cb147ade148b619b615c3538f064e00589257ccc581083aa0218174f15b0f8989dba658cd5a8892f3a890520d2c278ebc2c1130b4ce9145281ecc5238837adcf8f9c9e1000126e5dd6c69e16ce3ab8f13dbf78bbc84fc4aeed3a5d192fedb05ef9f258711374a3c3d3ca1c2b65bf2750bcffa33d61c81d5406fec0a6cc3dce28df6db60c558196015a3b8eb84e3dbde0f0d1c0de780c5cbe0a5bdbe3f614c63fff6e0ff76c353c61d0fd392a4e9b3684644f221a4ae22e79bf36bab23b53e15f572daa69f63cc3517ccca2398398dbd1dc858f31b48ec2dc710f7d5fe431934ae4b1180c16aa05d6915c7c22e905762c2264ec123d14022a1b7d19cb16b368543f274674199252ebb709193fc2978e74f2d2a8f44e5c20fb996976ea442c349bb7ff76b0353071c0a8c4874fca1e5e34b73298f9189ecb0a12794f89b5edd0441f2f5878ba608f97ffa5b55e2eb7644861bb032a6dc77ac3868fe94eb5cacb1affd2a8dfdf3de835c4649752adbf8af261e73e9645c1aba71aacefa801996eba7193d308f5df30740d9d3a0f2465f430133d8cb1d9318e021c83265bcb03da17808b914909cc60397436929c55009461829054a8c336e93931d60da51745d82e44a3fec5e55408d050e4223430f163c610b3e53bb12520366e4cc172befa646cdb14573cebd5c00b4e337f375fc8427c3b3c00f7b7688c2fb8f3e8060f216751b882a39b7a5f7af610324fc62f280b0cc57c1f8a3b887ad0c4439b4c00e467bd904c493055c652d25570a4d702046789ff98f534b3630965bb63cd02cd6373a85a3c3b87ce7596539609ea3f0e90aa55cb990e099d60ef078ce36f7ac05f44c48dea9a6117713426303c0b39c04c7978967101eb0134114e24b5425a7d48aacfc999e8e06fc042ea5e30024a1c369d7b0c64219c50f36fa29b756044227da990abb515e6cb21291e9bd7616b66746bef7df7a2066b254228b9d961761d77b20501eae073b080fa9eb6346fbbbb7bded91b5c583b6d73e0909cb4903892908633721f2426c9295ebf556f62e46a10f6808287be70f88db8941812c9740a87b8543b15446c78a67c9344dc011a59d7c6a7f908ba5732722bc1095d6ffa2a3525f706b027ea6ac6404f8653bb403ab83e17591871e4562702030c45df7f1af860041d04225e7b13122bd40895e652145be8f7b80f45520e48c860424e22f8d6f6de3194a2147b863c5d6c038046b1c753c0a71fd5962d5eade20f337933d4c1a6a9d0473648850b09b7b580a043639a3273bcd480625272c872a0cfbebc66c281a5bdd3b97c1e701c48d7a592f800848114bad237895577489ead069b1ad1d0ac76231bb74e2d579ae5aea3318fdc0ab2d60400eac1cfadbfebc5665782759a99afab1c746cde38b0873675e0c9ed6a242c898bb1083d886e5ffb24521ff1b97ea034ece21f967e8af4726a59a446554e4bbd04327f2e5a3663baae698ddecc9aaf9455972469324cdead00c069c20c179b677bfdc3a09639d9c1e59fdb744e229882c5c86fe70f0e66660c441d14cad12222b0948080329c20142c3a49445a1f851c40b0b858f2bfff262c7ef7d9e9321630526816776bee59fec05f3d34998302e18899c3ae15a1014665e833e0ee317b46323591d7175fc7f361ba34641c105db674c4fa3121f053c1362213c699d01ee84f44de63d8e99355076356f094e0e69f6c631845f1779b1d3ad2131560d8cb5535e3195b9476d0c7d86fc8f6f25a8ef0ec85c4c8cd0417d54f8389c8f99f6faf069875f91dc42a76d13e48c0a55482498ee5b269ee722887a1d93eac114e9cc2e77d5bbfab941d15d2b857e154eda0fb379efd148c13fd5785d89822160639206309c160c811465021ca0897d49166c4571a5ee84bb13ee3ff331de57307c1623bdf8c58edad856e05d26cd72dfc51742af5869d8d7e55a9b8553a6962d1b40ecb3bf3852816e8645570380a1baa95cec25950f0376b92107883263511dea06e81b77d9f11b73839700915c573192eb51f55330e037ed55c86cc2147f9170d3c65420a6511d6dca76b31f8a4631ccbcbc24650a1800dccb188df4ba5fd61d6d0bed48a1f46e3ed2656b46d330bfd2c5d788a9269890bdcc6f1d64cd66974acbe92fb57ca1d61f7b042bfd509b56cd92f45a7d5d63c88fda7a051c4d2bb0fbd2efb587c14efd38572fbf4ef61af576ae0502765b99eb610b6cd3c3e6d4c1d9ab97706ed4889939d5b0c440f7f8dd2f91dafa41a59343310e37397885cc46a266f85f09d0dc92065cd6651916898614d5628178d214141ffb6384e523454d2e76b41c62612a69dbd10599d0b748ff00b11efb891a1c7f783109eb7c097169d111774883c9de1c4627577668499cd0c50c5cd22eb4ce5992c698f40dd2a92317151ee85993328561a80c4a6cfcd4f0ce5f663e9cb2b14cc369f6a8bc6004276f78d1193996581ed04238d44e7b2a6a6b9292d2aa25875058a1a603a812c18e8cbd969548f7f606b800e0313fa467c2fec48d1686dd83ece44b369916da006ddb6d7cb1df4342dfbae500595b3c8526cd0c3a071c02f0f7c3938e2dd4f8a360283a2950d0c4cfab174a7b1f8c12c62593001f467f74b7d5481f6ae6fb485ebfba79046ddfbb37f6c417233191c8f07094cd23b20570c828ee12208f260e92743707e7091a35d73918563e771b2a00307d9b2b81780a1b8e03ec7b8dbbc43c68610985c82c542e04ed0bdcf41b6d50d49f0edf3c55662b7ad8d40a0653d7448c3701a74f0c98337c0bcce70de2854543595e8419774989ec3056abf819588db9aa5a98bf164a50aaf068b51381a857ce25751c7d35045a798cd970b0b2a7f12cca593b550cc311491326242fb13c9fcc7d95bd31fb7ab5c97256fb9416b9a86c69786b264630aa1b29fb52dadc30ef4a4b190f1614e234d36affb4d83b663009656e9e4d07ad4b5b9844d4c290b0f0131d9fc102089152da28db33f379f76884b52e68cf7a5d80a664ac0618912e950decf948fc9c19b48fdc1f5cb49423fe719becc0745de74f0d3f6c0d313e4a5218625cefbfbc6fbc91d3ab9afe5571bc3dc4fce3154a4fc91274d442f9040bec5a790501b4ffa336394cb0c255932f19a7f9cd15f63821be22c9790ace9102beff48d6bd1bcdfbafd381d737d027d0650fa960c61bfb54c82bf50451eeaf36378ef3027dc121e64f2b0a49f79d9ba965c57231f9bed5e0c1486c7d8b3324a0513a6002336338e5a4c5fdee733f6dabb9784db62275454afb15602ab1c57313ff9f00424b9fc5bdb64c4e465ec57016622a74dbac8b981bbfbadddaf8716422ce3b7946a7d7d171daf6d5fb537b8ef5ac05badd0bda9f7734bf3baf98449cb92c9023d1f9e847fb33e2f1c46e9caddfe9c9ef9156c80ef373066b188ea659e8ccd2e52b7c7c7f1c45ad71c0248e00f240d65549678bb050dbcdd22013e86a4c2ae722a244baae86264c826f70d55683c53d75f332c8ebeafae01c5d43467142f9d3e708cd71f2525fa31debc3ba0b2b4d7f659a9d22b80dfbb2502b346a61a4b9356fe713cbff8a25e57109f08cffe821ec2a765e345a8d0ae83a40ab2107dae509be0c50e86668efd2b298d1279e1e8647fc2708f177a6d958113c2c33256e78583cb68cc845dcd2e5787356b4c690e28aa71dd611bd59f77dba7916fdb652b6125c6c99d463cabc08f64388940f5ec169785fc1a7a559f03b904e850bc1003620b38330b1863a1a395fa1b2f9d6e5ea37ee84047cfe7868ab8bb77a3428fa4492f04d44faea4d8eb0ee85938677ed0bf594010b0fb4e7dde6a6cf2168f1f4984568315df93fc4eace758339c8e632d0f46bbad7c7ed1d0946d46f28c8b32f46319d1b4edcf42238b3cb778fc1dc7c9b02e929b12f1a152f6b8d49d4a6b08f53462a79380610a3f3ab07d92d021c598273a6bc6d3e8834682325a4e76cc44b7c12b3a4ee2ef499694e7b0007d72be466cb051df9583dbd29777470b5f2badddb24a4b958a0648d7cf8049781fd564f41ab847458a65d3ffbf49cf4b9a6745a8bba7549a61c9d24d2b920c5d6769f2cd3314197a4ddd45b71e5390aed7d38798b7c4f64a643ec90d0a416fa55ee6d7d0db205d02abf7c240e9e1fee85d70133d96d243f6e86d4accec1a7a18243dd81932e334a294230db10e7a9130278d0641982594867ea8f3305ab59249587a93a15e649fc68e700b3d41fc9ca8ecdda26d5635306ce4b293674e1f3d73e655f8f30ffc197c85c7958160366205f03e2033de51e8b10e562fa2733b8f8295e7910c307f126d0162a44e7f5d941fc0837ab0f59278c60f657410624ab41806b8b8df2d05cf8461017c88e8c5479bdc726e81676d89a1e0876e765afabea5e6de5bb78ff9e0462c6b33ce6a781e968810a6619780a19da7bf6dd500dbd904a5363dba7b046ae184e4d70018f209db5946fa0ab53cc39911683d4619164e4bdea5b2b7e5ce705a93f05f8afaab3e2cc47ac84107ceece91dd5470d11e07a412264112825821e76e57f2ec58286222c77ec6371b7ac808ab98cf5048a65f11249ec0bfb7903095929027db548d68e519f36bb977b46ef18fe9749905645218078eacf52c030be7a87bf908955d56de5f9f7ac7c60ccc29547d66746f7b315269acb0fb53490924b27cb4242e63d723abbd12b656f8fb71749e95edf0e5b21f21f8f083c348a19a30339ffd897ac270dc2aa6d7f338759be85da442fff634d326410b7b28222b4bf7b909eac54539e32bd7f3a46d97536cda9146f907e257cf29624e27420ab5dc4c7b820a3b450a51cee08732ece223898a454d3a4ecebf5cdbae5decad2408c2d7281a5b3bce25455860661568c4f85362821d5740dd9c224bc9bea83dfed8bb774daa57c2ea7bd447178923af2a3c9ff5060d2944f4b9932a7c7d4ca2cc09201f7192fbf960abe540afc0b11f930ecebc50f906433422329e04f37d56f5a85c54237d256aed72e3e408f4cbeaa9ee4ee7a02a6ab630e1fb315de3b313625d9a7c858e71bd4140bd054e3736f1dbba55fff0ac6b8d63ae807f39df6fc5c47321532d2b36355d4c09b41d288b57241a402c776093afd3e40b014ba1f5e42bb9b65035a548cf3e770ecd40d2a22fbcbd9355be8e77968c3f2e6431045d4c9582a7571c9a5dcf3a3bc074b034f07c7864ef44362e4f51cbaba309d888d361de6ab08bd35ed9a872ccbe573e45e6ad24652b9d6d34d3e1cc1fe9dd201fa4b26807f5c46a82f6dc1af15e61e2bc2dad6fa92a9233c482ff412841a8aa4ab46fb6941ad8d487435f74fea944036757b12f37f12d5797c0aa60b38af158fa91d270325b08ea6642226b0db238c3940ae6633936f9f831047951482e0c1b5cef642a1417064e5da858bf3818853d3615adb9b000123681c0a5cf94c5329a64b82aff37317e915e04eb85ea9407c5cbbe17d355eec72d7660e3f6125984efa4efc813571f94ce2834c2eb0a61fa3c3a54cc8c7d37c8888d8c0613e834ea1aa4fd6a884912485a5ff9c4a2aadc33128e391f30cc744ba3adf09cca51dcb484b760f123ae01835f881eee5a8496c0a608ba5bb3d89bd9ca636177d0b5d81c779bf132c254b7b4ef7b1e07d884a3f13b32b01953b5dbc0b47d0219ecebcf6d7a6dcea8a78e29f200422a9884317988033920d08685b3d737309c6bca6cbcd7e48f0a365cb1a68282a34e497289a1a55547f0f01114062c047b854c5c148a9fce746fc9fbabe1426479249825375a2e0fd9351d8c469fd8f45235f22dcc40ec95fe83b1fccfbcfa933451248d4bfa13ae0bdb0ea7ffe19c17f9c535f0e85d608610132818739fd14d44c04ee939f6a411ed7a00f8b3950f4bf0f1e54fa47226b7b7a8e2ef4aad18f53ccc3e8daac338dbb862aac1e921041ef312231789dc0982bb39b304c683d3211aa728b3d06c3c7c131ee647737ab0ff7e68b6ab24362ad3f0ade795eb0a9e1baaec7074fe5828beaece40e845906b1bceb5e9acc6faa8063db5d0caebb9f7223916530b13d991103c67e3082f890e9022565251049365e5d94eb24e64d1824057dc2d5c265b17347f38a94df12c52ac8c225e0b16c4c59a293347400372954c4a1201826e5ec4e3632e801df4da00120f485b47e8f8fa449bed8fb053d4afe39971fe00dfa95a0bcbef587a124f75bfd6220580f9fa0236cf4f0ee1fec40f3424df3e1e7981f1bd065ff7db15fcf7ef8c814702df230f7b300001856ccfc9c65cc8466f3967d44d136a839ac15f36c8be843b8b8c0277e8632085cbcf52b3f27537677ad190c3954364ffce0eb863b1554e906345a1b0065e3fbddd1f531e0a436e587fd68cb8a75ab848bf1ec0c805bb16dcf2a20e303ce633e1e4a96b71a5a5749a02951dbadddc972d9c1a1a1e9dee286529d0e17e5aaf9fd981ef86e5ac90e294404baec4df4b0d1b2197c61feaf312ac676a043203155d8e808f45b84b855a590a2e03924c7eceab168811ec43a18551943c26c66c6ea250119a6e6701b408c711c4bb1d17876ba8f41c812f3965b4fe6316f3d476e3ba6a7b3df9e86e75a3454454b817ab3891eaa2ddead3efc87b09569289d4f745c38a5f3c25a84b9cf7f580ad6647c2d3dbf271243ec445b42f784f89ac2c448cf7d401388290c769e98379afc5205045a9e7e0a52b79dc5e48ed4d2f47954a306d48bd58c15ab0294df1ed02a5798e3a0eb2d097fa282d8406af3ca0a67b8e8dda7554a67aec0bacb57717d779e9c8782bc1d172bbdc17f3d5d1510a91e5e2d42ba8ed09a40acb35979bc255a7ff065c4295b1884a9fcc2a3024070404eade9d60048c5f34908a5570a4d65718033b03a7ffb0c3484a52b7b0543edaf80615767845328b26004d0ccc33b9c22b893750a260a210c7c66956966d0dd8fad4c33612a96f7471ec4473e9bdafc2233d2d6fa0ed30a0390ae01a3138b296ef0cc172f891e3f495dc30bfb47133670a1af16c87808723b2f65a2787a61459c2282ba860e66e20f3c4c6ed5e0bb7542f63876f114be8098ff295eaa8b55b018dacd91cbf681711d38d3a4d0d7b39f5693c13b60fc90a22c9d4cc77b4565f81384ab350e0eeb0d44d931f30b6e6020acc3ab6b12bdf5cd21f3827d7486d15056ac8ac37e6eb797f78ec052743d1f702adbcf6c5135e215e3fd6ff465cdcdcc57f4db63df95eb7fd9e7405957581a73347099f4a1748ca59176207358401c37f3730ecefeb7ac0b8f3fcb73e894730998a48d9120a0f413432446321b2b0fe8c70516cad3e84ff27b0b0b9a323808c0445adea09610d0c5860183397e6e3003328a901059b8e4eea619b92fba9651adb06ddab69105fedefda2295664224aaf2f286f3ef5825be22088f26b262af29a87394c1c9e0208e9c3a2fcf9beaea8903c5ec6455e168a38f7cfc933c2aff4f1af83f349fa2b9dfbaf8572c282367eda8659930cdf79143c072d77062c3015d9ec237680a893757519ec1ca4bcf4dcc2d402b40563a9bd76de5da22d48b2291cae476342b314be57c22e6726692546352964a39db2813eef5f884c86d0da826cd978021deb615c1af6d100287645870137a57d642ae6606bbb96cd6eee85d07136d8267c654935c2bf4a790c810d689f27360e93439fc674fac5817271cc349c589f42e184771cc4370010caf72a45d39549136eae3ca1601903c905af28c3fcd385521a0b68721b43065521f5a88bbc719d63e1e15af6a4302d610d668a3cdfa34d48b25ecbed223b96d07ca2cafd374ea9d85b13dfdbb1683536455202bbbbe472293e3d8c2e154932f1f8b637b8754470d014949dc90a902fcada897df428126790548c7bedd9bf20b80a7cefd62f50854e816fce8ae115dc31c76c084bcdcd95b53a4b5de530759a2efccfd04d020292d3097a1e4e0d5b74d4b3058784f30731c598e0fd4e9f9a800209485977fe734e14d11315a2179780e964402bcba3ee9845299f9d2f8ca54fc05e4f5d51e3ad98c1c2532325fbc4e822e581f70246629162df99932f2f025afb5970e12e7cb4e40f055237fb7e2211f45e640154351c46c60f9d6d30713fb8cad268a29b51a394d4951d661a214989c38a8871ae43ce432f6e3257b841e596d7de40033378fe21fa82049b003d37b47b14a25001eeeac85fbf1541984c4b72e91750710337a34fe8c30104483642ad228e90c1c7b4368607f3ca1215b89e6972683c428654bb93991387d080daac32841b0451eeb453e3413e20b093ddacae786568e0370ba1ca666e00f3bd7c3abeebf33d476b646d3a19c44fcae2190ae7c57d6e91f839139ce4b7b6044f16ac78cf63c7c6b06c8224c18948792992ffdcc40049e151214535602ee550a9b6d42f1978f7e98a9db2d696c6408d475a31dbb9c96e6285079f8b326eeda334558bd39cded5d70804e3a3f03eb30be0bed625d8dac10b4fa1764e8a965e459f84628c9b86d23e29d7d0202be0ea7f9666d6ea8be9213ce807ac9b4af84da1d053e3808b8d854f5f102e6b3ae120deaf5e698a1a83f370ad90be26d832433f2ada7081ffc153ea48847380480a36b823e10cd81ed98b23ba1c71f7401328545ff93883246a39ec4c9ed1b948a99442ae691d2f0b5910efef0efddace9eeebf194de7797c590a157e38658b51b943eb680fe5bb2e045bb89b8a24282bb8fa625c5cfd259cd0cbd419cff4cdeda4cae32270942f7fe44cbb9dd3dd89b0d536149187f3f6b48f51f6622b24e60a71523d71d50f539fbf96222b6f52a9e45b34c12048a1f702a56a00505521a917986137d8eb600a3c4b727ef634461d86e2018ca03b4dbc34b2b5987fb5ca086ba0e0bd47726b07bfb7fe2ecd2c3379f35f0445b1df8eb4a85726d96632a38158591f5d8fa862b76bc6b57c6d332e2da28e297963830dd4719b98552bc3c3590070ab54ce06c29e1fec1052021bb886bfd9ca6bf5c52a273704090762373f86c39c530df466096527997cada040c3071403fb4411bdb6c65ccd5cfa6894d31672f02b5f98d414650c8c3663ed500b9cf55cf47e118e9ee7d3360aa079fd367cbc7fd99574725b39696e7512b20c2d4501a2168504dd100c66249173cb8d4794840359426182a824d1b51e2051df2bf7cb2d323a9fba92d7b5e026868c4e63d7f56f3c8e338ac017c19461c727ad849264f3e3ab91241ab022f17adfc592f87470c40f1cc8bddb43e021f0ecba556544540d143ccc0134312dd96a405dc64201c3ddb17708bc553fbab98212a2cf6109a199fdbe5d65373cbff1bddf2ddb5b5a3d5044ff8391cdfa580a5f88cc763b20fca1dcd07e8cf6b68fe86b7d9e8cfdb03944518535eadc897d7744c2789efe886bb632c2bea695c5ee0a33980658a5eeb0aca2431108d893f1217ba4127a25b1e51a7c45453af0dcc7c291a88ac9c34bd754e6af72972b6aaae918e89bf819bd50481bfa6f6728cf51eef3b876c117067ac50a4079c02340ef613af94e1913b8e4d539a66745bdd6eb7f4ffe658dd8f2e9eb75454d78f2ca6190c23b53e868e995dc0080febd8b12e503020e98be3e25e693f07b9a5bca0dfcd11c3705b907a844c4ab8ceec2a323a03972eba8bfa1f6e110a3266186482393a3ff824deffcc5b5c83dbb55dbbf14d2faf2f9a91aed1cfcfc0b3abd00622d97deec9ad4b9eeff50452a62ff558203cf8c3df03aa09e3423bc6338e66e1b95dd50b24bededaa39040e8abeb055a70c3df28036f5cc43e4fc4306e4f713f1b55a13abf6d94c314ae1bb69d30196c250aba16299c592a7236c01f355539828a6920bee50ab18280dd5596858b1f642ff2efe0f950bf6d70908b40a5ca6e37a70e25285bef46b742f0fb917318aea863ee34ce7839bdd64c3480f9e7960785ae623f7b8a1fd810a6ed3343ae4c3dcdb6706ea07c6951770f25e94a5747d2dfd72eda2b580c3ce62c776f6b6b841ce91f59996758bfe012c513628f70decfdebb8c8e334702191236fe59040a5a16964ff176d864fbf9d47904368c1ea1843745c6e9aea9b073ab920051c0e2daacb43abe36c926741e12b50f2958576773a8f9a204f6e79e3af52c4a93ab015789f70341bc24d4bfce7ddb91704209b1095e0a0734e18ffd62419a1f925b2df16117f337bd6a3bbcb3e447c0235fffaa7d4e503c1bd40698e3c976efb051c4e25b8b72b2535bc8eb2eefd3812a39828b87e2adb7b3230e91b281a69fe3e4485a8cb3a4e6766ae94e1c48cb65711a5defd4bf65c758813272efd741156d62cfa03a8d01e91cc2203ecf2902930fb0cb214ef8cc427be957449f8327452727c2d73f854c3db111dd4cb3e3d3dd97523435ddac6ec95260019e076ca5e1e42a60ba53a58a6c8c8ef4d57a8c68f7a38bbbf835dc25d13d90ba4b74ea2355737dc10dc3ac5ffeab62177b2739a67f254235e94fd2e71b832111922267a7349c790108a9d8db8807a00e59d1011e5fbc3979fb361605b32f79bf04b427a990e0be0576d5759e6b936cbfbd4f3c297a73bf90c6b30e5fc3c76229ccc3f2af002de372717aa4be8a7230084242cecedd181ba4072d0d22f26bc8a334687153c86be4520a5ef06a6e2017fed48b279040b41bdf395b23cfc435816093b1879961de314cba65650e4a88221f57233c13e8e0dde2f02a7e85dc0772c6df71418c19d048a554248964177eb8b13ba83f11a190ea29540ef65920ccfe8196456791d4c7cc9af0eed8b17638b49bab1fb36e2eb65a5fa31c5de195fae051a4ca7c26291d37a7f40284461dc9bd5da48825308b0798718759291c006885a81485790ef4fbad17a134948c465fe8b3deb8e557a20c0d4c0192ca7e9d17f1ba4455d95994a824935284ad3b549b18a63be543dfe1228f87c5a65b3b757715488d64e8505bd2f9081e6e9d47a1073418b44da8fb5be3a07b1cac4ecb6b8d85a23da8b21b9b55b1f75500064eb5f1b74730cdac588823dbd13651158194cf9ab55d32b98fe1f7ec27e2a512120dbca15de26f9b2374d32d12a95ce65010796afd86cc4b83331115e5d46eb7e7778602389fd02d55eb74a60158ecd831c719f9c690716b6c9c7d1ab4a178ff114fecba87a99887d4224b0a473a2786fd26b99085a96dbaca5d38ce2d7ea56cce3ea80e48bf7f6a672c54479d3274f570e4ef0c71e27efddffcb02d6fc4206f3aa46f7d9ba09d0ae84a5515d86536627dc775d526d873852abfa1a90a8713f62d6562929886a3aa9c072db3e11c076a7b52046cc1d278c114303d66e8aa24eed49844aeb7246b170ea5c99782ed6adcb5d50cab51897871b6929ff02a1fdb73f5a85be7eab496218c8e05502ee967db95eeb4828d93df28a996c35d9cbf0b1d1817615fb4e3e19cdd4e918a2cb7007e2babc3a298801bf51b57b818cf7269f16b8df10eb4b921bb0f776fb726c78e6e7c549cefd87f6ad312505a184c7815c9a5565840834d4117d7000904f4ad5365851385494d1bf589e5acd12b76603c9667e1ef092e0fc37c8035cfd01d05f14a31efe39df9228814af7d2b591a34de06dd3d390003cc55adc4126f026cb2e9af2977352d40cf79a996637c732af1c28c2184fb754974973f71e84d6d902883b05b7f4b3e0379c8df8c4d4dcea501a7131945035d3cf571886a497ac41de69ea21ba4ea71ea0508615194bc19add054edf44128c1694868eaea14209aaa2b62b9bce743ad42998bfbeda150ad25524787005f4f9ba12896210d77ec8c0441db24c728ad3257e24f3b76e42f34cf95440989619a10f6fb405babe29211c35304b6797434f195023752b9d5cca46541f7319876a495a5ef3dd562e5e34c7a0942a8ee7f411362c9153cb67fe2f1f5cb4227cbb06f5b054a2039636b3d75ed9268a8294e5382405f6ce2c331c0fe3309801905584cdb91782745be505b940d15744de992a8ee35586c7faa41df9f1326c1c67b636cd06d92bdc014f47a72a374db742b99d35405cf55a390ab03d06275c9f341481404d226985a7610f1b91fb5b730d8343545687000ddeaeb25652153cda362220c5189558fa30e0f78fc840a9605fafc11d33c8572c53d1441b0e54ab67b36be4c4ebc67df56364520da5357b45aa6e871a125994ccac8eb8c2726fd41156c8d10cd68dabd21437fa25626bf46d0ca804e4022776a8d13c944cc63d85add88594377b468b20718caeb93f5666b57a08dcdac270a6d6336bac5ecae20f198792a0003477857c97bec7447533f53bdce847faa4a7ee41aecdb4a4d8a88330a9fff9241145ff70c40955ee214c3e535155c442bf55417f92d2fe0250c407f7a75bfb4b06dc04984aedc7a919679e31f513082fb66af25d8d77ca0ef74404c524080911e081f80a788bf498e5fe620d7bc30afdd115d7bd407f80b24a70e608e2fe12f8f048bde50b5fcea640cd5eed1796d6bccf4b2bf29d3ea23ef01dbfd5e08778127bb77d1404e14c3300b14e5810e7e0272020f07b5d05352c6906da1188af254466f40089b49bfa9b23d572e10ff726a98423ea07d835ab5bd6e3497fd4fd760bc124d783a3ec20b93cdf3ed66a33db0e2c7af7b528c3ce5fd5b14c371eacf114e440ff5f595f9b6fd1e55ed556b6a49af6ab141070c2fdf24e4f662edf7fa89dec93781d0375ac5f03aafd8e9c55208cbb69c6fbb9f240482d0115a71a5c9640ac3f53edfd1bd0596542865a048075c2d95b331a31f77ffa9937179c7ab7bbba343b743973436cade95ff6eb28d197926fbf6d7fd2ba511312b2b2b737e926444a29033209d50ad609dba6bed2093f5e55625bf5d60864b09176abe5d34db99ebb95b3ed453859ac592a3386a2ba79894e157597d86b4ba82997d8d6b4ba1d7510c263d7f2f679154077a87dd3dd55727ad2d68eba4a4c27c925f424a68928fdb67deea45daf99b6a46d4b7a6ffb763fa03b3ce911c860abeb92f09b360a8f69239166a4ba358d547768d22552b537048e48d4587de9e85f3deb4b75acbe545549d525dd2925a9af52b924c15e557a89ec5e9dd33a9b57a75749a9ddf4cdda4daf92b25ebbc9ee942e51d8abdf6b5749ddab5b254ff6a6cb7b24bbb997d84ab37ecfbacdaccdde5c8f64ab45c2b6bd25cf6032047a930e4ff54dba44ed6d3b88e20e1e04733d5532a1eeca1d5ccaa2cc06bf9d0a369b9bdcd69972a99550b676fa6a557ec03e75f1533b1666efaa6c42eadaa91152dd297d02ddf56578ee1255eee04d97a81ed435634b4e265b73e52e92d3b56c22d29e1d3bfd7bcd757397c86eacbeb4f0d3a4b1fa0a6fb469f028bcbf9ccba48dbae90eddce84531f7df4a1c746a29b7b5025526d4e5332f595651fda026bf00a027406c68068ddb64eab7cb1d95b996ea1574833b81ca9972b57700fb884aa4b6da80a4ca51c15d95a7d2141b12564cf3e237049c7ec6c23e2f4cc4ba55f344ddb3452dd95d6089451d5d6111c7d58032e6d9a2d4497740b39c74daed65ae924f24892bcd76ab55a40ffc77b59acf1540e8d73b2209ff596ebf3ce19547b387af57bb2cb52acebc92ed70daa52c09142cee6b64ebb43fa37fbe8a173a8ee669fcf3b2aa16e920be4a8bb699ffbdcfbd6816c63eb266d7c36d621fa2d7d1f5d6a4363a9b9d345e2f37975cf96e714d233a7109d4b708f768eaf5a37eb909edfab832a2b043e342b9f9eb305d975069bfd538799fdf31f2f56769097748f67ce48d9411ee4f7147ae2153b4e44fd60f073ba7f7e7e8efaccf7cea05a53778866ad7bb4eed9e8cc5cbd431cbd433d3d3defe9e9d1582c5d62fbfe74918cf709aa948a4975876876918c0ff29b590fb2acac814f087407390df2212fc083aa2b971f8b60a02e2f4da39f44b02ead8b842621f2225eb619297bfb4433068d95bd7d5e24db4ff7c9272e77ef7c689252071d70b5830e3ae82049c9a7bb00b20948e80ec03be86eea7c3ef7e9dc381e797775397e4e0edeca1ebd0238969f4924e385fc9f5bdf25c5c88f3ca872740800fb4a37800174d1916f9de4c18f3c29e8468e64d20017fa143292490368520423df77c0910b69143cf8916f8d0298220f7ee42804ddc8a7d0bc00b0e048bef7b2aefed45a7db97a5e76db35de740164138602f00e349222f7794f2ec19dcfca25b8b55b904da0dbc772a0319f6ff7f9cccf3eb759fb58006413e82e802e03f0227fa67bac4430219f3c37b7751b0905deae120a8552ca20830c3000faf9c1608379e7e71d224090201a3ca872403eb7edde7b8170f59a4077fecc0faa1a74d9589c7b916ceff9987b94f892665f99a2cde6b26efaf8f8f864a66be282b2917b908fbc481e1f804c77ce746365b02ee388b14bebeb1b79d09b18d1416f72e4c966dd8373f35e2633b3decaac7bc1671ec06b1b9f1d72fcf6f1948aae5a7d01999a2422f2f173f7e812dc5367cfdc3381dce63c77505612f2202b0911c9a5d2dea698b3e79edb4c0a9b0bbbd46d1d83bcc1061b3c755b1b689f7b592c164b9f9b63abf579c78fb9c727933e073a01eecaa4cf0970a0711c47f10e8d638f267daec131d0a4cf83fca7479749bb07534d3d965076cfc73cbed4b67eebd3e5ba8bc5fabc2e17eb2cd69c1f73d9a391eabed7b757bb43accfcfac75267d740841fe730cae81268982fce741fe73eeeb80641aa78252ecb98486cda677d3544e7dd1232983cb6a85c6214308f2211fa28db607f9dc64083f9f9fda68fbcfa70640aec12906a7e5e918dc82276dd6cd5c45d2d263abd5f3d6b5abf512dcb3d5d3eaf9ec41d2bacf67dd07c859f964412ee9fef9964db0419e7399b435b84f2e9336063f3f079291ea0ef27913681fad6b197c6ef00d7ef1cee0ad0cee0d5e823b830d7eba4bfad8e05a1d92c1b50c3e2f920d746d730d0810049541c620d73740b9c2a96794c1e4cbda06c839dc757508eae4c973734ef24195247f39dcb55a6fe1db6ae13b8442dd5eadbe50f7c8930faa28542ab39ee5d2a6a976b669d3c4a6b22cb39eb23a3dd9e7d2cdf3fc52f3d164d6ee10dde3b9f9da064b93b1325ee0b2b6d963176c676767871ebf758fddcfc901abd56a1960b7aec12412f4d65b3bf720effc48deb991bc73569e534806b403ba5b43ad2efbe6daa6bee8eb1ba0f165e7e049c4ce993f736ab06b9b3a0475fa9d86a7af717a7ac611e31f9f9308a5627fe87f00c974a3b0eecbac87b9b4581766d6bf3c37a58242bd27974abba767688eb9c4f6a8438e19751285aa6d74747474ce01c973b45d581f4fe6526993e76c07846cb53e40f7bcf7de3dcfd36a691054cf6de425b05bf7de2799fb5e69b77299277073ebaa73b56365d78ff276e90ce805e35bb9dc608f0fb263469dcc3dda2ed517b569ea8b3eeb52f3d125de3c9fd3fbe4b99d03ae448ee3b883dc579c909b2e0a117972494b6ce7472ec10b3e807c1404c3baa41b7f455efbb2b14da95881d3581f8ebbe6d2508ae9b332334bb367b666cfac8d9197da9197d8839763d0cbef972fa19740077859e40099bb509e73e73983f29c1e1c31a275f9817640f7fcb27b1e54ed1c4bc4daa53aa4e7f4748d05aff225deec0f953aa4c269627574f91a7579962ec7169d9aced1a38b305b007b2e6991c25eda4196d2bcd90078eb1847bb9e1feff94e2e95f6ce39b0eb6e927cd7dfd4171c8eeb58f41a4b6b5fea6b1e75875a7abb43537777a87a3185286d9107065c562fbc981cccddb373d6691a32bbac70dad4217329cd984de9bb9b647e54a954a77788e79c4e4b97d86e7d3cbd4b6aeb3aadfce34bf545e9c6783492a95b1f75724d8354f70f5dd70440003f7fbd5aad1bf429347e1ab90777c091076914827ee41e6814c01405fdc851f0e0463e8500f0356bb0346bd22cada92f20ffe1c18ddc011e68003820481fd167b24b26fb086803f901e4c78fcfab047b9007d556aed8eb95037021417e02f0798704906b99faa20f407efd00f90f5d62fbc7f899cb207b9eebeec47834f72357129a2d4d8a60e4475e64e447741298d6936691911ff9119d64e7d81f7a235a49a8d5d225137a87743e5b93e7269d9692d60130e6d7363e75b7f4acaf1f575d3fc8fec8af631900b902c9af9ffcca354c9a3a64c9748766359ab75b89622a15862088f1f779debd5dc77128d4b6b1ce52a974a9ad5e9e38689dfc9c1ca85e661b8fa42e4ddb9b53888e2e4d1b7f95371e75896dfc957755f63ee710d53d4f97a983c757e5395f5897ddc5075931cf83d9f4d4f7ee613e81eeefd825aa21d0ef9a2eb97fffb2472f084af3f38e33788b0feaf21b3fc87eb96e9ccbee27ef5faefb7e7bda887ba791b2cd69ed136b2f4918ca30381b09dbf4aaad434533dcac43b0ddaa824b25fa4331cea85e493d928d01d39d657508966574ce2607375b9867cc91d993d03c976dec25529645a46c742087313b687183183453c6367e38c28a1bae60420b0c0cc002060b5db0e4604316ed851f54a4d400839c2958ae6091c34c12429001060922d6e851831e6fa8e186161b3417ac182d23588105192e7350e046cc03d4d0e20e177420a28a0d1a1521b4e4c1c7186fb6d461470b6628614394385bb26c218616a51890b0e2cb9739c0f061c61a54948962c40f6f207183c6824f9a15c2b07144112db4a04dc1020e2d7ab85181092951b036591b6c60e932860a52cca049e9018e2d627648210d9827b428bde043176b7831250e0c53685fa8b40104176c1c81455b61043cb471650a137850c94253215c618a3055bc88390386d29627c4dc4066882fb8c0a024c3194e1851051a5b8268438bb2c3136b10f1451a396a76d052d0001b1df690018931e83033d1f041431b3937c480071e4271aa3c11c5183b5840c1a90f286fb04081831c38a60073e20302419029e3839921fa909285cd1c39a420650a20b84c51460f56c098600834fa90b38712181cc0bc70060b2eccd0e3a487111d6584b9c3072e589cb1c58719879629d8ac20e6862e6220420e3839c820c707386caaa4b0020e071f76e8228c14cc3491c70e768481260b9a22b2d8a201727a9072022e54aaa4616a828b34a2a051638f24f01801cd0a6fa420cb0ae2303307083ede9420052d88a1c313593634a298c942052bae9842003af04893470f5178907252811859e4d052a7507a820b1ca83803c51461c890030d6b5c98a18c1c3be0b863022d14c1660a14f47146093b948a2063ca1c708c10a28c1d5b2eb05485092e5b442163ce132c659459d2b2820a6bd4114e61830b17a05823054bd001079b28aeccb0c69531d46429b344c499384e90831c6d686e94c1039626a860b3c51c6c68e9801a4d1881031d38bc51610c140c41c5092c2d60e1410e2e6f9628230c3db0f8e2c5490e6b0f35d0b81113c317626a13130e1632e86843a5071fc064014408c4b8b0c618589c000619e218018f3368a02305375610e70407d66288a5219640e38b2c59ac0011c31848c0d1820e5a8819420935679c6125cd1b5b3e2ab278a20915b804c1c61755a22cb10973a5862b6e18991953a60d1a5cf0228836a4f040c31362ecd0030b347868c307195184704309382ec046172be0028c0c61527062e3023069b0e882c594285658430c183124e1e50b3267f050c51572ba5001c7152f0c514410710ca18611344c21738a5301334a54b185943c84e0e2a48608944843073869ecb074450b07f200c3a58b2b567063821384d8818e1eea28420b1069ccf0420ab038820821f4b8038dc9c60d971eba88b3c70f514c0088384c80858b209e38a384821bc01cf1c514546048e20c3bc496994ed849d3aa1b4c8814b8ace922859936cc50aa018a120001a60b12675871809914f090c7155ee8d0021d72bca4d1868a1136305106c643b7023cc2d020c60446b031d4a68a2a6f98a082cb166498c92245194b2861c79c14c09963ccf046981abed8a3cb162d4a425c49c20926dc60496206333d0041068c153470b8328645b3c567093738f0b0268e1fa0f8801467ac6ca185971f5e10838a4983893774ec7045853bc2f860cb0b4b5aa021f3c60e59ce64e9a28d2a74a8618a9b0b446146156ea861c40b6fde30c08b1c3690a14594388800e30d27ca00a3a50e1fd2e8a205a34d84bc99a558b5006d6b2d5652aa4686016d7ba56dad1d31986199e958ae61505a336bed91286699b6af20f05176362bb167d95157cf64992eadb5d38723303a6a18ad5926d6302cc66635dd62a65a29d67578cbde6559667dc0304a699c8c525a6b7d236f8c52faaed24a8feb4b3cca35c3b00c336392110206ce6a86611966eb186b7595029b5836b36c6aa7ec42c0c0b27934cdbc669165733ecb320db5993291cd071b23af28528488176d23657564190d5d1898c994659305cc846126131e2d667ad999e6f398d8f4c00613128695b0330cc37eca22864dcc075c76593e1a47cd8d6962d8d462939ddd9485bcc165374f26932ec59de9a39712d99c59966559a6b5fa3261221a189e1a1b0a02975869c2768985603776ac3b993424ba6f309930133645ac69b8341dbbc54cc7b013763299a8c944821b031552d8580656904e48a738b20ccb321366321dd34e278b6118663a65a4cc9489f6872c33994ca66c4e712365364a93959cd7eb8d6c6736b399611866adcdaa1af90227a6b5368e1cd9e9348132ef4c63d849cfbce7bf8de6717d59b1be7246336c1fe58d69ccda164e9906f5354f265b5f1ac3943212d46a79f052bd74e13022a8cf7a650cced36a9f7b3b3da866273278842e3019c2b7ed356d648fb7d52411dea7e3126f147684096cbda861b45aa3b0563bfd3d48d912a6898df0f866ce79253ddbc822657bce69b11de697ccffa8d48ccf7a9489b3186c364f227803c2d9816ca669182adb9b4e132b43c7d031096052548fd119ac28619fd24c41806cea26ad9e82ec0c4a7d65154a7d6511d84936c89a90ea3edd6af9e8c7a6435b92176cdfb46185fec75e5553956ef59a4fd7924cb043277d9a48c2d4c35c1e05d937a5e9982ce89827472558a952a584a32678a4ccd903d873698b349bfb38ce76a63c4f9bc574d236597b97d0a48dd95c26ed721ea9d625f4f5873ab02c5bb13ed7602a55a833d68aa652199bf3892130b8a4716c2c0c55e751a99e44a652e7b94a17b99254aa548a6257b344784e4fcff1642521322b097db943aa22da6bdc29a2692e9d4ae992844dafa7fde9d14055cae66ac743a74a97387b88b1bdb27a26e6d5b333a878234d1563b08be4f4f1601e9f3a47731852ba7a18de9581c84ceaf0b474342902f99e3b80e7d728b8cef31e8d029822d7798ec2cec9d7a62f8140dd9383ec4fea3c19c8fea4eeca40f6273c99532b5d16d9a178aa3acd4cea2b5485c73b05a6b6d2b677756e95b33b149e9b57a50a33997a787a31936790a9f35c9fcc64eae4ff9d4ca6bef37c5726531a094d800cf8bbeb3de4319e8ba1cefaba04ead1e52c8377b0d44eeaaed47972ea644e5d954fa85bfc0caaf7aa8759753197495b3ccda90755552eb11d9eaeb4565fa9306f1773779a511fad775154a99e4a5dab43ac6c8e76e1c9f03c571222cf5a69265276ee3a196a5204f23c2f22cfa393c0ac9eb4a3c9f04a42d3fee0b3f44af3e824972643cd44ca15fae54a42a40e75024a80ff9eeb43b13fd89f04a688e73b4f0253449ee749608af2c9bb74129822d7b54e6af21d9d04a668e72e9d5482e6d149d3923ae903fd72a611cb19e753c8a5c597b30d8f06b23fe2a710a96f7f4429efd134cc4a7ba698d49778553e9a6dac98b32abc0c855adba97f87a454a8ecdcc59377b292902b2b09f1642ab4a3a7fd71e9697fa650ea41767b98b99734cc6b97346b652e9336a7512491e994deb2ea0a0d996ffee0b24abd542248d987a2c0e55c6a52879049801245634ca6d7ba51323633dd96b34d102093bdb66d9b4e6d729354026741d566a4207bd34966706980a309671b60064dab70e4194c3777d4e6b6639bb31d9116115847c41ddce2ca0eb2e792166eec2dbe68b1c461ddbc21501a339b5990d5e6cc34b7d92cd33328fb61cd9a50cb0fccda89d51ffb390f14949d8ed2b48e52cae496c8149a6960aa755236761a8595ed79e395849ca8be7a11eb238b8a572909518ddd8b869d6a6aada4ea1dc2e728099b625ec6a91c7e4f65a51d6a5b03bde03bf861f5b5796d4670834ba52f9b62b4bbb8e350f3444f1f54b10ee8952d58b52f560d6d2303950daa51e2363188b1679b18e6ecf928f6ddb34d0c5e2cb0e4a6ca864d2170325583e712186bf6fce4606e2bc8d417c23ddb30d1036acf2528ae6459964d0c2b8fb0899da61246d8ad494fcc56224c8b15c8092cb670ae14d0f8a10a307c702308abf980850b77b06183841a18729062c30a536028d8218e0c730cd1021951685ee4e86ca525c478c30c3971e6a0f1f2238332f08f572582615fac78e39a11420d14377c91840adcd0327b50d306d00a53ecf1e58e20cee021620c5448637e5970f1218a27d4ac6186cdc20318786c4182851a522013471aaf1ff505d4864503a3820b930abbd6333d68c65cb1224c1a7850d17650b3b41141c79a37c24cc126090df3420d139a25f29afdf5c33585d46740062e1fa40a55d7e4605aa0376ac46867c43945b021c312549c814617353c60252d4b2cc96085183bb850a39e5193428786a670c51ba93214a5a60d32494ca1839632260043015390b8c2041b15d0908706241db8c4bbd62007c33a18038b2a68ccb0070e7c685caee822d3630c38691461c40b5570c040ca06e45cf1e1b154870b3b648922840e293803ce2517c89023ca156a74714308fb4bcd1a7744a1c4921946d8a16db9c28913142eba88c209375eb410450d22c23340d308196c5833050b229888636ab9224bb83110450d7358385347115d84300cc3b01a04a88c206e5022410871822cbe6041230709bc2044144518d1041a2e64d1b0581127c38c1873440c2a5832b3c2e93833e70a2abe30d186032a8592142ad2d0828923d23c81c495aac515346c43ee98e34b173918f1c60b42d85f68e06459963911030c14ace1c5882a45645996655996c3ce8e804c698c163d5c5133079a21cc10cab22ccb8eba7d3a9665599665d8b513062ce052ec5880832505ca444d1740e0e0654e1c3ccab4a0051573ac0963c5ccc4e186394cd0c5127994600c31d0d08152c30d1936b868f3854bad500e700494c9c169d75a6b196b9b985ec4c0058725e28041061f342b63a450677c084347993be064710643b345470121cea890879b30dc0853cfcc20850c51dabca0a6ca14704c1b96d05c34fa20f305063de0f011050d5ce2c901b6ebad4d03850f2b38a106172bdc80d16a58e24ae00a36d07842872182a8a2d6336b3cd8828b2a777869428915588d8613e00cb4d147113b80c1c4116ed8252c0628c2ac408b9b2d6ea83643174f8a931fb080f105cb175db43004434d39436b9d706ed818b73122d3d21a65d76a860b27b450011477c4e162036dc840c19c22c810038656021996aa6c1b2323c713667a3033c613530849408c0c57c891e18d20bcc0615287cc296fc05162018b25cc30411e706cd821063e3c252456f0228a2aa250b9e30c18754f3877d44ac2e460ce71636aae7471040d66ac7c112a8136f6a24a64d60f300d43b3b117a943b42a1b5bb2228f8d61981a5e9ec8010c183ae26c11c238700c3c2f93d1fe9081cb715461db1d54c9e0263e1a371c38d3da9422dba6ca719b8034a843ee4dab9bb87314f5c13e71188771188771dcb99b82b6f6ee362bfa1e666b57a956aa4f09579997fa94504fa519b6765097a7a38636930619af3077551eaf92595f40e7b88c2f7ecaf7507c11bea88bbe877a5e2ebcf8a2d555a1a8a7ac541adb1f8cd3242982f8d445d3945069977f6d932e3f78fda8080934a5ae9e6ae0723a1da5734df5f0a3f8d657ac9397bb19bca76967699d88b54e043f71f79be46ad6f33c0fc823f1a72fa76927937c1a4803d5d7d4ce69ba6847bbf4edcfbd96691fe388b1fd99daf5941dedba593b98cbeff5e2f1cd9a76ef81efaee5f283ad7dfe6a57bbdabd2f5f5bd334f9bdd3259984fc3412dac7dc1f70379344dfefc924b7fbdc4a9bee79ff4fd9b9ebf47e3f7ed1cdb48fd4949d264d767777ee9ab2a33fd8f32efdc1ee3e4d7c97cb7b508f40065f7d4cd346e2b136625d3bcae5d54745b6a83d5d1e15d9acd7932b8d35aa9e5dd3656bb552a9542aedded3ee3d95763d4f4747e75ad6d1509ab6699ea671b9a7fb7eea5314eaa77b3afdf4a05aa2bad3e9282f9745b6f799cb0fb6f6f1d3125989c7e4354be40f7509b4e7b1d6d1a5c6d2255e893aa5cb7b0775f9c2ba04dade3f6d53efcf41d6cbdce7e9a677f79ede9f7489faedea55e29df3b48febfa453bf7e9c959ff53787a348fcb27ef5c67d7d5257565fd9decf3e77c9edc53e486e07dde21ef5ed6777d8acf77f45d2ff2f9ce79fe1759f01f3cf3d7f3532cd0d3fe789a2445f8f38b78def33feb69a7f0bc474f3b7df2b43f3a4fcbd54b6477f71b02507d9d9bd9f5fc293bef39bda408aee717b99e75d1ce7bf4ed0ff79ee717f95c673dc54763fbc35deb697f94485284fcbfa8e73c5fc014923225eb69cf7d4acf797411fbc35d69bbf2b4dc3b6d84ba3d2ab251faf48a3f28825222abce109de91a87b4310dbbe974d6570eb298e9d8bb8cba86ba7694a68fba128eba1a856b0ba6dbd66efb76cea68e627d75950e3e789cbda3f2c4f8e3477a17fdb1a9f77942cfe69680c7ddf151b9ec3e4d761a04a5cd75faa8eef520dc7f197f5e0560f0281069e39bae12d4bbeef3fb3cf801a5fd6910f4ec4e93dc8dbe77e7be771a69cf236d30c8e25c76f81ecc25784f8f400683fa1e6ba3fb4f1b8dc747a03eeaf645e9f2a8dbe3eb7572896d151e59e2b3635dae54aa3975283e14c3797c0e8b6178eed4a172081e773f8547cd83c762f8eca7f0a879b0d3657624bbc372a252a14ed54b5477eaa89cd225dd288c5118e36b288c426d014f37f8a98da82689ec9c1bf87997d8cc81f6dbd6e95269cf5c22edf0b312693dd49fb631fec1b7eb40d07e03bf81200882baa45f0e3fcb6ee3dbef46f3ddbff9ef21141024c11be1cf83f8f3feb347dde6f4f68a2bd2aeb747dd3e816e6ba94ef5965c76d04d5358caee128efb367e7592f5ee3a29a3ed1fb7e5f05ec6dfde82a3d9779ca99b974875ac4b13be4f68edf0f8a6cdf33c4fd42028ed107fbbb75d954bf01beba2a9dbb67bc79484ffbe65d355e21d831bb88124084a1b3c168fff7d40698b1a043d1bd4246cfc9284fd05d92d97e04dcfb2fb01ddac7fb9fc1eea11c8e04fb3be6923d6456dd4faf6a00a66a4acfc3452b6597ad61799edd6a70efdd622c767df74d9e9e8e067781cbffa88ef9df3c62cebb6ef5eb6e17ff7c6ecd986ff81bacca877ec71dcb30755a2ba65ce3ba64b2ecbde3defa8cddb36971ddfe9fe8ef57dd524113d3e3dd6256a7346dcb58f5e25f4da35eecb1ebda69dbb98cb6ff1602e49d8a0e7e9b2677bc757615df6f0f0ececb85c24d96ae9e88c238bb55aa954622a70b9808080980035516badb5d65aebb8299d73ad8f037378dca9c097088207418cef812f2f76200b775c97d2e1b8711cc7d1f3eebdb78ed7169b783fb6f7c3e55a9dc5d2aaaf4a71e35197187b2f8cff83a63d79f2448e3944b23bfec67debbaeb7c98e43411e86db7db8e3dd9f8d3b4eec993275d2ebb739d46c248b2c336d975a2e87da9542a3587a6699aa6699a8684618cebebeffab0dd29cf7327ce6a49fbf44d2345e8cedd49b79d33ddc94699d417c6a4c691d38917c7a7760a3ceae0bf7360c6ffb2f710ce1a8cba4b5007c10d6a278f3bc660e6501c3eea2078d455f2ddbb247727ae93a8ab494edf22d73da94fd7bb89d34cea0bdcb615f656ab636d147ab9043552ddab2ffc448522caf354aa772aaf53a9542aefe0bf4ea552792acff33ccf93e39d6eefdfe781dfc1cf0a22be0c82f8b31fa879efce793f992e9177a9132727d3edc00c033593fac276dd9cd7bace8b5adf75f4b4de8bbe7f9a497d4d4f33a92f8c25615f55d08df2c73eddb54f3f75fbd4e99f4ea7d3e926ec9d3d951a8735ecf47aa1aaa503080e4ddb585771abb73eea78c79c9753ff7227be4bbd7b79dff77ddfe67ddbc55c7adeeae0b67a50c5db879b74dee66ddee661fcce6bd26477deea38a557dfb4d1ea60f7da2b3deb8b23478ed51a4715eb2a968aa552a9542c954a7555fade0bc7f77daeeffbbeaeebbaeef57abdeaebb5a6c9eb9372cae613ac5235dcc0929234cd8dd3992cbb463b403d3b8a76d03d3b57afe512696b59f6ea1dc3325176ee5e4e9269d3b912b64997da27dd2a12eda7139d507b9eba8ca21760d76ed2e805d84d99684bb2698cc894c4f4d3eeba8e625ad850ddf12c72fbf7655c7178fc8deef0dbe701efe1768d5e801f7ee3c24cd43dbc9793743ad4587de1138549c2776137eb6b4b6d9bb87dc7acb5d65a6bade50eeeeda66bb2c3469d263d903a78a2492f289336fe0e0f7e6efced1ca841301375f7ba7b1e0e454e14df85198b5d6bc4f8aeeeea0bc17f2b30c49b4aa5527ddff77d1f1b209247c495d2a5e665edbb2bcffaf3dde350fb3e22dbfdcbf6921e481d9f48fc8e2fe6f01cce44e2f1533909d644f8dd5339097ed77d9f77d003e0bf1369f482fb501385ff0ee624a1c62ed1777c3027f98ea4ee6f63ddd5d7fd97bb2375f88938714c259c36ac84b184a3d14b1adb25371dee5f6a3b5e121e3ceeba94260a35476e5b099a86c9f0db5642092590df72b96dfa6824c9ed68dcdbd1b8c9a371dbeeddb6ed76dd15d3d0344dd3344dd3c612f697fac43b19efcea569e3693c8df535029530fe3601643a67d2b40ce371fc5fafcc843554e7e1f12f274c809800551aced852202b043f4d1bc76d478b074550d330fe5fafcfc9ce5d453bde5d4c4270d34662288ee48a35aa5aab954aa552a5543a3a3a3a67b85c40aeefb8f20e90eb3b40f667c2d1a9df13274dd34e502c141b461977f595ce5517c7ae6381da3ec1b5394f83a0f41d979cce411d1004a5edfdb39c87d2017574583adde747d64a756feaa6eebd3775efbd65b458b5f3024c76162eb404ab1b408192059c30d5bae30539dc3ad8ba20c771addbbaa78d5a5c2b951253622a954a89a9542a4ce9300c4f2738dff74e03bf839a565f18ef6e8921b81eed4c1351d7ea769ad9c5266295438cade3c26f195f2c8a7bdbeaf78920f710e4c0f0081f896279b4f1cba3eddd13412e3c1237787c4c1b710fb5d115f391b8bd6371739b2e8fc47d53de4da5baaeebba6d63b1582c31c4a30daa8eb12eb1caf38ec9af56bafc391235511337c69a288a47e26f15073a9d4e279389c9e9644f278ac2ff7eca259009bcb5dd3d263b7be681c77782b593ec405d80ba8a09f1a645721f1c7b6d621d10fe4782df3f8e186b5aa849b0a847f368ef03bff0c398c9ebf58fe3a749f0589724f9dd89eb3b77d2731e7c8ffcb408aeefbcc8a5a7dd29ead14fb6779e271b7f6e26db03315078040404c491ad56abf50688c9ee3ad2b6f028863b40d48913d74ee6b92bf7009122ec9ce7453be72972bd871481e73b2fe2d9b92f3a02a2293001d2a9f88cd7c676b45a939dd997a7a14c9ad3dbc9cbd336397a2985397a71d5d601e4667551f57bd6f885efb2379ed0b3c37bf8d575dd35097ac71bde5407555d93bd799a86f18fef81f78e5e206eb2bd974db04af54d1ba9b6a357f9e9a3d75675ba3c7aedf1f32d96ceeab258ab8bab8b2b71258aa2b81245d1f33851731ce7e6d5a4d3b96689901f5762f750d32cc6761c3defe8f57d5ff7ae7b1dbdb0d73e818ef55301c330284b6dc2eee3532d95f8e925f7dcb95fcd694fd5752af09efbdc49a026ba9ad3a8af53759dd8899f6fa5c430955a855f85ab70b55aadc2d56ab56ab384e8aad1b695a29d850b9d6ed24eed4d1adb00fb2983c9a610fbc4b6d1c5c671e2511ceb2b9db7bad43b9dd4bf107bfa9df794177ad7eb5250ba7f9f6478942ec925e03dd43f5d92a12602f59c42e686b23fd04bd9edfdf3b4d17da88d748eb2765fdbd261ad56dfa752a93a15d7799dca4389222a8bdfbbaeebbaae0b7cbaf1bffa9dfefb30e5f0b679ba54da5f2ea1ec2f7c2aa5c187794e21a02eb1dd7dddc11c64bb7cffe512c97a18538c8fb3b7047b1a11f80fcc26d03ef6577787a7904f6f2294391ba98eb47b03c3b45336af604304aa135bf843a1de5afdd3a509d83e6167abfedd7497a08e35a84150daaa73f77ecf65eeab5cdecf835c787c0ea38e7399b4f10782d2e6fe7d477d40695f0d829e17ea72250aa5bf639c360a0f6aa3d65148b5c49e2645542b3b4a14bf675fd7a5ba4feb50b9bbc75debf0bd54f71d731dfd3acd7a86caaceffbbeef63e369238e6edee93d6fdbb6eddedb7df4eab2ee7bf15ec658055e05de874f79b8c362f8fa6b5422d56cdbee058fb3f5f0e9de12a94eac25dd3a4e59f6e4743abd4ea6fdd170f664634e48c0e81e5a6cdc778ffb32f82d779ef7d15a6badb5d6daf01de8fdfb365017912ddd6de1e7077e1edeca27fbbbe92ad94a6d7f24bea74bd209f9968775510bcaf63ef793ddfd2b43efa0a791b08ddf81da68bc87846def1d367e7a5ed7719cc87522c77198eb448eeb30d76d294ea752a94e8bae3b7dd76958974a5d2e9fec2e7c2b6be0bbcf3ac43b98677d2161985e275d2b93f616b5de75452d8dbd9ec8d9487653caaa1706ce344fc2ce6636b39d31a8d40b99c7f328a91856230100080316002020100a8603a2d1601808921adb031480117d9840644216c863b120487120c3400c641022c6184288318618a30c4d9d00ccd7dd74961c2dde733c0ee8c7e38fb7dd1cd61f6770840f60371d17ff7d9dc08410d419d27c1d4a0f397a79437d4812a66942784d5d6d836c7c00239d552da97ee03fddfe3e90924b0d40f424e9f81b4e9b68cc7263df7642e96a5988a5dc937e159843e17b5a80b82c76fca931871b035af038cfed03377035fa5216bc480f90c64c2a3fc7f9d40c4866dc8392b635efaca49ff123e3ee147d5ba4ca0bdbe543a14354287e7dc27d16a6c60ca2fba155302254a1529070978ef32ff68e40d63760571db99c15f9a724c30fa5f17d909d785e59701f824ed1b2277b49adb0c792b7a154c5f725a4891ea8a50ce1ef0d485e82640f1fcc95b043ce5aa1fa9c07310677d0d53dcc249eecd0b0388fd27ce3aa6b2fdf8fd426e03d5b0b780f8b5263bbbb1e2952bfadac23a7f29269810c74df7389ed230427e0c6b3eea837212a70e5fd47d9f7605522110095155ceda81b06275e3203d62375f696fc259b95ec77db0604f587e747a2e1d663742e49e07ac4a1276a040a8a5e1bdf987ffb83d73e0f53709980e09d1d274a69864619395fb841305038ce2c154ecfcf805745c783f821dca7f593133960fe319177d4d8b764d483744b76fd707af16047a3592dc5ab7083110cae053ee4ba4f89d0aa6123983df7997c4e736223e4c87a3ca76195fce3ae932e6ac435cab86bb4cfd73aa355a0dc9451d260575542b5b4072ec19026f7c64895894a73eb9fecc66975fdb2c31010684c8153ceabdbac7a6608a93c69bbd5f03164c54b3c2ce6aa5f2f6a8a968a0deff5bb9cce0a345587d3eeaabbc609ef07f02f16b00f317a107ce51c613e69a5ad0a77fc74f45020d15f8d26f9ccc65013d251c64bfb5ce13acbf23363a1513e19176d4ea36649f6958119170d050a5daa22ee0da1ec20ada8a4c11759bb9ab8959c95c873e7b3544ea89012bcc4319dc1e3a85c4d49759134fbbc986c309795ee901f15ca1dadb1c7f7f36d802e4f251d148555bc51541a526ac81f1d9773346d8f959343baa73906f4429db4716961e3ab840ed6399f471bb72a6eb7f2bd060ace73730d79b15b8c3911b12121b6a21b8f681cd64ba4d6a683abe4251a1788c1418d58d0165b686c21b2e99df147e3562eb61ef6bbfb7a11c334e9fe55d25e0e529dcdce1426df80c697f9287aaf9ce989473d86f919886bdf0e9a1d9c45e967312d821599076d223fb1caa390fa749adb8c6fbf7c3c75973deb705cd973acda8d139fa241da39421210311647536ce93e3ed66fd6846bf59ff72aa747a2d250619e1ef62a39856a026a404469c22af5239eea7bac12794168a73bf246c99075371a28f9cb9b9a66c6512a664c81d2108b86d044a6362703c96324f6149ca9fb77285d36873eb2f99c0ee0d706f93a1ed062330e4342a04df99021aca59c3c46ad7e2cbd5e1c5f7f485e0f13469e93e219f7c2ca88176116c2f1df988588f39d10887411e4691307eef129cd7b6c1acb14b706ebc6b730bb218127de9a8bb779148a0862d6044bfd29b28f20dc9c9373ca4dcdf76ea6b63a7e5885418cd911d4452763be6ea12f0b53cc728653819f06e3c7fd783dd8648bddd010f9070ab6ed9244acbe12568f1e0d29ed55d9cb871b5d94d4b99de48d4d31841a41a2c7e72395212f922f7a986c2efabe101ffa85ac6dba0c871ffd2822a48f97eaa3b938fb652790104af1a3e801ee9610910fbb42e542e465272a938e77bd40a3fbfa0964719b346085b3515d1aec7bbf7bb47808651d1b195587565432fc78a220daef24d36708d1f0104499a33e222127a2b9f39a37b02320fa3d653ab2580c3d405104f6ec78abb7ac13c0d05eea50abf8d3145c99457e8989672c6defe30d81865a296a28ea641669d490f5bbde3ce6adcbf0422d03aec8632844375a0ef54f811b45a7b3ec1ce4f5b0e8a174755bcffcac3a74258e5da55029e85331f7e9ff1e237d941d57a075304258784aad73f88bce342f7a6e517a05400f851641db5ad162e697515b1426ce6a5b1c3a2681ce39cff838cc5af5f0477c9895a447b2b1fb9f6090add2dc88fddaeb79bb7c5c071a0bdad3426f1e67420236a5bfec61715fdb0d8b09f902bc38cf488f1e37a6b0d6bc3bad78a8219f36e1acb711765e6b47a85d696fd5e261bcec48618b1db3bf992f9f7640da505cdd11b17aa3894b84d4ab508cddd816bcd22b88b105607ab668b1cad7f4bf3a98c4c6b0414b62e9078ca43f5e656c4f30d890c159ef0fcb4f02257fc03473ea9020f88cadf057af4b5a43775fe95f3c83caa4b7a09f70d0269335c2e12f0920faeb1af227a63b3b933c504768699f36c859c56c1c0fa6123f2baa21d3216f5e37decbad1733d2d0be44ae23cc74824a17f0a25da521da630a65c26e16f8a194b65a69c47b9dc1121782ca3d09e6f4cada0ab248c3c560320a2abf7f41092a0367ae7e6515f8b50f7e67cb1c4d72bc4007160ba3e16eb21f34a5a10e3741652c164578d6eefa5327f7e3cb1ef2c59744e06902c440a7861105bebbab5fb96e14b664a6511ad27754b85470f8885f9acb2eb223c3d0c7341cf95489631baaa0af7f9b5bdd671cad0985ef32f8b16bd198ed83ab013b427835a12f7e326702919b5b9bd009838f650a5199c1efa149b70c55d9c947ffe7a7f5300e44fbfd980d12237f8aea3ab9565661ae8ffc1f37ce3f8abcf1ff4fcba21300eee6278a6195e9e94b1ce28c0c87f267d4311ebaabaa179601d1bbfb54658c6519921960f01896d986c6901b94c2ea69c83194319e2c998137054f746630e522217be6e8d8b54d512c21f5e02aef223bb4f3d1f976774f6000044484c5b7833527b8126392949a9056c48f3ae8c827dd03aa72974ecb419025c2d8ebf0cda6674bd16607e14f37c890bb10b144a7de8df1019ebdbc2a6ab38569c0e4d2c21ff8579db0c563e884a9fa3b64748de38e6422896e707fcfb7ab68e8bb08d4c1b865ed6ed3846e98b818d5d32fcb50408796bac3c3e4e8b2490d18a9921f23353c4fce8666ce4720a069b1e93dcb0cf4b8f9bd5dadba2cc383bb8e5bd1eaae80465444fe34901aebaefe6ac0b88d58e537ca0ec3e5f9e068e0f4d298ff078cade354bd0b6890b6fa98aa5c8745eb111ba813e3aa118e080f30962b64adc6177c93b454f0e703ae52b1147ca4ac58dc3192f7009ede00af80be1ba65a70643a4423b73c2a9a41e6291dd0bfae7560cb9b844fdf5bece90483f0057681daef01a465b313f3bacf7361681cfc4e389c506aed25b0d6216f00ba362ba00030a88043578d2165bba21a4db523699e0c0c11eb469177984f7300017624fd6c1a0af6d1dc2a287a90db53b7d33af134fb7eccc9c15891af3bba1cc524839a230e1484b8536cf41e09628d9810a3f2345cbed5080e54ce2db23942636cf428541c7e675df66fa3d9fc3af21035b36760c14cce7e50a6f9e57f1881c1cb99812b9665ee3c81c8c9497382ae2c26f3c8b3cc08203980f45ba9e81aca1da35449187501178a605edafc334876a490dccc5b27661e224e87c891962749b83f63725f71b2200df00c466252dd98f9f8751ba49575aa4c62c0dc42bf03ee32ba9acc54f0231cf025b723cca0b33c937efd5857ee978ab1513aa336741471bf39d557155c974f5035656cb030b974758031b2229ad5684df293b080e7b018aec61fe48bcc42277265ca9d414933c30ef1a988a3a0f1e5a710477189063e42b1f0d4380984110bdcaa026d6bcf67b8d158f8a40db66d3638e5864925b78e3f0f95aab1aa1a2aaea0059af1ece3f4cf2a25f780b25fb9e480ade5659f901048a96393b934d6d02c3d05c2aff22cad66e02c93155c0410a0d56bc5b392677582153c2540a2956fd298e143a5c592476f07e42d6dbe70c012acb49ad816427e2f535b36022e046f93a0e08219dadb521d5ebace50b98b404707664fd538d15d3465be2e52347398d2731c7d2589b13f336512d1dbd842a20c72fd638af29f8ca1083908d675d0cd2475fa80ccd4d5543f7b625bb1e0738831530ea4bff6e0bb6cdfb141054dcb949df37c1751f52957e3d7520e260ea80175e069c66d2c8f004b6227bb8b5be4c9b95924cf30d5bf1d52f6671c7e8c315dbbcb015b4e9e4127e17f02206678a9ef8a4dfc7238db82127bdf6155f005254335e34f897539ae997208e5e51e77d40ca74726730d41759f1cb0427d484935bc405f60340dd60bf021a941390ae2d30e65c902dd9f624836cbf9c9682c47b1bc4856a539790e16a4e8c5f4d6f8eb856e5bf17614afab971e48052bfa41a58e759c05eb40fdd9667eaa77e97e73f3de8749252a3d28335233992f6005c6e58e1224b71446c89ecffe436f7e0884dbdd7e2d0b27b62843d67383149624edcd8bf0dba969d19d825d59b2d0177bbee248039530021e09374a9d3295b4f24afee5d5e72e5cf022ba9461090449939ef317bc4c4fa1911a5bc624d47e7db74e57c6bb14a8b7e26baa31ad1c00fca5aab411cda4460ed648484996298fd0d4420ae229d678ded83661b809e6ac3984537a0766e5aa4936558042853e42bff420f77205a2bb74af9e687d81961e9e3da4488409b10a37058edc1505742675686e37dbeda35d6c68c807316ae3fd1ba1df085dc311ba0ec1662606267d3991b81ebaabb1b9ef1ecb885ca444aaaa6c5426ade579749de0883c2594207e40342584423bc0ab43726f61492e7d04ecac1809f6b48d073b777d654585dd8f1a001835ecf26de4119a938873d1c7c9e0f3a02ed436c901c113c52deb61334fe247e8f31c75b23e248dd3e05d7faa05f5ab4d104b972ea3bec002b8e9dfe39a4143f7aef6aa6694d505e4d071cf43a3e207c0a299ac5e3731d4764fc266073eaad23b05feb4335d51348b212efbc8bc1a1cc0e3a17bf5e0eb84785c7e4ac2a8a7f23f0ebf27823250d28fee4f3ccdb5cb2342b6648bbde83fd2b5b909ac9ed85d0d054ebd9d7dc7b719fb86b59d54acc43084b313ec44f4194a6fee9d4ca37a03d01cce60a157e828830421aea0280221c2075f1c09d0720942cdf124804babd22e41582a069c04dc7f90a7069a9a6f743ec64aa6f33998229f5aec2cc39f9d7b802940e814f2dc9190681ee4a88d224090b87e3859743e341e859c870fed795fbe19469ed06d5fb1d2b81ba4512a3f8836e4eecbddf9cb292855e8d367eae40d8c7f8a36cb0fa413436ccb06f65a647115574832c0d2f26c1faf6f8f1227197a77afeb8337a7100e622eb5b62770671ef2ec91eae994a64ddc672ea8eb85434bef26318a5f8414ff5e58d0f010fe4ede9856f7a274a1204fc2c80f98c81a32b59073f9f5cd3be0e2b5fa0898bc83d286114bfc46c99123ac58c510f2f0dec9959e8c40d08e3c8ec6e29fabedc3e9ac028e7ccd6e3f53dd8003013cac7e8d7bb7a6c8a4f83369261a8869c85249f6293e3aecc3084eb39ac2dfee38b8bae7a3790ac3019f627f1fef8da3b78a6f616e3e8fb6a4fc165ee6e135ed19afb8b7856fd170ba0049c8f0cf7c08863a376600a2257ac1cf16f655e4f315ae44b081d9c2bf03eee6e6c3433e66ea617185aee37e93d45c74493e62f1eb4ef31d5c629dba94eb701b86d56039cc141c89147bde2d9180388d0d28f349817a6a4d449446981282d3ae929def77a147409989a31568a3a58fccd338c87668a0070e27d001fcbd01da7eafe3aca953ecbd4d2ddb737eca739ee09dd592c84859eb8ab49f098c68d4fb559904ba3c5c6560bcb988e84525e24243e7e8ac1e69dd3ea6b75abfcbbf97921b2499ecc4c7f18a546c5097951e15af610e242daf173d7dbc9ea8e55222182117070ff63aa0d55998fb5afd1d1591f30fb77551d892705a578bec615cf31afcee87d7023fd1aeab265efba9bc3baddb0bc633cea20f98938d514ac845daba1c3e1c725d50e563d25affca78dada4deb1b1c096700c376ff911e947cd6fae62f903cca3eeac77c639b9b4cdaa1badf85005edfad49907cd47e1a697c435216a2b0d629760cf0b08f6a41bc6f51708fa1fd5a88e820e21f73863e3ea37da3ffa7660f7747bec689aed1f2f71036fc31ecd221344fae062e31369e2d3610ff1e53eed19ce9db2bb490784a2d1b1af451c6d0cb9f0854e18236548b6984f4708e62b63f0a74291de9ce07c17143132be76d493c949451e395d83f5e7ab9abcf93bc94901b7f24718bd60712a8592afb9d4e181fe88fa03dd28cea0e49cd50608ab9c832a05e31409e958d7837bc57cc9a04a6e007a550844ddf02ced5ff3645d3185690ab4bcfe4d2dca77e355561d0c4e4f0a9bb9ac239790f92b3e72584d594d7a759ac03ffcf6a3123e1b3409934258de81018b42234b6de4237aceb7941e1d1662c2417a3b3e57108c52f547e323e9b26884fbeb3a6f0f172f3cff3480ca54f92cbfb902f68557872f1c07f8d622c68736c94c634a2d43f156da224c352085953b26f50d8c5577a2feaf1f4823585e37049cbf3856ab819088a1b45d8e015dcdbee454f11953e6a558790673e520fc83276e82984c01f4294a75ddfd8a4dc3430b0048696c8b0c07f83e7c84b732b09ee9f53a820f0fb70971e4eef4fe2c38ed1b07ab795771b87c026b0e2ead6dfafbabea75ea76a2360f56360c6c11f9703d94386bcfe4b458c6b056c69f4740d2a9a0356274160211211acca6e22eac27a00ce4bc90df9c106888d836f040273b12e38b7973f5e8fa2277721479c1487824834123322e4d4684c732fa98ece1c4ed89913fb82d6cc19e1e70482d064b68e15896017e69c49f8822689174561019605b4ae7df2947c66269017e651326aab171ad107943ed1108f2e950aae1b46c583ce93123e3ec8cbe0bbd1aeec904efe36187a41d2f0f76b66fca64886646a555bc28f40a40ce1759de854f58afcdb5f978eb0f8837229d89b3bddb82a6b3e28dbb7ef5c6124e2a01c7e1dac97cd1dbc4b0c92bc12c2a5a0fbb503c7146b9cc4e96ff6cf644b5c06f141ff4f3b2873949bcf1d409b879827975490d76ce442a9f0179e35bb4ea887571e83bca7d272d6989cade1e1ed77ebd8ae937c8b42b3928fe88158c771f82e444d021fd1cfbe31ef5ee3ba0b98d3f55c440b478ec70411025bcccb85afb227a028e4c25c16e0793b0d14faadb5b2018a2776bbd3c04120327645a1d1c2c313b8e401b6b147bcd6c3d7e100eb517243b169d2319aa50a58313da9e414ab80ced4ad437b216a851f1a11f212c04e3ef2980da9b9c0ece0558e3819a266d0aae10ba76d86672bca48a8550b313c80aaac523967ac0215eaf5bacd880dd1c9bb220b9a5b76f88f66bd1a17b934a603c5f0fccb6e9303ff9f2d151779eb8a323aac0c1bfbc899249b7add7983e01efa54d8bafe55ceb841f966b953062b288ef05e559f87061cb0c08883fbdb8afeb989baee8950d6cbe3847163c03d2b9cd45066ecd4f890f46448d50570486abad41db581f46e8594e2e08c2b131157ab4cd06747992baa94eb5af6d4e6ae3338cffee40eb4dac262ad43506e35ed6b0e391c016c306b11619ae97eb28e2055b12daa8860fb1f6cd5a117d43c8433b902b8f2b0a13560233001aa89880705b8a0d0a89a528a7720427efb22dd8863b399fc059560bc0d47faf5b34561e0cdfd9b7c5a07c0fb67ac2c87784606afdd001650510afe5d4457ac87569f46e8002ba778b69ba02cff1a5ce5bbcd07a1013a61412d7e87737d85d003a86ea6bb6c732fca2d6dd874882b6cd0ad4b0a33d68686ced151eb942d457c170521c55edefd35a4c27893a0b1200e0b90ea9c0ce97f2c80bca582dde794a81bdcc8fd6ad4741bebb5cef935283355c0698d1ad406c7d5212aa56945751d0ab9d93c0eaf7b0e862a1677870a7dda4d8d4d6ac0b9a0a3283b999e62bfe8c42dff209ccc3667ee68056e101272566aca8c11b0cf5126087b4463b8d0d5253565aee19fe795f17870947799fd086fabe37b0bc50292b2c523eaf7e296883e783ec76c21033f95ee16aa1daa846b7d2044d1b692445f09301620de7b4edbf49201434da889087b7cd526968d16f55875e9ce421eae3fea1712b38a3a08a23bec7083f4c62759c835aa6890a26e71dae3b1fa6d3834dd71ba2de454c0826a8b03d271f16ca455f330cf5b605938c388616a2902de4a7f924c6d6f2515757a5cd362a665c9675979b4d1c39c2988190458cee77e964ddf41ea61e598929cb8ddfbaea8c35055b7ce80ec7c35ad357b0c30b340a775f2dbac0bd3a7c28c703059701172be1c8e17cbd5e5ec8968f724548a8d76fddedc7c7f88c666152ce957e684dd2e9d4f6f2a02363950fd9c86633b96a8e4eeedfb041a43cb40804c2a77e8df958c193e38c193982edec9c987e46f879728eb1630cd84e174292a8f13d0e5600b7fc420f06b28b585e48a651d04d5551669fca5b44ba4fbc980af8dcb911a1fdf4e8cdc4050b6777c69171f8e06536f84470de4770a5bae90e7018a6937fd17d5f1cc6b350406d53558731d3e30613ebd2b03f72a62a8b0455e9aa0e827da8cfaaebc728416c7860678067e3f97346f9539a8ad4408945393d4af016d68336973c5e1b9249d3e8a5f8da19939eb92c75ad82e4ea64fc5a643a797644eb76dcb26f349142f27500af70c3d1a52b3c06bb3f6bd4c5aa380294da4704e80e927efbbf6ef22fa66f06a34e78f7f28ac926f5b399b42b4e2e038ccb9f6e0f7e98a963485c84defc4d9441aa467b337edf4c3b7134c299a24f504815326142306937d8252872633a11e6b4545079a1e3897cdb15a28bbd41bb5af161691016c8dec512b1a7d2621682545191edf29512128eb0af059516496ce7283119f85d5b6ca22e34c0deaea66ed82f1be651434897163412b854ec1896ac89e783d97b678ee8e9471194e2886e5d5cf71b9bc44d72fcb7380ba66fe8889822b011caf89444da08db109fb11e24fee4b00d12149df4e1cddd2e8eca3c54913f5e6d17eaef93ecbd72761ce707ad28f4772b875816efee3d7356c90569312af8f0549e0aa3f8f37b6ea80a3eec61886b960c2d1538e7f6ad4209baa2f7d1e4a933b8c3279021365a6f49e65d75f7477d7681d659069882816b8fb47d52c7b69c57e6f202a1a80556f1f5ea7cf7fdbb8ab216db114496df76731ee1082aca20647641fbc093f3714098038e2c1a8da477244ed85e6b5e6eaafca7bce75a9121398fe9ab9b877d81f4605b8ca56a2614e70c211699ecd7b3ef077a68974e6745d57994b52c24b2ec5784448822009f7ba7792e0986b29fa1e26fdf0e339dcb9e50cb82f1a73edde061884e62ab81a601cb13029d2fcdd3f74fc261b62d7cce99a177dec6e16ec052cc043beebc90ab3927e5b96cc5c2a0026c398c381c9700fe290411bf0d644474bfff3004505163ec49a1d22d0a5ae410166e4576dcbaa14ee08470978beead9816edc75f51cd0c40201287533ec9c5b48370ac29c80556c42c5a352c5dac1b1de1038a9b23b3faee6fb5ee1018037c2b693da72a67552595c4a755a8aa0708e1f22f0c59b5b2acf40a2a7aa1d82c0f95e5429e11ce429f72899d7d0f25e80c4ca50c235ef22f80ef1a04767ab90ca468d55720230bb668b35d89baf8660653eda2a21ccad4d74757ef11ba5f27f6986629671aa00bfafec09d438089af8a05ecd98cb7aefdf6bab5dd5d1747fc9246b3e4a49675323e5195ab1618155d427e9115ceb87ffe0d37b1218ef7a57db2bef60faa9a6afa82dbcf4bc347ef414e8229ff44d55b64a9658b8b70c045bc1954a8249daf0dd8674f2c400d60d5e4ad24757d32524eb47920842b577c23ffc308b72051d8ed9858de10b5de260785034007c3ae8e1f19852d3a1ea1b518332621401c410142129378f84ba0dd91245fbd60d5741f5eb1c77d5ddc591fe4673d72d2c9a1ada4ae81040e94330fe9a5494a2c8810aacd9fcf5fa73487e2f34a2efcd8897e9f46087a0b15b33a294b388405344a461b29a78a4acdbc7c34cb6e6ea78cf2617e4d218f420980bd7670a7455d72ed5b8657c4adda078cb8230f9043f2f6a8df82fe5b61fe1b2d66a4b8b0417a8e56619bbecc53e61aa0fbb94b9ac46f26ab0006e6400f0602e8a0fab15eb5ac63ae6a4d7d0158edbf95650571d1ab82dcc9d41d2eaa00cd024d053f5afcf16541be4255bda11536320694e5873a42571f0723732208f6a436a7c8daf67f534c1316c24ece55717813ad4e711deaa8a516fb65a50c2b8c49df32c2513a0d006035ab6f21090b4ea39767476580d0b91c1e870a44c9daaf06ec26393006a1b13e30b1f0722016fce40f95f38665a8b96f57360e23f14b5752ce5fc1ff905dc49a4b8370a54e9b99fe2c7860353af6f173df050346730edff2c35d99c03feb3fcbc01cdf556c00426add00e1ce14c6dba6a695f335d53c24e48cae4324227639f9526ffd59f2a28040e9de0b6663685ff75495e56909334a82545b81a49e9e2c238d71842223c0515e97c1854f76a7254d64e068b0a3d62b3238c12c479526142d6e6ff24065f3355b493465a6891528185cbe23a38d39a54e48cb5507eaa96624b4573a4ffa4a1fac89104ff80b244db877272b419670090f1bd02d86efb422ffa128b84e155562bbf3ddf2f784f50e1aa7db83e3d395f2b57a9861a1b0fd8a9bb91cc93d0f857068d5090f9664e406f5f1ce2ee68d4c53caf1b03dd052a3ddd2ae6c826f06b4bc34a79ae61bb0fb7cbd3e6126faaaae19f18b55567634868b55b4ede3aa9efc0c9092ddc003cd9e1981d86e9b42527dd61c1262829863d3bb736862c66bf64619521f1299e7dde43a2aeb49cf9c3607de0bf89642a27e9aec9086b156e80e137f8a683dfe3b28816f9e9784e2c739edf5f058216d42112fdc215601c716dfa5ee0ecc18008d5fc6fc0190565525c671a60bb67e99a0865683832a42983ec93a8521614233d0d58ca54688c591baaa4c98e5c2b977c430143190aab522c62f46750ff5af06eb92bfad407bc39f0dc1df743ac82b5c13f98ab4929a8f260987b7b21996f8d6948cfe144af2f1bb6b0f9ba6441a2a7288451a47241194af3e3974d93595c73dab1c5108107f396042b7936cfff662bf0a630cacc566c9b4dd2766e289ed084c0d3cc51196d0b0e0473c4ed274871d5a308e852ea940583e1bcceae094c63b74804117efb2b5adb4350ff7a079d6544107b0046d173ee48d8bd928a9688f09758376da31d8d08b4aa615a85985628965fa804aa99b9ac603ca5e741f3aae062f4cd04f911b7971ae5f4e635db025e693719014797987704ae8e1804c1ef85c9eea05eb8e1209f705888e44631607260106bb88da7016ad7d9813f399c906309523833d70afc81cebfee6dd3a880e6deebb94e341d24d2a9d36be9aac6e35c147d7cf9b28ab8629d53c0cf00696e31e801d045cf4cb54e4356ab2b139aae03995c6f5982feb37ef436781d4a883e2bfc16b2cae77713bb0673d6b4d052a80251719770722b8fbe716cb571fcec8526a201012cb4d56036292af53c321403a3d0eba8bedb6220a0414b7c8c45c0c6cb83f5889b71e8520a007691beae3ac0039d23e20af5c55c8b5b710645daac3427cfbc35d7d6cc70b965a8d1bd77eab484feb6c6a90878f450a8d3a4d7aa02f7e1dcd71a1d7cbf367e5754981504cf671fda9173a42c16ba561b8f6010d8c590768dc1ee7c9edd6eb69de7e6885334c726f0faab0e512b44ac0d72936d76654af4dbe2cfc8e1efe56576714d79e66136d79c57f15599470d007f63b2208ac4ae28d896355bee7eae4a3ec111f6d8e4e15baad7e168176615acfb2741aba23e0825f1b25d807887160284f75f515b6e9b92da03b8368fa9cb51031e05543fc71001079f80fad7bdaef35f66a170a92749d2e9fa60a451e488484f0bfe5a54a95ce235983348387104644bd91d7723b6245d71b5c280395cda85f7270348bbfba93d0e9e14912e703cca5077df64213f013a0be8d9cc1e34b0533d77ddb759f7e1afd5b3edef8a9d5f499d96b774540f808158315b623112f52cdd827ac9c03d455725b9bd034e73a5d483f32ff9ed9e213142547bfb877dcc0877f45c15c72062235985c8179ba18ac702507a69d9f5cfe656495b5cadbd256681a9cdcf0cb565f469f16db63bf7af20ceb6153e2148ac76665204d8741ccea5aa55b9994143454daeed56af099afc7099d3210ae40d8afcd6e54e9830538e7358dd06c4d5fea6eab825c09e8a9fde215dae1311d1502744fe3dd22060a0f33efab2600de56991c8ee6075327f4750c0210e447cd339f6ac80c8e949fad6e768e5382a40518a42d481507495c81027906f5aee4670b8ec901afb1fe778021b4d4c6a611a0b98805c3b09241c41db336e7beb8967a03cc85b1e0a2e442cb7f4a46c70633bfe86c23d9eb8613a33e45f2f82ec09b0e176c8304c89f8bc10539e40f0e2fdc72acf6d9b8673cfe1c8d877e5f52b12b5b79b1663030cebd5d0ac49f0274a1926944d9d1e940a0f12d2f5f36551b19996d05f1db4f29c38741a75fea59a9533d4580a5fed235ce84a5d61344d232642f9455c20b777b9d75775cb1ae2686674565ee5bd10186ad163b8ef1f359ea0d32454d636d63d5d8f7c3132d8f2487976d341e500fab8aafcf4a5db848ba40b3b5cd9ddb4ac3c66f7932167e080e07b8577eab415e77cc36f0105be6a1f214bb53d99cd442af8282558c47ea9f222a83c248c2a7d923e94557919bc2940961d9d8931818b9abfe54cab51e40ccb318ba77922ebf18c2ca229b044d9df881b8913ae4f6dc53c7a4b2e2780c0c726a043dd723e9a362ee701c1c420a0abd6622e9456f7ce80c08917a643c5625ebada52b2a2d1324500d31e831fbb89f7b27afeb9060eca2981d0455588762ed5f10b9a031d19ca5c4ed645e8e2c6c2b486bf97ab5fc64a52cb31c38077d89124d5e25c6d0a34eaa44744c03cf6b8ce78eeeb74f94e3c4dc1629817822af8a90188593d4eef728dbc97210ee08f1b0f92e870e61d5190e046f8b8986f95d3a44b9c379d0c5e0033b81221e2b6081e2f0edf146a071b05bbacab745c629271966537c4e98c407856eb004747469eaaa885af416b5cb03b2d75f3e949464fc0c0a2ce7f9fa8a61b736517c159bdb64cd894f5b09d7afc0718372e98c64dc07682aefb39b1ab05ace440791c1e7e4674da465badbcab9f48983da6e604e2683d6ff90d57a0b70830c5062f4c24cbdb7208ee7dae51b7e360fdea7c83a4f2e55a82cc7e619c989692724ff8f599ddada19d2afe5cc5a3d46632e2dd57a9baca44f0a085c0c968e09931de2ce805fcd622ba4bb39d8a2b4af0b8d99fe327c11c97cddb2a281af789695be4ae58bc1a26613793fdb4bcabe161ce3ec21d7b4bb69df26b5abadeecc706f844a853eec7775bba5234ceb768de58bdad6e3ffc945d1455bb7a9bd3762de7e68c4c4be01d2bd8e285f969e723baa7187f5f10deb1a715ef5082e9185ad4a27a63e7d6b4c30aa65db472e179c7b6b7484fecba1f7e37cd7c122787c8931ec38b9fab62d276dadb5bf450e669f4167ebe1ed60297bd892361def337b8f6129dc33c3dce8ac9b788fad97472cc51cd7b530e6db981696713953687e041d7ce6b76118ddd77ea1976fd16385031769eb0c0accda7ffd225d6d7cff7f9d1b76bde9562b1d958e340b9f411b62c4c1e8da91332036ec4cffb21dd2c04eb7dea59c1ba9a6dc6be6d989073329d2ad0b5a1720e60dc51c33b2007e44dc7ce4fd8bd1f727f5ac481c29f1dcceb297a6a6f86775307addfc339ecdbc5910334c7b7a9903c3dce3fb2b74eb9b99f6e756a1a705a6f49d035803b4febffeaa462d5cb0ccdfb82bda54b544422e7edb20e634f8577bbdb7f927bdf5cdc6ec4fdfb4eeadaa77f02a7f1f084ae29dc85eaef8298782b9e5f6b2f42a1e8c039f44a2f7c5aa468f07af2c2331c1f7613cd641fce0ec14b979dd7fc40036f7eda718bc7139bf22f9eda94074abefb16199868c6139c9605e1694fec69053bdd4fbb1117ff74706ff6d0636f26e0c06871da76e23c1dbe90aa659ffb041614e875d8c313feb0f51add30d81035ad67f7468b7cf7c9727a32bde69193787cb3e7b6153f47681e4fb89d6bfaa803ebc974d1270172c8659a21a4293c3fff492c3ef014c53c50bfcc9d8afc90037be1eba08bf6954f10b8f06ddca184c64bdec2d901e7684f4da52dd3179c69ea726e7ca3fb132af0030ed31a9e4f9a073d8131075a3bfa69113a503ee20d59fc76342fba76549b6f8ebb9e9521497cbcb34e0b81a77cebe164ffb7fcf1dfa9be6e3396a8d46a7e164de477faca660c4817957fd90804509e9b9fdadebd9c3987a840b85b18801827ecb22d05e341b1abf327a739e64f9caea7de54c92d6ec12fe3ae873c24e0df1cbc9cafd7cbefce995bba55934eacce03f2a7b03424a60e81d4fc3df18c2cfe3f3f4e12912abfc06287ae3a75fb181d650de2d562d5a5afae34c888114b7ab752ed4cce1e98891e9dc599aeac8891b09a2580f76c0f1cf2d310a09c7a7c2f4474bfad4afe72205f1d1477a36ee943f45c671704293ed07cd7f68748d03e8468d5948f74aa21195d357ae8f39c0afa17a57c276d77de12b07565e8e294d4269a1284d2aa0763a4236128084141c1f1cd944f74548ce04f9184347bdeafc635a700bc6d6258320feab155e4e1bc4b51292d7576b52aa81fea50703cdbc8ae94a0a65880ff8a0a851704d153a1e658fac0960260a89c5a15184cabb832991b7a7876e3e5b2a3ff40a2e575285fad0251983ed324a5cb01759c22d1b42e66a23cf6fafc2cb252b3f5a84b85c90b086b6c1c44b7ad91448155e505c18181decdcb89f9deb795a2b3468927784aa830f19269a7b388b978ddf7b9abbc661bcc2b40ee7b798697d1b9fef3db5d6d3d9da3071b44f1fe421f3adb013bef9ea818b8aec0567b51f2380d2ec1bcade7273bd5130941caa4131892941f001c9d8964b664a15123b981ac0fcafc40aa1d2d21cb1eeb8758ad0d1d0721dc99d44cf11e34e4fe0169f62094fa7f3876f1df652f69e0817fa68f904f0700f6dcbcb268dbee905e45a5dc27715db4aa51bd39239214d71b95df96c378685d725e78c66662d63f23d6adade0d52440d41c1432c1c3b4e89227be50f75f8ea2816da8d4aff23b41b3c91a6d55e65608e369e39cd52bb63e1e67b74da71a8c30be7391b325cf143cc4824228a4312ed3a8f936e051d973fb7ed066e25105468e7f81e4e1a279213fd16deda047d2f35c7f336b4c818b53f4da1824516a8c47d8de197843211d8a0ac2ec444c5dcdf5692d4792b26433c3db7b9b3315de62fde48886cebd05fae864cbf83f47b7349714a039da9d0ef498c26998348b5e00d29cd1059b058d1fecb4fbd5f5367ac8b3f0a2687ec61ccdc4d25200955e4e23277ed8bdbc4e740d3275e3785da5ab89cb59fd6d59419f5ff27a6c8e713a069f1592e4b86a6be7bd2fe86ce5d5214e5cb65da1bc2f9f36dd4ec3ef8e940e729493c9634fc6b1f601593f2d0fdb20fb4eedc5f287a20356c95662c3decc917f9fcc190e1022f7b56bdc2b4d5dd770d8c10a935f2b0c740503e8b6492a358ecc07d398781cc031a91fb6dcd0f1f2288a35ff49f5c0f7b894f53cc89ebdb7b47293d452eab6690389751f8f48ae4b662817a5f1ccc24f32f43907524f897c0ea50a27475f8fbe8c005fa00e84cc1c716d7568b039a9686887420192ac1a6d8106dc77b9446de6ddbd8ebccec6b97a733aaa9b520e0a345e7e4750d81fda6014e6d5918c9da8925973f9a5ad9234d54eccae91e048b74f8ddc7d4db6e1723b4e1a49310970df14955f31b7c8d6da75d25adbd1fba7497003a0f6316f8d325c18b23194767220dd2a6be46c52aba8c70d492917e329cdc2c8cea8fa59913a2cb86cc0d5b96642d20e375909a65471d3f75a16845e83a4a7a6ac1bc781115d30732f5b340b312fb2d2dcda6c2007fa25aea1e09281c69739dde03a2f814807e3bac577d4a3c83900b9667ae25cd83fd43522162d68f0b92e79677023531176987d0f58c2ceb9eac0e206d2ea8cae14a9b873aab02b450513026c1143ae8de43f4e79a135133e99b9650a37bf3a235854fa52ca44c9e0695ac749b286a075d8b2e07cc5b13058bddd91512d4bfaab850c97710e6d33252a714c99888a358ab91d2326d3689f4a44a68352da9341d27a30d085c30d25efd51b5e51b85999b0a7c20122885eed8234142f7740e4c0deca61ccf6c81db65a4b3dd8d603ab7072f1f83b0736f987e54957c9fd0ee0ffa7313c47084cc9b0f575f4fe607aecc08f6987c02d3bcd3346b380da419a54f6eb08fa6c1800970a440219c00bd7db34a9c41cb693f65a8353c607d45944a05473aaea46b24fc58259588568e8eb6b99b89230957c21ad2fe6f6884f60b37ccb221771e856bcd125da342f28b35f7efa0ef3e6c874cdc5d839f63e8ee5c1b41f07ad2ee3b1634bcb6090147d12f85b5f8a6987eba200c29b85c9bac25777c5cb8978dcae30fe237ecd2258d0d8a0ca62ff082fe6416f2ddc42e09fca945a9068459ff18f3e7529351cd6d5c2e5ca27a2e4d4b39a52c5ac24996e65652fcffb271071525bb4b1d7346578c561cc8ecf707f409d3f22a376875fbb85328f8ca4b6705312708f7c519f254a45f554d69c922c870160c3e181030f5be1951b35968bf5d1708a914a9fb8c5522c82d119c20faad8bc3c13d7934265a1482962578bdfc8408dfa3a53789082e19b420a6a5234ed6d34852e674a5365578eaec72f8252d84c100c086ef0c6c2291e6602ab840c81ae7b6d7bbfd9feebc741eeb4887d9f6dfea2f3be9b35e15b2cf0cae5166a366eaa4ad7053087b9629032e2679114aad403bf51d89fb106e76b88754c6c423f3ef5630b04d6b9cadab93d500d8c74ab9eb17afd9199def0affecf8a72296d8d19bded4d4441080a61c27faf6987a4d5cd1833e5d9acf6778990cd299fa24550176e446ba80d71ee9fabc1b569a1f8cb3b69206ba96374c400b50ca15c03bfabbdd895e5ab31b2d97baa48e18670828012cd3edca049b15e16a6436e20093487c1dc34789f2816f5d3ac8b68318339a8b02745bf707df177ad041bdf7495811531d0d49763b2721c991b58a38cd12c265c82e8c3ee91931e52fa3af16418a233f2c388ea3cffaa69eb9647a7672aea87133445c70796c2a5656c725d21959a746452d3b6019e2f22b0c03e0a92b61c6d9c351c98b638d12ee8234a1b52acf545870d3124b9c3dea6f2b3589930ceb6bd6cb9006326fdb032bd457a52fa3d4c3529a08c2668d14d1496efbf0d4631ac2bae1698c370cb68d42093ddbf8cca03325140c346fd98f4b01cc352287aa1bcf8fe15502740f470712df6578488edf163483e7bda6339a8b6094ea3dea193201341d1aba1f786bb53668d834664d8d48fba49da1c44d34f260b9942ea20c6051738001855e4f3f4f7eabe8566da431252d3c2a3f585928aba3c842e6f57fbfe88d6c1176f2ddb8e14b39a2e52ad5c156bfd58b8fd08d98c2dc28fd91d3afa6dd3b9cdd0a5ecb7055e61c03b2fa26ec4d79d111dba41888e8d3ecc6eebc25c11a6a7e831df4deb615119a232e824142051842d4b60c210e5b5924d93c79a8ee5a13b64189328473a71615845f5a87e346516f4783d3b293e0d3d3d4fb3d70bc230afd74384cd1ae5d97cd2c2a464e63f9488aed918d1f1e1f66590e69553b14ef5a2d1cbf41e4314b625bfb40d1734575289332bf54a1a2fbfe69301ca4c20dcd39e8cd0b31e806eb534237a5f6b85b6f29520de6e55a200a8ff0842db5d3994f82a16c42312fd47d857c758e4d87d9e5f2665009843a9f4aaec85909cf262341d4a9a02599ae95a011d362714639fb6afa649739a477a746589a1e6af90ba2f4d4e888a76adfb4452501d23b89949d7a419955b2a9ace9da5e9f760634a940aea627f5bc4a054ed7a38ea91f449598ca1caef7bce4310df3dd1ce92ab8f4d6ca1953e064eb9f843acc876369013df10a5e2695cc597ddb403b09b818ae582d536f73cdf188e76a415acd0b56af575648a3b2478cd2c142da2bf8ec8ee118ca8e76bf762c4607c759c4dab6a41aecc21080f1eb1df8f75979cbaed903430c8bc21d1b4e04cdae978846d2faf4f2412813233124dd02843807f0bd312f483105974484aa33dcf78efa6a01a1ccd146cfa5a8ee86c572f5bf03080e92dc860c0c9163e1592168c2f2449a954ed40e02993495b866a74f3c42dea7f18bff5488ec8bff9d62dfa1fff6ebf84d3ead3f7d25d8f97b7d23cd3fba751848770aefd9f1e3ccc0340e3d78ddcd60081cc889d2c87868a95e486f41c5eeac8fe869d8e8020ba9e418c343f1044335d7f00f54c16043d0924c3654e4bab440bdacd3f03da19dcfb5871e6a3302ea8e652c5cd1aa290704f05be76d9f80516a61d6cf526590d1c0c6bc63692ff5b3953c1f98667174229734c324a9a5a11a540688736ca9f82f623f5b80c18d5040e8ec81e0177ec838ea2b2c9e94711f59f282bea8994a71a3d488965802b3225120642881b823fbaf8dffff2f3f31ca0837577177b2293199df9fc9f0627ecb5679a378779b525d2929693efc3a2cd5364a19b95402ce216188e6716c40676b108e4bedcc3d85f22237c488d1658e094929830f718ddc674c3a1953483981c90f3fe04172327e163ce39c037ed01d17a377e7919bbf56e9c77d65855916691332f5fb99860eac7115bf394aafc2e8fcd308a0bfe5a69ddfa9a35a363713b155f257d32b585913cca2a5de76a01be6d7020afe8c2985a17963a13f47aeb25e5e4e6b049cd3720c66ba1a76474130bd7170f8830c86836fd26fc422dec04df3841e287fdab87b84598ab223e2bfc24a44ea6a9696ae39e2034421e6002fef3e9fa652c5c7ab221da74703ed9e805048370ad1399342e7f92c95c274e8adabaedc995755352930266cdc079846837f29cf2cc044f8ec8d5cf1650f7083344b04a6288398d2e079903cbe7d013dc77da7e17db4f6c8c558577662048edb5f7451d33737191b6f0bf153a8f854c70264d2e5ea449945ed878a042e5f50b13c145b9ae7c48991d492295ab4d71b1b4a24a142522d30d0c5d41250945dd5a3627554950aaf9f5cd53aabc753e6ec4d354b3ff45f2cabd4fb8d5a6b4c39752c9f853e68d1395afabb065b6230808c369cada1cb4a766a2bc4760c2a40072f356ebe4e51c6c12b4b2088f9680a2addc66483c8bf0a18c91276edaabc89f8bab983a5947c2c3132dd63015160c3eacabc0455cefdd50589a1983f86a1e9267be6e67b17410cadb5889d9912420ab402159ccf2ab95d981fc343b8a7865a24255746e628631349f60cbcf56678b7da37333f4f4f9206efc841bc70ae38f8d0309e13f9ab71d9fe11dbf97427bca22c1c6d1ad4e1b58759b07265d5df96e470afe3b1278a0c049eeb5682f610b52cb1d301d4a126df34f157fca8a90c36940ac7ebe4d2cc06ad30c9a829a14a7bc33e41fde3328e5b6c539ac0e62f650008c967088714bc5eff93863e2540947061c3a1e8ca2cf2bfbeb9996fd8a2aa5c8453b6b7e216760510fcce0de6bc42408484a9e7fc4088609a774029ef3fa3e2670e640e8d46f0457c07a12118a7cfc54299b0ba8f45bae611e59563cc84ce9e5aa0f5ae48e941414b77022f1b5c2f35c332081aa432760d2f5c11820badf2a29fe2ba7a11426380f12c725340edd3397c037a6d7c34c2e14bb13f8ee9237aaf84b2ce7152e87fd53cabeb8900eecb4984e3c53d3b78701f6a12e491d52d011b88150a724a09d1b054b650c3aac0c3c27125d974891a6314fb74d5d95963925d2ef190c518ed5b81c5a4ca80cf9ce3806eb3e0865f4468ef20375d57155b45ca620de157bfe3ad5a6c8d8fcdb4a07cb9dee02cc55aab5d7815189934cca43226d4c42ba847f642897ae628db2828fa64ec02d0cafc76a1a317091112495c403b4ab3212300cd60ebd6ce00e68ea949c98d6af3958cb014aabc0c54a754295171940b2eb2348788257715c234398bb23aab2af109bffc23897293097e46c6fa4917d462ab5689af168558bc7009595c964f1c6e650ad452f812b0d6447ace530715c548fa47a92db4d9ac8211e684c46c27ae7cf1d0b7278d5fafd589ac443be54390c699ecf3b065d79f1897363bc787cd7b237d2311e48e16cf37448ff356052e2657bb98e3175d06959ab50d9a7b2c9fbe497d24caddc3319690aee03ddb15428d8f0285825f20a41a78fcf26f041ebcdfd0bca39bb484c812e4e7b527e607fefadfd8d6355dca81ec761450d4530ff201399d1b4149b35cfcc23b4fb37d43924479856311850ce48ab0a17f50f18a53084e1967baa860f0f77a7d07933e8c89e24a55900554586cddede1077e4182637bd904abf99bbcd7ad4ae09d1dcb3d78a2772e93149b0c85b464e2e1194c1f059bcc98e3dac5ab705c9ea7aa6d06a58ce6877038e4431e5703a5b784db5d2b4ce97d84867fd4be3c3967de19c3bf5117cdda8a7b1ecd0ebe94ae2778d57c545ce9bee9e48c896c4c815a5678186a016e8d16ca4ba990b3549a9a404472dc98ea13f07381ecc2bfcba90b4152152a5e8e487397bc352cba7825ae28a684d66039bd53a289dbeec4685a5458223263695896ad377972113a3505ca33e4f7c20862572627ed8dcc9a456f48b6e520b04eeb5bae2b15cd8f1662c7f97d5189def343ba281af007bb13fe8ccb5c8ed63e40609198388709014bdc902051d995fe99056b7c19ca4bcacff920ee977998ffef4c1835654bc832169d0b33ab8d0f8201fdd5ef42e8f60cf16ae1978565fa1bf0bf85bf18c45a8c99dc23ae140662799f242f73da05594c2ebedeffe524a3f67f33a3297d86fea2ef8f461618e2f410e2f27eebf3e44c8a23b23a6945c90fe17b4098492ae8f4816a45025821abab08a91b11be6621315e8f511e662290fabc8eb66b39244f676e55d568be2bfdbb3bf647b8d7dda6525be5a5c108c1f4d3ddb3fda255c28c368f0c4aed479010641ccb8300ff8897414e7139e026534b27637d6e75ce6fa6e5c51b353d779e6fc41e5b8864687c28773dbe6348f0a465dc9bad950c76b64cff1f267c748aa4d0d6b281a9174b41f2a41b52264ae2336d3ed6c5e77c4a3a6984752f31280135011ce5dc9a6d4fb1d0486acddd8ee565d9fff27b405278c14de81f95da454715857a4b97b94083ebecbca3586fbe08f258ae905c2193309b3e81dd6c574211cc78a70a68304b49ef300e571b2a3c085bd2034653bc76fd3a6768e4eb50a2a64600501e8ba568212b6c0b2eb423d5d07a5b5ecaa6570881b731c4c3d4a4ee3a9cf20a313276a8eed4c7ac9a84a898184ddec6b2081a75c277bb15480668c0a6847bcf043fd0c24ac02d11e6f207bfd9482a40f65e7a397a800f64eb166abecda30ad4fc6fa0c75069aa537e868b1c09823a9b8cef7f5ab7e0dd87779003f8dd2e85eb32f1e4e8e771daa7c4b0d6ff0eef4ac58074b4d18d653d301ba7906a7bf1a4af0bf113cc119ecd948d702de985cbba0c4c701c83a4d2808b202f5eb6e529c16c14c877e645a62bd43cbfae989ade73e7a35a91123d12ecffcafff8a0c8632aa19d99a10185d6d076d6e15e298eb58d8a8e04b67e34a1e8379c3b95e9b248a368e011a05ec8cf89cc7bf7e10a89b28b4f4b64e29d080d8a58d4779f0b48ad2049d91555277f1ad53d5eedee020f37e6480e1ebd5751ff2ce004ed8ae64c82c5562f5a731ab72ffa0c30b7b56b96a4bf997406a94a4d03167882be1a9a2da2a8091c5859c96fba3b641a4f770c39f1835544e04e2af16667d3d5d64aed4bd5be0c7e2a8b04727efcfb92b755d27d2a30c3f8ecdbdcf75636ca28505b582581e39c953b35cfada2c568c41893f580077c8c784f6eb4f19dee35fd317a7cbfaa57df879d20a9f43d3a15af78823205ca6853a5e5315d593e1159e10f0b2aa1b5529a0e7c1aa1624054291545458cc2abcafbbc9f0d7e138129acc201516a4ed5efe042a8ab6344abd3f7077f3c971f8da19c7b7970508052b0199c8efda65401bc419e8fb252fc78b632dd6e84571a13ed5e30406f2a13f0eae74f589c91b084ad31e6c6e59503f22c5a833346f9e0364bd97f6507fbc15e5a4ff3e5e7f725238fea5cb5e8cf50cee3599aacbca78f5c5660c79ec48abd2bce284b4c221e991827f6363a921acd9120a233fb9720899653337b0b725f12597f3f3831c7012016f67e01565bdf1bb31a93e93d85b4bdf1287bb8422ae31295a12973ade8b5aeccfcc8eb9d0e342e0c638b7d9ffe4adfb3ef5ae89b9590dbe786e6464e50818795d411710d0c4bcf7e649e51e35af3a7d6fe093191e776d75eff14c1745ad09e267ea1c919760edb52891db78abeb97a87164f703dedbf25d9bb2bb138767cb7d4c416cb1c284dce9e54022ac6460137d72ad6deb6581e936fe24aeeba7b160f342a3fcd9d65fa729e1beaa2832adabb7151dd554081054d990950915b56bcddbc07bbd75da50e08d20990c38a2cae5c68e94beb774599bf6efb5cdd24e85017f633904e41ce204cb13b386d70bf568cc650041c5c7c5b1a68135661bbe706505d04df00fbc51ff5b2e6770b9a221bc2058b39bb5e7e9d857f0ab7f5a1e9c9bf04ec00ca484b0761a61552372115832d4f06c3addfda2af737a0a71f725ba73f0b70f5e6765386cc88c9ea1c823ac9cd8fdbb4c4088136e3b06e2793a6a6f35a297934b82e682f05589fb64cc99ee21db4ee90cdce3af2bb241fc14bede9165ad9324aa545d51ec6b66e1c45924a54b746e676a463ed16d338093c91fa754fd694b1ae3511eb776457adb2e28b1499ddbe170b34fb5c6e6ce180daad90ab100df15dcdb3c15b679f46e69086b39860700a0a199500968bfdf95861b8b2b2936664b84404ba51294ba1e2ec9c83ea4344678bc976d50d6fd4d6de9c3c8e09e047e2e5e515dda50e01c00f3f5acec3fa939e3dd2c991a495e094b003f478b78722b01bb74fda9b5cde745e34ba37d9e14e2e6c68f5728ec1711372912a3c926ea6e695dff990d3a1c63d391a80ad0caf9b0d1f3237801b67e22b92c3325f0f55868fcc206cd7f0fea8ea0599a2c5bf5653659c537270957e47fc75922dfb61d02e70780d24aa49fce41f2b6382002a2df2c849e40ea40472005ea03cdf70afdd3af2e82949ed2071e4491d3948b8ab9adf5914e23772ad57d0a783949c43dcf59d408b875b823dda8124cd94b625fe62fb8a37316d8a71ef1e8cd4338c69dd1316e921785226d9546cd529ae38fcaaddbc1e4b9ba4ec87a2a19eab2df00b71d1db4b8743b86d1bb540be10de12197ab2e197bc6e076af99d8500f4c8748d6b27c473f91dee208ff3536808edc49941cfb2b080b58da03aa9342a25f1a5ea4cf67af09f768e3f7cf0ab08306dc1efcc781e82d77dfc161055c51601610770fcdf2e921c249a79b9695e8ec30221bc5030f5aaf097062c47dc3324557dd8cab1ebd60d112182844c4dbc59c4a8ea60a814cf9e4a483e867022b993cc813e51a4a6a4dfd99ff63a5a969593480b7f8702c39b876bf0a65d5b5c162b91fce994dafe187cbf6539697fa770c79110491dba03dcd2fda84f2864268dee3a098e13415e1cfba71cc3f5135a3c62301123393686bee45c5fd582fd780dfe60052870e62a6d942ff1eee33d4cf79e1288df8f3c3d374b7c7bf52e124335a83971757d182bce671914111886394eca3c7471a1c8fcfef7f624b35be8ddcd2d6a7492ee772b705358a5a6d128177ca484bbb97add08c7e98cae1a01e48fb995a0cdc26e98e6e12a44260f4b8f6821c217028aee7c82d0769f8e5030de5e13826c648a2d10c71718de1790cf1de843478637568766b49dfed514e6ecc50a4a11a9fcd6eca1445ecf5f76a7f4b4313ed052b17ce8e368bce434d095d5262a670826160cf322a344094bbb247a843d229e724728510d1cef92be6211b191c1ec85b57c5c634af531a187cf7a28078014f0045a04e94b6a23415d10487be6844b038c3516cb5bc81d7c0ebf94d037973b7990d25d8b11e081db70e9bebf240c82381d6e7d21dd72169fa925de13126994417dec31ea333874f4f6016f57903e69e7565a8c29626247cd24c61586c5d6a3b89b01dea61d35c44e1f22a3b036e1ccc0aae7eb029a4dc76aa2b474feb7e901db58a9c3481095ef6f16c1c20704ace0f34f4f8500843228245c559cb0ce0c3aca3e0ce32ba70c136cac1532a87b3e0b4b3daa8f293a88a007c386b03e4ee96867b7bf418e8fc06c21a6df810aa4390f32893e04cee17dd1e8cd8b359b1702ec8e04caa5c4d920bda35fe8891cf36a01a87a9479d575be247b9491b4f2b510ce37f133f3c15e848abd08b151d25c34e5962d4d391a84d9adf384723c9f2b90ac5ec53adc7d0d599f7a33a62ed942ccbb369ae172942a99932afa24df819486c36ba883b5eac9f3753d9bae25f27fff138d918c59d6a7084d94d6525bac1a6369639207c2e01f0abd09cdbc435bcab512039b096ba104455bde50a70289d03297ee470e1c3c426b0d79ce66da2535dd231d098a3e2ccb21b71bc8ab7a37b0be721b913b9eb3879db8e9989df69670b2ca16984ed845b1f429e14ebbd9ebb7e8a9f912eaa749c86ee125fddb5c6830ba4f48f3304925c52a2adc2f25245ef806810dc86e48498d1d0b20e86bdd8e85b680e9284d441059e31448a0c57405c15251d9b0b6584ddcb9b9f40dc2c5270be1dc0b582a4e24beee834f6cd45e15dcfe741b8bac00e033a9d5c9c073d52bb62797e1bd6281bb725adae948d83c3a0b837f88ffe2ffaedff8d10b2c926646f42f6967207820cdf0c3a0cf0ef97f531d9d1b4a3791cf8779c5105ff1e040c62fa75238a503c4570a6bff7ec8ff76797c0fe3e5924de0ccfddacefbc1b959813ce64798a6c399896c03e1d52bf26ebfa00d3d2b7f4c1412c1ba90f418489c8481e4e7f38f0ed6e1e1ba15ab26152b13f99eeb03ed2b151af76c039e7bc5bcf68872d51af2a08218410ce396789a2aadbadb2d0babe4e0656a10b4daecc754ab018c39d1918c0703729df7b520937e268275c8cf779450ab487857d5668d2bb01b4d0f8c9b3b4274fee73e2bebbf760305c78c9a4e28683761e8f06eb1e35862082b6f2118f958f34edcdbcd77363372d7b7fce9652d336518addfa9f635aa6f165aafda365d946bad70e75ed26f20005d1307b7294799aa6699a628c71b4e33d3eda52fcdb44a2e92ed3344d524a598a7f8e7267f7a90cae09163f261a3c11c164674327e7b7cfd1f9edebdddbd9d0c989b9cc7374622ef317367472600e80e7e8c01c0087719d9c97939ea3f372d20370f7c9d9d0c971b9009ea3e372017ce6ee94b3a19333ba0ecfd1195d870fe0eed1d9d0c96939019ea3d372023c864e0ecb699ea3c3729acbb87be56ce8e4883ee3393aa2cf7801ee6e391b3a392bdfe1393a2bdfe106b0a193a3721acfd151398d1fe0ee97b3a193137a8de7e8845ee33536747240b7f11c1dd06d1c0177c79c0d9d9c9427e0393a294fc06fd8d0c941f9029ea383f2055c013a399fdb3c47e7739bf370f78fb3a193a3fde6393ada6f7eef8ee26ce8e4646fc07374b237e00cb87b8ab3a19383bd87e7e860efe138ee0e72367472e87d788e0ebd0fcf71f790b3a19373dd01cfd1b9ee80ebb8bb8ab3a19333ff80e7e8cc3fe03beebee26ce8e45887c07374ac43e03fe8e454e7f11c9dea3c0ec4dd599c0d9d1c79093c47475e028fc0dd5b9c0d9d9c789ce7e8c4e37c02771f391b3a39d483788e0ef5204e019d9ce9423c4767ba10afc0dd5f9c0d9d1c78229ea3034fc487b83b8cb3a193f35ec47374de8bb805ee1ee36ce8e4f431f01c9d3e067e81bb1c239e81e7dcc5e0eb1891016b83812f5cfe0578b8fc22bc70f91658c0e5133184022e5f082c2ebf024170e1f22970e3f271aa73312660e3f225509d8b1181ea5c0c1ed5b9184054e76240a0fe5073f90fc0c2e5efa071f90ed07180cbf7a1f27354e762f4507118e0f21b4085cb67c08ccbbf99c2e55f1b1e162085cb57808ccb4f40142eff06012edf06142e1f0135945c7e4de5d378c2e51f600097bf83010470f9339c70f905a04972f93208d084cb8f1180cbd7c18acb1f00002e5f00d5b91833302e9f549d8b1180ea5c0c00543e8c174bb8fc17f672adcec5784c6d17830f539f8bc17fa9d0c5e0bbd4a9522e06bfa5461783cf22aa958bc15fa9968bc157a9d3c5e087ea55a98bc14fa9988bc147a9998bc1ff68f5e362a0a4d00aba6a685615abae5455242b4bac2d541d4dd505d69757615c0c7ed71817836fe4f26522d75dc70524b76fdfa63bfa760f06f81aa2640b503860663742bbd3f9ce3516307b195f47b3f0dee69618f19e65f1a8de4322e9370dc36ab5aaaaaa41e25d7f4f7333ef9b0ef7598babe639e7ecb956ddae5d691d52efb9b236163752366f82f6620e32550129abbd4841dbb4bb3926463c1ef490da6d870bbf44bb5b3bb994d27faa56b3da4cbac6e6cdc0d3c320874ff00d8a830eb911c417420835b7438d04e8702133ad1e55550e7097b2d7ad3ad2ade74a1f515cec4ceb46dd9a3df79af1565c72a3bd9a449db24166c712b81ae866a64b09eff442449b1e74179e456e86274ac10d521cf1d72545c147841f5399734025ab3a511c1643b6183ecbb29ec35deb3db7aadbaf1155bca35cf55c864fb00c88c58597e83e2170a1053838d83458b000b73efc0e09b8b4a631af8326723390929ae4ac8a45a026318d9e26b9252ca8aaea49596181a228263f7efc20810228036cf0f61694525ef2e3c70f14dcbc69a25890523e76337cad95400869402674b7836f8210ba466143df08e9ee1bbd0466e625cc39df162f7f8b130bef319c3e31333384ccd3bbaf86e6c78f1f22b0e181be900fe16b29504ab2c0c5754ab0c0c5ddb2fb3e80eb946001c9bd6e82f05e3787e74e87bc4d96ef74df1d7c772e01407e13bfc10544cb843c5f770057802de265937a380b6ad2912619a982b6818e78f25511f52446816ff0758f499a865b72b9421bee7de7e43a1b9589e09c1ce973f70da0060d3af7d784e1a5356486fcb89fd838242da0dee4ba707072933bbfc1b91438e79c9b40aeb198267745189d83939b9c9b1c1a20cd856f7aefd07dbbde5dde7b50c67f40c628ad7bf08580cac08d7775ab0f3a474dd334f5a893538183d3e426e7603ff15e2741fb46e3d232cc7cf5f6fe450a82a32808a769821042072737591d7865a301baa9b2ac673deb3de8a083ce49e8de7bee35e1efbdf73e2e46bf7a35e9d51cce5597215700b2c375b7c1f7d264fa06d3aaafde2b5b72af3e39e363f0d3a9779bf7a4ab3ec9ecd7d67fe75759756f46627583fdaaf66995f5aa942db96f3d8eb8aeeab7e448361d6f21c99d0eb770e44e7f525cfe34f5eb77d76f0262faebe94cb9535b0f6d1d15de39ea7dc2716f06deb925ba07f68f3b7dbac8c151a1f290122b38b9f32a5ddc0981500142abf3afc6bffca8fef283ab07de95fc694b7cf996ea95dd42f7c0bba595c7ea53d39ca4b487927677276b2c557bac7cc52574cc672c949eaf51fa66ac1b12b744ef6e123d3763518265565aca28d367771765d4c32d597777db7997efc52cfaccea16e3afa7f427c56e71d341e2c7c5727a62123d77ba6367c1463ae6a3f6684bd9a9129a769b37afd5275bdb70f8c7b53eeb66c47596bb562f4bb31bffb06ed3978c58ca67dd2e7a5aeb30112d8fa7b779292828b7e999d9e9f15d146aa73b8a92833e2ba1580fc01b3f47d847299f8f47b95547d8adc7a9a3c3eaa0cf3cf06eb43a342037da12df7dc59e8f52f9c7bdda8febea59e54d77a83c44044bed4b4547486553e26e3b8f863e1fbae2ca634aac30e4f2e32710a1cbb654ddac1bdf39aa382d6779ac9aa57356cd6a382c9add7ad8b13cbab35801c8e52b54676812d172f7662287aabbb356af2aac29112d76e66192bac441e3780bc79644cfc5ce9ff4292db5e7bc3624eeccdef28973ba5937256e4c89f351c7bcf1da33fa99d588d5f8ac629bf62d3bfdac232d1b6516a725746d941d7bca631da1fcf3f819aa204a67053d5427684ead6ebc65948ea8c569015dfbe7f433a55e07d51450bd522e1dbe281667f491f696b37cd32c4ecb594695e5594b65798c1fd5963b8a63b71e969d7769ddf86205d8e11b3f6b8f77a3f5405f1738687cf712028d9f137f5999fb07a8595e30a77b13d6e9ae42bb49ed3acdc7e5f7b6a21cfc76877593443cdb3d6f896e7682a4a6699244444b4dd12a71dfcc43e271145e158e009151bf1032ebc898e31f0522badbaf690f73ba20d5d1b04f59aaeae0f7447be84d3a8a23f9cec1450eda7b03f1babb690fefd37d9bb644673df0f9f015561cf95edd341c67e59b71b7e9066246850248052c6ee61c33641dbefd77ea3bf482f5391dfc69b239d17a60035bcfe524a6ef4c77b2494cf7c0e74e3609fe0ebd0c7362f719648a902942e688cc1b6464648a909129a2081919199937c814714d4646464646a60819262654a2d4e79bb2e5c45bea333f899edb9fa199f2d8f259314dc3306c4e55555595defadc41cb7a9665536555d6b34a8fe970298e96c7f99489a255daad4016aad8ed17866cf551a5448ceef2e9d22e1fedd61c91526ccc8ed5ed5d230c04023d87bba0f7dc941aeb66c48d6cc597c58f268f556a61dd706e555977e168fa439f4f733de106cde5e57fcc61bec10b336756fb2b3594edb83e3f27477784be729b4e49494949e94fbb8d88985fb1dba8ddc5b93837e5d3662b2fc3b0cc883b7de0dbcfead5fdca6489bc566ae87332d591f21596af6444e870431dea508742a4901db1d8ec2b0f7d5aacaa3ed5a7aa6ef350e68b887d3ea7f405bd3ed747b3d84a65dd8dcd8bf401b51fa90ffdd0b37a3dcebab1fcb24350a1b1d895b6a5d15b6ca9be3716db43873bb2ae497fa8deb5854dba7d0c0c4cf7cbcb417f61f9647969398ba8e52c2f2d2296378b8b8b8b0b0b0b0b0b0b8b1bb4f8eec9d7a33d408af32e10afacd8952cbb40375b32e4b2bc552eaa9b0e17e7b6a09c8574594e9291f9657171b92c292ca0db2b2c2cef5eb1a1a784588ec272d735f6a1bbae61b19bf696bbb754ea5add7ae8a0524d9089b07ff1f9827a313afdb4d3ca8a5dc9b295ad870e239bf78974078efd8bdbf47cd12f8e52b7ebd24f5bff669802d1a14f9defb29fdbf47ccf65a9db2fcbbbaab45414515db9a3cd524317d59edb2ba1ab846ef3b47f6af61494bad5b8f487ce74c0d1c1128126a3a2f7477a52d2b8cc8adeff4824dad0066d70f0a2f97cb22c849265343499dd785ced9a4d7c05df6840154e730d98ba7fbc9afe215d0cf9ac8a9a245f5550d5ead524d933f2f00de01b950e57ca59c554a94f9926413e4d565dad55de48f956a6478d0b738cee4089c2094e5c984ff91a03f3179769523706637568127c65e9702f7a6082b6f58f66a269fce8261a48d308222bd9241e2faa7b79b9cd7ba99fbbd42d665437514bdd3496aac3a2aac32b7583f02a55876f4addaca354ad49f09f7ab9c02a4668c1bb69f6d94d4eadaff6acaaaaaaaa9899b96299173000f0ed01880f40054085515f54995af1b83d68aef58dc765773396cc56ba8841dbfac7ed1e5c7848baf0ce773d8a8367e5fbeb73af3b57f3e25b75afb3ab81f1ebced9b07e1dc68b1a2f53630f21f50cae7431228e8bc4515a7869ae2523232323737e21f3c2aaacb4b63ad94660ba003098dda02db48692493077e0b6635d2677e0ddb13f3c5b9a4a3f949e183476e289eb16973004c9020e77f2c8850bae6664790a9730f0a0c925d3f582046dabf180ae31e2c93f99cda58611af86ab601f584a0cf75d76a1044f8f1ea41bef22aff8caa55d9a04ca427357da57a56aa23f843edf450f9b86d456ae889508d204cbb84a04694264bbe02073bafce532c8cbb36f6c248817179797b355573eadcb0aaf109ee2d5b8b85828685097563e5ec60b3982b6711026e2e52ef631e71b86a249ef3232ce5197ced160b9e48265bc4b79171929c352f98abf3317a0ab5876824e3117f73d17e33db3427379761ed234a47c37122312816a806ac857f2b138777d3e1f27ff612371076573e06374974b215cce5344da91dd8eb8526a9f4c23006f69a483722e9507e62391ddc14f82872bcfd37313731f3196df377ce303e63e6efa06e6361d8197c35895694b2ce45aa2abdca6276559ca2b458e8a4497f70a71a8e25adf7aae9c2e519517527959b56b491a8197cb1aef6427ab3ae25357a9d665dda49ce7af94445ff9342fc7b8893ecf627be05be5958fea5021e2e5b18aec26e3eb262f956abda9e853aafc454a7e5ee63c6a3abb2ba2ac438a634abbf3ae35af95b931a5c44b0dd5d06d5e751db4812e4adde4a76e4fcbea06ba1ec8a5654a29a7dcf85a2ed2aa0ce1cb0fadb401f85f8784872b1f5d5c5c5c5c2e6d0e40e063f4256e1ce5e11277a0a412e09b963b9a832f744b2caf749d421b8152b20b24103438f9015282246e08013f794d0461204d3240193477b3319046f918c0d5a0d81dee33efe626175844cb394682464e48bc1a0bb899f6618b30dcfaee0e57c36a8083ab820f4f5c127715fc3dd23719974bab77c59be97f0bede5e821afc6355ff1b40c6379cafc848d3c811042faea2406e26cbc2dc6927d9f752e065fd37ad4a9fd4946a8f7fe57c3407ac602993edfe49057f3e16e620a2a6e9f9d111c4ad0367e42a3d5d0c5d691d5c04fbaf8fcd53013f8095c85db408cc4dc8d9fd827468c3c79d23f1a481aded022e813340b2064a63e9fac539af065fa2bb72f59075d13efbe5d35d1f6a052bac6d5f03b0779351c704eb421bc1cd138e066fafdeeb347b818fdcc0acddd6ca008291fde4cf7abe11df44c7f8a67194712b4cd39e1691a0d91d891a269c47b04121af557c323856c62e53692dbfd265056a2c10d2cc5abe1769775e06a2e20188109b7efdc13dc11386493667541768de580ba4df30ca21df124e6eefd04571363398a9e79bfed2adcf7bad2a0862dea24133349f21e6426a2b7920464a1adde76cb78688236eaa1efb40257fe6e73c4ebc21259274abc99770b0a96f17e7dae549777854a6c5a3314f7bd690f46de4516da95b775a92f4cb87881029349492fe924310f4284490b1191cb75e9243fa4d81cf8f863de1722e63c45fa8f79c395d15346319f1e739b16391bfdf782bc99c7415e0db758cb4144b6e99dbbd13b6019efd927aca1a77017afa681bc9a4eb203bed15c7cd3804cdfc14df29ac99be1826f7415469210e1e2becf5055b151e20887643a51a91c85233d1c9fbfdb387784745d3861226d803268bf119b37c337946019ef9a91fbcee4deadaba87cb71bb8fe53826fb093d17f2f44e4f5eb4747ea1f4036073e5eb4103f4f91172fac7b33d79ac45b8abd9ad436073eec8f63ed2d4f3d098ae4f07051bec48d4dc75bcfee9a26fbd41d91f72cca93e0a1561ebe89f9ffdbbcc9b4871c7ce06f9b0310f888b98f1b4779dcf2f44dcc632acc3f759bae66375026aa1be8aa3a5cab4eacefd42f1269dab4c58337af9f8cba850a2eb2c0e2beeb946471c57dd71dba9a94bb5bc0d5a4d81d14bb1dc8e72ab8dd9beb82a195325a36049e5d8d10a02d7808f5be109a66339bdd78cc6ed96d245c8c3e0f51681b0d8d9452ca438b5dccadaaaa5ffdd11efa4224289c77cf6e3d48773ac65bcc26b2aa0edfda4fa6be46b49646b2d0848af8a369b82c80c1c97da7ba681a2e0b61a8223271df67f6e6af07f1b9ea55aff771aef7a9e5e1e951428823301f5c1227ee0a9c0c9e477b76687140a183de73b3b92e46f018c4dea776047d8c6090fbb4d77833ef079d873ecdf2884036b33c24ccf2f0c837f31eb292da11dc48d7457d183ae83eb4670f02747a6a7d840ebabbd96a10819d86ea085a504d795651988fac0011591e9662c8112980a8a4a000d978c8cadd8de82defb961d9f8085f3b287b0f599e22ec440b591ebee2cd3c90e571c2c349aed09268578438e3da7544fd73fe5547941d4560be1fc447de7acf8d4d8f987061076a6003911f3f6eaea3bc08cee7b3a59847b13c0da4a51872dfe7b70632440a953f209f4f8a131415cba3f2eb9f8f8aed2e3e0f488a2501dfa0d82e5a5844d5bd19edce89a67deb2e427737a1cf53de7383f2ed0111bdcf5304673e749e22382b9fe701c2c38d8ac8f2887e3d642fcb23b29de4cd3c9e3e6249c0372a16f4ad8f80ec887acf4d928cb23c98e8b98940fa8aeca117c101151945e07a769cebd990fb7e1dc1b91eb23c6fc8651f488a944aa1d4f8a95aa5bab8bebd21d725858fcc8e70b063a73c2ecb03a46fb22f717aec7d082e68eee68a2b92dc97591f4bd02745b050042304f9313fed085a1d100804f266de47eee268d97390d9e764522820427531cf37f3ef70c89bc1ec081e0e1905c137d7f9e675f16686d0821de15ca7bf4ea92e7e6caf8bfb4e802ca82e1c139c0882154abe80052c4c71f34e3979353d4f44010c2b38430ace00832eae6fd447d0422454920ba58052bc99f74abe3f4005508a08ea812de281364dd3e47ac67d7bd7dc3051140d081f7b613209c2550057be2ec6fb93c1754f1881920bb31a6f1a130aee7b021349ee7b5063c3e5a16473d0e7205e16a47c4e76ada6494ea7a275e66aaa9cf5180d5202ee86a7e7e69ad3f2f4dccc6f72f2b8b4bf8fa8c7abfa98e7a1bffeeab33ea80f8a43ab26223b16795c96a7e7e6e2312d0fdfc83713795c32c63989d03ee54ec4c98e9dfa91fd7dde650ada06e5a18febd8a7087989ecf473da0d3a24352e258adf6828ea5a95843cd0fa23b345fa98f5412340ed086714c4fcfb94f57aac38f397e58953dd79b12f2193292a46ea32a598dc78c9aa4a1b2b55e3c590d25c2e45511475bdca799cf32edb1c6ebbd3b75dbea06d52c69e18dda4ea883abfaaa5f86dbabbe4f6a9d2d4311f29c577b0937ce1c8ed5352c68a71c8c38b443f9e7ae1c9ed2bf982141700d729f9c28fcb1488ebd16ef397854da2d427aa2dae1de8bfb7cb16da06a7ecd612bd755555655a7bf4e7e7a4eaf6cb4582b6eb52f294cce1d97a72de77de0e378739cc610e1de85bb6247b9076a463b423fe3dd6c01b987bbf107540ea4cb93b5519789560ba3b994dab231dcf662e0667979d0d1d4da6b82cd729c162c99dd97427339f1d673e63ebf238da3f1f45003b7d10980d427b332c01778372591f45a67f3e5f55ecaf5eb7aa76699d56f9597d501c6a797caa0ff76678a0582634eba3880f1fd3dabc19388416b46bd6e5e6966416893703af5923de0c462debf2579dc7ea759bf7aa9eea9cacfd83699f3c98b0b24beb83623eacd36bd547111ccb3a1fd587d082358416e43fdfb4117c2c4dff6dbf3e291a0177c3445bebcf4aedcd6438bafaa8deb7b24b4b3eb35ef55164eaecef38d5fb596579a4f56ee40f20afff81678de229207d438f552648b0801b7a207d833d561ef4549580bba19f6a10ef067b557d6496870912f070731d08dfcc6b7634f18ca6eaa3084e6647d3331fa3c98e22a0dd3a4ef6ea9ae529c2739ddedd58ee667290370387d042cb7172b849f458d53f60ddddf0cdc6412e262cebde6f660f6c2b0553e711b913f7497722391bd89d4ef3b44994e4ba258e89cc1919d1aed37fdad1fbb4a3f7cee38c78339374b5ef9c75e4ea9291e371ce59b3f220bd9909004c34cdc5d011b918fcbe91ae3a67757284d3b7ea08c74abbd5b8ee94945246fb88744f49984ec6c13e8075faee998ef3a6e9d0f2c04fe7e9111fdedd4cf5bd1fc474687dc04f6febc347ff2551fd077e95a708ce7bf66779c0f79e9b26e293e529322d0efcb33c3fde9798ee83e6cdd8d1fcdb8ea6d5a1de9647ebb9e9b9c96c912587cfbed1dcdd64d6a634d2c1f2237803378d0845f84a3bda313faf8f2238d3b3fb18cd51f58777769212ca6992139493a466a5d2ce1e1e79280fe547cee9b3821f5baa268764754ccaf9a96ed31204254b8949394d729ae434c9692a517928a13c9c26bd8c8f739a3e4dd39ce4049a224b2927bb55673b92524e734e19cda1428fa9401528270855e44b9385d26e495cd75555554525fdd4fe59f9aba24b4a5152ea885198a9856c63f5f9584d9e93ed9652619376607c971fecf46331515dc9286669a7409e5e6f209d82e956d4b52ccb92202115bf2a9e900bb5664231eeb6bc72aed83d214da382957575e52e94f2a92a4a2b4a2bda4ce8235265d5ddabaa583dbed07ecfced945fc62b79da6f45b557acf5e31551129ad705551a7f40da9e2caca797b54fcf65edd6e4f4815ed4e5fb6faf6ecce9baa37556faab8c99bde54e958799f3799f243f66a949d9eba4dcbc8e5876efaea2f48b5c13c21977e25562bc72a8a025281b12fb47aa195ddf872b123db625f152f7bef652bf639b1f2c852af8ba8f99515eaa1948fdd449a165bbb7393f69c60ba75893e9eabaaba6855b9d2a62b9fbd3a15333b0415b4c9a56c9020794e3c279ac973e209794eb4304b1328955764f3e25f43ae0872abaa672adb3f89444353a38648d46d9bd21c5a4b2252fca2381ace94aa55cfc6d3ba699736bd24f2cea5942f711f0d51faf7fa913e3687ba5fe82f64b7573729c5edf7de99dfb767bb7a5dbdae5e57afabd7d5ebeab12d614ff99bd3a38fa24f4e7137eab5a47d89dbaf7aefbcc91ddc8da29506a2d46e528a4b5187e2501c4a0b3dedaaabaebaeaaaabae1e0a45a128d421a194524a297d9f5fddf8baaa4ae9533b0a9d75bc37104464147ca34f634b71f95a0a7ddb525f7ba75cbd7a8979137933d53f5b8d8d66236ddf4455d5a7e83718a691d21cf4a56837fa26721b6389d83ecc8bdd4415edb38bdd6a8cec46d36237128bdd2eb215a562ab790536513754ddc5ba2f56bbb5f74873684f3955fba07afd55ea362fc55d940a49e5ae4d6759b4aa2cda92753e7d86834871f7ebb6541f7b5fb6543d9e625ca346acaa4b4a4da3343497d6a871293d67a775dba1ae7c3cc5e44e0da4460d1a1a12e9178934ade209c98d76082ab46d87baf4d4af53d446e726279a262497ba116f62fbab460d1a1a12e97793a33bd4e5ee35ad89bab2ba6b59d62d4b4617860164baa601b109774ce708e7e49a4cec829556524a09bfd3a5a6a4ac2a694bd34ecfe01bd5a1fcfc367f5d166577fa96789b963a33ac4ec337e4ab0d4e874d83dd7437637e4eaa87670947d33b4dd59295757f9a68f8c6746a43b9eccc96a8e9fd2dfbd8ad77b8d93714dbd42d3b8365c853d28eac5787d3349de56964f70e77fb1c7edb61e31cf33cabcf683be74b1fbb714581b8eef4197c63b25b12ae096559d55d8aa2accab7a98e793bd21c93afd5ea59bd3e5538836fd051fc64d9f8433c1d51af0e67f08de9f02dd6af3aedc63c63baf5ea6e06df70b78a1315637c8c56c24b4d7606cb8019675410031c98dcebb2dc4272a114f700d729d9e2c9dd62c99d971fe44257dd494a3736a2596837c62810f35a94e6081dba0b2de67790497140eb4277299fd3b28fad4bc897d6a5cd8325ec4b5c4b454a08ffa48a7d6ca93cbbf5c5aed2412ccb4ec97dec5603b16ef3ac2d7ea79642d6bb65c5cb77137cc3badc227c5bdfd02d09a1dd3ac88d9fe2c1370cdd5ab96571b31d61978fd90fd6d96e3aacf3adb37c3c0415dad64182643407cbd996f8a1632c12c48f9716949f8fdd24a539ac97a0dd7e5120ae6bd92d89cc4e8a8322b93d5117abee36f3a7cb5888656cddc4b51e698ed09fa8d2af54ed2af573abc6eba11a02024a4161b62828ccd296e6adbe3a057ce3596f66c7e82953792cb31b1b796da19cab44b1a3eafc374369d6105468f1f42d7cec1b1bd12c164fd11cfc92b4d8270ac475f9a776600af8065bc74ea9bb945eab4eb7aa8ebad507ee04c19df0ea9857460ac4a12dcce0a4a7b719ae3083113310b933ae5352062ebafb581f9b8ef5b1c6a6c3c6ecc63df45014e68e511885390a73c7faaf96e0a5e6a4a847fde5bceb1b76778761183685b6ed4cd36577fac696e9d43b3b55a2ecf68bbaa452a82951e453aae852d441559399c5acf5948a523f559bee65b71eab92a04bd2e049922b80eb943c81e24e08e146fd7d0948c1fe849ffdeec697dae0c5a6ef38517dceeb71ce3867dcaa5f95eb162b73f52bfe7a50dcadfa4edfcbe6bc3bbfc42d5dffe9b7ec5c7dbacd9c7266bbf53c487b337c94ba33b5ec74938d35bb59df32bbd3d4eef4bdecac9e132ca3e268b79b757c4119b028c3147766707b43eed6dfe9eb630b2497749d922d86dc32447103709d122ee0c00517d700d729e1e2c8ddb86edaede1999ac90bc237361feedd574b393cb76e2f8adb87fcee645bb637c46d7063bbd3db1b12a98b0f3ddaed7acfcb789488f2f894f72ce8f121eccfed4c376eddc4d2677d1a820a6d6ed494e3d99265a9a9df2537b9f0fde704df88b6c4a7f894bd16d4a425a69eaca91cccf74f571d4ce22214b7ca972654775facd04af0938eeb6e7cb7e704cb88f2fda6e77017924187db645072fb20a6d13a96b1bd20d79d72a73be085f639c1321ccdc3c1748d0626d050856b120d1a1a1a1a1a101ce0b46ec9c326758e4b9e008aaee9236f0636510277a385b00cf8e3322fbec75bd2ad601f7139226bdffef1faca69492492cb37edc357b42461199004f9dbaf0c899b30c26249f9246120373852555505798a0ce44df1637f52d3600b650582624a297d7880bceb6b9174d864b8c64b9e4978340db6305a2e81731f16d0741e3e809a46bd3dfc7479cba981236ed31c638c50039535422412893e670f40b4cd5941034dc3ea6159afaa8a65ee44b5b4aecfadc951202273a907cd9dffdcaa25ee61c7644b5c82b1231df2d37eaa6c212e067c136c277631adec1c0285101244d2475c0cb6028c0e2e3d619c5fb91b1d44d25896ddacf392244db2022b5982b6711256c25678a91bb3909e79f241fa47ca616c0a037131841ce1c10a6deb2342aeabfea2f13c9ac645a26f129eadfb80a206cdfae6923cc0d9e0f39552d336510a0e3768510346542b02c232a0768448cf40c14732ce6e59b80517039e5f75089aa000546e461ef40054005429a3dd62bab2d2c59076eb41c34be61167633ad0695448ba8aa621abc72853e635b929ba1cb52cedc6dcaaa31d30e7b32dad5020605e3133977ad0dced8f3197b5c497d28e7654b6c49f87f90673b6a5b8f2ae58b9a214c7741a7bd0dc128c65710b7136e247df62ee47b4c9cf61e8b0e476342b981616cbf2124e622bdac3cb612adb019a5b7a39cccbe15949d35832612a7f5a1da0e90106e6f25ce5ad5a5dea10adac2f9f558826c1bfb0ed4153e3be7cbe549c26411703de8877f8222e1231792a2ff0e5e54024f0627160636c8b68121c229be020314a2ab48d815881c60684854859b9b8dce6b9d4eba32bae704c801cd161141dd6b28b569b043c8087ac98e90e97236808430364022efc947253e2cacab22ccbb22cbbcd0a892bf9ca695d0d83b63190fe028e24da06ba3046192608b0418f1a3d6af4a8d1a3468f1a2842b8a80deeca3d1adda6b98534ac2e1a2404ee061b6119f0108a91913010e90baf1174d291f8b45e8ec49f2037c37c83216ffc830b2d3b65d3c0ac7c9305891851a8051bc232e019f2a16ca91da47613a2da4090801932c13c99d359ecd68df110055f51555505334db2301fc658d2b2feacfb9169123b0b76a8d558ad696b217d65f5297299ef12519f33b870ab6e24314f108a60fa750218830bdf24d75dd577dd0f5a7cca5f3eab8bce18b5dbb40f6f0616c132e0352ca0114d8279df5975131d245e30efd1347a60ac915e8dccf9348e068ca311e3685447e33bb84634a9c70b12adb23d627ded204d82afb59b6820cd4493aafaaea342bcb88c9539df845442c72c0fc9a0cab51df0d004bee2070f4dd0388b2459407127755595a7e023b432153e1cbe08be8104cb802017e30a67436e315724ab8baaaa7a6637d1d63fa4753d6a1cd134aa6a895b1d4ee72b9c0debf07e442ca23b57c36ec6d26adfaabefbda5a59b1be89ee8a75677de54c9d8b61dda238ac4fd5a23d50b75ed57727a4112049f998f3c0f888cfd37323731f32e7f8bee1ba233e091e2ecbc8c8c8f880711f377d03e32f0ee3469c0d6d8b197d13b5b0b81a96c38895e688910e98c7c3580d3409321298dd7a5c46fc96ad478d1bed11d688e98fe2a86e44d3a887d740d38039fc113de463be45bbd1dcf81a9799e532e9f20700dfaa007c0b40b50e80eadc0c8c8af58f1899aa59ab72e5eaf35d7073d95e4dffd0ceccd7e4f90a96014924d0169a95c3b26f12e4db2370350708fd4e6df5aa47eace6f3bd42b59b69a90c03f9efe643c353dcb4c607aa22149572fc91089f2495946a2572db69b58d6ba6accba7955ad9babe620d50b82556df50ba272c6aeb65e55974d57fcaaaa2a8b59cf30ac5bb6fc4e97347875cb63986c4d7b12bbcce4e93bd344dd6f0dd3baad11f6fe0bd2d7ca2576ed6aadb14a55babbeda79f13ed4412cbb22ced05b9d515aa14d616aa8e0e92f228d6ddbda6a92f4969527e62d5941343b123eb7c59498d7e545baa08fb74932bb38a993c27ae39e79cd3aaa4d62029a27889a2d5d014e34fd554895a0d51fc10551d45ad45dfc98feea2d54063abc1890d516b51c5f8f2d25a74f5175a3989a2b5b0ae59ef6f4e5a0b67e35127ad851327ad05d56a682d5898c5049f6ab4e4caa8b53869e18263f5e1b73819c16044a469c457c56a9b98f8bcaa7a781e577f5dd11627a3212a0feb110c30901d11b9fc7a3c5ba2db8b918aa31d94fa4b5caeaeaa6a71321ac237aabf511454bc60b58d88bccf376c44e452a7d5654bfc2a259e7b6be1a26215bbd32d5cbcaa3a9ff92d4e86c4ee6d6544e4be7f3ed8e78d60f0aa6b5b5179f6f3ab6295ea335a4229a56d47306019d468c8ad3e8fa7b25717a57e5a9c7412666b45787904038afb08767a61d845f91ac1c0d2a860e24e558f3e72f9f12d5cdc2b567de46e3dfac8ad4eb57071a98f60c037780483162723188c888c6010531804048a6f3033cb259f25afa494b3a14ccf796acad234e70e5f86bf71ed304541ea4b208450874986e21bd9b71d66664ac27fe6a76e5c9de21b3cf53f9bec8bba2c452d99968214df606ea624c52c77585214750ae32c0ccc6f093b1a94140b3a28dc56c0251de0f36d871933306a06c7e6a654a58f158b4da1a438c994dd62eef439ab1863554b6fa55b656565c63bb51252b1af298aa2dea91e1e8a4f43ede06ef43b5dc2bae769f8466f33f8c63cad1e11de2acbd1963a4491d460e6534c89583ed4d951d48c1e7587cb76b4f2792ab36b49537c1a8e717ba7df1e913b8f45c69ecd2bd16259acc852a76f799685df452c7683971e7bf673cae3d5b09bf1b9fa595317d96d874b2f97542b5555613458dfe6a9d4cf43553ba8ce6318e9d5f0d0482916cae73c5e8d12336244f2d20c859999a9b56654f556b6c49752d366b4b2493bfc337ad46b1dc58ea412af4624d2a619b35efaad47bd3b384973d097327b3d925e0d4f75077ad9193388c419bcc22f44264a8cd5b7794a6365b18dd24291202959de895db17eaa39e3e72c6974ce6ab2d3b49851be9a0cf4ed2af176d9f9e6d424cfa92257442c979335c99389164e9ac6ac2613ed73d2aa6a52d15acadc94729ecad3599530f9ea5382403cfbc1aa3a6852ecd9b7caeec08d7764d38eb2578f52ca7335297552e500699fa0eaadc5163ac886a8a856a190dd2a0bb2680ea94525298e0bc3308c6f6b6fa2a5a8fcd595c32afa54592eb5ea6e33f94cdc28fcec1b7d66e1ddf89f6fd47e2e3fb7b5c0d8085bccb288b2c7afd4cceec0662db460a2854ddb7495520318d5d44586727daae27517dd4da49f7dfd4e698e98e7ac9892501cafe21f3566cccba80513a98062555525cdbdaa62755bcaaef13bbbd63060d829c97befefdfaad76ff1d53e18d9d64d4d5628c5c409c954c5a4e471ccbf4d49ec3625b9d4771ef6b087d1ed3abf89dfc46fe28c8f31c618734cccdb3d8ddff6d5ad623bd25ec91cc6e54345a0f7fede27245315ef558f8930fe6ce93d064645b54be96db5320fc6b7becc10546830ecd6158c5fd56db8ab77182e7c1998bbf7c26e226bab9dba98de7bf066f53d2dc64e56bca98adb31efafd73ba6ba4bf947ccb3139226513076932f76932e76d48291ee8484a6c6dd1c921a170505fb1633146666cc7a6651262ba8cbd26f1893d2f5f8ea1b6677a68b6157465576b2225a941ada371ad219c99b995e8384d9ed1592c90a1aedce6477a62b7b89ab6805dfc8ec9644cf64854834d189a3dd99262493155312ab9aac60191457ae51984e66e5f0081b691a53641ab3a5ae4f9a23852767e48845714c5d5d0f55ec53ca41b53f3f575314455dafa5144d52d4f5ee8bb2692de52c04797da7ef24af4fbe2045a57c7a739d9f8b51263b5d4e97534c55dc6da74bf34bdcc981a49cea06efc45444598a9f211602df90a77a5af9149a5fe123b06bb469c6cfc3695908f3fd8b864e534cd3b45d2957697acae70acd55a65fef6a59520898d5f63a9db3ba1ba7699a66cac532269a2385b194149bfed84913024f5c6919c6428851ab54a93a7fda6d073afa4375ce2e9a27ed34410ac47578b110a66521b01116c2a338ac23949452b21058c68424450b909cf32ad9d986a200c4a4396874ece292497150cfa23822768abed3d0a08c49a292888543893149bcb44a322546816f58a750a2fc1541292019975ceacc6c2dbe6e3d8ac2a8478c7a8c58dc0da35fe252d6e1c5fe1e95442bdc0d8b25aab7b82446c18ad16e71c9c57e8badc8d713e2a5b391f24859d84ab47674fd1da3a8244d4309dfa01ea921a8d0e292b884e6009db225eaf419e851c7fe30104673308d2a3d3010f6b08be298d74551147561545472a9533407bd75acb2ca536af6951aa23426e14cbbce6cab6b578c02df78f2bda76dd413ecd4f41805ac0e4185d663ebe196504feebc8cd5c5beb116eef4ac4a1703bb4aede196842af5e4528f514812a340511cb38a310a2c8322125a8390f784446eb2620911634a833ad4d9fb3dcb289f6b6ffbde13e241eb84c07a78a2104c22753231f2b1778c65307ef1aed32783c934b9dcaec915b7e6eeeeeeebdcc3f39a9fb440ac5b88d88f4ef8bde026f7bd3fcc96f82d7ffdde7b93dd7abcf71ec71e7d8b2edfa8fbf2cdd98089793b1bb7516fdff455b623991f46b7100fc39a60dce4c617619c851f00e2ebeeeeeea65efa7bb10100c30a31a7904b46a6ba7b5d576596e12cf8459db715e5b57efeaa3da6aa1ca6667fa9a1bb54d04735e56dbda5458826519a68851d161c6da962cea231d7e4623dae3bbff5b8ae63b674c6ba03d02be7bab2f5b81c16976dfc16aa20eaf2531c377431286c9ad86171a9d84234e9ee96996c8bb8f024869ff043f28e50c137b08fc62251b3b4f58e3c245818b3ac2c772b21180c6becb9160cebcb3f2aaac05aac16c86cfbd8b6f34af00fb3ac682929b1c8238f0aec55112dc9c2f290608fd23ab4be5996b4de628dac28a5c5f2c658564229d46b3b7a36d90bcc3bd234b05b7f5458522279482e7616c98281ee9e8aa863300cb3311686c1d8176b9fc00721647954b05c3ed28faaf696fa39d7789d85e51d6952a450e4c4505090c037367e117bd1b22c0bbbbcc5966559146394995d24b2a689c9c4d8298cc2a88784878477e421e12191f621816544aaa50845bd21175e4e2ebc58bc288a2a6593a2ae8b6a6e2d2645d9ad9ddcc951545f4cba09dfa0decc190562623447f6eba29c508aa3df908be2a078d6ec6e45655e5793fea586594b21a75d573799cdc5a5d9127de854b7a89d5cd86d456d43f4a11d21ca8e3ebf3e1d2505d44da839af6794e6a032eaba48e5a24293e6a05e0a5db7a80b64532c8a7d9f4f7777f727eb2639b24f6daa9e5dd3bcaeebe253dbf4abc22665d55d9e7e4128da9899cf7f35d05ef6b22e698eeb25b61b470ac475afdbbc8bfabcf566f2d6826f38ab2b39dd48554a4a29ad843752937530c4a1372489814988c0206f8893093ed1f28641e01370c8db4893d6963b0c8442dfeb07a3a02eefc12042e873b1a5485d620c8d8970c86d3e642252093d5b8a8f8251b4b010bec17f108aae5ace43e0137ce39d82433aa5b290096dd9da89dd7660cb6b11a984e01331d2fc2bf5180aac0e8550da42635a628c78a36a3fc1d84dc23c86260636136c8525c6185b2c7c020a693975a9d7b952f32dd5dd516d81414476939a8addb469a321410899c02724841032814fd0bc1a7b6b6fbf896468606c9791f285b5163e01613399a6ac1d7c023ed14c2e759128087c020e79e9172ab2c73bf954ed734e9547cb53b01533ebd11ad2d18ad9e78cb187a739be4bd797b8d1a2161b6126a03395bcd3284048bbf5bd8e626d3ac648af6d07b62dd15f8f6fcba22c56434946cb7a8c547c331794253bfb76ddb22cfd2d1bb3d2b7cbeeb465e990e7531beb06b23c459f8ad10833b1a4dc404e688eec8c6575e3db7cea1d1b9485eace14f1a5b61b5f31f2b321f47297527a31931cd9ad53959f5227ac2a47a9d863a5dc65ed6341b8694cf9b294b3783b70074aeb7d8bedf6a9b0493b2dab47ed5c299f8a10ce6b5ea586eace1497ba388bf8cb72162c83facc624e7662b91b635555b15655e42c86481529e58dffbc328d03b15ba8d4ecf6b4450c199a11000000000073140000300c0c8844a3b1704c22c8b15c1e1400109eb050705017a6518e21630c314400000000000000609240bbc51862c5e77e8b556ba6e8119a0a5b8dc00f3a4082546c0d5a51a66abf389d2dacf67b9c2740708f3a28f3e660736f3d7ff86e7f800bc82b84f9bcf276823efb4b4121568765ba5f7d0cebf1ace4b0ef279d354c8e92d05f4ca3e5f3d8e8c7341fd64440a68e04d4515ccd05998d7d813e2b1be332e39d45eff098d574c26383608839a2d3a956630db776467ff7826a7f16dbb159cdccba74c65b8cef948c95a0eb7c590a76e810a8b14f9745ac8590b83f39e876c58eb27cc4015d6d783caa2ccf49b37ffa2e979dfb3615dd08ebc96fa6bb16f4f376aeaab602ed10288142460173da3fff6cfbcd03fc2cd75adbc69877be6392816a4b786d63c6f7ce8f7383aee9aa9c82e7576d9c4044f9c12d3a2722d24991674b8ada55fc77945deb7c47170179ccf5f5bb1fe62fe218a3d637e2948eeb8b3afb60c09feededf02f62c99c376279ddda42d783040208d271b96c5d2cda8e08668738e65d8de0a1debe2e81d773a8281ed3e6db830a86d8a735daeb965364d79495d4fd602d7da90e3644d7c41c0f01505ac0e7163a7dbd29c12e9cf515f81d8647430b0a18bdf1bd6694f98ec06459cdc8d8f9cd7b09653908670e5b354198b4c307bbaa9d1ead488db80c67e61cd8fdc7c922331a6d7cc2e904ef70bec2d4e69b0f9d74e24a93a058431155fae61e323a1eddba0ee900f2768b5cc0abb5cbe493b256c07d045c07af11da1140b42a2e9f77b131d46de53e928ebe16bbfc91665f7f296f0b3a681b69b84ea4ef96f08e3889886776f4fcc5f5ca92acf8e94b31921f247f54d4ee6542c127b5da16d9379e063f5e5e55253f0d74e8affb82cf6f6d15ad1424b9797a369a9f560eb63243b3599678b7424e6a012cfb19c340d6b4870ad39a8d75f2969663a209172faf484c0819dc660a3af7f5c1d909ab34ab49e2dd1c1075691d415f176490b3833d07a2e6def9ecc00d6b6edab0aa452b16c0e988bf3dd4ca255c553477a7229d30c1295a4803b04aa830b797190fcb0aaf5d30437eb3fcfba5d0279163bcf3f83b28fc201b8e2e9bbf9c813f493fb1a9890068e3ee223f2f6c4aa05dc4358eac4b3bc802b4ef6e8538a0b9dc58794a6773de407476225bfc71c116dabc9ae37da345610b03be325d9d793276b68342447285e2f5754182f47b593f756b8140da2293df1fb097ea478e4af9c0ab3ad287e00051d09d0ee0b9a6eea3af02ac0c570cdf27254728e5aa123766bf8a6a3d6e18ed1d2ed9d5fa457903ac295368ca4d6329e955d1e8d9d3565a1848845613a9aaaa2a38be600c1eab454583f7debbe805d1f40830a7da40f25677d4425c48e203186000d541589f77636364495dfbbde91e09c1bd0b48a48bce58123f97af537916cf2284352618684e7d1f2276b1d05641755eb9bfafa8b6dfe3d5af4d27a030abaf97431a0d184bda0fa8ea4472f8ce7e8a9c52eea8c4b7a3e82314454b27834af0e3503ba31eefe307d46a47b06d42885a176e2bbbcf02916b80b14b4810c68e9240253ec11c38a889917b942701b0b462eba901b54ba90cd8acd84eb855e5c47f494c471527d0d82e027981fac603fda26a7639d665004566c195f2391d4794790a92ea68d07da4c3868410137fa10896530951a2b90e967d0dc88c4055ed756eea75949aa5a5eb7f6c28f64966dd4e439e3b8b167b82be28c7fce187219d02843a8fd28d36131a3f5ec81702c79d19018051ae40c40fcb52c7b0a02b362fd1b6c66659dbcb40f10b62affd1b9d013c540acec15726af48f0c39a1121a4333783f5b0ea4e97771944a8b6e4494c30bc082f0d7c4b131a667c9bccae910902fefe0d7f3246eb36bcb14a1b2dc7a660d404c1d811bdcd57028cef6b8570bebaa72ee96fea5be6baea8e424c10eb280be2231517042ea995140e5145df9f91cb1a3e7a4fe7c7bff435c33397c08aa26917a0cac76daaa044103075b13959da5c7fb2134cd2c8ff6faf530c032ad0a9ed271b93fabbf11412b36fc8eb5c95cb613fee8bafa821345236b192585a291e944d61cdd44d69c5f4b34c3df3b0337b97981ccb422cecc6fe03e0d2deaafd47f4124f580422f8da8e8b9eee33abe275881d19295ef82d408be80485e7fa2ea4a8d8a6457862282d0094f44af6a178649ed8db84f5a813414e9c3a410f4e4f8988b31f4629b621758a0b7f2d173d507447b3f2035d9a83d6c7d5558dddab958b0a4c2c4db8d989dfb26e8a0c215344a41e72beb894b0d5c0c137268e17f6c04b202556186a052cabc8b9e7bbed40a3a281df8f52f7e89cdf365d313d6f27250e64818947f95c9513c08f1159dce86e857803ab7ff017ae07b78048585c7a29bfa34002b6a4f31593e5b63859edf5e38a0f24d860721dbbfa3ae8c47c3d3379ae1a3980a16dafe6eb96069f917f94e58c0a535854393de6b6d997256dabfb3a2a0afebd5c4ff37ff172c5dc111d91483550ca0d2f58b97478d77cc582495079907b95f54b050c7da05a7dbee7921f00018ff0b1637b321c61a894dc985015f9782d53b93b9061bdcdbaafeccc73f3a5fca451e3d5e2fd9b47fe762dfc2f897a1e61520d6545cd015f737b3284bb5b8cbaceab519dedc7cd13159b0fec3bf88a112b3a31b30230466ba2b4a3230ef26815cb8d5093fe6c5510a32ea884b20447e7922e2a9dc602271494de0b7fdcd83fb7ee6963075cb20237c570352aa7b147997f9282b79e1964061942ca05da73c1ebc70f9df8915437a2c03e4f0329336a923fc37c94bba4a2a81b218c6e68be62b77c1c231482a60ef6a402f9450f8bd411311d255456fc25c621e4bdef2e6121b621dc7bc4d1b0e2631ffc824b6e9fe3bf1d04fbc91f68d4ab2530d7022ca556da23751fad63bb42f44f4fc73e5ce06f2d968d175d2fbe74c65054ccb1d90b554c282b9b1c0eea8d1094a7bda5697b2c1dedf64426118e00ced0d1e963803fc5b58d5257d07ab90692de0b74ac9d701875809421637afb16e7e1fb2988912acb186c6810368f119a24c1e0d8281875c27ef6634c3b3698bcd045ffd0eb08c3e3c92661c06b5a224b34b11b2722f12461f80206548114ac6b77ed618d1cd17a3883fb6cc72469779efe15ba9e8b49756e2704b659d1c93f4476b60eca807e4c96e58773d4f07bbba1f57f25d3ce91fdbaeb26e1fe0c3d9fb608315752248d4dada2dce8d4c58c60878d0d8669e811116f74d48b3a327b38012cbad04101dcee82689b79efe3fb3517dac00ccce4020096663a537b06fc84485aa609c8e5c6dfc3e119df525c78d33bcbe508703cc143922def14a27da742a0b8bd8b727d1923cc0d70089673b7751d7022510fcb96beaa38e38ec30303e8dd17865bdfdf3faf0d1b892630ad5bb0273b0a87f342c20194f350cc6088d29e281c97fb62bd5948b1007e05916aa7c8672e35cc4a08bbaa4d80a7a7d9eefe6e14a07e31fa4cf5ee73a05be6819dc5f5d5c1a56b4ab789491a72fe8e79939c8543d99126f22de1460f65d41083c7e160089104c808768aeb6eff62e0f3fcee0ed2086e3f6222309c3b62bf38ed0b0a231c73122039623a4c6dd08493ff1c50b81dcfb07ba5361177952f62bf0bec9326149e596025075c3b699c849d90219a1ee5a9cd8f05ba42c0722066d4d61543928bd6ffadddf3b4aeb6731e0c800533d113e0efd4b609dc998596ec92c258fee644f192ceeb783b5159ccc7e3a2fc17e1cedafdc044359ee77b354aaca17c77cf86ccf50da50c964dd3d15312a5b10c041b6009111524745955ec3cb1144da0c0423b839973ec76835c869ddea3d685ece3df2dbc6b37cd4bc91c37a4691c10f53a116e71f5aa090b37b0cc226e744cc839aa3b4c1098d7dca23845bca70eda9e710e5c85a8c153da5bfa7692f7d1300e50ff7754c68e8d9e996532b8cc8eea277a40c8ed541cb4be5c9a542260619e06155103fc57e1e54c20d41c8a2051f1823c7c7b560895d3a2a53c515b11894770b3e45c6f036c3251b92e87bfdc4defe3c9e9e7811d672f1c366bf0a10950ba9b5b1cc1f2da178ff5f8801a6299b8f50fa9e79e888b7e9d4b170015d88e43b4af1fbff49e43124974935008d60a58b3f827adcf3249e0fe1b03e92b427d5c4c687584b1dd2504cfd2c9dfa3f95715d637e70bdb8aa8fa19fafaf46fea39d3e14315b91e9a9e1e22c3bed04813b356dea06d7ae767ab8f040ac01420eb1cc22725dc8e4fa795fbc49e0d3fd87c9353a03861e4b9c932b9ef30a48b6cb207e2d852c6df09c89299e45c1ef5509c02a2ba2519754da57241830197ce7918b4c97f4632f809b451c7b1ca36dc22d935e32d5c0e04c865771fbc5d6dfc868f113284174d12071f948494d72b203e29f7325580785c77a09feaeb04e2f42d6c6dcc1de82d769e50cf258ae7185d7ab86e5c21cad58ffbed8cd23e92ff02e6447e84e164709781088258e6f5acca0ed0d8fd3641822c95eaff2e8805fffacc288b1cbc34f73938aa8171466864d9a27377071ff74af96c72e7b7ecd2187bbecf86a7a609810373792225de6ab1f797356ea5562bfc35ca0a2fbead5af66580a408b9fc03dfeeceb5e3070c9638727b1892e32a0b4de6ae78af64b59037b14c29b4003d17010db29bbab7435c506cd4cdf6290fb59f83449e0ca4b599b07ac9e3ed5123fb015e5e3824940ef221bfd5b7581931af4fb782cbab7020bf74c0c84d46638e6e675c774572582bc3edf55f98cd380535603d6a296cb99a3e68c45f04688943860a4493cc429239c25ad6c1a6a0fbefa2abe95185c3a4f4235f504ec7a1995ec7c3742c359b49e84ea5f5234cdc78d94704ecce208433a7d3e1116e4ad74116e1221a74ea859e88c2e3f1e0a63809c3e334084b047a2b487a51463a5975540ffb13a0e8db7823dd07a229167820fcf2f930f8687102139bfca84da64fad77dbdc9c6a4cf53e4ef7ce2e6e5911863e8071970895d3a7a045ad802a2f6b520606f0b77536d163e40d4fa57ff7ed05107fce3dee2b56502c9d880bac1fbe7231be45d64ec4c391fc4f9b47932e65b55108da82acd4c968716d95a81e3f99480635368d80112f7f95f8c3830459e26096a3fadfde6c502717093e17b3bdc0dd0e4c2fb7138dc2286679238bb9645a6939b3c9399730eb7efb794c5ac73f4425fd5726121af756acfb5f1ebfd03a63321699882737056222431271e6155a65c1284fdc80baa6310ae4bbe6b28fc8652a2e67c1633c0bc2ebe8a2753b8b62f9c5f157a49978120536a6e3cd14cd0f1c4f2b9ceed16eae1ead91f05dbe9aa4edc8d970ebc5c688e36bd534b4b1c74300e59249bf52aff6b9e3828db6044073c65fb3aa9d732bad102aebba42bbfc25f4471ca7e2257130146d2515f32bfad227205c0c99587e28868b6a982a646467d887a926706a1877d1518e6e36608dbb86900ac0c9546648ec38e7d2ec625a8b65c3ca8d6394037e9a18cfdde8c03f184dba095820817146edbe4427f1ccc21483296ff03dbb6a348752745ecd07fa3e3ca72c2781547f9df60a29ba3500a12fd38512b22248f7d81ec8feb2b45ae5dd2ef20901f2919fc94244e4a51aafe6e043c132688d47d95eaed671594e0ba19945501d4817529a7fa19c2738c9254c578ef90822a70315481af494033d07eb024b05c306b499f9467d7fab2cd3c9523c01e9747365526c9b82943bb08e27363922ac4af011a3c940d3f4a264ed959a58eb43f1d61687eff9ba9990f3f5706c8baebc43e7e3ac55a1c94e3ff679a4c291d6a7a8bd6f71520b145c8427c758455ff6e9cfd1dc754f886dfd0ba0b289ba8d07e70f93d3a5527d8bd691802a9527182ee05bbe96c9ba226dfe77b537291b9aea36ed31b4569e9d58d4fe819624d467966e9862b954fbba9344498bdd1440b2c4ca293d08e23e68a392d17147608c178d0a30937f2ceb1cc70ae1ea350b302ef6b98048d4f8086c12d4752e77ae0022dbbf80341e86c9540d09a099952e44f0b7b3a0b9536d870de86898f2f0722fb141097e6ba2fa523fdabb07d23827bbc719e9f8ae99a415c7c232768bdc5208c8704b74b466a9f1934136554741fbb4267578e203d77d307412cb3ecffe3ab9a9b4071079cc89c9bb35e2bf0571a66250ef4b0de004a2820e8a64308ce370504e9f0769c235cc2a0aa3d4b1d3261820816fac0b931edf31be0aff744b7ad1036d72128243833ebe60209b93c08441399acd91f1cacaee0dac0225515b2f444b72bf26804fe9032e84c60767cf82461c098f6ee54bb7bd63a884642d7980554bd72f7340c084e405e83ef56db21448b9919d170abf1edf0db4826a3ef8abc85cd6924177e3f02e9bd193f57b54ed413af4a65f05778e7c77bdfdaa0922224f3369048246eb4020391ed1136c7895d932fb8456a5525dd4c16ff3d8b40d63ed8df3ce3949b6c99f4c12c9fbc01833f66f834905e47aaa111c0acb44a7b77dbb64ff5b0923fce56876464a7a2cf0410f1c02de4f1586508be2a4934ea8eae5a001988cc93d0c6670ab5fbc1c2c1dfd4478ad225128704f88e8c6e9d6995ac674ae232391110e8357e3a30681b98b0ee7f0feac96ab612a9e769084c4eb01588e055d7525d8ba958b52ae6828824e987f2dccd036833ae337c73d23ea90a2fa7b50e6eecf66cf0ee55a8b0f44048431424e006bba70d6393e94818264bbf1e5102662ab22bef7e3a06540e67ce22595814063fb256a94dd1ac01a6f4beb420a62e2f1695edbeaf1bb24559d4fcd4bd231cb6db32ac9c7334da097bc961210973c1b466e56cca7b00707628a7ce00b1924317159b5e26dc4395a2c3dac02dcecdfd9d6d1546809d5dde1855a41e6cac70c6271ad2535496826035ab7719135b09d571fb331b91c077b1a0ecb0d982fc7617aa1a98fb8f8268c3cde815a94d433cbc292fbf5212c08894c76fccc470663847ebbdd66b849838da5c3e66081219425c7f804c1fab4c2bfdae82b7e4685b89441da26571bc73a027b51ff1e21cf8b87034950ef8b1fc50c0316c97a3550e7c855197dc1d7c132e20180e52b750a19ba6eeca1d9eddc1675d41a7408b0b12305762a76ca27f7fa12e67f04390f05372b3240215373b87d7a81b151876db45dd971a5584f48d9aa8a52c148761332248d4408ae84041b31042fabb270f55e475259653111fcc8e13224d4ae782eee6721cf84799b6fd687df457e382b21be638cd5d3e23cd76b85f48fe3bcf1d3c252f709f1a6f6c523530439cea26ffd1f53a821c162265d81274a267ee690675202cfd45a94166f29bbb6494ff743fddc4de60dbbe3cb753c5e97ceaadc5f6a1249ed0331a8e11f100bf705a1c007f0fb938fa7a978a1ea5d884bcccc389c34820bd9234c929fb84990e2d17a5285ce62a7d0a4f130117bfcd60e453d7b975076957f21b8f351cc2a41c8fbb97a3755563e3a8037c9d62714e3835cce82feb5251abf261256b4d8d20d9a2a2d47edad9f0b423458eb6c6702c64ccd3269ab0875b6077f89d9a1119b19e8655c3606ea04a26a674dfcb2a493e605c7a909913709148a2a5fadcc6f75459f66408a2625674b64b54286061a8a6a61aa5ab549b38237e9f82d61c42f8344857a40ed781331e016e3a74c9cf569dc1d18201925357f07e2fdd894ab9a493396ae9e075d624fea46eef7c438c930128302da5c49e79e63809bd29483f0dfe62fef9ea9cbaad4885aaf3957cd29e39842791db62974e9a6df7d0130762686e88a525a40648768a43e78b3648c41d7ab638e5e02f90a1b7460287a914e8c827f8d2ab83d1d320efa6e46e63617177dc45a70d9e2e027845d73629f739afce8ade63b4f20789fea223174e31dbf004223c88a0f7c7bde42c1eea06f51bc7804bff3d984d7d4d8d302dfabaedde65935c6641768ce0f23cb2c81c214cec6611353f2e3a4a2ccf9f9fabce691e7324d8dc273349da39222850bec586005df99021ae7f78c4933c7b664bb98626c18222cf4292cd66bd5eb60a470ec6a8082686eb04cccd058b7b2959f5f4729354eafd6fd2d3364d5f4342bdf2596eaf8caee506e9ac86dd9d36e54b80508bf4829e0606d3b7efae3c007186cc1e0985f82f944027ac0296b1330440dbcf2200ae12a5fb8c076d1a33d0ba3891e09c042df9f3cb0fd9468654799661042db9419e2dbbb60cf3e0d31b938e7663bc9515aaec0e1829c0ccbcdf06d4b53d21b7ad70098f3c8dcdb3426f3e0f58c0f0df3580c5dd997f9780e63b5c9ba02f4f0008bffa38d3edb992eafe06b1af3eceec520cee03452182e684892442c6b948836da1cc0605fb767260084f92e17c1db6086d09c53e2848b07de13ff25d92416e0c04a7bc74b388adb942999de48684c9765eb4d7e0814020e940f02288d88e287617893dcd47cbe979b40868e7bac74b7dd32c60c26519fe4e84eb10b2fe87c2bfb4055e0b75548caf6e28abb8fa265204f658df1c674cc09f6fdbed093f55d3ea0c6f4f905205d7bde44ea2fa176d53f3f2b3bebe0f03e4fb0aba26e1144017c7619db2351f38f246f990b11a4c218cf1722309715871c3b918eab9d68d43fbc46a77a3859828468c022a4ce4a0acc1f4cb3787f32c9a8201505d5371eeaf254bc088691531ee7d622b87c8dd3fff4efc3035c2289632f5c5d1dda6bf69a65aff78a3beda9bf0efa99e3138e960660886327476aff48db4899faea7552a6bb56ec5415529bd800fc5db95f03e8ec8b3e09677313e039358a8e2459fa243160b4124d9fa45101f5140d08eeec17f6510fa5b86d90cabe7b97bcf25572e1cfb4d92ac76987b2e85fd74854aa8554ad8e35dcd24e83053875f99647c59c505df1d721c9c0f0dbe3758bb1af10f535cf136b9a75c4e54ee886e6cf9083ac233bd1a40315aecae7debc0400c81fbd3192bd7c7942d6d0d5118e20e2849ba8ac02a1bc73e022b01d2e3a25b14eb71409be98e6742c76d00de9e30845f6c00001096d084ccb7c09aea6bd05dc241fff5bf5fb3e8e9f6eace803de465cbabb197402f0048997a36190e05d5fa4e190e574827c7a41ec319bfd5d642bd2d30ba464e0d0aa375a16a60f869eadb9c74904a9ca7f515a8d7116f981ac3d782493d3a88bf061502b89fab666d0b988e8254d27cfae01f439f3e347e8c18d596746980593ebd36485d3e68ec02c73348cd8c4153fe7d2e2498fff13cc8b68746c7a0cf79d08cc04896f05e1597d4e3bf28000d707c2d9f6b4586ec9d5e6e2d0b19a6054003369e293628eaeb8e2a7697728a89c21e5802676a038a2fdf04ef47e8d3169b35cb9814b4e5941e16b1f7169261321b00da0b4108f0b714f50c95f371f03829fff220671e40a9e8751db0c58ad71884fe712f6d529d4c6b429681c8b790a25d882d86c47e2b3c25232ba11021d321bf48d44b68808389ee6af95e8072421961c7221832590260813b02e3fcd151a44ad9ed57204edff905738879a6001d99251ced63ebe55abafdd6aba6fc7399b49f11824fbd7a5ae01113d1343c986d2d501fefb491d96995dd14b8f18a8f737bb1a73ed9bea7772032194d83b1354c1999f8a339325c701c050ebf041b41c97b54dc9fe3d18717f2c4393250b8708372e0dfbc510548d94bc3f2a88fbc4048af93c445fd0ce36e002ca816550307ddcfc27e0eafb020fb2c00cb4f22f72bb87b8677465db40e2e31af278e25d27e1513f442b56115919b275285c76e1cc214c991f2fdcd641528ce02fafeb344556f6701373659154ef17416a08fa90b0477ba490dbaea02e934769ae0cf44390576bd49cf720a75adebca3b024ac63fa2911e285bee54ffb691ea07b61edc046912cdb7b2d7770202a4612a7334adeee51782a980e40ad04382bc1a8a0a99383dc816a6f4f477047ba5b3165dbf39865e5073fa238939ab0437b9f9abbc02dbce136c19906942b8dad4402d0fea9fd503adb6f7cffa6932ad8910373de37a19996c2e3c1431bf42cb8046b216d041be1023e9e5d16596472c19fcfce43f7851379a6cc6ba0115dd7ca0185028d6a8203111c9e746f365130d6d13d6ed5205ce9c62b15bc4e32e8936ed18ae2591184dc93cce94dc90ed67f8a1c8ed99cc05c6474823a08f5fee3e1dca7f827e4c99e2440026c975ae5bd4daa9d733e233c151af1f25e78f13810f2f7faf458570da11ac6661556493ff3508e903228020dac3c136fdb8dbc8922fcee6e0dfa52391698a5136dfce42c9cf55a828bd1b3a05b91a72b3f6f262646ca55133ac4a72865c5f58051ed3ad48f72c442684a4cdcb598a21a6b651ecb033c7f6351510a3519abedd4b0680b6021022fc2dc53d87f456bb6b54fef0e362d69222ec28285881d71abad5060b261849a92ab9a86732ec877895f0b205d6824d40d8631d0b38142fc10c1ec565aa12b00654e2e151ca80ac10313da8fe962ff91840ebb01f8403e24593917224b650dbe3975f818eab66e147133a5e52449b73ac06265d80c2bb0d32e8844825e5ded1ec01a774362fa2cb78f68104fceeb0171dce65cbbf2807706e61ea5a9da8c4dc383771d634eb2e7f7b1805ebfbdc1835b5713fffe024bf16f21bccb14478f2231630e4bca41ee87f981b709b1c7e208e17d24332b870b757a1f722965147a30ef1dfe3432cdd1aadc36666011fc73b8dea1966525211f817eeb5a466a98a101f8c376b36709c8c1114be4f7f88921c7685295a9544b30a0c4797ff6d3226b3e09fb2d0a02ce581015b65d83cbb64bee0d1f87151a6df1ef3aaf90c776ee95953ed0895b66e1ee7bed30233976e15d95d998b51b56bff71df5a63336533b33430ed2a7467ff60137cb26eb0ddc20b09e33c4ec25b1a16f216cf3d3873573e035267beec308cfe5f5d24268b10a7d470ef6f6b6396c76615d4db988bbfd3f7d8d5b82cbe715e5474c481987f19a70b4b8ec20bbaeb36bdaa2b3ac3e64cc861fa04d876e9c6af4fc4ebb877258b1360906c5b5bd9a938a8738a54796999bcce8ba154ed12e5f1d81dfdf0742408f8f8e1a20c535a7f2be0e244387cd1490742c6549c8cb6f9a76a3a29aa8dca9d3b4b00ed46e79a9caca9d09ad413a77ad7ba2d4966899bf6222c0f565b21e8f720506ca05aa8b622a625f9d26ad11a451c4e71ceabde2d1ff1fd7eb101a172181e104c52349171ea97117c2778b65bf12c0f12c0188298d0aba97938ed32266e120ff35bf3d0837e9d72d06fdf85427f246a9671017858f2369c5047f3108a169cd8ea696822a0e10098c30c3a85f4e8b4cfa839fde0d50e0c0282fa7a68e311b75b1243c179621b80c319e65043bfde3c51a6c9313e6624ec89eb2b1c02e3d3ff14b293db54761e89753224b3ce2f12f098ea978cc30ce35b80c467fc62775a82e021b0e39fe122a4b691428b6c433d0935e0988eebd1740a626b89ce4d742fa3050e59ae1204d0408a2da82c7bf3df4b3f1671b749e4fb2238aefd96520a83bbb3e6b417bc8521933b9a2e00a3d70c76480b82e17a7db734efd33fb7e7b4ef86cef756e50dd0400efc5c31bc428bed43b860952117eb114e69a780a7a01dae6c25b63a199bdd8f0a6d4916ca7cec6bfd48fe1b8ba4ed36b242ce7674be3ee28ec90c331e0f554d80d627c4c26c3871c5f572d2d33352f09fc4e2a3436fa1358f95658152a8f07f06ac9f6f810495ee723029c413c7c6f9e9b55deb65038e42b1561f78ac1599ae05d0aca3ed35704f52b08721bb96d08d40c3466e23680411a5c75a32da4af17e41f895781d729fb6431114d2d1bd2ba8ddd2dc10b2d1bcf5dfc1b4fc91bb97e7a82f316207d6ae4b807fc31b22ee6a60e3df9741ea9a2a83764ebb5e1fd634367712ebfd339d3aca51eac092298a60e40d1791121e0b4578a1366b0db12c9420b7d842df7de327e731690c410c29fd803ce8d68a7492406c3290a1b2717bd110a5489c3dc09fb41f98b060618fd976cad6508cb6e6b91127caf8480414f90000e19f28b73fe8f39e451e4e9b6f223470fdc0b28acbe0624dd23b1f6c3555178ff5b22a3a15785635d14e0a21bf52e1bda4f82a6c5b9548124e24ea68f80d6d567c0edaad3839af7548fb9a14af420303c891558739dc83d596f8177ce11e8890d306ed078a7d987f49b517f0b4be395296865222520a594033416bda513baa7fa4fdf4a494a732ad99545217b9805c2b0362d10da41c5b37fc7047a0d78bd15a64171b5bb7d264546c5452e13fa8336628202fc478703cd56d28b21a0e5887402f0a8077c3d0e1bcc1c55d2f4799ed773edc357ae9d09fc3e022dd081cd5a61e5090508655e60633e1cca7d393a32ae9f57322265faed1214201840f1fbcc1526a78fa59ccd26d241fb4ed209e21381776ac98df31a4cee8a1a732e185334fb0f71890df065111a690e4ec85213cebed94c5f494d11ad3aab85ef45b7a48c656e03efc33e592d4c61ccde629f1c6a5e451e8a4e147eb58a237f8138db74ddb437e3968cb312511e27ea0445c327e68bb1aa872cf5a29089314dea7b175f2695bdf35a4603e34e68f98a413d8faa05487338191960b5e05932f5b3da4802012723b45521fc1ffad7574714b1d85ef5eb60aa1f8f48b46dd26ba8796e04a8fce3f665505f85bba1753504ea05bb3648319fdcfb764578aa354991811885df4219da17e4a409aa4d2d9d4a0d97961bbc5e5622cc12894c3f24e9ccb6a9b1545add8a788df433712811f2f85129611767204c9fe27b38cd71ee149e32cc77b72b8321d54c9464fc23b93c017966f3f04cb1c344a793274e5cdd0d1747ef5cee327c8e08cd0e2bea3069026ee56006d63f8a7dffe7344b3a12bc547b193018a16285ec6578f6d2a712bbc619fc550c523d718d78daa9e0bee2f87da13299a4d0f7ad664ca651e0e5710849b2f8278ff6c09ba0c62ad0d8e46859f2a0e3ee97984a1a411488ebbaf719769e5a30bcc88890461fb547db523e1ad21b4b8a9bedac0e79875529a51483c04201aef49e371329aa3c5995e95d8196402031ec4bc9a676db9428bc0911af56e1b749731f0281e208ab102a523f3adf8344478a0076924f70cf0b7da1f14de07f0fe13f2fb1cd3bd2bb9086138af73e4b148e0f9356c50aae224378d44ef8a8248933b16973eaf173e243def491369ecc88c922e2abed5768f56c543b16c2cae2c622b8aa2ee732ed282ae30202c227cb621a4e283eec435685fa0b9fad2e6764da29e9ccd125d0a1d6787250092a8c18b8c91680e97f078fc71ca2041abb4c53c731194be4ba73fac1919dd805810ee70c5845b8741688c94ee3646053058fa2ed26488a01df29d3e8546d690d117ee608f91a560b4af10427f245e77c0f7485a53f692628456251c34dd4b21ac871ed9577474a6dd5716ba82d76ce5205e6323b7df0ec6087e74498d1bc86c8d71438bc18f2e4565c2120fa12620a445472fbd5aa736a6d561fb10c315311b8eaa28a4382c5cdd0c15f44cad8d27e2a29049b9eb46c0173b074ff215d2e76dd63a76a358cc54d351b18e5ad934b09ccc8b6b0608523812424666a74d6230eed86e33d5e2d12e49032559c888802941ed516cf3295d632926f2e219513a42523cc773bd1e71da8a0edb513f5b20167b0f66f39410928a767a5426d9ae0c48692fc5176ed18aa4ef19d9796f1032d38b2935a6251008aaddd9bd0da76eb6c1988a2a87b88dc411b36e1feb293353ed104397b4600a381ec8bff850b9c80163e2a36002ccadb351bd8e65fc64938bd47be8bde92186cc3e5e60021440a877614ff128529716e5299fe4368065928ae506fd0e6082cb260cd0d3c59d648b8914fc73b86198e8a5f66b8867990f7ea2ff6f1dc0a2d989d804d7d5db55209fd0b23e25c9fe66e48eb729ac14a587b3972de2e77c40e745f7a8f889eabb6865992f917ac98872090e04a37540edf870a22a1a93384419eaabdc479e3602c955c4162edb5b5dc1cbd6f23955e3d6a45db78b1cc71d5f7cc345fa1284b24af1e816ec67353ebb3164771900b02fb508c0bffba75f7272970c574bd825cde84a98156295188e80c7d234dc2850dfaaf29a1c1c593d3687f8150d235953c2f00c33309578d994fc68a2fb011665667eb84e88f761f62d5e0162b2393258906acc94de0ce6a94e227ec271d616b56b53dbb9b6dca5ae2688735909b6c48d31d6a7c6de2173c3b9c109e7809fad5231357eb9c13dd8b61fbbd5d530e547dcec7f0b064512503b69269510fa2629c3c13e10871d8c952f69a471a97247291aa643044fa27b8c626dae3af9db0d90e7c66916f95529d724bfb799b7a9159a40a8a4a130658d2f5428770ddbc58e3214a081d876bc9268b101b763b9085d08a4025732119f578d4d8a2f08f237ec1c573c453061179858f871324046dd6cea284c0edc2194052201ac4a91a28ddc6b46791a11201f571bb00c20c9974dc279d352cae59964be24a1bcfd865ca2666daa221e938c6094ea260a404a60053c1d2c063689390a6e43df96d5e1323f5b90277b930cc63385dd823165c3845bb16ad025734e422da37798800da76b98291d1102903893c2ab0f2c3a61ae9cce3b9ceded62cb2fc710e113ca4713310d4d798b78583c27a209f9f34f7c3e151763a7028cadd8d05d8f869f0d04ae9920bed63966a0ae56f25678ce856c60c0c04986c68c09a5c0b71d57ecfe5a95f9e0107083ab3091a675361200a5d2ccfc58d2ad8fd83d22a75849ae51395d67a0b260bc378af2e37e54a1d4787e8dd2f072ff83b33725b0747547535be1dd4dcb1a33c2b4f48f131cc447c05f075332ffef8a22b0a9985fd627896507a39a6473dd4b365c9c7800dca8507c7dfb5f82624f79e5a99edcf76b3a67b77bac2d0fbd30a73a235f222a0b223b845baa3a58196974d68ba2306e55b5184d12be4f4b41407dbcc9cfc5dc2e4a92bd3c13dfaa71233d30670f4ff27c887e975f5246d53486c4466c0fd5322a1e4a2b43e01d27660a93e1bbf7bd0ba9537fddc55b40ef0498221b7e0e82667c0e9929150821f8e1dcf58b431640e2e19836c43f388f01805666f6c52f650acbd44a93e0822ea0942160821bf18805c3e4bc88b56a133288e15c79beeb94078d01b3e4da513c7c4946181868e4bfb72d896a93565de8775fae3d4daf1197702014460f76afc68dc63a4eddbb47ee94dbbf3c510a51e65b2bae82a71025fb2840e7feaa97bc7468972004f1412c269aaf310861764260e5ef142a21cefb7e25835e0dd31c29f6587a3393d703ff6b644600e003fb0bfc6bed9e8bee56b22ba27e8dd0a4cb8dda33ab9747f4f9532e209949abbd55fced9a1c06eab1cbb546c6c531f0cedb466b292bfd4f5419f8f4eed3b35a77740b8bd4261d3d116fc27550695f81cf7f262d1b6cb08f796e9ca98a38dd121fb3d44fc0f7f31f38ed8f10f057e19ec1e54f891b5597d2605b9665e6687c51c211dc5e63971e3cedb78d16d6b235665daa9b577fd3986dae52d09a05e18b9670064c73fe0be16a3562efe975b396815d0a771c4540b68e5178bdba7b85b996659fa0d9f1eeee1b9eeb492562ff17c03dbdcd0989034f79cee8d73a82d4eaf13f7f906e60e5837553f9a8e9b9f4417050d8d16250f58401b602ecad63972b50f9aaee29762a10739a48c610d6be1a217b8a54722c3a7546118aaba7135fc03db5143c5b09ebe3f4869c8aad23c801c6031d2bf1aadec33080687058fd398150a8d862b0c6b2665d3ac0259573a80d991a9609e1934b8842eade04b1270665ee9d26a1481f7b929f889ae1a4c2ebb72c6753bb21ac22e3be4bd0417d152e9f350d42eec6e1b88a526fcf83d2846dcf5591cbedc48a22e808d5cb20aac96bfbbbcf8d940262c0ffad2e600785d9f137598e7879426194ba7e7aabfd4b98202909e83e884354289a8418b05a8644fee456b5146849086ba99648ab72f369639d940fdbe83decb05ad506690ef480304a287466e0256ef22789cc885953cd4a8c38ffffbe6c85055f81295ed331e701216e09ecc7159855d0081d910529014ff10439bdec971642c3f968c704cf614d8f6db4735e234321069d3d5abd3427b880b3548f0a01a30220d19e1fed01205ca9310c36f2d518149becf5b45d6c64f17d2279a6af38a774e0b74894291d37f571847443dfbfaaa3a1aff2fa8693a665220e93fb070f89dc479ed3ad2ea41e678d44e96be25598b0a68f091c834db0cc0b65024f9201fb20bcffd13cc97030d5fa9c1069ada2bb1de7a53a9e9a321cd6249a9a326d1400876ad166f6705e1b3c6c01103d4aeabb9d1fe913009e453867b26805bb9f9519883662314bb41794dee0264c3c559383c9e40e5ab5f4bbb3cdc2ba3ab5cd7373256b1d6b1b8eba618f315f7b8ec3599268f02b63cf3a970e310e597c4dd226e55ccc580c34d9e519fc98eea35b257e06cbd40946f7a12f964c6e4de800b39107432bc55e381ab3f1ed3e4b03cb8a60f14e3b0f6050e88e88228f11daad22d49d027a364c4e9438b6e0a8eeda81223778575c3219d56fb9a1175c6671a5a74ece960378b2dc8536317a27507c4f204ba15d33a5fc9972f6f4a7262a1ff5b00473a3c3a12d0838dba2c5143a908118b97723b0031a32a0c530cfd38f31301c2ca52e32dd3cab01909cf4f69d59f2853a94c9f6f5b3c0285bfa0d5782f927ddd7e062dbca840f8709baf3720cb216e813ae2a0262f9bf3dae900aaac3e11a0073ad86b51a7019eaabb5f3fbe3059e5bd3efae4171e0063f1024087a6646cdedb039ee1f4c74c6d02070185bcc3c3ed000e2edcb1b545d8bbebb77967533c6a3bbeb98078a1b3c6f1129212c7aaf2fc4be795ff47cea018e8e6e583c9037cd2d455e1bc12d0023987a36636602d816d409b4c2882ddc3276d2c9f895b720704e0ada756291117d51a89e9dca63d89022a089ecec771f1bc3e5710bbca6755044f63b3f1feb21a9844f9e108256dd15fd59c9255c5ddd5c115734eaad4b0949572a5fbe7125bc3e8db6c8a5458f08625e6941ecd4c4a9c6663a0143381d30dfac3e642dd86e852badfec1cc3cf04c682b1d2a33c34100b42e8a6d7f56611e906c553a8caebc5348eec50dcfecb3473c8ae9ba498793e10d3bbacb473353e503e7dd06e3e2a0ce55fcb39d24d45c82a6b78d1ccf3bda398c78c2bad255edf7d99ab3432e6693cd0291c73967088a8a90f7ec0d16cbfac1fc322d16a3c5374f99ff314992a898a146f01ee745144eb106db4731515c9a48041ba97887e5cb46132c708b898dfc9de5e5b1b98003a2f8257750b8bd4618f090da7b71ed4d150cc6fe5e8a8897d6ea862cc063224e1b606efb87b4407741773c256bc36a1577e1ed2b9883948d8d52f6f862a826cb5427dc31b105fabab9f5549bb8f6d453882eaa5f5d5b40c7e88b4292869f079b862918fd7cf7b9c80b046322b9dcc9e8fb706e3c5f80369209929cd3f794202b415e848fcfbd7d4e09ed2d244fd3740b940024be85e9b15d877ff10f9feba9ab30c0d11ab6c210099d112b8835c501076083d7edcc18e480014338f63ecc267b164817dc24d599876a3f830c39dbcf8e64b2629b599387cdf849d981e94e829c262d7340daf87549e34221479c12aa8e19156370ff9035436c98df2cd85e17fd4743fe415829d811b3637d19b5d9ca3de40dfce50ad05b88c7452ac4b77438ed319f0c818751afd2405d6cf6e43c13c895e2210fa8898572315de613d1c79da73dc03fcf141af251a2dfb7f2c711cb56ae23abb9f00b5630a11ce8b493700335de8c8597aecede951db1cd5bd2a070ef2f4935ecd786cab008c924ecbda88382e3461e50f9af811f3c903f300d2be64ebaff2e9acae50dab97a328ba0f11b135c639d14ab589ecb63135d7f0c4eae06cfcf0bef177493484b469169869c966dadc48e10c2570236335291b21ee02e153ce2ea83e355e20c4024026ccab570dcd60b42eea59e5789043445909aa921be52fe7f8c2a2d07a47347e0197babf87332a2dfe3e64147b7a11490495446f288fa1858c89516cb001732fb4af81f9f574cb0591189f5f986ea388c25b136c4701e0335097b71b684803855d68b0a52c48914e3c2eff5973c0439c9e8da3ba93dc595013403bc9b5512023d5fb12ba0063b6a0674de8409ddc771392fa1bd814bd33b8e751869070031c34d3d2473cd92c0558cf13834af002b7762aa628bf13ba43fdd2dfde0b812b49615285e6bf46b65dd0205b107c826cc4108a922c6286a5a52ec8d1a05fd9618040d945d9a577e51b9cbe1a6d8d826fa80a099996af6487b5a3fd122765de58f99848adf35134873576e8cdae0d636ff763ea2c57051474f3700c87b77080c1c3f4ec85d3a0086c8f6580e9f1c42142000d92ec183f28cd99ccdafe72cf487bc6de56ef6a0181622caa62f2691902970f6f7a1271ee1f2c1a4348110490bf104db09015bf7fbb51551b0f1eaaa4beb0d7840f7e773ef41518300710f67b3b097c5628e958c5043f2ac1de5ccaea574a949349735048fed4401c93d21cc85e25f92154ced883189aaac3c35bca246fc1d73fa54496377b76baae78908921c75e0c96a3f4b76432e31f56bb063b16bc3986706c6a12e54d30306d96718f80068adb6889c814d0342b3c59c8d74c08f821682c5e6f758e94fab84d2846eecdb5d5c87f2a569f19bc0969a168fd9b16fbb8b4421f19b084075e749b1f59cbb0516d4eb14f2dfe3630dc6cdf02dad7808bb1c5b743903a0f52f0c6059d79882ee0128574d1b4411e8282c2d8ed7a4a6e4cd5e91903515a68a31ac72b8fc0f90f7b80722b518c60fa3092fe02be0a13dca05cc8c9da408b1fd0ec2c234ecde3a015773ca3ec7281041a52c8464adc661af8168e0c25cd13d6d11f34888a6d1c5b1687fc9abcccc523f0761451589f7e88eaf8e890ae98dbb4240d8568c95a0dc74e7d9b37c6643acc4f1b07e7b414f040e263336b82d19a400cc283227ffef2d0a78b0798e2b4fac04ddaf2f65ae45fdd8eaae9fd625d148ee2cb8a962f37fb90dbe9803b5bdda309dc17526dc6d00dd0a9adb3f82b8da312cb041110e43ee78bbef9da126ffeb5ea7ab90d093048cd22374a037724bf1155bdee006d0cf5fe2cf1cb99850c7dacfeb76a3f20b8b4dc6264f77505dbc6c1065239a8e4052f9051614476db56e496be0593aa3065b26313a399be4fd7b9dc9d0e3464159fb25c43ea66ea4de67217018da8e1feed7bf499425446e320939a933a0e737b9b0baa76b51dd28197c888408d762ac60530fb1d739b0132c2f340825ad7cbc3278b333931bb1dc8a7d9cce2cb041a5e1e989daf07a5869774e865b6bbcc73f544a4cbcec8c999e29be6f1acc9d360ab8cde5609209812a071ae80ed3522c31429e1c39b04262f426b68c73e750a20e11367547a0d59c0dee9c16f77903ef469660494f8caa125924aca31186711d611559644746166bf89a220094be72f8630e31e5aa760128b94faf99f157c23972897567b202a12422394680198eccf7452046fc2ba821fbd78a86017e0b62102e1a227a8c6ea72239c3d996d78bf48465da23e4f4b9d568efe6d22ebdb0f16b04a39735e3b0a5fdff2af0ccb6a91fdc6db42a59ad047d603348b5214afb2bdcc2f19006c1861dac97c24d61ccffdde449a6c20ccc106e9ed50b96f386e0d32846e922ae8106563740a1c8070a613768995a178eaa926671150094b937945588a726c2275b8076c9c9bb139a90f77512ffac2b277b25d0209305d58a75387480f5f13f7f13dea66823822aff33de86a0fca5c38543f553fe96bccdfd0021acf0b2bb0e37db9d168b1e49eb533ef76dddeddaf06e8f93cbb846a35db5524e68c88ab403b3df0422ed8e9aa8794173d8c16af7b0fc291712d3d641a57d6ec87152639d6d5311023b19c125e29777feb358a89fbec86c262ab804965a124d0f2a76de25c9f06d6b4d759402323d739456b7ec58345aba8d6b5d49887e93ef25cd1c3425b34db297e41fdfcab77686c37484737a51a2a0f97d4a6b4707392371140367d1a4724762352e054d12ebe8794e7f86ac70bc90d8e720612de7f048b61b57fcc4399b6947022b1aaeaf5f36aed95b56ecea6598c21b545f0ebf992e763fc3392c31313b10afe2fdbe4c63c38646dc5eba64becf0bbe70daff6c65d316acbaa53ad54604668480ef9ae218b7a4c5f336b254b784fb791c60928553828cb39e4041d3d30b202deefea2a8d8b37aa06a746915f4bcda653520d963aa50ecc7eb89273ea36a9af19ef1a4d94cd8009141390105db30417df260a213fe185ee8b6cea18ac9350f4ed2448b0c3e900a01f33e4ea7b8cafcefc7f45f7cf58fa07f0b7789c5cbff10eefff6f224e2b5c6f430335b88c5f57215acbd7cc9f6acd08962e80b9830c612fa7a1bed5a3fce3358869ecd6b7d2c692eb405bcf4f8450e8810f3341242d93706eca851a206ad5385735e8156a20270af44e10e6ff4c6ca4acecd767bafafd0a7e08ed46a2ff8f7dc83b8835af4ecf30075bd984101373c220995b6009fdb909ee0ac92aeb762bc9d250ec458f82916c62d854ec087eb48e47b5ae0613500eaa2a32d4928f8d4411001042086950f0f9664434f086da76b928b4e51d0a9706e287dff8871f458381a78cdebc0bc41675132f0a8fb4b9ee58f014233024f21422833e2447437926bf7c3ba0017de90bb03439f3ba4a5ae0c544f1e4d316b1352ecfa8744cfa12971602f93880c1c09f96768d9fd4c26f6eb8683f55094af7af1c71884f8704bfcecffd3f32dec8e0d6644d92f42b47c0519782add9cab157598e408e72bd8dfcb6f54e22be273ae42677ce06aaf200bd80b5988e7feec4a09019539f3c77a2be3b77904b9d65a939316e7432ea7a5007016be3e2b95a045f34922aad445d1d0dba2bb3dc0edf060d3121857b89f5c3e6c8fa484a892ba1eb30af740baccb28a8396261d5e4805b005def94a346bc3b6bd1ac4969a61d0279ed2e98743e8cf6e6ee786da7b3599ad5bb55872fcd566c1826d59a387d61161a08ea39a78d4eb268df188471e4bc97508597c5ee9010151639405f6092a6a2a36bbd70c254400216fa6b10167c6c4a46967e2b84dd05f543232e281a5af55cce511f0d9e0476b9efc6c9dd7e971cacef2af6389d58a61aeda27891d694cab497a744efa6b18c46bfd0f67ab1987923d26051d45264a1ba70bfecc1d5e9a1ca2fc1e9e38d88d6806f2fa14b34a523f6aae1ef6dbd22726001f33ca3217989be8954fb0590a5c71a1940cb991e15540a1a067ef4cf30fdbdb2885ced6ee70b8c2884b82694924c9da6e79ca2cd48cd6193c8d0a40c0c2fe98e7c6dda1511d28e9e4da7447afe149e63324ea2db3cca0dea012d75ad9d4e41afdecb0546064d3695910536dab53c8158aa941fad252b02b4500ded8f69a8a4579fd426208fb3a2e2872990475848b1e61fabd22415d0c9621fc22fe0d8e5d47df44822169e32562058aca47d6d955571c9533df0a478aa8407846930da7ebe147793181e3ccda8c105d386a7c43b78b375912daa9cf095278bfd1d44b7990434908ca3137d3f29f2312d2cdc798098fa039776c8e8b8af89ce481452c1b3587fd2cf1f70f0c0b532747cdd0dd473445dfde342ab91b471f0ae15e2b2651a853bf1e64c64ed7fe8609f99302287e7298be172dd76128259dbce4a885ba58ac5729f2706bafd38cc16c8394801a5e0cdb654298689039ddcb986621d0cc93eb1565d8db203395e38856377d8b6bebc40d9f6bf32535a4825d37379b7508e1c82a351c97b74d6bcfb54c89e4b24e684737b2745cb237f15677826e34c83e4955e293dc52bbd6ebd52d5b719d2ffebf4b9eedac31bd1d513eabc1d6777598288d04901e9b95daf682b6d12bca76676ef351801e1752b0a90858181869fd939a08a4a2f3bc8e4c02dc92765763e5596d831093cd82f1666655fd43571d98a47d0250b36c994e87d28962ac9690158aa3df3985095eb4f87f37738de93a3db5961065c2b310814ee1608cfee989646fa0222b615f92b259c155eb29233eadf819cf485464b56f871ec99b4ac21065f89638b25eaeda6a4a36a8c552cafa96c63e771a02ecfed8bd0ca06e783cfa9c007cebdad0862202b4252ab23f4a5c85b7bf803f1e1fc19773d777a3903abcebe2fe2dc7b958fa4eddeedc947b0b2c54d2dfad26278a73894899aae3e969a79743788eac13aacfb85b5d1c0628e921623b5f3fb0b8c0c686d4f982c27312e6ce63c5ba1793a36d2e40ac06eba5d2245e5ee8f2b65c80625a205be10b8be0a057cf185507eae9ae679e1c9f4f6b9416c1ae363996f4fea316dc306e65734c708d58141d4aca5a06855b59bafb7d3ddb73cb1d60a42dfd182d6a8a672b47c66d424ef0d899edaa5d6adc3e696bb3630c9c40eb618ea6cca4cd89e882f4b948d9aa2c58527e790561bdf897505584564efd36b65370f89ad05f776ee698ca276f7999f6684144ace066480e9483c3573d920a7580b8d430698fcb3a839fb6bd2a76b5a9c9be5ee334389d9cd95fd9b32092d43f8b4801a6e6fa267429c425586f599f4b8547a2c7424463ccd38d2d93939cad7988999c311d0b5184ee98c6044b525ba55860017793571cea41c3e38cd32217991913567425c24e748093290b8b4ad1c57f53a46cf06bad2b2758d2494fcbc5ec69099da2f2740a0b087c591a1b426294173313bc727e06c7b8c9cada076a301abb94bc91b205c93dc267ae76815871a057437cd0d4d1c99cbc7dc462df15c940654ef101ef77e3f4e58ce72e53a2228a7c9d9eadf77c5914d74b27a3624e11b0031089028b1b549750fdfadd84a41fddfb3cd48da731f52ba240a35985cac05823a4522a8184902a37afcec1524b9d37b04a9883db57fb3693251fc3c3f56c184684530980d6bafe62e7ca1a9a6c3f281beb330c4b1b56a4af069b89d026804be080c6ae51eb09231aeeaa4b5de80655efc68f39c087a09079e7a6ccd2d2ce861d067418bbde71420a363e6bef36de7f6b543825107289d04801cf8e7bf15cef9ed348c1aefebca861fbe42e2728785473e811a81b9f361e27a7b71e5cbfd9bc7b0120cd99bf79043bc62c1ea488849b14a3f0ac904e768f548996931a23faf8a663a49d8f2285103b150d43e9db21866bd02aef1297af1f86bcb1b13a4d3da4ab957ef2f6f3e4ea096571606a9d3fa10a0b882f11ca309d75faf141df9dca7b8573f631cb29bb3613788c3c2c6f8858f9d7f5345b9ddc83f90311e3950280279bc8f9d8f9454776ec3bfa580f46cb3501c63ade84fe795a01fde57b1f750ceb8f260b2f552a1ba9dd14a3d65d48fff1bd70dcff8ffa7bb52eb293d26e6bba19e151bae7d0d6674ae2e7ec1dd3635df325238f56051e7caac8f6b0837e6cb1de0263169cf3d78dd90bd0d2a81686f68a140304107c85600c1a0f6afd216d83d8090c88a4f3748464a2f130061d44262c790094b971812677e03c6b123c06a677be7df81e0903b1189f5b986f9afd26ed75a5de7c7406e14c8ec3728a9ff18846ae535761f3fcae0496d91eb028f0115a7caba80f0dd498c7d6a0ec1e6f68e8d5cc1a1df90736617d1334cb08e338449404260dbc3205220a4cce9dbfa01e26e783cdc50614b7ae32d6c76d6d60afb554de1f571b1c9e394b36df722bcc956dc40f56949f8e1145b2bebf7013d521a6228066596b0b1b7a9a3a6f31d2d68d045b2f0db5f6e317201ecba77c6f2bdbb227898212fce70b07c27bf8797b9919979057d1bb269e2982c218b4fa38db41790fda8531e2a926c69e430e9649e0df1fbc050ed2393b6c0a97094b9855748f1a95178c7f3cccadd073471185799c19537bda24820a2bb8a7c5527c78e8589714a936147a95248f22cb0c827ca5d872ef9c4e2540404b0e519b3298c06140f5d244b525b02b9b3f40d7f539c6d95306c8bfd7643430902173616691b546a98c9a3a6b3d59dacc1bd5dcc79e758cb123ca969d12ccfe736743706bf50a503b84fb6ae3d1c3e137465c34673b2b131564c2a3ad92779b9c26c2bab110a8acbbc41621d6755ca159a83f61d8984693c2017dbeff985dff57d0ac02048e765e22ae13db40310c2fc4782e3e9311a9e834cd8da08c27346a8dbf28ebefbe0a6b8ea320e58b7e8f8499294faa7ceb5f727acf0073a5880fd20e55eda7e4d49a1dac6e49892b48de4421f6d0cf441350f6f6ac3ced7240e1f5add7c6f35e09115246891bfe01ca637924e4382eab0cb15cf1951dc272d855cf1525d0feb908bde4770ccabad348b25e9e93b1efc70b5849d9f63367a9219381640b34d07b0e8d8c9fb0a63a426964a984098c2900993ac61fdc9f8c294722f99c27ab19bcf0b09125e7b54ea5615c83abbc57633a0a5cd519196696ae2553c5df7b68690734b36a57b32ddb82e4567e53bee45cca60771c35708be21c1d687270c9ca21c6ec2211b61db0ca50515602b67173f6e8b76b7bd17be80003f92bc8394fc71ff8a8fbab003610efa9251d25e4db45163df61ed063b3c21a926e998220039e49b31520a55c024824f79ad22aebe8d704a35710177de7d27e49cf76e08dbb75ec0c29f0cbe0fa7dc6a2d0a99bb33d0a6e4831563adf8c353076ad0c43c9108bcd980927e4993d07d3fa8ce1909e2326718f48e5bb033002783c18d4e094445c436e8ac0e42419d0a38201f12238f7a83761952a7859d2d173ede5f2eb870f58cc958b0f9b2eafe329f336a2f9f973697f4976e0cf845aae90dc91f31af96d746b920eb2c4c445475a28a2a7e4e3280e7d62a911c7866d13c24e4020c496c49791c15d1dbdf0d573dbea8dbddb52da9ab4df0629d88accb8ef1c523852ae27e8250c6289d676de7a07139b7508e711efa602398e42c8d8222081578887d0b0c0e3183f290ffa2ecb1e74f6140352a6ff51bd643699b07d3782b16ded4df4cb2dada6e5957a2d3803dd756e5552f56fa1b1415c8d64c5b5f203ba6495bc6aaa2c108fd8ecb8592a5f4b02e0b1b7ddc9ec656d18f6753ad8d526a350561ea71f9894b999079ddd6eacce31ce25188c76df09c63f208e2e67668099b9175b347c22a3142cba39a9aebad31d2802c805ed512aa7849b6840b29cca9c0b09bc4ee67aefe2f68b8835fa1aa814e1236006b30061ce90346497358bdf4bbe481dcd0ab1e0e1237d64571ca03a6c07640c6986f0088010d02c7ff5483c74871d8530ee87e92da447dc103fd9a159db04b8a4813d82fd05c06b1562b6f926bc826623683644e3d1904a4079b104727692a3f173e0d01f72970211e572126ba3a7402d7286fcc83ea7a9cfb574ddb0cfcca97001c809f07bff9460acb24c6ecbfe984ecf4d9176c770900be13dd18cb2cfa04df77015c078ef9fc5b38d52312e1da3fd6e661884a904e09271f8912c005820b78d23fa6604c00a78ee2c3aa5e09450918e9e8ca54aac0f86a9a8c9cc66ce0cb93170506a286552e026c1ed214e4bc09b85543a870209b8f7c08b8b0ea1605f88790d20a48ee4474fa306cc7edb8093ab359956de1e30c2c9ccab2c09cb55c8d5d390b110c948f9d2521cc4de0312b0cc931f94fc676b7b7d74d2aa30b3d0904972c5a54957860fb5c24203205ec2ccc945480162f112ec313d4515399a191b38e4532cd7408a8964334a6091958c92c39cc52f56033bbfa910655be33b62b1018a3252010a210a1df2f90385e1b396072c1f65c7921272c5bacbc6e97b0579f1dc570ea2471d2f04d7df1ae87bb3ab9094e70e6cc4bd04d43321895824869690555dca0af24b795578c0272b0d89f3580b709b0e970138c808bec3a89993275ffae602963df2dbdd3bf922bd2714c0411be2458bbda19b14ad2f9534222163d6871dfac045f1819f657b29b6118a7d0a2e4c8f990bccd8cfb917166eafdaa29250b6fbd793ffa84a8ea04da760930892ce9bc1890263122dc0ce54f4f479e44538530a78764d4e860ced618ffaeb376703065739df50c13dcdeafe9385e6cc6318be12eebe9289b6171a5e766bdf7ed52072f7a051f4c5b9a72a0dd3f41dffc1bc468b20913b02c6ca01d6740a9b332d0fd818715d864cb7fe7611b1eed421c1233f8dcae2698da5330623e67e058cce10db5af80909d60ecc373109b04eb0076de91fffe70c62d4c6a1a7487532dfa7229e3df70e348e7dd67ce3ef88d0f2b60293ffd08d98c7b9e947b62fa52986d12a36b115c607505e98646174fdcc704372a56ebef8867e9935b8ee0ba085a6ab63c2810c6a2301f0e8d22ead862adaa996b454e0391b9905e80a2f1bb50c626e4bde24f08fa57d4aeda7c92b0120b760fccc564ede44d445ef423f9321da252d9e7df75335388ab9dbc1f94c4e4910221c30b176290969cf29991c551db94bb29e482d5582cd1d9435a400e803c11e7cdcbf75f1dd954d2b8dde32ade676804e8ce4bd96b48a04ee93abc12afb01046467d0ef4c9bffed332c51ad66820c1ce0a31066a123e0d37998ca95173dc5ac866baf0242eb2e11a3197928dd0b9d93d14b99a9e78ce507677088e44b6ffa1717cb2487ec683ce61820367248f015736872230d2de90cb9ad5a7e78ceee7b321321753bfeb643b405164f1563bb3cf4eaf6c05801db518c0977f54b6530acafbf86f9a37cf213af9327aff7b074f0e6cc986cb00a00647e20268224f9fb74e3ee84e1f3aba9aa551aee9fda88f904fee917b5f6e0e46857da7ea08ed1504c8d6b87234d2b8e085b4aaa07b88660349ae1ce844c4a5e722c311184beb387a09f5007a048e11cf0f9a9a791663e9c2b91bcc35fbb79ac456bd7d5cb0ff22fc584c71bbb72e07ac0024b8c18319ccd7d33d71f2c482f6df2221fe2185ba847eaeb0c23105ae3315e3136d9ed1cbbb578773086d54183243bd43f40a0b3a9049b457f1463565def93fc9c7cceebe28432f18e033906b50d3fd878cc51a137192fa604a08908a4dce6312ce31aa398a93139ff6b65fb1a36e3316456ac22ed44ae0141af0e2f17952aa51619319b3d3c5e4b50da0e86bc870a4b8eda4709ea7d89a8a06aef183bd4e511f90804c94803d5306de063f5190565aec3d952a1a307a3a77a18ac1211a8dcf0820b76feb6ed48e8b41259987feeed8218dd42abc819001d2840d15c5f5c71be18161c62edbdf48cb75e27ba0d15cdc7a26eaf50028ef27432cda4661f60b29bddc500b446f6f2b94b4ea5b5957fd75eb43bdd73e2e49025b3e1a7e24305b744d3149c6ad2db02585e8286af5de863fda9ec07feea88e06ca6b2929fe80a7a02d454bdfeb947ec0d6e3548c23452a0cd22ed483638e920b985834ef19a4a289e03f89534e0a39fdd4e6966a551cba498e5a5e879cbc6622db00bdcdd21cfd7d63bf4b52e8e56b4d94aa83e3874db5caa90f8ef683508d47ff6eb5c9e65dda20fa9bcdb8225619bf1165cf4e5956e94602cdf6127ce281657527ac4276febfe7de1202adef335f03fdd88c5186f957a71f06c57c0c8ddfd2ac7047655cb4a296229d43a4ca67a00fe9f6c3e67357d4e5e00c9a6f67fc4515fcc9facfbeb32d664a6e1c44b5dd41e8eac01019e77cd0c7726d4a7f22bc643521edd6d2ae286539c9febab5529500dce01ac489496ae775ad9bcadc51f576a795998f1289c58508bc8182881c1312058f03168806894a832a49089aab3ab76a9ed495da09a66906d2ddcdb884ab1a9d5e5aa9569011ab27806d0981f64111d42899e8663dfa0aed973cf374f13f6f83a55966d00a9034fd621126e3c7b528de7e46c6487f5da393e491de70cd2967dce2b4283783f0560d1e200ff924dca31389ac29e60c68a3670377dff09eb0a83979e73845e657072f83175bdfdcaf130b6fe75b95a83d2477d78c6db9869fd376a145625d88c1e5ce369f38e054e182e750d22c3798680428091f2d7326f71cefee5300882a0e6833ad3c7179779b5bceaa0cb071ed63c7fc55da0e9f09d3ba3ad0ecdb2c68446ee88b239860171517297a06fe3c6fbe1078c0e4fb3c9acf95518895740fcd1b9060d360b09e70be74568919df1c0b497ee02d213b5ead413c39feb2e577097f76234a171dab8a8db494ae71908743c70e58666ff08cb67ac8d2f4cdd93375b2c5dbd426a89180c2d016aac520cc05fa5c4f584df9e75f2cfb9a87094496748ef3149229cfc7772083bb8c4c392d86302db10c2d596d11d4d4143e3f37f5d13f12f9c9ac697543378b7289b2ba4e2477dbe323d1330e0ca852c86bcf0b7aac2ea61fc5a215f4893d7583283d0ff4d4a6e4e2833249b9602f4fa2f8c897a2486d2adb714b424010772d48b6f9062b44002629b9babbbea9aaf0bae4eeb6e0a6dc1d6c36aa6b7015181f08e7743c74baffb5acfa6a8042c221ea0e05aec992ceaf0caaa02c0f3dd7f1614a49cba60c78d8944471b2741482b086325d327d61a34f0fc24567e62a97920f1462502ea00d55246a8216f953085348ca2ebd29660b8562ade02b7082a67b7b455f3682362f489bd38380e919f24b535a9ba245b056d082ced5059ed0f5f72845d4e51b0cf920dd901561d43e4d646a7cc6055308789a6707e15f4893af3a178d1516fdcbd464734777f726e452607e17e9cfdcfe48d1d4e40c0acdf063cc64d2e1ba0f3a12dd15b8120e2b9c65aadd0e2b703558ec0201100bda759392bd8ab5c2141d75f54550d5c58d0995192c8b851e6c5850b3084460f9c9b5ef9bca3da1ed9451d88aa9c8078bcab305394301ee14ebd65385f8277298faaf6b0cc036508482694a615b5c83b994bb87ab22c351ad60f943d5d958462304b6669eb4441312dbf392113f5e7dd2646c15fdba174ad7cd2050b423ffe4f7f4190330565bf6dad739428564c99b3c4570c224661e97b0eaff0597c4234af4cf1100ef4c470ddbd5f8cdf277b1fcee0155a8b53434c90941bb9c754a94b35db90bd2517a1da3d417bfbd68abc5c0696b7b0dee45aee8f2d595d3c104e8bd5f0c390e4c0db1c05140fd2d6b11ec456bc83a800cf54a02e803c40510dea0c67ab6ee889185e0b9b5b087e8e23406ff1511efca8834bea10fbe70156d5982cd7a3e201d6fe513eac81bcffc39c2d34924d52c08cc7d8fd0625c79535c664439ccc8397b03f72f617e9b0b9bc76dc24b957d2790d44cd25b0727fcdb00b13974df5090752f75e776b2799c9682e60771bc4f86ab7555544752f113b9ed828a04f48fb4093e10f8718cd77cd8bfc425d7b66169c9e29ca0c455ec42ac87ef137ebeeafd10604e98199e818ab2fa6cff40ff4ed4716b2e3864f085fb0bb2a01b1ff521aab7b5c28743320858ffdd02cbe8be45c39295ad4553a829f322c98a0e555a9860908474d8aa0803137a75b1d11ec715fe8c954539a2ac77464a01fc9b0b79d715d137e5a48461d889065d506ff90429ac59310c15e7d129eb461f298a91bfbce3296089ad0d643630eaf6e1d4e34bb1f75cb6eeaa202458d0a09de13a9613556ca3ba93f0eca8fc0c29e91ab3993f86783ca02e6529611ce9bf1ab0f295de2ec59341925b595bbb20fae9df717125743d73f6db3497018b5f744bb562ab40d4d555557cce7d5131d1ecafb41bd1ab2e6645490407f496cf89b6a5de488a7d0d34c48d85fb6a93df8f5e23fe6ac8c0b2f92cf3456495f9104876af444878d7f240792579d74966fbe438fbe38fc96a53fdcb6be44237e447cf860a02d90b5afe310631158130d1384978767cc0b39bb2513de02af7b33a9322a3b7edb11fed14e28de4d623a407d7190289283f8817264895d0dcdccf22a45a66d87a4a7423874eb008dbb9261940ee4e149ba44ba82c308afacaa2a302e7024a5b411928534fb05e0b9ca9845e039a6d33fb1c8c56850a980bb48f4594ad57aee4ba881aae5caddaa5eb65b3c221baae07d7cbcdd3f77b032b32b415c5899d8114021a03c142fd01c464f15b68488ee2133fcaddb7b32c747b7a8be181f363bb7b375209840a15e7087de9743caf6e5bfdda31740d50a441b469d212099ccdff6282eba78c65691f84621e2f6097f4f2e443eaeda2a6a06b1dee4dc140c105f07b6469bbf3686e1ee8a917ba34bf40a811726d17a3174fd4d61783626d84121b18f63125aa6a2d515c6dbf6a97d13c694e0c9af3ccc171067097d91d5c9a1d8bde3f007468e1cddda1eae5d35859f15a93718f0e386a4a1c45b93f79df2ee7482633fff874c70a7071026d2732e88fa72faf8e11f69c892cd1ce5446a788b7787164f37d84510292ce028cc08738182bc333e760c001ce8d57814ce8961cc1029940fbf299ef41dcc4d8cd9755711793d43e0948bf3c0e679c2d67ceec11143076604d3f33c8caf6a8bafca0605d89c2e180261a00bf4f7c7246ac93368c9394ee03c353836bcb6178c6b52845108897922fdc5f4f3e5f616c1c073f95f378c46d15774002e48ea700d25ffbe86337370e3a96efc59cd53ca1d6795c29eb03461786de31ba4ae8c19608966c5912303e9e22cc851d3ecee4dfc37b3a00391f7104a77860a01052856debf24ac6978b016ad62276ecc12be35a2ad71a27424c1d7051e37355b09c5c51254744f87eafd9a9d0c2ecfb010399564c6e57a1809502f1d999c257f94fc89331c9bbf8f535f593744432ef86c5b29e25735b6ae638016d7dc85b8b0e8dacbf3bfd99e3bbf79cd27fcc9bdb3ebd5308a2163bf5abddf435630ccfe664d6a6400263588e39f403f2455865c4b9d184854185484ef08c99863a913e08f96b5ee8ac850c4f3d54ad4730cc9d4d4c61f64973fc27a61251522993eb07e51449ce92009a7c38937ab8b4177af37f9a7bb01cbbc0b8582ac09913f0b34a09a6a724ff89a0ff4e455c6d14e9005652dc4abbd1f32822e1feaa8b1041686982d4d38ab4982214e89c7a731eb82c4071667382d1bc0e333e587b534e4ce6bdb26751d47cbfa7a8f08454cc49e26ad5abe5c74babf951aedd859bc42e95e1711de40b36e8abb97753cd0bba51644eb961059c5eb2246dfed23e5a09f9f6ef130590f6259b17e935e075fa34e061c9295c96a8585b089b68fc78191de33d21c77123cd97279b575fe5ce5d4a38273095004054ec092658f0a1e895273f346e9463b635976b1c4d636820090b6f9a513cc2806d54567056fdcbe262b9ea582846fdfbe874be5a8de6c4652abae14378b11ffc85dd6f333f79306e9d34b56ea56768b57e5d70c374a97143f56236d051a58daafa74798a9854c47a9e4031fbed5cf63e290b49f2b2c317961d895d63458e03d42abb24f61f5475ac710c1a5dd0d2525c4fa7f17f14d5639325be01266140a4cb59402d3c7e62f23309d4a948786cf7c305a99aedf8f94ed65ee93c1e90824db082637a6ee4ff256886ff72a8760c991b0d14cd9e338e075865224af78a0984199e2d4205a1cc9773283712f0098315c117025732e4887d206e424a63a0144e753b4577765210dca0afa6b636cff7f997a31e6516c728c2f434039abbd188f1e0992e36dbc5e01047bf01a0ce3ae8b5c60c321a2684e1fd824930e4b75ed9a353d1bf624e674404a82b45157f42eef4131fda4905a69f25d3f5ee907df792d3fe1df36bba606d42d160924aa621f3856822730f6cbe7e4224fae39dab4fdd77916353cc0aa738a31b484d28e0ebc11ea73050065c1dce44c6e484a8ea4e3624a4c61b205fd6846a5cf71030a8bc07e904162634165bdc2bad6b66a5081fa8e945c34072b6d1fa4c73a13fbe9ce2558e33a1648c9a55ccb80bbbe090a489f59e49d0ab7c393766f1a9dc169700a0ea9ac4e6093684ac010975646c184105491738e1602032555329449c7d4aee70151ecc198eba3a05adbf64e94d4a38114526fc9051107fbf2422e861b801e129a87d1739c40787097443c815b684d814395dc740988e022e7b13b8e2e4beac053fad6e123414ddfbca83b425b9b5a26e19ac1c597b0eb8761392a3df9af1c7f786bf83970e82d3f09e438af4d4de891890599565b815a8f281af598d7732b55d0d68622751cf136549c9fa701c60c49abeaee5daf50c99a94fcc8c1ead32d599fd3a94f1968fa9e8bd992477e4089a2745b0811a1dab5844efabbb61c6440ce278dc71a544dc70c4f69687f716adc1d796c1251f51b35fc604e3b18f16a27a2ebe83880645c81a1979b2552244528ffb3da289c41a5b606a91fd72a793a0719290b56630dcd9b4fd65f8dcdb1e3805d067c51712191e51dc4066eba534c3b9e4a253aaef47d26e420e5282735fc8fd0a549ddcb85c56dddb8dcd82c49ff474dcb518f833e3d49c0143f3ee6f4c5468a3f59377b23304cbd9eacdacce522103b0cbb614e0b86799db52917fe129ff3e5a0390e5994bbb3a7ee4212862ac597f51d9f997bd6a55dc4669400833e93b70abc0269fc4d78d2811b86c7cc4551afa1971d4d606937cd27086b57561f9cb26325e141e7824fe6964b86a16613394976b6e405c272243c8cb01c544f5fd47c84429798e5b0a27821b2e777146800398dea9fc6a5fef2d27cdc94f4b99d7042123c1b066a1b0129a9c5bd76ae3ac745d16ee85da9bdc1e98067357cf6a7b256da9ed2e85b28ccb44b675dc9924876657db31d8c773a56ce9279458f7a41c2dcf3107fd375c1d65ced1c44b6fea4cac18061b9b157a0225203c9a99a5ecaa3bcf34dd00f4f2227fb6c942f74b7b10f6eabdb0266378faa4570468943c655ffc36ce3722ecea36e053e7c28f02a5010d7638404362540778ecd5ccc7e09813bc83dd48e9bdc6e4ac88ca58e538a650c0744245519651a51bf0220bab2740c221f637138b9f458b1bf3dc1234b02bb9aa4595b31b4938d881b4fbdfa3727fb7b18420de7302c498293749251f7f18a317d56f4b73345b299a1341135140836097b433f18afe13fac2db0ca6c5952ce53c4f7cdb1e25c0e95474dae379303b4a638c432e4804c4e73edf8515af6997a09236e7d50296e24e4b7b306e6dd2be3733fb37aea8e9377a28761413428cd234e7e7d62297c1020ae2f12b11fdde013b2910d75b129faf9170863f6ad30a8f37713d78ea6fce5d46af32b372b112910312872751e1843ba241b5fa4c15214e6e675e145881ab762ae4d76bb6ece585e16db4028b0495a4c7a16d2b49ff64ebae6cb21db35a0ba9bc9d58044778408c432c04bd8127b6fbf7167e25e80a518dcfc94ce3d6cda671a67fde99cc8ca192f235489fa7a7cf43b5e1e37d18da41dbcd83e6b40f1b6a26fab4e2f566ae6d45ea331797b234cb0919fa81e256d4335811cccf78f85c12c8bffeefc6d113ed73371c597e375699d449d4531180dc7bd97bfdd2eca83aff74d791f6f98862da506d083984fa6ad16763b0e58ef9f7e50cfae2a46e2600bd52f2e3b9f9cda729be0f8b77c271da9957257c55f8b5d6602ad916a3c39ad92e69181a5c984ff8563175e99a5ff65b4e4e7176e9a8d37d391ead520a2ac1afe6f86f3d155effbfae29a6124ebfd3e8d289978a39198806c4f5e220488f79829c954a23a5d8116cb6c1f3a7f968c946474d7ae89c03dc98fad031c001bad3463e1904da13d7c96540ab7f91dbc3fa55d5a51fcb26185899a6e4f1820a4a029deaee63cab9350144041b4bc0ff1f798f3005cdff1666b20ea20a662443164e271cd7f4b8e0878e8be80371dcb61affcbeeee9ac70b75dde28ef8fa0f9334670f78b210c606e2c031cae0690fc1fb35668368bd90df31805a7bf962d08166bd475ddb3d0b8e3982f40fe059bbb92b5c2a13ce214ca7f9e081b61f97ab9f76290a9e5f6952ff28fc74708cec47dc17d238e4ece5fa39ec30d3702a095d62c5697bbf1b16a2896d900cb8cd4da03845e67c169b1be0943632a70a8ba10a59c72274121577f06381c1a942e2d5d3037a598cd77ce452ec9005bfd85004fbde4ef92e3b83d0a3c137b620dd5f1ed42627a6c72182389615145be3005bd6f05712035d26b420e23b30ebf96f7c2b8ff593b915150835b9fb41fb76314e224b714ee391325e7d13e0454bd2101b25d62df3959890ec951416924c7cab4a526f309159ff695cabfafb6c307ba804859548190c9dc3569ad5afd4ee0dabae745122f7cab0d68d9891bf1e56ad88e9d812375882572b483bcfa43c0209531d016401585041a5bd4bf6e7493ede00140e093c0078bec78fbda77dad5409a558299dbc82a4864a95fc8cbd79ba7220d236cf9326d31aeea287a0c14fd37abf00ea929990c84b97b0a3561a51d42585670f56245b54cd39544b415ac7f22b0d54469974f5f0bef8e22a788f7c0daabee88ed228c6370e00eba8d52f39e2e81eef05fccbfa4927d82f9605d5b59fea9a37276e1f5657285d35227893189259253eb155657ccd11098282088515351b81ea5bf58466859c1e548677e7b5950ad63da593a0319f1d3007976ca1f31775f9533d362666f422ce334285e7baf33c887fe777f67900f571d4bc30f47810de6edf23fc6cb95d08d3689f6472684cf8d9142d510999d62e743e50d053dc228e0a71f995285086e221900f3af0574978a969a1c816fb77960400af781a8189bab0c7b3a1d3dd94f7b72f03ace29a8f7a1d5d5e8021ce4c9a0bda80d474af5febb981db571e0bdde13aa3ff5921a63ff1d6d565be3cf6883b6a88dc6880831c6141f12e654c0fc53408b1ec459bbd1b3a3079d937bac3b4acacdf7c96939e979862892d4264bf287659593f9f3285a2c585dfd92a5480934efcb8f0b32171e059e1e316fda13c4248efb6e8df384f572cf0e01dbcaaeb0aa3be46af58fe06cb4f67f9a30b38cfcf1e10e7fa29a705b7feadbcd2fe921a2088c637aad3c1f211dca78afcc86ffc2b2ad08d040fa75a82b3721a454f6c95eb6fa2f34b7663b1c1a73e5c05de62a23e74e9e0adb91a5c920144a81e0d31b28c93083f3cec7360016a7c15eb50d53873e6f3b5e8983d50af3ee5fbcbb24fc1c351fa8193111559fb3525d75f9650de951b13784ee0d06bd8485842ff9b79b2625343c451e700597422f2122f1c90a94fe04eb758598fe6a885b4f695e57ba909ae73cec804d984f3a9e3902cb81e5d1feed178ce03cbe7fe3e8a314d7fd6148fef5f5e33c88dd4ca3d7b9b8929f0f7f72f3de0ebdf1ebfffa98fc7fbc5c6b04c98fab81bf15305e205d9db51745979915e6b5f05b4bdf613a7a63b7a700fd53663a35370bfa030cfa7a68078834001bc667159ea9ca07ef09e960c3ff9db80e38102381814c9144ca20c0bf7bc23ea5cebf0a28a3adc65a4a431ca518b2ece70a09dcc8e458b161f9a6c7793d6fa6ec7809219917891228ebb9b0de49b44ddbd66604b666422053fbf9bae3f2c51e4ccf8a28352d5013cc1ebf0e94d54ab6416a1e4e360adced29f73197a924cae1202c421461c3b3220bcb194240fdc42d3987447086399ba784e732ec9143e09b8113cdb777ec2b9cd8328aaa3ce09326ef21393d08661bd7ab0a869a4177cb3dc9c2c7aaec24a01306aff2e8a394cec601008abc55c0ca617f721288802d8bd8cbb7179a6cfc1789310dc50e3fb42c12e8ae37269037e0974e72df4c0569f7f51a54716e9264dc8ebeca679ca336afc38e717c8aee094c8c18bc3191818b4a606f4fc0c887a2d7c198b9f182508365d00fa569a123f97a35f51bac81d8b040b1082adbcf56044cffad857513c465eaefecf42eaa715ec60ad40a8285b21e843978132451bd1dfe70b042dc82a47c614b465fd60656944f5bcc692eddcc150703c585e5cc030512a96949afebf99d54fa93b0f127df19030340bd5f7c98e79d86d74f7939734023110b4557dc122d4355ddf787f1e9603d8a6b39ea2aec8be07b36eb3cfb17e8bb68e8fc4d5f8d0151c724de61dd56619c11ee632740cc6e91d00a132c38881fb7d5eeccd7c491f500432b267ff8104ca0d87c08f3b3c5337eacd71568a04f423118e81b2e4770a8c206772867207de65cc294cd0c92ed7f3a23b6a468f93ed03862cf1ce7382ad4bf56a105622f1e5a45076fc96407871ee5b5d4c25e1529d03a322fafd5b70a312d9bf8d9edf2d589b6de2c10eff25acd788f9df2bbeb864ef978a75409e2f14d80dad739b67ec0a4b9102aa319e70d9513d2717b12d539980e04cc2889173a5257e62795979ec43d53d832b122974744895235bbe3b7b6718c9f74c61274a4895b06e74685b8193bee67fd7bd2b6250f13b3f2ee8d9e2b8bc4b3833a1870dc007608200bbcc21e3101e362414177ef0b7e5a0f213e096680b7d5303d051e94d599d9d1d550b192f5b74aec258306a9346b565e310cd0b46514773958e737e00cd340e30dbc42e5de6b6173711ddb2c3bd69d17faaca8a6ca59d13362ad2ccfe2b43406ceab1a80b0ea8beb194ab4bd4da1a91ad3fbc50b0589ddd2507a4b42c4b49b580b584eea4a6d6dca82d28882678051af5a7f7f7867bba470c22cac98183565120390928e3933440b1307df5ae4661a534da425485fb979b8e70a683130f50c727b007ed10ffb2f7293db88622a0f37420fcc11b820a8d874bace9c0decabe0973044c1a5c52a31ef61f2d883379c67a0df5158c42193bb7d1af5626b8ecac59fd1b03137587cc9b830f9f5bf5a9401299e7ca2df9ffdb8115d5077a60b67c243a771b3af3dc099c087a412aeb1fffde3bc61b396eccefb9131811f4dd70862d867577e9a778992243252229207036f6249e27f7e2b91318d1765e860dd6c97669f099233ffa035dc9a5925cd865b1524add23b65fcc915779912df22ba564bc99699fbd4929e185af7d55f18a2e8299b3fdf313da58e13c17999069d62214b74e82e3a1f46f0223ba2f96828b78bc74c1edf9f95b8189eca00d21f5d33cccedfcbc9b8113e17eab9b8abd9d5b3dbc06e9489c84b929bf7f53b067c46019cac3e1a8e7dd9f28d6b466294e52ad1c5be2ca7daa8066820a031091c8fdf8b84e0ff9777ed7b8e304c70f0a45b7a46510ce51579d2ef57c7aa71d9cf1a3bbccf8b1c2246e2868721dbaa82a2d9ed13b6fa9acb49ac1cfe676a3f49a884f4310a09300f2656eb4abe587bb77ce0307ceb201b949eaaed6d74ffedb01e32bde0d6804fe97e99c558fe028cb9e7d8fe7766ac0c40117b7c1ee157eff5376304ddb166baf86ca748ad8b7b7280a1670b8d880c0363a75a07e9e554198fab0db2cdc24fa09f5460cfb2424a083bf763858dcaeb0edfc771671b8cce66092257ded659fe4092dfc7fc81a251cf727ac34e50936b61908d512c25bfca14a530443ae6388a44fcc1b88c5fc7b5814223ae5524ff89a3b2bbd55f8822b1a168077672200d7ccd79a50b7752e607797ae4f54d2ed3556342e528b5452418f4b0203eb8048dc9a6f971e1f6578e36973f0611b555a944efef8a5cc2d83e74c326ace2d6a0d3dd24bac276600137d75eceef31a5628e996033d9b9b9c1095c86da64bfefb97031ca1c6cff302081d001e857071c978b6468d6a5f8971a12c08ffa6e4b7751bdcc2cee434e71f715fc9f7f0707a0dfbce004a0907c46a8cc6f676dc59c2d8b37f15b88836647cbacccaa52aff90dc7fa53baa4ac514dd76bbd9ede68656361f9f7b66e88159642df2fc4212554cb8da427cd90d0a3ea4ec1bf5000c87307370a8f60cc85dfe7146144bfe781e4aac0f0e248826b886e99e1ecc739ac7e39386afa0edbebd5c32bc9945ff19ff1fb4b448c048b8ade033d7e1bff228b4b27cdb0e3ac6c7aa44fb81e0b1277021f832d5e03c0b22e247db075c16b7769da72df12c5b337cb6b6806c905bee07412328f3b71e4b0aeb6ccd56b053118053f299e3b732efc7481b4d04c9ba4361f3444efd04eccf39ea33dbafa695be886985978213eed56dc34cbf372dc89527a666d3462908ed296811f34faa29dcb1b8117d6ea6aeef92c21ee95c4d01153565e0f44fda0ec5678d293cf86c7007ca9f24fec90c1a2114dbce0632e90ae01a79fbeed0e7e60d594f8f513be68f35fe84300ecc45b407158a865abb34c55ab7a54d9b1856e29a0f97d6f7e21c2cb55b893970084c4abb350faedaaa2a7808ae10ba3c18e27910276d7c106ed330b7f7a307fe18a7d390c5036794a8bbeef7083211812f52c0d6c83d4e85d4bed893d8e02f96e4f819f5f372171b0036c44f8008becac881064361314f9518e0d7baa93102c8c169d03ad21e128712aa6a890ba97537ce16ecac2d670520af2fb11d39c80564b7f4af945772932c875845f413c1296d14e016054ff646bcbeda17cd84c2456724748d6286332e51e7361a8e9a048f5fc899d94e137ec46b4cbd7e31178f31c08314452e93892d196c7125bfd25af50949021ebc0e577882894453e5f7a4a0c9e83c70b61a82e63bceb9f77a9c8457f9956bb9a3361a920b2c3e250f08d5753d26e7592bcf58d6c2264b63aa4611463c52f19b17bd3c34ee2f6e35cf0c2479bad2c36ef360bae57c235130474e8bb1a980e62a1951d73971178d1881132055fc10636f0513cd018f9f4fdc531d0444485c4565dc4687bad04564e0e6f78f80af7fde48680e6cd8242f6ba23a2e8cd88c2317848ca002c5babb74121df0cbe9738f1954c0c48e0131156790ce0acfccb0601f32928fb403662b9b1044a2866b95ff5608072523e10ed8ceb6f51b443ed776187307afe1725fcf4582a98c839b22777f92b12c6c09e8dc943fc7878927d33e82567827c778258f4d6ad8bcf696de742dd7a8e85fe071696b6f4002d3d0cd1219bd02e1d15c4850e9bd6e5bde92c91f78aa1ee4b4123904ae7b71316edd45df7d30b55003b98117f4a877f48a80cb2b7da63d5063fa632883fbd73175def2f62912a43b149d61e2c6a722f56662fb4ed2ea4428cc78b46ed74c4e3b9da101562231b39c3b095c69c3044cc969d916a9642adc988feb1c39b54a27dc39839412b513ab46e95860bd86756020164684a74cbdfdc9495e4208b48ea2f5ed6b7f5bc55f86e6bc507508e671a389aad41b880a0fadb443b58144be949251fe36c62c8a4226b542e776a16e387d8aaa67e6c2fd8b88701b4e2eb6465b52cbe2d95c3832a3a40d82ea2df668605a282bf57241000afd41f750f154a75f13675e308ef5ec17cb8b5394e1d719fc2820d9bcf061b5baa7b38256c5f43a4e3da72b47cbb4bda7e684ad2ed3d24ac06fd93fee712054463f8665c15f34b8c7a4113bdb231db30990df6a5da0d400dae9b640705ce502c5429d2aa5bbed65891285a66af405c3ba1a95a5d6b0e090d24e53a185948479030171d947f4edbf5597c332a1bb9f6593d8efb49f9e4a4d060384625359aa5cc1fe32a07cab5403476918ff6423262f8b416cd51cafb3121f091b36af63c16574c872376ab2d3dfe5e889dccb547649b9b44dc114c2d349d837e296ab87e8bbd41409712c228a40506002e1b85c931ae04aa32db040b57d49470ff1ba1eb4d9e7286d2412503c7b6f7931ed8e5703a868355db0c2ea8901000aa9b463a4492ae05574defbd4d6885876056fae23626c791934f7b0ac632901272863fda0ba381e010a12607f4d02c0c656563bc656cafd498209ad0552cf173d6c8849a5f2d86210b9f3fc4d166b2c429cb74ddab3947053e5edcb5b968e240f1f5266dd641167085435dfae240b7a9aec335e0445613b6292cb649a34626340d050aa73a55b10e120d462dae361b3e17027c3bb7c26264250f8713c5c053a7c658cdca784c6eff80ee58da9a8b1b26e84359c2bc32dce55122288d184854a5761c67f1861204a815ad22ce43285d701c36488600b3c4aba410801c3cf840be2f9e7cbba733e6a8c0ba9c8100c92cb1157bfee25fc276cfc87fcd49ae7fdce1264f55c88bb719c56684a5f03b4225891a156d45a67a6087c2c08959223e9e08c1f023164e5ca24d10134b466dc9e8f03b0b4741e473498e8c8a641b144927e838f1102312ef8a0d9018ded4a55b80b8cbe3e425d4ddaf800e8e603d23e76f14a00ed1a5286111fe4082b144d3728e9c353356b50d114374a7109f4d5f87442acdd40815a268844b1f3ec2a1f833e816a3ef43d522f830c4f6163dae3126a37f1dcce772347f75cf63e435afb4c0593410cb70feaa552932c621b588bf07232710908f1429508d4a6a8d901b18df7080e971989fc42ade60b273e4679d2a84ea38ff842920309d07ce2392127ccab8227a2fbe289471c913ddc4d9e42b2528b4eb60a06617c0112266386acd69de1a399502024a9b13c4a273fa0a93e4a1cb280d17b8812f0d838a7f8b8ff934ff003efc30994aa820a756ccf71d89a3dc300b583efe222043542f369dd1051b4a668a1eae1d656e17d81be585f299e775b4f00ec7bc66b5bb721e839213c38b9bb8b9a587df9e88f3683116bcd7e1204566cc82c884227331803f0196a7606c7089a3c589e68268e74954eddcac14e81d4cde74e9e7e12628fdd00cde2711dbbfa50db3bbb5576cd37f024916735be1cc25f163f666f8631fef7a5dbcf695b53e0a224f91a9186648ee798e548b170e2d7389c4f94d523899e6f00f5ad253f7d0b13da213eebb44ee2460fb4ba8fd4a415c3e919fed56f76c82bfd669094e1757785e4f944a2108e781765ed3c44e9feefe1977e48bdc5fb47a665acb3fd8cab992b81b403112f42784582a4810744b40f202d4495c991bc2b880047eeefcbf6d0a43541a91200344de32569669c10c715b7d1c815257a435e03202e4b6290cf581614b8e0beb49e3e87f4d749c693bc0d958afaa080833810dcee5ccf8da4edca2920b04b996de1e4b23a8566a72c989d46e90524014548a5dc484e63bc161225a72d2a1a706aa9bc5022fb50dab72289a1164f5b2c867b6c61d1713d6fd76108d860aafda1ed3c37741bf4658fbfa8350e6e68a425155c394729a5a5743e90d39121113d34e831768852115dabbb37d18704a664f82ee935bae41004ea6f6154a4f87bdffc4732d10a8cae083f653e9e65e7676115d320912f64f8503873f10b7f06c3d4e00ae67d11ed0fc2215a43ae6224eeb969e760e31d1bc1c327f8a1b7ab45c1ed215d25a0171b261b418d81a7bd707a3737447ef4bf858e081f0664c429a0d2ee908df44a066f4710b74860d57a94974c20b8dc4c3652b79e5eb741585f2bbbf0cfc0f5213450792e85e4204f42c61c64a27f2279949822cff2d43e362e0a67abd48bdb655bde665ec79c0b8f710fcd08140a907c7baac0a836c4c2e2dfa48388073bda9edfa20c264ab195acb83908e584be209f2616e1f76a7fa217ebff89f25e5750c555694d0a281f18e994c2fc051835f823ee5cc599519677052b714737be752e0c4872e0ac05b62d3005011c1019359ec508d0fa38f26f23d83f5bf0cf7a6f7906934e1f566b5dc40dc756253b6770f1a10f536e202df760610bb964915184ca40330ec84af604767a67fe1117900d79138f1dc23dc5995620ef35f4b18260ba35c8b620f52c886641593c67b10ee1e5920d5b65e3c0204069ca294751d4d9fb9f273c9ad2f130526d4c704f01d05de64dccfc06f182640e84743a8af691854430671cd2b4459084b13f87c00ca75eab55b166647a6b5f4df38acd4f608c5c0f4b33b63a831459de0573871e207b6296c908622eb1b344786293e10bd67c0e6c7f381bd344863c9ca37f69c7e34445428000cfabb43a36672e4d63defdf5cf4d70968a7ebd350b0d475feb790e6686d55cfc129a4d4e61324e17ac15d3095d95dd6ec31e2b8be5b563df42d93221cb12e6b47dc71d8cf6bf0fd7669707b20f72f57c86c80bcc98c1ae43f559536813fa4ea381e10db06e449d048ec11361d3a3dedd5b642896eceb4286a8dd37704777e440aff714a847cc80527c41203160a0cb0c1667030e948cdda3025b0a3b8b703293a1ce425e2776c0bf280fd83db0ab519ed4e36053b540d7fa0e37eadb68c7081b7070127d8bac749e21076ab58957e9dcb25ba9d2391667652c3ac92099b00cc483f06e355fd615e3137b84a96c07878c51b80ab87604bdcf1be76db358727513bc0351c7480234549b5ea2bf32676679ebf6ab9951e219b0719dacdd18c1ed3724ba843a42ca924d78574dde7f6d76a228e80fe5da3dd39047ce4ce3cf719427b27237514288627354e285ed029d2f4de7161d11200206f77711d0d4202f8a4a110713f43f62bd95d40162f33f89cba437927780f4889c58c9a8f2279f9772daf8db21e8c981e61f82f8c5efe3ae8301d97fe8c68980edc107958108d476bdea2f9e4574a98ff302454af407e600034141e6dc6cb05c11fbbcb8e1b5df2ba3ff8dc39f8388fa506435fbb1a9e63f8b541bae16098e39d10aa6d36b7160250dd48b506b30ffb4649b681364bc5d2fb88010a4627d503822b5fd4cfd31a011e2fb45b1e5008908484c1a00a1065daa802b81c9aef93fdba09d3c74073e2da5d34675002542cae837f5bf315b9d7ed52fcab473805ea09f6b969d5e4f5b06b8608ca9372b65d6294c4858d106895727e8a34953deb596d47284fd747241892c933ff55ed2fbd3307ca6ec7e2f2588ce9c0afeeb6423fd58f4aa37e83ab25abe277dbe529a4e392ea74e3d06afac36473ca2d5bf2fe27f5527bf3f791adf9973979fd8433e8c4e03fed67e605a5cca037aa6ca85572096324a073e8155592b67bf749b718501f2159383dff418acf907d5223f31c50ff4d52f90fb2e323cd801ce62729b9bbc70c163e6b9c7964a0801257f92d591190fa43d793a0a48862dbf259290bde5de524a29534a32cd0730083c082e3b82d98c55395038e138327f4bcdd068a7ee61d56847e65b2ff3451afb1a6df4345a9dd14aef321b5a25f34082102955ed473d3c3d3c3d3c3d3c3d3c4f3b33823a9b95845d3c2d9ea5b1dce757ee7bcff49b03996c7c5b7dea3a5a31daed7a14e2e78896ddf1269be34d8f42bdf53a3493f53bace97568282d87e6e0c97a95ffdd6a6f306baa7993ac7978e5abb137fcf03e3872e87ea6bfb8bd6766c68a80ee9c3ee4f4a2ff7815b7e255fcc7818adc73a022fff12afe73d26a88b4902da59a4f04870bab0c6b2e6c544f1aabfe4e938eadf5f43a3ec4399116226d741dd7711d23349c9e757cfaf4e9d34fd6790f222f5877777620ffa1691a2250ba438c7a131f722603bc31ca5f61fe2dc456465a52da27e550bfcc888c9108da27f4e493f1b99373c1f48e59cbd616629a733ead5306b28cf3bf1e1b7d67268daf0cb4ce4dcbedc8ab7cce9136baf551da93f351e79cb59e4effa9148e85ef573042f84858502f0a5304b1bc2b7e63dfc8373af6d16e418ef08574dbdebf4bed8db314b3f2fa0df614b3b4ad92bedb7d9605fee1361669771131899059e004c0f82ec8cb8cb0dd56f05980415ac8732cc019a817e9a8cd48bf883fb54e5e3ab523f2277d4ca3d1889b58a7a466ea14e35816f887af6e4ce2f7d9e72ea65fd4f65261855f63adeda562b5b6975ab3c9cccccc9cf5500ff5900ab0c6de7b2c422637d7bbcb525a4c308c8e3e9b32226d22208dacef26dda49b7413ac63134a134a0996e097649ca5d284529a543299929df3fa6c7e76652599cc94cd4b62b33e13963d767d2946c7332cc325aeccf1ea9996e952d726f5a889cc2833ca8ce2ac1cd0f7ba335859a862d2fa5a2d5a223db5227d3aa3c9d08ca9d052e52cb31bc6d67317eef2221b995bc920849fc958b3ecca2a9665d7d7f935ab5fa4b19a5d9f237b5e31cc6e4a7c6ba1083fcb6af6ae49a3ce30fff11fffb9128cc62084fedacd26ff491f45b7aebf4a18863daa07bb4ada0d7d37af2fcd2f5d58e98b74467fca609ffd561fbbe07b977ec3307b612e53cab04b433de11f9735ed764b2c81f01d87f2fc88d224c548aa17e97a1289547f93798e9f633e134d0d8e113f8e1a9a527b612f332312a95449cee33ccee33ccef356b52598af6ea5c2ea571cc881fcc77f666af52a6ea54a3aa294d29fe1caf5eb56239c21bd8924546bad5c6bad95fdc77ffcc77ffc87493acda48f20b50ee99b09e9c1cb923bbdd34dbac9884422914695448a3f1a91485fa46b8e293ec47b543ba52443922975936ed24dba4937c95a664142f5a09a2041120aca86f241f9a09e9848a41c44a447f590504d9828a5f44d922b0de9eb6f334f929f036e394013e94924bbe5d0555ec9924896c62ae96bb29b0856db8c75553eea09ea09ea09ea09ea49cbb0dc42698c31c617df663d74d675bd283f3e7859b2ced58d33d78c7693bd235d33339147fc99cc8fde68f4667e53f246a33a7a26aba42f6b37d208a376b3a6357117f82cd6ab524b2198269449c5044d53ca9432a3cc282693e92714d3a44263324d9f09653691c469704c29a488e337d2934c31d6309f524088441cb1862695020284489c5166941965469951f807bc7c60729988ebb29821e652d2e69852486fb6ebe3f370255fcc504e3091be95493a33436766e8cc0c9d99b919bda3a49999a7b45699c449f547334afad6dfd8fa0d32cfd84d04ab4da6922ccdb4d7989dde43fcc3d429c62a4b2efff1a58c32ca28a37c54debd7f97eff25dbebbff22feda36a9bc7ce7fe7ffafcbfd984734efebb94f2ba0095ba2989d7bf95c2c77f7f6a7a339246cac82a473293d26e25138d4ccdac1a992aa5ac916f92915faaf2a58ca9e69443c73f8f1fc0bf00fe03f06ff30f807fab7d8fb75b0af19f87dd6137223a2c0a764b9d70d8ed6b68ec8c8c2c5592356129744646cf09e79c73f6ec23e6d46926ed73ce9e734e48336b53e255a6146d69f42ad6c3bbc943827b4b2965cb9652a29ae86e1414b949d952ca19a774f99db953aad9adb37739c0641a66adcb9a3012cb366813514a6987a1943aed3094b6970643296d224ae95547f449f42b1d3977d96dd543264c7ed15906b32ccbb22894719818dbb32dcbb22c7b8f66d8cba6dd9c4afcaa6464336b6594a9ccc85d4c58d6320c8ff2f993fc499144223d52fc27497392482452961b284956ca27fff923914891442245fa16e9e36f2eed36c4f4a4529d31619544fa1a52cd931e07497e8d666732196ab79509ab3dd9783d6fe7397950e4f57aa494d38eb01166b73ae7b4f34da6199912f6de7bcf8867c433226b2985af7bce398ed13f7e7b8977c677d769eeca48644929e94bd2958de693461946ad1eeaa11e825ce444f9bc397310cd47f5cc37514d4c948fbbe69c9bd5bf3d3157ca691be8ca774f6aa9b55bcf2faba42d7fd413d413d413d49311c33131cacde394d2abb895e93042077a0e747de6b7ec2d6ff93358b5344f9a26cdf4f369e6d768ce4993e61c56b2b41672e9eefee33ffe139fd03badd34cfa08f99cf74efd0dfb492a5d5573dd436e4adc493a5212add6de6dcbbdbb4937e92658c32ff435b39392c340e94c44c246b5da4dc923698ea96458b44ade8d54fc3deec25db80b77f115a9a19737a550f7e8fcddf471d36f74efee94f0fdbaa9a4efb3d2dd816468e85ba69a772099652019bb4d1abbd537758d2dd9ed47760392d98d48e39829d9875b9c18a8056299adfdcc3be78600e071a080da21006df6b0d1e603c06ada6b4ae2a76079d88dc80ebb010182b2ff3356a6546d54067b9ad33274841e159dc19e86e3a8f8d253a4e2c15dc9820418d57bd7707444a1e2c1b484ea59d72d98b0a77112965004918ad2604f63255c81c18e8ad6604fe32a72c0041f15c5813dcd350704514fd8d35c1a573021525114723837de780216956b3aa250399b76265067f3fc591cf621891f00a1e2813651cd6ea11f3e1c94972bea366ff51e4c2adb375135bc870ff99fc5e129b644d151f160ad40f57ea5720d5583e3e0f0c0c14a950384118854d49b9dbfd1b6bacef9e8a108368454aea1bca89c4d73f70fdd4a1a4c94f229dbd595cf4f1bae2ed494f47df6861564b6824ecca166bd37f39cd38acf5de77c4c291d83daf50efb29bc6e9cf371e5f5d1ff883ffda75d5fc47d75a9c63da8229f9f651f5acbdf9590358e187459c4bc07fcc38d40b79a1c6300042f7e2226827f5d8fa970179e0284c81524d50377e9618a7bf7ee6dbc4713355146b179c599b5971efaff07a28788868886888688868886888098588d6770a37c503e4411a29ee420423dd9c2e5faf3c8413d413dc98190a10dbca9252784dd8f759430c6f7b4bf52c0d3c3d3c3d3c3d3c3d3c3d39302f81c0d8ac3ebf7774ac141cb9471beaf91ef4ff1d91c715ed8a83ed308b3db3b8b45de41c5098573965cc7e1bb877f0ebb393127bbb9a21a6bb7f9bfc33b3c96cc28a61965499d58b58a409dcde68ada66c8c981a0840f42d27bf64e0a61d77c2f7ea95ed7233e181f6a8f7ff4432dda8dddca7dcf94d916b942830f39f5acd3ca20fc2708aca515d4d940ec62cb04de1357ded3294e22afe4e1368c7f9deef5ec3c426d8bf850e77bcec307e07f8fe174cb6e1fea7b286113a8b3696a3a61efc5b8f170df77f79cdc4f35d73a1648a78840cdff6997c6e387d3109c205ed54df8003896230fdbaa533c7e70336a53360ca2177c41541245230932bb268646dd1cd04442bda10fb3a71756fa8c7975bdcb32ac0ab5fe53bd4aad66d49a845a7fae9881d58a04acc2ea3ffc03b398ff60b67a95ea3f59f41f2b8ce7a613e22ef7bec8116542dd1cd094628c8a38200608c8117d978d24953d246d10222f0421f282fb02658351428dcf415ed82146e51830ac87f84766b3188a38c065e9a1cc420c4ab851582774195b49e020a5d5717d4a3b31227941c96ad48d75ee0e2ef5663ebca085fdc50c254339a338d3e9d3a967717278094e0b79394bdc93444fce269650e33b61c90e2e9559877d5a089d51f88765a52559070c3b9951209d3e3a7446811716d6c25ba2d0b5a08e93ce39275927daa973a3f08fcb0dea6c74604f670c33065f328609a3decceba7b446578c97155b67663083eec531626c27b18c0a67b4b26c471895adec65365a7166add34d56f1316aafb74ddb4de0234d365400f2a9cc7b765451d9be8941cc6171f7497946c58250b99a1e3e2adfab49c7055b484208b58a9da0f3b417abe397212f27c7449d62ce8c48f7bc30b576a451b79f60d41bf9f06e7fe9b710ebfa8cbe532db3de7a9751669e62311d261dcecb2342468dcf3ac0a87cb7bf1202094284bb6c2fd8a8c05d5888a73477d99ef6b88ba56d61419d4d0361cefde9623bb11e624bb2ad3b8aead65db8cb9abb3b84eacdf5d09234b320c347f96c2b86392e5bc4a1853bd009ecd969214e604f0b89eec11d43ee3e082d94bb034c8dcf7007f6ec10aabca5b978792d047b473de11f765b359716b2c92cb70b1772d96593f8983117fef66cc3b8d3ef45b0923fed9603cc7d566ab1c0e8329f11a6aae3cdd363cf08bfc2cccc8f86e6df430821cdd644af34136988cf88b7b3f38c783ddbea19c1efed3c235e0fef74ea391dbc87e3f8195bb2241b430b81af82da06e44aab83753dcd9e8b48a5190971684ea543b42e8a4363552a75e7974838e0471d663d7d94a9948f8f8f0fc4f1ece373d6d39c3e38ec8440d462c0f27a9e11a6ae612c668b2d8bb3677e4f47d888342232ca7e8a808aa6b4943126311166661e59cc6c315b96658367d43a66491609fe834d9303b97a7afea38d7e6a72f4414e369d923fd2be533231d3fa9aa085c09c2d5bae3fcfeec9dcdcdc6cc1e00e84bbbb475f4828e541719f3e827b769c60147352f3d61c99a6c7afd564e79cd3649a26d334fd34994c76e369fa53cd464ff6ad9a1a7b63fa9ac6bcbcc963aaa9b1ce53ad7427ce038bb413274e9c3819bd671e5d7172058b4eae3871728587733a6573677777f76d9b1bbf755aa775babb89bce084c7098f131e273c4e786a9a46a80b4f217a3c85a887a710f114a21e9ee26070176c9a98c8d5d3e32e4e8569d9571834cbce68260d9b29e2a71913a9f4264de667b4926495d4b6d3b5acdb39ad2fd2a71136f22fe2f36d522a74ca8988888888685335609857e4609a88bd600087893d3ba1f73eb3b44dcb7ec3ded96795f465d91b67b1cf7e9b9fd139e1c8deccc726666f9837f00f2774c30d1810bac109f14eb43760e0061c6ec0c00d38f0ce0d37cc2c7bca1a3fc60f2d6604fb6c6a996747e4c4aae974c30d4237609c6979edc471a97246be0ddc85bdd8c05dd8cbb381bd70171bdecf7c46d2a2296a0f8a7961bca8c1d8b0b197ce6cb41ea7e5bcdc68fd4c2c454a5fbb80953a6d0e18e6b277f03e2b9396bb90248cd7335df9d77b4f87fbdc983163ded874dc6bcbe1461b02d37df6e6fa0bb37ea4312123639289f58b34cc2850fa999f9d925f8a2f33994c8b7f4da024432f4d3e67d196eea5597ffdd5a9abc7f5a597d196dc6034df6549461a13f5a566c4bdeed1a9938eb7a9b6760ff6c25dde2aebd28ff7700f16534de63cbee33cde83c579bc078bf3bca74178ce53b193f73c938ee93cf461329a5359da9c9dc18059f7256d760ff9553b750f39eaccf4256de6475acd578d2635a399341a0d883ecca49d7e46cbf1351a8ea7d150788859a72f69397ea4e1f8aaa1f001ce3722d781dc834850e75cc830eadce59c35ef66bbbb5b46e7e0ebf7daddefbadb39c76e34b294a0d975ef5cc05ca00f9248f3ba1d8d2e95a3919cd6659b39175cbc1e1d615ed961188665d80873ce05e7487434a2f4f1404f0d51a17bf4e8aac0238bcabfa970555045adcef9191327efd1cf0297cabf9d1cf74805e7a3552aa8d02ce88652c064fe438594362c1af8f03ccb7b962704618a31c670d18424545bbd414bceb80d822b2c18a20824b6a062cb755dd0922f1785eb829664d941d74086d03908df39e8aa7307c695ef58929793d382ab243e5fcf90e0b8f2bd53e8357eb94f199f5bd6655960b4737fa807fd3df770cad810be079f6befdde10ccf2d1fd0748dcb08bde7b4e63ce29e70dff36833da4a709f956d1871fd5cf76a726f11995fcfeecd65f49ed39a93e4ee6c212476f7fc9dbf7687fc9efbf3475b73f7e7de738e85d15602b6186e4179328411151f8cf17ad4654df95e7cecbe3d0641b83aee77497fd9314a0d7559939f8c91efa7e010fa30d53d6c908851dd6f36146a51fbf9c8bb40aaa8eeba185f1a9213d039d75f9e31e5f59fd9b33caa54bf2ec80730f4faf3b0a2ba477284dacf0fc4b9705d7f2aa18cd868bba1e79b3ee1646db4ad96b8f27d844e748adf08de9d4aea75b7ccc46ffa7c1ea9696e2696f33d95186b3c9e78cf6ace873f8f28ea66baeeef875495432d688efbfafa19d5b09b79caf8dcdb9ffb05ff0a094208a1fb3be773caf8183a67ff37833f3fec7fd66376eccdabc9ae84f8ce861f33f3004275575ba7497be4bd7fc3b0c2ed7ed7d6af7f6ffeafa3fb83ceb52438b73b498cd9fb87f923b13c6633f88319128fc0742b9bc11fc86dfbf0398be315cac34a7d73fe78f4ecc80ad1756a0599a9b404e20750d0efebb20b3815665140f942049cbc005e794c51618838ef79b8541452807efc91f4256747dc1757c59115aef5f3d98d866b6533681b0d773ebdb0f711f56e74ebce702756b3a8b910b57e301e56aabb4ed5cfff24cc8cc867d49371ebe70b65c9474df9a8969c04273ebe2f4302ff3dcd30aaa1fa572edf57b8647c19610022e35f6a501e3ff53dcf08233c018d61a32811c4f03efe039c084c90939393734790c28df686fe7b128f2b153e0dfe30689bf5395c973eb5869c78411608b821275e80c5a5d7cb66b8ae75651e63fcda422eebd250345e4c3768fda5a11e0aa2667c948c17ce9597941f3d43325f7a26c375a98d56be74cdae537c25cb25a8b371773a0250fd4f30be347a66e46df2a37cdcefe343cdc79293b8bb312279d90656452fc0ac12d9d7d17d8f2101d366903df65c80cd7de144ce55e2373615bb359519acc4c8a206106460f17100f69d3d6075dfcf4c03ce0158f3e08a20da11a40085bfb38138bd92fdca702d04c31ec3b02d62d8e85deca1b6656f65d8a328eac21e6561239804e7c6517c2cfee42145bdc1fedd4c976d18ce0f3c467503f83c5caa0c49468117d880429621275e9065c8891e95f3f8e1f1838abd7fff114cbbc1fe8d465f5f6664c48fa1d882239c3bdae86f173ff6504351eb51172a5a8f620b8e34be309301fbf918f6d71dd9243ce642bbd170b1f8969dab8ba31befdddda1bb3b4cc24097ff3d60a5c2e6ce8f55d636f8dedcfecdccdcdeeeeffd75eaf990de3b5ecd77a8d90c71eedbac4d435928898aaf992f379266082164763344fbec9ce1b29c0f1e51d466e6e6e77cb455e042fb5a08d3d9f3dbba307fd2a9f59ddf7f33edec54ef50e49220eeb0cab94918703907c62b2697ef784051f9a7fb7277f8cc3dc75e66c459432254dd7bc8fe45fc6533c07fffcfdd243ce66e34dc393f4e6957b8343f54f93c331856a8c27db1b30abd9e622d84fef517fd820856aeb430ea775b258917d5b6ec292af3887333ea7e7bbf8d508d72a8871a799c717e12cf6478943ecc9090fe88733eb2a79ab66df4df468d6cf4089d1685e47dd436b619c321ea4cceb4c16fd750f01a7938176ef337f95b4459f6c875dda3264ada23d745457be4ba7efbf275b788432d09ce8533bc0b3f094a06f8efa15d4d6e2aba1710853471c59230686b4ba8dbbceea8b89e85143ad71f6b213da7f8e927a0fce8ede7ee66f782633c78505dd092236ae81c55447284eabac012e66e29544700f45b007e1c5eb9f796a7e1e2063b4d0822cc133d869809f44ff8f80c010921e854b1c201500f971dd0a0074510d1865bc3013d10316b4c29562ca082054308c20b25c47821c1972728c10d286a44d1c4b5088205506011e3c74b0da09cd105162222c2c841107eb8c2c3b802267185db525bf0bbc97fc2e230301204cf10b614755144943e8206b420e3063d4c7a4044959fcb67d8800b283d14d1e5064ea8588a175fc4a0e20a1e19a4a1e23f6179513c2d3618a2072b2d708305338955132a2822688b1421ae588153a38a2b35b852050c6c90c6fc4109c640e20d276bbc4184456fe1de7da0b798d7650cc48a7a9aee9d07827cc8b92ec8072e178beb827cd8b9a616e27f722ecc975bdce0dd4cb7ff59b9feeeb9c8b92338ddcd0439393957c98964fd36f271b77addf55b7677d841c9bc3bc0bf34763efc2dadfd4a18e385dbec0b6f9d7ef96ed3835ea9843933b35542e1f6972cb67092c5109a6020ea2b5157250b2d455a7a2e67a14598cbfc8300a42bb752b94d5c313ab7856c3a6e982e6eff6ce7cdcfc1114a8677dd9aae6b2e8b989eab03caccccccccec9c0f1b4e2e075597858d25f7ba2c6b88c9b286976bea14f350e5304354b6a8286ff1848fca351d3f382d7e68324505849e368a54aea17ea0a20f7b9af30248082c2a0ad16043474523175de8a838089f221d159d46e8a0688a853d8d5df045133a2ad7763041452f35c068b2a3a2748d253b2a8a690973c61615cdae204215151d614f6331b830a248454948fc00a4a2958a245c2046454b56ac88510550661025c6074f3a5c25334e1b02ec4a7bf39ec2a7bd4c8e2629feec54bb4fccca8c58d63527c94e9bec08a5f3e35bf1e79cd3fd298d914697324a4927b526b55294d239a765cd1f4c5c9d6d99620c950714b4a305f3094a01d0182aa615cf1527a0c1032126c60ce5608994213496dc4009675051049096290270c2658b0f4649ce31490b038cba3d2e47d08111ea96c9f0ee743e8a704da9dbdb52b7f9450ebc2042dd5e175c6c31041c68d1a26e330b2da86e2f4bdd1e1642a8dbbca26e4fc3624510ea36abb852b709841dd4ed51a183bacd29ae74ca7d010ac040757b9a14efc6cf0fea66004cb312850645dd66907e27ac723ff7bb91202d1ca085165a60c100407eace0438502b440801ea901082000362d00c06a2d7c0a3c76e840e540a185138e1a1a530b2d78f302503230e026e1316d37145cb6f3a78b2edfd9a779c3f6d4a9eedaa6d36366eb2aa80100c3434b6d7e1f32a8bde4fa3f3ba48b545de445688198a22fb4387618a6cd224daabbff10023dc4a9a04b71b9b00b213109448451c68dff5cec2bd459b9fc4eca45d50055fd7c99681e985dc88648455a82749470a306439904b238a10932aab8808d32463e643923094c5cf093f3301c54f1de7befdf7b87f1bdf7de7befbdf79efb7bef592fc6e71fa3bff8de29c6f7e2b3014aa9f03620d09f3b3faff739bfdbc4e70f0b8ac231c6874f32332761a9e47208b0cbf6063e43abe321f6b238faca6ca56466c4999dadc81f7914ed898ff85ff17f4a4a2dfa5e7c58a72ebb9d6ea539acdfe49c73c68e335a156c8000010a42e405185f5bb7ecc30a2d575f601e108f6ece39af6b74716acee99e35634cc519e37435c668c24e17c8db78dc74dcf8cc8f999999996d66a718d3010d200f95dbe3ba201e9df72efd22cd04967d917673ce39e7758d2ee6ccea38c1e787d3b6c53c2d2c336259d3bd629d7af0f9a1a35766c421d4d129934d0a7e84f6758ff7f16566249e74dc37271b895bbd0f7e34f26c98991d74d03921af87b02a6b2288083157bb2e6827cc731861bdfddc32a1f32a695ff7e07f8fddafb04fd01235d4a892c5f413441b61f40c3909a30726748abcf88cb102d3bb9273c1a425206807402af652832a5354339a0c1815f5190d2713826ae64d1a0e4d501b674c51d1e004015533cfc3a381caf4341a0e0fed032b62543770de649e7f754bbfbaf55797f4ab3bfa15f6ab4b7ff5ab3b7f75e5af6efcd585bfbaef579707d216455099dedda8fe1ad62df0977e847121b2261386725d9bd19e83a36d7551354015cdf7ddf83241c3a619cda960103b405f30f1a2a8076989f3e1dec812d5f5078ada6191927bf2a43146e8dcf570dffd8a2877c396d73b13b41098d342e66fd99c1620b3ba1a436aba1b6fcca153fd814e75078ca8fc495c0a3e1356709f461dd0d856435c1a0eae077c4b83453bd7657840409b13f2e1ff6e0754e4faf33b9d5c91e414ac49ef76d2f136a7d7c1852e91c41b038b144f0d3450f031aa161df4606609537420a970f28654c30babb750638c48851a65bccb39f26e36b7dd95db5b9c1647e48a8608f2e2f61701e3f6e34074bb3be7f4277a5dd010545c795dd010519cb48cb00ce1c32d9f1f438e4c1a5d77b789c2650d31a5a17c976669acf5e6d7317eb672730d9a589133fa8344b07265173a57ce1ff2457fedd22cad9d0ff9537b7746f8fc4dbbf9cf977edd7ddbacf2fdc6ffdd1bf789391fd96dd2edda2905f8503729df13166c11b365a767a8723e8a749904eff2a364609fcbd67d718130846de5dd9c0fff66feeb0b744910b35774492043a29d912062429704d8c8b9b003e7dc240cb85d736ec37ed75dd921892bcac9b94a64aef5ee4ab06be9707b87240cb8ed7cf02b8937f60ef195c40cdc4e21090320b05281bf5f489c72eb57c2f7bd0d8c4054f86084a765274bd1982f3e18e16ac0144d90c184284fb0418430acc8c2c613c6142154c5ce1453bce184cc192394869629de70c242810a95a12f3e30f1854f0f5778d084225630c58b25a08e78ffd69c80514e10e7c3a99c0ddec3fdbaef51715ac8c617e73dbbe580a570bcd4f79b0b63029c8d7bb8fe0cf0a9a9cd69e1a24e35aa8688e3c6bca18a164543fc958a81fc71f0212b95d3e084eb5fc3077cc853f9ebe0431c90ca1d05210d3d845d0074e5050814b40233329f20264feee688aeafa08b1c4fc8e6b2a484cc2b40b81b769d161c3e40830dcccc73ba8947126ac77799059e2a5a1c1e54ec63b3710e9440eecbb9ee5ee43ae0ba2bbaf23d1a6a6022202ea122dea3896c01c25a2ed780598fa5f881b8ac6519c87bf0c580f3f1a5eae04364ca2043054288c1921e2caa7e13f8900724a5e7270949b49103553f0e1fe8e76e547e4fc11a6f108d2103c8883482d64042070a255009638479b9a85e938f276a009a6004215c30c51369b440d55bf08ce959e30a2831e881f643e5bb0312bf6e79b8ee1675245e7fb7a7eb034cfd1234c18a1d00094144194550f513f1211b172f80011451988125052ae78511d2e891e28c160ca10c557fca8770008a2ba4b0e209296250a4ea77362d5b62c901543426065ac47091b3c4f4405011400461065ac44009152ba186194f7c004483237680b8e6148d09420b1b53a618d3c614c20d30cc58e2091a742182288c7b029112823004298ec8619223457201a70409a1854a162690c1c5e5cb5f90f8f587c1aff3e004b87b6ba00102ec821608f143143c187a4244118a90c1143ca0d2041fec4c417988caef4a10892984258b1390b880b284e192c5093a3d20218354b0250732415d77a9dc43de336f7ff98360519d8adfe788eb827c985cd7c5754149f0e0d2ce827c38c847cb656626de732683fb7299d079d5b3afb3948dfd4ef10a51ea5ffe14bc9f3cc0a81c3fc29843ea1ae9797dfebc29af3ec4891992620c2f53a01c41089c33c468230a2cba3882122a1574011a62893078aa204185012b4b4c71840f8000420b546650d74242c062dc1be7ded970159622a68848a887777438c7bdebb1b9c0ccec83d3d262dc4e42595bc2dc52b7bf8b70fbab94e6e9435047fa3a1f38c10c312aa80225847454da90ca7de50414803637f3d5964f77ff1eb77d3142f9a65b7d31a5a37fdd5306ce87dbd8e9a0efd52adcddb7e7efbdc7ce9d3b771ea672a8e44d7745b563666800200000000316000030100a86c321c1589c2792e0d3031400117d964e6c509588044a94a328831032c6186000100030004343db2401d0b2dfdaf659dbedaf5b312437231ac34becd7053d9263f89f5dba30c9f726ebb09425b5d0e324ec11c41984c6e491c6c701b5a0561b7260ad6aaf75efec6918ab1c1080b124e77df65bd2d10331cc86fe1f510a5e75384e2046bc5c9867eed1c9b4319dcc2a7047951da8fdc58017d9437efaf09098a4d5f7701253b72f3025a8ca492a2499b07dea387880fd1626cc480762d18990f3f7ac239d2554f0adb75591aab19d9ca5b1f28de03feb9448c7e009dfe547d87ccb49ef0d70e48e332199f2b79e7975fce5eb2a671dc3d2ced3152819927b2a57949cf9f732e1fdc5ad957092104201bcab8ca20e2edaba5f5052470f748c223d7092cba2fa69120dc66b3de6c29416c61797c9bf652c9af985b4f7bb9b3f8d58b6b74ee6c568ff3d137025870d588ce4747cadb9f62ec2198d79e2ceca55aa12a23e0b8b8aea23941a68f624a7a1d92a2a21d4511fd71bf15ea2a0d4bd4994d25387ee71ab27cb5b4d9b1fbd0cdf63d1641ba10a2fc8721602bf296dfcb5aae5fa0414d5fef00deab90437e47adfee6aa9d57855c1381682a612729652aec36b42e7f26e8972be4b283edf5743b24b089bc49faacc527cf12399a54cfe12447075a9b5800214d3a7ff809e31113ab25ab5a974d070d6a82f33a9d4dbf6dba05ed9ebd16b0b8ef4566c2017624be1642b2d30acf90448e4c2e8ff7254e7261cc7d144ce969ae76c5929a9392b2346bf037babce4cf2a66b8013414cb75b3336ae713941a4d2d3e94b5b5a5713d5edb63d315ab43644b147872b11e323c483e7614fefb3117704e190f7b8f9704d6383c778ee556f1aee81e69c27b8105fad40848ae191fba294db75ba68cf0f73af2f82bcf7cc4ed055558d5c0413b521e459b216dce68a0b05ea272331f6e912bfcacdc5a6ffaf5f9b1a88eb630530fb73c99c1b7b8d7b46bbdd72408eb54a82a1f8984c8118d8da3a6040091a9c3343bdb1a53f1b01c855a31e0e666e35310033af1ec957275ae92e28be5740ab079573073dae2f6e2020085118652bb0bf8495197a5338847a1414a198ae5ec54177154b8fb57bef1082d6578928db166bbed1f26c5c8ec4ba779d02e2dfe77679117f55d44f465c7a7cd30dc3b2611978d6f967dc9934ba0681e32ac1bf1965a8b70f9a8c497e1ad25ed6a67f90249917be2cf938f7793b15c268a294c562ce4ad2a443246c43f793218e2414ee7ae6eb6152f1d6b002aa7db68916afaeff60d6c5e8ab18f27396743c2793b00a2367d2c4e81d077c0a17f93ea6af457dbdfcaadfadf8a223faeaf5c312bf5fcb765f16221f5265d3a1a3e567a2ff85288208d579b262b467f7817c5608800ff67d33aeacc61533c87e59428a9bf4a928c1860f19c9d45806aefb16a0e535cbbf25bccc8df2f782c7fb73c61b025c73f98dee1e33fb5d1d07fac86ee4c39af04fd289715695555cdd705752749fc0eb5eac8fa0dbc31641acdfbb01878e1ae89e8614367237fe6aaeaad6af6bbd921eb93a1e3439008789c0c6a462d589814b8d3e3b77c92760dc588f4ee906a912991b22f0e396281f9f8deafa89b7897fe6514b6eb5dc5b9b59a55635a4eafcd53eb823554bd03fcac8d773b9dddaa1ecb3ae68b7385c143caa1dd629c6cb4646c517874c1dae5cc9d198fe13f2b1b2f444b67dc09021dca30b9548511ab56cc42167651f8e86d53008e5871ed6410904c84499cb132ccd975c10570703080ff8897040afdd9cb86f75001c26505464be43452eddd32e902aaba3a9ead8f65b67fe7664772fd365d47bd80cd6db71c0d00bed663e8d143e63889cb2f671c7e743b8899e12c6140e134e7f340dfed43d7b4f7764ef0343ea3ae9e9cfb697723d145f6bfe81d5b48a0c9bbfcd0e42371198788b1d75b09d11c172b0a7b708278607582e8fbbe5afb10375b52c71c6532dcfe4e8efdf9553f596c9eef1bab0f2c61f2e22b1ebd95729e35a76fefab7ea349d445c0ec5b1738d0a908cbb87045673ee3b4abecc191185eddca092fbf2a0d7a8034f3ae8c10f1efbebe5b8b7085af078beed3e689ece7d53b6457a8878eec857e8126f9f2170cbaa9fa998e7e6c40076c76203086959b109f8fba0f4563b50fa69f27dab7b807ed8324ad5ea7f2e57ae207c1353e1d5188e9611e8b99aeccf8b15e895c13dc0b997c79f236e9e4cc9826bbaa1d9e8a88608a29cb4d1e12352af49d5c1ea83720d3b8d4a8d899dad02e82414c3c4f273a0bd938c9664d5b95332f921ef61e61a3afcb436150b1e4a09481ba285752fa89b9e4cfbbe5349ee507238bac54f527915e75b2fce39e9d70e7a03f28fde90072bd601cf6a4fd998bdacaeb191eccf409073d28786591a4ecb5748d00051f50d34a76acc13255815ad6d34044cc0f8c75ae7a9fab8a1adac8c0ffea5c504f474d1bf011d835547293c60b02f771eeb10b3d37b6e51f224df80247a8a2258e2c583e2c602813f71d1b956bc5b48b1360bb650ce87ad1f7efacad88dceafc97557540e1dbc8efa3db885d692d18d38c3dab1affc60da925b9e43bd4e7e540199c1410fcd9137111405f0e4cfe014e2b581b36ec6f0d7e51655186a69cf2b56ddfae4a9d5ca4ff4a0410cef6b2b83ee94522335ac6923228932958e9fbf0cea3c9af390d9afaa89f643363ba3dbbbf65ee708d6a8600bd09df16a4e5eb2355eb4cdea3b071c00c2d9871a3b0b0a21e4a9f29687f7315833213d864c33e91c77c2337c2dcdfc14eefb74f889f408e854fc7c977f3787242a7287a0a4fc8f099fdd266c8dc6254feb47b8ba29c6cf8efb852343101c1a19046f6b8e6ae25af5339bf98c35120f9d4b9d853b61620a12a3b1a502fcc2b725ab204ae20628bde608c181cced2817d58297b96f7acb5cbfa9f49a1ffbff359d7c2e0bfb70fec3670c4d84141286b6d964d3867e87c5ecef90cf93e589088be9d88532ae317101877d353a513bc2d4aec029caf1271ba3a0df82cd30e06706b27d456d32cf310e035cf64add2cf604e969beeec00e20f1123aea8ec01a263bf12454a58ede0517eba7886bed95ad1e261f372b7473303f7fde0c18b0bf3547c1d54fdd1d08192ded3ff0c72bf4bbbcf20980b7c4eb9eb7d53bae9ae8db13881d8de207b9bd00973c10b87b9f1e31cafa077168582a281df4c53a30678bcc9c353992b6a6f0f2ac4b2fd1f34b1764a7eadaa1b1b311839a9abaf0e22aa768b91a8deb84aebaf85cc4a5e440b994b80bd0ee818dce79bc6927b9b15ed0c724606c537d50929c68fc26863b5ded397c351065e235a5ca4b799293486d748d2b84e7064d83873adf38e3612616152ed2e679d0f926d53f9522b23d5ad6e1875d7d3de104e85ad42e79d8759ead4ddc48e476aa48beb140fdb358e513a66f30e41c1b588e8da2447d760809a776bb97e0fbc6f2d9a43b9f2d82f90086877139ad6dd0eb98ac88cc9d0c71fae03d19f9dac38d1f19c42612c2fd493d71e488057f5eebcbb8e8c639eb533aeb0bc2d129088694f1c8b44774183d5f595784dcef5dab5d5d29c894ab511cd46b1e07718466fcf078149cf29af272506a4fa9dee857144f25ab45cf3ba85aa72968497c090d26241fd1688501c24feedcf74d70c5b3f65638ce507bbeb875a217fb5069623de1af627a47b84326b1fc3cc69193493a0048309e324923d732fbb3ab7b4d8e1c0025b62242f132fd221a0702133df244326ca73a08ff0e5c75797f4d97e803df0d512b1c2df6321c1752d9329aa425a80e9914c55651e08e73b49c1789358034746c187388a744b3ca9278411f8201625f4215597d8a2de997f994f1ccab747f13d085679c6dbdea3f0d0e9eb0915aa193853e7b810bb8303fcf2acde643a007957384e636979821a865ee3277889aa8bd16a24a0e4f24f1a026968bdcdae5ea716f9407f71cc81a8db5f952e0d68e4d7fcfb98512b06fa8246eed227c814fbaaf033bac68e2d24d94f3e1694fabe76c7e5fb018a7425efa8657465345099a0e910f844a3e8f25ef753879414e3d3789b9fd56a741029dbeec80d0fa371cc0ff260a6261328e4a656b959ee9cb946ea54c4e822eeca0224ec0c12e4ae344de79f43ba8c0bb515793e8a96b7b424af9af558113cdb7a1d5b9fa38630aaf4d1980dc533c158b8e1180bd6980172abe67d396bc78bfede9817ab69227662f8e2ae275291061c25a77d029fa0b1d551845093a01a3d26baa58b74a786fb0c716487fd4795c0b1cab11ea1ba1f3313b8397d9c68fdb66d916c870f290333a901d48a50447bcad814b551da9cf4d77f4274434365899796bcf9bd1b2fa4cd1ce3ac95b389d7d10a67c6c05878748132f04cb0682dd5edb4326910f558f04aa9f54bb8235e7d37156124b8a080b08f4a759fc8e9b67ec1aba925917995277369dc9635d26baa7e769805e724ea9d2f21764fec740f46a95937e2bdecbaf51d90a2d55513d5d1537128ae0022bfafbbed9fdbe15f43b0c07a906529a90876e33949789cafd555388be0eb041dcd8337d1efab4058cb6b27f1fe58c08a44e1e09a82e0eaff09d15f922d26f36a9b7f2a711df597a856a4aaeac671141f785f4f95e60802b1798c9829ec4f30ae7443e76a677f34edd9ab1bd7c85d9fecfebd5b9d543898a865e0eba1d6919b94ecc5f6a997abd0837fdf6f978f326dd8c1886a70a4a2a0030b35f87a3017ebf3e8c8fa6ecf65963a2d942d5b3225433fee00b262b26de4830ae7020e4f86b000e2b676ee068cc7a93515e2221166363dfaa79a877d2d98f4a24b44da7ce1a12bb5e56ae4e1424c625a6516dbd4acc0b2c43ee3725ea58addc12b54c53170b748b1c84b2b1b35c725c0d8bf1d9c44576dc212fea9037c8cbe187d02b2d188724a919afac49e91986ac8533b8bdd3718ad8f70cc8d399e435091a0143432ff262172ff7098bb33f659f92cb4bcca4e9a2d9882878862a42bef9368f86c20c1c67b48ea47fa0a688bffed32bad0211754c358e0484e5a194e6a0aaa686678eb9bbbdfc9ac7b14d6945cd1d8773b3cad8ed6af8e51093f33bd53115e76daabbf837744c2c5b2f5f0bce206010bbef5f382107c69e7e188b517b736cad5aaa2e9cd4795009dfeb08dfc103ebacfd7b65a736928e7cb134dd81f89eb623d61dc809bb03497277a0c4ecb38dbc2a525adc4d7d5e156d976b6a801211b25db8420f6cfed6a794548c3101409a75b462d3779b3cdfaf849a30f469af7a60da9488ac0ca91fa9d7f6b8aff0f1b2951b4e003b591a5a1eac0099bd3c3b00eeb87dadf24383103f23ea3b430f2d781f18a77b6deadf9ac7270042f77e76e2de31bcc105375a925ff7584428ca0706ddf13606569800c51c061bcd6857cecf75b5d769ce41d7ba19ce26a8270fdfa0e41f7161dc24c6f286dc85f0a5fb5cfdb3b0f5bc327a6d62d07c525396d1b7a624ec231c8030092beadc0049f765ac63da1d444d3a41d7956a5a69462171920bcf223a925fb4e0d3e3cd307318c8bb1c7384e7abcaf442596fb7672a23a62fb87db8524976293c03a3c86a7628ff54de31591b848c33fd5445bc469d0744a6a6fef251878ab1bdbdb87ea895b974d2c290dc2ae1fe1ecc49349aa384450c7b022a493d22b65f161a0cf483987e9a896f4dff86bd88d56f55991c3bb0faf65b87fb5bdbb6f470c7c4784812d65882a5603d107af00ac610c5a373218b75f17ef965ffef11248eca0457d1266232bbae3ab0a8ce59d88da49e1d659bc52a32692b76483c8393ec5b0331825fa2b95991a6224808dd76e6055f065f712acb3d4376e3ffc647b0e7e3133b0ea71176efbedc5074d3f0b0913fb4459766d5491cb7d7ff1fbd965daa6faddce6f8a294f2432e5617c7792ccaeb20a79256d4476611b6c105b8ec90f528dfe4d033a935aa572da1c97eca277e7c0b5d6e12a0d93c44638fc34b5f3ab154ed14dd60ce2bf9ac6d72ebe64482952a8adfbd8fed65626b76c1eeee1c9b031eaaddf95c6b0dfbc126fbb3707bcaaf1672b42ac38d1041822e1ca9dd8be428d98d4428e98143352524889d1e9c5ea52d339f8c05e88035e8e2385810a1ed291226dc86e530e844f3995b7aafb68943cdda3734a412a97abebefe1ac48d658662cab0a61729be67b60e72881003afaafe8fdf5dd4d053dc2d0ffac7b4525fb0854c501000e838231dce54319c623b4e1301b97e0f2d576f1cbbf492dbe64564060d017ccb4bef868c64c5299d8b88c4303b123575cce23f4276cbc2f39a85d055372fd65bb35f92be2a163c9fc874830c485a6e5824f2e6c4f8b630268f816981b05deaa16d79c2389c71e28ab8a2282bbc37b17915b03d133d22a47074783fde3e7adfd08d0e848c3d3de83685a1b682313a7e42da6293df0fa7e970f85140eb18a2100510e5cb1174fc869c3206b0d7841ad484fae91fcee28a0e98bf6141ff9c9338f2a88e99562861a0b6e5b60fbf1482f57ffff1d6900a7f08909e580dcbdf28712330873fc0063245ebc4262ecfaba79aabff13c70bc2de9168cdfaebfb792485a584edcef47bc2e1a36aaf9689bc6ffe8677a11dac5168dd36e8de63f9c65934b0becbfb144fb9405b6945e6a9003690625630cd0e49fa943adaac278f88cb475c17efd172c916b2526a0e9d83ed760ffdc438ba01f764dfdb2210e7f3c0ef13a9aa4b28872da8343a4b6ab373594179d46c5c556b6d381cdcca5a5cc82e9bd5d6bbb38b8b078f206aed6f4a2100a72c22ff029f7236e87b17159795c4a94969c956b6d08c65ed86a65f75cedec0b0f64b3ad40a276f7b0b91742b9cd27e5a57eb7817b42d7b13f6350ec4afd41dc06f6a1dd3dfbc60b11524115c036466ae1e006148832482d7c078da34f8e42fdf5110062c121d1eb2419b033c48b8c6847f8f66375e9c2308948a794abd0532d30cc61ab0e3a82841933fdfbb60e62d94e63d6186ba4d33d14324c99ace1631f7f9bcb4f73e66f6394ca781405b7f63d92b7d8c6682f56819bdfc40e6d1c4bff247445c73c796d35c6bdf76a672fcff24ccafa703962b0f0ddaf2fff215b934c82e4f2a1c7cd7a7e1b0e0710ec2bb7f6d59a90c97ffce9317b04d2e74066b55c3457b4ded935b09e71fac4e6bf10a2767b11d73a616cce98d15e1fedaa70570eb0a67bebcfec6b67c3ce45a12e06120437f3ed34aefb3e68975915bf85f546b2e492d977ef5dba1e5b76e21a51f153af966e1729c4cdf40a0b02fdd292658b3a0785cdffe64684bf7bfa084287c7e84bdfe9ce33814ec2f5be1fcce8dd9ae7a81bdc34bc5147e38f125915a5c5d2309c50baa4ffe7baad5949862f9b3e54e4038425b948dc3e3e685f5e718cc72a7c24c7f93b6366591aa01176c9e5709986c8bcba64d4f65b39f86dc06045ad81ba5a0e4b3505268ace77e84626ea331e62fa992b972d5aa26563ab300f77ed4326815418e4d3b00b5bd0596bfa9806e05a01ea1103fe5d915bd8ddda0eff2902e930d56d69e76269f9769b9a6d80133780ea7fc9d600afa8a19bb9eb45dcdf89c30163529114af566c811e3708c905520f66f9b488ab7ed5a2f042a8643446b145656287dddc4b4e2348e64ee8509c198744449dfe7bba7e8abc01599310b81df1bff76ae55fe25a6a574a1e89000aecbf03f9e5ea3d69322ee3c8f9f2a0455e4f46330fe43ad2f0d57be672d876fe8220d724e2a7a5f16c86a3b6c3f38e1c4567838ce40b4ac24d509753e31ae6e2eb9b514fb1c902c72404161b5157a580e8d2ecae7cde1b6476ae46693861d0e57bece4b239b4092f8b54a9f44fbe04efecd834c6f5bd546ca8a4e9977e249f0c4db440d6f0a5bcefdc08c2bbc4958733feb546103b1f779b14658e86797b05255e098aa6e83524e56325c0f84420f16171419c9edbdf473869ae06b9b32ecf05a5b874209fa7c0f95b19b011c20867bc80a7799858915e4db0225aa863970da6f526c75294910cce04159a30ad2ca8a731e2fb58eeb9ca6165effb15bf6d4630ee5993249b6b35b508a4ff22d623cb76502ff31d47646fa1d68b850dbfe6ca3afdbb6fdad534d7687ea79e0731af428ddf81a33ac63a885c1a08ef5bb2c62666451e7fba46b2f27318224a9a8d52b72886e88331081001f6e4fe147915ac417f4070345a494199e544193fb713033aa2792599242dcf8318c00a044924253cb43e24b61c1cf63834890f8bde10078d94d1d61fb73cd65e75ff89a3d0015fffac34b150b1760f2957ff5695d59ab1634dfb113877c4ab7eba3a3033634c10226e288686097c1da7d650be1f3cda1c84b1cdc9c79a5492d52f64e3e53452720249107f7044ea6a9511c4d809dbf495d5e1c5ef0092957e42128d72556a0dbf844c5b3edd9009dd7a5497a0af445509a3a8d68daa0a47c01e802b48a9640023c2bcf8740e02666343f4ba687c59404f141eb43531156e983005d0d27978abbbb75b7c8519abe245c8cafe1e2906b892f3f17e564dd039779c99a37487d795495c6131765c85e369b7225b59c114532af32ad4d0880055d1d60fd9f8f09f57c7107c424a9425a29df42123287fee69dd54a8ef7ed25eea8f12d7eaa11c6ac58b135d5615af1dcaf0591090b1d5a9060aea8a520464b48d6c296e8806b070b6971325dc018b3ad769e167f3ca5f160087941dc0be761b269ce9ac12a51f406d3503b3594ac3d18b1e9432d9eee59350f9b41c7cf92baca2b2320262e8d6d990d9e8c1fbbc1f1ef73ca8dc32ab77f185fdd9264c8df34c9e6b2d0a446b83ef5b445bc0f9cbbd0a197b7c98cee2dea9ef1a6479a2ce52078fb452beb102b2a83e0aa90f8993fcf7ebcb6d7833c2f4b23333d1a9629b5c3354b4e2d2e912deca486802f5cd409543a86998c5f6eff947da508b7aa74ee5fda867519ab385061ad2624d1a0de549438bdce6ab24988e3cbabacd11499273d680d02709cf097c75050e71b98486a049ac2453519ee559aaa29a6f69d0a8f0d108f8d14f9dc2799e5b1eda4a53712417bbed873e30fd717574543ca5efadfe8bbeab3c5d1a4324aad8320a06262737001d9affd567939aea1896e14dc9e9f4a9587725ddde690b548114856201ed707169ce113bfff78f9486af9cbf9bf545d4463c07f9af7936fe123dd3b2f79a160febcdd87234cc65d63f92c87e5f49e98c42c83cdc7b7df63276a63e0ad5c53e0d8e014007c91ed607367364d825a39520854c95d3cdb7aa4d048de71550956d0cf0ad698e57a353ae0836ab5760f4eabca21ad7383385a735343685dd514b943713a2859c068a1b614c0da93489c8547e6c8ab66a864ffc1c7a1290b0134eb44d14f9c87449b025b00fcbc7af2b0a1f7e9f39e910c0d1777b0a755ac3b54efa699b29deefa92574928159d3838d084a8004c9fcdf5f8bec078d68bce924b365b4e45bde884e33beea74383f1398a8c062948a66f9365b3d7a1085330e09ddc443060c27c1dae2d61d96842da0b670532b0acb1cee20677d25230808618a0b924da905822656037eb74d84b4c4894d8071f25d8eb2f35937740308fc5273a1b40af8ee989eaf294364b2b46761a9464a424d1db9b6f41bbea927e3d1fc6fe9f322862b6f04244e492c277d10ad35e5d7b7768e613556e3d0ea8675778c929e97731bc89d2d46d66dda1611f2943ffe49d9299d7c3f14c9d26c49c260c854ed4e662813c4ef52fb41e4ca979bc080adc678d0834baaacf640016fe05cb18986c2bf0134080bf9994476ffbd1cdcf8867e6f3176e58f9fd071227146cc6abf5e2801fae89ce80486dc05141f4841b48fc1d7b001db303f2fb790efde316f2d436a4aefba65ee9226a48fa65d54c9b0bfe1e974b55eadf8c61fc7700e15b752f4a73dafe33f267d7556716957054341d23312703a703522293f285f6989c219e43938c1ea160c47fee380dd404bd88309e9811f62ff93659efce8c0997dbf2a86d055df2dc2e27ace3a624596ba784c614aeb14a1d8b3942aa64f86d922509bfdf15f82be831034ef86e67d5fc952322671d9ac2e7995cf9e73b31225ad403eb3ef8b96658a03d5156e7da85f9c42302f04377c0bc604a2247e3a37f5684f499da4804d9e5312de00d91d9c70a812502ddf7f03cda1b7fcdbcb1a20bc0206b18c3e8d1eda736a8c143e763bcd4662bf67cfeb2be1f998c974ab808c344b6eb49ddfdc391ec513feeb15bbf986f2c57513496061ee57e0eaf6270001a0db15b361d936f6fe9a372b8b2d6989edd6a78a549cbe4d933c84446e83f24abfac5cc4c5c394e5cbf15bde511127f5f3841c88a9ab13e11a63e2baefb80884664253d9f5b0558385d5be02860658280277e37904b6f7111decdee9da0262d53230802b1f2ee445cd2c2ef4311fa244d76aae2453224263221c529d212388c91ce8a9f9f180eaf0fe652245f1c06eb5a278ce9a6eac52e908757a54885a9ee256f224d2f942b10f1fb5083f7a7b916b376046e916987d12729926f8651d0490c818ee543afec0a027adbe2a18f1569737313df00c0920d74036109a5b241ef56645aa075d4c5088e9d67b24e868d8b741f458411fda9141ed7a6909a81597d0d18c1d253c8d21d2d2d9ec844d66b14cc19d5545a25ce1f84dcc299c87c90f36e7b7ff3a086160aacd9b426f5eb1f459a64284dd019722ae62fdf4b8bcab19a951b114af4f79aa757b100b610c54c257016f936a7396a267331c554bd989c6d79ae3bbe0ed40b283e848120b51c99f59c41ae6a1eba79c2c726dc4cfd1e740083b012384420e472833ac4a0f07603f06ccae9f083d0cce09b625776623c9d24babe82c1a74fe19e385bc220c742a3dc5935c788d7771b10f987ca2e19d8f921260814c034dfa7056a01f1c193a5d4b974a88ffc2d98899b15de7e3490a647e8df1716291f003e0eb4861a28dd9fe1d656cc69537d4b16151945b22978f19588064b246db992f480f975cbff029f041e332a580f1a4b29a6006d0c2563642ebc3ceda580da4bb79f7aa43587e1019c208552aa0bac4baeaeb3656047a470f3348081f12bea5b02a22694329488e345d1d4dc137740be43a3acd38857a296ab0c5fddedf9bf471058ed4ef477c0719a0524672111a725edb0e11b9bdaca9898d56b2f1640353bbe032ab32094941f74627d41d7cf25896c98a4b2a626ac62c94517e1157f57679481f8aabea41b963c65f55572a3fdff763bb4f4a78ddd1583c9fe98e5e84625fe5033d70da2fcf7b14f3727e953c52ad6a92bd48b8e5a8679d6254256cba30e1f0344dbc9b894fd65d73729170785bdd2f7f0a139b181e48ad28dec864e99454f5abe86a4d7b238ac814d1da9197d47f302f8a38318bc532c7a24189aee2c2f6b94e509f0d68ca1ca568f152baa7522f527e42f150413bc21f03ece9a7242d7f6af58a137ac3213403dcaec1fbeffe5876e1aee9165bb0f2be77189a52dbb418acd2a78c21c27dc14a3cfe7fb61092c804c17e82d6de6714aab5028f0b834465c0371ee78c8daf9cc64150a321da1330936818fa63ed5eee2be01c06c43ad6969cc8f06e55614508851d075a91e1d875b47da99cd82c26a2b80107548842af111c111805afd00d4257867d95fa64c8a3ee30a88601ca8264c1f173a30a1bcdff158724e65a976cc51b56b4f7ae8f62d6ad0a55bc0801960b2c6bf6772a1d5429d8509dbd7926a0bc82ed52d2b139cac5d09ecd96cfed02e2ef5daccce65e26dd722f71a336f20ac125342961646b68656e9d42729cd18495f67009be8bd4b22946ae8ac2f059dc307d29bf49874c00827f092f761e1b61fcfd78a3853247ba60257fc3ce2228edea1eebd4e6b93f4129454449cd2ad083af0d04097a90f79f69ef7d24b98806199aebba88af48e7cd57bdd26c3fa09e1608a15e4414307dc4af422ace2c0a4e5ec359b58c0f83cca8185a6b71b05fc0ef33400b5c372d60f32947bfb6a303cac8b8fee488214310ae5c05d8ab00c00e3a45ceb72884a891189a80f634b51ca392e020770801042679012801d5195c95fc817e81320ee548caa72b30757c5e07e4d1fd4ab7f34a425acb3a11c16c43a2dd19d83116c10e6b1b06ae46ddf7a2867dbdbb733097d5c12f97117cfb5b33ae42995ec8da4154b08c34554f2f8801df92258a78e3e90c9d23eb667a97db526a9bb5d6e40240cfb157576772008a8f189874ecddfc924fb697a44adb189eed870414ca519c2219b4dd41bc788bf8b79213c2e22c38956e8f51426560d3bedf1b34213e0980e603ed3d1875ca5178453ee1d6631ed480ef9e46d1eb2be46e5b3edc97c79c658bc41171007b6d3c0ea68e76b3b498d7359d8a3b97fe26786ec3e1b233bd0ed0859a7c3f438bfea85a8a3d43cfdea9887cc339fbc548fdcc5415525b4b125ee84c44ce5f296226f30af9f14bd61680863e5cb5d81f0f1c83869a05832dca6b47611a017657ddabb7dabc88dffabe63fb07119efbbbdcfc2108a2938f718230ddaa692972b68385dbb0755594191f1e1b0a10d09d65258b383da0bc9939f7e44d891c24ebb9eb6eab7cdc57342c997344687e4abbd4b3d84d75be207718f923631d06ca4e4286580f177df4139fdf02982d9ef53f8dd489a90f487727febff3eef4b896e3584768b5f43b24aa588107171f68a329a8830fdb006be6ad30ddaeadf6fdd5201f8725ff126d75e71af7cbadc28cd18eed669dd1fef9a8caf42cfa1ce8f3f26ad6470dfa2107af54d84936ac606738e8d18fd706c648d61ef37103d760ddf10aa5096cb55e1c2638bc3d146c894626d4286b57045cde57f89a8850bd84630cbf1fb25e9aac786a309ed757299bd7f2fda73972b52e18e26d9995faeb98eaa0ab9fc4f53751edfcc96b31e71aad90ad33b1ed2b1b01a397748ca88f0553a97469fd1909b9576aaa8add28ffc7dcb34078bba836ec1ffb20e061603756650b2f5bd092a526a4cb93733377259812b73c1666e5ee6bdca674423d658e4f66c76f29096b3ef74c2cbc7b3ab7286a269a4a8691dabb27a75ce1eac81f0489d06729a997788930361cf7286eeed80a22fb6faa2304a23d2345d46447b9692f2c68e12c4c1fcd99e0dc81ea5fbadce7a4822e2f1c228f2d6237ea68ea88fc75f322776352547c55315899d0e5170ff98c9518a0bc72571e6f80610e12784c979e2c0c6934e040b9641c5e00f631ba5772d5386665d96f104c380d2db9fc14a555ad808674489c4aec69f12ca93b7f75e8f7163ec3432cb710bcd5e20a42fe247c4fe9199776c2930961c39afc42d59dded9f2d2920f89e28dcb138715464276b0446a5725b73b0cacaf3faf25d4a66fc4233bb317bb9091652989cdcf4c40fa1213300c3df54280f7071823f239cac69e4052603981961e748071d431d55a3e5229cc29d64dd029b3437bb928dc26899f644ea163a1579e6ba6f6d6bd292c4caf01d80717f6501c179a20ccd9c3c924b1a5757fbe046de2b8e3047497b41f54d152899f36c1a828545adf00ea8199360ca30fc28544411b18c9483cf7c87ab944b8481e86c0b73255e1125b582608140d4bdafbdab8faa75cfcf3d617350c53c3fe7689b0c2f1fcadbb2f443559ae087f40999f6fd9ff7e884f2dbaa13b4920914629d88fcc30743df59b293adaed4f4b7eab49e70150465cd5c277dee2b6e5a252ab37251bde0ebe4f6c5d5570bbfba6de2c8fdecd116b8994b25b24fdcbb961a7bcdef920fa2e2f73235cdc1f92e9a7f53159f0755c29398e5e4dfde12ec779a3fb2fae1130430c99850e77e69c4d84ba49baa6bfeb456dfb3de4461ee1655d90ee772a22947903f7ed696cc2046781026ab122494022ccabb38176fab080064e808988d5b11e5bf4011a5165fdf92c12e94bdd25982eb62db37fcae005c369e3cf1aee8ce4f1e70c9c34a89cd984c746c3397ebaa5cb72b3b52fa3ed2d07135b1a04ba351e395273e7b1f048bcbc8b07c731af04050795aa6b8f4b30b7b18f94dd04f5b03f1b2577e648336a85c795521efd2f670767fe7c55111a633db43846bb40c716188651bab3d919cf7629e61832b088eac77510e984bc5692e953b36426b64f2fadeca1dcdc075de89e265bd540f3887ed07099e469152960f39d5e8d4f90cd432438d1eeb056f80ac6d26fe9c5246546bf3fff34a8184ed4d1d956dff15c81462e51a1ce14567f120673c01f9237e1f646a9331853bbbb61bf90d77d37bc5ed544feb13c39091ca1d99d52be5c8ce5510576320137948250046a48c08fd8830a9f64fdd89dbd590a77fa8d03efb3c6b41d35e3e6a1b0203c5cc5b0281d5348b27c77852108b947bf2cc4f2965bf944cf65316affec360674d0fb6028a788f2e9663ecf462efdb81410bb39d57a884c56d8b4ab6b34ee1f77baa588d0ad4abb587ae3c5d0a4632bf7fe0beb79b99089a0a76b4471681c5b8ef2d2f5492a1b7869aadf385739f939a9fdb499cce33a04e520fdbe0c99c3a7d5f8b1d09cbd5f7cdb26b6912c037767f55be2b7543fd969af7927ae1103fa542592ee3506ea0bc1a7a6e283b5aec7d42ddfd5ce62b70dc035255d6b2443158bf2f14487f49d0e07819028fcf852e391602729a11b3afa36b25cb80ddd50488680c62a8f8481a5a5316e4aff49382d923288f8c58590fef7a65ab4ea268f3a1e31b89eae4265c8eab57a2bd91fefb98bafb15cbaff8c2f6c790cb453953c8f136b78095d665df9661715ce287dec21babcf6f059c29eff786325246b9d410d6a380fba941c032a2c224126dfa2176e52a5c076ed8054566b30403329cd2ac3a2e08b961ae8eaf355fdff6ec7e0a336d64b63fedd55c859299dde6f72b9a35e83a00bd00abbf1d5adcb123318d68e5c22ba5c538e9742145dc7df79a5b2e093e8829af78c61dffea9ca4c36563d868ee7aa5c358b3a47da8446e73ff9f1cc1e240f11204185b53a7e80f0ee75ca0c55d22dd62f0ab5da09440c433e44eef6b02809518481108718dcc65c70c24c3f85ef9c496ac6babce7db0edfb1d3a0ad09f4e140829b93f991f39161d163942911acdeff570812725fc0086d0797a3786e7162f9e09ee7a093e87cb5efba667bb0da9cb5cbe89b44ad4d8b0f3f5af43bf051bbd0f15989e215f034968fd17a4702121b779bf82e8331fe5bcf128c2b2f521082dfb3b672097956e302b21cb996f38199828cafe20240c0a9acad9adeaa9fad8a331cf65f0aa12981bbc0889c1c8e60a8e6609c58b1df0490c410a28e3a95598e86e3d9d2c45114747248702f5cceacdfab66d3cd4979acdd89d9d3177ec54a82ba6ad7a06a9ba633f17a712119d8f7552c80d124f722f087cb1f8d3397011ac0e1c8ca95b014c029619a088ff660433e84716e3919821cfe7fe00514eec058b0f5c32b8fec9598e3dfca54905a226317850bca014d4c8bbb4ddf516c08b6f14b17e3b3198c83a7421c77f3f69513d6ee68795452f89c22e1f54d2192f3ec8e3845248160c057788f66e0743624965d4ca4d5f6c59bb76ec3cc4ec1cf0af04105e00d95e53b50d652c1ff207d1346f526385958f805a8761368d29ff912217e836f7b1a8741288c18fe2829bed20fb39cb226103a58aa9f741e9ee42c036fe4505ec6f163cac09a2df7465ce7c1a266c2860c3235e43ce7fa00e5c84cd3d1859bb1c131037e0f28cf0802b5dffc1dd33940eb7b996b9ccab738da875aa3a98ca9eec14dea3c9763278aa0885dc9e83729714e38f992555ad490dd062f895a21f9a3bf904147be8bf671ee54c6873f0e3e3446741eadcc1da069908d12e66f2f1e7c957c3540f1d87f5db6dae3e395c40b151447fbfa509c8f1b94646a2bc8c652273e7ed29dec33df3493052252b6bd7e4db95d07924853a6719c24614d1c9f6d58f7076865b6388d8e3bcedb86d33b4cc5eeb3c96c8d11a67555436cf700b202f8b115d294ec98e912de376436e82f6d939b661448dc3940f6b8090b10d6ebba889b935792d351ca80c37c1bbe8a1e454d1677637befcc8905ada70b29a6c80fd5b33d13073b30df53fc2abf90be118b768f85aa44399e9c42179c68410db49938e53d5b9b78c35b5608338bb5b4482c0d814393b1545e81e5cf9647128e21625a26d9dc5220e462e09a7d9adf9a1968b2b576bc7ca0ff50575919a5bccd5589ab996e6fbc6d808f5c1356b10f64750ae67ca4d03890c66522c33d71cc6462019dd2757ee1949a045af9cca65dd722f6920cb888fdfbdd85cc82077904d98a7ebd60868c4505f4d4c9b711b406ed7856476fc86bbe489c0ac26ac6e06a4a3a26a24d4cc2f93af7d414369219c8d246d0860d698bdb7d5d0073a89706662243140e476d37c86dbc8336a1b65c1efab9c18a272bef58fb850bfdc98c1722f2e136c39d0906da848aa4f456ac8e628e12bce6d8f38a41288390223819be8c53833b3a31bd0d23b4792011d6cead6e15ff7524dc30038a3e5c71feefff206a25754c0e62c4582e2631ad4d5e6294d7f56aa12f581cd3242a4237fa82940103c64701dc71012bbc1174e6c0603f7f36a920a060483de9204e72e529d0a06d659a9eb6a4c1bfc1b3314688579f9d05088a39a11abd3ad8b6b893454734b791c008e98c9858d1025b3845b2a60ec85da62a807a9a32884460ad518efb2af340b81e35e040a8266ee9c6ae75e3fca1f788e100c1484594df3d21649ba102688066582f00ac2e0fdd45a6bf85886e2e30f84fc971cdefb71c1965183458efc176c6502a02028547eac50e9615e278848c6034bc042b191c8bda1456690ad50472104e5b64f447891f3bdadbd6cfcb3c494f2f6a41db1f6121a4498a2ddd569d2f023a5f82e20a4231aa43eb88e06431461ae43c3a502d1110604e6a41a8eb0f85c0f8737a434697dc1110aa3898c7374daa73a2157808e047e121de1efea159257cf5c528514e4f7efe67e178d5592c2cbfd2198577d890dba1d34bcf4c21179a24de9e925c80eeddcb2e40d544383a3fba152ef49d5ea1a5862234913038bef678a7e88e7c45a213f7ac28117b487ccc7d7043d29fe553f17f2b953bfd5cd59bd125aeb99020345e9195bf1bae112e0e571c4f355cd5b917ca3340909002a54920238c2b88cb8d1ffe6705d4129e4b27711a3546847163c5a69813df49a09a5c56d6bc3b5898db891e931d2475c9488bbce764385f0800038dc81dd5993119645abf0188e81b09e10fef2e2da489692c090c5d967a631207d98982d4e54b85617766a854755c7ec26a8457f48214195ec2f23216fbccf2f5d7bf24e2cf101c7ec9f3e534ae57da5ee6e83f9e45f45096c58d7a8230d1acba9227cb5b48828d5e223fdafe12d3ad273058140266103dc1b1f0721e107dfa1be47eb45622b28743dbf1445f114a5cb7b6be308ce6d766cece27c9e3d1b1bde8f0817d851291a82a898b074af9be794ab5cfb4e159de3822cb28ad1d68be6a55d66fb9ccc5e10e9a30f652782d858c98b0fb0273f286cccf15175c2bc6c8661ac9f638204b94f11ba1b8521937bba22008555cfed2b29733f827570a69324913d63668a96e7fee044b7fdb28711ba266a27af030f58b971070024fa463906bfa4155166c02438ce629228f33af06688bfe7accc1577505ae9c0f55fa800fa932735ba36bc30423fe2725eb301c066b9899a0e0efad3fb6eec42b3007dcbfb75fbedba6eb5f1c74dbd89c0cd6d3f4ae4c2d14156e3a3c588e5c8db0d2e7d2ed47cc6d826b80e2b177534a52096567c13916023bcbcf84b76d1555062845910dfa47114839a3114fdc4ceabacf1cc2acfa0475918d35a4f061f4ed6c6b03eb5b257aa4c6bcb633a8f5b1b0d9b8674db3b6c55feae19d42ad7a45fdbfcb342f9d7ba12fd37369f86d6447ff06d2d06e3c029f83f29f20c300b8ef69c95d0cfdba994d6354eeb6106c66c99c0193c560f5b44127ee018f12e2c69458427b3073f68dba556702c31796c644d91ddd6c0a5e0d64ee82a663d259a55e60f16d5b6ea7e9c6232a762e901f61421cc5370b4a60061bc060dc1516acf28b3386e6aeaf09628ddcc947dce0b625edaeae86bad41d48e52ab536c04b8dd168928b38a412d9679d4730e79c24441f1d06367bf7039f191f23aed2d3c1e894f0ecaf948f80be8f366d4708562b9ff1102061f7796decf20858c24a395372a51e7358393ba86e56b0ae53235f5a204a5f43078e64fcac49cff04310a1b8e1668e310b40fa57e92a46f3e6bf99c66636ad66310bea5d37e4c466422cb7a0af11c602b8a55459f5b2d5a5c6dfab5a0b36616a5fde7a80f29556e0bb127271ca9f02c77a16839a7be6ca24eb7eb326c17e6c592f98506c74bf20178ab830f02fcc018ce1ec1c96e76d7028419213fff024d3fcd6994458b8f1f59b7c6960719a0b988b599c498dd12e48cefedcd2e54a3f31b79d2d44f076a061d4564c2e9248a3800329837006aeb41584b8dfd2db524a6cda4292a4734868960d2841f322f4681f1fa793476a2ba51c52220da1b154eff9116f8dc831f985440a8fad5703dd85c0ffd71c61f3603838a101148738a6396419edfab1a73a3673d0ec449d16eec5fe84b93c3062b6d5e03027c2a20e517396198aaee311c72911c019c9a5baf3cfb1dab124f47933885e9fe26a9b9ba1312a89a106ae8ed32f2dec18204cd891bed1ddda2bd786cbfab1ec46ed14f42cc98cc5d1149fddb33bc64c0f5fcbf04742f2a733dcb6439b998d5719f2ff3327a4438af5ff5bf5c19855357345f6b2e58c256bd6959a65ffcd4ff638b8602d5bc7da3ca7b1edfedaa1f409afba3cae9f2852a832dce89cb964ab8396a1776a064328b1cc5a1632e67ba620867b57df951f795b0c131c80866c499b5d68dfcdaa1dadaf5bfd6d579b9f8d81e0de1366559a407218ca54f9f673e216893b50e1ad9bc4567063ea16e3011d623d378ea1712d13f24597eb42266821d28309b1237dda73b44adb83b017e507e4f4d5a276360507c816f4fa226a20f085a7181728a9bc4e0238759e467f8e718a3fcaca690ae9f1220fa3422e9531db21a7ff8278716c43599fb7a5c709fc8dbd3a5c61b14023a7917d33ca6be210db55f96a41cf8fd090452480f4e93ad6d8489fd5b0a4edb22e460423a25b26a15ffb424376c2c4dd5fff05167c3d201e7c8e681f4536fcd3c86527e30b30f591e900149be93104e3e081d18a0c9946d8378e7186b632f3cd9f29f04657fed0ae5bb9cb6fc32752dc3829354cd08270826619ca5d8ed26f751c68a5baadacc96316a60d635c837164b3a7d9430fb59d8005a08f226fb4852793393e3766926421a755bd8878025e4ca129f261b00dc27c53c63620ee2c9c01f0ef4af15895a2432a54e38b3a2218143ffeea571111f6ba523624613099d4daa97ceeb662f9a22e207458e7523480d427b5503c54f2ec3b337d4034985d0dab8a73a8a0acd40632fa886d972e4a3452f878c0af6a0c86c8ec9dd4034388bb09007e8d7bab7763de8e070024ea4af688c49e3108fb0a4ced5c357a38a2eba805136c7302b0b4a6aebbeabacb5fd7b097ef3c2f32d8e68d3e536a43a3d3ba5140970fc7205d8d04d75f75c740d53f582b1df9ad85fed4a9453427c62cde5ac0638b9f7b41dcfd867beac9b2d365d8f069f125c4a0323b54d78dd76b93063366963771dc3408c37b853e17c002cdea1dfd663af0372847e4c4bdb26fc38a39c08d6ffdab94e5f1bea08805618772f12d33b33915401dde011ce265427a1643ec85164c5dcc50dc0781f6946112ea976260039dc24eba36e6202afc59231ed289dbee3797fb21d056a1eb1f95ce6920adcb8cd624b5ccb477d0f3ddb1cc4c931b314041489aaf09a7ad3e989df04be1caea35030d107a9ac15a3f93c98ca809f72d2d48b9d89328f35e1c474dd6a012cdeac0041f4494ce92ac071648a31358024a12c47609b4a98da4fe6d4f486abd911aa19f44462880407d238280d0ac6a83a88181de81fce6bddb47b8259a623383f2a31feb9940a32af918fd27882ece8365a0507bc1e8ee1fc37ddcf57339280e8117c90389d87de8af270f6e8d9e9188ec275b1f31c487dcb4060e903568f134edab38393937002412f48bb43a171f2e29c0cba600d7d1c9c7525feea02a81bfd300271284b17202d32531234af81e33a84ba88f402a0aa7a7829e044c7ff7b66b783fbaf921d4e5e6625e050dfecda90a5ce34db2c293ee634a37c648f6c459e8299977a8553024e369aeb49b731e91951194a5f6acf42e0bfd3a94777383ac9991b1e707099e421765da5d458d1baaa687898f5f0d51dc25fb5105708f6ddc722e0b4cd1e0a382a033412b4f87cde0918069c44da9abd45125cf0568eea829349632a8a399bd015855a061c6d07fe0a075cdc8f8093d800884eb28b24656ae2d201bcdfe3c2486d6b61f21f7086191545c0e900c71605043ebf1d8fd34a511534718fb78153e708a4c666fc2ebb5704943085e33acd9185ece49acd92198cdafab5a5b5ce37176a94be2b4d2698ed42667319040d82ac319fa107d5cc0044b1ea174d126a989fc650319a1a1a2c08061fbd99a11e6ba51ce3c353a9a622a8c9efd27dad9ba0384d28b9fed20ca42021d19cea20067d40933f3c33d43240c9a12f500459202805340e49479b13eeb42b26cec4a2d9006dc161c50d35930875712604a019de0788847d8e18dfaac7cfdcceb840b741c9c685e7d59c1dce37bac52a5c0c5c5d04b893be4c82114ce8c6e3294af3552a22ce3f3ec09ab522196702e912fa7600f7a8d21c9ddc45adca35badbde6afaf7060832681c47ea65ae3726480b2c5fc83b2a8c6f89d9235d33a5c824c73dc4e0fd8b6deabd811e210dc94d00e17c1097b7a09ce4cec98defe04d0aa4f49462591abe00d689464087d821ec873b2c94b5de15053c8a3ed9cb67342c6459abc820f7f39eb4fa02d36644313e351e9cd3a10da334ebfc32c7d642da9c3df02d719dde4761e2168cd1a326563684168cc0c412c010bd98d8c8f54720e028f188a64815a37b059377ac2a73c83e949ce44755c2a8f6d09b7d683ac4b233e83ece902e1fb2f8f03fb3bdd6c48ee00ea5d5fbc7382fa1b91d7240579664ab21577c51ad17f216a0f41e26b8f2ffd634eeb2a5ed09147707119f755d2831af94ac5dffaa414f09fbd77c5c28a16db3459f9d52065cf28e80a1fd01a82aeba4a34109275c08020ae2c2533304bb5b322bf6ee5873c196549be48330c2631d14aab7ffd9d2a44062062fa563e31fad4ad199c9c55373be0787b9f8935c05dd86674498fa9992ac2b792efc50ae7c1a9c00e574c98f52a194fa876c5f6df731ead7f9a07dd62d3787d967a8cd36a05d72c7f83a817d68d57e687a083d165107ab808331657b379f5d0ee561cb1ba34fde0b0d0c1544d34f348321793facc4393d174188ad2c1edf09a7a5d459fc5e85552e1072499f85adc77eb8578105a4363643b3210baf22cc9442b644ce8c0fd620b202d5f7d70182d879fada7af696651248b68d9378f5a49309663fca799878ce196532b8f4099eb2c972979157ad1eb7098bcf51a4ee4208460528c0af10314ebf74f32d63f0e992d2456b566595e7e1c96ac231385f77cc18b68501a7e2872794a0d3e7ab8369a1d4c0433e0f0c505bf257e7e55ab39dbf7d003fce376a95fc734505e3e14045a07fe2b5d08fb00c6f137a0827ac81008e142598b303a3514b6f1e145905c875770d7a349d9f6bd9e4a586764c257506436ee984d964b503983c549164de5dbc5eff02e6314ffa5a5f08b1b953f30a744104a3e302fed9e4e4c9f89712fc0fd57ff5c46e1295c136d5b3ea7a83e9d6061d2abcb5f10d433610ef546819898aa4910c5231d7db9111149bbe3ee3f4c7efe40e25273160a920ac788c020aa5b5905c08093c8ff7ab8fbb1db60c601d47b3ffabbd5cd0d4abeed40ca8ec1cc737e0bd6690925c58c7705d026f7e1517db8dab1f3f615179fb359fa86a1c2102dc7334505a13552be0d9ed83b13d5d3f7e116c93f43ccd0ffa8402ceda3827a48ce205c6955eb0666268c89127bd1dacc7fd4ade0deee19f66b912a42cbd50056286a9fd644eb9d46ef0c6a6ba0172c3562fc3c0b765a25a411ed420022a92f2c7ccb876e7b01821a0122c75d8c03108853362db244e823880584028338eb2f731e8cbefda137225218f1039cc29a2b9d179bc8246bddf915440ba9e710481ca303749ce79c6c706f1a57a68d54d7cd7e6254846cbdb26452f87f5a7b365063babea17cd9bd4331ee0e30670a3824710c4360c879096c8e82430990552432830510aa850b4e96e2f8bd8c342c71e9bc26bd049a63c9aa4e82d57855e9779ab5e1d7bce57fd4ef3a45465bb3fc7efbf74084860b42a589c80cef0d827d02f54bb619aaab05357cc2e5daa75dc98513483830c4279a04e48138934727003d18342f749924a604b56c318f8b961b1423294ea0b06a6da44bdb79e22b1011da7c28a00a4704231b6ad61b60298dfa19ccd415add9feaa00bf9298bfcc74edb5fbf3f66d02d4512514ab2b787db4c907f8419babc4bdd6b13aa7e544bb222b30d65509a904fc9f908edf72ae0483df76e3c1516300937a313da4a97f08a7efa2c1632914354f801037a00978777b9d306ec63e6f637a21bd11a88d7e332eaeb8386c72a834658391a5187d66dd8fce66ebabab50e289e75290cd8d8ed523bfd0f34a853f584069731494735795c80fbd618dd7dd9b12ee293161b46eeaa47b2b723d3199165f35319fc2414be1872666c103ca92d2230db15839af085b3e3f40964e801918d1a772170286b4543c5530aa33bc3c49fbc85a65dfae0e21c065902104f418be6bf727d1b22d90b0a6543e07906e9103d0ddc1ac60655458c1b4287d190f48405b0c873e2cb58a7ff804f5b078eb49ddf7d0b75bddd9d1a9410a832fff491e855dbaf98ef5e4543acf1ee898c35da829cab504541aa4e8109400bd90cecb7cd1ef730628dbb7c0a6a364f12761ae7ba45c38ae2c85931d2b6d257873efc3876616e84f01544a93bc462e42938d4d6b4200feeab0ec6837a0164a2e73826f9829170f3e440074f63f7c10b98e17937848c30417297809c75a16d30694f4bc08cf5de6a02de9d1ef90474a5ff1b760d9fa202154749d4b610014931f3d831bae4d418818ac09e2c189faea36f24c2b7502aea3742ededce83a393a042540595622c95edf0f54dca0d3cda4bf030e33ac03a093581f65e14b367f5eaeef2a93f5314c15ea923a8eaa67783633d5154f62628dceb54065c3ba471bae8631cafb843de611d1019cd27851b5e7a28a692e010ed9683255a3891eb01214636c9960f613ac630d6b31d1c0e2d06f97b51804c4174accd96277ec25a464a69552fbc80229eed0bcfbe1381b2346dd91d84eec61a3c3478074c0388b504aa39b263f4c0093ec8cb5eb250a3ac5753600b0c233a30d5890eca3449b48fb29b73de771b3357e3cde68b0c33c82f685bb74da9d952fad333042ed3cf0792a04980ca1986a8442d2bde2f695a0731a0f7e7109fd0542b93733e081412a27d19a4733e4e5e45d1432e69c4a3155cc1b1f9cef8121f84fe947c13992cdea6ed9e81ac1304cb10212b834c938bb4ec4c04b0ac170db0316107fa2fa20ad5674e4a571a7091b7d278459a1c2e84aeab7760e028e7e0baca157c5c01548cce9d4a6eb50b529cbb244645e91c0f5126395760fe2e48ef35ea70760f449d47bb79655e7c0ad2b9b0e280421eb7b4e6fa1608aaf3e44b7c6f1e42c109010092b4b884692f305db3871040826d045694989ebcdd67c0b1bbb942788bb867f463ada918b0f519d7b663188b40283cdca386816879272b035dcfa1efcad31c1fcc3fed19d7a28684a78eb2cbd81de6cbf12bd7093ff372f98708486f11d6efcad5e59eb28960ca31a0a6ecd828e905509516d2adea3c3539a7269132f95d2967b7cef5f38954ceeffa9b1e35d3019c76ee0417c14a00b57734f82db7e45bb0e3440241dc2d9ec8ffb599d7861fec31f4d21c14f1dca47fd35b32afed8fbfc791bb6949ccf21f7b40866d8b64f01f797a96bf42b6dc87298c497d1c5aa472f0947a771cf074ba0056e25c7387e9c308cb810b110965aab212bc777b4a71316c2123b6b036b815dc781ca4aea1e2d096dffe253c3f8f7e6c2c146a3e6e790c58e2c0309e2427482483d5f9a5e046c0e2561a41631b21de88c82ab5256d462a5633220a9382d51193bfa72e2e760a1086b16c69d521b1634d0fb28fd380f0b716957b10238a0b0d2dab9c9e3344b32bbb1600039ad7df9d9dc54692a9659a471115b8743d7d434b25e65d5134b2b9741387d255cdf6a4d58be5de937048b61739f15c14a113a9fad66b8a992ea520a26c818ce0d4b919b283b8994c39d31531113fad0d0480869047b27f35c156c0cf942e78c29e54730e278fda211069d97db1d0c17243415ebaf04f98711bf9f3d60473886b2f909a8c7df41fd4440dbfb62b37e19f88deb27a0f73e77c22b67075be918499e96daf490141729881f7495e5526b0ea9f84d00f3ba8e4b87ef128622d0002c553ad27ad5ca6082093e346bad2728e65b96b54ba40f00f96d352a2a55ad770f7a980a428be2b8de590160666e3c338c8cfb2e01bb77292df82827b2b133b79ac7d45dcb27615b99c96caef59312c2992447a9dcc0c25861122d5e21183301269b64ef19bb8e120b1937270094306cb43a0d00870b772ac8922b4ac6b8198d5dc58a1a3c0d7a1962e7d2d75eb3ec782b71b6318cdf90c47d7c09e6287f706c4d7eb19312c4c39234b4ba993d791a7c305117298e321d4cddcdcba35a998155eafd5cb901d1e317c0abed5bcdea277ee38b980ad22e887595fa075dee3ca5eb616a93e1f0ebf8622b412e593149b637004baa4b4bf7fb12084492065b93186cfd1449f9b15a0d1f594bf3306987a00a766d672768e146684c9b28df0af65427b6ec7073b3b30dcbeb311b0e3f151f2f71d8f88c79c6493267500999e21c5cbda1ab340812c6b9b1cdf9468145d9099b8c9da395755e571f0c1407974997cf7c26b6d1a066cb6c9528acbfa164023e88e5c0e92a5c0dff4740ab7b683b97879308d179480c6cf00ff7669247511ca44d102df3b2341e12aa0db5943ad4e97fbba3dc7d2938db020c9e7fe63e2609f02cd5850eab93dc6a809d424c765e51c2c7b695eaab1ea66971a9164643921469081dd6202f771a079aab5f815a084f680e9e75283fede9bba36360bb20b2b346ba546274a0f93557277907de54e9ed28197c0e8e8c5847cbef38b94c91f814143b4be338d2651d32fbdcc63828f3ad8619edcc310969859ed15dd78be8a134f8067160e29b8d34129f412de98fc31c12e59cd522395ad611bad4d7c5c6a0519372211d70921f0a012c40f28090334177b0e7dabc101593e0510ce406a395260f1ff1054db35792a7613919aa9d62349e263a9e3a2a7dc2c5de61e08cbae0fa23c889f62815dad29b3405e5dad8ed90d3fa1103f89796c2f50e0d36a659885ffaf2c0a980b0c7e7a628f69e0accb0acebb90bec8fac5aac796d8ebb41ce630d5d4db4122eafe9fc02a44da5cc155aa652d23f313bc94fe61cb2b3dc0ecfb8015f04af112a56d95225ec0c7a986aebe2cf5f43ecf82b31bc663e705eb301ed2d1381e704aae355ee2bf786c005c5a47e3e384f52001e1db7df57a69e8c9d8332b4d217708c58b27013843d91b8de07764019de30abde43c983e3369d21ace46d629879fb8f71cc2584889ae99cd47abdf543b819a8511d50cf8aa9849971ed1d417a305c54df400dcecabe842d956b85a42bc126327331088ebd32ab75bce881a5f1f615cdbabe008385fb654967135bf9c7c95c502eb789d7ef0ee67bd633836097fd73bf0705b973155b97a3476a9102bc82226a8fc2ac451dd8548934653f229904d0f226bac70882b2dd01f57c5c2e477f326494a2d26a82653abfe5c1ff71c7dabb3a970f4089000fc76be38cb2eee372389b0d67b7c408bff2e83b929f274f5e893ddc941a31b5eadd70d10e3b141fce1eca30f9cb300fee8f59cac74e5fb9653d0e99af8af31934f1e6d98abaf69e9570ae84eae397f2046af98b172e6a9e84f77c67c01fde6d153c8a1a6adf54c4a39ea1b76cfac1f2e2670c659746c80e5c65205478b3f570d5d7df59248f4a3bf68b0afa8d873cb3558ab2a1081868bd194a1d9577f512c3b669b83f08e5e7dbda9f942ba0784632736906426a99ddc4c1a367f1751452bbf92ae97277369a6606b650ac181baf2de018d40638177f886bea2dd6c228bea6edc8a2cb8b5dcd263f175f57cf3dd3f041ae1f9aba7b9f89fdeb275c0f5a3cf913b1760fc805217dd679a64f58ae4c351ce6388b70169a111696ca0870ec91735c15486e698b07c61ddf4095059cf7984a233f44a982380c7885843f522ef9d439bdf2dd00163114033c9d3afd12b8d6cda811620bc7f4709c6cc0676de01e7f39406bdaaea0bf711c4545d30029500434fd7c945ed27f716308c94faa65b4a480c31d0dfffeda25078df1947952682ebb8e2e27a0d2c426055019b686eae274fb73ebec3f7ea06dd4c08f58ab087a41ef1547dc3687dd7b0197d1ca0cc4f2dc75d4190482202eaaf987c202467aaa8ae0f4bfff3e9ca6e4b6f8a45321b2807eed9ed4fcb2dfee0372ac8a3c2aac818b46e6c23662a129722fe3c7d47ea87a97cf8eb4a0790d03356e3b0acfd39b07de7076396d447b3fd9781433058045ef4b4dbdf549c1daf8be8684c45bcd10554561e95229e3de19d1cc71233e4e7d80885d51bc5a64b53cc8a0443acfa57221011c765c6367dc2e5d4cd468ed09dea621b93b4b399e22ba352ccea8b1b59a8472f3717d42b6d79156bd547729de6566fa4f1feb7e2a1e12d2191be044b280c5ae5939bf2431cb61671488845fb5f177ac02b6b9b588e6c8e0c01e7500ebceb0e243ebcc2c5228bc489c1fefe25dac54d6339275236616d0807394026d70c4ea0e31ac49605378e37ebb686bacc47ee981935e9a63700738d607f8280a2c39896462f974f2a877101b5d5061f0c748dd8fd06cbd092924a54f2ca7215ab7108105bdb578f3adc1fdae7474bb1c3a02cea0fcd1018d7c8179915db0fcd5a6c30ee5048f6e6eae305587e8a6eec459abf1eda678724384420d9f73a9ea934ebdfcdd62dd3b905d2581f782c7eaa5ee2ee4482e576893482683d8fa72600770766bd88f914758196b1e112c928a6cf23eeb97c85f6abedaaf80e79aa66a38a69e9cae3b8aebed64b58131856e40058b0ca016f507dc5e00bef5b13fe06e9919648af1b2c32d9d0e50d065deabb70d59f8cc90b3fdf41a9a27c978133717808b42894b703d03836debbe8199d0dc8d10a3bf202aaa42ad9d4db31e6fb9300f876be782bb73004d3bb029a360f76c6bbed36c8d87b04ccf9e5d4b3cc3bca2002165e8f40b40e9e5aa6a70d999fee6bfc7215b7d2391c3d91423d1a0492e4c5ac7f099e6a2719e85e81fc96c647550be6483ac34cc37c7f4d05dba5fd5b580917b31959f63a44ed6c48d0e1fd3826688f7f6282fb5ef1f2381f435b6e8247971b03890c37c41a5f2b127a90207f318d3692d313550f5d68943c0800825d2c639ec910c79b9bc20d1cb3c08f25622f6ee849204e1b6fa20c0203498eb82e0386df6c7cbba521891f67f4098ed12822d38aad367fb6f18aed1de6d8617be8fd23dbd0531bac00cf2a479ddf0d7cbe05d3ae292565df4124af2f2edbe268e0eefe0fe610b1f34cefd226012b86de856ef9d7f5ef70157061b28d92cd87cce0a6b284eeb0866df0a75cae2ce7cf8f9a9a5bfaa5cf563711b518d22aa7a2aea2c0b42989fef821394ee8fa07536aa94fe4f992d5b94ad797b1d6f3e4840e0cb602280131f42a4914748d504782e19ef5600e3ac23f39f5c4ffa750a6a38e39bbd7091c7d9ca7f06e2f38d057b58c74759acc572eedbea6c556a766851760d1baa12ee68f64ffdb0151b26b42232e4d5bf18c076f3b5261bafd71936ddbd18ad070be1e2782a6d2f2401fe39a9d42f3a38dea7436afc7697452bc2da826ebbbea71d28ad6027b8cfbf738296b81652bdb9928276751683a993e439c02e8a604a6d562449ab7ce5bbc572cd20a1d4ae3736c757e0499ba692909b25e60199686887e02f9f2581cb13ff23f8cce879c6f9f9b7e5bc8aaeb88dfa780aec24041f92ce75fab6078b9a3069b18fd9977abcfbcabab31574dc9cd62c03bdfe34ca78c9f1db30dc8b6b1b178fe69e9e4b0ffb67b58fb731f76a9b01d53b1e6338a3ec6ebe2c3fc87e45e77ed98d0431c978c293c1bbeee678eb69801c35687435ab22a1c9906477ea93957a4040e0dffe274b2cb0a7d59bb456a1e30909d8ef51457600e9d6660069a9a742ca77a9d851d613aca32da919cdd780241e095473227329a94d795d832ee2cc7fafc3a8dd8f03533330b451ce899cd46e0b81330c23e68794670e48f14c69c1f1288dfee6ba769625ddef77d4668608148244aad8e7208fac617af10e208dc9ff715b54481f9fce5b85ba53008741a50907de90eca94de6dca8c39d36fae2cf0df6bda64be2d01950594c75a45279551bfc5ffce3ff40804a4c8e9740a95213b2fb9397f83f1af2dc54d3a05733b084cde97bcf5826d59068f06451c36a318cdfc0ca28887054df7ed1d05b9a1f65793a0512e6a8fa359ada93e40be996b6f0785e75171f725ce417cb876536119698475fdc520e89b2f8eb59e04cc07588e6b4e0abcdab6dbca04954bdc7fe13ac6d33c3f8d2e2d8d3ac8d076cb185d42b6195285641af3ef6a4d83e8674aec106de7cacb070600e86172895406b3ebcabd0a40e2dc81ac0f21a94a08ba300e83cd93f0157aa0566660df53913564602f6fb1125a5f7cdea7a9fd6bb05615533f41d7ccb0e3eb54152761c755d565e432eb9bbb071851b04e170b2792f0a6cac247705b2a3fe30aa86c8f1e5bafb8be5d0cdfd27f211b549642ea610a42f97f0418d5eecabe6c8154e68f49735e04726342bbf2a0f8037d6c3cf99c77aadb35572598bb8590395d2cf6bc1b8b7479e17d2e90529198f7c4fe3c17b67d3fa4463bed24f4f7802a5ae0b259eabf81abe585f59a8f4ee5a5a05f30f89de7e9620888d45df03b5e2e37b3a06608a82a995f628f086cea058aefc7d7d5a77e9e0b5bd71e0bcac8fd0f920d7824c256e40fa207180e631f9cec123efa0c8d90bebf18427df7c529345807ef7b6f090fc002d30308ec8eaeca0684fb15e266a98f0079e7b690283504170f3d40f8b04f1d7a094b7c0e62f040a407a83b4677261969af3eda796a2bed57e53a586731669d67948d795858e0fa627d737d28e80170f2cf182028e0cb494086f4d4282276e8dbda95d7d00b02808b3cc01b8b95b906bba1986a1ec3dbe2f879e305eab5be0bc3f44b2e0d3a68ac930ceed773132082e8a05c233546d43141d10fbaadd590f620de4079058e4ecd8b863e2845ea561c3f2ea0e8cb00f381431c9a495d0ef8ee4b44a8f6312c7566b21678f30837919f2069388f863e549309c51622d0b7640f3f48873c91dcd34ed29596db836cd3760218b0b6c601e0246a43ff07f24f7a486a717c86dbf3300bf0440a0a2e1afa022d211771ec8a42df4c2c4a57e7fbee09e44a34022f2bfcfdcd7cc08d65e87e4d6a15828c4ec1dd27ba9f47f2ff6bae5286fe1fab5be92aad653ee49a2da3d8d45779fbf8c5466aa07c3ba1713eb642a894c9fe45d70690444be76ea574014803f6e1d9a50e36b41f954534a20c8126e639781c4dd823edb3208acb7241cff3babd4df0654a3ee474cf9a519515174a63a13f5f198f41970bd53f311ba849b26f5d685abc50883b5a307b9c07637c6c336c3fd90468cdb3fd006e32d18990006334a564e42f0ea63e865ca6d43cf6757d6d3c32771105a66b52c52e0d59c8c932fff8fa1b1f8ff58870c9836393eead25d5ca5d1c5aa952d0c779cdb6709ae7948783d41ebeb177d508d4e3424a588e85e98c65b5df7e4ac2457f21d5d68a375e7a1a17dd49352019dcfb40267e43735b84ca0f49ad007ecf88eea536daf53ae2393ceb094f6c9e75d184d443a4d0a6e878b950b5b2d6d28c88568461c4bbbcbe2d3b3277f4bc16bc9c190ccae856a850fc387eb90d9c4c457d8a6d33ea7a920196da7c0ad9abb0c7eedf6b9890ca51bc2e251e2a81a5cf5040e8caa6886e013c59842f479f92830e9741a07839416f44687242e6a03d0e0991270b2e6c399f8a7fb81f1d72c020b59772a4e5034d8a526616a0286783ae6a4deebdd19ae2c16f469005e3db60bc5217652c037c07eff42a6895173ed75f1db7ae10eb95af07daeaf9db568d29946933acdc7498130ee38f5f9c4a4df8f1adcb57b9c91f32e94ff91f0b152e24ba2ca4a55d03475a252e6d0477a9dbff83a08b2036e69322d08f6d04e636bb0cb8e753b03f9402193d274e06634e21c1c2bda61d770b7f455bcc031fe4097493edce3b55f96126c0073d64fcefde5d14c1f53a66d77b7b036babb6580c60a3ee85b516417786e6adceb99b0ff606bc687892e0a316b59ea2ddc5d3b31350c150c510f7f71f6d9cd4dac1203b7eb8a3044dd39f57464658ad90688244416a015ed02d2fe0ccde7ef3135ea10690f037de759d78f87e10f0f6203b9f813aaf486224b4329fd48d4f1bb65da0c2db2b3a0db669da838985875441825c46e706a923f1c451a4df3d457838ec21f7568f26670a947ad0df2a7cbde37be95a50efe820edb73fd4fd6f9180585e6f2924be604745fd9ad31c16fe735972316eb762e25ed9fef102b5eaeb388b28a9369d4e759ae1f728573945317852beec846e5373b71124b3dee597ef6ef773c0c6e40ae26a0f7419f74b2aa5f9332aa073a245ce2fa7f8cd463f5cb462741b7a279f71b2c58751fb84c114f5d3a185574e1bd8cc406930fa10aadf2cc96d4e41a2ac4fdd5537deefcbff302137f71f076f28d6b7e725f57deae0b08e38ac7908f889c89e0b58febf6a706877e4c02decc187c345d10927dce9d47400965f2bbc0cca80039c97ad70706f2ae1b4c221c76b7076b86200953390eb372d96ba3f489253f30b4e5be1178841a08d09dbc1ab4628ac815f39c2ff640154aee3a8816a70c08fe46779e52e9cf2b5e1e3b510035906327fec2abab4108f4f507f81311e90d44ad19b26c4b45cc72d347cedeb96f02a797eb3e8719cefb9b3193f3d2045c65f76979ab384b0ad31b9085124232996b6666df90bbbe65f28e16604499e366f6ed34b9c609d906f56337e03c00498e1cd11fc5d37c27f61fd013300a64016e192a4483f0e3e1834601ff346d6a21064197d721a89529d6a8b529ec6e96c4c7adb616f5e9c73a802fd91c6d7cc980db0147df8823b8fd2d846e8cd42760dd91c237bbb57d415e37801ad460497dc888b3dd6f37c467c9ee4921e1b4e3587c4859d7a8e4426d02085852049da8d4214d8c48b2371b32588b62cec87b74764ce36a4070808065b22fa1298853aa2343a8ecb22200fb423eac5dd1de0b7b8537b9fc1ca2c98039d519fd480aa7bee339a79d918e5475e7063770abed90174f5460034a5ec00a61679c051538b1cc04a87a97efb33cb17b731c22f31391e4b4884e166a19c3608b656dcb0032de58e055c8e038aef2e9b551050c96c3a96d5024ba305361c757a9aa576bf9a5d55a0c7234f9c11732742d6afe2c5ead19e3bebc079b04f7f5ecaf1325ebb660c79ca54185e6699748c1d61e2ded6bd1807f0f8d3402da46dd96dcb2da59449cab609b1096a09f7bf211705f0f7bf282e06e0ef7f445fd167f44df98e3e2a1fd297f42d7d563ea6efcad7f461f99cbea70fea8bfaa45cbcf9fbdf948b0df8fbab9b8b0cf8fbab9e95cfea6705e4a2ebefaf9cb86881bfbf0a72b186bfbf7a227776fcfdd511f20791bfbf4a428a43febe074569187b52faf6f2d96306daf73d264ad34354761f37ed1ea4b862f2d894d338260fc84511fc7dcf898b39fc7d2f88d26693bfef09b978e3ef7b505c94c0dff7865c8cc0dff7a2b80881bfef11b9f880bfef15b9e880bfef1951daece1ef7b4894367ffebee723775afebe0acac5d9df5745b95881bfaf9272d1c7df97525ced40c6ee8fdecfe8f5f8fce81d31f9d15bdaf7554694d60109511a6ba9c8c509fc7d15918b393f738a353dd36b49237540477b685f174ad34854e5e3e208febeeac74512fc7d15908b25f8fb2a272eeaf0f755412e9ae0efab9eb888e4fb99ea169b7decf5fa55d3859eff923be374013d0714fc4b9c27f810bc4dc6044846408221be5d1e0438bc10df3330201f781b8cc6050fbcfc3cf081b96f785b8d9a9a0d3536413a60f34238f02000360086458e843604a0011b4606408019562b02ac620a30fe108980979fed004fc3cbcf9680e77116eb69781e875940067e88dcf2b335e0e53764ee1b30f043e4be791e97c0057e88dc379ec75f6ee0f143e47e791eb7c0d7f05d575bd9d3adbf0149abe33ad5bb6a78d77b3cc0b93f87a938dc79de6310b6e3cb2dece18e5a55ebfb7ea2009c7b9e009cbbcb2f50ca785eceb0cf5b651a56aea1734d2bdbb4e477f15c197cc9218c17936dbc3c196f26dfc0f20b4d76d5c82d60f56c720ee0dc22f8890270a200943b871c9ec7e70940dbebc50f016893d1796f48879f9fcd048f0368e4880eded1e69e33e2a4154e0724489ec73192979f0dc9f3b83782979f8d04cfe31e0fff01d00603f29ee799e6fdb3b9f01e00e5be01b4d5e0791b405bcd7b352f3f5bed3b00da6c823c0740dbbffc6c42de03df3f1b007e03a0dc47405b58e43dce081bef9f4d00af01506e2f03e0dca0149d01d006f31e28457b9e17516c1eef9fad018f0150ee0b80b61b1078f9d91e70e3e56793c0f3b8d723af9c564e2ba795d3ca69e5e4a990270f60b774db01ec987c64ed83c2a3f04840d5138fdd3701a80af2d87d1d4095138fdd2f01a82201a8faf1d8fd11dcc73ed807fbe4c03e39de5b21cf26609703d86111416b49ecefb77a627f9f054569d265b297bd90fc812c7c0744692b272abb8fb1d6afd77f2cb672dab703daf7b113a5b580a8ec3ec65abf5ed869dfd74394769ba8cc87d23822d612a5691f2abb3f3484b126e27c346b074bb646a234ec43574c2eb67a64ecfe7d8e89d258502ebb3f9bc562ffaf97d63efb3ed2be2ca87d99f67daff35e5e7e360a3c8fdba6f4783fb0c68a37fd733dd12d7291027fff1ab9a8ffbed7651ea0ede53fb0c6cafc5e5e7523df3c8fab3e1b137309ccdfef925c5cc0dfef965c54c0dfefacb848c3dfef985c4cc0dfefaeb8c8fafb5d938b08f8fb1d16170ff0f73b27170df0f7bd5586791e6f19b918f3f75b535c2cc0df6f1db9a8c2df6f517191007fbf85e4e20c7fbf95e4e2928b46fe7ecb8a8b03f8fb2d26177bfcfdd5678bf911b4c5bca773152f9460622a69b16163622679cf9561e4073e8fbbbc578ea912b5e74cee9866b24b1935b05ce3791cf6d968deb3c93553ecf979c87f20086de42a446c1e4ccc9ebfc92100e7060138370ee0dc1f00e7f60038f70de0dc36807377009c9b03e0dc1b00e73e02cead0170ee119c3b03e0dc1800e7be408d95d7f3f88d0743fec01a2b5580b6e4f11fd902e0f735e0f86cae2538825451f2e2032b0064568129db86a166cfe35e0b9902e0f75af6d95e3e19c8847066bc3c8f7b4226f0de37c477ce04928061086bcb2a5ee8206748bec19325007e1f01b05b8200d8597900d8313900ecaedc002282039edc00f07b0680dd12ce67bb49014e0cab2dab7841e526865a9e4bc0596b0161acf5eb95a3052484909c250f800c03435e00f8bd026848000b010730004c08850caa2119720c2877905c00f07b15080076563c767f06b063f2d8fd15d85df1d87d2360d7e4b1fb03003b2c1ebbdf03ec9c3c16f3814e2872b75482728a29329580b3769b28bd4db7c9634ac4a082125b1600f87d0056f86c36b2ac20802360b12180217926f96122412614d14942241701bf9761e7b385a10a766668f189210300fc3e06209f0d04d10042802a5edc78dc23802743de0176369038f789805d1733e7fe10b04b22caf1f7f5a3ce41b4af0f397ed43be4610005a832e53b0050040e3877015ef86e981be78b6421e0f7b6fdd95e8ade07501afa00e420e0f730c0f0d96c866040804b193602c835f0fb6dfb6c35610b6c09e8986a069079c0ef5f18f2d96a80670ca1a18506355c00bf6f2186cf46f3440c0ac082e679dc33923f30ac420738b70264f86e985b07013210f0fb1f01f86cb02b02c08027600cc8333b333b5234c06e5945298c99066417d059f8ff86f876095900bba4290754a93224c4bd03e4d903cedaec01ec96a8ecfef4e998f6fdd5d721396101337c42e66662f63c02b20ef83dad009f4da609058000de5209092990791ef7129045f0fb15c0037cb657180e411fc08b00b7a5d2135d6c1eb6d7f3b81781dc0256ef037dbc8d6f48dd2d61c72471eefb00433434f75202f903c122e8ba6515a527360f706e1af20786525c0ae0dc12f83e077c37cc9dc2f3a859b5a89038f783bc58a222db07b6a67cb69691c4b95f61a0bba51f5b46fb7eed13e2bb43ea923c765f8632340ea4ed0969dda12843fbca2c42c2edbda702bfc7dde77ca7c28e6fedf8722ba7c777dfe3bbcf51a1879793a36a3dcd3f37cd5eeb5bad18320f91fbef7beeb37d53e8ced67b9cf71e007207aa54954a4abd906b8172cf40df39a0efb90494b5a90494b5990494b51da0eb00e54e01947bf680b296031cbba57d5f067aa0eeb143daf75bc0ba63e0d88db1efa3008e2aa17d1f0738e61ba0b4b141b96d40b96b368d9401e57e8172c7c8ed02fa6e01eb56fd7c6f35f74beeac56df7ba0efeff5a77a3c612aceebc01be8d6a1b61ed6d2ac950793217fd7792a0a8b41f5ddab58accff957482eb63e9bc47971eb51ec751377dd8fac1f573faadefb09c2346ba5e26617933fb086065a56b1c1d41e5b64ecfb4ed8aa1d6cd567709c3ee967ebbac761f7d3f3bc7014c156e11ab65a7640e233065ab86edb2b875da63ce6aa9f5a55402ce8d1656ab37c5cc45c6c7fd6cd45a9a4029fedcfea71716e67fd6c7f9729568fab7cb6c370d83ecc5e5cb90cfbb2672fae1877512ed6b769a22b11dadeea4b79cca73ce6e4a0ca47f5a3025239e9a2dc3f196236178e22d8dd93c7bc83f22eaa4aed917553f9b06e1ef3b7f9d1fefefeb4fd47d65307d545f9ab7ae4cebc7553aedb963676c8133b99d9520b1ed09035b8cdccc74bb0600734384d13a1b41795cdc734d8340c1a3cd9f483504a298f1158f0c5bed9eeab9b124b53579a5e6e3c49b30d0b74e571c2db4a53bd7d1f3ab3ef3afc1ff3c153c4be8e6d75b6a5b26d8739edb46d10b67d97e5388e9b2176d97cefe5e2f5fc93e1ce948e00c5e96789133cc8319a24e10a1bf4d0845b949de9d8ff9875800f4998a2081f84f0f444cdbe0ea5ed5094460c9838110106d053cdfedb8fd9bf5d542077a74d2e3acd863e45b2e2e213147a346523c1b447ca844414bda17a92a47eccdf74f37872bb01ba949c4f5c1ce79eb98c7e8c3ea141f489c7e84b894ddf75841e1d8a22515aec47ea3452a8570e304665f565b11085d70b4738a90f05a2415448ee40b928958e98c1a6ef512eba6cfa2e55f36eb56766859e47f3873ffd7abbf1f45d8ad2703cfddae3345a942493a81693e6499832fa2a554bcbcc4c18e6c8d1638fdec3e557efa043cd1cfa9268769590048b10a88b1e397d9b11f48833f6541cde378c9c361be7d19c4be364724da83d7f164d27defa713ed136de00e14b2cf2c96594111759ffa3ce9e4b54467fc2c2f1f794794d282ac3381e8577281b8e1a261c5fe1f8ae708cdd84e3ac65b61d88d2a370d43624d4a6a16a027d0f72e1a8b3147b1a0bf1db84a3ae913d4d38ea87853934968592c642ea501488d6af2f138ef8158ebad6982b1c6750504f76fd9610a80534a3ecfa1a68d34701c4c1a2475636d12a1c75ea542cea77c572e5e875ed0d704a51599db77a77083d060947001d11c5964a470879bbe5e6b5a516b7299ed0151a624926ad6e449c60c3ec5146ed39b567cf7e4df11902e20845188114c60c6412a64801840d7e88c005185c1c65df01776df5a103a4ba199d67b169d898ac70228b0fb6b002466d48962a5b9021861742b4a036c6a8608254122122966042ed861a2855895282032a4fb5231c5831c4136324c10849a841a53175c40fa24863a9f60120a486b87284221c15e1090bb8a9272f78d2c49329b63fce2e199cd0b12d9556d084ddb2a5d20a9cf2d195558260688d750d2b60ba32b4031e4660b17e9d73a72f958c40634b2523a2603414a2da76ebd4c088db0e6e3a0042aa9242114fc63882ca314a2983a0a79c4f29a5ee94de3c7953ab355ac394569d09fc1f132f5bf39aacd99a675739b3962377aaf0b4a4c9a331ccf87142194974104502c8b8728330b62003062dd8214a101850482146151f3009a2022ed260120422329e5ef0b4a48960e8e728085010e189131f0855a1451386a8384142cbf9364db4bd05196da9a482a39c2d955400b46958a5a63c26e5b13ae5b117e8d13ed9f3898b6395da522efacf5b6d22d1a53dbf4e99522eebb9edf9e3fcd9d3faecf9f36dd09e8f014a73a8514acd399b9cf6fc4aa472a240945e711aae5d218ef6e8958873aa8d6e74b4e743d59b0fd09eb5b106d1ea4241140ba552adc89d28d4c994fb12b5a293a61441a14f36fdd9f369cf9eb5a65a9d728979e68d566bf3f584a2b49e1feb64cfdaac8d13692ef9d39e51af2915d3b142d8081e52d296f77187bf8272db1a8e47903c2697ea947af4aa532a15c9e4b17985a808ca500daa4f6a9050fda940b75d7ba2a43e6acb29a7a72b4d4b56a820194d89422404c549900ffd99a2b72d9d695f9953d239e79c734e9fb388c7a4848ac2e2b1a41dba999b3c7933b69af6e59e036b6aa0e77fefcd979c93b552751cc65363ddd25887e334da77621e6f3503f9e3362173ee6d62d50249bb445476697789ca2e10da0ca2c6a60612da74222f911544443f9bd2b8a8d793c672051be9a3edf321f97c4b514ee388a8ccbba25d3b726b4569b307166dfad44069b3c7853693bc50da54f2a2cd253294367d80d1660a9ed2e60f34b4091452da14c2c59bc7ded4be3df9c7c9c6b239a6270e4a8aca2e1320985cb4017363a62587184ed5714a90fa1962de4017449d3fea8c7840ef06de27b7073a7e1e5ff5c0f2790f6c428fab1d35f4b8247951f25a22e3032c05ff030dd07b18043d24d3498c07f2fc07d6de05f0fbbb4469ad1e97dd6ff52ced8b9d5c76dfb1d36dfa0e8823d2482d2020228e48eb4b4469aca59691cbee4beb4b8471cbc8e85d784e09525c81b15ae2a4286db562920aa2a709fc4ae6104100f1dea41604410ca3ca417e88b74de9b1d5b3ef7b40de0302d6d8de07e43dcf2008048892d58864cf1b1090668356b47a5a3e4e9b43849e07dbf20bf23c1e2408d8254da1e365704654dd66b358ec9f22512c2291c392c76e80d26330605396e1be0ee90727a074d9f7daf24302824890805d52d8e4e68b69014511eda7a1b1436a09dd209cf093d3f4108e72ed113bd1ec113bad608686866c4804fed8a232b69290fcd8b2b25fb6fc62c22ec9633e487c6e7c906a136c80dd122b83aee9e4799c0545699d152c37174b6a06af4d2761170a09e1a23306c12e099cd22ddb93ad29e98a89290402bc3685083b24c74180130850fa0a637765df079700d46a6df9d1b43206696888f801942e0bdf6bd15b7eff2fc5c2a3a6f9f165530326b16a841a290c3ba77d9f261c5f1f861ede5a562d412970f9b6fc602e19833058143eb8f2969f8c2b6350468689252fde96dfeb2563f0f50a59a00446b5e5f782c19797a824dd969f8bcbcbcfd625391183b7fc6c207162a8983da07499f7e2b6fc6a781ef75e198335bcfc6c35805dd20c5c3bc06ea9257375d82115e97185b4efaf9c562e80b5199e706a86860630d9ed5d8ef20439b2d78801e492ce79474bbb25520449e7568b09d8d32df90a93c9cf1fb0c7e76b9349d85971d97d255f93be82be36275c0c1c71daf175e66396235081269df38e96d61ad401a2a373aba57d584d789939e82095e9f62e47eff5b0bd36e0c06ab5b266b158604c478cd5d29ad503e871190f4173d3e7c7a7f53c6e33f6ed5d8e6a979efa3d6cefbccd9e5ba77fee4eb7585abae8e2ca8657e00ba4f19ec552adc070edb1435a2db9d88d2163f476569af67dee1352778784c6cb0c7a1234e403c1a72a3e7bdefcddee3d9c6d057282bb9f1b772abcea285e7da702612b55cd2dcde256abd5ea7138ce8dc1d5ff0a636aa5b59dafbe30945a25c91db92f0fecc7cdd97537d0d69c9ab552dda0c386c57003c5364d6cc6d8660e7479a88d6484df6506f207272573562d9034ee480a8b7d710cf695b2efcc195756ecfb39c8c599bf9f9fb8b8f3f7b3908b9387bf9fa1b8386f7f3f0fb9b8c3dfcf515c7cfdfd4ce4a2f8f773918b2bfcfd6ce4a2ccdfcf535cd4f9fbf9c845dadfcf545c84fdfd8ce42290bf9f935cfcf1f7f3928b347f3f5b71d185bf9f995c6ce1efe72b2ed6f8fbb9c9459ebf9fb1b8f8c2dfcf4e2ed6fcfdfce462edef672817f7dfcf512edafcfd2ce56290bf9fa75c84e1ef7f3717ffef7f3d2e0af9fb9f8f8bb6bffffdb808fefd0fc84500fcfdcf898b31fcfd2fc8c5f0ef7f4f5c2cf2f73f211765f8fb1f14176d7c2e473a3a4e5088b5c4629f8dc264adcb01e1b1d93b53653a478e1c9fedc2526059fac2147a02e1b1d5d047cfb729ac74e8c0f9666470766499d70e584e95e3ecf5924b44c2d7ebf5fa982f67a69a753c78e01e3d54e054d0f158f5b182a581c16a76d1dcf800a2835e4bafa51c6c4684d1eae8da3459d2749e43b23332341d1d180b955eabe3b1ca026c47623dd3d189499a8e8ece4b4a2340693ab7a9e9f53a3a3a3a556707065be9e8c81db971acbcb6375f524a2d657687b7576db76578b96fcbd0e50a61bf3b1a956f19bae34029a595522f772f9dbf6c64bbbbeb504a299dbf75d0a794d2957565ccca3ab770f096eea5b30b7ee9b93d57f7d2f9c56badd937be1edaedc1dc188bb93a615420b3250c0dabb5d66f88e953eae10833d2da73536b2f87f3387e9e4bd5b9545ead95a3dd23eced96129452ca7993524ae160adb5d65a6badb5d65a9bbf154bb77cdf8aa55b2ee0f8b21dbcd2ca925297118923ffc55a6b75acb533f0ea90d65a6badbde18cc6d172b564171c2fd8ea966d7191e088836faada1df70213f392814970b4d9f4bd989795b133296cfa1e8d7f42ecf650d2982cc1974c96af992c758e1add2b4b4afdde9b55bbe3b6bcdb93c972c6fda56b74ba2538e2d8f4ed9ec9121c67605982230e9a2c6b64996da84f59c36e0f696ca868cd923293d299d3acbe3c66e759152d77952f7656d775a194524a29a5b405cbeaa2b4a394ce5aab9d55f9a97a973812473ecbcbab5ceb87a384ceab5a3d965469d949294a8929a59456cee5ba2c8e127accd3ee5c61329e94d21e659491cbf0179d3299d2191d607096b377c5b261d39f55d239a9a5957379714d7971b9844fd01bf64607ce8bca23602ec771dcc531e3e1aa5c9d73ce8b46c5616f543b73b3f5881b7b2be762af4b0fd7cedcb823f4fcb0b63eede5dafa346b75675c91fc5ece39b7b464cff33c2fcc2d9f43f9b5beac9360adbe9cc4bd4958eed2ba82c812692b4b73ebe56c12f72661b95b6758f07654f50790ae053aa510246a5c78e1d6d47881c7de1e536ad0f0eccad1582514c655ca51cac1aa4d22566766682eb8754e4fca9557ede570a7f2f2b762e98fd572bdc0c4bc646034356a6c1e0c6ddcdcc081424c9623a7905b52e6029bd23a29b33fb3e55bdddd1474c8cc28cdf5302f615e401caef0f5ba71a303e785936336a6ae1e30d80163ad9793337ba1dcc531e3e1b2d5561e99c767b33db2943b2e5bfe7d8a518882828ba3da7ac3eba1428b4bcba4916fe01b15f2abf0d9381ff96fa6eb65e55ce18c32b384a8e8b3d550260d1bf680819e1fcef4cf3e5bfe196b05edf2f27dde98b0e58340fe984333c7f5cbd70107b9c36ac0fc913f83fc317f967468308011b9a3faa759927764e6cc6a9129715a5a7e7a3f5d4229715a5a5a9e97f550f642d6eacb9e3fa83af2b4fd7f56646643ed0a224ba4ad44f1b3712f7e437c77af9375806663ce9e395036501d72a7bbb31966924d4e46386ce4693e217677a10db389740435d361215316bc9dacda3f807440b2943b2d588bbd165ce074148f0909a2c685176e4d8d1778eced4154838667e75ae49a4265fb7b96316b6960bb96a5dca1469a6846f158120aabd9ead760f0170a8202aa36701c378b2691c7dcc86d983f661332c71f49e8098903b3306429778264297766d1f61965469951a2481c213dfda99d09e232d3e23c94b0c9424f4ae98c4e26aad65a1f5181d4aa82088f46b9d02b74092bff21f2e80f3055ba6208152da2467b3ed64712494add8826940bf910130d9a011176ebab8b39f4b33e9b665981bf7e33e899a2e74da1c1f6a0b44af5dd675385b13b2b9660acb997552871750b548cb16dd54754f86cac5b7315038cb5c6dcec2209c8f6ef689620c23044317242e3c4135eb6ffd5690208dbfd2da689420650f8d8fe15d348713385141dc8a0c9f6a71a8618c0f698a5d0428c2982b6bf6b1ea4b67f75c73a464564c860cdc9408a8f0f8eca90da2155c64f9317c50f19423d107a28867af023c52222e2c1151e1ce9e0f1042dff9ea1bd2d959ec0e20342abb6547a428a5594feb6547a62e8892227a630e69c48a287ca749d70c284fa58277e48e243d419766289cf9ce9cc7ce81011446512373135841195495ca412631585be5b262da107f908bdda3269094b3d4b4852b2042adf19da6e99b4042c8aa850b0065f1ad34f33be7ed0cc1cffb1a3d9b86eeadb5a6c2f38bd9a413a9d46fb7ce9aa273cef5d8ad63aadf5d67abddee937acf4de7bad0d96d605d41dff0dc798adff95ca9ffffffff4258effbfdc914746dcb9c3f626e8dadef44ce96fe9be8537adc3f8dd964af73c86db1f1ceda641f0bcea4ea9f4af1247095ddd6d0f2ce65ed762989039a78c71dc572eac1eaba1a49662ee5a5c3bcc5d9b44ad13a7c09392da6ab35f6ddd99fac6c799edd75689c371f567d561d79fd55e6a69fdfb0df14ddfdbb3933f5e5d78e3aff9a386ccf1779ad046e2f8db4d431c213de5ceb4d8bbd6e2c91dd1c4130fa2f020c88e9dcbec39b7e7be030cad6f5acf2c3d6e5abeb7a552134c7bc47bfef0db0ec33f21948697a31c27df8654bed4d7691758ebce0a22ee1344b805b6d6041387674c822ad638eb9a134d7736c32ce85942634493094d1c6b9c75105254263126c28f104f42446925259a98482897c9204048b94cee11eba59f58bf949a18c25f13139db74c3a838c55134db365d2195b1c41bb6c99740651009a108a1246d214124a4f5ee0f4687ad2f42397f9b4f92a5f35a6d65a5d6aad3cb5ce2811e86aadb5da4a6b95485c9dd551eff95f5f36f1509a0bf92a8c00a539b6e138a321bdfd3ca2b4f03d0cb15b2ef49a707e8d70c4e1c3c27974f32f1b1a8733e06c12a2ef94524a299d4ddb29a52028a98cfeb3fce694524a29f5a3ed94da50498f6af80c9037ce3dbde9928b3d77d81dc0c1a4f3a414e5d3ea319f387cd0932ac193373a483aab0e7b5bb7527ab54fa5769d1f01bc66431c3de8f9fef6e65d7ab3555cb42298d252ebb4c5073d65c56286e7101434eaa358c04c3a4ea1cc75c171a38ecdc18087cd55d91c07032f361783156c2e0640d85c9428b819cde6a876b1c5421ec528bdc0086e5e2673e2232e37416383368a6953b19937a501638f375fec51878f4d81ecd8a34c5a82874dbfd2c74be460d3d7af2590b0e9bf0bb4d8f4634c0cb1e9cf9808c2a6af33c5a6cfa33474834d1f7f364abd8ad2944cb9cf56318f1c2841594263fb5f4d69608331387b13c6f6af5836d50009d5ae392d70c1f6f70990014515550c0144d0151048010f41101185123f42b2065586be3979f0e067f0d8fe73498826a4ac600296a6daa8374502c807473ea820ca8b9a0102f3f3cfd44685481983d177da42c6e4f6298ffd6c87f22897f2d8f4a71d4be8f7a7bd03144a5f7cf15303268a40a3369f064acb41054500c1881f624085506d3ecf7c22373e7a468fb888387595eadd65644948a453e16b2b3de2dafe94de544aa83c51c15289f67c977edd7a381538d6a91af154612f9cb7e933ce1b15222a438f998c9c6cf9d9c6d9f630ca1e6b1017501c0a8f2eb454da026a8f35686f0154a1384dd6a8ecb106edb1faece9e25881b61317eb1853f69c3e6ea408ed011cf4a64c3843e6cc1f31174d3e5c303938ba6ac6dc67bb97e3b8b9b94f013ad0dc638f71e1102963dc7b75c5bdeab937c202ad0a471ffdbbbfd9bcf79e46f9745ef8baf9c18607fafb9b269a6a2bdadfca762621ce0187da1af0bfefd16c02a08d599b465dd1e3bc45edf994d29c9bdf0cb4b60add88da0ef4a076752038784c42d120ca0e9a3e3717a5120da0ec59836e98aa2158888e8d855c6f06afb9119d9f10c7cf4377d83edaf0884349d9e0b1313fe9e1054411afbf499c59857c50a1c71db64f1d1e93bf032d2b51abe7d2f76f06afaddeab36373d97e48e95c9e44694b6fa197a931f5147a2be44a5d4b9b2890063cb9f5fc81fd3094c865a3d26e5e6716f923bdcfbf4a212511efc31d6faf5c24ee60f87e204640d5199bfe741dee450e60fbf3273fca16c7fefceeb2b26f4eb50072435566883a86c88d2ac1095f9236dcf3eb489b6dba13a651bd5a24a7465fea850c81c2912c79f0baf6cff19153d7fac446e4469b436bf225e93df90ba6f904fd83494977a0f1de89b1d236991f483273ff009b3b89267164f37a4c165d586d2653f767d29c52d72903b39bbda5d7ff6b8e8e3a2d3ea433182470a9d830e375a6f610e1eab520790b2fa45780161d7af3cd8f50d2071ea0a4be8514a8d184a0ef4ff5f2fad6b4503bf27a76b4aff6cf9b3711eb3d3eea87a9032fcf26e9f23ec314f1f978d7f4ea0e9f3831ef1c6dd8c891ef3c6f8e767534d500770f6780cfbb8424ffcd389d27c09b9134469b286e5c6ef3e0e45ee8c136ae329e5fde8b76df3f4a12b3c993296322fa4181361ec337d240efe5a12eff077e1f4f1187e1f57e879abce1101cb6cfc13ca908b4f84669011fae5f668b611a59598545c7424fc5348eebc36feb9f459bca880e20518e39f6005679aa067d013b9e3ff92423781710e474c292987392c03f419a93fbfdff8f1cf208983dfa7191207ebe0317cf3187e0f73f018c63f1384c6f831c6b8da303c79335a772f42ca2c1417b3c76c52ceb6d55e712bdb66d84d4f222ab36fe5b6b3164d716b9f470a0d1a27d1131747ec422e8e597a900d153d4ea2d183fc2791f320774e30451fc28cd9b7520cb96486c4b10fe431eb4eac7dafcae9c4fc41a79839f6edebd984dcf1b7f3890d9238560a8963bfc863d688086f6b812e0f3c79e3e510bc36536b4b3d8ba490b24a81e8ccbeef56a06813a575ff1ac241d8a5f4edbe3bcd229b2cb4bf235971713a3d796cca91e44ecebe755fea84feec3bd29e7d1f068486ddf438a19efc8ad3ec5f282abbef427247de1ffd49f5a347bd545c38beb49654c6230589470a0d95e4e29d13cab3903b5a4c289f33509adbe32cb2c942fba540c851e2c3073d4ea7a78944314642ca8e81569ee4b1eb484cf435d253bf9b8e741fe357cb86cd60bff6f8e8d4b087b1afe7605fff62df4740fd2eec7124c9e3be125cc3a1db406280d27c0c29bb524b90b0cdd8f7cbd8f7a733499cfb3b9c6084dc993bfef72730456ac48cddbf628c7a7b606eed4812e77a488b9038330a47097a4a79ecbe8713ca63f76782d06386dacebae1e0284b1845584d2963a5040db3a5d2d10d721a7a664ba523285445474a7c5347435471e4c36a896639c15302543642cb6ca984450e3218fa654b252cb4e0b880e20ee9d6964a5808a9868005101a58245901a1331a788ad6666024b4de52e98a31543d601021458c7b851213aed042ca15533c2a74b7a5d215523a20e8bca5d2154cd8205c21f404930b63d74ca7488c1e5a3530825c8a927cd0b5a4a39619ce82096ba633f3a1534404c48a08bae808213e565113a05cb382b42a5aa2c493fab2a8864094a528c187ae76031fcf0c1c64084caa2b4d38a64e8a184a823c0d250942849b94241f6050024a8a163ed49680a448d1a4a62425050a1073a633f3a1e385b52f96a404fdd4bc40fa1a517e48238d3dceb8267477860a892bdd09b46bcba4349084b4cc9649693c81add0315b26a511c415210d1f82d0390daf079a7504cc447f3ef0aad0ad2f3e1968c14281d65b266589a20859607099e8962d93b2047543d0ac2d93b2f4f061a15b5b264d49dd194415b1608a08b3261a53f17c302584ee095db74c9afa81159adb3269eaca9e3f34b5a4c262aa8b0ea479e12aa7ce15496c3f52ea5102d7c5acdbbe665ab68a5a4fb5473da3a96c22214d95cc3725ce4dcc53d1e88be330772bb52c17b5b672b5769752db597b39edc2d95aebabaa8ad67d5b2d2dad5bb58be36cb69cd52e6a2da5acd50ae68bc953366d22944684ca6454331d0cd37035b63a4df52ab0ba6c02993ae6dfdcd032055f2f1bb3d9ffeb157b2963723a7b877ec63315c812828e1b9ba9c6d20b916fdb7c44e2f813a1b40d4899bf10b62769ca7246cd0a9eb2c4999b03eb8cf78a8159694b3f6aa9c77259ce45298b5217aee06aea995d34fb39fbdc7babcfc6b55c9fad7eeb2bb2c3a67473f59decd7fc918f8311cca49b9ca072661290d88d3ce348963366922cf48814940d5247ce90596692d9048718887c310625925484480c44be30c3485d61d29b58ece6c60dce0a2de8a893ca5ae594ae9591242a1ac8967f7373a389b8ccffa64e7a445af9628c33cac86286913a29915952911991187088acf0450b636ce7a28cf975d29bd8cd8d9b9b9b1b981ce3a960dcd5dcbf7c363af315d96173e1ccacfb5a9a5b23ffe8e8b999a2c97552adbf9733b6fffc51661967925cbd9a2c5db4f1cff229269f9efc88cbbc4e7ac48686ce36b8383720a57c92ad3dca27f90423f38a99a13d49260c93d92ce01b8fc907f78dedd93943d8ef80bbcfa5f266fe56798212cbf658bad59227189348db73e509c6b6f702932778b3bd983c414945d5618ebb348b23fbbad650bf709d99526636869e4f69ec45650ca5b32a7ad65a6b85b12f97da7771d505b7742aedb1b25c7db5d2faad6aa595669644a2b5d25a2bad9efeb719f1aeaa96ec5a2476919cabde174a25b5303a728da994bea4cb502ae99c73cef029a5b45a5b258c05144ca730180c0683c16030180c066bc15a602e30180c0683c1666030180c06d31f9be9202df17094a3ae535383e6411998fc9ba3ae255d47ca5ce7890655600d7d61a18d1898fc1b17bbaa75bc1bd88d977a674e50630a4c73e3060c0755b9ead59179829e0f84c7764f406153e8f933385008a0d7a8d48bd96a8a142a53030000000000004316000028100e89844291208ed24c90e90114800f688e4a66603697c8c2244862144419638821c400038021c410858c689b00d27915e1e496079b8a7ce8c4a806e8402caf7e16653874989f60eb0f65e72cb911589a2dbf74431e97d7b8b6f2a3b10d8ecca1c0f96d7cc37163289ac7ae5eadf2168968274ee519d8281f5461b558a6d55fca34c29e3c7987023a0a8fd0d7b1d8dc593e2e25b3bcf4c9e397672463d923b93515d94f9745b567799e5b3a147d100505018eb6a51472ed858e31c56a0ef5de3fd04a3b4eb7922261782613e4a29b8003517613c3115786a45dc1d85bcab576e7d4c4d52f9041d875ce204db02860c18d82440ada3f1d6994ae4d78c751e0e90c6ff834001f104216770c182c135d76a879cc50fd32a11a0b1b688f9c3af23141e97c02d618cd1d75978e311e73235c472ca123d911f6e1b1f63ea65de1a8c6afcb6fffcd4ec0c36bbc9d2488e2256da3717c9c90550fcc28fb49a3db35492c26aa7e3927755b75f86fe069c4c10bae10f1770efc3bd0e5fc69176a01cff4c373986219f2b867442af0a97df9e0780bf94f03f0a2429f2b2d8f02f766835969e5dc5e79d7cb4d003a0c4959b6940361e158444d534329d20a54263071606d22e1d4f662851e8259d8f907baa95d6514255a4678e541faab8d1809a7f60d09432e25eec6157533b255fa33ed66f80af6e878af87dd04f026c62a7a2570236401c4b805947077a62e44418d7afcc0e18af0831ae3d982f139ed2fb24f7c8dbdc7fca38ba69d228f7426a6ee8287d71c5c19532f2c763feb6110e64442082ccc26fb8816c66be6f37be8be3a4736531eab4cdd82a30bf7d9861d8b7d66104430b93046d650216829f819f918c05c6cca751441e811a69234a08c9fd441b9738042394afdad22096f37047638240a7a3a804094a61ef3bb4270da3b81d8a9e32eb3516f7420c47b77097ae1d055ea31c0cc6d72694b91668576c7935f3e45b0748184d6f4b840c6edb60fd9eed2875d709ccfa2a9c050636a2734898cf9ac52c44c61dad2dac1f565b2a0c579522429b5c38f1ed4010c5fd276e777b2f0b0fa2bd4fdeefcd8be2c29c01cf0e71dc8914509253d42559963c76a481547f2edaa121ac9c7fa908b1d0ce5ed6f77006d98d03a12ff5bfb07c297201658a1bc0e1fad44054002913c570fee4b42cfa847cf827c3014aa9c404f96a9fb3336a111d39c086696a2fede3bcdfd78a10e930b0ae7ca7711df6962d50d893b42755b53eef1af4e12e00045f32923292a3639723148e3f7caa88fadbf4a4c0245419868c214bb179585058d3eca02965714b8a590c7eb9a5336dad7935738c3882c79e80f09935b5599fa4d9182ba5071f48ce4e4182bcc965cd155c712acc0fb1d75ce9996f8256478f9e43fa1b5ddd034072bc03e00fa9108a56eaf1343ac20c5699aa225583229e5409053ba82f0e41f214a194f32d16b90f54476dfe1182e3ba5a3113089cb375cc206f7b7d45e283dc8e7ea0256a690feb67f1328a14bf513f09c859c98d2ba884ee912f8f7a8b3fea93761feba2cb51e354103880c44e4fe5830d63decc4c2b3fb70c53fe39f7d5315e6fc6154656f73799b038efef92bd7cc6d978ec742585f4be4c4acfe25861e7499f9911783658873f307a7e0fff6243ad5f9f732d8419f19baf23d600408402b32b5ca53aa0143dc96ac1a822bd5aa55aa61522bcc138e15d33bd6391fe8820ba0be1563c80f32a7b5a393113ad673141f5c7af1bd6619848c62c9184b35498b26232c425d182fb3e139311f5aa48455f87e075f828dda560d748ceb287526c7cd790eb1b6fb162a02ce15b31cdc42822bcb104ac9c7b4ab63f3484a8e10a29a83c69e1f897108c4786e7ff105158779b9d4a5e3a0eafaa447a8c7661536f0027e3e59abb72c51ed11e0b96b953591cb2d86be57dd3130b5f1821c7af09835d756b8e1d427090cbaac56417fb1920063a1df1fa8d1b14a75d804a5db4973b3d28f56da618b6b2f07874d5abd02c51ad489aae3abd500d4620a042bd6b711a69e62d5a3b542aeeb5dc80b4a608eb0aa92e9dc06fd5ee6b5e610132a538d0368c22151606432b8596b3072f06e7688134c2e621b25a00273260db6550b9ef48918ce2f6b6a36ea3dec2122933498b651684c85efeb908d85b30c9c33498dbbd40ff87ac7ea2ee8b8c00ac1b25c904af51472558a2edf675e3bf659462bf0f96e3fc1f07ac8b53f62de0e16492c173e97de1d068e8ca0b4a25633c7c9c3955a8abe2d3b04b8ae96a1fee31d482125cefc4bc24acab6665888bd923ea01031ce403d072ad902566f3663a4d9da4f7bd117d87b953b0a94776d6899987bed917eb04d2671eedf8e4dc9c1131f47b321d314d1cf5f79b81c6d120f49b54b50aaa4474d294748c3e23e18bed3243ae6c0231a15e7266976bb53282a1c199ca83c3e43bbc1acca0e1509ada1b3162caf436b93f989393907ea5078af5aac2d1797de697e3920093c26a2c5d7e0369d77a13080666dbd7ab9ec9343e0b89f07fa9ecb63d4e1493a1effcf6c1eac189c92af4aedef7628828e470bfa12fdcd83902a4083d44b1694865fb467f0b4811569c9aa21c106415793c5a1865c6a0ef5276a514b255f501cc97c9ac53a86fd7b690cd28e381bacbf827fcdad566cd47bed3e59237100c3d1390cf18f57dcc27bcb5cc3efc05ef97f0799c5b6b7a375ccefdaf0df8c68e292ed633728a16869292818140ba83c29338282ae2b16b92e281ba73df7cf69b848dc9205ab2f0a5c9dfc6d7edaab2780c14b213282b90e6aae0df9f42fc16ff0f307260529ce4426996afb0b3d4a3690644c94935d56e72820a664dcd0eab106135311a6b17480c510100859e75af6d7e41e0fc23c86aa1ad91ba520abadfb0eeb2f6da7c2196006a1b6f7384b7247acd36e9e908f668859a2ac389947fd1145abc0f31166e60644e441862dae31ec073821cf017ae6add70cd81291458821584d4829dc98601b82e539d1c6b7e2e57904e27572ba7f576252688217baa2f2d1ef41192c4dd4aa473863919b9804054603db7dd64a0d41ccc90a5636fc374294b6c027933a4c2a76a6bd178b2d8a2c3997e69c28afd0f18570d5da7051ec0bb803a7cbdee45bfb91e863290ef16b4224c55de08200194db937020288a81dd921eb8bb019d33826dc7705b2a23d536b38cda74edff6ac49d270f5b9a502d926766218b61624e2d34aa2091ec7bca7a816cb3b8289d8aeb7946909cd7e2ff84e6f781ddc23eb47e9ccdf8906c58a2c75ba556172fa870759f9741c95a01a71ef4970317c2e308e48de81210246aad10a3366bc65a96fb2d032d58e96efaf177a771b7d193d8fef79c088bcd864215b71c28f79095995a651d8e4306836420f6ed2c13f3078bf92e91ce4670fa843e7375115e3761e9e62671ed3e67768fb326bd00bb33df3055b5c03811e59424e059a16d772c3b975ec0ffda9187a339f681f5283532a9a31667fb538f2d619259103cb5e57c266659c78b2431a3f1ee78ddcb56feffc519db92ebb3841987b4adb033bb8550e5d16d66955c2c88ec0e30a3001899466216ba92f6296eec77112b3800a81894e15efa6e7e16d9a2702d9fe80bc364cce5af4e0ba43959dddeaea068e84c4cc006ba9e1b3e894ff9bcd4af9762146d2ec614b6659ce7b634271423b76018ac54aaacbe4569146e0c05168bd81a3b82c377094f63d823964e6800744256bb14c731157ce3156520f1246662a691df7a9087e251b2390074ecb5bac993295a026cd550c40b2c79aa4e574580158cce99b535a0d8af387f357006539a15c6be78c03fe2626ef1d65ded694150c70efb4effd08c97e075f23a5359f274a73c1188984a1fb106da3296a0ec94c0fa3f682bd0dc18eda514cc9ed7ff2675187b7aca517394e7c1b4cf1bcdd478f1790dc44dd1dc471ee3a1473b252c00f09bbe05c1f546597c0556ace1190fdaeaf4a09fdd5639316de5ebf149433caba02d1765280eb7ba04fb49d58671ced32fa70b6881762dec9b85877886a06f9a1ea8b4158445190d0678cd7f27ef8ea34346a952b2fe3ae46e4bc0caf4729cd6280f51478db8655025f8f6a8ccdc96847a05dabaf0635309b5bc4e3546f03342bcaaa2a27c3d6dd02c1bcfd2f815d05e7657d1aaad958553937d62cc03cf66b60696cd6b255de02b50f2da27b624e46361e1023ee8b90107f68f8e31527a5380d578294e22fc4ca82891d9edfae53a06b1b592e306c726fc3182ef1126b023c087aabfbe360c0b118dba94a9220e234b8ac3cf3133d0537bb66e5f9773c82b5d678ef2930d25c94e99d273458736aefe2c098839888d90583290109f46f5544f1f24587e9cf3668ca44b6d5135c741424929600eb123c6e7d6b07113d9ad183914bcc9a326d9fe933672a3f11b576330e0eee9b5604d641bed30ea4d907ae20d30e7294af801a3a90c031a8154ddbc6ce310538245ede78aad76f308433a5e0af07127840714430a98c111a810156cb74809337c86e2d7178669307623f5be5ef65f1f14d8ef93e4a4a971d306ba88747f3f4cb50064160936f357fcb2e159f3f00988b84141db446464e308cd128e80546672d026809ab0612d20d7645b9e59aa22fd74f1a145f9b867f2e0fbfdf9b8ce58832ab1dc50f449075c13cd89eb9c3b7feef4e7af1ca4743941c5a56be13364b3863e6d5b44a8f527e8421062099c139b5004f880d13f634aece51698aa534bef1b22919c0b5f6ec62ab8df240653aa00723289dba883d61d36d14231cf50bb76c7f16a419cdc3959f35ef5f069fd935cd6027b6a58b173ce560e09708c24034c339bc77fd00fb688ac4153c511dadfc8b84e469795d625e52d319ba7fc5e345124c49560a2427351a1b8379d25eb861bbc91e9f69472b67edca9312b835f806eab25dc980f0e45762ce703e9b88ddde4b1e35c1dbfa825edb684c7d9967ca900941707cd9095091e66e3bb7c030fc6aa1be86f5597cecb76a91bf6106c71f1ac930ed98bf2d9147f18700c0fd47b471fd763d1f9ff6d70349b393bca30b8a7a120f2660a4a17d15ba778aa7f1d17cd6963d3b4ee7f95f1d26fbc0fda2691251034cc737eb6c149a8042a310ed091ede1f7645b10f4a3bd87d3262e33e932efd11f50cd1c2bdc844032c6ab4cfadde8cc0089687a569714c9674a5fd6ad65cfd32af4a900f513e59e8e452e0aa71cbec6d588ab59c553dd129b32bf9c46096369b26d8a4181a4d9b1f11ca0c6c02f0dc3fda0bb08e0e749e8b3e140ac86edee54d905064aeb8e4b3cab9c1d366eef0294f093384b40c8a0bb9ce514ebe3dbfca5e7250a4ed1d1430336251b5cb03920f3d4a4dc662d7e581e57367e159381faa65cf8976b004073e3b27c64f9a4b2058c810fc181fd6a299869bbd3d4cc49cdd13cbfc116529079b8e2fd221ff0a4f01f9f7351370c660478067aef2b93507f722755cbd1fd4520bba6bf9e7b0d3c4fe84ba31f4dbfa9f0b739be285b83ef557980923c49d46060fd20b940c3b9483c1da78afdbe2d9b45621e70a60cf0e681fc2c21da6925e6d26003c779c9909a64f614a344b74bbf0a204209c6e144fc0761f5fcf17d34b8db2b2b750d2fddfb2b416cffb1548befe9d7e48a2c65606619fd10939f8c280cc01d14247653fd920d3eb5f6019d2b0fdb6da8fabd926ee73d6c6bd5d6d9cb1a40a236658fbb4500d115e453402fc63d031639227948df30565d76e0ef5ec5e8fea59d5a0a24094ce89f2604200202536c4f16527271ff3b58c0f1dd50944d4f2319bd32affbb050d9b9e0c9854affe9d7389760faeb173f56585dbb80ad5706ff8e706d35a9a0113e4a3912925b326a9925b24d0d119db90e0fe4f2f8f588c4dd0a44ed64c268539604ffb08882edc09c458fa8295527b5b002aad395e05f1a1aaa990abe5f303f305855e33f5f48df81f500567ed25f4cbd6c2f345547518d26a04b6e4c0f3a160282fae593c95c47eb1d0f60d43521ac89a66439049f9f42fb9fcbe7c7b4025793bb93d43059d35d99ecb8dad1195b23075832b71b590a098e5debad28a826e9d5832cb8199e5279ae5834626f3f33bd4434171a4a44330cbea921391ee3ee6057d608276453ca8f3cdac5e1aaada665fa970267f86a85804ca19ab4dbfebcc8cf725c76db8620bdc14e0e9a9657bf87b7113c04589751f57ca83220b8eb6cec892f02dc0d9726a619a14cdd4f49d96d27b07b657fd910c1ef37a9ed138cc3f8a00d6ce1f149a3f702678ea3453b871492d628eec2e73746e90debf0299096dc22203c93717386803e18e74db77be1e0c9db34c51948594fefb60b59a5a8cec14a80c0a340cc3f08433a2103d3ae77f783a4b1cad05beb858dd59dc42e1f85559bf716685772aa1b3e88d8a039bdfe5b373bf959afa67d359ce4763d9ace100323af095819006ce5baf43a2b70bf70805811a79bce847c7dedd2c6c52fdc476e11b426b5846c5a8e0d7056c6e23e4208402a088eaf4c802d3d7b30f8c339eb47152f28df4b5d6361fee61685307d902d8969c01d7fdaec4f06f7491cd44866d41a8a5cace53510b0794a872c804bc135d554f7c0a9208878611b427e3cfcf3873c7e348a0275fa56f052a8f3e99a5d7c47c46b1aaaebd86497b6ebdaaf868196358a130b3977d6ce9cd2b564443dc6da7ba3c1c9070fd56ceefaac9feb28da98011fc227b321fb7907abca0056c5ceb224cfef6ad037338e16f667ada1c30600b625bb76db01a641f5dd9b96eea7d75e6576576e2d76563b23f41d2e45fb761093167761c6509d59f5041cdc35dadf8c192a874ce0a7607fc87d28bfb759eb9f7b854a2ac4ac3027b9c7642f3bfa0dfab92a5814119b94c0422498265426af888b8d01a8e9b19f95051376c47d08a0077f37a032a37c478e1a0be451ccdbf983f765044dbd58432f39783ed952cbf5b5175faf36351f1dc780da2ec358723d4288788797085b29a3afabbdd17e425a2491cb82f89c82cb24f6a0530757c6f677c6432206ecc5025d8594aa046daaca4774b6351afb525f43900b8c7c785db8a8f276585df9dd654ca06abf8b98b45fbe5c5345b49b02e8fc3014f0907de92e53a989ecdf8eab53a83a95f7d4f7d47d4cbece72e80e8816afed1cda8eb71160a10b1ce7eb7efdc6a120fc99cb549943f5a0ab5d33b2a16dd4336e462cce25216304711c6aaada9fb9b75fcea59ddff9ee578b5440ff601ac2de1879d92741d157bc3cd72458c41adabc7872c8651ca159ebaa1476f5c4dac71c523486ca80e5aa7a457378462dae9430865b097c3b1e8c081c0de9b457ad7134c620cbb78c34fb3f16a6bf54c57048698c2b84a9516ca4245065c10455b386100771efe681e6040aed359e919676668aff0422fa42d4702c3fbd2bf0c3cc6f66fe710a1aaec2335180c7172a6dff7bd031707212cc444245d342056441708911184fb2a071d5eeaacb21bcd0de51aea2267df12722bf9428ade4aae30af1fb98c249bd4043571dbfc434da4aa983196b83cbe2d6fb48616b2118a8cf0da95986c685d0e2784e62274f7d74d4d47851adee3dc4537b35111246d9a558e6cb291305c17c9f750b41fe181312da7db51e1b64429457bdc5e65976100d640f285df3425847d5e104d4595ffd52d0adcc66adf09bb6a7dcc29a80b18498b00cc30f018c6c552e0412d8b11786ae162808abbaa82f9d8059e7a6d9e9d6c9bcf187712044d8a78708a31f3f0120cf8ed97266f5bc6610b68e5270a8bca7227026baea63cab81c56d212ca954918417dded2d9242a63a899b3b3e8da41ac6fc5a7764ef686677a1932c3e1583759214a12ca7b95b49f264621e642fe64b7fbeb07d8885f629ed57e849c90b27397af1d4f8ada3d21601c387bb0d88bb560c563f9093391a5b2195104c8db6cd62c134230097cf2a74b0f366439f93996a44ef807f221ed0de165efe6816341fc0078f6fc793cd4386607952192dfd1ea3653e2c715a1e6a1d0b45f54ae7bf9733c80f296c431400da75bccc7ab77b9cc8a82c96243a34dba89a1102e1fa6f40029164dd8f8e2da2915cc4c5d93b7e22e611980e079fdca3bad81d1237c09326ebed7f67665899f7ae8d2c427c41865ddefa03a51334bdb3e447a83474f1da6908112deade58bb502376f6a87c1908a5ee056e3501dc9b60723e34c1517b6175c4ab4303ed48f142ba4fb884b1e6f30c39c0141db38293791f3a096d99b7f51cfa6508cca112366f7ef87d59e8720589501fce67ae2073dea5087238509202ac62524175b7a91209f24ecda849eeb4f6afd6b9a86de034d32f86a8b2668bdf92ac15389054903389d63553e27c738ca214a95cd9a3c445fde52f47bb2bdc9795c31c69568e8da99b3b874c1b9cf6be2cc20d3b4e1628840c83fb3f9e9916fd62424296d1f33a0bb33fa37a68fbafb15957782e19c3b774d24f171c304837d372565391cd56da172a29f08164345041fbdc62bb7e9a1882ecdfb8874edb6c00eb089f2688bd29e240bdccca8260be8852716359f4a56593efd761f5ef3e6084c9754f47a87220502769977a8e1ab0df0b5f16baf5f2738cfb4cda6407174aa8a3749fd3c2d0030137ef063ff2fb0a87a60f4bdaba24e1c09e5959a6f7ab1394e19dc2a16306e0f91470193cfe82f158c07300e138fd5883f6a23343bf7b161e84ee0d570e6fa62d17430b5bca7d2b523f72498198c8222c6b3ce64d13ad952832b65cbfcbee5a8694dfa2d35e40266eb373244cfd0943517646f1b8e80d44a64a88ab4af64174f606ef92c00052a3e1f245326895f8da601eaa8a219f233dd763f084605a19da5ca53ebf216b701498d5da97513f3e075d153f587555368f33c20216535b77f7bba4826a1a560774e21c8867b55b0de7827704a1c0c02b772f02abdba825d201f31e823c749a9f5c33b0210cd1a22e6686cd5857b20e867315f7a86e7b91b6e3d089a86b60ceff1664531675ffa2ff2757198dac15eebd58204782ccfaf404c2a61e1b41512250cbf5fa850697115ab1b242f3ee66b715134331941068ae4173079dc4eea0734108c2bf6147b7c3d885db8f7d966b4559c17f5d77c4753ca0f86ba8e2b7d9c46ccd751300b8ea94a5b384eeec8a8db218650390a6d0ab73dbb23c06557f98826104e38774091e27121c5df4ccc629fe1a935b8e17ad09943a0691c9268000aa7b8f96cf926ac800fa88c8d5ce9939650f3bf7bf2c14cd50b1b8a1bc7d35a4fd458217ce0016faa1f16ea24c6263d77c2385399527d2b8836f0400da2447e470076606d1dc4b611f3cb7997fc36d6f699574854b091d9508d61c394e7739bba50961c210d56ac6e252980ad6dc053ccb154f9bd62b5bf41fa24fece0616ebb5b02c2fe4e5c574d545d9b523c4d1f81b010dd78680a69fc28db4890cfc68e57d6f655197b3767c57355a6e24594dfa0e625da8f2f07bf3e28fb4db14eafa9baa1b9b17e082bdfa3620d54f31400fa21a554a295a0d4aa87546644cbfc5946d34913a4bceec6a5087fa135f4662ff77f19679348a4c6eb1f275ae3e87155ee668472dbdcbcc251e69fd94c77326a966034256f661f1da7d936a783c21c6846e77135aaabb168e140e4ae2142a42063a3e640aa94e904a4b0a055da1f849bb376de662aa573f364dda38adae61229b41353772edae72831be5b57cbb38c85be144a64f1eab47fc5a730272e2599d71686c830203c9a246b4fcd5fdcbd6839e86128447c78b04e25d49795019fb3b5c42b1707421d5c692e29d4e42fade5daf6e738e6afdf06d5e4baf5b276238976a7211c4014cf109b66537f6e61186f3fb82cd5d555425c41c422380cf6fac409eaadf773f6466169d88ab04821376bebb153615b297de5b765fe9d5a9b81f7f96d69e4ce0183d572fb63ae1af4db9b8b681eecd6ba9160945199dc27fe1aab602d0029eeb80fd5d6001d83bb5cfdf5a84de5a22afaf44165b89535768d7b9166c2016c163417577691be964672888a9fe847acb427460db4739d1026bf76ae572c718673e1126abea3bbd497a929dcb03462a41c4ef6584c3135537bb1772fbbfe3e1ad489106eb4663d7b49b624b3097a5883b540df787fad9113d638fbd6db9373b809df79bf7d4e0f2161c0e432e098b31a4235c883eea6145b8ac4ccea7e11174d15c87e77d351643c5e6d88672e8d9f4a7c399bd760771d0d689fb57fc601b08753c8fd682703b2930bc77dbc133620b24b47b508efbd4d0ee1a59e77485c28053a620e403f0feb397910fd572f1306cc80774e6d28ebe51b50ac9b6e1f26e45b1b7d93400b135a5bef31ac89287f1d083b2d87b9558e4d1c1e853eb1b96fe8c325324b01d732516cf60eeb88ff43836a0575feb31d473d58d78e598c0775ff84b6a6ac85a14b5df91b3e62b290b0587a043d8e74bf6ccd29a8d355dcf21b5e9c30e7cf8903cdfb21b6fb2aed66064976471ec50305fd38b8f7578f318170dea222293ec5979eda8f392a40ea41b2791808df26e16eeb5aa5ce234fb8100dd7fcefc7dffd254dca03105bdc32c33844f07fb1aec97fb742ff9691ffa8ec4453d2e227dae423fd3db2a14579d35fa9045c24c7ff84e8cf9c9a5a3e12aaa9ee3d0980bf3bdbd608ccc3f29a9b1d2fcd6218b29e615b8b6111bcc7d9e47dd99158575f28de44185663f897c82ceeb8badd6bea2c5e6a67dbaa5daac8d5d2f2368d26e026d174c5da563ec5c7960293e0ac468dfa0887b5d7a2c1435bd627b22064c64970cfab87b386dd81f6f29ed9721b045c40207a08b19860bcc7eeea890bc6835e58a55dc68c3a7c4d29ed6c256933c9f2287c86286053b473e3ff16116e39cb70ac7be4ecf811eb3e0e6d711de61ee0e1241dd16bc7ff32f912dafe13459296cf23463d68f58e58ac7a4e43817990b7408a2596602a149e5cdb28602acbd648c2a019b2a96e49f2fe02df8e3cd56c89daf95a106c36ccab9663adfa09423195fe7fe20268f29e3c2bc1e299d084683dfdd66dcbeced3059f9abb495bdde08fbab8ec24659b6fbbba6de0bdfffea7537c6c3060b84db013e27adfc3a32eb904cac9988ea553eb3fe1f1058f1e62a8bf8b052396e61a287827c6cbfa1261f7757975907a43f257e180d72a33a165166e4eeedbd2092127fd226ea7fd05e1b0b7760f9416277ec66e27576e06d21d70d7e45e0839c1e5b3253f8809db32c6fb4c784c98f0c4a9c169e5df27c8534875960b35040e0bf54433d8a5ef6130bf7d32f5a4d961a028fa5b787999480e5a217a3516e7a437188ad2cc48d1448e3b1c410b26e5017a91e9c1d2e168446a64e8fd32f62ab870eb03201206942338de790498bd413e3f1d8b293381dbdb8c2920c472cbe1817cbfa3fac77688cefe383f6b60700932630e6b48c5ac8d2dc1d103c5ddb5ff72805f2abf889831f172937c8165529a7359743720b4cc51871125126f297315006c5145b191d7078430b41a725e4bc7c279c61613eca36775950bcadf5c9a451e77c4f2ea41ad8cdb30fc9dbaaacb69acd0de57082dd54155ae2cbdc6d820be15abdecf70d3564c8cee5bcd0a9196c6d59c66c715e52bffec77b7168d2149d7cbafead3bcc78446cf642b1616d340e5794356eb8afab7607d40b1fdab42a26d18c43e069d410e4bc4273900574279a3542b29eb218ce37f4e9dd14dd23066cfcbea2c14d3583d8ffc9095d72e52afad6fcec88479bf0268e4f130e1f5f6f2075607eb268b997f3fdbd6e4b16551b5d22d30416a4780ee7f2a765dac69444049494617a8d54c929692472c48b7541bc5d178d4f6e99e20007c2efc8c608a3f201fb605cdfcd444521c1d6d9bf8b087778c940742ce1bc51b4b105ba0486723ff6190c06ca2ed6483b18a03d3b055c307189a4db85a64e6cc38631f019e031faa8b819c9fa5b299090e883a84dff52177f16c25c70771e57b27d75bb4ed6aa0f5ffcf6137fdad7d449a5106589555ef152356ebbe1e91c3998940b91a7c2daf8f6e0c6216962876b84f99ffe4523a1763d6664ab90f5ad352222f1114ea00da748fa469e221cb996e5403fb86d98ee45a4a14409dff2dca5cbc440215b1044facc70d67aeedba506b5535bfa28f6308b275c636de28bc05e8edd1098fde41928cc0b59714184bfeeb1fff1f6862e5a135a7ce3c3642659046eb1a629829b4d5ceed3d667a2b00cfc729f689bd671bdcba31d4b825da237e6fb8543bc97780934848098c64ccb9a72eace20a21a46034eb01421dc8b084cda08db3eb01e6472d3b9d3ea68a65c6246a3d763bd7383ddc8edc5fbce102da0f000ff128e06ed91dda750f2bf64fe315d1fa9ef9e8a112de41301ccba11e2999f15a554c7d7b649b19c512a5db520f6aabb377cf596411dbaae23743e0cd36af2ffa335afe607f6fc5688cc2e2e409564a1d876198e8c8a383be91374657668ecc3073b5e0768c144604631cedbf99908147c9e071057a2de1141715a72ac53728635315ccff45a8433530246b0d4bb3c4e2ac7f29f025894423755706cf57900d8ededb50224705684f9e1d1f8cbfcabead474607ca4ec160875e619d85c0d1fc396271d87d6410db3b778eb1b33b84ae8b7ad13b82a9fe4fb7db413b69f3fef4c5a64d6ca4228a60f0bfecd0800550f005fa96ae5aaa72869480c902f3b3bad423258549e3c7f452bb828b6013014ff2a9162eba0035a65d89bab1d4b9b448c1c6208e278a6db164e33859c8cca2a2582e29a0fcc8f463769b34dd08acbb85005f9bcfb3e556abf199ef849a6e45036a591cd119547ef601078a87c4f8601f3f81ca8f453df090a4e42dd0d7d10814342b03d59f889b06fa47a5ae520ea2041bc24d38f26d060d16ccac384480c5be696fb80d9b8b65786087b6f8b9f0d72a114cd29da06f8d8d420167d27d3c36d742003ab1b1c1d8305c48d714f867a9d0f99f3e88e5b4ce8a8dae99bba1454f5ade07321e98043a29f8f935d88931fd278ee9bb542d6e83a9a6fc5d9d1fdb852e8d70ffccfa19cc2c44b04a2c2af2b66912f3ecefe81d7feba1f7d385371d75dd9956a8a298c2b95db3e7fe1dc8c488e288719deae31f9d3f16113e6f057c57268ac7eb1458d494026b31257706d1899434e88a8a0971ca54b37eb1aa6de936e19103c0723ddcc070fde14634f32992953340ed00ec786dc1d442d4ec0409bb6aeaeb99c451bc1e2f441b0e0ec9aa350240e7e804f61e76553087517bd03ff2ed41e3a7c1ce2c3bf4bdfebbdf4b70c5649051282973b31e7091127b346e90a7b39545b0b4920a5699fcad68285a89ec38abb028601e91004fad4d70fb9c7b741e13ec6f5b884c81997c2f1e234f4011a87bf82102ca2299dc1d67abcd8d5881932f4f60ed3242e105c5428744ce9bc8a6034659e8674d7d1ea7650060425f6c8dc0b25aa0c7d37cf63ed74aeedc7dcf6d8ec762a1d463b88370496529313dc3f9b3191dd2307300330dbd61741707edd1fe8faf76a612ef443fbeb3b5392bc0740780bc7d81f883fd5a55fb07e0412c2d7f766d5973950531f1fcc4eaf1e42ab39720510ba172f1130a61fee3b28da4acfebb7341c290182383f49032a904e9d33f84d98e31bb28dce20153ed5136f4194d9b2ea2921e47efc42350c4960192b0003eee5595c624082b5bd7a911fcb49e35535d976e5848c92e3f878542dbc2e9285766cbc7ef4b62143d05b9f76117ba2b79c53273a2093bde7bae9b4076262af3bd79d0cb12fa4ed41b19c8b3b67075e884fa2772f9be52895d36a85cd127d5bed6e74531aa25e7a6c8a30ef30c94d7ea8649943170ebd3a25f134b1b60353421a2783dd28ffba98afe67cd64df15e998e62aa8cb21c7d0955ad04e632d4fe97e306c1f5e621ab5451ac6bf64ce15eb2a1272cb5e88aab9b8dbffb53801afd19fdc2649132dd712b99a5b435e1cceabab16a7ce87c37ddc8b3556e067124e9414555831c5d30f360641301233d7279830fd8465f967a7b13085033c3ba538b7b0d69889c5915e0bb0272d0e250aa600b39bcf68e6b76a22a12d3fd964204061aa2bdf363ae3aeb8449e3653ecc5c04f4d49570436ef316e738f37cb67379855af5c741e440dd99cc75f96ae42dd613b022ab0b7e4792fa34e011716f154151e4ef55935c6828f63ad29eb4a5cdf693039cb81a0e5ad437bb75e98e616e03b20f0c2e9488f327fc0207ab9f82e56411a62fdd1577c9e1021e80e0972617739c27e8864dc53c365bb049b4051684992f73d6ee156133a1c5157af058c79ec0f417af11f8921caad915ec58bb6a496d8e8061c8892ec44567e10ed631a24d55ec057f7ba931302bf4f57fea6d1d6809f36d3a4998a73076009868ba6dc81a98e5baa7011efd33d6258b82ecff838fb75d112ecd2985cc601687818cfda1f9d41ae27763805d3cb4b3df5bf21ba07e765319ca3b81a48e660a45122101d14569a64c7846ce3c23625e79e22069d85385b15854f7447e287bea02969e11e68d4dae6eff4d4e0258b6de1bd6c52b310510a5be12f556e63af70f8bde77278a3f4896b959a43b39dc3f07cd320305d358534fd9bd60a002113b673503f51cad556a860ccbf5802c1f061c5a18adf56765733b07b1bd64cbf6d2c4e9afba61193985a43e18f110ed4368f42b65ec4ea5e6ec44bd5409448edcd66200730966d0beed5f2093380a5633e82775d4df6f0213b4fbfb938e972126d023c6516ad0587a56886fcbc1d38da33e5642e544a79acd5e66a10c2334df4e7dbe6724a72a10106cea16c4848f67668d638152c34981b30d26cdb84cdefb05462eecddadea733679b450783812a896f3cff1974ba81e272188915fa36188f821dd72dacb799a2c2ab2d9182c5df52f6d200917411b4af5fa2d489395d7802920232727f0cc201197ca0702a990368734df9fe279393c1600e1f99b76697dfb26f6ea726fd668cf71703df885dddfcf0733415e89d7da095b968a0072096be0cd703380e668407fef336b912b702e45f42f7262e9775ae555d3ac95d308cfa4a824bc99996a847f8ecefc6668f45c94f320e0b1decff1839cb372820f9895dcfa8655d1ad65509ebbffe14c2a81cce3651c8d3c2b3d7666b76dc3c1e761a5b36b8df0b9190ad9217ab66a9f4e1c90aea1150bc66fe62c17c6b2af2180e80c5c26456dc57479ea6b5995f1134d76d70c38b4483422dfd5c9535fcb863291aa5a1883cd09cc0e460186d6279439209ef408b35309e626ce128c13ad29361b62333423164af5ffac5385bafbd5facc8a2f6d35ee6dadc66dde103344d7d30e2c80aae857dc170edddf99c1bc700b23fe61d1571036fa022fad72d1abb97fbf40f012e633ac82c1079c2b5ab85236e14d33d055a6e3b69aeb0be3abbe1401b310d67d51895a762aa3a4ea1b22a5620919b8cf95f774c7f8377293316d125b56623be92c99259c04b01bd20ca567d3fea7dfb2d329bf57768b1dd4ad48cfa14ed5811ac94f56603b075fc7eabf580b6688d81d6343b42f63fcc71494548ec0f7eb889eeb331661b92f63ab765605a83db4e4c909b50c8e1918c058f0214b328045796b8238fa26eb7a6bc2b903b49cfee83a6aa49397043b0cb5023cbd4ec51e0eb34ae1edd312df27788fe09327331531b7dbcae433b6cb46f4e198a164eced7e0687e47079e022948ca92996490ab8895cf6c3702dc8b22c7a483e6a7ea71355db944ca68ff2c937bf3c14dc0b5e9571e356cec3dc67fa66ee418c04cd3b8a595125178dab79508687ad86b9210b9b2e536a0865ae30e858c1fbc4c88a4586c3a911cd38dc36a6afa5fab918f2910a3081d4c706702bb0de2f906a9ab1f4eca442bb06245296bb6c23f55181ba2bcb999984507af9eca9260aaabc0c22d5cf37023d03be96d7f6255177c0de0302d0300cde738cb4534fade5c0316fc1890c4a4b256948db4ac17931e976a2c8eb5651856904d09a065a3a9d68c032e5f06f2849be73a82f292ca781de0c6be5f6fa74838c17d17cb112d7a8323243cc4084d1287726e24479785dc7329df1828e0f7aeb4ff40c351301549c58c29cd633f80a4d454d26614908b56e9f166538703ad0e4d9eec2266bf77ee33c101623097c07c6736469c3bb2cd7960eafa42cbd3df77a342b01b3719c919c0c8754f53b85f72b19d072a522aad9000bc83080c9ade90ae955b814798598d039079459dd80b91859f0a8536eda91181c9e45b4aec6b59c6eaf834061925684f8a50f7bc2ba6ce4cb43fe0a549245bf85c0815331bf07757a0279b12292a1f30a23ffd758919bc3a8c40f1726206372296225752b50894b690ce8e23d1f95847f50be64b1c1ac11b49a240afb13b39a59cda492cf2e26fe456a3328ea35e5523a9d5eedc6a0ef49504c47d1e5ef81dff4768f4430ec4141ea5ce0b2b5c9f40e8a9684a05b4d7094244f2783073e18e40e5074497eb9c3a35e82550a0b35c0a454850553fb7b905858dc362636c8e44432566451e721646afdaf14abc971967808977226269b1be48af2f259b81fef0b30cac4644bbb32f1a2aa8828451ff06a816cdca26f571a486535e46d2c5326cffb062c929448d4d6c9fd60281333d1d429a7f433da25b246b2c7ef42c3afac4c0d348976f86b1c9a7361de68801a85c22451f1df5907bd993d1a3d54b2b58cd7025f65423ed098bbc1d563dce42b5452260cf806ae8162d702b13c099e32442b2c2dc844451adb808c29958798ce3fca84a2923f00d63adc2893701dc39da7df670799f9983e0c53d7005e25cc4807a6e04cb601bcf5de31cf213314665761afcc012a90c1e998ab8ffac1598220e19b0d560ec1bf331fb6d25b1c8e8a211379836d7c553d74d083ff538afb0436ca1857d183ab128cc5857afdaa290690b6b125b347f5543a843189ced4c97416a9b956801bc2c741609e6266b53ac94e324c6abe955022c5a0350d337e28a2cfc4e3af4b333f7922f3a876334354bc32d1b60af767c62c6eb63451247c84e7b61072877b5aac545ba5c83473ba06a9acbb303d9b7e5e8589728cda331319054555ba1c5ae5bfc14b9944e49cb09d6c3b38ebfb689d30b6f67cacc28fd74a2b9b694f1739cb3d5e69b6220f043aab56d1e2fba5562af6468fee2d71d2a3c954ac08eec438c8951e6ba204e8a6233c264085799832cec481d96a4cb2e6c0cf47d445e9b85abef0da101cebec4762e11c4a60f250e1a1eec15af735cd80f3087962a74c338ab94ce0c830375a69943820b4eb338e272702c1593c5735a4781e2cac1289e6353611caf78ec8f91695008dd9e7b95e4a2906129ef08c0868b83e49b668ade3608c24b9734926ea8952e81c516cc046b4cc8f65141cc53bb59b7ad1d052a28819d904e28edc0730bdf6077c6caa70279576826c254d9c5fa665939aa58a2f3cc45fb1325a4b78fd3e5d333d9da30dfb9e64eed1d9ec1dba5ce3fa02ee5b33c559d7c2b635ed82efdf668be63e0261816dc7f45523e6fc7a6b244e845852e16de2544ee0d6207a68b15218fa9b8cff200b262a430cd9f6c2eb1b85d18914b8bc19d017c8dddf621fa12bf00fbe286a4f643b9df20eed4f1f5895179ad93b3262dde663ad587cc31fdf7082addbd2ec4abcbfac48b950c541635d5a522b15902d4bb2aa987004a6bbf7277573fc3d608d00b463d2eb8a4d8dabf08f7428c4f2e7c071fd7b072f0c7fe9988b4753a2d5847527ebc7672f3308b5ac070e99d5c0a8c14c885ee0be2e181d70c082591f8bc325ea1c407f6303b85a09badffbb3e8323007cbfa145bec750a28806ec56f6d8afc2b278657e40fef2804b2243264664c54c1fd49a1af71a8bb2743e5d2b6796075ac1cf9b56b86316ab9ea9011d02eaa7060f4fa72ae2f2e4933bdedc56108fc0d006b43446c76eba7737c11f494864734ecb829213b5b011b8457ff100a4c80f812209e98319a640b741b8141ec505c4bfd135cf4b50055994b1d187518fcbbd429e1c08ca5f4725824df75116c77747af30944484e881958be07022f30a4310b558e2b12f68c14740cdffe03a614c54c3a6d1e93b773b3833af096569517ff205194fffe2e9d27822bef553027185af384052f04a79286146256596863f80d337e73fc7ea4bbba83834dc3580cf5e09632942d1984d55fee1200e3e88802463b578194688f827d256b44a591792c54ed85dd21b4a274e2bd93d8c2cbf66e33ec5faeff19300875c5f4d423258ef0d0655a8a40375fa17889007b6ce70bc5b7445c5699e8e3a1495eebed2b5941b775a7b62a15c86e794ce9e0b23edd9b7443d76edcee68cfa72ca2a7b281b22a00efd298d355a9a100cc1188fd787a0f9b4ae7020861d2c6f34c95df82c88199dce04c83326f3ff5d8022f3180e0db2fda9eac3c53390e826b5287f445a55eba76a30238081e3268e401c7a39a4b248e4180cc019b0010916d266a3242e3c95afa4f9c37d57b53e8c04802d850a65db0fb33d85f48fdf6ca383579ac0731598502a330151cffa6474334c247304563d028154a5a46e95a65be2bc1f0793432361b27186920b857476ab2128a6d94714a0b6aa74abdbbbeee81ea90f84c9b525fa84f9a309aa13c3af8d151fb23f56fc22da5036d721977f525c1f2527f7d7c61ef3de16628c06dc6de3d8f272e13566984e9ca80cbc2746c13e6077e1f98d87588722173e3a235c62f2d90b2ac6ccb5ba2a606750d15dd9eb1c6fce3d06da01c8a87784ed4a3b0173f6534cbb24c419e5b189c80dd945d9c753c07050f5b0f03de70dfdf63bd1b6da00db418c0598c53ebb165d5b0b26b601975e920c9c3624d6c5df23ae072b1c89b2a5c37bc4ffd350dcbec790eab12e66d43821fbcd0b510d6ff6e554efc4222ef5d493e54b9f69be3642f9e0b569bc96e9b4687ea52388abd7f3878b8b14a3bf4a45f00bff17f053007dc03be68c767167236cbca7ecaf1bfcb1be1aeaa32d5c3f48e934fc10e82ef14cb501260f25ff6d23b24d1f59181f06ed968ce7933990f1a5d50b0bc4e252aec18d0f3a5e0edc12b16846b6f0999da8bdc1f9e8a743329280a8dc4c6ac41fc03e3049a9151bfec15273088281d0abe28558994460b2a237bdcf505c4401b0083ee92365beb28462f5497f1c2d57550d31e0192bbd055c6c61bbb7aded79d6752554600150bb14b65d96453f3ae82a813ce0c4abf70654cde1639531c01bd0efc989a5de10dd3656a0e3641aea204b980d3d4cd70dc3cbea6bad9ecc305b7a947e4d69d00fe36124e75302fe05b81631d0a01c8c37753e744e551da6e8789a83f99bb256862ffb991a57e6a02f264ab2ddea497de3633914bc8f53aa40815423e17a3d9772976f7b3920428730c5092704427c5fbc5448bee295de6bbe4da0a2927cf14a81de4a8479426d12e25bfcd9d0e4a720b8b051205cc434edf070e4b495f4f8bafbc722299af2b7bc516595e6243af86eafa059ef9a8241b17b13581162dc940a45e8a987b7dfb7142d4e5e39796137c35ae09163b56aa58d16ac56b033f25082f478e780e83a87e008efb815139137374c47b78f227cfb752b6c677b4ef1861d0a5cbb60ae73a4a0554cba50341640a22256eb4724da21de90e264212ac6b6e694c5d678341f62abcb7e94a7e6a24becc70a5ef60a5bc5b7b673fbde0e128cb0ddf169a70bec3a961d7e60d29e87f523ec08d3954aefca0e99a5201fa54a41ba0ca3a02e991e750aaa5468690e9b970b6f7ea9fbed0737bfa7f5903f97909ed399af414731a08926be414eb2e8a108cd99d54532f104bee06bfd519a64d208316e86d081adffd7ab5ce23fe9beeb6c5d66f456f81774afb6498eb769bda9b10ced7af2386644a6c7cefac4417fb5615361fdf015c5838c13bd9f93eb614867b5c46781d15a0e5d65cdf06d02b4b9fa832937a009d5fe3718bc1b6f49a690661eedc5cba9c345894a25ca7ceb6032fd6dabb2a960188d3056e95d374663d02611950fc7badbf9b39cafc8c721e016cba5004aa2280d87b30bdfbd0d91193032dee2d166ebc90de7345faae765b622e9631d4764a4e4e050a9517ae2998b1a2f77c900a62f0040a23630462d022356dfdfc4a95cec25145a812bafce7df40f5192b62f9c8e24018ec8b40e0550198dedfdacbd5268e8c2bc4dda4479caeb9c47ef51a59050f406e00a8bf8cc053979b096ca43c16b54cce728dd62cf81ef9b7dcf7921e931845b6341bc796ffc4bbb71bd5003438d546faaac77c628aad307ae442ae6aadbe168889de0fea0ace860631c3ddf73c03c2a3ee029865112a1a01ae1fda3908bd57f6d443d87b47019a7f10c6ec9caaca787e3fa1ccd5c409253d41c0390823873341d4b13811f97ec30b2cdfe5071a5b15f0e972950022b5c692de81469015487bf28504a5c8b87665fc304c5e250ef218e73ed4c5c3b48dabbeb4519e1de88c63797dd48c49f4782d431a56c7512fd6a5c05bec1b5ed011d52fc926c3f4440319d3f4e2e2928b13fb0ee21217df3bfedc24bfd5dc32d5776dbba5cb609a77bf281d9e0c0c0527498e798c0700bf8d8e61efb9ae4dc1cec9d4be69801f32694a0590033e3d4244f47f8d997ad71df374134d755dd11b2a535163b5aa13f47292449394e3f79c218d8151a583d0cb9b1f2627bd49df3e79f47c18ef0713d58fa8fef8a886ab11904077c01992f0541364843721c48abf116e19c4da80cbff9613e7e41397b2f0513355891a6c82efb9ac7a762d1ce5cf0cc7de95a2c0e0ef3ee4a933656e7ac25908987fc5110e30bc8e85d30faa2b69919e4f1dc0a367a03a22b08b993a35a494d99583602d913d10bc61cf12f4c84e3b0cb1aa6eb83fd9c1770f036bd706ad927f592396f59506a5c95d6643339b8ab39e0005a61ea31a1cd9427869940ff882765512d921ef18f3e87f82c461baa7044a11bf419e80ae2f5383560707c63c199fcb9e96b673ac12cd0ccab45249c5e3679d6bab0d11096469c5da63c10d8adbc28c25a70b430b53075e17861eae0ebe26dcd08b2857f2656d894ed4cb0add00f7528bdf333a03a24a6e595c15a361ccce2b7996b2a81efd0afdb50c351cdcb2a039b2bc3321039e5723214e76fa9f5be9cea908d1456b4aa0913534b231b6fce81b14f5fe19f53ed3eba95f1aa283397cdea90c403a06d2310684e13b956be29d084f960701d92796bec60019ebd9801504d04e7c1da44ea7a130ce50c1a55cb261d40b3202cf845bd74d6d543b71852127bd5803225a0096eedb2863ae47e7727d1726ff1958b04c246730876cf93302df689cb58825f21aed683f526a9cdcafe229db5a312558f8952b128995e15212e53849b9ff507505cb0260bcf6bf5eadc540431ca33520b21bcac828ec0dc00872949cdcb513e0cbaf3c649a252af75d775dd9de841329cdaa689d0a45afd6c689972f34212629448acae30a91136f0e7136f88868e1514564bb3946442b1047742eff11efd1351252289a04da84a884e8bc5be248a506a164a3a4cc71ec0b78424fecdb7032d48ba0e1b75c9cef4286ce7ade2b2b28c446e9b13a7a5a42e2789337fca78dc9b24690a4712367b08732645d8c1f07c32badf1c978751238e4865725c6badd8871b76d7060d79047b18b36de69daf89eae0de35fb409e344ed006923f8a5631138199262e1a2d872358069741d009f88ff7c205d2b99abc0c425cbff51330d3706bc8d67f888c8dbc87b60098cf66a768f0c53d1e4f1579ef46bb2e926f26e41f555a453d552c740a237deaaddda2fce1b34a1f6701f0e4f48b018072435372991942332b45de8007ad274c78d7e099865e2f16d1211f925bf004254a10ce701a05d4548fc4b0f5dc3f5ac14b689f630ff65eec42da10f1f0d32eaaf3ed6ef145ed1328398f8e8d1872af641c3efd03983e5caf6e7292eda8d15a3053fc136c7901d2409988ba78ec6197b3b6906d9759aa5f201f76bd9cbd5619a4f122dc92f774af532abc5b0aaab2f0507803c5809f126f8b23707a5cc26a08c1f8da8b26d149ac3fa4a79928807ff333368f9edbbaddce288319abe4616c611b01563802847e9abe3a346d0a993d6d03a6771e90a8cbbb8c6b0deecf1917a3c9307e12db9abaa20b4d5d4c6d9c284fa8720dc76a99e03f210eb7e7b2e100a7e2ccef3df59d7eceb5b2b3f39f91d88ce206612e5cb0165a359e070efdfd6372b996a10b109f3dbf39b43260057ec9dba8b6c8d9d1e394936ab2e21e96d6d5b442089d47b42550de52df71e8b73b82cb830b12210eb62372e56ede66c38dd56a76c244eff080a10291ae63f55f568fcd89e4a3b1d14a0ca38c0e4a4aa1d0e2c72958ab15afb84bf5ccfd8707f4969a7bc3753e7f3bfbe7cda39c25bd59e7f15d1e03362cf9648a27cbf3d4c190e219f25101673832260114c99c2906b7b7afbfac36b18251217c7a439d971f20f03e09bc4c2b83680ce484de08d239f9c64d23820c96de5f001e7f653d6ed5714e591cce005647774574b778f9b93a3965092266bc3351af632a11630a4dba519aff92e3d8e0e3786ddcb17e1ed5d7d227dc62e174e576bf3840e42e478af666222ef42d4a45349b4ddc4d68e825905e9089449ce255dc3205db619cb140d05817390ff533ae73752cea71eb554ac022327039858bdabcac92353922b6f7872e96286e55f7e769cfa111104b8205b3f27bc8720858b9a0000008f5ecb4e50ab660a49f52f008d6fe07d6923cbc7adef8d4b298fe9c737fa601bbf4e48895d2cba3095db4f1be587afa951f0e6d69948828de7aced2cbdf5a6543621d77716b4be7115b6b5e2efe1dd8aa463dd2c3a1db01b3e9409ebdee8e832de81c047d49cb035db35b4b02253f31a307c26a4f9993653682537cff1554de6b161ad278d39c9a156d8a491c8db5750692fc5560186b48106a8c257e6a7937e98a669632191cff8f647db764ddc20a3568e42f12bf7d83d20af9c6e15fbe5e65b056bf52216d5f61617da5eae90d6b32fefe0aaecd318f44a388f903333e19c432bd494e4e193f5852b8921b6ab249903e15ec31271ed62f3eb0852618ebd856d3229355ae5c3a2395756b3688663ca8ea0383d5c810c4c90b704983576eb382375392adcbab21799fec542e872aad8d97cc13953132cf77ab2a8e2ce5f3aed1219ad7201a577171a64dc2371d779d85b56a2e6f778bc11d208f67445fd33e5a008fbf54658c66191b7d7a9cf0c145fcce97928a2f36ceb5de11a39aa3330eaf93753e229563c88044cbbb3b01bb05ef5283d29f9624115b2345c04179d342d52f848bc214bc8dac651254681c9bbc98104f6bad713daba8505696d3bacb51a580fb41edd12075681986c070bff1f4f497eb014c15320090e025407921f8a4fdd924334cbb22d129f0597bdd53cfcd735182c135676f45982ddf8d8a1dd832111352ca489b30f4128de1481f09f21c2c044ddb55f42e6a74490d32c175dbe19cc3aaf0526434608ffa42eb5582414b4e15e8b38c56aad508a905788934fac28be296bc9353e1826cb939b01ec568f97e0dcac90124a26714f5ddb147d0f3d28af552a10801e19b377a6de121db63dd1b5da4765604e984c11b3beaf7e6e359a7bf520e88149d7cac9f3e656ba2a3ecbc168f8c888c31d722d3a6aa5bf31bb97426ab034f6339b824f2823b2a2244d08685b61110377d433752d097fcb50901a1c4c1ea99b844908e51693f6b0a6263dea32c8cdf3bf3433f0215105dfd6d9e52e3d41de3f1f55ee10fc7dd2ead694284ca5d9abdf2bc9e410832850740ce9e92eb1db5e6ed5a922381a5929d104c77d874d2197f030b58c271b592de14ad853185a3033d71089b5d82175cb042e6ca6b6b8ca010a005a249481bb0bc6a237f2a298abe74bd88aa0153a9254f5a938c1eee0b60832d730d9c9a0a0549f0a6c7ca658f19d64b7c9160af25173d6256a73f2ad72ee4d99a8cf11e8aa553ab66937b05798a91d9c06b149942a60d86bbdc5a53895f5e21166a892da4ba1a9a52bd46cd1018614d63398e06f63f5034b34f9f6b79e008615d092b02cf917256c3b9b8d6dba07238fe567bb70029bcfba7ba2fa2eb84d4a8858dee4e5a4c14172abdd9b6da020bfad74c5729653063a611b27ea4c8d900008c7565711ce5aae7b10189449136c6b9096797e3a97fa1e581df8fb68ba2f2170358bd688c485fd39778774218f11d4db634818b5e807385e73d7d6c50d19f6711f622891d4acc93ee38044e283f2b182ee09e1d0b44fc5108a59a4028e8971613918f4033d5dc9c66f67f98b670684a48e8e9118c20a50d1c63ccbf65937ea8d9d64deb6dc9f106d4b3e8f8167ffc214f985c8a265ab195ac2e8b438d628176749a21b15f9310f441aa9d3983d54737bf7e03ca4e78780c03f1ad481c782b31ff76fad990ae3b92f93eeefc9d35b27c617f578c2625281e244a1164011bdab32a8e5b400c1b365a585f4da943f80c8e045a72ea4accf4ac9219f8b8aab645fb4a8655b1e49c1473bd0c560c474c3c3ccdc57a38fb12238df2bc87019839eb59b2b6f97a6c8e249c6bd13ca0da487921675a3239157e672c357be7dfc6b68ba7e501d69d650f6a854a8a9820a4b58c3b78b852d5223e74680ed493a105f18e4e62966629481e95022f420140510258268e15491b761f8ddf496fc62f2402a2478011a2cf3180513ea59970398ce545fdb14ef2529ffb774623a560e9333ec73c04c472247c127d65ec0281b59d82747cc7504def59c45bf9c0ff6cf4bed95bc5599db363c20bba9d3bdf0c19506e613763ba01aed189a4fda0a6d4286a0656813b36eabc09734f4a52f3ba7466db27e5d69c97002966c2fb549db6d54dd002c617db6827955ac03cd78180739f0cc6d4e40e4cad021be80bc7e350ad525cd13494c8b642976f462704ea59122d4927d17308b580cb3dcab4bbd47484123f8561c9011510c04e307d1ff366bb6ebb54df33346c563656a9200a138e5ad040631f30d94b60c2ef61486a3e3376b52b92901e10146777b1d477cb5bda650abc0ea5e3e39082c3746d139417c460d29701594491a8246fa5813ac0299155f4ae1e9eae0f4ab51ece8e2131f32d9c5b1261df3e1753e58ef2a055e3291d8dca559f4ddca447f590a450ad747a229730dacc43b6d40debcb5641629c796ca62c2855912a4c18f6ae1bd84a420a94a5a8186f3464bcfce700d1ce97de895bbf335cc95a7bb71746564fd2c53e9148c5a41d90d0ae44ed0cca084d72388faf7efb543d7d6a620558e6e500a37917826ce37932996476563c2a5841574d02f1b7783464bd2b41b80224f26094d7f54e3aa40c9bed2510694482066c7c1377418da5192ee8e0d38710c1f28e9fbb848f9d98c7465a6d3ef52a2aace09e617431c81cdff368834d54d63e307e365594420addbaa978c827bb1c657b9568b5ea5078df3e73453af9cb24f7e18ba5d2908b91b0446f84d62a5f5300a9027435cf33b1abd549cd2eba0304388e2ff95d9f01a25e720332dfec20f82ac0b703bf90f77f8ffc340a0c582916df2ec2609a0ec875bdd67e9af0aeab87952027740cc262703b4d55d3cfc4052ac661065daafe29a7d430a2f83d23154664fced00e5a9c81eeeeba4e043e9ff077b95726f098c6def77bbfd78f207f059a5ec233280a132da5af17e590805cad5efdb628b1f319b016332840fa9556699941a5d076cc998ef2dbe57fa29e29027eb85426099958546d2b112bd6a931da8095ab25ec4139ffd59579f4121a5e4376bcddb6fcd7c916267e9e90469f3835f4a88e48b02a0a79a7d920c9ca8f7df63f470daf5a0d5e45130dda5107a181d4095e4df48e68b0d3a2dc6c1ab1e726ec789fe449193eab0c300ac5adfbce0970f916fda8542f9b4fbc6982b5c5417d1182262c4705d584587f63f1c7ad7228d70a139eff5de97867a6b8e78da9052923c5e4ae4967f027165f4cdc438381d9e86d11502cd2e9392bc25b9dccd5465dde24e900b38867b75e801f48fc59bb5fe5e3fd4a2258eb032f1c80976d1e0cce149415c83fc07e41c8328e9e2758012a380a02b7b01262937dce41848af679b9e1c0c8f75ec68bddbd6e421bc449e6c0f49af4450eeac5f3d425206d01ca0917b8177b2219ffc811bd77025fe28802bdfdfd922a0326cea902e57ab606370415a05560b818024069801543191188f634ef8ee0e662e65c2a047315a3b2bfa52816a693877efdb78a5f87721eb9286821c02ad87db746fc1e538fe2ed6830723fdeb165aa88e10c44db1a9f8abf33f8769433e6d5295796a908036238c9c37047e800a6d1b1e297d67ecb09b640f56bc4b526ea1e9bacf7d51eb2604a1ef269488ee0c940bd73ad5f94ee69a7af7a1b8ac2578ec5f349141875dba4cc1a45d2809fb16e391eacc36642b516e4fa6a919ee9098f77da937b19581c8dbc23b08bc37a9e4eb30d4875300577aaa83f2e8ddce707b80678e4293fcf4a5c38d8f48a10bbdfa9673bd283bde7c095d7828a885a74f272f6c725d639477f3fc1c225d137efec2d6ce6dce8e7dd5ff4112f7ca325851ab17aefdb8f193fd90b4f1eccf7d0b3f97553066a8b7dd96e762f57d6f88738e1a253abb20696748b0a3d6bb842f56a2abe87e2a2d74684f6a624dd5c341df2c3a84da8afc4d153024167fcfa0e9e5e190adf483a1b66feea67d8cbe16f5d996f58e7ba875fbd765e8cf7125cbcf96a5e16dc2b10b1c5457aa3ddab0e1d8ce3d2ada9c2cee280289033efb110b391819c3f648f6e2a18dd381b747929804fa426ee7308141177435788e13dde458a4c82fa2ae182252c35ce8c4e0531dd24a4fd6710d51f61c66522019c529efd0401dec1e381c6b61863e9d02c60735cc361b7b9526e727b56b2b05394aaf4fe2fa1442942eededae79d87e9f7664df8beddc871ceb91e7f35dcf0d7d8e8ae4a114706d5a73a79f8d67da370566b2903c536fb0ae1aaf0c3d4ae472401abb7d314af7bc4b0cfa10a2812350aeb71e3366f8df18394192d40ed6ab4000d6f2ce15203a003e865ae18d5dca707d0debf6a3f6b2d3cc30f026c6b03ea5f027a5a30d0324e072aeb105c73e08ba0650d7c03b953252ba7c27bb097f7d60438f803db72d829ce7b65b700727341787bef3b0800d1f089011082878b3b7493d7c1f9037a28c01e70edfdbf498ae5e9343e0a35b2f7de724b996492297a07b0079007b7dbbcd38abb6ce2a506eb9fe411093a581d42582161b5a194c9c03bdbd717225df247b2ead7982facf6939df867020951f9235d52d6acfab5da5a4f1bea93480dd63f7d52d660fd6d258f78b048527674da4edb277fecfc6f0c2cb7be573f6c6d9f94f14dfd9e26c3ca0fa5ecd6a73fb2566b99fecc1bfee557ed48b21cef06fbe0892c9490814486900830d07715ac3f75ff1dec8ea4f885ff777baa1d20dedad3f4b2a9003fe7d315c71ae812ddc7ed4278ad4e7fe5318ffc8ed6552a6be9577faf416fea369de3f67a61165ffad50050c03007b786e96040d132069631827680e9b225061629d912a4458962d18416a0190ca95077c0acf65d6da2c8533f9ff5142e8626b5af89e4d753f08dbf0cecb2e7514a5b7ab77ef3ac2d639da141def9893cf3f359ecd103efd4cfc5e01b174284cfa6cfa44b5b7225f7e24b0e66c22692f9c33b75c63bf13d0b9f3ed513711fda586b512a9f3f43589f4d24bdd420cc5b3998957b69d0bf57aed4a0fb4cb2d4e0bed0c6270f0cfacfea377ff8c69f4792192dc94af22456fb424ed290ea8fd710bc3ff2c79ffd6772f54118db3fd3d2a0cfa9adba5a6bad957e3e6bd0bfa76b74b0a1cf7cd62eef1c22f799bb7b521ddaa28b5f8006e30361e61300f9122fb147231196e3327313308fd954348a128b6c7777d74a780a51ecf64c7f0a977927c78d401fe016ba433891c191d28df7d9b048415ddcf85996929c48d8595c458848570ce2a5f61214c433a0f845a44af585dd0490c7202983827e7870e510ec427d6c20d4279796be8d3066fd312848d2a4b934c5d012edd0c84c90eecacb5f48c3eda7210649170a15bf88447db108091098fb0dc522be898f652908cc52e77416524a391489aabc1b7148bafa0331b6d00b7e00f14dfc0763ebe52953285d14ea33b2815e6d705b86c43b5db04be6e3d464beeafc158980c437b1bbf8420913a1bfdcd868dcd865dc089485dfb0611715b5518c60524baccb535490e4c61bc6a55be4ddb04578a73f3e06d8d555644b377eb161cb6e7cc9ff51d68207b7bf96f1cd920d1b08f5b1bba03e1c1c1b9b9a2ff2a7bd4e5fcb24ab0d1bf68e21a22473f6c4d10d1b8bd294147020728cf547173be5f2941478b9de4840535810bbf17663f1c276fd6c58daddd3e4c31ec4344089a258d439fc0d24a391f338934f775a2eaf64ae9b82f087938fa460e3f26ade683200bf7fdc410dc6066a302a61c4538896dc78c306329910c0dfdf9f031a8c6f9aa185befd41fcf66d17f826bebb472694a613487cca0f141e675434505433ccb276719216bf393c650727b1bddc5e923096bd6a00099a082ad23933a04d2be99cfaa4a8812ed8c9a2791bb04413bcd3dfcc0ffa35375dbe659295420aec4cbf097766c8e9514b845ea78f79c434408923329c1b16c87ad64932a4b8a4734cb8718a0e586ec846ac1e49aac773ce3927f3f4ef912bffea673b08c3f2a78c2cff8e99e52f4704b63da6014a20f1f1c94461f9439c5bfbf351a39f38c92f7eb51f094907a9c5a0ec1fc9fa912ec924b2fa6b8d3f3fb71db69245921591225244aad261b72b6c072b8b3c34487b22f8269445b7a99095db4f83224f4da244f04ee5c237df57dcb02ba24231c9e2a230ab28ec6860c6cfc00b59b7c6edce74c5ed9a14793838b80717dee1c280e141860d3930b79f8b4957d76aad4af5df4acdc56ebf3c013bc139fefd5205ecea8a248b49e4a94ab1476fa1924cfabb8885593156e11e319671635774db4a1a3b6056be229554584661b0bf2b922e698595228f2c9a6d71db0b99cca22ac925bee9a74950261f159245f3432ac4b24ff4956ab556a5fa07c1b0956070c3e8050557168ffa7502327dd1714d0d1444d818eff4a53e3384fef69bb69a19a259c98a7c8ae106fb9bf9c154aa985140d5e873cf2f6e53f7f70a06f9cd04e90f86392fc054aa50924657ae98ca0b62b75732b0d18c02bca74f3f1bb8ba9a5100d59ebad0bdf6cd0cd1b6d7e8e702c73dfd66ea67a43ef5be1e922c2e96ae5e5bbd387ed515bfb4170962c4e23752fc8e7551cf1c8eaebfebfcc38e16e649b202f14dfd40156ae3f610b73f6a4a92d5a75b93c47a927469495a12df546d49fbc23c1c1a71c529bdc12e4e0d66f5b75a238c0002083333396ec8859ad20f1e63d8988c23ea15826ebf06d2a46a8978e7749bb3ddcfedaf1f97e43f58ffb16175e2f68733c6255525e9aa56d8d5c964bc53857986d8c5115527b6c8ec0cbcb85d6463b73fa2dbb06ebed8d48207d970c66e7b2dab2cf2c8af63b18716bc13bf8601dff437086b10dd06399974b515ccea8f52addcee64b7bb2d0998ab8ef14dbfafba0aeed1cf638b951f6a489e348371b06d265dad1608fe871c8c8355bacde636bbfdf347b29ac90d55d7868ca421ddfe2e21b0aee4491fff84306ce849f632150fd4e0b6d591ae0abb1dabb23abfb05a1b3fd9edfaf54cb21a0c1b7ad2ed564abafdf283309e9035a26304d889d3edeeee2ee587737ead06a3fcbf42a48b032d90ace45085062708a34305521041c5921ea800e21261c3eed28577fac6efe9be9921de09f547668674a623aff8a8551771b121c7b846616d6a74b0612bb459cd74b73af2ea5a6948f7de67c434c4fbd367e4f4de7730d45d3aa795da75b95c2e4b0db2095a6c6841538d0a6c175c38b9f31fe907198801764e0455e12566bd5400e4572b8325b6d0e2190d2ed600a203961b42f55c8756b861ea48a9660b25b7bf5554f01577042b63f411ecf6d115b73fea40b192c4ed965590ca282ae367753be6f716665ae0db5fc832e250a5282929a988471659968d8d2aa7216455c064523861c5e880090b2294951fbc2844a718105d11135394147880cb22e62de1c386c54ff753af48e2a21cf1a3256d519200417d624054b3682388e903858996c51610b8cf1540348ba30f489f2748330b2b3ed03e45489e05143f449f2c96248b6b164900f96031932cae1d3889b2f484bb61090a254b4d684e96823ab86c144607293a2b1d50b5d82eaa236bf484a686fad0525d378b93f228c342bb5868567c23a3a3232c585e68d70bcd8a8f836363e379a9140d8a53881f96709915fffa17ce70e5a75d89b22a724861438fae200470f97d9cc086aea259e1f2e7c8c23b333fe28d7ce383672786875a93c2e55741884d8773fd84c0459773f97998f05030556b55aa7f106ce9e05cfe1f810debe984cbafc20fca047e9711312d253674991e97ff8f6c587390f0a4832b36f4d44d110f2e6ce87703fe12a0e0803f754507fc519bd7e5eda647b55378e446d693e10128b443850e11629014fe0da8b0343c2e3f8f1300a0e603102293bbc68eafe804247e75f95d29b0615dbd6cc71adf0e594d096ce820d8948ae66b3eb8fc3c4f0070795c7e1f2fb0a18730b3b4c48655041d46bf830d1df440a6021b56966af6847fc84f8c9a1569685229cfeb46d819c386d56603259e2e6e78cc48e051d46387096ce8377e0fa00436f41206b0c504d4093e927054ff20d86ae90c00054f470f286c0e4d151bba8b93b5603a3a77a543bfac78bbd8e6ee20b2a1f3783e64d050c1ab2d250f2856f0aa74b14abe046f4d1036ac37aea0820f9e9d14745c3928e09c00c2b712c076e517dad02dc29254c4a9261f9f3e9fd971620f109439def3b7bace6b75771d90d8830b6b2e78bbe7af958633f9d46dd559295736b147fc4ef3bcce99b21d6c58af4193cfe4366ee336fadb17ce1ff335f9d37f7e354c02ec0813268c573ed2c5ae055d19b7432501dd1afac789b9dc0ec559faf203ba4ebafc808aa533c43058aebbfbb89d4f39a5a4384e2975774f793fb9353789b6942f34283b562157b5aa54ddcd7ee517ce70fb8b31eab8268cb1a54faad58deb64b68d487555daaa7e1c2f5d5c3d3e849ad5afc2a9a1a81b854478a2ab7f55a3b427169b3944a8fc82ca87c5b9359d0a043bd3d5c81ef1b3c04f85e8742d0a4d219e452121132a855b022b0a45de180685f9ef0b097df4ebf45a6b8e5a63074ad07022e1f2e7ee2f594168a021dcf8d130d3354cefb0bbab64f18c6f974d431c061b1261b0d77c8f7990f892865e1a6a9852fe58afde37628cd1a93625fddc9d793ae2c41e2ca5045f4a29a1d8f89a4e2bf471b92390d8a37930018a6d9e8e36b147943cc855f857bafb6429a534b9d17535cc8ebb5797d549e92e5d47de30a16970bb5eaf76e7ed47492836fe4c90286f7f10bff28647aebcd2b225d52ad745198ae338a79db681a10b5bdd6a913b9fddc8a45e8d67fa97315da53e3dd3a62dd1f529d7fdedaeb6ddba7541a6a9721eb7d1a854d5522a437d6a1bd72d617de827f353eb47ae7ee55c039706991cfbb47d5c59a0a91e2e6db8328894c9e1b14bd9c33748accc99b05eed22c774697a02e8b6f65dcb9654ab5c67f24ef3511ed38ae3eeb5c8d598ddf3d9d574a67fee412091473eabb6168e8e8f1e165aa09c44fe725cb7551a954a43ed8059972e148d4de491f2d28a5a9d56427a24ab04323bd8e8ad2683dbf63e2383db6ba6207ebbedfd0b35a099824c8e7de2ea0a4883bd62a1c14ed92bb6877b5f3a7d748e77325e8e1c261ffa26edeb718f74c54203e959010ceb551f9d432f7fe7a726aaab6ccb4e59414765669231394518151a5c1e8772e7a422c41418a8ec8a6f586363c4458a0f574a8972e514218c94b4ec94f97c6f731648aa671fb4aa16121dfb7c36116005c37ca74dbf19207ce9b7c097f617cebf40bc3ddd1f37d8ad3f4dde025fd37b1d9f3efcfebb556f5bf17dded99ebec4d274258f9a55adf04dfd10041e59857bd4e7ef28655da641b7aed8453b56ba464308cdae685b568092c2bce556fac5ad748bdb84a912aa2b6c0bb846614f40d245bf82748719b63e2dea9c2b98876fa558d4da5f68ad34f9cca7da67a4497d838a21991a33d84bfbea02bab0fc1ac14a1b600cc1602f7ee120c3847935e9df3caf7e34f93c89af0d563343a811148a78d18f256b6612dd4a9fcec80f27933b878c441ed828020a356a18555e4db83ff2ea17bf98af30428b11bc8c6ca08bf26a82fa0d502cb05713ee438b4211af507559a973ac97ce8991b2339ab8f5a912467010329a742b1d9295c8c66eb5c2a1f4e25639835ba519b7fecc8f94995c32fde17e6884b0393e94b16af9156764e80fef80b73e4dc23bf3ebd3279d13f3f569ac03ec9a48925583b864dcfa215d224493689174b534d8ad74e956aa742b9d51242abb4f896e8df14dfd89245db38a29236342b97522c97c09e817fda69064ad4ed77fb0e144f21c6c38856ead3f857827defa130976b59855bf5626ec13b7b2e0d69e2bac0492ac5a7fe687ba03664d377c17b4a74092559f4d0aa04f7f3c894c763b926c475387d48480d3872ef3bcb385b199a185fa414e9fff0e2e36bed79731f0c67c354983f6f39f5517524af981ce03348e74ad2bfde5af645575773ceae9e9e99ce8e25a3ad55a958a5bbdd0ac466286a4b260d8f81a5dc2043088c4623322b3d90ce62d9790d3b5f6afb4654b9937bd347d27b3ea62d6daee6d0157501f738a399dbe47da95af422f2563f27ead76edfa55c0267e206a8a7f48a3b2f1cf6b3a27856a4aa5eb3a9e7576b27b96afc3bf9ac458832e5980b2b9a8ef52f11110bfae8b5efd233e32dfc5fe2357ca5ec5e4b039b655d8b36bbf477a3fbc477d71fe696553610c36b7fb2a6073b9f931d6ad916c5af5dbe686436e7f15b0b9f183a17efd5058d890461583cdad0d469acf6b3a67daa65e68a0040d26684091f221d3a50930b2986a39affab36a0b1916d7e975c19f88e71fba2765f4c00c27eeb551c73591b9ebee6ee69e3bf56b8df541abe2648c2a53f7d16000ed5968b07ebc950411dc7c61432b13860d63485dfacdf8f305d2609cf1f7eb5f0f0b24c41ef4b62dc68318f357888cdf0384675a11662c51411497a598d184ede0744619513029e374540650921b2188258da1e4471cb3a429412dc080925ef0c34f521340fc0853748615e1b2d11b56783f6f98e08d378030617923071514e05b2965abacb79e7ebfe867c486d7fc66bec4af778e7cee8f20d86af58dd73bb618224061e3f3d3a9cd3aa7a53a1dadeaab6429979819d2affe7ef567c486d70662d330624bcf05950ca9566b55aa7f5e2a225929b08d14978a2c2d2df1cfd7eb7bbe78687a116e2dbfe5c79225df243baaa0e3f1604bd55cfc4b1e6c7c2965757797746ab3ce095aaaea8e2a7667fab12a3a7bf58167fc5e56adaeac56eb8a41e7d10039e79c105835a573ceb9f2b9a58bf2ff06eb3e9932bf8ac107b96567adaf520579da31979fc857a756929628395162c233615772fff08e8f2b9db8f285b45a20f82fa59452461985e43793807eb1f41f6cd83f9109131e2536be1c927f4218dbb2d6f8fd4cd85052122525180852c848e20c2d6714c5608a4bca184ece5052839900b6106dd1e2b2942d45392ea7438bac06301a0859293348eaa2c40c558b01a6bbbba3e3cc208994527e94ddb1e52b5125044b97abe8e0e47670b98a0e24b86962fb7f34b12c250b1327a48780c5f6ff30819234223aea4e860a5bb905441f7c615b46a25a7313c5c66729599870395060594a962459926c35042f9494349a838ca3a3e96358ed59ca8c48f68a724fb767cad595576911fac9608448ec65fae717f8decaf4d1c4801db197e9ff7e33f4e3cbfb8cc497f7deca0ee19bb90309beb58606271fdd39a473b69f5f57321469703e4e143b539f5fde87dcc269d96074e568e8862c5dd2982fc3fc22f3ebca5bdd18e9cc97a10812d6010dce8fd785068734389f8425f6071396a5cc965cfaac74672b044dba0021b4c31470bce6111750390119606480431a485ef36528f25a8d2166a1cf40272d3aae095946537d748e9b20082437dcf82c3f7584175f668b0debad35729fee8f0d7ddc9806942437dc18e5ca2ff41b02cc86b509bfc7fe9925e1b2c425e98a3092e042c4e587830eb4e0862d4a026b9ba07cb0a7cb52c038a26a0103488d2fc268707ca1f445921148324b7e505d10c5d49615a024a76aab67ad951c7c3081c104555b6078f0aaad9e2d3ad5a0c392649a810f5c1844de151e362c439d16b21e2a18491c0c34d8565b5a0c8180565b3debd305901623f080174b5a0cc1c395580f7236ab84016a9f2f9878ab5649a303b1a5d3c2d10923a94a520f3e57603a94d0a8b841c484c30d1f9480a303677cf1250b85e28bac872f55783b58d365a32f50988ab0de65a32f4c8cf8e99877a6cb8e2ce6b9859c326e33b6a6b5a431b57dc66c76d3316b3e4ea6f3397cade5532ec6f9dcdf1d799ae328a5f2b79f5fe55e7627f9b54aee2bc7750b6784cbf2ac6aee6cafc3f2b1adfcca11e66fabbe3a4c3e717a334e9c6ab3ade28d3675be0eebc60747003d9b524d95ecab63a23c2be98a1b748d53aa79e3d76820ff0e36ac3768f2d1982b3d9928572d7e54b299d27531c6d81f5d767bb7b79c73b6a6fd0e9eb335aab59452aedc5d4a29fb677ff789f9664341175b7ad2dda79c94f66f31ff3d1e54962d61d5f3ffb19e582c46ef16f32e7e4d47eae158cf29055db4d5db5677cf3273f5e9c5150ddcad61ae706c6c75cd1b8ca9eef66ad5ea1119b72d556b3add25f539e77c8f3d289d734e977d8384f52879b841a272c5a19b9aec5a3d6e1c7ceeeed6ddebd712c5b6a2382ab95bfe06b7573836a895c7c1e7ee6eddbd7e1eafdf0edd3d15dd3dfceefcb6d8831ff5456c9f54ca23a856b5bad1d4b66ddcac5ce7521ed1bd4ba733cad7fa8506fd23e2d5ea799ea98f90479852b313ca33f9d04711f1f8e688d3b6810762f3d4b6d4a66d1c4d711cd7cd4d761cc7ab7410891288aeedb72fd5acc881ed431ddc8732d1d5f1acab95b3f6fb54caf366703ecdc0a51f2f7f471e4d7a8ff93ceba5df0b0d12e14c2653e4893cbd237d6ab5152b721169a73a139829793a997ce89f4c2d441eaed191ace620157bb49c1189a153912702dc63027cd3cf11d9a41c4a4dd16939f87126832a3111869423072d7ee0be88014a298c484b9b946dabb99bcddd70ae5871372ceeb679d1c3ddbce0e26e5890b81b1633eef6ad2fa8d0b10206575881d4e56aafeac289abfd7781c6d51ebc22c5d59e9198686d280e69eeac4dee7cab0afd9d4eab7ed37d4e37e25cc78e69532491c30d28206ccce52948949ca03f28012205e806243e18cd924c8179016214932cae35aa7a13f2d2c31a376cd51c7a48aab92c0548a684d21618a7cb49f3313539c01c746a74524a3353a909e6b091fbf82d30c7a7543473fb989a9a03cc4135934fa594564aa3a56a4a559f26a6a5026d8e0f265702e7f824492bb91d1be8f637926ed852d472fbe3ecc37844149934711b056bdc7e57f551f534e2b8a7cb3d49717c5142850a07da7889c00723b86082890c865e212f096539020b25652059c18be872d7049f4df54892dcaf58aea63dadaa19336c98ba38087155b8b5062bb882821814918396315eb37671fd2b18d73990c3951d745b9c165d835cd379cff4fd3a6159022900ad016d3a0788912643b8f7bccf4893b073cf033223847b057000c61338248509f3ea9e4d423cd05b01912cfadd4a8864d1e7564836350dca0f6b9c881c928875f50d52fa4e7da460c39a4bb948880b9d13a62e7d3ae50626973e5880cea9522e9535971a71d1a5461788f53b3ff4716911396889c14d710df5a620d0e286901b402dd9ecf1c69e1ad8d07dbe569b230dfe3f64c6ee9abe01c3474b48a004174b3088428d2522800349113994800b281de88210def1e0c61fd23d62d8fef8c3aeddda77ce91061f22c3e2499e91fb244488fcd76930ce06636bdb0fed690ce07539ebed1518a3eb3418715ebafc4a27810cfb3724129f02f185b820334999023b5a9aa150d986997d19fa023b414a1c4a4b4eda58ca1107ac8da33686627000b5016363078c50d4a8f4b986ec7a91ddf8cda081b91fbf500357e39bd6ea0adc16e36fab1a5f8b9aa6691fb518b5c8a30d2fc11b436a785123a88a296ec4d2f0928609f52493f2250a2828987d59c21bc2cecb52be8cc00921296a9d6b8ca1448aa435a40cd14214b335888268418a208d4bad6204d10d3e986056e6b214d89737ca7802f3e20698110d604e007059cacf08c6e874745aadfe5663462da22275a945aac91ba94569d4e413b54823952e439b8b9239adf8f44ad407557b29e79453a55969b554a531ddf8281a7dc6a8624fa86359b5f959b7282b59dceeeeee5d5df226822eb6f44935e915e4d6b3af687f9c2e9d4eae1bc7ccecfcd38cd8cc2ca594cc3c254b96acd38a2a29a58d74fa63604a19e52764fae6a5e39a6766a63fdd5d08f77c8734ecd5bdad3ff5c5fdb642a283ce8bfbeaffd457f769db73ab1f9dd7f6dd0a890ef5b5fd8fce8bfb6e7aef777ea779cccc751bb0eae4b9f53a87993b8799399ecf93ab698635d30c7f422a77bcc1f5ef6238553ee7b41d75975f5864fbaac9d50c284fae505e342140bb1640cda05df9c1403feba619d79e9a66fc5592d5d7b6ac0f2133334b8fd3dddda794b24d20a37583848d33ca5558dddd9d55df69a75093e2ca952b57fc08bf72e5ca952b577c7a187ec4bc72c58830ae685e624b9f54ab9ba604086849500cdab8287f3a67caf9c4e8088b93e8a40619948c1469b07fa9f3fc0522b3182860f286089139c0052493a985be53828fbafcaab62913f344a2d8a37f3ebfd79930e356f14983b1581489224f6c01f7e8af4c6ebf809b5f74c24201809c3ac7fbbf4f9c3801c2499dd53c4adbce88959564377efce2430737f4a1a52e957127164b3c5c59e77556bab28b1ac718a621da8032755cd0060942b8fe4eb3448c83c7ad4f6c4aa5c3445c9beb52d888c1b54cd8586df56c8eff1a6e543b59b006933488d27892e31ed3d4b8aa8d4ac60fece2b0114b83fdf18b474a1ccd4e107fe24f048a4a62109df9c246a0f8f3383bd8f9331cb061bdfff3854857ff52d285998186521a4ad050b2628a92111a4868c460e036004d4f87d70f437ffd208c8d5e0cade4575aebd56b2529a4a4ddde1605b69c9f6d50a6fa6377cb084a5b9e45c95a552a5abf185a373ed3185afe02efe83528a57b4e844af776c597f6b9eb6cf531b0513a37b07e2f59d191a01bfdbc383fd255eadb9f76b72ad539dbb66ddc17d6af5d3f8dfb3602a02e7d6dc5dd946d2a9c9f8a1a592fe5a5ac974a799ef5525eca6547a193dd79fbd6141bfa95d2e4bd7fe1f4f9ded4e6b7ad425e5a795e397643bf1cbb3310b9f463b1fb156c8197dfbd56aee991eb5f18af7f335ce5f216fdad723af99fa6c1204bd69b73cee9abbf4b68642d66b9fc520da74fa96bab70bafbfc62885992dafb0536ac5fb5357ed673b7b536f5e9ed5222d15c2607ebd1f37468ab147dff3cac9b6b6fa5e68a2fe7ded2d59fc2f277dd92dd237f514a39b5e8f5e94a01020813264c9857653056279d82ba1b6143ffd9b1da6aab9455def99e7cdbd57e3e85c6eff1f3f8dae73598f2d4aa8649e3eeee85ccf5d82da1245a2fe5d9cee170031caccc0dbdcbae1682c1602078c92266318f018664dc83af018662cce2cb2c1327a36143ef77fcf4e932966e456b8a4bad32333fb3d7402f3f73cfb8c0c6d7bea7dd5d05276cfcda20bba459dedb5b717d296c3ff777018e78385385d42fe1467777ef58ce6dab5cd35a84fc92a3ad3dfc30c8d0baa190185a579a707de4f32a2ce132ce4521b2873a3550938ffcd85fce08d1de84db5736a77075723c14aeaf42f9ee52075b1b64e91d6bfd8c6ce0a57dce92b905d2aab90ca0cca844ad5835b974884600000093150000200c0c87844281401228baa6b80714000f738e40725e3618c9b22c465114638c3180104280010000038010111179f032272ad7d30dc4a85d28d82d75835d2672700dc863e4e5045ed2acfc291e60828033a66085312e87818d658456579b419159ebddb5f8d3f52029b4d1d9e302ecd475df130615d8d35de77c0d1afe01cd03db353abed7473a75833734be5ebfc233701b075b453a2f56c3f89fb722a17b31027bba99b61887b457f2fea995d66b897d4efe5de5ae7ee10da8d5e936da254add019a468042c8342846f51cb6c037598735c83f7720e84bf5112fdc832d537a671b20d868c0ba59906e1b8d3eafe84bc35ed968dee7fdb83002b81aac6f82355c634951152a08d1ae648fb63cc873fbfbaf66a0050a3ff6fcee639129fba0763008fe2be7b7f2e5ebc55982324120b9a4170832173f7663c923850e1b35c16c9dff452bc9a29c9818b8bb542b80b4dd1df7448c8beece0ba7221a28d756e8f41f202ea88fd741315e00c9315a47a58aa6772ae6e0ce031bd56f47019c846fe80bb026f1076eb6a34de36095e1571d0f5787d3c5f1f3ec3e01ccc0df5baf736d57cb10911a9436263122fa727c238e78461cd4fc488d8da800d1e976952dad24aeeaf052a4dbd2500342b8c1ca46cba3846b51eece9186eb3e92d7989d7ef23159a939d5faa8b9bd23b3946272f21512c32f1c087c31ce2037a2dcfbbb6bfc1ab0655e39717e5e4a8f21df092f87cb31e56dad65d4e7414d8d0967c0505ea71d281c00edfaafcda419a5faa6ed771b59076519820aa1dde1870f56083632c8e9dfe45352208c1f44ac6cd50aba9dd97ae974aea05d4a7dd74b27f29f8464d4cfb133387c8162c25c6c5f83379b95c2151d8d3d9d765b745bac732c0653579ef8fd8b9a0249a48719aac05d078da10b666977509749abe116bf803c94bd42027986a365d12b504c8402ec5d83e65075fa56ae6ba864e8504ad211a853d9c2223b279e076f43d0dbbe659b5bb51b0ea1418a3da6bee51082636a4559cabf344671089542286bb4461cb3a14a242be095b671ee2d98e1196a78688892f8dc4feae133d6cf674e579e50e75ccda623c8c1ed9167a24b7c61ab2f23a78d3ed7568c7ed4ee7caecd09917577022aa247bb52446effd8a1bf6f28834c8f38d61fbde047c24285e69586f1f1c1393d55c2342088639f2ca801caf1493bf4a9afba689e173005f41b81cd169cb6134380737cb283fa4decc733d95848762cbbf3eadd449df4d474eb60a332bed263757b3eea90e6a48326e5450fd0fe2c70a030f69160ee25699d1186579eaf9d53749caf5f13a0e5f0f22854bbd7027e7fa03bdb2888270a9a0a877ea0c3fdbf4f4f2db69f5834297abe556112d7b54018dca65a3a424738a41e8cf76bdda15a07a70359c5f5fa97d5a22aba1e5cd34ca57c9d9a3cabb2186f79cc0ba180bd0a4eb9ca7defa986bf496ed12c43be6652e219518e5a90d8ff2f7ca12d142e1d8aa4f0c5225ae1b6810d234b249ebafe41cd97dda15e3da12c34b4b0eac886203d64bc5cd50864ae05842eb1dac13124976af5596967c6d9758ede4a1699dabfd43bdc879f1e06b98c3139875563a3b8ce7ae68b5e4ed17e95436befdbd1098384469beab6058cd480cba1a14a97d6854d4ec33df31ef4cf40371edae5b9570884b8222c3af30c04cdc26eb65dc1494aba425ba3d7c4dd049af2d830903b854d01d704773385e35a28bafb0c3f32d413d0b2d6bbeab5c949ac55449ff19b2ac32ee171497c5599b7e38de96688f777bb20f24738e58878e3f579a3efd560f446bf9ef1d9e5a12177a0248a76a23cf42acf515b84951f3a049740a95075bd6ab56b6a3444478759a25f9b5ecdee550162b16250f0de61eb27c79f999b7885d24c3290b4016dc768c78e0b6b0f38b495972778c3204a2553c6d92df70d9b2154011c42193744f8a79c050faef362929afecd58e85e7c758fa617e3a3d4be997bb7756ca9984bbe3d2bc46623316bc5e23993e9da5adfd1ed77c7cdf7611e3d06156dd2dc09f6d85b3ed02e1caefb7c44561ffd7e80cef8668c2b94dc79d0395057737fd49142e36bb17f68e838323db67f21baaeebe6445444b86ae22d1dd729edde0be5aaa51cc02a1d0d476c5acd3a66d9e3f59e47b6ab96d1a88757a9745a736f8bbca8939b30c79e2ffc0ca1d3b59edf24fff430d627f56651ce8b396940dc98dc046fcab92411d0dcc77ac4f9be4f8b3da19de3304ddebb408497de0e784ad20d19c44c657ce904d9d376237ca0dff81b051be51a4fb8b3d7c204ddcf91889cc9a9d801396153795511d85f5a9be6015c140bdfd2a939abe0518ad0a3177637b26e1e4ec7741d4b7d2ecb2261a86d181e92c1847a43826d04d0f1cf2d670dcde87368e5507e03ce8ccdfeac95dd8d677403545666b510c2940ce0234f2d0626acec3130395f428983fa4b7a1be401aa608169759fa00dc8219637374a0d28466c7bd48a1422ed6351a8727aab4722d388b2243224e991c5421598328cca283cb86585e6e40dedfed6f975332e53c734c197b7726c0a47b572d59c6f7e158cda95d9bd4642ecba945f9b9a59ad0d0a49c3cf3f8ee22edb08a2823bdfc68ef26860f550703d7b38f035baea020b60f9c8651cd6cf8cd8697b91e5f0a501f77ce474df30581efaf270c37280d02d71e5ceeb209c4344301eb2eedd21aaff6774349f045395c6fce8a6dfab18800e943c4374a082e741b99bb3e731b5bef0e524b0e01430837449e05f4d7a5943719ba3a7676894513ed80267df9094bc29f82308bde8b821e6c8aa70020b569878cbec93f0d0e570e1a0d25c7291a2549b71ab6ca5305e5ac3c364a95afcc68515d3e91297b827c0d0d89255780c2611f9ed46a08e1b4b7638f716cdea3653988655d6a05e8640680d830c66f3606a497526c930621534847a43fe7fb716a68f07bbef372eb3581490fb309ca65275233201fb70449f03f571076bd9b5224c21150c608607b82b59a02bb590b54c4d8154b09338019c0a81720cfc58d3005d8ea9b893f777bd92177710f0f2e9cf21a00ec91a81589d2a1d6bbb0a2f120823f2a924517dc13aa9b0d3165890fa6af66f5d6abb5b24bf5e6458ef8d01ef09577536c0962560df46123b958f40d3ea1f5d68d7a02866aeeb279dfe203e47e4da4213c459ca7347db57c94be4f005a6e8dd64b3b66d0d10796924a4c2102ed4dc7e42ea76cd33a2f79380aaa1247877c92e1aceddcbb63b3e9d4757975ab762578af15ee68d806b0c6d64c3b60725aac531b1f84b50bcab73886b1cece7181d346ef000ce460b570c6c9e6a961d2508a2a117c75bb99eb1f70c3091717a300bbba29477e85d16c663800e73f4bbaf52b463260837362999545c5cead13fd1403ac6b3400f89aac457b454f0a49d68fa8f14585ba537fb8dec0c96e9898f6e0ce6333f4db19c9a023d9fe3f3e293804f4e72c930264482431bc57c572e331fc5342d408d6037fb4090864bd1506f5380d2010db4757e11e976cb7719f35fbd67b8698778636fd1890b7615ca4350d5f7b01d0e3070401ae24ad344b2de1a22f28ba0ec2f33358aded15c520a1f96b72c3584a30c314349f7428c75212518c4cba38d84d3b647dcf7e2d8ff5f36fe7379acb82cdef90c4e5b721bbb05e68b38889373f3f0bc1364607a3499ec2ad598fae506d55486281113dc41c02454d4e104a05200629090c7861b1a5ab84c20aec7161b6279a211ea8922913c586fb57793938bdce50d19627caf3548d3b692c3449961c1fb6ecac37582b2409e2093217d87f2d090263cd07eb3fa71262b1f4281fd50c692a90ba7fa5d222437436f40a38e35cd42e299235c2f74496aae8875169f8845fe5db02657b897209a06d4feb63a441f75e436781236c375b51addbb351f92424cb881b24712353a389f03dde13a285bae7794a4cdf518a258d86356c6ec8fabc16888e49efacf732af7c9f42e8d3d34cfc5cfef452f8d2691f536808e271613b3a46dd994fbda396541064c5607aafcfa7bbfbfb0f60518e425d9a9d43e59e5ddd859b92f7af5be14dae11b37be72c74a47da6864d01bf695dc90756bcaa22dfa552fb38f5b061152079a171ca73222381cbb68dc25d84f1f4922ce9255e07b2782289441e4d438e942c5ade5cbec105b2ec81d0629ea0c39e62f6bfce92e551ec4ceae54fa5d98af7fd74f9df207fefa7fe0ebdfefee9fdbf7c72bb8fde851eb0facff5af98cb9cb3a566bdfef5c253a3c7a00993567adcf97fabaeb63e98b3401e1c998ea5abd9218e6a6a8b5de3e820ce518a6a2a975b37e055b6676d48e5013a068a895c259e5db44c9ef6d0bc563113ee9598cc6978cdd9340ea65b3532acd080bd41baa054a58fa90aee237d87dd16c9a1a2a2ef5ec56c7774d0e60608a7d3db9f20e643563ef54bcbc69cd33e9b5be16cf77d57cd452ad911ae267f4ac495cced7a683e84bcf20db60a3a99d8181c101ba57f0f847894e947efa39e91ca726ea8f1c2c1708d906bc4970a0e54d2a082aa3056216d4db98c790c14066643dfb4dcfc3d45e8f364120a94052f393b71e58753e452941f4eea6cedcea987921c5dab15ef15e3091d34d862153c8940acc047de4a48ef44b1a13524cc540f2e269e2a942e805440909c0a86b25946d37545f30a666f81ea6c9844c3ec1af5fde1bb9fc4a567a46dcc181e68a5fd7a5dc3944f82268a234b4a684826765c9cdeda65b1cf244f159d7c572de06e3588448c924a419521e0594deccf038310755ccb44a141fcb817d98810fbd8b48a04d7518d558cd2cbb5fb0f9ff6e3846592aa6fe5e1fd86f7727d96890bca35c7c7b4d35ea34a2e0cff3879f16939fc98147690c13a9521473b1c56b048bd5e25f46cb4c06f491c9ae0dfcefc6728a8b025057422d99c81fca20b2222556eef8dfe822fe5cc78f31aea6480e2f6c3121344227ebf4abe45b1a7509a5f0a3a0339e69db2eb5eb4a068b7a26f7540cd8d3cb9a3730956bbabf8e6cbe1ad55954bb73668876819f0d2806d6bd96384dbf9181c2933bf7cebd357846cecd38c2e3d03fe4d25f44167b9d475f7dad4de280a8f6c60cccbd4ff2d3b1c4f4897eb259313f768b33e12af5f2c6a8fa4ccdeb1f84667395fa6ecaf416bfe7044fe2d932f0d9c4c6087725007291ec0b267f9a4b85069501430af0a8ff50d82ee10c3c7fc3c2d7adaefeef7e9c3b43dfc071eff1728883f98b6d4ab75804b8417a703ec88e3dc56ce70a4a3a353d6fdb8560dca2a292f16f023e69f538b029ab49fb2dd68f0e9d28895ab82e0ac6273f31e819153fe000b30a7efb8173bd73ee0e5baedf7687c9f2620c8b8b1490d724ebced8f685caba49b5a34dd2707f4c225ec2af08bc1b3399db88a9cb7cea04568f4b053aee91274ab3094833b8a1d2cc65653878c3d761c19e18528e3b4f3d2c8c01444d46ef2cdb138220b14433017648db49be4c2f1ec6b98238d2f18c2f9397178952a66f5c05a8263113a17a685576158615945b17f5bf54e80912a7a5ec5777764e4326e43b1123dab5b8dd6c4309e7725461b326a8459870f06cdf0bbf3bea237702c9c53fbc8eae0fd96cb8eba4845d13a85b73340f7c815c94511cd69c872ac48860dfd93d996be66a6b0df14ad8cc17c6011aa0880275f70acc3e0ed12d0d2abefe0a171bad3a33180a3a5585686fa7dd7ce8db7cce8a8b2e3065b1094cb6892302a54e59e5270dae48419e3962a34290f6b8924e80a41c12dd3d8e249b25bfb74697103e41bba374974a96165a6f6c18441acee4fe56bb22e6c603736b0fab4788c644dbe6b127c74ee50fbd09bc344f81f6551a7b15e08e0220c9f61303e9520ded87cbd4cb0c6e1b2097cade96d8d8ab20eea93728b004f3944f58ee4260164a707db9da1386db4579bb22291a5c53910efd1ec930c528702308e9e262c2c0c42eb4664aa80f99ef100163bd0e908f6a1710a2061a077b258f2922c1d6678ae302bf37c315ac407650332d1fd63d4463986cc784244db6807bffc6f0d5eccc294b92cde15a75831415c4892273235b19b4850ec07d23f62df4f2dd664fa453e58afb6ec06028f06b769494e31d9e83970e02c2f809441d1988c807c628e0df00e3d260ac36c392c176494d462a97015312caf7f78f75cf7f30971b397ba18a7fde05351c52b099b1cacc0c8161b74196799d6c05c85827fab33740807d5dcdb388f018ff6933f3ea49f9be7c02f5164ee6ec5b8e435e3a64065b84f69167d7288b89fb21dcaec36caf8eef2d56b6f6fd503368c7159705f013f6e9645686a79d21c32eeabf78e007fdc429882367a75b2a9dda14b93dbf16310dd080b69c59e638e8900f6aa2c9a36a50ca2a04e20bd2b243c9b7aa85aa2c160fa68394926ac9aaea90fd3d5a2bdad5443a910fdd229463ea1a35a2d8899a12a0462a124b49f6cfa027d174a8ca2b4a0dc8861ea3d732c9282c4765eec4337c07f5217aa907ad725826c12353e988e6224317965694e8632fc69f59d274c6d630554eb2b5d8b71b07786e06ded8e4ba2774de8bdca682ee43908d67d8920d55c7e9b8159e704161b4e203acd6ec8f4b44b7fb01504bf4a46dcfdae6e576a642682ed6e87ed23b74f3f15ec59ea4b351e2700653e3ac1fb352eb4b0309cb231d26f1a8681ea3aad6521343a63f07a3cabc92168ed379a9bbb5a225e28932cc198a5af57c8f0defe873554792da8bcfd91f38c7e7bb73330b6d624032a991bdf09b9ec58f6f33171f0b94561d598848f866eda6601dc32676dbda21dd3e43feda81a6b6c894879cdf7d82fffbb7253facc6d2ae8999619e5151490ba18d4a41143b6a0ffe666a5236f97c420d855d90515622d373b40b82ded2061ff474c8b7bed10a94597807a080cd28967e70b96987908b18fa4675c8f10ddada9e77312a5d4121e0c9405abb9a3614bfeaad78060efe239f7625107af8d76b44ab0b37aad8cdc951baa6ef74bb0c83c0db8390c9df3413928ddd3adfc82904c67ebf09349194234ac101a52b5b90f553487ca121df46b891416ac58422e74861a4c4d27c98b960b8b83e002a22cd3b3f824fad94d21acbd8798d8d37007d58496a1669c3cd5f1e7c63e07a105b0ae994be103a6039c5bd13eb19cc88424b909d487660305851ca521381c00aff82fbc01fb3fc144b4d79e345137c294ae6d4eb30cb94400320644c2ba7726ea1755802e3a2d4863088404231345c8f90f88db783a790aee6c8feb3e709546acaaed7e10c7a1070fea01f7426351cd0268a0973dde676caf5a387c9237b67f128e4562ae62557cd8570224b865ec7394960711e6c5fa7a2d77c05417f1cfc8796ecba50757d6402e8ae0b4efbacf628732e8eee4835e1d9e5a6349add57f0ff48f7232614ba90e2d048f6de5cc070ce26e9b7710be330937184febe4393946a4f8999c00e7a0c795bce05a82e6441646bd42e07befff405c638844e1040688f1460553eca3b698fcc522fb49b506e20b38a27b9d8a60d98c3af36032c599eac60d3f315c74a726ea72d0ad6df0b3a2be1237e73152f60a6acdd7040ceda50572648533229ce61afa2c0b3b7d68888574232579442aa6acdc5ab95b88f4a097a2d43dfbafe9b7dc2136e887dbdc7f241feb62c45450f258be8d20c07805964f198e01310e0b8f7e860e5cb07a51f771ce425b4311069ac24b663cb92ea24e3fa56539a747088c038a739cfff153ae5664d076b438e58c56d94e3779581a256f7f87b9c3af39dec3ed4a78edd656b53a28957b6af638de1f10e5dfec3856dae1b50666aebded13c9d5e0fc0ae6bc839db710d07e6a9de1a85b59687d1bf7dd82be2fc802c876266e6c35d72b224dcaceb2c859aded7decd36d9b189bbc710ebb1ac73a1d0eaba9057c77194dbec3cf0e6fb3e050f71d5d0145434a6d33e65a782c24125e4bc8fe5ec6f37d5868c89a75ae1aca4cd3fd475e030c4239f80743cd777f382820f2770d3c0d43bc3e933db1017c254975f48f10255a10490c3bdd9cfabdf5f145a27ffc4cb31bab0406be9a02b5af563d3fa0a1892a907f7e45466509aea0dff737188e2bd75ca2f6d92dc39b0ffb15e0589d744acd07cad051d394c413e002bd4bcd43d1912f0765a0829c06929d8463682b8c285ede5e0f6a30f754f4ee107ef54f05a630863bbb26387bf97883a03990ce4c449e7c0cde20934aabf18284ba264af1dcaa003067e0de5425dc377f513afb6e8f32c0b62af406995805cc0b0dec2eb82ec694ae97fcb7d42f6cb85458adf05672322e01fc376f25e9a1cd4498c60880ea688e7043b1f102b4884cdbf9713454523ed4e33160382f700f600f1a434a0f88672b98b31f692c34401797444b1108a616c6e0bacb596f5d9533f356d21113a71abb09017e81ee5f52b5d812149759722fee59b332b12009b19d095088c8d9c3ffc0b626ca8f75b530aa8df833c0f765193d2fd7fd652788e9d8fe48005d42a4897184ad82621ca1d7786652fe4e47230180c00931f450b2419f91489e1edf2fd8e4661ce77e3d8bc014a49a499aa03ced54788290a6fa81da751510474367efead016b7f3317013a602818ea1b412e28d9545bf50b62a72a245e72dc1c0572382ce91b05353a03eb077e222a688123561854a32a15aadc34378d9662840141e6e4dc5c1a23e08470f50ab34dcd72ea082349aaabb34882f98c318842b8fc1afa5fbd102fca246dc2130ac42c7e49b8d76c91854db60a60bc720bbbf7672d4d05f7df924193f90862014c1bd3bd2b178e65cdcbb1ea2ebd97854dc3426c3ecf7439fa6c5d8ec617a6cf83033ae5c27ea79e7a30a472590dc1ece4151176e62a08287953215818c66dd684cd765ba5f66962168d1c1c49c8bf4e7f56ee844896e41fbe96b7aab30629d9a2b61a92123ff9dc6c8db89a327562e80b8b23e25d803ffa4e6fd4167d2fae5571f2b165dd5c73d3ca19833b7a1ae13ffd274d9fc3c9a682865e60baed6a917fa7f0d32e6613b29bb053a327d7998df2023734b106b1dd025a0335f02df803a7c0023144a16fc88f8f22cbb3162cd93b11eb686d822615930ad0daaf793041ac4111e59f1693d17c17d736bd704ebf6f25794506f9b05296381673f7e34f3f652c6182f60ce56f0a7cc079a2606553308124fa79a82595db0c9fc4407b76bbc34eebabd3d69dd06b7293cdabf2840d8f3ffde1682e82e3a30384dea7a3d37759efb2d7fb42ba0b773d3f20791f17d20c3a24afdf71188fde21655c3a5fa7b5b259ecf97046e994fbeeda42cd749b3a69b08dfe3060f0438dbee75858b4ae923d9f33613bbf520ec296de2ca1489f7ce7c29ed27c7dff4b276de9bfe08621333789532abb3f4f9af0cd48cdf9aa630bc1a27484066e2a8ae65c9ad6ea914b0b495e891ca71f46cf124b3854d35d62494001e64f5501184f055c15d8abf3127bac8b50e0f65de0d24a843fd3bde29485c4f79aff150f5a5a3b607d07b0b50b44670d97d8ad83970a431059b2de0c4c934a990f4d104fa5102531841c1395840de0f7e1bcedc390b8639f03fcf0aad08cca11a151fe32674c3b77f7be7203a1ee41787bb1494436aaa594639c6bbf615c5d0775b96016478a001a43fda77a15d2de1e3c9bd83c7f498c8e4831fa515787b65957dc3a01141c6b1c809818ad434cecf4af131abed4a5f871776a88ed438919d8dc930671d86f3df2dfe25a1f079c21abf5e7672dbddfaf1c48a8718086f76a7f6a98842c67af040a246f7f6512c56e1a01bd51d5caadd57f0f64f733c067db93f9cd1fb01ca0018be8b0aa3e1e3461dcfdb6d501c884ca072ec92c4009c54a6c7bb8f5a6903b2c2c8e4c00f2b60f24936e8dfdd07a7a54e50f0213f1becbeb0213f58823478655e6c1a57e17b78a79f4235b792ca3bc71cd536e74c016daaab77824d007cd49c72c006e5c22e4c50e71212bf4d7b6697e17b910bfd07d56b303e20e3ec40da0b53edb86c320955de50ac5391c7793b427848509e1508b8fbd33ce99a7cb4e11fe8f5070d639bfe629905ab3723c4133c18c326eb1c65324b2964cacd14f4a1d84eb08ea6d656e1b193959444ffdce476a7e3a71a79c8bf2022b6b3bf002ffc27347ff88a17efd23956f4bdb838e88140ee586edabee00297262bbf911c7920dbbee54065401452f8e745d5114913bccbed581315a245fd6b5b7c66b5870e59f282e244eb24fccb86746f085eeedd99b9f5f7be24debe356861d01efaa08915c3f5f01366cb1c0c91780c205d420568f9ed8e942bc033fe700a749b19992a9b49e05b87d2e3a233e7a917c04dab80c9a9de61af5da1abff79e102006681ad84b756160e0d6ac74a8e0d6b90aaf217786e735e7c4dce489935fe52d040517693365a208d2e8597eac5d7de098f8ba2a5737b99af68de326e3294a166e036f32390c388e7c93814bd35b11b0d022a4f449a6337a43cf87e5e120799ee4c31ecd4db79d025ac1db5eaef98b7bf4a4a20a6054a7da6dae3826f3d95aba9695e6dced7324974d7430680a3b90858828f8390ba35dc7c5970795986f4384b874d2f709b64a2ae4b47c6b9877d8bb51496c6490482a047836486ebcc2665acdd8b528544c0143de820d37bce4a06297bb8aeb41e9552c8bc5a614e06b24b73001ba3d5517e7d70533bb30b65d12800c1fe47dafdfb574d401436ec526ed1852ddcb7362999bad6e9c12d977de59f3d6c8887421558fe0865bea48dd15fae0eeb8bf9465c1aecd303dd765397f24cba1a789c803a8b8fd6a9e9d77d5b1f595b17add98407a59059049bcfa4885c08e5a7db0cce1508633712312c53a4520d40c4a32c9b9f30820e68c51d8ca1611211581d31ad51eda575476574f0a58184e0a5878c9f41b93544d4e68c5f645cd88b870472536c56c42045c8cbaf9011dd7cf0b01cc7a8b2d8a043f280302eb080424107c8ffbd6889bc8d48d9b4d74efcf55202961c0c82448c45cfc4f4343c652113b32f9e22af34c0b11a486d79c3acf14f8b7b3f6b990fd597cc1e8fd8cfe4dd326900f254cfcb8b2aaa78a6213eee423a5cbf9eeaeb1222fea5fb8b19139cbd954acd760df1f0bb422ece067e748b7a2468df210dad58eb5e9fb28ea68bfc0885cea4cdad90b0f85eabfa9b5f6eecd53f7ee719a98c68b8e441f57e5ebe186ad240e34849a9299e2277dfff4005655e7070efe634d6448d3af0a7b7d1a092b38b6314204b9821be6a6ddc7003b113e1e6d81fff3e8e6e11b5289c50d30273a6fbd539c17cff05606c8a811f3667548f94eedebe125231ed65cd2cc14f7bdc07b09861dac00a2bef2ab8cf60e885e2df4cf4b854e78073015785db6f7eb2e2d7d0267a071f162131171c1c667805fda930a38f71eb05e345983d9a9818e2feae463bb9dc00e77f55157121c6a192ae76253da3d71a8f0e67dd093b3f2eae3f67bf37df74dcb9230d689205bbc83e0889d90f0949c95183a6bfb1328a0d07552accafa0ed924e9b8ca84d80c8af9736b43c0d252a6dda28c080e311d0a596d103ad1b7bd8f8695ac58a33746cb985a0c2903d1b534b50476b5477db01ea181b39d6100377fe3c51994e37196886069ccc5955da02840495d9d2b7c4939c343d96f406830fb683cf7af55f7d3a2c52ef5cadfffaa23959bc5c7c2f506a48dadf34dbfbf904e5f8b92de9f2393be179be9038dd67257750fd40d1951efbb7bef0b381af8f958d80bb470dca62c7b2fc24f2906a0a89b20296d1184ee6ce16df2ec00a6a6885e0666125e59af4f1b8449acc619ca063a4a8d830984a2c50901c7cbc4458d08f253be4955970d239792bb99cfcc1f15760f7986e492023629d9dd60967425485fa7e22d0ef13405c1f1f21a0cb000c265226d4f71da941c88a475f60c86b0595c93e953190d8b242037051cfd631c65df9140a26ad124ee13495759cfe0d604827d24f4aec6fbf91f84ec78480d0499ea7d306cb38bfec16bc3568e56f82726cadb580cc9f370df4756300533ab8ca09fae75a33da5cd80b80b8ea65da8da118e3c9d1c647c734087556e18a0b79bd149a5623c6acd8e587f03e89e68d4c2d4b31a2fc185f002266fdbecbd448fdf9441f080521f13744a5758c419daa6e195710d8857d367743b644e9b12329d6a13e0048c7f02f9e490639bdbd40f47240a33e32ea696152fc9234be5dea4a6a5c74f54226fda3b6e7bb6213f118f082174979383879dda26129150bc00aa49ad52e1456b95bc60e3272a6990e450b545ceb0af28ae23f2482b32a438972a695a2ab49261914e6ea60395509ccb45c39d1d075c869a44142887a9956ed9d1aca2532104fc4d392161de9b4c3e75290129fc8dd02684665900c5904189d2a5ff2fa0b9c3716d858c816b238db5029b053e25e67881456a0d8390e64c5441757104de51f59a66cf2e2e15277248047e2a75663db15631761f71654fd671f304fab1fb1199145c51af93c16752a5665e8049f16f6f4d9a6a2b8126a7ac0ab2be408c9192402b27ea844ff803c2c408b23d1f8f163256d18aa4a62b419a66945a95a714976b02caa6917653207f969dd1d271758ab677e1c5890eeae8454c24c675517b9a9b6bc2a7d933b50ebcfa01665f6285d4da270bb7b36b40d29e6a8e6bcef093e7049658472163278cf7cf1354901b183c0fdf613199302ed4eaae7bda63d2cf51ed7b0e86fdf1f2ada5db782465cb16d855439a8ad1cc3acbbdddaf942ed300efa256b4efd37ddc1ab7f476bac7af738bf4968e3b9e1a1068618dd477d6c54fb45c25bad10a9f496d402ade372cdca1cf4132012ac592b67b48ee035ccc3bd51193edc7c18f97e75d4b2d4993c8ac85dcdbd4b545314bca14a53c4740a4450f74083019670e17d0fa7e5c4c70da5f8fd3cca52f242df94f0f0842441d2a42ad8fd9811b8c421868526d11fe4590610894f662295020cd9bd3400009b00588cb73477a30558d5d4ac41b1470bf32196c4bedf7cc8603109bd4e03de11358e943afc1d36263b371e037691927ee33642a13550b208cc1398e542c9380aafb950adbec5b3196176523ebf30789904b77772699f52d831c73128f64e1953a572c989bc5b261321b7bfcac5c98371727d05943ff6f29f9b12beaa5d8dcad4c8f11df119e1379a6c728a2df5c1491e48bb7382739b35b8e5458e8912aa7c2a6dcb978436ad008bbbffea29392d3f099761e6a8c2b1092fee3f502f370ee773f6771f4782a5bc106554414789e13b6704f180d88dd125dbf1e12caca4b3875fdbad9508a02c8be1fc1677340e1d2fa9fd71f473e7877dbcd0c3a3ca68b63a3e82abb490914be995813fff312583ca3d77cc367dd9c366c0fd0367094b5723312cb9f7117aad0c4da2c59b0562b510b6ede618268168bfbc661f07052601a2c5b8bc3df1d35e48387aa1d6e50c25ac2890d02325510fb20c5dec9db9f604ba0bf7edefde5dc43cb42368f01cabf03824a50db1038da9bda736a198ad05b87ce4687b1545c3cb49e2091c801b97f8a17091ff99021d79529c4257dcab971c0389103cb28d217a1f27b3989c278bb1f465a09e58c12a112e251a884ed6fb1b2535cf4bb6edc19e20f7facef3952ca98a2eeb2032622589c0cf5a4d993146d5db0ce623dc069956752b2babb13b8b419b82832e5313f9bf840351362a3173684dfc0b43804f8194c79bf08e62d65b967a62d2325ef54f68353c367afb7b9a7e52b0bf8a747d1362e5af2430454076de4c2f8e5800ae58081fd9cab671e06287e3a5072af37cf9ff2103f396b694c5ca5594d18d3feb04d98e64059657310548fd3e801b6344c0b43940e9ad7c89b837ccf5b00e71158234d1a287566d3cc1112b88cee1058ae3fea5053cf0a5a1b9de5ba3c5a5c06e2373ab1b310cec42108f87e6bb4c3f036a6d17cd0ffe79d8614ef4bd1e043bffeb07bd1b4652923baeb570cbbd7d38db72bc356f5f294e901a0097c69f235ce183c3975a40ddd298311bcec525fa081dacb9a1ee673beed35a36a2d97f77d79d98f6320a0d36779be6d63a3a20553c706343c77c88b6ecd7ba88c0b5ba6efecfe4b2701b2e683211681897d9cca0c46099f23f83c5db9dc00d55665506c7a4582a1227a024fee3128b799b92c061ee8b45d4fe2e3106e87b84fe44d50c501226c4c23179d10036ce9d0b497420267fe958bed02002abfc772306d4fa6616504090b69e1c9487f37d21f28ccc3d155bdb19f840faf2df461958f88263dc397499bb93b6520239326509366f0e7041c89384a93f43d16ba6b77222551793d165d3c7f677f2de87c6d2c9aa61d53ddc614b95e3eff2270ca443d2ea7b9c8651537e3f39306e75db798f88bd4efa7475eee2e4fa3bd89d6acdf0e15f40475910c754159590ce17748c80c9ada44c3683bee49195b7fdddbb9e3b6ba6312bc63766c67b943a69daf74f04e9207bce6ecb50e949fdd0eda6944fd1a6380542b99b3bc129c8f09cb9609906cedbb2b98aa6509027854f449c7dc06a805151f3525e1eef2e9065a11049da4d3e07a8a18e73ec95d1e9525d4f52e14d78ac49da7894afc2aebcad31196a1c490d1018a8f9270f7b23778fb9b2c184032a5e3839806ae55ce813ce389a000e8a1efb4edaf83f7f7c9fd1604ab10cde704ba15df01252b814dc0a6e703bca9cd1cef00a9094eb0494644e429def54dcc5f6db2599bc1010ad6902d6cf64b93c649e60085fa1dc885ececdb4065f64145419ca5f6382750a178e88bed9424bd89cc3091ded4e82921afe99b4457d14accfaf105b88d6356a87d755d6034b6f5e7e0329fe48e55ddb294e91d9bbcceaf3af25bcbb04c2473b309572531d0359588a2364d0ebdb8e39fa9538b86655694bd75d9bd43b2673747de8a00b15e399452f999543d659bb39f49e4072d170f7900311a0a50e12a046d2059790f0bd4d4ebfef8c8b981cb0ff066c5aa5e9d3be892edce5ee82252eb9205a695637dabf88497865436e85e3425da633eef51de7223f3c5bf3c6869903395d0b54b2c4babb27b85747f7f8e7cad1016f615c27d8057cb515a9dd032af0a678d4525d1950486664d638b156e9cb88c4047ccb3db1252709323c1e5f37ff5fc52b3472cd4dc2e9ba228df69e6342b4ade8e39e8eaaf144d22363ea2ebe71d67dd9b145166539c1f505e9aa3375bba53b03da89260599562e5bc4112aa48c46343a46a84e93df7fe89d85c9995ea79d9a0383aa318f460692c7552ee4c5f4a812f14c5b1ce81ab7d4c19471aa3a358575bc1a86abe34a4acfb959492693f1577d71367c1d8cfc43a8f255986921586867236d66979b536cf7b72728563c42919a1ea498b840958b5a90e53f79828b1c1cb1c3db296ed576e86d814e2712a45a60c7e876e496e01c1201006ea12da8dd474b843de058b957c35c902eb1eb5ca4e33a5f2a6f4cb0301529f0bdfdd65b0180b1f203d95734fc3862f2829f9f9c2ac34d6c855d8330b28c172b3850a468324fa060989078e9147c2da6f93a625f4c76775408c5dda38ef95f0c34baa61299c04c10e3fe45c0bbb3f254d97a5683ad69f0ef290ec53081ce327d8267619d811444556f8894559bdb50b33ea91754fdfed0c219cc1d5e9491fd6f878583d057cf3305ffab80f88749625d525585265b514ef8b4c6924269651c8119dcddcc726458a0cc1c7b6b29e44562f92e37de41e1d8fa4e293665c676a406bd8c2af0ec50fef9ae155d33ada8d73ac3049a2ca2b0cdf493f84e2bb1ab351a0f3e6e1c69bf6ec6fc638c40c9caf13101d36dc1b885695ab34fee814a5568be35d66833e3a3d5d0e01086bcd0d08764c796e508d89493712323784cfe49e95ab4b32ba48c5ddd025cbf239054590876b20658411cd7a66cb087c1df9ff10f5f27ee173eb465a9e541d9d5559cdf67e754ab333f2b48d3298b9f73a616bce206ec6763b495b75eee405c1867ee1a6188a0cc0f3181ec93a47396ea2e71a31156c644442434d7a87fff5fa39e61971c7da9ceae7eb21f9c892009aee80284168e8ea49979397990e0bcfe4af3028b94b745db9898d558e464fb2ec3cfe149c73e8036415572e397ff75ea921225d5ae0dd8d6ef92990c729dd4d2b97e39a25e4c61350276fa7cf3752e80cb222b8c75df657b68e747978ea5e159b44410af2754741a5e82d2c22b0ac764bbcce9676346e7c55f30b523b98738023ee417fa107bc51ba17219582188c8edb09f59d7d358732ad2bb64e884ddcff202dd07290781d249c07ed3a0eaa94c0a3a9b34f51cb7f8efee319042232e18a2e44faf1e245f117c17ffc4f1f7fa8e91d236d043b9c20d97a76ecf6c850fdd84d740e4103acca2beca867bb61a7422505e775b006aacabf980c36b2ddd71b0d8d0ab676449028bf47ad366028e51260bc05f860b59106bd0b82a8fec89247b8deefba1486c07b92ce12ef14431adcf0d508cba64bef7471d2f727ab6cefd7bea6973c4c98fbed91ce0706b67cb38bd21ca25238f9d7447feb1ad3b78a797a4137925462bf68504f47046c44ca89027a4e8537144f7a4998e51a1e941d1b9a799c984af62f366fa9e73abfa53ead797a7e9921cc1adcbed60207acbce61a341704caaf381ac6ae86d20e2819e3068457c377d84c2e6c81c184cdb49214b630589a42d8c2172cec4c9554a18583a569842d2803a060e1ee37ad90852d48d8b9e9b690852818d8994a60852910d8986c300a2a38b09852202bf0e1560465cc32b9600b5290b0997e640aab70b0c4a485190ab16af1cbad70ba6a66d00e8d57931d4c6a7cdd1b16ecc25bfbc866a5ad4482722de6d2097c6b89844abbf361cb2f2192c78b16ddab54da315cd9dc30222f008aef34b025306dd68662e15f9a11b7b7607f7d5a09ee6de2c4a25ed53f2240e44d835caba5c2861b51a6b77f99677f0ae104796d651d663299d161416cd6015156ea282292814b9f0528aeb8dd5657e67867e2c9675ebb885a6e82dcd0f86730646a541d89167bef47647e004abd095eb41c002b86c7547fde97d094ad707db7d5762340cb4ba59a14df6cf133b0b231bf24dfb9e5edda2c97738b566d06faaab56bd32a75ac5a1802104466404f42539b6d8148a8ad1ae4d954bd5778311490d1366ea5dc0ba7cab9f23cb84632949b34f474105519cfbeccee8de059bb90883b45da05eb5f2d3d6efca4c7d333dcc6b08b6d7c98e73b0451d5fa8a13d03f7ef86756e4afeee4e0cd901911e83895ed1676164ca544d86d0129e72e2cccb3d88cabe009f4d1982b4010c1463aae0648f2156e259d67fe71d585e8b0cc6e4a0cb291e014545cc6f454e7af4c778fbb1aac32e8cfc94e356902e3650fb914c6000b2d9b6a70f3819206d83163f1f6a8703b8029d43d2f7d51edcfc8c24fe45d04b1277621b603d85b80ddceb617ef056baff35458a6525d4a471331a8b7a794bd13f5ba22a808e68c071a88d9244e6980d35630157575a997b3ca01f123bb002b3f35a95a567d304f42dc393d91cb801689e6e7e28a45677d74c8e93fa5cfd42ba202e75876d3b36f905c43cb5d26798d261bac005b02efad0f85a57dcffab04c1eb4dbec2bfea4ff0bff9aa75091857dcf307a3d58c4f8929b2cc9142ba66be4e582378db084e8baceb175ba4b5619654d6dfc759fe1176d42d12ea6b4efb456a4eaf94c8dc1e9face8c3f82f62dded299972d119f8627ea5fb78671399e752848cb6da40152adadee0baafbb7dddd1adcaab9d232b56072eae4871e126c5497de0451ec163b0b554ec85e7d96f92c0b8299febd14d85905782e5ac5b0a3c045ed400593b17112b7d1b61d532767d623d5d4e9ca02cf1a01228514b549e07976d2fce0ad80229418dea917c452639ac41c1a2d2864008f13c7eb2eef49e49573b37d36382e5fcb2d8e85dd4f10ce365214707ce8ed2dbb38479a408bb19a4968d2b34f82b792fe06cfbc971050901f8367e3a70a912225756fd7540f8911c53e365f0b19796813924603c78dba769c9d26364f0e430f251867964ae9842ff0b0f6589b022600d89f0e14f7dbebdae29ce19b618f0685ec827117425fe76e4c092ffd9bd8793bbd95cc268d3bdc4ae910b79a1ab7aa0b389fa8915b9d292d6516acea5591dfff80382904d42954a6681df3027baf4f4916b46dd7442d060d5d1ea766f8b29558604caf2566f041fa360968327ee12c28d6365f4cdc8feb23c78e0496abfa43f50653ee0586b994b7942c010b9e4c5c1c629fe4c2d9d40ddc32d7dfcc17b0fd77b1e1c91dab7ea3250e856a9848684550d95d9369463d5d99b48b476c9e97fce9b1b11cf8d1d33535a831575f4c0ffdf25753653aea9e892840f64cd1db314717da3a06b03b35f4eac083ba1a88fe8fc4887ead0c26bcceaf600ebf550fcabe06446ca6655487edd9065c3fdaf77b6dc367d4798aca99815b42682b2201ebd5db7b9507bd8efcae95e9847ad48c72d9371fb8307067142234be5d297044ed31b0f8024c76be0718a2c1c22d8f2d8a925de104bc56cd8c0079fb1755488fecdd99670a963b97313203c0228e372029e9512d08e293ee0ed260bd376a183d48870d8e9ca284d5614e5a1fd018be4810768ef9260e3b4c38e627f39ed2ea2e02b4a7f373c8d81d61a5c47af1496ec6be463f043ca572e16e0bcd3a1407f3a1c81b915ac83376ac40dc20eadb75debafe435f0c19baaaa791855ea89e9d9888f82202e67b835014bc61f6ffd6c4b0a01ab0bae7b9c91def94deabf7f61a1730961001a5a6a199140d02af9328f219fa7f3f3304b6d39bf40c0ec10d61c2a3780e4512de4ce4f1f7c4356fad469b67cbdffcae99bfe9df5ce1639ab63acfe7d3f40640378fa888df2a29826f80cab170599224c960f5649cbe5f041695f8890e422e47238e85cdc6013f9cf3f3960ed6f559df388ab4121cfd948bdc9452f10f41cf281265850af1c15a5b0be16b8939eaa4657f0c312593852849e382b6edf3b223c4894f25313904f0df534836454ee5fd1a0ddc471215f1b9aacd01d718d8bf0d106bfbb605bdc1f3c48df0b285288e275fb61c1bc22d3de62003caa5067cabe3c9af33f2b53ab464cbb70dba7bf66b1a85dcd004e0d1bd88b156d893bc8fc907a37c6a96d3561cfa37c04816328e6fb1c95940d198332de6157851dfb452fb568285b81faead1aafaba069c372151c2306893876ce82a328c5bf115f1eb787fd5da762cc28083e619f65a21d1688c06394073208892a301209c66111e7763f967d5a1312ce7e5622fbbb77bc5cc84667685c54356cc1454f8e7a8d39b718c8a593c32e8747d30bf46426f8c4e92bcee0f2dcf3b3488a35f2c8062c38f667b4ce32c9c2ba102a04a3d13a94098c5ff807783de545564ab1a734f09a9746331a416ce68e08700f18d0a3eea97c50c33eea034226bc572e012de359e6e764c23ea25588ab17d6530b816b01b86736f67e97371006d95bf86eafd0e58237a6ae1e87400759ce34e0a084b0520615885c72dcf7ebbdc085433803eae3da2160ea2aab0effa1f6e70b05a13fb0d1825dea9365fa75012c4cabf22e5e23953f76148d8653e9c6cd3d50bcf49bc46b24875159087f3b0e9d5a8385a06b34e4908bfbb08be2f022f741b60b22885e228eba9789b46f91adee860d29ab5aa87bd16e1e4f2ea063e1212eda2fa434b3ea632f7d74e55b74e21a733b7a0a648586368e4d03805041fc94cc00f813fe2fc21729ce31b1a5014fef39d8f00864b78068f10e4936fa905460f8a3916f6b4646e122d1358456b40ad0afc18ec0e231d201abe36377a124848dc120c6897240016d038223f1089e76c2cf7f046827e8590f035cf22882e59a8cab84e37b8a0700cccb9b333968ac9006f3a2c841758b2af1a911f22d35047e58f0850a8974b63c58e7e565c2c9c25dbffdd3d430ad8da3661ce1bb645a636abeaf44d9a9a7d0e901f2b21178fbfc01df48e78d82e1aa1e46e483db00d90e7c89d38e3633f7c06628f704d33326f51e60e6e676b815281117b61045142922b015db3b2b1979af74dc3a9a44ab710e76672ae98c38531d7b7c089c24f42baa5034c5a6bb788a6df00607791f154ec1d11b90ced3460c64916cb0ce39941dc624d19b90a029c27f1d5017db44b7658f16fd38a949b980327a1921a1fbc3808ba862af2cb75881e7077719a3dd249a9dfcabc32d6918c824f390b5e79b74b4b08f9c9e421362832ee669ce6f0dea6d666eed879dca27b53b0298c9bfaf0975a045d45615440aecd97a6a11501068c36948871694190517611992a5ea34a043caeb8d1126cc15835060268ad24b2094ee47f3b1890c3fcb08ebfa94884544ffc4e7641f5be75e87c809399326a06dbdbf14bccbbbafe73b2b3b3bde123b9b8c3cf616515f20f6c7239e63962aaa898479b14a95eaeba6cf5b9fb1a20da9f1216b6a3eb40b194c5c3a6881f624785a923b0890b70261a60e6458bbbe312d5408443981bb0b76072feca3cef69d5afa656799b66932d5c3776e62db041f576c9bf6bcecb279ba09a9cf896a77bfa072baaa8d9b907a013fba6012ae4002cad858c39073b320681c6388b95a682049543d656c7b53cffd483835dc082e928905a4524970cc8d3c8930a653b390456f2be090ff26d3dcfc134807ee4f5de24de19c72bcd02a4d7e255db8d46655a506cc08db9f953f003e1958dd503274148b6f7762b904955013cab1c5dadb6ada6ed0ff6f4539f53429dbd208433ced19f4942df801dca0e6eb18a650581e056c14742f9c9407e1a48fca2069052ada77c1e528db5c3224cff602545d22fa3366e74345163a3039cad0501234a4957d1d8382aa5f04f133a44622623a76b40333ade1e247cdfc29f615bbfb1512773e86a183dafb9421f47c47604ea3c875eae60d29ba3cb9c814c246962ee13d673ea3c001c1559f8237d91201f351ec8f4152330115c70033b8f3b64660cd5a8ca411e311a62c23de261daa55d3939b00313de670ef003fc5ad942f271ecadf4ee1699a259c74865212e25b8287c7dde4b03c2eef5f5c36c44972beb257d6106334167fad56f7cc08a04fb1f9b69c8eeaf1251e79e7b1a59a5d619e522814ac4719702dfc68a4d13e856151d6abdd57508fa37bc5444cd0b9bbd147f014205eca3c87cd02982548d799a8449010340d5cd6675045ed583e1ce184b83dddb7bc24fd1a5267d6b735b8ab302754a7d64add1f0854818ffe0a4a5e510ce19a4676b8304170ba4909fc897ce09e5fb665415b9ac22015daafa396c9374b1cbb7945f0e5c722cb2852de831669b490b4d6f57acb6bd187220970e282df33d28d6320da5cf38287a648047a786048bd2353bcd78223c75dd04ee89920a6c84f81b0ae0a39c3b211c6a2eab03b2ec0e6beed3c1c41e2972ea8622c03f7fff9497802362990a5df4382cd25bc92523a910eee85d8e658f63beba3b6b5be98252669ece21dcfcbc7828b48df3815adcb6bc9f16bc9e5e10353575afb6c5d6e8c53305744082e0f2bcb42aaf6d8a71ac3f49041742ffb45d487de7f6efa2e321827e469fe394280b8ab8157c56490d5e46c755c83e1b5b2761406ae04ba76b5b8d9beaa36fb7572e6dea9e5e4ab534e8379e91f56d04881d95c57c4237189ee26055748134badbbeef54687aeb268b0d24be159d1c186051536333c746a7ea570fa8236a865352376a7506780a1cefa143939920ae9db0d3ccab546f9429816b13453e6ed26cadba655f46c9f11285c6d086573182f6a6053ae8350129c6d895091327a47379242ec7a7c7b1a4ae32f36ee045550da75b0eb71a209975849345831e9cd2b34dde5d4f9c99ff1e9105f33b3a0465234a09fdc3a55b4e95f4d01043a5e41b4b459da619eb8a0f642347ff4e53fb40122a9d279996aa0776bb31432e0b385fe363367d5e34082aec2b34b9c4a1119f96a90be351dff3d45ea904ce4df0aee6f3ec749aff91301f8e5f3df42a93f253510e0b901d87bde79aecc6c83f645f6d12dfeacf8edf7357aa4be772f93cf9190c546ebe714c4b1e43fa8552f2f1224e9107c62e7312d0b681025940b133bfa9ab23e0d88bf329e769c314eec70dd70261e3e3daadc7bc4e8302b2f8175b5b6493cab253a2f4093cc22f18910f4c89395f9459a1eec2378df27bfaa8475957d573a9cc98cebe1741709afc34a5f1a9571994a520340dad41da554b01727dae25433064497363ec50e0fba44ef7f8ea7d71b744b823d136aa9b06901cd5f1d0defb1b749d4c23076377035de6ef9c087f9239cec552c6f98e693cdf6812b80d081008fe4fc2a419f7d1995d404b1559b661b2a2cd2d359cfcdcb526f9b5926acb7864c769408c0dc791ce24871918f5b66bdad845959da23105ee87dd739d3b36b12007c29ce574a736b9893cc043741d40a274a4962f3d5167b5e65329fcd6f0bd7f15af8a282468267d1894f75db0084eb4012168c1a1a2812922ca745d42876f54ddad469a4d93ef16e4755e9f91e2cc7c192547ddd86b09aa0bd3a7d10f47075c109d59a41ec22ef7ad467698394ea77c47e30b629fdc751e6785c4a7ccc2a165f20f3ec591f0bb9622c711e375d44d69bfe080b238bc9a2348937badd7dd420d8e84ad96cad794f580348facf0a304980593174e81117a813f644de829a826d8a27f89d904b1c378f4cb0cba84957018d6dde501687f12b9957e69733ebe308802822485fe8d1e83edec790ad9411d43d9c3aef5146a8f250bf6a866595bdf8c9e43ab4ae3367983115215b31d0e84a4f04e3e19e0211293c28fec336cccf0d0643d408645bbd9ebf36e8911c094df74465b1de0a9a70454e9a1fe38c450f14d7f8211e0672ee590ab88239bc00ad261415fdad0733fbe3ceb2be65e9b5114a85c8dd7dde4d638b8474557432988140e8970f3a86c9132dd4772e2952ebd8d2b0d187c885a46d98749afdfcc985a37754d5a81126d3ec608820e962a5cc33a8ea39cb29063c1f831c512995f08e92dccd4ebf5e12fcc495c17c1d0d54bf4fa40c16369673c67bd7de4409db7c8bb15b1e38949c08d121aeb2683a6d75c790097a17c82aab0c058ffd0d592f8382b4cd5d13dcea5279b13830d7cb19c5b271da544d5480f0c649274330eb55a377df7049d452689097694472e8bc27a57ef13070f0d1bf3e7d553850d0d3eca1cb7db997461083a9c2300d92d2875df22602133a7df40ac709252a504c5978eb15c4da2653483303a1d860384ca82c003478470c45032e8cdababaf41f950063648687df36d493a95bf6f4b851be99dd2fc66ba8f31da1dc2da8c146422b189b98c88f2193eb16a4a5c096ebae1d94d660360119f72f5d63fc784536f7d4dd384d191a66b308af561ec86514a790862a97783ef86649b6215d22156e51f0b0d0c63f8e009ebd44614f448a6f36bdd6c06aeb5ca1cdbfc14c8d9002a947a9c87d57db5970ba0be538d2ed05a76accc706dbdc3ea19b6ab896342a45d07b3ca20d9c2f436e2bee7090d9c537112077ca12b512f6ae5095e51f3bb38469a52f54e0ccf617ec1a6bd66d1091987c5f7cea2d6590ef343ef5628ebd6c1e513d65855980eb176f56cd6d85a0eed2cb0261199129fb6b0f94967a44152d3768ab6740ed39e04ee912c69da846ff31bdbe749851235b993cc74b4e25c461f3dc0b4b0c9a3ce34f9633b13e76d5f90a0d3da7a776ef64bdfff747b47c2ea4f5308d8e43a7b2bd0b47832eebd0114974857b03604d1ef8d124bc11a690e07b9d6cd8a6c238f8ce4624096488580fd0718ad82a81f8eb9e48b22e4901c9ad50541d03b2ab300e79252faca38a80fed8a5eb4fe6290127e78aea1851e116a16379e614722bae0d1c2ee4990055d12128e5ea4d144dd41233e54906936a068844e68007e40234ff3e0a9364ed0132b0791b510eaa4336e22c98763dfd2bd247c8dbfd781985844f3c3b19b0296406cb1e88158c23edb50887e9885822a45e450c0f0555055c89b94028a73d01fcb9ce2bc723e6fdaa1bd9b2421bf2e6441000cb23fef30af1e659ba65abf100408ec2188ad46a8e69c209ba9a89dfc6787a687e0fe2485877741694830c9de2ad027449dd9446bb964baddf8b84ab89ce97ca4f00512a15b039cfb467402e7ee643e57139eea16e9cea951e96a3253780f3ba7c85ab3bb4af30684aecde233778deed0643262ede074370ec5e7a9e4777109db8e8b4e1bdc64e397492eceda487910de11f801ccb1518173eceaff5c765e2a7a51e8fcb0e53cb44889cc99dafd927e9e57d03f99eab562802500080e1e74b820e9f9e349d9ecbee77b352a0996ccfb88101eaa857c7ce0fb965dd06b6c8f77105f4692dadcdc1ce1e4ca232abb1e31d91ea41e8348a8412622ff30d0142fe46c545c521842b7d6cf66b2b7b4bbb8f6609b111115251d2a8e9f0cd09b392b11c3f386e5369b5104af985cdf5084053e354f655c910deff4328ad622d55233c9e3956b2d6e38355b033f14428b21a1b546e8b5de6c7f96409541f345feb509870d6745c13d113a83dfc05479e374c13d4e051bee4ce457fe7c3a0d06ef71aa75e839d235a7a47f8196bbf5bc2017156b3a1c74885f0298628baea5431db5a02d780f1671c89689b22efcaec75398f2c3ff0634fa67cfbb9e4b0fe40c3c9429828d468c34f5d2f258220610d6234586831188c97d89fa1565bd713e92533fc088351822012ce01d72428de3f57def66a9962f442da763755057d81e0529992edd8af98e00ded5bcc20962b00077fb74935759945967a6ecd256d1f37c04f3d048d6a5b54f8c3d3a9e81b61e093af8c090eb5b4b23dd30410789a67596bc737443e02c77ff9590bc8f54cac2ed9cd75ae0419e1c6810090e90cfbb916011b659d4798e28babc95301698448c91239da76fb5cdc9fcf642de5c1f7e1490b59da509da5709813be01a824e41b1244e39c226c3082c02d1011a77d742a56efab42e3c92be43700fdee58acc4a5b310a683a8358175aad5a9f6572096bc325a87556794b26e2243bf4cdde25f672a63315cb00aeac630a5ed95613192f0d8c2f191c2c8f45dda125a87698082be0e80a34e3b441b4b432a7ba2825a7c60c3f5fba70e06ec7f77393ca7741f05405981be034fabb45a91f1fca438cf90480e6a3e805d0e00fa0df3d5d9be5af1addeb5627618f54ef40cf1515db9b080a90a849b8bf17e61be4e658a9e638aa2539c411d17b7f359e24cb64a174db140fb7abbaf61133fa546d91a6ec7fefbe203b89c2b9a91794c72a9cf3e41d46854a20588a912e0759d70899622751a9077121bbb198582254d65b0b1269f9f8353fd0b875141119510c884a564694a7eece1c182743ac93cd805a71fcd12ba79fa29ce7913012737ac0748e303aed7a494e00b7deaa328bec5e569799aa1f31e78b2c01018d0ea7f9423c68c35d5448f07a38e2e238d3eaecd65e106efee9c9cc2c6ec4a50e10de329e72abb8029c8476bcd37eb77f75af671f0fdeca9e04fa9aeac2572b74dd8c260da2ff2df38177f92aa7f035bb7050205aa46848b6c375e49a47c4c7d3c01acbf3c6dc8da47d481ac4a1ba3da916344650b12d7f6fa345a4864a236bf2517e415df91945e686257d4cd0bab535826050c368255cba7a1e49591404905427719259219a194f042293d9d453ee1617a9067ea1511381aedb745b4648e4d6838da072cbb6b327ecf781eee3973f771a23823d5802d215319a69f94d679a198d769f4ed3cec544b395a887e9f0cbe764ea4ed90c9035d90cc3063c1bbc516e0a84ede17ec019d627b1299322e57aa03747503fdd421401217f84cb3b0fb8b57a5d8feb4db487fed349be9479bba78598039dc2c957371bd7c2dd57df2ca127b66378707ee5df674a3ee77a4d10e4e8e18f454cb3c08a5f8c5cc69744b905a8313f76bca20cdb699ab1ce5b3e1c2f04099768ebb31d6d7e5d8f681834d9d3e451a10fc490983bb5d65a672675824ba9d395119550048505fcc816e622c18e21fce3669f0254e476c40b3a51d19b17621e37e4bb453075f8b8ef65a84224e176736cb0e8e167ebfa41094a3dde6db3ab381446807d8172854a174b21df08fc9cebe4ce23f2c235468be65d34a2845d0272c9912415f5bb2510a7d6049541ac15d95469dd7d7e05d6ac54a3e3ae20a6e1c3fc21ab15da06f70ac5ef376dc9f83138b510ebeb48596114ac53f4de18010ebc5164dc955d04c4dffbf38245c03a36bb5cd2cd767a012d580295845afc33d23564a2e9b0b00258823f1c54eede951fac2439630ce55877bed20f49d7f24bc4f47e6dc686087896dfe25b4a7c6c7867cac0e980d280982a35c80130803a7a3a129be7be7c352e1e219f00beafd380e8d8c6522e229118144905c89921cc68b3bd449c490fdfd4a27ad9719d832cc2b43aa50c4341fbc8211e981eb672fcae49ba996fc854f550d4218dec37a871faa92a88b40d1098f3e945ad52262e6e41031a348fcfb70985b89dc7c21d8adbc9ddc2934048acee860891149a7293660907cb068a81446a3ce7524648d02dc7b2b284dd38969c0c8fd00da18612c80967fbed036ad0c293774288944fd4cc4c89ca4d803966bfc5d9968d7dbba9ac09bdfd0c9132cf10040f054d07afc01e8e2d302f7a9f72f83f07983ad475411356c8a78f4be33002d2db502d483d35535f498666eda7c2f2c3d1e07edef22c147ddbef40fe53be13231f4b5644046ca07cd7a8f9334e84b83a98054128b6d7d772004d36d95c02c3192a93351915ae1e1a46947dd3fb1747fecc692d6d029b45dd70c79fc408260a38bdf86c63f643fd8afb7e616356bdb33504e0bc2540a91bc2f7be896f81b08d303dcd9b8e5068f85650ce97aa55cb51080f88f52846a68bcb7da8d31d61a40ad776b403a8b84c7ff28ff231835224382a1b994522324e129e5847ae2a246402290f9f4814e7625a93c4743c33c723334b0e0d64e8a422cd37b093135b058b61028dc7f85b36d1ec6505ca98a666e08b6f44e6c55814f35a6aa70d11b305456e2e6dddd102a263e33da3391503f44851f32838080adc5987b133a6b9022c39ae82255443e4dde106a425c751682faf2689e184f41e60941b4322aaae82714ac459be8f2e01674c051d7be97246b42856b829f6b82ea9d9e30c760774de9324b4b1f62a9962ffba631766f37010220da45e8f1b752f068e96fca92695243f0a61fd60e7cb116e68c94eed561ee7e6e58286b82c0fb890acf1ab4104806e85122524d5812921ebe7d1919e78fa9bebf0965968c9f6a8a45303d3ecd4abc5bf42f803f11e99c44eabf0cd0906c7ad716c1fd3c1c8ee9b25662348f72aa90b7b40ca50546c343860c211e24d1ad168a6321b8ea51f0456e1cbd2df5ef96fd67250f42e90c8c113255223d3d98529850f6869eda224851aec4aa52b9dc7274d56c8129a23ad793e371d02baa8d17b9b20a0274b245ab1c543755138ca5d55e515a1179fa671095f3fd0fa01878728c19996ffbb1d42e2bcaed4c3fa900a70c191fb608e7c024b1d7e2add304be122f178735445ad6d365475def9565b830007ce222867a0a689fe6d60dceb1e1695405f53bfac5d8a66719f6edd16937da24a262ad11ebbc60eda99d25dccd4f00199503083744889fb97bc89e5697a6e69179a4fd1ea05f20337c80cbae323cc4a6147e42aef5333a94822bf05af8170167d0d6a0ad51e9a38e032db5fb99cbd2facdc0328c41c1cb7b09d1b681f700670c66042ef57500dad9b4445087d985eb5712a8337678562f4aa43014013cd92fd5edd970672424e9bbddda0c1727322b1e1219fd435f790c9557f64b18420a18f2a3c4e7a4e2776e04b9a4eeb722705180585037e103e787e411c80055cdfe803d1ad45ab82c7a0af058089e169c59860fd924cb6898d6d06e218d59dfed45d74182e4311f19e4960fe2b38aac4af8b098dd4f461cc7a81fc288d306ef45a34b3d0f1b51d24ff69125c16f0636c8685c7bccf69e9b639d64cc895fe35ef5e6c80b5b1f7ff5c04638827173d98c5cd490c91be81a62e6d63c96873e782af9e352652140a08b230d0d9c40a164e2246df35c60f2825185fb2d09739f22990f414309d7da873262adb8a612bd5325db2de491443c9548a7a8b6f7739f746bcedeb5dbc42fefb28c37518cbfaf4fa1802c0aef9cbb31e2061f46f978e9c1f7ac698a25aef32fc9a078c2602884786cc57042104eec522512fb76cb7175132388dd63582c41223c73d77e23f4545bbb2fab4998cd28d72cb257e26238317c1c6e9b973a270a3f0419fe7ba13ee818b0183d327d581871245ef46ab0f831bc6a025c4f030b1c5a6511311af5e2e8acbab08d5e95762bab48d745e89c029302fcde890cfa62d82dc44a1ac83d529ddbde98661933d1973a872dcdb932b69b76f71303d65e01dc87a0fbec01a1e2d5b8975db124557c2d3de0b0cbb8016b94c822a6ce4c83039a97b6845a201a56a503f1e77f1755a5233f855af91770e52e3e1523b378af4894fc913c32c5decfa0445f71cd07930aae78186760700ee0108539804c0535a5857a87d4ca7f52f9a2b6857bb1a7642346d9109164efbdf7965b4a29534a013e085f085408a18fdb6d4f73bdef5c71a6bf566b535115859531c6187aa1bca1fc093b10fb8d0803b7d73664c5c6cf5e73fd6caf8dc857fd36543db0db6b1bf29b1abf7df26ede9f3cef31eff4988b274396fa1aeb6fa93829f69ae779de0d377a9d165d7baa7d4edc5ebefb42eed61c4f55309efee5cbaaf8aabfc6d7c3c4bab8801da0b9281087d3b7fc297b8c461bec3dcf8b511e69f97410d9f8a73fe1382bccaa9cdefee9fb251267452caba2a414664e2c111bca9f50c8bc99146785999151bcd15c3ed36f74bb4f45b0d9ff744ecc94a43497e63334a138893729305b02664e6e3fcbb79dbe0dcab7196d479de9524a37aefb52d763ccde33d0fb18638c310b32e4d68f9f0c9dd52f5b9209654d7cd5efa93c2f7bf9e33737ce6a16173549ba9c0c924da413f99244b7dfcb42cd65c559558bdb31c6dfd1376aae78b30d75b8bd7c4ce0f6f2810d355795a4ed75fb3597e60364bbf2473b72b59faba364c36cc9edeea66454bad3a4d6c5eee273df6c89b3849cc58139602fa4664dfaab210721b6068aecd378e017fa6bf7704d3f6dcd0891dbda12fb37d45c3248fec8239ceb32b1b1cc0dea677523a7c80647682ee35c66a2e8ac100626c538bf6229995e962fbf1b777e5c4404cac5322ccbb8a7b1d971232b88828acc10ad084bb4b897f4a34fbe33f68ac9fc5e80affa758c008910103948b203252808c11241449cb022073368a2d5dfc38603d8c0863a742c0067e3c1062838af1a7286288eb324d8e3004d5e6645e32c7f9b9c244b3f070936fb52305a19f19f15a6b828063eb7df870e999a45f6cdcf3ea9812a1ef166bf23deec53ceb2801299f2d55683cb453e48d7570d2555c4e4c9ed97d1e1a36977f49319fd1d7e69035235388bf2c0a85c0ad61041660500a05b874839c395355c399f26d1c04544f0d5995fb11788b222b8e817802bbf00dcf9f14b498abb7d7125b8a2c2e2c006bfe125cf8c8d657480377ce5af830c1b46a21b9188714071968daf9c866b4ed7df06c631afff05fa06c6a19281defe7ebffe1ae000e3882fbfc68fe64359250ec48e919bc912a41b3dd79dabb095c87dc3592143d11189aeb354a90be32b9c1b3770a0870daa7f1b381a61481bcb84ddcfe519746710e3f0cb2dbcccf36f52cace61b4046806712cdb6790b3425f127256d8535c274aaacacd250c841b72379c4f2e7ff51313760a996193be24ec8ab31cc4a6388baf3f0bc9570ce50b820949aabc5a2d3c4fcb7e61dfede7112c29c7377db0a4e84ddac8c85973f60ca262b326dccf20efa91f6a58920b446c04dd07f41b5b587f9f72fac20974f9ed17ce9fcbcf7d39c86bfa7290974a0eb28fdae80050d846e233fcfe61b5a90e0c5da9916c6518411214f9590a283b08b5607c68c93c4f2be7c80db291399e6362f879e33038728e4053543d7c0cb151ec66bd240c5c977f8a91cbcf21d63ca3749fa2a4e42c950d17a8438ce453300e24ec0d71863f0152b02aff1ccfd35239a8aa008e8fe17de07c0e7087893fce3be803c7c7f031803b389ea795f3031bc3e7f89097b0a58851611c3172f5b9fc13d69f7be4729832f2151f5d769fd1dddd9d97a20e2b0ee440f146abd5da54ea81a2866463a321e16c46b886ff53f968616748f3c009466831f90fc0b7f03c2d994fe543e657bf027700f032cfd3fa8cb07df9bbf6ea65f5f1679ec60be05dfe66008ffa7843f3ac96e7af48fca6c6592ccf5f83e28d0bcf5f859c757afedac46f5e78fefaa4bee28dcdf357226741f11b189ebf1e55a4784380e7af49758adf14e0f9abd28de7af569c75c56f0cf0fc590febf9b39fcc88dfdc3c7f86c459f53f16c08f05163e185714aac1f62a6a20340962c9228aa16601fc180835785dd9c5f7812a1e7dbfdfd1f773fdf7fffd0786ffff6048c3e5799ee7b2b8727c188e0f8be1c3f9dc155700c31a038696a8aac0d0da20aa916aa21730b4b934bef9c4572efca86f1ef98abfe59b4953c957fca76f5aa13df48722a1dc479bd097aff8b58f42f1157ff651a48f4ef115ffcd47a5f80c3feba3467186df001f1df219fe1b1f751267f80bf0d1253ec34f808f02c5197e183e6ac467f86d3eea1367f85ff8e6159fe177e19b4b7186bfe69b537c869fe69b4871867f00df84e233fc02f8e62bcef0cf7cb389cff0afbe19146738beaa1a7156a8215d7ec692fca600425494fca667be9a5c7eac8ab3acf84d4f67d444d2e5afaedac3362e7f2de22c2e6a02c9e5af3fce3ae2598d1a92b3420772209f229a147e2d499be22c49c6e5d7a8384bc959d5a87da45c5af215ff019c589e1b3927ca8418d165a4cbdf585200be1d162a8450e4d51a42236887560b0f806fa79b416ba787d962a2ea1f229b68b5003251353883e6125f6140975f379c412d7c1b14965e2deea40b497a0ac611e42c55ffdc36f28d04a893f8732f71561397f9b8d5af1a28e23785be193497f88adf8521981f5b8a98958825f16354ba9fcb2c0c49f1c8f8008c100518447fb79e9204c5a2acf315602c5169d58f23426beb6e87e462c738935cde431125f738fbc71521ce0a717680607143ae4e9f9121e6a1604346fa2a2f86ed598006340d04b86103baa3a1000de88f4b48c18f4fab7e2a245af4c3a16db8c67fbe0ac3e8b7cb6ff88b2597cbb5839159c4034e93eb7de47a27b9de412d84d189e3ac909568ae53813354745d48628432a4a04284255cb9e2847703264562e0ba82074a7e384b95e2eb4afd1c71f9708edb308e397f827f65be46c9fefde923edf26f1f50c5a31f7ca10aebc9404a3b9df3556cf7e973322dc2ddddddddb338536f2536e9f42853736a72cae83e3b18946d1560504f6c1be7ee1387153dba4b32b68e2edc081351747ab6bbd1822ec0a05c98fc61777d6274caa96d33ab98b66d5a56312029e737e58c4e85c0af8c620f03030313314ab34e677e8675614b73db8903e52a36ba54f0b2e2c85adf62ae5bf96715bfb19957808e50246a74ab283db9feb489d39e2b549c059344a110e960e8ba8a065123d79ffe34418b5c7f8f4691c8a5ebba7c85d289b42297a6d00c9a5466d28472fde750388b241df94b24539644d75c9282a4c43cba369ccc24d77f020571a791eb3f7d9c959a2ea94445c9095e3e94528c9c4583e8babf14dac1a9c723d2d00bca75fb11e8fac722d73ffa2471fd4a1243e894f86143d2834bec8111246103a98007bd84a8a11c1d317981fac175d7c2dd1d09e66d743a30d25ed5d7e87454525e8eccb2f1a94ec786b4358eaeacf182256e8d1a2f90c1ad91c5adf12f9d4e8d4f3d8d4e27255f9838e2bebc4ba7f342e3519d0e0d1729d7e55b3a1d1714ea593a1d94056f4b12275858de763a2c568a7b7a3eaaf1daf73a1d6be2c28485c9d4c23599deb6c0886bfa540b96704dff2e80e29a9ec3b82b7eddd8fe3886f5a278de013c1d37bc71bd6725d78be17a5ed10a92aeb7840dae0724c4f580acb8dedbb06005d77baed3f17034ee198bcbbdd6e97075ab3057abb99af696e86a9f5201d0d5902871b58f91f5ab12546e55e2885b6dcca54a49ec40ba2e4cc380d13836296963b383146c787c61c1854bd7e9c4d6a484e122092257be4d82082484ae7c9c259a43e5b8218c0ccd0d1424418514f4a440084790b8fe3647c4b8fe1b0e1131526e084374431a23c008c2f5af44d78d20a1e8881ea06089eb361c17450b21a4e464e5e4175d705ef01607b8210fbd7e7470fd53442871fd9f882ad77f65e3e2a222bc28324268882938510e223051c40727583031458aed14521c599b2d6cf83f041200b094bb7fcaa344f9e2baff0c35b8bbbbb7445d59802be5db21622044195702c15c08e12344124f2940091bca97095141b0e03a16412cdd940672700431b8a84190107cd00a2d94288040c50c9880b2c3125abef2216960c4dd5d071936b49671f82d0aa20813c74db1c3949cac5cdf282a9a3b80eb406071fd5349aeff1715d9011049246783aa52e4b344861219421a8e18aedbafcadf7d27468bd6ce10ea6a997e080c2d26dcf78e6402d21346ad21a71f7a5aa68f490ca37b2f84de49dfbf21afeb3caeebcf59b9de7326ee6f802c2dcdbb4997326eb1d43e4964f4144caa3f108473fc00e2f255cc8d20901d1d7c35e39c520a217f62e453b2421b1b966c9ca57a191f5818fd0fff96f277f895dcc9d039f40a08e38081b9425e871d6771df427c65a57f64ffe0954448e8cad0edee7e45203a2809897243aebbbb63ec64e8746c7777ff308e13e34082713810e348a27dc76ee2cd02ce51035117b9e0f6ff601c1caff709e9f8caed165f26e2161701f1553f0280b061ff2cf98d7442df3412a0b689373d620d9de347bfd0df2986d2af1e6aa23ee22b23cd5dfc4ef2a3733411fc427fff93db8f8161aac9048de09aee96615e071b0ad7747ffbf403d1e1c5b0f2a7c6d2c637dc53eccbb46d8678c381118c6005999929c81cda09e6f04c7f10204088a49cc16fec528f0b70400827b1122ff595f8f287166d2c63c32e83cd0db273fd77ac6e101d263739bff17e5c2ed70e4f83135d2875e3eb8c27aed70d1d379ef1e4c6761ed85c62c5f1c0a2605e66157f624186b4135fc9168af5f9c1f87a79bbc7167e94a291c78e4a48314955b9787474c338a57677c757bc69577c5df99f112f57bc212232324242ea577f446cd7b813ecc135f2a351bc81003b18c6215c1991aebc911172b95c49ce925772d10d964829a59c614af6c82e641bb96dd448fd6a2229650f29a591115292a3a2a3a42dacf28ad279e504996b686f98f36a3e1d01c5c0e69a49758861a3e4308e46c606162685695e96da4c1e011cd07d2c9c0de799f9da67593ac0726373cd6c7d41d8d8cfa1acd52186e5b6c964a374be874e29a534c810e9dd43dabd08efaf71ede55fc165437ba75049228a3d37b4b755edaf6cacf51bd0282563a383caf5efb9fe30d757d76fe0bc66ec7156c8a958d621bbb2a99f31baf9e564fef8ddddddcd3857825be48e2c29ed2080b528b88a33be8a33fe71462855832233db54cd296d92bbfb0c86aebbbbbbfb94d15a9c5f3561639990e3b2aae5c05a1d33331bf588566efd809e7052b3ea1352a12be4ac9e5a8ddcfe3172e40616cce695ac97943de28db7e6bb5088ddf8f125e3e8627cd4e41cd8472bae7813932a15bb14ad00dd0ed948e836f631e9b6a4e09347f00b328904f215d7f47b5a8faf7c8af8ea07d34ec035fdda0efc42076aae2b4ff4dc1460df2f8fe01c18e3e8a8cb592afb7db33a91e20df58933f3c85934bea795a449e5f64cb29f45f9aa2d56ab4df5572a749bc5c9135fb5f71c8d9c17a43327d96bc857edc518b7edab4834d736543728d605f60486cdac80a0de8ea31c0d532ecd88f6f36d443436a338d3bff454526f63fcc186d9d0edcf96943e22fe9dd62d74911889d995272cf61bc6759f099341c9c6e72ba7fc1cb172253617d5a0ca8d496e7f9d65595479dd8ec8830de50fc8813860a02a7befb1a7a02a03793492cb75b3a226456e7cef93485a1a91477cf505615d3db1879f32acf7dc7b2008fa8634abd2d3bdf859d6d12ccbb22ceb1ef3ba2f1452c557d915ba59c9ae30107e6493183397b33adcacfc382bdcaedcee71566b2ecdc8edcfb22cbbe22c150f1ce2d3cd8ab3e2ab68f82881d4d700774a40e4039f568d1adf8e8bd10c9604b57654c8429e9ba59e497c158ff9d9cfcfe2973df679affa9864df7d34c88b65f1b38883e7bd0d12b0f1309d8fd4ab9ebb0ad87898dfa9f12aec73629c355400550ff3ed7455b47686c8265a2a90c9fc1e668b89fcd4978a63d83095bd7c955d7116d5d168f716e5d1c7bc20bd0d6d449acb57bd81db4b870a1be4ac707b4949e2ac304bc2348c3e76310da3b4f3ba0886345d06ae9cd8303e8679e00f9adb6d589681a1f7e10f9a4b1fdbbacfb22ceb3e217d3bc0483637f204ddac0334b703431f370371f0befb1886c435fe4e9e3439f2b354e5c70c3432ee225ac970bce22befb9fe6599a6454dd3346ff64cad7e4d0443dab12d647c15636a065bce10510ed73057798a0d4c84c3358c6174ca8ca377a6b5fab3eea883cd654bc9d40b79825a76778cad84ca490c7035cada303bfaa62aad337ad75ad976164d69a72ea554be4b4abb8bf44f944f67f4d902efd857b23a18fe90717777a712c3b08861de30128bcac9182b27696c565cc3cc546218d73065c2b55360e3644c5d69a53f8d2b20be72b62225a5bf514a299592c69650b883bd8028d8f650ca60db3cc69629ce7afff41839d59376196b1aa6b596c5c6bec1f00dfbe61efb55594aa9c3149b92a337c5fcc80a2ecbad7cc534753a779cc0d63a9225bb37096e8332bd64eb768f51ca392926847b609fd6c3e6068db66d1cd77d1e0d7b2693b5a7130b4b4b0bca85512d3468d06039599347a3a3c16d1a0d1a3468d0a0e1bd8217f25c6c88cddddbddddddbddd5dc99327bd83ede7a21e0c5d7ef636be2c137b28d9a51b04bb2060e938cfd471de2e87412a1523834f38810a0ca4b08326bc788288d203932b45486942119a0b1ebc954a092944456105a90807464f82ae73a8a8c44f195c7fbe7c3a626b68200c841bf2d8dc30105a31c638c154ab5cd0010f1146d840064f3c21f484245a0270a2821614210b25508868c5b7898f13bfbf9833830d4e44c246c311292bd7f8cfd9fd7a02e597209197e5e5d7112a9a073b2fbf8e0cdd5e6d3d98d87e8ef92646e60f0492067bf963e490cfb8518a7e60c4c5ee6006594a17592ed201941ba6b84f712e1685f22366e493ad79b07eb9e80914b79f3d90c68dfc7c644b7efc7cd8968cafa241bb110c62ba4a649c7179177f73021bb287edea1e604120af0439320c9f7371631de4382a2b9575522aa394d22ec9176c5734018a14188d4d0dce6af099f808a8c2fa87cf835f1f087278a15f48eaa27e5c9f2fa4de13d7f4b3841db8fe11043ee39d1eb8fe51ce1067e2a752e10360b8f367a895fbbb59b7f428683d70ba130ce97726e5e7724f1ce2707d9eaefc420f844036c95da357a95f1076e396964f1eb9941b7fc3381dd9c457119bd8e4b06eadbb7bca204de4abd790afa2d3e0f21544826e3b8bafe8c1c8955df050c4b7b85bd765339b997581ad95527ac311c0bc7204b4645f23f5f2aca4e5b1ef79ae7cc59b160b2859c2ca9470b397427126f6f0807a159e87978771f9159e87d4c77c0f0f34dec6f350e3559fe3312ccfd35a61856f791f2b7ccbcf6f8979167087e5637ea7e557789e96cac6b7bc0fd5b3bc8d6f79984f35ff9fa7a5c2a7c2c3cc870177984cd007cc3fb8a39a9f8a33f1795a30bfa39a600e3efe3ffb1fb8b3f3fdf73c2d159ea745812eb8c5f2618a05e4560b98136d7c3cfdc98f27e6e3960aaa8fa7c55d064a27be8a4238b014bc72e357d0abf82ac6f73a5ff255fc8f814d3a7296f64fc19086e3c758f273cbf4f386db0fde0cf43e279ebe9590796de4736ffac21f20587dd5bd04193c49b12177e9763bee7b6c75e42ba308448cd2c867e2d79b74e36fa72258f9a12fad2e4eadccd208c9593ee44f3ce38f6fe64f401f22f2553cf25544f255f4544fecd2a5f1353ef5f1e34fbc79799768e3735c7e7fa6eb52b01bc9b0215b39eab8a2f98173f9a7cb196a90fd71e64f7c35e4abf82c1d8e79312267b57c7c87e2372c1fdf9f506765a092968f6fe3cbe9a5d4d72f5f27c5997e1a9fcbd7545e3566b0d21262c045142a18030560e800350102a98820caf8c10d9b96af5ddfced73e3e135d5862df0a8e0e5fc5f8d1153ffac4f7a5f86ec5f2989c8524aafeee795aaa06abaa77540df6e8e19ea7c537ee34e2b239f14a7ac30724cec8f8e33d131f1db6813eb6f7c09d0dc401651756ce1067240f32acaa9f2ff63b4c7c6c339a7c5506f6e8e138538738e38c1607ee8040e24c0d43586ef19416b7787e30025112111640dcaa81423e10f93a60d2852180c8d741fe0df23910c9d000077ab0dd403f847de9a557c523ceab5deddac0e05cc31f2f0b7793d15df609b6ed003188eedd2eeb27a58c31a66e8ccc2a1d5416b886dfc643771abd4241299da8e64955734e965f8e8ca02ac618670ed7b89c324e49f9e671b22fc77e9c12ab5db77feeb72f27fb727272fa552d5162298ccefa548239180f792398d38c83b3ee5ca0ea111f86b06fc8ee2da58c37ee94ad8993a0254880da484ffbe870e5c7d20d537c20cd00855f36376456a98d79081e25ad523236e59471fbd91a036b4d9a001fbca0d8c733f2bd4fc270e5034e5c8d2f03377ecfc8d73e79f2c04962555a1d6360b50a65cec270582b318e9408bae215f483a2a0278470aeb206e1c867588acff09d2108537c866f68eb0c8a825ee083a023a92a991e71020208243c241f6b4617c5657a02109c1654bc29426c40dd1642685bbcb8170a322e5c5b1329a84740da0f490c81694194fd40c408bac54f15c3c84472827d81027964447d281aa28b233ed8008928484928310317463eb8928812e480a09fd4136814db72f90a238888c208204c4d58152e5f514418d80daceaf2154568c1832286682e5f0144181c6af36f5e6c93de2c2506c66fde206d52b1c03858e09a7e8e946eb1dfb9660eb912ac5cd3fef99591a937a7bcacb4d24a2badb4ca9777337593e6c7e8c9fee0a1db447c4004fa4bae10fdea9b3a9d29849ace38e30ca1202440493c1d279fa1162431728f743847faa7a77dba0877a305a9a808456ef7e870a55d9b8d8b13519c68970e3f96aa68342f2da812832a3f6e984225fbb1a272830f24295506c689138c20e5d28772b16934838e210a2343451149e68d3b7fa40410c5892836322b1af903550024a0202185d139a94dc019679c51314a29057f70519c88e244cff7ca679c71c619777e7cfde3c1fa94b4b18c4dfc554cc56a6badab7853fbebeeeeeed621a3153b9d1e6d85283e1191911112525252fc8804de893bb1b0d8cfde9eacb5d65eb9e10b36a65ee1082432c4144f66cd8dff2db04c0423cb0d6c8c0b0085109a2e0686fc032178b044a450ba210f41ca383f185f7da88d3998d5ea3f95923f6c2e865db118c617958a80b7b8e70e02dde2c08f334736e46e6a8b33228027a026af33994c26a634d57de8f2a6706853d8ea79a6af9ff77dd9a7e28d0d48bdd57e6202b5acb910c2e2d2298062976591abcef20c87fa5903ea67cfdd5393d775b7a7936d7d4d9f7d3af5bd6f077f34b57dfd62aa3061187632795df644da1053d66ea786825fa0cf7d8d035ed1ef233165ada99d5861fb3b2c0b28846effe9e35bc3b81af7a6af2f0efd5a37ed3b7d3b893736f00cfd5a2dd28671b4629f71f7800dec303086c86261bc2e9f5ca6164443b76a41a4830af6cb5732f86d27fdc47e7fd84e345ab95aebf61bcae47596cbdef32a8aab18cb6d73a9bd834bdfc6acebfc669f659935799dd5baae03996b34d07626af63e1b62a946ed8916b167c08b90f07735c03eec0b92ee3b0219242e79c734e1a63a435c6186394314e3a8798327ae6c419f68954c1a654c1a664f18394c54fd1c5ac40f229180e85320385fd10ef29417d8ef7e460fca68749cbf7f02d262c95dfa25a3e25a867f99478b77d7f3156d049b96dcb718a75d7526b1653c5b73d773998beebbaafb66cd8e953e2f2d5c5a236cc095233719ef7396ed2d16470d998a3ade35e3ea5db1773d49df62ddff62c1cf8821ee39afaf46d5f3f31a256c3d0bc6fcb40c9c3b6615f73936bb28f2fc7d77302a6c4e53fc737bfb1e39e3bc9814cb8f4d594a05efbea133ef6994de3bc260c5dbe99f76db5c7e338cf0a29375cc1731a53b0b134321c5706e7364f6c4e27938c9cc9f4398e7d31566cdd59f04d5a3d9db24ec7f461ef9de9abb08f61d8c9eb38fbf1c699be9823aeb3ddaad3b1e0fb8abee9937182edc73a13184364b1ef03a30949973b1dcbb96029188feb3afb58156650b9db630c30c308bce2cbbcc23670e52b2a835fef39ef543b1d6cabdc6f1e675b4e5ec765590b4b96711cd7751cc7b170a7ced6acd3c1b6ba612c9c8c971343eeda8f4d9ce94d2693f53acef4d99b6c4b8be94d26d3f7a74c29ce04a5c80d5fb0f1da46105290c1b8e78ef33c93e7b1f6dbc641b25a6b9d917d1564fb1d7cb12ccbb21cbaaf5fe5beac8abb9d2a1773c45bf65996615ba66926afe3b28f6f57511be792bd4c977d1f184b53b85bc7b9f72edad73a19a88028aced6490dd8e1a57fb0d65b32ccb32d7be2fd6f1a871356fdbb68cb5d6b46e190f45bf253bc2f68736190bd745298274b7c7be3b1d0a7861e3e528458e2eb681385c773bb4cfbe3a4b039bbb2867315f16b65bf780ec3517ee85d3b0e73eeceb677d51a76f397d0fdfb2bf35d7b13c0b68136728fdd3a7c367e85b1ebaf4412376455375aac65571e5868c455f231a6070350a18cb280465e62d7aa68ef33c93e739cdb26c7a5763aaa8314719f62d6d1f57bffa83c53e94973218436469f604d7e41afa9bacdf12cdb4ecb32fc68aad5e1106958b7da00f36445dfaa84b5fe3b84aa474c3159a316cfb42cfebb8e6eabe6915a3dd10a060e5cb2138660adb5328dd7005bbe960524e1d8c8bb1020145d8bea96ef96ddde1cc2a9d5162da469ff6a51e63ab66ec1da965aa1a63cf3927d6145cd28efac470f11dd817be1189978fc448ba31baf4a48017965e3e12a38a2b7f7610f02106d29c11f0218611cf30ede88523b8118499d3376f89cd85f531c1f6e523268c2e05bcb0d8e52326a6b8d89d208cb352bee241041b59a708ca391dc3689078390c9bf3a38c11e3b155aeeac86e8e3e064efa746afd7db58ec7cb6d300cc1b66dd2e39a71b0773a926bda0c2ec61a2386450cfbe86f9182a0f7d65d12b6c992f94a4e5e1a33cebd56cedfadafbad99979be8c326a5dc7a3c6ad601882fb80e9dd8e9e22ddc9e0f2c32e5f71822b7775f90a138c7137eddd43fefaeeec72e732977dfc541ccda673fde8d72fdeee7670193708d741bfdad7777b94b338e6206c940bd21bcb4e062ea3d62f62d659d62d13eb731594b57ecc359e6d9d83313db0fc1b97824969dac71715f6757fce572c51180e0ea2381e47b0533e81763a8e753a7eb2dd0ef9f3a9d3a691cefa1b570c9b5877b7e08521f0c762882ca394e04191d795d7cb9f4bbd90dcf8302996cf161f07e70ad20d39999249574a299feb2ff8e3e1850de57b648ec1f287f2f6adcf3a1b5f9631983d137f31318c524c62a818a34cc293255588179111d2f3ccca06270b97cfcf114e020a12fa2e36e6f921cc0de598e3631fd1fcfc6bf7185f3edb70ef303697d269689f52c8f4789d439e16d4eadd3db894d2a806aea1b15971b632e7853b1106eeee1d6394724e1486b2be42655c56b16da37393d1b7ded8f48454b77b9c1eb09ce564f3dc40b77777777777ecee6e54cad686d9d117e5ab1b0eb90d528952ba7b6cf724b6cdbd31be89c0c6cc298f314a0ea5432dc5b0aff6e7c357ccdbb6755ded3caf4da6cf9e4e2716aea50525dbc5c5856b1a9d8ebbbb6b40e9babcbcbca05e5a5e5e5e5e585e4ed6e475dccbcba6bd64157b7979a1f345c6176f00d42a16c57944a5ac508cab35cb7a685aa7c3715cc7793ad69a4ea793773a9d4ea729a39f9a6bd022bd8028d8f8dd2d04d5a88e1c8de0aa579f714e9f5d85d8304ba1158d8ccc8a46862d8aa3184631cc562d7a67436c9bc7185b2e8041eed9d30b792ed032ca29039b55e524573927a52bb82cd7aa5339c3688d2c60c932301ea7cf397b72e685256862b3ee517e1387d28e8776a20ca026a8444d1765410a159a110800000005f314002020100c87c462b1582c0e2451770f14800c7c9644764e9ec9a35912e4300a21620c2084184000016300466868e20008d1fa5ed27a2b8fc638d2ffbb97ae90893ed302ad3759b90b10ad5797f82aedc1c166356a6725cfe703151313d3f87ddc38e3d4e22fafb76fff40780e4bf73bb886f6d83cd046caf76aa29f109ef4e6d6eea6ec0d344015cd9b9802e6c227cc59ba26d86d846a06dbad13b728bf2975d1ed48956cc9a4d5e54ff747bff643b9014e9c1c44da6a2003dba449b7c070f7bfc90f63222cfa2f9573349119d69d116d38a037ffbfb9ad72aaef85ef11ebabbdd803b526ac2a41fd3ede6cbc1309301b18b349095252534adeba47c71b3d62d46240175e81997c78b8cd6ac09424493ab24e878b230702b30971b9e5b580a7fd1563278ce4afb349efadab9363c8cb5be8fd12146213da09ba66fb786b0da2249f9397ac485f0a0454bb6f367fe40a90b66ee7bb8cae4a99a931244e8a24b365640ae6cec325579d0f762bf38b554d36ee9a659648d7262c07d47a74f951d89e3701005090dbc8afe3274ff7c79f761218486d1eb3d9ce2cebee387edce15ea982eecee610113603bbe302ca830419d8b65a2cc81860dd73c0a59acb5130cdef26fc9701b4ea16233c6f44b995ca7929c08e700c3f371cbf76cb5685b636dccdcd3b050b4a11e7239b7cdb11d1140a86695c2db26fa478a91bb6813949350e145cf58373e6afff9a413801ac73d1df4d58f201107276d8eb9a893918865bb11a2ae8a6325ee25a1473bf86189c69d00861202c480b448f0fc728b9ec6a29ddcbb817347fb0b2d7c9b2dc0865708cb90ab16faf7029c91339960c12440500e56c3719b3ae180e9c9702b6156b317e532c4f64dea74e55e6a0f4dfe21a4de64fd7c5f0fcb89d30c67a23a14375579a44ab3335450aa61e9cb7aed2e456f403ad93e18749cef53f2c6681c4262a3d7fac04de1ac31e0c6268dd8e2cd8fdc8df42952b4b7bbdc276eaf33a65348f440b6eb7b66d5a5b68b1aab1212e9f44a88027a2cd516f6cf1835daf6711d89a23c9171f06b685d07217760597cba942ee5318f1ea650ae078b1c860acaa2081e2f75c555c3d2dd36d5f3a9ddb9bf787de7f751446abf441962954ec2d49ad013bb661a495f4dbe300759744ee56440891af60367abc31f591bde836089e4080b4d1a662884f9269062e73ae6090064a85be5e89687680a73330dafc891345f3c0ef85646de8581858acfb9205d13e5787e751d5556199914a4e3beb885a156d273b397eaa42467f8d66578742bf6ca0c71e307c04b2114bf92f3a24f06d2b90c56e3630f5e3dc5839e30c12f1520b895695a493a48549ba09ecb38ae85c7c2c2e9b619f23f4081d128f5b80030fbebe7168c060fb5469a0a94175f85149bc1e06540d3c21ab8840177c06c86d9da65252e2a3fbf90397ddc29d717f8f2402d35496dd2c9cc0954e970e26dd836789c8ae5d8e6858418166375bd35ff412dfc9901e56aeaf0c71d9869b088a55c41528a16c0651d70ffb63520ea98ebfff324a42d6757bf4933cafe964152c64243b23f7dfa4d7eca95c41478a5c8da292c76a56af6d0432bd7c9f9eda015fe299d46a1b3b41e4623ee8130f724c7b6f24ae4f3c2a6e6c84f0b7cb01d54d073ee57862754e0f75f533fefcafe822db010683453c41572882586a37a7d17887f12e0afa7af5e94bd96b54c83f0d19eef8e9e5e239c3889bff0cdd905b1925d081d7c044f8c0c307ba776929e2012850f8a50c91d0210a736ed3101956a699cbfd57817ab158d84250481095d66ccad29bf2845c6c6589586bdb6bb0c864760ea2668f4c02b27bb5147562d6f6ad981376204371536a85a28a9e005cb7c98e0d079d2239a9445c20f220e10f048a15bafd2cca044cd4a76c1844189951a36a35a9ffc287a889f6f1565fa5fc4246f77c1ea10a1b2fc950008e1eb68750235ac76b82030dfc2a8439c68d75cb3f240b22d137b28e9586cd03e01de90d1db5879df7ed58834832af761eadd5409eeff4fdfa5657522238726db637a127ffcce4d36778157955bf5212f3403d73c4423eefba428e142c5eceab3e1de35f4c8f6a3485615a04ce25924d5995f63ea4a3e564f0cf49a6e2a56d4de19976cec68ac451cd685bc50c2db66870747a5104dd190b1896ee22a486c2600f7f0b18d1c9b489dcdd5b987de2477444508b048cf4291f6526ad8e1def12e9861851b5b1ec5eb980f25dd5c74801df0cb54b86d1cf45dc82584c3f03d210c858e040a2cd7d17d47fc161d4f0b7bb6a913f6291d1bf8c1247d2225717108c1ea6f841f93820c94d5743de753c421fbb1e228a57e2a214e896132e2216e48ab881d6b4880963a6ce5a3f82a6b312ef8f7972aac32c411f48e601ad164b021df94a3df5a70b1d82d9b5c932f3db30791ea10729f51ad8fa6c0d834f1c758395183a7fa9ed5d4ffe0cda55647e8ad304e4cb1a7bd231661dd4da68c97b6e106947b9b80a101d13d7465e29997c8dcbdbe9e5d1b619ad7562b523d9facadc349b4cf50165a29326b768b635abfd280c421cb410ffca8b908029f7e92c56b529898058f8c210cfabb6f53b85ae7d8ec49ba6d244ad3c32d94cbd3ee7b4c1f13d198adb2e378b0c0ff4dddd8518e2867484bf05d1267c039b8916782a150843352cc2bd9ac50dd6ae8a2ee314038739049348669f27280140e51d8c0fde26eff54f2fb7c9ebcf0e368792473f94fc33052dc2690870fea17f526cd6ce6973a489efa88a0dcc4bad1bf7bf500c2d922e19c05ad8251d67485f713219d76887e55568d826254a2a3a5e7ec9d094896bce2638c1f9b7b6ed8b445e81ab51c8de447a2ab54ccc9b95bd9820ca8e57d3c89c0a13b56f3f1eaf6324218018fbea6eff082c580036cc99941abcfbd189baaaab5b51364be01b3cb3b28f97a69ddf003603126c81c6f60298eadf97a2ed6d4ebdead6a9b1f4ba521293acd1712e91b7420707efdf3ac5526ad05588607f3abaa457125970cbfc4649a3b2460e5c7a51dddaf85503ae96af7dbcf501a7da871d0736eb513b29d9cf873dd13542c26709255b50b3bd24848a2c217ec980c4201bd985bcd6cc640993f07b74b12c5788fc1e9598e680e16ac74e08ee500b11188574aee1255e171c4523ba39035892eb23b08b0d583c99d30e751354c64fb13ff0de5431d65ad68f68cc8a69bb4e8936e49ce2d5c517a8190f2e15a74e033da2a3eba77b6e8fa74334e44c4fe08fb80d311b0c1d2c965ded21eb1e0bef7c4ad4f714cf759ef7684baf6a44d20eb09d9a8dc6fae4642426479e26ad79abd3164500a668ad2e3cb575f47b30b31fb6bf5c9602f568e5cba3479cc852e0e4a91ee07394b326175a865080cafd30d554c63509f832cef5b80733ecb22c32d0e0c6fd5021f6a1f1a31d2d805d403bd04cf3a0a4a09ba8d786fb73816f8a02d83e7ef36b603a88f129d8ca9892f9926d1918d0bd09d3a714ae8e6576724a51dc82737c679d7d5b670dfa1e6d92eacedf23e4781460acfc28c953a24193399e54c8c8b47c687451f1af64521ef4aa040cce05c718b2aac7d4c0637f84e839dddc731cde7f65ebf5037d182ea4598d59d9caf90f2b5050644d16b8333c8aacf097457055040df425c263025c40a9eeb871dfac1e745eeca95d06bdebaf932b1969c72da32a28cdf8faec25814fe7b28935e3e64b4e21d1c75997c00e4ea6676c5a6e1c3b90a1b2c248273179dc49548af1e84c27353e34c4007894d2679261aa879ab7d2b44906f7dd63cca41280497a07eeb766bc4073b6854f4d5a76c7932e70b39a3c5d5f8ffe0b2a534b2b9bb135a5b57a1673c3d50be11a80710c8cfdc1c9f15f40d92cf6537e41a745583e1429269be0b4ef64fdc090a732de80943cfb7a585459ac0945208e0a87688306ff347a49cdd0266f4b63c0c4ac93b1502407febcfcb333e564869e2c23ea65dc2b02ba5768f02f9157e26f3323acac30c118a0c9aa8d56dfa32694c9b7f9a737848d804ba8cf7289e2302c7485447eb3aa6c98198f95a0f98ee8f76fd2a354be5563950c84d627077887aa03ee1836284b92f1f00c719631e80ef9a2d3b19708816144d673f4d18418e52950f51029e17b6384df088da6a228906a8c99e6f6bf3a5d0c8f8707d78efa73bd1e086d7ddb5a4525f4f9e44d97b67224c455d1a4f3af21797a4a251c628040abc42dfef085deb1ecb319e5bca96396c6f7f56cebb9e8861451b05c2eb9ea4c98c356da3ff924d6c9dc7cc73f8f86b6abf39abe4a506164b0836384987fab00c7f8a13aded2aa3b03feed8c90ab9fc73327d28927d2042b2b57a4d3960b1e06f5dab5ea11a172c556ed1aff91472f76fdef8573293b908119936ee0f4dc7506d7847fd160e3999d0d876215b1701327e7f5b64d7785327fcfc0687415fa7b2d0f9861b048920fc6374dee075c54c9320da0497c9e4d8fecfbae6b81ff63484048e3b5d14e56c241b51896990e69d3e18696c726d1378a8163ebba548ae96211f74fd9756c7ec654ea29969559cd3279392803f78bc5ca5f468e9793f29a4782ec5857154a9141a99c3a8a7295032943857f5261beef51ae5b2ae264d7b3c175b571fdd4b900722173144eb152ae25aafefd0764b786c12a7d883a2bc7338c878473ead28d0d2c014ad9ce84ec0df00b4051aad990a17495fa436d200b7540554a42c43ee0a3bf835583b0248e6005b9c578ea1a9d8a302980626b955f625aacfb0995ea62aca06246552cabbdd20a79f206bbe8986b1c15a00fefeaa66471bfbf3e4c238b063a0c3027bc284c787321cb3f4ff37ff5d4b85d9c977a5524a1c77067f09ed17613baa522c2dfdbc7c44692a96022372302f80ede1c1d9c932ef63c772925d9fada73b2f5121e440f7ff00bf4602a0f1c4bce60d15f30fdfbc13e26d7f5bd8310db4dbd04dfa01e20513c733875e15bedf25f2a1128b37b57c06e0a40ba535d06735dd233afc331e51ecdcd5e975d86eb6878877be8e6041236b9595cf92203e1410e0dfa395857a84cb9ba9815e93bd618e61cfd85519aa947ceecff86a512893be05f5d4027862ea14b155a902e56544a981c96870e531261c1ab6d3f82b3f2b1ab15412c1a1fada9d75ec884eea46b707ae99a31e0d81fd63ce80752b7ca101616a021421d093e0f6145844fb10c57f07ca78266bc734414d74d5b9d3d3a94c56259e2349984e2f60563826131b66562ebe383123739f5b5b7573ddc8e00c484b5a9e64817df2b5dd4bc6603ac0cdefa67d70de99961122895d4ebe38e314e54ea7954907c5643501a8615bc5a13734038c20fdd13b9f3d7b955299c36cd883ecd6fc3073d5bc55f31e180bbd14c327d2af602726890ad0aa41c7fcd2216f45d646c936cd98506b103b68d36cee3b5d325c0a648b2341f047614685f810c8de8aadf5108f793f195692d523bcf7908813450fe295036105ae3a6387804a07293f9fc5c096e1812580d12508813fcbf0395bc249661bc04407e98934bd5c34e65155519fcbc6eebc954aab0d3866291d7dac1f2ed174a76180201896d7cb625916791284115684a8e13b7c953d595bf47bbd584424459bf4da7f71508165c6292750f370d42303b3712c68024c4965958981cda38428c6db083f418ba7b873894b235717cda5693946a078b988d2ac935ea3d0d7e3193b57f9cb3a348b7e957a0f57e0f8fbb33e0f0ce353d8412e6cedcc92908a601183a61ecdc1dd638bd73431548bf7bdc0cec46c501e652119f66136425a0aa85417faf69d22b8ba77fc1516530fc9ca1f50fa4e21af0680c284c3d6c3a3806e77431d75dd8f507bad1f5df12d88062389c4f76e2323f78ce9e5596cbf121b20c0e9500086383c26579a212148489d5347332bdfc2d0ef1729024e6540824305cda365960863b5687fd31050ef8ad36457d88fe5eb3e86e22afa1b8d8e498e0876d783b092af02c71025fa41b11e085e9a2393f8770b560642fc5b7e3cba2641cc47162589057ec6ddf90edd51403983d4b7269f96c63c686e06d72a680b01262b7c32cbc020bbf6623d03424f4ff4ae6212c350b5b8e27a3dc11a86a38fb763b1e263d9d011962177364c8357cc87da9c8c9d9ed1ac3bab14c87909a0eb5a30ccc737e0ee60e2eb00d056ed82efcdf412dbd09c6ee97d05fe10623c414fe81de116c8982df8ee64139bf5567bf74936dfedd3d6cb9b2676baf85422a80c2fcc74918299eb8494e9caf378830199d9205470f9928026af22d158539053a5b1a2056585a6b6913d5cb7991214686bd345aca0e50ae58af58494d0e5c1a8ff472c5521ef733704630bab79c59dc1aad791508ef94261b3a269abdee5711b67bb4637f9812d91346521b300d406746919e39045d9e33aa19bc1042fcf902babc9aecb180be264f61e23c6d2be164310bd3017b740ce38b1e4aac8a1cc97936621541aff8d3769d94d17394997065263bbfa624c0f871fd0077d213d9718898d2697220553023db3432718b502b8ce7f16408ee83ac6c582809dd5f45e61f7848ac82d93e9d7dea0d59dec22a6ca086b751e16e10e095eb8a5383fd5ce639c5899d0e9c950d212f1423d228794b62e0e5d89e963ffacf71c49c0bc2d66281dadc3290ae5ba481a72d61120dae8a562c6f0648fd8906982269da174d0df5f5c14340ec399b29986fcd36a266304db3178815aa82b73d8d0fbe802862c808c33fcfa0c9c032c2b890ce1fbcab379d2e35661df2902e01227346354f56740d1acd1b59ae3fdbb8b92eefbab1ca1daa38c7e646d7b5bfbf6d97d2a7b6934637dbd58a036f3770c03b439fce635168c0facd0322b0270c066d379557d75ddb70e807eacd6d9e2bdd6bf1eeafd49b270025175ed773e0bbb7e4c7e0e23b921170ed646470573b732251bf5ee0b873453f2192352250a4cdcc3b4eff72ce2bff6c4f0289c0e2e928fc1c211a7b92960bf7e65ac975d0cf8c1927c162756e56e21429423984c30413176bf06d24638306450aaf797f0852542465423a23cd8e8f3dd4719de7d35ba408932e8735431462fc99f8dd898548f1f3940cd07fa51c04c72301e7905f51454a11b5a01b9239faa8d3f2e6771a228a5afe5fb6a1a785d8e047935031c8e6650d4b08127d441040443c7f5e8509a76664840a6bb8977a4cbd7401558cad225b9d94f41c2c429d098b4ed8bad1579fbd807d6e8249ac498611c50dfce42a58e053db622e5f0d330bf66f39fa53e233b6f26e603ddedeb5bd2c999ef038af16ae98ea59fdbbe8c7a2f693409f1d45b0932c66da014b31a3b61e86545294aebe0bbf5de740fda3bbba9cd99a1f377913e5846a511c01723214e2b72840b22c69f961ae3b62c0e07228511cd068328fe5ece8d3e933f6a35b2d24f8112808fccfaa34686ce1aa591044849bd2358f01e624f5c75cf6e7b6da3d718e18f5cbd167985442001b75aa2f3456db4b0f1f99d4a36f59be204d81e005186c4beddd84e5771a45bd8e78140c51dab28d429867338b03997562d841e8c319cd71a274609dbd3f30cc8ae9908978f378ed81b9094bf22b1cc5832f29a3d5df94413c40dbc6fbb7d96444aa313d0cfa88f7c24eea8dfe0bcc0c88b14f4836ceaa8cb4c496d85b161dd99a547bc8c35373d899acbdcda6a4230d5ffb937d291fc7ac8f84f199643fd6a980e39ea039309062430f9daaafc4133d0f9ec59bafb25c25e8f82124817ddea5d00258d400738f40fed175cdee02c79de6d1444177b671f7759808dc19989e19dba955ba7c9654143b53be414c4a00b8c8efbb8550b08b8356c4968c692617ba4761d3426c367021e7a25a24d618d9e674d47e83c7b62b8c510f075821a6f0e49825a430e05ff778218a0e28b65c2a900a63d4cfab49a5fe4e12f06e13b53aab8aeca2423c007e52034cfbeaf8d300e1058e814f5265e5884cb545337d110840f24274ca710e837e38dcdd701954d243b38a728a2509e6d63019d6438fea5ef56bae34181d706778cf8fad0ff6fbbf19f24fa8d4be3941275a025ea582b6f89e18a3b856c153113bc94ee955bfde81b097019a6ffd8a52dc28cf3b45f431106b6d7305e0fc69ac9c30194c48074536cb2e08030e5d4d407c9364d904d25716147505340d5e7ee9524ad8c3f4955ac65184fe71bbc8d1f9aa2d2e407273dd8561ccd7547bc000be131a2b8ac2801ea83481e0136d8a7db006951fcc462e7e691707f98eb7410138356d249772c8f482d6603ce0e2d68c6592d613333470a79c3823f9bb908af5ea7acdd99bd43446f6abdda97cc14f496ccadb81593108f868896c9ec6ec852cea45de2b73a06056e6e19012900d25a314844c79385d96530bb36cf1be55a6468accf5781101247b0d2f3d327c5624bbc84af6f625ce7384d8872ef900b90e74a276056c25f7e5dca563cf5c7e164b53a5185a51a8879ffe4d0eb86e1cd3a9a4777dce9c09b9eeeeb5bec712c996609537b6582e2101e73bd7259ada7ea9fc3c1487e91cb0c0af6851177c884b98d87853d3a36d2d0fbf30bd383aecd2010f04da00d7783173a156c22f685aac1f180781e6bc5b8653d66e8623655251f68013002b16c588d6a3d2d6e2ee2ec1eefd4493c1651cd5739f9c219bca45f79eb86f7827e41b392543ddd61b1880dae0ef6b0152c30d10624ad27efdd5b2e2b6ac71594c457554215e02f28368081bccb11e34f0f45004c22afdf71e4d6216a580f632e32165702436c2f0c4b7287bd0ab5466f779573078fbc0153da2c1f3ab0cb0c3bb13d1f726db1af6a35112cb9836858acde46f8847f4f88864f189fc595eb19b6747996901b937321115850168595230523dc782258aa0d0edb7b0cf013ea5884e2e14335d7dbbb8fb9e6be362c58005724144c205d1db8ba0f9ff0f422102ffc5d2f0e30d61e26f8d370b1ce296bd97732e61a04a87ce60639830da88336475145a84ebb7d44999d71a2e54798808a8a0f2dbcef5e77ebe5768a256739b226f5dcce89d3bbdc850645dfabc09bc94fc064f4daa659dfd033bea29cfb54ef6c605d2135c42ca7b91941ad5cd10445dd5ff9828e7bb376b9f67c49255b1215e9a2c74b5d4e241f13e9210d9fcd60733f9d8f5491274c87756d580cb28be86efb0ecb3db8d386196c371998339ca39bea9398f0eae8c5c14bc60624ba1110949949fd82c3a65681c5e44bf4ebe92ad2e01ebff8e9da3091e5cab0a777a1673ca69ccb8c0d63caa157b30a097fe0d7cdbcfa30befccaf2dbd4917cf431d0950ebe294e449624cb34bfdb55ff891cc450beca1b41cb544daf0b70605b1353c0196fe7d8a6c630cadc4f91c6c2bdbe2962d21e9895117b5bf90e3d6eee1d329fe0aa207cb04e354f86b32d806610e0e6d6b95aeaf314bd914503c356598634f4b604e408411c2eaeab087dac4085f6ce39374a7962726ca718680109ab302b52b6fb8eeb1cf90c5c7c6e3863909906ff8cbdf4b3218480f945f2e5261bc8d94509802fb1d8d3471ee3d8037d104f1a8d97050252e2e032c547185045087345b95e40d2683928d9f34940177258b0b26feb136589515233c9356501ae420ccdd01a25321822d0cc31d4bda76c3fc5692016e752f947037d18cd4eeba6dcf4f698eee3898e7d19faa2d740be133c3bceb3ef351b74270fb071988ce3b927702d433fae076f2083fc7c80bd90a5b8bbed18081dd1102bbd8654c3acccaef12d01d5e96d909e804edcdf4713765eb0329bb8a76c0316b84c310872588a141843d23f17c9a58e06c2886d0a3b001ae884a775931e89d801ee940006556d903ec4295c43faff55802a4f0024b296e9359a178f31600d13c9e7d99e83bf8cb2d90deca515b052500e2d1bdcba49b59ab8ee2154bf24e8e8325912b1e5b8b746672b451151005db9a3f0be8b2e2043f03886ad2f0acc2270339b381d09b1160e0e9cd2db81b3b5e89b196d2bbcbccd33f7a5ec6d6cacce67ac1542e063011a3a6c0392715050b855ff1325eb3d781d2f3fa0f0f24cb45d55779c225feca8523a6b983ce9263816efb6a38b6a5b1474c87aa63dc3cf68f7a2b3feb66a869d73f338fe1e15c64ea5c3ccea8d5fab2ec0475d74f6eb11c536d117db918cc83933b959147158ec1722e45a11003f4d1c102913778ba8fc6d2cab30efaef974f5aa6755bd8c5f15237721b199845f0d008d944adf77ffe6b6759c3179a02a10a8e0212a43707bb7125ae991fbf5a4f3ddb42d60920639194deb16835c2c628a0df6d18c070d30a1df8e0f27fa4d7a7380a205a7e59f19d02a23a2bd04a11594383899d43799d04e278fc9e106eff71766ab4564a24b0ddd5b83b061d1e64c448df719964623456ad5560dfb528dc91309a20e152c2162cd107120a718e8a1a2b8899a6b352d6bfaa7a2b6aecb6a1a710f3b2a883c96d5c9cb8f36337b94bca6f617d1911fd900d46dd16f347572b462be6c75f5765253c476963f7058a17e7ea40bc241b733a04b879cca48655b4cd4d2dd24d314f6777d568b8e29d01838d280003d9de501d7b8a5ec904058e37ed8b89b953ed0a8e17e5577d46eb81e544980ee06202dc786475515f1aebf199b2fc9b7b1a820b48de54684f56ddb82f9ea9f45dbdee24fb83d38662d1937e32d6e2803ed5274cc140737e78aa0c5b92ae73ae29c7502ae2ffc8dc17f819c08c0a21f115eca9db51d7c5445be91cf82b5fc8c78dd86f20db8a4164df6d1a62360760c4f10cc5f5d0a45f7b09a44cfc9e8a0596271cce24893e81dbfed63c81be9acde4ca8d443626ee6fffa7a5a8740fa3157c4c353fcec758acd57930af69f9050d334dd7b48015b1933d59fea19b0646cda66fc01bcf3993ea76d9680d60028b62799d1fccc9408af49f584e533ff13cb801e0aa3e000e776a36c040e703ab65e7a9ef64c9e2fab6908d17b948cc1539ea96594f3c3e0adc5ec270661d9d36887188f11c61a0fd9a146de86a65bca264875bed3483b3064e2b2336b398d04f2bfeb5f2cc9aa4217ae9b8a438caa1ca08aa0013a531d66d16641fbd036ae2a2696fa962cce1da06af1f3999c88db6ec8810a3f8ee96e1ac5fdcf82b8de664c62a01a1f494350615034907af16b1ca703aec18d68e9cb1e943ac35cbab5f15961907055a6af86e2d69dd8bdf041daaf8d6c27abc5b327c8f37205fb1ec1310bd3e64b4bafd4aa647ec13a8bce9843a7a7ab17b1f2cc678fc6167222180a6c865ac25c2c46cb39f2e1cfce19207578aa9b7202ab9065a93652967206bbac1d60b5c6cd77be11d07bb16a6252fc4047bf901a4eb0d8f634a788cc3bd14747398aba4d6795773d7360d57745e698fb5c464d973ffef0a8cc1f3a0893f10f32b9ee85fff88e5b1382efcafc8d740e50a3a198d6547c32ab09ceeb0cfce9494ee6aa8af9f8a2971522ad0c87db880f3e4823a525669b943301b94f4d974310ccf7085de738d1496cd56bf380d63936d01ce27b92538380dd282e0b30da30675314f2f53295ca9fd1b9e5246d6c9f0a44b1c0b390031d8e70a3c3cceff2734e877e44016203206f0c490c78b5562f947a72f8deec505612629fc3525058f4b596c64db3702d05ee311bcdcc04f81451124a60e9909eec077f9be96972be98036b0a67274a0b5e3fc79c47a69050e74a0f3f91909723b33876164e4fbc14e0acb4f2fc872be08a0894c23b40cd85e58cf5f9803be09c89d6e43bfb802aa7f7ba4a1fdf0620087989896e6af562d5197aee2079ac6bac76cb71bc0d260d71fae1d44e74288c0b94911f8ebb166f4ead58404f93507c7f93e1daea61197a11e7f8426d162d6cabc786b3b46a5d58d1e0e5f7feb89209fd5cb24fb9e20c87d1480bc3197ebf72c1438001716e8dd76bfbbe216db737d24862154e3fbcbf813fd152539d885e6bd2742e1d086d05dacb30b54e2ec93eac1dbf5888c1a690345f852ad099453db4f288552c4e5e050f2e5f025b83e538b29c1fb9056d49720a5e7ee97d9e96c392f66e194af817da3f3307708eff6afa8e4a0685fbdbf62cc465f9a677f81284764b6b2995b889a0ba13ecbb2613a187a32db30ba46fb33cf024fa9c92c22230753446815fbf928dc896db26819944341b076e82412e5017e66ea83e6309782519958b6fbba8198509c167b8652dbf4b69cf6064b0c030fc3c59e1997baacb5eb47f1bb0aad45fd74ead6d2f9bd91cafc4781d1c6ffaf31906e84a88b82a8876461f2c12c7c3ff92914fcd8cc67bd958cf834f5e26aec455073c26cd4248d8d72dce47e642db621d574ee98c6d87f220cf13bdf75c708643380200a293da243ac7628a641a09ab0dd96b5bba889716d1d69f5b2583005d78692d8cf272a26eb5626d1b52409077f2706b6386748c6fb5c6612d0101b2c5219c6a47b6f539928e7878b6712d45d3ee27f0865c44a0603d4f9c9e2f37a1e483b648b1ae85071d809b2de10bec4ff2c384cfe838b424be5fca3512f96f2f3287af53417c4819a986b42e420400b81ac7c7543f2022c833b9fa789e7231c807833931b62b4b2e88d281f6f59ce12de5967ecff57605a6cb0649b17a8713c15f813ce7e39b606c5c9e02272c0b106a3dfd4c2b3c04e65afdc2b59bd81d7caf2d738143dff38140c6795909d32d6968eeaa9ab0e4c747a54d27ed1f63eff5852554c790012da563928ce197a79dde2f9c8ff914d02f14a00fabf943a620bb472dcb23b55ae3c3d6b5f3215b93849c8e1baf6cbbcb55361e55eec4ac8cf8a760b95abdc285d07045fc7d58c3cdf20da43ff8fa8843d34cccf66a4322aa1b9692d2f0bf3239a19e14213f5d9623dd6f22f567af169a6cd3758d66bdbbf4199f654d754903af63eb556699f733b13948c013f117019b264c4c82935f65d89c7adc919b50fb1151fa1edc8e96a7d64acbafa60f890e9f6703f4161f3455819d09180ef920643e551222b853954f9e6d34ea61ecd10c33f7ba1f3edd6256c978b293027b203f838f3f85e27ee3f3d74971f6b186b149aa7be85297d967f79808456dfa4fdb1d646e8fdacd3f1289269cb0b3d0b84f17e0ec908ca9c16fbfa4a436895c51c5f42fdeb1e2b8487cfd56dbc20605b4fbceccbd76b2f8d34b184b1957e9be651ba2a2ac18b48a508955b5228a26886d40d4dddadabc7de8cd401db34e94a3fdab582defc265d47f12355a4996deaab024007c41deecf38dfd2afb96447fabc9860f43b0cdd3606bb4346c8f9ba77f7ee4ad7c83ba8c6457d6ef59aa5502680fbdf194c5d287bf2d68eea0c861657b5dcfe5e43d07d176402d83b22788b91fcd0342cdb772ee8376289eb88ee9e6b2228df668970ea6eace8ae02b8966bb69f35d1858b0a118d035a1d060a8866202288c6fcd3e5a70526eabc9973ad396485411433930ae546b86b903174beef2deb5193fe7386d77c786c2eeba2b8fcf951bfceb077fcd769da0c1958c5cc257b1a0adc9c6268c31819e67dd5213db1adac95842851ebce4e84e802800e600d0ecda9262d70fa5005c4c028ade25a90d9f1c78f62326b548ebfb4fa6e73d57cf72f6b9495ffefbb491d1c26e1060e0cb81316012080be9c80ea18dbcf19036bab795af6a3673f6c56dc3058f8e6833e0019cc53ead8b2d12b0ad2f8b8c02e7c21c1dace3c0e83b23d96014d9f358701c03de9ccbfd14ae0977e6ba437e1f4966470894cc1b886ddbd9649c683c816bf06915c8406c2e3ecd58e5f80741bdf2aa9cf136708894787f97b7470417551f3b481ece58eae894e0ba607c997d9e62d87f307d23551413a12dcb08147f2637626e2f997ffb182e0504ce19b0735372a376d05fb116b2df0d5a56963783358d6bdc7fab0f866d4778b7aeb04fcaa4ce32ba79eb55be9a98b72e46d1219b8fbffeab72a4735c917201f8a5a5557ac944471e7c6275d7a98ce06721207fb8baa8fa0d19841f20ba6bab73c8a9309c6daafcf21c5219f3eb0fb09fbf85383a1e04d6165a0efe180bb0082981fe0ed9c85609834294e3f5ec5542035441429fe5a3f05d74212c56ee52d8b59bc295ab9daedadcb219243457fe149b3a9d24a63a217cb3b49244ef6e860dc0e8ce51afc30e391ac318f0c44121372915890f9eb95a2b61b35f4f1e6d31b361c2b8379902fea6fc9781120ef00174514f9d346379a0fc0bec425cc11600a28b998ed2e78dd64749294846d7050a957432d8d2f7de763f073a2b92e3124cc63872fdebe9320c7befdfcb4a79363ece5e9c4af96bc38850436b0e5bb6d8b46becf77a2422292777028841404542883dca10a31aead536d05701f5d369b3d64464e3a682824a3d5344d9d55ce0198447725afbb01189edf29ef639fb97e35920dabb4b2d52f0d46bcb796bad4f9f6c209a6ff759a55dca9f7d147c7f14eb506b7011bae8a7fb1b706b2f81ad6268a42841544889e5bc37b5dee5770d5eb5a72471b8414b1f3bd7c57f9b2bd398b85d26eb393d469dadfe03e026d4e31ffffdc958020c7143a0b39c9ac2007a8743127167c15a3752d93e630e6f1655167b8a20177498138c8dd4e9e56fdb04f83eff802fc2f7954f88808f72331ed79f129db4a6dde6529073ccf913697dffcbd74815ccf346afbbac0f459779154969eed3af4ec5d301d97414db2bb1b7602f73fb906adba95ca2992121a899fec41b9e3d51d75a65713165c3cd8f1ad8184fd3df845b5818b33dd0470b04a5d7b7c815164a96bf021d857c89b6bcc9bf508cc49604be44a13981ea676974e2f62ebcf582479a286c480383704861bde43a014bc5d1ee3f1159262f604a3654e919ff22ef0f22328cda83f5e136550a293c3054982e079336174c7ecfc26cd4d7b148cf6a143583d69a43e6d245f40aa415c38e7133c77ff68c6890663aff5d9660f0cec14fd55f59e98aede691a1b55a71009ea1d7de6d1c411b9a0578d20a64cc3db6d41fce43d3eb70c179da877040fcad72f663305edc46cb5db9df6c8e297531b3d36b4719450b6dcc66ba3ec8666b5960757be34babc59dffedd38d2186cfa610854999d56801e38fecf17e60366677c1a77293da149650ab622e79674e7f9593f52ec4fe08bf0a6c4776ad9a70d873e80bf7e89674d9a3e05c6dd731023425e51b78085d36a28f84127e0838e3e4b03262e0f3d398f4cb0f7c2eaefabc2681705f57b17006bc58772a2c844d788eac6514c56391aa04eef6b4968a7ff9ba3db543e5907c331e1488422c6a2a526fb74fc3b8b8dffcb97a6a676b0c523b39bc0da5e3a4712ea2e56509c3b1e404e502c6f9ed6458ea0386f9ed6dd1574cbcdb3f5c911b4e59ac7bacb1514e7cd83f5d411342b3f8fd62b67d0558e79aebb1c4171de3c59171d41b1fc3cadbb1c15c45b00e8b041813ee293f4253aba29e5386c462bef731e437d5076e285076775f76d978a3f9499cc9c4a58863ac0befa3f30f34ead59ab7eed7421ea1aae5bdc968cb074acb24c9196999eaae5d7e1739fce752493705c2149e475787b2b80cda2ade80fcf7ab5593a2a4595b43afb667860bca9b36587f4dcb329180ed8b0b05c56b510384385e44f6bb26e3f890bba8f8ec9f8f5cf7851b2b8ab1ccc52572ec0db215beac6ceae3e187c9e5c0b6dd356d06ed7b5324a8188c50249e98029e34c30951703b311c1091f662e56af8f28853ae9a781024a8b4234eedca5bf090edce3d5e39fb677cb6b9ec331f76bc74bf897d494195ef1035cb8675c857ed92b7e4c541cc240bece6a55ac3fe82d05ce2b45a4a66ecedd0427144a256541a958bacb4c19274da5871ec8a37bc82c611b2a15bc008107a02d04300d22bfc2a167a56aef588af4ff9ebdb84fbfa9a89526604dc6282c5c6ba3d38a54fe75d7871a63acc926740cf7ab83110b1e587fa91ffce0592fccac2ec5e24fa016544249c63b81864ba511b62b090a63bc027ca030cbfe46e8e795534b2ff721bef65b22eae907c5359e132911a6868c5b32fa652b89e1c5c153a1618688abf2b18080fa3a70cf91fc76fa1f9183ac0e00f3924a35b84598e2c89205410b53d7401601a0c87969c954225bce0cca3d1cd097a3c377849448d67cd7af5ce58706c07338250055c21111ed18bdce8aa0565cc847042ef89d6e0d8006c52ffe7504284188e2e737a374d4a3cfcb01b430782d26585ffc926bb02a6074f5801c13e25682f0c735541e6fe2037925bada66ed6a9838be550ffbb7a52cb0f7f9fc0fb8e8b2f1641784a4fa9f949c68d09ea61b37c0d3d1bdd47343212a1caa9c64138fc99d1295a9d81d923ef80e13533d73dc8c8b61af20ed8f5088d61fd5163012c2fe4859e39f0315982a54c6e870d7166cd21cbc80ecc6369092f7dd64817b10a1bfe449d4230574e62aa7066670bfd64a7950d456085538be4095936e04e0fd263e7a4ba3946d497e02c5fd2c8e7ef786affc12ffeaee3e97d10d6e5c332dba444416df8322c6b0f36e2d9e5a3a47f9762610b35a4c9d1a205a96ab6ff9aa087dc79100a5a78ef0679ca120246651a5356311e5de0d6f244f3871181b5e596d57960beba80aa7c11097deace45ad21315afabaec8783480e998e2882b93931b9ea5123ffb9c9e69bb722d48aec7414158a0039946db309b05bf1d6ff78c52302f00b4bd5072884df1f28f07e88753b4ae26d5660e313e6a547b223b2b75ad601b7735a498570786a7387b9c9b6e78363e0d090644f392d0d94c07360d4cd1ad2ece9859f5abbf3fa37dee6736a41d3044f9b829d87abba3cbbf899f4ab72c6452dee5cdc59193f052b6c1849ebccb8a4e91f4086f41e81f18bed19845c41cfb1fccd0b951a02ef99983fc5443ac88393abfe0176678e71bc2e1e64795d63e626ca0182520f456e67036e28453c189e031a6f7feaab1954611e6847953bb3602f32c1746907003c426de8a3d0f77277287341445e4c0683484b99f821014664377b39891da65fd0849cb56b7c59a24a626eddccf56e7feb283fb33721dcf0aa87ac032f107a02a9d86cba041d1bd9717952244fdc864e8d2c79452fc7b5185c7647eb0f4ccd751a02562e0ff3da73ecc7a94dfcf94ac1111fa34dd37a6ec831c4235b7ade03de1420c9d85fc06477254beaf71064537454ac4f6a6b17a471ef74a5ded1413ea82d215391d765c83bec523ae4504284411ff8feb819d388dd3eb63f3a7e606cf343312a9ddab28a2127b1271f33a192a63fb1f267ca1e076353bfdfc33203151a06e90df346acdeb42a2b6144520e9bbb9a3f95b790b8d9d06bb8d57a848a053f2c51c44981c511f937de9caef8ad96c82d033344cec938e4f5bcca4609c68b0907ba028ca8c71bb049644e1a8ea1dfe6cb3b5b8564211d63ba58ee03466ea2b02e0550f5885b912937c88333092cba2be91588cc4e107341c64965ef40345f577aa9427baed4dd4b7490fac6e2a7b1f82a2050709263091a69141515e665015cba353a0bcb2aa903bf29d058db8f13ce473a7e938788fa9227fb302020949f4bfaf0e080a898cbc0f1c30fc40e4ee2d60cab4bc13fdf40b42810c08b3fcf2238c0c97d7622eaea82094ab6ad2439c0045f41e5c690f304e8b41648ea5f571b00b9a5d8287a79c614501d8548f281175695e1a254f6dd05eff9ea833cbaf3833d2b4c23da5256bf1508b90fdfe3b4a807de567c80f5a2fa1f9e64573591a9bfb72ced4d8df01fef759e431f1177e791b337a38124e7666666044442433d37249efe84d45b8b21f0e9444752b3873302b506c2683dc7309ab7b517da39663d64b22100c1c03f31695c7c0f8d59a9d28ea47617431490e5ff6257774c315d8ff995f4a2c1c382e7a7e5015561708220266b69269e15f915e03a6ea40c30d90ef68260578a517b12027d8851612e7b8ed7a69af4c1f6e0cde51a43e94c1dd13176f9dcbf7d0af44b4cd71dc5bb4d1fd0dbed2a6e4c968982a24320718d55a42ab134fe75daa75ee03bb65d6ddb08944a8f1425315dc11acb88b911e1b1df3701108a1dbea336a7702ccda03f01e3b185d5ca6df19f6ee46bd32123e23ecb95aa9cddddc314038df1839a166c5e3e36bbc8d096c9da3c5f975f78bc65d51f86fbeea8dcc83f0bde9c5f2c84f0fc71fe2a73bbf56f8aa83bc9d083af9827648772d9827be2eeb55937e3b09b9b4b6ae29ef74742a5f347dc239d31035c2df1e1887346e5ece3ecd12d85c9e8e9b826bb65adf7e5e063ff8af7c9fcc375f39c22ec36d18a0ca9bb0b4dcf9d84e9edfac3455d2f16bce372b4162a5423bdc4a24d5389173043d6bd3cc9ba625db90a577c7c31e07553a6b3f302decea789cbebfa5dcdb71e6cda13b4cf1b3b0d56036585fce400671a88c862a3d9072d25d2d6bac084014ab82c4c6291a98239f2496e606d7d0c8b68ea9ce37cc63d0f211f57999d0cc5d0d25b33f7bdcca14d936d2b05ddbeedd5a4333acebcc40fdbd6043c52ccc400291cdf46adfb788a849585639d4b16b2ed1bd40da35a0f139c654f845f7079cd4717d7878d8cd9b1dc4e0f022cd3e5500cb7217af823c7253a1dce0e793baa0331d303875c9b384b69ab6acfd3c6fc92efbc3ca543a38f10e736a7dc839ead06496a0d20a74209b6b6b1b8cccc7f4e2893a12c4542ccafbb0781de58d3dcd77a5d8e3339258bdb9f17ec40abe6f35944600984a61a389ce350f6c36e401032f7dd6852ea22f205675a63d79b98a9960b75f53ba6e20cd9c3e92c002ab131a5b02701ad419d982dd0e4024528b9a88f4b314b2b74ab09045b24e4738569e067076c996826a5e62e24a09fe2faf6b67720c66ac6faa597c714458750fa5c70d01c37f1bc3004a4e61859c47695eedb58668bdeaf06a87ed696ea0247cc0b793d81cff4bcb28be36987bbf13bfb89d53456ce68671de843807d76b84f63a4e5eebc565123c8f56bd1126e248ce69001564883107c868386c06c5c7566ad36b1be435301215bc14c3c46c2032f169a0217ad4c0146dd252cdb620dbe80ca271085d29b5359bc50b3748dbac0d8a70f0b2f8d386ffde6d44a1849f7a1f5320a2d48957c4f9f74ad6f8b8aff6d95d3d74d229a58970f63a10c666784d19c96310bbc44a85329b83128f83bc8c5088bfca29cac724bc987ba504268be4336ca2962cb39a0c7fdbf04d9470631b42cbf224164b5ab178518a41ff01157d3225f4126c91cf9b026d84fe1879e93869bc46b4d41ab27233209cd08185639060aafb2b9b1395374cd32b0060f70b5022c16ed79a7200a4534e15952f18f9fda49c14e32b2c9f9c324e376101da3266aa6e088f131bd61b330e304ecd6bde0f37066e8a9c543380b04ca68b26f60beb6daf12f47df503e4a7e2ba63bd356beb5a67398c7903d21692a87b14fa9a78597a47682cd41c70a907809314d6167982b0f830ac40cc93db2a6ad620a0ba84a26b2959ce067368d5eee97bf142c93e5911f9d122f19c259943fc2c3ec0fdfdea46153842664eaa98881fab7969db481cbaaf675879a96d0451b85a4a99eb2eae92ab2599b22a23942715665b2e5fb3d0bd2390e285596943f3f677555372950d446f3d865006677db170016a6db635897f97f4f0be8143e2871c7963bf9b9f90a701a3d2221e1ee825d43a1ddaeaf09d9831b6167d7deaac53046d6f17f585a970566a2b489d2b1ffc74bae9720d611733054d34ff2d5b79db66e94708b9dd7729fcc882682a3c2d02cb9e66c7d22dce356dfaa719ad10bb6bdb723377bf0491e6e41a5855b899d6ac001e6f6fb045d7b16567aa055fc30ce9f261aa9450256c72893f084e0ec5ef16177475599551e136d0329d8611400550f1a4e0f9c0e1bd648d475a0d17a881b9ebb605989ec02b569d87450d5b292525383992e0a96b1a8736329d9fe4b1b0a38f3d05bd39486caf8828648c1b6f2ccfdc8350084048faf20ce8996ebeda9ff2bc78aab9b4fc620d901427a53573c4cecf17a2aa0cf283c2ee412f95c1ce3d23404172cc60bba15dd5e6351d8c98aa1f1c31836fb10c0840251bdae1fbbecfcf5b0449e265a053e07e2a06dbde6294081e7340b81ff0672720b93813d0b1a97327a0fdc4a3927e6e79b5a70b24a590508e19050b0443ffbed23b5c8c330c1d2b813ccdc556f5e401c3b7b093f412db87e035a23cfdd2d6a449ebcb388674869ac631d47ea7e6f5d0e9eb83e4541cf01935a48b9061bcb4029d770c70112ab2729e9950c213da5a72d2c38d4418f6853b8abfeaeb37154b24646db583df93f78cec7d1cc39e7ed901807f32f0fb3faa8656abf40baf2558adc1ae4d9a22afe627d9bcd8d6f9daf0c1a2ad3e286c9a6684b0942ede9112b4deb5e7481e4e91a9746f7d5195ed735b17ef8866dfee3006f2cdbf1232d36d353d0879cf0387897e4e5f8960dc6bd4729829e260fbc3170ba0de85a7e219bb73b13bfd82673b46276893e4080a880e4611032d220232b0bf4eb208b547b4be594c442a5b7e107ded31b6a57524d92a2029d73aac45bca7dbc436d503a72bfb8a95d8ec153660ac439bb88c5c43d98000a7ca6a3d638179a14fec06c00b8f6d71ec58fbf2c54120c0946994d3c27f2fada744726ba86f76f884084c597dd9e385016ce645b073d452358c04444fd372f0ed5870ef6a2c57a2d891f4e07c916e2c3718069ff72912633befe07084b24e620424b305e6b498033422efa115a3b41d7623f694cda47d4940bbec2900c26be428587e5bb6d4ef22dd3a661f29041abdf316204d1f94b2791e7db86f4e636d0a8df9b6edfb95fbbfffce12aa479e77235d7e2b0b227fbac3bdca6c02995df92f604d648a61012c1b28763f2238cbd8c08fab05b6d67db60c57c76f017bca15169c7fb531527ab28d217b9f589b599ac4b6ff0215eff4449178a8de61eb785eb83036a64d33820b1492dfc846190dd26d35c18ca95e874db11abf47bdd8abba601de6cbf3e53e6a4af0fa35a73431721d4228744ee5dcceb1f1494727105ce1b8586f5c8fcad416547609870692ae6b1d2b4b51f8261380e0d60d779697894bbb4e98f025102304238c4b181bdf675f90dfa5f434c3b80a0f6333c534dc8ac229f5f38262994cc975c94c418a87b0edf62c03628b4352dd320a1eaac460c7e3806810af78b0ce3aca455eccded7fbac9721aa9201bb34b377991134fe81f988a40c23d4e328b59a990625c6ac42f775135a4d81908a25e75059d7ab50a0d86d0ea4baf759447e6c3595c5b628cd79d09312046245cf8bd449fef62634fa0c2ca35b9902c490cb9b2fefc672955081aa1a53d6b62ff0e47506feb120d5ecb0c1ab8e781a51721ff5f1d69ca163296024f0b38c8e681a8965113e87ca18633a11d9d0a087cfb9274333565d447b3be88e57c356d15d1678d24a29f0805ff8436f4b58ffa4bc3cb81224f2a47e9f2ad8f2c02d48f8127073e2019bd5eda414469d251ca8c081a749fb8e135241275d409845ff114ddd50667952c6e55a0f5c29cd70446adb51f3c8ff7444b92bb64f4fa9ac667a4281263a0f7471dd8959684a205fe7e84ee2c954bc0d1cd50ff0b527abb80fd5c6576cefc95366c31e37f0716992e13720a5714fa64a594541c35de5cc432e96ca68a0dc73623bda4ec223b1ad63b1efa7be2525a750d776ac01791c12046fe569e52f6d7f9c20bb281479a407791e585bbc50fd464dcb8423a29e02c371b089f06e5f7ba014469ee90d2f58cee4d3d9648bad94f9ee8599d0da3841464aadd857d3aa6a4b2c5d15b7c0dc29e6c9cfc209b2bf1204edd43299040dc9fc62bcc2e52ae958d5c6a788b44fa1652997af1d38e0bed7dd8a886740081e35502f68f30b347b6e4083b5c17b5df59ae7e0082b0ee47adb967f27ca8ceb2af73eca166c093929a5bcee4101f8e925b7fb49ae6f483fdac24a18daa3d68e48a8db41e7b750ea0f871e6071de19e088ea4d93470e53093149b00ce72a31254669aab31af5678be056a751a8c33ecfc0ceba7ca04cede82c1413db4dea2aeced26b100ff4a04e2322a30c7067e96f7b3f8c9d3edad536de9543e41b4fddf032f219df6dcc9f111c27f28efbd0831c895c2260693a8c360f2afef33a564169e9e00c53a1581b01ab42cc261f6f325da0b9175e1b206fed2d36c10c46388609315dc66c1188e1e4432a79637601e84390da4dcff0254635e2a9e30a0970338ae1f3010eb17e0795192d5d4086200898f96f2c784014346e0672af21f03cd6d48d2c5a06a79a768dd3035bd8dac1ddb56c81fd9851b530c5e824a6ec9f88c765de6cf3bc3d7d634ec077aa85058e4910c63b3d3875cd2401d08fc1e0463f972d5a511543d607e29b5561da7fb8ef84b4e9f8717a22017119c66ccfac371d81688f50e82ae37a7d28afbd1cc3416f9da7bf2637b4b81e47bfd0a25fc18f4c8a54fa4f0b33085eb6fff38a75674b4c200fb72d6cb347eebbb1f89833ae820f0e5c48f479cf0eaf981214e2cb5d44b48bc14d25363faa1c06eb47af649a71496409bf947183027d654be6faefb824898ac8ba4f757ac7ab3188880c259c324cc4b1b20c33e4e25958c2aa7c1e18057d8558909a30398088d43515f7842e1324ce5abe4329a56912e92d42002353dca10ab7f1dd181fc10db1d911d1cce88ffdb766db5512a9b9f93aa68b9a27a9728bb4b0f12f921a8ba64072e23d555fb3de396ac643db1383d64a896e5f60bacd4b182065c8d38a4bbc80adf79eaba74a23355c5caab1db3f77c7c844b39e8ffb645f648e9cb5b037c5bb021d7d5dfbefbacffff56ae2f733155a995700ffcd42da1377367949ed18611f9e32a0de44d07d8342f132d317891e17921705b9f24dd80f6b78366977a842b65c76d6d3cd5e822457d97ceaf7c3fd61a15e215b2ce381b3671826395a9584e50555a57d89a8f5f31c2e8a10d990fcc8162e6665a929df2a2dfb2a88216220559f25802a3d07ea5cf24ffd07bd048fbe25ad28639ae97a6aa7e2ec0352324b9f8e62c1885a46397280e882b96037103c5ae90de7ecb34aae3dd44e23bd55f6a2d6761871e4fbc8598ce33133256c29aa0680b0da97b8701659e6c7da1a080efb56e4134274a137994551449e53eef3d5764785ccf16c57553364f115657dbd01b7f3a0b7e38bac23fb4140928f62e7b9b0a3bd6f8d9254e25ddf0c2c5ef738e967b53be3f6a206e00da99f3cf5e6e629a151f137b3313076e8042be5a86efb4a76079e211b3e5d91974d71031ccc9484171d7df841223497239757828875310976bb3c50edd5d4983d11a866b76e70d7fbd4c4647e676c763626dd7bb7babb50d0d757a4754e2a9d83f5432104e624f09522c09bd4225be7bae373e6919391e3847a568c4786ebe8a45b459a24fb2c8fffe3871e22aec9fa7132c93ce0474a27be3c623bc6c5cda1b212861e336a618741fa7b5695c6392d8f3b31b055e2ba26150f6148fc277510ca9f5bdf6b06bc0797523d800596dadef9df853d884609a50576cf571834692c6b5cfeb75927e8f34051de247408b0cdf94a9bab84f06dde8d3a5214e9d0fe24443c53dfa6ce97b93de5cdeaf93a753716b5d01f7f538bce444685171732d7d3c2e0925d3b1ceffa6e7a5c58434d3bec230f7d27d54151dd94c8dbf9f459db5e8141acefddaec98e7b62fd8df994d4c5d18dfb4e307108353379261103e9cddce4406ea81947cfc08bf919e73eff26832b0b6bab7d1b01da36c9c18ba39504e0349f9f5b7c3483cbd63c9347e9d83323897ae615fec0fa479de8b12261ca9eebdc00fcb477f6e83492fed0d046cd8c39255a87f8f00dfba658444ef1c8334028c3677700de3dff9dc3d42bf9398de21f73b81093d14ed954535696442a5b211973b29b4bba16b3ab317128bd751a35cc700d6d5dd2719d64f0d77465939fdb57f4d39be72256aa0efc8261634e2a2d5f79a8be95875278efc300413fbdef61500cc11f945005a2e9071cab945e4dbfba8295788f95bb21c8bbe2f824a08263c1378b42fb90c6fe7b78a053cb0406b61d2e03629d65c368b893fc2af45aa3bb9a441265c81cb708abaebab86a71710fee4f0c047b9c47836f5723b92f19151badc4d9ebdada454fc03d302f709d9c651d2a27332d04f7d8c53d03054c5689f5e188a1f48f0a32492cc747f4639ff5b0c5b4050e53b25adec97a656a2dbc09d9c061cfbb13a15835225cde69721c8061d91fd1a69e57047a5a43af0406a1cf7fe266c4c7a19acfb539b08f1a2d763428175023b4b388e54c02907323015e121a738e41a0b6c0d13a8be80363542beff216f0044d18151b87d813ef042c02eca9b23909d0c376333da377283bd831a8889adae01604fb7a28298ed3ab85d0a48a1b54b54ff509c5b4fccc250129d78abade1433914df88729866ea324ff4ca206ce24f083c9e24272a78b4ccdbc19c7a5c1b14a6a6794c0195a94a6ad133da5323dbee47cfdd951eaa790943c3ee34caba4050bf5a8166ecad1abe55de3b41d9908d286d6ea13f9c52765ee87569dcdd54d31eb40276093f294e09aba61bc2580f76529dde917ac93e4d74af07a1885f9a8c101d17462d1912f419a96e51239f0892c2fdc3fd48474992fbfac008245f8baa04b55886b8bad5bde4e091747576eadca63434467984e6da970802993766644c15a120fd686e07cd6e56a69b4340f402444060d5020d2978073764c8ee1c4d422bdb69ed7760868f72831120941363bfb15cb50d830cb9d97f78264c8a1bd856b0ec6ddaecbcf0fbc6180f5ec3e1ef4d9134120f329046c0d7bb5c6c4606c5fca5131d279adec726d64a1b82b198b2acfa92c13e9c278bc969e976425f6e7f6a5d1e011794d5cb64eca95ac3041ce8a5adb862dc69ad577d9ae6f84133445c0b72d71141294dbc7a093d6f8e45c985c597c4387dc7c08b292ce07a33be816777e163872b2e5c004a8a7d34731334b809b32cc937eee016f1e4cb5645b173bec992cc7725900f14ec540deb794cb0b9933c6d3e6d3652843977838cd6d7019ed0ff96a2e640a3725eca5f0a25ebe8263dfcd96faa4d3d112da9619cd192d006b9d09b895d06823e9e851254d0194a7ce7d858feb549a4dd24123a4e106229a80cdd7a4e605e35c3531de46e9d0efa53d1d022dea9df7f4137bc337d2ef33ceb5ed1f00dd530432cd034526b6ef76d420e38010ff8ca20a916d6feacbd72d932c3f508f7f4ebe634e697f1c3476d9b67ef3d1146f68f8e66177d8fd32f2aa1949391cc99c15ec6fbc2fdeaf380cfd0f1ef07353530faaf002158467a5ac4fb02908cc64f826ebfda6e95eb643d74e6ec36f192696658790042594e482ab660541d33feb2e568e59a8a13e886c2905b5012264c2b13f397abd107c2da6fe072b3be65b617b75c323f87231a3a00523829f7381eb3f034e0a1708baa16fd1e1c825d122d664f61e8f52ad1b62cfd9cdd8d9c526eccc5b79c6d614e14f2d9380c706896b604203ebb696a885de62f9ae86a687a68148b21f308d76f429b26132c8b5e935619d1a52e8fc738a607d6408dea2f4f88e770fcb1afa2ac33321545302a4916e027101471e6aa12da4117b880a1844f3a7dd4d772d4b5a117b3774cb5281a61bad54b34cf9c0008ad393e4bdc0d9e5dd9c816ccaefeac7bc02af361cc5a46212139b4b993fccade1a067e70323d391933f2d3cf6eedcc07499c31bd4df385f4939bd815bb6f330695b902229181f95593af21023f87554c8c4d96f859bd98e1f9702b50a545b896d382a8fac4cdc7c51ec5541f364f490a202510d755f9f4130490232f4fabd35dcf2871e69913e65394c380904f551f8cc126ee7d061f419d4349fcf18ac1490fd4ac92ef5beed0ab3362e8433b60fbaa6c49d8e27b05b1912fc3e008163e87c65dc8c95df9e07863ba33f9f9580ec0cd60bda5221c68c50fd7c49df0e7a9e9d5ac7dc523f7c902385b3802ed69129875835ff3b8a439e0f7a6d88f83cee0162b3f2cebc3513ddede88788f61ade6ed3b5c40bf8ca20bfefc2d5bb7f44c4f71a8a5c85300bc8d0034050907ede276b1d63cb46297aa5bae99f5e7d4a1e2499cb1d15c9ceff9f67ad3fbe4e8c62ff26ece7bc36cb9f64df9332ec088afd0c9180b432e37769facb5f167df4a75927b8c7574602c0232c30f3ffb545d52091ebb4009590b911adc55b00bc93bd20ae759f27638e4a4e9e8e174687b5f03ab2cca7db1718764477af596126d23df09aa03607ed7aa6d490fa5f7506b448b275ed1ad3fcb7932503081a0441cf612612376377a2161c6ae6e89e6e38d9652ec536d10cc8d31efda8210ed22653597e68150eedd6765fe1e79de7dca4053357f7228ca6d613a05c3e56229802867e6355994a8c186febbbc46018b6cdab6581706536581f79669d56756fc586847b695f30a17f1d26a6105ef901c7812168f5602d3807ac7729bc2f0ed1e1b89d00cad47d92f25217f2bbda63c7ebf9552e94f717e672d95dc680507117227046024511ad29af64906a5a3147d4ed653dbd56ea15d032e68dcaae6155867592383467b4bb727f9be1f5d88b6825b3ea152ea0a6a22d67c1de216d1b50f027db57363bfb86864e8c35da4f497e0162bcb1a00e57319ff86cd7c644266bb01ebf7a8fd9787c4ff64323396f521967ef421b2c51858f16250d01938e51c7f6a1d0d944e56ee7eea509f81ecd92f874d44541e4641c45f6f62b6bc4f8f67f5d20b553f5c616b2244d6a2241af69bc4df05e131be584f3a265cda93921339aca3850799ef593611000c0010d13bc887c27e3f15bdb48af553519d6c30792e07421f84b4e0595dd083363cbb8c5b4a77a8f630b6b1962371244fef8d4b1c3095a9e6734e3b96c10c7c7c90fab3a5eea730bd7e11c4f0e4e93e3418630abff1fb77d0e2138521d48796ad828e629b8b4048f07f24b025dc03a19aa26f21010acd43f08b1377e14598e35fb0df805bcaa1b498a35fc34cc6d9e0b823b691a3c17c8c5ac22f3a4272ab1c74f889f5b13535a5317c260a17638d5128c4939c9dbeb914ce133c91282d838ae760deecd2a47acf8eb0c8536a76913d5f8b3f026fb2a988ebbbc604747bd64c6df0930f76be5886577ebdf1aeb838e792b6fee72fe79f72e9416bd69b4062affdaa2895c6af831492e7f161be749930ecd5d519d9527c8287a63172e0ff85745cef61322ed4de51250f510803425223b96f6dd9e0b83b9f08dbd3cc1d450170d946b2a1ea86f77e7295a23d069817b69913ae0c22c528bb38d226d3497b6937ba6bb046c3fe02be1adda8dc6e79473354b5a15b2cd2a40c8bb99bd7149b68fc6e4d343b22b6a30bce3b8dd59a9d0f5874fc35de331e8ac7aeda733e6bbc57884a0b6cd4460efaa77cd00070f1db9560f50d9038d3bf575b7608b4f3489993461764910644904e68eb2ddd728812eef74357a30ef9550d1412cd7813929ae4f50f630f07228f58192bfa1efe6a47d5d235cb0287d96156d56585157d3cdf9ae569ab60cb4c2c07fbd20584be7bd5a1783493fc7ac9c7e94b0d3759037760bea03859da93ff7af5160419de73e0d2d5f5a79f623f6dfd6406d746ad6275cad5bb6ee4d364d0f5899b729a31c6136b648c7431ea671730c60225ea6370fedf73f539e58d8b431c87f01e1c191a3c790dc3d85cfda379810d0e14f830ce1c1ee9c1a5b65606455675b509d6ae133f1d3c564fa7b77a408c164086e53de4ab826e43c96dce9dea6841ac73181ec3a1ab470748c4923fbb4324ea5f82faf169b7301eccfd710de6c5584ef73b11a5f43bc9b10789fa3db91331a5526a0b70aca620eba285693973c9310d8f709712bf28c7b5e49ef327b40884618332f9f50be126f68c5b5ca8f91ef0b949f90f8e44027c8f48e4b0d499736612dd22a78f9d0770aec37b07ac086207c3358a8cf9e5d62b7db49d685ea0440961dbecd057f3854ed27d5cecadf1b77f9314ca44d392b5c92ab2b7d16a0ea653e31817325d3dc4975d92758c404e2c645ec06c149b885ca2ba9fbe591a6142a580b9784f951a79934369922a335d73be8f46ea9e2a85955974c645358a560dcf82fbf0552e81dad5aabc8c5a994dd4afeb1c7d3cc0b7bb17ad66b8503acb342bffe46a488413d283f0d58de4432cd37708292b62edb349302011c9c9f482b694bf08cd6bafaf1e28066abb12d1dcd164efde675663814850b600878823fa82bf3ecd507d1939cff8ba9d1f2afb4adc12ef62cb908e5038e99afa56e9c82de5bbaa5873b8aa1da016a06556a520a6ecaa7ccef080e3f4ef991a4161f665edfc1fba36030be67742019406369fe4b858cdc727c69408b8815f76527e26dbad1fcb0a3e64ebc04dd6758c8ffdc69f29cfb25d1fb111dc690a472d63281d8f016de2f03a9169c06c22b63e5bb04c03cff4ab2bb1e3fa70785c8b507276c5a3db4dec71679e3d4e56e43707e60924bdbed1775228da65c0cc9a93691ad74707d9a895a54e155284c1605b8c14adac1fd0349c6ae4f3a992b4a7046c88e027f415b21691338b3917de62c919d921063cd22161653b4a73e525e25835f5aa0a9e985289643f82f73a2465aaf6de0aeaf04613d37d4b6c82ec86b2b363464f0990d994f706701bc9a96c3f9a7c8a43ae1319382181eeaa5961fe94b42294bd012a33113c5630dcd5a40d397010663396edcc4ce2e4fc108031371a4f068ec3d1316836e7734a192bb37296ce4b63ee9071506bb7a4480a3503cef27f3eaad4159d842b7dba53f5832863a38f9ede7ed2a84922919b48e4d29699648c03ce03a3036dad03bdf793d28075c34418d18a6126094651d3883e9d92fc0927dee2cf18c5381bc3d04992734ef718350dfd59d2c4851f0a42155166a0038a49e7a4bcce490c53a934a574565a981da2fb297f62f9d15d197d8c22e97bf8e55a24a79fd2cb8f518a130ff1f27d796da5439c20c3f040fd7ceae7cf49ca52c2388c8bb916fde55a745d8b9e072f6e344dd0f2f042513f9d9a59cc15d77dc4529568863990bba248769214e74f30333a39e724fdf44e8acee529e79ce6d3e9a6299389a8205c9ee1e0490aef14c50c33a27005880f64b80285dca0ba1076c36e08a3c7fecd88e04e597e6ddbd0c60861841042f830fa676d5e4359ebc5b2827aa7942fc9a7b3b65d8074f9e564f51c5de37f511d238ca42923384d749a6e77943276b641cac8bd35b80f892593e3a82edb63b3d65aa9b773b23fd1676da48ab21587610449962f757e768b29a160ed16d3098e07e7aa32ca08b1d1faa0aa84655cf3e0aea1f1e2aa0b770d86b53713dfa5edd7e04e279ea7ac031c6084076ec665eaa9d218a040e5d019e7faca1a61224b4f2f96e95e363b2918c171966559cf25b59520cb4cbbaa6fe9d059b1c85a1ba9a26ceddc976aad8d24717d99d6d55cbc856aaa37cd69c29546cbbfe01b24be86e5317c63447adec57adaf55d8b324928ee395b582ef957f6d283697c26be859ddf30b3ed069623f6b9756a122523aac398715d1a7667709bd0299f465104231ff07d4c156de10ffb548947c0881a2bc1c89b0d0d1da4ee9b89b2f93e47113e4803ec7841efbd9dfb4e56bfd4a528e838a4a4dff92999385b3ded7b295ba76992a629c3615ccf4e8b2da864fad2258e81c2f2135b4fab5a591b969f31502a67ab8eb5d28e1124b3606965211a0bbb318ec83d5c5a2db6e822cba7b5462db60023cba7933ba73613649add702dfaf04ce3911de9baf7f25054a74eea71ed32a57b07e3b8fcc5386d69f5b4ea4cbde55db0f3998ac6359c96af629524d9e5496942aec9e4f8321aac924991bc21409af1facb18b75e335b62881545927025fcd577b99825b7734c126ebe4bae9b315580727f12b0c24c087cdd59143f7a2a5ffb35e31581f0bdf7207c317879c50b426ec765996ad040c33a079259a2b80ec7b2eebdf7567bebbd7f6dadd95bd6adf7de7befbb9dd6e6defb15bb5c59caa22caadaefe1f5de7baf45d55aabad2f59b855aed43b65fddb852259fe6d8002bae0849b99b933cbdbb95352f7de7b6dd4b528cf4befb93c14455916455154bdf7de29a92cd6a6f35787a5aa3a76be84ad6fc15d4333215c016447852fa0e4d09bc9b410dc29876c6416c5ed5b5b9e765824f6e930a96225cb97a8ec9854d1821830c814b6bd4296fe31a902a5ddcd9046a3d179afcb5225c9da964aa734eb945a6e4d8b46c3a269a120dc976912c5fac70817c37af0047532d4b9fc4cfb711cb5868d774fbb7a9b2bac97b8f316cbaf4e0027b7fea683259a75de2babaaaa6c2a5bbdc4d55f2c2bcf52ca7b5f94ea0bee9a1a9f18bd3c9d30dc3536700c7656870e89837570e716cca3522b69a75fd73b97742cdc997ab6d3c9b13c3cac0e0f654d55b0aac455b2363a2a1e15f5ee1e2e5159793c5f54654031b53f284d917a8003c57fa912b7fc64bdf52e4b9ef7bccbb49a18c687e7ce77de654aa3ca328e90270e86f3f2d4a5b2c0d00d0a233110aefde040f16b50e2f6788cc7a5e3136934dabdd5bd36eac49e677c99f8d31dc3ae86056f2ea7e68a928d32a5a483f29f84b10f5679be73e5a9aea52c100e14ad0d10af7a6ad5ebf9aabf5dfba28adac037462a988f817924be86c6d7c037462ef61fec91f81a978cfee05a7c28bd89f23cb167dad7599d8c070cbaaa6068483386e4fb725f321d9e2fc670027c26de50659b6be2a0e4f83f0061c92ba474bc06299e841e0f1eac475027b3f912f9eda8f6b7972155fd26dddfa6df68de61b3a3b2ab5cac97df3ccf925d4b762e2fff1b0dfc1b4cf6db0700bfd590f92de6371b35fcf6104238c4f439b8007c247dc4f0a387b17300b0cbb48338907706b4124d89522417f38994332da149ea110b0545a462e2d6897b09d7de7710d7266e209e3a3109ae3a310858eac41b10c2a54e0cc48f973ab10e34eac43d60eac4a11a75622da64e9c558963aaa811763900b8730dd89198988822b01c9f88226e9e4f04fc22668e6c64679d0536acdff88d1962ca1063fb8a0c6e31d430a386ed32de030077950f183eb6a964b8b900939ded2d38d06b30c0c8ef316e2cd0e88286ed2851f2fbc7bdc5cb145e6c43796f03b7130c0bcc7693f731b8ab70a1c2c5f614ef6be06e420b135a6c2b79ffc19d041624b0d84602837b089791cb7691220d04cf0f3cb69f78c1bd03ab09cbf6902136e8d4a0639b062eb893e81838d06b212db891a8b2b3cd0207b27dd33729a0b2b328a0ec092e2c029b9d0d8103bd223cf803353beb816a3b404503343b9b01077a18e8600b385b01077a415c0c810738d0fba1c20c7076010ef47a68e243825e02dc140770d6000ef478f0c01165676f70a077e3c6009c0539d0a3a1c9ef21aec1d2f0ac8c4c8c67676b38d0fb38d0fb4f8b03bd7f6bc382b9f6b22c28a61ce83dcdeac4170075624ce5ba26644091375722bf7739da83535c7b508a033df89688b299e4cdd8a8c2ddde4d7ebf4520f9fdbb711c41844c2baf0ac4a1b1e3bbc8e9f770d86e890eed431e7ad11d0a9f797f5f8e06127a39847833ef312983523a7be288bb392805b0c2dd1c14201073708a1cbd92f9423c0c930922f77b04ddbb8f7c41dff994ddefb2339f13c3dc0be0c5f5df6a14efc1f71c86cd39a38826ea4784f79ebf0d7cdf4f3c0149764e9c909305909d13270cc99f2892f9a8fd5907fc0a6c58799ff9b413576658e6f88a7cb8e0c2bfceefcc1d724218c29085912b0d3072869472527ae7bd55555555ce9526785575554929499214a78d61f2aa8a6acada5818fbd44a145b41c141900c850932d43c33cdb597a9feca59e7add533af099f8d6423512ca54facd00a2a2e39a8d58792f92e10285de458216409eeee772283524aa935a9457b5a56f69d0eb528a594d2773ba9f4167619b32aacb5d6dba16cad9665599618921861586fbd1406289884814896b27c99ce5b5fab7d4ad1a94eb5d28eacd3e599b24a6bb5d65254b5d65a2f4952ad9645ab4ea762a2e4d30325b8ac5cfb2571aeb753067b199f894f9b8c8fdbe13c46f1d2aafaeab3700208f4c8bc90a87a5e8a9556b6fa9a1d1655ac746c2543869580152ecd2e0b1f4cc9b28af7ba35bb2c7c4046964f29e74e6d21a0acb76cf5b34ecbd3e978ac96ca62ab9f2d6e55939492a2b00e13af91c4bbb5ba86047f4d508749f71e7defbde7af52fa6468b4d28c514f939da6a7f8d5f7dea3f451fcea7bd04ed28c317ab5b6cb60cd0bf4610c0689b93f2c8c8091e5a3596634aeb90c0f5edce93b76e6bdbc2955df8b9e925414fdd6d17b929c334acfa515e37bd21427854f6da811f1e1bf175f8cf661ec24cd2763f4f4a38f64ac3166118c1e0f7d4a298d74488c117c7e84db022532b516a186943421c22b514513182560aefd7376073fc2afcc08741c47a0fd3c58e1de2608c9ce09138464ff1cd93951028505db27e438b6fbd99f87dbf12e66843a1fae832ff6d38ea2c718a38c31562179abb25b1f2f39c6986d23c83ec66b2b1f46cf6201d4d0ae5666d7811cfbed5e51dcd74fb578365256eeb22ab7ab8ba34e2746093b9d8b5dad52d62caa526fad34aa72da58a7ecd0db308ae41487e4cd0632a0a0e2baf5721cb0deabdec7b4b81bc4ea05e7184008e1783ccfe389a2f86cf51d793cd7cabf41135a01cd14a87033852daedca009d1581e4fe7a5ef589d7a51b7aaf0bd990ab4abb2224ade10b0c405064e5caec4bd17f3dc6ba9c5945afac4b8c9540c19644aefd5f2b4d22e8d76032107ba3e178b4172b138a4fbdbed08515422efc7a113df638c1146f1c1c72e538943bd84631cc87fa29e62ff644149cf1f1c6b657270b70b53c9f07d92dcedca7e61fdb26514bdf72484d154230c062e9abe8e6f3bea6f081dcb0db22b208d1fbd896e519a1d5f04b303e66d6d1a46fd6c7f846de09df3c2771b1fe2982beeebdc79023de3af85ecbfe9f8427609389003e14051903888205c732a40b8e69fe4fef801733bde4758688106fecf9f944d256fe8fc1a031554903416ed72b41c1c38a221647fcd9f2688c6217a7f0b507193a7f79cfbb71a2df537cafe166da6bd197fcf36cd256fb36d1a10e4ead038ccf7a71eb919e9adf4c9d26f08c80e925ee27636481fe1e76c6867c3f4df1c885ebe0e0be83c653f7aa072a38c88cf524e94c300f210ee0c66c833872da3d234a7aca3b9835be25966a1ce3172ffc1060b777339394a1059871ea4c809b94f2e93e052e42ac277d4351ad7ac73ee448a1cf71b5a7cea30e6fef973e7ceb1e9ee0effbdf71ecc28e0c494b6c1e51e2e06f5aff19e93fd89e552a6646f2bd9b1cfd1c3bb4894e9577e7c9c46ccbb8df766c9b6e9b1b2ed3ddfc936cdeaaab3cc6563afbd6c0bb95ef272fcf73f222fc76773469f0c3f4cb6cd7f1ad976ff25eb25d9633873443ec3dcb71427d2ee5db26d3af72cd986b9bfb2ed3dd9a659d916b292dd775acacdb6e988508e63aceb765f7b0be5a9dd4bddb26347b05f7f0de72c90fcf14aa42e911f84f08903c1fa98c8d04a1dc3e5784cbc24eeb920c377ee880c7d0c1184ce058459cde69437f3e69127e5b97872e4c894fcfe31f136ecc523f366069940e694fc7cf8f88444241ea136aa70b7f8844484878e4f44281c4791ba44744148a33c7a24c0ede8d9df35753e9df33bceefe1351d70edc51bae6d0003376ef478dd3774f07056a2245b03c90e049e43078d77df349884388e193be03822ea37f785d5b1392eb00b381c7a7821dc0e79b1b4b8bce7e5ddd3e8e8e8a17168246dc3d55121b1953adb564669f2d1c4ed24d04da7c18f70751afc268224fe3b9271e7bccbed955d846b2f58f4b0d317ee9aa8053f16d2b410017cf0f45b1dcafda3bbbbf2a981388e9b0e020277c61429ef85deccfb612fe6de83bb89dfd039ae35911fd38c624f118332a628e3e2aeb170bb99fe0e86f161ecdb35302b0263f77d5b9c7f33ef0bd0c5dd5c193f1cc8df62579305112aeee18c387273f44da47b44dddd112c82042778325d9e419dcc36ade4f7f48c3c3b4a4b79bee4e588725e8e9993f3e409175c489132c5a7e46d4620707b4be407c1f090f0a8344d5a4745e81009000010002316000018100c8582c1503820184bab2a1f14001174943a66449aca43a220457110444118638c210400028021001864083373ba01195553a057c6bb72809a62654f876000dbda6090171c9dc6590fe73fa1d80b08909861deafcd2b61b9d8582d317a680411b76db0c7b85876b4600a24943a51d99265b039eb84d453d9af8d776573b652a8cebd8aad8c46337a682a5f6ac03b1fd7a2995b59efe0826076b9955f112001b9d5b7e61f9d3269e1ccb797a7f528859e583dc8844af7e73fcfdf35cf53658b4694902712e8a817ecc9a1ec4c1c99165613e5f364439de56c7d82757357c7a4086628f1e19783d5603666a68a904d60a05fb20ef3030f21621029b5c88beb8439234e828cfd598209e4771040c3f66b1c2b32414f9e5b7c9b090eda473aba1b70a38273274b7dfd74238ae594f16af7202aa3e5e3518a03da28de82a810e762bfd6b735b315b6f34589cae0fa463a73363d7089f50dd6128f484cbd350d522f10d21da76dd83b5b2599102e462a97cfe64f503cc15f5b4abd945049b9c2d54d565b415e0e72d5b046d468cf6140551037afba52dd3e54bb319fa54cc3592365740cb1f7c5d4d89be2c2849b8e964d2d683649f6231516a14dc1d3ed3b8b350930ee0c2a94d2fa4a1dd9b77ba92454a923c00f25aa03535d04a19c0dae011ea0230246ac8fb883d53af4aabac0237cbb244f8d241653493ffa9d733087e378d7d1ef0e93d753b31c3ad9fda35728638be00d510aaf51365ca46eb1788b6cc674a05222c027b3f2db9c19ef1016990cce299fed8b76827cd2714cd32b4200a4cd8694871ef6499a72673266fbf2692c7640517546af04de322ab26a6a561ada7e8b367b2cdede4a8e5fed084c214512a7ce589d398053f09535c5f62069d61aa6720833a398af5ecca0e6330ef93c5e1d91faa05d6ed5c7434090195159e5b718571ad3f3850966972f2eee549f5a6eecc31471bb9bc259c870422da7a911fdc72c84fd05bf42a9aff0f5c15c7957b5436da5ded7d2ef2ac1319173c62e44d2a163cad66a1eb393999459b807fa056be28e7344cec2278906abc91e7a26627caf1b27da2a56aa011411d94fae256a84da0700cd38e8ca99649616993061e56bfc13f07bde6f862ec87bbd0c888d3acc955938685f27a31ed0cfa697faedc8a0b78a41e0e2dbd06de5106d7b7a42db1e4d9c77d05517a4e868591e81dd64722bf0675dd73f5dceceba98d106ea0b0e72e39a0c30cea34ff61300b8ea0c938bd3b271b1666ef2082f25eb7abf8774a4873a0cdfcd5ec5e444a6e7527b908f3b488f352478b0e87a32748f68b54c481c8624bbcaa5730c288ca5305d48fe7d19730550f66e1aeca769fc1d422698392574c7dc171c5786b5e468b3c1f43bc6668a72200bb62cc68bee19bdcbe42f4d6fd65c83530c0ad8a94328986ecc818cc3b9f90f8307871d2a453e111db5bb031620f981ed5184ea38b1a2b6b8be07069d6d28014364c11ae499d9eb60b9af63f2c08ccecc9efed8ebca78b2989c8239b0a6de20d7c27a161022c4058a326dfc9cd9a32f46ac49e22d745775d6dbf201dc70a2fcfea30e454c5edd396bd9cc99a3a745732029c5b30879c1a94fb04f3b993454fc321286f6de2bf3edf7d138542a29c50dd9598b22c7783390ea4015d73e2af59f4b5d8ce0d36309c11b09d1e3f482c983b02b7cec34d7fcffa35759407b7ae21f1ff5cdc1b04f46f5ddceafdf09b8f9a98104388e72ad12e92e8729ca9998eb3439f6b4ae817083bd1b241112609d75c2b96233d42f76adf547273347a9587d229b5bc038e8e5fb3a87005fed7a2acdd445ba9d97faa7d505170768afa90a3a871efafb5b98d665c2dbd2d5f063d32414e3c789b7fc305374e44431a8fc4c28e53106390f07a05bb203b93bf667ac29b1dae5532981288e509ec8d3c8393f5a5bb0684c45fe00daf5006dd4f2468cf830b64c030b9b4e9e6d36eabb59885c711e1ee18e3e591025726aa3f574055928b6473759e0b5d6230e489d468678754d1d65daa845b7302cb0aa403191516953689330bdb94b42319c4ebb6dc6d132f4860aea29dc61c1902cee75a28528de14b09261c417622836d89f4c4231c321be12c56a76d7981bc92271bc6b48d5e2192b66f7517f9c5f7a2754c069c5a479dea0fd08a7106a9dffc41a8ac5386f5d56734405d5b0400f338f68346824146b35a0612a3c90f426e5ed36987d36fc56938b82ff458e73ff4c902395c29867173ecfb6eb34b7c1c157b90a0e18c7b585f57e584f9819e42000c1d50a009182eb380f2ff25bc759c1b6256edfd9f2d0894823a1d83a9d3999770d1060750b96d5d2d81dbcbcdeba5980c8791d67a5dd260cf72035ee49a7697b3abae82ff4400dea38f9e1c58c3c3e08a9fac6492826d568d5c38da8b7849b47a3240bd7661e8feb6f723a556227c74df183629c5d25a138a4d93661c03c9e69520ce33690507c822e33ce5d8ed7c54694b98f3c149f6312b539ecb99b6039ef3e6d2d5ae10ddff480de2d055f95e7517168e68a99224ba024df659eb9e97c7a55c8cec7e0cb69bcb113a16f72dff4820379263fc4f5f3bdd2eb78cd5fd18a4de400742b625a0e4cebac5978618320e2e4aaa84fde55036f6d0995b67fdd5535528be19f387d94e4d162cdcdf9120346d90d6990b9ffa175e0332e81daa1af04a3630a8610c4059ed0a2d2b09239b54a063229d88896b69b9a3e1f72669028a3245fa58079b2609fa20380252d86756425f7652ea6e04b21e1395a0989f1926547dedca29eb1afa2e2d70f93b486a217c37d3f4411f6194e4cf84a0c243ad35244aa1bc5201523b06b9fcf6dd0b471ec6a5eee56846ee5a25805d4660261454fc550009a21fffa5c39f180bf53144fca0a802454f646d066bb51d88fa320be17ed73c2046c51cc4ac1b9b3a57ac1908f06110ef49b5ec6300c491e3fc0b61468f6eef4c3f06fd45a1884f5d75444413a0082b58d5cd9da8fd2c68b2cea5807156876369cf174e94882dce0d2df6851d42024ff60cd94907564bcea4cf4c0e422b2c9f8f48517d24adc7588d993f6f6425d825a1e94f1263ac891259cdb3c282e04e42c1f888484e8e72a4cb55f6e2e2897112b200d2f7b46dc69ea9be5fbc7fda826279fa34c234887b61645b17213d5aa08b322d8d4ae175f2d7401f37b8222e573336f674ec8935fbc2b8ed3b0601c1e62fd1717b92943e13f8d59552794342f75485029aa2acf8a82ea5ba845aedaafda0b85560353d295bbd8091ecddd8066275907554b7be3eca33471fc2630342b06412a08bc4be0baa72ad0c8961696d09aac8146c7f7a1c92c1728a19bc16daa5d44a535fc30f41b38b6391750645a780bfce9581299e952818d3b9f01cc40e814d3ce5f23ce0082f80efcce45fa09b4a06caaa66d1914645b6198517a9a07bd72855ea06d421a8041334ca41f297b384e53158784ae59e1959735231921428894d69399ccc8d0824a1c4e244888f6e8b5581049b5d6149e7b36b9c0161ba7188b24d9c527b3d1907d7cff58aefc410cc93b08d094239c9b47038d31bb0fb6a58d74c9b822fd9f3faa6842707fe687c3b237d68276033376900d6091e95c3aa2d2f6aacfbdd0b350dc9f6b9e1b1894a72c483ef593af6cdb8c8e30f564af9d1ce2dd3e602d7289c673483d98fbfd9a2bb037d04b902bf04ead9bc56bf1f9abc2656aeb2278b09043054681ccf1976ac21050a5ab4a46f063e0c52bb2c9ba0751fd40e810a57459fc7360416b1470acb006d8d5f84482f90b47c6a756c359a99f1a62237d21df2ecb0313c371769a20bb1379697e99f46aae79094e4769d6adea8a4ac5298735ab8826b45f0af912e18309deced4da0b4aa9edaa5659a6b0e3b5399c84b060bd4c201a9081c2bf45289fca904493cbe6574421b9db50e9889e0fcf7b17b7cb163c0db23e17bea4cc5cf8aec7889e89b4893285fff99911019763b5d3eed1c590f97ed58e6035010e8cdd766b620d6b0e1ba1ac35d0714a78628a9e8417b61915385620721d891e464bb599226770a25231e46f5bce596a6cae768189db7159704512dc3a0677462a59b11935ed02e9fd54bd2547fe22fa942800eaae1a75cd01eee26a320af4e1dd646b392b99b92eea273cee48770fd519550ab1ad734608f1271220c7722cb4cae1ef222a1e43e60df8ede69d5569d4fe3f8d976974f91f34e737d4e31b785114453db615bd3248c2536fd447caeb608f123a3356bd593bd0cd1af0062806cba2dbe9390afd6a2fc2ebea2fbc7c6f0f63dec34c61f12bd8b61038bceb7f173e8e6d815f80db5c7dccb059c1180f758c7bec931e569ab02d17a83e4599483466c80292a26535039cf1b929a1b0d8c4bd96a3dd68b1132335e1cb3402ae1d080b1d044da66ae86bec84f3e38587e58b9c2ac664a2084218ee6647253a41116fb2fe6cdeee1451a909f37ce82341e54498b38670176689a02492642dae3d37277b77e9f924013d228b0a93d063c7e7b958aa16582795a7c5a909ada79bc4203173f2b3b97c6d5811c6cde9033e33e8ad3d9e82772c18e683d6a37156ef042abd1f6ee7bca9da32684c282893819a2d98e29784437c3dd871daa2813cb6b9dd3605d722d090e976e75520dd3442341a9455610617bb0afac747486505fa505c51de53836bfc036438e53c229eee9f7db7da459caca504ab3aebecaac4f7d51cc6cabaf92f0aa96d28c3e672960204a771d330e0a7b240db28b18057a7f7b959b2acc11b19a6e0cb30678508b03da3cda2e2678a6a0b66c2d35050904e2fe423b3b684a2c605405d9491b132564951a25e2a01b1931f85cec792f586d4f412e9e398e76fc9fe9da87596cce0d4c5aa7cc61b4371030611123f1636cf2c3661f3c5c108ae2e2348814154c158bf41628b3d3e0039b60fae80115daca4398a780d1f6c5661cc85efb0a01b917f1e3c4dc07a13694a48d86b799e7077d91031996da32c9c942611e102784b098d8b58b28dea9e43d195d34af01feb6386e53aa0f01c0e797d4ccafd52df8ddf0758dd0b307e07a6b16f90fc338c03cd3e25eddfd920cc5db22555223f2437a4a334310800b0be32182823d55410edde3caf7ba7695be3eba8080843bfc3500e37f290da0e71a0e9c175467102a99adbf7d9af3b24cd276282fa8aa3fca401a00889a6b1d1c20ae446752d7dad991b5d2bb0fa919acbd1edeb9da35ac86b03b2724f39fdd1dc9cc082b048cf497110cee441036a84ca5c0396b468b40e8cf9d4b8a88760cf1eedaa09910d48b19b65fc2126b33cdeac9af50fb68198eef555722da9753cc91759e3a09027b8de5fc8772b3e1d8cb1fc805db0c329a44b6e637b02724eb58a27d412f86f0bf3ae67a83bf3b13f599ba77358013f117a7810227ea9282663761e6aa906560dc614be3be7fd179f70f5231964d1d3c7e8f6a15925737445eeef9a4b153c059e3c27577c4eb7e9ad7798db23f37ffe2d57bfde1becf7107add8787c3fdc547299be4bde6bac5599c790020bc3907b13764b71229d1ccb4dab5cc4bae9b1d2eb258f468953c4bcf02d61ddc23c8bee365c5114ba4a97dd4877d7218c9b473e6517c0e7195855353112e1deb8605c967e32f562351da065a606d52ebc15f3334e34f931f618a3173d1e8601b71a83856b6a20888668f516041c52ebb47d3c105e0700f8813b914731b2a17dddfa3a57764a32cd8414c4b641ea8b4c888693af3c1b436f4d6afa3cf5837eb248a6924588370ac199eee32c12387d8a978d381ba322872549b1ac105b7c513a0d679b45526d7719336034e84e11e870117494dfc9063e6f149784caef3924f86810d8393773b263da9e11f4ac93899246dc2e746d3efdb0777fc6dba408a15ee33f7c1a1748650e2918312249c2f7e73b92079ee2836ff28d4d83039f2c17246fbb0a166dc71e218d9ce4acc640b3e24794901b68c2b6c5282a93ccba7e4c74e574acff26137ccddc7a372758242a44a53ce60941122985c9be1cfd1e9d92682b67b3419995c7f2b2a4d3941453bed23469bc43b43ed95d7fd76d223eacb4b316f69ade291dcf4e96a285853a0b5e2a1a7f23d05ae2465cf7108a584d28510408c97e4cec739f74c06bbd952ebdab2462ae043ad8434c13681330068257ab487ae3e6cdadbd62a1383c6a8efed2be5a6b84ccee43b3aad35661b66754518d111f86b1da5ff9e87c347b4a243fac287a0d0ca26a947b7ba5f3a2ce5c960401077bcb2954646e998c7bf87e71f1d6cb08198b601a5ba3aef6a40f63067e05fba47457ca0a577e6ed41a7fc440f8dc4dc81145482c0a1977946a80b0b1922529d988e767db45c950b97dbd145099017c6e07b38f53ee59514c369ab2923190d90e1c267637c851fad8ee36e1433f8cac9d32dbbfa2874b1ec22a8185ec8e1715e8bde65f1b5c65907bb11a50237f087bb4361e97828761cc71cacc3e48ee082740a7b8c39924cf9edd5bc273be4fbafbac05e21e6a91927af806fbf8cc843a6ee45a6000a7ea0cb7b80e1c587fbe3d9f6341fe5ecdcabf6c7a93dfd2a49b869ab76ae9091436fb4be0c86ec6605a4fedfde60855488372408274f934a2c063870ce4d0ac3186e7cc57b4b30b8819bb31b51d5bceb6e486c523fcb7f14bdf29929629b1495cf008340e30a7a96e3640e9aa9c8d94d914d58c18879e0f9ef6b6c6c454dd24cb36c5e68c57041aff8550e96f72bd8799ef758bfaf9002dd62adc5ad5a0572c6e46fa79b9bbb9f4455bc75d82b580068b486a08e3742f5dfc3f92ea1b83df2316344d0c218fdddc6640a052021f6aad822312d7638e40b173f52ed1db58527f0560db5745de42da521fd4513052288c1bc050af075205ec14ec254df28cf38a9eeef4b6908fde0765f19ec6b125826be09e5531a2a3a1e74ebec714b6665a4fcd3a1346409c5decc0a7f61f1a7cee77a05fbe88470560517defba2128c5dc1d25364b1033d12a62ed48f916b32d73c10de529720e46e251ba212b24ea508e75d75f7adbfc7aed564c21bef3885fb6fed3526b72a089e80f08f3cc745015f22fab41398da4498735f810f6f0093754f419fa9ed501a7a8da10d448ad3e327b7b0a37a77bc4e47b079058bce8cb47e8581276ed73fb4c745dc5187e5ac4bb35ee0c0941dabd2102e04be73b2a2f6af60671cb33f20b38183bd824522dea4970cc5b81d73d3f19f7c1e0c3526787216ad05e45e79968a04ccd2ba0731b3cdd59e214b657669c71f22d5ad5b844dea1e6caae90530bf4c19edd55b295d172671f561b0531edd76f1b7942401fe83d943459935407c483edee18ebb57b0463e16aabdaef740bc82350d845b3b69add0ad405367df7955f365eeda6fde6daf34b46e4cf5b21ae5cb229051aa02d69d198b8492be45ae27aec517f77bbfdf62a387667b25f406833b0056ed637400bd1e4fc0e9e6ca686531a2046c4ca6e9232e9da7cc98dc27ccc63ae845a1e65ec0eb26885034f77c08ba8dacd381406d3cb79249fe075653e4491743f149202c90eb99a97513f6347d1a6177ce61725442222f9b82c29f540d14df557b74309231d3add8f3b85b1f9b87064ab5ee86acd30166b37d59d39c0384dec00647f7e1a4a0745b159d3993db1a98405b2e77f3d111365b98a774250c0fbc43f029ddfadb582dc39ca96ef1f1889833de38cebaaef92aa79e08f62dc32dd876aceed01adf9fc122ae31ab0ecf52008a1584140ce4efd468e9c2d4b8b20a8429ee537024b2edb2522fbd899cb41f0750af0607ac5e4109099855f9e456953dd8a6d9a98f60fb4aeeff622256ad7b36484b108f38f674440ec0832e7dca0b6a806cc19304227b84bb167eb736c0b398dc2b19d83d31a5cf0afcc54ea5fcc39a9848a42045ca5245ae011315d799b1728ed01b62d9f6e33d12ac2d89477231e80d8c282fa466e4a6b6b559e91bbb89d47959156e33dbe039dad6d1882a2b03680df108fe243b91bcac9c31ae49fec2a520a25460d6b39fec39e533581b1859b74708b4fd42b91d4b87e297233662b5d94b9af3ff4e7fcff853a312e1db0a03b5ad1d4fcfa969acd5043d50622695da188ad7a035e6b72b6136bbb33a74236c4a56d92899364801b48565c270a9f76d6ad29a46d89bbb6986dc08195a0357d59b38b8b12c6ae12e6d584456ff55428d10a46d5cdcc8f79b1bff4029ece2706527607520c46b8736474755632560e9eea6895298b62bbffd6de9734e6b7f2300338558de4f9dd38a8f5581d20666588100a0f6f38e7e027ba9c86579a700308bf2f35815dc3e7153ed52bbf46a8591d2ffe6c2f08c4ae0981d90d51310413f2b2788584de951cb4ba000ec3b8442dfcb1611b474d60753bfa924a725718237fb703edd5df8959613337c9d134994461dbfcbb295ae8854754702e26cd35b40103f3e4ec2396bf557b5917b5437e21bc6c792ddbe7ea5b525d7ccd43f655571f938f06548fe8c46792e6de8c71e445f220106894fb3f44cb36bf79d84ae314b53ef1c244b0b5a58f0af30eda52e73698663f76e9058e69ef90c7bbc752e7b70c607945f6aaad2d3d3208345f4a620c201dc42f7fc9ed95891c8f0156c0e8d50086f34929d4aaa0ff6f249b22f0d1aa1713421f163c8ff989891cb46fafd6234f67fd0c2de004d9a5ae4c043e333bf19cc8cf7b63237a54f58b682b52b0184f0324365b7b946bdb3e4b0c1cb21c619a46e88bcc724acd3b6cf0cbc0eaa015feb51317ce7d6c69c13a6ecdf75330d587dce6679cb69c79ab1481af14dcb9801813a726ccc0880c317913ef7dc36ba8794758505317f564f938933d527d66b3c8e1299b3886e5dfb85c854bb0909615b5545497fdbf4f062996ddd4fe192952ee8b5d893faccee6b0b5490c1cb80176547fe988d3ae32c1779b17221085c732039d58d247c8df001559ca5bdfd561e3220a3751b1e71b5e3d779f7d1c51edb7c3b8147862450bf7c35112fd8fd157f496be2acd57660b1f48ea996e52a1a4a989cc3edf94ccd1327af3bf9841bb497484f14993c807550ca87dbb1f835429bc0572c0f8bd3c2d37de49923579a489080c67a743b57f778fd33b050d8cbe1cff84dd421c3c8c0bb0f2b0415aeda747216f658f6f4f5ae6d1170f8cfe571cae17f08ee95286c007e7b2cff763c5cc9ceaf45bede9eaff6fc67ed5aff9234630ccdbd11b0f38e0d2f75ca1621098d00841bd59374cc6dec634469852295d79e54040c275f811633ffd4f1c580c4d3a53718d9e6f6c97da43f9ca65fac87f2cf17d6fd8fb7941eaa0f47fb1863efa193ddc54ca8ffde216b54939b994fab5627c318b36287d19c52cea9804b8475aca27cb01e67257d04d34526e58c5bede16b5fc43ab5fa5d57244b2c3ec5f46336631d803c0df79cd6970f3d3c9d4fe144a150e4a0b8d7e1e65ebf56b80d34aafe2055be503c58a454f0145522160e9d880e19fd1043844ac045c8d72a60de18297f12616099fece61013a9e7bd10e52c49c1a2fc0544c0352fde70205e4340f79c1fe7c414377edae696cddec7b2f76fd7e9acc1f5e793feb073d3c44297f5141d86fdc6092b23517dc05ac6453dc99e253edd42d394fa1c8218a8100a53e8125484b57645b070826f66f57f8c08e4d75723528451cca9f04c0de72045df123e21b824b7d075297239c0fc36089e813c33362eac38f8801ec6a6dfa6b72d7551aab678d9b06a96781fd3b6b992b3d5e660ab670cd39de80d3bb5a1212157f61f470bbd65ef88ecd4dda727701eed42577ca9c00bb1870fa6dbc67820164d1e5fa3b1a0805669582c136ac584672bc0d32c739c6e78d269463606f86c385dbf2cb7c0fd7a795fc0496d4ecda93f31c65a6067fea985eefcb7a350adbadd6d594b214b384492434dd9f878004310cd4760853cb330d9f8dfc4d3e244fec9b7c1180741dfb9f21c25c18c06d7eb184a7015b8974f99a4927fc2ab1bebd33675f278efd96767855e6a48306547d5b98c716604d6e9d5c5653a511c97d4957a4b944490742d5212662f14e332862705405a41396015831110a087f1abadc4b4ac16b0440d7d2a26a4d132ffe3665620e660a4804ef0914e840349f586990d0d7619d2b0ece56c346da7822d6edc50fb9c17fea547ededa6ff023d7f3082216b251d2bb55cf09cc00eb04aed813286bf98bb90681bb74fd8fe6ff86e967551bc1010291cd4e8f05ed59c0fe7edd997d0be18e4cf78af704e64a64f95391401b2c90e31cedf154a439d4b6f5e27aba8056b33fedc46b8a885e1180c39380f8e866610c70ba9d2735e41e8fe61dd7cc6eb9d56d9248b7f669bd16a7f81d745bb6cdf02b94442aeafa82a4812c81452132c56576bddee94e8c3b7c7c57a7976a25628a539d2a45bbff9449ed4121f1773f64d13b96270164dbfd4f2220c5ceb0ae531220185dd66f83b1f5c74fce1c9e54804ce007d30c20c63fe71d97c8b897bfcd50d789a70466cefe6a6fa8d8872e4f8287948e21f5e21e854e5101fd4d360d9ee30953a35e8ab43ac52c9c12d5a2e00a1f01549d17a2a82cf1ad88783a26e4afbb00abaee7fdf4f7ccba729c6355ae9b3430006e6d3581c3a981beacd4f069adf78770801cce00ea14914767c05d29df6bb5bce0c1c57b4e7fb2b701c90e3458b94cb97fba27169df13af8ede1899943ed92ecc097b4a26e6feb31fe1418f06d2d3527e45d25a31837b4dd9f901159470a1d8458e9fd09634345944b3862c0eb7bf265e747d20c6ac117118844aa149de40d93e83bf4116206959efb045fdcce3c5b5059f90fbf037a72e6dd826b71cfbd83aea37ed6f9eb07e3a462f86d92ca5cd49eb1d7d8ba8a459f4a5678daf6a78e24e6e5896631737ac1a36d06c3677d07878ddf3f2572f08a36908109f7c5e046e4b321d2f2cac297bf81c1b8d56e6e62e04cbb43d4e222bc72f401e4acf57732caab63820ac6348f714f132aeb85d7eb69d043dadd499896f7454b5cb8263e48908126dbe02bc6215c379247c1b192b5c52c012cd451bc22be8bdf2869c2c7d449a287249a96fa336426a36c39fdd2e7fc7de68791eef9ea81b1608f5ff3028ea020f4392bd27d1565c84d28a42afc07fc3b6ec127ce3d45269ab0a85dc7bc4de760141ebc2caaa974520d4952a7fa994aab4f8c860d1147932829ac563584df1c1e09c4260ca5075e3e606a25ea7856f2a8d19b692dc7de8ad521647e41880ef3f573b844356ffd5d9c027d3c255b085cd284f882b820135662d883367ea0cc1b9aa1029bdb8e8db83df216bd837c65760ba78d50debdf9f0d60fc48e4db71877db04938a1b9972f1d76f87988e4c8625f57b03d2192482ca412803ec7eced6dc5e6af35abc42bd99c0df0987c505dbda15e4e299d74dce1196d0926252863be49d7e04b7f2a41f09a23dd0066c442163883ae9d09b6789ad1fec35a5b27fb7ba6953ee60bfcb52e787065ee0b70b853db9ece8e3bbbd5150504c855c7220ac2cbc547a70b9c7f41d0e530ddae1d172801cf1778a803cf30406360a11304014cceb047d4b3c8722e2e3c9e462b3a156c4169349f9604011f5244cf09e8846682ebf2292e057810ab9ea915aa29cf80a1c4ee1cd3a2211808c85f0700ee5962941d81c46cb13d75f1ade924ea99715c505acbf4f0bf0304fc9dbce0c66c342f73f12cf00f7a718e45caf216038996cf8a41937d6434b0542f78cbeefb6580aa9d26d6e0b48fcc51a51c25ad36e96c3b8b98a3042b1fb57744861e0685c9d6b197e0dffb0e6186c6e944c2b5f48eb92276e4c947e5b0a5c6ac10c82ca19a4abbf00f05b9c48ccb39b2d2adfb0ea932a0f64ce6d946dfc5760455f40b0077e8991b831a9173cd047e9639d9dca90efa1b8b32434708a4232626dd37d26a012dac1d241902f8e827c33672b9865776259fe268fc9ae13d7dde975aa3548434a349e9e5702f5ab6ed4c00cc4035e79ccfbf07ee03dbb5b3c108859ba00fc104656ab41673fbcd2081b9af6f7ab6fcecf0800c613f08374bed35f618b0e87cd49b1a04b89efe358512ac50bdeb091cd1d68390968aa0452701d036d2cc22915035dd55380f30c69d098e7f8bd2f508ced72b33900b53d80836dc873846956d8e5e2cf2e1f3810297bb02120617a094ddcffac0ee6eac62a9dbe01f3c9c83faa11b0a27e382bb930e242ac12d6e5c6227de89a45c87c2c574d40c74b02db3ff716cf8bca3bed254d0ab1df503181e95d693d1efc0f6881f207ac39c48fcea096d04acee4a8996cc3c66e86fb4af3f94f60312daffb51563da28dbbf4d0a0ebb5745efe9c119ed7673f247e9a0d0e0979671cd0bc153e9eb6061927a28a82e804f0e9f23cd89999313df942b090cb538f06b5ea33199e787856775e7dc1db395494466afa0d99cf4fd797607cdc5a595e33aa58c53b78346e6abfafcaf7bde0802850573cff01ec4d8652a3a692d95dc09995e4bba1483122a82477ee01c25a65cc50eb071e29a663513ff5f97eeb4ee8d5c5ee812cd3fc6972241968daa04e8c2ecf807aee5c0f530424bc0135decee43162c17d4790a870cf27dde02ec38bc618336f373e95174a573c1dd034e8b452882844c2081b57d9d60d3be2b7cf4b9b7dd32b3aa33ac3cc2cd5abf45482e0d417da2a494a402a9e419988d6556cd2a1a4f05c13445d1b75ef9ee88d27e36308d6b225905df20d1096a5807c95d87d54a339c842ceb8575a3a9d0b9a255d73b40420e330aac7568ed6a20d2c92a2314a4e96e62570264b027b026401e119218267c9e908c4395997ac4e985e469d7a38c4d098099111db298e1524ae3fcd736a8d8594d4d0bd28d44bcc7ce7a4412d8437bdf7aabe0e5b65300cf1614a8ea86833f7fadf61aa5bb82b1fcd61daad2f0de3c092e3cb09d33f979cf5a08a842972da9a501e4af9aec021c8d4a5bb9d2e65fb0878ef406278edd770bf6f98aec1195a7069053235978aadf6bd9f3c82f62b928a22579eee09d44fbd3f8e73f40d16f79913225fa2989c26d5f7c0738e0936cf7a09750eb67a4d06de81a907a7cb3769602df2f587a7766ee460e3a604dbfb2617e91bc9fc3a47fe4cb43c2efce0b97e6c000a4a866f206adee3245f62fd80944e274cdbc137baabf88b88af29bcf8a044db1c22c049b623bf4db08165c06d0e7d42f1658e8a77d4f75e1ed10e1850ed544ebe38228526840f1a2f921e2885454e14f691671d0993f9d82eaa64be3253282e949335a06a4673241eb1a11f11e714841388885d310ed124fda4f159ee1ecf7ef684e30213847bcb7c85fd01a227f64f7a181c6159ea64e70f992d5ad21442be5927a2df38045208b0d4a41f00418c50632e75c3f84779ca0675e5585a0870aae52fa5f572c40453ef9615062ea4b69f3bf0c2e877bb0a02202fde2558b84c3a1cb8c90d94758070c773d5b8358104db2da83d587992430ace88dab1cf20927da49893d5bcc18fb4893ee999c46a89b8d5fb98cc7aa5e38239c3b25e150ed040ed8a763b10101c6d3bc0a46d276db1b0a055194b58a05040580de0908c2b66589052b809128238b9dc6784d4565521a94113dc04be48c97416582869f19802e1cc543c2db78e779386af46c7f3705dc0d44ee78ebdb21ec498566ad47713603e82c6e3167eb89e2d9eee5bb41c3de42813b89fca3ea6624f9ac75965da33eac52b05f9fd2f74329febc5cf5a237ce534c8c7a5722e2441ecb7f52bbb870f9612ef94d947d60065517545d511587ddc861ae79d1f37c73db31518524a2562d5488751e25f605031deac51ee343fa34e49c36cb4f967416ccc7f8cca082c97bb760d7fcd75fe4d5cc1784e562adb1f944069f2ea3d9b7c930f1f0ead184ac339e1c2c1015de2e80da57c8f71f0c3d176e624b95c8748bdaf71cb80606dde93880c3f76566618c09dcf137e9347e353a4a08c457852ec91a02d9ab1f8ea280b7bec56341db1db0df10f163c5bf2bdfe466e1913c1bd510fc326627e55cd6775ca8b03dc8c072f758d0a8d8e29899598f917d7cd7f102d41b36d99eaf1ba12a92da8ce5dd05b76ab8a6b4e769f5336c3d70751b875917b6fba13d1ff4ebce141bb36645a8bbdc3ce40693d60ed1239f4f8b44f56ae7a5da48ddba6c6fbbdd9d9eb266375b7853fa596811e5c95e732be71fc0c5beebffda6931701d31c7b1bdbc99637a0b3603f23200b15038eda0aa647fe68a19cfd96b2962338a3ffb4aa3b8024fb004a7111c52494f435c09c7871fc089f6c0043ea1452dc21a04e4e9c816e50f177b6f5fee0026085920e777af824f74418b555c0f0b86c53234e80cf5d1280499672740c482f105db9d56293fdadcc33b1161aadf3e6588f47e0df886aa60601a54e3f5f67ea1269f86e007dc13a1cf00dc401885a31028d08b2db8063fa5f25ad0056910523d2f52bc89dcbe769ea0f1cfe3dc559a3ee0a38a770f90784895b8eb5099b3b7da8bbfc1dd82c50448d6987f7b77c02a6d14d550cc3d4a736663dfcb99c2c162ac3792e3e3c801b947fa26e6d2fe541a1463d50bf047301a21513872ed4d537fab3686bd7db80ea410705630031391cdc61a44f835e5ade519dba13de141ec1bd7cc66ddacf0276a6a7d785da29e051142d12f8bb5421da297695531bb6659a71b02540fe1fe2c82101946202aabbb55e5b30cc59a539cc1e5a3cbe436a9ce6ad189c89fa41a8a483cc3b243dd91c10e86b829277545f3d7930967f64cdd35bc7b796a4bd8007983de22d02de28772a4792abfb3d28b10b3f096fb779e098e7ef665b935e5ada2449c89652ca90058f0593059b67a787dbeefa79616161617d2691ede37708cf0d7285d4a3fc3efc0e89cae5c7deac37ddd58be131f4113f2e6d48d061bd5ebd90a57f1ff638f53bba10c1f69e17af5e90eadfd7ebd50b36f4efc352d49e0bbbaceb8a64fa817e6bf7e9e377c8ce7d3a519c6138e41a5d7c3ea28b1c7d5ee3388ae2388e432239baf8b42712853dbc769e1d4fdce278fb6bc33a5c0a9530188d170d1e717f7b1cbf194f58c96e8df7c9258ea6b55b58b704e01dd2f387f7a98dd50d528fb65ae8f973949e67b05b1789ddba4f4376fe1934766e52cd3fe2a7454a4f6f0aae14cfc520861e2cedc86462c323894b3129a36b85e2aae859e4cbe0002b8d678b7c3b873d0ce59e275682fd3d6d93d33639cf6e9b58aa0b33f5977bb53267fe14b16fdeb18d7177b11675f746ff7d20d4a3eb02049d4ba1d2c56d1496ddffc0458cb101171d4ddb04cbee9b3eac132bbb7f82271cfa75da62a1ac137bde0fa1867effda33b55d6858fabd01b433e8d136016174dd7a6ad778316e12ee5ae11d3a617bd9f33ccf3b327a9ec7d96cbe90925149d6659a2cc7ed40e9b444917c5712f86991056212ecd35aa566e1f9b492897d5acdd4207a3eb52594f8d4deb03958f87c6a5b28628ff48a6550514b521c581a9675c2b24f5833b0eca6b5ea56ddcada5869b5aa48b7964fd566a34e23a3bdf7dea5d1fe25acd4d17296c6d2db3e45dd6ab5daed760b4b5e7b987fdb38f5cc76eb268db7dbed66b3cd6c335ccb0f55e368564e65da9fbfbb753e45260fb9ae57db2b0f25783755cffc3fbcaa67cfbcddce363b40115b7fdaf15c2d6a1f2395a9f6fc220f4f2882a3d106fa6d9475cffc308eb1ee993fc671098e8b3896e22494bdc4ff7012cafef32f4e42d963bfc34928fbce7f9c84b2c37e6986a9d4a4129f1f4b5526139f9f03ac746b355dc35a6ad2cfe7f2f3e3ab9ab4f3f9b1983a032b5da92ca3cf8fb12a53d14b65a9ad9bf574b39e30999a04fbfc360a675526f333ae6159fe72ef5994d6b886d5b3f746dceaaf63f81b487491e30d31177661163dd083897ccdb6cf81b8edb78695b81b6783aab2fcb79a4d4aeb9d391abe5559fe8e5665f939cce11957eeadf5cedf81f95c4562470ad1f764a87af5b9ed3e264a74b48ec62496ff431e12dcf69ef2e776bbdd7848121ff61071db798c766c369bad67137de833c46d178b62505050503eb0a10f4b216ebbcb8471348e56c646116c17faf047f4823a2db59be21dd53df3e35bde9f967b7faaf3adf6a76714c1f6a00fbd0e493dcab947cc50f5283f6eb33bab1e5b4705f4f6d3cee69d403d9ee822479eff9ea787e7f50212b517a44320d03572e5e6b8873f5ee5f287401d570a953e3f6fbbcfa8814fff31c3d838bab846ea91cf8743e2e53af4e9e9e1f5d6ee99ff76bbe5e789edec90b1d96cf945d8ab1437bfdd8e5ea0a0a0f2bbc08fc6d1b05207b569dd169b22ffc8a9fa918d5393b6c9a5d66bcfdf69a94750573d7feed0f4fca19996647aeec4f49c9f67ec6c4676dad58c0891e888a8a87adaade9b4f875a1a59be4fa69c56100b21f242cbb5daf758825a4f37c7c2f542d53cbd8149ed7d9f7b88bee023144bf5ced96b12cb83136c5fd2524a4f3fc2f2f540dea96b15e0d2be51b96ddf2ff3c91f22de54aa84a1d0dcb6e788c65d135d914f7cb205b85ce43a167332db95bbe754d3de5c6a417887e51d0d3bc4649bffff18ca6a6b8af794e536ff5c8c4baf1e052a8cc6aee795f879fd7ed18d879278a1304b933f5c88e2eb833a3b86bd7bd97df33b9ac7b5e1a56ca4258d9fd364ef988a7ee9950b369beb1e99a2c8b2c040addcc2b61abe7385afd663538329a7ce3b272d64d3a436e34563dd54c5e30dd8473193fe76cf36845052b342bf6caf77d25c6fade192664dd86d8ea49839473b6961bcd2a32677ae03c1263ec716dbbb5b37b8e1ce9fe9171347d80c0caee9b9042bf58b6c7fd403d9a418346b7e5a1c9eaa92552eb617280226e9b049a1f5214c79101dfeb5f586511b7a8ecdc309fa20fb768728b5a60e2b5f3637e1813612209fe3d11e7754a886091f8b99901c6b9454b706bc4473bfbc123c43fdc117db8ed620fd1f8c2761f5b423dcacf937fc7b03f13e2e786e6fa21febd10b734b3c902f1c52d68b382eef51637e87b6c0ffa31c717b6f77c08247e7cbfcfe88287dbbeb96d02321a5fd8cef31ea847f989783a0e2630e39e23d4a3fc18acb02d2d3f6c67f6af1c4386558f902806fdf7414241404045a2f6606c007a463fb717f18a9abca23e1ce715dde1a9d85fbc76d88b24bd1e4f8bbac32d1050a54ad7db5eba4890670ca12704f243a0ab976e06e1a74b5f4872cf04e19ef9b9a5bd5e28d837b5b096b662529ba66dba677e353d3f08215426db7f86469284386ed9d1534be40b6d045d262cd88eb6f7c14f6c5a22c61e16fbc68a8221271ed97918a73d0afb186fc2f128cca43dba639e58667e3dcaff227cbdf4078e2e4410c557e542fc7a859e087edcbef8e24ce9ddf899269cf66934feeb9718eed8d65a6bfdba6ad082de07eef013288cefc0f89f6f845d3ec05eabe4d0c0aecdd32824ff43d708c2426ebfeffb7a7a88402e8253543d3540d0131528906ea00043c4aa011020924553a92147327f2af625ae17403df3e8893b09e99ef972fdd6de10ccf8e0c64d71ae1fe97957086ad203ea99633ca02619b12df8c8b88723c79d67f4489204c1b1c3fafb5ca4d620f8fbc1073fd4dde862cca1e5e140f0234df013b5fe3efdf1a0978bfcbe4f83200886600fb73ec69073dd6b24edcbdaed09a026698074936260abb0877cf770e4de6b247148819a1482eac14d9af1410e43b0f3f967ec7c8e797ce4316dad1e65eb344763f2b70635c9dea8a79ddd184e569ce7ed0d337d76933cf8e0caf2df3ac722f911417389a675b2a6d6b63fee506ff132eba19beebd179ad67b9e9dd748eef09024f97a9124c9236aad7bb82eda167a7e98f891a4388ee33892a1abe2f153722479c4914a4a4f2d930bd050c9014551144511c418638c3d8c7187bbfc60288262500ddc7f5386e430638c31c6b90b7aa2dd64d9e1038b1c30529c94a8806548017860d911e6ca98f2c7151ac6f4cb6bf7f9e65c6bee6aced9c4782afc7617417f026a07f273cf1161d1f83fee3fee3de644537bb4f74d4f49b83035965d15f2fd9ea4e4f4d4005bd4fb265defdf889eb92f6776d9f7d358a9c4a1d796260d932f9e87adb250f5b456c5b6183b6371b2acaeb694949013b171af542950c28d09d8e0865b3d6be738174574fc1cbf1dec80bb0f7fdff775994c69f48c392fe7bc7f54a6b11edddfa9b3cb7bc68674b3e7ae0a7faf3ffcf4f7e98ad46b5d42fac7f8336dd979af4d9bc6aa4a2d30b6da763884a1d57225466750a5768923a30b8a4e1e1baf6572403d1ab1b2b9e4eae992032a53fd189685956353fcfd7d41f7f7cfbab93f12cd94c30acd5428abeba9ad63e55816775653dcafc3f5986bccb8d3e9b74e3dbaafc1959ddaa8a8a81a757fc6d21267a65fe62d1b350ecab2f3a0e3b7b8a6b984d65aeb01fb2488868482807e4a9f1e9ed80eecb55de42886e0a7bddc71f8d6a37b047f8b7b7df8f2c5c8979b44d5535717b187d778d8bac8d446097a7eeede1af7292c106d252a8ba39ae2fef5fece6c3fecbc635bc6b5755e18ca90510a9596c63dbb19b5d36a154386ada796885165ba4042eaf77d9daa5558f47a621705b9be3e006c002ad3ebebef54d8d7172d0bf2eb9316867d7c7c7cac8f4f398ee5f6f9108b4b58c93e453d3de1d287688a8ff7c9623d3de12d67bc3339760bced69fdaadbd7f5b6bc7711c7f83200c06fbd013456eb7ee12569af154d6adb21c4928bbcfdf2035c9e7f3eb6d9c6ab72ad37d1a817e839ee779fbc3dae26ad8165de4f88d1f09f44016abdaa82acbe5de58218fb889bed8717f1d5bdc10d62647af2d6ed8c333ba007acfabb1ff83c1fe1b15f0ea30f3d6ee1310bf43e004b58a160f27f4f2a11c68188a98dfda0960c0422faf68288a970f9100c59c864d01880f20680d520d5aef0accab992baa2df4f2222a342445cc69e021360079426b883a14a982e2bf9c4611155a63070bc5e6e77444122df4f28ac30e68b845ccc1a91b35352ff1f2124350cc69dca639488c406bdc2b55a8be2b30f796f4d0440bbddc8ac982863b22e69e0f5f7eb8a1616c07f6da2e7214397ced58633e1e14199a64a197d72b4bd01ad762ac3b43eb8756147979655cec9edce8a2bc27f7e2879dfe4ee75e7c93fb9d5b75077ef79ee7bd8d7e79fa1e741ce6af7bf066f58eb3dd4dc248258475ab8f80ed87a01b8969830e20ac561aeba95b7304dcad155610ddd60384d568f6d15ed8a9dfbb75768031c698bbd27b0b0c5fc45bacecbe97d90e345cc609df8088267e935a2ffd6e61a5adad110cad9cf33c4f3b03bb3bdb029fbb352890dfeead17d04cad976efffe0e3b9429238410562b34533bebf676dc3bf36aeccccdc50ff13572cf2c5d7f6a677806756b6ff6fef4d6f89758765fe23db97bda0e2a13eef65e9d57f5282cc591fc6a95ec16eea032b9ded6f0d63def567eadf1de443d7f4ad453bb75f5e2769789b5d4231e36064dfce682d9dfa7f84d0795e95e55a6ee2f7ed24cb51ecd746fd1fc423325eaf853a2fe5d81a02982ad6367e9d7ab979e5e315d73339714ab3059563a3cdde7613db21f84f12dcab2d65a6badb5d6e25bc36edfdadff6de7bdf72bd1ad920c2ad310aa5a22c152d36e040280b45b562c5616b24f4558462e5de980b576bad95b31c874da90caa6e4089422aaa14ac73d8dedf378cd8afb5d68e599ce5b2ac94cc10464a181f372b3052ea514deab85aaf3a0e53a98d8942391e2406d5e10c941b28e4e0a10bfe01cd1639dcd51c197ca860e0e098a11c27e23174433b4ea3da8a58b2025a03770902f3324846b7b734a1a19da9690489413973733b36a74288992894fbebc47a9aaf1082621a952a0b0a26a0353c1e51507d57d8d756d6d09004ad91af7c41bda921725c416b785523403db3de15365019dad45866f5eb0878ffe9a008e8af91c7cc50ef3f53ebad3b8769bb3385ee596ecc4d1a1587295a5cd01a7808d47b1be87957dcc7286cfbb9c3a6a87b8a82aa8daddf1763fddeee764284b5cb0a6c186ce58043ea4cb718f0a892426b586b4b085f2f9c41fff400ea99411004c1298b6dd71c7b96d31da735893ff0bdc75a835abf401ef4d21fe40a22f5078d1a04436ffc16371cbfef7b0d63834fb7502384124c8e20f81e07ffe35b707fb9c8117321377ada6ae923b10ff991d05549dcb9d095bfd7a3fc756c9103c62d1ae33062b450b33d0d43c3a66b8efb38d5f4a37be38b6aa6bf74a8c73bda914c6d74182d102085c113c5298ee34f180269dc61bca22ece1b47ec799e478e6138ee8ec9714c4feb0f59fc8c4b1c47974b74b98cead94f0b541617b029fe35f4f561dc24a1afbfc14d8291f8fa326e12d1d7e7e026ed0ffafa1edc0a54265789b740f615b4f66600cdd43dc23f7c10e883f8f843fc087f21fe32deb4843cf1e789c7f1e8056f016f5af2996fc27c1c8f163d91ec4bf0a625def946e7e378d48210ecaf63c77c0e64daa6af9b3ac807b9ee26c8131798f8e7df83dceb26f811d97f6611af7745682ac93eff08b2dceb0883d1e96432d3ceb0ece476c795e5b780d7bbc2f4617938241548b68a9e874ba15277f944717e1f297edd1b3d87dfdb31ecf0533bcb76c776089ea7895c23095a226b4118f8752471fbf7b5b8200882a0fe0b581620d414f973aee0fd7ee8eb089280919ee7799e07fb908888e4767461fb1d5d7c23496271dd8e53268b786e6ce068fb68ede8e22b2d167fb8edcf6d939d5df187d71e12cbf6216e7b588a43bc767088137d71e3d43d6e5f0c79d04ff9b5872f706c5bb7e391222e6ea27a1d8f98dfe2ce6e12ec3389cf6f692e60ff71a22f7584b929d2bd23dce7c30c12f1f4caa58d0a7a42f0fbbe270d361b0c185a23c1c89cd763a7d536030bdd116c2aaacd8ad3a705dbe0386cff0234dcceb43db9685dd6236cfe04d91368ad753d92d970262a2aea7f700823a0a86971a216e741054e7cb9595d0c19b9e3f27322d8187687d3530cabcc11206baa55290f45093a2a2a2a0ae9c44a48515869739d3e61cfca1c352baf08e59bcd667a169535bbcf611b35675b257636b3b3aeb18cf7f071c77126bfe8d561eff05e128081ea9ed5f2a4d47e5d2fc0d2e9d6bc5df64eaf54666a7a8b9bdab88004b6e370c761136c6c2f508331c61857bdcbb7b47ad2b0d2d6f59c615f5b952a9794386b8d9a4a4e2f2d2d2d6125eb6469b6c912ee6896e6c24e97962cd2d2d25216d7a5b6e3ac9794e7755cc7853eb02c3873888410a2e889f5e8048ef4fbd2fff97fe20756ba596b7e8004037f8095ba7f990c3bad37fbf45876bb6da9af37db04dc11729df7af398ec3fb7ae972d7711cc77de6b8dc19a00428ec618c45b03def2e7b9d19a535e6300b43c42162f6654bc98c478c23a654cde6c02112d5031c42de2a487020d991af95dc7158c55206df95128343cb54161482dc9a966c40f243cb8513449004886c45471aa05eab744cf5aed72a1d58e0287d06c8d2718a2ac34474b6771f7f3af6fab10654191e5f90fd9a31ea117ea31c74764d5daeca84b4ab12065586ffe70706ab4a690ab2e314f5083f006248a1a5fcb0c2431d2c5e982ca0cac90dab2a39351881e28fc14194895eab5620d24324523b5e972f778d625b2c53f45a25a4d661bd56e98082a5ac78933650760de8a82650356b9db819dd738f3b0a50a8c08063490f514eb0a1038b93376666516ea8a19ce94156ed5f909e9e4f3dad5224e869c502d2d3aaf5a3a796e66305fb344418179e56e094c606940d0eb319c044793323024d97c850c1c1c309b72b2550506c8e8132e50a13323f7c00835e33adb711ca7801030448972d3ea0a99d11808d0954769880c44c0ad0d43e1505f1839a1b25d8aac2064d6d936e7b68c0e30b0c38603941192250fb044c550a344cf17062250686283971a0c401e304b5519aa48044cd0b655c40399015a54a096c4aa80841ed14203a4cf1c0e6853150366a6daec8542591a1cb15d456404e9a2c543f8aa00384eeb1068a4b95312cbc41ad546f718f204ff07c4ce9e298b0022f425668da1261cb1497245da69ebcc1546c465a9736ae5a172d659600a1e1cd932a5c181b40a8b4b0786842810d737290d08665604093189a72a001320788e805ca0e5a5a38e3a3693cb24354559b1b9cfcb86956b0a142044e92202ed0b4442039ea48530d6eb4a85c58e265474d73a45603104878ec488281141dd25429020e55930d30f82033474bd3162c38dc746e727841cb4d181e9888800c7641cc902142662a2042c7849104368ac0319343ca089513f4c8d286b4553335079b98ac3537f800474916189e0441c3105ab4ac7993d95c14b8017d906638dab9a4072744007144123840c2d450035554103ce07c60650d981c5030c28b108eaa832d2130f0507344103a6c3e15be1b8a08810d8e1454f084ce143746b0580802cc16aa17dcd8e071030b5410136c190304cf99408e1a82a033658d0a66dae42d39a000872d45523027052cc5861123903c71523353418c9b70889107ae889a1c572a80d3c30ac8a0b161823070eaa401424d172565ca8019e334c31320b4a2542c45f8604414206ca2d0de70d9b8d72a1d2f9067f6edb54a47117c035a84181458d9b2b0668873a58b8f3831cc80e507c745870bfd362152650d99393de4d4d1a0890e215c1bbc8297f497908cf8241096fa9287b484a442bc59d2a4909f7c10635b1463423ebd56cd9975b0d7aa3a45c4dce34ab7f6b5fdb24af9e05d65b6c5d7e5a01f76ac14ca40c5520f3ff474eb1c627a86b373af555872e8e9de258ab38c6da1160880b1c1527a2255e968014dbf5558bcecf27badc2e2a47bbd566149d2d3d36a054e06a01e4edc34ed1025e4698519537aac0923048f1160a1a18de0ca89853a6b6cb0f04385aa1d4c6c905365ed97679fa2a51645cb0115258c8d245337ac7cb4f044ea88145b557880f1f283962c6ca83c395921cb981c5436ce870ba48083ce10408c647141d73a47e4e848410ed691262c0048818ea93838c4a0c6884f051b4f32140963e5063760cea0f52b06a2d8132ab820077c420de67490f1206e8b5a8e810054d4a3fb4b96053657d4142653bf7f518b92dde8c4909d2ef55b810fca25adf72eeb920eebcb4c58cf74ac6ecd112e0b314dc4ecb85f654c0c5a96c9087c58a17609962f365c65ce92a85a35a70b8d052d18b4b288f94d020565f344cc59707122a53f11f3bbb5e3072b50c43c9598a8842df80431ca10321a2800000400c315000028100c8643229148948589aaad0f14000c668c4074523e14886449100331848220c61863082004006388310611538416015856b787dbb7401626a5c68741d235bd1875daf2de68067da3d95718a5ede3ac3734ec0d3d5757f8a62a6a55e789a45e57519174557d48988b0a680d178b4ca6deb34347ad52a7fc37460a7566eda14fc29674565fcc7d04812e965bc5488777a0a7ddaf2cc80b61067846a92cdb2382d9d3a377d36c092b05be742de91c2dc2b314f9502097ecd15a19576aa528983f053c831d02f952a45d82ddc7c217f02a5adb34dc58dd99df255e272a6a4a5792cb269457fa58aaa4bbafd08474d8a3ae3667ce3061642e94925a481e6d44e088c04bc66dd0987cad73088c3b9370ce7cb583369b3c4236b160ac3d0268a38dc7b9600298f3a9eea0922f1e754a7355bac90c94900c1445f6d37947588406489917367d8d4b869fe3e7569d873fe0edd4e73820b0f02978f3d815b1e58f1e633fc2bb938340d423fbb205e66997aac75830514ab5f74bbe79bb8275a5aa3c7d0d50300157cd017cc020557811b331ae0c5e898f53dee5acc93154989002e7fb27dda791a0a4a9353a4e19da2c40bc86ead76d918ee96fb678612283429312ccccdb9c4da703157dcc2865459907aec6d3714011049910322395ea5353c04f2fb7659f1af4c13e7f34e08154a0fa47c10d4a2848e982e0432d0bd0d6a5ce05dea68e523a1331668506bef13343a0965e277dbb4bfc83976b6d570a57eb72d23dfc06ed56d82543e06a21c61f55a90f2e6e8cfd2ee505e72dd58d03694441e136852addfbbc066102c08cd50d8edf2de0a188f823a1b613b4f6ea5d4340bd6bbda1517d37556060208731e05c2a2bba7b6c410a385748dcd581056029d295e79742fa26801701d9344e66b92c7962d83828724a69aa9314ca9a6603325450723a85d4a8949170c25eafe43f5b518536515d5e60ac0f5f2a12941e43ec81a6de238453806ae3d6fa488e3f72d5750afd09cba674bcdd2244497e52d7d6bb26df8da1cfc81fcd818048e588399d0ef4e63b60a6d3bd2318f6440248030ac3ecfe77555e27b97aa000df4a8bc1e4c9c308a32ae3f3445e93a7f1bbd46905ac0cbeb4e854dc151eb0e91a17168a04a2ea737d97c238cb6a348aa22f3d7073830daf534ecee65dc95917ea3e55bad3b6cb12e998174a061a5579381adc48a8556d2bcb5cc5e079fddd7a8023bc96d02c77e35543f24595c45a6830be7cbad090731d0e83f9451e58ae2c856ab394280bbf34e0907f4e131b3eeb74f6c64707d678c8d6a26edf8e6fcd93d4a52785523e4848e1fd838e6de1c0046c197b1a0142198d05d05d3cd9d9adb1617165e42297c96f10ddfd005cfbec86e1a65fcbc9ac18dd65c74450ef2f7d35f260c0a9ce92e52ab0ddb94f2b017c91359fb0c8246d71b84bb3a5bbd330aa730a748c27fcb670f5672699595e924197a693249db6cfe8a9a70601b49ced6c6a1832cbd91253c31c8898666ce04a9976953052e9e5fd2e8d8d4f21dc7e0bd36931617d4097bfec3356ab8fa6f9e8043cd2640f0dd6433fa3338a4257444c5250f7b3ff4beb089cd1d64a3c5d5d787a52d6a8434c74f3ae876d2b25d18a3569007a521e750611ba47922ca727e11aadd56ac58bb6a51b720993699141c17a4dc6ba29a2d92a22514330f50718dd1437e02604dc18a771c01d8a5c27fd36e31d7a2d502e7aad15755fcf8a2d616eb6f78bd32b70a3cb784bd1f4b4784422d003a1baa7cb2bb6a8a5d2c77e080d8041c5cff3f7902ed6ff30ac3e95fa8875eb0004eb144277a325068f14d25eb5bbf0e2c20380dd8b68742430e92c47a2da2654ea9526b206643b59297dac8a6c5c40498192536c8d06cdb7ec48164d210523da2a5ae8951e643ebeaabba56e192e15c50f134db340d961577626dae1c06259924d9541d93924e4448bf5426113c89c309392807470ccd02b56e81c6c450985258f1316ce9cd2bb78ce10acb4425168ed288c3845047092149d78aad5fe0ce61dc0a169fca6f57072a590fe1052b06495ab18f0cde1668e46651138890464dcf4187f806a9167496021ba6bb2c82cacf9fe844fea4b0a4b3877831ccb8741f630c2c9c499a7054ee8306c66815e96e16e60668779b84be8c403899b563d418ddb7c2825b72220f0813ef322d20d4762534015cc7951460d4faf10f6a3e846584041a39087df3efa834cdd06b55f13ea263b30d604f8e996966acfcd97e6f88011e41517cd6f402163e9207969010d55e2141cc44a9c2ed4a1e32deb4e5bbc009c420f0c05e835ab99ed3120bd95a28c7553b71865045ac058965c588f5cfc5faa52f8536add56ef7956f42fc1928ad97fb1f70156a3faa17d05b35143a200233d53ebb2a457ce303351a3bf9d25314926eda06c0ae66a0f1c44ad5266a40c5b754236ae1e4bc5d502014d6286037af7c0fc32f967890460bb1eca22a3f5395341fb10395300ad34324b3a7c1215f293def9e760c04ca780acb98aee065646f43cc0b0c8f0c3378c52b2b8ae68713398fc769d0d0aef1c9aaaaf54d22fab48f6c381be4b015166bdbd112a9d60cc73876da529c77d62ac21c9e1d80b44d4b56a2c89c55a636996bee9d0b08e4c309ad0f14716a66790283e70552f758e82b24fe73f392998a9e56daf04768fba136f4832dfad2c81ce75134049e90e833c60164523964fdac0f3c96bd96b0238a33432daa0ffd8553bb418051b44f49d13452c4adbda1d07ec607c1150c4088f5f72bdca5fc429b98555a4185aee2fe91d86702e7de76b4d1bb94b6d2992cacc6e6424efa540d2a9a904ae2ba1473248a8fa33cbf7557b6d1f4ab05d77a310161ae85784c74bd2b99f2c53bea795c0c90414b15ae166054cb19b36f542fd9f5affdda432ffe47a99c65e1e71f8d338aadeb8b7e4bac57c9f4b4f2601529a39d3ed9e83522d56492aa4bf71e9bbf25f94cc5fa0094ee9a4ca77a2a55329616a682ede8364c3ba28c7137fa429798dcb7d2f26ea0f9ba747fbe17f6551af965c127e419d51aa4d9dfeed0989b7eef8ff724ab512493eeaf7a55c7659471efc75874f8966c577aa29daee62dbd91f522b99f41e54ddd8590cda0d3697683b267542b6443631891f32c6231d861dd309c605a610f73481036c53590e967e44255691bc9dd1e355745a57580d3db2f6cdc30fd14e9f98afe59f10f547e83f78ec57c2aea3fb1c17b89303d0661d75dbf7d995a6883af4c4d52972b4634baf3fb069122dd8dd76bcdad2d0794055ee14ffdae962213dc044d8d5ec8afe01edc79dfe3de47cbb3dda1115c360b55a65d4d02cf177f240f0a2eb3afde069e928627f7a427d671df33505142be10924b22c2848b5df9372539041799522c654fe1b290e146c761ddc71c8094acbb2d64dae060fc6d78d939ac314b89d3c6c06dfc8d9c30d85d26c9c18fbfd6381c624ac2ea294d4907fde202aec02c05bf36766fc9d6b8075c4130cebc812329c2d22d3e0386fdccb5a72f9e0431521ffbfe845b02b0c2d74a26099b203fa07f8f429f292a75a0178c9106321fe024f685b80037b13a59418788324eb4d422e34922fa74b7e3893a3716e87be0f6205c52fbff7714bf799efa3b2090af73476d249fbd267e6af3aad29645cc23358043d8ef537ee86a358425c5ef19c285090a16c2012a6049b9b0f999597f328b3f2b6e241db54dea265fa260fe73040b1185799f1f6b9c6ac56e4264fbf069d8c1e28a837f1e9d7a0de59dfdc5d0bb8b94948761b0bb3c6e7fb4c9aaed1ba52de178337d754dfd076ecdbd3b8e590a863a8adf2b86f2baed0c59fcf9d46c8de01352389b54855dc44123f174ab4a91c3b82d9af22309d0e233f2353fae1cff7c874ba00b9d2e9cc411f690579e1265135123a5cdc989157d015b1349a24dc68246d0fa5cc222c0d7869f77b5dbc928868d33da91f721839b7e6b286f2291566fde9312964261047202dc9039d1024673d75f34045e7336886805053b8cc76890ff7f244b65a90bbf57137aa13b5a4121074cd34a30d68b0ffa8a06e17502e844b0cbdaca96ea67c656668bf978f277b372a4730ea4895a5b61f16e67dae5106c689a3c6ad6b1da23ca6daa4ead7efa0616e1255407bc33fc64c69768703690562949b98d523213027e5c14bd20fdfd58d0dfc0047f09d8baac11e8362daeed8067e5c9b33101c2452c9840aa0139e0d51bbee23b4e0c0942d0f26841d655612c15b49c02d9ab088a6cef67fa65318ae8ac23c7ff5923ecdcae2c6919ca35fb962073e35b3312700d23af281a76e6d12ad693a883796c667fbaf9190bafd483fde669a9d2982e3a7c857cb39c235372d829174adf22c6431520fc3673532a4157df0327ec5e3dd670c4e94e93499ea4b73947921e79dbe2855668a662beff76f2f9f08440ed9610acec2affe01566d1e4b306273f48c9f5f77d1186c2b0fe6a76d94e32237c255481c9d9701a9d7989d70a792bfc62eb6dd97f8b3e193a6133414b5c241f5fe30e0004bd923b25ff61ec64c224b16dae085ae9f07e75f060bc6ff4856a569c8cf69fadd68385f2f56b2df02a22fe24dcf5a39d1fe75026875bfd7fbc1f006df3843c1bd405883b64e63b26fc9c9e690369c8e8a00f1d5c02d11ca8e2a9cc9e03b0013e18cd19c700962a4f44c8752cd4d25a4f1d63f06cbab488aef755770881bfac77107768c3ac448a917030d7401c6839e1a941791c0f0932f238559c2cfb90645780a86a757d5466e7541860ba2cbff63008972a01ee4067556a0084b5b57a99f9ae4f19266efc0685660d62dbe7a27d43ac0e841bb97aae96d2418d6c992ba0d51a4887cdae5f8a7ba82854afc810866f09dba8fc4496fefa2bcae0c7a07d8e80585b938b7110355549fb22ab31ccf9c367c2ec105ed6d3c39450233ca58f8a3882944dd393586601c416a9c4693ac52f3a2dbba9bb0fd0e94900507b4dfc831004ab91e48dc48ecc813410476e7996a69f6b57b7103bbb7c91557e0892f0405b7f0e02abb6fc68596ffefc7660a60e75003cd4cd614a5864faa43b47b922fede66f26b1808913457b70d561e3cc310801902eb2bd11d7be385c6fd0a596e38023c1fe97aa2f338190074065061a65f9bbda278d63d64814a50a6016113967926eeb8facf8b772ce676d2005ccef7e9ce8f3b3a3a224bef2754053c9501d75fa16ef0bde921186973e23cb586a03184ab4bcbeda4f10308cd71834b9524a74212283a693c1dcc19e0714e39ca7b446e841e72507502de3b2281fad746de3b2a04c62ab257a5af314dae2f0a0c4f0ba4c901e533f17cd7e4c4406b9951f5fead807b5c5947348bb17ee134b8fe66e3a19758770e6c02497a322127ce4f47f8b5a181cea955c3f29696c0d8647ac412c7d7a8adbc783307649816ec4ea71fd37f65f7fb488d90d4b65669c58f65a712407d5663eee2278f2aa1be0273974e0032722065c10187d832de6d750bca7a18a1deb01d8516013caccb9989b4f3ab089a64e1a4764d12a833a2d5b4e979e3d9cdf940f4cda95db18efed0ddaa59056e1269f4314ee1ecae1b771e6c878d53495879cac1e75d5d4331df945b391c68f827490ec6f6ad8f31d49c34775285327a00d740f13c490622ef588004693f02605f48fbe35d4ffff47c622569b36b255e261d4c77403ee749d1030cdbac881f4070026c9627b307a09d419ab7ae9b2cc592f8713f8a1b0e03381d31e403640b154ffc8d0c9b2b9976cbd1323b752c66a06a2414fcb4fd57cbac4471278207974a17675316417e314ea5111dfae6162eb7b9b0b9a8d6543974a9940ec24a9f2a3c38d9ad834ec7762941f98395f9224dbc11e45edadbd0c4a072c0f3824faf2e8b50b5f67f2d32cd5a195ed481bc1f1fa7698a6bd4964325881079c03b4c3c3517135955034195542756caa122a4a656e1f4de72f0e4137b4157f156f15054512313ffaf902bb6f73e7e426f719201ee5e84028e01f3dbd04ef6dbaaa29c0443cfae133e6ce87081fddfea210da7742f630a333f2d2f56658f9033f580385d867b1d41fa983580ac245ee27dbd289202551634480db781c72301152e73e1e7decb3cfd39d1e13f215b0b7c0c9d1bff48a4462a312546119e841ef3352cc69e903dd38c6cc363d94104a40aceb41856a0534e761308e5b1d63ffe8ca9d05f0107ac707249e7af2888ef8a5a2d26ec66c8ad1d230fa1d7b5bc88230e11a6cd593e916c59cff0117f8fcd2eb576737fecce367978c689e6af15719d502f377401b9813660edb9c2204f33604f3ed15c0a792b93714ccea45593e1a6539ab7b526c3e1c5c2f4a8ccea54758c6671a6951f97d82094584a496f236db5fcb0864755b79cd0088422ddb48dcdbbe5e80d3a30c4dc93257f3969ab30c8bee7814d52d438728ecb41758349585ba73478dfda0b99c4fa066d75a9f10bb786927e431bb6554fd02c81077a3b319dfdd5e1c0b35e7b12f78a01fbe119cd6e3c8756c6e95d8854034b09ab634af37aabc63bdaf73c5dace0b1a927d28bbf1caff48d13c997e6ef119e10fd75a10cecdda057767171300f18a8109ee73f3d03211ef18c52dc2319ad4e6f157801039cd1ddc723ab745046c76afd673b77422d7219f9632a4b8bc15f63bd086cad289a6eb656201dbacdcfa05168726632d5e9cff34efd767fddd914b1be706d2c3864bec178fd376faf8d40a393c920084ae4540a86920a8ed8dd94f1bc09a373726eabdabbfc1bab242b45575768431a7de3b36d6417683a39abc708b9e059dd44b3ac37c6553ef9b57d8e31bedb4c974b0421dca41dd3f009da87d7650e2cc62326c5192908637a718db763cb518c7ff7810066b53ab82b191eaf6bafb8b3a3978ba0ea15068a6ceadb850e3069a2e3fec8b32e31fd2934231563e56ace05c6ddaaa190b35e6455e2e323856d2a352c90daf1c09c3977b8ddea9f7cc3280c7e0676545ca93fbaf78b7f23dbac4f45d64f20dda565324970359b908e6ec7b84ce42b84a41656da5c67c2974eb12b3e6802c641cfbc1ab4c643c12c16c3421536601591cfdd2de94f459de3ed372c6779ff23f06cdfefb08bab7523b1d131849ffe9926cb1c77bf2d6565b4c55e0d795e5cc70a4f27c16dc76601e456618ae1250ee748f50916f49925d5be50164519fdcf9ffa5cdc0b0077accbcfcd2582acb7e1376934b098071abee3d8ebda32425dabc3d709302572761ca32d5fbf2ceea91ccc549cfb4fe6743194ceee28080616146cb0a6c762a01ab30784879afebc0273c8333d4c71fb603bc2416334fcf48928f761e76a63d5f2a282f03fd701f22b8649f1f6cfc3becfc53113650db2a318943decfb0648b2c3b822ba3adb01f9b335396fe05b571fa2c44ad4978297d83a37e2c609d0d550b43c8647f8f2dae677b429f3b5971b828423fb704c0f9a777ea1ec02c71c180952d0f5e7f09cd036fa458c1d6a2ff0db6e759abf9112a63e2c2c31da1524dc4229f1130c3d76577b0f1f375856ee13902e90f276f88dea6d2e628d4b50a24ded1299132e648080b49d761e4a2fe8a9bd2a8c389dbaa661d51c96db5b292969ea6eb65648b54560ee9fd372e198f63a3d6c23c88bab1109cfd035075b1465f7987be94822f8cd7b367b604bc821863987f6a8f5cab6cc8ea1c7065cc292b3a8853ef6d8eab16f00cbfd49297fa342c706574ce0a1e459766ee375c3ef275775cf04dbf3f42ed74070c0edbbcd2029ca2891fa4623735bf30809112093f269796440c1f9ba0d50c8aa2530e81f2a836d9737f3188e61a5028fca9ae1820fdb7a7f783d3dbceed45e66f1292c192223c07828ca2ec01b46a17acae23881d2e8d2609a43a3a86284a8d1a9f8235ae6ae3ba304ebcdbfa9b8439c7764099103665091bfa85f9bba63b1357b06b5fa057de5962f53b15d0bada466bf2d4d15955212f6ba86c21c928cf71d89e25793820e591e58c4ccaa8c95815c942d567f14abffd91d07d675d6658af28277e905a07f358e3d8c01ddbf6a05377e865beaf56653dabd5acb293c7c876a4a38ec814f56fff65650935c8ffe4c650ca83854763e7b07e7c2c9157d7d551ce1a074d54cfd903ca2cf9d3b25305b863feb6e2a0d4610cd9eaa766deabeedadfbe4da29e549b17a63f15e4204e684200dc01f6743d85882911426a44f037d41bc14f6feaf98e2c9e582c1c21092cf9d3140f587065d4a07c1620ae49eb02a28efc5bb6875161283d38c7e923e01bfa2d9a46261381c3fb0cc45b147e49fba0b1c321450b8fdf10f9124f4700d89ec8c257959b08a49b02c697a31c1ae5ba96950cf8fae36e3dd7f0a0441c81d83497673a61c04d6801d34691147c19d4702431b7711354dc742abbfccead83285b5c17aeb6615b83e499baca0b08fd36004ce836a332234706cef5761390695f6510bd11e02b0bbd5058441f808fac3084ad30620516a44fbc575939acc60111f3ce81b0bc76da318823e1c00b81e523dfa62ed1f8eb3385079c7f48eb5b8d4598544cace0dde2fccc9e7d3db3b61b2fb93f145a696bbe7ae15436b5e34c7639ceec6db5ff43187d690dd8dfb0a04ad316c807295b6d91c91bb6fa40c39ee65bf8c1e350345760b96f3775cc1e2c5ab4a0b7f262ec348ad317de1b042cfa45033a4a3c5b12d843c1b202e6832b6bc1872a15e522340823f527a91a21f6006b81584df8ae80cdbe2bc43d4eb3b2c8823e6a287908c8b3ef85304a5095b4cff446b5494bb3c94e2dd187a19bfcf1c08ac14153e07f3b7f158212ea0e9b216b567c12ccb0ec8979267507e92250cb026a53205cbc1a90324fa3b4c4f04e9ed9b4293e3649ad85eed59127bdf92d6302a80f1937185242419179eec321c769f79cf5bf4abbcc903cabe5315bdcb5054fea30126f420a477ab6ccc8da21c5a68d0eac28082c4cb81c89d536119a4ba8b967ea7e700418031f277ed3b7dd7c00b7c5d00ef5d5c4bdd226ecb671b94fa30a33f0229598a4f9590683e1ba35f6613e417b005028815dbf0b8a80a53619d6007158373533cc1622f0d2f99f75960e33b70bdc0691ebecc13870975285749b3e07c02b55249b83c26332841d7711427bc12b23e3797040cf35121138f0fa31abe2b07924deebe2696c8be73529fa24bd1b9dcefc1e8e561f15aac350d3077138fa846ef2900ca14697934cb43a02eee41177ac08981a44e9d73b27abf3f7b83956436c810b5c832c0c8ff271e78ebb300ee86f6088e9a24e5e5001ae33165c26e57d8e2fb0a88705fefc6da7fc333eb63d4a1896fe665740767248919df5a9b0e0f0e47b6c53a726c8be5208b5870c57b34b02811f8d58694a9781b86cafcded3dcb6c2183597f6b48985cb078c1b307da0f76ab899699723fff4eb8061ddb3aaa0700f893feaed7dd4f675e0ad36e745e70a7ffed36e96f7f8e0786a81cf587816c5015bbace7be376fc9201276f11a8ea1938242fe92f3e49ad56f572b417f721ebfe9474751bff581c80624bcb6fd294e420901baf153e1c62aeab7768e319a50d8535678d73225f5553b5ab05cb4ffbc28412bc44fe089291e60b261978df53909b5ee58e51586c1bdb0f4eb390ffb2af96e4d1bb25bb696da851a198991201f7ead5f924a99f514227c04f265db5711925be5238487d34467c6e071dbcc773561686e8e5af0929e9e26275ddf2cc939eec35d194b78fc1099258fbf730986ecaab537580876e981e5b78cffa4f20e88eeaf10c7df8c19b521afdc17c0be7bcd5f0cb16006ee422420b95b4ec0845e32758c82ed58b277fa4030078b0c3cf2ccad40266aa039a28b5e8362ce3b175181f2abee3aab77f5ef0c791a1af2da772bf19f1c8b7e7f9a993702fb413b0f0d73dac16bfcc42ab2d83c083acd609f4a612a7b15cdb35d6ac75dd2fba4c5946ce651d24603608b318844c4cf7af5f7c4d3c4e5085141a4a3fe72e7c92c7796e19088239f28c9d7f5493559e2f09cc2b066af6fac7ae16a837da4b6ca405262843c13eb372dbbab06e098eee488ea3e2868603856e2649794a59b1777689e6732d88e75ef885635159a3fe47528811b999286996f1df6a47f0bc7759c49c9b7b38537708d6b5efd4e5b3805a8d14eb4886307f7b0dcd61199069b568ee0c710bb69fa34edaf79bb876be5f11143746017e2301082c647a48c19c18a4906bad22819c71c7c33d3aff01c13346187920fcd9332c184fcf95add1b14be925937aa4c434bab8c3c699c23c18b2b728e6c94b0d0dc6639c77b31f54b7b9b96588f6e4870dfe53988f7f2cecb782fd04ab0732dc174fc1a9310aa276ccf71176ab8ee237072a07f5742659160520d69085f3f07e0c8d2aee1073d980ecf44207b1e851d45da63ebd38214944a5908786efccc76fd4e419c763a93f4fbeabc02de281ae57251559aa016259423a0e71d727c7bd699c028fbeca00c69363b6d2d923c102dea64978be45063bb1ba1150fb7cff4dbb2399318d1a30b56a79f7730942ac15c200bc9d0c7618107042b99bc2b551f4cc97eb559549038330a7c7419c80d0ac16f23d298bc8a3179554be2e11f1b1a3bb60adc3368d91e2ae964b11841bd1bf1257b1bc9375d8c656d6a79eaabb8196b14b32fb9ff5f481708c1b2171e760f0b863bacd858cd4c250e6436927f4ba6b87f520561ca7e479a5e5857e9a98d765c7bf711aa7b94ddea3b8cacf7747f170f67bad52d175bfaccd4a2ae05daf6afd386302544513a59936792834c938f3e0478618abeae49fb08310479ec4b3a0a34c5c2af9b6205644a6736118f7cae33e76543c153dcbf6c8694bae9f1c9495caa46a15e14142c2eb5c7c36b9096ae948da420e6bfc1efa1bdadc07a7c9b89d8a28f636f21dc8abfe594deba8f74cb6bf9560321a17ff840685fc017da3836492147b3c2e473b1214c72f47420416f8b3a50ddf3a49aa4a84248a5172ee9d78183b906362e8a41aa659ece570808424aa5b37b3ad1adf43edf647ad91024d1f09871f86fd28b3aa9b0a41515bae47f2a3d948086df505bd4af814bfa8ca6d213fba1c453bea229005c3bb631d7e9f5418b661222e72ecca3576cf2c852ea41d2de9e7912f552b21582de63f228c5c97a9eb9723de87a4fccebe052eb4553afac794ef45232a2dc1b9b112abd83be9e87617ab7f923a5d89b8e5e9596338e71bb345b982ca214953c49b23b7038a83dafdc12d7cc8dad6c559227b8e3c6994611636746bb1df152e7b9550192989acea9223d167bad8288901d0028b4cf3458a03397777139f1f9bdcf58e59c0dcf2c3a0d0f3dd75f0ca8f9008df8f6764bb3fb00f8ff797de8fc978d0805f9a62ea6548acd323cf7f4b2f07bcd1c9bdbad36964cfe25da165e94e656c8024b566dc61b42cfc2853311fb4ca9f8ecd2f6cdc6092582b354287c889037ac1e7041ec84a36635e8344ca1d3da961f67e73bb214e419155167c0c6d068abb784a2db3fe0913433825f1bc40af7bc39e36ee8f184ad2f18a050e9d11ef1c2f843f3d13e879431b3b566cf6aea882128ae26a1df6bb15fd2d6becda7bf6948cad74ed8cca6a688065f3bcc5942ee23071c45791e000d3cca9db6d057870942deb559bfb7958de1cd08f099cf8f6b35e5f206990ab96b5dfa2afae2447f0a9d84492fe348fc62b738bac72f508613f94523b60d08ecdff605a51a2523f8f5399102fbf50694c56c85f1efc76e9340a63104176d779a9ab4c02c2ee92537ea5f4ea6e6c71d72408ddccab6ab453fa40af85c871222f7cf90df3a14f1f84ac655c0e23e496421d8d4ed50e7dbbe6fd9dd55ffe71cbb87cd0bde8bca8f72e26895b707b93d9fa5871f7e1a94ed46786c0a50b0c68d3ee2cd512aef740bc18483324c6675ab3ba86209b1b8c5e578d07700771ca5664da7644ead97142b89fcb0c6bbb788fa7faf804df9e552315bb58ad5d66bf77add7b1b16084cb67d3224b149ddf66db2c5c1b3b2719685b35ef545435359def89f38d76da684bd52cbd1ba4237a32a9ccc3d9797ed0653e259c5b8dddc3bf80415b1ecc2ccb936963849bc4f8fe70e7430ec25ed2f9d7ea980b0c59e5f59a956d812312204d75458cebfb5c20bf6bca5a2c685713a84d6a67fd93b69bee47d31a21ef0df9c7ef4884771d00df32b5b11206ed4a347ff276ce7437b417ba5d9e5607cef0c00f8f37990d3ef60a9a5a302156ac2c85d870523aacb1be4636755fbaad647faa93a6f60c569ef914c9c14242d815fe12296ed239bb0c018436eac27361abee050c29f7f12163813c849b58bba65512c9f3959b470c03ce7deebbb820c45bac929a2314664efb6b48e86773a591d1939ece6b26d8558e2513b18fa206016b537865039966008bc69bbbaa64447b5bae2d089c3013d4892af17bf572159a2768af718acf6d5c26e3746e2f10256efda631cd5a5a0f8daadec811f1d08789ca35ea27cfd88381ce0f5ac5eaabb6e0d64eca42682114ea6e551d1e544266bcb8da1235a354c99af155c62765ccb9b43674298c16564076eb9091adc62bda295d1e7f03907303c6a2c7c197f892fee251562b14c6363a6928148d45804a64ff15e69c64e7e2bf6c9d413a8c3e02fe9f51af62b7f6d0b729403aa8723902118ca732b89b6f6f50b48ed85523cd3db7a3241f02f50a013930751201af0dd44b36fb3f29a5480a834783d3f5c73f4e4d124e29cbdcb27b1e6627ca05fb510fc14c88bc9cd58822eb52d8474231366687adb071aaa7d5100394d4a7fc26eb7df52f5e7d551017efedb24962de68e2858d0c07c0d7e10b2fc326b8c943ed745443c7592807ac9d02661ae963c4c66d3fcf7f805aa5c51cbfd673ab58bce71fb9d8d31e4efaa42ab5eecde59970ea2c38f42d9fdb1047d6de4ff36704cba43e4e5bb136cd5830e26d569fe6cbcbfb0b21fc9f65db541d17c7451d8d95c08f42ad3026066ce2d57e4387bcb602f3ea8a5b6b50b1cc5f421083a97822867694d053b575633022e6543ac08d789d557fad055147342d13d8fad751e2dcd5853f394359526b3a6fcdb432cb2acad298fa274adce03a2d11f8a5eb1b7c3efd4eec57facc3d6ab7514fd41b886a78f665716c5f385b633b2e816ca45d7379aa7e59837982608f9f715fba21fffe245e134a0530da077cceda33346b2b0c24c9cea66b0ee8863944acdad9ffa019cc24456f11187aaaefa84e06c5b787410150e7b737e2d42a9706ab88f7968b1e781b384e6360fb22ca84c2c5cf80188756e0b292bb522664766ca094e4371d97b150277d5b96d0bfbb47020a931eebaa5e6ecde025d89c62235447c876040565da979129b1bdef59a958623fa4e4f7bd8f84262cd2d246a31d7955470e4a5314c3c015fec2f9fd7467347492aff7fdaf81dec45bfa0a32ace7384adf6c2d4d54c3a0b475f0aca707fd758c05562287177a3047db721d998419c3fbe266d0504f6d5f0a66b988cbf5da646dfd1659571cad02d470c5eca4fc1985158c99d09f99efd563782a132729ab522059ca39525a220ef79934606d9ff528d4f00b27e46705acb563fb738bbde815f60faf0baecac6a1e9baf4598f66693bf6294738d46ad90b51cbff21e0717c15da0409e134e206f797992e7a4cf4a0875094a60dadec3cca1cbc93a1dc27758a97060ae26556b66f4a2b87c581c8e206110474629a19575552fb6e719c312924c7d93fb2eda424a4d2d95149436ccdcf738a14a58c1acc56041fb46b327f89bd93ab77db01baf656e74760913a0e70db3a3590d64da4c08ec583936ddfac299b75d51c6329114fd5708ff89bf4845da85352204dcdeeedfce3af92de154b0406094976137f2377b8317e0035a74b0c1fa2a6fc57861f2b698e4a0d2d87bd8e0b046aa02a102941564c1aac9590e0ff3656e51e42f6704ed88a88dd6bcfa31b956d20351c5e9b000e3d552ecbac6ec4806da6a8d33de7c06a57b3f0ed404fdd4fd139b0a44686fb5771aabf3ef4d3d624558577e62c0c9aee1f5db493383d8ba9dcf9556058c8803c9408bf5b2357f5afad0f3c1f7a04281bd4398ab0355517d901ef1699576afa67720ff3c2b4280ccf243a4bd46a2da6b52d6299dc9a7e28133b6750e8c3008c21002a856ed49430352a0c7e6a3c2b01673cf5d0571ef2ea1ed3a2250e8a01bda9c7453d42170772af2eeed1254afc442e871b788bd7ad0f211f893523fbf1bf73e35b62037890177aa86c4c44805476d9aac9e6a465bdd0a98689f400d995a20874381462acb47989c1cbf0c8a1eb7a9b7501b4424dcdd3f0b155c43631a30f2111b93cce2e9c5c3dbc645414ce025804befcb47bc4024fa04f6b5da9b62c0af813dac1aeea70ea476706f7befb677510c0cea5b2bb98641d10983a1753a68011e22112ba91b1c618a202e10801df9e3c3ab67d244fdc82304620bb3e95af8784713cc2a72685eac2091c4dabfd3dca57973b8382fa6aa21f21e4c8c541e1f7fe17a8842366a6bc7db77b3ceceab1e942d85cddd5a60194075f6d1484f12815775e90b88ae53988e4b6ad4c5201f5e476abae22e73e728c042f48d47e97c2f08589be08cef98c28c5e3753b725c2f1eb4e276d91785398d1fc1b7702f3ec1f1540826030eafee3bf5f1d69da0140054883a39b8e31633cf6f4011b334c464c2f848faa81cce05285ff2c9be3be107d735a1a4e99a1d13575065d30386ab8c4d420c093ff6295c177bac72aff0b0b82ffed1e21be4bd19d4f00a3b2ab2a477b075e1f7549c5265daaa33063fb10216b337fa89c9c2760c9ebcf4b9e15e4507c1a315152a6610a86c2377d3a247577d7d054c1d9c9e66a257c14165603b7fcf1dac01dc1646d64d3a417e0c5109b61aad022324741e5cb66e94930874aa086e37de7bc570892d3c54534976c96c8814a1e8d3149147df223058c1dbdee418d76cdc2c63e40f201ff18bb570b74f5ffc1dc19b830a8a4a9e1ba5eb68e7f6e1a0f46120e44f44572c419d5c1abb69bce52cef2ca8623e44476fdda0ce1568fc8a5fcd1c796059c6ee42dd250a569f5fd292fb254f6249979450ae5327352517bbd6c48bb40b76673d4e4468acf2cf8f3c37e8962becbc3e3f16ce382fd4a4a406be6a589e542486a4f114cf1a4bfaf13c9d91c9f4db96493686148f68889c2e52bd060543cc13f67fb166ad92fa6bc139bb8ea5c5bad777816bba796acc1595b21789159177303254f2e7e3015ccb35dd4a28100a43c99a441f8e14ed343c1e8937f6e798ba8e8132abc41950eb94a2b708a39569e9e9fa46cc787bf28c53d78118de0369123036707bfb3d3f45b000d03edda9ad21a631de9930b2d4522ac82a014419794ce05e4148333f9a6034e715268438271d437657abf4ebfc36a3b426e9b3c0a15c756bcdf480186be41795f2683577da2b435dcba4b544d44227e62b853efdcc3fff8777f52fa54a9cd62e0b9f280837e647ae76ebb24144c8c11e0bbf3489f8a65a4f8dadd1b5ea2b955122f6255c0dc7b33f4e7fa69b1a5bd934ffdc4c4a528de591f45a4d8b38f561e158d8d439853f42487b4e9bce85335a763890037837fca9557f962afb721b57fecdb22a203ce580a86ed67ca1c940b1467dedebaae4cfac3785b64838674fde96d1c0de491deb22405f8ed80f0290af45d230d077d78034af46647f2a86bf4e8318fba0e44032ac86023a05441bad912fe0484be291fc6f70b3a74c214b40ac62b3074b9d08746fe0ad58b0db29d2ab490cfaa292fdc435685ac660c93acab7d9d6901de4e476b90fbd9e7c4bf7e7342b160b06ad0d6046b5f92cec691fc5ba4a29ae4ce969c07581fc860d135cc855d6f02d6203ea26af7c0a7536e29009ef820405da2e46023cb41fea1a0298510586d7bebb28b871c8a374708a531d6e7387ac0d65010a24a922bd3627690d600f4b5bd89f737f6a62f17b0d3bba716ec4d86ea81140d8029f93b4ccad744f1a6724f9a259797baea83c367137ef686be88d5e4cb29935e7385652f5956948a061b0486abb3cecd1b48209243e8b92fe97be6b386ec28bce56331cc7483cdb1bb3913253da1b37293cfcc59557ee8d8829baa878a7549b0dd71064bab59d28f0f4b1818e054c66b5c187bfe67a6bc6285bfe99404893de5771f4b18160a24acfa658fd591a3584798b50e8760705d43b263d402522637fa1b5535049de6db683b00f77ea83bd98bdfc69767066de2da215cb3e7cd9de7bd4245201052a5421833c946365f96d6021e90844b23e4153c673503e6017a85d8c6020b9998c77321b033a6ee2597ac9d4b085c61b065a9958181ff1e64e4991718f89c77f079ae7cc2f13b7ab5554ff5045a55f0ea61cb12f8b4d0b944d87e42fb88ec0e5f600e5886b9642eca6516ae6c75307a4cc57e0a31a34e5ae0b80b89835fadf77d7887d74d26de4cbce33cd030192fd8b76102fda35ea39f29d41513d59ed41577941bb0e6e338b029220976ea1aed01ffcf568587a71cb996e0a750acd7dcf1a7f63e20a3f56638c371ae7d2a0e99dc2f1b3acad868a03db9783da9999488dd99a8dd132c7435138474f66cf679f131504f1006b93fe74907cb45057dc356834603932c7af790b6469b796ec6d2cd7049549ea982372628ff2c65ba3419af91a59e3337e0563e5badfce0a60b30d17cb98c1527bd3f8f8ce87c7d189c58b45c1b7a4cb449ca0c232bc8c23f96983d9063aef646fa2b8c480c27308746b16a6352c139a48c76ca68649ec2f18aa28227c2ab36e18673aede3b2ee07aabc6ee58c9698600393dbbd7b12245b6da93313857d64972682bc29bbcb47a51ad89876d9c35c8fb7bdf3ef9a9bdd919c3f8af2aaa18c411a680f0233ceaf6fc44d054cf909981e72f7029ea56eafc7386e2c50656fa5bb24a8b13fc081a81005bdc7e2e74d4ee6a752d3c826a6a4b017389cbd79a80758cc9214bd5f2df416ef14f1d81866a4adbd97a272898469ad4872b4edb255c8c89ce223772da38a6adee4488798450b2a390140817a5ec23b81e598cfe39d0146a140f897a50e6c14bac59f3ae0919cd331825cf2c431f645770507ba4683bb81d046adc033d4893d141ab967062b6bf7a24620d066b80c9568486f305f3ad81d23f40baa99b7015107ac277b89ba6c5c4f5913b4f713732c183a892b7150357d785b5c013b887c41bc2b39f941c4c56a88f90d28f57a0ad910b5dd7e9c6b202e07c3e6c489eb6e4aeedb3f3c5f9c4e2d1dd9b3a83147a91774d4115f8f1fde6f2e24bb9dbdfbc12cf432462e12e4fe1c9a298154fec3bd1e27af0ff25bdf28ea4ad3bed8140ef60bc76d1d81c10b1856580c712ce14871f0aecb5608cda78d4ceb9d589ec6dd22911d40478da22ae3c79ad4a992226caac84b62c4d4008cc9a79f20c201aa4cdbb85fd05a7f719f839a48e990fb3631f98d4a906289062a6827c06c6c02c155f68c666fe3ed7afb4fb628e99f5473e8cfb7fa626a239493b0820d0b102f7faebf95d7e572332caab0cbed88b6b82ed4b6746ec7bd3550b995f533eeaeb92c57a1fe2087cde8898d9b8019c9946a0a214fdba31424d32731dc279d3940f947cf51f487994be24dedacad949089ac412bd1367f10789ca535aec1cfa1d1d0797d3d89573ab7fc7bd379f6ea0dcdb0aef8b6fe8191381e1dffb90b78dc3925f5e8b22f9599acee65e920f4a5293349f6cdbe2da9a094bb03a55bed2edd3ceca8324499e67115bdc894268e656279d5d5219737fe7a44d1d6eeea48ee049379976cfe3c3830cb91ae24346c469d55fb6176f6115a384008869e0375e2a9ebe768830ab765197e85f2b232e2059107a1ee3b3ae8e14dcb66c3035308c5398aeed5029a7b3e2816281dcca3957e4d26f19ec8483747cb1cc759cdc0fb9eb94a55535978a5d63c4de46db5ff0c0172c77f5436eb4a389f0e6160f881d5cc8399180af5b37dabd124984bc82948e75bf814f0ea8aaa8d1a338b84507d6f1e0fc5fc715dff506ba43ed16ce9749034b787f182f6676512b1eb78c66ba87a12bf3e779d848ccabf36830cf6636749fe74752a0cf4f16479e0b4d6f5e72099df8f5192a4452d87e0c0e26659fc44bf269036cc4b7d0e1156427e444a9c43a7e5ced3aebc937819c94a7207c17b118471ee986bf73ae3675be9f3000fbfb2eb3c2e3c7203ed2376c74abb51387cb569cb1186083a080d14dac152fc27095e1c1b5e2bbfa4cbef08636ce20c286dd5b5dd0b02f9d6dab84564c05cd668b728d0748bf2059f52b03412236edfb742b466453540b362936a7e6e4cf81642ca141e7d2362fbe60489600540202a684ac4109256882af38523894f68c023f9d5aac168ad91fa77beef820dacd172c2aff8920a3a07a501bfc9e2fd828c430a508d6d6d969e0a16eac58b90f3a173a0d25e65ad9c4fcc595a8fd15c4136482d1d4e70e0813ff9dee532a0ed8987ab21b8e0d15d82176473268c576fabf7f53d65f42d8e88acb66acb6090afe449b2a0019cc87e785c8c7129e1bd50369e0672d9b334dd6fb7797d2962de2c26057f42697afb7336ace953ccfa670b95b0626f449b5f13b892b4aa9b106d03c6b58315d52030d371c74b3ac0b77ba7fddba60794d724327915e0257530d7e664672ad10474c105cdb29c0b9ec74ba26a63a43a55965e402e391cd07982b1fdf343b1ad12725baf85dfe82dc1f458937d1b837d908d365f2d82a1719f2211612db4594169ee3318318d403db33a2efc8902867e085f039fe77440b1115e3d0330f8e1d383c2f5eae2daace9ff1ce966eebc7eb21562833087010d5bb9ae42b88e4010d74980ba53aa3a1485f85cb22da399281882ef39756304e5f172783797b3e91350625ccb0943615d0a0d34a4d7d449da84f4991324d1f615efcf964b6815f579fb530099dfad9996fe9fbc6f726a7fa3c3e82c14727cf279f1a8abe0e44b926028782ba077440b81d455f3f2a0b9f87a3d3ec8328b3f7d344565ba04e0b34da017a0091365f40ccaada1c02b0842f759050924a982985cf6478140a968bec3d5108b1ac114fc79811de1b6f5af90ade9472b62c3c44f38ad99bea9fb01dfa5718a293aeddfb139502921a06ccaf5320d56cafac1fbbe82978787a8a1a66d6646f296592325803400341038fa3576e9020c3a6b44d15b0c9a907410332990ccb64b6b53b598d4ce74edbdd598f05ebb2ee36af3a20f5ce83e2078993fba53351ed4805d98c66596c6070effdb8b8e2cf3adb75dde5deaaeb708784ee553673d53dfb17910a39550763dc4316812a8e98b9b0cbd4bdca46d98b566132b294d9c069627d72bea10af8dd3f0c73d883fecdcab6dbfc0a54c86dd889eee1918faae384b086a1bd380c79b8dad19d1e893eeafe58d8ba234b102a1c74905437e89e91a86c50913048badf1a74cf2a1a60ba3892a3fb355284880a06b302d50c2a0ca864500d51c5a08241f582eaa512a20aa2724185d382ee590504e60bddaf8a05182f54234c0b60c680d902460c9824983060a6c0b060db686a7684e084c5da5855d46da3a9d9118213166b63cdf6cb6a4567ecd6da7ad5ae729effb6d1d4ec08c1098bb5b13a1842d7d487c2ec8ea7f2b4322bf7d92a159db1fb3e8f625ba6602d74a727dfbceb48e09cf38b7148637eff0041c714ceb911ba2af981579c10f103e7afac810a0f566dc0185f7b79d5613f144631d19d6fbc39e79cdbe784eea654e6f224901c3529e20361f000c29416801459a2240a26aa58873032d2d3e4089097135a8a2113e46840082f92540c78f416bbbebb6eaebb03b0dcac9f2489620a313902c3139b7bf50f9a8a5d6f3bac82a89c05cf6d98dbf016daeefbcffdf6f8afddf0ddf0d542dbffffbf5ce06b7547ca64a1fff1dfb7bf7d32f059477696f38a649d2fde2edebe2de88ca56dfc43efc3c5e11bebad3620d3a9116202e80c592b8da917652212cb6109c572e24b6436cb7447732e8184801448c4bfc9374de85e499246cec8965925377c377cb9d069c5da9513f85a19bc053fb2cb576ec3dc86bdb2873fb80dcfc837244992b15a62f289ee54b6654447344892cc2469eba87b25499ab2a99ae2323085f014cb26992ecdba944dc96a9024994992244992a44ee80f6531f0c65a161b1c8fc90e0f12f84747a2ad1111d12aeb57446ccb061ca050282250ddceb1c3a24023aa0db95f0fff23fec35ea6ff0f62cecbf40742fcff81ce005175b8c468d26c083f42d550558711f680e35c0ca0526ab81a16105d7db80f89ec3db1d527a6c471a00008b037b769cc5784eed5e75f3f84ce5c1aab89fdff5f8bc23f0e1aa0be82f8b10e3c10850c0a235847632e3d825bf940812ebfb515dd90502b6f23d88d13b878fec5b5d09dce64ea2ae93d2439d7578521af623df5f57abd5e2efde4be5eafd7eba5a3dff57abd5e212b3663c965e5d0eb929a51b763b763b7635d62a48394b4839303a413548f3000f5ea46e2470a109522a8c8848f42163473eda0b45ddd70bf1200bd4cbfa54c4990391322425bb5463d988df11fc41780d8edd8f5209e3a88bf056dd5927a759b60f0d416bc909f41fc14a53588bf6f8951d6dbbc86f173c7d553aa969fe225d8e1e9c99ae35ad0dd8e19c5d2f2c202ade7e2656147b0e411e1539c3e9e1d141f810ad23573c74df023ca5881b1832bd6dde6a0e641ccf8603f5666679646848306ff220bda4a51afeecf8b018821fecc75417c2762ddfdca20feb6e5fffbc46222a9e392f76d91f05edd4349397563bb1d45e851c36322665b389ea6c5dfda116c7196fb74ad92d08ca12f12dfc5e8a586a5667b7c76e88cbd78a33136381117785c60b04af21dc73f90edc8f39881b783061f16ef7aef8bde08e97d6ab55aabb55aad56bb71d6b2ee366f594de12cb7810a00e009c1c1a7245b1f71dc5ee86e473b13ba9be34e168451ab71b523badb99b5b05aed98e27811badb91db1de8704df1f7f7bb63693b37a3585a5e582fb55a8dab596bad695f9bb576dc41f75a1bcb00ac706038ce8e1608c755a0bb1d73add6aaac5663359f6ad6f8e7bcce2bf99def515d9edac217a5525975d89aa4f405a911d55629f3961a65e1a81fd45d7239d50ddf0d5f9e24eb190a684be8615ba51d2260c3b77473f7df54a791ddfc6faab9ad56613e6a357cc20ebad7b20ebd4ca7b4226dbdfa2e5ab975bbacfbbdba69b62ccb5259e2adc45bb61e67a27b2d4fb0de566e2557e692d64a97cda91a2de7b30e9121b1d75249dde19e46a9546195483532d6b154471ab312a28ea7fdd759bd2e9e654ba5734ae9cb00d2cc06d511a88e44bd8e75ace36ad43dddcf06e2412c1a74d02c9b50596fbea9297cafe7670644e3319af5358e2315facf2f35f70d596bad0d62e50f4869c377c3d7c929b3dbc4c5c96f5cb655daf0cda513be165febf980af459de7593acf8beb797195729ee7799e678f336b95d2f9e58fe759cf243de2bb729e67e93c4f1faeb394bab1de0dbad7f3ecf15eddaf713c7b7e8082c4256048fd8da812494901a1582d7d201db1a39ec7b67c6cebee7ab7ca03f0bb681a43b1d03dffecc9a34691ee53adf5548622d8cdc30621d1a2ac0c5befb7bcd88dba978ad705ef6d5750f8c515c46ff1711c59381a479b8f8da338723af3271a6377ff12fdc0521d14c8e2ee56b0a19bdf28bae60e66fab7a631b58912a93227b62bedba1b32e0218a204c923822856943b700dac18610240de9e288cd6f5709d4bac4f0abbb449d0e197922765a3302133b45aa327d979068dee9ddfd6f970754e83d3b893d68aac200ae01785f0b707bb300de77ff3e71b56e297a392c72e6f286cf1f18d03de70cd6f33c7ffcf8c1b182e84e4f2566dedc99b99a58ec3d2d2cc7b96ab89a1511fdd15d1efc2a3f35563d902900945ae4e94687d02ab83e26c78e2756cfa84137faa33b9df5aed3e0d025163084a686a893290094ef75efb6b92813db4a09dde94c854e4363f1c55b0d26582ed426fef3618496e7dbcaecc7e4f228f0d0b66a82c378a732cef97fffde9965c813b3d6b641ded5aff6df0cb3586b9399339366129935f3e5bd0ae5b45ae79e78db3a33831b4c72def26a0addab99cd9adfbf6dde17ba57d37499a669ce5cb655794cd3dc52d514a273364d73334d934b71ce6a6c6d6585691565d69d8010a2c56aa857370bd5b443792ca87c3b2bdb6632c95b9ee9fe4f6391b1446f9bc9645b65a17b3585aacc9c9933b6cd64b2792fddab29544dd3fa9844a6b96d2693cd8b41f76a26fdcd0f4b67336e736d5a03052c1836aede4b24d3bba1eda2762966c21bcd3a9ec1bfd70b5202d1150aadb51f0eec9a2c893a99c29af7ea96cd68497a460dca7d9c94b170d068202aa3b21c0e5b6c3911dcd817cdd4ab3b6f1c67afbd1c276b9ccedcdcf54963d118922439d2879dc2845e93888aaaed6806f9594248bdba635936db60f65c182232b55c221419819b244992ec488e2544f74a8e32254e9f72dd24c9cf9d5db87fd9168ff7ea2e3a8b8c907a258b00bd0ea9738304930db74b5ceabe07a597813ac6b390c8ba1aee36076dd7e25d61f432dbc63bbb84b8c391a3f5f2f2f2c411c691a3f5f2c28578e999d75248da6a8d2a3ea1fa4131dffbb15fcffd6c409a8db0614c22c12c23ba57329baa8e3bc27b7567246ea5055207f21f01c5d2f292316ef178d0bd92768f80c48d76511c877c555648c4429f902734c332dce9f9010a7a99108661188661b80244c6131d862187128a76c637d230996e4e5390eef57c25a44facc60f2f63cff34cf174250b2f6d7c405c4043876269796161603acfb334a5ea8984b6dbdc1d6f2128c7429f902734c3323499ce2926ef856dc35869849484a3417e0700596ec3dc86bd10c82eb761bbe1bbe13b06dff0cdbaecca5d3e14e368390a2ebe165fdb85ee4144c4c1f8ffffc7c9d1d93c2b387c2dbe966381afcd2b294f1b7a99920c6f5429975645988c38e5ae4516b338a5b3065fdbd2bdd058341c3428be850ace0a8d46cbb459a5d9d6f36cdd7eb3039a46a399f9cd376d0be4ae372de7d6e345e88c1d357fcdc8397f39e8fee69fbdca4cb41a2d041f67488e8e121aab229f1a39d7de4c810a9e098d96694ce892f96629531698cdd189be902063afec95940a32f60a364f5375bc58f7666d88544a5091f8325c56f60a36ad25a7124f756246119073ce2b2e17f8e00927a30d8ecf51f72ee59813af23a35acad5e60de2085f78dda7526d598293374ac63e9966a464a450225da20920510595eaf994eada9437553940a6a229ef1b265369d37c8b2b4570f13861e789d8a94c280562a742423d62a7329d1e994af95473ce3b0156cc3141e84d6d565ca84d1d6d8b867a7573344f43c41838889d462c5584f0506130180c0683c1603018ec05dd2b2c08c6f7d63ae7d8f1e47dec12d71b01e629d862b1580d0c0683f9d4d856256130186c8886c56c2a16a31be6882e20fac0f892ac6a78821b71291f9107c46bc28a6125c6476445056bc8171b2208ce05ef40131ec4d36175026fe803014b07045178189e90d95764c581ca5f781c2c4da7cc9bcbdc5d955fded5119b9704b722411112ec95bf304a1f15269ec3cd6f7f44bcb38fe695b49ecbd3981494e474d07610a78320d8c10e9eb811140882df15a0cf4f2d6d2b5b3363156f052bde113e2fd362e9f992cebc29dea3930cee827dd59d1e1004f5c7c38ccf0a1a436a702058aec8363e318a6a48ae3af2f812068220085ef083c117a5e349328092a4c16ac90d0f0c1004c17af4643deb513dead13cc0186d831ab10810043f0fe8984763acdb4700f87cacccd2997b39e0b8a315741dd701e95e8f7a062b08823c8a8c9092764c02317844842b185e02a06261c12c50e8ceffedb6d672ce8ad304502fa7bcb5701c2f4397409213ab609400a8944e7a45662400000063160000180006828563f1689e685a87ed0114800d445836705e3a4c260e866282204a412083400c820000c300800188020829a41c7c00014cfbbc45bf9b77404c233369a984fab6053beb12efafb12894c88608b80cb196274752d3800e02e216e48d46b87e7a08c4c03cbdcf6fc8aace4e9fc389fabac9ce8a43a93f610c35e794152051a2950aba14af5d34a9460730c751a6ec67a6e429b8c409728f6038c6f3f3614a3e8b94a794b24d4f578cf28c8116f7b654069495ddac86a3344f61da0b2ee66ba73f52ac042852999648b1dd3ea1cde3730b7df75cf5506da81cad9cc36a3387ae1071cb4f5839ca2f9d9acf03f00e5dd086c1211f8ef929a889c413b8d810db9c0c21fa1e3e2057c1138059d94d072068a7fc3a3358d319bce3fa5feeccda46cd800d7cd2ce33170962ba4603b6cc4a4562f838c2b82809b10a8e7b3869d4b4f861942553fec17060fca1081534ee6e5b3aba9297363ea1999f7b40f36d4b513e582dc787c919c6295512a3e8f99657c6076370200112d5551ce53cd2f4e5b59b7a9091706126751231e793d89526aae676caaf0abd3bd2599fe7bff962d64ba553b4ac3d83d0593868239e209b915ad329588ec7860b888165fc21f3e61add4a8fec1c33f5c038f038c295e958000f6603968fcc7651fc1018edb35f46aa7cdd4fa7a05f7a208f0d4ff6a4078ec665dc518926b3991e9a475aaeeb7a7403c3a54bcf23cb850a8a62c0993901d667600b9f61e2f289e2c66c797a508a5246ff4c7e81e2d7f0d6889239dabd520067ce789e8687a7f44361eeee7edbb19285d81080ca87c3d74761ae9aa9eb04d854058090670112f89edc053cdccd897d38906ff2c5bab5ec0483b71cb7d506b7cca38144ebd102c681c31667079d077a82466c81c654f5150208c82e4cd6f999fc534f16d9d7f6a734c496db12513cac542f85a3fc1c6530d6e99571a5b835dfd522c8193428867960140eef39bc3338e9611881e648b4cc156de800d5f7910d17f08169f343a5b16e72e64634532caaa5f5df912f1f23848046ec2f240fa468d1d074620d6276869eeb4a991a0244c3b905009384e4fac140309847fd010f70c5e822112e1e4e9ac31d9463c3cf1fa388f9cd5e29d1489bc083eb3cb54c3353d1f93ed2492904178cbe9bb6ac64b73bf82e93c285df2d71dbd65571b683e5df6ee9d3414fee1313385d3474c99b46a72701b4090962fb532344e081c2fb728eb76beabe39d9561be43b7db57348df94c56aa3ffa93a9149ae8eeb395f9c495de36e0207fb4871a055f24ac7f99b6ed37fd0abf62fe1e5a673cf2d2144acf32773af9c586d5f798094d54c9dabe032cd30541c921d9e8c31e6b78f626d4a0638483810152b99cadf882ba88c6110943725fd883a4a5c9d006c85ba19b0ee8449b3b43232acbef25774812b58eaab15ca461c1f1d97955ffdc4bc54f9248bcf9c9a63757b0960b18ed3d4ceb5bbe3c01beea5ce8526c7fe45376aa218447c5462d15bb15dfe15af3e58afb6846fa3e27c547fc57a39297bcb9e4d3e516db963f6ea26c7d2fd1f0395b8c640def80af9ff859c7b4e745ee5bd97bb883a27c45fb6c8bd496ef493ed1e5a0990096e6e243cc225f2995072551c291f36eb3ebd7c82c346b5af9c1a44c195fa3fb394528a23ffc11c8b809e646d7f9824838242b1be65eef43926ddb2ce531b3428d1148ac0d9b1bfb40b2608b0181838b60213bb31c9905d2592ab71003ee7cac0e99a0e8e4e2378dea086d073d0648fcea29439a2b0cd69fa67f7261441a939c89bc0df6d40edf9d7243cdbac4fc0f9599b84a839ed57e4fa214a1f1ec91f088da8d8f01b373e0576acb02f5b0635ae29dd34e60d4827288430f56cbae784f4fa64ac1782e2e7a9d8e1f2c08396a3a3d27f6524e297a3f814ba0f10586c40e4a66d257ddb57cae4941cf374191022102f2b122695caeb8aa50f44dddaec1cc94b62755321c331952a4ad19d528dda0b906773a5e5bd56ba3602040196f87d3bf075aa80299aff9caa4f75c84d40b07ca961352309b0c30164c973038c2c272c4a35c2aea622df7644ce1a4a7441cc44e3721281403a02c668a378fa14913dd8ca4d41c9a516baa38d6ef66e55aa3ac79bdc229c8ce4db120ef49a49ab3dfc2e97784fdc8b990f72463c48b670e24619d07b22ee27746b05f4fb4450b3a8bc1c4d8175737718febd1c192a53ecfb921342fc72e8d377d2ebda7038e3130fcba17fe8101a80110cc18e6372b07e5e2e6078731f6b4a1f8d9117bf06059f5b8ed7beb88082451249f596c19fa03e4fb11090d59fb350fc0efebea007bee40187ad5d1820a1fb1f7e169bf3da2ca296be3e728dce4e02b8fed600c9489e57a95b13805d9e931019e3f23c48dda1d82ddff6ca325d81a4f5159200401c8f3088c1c07a44cb6deb8e750a92cc047d7005aebccef5483f65e1805ddf58c0d87f9700683f4800baeb2cc200e01c07af3542c199e373626814f1534a5dc7a0f78e848ad98783763980cbf9ec4d73e8b303d3e0e8088dde05d0b023a8c333dcd6816077dad9410b118fd7446293554ebe39497f257dc9de07b55f1bf49ac37cba773b19fdbd620b45f9dee0062a7a37623fe2a61379a5e4f606ba1b314c7275127ae5200fbddced8576afd85f2e97d0b514bb1bee1b68b3c6984dc8ea3da3583a7376f9283a399d3735bee7166713b4f69f8a8e50e512be06888dc0edf96b334bd18f9801f80cc5e4f42bccd1ac27a1957f9ca75bb809813a4d5d6c344a5ba5cd6133cbb1a7158ae279383abf2c429df46dc40eaddac8f0f6c14aef6b257b76b736b74ee6b40e1147a1153ad23621c48ebfb736c17bdbcbd3e31ffb14a4dcd2a184312edbac2aa65b8ba85b6c8513bdc1c5f984e8a0030558176d97db5868e7aa436f26ee1c9fdffd217a310f292ceba49c3d3bccc8982d5279f6497e1bcd8ba63c5cb50f0660f339192ae2c3aef80664ffd290c6bfd9c9c2aced83a978a69c3a94ed31e3be3a142d05c2ea19f12202d8d58c84207300754ebbe64962979d3a50f4365fd5ba5edbeb952997f9c30e66382d49a272a510286bb6618157ec8738bebd6a28501eca8970dae24c9b9429e09b4c1ad0b04729590035474252fc796287c408165d41e7b4ea569c052f10c7e528f6be133707becdcda1cd42f094e25576b87dce8174f3722261c2725dbd45512aa6236fabc5af885cbc8aa7f8ea7f934178b4b2b09866bad6e7e87f295d0fbe2d8c933b7a3a87c50d221699dc9325ddd019e16602219ed48653f084adf839df3e6b149825bfd34166b32903b93c63df249687f21fde55c1e2654d29a9e33b6c45f1c05d0bdcb515f5b7c1cb9da1847faa7c44fc3e0b40db87f1ab360a6ff15278ec50e139e53aecd6e1dd201a51ab879fe3ee1dbfb4e2560bb30e2a34886d16d39e2f053885b564a711e87ba628ea0822d7e75de119a8f719cca28bcea7f7530c635ada374f1e0a5331607264b1fd852ffea3711fdcf9686f471a740c58f33ea46a431281a4505060559bb973267773c507abf60b614fe1519e75cd08501a430a55df1930d743fd7246741be3361bc5de37252e997c93c3561eceee1fd35420a2010db8abf129a0dcf214fb1704f60e2cd59bcddbbfe9136299c3587155d462a55964fff39cd5a375a36307c4cfca5abc1b6724230a2b4c5a594175063e7a612d2d9a406d4ec75528897716a5adf287cc31595f8be525e46fb67d4c228e5da5927c252200752de8957350da578cc247d8fb17011587aa8369b3f51d10d5c12f83d222f5309f1cde1aada9d1ec6228982c2ef9204bc3120e2aa362df2357a15fff49b54a1c11ce6fee781379c949a2216bdd021f82e716c60c2091c01e8cd13333162685ae5be323c3c76146658f7ca67eca90d5e4cb3328ee31d89cc621eb098f1cdcadb64d76ba78b2e7ebb2845c542ab9765f1573317bb7f091d20071a68393b1bba1bb2b0b38775847ee7e71921d764f6e57e2ad9c2e71dc246790be894c7a1add9eab95b54c6623820d4bc78ca992babbc3bc4b41f1291aee51d3c4c466f708b69b727e0436df3c076173c86612cc255cf0ff14a9782de6c24ac0b101b2c16471cefcfb127372fa09b6ddbe5f77e2bd3f47fcdc15b4e70cfc2458bd35839b846a73ec10ebefeefb321e75426d7d14e4f5cade5bcc1d9e71b8df569d6c4b5212172c7ebadd93d525f3ab5c80fc0053784048d2ec6ef0b30ddf37e730a39f7974ea386d9cf35ab674a6bab0cfba278b42c998551fa98262fa3a1bcbd93ef0b965cd253456dbedb3a77c6f2d61d811c58c7aeda71c2b1b8c7ac18edd32a99e7519cfef89e8a146373ae02efd966da667c52e799dbf29aae551fcd758d62d9653055e7fa08f7078c46843f8fda40400e581b9b031e243964f7bf95e647cc856f7232eb595cf9c3cf4e91e8ffda498e471d4eec5b6ee8d049af8d2990b4d0fc3a1a156590881165a56921a74e884234563c7426877dd3240db708927cb1fbd60d8f8b73cdbe50a824ca1b5ceb8842e2349de6b48db67c26a854de120d2e4d135901929f3e992ef23e4ea6f9b58dd2796b9e172f96f26dcf36aa9947953c4653c13b7cdfe90a10ba21c34986efcb0597289089632e1783091191d3fdc0dbef5fdb985a36afa199fa69f80ef6f9d6cda2c443d2098d4c8573b4a02dedc49c10122e28dbca39509b897d339edd7a4d8f4f150a08c40b66ff4bb9481ee96df0b026b822a9b3b0ef0f7d6a6c19b9859e066b90cbe322b1ad1514df66f6f7f37dac4322dc1c0400fa843ed5096493e31c425f6cd2e96a195ded9ec4fbe9528166fe9faccb33bbfdbf2609264de4dcc941f2f18b50e0ab5ec5cbef5aa577026d0dc26f44c77470318f329defced70e145935fc7267d67da9cab383292f68d14fb75ed3fe36d7850455b8d216e1b23abc6294b1840e61c5a7dd8d4607fd8033585345ef138d68ec6288391e7185ce0557640465cbef728c1cc19aee403c654aba6cb1a3ab5eda561365a84d629bbccc3ac030565c909e18c6fbd2eee14f36618d91490c20f24b50a55a17ecba9c9b428619847db6f052d8e60d76311a3dd442d9b7c2c87c56f5678ea03ed4cdb4bb5c3cbf9cc27f6c15541ba753dbe68d35c398388f1effcb3a8ad40defe07cffc493e54ecefec14bb4c0ac5de022fecffc43e5b01b6893d06a105a8973e6acc00f5e5911ea52cdebf73d4ff7c85a74a83515047b519e1c7dcfc6980741ff4e421e4eca82f7ca00e98695d4cabed1db8c51a93bb742822affb07459c39b1b93016a1e8960f66ce53b10821fd44817d1e1e1eb38872e2ae11eb31c43e194f3d73683c8bee1b89e00396f864e96925fb09b3ac4dfc81ddf159759972b8bcb1e36ab390bda3ed8b768208f38ca4bc27a848bd7d840a4942658eababca204e1100068736b11d6010a2eae8ada74b5420f1f9ac86bb81759d007dced8dd73b71b81065eade9c5303b3992d58962f48e6eafc2ad601aea14419d3e677ba01c6898355558811f6cb38807bbabbb1204d517741738b619fda41f340aa9c3e9eb324fede2864c74ef83b5707f7407a3714fa6f594f274bcb7b69bf0a155914df4e9b88244c4a7a8ea70024d427e9490de5d4c3fd875a34c2473bf4946b2dd5492190ea5926dc39564062f4ac860a2d466626e9a70aa586a3b0413e7dbab4c2d246dc8679f14e7f349af5259b6b4596cd0c36aa852d193bc2972df6ad4accb920ea85ec47c0aa8de9962a5fa3904cd56d93ba5c77b9247184e9b6542c18a61379bb0d296afb43ae528a84d94204be90ed601bfee2a9f5a0cc3912a7a7487ddf8ec2b4574943ec846370a55b738ea55350a164b48a16e0905aad089093d662272936cf6a18f5b866fdb88fa2e07e1261e09b17c0aa47a8d215e2a31316994c0568198afc0c22f083934740a003a4a4de90039f810acc6cd8b3c9e98b847a1ecb5496512b09e9173611c83b6f7c9a59d06348e85ce44891918590e7e4056938622542cef81b3d718da74a862a465b1a6da06b66535f6e4ed0fe321c6b668e5abd6f42ad24ef33bb8e74ba0015ecac8cc35c57c057920ba446e04f137890f89aceb5ba081090f011e615006048460dd9e22628148fe438e671fa267917b7922751ab62eccb4aa0d10299f0519cdc2e2c11dd22e5a150b16c5014f0a588cc1a115668133efdab9d32bb3ddfc13ca62dc697a82556ed9c0a36b63db3e3da42b276f6a2737828f69255b8732b65700e5fdbd36c4585707b2711d0838f2e0b14cf891d976ab4f16e051bef08d746ef939c9bdb944b104339dbe702cb672bb078d18778f953edb891bffea6cd9ca186d864e201029ea005d78a29cda729503c58aa41e4a681b13996aae4a19e29271a84d68d310b3b1a7f6a7644b837d97a76e3479ee9c455b2555ee3aa96c6d0728b626e8edf8a0c015e4223fd5f17b162ea00c56632c191b965af3544383c5f7d3e5f23bbdf1b567c4dfe2687a517ab1806d79c5877618405c5a812ece46b6c214eb1ab5ecd297aa2e084bb22d3c78159161674933f40c3a3049cf5c0d83afb5635ca5f5cd79ee5c04336ec45f6362bcfd1408c374c3c2dfd164d8aaaf5b15f4c3e5d50e6c2436fc5b59ca252f42a01a66928c1d339f40a6feb8c21cd58bb27beadbf3892b97dff3dd6c9b5ebd37ed953fe7901f17ef2df69ba8d363fc1143b49f1a9a62ce3fd4754b84035fa14a96e5ca2f24a18aabef97b79972830f538c8621d7fc79d536464702689748ebe6d750a5cfad6562d6178a1db88edaa1bc61a84a48197f5694ae18635822a0704ae50f7378e28fd20a2e4bc85e2a8f808768ee4d1013d7de5dc29b566fc5c660b875b45a2b751799ae6d0ccea57c8a599318a7b139c9bc0e4945286acd9ab48d28ecbb6662737d07451387d8518aa8922285c89a8ba229bd8be7597812ccd1c8c534c0897f43ad418868a3eb86618b7ec2910f279ece530d992be964e60496f3ccff4bc5f2479f2fc4fd9363d49c28aeda5e36cccdbff22f27cb48f0fa99d3dbf57914c2628336aa9350b69b142edc572dba6adf2a2e4f2a21a939011d9cb5124689161ca1c478a31e9887988d8ef4e444203e8740d36d06cf10f70010319b8c326f4746b1f7ca0d40b7bdbe298f40c611758257b12f93fcfcf31673fe8203bd53b52a89c26f3418244ddc4e0a2a501e203b5144199204a3f4cf0c01f6c5fc2160b535d80dc04638c7c4075bee23cf39407b4d2e81406f5272b48e7a008657f19889b42277c3ed16916671ec0ca239ab2ddab90294229d3a18078e9e78d9a9050ba25190379095ae0ef2b3c115488845a712da46e6c6e8bacf8a3a9d717e58aafbe1ca9b0abc6e25b64ecc6cf52d8fdc02337670c6a5d02d7e60675161c29dfbb2130a9916e3882b27b9ddf2e04c987510a793095ca28fb60cfd17714c3a72711fadc9d74db5ed5f356c6964e35ef9f0f7f607c119de3367f844923e7996f1609cfd410bc5f79f2114a5b7717d7f8e88b57877be65281322ed29ce9d27dce14478749aea7cc732edf33d878ec88802def08faadd3e594f0d62e06bccdff58e24e26d64e49d752622877ecddb56e9a1953822aa38ef077304fe854aa86c52de17a8c272372352b3a720998aafe7a5cbe20d691afb566e3604b430451f6e21062f9f6aa84144909411f63d1731ebee5cf8ad9c365164224397f09d413a6f73be0654887eb9b64c9e7dcd5994e5591b6c997af8192c909d7583ee3a60d80fd7b57aa41fbc81dc4a4c87abee85264704d935b0eec022bdcf1bf34ffa2f0f8c191cc18b50d9c4a79c879979ec244f209804fd8d3b1ee57886df480dd64202825965af6eec29c3458c26f89bf717eb5b9c49d48a7c0af236cc8e4a097b0b22cb501a0f4bd40c2e18796c0f9bc12c56390759dc2d7dd2ddebbbb00a5181483e38495d7e8739bb156ed7f82df057ff77bbc44523641015276ed72d08c90df549bea4930cd6eee3d942c71fddb932dc0df00c3f8f694adfa2b9c3c6203dc5e5d8605af112fe6e69976ca5147908017016e4b74c75e83fa93918482528bd2742ad386c0e4ea861cf7a4a53381294753acb91912feb5e30624e5e905b7149f4f0ba076d33d350e25072c39eb2488419c0113795809e8270ce59ae7aedf80eb6b9047aa678a5605005cfd117dc75f239fc9281783bb83a92defae47ca1c39e779795097ee3d4a284e7940b1d1ebf801d6b274f15b9c89700b4654959941674c315e4d7115fcd040091e29c7d2b1865f4dc6ea766a27cce5fe6d6e59e00675be12b5ec13eb9bbb90869df96834001507fe59488a9eb6e4a9c17540be294df2da5714782ce5628246b11603cb361b43c1035d9c0248bc5c346dfe6b489f3be3fa94f90666fa5ceddcfb6d91a13375ca88a0b926cadab6e3f6b2bb62dadcd2d0080fc2334a54eab9b898d564d6e099e1ff5d25dd5970cf0a9dc87c232c1e6f76d5c393edcecaca58a9282aa974191430bc79d1a5d9cd256ae906dcb5ef0b4d171a65c1bd92211f80ca9a86b1dc48f171cc4b33ddbb0c5214578581ca62f53d825576620f80ac2d76cc9f5f77f4189c9f43d0ef03db2f9f802e09249c564631d7b81066bf8187cb51af1933264a1628ce817cb12cd364657957472981e07d73e11340851c429c6ac8e24752f14673a2074f61e03a0d889fbf4eb1cc9124f9b6d2a7ffe09f5de6db09632894d9eeea8cfa68698e83eb592e4ba84c85ef47bfb6bfacadc0891fcfc9a498488e5c2a16668292be787e031c597eb72d030d398c5849eea88357b77d803dfa4363050d3f8cdf6394074427bec7f5b3519539a46152144c038ea2fa55dc66bc3177ab3e794a00603838221dceb97e4ff805bca29b8b4c6a4d3cd60c37e77c60358f3fab3e9ee061fdadd786179bf3b1cc7a1a81981fd0bf5ffc9efe78e72fdcdd15b288b8a706f53b2481407ad23f0231235cb92cd4f1024a616afb673d0bd88dae75fd0377159b2bc7df00bc0b366eb693063fb78442a1277ae814afc5462f1fa72c5b67537b891bcb512fb5830561f8481ec9f3de298dcd3f9100e90dba42d92771e8eb54a05be934d27691c97bc60a7c849f6ff453d4426f282ce71705656229de823d0d9c8dc73dc8ebdece3ef0dce10f558acc98cc0075dc4d74b7d7d8fca7fecbe541ddeef50dec60d7d624a17d75d2cdd5d9526f5b5f47e8fce69b7203b735d1f6b82043bdff72dd743508198547f62fbe2507ebd7da3cec39158af8bc0ea548de94a844f5e5c5b5990817d97dbca3578a994383070e033143cc684e72cd3494a9414c48f3f4ef26a212b3e974d390522a3e28933d5a6e66980d2b6e2ba785a23470a9290eac78588950ebe04b24ac592beb74d1d39cbe729106c94f9deacd22a09d1f99d29c813eb1f9eacef66b89bc10122527c967138042f119914070b0ad97aec9f888e5725396e091aa9271e3065d4664fcf8f984a683bc8a7854c8142fd754103ce06b63452c6cf76f325975f1b8b725f7f845589ab258a6bdfdcacd34e4b5f9ed9dc6f70d92da797c0ae99cc3c817d30446f4b2a62f7d7c49b1c82948cc8a11e4cc2c1d0face126b805a871ed3ae22ae194982a73e0b5bae7c7ad62e2ea11ab6538e0fa6ab54dbac228fbc5ad6a27964b9c2591d117f22ea3ff202cf08f145d6b346d2eb6613f7471bafa3bc8e160a536bcbd231c80566852c7439720d66f61034a9b8f9114e7598057a21c35e613deb51c3958ae19ed4da3f63a014866dc41a0d2b6eac378685a37dbd914035a2342bfa9063e7cf6862e4d13d7d9b4091a752bdcda4c89bf2a7160427810a6830224884276b48d3997b62dcc8b8b2463815d266ac3cb6032f7fe43c360efbb9622c6e29efa02cadd1c1918a481e1dc0229ab791233203d6185f8482b1722c8ac220ef3575d49b60054671ac6d91c078d2b70f272eb822a484c18d58bfb09ac4914ae57f2daf90889466c1954bab88e058da04a1746713a48fddc248e144dee67d680e687c5e171e8eee1da6db8d1c2967565a2c43ab4c4a14a87df4084f54fe548a2c710f437ae83a11acecfe6852d0064102d867146109f777a15239e4d42e0cef7a8662658ff0624fd2a0e6e80cbe935e964051f9dea4e1b31d410a62fa5ad3256d92023eb08ce2371643688ff1da9ae9e162457ef6fabc72b5a8e60eb8924dcd8c5ce939aab4906bc73bf40920007aef745a855d1560d19f076334c4eb1d53b2952359ec95f5ece3af0704ac4786c805e28ceff1d0ed7bda976c6efca80ab6ee5c083f20a2b603e1287da938d5440344af33236c5bbe471793303aa265216029c7fb98bba7ec413107ee29bc4aa31b9c6d6d749ef4773f1b2a48fa974cc1a7a0b930583d149f71fab4e4e17781315c67ab0b8f1034c44f306f543683574cd9682930b09c7d808a5d74d64640d4e2ac250dd1f3b5f4b5115a7d1e86926b79061ba1bfa310d4deced9237d9003d0e48014577e45e990d6fc9a1911c974f3a04f3112f509f2265c227f48f212285cdc338fe7b82bf5380ff5880d1aba22cb092018c03f5a7b952ce21f472e3bacbdddf0cf457a16c9612a1bfa932e642361070640e6b12c54244f3b8c3b6b1073ea2fb6e475cf65314e649750fab54e1780f4d6eb59c3f5dba8c8236926a4a09d072c9a72d1465d904e6ed90de9ac6a2e57272711c2344c9b27b840606f3f2cf926ee4f696f67d8b75e498261a4627e2f4249499ff03ad832334a81304514a9f28d2f34482c0396469ca594d724fe7fa85eb9f3ff9da03d8fb03eab7091d6fdf930bcdb31e2b37dd7634f3202980b5d632139e7763c9426790105cbc4c5f5c47040e95670186c37d1499ef794263d57f3c33ad21651c42db3ea96d71bd412c432df0b2e04b9c9264db4732d0f1ee74364f5256163dce9b9e8d51a32676aefc85299237a79960acc47ed77532ea35b35c13d2061b9718e5058e84794f11eef6e3807d395bb1818f6b7e32ac2d4d3ba878e6cc1b208a6bc50dcd5dce2ffea1a5b1fa9668dd6d737eca8f831b4578e00e23cbc697376fd9f4a4f8236e07d5e6f20acb8fd568fde85065ab8d09d649ba6aa8a2e4581d8b7bed7e25484e39e8fb2cb0ea8c57819715795096aa9aa9566a84422e16ad7230c195cc3b2064a1cd49e1cccde6bd44e5a3164e1e8899ddbc95f439aa395f58cb2f2daf5b01ab0d8f35c81037c1c2167557dc29d71f2a72c96899b05096e06eb88bc1f816f0025dce9bf9c3e4d6b26356df9e054ae8496e6404bd84417ef27f76eca9bb7c3666b77cf1b7d2103a467c276f79e4e08619bf50cdea784660e20d6396b7a9b67b6955cb9088204ac5fa1817e25144944862bf95079cd42ef714e5c9b0fc1100786e5063d0c17c1bfd2b6b62675b67904c75463a3ab0539081bdb0413d2a2ced21f0a4441752cdccd9001153e7a3edf9280bdd82d68fe76f62ab1bce451a41acc8c0031a81c53f0cadf486edf87bf85e9eb0ea698335e61b912a3e6c435ece9eb07dc472a625481286531511652c85782fde813c3f7dfab6d8d84f0f45c0aa25349564da062242cd3e74f553ba7570a27319a29752dde5782cd271191d9335a22c69c000a0a52860c20d6d5f3ec7b9021b32be214b69f815e3a88de4bc1a5e87fc6f893c01047297c4351f6b25f07ee571bbf0a43b5fc8ca990158d600723065d96ceac02c73f19a1f896b127f8f4ed47799f64f8decabd6b5f11f449d9a2f94e86a37ae03a6857747282ee45541fbc745a1a06931c1b138a14fa6a07d5bf2777b91dfc83ea019fbbc77befcd1ae2a72fb54c1e76bfd4c768f881a51b502c135429d84198cd3dd3afa5770a459b301f9846614aed11f25639df16556e943ed13656a45bd2cba5f14cc1aad0abd037499dd732be8008c6729aebf90605f210ae7c845d6c6f216651781af85bb483f1eac0dd5968e4c5397e04d028f33b0c4ef1936b398446afb4ef5f73bd6e7058b5c0030f7c21570bef9fa59487202c0042f5610a81431f9980d1ce17836d4443e1f751c0b033daa2931275964f202a6d957f7a93d43664c6a351d5a47bf055b3ae88d0b544afa9ecceacc08bdcc6cd82a91a46566387324bb3f1e72aedc17781019ae34c7abd2bf11b19dbe780f441df714c92bdbf506cda09fdf177cc47034c93731c353032e6033d466d39aac1d8b754067f474dcdcbd0a85d70caf233fbc7440327e4bc182e7a949e5dc850390911156a882ceba6684cb728a786bed9c01cf045dd40fbf0f0c994dbaf766fa0dd64fcd717af737c6467afa2415c7d86fd5b73b02633185b6f9fe24f8c0e94361e21203f16baca213e6dfc779242faae849f2efe4d9ec7e0730a53b5a21991824a6e1b40e52044e23fbe40924f44fbf23d9ee30cf42d7bcdd6a7ffc5d2f7284f8110ff52251281410f89ac2a2b415c36f3efec5d68adadc145e097c7acec156f6c0a7a238dbd2076907cd164f955634a39f23d7c0cc03e2e7e1254a10252be74af4a2c1bd8189e74a8b9f70fd0d66b81a31c0ae669a2ba0a5f8658a18fb78fcc55e02fef35e92a2f47fc7db39866317e5a4daf0401b0080ad0876a809e5d3cd76c44dedbd8bbe252d89660fc3bf3c259218b004d8ab9f4d5605a925cb963645d0f5ee87f25efe9f017fcf9e8321d24244db966e02f679dbdd182f17f601f9910daa69d29218ea5fbda2581c692b6f4d8579253577c6f7447c303c5d62e0e72cc500d539aedbbaeb99cbcf77bdd3deaf1c465a0ee2f2c7426ee19b2012117500faf25992f2aed5c1ef292ec7ec3939d6f58884f494163d663511872e628c1c1261be5d11bcea62533d9a2424ebc13be64b1c8c929e40377ecf83bc7c3ddf849391e40185e740705a9cac5f834729088f0efa68556aabe1dd5cf10daa0fa9bc1eb7b391678fd8d2a42cf3de69450fc436db3be089b53ebe363193e2e0ac5179a46c72d079146e1b00f4d236f0931ae256c50c82f804b66227ae25458a5e4b55fe1d660f1603e73deb879bc46bbbf3384844941cabb7413b93cbb328ec6e54dc7b8c94f91a4aabffa1659af909b78f1e1a5255df44593d630b2ceb2956190f4b0208393cf99b05d6411035e9739f7f8aa9306d18e928d37c4afefce3a410cdefe16bc46156220b549a3deba90926cff84a4cfef950f008d4bd1d6ada0831c2b8f59b203a7c8927673eff909b78bbd8f6a9abc9fdf8d3ac994f76435d4ec32f670fefac236b338e5e79cf03f67b12a7120db4c012c1e2233b6ebce5adba2af9149c3a5877a1a3426403ddf436d38cc5004dcaa4154d020c0d51c2c4aab65c0b669973f0b50b1aa84b8ab0540a8eac199b7799d54827e0af6987499df3cb8d3c9a91de5079b0ba836d0fa5ae652029ad0303347a99ad41cd503e10f9e8991a0228420dcea9a1a8e3c112c3df14808dc532ef34ddf15b236685e99291f8cc34bedbd5c8b3a44b1de0b949a6c4c6ea5a195d37b47967897bd609f0cb93d5f70de11d53559320737cd4592a8768279566686d2e698fb692205eb4f7b40a766b908754e8af50d96ed0f772ec9c35e10c2a32953211e213d84510eefafcb2ac0878d0589a0b01babb5f0024f322f5e554584ba935a4b3322613154dc04459d13ea8bd4941392f7ff1d60a046a9f3eaad447ee088a4a6e5db9d13a71f4a94078386ffa5bca14e8ba64d6dd96ae7596dd4adbb830e2c1ea530493709d9ae7290a5c207ab54e99a456d6325cfd99260602963813673b4c70b087a7eeb6755839e5f4ee24bace87969b4d3766d0adbec11bd102645629ceb32ecddc3571ee2b59198a26bf35bfd002d2d1960f466b17559263438b1994b9b33e2be6a707256993818eeffd898900becf40b7559eeee02ae08545ce8516f88de022b1c53919d725b41722aec50249789aa2860a016f26ddd15f1641495041e9d4d89a298d3217ea91274a0f3dd782d5d187538ce8142e17adb7f8b833b05dc3e017d6a96fcc8d65231a613e454eb58aef5e87712673545452928b2ff7792dd2926ded68aec7a8150c32bf8ef40f8abddc3ff09e760f2e1bb47b909112c792d4bf366de920ef847655264d9b7cc893b46677dcd37d3b79da14380e5a70e0bb88b7fa7fa2ec93962c8dcd216e9c3722377e1f50260ba20637ff0fff9f9aeb754aced500aad071a756cb9814ba53dc4b016735bfde1786c80a4591560cedcc424746b87399110f424c5bd08ec04ff75dada842cda12f45621b34d924cf9da5b21c334cd70d9340ff6dfe2fafee6ca4c1c632e6b07a5037f4a13076ac0fb1344fd59d5d07c9119ff530205214ee61345734266c1b7c969359af5a8e4d3e46efb4ef778460da333c8dc54ad5b78ecf721b249ff8c442617f9a3f1eb60e597b8fce7f50963d33240f0a9f206f7c0b3222cdc2cc0b46bddc70d440dcbdbd80a477a59b0c17266b00183e805cdc9aefe45ba3c04d4ba36c68e3ac86fa4ffc96f4415f2b59515fb011c8bc4a49ffe2ca506ca16135009fac16557fb4aaefa2a4a972472277b4e07df966cf7e4163901138a3fd835b8c8dead1e264b7a947d143219b1ff8dbdfad8d3c21f489d707e7dddb221bd1bf7869f2d77aa7ef27c525f697832e7f760c532f897ea7b26c089b0561207653891c93431641d394202fe124812f91b6b3fc39edafa59be1ff7c35b61a7f5f7be6c560a272cdcaa2b0cdbd3fb3569f609d7160c7ece89e3f4935f0671847555e69f70248f8d80fd2821ac3690bea8492e3ececdef0743580c5fdd4fea210240b7532df856dfa2fae9bcd6a5d62205c0560d967d3262202095c5ce637abf2238e72a7d983d2654dec7c9297f64aea390e3678190f971bb1c67e39326b03aac859c2ec767ac634217d8b581c9bca918975ab50d3d15c96df2767e6a922d1c99c39b3e3c0e0456850f4994d1ec9da2dbf3f4a5162a2465e0a96996ae95121e69ea5b28a884bc67fa950bc2ea6816d96b3a348c461ed8397bcac0a320e520fa7e5cfe780bcbfee471d1df3bf257db908b68e6e9db405bf29fb92bcbffd37abb104ba324ada8ad259dba1d8c29f33aff1d4e934f27e44012a9f4a1f5dbefff248c7b2a01946212acfd0efa7a2d4bd8e3020a41403feb603d8d4e1f46f3bb9fd54cb5ec0b599c4dc5ab3731874c11a3b42f2ec468f68015afcddc46b2058689022861604cb49ea5ca507309c76d8cbde21bc10e83a8db166a44dbb6854d8aaaf67871a9c0dce163198f7b8e40154025d305ba318b5f46dce6cb580030b7042f21b612563c907cb3f2144d152f502aa75ac7aac7353c2c75477dbf936be288f84444fdaca0aa48d52d5e6ddd63aa66014bf82099e479577672383577a9eadd98a8739a56f5cc3e653b4250f4712c7ec4b2ab546df1882bab15a80bb9dffe2a380d4e129dbb9366da2429a56aa6265e16c1d0d849f894186f43ed4143d7411c315f0b906b8cf4c19a6a88fd1920e3d20dc4cd516ade2d0d06e8377dae11704b01c64ecddf554ac30dee86cef0c35268e656b5fd70d1a97a89e861a0da5f571255c8fac26cd81d609c5080348298c981db34aa20f86ec719de5dd7ce6d5d3feb8667a709e20c67b00e06e7623ca67202975e074561ec8b0d966d5d1375ce4bbbdb860197e7f2068901765804e3ae4444c0f7261489d4b4a2ab3515e31b09db7005de4040c5360a6f9996cd6bc0eb73be298d31c2387164a5c4b6401d3ac3dce074fd281d26e31f854fadbcb87c315cab1a32532b59c80e587253492a857816716178a61cb01a06db86be96e205bc92a6d4c3db09fd173e08071e10c106d83d8fb75fb07c3925921dc41feb91e38a411aa8fbf51f8313dc2cabedb4a3d780a17c74d6ddef0c44c3db01c70c37288ca159507928376e78550a4f3df8409be531945d4b652743cea183a631f09bc7854c1cfa426a4b9dd03a7a2fa05089306820d47f7863eac8144f401414c816e07474a08d72e680a9b4f335ff29a23ff49f7fb8e6718b01cd93219bca50ef2bfee4ade8271dedd8f3e8e809fa097caad7d9ecaafbdf71343f111263c426bcd4d24246e05d4f9361fc2dc59fbabf053ec108c848828aff67d5e796d659db5ecde1618f0574430920ac913f1c4038c8c462dbd5b6e0f5ccdd84e5d2ad72cf306ab3ccf2c66df37e113d9fa568284594ba8b2a51378c778740dd1ce08da42769f14e139cee7ae01de21b0f3b5144ec3f45f3970bf647d9a5a565b454e8a69b7cd9345cf7c81185d7753bdfcf228502dce88d0b21cdc6568b50fb26738431833f15a067f12807df96316d51296865877ea6f8c8d979d91481fa47a6fb6c4c3c3dd6ba1424564b9c9f1112a85f87af054182abe753cfb2e1e2fd16ce4a71d5cec242ffa2941e6ffa44ed55b305176a9fb04a3e2d99c8960102543064a922eced19c59c12acec80b0f544cb36c3debefbe8cee3a940af1d319c5dbc48f6cc0da1e56a648715758164744820dc909a07ece602eaf70d675c40961571c63a21aa47b283321ce33858db83b73c827ca0531fed88c6a3240f41e15bdef31b42b3877f1aa001147031e974a62460dca0339896c71f691eed1fea00785cc6d22da22d3c8248aadffdee77f9d1d55e5ab2b27b4b29a50cf2064c06e905e3026a8a64a1880ec492d8818d2e1cf1010a27b0200821f2ec074b002106583cd1c40d5c6658b051821656e0440e8a4c0817a4808328f48022004546a0032cf83004082552a32da34822a6031f80408a16d41e40218915b15790298858552b3c4136031f58680215590040083f1421a7074d14b962659ff7f7bd5b4d0a15685a9723536badd11a5da748235057727997a0b1d6342cd0a8298c2d4b4344eb1b18a002cd45bba0d068321b9a8d868686868606f5636c591a7be3424343c3d17434de358a519bcb68349d43ce040535e93d8882a286ce943318a36a6a2f4880fef0344609d9861084080bcd8c0b8d46e350861072efbd3b8e50a2c3814eb9427b41e0d8d8b2b51a0f2cecae5c24dc28d20bc5ddf18a55817b48c2cdc2de2ca4f7d5de29a43435406438b0681441c6c282a291e1189691d1c233e9fdd8f9ae52723c73553c57c52434d9a58b42b1a0e0172e71696a351a6d66a3bd525ec0525774c705b098cc0b4cb3039f45bbc1a9bdb85a080d8746a3d1683a9a80d950c4088d8d0c088e5aade6d56ab55aadb6033d96474d50b4208bd5645c33359a5a4dcdf36a59f052b230b66c4d56691facc6be761ca1048f942b803caf9605ad5123d0a00eddc00015682e2e1506aac4d8b235584c6686a6c613e19a2fa6bb0d107282d07a1e6c882e8c29990d6ccb604ac59acd66aa22a1f7725f1091928562a7c4c66636b3b0f1a910fc30ca094ea44a1bb1336304ef09d19245a4486a8b3bfcbcec79b021bc141e63cbc260f6870c6c23ad806532f0870f8d69357526a603a3502d08b91bd76d5c873241109c9b2be4122982516480ca42085ac48546a3712d10a853049961061e41ae917b45eb8a9dab94fcfe1eb9575418f0553ca367cc17a50a37f8795d128d725bc6f93d14115bc6df8d591c1b998c08402c88c6f2c6757a861c594d8623bb91d18c20a244dc5a6bed1851f2e288114dc2831204931419a07052aa00a158918324c97ded08a16468ba044530213aa0c3d3e163b4322b63dd1c994c76042cb3c875059fa647dc96b92da37400735b26c96432d98d5d2032ac7265eec5375683b1656547649b2ccbb04c66714c1492582c168b7925cf9bc5a228c20764324f4683b155733cac9283d67e63318caf0dbe337c69d7ab265777297004bbbd72d7afd17d3b61b677d7278c8f16987af4bf79ad794f9306f7ed2ddcbbebf3657ba7ff726356370040185d3874a8585638b0dbc6eaae258203a374649a9d5d34c68e9165f78bbdf786f626df6e065a6f9b4c121a0663cbcac8589421cc2e6a04a70cf996ff6b2239e7bf8d610bc35b4a125a6f9b466df09f4811235d0c8404d410282b9ec005245040f0c24504ca04aa0a1414d021293359101b9619b1d8b7478c3a9a52d92de32d632cee96b1f53ca3db715bc76d283ab83877dc56b10d97e65c6ac6968d0591e98ea3d1689e8b0b1017ac623b6e8bd5c656a5c15c6c68b41b9a6b8bc5625e2c16ab1895e2c3d8b2319b188ec5b6588ed1622e7a3cedda23698aab952598814531725380f042eb171855cb9e97228087ae606ca52a6043a76c64b4adf44a1a8cadd40b8d673e2f244b2e5e709e972240e995468cad544be710d3a954ea05ce4dee405ba40481b241b149914931012a04e591f2044a86524418da1429a044606140516296d12c6c2f5e1c8792c5d8b2ae1e31144539d4a2d885c5489259739c0b97ed81246b30b6ac2b6f317288d484dca03875d12148e4d822ae6b3240a7a9c9c48b1220b9819fb3901acec1d66561164dc1e5b81d45702922185b764759ce80b7ed6cd5d91704aa4545511445511fc62b436dd0d935d2750780a1a26887ca8c57453f77ef324ab3a14150b6e8baee0858d7e9c8a24bd9a2446f542d458c1c418276a9111233b40aa5ffffa9705184d0e36c870cca132c33acab0d164e9555578c2d1b7302c7f008e4a23081a130661424b6142ab45e71e142bb00c2d852c176e0c462319b581021448a745acf2c9182582ca6c5d852e1a0c2365a6b9408a34aa562c136866318c7b075e28644041415366567b646a72c0d46a146d0e0e88b5a8153689051176c445002092bdb70342c4021c1d8b234ad739b0d980bcbd0ad02468e2049d2953b40c9c0ce90c964b21b3336168ce2c18590990b169b19c6287b7d517ea8d509194ea69391c96e79334a0c36942470a81274e81150a0982579edf050293e540f4014242f1fbe402693b9b04c8fa24c26636161b919736091c96e3a55d7298c2d2b2393419f4bb4ce38638d8e20888d10169b998bfb999046adb512c6969541ab8cadbcf1d40a60c48b10f0a0019fc1cf9623536b5d051b21b3a3a0ac0a8c22c165aff23d0504ad394d399333ca0e80e47c5f4e16fff72b8c2d9bf39aa3a98af64e952a73a84da752a95098a0fa0124bc99d4a82d64e0931795bd22f00f27d2d633cd5793e600c9f9506a25204e5c19b85457364d33da590f95aaa552a9542a153844980ac7b7302b6369422cc224fcc118d72e778370a5b35cf31ef4ba22b779b7d2c6b1618c4b275fa374f284f101737ae935cc834e18d3cd83a00df336699c0e7a0dd3c92bd210ee9383fbb7a2154d1aa783ee623af9bded2a6fd64bf4d0aba8cf9dec17e8a5cddc360e638c31c618e38dc318637c8c31c618731963fc123e087bf87c0e7d9add9feb4533c6f82718dfe2a830f0636031d68be6d0d727777d7d561dccee649dfc86ba3a39cdeea09f984e1ee6749add4f5e3afd74c298344e5e7acbc9699ebcae402fbdc574f3a6d3ecce1c3adc5057a6e7a0419f65bae99d26f91aa09f9c303e5a40af41fee427e70b0696204212245cae15f9ba226f9e7c5d65d6eb45bae8afd143e7368e77f85cbe68893b57751522edf1a35df2cffe5e6ecf45bbf3d0160fdae1c90d7e3359a109e9f994742e86075719ebc028dc29193df81fce1877d7240960beab978fef2f20c6157920f4ca07bbc5ca077ec1522bf2408cabf233462cac227a0dd245a210e9759573ce393f944fca39e79c3f640a206955425a871c8196966f8d654994620165f0181f969ecde77c9b4f1c17addd2d7f7b1559e459ae793f7a5d91b6794f7a476e1cbb5eb433699027bd067952e830a793af11fae8843979e8a00df1bea1ae5ee545ffaeabf2e116b148bfa1ae48278c0f96e85aac5e6256a27fdb1536efc5d755c9263d7c8dd1c513e6e4a3938f0e733ae9da8205f8c0f8223df46e3b8eabf2c28d8e9a6625f24db647a4b9dbee0d1bf938e47a3303abc4b83746fe77eab4a8fcd0aed6002d94349fb45f61e41be0c7787f8f4fd32b4567b960013e30deeb5061b82e8aca2fab2d40ab93566b8056cd22cddf89a3c2c88f81c598a38a3ad450d3edddb7894f3af9936de2936430319adec92a45ac97e9a5ebd3ecee429e7497d047c7dbec4e1aa4936f193d74f0b3ebaaae46e3411bbcb94d4eda251fedcecb2d5eb4c36f264b7c4d5bc28337249576b559f026e7409bdc157b3e96bc233e7c5de9e86c8c1a3df9267b9becbaf2d415b8635c19c68f9135e3a239cf4231ddf594c0458bdb35bda9123324123219cb6c7d3d5f88e20656c92d7dafca56c3a8ee6cbd70511a491da6f7ac18d58aa1cf17692b0668c6e68a92a8892e35c05b5107979bf41ec5678ecb46c3a8fb98199e2fdc776e358cba628d1aaf22ebf3768bbea7cfda125ec7acb67333989bb92a9f1f5786ac0e21810cd78303c205e16cd2cbcdd2cb11492fb615d71a3e3c754b78ef7cf15a5c2cbd2dce955efcadc67a8167ea2c31cad636209bcc863729cef7af9563a9b7cd16efdfbff325c330ea7af556a68655f0b8e594e3b75aad8655ea6acb71c1b61a278365dc8c8c03c2cd7034780a230e72d1cb838d9fb002905518d71e9f9c4911c0eac2c510630eab68cf960d034861cc3f76d868b04f851863293e27e4cad0c73c8618bb4a7302164510c216aea8196285eb4c8916e45ce1030c5c50835f19e602709ae2bbc03357c63d8f14e35d7fbd7387cd01a72db6d0127062bc01f831e21a6c836b30106e96d617623abb51810fde329556ccc5a4bb93de2d52fc029211bfa6b5ae541fa4f8f8c75aa45e9a77ad305cf926888e196c6c6c74c76d1db769141e66a82b55db8c3636363657a75047c69695b138416c66b030e0637447462961934942eb138c2d2b837e8724afcad5c829bc80bdd0f84591d0721c870aa271f7e2ce6c55102137dd10b4070f0b03a695b68891234892749d8c073da8e96a8c185b92dc203962440a63abce2c4e4d4d4d4dcd4c470d56716109315a18f06735b49acc42efbdb3dac3d8aab3960ce9c5352c3364a82b995676458c1c614951c458e4c646cfc61a5bc322a1e83a9c4e666cd999cbced81891a5428bcac175a9808b25725d35ec72b95cb3996be6aab9726833d7cc5573cdeea6b23098a970b22b8665f04c5661d56c369bcd465d8ed7655340a0d21dcf58ea45bb6ee6011058295c2e9790b1656738b39bd9ecc6480626b1b145d6d77cde91887bed3f0f788acf505bda0d550aa7bc2e4e148a1bd7558e5a9572e9b82d451b5be30d1c9c18385aebe040e542ed86be5161a4f8606ca56433a015b158ac8bc56eb06031c66236168bc5300a75031cb2fbc2078c6283f2890e45051bda046d6190e1c0b22bbb2826c65695e5d0752c5d11a3ee6429528cad2ad3b29857ba02ac2eea0590200226f080b363e60a49a6404207862c610b3380d552698128a2004205088004a106bde20813ae60c108a4500519a18b7e2f125d3c5f7e91e82f31aba3a1db7b6dcde6dc2043e7855d5c3ac6b748702d0749f15d253ef23ddbccff4d273ffd656b5796e273a19b80fd56cd016db8b78f1bce5d57a28b3b248a62e8e7b62bd08a3444a2d0e656ecf16fb02a54a4364e483168715cf6c61ab1358be4cab8b6666f845821f663a2c2c02ab03448f15dc09d96075757f4f16954158b858ac2b656abd5bed7504d1b2674f1df30e2433f6d98fff4930d7372d3f3363578f0645d1939cd91b76fb35e2ff3a3bf482fffeda32574f1a70d237ae727db478bf8d04d1ba673d1bd5d43f4cef5a6217ae779d7085dfc0b486e0cabd45a5d11538c537c5d5825f4ceaecaf0a5fdf17cb4c797bbc4e4e35f9e9788ce8a4367c52856a7035af17390c93d5fbd2e8a6d0e465dd7855d99cfa649eb2aac599875d55257ae8962bc0b0a22c7fd0e3a55f9ecde804ef3efdec098e6b35465154cdd537a62c907eae87b6f919b4b57747c10b4c3873678d1f6f139f9b9b7c997db8a1bbfa3bfef037ae8553c4f2b1316e00323f7fb9c52c6cd5dd77598db0758b10298e1a23277ceb37b44b202c0f776d9759fdf50579f57d1e44ed6f7791676d6eb55316afbcbd260147ef7ea3cfc4b5c0161ec70b8326cdcb83272b8323c2058a504fc768ac72d2b3b553176698e9cb64afddd7bc9fbc050ec94e897a52766bb1d1e44a291bd22916734227d261f900485ac0db9900bb990036d486ef1261fefe548f46f8f407074f0229044de44f41a1ddc388c31c618638c370edf7befe5b62c02475ab38846cf2c59347261b968d7992c916824dae73d79be3ea7c909ae3c316c98c47057fc01585de85c96a06a4c479fb2247d33e4b1e7d8ca581bbb037337e1391887f1472f47ff760982e5c18f405268547e5f075382e6478e131636d3a30608776f74bce07befbd36b08a0df7da5061e003cc58b128fc6f3f91e2832a55573e0b3184fd803e2d8c3bf7d1a8bc066252d0457f910ffd58c5c20e035feeefa72a462c9248a7c99df4ba72a918d5993440b0fc7798d159e3fbe8a313a63cf3ebaaaeb61d1eb44b4eeece4db677cf1e5f451a20f8a9ab8f8907feab2b1c36384353030476c3c645f1cdcd2786bb230a3af060a8310864429222715476483997949494e81274f222d0c14d822079107991791fbeae3a5b74f035420f43074387312fba975fe14139e79c35080a3bbd5d9fa6c61a0cbb9cdf9dddbbeda63e59a0df5057a0ebe089ee629ea2bb94ce90be3e6845d3cdf3c587f797d24dded962fac9f962de942f7a4b5ba779e4366ecb18638c31c618678c4131ddeda4207bf8743aa942f7a97cf29cc567d173ce9d5c6650ce39f7c8a00d4f4e0777a9f4f0a71371c3981fbdb3617cb4981f1dc67492d9bdc667a44fa5d7e9a577b7ebb6176e5e363b68dd7667d890efbd373fe79c73de72ce2fe59fb42e1de39cf34f4e48b3cb766fbb77d650d37b7db24ea7d2351093e2b3ccee2e9f93ee527acceab4cdedfcb61dfcc96356a0f77a041f82b85c1552cd9551d39ada5c5bd50811d256adb56a12970c4f6fa9fc18a6036cbabd069b6e268df0a7b7843f9d9c2fa6d3dcfe39e9e1f5d902be74be98a7b99d6677d2f89cf416f2a3931f3d44da9d8fb6f8728f17ed92837008f4d972ce39e79c73ceb986bb9e25f25ff7408cab303c10e3aa445ef326cdc5060ed0b149c5a939a1b72cac0217c5365c2e4aebc1d231446ddae26fe9e6cb5d57a583dba411b30a7f43cc2a3c5f62562f3e5acc872fbd858755586ebbbaa29b5e45b32b99dbaba85fe0c52fe0c888593666d8e05201adb5c6a512a6c12b3f8bc2174db4debe49e0c604409a135c68cfcf39ccee64955e53f31bebf50a5df417e8a601849b0016850fae9caa183b1aa59777313fb2228bf4ed8251f8a312c68fd14589562f5a62bd481fdddc30a3832f6d181fde61480f699417bda5bce87cf1a1ff427a797db6886e3a5f46179de596376dd15b48a777b68cce8a51fa04715aae3abbaec8b0dc9d8bb6f8d01e0f32d99ed70e67b2c2102463d810735cb0988c8b2a5543c674b7a408ece5138c4daf2b0cbaf91aa59b4e18d34b374ba5c39c0e3acd5b57a53d620bc3a103b42727a449fe4d20bc8faf03ab8001e4798f5cd445c280168cad70654b4118420e8c01a72002121072360565e03a5c8a5f52a6a04ab86d9102a030b64618c26d8740352fa830ae0bac0078dc28413b62b6c306bf6290c2d80a6308b74de22820884f1aee0484db3649f130b6c66d7b64364c8690db4d7c86450fdd7c4071a3a9572952fc59256918d39254ecd8dd0479568c223f22192afa90204bb8ed4e4a7ef06fa846b4490584db16431b03c1a87bd0c6351875dfd9b8076e41858193638711b3a066269542d1e394e38ac8d81a6908b71da6e0de80dec098721c0e8e26c98b8371c273db60caed26c887fbe27c9e3eef918bba486e920668616c853384dbfe527037419edb4dbc3e0742afc87fbb09985e91f77613b071455eef2660e58afc0d8255b9381805455de1ae163723153852685df3d9dc6a5bd95d2b0c2dd227c6958c57e406a55894624f8a476e004094ab7a0d70ad605529c60448efb1aab3b5ebd40ae3ae6460406a32a0f2009576676b03a9ae30f057527bb08237bceba298e5ba90610b634bb394606c5d1c7c3f56fcb2e2d7aa2bde6e3cd79a600ad08ef5da430115bc6cfa34556b4b8f154c6b117aa8416acfd6f8440f39692b95d6cf9881ebb5f80910acf5448bf1fe448b0dec30e0129172bf35a4383d30c18b35e474bca8e6b6bcc5f0a2b0115f5f74e7eca1008f203319d8a796057fc6bd3bd54a5debedb461c81542c8118115301cc890847e91e21757463df159667cd23a84045148634832b652a92132ec5336e7946506878454db55a8b74d6f39e0a08de029b2b791e4c77e3ee14892e0e80b794a4a722ef9c1ae4c5e42e3d9e1bf0dbea4e45332da76e5d99f7f9bfcdd39b89b7a745f9f875fc09131e79c73873732fc6ce4c78ab83b599fba024db65d61f082f6f7d0f6e06d531a1b88bba18fac4a3d1f5d21180d10222489672ed05717b421c8f3d0ae2bcff779fefdf385c80fc8fbacf75917786bc77ba7695f4c6c4c4cc605b3dee78ac9b860aaba7279a830700f1685afb2aeef5a170d17b43cb85cd5e5fa8eebe78935d83447fef68fe7f3c8f3151e74d919575d11c79a32dd72b0307cffbce5fbc7e4fb76b678f79c2fa3f71c603199199a1a2032972bbb4a62b6db59e2033fb084e3fefb5e3a5f48ffbebf98311f38a3994c4f89447e20d1e8a6765d377689e0300cc3d2c7f4214dff4010bc0924430775a6cfc671792b693b9bd5a0437e0cd7b4bd7ce82fd141074dfbf4d23eb949725d4adee65c1ae04f6f01b9bf7c0e9e3b5bbe9f9c2fe43ff0a5fdddae409fd0647bf5cc2517ffea3c0441939d83a571d7a406a269963ca4f1a3a924f29c98a39378124fe2493437e8a5bc7f3a9dee398d3fb9c933764afb55fae9fbbeced7e998a792d87967344ba2288a17596e3ef9ab7453d7895eea3fa93c6ff44a4fecfcd3e6f77574e79fee68d1dca6688a62699bfb747aa9543a9d66e7fb7f69ff343bff4b3f99a7d9394d1aa79baf71f32c5814c397b298b3b9ebaaa4d3ef9adf995285608cc163ac17ed2a77b23f376d939736e8e626453be4f18c27d5d5a8a43c5f9e8fa2d163f22141a192ba2a092f09c50c0c4f55783e86abf21b38c2100441f030a787a7f9ba9ad1c07076637166345c6299c7c12a2290ad5dd78dc910c2682f8f6b67276fd51bf0e407d2c3ff303a78b26255accccc133441006dc5a1c9644166446632dba3074e0f9c1e3d34f74385818110014d1133f6a53a4055b151583b9b9daa18b78a93c3b46bf917e8a29ac62a15cfea8a98665a5dd13a47cea1ae78c7cf4055b13eea0cac48f1abed5161dcb474d35dcc9fdc8aacd3c16d67b8627cd30efb7a8158a4e184f1d19927cce860f8ee6c790e96768353cb99e1b831c399759734e2bba311c92b2973a763924025a591c8f3f067f27a7c2cd367f268bed1fe9c94f70d7515fa8915ad6832995e62ea9c80af6226ed17e9269bad052d9873ce19ccdcf54626d2e775ae37227ddff7fdd3804db792920eebf51abdf417e926f8c9bc9449750ff546aff446ad1d72386aefd401a79d065bff46dbfc4e9386c9a4b3e71a6d1c538d44329d26f8d34f4e3a4ff927a709fee4a4d169fae8354e48379da3b3601dea165b6c912405bfefd44106afae48375f6315d2f399c7d2f6dcdce349fbf3d136b9882c29e9bcdcd5aec857d12474823a25a3c7e4436eb1ae30aef9ee67096075d1caf7ad32159dacd089cf1928be86e89d13c674d1459853d5a37e4ce8a2b7049c8ea8040e5974562a333300000000040013160020180c0c044462d188384df3bce50e14000e5b7842605e4a9f0963a130888118843106190000300600030031c6100df100ed0ac815f0aff1fda3b06290da8665d962c420aa753051822e2c82aa773728a1c9887d516cf2b2c1bfb07ded7f3be5c47b9ea71b896e0d7a1f158c66eff97bda4e63b202aadcdbd5a9af86f22dcae1b02a59df923d4d42500328a2e6828c05b79d35856e6b32667c7e92463e91542cb8751c1784bf8a60148edbd9e0ae3206fffc98a93de18c811de47c1b312df4708e9ef53a7f884c8dbe2a7b10814b4952ed54eabc9a21a1cabf25ec54b2dcbd57240322070398f4e600a4be8f807ec8633e38793a1a1cc48a0befb140a054ea1ce82d942fca68ea22f781b0734b641801f41d4a4c444878753d831d78d071e3c60e5273f88ceeed9f5107757fbd34aa4a6cd4b046cdb04bffa9a005af858ac112715b042d512f40aafd1696c5a2c3c80bf98f1a5073e25b92154d786febee89007133bfb7dc904ecc3db8fbdc3a390760619c6364043cca36c00ce646c248718cc05ea19294b1b9f8f548f1f157127e36794d6ff298af7feac59a57cc8ff0640d8095003b99aaba01a9e7d152e26de8646def121f5aad71690d25e24b80aa9bf52b4a08e0c07990622e9fd88066b8512ec8fd0712664f4744a3c80b3923b48cfbc93bdadc3c2baa9ce501f9c6f4c596a77413086720970ceaef0fd6b7cd0a11ac6b4673d9d284a3b8c51765fbb5d4bfd535708e7087a3d50e3262677573f6093ccedb38a671798eff440309612d7b0d1a0ac5874c8c68c4d739bd8f50bb88000df7b9be3148ac52ece846f039490e292884ccc447a393e43f52a4675154286d9f227caa8d50f20e13daee33fcd660a5734666232921ee981b40210d39f62d9b672b2e5b5f6f4553d9f91441db46cb1b066412fcf6f3165c58f4163c22f516743b76f81c11fc9e76199a4b40d198178e9fcf76f04a8bd5ad28736192a0047465676c4c64ff56e633ed14d800a8beb6f64868039c12e204e34fe647368091d6c8d31f269a0b0c7a8d13eb687cfebba644acbedc1d02341dda169843db79e4d0e6d83f29c5a7dcdf97a424435b56fbb8479ac2bebd9f385d6057ff1a8fc34e153972102cc72f9ab7643638642d9f9afa49c0f82d95444922721ac1b3c724a1034fb7b328a51561c5d4270d0240c390cda74439e9cd17bc3c9f8a936d60eedb8f1d896ce34c5ea09211d5cf98b801d59ed29d4858a8d8525afc240de92b4c9ba45029f9f26b132a559682098f844adbc5384854c46b4391bd09147b760a3775382f9758c34cc82dcd5f14c5be5b75df4239d6dd5f1caec614442eb1326d2e470086a97817f7edc830f1e91c3ea42c2ea285127ad824a49f94908829dadd1b65d12b8cb0136d5ac1a93c8185ea28861369321a1ef6ceeae29d6a0ba53ad5f39e24b2938118903036cc08b52eddcb2a1c421de3955f186f09ef8f7218126431b18265c95b83447a12d4b28ab0f5a1939f395a8f2e9f88c4e672860f71e0fcb46281763353aa555b1d598f1674c4353161c09fb06cb349e72711c8b69d96d1bc282f47f5386efd27bc2391f6aecaaa315b1722a3447071f10d6b03e9c7f476315b069009420bc0ccbfebe18aa12105048006d3fda26362a9a633c0b8993ca8d1fe81cafd107182be2ae82304422af608336fe2e8d7543f74d16968aced9a2861935ed757cb627b555130e3496979c3ada5c9be71092653698c7712afa4d026bca5811b5e8b02c84e876060078da2651f313479d482dad3a2e64d2867e83f6c4cbda86bc0b46bd0866f836168588b57b6336037c8fda5a500074dadbc6a8faf2b0c49abf001b1872897f75e6ec99eb3096bcf8ce03441df833aa0e9442f7a3c86115b86f1995c52601867216b55ebc17d7e052534a0b1bb035908b41c63fe08dc0f72207f44453e8df95c59dddd2883f23d437ad8b5ed0240a87d676b47ddb4f58e86e3080086b43879c902c5e3a3f2d30c71760674065b14ad2403c256355f8f870d2b5e15de4733193f4a22c1643cf54f3063f7220777b562f16c47c45ef37276b0d3462c14f86229bca5aa0aea4716d60336658338cc1c18787e9ecfb4ba32c171441bda4e76eeac572d26b4681e67d56f5c41c03e13ff259cedb8fae016f396f48806f7a152a2c2c433ca4a783fdca5293a16b5202bf51f3dd185a25c7ca05bfcf15c87fe839f264334297d5738a2a27cb776a49e442a93dd7cb7b569a05f9d230c2e7609ee43dee8528ad27a0735dd8ea8f72627a14d87497b55d82b27f4e7addea69bd9fd01b089aab6d0807378339d835e92383653ab9424a4f2f3e1a4ddd781375dacc922f18509a520e1c36fd3fbfc123e34da2bd0b320ce96ce943969477bdf58be7be0fbca6f7a99fc2ebcedf5293d856473478c495c252b328935030e57777df7a0a9ac3c2d23ca57b3b25e8a6252af41f62222956bafaf955680c8cb0d3c5ff9245cf80fb427f53d2091dc2e7aa3786a389c9f4f0c8a237e3b54e2db6b8d6a8f83cc49da0a8fc3e461597cb1755f1cce55e945cacb8029f9d40c3281bbec6562861ffb3f969847a098c34773cd8fc595d51a813ccd80d1751b223df1135d0e261d960fe21f4fd7e583b4e1a5537524587cac2af22ba9c2ca58ce4fa10064b8224d2ab5c1451e5e8d2289ccae0b35ba0ae86b06440c94d002f8642ad53e420bb0db13b92a990a3ce204fab3cded8a43392c8b927157e00869bec560ea0f144733b07a527cf84782cc5c269d4d7b951a382317f68123749c451011926ddb59484a63e1fbd4c524a64cd0bc32e2745b8da8cb841e0543d06a55c982b1e368fc76d7848ef064c9bd31bed289bd7a17e5b8261532459f6741e70ddd2eee73fddb3387be952e1091c3e57e569ab4eadc0f9a8dbf82acc6e18fff0027aadc0466aa97bb47cfeb999f7838c12aedf00092082d3cd09b4d5ae393e8a1eed0a70e5785a37eed54770af71ecd301b8496a08a28ac34117b6d96b261c1d0c1d1b1e0d3df9759158539f1e0f80d48900509d14f7f20318694443ddce347717ab889390f64fe72c52c551b24cb637150a80e0c3cff0c6936d7d2ae361a78f5897bebf7843693efe8250ac2811bdc01a3f7e0c401dc3eb0e40ada0d860f1e30025c10fe4e4a3e00161ca4817dffe1a587b6c5b8e927024bab688d1293345f98d573e9d1f07386f668ad780886e69ed31c6adddc6f662e895c1da6f5a643f276c796c19150ce8b0c91cc6e14955e87212bf47e1a3b1f773b165191b2e81c014fe173a5306c51494839d778759f50af547585709c52aba4466194a8dcbeff0c313c11df339767f404064538c528ec018d23a69c29e200edcd5f29a21ff6e17cd3b5af96f661f683a80fa87853a2ac85334495f6d8d04ac0a56f4384efca5f31242eb4548be6200ae1dd21369f108557e48b28a785b95bdb376ea3bd8c2a4a083127e849897d21df4b64405bdcf717d54eb089c9207148e94d5fe46b537b946c958c32e81992f145e53a0ee82c9604732bcf46e073e58b1e108c6f0e61ef6c62e2600ea64872ce2f1a04615c6bca8a97d7434a1b01310cd4d07e6cd3bfe8e4e6376f42d06da042c086265aff8403b8fa5118ea25595bd7d4de268a1522567232a96b2057514833ce0c7f7b55f228d200556f13957405a2d3cbde9ccc4d54e26d72120942d97e6324c1ab168a48e27f2cd6a06e895802bafae8b434c45a1de558413bef76fd24bc0e72f193f55744b1036b6d1c679a8292b37ea8db87b11a63f6ee9805482a5a3a4402655e684afb7b3c0222dd272a1d50bc6cec333ffa412d60d7a4d9a11c8af4e34d1f1cc52e69ea13679e2cbf2a20c1e8ea74e8676c9e33e44794b956a9ac255af74c1c7c277b45fac9fd20df76ba7e3a34de6bac48399afd2d3c9007fa1c1b989ef882a5c51ab225b0c1894a9f484c87ab3c4bc64ca0bf3cfe857072728bf4a813c5c3d9414cddb23c360b45982ddd95ad871382323c8bcf29a330c92eee9238a1628a0b4ee4029f59b6300b285d7dd1a2eae823f2edd5966aed78a2a12b2cb0dd2f0b51df8b20c4506d81e5219133a90b85bd82bfa3544317c0854ce3dd5a1e49b769025f33da70f5d9240e10557aea5c0d5ab0a6fb46ff4c0b92316db35391a202e0d8c52b3d256056b09ad58437ba68cfa74ce6ba14672716f45f913039a4e459a2602aa7a84ad7d4740741408fd6095b6ee775d09af8624c85540eedafa9ed6964ebca2370107b95bac46668aab1d32ea1c2999aaaac74596ef8844d36d53f2005dbb2c77d9efcd4c012c1918d7d7fffd4b7686198cb21426624608d368ba63e6f5db9522169c217f0dc8266554f12b2e254ff068885802a2a6a76ea962420527cea2689829d5ea62132277b67dd65507b682286ed88ea70de9c5540e96bbd3c5187f4f3bfcd9f7ce8128fcd532d2c6f7bd01ea525f90643250663bc2be2175f08c591417489aac787c745544caef68eb6831b9a6580a09435802e5878474bc55eb8194b16a364f2267c3b26c670b500c167d19c03fdb788c93229698d1b401b281e7b0f9dcbc45715cc8e07a81805ca930c2008c434be041ec82e42156d00340a6f1ea5ccb24f02261bdc83da0663d10f12cbd5e7fac0a0a471bafa90f5266231c63f43875b2a6ae66c749deefcbeccf16f6b6390deb4758e37d5fd94b6b79f11224d52098ead428d2ef51e8d0a7b450a31569663d93b835f2be82bccb725695c5677fe94417dd2f866429d9524a845b7bc6bb2f92411e67ec654a8fc147f61c6afe740941e3b409284dbd9b84c56948619b099241f648517684efe8984547b6c01daf4a7628dbb5d4fa5da71973aa543174a0ee7a9ae374a01d2483c7d3ca96017c7529854074f9ebfade96188fe73121daf4fd15d2dad09876762b8dcb498b8869fbe6e4bafab7a1cf75ca025beabd86b12ec7ee16185a52443b6f7dce0cee0f38f107798dbc8db7d27a42e250241040a72ee27f06894c8542743f8fe3bf43e282d6dbe30c32c134ef72b12ff415cdf64d289a4d8ba77c9163d9acf0bb513083cfad19a50acf8a4c3ef19e20e4f38c27d5a084fcc42ef4a4febe3f6fa221c2c7dbaba0288733b5ccfe68dfc41af00c6303b345b3462ac82da34d7380bb84a23e6a0b741d0ff0eb09c2bd7dfbad722b209cb5ecbeb18cd76cb3b1e296c0553fdd34d1352d15b7dfde4e2774304a74cc039ce513aabbee990d84f8ab56d72959e30967d2162e0caf400c33779851742874268ab0de2c400facf0ce1d960cfa067662de8d53b12103185f2be47b7846aaf17be25e8a10bf87d52f5e5b2073e2d791447bcc702ca237fb6744595410ca06a14d198362aab4f4ab3af7a016689b52f3ef6303f8c15587e1af0358db37fed8a053acbeb3936e388280598721538a99759fd4febaeb82f40b75ea098c1fa7435aa5b7ffcfd2fbeb4290afd1b658c25bed29e861c0c624bbd2928967e56da9d9cd2e2f1c49e8d41dc92c53b9916b0214cf72d210c0903e4f2a0e0747bb07fca13d5768fa0c0026a028cb34652aa2ef3475f766915aeed5025beb7c396ce08413f92331b5876a83bae89cbb3ec54c4dc8d34b3b0fd7fb8dbecf26f500fd6584e42f90af7fb0f2716f0f433225905cb7fe793ae30c7428c0cecb5f2f6c81ee16f8e78c64fe20263b2ff805bfd9535980958a4436202e0d0f33e17886c0c132a62a756284453c2d8faae256c7c702812924ac6707d9ac481da59197ed5d428bea5dac335b018ddc2a48a53263bc90605e1b0cf5c6c21251eb65c9d71df73cea1f90afa0fdbf919ba6a0cb9dc2a29b302525c8c412d7c76a873da60e2018b70d82f1863d05f0c47cc1cb49c0af768955b5af5fd51c628724d85f99cadcc96e826aa6da1acab186f679679e6545f07bcbd5621b80a2ccae5884668261448b6b013dfb10f249dbc057475fa56cc5f99e62c00d19a3d302a7af3c3970fc844d1aae091cc7c059936b5e7cfbb394da2260dc958c9789a55f30c40d9b948c3337204934a9401ed8369d576eff9db5424e34ced70b095a0ad667e6cc20b22462ed0b4c4674afbaeeead33af15350bca402379f9df3017362dba89cfdf64f4920bdf79117b65fbc46ae05bdda0da7541df7c7a5316c0329e733294117f856c0154f90247afe5ca5ab567f08d8b6c2d3b569b02853519faf86bb90fe85defc590574b62bd4c0d703066246b95ce90843b3080071d19d2b78ea14996e6a82967ccc063d17f3f8111552e7dc50ac2297bf0c89d37702116ce85097ce9963d2ec74381b9aec5a84befc930f0e3df6c9e9b15f54d9a194a44c6f1a455b9180202aaa53096193ac7d4bd446f3706db7b7497caea6a4ed06ccbdef314e9489e7301e7787582b3db9c2eecaa0cb9c583017eeeeba29caa8becc207eb491eb336ca412fccd77b494b483ce9e220820181b0d26eb55f5c1426eeaf27f38511741012bc73b10677a5a18d395f1290444f361dd7e58224282ddbd9ca614dfe3afede0fe706135608005bc06a87490c75cd5a6f6c8704dae5b630093aaf2a05c6fb78d03013bdc2feaa2ee02c64cc8c83ab0857c20cd039d3b0738f100a1d37feac4cbffff9dda048e45b8ed366ae14fcf4198817903d8a6d0dbd720d6e761ff4bdc7e96d94e16f29d3fb174b8ce6dc4d6099ae06c439f8ce71ce02d752df39c6908aebe6dfb830db655f21745f23deb6803590cd8fea12eaa25dd03cf90601812c352862792b5fb25f944f5eabf465959d48f081fc1eb3614ab4254a320370b5141283408e2be4c892fd2728e22fe20562618672b7ab3d0cc072b72c4732eea2ecb88e03cb4ee46e89272c1d6d49c6a55c9baeee6ee9461c708334f4c729cb5ebdafa5df2d548da4caeffabe9b31cdbff1bc7beff7225efa458c6f44512bd05bb20544145c96118edc88c7d6ca30882c677c098f7128950714eedffa06ac9c5b02a93450fb2e4f10a5086a85b53cbe1648e6bcf28b29b6b4e5d2d816c345723bb2996ffbd1c7484d1f7884658ecc9456021ddeda57b471378f5d9643011f5f4baafa2f2335bcd3a28994555fc3d86d2a363ac5325aadecf3b4a9e68b487ad2ecd8ca18442f2cccf276f10f7b8344781e9ea4505627934dc6a7063b56314d5a67eb41349fbd761cd1c80e346000412f9443fb0bdc175f9320f2f1c54d30fe820bdf4c2552b712282830ddddf17ee06ab7201f63f17fc398aef0ea2999d36a283053243eae57a4eb54c5aa085e7d5778ed9c167c6d22a1828d6cd70452006ec0ff78dcbafd0e183de49627be27d41aed7dbf7a7a7e2bdc6d575ff2bd0af59e12c7e43ab40876e697acca63f7922cbd6b4164a6bd28bba1cc110ed0d8a0c210afe3dea7e32c74f7a9a04ec29f0c47220baf9c4b7098a85afd414d032008d99b8d9c7801db4d84d318ab23514e758fff6d87226b96688a8117d21e78f53e18a89421b43b0523f01778f32c21cd5ab5721a95bf549228692ff051f1152237d5fbd9377c2f6ccb713a2982008bde37fa3b6dd3c040e730a2a8c267a7f72e71c15e5fb4e4d54bcedff39d0d5b1c25a5af6b6071dc0833d47807b60cfa0d2e0f6c77b16501aca66772b9f2deb3b3319f17a78bd58c661c8eb211f3e2b18d0e17cc35f12ea116364e22f942e417abb9d970152c1046d002ef0e1cc9bed13fc0c15677b3540482b9b5b29782db1c603e70f87d66541c21e0b572e77b0f6bd6b79d3d296d913217c913214743152e0f567ef718beb04b0be4b801036b78bae7107c0794d183e6af4fc711e1cf627713eb743b0bb43a1efda6b4045704bc2f050ff02c17bb0b327cafd7ddad492760f46e6149d193025bc1d6e08fcafabaf102a3d010286c6d802ef1ae02aee065d038e84dd085f94696542f60975cb83caa99f0bc69e6524e33471698419120d4ef3649e257960f9a2d19781a9f2389a646191cc812dd6636ee99d534adddc669cdd4b5bf2aa283aaa3f1353ef6d73ea5c510f363a515127a4dddc72e51a13e9794e2841187307378ba5b58e0308470ba052081e6a297abca1f51770dcfe0c639fe42bbbd612ab55d6d605acd20085b68e5f896eb5894c8136720fd8bd0e4f5c3d7305a9192f8d7cd7551ca98801301429a6104be5c1334d1cb64618022f3e65c8bc61fc7cc7cf21ee92f36b64f67038a915ef4d4c0bd0c7c1ca723257dcf3da2a40bc27f01e75a756d54378e973971df7acf5d3217f5a5a8e725fa4ffd5e058dee79fe07cbf94d9d4e3f0b805663650eed025faf72f3620aea6267a8d6fbb2888c2eab96a08019767506843a1db1532da7fa8932db41b534a9122af8926714feed9d72f812bda264c371a071fcfe0240a63849f25f185600ff4a28de4b6d6751e30c6f4a5b42d49e3806eb12445cfb37858c6e558b14f1a111679cdf9ca3e1dd74a20607f3eae8adfd88618cfb66f9725ac18776074c314b3b080cbec8950521b8596aa56deb295e2f7d19a8454a1cd4f55b415fa5a2e7465afce1ce2916b5b53654585f1e1e531f8aa4c57bb073a5fae6d78c9a5fda62ad868a88bc49f58b0bc205bd5b177996e3f060d05bf906943dfb1955c3055394be9eb33996c5490ddc9a269ed1015134d095094878051a2166a2a6fb74422d16c03e2ab21810fa66ee594053784ffc585029d31e0b8e00da1f8b260bcc48160a0591ae97bd8fb27ee08f759e053653fdb1a886609e92aaa07e21848f87c27dbd6b81bd3bf41840ef7a1bbf3e809ae5795c5f114a4a1d3e9df19d403a53777022f28bde8a8f233d85ba8570877c4c4302035384f5806411223ab67927f9c3c0e46b697b4c5754cf45624004170d02f30b88efe0ffef9df3141fb19904fc8356342cf20eac764dde09f184689a8688407801e8a201812c8880ec238ace09be3b0692ac909ef42c48390b1fb3881c01637eeccc400b9d747b89bc6c8fc2d7f65823a07547a610638e85b4285874825214e2f4ae8d8ac0df6ef602c714e80f842dc9d2cdbe8161e592f0f036d42e06de1acf2ff42fe6d9753a821f034e67405822dc883a0571b774cfb5d51cd376d860065bf40cfc76d00f9413938014f696738a6f737ef512731784f2b197ed6ed905acb319b717cd7efceff253d17f25d5a29c2e95eb4a14f6af3c1540cfdb7b01ee066e42abef1a06bd3a303b1a404c871a71c67f61ea200302797c4fc8311da59a53a5d130f55f95243298d639cb4685ec9018c2bd50f032b806e80fdb405db6d259f908b25d6409afee467c2d1918aa771b4f69f583bd8dc2ab49a06f0173b7183c657ed6e407a6ee86778bdc1bcb9c6626e954e12133ce90ac77ffdba01091a4441542ef6176ab804188125f7a019c77bd5aa42d404893058a69cc0a5679d46196360ace1b62213120ca32f6734a964784a70a5618dfa107f380caa6580cba0f38c633c24916bb06d53255c12db9f4882983b5aeccef7ff395be8e3584304b89276423c3b9d47a3fe0f52bb02720572d0f72e12da95a781ff4f7d7148d681c800536a800b423112b1e3c10bbc37dcb44ea8b69763e09e61f05058b2f79e4e4e410feeadb14abede0aff0c0a1e0455d764d6d7c2d97d6632a867a024cc8959df434a49a6cb94012ba984d1a736c73bbb8a176509d66c428139b21e11ee3c38cea80f10d9901a27724e872a61be5a2f2df6b54fa857f0b157e72eba49d40741d60eda0ee2830545ffff1272b80f6796683607763008efe99bd51ecf84ed6772d9e944bb51b09bf9af807fbe1b3de4525f5c2e3fb69fc0dc92738837a49342871343c2f12d40897aa38ee10711b151fe852bbf4829fd1405ceafc46714eda454f518468cd48cc5493b2a8b377c80526ec441e01c2b319ba32e458825e9ff7272ed024d78beb1305f193c387933e18d48a3d912bfe3756df8e33b4f82c6bcd3a4b50a9269c4a0fbbdca21e186a4cd990a31fe860b3023a98e313c77276c025d840a26631eb70d602850011f0e2d904f4218a2f0d1f3097056a9d80439af5b4ca11891dc9a7b3757462ca61ae62a9e1823920c57a614232be4b63af9e6e34767958f9db4c4eb4bcaced3a1667d9ad4b47e2914b1645b79ec0248af9f14b08dea6207d28dbf4b5a290cebaec78d91956d21d6fc210062bb0ae91a86bb34c5a5f7b270626e45c7e0075f96d95b718f09210133be6ff80a7af7866829eaee072142847073ca93603b1d238980c2147396e0e788faef60148e348e2e6ee285b1708e4beb164d396644b12e83432af886a2aa50f958da8a8ca6d881a31f7aa24386392479c2df20b54598d6c6c9c48e82b35b10577ce7610ef909ecd5ddfc852fb68a8e7b19ac570a8c20138764bd9134d21c0d394cfc2ee10df2d06999c74b21829efd5f1d89eb25d19c090f691fce64c638a37d8205d061137744c22b162ed736b9ee84ac30a447e2077a9893f510a04bc13bd8242c5f8edbc14c6f1ddf2673029825ea34677fb7bd9fd590308b47b93782bc0fa21d5285ec8329f7069dd303fc47e2618afb0d0fbb05e028f4dc497229556c68a3a550e3aa7c1b8c4f914bce645054cf654f68ea7dd26f2e26f506c453dc501063ff606d418fcbe8afa74659c04b2687b0dc95df9db078968bc73276afd14f5c8005f9ca69ae837fe8de66bcdc5a34898c380baa1dd9b00067e8a7961c8887ec2250fc7080006224fd8f13ebe2b8ced29cf1d7629ae110418a28d416034c21001c3e900dbbfe8ef1228dd7e1c50a4f745609d7ba4dc48318b5d61aa0c6435dc0e28502f4894cdf5140254158ce873174b9b799aec33f956fb00951927569e98d0ffbf75ee0545fe081122f1ac0afd5a2a13ee8a64938a2c829b8a32e60af972d2d2011a6c89463e9d9f13c165d39b4670c4b74195a94487e393a508fe1a4d17ec1f4dc4d8b225024a3b91c9c4b249873510b69a0087bbbffd83f3c1bf7ee3dc6c5d96465127ff0d6408926f072f86e7bf13d16b6dd9586a7f6c0de0c48596a5585f4b497421fc1f4175490980b5d9ff24a2c96e731de534353e4a40496384c6dfd02a33b7088a285feb539667641058254cf1d1afde1edfc0147d6e1719a20862d04535438f47fcb15066a815a6d54c04148bbb099dbf7e91c43e753a09841981503ae6f56c5413b38f5a3529e6fc101d0660cb8aa53dbeb1921c10f02d3f7409e165d7a2b445736a490e90696e28ba7246c025194c891bf2f7696a2e65a96504ba5fcca34d633836873c47272787be5c7b9e4f0c461dc78d1d7963ea138aa6b58dd47702262465bf09c93b4c7a0f8c2b56d5e7e92ab304045d2e0b08dfa643efebfeb1939831d4253285e79e5ead6133ef13eeb4ced5092c68fbfe1219314ebc644c9eccbb05e5066d956fb4611fbcd55161280243848b6a07492737a058e947025cd80b9e215bad3b233252b1e6303f53d4952c415b4884bde0c9be23bfad91d8f95c783ee0cab31745a1206dac418d1c0212a4244b2268bd5f31567818681805a627b90fa8a326b84adecd56e7dd7c58e2d38a9391d69c0797d66809ddc1d886ab9e380c8c6310c3f3031b4a79edd2fcf33f3133025ca00cdd738433bebb8e6797087fcbd636d0b33d8de52dc3da5e02fbe28e56539ee298ca8fd2fa61d1f9c4455da7a58c19a4fca421a56a767bff696b6e9ffd52dcebe61d569306428cb276efa8978cac0c68204aaa9651678405a3df1334bb0599d36e90c0c604190420443a0621828c4120d56472a90e466b430c424d1c06f16096c10489602d10e74b8f261107f78865b3f4b57e142570e50dd84f0cae4745d9bb6448a54ec902063a7d0f8341ded76afcc2eef148e302fd5dc3c973790eb124913b3990ed3c41508498f076cb4c429b3105d60cb70ab51428562830ce711e158077507444e2e97e24112132e12502ddc38eb2e63534cb80d9e79e6b4916e951caabacaefef34ab35afd9dc4fb31be44aff96691c1f4853bdcc070caf32a8fa276c4237b425d3698801645572e54aa1794d40f5fff51c4fadcad802d7fa98537bc7bd70ca5719877f0da2d0aae6c180a1e8c51cbcfb50fa1b4b6b4fbea496b4ba6f7c38818305e4a3a36cf3804d2bc03e72050d21e97c7eb1b63b696f6f10ecbfe5b8026756020a4c562f140ffe1435b121e05410220cf40382bc961780bc26e0f77f3b1c3550a98c227020bbd88cc3947b466b05878512dea4e72ca5a7741ec5e01b25f7295ee7bf7f75002695fe4ca51ba46568456ba9d2f049c1469e1702974544bfc9ae17e5dd99025fbe1ae41df42b3a4ef188f92b7ab0d9c40966e82f18c19eecac1db10658cef7c5dc0b91840ec09c365be304560b3c24cd824064c63d0282ec14919f235bb08f1d108d2eccee3c52866773d6cc826bcf4dc504b8add4c5589881ce7360ead8624f28d3861eaef75ff2fdccff4b22d90a6ec3f015dfa89295c9e3f1e73ace6e4e74ea2297307d21034803a91aff3c40c3381683b3aca38e9ed5f6a95b18ae251d2eb4ee83b68bedfeb48d11751a90bd4a3e135be1befe2482b1771817666f8c831816c053ce1e3bdf5753b6aa988f9dd38f03550d98f9c3cf4a2b6a98062a8980dbaace5852cbb3d9a179f8455828054fc70be800c2b399786dd6a884cd30dab3cc47303aa17b7ce2de035e50efb4a259337cb65e7b13554b17aa79c1a85e68b72c07f68948de7691aa0dd9860b77549f0be4d6993c0b79d32660546c6e0a8aa66f3178b019ab6a2b43ce6bf814c787208c8aece05327afd32d459559132d9905fe3422bd1b6b20b9ce3ef2609634e710b1ae17917efdfbda36d5796988ad9e1071403037bf99adc24a6f03e76dba4a9416c0c9b1522ec7c11730c385155618f8f8c35f58a5e1d92656aa78f04a728d7ab3a8189048bd5b0b3be446575a24f456aead8b61a4352a0102dc91c73d067610ce77fe29f027c694ba6916b50029834621b6572e33d016fc4795521d1bb3ab8c8f5c298331b347a657d0e31f7b87e95bf664742b071066d0b31d6e2a8830347c85fa9f33dfbc99130255405a482e8a4b7ae2d5050b1cc0e9c89f87357e4457076c9198b41ac23eacceee1339d958657650f3149155ea454ff8a8b7b3e141d1f47536e1c11d4c19fc6d243537c8390ca343656503e6f0e12d85800db0ba54eba7b924d676815de0034a4dd0e7d4bf0bd556de52f6002b158af03962b79d0c6acb6e743dcf0f44fad276d8aa1825ef2ff2ea447f0839a3b1e6aff3bd8353babf216b00a4ceb31df304ff70dce559b1e177a4741cab524a5c100fe2caa389f7c09ca40aebcbacca783b4f5c959b783e1afd6c61c8d12b00c2be075131c9d7a8e570e98fd310c84387f6cb63fc836c87c5518c88bc95c904c5664fd24e26912d04a2570336f63720420b714fe1e6b4441d62d92d052037185b663e162327c9a7eb2c724c70c7dc4a743277ed610f146bff21a35de9fcba326bca7feead40545282ebe8ddec0098968d42dc4966985d675fd6f97f6604a177c17c5c42914202525546f0889bcaddcc53624c96525186a05ab1fc024f523bc9a3ea7db2524f187e25be2d0c42f1df661a07953a920cf13b703775117e296795b1e2f0cf14b149af11029a11ad0322b53abc1fab9d136de334ae4c21c5c7f0337386e77cbb4515d32044ad3e6e019807e6037fe5bab66cb1a559e00740998c35946952bc2e6be298b16140c3f86442c497b543272392facc47e63dc854dfd2495178585f7946a2a145647adbde7471cec7b5552d3afccc3b4651de768c41a6bd63bad2013dd3862ff57f4748f53104bdcfaf575f5fdd29c6cf41075644b95c3e9c7194b185ad565a577f7617c69c666b5d742833987a0405d0b4cdc96f4578debc9b49d36b48383f68afef74c3b5552a157d0431d6938b2065e57285943a1c54acadd5fab1b621d73d8e2d237decaf9efa53a03448db2d74075bff7ab86f808e019a1d02c8ac3380e2637e3265851670118efc911acd27c4ce751e47ed54ab7061ac7547c17d361a036034d9dff1e417ce5a3b40a5b14cab1df08101d4c27b89f70e3e087473f8372390351d2eb7842e1b80cc496982ee5751e2de9b355d22a79142e424507fe0080890eba9810d8737b52078d66f97839078fc0f8fc8d4fa2dbeae85ecf55f6496faeb2f3e2b6d401640b9f16f907122f3011d54c4d6d9dbdee86461ec218516d3971f513b35c88d38cde5478011772255f00f8f9a0fafccbd8030b35a5d8841ae25ac1a77bc7c522ba5ce63eec2de62ea2cf277ace9c13c6eeb1297da9e205e1a5b527d4c6e6e1824040e007486041b7d5220109b6e6de7ec36b5f2b74544cf1125ea05a3e49477d75b29683c8cf7f4ed5cb129f9d3eab59afd7f3f5782a5220540fad1e7092682724e9aaae5f54934353527c1cce154d61f9f17f1981e8020955a0adc89ce81cb07797a784183c5bb9c7c796cf2c1febb64c01aaefa593a47ea4b4384e77d6c60f0977baebefc8725f0208f5fc18739a67488ba2d1809cb96e4ebf5a00980690d41dbac14ac3734d784348a636cf40b3b58a87e7708ac115268c2fd9e10a01eaace952cf92d870b55be5ce12d09a30f7cc95324a1426d321e4e2c4fb89440c5a3b12e4643fa852c63a3eba5eb5f8838a9a3cdbdaf39540b89aa4c6f658bff106d69ed0d3dc523fa63d8c976c526be525ef26f28d3810e689504a5bab584b31f9fbfdd183ed7b208dc9606739c715d6a205be7478f1c798818f3ae64e17455b3c2bd06bbeda25bfaeaf6233e85091cc571baf5d547828f34b9c5bf4963e0200a8b71c2cf09bee16edb124582e08300484c647a75c626ba4b84f65e654fd6b5e0eba68238445ccf0381f715b14d672c911bafbc57697a49a94f318b860e05c52e5c6ccfc5753a64f39538d9ae67bca80899645db2e1fb75a1889c1e90c75170c617ff50615b61d6384895a563811ccd944db59eced5d1b40858509eefff2fdd28644816c10a760e7be2663af8296904ef597e84caec967d8b29f02d01c10e64d0bd9b5b9c048792e1102ef3afa4a4644768d640f3306ea3eb4873b8cfe8528546eb2d213f287a50004c38ccff229515f8b30411b4892afd3c8e88fe3faaaaea393ca03ba89014e0450625279a3c4205f02727cd2d3926539a2da4f1dfd7a1b85be91fd4935db37889fded0cf45338162fab6ec7fcfc7d0576bb6487afa92e9d47290b505ff74a59c143d3d625b16a2c74c4efcb70bd04aafa760677bd30cc5610c6ecf403a4197a9d6feef614f123164006e41e3c2391b2c9f649e66e45fb6dc04326b1c09adf98d94e11ad0de02ce1738f15698be6d134495d0117c03c7e10ee81f5cd6e7af3d709fe2c3b0563a0a141ac7347887b69b0bfb788110e482cc8c1a5de69356d2bff7d2be65f2cb0c645ea7f1423dd719efc592964e8d08fde91620b835247fd97e1bbf550147ec4d113ced272d124784d637fe898b330648e0acdb891f31b671070d5e8970bc7f3f3960d55405570c256bfbc9e483e5cba8e268ee2419388e89a37a87544650fd6b128fb994e300f73d262349a44bebbdc62be4965a563b0a97f2e0a8214262aa97724fdc1928f12acb0c073f523d3de60cdf3013802196a8c377d8fe3ab043c790828a97da7c020b37108e3305aaa7633958598274fbb0d826adfd691b3b34c8d52b6a52e47dac2d4159800e07bef3f5ee0d9ff9d03be54b27c549edff2d2a1b70ef8cc343ff837c8a81e17abad21a62896797d6d2ab42abad0d8f9e5417a18144aa12917b03b7438a3834a255b94d4c0793118830469577b7fd9f06041d5f879e793698d69bf995ce868940715ad5ff9e2c397913cb307d83a0caa923396249b930263ddde1f38ba5bedf9dd1f0044f6e7560ac0bb91838e1bca1042b46c24e47017d5282919f73bb25205e1c36f1d4202120a3c16234eb934c15d706a9f81f3337ad0aae4f54055bf59ae95bbe63467c6c372adb7bc2819e6933cf918a18705b9bfafae4495470d0091557de2a0d4b32e164fd5d2349152cebfc68d5b92897e4649e178b5b70a48f0caf0b87beaf93a30003654f79d458fd91079d2901e1d85f1c38d8828133b990e08c8b1db8043f9d08906230b006ad02b9e276853416b641a7f1c137a96e7740e58e8909c7e01b4ead50289f7fe216cd50b08bb70d907d4ad9c24f795522142f71f8a65f64d667ab14c8c2b9f5396d61de39ef205ff6a4336787b20ad4f44de9c396e7558a67e3fa5c178b566e73d3902a78bacf71e449e1d75c033d7cd75ca8d0c9630bcd223169e8d791a22add4899d35ef7c296595649a47dc5cdb9ade75faff5d8d623b9bda7f0a2202d27d4acee50095abfad87391e22f1512667bbff60fe09fa5207c9ec18f69ba38e67ba622a824fdfa720fb33cc3d72bcffb432e210ef93337d05e338026114b750037f00e54ef335eb33b1923803774a1a72cd0a943d1386613aa1e6e1a76ea33d7fc29554e5cf47393cbc4f67078e131360a222847cb47d12191127a6ddc67466e328bf1f63817f2822997ae11e8ab452b4fd8be3bb8d3da286142b488555ea6f679c8e4db8b6c4c0b885fb866c29cfaf29f51ec5b8dee349cd1ecb62093c478d0018ee6609fa5899a2d9964b47f2f30029bf82febe00a8d82b386365c3efe051ecc3c0a6a0a4077a5b4d5bd3db6f6daee3e6872398735cf7f47a84f7b0ab6a0c61e9705c7147fb8af31f4fa713b848be842fee78ff09850fcc9c9c3e9383153ffe12ee5fe18dcaf2b8e2a88ce92a96cee2d62657a1e5c65e4ec8ccbe8ca94adf150550b19f6261ba4c64236f4c922230912c888ff32e4cab664af2cd1a896fadb882b89a989af46a23aa2235fccd3ae92a90bb4b6b1f2195192589c3579136173b87881f73214528f10a6e54f0db002a6d0860c9bce8a3174c3745f7b6a9cc3a0c56f81f85cd7c968d032ea1042b45b93978ff3a9b76dfae665f705b70103da4271f5e9dfd6a1adac4db31a503e9d7e274668c28731a7f51133356e83fb6b3036d953a2f292a60f97a32874e13ef69566d729404a242185ee0525367b77e3276b98d8fb7c362b5c679c501b9d47be48075dbd6ca10ebe451b1fb9a3917360418a4c390d1c57e5a4b63a286e47b1c4f247942a0a048cf8ba2194c7dd5502213e86e5c948351c1088d694842076dc3e89471cd74ed6ab6330dc70412048370ccf77047058e698d1a8c1c791c53b006c2162e53617e26bec2bde3d4f6f33a1d23f630f787c501fed0036135a1800f87e947a5879f882e406ec022db3d800fca961dda208a7e1bc270fde44de5be784d4cc37e3550e1cd1e44efcedb3a286bfd500b81ceecd9bc1f5812e24f7066b47a62e73e5f5a74e81a9c7851c64320b129f492bc2a9fcb5b151bbb8b09ab42e130753b6f1558359975580417d7594dc59b4b9fdf2b02319b5be494c27a4c4dbb514bd9f98a228242599939f739bca9f4810f67be6b2623c2ae90da8961a4ad57c05099ff1fa8394ed436d13034576ac8151b98f950b8162c3409b8290b2f1f902621ae0c9a84b541e8b9b20999541e6279bc1b72b5794419e4d7ed4652651c68fd52457fce60204e50d1765dd23f4bb4af0f6b8afe41aada4c1161bf29f1213e7463cd1313de82dc0be8726d487d48fc32d05351257d6e0d6348ef7e8c590566b99a40a45599434630b85cc7ce86e218945497d508f224bbc6be1632cb4812000defe0e48117f908de17ee1417fdcdc0b1e3e36a95b116de0f02cd51bfc89ed0476aafcc949d9db0024631be1a9e7bfa966130deb07bab8bc5376c48f04432aa251ea4238ab911265e6c047ec62560e390decf2592cdec48faae6e6e0f0529e5e6a4c7dbedc3f30a221924bb909d4877419899169e0c2df89fb65b1a61a4c42938e2bbaa3bbc62be442f0cfc1be1db1ac3cb0eb99a169b8236c64152761a466733d9051b7442d3d1e784992a747d047ece45619c66c7391ccddc9b561d22a77116b99048098680572a25929194a8dd1a8e52361ad999d178d9cc534f6bb840ba4f13d3ba944f55561ae0b108ac14814d957d159edbc25c4d0103eeffaafd22f4b283c9c40ee4585e65425c6b753e8c4a5442f08046c8f7ae3c5f24373c504faf03d2c7a368b5cc805c3886a32e644ef073564b1dfd52380ce472c2625d7dc687c8f2065d2ef4972d07b057a358fe51cf748be7cd58eae73789e47b2acbe3b0f2e455990b1bb9a4c4b8f4956ebde2900cbb92580b4d8bd4d3cda608b7cae58c7bc37dc61180175b5548c496cbde844c25dc49f71914e1a193e7d8e0000107951de0c7d6556d101133c8da3ab42fe24cbf682b33578b213acde23f380ea9ee061762cc1d99fc281fa07974038078a465855a1b496b64a67de54251df339ac524e656da1d1632021070fc4ce2326ee49fd4003c716ff4c022d3ecf47aa4293b195154205a589585cc2b9a66f37a84888edd83de23afb9833ecd8cb9e8a3bb020fbdb5d1d857e039c3f2c72c43ddcb91415d144d4a550c76a3f69db3bb8e98ffce43c11017d8cbced24757f0ec87669c25c22d78a74b202372f9ae416b99ae0ade8ecc390080d619584254ec45d06a84c9acbf81ed6005290f4584af9177cf6b1379449d289747ecac7d3ab023aa79665c1451d94adbe68236373fe2f02bfceb78d2a196714863d4971cb9a521462cddd28d15eb20a2a67b0dd1a6f2374e605f61b39dea3d3d62881cf4608a1c6406298593bf5355d762f297217220a8fbc0c8a4200a041344d5fad150341403a41d061d7986bcbcacb4111f04c4d474b50d025e43ee7853881dddfbaa02175f68de98ac73786476b30555314cf43cc1abd593d8829404802ea1b2fc23d588ee8cb794d02651d11f13cd01cc5c8c58db5ff0bbb2208d8563a3c376abf52485df1347985b5a7390ea84c506d584c0ee807141ce7f9c6592a69d98ac50873ebb96b5e1892da18e043604377bd1d11e2fdd2a0706fec676a9c4b381a51eab28670d4f7433248c8e906870f15f61f32c22a5ee1f0e18ce4e2582a90ea93bef95b90acb3c17e1275be1e2b419ca69c6e520d367d377dd321bfc97d54ff9e4de643b15833a16b45be4d052c0b83f4e4911c66ab9c2868c06a8d8952ed4ac5ab56ecf2eaf0c3e0be9b933a34ab48612bd90e241a80bee107132cc0e27dcb9c4e1dd941e3f6e312bb6658ceb7690dd020e6c73952eda913b0053c68e71c6448e95ce4a5b93983e918eacc8a93c36bedff3c02a961c9e912154bd6e5a6afdd0502358c070429756db2fe77308f45acd3b5693034b6f692586c2a7eebb56810d8fee5ee41b15d27dc37b15a40257d0ac79ce8175c3c0df3e20f5eb9b65c01c375534da41c409834d62bb50327074f93437c7cd5273fbf6630bcd1dde4d91b686ca9cc500b35180892824e87392652a18ad86de360661a2094e9ca46be9b7aac9cb48577bd69231ba01f88e93425d41119614e9ec4ad9a9ca533ec22542ec02267b8a10d9e19e16bd130b3eda96e87fb07a0a4ccd22224c11da71ead44483e956b02858f57801abe7d9d586b7d4768517c268baf34a840145b4158b870722f86ba8b0c9acd5f7ada7dde0128d9c8993f75e881fb452e107180805ed1585e9339db15ef2a5e931fb0e017918c538b046d89bd5fbf779889e79acf4576a01cb979adccc20f1e342bc1955f0fddd29f093effab8711fbb62611be8097b5d0af723afa79f5ee3f4a6915e18e63e2ab8bf637acc5faf8ad5abc6d37b2b42a864425bfd99abff8ceac2c5ea2395bf014f141a5b250212b9d837c23f5397019fd2f4b59f91d22194815cae9e8d16131b7f67d6a4666e969023e1a057f9b2a8d72e03a43d9f9a7d3441502db528b52581e7e46732c00b643b680675272b2280e00222f88ddc3a8c2be46f128e3ab35b1c806c4507ccee43810005b3d931bbbc84f9db81505e46e34baff61f545ea203148fec2274fdbc50be32a1236844239594f485ffdf7d8eeb5f3faa66334ce684fc2ed8b035b2045f2c3a82578e70e6acaf85674b653ef3cf630cc97f82c5b8187fc2615e4ef008fd4faf6807189add0e782278571644dd714beed88196577968cf7866b821e9dba802a153833511b13cd57f80bac275d200d3592c4cd0fce7ed666776e40365a47d059386e1ad621d31d96c56457ede43c37f70686ca96d6edf44eaf916fa085bfd24bd9e33fc37637d012d07366e68f2329e1dfadd245c37ebe225d0224b73c13fc66c7198aec3ef954ec9c233ade87a6b6ff496283cba1c6f5e168862ac20a46049dafe6ba796afb94262378b8e688da8542519c164ade28c506593ef2157262e37d03ca0227bfc3c0dd6404454cc36c65afd8838ed9014a74cb5d2a5232e9adbf7fabff9b629ebaf3a20fd104c15a45e780d1a852219f45d63bd319b3cfae502d77c35552a619782e08ef1665d9e677f6e3452118baca502a263267f8e4944d7969f550cf1c5d15211584999155187c632027a5c11575f9b57bd6fb2fcef704e8a7bd487f71301f36b776cd1bc0232fd69b8f279053e5d2597b9b1211bf4be56b1acc325411d50a036d2cc6f7042dfc0a4fd06a1fe067f7b572aa20fa8a4340bc4487903f9d25d51440d5b18880a93e7f7d061fd88e412d4dcdcb2440d725fe52870564d7550c7a32693930cf3600b326bef6c1246cc9fdfc5c8d2acd4aba97ae5b45e7dd92b31f56eccde49d5cb2fadb7a16aa5690bed6416e74d550ff34b666584cdf574a8d06489981af8dd93ec07f29cfc8151644054f4072c0e3ae3ec5e106b0ea31c1ae7228eb3e32a8bb7443d9439db6b4e2be55bad49841e880a0d56d111e0874689d5bdf01a67a74c9a9cc91b9a2d42e45cf98a820956a372dcc25134e1b43597dc831861cf5e8fe2abf9d45f52c5bb41121bf04cb6a5c9d94c9d7398cada9fbfa7ca4dacf7bbee85ed1aa01360f1a8a49b8fc6dc93f1fcfc0cd8b7355854f9ae7ec25aaa735ffe051dcf0f043c050b410a7399285ea2bc08bfa51b88ffc562fad0bdde6d404f382a9b11d45e96cc7c216370e1c88b6ea03bb4a773731ef6a5825724d7cd9bdfddffe6b0440026f641430b524450998b55a6489660c45efa62a4149cfffe8c15d995446f7e2bf3882d79996dca2f463dfe56266718846904da117576a4beef7eb2fd5d2b85260c05da9a7088d91c0674274c5c1cf8c25b5bf98974ea5bac58c3c44bf49de5e341fe84e3a26ca91814e18fa1c3323958e0449f9c74e84f144a5b99d39d3909cdbb49ef5e6902e031581d9abbb130c1bb644b922c80b6eee4d293cfe775d12e32464dd0ce5deafbbbbf1bc25733c0c4440937e97701a90b6433f6ce508246e413826e602df4442f1270be77028ba7eeddf8e45e550266c753bc67d3d1b481dbe327dd07f9420ee3910fc0baf5a64b7c3a36c6c6cda8fa3633a63f04ea05a2b988a8617f03fd8477c0e30dae34c4cc81907a782ea82ebcbf09fe8771026fd7e3a4c467075da830f445be16f9491b1d4348f99a9aef17a7bd48a07d48022443d018a011d1ec30be1c1dccda41b7bd3e812d6cec27580ef44fc610942760986006390fd46174fa78bd2fc4d9a173aa149283fed24773b080bac556f9f8ba58b081549b0a3aa3afbbff8f64e5bc276d9c1fc4b532e9e01730b8bb082539e52ae098a8095a3cd56b2bd20d5a104cb1c3a47054708dea49d01cb9e69050397948a4d4097f8d21c83b330da2380d0b847e201722fa25d8ad80054a68010a3b7ae218101f20e02633540d44e15cf0bcd2bc64d37577ab65008ab66c913eb139a3799c0ef291cc0363c3e13aec8bb6823e99a653874a433137902203e767f169ddc9652ed68873c4988c6d646e74c11fd97f0a01661441af8242e6617f9c82771f0f9d5d1006ea689c7c8048004368a8008f1d103527bc11c58f6fdbb07d623f4194a0229d4b8881b2b9b1f35026a5ff81cf38a9616704393dd03acc08b352e304a127a463784d3a9b1108b5234a2775f40dccd30321e2285cf3ec45af81c4c12d89128a29dc399e039361c83caeca8d59646c48b6e556ad360b161025472744c8c56f003fd108b7a076deecc704d3a87abb8e05bafd34218756c6aabd04859438fe39b2728086323879ee302b7bc2b5561cd0bb0ea1fb60a764c250e10e00eec360958d54a08156f15ef9ca826e3a7346141e367e85b6108e06fe04f9f6aed24756e8a21af150ccfba6fbf105c6563c3e0e8693d45363e86aa0b3c8e1a86e73b901e5e20cb9750df1f138085e052a496280205e505a8462b832d292d1586ad1b3aa5ebb63e96d6795cd0808e8ac0c77d3ba0b4fb8b3128b03f09fa85781a298273b4e123569ff037316b3d4dc52610266183b4bf6002813e037f3146e91f728eea025be6333767d514336962a9bd39acd9de2dd81f1e3d6a96084be3bf571cb74f08b347ea2519d6aa62e9dac6b48f4791e5ce2bad92ad31a62569c4c22b326da3efe32f9d99a3f3ea1d8cc02f9dd93bbba5cd69cd98113d0b9c0858e7ab14a2e57eeb7976812d88b94cda544eb5bce7a2d2f36c8c1384d48ff59fc911e958fc7450f0cc9175435e311b1c8605b89e665f2c4aeb58b29876a9d81a8ac17f05b8668a04308a1150d487435bb9ca30ebcf5263c52a5948beab0ffab33d1af7235c5d44229d7f152fc64104694744932aacf38f24baa5ca9931dbfcea9ee46081eaeb18911f12216cc1108bf39963feba1bf5a4642cdfb42960c0e930204c4dbfddde33a7094da81edeb3040a3452a95ddade47e5d9839bffedb4a618429912d0d87256554f5855501513708d01e4e439093913c00c3e4107fd30cd64168ee60a930000c4ac03422cbc42d9feef9f8ade7e8f3d719983e2fabf615a96980ea59b53a54aa005bb94bc08b052108c7a909a39a0891da469539712569161d25c0f4e2a697fd03674a38964e81b88ad87c5a6f02c510407e72b3bc51d17ca43f9d84982da1c958ad34702395df165c56129249dbd6dc9b13bdb6ee03742fcb67f7564ba8168d721b72395de7e08eb5fcff338b4656328bb58ea29145cc7936a3a29b12c9bbcd1e1eb7e4a4bf625cd3e60953ecef2565cc45a9fb57da2bdda949b4dc618dbca9c68b01ffa015f8a4b1dd9ff9c41d304aae511caadffcbb02981a9ca7eea6a1765968dba03b183ba013bb8cf8111e99e7b34a97c8170d1564b21c7da3357ce36b69a27b961892750b09e320a14921525082561208cb81acf0027fecffb4135178f4b34ed580a6a323963bdfa02097d48bd41c0b079468b77f642bee2e37478c5fa581942ad7d0441d30f987114cd935cc16bb6a102bc697ac084e475df8d3efe7ea1701bea1c8404fec5400a7b8d0774e359a6a96b04bb9600a9f1aa2496650e9900a8110fa40eb16bf0168e95901ed02efe60a2bce7204d400dd89ab962aa06325661793e1f93786f022665f1a61d98f72987c0c4e2253164c1d93889549c1d5f0176b5c1e2f2572e65f5fe2d650b4a66c0dfdb3568da7e6147e64418bcbca319fa449fd2a3cec3954c7e5d02de375587b28bab2adedc41c57693c5d3dd115ca68c11ae1dd75c6be7c3de033c450958cc3e5ff48a01d323b4677eaf9e7768885f939a02d09f72023672a2ac74ce85c3efee52ca0a3e3c7b789f00f4fb50a60edac24969df45578b478dab1a1ba3f6ca49c042cc0656873f996d8e6d3e270028f1a18f8e6cc02a8224ff9eeadeef4f15991827cce4a65d12742d241a90c6d9218f734e364861a43676cd695a55cbb43f3944093c34ab68082624457f6a798c4a578f7a88710f89374f58a5faa9f71f479089e39869a01c06d10618be0cb847b4130d889190d10943db467627720d12f240d7b6ca574ee62a4fb1449d31b01c1227e006c2b92b10f015e96b1fe6ecc1adbb518e9cfb4fb9cdc572f0932643272578e2eefa06c3244333c55bb2cfea90a3e05f8e74cff72ac7416eeafe566b025be6cdc509831cd8ac9e2b41e96dc53e26eeaef1079b84b70d6d7b2ca2a2f5bd2c433ffc76e58235aaea751c66215ba43d37cdd3a5e4a939c07ff7fec4a080c5ef2ef5ad11f1a97fdbd1fd9658d8907b18beb803a850de6b8621a09d1e7276fd02b807e9ac9003a12381e349b643996db216de6a002a04309169cf472a0e58184f90e885b5c70b0ca060f6b7c5be275dec9681c264ae44a955c78220ac80dda01bef77267d1977902d2b5f4a51df9a6e18451cacb729c58364af27a68e54a5319ab37a7515e2dabecbef05cfaff817da925033cf9027a3d5e7a5510302b491d9f29de4e3c91d24bcd10d669b4bb1d35451904ca90b251995bd26345ce52a787a52012dea6ce3ecc3df84bd8705adccd4daeda545cf2f19f01740c4d11516d0bb12f3cf88d1284ec265beebda54c520667076a07e40736db3155b280e1e2a404509868d65a6bed5b2bb6b5d65a6badcf4ac95ed74ae9560cf659b2d9270d351fd03168b098c1b245161bb260d1e46493a2504d5e40fd20460b94eddf5a29798f4d1d552dcaf74a18db7e8f0f273498d0c1639f3ab697c9554cb0fd61454059d162fb15273ff26143951a766c1f4f7c3041f91467bb7f2d22ef123e6cd931d0d612ae4fb1a6c897550915079c5c9f01745c29f94502956ea562dbbff6452f3d78c960fb87f8f542434406692f8bfd7a790c4f0f36223d3370a49e68352558287163c41058887441f3275bc24885cd12f29543a6345c793932dbdcf66d9a2258b47c95f95539c8e5b0f10ff92c8d32152a90cc20485acf640a3505cca6504c4cfb24c3ecfa439b424dc191bc5de9cfa8912acacafedeed0f13ca2f1c45874a6a04f2ec0f6a847554569f46592b9a27ac06c102c67da647792c0354f6755db1eff7702b2318915dbcbc50bbcfdf7894c7ea73c0cb1ff520cf1ae121a8acfe114f4af4763513b52bcf1a51dad3ee45611d25c2c13a7955536e54d990362fa24a98482b3c34e548dcaeaa2932b72bd9b42ba9dbf56f4e49134ee764a7036f87a7283d292e85af0818e6e745a74867d7af58882dc418c5098cd03e6b0e4dee4d9c2e769db2cf4a67d76a67e7fcf9c729950deba2767d918e178953e29438254e8953d8866f18274ee15cddd51c1866d663c6235f550b77204f879f3658c48b4e9009bc8138f076abb85d41a65dc1dcae3750274596925a5969aa7044a6b4f25568a3fa93fa50285f6506fd503df9a33483bc468bf228bccb5923bcb33a58c6baf779ce1a515a936e87755656eb8320c8039fa2b800c36f078ae4af01e799413108d18122d9d7400b34cebe3f9b6d5f33a8da8ac4d9ae699c6d73725372c3e19c9c5589170555268f49c13a1e7ec23abc237f08920a9d36b7c3cf9b5a6a149a42a4c77c42ed3b2bf32d66fe47fe1fb317d0c9e73f9414a75df5fd20f23531b596084985285dd5a7bbb6a4450e0d581839c112123457531e243e2f98f4bed0e867d82c08b0d6ff4a8be8d70aee1eee827f0cfe2bb0b082175133887acc57a048aaedcf0245b239b7a6e286906c1fa2640c0d5199bb8f1b74cda64dd0d388c7f58161a3e0762829554a934a97c6ced33ee9542d62e990179df98d8f51b6f3e0420cfe2bb0c0002fa29f83d224310768512412e87e014689eeb7de6aba718d56c2d7f4e9b8badb5ebf92b5147510109386e6094e034d6a7dcc42dea7423a00ad5dc1b72ce820d0fc81adcc9fc829b7604ec0637fd2383f1cdc6d7ebd1c26ded2aeec380896ee0198619f23d818d308c7918e40437693c67b2cbfc81246c363301ae05dd1c2bf18936359cbb2a4200bd71bf47bb86ba118092459ce74b0663a4020d6e9c26ac562f5f4c0dc75adbbaa6bc562b17a687ef5ac48e8d9b82787ae5badd2dd2fe8ee35a7edb56a6bba5c0f29d9d76b753df6f3b30272b5803210101009040404a402021a31109018028140d70239105005a239586707b66cbb797e8075047c1f00455ab1fee7e9a7b082359a919f7e0b2ec4608d5ef5cfbcc0819a07bf00034ca7d3d1ea35c9f5f4ef7d922449505332fb8c192328f4694bedd3fab6ff8c2723133bb6809a96d93e5790633ab0026a2a269b209fd9faaccca560fa74a92576ab867c6657096aaa04084ca0a63c28f9ccb90c35ab3e3e3a7a91ae5d0d61bd9c61d67f4dd03314a9c7eff8f214dbd7ec9d612b5df78c7255778e6d3f49cc9ded389e42dd0a75ee5991e03b34b5ef4a5650867a155486ba24c7950565a855a11e55e34adc853ae4814119ea3b83c53288a2330c7864c063f77ca741096a1ebb957b582e16a843d8b35992967c66105eafd74b0b50efa892a483791d1c432a520d4b6cb0daa554cce73f1683e9ea6450fb01920f36a5327a343bda3b9e80dae8a10075d18c263cd8af577e911694a0d6b14bd3469ddaa795b2ba7ac3bb38013d5959cfb2f15894f511b1fd61da7f5a6c51bbf0d85453ec61b032f9d228436d6d94a1760a70c46c94a0c6b15d678da8b5bb12d41d6c7f22bfdaf22f87bada5aa5a4ced96c23dd78bd5e2f1b69cc12d41cfc800135d17e8dda7eeb0b7ac32f2b04f510a801b0a36ccfca1c0683c1f6181994a0de20870fa096c1b251977c665919ea2cb07f69fbc665fe3edab27199f7d0786c8c83719993cb1c0683c162b16de3041b94a0d660933a4b4fa95f08ff85f161280145925393488ca560ffb1d3a5885cca1a1d591aeb31496759d64a7f00b67391234fbbf0e0a4527e87128180810746b6afb2f83c6639b1ed8fab34374cf3311d0f07dbbe937912c2b67f66b04f972adaf64f7b6467c0bae05009ea0c62dbea5caa6d5f56620c7648beb4d37cbc7ce923b8b52d51f924b477f0f25982fa8219b0a8a9de17a9b42398167bc1a4cc1d5a222851171af34265fe40da86a13226688e2fe810fb867f8f76294ae4efd25e6ae782c6fc0454e69f854a0e36581af2fc2d9fe38d12d49ae6f47b46443e33a86d08c00750d7f0a163819428273d254f45784852a0a6d1d2168d7dd29667659ee4269f7956823ae8c5f301fad0eca00cf52ad4658e32d4a48e32d4aad1c98d667c7d796f16c3a1163f28431d82d786da793effaaae2377198e156c7a54829a82ba8ab37166002c5e1ccbaf55e9f486398e57c499d6fa96d258f8d477a5f6e9355b2e97cbc7faf8f8d897df7a44238b775f53bcd7be564ae1bf7e54ae191866170d66a544e3d351fc1e7e6b5b1481cc724d2200bd61004a7466137e54a32aa84d68452e37850ad3a52492559b4285f9410c228f9b4285c989c9e4a650619eb07208730b630bc3d1e58cc1183b8d4922e274a3d3114942263cecc405bcc126e2991524d707135ba843126b030ebce1e63e6ee05d24b72a4447c711ee6665143b0da1c1069f95519c44941c5619f8c976649f33159bec13c6aa4ef6f1f52c651c8581808aca334684224d1e23c6c8a3a5c7491e374d93078493c14dd3e49122474aa5638630c6d86fb5b319f500844d66e8568bcbd229c618d7d1b13866870e210c883ca83616bb1850220f4010fa398df2569bf3eaa78d0570ea9f548b12bcb65e1aeb3dfde1323fe147af77c28f5eaff7830d901f27fce8f568cf68c887fc635b284bbe1ebb3da2a1a121a2a1a1a1a1a1d96c88686868684895aba1a6cc267ba8129beca16336d933856fc3e023b03635af0577add6039018c360a6dfa27bad081ec3180633ddbabd21a56a367df06e0b8361acdf8627d177a7d51b15c9a953777777777777a7ceea51a2babd607843d18a20c623ad2655a4a72a931abd11ede1d6b45de4fa8ff1afa835da54e6b1ed37b65bb3078fb5c1d0b39bff7cb12f2fb9ea17a85d55b5d65ab5a86845532b1837bbcea8aa22504950d995825adf770ee6f431fe5457af0bf64963af9eced91eecd50a092c7b85841deac608933a6b30355a2995997c917f49f2b36d93609e802281531edbec1d5f9a84e1059d00a340f04170476583bb2e3678c4182f3fa2214c20f1c349638c0de62507239ad83762fd40c64a19be552da5705e02b5c08a90aaf8e84ae904b5fdaf1791c37989b51a5024baed4d8112d977c11aa92045f36c0be7776465f6da70b4cb1246cf124f16a244f48de4b3de2a921baa0e3d582ce0df56fda40f68920d72a508bd4714897ea633aa8316890f0695510374a94309909376d2eee1fa6abaafbe387f2cc3402db010d1a9c13f0518883f52d97dfc42368664bb691882d582e119db4ae563a4faa45fbf7e9330084d214a54c727f5e92dc476a8b227d1be41f5ef515035f126fa22efd091234eee72eb79770be50643bc493ce2717c82a42c9cd6ffbc1f82549faf1660377c7fd2fae91e7a3def9761185ef3b4dbf569b77db28704eddde799574ab49ea0dbb20c574af404b7fd330c40ada77d2f5d934eec256b0882a15579089ae7bdf75ad0da6aef68c5227aefbd6168cd7b6f088220354f1644d822d7b72d3cb557c46e84adc55e74524aa9bdd65a4be631c2d0bab1d65a7befb57adc758577035eb08ae0662984356edc607cafb5360cade5b1c44d39879674cc8ea3a34bc1718758c7adf54df098c75c84217015137118c22e0bfde311e45143a601a3af9c4bdfd81ad1715f108c655937a5225012a891f8a209e44f0ab5d99cc9970da54894548d65099660b06a74ec8ec734b9b5295417385d32de14aa4b1b551479b5295417342c1364d5a6505d96d8505dbc24f171b3f5907b3685ead2c4e2e5bc295417a62e38515485524b1886556a948846a2463ce3dd30e5a4c477c5061f44723834f1b1846762f0e038e3320fd9b98cf2f0902797d17d66d8143be47c1869829a82c6069e8f224fae7da2a8d242a1fe5c622822783d5e4a2e19b6691a3c440839c9bf691a3c38ac86c0b3d4d3436efd441f325982508b5c6e9ae64e1b962e939ba6b993a68c93676c9ae68e973b196f9ae68e102a2e777ae8f121cd9d28062062e714bf36853af2c4be9b420dc1c53e613c2dd55652acaa71d3c7e3bdeebe52bae00d4da0e4453eefbed8da95928f5e7bac9795acb514d59067ddf537e9a36b87b93e69af0a361b06bff7debbe90a5bbf6d5e5322faf75a6b9d821a3aa594caa8760b83616cad5bf0ba537d56a794d21a50b7f6f844a92a2cd5ad87484123d45dcd2a8263cb67fb1560180caf288ef4ebd78adb95c96ddba8da28116ab402ec63b2a22649b6576b9a308bc57a1ce178934d08fd6ba4c9210514a9ee6b52fa26dc38de64b1da3e572ec53c97de53edb83fedd96c3623605ce5bbd3a5c0d96ebd87d1caad4a405f6285a21a3c56a968ea8860f659a72a17db7d10034a0d9c2b8c647102306827bd028a0e77ea3091278935352f612c51a285ce1643d8d0ceaadb494bb8a85204cb921dc4a0d55133e68730bae020470bedac4f7c99e3244509969d8f76d65f1573d0ccf1597103af4773209078a2b754041e2e51ecf385669f34686cbab455af52e980d82a1d195b35049958d206bbfc71a5543a8d365b2b913b843c56ab09e3c1c316532ea3db16bbcd70474c2ea35ce45c26840d7b7c23528c1f8f2606b1658b0fae9444ecf22985e00936886991f3282db78ff1a263dbaf433de41356614abdbdba5271adb4777d43a6422f23b044953a77a2b802aa862871a2922c1144ee3686f600c5193aad5918f9847141b2edd3c0201a3551b06890b9258b6dbf02dc7b03a360a574ed1628f06cfbb0ec59a451f38334a3ae0102886d1f68a5645528a28926335430f90206c5a24c0e5d6c602c1973056dcc95e9e2a2483f150a2d516cfb2fd80e7902da324940dbdc0746e4d332edfa11d0b60902daea6accc9a76ddaf557d076f7006d793fbd7cda9d031ae08006b07e44a89410777c44c248d1a40c0ce4de58e165c8ae0c155a7d0668fb1444dbde160bd0364a056d7d3cb8c8a78ddaf553d0564a01dafe9ee4d36a3b95007d6d397ec8a79ddaf581e87b4380beb81a70f2796f0738e10027804ba56d09642121e5496aca1b1c982e50c345165f6c49e82006adfe0f7d990ca06fee032ff9bc4cbb7e01f46d2280be3a1713f9bc4dbbbe09faee06a02fef832ff9bcbb5d5f00fa3e0540df9e11b9047da348d0d757e38a7cdea85d7f047da594f4fdf1f0229f576ad71741df291f1ab47dc9e79d02b7066d4cc927d843833c34e883249f60081a0441833a12e4136cdaf5c91d493b92aecee5011862284185491544e4286f0b1bba00a2b765a90c5a7d240dee3ed020cf45453ec1ddae7fa4c127230df68ac8451a8cf240831fecf209eac8a123c7b844e55b326a9b104bbcd46983c591a6252553743f3051823168f5491c1de0e860060f63d0260731412c65510549ad4b18464c4141c66ecc17b4fa330d4addd0e0af4615f904a5767d0e343845a4431b9d7c8253e10d003ac48d517f031d32c974981b92cf9069d78fe950031d26d9f21936edfa19e87087810e795ae433dcedfa423a7c0a898ac86768ea50ebd017453ec3a850ca860e7f4ff90ca5c2290bb4680b229fe1d4ae4f438b415ac459597da231f9146f9b022ddaa8219f2293d834438bba1c40e4536cdaf581b4b8fbd1220f484b3ec5ddcbe7e5e33a4283235c1570f1050e5b1091d2142617d99d89ba0dc1660a5a7d97169facc8634e3ec5a75d3f6b31ca8a3e5f3ec528514afc5959fd1a59e4539412a7accc56453ec5a97db3321c987ce29b884571ce689b2356008a942bbe80228918286875042586a81923e58a181c0d0c414d69f80d7e5393fcf11b2aab8fb17d63cd334fa937eae337f88d1bd9e8e1383f6c67bc791185c215d98db83798ce681b8b8c4a4627bbfeb5bef3222f3af1141d76f2a270d7c760f06e4a4da2fbbe0a6e72ceed8ae378ac3ef6bdf158c56205e7de348d39d4ae0739b2011823b632b20220c9eb67c6bd170065dcb751602cca9fde4d60635f58f6249bf018e70c83cd2ec62950378fdf493e6954112fb229605894af74196b0c72cb17d6162a6eae1f5b124cb81dc29bbb59c9813f3961a4ee6c09c55099828871a5bb62c7d7448a04abdc103c3cdd11235adeed3d214516514aee9cb11ff02ccf481e3257c7573ae1eae9cc94c1998173a70d996b3273e68b19323f33667477e2f410fd78bea62477c2c844c85a86f7c381cd3e63648f0c939e205b1628bd274e78c078aeb0ce5897267264162e78c064fbd359b9e1ac544143f6c894a12b83c32345d8e23569e1e361081e2ac69e1f9a3a5af0c8595d9d115fe009c3f5fa3189c267e4c9c8a806d784270b1357ab67b5389154ece458a40d2ac911db9320624eaf11a77bc241d93d5d9cf33951240c5e183b343ebed81acbfaf9681082074564178548852ad76b4385ce095f16214ba77b42821373c68b3be30933482c21c63e75ccc1474ea0dba70e25f290814b9b9c3478ce2c8125cfca14bd28708ee0f017650d2f8a163626224c87c589cf49124f46d7cf67270cde1869a68831db158c949b420d0f0a898d8bb8b2fdee20e94dd96c4e38170323da726780a8628bcdc64615e67e7772bd3b5e6c55e0ab73f2e4640b9b1c978d1c0f50e2d8a6b06bca14dc94216c370867b30286af89ad88ca07a5062196968c3378504cc214f1b20405fba6ec33b63445e43da1e58acf0cdcc5bd6943fea2f0ec46255c3f3e9bc5adf961e9b7864a156ba6dcd654608b92e34bd3c5cd48d4f3d9a18227861416a40e8a295e2c6d21f6e03c2705893227056a8ef5f17a65984095a3134507147b3dab86063bfb8cf5ec0ce99511a504176f44ca848d77c696c8a880957b0273515af4f0da34d94f90e9c19aac7e3b16ae89229234118507044b03dbcd41a152daa0a02871848b82a71f9b29b2e8b181a2824d54af091c5b23de9e2da6c38dca659b52842f872f71c6954fe7ba34b8333bc039b3c3ce8b3bda7c371f7850b7dd1c91bc7eafb5d1bb479cfc8c1d010354ab975e54ff55efad558b1cd72ddc21176e1989c024a0a2187ba674e24e9b3b71ee84514922b88789631e2eebcad8258321d1d0508a3a52b192331a713161e5c2205e4ef7494463d750310a151535cce27a71e7d43c64804bf508933b3e9972c5452ed889c2c054159b2a6c72aa6d8a5e5b4f917109c55040718acf9571e752e28a6beae8060b710b3b87829b2eb1448755614d584050d711153721ae51b919e35c2f1e9cb3cfdf4fff6b12dd3434e9856dffa7bcad0359dbb5a3d9cb5a5b62af334a696c1613b2b398d0f51accdd734986af128b35a494bedcbd1cc93275c414bb68c1f06d584bd4430e71c0c1f4fd5624bc69095a5b5a7f6b4f4a29a522766badad16098e24accdb7f3e768a6c1a1bfb3987da796e22d82f7de0bbbf7e612534a29a57484bb2b25a2efbbee7aefbdf75e954bce057128e2f08237d1c48125c438cc81179b79a82ccbd5b85aad58f88622ce8537bc222e5524a9551a34ef0d459cc37704437c2bbd113e0d65b06178712ea437c0af61b8cd5304e1b69512811fde2b44e386b9f08e335c690c8f80de30178276ace06d342b25aaf56e0a86360756304548babd6028e291aa5eb522c1f7f8a5caa808146f0c95304491c6cf432e1a72357164c9f57bb808ce4a988de30df39079d29c87cab25c8dabd58a85592cf14395bbd1ccca4e0d72bde1ffb40ca0b5d65a6b4110bc74bb534bfd7241522152e8887c9f4e5105cdee8029fbd7b3f661688230d891081836db4179f4090cb315b8bce241aa4415ddaf2ba52055a2825489a275157ef5a2d00c5225ca633448951edd41aaf48254e9ed20557c1ea33b48952055e2788cee20557c514e77902a6c76902a3dba835441030b52858dc7e8ee798c6e514e6f09df0dc35c7b43bcd9a4c3ca9a3df6ea2287147bac26b4cbd46357a9d25a6badb5d25a6b6dd59a4327f786e193188813a1283e0ec310fcf0fdc604c46d51af4ab86e9461f07d75d628e802fd4f183eb54645b8b0fec8d3b8881f726155204d5bdaa50ac7b71f850e2c5d52f209dbaff049673df52296e9b8bf5e34be1d4dea4a318c3d6682ae71cbf516a34834149fd216f8d48bc2efe979dab4c117b151698d60a2d02b8825b2bef5359af874c532834e00fad60301fa9629840beb85f83c10cb04d26a6d52d4305cd6b34c20f5562d8822c72c8de9f65dfd5d59bbdbf7dde745746f29115cef7afb3b7e42f879fb030849495a9652dbf5593b6b6e975f57de7a147e1ee85b3f0f64522b63b15824f4f0dabe30dcf27bd8d593b514f2a2d52ff15be913f6d2d447bfde4996f8476ee4f3eb5129d498dfb6d68e297164ceec93f6c800b14ffac6c63ea94fbc5064bc0800dbde3646a8c7c05f99d4633de62984aca42649d10c0a3ae15130c2c1143d24961021c54e1a9acb486dcaaf0a1e9e609943254713cd7386a82d7e6d5ffde5ea59b57d61b87b653a937a43f5a53e6b53dda2a22b15ae612f3a6bbbc442f629c6b6daa517ddd01433b5e92a00629e3c97fea5f475f7bd34046124ad4f99428d61daa4570c35e6b6696bc5f2193788b9961904a4d532835aa690560fab7c97a97abcc2d3e547c3eff3b5195fa351f0355a908dafd1f4d768177c8de672b9de650a71e5d58ba6f8afafc1be46aba046abf135da7f8d667e8d563b6a63ead71ad6f47a6643c7bcd4d03d2cd0473e1afa872ee14bae4053a05328935d60c1cafc3710f9b4bffad5068296fcd215e7a3eb6d8b0d259fe16f93a2cd1ad93954e66fc9b82de1b65f24dbff1499b6df70229388f31799fc455bf8036dbbb7fda9d65a75fbe7c95a86bf5738e5f3407e7c7cfe650a79bd4f65aab9eb7fbd15c40a98339b4245f1f68f599f7a3cec64ba7d532bb33ed1f624c4822468ae6f6921b68aa7272c349f272f187e0fa69cf3d1d6ffd8fff9f919a610c79956884979d4c940ff72195edf7a19b800799941f75bfff3ad9701c80cba66d009af077a20afd6fffc0b08d0fffcfc9832d4df0399d5f77a0bf43f7f565f1b20f3c774108af068b6655a41897c8658143421ad77bd8f1632436502072f5dd05c26978d25cf607bbb3a5a682d938bd51b877cda1f1d2f3aad15d62765ada048f482d7862e3308fc20fb3f2d33087c145aff4369f4821774172a1c1b79019d7cda9ffd51a40ab6bf9df222bcfddec4195f7bfb40a6102ed60402f4334c212d213e35dd4ea7fb20fbb0a7347ff1668d7e7ec6a300f4305306d703fd0c53062e405c56869705d2de7b4ac0912b79b0f8c20a097cf0971904fa9841f783ecbf8cb8cc20d0749fc7fc29cda5cca06bfef0f9206b06a1e0723d0aad7ffd8bd228ad8773c0c4cf668d6a4990b8697a124797c70ccdffdeac910f133f483901161ebe10a1f9db9fbf9df2908ec7dcfeaccca5a9530ea77e3fd1668d5aa20d26daa81dbf4ab6df22dbadf529db9a4ceb5172a1cc62dbd5deaccc8716b97ea92d93b6392bf3efc0885cffb44cb6697c3591edeec1c82491977cda39db7fdf944f2b95eb8b390b6aa09bb60e8ec8f4ff8a4cbf835dbe6fff5a0bbce420e7a008230c304913258c2aecbc09c3802fb868cae2ca162cb0a0d59f1dd97092cfd96ee20636fb9ced333e28d9b5891bd0d41ddb2c937f27c92f3399da2924153ac7dcae4b35194610021078a0031cd840063070010b5040021078400382a8a0800420e00403106000012041c9c7e60142d207461ee4e8e0061100641a607081b661411005337e7c5a3d2b727cd0141f2cf2355a3df2355abd7d8d566bf81aad2af91aad32f91aade2be46ab387c8d569d7c8d56a17c8d5699be46ab3b7c8d56a37c8d36a4da66102282183e00c30b2e68a08593850a4c20022b3880010b4801052007f85100130450c20822d07a84b003e9a848078e1907431bc4321032bf068d0a60402f5766951f12f91aad1af91aadd2f0355a45f2355a4df2355a5df2355ab5e16bb47ac3d768b5c9d768f5c9d7683587afd1aa0ef46b149d9388e413efa05f070d7395c9278c49cf72d0b1247285a27b3cd1474d7275a27fd426ba0429f24971d02bd41b740a47649c76c106cd82cb897c522926bada96e8187268c9279d52a22b2e89ae37a230f9acb71a74cd21d195c9483e2bd34d571d0dbae623f5eb115dab115d7746f25977f5094f1e5297ea90ba84b73ba943ce753d144a079db5d5a66b544d57df549e4157291974fd2d6521ba4e8d40bb4d4e1681f65b08b4e3928ae4d36fbb7e0cda9940a03d67a4fe07b4377940bbce498641fbae03da794879f2e9bb5dff05ed4f1cd0de2b23bba03d6a03da7d404ae4d3a33490010d646034f23232d66f41bb1406b4ff9ef2e9daa72ea0adcde7964f9f62c1022c58200c82b40511a22933840b921c706c8cb8f1859415329e92f4eed0ea57405b0a684b249b48a8a4acf76545eccc90000c000040006316002020100a078522c128c88230cbdb0714800f5e823c664e32190e438118067108054110c3200c43310001ca1882904310bb42015b62e036010840a95f6a204e061467284419ade3947a4f284fa46218609498027332540f54a390bf928b3ca217bb657531a3b60d08535b595b8d84a56f8d12a7d43c3010a9267545ded74867d35186cd3870c10ff848c6966f8758cfcf91bcf11ba9f0bf7a305c55bc301c62f71dedad4a5e3b39b409fcafd7845dccdeb75f8b06c8b202e6a41598326b1667b4bc5c852ab311798674d32b03e4a41db59c3c439a9467441898bc054649331f80206635c6b756cb33a15bc4510f1f928447b08a1be42f16213c129fed0534f2cf0794fdd817a4dd1b7644fea76d8170c7e2202e5ca09ce2c25c9ec9ed167c3c71819972d05472db590b39ca517996e83798186b7325587371f76eb914eb828bace167039f0be62fdddf9bac786aa310eb35cd7c8a7cf117b440328b885b93ae1a4a5fb88cc4e0458def869e137a3bff8227baed4ced9f7603311ae7b8415104b444db4461be7d7003915ba95e5d8ef28b6b85d53804360cad98e0d2ff65276f3ec138768323314992f0b2f77cd91b79db581b7ac2e87146b4999fe20e2c994ae993ed4603cb699afe0ce54010f175b74d8adc8c1dc7bd14ce47694874ec744011fcbe80936fcfdea719d0299781f6dc0b996d601d38431011c7048a1d0d56715c321047eb3f10a17419e288b7d9be789c5f31d0292704a0d46920e734078a4e0ca864f027c7b97726631339c57d3a2ccb61a43f82b8a0dbfa0221719609e6644717bb51d8eb786563534080d9125200c31dad7a678a7ddeea585aea61b5a1e38c1d33c3710686fb9c643c85355a129af5eb95f0637d9d96cc476d0c98fbd6480ed8ca2427c28ad9e9d33a159827f30c699fa09c9f10dd24b5667c02742b870542ae5842a8d0241659caf0899a8ac485c269d49ee4cce0756152bc8e48ec2d20bb1967d72a71e90cd87d0f768e23d4f58c60b864b08d9c39d201b28e3920089c58b830737f4f624cb8503b419990b1c693e0429b5ecb312f358b7499f7a193e803910a7466f19a68f81af33ae9cb22e522a75b937ad36060d763430a048c554ee703103cdd55848f17b329541be4ab80cd5f45c4aece8c25a0592824071c4eccc08a6947fd39ad3e0a57ae44fb3ccf91164acb5218a5e2042b5b652cb21bb23f686b4efdfd711fca556588cc5d9bf710ee94b0def866293b44a82a0f52732a429f0edc7e30a7c3a52ad24373f706c6213c7ddd4400ab59311cbfa6986ff61166555a06ee61898bd5660d81eccf74784ec899577143fafc45fa20faa2745f0bd2aad77b37c606b28208ac05f8822d4e690ad66bb520f712130b2d08b6988d5ab13ef24cc447d278b37e3d4af641d1f003e8ff035f4b9bb4744bdd8e97b87afbcb39f04fd3d55580716152b02334c03cb687a70b00aba18a855f00ce1f315c1c6601db17a2f04e5adbcc11aab39ca6f5d2ba3ed0990efe5fe0e67872b60aa03e20fb82622658361db207ab42680245ae55baf4e27deeee2ec5b2622a440d98d4c288960b3b02d6f6089d01ea0a5db0288241586cbb05197e26b4aa7908bf399c7e252504f149bf9142b2844c8a8e3126e5b72bd9977623d821a628ea62b7c803c414d1bb2ec6d127271247ae9893465b88631d2a4d0c7e1707a25facd819b3e0e24b09e80b411193e5c1e7c3af725c464b3e7b2141f5c3340c9e3961b923e0295ad5f46c7743d555a28a53a7ea20942d9fcdcef1c4af0631bb1f9a87eea49f072620a36354dca697e88be8cb14f613fe4d86853f67097887f021b5f71882589b7fb12d44fe89efa6faac460c6437d440595013653a15116f312c04690bf08f7ae5833a83a405c297cbbeb851aab3bd30247f45952200f42a2e870622f44921de7fc0f236358c6e3c0e2ebf11a32799f643f210c040eb8580c090fc8c1db507c179e28a221784571da3aaaf2ce4d9b66fde6cb9e9df5fb471426fa8238f84fa6244ade99cf0a688409b205c4de40d61d77d0ac2b62abc42df8d2ab6c75d75d195e7c6688f3756f20d82128038666efe02866a77563742fd5f7d7f9d793f041304e7c3f078ae375c55a128dce8f92076c849818c7c7c6a2861e614aef1cf7543d81f4e87b3a94ede91977e3ee2aabefd667b9a8410b728148b56e78f60c7389aff8dec07abddc8f3d0a6175803efe67e983a031ad3f9c56952ce1379404e5e3c1d16d91fcc83ea7273d43ebad164584984d66e80ad74e9809eeec7bfd12f0bf23620839bbbd4b5bb0b107d87a036c4a4ec261d12eec785654894876cf9b9a74b546cabd2118cf3e7445fd3f45bf352423aa59b9e98d2955386142f63489e8e8680546f021b92bbc4645c2caded39091b29955aef87cf6ccc5cac12fc05d18de675c572a51c0e8cb84c6ceb7bba0c0a4ace782ecd7b511b292a5cb700f1c739a81235b06ec18a38cb31c11c78001f13cb726477ed645bfdd53cc6d5d8dc7d375ff568c5485ec5fcbbb74d8bbd9bf2ede731bb414e758b88dcd44208be9cf6798010092c431c2441b60106bcc8b660fae0b2dd4b061010692aabf9698877e7b016028143188045a47194ad61ad423faa29a1889dca187b1783385d2651d0bd4cbb75d37a34c4ebd6367622aef62fc11fb901ef9ec12d4b4e193992e83bb3f3c7e730a15daf2b56a876195dcd32da7c522e54aa4fff21d94f8abab4cb96f992f3bb4ab02114c6605854aca0cb63aac50d369d1c93034c30d91a324c5cdc214cdbf4896151b277e200ca23cfe6fda46d599609057be7ed4a474f4d4eaaa859da469e1656d740457469860d8f8e33f07f34939dcb9a0f74721f6d9dfa5fc688ab1135efb31bc3c41c1cc10ccc667458ed152dd6be75c2f3510170d3548a52af3bfb2dc01f016a03f253c5d28460539ec6cd5bae0735c1f2750016c48894eb32bbd48ea7ef26069b28b408fcf83aad0e7d50d5674710c22f3c9a62672829f84c00230615f1332c30246db12d87a373130ed56bc5115228b6690c058c59fe18359f34e2d331e23c01aa5fae6d6f171851d27e890c8da9cf3ea843508f1b3080f6bfd8c5e542ad9055172cc967ca1c4c9f6e52bc049fae4f45eacc3be8b60f4975b330c57b7d4fcd379d98955abbc100926c4888c4d34808d968cfdcc008f7e720fee95fe7a5198f763b0150a01ffceb3809e42db89a9d2abdcb6485ecf8a6123c05a8c5199aa331e31df07b45088ef8a58f97b9b98502971d061b12d38100a1a495cca4dcb0e4b198901b9a4a3e378630ba397d2a4001053500281c688818bfa5231025f6abe5f72554c22d674414db13dd6cda0fd4e08b6a573fd5c0d3543a3806c914cf80a2b158dd8885d74ded1de101d5e1276d5d7681c0f14ebb13dabcf94d6bf243fc3cc81e96305dd7f1a417266250283637b322d183665368c3884417ee51ebca205ffb7597af97efce63b11a8f2ade570ee82e4558c8c94778423e00d60ecac26edb55da75de82890f1007faa055ce16bb05abc3b32ed4ba498090b63390576ba0aaa7aa8e2666fa0644368fc1b297fb1e26c9c3ad12b853cec25106fc12ff42cb505e1a8ddfb647ff1f9c4440cdfe66bde51f45b5777ac130f30a8aa9f023420c0f74303291a7679278581c1d98c720091e9ab9c4c360d0401e8c5ce0d1cc643e1b4e03e03024624fc324f1b0381a308741127dbcae80432a596a85776007b2ae65cedc002651c71515583f2bcb81c0677beadb31cae4d203fd8c6cecd74d481e03460fe06024045fc724f730303a108f4716783413899fc1a001383899c0af99907c168faba1df77e22e02d5de8c68f15c72fa411b6b9fca614625bdf40ca7c6760f14b2b479b6b7231c3370664fc5e665dbf29cc268606ee5409c1bf1c474111347ea998215806f871dde20c3e5a90ca9570aaee3ff2997da0132b9b9d5b9880003b93ce4993d34546db5f580dfe781bae1013b63082d00c4a471b3b115d0452f21fc016fb1786e625e10ac58ed0950b1c10e79fc80b5bd9514d78ca308988518d89f3f20a3ee11e8ae30f4a6990bcf432480746d2cb03c1b9dd8cf76750628cce4257804dbb9b69a0872659e8608c08243475c871ddaee83b5d200a4975bb9b2a582d42520ed049aa6e585819a5f2f28a208763dcfa9e2e06951093a4e405c8b280109eda27ca3174e15ebd5795732b3b6cd94cef8e501a889413406f9de7685f3018f5eefea027151640b2034b77c0c55536c93ca4f14629ce464d673cea1759cb5f5c556618bb18300347583355bca0588ccd06ed4899bc770dadeb61864ee069f602fcfb263d0c32269a014bb07e30a0ca0ba6e0d0e7f7f6c0bd7d60e15daaa7e6d9d0a6b746229ab61d7dcf26b534df4ec56fbb9a67a481b3a48fb7a3f9d573703ae2ca7a87602abe837cc513856696eb0aa5bcc1857d741081a742dfa0704474cfdbe8389bbe64217d413d722a62701aacbf354f225534af432776d735d352fc9781d138617c5a4c725d5eccb6659ae957d05ee6a432d0ce56bc9176ab75df811534c37c26e0e020601f42c0088358dd50e910752c51e0f0448c6e159e5cf4e11b909c2dae75ad57252aeeea4d06cf325e7431974ad6712815c7fb5325cd57dc5664fb2120d50fda10b7adf5e25063c4672df131a8ee816d1df13acd591b7652cfb2f2dca335a42739a7fe816e34b3fb335de87366bb0faa68b23df335c713c986862477b13dd62eb4d62bbe607a69c62f7093a382c14eb425bb85d0d0b2e60f9e76946848c5599c2cfcf087dc12ec91857f3ea57f2f52812f21853fcbf2021b4765bc5f9ac8b1a76657da22daafa246e77e0e79b0613ff03364e7cb3aeaa954f2f8bca9915f561ce28f9e3d9ac8c09145863052aa724215c58f0e785469715a3bf5392f5ef1ab610cf5ebef68aaa857f9e0a1814be4b8822b86b60d9503a360955b4710fda7e1a276850ef2f2f35e1c6a3dbe5f4040db7edcc355f6d873e22d8d8a71a33c08c60ca4b4d713b8c4af385f7b4c2b4cb172706023762180868d3c656b4b8770497ad22080c1f07d3c5bd7f68962956bf76b3566262152c44a6dc4f3bf713f4c0e0541a66024ec48573dada30cb858b135bf1ea5247bff4136ecc822df10cf0e950d90deb540eebc399f2bb12b13b4315eb4192bcb083728244e46bbd5c42a7343af0e3302a89bf6e39599343c22b2767f7745600d6250dab84ea86e22a178c30a9051b8265716e1f71927d6686a178d8c54b87a6951180e6f102e1c7b335cd9d8429004980bbcfed102e4e418a2e4dfe52853f7f6df7fdc2941c8b3f4902fc6e300d4d65e02c0892163a48f39c2d9c5300822db79b15127dcad0a8ab51a616dd061db3a59f966886777c4bb2bc3cb4690449d17bfc6c5ae08e5f144bdc23fed84dc97d5041d6b3b66f375392f7f1c92b792f9d99c7556d7e97b38d1189fda95eb0a5d60f8f8507d8a75455b483923922c0584a66b0bac287cfa48cfa4dd1a78d2b3ba6cadeb37d849168cc68662cbeefe9c1836356defb678b822e5f1d285dfc5635fca530048b456ff5d815ed9ef5523da78973d12266c859de450aaa3b78e85724ef6336297189a83f49078b14241fad9516ffa3aeccfd2ebde473076a0459f049959f44f02f3263f681df0b71c01660154d55749dba9b069644fdc672a40ce3bd0f21e1f547e9bf0e4af7ca03b4b4d36a99f2affdac210a02111123b411f4cfc586dda8391e82c8443f386050b478bcc4f90f5813f18964f499161980686c35eaed15ec7fd68d1c5794eee3120b2bc40936863ef47622025be40d02f0b755d038dc22029867523f93fc83340eaea350d8da8de9da27e847fe055f7121e4127d430ff05b1a3fe89b79f530ac4aa8fa5db3c996ae376783589001447cfc30b95fd7af24d3786a9139d8a6ed40df05b1d56fa3af58e413cff6eaef8f3d6863be1be2bcd6a08048a474444304050a43e752c926e6e8fc06b6ed9ed58b4cf2263018e7dcf71088c47a50adb483eba778db623e007f761df8d06c05f61f720bbcf701f31b744072a0d7edcd0be23eac1dc8ebc6d8c7a6f63a37755b1eda84745eba8fb6ff66379e04ab4b4c55951dd5804d4610719aaf81492ec9125577fd748ee71c29802d48822d2bc80c03826b0f000126a851325ffa4c876712303af76aa353451bc55027014b95fdd06fea3ff418d7419c8630c7af027780e7cc165006a343574fe89c97dc1309c0e2f4eb9063c1dabbba3995f3de9b32e75d6fc7823e78bc211c3f4d1a8387bdc66118184011a41f41d87552ee5d60f0cccdd04670bd628e5f97ceeea945b05b740f238b2dc52ad8f15256547759b01788a05b72d7afa301461da7d77374a8517de61e0f14902ae659da3f64dc2219e0374007766baf7ea32b3c6020c38034846441fa221478c6fe47fa110fdf62f27457b7f20c0024d85183038691c73b3f30c7c014ac5ce22a00ba525600aedf088485fc26e8c06ea9184f90dd9e78891d6770760f201687f091f6718998b3449eaa500951b7274ad40d98d210bf27c933c56f14107dba65122b397b1f446055faff5398c84eb34633b534063e7a0769e09898b3532affc350cfdc8b2600377000cc5b74d141d00a9d3e20cb3d3128c7801b3d589c68ec099c3fe74a0439f0271e7ac544bcc7c36e208d90abca0b1dd870a28fed3934c37dd0efd67f119045525f7fb46243819e1e98083ed7b414d413218b3b109505b08185c391308322e9805d832889c56163534647d16a07c5d26122974c901f6805f5f62c0ec418a1864113506004ac079c4344168209c1ae56ab59112e96183d588cfa7c2f3459a901f323370084413a08b4f64c5eb5fc29176900c8c1c8c1180e7509e9862e2b021914b3eb6ab96fc7ba0b1c415000eb7420917bf79dea14b3b7480dd88dc5136163af0776e023455d25ddb4ee2c78d826c33b92d515d4ab896fbad51042a0db06fc092524fe78c3c1a5ce56b06c852def1002252bce74a1faebd231dc5385be8e9530702025cd0ad4920d03c76b382fa0081cbea2ff27b3e8876f4743c4edc8e3b845747674fa533c9d3eea5cea1f83860aacd4b9a3ea7bb7e8f7689d0dcb04cbc306c94813c8a3e049a0bf1a29f53a3044996651a2088d3752a0de9f6a869c6a0ce8ca614e30afafa34f75703bc1d14566dd576897d83b7998cbe14c5907a35c9e8937551805a7f04435cc21a1db21f38e6e38e3e8a1b123744e80752a0c0b8e043252ee51917e03399047d69c9116996dc2612004cc0352a234dd2c95761f8a147a8fc5f159a5545c922e922d30e5218258a8131c032290c743f13c5329351722903b9e00a7bd6b926527121991cdb292241d86649847aa39b3512ca4848f01c922d84e38069116690bc131084a152e6bac40d3027d334b38069218616bbc956f95a274d956d92d50915496ea32b6654502b6bc4552592ab84edd634fef123b9fab6adeaab75ad62e49141984671849116c83290f11c28e8a703010813c1e8be789ea525c246288ca89808aacda8afa2a00469a74558d8f21f3bfc80b20d15184854a4c7d89b452eb2e44208f50391128d1c406a90cf86cfd116c5d227279c0ac93075fc80e9a85ad388e0b8f55f36a7a40c0686000e216c89a021a37bc3a282d6e8a3d67b95af9a0789f66f6bcb0a780deee382ea739b22521c15673fc0639a601cbb5bb4970237d0dff333d40c9c29bcb5a978da22af0d8084806d4312d8028dea5b62d5a738179117fdf7e232026fa7ac8446e5c8be5e5632bc3c0e797ae62173be0a55f5c4168e896c2c7519ae1a0bb386084c96a0b2f0df6cc9d91155464aa37117d4d4c5f919d16eff169074ad7d141dfd499089b18da19bfe29a661a9cd894cfbd248edc073a9473292a77b1f091a956a65fd326491b74e93c1a3b318f15252dfa79d15f9445330e803dd30a731facc0d48802e034d552bdd8fd42865eb6c0cb0c48ab00a5c1df244397c87fb1f4b4ccf62222b913f5b20385165ed11e8e684e2d305074f199255c939e40f33f0ff4b761aa26d4929a57126198242b9fa81d1665fea7737cbc5963a8db403afe1058988ebab557e85d4d86b4c3c35737800440f7a31ec1858728fa948673e43465f6a8739a9a12ce01a1e99213b5340865ec45ab7c4ddb9fa5ed75cb010ebb3f5524a025845e845c32ec6ff8024b3e04f16e306078f270ed5318251a26da9117a94b5e792ab2de3feb5d28ed10fda5c0bfaaad63988f58a9d0e9ad693e0400dc8a545fa4075d4a38f52fd0e125e17ed0e0c0a1d4c91c4ccea6ed519ccf186257549d590e906f782086d2e611ae6e68e3839f7697e2b035d32e41f61b8fbc0f65cc00895980109fe1c878ed3d596b89eadb89be47a23c9d5389993631d632820b231283244eacccd97622414b4bea1e97ae80d9f14ca7f36afa3bbfa61dc6dd8b1189c3b978bf24906c3a42395572c98978e56a6dcfafad3ff6b8cab3312dbf861ef53ad7245a72fc2dff9a594bddaf5e908b2a7dc4c4ce03b450373db177dd17f78950874aef1fcf514e430fa0b8be72dad001435eccbf05242c5e830fac0e3ab91ad9823439ea048be000a0f781216df6fbb4415e1d47a6e179352b72e2945080c499575b3223ab35d7c07157bf29c41e4dfb2a42ca335bea19761998b9bd9fa6e128529216bfcf668e39e40b64a5608563ef5b73e98e1b1a8e400726cb2a140e3fab65d74204721768eaa31fd9608b71643cefdd2e216cb0a56781064575882d7021ac09969e1de74587d29f8dec895589c2d155bbd6519ae4861f2cff6a086e675d71e2850e17c61884709d47bb2035cae0000301029975a5f7b3478d381c11cf3f22c636af15045d5237a9d469d88c90af483b11d52efd0d0cb36e6d204fc372cbec74a6a5456eaefa27a607d0b8a936416e2d6c26321f0be9003b0dc0737c2c05deeeefdccd5b6649246068ebe8820281fd5805070e0996c57117a9e0b5830b3313eb950d0c12b684f6759ecb39ce6aa6c04535c79ed68ccce93457190df8df7dd38b09727b43b76c6a9c2557b4888417d83282c16bdf9a119b313ce60269bcf34666e57d4ffe1dfeea6bf689bd7132ad1249fb633219d1eb245910cb26ec9c532a4a61cd2d7160a11747d96d3094e444b90ee7b7f28a8163e2c8f50cb8ac3d681a1ceaedf0fc5d174344a31966481608c82bc2901d3d3f2d20a8f6264dbb2ec762d86a00ca57539ca37a4f8f787f644bb3d3c2edb257f875938461ad49203fcbf05621ddc0192d270ead7a1d4627e6494c3d77250eaec4526857944c383f3ba15e3f63dd5d5b9b2ca828c96028a5bfc822346b2367420ad543d442befac6b0b611534f99d39a8de7e1988f8dd10a0ae3a07df85cb8b8441a67ee3b3cf8c04959633903a8c216dddb62e7f411e721b430b674ddcae850148b2d7b44a04a1285e402688790f162e4743304b2c3203a7822a0b797d3ab3f8f68087e2c6fdbe95b41f5e2689aa0bee9ed2462bb089e61f3776b9c5c6b03da1c157266745e3656c4c3aa024c1668252294204cecca7e597673496093132935517891a64e5b0e9c4ea06dc336fd7155ca993ed1c79a65dd8c39cc6afae92ebbd3623d4942a0e498cad8d208e045481f03da89cf22d2db87f86e91a3ba79817f000f22ef74c3dca748686a3c47dfeb2b4a251429869231c834ff269a27c7d82009c72f853058f4df0d11757b22043adf54f6ecbffa5859add2d078264f6f7680819f1d11b7da17d762a6e4c150d1b878dd9007838ca211a14981612bad98177459c0fd3de578ca78d44169e311e8c5209a6f3c8a0cc4208227b85a7ded82630f9aceba4ed2265e73f6c2bbfa5ae912f96ae65a6ebcda38c3d8e4d86e1abd76e85db9878a066f45b8074dd52a8df694d0fb4aaac292a793803156fa39b0045e086d71a7f97103852e625835a1c6fc9530b704801ed4e5fd150a841b2648b498bcd691bb91f1f3baf775c7d7c3e8bd2c13ab0e983a1ec26732b62a0a944925ee8a499a386776a3801f8ae96aa53d5d982aaf366a61bd70365253a65067fca96a9129a1770bc129f80847f647c0b447720157ed49f35b3a8a6d8529b5f7269a2a139b0341452eab0b4ef6a4266f660c7d6ee2c90e5320f74071506f6bef933211a5792e731da5484227d224b2c574a2c19141b5628a13e78fb278f79140535ece17cad967a966a1235dad584d6c14f2eb749d83d921234eb40b276c667ba51339dbd4fb574693c8eaa1d4b41f238411be818a0bea8037cfea631db04f5b62ef36b37dc074fa72ed1935293c0f846d02855d01037a2f93952a137bed4774ada8b996c74f224a35aaf743464c69b0b7c5a0847b5eac51f4f65bb81c3971521c153cb5f1ef8fe8048fa2d188af22de9f8e332da0149e8601850eba633500c84f284314ac3c8f5ac41808d41509b8a64d41f653dc14fd3faea739ac260253b8af7b502178c7fad6c486de69f040035d7b68731ffbf38c70ccc9e1f9ecdbebee0d3dc360b94d0067aa5da63def22dc71a4c5edcf3bfa5c806f3622d41cd770a2d388c8a7bb95c98349931958bdb81e1a4db06acd4730be2b1b75a37d4549390a5632b3ac0222563635863e2621c0890387604c7310d1881d5a77cc2b1ebe24c30674bbf41ba7cd7c9ed06c2176e3923d66b157fe332daa04e0f9ef25e9b82026dfef61c414616d5c54ec5884128c6d0728cacf439bf2458246e07306dc28003b5b9366ef81beb5f82d938491c5e5cbdb08156501dc32e6675e4a381b9f12417a399e08017288d1d10ff34057b0acadd01cc57a01a8d5837178a9d8971851abfd6a54921d7290748c161f70399992308e2a4d198b8572d623f6646cfd1812c43b432ec5b124e7d9c6f5cb328aa264152e223e022cb46ec683226210a31d6da5f3fa4aa3e542803f5baaa5327c278cff7c2f6a5b5c400fb650d636badcf649735259cb0799afb6fdfa3ec4107070d98efcf6ad2d407ff350eea0edff5a4caca6d160c85a9c27f084c5d8a84bd909bd17fed361a28b684cdf9511d0b3685a4b589d0bc00c843d172a17b1634e3164d882d5921b1b7dfa2169801272629b0c3153334b2bd58e6c92e365819647edfb279753e7491276fde7151e9802fa0a5b854af2db76df033be86ce9538c7f9fa7af5e9f1ebdfd5c2a525f1535b15de59e550b53ed7a9a978cd35f91040c23c89e95510c5038c9755bca50f9b42da239e57faf83a07d9270bd3e89f892a127e9d81d416b9e9cca4014b4a096ddadf1f856876b456ca9700ecca25a446742d529845d7b1cd823f898f81482c30de69aa50de0141c2143a6446faa4e80f866e53dcfc5bc20545d739da3efd5187e2db7225dec900c77606ede6d6a55b4651843289fae12e147256168ca5d3be3f95ac230af79a43b1f7f6a9d2663606b02b8e27cea9ba751601590dae9f1a267605894af65150327f792ec9d45347a2503f8784883cca0198a62b133b639e8001501f9b1cab1b0641941d51db3675d0a681387c70aad86ee6400450729216db5d487178edc69344b585f9dd0afbfaad989a3e93b77cb002dbae00e55a34fd7eddfbbb280cdb248fcf915409ee988c66c6318fda8182f55e761011e9a456c6644cdf98a88d9636c7bfa6c480f517e77b07a0ee36e1fc25cd114e6a926110eb143684d2a3093c0461492176f7d51050b31d1427e98b20717d0624e9768db30e60b84017582c8f047b408536f29e999fba3a073b3c000be6b7a707f3842b1cd27ff5e4b9abfdb5f0b3130521bb58d0e70592bec8d82a88076d1cd03a65087ba226591e956ddbea8c576108b3f5984bbdd88124b19568f4d9084776252ffc63a5fbc630d806caa3ddd2f604be83485c85745f4104c4b8e01daa445db2782a35bfed9906c077961acedf3fd3500f253c90f630db432860e0ccba159622e4237b6052e7bebcd71226e307b030cda28b83d21abd2493537b2e467977aab6d472e2f8816838ee59878fd661396047c33a1d6f9685bcf7011ddc14362f13a3656b8a1ade31b264e258aa10dc48d368fb5b17da0526bb0e3204a8f3661153009bd94cce391ea213ee9708e648410582e459948b886c5b8b048301d3e76e188e0d0603fcfa3e44070c3b086611b715bc210a80fa4446487fcf0387dbb56f28e41b87045d40dc3f8fbb6a10f87b4f1ac7fa4b3cb91aa0c80c1a9dce17c0ccbfc7785063f0210c4d5c4bd6f15d93bfc574ed71679abad93aa7ce42265a51f55f503ff67bf2cf1cf5f5db200c5e5b87a3c88c130b05345357047679356ca12a5884e21bfa42bf82d13e5a507cf84bc55efc69c68c09fe8b8db46f9bff2c3efc3860b18b4c0e615c0991516d162d9ec46f9feab41d5370b895b82462565d7deb939aa19f98912de37d232bc86ed369a901d91a7153602d936cfc449c439e6f2fd45f97ec87ed94c2c6d275f7e711a97474ce245c3e403fdbe859913801f1d6b880069ce844f27d0278ee691895be5a33212e22d9e3c8fb6a75dbefc38ebf7d4a91d4be7041dfb0614f89b4bcef8ffdc2cd2db62372330164f149eae57014b0e58b90c2c5ea4a362b3217debc8a91be731db8e6ff00ec6d2451ad5588784ef8287b5f52301b99e94520e398ef659f0eacec29ad83c3894dc41718c5832c6b360962b612ad42ef7fd91e0e9fbf88a53d7673024ee97e1ca17a47b83632b7fa8c4cbfc08c25f0a5b9f493f00ae3dbeb11dd94bbd22ee50a6d904b2063339a77f0e9b75ac1d93cabe400e0b5afbcbead0446b2fe6b526acb7b0c51a8e7291756b93dea28ebf5da9901da345cffc9aec2945a199574571aaaecc6ff93a78150646bd2ac6650b356611555d84e7f75e5518712fc301ca9954c868d1586e54b9a8b70f42bcc975d616e7a336a46282d0ae1c6dca5f424802a4dbdc2d5c7bd9462ce4fb4807feb217aa0288ceb1527fd808f15e2b5b01af246e6f00c996abc215a664c7e1a7ca209e60b0f4c88f495464a0cba22e79c701b9ef5fef8bff7a0eef470cd178b8cedb0832112f844ae39931866650f36802025e43e01447f830f9c249d0cbcc3686dc4961451bee857ec5f4c5c394e87eedd4d9fb4af8b8c876a731ccf7ee3419202d461e214770f6fcfb41059356736e9119df1a7936791c6d3a90458043046f93d9244950232aad0adca5550722e03263cd4c8558562d7e6b7798c1a532f7c3c5d447ee695865fcbe3602a3f3e6340fa0d1671d2e431a73ddbcb99fcc6c00d5979f2f6e841fab51b279bb7aa5b45710460e4836a34827240d250ae7f90a7d6b8465f0125316411eea11ccb9495efc0fa48b39e1a606362b242643be67bc4203bb2e0e7209a43ec1776f89e836507d94d94665f80d545e162a12f166146f9e9508e1923096341bb3f29d54ba01924a09af5db6965550a74af6199667578fc8963bf5d707d55c78993a2f2e73925a0d15e808e1508eb6da19fd185f4fce2d2f85736e782c7fe04c0519a12b28afbe1aa080f3101fb2cac6a26ce0f2b56cc7f6923524efcd21c131f53af4440fcb7da299ae8349e881687c8b101cf1312dc9302a3d7ea711d6bceb15ef8ac3a22406052796dd29af471d3646557e20542faa295aa6761315266f8ccf886ba9130600eb231de82252d2646aeaedbb93493b41363b03648e2636bb94d03a29b37a81efe2a8349803c77d45da2e7ef0d5fc8fe6f46df9a8244280cbc70e8c4b4fc7b5475285556a5ab1c9eed6d368f1dbb191ff1d78a7890263a0c668b9f53db93636b09159f3701acc922e94321e5bdf23a63fe98ceff37a99213bddc773811991188c998e35d6a3d5254d83bf597872d8923f23acee59d5d2a5becef6854c28722bd85e34f8b486f0a9b713da41f87907daa84190e456138495a9fa9632785de8983bfbb18b94865156c69d1f5a20af13109cf437e2882687994c78c25e5ae04e1d5284a2e8d2c1c9fba511dd8989d551ad462547666df90669bcdc222e34441c875c19026b3b91fdea69e377dabdcdfeccae0c983becd20d234191d89162b2aa8c5669d9c02e9c5a8323704891eb0e180a29bb984bec177ac9bf1f46984f5cb89916990a5208e4435fd3916a650d7f5bc4eec8efbb260b54acaf690f5dc2cdb70ab7cc6de583cf47c1b5c82ed9110ca65f415d74b1a6af15cced849a9c20af1ed7652ff78d411392056807ff443c2239e0adbdf31358002a99f8ce8e84cbee5034a9b4c389db155cd1b3366623f0c2504022ef0b84e77c1d2cd07dbc98d04cafaa4842a29529c6dde9183daca6dc6d625d7aecc551eb6dc687902b5c7033ca96e020f43938395d86d350f01bf1835e19b8e43e99bfa1b43129b7c89084362305f1a56f7178219363713417ab710bacffa8b08457abef4140d61460089493fab55791546410a627205f37731e3db71cde4df48958f5eb54f11b17011dc9615582ad1f0d5cc2ec418020068b92e2c7ff3e89973326979723f620e95ca447b965d689cd6f9634c9e4ea43e9881393f2d72baadab034c9f9264aee349f40e9eb7253072e234ecc1992a3f15f14072fb08c5a001e2090c7672e6bcc2c595e115b69bd4f9d89aafb3cca0152628a223e1535c9252ec23efcf0cc5ebccf457071c43c2d1ae1610568151c7b56f86d5c42ee3da388afcd17a74bae1d70cc4da1a7bc834d9a694dc1bbd0c1a7c15c3612aff160342a4ccdd05360df72264337040919dc4f845956c8f63e105a76d2d737528f0d4930745714fb3ff144dd25741c0212f67b4e067e72d1d9302640b95196f469acce7a939313749e054a855f3442594bf53c836a5c56e3cc00833c4c94557bde351c3d2a70559886ce9ed75aa1be5710465c9df23d5b8a13c6ac57cd9c42291a98e3a57a3c7e081bfc7287a7d18f8266b781b21c6fa03fb04029e985a1be1b0eb5a09d67275a886e37a7853f421567ca923f6258ccd4ac919d24a328d063c135c3e50a4315d5715da360466ffe9a69cc109bd291ef357cf81adc620fc2899f6f6f5841eb3ca05acde8b3635eacd6609f5c89d74b0415f09a80f41869ddab68cb02a404ce0a695b6e8d1f4322afa827a74795ba617aa426c8a9527ca909cd98e28464777c4b5f2b849bb155c11d50cde855fc751d52e147e63d346cad7542f7a194086d5c4e535082bf39a7a29b13b4830ca584add2c7019f68fa7aaa75a5e251e69a727b8042679bb7cdde27b563b4665c3a8b759fba395426765f60ceb4208372c21cdbda721b66e2495f9e20cdd5a30e6b8cc2a5b52edddc88660cdd3b85bf0d38c7806cab2df1cff63091f8028c72c600a998f566ce9eb1cf8b82c7251c6b357f53627706484cf14db79965f22b694d524474f56925af61e23e6bb09e44adc55567938267ef298e5d95c36b10f4c994330f6f35ee78ea2ab3f14317bc727354b07d507bb21c2d9eb2fc034936e899a4c5d55153988db7cda3dae2175d02c3bb2d62118e4f85d95ce84ed59ea7798b9da96c2d75b4a409475bcb589bf708171e1b2bed3b39121cba760ac86cb71b7e77e7d98f9cff50bedac08cb6515039433af31a5f82cbfad4760298d3542eb7e74e36a5515d4b6d6dd394acc50824330af40290da798794f2e788e7823e00a2c8989ba20511d535ad9ed8d04ef4bf9147443e844239c6a980bbb8dfeef951d86b1de53c479bb905d1b025ac6ecd36846152192b74b0e7eb9a177702c4db9f6204b9deebeddb0934ba69ea2b8ecb1d0e164f43739150e49a82dcc1679d0c2750b773e0df524d869207de0e8c2351498eba4a40f6cc188081bed89cc60d3a6a8ff833a8f17653e6ed8b1481532e573bf969a88d4308ec70b771bf141366775f8895a39a5775bada41e08191e7193842312688eee409b8fb74b482ade170fb9dc0f5fed190cc22c25ef323d4db747a4246082c2afed4a8dc0d40d990fd9d8032f5e602fa6f770acf303304f7eed0fbf97750994ff43b1b56134357ec383b184fa7ed58829d1832bb836231c4fd8845907c2e80c9d1404144a3774addd817ccc98fa0375068f4ee40259f606b7e688c4830ae6afb676d157045701a7d89c702098567131ce7e794fc15d0b236a0883e17e18b8d341d4ea63fe7c8e590f02d902c0b54725ce03b1853caf9d43e54c5ca3be51df793185d093444043811656786577a66478676ecb05c3de50543c53313541491fbaab67f65738588af9f66e53c53e086749de1b007e51f52bc496dc77648279a2e8bae1782007407ada075552db63f3d524f367ac3477901c0277ee0e0dd0b741af8c4efafc7654f0e9be624aecfd160982afce0f11c459416ffa6b159272778fc5ac7e37eb9c6ded9112404ec7598f972659acb5e5d0e9b62f5c9058aaa458730eaa922aa0ca35d6e04a853b18b226781f9498e7aaff7eea795d07bd5dceb309bd73d6a7fd0454f6a32f4a033f1495e7c17f428ed4d7914e2aa22c722c9d05a070b04a0f25ed2e5ce59f7050a39db8e95dc1e795faed98ee17e3b9276d2036bdd44bba9aa1f33f1d21936d7aa4c8b28b9f9afa42330d9b36ebb842ccb21423c949ada1d47b2589f7c73d6d8157387551c175e0d85cd02fc4348f7c32bd1966349db6532242b029dd31062c00184cd72cc36a385bd5bcb68f66f0e4b357542614f2b4b3f225ef9078365672e5eede044fa728c6569200e3dae2d25e09d48bc1c0b20d56b9065eb680dc82a578fa571ce5621a2e54029bdd75244b271c3c42e51b3fd4b559926c04953c11e4008b54e3ed77ef35209c68eca26227bd8522d8587f2f94ac3437039146308671d6e0ddf391baec95ed9f9204d941d98a403fce4e6e2515e76ed3c6ebe3dc85e76425f03ba54ce73c110fd5e4a0c410efa594764416dde52d63f0ab71d7f76afc74301db3540f3df9124dabc8bc71cc79d4936a9555e279d763364bea078a7b967f1a1cb16f22af0381fb8490398760a891104969d555cd1c804857c3c60fe0ec511c43c9043fc9c49e73ca74c8ef37d9a43253627c86940b2061b7757b0563e1dd9cc42de30c8246f072cc512158c845173813b6c33f4cf3250efd85750ca61ea461da68762e404255011cfeb08c374c1cfdb8db8fe0f985501fb5384843ba847d65b901be4910519e612d30024a19985ee5f9a34f559a37d4b281f0f6dbfcc8d449ca18d6cf44ec5b0bc541c1a92a52354d641d5bed9ac8c5ac67a6cb6bf458ee414ca181ce7b2585a6d3da7e1199073fb17aec93c4d7e475bf1ff39a3619d1fb9876b98704991ece598f4ecb528bfdbcc61457744654d453275b98a63b7402c4f6126dd8ab41cbafe7e44a47de782827634421a6127a3ae19d560cb8339a2f321a37c2cfb23d674cd6a6d71687b5fc22f277cc97aa21f6883a9b7c4ed708d59eef432bf39cd58ca696527a47f4301be4cc6f509ddf4be63b4bcf314813d16dbaac99b067d4dec88878149868cbf133deca028053372b2f26e047436bb019da4d256fac4d897b6a065fa96bbe2f0010b2f0f813f26b8cb50e9fc3b353e40ba09d04a9600654ad8e3d81df24d0027ec6f6c6c9c8a12b7b8d1791267359c2ec066c45e7c23e11e9cb31050f60b77f4cf87047b35747dd49249405bdd614000d2636ad6bcff5e54035dfdb799fe5b2932c466bd0c6954e21dec2efb01248720454c2b4ffd65c1b3d06a42968b0f5129e8229daf28c865c6a0b47a949440682d8149c10682baa6ff09a3578a9bfcac59b2e40cf56c7b8886a3fb8880b1cc2509b6785ff0dab5e65b5e280580728589ca4bec9d9588957190b6b6a2755ad9cd8f5a08bc4bb434048947c8761c0eb6ad2c8a92efedbd154a21fe7b5b3d13b378182bcf2e86027b785810f9ab23555b4dffd928fc441410d43b78f6860ebe48d19c8f2308fed0e1cb681d693cf5f7d0e46f8d23d344172d4a1b895d70b4ef68997d45c41b063da01ec9664b1291d0045ce18e605a9504b65ca02f0848ec3446ee334e2074128655ce90744020385afbe55a46345a0392133564376499a31f82e54b43c2d678d47f4d242c61a14a75d7d25592fbd2714e3a2a32a4d8d776741a9c06aee27c50055f18fae37c0b80f7b2d892b132ce7b42cdf54ba0f5cf67573df59aed07779d073b00b1c60d44862478dd4fbf3c6df4558f17b188bcb8e805331d697cc508b3b888694944a50212a3ed82ca22a3e57337d31a86ff29b5159869d58c025d0c72cae4c4524bb3f884cf20906ce9185d04436b471562aa2ed5570274dd2b4307c1942906fadacf5e28a4b7624654d2cebde218b590981e51cc706139114511621efe40c5c409818d54a5f0e1e265ec2a647e7854871118aa74b709cd39d8a1222f5f2d919f6570baa22623e32402c0148d76f45c4e22aac2d938dae303b873512ca742cf1712e5ce26c675b923cf8baa9c204b28e61e86e57fe54e27cb6068ff5e603fa68d052af53142295c40ba861ef838e82512cac52f404686cface6a938df37465a6b905cbca9d66400ac835ce6b05f323ea5916477f8c5c934cb92f46175d17d270deb44d78dc7b65d62b617eb848dec6be47804a13d9128c5970f9e7dab57bd47726823c55de95980a006554547e8453d1947d367626bbe0c6056c506aebbf547906c9c81d6da59a904914aef1acc932d3dd4a776ad33830a2c6f14c49d1040edb4602c651220981d7f221f04012f448011411f23bf5cb595ffff7f3d7731bb50237a6888be0fda84a7bd6369ad6b8c464f44674ed326a3559012a24a16dd9afa9f40dde3ae909485475d83dec6257edf866c7757c1d661882ab31b82f35e23c1bd78d936546e258c84e1e0a82ac3dca8451cb396d61bf90d147f6617856b7c714cc01a909ece26888c371d7cf00b53db3380050e4a3d5e7c18682de757076380d0183a9084432c0e17064cab2ca77471d22ff181cbe91396836f2e568a531ae1252cd09e3dadb8696d5f72468966f4a6ab088386674c4442d476ac77c68cc8046a5d72c404b2a54750a36ed1d19e6021492f96fcab5b649741746973ab8d9751a4eb32bfe578b1b850eaa13d503b04092e29b44a080b692e15fe631737a9cb2b219e97670c51d6c590b2a20bcfb877935cd6e88974f154288f5a73d05bd894faea4edf75184dd7cab742c18b465f456f35a42fa26633543721123c05259443f3c5cbcc103609ac5e0e263af98fd09614a01ff0de53ce1b4a11831001f76f92a1d845e8b9e793dfbb1a00f6e316e88ec3fad388b0c1ae448af79af351904871bee1cdc0ebcd21e202de223b2c66a53aca7bfa06beba00dc0f9c80fbbf5d7a45967317749c5a5940a997bf8b364625618d8b25d6bd8212b7249a717a47d6d30ffb468f6493b4dbe01591f62dfb434a8cf2f22bf02711e99799a6d616b11656a4577d55838b81b38227f29c3e852bebcac03256c8ac3ef768c523b966122ad275e9202141bd7982530b283c5259a5de10e8da84d480a184cf3b126833a444f3893cc9a027760f4a72f038b72a1cad7ce140af708f365000635a780addb451d8f725c6ce69235fe6c4a18db5967b6771afaa4db0c59f2a017734b97fbe2036dfe731218de8893874e5bd3f1538b41366e123c18e91a088c5873dc1d3782dc96f35ce4ddc340ea54258f93e070d090c93529a93962fbeb7adb314e5b9a4f581d3fe47270e10108d8c6dd5cc4539a439574d9c089ba220a409035a9123cf3940a692fb050b541198ecd3affcd741a49e3d7cda3a46d6b4a5eb5c1ed7b0e47352fcba91f7aa39fa481d43a2beff2c44a0312ababd13ad4129b21f544605ffddc98c1a290eb817933626ecc899c0615b7580f3196208f510ae56836085891ef817fbdd5f5a9e9bc8099b42a486360569f24724f91f2fe961c520e5bcdcf6fdff387154f1ce3fffab37bc164ea2cdec42c268c21dbbb429309039dfb82f7342b1707560f30e7a88de2615b4051f807b04201cbbe14f889a30a023ff61239e499f55394dcfa7730754f9113688e5e0b9741af94893c4936c6b2939636bbe7332576cbd1621895cf23cff302cba3df1ea0008ee8e0e5a016c871d63179e9fc1b99db5d1facb26554b647643b1b78b55278af19c2d6c6eab6b146cf64a22e2065289f41ace39f2d2e850cf289df049ad3ad0edbe07912be1e1a1a6ed870861136faf77f21fec2a8b8d8e77b8f02a85fa55acca0055c9386ac0febd538a6130e65e2587ce8986de08d6c15b7d01023076771ad0098c4f073d42b0696c3249dd30a6fc0e494f26673edd2b48bb0e528d673db4eb7e8332b42b9951ef3d4ee116630609ccdafe1eca374e364b8cdf49796be09fb58f57c2233c695d9493bf890885a51a6703c8f42fbcaeb8bcd530e1f80afa648ac794cdadaca5371e807ce88e971e78e7ad33aa59698417c56adf5423ae6903a743e2cb40d1eb4e2f13e3ba1589f9cb34dd329420c7b8cc92d5f718dd906af2ff66256614bc2a2a1ddfe80fa263151f58706715cbf1f5ca349531324929d7523817a9e14e03b50b77929287b4c7cebf9d1c50300a00390168a836e8be2acf6894547180e29d79dd69d573d85ab7dcf99f032413da32e3e590384831b2f1a5e1eccbe5ed14b85efac32b393f8c8e329a0a7cf4ae48f88de385cd8484567ab40c5a4e77f745a0e49ad8967b929a4d5977a841a4cdade0ef1ff50f56ddd2662065ad9b74cef19f89a8aeaf0d95371cd985ce6e13e0ceb397e79db5d5e6aae37a06082350e50eca89478195a3626aef339502d882c2f3c90dffabeea891c1cec074ac447c6ac37dbbb442376f84936d81e33243cc96ddef3be0385408b1958b5a600dd8ad7988a3c6ff88e0c2bec4bf8565f08b117da551a780ab94007dcf5604c339b67b5c7956320304282cfedfd2dc2ddc6ee4363b093bbeaab30110d2c415d0b931cc9003233181cd9f10986c11d35c16cf4a371f82b150b986140ad4a9622b46e0efe5530000b09aa22b97bb36ef575794d6f69120827711e252a7bf98b67cca4f49990d4cdde8f204906e029a2db256b02811426cb872a3e5ac4fdd5055ab007f8e6104adb3a56c7ab22cabb491f589284f9a6815d88670d6b5f758db6b077e05bc0ca1c22ac972185354281fb7cee49e7cc1826af0529bb8cc60b4fb52747253425e7bb987492a7d36138d846c42ce3d19d3056bb53a5e802ed36f190ca491d92e89a1733abcdfdc14b6881a33a267993302ed8d7940fc621e02e626ad988fb54034b718ec1e03563508a0c9ce042113e30f7300b9a2b2a839d24d1ba39a9de408297b5a9a2fa31eca9bd42e99298c168f087524e1685735e859014e5376022ca762f9cdf4b70169db15cd49e6ebf0c1ce746c43e92f4d6c57b0bf838713028e3bf9a41c24fc08a82be912ea54181c04930887dd5a5057554875827faf6dbd799674beb99112cec463d048bbd8c4ccc83cfb45654cb65ed46f6d42c82c8ac9e1d23a5a4991a186da0ec94732c6d5b9283f188f7cfdca20159f7a330996e8a0fc0c26cbe6b68e511a9f52258d41c1e70b664071e277754e349659732686cbb6ab5d0f987439391bea67316ab38a9bcd2b4dc59b7212ef468b1c62b662c732bd44d2f0f3a28a7ec6d4fc4f25963a6a031168e2375795372e3b60c94a701f255c6fa235793774d44f433eb0272deebcded6ce86e7a81ede602d05d66b5db0c1e3090f58663e4c3c634e24cb7511612af974db62d9d26811038c4f92b16646300d734ec0f2001bbf0869b1482013d658192ff2cc0018b36e3366ebd686eee8966424321219e4644043f98b6a97f1b91e29cd457f4519b5cd0a139fa25681d0275a7335bd831e6605d5a2821b55774313110b3e4af09096420e65e398ef0a70f85cf5644e74441dea38fd5e9ae6c0b6e591a150526e608e3687e40858e01be674d83d327bcc5ab9374d294cf76e2ca72c3d741387403960f7272b61111b90dcf55fc5fd7ef0684f8efcfb917a69578c1bcc40e99be04457ca5ec88e63fc2cdbd1319fa8b57d45c5165cca8d46bbb94486e16f0e5773bafae96c926817c053b4d23777da210dca3e4be863244fe03680e10a97cf78eb19c9f8a307de07a99ea1ab9e16de495446689b3bd22aaa807b5f0243726e0bd3252b7a7215484e90518001145a477188c946ff2374a780560cb2df733a634bcc0b0c4866fc743618248c878a96c70736312939faf1b7f9e6a306d201c5b241b075abefa26f8aeef64a19ba730cd58aca29e9581cb82887128cc33646d626a9437eb8af36ce266b3c731035ad323a43bde9ad549b32f29a5b907c802087a904fab2cfe73052530ec60f19987a20ef554785401815f420001c6e09f5d03cc9f28f9a5d406baab975367c4ce5c2097e7db261acdf390b653f6be8c4690ba4ccf006872a00100470b12aa494e0cd8c93c06d7aee094346672586a359a544885eebb1c90c3433b1b0b5abe8b1975512922898db8ef2679a3c4e608497adc5d2bfa4bef5efae92f05221b26acd2599e0209849533a468a4493b633266a0b706c0d3db25d7083f230faff0e7c45e1927415be219c2fa55c49ac9f2412e872880a4d29bea55aa6c68c9065611ed69cf5a8986588979a46a2063d267433959d4104e8e3f8d03719111558277316bc87494bc95e3153727abbf18bd9ead41453e733df7afeaa0e5742be611a6714c397a1bb1a8544230e2c0a317c56df987ce3894b9abc54e54b4ba55d446419079a03b9c5f849a99662ee17b0e6d882025ad84364ba9834ae7bbd975f3c5bdeef5209d57b44dca2ea2c34c70b813dd622197c9fd9f968ca31d0d01303d687261657e33faf31c2ea40f172f71e2ec93f99654a49a63122abce9f773f9474549171eeb070462bc1b81667d06531b9698749bb0b4623d3ef349b66e48eee3dfd1b3203ed1e8d1509cd194712eef4567819dbe47fd076ea4d06b17fbc41a0618c67e49d4d13d171110a5ae389473d900770e052d63d6f957bf48e78f5dc0a2596c4b45f06f46e40ee96ec844cfb990a1d9b4b2cba1c20254429fb4b60957323925ea438433ad928f622113f4d472477d22e6bdbf7167bb25d3c333a2ab4fd9d55406a351e4a51a6f339ea241e273003124b67aa52f19f50c24249a65bfef72837ec09c99707cd6681d1c0c08036b08b0824c18add76dc3fd663da72a039546b536721688c3cf96e421b5b502cebd86d1b76634d5721add45ba516ceaa8d725997b53611d821afb347be8589fe9f539a702d87220ed541e339b0762446b05955cb4901bab2fef3dc29bab67eb779c12fea1b66e7d62988a367880414f34a5c96e21024097886ec4b4de83204530069533c03e434024a5311465d404c4a4e07f6a28165b90722519488252e42c70055102db0e75ced7349394fb5205d47bb9175bf6f6e542f3090fd8bc7c6ff54bed3d98989fd016c99ba549b829e3c780ff4babed1e2257eeff6c51f99f8412144f6de5b6e295392520649044a044e04e28bfff2d65432346992060924643196183cb6c0610357313561c21cadc182455e3369d2e012e07135019a83691c4bc1e32acac15b972eb01b1020d65a6badcb5a6bade560b5ead5103cba26407f5cae76b5b535c8d52e171f4c031e34e0e1b55a8247d6c52f3468a26e44ddb88df03466ccedf66e6d77cfb6dd73cef9849cd85a8ee32c0b3716a948456be58823644b50a028c9946432a4d7d29219334a3225990ce975f192162d689248e268cdcd071fb870519229c96448afdb8e921d2550b13364c8e09105934d9922ab4141d166b4d98c4976710d08206833da6cc6a4e4c5cbc5b3a6a6a85bd4ed0655bbc5c0aeb5569faeb5d6ee6eeebf192ed126daa8d83c2e88356c369bcde6828aeeb5ba4b6c71958a9ab355107864312d312d2d29cdd8c5b31b4b0d1e5bdc6437faca9225ea1675bb41cd2779299a98152bb017ecf532012a76e6ae9cc0234bcbc5b633679e6a4fb51a6d32d9b66c0157af34b2269a408a21c562301925af0ccdede909ca0665b33d4d9abc37344bb7adb576568ee3b85a6badffcd02d440bb6ddb98425632710910068f7209fae22852d14a326e5bd435366ab5b6aeb1b1842fe1e0705742e0916543cbc569a85099cda06a40d5b08940bb665646e091f534e369464d06fd19571763d6cac6d11c3bc1e30abb8360edda7256c1da0970e1c245183cba60ade9ee1e92b3599428e0ea950664c2233e62234313ab5205f682bd5e38c85c1c5323f3aeebba6e76f7deeb5dd775b7466359a381587dbb2fc4cd134310a406025bdabeef765f630a7561ab35188331256a1c8529919f7a2fc6365b2a46d7dd5035bae585ee79dd85aad136ce41fcb56496add8c18489ecaebee091d548b1195bdd5617cb6ea00e78c423d09f119c2faf9909ce39e79cd3db31385d8325b09cb139df2829367378ad4649448c928cdc98365a93b5b269540419737c464948f9eb162562a47ea76a1dc0ab1a2521d11fa41f234649b565946464095c5f7e49229265ca03a3241915652379aabb76ed55af784480c7f95a31896293e9eb3b1c5d1841a2a2ccb1582c0811191123321812059aaf204162b1a3579058fec87c72e7bdee654ae6ae55dfb6b896bf0184e0afd20020c0f3ddd6cabde5aab596737777777777f7b75cf57777afb556ae56eea5b51c576b75b7e19863f45cefbdd6bd7acd3b1910b8793cb44a5e2f992ce5ed45176db25882951ca9813e5903794a4c0d446b2049e448ad43c2b0dfa57eb8fae023f50e39afe4f94e79fed83d8ef27853e0d7d371930cd46d224d24af5dea95f921ea074a1b067c9ba74529d6bc25654f0dfb73dc2ba594524a29a594d6a64f29a5ddddb5dbbdd6a6d4296ddaf4f270829d4c1134a38db296a5b47d0bd8823cb2823a9854b07482a296e5982c9d4cb044364a6a922f7812f3d34ab8b8e7fbdf961c734c374a6ad2a4b66aa535344a62d2fd46494ce84f33619a351925cd8c92684d4d289048792853333161b24445c94445998d92985051e6fb820f7822f980a7cfae6d3ea90229482f182aa460b09b2d47208c96ba02fb545802a3c0bc1eb1cf07153a1f489e0e3c6e110c2a098c2be2613b628b548072dd2945aa2bc8e51314bbae29427af8c517c4453f68aeeea6fc90444e4477d6dceec21b4a61f3819b94277c14f9a049498285a21eb49dc7e07d0b6090334b2f772f6797702a4ba71e21d8018342b829625d931eb01d7aa470660a0b02ec593af190c2da8efa047510f45582c8f4e58c45964e3f78e8f8bc1b7b10ad5c0bbb75e7dad8dc877e643bad3d2b7cffeaed5ee7e586307dd6d010adf6647d687251df27250c2b656dc9d7a9de744a29a594d29b9ef854b5d6da9c7f9e4c7cf56b2b7f13ac2d243da3c3a1e6711d3cfd9f8486fdf933c491244702f3e5d3982f6748633e17e298e187ae3c65fffc10e8f7532ae4933b635dca3a43b03f5d5a923038c8fd9449c2a02c58bfbac7ee1e6a837f6229d0fb0f227bfabd05e69659f53d63dd4d28b592db7f4c68a01cff9bcf41043e0dd583ef0f827fa3fa1c447608f6bc10c70b85135ccdd35ff8cdd3ef85490200047baffaeff177c109879aa76f1e7cf06bddbcd712e10b45c0a12a1c21f5d43c6df360c27486609be5772ac60c1d37efdd3c8d2fccf19b9086f737ef79ff852724394115e6f87b2f8942f85ef5aaf00430fcc2cf0bbd3f2104efbfffc213c070845084e6b9096ff3cc1c88c061c7124a9c5d923da192f9a2ffc1609a47bac4848aacf9a29f6b61305ff46f900453267a0013e05404521fd47046cdf69e1279210e1488bc1fa2357bea83a319346eeee101534a972813659a5d2410e541f2f48b62abd5740947024ee48533c806353cdd4786a790c9d3ef3f4a1bf7745bc8ecfff9fe86e306799cb1e7c25100799cb19f24601dc92d03280ae00b3708fbc71fba14057f1e692c779b2636356db62005014294638632b71b14590f295043d44f63fd146949d586855fa42226cf3c85d0926707559ad871ce38216c99e3b8c76c32c7c2155ca9cf12e249ae549ac8f53d15a3bebb737904738b1d2d3414e47ecca29242ee7f2a4e3424599cb4ec4a90c0dd9d95fd8b141f6498f24295214418701a73e4a542122332227f19133b92ec597ec4b2dfeceeee6288e674a2ad9029a5d707eccb8dcb132f47268ca0290619a4b0d2a444d41d711a32c3294a5c07ab93fea75ea4ad5cbdb55ece5e4a6777cb59adad377c7267747597b3b5bbdcc4d765dfe93b6add2da56b74b930c6348bcbe5f2711db99e5cae2097cb77f8e6c4fd79457928c61e8254bc2ebf76f9920f4b21a2b8418c962b6cc6b830f461295f2ae0c3120887871330e8589242096c4035a21802e6479724669ae45f295f2e40151424616060bfbefd0544b178fa8b82a41669e54a0c5858a2332ee845d6d38b25edde7bab7bcb9d6eda596c367015534367d35a6badfd6ffaf8f87cb918b38a64c4f0699f02f8e04393341ac560f284990291eb5b19b5268396c10c62822b3afb51a3d16833da6cc624bbb8767bf244ce3420183c6213a0e48d9da94d6bad254012da6ddb8600681d10046178fcffff0fd3db870c787e7bbb109d74be98b6da23dfd7a3d45426a5b7c8746f6b6d4741b9db556bbfd42f5e17ef7377bf20375005240f6d80e714ea077601a70eebde9daab5cb8ded9ef8e4cef42a4e219aab0535f801f7cb29c4b5c407f3412e30edb73685a6d044d3542bead1e4e5b607a6d0aa09e3546dda53a8ccb561914493695351d34d59ebd1e04e5976c8a3eb045972c852c35151919acc020216a49c5f9397e33c8b447705090b3606d9bd32e4a8c6f0e2aef408e2445ed60a9b1f3d0456addc8e88285929a3c210262b5d5688a1960a02ac82bf2c9d74dc904797191d337c6574c0741c5590a5530f1c549d634031779060f73ca5f848b36d4ae9fb943db552da99767bb7bbadaf43a59455cd8cdeaf65cff4aede2c16d77afcb4feffbfffa3e082ac01cf3666ed6b07f4f4f61fb7f53decc6b4e7376d598fbe6fca4661696c2a432da57c29e5f449c4bd40f66060011652f40b2e605b382c48c88d935b014f5de4942e1d2ec527b9eeeee9fdb7c5b5707be8ae03fc2ac6027adcebaeaea14bf674004fef1ce6f7de5a11d79d20e2859b8507ce24a248e6b0648e0835997b8c450a0ba816e67afe24f7d37b2b167fff22b83b1269a72d43d49272e3234f3b4334b118c22987dc6f5f0b92cf9fea190c7124060d415fb1f5b5c1c30d51d49e18a2e44c27059b342ba83132650a51774a5570e072bf8c074818f2e2025cd12153da5dc68964c632e78bef119f431f9ce17d0e0d7342e8fefb10ee835ff7a2d7125d5d3d1ac539b27c9a668ca33db3dfade304db49dffe97f18a1592a7bf5158caf541907bfa53c2b04fc3b18429ce5a66b1037b00429769087688654f3fd7c2913dfdb6a5823aa64edf521754ecdf1177764417b761d8c6ac655aebcc9ef38197e97b99baac7c72075cb5805954a43e30e01bf4fdbbcbd9ea4d690d379023dfa09fa38504836a7a28b20214475cf9237337887fbe381fcf675d1bfa76614ca10cc817fd2bb2fcf2066a05759ce099257743c2e8c9fd2648189d5ba2c003f2870b4216902ffa47d96a31848022b8c58d32e3e3f0ef112e9843c8ed360be2090d508410a928420a2457cad8d046090b4818dcf75fe0d6d0ab57ffeb5eabd70bea38c19ee54cb9d7d9bfad9166afefadebbd6d953073065a1a903dfd9f8e13cc65eebfd6943d550615878a7c14e5f8cf1c7f99b94b1b86e9cc5cab48c6063e22b00403146a969822c31aa216818e254c48e1a1640d1427b873ce07fe3eae1cbce201df3041c218923d09904214902ffafb5b1228ebe8bc9ce1fc04764cd88d7e13fa5bf40d3c22470d604ecdf80053a12871e19336ae098985fa02978fe6a0a5069982a3565e9f951f99de64e954c5899ccad2a94a127964d5bc243ed953f449f943dfa507ae7e49c58ec00c49f0f7320932bc304697fc717ee0e54fce7044a1e52f532048245e82f0820b106d461c79926043924121d797b296842997303317624092c9210936e410b1ec2106e410b18c23d7709c5e9643c4bc3e5a52a54b1e5d57aa6c8955a9824315285a54aa23022cfc70a45bd5cdcb3dc619f405e72afb6d51fbdcf5ebee77ca173e6650ef8ed779ad0e7aee753b194cf1b618afe7e66a2ac64c4d5cabe355ddc9003ff129e51268962bbe2f057e1ea594523a8addb1fe72b6629504b294368b524aeba4945600e4933b93b657cbdd54d779a0f781f23f0f04535d65b982a44bb7e1e7d5eb1b56d7fae6b9adbf51715ea7b218571c1c57a1628563f1e98f145f74f5a7c0d50d169f8af4267f05373729f0e646d5428eee0e2f15595ccbc235534adbdd6bad584a79c5e6a1d6769c924fee4cdaf65a972d6b6d6749736baab8390f765b5901e5da7237754355b4c69a3db00359b8b250e1e05cce022ba5b415803265ad6d6580c572dba5723c9c7143d93c99869ce5a89690d7bd392a6df5dad43930d35d1eed1d77dd71f8757770e7db6b11152be0f9b725c28cae29103adbd06f2a46875e777bf9c0cbcd70393160777b4975b7971bd5e566b89c185557c46cb75cd7ddca812ac5ca81ea8159eed01fafde7ac00c65743ff07cae25029219d33fa8b9c15a3494ba7124a278d33b4fb3d39f162c8923823bd2c6b52924b2bbdd55c3bad77d62302700471014664b07627a58418d10a3e6b33d711fc1752752b43132aa85dee89a7ee5f90deba3f9add4375c0834f112a5cc902d3938a99280aa558942834636bbc000454352ec09121344e384ca1c4062c10a11262668636ba43137641c293e615e19bf2a1503ab56591525ab548faf6495d311b0acfa9b540c158b8ca75eda82b84d62a4b8190421cb2ee6ca3de215062a739c9c589cc2786004c12c31220c6e1eb5ec24b8f75e10688d113664f7bf3c3ce731a203f4ae56272c49aad5c0c60898928ce2a9090d513e7e50220d6bbabb12d95b7077cf41e3e20b1405d0f98a42e5c31d7ce99169104df402957556ab296d52135c8178f5e33c5e7e00572e4f89ec2e573f84faddad6fb96a5dc7f5cae3fbe61c6bad1dc81e19761015db76e843c5aef675469cebcf5abfa5bbcb4fe24e8e7bea8107cd6b401a9e72c84f36f420da59e3f459f84929d34cff822bf089c86bca74a64cf14207c26851bac280332848c3a4061d90f0f2820d1609262ce844d05fba284890f13e2341a2ec0e900c102f0a99219d8feb5bb02eabcac08fcaa84ce53891c6099b312e4f745cd83cc132fd1a4e4f2e642afbb274e20295659a1a2b4a9214875204c8d761b921cb8624518cbcee0bb08e6271e2224695a513975abe593a71a1e59155eb88f8bca99494524a5f520d389a1593ae6815b35496535292873e8b292008e680d49f863b3afea3051eeeece09b152b0ca65680a0f4317705a89a2de6fe48c379b4029b98812b8ec3e0aa05c88613e2e44ba284c90e243733ec9041cb0e205e0dd72c9d76c0422064f36da0db5eefa5627360ed7739e914f2beff6bd052ffb1877a608bf9825eca6a512be78b9166fff6cf9ebdc5e7755c77b9cad9da37ee5dfbc6b6dae9146af9f383e21b678edc302ce537bff306676be6569ea1ccb1e4e3a04c99f1faa8349630a8148e3a7cca686400000043160000180c0a06c40171489ce6583e751f14800c5578366e583a1eca4391400ee32008c2208601188a6100620c32c419a51852cf008b1a98bf1022a9f4a06e621a63c612ca7535b7e9fcf48955789379908d7fe9bea68985215535aa0ea5367fcbec69d021a7126e7cfd88fd07215ed23595d30870be6167ab553a9009c6631fe8c36005d1ca495fa5db8c85349b71a1cac9eb4cfdbcb08e8949faeaaa6bdbd966b18c7893d10b96618af500944b001fb8b353828907bece9286209061e7582aac318a916c9567ef75ae322a9ad2cbc090b34888adb07beb3b14e2dd339f3387986968100826fe24e7e34a1436ea2b853005b2ca74ba71274e480fa93b1dd98f44d913eff34ed40dc2db73449e92253a4cc518ef0a3c23294bd564139486d4d7568b938bd0b8a7983da637823235d24208ce29f7900e745f21de28c24f82a103604bdc6a5cf2c2c4e4ddaa6b8b3c4b2db527a5410337739f00eba8403162a8fce8420cc7fd6091d9d3348dbe9c31c2b3333b6a5b82972050c0e67b87f0393cdbab32cc5f427f121c9e8bbe36f52d3213cd64a733823ea65cac56debe25dcb443202742290e30c7e2090c4ea566949e2675adc67251c3650ad6bb9a933bc243777f1df638b4de1e12496c7a1c9a777fcf8539f5916008d4e5305a3a56b74a2334e92bab4cee7f68fc0e44a47107bf1a750e7e86f16b8c1301ab745ce52ecda10ec5281766d88ea3209212a31d5dc38fecf0556338b99d5f750c8ba8c1868ce0a562a8778ef704e35b88439521e25bb83682b9970a7bbee387dbd371a43857081918293db9e281a4f1341509a8e4b2f8ca3fb4cc8174426a9beb120eae30dda0333246d48c355c8e2635c9a86db6868dde520e7979fb29832104cf0eabffb8a8a3e58126ac5ac66ece8a4cabc408961808f57eda4185906fd2ca8aff827a59d71bb29880cd6e03d5d236a90a83debd8001a553ffe18be6bd1d9152ee184cfc603ac0a1a1ec5b0050e41310d9300068c60d4444346f254ddc22881fa1b0006302ab1578ea46bfef5ffb1630e777324bbe36818dcb0b04270f6fdd86099fc154bca7a97e4c055bc699294fea2c2dc341203035adc9981f0f4a2ea58e8e0d6efa907a6da04c33d7f6a3a9792e94f18771e6ed5ec9e3e0dbedeb524792fcb4fbe0e01025a656e1e7481c8b535e66a6c265b964abfea09ca1cb632c63853f4d32cb9d001120324f0daf9eca5fd6ca17eb272c128ad4e9ae2dbc9c38d919953532daa573a120bec7ceb9f30ba8fce5ccaa0c4aa16f3cbb6de7c94e75a0606237d51b8e2d12ebd1c86bd8cebfac8ed51b8e23310c05de1714200a576ef22b10dac69f2c8960889be7ac4fabe2d1df6aeb66ea1e8bf5c1e2cb84938297adedc1a9c3d3d159901a6cc5ad175a7d5e1a9b6c221ae5fa56530dca85b03ded16903ab733ad92d3df8466f5440ccd58255baa8ca408d4682590aa93ecc2174f4095f53581d3708b2bed61887b3dd8ae3c0808beae39d257ade0eaa0535e7813a4232f1cb5a652d94a8ea117888e6a35e8ff80793154ce0aa0cd9632d38ad123664b3705419fe5150913fe6ac996798dbe57bcd3df012442e2f58320dcd0965a3d6228b078b7bc64e5c8ae447b56ba2a2173cea65c0cb0e2c86e6d9171b99914c13d1e455c46c8e3be6815a52ceade03ffcb89d08a7efe92071ea946841908ceb3b0d15340ff6dd71caef6bcaa803fa5dc715b868d46000bb3c03a8ea97c9f95e4bd5c7251091176f100644c03fde5d72768c201b37236638f8213e164ad19552f1708b30b5757c64a6cc52e768ebed2c2732dc676437b50460248a578fae889b5bceafb4b4aa24d2218a7a128f6dd9bfdf1255f9e04cc63de24374184347a878eb7cefc8dadb6b0788d170a64caaf4583c5ddcc5f9cc257257b0d026c1bdf99573b19038bf7ddb82dec2f3fc13c3bb7a45171484f3ed497822eeef64bb3865914ffb92fad998b061e43dacbfb678879a7bc8e69d2c07d45b247f0e6f1a3e80f88a8874beaa455a2269649537f3c417c9997c989d09bc74f0a8ea0c33e51219d2b5db7c51b33f19cbdcce14e0105bcaa2c2473f4bdf7b4fe1db8f52ed165fa7b9394f99637d50ea6c6c36d019c4e9a85bc15e46b230d37ec48f1eb4857b4f5d8d097912282d0818d62bf89f8c7f66a90db424e5c3931af233969b380e2fc991c9c17779b74077c047d45dfa7949efaaf73025ea9c195c060e1e17949ffe7690d7cc553cd05dd421411746fcedcfaadf724e1231b660b462c09d187673fcece684b18f98c7a1c9bf856dda90d9a2df2e51e222d7ea860a63ac191cce04373a3bdf568434705af1137706eacb37be67110da399392245218c01c2adc210ccb465529fb69c6a1ba8505f73032023a465170012abbd0026dddd5ae4acd853a144ce733ac4643b2173ac672aec26222f1044e06bc465ae53748e9b1cd90aea091d5adb75056ace5d4e740bbee4980f43ae7558e849bede8a9e86b92d2d5593be70795173b627feaf560782c3ec3426cbb9590d8477e8b9d577314369971565eab5d7a55a6476b9cde85e5f09b58d744fb10c24d617d59100811996043ca3cc4ee60fb4af2a7aac1c481d780b22e49ae0052b8522762b6510f361542f8c41a61a9ecc593fe06080ab86a1bd572cadeb5a982cc62eca63cca89787ab263b620efb849d7df18e2d06c31b95ae8650a5ac02621b509bb71363b2aacde3f56e1f00dc9fd41ff1a2d2398afcbf8588b301d89f8950ab1286492e1e07a90b6678fb60120c45316176331799d8286f4572e34dca9510ba66805d0d489e452fda2c3cf65ed78f3c07ff356caa0b7ed3b109c36312a04aa3e47aec836ae5cf16c0440188b3c46dd55954ace54c014914d5ebb7e6d249c85afab639bc33da42d46c3704b334a31d7710f59714149a44cb46eee4955ed937a58b57e0adce710b1a5a8b7fc88a938942a377969b970b41c65a20ace51c76ca278db422725c35676ccf880ba94214352445aead9610c5489cd5e3da7403b9c539c428c7686c67d9aae444b1a3b2e74c65212b3942176495227c02cdec3861396327025e7e59799711c5601feeb80fce07cf0af0de14d8dd23da1f534dd90451976be04f298aa65f0df906cbab656957596c0e1783ace613d410e53089654614c0e211e50e811786e7268bd89036c9e2f390c36c2b712aeed7345a7ff45b63d8d47824857de7c6d43fc4fe8b99461a9cef5081de0ef3ac4eee2e1184106115393c454b52d6a4c814d2943c9a321ca84cfeb1c7f8b9a51be8fbad3b6162da6019be04030f316ac818159c8fa1fc32d1fd524380a06dd291a3cf34845d8958099ad62391b8849bd07270e8c2ec9a14c483f8fa86255d5bde47b0d9ae80704d160f22f7b6b384f49dc1ccab422171893fcbf3e4efdb63ecab98c1503d39dae764d6e5b99a773082bb727bf04f5148815a33c07f161bf53d7fea67128d12af573f2a7eb1e636a69b8e523d65d655a4132ab904598ae8b592e63420e2a2672990697d152e379f29242c442962ec55c601cadd34bda454414d56b64750d7a424e3825836164d59536d4ce787baeae67215eaf1318a2191968677c160a897ed6a72052c687c51618d0ca320a519617cad8e890ba66e027f067fac3a2c8c5a080f4e4bc6c13bb95072b271f364aa9a088baa0f665d199feba70bacfad76c77f631fd28bc15a161d10128848130e34b8c8c8c08aadf18c5b3cf1a4801091d9723c5b4bc5fa4e28288be95c0712822dee11effe511e9941d8970887bff72be0c2c55b283db64d1dc85f7adceef73bcc875fb3d77d5fc42eeea26fc4df0472010698d61cc47afb395d1078790be4c9578fda9cce0484a52b5f96c322e02f4820aa0c00f8e0bf03d1896114c55c8db77b89d885f467da4fa17c1b0472b9c2c0d0c3fbb4d616a6807a02f4f48e3a41c41818afb8e040c4462c5798d80f03e2a2f6a3367396edbb1a1514a5a0b796c8ae9d9ba8a1039ba46457865654c985a8dec79b0894412b200a70c593541efa96bffaf2ad2904f25e0fdeec2fd66b914071430e86b65f0feccd9239439a311064f758c89210bb87eaaaab9df5addcbf8810dd38228d1ca0b576fd000d810630efd0fd3b9fedc20aa14a5d33e6c7821b5c112058dbc847e4e4d6076e1332fde4a93018462a19570914ad70c35af96c0e9035e14468ac37cfa6123e1c9cdf2f3b3d861f4601c0eb34e65cd8a0e172b9114c37a01a9cb4c212042a118643e2b8d5056b79fb75a9c4fb0f46e983e25429b196965618e1ece14b4ddf9c5fe4233094807ba759a3d5d085e6b02fba89ad6cb5ac9c85344e71e33a8b99210bcb0950a88a250dc6d61db6124a555e8228a65841b1662cec3916e8f798a500037efdba1ce45eb59f917a658a6cd7d4c6b9202bde1090da3204bb5e967bd03df575b120c58f97382e5d15777c5d23fe2380f622a0d7250b03ad466020e71cdc7b26d80376518fb8b24d290db9f2e52c265fea166f7f833a70c90682e50ecf13b4c4c123b463506316e11440397ba74bbf620836411cc4835e542977a9fc0c85a83779a0e0044ce03e36460c9545737624a69cc34eab8d7614c8d945c1df55b98691a777197842c15637ff76d4605481377276e4d37276315597f9439827616ed8bc71bcccc39a624433ddfa9f8a655d8d9e28a68199033ae6bb424f37fa0aa291d651ad25915c5121bc6243262e5fdd38a176905f4d867776e7daa17a04e2800980bfcc61960927b59241a3c792b63cbd4d7aa08e53e6ad6495f728494c64e4fee13491f8b320da82f1ff29968616d629b3774b3c6e5f0192527792993bb87fdc917ec5f76813eb73ae192538965402243ec6235940d5ba950dfb82a0bcf07102e08ac0b07240c01dd01bbc0768b1011cba42a3581f69d26f9d4c5d6e80fe9200a507adbcca1894e5200a264cb711bb0229634fed36047eace429614c4c378176260df566bda152ddb3336a11e3a9c7300decb370b42478d69806ddeb3628a971e4c0f746820f9d1c256d0b905ae3d951775ea3e3cd6ad8ae80b9012962340c0b1c2b5b4ba830ca3630b2df4e9693b2046068ecad063e7688d4fe573e0d3e4ef7e0dde36bccd83b242758763aa1657017467ba2d32a12a73e6d4b6ad0633dafc17d6e09330859d1a9965b43d7f37122b0ddbfe51a92d2ffbad2a7def51bbbeb45e6618da2514e0f9f8e69e206f34bc37fce5a11e1d4916030810b42437891a8281501511ec746dff71ff7b004badc428b6578a9581002e3aa5050bc6141689166aacf53edd6f67715381511fd491f4a98a4cf75a605473b247819c9027b49df63956298d00077884d8fc77ffeda0a4cf1be080efe58107df70d73644361ba6b4c6711315b40653d37acbb4815a9e7d5674ecfb2989e294f6402017a60219cc2a9803292616fc56daef48c3cd9c3bac688653ebfdcdaeb7ddbbe748d3acdd651ee2c26ae1a654cfdc270595eaa6942e24630bf408903178b9d72ab3aa9174aa7e5dc9be158afcbf94936c539a7fd5f1c3948e68be29fe602bed2075dc2b6332ef8c0e5bce8a1ddbb64d600898ff8e8daec0d215a97da5c519a7857a207d3fe09b31c2b031403cd93802f278c8a91708105ef1a9f33690b3956be806ff105a1315a27eb2fc7770949863549b52a87c1ba434be465bf3c38caa145c602570b9f39898286c9119cb35ec02fa0e570f54335403566755ec4790f0e6c1d5a5da4608ca2b3c96f548f203799885317181acd677c7ca6bc92429151384073fd378fadc4a92e81ead316dfbfe3be36444995d9bdc0caf85c58c2bf4d27de6be1e9215068fadb413df92b4aa9b4df0eba0559b908b82a3982dd156c3f531aa4327913a2e0b2043f1474bbf5feab5c99c80a34b038fbdf8ea19118001ff1616a99a5617bb9bf6b53e68d29a33c1dd71d42a2e36594b77e64c4038e50eba4f42ca880ae426e33b75032090886322df566cc81337d354101ec574ed87d302c54fbc2048430a47e9fa9a0525b33f411ed5fd76738db4804397befe0719ea7c4242d89a5b22ea706f1a3f05628b610f65ebe55d9668e7e8f34f1df4b5541d27885b229a91bd9eb1bee1000adf6c4011e0874855474644ad78dce88eadaa479ae29e9076cd10be1484660443ccea0998e2fd7a86cedac408cf159f4f9e5ea132014ae439b15127466e657e1caf0607a32d53fe3d03b955007a8b2c9261f6115467da4f2f68f6ef8a9baaa9cc080ec725a416a8922a2ddcc7041405a85ed66be575659085e2a65e7627b51e2ed820b96976afd7cd81296c766fed6cfed70475d3bfecded99a1fb5de384402973ff6dce8938587d1a412846c71e72036f43175f4dcdcc71f2e7d3c4caef926d3655bc6b753b9639ea6c7ddae82c3d80e4c90bc48573bd3f360bd7a9578b55469b823d8ba28eb68ccb7bcc228baf1e552998699bb288511a67e3f1014795b5daed3e8590b4f5bbb04155062309fbd994b81dd02c4d1dfce6eb2b906c1908a6b651062a1b7ccbcd5215f0ff3fc029f54c010e2e740f1ef52198137b732c7c15a87dcd4add0208ccf4ccad386929777835cff0f1725fa6f62a97ae24c3ede14c1eae475c9ced3aa7d238b0e63591dfe32202c57e89cdfb621f3e392332162e7252c8523e30427c44854284e98e838f4653bee214ea7129e331254d9d5f480ed29d7a3db98880b9957d21499e7ce9b08e0857b60bce0784d5b0ed041ea524f14e74b1880e5dcace14c24a1a656ce1e04df1cbf34b1a9afbc89d159cd2e7326392e636ac77d9d05c8c118cffc842975733d97482c62639fe9489e1baf0471f2ae4dbf2d6626998fabed64fa1a9610a9e956db66bd0b1fd9566e7280ef21a16ba8a4ef19fcfcea9448de99217f99d930d7a1190576b08abdb4a7f29f478047fed015de31944685e6fdf31ddeef8f6df0703de742b10a0d867e49cc38d6823182db4f55e8b333056d0a9eb85aea57fead06cc50cc24be77e6ff8cfd3417ff8a5f7df741c33c027c9db511704cb064d68f171c83c7dc24d7d2d9e1e2067d604e24c9ced6dc16dfefc52e7c6666cb2af0c6561ed1bdb961cf07ae12beaf8731a6e578a3328e676c558aeb15cd0ad7e96f3b42d7d3c2babb824e0b7bb40f69d42e1ca74fd3fa34d1e97e1592b8de6919417662e512e2a773afd1f12031fec6fcbd93c682628f8133501eb4c4c252063c92e814cb3a552195efd09d68b8782c058066b0e80205f4185d30cf95560a0733858ff5a6b8a6dfd4643fe9458b1baa61d9b525e6610ef6fbb4fe75453f029f0a714c496703bb01e835fea1d7952883188a4ce41c847341b0b04038d5e85f99be152125210b15838b94c6bf9aca972c393ca855c4d98e3c9705f40d3acf94a86e30fee4f40875b3b787365feef4929f450a628cd33416abb2966b19eb05b66d500e8e22ae78dcd522bc65e46d75eb6cb60f5c41199c442cffe14098956c915263c14830a04c7d55c8602db19e1bc37d45fd07568ee883f731aa907588fc514a4597a6d01c78026f111c81b09e72fd1bb5acf026ed9f8f975914bef21afc93960d7ecdc92563a9c6622ecd6525460af0b11fe89994ab6d57d0b3468b8c2ba79c5a41b237bb3299721c6651abb60f38d2ef1d0484ec98650f894cc8ec4934f8cc06482795d8b80556dc788b0d4ba0c416bb8500487ce26a01dc362c7f8bdcd70ed356fc3d4269f7fcce8dade5323fad511f3aa5be5711bc4cd28930519ce71e5f40e1bb63c90b3a15973ce27c6f679ca87a39bc2b0fd4b2ad12ed81e1c7b4cd9bcb0d647db2ea0ad6ed278beb5a3d6e28c5d7fe63c6c364e4478b2be25b76e2af379246759d07e797da8a545505338a7455cb3319e046dac70a5a2c819caf38c8162cf5002bf7efada0b1773f58b7588a67511f7a59efd38ecb11640c6ac423757ae05bc323e9cce1f5ea2201497c138015b00de10b0a950042cc5b10519126ecf8e6ac546691396630bc11214d64dce3b15771415dc6208342be1930c67e7050f35960c21f7bf0c163f36dd8a14642547a5c873142c11cb7087026054b784a6bd1a36d8e6cda42890ab61535083396b0152cebf4d5d3f8dd5c139860912757822f437e50d0aab4efac460c67a4e97af5541f3c42acbba34a95e2ba2b741fe87c13b9db8a3731490c2d4d92a6383892439a361ae3f31afa842c09acd5c731dd331c4b516d12cc0ccf5e4c71914c496b6433a95bc12bdb4cf985484b956678a7a70d2241288fb268f33b811a0b90947d622700c4c58706007362e0c5916152888946c3235bb38f789f0072ef110d2585129a0f0e4131ac819b966015330fb5a7ee796defb2d0fb19dfceb0394c2b660e8895228121808c66149b6f486c5ca5ea1913d11ca817527d77d9592d329f00b82baa3b824c4ae2889f9a097aa6280c6967a6be7140b4572fdd60fb1775cb0a69235580cce1210b4ca6565708acb0259c096b32a681399ebecda4ddc53114b422b206b714482472546d6324cf7042a0c15016e222e173e45ea1402874d21f7db84626e3fdfb9a64d05c4af3e238746fdde1f19236b2117e45e40dab4216f0ccad0094198ac450b646132317c9f212b02fa8c53bfa43c48bc1c4833df6b8d5e5abbd5b7f9444261d0a2272580e64fed2dab0f3275f46565361902d49f787092de8ecbaf42b249928f303b48d87ce98df308ac2233964305406bbd4f630ad0e3c5d37df2e425344b970733b4e8457f74d7a98119846e5e46cd2ecd10287131b214d6d390d48fd87ad627e9c75b1c3086e3b3122f3b8fd36df623422c0541da1675a11f1f61a5d5ef36437a5d098aec7e0c3ed3e4a620306edd592558965c02e48a7f0c4f4c33131d5f53b6651886af437e410945198a8a7db9676ac2f10006dc23b51966512671fe8884fa624fe212ebc45e895b84fa6c63dbb592a8986481ec584783cc44ee4782a1b32f8b26b87bc973b73e7fc6d1b85891be0cb64046af3c22a625f08c270534a5510cdc26e0494828806a886d928a20a8f2065982379533690e19a147ecaf20c27b88fab0f4249c415b2a302e49a66dff1a03305968e7258efc05bddbea00f4dac8ec8b2fbfbc21039951454d4113dc0289922549f18b55460a210d5ec598212e7d2ee15104f284ff11592130a9458f2b5947aebe1734d274c9539f1d3a2ee5f20a7dc008b34f5eabf26e1de7bee08bbe3642fca133edd5c5d011037b8bd28365067c5917b5b594ee2d0303a674a96fa6c9a0bfb93fc12ab1add7546f40bb3a610a6efa5aa3cffc7c7baba810e5cb8a2dc65e4d2ab89248624b661a14633711badbe639bbdbf8ecaebd301529d74ff2d8487fe99fb58fc08900c5964be027c3ff4ca1d2d6db92dba7ccce06048a49a32b01ae8cc7426b674e5757caee455c08323d9313f1dd075756074bc541adfc06305f685b279bbe6f810bf37efa7b7a07d88ab7da17bd9eb01715878db77fd966d263416caf5a4e01b11d7b8bb96751e29d34e773ac05c2a422e4e98440dbcfef2646edf5affd31744b4e6c5320c0888a1e17ef9c904d5d78ad4531c070787869ee403cb13ba3197b2b85f122f5784597e3fccfa2ff1b3408ddac7a774906bc7c048f9f31d5bc8b6ca886aa5ed63e9de06091d3555bb7fb93200c16145f893513ea9ec6095c0f03add25cd8cceac6787a88f7500026962a8029365f9a496afb23484cdaee6b9aafc8e154bf279c79355970a54878f0ae63c9d82c683aab2c726c6f7747cffcdb4259e44069547d2e89f13976161cd8600d45f62787da8020de8a45059027a664faa4458e3e856c5f31e170e7f930374968ce2f2fdbd938ae4dcd02b85a8ee011a74f35a076bb4c03dad401202f403984c21d8fc0764e41391736c49d9380905d9c09d62abcf1c2be2dbc54f0a528c5a3a7482a47ec45fd72863d5674d733a7109ddab97ad4b985ae201bb2bd6081965fb031297d9415a36be337988beaef1f6a6ee04091a3fb2921d4a179dc9e59c58049a565f98ceeed2341802f4b8e0c785b4b411c4f3dca8dbcdf62c1688216ba53a6c601aa442fc7613bb1228489231f2047d47bb20fa2ea4f027c632958fa19d0b0e1f513f414848a1c604905fc560789db740f673fa038edb334948132ed29acf4bd9ea17fefecf62f309c992652a1a0c5c0c8adc3d9f495950a7c8a73a50918792b1406f8932b967bcabe667c893de94aa26124a6116731cb72e5013c573fafe7ebce708fcdf0412e70dd941d57f77d60706552feb334851d6ee34c1f22d70bdb542e05490cf9708607e9eda5f5959592d0c37698f123f2b01fdb4ee512b4012f6a41c1676e2ede7f2bedcc901211efe4749769bdda72f097d29d91474bd0e76c3c169bc3aa53fe22770df295345aaa07e5825e4b24aa1614df17abbb9d757a8d834d38d7610a1de7720d1a64d3c58313859cf1566c8c576fe8cb8984fdfa74c60c59283325e547a32a633c6a01fc24da4c8eda7e25102240a9b53a4aa29a9cbc5ac034e6b4ee6f96cd0d245f362a64d80e58a60e0ba6c79680c829d0087f48e188f22b79ac33c2b17061d095680f3edf744b11222a2fee17e7f5eacb62857d4f567ede95e42dbdb7f53601405f7a4fcb7c0cb7dab8757e8f143499327533cda0b90dec8d41f0d48737303dbb067f93599c5b146d4a4ccb14c5e7818c426a4684f7f42f11720b52a440c0852f5380b5011a621c83cb757e03126a165d1952371e34dcd04a72faa6500137fcab17cad3ce636494e036d3b8023dcd9de2c25fa0278bcbbeee7d4ca49a74876a98f4491fcc6c5672a55fe34d06077e2c03c33a4f290e80106ef70c1821aaea202e0a43940e0e19fc14200f9b41645fad38c214141174fb37aa197d8b7b8a0c9c6c9a72107220efa07a79ebdc8f6c22060f66103754fc492e35523302654e88088048822bccfe6c3021c7ff49281fe94ab8ed53c2295389407bb14d5c29464821b884a709875bb39eefd2727a88053659e4cd7b941e41c210485153fe162052934c026e55f8232b388ed26a84f555d38c3afd575a78b017e373805fb48a8a632c87436993aeb5017db7fa89718c5580047814244d5433acfea563edaf6253110c5a40fd6260becdde2b33f9fbb1bf8797c86500facf722b444c4638f057bf36c4ab1c9dad666f3e10f754d1ce631e483f36dba4c62ab33662e3aaac32de3bfb4f2dce0e82f7349007cb13cc3d282e92c052005c441a7a6d9c0cb614f7207631f2eaef0a83bcaf3f7c4a8ff21c0adf11fc9afda6a8a4f8a4cc6c5eb5a51f44b87d67c6a115450f1f3ef61a65418e40d9b95afa2f25ee68f0286669189c0591064bdcecdf2c991ea0033405525efd72c8299a3ca17725b3446f2d54e90552861f72d0af65d83dcce92e1bb99a3faeccfc47864bd8d537102c990be459d59d1fd0756dcb73c1e49250322a46b35a284e24083eb98a11707043a1e39d5b7b443887559c45133031d449ccecd2ab549d2642820dc692c4921fc1fca6d5cb2d29ac2e6815ea58896ce04f5f2c0f63bb6993744770d9d10404e34c8f824f8213d22373ee2ece4d92305a8fbc49699e5ca5b9640844de63e63a170839c5400f2cdac5c740303bb63c1bdc8c613f4ac5c9403edc6a06b2a3d0970603facfc118c1a4d1d0f9b26eb80367aaaa7dfe7a71cad9a70209c34775caf951af3d2ea998c5ade4e1645172a476a259c7a91dba3e9418614c7bfd7988378b75be3400d8a420836ed7379e6ad1aef2fa5fc731d0ce2e582d0c69839991944dcda1ea2785ffd14388aca603c491a4455af1bb4bde6a277d7743564597ee9560974bb2a0813669767c3169e3a842575d9c05baf2d1f02c6c139ea8e6d1c3eb43a8fa920f8aeca3834c2c515b11ce07cdba5b07dd0d3b7215caab3676368c34d98169abc8b2b9c8534cde8062343bfb09bfdde03c7b64a7ebeca4fdad7e37c2a1c2857700be41e2f4fef2d3c5ced3a34060e64402de9172c7b27688b187c4416053bcaaf1b3dd5849bb2a51a6bf4495aed2cfc7796944d3cd64b90fdd1c639c91d23cc65305b38f359443ad0b4e367186f1533d996233607f380dcacbeaf01fd637f9589482bb05bbd516ee4890c77d5ebac608ca29688f0c64159503ba8d5e2abfb420455f8136f822ab5c44ab5574f5882d167c4b98a0d80a0575cf076ad4329a472e11c445f2fee635bc7df484bcbcc3569ae911a4b7c9b691f2234f3f187296a0e48e441ae0b46eaa954de893f4a27ed5ed1af1a9f7192a418bcc2c6033e4f57e1546ca52c2dc6f21749bc6ad50827167c2d67bacd96d285ab0ed204b00700039e5316cfd6391a2fc12f524d551ce50eca9cc9a5337e0286043eca9d5bb49eb48337877be6ac6dfcd320ab25e3631f2341b94d68e475582bdcc7543bebf0a476b6efaff9bbfa44e29d133ebb8f9b58a8a12ed1d3bfcda5680082d8550f4a90ca558f6e28866a56cdafdc8fc174e46e8e238f7b61707b6494c16b3e6cc090475a5ea2667c77e35dca3bcc9f9792f0ec0c643d9fd2e2539574ed2eb1f231015538edf3ebf05d278b5751641263a8438a224cfbd394603123e8163a63a5fce852951c8d5c000c55c40848e3b42c74ea062d42c744ad8ba7710261141f4764ef79259abe8891fe7b03653098d1828874e7d380f0e93173aaf19039fdb7e391b7741bdd8e6fa24256257121086002ad2460006eae28aef92599a05614d8bad732264121285d3c7bd1456361a513018cb9d3efca0cc888532e8b517a02c86ec2e9c2c575efdad3b9966b0558f16acbf08dfa54a1229ad9746615f9a3cf43a690f63fac1430254f5f201100e3098f4d9cec0271c2809c763b0fbc006957527372f4bf90d828a72b290d242446cb118ee14a8c794730f9bf16f6103ad92e3955e44a59ffea13140f13f20b60b6484e5e0b51c24c6fa60dcbfd705b6ecd2112c647f5b08af2d7800358ff167ee6b2abe54633e9674cd416ea40d1616fb78e17ee9412dc0b51679cf17a18d3962479a4e8968e72eff3c52aea8ec3d07fff7231d2d667acd70427f82d287e5efa700c84cbd3816dad26702b2d7289faabf18d99e9fec60d1636cc110a1177ce5a70d64e9b3e0567d4d3421ff8685b01fadfb142d2fde2311f87ee2105c09e31062b0da44874861d978163dd1846ce2cabce1445f140e14018ea18bc65215022911d5b2fe8862734357263f14a74641d0f94588e68c237842a13372c83398aa41f249c14fc4649d10ba23c9b88781bef9b236a31e23ee79b7c6980d8534a5b57d770c052a65abc339379e454f9b38318d92133366f610063914185bb4da80d1003f5e11acb96c8ab322fbd083fd0fb21f83f2b514d8c630b621c37c0890ac68029eef14bab3e5392028eba0778e4a95366caabbae0485c7dc792a7238c254ee57ba86906f3b03c8e67ced666e054a9f30677e9532807b80e2a138b150e6204322a0b0f20de12ba8f2e36ee1ab9f01cb18ac934d622b98fc794978a511a8f1d120f0a775b77bc12ab3f5b1b64b2efc51029f3495a3e0c1cf01a0253558f5d04e5cb5070e2083b46528d45f7ca488488d063e290abe14f7a9502645ae26104630800302316943e6eb998f02c2135b9e0f2f2a4346fc63670a08613453b9080eae99faa577d0aaab1cc2d277ca42253933d60ca62183792ca2cad0f936db20df35584006cbd7600aa748b05be9b5f40baa394254c080346941a0247f79b6558797b0e0a872c238564ee20dbbf0c33d404f810ede6aa023a1d42ae2a9d235a49112ffdb84b944e5e4205b81ae65dcdd636b7a1cac033761014aa5bc7bba4fc7fd79fc635efcd5620cef59969581e2c92d00e40f25497583daab4dd0b0230c23ac57deca97098faaf5da9debabf8bd432513d82c9fdf27aa1b494c3d2248a860653c78b84c2d844564a5b70543147110d4264539cc5bca1162bc073a97baae893931994c7a7e11cc84193c351013f4d3a6e329d5ca893741bf4e6fe06a2dc206ddd7992081edab37cae80a082565cbe2199dde4da75efe16f0fb0d282bd3904c4a5bd0bf86acbf06823ce34c8c33ac0fd6abaf25845b21f50443635ecbbf762d58ec70a2d28eee9a195a467917ae49add0b33bcb52720e8af2ca0ceb6096c2a537b7881b5016528bb9d567a6469a14cca394d3fd4799f3a940b1d07c51c20646a80905acb62088ad45fd2609295b76b848dc6ae6f722f4298d9b4b64e31ddde1a491d40b8edad5a4eba0b0cac26769d8e8a1e8f974d9577b9674536e5fc8bc3c28544720244e205ed0b26aab3ef2d438cc87e5f5ad6a31131331cdb274dc8f69b5bf5509db95cb152dbdcde70285201ced83cf4dfe580a8f0e9e7cd04b7730d0c84cd20eb65638ed94eb939604abc125c2edb5c816cd71b18a1063ecf515d2806b54898e4dcc683288e77685ae05703f853b6e3e6a0a3b84ad8d4d17373480ba5054a728b4a8f74a21ad63545985dd28a2a09b5020a655a2ee310daa06724688689d033b4ad69f94d05bf9c08ebb6c04be492d8807c32a1fdc37cec70f7106f0386f3d746bfc7820ad0f6cdcaa15a624b31e9c022eb0b2e1729ba27fd5de823dd536cc80ef560d9893de9cee80a359b9a09fab6f5c8f13b100d90138423aba75525edd633febfe06af48be80b66e391f3e330f5cca497b0f8e3812cc3fc112a1d65a81052d939ee9826e98352207c0a3fd3e0d14bfa8e0fef0b0c5d87cce03031de3baa67916cba363d6e6361f66cdbd24d4ceb3ffb1209b9ad9ba68699c0d40a6c2d84d4f00690103edcd2c431d13f2c5bf1c8547219df347062a6d1b0644cd6c7ce915e41e66363d820d96cba3d0951594295f41478df1d218efbc796c5076253a9a6d834d987e2922191d055c2e301c5abd16896000bd1b1900f6de4cac14beaf57ee466768355310817e24b9bd1e271f0644f93629bfb3d35f2ae40ea333e2268a82a90cec87d551acf07411d63a720dfe9a15119c4bad1c98e10eaf513deb05e6626730acdd77479135cf9e38cb067b122aaddf979983498dbe4cf47a146b75f8987cfa8795c28510f26e38316d2ff410966a3544c4e0759657375ddb29702f306f20a86b9420cd51e49bbf07ca40f28634d2d3e02d30c234259c4b60cc59cdba17c205050481f3e27ac16f284edb62b934d63f0cb8c97aefb776adab2e8b9412ecea82a25633e1898c124d49ab4f995a80b9b290d495193c9561423363efe15435db3fccb8c91a50f70ef38a6888750bd66426fac201876bba565718c4968303ab3eaf8278291c8cf29a44af66e1884c13c5c401175d4d69f08354baf18b2733b1d2f4b9215eb456a6142756226078e86586c1c3b3935e4d43c3d84a1606bed12111a542605859ee6f6587993281892cc255aa5ca7c0803660cca484b57a21a995193c2ad304d365967b048a4197d616ac97fe86b796ec404653f13ac58251babaed95dc0665cd64be892dfa51b730755ab181e4c08176a91e732eab3b9b2254d2c1390ea85409997c30278ad40eacf6b40b782ba84f88997ff61c72007f067f28894a1168f7fe88232ee03f904982355121eb64cc4e4a8cca9ee410b4770f3356827130e1ad67fc449ee98e80c876973882ea3acfa6cc2be31260f69ea513e9dc97b2374c7b2de435d9ca0612f194dbd222021af600bffba46701e38026a3e4b64ad92d7c518b23d6bede01b8754ec8a40522b7e3dce7c60dd2a3953b80f4ec55c60de2ace33613ddb1db07a7ff1a422da94bb4023e2bdcfa1fc51603bb84f6e9724c1125f9267918a515455fc9c1131913cca8240127b70e70ff26ff30eeebf55b69339360d2ed18cc2d1c18c6a50bc8e82dc7c3c73440798f715a487a3f39d8e417c67dbdfe2b4d26d224263e8271dea65817b05ee9055293f3a206a0329338ccc7d5f5af7699101399619eb743ff05da9436130bb664e9b057999bc858531b4c5907c20bdc9758236d7ca7484d33e3bb7d845d39c04bf1a4456a45d4bdb9caca7a49304283c63b02bcc3f7fe094495be7386d5ca5a566035b41b271e45f8928cc841a372282604559cb32f1f13094af3d7498275e0f38dbddde2921e5c5435c03feae5ef05d8b640b080854060156e3a871da74085254d48a89d3f2900ac3005776134d0ecfeabd5e5a872fa23746858bc828ad0e1abe04d397a0159354f726ab3c2a28f227cc580697d3693e38a8a6f61d298172046b7cec74f8207ecbeeadeba9953e20f6dad35561fac5bb870b7540526b2b01fcbadb0c2ea902ce92eb7620943e0278e104e31cb672174e48fb76fb2c752bb0ee2932b0778941536fad4237bb1774d7061487ae12f651ec0f9271c9426a09d4216262b5caf02c8134e8029a062356890b36ef3c7928d752f974ef57e0fd1adef36cc4c5b92c445a329d4640d6ee9a87cc3c61bc6eecf598b9daee63678ea1a82f906d7799f1b125aed74df0fa3b1f0ae9361ba1efa9cc31eedc593404eac4c1a170917db4f6310484d5df6f24437b865d403aa7727c9ed0068e0d3f5b8e4f08089b7734308e389aef39800cdbd9d97750c963f7835fceb710bd709705d3f906e1d8f9f1a0fe04dcfd1c573633a4918195d763922145f3e250fa36ca5522b497812b26430509f2c8352b1bed26631659ca7edfdbfe73e7c0728205d97a86644cf416120da01633d21db887901081f003338a0bc8445da0b76cb0b0d670fc3742bc3386b145e7add9d5c2085546b6aef1282ac821be4e0fe458803cace13ecfc7b4a038c518a979e782f9cc95b465e499c5aa685904a155005b2387cd5c82b7b07a328b4830058f15bbe06c01ccbf333aa39629576e526cb75d3d7ee2a0518f4b2bafca05d56f5ec733c7ba63f9a4ecf45240709e6f23bcd24065aa9119446136dcb6c0161c0699522767ed98118e9e834d940e048e6cbaeee2f52e0d207138a88f5e3518061df2ffe112439dc5de96205f64f530a8596ff947fb9d5e1acdaec9ff4054804f4c57b6754792b9e8cc0d6b73b8535610aebb6e4c7acf08ff76bddc7e3a7b06100f2759f6c052a1a68155b188be3db9ae7c054e223ab054d11966ab048f3909c13b49dc5fbb1a5baad9de4721a04ac1507745e20ce6e310f0d85e9b8b7008e2f64fb6e3bed000a393162c61bb7da751c88efdb65838522ea5abb5390bb005bf447dadbec7189a56b4c96fe5b3ad3f75180af213e74e068050c72a72911d7c798a5fbb857d5f7e09f1c6192dc886f0aa962d4dcd7024c3258e07dbf606830973ab8ad170fec05d5351fe8367f42ca3b638bde1675877260f40294a4fc9bdb58af4cd0902ba24356f87578902bd99ad20bcd2898700041b535d01014d0fe6a2f7e66ff739fe0f2795620e139e9b47bc0451585c36f01c31f9d6e7df5d4a06a6421e89d164c2bffabd15c5d1e5fba35bff6d9d0f8bcf07ed489f758ee8d4d4de43db48603ee49e52db2e86ca28a640b81a2d0541dc320c0c18630114827859cf349bbf931414889d1f3a78750717a87227df637ff39c308b800ef0a3295ffd48d67cdf81b1f59a83384b1a23cb43df727161c6e61a6c1ec0335cac8dc02b4aec2054b966d94d2fb0d89f9e314e9d415c4527ac245300f2455a862131cae6a0ceab91d3a20e8357635567642b7a003411c0077b299668f4de73db66808b22237be784e0bf36922dbaad3383459b0512647741e9d84383f21005a3b427504b4ed1af21bda9f3cb04570b56e45937acc2d481840c74edb53154a8dff41eeb474ee4266c4d7fa315f5058440363883cc9f406868b0a56d0650b436978cfaf254a9cd4f018e45d1c034643be4cb3d5915e5ac5a046e4f8b7d5eef42572b1b90b81e366c9dc17d007ab47b12a47e050690d6170e1c8a9b51440d6d89e29a64a81ae4ea7402f2bbe3cac0e5d5e23ec8564043279922fd5a9a5e3105f758e3dd3b04a935c00f5e132a945bda52f62b353133d00abe75130e6104db72870a43ac5e73fe3828469d704e5130edf32729e0756545e22b51ef8a0a3197b5ec2b4d6a6b9997c492b06bdebd4f78db44e8049e47f01e8ee2e1c9a5c3b38f260ea098caca7810e9a8296ee22003b4f17a59072e2f3d392e4ade50b00a585ea084d624320bdf2925889cdcd912612000a1a428d8a38e104b7f43504e93d9dee721166c6079d01391788c7dbc1d71496078b017b659ca08f74b573c72ec78b47c7a6dda1e02e0abf97d50a50e1055e8f73b90dfe76d46eced36129bd076cae36168b7304329bf394719b0b3a066391e323cafb3748f1564efbce2d216bfea746cc518dfd632236923cf35189a29a50378b34e2ccea9d43017b6540d19f615f97958b9709f0ad38b37be28daf3842bd677f55b957737ed334a1966a99cdd1c8d948ef139efd60ad1da5f469709e6ae9de17200ae759e0f5d7b91512499653ac0c057feb4867f305abb52645190a17ee0824bbd1aa00b1b50ccb937dd646ab2d162d28aecf4037a18fe048269e313cc4e7257e753124c6ba08dabfbf6c2e3655cce0729323eeac0ad014121af5ef37c04bb7f52628fa946ef8a34e44c101a1cca2bd3a8a427daddfdda524982de12ab6577ce58cdebc8daf162d91d003843bdd6ae2b78ae0ed2a60b9753fbed9cd6a250f299927b8ece0a88155637edc01c0e141840226f26f421ec6958b5f12bc358734328383e845f52734ce155f25370e410f1b6bdee0b4d9751dfed80b35afb19e7bb6f161aa4c2c9578e8a4755ec6158c41fddf6382f9a7a608d139766115471dbc8f5658332bb40950147019aa181924baae2cbaa55070135d370fdd94d4635c70ff46d743f152fd11979431f1039b9bbd7447255520c947e51f9d3a026c8061aa209d7a6fb3ff2ae5524cc953286ea2e2652b07c19ab2b3bf25af44f06fbd88d2e44351ccfd4bb7d63827e26b68c5488b5829cf5aa212d2cf625bdba2ac1ff1ee244c9576b820e5cb12351b5357b063289066057ba0c33467059f0e9c4c6ecb04d8933733e56959a283574b05e80e1cf9a822e7950f645af04cf22bdedeffba986d85943b7a1493e57ab6a3116e056cbed9eed90aab4c0d349cc3708cb20c53b98a59c16621c8c2323516293fe6961ff6f88d29709090e3ec5aa64e3b2c64d28bc4113fa41700a87b3073e128e480ecd4edc485e19fd8388ce9fad46ebc69d9228d5904d92de8026420045ae51295593090ba4a07aea33faf4efe9abeb13749462f6d5f4cfcdce281f4ce7b9b97b7567ba0a727d1ab37be9a8d107934926b00004148412982150f65ae7e6652560f52523367e398495bdd874b68b9f12c64237b6fb2e59652a62453380927096b095167447df165631c2536e42d420d60e63135ec0e01a106fb8598a0638d8ed4076ee196c73c1ae006f00622cf175b9e7743dea2634bcd164d00acf84522902e21de232474345223907ef7521148ff8f2916024241ccb0a1ed1fd3dd9b7f424aecfc90b734e03267c1dc05f39849a9043da312a776678c71b6dc99d2a592cbddb83f77136f487479acdf1b1a3be3ece46ee64bff429047fb70ce3afdab75b59a9f7db6035bbd9005f086b35ae5231f0be0951f9735570500b2b8bb97a09af26747a43b4e2f1eb9f27b7dadfe71d67877dc6e69657d143cc7f188c186dc0d95cf091b729705c602c4d9c80263b9b5c1548f60b64719b38f57338ac9e2e2c24ed6a2c975a1a6e54d671fcee93f5719fd1dae431638a2eb374c005c612500b4cc2927097de59433c6abcd8f4544ce6fc5028723efd61d91ee48c8a60439c793f07cd960cfafc126733e95d43b81a8755b778b44d7836bc3c60ab0d9c71b5d661fcadbb503005c0eee8ecbba1be8b85be5346f75378dd3bc1c17c7dd364ef36edc9bbb759ce6d9dc4dc5695ecddd6838cdb397e6aaee66c3695ec7dded86d3bc2d75371c9ce66977cbc1699ce66577d3c1691ebdf36e2c4ef3e4dd76701c70dad601003af8f937f74a16fd3050820d22ffd338b87f10850da5bbbb74f78ff286740a8edf920b65e5460863e7ec185d403e6777c2bca10bf31e71c1afe43e33b5f08da5bdf662a085ebd95b332bffb22c625b837398082309aeecf60ed94cd4a2bddb7d0577e92f34c83d926cfc8e7ca5bb4be83b828e15367ef0c4074bd8f81f6049e2e3add58332be90b5a54296f6de65276ec822a17edfefc61bb232faf16a3764c9c7717d2e6b7e64e2f2a73c120c710e7ff546e09c10743cd0db89648ec6c93ed73bcc298d73edb91b0ea5346f47c68f452494f263e1e6ba0cd1876bd03d686265482fbdde21089999bd9bde0913a0c6f4c279e577151b3fdf7eea1dfe14acd87e6a2ccd3363de9a2f312b30d64bc7b6f82b365fb2e81536543f3138c5dcf9ec44017ee5cf18fdd5cada583fdd8904365fcef3fff257385f7dc50acecd2812a7f961438100eac6d7f54f4ea722b6da3bcc96ae7af2279b898e150f823ce282bc4114b18a44d7fce89a9f11d7e267f9c7cb224273fd696e101e983d838c518dd428682e68071bcad74bc2e49144924932e649dee449ce2546799227799227c5a81815a3366fa78806fbc4cfb7e01cfaf3653345694fbfcbf08e5ca27deef4b57ea10f1fb4d6cdbfd0dad4473f4a23266264721e56110d49eab55f721e6e727a82da346f687b24316c9f7a760d69bf7db60bd2be292cfafe729817b911a594524a29a594f6fc0c0932a242d00e96524a29a511849ba2fbe43c442efa9a47e49246eee450f49952a994428335edd3344dd3346ddbb68d861b1db26d7342ad10ab7e9dfedaff9307d513a9851b414be150a860cd6d9b7bde57f052f1031216ca4eff479dedb767df58e8b9a98f6bf0060f365eae5fb8cae837bfd0ca2f7c6742e576471b6b6c8fb3a341b60d7a14f99b933bf9934379942c92465ee448ece32fdf8b9c4708de712e0c3639cffc3cc95bf2e5dbeac38b6aad99b574b5fa3ca081eda608427f9ed4857dfcf3233847fee74d3cb258ffa8a82e6aa37e35ac8fe2d2125393d313548445d851444a8a29f113d20a2dbca064145f3d3d3f43828276b09ee42272499712a8c33ef14a2297fc666a2497fc97afd8d9517409b08f7f6194e14610e217933090fe189ab842be12c215727dd41dced52ffcbb7d46bf50e736f7d9db51d2afda98c1c69f4fc92352832a384f4cc2adfefe285186d8fd514ad6334ac7666e1b2aac7cfff9dca1305d3caab0fd3833768cd973d309c45c1d979b4ec07437e73eec1b3f9d68c33efd7dc039f4df82f42b03a6ab7e41dea2ffd33653340f33ec2c21fb6c96b0f3e5fbf7576fd11ffa43e8ebd0efa1bfc5d49dae6f0bdb4a363033b3f4e85b544fa04802898e4bd40fd506472339cedeaca29ed850420c2f2e6a86170280784a51996144157da9011ab44a1316e8b89ca586273ec4285bf6c76e59cae6e8d3bd41156c5172b376ed208a9d9e8d52c6e9d329cf497d6963de61eea6347653faf2374a3f7e4f297dca31b2a39c6d3f8e4fc40eddf94d33bfc9dd1f1634b3a764f70a4c6ef9fb4b971d91799b1b48051407339c544598d1f4740411666cc129c12685bd71394b0d308441461a635697b3dc1003259772b50a612504f4a11380cb7fe3c303ed79d29b4c880f0f7a56fe9aa64d1d0dd4b41a57427c7870c31f4ef926c391797e33fa73ce49e7a47cd38d2352baf2c9372bbf33ca4c46e91de3aae34a4aff706c8c36669e8c52ea4e6d6c4a3f9e2cd6cc5b2b9eb2837e88abb75d6b3fe774848245c4a594d1ddddbd3f79c4b6317beee1901fb6949c94d2f3cb52fe9671b77fd9369ceec6e11cfe3259cd2a9df2a86674caa3a323776f0207e7bb6637ee43c8c5613aa34b2ae78e1d3b765c9e1d3b76e0b04f36af34fd102e698614dded212ed10e514c5c0195c519585ae0f292d87286981b6040c3999bc85dd1f4e386383edcf9ca1630643c36894ec22885993c5ec112b7387b24e3e386d14c92ebdf5cbca348b9de4450b96ee58a7701a65a2f60d77fe50518d7ffbf78e2fa833a5f405dff9ea729aeff8f09aeff90201a8071fd8da8004692ebbf820cae7f0b2f80b1455198238cc2a0f1121305ec484c17484962ca888d5952822d318581a5c9490c1fae7f7ce22c624c8182a1086a8ad1184a5e634c0123c3872332a290ca604a8a35598291816aba2244b171e9b21362305dd692584129d12800a689261e7058238a138e22c91041c800ca8c5713ae36d228b86d74bbbbbb9b6cf831bcd1d14509ba50d253058e1337bcb90d46cadf0673e5369497a2ebe3f2a846d71152d22a16c522f629c08d4711c93379e42dff9fc651537040e4f1286ff9d72d2c181ec564c8277e24aa418f729e78456cf97729dac21deac9f522cef12f6ae11c2cac3423c934180406649436fe5839b9004d8c555dce02e60914304bc4a498b0b64cd783b5f9a28ab1344d1c0eb673c11936bb9269b192c560a70aea0f45a4acb0d9e52c5c2095714493700153a34a9abaa5543068b22d755d9048197148da067b55a854171b9864495a17189a50a0304a954b982713080ca68c4b930e12e8a989ead4279eb84e8f8e901e31dde25b9f4c5b2e47bc806850c4058826405f4471a9210a90104f5cbc6ece5c59c205f7c512197461442db902090ad59525b14e086b2f67598294f262692e67590265064b9adc2a788bba5a709ed4dbd803732bd35e59166fc73bfd59961d4143a9e781f6f4adf3b0a2f645fcb5afc8f6da6faf7dd65bdafb0b69efaca87df609a57efb865831c64fc8877efc5da9a79eea32918b45fb85fcdbbfb0e713da36de787eebe09c550f207e8c2cdfd654e216ad33468fc1faf0119fe213e897a9afd858f169fc84e6cba7337a3791b3345f6cb8c38600fad7388fd3dd475bf68cb3659e07b73a0f9229f591f4db788e6ff3fcdbcb2772a9fe6331c05fbe90bffc86a6643f24df3ff696eacb3ea19bf7ee895c5d4df6ac9a1a1fcdc32e8012f243cf14514a29a55fa3ca76502e9ce58c974b69166465b0f437ef16b069daa7bc90e8a67ea35ce66d97bb9477dda7f27e3c76442a179fec7335351fcb84f9355fc2fc9a27ba2a2f9457f599170eddec3b2fb4b78bdca0ea699ebbcc7a4437f3e216110847e572df79610b97fb1fe73ced372ff5e134c8dfb118d06fe385fa6d7cf5138a6ff3655e77198abe60e38fe5cfe2e7dbff03cc8a3d4fea442875f5d6bebbf7cf57c04f8f7577dc12e677f3030c33a9e0bf827f901122f45926d40a645fbf5590911e2c2c07979f0431632e673903bbd188d2cf0866a2ae7f507331c610843418df04fa1c5ca1de91cf3241fefc12a4e40e88a1321902db970fda150f3236b4575af611e14a6971ae7c16111fbd03eec0c26e70fd7df8cf2fc17f7e2ca20bc6be946fe5affc05468a7e3fd7f72fa27d7f48fab5f70fc914a17eed91f8d7e70de41cf947e495527ef77844ae94564da8c1f6cbd7711ec9d5ade4befbcd63577d8ddb40e9c20b9cb44f6c44128279b897d1882be5836c003045299d4f6917d5a9444f7dd6ea87a47e45c2b1cb5bf07fc15f05ff155891f334241d47e6de20297a8f73c71ee712638c48bae73ef5da3b60fb3a4568fbfa9c8724e5b16b8bbda59881b4c0b60a9ce37f444a8f521a7422629216e31c17430cf6e1cbb37229c675f961805db28b52461be3b0e2675f3ff545342d22d9be7eacf805a5bebab221de2f1c714e7f962cecc3136708d8607ffc9e97fa250fc718638c92892dfb0d870efadd9110ef0b0dc6ed9570dad7c8d8c4991b39276adde5f9dd3ba0e655bfd578aca0f92c14d8c52af259cddb3ccdc7f28febc792f38bd47c2c9f1f4b16a1f99aa7a1f99aafc6bd158df736ab55f6355e4ff6395dd830bed815e4adeca7c792df1057967d3cca3e22651f5fd94758f6dc0105d18ffef64ae67336091bc624377375a064e38b73b23f22a91001953b80cb54d4e0e46ecea9bcf88ab00e0576651f8f3c2297caa62633a1069b7d84c5a32cbe1ce63c363e6357e65d50121b7ff39dc7aea024356ff33fcd2efadb1b99cfb1cb25538359e6c58b4e0d667fe345256f65fdc439d9db2736f4d8f55815e6b1f1993b71b39accb5dcccc6c7dcea21ebb254562359a9140747514abcd9472bd973ef6431cacd22d2cdb2d8cd966ef629f757efb016249c64bfcdae73270d6636d9d764ff63c93aacc1ec539fbf1acc825061fd437fddec57701efbb1e4772a380f4df745e6738f84fe369f7b76651f93344f7c792bfbec6351eff867df429665bfd9dc60e5a7b28f32c27ae71b94aff26c4da18b1637662922d916062c7f0b2366f00136858c1a38b1f9828c3167a290682a23adbdb93b1aecf7175ea7bfa7ff41321be3a8fe7a7c49f9f5a57cff86fce537246bf538cff2d21217529a5c8004931f5c74872ab864b1444509052efa35f43bd65564c75a64340be552f6a9dd65fae1244175eb072a61fd0bf374cc2f8d652e8d63d0e0d2681497304fd56c0d730f91ceaf63f18bb203aa35935559b5d64f887b9a6fa87bee8754bf3d11ab3e914be5b1ea7744a87bd51114d8057a8b3e065060d7f628b04bbeea1b1a7a6fd1efe813b9b8f03b50b2318973e81f913726d1efb8a4f2885c9d47e43281066b69de841a6c18938c62fe542a3ddd2aa5094ae2c9efbc1454833455449fa68d388776ac0af3a89eb613977eecd298e43caaefebb8e4ade02da898d420fd1f2696359f6f5fc914e43c5b8aaea21395b6525f68355a6bcdbed62ea244b3ad185b8d8f4ac91e9137b4b7b1b02a5650ca95429515e86743495668a209a5d80437ddec23c23cec6a69b90c25a2d870c6184b701deff84b59737fba8b1a8c58d81b979fd7f0275fadfe75bce56f93d870f5e3bfa377fc431cf07a7b0ef3f90e6bb067f8cfddd4ee77d8c6e2efdb1e0de7c4e78ebf7e818decc3429379b5aa8d83c3e3eb2bb1d6ff3971eee4712b30fb68ba87f115f95f38dc0ab89928a61b4c6fa94936966531c60aab32d628b32863f42a1be38414aaa337d406de94bd13ab33f64e3e7166b5ab97af1b5388818dafcb379c4e148a2ed96263606e7c8260c10c442c3184d197150a6230628a1498000c1042d0c4a26e3424aac4188b95259820c3b44617333590a108337e90414c18559a7452548162b52370461872c2c684892724524ba836766a29622ed0747ec7aade7e334866a2dc6c065bffd64e38fe8e17c6d2cb59d2609f9942176be372963494c882461a691071a3ec52e892060f37ce0e052e43091ec69821c39727c6b8985b5d0a5dd298e1c6dfb2997596659c49cf22a70a5fb8fd91065b8c11033d6cb035c6d8277b3d6cb0f503bd1546331dd5496eb4dde4c6767223371846273a7d34956cf11967e35900a5f7d1337f84dee12c68bcee9c21ce9d5c121ab059e6cbb433ce389f36dff48e6644aae6014080a90d4e041861e7fc95f3b8fc9ff371789b7aa02052f42bfdc29ede66e7a4f5b51884d1bb52bfea56cc6ee00810e7e6379ddf6450e340cf39bf23dabb50efe41c7f1a7ae0ceaf1be8ab49cef1ffc09ddfd589a64c94282512f1a116bb9ecbff1d3dca16695c5d6c7cc9b2f63b3f5183207694418c7245a81b76518702bb6294cbd564637324722828b6a74999262565b4acd88e30e404bbb2655a7043904989520e3290c10d46408cf962c6134844797203146658c10513e7c5464bd209430a23c84c2be894de4a3d2118c515518a3257ca24dd9acb59ca98c06bb8b0f423d75df7b14ce8efbe84a1bb35c86d5cdfd4e7394420d96b5ed8606e26a5dc4a94c52eb2b1e2ca18b026446851c2666255e41003580e4b1451849308a2c0c890022e579c81648309102560c26509a6460abe88d0f4a487199438a185051010530329638089014b962972069cd2d4c2a96a937226b7e8e9d1000c57bc48c1c41532d8a1871765be5c21c30c6e08814b043ea83422409c1bcbaddc293618b14c94588604654a70fbab530d4ea6ebbf49fa621f11ae3f85b10f0d8d729d52a4eb1f44c96ead3467f6292772cd2feca6eb4b0d7a758a790fda9c939bd3e98b538dd3ac5f2b798bd20667f6f59bbee81145a22f0aa31ed7424861eda402cef167513a979a2727693279994fbd43664e33d75dccf5283a7b2af54e38557063d30a0b6ec8f99c73aa807dfa7a7c79cbe9c4d2a04f26facda5275ec9362f77403109e7f87b079442978d9ba5ab4ee08c62134c834e5fd4a34e38e7a3af06bd9fda89beae7f102aacc6bdb63e7a4d094a52b5eff156ff0f4d11a2bffdd094a12942dccf1f1a5a79ebcbbe21f01b7a551af6cccfbe087ded43a221496df215bbdd1de57637958eb592c7584b2e9c4dc2768c917a48b4a73f3d24a9afd9cf7780168da608695f8479c39064dfea68f6c71ad2609fd060cb1f60fa1ba9bf5f0d73d2511bc8578c3991f2d5607c6f58bf622c7e41cc57073981bd1a7c49a794104ad7b78f491af42051d8902a0551b22195d49b31aae43c5c3da44ad77b3061439d98c77ac78a0cdcf267a283e561f5c3f5cf86b8e0f50935bf23f3ba951e4bd8889f742b0dfabb674a41a208a264fdbfc1f841966c7f2958b15dd4450d761785b0b18ae714e1ce8f46ecd377ce39e50f6970a6660cc1a4efcef2ccfd13da3abebc359f7dea786bfed3fcd014eda750f7f61bb2de9adf75df104d4afb865253fb94d5361a8fe54ff3ecea3c96d37c1f12bb7584415656add90644cc3052b973ce39936ae62a4c60fe261f0b9bbaa14442f3dc771e12fbaaeeb77700cd73538468b84fe521e9563dbf07109645247bffec63fd34384760f933f7f4e5ff00637f7e84cd8f45f3a35173de0a5eea93b2b91ab2f734dac879ea0b76e4ccbf01cce9659b840d7ddcfe6dd29045c9a26452b2a4cc4ab6348d32a62c4a462553caae6458b22d938669349b4ca34943774041333b8ac16652b2284f44b9fda137a1c239fd73c29a2727691e1131af34c1727bc266d2b43295e652f74fdfd1567043cedd9d0afbc4fb328d7b644e6f46e19c862d492a6cf75f7a80c8b37df3c85bfd3d3da98f81b6b2a27eb0286e6713d6837e3f6ee84dee8479ab630d9eb16da5a93418a409ebb449d91827ac4e970ac1c2aa629c5ab8457b3461c3c9d4bd64abb576324da6d964eb2afbbc5c4aa9d1a54f85fc35eddd3ff5596fd11e303b9b34a7f6f8ec1f72734bd3fdbed9e42daa79f425141b6f503799b04a2578d0e3049655e9d7ec0718a6e9447f3ed19f4cb36904af951aa49ff22292b7e8cf08ec93c9708fcccb03b7e8ffb01ae29160c1a5505cfa610f45e21e99379c4cb0b98573688f25786c8de486442c126436b744ef07133b9ba6101c6cd3e7589d525ec40f12031b848beda20661ec23c29d4551ca8df1a706ab4383a2245e94bcac283591317e52924129895192d4d74fb2bde6f1c85b11a9fa6b71f9753618e744f9f2e215039518cc74f4262f609e942214e7c4973159859b9c9053482d37fec6044314189ca27717af2231eeed2fc905e6e43253519394e2eeee1d90bf77419993cc254cbe226c93301963f14a348a31caf657efc48f4646ee31e771a19271817322755db12c126e05e65702df0ee52bfe945658fe95e59f8c2935181f080c361e7d428eb0a17cbd9c27fb962ff9921d3bc80c6c7f902c6c7f102cac671f6794714a8ed1a373eeedd4c116495a18ad5c1a97b0d8ba3df7d4e657f016fd5a797e742798bc3489606212a54d977ec64d24972c6b3035f1ee80baaf7a5c12fb8870e9c718fba42ead4f97e4a76a58594ca2f4e39525a62d4dbd6373e9472ff4a3537c6a9ee8a29f394b24ca8599d93e8d1712d198a0faec4b507df644d7bd508643973fe5857f53af7961bc9ac6ffd344973d17fad6780bd7fe8f6fd2f33cee0ea8fb6c83f469bed83036b9f4c3265138cf23ece5440a87ecc45e56701e1dfb14a4e32dfe1104eb5861eb3db2e15fca5f102f96ff41e7999fc4b5ea083058566198b921460858505230f08e128fd58ec7f91932c2992ca4a0c20ba428964c510032c4706192a1862ea66c516dd1a355f1b1e482131c41010ba2cc0c834608ce0c0115c50c61ecb04309ebb12d6052841105c5218b2c8a86a8228608ccd4300651121929f04207a333cc8ca1a572b94a5a2c0c1334cc95ee51a2aeced01b681266382b21c433d59f50a3069b156a9051032a09c7a487a8c6531a6c6da426e59849ed046a5c7143561262fb53e3ca0dd6368f4c593586b0330a6fd1d31346086de330477050504992f91338379663213a3d21146d6a8ce0888d3d566622193b068fde520ba1775434cfffc2d01a2b38cfea999598b9fefb03310f6f5c67e39c31dc302ef9cb465caab55110799ac97b09333dc1b402a623707cd821b8dd506e770fb75b088f71abdf86d6e60b57b11794f378156ef53b51a7702db73fc639fd1f1ca1e37bb5b25687c7dc42c213ae27b945b923f27c73290b35f4db3df613f398c77e94943c7f4a29ed8ec877fded17dbbfafca8b97c65345a949ee8b0c6eda02dc4b182730dcd41719a43fb578a9c7aaf5585ccae2521697b2b8e4c1034ca85f6470ce3ba5dfe81a271b8d938dd6a79cd2bf3b96097d80fce174ab1fc72661431c1e4d6ca8739bc76d213d3ceaf58fab29ef86274e0801c9adc9dd38e44525c8ae7ca1a49d403e91b4a5a6c5188184a6f51527ac7ea5c60d349420c392162ec8f490c3144b6c700236c619435ce122068a15230410cfc286ae055a743418b686198c8852832d6268f08222a0a09283136646c0c3981d3629c69c0088a6020eec8045152ab498d28498061869f184166b301162c91524988b51834609277ce8c1cc13142f687082c312666290c4e48b2dc4346562b4e8c0abaca1445b8387cb142b5708d1c58a2c4014bdaa28a2063e14a920cc6b861181269d10dd20a58aa727315346e0b4803356f040c6992c5a804418b38c1c5a122b2530a68061e1625421439830be24c1e589eb0b13402982063cf040050c19a4c0f8d2511961c80967d650236a818373268a86cc0bbb5dce7266cc0d3959e994be62926997b39c01a3544311b7a59eb39aaaaae75a5575dbbc9f214144ae0dd409ff674850eae5833ada7391e352cf79ecaa4595c8dba3b0e6d79abd10f7d9cfcfb6afdf90f6db0fa59e7b22577ceb4f947d7da1ecebd3afdfd014fa09d5f76fa8bffe907fa6792cf944ae94c7a2df1121ed534750908f0114d8e59ffa8686b42d7c17b73dbbfc650b2f18798bc8a555155a78c1795cbe1115b2af9f84fb2aa7a2b79ca1ae64c7a31370b0f27d8a5037a5aabe21feac6565dcd01421d5ebe850f9ee158140f54852aa6fcafceeb90f75b8741f473f852adbc7ca521f2be3b822a9efbefb90709fd5b4ef27b5d10f3ad7bdda5577777773d7eeeeeeeeeeeeef8bd82e27cd6ab26aab46a3d9a454fcc4501c65c408e7c46a6ae39c93466c38ce8dd8749b5313377193916ef0074fd9f86495116f39d1d84c4747e7dbc056173016b72280798cb011f985ff71519a74eca553724fa7ec38b6ca3f23917dd8d6646ce49b9de66aabb1a1ad5d041c61641ae126231af73ad52eddd8dcf0daa364e4860d8e95cecb8ac326474c7946dce658f5581d1d230d4a233a55e72bff66a332c24d46d8a703287a7b70b575b749b9e8458f1514bf30daeeae52de4d4300e778f37af079de8e9b903bc222213220ba401603a2eb678bcc711d17bd23f5ba30bd6c09ead1f171c3d51768984e20ba42c076f739690b76de1b8e6b2eb30ee845dbdd5506dd9abbdd709135c44aae0eccef00fd1bf3a663f1bca177bb7163e3866cebc4869967c671ef34556e6aa91338875f888fa879d912d4a373434a29a594de9d3ce9cb3927c7b930eff4c28ca6b8b96ddcdc6cb417e660f1173987573ab80db81d1e5c0e380074073577be94525a779ffe1e0f9ca5eb42df8f73f8ad5c173ece839ba4065fca9dfefd3408bb2ef4e5c119531c6ee585f4b217a6724c16071ce0b8118b5ee8c09bf346c79a37ddd782b778ce399f99f98699b9795b5c0f9071742cbed1b178fe16e79c76ce3a3fff06c0f9e072b838008ebb397372e4f3fc2a203947c7621c1d8b6d8d3ffe4c8f24cb1107c70dbef12a6d3ec0e23531c628339aaae9802aad4b7d5c58ae4300e7f0f3f838e7e3a227c089e043a75add58ce0739c218db3a71843196c1cd65aa8b1b0de7eeee2ea5942e4cfe4ac3e4a35afe9c1e9ad6b8bbf37477772941bf11e1071b471863f9c68a83f3849053ce8cd62ab366c381e386d6dd9981eb34cb341a418d031ff4306f4839658c5fe49cd9545299bd4d967d8c5926e9d19cb26a32fbb694529fd25dbebbbb17011d1d11ef4a6d02c91e0e98393a20f9386aa6d2bad49c91c13b79c62ede5417af46277529abd797ca1ab945ffc6a35f73812b6b6cfadb74983922e7500f90c0c3d2cc6895f3886619ad475366f4c829a355ce8cd6239a65b41e4d99d12327396b26279db266f4089c72ca5933ea3465cde851736bbe8d372d70ddfda325e2349f00345420a7b3a65435363672ecf833b1537c8a4bec372e718e941a1c3872dcb8520ec915a783e3fc664a29ab0edec041392425cb866969e9c10f92b8c1e2b179fe50bb353597d9c663b6de0e8e03770e3aa0fa1c00802656c3ed282395b2ce1c00e0987d54dc7d08601f9fbf02c106e1c13c11291aa57869696929b67fec1109090989524a297d7f1d7483fa4522a0fac9068d96eadfaac24a47e4e82a29678e0ea8e2907fc3dd9bd58e077f74866c2aafeff67544dc4b182730c41863b3bb4aa552a9b22ccbb22ccbb28cce39e774970cca21293f5774ddb8b1d12e296d0bd6d9f56d24c8014af7d19648a841aebceebd0e48f59ee6417d811f021bc780d487fc82cb1fc43e9a9191119db12816656f71ae0a4334343434aa2e0997fa56d4a8c8c828870a43ece48423a829882138dce3643db2162cbf90e64162a71683a04204d2d91bbd519224750b18fe139a272ec5a54991544042ba911925895e6e6abc9e20747af4084044aadbe5d7188468a4695a8c4b316623000c72554e09726007241f6cc95af33a9c5d468a461148ffafc215537f9c8281f483f1e202cee99b8e8479fd8b4b3e008e9dc7e6376b3dba06e08393926b6c10ec83cb5100580d6c7c1b4a3c13a00c1b9f9f15603720249820b91a45d77b5861c3d5e51e55d8b09ae0c59661f9ab0eceaeca39ed1f01bad8f02fbff513d408c586b140832bc11037cb5261b00347c89d2104605e31d9cb9d5072b8538a3bbf5a285ceefcd50e29b8f31fdca18a3b5f870720eefc9ede61261ed2b8f37fb6dc3999a2a471271309aab853cae8c1c6c872f86ae52ada1e0bde40536b14cc081c35cb8dce0d773c3183670444c060b8fd373aa07e6bbbbb61f0c4edeebee9805cf21327ae7c1b1d90ac2e788282dbdf6f53b75021821da21081d3edafc1c27d71fb653bb972fbad7d41ac82a603eaaac572373a2cb13a4059d5eb4f4c31c64627bb84e0cc956f738822043f5cf9dcca0a1d6e6c02607a9579a596c850693fae48030721aefc6aaf1c55679fc85dd96587997080ddc0c4954fed12966e72f9bafc0d85804da6b0c187dbffa00d576ebfce0d2568d2c3ed97d676b79632b67b8250b707e0ca6734a4b5542c61abad9c6d2f1d83e6a1c66da61aba3031615a8245471d29a8bf316bbfc5e99ed2adbff59c50b74e300dd6a7f9855b55935b26396fbaf5a73745101a864a61b73ab18f08b7fe7c527da9ee0b69d1addc1752a35b9fbf708ab9f58330d9ecc3e914c574da2085185866ba7c8330616951ef24b14ff3f56993d4e7b1aa555a63b2fe4fbba0b0f5c3e9e431263da4b0f3f3a406ad379f64379d1aacdf038ae53b9d38a77e8f1dac1711c53835257d24c33e4d44151d06fbc45bdf9390ea3b0ecc53bfd188623008918808e48cb8b37dfd2623eecc5f05e126087d0497865b3d86facd450b370c7827f5f5db8a08426cd25318ca8b2f4d986a1276891614000536fe566d10a1ff33030bb5557f9a2fd2cf0aa26115a9f66bbeca2efbd9a7f922b6e6693e162d62f3f66d3e96663f167dae9af7361e58f37feb4fa8fa33aafe74aa3f9fea53afc7fbf1567d1aef8714f67b6efd9c2e6c7c111141985ebaea85084ae973549b5bb7cde9657a9973d2169a4410e28bfbc2aed3ea73dc9af3ebdc3c875b53cf3fbf60b0bef426170cd60fc3ad5704613a4520f5eb8cbaf5c3b8c4ad65dcba05e7d40fa5e43e9e9ff26a83f3839c272679abfef685b5562dc979a693b7aa53ad355c55fae29caafd788175a55a6595b2ca2a6bea63ce91cf38f5ab4075d2f1dabca6a7c116cee54ce37ccc0e48ab9f7aed53f17990b12108eab08f75ed43323465b282b447815ddacfaf4809aa3b3f9073fc5d50587685f52aa99a36e7d73bdd919c0897020406ab0336e8f51aa03ac8814bd65630296b22d6300f47f78e579a898b2ed75ed99abd8ab8daa2ed954aa55c3f239cc06d469084609eed65d8465c196b52ae24bc82b72494511735d364c28bb29a559d1e1fe22df93f294da7e7a763add4494149b44f75a06475640734d4a06c507eeaa9a99b9a8beca631aebc1a654a424f59e567f27f2cd98e05a1c28ba8141bcf1aae412f5b2e3f53165b2edbb8fc851fb83743b4d7df0e322c01a60ba8d48dd63539e9d49440000000e314002028140c0744229150282414f4c4f914800d78a0427e5a994aa42089519032081963083000180032323232449b01b655d0cca8acfe0c6d19886e316863f4ead31d4439498c04f9dac08515a228d8ac5444984e701bac254f6a8ba6a04944191df59b8e5a007da5d788583768bd07e7e7f0ded9a5a80caed74ce766de4f2df3d68ec370584eaaf09544d2bcec267b07b4971297dabb5b135db9007c9d7d0bf97e30eb81ad68dd8f0454cf4940ffffab2000ba87ecd015dada4304a92a0d9a7d754c4515c692dad6a07573ad236af51e91aa75e9277259d5c846841add69aa988f4170c9adaa7ac6810378f9793be08a6455a48875bd52177b0eb56e908491ffa0adb02868af8912e5b4d6a7485c4da194817a5a9f288d7cb540c1c530ebc88a77b7e89c6ec63354485caa7913ccd88268d8dfa6ccc96912706402c7e22a291978a510b2955b5cf7a810103709ab3c6c47d0ac9609d15fdb35878084132a6d3d6e704eb3c6c10987c2c2e2a8e4d911f29faa9122dcf504833bbdfd919671440bcdb6bff547b9e13cee86b90db84ae29a3133901c4e30dc6ea7a54de00d98d68beea6a18f798956f2ea69f043df823b10984a8a9ccbd1b53da5185b015e705fd316f11dbbaf89a5d92c5d45876ededf3d6b36f2db916151dc323b7f12b4da3e05ada94047d404321065bd14740c8cbef53c8db900f543fcb7bfb13d8c8eba551da380964c43e6be3ba903408be1bc40604dd6340e6f62ea0577ad3d4266f395584da92b0983125d19e7ca2be4359bf923b804467d0af8e392fdabfe2d32489a6e7c6626b72c1bc630b6f36789e9548ef09bcc00fa87db10477a5ec095d12b365d8286c283080099a0d72306d8e312deb80dc90e48ad755f5718a9f88196a902a20ff5643e39a4f68d39b35cebd4c4961b012047b5db198300ee5a81babd28d53f52a65e4b7285c0004b6102ce90b741f7cb8fc4749380a8e1dd40f61320ff199aae4af120dd835ad1aa74a9c747373635ab8adf5cc69540a43956b73681bb621096b02a23d59b99524f3fe9233328294fd8e811fface1e4615e813eb37ab83563069cfe2dde00529fd2073b776ec35e4d3f84532ab7453a437b58ea06e8ba846632624e9834e5b54cbb1d72d6641dac7e5dde4e8ef38fb1601012de257bc901a466fc40171630b1b4ddcdcb011854696bb079d374511e5ac195daaef218aca292bfb17e9398735c2739f2dfee54ed18cdc17d75bc3b109d096f958301784fa2752a9fc4a5d94bcf8037a036632a80e8f143026841fe943a391836c89e8c5649b77a3fcbe536c617d54f359c1ce9f24a342ac4ecda8607d8d9074f7a107bab8227127e274391893347cddc01e068b4c879420009bdc0bcf79f40effaf801a1f97a546a40ff3a82eb0a9279e030ea0bb8ee95817262c9f7540bed5dff2628ac358e425fe3ce5155f9c9d732895387c7a6c672cd6164da2d2cce0288157635bc87a097a828f245860aa805704d8e305fa880c93200e3a504a4c540af066b2e1be8779f3b254d32a62434672329e346f21a1f657e8b898eae53780b7f7a8ce100d38ab615c0f1d74f7aeb7e3d49a1e8fe4d4f132410f08688cecff890315f1a80fe040260037ae93f932ada5c7e0edc4f425d8234fc9a3510f91840a8c6a3b1fb7e0d847dd720978c2a70b1eade07e7bb50c95d2f40cd21b533494e656517a0091663ab57c46f004321828a450550de3a782e7813c7267b5614bb95157485c8676114c91f825f44ef2590491fdd8d7d3a19f7564788167d6db50fa238e919fe66c84240094c400d15c8e9541465254d6356d0f9818319212c42a8beec7c763e811e8ccbeaea56ffff1e4ef83d81b5a7a8a6fc5e3fb81801d99657e74cfdec4debfdd1f9ea0cedbcd099ba9bdadbc176d56c3f6958688296836e3256f7ff9715b8a76121d58fa23c320184e334c2307b5a8c757cf66faead3953c02cd21217a549acce1974906461ac56839bdf4a48aad89d2d5c84ebb0c1060b53499617b2ac3b3c420d150942a206b5fab9ae8c0a135326e804b0e8beb5cc97438592e0d1762db63ce69aa23520109d6b5a02e54b5b4dfd7a8dd7c2405e1c641be69dc2d0f0bba946b6d7f7f16360380941975f1998697cf3284399eaf9f4ad5ed14ecb68d8ff626338dedadca1bde3898827985322c9c1f38067f80e05f90dc629e8fbe7d00a4e6045ec18a6cfbf74536b5cefa76a997482cf148bc04b5e144e34c14a1e5ee5bc9c5589b669059272ab7e6727b01aafbca00217d3fd0d6aa8ac1754a0bf3725c616f0cf788d4cb05a736920cd453123e2f4c20af302f3f892fbfbbbafe3e7d09f2c8102e9815716c376d948e95684649fe334e26cdffc9a18986a18b786698816961e466aff96e9c7efc6d2f1a71ee69e8cb9e7d86cfe8507866804eebb194f91c3589fa151e24dac651c9486c8733e457b927438403c6a2c2f91635adab7132505a791546e19fc11f80e53e1fe6c974de0be2049d35c96f4183ece105675aee63a368576020029fef2c81b30f7dbbe1992e8a8cf7fd923080d9cecb32a6962d0a6e4bb4d039abf826843e5d716942c57f70bcd1957ec1fe833682278cfba280a7890eef30d880396409a54c869cfe4492993c547c4fe0d81f161acd56d779b0031e0be8a10dd8f92c190b44d480dbc6240a33436f227fc1d2804af1421476a104efb48d9570a0efaf0db2a590d3233a2c46b37b05936819e4694f836edb1e9dd40f85fd743da37357dbcc665823d5a9be1a46585af9e221de97bfc3858a84ac55ce73af8df6baae1c45c404b36c10df8cda53de6cca732c472496a450e090819c68890501366e5f6edebfe57ffa1ff3a7707436dfee71f38ef5376fa1ff6d790e896cfc67bc3964da1d233d6011aecf0ec55b5267937edc5f66aaca6cee23b3d64a6cd435a10268e742d0e009c5bec46890b0525fae8a3267c0f3852dd4900fc661cb06c15cbda87c7d04cb97f7d152ebfd815c885be1171cc8471caa37800bb73ec1ac20f29731ebfd2382643731b879f97fc1526cee14ad0e9849085a0ba43ab293aea12a7485bc48bcc99c1b45bee0c179741b237b8d168d9495ea85356ea61d8e2daf14b567838370e3cada4317a849ac9a05d870568de23290f88d28078778e4252efe7737691c9281f12d044c9c0a97f886a7805a3d7dc618a7eec034623fb2cfb4850f0420acab38f1ff6d6ad4e0222f6faf16b36136127cb3514fb34f2ac28b21e90908f956ab158a768c7eaf33b83d1b47e402e22acdd1e784b187105e218738754ed941e943aa7f5bf2a96c9b6c1600f7331478a0944a36a82cf7df13408dc525c835986b33b70efe298cabc023f6a6d5c6262aa7cf591408cfd914839cd25c6bbeb9d7d3f9af5f20d0926af6beaa567a1af7fe831346907c7118e3416c5fa3d129823b6885812f095e495c37ea68d5500f07d808ad6c9f482c34002e8add497030787fac989b14055b498ded17233b5e360245c1018ea9459831234425099517415c8f2235f81ed0a398c77a3d2cebc0d899385e26f1b80a85399368dca0bd843c97caa7195411eaf1c660716c9438cc498a8a0fd12325dfe3328b5d49ead7b604348b92c4b6342439e1bf63990667bb84c3162f6f2eb14011349256f7abd4b45185268d9f9d4eb8dbbe4cb7e77d3a02cb29dd6ab7471c11a40b45281ff9806b0b22382f86eaf14bcc03359e04ccd7691f5d1498a054535532c503279831819e50f3f84a8b77ba9c89a88c0d1c41b8efbc455e8e001b4b8f85c6e7eed12f13ffbd2b5ac95256082c9c515427873ec7ba6fc493fc1c4d8da872ea3d7c4e4d04d96cdab164f0b34f9210ab945d465a115d52ba1faed41b91a42e15fac9ac19fe2d9d036d4339650be2019c693d69556d3aaa88557b4ddf1c87d15ba3178ab277dee6f23f588498e63a590a1d2bcd783a49d68b842a96d808f6e1e5957e9d2fd54808cf6032bf634e17bf71d754117ee7d0e01f2281ff92dedd7c737293848e39a497cd7be5a36d01f3735d5ee7b87b4ceee6a29c9fabd6f3077a6b3fb5298a6ace2502abd7d83cb801d7a306159d488f000706ca6c6fbbb111107084ae18cf5d170cc9e42678cfc8107e9169b2d3744f441bad18a5ae07848f02c9d18c696495b5a28c82fd5b7cb63a4aab58ad46a8320a77e23b123b6dfac5385f7a154d12b5733c84ea3bfe616066f6062b40a8f0a5ff588a88924419e755d8f9e7fac9c0410fc28926869644882ac6246e0f5f8ccd8b24a9881f3b7dbce5c24b0258b8907a3d2d6b630e569317f29b6d1d97689257caba310a9e058bf71436689aa47441a0bf52d44ee3fd1f06fedcf01c9f53819f51189db52a5a5bf9bf45bbfbdb332b1c84e05713d171bd77e39e4bc74601570d6379a48943c59ad65066354cc581282c18100e435738e6056fa201290225e2f9e0a79c66c37098464435cc46d5dee378a59819e96f7ccd32759a0afbe934c7b069697eb62fca74110680926254f2c91d0a20c2df90bc90061a2c11f574df8f62311eb3d1f050becc8b6542c4f943371c24db3b87c3ffda7dc9e3b6bbfec1de3ca6964cc88f19ef96c504816c00cf096448ca005dcde0785f19402937c875c23e989a2e92a793f5a6934778469a046c4e0ed3c3d6331115cde51c27dbe99141fbedd194275e2471a369c41b84624717ff5c8a1ba3213d4660cc1c141f6b79043341b332c4921a7b2d6f3399e9898c85c81a90b22bd81fa32bc6b3a458e28784f8551095350689f5e9fe10ffb11af4220fa7fbdcbbe17c20f2f06241f433730f3bb922af9c7dd472d8b62810fcf38494482af3041e9c5e70bc1ada36d87e3501c99925c8ec22b6893705a386bdcfab272f3639f070a7ef3d8bbb8feeeb2cd2d0cde18e03a04e49cf64994970146f48834ccbde90c71d7ac88fac54938fe0e8fecde764f344ec68fda4c822104f0f4f9f60984a5fb80d03b1a2cb592ec8af386d6b86594273c4e75bf43e7400be68c9385b4be35a426fb3766df371edb4d9e2f6b323dfee7a525746e8ce37849438cbae69da2b4007ba369d2735a7a4cb33c165fe912ac3381ccdd2d795716184f90e78f38c1ea1a595cd5b7cab1f052109d150db1885f8a5d702c7e80bf4eb7f52263d023a6aaf82bafa05f17025b4754e55dcc01c4f2601610b61e4114325e9242136035c604255c96bf185f46781420d1c1b543f2020898d9201cca492af4069b5719240ee0561d40592d0aff7f0a0f5474bd7f4160115ac18b6c7cbf6087efd182a6113fd4b0caf488b3b6b00fffd29aa012f8a16b09a8eb66df19d845ba350173c21c51972ee44250bfc61351226c4da44d70ad61defdedf749954e8d82a33f2450e479aa3619acd188727bcacc7bb8f2ce74b29a181e52dc9533133211bbf08d478c899a7de7d77883445c72c44442227a134e3a9d14dd8238e9d797c0dcdbe7179c30a9e26a4c69bdd0b82828ae2cb20279da3e7d0a9ef4803d7965b89ac7bf69d2c9af16c36e29b0c3c655aef3bf06284fe86105fa804eb6a44b196032f36218e610e451d0f024899f6c23859d928954d7c7bc06f457f7500a7855076d263db1a11cb5d178a331f6a8ecf995df70fce3b9b3b5ce1384a3fd417072722434264795b5e4e4c6675dda1eb591d5fdf854ef52e080b6596b200b4bd6f8dffb9bb8eb5fa14a7bd4e46ed688e43b6c88808847d0c834f870072dbd18af6922f83477bb1706ebfdbb349d1510e0a2f92e1a38b5007ee844e8847b5d376b98706b8f1a870d672bb387641df12d61b24a403b58f6ef2180a21a57342b2b38d9d08c70ab326ebf26ecb1e43badd7898ddfde6a105250e77d9edd143a2f1bb91d4c28b1cd5274c58cd849da4b65c5b2335dada0bca21fc92339d0590d23710b63d8d851e5e1eb714bd0275e1f2cc3172a3c7e24c0f219a4a923d5f06faeb4a4fa4a3cccce6c019bc361dd15dcdaaff7b2bcda2a8c7e6530895335546737e718259f0a18597c1c3ba76e574f15ac504d1759c90155227e2088bdcdf1c4a1c6a230cc43b1857a1c19e246101c0c1ba123f6f6b0c6be7ce06c57d58dde676fde506b94177803252b749bfe044390942afc1a5b5529a4f8089363a2363d2f77e588fdabbaf721233fdb468cc6997984d54e8796eb4d4d8b18baa703c4c43e236b426bffba35ea4cdce4e2d7bde3e077b49cefb64b5b74fd2ad50d321e1dc44c4996bac7aa8870887374fcc16707b5e963d5eb0816ea15f1f496c25f7426289973b0bbb56e105bf0079e1a59bf80b0b229815568c1e20085f6f9bffe370d6fbef35160a23206aaa1d77b7c4669245a58499596f24ca2e1cfa3377946672f4911eaafc48a1d66815eb7f2fbde82cfb6e08270df0f061a8b8f562b91578d46042c08bcfd2cb6529f39aba8a74391c81086fb0c0fe122a80ee0d301821023d458d0ffd704fa153e8f7b3a5c81b8f329b62834e0c55e6f5473d8cb10e3e9b06c5d23d892d93a1a3594b5e552993fcaceb5bce41272ede1cbfd52d55dcfc8a57f7bfcf8d076279791ca59b27168cf1354fe7a858246f4f73d1036e59ce7fba114a61076e4a2f7cc6dd54fa928017cb8ed5d324e4aca1b1c60faf971184f1c89f9bad76f1aa3b5aaa0a24187dae22426f69b0c60ff654f9d4d9fb87a5f392eb0aa2f6607a525142e3bc4ec8a019c1eb5116ce84f2ded0d18c522f31c1f034ae96efea7ba745e78d92c39e2a78cb7b789c363ec6e7826f70ab580432ec942cbf01d0d4e81640115d770ee3272882e7eda9d0bdfedd37b0532fd098389cc8b1e50f8f4d845fe4a4672224804a2eb76b2d0d1472a5c64750aa4611bc7e0655d2f5d1324c5293c96c1ef42d666adcb4c5af68a77a0181cff8b33bb3c33ac17baf8d20cb501cd86a765e15b4e209db700bdfcff53f3b9bca7c7027aff72045baa153616897f9130e85ea6836fcd22920990203a46e92b527d1429d1f19dda8d51552419ce6651a4484bf877d10d3722a5d0d15d1d8dbfca6bd41cc2932b8c4f6f8db8905e424b137dbe2541e2596f25d4e1ebd0818f441c9108711afa429d42bc386a201ef11bb1f1ace7c375f8828b544e3a293b3e6cd412457aaf40cf967f0a040efba214e63697bbc909e9d51a900063852778177680440825ba168385739e1865f360135aa9bba2370fd0e830d96b81b1b4d4af08ecf71743612ae663cbf2f6f9c9e63c2aa0729cbfe5128f47d3ea826871248ac449c03ff4867b1c1bcc57a0c38960cafe2b1d5062ea6f0b357eea7c405bca321d1ced3e502a55195e71ee6f8c5e67bb1042495cf16b95edda60413eaa7be59ffba7e2fd392596a9bf4a0ff40549ac718ad1b6d4529c092b027552ebfb481d0f45ecc6eb7f3bb8474a8b7b1bf767aebdc0375d300d20462de5eae564e4d0349715241987fef4129b9f64d9a51b0938e42052ef4f39934eeb6da4e3a1bbbefd04881249ae45440b93ee38ccf71aaa38e0e0f81524073c295f9bd38b4869fc501941e3e3716c64e18436c17035cbe52102f79fe693dff4c96dc2409968d9381fb3f8beb2fabfc31625c867ea0634f23a1ef4dba23815c701941122cb4590e1c734b0bbf31dd25a08694c3bc58667d19eb05479c7d08d58d0da2361842c652e3f978234c67704e91e6631ee36c682f4edccb033b6b19b398e9c9f3df35de859d387841ad2f4e4558a0e36cbb59b4544317c94b037491912b03641cc7bc1b8a6ecb3a1fe214a8f7e9052f2b6299d27232a0d6a0cc9fe67c74716c2a183e0865ffc2cdf14f75952e4f8f75b6c0470abf560c333843447c409f5bbf994d59a807e05c40cb6e00520bf5555d49cba94c2434b5bca69c1e80312c2db6a19c4fa163cbb5f1bf3715daef86b9c85af0cd27817b5f08e45fc08c63506a071d44c02949e3ea1caad2975da85c5a1bcfdc280708f69024e1341057ad6997066055f333632dfd1596c67da72d915eac025a6937d65c3fa70803f3a3ec22469a6dc4e11ad5cb77084e3e6a6697e56a71f57916de5f77475a5061bb0d8a995e09836006902155366fdfb980ec9cf07b95f07886dee88dbbf841e300f11dbcaf822061161858fd9b27da1ef4f36dc68c688ebd513916ae715243dd979ce348f2afd4dd54bdb6291a5da1bd73f951c8b7c485447215f122b7aaf886aa7f5018d0a58312809fe1fe59cafcd010acdd05f35f9394978327dfee1c6b3d49d201cd0074184692e8586e34898b8f8b7b89926052dd78d6eb7d91dcc6595359bc26c8237cdf5d65d9b1c2a1b2fbc8d2ad4aa43ea63455595a7c5a0fb6352de98ab8d1699d26b54d169b1d5a0c04daf1f91fbfb813df0bf57416f0d394330da4ef53c26512ed34ce5dc87858685827e53ca4461746b29edc27e303f1835f1e4c8079c27e2846000120ffe870e049eeaa774093114c0b50bffa664051c22140fbc68eef01e269145feaf811acc64d67ac9a8266b5d59eb93c5017aca4b18b755bf58adbe121d3f7eb019bfe08ea42a482794a4138aa24229630765d27ee3a42682b75c5890a263130af8efd2dc1b22fd781c0e980a64468fdb224d7f7c1bbfd033e23d3f435e9840a93cf5da67ded0051071aace9ea550fee05cf514c36410615440eb2e05d39350dabd3eba6424ef7a2ac4dc5968138679bf702122d5c0ae014a9a738fa4a9c98d8970a932232992a7f13e5ef3689d0a396e9860d72db509e148f8dec4f7927c6f3ddf1891046b1221da0ed1dcf4242ce710c51b4699262b82b96c968e89843bb9876734885b2393124e6a465abb644a47fd26d1482393818a91f111e1192f2f6401165fe5a3fe0ddb956dec9b066ec92e9a434dd86ba1b9c535d80d494e45373b868f8ec7890293a4a5336d6e6064d3419b730dd8f63c61e6b265627bdbd945622f6d78a8c277eb81fbe5544c0f90120bfacf8cd45b29f94e1b381926627024d2c63434b310f1f83a52b29ff48640e74f317981934e267ee8e165f43449cf4e1829aed328696e902953cf1c520cd0ca5b26c5799bcb58c50fc8c8c5e36759e7f4acf1057c3adb6ed474924ae226bc38c2aa147c9c4e67eee48c8f7d49fbeccadd638d881a912d779c6caef81d56ad0a35b5687f124cc8057f33a83b62617b5102f5d776396bbb80a02eaa5d7d706005c7ea73ca22c8be995803c9e87b4347a60c4df9c6d0418201c7b7846e0e6c86f8c5f22cd82221ab9b24794ae52ca62d88a4ba883661e9609490830dd83066c1fbfbf8fe887fb55ba53b316b4b7789ad5661193dc1d005bb9691c66a0aae68e123f4d16c91e2fb7f4eb32f38519ffbaeecf3a54f61f73f3ed19cb93d2b5a774ed38824f800f9005b09b7ea9ce4e8a3650136b63351ff3fa6214d668864643100507f8639d43a276eba76fc3c263a17ea2a73bd693ffe01adab0af7b295f487d3ec4db42be15eb4074b8b295e4f6712b009f057532a607dbe92ba637cb8d00f4bc2288189d599654e767f4e7b49398c71c39c095253e0f0f30cc5feee1f11ea51335233217c22fefc6516ab0d30b66722f98d5f8370c1682ba21579679ddc4212b45d55f483717d61aad00d7870068bafb079c58cbc3106997a3a744c18cfb048830f1f46e9bb50e808deecd42b282dc280a1176118b98ccd19b5ce2ecd246b99f49c5654225968cc38777ad3631e33c2f8d0316e545b9628379a2f355628af8b3270d079199ee8f81598847528392c67ade334197c7f69ff42a845f345b050db4db0f4162d9e50e70f64f18ce30d0560514f00d72df9705d350112e71434a7ad063b6ee6b2506e375a609ec7fc590c2d8ca46c2186e78662ae0f11d5afbc4115ddcb46b64cd580777ba0b2f7633c8c19d98f379563b78829e44a32ccb46c0d751831550ee77406c48d789f6a77aaa542265eefb85acd5c7f8fe738563e7eeaef948c921731c0d079f3624786a91b4a9b2a1e31fe3c386132c27e63c6ca54acd39b60ac94671b226ed1d82023a28fdffbd41455b7466bc3effe7b452fd8871e89d6c231a7a591ea3cefe6a248613901035f35412f9c964b02af9dce2a6eefe8d28165b73aa5e29950c08e1c0ac98add84180fe0443b43750360148c0ed0aa880b5c42cbe69877c761f0d4cb2d5a52aafffafaf05892ed4ea810e2db10f907ebf8e8ad15b3fe1fa42ae59d46dd21b19cc6cb485b07ddeee9a1279d6e8666c2c1745817be153d3d4bcd9240853147b1772cc209bafbc0d1b01eec088ef7fd404557f570a3a70aada3454ff928281205a520a192676dbb1a7abc88ac4a0b47748409525420c4d753a3d86fe1ad07edec3e489896ed8e1cb8671d28c54389390b1e831840d2c64235c4e4fe155ceb3d53644344e25d45c0074bc62a241d1f9c690f2bd4955d0b3e37ca8271390c5a3c4d123a0cd298e87228868b39dd462ea2bf446403a76b344911c4bc43b1848fed0b2b15f55053da5b0cd10d2a987655f8df91210fe028c2e20c2146d84a0c14ea7f76c6a1f09e74e32be4406a5961f3f40f999d7ded8a488db65d3c1ae54579ff4ad26a45798d503f0f60d34bb2a18e89cbb11fdbd02d501001128cedd047cd877472847a248e6c3e394ec72e1cbf986a1845646b0841f035e0bcc7bf65c09a821ab877d604db52edd4efe7881b52036e0923cf1dbb0df06626cf08ff3fe9e534a2051dcb5e8cbc60bd3131cfe70b041cf2220b2ca61ed168dd0069db2883157b64ede63bbb6d1805f979e70fd8368a02a4e5628ecd4bca805a2cac3f735d1db9744000439096348107bb5349c1ffec9cc5030168a4378189374b776dd5dee3223d0abbc6b47cff168c135f229416f21391cb898934f3d08995f8ee7facb3e990b0b661ec211bc6a09ff7e9f36650722f41375fdc9eb08d1827d5088bf94e326160ca554a5f4670faf1095bdf6be4bcac79aa02dc954f0728acc85b33ed5e2180ab236da15ac9c52b3844e5a2347bc1e96e514975b7883bb76262641e2424e633df1ed810a70ce22822765ebfc75292daca3556273d1523e01073178e276f6b74e7e83c378257a114d274f766ed5231c7d522de70bd81da5ec3ab6ffa20d6615e0fe2314088d8631642d65b8dc641148f0192a86d613450847c7556d02b8a46d6be842c297063fb637d24736cbda9234457d72508d403dc46752f5efea475293ad0d5588de26c8d81d7f56c572b8027f1dbe0d41d21d594375601d861ec7940410f45122b2de8310b3ddae39eef24cebb6f0bc7ea3bb208441f36f76e0a038ca0599b41d4d195fa46d6e5a63e3d7ec0c9cd4c678b56e3569ba734ed1d1b63a5eeb214ed25a1c56a948ed06ab88ff4c464ea9fd16a298f61b5fdb19c8688b3a6d3a525b1c7335a4de56bba6ae1c833c36b33bf5c0175092015b58843f1a58ee9c05645d3c061631859b819970288c4dd983e46796896949d5b5324aa6c4cba7bd19eea5780d1d9aa442a52e8e95427d51044fab95239c6ffc618c00db714981a159cc850d7b95559a79f5c597d5cb0ad9b7a6e585626d0ee02f8166c821b4c2c4db62dc62c49fce39fca4b7cc271d9baa814898d41c245a46d7015ee09185616830efba3d2ef9c96a6e19ab46a7c52f6b0b2ce413f890fcdb178d0bd58d860dca1269ab9e1a06e5f65261efb4b64406fb291e6d5bafa61f7ba8761ed3db7e79ab49b284a30bde963d9277dede543eea2052294baae8e8c96e8ec6a3d7c1084039610dde7771198d8139279bb153d88ffc0c9a7bef1155ab1b853f9f1e46c3173f53819e6b1eb4164d8320908bccf99a126486154019f6823106b8b9617eb484091ac1a7591aaa35fed25dda7f5d5b1b41c21c957636d558a4dc0e1b578071b50c85f098914b969a564d3864c8c59e6794405cbc3026d1f62d1052f0d6c618beb73afac49732a06aa54e2540e85b36a34ed317ebb1d41df5ebf15e6d941443a12927c3930249295b4ccc3b36614cdca1e5cc45061be6ee2df90b11d5058832f87359f2d312669f9d9ae1f2849bfc39c34b5b1fcbba84314743b7ea4a750aa28d92f2fd6fce85390c17cf175f93dea7f96575acccd568b5586567a675200f13ffe8da573f3e53c7aa1071582864f0228660b75aa7eca0069f2fdba79c2ced70ef31154192caf98f21a4e0b48bb4cf6d8d29c36ac69eb6fbe70f4bdd516af248ba538fdfe4d2bb8ed07455f48e642d3eadc9e3954d6e9fa7460aeebea38547630542d011b4da93808b3819ce1ac0476ba995a70a1c7b0c3549d52dd0aa86d2b91f20e0b321422a97c3a9ddd8323238d2393795c6b54d50e55402936f9ca497e0ad23f94cda7fe39dcfd8b150b20b1d7877975e66a274177b9752e233f3282a8d4638bf57c37cadd45b771c02aedc926bf4799decda4e7b0f2d6f22b4016fbb0c5d760bfbe0ec9ce27c1bc9587000f571ffd7b8256b14c3ed0f87d5d22e6d94b69720b9b8d326003029ba94af8ff9ee77c01bfb88d2be21349b8e4ddf114f39302a61358bca27df39b81db1e737ddb1694304f6664b9f4813916f4092d9ce7e5c2322dda06540139c4599a19d92af5104244f9cb3dd043e0f93de125d506bc0ca212b2f896586cf8a89dcd4e8d14e20c2c81c3ce0a1dc09cdb324380f16028b0350513c8cf2e1f7bfacf6786376730c5d9b1c5f942c5508e177f5c3ce353f54d62a0063b285cff5d5db8418301a3781544606953cb5b155ba66c9efba388086336985a2be790cd299842153663310e4f38f152c6df3a8fa5e54191b5d735e4e230ed31c432ed575ef6f6e5dedf966b64dd58090c8265d98a73def9c2b236bebd3854af93d52b45983bea3e086efd96237b5f4ab574c1d2d1b1309d5c4814e9365f461794b6a2cc55a33993c753bf2762ef0f78b6b0fa178ead74cb2fcef2539005c1505910fa0392f0a40dad2176e1735a6cc682f3787e136c16114b391cbc03404218dc7398444a251702cd520fc328d3801f0b77929db1d35e525ee81db4bc373cf2fe08824fe712b67e68235250a0f4d5f02f893238e3d538e6a4019ed73cbf64af43754984bfb63ddd000d6a724c9c588c6ae00f1c50f4d5776b4f91d38271c939d0c052a57626991ba71bfe116da2fd4e1267c24d94daf09333c0a0f3d0331625c2523df07268cb7563e4bf3e7701790726016a1a7d4a9b18b4d58e906fad51d4c768267755d2b163dde41da9f8748e554213258754f9855b6a9d700533cfda6df54a3ecd8775df1fbad1a307fdb63f3fa65d937ca947419799aa996ef294b621b6513839180b8e789c2ea3055c665686ea5e2146c973fe07259ce4a96a926ee8fad709409ee8e42ea498b7c482221d103367efb9e03891a2a73dbc526fe56f63cee706b97283bbf852dec4e2b24ffc51004113ce2af1b13b52d260ae0189c2aabe45e604d93a5a13b461aa56157517317ef5d2022c48f02d64fca10bd2365243f310e3124745476c11d3186e26c0d451b6a1bc1798a9f38c8d6dbd68caa4ad736f827583ac994888f2c04e26291949887d1e598b7a95c239e7951ef3423db14de8d72ea4e3881b85a1965b859c934f1650c158c178270cbec70035159ec0bd53c605d9efeb5d2835963a661d9597e8150ed3b841c79d56907f7ccac19d5c766cbf476a348041040e14281999183b540f836bec715d407132b6eba663667e08d0cd17c8a9159436c02f8cf5fe1a313267606e819fff693936c140c78d250b4066f6aa1c5c014a0efebc297cbe95d47963478d36d8f2ab46fe313bd142acd06ddc42da296782c365ca345d7c4488ceccabdb0e1e9d3af65bc011200e747de443801fd3692ec42b7462ce731ad2c4693aa29586179bea381b20c1efb51cfa41d08f2a7755aa74faa6c160691bfb37cdff0b898a42026c3d66c5e9b03ebdf8251f2885d38c126de3dda09384f74c0f63a0ce061e88d9414afda4995283309f1a22afed7cf5d22c971c94298bda67bf5ca808dacb1f46fc324cc17c0d7b56e6fda3072ebe6ae986429ce221cb881b104aa19b6b5c466aa13ee87f58215493758bf4056c4b241740c2639065e2ddf3b8f0b98759fb640209e1e085962e3641c9f7b38db329ceb3dc2c75b26a648b8e50f37ede97e6f433e2a915c8676d2a87203c2e9f94fcbd46e5e8c45170b59233ca97c0b412104177fa815cde1c269a42a96cd8b5e12b1d9e6bd8f1937487e8d3cc18a6ec87443564b8d6a88299bd544c09df86e87081dc0233c5879fb58edb3437394e7b3f71ba55d9b94622ff48e28e32c989bb680744a316b43cffa7f24d9d037ddfd2a9d6d5130f9c5c3003642bb0c650bad322b814547c9d45226d1c082dbf526f480a66aad85f2ec73ec46d9a5c06610edf446e18c62593d260d5db8b0588d4049046a9051cd5d18765fe07c5bd413ef013f9796f47a95a5e24d6a0f2f95e03f7a039296a3e8fe762e56b19657c74bbe0ee24bdd8e3f7dcb7b39d72639c489718bf2cbd3c47f697a799d812d3cb1ea74d9db78669e3a5019d846a5dfe0561e8c25e0c205b585cc99a527b2fdd03d191db53889c16e4f2a90a4177e1aea590f1de4db961877d4f17342e9fd1a75a5fc17077d0151e0ed696f229f70670ca3053f0164a40218aee1c48a0a5f1330a08eb28836f1a9b7b7d5cc8f58257acf98131a2b62a3b88114f2b8ff640efdf35a7d0ea5986dcf2b1b47d340e745953d7cfe8c75b867b0ddefe7a704b0f9b8abef67f8d91c5bd7f9d007d632b34e9d154ff02945078dee649f31de67100a1833cf4640d5e78ddc64598c80cf2a4c16b2dbbc786e80d18b841294754c7785f449da6b10b0c388e3d204af72cfa4e0e4372e54485ad3f5fc27f40ccbb5b3fe473041aad8ff36742b67476c61125b323a2004fadb6eb9f3f19baade26aea1185b1a930eee73a1d776e973f4a4bd7530ba3713f1ea410db8d2d469e3f4c8377d9b248a78a90a4a05e3a60db8b61770e31693e2d6e0ec35af3870b17cf355c9f6e87fcf076cb00f15fbb2c2037513c7bfce459a65169d819628bfd55377a01508969476ed121e9de891f5f8c439a3cc134e622ad0c1a617a1310564156d654a537cdb958790d794085195075f607674423114012d3d3cbd59c5f1180340a64be1badedc5659c3a509abd8aa7e33719df0c825f594497d868c22ac5f69f8d129d4ce3606aec70a2196401c81f5b9d10928a3c0c1bc28f06a0f6aecce43fc4e3001e50bd59e01b5d83ea2d445254aba16201a54f409800fb5f135686a0e62d008bd5c5a9854e4b90e9163e48aac92c44885acd4fca246bfffad756adb1fbebf6cd067e6079335a55fb5566b3b603b7abf61b2a3f11e35ecbfe77e6543a8d3de1174e910974aa1e9c9bc94b20d2a9f0ff38a7f375fcd6b8cf51a2ba7b2f464af455f370fb202545d43a0cec266f1fa950263cf8996e8fad8b1f2e306aa1688d011162c05c09e06576bc978f3fff4be2f781b521b68feac93412252fe9f4fd269df27be05c0eacafa04131ab0e6d8b56278bab9dd5f0f3c29c4c94e42ec52a9b942ed7a703f3ebd9e5849649cd6bbbe4a4cfdb5f1ae5a9bcda2d8eed0c259c16b32caf1c350994495ac008f44f587b951f634c4410eac991457acd6b70de425f44eebf0b9712bdc10dac635c2c09a5ce51bc3eff0e7bfc7ea35a350276efee49527f17a5453b3e0ddc0892c576001f418fabdf701308436a67230b32813135b91488644e0f9caf46b3b176bb6e20cd68800c81a72495bfeee2fb0beeba3f6f47bcf83135d6efae5370b68100a21f2d8855f2d78d0fdc5203852763faf0b7f1091c462e091bce3f2c47a289375fe1559dd433d3a07751c3f78212d66af151df0efbef6a6dd4aa77630beb846b2e3b67f866fd04a2d5480aad9c16a340578ab7f5cf1add6cab64d8b6bcc3871c63f8e985e367d4f46b081eb2277af850a57fc56a1afc24a9e1be42170b358134cf048ea4d9ade90d6086172c3d14f1ae7aba8c4892bf4f60415b1af3db7ed78c874db4a1254392794a5ed40d246c773044927d142e134f21409c8b1f494abbbb215c9e1ee83677aa7006dbb17b20e7cf5e6c2e53731c90e33ab0ac8ee25c67280a8467e7b818be7fcb4ed9810b7141d6d30902072ed797719f253e37c88d6e831e76b24fe0480fe055ffbd33876e0dd1e64be881f0b3cf9f62b2382001065cd23d8fedb789a93cf413527e749a564d601df9bfe37829a75c5c5260ad27ef740a2e1316fc0da030b035e696cf98da2ee309d3d8eb5192e660c1f8426102361421382b9b3d1df4b3084b75a479148e90c976c31f2cb9526e848f5273d42d90eb76c3417a7da448e44c4979ccaa881ed6d394d24511405f370547cecefe1b90ac61d052fda3b39982e6106a79826c495ab739e4af7527d69dbe3068132621397746c47423f5f26f8539a8fae4fdbcaab42018d4de0d9f30c81ac2eaa74746929a08a16d34e2aef00c1a742e5504eac44008445cbab6125c9258818edef24a7e414704639d16d8c21d9ba70874f7e2e907c542a1878923cbeb80b8835c097f984c3aea3239a5a39aabeca77ca868befca0183e6a2bb9e14170f9f2f6c69f41f5e69b84cc0f0fb9a713e8ad59c7a8d5cb05657a7303d223c710e3c21a9624684137eac016173b2a1df157462a62cd28d3dc50431eea94ecc8396e9c3d0163fa2bb1b395b133f8c24e0c4beca458ea6a0033c8c2aff2b0398ff46bd1f6e5b67cf09c63588d12108290c8c06cb19201373d78686859878f18b0356259ae68f553dc0145d0f9880e9e943250960f01196db422af839cc99b361bfc10b2fa8bb4a8087b8b558cc08cdc58ae8bb7eac401a138f3fdbfda3a43214859950b6110a5b8e75e5c2bc93b39d65a71a7a33c2aa26e1a6c85a3ad753e2ed0c6c342d00d9893982a46c23604912f375734a7acf5ee9430d0a470971db36575ac0cf77e41fa5dfaab392c82a8d0a3feae6b0c2eb0bcea398d6992b4a784a9e59108e38c8e56d84cd91dbeae6dbed7c864f8ff28d2d7d1b1f6142f969c1a09cb5ac0d74aa955b8104fc354fe464bb20bdd9a4b033a3a10b73da6ce8007e3ecdd6661d7a4c14e1b2f75f814ccbc97e59933269d848ffe3ed1b8a04db729ecc43d34ec2ab791a5f3b41b399baed8f6883e902f844458b825a4338826bd06caf4746337a460ce423d4e1af713252da0e0cdf9b88ddccad169c5cac9324c2fb962c71cb3d5490250ea555b5014ac0785efc54cbdcc4bae0fa41eba9996939e9c9862221bf8955920eac6f90c3730a761bef779d9e6131b78b6225fa22dda4aab53a7a85b93651027cb91714d783beec4bd6aef23fddc7b22f27bd68dca696bfaa4e238d976f654a52e0e0177418507d42b5ce1c5951841af61609fff0a7fba53543ed3d48969a75baf9872f56e841d4af1d4abeb32b8ecae89a85e3551eb70400e8c6d403962bf150214cc558917cd7c331445ab6a9c5299865a48ecd8a5b69a7249357071c11f0e83f15e4f49d79e61895f660eec744e9233801412132765e22660c313095e6cce93ccc1fc28dd9eea03e68333f20728f4d0b11f73180607d27affceb1684f81deb121b2b5986b90f2df083f3e6601e6d9e53708d0894dcb648ff2eb58edb062ee281820551969559614bd223642370ca0e03bdf430a463ca788f84aa15e71eccfcb7694f03085f6be626172660dc45def7a48321f81b0588550b95d9d0b84a5313a8a400b68e7314c8f7e5dde72d762d4a9e43ebdf5602328879a41f60618a7b357b76671a0756f35ac02bdcb1a4312d04f6abe0d7a6f21e78443f7620a281e2b8a4f60fccc3a2b99274f0d2d0c9264ab27a051350dfd4f6b98dc37a2145d646481484d729225aa60a235faa293264313524364eb79df828c98b3d42677e67dfa06658e93a285cdf23aa1423f5d2ed901f33ead3fca037532046d476cbfe924acca224b5fc5de2e6ff730b815524f94f23a5d5ed7ce5ed7c26a570078715b749c6dab3cfc7728e170ad433685816bd38c6db4b72b960965d1a654ad536959c435de2ecbdb230edf594820596d05c4b1553104473f4852a8f817378bc9b3bb1344692b524f70c14098b6e99105a704a592b48ceef8b2162f1d6059233ef3d956ba401f3d81b5281125d4ac95d48cf041b248e623c646251d4e630c9265631c8cc607fcc8e8d03f713ce211789e50d342113d3e2d104205755a354f9ed108f736d5c8464e2c1115595ba5d5e55927075d0467d474d0e47b88f29e4fe89c601b890475b517a81a04e97a7d24f894cc37544fd4bb459cd4a9d47753e2c63628042ca2877229e8c0dd625ebc7d97772251bdf1c179b73d43d76849cf2d7a00493a541e2a95745f64afeeb1e7adfc7c8119d167b90a50e708a98289a94371529fb80883535c2c6497dcde8bfd981053d8e7cecbed626e8b0821d30bc0ec487da1088e561ac1c94f9f43bc559602b7063dddafc0195024b5375db97e6b01a85f7caa585cd3e81b33d1d19fae1e6d7c8018ecf12c8b77194cb283fae311676d2befa88ebbcd1872f5aa578b01581d6048d9a7288085a59b7dcf3a56d8072e2ab4e630807e8b158d54b2f2630f883f4aa3c62538f73b91d2064f43405b2c5c79284c96f047569ce412f7070637ba88bf2e486280786ff27127f0e5ae95759adc99ae13321c17df7d3619a8f3a45b4f6c57d343e1bcefdefe617046c5cbe96c64de65f350b79c8c23c64ecd9124155f721a17a7ca842fc5a398d9c0bb92e6c76be971909cf164a837ee8992e82b1d7bbba42bd3de025946e0887e2648fc6272542dc0ce83f885e41895349512e87a3ea053c62b9e370e8be7fdd4b178dee2249a17859554f823fd7c7cea056633167aec74e66a5b7f7b768db2a3b0cfb96691d00959750a30dea6f036a585e51fc36a7c02b75cd25ec05b8719169f17d5581a5c436088da3a946abeb677048f0621a237d5e2f0be2c06abe50db79ffc3494cb0b6b4ece20000cd5ed834196e0fac0dfbec9c8e3aaea060b7d27aba4576dd90d639be7a2026340eca252a0f40b1717d03c358e47cb33252eef01b23e0088fa274e992e714e40a257512278bda8b0d5532cacb22b4de5dd8c9d85019a57cf102245f9c50572aadecd436dc2d17879d22617b18a4a05db250b8ca2b903bbf9632bd68a36c302dbc9ea0cd7309f40998a00c1562f74f12ae8a99fcadd639552cd3b6b30f5e20e806ebcc25edfa0162a0bb0cacae98ffbfb6d062e5e9e9d14593df0eb59a48d6a5b3a9b2a714410395825e13ed9a42f3319658a042a58301340a0b47c3d6d0a80c1e0037e04b3c8af0f89797b9944c03e737dcaf8c18ff3656824208021bae25b512c3da6d7e025d1378acbe73e8af84a6ad6dfeb475263fd6406df44903fd669693780c287e1bf5ea5fa229bf8a781e29d1014c09445b999512e0e083a278150533d9047416e05522ab47543d0b78ad9355276b53ad318cadfc58f818459b526254c0e8d6f9b12875fc19b02e1acec997c73a4c0280de9ba509c641787cc5c5521c324b6ae0ba0957132225188522e54bac9c5d5ca10c61475333f5acfb6835d4acdc4976a7c2dfb9be39e1d7d5dc15f18855138e42a6ea9627c921153992a3d85d9db11d91bb0d347058864c8c1f3a74083cbfa4eabbf6509b85685cc2f7f2546c9f57ff8c49e898865e60860aa175f789dcd2bb7546e2df202e1097cfda391d1ecdcb9cdf2e387b7adf49a5332508bc6c141e3403fa3bd2d0bb9cb7928e78ae8908a35c7f54b851cd976410865a6228f2ce81cec7b1b0538319f43b05ff8e1f50c0f8b652055110986b73c6002fff07146856bba646877475a8bd74a0a6006939d572d72275b5b8b33d95aa24cbbb737afa93123b3ee8f879c24619d4f7472ac811e09ca9c6ce319d6271af8669c498a32248e79213d7de615cc3b4720812a6553b2995b0c7b9d64dbff9caf6847f03f045bc8822cd35967ede46cbd2fc42a97b20d7c04e421d8e31d88b0d9846e6e041bafafded72a1b37b3a77caeeb28e709e10b37cd43d891e20cb6ef91415f0ddb2f31425359103105b323835c8298cbb451cf5c9f3a1e89f4af81363da12648debda88cf9620a2384344fb22673c914c97090db24438de6a34ee1df1247665dbf2d5df86fd802d80027be4378a723bdab34209e161c807e441e5297d678311f48935b7fa3200b9e5f063f58274a1be0a46235fa07a027ca13a86d7fd19d5e74e0e2fe73f460150dbfaf9dfc33e86b5236c049cc98e7d5f183384b5fae31bf0ea3980dadbfd6ce6bda285aadb2a60d11c205c3aee914840da6045e09ec6f72761e0973b889e48eb492a71b76ad126bed5077abc023855191276d3f5c276da0a1bf96a3b9c7bd1d49a8c06d6a670f3cf71f8e08bba42422665a796b4d4ff0cdeb673f9bfbcdb53bf4c5649202b9a475f747da515ca4750d72e99dd4188a0d5c15e16111cc76aac06b7792d95051a0d59a32584cc33db7103878ae1130b03eb1eb9effeab05a34e47e7ab268c115b5d93252ad40221bb23a0e63778caa4b9c2939c674558725480f01629a45873b2cc5f2fa2e40536d71de5b9ca161dbbf1f4775a402bc3ac77ecba7c79b095553211e6fefb392fa8e979bdbcea5422cdff8ee0fcb09a2693c4427900b24857b16af2b7def45398239c0ccaea76ffff02456b04a73abe742b85c045bf0cd6930ed796b9c1692855c04c15e520853a956a0c1d54708097c761bb100b9496489d22ebb05128350fb6645e4a3723ce21652b333b78e0535521731237ee8e977e9994b73efd43caf403d48b5b224e5d4b85aa25e6a8b27945354963ec2975e77cdcc561116be02cfb5106c3c328bba4bcf9088562a37e9e854227684b28ce56ee8a4f320e9af6b2c18e3dd38c9c351a9635634d91e5052301a6a3a2b84732449ae7f7c4120bf5a028832260b586b75cb9ce17c255bf936082e42da6e4e3703e754433f40dfdb02a6f6eff993ac99f3b1cbc256c8cbab472ef060ac06a277237e443ffd00d8913542b7fd4263d1784e63b175652427acc1d3eae9d8a5ce87831c00bca68088bf8d71c404b5f71eb10b1846b6b49e8c4566012cf5adfea379259e456f018b248f34c1a76f5bbf3d3273f9754d62c75ca01cd22a4c859e81270e6e9b15896bc83d479674c4f5d217c80177e37fd7b0b8d81f8621b998492b92dcc55e661cca46d7b6bd447007fc8ad837e31518c1c71f2a805730f8564abef0bd8decbdfee530172fcbe16af97ef3bec7297229116b233c7efb38c4550c6dff1437a2e72e6452b0ad7a996385c3a7f2add265cf43f456ba34a7a21751f277ea77750b8596ff426ae438f4e688820fa4a2361d51bcb546ba374ea0f7a9b80f1eb4f0da85fca23cb7d1822b260e0c8043e31cd8a023e5f2cdcebaff0a75a4355d67f7448ce3f9bfea5b481b8a047c3e0605b06987ffbda8043712be32a3950cb41eeacbbfd74f3bbe1e231025636fa38472bc611957784fe0dc799da4c632d59d9b76356c8828221f63d4d29d76285d6706ad82a94a52f09054ec66101c53c7efced2095f55b2a1b9ff51af8a8ed16f20b7d44e6862fbfd9da0afb61d58e4dd8ec9d3cf8a242ff5125761ca06840029088a0e41c6366564eff5db3c1589363b5d366daaa19c087a8eb8351b7abf6e1a30733a10ce4a3bd22e7e0fe8d74707f622b09598038bf6c9a63e5869da25adddd938d9e4aa60599984ced983f73ec91eda50afc0fb3994ec3b5d8b87f00ac427ef9bb29b81f6be21fe45c8250ff92d8e01d450956be0a21759b5305dfcca972fe9875050342e4f90524905b9c52bebe3b0d99a81ffb4dc721f15e8202933c1a8a9ecbedc86ad760df475140997d65b92014add158bf9f566ea99558294cc0a564ad9981e2160c03ddccc9a403e6193352c84967d44a666b51a19bdbf488587829f44698264e92563db760dd1e82ad8ad82d5a03dffac136e915b67f75b34cd3ad02c34dd576dfb8a0e08967eb1662ea0e482fff474f4f923eba4f09922c23ad78e18dc6dc5e1117d0f96cbf4d22a441f3ef52d137c21b3d5ce01ca1cb654930c36ef42fbe111d66da8e6bbd8dcf6e381ab2efbb78c8679497a0026722b93a17fefcc98a1e99011b83a16609b363631c34e702ed8dcb20463357dde44143e8742d443c77c2ff7a62e9c49c217abfc935fc9b505bd29e0aa84066be0ad2a734cb81ed6a10558b6aa48740eb0bc9aefe5da1230f0a133dbbf5028d40f0ca7128075d846e052aa92a2622df7e4fd0358c0a5ec09e8f9e0b09430441d3d91b9591017ea2d8ff1c3b809588fb3459fde93dcc6935903836c1143ac61d84ab14465b88555ffed6c82fa74ec97dfcb92d6add40e7b002f3f6d9d68102084b482e6d3ed0fbdc4016858046142340df7f41fa8452d031a7522ff1840931f48d69d732edaebff6e7694fc478158457fdca8ba01c38b0001e5a05c7b84fdc7febc3aa7620a624202ed296622184befafbbe00f044406239e980be8557a228378588470edf4094e251cb0c62bdc2ce4595d6f437c625900dd096d45fc88cfe7ebf328506ec62120d1eb694e49aa983bf92786c03a7292bd9b61431e79f14628d0e3980a6ede583f470f829cf48a20f67234bf9c4e278863ec3a5ff1571d91a04deaa6f8749df5abb83a4b93cb2eec3fcc1bbb51f43b1b101decc261c23bf6de2ea25d4d82e68b53546668c797d8f446afbe506c5a36e3175bb2b21e7f291e2b6b1afcbf14c26731b9b691aef889ecb81ed42cbeaae674ef6cc43f9766bb191c097a47e9204e5a80bf2d7fb1178488abbe54a0addbc5d15394d402af3ceb3beba5a7d3b41ffc4dbf56c572ebacf8bed43bba07b256e132962d7295026276b1ae20798a35bb9979d1340fa0196abd69558128858589972b20f5e15d3accfa99fd89696a5aae61baf0184bf2b6494ed6a1e3d5ff22250403c90742e0a0d4405576b005f45f2a24991346e36c19d73a268688eae63f8955b48611df27a152c9cedc89a93b6e8c903b126a50800db00a4c9605193a3d1cd5114a8c09dce761632bd90ba5467148c964889a8d8c0bf0c0854d7905c09f96702fc7fb8dbd8d0fef411221e3baf15a716cd45ed58ff1c629cfe1e9b1cfd98f5ebca97a52ead5367719e667e7ffc79793acc73ee76e158d3f675fdc35c152e169f5f983426b572dcd9d32356969a95fbcfa5de3956afda64f799fd1337a91c8e2e3b068a38adf2272a05909b1ec40770814b15b9fe5241b0e71dbb7a48630d2d061952d7f50bb414ed9724dbcc1147d741fda553f6adb55a1fe6103ff82f8530f1dd629f806559a22a898e0b31a3f8fdbd93501ff49d8428f5d21b19a3a561d5583b7b03fcef76687dcf341c0817fc1aca0774736eeffd414e4ce0c978ef3e5cdd01a62752f652f4ffd434de30f17cb7ec35eed966c9d67bcb90facc9fbe6cde978c79fa4de8ceb5fbc11989a07fdf134b0e2b0f186755e16653108a87be87b67253a077868827e502162bd6d80e7fb747c01b5cc21396de26df047e5b8288243c6443e5be5cb81c1df882eff9eecd09db87fb874ee1462cdecdf3ff50d1fb4a75e909bd0e8be102144f9447241981803183daeeccfc3c39166a7f3139b7236dad20ae01e2ba618c42b5575797d701ec1f8579ffb9f8f81552d34640cce57a3e5ef1d457a09ab38105b9d2ceee862a56a7f20fd2b794b15f0b49872124e14d1257e11a9be8527c6b824fd9916a219bba0d2443388baeab10abc54e3e9110d98e586dd47ba02294a9a67c2c4b4e36a71e9dbd12ae4725ebe4bdfa2d08c252c26396435dd3a7a851200106bb79b0bcd7a0f7d76391193cedb7180f3fa3b64e936b8b292b1e28444d230710e0b3b79d33864c686d5e309c5568dfe4336703e5f58b7ec19a85a8029ac5be6aab23b520ee252987105aa0d86046261846f9c0e4d8cb4742f81f665c2f0dca85bbd109a20d4aba2369317db5b01aedccac1e8aff4bfaf57d33e6583bad4aab0d8cb45a72a5ef3c00fcf7106c805411fb0e4babfe2969d859bb1578ca79f0a5c4a48ba3abe1dec8db097ae868888d9cf047823f0933560eca0a738d1fb669e82e7dc3d5013fa44aaf588fcd418fa07d7d3151ad51d928de9e7c4cec997efbb3014216001d0f1c53aca3f847028d4f37d93ab6e966cb0afc87c2cd2d127c09fbe0b320e9c54c6fbe813172a4460792188f0a899555a20b0419140be450a2cc15cbe4163122dffb5964aa01c6bb3604f4cb9cab99b5a46baf8670fcd650d843861703cbcb328dee9ec69889815a09202020cae928af2a6cd75572d4e8e12afc698d440565aeb3f5812da2fcfd28a63038d7e495bd76c203ad07637b67087dbab616c2082145f7ee48c3c7ff092a9d733360e64591aa923f6d1f3235cc275697a1e18eee49236223b739e1ffd688de03bc9824b6c4bb4fd2fa1211c852b4d7c995d51c6c49788c009fd8cfc4981c054add2a4dae2af1081262c6c08dd843b88d84f7587ba8a0684c6dc29bd68d88c451943e2518070befcf0024ac5a11a554e4ed83bb8cb033c592c15667bd3d74339c65b70c6ae64de1ef2a04fcfff992ea5b6bc78368e5665e8eb387057f981ebd84bc90c85d0ce5c43c785f2b1cf2727e754353a0a723a94537c3ab5fae89953b688623661ef27b0cc8d4f2f1559dcef68e5ba1910cbdc3e5abde77c9cd4f10273f41d2193cb9360ce48e51a883456699a40d6894e8d482bf737dc097ae04dc2073de3a6eeec2a63b27d939c8ee7f6600ca00f267231ee980f10d8e5f6c4eae5fcedbb65ae11bb89606078a3081f172a211bc3d5ce6e55f20a5d6e1b5aaff320dd30828e599f507c32e366534be6ca5dac74642eeb3487a7c58691f6f0bce3a27583701edb40d7c6c4226806ecff26d1bcfbd499b735c2349c80e9c39a0898d64de1bd71648356f436f8bceb59f71a3fedeb350fd6118c67a8571aff432e10c4a0e6444c60db82e674eab6cdf13273ad6b379e67d3e29c2bc4b09b151d02fb68fc1188cc56417525956ec0978da3243d783c08b70d6bcce330287f9845286b15e062ffb84703e5eb8ffd6ee9e22fda08acedc7de4da7431c528766e0f1ee942d619e9cd5ddbcd407bf00e5be3b003753032857acd4f21a4388d266734a5e529491f9e22e5351c3bda0c9dfc31ed77e630e29854d1870a54e3e799b55524c736e230df74257ac22ebf33abdbde834b384f3392df55c8b9502ab193463b740ffcbdf6ab2e88f10cb09166dd084422e489540a5e84d28c4bb3bc4eb844229459cf9332802d6dde5e72d8abfb6b8e74346200600c708cc73d275ca70007c5b2d19e5800dddf9698d42dee1afccc2526677784affe767088e0e9af633111d66d248c70ac8f0e8704d9b5cebb1b6e865b0f7c4f966d2be989342d21ea595ba64f7a97cdfd88cc06d6042cad232e8638f34f74ac95fe11655c1b083164582400e37377f105b1a3e904a2eccadc20dfafb916d086246f97b52b7693736f9a5af215d4801dacf6fe7f66428dd038c2d285b32387fe62a0571fd2ccacc15f47e37d328e7b32d453825eb99461ec5cf85cbf20e97a22d56b21bd560a98725440061f8e7bfd39d7b3661e907c41e951314285bd8322d848be0ed80dc611eed7619c4e0f20004397f87ebb560449b710c096d78a4268a2d1dd64709849107e5d85511b8824a1ed6a53fba26cea8aebb9f24e26f7ed8fa3cf591418c6f9e6474f3aa5a7d0a3c5d62941ded7bab8d77d6b45fafa2147d97f3ec9a3e135712afdbeb6b80acf30e64e1f60affb4befd1a02e8723f7a72b3c4581059dd02abad76eaee269082852ea3721b9c12dcebd20b533123aa98e07e45e4b130c90a19f8ae1bb27f37e799d392d7301896a1b062f1e92d4f89d2f197b239b688040ed5893cdb851beaddf86c3c43dd92557eb1451c9c82b4801a9f16af81fb9b0ea1a39c4f59176c79da7b7e31fef253a6bf71360348604002577b01f188371218862a6fadb94b651560ab21557edc4aca92900d32e79a9d5eec2149dd61a6f54d6a5e319a16d436213b86b79af74921aa8868f4425d65036edc0e229d18d0a49664acae99554ada13be47818be45d770200b0d586ee9bcfc62af4debcd9b873e0cd7137c4b491c690d48dc69223508f1547560c7ba8fff6b83d1dde42cb614c15eb706c95a58d39b66573d685a7284aca5e58c210b9145083ef70206878b7398dc2bcca52d372317a881bbef2145a683aa260339e7cff032af8bfa1c004e0de128e390c8c539fe18a27faac4d5e62f949c708af2610d7e1b8cbca8359633580fd25c0651997b1420f45ddece6e86bf9f48a54ceff6ded9097db41630de4ce9cc6bac4cb61a66a47369913b5c40b3dfdcefbe7bed04395a200d0a9db05e5af5047118693f2891c2ccb62a61c00dc3799e584defec1c8e526458d8515cc5718d239ebc6b8297a78d8c36f6255e02e0f114bc08b2ca5cab7bea82a877baf2f03ad0c08aa67d2adf014c2a65a9e51b88d167c54710add4c3be23551a6b0598662d4d75b374bcd39a23d1b9999bbd62674a788417347b996e65d9981e636121b9430f0c9393a1fa83e02c8d3686796078e9a193800fd8c0948771b51739655d873e7679135a896c31adced466ca56f2207dbe9d062d08fbe0eded200e963b273057b99bad4b1d14804dc8db426e9409ad9e656358cbe38c2544113477d7c8367ab105a95f3a62f82ae9a24b2e7c2122e7f252905f6ac276309043fdcb46ed2c39729dfed7d0d25a146402ecec9b2efd3da5bcde58e007d8bb5807d1743e97428d248d1fa9ab5320d5c912cfb2669d491a4e27a9666b2d7026116bb32c352944b4f8a4c359fd4ca2b7a52f4f2f64cf80ff5e7e9a56b1255b790abd37863d1cb50f6548f48407a44f065252858b174ba8970a0b49f549651876e061cd51fb252e4971c95660769a1da0de59d0155a6598a616942237350503f55d0452cbd4831b76fe6cb6111efc42d8046f0de1bead925736da1f63015473facd0fa772078a82bfe38b7d13182585f6d5a0b4eae457b5af534b9f1a2e54825829664d4f5029092f330235db72572911a3189266f3faa8a623b17ecfea2efdd549444833905349dcc63e244380a377b030d0b4f81d333feaf26fd6810d362dd0fd0bd972239b420934b9a9c586599a6e633e0d68b040137de0cb3d295325171feb5b90fd73ba26b4d0fdb61b115e482606623dad72ca55db486470686d4403e6e3d3f6d1adb011f5d6d3da6cc434e2e525e96a8da4b87ef0fa9d86e74a806fcaf3492c5d82d3505b7b7f51af0edbaaf668ad9509aff7f110a095b2f84d58d1e6bb71af067751facae9debf89bb2afc09ab653bd77259d77ca020f97af9379f04513bfd3fbfbce64efa43dfd12aa8ef644b7cf840efedfcbb432a4b8bba71b58910aed6b11d96293530942fb5320eb991546950e7ebe9beafa78ee8a8cdfc82fb688785ff5363df4926482082ec7d50645a970a956f881ab1a1e174c8fdd6a933f31f68939bf826b3b9edb86f4f233cba48078b8c2af19d2d2902612b2f31d9d75ec85e50fccff1efe8dca7c82d30c8970a88f00b90849f288ce897b7e876d48beb5d0f6bfd0c450a9797e8ef8a0c928a15137bbe0dafb1d6c66915badb635fcccb24ca167997820019a3ce445da897f6debac8b92a95520a272abde53329fc1a7fa290e3819d4df16a8507766f884910cc111c234e7d5a8e23697f1e5e4c6715a4fe54ddddf413c54f833fea8b5c02e46d09018460ce9e622280197df7bc7f2760af1a5267a1a8d0566a331da7d286a870e9c32a25962b8c1320b81b5dba98829b155c0f1fa7e271651298f873c800a228d0b178e8fff456984eced3b8dfa72e04b26621a4ee81dac7f2a29e9e5a4b4d0b75a85c8251e52a54a9cdf324017b7af309d1f1fc8dcf72ed13b849d327f4681489e08f3d997e6998a60a9c170c8dc275a8310e79fe28d4286ab00d0dc612f40aa5f5a0684c669a87e116e162d31040c3eb095a48c002681577590ec5ef6f7bdd0e5d6dd6cadd1e8d19f1f106c7850a6a8b24e6e4c57f0beff23413e4e6e9806ba0e9a51e4084214b45ffba53b6b632486c281f81025378e47ea69b63760a16ecb93844908ce3a749c404decab522dd04edbd8570760b1c8f1f2e038bc0903a1905df8230b2df7d0f9413bfa9c1ca9f9469f6ad306d14568695f7ec5eb2b06d1b921a53aaf141be9ccf89d5fd00fbc6674ae911a8f4c3d34f2fb5131bffc57d8c1aed201bcb2253f38415bef8987531c3f27d117893dd75cd089c4380ee0a6eb24fe5abd792e26964121f6d1ac46b26fac7cdac90e0afac21c77f9ae6691d6f662bdc5621109ce27c3520c4277eda2a0d13d7ad71da31560dd3c3365513889b530895f4aff9415f53acc8c5cdc5e8318a3cf552cc4a15de8a1dffb6d7cf70c399869d6e41c397999496d4af23c36212f8b5082f85679c98105b1d4ed5f4b87125f8581f76c39f137707378c3050ce93a7aa7265b66a2e83b36a767f680622b446eb468475ac71c8d43fb3a30d1513faeaffa98ccdd7f0245231dccf2fbf06b047fb174782b1436e03842d2e831f8eb806f940c5f4914a5bfa55b8b5a367a679f0d4da29c6ca331a7c8d7f2856c897c712871d6af2cca44b7c95132ec812aa267498566ab037d183313070f10b6a099ccb95e1df25d7a78f37852c6a084c4fb07caefc70e796c5fae631b62e2c81852694969680286986cd9a30a1215df8240daf7afaa6d1fd29d82de85323a9126e89c958214bf864fe096d7dc6025e5b40375f651650211d78b87562fa32bbd302a7aa5a076142774c7cb627692483fad765a30ae0eaaba7db1198bd4be96591b4010f8f99e988d726792f1d1aabd983e9945fc547be03b454d9ffe1700e7e81e340d48c281a2b377c1c261fe07d385d8bb4ee7e84df400313f4743f123d103c7d4baec2098584b2f81357b1e651344c13646b024360534f71ff803bb115e3233e606ead1ad83803a1b7aed517230015387416be73c66c4c40bce62620fe9f796e837f887e6039c53a6eea64b98c7cc18674a575b095546422b0163708cca840995d8facd80e1064b6ca3c9a931635e6f94b899e79e9833ff325382bc6572866cac5e9f24eac0e8de9f3ed139b6a738d838890a06e1f4f14836fa751e899b67bd903be65f284980819c9279cdd6827c09f05a0df8e5919b0f22a0da7b4cea783317ad6f10e30a555804e586fd1a58a2dd8f867af302a690d0ed070218d9a4cf2e996b809baaa2a0cb56874424e488e4f4cb518c5a89dc4b80bfa780e3b13bfc6a95350db12cb3c2cc80ce03759a2c0be69228cf9a89f2bf5134eb3feb21d82b1552ac221270b20412d5344fb9d14ef90948f801c61fb30324e2c8ea4f1cea26e42b67ffe1fe5910358fa851395e03fb8c09a7756ebf9edc6bcf1be60bf20478b5975015af49d5790f36074c3d38e826e8ddff3d554333b3230c2eb123ad1195f4a89f29b53fd817a646166304e79d5d8ab9114d2e9fc06707174c3708d5c5832576d375c73479a3e14dea199e003c09c02740161b6ceeaab7be1dce0d5304a45f9f290146e5d4b9515324258fac723dc48b50695dbab33b3cc5e264691c0a136dbe25df2f37671401658d7563a1c19a5f128c92a5aa228d1d4bd12b033db3424086e8273330b9ae44a356927be6b41ecf24d76492eb3325b078f7d27cd3d514513a5dfa22de4c2d0d7bc52499c82a4c4f0e73fe2de29e0316303b4f821aad02193bbba35bfc5d251aaede7bdb3db0661aa4d3eaac02c61541fe8d6e410d26753885e9396dbf667ad08137d0565ab724600d38e0f086482ab472e5df60a1fdd2e4702b1e681b7f1300d5de307c44a651a6a6eded408be0833c04e535c1b24adeeedfaad26138256f736b99361d054b0f6d4a4d5a759887799c3f197252eb035e56227012ca9328afdb3555b93de560284e19471227b7aa0ca846e9c82ac0cb032d8d5cc365e2be80afdd3a97c3b8b49d873f61f884c76946d88c22b09a5133aa89dc60528d0d90b8a40ba85af90eff98efd9f54459c13411392db2b052bc4a8efc146c0ef087bc09184463dfc14fc7bc4d1b3021661d538e2b85c7ea18e7a63c369ea9030ad9934a8ed022961a249485bcfd1596177597f54b8536ec78ef55c20da76baa8fc4b5fe79e0e2af73ea0a24426470884482b13ad0a5c76a093ed6c0978d7fb5e94c5673b43bac3029b8345bd7178fe92c3838c0b99dd6440ce6b265c71cfa2f54aa8e8e5174bddaa083c5d430fc8d76ae6b25988cf283124c557b30d350ad8628a56a1977ae203f6245ac4cef328edd07241608afa0714fd6a4dc68820308647180dd3cfffb4b7ee0b5ec7bb89c204030761c1b9273a9b43b35111246f2a3494418bac41c5d003bdf1f6ed2f45d52669e58eb3b0705ac59de50c3071d867e6e77fbebd40ff3b2e63c002b590b23aee545fcaf8ad21b0fb8a3bf34f92fd3191305aa6b8fb7f45a371b347245d146e6bb0a0779a71f88a258d97e1f1a0fde23e537fe6f96ea91eaaef2a30e7e8d252c8d2090b013299884f5c9752d81ba5dd9eb4b7b9299cd6bf0cfe3769314ffa291fb90ea07e53630a9dea2f5f38b53c9819bd659dddbeceec7e2a9e029e6bf22b6b16897c56fa138a042d1dd3e2a723e5461b653d77e3da39a58e4fbd46e0626050ab2565978a294e5d217d9e1bd18675a7802628d6814b070062e5a24774f01bbfc0323c24d6ae59b56728f06fb3d093947218697d9515321e88683e834f6b539c04bca72a264922ae00207915c59dee8ce1168e82699c6bf41b6219083cc06b0076c93c56a4518b880eb873a261af5908f6504541345c45a9f00d9d1280ec95f37836ea2c73264b540a80f60d01dc06faa8fa27962acd00023b9072bd4721f155a5631f1a146e2ba94fd30939a172889eb140eff1276e19872e7f25b1274855827d5fb574887c1bea6f522f33033766b53922c7817d74ee51bb12a41fbb44f6065abf04d2375103484ce2c8ed6507c2e57a2641baf061a92e523fa81d882cf21c6338c3f66207906acb6d5ca57409f9547c7cee03150298c82967670f5eb5c46f6f071fe967f99131f657de49db4beb248399a0449372f29b5e167a824274acde82ca46d550018d6355e50611eb1c52b06c031c267993fa1c71dde4e1920888af34052ec239756fe535f54b548852c3fbeddd34f7754bde4f746046041baf031f13f5b981b44adfd5adc592c1db0dc780953acd58eb329c6da6435a9da201260509edda12698dc86fd4492c99dd1c15340d49e0282cc6883a419b5f98b8f16298d369c02720fdf6b9895432d1c8c47d3b0ff33000bceafdb10c81cc8de415cf2ad971132643949975fbf4a6cdfeb9e3ded090a49e4124ecd6b9e28e5695517d3ad80f7f8f151035cb59b337406c9597b9549b9926887add70aace7f2318d5eb35d0a5f345ae5214a9d3c75ea446163c23c02ebe7fb8437f57303fcde7193b8f7758919190342b267444c5465c205707f6946de1bf99b1fb37e6a6fd2eb54329369c8ddd425ec1144fb9a6e20833d8fc1b3bb7c78114bd57a2bfca86c452ede793c4b90079c2b7c53cf3bb79ce9723a621d12e60c93efbe01fb6a2649574ec08799807c573d0665c2cf708476010e8a16940f05789aace1c660f545e4dd44ded8745783894a521c04182fde5215d1b98f00611499b7c803a4824afecdbc7374fb7c569e710a7ba209ccb6692b803174e899aec83ff864bdc4db8821f513a17580341afcc3801d5a662d58ef218061597fdf086e7ff88f22a061f9777a155b582754d76ebb4e3eb51010b7b3359645703650548f08e08ca018d2889f9e66fda219cf61789ca26b7b7697e0b1f3600edd34b25f98980bd237538197b7d5dddf2ec09b81d5dd059a2bd4dc66e26454c2ed84c7f31e8f4f7db2a0dcd2a39254d7a369a8e52d0ea5dba1ea982522cd1a893216c46241d1b205ad4a6c61fcc0a2b098f331833a6ff41250ebec90a232a7ab928dba8e27fda88dd3bbbfdefe6a2457064d1dcaff9fd6445196739aef30c12ffd552c765affa6b7151d0d3d83b0422befa8c0f90e014c227c1856e4dcbff81d1f0d1a1d9bd2d344bfe214fb7c275700ccb07ae176c838e21960928a679b9b6aabc53cebf1b34ef3d940057b7227850600f2092d394895aa14a950099089f41557db050a84cb86d92fb5c5834b019237338317139a53b55497f5822c1043e4eb04970264bbfd267c18d0c00f6ac32ae1c00d83308d61a840929607f5a1950cd3a195c073cf0d68fbf90010ff6321be067f87febefe036356810d43dff2fab0bc64d8841896ab81f62fadf21ea1e5a2101ffa9e2ddef3fe811abe0595a4e695261719fe17dafe25aa71f5b3cdc478762f787b9afa3cd20933abed0fce71ed63ecb0a7ac758d438f3c806357b7ec9523429e6eabcfa70928a14e70beca5284060eff01c3281cf4a0843ac78ebb524dbf478aff9acd971498e06af2f44b897b6e79eea378187ae4c7b1484de074a04882a6e44d43b06a75bd7f3af071983414bf49008bc424ffc4faa618d094bbeae8abe157ba5c7226ebedefd1560b8bd5ac4f4f6121930effe058340816a8bd4598b05d25897e9913c546a2dd0ab549e65e8dcc22add090656c08376582ec02302908e980b21599adb2e89ae14200e12c5ce57cadd2cf957ee1d99fff50723b48a0fce6fc722ebd7c13624aaa974fd159a9bad85d2673b20f7acb8d5b852661adc4b466b1ff1151d1aebdcf5f165222c6b7336e0915500f4f09ffed623be311f2aa6b4185b166714b72ac659b12c514e8b4a523d7048162b4bd16deca8d065dc1141dc8c0e5399aca04a946f817de2b9802434374a081bc7c9b40b91953bce613c216e4e73608033ef93e176c99c43e1c876b95b7e9d98fefad3235de3f24e475389ba4cf44575b06a31a959e11e7003b4a09e8d2b134da54113baee834fde8a25169ab784b6016af83eb62fe3f57e230e7d9c55bf5c2b3c6e830662daf511122eab6eca641a1256df9d864649e3d5df6fddb0036e8ddd98ab16c0c23c5b1a1ba628839d93cb1167cd82d2de8ec8e0d5d978cfc33fda2300a4f0ef797c3c8bab8a61a3af6a20574336143a7e1a5d89ce0c413307b0269235fd113742bea3696700e6765a0e0c20fc30e4e6c24eef9c6b8e4b7b6cacdec06a57cc1d7ddbb9d974a84859e25a8a103a610329fcecab882fccfa3f0c61cbc26a6a0562c3065814abd2cb1eaad503cf3be046983bf012bd7cc2c8ea7a2ebf0edf6c17fbac8cab7419f178bf5e8380290e9194c3ff9318fb368dffad86c58f2b1e63a78bb6df06f7884ff975d079325e0b72cdf502ed87c2193c05e801090ea0f18a10590bf8143858cc2de5541d3430cce18e26deb1f5fe1ffee7d424375ba7addba197f4f703458c5b1bfae7d8278fee1a077ebd6667f1da6ec22f14da1ff37b658b7ce4865609ce6094419ce2e1596adbaac5b4fd5d7011d7b7cefe6015e71522bc26fabcb76c0ca1264d0fe3df2d477f192c3a5c25eebe24ab17816ffb78e8af0a505d6a7bf5919e95331b383c5da3ef168d48b21459dd73742c3be98745ca15df1e7fd8be3705970f6f2266b90a9a9e065fe4254f6e463cfbeeeae227400e55abfe64e55b6ca0d2108d48664fef02a28098cba08fc20a99bc793a187adf47d449a5b8da3a220bc3dc8f88acfdc18374c15e82a03638fbb9848af21ace8bf5486fd8d70861ec2d91330363faf411ab6b50d159497af6540a1a36795a1299b04e3c2818cbcf77213442b5f9ab95bf6ea881041fe76766c44ccac9c3c6b052e6d20a24afe979d1f188dafd362087e7ac21945a3091485c35af34e6825b7f1b934da62eed45daafae4e960b917e645b74bd1f3f0c7decd9b6a7758e66e1d882b63d3864ceb7038b680395b3194cc3b138971c21463e076f891871ca15f7ee4527c0908bb6195281f87c36178b062bf72e58beba8343a041596624ab76b41023cc014816988c841f2b634edbfe5ca545b5c0a8d0b2243e65ef855f8e02e73ee7e9e137832f6cc07f3ae72dedb969bff0a57c865e2950780af6ebc4296f1bcf3b7b80b452686d1dfce5748199767faa9e1cd22f16a269d42212a987317545142c3472532a8d754aca985c280f6a5788106776991c81ddde7f9846588a57e024da9c76d17d72acc30f59e912720d5428ea864c89a7653a6a33e0d88ce7cbbcfd483fcf2e6aa7366ea256a63ed13e82e0ae8152141942b9e2360d1dbbb37dc8903ea63c27e5c304ebaa20e063f373c8bee419b70ebdae4effa8823c73c38bc35e9ad41af0bd2533079c644177898fde4add14a9740b1ced0c101888228a8cc74a2cf5ccf0ab91501cbe79da63fe1eb8b5fc9fa2a39fbea2768bb4b88dc7b4b99520a0c08c707b7074f5ec4e87863458c8b90270f9d1ef37112c103142d70b139865b903084086eb139722cf4b9050e4d3117c229433c288b2de6020e1e9a2c89d19fe39096c55c6014c4684b0a4dbf7744cb50cc859c31616099433a886928e6024c861d144f4289165ddc622128d27148bf30025dcc855924c66ea314c1af511cb20b94aed8c5e6183211f3b1af0b4ea4dda53ca55d62964566c00070014c7f950e5a8304960c614521df4869e101f3fbeb651b81118270dd00169d741dcf2ffed0db51d4fbc3afe7f53a5d50fc768ba7cbab60f18bbf0057dcddf90b70c5b6bb3b0f6100b2f09c32be04932c9261b445068009db93bed724497a3446ce39dd65487ef99324d36c12f24dabb83573c571e67ed78058e2c0b623cd1e7c021145268a76229f4008892574e9d2ee347bf029e6c914611fb92b2799db9dc479390b921e7876572cd05bc32f56a94ce82adab85c7f15fb887e390b9227f6ce2e21df1c95bc74d963cfc3b9fc5eabf42af567fa5d73a0e5a6c82afbcc6005ac882bb81451e3d6d6501d562c0e52e6563145891388944b20c2d62e229c4164f919ac41a506951a546a50a941a506951a5474603a37a438b5083dd8596fce78b0b33edb8742fe64884eae662e6719e3091e32f09865796ae27994292d11a4026d37d00b54189492122ef0ac308102d28b029d75dcc549182b71c94dbc8bb203988b627445d2f54f4156e372ee87312e7839f703184f84f683f57876e6f3dec65b500023967f1686b1332ee77ec0e2a675390b089cc82813d773fdd58673cbc4b9a50e8e195b83bb3881704b06436fc96282849a49110bee5c81945c0f37a19c0f58889c7250c2202141cec88a915b4e0448b4dc085a90fb81caedd95e1111540525463409420645298623a8406a02871c6e6802450c65440aacc85091d62bfa8e386f4e2cc91029754b455d773737c063fed51ed335bfbe2eace337d20ca9f551ad2175c847244684355d93b664f06b7a317ecd0608d9669a4678b46331d55f478d3ba6abeca75beb37ce2f75a4f99e486ccaa6ab7e6aa4f95a3d825cf589c46602a84d51eaafcf43c94f577d29ee9faaef5f5b343e50ef8fa2f95a3027ebf74cd70742d8af3f65b3fe9cd5f75d7d7ff266d3557d17f36aed7408849de5a797b38411d34ed42c6660518b86785fad161083224d3c0102dd0c359d305c4e00430abe1459129b73ce3951484c2cb9f373cc39278da62e6202f384689d29f75a6ba5f3f331f55f6a7e3c53616a2cfba6649807f533a38c2a858b6a95f4837837f55feaafdf2c36f5f4c3d43845275b14ff7bf1a346acf8f341ef7f661dc5ff46be2208ce4ffc298262abc73d2af6f77defdf47a97fdee3f58b3027515642bed1e969c19ca441a82ff231544b8a7f7feec9d2e5dc13a45b9270fbede5dc1311dcd0555fae28e8b2fa89187faed5fbd902ff67fe781dfdd9bff98deff5e8c0b07c3fd96f5937847cc33ebf29fda982044e8a40718361894810424061cb3d012505344c3aa74fa73c10b1a39452fad3137f784b0527bdff4ba3c996f57a2084c0c816445fc81084939817c653172f2890dd10460962debff7a4f775f2a8e02eaf0b3b73b33cd0f3bc67afb91d72d7f372bdaf717707e2a4f73f5ec208ac7f7b5e77bd021ed9e1764b180c9683cbb91d9ca492ec2003a8646fb258b23649883758d61499176c069773b51c5245d8d5e55cad488864c330324b7051bf5895153336587105a918581413a818585412a8c456a4f0488823ec7739e764cacc072c7839e7c4a88793da5754adb563ada25d2d29b151fa234404e0c890cd91284900a00bc0911d90d49810060d00479080804656337baaa1031894686650e8c041905107b32a38b09838983dd161831d3228b166488634d821c36d6004cc0d193069e0469880b212d3343350e9a84c1675396724e996b02936ccb8ad8ce460838c1d4772342accc8111a6cb555b44a33c2cc3003868c0a7bc14ca6da2a5a31365bc4c988ca8418d0668ab0c00671662403ab4bec888156e48824eeee636a758c912d819009639e6a85ed706b7dd157f559b5de5a6bad6198dcc54d7567c33cb98bc5c8dcc54ee68ad068d861243786861d300cd52e66f05e48daf1c21258613a1c68b555b44f5d4c7872faac126dee98792658e23b8acc682d5ab2e303b23a24544d188366c55aab65551c2ca73281b5b99c6586da8c0e332449e1ac8d81e7c576704548a4e50449ac504902840e7675394b9210cc14254922f660bdcb5992ccbe2a561403fe60c32eea08ac88c5934571e1c1d6cb5984b61c215425254b85111a816a0cabc1e52c424cbe98610b2118c0279bba9c05c9130d09189bcb59966cf960308353b0d6c1bec9349b76a856f38b644ab59d4c730968ba50cfba614320c04dd568b1cfd7404b4c5b6e73d91d00a582930dab71fb09d013c2edfe6959214f8dbbfa7baed20cf9e3b1981d674699519cd1200319e28a4673b30cab414fcf4cad94e906e2cc5589a16aca904e7607a9ee0ff5214ba503d51b34aa53a29dfd7dfde07fadb24be8afff3351750c39f83efa1c781600403a9d4e57979270e890cfb23855889627aad0f244155eb66cd1f244155e7ad09e30988e0e0cf6621b236011c5cab5360fd84d4d8551dad30b165d00718e9970420a2f5874c1838a50656281e1e8e0c04070c1d887fb4b11aaf4978c85a41cf4aca25851550607e3b802c995f61451008a0010eb38d08dbafa22f59da79b9a95787992404e7b02a00ba0ca05850a1481dbef0fe4a58b1980158d0c3690a11ca7d64fd3ac92a669c08a4a85628faca463e38632628f37379c919191f11286322c9d7177777777bf917177775789738696e529779feeb0276cab6b77b73be89f7b247577f7272d6bce38f40e2d82a6817177823f3ed89271a5c5019b336b85940003f6ac65a91d6f986412e8f633c928dc763185db5fc5daf5036190946ec17a0b5bc29cd8923559ef0f83e92881445d2c588551269987c074c418613d4a08b5fd6005d6569d2a6c8983e3b49d8c63b06cf1bc6e8f83dba58cdbcd3c75ba5a06153d955b1d0cc13a0706dbb5ee80c8963843f387dcae348bd0f33cdc75c755dccee2922a16a3eb2fae2aad3a5cdd7517dc0ed75d38e87b1bfe7564d91bf8b31d3fa474590f4de3ea7fefa37e8f6a0d61553b5d3e5bde9087437db0e5cda6cba395f336639f996536cd9b1391659fd9dc6aa16f0bcdcc93c87ae5bc95deec361312a77f50c62a5aa5dbf55fd5d4da75a434d49de1cf97c13ca87164592f2c97963fa73a28058d2123092494edeb349e2fe3a6c61a036b02dff9f5414a53425b7e59e0f63421049bc90e7897d2b099ecc0ede7960205607a5a669222619d0a1207a68323a6345d0ebb9182355db60052d812a6f337ce5464e73be5a7c4db814141d00ca589b0c4d6a062cb29a35ba88ee63c60b29fec057e397d6ff7c3808fa6c46cd2dc86bfed62cb7a3da8c2fad36c567a63266d06cd84269319735c126d220c92c2955f3f3b60604b7b43c9fa8f07beed52dad5cf15a2eb9f63a9fe7097bf0555d0619deb3cfc2c96b553a7873d283d80c2d8b2de58b2b687d20abc0bd223c9e9fafbe0425b491c35d9723bdb5113921318efa01d4e0a11d3b433812d2dd5c1965eabdfb666e22e6ff2af11f15395d99e35a5e0e5946c399bce665120dabea5d6dd92849092388717b6ff6736a5e043c7e40186b0650d81adf476f3a1a17ac552977d31e4b0c2a4d413470e1decaa04255be210594ce596acabb7c4c1b95aedff1059168bc562f27220c7c0482b46d71f47a76536986c596bad55b613594880b9fe353730d6af76f0400a5b8a462815b7d98ea21c4d4a6454bbcd8a445cd20f4790b00209a12f5daa14ed7a6c5101080fd67f86163b167801e6b2189759d0c5138eeb5c388743baae44a1b0623f6b035c29c6b10fbed8bf250e1a42b6c4413a09a3b1c4963898660cbce5e6a888ee0305224b9b581870ca2ac2ba5c7f1d1c34fd342ed7d103e6050e8e6857ddbaa143e4dc90e21146d7dfb218d74d69103073fbfbcb156e33d9255912747a6a6ed7ff491cfd7e6eeac115cbec6272b564739049a8238c905dff1b1c97d1cc9e2d285fb7fddc832ab5dad6edd984045a9196c04a594f697555b758940a400c5b526ac5962c76bd0e4eabbc216fb3171406d97ebe292bedfa73f7b36a3e8fbda2c23ef94efff7e44541d789dce55f8262ae0f7920644b17eaef5974e63ba5cf8476388724e60b82f20d5dff92e58971977b4f50d8d285e8ac63fdd199e7952e54f9c5fdee62bb1272fbab50a57d50424e400d8e9a228eaeffb76c3e0d148fbe96ecdfb2c646892d6b704e6e4ea0f43ddf78b447baaa591c9af9f5031fecdf92dad0604b0af31fa82042e7d1de270234e641c15dcd8fba7e7f7c031a2cce77927c87be93d5a1e03ba8237244145d7fdfe23bcde53afd5a2555a2382793dae97aad16a8e7b4d8d293a847a3c2c877ca8fca37f41119dd9ca21c51f0c379ccdfc3af69e4a42d0c5b5a9b2a6cf90d4d9ef902bbfc8fd468301abafed648c62f576a2959d9153fdcb7745382b4eb8d7d731bb81d6c794373b0d43679dc56fb8684837473b35d7f12d635264e3613f23be8967dbbe1f18c6ed7339a3c1f918b334a4fdb8ce23847bafe211125fcf29f91c296d446917ca704955cffb2a3dca31ba8a48fdad6362747d1c98ad4c1bc3912b55dcfc8e6197944cef3117d455e9167e445f18c3e22db513e22cfe823f2ef286dab799056890883a4d0f71d03d886ff5fb1b305c4ad99294870588f471d318498eb5f7333852d61ab29ec0266a4b025ebe61790a332ee27875d31d5d0417688a4ebbfaa9142bfc8c7eaf3cd2a04411004c16eeba45321b7e13f43881b25d6460acbba4962695e8441453e067e7dbe293f99cc6df883e314c0186bc3c59653e6dd3c1cb74ab753e681d185e07b385752f25cce75a5bddc2a9de996b63565166c7960a607c677caea3d55f1937925c899a0a8c8c7bca72fba0ddaa4a43b994c3643fd1c6435b76e2b366c095b8a4c583256029cb0fdf4f611564e08d9b4321bfe3c9698d892958015581a6cd932779712762c8890714e6666e66e9eef7d2bc8109b286cc960e67b3fed6257b923a2eb2fa4db1bc84aa583b6ca968d428604f1da4d55f421ec98bf0d14b65c5d7f5a1d713d882e4c3a2673b284182c930fd8a6f9cee842e54ac8e996f496934665eef21769257cc09693a6a23224963ac92e9b31842d67d00c92c962234dffd31dcd22178451ae0433f4f90686b3127338e936fc4908812debbd5f76eee2fbe5a9e79e00258aef84324e28da720214a319b6e846bec3ba9b5014df61dd10604e8062e43b34274031ba47a8daef79b5882762e4b044857af4045b18551004b5000388a22e4378069801064cb1daaadfa38eefc31e476f2c7f78ff337fbc81b0aa0c3421624350ef82131571129332512365950eb0c71276fb2b6a44b538d6237dd4ec910a59af05847567bd75aaa85026a1c917b9d81cc32fb1b04350620532c45c580d81e14f5c608416a373a4f131e7952342b8d81c6b8ec47ef28d4727ab9d20c110361c2462de0f4d34994590bc20d11e4a52454c8c8e3848c4424fc948099e88855f0f554c8985a09844d20bbcc4c22a4e11638c5858456fe42c4b618c60c88d15312fc529c6b244f4e9f426c02730e914609703f1ee0a6b8193c0961993219a934d9bde399de354d8927540dede240ebf603a3aa09a0b9a8a9e9e9e9e1e92fceffb3d5ff6943ddeadf23defbd8d68d7f5a546e2977f0e13966d7036acdd4028268b6404fb70bd6299b84e5ca7e9bf3e683a365b3e429a0e4522b1c68963cff833a2c6f175643b09a9c7f3afbb4110049b5f38b09e9e10041f172914e557aa45e96e97c3631eb7adeacccc2d80e779dfe739d77f3eb18feafa4f313c53895d41ce42b2474c9950a21f4ecea73fb698415b6db96d16e07ee3dc39b9b3a96251b7a4d5a68a9d4a619867ee80c13bde2cea9c69c38e67453ba52a2e960284a1e4c513fce53a0b7d9d693679a65151df98494633a35952d1349a497d633a758ebf6a3a81315fc0e40cc3aeb9eb1c3aa3317851ab628b3aa9e4d43798739cb83e73496cf1b495835ffe365576f305dc37bc601fef03321ac35398ebd46decf302fbc0d03b148926fde7ae745bce6d3b5a65e6a692931d2cb13f88e6ce4b729453c4facd26839dad929d56c84049c946e3a6b9adce59ebfce6fc1a0cbfbce89cf905bbfca90c19cc72eebad605bf7c7ab1a4775a4deed8e77bffd90565c960290cd7ab18d783db93e6fd6c1c5845bfaf9b49d6dccddd871322a429a52608e1a7180cb664dd20e100dcd33782748effec010aa2d33118221d60d2636057df10424372fd7d38d06dd4477db381cf62b1584f4252230829155ce31a77e47356661c6ea5c43edef56f2c3ce2d867bc3ed3729df6c4f50f8f6e3459faa8c1b7f1832d99e9e78aed315d3ba6cb6b4964e856a01f0837ddfa1e377d40b8a9070f279d8a45dd7275c7d8bf5676c0e1aa28b1c41549310820d144b6040c11d85025c62840c2822567e404172462ce421317f450450e4cbb2331ffee6e77c7e168ca36a7c85cf286d8393ea46128525425e6c2082db0028a18f8fc2cc6519f4b1b03cc6aac8e302363b53584bd40117361052606d60003639fd5f51781796cbdeecf5a74dc46cfeed9a2afd33740e09c1064ae7fdb60624b6badd7b23ee784e9e079b99ce7843c37457eb18f5f679fc9e35a3c27baf87d37d8398a2851f41cfb10e0fa77fd9d8bcfdae53eb4ebe7977f07385bfacc91b812dea98179dc68cefa86e384f059139f390bb809263d0acf7993107e85cd5530654a4b499e6464641401288c5ab500bf1ec42f47ba2df46d81261162629de63a5a6cc94939fe7dcee939cf79221839cf52f31a651fff4cf01b845f3d18043feab5e954c7c9967d236a011760ea974dc5457dd957dc3e9a424812d7b35c7fdad256fa4633e91c7fffee1bd24ef8658f61c24a6a46583a3314536218a68efa8623813d345b4847b5c9d3337d748e37ad285445f22457725cfdbce99ecbd01a4ea56a3d31a152049356d8e57dcbb994254ec02f6f22aa0ddd1ce7b59ae38066646464ac8c8c95f91f9f9191919119e264b7cc5d7d03039cd33f6381a1130468f4c1affe9ec983828fbec100cee977ea726fb7dcea0a2a25c8dcf9ce837aa15aefdda1075096998aed5bfee774fd6da858ef96ff7dc367d777406081264dc791e59c154e974d90b9b335845ffeb1236cdfda3302189673570cddf22f6371a47301183818e1c52e063479ea3bf8a8f7013e8ac90708b680a60b0134ac366a5a0fedee0f271d68ea6acc5398dc3517d80e1a328698169ac62f0f626fd74003e738110aaf2e6c0a40fd64cb9efe3ceff33ccffbbe172e04138e9973ceef9b35364ed8b29bfe70bd697d8347e778e770bbc96d27de7780772bf40d1e17d0809fc03c210478a76fa4bee45cd85a61a65a55856a31bfc2152ab8db81b5d6d8595333bfb16f60b20626bd09bbfc6949c5f1cb07508fa65197015f83296cad738439a9d3c3078d162ac9e261b8b2deca572bf671dacf0c82445aa493a8ab33862d7b56ae48cab3a35dfe4c4544edf29527da54b1e12d57b456cf6eb6642504f0cee700e6f911f4c5cebd95702361b26b609773ed8b2632f0cbdfbb935ae9fba16a953db305fe8fcfca9eaa35f5e3a8b16b7765958e3ae2f04ba78793fdb319aac32dba6fa02e0b6cd94aae3f8332380a1f842e47e1c3d1e5da7ad0c5b0b57b5876b6a618619094a69305eb19c3da2071e2d63ab012c662d514e14490cd0c1e84be5dad449205b6147bee6cd94ee5e804e6fb0de05f8a5b98744defdce5f44e979f75c3d366d369828b478213db039b5cd892c562cff3ee960ebda27f3451bbfe2ab093ad69006145a6eaa4d8b242db754ed4f3280f2a60b10249853fe79c73a27ece1a2a8e640c6cb9e2bb721e8ed1b0d972555f443ccd969f72ba04e7b43ce7fabda2245dc4a4422ecaf5efa01612e1892d5ba6238aa2ebb34b20e25d5567b2237c21525dc809b0fc7d998bebdf83634796ddf5e7b1e527b7684a48d127b664a5a9746bd5e18552517d7016a4eb4f45ca54757834c717d69ff2601d87ebf8624b9dabd3c359a0b2cc688da241832d6b703ee054cea580e8fac37a7074c4d8b8ee57aeff8b5bac5685c3af0f96d8bf3492c0e04a10362861854f89c3c5a4569b62542baa1545b1ed604b5a73da9091acc6eac1765399b85d7f71b5bac1d9d9b2be5260cbea3278384bb9eb6f3daf39b743bfdfbbacd2c18207ee1cc3fe2dc557175b8a305dcd2ed1c41259d5aeb6844152b806e4c73bf9e3c7e4f96ffaf1b3a2f956601f2e7b88572c56139025a2d89be7a60f3f8f497ed152b045f9e57580142d102bd6847af6b3a367fc334b410416078d7d689a03b407a594a61cd544771fa150a8b6cdd60a4e8209c0173b5ed487ed93c5aabee426d4875f521452b84098ebffa36ff4a8005b8077c007827958ecd34454c1328e6d2bb909845bb68d9b44c0a918e0b1d6f9f2a9a09a5d86e0208a6097b74dc94a09f8e5ce0484820fdb0f15b80bea3bd59d721c7ec19cd4e9e103c8665389a9b6825fadd5a6892060828021d2eeaed3c3472a88940cdb4290eab5eb370a854ab5207383d43b9fcad83103f57e44689014bde15bb186e2f3c8c2903be79d330ce78b791adf31fb33bec4b16356a631ce18658c76c4e13b2ad4bfcf317cd56c957ec39ff9d438c7b2a6de8eec2eb1c53335aa7e666421f5576664a16f8a85899aad9a1385528df4863c6d28a65262984a85a9948e93389cfc51dab19371918b5c161b335b92e5ea7e5e12fbcc3f9a45312af25a931b70681bae13895e920ec60b30d04549ba972cf334780b01725cfd3332ec8c4fc2c19348c71ce220a288aa334c8932aa193b4383296c49b2d32071f805d3f10114845fa9718893dd445d731229c949252749325cf27d73ce23d7b1cb9fa66b1a8e55e079df47713825f659f29d0602c6a7934f31e09734a8a44277cea47efa31e671544b84db20b874ad6bddc8fd7ffd5570e738714ab810105d370192ebb4c9e4a87340b8a5ebdcdd754f382b3824a66e098afa71e2f805b6280dfcf2076f4847b8fae53cc2512a0508ca606bab6427efdb3c3a9a493069652ec1ae89eb1cdd952690983b2e4cfda5eb8e6ed304ad1cfcd2e9743adde4e9db4d77d3dd743da7e7797336f94ca2f3ca84e2865362025705896905aeca6c9a504c152881c3dd7044dcb460a9327113f7e136086de114db510dfbb8db6c6159f37d5f8f6aa5517c46f8e55f8293f5e7eb5a5cce55d1e5f6676484e63be557632afa6642fecdaecf39e767847d6a7463084a96733927abaddad88784eb5f6f7dc35f40ba4cd79be644d5dcf5236cdde23bb694ebb85cff6c1536d65bad36273d070f76b01ddc3e9baeda98c2565b0d0098e7fb6abecf16859d51d67c40b07fb57d36cb2f7f0f86b2f0cbebfbe781338acd568faa6ddaa69193b535eb510d818a2d6b5a0fc0f95725ff6aab375837ac610dfb2a08d63ac10ada6ca14d0618435e6e33639a5f385eecf23941c06259091288b93d7c8795200198ebef03c81f0506a0beb6686acc7ef0458945b5641bdc62ed6348c825561ff585294745d2f5eff14577fd7d84b5f5d3f55ab2bf802c745354316242c5099122c6b8a1c6c410495409fa649ce0039314268f064ae0031044b5274f8a883916b6a1dd1429a8886124e65d68010222c434b9c1c82e96e3486e4a0d065eb0d022e6efdfa7fafefbbeefc3c9f590a1a6d81910cc518175be2a1dde7f4f2ba51504ebfca2e6e4887dfa75c8344f09edf29f31431445715a61bffb7ddfc4b125094885fa0840311f2ca1bf8223cd1014c216500a1f7c615bd612e2640837cba9d4a73ed52a1d552b0a552b8af9d538309d2a3b2e06f0acc9c33a7394b9acc963835dfeaccb1a21c94ba574747faa1b4b567cd54b6900c764be647db4a2522954e8a93a950a3f35fa0d53ad5f6203a0e36f28b1256c6471f0b38347dda5bc1251a7e7d5f8e86cc939ef6130ef6bd8c72b0a045120bfba67f70461ccf48da1b2390688b68e79fa0594e7d54a856caad82973bd67ec336ff7b4cbbf27ca0ab222b6641daba70315d81ee22bf84eb7c06f484bcc10316d843b06242c1bea1aae3f0cddb60e226405272bcb531fa250616a4e146aaa50287ec19cd4e9e1a3652d93a55a8585d9576ca74f0a6cc94b3cd8a76f4c1fe6192124278f104b6660425f14087e737e41bc87023ac75fc8e4610067c14f4f24805fa10212c03e2067c153f8f3d8c00b611f9086232f74f7d7fd753fe9246c89474a2686898989f2649a3c9569c8d26ba38aed2fbfc6c929fac6d4a1735a0af6e9666aa6198259348d745260cb9adaf5afd1600a5b36d3656a26cb62391393c7e439a9b5d65a6badd55a16eb3f05995ad68bab2d5ccd0bfb849747480f8dd76bec3372bb5855d827b4381036b4b023cd0c4e631faff1cbd927047cc3a5700e0dcce33bb0cbbf563acdf33c06e70453f8c49fc9c3b15699306fb73c0a3f85cf596ecd8d540cf058d8f2da74fda073c5963dd44dd8493f619e765ae7f895b6e1fa075a0f4179c2a4ffc02ef75a5ff1201ae73cd09ab8d1fa4613f2f44429add5bc9aed82a6e448c806073b8a9eb7c3c454c8eaa53bfc27c03eeda5c05cd9f29c2038271555dd6037485515c4817509998a50480cc31aa46f1d2b503f254e3b45c806b09cc362e87a14552b8afe2c612cc792880c20acbb650564befe8cf167cc61471e33ad12083f9569b193f35344ee1457b81d44b4c159f096e29d0fbeaa15c4af47d33ffae8568f540b68094bb6dec910bc582a53bf4754aba4b7fd4e50b4c1592f04206cf9d79decf977199dd212f24d69c32327d9794e9ed3a5d4a065cc85023eab24d0924999ef424c4a7f534a1323c2ceefa7f99ec86d0ee2dd6902a594524a6b05c21b53038c2da70c8c2b631f769a4dbce34d4ef677b9cd85cb962d772edd7e4f621e4ff21af3788d5dfd464636dbec59f65366eae44ef60a2954b660c2d2440e3127a2e40343e0866c08423725e63361106d6185115898004aec031dc27082a8698b179088f9bb0656d8724e1cd994c964b2cf889c97b9a18b93797273c02effb13aab85cf6f88024154d5512beb4bcd894e07043479a86ece49a90845942c1a1baec12c26c016568f8f1ea0a0eda8848d77453d0ad1cc080020001315000018100a854342b1704c2047a21c7b14800c6c8e407c623a1889a21c476218830c31c62003800100000098a121220200d063c33b5657c0109904cbd1fefa98995985ff6fc0dcb08ff3586555df3c9ecac65fb0b23a9c33e89fa41203239c03640f431f0acb28b65d986cfe8a03c198226b8d0760258d75f44517ac4907f8d34ee8838cd9039a5f242a464fdbe1ded61e1860f1a3908cc4e7a4f7701606792b47652ad504b10dd86f1204e2a8d9bd04332ae25f3f8d24953ca71f35801fd8253e50211a5e9a520064707e359a5da7039510b0f2f45c8683c01b867821011373ad63cd0a97329e5652634e0104813a5ab0a4fa3f3ec454e65067b001d192fac460c18b0a1c07296c0be56e49bc664d7aa04b80a714d6a3b6ba9d420bf145b9036f4579b5872f0b70a1a35d6352e8a8a7f8c047199157ff5b7631f0f984e8a10c14467f0987a5174bab838df81d5d7311375d2bc18aec14079e5c52215bae9dfa97c8f537da0548b34e53f05796a33b6d4b97487fac776afa635d967540471309dfa13025c47434b650e917563c50b9c9e8d4b4c474ebd93a1c76db5f8c7f55a574fcc73d3a2ff5522d24c8ca8cf702bee5e7ff25aaeacef9a35141df12df63bacfcbdb7531d75dee9ef96f51e79f694685f081462d6913c25dfe5c75dae22b2b576e09cbb9eba82329db080e5cbe55a4563305c6100acbab8ae08184951ec23aa8c9cc01b4cd0544569c5597985c0410d58a628d2852d285094a1e3ca24b42dae1ff5cba0b62bf0d3d1e5fa14bf161c3697410155ad2897255de4902eec53964037a90f852eee36e1c44d419720bffc0e03fad1ba907d65bd00b90d404124890e04e538f2fe61f63c911b2730816058422dc0c8f76eaf4f581927d49b02b058157611f2acc782ac69ba81f298e656d03799012bb48c0aa81353c887338c2fdaa2b6f5a8691a73cec0186b31e971720c2df6de9a1c0f1daffd6a91711267dd86867441ca813d145d9719bf21b784fdb580ea5d89aee36672d5ca68ef2394acbdd2e69b2a308b2cce8fa8a47990afb73e053c34b2e9c3964c652d1885ea0072aa0aa509a47096646c746673564bbbc9b5e74aab2c8b5172cc5afbfb472bf25c3788a06080d3860251058a4b8f2bd84f6eeadf751dedaa67fcfa65c686db795341656b95f2d2d47e217d73c3b3a0a8f9850f2089ddbbb63e6a06a37ee5da047d85a4ef0faa6f5a53a3d2a0184dac31f0c6efdd22668324735e52c2ed3dba78444a0265d9111e6a34b2bec7ca542bc2e847ab09f137da025c9b3e27807ae0a6230b6602453e6e08c6ca1f7f449fc6f1badd522f5f7cd094b7172f4dbb9eb4a61fa30fa6d0e05f4c77b0dcffafe1ef544d2a7f7a1a0e247e72d1c928253b77e74021a466316db37aeed966a35cc0f7db2fb229de6f712acfeb5d219a856b5f9d954793548d81257862c4a54f6b3dcb96356cbe19ed09c206ddc2601f85f0856a409d3b5d9cb816d663186a2a43ba5c1c3fd4079b811c285a072c2496623a04d3613156611b0541f2299c90eff099c261a46a67518fc809175e063ad7222fffc00910f0518c91c25964d4a250d8b30ecd299ca5cad7737c61700c76b8c00483bddbff45d1c771ad1a16d7b026ae4feb38f0e7921e3d0cfe0a042fd337cd702cc0bb241381c1bb00440cd421015b2986d48f94d4d19cc374e06e67294c896c4e419c0def9e42398029ee85a6b27254223b4f0b7cfedc9c0a0a00e9ebf19660f5ab7d51e527f2c6f9ebf19da8a25fa10e4233ab899c696f24513709b525e68e6a97f0ee9d839ae158316accf7c2617f91bacaedc5fc9caedf6064a1e74c1d6d89922ee17b4f7216e513637442be531f1c4047203cebffa566c076727d28c5781b319368a82206022dd124a9a744594a4f7d3629983449f5b310524159107b906971d997a8e58901445159bfc2a02fa522b869b2bc4cd5f61adb96796846ee18427462c61e6ce14ce9363192d45ae6fbd8ab006307f12c61371db905531a0401de3591f4b8c2c9add739423675c650cf1560ff414c60a4ae2cea1cf1ca317cbc4b13db3ec489721b4d8cc371484871361d4e6547f8cce31913e85897cc3ff649fc71b013c978dad3a8617379a4d613c3f8031b7865c6448f26f6a5cc60bb68f5b7f154319ef7a8b08a8f505566493f112f88d6b50db51a27314a8dace420e09974d85b3b92606d935940adca360730bb797cd703cf413f81db59797e138c1daf98976d7b1b460ab28d2e92861fa42be37e5a0970ae1ba9cfefc6ea1167b136c6ac006947121b6f8c62ee07bde5f63d73d7fda4593e4226df32d46d3e333b212aa28ed017afc733bf795a1d63952bb48124954df3fb9d0d6317e5fb413fec001d52adaa9f16a4149234104f62dd013eb7e98367d0e4f59ed9c1c9e80d38d1f607e762211ef5df0deab9e011cfad0597d72e95d2d9c8c8ff68d823f3c721a9c929699a025a59f427138a098744f7fb62bb3703261b4cda21002d4e8cf5cc9c43343676edde9b1e340e6e1f192cbfeabf9a9f4c58aaddc045ea60e40109cbf2ad1db560d06712806ba9edcbd35eef7b4063035674f6df0fb2440c844dc8494c03add5fca1bb502288c36892833f281a4266aa38990e4de57ff6f493ca799f3f039ddedfc4d2515957f69a5cd7ff4ea46727e4c20a3d334c5372f211a1c55c0297bd16160bc1d049f35c58be82829b8ba4a5bb3beeb60a37f88fc5fa3e092bf56b6cbdb6fd953ecf9d5629503d4d3887daf330c950784e3634b31bde2d69c056ae37a90a5b0245adee36d866a4e1fd7528138d950f078bf2739d35bd3527a7a7ed9d85791180488541c579719d6a8ebf77614169b19b12526bdb07a0ff9ac78db46ba8b823b9aedd7b86d8b256cc18ee1193a3e5b3c77ed59715f65886c07702b5e7c941c1b173c9d0edc1dd98d7aa279afb64c9730ca7fc52a9f8f9613699febabd82127cbd36067efa4f373fa46306ca82ce6809435947aa584718dcc82143132729ae05a005f9e92768529503261fe66255466257c347170691ee9518c822231124394b7ada35b54d78ce452b18f42cfc3630df2bf64154374f2b7bd1f0f46314993593f18a8c4963dd3815d2633e6b0f2809790d0390b1e20718450e8616ed6de1a21a04bd5849cb11d47919e0bca7dfd2c3d88f96d5301fc1928e18ebfc5430632a8b1e8abe42fb465f4f4292a1585511b2db262b3169e23f656a7e761a91ddae77b058f6bab6e3d55562f76a34545f60c0a03b01c759b0cb9ab7ff5cd6e0d5b1cee8afc294f491da43e00f8752a1b566358f05bfd5bc455b78f988f11d71ca1cfa648b0f0a921d05b76dfb65cc45fd94e2fceddf25ef625778f77e09588284e308de0928aae5e88a8bdb5fd08aeed1d3bb6c0ca4bf43e530dcb81e53c03575684f1360043ee869cb236d29c7582be9417523c744a977bf2163ee54b6032af876e9079d37fa7e6b819d16f4e6ea8c7dc11f85d8f35aa6e45e8efa436ee1dca15bad11a33ebf31baaf48986098ffb49412b15c8e0577fdc66d6a4cb1708b05d78e15033dd8e36ad15838cdb2a30b6d42ba45a48b76ad6017a2f315b8a8160bd36bf11b2f6913d36243315dd4efc31b141621c363c3508d5fa05a604358826c9187d8b53b2cbe7c22027234aad2de107194f8f19efccbfed8cc594424c0ccb5e8e753d5221ca834c80c63a93061a08673c691be365d98f438cd071263f0767c5e475f6a55461ba8fbce642b3cedf2c0209c0db400f64a356e6674d9d0ae2822015b146158be73dc86491c6944d1b473c78c46e99f309c5df35a7508dd17495de790b6c7205382604f559a76c6011129deec8997daeb56c7aa9e906455390c599f4aa3d8b2f7f59175aafa2aab23b101817628069c467bf755fe4b85371f080c3a79ac54f33a8f1771c0b5d8eb75b849093918fc3dc9ced91d6689819e1a019ebd790639f9fbe2a27ec480ba5f878e97b76a0609ab868c6e3b0bed96dcdc01fa3fbc8c038bb24de32fadff1810ead09303ee71cdc53b48f7011005cf0fa4e2efc1c668aff82f453633ffefc6c61e2fcffad9b3d3464eb4c7b400ec379394cbf19475810d628625aba1d94df9a5bc2a2c9dfe50ee0433577fad5312e4682368e8df20d78e533cd0c2b5e35ca4dccc1de275b511e71000b2a37a6d27c08df4435d810afb6e0c26700e77e1653c30e326224c6dbbc5089a8f2492a196479e486a94b7669c019e444f6f3b147297bcd7e53c4aba83d95a7cc3046443ef02b067b4e345fc4d8e4097b0f2fba9c620eb8d601c4a97fee7f3adba4438911b1ada331614c12a2389562f9b39d6169418d9e1c0120b9b4e468b110c5a43d1063a9010dcbaed78e9b24f192e761e86f00fa1fa6cc9dc3b9882ca96e888a67395604e9ce0b396ad1c987a4dbd86217c653b8cc76ead3b3537040b4d3768f690700653b03411c49c482ba3f22b50a2a1b942a04ae6e02158187291457f87a7a760c7c6d4a90a2b5970dcb10ca30a2ccdcab8ad13dda8a0be93610d099838fb1aed8709b9abae2b0e730ef4d87decf911e540c386a42c38d25516f94709db399a3b5c5117fd24607da9cc3ab513a7825eeb694981bce9ca05ebdb74ce1521773c41fb84f52aed926dab3df6908c9037a0c261bd82a1dd685a680db12c02cec10f94f34e5503c5d920d5b454943bc171d85a46e5070aa07cd707efb9c5ce2f1c66f2279399c71b7d20c53921935fd857ed95c832ad56f9880ca1af67f73c30623c215a36ce242cfab0b1ea7e0be3d9e4575d74cb9dfbaeeb34459cef63c21e5f638fa42109b0c91e01f7cf785ec4104dca4a544bb1fe87c50e998a8c8c6f0b71148e60311e47daf7b4d18235acbaafb9c7b816865293202713cada7946a780c9766833660b2440c6469ecdef3b364d5c95719f7097500e5adc9a6fbcaa74c5df0db802555f0046e1f56137a905077243472094c4e80358a470d5109ec25084de39fb64100de4a345e81efe7e0085792289c4943d6d5f8e5127c0ebf171c2a7c8d926ba48e942037562c226c8db32bcd772a4b234dec147d01de59807e2c6b7bfc06db009ed84be82a1561686448fccf144d4e0d6fdf51624f514687e25690cf5586b2e8650d5f15fa19a1be8d25dbdc59750197a51a937c5b1bcd8f0e42839ab9f1828ab47ea4ee98eca126c0b60ad40136004b12074d247d90f2aff60593ab91863e90f25cb0285087b06233bfc3e7b473d740eaaa5bbd42c3d18251292b4baa9827b26d21bc554a460ecb7b77deabf05e6277d2d19056aacfff851142ef2aa9f1359f584e6f63701692f04ed1bcb250656c88be071dfad50a1f013ea9ad187c3b6d917c99e20aab4cafa583d2ec2dfac1a5488efc925c351eb03c32d0050fa779f4e71b9db9e037d0eeeef2c594bfd063f993aeb4342d96798735fa85406d5ee21b76ec724f4f33a95d71c22497342d7c70f96d25456275c7af2fc103d42b5dcd61ee8acd76055ba789c52888d342f437646bc584930f31062e788824b2b5a9365d028ff67dd1a3bdc5ecbd585eb4238f18059025b74f0c9371cfb753a5be9b6eb2b2b405dc31c405fe54e68f64f491c4decba5fbc442eecd31abea991151a36528497ee26fc10ce51bdb2100d51a844567445b5c8beae26b8c98264b09b4b7002597115ad1173d1de877336f63175da694c4c67db29f89aeea60062b829f97139195587c99955344b9d4b63206c44adb1f0206303a4c9fdd99d66c0971d48846012defe672bf47fb747cd3abbdbcbd7ac58444210de8d9e559a0fd9bd12a7bb3146de4a8e633f39bd37adaa8191c4d57502a70d850808802ba10140388ab336034ef112e0bec8f5afc1cc5e4b325a6222426074f6442e3b0c44a970e39a10f0916db230cd6c58e5e5995f42c09721d908bf208c6535636d30606d2ab83a1c00f5cd0c72100de32ac4e3e8bf4d2eb95365ee0a0ca8da6bcad5d2568bc2db593f1a17851ed8e5d0d0c1b490641dde3f885a9de65b4c6801a673a34003d1cfcd6ddf180889f2c59982c68efab2fefaec723429a5cc3c14cef8488c45a098628df95f4467d3244bb0c8451e94b4db1a76db990f9ec85668a9215cf2c0d2969270c636e3bded480239934033d543b0fdb3fb78bd9d08aadab07a85c61392b590beeaeb3708bb0704920b4b7ba65373e47661c9d3d13cb9749dadd3ee27208ba8a2dbbd9807efdd59b73c6133700eb30b3b6a042b1e35b55c30a590385eebffa9aa4b65773ecc5b87a02ef561503b4a29ea354c603193907f651a699faa31131c65340e36b5e232dcd75cbc93dafe365af7f3bbfe052b83ac9434498566b94c07c65b58fa5bea4dde3b302654f47c62ef73c8e5e73ace6b37ea464fd6703105d89f4062ee8b0cf98c1498eba44c1f0fe3ff07d501ad1f4edd6be1e974af8acb6b5adf21017299688b0bcf9f19013f8b3884b8a749a5522c6f2725c194030b612d93628e15e3ad5e9a97df0d40d1480238760f0c406dab4cbda68a4ff2c70858d8ff6ec09f5b87c8a707997b2badbc9e967a5b04608ede3dda450c220dda05517eef0a256c871d2096d39e5abfe6eda2e1189fc58eb8fcee99ae4c2638bf0234a8c92b0a4ed65c230c52ed379b2a40bc2b8897c43d8ca55ea9afd62df9cd601d256d407a6a664308ca8466085d966607ce492468cf094496b9cdc2e03a214304e75f96c976b7699098e4ddacda6f181ae880a38c6f2be7eafc4a2629d13012efcfa7efd5eb3ed99f9325a3c527ace28eea2690fdfe5c6ed5bfabc3fc265ea97b6205caae34345b24c35d45ccf1b11943cfe41b9c5962956a1e860a4fb0ef205b25a2edff1ecd8f50da55bf5cc851a54147d486a465016d9278330094a4a2cecea303e7cc75a308b164fc177767ade23f2caf003aa63868eadb0a58ee3b521ab0a848f38edd2a45326ac9a58fda461904e489646b89dc64112bab0da841bbe1945d8107587746edcab56b8b5d570c142d285275ef7066d5990996a6cf46160ad192369085c756ef4ea4ed3f0ec500c9a9a433ee90cee56399ee13b05f3513abef8c831e33d009f4b7fe7a78f31ee014e9aefc51b52e69db66a5257e8ea5cd48849c168649c0c0dc01dfddef50c56f23e56e10b1262c669eb4d59ca0b85086523cdd22c123c71ab0b9f7d5a0527fa05058b480d4be26407f948c2beecabcebe074ea598047d4b57194b812105a7ebe327fdaa81a5d7ab50a01663fe1155018d2a1884dba5f96eaedfa8e756113284d7041c7bc009eee8bdc09b84ff28451ebd2262f4c38d1e2085305de0b11aedc487d94c5b98768bff2df96c1104c80e1170581c8ce120bb2dc20c1b2e627f470407a77943bef1fdf9039dc51eb302d95c0689a6d1f085213a02c046b00f1ba549f8505113dbff90a4ee1d58b45c8b14bc3ae0d65bf787434291693e8608510dd11a5a08c833589541ec61f61d66e0b6995799ba7e8c5664dd522b51d0fc91032b4be9998a5a630024d42b6ab0950be23c65bfc03f535d80f00c11cedbeca7e796fdc6b18ca30374333f25724c86abc40bc0905aaf401cd0b0c7ec35968b4ca6428c7503ed59654feaefb4e9cc19762dffe6512db0148008e16bcd695aabd222383c7268484e3cba4ed2f211dac5dcd30f7995026badb908260b4a552a6b8678d663c592924f8d0c6a74e600827dd85834d35a3ca35a9049306399be9b46d07d8ba2ce8892b0daca679c870d71bd451cd940b3acc66faaf56297065c704af070fa6f28b3ab13bc563c820b5737a18fc45e06b18c77b0eeea688f47258018557c9ef1723dc2e047746af47ec7c171ad8c585fc7789b99cef21714199e3156d9e139a367532c192bdb42cd44764a69b32c1ece2b452c5b736d3236ed2f60c35da207314a7b4afedf289140f99d25973793874d5d109874f6f4942ef7d372928c6709368d61b46d48d2255e3925e20c066c97bcc1da72ce2f6c1e84a8cf6e9d6be3e2c70e1dd9c397ef14806124414591abe596d46d4efeb9c447a8898927b27e59132bac9295b57111d04c81d235ee4471dbc1225bac788a1c35ac1d73810f13747a45c8216f50c848e8887fe4702c33a722a3b7cbbd706f06d6a555df49538869b0023468cbe381477b9c89a626788437f0b6575f254056592b8751ec0b91ad204a7676878408b764866511fbbbf84a503e173af1522041ee03d6faf7275caaf5756c45db71b6b70a15270f7dd0042cd25df773582eb6fc5ce3dc652f4518be00018126521b8a64017892d6a00b6075e10db988a932512565104d6c136a052c64d97bddd68659c822a10a2a22bf2caa8541506aa060912be891e94b70ed147ab0dd0016060a474ecf76cb1446d42df716aa8732530f55aa8d9c1e8b5e5b1a213283c231d3d800e96c03fdae060a82953f46069ba9ffe4226a55842a35ce9efcceb1e5f4dc437c2a9e8082719c04d412f21073dd4a4ea04d6391b51aa4670750e55827d725dd328fd7e884afc173c76280fc3679e1b8fe88c314309a009083be26ecb14c0e54d4487a9b7a96ef22da0778aab0120496d361eb64fa48a97d551aa12054f23df293463ccf4c1bd3efa82e536ed92ff8b30a3da4b1707fcad78eb857b785a956fda678bb50ca803ee726b0aa97564ac9bdf066b6413bbc4cc127ba3bd1b7425db7c985937e91f9d210f87c8c8b647f051db608f1ea470560f5261b0f84f1de929cdf8381e59fa826d05a2d156df549b100c4872f817df7b608b5b343497b7a68d820ca11009a2929c2b70eeb2c4f9890d39c873b68fd13a6796cd2cca1f0c6874b8079d18871b9963074646b4d76a2fe9848d3f3e7e7668dd2b5395b7faae279959fb4adf477526bfa56034566f2f510741509e415349b41bd070e4770e679fac85a29b2c787e06b7e45f7f6174bed80f07ae8fe41257c6230fa495b90901c4031b0d989c07c322eef8d43a771b1846d75cd573788be4b4d491794bfa7262a5b4a8cedd5499aa65868bdcfba7ea2f4c6b34d2e77481637f0baafe44efc5d31a272d29cf90efff6eec23cc7d189afe45026f7a0fe047bafd8622bb557c590ac76c0e8aa4bd863da00ba42005a74cfe754d8543c44ae46277b51baafa29100c483cd44c594a7f00bef94398e67aa65dbdd5520fc0eb83815586b5dbff5230c9dfe35ffca109bb8f335867f2d9f9d491853467adc153d811a5f431dca841160c76e17ca2c88ad8f9ca9f02a06acd6c88e9a5fb40b2d8e33a7529507fe2dd0e8c30d909b6d1a2b22aa82d0a323a168198d545dc6c422c82b7276f3c2521ea281469840db1ee3a1334f33a982f0473ecb0018c870fa01a28fb76b8b4f38dd6eb9e9213418b7720d605e3649281701cfcbb646a4ceff6b277b78c23b20e7d7553eb488a37aaee0526c3d0380e61db5619cfd8d615ae2517af06a2796c1debf090b2a593e59f5d18fa398d5181f8005d8b822bb8ea2df28132c36adf85923cfe207b47c7b63f069854472026f31c6aa1e0de64c35530de4f331287fe5760ea5942e235029f7f57b77c1383cdce85e8dbeb63cbc4a394b3370c37bcd2d4c4e9d64c3b4598615a0d32370ab3932d2b7dea2c5c6bb88a82479c6b4432cb0eb18a63f53fae6fbe817a37c2c103aee76d5d72f253db7352f8e3a50d6b94113b85835549a09b565e4e14172bf2abdd5c0eed0d2a1f75313deecf75c9d0668aab92a97cd31b9791612eaf0b5b3e52488ba9c1ed70fa42cb597a531380d9aa1a62673fabce1743f264f00e8fbcbf8cb41536d35b6ecbee2591f42602db46dc87afff6096bff6ad0448ac4141bb73621b186cf9f61ab9d31642965c4abfa0b24ac1d74c3e71b6a75bc6747da6a8e36d574a261560b71dec7f151a868af41a9eb6b13fd0909f90a57c3d7999b1bf288a1e400fc28208ac7ae9b06c779b2e367a54665ea9594a79bcae83858b46da1584629a67e19f582a0749ad652fbe3212e400003c09416120223519c6d7f133acb59c2d0082fae284e65a26a0e213606e2c8bf700a49f5257fa12f51f82a907111869958b3aa4b294c759ddc24c8cf8d2b4aa8feeb3f548350a1a6ede0857842fc8b153f3cbafb2bc12f2e3c7492353ae34595b6edc240f184008eef341dcf409586a6ab7b03232c5360108e5ce295f54c3a2e29dcec1d4a7012b6dce13792f2d4f4ee76fca4ccfe245a4f30d1d44b97a4a02f4d8c0a95eb1293d6ca26f62af71098c67cc5bf5f2da6169d469746620f23184f80490e06f73428cbd2a34c186b002b49689ce4712210d7e7b2f1c74124c3f06fda20194bdaa7fc91a51b297e3431d847240e7d505b5775af863450c0f4d8a299b9c642262ae1311aba69aec25c0f7e26bcdac67a93ff35d96a823be10a6e4c5bd12d12073610afef0da2fc1b1e2bc92088a7d8c002b46ebcca27b914d078b7c362088f431e22445b1457a32968ba98e7d21ecfbf444645d937ad35d1cc4c21abcc9f769ab66b90d9e6182d023b9ed4fc8676a292c719429d39d5718395a89f8ee2d5f04bfe66d23d2c7d1638e3d577cb61dbd0188dc35ff00c2926e14a5af48509c3b91006bcbcae41755094b0775f92920de94b6576e0e7e1641cdb5e6a03002f2ab3164826a2efc0c1e5d4a436595ca1cea84a0b6150c4889cc52401e818b282c7885accb3a17dab324a851bd5720dc7a380fb20e4759d3ead6144026ac7493b3b6335f91af86bd4d7d6a7b8bd6a5c7bd92308a5f4316c8fbb8a8eecc1f0701126a5a789f5a8b33f912c659e006120be70e7408262331d9d4e2203ba64d5e29e7021778c2f56723a17f648f0bd28067b79c17c7f85806a8f165b4fc738f80d6f8127aa9bc77062451df6b1c2268c5788a908e6029b211d2c92d185812a5eb7bda7f8dda7c33ac905ae0d752fb0e7b86aef886c10bb87cb14fdfbe72863bb1e13aadd3af191469dde7a4bf98eafb6c0779b5eeafb07ae9bacd03f7765c4e114cf97216245db9c62bfaf176d2811cc55f967a16406f9b78e5fc849b79f454001dfc7a44da93b6585d2af2ddcd2660a71e8bc5cdefecc9217fe330dca2ae0765f33e57942611aafd0cd8b4b11f554a1523ab30e9bbccb17a8a7247324fe9972e0e729dc441167a041598f89ac1824079116c13d01cbcb0f0a9fc5e7b3c73fd04d4eba345f7d04ac34af9829ea97c9e2b06afc8ccf5378d8c2a41a67a6725708b74509f381af0c7ba709b1b42ef044c1831bee35c18166b5c87136bbae04c80fa822a364dd4ebfa5663623d511805a71382cd9788385073d660e0a6e4a44b97df1c584c8ec990e57120e9764562f68e22b86cc9f1c4d0e4b364ef6ad0263403e526cbc9e1fcd74e0958cf2a4c81c4ad40aaea4dbb0c31920f130e4a38b30b7e8c0b6dc5602089dfc701257ab3340d776a879f25e25220e4c9270ed0787c51ab25ed747e064d3e79f6d6a03cf3f4b22cc93da3371488b9ae0928c7d21a9acab2a807c8562f65b60dacc40b127bd7ce1812638a112a0369f6c40ae318d07fe1cb56e13a30337df238815e6917bae0b5faeb0e9824855e52100c7cc6fbe4736e9e4ee63877433a2980b5c3416bca3479aa1ad9fa174b950ba5edc747e46d5cd12019c31e44d3e79f40d6d223fb79d62c3d85036d0d79bda7225adb2d0b87a725c9bca078521f212563cbb80b11442a7736445275e6e19e11bf13d0cca3bd4fe3d42b95e26d85fdcda0a6dd0361332401a18bd40fbf7470e29ce13506aa7bd468228d283ea580014a21332573575b27004ce8f23543f871bd076d7128a57414712c233f195a0d3e52d7f8d06b272fa9280c3a82d7b2acb5a019efc8215a47bcfb3acb687fd551b38eed9383a4204dc65459f5c18692abd9a37e4104ba1ad7aa7fff4a3ae1faca4f5257e071d80628955cc3184552ce5520fea8f7ab807ece5837a0024d0979b4e4c89c2e326bd0ae8de01074a7f2f6ed6e8df8623a5a317842f7dc6423bb7bc93f522709d13a9ae6614a6f903672219c79cad0ee9a28f3ebe925fd62021d01cd4590fb148e102588acf2dc74e7043a237802e24f9620250cb63ea3f236d3698287058ac8873309e794f6ef9e2c3cd5bcc0faadafafdbb61469fbf6c7ca15e7d0beb252c5b6f4be7c4356aee17c7acad4652eea248bb0d32462aa38c0a416ddd66de6547148ebeff587c0f32ad0d9acfca26a753ed65620c19fb88a45c3748b87218250f6ac69119128ce1f7868ab2b2bc7a520f64625324e7773675c75c5f580944599688fc67a7113c13b19fd3036dfe243934b5648d6533e9ac9d581f0c73a178d04408c4e66aacbbcaa5acb198dddf98af04294959db1c425d0044a0090eae0aabe03c24a229260bb9b69493e014f6eb87b2e29b6b67b98ae26e741efa31d5d69160446abfd04233b3efffe065f81b9a5a6e6690564a16f1054d068deca781013b9bc5d0ebd92366ac28d941ddc596933023c29fd07cb7dcd18c78d502b3d2886fd20a5273c58d847a5c40fe0c3cc8e180e14019207a65d23fc9b15d0ebb13b84bcad24f8dc6af3a71983ff8817a670dfed10ea0b806d1e57312720826057652bf1bf607c4caab9e6fbef81a57a06301edd40f8eb40d73147725b369c476c52baec0cb14897122168bfdf23decd2550814377510aa5028b53ebc2fa6c9fff44f27ba15e39698f2da024d8a2bbfb39a497445c5aad6f1dafec0135f0171c324da65d98ac73ce298acd14ad7071cd0b64809128f818b0a735b2df3655c98d3991bda53a5b1cf285713a4040fee44fe9b2ccf38afbb84ec06807099b71429e45bd3b690d0bbbb50d2deceff2568e91b7c17a05ed96f19150544faf8dc8e1e6d9ce223fea94bcad43d59111732f97c2701308c53a7f744b5d03906b06cf99d652727c69dc68ee870fb9ff3b9fb9773922d7484ec1e972a17458c7e5a15eb78ec31ab0be5d8571c886d2fd21f6508706084b864a478ba10f351c44143bd8eeee4bcb3ebd2fd963868e8e194120b06aa01e1b7a0b98585c0226851089ffb671eeef4ad983cdb5adcf4b7bdd0e5b734e725f0344cc832a42e98a3f83ba972845c33a6a328631e366c27cb890200de2d3234c99b33bbdfd172a4cf84fd2f4346e33c912d74b5884e6255cc7edebfcb46d72d0342e605ee99e8341c0a73273886621da08202a8814cae265eb6a05a80a95360595029843a33e6555620e9482d3fcd33d54963264bc77f94cac9ed1acb63e3820d0e60711cfba9b42181b6165f429faed689e4b6e761efcbf6e0706f9ce3dfab3e31c258eb8cfc5c833794abb3409217f049a76a2cb787b32e36e0a309acd47481909ca5dd04ee1021d7353191505831943b91f35744246414fae974917640bfc6ae4d27db7133efaa3b702266a8205b167308c3c8e8c918d7df6333e157c0abaf41a97e22797dc35efd2344ccdfadc9fca3a1f1256ebd62cc634fcc174656de613264f2e17f14a3bffbac9f2827f242320d30ca4640f34ccc5d63034a1f0694706da791aac2b48ef35b5ed70420a3d99b0bc042d0f837bcbf223efada1492a18901ff957e2bb2f7698a0a6fdda2298ff98df2b9a60e78ccc179269a74e1619d4e3ab094f5423cef7500bd03c407e54b7e544835f691aa2af7770ffe9b9255a2aa1fb3acbaa18aa1966bc119cd6000b402be5575b7ac9cadcebc549b38fb41ceca76682dd77f4978401b14dd2d8003a59946383482a41066177ab81c82198c10791ab88123b8afed1f627728c193d3d28648bd50db9236513ed5923fb7a6fbc03538d1595465c8e29157c4003c4112b12956d8be9733b608a52dbea8bc72a8563be618b71a1153afb19315c39b381302f2d466c52bb0a81665d4c1355302c5730a8eddc365465d4492ec4d134c821613d657e80701b0179c6d3fc055f84bcadb4797c6c45cef04db9b8306a06b68226a859493c29d4c346a6e81527a12ab5b0d71af10d400e6240daa7e66d7e153dce1d87bd03bd9d06ef94b29be3cf5fae79a07e01e284ed95f4954b40eb022de297cb658ba4e5bbb5b95fcc5df451ee01c28a9cd92ad83101ea390c414953dc14f3d323344e3a3bade9c53aca62aa4d46c6e9a8fcf2aca825c90868d4421a492deb2fc95beac8163c18489a26ea134cbf04c0fdad8d13edbc9558a3c59c2ff25093008a8d5956ed0dfa447913d78ed657f6553b5be07b55bd419aadff75e4a899f28fea15b4490c265944d177c8dd7567197100eb6679045ed6dd7b2f1ea4f6112a9a890c56f3733f9ac1dee531b516afe63ba0407de80b67cea4f79e8b82ce6345d7005b45c67abf169e5120128edfdc95f47d9aafe30e2276cbab95dfb02ec574a23e6528c18e2238919749c946aec2337b3368334b634495cd89a0e62781f638afe3912942e4fea621bd5b37384c7cbabb72b8867368d32431faacd19f804469f5baf2fb2e1f0b77c398c52335d4c9bde751eacd8303beb17efb1be6da669709e3dd57b422186beeb24592c8491ad8e21cb7c9294a9939047c678d993f2a79906f69b3518eb58a838e4397ac200c926750ef130241f3ee3b318f03e1878a355a794b295d4d416c47aa64880d643ab7401321613af2b2fe441c99882a900766415813e5478b4c53aac2cda9f07fdabcda6f0d4d5c2315fcbb03ceead79899d6ec300656f1d957465eb7b1d157a5146b9d7227bab394fc72f8da03f9ff4e01b2f26309ff2034bdef47a9198e39e6696f2a2dbd34abcfd739a7a4c2fe798e1c90209eb9e8d4e621623d4f450b8db1336ba891e69b9a312962b664d425c8dcbd93f2bb65617f5054f8e53480927e41d10270f52392a0d9e0f8526196ef99879d3d933a8e3d1a05c26ab26866c5815800ebd5d2903fbaf5d71b01b7060fca9facc2c676d24a9a5b27c3e7d19e54ff7f2f934ceef1f8458d2539a1698cf18feda9bf32c701e1d1485005a158d5dfa2d2f501edbba5cb0c1622d38c97b62d5012829c5fb892e2da84b42a7a2165016992ecd5ca1454dd96cc0bc40adbae0dcd6b6f4d622122efdc3410860ce3997d61ea1ad4b316202d7a22451e21215f1995b30d7bb96e62d131d0f2f9178696dcba8e3c282db36bedbb1b61223b0a43a4a9bffb432f9b7211f75433a825c7b95a0b194b37b5bd448b920ca2e6d02aea2f1cadb52c76f451a5271fd884330fe3bdadefe02ca942e83e3a3bb77454b475e636e0a85f9705dd6c4e96406a3f9e18ba9525fb3392aa624434528f2f4499a173e232ff4abb44b9d7eb3ad074bdba427aef023f9e95a77b1a13f05e8e406186d0a90e24f0702d7110654b832ad3ba0403eccc31eb2db14cfac0c2bfd2e1c199eb3133ac8f16ace73008880b86a43c4d80612ab0034634c96783dfe270900d086117dfc00b3034e3cba1f537ef2af4c8d8fb89aa3f379eb2098b0bd17409a38e513893295c074067b823a42d20c36d9a5373a14125c18ccd81e04877b20d0581af8a597419e2f307dbd77bb4fb4d68b6899a6736b9c0066f2c54f7916cbd42629c6f0c0adce1da115a6595fbaed429bf6d14901fd046aaa56b292bcaddc71e3b14af53fe64b4892554ba5d5d272b62d1826f405ad710bc44cf2e06c28ba1d280a683916c068b4a00c25a7bd2e92ca3e768b2a65718701bde735ffba15376cccce02e32302bba3db3e8d07e87bb5b3c39d4a7d345be96a657c88abe5e19d1bcc45446e34cf63dec3542e4e071a1720efe68c22f992d9a89358c3552498f9788d04ec4d52ec53142fcdcaf2da036fe526d75193f93f20e972e1767322dc2dca386ebb83cb4b6d21c102bc4d791c7470e3d01788fdc389a4278cc48a19b9be81b8916c8971f08887921766c93330a668450a548094fe794cd6e4baa0df42c87e91005ef91804026ca9eb78bd2089cf8fc0c2ec123cbea23c473d52eaded52a1fe325092638e01a7a7fc9b170fb444d84d502c5aced1fffc39b496c499e61a8b72d8b8907d9d30074867fa68cba8055122f6dd379ad80e39b758dab863be05204932866c4e59756525ce3cf63c8010f22f693ae58b0c10fab072be77ad1391c3976d2b3570ae55dd1ca00e7816caea2ca2ffca1366a5d17389bd76719ee770250c461a5d3dc41c379260f97cef61d24a8fc1a3c869449947b57c944a9a35986b42beadf69ad44903bc6076ae3d6ff430452b94baf749ed4e112783acaa157149ea4c5213ed40e9abbe290bf4e517e6987dcffb1cb5b882299a2b1b5ba6cdfd33446ec71343c4372c63399cd82fa3abe61a9174768b830b94304e6acbda2e19352e276bbc033c7c82b672ced0664c4c067bde2469acf7c3762c78afcea8b7db7b7291dd650702f996596436de1a05c447844a09d6017a8c7308a001f977f93bdd41b527ad5e212e48517aa8f9ae738f4364b73b69575eef1b35bede8671c144519c796022683112e5018f4b710f1d4aea018a00fa48b54266fdc0cdd148ecd33928bc7141449505d3163e0856a5c90fc11a653e0d864dc85b222a5645fd30388c28d316bcc4d46e1dae20959cc9fe06ac889a008143799bef62afe0d40f1a9b63deb192aab93027c962c5417b5470704d9234a1f4359ba7be61c7f839e98b718c8a80d08349c9c5bc65cfb228b1fbf434586ef8c082743126ae300f080aed77f9caa3c624374a175b37037e5b2ff08b76247341bade58542f2ea9071e0510e90bbd407e696ad6b8be62023ebf324566ce2ef3b6764c8bc401b0c0e3ba7935738edd63a44793944fdc42816c978be627cfb3033785e72153a29404719042630849dff077eda11e8645e7ae50a4db99d95cd0dcf71a28c68e70a3620732f08bb6db4a2b0a8218ebea9f52b0c17461f17c1408aa4c68069142035497131f65f49c4362ef74fe9467f8a1c94eeb7e64476427da7af14f6f8483fefc87cf7b563a5d3a7145fe64d49d713fac17f8dc2141fa658e8762d4075e505ea4842d5c567fd17e745e91891a7cf03f058a86605017106272b892d15fa3cd3b825b52388e0cb33ce67fbcc5f4d88bc685d92d8c112c543794427bc76d895b6e8b8804882b00c34ba7c94fb0763b8aaf80c8f2f86d375b9d995b3ebc93c56ea985b0f43c3049555de1b29b0de7fe07618a86f278086fabc7f85dcf2040014ff65e66a4cfd19f780c075f2937b655ae9d88af9993e9ab09e27d1196992a1bdcf99f2647785b14e7fadc22015506d5669bd69a19814204049489f5d06f4085a23cd01542115b8cc379b088088c66d28c94803024083d53bab239e4c9d0a2e285239c29691a1205441ab010f13db33314f4d4e9692734894e4dd9fa1779dfd0a947d4c2217d38204d67984ab0a67c79cef959f33c6a7fffbd52b5bd1bd2676f8aeeb96588a08a638559e750d797d42d43147eba47cdb701f1c543cf4e789007260ad0579c2945b943a8a919d3f2504372c94eeced14cebeecbe96a4e9eb6b7dd8bb516a443a83e356df7019e175bf374182c2549612b2b9c18feb1d9c3fc1936f0b9da370536422f520e13577219c40368b7861f2aa8309b389468ae3e1480195a8feb233ff9eb70fe02f1f3eb6ce57463a6eb1d931e98ea3df574be0f21f6a8bf239b38285c2f0468de05bd93e043957d2a3bd8153d41f649f6b2a956301094cf2abe4955a45c6d2a05173c222c7d1598f31f80865e0b3dfb63fc6ab4346af4a347420a2a040a827a8483f7bce8f62a9ede045e0632be4644786316a6de7c975757b0856ac6e56022c20bae20c08845803f5340f1646782ef4d866ee3fea917cf0a5566b565d746ba4072f6934084af0c4bf10512bb2ef46f61b6f8c6bd6c0308bf8e072b0063453d601e45e6005907c264b03d7666794cacb048ff4b8d4af76b952dbe222add73260c107f58c1e663be9eaa9e3498ceaae1d458b525f72b73b40717cf654ee0161905e0609eac354c9a0b331668887aa474ecfe24011fb57b8079c1ce568b6efb093f0d1a9ed18c681f213d0094ae3ca57315f73ef24b145b7156b4350b7d6149924eb2102e25a832048cd9b92083b5882f89bdb3537a568b48d2cf94268ccb2ebbcc5a38855d236675e99164f5cf1e06b5dc38a0a0c41579f6e187f722e39c93e25529e873744d1bb1282414bc8503b529b398cd2775b183fd69235f23d6c24665e17c46738a4fa34b2987ffbbcf34447bec131337bfe9a66fe99899e31de14f42f2ef03ea878628c26a32f19adf329ae69303414315acf2e136c4f2e9d0ab2a10029123b53c818b193ba836f5d75f2f1c6e1bc5b12ef88488c47b1b17ece56a6c3bc08637d24c565a9777495c69e9adac13d56dfa4674658fb7609779b8628672296fdae25a95384842eb764a7019c3e688dec99d477a60c7ec4a831c36780e16e3490f7ac861618caa36f40c0f6341fd98f7866fc1ff970c2590a21ae1a2ac8826e65826fde93f9b662427f8b1ddcff4a13d9ad493f0a9a07d544130632594663ef2766d9a7c8c724b0ea79e64808c26ee7c73d11fe2138208763cb80809226bfea262128dcc5dd1f95327c9309d175c075aa8652375b27730a8a388bfe13a7cad181cbcbd249ad1ffffb7e1cb886b6da2f4c73c62943974577bcbef54f6192663afb30e25c10c7ab8af1024ba13fae5e52cb1cafdad3209335756d6c1b03c5f7a83f00080ca10f8416469759a92afeb9315e723f5268ca9672256a41de2cfdb13ee229fe8f063996b0db790e7729014584f255ac2ca5134d5bd3ddba8c42cb3252e803c863fecf4d04eb5edff2a31936186522fbeadd5385d5ea303d04baa82a425431e8d7841762cf0250bb66dda1dad9ae5577cef20375ac31b09da1cdd0d25d4378183600855a766dadddf2e49cfc21b9229c04479cd65aa2e33852c9a5a7fbd914a892c2f8a87ea6a991ae71f2a5911bb747e8cf74a4d9fc7d9e9b1150f283b0ce9be749bb50111906f41510384284d50bcd3d6d6bbedd1e8bc92d14e785cd215a59e884e14f8892a5bf496fadfd6fd8f14d5989aeb027c071f442ee3cb8b3698db577f22f42ad5caf0b8f3e654f27b05e8cc1f0ec6ebf874a84abf9c0762f40f9e60a8da8e036ea48f9d49a7beafc6e4907dc9cd7313bd7cfc0e0902f851b43c820fd04b79c3846ee01463cce664b65e1bfcd475635e8b3307b6ce3d4ae13a1a4f86a906de90c5f35ceb4be49ac934d9206a579f6a2c5dee2a4f7ef2780598c1c2a9360bc8f0bc0bfc52d8a50fe5b966a3f8202951aa5ba995739e619a1945bdb25162f2c8fc0cb77f8d4b68f93f3497401f4ce6e7722258e6ec7a8865e97d4fb4990f21e7a13590014fbe9e16e15d3c3f836ae60c48a193ce564a3d3e14ddad814ff2b4265ab1128eee3231b5f92fb4296220ad732279e648bd90c88bc48e14782827937997f2f59a032cde4dfd501f14866ec45da3a89b842f03a66a231a13c9b0069a40e659e3c4d7e9486610a1b6f0d87abd3559ab5ad38c95393ac65c5e2ccbc20cca91511715f786fb04dc7733f48d42623ee4189c5d881e5b04d3c8c899dc04eba122ed28c94d43e9e81e2a36f2681192d502ecc65c2b899031c73fb3c9b5938091692a988245106024f3aa77a9bf480b38535673465e0b29fbbd07558fc245e0af2ce78a2b7b046993b9a5cfa8290c84457806a4de2022603646552615e002b0527589e76d094301004a982036aa1a2fe9b6e704f2f11c84c9b5c50a2015111264fdc911fbf661507364c0d031102a9232f21adf5c2c064aaf20df8659393e5a1c94c82a632f6dfeacb84fb495d094423de58940555c82632c5f0fdf68eb11fb78878611dcd0977ccdb579eb7a5b282d304cc6cbd2c34ce85fa29e9aba0c4da2b85ebbbfc26ce80104cc77da15c5a59a8444778f191518997bb063d164ea6da4ad734ce51c79200ad9c541d540f6dc98a558ba91f5a9c4886ae120f4dfe3a940bdb040e4c0c2a1b89802588aaf15f04b072894006b6f2964e0e6cb85a1ca4a28b047c1f0c5e2f5c09679563051d47f50ff628069357d3c475785cd85a6d46424e2243dc9f2b60dce5916b1c892f172fc50467085742f35e62edca45cea189f390a5968ce9748cd85d77ec1c552d93786b364b84bd12ef0bc68aa3c60c4f25c75a906086ff876a5abda8d4d9376abf820f6d313727c102d5d7b8a3d5e8116377ce11f0562642b0884850ffdd791c9c2da39ef95d10bb3741fef5cb32a8029d5714962a8c1a4158a9d75341871583a3c46106c5f9576a64bb7352bd6cfa19869a1839645f515bdc7b890f30e7ad4df472b1f9b4531775c1ad4fd8bc7f5d3c3e12096259981f42d3293cf90b9824cbd6034d12135d285fa01403ca1cf80d9d1fd99fe16587efd5a5924e757588ab2f27e16a45a6c4b30f459f40cb60621953c94766d618c03af9f5cec3475f13e03d9515069eac8c071cefafec06fea1b24019ebc91b77a669f7a30bca91cb462619477093b26cf8d24ab7a477a2f2910d4e23e519c85e72ee57e776697164288e24583aaa3a5b500fea04ead37880a851f00f26b0bd475171c2d2ca0b6eaaf875d0d8f6f788f47bca15b018cfbabb8b46584c9f2a7912598363728c0d2d85b8eb3baa15d41c6a6f7a40760620d8047c3a3770a7b706e44b2e55a2e9f444d9d7c089ad80767beef4c605e348c38eb6ef9172d5f6c1bb44b085d2660b955ce7e8911e314497067b7db6bb0f9004d9a4245301a991f6f975f7ddbe56ca6e8d21a1102917d9c9dd7062ee297bbbda69f5e4def7cbe9ce6c30179fb39f9306f32f160626dbefc9e2731b4989bb7fb09286e61b1367a35ae9333cd392e14a7547b73e7b2bab490b465e5de0b3b8a65eebad9bfd7a4a38880b4acee80037d9f2e8fbdae6695e37e7421db5ee81e50691f3675be2cb11fd3109765eef00ec1259d5ef761dfcf39407f19b19fde63a6bf6f926603106796286625b91774c4cc5329cb42032e6cf1183e71fe6296500988c4f48cdb917b09e4c199d5f52168909555871db8ee373bf231383b0f4bdfcdb46aa3bfc92764bd8359f88bf2d9ac20c237f708a6f744c3dbff7b9c6ebdfa4ef8d9c46d5ebdfcf8d9b51337c5b4d53d324c105c12b3760df5cff02503f17d169e725e9bdfc8457b3dc87c902d802c073977d7c3e142ec947772e094edd4a460292be268736c2b08bc6347a7dc9d05875f1c7751da4720e26e5e67b3a3d612705eb7050c6bc5137d998892e7564ad654b41f8516d8136344bcc920d92490ae3ab7fdecff475ec7420e49b8aa0e424107042ffeb715d555ad855c5d376922f658974142f03055f841147fd306e5b78e61ab90984d796bca18b64381f9aac0c346f8b3cd656aac011ec6a842e8728efd81b4a580ef762318370aa6e47339d0088f3374be0839d70dcd3f05c83aa67449ae125a25df100286f0542d6956ef2c3a8481a9506d9408349b39ee0ca8843f9402c49f2907b72044530ef0d747fb8802d32c06c91b64c0e1893b9ea5b822c8578a0362e990b70a731fcf82646d28901085cc6d957ab24bb72ed34a8f50458283b27e3dcd06d8135d5feaef84e882fa0b09ce92a8c9899381a13cf16b6d5b8cd3c85c4c68028196d9a7bd7317460a3ebf0f852685a215cc9b21a7e95b44ab79bcc83f266297be366825de73044397786f6661595ed4a533f49d601f4ee95de045eb1ed406b3d15aa5b2676099b58f289033f8949a15510f94c0d630703fbaae26eda633dfd5fdff60d6bc581f849bdd1155b7865999c8667c832080a9ce96d1c19a43f06e7013cd091a1d25d54e6c08846f1944a2c7c569e16e8780fb0e65b245f6f7319aa8e6555a83ce31b2c76d90ed0ad7aa6c99076b76e05255890f5128c987d6d39dec60e509f65f446d56f3ac540ce57388587dd2293f34b9f32a93b00c481c010115dfdd81a979c985d94636defa66da4e3c0b52d24011a384c4e6ad2709e9c38e13cf024231bace4fd10434b54cc29b23092346402c4267b965ec189829e587b82b290a660feb2b57c80a7bbb4f88db33540ba6cd824f6bbea25b9ec9097c5a206e05168437e87ed8c11e463f7fdbfe83d63c8cd8063180568a71130d32c4bfc6cd97275f62c3ad7bc6b6c2aae843ead5647c3ae63092e94a39ef911268ba92c5f469ac732f7b29b5ef14d2c821bbc62f6d3abea7044aca3c95390548fb648b36b106463d6004e347012715853ab1c651a18ef35121f5b242d15ff87ef3ee77fdd9d83e61da9d980f502ce3e806aeeb1fba3b28a94e7bb2377c91aa2bbd5fc64fa5eb19f600067e0b12c83104d82fcbd52628e4253ab36f70a13714bb3b10e3d20a32f13d93cd7497fd5ef281496cef057c21177d0d3621e32838715107597d19814b9062c0de4061d80bea6d779e79d5cb852dc51dedea2c9b1a9cf8579757d839d9e7ffffaa9b96cadd9a9ca9aa0d7a46d811fc6f0d59de666eba548eb8c9776d29f5fd6217856c98c3b7158acd798b1969a29ee68a3ecdac8f5b7610b60a213b24d5caefb48c92c883cce05d83001109edce44725c6ba7274944ce915c2b6bfe1bb8a567b3041d7f312869e17c03b0b0f524f8bfd25346be60ebc52fde436bd4ab52e42514e2882aa1d13af965e0881708e4125dce4748a2f8f9b48f85c36d86827226b9dd86f0964b323432851281857523e8b73bdcf5a7bb14f8435f5058e16b318839641cc857106d664d68e2c28914568f59abfd62115ed6dcb708f8886b2c5617141abc7374190f564b79905e81f532355910e76d84c535c510e1e5d808305e0732c43457bed86ac91bbe797e1f1fff46933b148ba8ab0dd6df0fadee7118697254bdfaaa44634a1414282efcd025cf349b56fa340635db718622fedabc080f012f9a961958cc54385e8a147031dcd945f8c3936d8a84990dbb17e13db20465997885d2414f9685f5c2564daad1b3347c38d9770cf0407a5e050ae482437e9ac9e88d36639fe2db46cc4d7ebe16e9d5f759a510d7b199432e7d003c8cfb322734de8f4dcdfa5a2c2463c8076497cadaa499135081fb190450e837bcf192ceb917c62c55284eec8824bd60227865e05f86a17e90171ea9cd690678638e6fb06aa802c23bf598a3dab3866687b719e9bbc26326cdb04acd04262e4281969e068ffde38a8961a4936d3d5508b62e22c5ff9d6f1fa677fc8430c6b8852e9b298a09d61af47a2d065858f7d20b49519d30d6275da1de510d51ca25a721e2952ab9a1f3917c4892c136a6fef22865650f92788c38c22c60abce1de030210ca91bd917904a5e8fdaaca3b095934b7dc40bdcc9e522d098842e77856293a78614ac79bfba414a2b6110214e7b49704af2fe6d36835e9f27efa079cd5ba048c4514233dacfea2854ef179727a05f12b44aa5abefb5a816820bd2a7d1be0798cd3a059c36ff04584a0a42cadb19a060395fb626c86800beab860fe3bf6a26415555eeda93d090d51a51caaa80e0a9ff27f93f1b9980d8b77eff13c0a14f30a6f2ad61ddd0e25ff716c5b141195243a26e853434cc195cd18d27d9f140e1eb8beda3ded0906600cd7f3df35008d26fde4a66b9a4a1421a4fdf66696437b15e3dfbf4aab4bfc4bbdd5fbd1df015144e253f0e8e07741e88f90f9905c3f3f7ceb99b6eb6c80e7af0fc21da08857c195de0c8fcfa2bcfa2f9b3e31599fc0792dc87f2e1594d69962f1c8027f67d447093cfc5221e8c7b8d1db19f3fc343f534f538c9f80c5b2af3f98f80beceb576f66702a4b5d2ffccf4724c1fc6a07a8e56914d90fefc10135a2ad8601f63c5c87edea09b4fb2b4050af90dfde543a4092b0114ef098de3393824a65e836110e6f79ff440b62aadea69b0bbad6a35d788193f02c5d6c8ad97a433d4cd3746ee5c87b39674d71a435820c64fa259199ae9ae4369e87beb15f587421c33311bd2bc534b141f04750671ef2a91108651336d39c35df6ff55909ac66003496b1c4963b12ea191f66b59a480002b1510604570f90d5ea59bf8a4157d0377e2837b5d86b5aa09e02b12129cce74c00e125c25239fb35dff5d89e8e83e3bd701bbc1efa57a80242007e5d4d5275d66442021909f1d8a1daf1fca358ead9c3e7d45d5c64684b63936fcadc692f326e77ba363c4e6426dbeb7581f25d8be97336f0cb0d1cde130d0100fe979faee49fa2043dd4c72d9ad7a48da446a00e50aeffc331b2249e1eb7b496821f3097340509e2639529938b991dba27bbd17ae4a97a3574ebd0d60b0c32e6fb9888c45b12023f5c7e286cd3ad93521973881285c2b9614b2fdb7a7e212c0551f1c5918f50206dd3e0426bd912ca7cbd08d407e7fd531a9dd83e02160f58a8eb0f45a991f21517d79a72a057093f6357eefcb0d6193a0d9e70ed5f7cfd36fc8dee9de9d2f9e76d8617f123b916d72f629133176a57304eafd5c3feb09007a0df1fc5ee62a2991838a2367e1bb4751f46cc5d7373e254933dd802be8a875ff7d7ece68b32873e11e87eae981eaf4788c369a2c52673d9008e0d4fe49374a4765faaf2e287f0d2d7a4f3eecfb2502f0ffd5d1e76547d6d9b85a763e9e659f7b32a194bbf962bfb117e9c5b35b87329265a551b43c3b6e4c3d8d742706a01acb8a3271a2625bdb4460db44aca5a88963e6fc38d6e0e6351ec52e6abe945ce261e749e8adb313ec6468d5a263048b0ac4f1985777acd083eb91ff486af3d98e41e14a64de8a5978385a4f63d121e24dbd6cde4256e1563f8124050c22d0454ce16fdd5010f1afea0309246966c3efa5ef973e16530dd7ba234cb8784d456561668005becf4642d2e6ebc852ddaf441f13cbb1e0d98b32eb88f572c36b50ed78e5dc9c70f70f162d2499a33c7feaff8070d506a836ec2cb0dc885711742cb5acd46c6460dd8442cdce1daf46cfba2403f09c0e08631982004fed6512dbf14bdf6cfbf71ed74a95a755d56175502824cf6473ac6f6ae42c8321f3383baf330452008c091d869dfdfad83973420b0296fee53e4753611b442d7da02d981fd29082c3ab0541b50fbd2fb68e600b23e44e91ff20d4f613e20317483ad582b0ac51c2394e756019a8f03ceaa93adf99c13d68f26c52555b1e67bcbf695efbadccb83a8f48cc66f82b6bc9daba37371322fdaf2c0a46dbe9076a90aadad05574d14c3d1f8b976e5ac7d74a4f2468dd52a9eaedd568703aef6b0d3c6bb8d7dc98c09c6301ab9e53f21785e47744526cac79b2e9ee35dbb1e87a57f7c7faa5bbd22c6223d1bf139bfd7b99b23fdecb3ca6550471c75632ffb1b3db4d7b64c496312b20dbfdcdd331e859c99248462e6571c6ecfeb19939c9b83ff12080948c31dbbb952585cf372aa4ed50f576afd80b98043eb53a11d02752a007b791995dde0d2e584d91b3beea7de58b02ccd68556b744580174e8cb58cc0cf022f31998f94a6a5c3b3f9c72e616763c9f4b79799d96a217d630e1198514d0356d982ab6e083f63ca7a307dd986e1644c8254a8ad0147109484d958d42d3bb4aeffeac6ae7660b16943a3b9c6165aa912f7dec86e4651fd5cbcdadbc0d33ac47c5d3aaaf7638f13878173a170791402ec65deb8cae704f4467c1b0362e9d6cf490b8a3899e88ee279b11a4a24fc82649ddb897c7ae50ad8fbea2a641c8c2b265d1912dbbce16647cfc07a0ae9bdd1e7b88d085756cdfa06d00ec1b75d1ad39c7a6612292eebfe8965dc78803a85fd4cf6edbe722ac7d31106b1183930ba293c750f7140a2871f2281a92aed9fcf1ee45be4556709818cefe3902cbaac82c0e322f842e4e5a2290c101d91e84c7d7b9d309cc5ac85658200057823cab5b5228741b626cff72e616b3182d08474355a5d932cb3567bffbe6d6872420ba3bfd108ea2789ad81ca4c9da11a45747aa1bc577a2f340a18910c2e7cdf8c92b0ba6c9e85fbfbc98c0a9b7e0e9b105364055e216edfc03d911df1bc78af46f39868e307aa4f847b0a0ea336f660399793298421065e6a8f922b4fc1b2028021476d6297113411741ebc04498d4b14bb4f0051f8ada5df289f5a6eaae0ae3ab3cb2351571ea6bdc5a5c761be7c5ea8acb20f09c3cd8190ff911e4cfcf458daa45d6020f88f988b3c98211d4758345d370c47a6c6a2f2828de23a70c4b6baa5fa068dcf27d4a39c097f1f0579b2481f59beb7bf31ed8503027a51ec505ed3436ae4072f4f5217d55bf5052bc53f77fac62231292a3be00b8b0d06250eaf73f39a41c6a5f0ae7cc66049ce28222bd0f22fe0654dd16e864dbacced60783ec2638a68b45fc9c3cf9ca162e587c1b35423d5e130ce0669729c9972c9b4bd39a0b386898446b43e00c27e9f0e5972cc2c00fef7c4308d31c49f43cfcbc324e12ae89b4547b84872160d006ac7c457ca740f66fda6bf666003a1b473d4859a2e5ae89bf0cae69e9c87f1f035526392955a1e1284454475075be76415017bfb4511a41190dc70b4013f114a09c1132eadacd92c28b273bf4617c7c19d129e941d6d37e14d1f0ceae5040287b9b78c1085b301891c951db39aac9c5833ba8e793b82b2ddca07d4e513758b354cb152f691175bcc582de57d2d3cee8d831c55b46e572962881e8e45a6dfd9fc11051da1b64d0d88c3b52301c1b8c16f7688c5ab2da693fdd408d2640ca77eb1c7a5da00579924496c22a49e4ba73282a5a37a227aeeac70cedd7437e10c7ab8333cafd2b8876fe41b9f42408fa3bdf877e4cf05d807a521eaf8ebe8b29a871f4878baa63ed49f5ded6979b8812ded606de615d9832b0ef0b2f0fd03bede551fa60cfe324d6158d80106a9af52cf9731120c40d1e0d144fef52181c1f0e45bd8324f57a6ba0f7b221f8d642971a81276f2bedbd671e5e59e8abf7b6d807250f18c8b46742e0ebbaeadb6c337b839243e505a44fc7dcecddb469ec6d1660b9346a38b7f4995ccddacd36de4723e4509900f309454ef04c969a1130dfcd73b3b7d926f6163039a84c40dad796b9347b1da2fdfe571946df338abd11694470e79e51e16ce6aa52acc0b7dbf1c127d93b235bcb0294afc4aacd6cadfdba6a7c7bcfef59b6c598ef9a3b3fbfaf8ea3a506e3cea8fbddefb07cdbb82b9bbddcae9874df0da3d99b61937b4be8724a1e976cae2f5daeaf601196c27cb50c7c89736a3027cbd8d1ff9aebc4633aa6c3930720e1258aabf5df2f4e8f3ef8d90b19369521a887618fcac878a86afc51b6d3dfd10299948320a2e1ca475a803d8b9e3e3f46e744594d6592046fd212f9c886e73cdd21628af2ee25f9e17161c8ff85e5b35925c0ea4cfdf6bd45e2c3750499f0547386f3254ba7fd07a4faeaf5223789be11d7cdb99020d546daa8802fd7722de5ff0411faec535162a6d1b365c097fa06fb4dc5c57a41982e2191a2fc6c4a9406ac5e10d9c6f9d90c2e68fe7d5ca21d2fd0ffb0b61c2592975f4997f307dd1d381431b2b702b461f060a7372d8e17fddac64fbc8530227a07ce38be7bdd4ca9fb6f97f46d2fa046cd3f8cfdc234358681f9711ced1dbcb4d28fd50cb180b5e8f439d0954af572c68baeb9c23748514a5174c79b3b5c751720afbd5dbea4686fff7ea2da2d6cf2ff2e9b46d4b3ddfe0ae33d8c9d958ac067b4e52cb2c790973c40480ccc949a05e621029ab18c4f5f055152975e249b15295f60376b611c779e5ece3977f2be369af8ee365cf27bb37460adb6503e0445907c9963d2fbb44ccf5f739d975705b921c641df98903b13bd3a2210e3b00948621e0d72954737af68e0fc0de884333ca1c40831c8b124397514de1e8b950893d074212952d968abbddae954572be8fb7c4d435d5f9d6568763126fdb0be439895b114869ec8fc9e35bcbfc9af889c78c87b3ee1bf9aa7029be9e2bf21e11bf93d1865370d6caec5a6e2b288022a2d480a88208be5b3f53a0c16f1b09db86641fa722c2b0e82c261209eea350ccee377a86e4e4dfe6fe8547bf2b2f1f20a5e64de7eb509fa14c1e088870c17f64a46077cb209d6767b043b22a2fe9159a71225959de22c35c8495aa2431c7f7987c6295fa11f511e32c3e3249fbe00004493797596158659827c217840c18ad5b723d46ff08fbd24c82ad3566481bedcbece99d3057eed5d857981756d3b7569f501d36a5038ddf968a5496db3c191b8332349876233f21b700a6d648e0a5274dd40b7a51dffb402077360104f6c214558b527e467c1f13b648e4eee51cb90192998f5d771a89e3ac4a355e173fa838a67ac78bf8878688bf6a0bb880dbfad9a201e371553828a7640516785536224d5c091030c4d01b4c2daa084cdd39a403e4040b7b72aaed79ebf1d390b5aa4850a79c925c1035bdae91d2c666f6fc06a7e6a1522813e4e924a752542a457d89912a3ebd75b53c4a7f2c8888eb1c258f5985a2daa77d7487490193e231699968dad85579271d04bae5368ee136e39657257ee2f547130703c0fcbbf3e1a3b1238fb7a248398c5d7c91f305194457551194ecaec47f75a8247d62935b60c8dfc080380905e439950820a5458e284d758a05f4720a9444a3a09664089ea3e6b061840adc0eed061c1f11e0504e182319f0332184fc856e68e7ca2b0168578201b94eca436634f5d5668292b6d8f1b565c50498b1d321bd820fd3b5a047fa366da6f506cea379a27205b32f41c81e22758e27e0f69230a2d38f44ab8664f45e6183cd5c8d16babd609150d953f6c2b6a137592b356c2012f66e08e1558e74aa78d5f7f5cae9abbf5aa2a448b3fff709d4c0116325a2fe630e98abbeab369a6b302314ba1d6cc594023ea9f68e128a822c96b7ce6d820a55ad15da6b183628ea09f10f1627f7e1415028238652cae49722073f58e18975e7b6bc600f4e5683e8f43226fe1c9dc17ba33e6b8e362680d4db4ae985554a33567bf666cf35d92da463857bbffc6aba61f4d0c85335a1d9c0db3587ef3acb2f96d605bfac2d5ce9699b5b6ff3bb490d530b107f5fc3805b3c7994a0be4a9734a0a4eba065a41793746c1613b3b4dccc0d0e4acb4cdeb938165f232e78c23096b546a9acae789f94cf7525a5a523b68e98a70629822f3dcc1f126859357582ad277323d27f9e3b013baf7f3afd7c58372d76aea9fb460ccada14df5f4518e39d7e9b4ddc23aae53849fdecf93e97453f0f84506863b1fd6764fe3b49339077c2bc8a359bc4459a2357969d34982c442e157230ca942ef58215112989224081b2f8ae602d37b21286be66cb8d603b224544ece5286a4e1583cb9f3d14287ee2f24b7afaed7017a72d4583e9fb647d04356fcbb0406be81a7e1dc90770debccd32c53b0381f79150099fa9cf20ad40069f021147111eda348a66dc0c8dcdd1977921114554e6d32f14cdc1088900b3e3c1d38dc368158dd0d8a630e83baca036a76c655849dd547d46dba517df6c58726d87dfcfab6501ef2cc1ff271cb793cb1bec9bccdf37d2521991d8e656048f7a630042ad789db25d71db150eea3bc16ab389e16ee6e5a3d9ddc607ccb1fa478000fe4e47e616e3ba41c4dd5c1d2e0502fbc17039f8cd008b6442b4c286dfb7a29481001c490039a4b327b59208e42520745a71715254888a73ec979b2fde52fa6901276eec1396e8ae3295b3ef9a4246921e4f57ef79423edbcbe8f2c69cf99e781c064531a2cc42b6a4e63a12f167e74bd9ce82e4da04c5e03f220b6c9967b6f295392018b07da078507b8a55b923daa2e074363aa06aa2eafd59a545d270afb1ea7f2e1e6b04eb5ab4dd93f0606ee19c1330f70e5ccde2fc96637b18a569e73728db38cd86cb6829ccca7966a293706b57b6fadd3003d29cc4db43645f6f7bca75e8b51c114d6ca421ff55d8fe7794e55e58a385fb240e2214ee9ef4dd5b563cc0f6b54d145132329ca0daca9d50006932d9c805252296250e28c520ab064319303759dc66efa983c262670f4a515302dcd6eea261b29dc40fe55875570c1240951e3a296bb3a9cab7fd254ee39cfe1b0b22bc32976241f1f9f9dcfce7d6e3e5888ddcdb9dd1e6595951abda7d59533f6842f7ecebb3f929e30f5424e9f0aff34f6846310d4df71341a7352754811244450d815b99183d2c026bdf504115259bdaab987d430780d754abd71ee9bb5d6598d5baa45ae8b71bc8cec2f56daba21a561bd340429a52105e98794d29567f0a2b0ed6b2f0d65ffe475ed93bdaec2b105087c4f731fa84fa7d3a95f3d3c889630fcbe0f09f5e13edc87b3d6a2ea87fb701f1385a5be2bec9b5fcef35b9124fee1729feec37d4ce26d5bc62eb95dd2209b768901f5fbdd1471d2bf9d88558e2c73a1b64bdfd287b34b5f9a0ff799f9943edca794bbbb6badadef0b4f66b0c0662b83dc62ad35c7aae5eead56cb36018e99e1ce647ff149833d03c1bc20cf5aa4ae07a990f5a8508df56820ff00b8c14a188101a0ca40a030ff4c633dec6f515db84b9b334c11bb2b50d035daf410868630362f5f9425c85531650a9b92952b965c393344103b3668662a28fdbf635d344b65f37bccbc9e79b5aee853d8f72050211908ee1750d2dfebe884b2fca3d09e82925050d2adc0e99a0a174f14f9e903880c77fb3cc77b1166b035331cceab16874b05b1ab65b4eb741581755d8180fe1851418d5aebe974c3fb1501010aec3ab293946442c976624198029be42ebc44391284ab109c80b2bcc8ac9b18c9d58610416117be49d710e5c44fa1ac45a1ac45893e2d278308297242a352a95456707dd3a9caf10dc103bf0ffcbecf476583ed8b482435c44937005007d485426c0df9019a0225fd81545708869ca65196a39aae066469e9de5badb5b69b4edbb03133632b95f49728a0d0a1dcb1312601b32895f49051ee380ffb22d8b510561ee85a4ea1ff7bb157b56b6d11beeff1e636271da929558b6a6aace7d7c744d4d3dd3809c70d85899f531b87d3d4fa3a8f31ca86578dd359355350187c5d25a0ac7e26d7098e92bbff749f528a84fef47b7f5a991be47034bdcc7b2691aee53af2a090b079c4cbd7496bedee5e8c55aadfedc42f72e110f8f590b5f796a032b933244460b36d4cafdc22d07cc4878e3031b9f15a6b0301e183c3e63d834dbbc5096cde267cccf830b1059b76096cde323a2c29814d9b041925247cb4f88cf111e373f339c2c7089f227c88f019c2278c8f103e493e410081cdfb830ab069917c8e7c7cf0e9c1078c4f161f9bcf171f1e7cbcf87409b38f260aae11150aa524595b22d26e4772c11e17ec3dc905d3f1e579efe3ae23bea2311084e057d44529a8fafaacbcd329c5152d53abd48b3939948a4c7fc222b53a569164abba3c058e2ada2324f5ed8c80a15452c768546a4bea659e33be522b997873a7bb224790749d61ef65be8117f82323fbd722f4e70b6cfaebf3d6e4d0adb541af5d115a4ecd6dfe05250ed11fd43854877c4d1006576093363512f35657ce3884aa9f389ad44c12277d09dcada13a2239aa69c10d82e06d9f16923ba367727275d7716f75ad58b8a5a3475913b83e0fd8fcecb9e2ea19878669b47b31fea72a953dd1685516070bd1b0d9389c0882a0102fef8b1e0d38270423fae3ef5528cbff820b76761a476b9c09b6bca3d32a0b175493a159fed53dffdc3ae8f741fbb957f79387ee417c07199ce7fc5de7ef4cfeafd7cbfbbe8f460343dc02d32c2a60812fca78732add8bb14af58f742fc6ffd4bfa948a05d2d43ebd036a829b9b45e2f7f7549d38c318344a9c436a121c9f843c9c257a2462fe29b2a2a3d458aa3a31bbeacf6d4ef235e16c71edbaaa78e7dd45d9cf41d36e03f8a9101c30e6fb46c11274ce94d676c64dc208515326a4a8fe1cd520e67989818a334a187306848a1858d0e4f94fe4540776f05a160f8729f16b556a4aeb95cae695d92ef3f150cbe994198458bca89e1424e751df3ec6f4f3ba3b04a73a1cf32a11fec7cce9b7685376d0bd99f071c7cfa5636e362684c47e8f390c89eab9e545da934ec177e94bb81a98a2a8a3b6192c9e09cd779b37745a63fd95158386e49bd7f37c139d3a0b1d3fbb719f4839d7176cbd4fb1a09408d33f28c1e789cbdcad49bfd26fbdb294e68ec34f6b557ec0b95d27a5394a64ce852a4823faf7e35670bea6b0a025ea25ea462bd94525abf9c70043bf608f14a7cc72d784ca2045c89d9ac39bb5459494e5adc51755922dc82a1404a47d60720726a658f56b656593afac386b28c7294cef592e8060ceea65d9582a9933992c066cde572b95c2e97cbe5320d80127049e829dced0824d565adf5ec57ed47c1fddf87242582cdd1c6b39efdac9733819b23a4245b93ed034110a43f4d486e6d2a6a65e4c8ad8d5aa5eae8f37d357f5e4d91e50bf45379048a860a1a3e6a452babae442af4dda02eb2fae8c90da02450d29facae0750960369201e79014a48e88f7f51cf4eba44561fa9174895eab5012cbc4a71ecd9310b82017f0d86b26cb6a1d702ff0801da80bfb18784fefa754ca17edb1850c79efab44dad892fb5245ed8428c19c80853840e616ca96ebb2dd9926c0a049d77248159b0dbe1490d4d7081c50a25016240438a9a35582c61542615f1429a3662d0480101706cc29899d16931a2f4ef82e0ad3e2ddb0e0b177423fa7347377296bf1b5d376a266c52a637ddc89589c696932f193a56816820a7523d07b928ac5d4343d5559392983c6badb5d67a15fae3563a498a1e703be090fd732b1ec6ab5098e73df80e8e831bb9911192284e9874dbbed8477723374281a961c9fe22520917ec5a75ddb10467f9df7b42dd5a29ada9143da14aa81d51580e180ad66a4d277af212de6b868931a4a89141072f687461e60ad396233452a830b9b24486156630a20b18d65cb19403163494c6287dc922841a9a1ae70d64685840293d0b27665841131210649a924ec0744607242dc060b95181a2060c63bc8872c6891a32a4a14517169c91050423ba685263da01b7d4001e54d832450a376f9270418b2bc8b090061ba5282ab0a5694b0e43c420c54b115378496309da121060d8925030424b183eb459a14a14a53f9931bc2041e5cd1636201c51c999898109382b5ca1c244166378d18316a5dad1c5180a2660802a95192674df3fa8834792d8896db5a050a1cabd18d7ffe17fef136de0e436bbe6c34999933f42d4c0f0224e52153158815446b9648a99a3a2315378e1c20db5a3dc0d35fa5373a20723354fa4f0814ab9e4099ca52a5dd09086132f9c334a696e140a55abd9dad885470eee06dbaf22da3276bbdd1377ffbe5d7571c0c18e03fac30185b9d7bcdb511806d9a5cc40856880d33b141ac87bb7da612118b049757d545da8ef40d736717561610852f8c0908e9d46141ac87f6c281e086f30389e21020717b0f8a2e5484de9efb3ea5a02c60c2d66be88c243133894feddbd54734bb9a5dcb7b4f4e5fe0906bf7e43c91550b2d7c875ac773e8bc29be0dae46aad13c349ff351f6d9a9333720004ae6f450e4ff23fc1369b1c6408a05e448db8b2b0d87577f75777bb5d2a0ba73914ac83a23f23ca513a2375944dd10c70d05c9f301ca69515be0fd4d52717fa850a7d9da587c814b5126bad2894066084f4a73128031f113514d425ab2cc775ec090a13a915d9bdcfa2faac6d2665268b7764e607dbf9663a557b98a9ae3eeb2dd7e77994caa93527c75a142aa7e634799a553fd15134188d6b2c52ab4683ea27ba0deafd1bcda9c168355d45e34494783aa150a714eab4229d1c1212e4404e4bf94e8e8a3ab62f47649af4a5ce9b00e8316b953a6f6ea0d279fae2cecac6e3559776b565e77556b35beebcb79cb496665bcd59d192e4826bf78857363ea7a888852f739e8556a9f3f8f1aaa3501e4e3b309b0aa507307b86ec5faf80d4d5359d9c959736563d42725644b54708fe9cc7235165798f9021fd780cd2d3a3095eeabcce8864ecb39e6775a9684d9da7ad7e136c77ec2320f79bdda2b1d3f7dbf0cd1d03c88d23f76b405d40725021f0fb31a042dff7dfa0b1131a88c6eef7db800289868209caa2194cfde8d303f1d1409e1a4d8c1ac7b1eb595d486aed72fe4089a72c568fec22e823e91891adda725d3c6390017592838e018002bd32b880fef8ab6c361bca718079bd5ed5659dc2b8c0d4c92f3630c4a4b0efae600d5575f56ca69aa966aaf082e0bddf77c14bd403d6400978a26746643c0061441e5018f8c412635e2f27b31baa44217d5a2f9b94e621c5f3dc1dc96fb7effb40508332b067330317e3b75b06b71b851520d3a65196ff454385902351587bad15a459fe4528cb5f4553558abbd8c6630d6cdf6fe50a581c93784992230b304dd8dcd6751eb67f0b369bd683054d536a5fbaa9c126ddd99d096829da65a04119b8bb64fb79dfb46ac4054e092428e94c30d500858f71dff9ad6944348d8856ab653dcfbbddbc1baed5b030310d0d31310d31315925f023d34a23e4d67ad38095c644d3d53a0674e97cdf9edc1a75abdebddebdbdea2bf4c759dd23a54066d790fd1d0bc905f7d8c3c9efe3825fcef2ff7e28903f10aafbebfeba7d7a30c1669d9263d25bbde2ea23af42635328ec7b57db1c1cbb060a44850a75150a8e661bd5fc8d1da3828d8850584d6511ba08857d6f9489a48874c0031d0b8bb0278651039981c906ba914ee98ff844b95bc5b9cb13224363b206f22b86c2c0311d0b29ecbbe57c770af5ea71db3de5f4d6b812b989d19f4781fa01e0f596720cb6c09d61621a1a72cbe451d7ebd5302bbc0517fabc1768b74061fd31179a06d50b471f1ddda397780ac3d3e9de5378eaf30409341005689ba350027d7a04282c6c03869aa1155440292c14230498f0ded3fdd3edbb6a05bd86706293914f124e2035ca1d85da15e9982afbc7528087509c164ab9db03c00ab22174776b05bfbef909c0e03709fde01339e93914a8e7799e67bd342a4502e52283ddff29125629f4571168aa0708cdde8b40b3371ef17e040dfeb7da7247998344436467e0b367ae26535c1082065b1561ca1f4c63e2f0d0021433984aff0010800ad9efd8090dd4c1152f3ba1d2db15df870251284f7642134b8dc210a21dcd15f176457656aa164adc5e482f7f4f2737044465ea52a9dcb41012fede5481e10dd2c205a9fdea57c5596b6bb5e1bdab0d6480922950a2a6156080467321f53ce7f439a25c4ef4b4104fe2a8aa46eceb02eaf232147cafaadc920cf86653a5ba9ea7aa2ecfe248de25fbab282c2797a3b09783d1b1568b471c6cba18bb8eb5a130da4c365babce145cb4109405a63835703cafae4c329856d6ceb76c5bc8cae2e10536db66ab76657e08f86bfd3e7d5de5fcceca3ce2e19579c43bea417d67d4a7563da8980b38fc53cf1d3b4bc7ac6099dbda3f643e6e752c0148db88aa8b963c5fc5f5951e2ff778020d7726a043172f9b7da57efe7e18f9aa0ff69d14e4b0b53e241847474747617874046b02bf7ad81b9e44f184124f27510c43f12486a853783a8911024c9fc2500c5f0ce90f19f4ea819a42e914d8e4a194f2f0f0f0743749e256a8b5bb918282b0535048eac51792f3a817aba5322ab0bff831f15481532b191a6caa6451609348fd7e337c1210108623913aa64084aec93d7a80943d814df28673643328c543076c0f407f5a4cf88534196303113b6c11a28992b279020d2c5f14a17173532e7122c50a59ecc26481a3c502d058a306315cdcb001a2f4a74b41404ee09bf70e34702b2ddd8ac0b65deebb37d999bc89a18398d0ea244a155114cfaa02655579534fdfb9e01f7618560d6a687a487263f321ac8de44266cd922d15dddda9fe9ac585288e0b2c6b7010d8ec1bcdbd858ada12d9c553dfdc75e33ccf9309cdb44c1aa32e4c6598c8c866339581224b367b4deb7a770a6b1717a2659eb0d1324cb8ec5deb0fa92d649a934fbcc8c9d39bc450967f78772ec8418cb71be21db32e2d85a7d3e9a6638beef0cdd64d8dd4c97b653ed4348f22c5510a4a250910233746894aa5526392b6c2841a7b380f1faa4dbbb7ae7a38e91e5020ff18fdf1afaf520c4a7f287da571afb50ed5c435901cf533a0503d6ec0344573b88aab4381728eec4fa4c808d4a5a26832a5826e616d7710438f2c5b01b93ab234401f406449b793e7d5ea79d56bdd90fe5c235bcf46fa16265b6c1d80ba184059ee819946b9e7d96ce5163672ffc8cda0974125846188c9fe5c05e7354ed227ea7fa90ea0022c731c17b36cde06080962e4880914c84b70726606046f7777ea823ead13d574da38e77922352ae743af2254c37ed6abca26ca939c3c4f0ae3c93ab9dd7895573b1377e251a8ef4c400b9c1d31e06fec22b0d96edcb85057af9eb305f59d824097a8318992d29fd070d36653b0f918c482c0efad1708822f053b13cfdd0b7f29f8948dd8ea4536e2d9f4b3e90d6e386e9c0c9201876fb69bef87cc6f50f9beef7b29f87aa91f37a660d34f307543066cfa596b8e68250617bcc867a7d1cf225aaf27bdb635e7fdc4a18568932af4e74c280cb4d9bee93a64b7e231f82905a73cf7b37ad1cc497fe22c7fca4471595457a6d4d1cf15e0f04d3f67a0b5f6d67a53d75efa13d29f5301729fa777f28821426aa2eab23667736dad7b9ee779f42f407336e7830caa9ae5ff39b2674433609a236ac2a0fdaecada1e3dd7cb9efa6155760cc1bbab0f851edff892f51022cf06c1795eed762f58e644b95c2e970bca116da9bf1a3be66a0faed22b0c4c1bc87eadd547754649c32490a5a5251e1e1e1ed007c80f1557cfe0704182e07038080e57df445113280ef7010d1724280c9c85580892cae6e3821861f36334e0557defeb2acc1f68ff1beb7b407aece8a30427f38e33708c16b382bf5aeb791eee7403bdc9f22da343467ffc83ccb8d55a6f32ec4f481e175f0ab6d9e4c93c9ee7595b5f0af6282ca74f01ec6e4bb6249acfa411ea796946e70c894714f83c45b73b13d05214441ae99c5a628497177ed059f1858c1444000c1423904002892e9a28971cb94903a78718c0aca04dd9b3e484142ea039428d1037a860b3cf20d5e824c9dc69871a1677777724aa126b90aa52e1d3450053136e66a5127f41052aa5f8497a90b4944a74be94e2e8e5bea9ca2c605c0c067c1fccc00a361b4b9093abef89cc04e4fe5a24883686d1f53cef35fa9039098e3d76d8403424c810b5965afbb910b02b920429f7a8342db289ca7eda85d1944daa0bc34cbe71b6276486ae7994b5d63280aec9b8204be8881665bf2f0194e57f7bb8b6e01ee05077f7bdf7aa545f96ffca88b1efe9f0017f362b1601b480cd8a25fb7feaff1b4d56766f340f90dd8ea607d99f52caf2ee55ddefc130bc7dbbafc74578de38fd41f966df795617d6e101075fe1d636b9105d23067563cb50afae9db74cd92d1a3192d6d894ece9f7afd1393b4f0a9b754c749d3755b409f65e8c7551e1e47235a7dbe98c6eb24973dcca99aef0353af79c91777196bf57a16694b2139184e47d7bdfe94655b27f3d6a7280973b23156cc2ce770a02b6dc199328297776c6eff49a3c389e9beff4dce4effcceeffcceeffcceeffccef0d4f1d4180ebca7fffd908e7d234f03790623fb9b01880d094f4fff4fa757791aef063e58c0409cb4160c52024fc77e50207f1172f038a3f46afbafa269d0578faa6aa48260e500fdf1ffbe4a4d1a075a0535da0c51fa412916340ada846e88d8c2cc5a6b47d9ab9ca4f48768554e52ead4d54e662166029badcbbad6b54ee6e410aa73d2c5e8990747605207129639d9dfe7d96e6b4d9ed9ec0446b45f6a255bf55e8c55aabfd97ad96a3131911e94fd1b299fb8b3f87ddf23f1be8eed4c204b96fc7d9036b81f14cd2db35b26e938a5cc79f4a7e08348f80d387d8bdf1747e69f08e05f93085dca9fcc4fff51728bf8e205c5950a5efa8b8a8a66af52fc19598a5f345395e2cf6e297e51110bb76ca2d3749eaab20908e73c4bf18b5820cb26b50567297e6dcb369bad6d17acaaea3ac104286c361e1b743a9d4ea7d3e9743a9d4ea7fb4b5e1c5975c94fa7d3e974ba7b2f8bba3a0aca722c6e9a56086970d07d9e0b5d307cab44eb06b24aeb3e53ca248d548905dfd1939c08fad34342b6e391cedfe836476a33a2bc2a3349231c5b57595cc8ec1e67f3d9b4ee1de7375fea1be80782a04ea7a325030f947091cedbff8c8a6e093929940e51757580b2facf60413f0c8ffabe530614e6ad9c566abc517b519847d5ca697009db9737bb2143aa0b0765f9e3c02123832fb8145b43024161694d185e30f450e0edae857f12ad154f635f3455eccab8dd6eb7dbed766bf9ed76bb5dd55d22bba8be493a19f4c7dfb6b555007eabd5d6f62532d664264aee69babb9b0c0aab96e2d634712158f67f42e3a146565147437d6c5357da8104f6a55b17f85629cc56d9620b366ccc30e346a7e8db6d7423314165a81215d9df6badd66b9d314e21088267ad94e55f7120ea14079b9689a9babe1204411014751c575375019d2c45c155b08a087e7d101cdde6471da881ed683ae579f71e3c29ec051e81367ce3799ebafca39d5e068be36cbccc6bf6076b9e03835ececb8c703ec2383e47abba3ae72c7fddce6f153cc1139c75ec890bd9cf19f1088e660bb445e1dff75616d740fe3956f65ccdb2a5993a4e4b32c9a3ec353baeb952a7541afd795267f5e459b9aeb2fc0a67793d473f02cfea0a0206c1a1f123263fb231facd8db209de6458b261c3868d11fcc4e0ef03a7f8401004c1133ccfec20789e4eec369a049161b3d9acb5599bb591ad02f6b269c1d86c960014f60385f5a3510210ed2a4246c579914590ca92c26c1b4ea29dc8fe423960b36dd816ebf2448d96da59dabcdf390057409c1c91d66093ee38c0827de070d65aebee5f4753853a83f4c44110042b8d8de0e60f360295f5ddea080c007095875058b515ccf78708dd804d9aeb40d8ff4119a8bfa9888c140e75f37ddf0647e00db290d37724095165e9f2a9081099931db40013a1e02cff1e1deb00353fc823111f406434a7eaeefebe0ffc7c52b37bbbb77bbbb77bbb372299f7f77d2b331604fea8b5161ce132c96be07bbfeffbbeaf7ed5e7263bb5c8699104fef26bf0c3165a705aa6e8c287d2b550214c181ac0ac61a54ca3a8056cb870534599334a326f6c4038a981862f4d4affa639b2c0e67b5970676200efbd97f4f95a9e19d59ff0f0f0601e1cd4a58190c75aeb79ee3c14e6d6831bee7714d0e01e41ea33bff910d97de0e25ff20e5ecba1b9102121c5b1c9d694081b6493076719fdb10f044978c7169abc4059eea71bb91457a1c96d576a467e1a2169aa2d0465f98bb965d0a83a298715d8f4d3cff374f05c720e31c31632d2ec40059512852c496b9cecc46852a6741c5892988ecc9c5181ae04365c86d021072861be94ada033c5c53fbd44b2210d3c2128d8ec9dd946650d37e5c826cdfd28b1e0d6b518465ddb35d19fdd0e776a1287528a31aeaaffa521408054172d31a618ab9610e0af16262f75b5d092dc2f1a9030d5006fec19a1dfa3e525b9f6f92456753d6946e7ccf33c4f7442ac3efeaa1d17e5d3d9bb281f1c3b563aa7aea7b74d7f1a2443bc50aad3eec59866927567c7fe92d2f4daf5a36a94d35dff7ea750ff8e66f8df8bd4c71bfcd927c3d40fef711aec81c66553892da7d01fe232f8a6125b0e5170e393f408d9791bbf33aeb0a4e4791bcfe33b6fa35096bff8e6abe9a23a25428f66e36eac92a0c00a1aca9437dea37953288c4661628f101b3c6fe39794385ee63bab1e213bafe3758c4974883cab9a5b555d65ad7a84e4789ecf31d65ccf7d9ecff13a563d4254afe35563d531f6dccf31da19adb2ee688297381ec7589b464bf39ce57f2fc62a55686d280b059b366773d5656d3797b2398f05d8b436efe2d1bc1ecd96337a345bcada524ea3629c668af9714759ddb9b1124119598c4a1b2b5aa256467ad52402cd46eedbf888342edb9f029b64145cb2fdd305dff468d70b575e14fa732f48ea701d6916e5a447f3683a8ecfd8bed86c365babda5cf55eda9e883cbc6093ee28a5b4d401d34c349ba98870172dcdf4dbd48f1e2a6bd8a44ca9120bb685756c2efdfabecf6613733b44419778c86285943656d6e04176861261b8b88196c3130b854643a2f4fb3e9ac5b5e8f4a6b5345ac7ae513e8b320bd86cda8bdeaad0a51be8193847a1b234d8a44c27ed8eb4972c0c9c8115ec1fbe7def668fd2d154a556af6635eb5545008f7819b4e17bea47f8a72da2380e398b299f56de434d63aa1dd1578c0a79d61b4ad2450e4e9ff7dedbeede0ab2b41d1bc4554ece3860cfeeeeb40b05d872e8a254024a7145797f8ceb54d2bfaf1e3c825c41f4c73fcf60628cf1f781df0782df077ee0a53f21fd09c238f731f10453813b9b3c3cdf4705e669229454a20d0c857d1fab6a3a56dfd559dc75852b79edeb2a415c90343559fb1e15ea393dcde11bf1ee83dfd7b7560cc2822feaae4e50028ae443da0104eea4b6750da1a7fed736fa531f0bec5f5de106dae1058f4f05b6426cadd6d66a2d18fae3968a1e690309e9a181fcbb8727be8779bd448fe9306d6b9b2d8a1326dd43c7c2ec8f7d10916cdcd0812347ab4592189f4455f537d31c3878de7cd5a8e3de1c18e350a978fe6f8c36c6962873a22154015560ef531fbe793fc8a9324c05a14ca834cef704b574666604004000b3140000200c0a0643e18060442a1d0e327d14000c66824080663c1848834116e340c620628c71c6000000404466486a1c0419831144d24793ca8404357a5459bfe046e69a9c7c852d31b21b3eedc8c43ce80eaa0ffaf365464fc16e821be7f22e763531d40e94f54ffeac0a612078e2505d045804018ab840de94f1d12dae2955499fbaf1f2e4a14298c2ea0b1871ee4a1bb794ab823fe2177c4195d4444c3102c10a24f1d8bcaa7eb4e2ccd1850fc82fbf713d0d54393ed01474e3589b3b90ae7d909d67cf073db5e483b48d45890b8c253985c39939add8fbcc7de77e6b8554c89077e0b8f305b9bc37fb1bb4eef84b1ae9f4446090fd7b691b3bb589afbd763e50e607a254baa29e018f482bf25ece1d99931891acc1a2ad4859d5273cc7b13c96779f7c15942ed755f64d07f0aa7355ceb95ac1ec882e331277e176353f9d9cd9247409d0211312a2fadae1a343fe7745daaa97d74274a90481bfd2169ef2474200c14a020571d14f633b88524940946611a4ac987cb05a831d963a3723b25d6ef8735a906766440b8fdbb2bb0fad00444d3dd776203e5b2d833350cb5017799e585833ef2cf1617905562b951738ca1dea8a24ade3dc255bcf9705c4401fccc55448bca03d9aa1d3d1812767500a4603e0dce7190b1bc2af38a09d15f8aa91fa6f7dc622eaf38c0402baaeb9c8e3c9c977780c8b782907fcd1730cf59411b4a63fdcd7fda880eaeba3be3b8375be4d50e20d4d6bd6d5b84979aa6c05804847975ad3c917b2c9056bac91be86729ca964149e052b0fcef895ac095646ea8f796396c75b09cadcd06755f5aff9a129d26b0779bd52241623c25e296485c5604dbddc292a3a8e40d9f5e5645e72ab64fc462f966248e2ebd4bf9189a2496364f1e1eafa57f5b7c338165c59ffb2ab508716e6ec26889482e3f43ee62036147751610cfb28727a1f0498051033d202c9129716ef7300e78424bca85882dce1587ba014ddfbc6c2b052efff0ce00eb6fc21d5cf043d950d7f1ca7f3bffbc03525aef273c0e6101fd881ee320d373053e93b5bdc207a66fabc92a9c53e6dc79ebbcf77560579ab3a0d22651b0984050d38a3dcc2a775e4a5042d6c4a21dca73016096f506f125a3c7d077d1c30dabb0001d5fc7d679e80893356744e8d30307c9c219dfd9f292926194828f4a08d4eaa40901142042c004f3de133cbf047dd1b78bf9ec2438651cd5d10d8005e72c8eae75e2d89eeb9c33aa7dfeba8afb3cd624f000caa800db42787d0178f96f39a957411c35bc94e94a649a6c8ee5623a668a4708d032c98b65700257866b4772cc0acca9b6495e3923342dc492e64e8619945a4fc8724830cc60039b1da715887190d889f0b93a4a2242a60409dc8fb2d7eb20913aba445da8366e3968cf3d066f2d7a9ce35c5e1280a2c21ae69b1c639a8f7834b64375c18cb454fa3ae9734a046b9aa02a1a8cfc3084ad34def01a877d000012587d13ee7fa3d664f589b0cf2eb186be129a36cd7d0365ad043542bd9e3f6004caa55e5c3e71e26882baf687d34cdc48d91bb2170db7034c924a7303442ee4acc4c905ab511eb19b8bcb3c323d9128060101292263c4c536711bac10f5213cc024274e65378e21757650034456e7905ac54e6b5979acff01ef3124ce27bd8924ec6a0142cde468525814940ffa0e513da4461ddd79445679dac9505a9279a17cb4f5d5690baf84b4e006dac65e23e90d116e83cbb518759bc1144498e4e5b7eeeba16498f6ab45c72de2a400755b8ef51082807396c363a21716601120681a806b68b08d1b392e3245f1ee034db6941f22bfe791fe599eb9bbba9f9e568cc46732480f1405f1efd5811b382920a7dd1d2178988404cfb4a95bedd7f5227b221ccd2cb632e0eb4a132523f3bd343efa6deab2e44e1936d610b8deb54f5c1a01a3d5fe0b2024643cc6563b6199bbc015fc0729325c03c87cafcef3658847a58e1d8648b9901a127aa8b4ed8dfd882fa211d799dd993743ce6ab1d3e38eeda2651456c8f88b40084b41072befa8542dcfdb08de677c214a86c78151ed725475e61f8426701573c024ecff945d959d98a018e303b9c751c24a66a83edbd3624fe1b8074b2037997ea0dcbfc9c67f5732a436b3887fc9e02582a75b20a7f855bfde897ed3c30dd9f2af17af3ba20aadb1bb31374a8827acfcbf15bcfa9feaf380a376c08ba118034602fdab30673657da55341278c85ab793885d784a0911d00079971892d883596a2cc3218191d8f8a4402f8964d6633f69459a8d817e18f5b36d1f0518f95d09120997b50bc79e441f2eeab1e67d47d9ad319d83041c7c1b62f386ea5de28d1f8685c098474c0d959ebd30c86cd04d0915b51a51af2b721ff0695e2c05b36118670dce50bfcccfc0f3242832ad02b07b39484c77040a9c88923fe96432ce8ee30abcdd5e28fef0bdce4d425b3b8262e181870bc0ee0ffa25998a292f945f006cf049b1065dc2dc8f4b2dce04c9378989551284e1ee4935e163993537a6b486e13defb8f4f5df3a09f6531b542b253a5b04dd6435432d1077e0da01ae18f0c863a19dc0c996b439d5cf1af9ba18926fac220dd88cd9efd5a474b4ffa3b220c2c6d48de5294ecda5a604f4014c116f61e8a4bfb305dbc9180e6413cf9171592a32a59905380b720c2b3a20fca36de2af4fe81c2b6be740fe1706e95964e95ae49a0be833715b20b18f5f3e75367d59c112fb40d7453b18cf78b01a374957b9f83697499fe219dd9463189c01965e05827c6126a45c5d2e2d96518b66afcd53b8fdb3c03864e3dbe7d42fe92d281d87b37cafde3137538d420298728b4b24737485864b94abaec77d70c24816eb00898591535cfd79a73fccfbc99a1b62f6a83c32aea8df5cfdb588210f98963468bf36a600c7fd9b24816fb9b5df2b5ca0f8151c1519969f170cfbafb47fcaddd8344bf20533a770021df6aac70a26499270e119e078626e0c0ca7c5e5f9bbe125bce5b51e07a801c80b99eaef9f81b70e637c2e2fe53941280139700ad053b8180d04a95eaf3935ffa08aa8d44783cd6026394aff5b25ad55b7134c81ae76b0af19bda35b232259ce3e21a3fdd7cb1acfa36c4a692b9fdb46babe2c4d67759c8592167a23d64801938953f2429cc0613e70dcd8b77b9fd1c85a4d2356bdc628635c7b02ec7ceac46e35f541816de412dc198d5d23b4c0286a445969d37c161a3098866adfc4e76f5a1ecb42203ba1932644f68edd9faa92ca498fd4626828dd1fe9767c8b6b178e00a3f0c8ea941dc716e3f82baf94dd1b2c05a42c9b9498600fa9adf1de5c02e6502ca5bf30e55319676e5bba7decdfec9585d8da5dadddcf8c0a943f94f6efc4bda7d8464708e12d2b1617dea20f6d0127136281250f66090f0e7a51a5f223e697d1d4f2bd606dbb047e610ad18c117794577f47153b28c9545ebf3f22f0c435ed59af972d8ab820afa1dee333f07f91aa80ad790bf5d81cf41af0c1971b9a022fb8b125a7349b2296000cd841c5569ce3f4feb60ad1cdac850490463868cfac9a8264225e9bd15d77d85a406d1e964790a2ca6a3c5858b0ebd76af007a1833e08db26d2d679a9283991fb22dace02b80d6adb73b63636eed33fb574bdd75616e8fcedfeddbe1982f3389e2f82bdfd29eb14f01032018c5001154b6dbd30e79594b03a170f98ca76c5365dbf92d801b2e207a26fbea60439d1709cab442e2e212c2e5a9d2bfb5c7861d06309362664c4bdbfb9b052334519ed87e3b50db6d8ee9938f34b4f08adc8a9d162da7f28b1371e85d6975d6b305fd520f95b71fa96238f3726ff0bc0ef53245f54896b89b8f18ba7644e7f5402539e06f28b2044995881eaff107328a40a06dbb1524f83a59a4ba34b82ee47321b0ad4f1cbfb809b6b29a841f2b3be1ce2084244ccd6458d03b4fbefc9594a83fac89b07106d81879f88a0d66e6380a5153f5f52392e2c47d5b364a3cb76f0068678db4bfb6ad8eba0c15b50dcfeea6c4a3093440fc22bb8b8876c245aedb963dab841278418e87e06e5f1b6ec139303d1699db3de8beb6d501deda4155822688f118c181c4d47ca3c2feb1693cb60fc2809d1a3df0a8273ab9744b353798da797b5d9d2971aae90c659243256aea0756ca2142dc271d6842765284acb5d75384d7fbdfd2e8abb535dd79ebcefd5fdf52b9b155e088830f71169dcc233a9135551f05f5d46954af602dccc77c31ac4958b1bc6352c0dbf828cc6a5e67d10229d05a78e49efe3e52a0f7a835c6816cbb44a33e12e4402c602c0585c594049477bee4dc076a45acf68b08960f100e6289bb00ca827d0a74ee588cda29ee0af4740c7792d5fede098e65403e692bba153ec8b82be95fb11c230c5e85fd699ad88f1a6b87a0da3ec22c82b337d831fb4bf78122d775e27959f2a9c91b684cfd689dc7e47332d4f4f9cb14939746701c6cc30c815843741a0421f71b121d9876cd15701ebdb5dccea45901b4d8a7b7c8cb6634e4e1bb71e5fb4941aeddb9fad264d09a7fb060abde9f9b41742bb559f8ffe0c268d446322af50ffa8d2ac3ef4a0281a9a92b8401225c2f62f45881c2e23ea97f0dee1697b26d87cdd35c198bfaae8d67a4e44c4a862906bdcf9e1e89d593bc9af3c115d1e5ecaa38b20c3d11fcc5eaf73a86d9585ee285518848232b3319b021e69022f905da55d679480da81942137941087bb3f51a3b62028586ec15f8e333ca3cd9d80124c3f06994dc448d52dc35ca4f6c945d764c1c28ddacf1ae4275a00238d908a80e680edf68f05e2ea04bb17b8c92273c5c4111d1a642420c7ce5b6a8c6b00f54d3f028b167f5b57f3f09bdcabb1505fe1b7441c659ed6721db939ef2037625999b05443675aa7a67a7efee81ae89591d5ff51bd9f44bd468348a3f1fac62cb50c3666cc6b12b81407400d72c5722efbc120106a34e1fb1869fda6ff0f14f62decf0b500b63cbf708a1189431574595124564deee81c3d956c16c68cd86b7840169cc86a3306be8359c85af8d837d0c3f39a584425dabf7befad366e4f91281c6bbde027395744f5918211e4bd5a05994a1aef5d9b6762493db9f970b7cc23c370412ee256310a889baf645ca1dc9773245e4820c91c861dff253704294f6a56fac30b1d8be8a2898d84376f6422d2aab2e1364462d3c28e309227202dfa23e186f24a387fee5625ecbb52f9cdd2fb79f41d145cfaf3fd99ced52f90aa29347a33df5ea4c00e4213e6104502dd6fe0749ab4069dc407d3e3bf4d65682e4920d1431be48cc421c4cbf7237e3ec8e0e6e682cb8c8f2a824ca1a2d635757ce96b2d1c544f65b6df5f8ba092eb0086b94dc10fee90dbfa879b2eb80f72adaa791bc7c5d10225b35acc0e56bdf7f65df0edd03facf9eb91761aacff51636c269baf659ad81ae525ea2bc9537078b0d310a4710a877c7e7708d30a878e637e039cf4c481209af290a87959e3c6e1690ff3b43c0d1bb767accbb3557c0305869844316a4ebc4b59f46cfa6ccb389ca39d1a71015864a9e7d95bfeca0e10f223932c7a851f0b7a4cd1dbeca8c23ae677318e2fd85d5471b09760208af41f954e2a4b61ab92eaa53667cb97003adef9a77ad061590ebcdf0da99c620fa28eb810b25d636980b4b4356258feb3a5884137298438c838a995685277babbcb7081fa157e40e7a3399a44e97e3eab56a459a4adafb9e3e25db73992320fc993b48d1e1ea0dc8dff24b60fd5395256c3934a45451811730ee1cb193e3b3684493de18425709feb00c3c6a0fef86a008be018bb5f3d4dc29cfecdd0fdbbd2cce15130f90d8968b4690517c6e75426cce81f7b1887f826d24121fd1da49b588e27e5e98ab21c7067c5380680e88c6fe0027084259b37cea8e22660074e442f3947321708c4501e8794a58c7fe4e661502914fc3f56c6ccf8bb18b07c60b60625d91345b17ce1e02981277d449aba0630f9a91d0ec1a03be282c1b0f0b7c7198a94b0fa4f8fc39624adde0c05f430a8012c25e1000d090aa2470b1b39e83cfbd352359789cca62bd41044efa05feb307e308ba19d49b5a8be8c22883ce86c5c8c60d6387e3295764c3403c0ec39f6d4c109562b856827c202b245685c5594f134b0b29595e632842100c7dd80345cd274e386c93b6eb43a56c7c31663ab08d1417a3cffc705be86bbad6d1186b042d2162d72e7cf0903631f6daa3eb33db5f43e5a92a63e74c9e802fafdea091a2e7f895ee159abced89e0420b114608a08a755003060ee4fa82a872d42a217d949281026ca5a0557a8efd6dd21ea902fd2d401d8534b4fb406f8e4a2f21d403e44e37dd894c5c88134481b606724489de333fd0d626566f94b31dfa944ec0fb822a871d128c05a1d8a375dcc64b6ee223b91219a31d5ff642684c2e0a129f9e552f9fcd2fc45fd7a9d0d820902d2813c41a082347900a8617d4c754d0e4c82598c9830c9556ee010b2acc5973edabc94554c1e1f65cde725df162ae23de6e5dda0100a5085f24071cf424463acc6dabee0d1114d0f5b3cefb79a6376fd6d5b22ed91d8dbe9c86a740896f9163588fa240cc93af772e56d30ce570e65c5274c57260dd503c24a816e6d1e5363687bccae1291ad13a09c529a28cc5b71ee17a8bbe67206efca4c955f76b4f07736376998cafd0960b87005bca886908fac5c13d4f93119bf133242287dc7225effcc0fd1bb9686aa5d408462742abaad4c0764392a8273ff19603e35d0e7b9811d9dbe5f8e7a9d08d4866026e95ca02bfc73da94402e1858aba889e20897a7808a219c74778f34dca5645021759a4fc63718afb3447fef55dd512540ddf461a49b328689e15b1084a43aeeb9e34b05485649d1021ba9321ce951e3927811a55d863520d9b2a5b79a6d6135a71f561176efd9e5344bee8d4ffae0970b18fc8dc8738e3aa517bb27b531d3c6d15288e90adbe300dc38c7c70ace7ec825c4f8c462e956ed2fc2a1c2345a91b842fec5f0a181e933ac612090b9cf43e265c85853400173a4a4d06424bb5fdf8661fb02ed26298736c90e5ab51dfa77ce1206b502831e83e6d58cdfbb883e81431b75ad1cbb90c08b42b35dcc6be147bce7064b7cffa56aa8711b169affd9096116f242f2e9f13e38cb2d51552d4663296879c417b07356ab22561266651f54a659cc79730dc7c669bf392383fb7633f204a83ff496acd68013bed7f3529e2aba7f9e4909db77d3110c5764ac12ea1cb65099fef3ee4600ecf9d21222c1cfc7c2fc1ccd2481bcd6024742d60c50ec1f876230f0366cd949a5f859b32556f7c991facdad9c500b7f3ef09c03bc580203c7615304649d1e1d1146e921a0fd75a47ae191164211716229fe75e977b2210d6eef2964fc55583b06bab792d36418e4e666c28b9d70f30f7e7f4545a68e235f6a12b2f076408310568b660f2e63ea846f0a67c414de9149aab808a3810fe5577827eb6941852b48dc14b203e83b1f4e48a5b682e8b49139517746cd3d843eb25a845c2c198104ae6ec19d9cecf3a0bef76c5861210e90206d43331404984788a610c496043ced8addbb090f2ef53d9850e1ceba4f24cd0cec3003d8433895e2d340568d91c09818685ec53f653b5467d87d8b6baa57a240600fe8bc000d56c5bee6f86f729431ac124f0c7489cc25e5fbf44ce4627133e624ca10a75625bac846f10638961700cfd37c7897505cb9fc7365a929a534fd5323ac82b054d58e21e01043a1c0f2a40488da79706d3ec994c9495864b5ffb4014ca723224216ec0055ed06da29096b6ccdee24713ddc233f531a590ee929989a55e38fcfba000f93221549717709fbdf43618f1afbdea16a889040df4786800a3dcb84ed06978c72294c69e19d97e877ef09a81b5ebb8aa3ca20507ebaa12f4cce06af36259c91e5fd53d35547154737232b3a6d132cbd4304a065b9bd9a9587cb5b7661c45afe264dcd3a4f784e89a0a8cb5b8c47cc70660cba150ca0c8509a4be2cc500d460c98fd2fb2fb99ddd667684ed3eea19022fea6f76eaed49915436a8352bc8fef3f0cf1ad5e567a6fc8e003b66dd33e96772d28be6ad23cb59c97f8959148255cdf437e4d1dee05983875efecd035137f2b7c11bfabea3aca60098e16f001870eb54baf3621f4aef1cd40f67941febadd88245a8b0e597b9cb1c146a47be01a4ec8f8e4a263c14da58fa10be63cb344ba4bab69fb2f3873cdf568ffe4d4c926ea0aab891c83245cf44006c5b281694ce653ebfb4df13c9e2f43454bcb9c2229981a12a0055d3cb9446b133f23f75f1c87be7b51b429e11eaf57b85bc27346e1916370a6255cd3a83da9e2e4a643fa003085606ae2a00b9b37fdb20b13efe0c07b472b7483b729d115c1b244408e1258d62ddde38a371cad291f1987101b270959f9fa4352890d6c296a4730594c5cd1d90948cc3e48f833e29d732e65ea3477d494f880636721bb29881f2850a9b88ed5fb57328c2749188c112303692c583c33f417496569219ce84e3cf9860d50a697db161645ca5d151a92c7260e51f22f9c4d7a111e254091092258857aa6c3d0451883a4192586534a7e6dff636ce4bd9e93a3b9b3e04bbb9a5811f17db6dc5996e3104dfd53b6a761255f71c1702f4245dc285b7ebfcad7758fb4e2924a24c554353490fc22929fb9f5a53a2d458611fd7406c835007b273861dabfc11a5bdd51dc816e5dbf405d72b93aa768fec8377d4d9b4356d7926b04f08df6a402f17626399118c799a61b7cbb439e2722c0a031c06794d591ce9e35d6120b73c2c243b85096e90cb521b1ea7438b954967c9916bdd96e25181886e1b14f5576178fa15728460cfb05f158dcefc40fbd782ee9c3ecb7dd4868373d3c79312c2ca0f5a05c03bbe427c412648ee9c7c376a2f4518f569187a2f81bd57fec610ca61b55092fc800f17dc4e39aaaa728bc43b2a431d441f7b1a5e06dd6144036be7440bd3d768c192d4c0d1e8ecc184087d713473b25f92efc598d742737751bdacd42fb2ac0ed01e31417bc6c51d533e6bba95fbe6454511043b0c171b3a34adead0e41bf90eea2165510a79ff34484c626f65e8c077702db89e7a9d18dee251687a098fe68fa8fd3889b679eb077f73783b6a2dec787429941d3b5316e055195b0ef13169048265443283d458fb8e890005b9ac18b269a165502190e64d1b3b795fb6d206382404043a46083cbdae7a1b6eac824252dedb0abc2984665681866270537c9c3d9f22f21e288a94f3ea23420498706e7cb2e85408cf50f0a5b1c94c1b0206f4e88c86812e23a65fff7ca37241ce532460347443f1f50a84cdf76d8c039fe80ee6ad6844170d17c62f0d854e07fa7e86386b59afe0170241574d12f3137501034536662223f5f1829b86607d63f63e5c4504223d5d3e37a6697480b10a3a023dd798c27c5d993e0da7517ae5526763d0d8d6375827a24ba50a2dd0117dc1f2da67bd8346d443aa9897722a5274b0ee150ecff2518bf0d740237772b32323381363f3034cbf3bf70275ec3a6e91c6c6e6d9797db65dc0e2f326ce8be0edd559237c6071474bb80757507a12aa46023e9bdf41f9e9f7e390c979d0e61d75922862fb1ce1cf0071b6e9d0c71b52fdac670d014281c5ad9b41934c4b021043a777f636e69dbc30281e8a89629d0d29fe5ce0d9e4a9531db0c638f3f55c69e2161b44974c3ba8a35be2ead4bc31b0d9a4580589f32b4a4addc8eccb1f5a76b3141298410200c873f01b0a12cc90163e09edaf369fa8d5201d927c88528423810c98d45aaaea647f5732d118c9ebfc9b82b2b3db9e49ac8cf6813be0af6105e5fb6db96d579989dab2b28cbf73d911127b6ce491fad741507998d2dcf01c6f9267769b58edc03390588facefc16aa51c83979c77cfef0bfae2082c4aad31b27ea03ca8b3e1fe94a5fee0b894d36d6a1de489394905e23c43d3a86c7a30c39a7733b4f3abe15e4f52309d218407380c20eead6e5f122a2edff72b54498bbd641bec591f353d6e1c40f30640486b38a738b58ca815922a68c56f376ad60d1c43d4e66397f6c1fd61bdc5869dca8837ababa57d87fc00715a2d935e8f5286057973ba7159d86c6f729cbd7a61a5a3842d705f3dd85b4bf74710492503e2e434971a56b7598470c54493a970123978c5158d9f773ddea2e46053efb82b6d17b1b3a6b85d8da27cec1a9bff62ffab2d7f621282d06e01f6cb00ed7c9133d594e62d8d151da0e7ddf779186292403c2c973434290c67188966d384f4c22934af96c23206b4587f904dd3b5eeac373926ca542c58195528bfe42487e32b401012a6ec6ec9c5074e48ff4f0e5b2f99c64e76b827d0a001657c4994bab39112278c50318fcf95c73d0260de4cd5e20008d0535a878828d0b1da93f504ae88a7bef1ea779942cb4862cec7be69d9e03500cbdd3d190b27414abfdf6ec8ffed1d85b438a81f1020b0343b39234452182eb9a8efb8f117f93145901f4ef655e5c5d396534bbbb320683226e45e25be0bcb32572c9fe3080f91322818af202c4bc1fcf47ac84fe424096bfd2c4d734164f344430ebec47435754d603eb79d8260bf106d3fdd0d06b6ac0ad9eaf2039090d8e2455d0b870519b1a326e8f37069e2b955b18c18e990b2f904e31a37f92ab9313adb97818858f9890de21001876ac980183cb8fd8c3bb05588c9dca9dc6c7a8aec90938c35ce314282b4511e62ef41fcbe38a83617f6373410d4d210ed5024b0dfa551ae3772ff75c36b7d02d8dcc5f0619bb25d6f00d3f236f69571f56dd59d5d5ac746d5b5457e0975227ece7d4c07ff385d9545f4e14f00f8ffaee07a9916808083dafa743d02f9844f0baecec3872d26b09f5ccd44516352ddf399b068b9d28c726ad3dc0f844418d570311ce8c3d7b6d6434c2c90ba4e369d831e314c54fa1770c9bb2f0f852286ed911a8b4552d6eff6e0f3f2b2170f9104ad0a8cbe5f8339a7725fb34ddf9935577781d21f5497121a3b1ba2281663c5474004528aeabd5a07e3ad9f904139298ac11a32a80e966678b0ce876c04785912b5557fa3163d4268473b899af4cbdf8daa056044389e9839ed385ad0c73cb4d74c4a3a6bbbbc84fb0595e669f101ee84d60338e81a2892fd0a304689b28784ee49ca2917f5f5353c51ad638803fd9b6399186c5bca085b08479af5f52d56959fac500170fe5ff29511476811c331a8f84b77a72d713d87d5f427e8ac57ec6af03b7a94db6a855f0f1e4133ca8a662548f39fd3ac9d7292f5bc3b610f44a176ef234e39fdd8999a972f4ec150dfc295bef9ea8590ccd190b88af54cb8da39d1cf810b0597eddecf48d65cde8050016ca3182dd69d887522eece16b516449aec3302f96d14e77964a2ffc2d8ff44346ffa0b00eea0a44e7af5a90025464255b0e1a88a7ef6005fd07db47ae42a44a6ae7aa27dd886a650d7e4921a56a5fd85e75078b80cf2c2b5825993827e7da463ad2bfcfcdb072deaf1c17e921bfb9e56ef55f85fa7d11d52a0b296c92857937d5d5ac2e91a644d954016fcdc5694f54956479d8419c9d097fb80e0fa27b5b4e17965005a082eb33f04685f8125b308a834555983e7c651104f85303b0c5d57fc41de3416546db77a91b29ec525ec44724d315b68996965f3aaef1c999da8a5654a18b87639e1d98320e6dd998282e13f930a71df4c2123b80cc3e6ba0d57dbb9d273ce784e43f39b8eed8906c528fce0ba0c0517fa31a8dd37a1587a766f4a4be41309c432b542e04c975cec5f30572ca3cb7d54895b2368595d528c5ec51301451a04dc332ce908342c86ce03949e1a6d728a19c421f2c5b60239e22b3ffd19b10bc61c3140a8c79a78d6c5e8b5e6d2faf18b6807853fe8a11aad0afd81b330194a5b10249a8aee4293ac0afd4cbcb5103a639003130f48e7c1698c2bb0d23ed5329940cd3eab1751a61a0a3c6fb5ba3c2975a22105f7c5827700d80d9c42e445658d10e3b83dc77651680ae8a161695977adc83064eaec07d2429e01ea29c971ff980e42ffa47d6671636599fe57c618b71a540ff286b91a7591f16b43633703c0652e7ad466a7a8b426190732893790199ab59514c5d35ac3e70457d86963b6d596525fe5e7660138a659eb1fda2fe4a62457ee5a2d78bb419f19527d7ce6596f1e7fb9d6dc5c2b326ccdc705c3bb7f38f64437f5aa6303b861dcf2396bdab5cbccac2596637cdc547fd555311a87f2c1cc5b925f8ee2351883185f73d4f9b49d80e48691a2b315a9504f8102dab1a009a7f0be44a60a83028d8ced0ad695c25ec4dba14a357a351ad5cc01aaf17e7af57196da57a8014c993a8520182e547731f030dec8a06e2e2afd0786abd2caa473550c51c570cddcdbf003438dc27e5c3e259551aa5cb686dc668f30e9b19e1a42b82f341aa722dd8a6f9644b28b0a25c5ebaf1ca3c0d7b31c9f9a728ae327cd3bd3e76057f8f77cd16d57edf8bb413d64c0f44ec79ab871e3d86c2d423d148317c57b5a5bf042468186150b1824611dd925bcd2e920fe56b7e48f4dbd5b38008feeeaac2086f2dea734f6d707a73cd0e627811962040df55f030f4c33ca90d5748786ef0cf55ab4b196335a36946cc5d0c8004da5b86b55d0e7ee0ce2311c8cb6a471cc545c7c3567977ec0fb6ffd055aa803fe6798b418f225b052e94789bbf17c4277372d493f8241be34a1766333c0799fb6517a509b9b713b31a5510d6cd70865b0d591e01def53f5b94166a9c64a9d53905495a186dd035a6d75fd0617558274c1e1e8b68129cca22f7f2d9fcf0c56c8d2a697c54308ce8535327b4c944361f15b8869b32a0ba9ce6fafbc2f592a3a2f06b428f6e3dedbe931a641c90deb952c14c6cfe6ebaa31ca86c12820b4891c270810541138c65204f63d5b3821206a12296617d7a689436f5017827afa2c62a54cd05726c1d3349f1c99d2bbfa9a6a2967059a6af7aa81c7b488d15d5897d53023c24a1ec16a7cf116581588be703f680e2ec078171c64bcf9c1068f1bb2043d1ce831baa1f38cdd784f6fb798a20d3c724674843feae4e936da8b723cc103154f886c291740c266b4573a94e5fdf384e27f1bb270e0fcd27338dc8b7c381642dadf3d9212ae37faa3919d412d8cc37c6509a542ac52ed5b935e3a79f8977354e02196d8526d3fbf33637df27ad8b729d5daa1927bc7d3c951ea453daa425ad6d0b534f5add1a39e6c417f08cba9a37a4e304634c4797fad20f438ce002435395e90157483bd80dfcb4b493f95671cf3e2228ad826c4643ba734acc2d435c78ba9b4dc01dac3d5f634649ccb7124fb2832770d24b364034d9b1125909cb56cc3657a6c97083e6ed98d154765eb124d856af4ce9efca96489385ab74773974a89549d5ee073201edc53e48487bd5d22cb33cbee94af5c9e95b5327b5f6a14babd88839547c64375ca9087f79b5a117d300065d23b8d4a82bd60ff33fc532fb733620b0c22594dbcd99b2210bf92196d2b4abbfaed403f0acb26ff63a8bd50af994a25fa61a233d005ec102c21cc14733655b3a46c337cd2eeffba280e310d306a54a4b29a2afd22dae8a4ad455b3f615cb49aa0f52a5cd026ba8e02f4110e64d31d797e34be10b8e6f3cbec71ae5df44866ee8c94bdb026f87523bdbbbf25f9792ce12affad237a8c5fde7357f1b49d94940948d3173dd5e7bcb30e74d1a53845f11e61c859f94d022d001a6316df130d3dd9786ba78247e534ac469c345695a49bb3871d8d856bf25b08c2d8bb1376701ebb413641693eb66e9102c99931b6497822777e1d10eaba97c5b59cddcb9df21e5c8110267807bcc487a9e8aabb32878902a04184cd7868aec0f5a0c90080332ff1fcf76e7076e26d194fd7065829dadb07aed54aeccb99f2301db7b3a6acb310e95aa18dd8d2311b558e0a45c86aef1660777aea6d506050e89fe9444257fd19c46d68dde7be041220870f4573508f51d958c705424a82e7f4860d7b0cd101538341014446405524e538a0138dc8c8d3bd8e970e3958cee7ddeaa738300061bd0f69a0f7125bb074bbb2d6d5482cc511933ba18f39c2a41fb3002531a2d7275c9ec80b13494b92ec2b0650099261244cf1d3735d52779b881a433290af286c32f5f7f10f2e33e89dc04bc872ffc3c6259907eca1e5735528a26f46ec3f014366a7c296cf8374b7155f894b17ac314faa5b1cba1f1dcee1542a50ab9c645e8f1da7a8c79d3a9b4c64b6233951546699fb372f9cf461eca834a49fd7264fa1df9a14c2a10ff16c0809896e8066e955e6dab62aa34a87f63c6a7a29c7caf8a2306ecb0c8e2f8300aa3b8b36cf16922b1743358a541774c9f6e72adc975a5b596dcdaf0067628c3a9ddfb404ba788b65a0d0ca2aadccf41f6eeb2652577d483e2852d5596c59790e91f0a719f9a024984af3723b3ec51bd529be168416db6e5e90c16eed8e332edb863dedc67c83e3dc52bc939b8e2095bde854a297a8b29c7d4d3c5dc80a18e4541a5f69870fca63b194b245aca623747d806e6d198d634c321497179a3954a954756cf3dd068d8a69736b293e9d56222bb1b1d54e7e3c1c4b862bff919e0caa3c06d3a648fa44ac85b095ad3195a621ac4cd1b7424a8359114e3091cba556f7c42e2574cb0c4dac2192a37957eaad6bc6ce6c3d5b002bcae36fc3bbdeb531460169586be043b1fc1b046e5f995e76171c41f066785de7cd94ccafc7fac2d4b37168756a7424d5ba0bd0d395a830d8c167aa337bb1ce6c517596647cb491c7815d1629a0678176b777cdb656a70e3dcb6bd0daa8416717a5739a3ce88bce31078e28e004a3d016e4cb5be08d0721877addf076442fc5f8d5522941c68772205d4887796060b9a655248e04890790591e310fa329aca5c5aeb96d92abbb4202a38f3135d7e0fc383fe44a29bdcf30f39578e29768b9e81993e6067493008e46a019499d4b03350c48de699d4bb9fa0220cd82e2dba95ee043e77b6a97f559303b0bdbca078a888f3579c2a61d2a43247a5f0e69aa8a3cb9f7361d5febe6f56ecf6c4db43f9055780a8cfb5847ba5384a01789853f7c2d4aea0b7c74cfda4aca4ce931eca8211a89954941614f51c2f60753bcca8d5f92d89281aec293d0863c4833cea05820a59f9fcc027bd1bd029de16421a1d5f89573252103e32e544519ee39059dd20d25cc5b40ba6dcaa7a9136759508976af189758f0a0f34fa80efef0225f80ec93a2bd93051fb4dda136ad853a0ab58a29839aa40d50ea48d4a3fa8a2ea3e1f722ca983dba5e2f1c015e656f7fac3b6c870d3546776b2e90bf647a04e2c20625572c4c0d7ea55b8f7b43ed055777569f94d3ed0142c3792fd8fea36522370ce865819324bbb7435a9531711344c54a128e0cd40832c52a027a32ef35cfbcb0ee3e72fa3e7cbdc4a97e0df469c9fc351e1940946490e136ecc863a5e4bfa7112496212a22e23506e38cc400c8912c320fab1ff8056bee62dc86d01b8e63ebc5cf43ecb88b4e0a3cacd9d813069bc544a2513a53863d60c83cb78b9cec9420d5eadf848d47dedbecbc9dfe59d64e5d3cc6b8fc1733a7db37847987300245e99b98028b0f8bac593357ff294f5990ad02e0d32b0be80363aa991bcfa3eb71b778f8b28c906974e5fa94905dac5ed0ce465be814c4bab82416abed6e835d381454e1c1b378a2e8358350076d49d9096956763eabb513563df535384da0b934c7263bf46ae0d87bedb83e8194ea93711a5807aa4eccd90fdc41f15d520735d08b2641d56c89b0a8b98be9160a0c91a5f83c48fe322e7d6cd95befc620455df1773585aba4f502806d38f685e6ac75001f44caff0cc1871e36963c0941ba58565c1bfe6cbda458a0c834aed55e16f39e2c482dc416c9d3d86c3056a30df67695a4703d1223dc5249a7c5c37a018b0c900079e182491e0d16aab7edc59c287dba5c64ecc0272f04c4b9fcc84ba22f579cf4af898041c183f81487558f78689ea33bff73207f4bb681ffe2bacb1b74917ea3cb4a6e204831f2424f44359c350d5e47aa534f45fbe210ae63854dc31a0824e4bc7034c4cd55b8aeb6170acfc0117c94ef901dca8a58a5d404b8428d6ae88d4c86ed27d1556a14ce5214624fd6c795d9939cfa1fdd22067c47c2049bd1f709f159898d99a209222d1e510a4291b0dd5e508301e28ba4446409434ff1ab76b719d5ca6fa23d1fe2ab332538486186565e480dc9f89ce5c9ef6a32da2826d286b5402a0f5a5ff9f4556cd046f59dd3123623ba3179117af145f72595c58b3ee3016a6a72e8379761f1836939dd25fbad819e49a29b120bb6cf08f6ad872649b2dc2bbe77bd6175e810ff7f82e7495b520d5f8692c282d349b770815e282d06fb2d453d6b302fe9a1c7d59bec36935315c57938377d8c49f08511b10870f0cbd4036188068d810e3b9b116e711d2bef747d40d935716af14fd6b29d11711e5577c8831e5b5471ed8be9484bb0a4e5f6631eaebf2c763412c9ebf5f311e275faf8cf137e8afe86f34dcb7152e724ba3eea8020bb11626f043a1c1371f77c6604f0031a96d35332360b44a1b58544e9e0a96c46427227c08573967834b4afde8e38b3034868b84d6cccf5d5bcb04dcff3d155a92696720f255711c8af1c3a24c6926ffb2708abb242365020312cb921ddd65d8e20159641e1ae7a119d1d0dffc4f09846342ce24fafaa872ca0caef33b3f199091798462299e64a180a9df71cf7aa3eb695d17ff875b1e662f9917de52d617aa7d44710d57d813955bd568e60d6d32bcdf94e221ed33f62e8e12fec068daef4f7427f554a7f6d7abf20868aefb134d62820225436c86f4dff9d08cac17bb57db14d0e40169ee95d16132efece25655a65927d9c8bae353d7beafd71dee32cbd5d77d9a5de8f63ffc33114756b5cf69f1e0ead227ee3aa26b2c7524475e9097b6a6e277a44fbbc984dfea8c81ac0c6a463e19c322ceb814d37211d9fd4affeef4df6a3d505bd8fe9638614f799287690982521c9914c7526df676495d09350e481095d469642612ae7974f6314e071dde90d6cf73f7acc0a44aa7894ea4b78e9737fb803482b30c39b00dd6390e83f0e716c9dd1b9b7c1d59d65e92735b2d3c5a22696aedcd66035c8b8971ad5b635617e246fb2a5a4c4823b6792781bbc52ead826c469bbe785dba67e68dc4189085741995774bd24f004fcc206545d93ef39f8d15c1157a8a828d9ff11726f00764085ba16902b1111b6df628855174a773c93fd67c06f32306b9d6fdef6c305a0edbf39a41177b9550b49aeaab2d27c47a9ec63765c1282a772fd7f7b044d365d03e2852efba582a6954a14502bc38b333f2be3151cf5a8a7fa5930ddfc07685115dbd94613cb5d07ef7ebb4754bff6dfc5aefdb41fb595d86f4ee0feed635519b9b924e480bd251298f6b4990fd2057189deb6b8d3be7727711d733b2a35354d4dfba3d6834f49f4e6809784a4dff1864152b0ba3460af9d8c2095cc5101b86224cca15beeb833b82f04bef3a95dbb02aa21daa043d3ff90ba807320bc88331b3b610952416b6d1e9f4600a5127304b6a7c33c34f17d01a16b785ab63f4a4844242b410812854870b04f48156685bd0df8ad1804806c4f6702c6a2d40b2a6562a04786c85d2d769b15edab7ba9bb03ae4d5487ed2d7778a8f93a09ff357924ab9814c47262a598a6763fb4f0a53e6f4863ce7e791dcc89c5320e554db6a54a5618a4d8099656729ccc9c6a6184eabd6f393c8c40b7f88c03606a91ce5de290ea3983a6ea568fad55439d5af5089d64e5a18eb53ad41358292af3412e0861df1fa220704d7cbcb483347b4820f85606bd158be65d2c84130e8a3a6d3df87b60aefd208a9eb258066a4153b3014cbb6cb4a0ab7b281b379eaeee78973b79b3b88e8d9f063093322127a1fcf9110eb3842d1f4a289503c736623a1fc8d5d93808e85d9852a9709a060f6ff88bc0937b970934b8282e9cafce44a9e35c5499dc8ad888413ed4cb7f252abdcc68b1b2eeab1bd32e0b65a3fadacaf62bf41e77380536d4e3fe207dd14f2074e1723721c48be644c5c87bc40027813c12625e2fcf3ec009477ed79159f7503fb91df1a09dce125520306e17bd77e6de461ba964a7424cf4853fe511312d9205a32c7d715c8d1d71727ad9bd21c07435f0a71a017c29b61009bc9419831089ce3b0cb68afe7ef1965bae3b145ded5056984601cc3182bd16a54a035368381822346bb71482e5893342648690124219328804765f41127f8acca81650cd33477f28f1ea990e7156f853d75ab85419c4832526898f7b631d3904b2f4c7603790100246513e26bb71215ed8675985ce4a1c62342da192bedb133b4f6937aeb27a9e202a4373e8c96199eec9b50fe0ba7c18c1242c0ec8a569711a22701fad8ece18b58f06c890fcb29529e9cb249937ce729864fe1ceb5d6e54793e5a16128babd35fda3036f5d21bd0d74645e729d3d38fc22bc8ff158db4fcb73658f3deae0466e3f7e557e7d04fa354856d22e808812d1fbc38240947322ae4a5126c8138299cc520036e11d0f4de8db3df1093d8823354bc68e40ab6b9fcee3197717e8a9650518950fd62fca7d275d6c747fac16e1f858344e8af50c084549d8cedc5e00ef6875c7b34a17ca30f32d32b6cbd4a9a5828983fc61fa2d9bfcfe9696ddda70c4c2cf3fc387cef02397e6a78f192aa57b4369d7c2ae24e4aac37d76abc1c4caeac53ce390acdccffb9ae61b3198dc9ee5c628fc22a051701cd9eb4130f339171f1c05e7a94cc6d68b45d4ca9ac2ddd7fafbad206849ca2cb9cd802f72acb426b524953a6338fca2f928b0d6e3e7a26b48186df92681d648d7447c47bb5e0031fb841e537f963832481122af564a4f76c0038a903cbc08b2ab169627cda2545353d3348cfc7d15cdb050ea9cbdff76cd557a1c710ca54741a78f9b07ee0f873c2eed171193f625385853f36574bc5b4a2ad513d6775ac25c1c251d10ba0393430aa2b68091d24e227005d04e88eb7d4183016bdeb26605c9c9e0514bdafd7d69c950ee23d0a490709d45f6c7f61132058133c4aa024cf554083a38eb185bf9973e43aca41c5691755fa5cf11fde912fd9b251e6c7c5a43a1b5d1bf98e3485428849f441b5924410fdee859d297a0b36bd0d8519e479b7f31494d155901890b4b4549517c19b56a2704fc0fba5fbd13af0c855952a31c4beaad465cc7a00bdaa74ee2fa9fd042a687adb6ea92861ff4e59b1b4acfa78bac4164e61c8d1d19bea06f9302e84423e7292832702413e4388bac32feff821627ac2692509e8ee65e45faa797d155b09f8971b1b13edc5d6dec1705c1a425b44d3e2fa54fccbebfb5b7dc643503469e2adc96534e73959186141490a61f1f3bd13ece32419ce16331f2ded1c1ec7511f8f21100049661c93177c08167d48b65404d748504ba8e4e1c543133e6ba733e1b1bc1face2e12e0a47b094976a25af43e3f349301056d9e1fbbb0437a5dea2f28e8b07b47f3e6e064f61e04dcac6ab49035c40dfc1ec1dfcc3734dbaef1e82ff0fba95be75a8516cc22f1e7a89369ab32acda7168d31fb0e4a90d5e4af7a969e2d8fd5b712dcc3589486ae2e9852eb3b237adaa02ba583c38c7a865486b57325e182735a7c0a65a17b4814c42f2d0a79058fb7fa2f7e09526212b9b7459e625577c0e4d9c5cb4f64a60e5d056401e9e14cd330982cdad5f351a2d29899a73b1f8b4cc6e39d30dccb58a41d2d0672bb9ef0cc6b3bc38b198d3ec4fe671cba84796e0cff30c8562002714361c472b6b581c7d9c7acdc3426754a2a43762368f91c5e769b8e38558012d8a224171dd40a3b40cf0d963b06d1a8177021a8584543ba8029a14a39f648c95ddc59b13a95d27769043d78d2d5947a1cb0f46763ec0668f521726b7d2adb5b6644e14695a7f11bd0e1382d77c4498b169b28fae4fa14ea3a990ca397c65f5e959a0433d0f6a22522f603f96839d11b58a0405b90e1ae0532ca0e63db0e61b9af2e15900f0f6c4845358ad8dcf56534d12e2a0bd2258dcb83e4bc8e441a349aaa901ad9fc9282ba18fd289670cfa4bb326361a61f4d078cdf5ccf8d170c01e52832953a8a0c2a224db56d2a2428af55a25762b0490a6be5847b7be49f88e11512a62100b14b70f8644e014d6a4fab46615a88aaecee7ab29c61b118c5864b28ca9d844d85857bb25d595b06035ad5ccafd8641f583fbe6bdd91dbb7b4837044331b3f27f0a3b50b53bb74dfb7b18a38f1f65ed0bcafe7ed25dec7950927aecc1c268560a3f70863b4443b041820cfb236af40952f0fd7eca41641e6ad859f2badf2d13870654702270ec9b291cf615e3687880f73ef2abf1c46d193a970b0a15bad81d0a05831cc1b1495b533b3029d4521fc399a16b9a35ae92578473242ee0df9054f17070b45414c0e1bd2fcd77ac700f10a82aa9b7eaef9b0100f3137f43ef60e52d342f31cb3c0e9b51a5015a295cca355f158dbad766ee62938cde63f73230d888dff6d19bc48c780eeac17ad5082987cd74e24290b1b4c1d400f6a0f1bfd39be590d80b719a2c637785789f2f7321d8e87635e63fe46d773ad961554276932bc2bfd1c24a2a0ae52da0660801ed24df8af187be53799173d3872af583d37a6cd577a6e3c3b97872efd05080a162b9836fd32461f8bb9a38f0c4428a3bfffb3362247f98cf35919f73932900f074126f1935282b0d53ffc54f56ae7f9eff68d8b80fbeca9d9fcaa6f88c1f8c6ce3a26b94a8101944361667346b8917cf96ca412e35a2b1a2a4c756e60813098291a97b2aeec25ef3bff377d747a97fb28ed68950a65b312bd3fdd2eda2d09c12a04d7a01ce70edc5c08eaa8ef6136651d63f83a923a8a05b92e21773aa765f07a9d43a1bc4acd1ce5b3d759feeb6175716678f69ef1edd2a7de8128bce715601d798e77400957e01e97dba187572fbf1a8e784175057b39c1fef9b02c6817c847e015ef4d468327e5c2614460f91a112f4d1a0f218bfe240c693616d7b0732529ac17f0682ebb8eb12bd105db8766462f805c22e992c050091de41c92c5aefc90fa0809699c81ec992b3b6a1e7270c4ae6a0f6277c8076db203b998f7b3b5587d910c7c853ef7061b6ca8b8197386053602e9c0e4a4ac00b261fb0ddb5fe0b9cc800d005e4d76858003556d98f81d90cf464f5f0584f43e839ead7644b65a81675e322868d4da5baa9cd64876886de1c874901e09c23f2608c33a4c4181f6493a57f26de92a201c4603b25a70a4de0b0149368fb6b770c599ccf5edf0f5ef04b3e011967b61bc8f51ea4f6fb8fb68b4af0770644486527d7790c572fabd11320607fb35202dd09187ee7fa8129d3051b56c696ead4ff5d64e848105a0b7bc425e90b787a6f40b0a6f215a3ae95bc3f0e7383df42142b3b15299cd20029c3bf1cc769dfdfd1dcbb732c40109eca68cb7700172cec111319f0f66241855db0764af6c9af856dc1a1fbed22b756fb55f017d0bd79dba4997bce9264fa3ee5212b4b77450bc94c53f8fe0abb70a010bedf293ed7381a333a3687dd26b4736748a9c5b6fe69b8fb9e645f8d5a5919493b7a34fdcc081e0ffbb35377f3b6e74e0ad68528492d305d3f0f24522e44334eafb32cce9ceb988c8a3d9db4eb2ee511184f926b3b9428a51a370f7104f7ac58ec38ffb46bde83d50195e13135b7194a8b29a1b3da1f74e48419a0b8a4810e230baebbc965c5948c3e1127ba997f974d5ae20c1945fe282f4a0a10538d11005f06067d2d8644044b2a61e9818e28600ce361675f6b1097f9b0159a92d3f9ce12ae0e8989e2ab57ac86065e4be511d9ed41f23c2c06c8008578ae6f3fc6a958d36733bdf74dda28916b6adb30ffe8dd15d578da42b0e251062155f05bc8fecfa81d46c6c56e929ff44dcd298a15c2f74e508588e38a4371c00da618009def46c946438822ef8aef3cd36351b8d5f90e9bc1117469367478a67dd1217f6e86dc52a3eb01f7e2875c21ccd6d9f90f834e3bcbb39e6c109d535a85b0c537ebd114bc5e15bdaca371e0fe206279118158288d2f5caecd807cb31fc5dab7722120aae6fca0e75ad3af03a0cbdc1824a2e6927e8271a53ef35c2d97beee49d8055e7e59e5ca3b2f49d4eda9f63fc4bc1cae850fb16543db74551eaf0b78e9972cb013b1da013fb842afe9b710939658c20090157b452036fc8bebd4c3d5803f91ee6602d1ad3d2a124f6bc9fd5b750e9e1b7cf7247548355ce419f43cbba0e4cf8a0b3e33af20c5a0f96f0436025c0b968e3f97a07b73b165231461e34f3d256a1ec814c31d75b821b1c785eb428ab62cda309da2001ddd26129cad5c2fc3ea6fb022a6789302af472c9e065ea9b7f95d8ebd25e9d5afa31328b19daeb198cf35b021053bde0eebbd866ee9558e8e13443c8eca57145d2b37d61ccb773982c072d082d91b6601f1d6595625b6ed2c43c7fcadc138dfbcc3bd1c6a6ab9353755b8994f17cf9f790c42f624e1631234bc542f55cbedb4f3163ada4c1510a25a52be48512bd4a761448869470e3c35032345532a8ab6667332865f501cc7e1f98516038a36b8b74d24f3cf0f8a3d0843cdf602d16d8598abcc6d65ea767db03c06136d540664b512a093be1650bac8079cf50ede7dfc7dc8a62bfe6d79d359a2b30d7cc67e810943b0199f556faf15f09475c42395e7d59baf4eb34d9fb01850ba2443ab7502349c48db7b9547e0c922e4785911e2a26d018910d1c2a82f8dbfe3e39ec66f6cc2df9a564aa38d7dad6ff407d475930512e320be5cd256150930a55a992b6d931d8aa33320a62106b914144c429020c7821e9cdf608deabc053719aa1dc4e9b681c1b29ca1e99e3710625aabe1d3e4f6253bee1cd5fd120e7dc81bb88eca2aee212e8538d54468a30f94f9c323d5d7caf584a6834294609d51994fd4573524127014bc034a606c6d4df382fa298537f2f679a8b492a5c1c0ccece8ec1fc4a056da97b1fec36f038f7680417c65b442358ee1b86c11bd37711abfd015250326e193b30699e526b00418f849a41ab4a4bc7a98bb19da3af7ff3e85c428d71baa050942ebfdc99ad00c9386b84095857cc58ca1eebc51426e1a6dc4d26b9b09903cfecb9b8c8e2385f6a3e3e5e4d827d213012bf5d05eae75a09bd09625ffc8ee3728cc8a33806d41a4b872fb7a2c79784113a01ec1ca70b64ceeec0a3370134ad8392a645454834ef82e2fe435a74c2d3127bd17be1403a6488c0c6ff41f44e728a0d485c93446b039ef89b079724346be7b321b19f1975d30c7bd4252906d5d7bf52166b926a784c8c48da91263fc51c0f59ba88523d299e7b37af6118035e5193600eeb6e5e3a8d02cadbc86c5df4f5b784515b3b5fc0d38b2c492257bac09aa949d9de22e368326f3139b969895b1cf020610084c0343be00b25c4ef6ed769819a89bf08f6836dd11aeda02d06921c98ecb5236506395568444e4a53f54ed428d30432c731ca14395ae4d49f10019ab38a0996a4500c92c4ea0b421f0b0e4b60b05f3c59f2997352d4440a1c2501840e67c709bbcb535fe5b326075cfe3ecabffe1520262e1747052377ac9a418473d9246ffc8a48cb16779ee65b77fe11b7bea9efbdb994c8e97a459446e9eb46b0f37022069cc598edc08808055d88c8de29396758b0ebeba85805e8498a6de822e89a22d2f6454cad5d8336d700ae9fa49c29e105e1808e6e64710a7d104d9912f01b0b0762970691c14b61210c3d714344030bb5190a83892452b090b509d691dfea5a42aa60d53bfbceeb8551328108de94a9da582874a66ae957928a6c2716a62a7ea3bcd473ce3360bafca9e320b1be811960beb6627ad425f05392be834a40c5b045fef314fbef86da60adf3194dced0b85bf8be7d11af6c8afb52e29ea3cacf49285078db386a7ca553bcfacb50d5e20bf2ae4afbd922a3aa6051db9a3c8176f9003ad0670e9715e660325c1b0351b099fcae12ec6849ab3607bfac6261693cf238bf074a26972f01e6a02412fcebc06112c39d6a440c05ae5f8142625780a21885ca1752ca0bb574add0c5d504a0ad5bf33710ff31ee3a780e2128328345d886aaffd4421bcc1e220eb2ecb1464643961638582367beb4b49308c0886584d7c1205cce2cdf50292e0213588a805288b8a365fdb90d1d025556233baf1c125f2989608acb248980f94217b2fd2f210a9c88c65b206bcc1699302a82098e06b344a956d1070e821b4bf1dcc51e606075f4d94bb12c5549647373ef76f42ca9b98a0d7189f6b222ecb6e2e457978e6ae8e4653e98e2a7067e22124a2c466a0675ab458ee8da86809ee82d9e0fb9757ac4bfd04240baf3dc90950dbbf2e7ef57c17d57ff5068002d07f339a43d898b8e1706250defc3f9d29959a1396fbbed24da74b6980d70e0e06beb6c52291339378c967eb8a7c5e8081c1ef2d0c721041df4115045594fa470b88fe40c9460c28f4eec38b7c8de1641eadd95892d82e933317d07c2d588229003398f5e24869f965706420c6fac87cb116497e5b02b68d0072a247b112cfc8f076432b7c7de2165c0c3a13c6a5bbd35ef0501c817f1d8662e551e0b67ee56f4f4754cec58a1fb17e6912701c646c7af9076f3f4208e4b0ac2a9b7c1a0caa2f85845272a32974b89d0076893c81d61108a880b4e1a0296aaf0dd4c11d4d40ad1936c4190664c2254139e1857bfe98fdaaf5a7746f91ea6f99ea77a827a3349bb0438c70ab4b6e350127acf3a388c85051f404a556500cc05d4faf404c9cda53108c50b69ff734413b9a9d05944898d3b78c6f80b7a074faf518cb1d17332e28d6191955219627a822db18894c7f8866ed45c7e337ccc88c54d601ba85b45a3bc27de75966a6bfaa9f266aca24c2d60562934af5de5f874adf04ba047097fb9e4a309c68587339bbc184019f9e916ee18938770a9b32ba54675a9c6388a07fa123f9727ad6a719d290065885782bd30f255c64443a536d98841d3e605c4cc3d5a4668a0b295011a115ed95ed9cb78a6d4c7078199d2750fb576b214a0811916400e99751e6f9bf47d4aaea6313a1539840d2e5ffbcb5e633199dec669d1dbbfde0469912c3849046e471b2a7f3bba495b6875b261107114c837d5df850acf1c8f550fa20fb3f0a640d217dbc4604052fd866cfb22c4cdef594645af882a03c59be0280cbf7f5c9a0bef67ff512c96aa5843d7186cb2747461c3f47a92e9da144535a7f52992410ec20a299078f13d0acb73ebb38887d7349762c5c45a214b78d53ed64bff31fd5eb182a84c40072a62e699e5cedc55742391360ef452fa27c864f52546cef6e5e1d12c24226de034a5aac8d5ffdcc350fd139bf41eae88158931975c399410ac5884ae08cbce89ce1f6d63d5814aa3eeb229e813ac241ff8468947f8a5b51efa244779582c33a55f7cc8a62f64bcc5d166a912714a4f98c414a4b15935808260aaae8618a6342bb4579d65d2f57fcb222bdd1f4c3b6d57011ec6a1fd16dec35824cdac3c1e5b0022505558b1ecd46a20759896931b561665f18794e77d96edd2b54b85ac9dcb46a472d684454223748372a16ca3392432c8eaa3095e3c2b9fc34c97ccb1411306b3405cd27403bd2cb185f7bdf534e1cdefb00a9ac5b68955bae9d2a916dc1ab229362b72fccd5c728a5040b1b12b96c9e2bb2e15a141f15d2cf204fefac18b811b773eee87276a9724ae4f7b49a54ba163d3150b4ba0129fe33971df9df2b0d3a41af8a421c3593dffc5bb752856851ab73f34ff94d5b36ed0920da20a6a6db86cbffa35cb86b412f1e566ba9d3ade170dd63435fc57faa686b75804b726148bef061a76279fecd92df40c66326762e29ea5434d7e293073791f4ec156123abc0da1f94c869ab52c82bc18763b1a45635a37ac894ca1d21d32c3d84ede85a54d259b3be7f5f2356968bb45e98e1af3e836c67aec54602e28c543fe9189c0061441e374e9f40a6bdcbf745807cb05aff83810e1d3aa09c56b99a655993cc3a4dda27dc240ede393af6b02f7e5f73020401f7af468fd1b356a62dfe03a2e49f07800f37a0bbe584a1687c22d5ab8f1b3c7f88a0332653654a7216f3d109d7eea685940cfca91248c4bd26f00f73f1bf9fa8c6c564d91be6e7ec4ed31734dbbd33ec34391e6e43706f303712c1f404ebfa5a6d52fddf87f68fa748e06546878406aa1f3f1602fab3cfc44e23e37c4b6a289ff88aa3b30e5aea25edf071c79e14e02aed57092b24a727fe19eb688bb3bc86182c44c8278a8060a943802bb3ef97051654ecf300028c2079a8d897dce43631051a08fb22b75df1905ab2e8e41f074582ebcac4f199b977aa55f68881452b7275835ab3c473dbcd3948d68581e5322a6e3bba5a15fe28c3ccc23c2fdbdcffeac12aa0b0b3fd41f081bb25ba248877eb09f6e32c02175411d2d91ad1aafeb51b7c6307c4182dba94cbb2f95f01c51deab7f95463e9fb32fc455daebd448328e135b2665136b1337622b79fca195fa5c5c4bc46263c7cf3247fe641cd745c2f7f148a95abbef284d84e276a4d904f1fccb262d9aad06fdf3b9ca41a10812693098200c10caf183b83047be8581ca6d276118bafcbdfb6e4282d609c59ed62e4f3bdb789dd2affb01691dc95068cc1223fe79f4129d70e49827c31cd9c7b336a995a1f37cc6d09b190d4551bc1aa84548010f0823f5fe22cca31740434590d249847299cd6f68c3aa43dede39532aaa4b8cdad597d77e8e3333882dd409f68443dbfd587773ec034ce7128b0a198246c3e0d8245cd29bf62907321f2223eeebec95bb7f48b80257ad6caa9f3386e2355161a4cd9199565a5cc0ab525ce206efbd73cb28fe7bf3b0f701b97e4e3cf349a35b315c32468e0eec90397c539d4ba001244f1886d03f411f226ac3a68d08096a22f67117040e637d09711021a8372ca74c2310aa27f8325d0bf8129f1fe8df37b876487808a8d6e56c1866ef5b73ef46511b5f2580ec85976efd74f9aa1398e2fa0f880e261c85ce6a504859b85ab6aee3edb7e3d812aa0595124e175b29f8dceaaf44ed92e537f8accd1b8103cbcf9b3c3f872b2e91ea1b23015be11850617b644f2af4f883c0768cbb8f073fe1024bb5cceed87367d468b0bfbc320014923b486b7b3a0fbf1a2938c9927abcee4288c568ec429b676d83a0bbe6fdbd7eaa23703a3b84be34b7142d2bbeaa447221775b73089ea7905428430ab9894830fce8a0ef69b357764e7586be0f1287827ead8a3b09c1db67435658cf7b71f174fa28783f366f49d02371cd6c5ffba0449a307a6cac97ad7bcf1e805846da6df37a3166f2cdabb1f3e204a8a9a95d6ca44f45a4033a5bd429dab381c3d5b386192ee0104939aa9aa1e9853f85951f1ffe63f474d69ff6f1e8039622a9c3433e0b7ebbad89b0718df2c885efd02b156d8651d6a02abe586d2896e18710eeb3a5aac4c6a87f5bdfafaf520c0eb600e3e51d013d2c3a166263945f3843826f067ab095d27560aca7601bef3003eea1185bbaa0e628e2d36f4f5afb08cf1af634154097a5aef3206c107e18ec5c0e5c94604b243b21fb09615d52ff054fe07ed8fa91421af02cb815a8dc9572331090618a5963bdcbb912d785e9d2d9d544ceeb84b5d9c29c71502bcd92f701d285f8950b0a3f1b3cfde1e6f5872b3d44372f9b037a2ec7080b17267ac5e4694aca9a909a9aac29f90ae8689e5c96dd0ea9bba0f51ffc83cbf72cab9ab7331e86e06eef07f1d066e89013eade3da3d72392a7aeaa8aa84289752ee8353e17d6b0faa3b479f883f1c977f7bd24fe330f75bb67a672450724b8591acd5672cb4b6c04f5cb24226dc673b2288d0d4df77d93ae4a3c930b857e6f751dcfbfd80badac0caa4cda0d5da68c906a1412157f3efe08f8e3b82e9284681b3bbd6a9ccac737e831b95da8572c20005e50725bc520493ecf40d4415479a3dfbd98b9d892241677a9ccdba1e0a11583e1e96468016e681486c16f8832a87ae30e43ba13fb4c92fe54b24955a3155e23bba63ba23275b6ec3ae46f232632ccbd56cec7c54ad3ff882742e4494f3d29b7db296de4d087f8b51aff48b5b345a65be5d81e70729b60bf830b01bc59ed22f2971614c8632441c077e8908a596833c0f62ecd5e1777269890625b69d3304002befb5f8d822a520c453e2af0ad0546843883887b39ab1a904914d347d5b917e141a4cc566cebced5b212094e886f18674174a7e1ef7b2ca8bf2c3ff6782f342e204e383e3219a6e776f0f33bc3d086c40a06b1d0d411b39828606f6b2fbc9831bac6d8cd9c850847a3bf133c4caf42f46474f58f26f9cfc49139259fcc9130e5144bdefc1b3f754dd14153d79851c3bf5e39e99468bd766233785736dec7f3e66ff002e59ad24091afe4ea26b91d91330048eb7fda5136a9f62f684ee5ea76c836d23111964b7455420a51563009d939121d5511fd4da588c3b6384f2f694d134e6449c24a56827947346f5f8733454d9c1821cedf144e43655df91d1366a7f30ad129ffc04edab3a8a5c40a14088e3be70b83e070b20b7d9f5f9d97d642e5b1446ea19bedb30fd54d7b949d2acf1d432dc92faac1f165dfd097a130e00765cdb453b87fcac047d6f6baa4ee74097cae1ace665e5286744c0bde3daee2f13658177a6ed81c7a1be6f19f3ee1d1c8518911c8f37d80dd7f78cfc4d3837a4f091c35cb8a27a7f889a882b11e6983064dc2652d464a806aa3b9fa9163b322d9e79b073f710f0a24960f28044144b9665143c9273a2f5fe5cb7d60123a804635d5d89712179b5ee9c1f45a8d7f168ad7c5c2b88d3fe4c0220c97f4a29c258d6fc930d0dac3997324949a0d286396baf35a88067c16986c06963ed656e6d4fb73f612da39dc2bf6701cbdbab8d5a65725419aa2b0fd28d875845375d8225c012f95722aa97bbf16a6820decb2731ab035d4a8e438e737ad42b7f7f70c34325021211b3c5916064f9c88fc345adc65e2ab2bfbe5a41416d76371348b258b414ee177100c3aad2276046f395f6526a5659a849da4b75b5388e8438b16ee0f778ed3f22c6e452b23bb4e8f4812ca8013e311fcbdad63e904262241160090a465eea660a11090fc46d3da545ba3dc5f289c22a0c6d7e823eda2223e5c4eced88b2c228bb74a063c27850827cbd713d8b9526916f94a9b50ed50c5e4a5c1220ab3a465b2370956c65055cd8df44da833737751059eea96843e9c9de78f1c13246bdb79c8da9257fe8a1d0a8080a203d8d706c30aa99e8657b9e6de70417d0a25e14f21dc481dcc088603d0e1ecde16dd3e500f9551a69c2fc8591ba66e816b942fb47562affae7e3358cba306a190d4e4caaae081f5410f4f3f96d0a095b9748090210875324211319199655519329485d82ef110aa4dca90d71ca2062446a0589eb4056f92aa2c25cf87c8c0af8aaa74744ddaf812567884812fd066d417d8821cdb2f3f6c5c508259b0dfb50a82f31ead8e425d9a23c787dadd9c70590aa396029291c10d79949a24255a8c132e4a7c2a8b86eb2bf9ebf1d89cbef4c79c39d2652051d895f451c6b2a3b3c9883019590f21f252816188756cfe95ee39c5b691b53926f91559c1c588f49b482a5613727a09f0751abbcd01ea1e152b839c559cc2f5ef537c8083ae8df6946eee299487a151796c9b7b9e7ff7466ed4ed299a1384487d9caf15113d898d426d48cbd4377216019cd6c3d1433758dc3b53992e2b4ad951004b08b5241b1fa78793df9bc899f96056b1937a0083990f2eb2509d701dc1e4e6e9083556706043416a8a4a5cfbdd468230b8a73c8f7aafd4f83089ac2d149594b7427e931273d368a99f284375db62868de654f33bbadde6af7ecb4491e04cb0b1d3d53130f588fd6729d2f57b354bcebdc0e318fa21e9549611958458432b69c8660ecfe110ee0c8e4f3ba68175514d8ed9a2a7ecfc7fab67f730bc66a1e064e2e541c8d151e22261c8c245e5495b1dcaeb9e31a3035ab3db3e7ac16b525fa408df93780e8d8b4349d24fc95dec93bd2160c848c03da156e6f5b2050b2e21c596c4f9e7737defff5f71e152299939e2944a9b7f6f5af4fbc7b4dac5d6b73e2458713e7354c8e84dfa61603e72024846382d5d55f8c48889f8ba2135dcd2d7468982e62714cda167063571555b08934dbdd5bca9464e606e506e406a57b22555df3b4e6e9a7b5141f017e81c948a3e6c6d3772ede3f58ebda8a24037f61ada7d653eba9a72e2a2bc5ce6c1437931cc9cd2337bd04a2706a53eba9f5b6b45a9376ad73d76a8e7bafa79e76e90d8f9142c3c3e6efbd156cbedea75ac1deebb5706fd78b216badbddd7cb878f0b8ddea2b85abafdaefd5b101398cf6cd851ca75d4e1c2f7150892591fa6f58dc4cea288d742b653ab491c0be61e9ce8bc283c707b5d55ff0b8dd3e77c37daa4ebaddd03af371f35cce034442b225d9b6c8314d64e0a20c1a94a22946605810451145174bc8f0423773ebc1511942460841c12106e708463838629b2105375871c3d9809bc788baf28f01e84415a4bee1d2db4dc8756fb2ae2008822038546a10c49824ff4dd34716b8ba0982dff7a5d296a497ac2d95ba4b25d00897390f48d6765da73251cdb75333b27f6d5bd3e04af72d211fed4a1ea2994a44e00ecd0ed168a994d775de4ead57d494c488884aa854ecd49a2b3c47472e13c18a1d09bf0dd867eacbf611186ca8be52f54554246385f5f1b12a1f9e28b07d127adcf46a61305823a93513a8ad4e5257b518d80c1938c84dbf91a2e5464667be1fb6c328150b2a94c85655420c604fca1b5273301792d22c16cb3b25753b0e08900ba4c71378092ab4f0e19de72dc05aab42c7001516505fde933378c2078e03de111dd434bcaefbbecea4f14154320a6ba80f023993fafa6fb2eaab53aa7ada18159216ba8dd308f52e8067cc3b0e553d4314997a1caa3e6d916ac7e350f949d6d38aa24da9647a52558a1067aa9441214584ec89f1d6a8020a0bcea098520685182238828ab8f4e034f23ea8c829c96954fa225f92284e234f4cc1bbf158118186423d213f4625049ee48b6237628c1fbb60ec823f26e65d609da92731a942d51e1e1393fd532a7f113da1543f37d2ac060b54357bf7d780656ec4a84c1caa6a572bd8f1077e144675a346f0ac05552a81d12e3aca28ce387ec7ff876fc2297dee4cbebfcb6ceb8696fa1a5fc7cb80ff398e37f335009ffa1c8f42cccf9444663ee67394448c7a663ee689e4f8d4d7136d5a93ecffaa79c7fbef08800a009d46c58f3a0c2f3033aa8601d995100fa2e6b493b6c141cdf100ea5117028d8e54dd509176e5a47354d5c61f951305aeb9e6d4c73c8ed22802f5bcf145f834bef84518973a72832814ea511885c2a8f1070a852a31aeaf53fe2e2273d49a3ea944d83181a7c727851f1580044915158d465e1cc6890a6dc2bde2097e76a612f8796157962b1730dab119aca502cce50876baf7594095aadb71b3493beb588cc8fa77e4f2f5554960817dc32b969e6a85b66dbfcf7ef77e0de22e8c46aae483a0d7ba47471e71a20873d8a303ecdfdc3f3dd43b2688e0e6f5ac2908190f32996c48f681eefe7df78ae20e1cb0f8a2eae6f01377e0806f46674a32597d19a0be5e72e9bdd6bdf2b7387ceb4bc311c269a9f4e28b256a24974a2f7253c7096c672b5bf258995d0d8151cf653ff25a1037ada838a62c2a4e78a5b63c57eb1c4b6493d4726010d572b6c5b226b072392a442553580a4d39229bc4c2886c6c8955627ad42a2941a9381f121507069d6395d06a4d1cd56c8bc702197dc63ea94daa29445d29e91c2bb349ce8585627db04a6ccdb75898e73c77df8f70c0f6080465a4278aa2288a2ff6506bac0fbdf24f02e702cb021f44261aa7ca7a2093b02cc868f9849579cda920e30bd702751755a8ec4474ceed627c7f37aa2f512613cbcb8568c5e63537b30419e2a6cac7c43281c5a2c2536b589ec903046765324f2636a9c55111dded7996a70624013fa1762f9247466bcd6dadf180e00df6913d67cb0b1e350ed0d25856d7e170f138dd7fb69d108b659aff2489deefcf19a82d13008581ab5d390a822098419d4f092bb33c0c89f5efbd7508dbf737651e5def29051de0995413fc2f2b63073e94827921dfe504645ba91206045f30469527f8b9830c0cda55cd99000888f7aec2bd201886e11886a3188661e872d3879b3a2200896e92a1d6a698919e456a0f5e88e282992b6791540bceaf9cf11efe2800dc6de31b606ae673541b7f9917f0871bc1b3d6eb3cafb3647a535f9e3dbdf1973c76efb523d5c60a26a1da78de08817e9d2bb05591b955ae25014e60b4d21cd07d2a0716dcba5de16188140071b329b106113f5c01620c2b5aa0602a5100228d40616206453ce8228d2ec440411b66305922871c3c1922cdf5d7436df9949496d2525a4aebb4745aa76dcbb7da751d6ba4c1d66aab4fc9a07ff5d7f15b83d8f722b5df3b8e30d439293d7a875ae6a4be4e9d7363d93f33299265571fb97c6e2ed739d9f71d68cbd2a757fee087d7bbdebd4f42cdb7ac000df07b57f57d7d6232954066ce73cb808e7233da51d2e974818a81aa81ead339bda46ddc8c2540b66f967c20f82de99bcc7a1d50cb723224a054d3615057de496429fcf8f4912dd7b23128a8368eebde9604204046bb763faf4b3b546bfc7930c13d546b1c0a1230a82d97758ed38c5cd64dd03c0dc31b23fbdfb6ddf67e59da868a8343c5b1df7299d3dca849f692088d6a9a514d57a3ae1cd73616c6032fc36dcc4ad79a88a2d4a935fe34db5dd7f7de94e31c3783c1a14d5f357db5b5fe5579b6a1c964baa0c95ad6141d45e0fb6875d1dc5d1635bfbc3edcbc71ddfb82aefbfc77766898c9400cd35a23969eca4c21f0bd9edad6c880301d93445c5a5f27cb243b93fae2a1b6cc5ef9832526a865623d3585c0f777b081db9a3dd41a1fb28c74018a05b4204280c00003b14c98f4936e22445d79cb92a030a9b916cf792af3d432b14c401004471b2a58c1b2877002ebba6ec6be0dd87a75e6eb7983dbb09bde2ecb4d7135e08ec5c858785566e7e8ee57c666b88e7bdd3f526baeb5626db6069303461de63087592d2a76241e50d402db47c5eca7da0aadef7ed3dbefbae28400ecb62a1ef72989b0f3a39260829408b40d4fcdf6783e3cdfddcd532b95e1855b7bea1d962bf4ce08cc852b2b9081614392188f293a3489c2081f8a68f0bcdb22c0e2092588b03892048b7a8694283bd840b4060b28f8be1d1004df2b16470cd598d8d280e10c15bef8a1072990c8b20588d39fe53aa940bb2a95ace96d188662188a6148c3baf1a113fa2987ae2469ade7917e6fd4286fda2684dc7d60650a1c286e489224ad0d21a79a0da82b77d53e9022bf5e37405c2e97cbe572b95c57c052f57b1d00d97f487dd57c244f61dad6aaae5cd92d089708a737c9ecaa4ef98505a7b936c47cc5b760c9f308a78f046016cbdec2f3becf45d5b7bc05e3476b960673c03d6055b52b1308aa086a096a9030b2d836421e6dc3237be0d050cd0a1537a988aace1f04244081da6a5b53c152bde8bc5e41b70b1912c446a56d544cd3f45114c5174fa2781a4551148700811fc8838808e692a406b8ba7944d8c6d0e77d1e0d8c260068609b519a2437698aac507d5d990dad33d4c268b6c8da236b852c0c8ce1ef917ce5512e42bbcadf167208ba8ca4d63c2c0bee4adfa2c53ed152ab59580906e0676db0e82a087e1ff8e9803ea452a9542af5682a26879e988a49a5523fe45b99ee4d4fc0b24c096d7a0296fb8df0f88d0b1835bb7c73c0f651b3cc590146cd9c937c55a1d668f13c1b821ff6fb3330fea800cbb4082e33534b25944c96f1516b7292c068bdfd7848aca5b9cfea9c5bdeeeca5a6b58758929401c711629b530c5f9bd27f6f06c77bd6ae31f82338cb212505b15e7b640fb6d53697f55ad045433a7b2dac69fe68f80ffa935260d0f1e0fbef73a7e242709f7db00ac038882ab8de23397412c168bdd58cc85ac505b9d46ed18593b46d68e91313246969dd69a181367e23cf8132fc291c8fe7ebdaef33a2f168b72bbdd6eb7bef5cd1402777dc5be79a55194e911c5320886891533cea022a318a791fd229507379ce21b3947954c28f3b1d385ee144b23d31b39c3cff3c4efd16a6b2cf5d57518b5d5331e629506f08c98986603a8d6f070829f210c18adb60ad4ae69e06e6e628101f77dd88d3fbe4bfe036cd93753b65330da2eafff7b1df77e646c0ab73477034110fc40cf033fcff36ef8852153288e27d3fc2749b091c0920d639b0ddb5e05d8b2ba6ec74d2ab40284d129f15ccb38c0fbeebbf2dab2eb881250034cca5439f221e96c2a4c4871747a5ee070a2660f353a22dbdab13ddac068e7399b64a3388ef71f921fd51a3130fad9320ac272e7c01ca7da6ceb03418cc9cff61d65b7e5efa8233a52e2385e4e18b8ba39b34923785fddec94b8e91d51176303d725c4c0e55c57d41175b11fbbea01462b2ddcb1ad8ec877783aa2037c91003370add68e9fe77d9fe77d9e677d5c9a0843c85e3f5429bf80fd2bf8795dffb558741d124d77bb92c66fe99e6df6762bd45d79bbe518dac9c8d30387fb3df51408313495c0533982a0883149fe830e964413ae5fd4d6e915a08052a791bdc9a8abc664dbaa6c0b37eb835d79efd501b7f3a30376fb75ddd775d77a2ec6e09f24ed0cacd95a201c06ed4c0794d205d2ddc1c3edbaee7e909d244db0c5064b98c1c40d66b8e174233074b842062838882156858674075b3069720513a72f31458b2d5cc4d0c4ace72370cbcf81bdf74bc20f4aa1041959e8e0871b5c61bac1931b94e8428629639cfe15ecb6a5922d95ba5e35886658c00df7fbee053fd62743977668a4699aa6699ada564dffbbebba6efc4cddf863fc130966f4d320fbc517651c7116b93fe8701af51bc95d59a61346276a85723a042084654ef0d353bbcad51aff0faa601b2970fa01952430ea52bcd5b2ea2e5f1d05f3d5634e7f4b5146007c8e377df85dd770fc0d00945d9b2965ca6a573aca5a9ad6d74bce12b98ec751a25676a3446d514e07d932dbb2527ce51f53a2964af64f952868ad64ff9712c5a812b55bc85c4ad4629189650ed508066d5b1fecb0a50a1143207183a22baa5882ca4c4b142156701a394289115a0ce5a086a131ce1e2c5e8003285a2843072d4e5beff51d6ce092e7c132cfa9733c1f7ce866a1c9245c1043d78044c8758eef02789ade05d619bef8e3a3a4cbf649d531ef71a4ae7a843d43ad09b04a6c84b057fef8b8a94308dc5d1f216de3550aef84a456f808b1d952d282a5ef2b81dff7c1602722308b659af585805c6b0b5e5061382c60b465329bd18a737265b5e6b9c06e9d14c964b2db755df8050862fccf6299a6089ae8037350f2011a44b6639f1098a8eb6cdbaea910b7d6ba888890e43ce739cf85a95caebe6c6072bf17f9ca9fe8c7cd86e57c8b0cf8b69ac9e93aee36cfbb1702b8fb98ef1c76251a94bba323378bdc3cca52348423b9f982a260fee56bcd63298f63898adfdf1fd62572ade82a37082855f55195eb981addd631a54caa4440ae55e41795e760645e1ec7d79752e6041d2ff32890248e274b99979779232711f27594322fa58c0574bcccf7e4f8997ff99932c8e8a5ecd1f13265d08dd7517a8eb29ef50c6f3c8e279fc88dc7910b32eac1f1379efc7a12c1f137645ebe661470fc8dafa3cc4bc9437e04ea499628dc781ca5b545b5c673289c9447b7b99dd269e9725d8a3a12daa53554a14e845a190a82fd1b2a99efcf3bfeb07ebfa6e0a6df7eef3c7f2a778203a273ae0adac67fc8e56acdbda1d6747b255a6f4070387bef354dd3344d962b974b39cc184745b0bc491263d709ba465057b821445808245d4757ba438ccd16d201c58f0ee817dd743731a9b2f66b1a56ddf1bcf44216351a52ada74cb3ad4a43526b409c125cdb747481b3a58906c3a25bae1974152d45a575ce575f9e185d74ada4b67c600d43f681dfdf07886de1b2c14601581980df96685d237b89f692ec65b54a9a4ac39e2cd18aba6c5ad3787097ba4b0f84e7243eeab949b067d49c54cdca14556a694a7d45d139dffb3795faf27e74295718e147e9619e9e8a3a77d9eea337ac737c689efab4edd2eb38aa4271576d3ef8c22e79dbdc5a038a34dac963c8b8dd6eb7dbcf0f08fedf9266f5e53296cc94e1c080d1ceb9cb0b75ee6402efc86339be4b79faf17bb0cb6b698116464f0831a5969eaa3309bbe838818918f5887f7a22e18f4f44fcd3a36deb3a2fa33dfb2162d44fe4f4e257eb325df69c5e1c3ffc24a7174f2a213db8c0b720a3a04a832d8e2863861bec0c4ba3eebb1205db0d7e97d648ae37ac0c963e5c2e10726814c14310471ccdc020aa418634d6a8d1aa104167879643bd688b8f17d9868891c11445282122891d949c350c308e20e38a188c7164ca49c44996140d2ad440da3283501839c0218a273b1471fa7bd7b22ef0cd0fc06db3d65a7bef75bd48114551bcf7dada9d4eff9fb4edf7e3085eeef187774be07b3d3be00170d0a9ecf76ead2d896180fc927b7ae54256c00ee386f8cce61c678b65a3be7ad039e0fb87a067e60cecbaeff3baf1070f524659b91e8c760b2a37123efbd81872818ad3b580ec902c6358011a9204e656200169b1f7de7107b5ba80fdab113eb06083346c604871d61d2c51411618d6a812440ca77f05ab4da236050d7f9ef77d9ef7d174f70311d2ddb52cd2863f572d44b440091938f08005248c3469e209168e68f18205191ab084890aa8489979e1e4ec07625b0da8420c2e7041208df1c3f97eafca7393c0026ddb2efdf66353603d53c9fb12087edff77ddff77dafe3f7262c9542971093e9de52a9542a595bba1f7e58d65209b42d957d1c6f6b65f71ef52c9fabd616ad9a4ca2ca87affaed8d8b13afb4a6fbb517d2d497bb773456e0990da375e6e96481fddb094b535fb6d5547cd56a294b541b7f7513f67bf43ebc1747ae6309a86c7aab7a22f4a7a96c29be9a11a089a7417864fb5d777fe67dd64c420d70b6dfe51d33ec3d4a038e3f4034088fec7d77ab7b5dbed6767b5e09deebd870ab70640ff4bebd366121249ed5bccf63b566466546a54aad7e45f65a9d8bea799ee7799fe9a67d9122dce2664b8a8244946a0952dba1e9ea6eeb16db368b363c9807f3905cb67e242b0c6c592cd3fc27491216ae86c026f23b4996262938838a94b418711a855f844504164c4ea3d2a3f80a1e90429eccc27c113ef292b2bf3ccca3b5f6d3799e90079301f7578251c9f49fdec8f9a27a7998ef797998ef8729838cbaec81f95319747a980f72f99732c8a8e7e561ca20fc306fe40c6d5bd0248edf2ab4cebaaf675090510f0ccc1904f332d7c793e9ca13faac7655cf6a75ac5da1480edf64cf7085ce61580a0195742d7b548f76c83efbc14231046aa9787b645be00f75e56f94948d880245f6f72639049d51cf52e1c1ac935a4303ee4a1fb0a7c48b95ea59f3e92b3d35b02dbd2b18ad359eeaeea2a3c8c0e17043381c2e8b0ab5c6dd1d87c18f05fcf190c9849a26f37a408165686fc9a9169d2bd83fa60aee1a0e6a8e0d7d8404aa35feb296b54c2693c96432938b55845e541cab313386048218ffef5c8f99313316b3269305c40b43389c41451670431451ce972fc22a02ca91d348fc1622076791d40ee74b6944f3a22b53c57d69240e3384e304eea1f1afea03554aee80fdf171b65c6b389a4dae355c2c7bccda988dd9f16dd943b7f4b5964357e8de9a4b59024bf09500d13e2afda8eaca3e8a67474747a5253aa9d01d2fc88ec47be8bd9f6c7ab475dcccb5d6fad9d429a1078f19f5e0877922a87f7922f8617ed471e2e5514f04e6f1cb5814601e7f8f32b63ce1e5518f3f4aeeff669ef4b1ae7d39e0cfb60a8451bda8825429f9d644a9c10b555809553ec491ca637625d6d3a46a6c2abde8e64aadafa9637b8995b9e95f6f3fd6deeccdde7b63b19b0e186e5ebca0ee4b79bdf4d5bd3ae1bd65607fcd4ea86b859ad6b496ae087e3f7e180451ad55884c2aab5240e9ab2b971e47b68fe2c828d9b11cb21fd904d1c31d022484055cdd74416dee6f13be175f1a968f1d13fc765fbf71e988703351092105446791dac4113a4091c1f99524f852f1bbe900a00177bccccc30ebc6f5e1b29d999925e11222d97b597d240b6b6da5b16042f55593fd43563758faa0efc30780a2854aaa3f7fdc74a802553548d8c572f3ab7608b64449270546ebcd5eef4617f8c636cc94466d8aeeeeee06418c59f5e57fd3f4d34f3ffd34fd47404da8a6834324d3b64fdf230619b99441635983c42edbf35cbf6305d8bd9429c12bbbc8ffcbe8a34dcb3d044edd70fe28548ea3da9179c23dbde669c9b9991ed12b7f4cbe697a94652a519cd2f8e051d76690fb09af445b89b1968ab534b442298fd78e664ef3234faac20ad93adce635b2da7ceebdeeb597263ecfda5c811d04bb9b06a682a4a44e0abdeebbf77e5fd209033e8191da02d20f5906a418d268c9da493280410ce9079996ce75fa5da0e2785d9ada80d224b825b258522c75b95cedeee48df949492e312089431e159ed775dd1533ead5c44c7312bc1a0fe09429f6defbd56aa520643cd86c3e3eef799e8f8d4543779da856da76db9905ac08298911d988dcbd443b5bc0b5d6dc9ff9bcce9482e3801f7a9e288a372e1f3a22ecf8d8df13291a699ad2a434290d0d4d4a93d2d847692c4d9ae6eaeb943d1d783b0059c85f0c35dc9cd4977d3206d8888bbbb81f70b6e579a997da56ad35ad29089fe5628b1bf9c771eaebc3dd2c884b2fced3e2a5593c2ca98725fbebcc66336b2d0d0b84baeaef342da561cd716abc4d2547691bffbc57a289aed5b57ade7749aa31100631c58f3a3dea47c8162ebb862ac10b43f6b26f34943d46767bb3b5da5a53ded7fd0dd8e6d0bb737b7a72ea4614fc3c9548f0bb009ea7ef71851e79c838964145cef1514a327aa324b9891445094b46ede1dfa9ee91cae22a0869ad21b22b7b46f61f2d1ae88d5d59d1ac0a8d71e4a6839a0dc5c0b39d6a658b35bef7de7be28d039190906d7d1f68c9c0d123077cd3b2865003358084ea80dafa013ac386b36266435d9d8173d8961fa0db2df7fd3f8f90100c053319e4724040b91c502e07823d6420812ecc77b080c18cdecf7375bb3beb86a7a7d6cc9ce82e0c8674bbfbf46d829acb39b62693c9640203db3fe2301808d9ed3dbd8347ed3848b04f058b6c364ffa1ecb573a12989b37601809d908d7b3cf9a653299ec2aa089250e4b826d403298ece443305fe24a4493f86084d586f2023b50c961335887e9e071985de584d0009751510e2cc98c8a4a2d036a992c67b2a03886e11876ade90ebbc3d218869dd93158866ee18e1a6054379e4ee3e94483f8fe3f29f03fef61449d1c94de84b241cc8c8ac0483ebdcbbb7cab44375dde73890631eff8633c7dab7c72a7a0634fa57044e5d309675ccabc7c07bc0ad000cb94e03d7eef71e9f2e0a34ad0cd54ea63ca7a02ccc7f4c07c4c49da95cb7f1d47181f97303e2ebfd6b8946810339fc2eff047d50add06aaca61990298eb582a9be0212b2e18b96007596ef041a68ba32a3b30a1e48a1b9ceefe04a82b7f1bb015826318156957b5465557fd3dc59457c0ea07e5e20b344cc3344cc3344cc340767ebc8c569cb5358a2c4cb07016f12a48a751b7b5ffb71eb9d96a088cb4f303fe097d9e1e5481ed43ba1c7e18fea81255e1873574f1f3efbd2721ecdef3924ab6be9ca82d2f495df91b1919616f68cbec4d666f8ea4d63889dd6cd8bd773c0269481445fbff04f7bda24c5b1ed67c28d8b3e186db964b6506f535a3398e67bfb928208511354011e5891853a46ab6255bd85002052ea46cd016e97adef5367046c5d20d795eab00054b5bf2664908eeaaafcea3abbe6ace79872ec0c70d49de2cf9d911e1d539a5f7f7515fde0bd9bc8686603275b7dd47efb000d996cbe55201cbc5c97e638bda14432f2b70add55a6b3fd0ff561cfbed1ea1cda8e46e977c56a29111000000800093140000180c080683c16058402619ef6b7a14000b5c7a407870409988834994e43808829031c619040820008c91a1991a0b927611d5b519b12db6d136948f1e63b2cd2622139e3930147518ebc767e2035b2b1b847f6bd4084a25b1b1c12240d2725fd8d8d3760ef39c5aecf4dd930608db1466715eb24c79342de6f795671e2c1eca094a11bc90ff57bb121191da2c8a1e504dc6308ec358a7acd48fef0b82c1ac7d5ebca90555827f11108a25b716211629ab11a623ef7e0156d82ccb8404384d7da26e84034ff6bc6d2d85dab394f6610ee07245e5bf9ba761b1e5374fd1b07ecd9f38f55a43a5e8d918c38e3a1b51a9678bbe9df7fbd1a703058a775059369a718cde5aab4af9b8d082535507100c8858dbe589ed3a9b2111e576c163cebcf6430d68e5f066435ea88a0e016c5bdafc2d6f8ac7fedad82ac65af326773640751c7db72727cf517c31ceb8d2303045866bad7ae5a15610b00339e60cd418e9988d26af8e4facccfd70595eb8c56735e3613b29d342aa723b808634578a2ca45d702ac51b614e76842a8b55e04eb34f33dd21435e953d979dc5bd152c9010a167d9832211505169d52386bf1f15db4f96b275475c816862b30ee6d06f612b0400addaea564a285509178574e09e9e0315d20455f5cf063b7752dd230d16b239f9c8aded8d8e0ec743380bc745c9da0605b097d84aa8f3c237245625189d24421e6f51f468232462e3642ac839e5b95458f55db9b999d5a581cca0d05766a0aabf92463438809bce890fc8d9a533743cd869eb9a49d3cf8ff875718ae3bb659836adb3c784e6b67280b3ae1531a8e955ad529d07c83002168b3e1917738defb69f6090c137d9a0508dcb4ce1575cc882dd8dce7b7888aed44412e7cf32aeb265a49730460d3f8a8dc7bc9868dd4f1931a63b2974ed442824c8432127bca588908bd39abc9f3864115ca09b75c4d9f1c5bf3f0a1def0057ee318409bd3a2330e1e2ef1fabe46bd29f655293ac58d4b937dda4418f01ddbb763ead7487d9496a45562657dfb836786c61efd6a0f534bd578bca4cbed208a6491e88fafaaf5e8d6a7dd42614a57b88f79259bcc929ddc0a1455b4b4a1ca9909f32a907ee264a57b5116f4b673725b2239d91be65adf15591f20254db70f855c2438bbc6be777249be7b55e1add246c3361c83f34d3d30199bc3a5693f4706ccba55e74e092c8cc865eb31943785c4292a410159d9ff091b081ab701eeb74b2b3f67171f65c7057129701a93346e704393a083a2b46805f178a7eb169154e690bee104692342b229da3f7359ad1e2e36cf49cab9413d56f614db02241b8b40ab02383901b3035333903a9b1be474b240e5836ae3c0a9a7a8395e7e166a579c50d4cd86f788c39b11c086cf2f59f8c4f82aa27f104dab6044a558f08689505a7f3f282fef3e5a5aa645574a90204b85f73516117786776a68278fb9592d7d28383f52366243143a1e6246d04378fd7706a3ec694bfc7b72971e9635be66e274708b852172c06d6c5a0509a20cfa597f08bee503be1456c9d6640ea1dedf278c937376f53306e1e96598623a33e3ccca01905c3bf8717eee55bdb0ff60d2132eef0d1790c128065cafe25cc10b827951cb326a9f5612f2bbfa7352b2c05724acb0daaf39b389c63b7149986a7399a3c8ae8aab034ba4fd018efacbd67d6b6e84fd5ceb4eefefdc4b8744c6049f661d7ca57085db1baeb1e8f9378fbb0836a412fce6104647e1dc354146434421bb6da0a5a95e61bac4dd8f8dda89438b5eed065f3f12dd5cca5edf2aceff2220a99b005560f68b37f5463e16f9a550357d018eb001a2f77baaf8cdee325f6f7ebcda9aa454ddb37a38d84eac316fbfc2af237337ef6cb745232d19851f96320f5c37225bb62d5e856957bb9b80490d4fb6feb8cf4b3873ac404309337dcf90aaed450a9e931fd20a4082bd368caf05880ec3de6718acc386a191697caf0496b65883f88d56245f1a726c83d437440ea60bab71b1f35c49a5ea3faf2bb030254faa9689abf33738fbbc5ff6bdc2bdcfb11a96c5d6a4b4867cad151236b4f8c11d78524619e0634aae46b0609d61121225d84870eccc9976d6686415dbc5519ecd1fd50d6375a215437f5b0a1aecbb624a74dbdbe3279aa362208215173c435f50386e6e1d5074b6420ccd390994d442f4006da8230f6200d4dd20a9528030638191b9f009c7dfa461bcefee1ed4020e95204451e5056bfedc271473e016609309adcc6d36c6c0acc5d6e03171310e85b5eca88db2d89ee84b8c122d9cbae46ba0318850c3f20fa6b0bc2d44082118b23a0816c7c312fc86aaff52a57a93843fe62ddd71c2d5024cbd9568bcae95e97df4d2f61dd0171900b981437561be12cf4122ade5ce864913b5eef6a6ad280bd1d22b7b2ab21581bf8cf0812ddb8f7780c4723d3a362269900837f6bbebb79a5daf9c72c30516a484c23c5e0ac77e97acf7c22df568ee342a04c12f39a0bc2b9fa0ac31e532f15a54f18c86f6ec7810fbd8e59d4db6f370510d1a4b2e20f48912a97330158f0ef925106e11b66784b795f227d2bef0460ddf72b8378fb796519429fd0016ac045ce00d88fc6db09ff048998cafd38888939d0a09284a200f3e27f00c7f5d6ba986640dc66a96a70904962a5aafe1768644533dbc5ce35785471c381500ea8bffd0a1b6729e0aba174f31a306902c6626dd8e673c783eb391ebec219d0e12b444a28c337d3605cb932c1052e032c0ec3571463761abe427042d45e7c5276af20fb654c638a374ab6f10cdaed4ceffbde85d6067d8c91975aa0b1c006f7ae27ed0e36f80b246ff4f8111e9143848569668e8a9bef79dd6841f4ca2dabb9ecbbd01159d6f5a8fe80e167e8551d67c2d220577553a81a5acfabaedd9cf8c76218184bec4274ec59c56dda5a9f8b2e80157897016f497e923793b52e1a38a2ec85bbfca96d34f9bbb5f04412b038a3d2e93d0698cda9e2ce1ea258e1eb7eaab1130a1ad8674818b9734a8a58909f6a57ac514aa8c787bcc76a62637dea54f02893b02f0f7557badbcca661d2ac83fa2c133807bc7c52aae3efb134a5342e38628a69313ff1825798de5bbcb6653af5955feefe94a6d437cb95e74536faf3888e034b2838b671878163f3e2bf729e429272841dabb2861f802252f2b73f2809b452eef4f91cbfbe2796f5f8033beb5fc01c7c05651bb1b757a7741c667936ad734ef95c28ba1ab9653883db0d366e625f97110c585e015fbc00cfc31d9e6237c30de9d90b24852bf49d01ef8171696d37e6cafcd0fd76e90e871248f79db6dd5893cd7b9ddb0d22d85adbd550875e6f7aa780e5d2139273acce07d4882f1bb88831acfe680dafd0e82bc8e65854fbfa41eebef576d920884095b9a2844b05201147373897228f89fb4c82ab965d92da9ec1f294e94ca6637fdb9ac32c297a8dc94c14dccff86ef8b521b89bf52eeb047775832aaf297d1ae5ccb22e54d5167a70b29cec7e18316ba45d52ec71db154171892646f96ebdac38272e5bd571860f643a4ffd62b6f8a01c508088295f9ad3fb331bef9bb88ab3b9abc8e069d4196aeace59debadfeccfe273967415e03091c67d10a8f7c459867bf0fc2b38b0acfa8e42ebfaa4e8be1e0899fdf927679d8044970543e67eaeb58ca5c8a707a9226d60533634a4408403f90fb00682c22ea106d5fc94e6cd82af4b3870bb8a1b5ef0f9ac868dffaade7e67585a2349e0d9a945762ecdd9bebf940d6a3bfbca249f411b098cc9c7ee8e8165bf43aef5eb929d52aa83aa660f5f1367ea7a8da5ea00138166b551977b2e2f7e2c6ace7378d5c8e928e6d159f6d8f16e693bd38b1fd1bda0bf4ba372803e35e0e441a78c225ff9fb5806793d1a0dfaf2adb16004b234c7b99d1431e646bfb64e0b3e3106409913650e7c69e203cf051a5d16e0fd2f82f25a86581bafc65acb2fd2866a28530e4e21fb680ba70f01caee8d0213b9dea800861a885c80a01243ffa8bd5488b1bdf22c84e1d2500fb1bed5f77c02b201b4d7279d2bd56e648e6cba2b795c6c825752e48edaa73dfd129561838ea20d87a1971aa3c65e2e557263e5c74e246d2b773a80db9806cd6e44524a0db0227e4e7acd05173edd59695b635fd828b7556f09c3981df32f89b1729c49e11d2246626c37aefa2392e7498c55a304c09667c2db7ec8d3549487809ea74090fecc7a82b462ece4cff19d0193477852f8a2524830af7237eba2aab3427012706a051cc901e7472a4a742b262af4eae78b4234cf13b390571b0bd86f11ac99f70ec5600d8361ede56d634983221c4223936845c8062391c0dc8bb55d5566ac919afc7790108b624ac6bfa6b222b975543adb7fac5531b567923c3f0e55174d1773e5259f86c97cfe9bb3dc944d81b8f83e94d1b05117da902c28591363c079f9de720c085e0d5326d353d30fb09ab5ce577c58e51a671cd2a25a8b07b2ca5a9c952776520823b8997e970dbc6d4303e41586ac643d1889765228bfd60178da18395037f4c58515a67e6a443e1fe1b8bcc1eac6643d44bcc410dc14f36b196950d6303a91c9832fa2e346c2441eaa70fd589dbbd461e134da9bdeb2ce1b336b4f65cf78df47512b8d9935bd9458531a3fe886124c464e8a4dc3beb32e5ae7bdd1cee1a4d52efe47e263c649c9da10485ec065ad2ad13184635d69598b2a2d30de24dee51463d57f710dd6650df3a678733f0164df25b8d7c9fd074c04b155e30b823ac643a9033d60fe69cadda03de8ebeee41be44d08ae1ce3a42f76089ade484195a484309986e23ac42e0d29957e5455286993055e11faaad9d0f9ec865b6653a2f14b25db9bbf1ef178918a0213db38f698f4ba4d3cd0957270796f1a036218ebc003a848a59f5b257e66dc0a1c45e4c51832c5b15a09d8c55e0459164451bf0b19c006bc6df8c8c86c568796e6553403df38d3847b8fa6f603180cb63d4b01ab03424c513f9b1e3f01cffc6042a1aa28453807bde10b990afaf113cc2297fcb53a7c7168441ffb88ad38e81e8504050a5ca718e27122dfb4e8461e132847329087e22330503849790338cecd125f580768806fd48c7c2b2d6f0627eab517524246d7542e5817d51d57a8fd08dd06ba835c4eeba7f70518e124d711693032d52a8b7e577e8675a5927a631c77c788b0088f9e4bd7a3042bfcee79262c5f08fe370ddca4c600263b6fc018b611bd8671099e6a2028bc4dc4462db054f1e282dc69bb52b56e69d3bbbcc26675cd4c41b776e559e456e8bda5b4e3d955bb4d56f768c358c75e910ee018eb81286d30f44198e68156bc0130ef68f7d8e8b91a45b3370ddc68de3c6298b19e747025020d6d80fd818342750cc737f372cec20f7a3d47281d80b72c264919baef1125334d3d86a0de5828dd5de0e75967adb02d98981aef0f6e3983cc7080008078f2972b62cb696d173f9de2f52dba8680addb2e53636219d23938a87aff6e16ee42c7a796749979bac4d09e907514d073471f57226887f860cde28e14cf3c989baa9473a464a2815b52eb721c5db1e7c77c460a549f589c4bf590328a202c4e3ca7efe7ce5f3b38bb3cc8cf17051ea0a7f82d76cdb1cdb58038e7dd77f160a408ce56ca614625cfcf12899b2c65e024b929d3b83b1e80ecde627a6205c383eaec8ff40283dcb0d48c8f2b313cc9b066683eb7789dcf71383c29d7394083f9400d629a05af486de605e21149317006425115a72d9e6854091176375d8704747c572d174b410347106d9c5e33a006895d003985b7a0d06f19e8a8ca45ec3a6edc6fc46c4303823a426d3d29a4c20efec701056bdf8a3a934fbedc1ee4a146042a32e82fdf80839db2c218052c110f5de4bafb7fc08ede3d604f693862404c2298670213d3747f02dfe86760f42220ca0a7b610f2cff95ba97c8d2aaa321c58fa1584ee6740be5e519154004973b6b35f099028808dcdb239adc794b74f7230a2183d6122e2181e8832c7c34b07c58a7534f1d05c52c3321f15c1e853cd00fb275968e14795e67d9fc0bc3b35fcaf62366c00005bc8fcf78ef036fd921b50ab390112d2b89b4e255ea0371552d4033144ce62df04961f4f21103dbf2079438f08544805d49d83159fa95fd53ba2e132e93d942bf03a4053d28dcace06e3237c2fd0515863094f26eca0b0282da5e7a86c428063e8c47de3e2685a1b9167da827832dc1c9dd89d74573c86779d214697251b421f0d6383ec02570ce7ca256e2ca85d68c23f0ff5d4333441f9031ec4447f364833bdced29616764194ac14f70c7f663a5a43c47c15163bff1e029f531051a6b336a40dff1796b25ea4234d66bc21ffcd0cd4d273faf2cc65bfa72acfd1220faecb4db3bd83b74896a8f80b00f8044d56cb79b34008ff2f8dc82ffc229056a1e3682eb99aebbd1a9f9a9427285c015f73e0e7a142342eb674e4f129a2cc1b87fec7d715b6ece85446f630f3ed228cbe9804f0903e174be731ab3385bf99f6d23f3dc9bde2f87ab629baf1ba47490dcde9d197bc3e5eb59915ba0b7ecdba2900f92db5c08f62db1cf249e619ead358333c282af53d9b95b326f8f5596ed6de2c30f4d775a9f9794f27b3b3e6bd4c0e7ed116990c84d3ae3da5a5f88a6edcd58c2cde5b812eb63781bf0bb895228b919b54bf3b2ab6b1199a1f5f4e02789f714fc5190f50c172104607ccf52e35730905eab70a03e5b409612ee771ff789101f4f239bbd2c9d320a2048d109c1123f86d3cd29177e59e9bd06a45a7873f96488c756e274e152891c100b465728630eb1b02d8a3fcbb520708aee920490c13af8711c4f25ba253c296cb6c759576205f25f387bfc87cec08fb89e80fe3c70da41529ebe27680c6194e94c1e166aea64c68120aa7e819e9e95160e706a40e336b7e9597022c7bf87871ed2e520ac59c8c48287f46744f3be0a713628b9c024380ef3bacc31de351ce1ab0c0d241e06280f2704e823f103fb1d6d07dd17cb5e11871a785d21d36a325051004cb5ad46b28d8419cc7ae77384d8ea6352d4c2744194613f67c984057edb260074ff31c18551ab89e0945415d7e4a25c4f84e93d51c5f86a0f4fb69a70a03322274f7594ae0ec6d755fae868f8ba34521a1655aaf932739cc1a8697531c86a33e807979b8fecd9b61dc42343d4d3484c83951f34b41ad5353b3fcd129e061665c7b1414cd9b8915791925b479bbe3d0226560b6877a6806f78beb8b591a10c5bd280641ed6b2d74a59444662065d4b56d94195fd74cf8a1cab220cd1b837209aa1b322446f459b555cb122242bee3d68d6b362876045bebc33f7fa31b28badace88f3873c5f6143bcf0e06eaef20572cdf60d8aa2d7abde48a1c4221e58ad40b87ebda41d76c4c0687aa5004de000dcabbc867fe476e5b42cf8ba96ad7e78af31055fa2ddb4888ba3fb253d5e6ce9e6a47840d048008725bf8f473ecf85899e808739a889e770486071fd5ec3d1525783fcb1b346ca2c0c9eb96ec6824ca8870fff8b1c4e3240d6c0015f894722e50d7c4a99ebdec169da853b5d336e46c44b5f52b2608e64cdf278fb0a7aa49c963dccfcdd0eccc16281fc70c6957ef5fa5def7e3a6e146b316baee4509b0d024ec6f9afefe7d1c49a0e676bd54b86efc0ae38b04ec575a17d58eeec0e42dc97d36920824ec6a627d86395c60bcb63f9b91323b597bdd1be6f4afa229cbe77615d5c39246400f62f185be23d6804087a0d02dd65833e9e6a123ed00d64b76be321d757c9aabd459b46beec25a3db6f5d64575a8fc0131b1fc40f97b98431b82f06bd35527e6c5b48d25de1417f1c22639caa182b71bf7c289539d2a72eaf636da9c1364b2c429bf15de1af4b4b9d0e505eae3f09c12d0f9023250cccc7eebe2f295f029460d035dcd63cb567220db3070a660bc08eb1345e6bde0f858aaaa55a4491c1a31268c17abca9fc98647ad0ef8c3dbc8b3508cd6b2480d894868ef2d646d5b4db3405cd4e4c65a401114594a415723d2f2ca05f4bfa7943ff049e6849f8e4a31f476bcd3b38a9ba86c0669485d212957b5db6541142367b65e48fec751a4f5c215fe4f9e8d1e5652f756bd770696efdcdb26c38ebd985c5476989528b861a79b6b79fe193464ab182552cd98663d1108c38942f37403396969deb62179b03264c8dbf7d3056f3d4c4fd0336ca60905b7e2998c7449eabc7d4da346959b305d3be2f46367b07daa74cdabf7b7c0efc4041472c60ca1089a13437cc5fe3c1a16398f86c775f1417ff444de3e035a4b76376ca48dab56dc1d2ded5e89e866fb34192f3c04d986cf75abf9f5022544d783d361fc73d74b24912b0d89bb0b274f5adf90eb8aa116686d33a6a746ed37022ceb4c3b9e9544e75ed26e91f40897c2d663f4f88444123971018ce1b7988ff5a8cdcccc4937b122a0942d436cb53f334e0c3731d0a4beee9a19cf444ba9b0f9278544e3435cb643ee4a30514c2f51ab158cebb9b2264662f8b0788104b89c4b3012bdf46c7663a65076eb81e304d81880627b70e01233361c1f05c21221e85e48c53d708d14ff120a26a0ec0c7554bcf61ac883f31603b222827248cab9a2353db7b4579153dcadcbed6709730b6e55a13e5888b886297e5ab09d95a6353cd0a7447290c0e68d4b0cf8a3e093c029ce1cc4f32abc0cc48c5c81b9cfbed63403c67621329038382d075b98c9ad356657e0e2496cb2d5e6691227e661c8a1861e6695aa1191acc8f1383b3e98b690eba924cd91a48e15d4138f47988cfb1e2f00d7fbec0ac4209b51ed9d85402c6e318daf8dd0e07c0c8dbae04bfe16c9d4bc25625b3dd327b7b7f670e7f5ed3ebff78051c4f5dc4e09e4be861aeb71b0f08e0adb4db01f7944b87870c7a45b885084eff9746c2f8ae8bc97b56b6f8d2cf56697cdaa67dac43260ed068066e76564e5dc8757c878cae75035d450518beee5a1d0bbba506a2a416b72f64f58ce624046dc0679ba85c40fb3f063d9caa13b9618d36c82a7c12621f3922fa198fb8275a1604b02be0571d646c81181c62ef9cf1dbb4c8c8e667fa6b6e1077360cf9b81a7bc7b5e9f43d8b235d2cebdeefcd50d0426e406e08d68d4724d95b7424cf2948c346d2861139d74e730113454cdd0a8b963fab14818cbf37c1e69088d799fb31515aea4caf5797c122df087d023507477c93cad98dbac50267e8338c19b41c1e6c417d7fc05c902ed0be67fcb9629f47514ed8075c9c8ae8f3666a76bea8f942961c88c53d7a7865436bcbd3325d3f3af0913e94e237340b08aaf72af7599e106d437ad6ee2cd008e997f813210b5e4abf89974c75af8a5fd4352e4e2710a246285162e623a805a7be55b6c077fa3541ef219b2b83fea60044919342bf98284572830b327047d07a1f19b95c91dc2e0d2b0a9d6679401e956dd91a770b58756d57204094b58d552aaa8b14840b33d7eb3441299f0f649036f38392d583c98a6d5d65b7337464f1df2d300734802d98b46d6049a4b435ea8ba645a55cfda7f3f0818ad2efd7f974172e7d7d2e0f7bd037ce33c48ae08e2f0b5f9da12d7343e794f605357ef641d2c96945cd82ac01e7fb2b500694b6658bef7758bd2ac58b2ca3f8f15a67f4bfcd148c2747ed475d82cd37c52ccf49903f64e5a8756643e03dae80aa78b3f05937e3b8357cfcd320f015c8264f8f8b7a31664e2f4eb95ec6ac7a5a9f48cbdb24e2502bca01016d4c68c75e382a2f6e92e318df967812c063788a52c9b24aef794479162584c4f97fb1d091ceb764fb76e3d8493f134f81de23a8b76fa0cb420ed01f069cfd63bf4694fde646b08054f0c505794a5c93c879600a1958a836786955cdaa474299d3c244b7fb1687777cb1bb1d2c3c961ded618f476210387f927237c8e8ffad0edc67da2146e41990de6e94bb176f45473d37b72a0176f57b2b08e3360b208259f8ef35ec53ebea43bd34edff315bd532f637e947965ef3165cf9cd54f47e1d1ee8665615132ea4893851d66b79461ad53310c287bfa6abfcd0eaa92e35a255d413f97e7db7645fdea31ec800cf73b0514d80871a7f5d94bded2f8f1cf4132b604533f5e367040065c529acf4f82760573a33caafbf2a3157cd1e5b22d19cc19ae830918a5e3908a00a47d732067d5ab1032099cd9410f64d7919f0dc322279eda86b382782eecbf30974676add131af4e04a6774b1f46b30d8b286dee6279dc0e19ae213d912b07ea4bae5fe1ac6bf0a678fd60bb1bac8e2ccf8afd9abdbc35c90710f79cd6fb0dd87c9862552f3bc1903082b4de06a49cd20338b9d4080b2dc5f9a36f71720b54c9205ee3a77e9d40174a135ff14bf195be73b5ec4b7918ded011861de4bee706da5a41453951df5cc26987ee2407b00cc5071eb91a89b68b05bbeb0b12f8179d8662b174546f32adf2f85cb0ac08dd6e0069210db5594f9baa376838256844cee99f626fb4e77022415241d50a28ee9c91e72977d4245a9f7ed5cc202c555a976068e1719cc4b939fdfa7b8bd7146eb4e822c7291feea9c4b880adfe79a3f8bbd19820bd958cbdf03d4238de1091add8cf72649af3ed36ce97df106f401c740e006dd182b797eb710c05c7ed7b0f2515b599320c1e8ae961bea5c6ce06ff59c4bbb4feea1c10eef0ea73280c6be49cbe291915fb80cf4749636aa5a5090b8ea3c6d69b7a7d057e1116b79b5a233c840aeafa97d68a140c6deb3be067058f3e277f1a17eda8af4e4fbd802f65eb1bed3138c3323460cede507e26502d3562d7dd973cec3334a405bd45402a69124982f5eaa44cf5499f2869150bb31fa71a8c48953fb8321a72f0c6510398d0f2636441d09058bda176802a386b0b686d84938e085034673e4d97e6d698ffa5a52be02c3a0810b5112d6da9c23e6ce8c694da406f6c735a6d904b9bb3aa1c0050e6f7c1ee8a4ce13c0abd6cbd4bce5bdf28e113f209228ff82488c3034388cba43c42e7ef81f9ed88bb72c81baccd521195a76b5917eddea645bb9268f705d3158b454d8803ed0e5a7f96fbad415b7abf75b3d1328e318f5b30eb8d86ba399daf612a400c979186f60fb18147a43cb150f87ad34635ac1aee51633bb8bea79ea60ae4a177cf0db076d25a1404ffcac75c692c62fd2aa40a53518cb79704b829773253669ef61d438e67a3cde71b4157283d2e5c408ab18c47280aeeae2c7c119ad833a34b7d8f38b588c9681fd39b7960ce0e8ca147ea7357d6f96a1f97f087debf566b0d6c4b270852c20b56affee74a6a0d81f76e73a13943c244fa0aa370ae80d46a3f20aef9028ff5f60d5e63698a7850f74a8b928ed6800866d44918d2c3344bba347343ab3fc3326a7ac2ca50cf15fa66c363589ec247cc766b1bee183254823b2ab4ae8042934b324d96af3e6e3f2d22897302b7128f975acc973a3a9189cffa8b3af292d0be7c06cb72608b61b1446f6388ba75e9e23208f255feb58d6e4b66aea69c1b79f179825aebf49829064e92ca86ab1def055cf260d4b900019c3daf7471f727daf5acb1b9807f289c490cb90d5d8f81a3265a23b896af823988189a15166b93246ed294c18af8623169ab15db44532678fefd1d2ebbc29be7e1c0fc9219b4f53a4e87d414a4dc9dac09e6b5d0b3e6509b95a15d4b9d26450382c367a8fbd08463ec153c2662b9a5fa4fc06691b9a1e9aeeedeeb755cc0bb7573c3ce54f36087d2e6e7eac53d112d17948a393147366504453760c34290540788a28adc1e226cc2a91969343ec2a2e8c97a05ebd2173b5a1754f4e0a8bd8149788eaba523a8be8ea8be1ef09c49b137fa53a667c8719535ee5c6859dd0a9fa6c7d81a02f6dd0d1dd6104d2065d0ecaa02770c757a46e1e017e68f0bcb99adefb51c53fd7b1848d1cbdad768ddc78a2c20fe007cc44408d22e4988d6ca55ebbae8fffcaa0f086c190510c30073e9e4b9e6d6b455ee5d5753cbe47f07cbc533c161765213d62b153b419ae25866f0327c3d16dc985d1220b67b83914a5c2ed5b64097c5746cd2c5885d152c8cd3c342c7246174edf71bb76668a08780ec6784ab3427b80898522389f987498025322a8054b434786f59f7d55b85ce2b979c63c493362f5d5bdc635f0af8d04f19230159e2bf10002f57f894da70666ea3d82cc66f562702e44e8c155ef7c1e8097d548976ad5fd560899e08ae295d55c2903a716b10c0c4ff56376fe3104e55ead9bfdf17529a69bca270200696f3729cbcfaa15f276ca2d202c3b7a9744f45637998c0fd5f6e4f87cab4af1d4e7adcaac896ee6eb38f434e9c3f1175fda037ea970c7ffb911a19fc3684ab79599c384f0a1509df33be355950973cd6b6b96fdd7fa4adf3fe9da32ffb254edbc8ef3bfcb2a6d74e10355541cf4f5951ddf9d63fa29833d994ca83f7599e3d46f9c4c1755da36dbb63880dc95b63acf3214a99ce2e70636d47b399f7c15029bfda7572ad54556c8dc1b4469c92ffc2d2581711746c5435c7f64b47a5143d4a0ab6ab66356287499927c6dabc8e40cca1ec32876c0d0f67e690208cc92bf01bb28d53e8044f4303d342ed4bafb7ef7900445686fe73f6dba8fd847a3eaee87996c43ccda1d0426973283c609439efa266445bfad42b96776bf3fbb7e144ee864d71db99df3b728cd30dae492bfa2444a26112ee3533ccf7a022a3e2142bfedf9efad7d562fd6b60ee0639ec0d56a6fd7eb9d1eb1359c027ec7371da086457d04e2a50ee410c2d0345e0f658c1afac51e7f36b8db570c68f72f594d3364cc93f393253c0d265217942a1642055cc85cc7e473ad1e9a143b417531cd1f74a4eebaea27395ceb1ecb29893ac7f80e508e2b86a3ca05e2cb9852cbd48c3d817b9e4d43a1babe66060456b199c891af393395c9503b588e38a6edc9037cf993a33358714833806f7bc0595b6f4cd58ffaae22aed4be0d2a3383a0ef0855fbda6ce046b599aafabcf13f2d3e81311ad06fe4cb646135c0fe52e52786272f894d1e570265cef5c3d4398da80f7159a63b5dc0c35e7fcb538d6915306dc6438c7caa2105f2573b0ce02436449312c0047d30994c35ee9feb71e33e82a4fa93090de84b37585a2333f51e47dad8304ee96a1846fb8bfd310cef62059933d284e0e856bf2040a993844f3f586507d1dcaf28ec71ff80247627d7db1e2f9f3bab9098ea0c5980fea688b41790f5420f055a8daf67b8460ab1217d93fff9e2347e4754d3364c1afa06a4040c40051261be03ad27d06e4d3f4625bd2163f6dcd84a8bff028288963590412590e7f09be7fc02573d9ce79310945156d4e002c242ef3b5719441bbc2429f631e33f8f6905220318ff09da690e0357dec3edf39ca094142ae8134daac86e14aac1fb55a7f958c6c13b96f53355872b132b654518abe2acd763e779e9ec8a91f29206816938ece85d398cf7b4d61d9e8c0f98b76f762226d38e819f113a1d08ab6bb72b6e599984b445043af2cf70b8f782191597cf15a304b37a04543c7b404d170406895f1aec94d1ffaea12808283ca7530d3c0a43ced0dd42dbc21f292e0cd1d56a7ec12e9df83dc0883c88e2b9e28fd2a04a4c40a393d5371297ca3b38e11e0be65b89cdf2452a933416d27123fd4e916cdba013839e329db60a906dc788e0b4d1b62c2986ad0e643f7b82abcab1d63f83f7430acfece831ccf9384ebee7a42ea0e7c25677ba51ce39d086115fa67035e09a0ae05a741e6f9f1054532a573ffc294790683926eaa62c67108789de1cc525215341d8df748b78305b82db2b4bc37fd980d3bcd602c0e6373f19cb74bffa85db3c40fb807686d66ec57463737e0dcd762545108c1e405697a9f31fd4c74cff7a2c3249867315a1fb85f9a4db29907d0287353cbfdb600d2838300fb529374d071ded5de0d1abede55ea0342340f3661e99141faa2688ec460222d6320cd9cbc51e7de1e16cb3c81aae1f3259d14b0f0adaa5a624393796b562abda4841786da56cead6b43225d2eae13bb6f041b91b580c517e2831821cb5ffeb4c447f5f206176ca77805f41a1cb98d97e8e02f20b59bf7a4537d8f393d0febe1a3866e762b2b4a29f8f36953b915c02b03dc5c7eee2565212f6d132ad6cc932ae3a79bd28080305e8fd2aebcff18b4522805481296ca9cdd40740adfaa6272df1e096ec39ce9ac423ace44ffb68fd35da115bf7e6d28ad50d2d0ddc15aaac656bd196c466dc6e8ad246d77d316f820d186ffcb91eee475f5ed2a97765a6e0512dc6fb761053e5c7ce5487946a2755f0c03374572591ec18e9e3a0dc7437f428898e81663e0a14cdb16c57801303e881dc73e9e22df12b9475c2c1c15d8d86bf688380fafc2ed889178639068f9f3c5e07c4a4be8d5dc95a26a32896477e42444f2cea5e07544dcac08fc0e611b3a99cae482feffb7f764f4b74fe29a7004beb740119ea5378676b8fbf2b474f0e00116f6546a64713a451e6789e697581b0bd87a5b0d8c82e002ab6108f9509710214294a9c8c17112a091d2a8b8db887786d1a299fc357cb9dce1ef62cb15c59f1793c01b93dbfff63df26473cc986b10d9e8bc18380c28389d0ee70db41aaf1ecbef9ca5c3b106afb815b7bf1b8adc657b7704759d98b56f1e3fb3f0c64edecc796dd64c82d8a45171bf1a85caa1b95f7d83064bf644afa6f798e017da00b9c777a000f7d943cd6aef3a8bd828cc753dfdf8fca80baf95ac40dd596a669c08f36226fd118b791cc0b5774a3ca605c71846f9a9ef9da043ccc065f835f0f96b8d13e3061f8c3cca6dc76a09156ddee2078cb04f6c3f3d50eb76b4fff4c0c17749c8aa71c19cfee31f2bc8122ac019203d363151ac1b6f73cff543633654bda5d8c9e72e8bc8edc7b44f506b3c481a3f526bd08ef1760c1084e2de234a91184a9f1b19a6da786651de795252397c31bcfda57348c512698b52c8130cda8ee0bc0345f8c9f7526ee0b1cb7837e9c967307654e039702704e5128744691e18cd0222dc19438bf1c56f9ddcf96b277dd104a721699bda7d0ae3ff67198021c7c07b34f983bfbea818253992933c8746926676486bfdbd6e4bda754071e4b7dbd9d116309407743485af32af00d91c5eff5065c8dc1f8d166f4932f80e41b15f082905f84150ec624b09ac96a09ffdcb40a8f5bafdbd8e6cdd596b273bf8e2c6bd6bc7c64f3fe60cb40a20f1e3e56e9e955d0907decee9901da7460a29e2c7cb079f15be875420a60f9f4f2f902a2e869f484703951e44ff53fa4034e3d14ada9fb566b4a02d158d02c887023096d777b696a699c4653fcd4fefe3b3394bfb0df42598eefa9d0dfe56c8d71e767b559954d9da4627950a9761cd95defa04df8364bdc7ba8329d68e09c814a212ff09003696df7799d73f6f3552d0a005cfcd9443add81231ca4fe0678fae05261032625ad5abc6a601c5c807aa838fbc6f4808ced4ffccb5824b3ffa94b595e605f954fbfc8239167ebf0e94571395fac575e9a3dc8bb316cadf4d4a12f3b2b6a18cdd8aee508e5a78b31f2d9117c310afd8999aa7b931ae5ba068fee90f8741a3a87da6223047877af02244c5f6aa18fe055553620cda8d519aa14e7b830ca75ecd03b46ded1b1f0c74924ff5467ca993e8dd12f1bb7f465baf875818ca1b635226dab9d6c05d7464104be3c75c8fb7709ffff8c6e14c4389d15f0fd50feee7254fb925fcbcd3f822a88d4aa78a2143ea7fb69b7b308eb20496ad6cf739ff3fc034b2f8080cbad06272a400f3e81b2fd9bcf939fcc6ab0c3e016e5b855c38064ef11341e4b24ccc8f38ccd2015751a81a675621c598ff5d65e9707d2c4bfc5fa6e6c5214debe44cc292a24892cfb2862567002b55e49f3d684325eb32d109fb3267f12df9c7698a55fa26db2d62a4a18aa665d54f7b37f4ed90e7ac9a038c5e4d2dd3440e3f111886e7564cd80c32146c72786abe2362227f3e80b52b668afb4fa76c6644354d96b114d7f75424c467158b1de2ad9bad9158d97ad5b0577d5c0f7d233ad90e114cc6360b273da6c9cd3fc4eeab45765fb3afb662eb217c0ca62c705ff560a820a05255263f0f81831e239ee46b68d078cd95c2201e453d644b83000c1e5cf2bdaef0fa82e0dae568df1698e4a729a4c140bc15df941609f4cfd8b5c459b3cad7144f59d6e8e5d01f9150928e2888479589f25815e8eb33020022fadb8e83e66590c1e441dc5b311a37e3a3b1d8d8a63eef9a7d8fa1dfcf1c119a0e10948359163eb3630e01137dcb9677194e93d2fbaa3a162c9e4dfd43033b51caed432e225f023fa8521186ed1399b9b8d62189d6a5deb6f586305e7c3a847787b72b67f1811e59b1fca26409ab5871d7373eb00005c40263e96764593f66740bac5bd5ec6771290c562b90fb379ffd5844fcfc1268c2ee3ab55a752fdb192b45deb77f291bd20cc9c75da96b9d2071925300bf5c5cda570e1a809bfcdf6cbe0aecc256137b44b65f2406f4b8d895c2aa3889702528ee534eddcc4e31616aafca2e56fb556068566537fc7433390b98fdc64f15397951ffe7f70a717de5b56ac130d7e1e584b61cf89e1759e93de2dac5a36954f824d62e87f3bb2425b1452fbe423297fff6548f40a913da71fe9cc59c46f4c10ed73813aba477d1c3f0cf6aea8f2ba4f9f0439681852a1cd2520240b02e1e6900964e06689097a0273724a7f9a33d86b41404a8a09dee42eb9c65ddf3b28ff5d4cbcb5db3b290f70ff6f55efda0986303be5975e42753e6246f515598e6b3b5a293bca2a1b3d4fc20e463be83ecfbfb689d98b96912cdb65e2b667abe884ef3393f44cbc7e0399235c2f86fb8b949909770d51b4f14995505d701568b3d75c45db651f0d1e212c4ba6090155aaa058a9d50229d47c180f6901d929d8f35db96b6d17790cea6a350233e96fcc1b1b3bcd2d198ea054f801f1e45039b46104e2bf9387925d58f471b14d8c05a650282c09cca2fb02a8751d153a41f00c013872d5e03f491292bbe9d0f394ba1b01ea8b2122eeac26ce102d1912209d90ef7022b60fd92290ef5ba2ca4c22a050f626947d96d3c409d5f40735d1883218032e5c5de68627d107aeb0add9298009986273a800596aaf9c4525074baaefe8917a8765d1180e7fb3c78ff2ac3e2968d18ac3a8c34d11d94e73ea7457217c5a29315b0dc7514b63e0c053afd78caa92a43d1d0f194921e7d497ac4cb1b7cf094c59fc07c0f9eb282dda4cc3ee67ad589f126c96de0dd6c07a658ae3c86f1c89381c3b0b3a5b1f99c790ddd19ce72f31a464691b22a1419f04fa1d69563cd6dc2d4fe7764103588ca9a4a99568c31cd0f0682392a708d44dfa00cf5e1a01aa053ec870433ec88013913ae1b7f47d55d95d7b5c96e9809173c9dbae3e9aaa9bee49db213e0ed6f4d5a8301d7a8fe7b10b351efd27ec604dfbb0dd7e83fec830a47a9bcb8f52af80dd8d24324ec1e51aca0ec2f7cd6f5b0a637cbae9b4db09b63d2945817408f1d01d7b1972e9a159a7a11e04ddc84d0c83c93b64b44531f1b09ebd53c52ded58b7edfb21db7866de7d39a0ed9d2bffd5240d0758c5cb5a1725dc5ac81d643d1ec872eeea9c299c687054a5648b33f39b0abd1426e9e3bcd117c5af7eb9c057284028af6ed761a32b7c5c3d71819f04f460fb8cf657dd76514b7cbd64803d6af4896c37d39785ca7e1471ddee6be5a4824ec119e2eb52d5db4ceab52230abc4182d15209a3cd3ca350ce9130a3f290545aa0a3a87cdb7bc73891ee038513f68db8694bd526bde261416870e36ccdb170bef91eee2de17e624c0c6de9643888a42eb52b5492aeac7419e8301073bb3248dffcca216977965393ae89631a259d8be087940610a2db3b169438645ea38236188a4a3a5939170234c209dbc629be40990e3b2e2e544f57a2fa4ca646a8c2ebbfd00e771094c9c2683b93c0f8248d9d4f480f126bbf778ec2365c09ac5fbf5b8c8401c3315b77c83b6e59855106e7b3dadf536fc64ed4efe22de2b901ac605e6ef8da6a6c6ec7a56dece737f8a6b4c9157b0f25b04a02ee6aec636df13af8810ea9297e234ae7f9c7c6f9690e28596f667185f360e506dba10e18efa7e6f7fa4f3a37e6974b6153991bed5486dafd6b278b8a6438baabd4aaa4fff8e13ebb99548e8e1469461b78473803db5a031de45347cdedc43a95716684b7b0ced1382c1e5023669debb221f8e9ff39b740e2b42c71309cc25f51df50cc34b10fb69c135faa78e3326408b1cadd3e4652fb700bafee56cb475333580cc4a332a65c02640c19fe3f7740ac66f335d3764423f00ea323ee2167faab339b7d66b94e3bb3d1d556f02084d8cc751859a416695eabe208aeaab4e8e456e952bfd46818f2809a2937a1d47154f6f800071c615afa9494209c115e28098a6593c91a4bdbe8fbe6c41ee0ee2779ca1478d9d5b0f479c37b3baeb9fb01bbc16641ba65951298cfc069fbfbba53216a709fe69616a491253112266ba5f45f97c6b6b60bed29e17ca25efae0ff80f550a6d24b88c69a9eb67bbea4a5cc32cdda0af92da9dad35bc32dc3004f34d396a94d8ee99e112fb9c3c77e611e88f5f613d2a5c56619df1ee0ae1428343ba2a009ede7c8f5c295db3de4ef2a35e41b88fc7c95aec00f0896d3ca9fedb5f2b76f7ea85efd81dddf70998b673442109b126ea211f4dfed13c52087f2ad0ca0e6c80078f93e5cd74d107ff4e51bc899354a618c0db3ac0031de118284de6d17050522d0329e72450a2c47631d41b1dc902ac691842575c72973a786ee834870604780c48c3b99ee2d39ca394f3fcc33bfd1f0c2554c44a68e27550d179b885fdb0ae3e96d9d5e2293cb9ba78307d3f36bc29f17a0784cd621afebb27fcde6ebc829b497a7d1b6c0a5e8b4322a1084fa830d89670279a69562f2211e66e0a082a8136b3ec51342c1c35b93027383b758a27312e8b3775900de6aca6e31da24290053212c215221dcc4e629a18d00866b6d47378dc430a714ee2b60d9ab32b092012ea5e67d534760dfe4baad78f2758fcf5ab403fe8987be593d42e5132a55c0e101dd75e8d5bcf3655c88db017bdb33d63f36234d9bfb4624e900b7a61658a03eba961795783e1086c89cb1e25e1bd15840b009bf6a30729de753202045ef6fb25420f028f163b9d0ae5532664abc771bbe6c7512d5529e9e4d4b3a0cdf856f127b56df864769b9c113cd7b358ade8a1e9d73dab8ecbde52b83a11815fdc1bdccba142117628e0e0100a506ac1715110c718ca4ffc4110d1bbd897badbed87c6cdc9352cd5b7738a1148212f51d909e68fd235ae1b2b0ab04cc96e8c5c8e8ea2ac03be7dc53e381fcbaab47b0158d73c6632d12799150118af108d2f2d5d2113cb47eb6e4100adc76f0a2e5b9a01c8c02cd6ed7dc82298433d6c44a25db02f04b2292d2ec9075c74671a27c4827a7748a09bb1e3092981b484a0526a6990bcce0928aa23c60d64b55078b807312aae8d2d13737f22ae528b3b36468de09d82bd3f4dd6658d0762e0ecc153547aa75f46ac20156390bac745048ffd8bc2a6f331c54e327333043e873f26f1929b743fa018df9248584ab40690f03ddbe8cb5769d6b25b034577895f40df89bde708330ab2e1e968c8aff77a44aabb5685cecd1f13b3c37bec160b2635ecf2ca915e8a53c7249da612c14ba7accbdf3700f69c940bd2a568384451dce2a009842b8acd03faf1ca7f40a6b086bfbbe0807bae6bf46ce4082765edf73c6a8c5401955a9f381fed84dc440b7b372f2b7e4182d354ce3e9c1888196e846b318598d8f111bfe7158d6db6ff03462a0378797b19af2e64dc0fc38448466d985a435c5795bf21a599a0a7a7c170fb996c81a834867af93798d9808c135425485411caa6aa4b7061ef76437d11286d9b1da5bfcf24de22106cd3f7aa39f80f49f67b25c70b154c0835a32e039c03aa167373a5e93093c1a625ca4d625dd646a6423cca68b21d5ec55f43243cad7ac669c1c7b0b44609932244cfcb089c98f308b55a147ca41c0691b5690f61da69b313074ebcae021b15c523ca583cceb98231653016b505b3860f28b124afffb61232c4c173484bd07fbd285f96037e1ac74411dec403869ceee64a639351405ce7cd549ba221f9afdea816fcdd1926c44763470240541878ce3658c17b0f8974dba2dd41f7cd57a624e3931ba5870e6d355611b12a04c0727db70a321134dfbbd8d14e31d8617f4c85499eef0617308b2a377513b8294b52e4c4e37d6544de8d9574d3d90ae1749edc3ea3d4e95f0953a7d20b50db7f718d2973284283ca75901ea3e93d5045e14c986f33c4a6b8843a3db30780ce8f768593d7c509353a95860c5ad132446ccc8b302e6d2f4cd9adfd0f41c421c41f3414e2d1a25baca6d26bf56fccd40102ebbb1e94c6a6e3532635874a82cbd8a785e9445fa3167f919a934dcc56c48ac638eb6ad1f9cd12b69905af6a31f9ea3b2488646d6e5bf86e33421ae5ce05a7be1ffc8c8259be68a32a4243f656f7a8fa7ca2d3bd4dbe47cbf57247e7dd0571f6fb097eb4c0283199fa2b9729e815feb6d8f48b889c453fef026883a72eec5a0b38d17a17e1c901ff591a21f5a097dc85bc8dec92aa0a879ca484f21735aba3d9f85790d61646e56d012215d69770171a5964567b830f569cf01e34b8f56c94811dd02cf790a3d726d2d450113d42c14da5f18db87a2470db374ccc0100f8c136812f4cbe20477ba43e9ddc9bc4969afe892210b241e88e5699a8b7a07de7fb829c5f6f05dab8b9e34cce667be6ffaa09a3489f91dd61d4cc844a1ff16b5a3be37175650dc35773d4336552cb780d03604d512852f9b7432a29cf0fb7ef8e1a29ec8eecd3a4429ccac84b0bf0f3f7b669aed49041ba58f5f8aabe4eba13f0494884d88c9a1a7aefb44f34a42d99794881922cf04e60b754958236365a854ac8b4f8007970a2fffc3c91fc2431a04ca79a50b1a1a1a6b52cd44621e3c96deb67333524950c98ed0b284cc2040234ede7e8015b3ee14c815f3d3355c8cdf963e0958b5d5f157d0bbb48597c16486262aba711609f34885e1a510ff8296ac1fd62999cacf8b7070c04360f65d10f37d82c49e78c4574640c6f652d36de7c9d03de4f7f086e29f981110d0eb639148697f572778093a2826514f3ac36638ec3d821f92eaba85310e7a70943b1e243e7197684fd02c4b54b0fc04503674493ed27993beda08ef3d8ecd1e00d3d0462850310bf0db46d8d396bdf2fbd75a240c795791742ee922fe7f539928712d82a24f69919c712c0919e0135627286a908b58938fff79f16637abf44f6939e6f7c1e188be4aa6445666a86ff2b3cc66f1be1144e7619833e6abc875169ef2c8b2bd89c4e688af4ea162f01429fb84d99ccfe94f5f4382fe86b68d32ff77c555a38412cdbcaed63f22009006086124ab48f9bbe2045478e6017021d360946075a8e4b278feeb137681a7d09e16b9187d1ca4714d4bce71deaca3e695c1e463ed6eda167e7c8b829d91c3f43b178c911645961aabf9a3d751b056ad68397d0b28ee59c8047955990985063bcae2d61692c98dd14187c7a0801684dec1922830573e45012ff38236964fd643a67802c22b07ac656438ab71191693589acf3bfebb3b3992828eedf2223a23c2f21be63c1740488aa857d783f5197b8b243b0a95ae65bf86c90c348d4a61697a8c9ea125a62dc3349fa43b1a818b3a9dd8f922c9c68a4c0eaa7a4d7ad2ce0e85eca75eec4f4a81985f3d91e67c3425e69994e6a650db398449176293ea96eb1d16e1120e4ed7383605f91b62c644c24c00337034f504dad8a14e442f88370c408302c4633b068da3a0f6364f26fd8d16f866e89def2bccb73e0ba8e7adbaaec147f5ae75c650dc8b0c345f986f0c5f2169ae52f80ac5e85a84afc04057187c85d53928c62be20d0ab409f8b64e3563a2cdfa31e23c26774afeac499718d416b44eabc42d61d2a2979456fc847d094556f10f95c7e0ba9e7fd6d8e2a3f412790b7ae5ebc5c65c1d510c712a75e2ea18bbe7cf601c983cad1a4006afc3cfd0615a555a04b87bd3f856e39aa92aa78924b6eb67e4b29070dab2f4306aa9b0a051cceab1f12133bd0bc70e7bdd55fc1646548d8060ff41b1273ff2a56dadb9cec2a607378b89ba37b123e4a2dd88e1471d4ae588a96d45aaaa414abafeea47d1f5730dd4914f7d06e1af9bd1f80eb1b4f26f67f109c86910ccfdf2eabfa31a71c50abd0f52b200fedc0f505075c3906a1e235dbf848e8b110517628ce5b24bb1508c5c1f95328b02e710b9699e46f2b6e8af302b23a093f63e83b51a9972f350d59030eb6151bdab3007046c034d97c4c913a9b7a1a652f2e855e4bed7d5adef723a83fa1d8a5ce344466167d7eb75e321d5d80fc5fd7c5764543fffc0240d260bf31c6b8a94e8d1bd87eb72e1733750ae11006f0dc4cf01668573fd6d55707b5332d4439c4a7720c251fb0db8896fc005271693df1e836db93e83fbefa743b45edf5ec1ff5d0c31e3b8046a7e540b8e9e95d10281ac497e326a4d6e46891677a05319fda1711d18b30b7056f1eb5c7a518487408a50457bd081591e38e605f41aee4d8eca9d65bd33740d16f7a261cf994956e362881b426f13cb7df5f18e6cf1db53b3de17976f7c5a181f74e499f1a086910f34f776e50de4e981ff785d632d95323ec841d0197ae34c08ee5d3a2bd14379f27cd2760babe930ba3d1c17ab05d171ee55bd475c98df6d0a4edaa60830a569e9a35d35ad12cacaa5afc009f5c3db9627aad883ed88bebd26907a586ca686ab96f727ff21dcbe09eadcbe5ab42e553acf2aeca5f6b6cc33fde9fe60da1f56aed577ed7980cb42a551c31e19ee7b9ac5267ebd9a3b9d5c233b0386030ed35f664f5b2d7e98a623f82e49920b15bce56e0e109c91ab5ae588c553b0844c337dcd39bffed1655aa450fbaab26bf00b3fa8f1667c36f8ab30296e8a07370221efa00ea0ba237f67d7991d81322e649b5bc6243142aff2a5b0bc90ce76f4b00e4cc28e4d10f19d7b9a179b24fb0fcf50669d217a9498b05d000f213c0e6c648b0bba95435fba89b50bd8741ce2314dcd5f800c4ca1743fcab2026c851b49c3270d68c400a8894833e4d8af69ea72891e280c820138e32c8c57ebe844d2e84a694b1d6d327f16c3a857e050dc93a56820e36afa3b777a46d9105eff0057569870c220cec64f15c841757d995fb88d1b8da7c6eb47080cadd3d5b18199faf8a5732e91af1013c5147422f70bce2a1a5eabf4f2225402acc51772f3cebc4e7437672b18e3b2ba4fffe038f80e55ded79ba810d0318ac2518c458e1a9cf656b3b65f8cc8572f966f016902e3651e5ac64eb0f374b82996df07345d80d6f94edccff686752158b670b4f46416645cc0e92c5f7f06d6eb226b8e01e02d16af737074a855026396fa4e769fb9944dba0bf0b8692a41da01de63b5897cac7836ad650f6bcfe8e72cb8612c3147b6cf2787167487ae2280c5240e69e480d4ac32f86c6d474cf2764e480f420ef0ec2ea42e012f0a45d7b0ec83ad428b8c581ee657e370af58e6568a03968ca57aa702769460cdd7596833a38b27c8c0e2001a654730beab827679442093a00f4decd886cad52f66d8dd898ae35259e4a2a6796d681de69d3f3fa28679f8b30e022cc63b546d4df619bb9dcaef79646b8b0c95053e9b138c29bd600d3b9605064a4cce4b2398145470dd6797010f97d42f4e8135c0a48a744a430834de72b11e7d78b0f92487eb8e0a13f80843e8da27cf7e84ccbcc88f162421e87839f377b38997935990e8a56241448d516cb8dbd834c5b75646e72358e5d498fbaab4ccf94324bcdbaf0c3976363eb4fae6a578afcb80041ddecd48f735a01bb006b0d7a9bd2e49c22b538a2149716950086f3d1c7014fbfe7c56fdf560d0881e1e0e048f5e5c30b5f0e9041f5985174cc7935964b3280d067879f5b2b7de925595f92f358d397c9b90f7166926751981121be6a1ca3b0f2a78a7bad4d222173a8f7e9914546edc488a61f5c597da9a0e5516b55bfad53f89e567309868b13263eadd1d2228696084d776343b454396a95ba2c819a069bee49c032c76a66803f9c8fe5ef860fdf97dcd3e0e39bb7f31404d08020a80c78026514134645f7c54c8ea43061f83a99272c027051bd80a57e3352ed4d732a0c3e630be1549bac4cc4083e1cf283079eb31e935e1b645d78885aefd225f3dafa49daecf8c9a6a7c8debaa9f4d66e8e08ceb73f53237d0ac4f3acb68780e63120b4a272f9ef173bce3bbb73e7c174d6cffdbfa1813d393dd125644ac75640603146f3c2c2ffb0655c02781b397cd5fe9983bebf041ec9760abcdd8458ebc6c8d40435250e9250f148fe422cf6283c86a3a134c1ac0cba486de1ea8c8c0e8bfd6a8a50c46bc6210319fe62d14066809155b1b2d51aa6ea4a536c4f2019530324f4c2043a95a1b8d5274546df9d9655b59b059df4f067759b43e56d167990e0348f555d574b556a56c87da174b890019941bd139b518ae0ed2c3f13258e3b61f5f4b1caee9bc1b1a00530bd5eeddfa615105fc235f0e6c32626896b5c05def798751965931f31894f028d69895bda92b9c4dcd27abc1bf385436efae9fe374a35e4c5eb33edf59fc19b7730ee004f53333fd491fd53b3e6fcaa72ac2e223c2b09b27cbefcfa57252c24029f999c31c8081bf38eb0464eb93c699778c0001a393ff0ba80de5f291e4e19f760440e469bb39c01f8b52b0917867727e8e34e98073b8702314a7cb01ac174532bf016a2a2b30c7590aed3a1a12950a65deb8dda4951c63adc3cc2b81f2e95a106daa1d160321e43f0e980b0d83dfba4f9acb848bfcc89090a6d0721a712a4c670180703fb70a18f1281d6feca139bdf5e08c18d9badac864875d2f9c6737ae8a57befcc52a5f2a186ce0859f719d0b31870ac6bbbd44aeac4b646a181f83793720c8cc55bf8ae3e0c824d33a3aa08b658c7bd4a30ee9b85f418b49c85305973627b0ff4ec52ff49d468dcdf320813067e236aa42c1ad1215b18f225d9c93d2c5b356d39257d441c9f81cfc98d815d67ad691d82233b13bcf2dd177622afd1fe037bb93c340b4ea7b9f95d20a72689a6e2906cafee527ab219197b9dad120d52b4bcc92da61d1aaa441ccbb6635dfe9f73c5c5c42be7b4ea9dae76f59c7fde0d53d1a4c2fc51d08830ba412a57a60f1c54f7bfa411c12dd35596d90c51f1a510346f4d6038d22e3510302922101cebe7d89db4029d31744989d33bde8ef7afd0f4634c9a835ffbacae41c0407f64599c75f510b16844f21a8b543ab90d771f34176dff4c5335d9659057b22fd483f5f02e427698b0331f60409b40ed8f64220f8b439b43a35b7c089335118988a449124afac61fc168de930a2c7698eb59aaa4b625eddc6652d2dc03bae356fd6f7845c1f08c1504ce3e12a051f283469a2820c5155a58740075c70ddb50d4748e8df0940d103f0a083cbe7c7c1f5db12fe10991649203863801accae68322df30104162125cc64620eff520035f4ed533bb40d9cd2747eb213f4845970cbc60676f932601013cb3806156a1905cb745adf75d9799978011e730d13338cc97c9f49b95c5117a10d1e6c1a923288c5ae5d25f0c2c075372e93086d11a9840ad4968561434d951bcdc3759a22e263898ddb469480ea22715c5d94f25f0194cb72d45788267f9250d1caa8c835f175ab78848c5021d083be5c9215deb58ab2448f8b246d718d944217edbd1fe5c36fd04524509353a4a274c9f1d476894750b038dc9c79f6beae1b75a2c084ea3f2f6f8007053d138445dd8582264d1374482793fc00e3f0a872ed415d0b9af8a36a824a4a9ab662fa4b469b344985f9688f0000fd2ea9aec153b34ad102e0e3c1760107e415ada494642503bfdd102d40d3c6348ad67c036e2f023f3059f3e17b5b7fe24a2483bf0f68aacdafbe83ce1b938e9b77b13d14ce5146ca5758bf9dd95fdd4f69cd852b2af3966d613ce84111a193db4459c3c41402f24d48a01ffc6d44e7497071b503a144131966ceb15138d293f36a610d2e083dc466ac653914acc3baede8939656a2f804c079b809b7ceed5f92b681b2c7ac9590c125dcf85f6a075fdafa1243531d4b58e1bed47879696c197d15f21ea49215e6054902f86c22a9986c1c04bd59e34f352e16abf5d80fdb7b1cee222d80dcdb56c241f58d96c2e8249ed63b68a6e42da5373d34620824c57720bf6a46677a270bf94a1c1b6b5f64bb4b70dfb3ca898e4c860e4cef84a6dd6fdd390fe4f7915eba5d90b01a876ac4bc31a4eef24d353987cc7692c17572d87288611dd08606457b933c9e140d837a7fb8ab45d1dad4e2d50b3c775a142d9b67ab8569d13f79572dd82f97480c118e4446b600a011a96ab2ac35951b6d863e6b67ac366059450e7acd559c0cc4378e6a984c43140a2af9cc76bfd4564dcaaf2d44e449bd80ff61d090cf7cc7d836071ddc9c9b3290aaa9322b6cba409e1066de9c49e7e4d904b4c5ceb62596e7b4c367085bc5807e15e1470d2cc9a4096f9e033e05256306569be6b85d6b002d7370366de76ddc5dc91644ade90f7cde4bf15e3cb10146ba3e75e18d815617f6f1bf77759a52a0e6878a8d4e80dc17798fbe0cd2ec87036848a18586c6ebdc9a8b9cf12ca320e4fa5708851a043558f1cead17ce92c7dda3c6e727519216b19aabb56cb31644da87c8535e5b39553d28823a52d4c46db4cfeb45fd2b6610e91c07bfb9537aa615448b8c207f17653174f5800e0eaccf3957b061201052f9d3e9d53a8b9458030bc48d5da0c7b930c969b493bb554dafea307c59c482cdd13d9569dafc2e62e9199f5ee42ae52b78fcc9a96593f1fd2630cf6827f8d4fda9115380fed526e35c5a2267562ce748daca75a0ba8fd7f7f039d69501e8756db07d6daa8299216490712af10c188bdd66f5fe1384bae6249ecba89ce96df8ad86e0dc22b3c1b73a5b1b530b3a0311e7461917e5f528768e91a0866c49c93c9bb61c5e046bfa9982fd7dd5805405754d1a66bba1e7744f922720c4e4684c5dee325db77931ec69c32ff8da5c54d7d3ea204cf6fbeb2860748b6f9564fe8c51193e1747a64d75b366f816a6f21bd7df5f84a9c6198b807c90ebd2fcb9d41a0c37f55d0e75a94787a3f987b9e33cc511e0c7b9683048462c2b0a4db75a73054c99294798eb2e9c1c0d6311a66451a4ac74a71808573b6236ecf29a19dbcbf098d440443ea8510602a7751ae28ecd9df52a31da809d54bb3964d2903d66d0bd432d422161928b176cb7e3d826cb2b5f364a0ac332723533e7d2e35b081b0392ae954d58efb187c03aee092bd0e7421b28a0082dbff27539d54e2a091bb5df0ff2fc180ec29104677dc6b42497a3541edb6d558e8081350236b9531a368db68c209ab0b87c00dc423d9cbe6a8e7634be38dd8e8ed0a0b573aad1b4702293301d9236a185ba9d27d15878dee2008a86d0be6ac246e70f5927df29b57d14fd1f6c2b91d4562bc9593c1291eb02e64e433e2cbffc8272bec5fb420fcc2cd128f7bc80be0fb0cb8345a0e9602042c4c4e3ccdb11b1cfbe80449307641d441cacfbaed490bef2e0c9fcbbc96165bcc967686c3ef9c05f5bcb112b5b087283912302439e3a9e2a9448d36e96d211d87440f7bf76595b8d92140066e84e57cb84569758610aa7f1335020f84ac1da90b09f78c7b0cebc6e830c3183f7d54aea89865b158c69b715aa82a4ee4217c160db80a1b80122d3b37bd2d050a0ec2d389839ef2b4de1d231f070419ba3b4f47159d2e57052c2aa498c74e9bba86038810d638f67066724d0672b939958fb4055c2f7a079356a0ab96237e01356907f7bf260c53df0ce5adb8c604c013235e6a39415c00ecaba6564de8f5638f323f2d4b8fba7acb9d8243a52800084390def776e84afe194e93df98ea200ff1a4bdb3789aa5617f87bd4ab38f1228798f1e2aadaf0622a9a6f22c2e9f72f77b425c616d0574aa4bd94a716db60129869e5e945efc79a48bec3811763490d2df016241bfa1d67ddf69d16d8afebf5253db27be2546924af392672d7674aba0f1060af6783c4f42a8cb789198ec64e9fddcf0ded111f91c1802336e0c6fa78b0a9a851610d7eba5aa76f68aa561dc2a06468a2abc59ba791219febf882323eeeaad26f090a5ad72de4b4a675fe69adf5786d291a51872723c77f5475b524dad52d44dc750db8431ae9f269789710448d94073cc6647db5ac9dde954d5d9d2ac3695a4f96874840b8bb61fbef6e5c6275990055aba20c57b17ac20a895130100052daf9e3d6e0e3449a49cc13fce2bff828fa738738721c4dfbe52a491d8438b543a266ae5fa3a95e01092c1a5bba2d1f48f367c81f39765df21c5914209510232672e3784c328baef601af0f4e7f9363beaae9746747c42928ac210f5c757c2f5879bded13d89964bd7aafbe65b808a4904df0a424972532c14a44a1a3b62775ed32c1e2cd339297c153d8b5d8d0eb2c60fcf10b86bbd68161f0e487677acf390a15bd486f091229b3b6c79b59255c8a05aa34e05b30038bf69d9915926e8c86e12526a96178bf6c0126babb0b40d0e2201a096ceca041c94640a8bf8361082fb3595732c2c82ab951e2409481d7612d79c08ba3853cc721806f625d70116120531f32d3161eb559cbe8bddafbf21a179dfde73386b597cb1c9ca80cbb80254d6b5c8c9ecc807e82d5944747dc8a7fcc5958911456653ba41bfecd78e8b01fdfd2161c1e404cb090d20dee2bfa43b24690e0ec26dd8adf2d60b422a0d1caf0e6913cf0a45d35343b92eb230c0e486ee3f190e670d3696947f896f9978cc200bbc49bb9a9433c9ae81de821694800af06f1bb4498e722ef60a056049a63697b1168002d2115e73801ecad7071da9e8a62a208db5bd78378962ecc6c150b3e049fde9f4dc4a729e277e8c1dfee354221b735a1180573676cb0904c283b5d13a5612e31b71284eb4d270262baad3ee255dbc92ea92686804c5d8ed541a2fe0468eebd3e008ef273c08cf50392d7a18bca445237cbc9f54df0f072f336ec1e394ed9a4d4ea4ba41289ae4a1a2d290db226cdacae751836cf2559503a0418785d4402e9305c54da41e091064610bbe7abc4d19d6d8ab901462f3f0b480eaddaf88612db4b2020309885254fbb66ca167d1f44c63d3369655fa844afc6e5b6eafa33ffab225b6367ee5bd5aad86f39283211d6014abe3fab4a44e8a923d6a209e22ec171dedd00fa145a001225cd783f3dd663d6e7336b79ba4605222f0daa1a2fe4628b09e28d517fcb6696b5eb23dde59266fd3023b390a0f8281eddc8e2d5b08ee1342f339a433bcadcb72422fc37e4ff7ece0c91542d3b797b32c5ebfc1dba97e0965b9e6b2e734b9622f4a223ae26d23c969ec730580e3270f09c354d910da54dd8092c0068562b28996b81da8478eacc288fb875fa443525886630f589be4f1ee89caf78b43bca67f9e8f0a669314a60d50c0440aba325e17daa76cd8bb3ed1c26ee8fb2d0bf5263491d4684c445e78513a53ace30caa23fba022b035ccfd6e245139ceb9ba2bc3bbfb9e3d68f83948cc2cb439a4a900d89abf233ffe901741a93717ce3fa49a4a52018f33a3960921c0cae7fca3316764404fa2709d4d66b17684e4d2c4cb407a6528ab112bac0a73558dfacbdce9776c5110f5d054eb864c9006cc3488ac84886dbf9f26785888c76737a439547e2f66b069173be4ad4a42cc525c18628319676b8ca5c26a6b247fca253cc201def645237a435e01a2f08bdf68cad45a80ba998972e764fc4302f6d3acf36dcb0e87a187c369fc599210ea28c666587711bc597a410c58ada505d1fa005a2024dae16c8cbbfb1cd8c85bfc179c354d1535ec28be685bdc673ddaf4eed97b7628c52003712521a5158ed90e4200731fb736f30a809fd9191ddb0048b223fc87f1b0c61942ba5f8cf6f73795aaea1c15b0b74544ad6a7718ad966eede7fcc01a6d62d0f5d85334f79bc83273e8615306bcc7a1d9d46f66c540ba0d324fd4c64488e977895df5f4a06d0c81639f05de9e433c0f426bb6c67dc1d97d4bcd8f007bae04f4fc111bc06356d08f81395336740199f2ad73a723ee0a9730b522937595847ec0d9b10c6c2c6c60dd0750d8742ee967d15411f89ce3dab5c56f756ada1c6adf0e11f9829d0efe53326ffc2437d895090630ed8e7bffca43b1cddbba4b8487a0461d2882154ccdfa16710e009c14a3540e05cae4b3dd7140d218571ba6dd5639d9f3be1ab5e8df9500813e43125bb0f2a49b9e2f4b17e7cfce4abd38b0a8170fa091ff689c68ff29fd0b455a5336a53b2397e4e4d2aab68d167b8d6abaf7139dc69393f4036e5312503debf8bf18cfa72505706ea65869d6975cb0c88c456164fd9eea2cbff7734140d2543824765696e968af1a158f907800c8cd89d1ef8ce22caa71ebccf9517fce43e8389da02c2985aaacc5c0f006bc649b4e92d6c3315e0d2155f6e6e886a4ad5dd320f62f4189a7f169ae58c541e4093660c29a926ed6813ac714ac002231385b9974534ea5bc1a1ca0bcccba8a290504948e98dcf4cf0de328c969ba1213c2386cb3afa743666a27cda5529420d39c5ab4914c8dc64540af7e166cd7f42966d6f65b1e8d4c3ac9a39b6188ee2dd70b3fac8deb5c9a8f57746b54fa864087786eef92e43e4cd3b98008a40da72ea3022b54120890598a464e90b580975dcf124284a4a07a0d3221d9900a68b61c3ef3bf818fb3fe2b4333088d1ed7423ec595e28d1d6af277a86315d1531bfbe139b23f7553173dcf44eec07447b5e5bd63f3e28e337222128b4ca47f09d4a95e2b73ba220b82c4f89e03e695f3bdbcdc08ac026eba70497f7fb9eb3ee8deeca2ecc2fcb0c19bb97c10938d49c6e40b31759746103cafc75695b30d02a6e0e2419585fdb9680f25be68953bdd0fc9ed6bf765b3fe65b6c9fbcb167e9d2567766ec025c36d44b054aa40634d2070030755f5886f61f1b7cbbacc0618f66c4238341bcdea59b558627ba5108a58d9636096d22654a32720691067206a510b823fde527263da3351c85c9f53bd725db17b47160a531238346f679c6388e13b10c854a947800fa48039bb456a4aa28a5f45900010e4c2b8a23773ad05e6eb101dc07e9728b28f0340ba8480fc5a916a039dd84daa83a90806cd29af9abd50823a050e3e7dae7cfb5161a42a4859a964a532b52036948d554aaa3dd8b3d9292f093489f6752254ae983e4c58c52489b518392f43d2cd267c64a29c35692c87b6f6a5549232d5d34e145b2484595c8211555a46a2147790f39cafb08da4988e0d337a842484ae983043cc34a497a1f241f4051b690fbf047e22c1c4af14ba30f0842a50f121e48c652249b840fd342088d8682e72641da912158a447c890effb3e8ee3402745e1b65aeb10aeacaa0ae2fd63103030984d3a0b3d08c521b15814a782396a9d55a37a54f31aabad22973951f61e9a343b06062e65aaa514ebccde900557d5caeac174afb2688d0db0e9a74c1cc50fc7f0794aa4f8a4f0395605da74dc69d428c730f8fef5e571657540843dc37c8e3f4fdbb642f822b942cccbb4f83c2f2f92fe05971ee310631bf3e1af1013be0be50a3a3e7c1e980fc3871175fc3b78826ddbfeea3509ade907038331b3f6865e54553039789e07f6a017faacaa5eaaec5be157107a3030c9041226c78db11e0043beb4c80a54515e595db0e9af9d1fd2977e2b91291299eaec151dd6c1139866fadc93d65e2fc97f5f925a59b54cb3b3d34f1d94009b5de3ecb8c3d30557a0caf2538f25b0d935d683816bbf9a8d23ef39fbdf83206843c682dfd8f6eb784297fcd907c75c4f68141850bfb1bf45134eb8df68df1b4fa099fb1ade3b9ed0fd7603952329a535dc386e134571cbe7c2e71fa0613299acc99aac355993b5f685439099468a1ac1d444bc72c494f04baa34ea783cd2f2657cf9d2eb18f1e718bb7c11ddd536fe322f63c62e5f465abef028c3830b6054625246059ce3f1d3d285b234caf0f858366ea052a5f42991322a94fee55fc8232f5f22495136e91e4929a814c722cdea9c4e426d1c06207280d5d5eeaa6290bb56394ef1ddf5d977c8fea607e52610a0e5cbc37c8ef0c1ef292d0bcd218d41553acaa0aa9835bcbf1d8e791b54852baa4b35c8fe554b972ba6bb3cb0c8eaa7252b3ae98cd2603e07edd7cc36732b6aeb60e460ec7124dbc65fc7e81f23e2d767f3efad2fe34fe95ffea7f4f8e4287f1947eac31f8f32a4044082194226e1ebe8bd381a51fa9711e896a51066ac317b84ae22bd1bd87497abba5c2e5224ffdf5d2178dae109c28290163c1744877163c78a101cd785248a86cd8ed15ab3825a3b1d110ba8485579efef8d29cc6a774dc8a290c9747464321d19c5e92067e1386eab57fcc8ce35953070bf8e141c06c63ad96edb26d3b9332864518837f4bceb91bdc44f3784b94e1a31e454299009a049c1e5da26402350017a823120406b58ad2025a7927347e67119b2202cc14d642340f61f42cb4b5a1842e4c6063c84765de73d78bd053ff90b9101770e1f7cf3bba0e1d4dcbe9337d05f4158229a40c518c0a715d57f89a4b2fd6fbcb58520324df2d8d4d0cd30f5537f7f87202cc18e8237f11b93df701c97026361a660118a23e694873b6290f079f087df1f1e293de9e57d8e34e1293dc985f205b3808af4801cc779de756f0b3da8019bb456fa23e18b7f84f4a597e9e7113f7c17659a7c80f8e1ab20929854a144f67861279e208e46fc54a4b4e27544203be1d3cc23922179bb9d4aa46d5627095bbebb3b446030f31a95ed1039b7d0a47aecd43e17633c26d5c226add55aad71411c409a748bdc7f3b8f52b9228245d11c4a6d2cf8856f9ecc53ad95e36ee7c59820924824d248436b788218f16070d1f868238b6d73f721b7d6dad1b65a1447048aa3e383fdf0d3cd0cd8f456cbba075dec9a9fc0ff9e0724cd366a1a29761c9d53b3681b7f38284ef5d6e8ad2a404a7e5a3f4c26134daad56a5d1be06c597e6a2a753a61278dccc400819f0421ecdf2e27eb9fdc94697d5fc5a4187225d69eec0fd6de60c166cad48ea274046a80289c135355dd7821016a33d22b94308256924619354a1a62d263d263fc47c40fc3a731a2178c86442f5807c17f8b709750e0f0f1fbcc6451923e1c7da81433204256fa20b96b942412494e15266437424efdc4fdd643d4f4d533358d74db2883c2f6df6fef42a6de4b059828214f1f3836133f39d94570f11325df7b22a1a901b383bc51000cdc41de483a8b92457611850ef225ef2872c92e92f8c5273d0f267dea142c56a80cb15865f8a5777107f7484f34b4bc2a0a268eab8a6a56cf2b6de3f0d81236046db31ce55c77b3288ebb9348e802c358dd2416cb7f1ce5d67eb7d9eee9563b4a77c8308be27493cef2d38f122ec04a64ef38bfe9945075962c6490c13a6a56cfecd82c168be534d81facdd36bb6d5b8fed148415489c342ca954ca9432a54ca9aa329952a694c933997c50814d1a9ad50f2999005af0af6a2ac58d717e5a70a02306e6858333069f39ba13e64c751771bc91bb3b2bca29edceaaf2f2615ef0d825f832ba0d38604154821dbe8caec40913b11274da15598e6af83276961c8e7095302387c58712acbe6d4dedb66152f7323616b3368e4a985154c1599ee7acbbd2d16af5b6aaaa0b9f23bbb39eabae7563b56b5d58ed5a5d6beb468f0c5af3e3056cda2319d2d30c7635f40d103ff9d34ca97424b092fd372b688effb4cdb951f19bee65c022fb6f455bacaa1ca8a23656975f59543722d11e6df6c81e9548e30dfd74765de72feb0655bd90eebd5e2239024dd9a3aac2640705a532031cd9232abab383d29d22d941f94a97557a3fd2c457ec80dac61fb43de0d771207ed3d5d0a78e0443d9dcac9cdbe927df8a7e3a67b3826e1b163fdbd6cabe013526edd1d9c3c6c21863b2eb649d940ecad941e9ceeefc4e92c7e8e0c509c45a20544af7a03149c8feab1f3dfcd423370ebdb70848a3c089948d89deeedeaebb394bed939710ee7d1721c4051625920f7696d7237d4843a50c5b79c926fdf40f404b5af6986dc030740f1ab0bff921d09a6b4d3ec0bd64edbada754df332b2b6bbbb398e9375dbe56032f732abb458c79ae873ecb1c04c43c8fc871c6ee77d2cbfd97e86fc97de477c9812e953fa17da25ca9336ca41e2f7217d8e87217d708e87799e1c6493f08fe47898cf41c290474a0f23f300f15f9e47fc175286fb97a76548f2941e8694e1c89d52c7b96e75ac89825a49ec8d233f71f15ad3ce59a681b6138a45766bc7625d80624a6ea04a280ecd9e92ff6ddb686231d04bb09ea39e1b22ecea31c52aec75ef6a7523c3e68ae3b8186052366d17ee88012ed97e05a1c0cb91bb560d65eb69d92002283019149b7d6ab37a4cb5d6eab5d616abd4eadd54557964d73a756b2e6cfb8abda5cfe89caa44dbf8e374adc9daa40e55a21aeb1a4dbb3b4753ab7171801bd74351fe20393baa150471b260b35da7db342d6d032e5bf2973306c5f17ee382c492983951102222b79bed19d0d3185d06a5f551afd162d01a1f560f6da583121d7ddff781e0f7b5165a2346dbc4e00644456d46f6ef2cb4e6035b8c17689d85e27cefdd400d1ad09a467b42b485155140f0d483467b2902acb57a80059bddfac20f77135964ff22b6146e4ef766f3d03eac6a0a6791aaa29e9b28054ebc5c4b7ce0a195830e414d2a2c1c3bef5455912ded1e7a0b4a91aaea5685a2a4d5505aad86829ddcee5aafd5c7136cbacc96e028f79bbae5952b8dc73a0b3aa786f18242f692c1e04746ad5c80e2d4ead1513daa2a97a2514eeb018c16175758961462443102838b2b64b2d710af274e8eb0abd593214a2910d86e9bff0f534e907d0224c11b394342176cfe535a37cbb930a601eeeca3858f78e4999f2e1ad88b3ceb39aaa909501c9bb302c5e9ee187415f35cb0f75a5b6bb5b75f3e22689b23ad43ec882804f68aa04360d2a15f70626356648fd24f4ccf5e873b7819278753610d3cd964a22891e4c852de386a70628612493f59419519ca4b726fe254ea746a1a9b750ef75158ac1b2bb0d9ac161b50df44a1fef65db7f641033671eef7771185fe0ed42e5d440734f9b46d2cae5086a8370b067ac3ddd84055b8be3e60e16de38660fac114349810931893ef76acc6623199959999999930707d738607bf29d2e257c25cc68069f95c67b7d1a4b28e1b8d705966239b057403fc2c057081cdd4977bfce6662b380cec45c91d0626657386458f7e8e7a840cd90962b76de3ce9def05b2287a06564fa521844051fe211c8570cb28b8eb4a29b04c0e1fe4e2040caac8c08d1bd4a895fe7dd3049b74b6c2323660efcdd56c66adedbe214e2d4c45fd354ab4309962c394253b604088165469838d25a01895fe7f1219d019e526b78ee33aaee3b88eabff41dbe6ee4361acaac254bef95e10d0c0cef21bca04a895bf76a4d3287fc9664228aa9f4613bf4fbea4c5311c6b2a1673227f72a3602be816b4182b461b920d11c56820a0816d36c34c67465e48518320569252c7c34e015ce0da71cd72a12e8446778236414fbe028a728fb54dd10d536426846834a1cb625d17aab5566badc73cb6c54a5a9ae68122188220add9a82109d6799ee7d9679fe75313c8c1994a9de769ea20280a955a726e5c672b0e2d1a92d0d989c9a0374bc702f6ffefb802aa1a52518ed39ff304c5f11a8b298a8a865455cf664633a399512ba13535b4cd0d44cc808c78a0d1d05fd7d038df37110d04d0ec8b591a6464a1cd281090d3a0850315675a3fd02f5f1fc29d501cafd5b7074b35b07d57555557f746b6da956a9ced53ed3978ab0d4bda0e6ab55c9b75d25b9cabe53f0ef396bb825c36954ab9cb97a4ecd76c496f41a10324b5ca46e01a2443c3ee6a0de11d5dba74e952fa53f796b7bc257671efb66d43748b5515489bd22e752dd3b955a0aada9c5094ff935694ec0e6eb14b769456ee27731cebcbfed45b19688b6d318a43d439a4ecbf41f11bd99bdb99b7998f38b0b9c562f55e92ac5bac61b4a65fcca08b9b919faa938cf09e8a2af416eb5a5b156855576f6473269b1528fbacbe6e05aaa82d66ad8de2c5ccdd7bf73c8fdc6215e5bfc13621265b6cb5994cd65a9a542c76631805f556da2018579436a473729888629eba40b8754f36609d8f48a7a23148c10bce40410e50a8512b2bd7759cb55d67855c3140ae03aff781a7d33fc6b5fb38eff32ec61d773aed2801ee5c5d2c205bebb6d58a83ea5ebfb9f79eacb53cfe0b4cfdf4940d196e9a1e3f64d65a6b65e82a7107c129b8e260e06b55061ae5947629eda7e02dff14ecf9a7e00e2ba5351429bd1e5561805e12b098a17486ced099ae86089b291838a186093667c06e26b59540002d30c601fb30029b339976d083d608790c01fda3296d0ad119689c41713a9f71063de35a5aa447c8900f04419a10529116453ab55ed995f91bdb2dc99aebe6ba494c60eaa78fca6a15337109cda980ffe3ff4755350b480a26e8e4b2733c6ed6ede2b64547c6926dd1d9f23f6a4e321d0ec6e04e4e0b87bdc3607f61b5d67f8167d3612817a6388dd3effe7d30a6c33821ae09ade1849cc016760455796f9d70166661fd4e4b8e0550e00cb6184476877dd79885c18638213f7142f956ecb556eefc9490c4195a4322676666284edda2c5519ed35976509c1e83d6b8ed3a6b7718e1fba4130e4c1689fcc70407111bd48c1d9779ecb6b0ebd52b98823616548687b3678711be292f53f104237e0273c3fca6fb0e48a1525229146aa4344a73170f72c64f1ef880cd269ac944dbef9001ded25afcd4b419e07edab5dc1be1664067da36deeb782a95f25aabc552877a03fbdb388e820edae791fa1e0cbb867e7e230dcb8dfb55553d80a26a1553b049b3630536ff0343f0d690d298f0813404bf0f0c9b3459007bf4781004c1a70161b46090ec410128f87b4e3421fcb62ffcc68e5e0ffcfefd74fa4ee071f2537daffead0f7ee10e31f097b3046fef8d26cea68907f734aeb2253d2d20b573be1421018bc13a44524924d59798b1cb26e1739d43b7e812684d3f915a18ba8737fc4bc6f4c78c28eac351b4a686eb1c03d09c978f19bdc46397a491969dc3b58dbf090ba5bc5418b4f0302b49a48c0aa4203dce2845524605f1494f228fd08aa2549ab4c2e3096c36ec042be988e9b86d8d76833a0c399ae2d0fc793a3ee6c6a327ffd067a0aa1910688d0ccd0487a435ee23c644881393d3898adc46885ffa01744b91ab63771f38f61234097aea26284ce66305292498cc60dd9a1963c65b51f6738c30e10fea07c828f274a2356e60b361b01a3acc610eabe4e974d22981d6004961089122467a4822e8305b64510c799efd029f540ab82b8a058ea9f610bb5b6b8d19f1eaacce3c2eb6b7ecfdf77d1f4f90b6027370639c5ce18212c955d2a4f4dc874e0907f89180ecc2263d79764c2693098bda2aef5611688d3f95e978aacfbd045909b4865231e5cc29e38ab0da441833ad29c153d8d129dba696501b88cebdf75e9a5ba361a1d19c3664adbd1f057bd7d9e0745b4af013e7df9dabd7ff60947c512314193315edcbb78cb5dce834cf1ee8804b309d06c7ec8a5b794ba335ac9a85a2fc8f300d4133220d27c309adf1df394f8ee3ea122d0e8756abb666666a6ba6b666846899d9366ba308d1d2ad7a512cd40ad471ae560daaad1a54c7fae327252cc044fcf4e33df832558601a60b79233d763f7c15be17c923e091263c20e91fe9473cf23a51939b26abcb6f2a48a9074a60227e7a55215ae34f00294160227e7291055741e75825dac6534071eab75cb5659b38149711f98948e5325691131111715bad9bb5db469403ada93a34ca91a811610404cdea5099a0383954242a1140b46acb555b3fb886b0d65a6e4ba552a9542a956ab55a39807801a0b23f9014a8a9aa3245b9007ca400d7375395c200571d994c26d3e9e2fe8eec0fdefc657a8a0147767f8ae35d67ad0ddca97f9c0bcb6b65e0cfe70c485151735dc76d5bd76d3290451182a7aa0a491b8bc56cccda6de3429b2ab0c9c52c37e43744b1283476ef142aee0998c44e43b1588c28e627ce6bada713278bb96f5bca5537b6c3c24f36c3f30c21683387f1ed799cdec8feddf6b96de3366edbb82d95aadce93928fcf0c33034014e515bc4018561188661e84318d22a9cccc9a13533e33ef37d331487547ad29bf4acfdc168f959570d1af82353defd5e701e4bdac64680de7877070ea3168296a0088a723872270104ade9a2767945826a1d94aab5861ef2b06ddb17185bdb7527ac563e7030f9b040b150c185a2e1021a069d41d7eeda994ca698f712e2f5ea57fd00172e31dbb6c5bc86f07c8413caa4dadf68d39b8d6c18f78a11bd6046a0d0177dd1fa30c0f8656d93311bc771d6721fd0f10024c15c5e2f2ae018b5fae0025b8ee32cc759ee69fc0c53ad2653359da6544c4b7137ca5c0d45b2cddbddbb992a69fabc60c1df834e858a4bf113955b44a5aff8e99a5c80ef69c5179ff461e8a77884f4e2872a905e7c2aca5c5205f149e03f809637c8d5ad9383659f99ce323d66c4b3ad323b30e0527c5a6e61b622b9599a9f343f47689a9f2e458adf746ffa13f866eaec21244d04901e6c95fe6be1f75aad040a4c8069255a9f3404e41d1764c1ddb66dab13f4172d47a4f168b5dab61d920c51ea0f522366970341b03d4f34c103de1bb9997b0dd0ce65140c804c4de09752602e7f0f7e132fa8e2431155aea841e90fa648804d6aa548ab5a70213760f3c70e05a0e0fb9d078ce06c7f7bf08e1c116f4ca101d4e6874e57a306092ac095f4beefa3090959e05ea2deb5de53db31619c3b5e0a48a2b5dd752fe025230801cde9a1a44684631956fb6bd795ec4a95a22b2ebbd255bae84a5f91c9fa4abbfb518f5843cbdb1105aed90ca388028bd90cefbdf746d1e16854673a34b8d1019b94560681cd6e5199ab36d1cb36222d0ed09c0e82daf8770ea5bcc44acbc711241cc9c26c862e22de68441892426e495fb08ef3997571f31b4268b48ebb5c27c40c23d6ff735dd7f5d8e169b55a2f2d7809d1d75a5be2803b9bb65a6ea382e4e96aedac7065c856b002548366ad1e3bdf093a70a86bf821796bada74ee9965223f5f0c33777644a222fa5d7cf8deb8c203dcf5692481f24a5f846903e1c816e497ab034760c5c600e031162bc4a12e83f586028aa3164b105c8c220c6116d8b818a1f66dc14326451d44971bd717940a346bb28c112ac6fc9141a1896c6d6218c188a4ad2388018946038460d8ec4b034f60b5068889524120993faa7a8a204b492347ed04609fae8824d5b1b82e67cdbdcc03aefbffb7edad11a91416b40d2ac42f5456bea10d4c6ff23cd5a047949f39e155593e99ed6aa2af41b1b50d5539c8dabf539e42a1fa74285c751fe3c78d0d0d89ab9326d4dc7a6aeeaaaa2fcb454d6e1771886a49f1565b9d8236b6b96bb24c7751dc771f53c3fc73fb125c02322341b65bfa9141eb1a9a2aac03d7ab4a6bdcb030a36afd93b64b383b2374ee7ae5fadf5dee07a3be0d8a15d672db8030e9cc11bdeceb144647f97a2553d8d7230b8e82b4c4f60268e90b835f4cc75e899cc0c582663d93ce3c266d3da0a6db53275b5b35dd7d9af3361c71bd85cb5ec7b9174578d4255ee79501bd1927016add9821ce5ef4968bb6666fc4423c108d3642d1b8e4c5de8aceb59efd2b8ad5d2d136bb40c998cdbdc067a829716239ab3685dadabbaaaab8f032cbe7c02ec4f6d8d016730fdbeef1463b2649c5af46d1d1fdc98d225639ec034b7076e29344fd09e3788d48468e1995159aa07a558747cc04346715eb265e532284ef7352ed96f8f761be98f23fc2ca0223d2959ea53a9549f5505634619345c11c48fab8849d01b696cc966cb8aec17f44c43ca998695bc86944ccf3586c8c8f4ac2529e228bfdc007ac0dc8377003d544ae9d32ebcf752362a94ec4fb96c323564d032f155a3413ed5a092cdd672ca66cb6ecc5476ef8b5376ce644537752fc626d3ff69dc017b1b29c2047faef917190373b524d99fc6bfbd7bbdebddebdd5b6532991012a21843e53acc5182eb7faf65a4d98095b0b6bb95b80853d01bae0a7ab3a984bcdeec99789fd658268ae996c7887a0a2cbb4824d2a76ddc81da0d925254488e5122855414c9c51a6d78d15d641f6a4617d1681c26136976ab9bd84edbe69d0345792ddc2d6aa9effc74cd317955c5ba62bdb1625121d381250352f2d3fa61ad5806a0287fbc45ab752fc626d38e9f7af058d14b60f860c516b3d96ce6a148554328ca3d3432ea51579e370b0d200536a9d1d7f7de6c276eb6a06ca894ae986c1632120000020504c3140000180c088442c16058382619eeb37614000c5c7e4282643c9807a44918c34006820c42861903000004106366086a8a0358cbec775b8f0d626f3480865b10b1be4ad2505a10d71934ca689067afd2d3a611b99b8ed140ed30abcf1a9340e3220eb917cc5ecc9a2ba0064c4be75ed1b23a40d821f6b7e9f50f68302da42fc88b018374cf72910b0a2f0fa61fee615be109172286b8788f7b149c42c65a59614d38e6c5e4d2b46ed53eb13d06044229ccedce6f12002b522e3299c4c53cbde2361a6dff4426a66f69b52dc0969cd416e0e1e1e089cbae5500539514460b04257dd8ef59bdea71b145125bf05ef3ec566eda956f20c2ba3671424ebd10a40adbdf8ba21b0a874c1b17c27880a75530d5a1790561c13438e91578db3a04a6027f0c5d8b7fa9602540d23685b59c7f635ab047fcd2f2d738f78b9fe563992459f50b2e08728991a75f695bdc61cbb8855485be4be2b0958eb7d80947187968f64027466e4bca730b671ea8e7656f1e5563ec07bef012f7062d000fdd5548a08ca6a9e89a4cf34a6386b034b1a4b4c1769d1f44c36bc6e97928b69ab7a4baa48224dc4f982ca3531bee6213b1e76fa5efed4eb926b2d01ed373a692a7274d2f46dda1876508d05f3f0de7770fc3079c216031e6d3d90f49813ba0424bdd2cd678cd64e8fc2456bc06e57e58c55fa8e18fb12f73b5462b5bb79273c532cfe4d70238307c6972b539db0384b675dc33b947b7d943c068047d52aa10a648d7b6c698ebf93935fd16196828220fb3c835dae76ac74a10ae25792d23b3555ad11f6e3ee667b64e49b03c1a19f880e15c003aee1667cb74d9e67a78917a6540e8b78d6c94256e4af9b2c148398bd2ea3f85651a86acfe0f794fca1d63918e1a07303c11631b87cd9657e236d7020cab84550dbaba2645131a2717992db68602135a9b158fddcbef84280cbabceab751ef874a25a246af5e91c434a2043b20d2eff6bf3531eeb0a18f74d4c55e7612975c62cc70ee9145a20dbaac5c714669df8135a5f374a072ba1848d03935d4464b5aa717cfdb3b6cbb1267108b7bbca68b62415e80dce6a9459f4da11ffb895fabe3e024c2af21814ec47a9facbd28eadbdf99411f087307302de10ffc39330c2a6f2b2b7d722efa9705c9cf507ad0dc5420375554059adf9ab510786b733b0b92745a0d41459f274d068ba93b28a4a753f26684661644edb286a21294c560f91263677164f896e27f65ae6654626ea67fde3a6a0026cd43f5294154332a6c26b1b09ffc683cc4808de0c8ba666e4afa61c345a91d376a3719b0de722988b10a659f3e8452f61237150340318964d25cd81818bcbc856c39e1c0a71e5dd8ee8d856e1bda05ee368fa4a893d08597d8321241acb59a72ce50e8c267f44e8b6af8dd93ee4f81d9d270ade3b26b8542f218e1a6d139a8594831145d7b45da337132e44ac3e39a19fdfb8016c0a6df4dd7bbbde53dcc2766846f74aec19e42b3da53cd88583ee28d4722b382884f8dd22ab73ba85fc46dffef1ff338d847ad56827b981aadc0685e3ca4165573981f74aaf9749ca8ba8e5b0444391554a99be3a75704b4343ef561a90f3271aeaddd8241c5560d69ed7c9c155870d85d7258541fe258dad6cbf74be79b61105ab6a26554a0523430edce963dc72409e8423918b397e379838d52239c4de18448670a2260214a133b6c1358d0c47fd0b19f9fe4a4bbe9fc1116fd1b37f56c3aca376927f95ecfe1b533dfb4b416da4729655033fe18a046236570f7c7f44e834ffbf03448ec028b7b0c2c1247475a424ae6520f36fb7268e9d263ccc3152733c0254d1be739fbedd39cbda55d757cd4e1db0932baf90d420609a3206d0685305e1410bdfb085ff79e5753c851fe411e7b0c12dcf116af5cc4731db1d1fe067451a40c497cfb44ec8146f25fa1166e5e345f815a7bedc543543d23d588a745d61b52c81722a728f048e28c6b1932d3482ea952c98172d9bb3d6132b0990f24735871f10849a51a939116e94e17939d69cc9f0a4c22de51fb652cf138fbe52b017ea6ef45686021ac87c8b484513214de059722e05b27d160372f480a4c2f09657bb65a87a3b248829c363fe1f9224e14f3749d4eee3b8a0f5e964018cef58569c8e6be133f24d032f467ed9524435922650a18c33603233271f9733b9b2238ac24773b9f0f7fb9c436058dd919841a7962c1c5b628aad549850230bf6ecb13ffe045c794a6ac8b1473101670189fc36e2543bef753acb81613b4f7f33e9bba42d43bbd95cdacb97c54c0871e66b8416dbd699e916b7b215e018695e758c23b87ccdc3c200f9722f6e6c35c4baf48341f7082e8f89eabbecabf7825fb1f7b3d11719846bbb84bb19c6e90c764d1b1c30234c3df1e8c91fb21d3b6802997dd94b06b1ea6bb5e0d0f6abe3ce08159d6ad6729639d51ecb350258f0d38dd5b52d0814cd64148240200254ad6992cbc8990f6349cbb079f72317e78711491b623bae32c6d22316b4dced9112ebf59912ff5ae318fe1bfc6bccbb88f8240f824d7789e92f8f24302c63c4a87f5ee3c3743ae92ac0bcb9c205a83776b07c09366c90ee8f22fed8f8fa9758add7279794d79b49c003abe18a11dc729a31841a9c56423fa3c6975e58429706ba39bf6724ee292e439266e3ed8b4ad0c9ad8b35799f69bc88a31bab105c45be7f1aad970872e6df4e98bb630f74e5bfd7878c7dfaaa45251a1782ededd9f64fa0dd4aae5a12694d5ac653d9afa9d9c312e38654216225198367abba5175225252d5fce7e514663a86c658eea81eb1844e27f70e6b40ecda3a561dab267c13fe8a62811eb374ceec6f26a3e0a8b27484fae4258ce1f3d95187286d054ac4c3799f0e1c9dcc960518eee0a4bebff25f7697f2863481037fcce4dddc3761f83bdcd4719639b7ae2c30a2a93342b16867b6b33ba218b596e03942947d7b948a68e7d42ca5a89dd75b92537b16002f58e8842f5114e5708cb55a98a0d384fb3b26776f48ca135b3288908085e80db9d6f2862ae83c21486ff3ad6b75cc86abb34974c6e82bb63b106ed2b1879f113cfe0c4809b9efbb279b61b086e9ef0aaf1e61e5b534953ba811573b52771aca68bcf15f454dcb35703c4fd8fef3bfe8dd0d96768529d20e13d5f7599442a111834513ba9f81a2a872d4b829646715c6ca3b712eccb693c767cc59a736f47d19e0ff23d7fe1a63bf0a9b904be2b13e445059599d6036ffc20cd2a7343f54f96b4f9212afe4fea7ad2087508d6867793cb22f34e1a8152edc74dae9652aea5233e4e6ca8baf91746803e2bbeb0f5ab99d10597720cf562783392ead54f24c4baa06c820367ef499658ad7789093a4d5a51671c35bc38a2b635757cf4ddcbe05803d2053795c5b03696825f90182045bdff85f7258eeafaa7fcf4328d71d66b4c8e00ddbad5883f380f443531143ccc6806ca9fb8afb984b2994b46f1c0c9a0e0e43eb5ac79d26f6da811987ce7c22722ec78b13b560fa4023fb0ec684c66e532bef6f4d3458d33c608b59324256211d73b7767cfdf5499475ccbcb895c720f26106203989b4e01ca3f1791b736801d80ad14d56ca2942d657d1351064c851c18c0cd42531ffae5b8300fd9f9216034e775f1afe55af78ba9161b74150b74bb5fe4c45fdf16de4820e294af3c8723e2ffe3ba2cfd97e58e2c2ab15e248700dfe7e679229d854468d1f234ef694c1acbdab9d332dcef2aef9f076b1d35fdbf057feafb1eccb23ed99dd0915c95320c644678d46ff2feea13990daec15d8f8b177fbe818075a9eb10171e8720f57f3c6d34e02a2b31990ece006465a4dcc1763cbdcdb71b72ed44668c2c16e6e5bff74a6ad23d356e8b1ce70e375d0d866cc7841b0469fd916cee05f05cdf8cee7e3ba8b1b10e217c750b51d674ac2fc9449494d65864b9f0dd1a47666446512dc9f7a1a8df99438f41f8029ed48dd494650e2409f2300d30d0b805cffb55b39447325b8db74929a3ef550ce6ba01b76ac91da17add2ffd8b3e47a026ad4dca337609674adc816acfa514cc68b13552cdef987c470d0bfffdba59f8df88013d467a525d62b361994f34d6a09855432aaabe761d6f737c87d12ab15ac501a86ca6e59def1d47bd02c84a1e683df198839098bb7ad62a158de6361e9aefe7329b1fd0a524396c7f56459f1d54075fdc88bf58f35d2d14ff3ce82a623defe13ff94fec8f2fc7d623af6d76dd2fc6bf8e8389e061a16ac0bb179240af122410edbf92b1038f98430c1d79390c692938bf5dba602bb9513b003fb3da01b00734348566d569c2e0d1f4706a6fa718e280de514b2531d6de84286922cbc8f58744651507b2a13c916b9316a94ea5b1ce8564e1b48bb6a4f4021900bdeaa1c2910265ad21ef9a6568255ede454cc24c3ea5887e74d65ba3d4c2938afed12ec7225cbd478f9191018c44e57d8554a209a8e2930b59a130efe9beb1adefe5a21a47a8da2c87d471e30a558898c57f8cf3b930d7b0deb4b3e12ff15f2f143ff5be640b90aa64645a40c72859b293645d0895f57db6afb1ada1857e432dad070b4593e4a56c35830a01180c7154d08ee9b60b50b481b1e6074c0a379c67b45d894db5d04c91e1eeae16d271c6eb6623760991b40f141224e6daf4c5dacd8024762a4483c8ee35707a438cd4ee2bc7dbfd9b29037a74116b8558593a590d05656ba2c670badefe463967fa54589b261132685af51efd6cf6f3d50ffbbf0652faf146714c829d797e125714fb1a4fe6785322bafee52315b1e473ecfbbdad83a15dd4bf12d09e1b3304bf2d1c74d290bbe769a03ee1b09d217ed6adbece49d1b7cafede5a913f6cf44962a99aa1fd4627456befae9f370b32052b370859e09d2486143458082b64b0b077a6503e48904b98396fd80b835bd60c62fbfd9e22194c97d6e472c9d68788fba2c298c01c9f7605a43930ed68ebab620a9895dae330e74f5849283bb3cf7736fd053043c4fc4e54094dd9c6031da601bb0b66bdf691ba9352fb32923bfd897ae7928170beab8803067a58cca3848799a88991e02f9b29f110179acc9e7e2b9fdb029521ccb932f530d7c648b0a3ce8f057815ead4300196c2dfb585e204d5838f6039262dc24bb646e78b465527484c826410133bc558a1254fe6f8715b3ba93f858e3049bd34b7d3a88bca24091868997b13c1cc8980173092ca0e85a8cca06189ce48d5067e30253a61b6a26725e4f5b98083b69230333d84369a1dd40ace7b5154d018348f912a5992f941f14fabe7c983aca8779e398b368cebab0876596f1e0da3489d30cf0e83f94c76d6255ff6159f90168c9fe0af3b78c872484446de221df94a83faa85a676897b488fd402bfad0fa8e0dea7745cba0f730c230dc7a2b5076904231860561b13b119d857e578f6b0d21b02ff7f48cc3440c8f929f019c7f2b611f3cc9243dbc06331f511cbc21618091440e610b9c3873d77271a6dc7131b44c93483c459b9010b28fc8082bd6159520e51ba477d948560e58490875b646b589a3f4ca93cdcabecbb84aa778cba7526901baa8c571b05ff3542f73748312c6297d6cb8bbd34aa16575a3d458068936ac40583cc6d61cea2cde052f093b527a719ea97f58a4d8c08f91992b37f546ec5cc5aa6461256870e7c8d4e2e53e0b0ea52260d95cfc20cfe31a2a1694d60c54ca87a84304a6f9e48d09ca300a52f3671b818c8a4a8df2e95984bf2eeee04bbf732dd7969ff106ec288d21c1af703bdade72807753995feb7fb3a9579a06d4e5c7dddcca926662dd00642929b0c0490f356ce5d2c6e5287e8d27e1a7807f9101008c94b0d9c0e1ab648823bacbcb8c73aaf0fe0f2d3faf2a4cd0ccc74d267340b806e099de67101f9a7ce41235b6c934fc747fdf7b4db93180a0fb43a9fbf5f6bf762a0c025df854a3c44601e1ec5c07b1af33f5ac26194e4d63efa51c6b6ee90954f4dc3236a46980262099a2b8460495538ccab8eaf291a06a17544ab9222ef162c790846441607fd136e4668a954516fe85d7939848e8fb37a33fc08f333a66b095db8c098e9bd928718a3862308cfd0beecd25f0b887afd7e6b5fab7d6579e360745bce2dc4a15d257723a62e5fbd11e065a521a21f6b0dc48fa67af65551f1f337afd57816db04a44e8dff9c229cdcd58e9fbfe8186f321e1385b3d0f839a954ff5b0a118c97b096eb7934a92d1251dd3794fc55f06aa20469de2867705cf54ebd5f9fb614043bf7a31e626da5dc177e04d59026152dbedc8e28bf4150dfdda1bc9f081fc56ae92543e172fc78268fd77dbe48468410af12e17098154ba21a7c5bd6c7e6c235168433d3f62ad838b5a133646e5bbae91c8f3d97612580be6958b2965ef0f58777e0ab89b0f185e3b8781fb77c7c5bff9c62ff4c269741d99760fee18d638e2a164115cc3347506988b9996426b9e8ce7726a46e0651af5c2bd01d12a4199839f834220aa15eb040371f9f25820fd9864a07bdbe736a41434e53a14e6991113a49411357dd4d8c8bac4705c3652190291f565eba2fcf7a78ee5355d4dfee659ab493c58459398d6180daf99e468a13982cb06d8cb3acfab09f71a8da1357844113b321f86d5e17714a3a46ab10c208fba384e8c5ae6d4f508fb514dfc3d207d231ea6232c0c6649f7275e78a46380c4e97a1b483c2c96cf8477c37777c3236cdb405eb58a192d6954896b9ff8f9de9147bc0b05e49eb4801543e522a5b4b9492028175ef6f5a7b53fda1298bb8a16d7b665de590a3f2abf21ead78b31805a158dd1652fc7e7ad45030ad993b188a8ca85bfd465ca4db29cf81497b21b9ef0609858fab22aa6fbd9830a9cfb20ecc5067b37339e0fb8b3763c469ac4b66d2fc20e147cb33662bd579fb5e481d5b725f94c4ec5c61d53f49b0313cfe830878cdaa525d4c2c1af539239a04f0561dc2b047291485fdd0d069f6709bfd08ee44a66fcfd0e9be5989ece9d9e9aef820937faa7ecad14831d924766282549e6fc061d0c6d870178e3e44e865aa03b009b0300e2ed18aa0512edccce2536995fe359147741569bd7f497d2296c5ac0fe06391ed382b25b91fb30d784fb58800d87456d6e48f7d706a1eac6482b7e0b72771a55c6ab0b73d960a9823cc23307297818ffb1d2dd056301e61811a072a81ca5aca69655349a3341b75004a3ad0733a15dc2bd926f8ce124b9494269533a4f00ac48143234a65fee487744212d9c652ae011556ecd8d90d30c2c12e4b876d5a9678d96dd04b7c28ea94926790eda4eb02c0c71fd20d1556bf8cc294ec13071101d23bd2134aae6a8ad93d1e36211fd505945ac60da8b7bfe456326df56763c46f06f1dace70945fa1d0de0939ba698504caf2b31e9f6e6037e2273a302339f14529926bd59aa47a2c198256c7bb4cd55ca5edf8a1447e4647e55a97bc0f9c49e18241344f2ed7405f227626d02ae27b83406483583991b90b0de3b6d17cb42e075fdc47308b32141d3b5098bb4d7d5526a3fa79737be19cdee32cf818994d35438b5e496a8456c795a3e0b0aa4a24caf3c64d64f0a659afcdfbd2159051fccd1c0f6ed016eae649e36995a16b1000d81264e6d64b881861b8a67692622086b8f783b8fde09f46f9426f0249fbb261b69f4bf546014ef77bc7dfe67dfcec41fd97c298bb1c9785e2187e2e62350059d44cc9cecba92c3384bce86f6fb59bb9c0c9686bf143a8d10f9181c2b730ffffb475e85123a74ac5828111928a7e14fb052fe4a7b697d2f795e95eaae986fd2072f293184eafcfd7b0dbf96c2b274eb945e0fe168a4b20d2988e925b5ff1d66542761a065910ce8e51f2894b2db48d989354d2b7a9fd8c6ca0a302adbcff2b71dd11e3017ffb2684aa3c3182717b70942f73a189d2bd65a4e6573c7d08691cd78f54095d002edf689343cd42466c4727590f5c194deea5ae2d94d8ee10cc3718d8ef73bb634651e84e6d5415c92e24dbc21355d3dfc97125e446fcb926735c78a11d0f97d3cc6c0594192ebf1969c25a14169e62c16823f9452578539e44d23d0311f303cc4de5c81bacfe52ff2eb3a0adcc1a23f58ba36ac861a165c303daaffca876b1d9db9b9a978b47cdd5aa1d78a8dd8df3049c7de27f6cb5ff9474c77bb373056bc98b65da18c4160bb0c65484089fb57748da0159a7c434a994ff772f12444935b825a17158c79b898c62988e8d7e736e56cfad7dd9d1e624d27a659135d40654d455aa554d39468df4c6b10f6552764617cc3133268c5b74b22a480b2098c8ab5d87517a857b617ad0db0e14eed72a428fefee7de474cc6d61e03f783d37167932a3adc85d20c0e6ec2d84fa123d600befb16c1d40430199a70a8ac17c0e4a06af1973893fee2d3d0760ade256a6b4ba5f76ef884b20886202164deca28a2d4a42a0571efc4ae8c78495da0cc4bf569956291949eb215d2d42a4a2d582c11d44de33e96ba6d188caa9a54299a40f2c42009db741d16f5fb538d0b4ba6ae85aa9829012ec37dd1258a70994761df56b7fc648d3347de5fe85100bb8568b10e1f35669410d723e0ee4516dba2359ea369aa6b59c44bb0cadc8198bea9f2c531cebff356d3182e5ada72927e8ba2d88752ec5ab7aeb83891747d743bcd571ff6c1970f6b3aacb015edce83ebe6d1490a2620c9152dad0c73b6a422038b3bd37e8ca0b18861a83927cd411a99924f98a13f52d4ed25db86474fa44bf64dfb4e52b4dc6405bc5747748871f14260c0260d3882d0ddd639db941be05ef139f1452e5d703b6a3b372f2e3582c333ee7b505d5eedc0f0097c66c023203b07f29b2d51358abcc4f5e23bce4a5b6727e646931ca12e7e8609681517d1a7d60e308e00958943629ee9a252ddcd43e24c1412768870567164b2963abf2f0552620ed3b6bde3d340b9556e474cfd1c390712f6cbd39cc587725e201e696ec58f7704d54e12207b1159719176554c4c6ce4535ba9225581e7d085a4bc28a1fe7c47b57c4cb5f295f7219fed578ee1dc4946ee6344cd7aa18f6300eb4e476a29c004ab374d03e54ebf7c958e1a8900f48d178216dff0fd2391450e0801d5b356087285556385af74e8857b4dac41fde36dc1ffd78d6e48e4f88a45fd416d5bcaa711699ed60587ebe7c0c7904f715313b6d44e6aeb2e204b927f2f8168b8243977461139b00b6ce3c5f444311622b0f0364bed386d89e9573044c45c4468993fdc526937e712805d3d7eeb116077388e3ec7fcf8d9af799b0d281acc26d823c416836beb853b15069d8c353cb57e8ad46854638022610a497223c1589ada752b0c4eabc8b245802b3119f2a6eb517af69127a43dcdb2ee5f41736da6d3c1d0dcb6b14b12bb99446e2078cac62a240656ad733c3407a480f817d8fab3f95a5df8bcf6474147db78647eeea3da602b9c6505dce49b547a436e5fafe30ebf64bbea6f638abdfe289a55f0494ffb04b6f09aaf35e65e91bafac90a582600db4533370ae0f1e2ae024e70b664988c5161267ba16d828f79cf609e5757a67e5cbbb8c6ea4f05b04fcb9dfabf1305b23defff1b90e4b350d601210842090f8610e9ac03c858f1a55199931332c09efd71d40cf3a418387067852b40773fef7598910b91e4683bb0d202346883cf46bb91771c2658cf27fcd16621cb6434962fa4deeb0b8ea657391b2a11074c93010116a711af1140e083bd814c23406d8c3acf555e40a6a4cacfff8d42f4d09f7f45cd77267017a069ee48a4fcdc7bdcfe5031b1f87f855b54e75dc0050d6757d300676c3e9a6694958350648af709543467a4a66af830b8a7d45f3c3846cf38f86ab11e0111130e514101952586954dbdfb56d588a0e1a47a0a24c51a0210a57d4ada2e65227416645a6f1f2edd4286e1bbbeb7f01c7011d18814cbfc82730081b5f38ca8ba24386c93cdc74836ed5c24a76f916e0c05b1f096fce08e322002bcc14d1ae2b4345822b190f2d431aac0b13e58721003b3fb13318a6b25bf9c90b21e50efe9a8bfb798c995014906842761649b11b726be10a305f8efbe3fbaed1a34a962ac6bacc04830e24fa1d7958d60b71f8a06f52ed9b7f1cb17d36a167be50a71ea4b14494043e39542fc31fa15b10fa722036c63283c2e896cedc716247e9509e8e155e9c4e12ab6ac781bb10c45b63e52e8a994bf365419dc0d9cecfa541ebaec8b3eaaed727144e4048ef3faeee128fd67ee3fcfaa2c83bc81bb20212dca82b07917de6845819ef0923443c2cd6eb863902d39eddf426445bb1253927627fede69e83187d9d73e0ffedc13fd23203101e2edde240dbd2f09182cfaed68671fd297bcc76004a2be8cd26398e2ac7bf314325bef0aa421c38661262a260a649ac44575c511ba0f32e7f9f3d72e95aa1eae3df460afd035557ff9eb1a1e8dd370c3e06c750acf11d54157b2fa769889738d251741572897a15b1ad30ff79ebcb0c5ffe21d74e10f03a4588abe5a8a8153ceed423d94bf81f0f96c55662a695cdf8b60ee9a30a3c7186315f919e1758680b203fc8894a0f87cbd812d1edb7ecf3fabb86092739604b802c95bb1d391285123e23cd352834f968be8a1b44341062432056c439df1e87898b91345c558813c1eef13e750a43d905aa1b4ace4d9669d692ac0c039bdb14259ff69808ede2601d735f706e87f20de45d1110112168aa67ec0a854c5256f5a2c850ebaaf340bdc4495aa0587d3a0d7beac031c122d5efa1c3d2d872fd88f99df273e4bae311790fdbca23762860370b0316f77236e6ad19cfa8496b0178c52c031a424ddccf3f126b8706c0828682c3e704580b808f520bb83177b50559cf4189dcfd32ccaf8165dcbc6984ee1da8aba0c284614fef061e0e22126e0406688c337d7882b85cc3e2da87087c9c170f875a4c7bf228019815d8faf0753a4e1227156110969c2f00069c9e24e8dbec9ce4d4a2c9ac075ec0b8e4331cdc6dc93a1cb0ec91576811b75567d948c14df58a9fbdeb8b0c7298c012f62bfb0ccd19e15a5b67fea7df029273c8f46e26d5d814acf72b497cbea26ed7c12243d12266590f9925650dd2207b3558503e3db7b8e6cfc71ca8cc0ee3e6db17dbcbc50f042903cc13a1b3a3c1bd05ed86daec1b1bddac23090ae502899238d80f8643723c39fd8c965b6ff89613fedd3a9f0f2eb6917d1273d86ed1b6cd0e33499db3b124a6d7166e484f8e7d16195de95c20ec20e374e414b27eac72c33c3c9a0aaad1f5fe50b57da00ce8d2faa108345c77c5be50663dd3c94e0c9fa597d2f350eb2bc3f7836e7aa88aed50ce0cb021c7f0d1c77c1b1f4407e36e53c2dc396ea7e52e082522aa9cd92879f459fad9b96aa07ca500caf6da4b7254c0f0f3adeb328deaaec715fa231db70a6e71a59593f1ddb4c469fb5ac3396ddb73f0ada47388f3d6580b17708a946faf476fd8e3d5bed280fcecc1dd52043390339eb81f5ac8549aac93cfb74a113466476b362d229794d7265ea59a12d15c55f98834aa1fb4c8d1c22a8b219c5c7888408ecb460f69efbe5ede75601b2cb230b55f7dbff177149325b1037e9bc9aad5d5c354f300104a4d68d1418a901b2cf1b86dec0608b4b07f4c876096c984c7ce2170b527a34068db00995cf8a454cef86cfe21642c3e6748d3258a62d22dbd2382dff432cf2659554c21e532f9e2ac302f05aba491fcfb8da5538f4539b2f7eee68450bc856d7eb210829d4e762a7beb03ba12467afdbe457df5da24b23234876aac5a682cfc5caad5a50343d9199e0fd4364f7d2ee9cff9f3da4153b98e6b0143ee283e073302d60b4302fb2ecdc6daeeaf98ac9d56a35f5058f444474542aade0bcce012ea43a9bbf040b3941cb4f5f41bcc15219024f2db0f71b48719cb9b09fae4d80a499c094d14aafc94668afcaf1a0ec4536c9694d6fa1546c8944e1ad0aee9451358e5484002f8ae0d2f0638a92e024d40c10d7563d427405b0682ad2b4e765fa856da365cbc460ede115071b56f6efb7b9a4fe4f201e5d6ad1fe98aa8c71647d003aefe629edd3c55e14f5f8755d729be4e9730c5f430e9dbaa369352941013d1849a183c2bf7b84f7fdf1df18feb24555c3f244568ceae278cd4e34377b698b09c9b8fc2734385b5c712964498602b41f25294383d5f192fbaac25cc6c17d3f71e01c79499bfb31e318c0cbfc21b28b4c57cbbaf54938e41b214fbe7b46d72b42edfbf8f0307b1d4bb281371caf4816b0086b77f7ae2832d7552a188ba95cb5944388c51495fd4133375b26422a848a2488a51bbbb4aff8ea375c03ad9de20a6a89a61dc98f7977eff615608dcd80a1bf9765d014f57925cbf9392e45099b214884efb4db39dd1ab0fa1bab9369aa6245065caf176be4562a3b8f25bad25a2a4501d125544819b982ac02ab750fc4cdf78d812a4ba36cef1a8dea4a5624a0fc81602403db767bbfc7c716604fb1fce750eaa516205b3f76ac8f4099218d72c29a53a2eeb2b62b790576419890c7bd8f34e0ed4e451754f721dd3e5e1b4283c836f5ec4149e59d3c8a159541bbc86277c71dd68adbb87edcdd7b8a1394cc7e6268eb4965200a04419e2014416ea4fdcacc0ff45c06ef99b01224ab3c0d178732580921a5b4b3fa990fd80dd64680e06817f7218e14fa8445c33debe33ed2480d31fb04d04dd3e6a7c0a7d52c4b7d24ec6b6d903fc9f679e67f7c1c31b1fd6608dde99c2e0c6cbe8574bd500778056832e47be72c2087aa0233203e694c76b44ace83abcde141b976eb57bfea431de65bbfd81b5b51ee5c2355be4209af33a3927415844be40b56747e52a59ff8c687b9fc003f930bc99e26e844130e933e7391cbb8e36cb04421080f0ab1dbc7748526992345b209ae151c8ad3446dd407b1e1dfdd34f3ed2851c6f8e6cacc672ea3961f4130ac5ae7d58a168edd9c93fffd223a655eb4eaf4d0cc28d4cd47825e68e0500e9331511f4555aa18ac130e9ef6e8b040833d26d0eb64b5cb2fc8279b1ab30d9e1317bfa6a7c652b0a596e07e72f8015e2f26ad663083db3c036cd69f5551cbec24934924b231a65dc77f8721faadd61fd82707346f98cc0e1688e53efb9045329f3a305bb02d6696ab5214b4bd1c0fcd3dd727cb19d6f66d786e2575e67526d51bcb0500fea0b4f40794224cf68d8ed6bfaf8bfec4a418d1b378109d1957f3f2cd725c61f0670ba27681ba0754aba598a3c60120a1a2319864effb615f66dc280c788d44735cda160897eec811b86ef8f14cbfb2e9b0d5f08a6020d1e4f076b492729c5f6acb37b545540f7bf8105680e0508f0eaca9a3affe392891b9c9168d6042f643fc104897ff1a6629861f8f874c6bcbfc46c80aedba73930b4ae3f4af4a47dd4078b660dd56252e70f48605426d9474474f3a3ea236222103051efb50265b64ccee63d34d20c3d22c321ceac3ae903a654761cc329f8916ce01e81fa9fa70a84b859c58deaeab568263d7fa1265973854940a43aba5074ad6aaaa7d99fdfc551d7f7f7a13768c4542c0928b338146f8f6bb180806434bad4326832b425725c9b29e8e36e4a76c2a20936f65a83f6872a4e0d4ec4080977c8a0ec746badf2e41ecc6dc23c8be7194a5c3f23c3e346707401203fcc25e4a5f5055d7e1cd78e89e7fe0d7f2a30c3d285d708c50e1c4731f14afdd3793dc6732cfa144e6ff6838a70f0b9b50580a36629b59fcf67190a76849c369c8f99822017ce167424298189e94791b4064d41d738e19c3a675999db513fe36115b0e610c4857266e245211552aa1593efd6a05c3f5036cbba02ba53b3582fcb407920b61f443c0e8683470ecd43f74caa8324353e1108c1be4861ca859fe749aa684899dbcbb4c720df8a457c5c259d1c813168fc4e4d7a2bbe7a4820d010f97e90476c8663fd3b4f578ab6cce9d0c322e68902d5a21b03f0e57455c4dd3887643e72b64f7f9033eb44b4a65302c781db4e88e953e204f41727c6d6e1746104d020d3b6756e2ba3cd608a4a908b406ad65d2762c480b037eefddb7c38d92123d7cdf0c1fd48638cbae9b3e8661a661e67d7240f3160ca47437648643769e62ce65cc834ef17ce075022ebbbab09f337755337b218797bcaa8cbb6a97f13079fac1a92b702d035d27a5c88b9631ebeef3c4962eb8d51cc07daad58a0e5f356a12acb26411be3e93e48bbd0299dab043999c1476138498ff369972a6d8f0982d3bd4c2f1539e603deb403027f61981be36ac87e100e23a7d8fde8c43bc64bf9139bf673a645eb3b95217e71fb54bfd981c707338e564d6fb2a6a14e432b7637476223874f54bde7f9f8916965e0ed0e18759f2640828cf67289e782a025f5bd5d6a37cdff9ece1e9c00d1e84c33bc85e0b6cdd9b079f66d033c74dc9dd7802ef0e253f8ffa1d78e6891f41c25fd6aae471339c9895e8ae75cb4fd2e1d6365c1ed4e369e52794e2adeab7a8d2550fc359179574fb0749dc1a252affed02c706bef62bb3365babdaaa5630b89ecc5801fe4f78b8db5a9d368e276ed6f842c523a8adf74e7a3ef202c1d18f6af4745324163f5d0efadcbaaef720bbab5d0a15497ecdf991e9fce33e1af47e70464b3af072becada6109a232177c5058c878464b5bc93effb74465b2c532a10aca7737ed5797c93fe2421a572a948ad2d27a1351a0960744bce5133a05eb08679d626ba4d21679d5f4d81cd2b84b48690687349c9b68ea927673612227303556baed1a33cbffa0282e089d772286cad92662ac7753aef9336e4425fac3bb2374f5c276bebccc2b713eb71030dec28f071bebc6db0362e30976fecaedb2d3e600dcb037861a4e83d50b89e90f46e7c63f1e41a147529cb77d8f5623b4fc72aace80131d034190bb21044336284cdbcd42064ce3f05d1c6f8c8f7289a81bff1ee8494881b017751361a5a7cb71a77af62bdce7797e40c5a654a36a5de6a81d8d2ee210a36f73b8925100387078c9572a92c01eb7f9089fc17a4cdb6ccbffb8c342ae8b0d525d777cab5003c3549180cbd21794c30b36da5b413ea5d89891d03034a4d5238c7088e5caf15cd6e75931427050f482fd9d6d150688bb16e51bed327e4c8c5fc70ba47ceb26f1b046a1a26ca596e8fdb4788da7e8b23f4328d72272ddd1c4c4641d36ae9d4fc43c57d793e003c2f369a092e7cc60ff0f025b229b5a42a520e6d0206cca35cc41119658690ac805314339f91c1101e7d8d509075fc150e1884c212976272bb03b132588a622caf09a1d800407e042b80933df9111be6b0bb0d89c39b1dce6ad83cecb1b261459900cbe926fb2ce4b10c8d5a5d29c4f094789b5de79d9b5c56a5b30a1cd9c0dc276602f2554fb6651074b5984937d9a5723b1bdbcb2d52a88aee0d33f0b65cdca3f8b1cd792074111cf0be5633e4b3a4655f22b8fde88a004a38a5b3d69763f3d2836167514d3535ae8e366c07e5933c15560854b4889d6e0c31d9917479b45300b91ac39fe8d9ffd42d45c9365b9f3d26f5174f1b7e9821b61058b0ec8227c72d1705a0182a943d504177901500b055c86a64818f9b68ee5d92f8740964e39fc412d2810c83292094310a6d456586d5ca951e14401d68fd37052f5b4bae5a0b24680ec7bbc748a26b2259e7c85d95f53ca810e98509312f1a875222d6844a340e82e1dcfbeec4108c02a6f66f693bcf6bd1c6c1eb74b499c607ae35f75a531c33eb35b91e5066bbb12112bf9776036f9f3527001e2746835aa44b47296f16b08aef9f6026a961ef065b270f081419785512cb95d6354f54023b850753f2c61cb69005d40f5aeba4c56da46715413f41b5c5352cdaa495a75211462c2d91ea8e2b516040111a15beceb8cc00dbc9e5286db840408e08c1ecb70937f831886d4980619ae32630b30c479a88d7b2ae7c44ecb00583afea12c54be3c0211d7e475fa4ed394e071949d6697a8907460a9dfa061c98a824e952417f272f41f11910f8c135b824d02e77493cae21e5ff9e5d50d323cbab53bc2e927976e623b97bff59dd92e9b8555fabdb17b4ce97bfe09ab58f31a1a824f18bbc4c612978abdf1c005ad08350ffd70f388d17598bef7210607dfe2bae222b90112f5b133eff8a6416c0df8d208e029dace3acb4beba139b8475ea4e66e770f2ea585ecdcaee22584b82d569ffa130e98be03a297406fbe753e205114b113f91cf18fa30aadc3115dca104c7b9439b871291df11e182842cc9e323fa91a5174c8cadf121a86444c507692a5241a3dd929e86149574addbd44ddb9a268294b81f2aa3f57e37317e3007b2cf0bc0016f49de6e6e98f7c8f385a642527a8ccdd0c54bc4b4390fa4eecee4834251e10afae8ce2dc48f906f9c47aa82fa41288a5a6771cf07163e809015512f6c09c0db795b79b86bf848dca9ebe4d8331a4ae3793f482468df449b8ce45296b1fbf4807c930d9ec5d6727b9cd8b14523d57b20f348a9c050229a5c09368811d57c35fa2fdace1b7951db0afd5ffa9a4321154c6628a0a3619d25643e3df040b6a00aabba486d9f62324307c4bd84132062c90930d8d2732629052332934473cdb749496f7b7901c8f7b399e8177a359439397827f89778d945d1e32ba5cecbdb7f28ee027cb3b841656044132f613d2604aef92bc579a0a550839a58a8cb4cdba500920e0a7d546a58786c930b0b21a893a1c30517d2bec1da30303628289fd725f53dd54b27b9e94ad42d931c8a53c47fab25d7011ae93244e063de177a28b06126bd88d9b1410fdfd68e0b65ee9a766ee3df83e20d463081975a01f730449423f87e9e29e5aad709c0664858a1314c6f508acb4a2ab4469df7040bb9e1c673f3c2ee5ca663e408404dbccafa52a10061e66c22f703b94f868285c7bb98dd531099f0723a7b76ddd2ab6cbab314230e87598f01edc4ddc3cdfcf53afbbb9fb01e7224f3456abe108c677e23812ddc284cc3fff1b8c8750ca031c4a9b3fcad560e79d104bb665ccf81e304064dde861f0643d1100b3ddbfef4b81f29fd8859601b695d10182c2b99d7b5c553b1dd5a2b5525971526d561d678dfba2f30c2e55d5a07809d99eecb977efa4ddc46dcc8edcd661dc71dee1db6ab54e0a65c5ecc447eaf95d606881e1f72fe826c36941f504369b1576d7990018e8efb95faa1e7c29b15f388ad35bd927f9abd00ce7698422a570ba941ab37a58058c3080bb58c91ca7cb2a7aadacf3be0ba6e6225aba09900c496569ab9f44bcf04d26720677c8acfb8a4f6f3c1b474c5d7ec3b96b0330cd04c6dc752e2852023bd0bbfb29e005fdd85ded4ca3e000e9953e8a4e9e15f93a0005569d02f785f41cec0886dceff5d68ba57c3a4d30f19340bb571124255e56e5fc056f4cbb145a1a8220f8c1f42306eea1fa0616900c524aba1e5a27452e6d6efb6d103742d10ace573389756dfc1289b6daf987d620f40aad12abbf0bbc13a6597f57e0776eb3f0c6d45a104bf050cea1d066ccd97fbf725f2db127b7785c15b16e7d3c5d91f4058e5d170bc4badeba0fb33a7a39113afcb6ccf379dd2c993fb0703f9945303691c43bfe911da45e43249be2a1be0d1dd64874f1bec8d92afd0a53dab047bd573cc32ebc42cda2a340dd7682aa6a4e4019f7fd50f91a85fdb3a47db161d8572147384b23db9289559ae0b40639a236880386f3634bafe546a6978e51e191cd4c2e00e18793eba0151e231c8390dff57472749a1bf87538d0a716f564ba9de5ad1575e3658520b795610ec90b35d14aeebc988fe7f45e9677d7fe298e9b4f25e18cf6f01cd62acc295761cc861b66d9d35dc6e65da2ced062bbe35148d6b18652a839dbaf98430becce9651dbdab3a4b85a18b62e213d96f85982ba01ef105c41fc0c0a29fc6065dad9a21ff2657c2b6d562647df0985594139a5162ac2fb0f2c95bf91d972bf8462c1215e5913225fce25b3b5380ef52e63aa28b27ab5a03277f74f72bb2cff64b4c28edc59c664604c2ec028645e5119f05efa8aa73ee89d2a27ce1b3a24697046572811b3a492ed1c1a38a1f8aba4730ae88c1012fc82d54ec1e1d2d82d3ed5acd0e9b300aa022e0f3450c152868ff883c2b833b57070c252c6e657a367963c80ed49b049db7aa398e090458b572d452f09302fcc3870b721a93433207e0e8723dff2adb2729c73cfa3766240cd0048c1f57e45cd9c2b483c28a1770d0e7ada555f58cb7f773786e3120f9205ec7b81bafe4ec6927b4d4ef21816f31592a78977b16521d1851612d5d4342d6ce8317c782a09f70412310f0400371af3ebf0393d0fe4865263b7e868370db1661406baa9af8ccbd108d3490307cae02777032823331ecefc7b375ed855161bb06320605c2b006a119811edc25464bf1925581b8d90c9d3ba063b1aae129c834a060efc15347d2e151b49b2bdc244a65d4d53702d160e697d709f1b645dd0f20e130085c159dec5bd92279777c46aed8f817e68d74c1bf12aed8269ee817130d0f0dc909f919efc97779884f8f921b28adf424b189930a4951a8d031cd58804d05ec2b807cb43cfeccea532d5f8727b4a0b35351518937cf12bb563687d257657a270e4d1cd78ca97045eb04c4c519427194c8f7d010015af4ed6f129667a32b8cd464b46703166b233acfab8d7d22d801e27a0cccee4df847674abe89c625242199f41d20c2a6e0e5df842b44e2f758607b312247d1c64c85fc249e1bdf586bb635f7eacd33fb10e82a186147c01af059f2592b4488792e7085ee57cd04149bf2db08727e2c72144e1d74580d2a5d1bbbadf9595368ba97d152059a5724aeba0c00b9bd99a22b11ca2049711a27f4d991c8796f4fd740b73177e49a9ea3653983860a5d752080de67576d8cb80a48e1e939e488d3cb50897ee027641915c4e7885bb8a28c6919c93a6530eac68a10e5a144922036db894c51a4c027deca54855b3d42f971b4e798d2563593b4a971e10c47b41c5d93cfd117e89e38425e141729c10349380a3098e7a12c519c674a488bc94fdaf725bc564bd424088e412f97dfc023d50f066e0a9da5489c178569fb9bfedbf96b07f3fb4888b06bfb3e8f24a411b304e2aa753414380ab81d3cac9577474cd716b0a238ed2ae28634220e2319be83de3726a0efde67a743692de5712a2868d9a64b2ade8d6c8d5a854f2ef9e60039e6fd24872f35a29c33d223146e7f459df25b3d15e29e02526d325d44274c02ace250d9f3f6315af92007cf85831461ae220e7038508b82853a228056475d829d9efdcd60d7ebea7265903ea1d19f5c2df07c30b203543af459ad95bb51b8b777a1aae5ff3ca4119214753858a29b31451bd1b62bd32ab421bbf68b20f065881940f6d8f25d9b1e46bd106b3ba509d0b3d8a094ea159785a00332a00313a85f71222044100d47af0207a202f5c2dc101486c0da93c16705e6cad60bbcbc3642bf7cf822d9623e8697977d56ab7834b00081d08e33af0ba2e730730bb55827fd82d3c66c62c4d71e7d05c42cf4df1735cac7f3355f47983aa072e2aad75a1828718c6ccb1fc95ad902795f00b8e756bc8c6ebbcdb73866692183f7919b5c777c2dc53d195771e81cc5735d562aa383c90aafb71347d55ae284125ac8046ba44aa464d6203dc7e96e979fbc1a3d0a88ac38f3abc70c404166b35853458e8e59a8694ffaf419c8b5dd30c9db4691c2ed73c2528ecd9915343274948cf0d5cd7ac2338e48fd5d1d5cc85ab1967f15bd9d415733f3120ed41bed56b5e83f6ac68dac409ed498bb3890ced49e4bff6832019f26cb28c36908e0cca519ee9700d1b058cc2aa48672bdc3ed007676efb7843b4957a86221afbebaf65fd977bb2e8a26c0c18e11126ac4b6d33681aefe47799cccf6538058d7e3d601dd948ee246646f8b32953d718304480d23c34052ba53f2daefd3d2905d4324560fa230c11be291438ab5255dd42fce99363b0104f5e3c26c2bf7f8d5d823de67b973130714aa33ab0fa7fb1de03e1239fd2c401054d6f5969583c7973f5bfbae0069c3439179cf9e1ffcace3d2e84faaf0769a9db1d36f4edcf5fb089d1c710e5f51ce668f81c548fd6d9ffc5714f7adfb13e2fe54154cf167d4d4e3efe993dd3bb60c8f73a0a89894a3ab4be3c41c1e4398423c4f16c8faf10241d089b186ead9044ffeb5123aa2e813af3bf70438c2cdbe7f53a20c5b528e6cc30eec8d635cfff6882ab9c652058d1afc1431f212b3b7ffbaa2de0f56e6c2c40400b81c48c51d91ba05bd5d09a4f3749f14a04ac29300c6be9d6839c8a99e0e7d4d2ca6126532b9a8beff61a8bc81a308eff390e868931098090eb22ded1f16908154bf4b07c63be36c714f975a2fe73cc0094a880c0a1f7fc6794bff27891ac58bfce74fd4712c19dbe4c982ea02bdb2f0512aed0cf3d763b43268929589508ad0715d844d7c483d8731511e947845da5f09f47b5d93cf865cf0ccc8bee617d0c12baa70f150715d1bb81b3d9bcb5f31238668ae03fd71637cfe6cab5411eebceb31c65bae3fe797a9a0f2790612ec49d2b775ecd686efa1d28ade92373675bd8e7942d082624118bde894d545846341c5a54f8609b481421903615e0ac42088d5cc29f2b7017988ff91a961731acf8b28c32cb3c971ecd6d1216826a098f89b61cad2e29e1716f8a691c025683d6916da1b15330d397ec8c6fb38fa5d9791e9ea68c6c9196e2c6614c0617842e6375009e9580b69672623d4258f94f6f778a4741b0f1ea06bc10a37e87358d7260a88165f0f726e31715d2e67be49255a2fdf10dd1819f5a08060180e3c0e3caac1a92a3d997f67dc71ab383e20072b3edb4661e2eace90ac53b78bef6641ec07e5d754f57e2d35c5f2e598f686a4dd277e31d0e63c11e354e10004b71b300214d835f4ce2d67ce1d6d3b7391b858ddd5ae0a24ba7914708e6ede22fda0ffa3c760311a8f430d72318b03b40ebcabc58256c92bedfa1c967cf124da9f372fc1f0ddf37c0a3cfc56a24a8d0a9b1d79e60628ef1bae8999904cfe0c2cb6c7f500b330f25f677530a977a1d4194914bb1da953adf75deb35bd13616dcb66ab995b1b24774ef67a712103e9a42aa608c2775870ee56f143c52954a0089c8ac938584fe996a5e3cb7315d259bf95d45ced9bef79820f0b00e9a01b18159ec37fbb0892fd08691b8ffee335c50e6c1a47227afff224a0e994b0f0fb497832ac9992e53fbbe235121f227c4c52f438cf0ac5efc28be0a9e373c3feef4e84f42ca702c7621e7a0545e881d16a6d07770f6186656f0d8e594057b8bad95f556313ea50ced1da2da7de18ba0b3e2fc810572ebec9f80e48f56d75ba1be55d38e0ccc5d64bf3c170378cc2df0965bd4b0f4098c333c54518ae46878d8418a4ac2b89b65e90b7c59d77567ddc01d5b4d2c1dc032cca531c7be1ef7e18b9fd8a45cb665a428c2923a196dba485676e8828c570c856b3f7988681c5637a990d39f186ef9e16ed0250d2a9f0edae5fb058c8511f4cb08c95156809a39eabcd65b57d66d995008b390a3f97ef9ee00960b3ede6a11010d06072634df2dd5deb642e49b5d636c2abdee1e91ccc055ce958262c67fd0c84754f57e9458fdc96695933be7c2d3c2fee5409a8d7d13e621cd0147687dcb1e33cf1a4ecc425af350985872bccd3252dd86616d3090cdc2553800b68740bd8763fb87564a95bc8ec59b419b915d6181b53716db970f88cd33311729b920480ddbe3cfe3df41ddbe4f11c2cf2a44984f21578e2a9774297bc5fc0ad07b6f5455a5a12d3a81d50c560a17a3b81aff44cab18b2a360e5540364f83f48ec4c905559e25869ea0748f17eb00589246b5edd575a99135e62ee8892d9566680d8d8a0fb155ad7d100e10e9a72b0399a0c8f8a10ea1a0b448101ddecdd76dcf197b8bc00378b60c59838e2c4297c7420ee2c1a8d4124af486ce3574d40c1c66d2bc86521ab370be8445161890aaf944bb976d41e891f6744f12ab0a4a595316a6b80a8a1194e4660318c1a4633cf1d67e71d8099a08df7be510c7ff435735f36f720e40f3e903eae2971c0ea042d3b0766443a82ca2ea8448b5639cfa5a2f2da54de0fe38222aaea28c8ffb470c023a20c3bf347e0b5da0a45d7b2ee97a7482eb309596c6043d0eeb0cf2c2a16d1b317d2af0ff237adc377c7f50af66b9af5416cef7ffcf79f6ac0ed014c207901a1825092cc1077d4630085b95ea0890e4264da4ebdbbf5223ac098a52c6d0bb1e4f17008a28115da485fe8ed2d642facf67177bee9299cc6b9ce9e54a9e540a57a1a4cf5879d21e31ffb41d272b3c7fc3e2abe728001b46c5f56678a8c28a54dbe8353e4d58c9031aa48ecb456713cb24dbf2dbb177c93c78781ef3881a26155f8e9471c4a3eb698ae9f1040a212977df8a0acf020d0632dcfceb86c7bba31f3f67fafebe3b417962b046dab8a58eaa0b88e333402d0a31adfeb187d4e815c04cf0bff589a03b356a50f9291af358c7ffdbde6fcf0fc60fda31f8559040a8d346baa25694bb14663858ea7391d0b6c2eb6e9e7b71333e21505d54130f47512bcf5d0ea18f1d5aea02f15026de8f38369e1eca3c2f2006c66e477f1c70f1dadacf13f6c51c886fbe870c23645c0724d0cb997ff39bd985b911c4048e392f2d94d34b7987ceb0ebb05a3fa37ff680caa02cfacb3d570dd2710012faf63af9d73c99ff341734be5c9070d6bad1a568fb0c394d5a06c491b5fddf0c5e8e0b3546ba40e04e68c746ca7015bc5c2c589c4b1238e4448ea31cd2ebccd2a6dae3b22d33f4788e9b38447471a5f0835c1a47a6ea8117bd54523b3b890d280337d2c1eb527f056e9e51b1fe5c393a16f726c6c1895429e3a263f56e90fd540d24e4628800b338efa7a8494fd131f19c45424811c8bde758c5a37ba09f3069336e24e81d3276688516cdd1410050a6e376de27354f5b2649c3140bb2446abbd2b468a0054c9d00ff5276d043c0b53d9cc317235c100232e31b2b2f6d81fe4cad5282bcbd64bd9c01af7d25c0d027a7d95ca4e991800154dbf0052302a4ef4149308c61d1162869a6e5bc47348289922aa78e937c3dc5eede5ea1127e64b1e2bbe396c7a0f8a0c1ae0eadca6003c3d06585a77232629b4f50c117acdbfd996402dfc854d20620b3823f686c8c415c49d197de3e6e06d3fa5502d8f2a1322bddc45c1b55e56b87d20f81295807da055d46e5ce54d0aaea47160d099b9012367b1b835286aaf222cd090534794f52f5005a988d58e595d0bbbf44689ad9619a015b4273b2e772130e84ff100b68265944df96bcf67f393944c56bbd124753750a622ea8e7d61cc08dba44ec568a107382582954ce444696045eb6b1bcefecf53fa4a26cb43d8b2d07f78c33bae6ae46ef62839cf4766adc19cf45445bf0c442d78c2a31a33d173d0d3cd846222348ba0643ac4a512e5b778b42622e43620bc79650b1eb85c26750d6ad1c1674e49b2f5011d7e185e6aa02889d9773d7752444ff806e3d80c48f8265d32246037ff3b6e7c10aebaf39d11c8a9614dbf2c34028f6d65f28db533fdbb35f72f28d32aafe8ba82fdb7c91da62005004307cd44589dd348e30aaf95ef21c2c5d51a0bc749de3f1ad6dbe66b16d6e4926087e65cd996dfff09e9f21c6093a8f5f89957de6ac11c1238515ea6c07d600785833796e0aef0ceb4f9c37c74b6ec35f267e4c556b1a2069bc67e27aeb7c1bec0b1ef0149cf513c3a5568d65d9fd3980fc9d711992a635326143b781a3992da82f00647dbbe39302b37acfb8d37c7093ce6074a9fbfd23c63e5dabadc7c954922a39f936dc69feee52c70c2fdb4131954b4f5b93a392e4801cd602a982ac85f9895028297f8c536cacf522364ce29be7142e5afb0559b49272afb98415f1bb8035b1fb3acf4729511ba6a1b6384d099654aca23a97431afba36b1f46742f8f72b0f1561592a31f5908d4d26de5b3b8206f713b3c05cee1d337b49bcbd8fe3998df4bcc02bc1b4784aa9a3dd4f54be00b9371e0beb012fe4568444baf1d3ed9e088fb105549622436702b72a1570aacb6380b7b2d86d885202263beba105d186dba5067bd853c88f90e58a7110c7e34f3d69d8ef154e2964fcb585c82739832419ef33592e78e8546087051e3b97774b34a1fbbcef28b03f5ffafe3562662dd6ad8a381db3623ad85a7d856b88fe8d7f8fe31b304b2d25144ff68ac357f0017cb8815d883e1d771900cf18613fea667135b45cd271e14a0b3645d822d4660ac0eec1cd179dd9fe724f3e26e6c006c3a91ec36c14e0e1cd65a42e0d4e0c31d4622768581ea7042cbebe65c73eecdf834e3807461cf2c51df7455cb15724031e522f7d3f8c67747e36eefa2d9b48cbdbc0fdd975960011100da999236e4d21fe474662da4a18ac76b00463df7ca31ca974eaa6986b666a84ac229dc2f926c2fdeca9c88e200dea9c00157b2796205c3bcd4cb890a6f057f4fc5f732c221d1b5ec80af740935269b0c0c4aa8bf30c7f9218026cef1bfb63ad3c34f2a744b10460910f5270c7cb30afa6ac5cdf8faf801cd9a219af5131a0752aa8765a367f081dfe39e7153c56be942a400d902d2f08f7684816a7b4d028f16d927d566b946964bc0e5d79f5b546551e43f09b0143eb874582a324a70ad3747e416ee6d1c151ea7cd930430de5842596036a49f84f76858568de2e21b998a19027a7c23bf1b83fc9836ecebb0ebb24055aa67909f4408504289ef0001e5ff9992599607827157e7bc8fe40544a774373a054da156ab81b26af00b3cf0fde077c186ff1552c9d81e3f2ab3efeca312800d322d944b074c2f1a4cdf7bcd28a9dc92f610ef3f4fa1473cba6eb635989727424bde0a8b858cbfcdd41107e36ae22923b1997762be26be37027cd182bc168e0980156fa13fc0df19b7356ff25551ed9aeeddcf9262832c158cc6a65221722257f398e19ba3da1aa36df8c25009955bc191920a80731a68d3e57510d2c4e21018e20e6a4489c48a76cca3e3a5df1f3968dc57db0a1f6f6eda4306e63f61897ddee030cf6ea6fad410be106fb216d9903134cca47cdc400b4d474d6263f6f2fb0890c65495ff93dcd1841474608a1dc58eeb06f20896f1f1889044a022198e937fb5915609339965fe0fc5b9f393109060a6e6814e623512e6d2895bf0f5743e26412e07c0dfc4a9f028a552e6f56097159709807e311544c6f500d0da81c65159889b9d188624575296b27624592364ae5a03963fa38c13ee1dc8b63dff680fc2159ff690cddf4e6f7f5b2fd6bfc945e849e189db2c1caec10b752b680663031254e5303fa8813b18877ab16b1682a8ab752745f579b987292438e724ee307971f41396bf5dcdadcd097cea3f5b343569ef201a6178c4a88901803009123829b23667f51b53b567eaf2e9a548b8c12bc8a4cc33f4f54498a9f00f0ccf284e64e5d0e42a483900e6004931d095fe2d655db2c2debfc336bd04c5af6012e55214f4380aa06c431685c90eed8726a9cb50a98bd24121ae93d005a6921bfa46e8afbea85b31e8b257b04df79610ddd8c5ec7657c13a4553487b0999192a06dbe6aad836e20e0f1159759d15ab53f7dfe1a2b620f0a49f447e610c3e8974d2122703060171577b998c45ffc5ed286a0ce7a95e2317c61a1fde0b010e28552ab51f39fff86bfa0bed7723b6a3b5753dda837474b85451b9db0a18e542579ae7bf89e1cdb6e2f03d63e8db2e810f3e8cd75ae849c47382f09097e2aeaf45d667e6971ad54bf2b1d53da478054f4c5f60af2511fc4054ed8554e6af62fc0ff3b11f9e697109a3d275446aa67e692f06ad7a7d4d06ea3e1838c64a574fa5611e4b48d95c8b748cd3c3fe82cdc1d2a1d9c2667638874aff85941a3b34fdf53bfd83c6d3a82c1d1d2f605e273137a82bb94d8cffad8c16a823d610efd2f40dffdf5bb805d1a7c0f1a33e0430a92e677352d15fee12be518f14b35c0bd154133c8b697c734111600bb4adf68202c8513beb92808fadb018b604cf59629ff8e5988ba69da7fd42bd1ca11ba81bec5912286c5f720d4538accee518fadd83e2c373aa350596579c47105f5c4862d3edc8d26612799ccf1ae882158df1a657092c135c2dc10aa976926f24ecd8013f1761eceb0f4210b3b875028aa22f7035acc37176e25d197dc6eef125f6dfb614ec8369769d5e94b3093adb5dacf591187bdb2730cbc26c35e1129d1285bd86c2188f196a1961788bdfd18c13486d11593a8078c9ecd612f305cc4b1e501de5d5a06bccfb5644f82ed993439ff362362beae3544234bdf24cd2946c7d7f4be38269e5fe521bfa1ddef4d438e02b89cd351290fd46408e7891c0733e8321bdea3d19f70ea58af6aa4297e9a44a5485251ac70c546d36d257faec94d5915b8e3acb0f7fba1d82e039bed53d08e0f1a9a6b72ebb507311c5f2112199494fc1b9c9a485b1f6c2d0a8c11f5470a26de24f7f40f755de28dfef9c4150cd79c262236851e7bb36c47df7ae4b45b81456e361d7c8a24131486e7a9ec292459fc5d44dd6c4df2ae1fa04a5bc7d9d13dc1f786894573eee27c59eb0e7bfdb659c070ec5784a38bc41b1857ec8753b722c7fcb313a09e0a3cc0d51742cd77b5fb510e572cfce0cdf1f1d0d91b2ddb76850a2a9f5a92cd3f37abd6a1ece8a322e32f62235852373a900329a533eff588ece69e2d6e5fda37b2129b3e1780e11cec191e1b6fe1c1cda6d40308d0ebe35ede8dd23ce6f41def9f8b96bb6fe763d458db3b0dca7583a783e8dade22780eee5287ac50461e310390d05c4ea46a9cca3c4f1190b75b37bdac2faf90e517f531ad23fd7142739acb341838d92d376b5090dd7fb283a317b4c4b36560b8c136e43b6707f1cb12ec44f7bd42ce97eec831bf8a115919b69e1e600edc6aff811462137fc89ca95f3ed19b5d52a27d4e8945560796179db3384bca7a8a1e9cede775a3c20ba2f803dbc5825880de77e29f610a7a86cc931ce134b24d10cc2adfe81cc7390b37d18e75e246ed18f70a1fe21bdcda36ce508fb030f478bb815e8640de5aec78ab4c91b619eb1534ce4d94f2521118affcb928e92ebe831753feeccc315fec9c92b22f8bd5ce7a909f91a27561d807392ac0db480097999dcff472e4b374378885135c64f2691ad361b8816408f027c8f1f68048b44fb4f3097f84f5a63ee3a2754f8166bd13c9116d5b1bc2144569b7d6ba3e7a8da1dbbb5e0a8efa35d6e8ac97a62de4440a44d359fddfa436e8a7a63140ac2c65e6f9d817721c0ef8b56f8cac3fde8fb1b1a9d5ea362648cbf409ae4d02007a57e43d2dae7129571e31e14198faa999fd346ec4086ef60e50d4d673df706b23e7a17f73103ff9d4b347aea1a547a19972425c17b98b54430d8dc2fc284ea1387fcbdf4244b4a1255a75e0725b1eb66c3f35da3b18154c37008fa0c15ae9cd7c17b295e333bcb41ec94d6e881829e67f64eaed4c67f36ebe5ad1f7389189bd9007cf3db736775aca3bb24fe0ab95d075cc47dddc757ae4c7c333b4e48f52ee4e6fbd807adb662d6209a7986c9b6708c8faa25d782e59a3556ce08376d9bbb873c84e3c96485c06c40d86144575abf2079135a3025e8b869a3bb01fb04b1d4bf9cb6e2f8973208cb60d03b7cb3f6469aa0276efd625bac770e668288a85de3ea37090c08056d14c596ce8ef91bb05f4b99e2ad6dd59d8b3ee844f54074eddf23c0bac28aebb333b600b4448ccd15d6a238fd36cf24d4491068530f4e9b3afb14b36dcb4e2cf85bce5d17eaa85a8e5bf905ac283432a69cd185ec881d286652d6ec1280053be6008fac09f437b422eee667109bda6441f7cfc1587a20431912e1fce82856f7979dbf0eaeceb8780007d0a8fa49e00c6b7cc49ef40d92fdabb83535cc579d12e5b7454dc18f6aae537ecaf1fa79a5ca4abead9e16540d7ff5ae544258cbc094cbda772d214452b84f52dde77643400fed1a67c71b1f014af296d47a06ac852121afe2baa2c1d4750c044824f1cd4669054acf67af862af737001c59390dc92b5efe935df85383ecaffd1525f056b0fac1de818e9ddea16b779a81aaf72eadfc10c2659822195fa0af0303231e63bf65730ea953243854e5cead9347cda6bf3c1c89d6e3c8f431adc8ec07c155ffbb6b22cbd568369ace48bdd0a00c0f8df82b85b12fc2741659b1981869522a7f9215949b435d153a14f919dd5aa41a927e7467dcd2ff27ad943d5c43baa2e1d5bfdab01be6f1fb814fda892b3a83bb2f54a757923d619eb336c78a961b969d50b921caf531d6e13c76e28651a73baf6038299e1a8b0b83592cdcff3d3c668dfa66a226e8cc82582bb96fffad87133e16bb85306e092028ee24187fdf0723b949ba4092a9ce5718d9de2742545e1fa2164b40ec08e50291d9143dd812db3d944d1132c1751155f5ae10d6f0b5b2dc864b7ac4a8e145aae3f6bf0a770c860878578fa46b3cebac318cc4550f0a2c6bdcf7b165fd58e311513b56c063cf3946d3815b3cf09fd77b24f4620cdcb839e46bee8fee97ca245059b176ce7cb047bee8070e8f7654c492cec1f2389509a37c27c5b039458ad6c440992ff2281fadc48c358e5c68b26e01e2833cd21c7d5e17640dbd6150fd1b63d15711d2fe1b375402c4d89f10cf4e20b279423c094bff8a16c4e5922bbde54758f9e4b0a51c3c280548d7c723b9a898133fc24dff08e410c59a89d1acf17823bc68c0f3b82835050425ba88e106a634a26cc67f6836b30d3ce6da12fbedfd1d77bea8e3eae922e971db0c6e5246df2e539244ca95ad39f85f61879f6d6fe02169db324d30fb985d9b0d02511d7536feb09533ad2216b93dc80f88f69da700203c1a5576a85f4d678a8a3fe9c4d7e702dda389da761e4a0620bf897ff02eaedb9f3cc4f5d59c2796651fd5c5469658361a3a171be24e46e0f7c02f7c0abae93c2bd2bac19221a8d4194efda2cd0addb8170101a1e7b698945d1a3fc6507cd8f575ccf0daac16d442cbce6d2163a44c63bb01006c1d53df7ce12048d1df75bbfcd516d59de57523fb0aadb2e16dce503469c54f9ab488a9e71432acd6adad858495f2bf22b0dae13405782151e24989579c65018872cc6c4da1846e49f4f449ffc22158c99a875ba8fb0891f04057e46d854ab73566eac4b24c2cf644fe79be8b2d076f0f1279d0d529463f7ddf92d11a0dcc1d87e9a4c36b5e407c43d14ed751ab91fcc6f03830fba9a55ba4a836c49310862f8c4ae867bf700b1e92b0f250ab5416a5dd6ed94cef95894c1eba5f028ef799223ee2a93baaada9a12945c96d34b2597d48cdb9cf3911eabcde036ae2260c0777242ad82501a20681de26410bd490f871b6490c0e259da67bcb8d972dc35176be02ca99c4af4afd57c637c70542ba51fbbf5ead7e9aa86a541851b7dce4b9608239f28f182bb084ddf8ce302d18809b79d34d3af52c0b9e4e86bceeae6785a0aa43bd91441debf7ea568f3e9bffd2f2b5a2d2f7188caadcdf1839ced0f12a9ce2bed9a01c97ad11f33210319eb017986758539ca2fc3d38bdaef2a4dd9935d76f54263797526199e0c501ece302dab5695b5d301232e21ca93dcf89ba7e1c41a7cda00444f73c1bed050b625bff2b654fb034a34c3b6d5d256525fb454946af3a57c638c0027018e6315025820038edba7717425554d5ff81e0043b46183e7b038dd1eb313b21eda7a5252bb79429c994059f059d05ee5e394b81f4cc10135bcc2a20d4aa71271a20a2ec6608bb97d486ee7a9ec7043669502947021c90b6f941a9a862680b2a5874edaeddf56e2783c014d60e4f2ba8e5ee39a094b67156adf7deeac37ce1fe055ea0555eb8642dbb7bbb7beb774c2a125c455114a94cd7d18a5db5d714b483cca69523cf0aacc5dfb48bca62a8e0af3315efeb2e092448ad5d9ced56ad2d91286a51c1f70bc1fadf0a750897bbffc617f03b832f1a4d99546e0b780992408278b5ffffae73898e6bd0753b58201acdceaccc0b2baba1019b56666532dbdae1a9a87b6f50d7dda08abaf7de7befbdd7ca605405a48427b7765a16c8caecec0b192d4836a38561655666adec666545a85dcb99afb5de5b513ea8c9bf070d9bd42624c80b43485e641b80406d340c0bcc66f76d776f773e6156e1f1dea3b68e729eb1f3b4f606c824a740d060e7fd075af718306e10d9f9bcae71e05a1c5964c8791a6515a65081cd537737c75dee9ea7fdb6f0561744d8e2e91482ff5fad484618974aa99b4762044dac60e0c143841c56de17c1e1c40a061956ea8b14b5bed9a7f7e2432877a4675337d865094c44c84c0f342f6ca5c0d6860aec5d3d35f8c4bdb5d69807ab28cb713d7a54c62b0ce655987f8d79f53eecb17aad9abcc2621eae308fd523c4605d9f1c51aa4a64b7b54ec971026c654062b10a83da825a04357985d51912958858ad8adbbc06a456f3d8d75a61b00b1b65e1f2c1c3353ccf74b3bf8e5a6b3c146cfaff9700bbac81e8d7cb5adb75321910557916405e92496ffa0ed9df741cb23b0d253030174110f5132d4549c305365bf64205a92f2c4f3328654a57b1e2573e1650460b92cdac8b448e5a22d2469a98344b3132e05a7ab78c346b7da17cf15e006ad92c0b4f56a50717b55b1450a0b47414246cd0b220276870f381bd5af62acbb23cd1e0c86432dc2c5ce4217610815b07761791f84c51c1114e80a812c4598424313c3102e80836228810c2153934010377ccad7f14f409b69f2a551e37a99bb2d6e2ee7a9e77452b62214607d8a44396085575ef10466aa81bfad1337428f5e376dd5dd7eeeab5f751bace5a8bc4b62a0abb632ae3b42ca6e40f43813155b9e7799885a2aa1615d71bb62dab43dbecb87525a66d926fcb0fee5c5b16fcbcafc901db90ac372a83001998b6655b15245be4477ed9c42f3ebaef6fd23487f839c44be7440cf8720da308d9ec406e32b43cd9dfe5013ac06e2553db2a4013b721dbb2d60ea1aa3ea98c116ad337500ed09a3e424bff30cc26bdd22fe80ed39ec1f94ada1695b13aec58d2a453429bc4fe7898f60c8e0e3de36f2d5525b13f3608cbc4f6605bf6b4474e1e92dc6075b0d6dad2cb6eb104e1f2c1f36c16c2ebacf5bace6be5e4e47847c0b854f294a7c25577ef2aa71f405119a05df40ed434c5ce0e166021b75b776f776fd791426a0a2645f59e759dcd7a56517446bfcf058aa7f5fdb6511185133be0aa60eec4239228a77e4f2ad941e27516bca97ed52937a0366827a8c967b5c6218a255e4ef48c06bd6ad7fa23674405921fd65a4bd37222e6e19696166bedbdb7f680389b2d5fcb6d6192513ddae45f5aa2310dda8b410fb366128410b04967b4d5450c1858c400ef5bdac6592430c46e89010387d96cb1221fdc77a4d93df7d9af087c5f1012a45576131f58cff8d7387bce2c17848b9b4e90d3663bcbb2ddfd44d3626912528ac297a857020b9808c3587fbb805c40b556cea640556e53007201a54055a37c4206bb6935a8499001d36af27650812b479a9e875d2970b6a660b3376963026cd220ce1269d170b62c47840626341e253b5eee10690d0db55c2e97cb1506155155429cd7dddb751cd7dd8ef32e776f2749c1401bcef33ccfd3f3302e95cad24f3a7bc9a7939f18f320667fef82a27a54d153d5e8d523b3fa749602ad11bfbf8eb46fe8d35bcfb2b7784e96952f4f5652485ebabf12b35ddf866254e5372ad3360e069d71946b718b79f7d2af198a9ce7aa06e9b27106213372ec804d2f831485134ce061838014aa66074d090730c00985110af9cb21691ac994ca80ffe52a52a1c191a66db8f7afa12a7b42d77cefbf6a94906a7211025680f94ce906db456e616d93d333352704c35b9a5c6ed1964e24fceb05038e418643000910b44420ce447126ce70a688271a171e60d3676215d96b1d64c7165eb61ab44d0542cf781254557f36a33fe8166bc64275b5d95836968da50495715fc2d640e5ac434b5ca1c48d0a0f72309bf98cebd9ec05483ab6020e36d575b5731950e0130d8d1e78dde5ea7bb1047ed18fb8db799f0882a208822228e2920d2ad33d5ac0f931125d23bc2647e73d7d8f74ef1f2cb458c1d05df95985e1c8c377b8d77597eb6a46c1e5b8db7dbb76d752a9543ad104e534500cf3e0c1e3c6e3e63c4ca0a80c501e94c7bd97c709f95b75efbd49693d03a9548028b8928d4b304408a5fd4be9a5f7588346a6a22134448478c9719c901bd88328187cf1459d8b87df1786df17863798caf468a1af9318758e4b71dc97372857ffffffff7b908027b0f947b86b84b5ddddddb456abd5969a1503a0aaaa4577418f24f191b4c29a868ac364e1355ccd96eeaee38be2fb76e8e0cb7d9f6d1b259b63ed1585201882210886208c0a5e48842dd992b57609a6f964ad2ddd24b0216262101bc795a003363fbf15f946079a225cd4ca912ce36e9898ddc864d55a1bcac059778fe950957bebb48eb78eebb0bc465482b96cb68ee77960365b47a70059a7f27caea755b6458d1198fa0992459c78458a38f9de88e85db84324c062c992d979ae8c846469f420e9bde927e8cdaa492ccbd213d1f7468c88c81e292844f2014fc8192ec03362d8ec9a9f2dd30c93daea0f075428217041134d5439cfd537a46617beff485fb590cd2df423fbf959c966b4203f79f0c750841445e48089dbed49112b0d0411032268053540810dab181c2c1185099260e2830e371fac4822821038c18328ab2e7f932f448ab4784e96ffc028c1379badd380b39aa040c12dfb6161ea65d7752c2ab048acb53c6e64ebb676ad5dbf01345a47c3c929556f089fac141e418bf391644e35f9e3e0dc00572dbcf4e3dedbf578640a0d94ba490148109c1ceae52e75e7791e8e58853ab9511fa2619468db2aea64baad9e6aa9528a04b5c91176d0cdaafa2526b887fed1a1548fb816fe0302fff96979905013d86c2952e88debb4aaacae20a49abaf356fd2109f62ebcd534dbb716d9ba551b25b0e9b61b28aaada0282ffd4079a05e12efaf6d1b35f9b78dbaad34c306d8a642bb15d4e4ef5a64f7ebf4c84d410777135411f805e77bda3aa88a661ad92c794b696aaa6fa34476cc4b1b35f5dfbc3337f952398e540097abb5914db76580fcde857ef0fbcb8aaaab7e2afae1ab3004451d251d54d5f96b792b742bdc56e22af743fcef2b19b68833eaf0f7a477017c4c1a113df824d288931fa207df88f8dfd3d58be83fd2881323df8b4f5754f4d200f1bf7741f4e04b7d52ad0f820f7e11f1bf8f0157d3e87b710cdb43fde0171cf069ee79f9e12bf13d2ccf7eb0fbaca67eff6981e450ee17057075a749063a3790b5b67e3216936cfa151d20f1440748b4ba6d15cafe3f11e8f1f9a9286fb5bc490eb0e9411e54835c6eb3ef364779b54c3327a30d7185db4e1aec4836eb491b22289b15496d551ece36cd7fbe2860904df1e34136bd49eed74bedfe56f2a52315c07df7f276b5ea0ee9362b7037f1f2891400d12952cc327d220550725f89d1d65131884143eeaf38df87422a8aae562e0f80826df5ab5238192c389a1938a0571f29a49aaaed4d6c8495cd97fa666d0d654b5652011c8b2df7b3d872ddc9fd54258aa143659aa454a65dacdc272f86ce0360442535268962786f697bc6852e069ef0826656e169f272d95c3704c52f043d1f31402f40cb0dec38b580d3c34b3a7389652d4597f8a2d1683412ddecb620e2154f29c70d8164f414a0fd6d857034f748c14b27d8af0c4890545fb46b470f96c0046a5c0902fd41ad8a152f6f30f41739d490fda9103e0415c28570215c88a6b06aad157b582c9608763f3c185b31f4c48e85ddee9801e3376dae0155554155b6793a1f7c6ffa125de3bde94d0c45a14fb21be14eaea8e00a26a997221c960cb9eb50158b0df6d3bdd8028b4c6d285a2b96acfd3ccb0297c16f9efee28ba1da36d5c7a7bff03e9f1afb815558eac7141f91bbb7ba8fbae7442b70b9fb0eaa57daa6fa0405f9882e17025a77a82d5645e5545685d9278249e48ccaaa319e656c1289843189a4436564e8191abc87caaa3c38e4182ce0bf71199c095691be66d4830e2038fdacac4ca23c509b49a3111e3d1e3d1561d288d52252c4cbfe3c2a93334406a385d739c21eee2d5763261da56a2a71adf1bcf4b00bc74be26a5ae5c8019ba7930d445bbb5abb5aa5984049fde488da3019fc68c9a2dc752ee0a33084453f227dabc6f39e52cf1b895c72c0b4862f3efe112647346fac3f1d8e61c32a09949b60fb3d04361b06b3e10fa491476548a4e7794360f34daf05aff9ec8b0f34ab39d1dcf032ec181e6c459158be9737baef5c3def44d37556e4a384dc7df7df77d77dd8891e55798bba0f3f31860783d947090f8082452ad84a9dea4879c9c3cb1b2f9f7ab428b2141253f60fe271f7a3a41d4df4f95d8e2400cd2fad557fd4e8149caed68ee6b5d61a902126b8fe094a251729dc6fd7755dd79d52208aa21873c4bd57acd1024e13f11a9bbf4839a879a8aa7e959a0fe6c81aca7f7eb87bafb5770a2ae3544e1db811683e84995f21732a3258961bc187e05778cd6bffff6fff6bb59193ee7a9e57034e95b8ee0e6977f7d2085b1d060ef31712f15551f445c209b04923fa91d60ddda232495c425ef5096ad352aa26efb339c13a736fdd9bc140077fe9db09cbbb7c7f59513a4e484fe3fb5315a5e3a4e571bc8e13195fe3fb712a4ac7498c9ff1ad0abfdfdb46f4a3ef97cff1fd371565e3fbc3b0ab189646baeaac4863a42b4e04c31862a5b4c610516c6d3f3dc2f42faeb8151772290ee4325e40653036503bdc11850cc46305773c41c614d8b42e235d9546ba32217bee1cde9147c663cf8c1b23ae26f05fc63a62df01b29077b451b1dc8000295e9a50029278c714ea550bc00e668877acb10162878b78471a181b25f18e25bcaaacce700499c0bae3010cf0825a824d7bdac1a6bd21de71e6a760d38b110b008343a8060f6462606a0891b08317efa823b3b8f818208643bc230192c0a62d07905d3e0cc3b1cb378b3c83e58c91826118865d078e9dc3d2f455942f55110298c5306112ef1880224820610532e21d73e43b0220fbd0adda6a509d5559e562862ce1076c7a630c0c8a086c7a0610eff839868b02c4c4c8a1026cda3bc26416ece34036403a4496b1ca882ca387352c38f28d9156173183e00d9290973c66804d7bc7172525b86496b1677c3cf6fc93c69e986f197b605ec6f8314235acbc0d29f18e364a2716d4c8a39165ecf918181b2375f0658ce0c718a9837f63a46e7a19a9e718c1af31d6f02b29197c17ea24f834c0c701d250016146ae2c1b285a6a32328c0d1266d8f4b24abc630c96570cca942aee56bcf47120978243c84d7e23de11cb68cc12f0031ee21d492688771cc5c0f0b061d3cb278877146596b127062606260135ac10f3a4b1e7bf65ec195fc6d8437e8cb10700314fe371903fa39e00187dc84dfee4e837f71f9d36facc4dfe30a3c3dcf41a1d082a1344cff878e93f2ef320b7b9c97f268633cb0c164ea70a22cbd803f378ecb1f1a4b1a7c6b78c3d33606c8c3560d3f321b28c3d00783cf6904f1a7bc66f197bfe658c3d311f63ec81199de6350090a4cb688ca4cf703ce941356248b7c1907eab261f5a39e1e57005b11b8dfef2d2630ec57d1cc8a5b8c93fe6079bb634d2158d91ae70d0d58c9b59c69e9717d2ab26f0439478472eb3e01a336268814defa50016971709b1058877ac9965ecb1f178eca9f1a4b167c6df181de63f2e36480f6f9eb2f7a512a945413d54a2d92ca17dab03bd1bf87dde144bbda006bf0ffcbe0ff4321586e1fa7c70b95c2e57795dee1c17f33c8cff735238299c20ce5551a9942be54ab952ae942be5ba9dcfd7247563831848c1c3aa080c5e1634ac9c803e64b172e2a5522f21326eb3bed1fa16e4725195cbcddc531486f07bd7e742b931d2e8566af272b9aee77da128b2222b821f1882e0ab5bb55ded028aaa349a0c6a495421e5d6adcb43ab282f0926829ea80955e1bab980ae929d7b77b2ff8ddd9feb22f5e89217e6ba6d807a807ea0d27ac697b066a071b6de1e5aa2e0ae809abc6daeebfedc16e4cbe4d2faca50bd79596fd5755dd7755dd7755d34d7755d2e1a6088a62826a00898d6dc22156c0eab83a997306c3eb773cb8246a3c55a68349abb68937eb3a5a5041260b3cd920683c16e8c46a39568b4ee2c702d75d0a6d0acd460d5721c5769341007608427188608282bbb77b6fdb09a7c3025ad35f960937ee11da126bfa19504134c5630882f206225f26200de493a4faa6251957703a549681e0f3f64ff1d5d60d3dbc9fea7245cb4e63bc29706883f7a17441fb2e09d2223e1e8c5cf095f04247cd23b4dae66f2c14d9a9e128ec76bdc234d9959e6da75a4f9b9d65a6b252f409b524abbfb02fdb7eb064110bc00f74dbbbb3fd20c7b34c7cea15fa77744b3d7f2922757d7284845893e7c1159c485091dbc38c275aec45fd121d7171c1095f1f7744a3349b0c73a5d6716e2063de84276aee8ca3b7d87bfcd0bb0e99dde792393c9ce333c598cd0b1e3c6b382266043c02cccc2603012dc8041e99fb6711b44554217074fec80c765d3423d73b3f2051695b5127d4575ad8622c8fe3c2c25fc3ca2f6e4c6821a10cee3435134e64d5efe83f3e028f025ee431547350d0a219a15a12848c0bd381e8ec5e970ae8ae290387784dba17133f4803b87ec687fec13114ce12c2872c5c19012377b44cdc294b88bc7f258988559988559988575b0cf454b944ea7b2c4d8bb8c4b258c697f36d5f3f186d2a43fef337db95f9ffbcc3ebd8eda5a74ebd84c7ac6b9116c8ee3a27c14fce552459d4e2718601db3dc83051dee7e7ad540c2f3e8d39bba03099ce3b9bbece652f12190745d57f18b15e29ef79eac1d97cf193b799abc60972544abc9a973eeb810fe83574e49a1ddf33cc24312cf57a7b2bc3c63804b5ea9068d19b863f918cfc9e823f5bf50f42459921b4aa4d953d420cdb6a2b5e821544fa18d2da5674032af67ff406b22d26c20a8ad5960d2225cb2d6b39e95bbf7767b8dc63b48aea51fa51fa5f7da182a58465d79f78e5853aa79a16568012fc1f0a3b41c097c60fd1efc5e700004f7f7385ee67cfd9139dec5a92820359c1c20281042444845c55093bf006e62294aa9542a0919eda0b23f5099465926d665adcb5abb049780ca384f0a4a5d13570a72132ae37a5d97ab5a6beb698a30e62530b04965415015cdaa0c025ce98a08076c354ab3451867c07614656badb5a993d310716a41e1ae6eeda0367df68c73d6519d15b975d078a9c3468798fb86db799e475aca1643535cfd0354fbfca4c8a6d8dd7d8a278400777ef1210056e6de51d4c74725dbffa8f85863c8768c21e330cb58c1ef7ab9484b74ddf77ddf2773b9ce663200025aacbd09f1623461705509557927d8cb87259708558527245e7471b2893e4609a8949b6c64e8cce8f193587600e479ee2211934e3148164c1a89c410fcbcee72b69ec21cfaadb5313c74cd1578884584e33e161bb4d6aae3f4ed606b77c7aced3a6b5962a63925db99f90e1bb0bd5c07c3f67242b87b83ea2d6c6268880891a121224343448662a68043e87b6304b871cf39b1768b00656ba42501c64cb676a8aa661c17c80f3da88c8fa0b29a46d9b670d9d211842378740ed92c692c070489eb3879e9251024b756bb48ca56d96ab55aad964fc7bcc76cd683aa46dee36b80ebe32a704ca6b420c0b2153580ae744c07c8012eabe90936db25014a8584b05089cb42cf9d72b3ceda3a45029c04a814ee58d5a854230200000000431500001808080583c17040281c95cdcb7b14800d58723c78603e9ac8c3912c098210043110649c418000000821c620658aaa13bf705a6c5dad22db88c098a5623377a1a3a6f6a3318c2f22a34175d1153c104768a2d3825afce7e2bffc936ebbfe2542095e915443ee03a3e19d6ff77c28b5b458cc2c90df1032a9f68484591eaeb934a9d67411126868a67eff58e5c1bc883fa172ac5851266c26673bcd475529b02399d362d1dc4fdb3cbf87c9992a460a0171076704932df0ed1ae786483d0b517a2e4e3bd41bbd0f7f330d96898005c35a31d3400890b29d8b126f6360eca2bd3278b52c9c7022140f04714bd4f030f5383175e7a6732887f6bf1c6439e645d41489ffaa7b626db219711508568c18fed634e738aaac8de18d7d1d25731501cbb4b1ce088c47eed9532dc163153db9fe6d0de7dc62fab52645deedbe8be5ec4f4c28fa8924f2c60970ce5205f55879789bfe20034a9a81137acb5646050c4b2359dadb8fc9bfc0d75cc038ac27b3384316d4e4c4c126de80e3731db011ac5110fdd0108285ea009c5d60d2cca7ca3e9ea6d55cf788e609300c929b02c63c9c23ce75aec290c358df631d8b3ef3800f46b3802e41226889950005fd45611729a679c32ed6dc8ced67be32142f6570e8f62bf50a96793c85ed8cfcb700b9532dd45c2566f23618818d639362a722abaf7a3a6ccfa4e5741ea0bf4007346ac4bac2326e4bdf40a0539ca97386171dd0f726902884ae0e2cd121973b440e481223fc8166612bb5b34f18b6aaad806c8632758e0ce41b43479385b50b301f6949ff7c4e0cb6389f58ae3d00771e19c3f1d0670e2cddcc46e2c8d7b633a6ffa06e25bda8983a1d11cdb02c66ac82b0ff4465eebb5248c62d009f064e6039d6232b9719f3b42c5208f403a94a77324a8517453500a052d3cc9ead6515ea9f8e6ec770514a66680f08fa4074826c91e96b29067a86c1cddc68b29e637289606898c5af77eab559664ab4a07c39225013269279c79982f20a16eb3307174a74befcf272baf421f08dc5e702932f27e4cab67b4f31a8a005ac74407386da7fff141d420385ec08426440bfb95475fef253dc7538d0400e5adda5f1d5af0a590c5936a77e0bc65bb052905935b659e62420565909a511aa7295597fdb66ee7b576be92c912ef78fb9e64c8fb938c28f302223d1b4ea138cfe428c0a130a006d13fb0575c0766a8e78af23629711360a2fd6f31850f9e06ee03809b1b628133106f834ac779709caf71d86679bc79d6a50eeb7b13506e547a9d626a0380e5e2740b2ee3ae3d393ce341244b090288a378a4ac38c28360eae13975260c2146a01dcc3202649f1681b8c9825ea25b1779a8956b8ff66d97b0659ee1ff19b6cb36e48f400687ffbe2498e22507baa8c35e05c7f2ad6f01b790f1f41ddbd585bc908e13fa9d4886f1c0c7199dcdd09e0604cbbacf7368bbbce14036be99b1b8523b9e83d2f97c80b1331827b4f5f0eb765a43bbeac868fd8b6c0113e54cb80db6f2ac2e94a146cae46ab397d6a9790545be7f2e1dd76ade559804bedd5c66c471582d699768469407c9e698b3ba330e4177c521091ac1fce7e6afe27e16e319c7a7a874abf1aff65efa85b816fb8bc07eb5973fd07bc24af51dd0bac7f2062803cbdc1d23d2686a6ef5442f245f1c56be68f54cd36a52f1329af128d3c4f22caad3c8b0ffdb82057cbf7e73912d99e264de762214eb483363911b909da78a1f49844910fead4afcc9a4beae0c95a8661f4839d639f5990028528a2de2d8e9ef520321474a91a7cec327d4f834a3522d5294931c5dfa19d3841bfe64a8ea1d9156dc99ae825a09f7c2ededfc0ed47d5e430d4995fcc0b50c8a75cb26050a3af881c2dbdf17a0ece1612aa321c344c3e109abf873474bf1a43401bec9ba2059fb67d4460448b10322e4179ea3ffbb00cff3da5ec07bd2d0467e1955143eb00aeac08594582880f84f8346fdde62ad70f4a6721b7498fc030928109bf1f30cac3db6f079c2cc10cc97ee14d153a43f2f5ca582d9f5f4b40807cf0ceb7c749e17325ce9d27d12ba09074a57dfb1b57e18c58d170272502b06d207103a19f02bd987567a7090982945fa8dbe95b371b660404b658b04f586fb237056a2dfbef436733702d960f30cf980723be0bdc5533cc30a4c1ac59a4c3e903e38d57e6843940c3a02351af5041e2fe2e4773b02e8dc3a507322cb62d0a9d921d3a092dbbca4e5a1563efb6f7c49ad58c883577fe0bf7bf09cfad2ea427901550e8a5e5e46eb0143a456bbe3326e9db3f3cbd46f43b86067f0004f589303aef00c864ec88815f789dd0ce8b3149f4e377e3d67818b0086bc4c8035522bd922f23a7d3381ef77429b8a253f67e6524af18786879ad97e95170a35a6bca043302b2f384e0bd4266d56b2592811fa3737b2c7e2329349a226f0785ac3a547de921b3df34d555d259a4f9c40b6b9870dd3f42a029e8b18c81bf6ac6afbba87fdf98c85118431cf034eb3222bc4999b821210ee2bc25290a775b63e0af57f3f28f3989592a03bf3f6f8db9385ca8c849db5a8fc19581872d6a1fa963a62a0a9b7c492091179e376a61fe2cead2e7062f09e5feaaa0802c14069ffe3a2d9654f8ea05f61e1d6cb3eada57603fa250d176ec85999a4b334205a8e03a160aec912ad97ad6c37aae8953de6199bc8b7d13cb60df1f187bc5c45be698f1d1879f85d6be3c1e9e986f0ccbdd9e66fd10b94ccdb1ea1502515fbc1948a5e99b26a48b8d268341222675a69881e8c59d9c065036dea22c0c40d278e29a98cac65a2ca26533cca92f8575b025d52be5dfc7980c5c495306c6e7303a27483cd1ef924226c5e10d6217c035ca510eaa7a62599e0c630caa2f897880fda3147acd938b70590422039671f0572ed8d122eea3a45ee46ad735e3fa40ea11522adad96ed89981bda036d239fd80a927ed5177def3c2e2913e03057265966739d347fc2517341ebc898969d304e6dd8ccbb4bb72677edc81f0c7f4059156f85c9d1b25a00b367dab894a5a92bad70b8ad9ba2829fd772b8703fc5d8d0b07b14da09a0140815322fd4ad7b315bb5a18c25a142423eebd4e9155e1109185649c7b7cf11139e7d6bc478f0db38a6a2d237d9294d5307616fb04dd251af48e8a2c940e9907bd032b35ba0414d87785ef4d09bf85a92bfd3969cb23e6a62614a73ac2dfe0db260fe63637f90fc2bef5d18a4e3e0023b5689dca9150ea81d19538127de33f5756a913a9e74046f49b2265eb7dc74ac6738bdb525e8c6eabc806a96b8504bf71d6b674c84330837652ef3f52616ba75e114c1065342aac8fcb8952fa5f779e9aad969bce933ab13c60bc321eb51fcc97066d2d6411bf1b65135724055f7a1611d356562f0ee1bf0fd093d2a943cd031d1d1123dad560324fde4a4a1305ef45de4436ed2997f1b0169c033fc3e9302df86e8b1ee1287ad25091d284a5bebe60f73014230fc19714dcc43ac215e447f883731411cf6b249c6328e1520516c91007b40b4cd7ddea03152ebdc55b29e6c22523ab53118ba736f00009637a78a502147ce1ac669069a97a74718adbdc6819c0404087217ec4bd4ca723a779724d6ae8f08aad16f83ac9572bc817ad5056ed105ef4d02fff413ecfe50c93d900b981a697f1a4ec78347bcf4e4e7a35efbfc422e8b3637952e919150cb4449ee1eee36952c5dc079bb148ff648a3a28f98ce137d5347a36c6a864a256c47bbc871adefb7055a497ce7aa4dc5ce685a093248a5ea1cadd9f7cb48dfcd40e687385081594793df39ef8538ca7978cb95848bc565bcc8003b5b5d3255a5da8c23a09f39f24d458358d1719c5c90fa30e17023688bc686112fa786564ce2ea86987917a377640883a6650821666d59407b3e2d8517a84023b82312801e40a55b14c317e2031ac5946a56de70849cc232401c76399c8b61d1465f091e518847163dd028bb091a1edf0c65b4f2f6bf54b58843fd22507c4b748b4268bd977fbd7eb3d7777eaf2c89a5fdf6574450178c740220f217fe8b4130214342a21ccfb63df3800254680115fa62a3e7c2b5a987723cd6917e7aaef8e9a5ae5a84bdf59fa5da285ca583c9dfc97603d1d240eeb9c6ff62acc51d7848b5dbdf2d215dfa7aaa32d24479557165b5e3983052dd66d10d14f05d7aa4040ac1aed8ea4b3893d0455872e9b8559cf5fcfa0425a22d651668bf7bfadc5744540b53b920edbeeb8f715856ddc7648ec3c8c8d5bbe97242b54fbcdc7b433dea3024088a0c9ab3589dfe14104f49c31adc2453e3fea170451b1685ae8ec4d6b930616f79e760884d1a1d45ea0254f2cd5dd97938349200210342eb4ec6f1e2bf3b1db83014d7546d15546d84bdb441ac39ca7fb30b7e8ecd6e4a3297d8a9ec14dfaaa71e4f36d3bb16337598d493e7b06d9c97f884d4c89fac91b98bbbec873a2a188353627538d889022036ee63ed84e2637f93b60c587b8cf1c0c84f466e23e537e67b943889fa4656db3cbb1820ceca6c564321403d106fdbc9d3c36bbd8c7105726b18d4ccff379f0e33800718fb88f86d6208742ab4711eb424f57f420b293dbb8577b44f3312e1fe18f003875f19458632907e611e892f62d47593f3607646412ef6695311b370717d9f927a5f538588b4158d441b11b89b97d7b60e972a88fa50562d1c6344836b2c39a2c7ab13af38d8e099f324e4dd35f2e3c7e88cda082d826e2522f50542560a84d95de0b0979939d3da47233b60fc268fabb564543e8b7e24c35fa5930bc3a9750fe650e5c3da6999f2f3bbc42a56983c5d7b1c9565c37c41f430644facc9c13f0c669b2d0f67324a1479ae2e995c2dafe3054add67084283a7e6733c5a876907ee666f62b3b32dc08a06875d793c0b0804f4279d3b7709a3a4c3d583e62001195c95968b076ab0f8e4fd7a1745c7077fab38a0a6751ca2eef2c38d3c19fc8296ae8f4342ccb8e5b0b8e5d3c633814e3aef0bac145414f0dc168432201aa1609de54c0b59392e2f6e78aa00bb669d27df3f6a75cba787152b33a4236cf9861076d8ad855587f9a0c5fe432f93fe8247d64b87d3bcb580cae65acdd632810685ac2de28be8a8aadd674b13106f4ef17b7db03729a2a5c856986b5486827d4080c20f4c6e75d32a0a4ac95236a76ea281c8b779595a6658139c96516184ae02bd609fb20353a30300222fa4a21032013f4ab221ca5f0619330d0554a5937828f8e1777f1504187f69630c836c4c52bf62ef4d909d05fed669ca32266b7ee9ef30a2427005514b151d47c24aef4ed72b7234580cff4390f6a5770e8ab67b3a431ea53672b1eb5fa66fcf0b4d4d364a19e21d85035297fbd6a348c550715b53a78764476826e281614d53b30cbe80fc89578f6c94abd4fc5dcfdacdc0d70da1d06f70828467b3f38397f0bec71ed8f5abd0ddcd8bfe59ab895911f925a4852cbea2bbaaa2fe5ae5667dc0a03595e99918f51419fea338b99788a9472f0664724eb0709c1f425ed4b7b8acd77b02194f7afb41cc8440962dc2121851546e92292eeaa9605f8ec839c41aa3c8499a6cfc9ff103e7b48bbce50fe9f83214e6b3282a8d5dd213aee007e0008e33ceac2f9a461fdb4e46605e483b88464c8bed6b4e737f58966df42d5f29defc3764d0bdbc169ee8070c6b9b64f42d324589388e82e662d2cd0b302f20d1a4e5e8a11b7f1cd6267eb224a4d155ace38315a196516aa7f9550a5e5faa944ea81f44daa696c131006b7be4cf5e9b020c3f55e10b0ebfa12c70243f525c0d92c7aed956e8f33f1b314d2ad78eaf87e7d6499eb3839869abcb6739a6139aa0cb13abec3ee3f8d37752f673f581217c935e1979753f794045cbc4185267ecd642469b50d716239e83603f844624c77814514612df59e0f5938fb788bae19a122876a376cbe0555a2c9ceb3a236a32b6a1700e7aec2dce9399880db3a50d4484576283265393a518246513e0bea953a22c6de275be50ea1fc6159fe69184b7ed4136b840b6ed202cd3d8b6a62b246f1ae7d646f9aa5a16882965749e56368fc9edd839c4fe829cae16c3ab8754d9f13a413bb132d5178a34f745a3908d6ad243455327b78b13e56d86c34118cfa83fcc7b0894e341802b0e20a2562e9ff323ea46b0aa10ce41f7bc71b074bd3a36385440820c373192663fde549ec3d0e150be1b984bfbcc514d3826e7c526ddd60b1c4908e892d14d4885d7422b4794e92186f3b34beeadb47afbb28282a69d82440620ee1ad76389a9f762c960b34e74133fe6bfe8c6ef57545e202f3ff8bc13bea1dbd2e848780ea603537bebbbcfe1569169c6c15ca364104371b309c3ae166d71c28ac616014429a302118e2f75680e5ea28225a93c61205e0aa25ba4ec6eda0c304e259bbfb272fcb9f10be6563462ad47c97addf0795eb4099db049e5273577e3a5618a1424eff6447bc0d736638d3e2563413572312271b1fcb412ec090efc0c6a8cfe809fcd0c0220cc9e3687b1f895af5900431e7d6514129f26b31e2e14b1f278aeb315f216a57f74ddef4ef7db17b128f6706b7545765d8b71a3ff25474eb29a10d20478d8300cd0835186c96a73b63480a527163bc39d3df33e3aca1b5946712b007000bedb4663dc7e2df183ccb80e5ee1f687af76c55a5d01290c26b29a7002eec1f615fd73f76079d8eb4fe61adfd09a6be9d54b4e930a4839e5b051348aaedde5ac14493e59f5cf30f0d32b3f5aad0df3ae07cc747786be58ccd7bb95e258f39001c3a8a7e6dc5ac5fc82af9c7c3d2ada7a44479bc364225d6b0077343481552973a5edf57c286c13f945e5850e60e8e0ecbce4d039be5af8f630f7d367a6073f7f3d97a824d17cd67731ed80cdef60721f2cfe4d246a3fd34817e73d07536a7d111f326c37339692fe5e520e05cc0c6edc40b0659dcf8341347c4d9dbd54019c63283a29cb8af3ec30e63203546503e90ce9dde7157537b816192990c5c00d33ef7c6a7bd517c77f6ad02560e399654e4cf55a7c188778e2cc5697fc2b5c575f322d5211aee0135ada63647a6b5c7b8af870da080db40cba4212d194a18a6aed3170d3c2a21f0b9db2e14f5cd6aabc1726efb60a3c6327c5a77dac640d9e895cf1940c499313e662f2a43e6a4ff152fd7a32de4775b963d4160e0da99cffd34d1b27028cf367c94706f0a91be8327ddf26c635367dcccc5f51d60cdf22a1fc9f43d602a011730145a809c2b22f7d01589c5d1dd670aa10e4526d5fa38ec5114511a6de7145401c8282a00dfb8c2041743e16da31985d26004dd19eaa3991018b0c2af7f4cf686ad3860062837dc766de27498eab805ee854faefeaa5b63d1a93efc8c952c36f9a6eb7f1e4d123394e660a442155e0bfbbfb010e99701650ec1c1e0633b3dad68497e81379e6dc09e94ff47442db238e123f1072faf82cb7c9cf70a50c9ae7e000723f96bcb39a472b86a0efd7523086c0d42492ceec02e09055b3fc44e3d8a24ec5e2144eb84a3db2a3ad4faee7436d25f04c90c322ffff01e98bfedf3e45e8c4241a442a8f88bc46367ccba8681c9d5c5deace38c2db106849b850ed09f4e84dcd46f53152718f39d59aa92b59d8f5c495520229e2fd7c887987516917b597d05410a9c1bf3196d4754290dc10ef8bf85a177164b68e35e6bd0d2056999a635aa290116d8a527e43be74b1304c677e48381e00637acc18e8b85ab8646407a6dc19e0b6bf6164ba5ebf82750c692a499d2e96bdb87684dbd282e19da62dd78c90b9ce42c5f163031ab29e0741b360caf538141083b5c05df37bef170ce5a2de75e4223048983c2bd052ccdd4c8f9679036768acd31d29fdd605f5b206b76b693d29ae1cfaac06d6dd2f0d44d701eaf172c337c2354e9e6b0360ea6d37467c9994bac92ea98a389edb00331c1580e80e62e7726836a9e1f83551b17f41c557d90317b03c41d8f03c413e9007195d90162208059faba2f7b977285250ed0aa5c27375a19e1da187f418c19a2751a75a7e0604f134247c1c4661aef6794fa2996e4a6fb94d8c53fc82be467462525af326784ef90faa2ce1615de27c7e3f03e4e0557749333ba788bef65272ae887a7e5c6e8846a2b5901128d09432ba2c3caa533e573e4243ec579f46ce4f5ad31e26f317883110651596c62ed61510be3513edba732bed07e868e15c0e67903762c1fb166996fd85c81c0ceca59aa6456e236ed25d497fed121ecb041d19f8d3b4283b4142a14be3435b18884b190cd09828de3eff88a833eca34cc1cf6c09ac1dae1b5a0106c7f48b0659e682678d7ebf55c58971b0b3332401932fe3f2b407ca67b6f574b29f65f6bd1f8ca41e7bc7fc697ee3756784c79d5fca94a095b8b8c5e54b3a3564ec11db58946f47685c70f000b063bd4269db2b1169ca547a3a7d69283fba83c9538172b73212c4cc421ffdfb09026b402ed5145cd0eda4d3085df0901ab67391672fb2da8b48c32a4ea815fd36952c0ebada2fa5ef6e3496f44cf4949f6da162ec22d944f6dc0013aeaaebe4c383b29c7bbbdab5558e69fb57e44f115e1b944fc109bf3813f391dffd02b3f4e5becde14d5406a0dcbab16f90602924161af444ccaccdae966f28b6668a6336ea85f816d1cdab1d0b5503ea8d48e5a62b3d9fe4fdee87bf773f8e52e5b54fe16c14faf0520719c4a963ac198575077ede27068216e67a1ac8051dd105b11f2dd90778f7acd29b2a2835713dbbe560cb41fe1d58f08af4bcca961310510ce5cd4da59bc88c3f857bb2dd1118df44f548b74aa840674b39194637673ffcf695a25ee0c55121e527127fbf9ad7f6e2419045e8fde1c9a1482903ddb1a305d6110073334f1b1a8af7a5dbf7078e84c02091eb2e9d5901c9ce623cc4de9b6b89ad9376bc3e7ac47ba00dbc7221b30c26af594859dfa588461e190f564f798199b460bdcf2cdc4bc18b5a4b3d165dcef88b4962c64a213895c2888c493b1e0115bec5e6ae03c84e4dfc344ecdd73ad7495eb6a2b8cce05145ecb1042e73c10fcb69bfa0a215c87e0a3086de234164f2410452ceae6db4e51c7aa97b65280139bb2e6a87a9d19e9003a49b20374188ef4e512c5b9b5ddc82c15c9949c25a0531a658163bf1abb3b7f402df716cc8e516b9db0513c85d8838f89fdd627850d349831f1a2c52899dc40e4af192ea69a32dcc4604e33864ae8159afc838327c43c5d4e2c1e2c52ebe2d421301756e3403b838c1545a1992a775b7c69741199522e579116f1dec501a9219bbff8b339543e4d0de4cca1ce4c954c821a7a59c3d0bc79f4673850b9629888436b9f9d0501217f0ddbd4ad2a777919e4ccece7bce59f5e29fae61a162b8fd79e609a68f50cdc598a3bd8c3fceecf706ea3f8f5b930d1c11ada999fa0701f98e26f93621c4230d3858b9b640a462858bd06c05e22c5cdcb9f935ae59893abcb8a54f80a022e877d866c5bb39575d67ff5a8592282c530a9258b50f82c16e1b91034038d386cb3f0b0d2bcc8f458d4a236892860f53f16c566da3b936bc2ae3aa7b74066338f8083e34b2842688b7288ec66de90f3003fff081826e5bc2b7853be7efc7a31ce94cdaf94d3c45a40ca88e1a516e4524fef5224052b3226e494c2c31e2999e601fb37f480527628733f52eaef05ea717ce18e988937693c5be5390cf7e0e2263ffe14c28d7dfa5c4df206366a72c8893e615d451a7a9dbb03cca3c1e1d636dbb163d5b12aa0e3a6050a0aa513a59dd753f9a3cd641f50b2c546c5fa2fd3ad7a596cf6e86f20e00678c8ed5e38ed30e370c5a5b3424e6402dbc6bf27ee28ba69a90d101a5a2a83c8e3ffa043bdf6caf5040df82b1c8adcc58b7693e6330e858cfeb67a580825bdd71a39d1fb3f8a48b1a6702b31ca5febae7dd43632394ae00c3735fc6ee4ba161b164ad6126172c46742f9bbb773801e566440af01226a498ad047d85cd07923b0fbf21615f69ce4b4ca1a2300c26e711140097ec1782bf40ce4d5c04743f5f746c01b43d6792dc06200fca5d641a81dfca96f41085f80102b6b5986bfb9b3919171c52b53351601e6429f371be69497fee19df083f4095654d899de0273ccdcb88de1fc63b4b7815c08a552b41219fb5bb2db161348429ffe5cc80b138f6fe46118a7e8a9f978e75d347e4f2717791e4e8836b7bc0e2be1af36f9e398834d0b00fa594be5d5076d568ab04d67224e5ed0fed372d8a6e651ec4250744a39ba7213e5f6153ab7daf6e207bbcb0b0ee199f0f50900a9805022595685642f5ab339998838ac7f81cee51efa74a64485d813221addecd3eba7a3df7846a3c1837748f16109d91715bf45ca38eff5bec26f4f6c5a3d0091257cb85b2e7fe0a19933d6a02b68677782f76063908d803720373b9c61f639a7b36012a8c788b6ed1483b0a0458e0043556eae03aaa6bd2124b8eb0319c26e04d857aab0bb86a20e8703cc44be071eea5c2b77e0a02a2b45843c4a48f34e402846153accb657d56608b723837cdc831fb3b63265b8eabc75d52b1e448679215fbfff7e26e566b410ca25b6a5b15b4f28815d38d72365deeae5a9b0e1d0680e1cc2a32b2b5fcaca0d60310c570b157538c00a54f38718654dd655b52f32afdc6322e644b88720364d4c51447bf63a5653c66027cb6810f9994c14485bdf04ed6918789db8360d2672c28fb01f2d8242cf19aeefeebef191a8bdd091fd984df01604590b98118ef1013518a4e761ae379898ba454fe17267012201feef9e0b0a251207ed7c3f1478a39ac4a0c84a719ef6e275630701458d32de7aa001117bfdcb7bdc14e8248ef7a8a6d933e8d6f5941b0d2e8a14743bf153750097cdf9b90f411e3138c27f15ccf6f83d31a528e838afb256be247b6603463b81007dd85866172e48886dac0e484173021b498073238acb0b542795dc65f74671012bafc01ac26b6d7a3e9a2d8b40f7ec36b3dd78e8d51afa6ba38b405afc4efd6d2c9618bf33d4ddd85b84fe3d7368bdc7dd73853a20b3be01af3f32cef9b804bfd1a4315e4831cb44c39e9d4aff32ce659167bbc2d20630ff2c70d2990508b84911f94c61df69f6ac0c11b5ed02d149c20fe9227a79ade4b44d57199c5c4c5b539dfd7d3518ba5bf4854e55f30b639e1b6a9adc5475984eaf7e7d53e038ec82c689f04aff91085c55938c50c8ba0ad1893df7d07a1a3e7f08d1f214a6d221fd4955d53fb849087373493882536fc3851c14c0e101136d5c8cce421f6e60df6074c7c11074c3913645337f65a1d7d1c917cf815520f0475b23add58dc31186bd5824ea98e5ac81da492a1391b40e4d04f8e03f159c969fd314c5fc29ada2f37281368dc3ddc6f4ffe8dd57c0540c5962e4058a9f0abaacc07e70e9150abff587682d35450c0de4ee590647e849c600164dc3be3a0591a4ead703c431ec1cd9f9e08ea5c60aa9109f6d08288b6376580ee0d83aacdd98b63c7bcfdcf431ef77cec3c96f8461ccc31abb697645cc3ef0fa7d43a464828a2d46cfd251695be17ea2c41ed63f350b446e4aa34fa11efad0e893690919d5d2bca8034aa0d4826e0b5204d4853ca4062af576c386d4d5981557a95dd6516d8ab718bfa9e96415810531dd8c58b03658032848d172712274e25477e2ab31d0f0e5011b26b082e7e94d002c61dddc214a26a89e3a700c8e25b2a04b5d990ca7a0864df46f536a2d9c94b0b62e2af3eebb776147456eb1b5ff0b623bb0c4d120d823a2847e5810a474d43ac9aa4ded13f8e4e40012eb9c0dab2843ab8ab0060bd66f7c2b3d0fbcd18f5f5c6863b5bc923fc1b8c198278d335c395713848efa23af37edcf6e0743cacbd17f95fb1f9b58a4f524392f64d2ca44d6ee9a2e2806ff3d3f8f14933f853c82aeadb3c7aed4fadb5ea7ccc0b44daee0b262c4ad1153495d8e847152f48818e04c73b06d60feb604d7e3f106e313904594714570ccdf0b682a9aa030a5215d70c1a6779e0854aefa6fd6e7e099f42ee2d27ab04fa8af92c9e480c5950a48060decc2a548b66b03fcbdbfe1e389eca34cafc063a7af0f621fee86db2cdbae0c752553fba6fa716b2b737f92a0360308d29f31d26cf78f19963069fd8cd354aca84e0c3b90df89968b0fe475001c211fa194bd52f3ade60a656276fcfafbab910ce5968c951854c78da1549d24ed265d3fb413c46ee397b2bcf345fb192b82d77a1b9fde4513fe6971cc0d926d6e7093eaa03f789dbefafa6fecff746158fa3455beeb033d7cb3cdb394afe7a5a9e97892c3038dc7cd1ee322868e0efa8253c1eb393ec78b2d2fa3ff26501053972aa1867015413a2b8227a16a4890c90cc8d0232dc8f8089b228c8a9210ce52608d6f471e9a8c0cce73219a014e4d85a592e8d2a090beda6bf692733deaa5fa6ff07ad4bd5cf1675388cd4131b2242d9b410db5d1f48dc3572bcb09fa9bff5267fd851128a82bacdeeeeabf398587bf719f1984b46d8c3d499526ce4e2c7bc39ed6736681bd02981c5c1c301c8ccad3f6994925c147850c7a8c8cb3cd42faf32616441af70132f3e563a4d110f6e3b65e6bbdccd18eaed3e722a06a7cabfbe9c82e955d7b7a24f0a49221357df85b910fea2f0a7decfd6666025c0b946bca39afb950a94be5b298e6a3a8f384c641393fd0ea097d441ce48e2c06e9d01b69d6c21eb2febf2da391c097c187f5da19f70fbe89d30788f6458c7c50ff7278b892a88af383eec6d5d153a49b480acbc88040c9888ec9d71a7d523b8f206ba309caef62e6c5e3bc22765c33de380eea6844c8e7dd4b20592c68160bd5c4c32e8bc0c39136624d252b162dcc0c5ac414acfcefdb3f8774d1a224f687a57bf447f441f05244af12178d44fd425a908b76160ff818968e134f68ecccb8704a03aba54d3ff4855ebf0572fc857adbdc6c61be30d56e2540876d6d64400cc7be75190dd2bc4988c2cd36a666a2669c10b46bc4f5af360ab3f41ce42fe146ecc758252729b0c1b1ceb831f69db59eaba8648e2080c5511610542dbbd77994772c92958ad6a5fa800a882d6f20ee949c5825120a72ea4f23761478e797c96538668fa4dce7afd42fc08cb6509364a9e2fe5e4f5713deee5de37aeba9068f2bf09aa12a0c760a401c3f6076c43b3f5ab0b8a3ed0f1d340cd311ea98b88544949097969e170310b3212d69eaf382f56ce9e63b50821acfadcdfc8326bfc0d9b1118a6b7c3381526ec92306075c4bb438d5a61e9914e84816c12548ff65e373d66f5c300f185b9703442847fcf6983e54431c0c765eff5477592e18fbb08824d057167a9b9c23774e6cf6c4957af3e10ee0eb4ceedb54e304f02e9422652b626b7917802fe1f90724777c435b222429b6a87ec37b6d02b031c31702a058b100e8a3c0f2c95c6ea662185d086795e794b860a11f4819e9b30410369263e3d580ac981b6d1fd7f6a4283214020241cef76cd504ba9d05cfd0d4d2a20eada968cf6ca0cb6254dd4666c0fec0300cf0288ad8c9d24a35ba0791957fee94543cc4e410b2f6cb0917f11821e40648c86e5fff76bd07c41d6d5864aa2b0888eb378864c67223c30f7152f39635cf5ea0e564ff94d954c67adf18fe0c4f36fa45c84e61726e59612f6dac8b2b28a74d0b4956d263355f0df8c3b29902bd703dd91060b77510816bd64503577ae2036d5657d9c25a568a5e64aef83bad8200cd426de6e4e9c29252f18b02de8333d1acc522d06b3ae3462afb9163664c8523542f098531ec0d761438c141e00ba5abebcfdbb72175cbb513885099c524469afc67d83a638141d254c997f800f50dac10774ad816a84b53f0dbc8b5480a06b02148f0efc09d43dfb445bef7a3a8de6199609429820be5704896916c78811411d13feb11865b1e31d0437f3ea78b957c4a23e05ed055c532a501bd470d862bf6bd6141a2357405d31a454e16c91471102ded32197297cfc596ae564183d50cc5a2c24f5008ac33cb79909d055287c6c0641fb959d127cc03a6547624cbd9e913faf9b9e377145077014b151d492a3628509285d434c92e9489313264c74822dd25a83ab9a1b26d89641f8abb7def2d3d82c564cae0ed9f6be59cb7916c3ad68b7055f9aa3087c9922b47d9e4f042c31a2af0ae02d80e65fc975637ce44aee2754377364cd4a635ae4582c8521b8cd9c10a15aa029417c601a6c93cbe2eec6e2fd4e25cb6a635aca3bc81b33bd2021130e75e98aa2c67ee2c4d7bac72df93a3081d9384273b4076e18ca79b57ab6b17687d8755090de434e802b70d34d500bece1b3f62bdd9f5949b3d3254393d6aff7e0bbe9591845c84e7992401c8efa4ba0d9678de73f5147ea045824f83a63c042638b3b1110d436ceeee59e27e18118badaeecef96ffeb54deef939436407013861922db8701c1efeba06011a26e4d91df2ea4697b60c356b05d48d6907c2abc2a300cf810a21e3a23ed908c98a27322934826142179411e1d1181f0daa852be0153c5c8d9da7c31adcbe17841c58602278ff04ad44725e2f4969adca9fdb987ead7dcbae7eb88e1674b8fc742a4d480c9ecd321654c493d6d502ea097a831cb1b99599cff572968302363174741d7a4be302664d7232808a32befa828959a620a949a997d89a92a4dc999214c823a24ebb29e31d1a98548a4fc6d97f7b93219dff2e2530db4961da26348165bd69068f1501a6d499755fa09f09ed9b3a2daa585a230aa9b5eb265a65facd0e54866120507189120a9b825614627944e9e4aded1dc52e239706c4d35b0def6e07a5bc65916a3e8357d93eca13b3d74b4086ee2e4c9fe7eb071cee5f102d891521a052e863fdf3edd3f7163fc6a311827e782b0fc74f8b3df6240662d14eed39d75c01e01a3ae2231ad5683888197088a24db85be9bbd2edb758b886503c0a4406bf7d121c0cf463d84683f15b73e42f076de7bc727ddd709a22e81deec5e0df17b0b18c6a8834183eed5f66a21e73ed28c449751da97cee4e3b7508d3d5e7d2a3dc381ed8108021fba1ffcc3f80e846148bad2088fef82b5112eeccd5e25f6e6625024354ae0eed99d0994c6fe2f9c7fc345996ec3b27ec8a02e226a7d9c5067456e191907fa2768a4620071f2e853e0d05741c32e44ef8e62ddcc7b9e0aa0f3da920e28b551d600fccabac681179ef138c57648173bfe4bf897d120f957df91ca8c996be51f3ee3f05fee256168af5784a9b3c5af3b92a398243d5559aeb118a835aa81d8bce8b6a712d6a3e45b0d82ef3ee5ab9c7e7b6190fd9e3081a8254a0f5642cba578fbdc9e4502cd0c4fde74a8836af0dd72e45f920a1b4733ef6d4f6a5d4c265d4f4f2a6c95e29b46a4bd8cb213d23e9f149b248c229a68a8652c7514b9d7e7590ec22d4bcecf0463981b8460f7015fbe21a8adb461dac7c9f24ac163c1a89912436b8f7feac75156b74d8548eba97c07ef5c6bffda59059a29f5ef11569eab05ec7c9f836f0b24250973c936328d5aee0342c2e214f9ef61379ec3bd79c434b8fc58f20596e994a2c261a4f1a35822ea07847fe1f3210cf508b29124319a715b3161821b4b6ecf1f990620ad8f4294ac39de00b6dc75358dc2aed25e700b6d867b13421620f1a84b682e47f1617b3bbd4203047258bfc66c0384fd9027a576beca8b3d1c20e43bcb9ded4f72cfcc1d4f83d14874c092a01b50064804d199a9e6dd6a80b8d8dfea085f2a47c4541a0c60e801dccfa4815876b57da459c29906931f49e506b415f71e9d445ebb4ed902196bd17c37bb39efe60678937c7be7e506805210edeff7bbad3485cc33dc47d987d8754a75455c71d49965eaba9bf6ecd64d802be649953b2c18da6f984a7689c6a64d34443575b06cbd50376eaf5cbe4337ffe000d5468f05a43481f0ef0ee2de08f08e22d0efac5ecdba667f2104173f391bc24d2bf7b180b088502c2976b6be88bdd6641771ab52655563f81f203f893d7e8b96db64f7b55af26716c28f0e71cf0cb8ce6c14cf4c663770bf2c17523d0769ad42844f93afae80c0f82759be337709dbca8eebf1fc7b5f2b142ddd92d51c01f34d4a837ab63b84d23f00a78a26d9f018c4a712ac995d13aae35e559fbfbc70519fcf184f037404a41422866d62b6371956421a8942d6731aebfd85155c9e9726ef9ba508a66c51b3ff4e04b4833200cef0b01a0320b0fa3b806536c447ca3256d7a9e13316590b8e1703f34dd42163205048e45c114714906df18fb41e50d5f8505eeccab1671b37389fc470946729c2ffaf7d3df0d522ad6d848d203efc460560017207afd7c063412b99db0c8411d0664e04f9a8e0009d0f11c75c15d3d1340cca654c37a67e85cf2dcb4c0fad857880a2f95845e4dcb9e07c80970b4ac0b31198ab440cbe434d6def2396f54c8c3bab1409f8b2e8c813d5ace080cbf6f3d8f6dddce7b27b3cb618d12dc0546a610851bbbe54cc8dab9f68c81d451e2d0977f53393f801d34c60c8cc902aee88edd6b6db5782d7f79d0e4a07ed3dafb12f7e6b940247f4c8118e92aa75a5f24db01967816224ef18beaa719df91945b023185f6998f280bee65a249e67e0f3fe0a3705a814f5dcb4d58ec5241bdd4863f94be225c029bc77db28f81117cc800b6dd2e453bb947d4498b99ddae886f3f0551ec1da33daea909f178a88463a98b5c0463fe4a06781832d300a03e7245eeb1ec58a8d559d0d575019397d8e06001c2c809c3f7229bc1cbf090a0cb91209f3ea63b601250b3df6928af8873b9b3634977cc89fdbf3b709b4a3522c4234a900cad40e8b16a5e3f0986453934c3552cf982519ebde911a7347a5c0e0e2febf5d701371b648cb1f050fd76929f9f78cc32115729e17ac490678585b0bf56c2d11594d7e079d24d673a1bd468cccf4566beb002e68765f1866680566479f292ab316f58cda68f46845d76f2f28696c37c43717c6cd72ce4237283d9c3046f1a303b6d3529019cea1539af49dd1b7a66f00619f20766e350acc6cda40890b3c76932df171ec221941823a0325fff950b4639f61baed4d888bcbb7aa1a96d740c260e0f2a12a56d6d40efe78f9d05d30d631594fb4eba439cdaee3edfac8c462f8557ee4fc5583b9831a58237472990ec667d5945f8e8d1292a073d3cbd79f9c5c667717764ca8250a53350214a182402de4ebe849c7efb9093370021b19434d7f48cd7e597c1ce713f3fc2b6fff0bc8fc635dbb2a41826ba83823c61b0f5a8bd1ee2f38b009d09947799ed81ad5bf1bf72863d5e4afbfa05ba6c9fa16676c7669946db4baa581e4ec6ad75e25676561e5d5fa09c943a332bd902815181524eb31afb1fb41c8be2b0bbd83e0db45092d13e757a4f9e9b9ab4e28a9ecae633acbcdc8a0cb54e621b0c859d515e8547dca2643ae52d6c0e52e7d1b50c4a373c65839342eceb475feb485c48a0736af7edcb3a3421f6c3356f0a24eb5ee12272746ced06cc6991c162fbfdbae22c2bbbe953a0628601e213b98752502415c56e4adf4195cf317220e4002e534a96751bf1c11d615654d25ed91731668027ae5ae329b557db508f39ca76adf07216d3e9eae9a840c8a03dbb0ea3bc3526f976fe18618e7e1757da2453d04481a0d74829ae7514782558d481093ece7c28610343ddbf2db6e7c28c6f956084bead09bf1fe808973f212d89135af9b51b85ac2591074d419d59ca0ea6e7b71dd6cbec9f4bf2fb86153f60a21a9ae95b2bac27ed31d99aa7cb35adec7c04452359742882b3d27bfbd7187029dd8e22f87300ec64bac9397966173087df6d5d4e40df25db02a4d18ccb9fc804f126d30922a75cc32584bdc50780fad0467690e650832b41f32f744f97dcf177d20db9cc679d3e4eb995dd276197991e63dc18470da7f0cb5dc792fafd6886c123b2cca887fde0be0363f8bb6380f95d97401ca6780aaa7ed64fddbaf743c1d859a0d8d8ff77cbb3599054b1e03cc36f491ee5b436f3ff2da03b4d8aa752a97a6ab782937e3b8950183b6369d41a16a1fb8ea1c556127cf4586697541913eec6ea171f4d868df039853d2f24de3a12fe916eb4557519f43a2c1d42512125b191914f777ad3b04144fbf37115575b9150a99648cb5fc4a24e158d824b5d834c31609d4d75286621390dce830cdcc52b4449a3bf85ebe3e49674dd8939608b67c048d83961cc0965a09534bfce70bffc1ee61532fa3b4ac66b592d96507ebaea84943c9db7252c1a0268aa90b4149feda79958584f46cef0eefcbb2dece7b43e6a46e3a81e0e1faee055e9a5338e29d52fe07f26b1061d320279ee2dbb4c64b61112b2ea41045a5874070d9e8c84e96a44226a74ced95125ecd52a240bd8fb3769259ef44774d67cb6d3687907760d61116589f2f380fb7bd30c30fd2d04a8a18a3397837d40310b124d65152ff2efd32b8333267c27386ae34e0b25cf3e05a4b191654fab2b6c4c7547b3861345f9705dc193d14d44e4cb0a258506f69d961ba066ba59092c88408dd51513a51a5b7e597f2c5823c54ad329afc12a1913fd4260f4f57ea182988f94485fc5dec8805c1dfe3ad7a2d4f44e08308444a6b274167de0a633846de458ae62b0845acaefbc0ab63b111f77828c929a69750dc373bd38bed10dcbbd2ebe3ec815631a08b7035b9cf9375c9ac01f03be132a981c54d83510a3095ca510fdad44521ac6b5537b32fb0e807701ccf50c23b03c3d2007b9b4f4a8bcb3cc35b53d6f11b6ee990f5565cd447012c2c82adaa2056240ac01f8f7c9740dbbc8aad378efa8791739673ad57fe81018baea36ebdca2b480605ee282a77756e854e2421d2038ee388f670a7e59071bf21682e6280b164ac8a018b8b4f579ca17642bd358ba48945f5c4550b8bc5449781e9c3e3188c36c1b4db92de83af4f609c5cd3da394681018e6094aa8538cf4c5ee09a6c2cd6343dfe45e01c08d188c589abe72044888e7dd8843690e58cfb0370ff1fe3e1ba0a65c442935e7cf107d97ed8ddfba438d3c2e26e7980117d37824961a8220f20d90e3ec3854c497dc7270d0d404d99758ba3443d0dddca5f6089e5bd44d4ef1ea11270f24b2d44f61558915f678bcc18fe17632313926870af867c288dcab29ac9c82a41eec7dff35d105138a332889a2a86e9dcf8cd6dc13b59b3207e9a2db4d53dd91a2f31df2b6ad0002c010b91a1d788fc01b98d164698ef31ade63814747af618a5338b463044407817e67baff326d57500e317366f8407cdd288f91e3630fb4e8909d24068c798efdf73057b8fe6ef4ceb4eaaf2d5b2fb8ec240e4730230624d41041a3a3d23a12d1beb0d2ae67ba430ac496fa19f1bc1bdf5c301f6d61033c5ff65c4ae0b3903c61c2933564bf33decc903388f3ba210a4e9b018ac5b2e14ac9a99a54370c01d7cdab026a99d2691042c4586a5fbb7fd944a408d0acdb49630f02429092ed219dd45eb1fb3602c1a2b42e667eb7d14dbfaf75609553fd38fb321cfe079a6d8a82bcdc9a87dae3e1682f37da6d4328a24a0d18ce7a547687669a6fd25c87f2cb20262bc10448120c65e4b8158616b270e97b40142f7d3ecbd699be4100ec0c2527e7f3b7b41a3a43bacd347159ad1bf2e7db56a332a8f9c11ff5ff3492ca83dc5a3b75ab2db3ce890d2c3a10a90c7604f7b54e120026110b4154bef2a9f27ee76a51c74ffea3afdff6df904e7e620db6a0f1b5ed86f96e2110fed113b3350425224aab16d2ad72d5e2478804c2644daf054a6af17a12d23117d0e7a01694df6ae309d4395f81b4e48a4dd85b7a67e8b2f8ff80555d6d98b046f45794490016d360de811cf0fccd2233f30a15a9632413b6ef80e4486d7fdc0117e25ecca97e770bececfed6f469c62f589f0c5e3da24d2223b4367c6e7c95ac95ed75dcb489a87932c02d9029ec01937b6549c358fcff0ca7547db2e77b04ad746008f33c5641e550cf11556e4b251b037208165bd18961f76dbdb79617931b3e70b3fd7046da3ce3f7b60ada3df53cc9ff649c7c2986c92feb42f608d24aa1b923bf689dd43e677a5e118115a2e48a4945f0f57e9e400601342903e3dfc589b0e507a088e4a0ef708f91f10d57267c575e1482cbce24ed74e7a4a9688024cbd2a2782dabafd81c2b57a533e530b8906eaf4a500294bcbaaacec8339475c7324d45f9a04b6b216d60e6dbb607abf6d02f778e8e97f5df47215383b572ded5d79f1863d4e143e471633cdc74c85bb06e5642b1135ea05aa6820ceca10d9983917871b47eb09420f0d29d42074cf93fcaa3b61e2220fa9cec50f4552852ec4d6a941f84cd221380b8b473e999d907db9752aa791a1f6a3121b5604417e38eec1cf34075e16f5be7c0c0928712954684230fbe444650c1965e95e95eb682f9dda269a9286488f36a86c33c97b98fa114bf8523372f26a192fdfbabda8ed6990ecf9aabeffca48e066ef3e2b5d23da5e28af995fbd98a887783ecaeea0fcd69958a2c9e30f1595e5db683d0af59a64741e429fe7de857faed78930d75223d3d023e4c5bf8c598e28266870f28678cda4924f7f351f95ff0a3628255a26e31f555ce797be484fdf5fc32a086ef18b26e598d7813e2f06abae6eee640abe612f5b678854309a5c8c92ade107af0de9de551d40e47081c9f3664f65b75f975afb97b9f60fa30071d92e1cf3863be4da5ff0474724525c17c44a0e896654d5799656e8c7a713ee405a02c71cd2bbce66920ca4f33d21bdfb43193d3f2e6831040d7c0c5dd43f31dc90cf82d97b404f111725860525a05f8c52682d7ffdff531daa3786994e3597535c605bd1a12c1529f94b74d93f219b07867d2e3af52f87db124acbff4acaefb2a0352088cf40334ec91c3eca4d7d4a95780e3d65d235d7c0fb65a3368e9252268789922c2910ae0d427061c0702148168d308d8717feaed787327478cf912eaec65ee4b4fdd853414ed22d205015c4f184dcd28b8098462e9a95830ac9a19ac717371f3f84a18afa35ee86bf82071796daa23e4c1cd33be57154cc3118ba669457cc5d9852f68349775818b80cfbc134a4281f18d27850ecdd23c4764d6ada2f1ba2d7b9020e1660e094fd64b5a84fd62c0a8516f4192952669bf48d42c3b2a6932cc4fbf1026ada7645c59c82f5c8176712c54cc2103a1f1cb80a53a3004b32fa93a959895258e2f380ef8646790040898b022917b62b752c0582d9069ab36b6540d84ff5e561b3aa7544572e92f0bf0baf07126f2aa86ef65dc7778bf8700bf85b438c40f35973d9770b7ddc3569406cbad258260cf00a8c864705a2422e209bad3110f5a1a81d6b63b1169794f82db04b5f8ab7235b8aeb2e7099384767a84f1454c4a3bfa13f837e359676e1f84ef118fb1d6ae395d0929e58d3dbe18177c4ea8a411510e33e2c9702c9cf6bda67a9dcaabbe34671152ea75bd55d8326aef89ef2babceac802f53d31fcfacb4b0ed96c8bd282aeb4b4a985ab2b103e5684d21f1e432ba144e3a4de7ce3f52bf9b86a85d8af1a3ac8106d8fd0c4426828821b6389bf9a5ed4713fb9192a986ff9e8fd07d7c49996e58d04b1f3b9ad1a9edf905ae584defcd317500fd2a97caeb7514e41ed350d0e2593a607f9cde7bf81eb6b7bef5df71bf04687785f992d47a803ac596269f609c150c976110282a752172bdd480a2540b34eb07284a09a1cd75370f023f3d51d48db58cb341479c72f9d6c5c767e84f46fbad609585abc07a1a35af8da353107f5d3939a5313e8e1ac300513da402f4ea7830d49837282d46064f8c1d3088a164aea38fedada8e2bd4f353fcc2149fa003bf64e9c6b25e249b15f80fc8364ce7f207b038383f23f21d05e7aca06b0bec2f4d7c05a7519366ffde2ff12ee8a9c8fb6140f02d5d50f8e7715e56d173aef6d9552847046aa8be699c0fa66601d7ab80b1e110019f859257834fc925f0a31f504c9e54cd1a4ebe14aaf7279511a3bfa5b2f1fc1fa150203b3652c11062aae2289c961b03cec37b70f9f501f4077929f6dc505ece0a6e4220b79c2e1edb053887a5cf0d624b73d526a79119d6842e606707d193cdf9f1304ae8906e600739e3477df7252641d2e50be0c6c74fc8391fad6234edd6322c594dd0b6dfb2094b756632f8acf469ca80658d1d54057986bc21ec92ae3579481a3fb74af34e4d0214f4b66015c1db8a3e921345f10694b12e619efc937b654dbcdac10fe1300782270a20f2d7761133269daee3c605147d32960d0e3db8d13c2ebc77c976211f7300f7f30ba0699080381ca940814af0859695521cbc3c800f74f90b79113d153a5471e9d0cf0416a1aa18234131834b4c54d1e9b44f3841d5dd2d83bc2d94987aec2e79fe6edfbdea85147066a5c8a4af17a0fc6762d70e94ffc9a3c85c39a26208e056818632a1ef6c5ad97bc3dd0e2d710b01d16db85c0be006cb87c9ff5e65b00d0b5e3d39157c5efa45b5294e6f5c15cb9bedfff54f9be3aab8ac938b72ee7ad96d6f24f3d51d0670bc61ebab47bb2014f281af6478e8da5c4ba37e384540d659d63271b43ba47ea4260d4d3d7c5a821522cad5c9711fbf278e1ce806aa1ed55c0bccc30898446053edc0fe02149a37ca78b8aa1b769d873ba36355c7a507d48ab028fc7538076832e3337bc45bd642e2e061e91f9b394a2a2cee49d266537e40f5291d50dcdb5bafeb29410e329b5a8cee08afe9e8835b0ea5d7770553e83d7b022142d89e3019e30de841bd48e2c41baeab8dbe40081e701be113f668637a2b2c0bc71588deff4107a7e5b4612f395598f8729e9b190118bd729bdcd09d2cb6be7c586f6bcb210a28d7d76dfc08480d2558d5ae2c152b2ceb986b85b9aab745a255e23998cb58ee2b58d4d4f238bffea94fbee47c1828cd76036f0332c1b6fad0c19c63258c9aef3b68a543d8028c8f590dcd96b2e985486bd06b15782280351b2a2f3dcec21d2586709a8a5a0e04add376b20d8ff3885d1e7072c03f4afff00740ad649ed54f6bde2d2d74d4682cbf23a47b10cb79591e0fd9135c91217f598ffdd42930c3b469d8b02d73d3047414abcce78f24568d911e9ac74bd4973d0fdbb33078d417df4d9a0e72d3228b0f7a8708908cc95a7b3a625a7747a994c55855185590c898f05240b82eeeeab19597de710308f9bb9b81b6eea798e002ae5ca5dda80799d2cd8d82ba63689de3f5552f30d147b4986096bf3f3e1c2e5247911bf3e5a49ec9f6b187d0ebbad33922b96e8fd7d8ca43b50a2d42022488b0f325d10c7352d55c1ec9c7624c725419260e996676fc1141fd6c943b4c972e0f824115f70a586c0896b7cb159156430ae7cce505644ceb2dead762d336f891096f5cb3386b3f4574a4c538f1a624153376cbd3532c9d36c191a2320472baa7569f96849bb8b3b507387109b50db8e9d44edc08b5a5e919b1d7153932a165021134e77f8acaba3afaaa07a2ec850a835ae549165949b3e1d3d79e246caa29f0d9b53ae08f29bd95d1eacd12d85a278ab89e67dfb631a7cdd5639ce86b01242f8ae5c9f37b6da6a0daf33c9ef8fb0a29ff7b3cdcc4ef41b9dc4c78392110a716def8edc627ba2052ddff0936afcfe0275de7d3525b7c59fd74775298f1e222d80e1a9faa64d0b6c275e8351fb5783bd618547fd54c9405c1f6c2d7d5b580ad2141c36169575609e6dfa7f57d6e2d78944abae509c8e01a9f6eb7c835809a1c07f1af1f5b2735fc98b6be9cec3d327a272b61c3f1b5d1d747bb7dab2b033d59769cd8e4f5ab8162638968575b42c46670d457791292bb0ea54a7d35eea6fbf56109277a78328494aa05de1fec101e2386b4ab58adf30e8cba3a624232d59807e7699b1305ece87ff69aac58aa35fab11d7ba66a7ed5c1b9b396b30aaa5e055946bb485723199c0edff2050d8c77168cf575812c928e620d759d1c425cc7a507a3a94720da6dff6ac7d370d3b950e37432414e90b819afa85d856f5c567a58a52886808cd618daed7aca103e46d5301249eb2c919870d1a7611b4d9a2a0437f88d1cd9408d09013c52ede1655ccca87cf1887aef90e48e3d161d5a96a63333f48b25506188f53f494d23f9c7766bb5f2dbe271764e5d848dc26001aeece1ee8b4cca7970e28ac27627b3326a0e62a047892b2e46be4919caa4e70a17f1c146a97af754658831504c5fb1146501fa4b800ed72cce3a9d640e024d8ee66a15341f2a7a95676564ce8703a73806680456a0013b56350272a360ca5c78d3c592f7c1d281bb11ef60a11a038b14d149fc5c6859fb5c83be979ba58cda33565d76bb0c5eba1284b163fbe98af84dea55dd664ba0bdb81eba6c9138aa741ddc531b261cdf6a1153d7d923343015b3c246c846a2091a780d662520883075b27c8b6f37e28127065c0eb5249151e33cca7b934588419d7bc2613b5743dc7c94361f449cd79091368e1aa87b3ddd5497022ccb6d8b09492a723d76913b79f617bb4be95268314827d536f0aada8a45e3d0e242c81da715406f4988e543e5dc1dda2d6cd281d4e6cb5071a71c3af6c1368253653c9229b6eb7688c8bfd88155bcec8655f492ead43b3da46aa86740be9661274696d3142d4fdb653783703aeb8eaba95376a0c1db76f8d02d3ebc41493f79944b7624e00e21d54f9d1bada1f05dea5111ee89a5d30f1a38e39c97ee18eeca49fb32bbd800279be0c4089d6bef33ab73e4d21805f17fb90537f404917bb27c6ed93a26781d20571c64c478fb118ae59434988969947c878bfea3320449a0b4549132fc52ecf3650ed99e00194f1617da5db2dbe2b2f9f2f2a8511b7eac225ec1b1dc970d7eb1206d52078e4b6f130aef8f8cbff893ddff8550946d52ff03e8ba05448ae20a39a16974198c841e35311282cf1ce2ac37269223504f352ab048bab46e288603647e4d644c3270e81cdc04525574e24ec8c0e560ce043444bd0f5f0e23285c806b56eb82fa93d5bc3e585ac95831d7c5d7a8b08848005b4d6b7128c81c9476ac0e1927235608f3f71bda54d48229d126f76c4ce33897958957e92af14710b0b3981b619370c1b728d1955adda1301f25ba8a0ba1ce62fa8818feb21cfe3e0499ac95b3e19905f22f8b82eeb6960f17cdb6b6b5ac2b4abbb5166dad6f08b68aac6772be3e72a56fb3cace03aea7a424981620820e6159ac80b17dd51b03ccf702fae715655e301232e21c555352049ed66e5f49c61e4521f92b4a12fe0c6d44af15f716598fd4e6630455baee30860411c4afc313c5ac028601f0aee3705065c100284322d5fb7b596b0dfc79417586aa8e719b0cfef1b3beeda59b8810912bb79452ca22065806210611f87eefffbcb7b29c3f1c719ee4d126fcd088e37df838df587100e58a0e3658f2e456c6fd57ed1414064514063f04472bfb6fc43e5aa42d4bb32b9aadc93879cb7e4b156caa8e3db65a39b329293db65a595d356a5378887acbeb02fa62bfc756b32996b5c17c6a404099629c33c6dcbde1857e5370ab231622053c9431b97c618309a49870eec018d3d24a6cef9cb30eafb3cb5281fecc7eeadfff5420d9c0eb936ae0f9da6e159263e13815a84c28cff22c47a93cac4b08285a405937d9089a93a0a74c836e9f00427032dbd79af3539e7d3768a85dd9bdcd4a781c4fd2db2716f9d19dda7a4399002db0dd28ec0a5525db1567da15ed2cdaa22798cba6b418a1818493798643f5253c79a3dc78f2d6ee0dec5643349548232e0a85e0f7b8e3ed628b90330c502cc26ba73695bfc31cc7bd006fd0c0bb11bb6caa9e280e91443aca866bbdbced64ed4e5e469c165af796816e3c91d6a7126f88aa1155ffe589b470e85591d9ecf66f8c375ef536375ef5f555aa7f19715463c6b931d2ab22e1469e5d2bf4e5fad854226d8d7072f2de663c9cde2e8b6be5d955d94f3d596b243c596d359eac3ea2a9d61befe2ebe3171c07e3ebcb387dfd140e0b635731be6a117eefafdfc3ae505f1f851abbf2bebe8d5dc9f8fa3e286057dfd7ff615733bebe0a406c10bb1ae1eb0bb1abf0eb0fb1ab90c6d7c771fd4b04b3ab3109dfb12b9772f4d5860fa4af008852fafa37eefdd448e628248c64a6ddaf3192b9765f1cc96c338d00105d8434a249a4dd54a324128111567ac9541aab1412c4ca63c3f4247ce93f9358e34b214da9468d2fd51887e44e126dd9b2a5934aa4b1ce44117712c42a73a9f1a5ff48a2f8a490a6248a4f12476f1a9146636d621269af21d69d91f4e28ffe2389a61f85342393e947a631484ce7a4265490743ee2638d9544dc45b1c2def4a3ffb8587a1ed28c4aa5e7a531888e2e2af92c41451771d15875ba49ac3934f8975ef41f17492f0a694424d28b486310981e72c143133cf49028345617ee25f16604d28bfe0b89a30f8534a2d1e843a331088e1ec2b821e8871e86c271884d5dda49629019a11f7df85f48e41f863421e71f72f04d60088e40443f6ceabe0c310529fc0345914864127d6ffafe1b296053b473d10605bee8bfff4031f45f48f38542ff89b89b42a69a50c45d24f61021f4df7f9e18be17d27c61f85e380691d1f79bc2135ca82069d2374500388018de879e08fe06b788bb09d46fd25b8f311fcce9d3e2f7e96f0c62eaf84de1092628e9d141c78f471c2e2948e1fab588bf0b69bec7e310dcbb37852718a0fbae279e6ceafe8b9006ef6d0a0276ae091e9ae0a1e346934d5dda3d3105299cfbfddd73214da77137e5378527d08cf7ade3104b10e91591f04c7eef3a497f6c629e8612b8a1c58ce786a8127b28e1b9fb4ebfdebfbdf7beffc007c30f431f12bd883f1ffd88f4a4d29746b28ea80554d2f49548fe0b047effbea9f43c24de0f459bfa446aef6ff1a6b094aec5a6b0abdfdb1703148b70514f00aaa6db04613b6dea761f2f5878aee5598e7273bbbdc81c9773adb9d6dc7539ef19006c0942ccf0fc5b95fdc78ff1d36668cfc6dfc7f5c04ef67b22e7a30a781e076053f6757767ba206650fe4f279ae52e9318a975e89b7befbd33fb868fba905c64adbd39e7ccef8f39856962139ba2ee722ed35ab9560065397fd0b199038e878bc2cd6600ead4c4409547089faed7aa064e62139bd8c4e60c316c5e15ac8a352d90bd99d8c4189b32cc6081b0e90304c751e02ad8940157c126364d194fad235841ca39d7d16fcad2acfd9544c4877306348412262280a1b59aa208ec0a932db2c05a2fc50d683a6cb104969d96dd92f3840993189c5872a455a3ffe3c01afd34a4a9d9b9e3b88eeb38aee34eb9be967b79b82814829fc7ff3fef3b10f6be1018b6421818f0beeebd722344888b08787e1ddebdefdedaee137ce6144e6a2cd475348c0cbbaa975faef2cba2a12afb4a544140bd23ea7bda816a1052e6955891db0d110bd03b5373d8ed937d6acc472c458bf9c8f95e2e73379643695e16b5d6b4a6796bcc1c7cc81901901a1fb61a51125e6877a1cedbbadb332841c50b5a2dd4da0e0d8956180a85469c0c85acd5428642d60af7d6dd361140067ea23e3e3eba3bd97b77ccae623dcfabb1f1517394e00bf6f2533568b5f0c28ad60e175db50bc64044157ed8540a3487fd09d017fbd507129c7471815901efe761804ea3932e353ae9d29f94f19e8c7992d5eb48036fe4e178e2bad71eee1d8639873b442146078cc591b25173d8f7715903b02ad39412ba48c2de3664ba02ac02e092820f6a05b502e3e2e2d20108822015fc03bdeffb40f0fb3c30fc40f0034216574c338a19441426a8bcc0c78827cba0621c83636c3581095eb9ef3aadbf87e28516ddd217fb30889942abd1308d96b375e1743ae59c636272ce119e7b31f6f1f1f1f1a1621bc94b722cc3a808067ab99565199663226c61b352a7bcac7c242b916526b3bc43940c83d917a6fc66da4c8c8b9e87b2f2694a396fce513a2ce39f89a554a3273d69cbb256daca28fa85c162950728e4e2912b92613a35c735edeb9ee62d080b50cd4ab12abb039d52be38d865f5806598acc70eb5da2b8a7d85465bc24a5928140a8d19965f5927e7c0720e0c0683655886c1601b369281b6b078df05185a2bda56cca766740bfefc122008822008eee49c4d7635c49e3801e8f66ffefe5d4223e9149c9a7b0a85ec38c249fa0344051001f5b10f7d87df91951be830841c4a31c77138608aa022e4d4014130739ced281072595f6bad1dfe4edf90017b731c973bb0810fac609e42cef33c4f2b2a9db2c3932767162562a0427b7e18c2862c3f4e6081658b19e7333eebc1a970ce44ca2735e37cc6675a3869673217288f54cecb4552daacfcc6974db950e4c6ccc5492c9bc930101094959ac92a4dc6aa393d2c0a509a8cd264942693f560a56666a8cd7c98c96c0a7777569b4599cd6480f1609d23bceb7c5cd529735cae35db540915a0f7ce3e80d87239cfe33ccff33ccef33ccfe33c8c3d8c6de7fdbdf75e6fefadb5e7799ea739ad35c7799ee7799ea7b54de92e6fedd9efb3dfe781a11ae8f4a032f5450b02409004bbae0b29eb6f5dd500808492df1afb3eeccfd8ef61c313bc7e9d304dd3344dd334cd144c354dd334cb8fd61709384c0c90abb2fa6561ddb6ddc35c966db560a8f0991c701c9827adeeb788537578a083abdb5fcd7b4fa7d48e3b62bbe3ae2a0fca822105c7367543478298b5be265af67bbc151d5260a2e0e049cd5c7cb029184cf090a660039edf860a78f5a032d4daee64ff8cad2fad39bfe6eb55b94e521bada92fda8a323365fc4d139c3062e7496d0821662d5b8132071b50e17a22058c56b375bf5f02fabdd741715f81aeca72634d7de1e115565f26d08c1872485272305678eda103b8f1049afadae1dfcf115095fd2340af970ed33481a05c7243a82ccbb2c4a1b6e680950715c2b8252664837a484ac3d159f56555f60794479759156655b61b59a02b0fd8207ab341413c66b8e1cdf61f14a84cedf9390a5486f606541e1b8ba53f40781e373507b5dd942538435be54079e0a839ac96e97e5399fc16fc3cae5a1bda9e5a962894654f6ac6e946b7314e9d7bb38389d38fccc570d9ce8604d97befce885f1b7db1a3f1da6c565fdbbd174728f450700e631c5e9b0935fe1d14cafa61a40454e6fb2d9de46ca7233a22cc8e05afcec9ab5bd2d5d0ede72b2a2b2b4179907ba88cf7a7ee053e84ac45ce41962237b10257c5005446f72764f4931d10b409ace6f1a1db262719380c5417d154f02bbdcba25bdb4ee76c41b8656783cebd5edc8b7b715fb65d5695c96c329bcc569e68ba4fa4bdd7d7eb158a44da6baf3299ec41da695070efc96bf3aec53784fff3c4da7f884435514df43d59ad108da456a2e745ff44efd6207097e35ed7c5fd502f0e9407a539429587be81ca743ad4150f75c50d514d2b088de4eef549aeefed79d766335d65adbc658de46c35dfda2e017dd950a8cafe36c2024d846d1f61db3270725a5283e681eea12ffa8aaab25a09aab2bf5f380d410b570e4e5268ba4567ebaa74b69e3b851bef94fd2151a8d6900d69bc5028ae405f364055f5215055f56138d52236d0545cc1f100fa5231976b0e0dda149f7941c8d280d5b36251fbffda8bff48705b9b58957d1e1ff4de54663f95dad7425ffb01b2abfc56386a3f91bec795acd686e0b4d3abba63cda44af8a0498fcdb47121380b4f6aa7b7311c43a368d457456f04b8f1db0cb6a852ff453e5434d62676ac534a2a3f3cf747825f0670fdeebb4f4670347e78d5ba8ab7e78fa935a6c6d4982d92e2e2e2e2e2e232e406048b8b4b29c5e630f5fcfaa77415728c93959f652b8edb19e242e1df7b41b7bb4c6e896ff93330e0fa59f05e3f59651df580eff70794bedc1968118d8979c24998d3e974e272e630c6b8561eb06c65e1ad9353d402ee68671cc781b5e2128b5dff6a59962238a4ccb5b64265d51b3c522d45f85aba84dcc0a0251b781005a090bab526629579339b03cd612b0d268a936e71a02f7f0740c338e41cbe4b8b529d941bd000fdbcd7c91952bbf7416efffe8239ef057038b8464c5f74aa2379b7a1c03479860c09328386dcd83368ef6ded8f6bc8ea04fc24b2b737e278afc77aeadf95ac3e33d3a68a743da2eaef11559f8bde6644d5b186a4471c9cf09fa06af44380b6f4f6fe45048d46a35d22a8ccb5e6cbb4d55a2091f82f3cf6bff79ee44fc00431033356169ed880af9f057a55cf0238d65c95a5fdb8aa518fd7659a5a6331b53c6c8707346471411667ab7f66eb765d2dd3d2b2a8933408086aab2c460c5366ca4c992933cdab92f23a6fa7b5be26299c6b34e28c9e341269911cacc3c07031ee15b2a028f47df51ac1d9f3be1f8928fe25ef4d4fa4f5d54e65465816ea1ecaa8ca7ed87536a32f8d38a51fbd27da90de34e2944ca5d2bb18afcf55e92fbd8b77a14d6f2a69503f7d21e51fadc08124eea1dbfff64864495b6844541a8d46a3a578606052a9ff7a2dcdd22c8d867ec6cef4d83494cdb6d10fc2e0494b3f91d6877f30097260b59616290c9eb46c98001295e92e2bfcf246abd1c2910bc121405b3296f05c7da8271e200b073f1cedf353f5f9039c9c2b3bea24c3094e9e3228a2f27b0ffe77f98b5e02a49f79c2073555b0768a4d8196464d9148441261780ccc0e1d3869633b64a31195517944d588449f47565b4d68ccf1465406df7b9bb093ffddc662b158edaabc7cad58b182d2624ed062f48516b34a98dc6ced5a5aee66f0c06d8fcdd6f21d2dcda66a11bc96265ce1ae9cab13abbd32a93b00118642211aad858f48b62f72402302fcbedb0be706067eff7bf087745d90b6771c52fbe9743add6e683a98f2b229ec02c7114159fab9540ffc86ba85d1e8e5ace5f0a5f9c07bdee97fdef77d387e5feb0b7ddef7a1af2dcfab32e5d5c26941f7a0e58d4ff2090b203bc5236d53b5891e9d785f6faccafea8c38e4dd17acb380c7d287c1cd684be8642f0f3aeb6200e48f8b084909b1f408a8082eb727e2247d1ed5b22a88c7e3d5e8c6df5b73c7db16f8970d169ddd97b2f0e311c53968019c19273adb5de7b71c0e880c940bbba2d5a737e3afda7381d8c3198635918765596d3e965929306b17d578e6b6f7d21605ba2e70f3e17af0ff7e13ffa50e849a111378239d76551ad393f9d38d74d71ffedd7a32bc74565be0f6503865ef4e1f5b92af3fa742211351aaf684475cf47ec7a8535a86ebce7886536bbea1efbf8c87c643e32198de78d64f579e970d2be04606bb7a206f35791f650a42d1c8a2bd41e8264907c7a970baeed72a173699073712eedf22c89c7058e2fa59752cb55ba22b947e5a7fd769c8b2432d460090ca27072040dea81a9431357a880320317534ca1821aca2a5e2f093001a5c707052410820c623e557770e91987a2b5e601cbcb0275b984d7bdafad65a9655466072a3392b5cb4a9377ef80fc5df75937d97b0c69b6ab575197366582c9b576755297a1027ed3ca1f8f26904393fb74b5bf90e6ea31bf0829d4806b57494306e4efeeecb260002161a264072c35e8d09a4152831468d9810c451869d9d7a596ddb2db5297bad4a52e4b5dea92bb8027d503cfffd9540f1c77bf4eea3fb82f70525b6b73f7f56a7db5ae1507cc2924ffc0ee88e1de3b737b9841015f20f8ca5cb7b50dedbdb7ebea08e88bb54185e3ff7918ea08a80f7ae564bafac2c005bc91a44cf4fa5b7b3f281cc07ea7f6bf0f6922d1df7baf3853e3647d711eb316e310fcbc21f4e506e7f59a49b1025e9fcb39e79cef49890fc63c9f8ebe576b8f49595e4e8bd0b182b26a28eb2fff4116cd047f82d625bc3ecdbe8e114e4b1dbd75f9ded87fa0f15e84f79929b8fd0f5f90d6187476d509fdffd7d86c361b70db49cd71e17df10043f0cbaa53aaf4749cb6810f1142565327e90982b4918bd76e690fc89956d2587067638561021d28a86df7eb07df3e4d478fe8dd77fb41516bdb3bd1f62a663d7617db54cd6205c5fb9d684306e8118f582471c7cfddbf23a6a97aef4da3d1be1aa3cacdb7f2e034877d91e8c919bddefb044f0962d083560b0590d293a415128d38d58617024f7805bff2c827e01c009ee338eefea5e787c5799ee7799e27c8e9539ffa46653e2de7798aed7288c5b5984de92cfa2c398ddfb2d7fadc8842d5ee75a9cfeddaaff356775c57653bf116746230891e2c4954f9f901eab1d995edf9c9494080b674b6d994cd557a8ae064eec1e0c541dd7e8cd36750107dd1678dd3a73ef5a94fcc71fa1491e854fa7eb966a06ffad4e7778a5ec815a6a38a30ac5a6a144662311c3dc496600097d16bff4414df7b3dcfdb58c73cc13c9da98293d4348366b6e0b77619986abaf2be3e48596027e3e607100ffcb0b7691061fba5a1909b1f40bc5db3bd5abd7a6b2dc5bc5d7d50e00708840590c9d3655d81a0711ca7f53d754c56afd7347dea0c8afb649dfd787587b27e8c600f007ccb02c73abbaa028075acaf24e04eed9d46a256b3cecc997e0981d1a07b0999016661f5a5ff1f630ca38337512eb902b831317092faf8a03e5664c91ccdaf2431980f2cc62626a68ac501a3c3c7870744ad5587579a339d82e7ff2938d849136652eaf0d67a7f0a5ea94c4807ddb1a96e84d39e263bb228668f535e2d5a046daa26e0074e525b8dab004feaa84b9d4aa5521dc7711c9771780276b95cde3d8203565b105bc28a133e626a623e8e4a07ae62c0497a765d7777b092001cf80a4e3490d3ccad22a9839c7ace2228529b4fcc88ea3e4ca1baef6dc01f719e74a3cdf7e188f338e0cc153550b76cd9a2a55ffd1fad750ddc0c00e9414ebdc654f08675dcf1c3cb300157d3ccb16885d993cb34d44960313531954929e4668f30c7713a6acab22cad600605c60b17a6126904e3850bd3ac34238df22ccf4a6337229148255289549a552a4369558a5d71efb53e8f7976c759068aa299d01794e869073f27a93c68a83cb8cfe15c76a5c5aebabf4110faad666d79269685645ae6c94491a8419b9ad16ab32837dc036591466fbc85ea6d14fad1984f2093e51cf24e9e85c6bc13b3fa8b6d1a6a8e9ca4e618fd8ce5723817d672a32ff80734070e4214278ea95836c3b359d96427731c379b896c09047b6ffb27fbd4bebe5bff8cc51ec6dedeb56e4d61b455d9e7110427e91519a032aca77105a541afa071c5bd7746d7918610bcce70308030d0080f901e3f947012731b564b3ddd77c354a0847f5c059cc43fdd7e8fcbb2add2d7278e6895c052ed365ac0c90dbb36854f20bb3a4016bcf6ae9e243efbade35c577f2456d387af7a7810ec834dd9c7518270701615b4c088560b37b6a545ed0efc26c480931b5669dc9bd0c3f7bde97b6f5b24bf262787f439f46de0c0c94a2b899576376cc376cc1cc9bd5356957d72d36ade48725bf7e9dca8c76e2453b8860838994fd2487ad3e8e2496f03e34d0fe34d6f63c3b88d1d0e8e6f72617a1bd29bbebe69c47952471c176f7a1c119ef4445a2f4414ffd31369954414ff174fa4f5dd1b0c8cfad24740868c2fc97816623cea298da7a51fe12330e3698c2cb8f8193fc2c8c2131b173fe35910e14b4f5ba2ff5c881bb6635b561269b990817afb34ac1b06e363844233be14ea9a1cd4cb781144da2afd0c11623c8cc72ff1de44da2aa1c42a38f85f4d8e0b31756dc8788c87f1dc166bce38fabbd1d3b012e9551c62fb68bc486a8efdd3f77322f9a3ef9fb99e8877401cb3298b7a40e95fbc4de95fc418ff8e362ffe34e2c018e9cf5c914862583e45f2fbe9b2abceae82f22d6be972ecead5e97423fed11968ef4d2b6b1fa12a259bc39dfc2b837d2477fb0859591b4955ed1b6cc8a23b010cec369a70547e4afba12fa34e6e98152f14cb836e2f1637ecbab77bbb3f601996e118e021f00a72b63ac809d7377d2ec1ef93faecf2b937ee76d76d9865bd34d9b32d259f7b8acdbcb261342b21e8e4966d9e1d65d3babd9d39c8aef013e7bdf762d9eb7327d9308d009bdab05d5ed68da02118810324335481a1657fcb2e0b034e64b1528513570f575af6376cc760bce52fea483e498bca8231eed825e5339f2fbe042ec60d338d1b56da30d2a69d5b08b55c39a12b0ecb6a0e2174dbc55d03dd32d0d4360155d90dab39641b0724b24dcb41f996cf0dcbe7799e17cb5c9dd6ba66c3360c0c11e1b684277870e8074ed2db4d8ed5b149720c95d12fa0d2777c60c18da7d3e986562487ed240e1c95477d1182a081921ab44072c4882c7e3061a80205490411d482c18414576640c2081a946871c0d6c38bc90c4200d3a2653b4502fcc00ffc7a8ea082529082940b69c013ea96ee51c1759b98a8b4ad3805b96433220000000413150000180c0a0583a150402c1e936bf3dc0114800d627c42785e3c1649635194c33808a218838c330600000030861042604335015dc03c5f4f5c68d33a9f7a6b9bd3f0841cf22d846256b5a5fd6d4a7a1e8ef6ba8d8136c86566341f72dc36f0dfc7eef7dbdf75f290cd07970b8cef4f96957c457de74102b2b066625e8617825b85a9c6b04f343bf7c05af2a38704227ead8175cb909085ad089694205f059dcb9adb7add8b5cdaf3762e0d3e90846c60637cefa6a55ae8aeb1239ad0f6235f053d868203c9959084503c6f106b4e898a3533d3aa72541cf3d096969d8e66c4d37530617d0480dd1c94cf128ca30eccb9be637ae04cbbe893438e74e294ff3a2cf3b93396e1231ccbc2838a719479537a5d874f84290cd8388e57249d699c30769078b8755ab974862faa1c19d2f0b531cade60145242597839889c633a1a3fbb1a94ff0658ff87a00d18958181113d5934d29fd05bc7845e4d506d5aa830d5bc80110a87574d2cadf082b31bdf80968c61f109553c2ab168fc8d3d8f463c1b45d49d6c08b9b8b7326adca0b0c0317183f7006f2868b48e5f87f56bbabd5922e1306c315652e4089b932ed28dc4bb31343f872f1dc0c1279a7fab033e77fa957c14f7507abefaf3b527d4dff67c7aadac76bf20c77fed58eae7a29a6ed44d229efbab4e52ce9bc9d03851d3ff4d2bb870aaaaa910d8dc5373ca6686745d8a9b84b5350a4baaa77e5fde3a9be1e884522233128e87607bf3f9433b61a2db66806a161aba4b84d91e1aee5f9915dc05ff2ca7b51e27aee8cb2787a3d3f61950a1dfb4c41e486d5b043608a39e432f0bd8334f633e6660f7f0ea6431689d08864db4cd235fa8e126bc5dc9a766464b514862f02d5509f81b14fb28344fd48b22fb7e7d9a062ddd718aab14c2f5d2b27ad3b8e833df5ddb0348ba7ea471df4f15cd067d09f58f39ff418f9210b76adfd48f588e99141b6c1e968351fa1c08b60ce634e9a3921124a8dfa6993620f2ecf2684a2fca8b96ab0015e461b1a017d20018e086422f641134bf3ad45de71b0438d77d04a662cd85442c61bc769ecfed565d8380cb3802aa7c800b5d3339de5865b6c76f97df9152a87a43422eecfaf28597e3fdc2d0388e616878bf989041cc94522c9f3492b2d5103ce5d8a1c8e70a6cf14c2b1ca2f0969b74754c3e581cdeff55b69be54d8d63c11f4fd1f0052a1ad7b00958b43b249a534bd9ff3b174431186ff779c239792456d3b4f601bcedf770f0fd7d68477c47890aa7bcbf8637f38c08acaf6d56c793a9129f37f86972e93938a4f40f697c49455b863c9fdfd54f6e400d9e6846277e0910148e44483babe34f51b1ff17426bc5054d1d8d54f9cdd0d91ca825f457289ccff1a673bcc18bff7521f8cc7c9b3360cff3afe13bdb3174e61050b4284710cb81b8ca4f4260c16618a50e2232fe04ae9072a62d2fa3a36c23473bc530ac78a11081013d90e4e5cbd4daac7f51510d334809fec6b370e2f22767d4bb13bba0c219bc84cbbb643bf4b0cb94669128f3cc926aea253dadb00318627092b57db30738a817fd4e7443eb868844927ba726361f1f8f4499a4e93bd4a185239325f9c4431e7ddbe2187eb520b694feae3b732138755a102b09d81532c2b23535a375b4896f748463545674e0744234626c69b1a171f4dc1689d677edbf3ffaf755b654bb86e3743e18835d223a3e94640f3b61403a12e2e14b27585b54d0c1c39329434e2c93d7e34015527b28a716154013f797658802d088ce41aa720a542ef5ed766b0bf94c564d1b887791c22454fb2c3b82f23be7cc6743eb0097804115ba6d206d805f9e1ad0bb6949b792e68aada9c8b52409912b8947e6857c43eacd08653bf1b747a0712cd16115ac047b10267f38242de0d0f25c2cee525145d874a04501a4ab400d0c254d572853f90c4ceddf135c915fe83eeb9fb5a28f4bdaef0816e69dd52f1294124a9c45f0cc6dee69724f3e841954de4f65031a8cd31ab0888f94bb40cb0d07fc2e496e11d9983184f383a2ae6b25de9ee1b6379b907be42038417bc23b9bfd89960b1362364d03dcf8c5d9cce33ed142c17ff9d68a78314474be4e83b60df0e80c348c850f247bd8c629a9179ac6913b7b28bb1f622693742fd684633204bb90021edbe53aabd54d7fc22824381265bc84911ca2873c317cb320c8b8c4fc57f8767588a17454a0d8e7522916b9fc97e7c008f6d83963f77254fc1d48379b16fa0839cf9a1a006df7002853d360d13697b6d80ca2b4fbd8a99a70af416fd808678af0d26a91e286f696aa54830e8cadf051305b367c882c12f2aee76884823ced0a544815968a6e52ff30bd67d40b316a092ae4bbbdaaee328a75d6419e1955e1c2b74c5db02a77de0bd44c43119076699973ba9f85990070c028f1aadc198095d8fd4c98b9e9e480556af30d8ad58bddd08f3f2ee540195a87a8beffd8d2fd273216b29ca54ef6d21b1f5acf1ab358f22aa6ebb55e93db64deec757c5097191e84d35a51bbf32c0a802fd117fa064bad60940a05ecae4661778aed42306b51b0dc4b584323602903c45fcb09c557619f52ddcc6cc08acdfa583b9c6a3aa6ebdda88eec8939fafb0b63682314b494e05e5880e5aec5a2c0840115d58b0a7e66d6a2a8ec568ea563af88e563c074e000d2fb600a6c20b14cc2d49158723716f9c6e548bd1438d21480a2276d62e5682a4e2ce4754c10fc7a259dab01c910f693a3ba3ec7a767b8b9f52089dc9d1c6da8cba280cd0fd45c1c0c13ec00e58c69face579a9d9d25611ced17d1b0912b22b109fea6eb8256fcd6e326539553aa37b66046658cf7cdf499533d2381091bdeb7b8b936acb9e2ac17f144f282f2cbed11842b741ec978b4a076c10f50974467f59a27903181ba0a7e5b57cf5bcf933f035008d05c12f374e12acbd7169f1aae4a30fb883f4691687bd22daeda26e38c60abc5b86e2d6fb6785d6c509fc11663132617e34d5b2c0d4e6d297276fd74baea37f0221b9447f6c9188b60a1b8623f88c4907229b5d19b0995f8fca2605a2078832bae72f085b98d4e6e5bdcb3f4c0fa211b97e0190a00e76780f34aa4a002eae50fb8266460e29fe05db5a93719bc8ccfe4182dae98b9316852cc5129438bcac482a3e247196f5417435d7de591a37f0f410384f3f3bb8ef37861f888e08b3d8a372eb1858967f608b9237a9372b9c53a379f414fac5174cb12e802b630d6d5f5a1725be52608de0cffc939616a706360fe3413384c41fe15d6f8cdee550bf68caff813a87253948888b98bf3198605e840615d75a4a2bf2ffd2322271735d9096c16366e9afb3f192fdea76e00908d8cf5d5e8fb575f6a9d8276dfa8cdf83f1be8abd0032287701f37352cc6ebb66f67cbc1f9b6f185fb410e2aa57850beee4e0d33c212fa8ebd07e882777e45f907d2094649393df934c967f82bc50b33b48636f67408ee0cc820aec257866ad3e5b3daccd430671afbf72432814b02193335b69c38699ed32753c360cbeaea3099323d980301be71c87c30067c6fd203afa4d022f91c4f6915f4a3f0bfdbd5e44754734bc374487e8e883dc6e8819bf2f311d24d64b97cfad14d8a2b0b1bdb7dcbc9dee78712213bbef4a5cc8ebc4b408398568b0a4555f2c38cbc1c546dde6ed7ce7c5ccbd186913ff0bf2f14cb187b828813fa7296d91b17fe430ba09e1e60baf01fba34612d73eab422a92dea362bc5abb86ef553a22069fd89d7fc3e4a58b10a9052d7180716c0701661028cfcec61fa39c4a9279de3ee8ad2394ee63d6bc06e55566a98c248abc9c7c5463f875edaa122deaf551bf1e5ff1523d97f17bc25e8e7ccb4948eed7d9a1d4ad2fb326640453cdf7ed38a886e61cc0e30b0a390d946acc3447bf2686cf1a3b13398da5da4107af11f4168106cdcbc3cbc2a8a0d0a70e9c562010d227745474947858dbc5901e36b964528947527153c8683556f8575957910dc519e89a81bb86500e48246c04c45b1eccb050899020b6a509ec34c8a9ba68ac48e24e682864180b24201642ce84ad478183b1cf8030434cc80830f72f9e25882497157239723199843ba62804a3bd9b088a6457db6d8e358e305c2880991dc18f7153e5b2c0969a3e7465183cd8e3430312d0e6ceaa159f19261bc54e0c09920fe52c3986661826706a96b2bb41118a1a5db009b1c4e0a781b364e5e645a62ce47537bb337886116172625844ec2e7bc40c7a12bf6fd67d97cb48a08e20745821952edd618badc3013d0f483c126cea739e5625b630d73c0883013dd57348e9d3483372ce3cb9d8d4d5ed5b9520fe041792865849fa8a91c9f6eca62d327a213a7990f6ff2e909400b6fd55fcd70d768faef6b40de1a7342b6ada313a7d6eff9c1cea0e5bf98325e2d1c647f04e12ed2c83fd17afad18f1082b60f08a3727d79da737f6fb45403f0ddab02b438b9f57ead5003eb2247fec4bfb30a042c3b531da7c4d10afb73c43a84a97a09346d4787e39b448eb33c9f5c040128206a1b222229f574d6962eece9c6046c0003f041937cad71750377a1c5f0cdfe557b36c66b4464a6eaf3fc5561a626b40f5435738fe88285a1757073e4947cb01b541c39bbabd3ff46d37481da856a6fe3feab50aa59386f453c181c142b1bd205866e6c25d4060c843dc037bdf01f003a2d4b4183c37319f92dfeda1b7ce27353c90ebbd3fa234cd782a0d5b71f1b88065d877c1a1e210b2779aefd195c0fc35ee8bfcc0bc3af272a2cc5bbb9a4f2db50ee33a2a28850f85d0def8b8904f2c49b0aa3f6d8a093f54b34f08c7331323a5ec87fd3240e36b1b26166412bc13e7c26c8d9114785f9b4b2ecbcabef59375fbfe0eb6b1fb4d5f7cde9058877d0f4043298df08d9d1f796fdfe55a5441c02e9d8de1c460d2081bc6ece852a50f3f749e53a5174ee0bed1d15624114a368234c25a57aef19c2cd53cfa882318a633bf188ce1cd5120fe5ab07afdd2973f20c0d02383c924ebd84f03f9bbab5cca98a1587b81a9159fa062691af055de4e73e9bed21188431678203c4b2e597c4808e2273367338b98e9199a8f78800df24f79d6663919c49f073800e0e54c88f053cc8047de2800136a33978d8f51728cf497a60f6d6058d33a3df448e58faff6688f8420967df0086351503be0481108550840e1a44e36f723354687576a1a57168f824c6b9df7ba09b3c54ff32d8d1b7b11b548b8f2ca9fd8006430f3822a0979829806b69019b3cb11e4fd4328a9ddb09a403f5b20ccd9bea383a4ec07c0c220aee52f87f56cc85ea4bfe672e6ad77b1955b4548727700e40ea75144040dd07c6c72842114f6846b000d61102627fe6a372a646326d0e18800d33c485e9b8281b2eed53017fe2fbffb31aa289e50928f354341024062e75c4e045e20c71f94612defc422f2059f294cedf446fbe29b9748bcb928a3ac4374f993d631fd8641ff49b9a8e5fd197114e5f0fa982e0e9941db26d6bfc788e05bf02a579c39a918fa28d329135173f5a3e28def58d9c87edb25729372b1d6fe3f73d93b2bc3be68e33ad971f164d188edcf94bcc9e130404e0a9cef436935841b96bb8c4847d682b9a34fdff03faf1389ceef278947951c2f6ac30655cea7481783f5b44ca0a8e4978401722ff5da315ae38b89382b3b5d0a0e186620f07bc8aec5fdcc9c713ca906f5cc0b6c41cba450044aa3c508b17aee2a3c3cd675ee1cc75cf772b16e3e020abf06ad4455c345157671d382447b450e3020702566328ce624820c5e3961a6a61d5a787858df12ad8221eb4d89a99ee7ab5955d73973756edea13fd535c63803a4b6f5e27704656c9f2e0727f1a0e8c19aa16524fe056b8874f343d6e409ffb34c34421bdf3ce00d1a148426bb294b8626fb12294d6de8a72acbbf7a82387103b9fc4c7e570733c7c66ef2e822510517fe951ff81aa7c95a17e9337f1ab71166592958925f3688a68751849e8c643dcbf24dbdb804f2f9e9d10d0923b6bffd9169cd674f38347c0ee5d4b5733d9a64d3375f5359478dd7be1c80b232ed5a0ed507d8914a9b7e98d6359de34631abbfd2fa5144c3d256bd3ecf3b211cd96342e0698ea0869a2312d7ffafd329f419ede21af818ba36426bcb67c40d1e5198d31e52f63a827f9bfe685312c00f4aebc0035c062a41eb02cbf096807a0358a1635a5fe780131252fee382df190e42593607d8ff6c4ff6cf50c214a1fccdd048436a6bd4c49212455d2c517b3f77b9bd6c42da2379b63b917e472f412aca957e5a268361b382caf985e7189af2ba554143e1bebd04b8df122dc29bac0f49b56990ee07e28c28dd3a09d378e0f5e3f2b0acb064fa5a1bdbf99a258eb7c256cf594ea8d36e80e1545048dcc5a44e2c05e4521092f06d67cdb202a9a2bef6c25bd912ea1dfe65c43288af2f3ae7442d867a6a6a200c1f366607a8a62babc486723bf07074a3c702998b36107ee1cf7374c7f21350838f90ecf2b04c6d37a5d21243123396281b073a2fb646cd8fe597a749a52cab82e8e6adc90691cf1a8bd96ef5562ca4e74b5208f39b45691df827866f431f9654e29af312e69184f2d0d65f0efa115c92beadded8baaa2afea935df8e826e97da7db274f66685cd3044e27220e3e1b5b006a164fa6a7031d9a0a605eb866e8ccb146d0ce3aba8411aabed243692150254f8aca84932b389d11b53c28f315e07dc7e837a9596063689df7cb65a8680f9bab2781a0374886c1b902a4b44b44ad9d6e6d4fed151ee6d10c5101cf07dc69fdb3b307ae144aeefe0819621cd55a4ea96c546f45cf6c47f66d5902a350b14c2cf14448db6ae54108682562cb9522b668d683c35bbb889768a63857320c5cba14680f7547eb61f6c522a8014ebc6cfa89c8cd1d277bde852c98c2f6cdcd5ffb578638c764b76db5ad5e93a19b0c2c0283d6c5a0e72e60710f94ff30f3467bfbd028fcb35717e2162c5dd3836ab28828d5d23abfc506313888db8d0273129826fff415016e218e6d6002a9a14480de21b61904a9d863dc7563d9c2a2aee3d62cc53b3b1d7a5e7f0d8fb6241ff98954c0ee3d00363b101a738b35028b955cb9fcb84ad5341cac78f9c32c93a9415b46f5b7ac782e7fd38c0c38de15039fe20d2f6433570d503d1004ba656290033b41aed261582e68d03a278d2bb9e0331d26bf8fb3844ba756c749de3c6b1d0cefeb1cfd096cb7fd14778dce317c4044ea3454a1011bbf306d9bb03028ff9b9c621e984eb22e8c045499da93861156ecbdcc17e932322770ca2a44ea658e0d73824132481e083d6294bba241ee31ffad8b8a92460fa9395b41b81aaf6e1b46f01e6e2e666395d0d9f6403d484f4f767e01606d4fa571202bed76c1724816dd42e202dccc60d95841c97ef88b3f82e02f2c9270b454d6eef5361d2dfadaab04692c6d0e417848f3bbbf381a90908ecf4db9728dab6109006777c8eb972eb3c5c4f688722d2a3fa92e5f0dd5a8ef15db3a2dc955ed22074c48b3632089d7acf0d33b41945a2e0ce0f8c7a9951c73a0f550d317906ef0c6670c4bcd6e323ac439ccf7aa556120c3fd183641febb3c6df033ff5e87d387d316778a10efc44910e4c5aebbfd256c1094f3a6676ec4c023b8a6c68817227ecf88cc39c258b907b7ed5cec8864af9a7ed771921975fab558462e42bd86c9226ca9be13a3eeab6bed602ba053da02b92ac102848967b084feb3bcb63b2ea02840dfb70b2ce139e002a6b68f8229f9c4e59ffe931f22d0fb2549004c0142e1a05da141af6f3dacaadfcb232e8ace969315060bc0f5694033755518d9b3e268f303550a44f07f70857372d2eadcd13a6521872d0b2fe97482c609e613d53317d7249bab0462abda4cc9d59e01e3bb4a2e797ce4e37e377f515412f5b0452fff2b932e2ec8f821207aebe910674601d036ae1ac674247886fb43408024c1215062309b3eb1a2097ba77519c234c35968a58ff4c03dcb3bcd20c0228235da336fd7f1eb42016a053718b06f6b0c006dff4d28104044ae4c064a15f2450b3eed3a86b1f4f2b0c1ac9c20565811dadfc43e2b24485905331a30ac934e73940584624451dfb202b7924821e05516c222537bb81ec7f3b2910cfa0f6f47c6b9ecdf8db45e442a5821235089559faac43ef3bc9c4ca42eed4007c0256e0db6dba39dd3fe4ed800fe83198043bebf3702f05a39b8adb16420a522a6131fb8406621f77fab86a4f863bbfa8287450d56dc080d501837d2b4314619c6e8ca0587ed8a39f83e6cf63bcec007e6b310d84740226b0d8fb706ff2603f92f77a3b77d58214bc79b05dabc497aaf4272967c194a36321d6309e15681b4af20e4a310f23905bf6e17292e50e895552c16e3a68f64f6117efd755e0854709730048b3bd495f33248292a00cca6db74bd3fb09c10d4ec3ec170838d68f427d027202c9e30c13e90274ce04c03054b4a9e2d1f0bbf42b9da8b1d2e57604f4bd0c5dba44cdd5c38f0fad8a9b35060a04cfce2b003c652bd4a72f4106056709cdade018518f6867452a36a921a80cf117d26a1a9135c687ae9fde6a18f9c8dee08314c735f1b7ab13044d12047ddbe41e965488363dffd50c88f1f0e2328631c6943ffdab85244b2025910979c9f493dca5607c98bd9dd489055b1bcb59f513bc9e3abd0e37fad8c0ea3dcf16671305ae4c686a6dc6d765194ad4665aff906097c41b6bd6841551344e2e1af4e7496d779363a16faf860859bc52d96e73482a26c858002720497d28559c0f2ebd721ad6b0faa76343cf8f61aa072d8d769c3254018fa291195b7a23ec19a0bd4252da26822a853b3df52cc6514f2062b1839c2ec022c512c97a02a38b186236e4298742dfe13c652382d02d48404cf27845661c004968b0ecf2bd56498e8c235374df3476128421d64c85a4c8e80c25bc55a90345518802130c1e8523fb3ce93ed7a03d327943098fcc67e06b5cb933dcf5d234d0b3fbcebcf40ef5bf093f39f0861280cc40bfad88091bc4c57e7ead083a58f6e41fd70b7e6f1e7187d013a5dd874ee0c2d0c88057b59ba0829c634fe2b587296785382c468f0dd0377907e3e7099d47ed86bfee8b673183aae52684e6404dfb45697b6114c9d3d506bb63752672b9204a2ba94954e75335f5cbed7e19e5d73174435d7a58eaf5da41126eab1d76674cfbd757f1ca9148e86d371f210af3430fa61d5fbcd035102eaefef69938d14a2ce591e9f4b81bc451f0a78dce72298ae386a44e3b7d60235bba3202d78c7430755fa5fcc6770eacbe3543c0145a918bb896550c9b5789e27260f5b7cf3adab5fa0379d16a93f824c1ae09deb7ceb13db333fcb8dbfc6fac0055fc320962106a96121c7f9dfc2505cf17f188c13b7f4f730e0d233d5ae9218a0850c1451b460194a8b0f81d7216e2ab5d9a19f007d7b34b01f252ca3ec2b968c261c2a65c69a275ca672eca32c163f7bf6b138fe1f4e082d71a1219c086fc9be1089987c71c9b43a54e160a3d21785195d4714663d5fe45c4012cb98fd98f1643d7111a439c44316da13efd9399eedc4b2093acbc5b99920e4a0f74edc34530a5937b0f52ed1836d1b736af3d2fe4834cb7eb5b84217c4a697da92caefe0ba53c54dc7d4ee2092d98bb2f968648f850664f6ecf8dfee27b56135ee42d9bd711e2daac876605d714d2c19478bccf61ec0c3571df7c9cbb69b7f711113956148913279889b2d69f62e20077ec27067b79a2d814973cfb8bf73e339a9dab56401d426b7f06b564f16ed7b398cdccdbee650ca85e2c87656bdee21b44c9fd2c104d4b272d864d6dbd8f7adb58cbbb759f955ba44504a85cfbba7d8f0f3272bc85031f46b1d38eb2d6126c1986f26396996e2141b3f3c9366dc9ece4dd555fa06cf2446cdcafeab1123bd64641ae94c0a12bc890c904914d9d2f42416b3c6f5beb3b45d2f69a2d1bea4bcd95e126eec544267f503dd40e1c4b94b15f7229669b67a3509e95d794f6678787540534e208aa4fa33eab85e9471412821a1b94b8dbaa1c4e2641a0775c7b402ff8f604f857a2906b43c5e0f036f2255a0ac704555f4d0d10f4d72811fc03ee9bea447589816b9a7bef45c707ff26822c648af49166114144dc262a9cabd89af914d5a565d3019cf2649fe9f4e44beda31fb7df871ac9b4de237d9f726d165723bff96218a3e6d7719c7096e0501bd7e0dd19b54bda7722becb668f5456cdf12304a1d97a53dfb2fa69e1b6310f0f4c5be9ee5680297f878aa7cc3ba59b1629d56710e4799bd7d6a234b51039e4edfda343c95ca8bf1bfae5c4d061cc96d1933da4c35b83a8db30fc80021e24aa0842959c17e4f852f1bc872c0a72caadc6dcd9c2eb583f7fa7dc9fa2c7c004d4da0f58aa3086113d81c981979b8df1fc1c0dd091460ca562ee0859a324b2ae4a6af6a6531ce1f2fc0505ac1b99d467530ccb65543d2984822b1dfad0446e562d21f6259c010919f8e1d5a4843608a332a6e62c8141ec5c56e691268179e3b02f1d13a20f307d66cff09ff141f734bdf958468a9785a49852d5037478e08669831018b62263b1b4db69d11e092f9f7feaf79f95ca635e4fc7a950056d597cc5e153d3d236851fea71200a44c4697bdb4ea0c7a33104eecf392fb29a701e8f21460ce579b722413513450f68c6dffd29e77d9608915ad3d59a4c06ecf120d274b80d58e2fcfc869d4baa14faf159b2956049d52497d443c7f09b19d727ab839b22e76d098ec8eea8b6de9f421a760ec2780dea470c3cb49a5916d8f892d55c2e80dcd81f36c695af6330732ec7be6606b2c25ae39ff8fda519e36336b653cc782123bc28711e9bcc64696d1b0a91db3d8c34a1418c0ee92dd5f6cb38551762afc2c423d2d004040876494d080327fb15780b1e50a0ab5f03bf150724e33769d39a270219bf86e671e568f6e918fee86721fb570d4bf23a94d3e16d9e2fbe2fe579026b277a9297a09e1382948dbea2b913dd2fe2e7c537120465be777cdc90845b60cdc3454456db3333f16495fce3573815632da6e85a7f93d2b8652a1eea47d6eb5984fb54f45bf16f0132fe7cf007baef3f5dcb7ded5f66cf54a2f4c7a45018b92a142ba24f68a69e9d50cbc3bcf2b2cbe7c58f43b62918e5d1e9248cdb510adab4919356f6653b52d8d429ed5cc4e896db00d90743af2b74d3846abf0a9f7ea3c14e7f66d34d38fba093344b4e637a46325e8d78ac1f037533c7bc1f93110c447d9acf591aa62aeb7e82b6a3c22122545e6214127d44faefe93a9e8f0013f00cb161dc5d416cbbaa686890f55a839f16694497449759133cb9d719b2e8ed9503645602ca7117c0118e4034d546a5e41122d28be07205781e16d7612c11c8a8263f4c0998fd93f968fd53622c3c03389cf252c2ec51215459357400c2ce1abc1dc4745764c18e679d380112357f651cb4d6feaea98dad6829c083b10873ed5b774863b09c4144ff56b37e8b51ac5b2b99fa652e298ab7c95f92c033b2af3f205f4e733493c27f36975c87cd264b482ae550df8f95982699fd3746dfad6b2dfbb1865022fb9a62dd5b9abfb9cb0d0f34cea0c001172eba857fda7cb010e9ba2e78454504267528e18728f5dd7e90a5b67a18c4202ad1601ac78061b39d2b51115ebf792d7d093614e0f9e90c5f71b34d377f5a09ee723c5ed7e4ff0849308d95caf3dc44d9623c57f02dc931b9f1c1bdfac0fd871e38c8081cd1c874c6c8d60c5d150371aca07ca4debd098d1aa70180a06ab7d70b0c6cab5b2301339ec994eecb5b58893ac2c006bb6e1e3d26e848925475d68e11b4a5ff94165b34fdc5077c280b444d4862ae15336c6b6d8343654581511e6904ba4c5134d4b423eba9296c60100a39c262d7c6f169b8f2330a2ba08da724b05e2b9d9762cfabb0d2d3f74651ac6818883b86a23b3cf8b894c2663d76bc009382f4accf0c80597f2ae867a5296ef0e488b1e09b1d30f5da6f90169db862e15b4b6e58feeb7a5c4d7a65cefe8f8299eb6cd4c4cb7565a02a3197fdadacf32f12d01f77fdf8ac334931c3eb54f74d484c398fe6b33b780256b74fc456b98b05b98d3f8b0e238b159cf1bb391e5a8596a43667f6da035e76fd55103d97a92f2de7562ddd53875b9f1d35f6c81431eb617c611e8b4b76fe969f77af21564b190ed37ba8913772798e14f5a53ea35423f11c92bb04decc6816326825661179e9b934f75923e2baadfd20c49f065c8933d49b91db8b280df452ab8281d6098f14f848e7fc3226df9337f688e4ebd25c2e535c1d6a9f4df25a2d9ec24f7b6269237bfc654a7499840e87dc7bb4344fc0c9caf1e0140dab830c96ad798150c138665eb911badf99a11676bfd81cbae6d470898c2cc3bdb517c44d55e8e745e4b475c43e82060108fe8e0aa104b7bc4130bd2d0b6a30204e97d4d51b2fd12ca1243d0f3917505e11ed4f53e064a2510726455079d7e12e6cf1b6fa49dc6537a121ddeb36468b6255146899c652fb24966679e3bb10a02228ef31174798a5965d9d25ba47eb38290c38a7948add35bd6ed49bf9a1e4551ee1dce3bc32206f3de3f0085f9c2bc436158f0951ce7e8ffe2df557a1733bb56350dcee7cbe68c1869f81a224534d3618d8992bd825f1f0323a649431ab294b0749252195ac0816141e7c9c94aebbab60c54f59e754621ac8d8b601c4f80d53b36676539af3a5af23adcfa43df0903240c901614590af7ac93bde5132e6b358210288be522cbed73d6abce4943250ac27a92e2c5de68bcb13475258832ca2c9ba6f0ede6b53d8d31ff4ff0b2cbd61d9136529b3ba4598841a76ac1ed025117360aacfcc2cba03561882d8979662ab9d18ac7d2c523dc7283a3f86e48ee725d7d716071d29724cd44c0e33be441f2e5fd017a207bf5218b341ce8aa195f28aa23a8b592a08a996630a7eec687a5289980d92ff03a2177024c18ffc42087baaa1480b3446242722241802a9bc0abacf07086d0bfcd7fd575de02a47249029fc1374a61e7229caf12206dcd2b9be0fff32e4462848e2a57d438eb4b40be41f14dfc2c4aaef783913346c9317252948c6e0e290ef7be734cbf60d9e5cd5186905606b33a86535339db716d2d4ad324f4341808d6bb24ff80f79ad257895b964cc65e511f1834f1c08deca12d363ab53037d198d91a5e84351de72bbafa5e6a43881ba60d9c9390c9346e4b3e35168ba36ced973f09215743279593949f00ac0ac7a4cb8e8041bc9c58633d40ec0fb4234c22f1d1d9322f2068edf76a34de6e7efbea9c3e4bee85ad2484c7ff115ec99bd169acd9e5c0b9ae5e52749b9dda73fe00d732d25b7bba1d8daa9371f84e0969b5ff073fdd0b5b82c2d0832b00c2612c5471d0f8286bc9050adae09576434d560bf38aba4a4dfd6c5bbd78690f267dae994af6b8e67cb60b751fa04b35a2f1d9968b5fbbbda40c5c8713d7bfe3145453118a2ca831f7f827dad29ef2ed1661695ccec4864b0446e12816d02b4a73823a0464b9792106c3c3809bd9b1dc5308cfcf16b1a1dff0b6ac47fbdc73d5de85fa43a4ce892b980d77f22de710d957525d934b837825ca8fe66f2baa3cfe45fa1dd53b6c6f3713e6f682a52a38fffaa45925bed648a429eba91fcc632d0cc8b5d3e702264b7d191f7c2c7b6ceda5cdb748bfb3778e68a1b1d72064db20f4df205c1181a9ab2ae1ebfcd94710f409ea2ec48ae6a79d83ad725b01878b87f3469e0be538a5db9c176aee5135bc2bf2e8dfa4e195771c754361a52c5b47f29116220897f7d41ed703970302775652594f33e46825dfd331a2743214b038ce531e420ad4a0c16c390b0c84585666fa2736f2eb420152a5232915ce19df0762b20bc686302e2269d813ae80c994a24dba9868aedb9948d7c9bb17726c870c2bae6e27f02cf043d7be0d7071d47924eaa047ad768801ea9a1b7f8c29a60fbfc18b36d73400865b7d7eb04c842aea1b407506beb32403e400df8ab6646d098c3e92d2dfc4290a3a56efb5b82101b91b46ff8805fd5da5fbb341c64aac9a708ef3c476eba0eeea7648f8ab34d5523f05bfb4ec51f8703e2e9f36c5b4d2ebb623ce7ca39ce517a5244b1377f303e99f3a160988868208c182db0f276bbd711ba5fffd0ae1b8443260f31eb8e4ded1863416e9b7b79f515851a1f4de9165cd3a76cadac1d9b5394cbb22614a5d1c1a9a9830fede5772f39e15a2a843220a0533d94d7c0f3bf00703d2930b623fb90705c34ce2af40c6c0610820069915776f24642587115de4821ed44556ab086bbdc6788c51ccc4ebadfff9a9228605c9f4690bd753df61868f39abf5aa4783180a1ce22e6942317b671992a60dfd3ba7186dbaef1b4bdf81ff0ff857ecbac39ee93fc04c118d58edd8eefb3d86da05ae8664d4726d0689d2c855024d1374e27eda0b17804ceec28fead81514c3a7438638fe0120fd5bbf698bc22d244472493220146ba02cc9d422c91257a41f13697f44f873eab99772bb0059caebe396b3e34fcbbc7860f7ddf8088d1c6e763e13e17f1188b7bfbb13445186d16e77f6906f4c25626025f7f0c88f82db4f326cdaa3940b6e7d12cc56cdea9700d8331495dc52c575161235f3a930c3397e54408ced2ab02cc5b00a02d9880b431f52bf23fc574f8a96adc76e7c46a3f1e6eaf104f19adb7051db6603003394fabd176dcc7f7f3cde86bb3d5a3566ab422d7ec14cf41df4bd192f63ae0ba13355d57255c928c9af343ddc675c721db2653df0d2e6700ba99b59be0ee156e4010e8facb38303d5b7a8b41053745170df10f90d48b77fea458ec7ee1cdc243d5c59068b60bf41a5a1a4aeb16c111470a4a4870b7a416bb3848db4fc840f519169d3e26d336faeae92c9e5523149dd43fe25563260e9e25e0cbf87479fbf1085be2021dacd3f8a12faadf27f6432a297f6178de8b618d5a3354d4a8e3cdebc8fe6aa13e766e45f6c56d05794dd010bb501d1af6b800ed835f44bec1a46935d03d878c5b2d4c4fe7339e6e5c825d5a9bdc51fb3b10cb1e69d782b6517256f88234e4b48b8b98ca80b4e0a11dac990b01b095ef664211ae51f9a25d6b96a2bc374d12aff06b29a7968597982270e99d1bb5081f1e8c4b134e3b442f96b7032eaa52cbb87e9f7da6f147e13a54eac8c7abd7f8ccb6f9b2dd1a5bced81f7495127c297e701041851edcf9ad0cdc87387073a6615d56b1d50a9ecae7a72f241016ae2428c4f4c47b1a59394c678c0983cf13999ed8724133e89529a30400edf4fea234565071cb4a425dbbb6dc5c0b221402270bad9f6e2352ee79d8e13154114833f3f5426138b9196263432f903d89bc642647e85262193ee1b75e38b2d0bebbd2c025ba24e379d71cacf28de1cf3e0933268730b8c59cf9ef02ea72ad8d969250df7f8d7f233e90dd6830df0eb170b9402e831090c2c8a05e8804ba4952325b1a06ce793ed6b1020ebd867181bb165551e16045d8c58f1d888d0ee8984dbe16c0139acdcdba772818f50e1d8a8cf3ed708b47bc44859b9a065335d2e7825569018b9d383c00cfeaf3220ba2d5bc6166e1174ebb41ef2fb5407aa54c0760200bdb22e82f3e6503bfe7ce8f107ff4ee8b199ce2a4ca31c323f8c466714adb22484769f6e1877627089f4eee885e72b70275ec7edcdb264b33265873f8c7423f9f284c99e524f65dec1ed3a5e539b1b53c20ea42efb151c4c030b0545f0b3b6cbd240dade7e8c2c3f3c5874dab981d132c8887c827c63f0b8741ba9b1e248fc6b93f141b33410a3ed005a802b735df73330a581216cf6bc496c53eb63b8daa481eb5eb567e842853f2b56c2640f0538cdea68e0642b460339be5534109a68e08df961e4dc2771860632e772c9e5a4d6f96ef8dd1dd087e805f88ba01668c3d6a854214103050502e297860c3231350d34306a306ce9db94f5004aaa2957684b60ac9b179782e7b933a3b88605954edf51c1852b1c1da68e7a06aef94c374485b0979e458edd180b2beb00decf97a27db6691b973c4759cfec6c6cf23f52f6a1b16124c8b5f67304efd6a72edbee16ee760d6ad6c3169b7e3e699aec2f88a239b5f4fdfdc2fb99c9c11e344377412cf6cd27f3098ee482080a5fee3fa1746080c78aec7a0d842de9d2ff8cfcbc28c1aad415be8108601c0372226b8a2364367b89c900685224d3f045a00c3287bfcb261c3e97e62ffe977f27ae626fef12052c8d81a8faf0aba921d5d46578fd4bc1f9535243aa596badbae223f219a1dc0e1a36ce17d0c510889aaccbb46a4b678cf5b95ee0dfd6aa7dd36bad1a25f00fd8acb4fa56bbf9b3c9c02de039a7e7980cbd972a87a74a090926f63ae8f5e2fa5348baea882811be4d80728d724526e2320218d6f7c9f5375ed64ebddac4303ae2fd09049c5401998b7a744598b26c272fbd1f96f8ea69142ea06f3ee8c32fe87aa042b0fe64f069991a879ccd45b3bbd921b0457860d6ea116bd1eaa6a5ad41891aa88e4ce927f89c1757a82ab9ff53a0f7876e39efbd01c7a8eb9d7a4a61df5ed59874e12b9b6aa3a11174bc7dca274541d19004eb4ad1f3b1b4a0b92a5029e1183fdbb97d479cd9c7e78062eb6ed500d9edaefa04388f88bf742e1c7f2924914c4c3b1f95ec45a64bc7e4289dfeb62911bcb95006453c4ec56cdcefd0495077d999e64855a30c3d74a007868468f6c579f23b6763f756b4b005659823c29f0925dd52490269896e7aa8575d68d5ca5635010c4537c36c0d9970290d9f207b8dce77512e722410b7b97e6bc1631b78c62526b57fc64ccf015d0865844022c0ee1f77e51c16b6d3ae9d060f070cad2c84141af9e47801e8c4c294d3a71193397e1dc792794dc84ded4b91dd98906384acbd4634606b5f4eb98f8fbba5a9f12a92de817f10ff92ded17425a1ffa528e6eacaeb310b3d4262f98f108095d5d3bf77cfa03e6c23c8e6c9dd94615b73c9bde166757d7cc7c22a0c0a51700834f8f3aedf90b8d7182a18085d33e8c420e5944a4c515132e8bf085d629c1a9efe65a2ef29ffa8eca599d683a046d000cce616a094b94217358b4465f21493fb8a4c8c5166db9991eeb6a61c96110e4723286e331c7cc916630e7c3546569acab7f02444fa6f3e0317d00ebd5947e981d05491543660f2ca7604d23b4dcd4ffaa18f4c0ec07c9ed5cc5a50b3ebe321c3aef5c97548de440241573eb23dd8d18b9bb38b95b93d0854d29aefa79d48ea8f6dcb906ea299642257043960132230bc6d30d9ecf6f17abdce0b68e30c9aaa38c72046c8e14dfc6f5f613882a454e0b00e30513c0fb261420ce1b4fec51f468dae53df8d6613070f144e63fdc2373949834d461584672e7da29ab8de3fc60be064c6e661ddf77e9a3453befa9f9bd6dce5a0e5f1d7ca5e1b750610a5654e394b43fc31ac3368ff50c1393d540282c76b7a68eb078ec8f490c9072ec9d2438502dfe1d2d3303e334ad604c86bcda886b4494a146db00b7eac331806792917fc15ece6334897b4165b2e965e01f5d3e779e05c6ca8d9c4eeb8ce984c3814bd7fe783c650e3af843676b3d9a9a527224aaa8d9afc92aa837151af28b05ff5134252e3f3fc3a8d9f1c3e7da642801fab2da9f1b7aa940715755777299dfc7ce7bb7e0425a14c501d3e0afe9b608d775db3c652858a640ada48a7bfad97b9353e2515c5fbab5712e8adf1db1cb5f91883e5587c68c29199597cc94a7774613643dc3880b705ff1e8dc465186d9e3d1c1b9ef8eb505063a03c128f959b95f434db491b44ff7c9af0963e8654e101dda3ada4693c9d1833374545228419ac38d8100d7a8c48b317a82687816117037e74b375d23979642f4b49a64d0cc24a8e1c8a061813c7caea5e73f7c38e264cbf8c4c363e4642ce7783c64e31acbc70f36734a008ac6ef063a03c05521c53b33225581b9fa47666617dfa37252e8399ad296b5bd8572eaeae3d908e987b89efcf7e064752a9e688d189f903b7ba449b2b80064c5e69095e554ca9e7272d0f13e093c06ca5f025c62133597abfaed541c3c4302302de81cfd0e0f1438de4addfffbaf8cbdb984bcf255e647815e6a06b444330ce03706b2443516bc883aeb6318086118318f1ed1d1a663042c8e169dfb9d2dc1b0f3f904e4d0092c652931cb3751ee093b073ea65fc86aa4377c1ac0f2b67859579dca947c39ee2260d6066e9ea46a295986970fa11ec2e70eecef87115215c849e5cac6a2ce2f210004656b50fac995cde4ef6a17d6afe4fcfe5282717d80def363cbc0c06c119570a544e5cb840ba1eea5d29cf81f92eceb1d1a5236a2f34bffa89820e67cb8292ce4b4607688c864efbdfdf185817f2d62caf051a2e96a4f20202279a5bc2df8bcfd96a5493a4ba5503bf4badb4a46b18e9b492344b2bc16f8a24189f00a8244a2b84834ff9865064f012d4c3330273a61956345edb23b1b024108510d88669aebcdc53f3aed9acce81d10acb486bd1039e90e1e2000616aa0bd7c4f818e6d164c1afe7a4f3aa4e36fc8ec74622a1abbb08a7a36a83863fc613e99cd03274252cff2cd369cefe9954ba0800ca906083719bc17fd9ca1b1b433d6b1567d0139947ed649009007392679679cadd3d75551aab91ae5290e548509187caca0126c17c03f0b4460cd22b05094226cb53a573cf2bee776739c7586f75b03a46e112aea3f94e17be951b48c9e75e332b30f55127a7fc9ee24282780007cb6673ddf50f29ca1516b1679ad66013cb6d372c3d777673c6235d1cbde46982877b031b8c7c9d9aff921a52b64eae0d841d068d3cffd823e5355d8223ad21ff5d650048b4b881890b132c0c7e196efaf33f68e031243e1d6dcbe619ea71a52d3fd013c976386b6b0c59eb92aa21e74b2b856373ea2a9c41045c4ec77b9d4166266afae08b86edf7e7d9fb0835315d0d4e9ada95471a0b0d59d9d22a1e41eacc550b8371468d931f0b83c9e0d6fa2bc339489e16989eef4b042f9e2b7b93e427c60f11883de2b201df74937031068af885b5b41e56da96db59260ecaf74225eda7ed606182aa30c20522576e526591b6aff2ca2e365558ed1cff0fa589cc3f972382053feddd48a7df43f85291822e0fb8ea550a30b6302a9a3a1b1185e92edc56736ed865b511f0754231eaeed33c8471d71523d01d084596ab776de230004eb133f162922ae261c2c01f805a249d45a43493a652813d5bb23a098799558e6b08c10f61f3f2159cb856d878548c7bbdb5bb73602359d5dd73ee86c69e483d14e550460046d6487097e4e716ce6c1be0127b24cb98d3bdfaec6b2627924cfec0f1fbefe54af4b0c8068eb7cdc3088fc24abc70da698e3fc388557811ffca1541d4938b694892b0249cf6b1744651bf07379b6550e9028e505b9eaa1b9a55f2d687840d74a527e9629e0f3c3857a851d659293e335fd0b90ccb228df2d5f093888d918df4dbd7311939c593768eede5193b33741c1c15ed1c55b968bba4b97cdf0f0665664477ab70858010bf4488721a79d51f73800213a5eab727b1a629d44fc39f286edabe3ee8659cc978a985d1883d1e1b5877346a7e8b01baeb562b37717820b4576fa7c56b87ee5b35ea4378cab72f7bc6cd30c1da082d7e0655969eca73d8f73a438c2a0062a0ec5a3df78e5638cbb2d8c3f0f5a8917bcdef05b348c47f019b669d10f2f66260584f84b56bad4c2a23f9eef412a0fdff1de56970b48a9c5063c345ca023c61798038ab592dc3d52bbf8f943205016c00ce9e83c1993b49d8ca924ffbde038dbe8748761fe1695a5113015fbd9faf3939f75039189475deab113ed224ab62f9c71caca56cc306a28e9ef3b6aace1f459392b34db0485317612070bdeaab30775e1f856e9de949be4e1e34a52bd28d40429d58a8915fccd2b71ba4864c457f00c3b36ee83b2fedea0198ae9f3b8840e2a3c46b1771f7cb0c27222dd4b9a259327ef6da331cb87ef17728b9a6eb3d61d437d117578eea2b4922f3d3c162d08cc10ffd8d3ccfb0f338b89cea0fcc4154d0bead3d9d7fdc66dd401632aac8716eae910c7145c3daab59be8ded10737d23a3e42e4e73b43be61f0b06a75d013e38294ec6c204dfd53e5c9e3fbd57382750bd81604cf1bbfa3d5f382a1c9fa6229d3da5e3878067de611a44ea650177b3d05068829148fb92335ce62759d3a477f552db69122746c0d2dbc405ac25bff71e160bc766dbfba1f48c39997befd143d7ceefaf3ab1224dd91cf905bca3bad36c7bf956edda6a1c3a904e754f29d9c046ec5595b06185c6cbe01eef8af5ee058d2e9117eace85fccc8cd02017f2ec48a6a4091c4accb087343152a1320388ba3a72d932d12df94e4a1fce64ea709176ca1c0ef84c37a026198ff176eaceecd1485b9d43826083e5e8e6ca5e27b2c8f7e3513c1e48cf57ac53a9755762daaf2f20e276255677d15497e4858967178d583cdc7a4cbec1a189d9290c0cc3b21498b0d1e31be70c6931f38f1f049c48ede75fc245b533ce54fb6e40b9dd35dfb4a9b3b3e2ed89706d01e3b6fab5b4765801f9f0254666819866ed776192e808d34108c0ca4b7ab30cdcda02e7ae48bbacb6ab21e7b024bce21c3ba943de726fe1f32b6f2463e474116757c0d4122c779eefc00b0a76449d3bc1d87c918825c52fdfec4a941ae9dad6189505fa6d9217ce0a2ccf4e5ae1de44c18778c129868b40ca430a304c531593a6107c0182125b59614f90276184afc8896702266bdef7a2b3e00274591d0dab364607f4034a0a51ae4297a39662bd87be147aca538b752bfb3f873cfc60b021b25740f62ba3343ad0f561b8b1c9c0331f2a292f516b4b1fe29ae68a51a3e2ba3a9964c932c9108f0d5c9ad0872207157805c6ae7a441f9ac09fc0ec3df61e12a73147abb782e8bb07976bbd5784b8917dcb4a611d66ee57424d21e7e4d06c8753c83bbe5b7f1dde6a8b50d19dc6a530def01b01ac2bdcc67d8c54a2744fc55644e42efb0579e4ba44c9e4245a446c0e64e736a7cdb4a5f4cfa2e1263fa4fbdbf4a1c5b8f42c5fb14bce848c0dc7dce04fc5eb2c0566f9c61e398dd007cac3af52840c652235a22180166e150a779ee6f64b2fb7914d8a7d1af8557b7e45ca2102d50bc329bc43c9fdbad4dc48a0b9caa0e7f89acc54e2f227b59b9814e91f12744f0de09ed58f2c75989d2116089c42f661eb23d44eaed725dd7e3cb0a1a5718f35b40128c0a7bb83662ecfd4415024018988fce95e0a75337d7cbea5e6851ab390e6ebdea268ab6f694d5730054690f191fbe58f024331d52388c87d57a2047c5a1505ea052f1c52bc72224c09fb3c5aaf5b0b1eeac00c0e97a5bf7bd4be4f75e1af55df622ba284ab087fe3489914d5c8292f42f785e534b969fb38b093b8a4ec67144213e37b1031ce2e26d41eff833e0e6029194e8153110706ad6dab103240cbf07ef4c94881605b9d1f0c63d354cfb1cc2013bc5a66b484cd134cf721e89d8ce58a1ce0b2ede04cc6f7ca0d0113413cead62fcc05f9025884dd70e434e9f69ab4cda7ab07155d79db1a734cc2133661204f08bb1487ce80eb18c0ffa1398726d20ce505dfa75078fede3bf363087e36beb2458e1c8edff00f4000032937ad4d819672f9d9f4d89284483134120da6732490b0f5f15a83e8fac27aa3821844f30657bce3ced7b63873132d44d0d1b06b01c82104bb8f3bead1c1314528383c22f48851485fff1e3838779c8c77d0d8fd2eb7504445d5266ca456960b3cef41505db77c848b3275b79f6bf4053f21450b1f6743cbd12cd87fef1ff5ca0d6950c7237f7a3b28f36ee69f81632e7234eb415f37e4117f7a1892f439f0d9e708f3c0a31e733aa9b7fbe4bb1d069f3f83d25e0eb99a54803090a28f4ef8907800ae41ec76d6fbabb12ad4b7f139b34bfcdab0c6f546de34442683642a3ad7b4a3cce8b7b8ec6fe33dbb7fc1f15addc49a02c2b1bd77de17ff0cf14a92f93dcad6d57b38f61e2e33fa59eaaa55451c460cc7127af299955fd24fa5aef3e6e12c01c48601b4573867db0f54b04a35045c9a6c1b6d00955598cf2cf9b6feeae84a518e4fc2eb84f3071fe92d167899c7e4484557c3795b6d7044fd08874eba72645d872a6d4d192481fad55e322f569148d4b29094e018156a1f0a338a02a565a86711c06b2dc8589ac39c469546666c6789621a0d728a9fd84f65b028eebf55572a34aaef323ebb2e2bf4a3c974f3f05547a9fdaa32b5e6d4d2e1329b2ebe712432e7f481673357e3f4590cbbcc672a481b837fd787704df47fed247d13547c1b6c362ed53a8b10aafcd58bd3b87fdf89647185e570222dec82f4d8fb41c833f4a4b5850c6e42973f1bbacd5a56a1212fed5bf7baa1981235079aa37ef218828c5e76ea0551366d67a593a99a3e46425bb35db80dc66ae3ec661ab2f1004a43b540d25d39e741678ef256600a68ca256720f8a0a2e4cd34edac883d304d440d4b971ccfb9a78e0f8a8b24312d62ca6cca9d19746dea7a45a0b9a56fde5a826488193ab2bf5eafdbdf23afecb0a560a13138a6d9f28591f76af40c78ccd4162f168742c105d025eb97e70428cb35f2f1f535c586f63e6bea7cf1516482c7339b3e8a5d755c2aab182665814179618215088461cceb704ba84f1609d5e1932c8476b43bfd21ec04f0f214f7164bd0a36afb7372b002bacb7ad54701897b81ba5b81eeaaebcdc6a994f987382abfe2820e6bec68557e55c395570ce9c7484ce884fab7632dad820c959c96a745d5d44bdb0ed3ac5829821f33988e116d2dd7236410d95af9170c8b6d188a142ac7e0285b0a595d853586fdd67f3c8081f4591f3f75d35f06f1146c32c14f3fbb5bfed1169615dc28b284de4cd75df383edfb6b21997ff953e044d574f6c1bf32cee2155136da51e689920e7dbe27b47a31bc87ee7d31a53fcd29eaa436224be091b16c2e8efca9e4e98452ee5288e26713c8535ad6dca01b67ed0f70ff24476f24cf30de3ad746ec4f65ed3fdff5a3c7e4f9586064a43ba3dedfa47a54c48480c7435a4c59e04dcc5d1ca2f73c0eeb412a1088ced1d5f16c82544f262dd3c0d4c33976bb537c3094897a2b4b16f1c00b741d90e190eb584dae58d61ac7e1b591cfe029847df9fe7c391467feb604bc0657a90ef415fb4ab8d236a40e8ca5481366741e1f09af363265103458e98ca5155d968862a5a91e0faf9b04c95d7a2344ecbc17807aedf7ee3d87ce8e555acd4ca14ad07d96257fcbef712c74a88197eacd2af97062650c91c256af3b383645540ba62f02bce83ad4a8b6944f1b73e284cd41ae49a3d80f82eb94c1442385413308440407eca5aef80449ed6707957ea644099423472a2e246b19dc828c64a2eed764e257dd4829b0c5f61b24dbc008678a2e568c23c03afcbee81ade523f5e5f924261e37b7624659d9564254be7dc743b31e4479995bee305cc0cbacbcfe03fcae9f834bc39dce11c72820421ad82a8bcf83285d27255d57ceb775ca220ac48817ecbff2293315932d91d5a8427ece222479946d918313e30b34ffb92eb35ad1aa018c53266dc0e6c6742428a944bd3afa3c085ca06f5c6121be095e1a1c3d0e1e98f4d65a3450f90198729c40fedd014b6a51d9421d6fe1a2ca82854c1cbab8b614185c5233dc13b0b889bd7697a013428e0bbba2e483f0c6f72650a99e033f7fd7d62b0083972d8a19945f5c12f5a0f388023690da03473cff887957a1a3bb407c0ab3ae55f569bba5dbca904d1f98b36d462a0971b04f373b21300549d9624ca7ed83425eef377b0df63130d2928163b34d77669a8201c95a35a33446c6448fcad41e2ca78fc71228eac96a802abc5e3043723b2ad375e9ce41390bac25f518dd9381049cea5b3d9a00193b7ed479509ab342ab2c35e79f2fe17f6f4e2ebf5ffe330b03d0566c706df8e076f5779adf49ffa4009011398bfcd185d4a54f059f45254fd5344c030daf1287fde60908296b24d127e7120ccf90f8c49874a1db369f22db23a33b49f2e8d4f6af26e1e8414d2a1c362393537ca565a3ab389524196fb628492aa161121c5dd2adfec5747f6ea668af91a56afdf727bbd89dfccfa5051a99a2adfa86d8aba82f4914abc3c6678e4b084445b15523109046d193361b47da8d0f5810a25650902d41e6783d51d627316fa4c4040381d2348bca0e7669f23d7f86c261cb42cd0938c8281cb87721dd5af89ce1470f905143fefa79ead92e4acef4727feba6b413cf0df4fd08af973cddbc9e16573e4aacbc88b52358b9c4ba6b90a27bb87d275bf18b692c50479abb2b27375e36f1cbc64df966e611a2fa5ff62f04499feb459cb5e534fc71899a176c66ad45a32f3d47eb86c6bc7edbf38efd09a4e775635708f4145f47362557b7b189b2c8966247a42d7fc7d938d3e56a5f5ae0981e194de97d4e33903835e8929d362ea6c24aa1215ac84c1f0b4dac51a15489afda410a3f8e3e713f59346cb68d5fb791dd6345a41fda4b1df757671d37ab5cdcd4efd77f56b9d8a29bd43564ac79f878a587160e1659913c21d0027f08e69716ded09531100500977396c980e1d48096da4f69ed905576b0ea6cddac9587541bd6af9ede686f7009f4653732af20e5c6b2c5f293bbb46f973841fc6ca901a60cc64059ed31b74fdb24774f3cf10af660d79bc3b413f68b1b186c0a747760acad669227696a9fdcd6e0723f4677dfc6405eebaff1d869704f9f7e02eb5cb814c86d81630bd05accf8b61f002767d2dac8f67f7e8db176d0e856fd8e8812380dc4d86ba74d57a1d7285a31473fbd78d5c4c718774d18924af9bb12d24e4439be95e7f41c0301612336397b03cd21c2a72c2755888660a50f5991d97449e4c0f390c6a206e349d264b450fa01a3f8591f5ba58626585f781de31ed105adb130ac809c498e1ed31b9921cd4b3646175240e50ba88f48f76652710cfb194da8c11d5a4bac89a7e14f2d74174d25a18eac354c698e532dce52dcb48e3c021adb7dbdef8d43758fd7c963a09cebeead004b029020b4aa9ebd223cce76738925f3844819f56408c461955a0f497a082d82a5ed8fa65e0afabc370c7bc831b864fbcceffb1edda4da0016258228bb07b2d058daff665dd4b443066228ec270594e60f906464eb3ea03261acad145c31364702a1c460104c2021a92a1525b3092aa9a0e2d5e869c604bc6be1119673ead7c816061e046f9040e44cfb435ee873e6f490c1bc6dd1736b203f0dfd902dcd218886331cc4b0d416ba6b3d24ecafe8006d361f2d0fdf3fa9b74e2a61361166b6defbda59452269964080524051a0532d6f2e0defadaa6fd6b9be52ca987f67db29123c98548c5041e6053fe6ea492e324372757c3a385a384244d4ec89bd23bec5731b2a4df47b120d7d1abe58412dc942b30e2492c0645aec0903e4ca11f7ea03f74457da6f40dbd418ce904ed9944b3f5f298f9c48c621e4d98c7cc5834f2e18915312aad28703812a2c05c3fd15010114d209c1f10499a27a20d145186fead1c88367e4343072211500dd4ad7141585001dd7030bba6ba36d99bb8c0e20638adcc881574109dddabddd72e6aa6c68cda849412c412c70078c09f6ce1a0a0d5ab1882f7e303c9fe66bf655d83dae364817b70962b1e404dae4ca0d62e68b0877a090fd1c6738c315e793f47010a0840005a5a4ea798180420203f0055adb53a7c80595467dcfa36cb6edfee6b75dc2bdb90bbe3c08103c74479e6a2400cc653bfe2a05e3b0aec90903f1c9dce1029a5095aad96a7382939f796b736cebb47c825b064ef3a4a94f122ca48691fc4b0c598b5a3fc004d9fa62e70249849cf3b11691a26bd2062aa638d46f498dc156023724653efa4138c367e2fc626d3bfe7812ded3577d74ede72d7b35ce0488270af51cb5b33bf11949892170c4c46f621cb1fc207247c08228e88ad0413dbb6514a722451c655c084fb80e405dec4c984329b4c412203fc792bba1511cae6dba6bdbbbb4f27eeeeeebe693d9dcc70164d27dddd0d4e348afa49f4da8ddcdd24d49222ba153942c9344deb568b841e17104f8000a2a9ab628b08b72d6ad2b2ddfb34e188b3bfe725aacac09f2957aad3deedd6566aedcdb239e7edc1284f61196d243e82e511dc73eb1c8f4a2196906354a18a9803ef7478303990c09f71e4ff88400c94e410c4134c7e94183992833494f0e24995263b50c99e71125880234a260cec5e5dc7a532846f7ac41dd2c64794999b8f1d2323520b9702dcc6b3d3c46807c90ab08d1712d2dd9700f2215e89091912c21293690e63110205fe1aa83b49a4b304f1e6044914f183ccdbb65a6ddbcf6afbd9b69f9f86c18036a00de8c379e62d2e43caeeee46f9bd18ffa350118542997050ab5e80638e912c1b33c596b0980c790440fe9ef4c2d7b94156107681a186ce39ace80a5263fed7b556e78ab61cfa46603cbecefcf8feb19f7644e27707e344dc88caf4d384c2f981aa913d189a52ced948f026adb51dd4f50034cfffcd0046b83eada48c43dde5380cc201c76ced47d59c6f1fc87cdb153942a73efd22b448fd62ab07cc03eccf076281d48e87760dc4442be2786afef55ec26a263d643299febd9a660919c2138447ca8d89989e73d248c1ddddee5e4d265694dea49400934963eeee76f2ed9df3de396fb70e14b80dddd7e5361e4f71dd95dde1e81b2f297bff18731944a3537a43788244303e13787276707ebca4946a2740f9bd189b4ca81e9e21a6ccf37abd5e37501cfa66fefdc94866571105085bd048819bf20c39c55cffd33dd13c5faf5773ff4284e773ffdaa5cfcd93d63be42b000adcdd4719f971d3684f467b3ed31673cddfc300e3c27cfaf4f10b05690f5d1d49af07edbeaf617906bf7285e3714096e73492de0c7e85ae6030daf3a89af724edc181f6f8385dd19e68d3b028235b0871074d5781f5941c635186fad015ed915e37a94d695b3ba725cd690308b3a4da09235762b266272408eb28f4977c64fa7b3b98ec118024d53ff29ebad9ac39e757c34ffdaf7f6cacb5d25bff4f304296b7ac59fff3ef9437bbf766d77edb0692298da6f68f4cb5aaee18416441fa38f12417638c479186eeb4ae5918efe0fc781720f0d72cd6cb0e1feed974cfd1d931daa942bf493ee6cf094cb0acb4524b6b6d29e5d0c5d7d67bafcd174db06612168bc562b1e8ac73ce592b8bd537720a131758dca06b1a8607dcdd05969f89cebac635a170c4a273488d0e610f0e8e0c01f258cc81dcdd6f666d76adb53a50332c16c9080441100441d0bbef81e0052f78c10bb2686c80e7ab8868dd97fc79bd0292de8fac59566230980d22b640b067058be56bc59386526d05c114785ef398d3da9f8fc7509fb4326aa88146926622098bc2095a6bad066ed94f89871705d640500335d0ab610d3d951d6547989aeedbaf51dc02790d85748ced6c0f01f2092cc0d9942e7a8cfc138ac09bacaf6a242798599e0e0dd49068e0cb6bf737d5580d3d66071c55d914e9d5b0c50bfc6553b413800059263cc13a413b41e93388094e10c7a816f1e0a142c883070f1e13f45454110905b15a393584825b68cab4a0253d6e53412b9b2269282b77b7630a6cc45de14b4f760debab86d5c85b32489e90829e600bae12bc0450a50115597eb6caf2e512602d3ae109fc45589ea0bbab77c89f44c04057dd22d62ca2277f829eaa5dc41859c32322c2c022ca48dbd3025d1304dd95134a2973c210c70f6a0d431f42a13cefdd9ba1a76ed8f57ef8622daaf8c04065038b104d54a4e7ba3b3bda8551248d51b4711cffda856117b686c814e46fb5d6186dfa7ef62731463e14e9dec67296d52a973f2f5b951bfd80c3fbf54e8eeb605ee07ebe0fae8bd2dbaaf6533b0991de8b2569a667aceba3434c512084f115c697f4f0e5a115973b69e22cc04ff3e7959ef43aa52e7b52a793bdcc600822835b9e1ffcf2949120b210d2e20455d6284212558f229e080334638ca198cac808a66891640c28d0e002062a10b07000228908a40c2154c9c769b564ebda30b421840a3d2cb9f75e7b6bbdb6d6aa03f57abdf00d27b4f0e7e55829adb56937ed628cd7ced0b649a9651b951fbba78746a3c94202a0c0dbc74dd977f453f7ccd0007f35d9d65803ab793112021b42c44a6bd976dfe4a99a1a9295994caba9a18a96907b8fd1e6be719244922412d7e544199d9d979e1eae5982a0b2d2ddd78639358c1a0e306dbcbd04b2e0a04103c510f8eba0c630581bc1726c7c64f9926c29724411ee59bec8f6252637fce581b8fc0d977f71e1be057359b44277c03173bf4589126dbc060f7ca06fb46c461b1de28d8cd23ba400711f551dcc035c7e7b202fcf7545f0bffcd6bd7c919677f9a8721f3653919919126625cb2951fa0608597e1a525a1eff27997c116d74b867799ded4b6f493144958dc72718db72e21e3f90ed6f6c8fb72fc2f2409e7ae960ecbfb8e07779202dffd215297dcbbb94bea593402c8fbba8f2ee01dcb33c9023745abef4d1816c5f2a7d0c5155ea70a933b97c4b773d86e53136ba52cbb7d8f81617cc42727996222edd8fff6a6c743b2eccd2790f9397644275626091419e62e974581e3fee88909e65633945951c0a723924bd5c2a010926e52f5a99400e57aea8881851b1b090bef411268652d7afee7accfce831f3b3c09f048a568e608268e015adc060309869fb0ef2d4f6460108404b0b025e4724288180324dd3509924e18718739cbe550e49d34e6a21e6ea0cd8410f0668811be8477a9f915cb3ed151778befd1caf63c6947dd124ba7b4c85a08a264cc490820a21aaa8fa4d31654404433c31452c0553b470a2ffc66e77fdc8824aa452777bd4b4707e5060d6484f074ad3b6edd6dcbab805333014398663801773922693124331644b4afe389b34b07f7b17060f1e0d88bf18f2408ddc230dfce1d8fc645fe2b4f62db4f6bebd9feed3d35703f524cd7df96d1ffe33d25b3bdaf704a363933ca1838a88ed826c2450599d3b45753b23aa8d72b6470e4f10f88b31b7827a3274101e9c56abd54466937acceb31d6b265cb96ed0d91da1a30d890c33609934efad4808d749f0b27b54a949136db9c7036e6247139d2ad60ae01710a5743d25497a7b08ba7b89fe13761fd7ab9409a98e0a1bbe448962deff21cc96131db78fcddc1bc49729809aa77404a4fea5abef440589ef4a4ae88cbb3bc9ce2b57e4b55c7756e3c8c93be888de71e08e947f811ba22f849374e18dff9f2e2f21929c7a7a5f31849a7a57b9de831f82d29c7c7c6e3af248701491c23f5c8f199ab1e1e30fe96f795a76e48313a55041753105afac05fe8017f1ee26f213df772171befd2c9b77192411eeb60fc08d88f03f9ca09aecf52fa92f7967482a14f3b8f2a9c1260d209e531351145dfaf066bd8b639ac0acc93c01cec56d9fbd57ae5e702e34c0586c2d0d7185328a594524a279d5dffc41831ad95b6b4b4bc5e15a64901f80084154f7c603fb0dae9842309d5f5d303209ba09d5ad5271f31e7a054b6fb2cbd87a303cc13d610318203155684aaec8958e0894a7e0370742e8e245437ebe21a4c9a1052655d54c9ceb456ea51f5f54afb38a972446543d760882dc250dd2ccbee7f02c8b16f240db27c55a74c37a82cc814a4f723c71df21940820cf0b7c20a7d6332b97bcb3a716d96654ef0178d6a2683d4a1b9b687083d40a3bddbbb4dda165bccd19d6443a1b456eb6b57001f9c122263fae50f757a0a223de9f5b32034254a94afc1af410a822ead0d288dc562b158cc63b176a7b1582c36a934652d85d10b562a2259276dc87a50652520a122a2754051a6603f93401f04060a0a0aa2bed303c46bae0e320dd208217ea417eb3c16656411d9fb0df89340abd4f7fc649d5c22a71a3d78f6784c7a289c81fd85c0932e99424157f0e7318f553a3ffa8cc74cb158c805a18772e49039729472b4c1aca1bf02f12988c7e4c861f31715a8240001efd4dc5674bd66e6b13bbcb22f7e70f4baaffb22a24764aa5d442d2a4444946a9853a08f8ac08c9a49148b88828858442051ec75f43aea9bad267ff53582c9c67fdf82ebcbe735857a87c3602f5d6c853bd04a8964462c0b724529723971b58bfacb53f7f5baf1ce4eb2eaeb871b376edce8eaab1ad52845af2d8a5eafd7ebf57ad5577d652f17598a22bc0285f23cfc23f4dc501a0c325c4991cfe93e8b3cfc21f3178fc25974afbb87e10cb52fe28cf4e48f14c6c0dfcc4cfb9052d6d09f9ef36adbb66d9d7692a0c7c8df066005df283f76966559a366a8193c8c5a5174f79095ad567c516a2d0b24f8db97cd89a98d8adc3f24a0756f626a080a311569e8f7a362e9dbb27c70b76eeb5a0fdba8e5b22ce42f366971bf753039dcf630407e04294ae4400691233e20254cc152e1a0824f4b6583ef10aab6dfc04b2e62eb8afcb7ef10aa48cffd87a1903ace89394468132202d6444c86ba85ba857cce3993835f31be876a14eaff9a7e4a37d3368e643261fc52155f7a7cbc07c68508cbee2712aec0440e2084991d60faeeee35359da5f1f3ff7f7384e338aec7f49fa0ff38c79d72c05e698cb1da58a3b5d1de5a63be2577fbb4df6990beb93d363d441b2110f8faae9f5b6cf9e39a544b3992ecfbc959c8fe33c05cb06444193386f020c1535a6232994c586093c964aad7da7bad459950f405240067a450412889a3a3201c77c41d7133c88c18f88b4799cb5fb3522f8fbc238e23b5d06faf069c98b901fe1ec72b7d149e56f7ead62d6a26e728c876062b8991d1ce8e911196f36659b66353033cff33cd6ba3670132f171a43c6580ce5f21cf9f9d9452ce12be842cbf8405d052964f032e65f92513e40926fe67c30df904133b178ce4cf88fcade3fbc793cf53e71756c8f26988ad1c3b181756c8f257c8b29b57f2e6b2e3745ab24f6c94beff562f977153d2e4a8e309eecf5c33c1870926682de03c43c35af83c43bff2fdbe697983fc489596e8a40ea0afbd4f8d34ff9e169023e9051f0bc8b79b6101f9b6267d963a20f307eadbf9f4bd762fd06e76528c9a04e5fa2cdb7725d75f5fc9f74aceba6f18ea374baeddf4c1926737034bee19784a3c259e124f491bd1dd52c62851339d7570f8ce798a4f6ba24c25cd39e7fcbc2cb13c5d4e9eeedd2e17b304c79e3d784a3c2505f82103db7cfa40fa635724163942a7482cc3a34b122cbf5920506ed9ef9dec01eec762f8152f65ccb9f463726e6be59cd39970b95c3f2e4e7237eb148080bf761d491fa9c60a659871c3a377b4b554300ba947c3721fb5cbc5ea0e5d3d74a5968a930e5dd2b340bc40a4a1a9ee913f68fcbc68fdc94202fdc89f564b7b1e28af24c6b5d7ed8f682373f63927b5c2e5ba55e0a0955cb974499794b25d3228282868896b763e9e922b39420e343e7dc2b4e0394619ef605ca06166e7b2771a30659f3d67cfd938a4d0102008deac04b829b5f6befc0a586047c2ca9047c03b0414d241498f10475c45462118de4ac390d69d90ca2bdc098d428ddb368edb362e5efb2a9d418229b0b5d6dad83aa8845784e1d0cf9c73ce299d7414980565162037186498500002b7db2e729793262cd6640016b8bb270c5c6cbc441997eee50566e305c66d9aa575becc79cadf0b6e27bd5243a6300e346e58e81d927bb92207d9b5434141b4deb48f8b8d5597bf17d20b5ec5196134118325aca45114ab08a1080a1654906028062587490fffd72da5524b4b77975a30cba99144cff35848a3c98f36c32543ce8cebc84b29182afad1292afae6fe07573be7733a59ee34220d119c846db46ad87f7dc6abf4f8949da210f0d7797eb75aaeedaa116d62dff4111dfa280caefbfa072cbac8628b2dc3f102c7528e26f0d760172df899f98b452d8f1f484bf738327b232a99754654d7638070e76ff9224c5de089b3d73a1817ee8c949e7c6fd6c1a066505c8cf18e3bfc85f5750c74a28dd4a9b6ef506bc885780a3f0eaea9699d6a260e4274779fb1d7fa7d9162abdf39632b4e4a35ead756aaf558964d8242799e8947e36296e0ed775a70765ed6da2c3b5ae5db4462884318452a1b4c54ca50919eb544d234d831f23f4f16784dacc90289c27649afbef65b3d753859d2931f435f1c9cbf9f41b126dab4a965ef43fbab9dea77bb88629226557faa7003debaaf8b3c8a173155ab98ac269aac269aac269a2ca2c9ea265be0afc1997dff24c1d02de9dd26129a4433086727cb31d46b915421d45282049c45c4d982a924c6c8c99a4455cc255a930548661865b2b844130911914f24b56a9aa6b3c362b16e8c6102161887fe11d2d666d91ad8e6ef45ce007be9b2e7350e5e0a3dc0f265e07e0821e225014a61a525d7f871ca5e3b655d9d2e68d9fb9dcafb38d26be8f6da6b0f2604b605fd8025dab6f75a6bb3cc5a6bb34c6b7bedb5d6da5b6fbdd65a7bebadd7da39e73475a5d7ee40ed68b9b66e18c6418da966b55aad1a3bfe97aa551638b07286ca86bb8aa23a62450024aaaf590de49e6528ecf9670c5469058932f2513ee0f9a68c3d155514c6671763fe89d28b471ac8bac9aa819ac0ab6b7d5c3e8eef4c0e298d23f863a5b5d69ac5de41a30ccaa36a4889f2a19ae8a8644eb96cead0880000000043150000180c080542a160402c1c146bebf80114800b57743c7c663e17c9e39128ca811404310c649c318000428031c020648caa06004dd2a06a464ac8f09b600647f1e9e9cf64055dc0d0005d015b46ae3c67371f197713bfdfb05b2ae8649dbdee9ccd09355bd45384ce990d40c14f2679beddccf3ed39fa1bb737c67281451317d3abbea901d061bf32ffadfafe3347f1d7bf6b1d1a1bdf05678c7c1e17ee736d754aa5a0c15a3a0497f9b0a2b2d72ddda82fd93929405d8d25353d1180db27c74105ef11e97e799336f38e2badf413d28d66855ee92cf8a00d2e2be65863c0c3b95e1b9908e9304def6febdf7d0268ff86ceddca7bc0cb0112ceada910b5f2797d35a2c51f129a87d83b9fa422f51e53a732f314a7ffc2db517feb7459b8da100b46486a4a0f3df000ed9efa7f6c2e8ed278f8e5df97d249eb5df9b0ef8b80af8b500d07efda5bcde292b770f5ae6cec9733567c274371df7bd82654bdbb7c739bf334dc09bf1f510cafaa66d7593c681ceed6e9b78d2829e340def324bdd3022593f0c038759d8532726532a153afd8b1ace34db2492e261623740911a6bf8ef00820db976356254a9becf54ddee116ba29c4ea3ecae9113a78fb249279b9d5c11905bc82b4f10160ed164ea04e48e183ea6e78c9a83f040bd8526ba894b92e2da274b92becf0088e7cff7802a8cc4db884181da2e48c863957ae3a52eeceec8ac33376733c68ba646adf64753c97bfc49690f22904876a6bcad3e01dd26c5b709b538df215eb30902e827d47e9cbdddf109bab7b25ff7bbd5cb5af2652bd9359fee57abd9a62bb65accf31be6a7ab3c06c6478cd078e81e3df635f7c72cfc0bb264defbfb403c41594d4205752b84f5297155f0b400e79403b017d8ffb0d5c228c2a7edee8e180508c9d875148f449b61f08815171554b1668cf80596f6b01398a4ee8d2f3d7993981ee27266494aed7801e07bfc4110a2a5cebf896c5185b82a0016919e01e650205e6980edbb1e04e0b6357125ee147831d4f2948025838fe399430ee86dfa4d345d0eac3c51eeb291d8f7baf47515f80b7324e16e9667c420804a3734b1c7859e505858addc6748cf239124b9771d464f56835d630239cfd6688cb9321266d31206041b986a3eab11dca8cdd8963f5d23a60738cfd50b0573dc8a9d0358f35880f35b50a87cc1c27f1e7f9a9fd84c406555e86d029569d5935c865baa0e1fb9690f431248c7449dc2bd5c7bf6ec921b45e7f4c9b2caf1b9917a53318db3469535018233cc54d51a66c07c9c7f1e75159c5e39ebea7bfe67539c8c6ffb6435f0c73f5eafc7ba5e3703fdaa8383670cf9f2daced5da8b39d2915e4f7a233b8e7217f2523063bb659d9348c408372b815e7b3ffe48b405166fb9fd6f636aec7feab6249a73527e2e230b3614b2c693ae22623cc8a4f4a109e21d9712e4488b3c36db2f7e70bb1fb1f90c2c5f87645097029352ec94867fb3244c7805a2c36ea410816e299ddf6922594964ca6810ee2aff7176279c50360422f91b0a5563c7933c7d9e6a12e8398c6a7efda93962ad7d305053aa413c354769b668762fc532f89e95413d65ab9aa7f5d5b14a75786677e32894bf169f98645f531df36c534a9c259990ad0cfaa2f29041414d2fc90f26e44455c4201ab8c3f7057120b1e216add59e1f33306448298fbeb39d1fbde3876d5b2a60fa447c1b0a65da9f2aa38ad5066a015759013236c2f162a7a6835851d8ad0f47c670327056ec36ec8e1ff095fb9ab11c0265dff2765ca5a6a2f858a37a660d7f55c5fb42a3a0ef8463ea5e6ecf66b68e2d1e3e60615180b89805f7589cb15d04026f8d1b7e727ae579c690022ba6e0525017e3ebf07c4afcef3ee0c9576b91e6ed0a93a0e3f8e423971c29d66fbae4a09bdd28fe6d1b6494381dbc414056c32add70a552694337a7b48536311f24dc35bf6226f2f03a148e5f325e218f166847a913f7a2f9626bae819a6b3077c914e26f6eeba0b4c5d1e3ae25cb91ec1a431cfb1683304d1c5049aaac9ad047f359d2f52268a3e5c41e3e206790bbbf70ccc01af1dd4f58452ad6c2ee73191090d0d6de3c59da18a11e84bcbcd27c6249a07360b18acffc0b58cb4f14bc343a82da3426b3fc9ef0aee02067aa2e07be3d47767c588882fae8b1047c2520258bb3df6c48a51c6de904a3e335afbec94b96e7b174848d01236a07505111b1c0fb5dc9e161e9c9220ede0852bd773968905abf80265f368f3b9ebe813cd3bb5a721308035993e3ee246ca5c7d76197feb5f771bc0e74dcac982ca1dfcd8e5c05cf9325a2308edca7a37d7150a6b359b0f84935b05f9a43646c9130db850e8b1ba19f23283b8f6ea3e408560a3a252c935f1ccc578f692b468bef7df18d3575432603b07a6ff962f03e1a8339b8c8cbb0e24eb6761bb2d23302bef047e1774cb33aac4ea3d29b69ac59c739c75768302ff62e69a4447b4699adf6934b873f80ec9d035e8f723125ab7b47c793d97ef4850cfa82f6cee595a2b39e58b61660c429ac75babeb776ad129469b06e824e119a686c08626c4c4f1cc1f4a9410127bd55f9913c26e2ca2a596e82c39f71c102dbc55b96bfdea1c2026bbda5af917afe8d2aceab72b1e4a209ba130b5ec65090745e3d5e66dcb9038ebec4162607b859f6d4f287259beab3f1c770b928e0fe9bf75e871502083db3555af6377ba243786fb5bb47facec39bccc74044ff29e6aba91e31572ca5d72ea4fcd148712eb7a74b793464e40a25971ee6029f569528646d83ff0e7ea1806f0000c8f3483ce2890c772d68885d8f10be6644eb2c0f3e2333d444438789f51cb444ca441f15d5872aa2122bffd65bda15ed204adc0ff8141dbb65648a9f59269fa11b7893cbb4fd40f400473c033550d138c13790781a5b17867941dd7258dfc31b550f514a742cc36235c6386715426f6f13dd82e68232bc6dbe8815683326baa3dc18d01deb0987b7d4920b366f53ad6661a6eb001632bd525455678c5046d03eecd3a85197cda8a9fbb1888718e191bc130a7c110a64b48920bba234842486ec5a592ed9e7788c25f877c9a95f336148a180aa0108ff36c2faaadf00b83f83b9625c096a9c12f6c098b0653991f5edb76fdbf2f5c4dddf9db6f170e7dcd3beb674c195f9ff7f993cc24d286b4eafabe90b5c80b2c66ca371640d969f544de58bcc0a499c5a6e60a908131fe08f3485408db87b90281787190a5faaaa234d5c5d90453515f5d5787a21ea00f5aada7a4b828aaa9a08f335f110ff80046489e26aa7564365d6853119dc7cac47386fa73d2a82c2e92806ae20697fd527d85229c17d458154f0f2d5a4ec292b5a546bc8dce030832069df8fd0ba412691fd9de1f5bbd4a896952409ee8048250747a1f0f13fbb3bb534d4c6c31c6a4f11a484535f75aa999c52983f8ca3cb9210c2edf27323793d4964ea3c69e0790e5aeb36360111f37f7c59df5ef35eb0dc350232f9b56486c8f5698b989eefa13897f35f8af273e5e3ba76e97017cad68c8588eb615c3de6cb878626a9d623f5ddfb3cab2029fc49d0cab7cf1f92aff1ea4951f92295ea31dec8b159d15bdf23b0a2dff98aaa749a319c9fe8c75e28152ac5bbbcc008aaae2e9a49a7f88e3748de35981402bf17b2e9566ecdfe90daef8d859a1557c0038205e1ddb509ad644fdce43a8c16bdb6cf07ad115a2ff7df061b32f44ec18ae171150bc797f97b637464bcc1c0f5cd6a0ad89f17eaff800ce6d62f6db30613593412765074804e20ba0f3693b755b0ee2a34b4f0ec3f15188530bd6caed46be020340003b8b09f254ad3cf149c31171ef685971db3dd13219dcb1142e3b2885285194cb1fa8e8f1ea1c28fcd90388029afbf7daff210c4d977b1a93aa31b05ddb3663c1c57eabb247d734c6e8c36e542ab26f53bbb07e180416f7081809509bf119313c49bc8d1ec5b2127f709e524d32d9802b862832bac21e69705b74c62e1675ca2493064e9807f7d11bc8d354ebe8e872a69ef59839b88a78bbf9713de070c73394c2be95577ae90643565d5d4cb8cd7d62b460739b56d079fbf74fb88b1e5ba5d816095a7f8c9c835f7a9996ece9f007af1d8e987c3cffe987dc4bb6ce996f10178a53fb411bb3b84110ed9f218c9a710ebc500518953d2ee39f4ad5e55a8a8b3b03ab65ec708894939a71e938b5dede6cbc285bd8f3ed545f55a32d5a0c777beac0adc2005360e4a64539682fea539b434becbf22523d5f93e96280952f0061af012401d306375f2487f9e5d5ff0d08d95b1510ed7a54fb857f45cf1b7088e903e6da0800cf22c91aebad16ea57a72e0d5801fd8ea9ab97eee9dbc29589d719042981497179835fdbedda8d48f3555736eda9e9835ca459e76045231a40a12987f178f2604742739a9612eef280cd88001437fcf38386240a3653e6aafa36690195e64a8b1769d19030d5490ec2064d0d568221398b2318ae8e0ba7e08676ca7767840c4b997ea038a5c3db2c8226a0fa74f1c143bbd4dc7c985c9eb105acb599d53d8e5714fd7d8663e4f7d293dd77489526a0c51c92aa2d48d5c95994f06704a7494865bdd30137219d6f3e142128c614bb5250a1a6e978c9a17f0a791cc2146c98e2faae696a3368da673ace54b5c14c3a64b71b8b37b25b1f095f5f873fbd8b4f5baafead88a6ef90e121bd0f385ab5c3afd1f1c17989951ba516865334ae31d48fa0bc0fd46522386f32b095a331ce9bf0d86195cf01e198e0cf3048a8e5ad105d982aa35dd5653c17e3d765181fb9e2cb3a48023a7ff4494d16272190ab8d70f9f3a817f5bb5fa3de8402ae6fbfaeb169096a176abaa247fadcce0b0b9156525f1ed9f3be7f6965ec41eecbd725fef8517b578c0f3dd85d51fe9c630013a1403eaada46add7cb00231a3a5c14bab5ef56fa0b1615d0a40af6f8b2571f7d6d3992d98dfbe23a9fa1688e65b0ee567360376ec7af76e3638f78050f5e5c339b807677fff8b11e5781040f929c28a8bd7a0c7868eb91810686503f12b20d4eae34ddc146ec590d9587858d61a0d918355cbab462ba1b6542bd3733e488113e11b1ff7b78d9b2c6ec2e79c70c86c945e6b147cca3f02ca27e107f6fe07840c5dfa0d9c077a8b0eb2df7b464efd00fddfa9e8e6f3927c7323beb1b59693297b13e96744679ac3a5f643ebd0917e03f2760f800f410b1f62b3bd0fa93342694d9cd2024d9c58bf88b44b695270246b550ff1633b88714d116e299f72488e0c2e820cd760b16e813849a2dee3c91ed8e63000968880f92190ad3cd21629d69d6b7281ac531cd0773d6f8fe305a863d686460c614cdfa869a6dbaae3fb213d0890c734c12918f1f191e35d18cc47f7181233695f77243ea5f58d849f85351d8601c02c151470fe4c24d36ae0879c261b1cd69f24160076a3fd27ae22c85c4666adf4eb92064ac21438a322c9187babe0b104194459991b32f31399726c70ad4ff843347725d4820e9e4c3e44233c125758d197b42f6ad570b031ed1edd5ee5f0066a858331d860d11d6adaf418fbca53cd006f764db1efa64df86d9d7df518e87dfb9aee4ef26df801b51de6f5496bd3e38f97e33a8526118e43412921d8057dd88e6bc605bfa8fe57f9cc7867c87cfb769379af05b3a6d647a90b79f226b295fdcc81748b58fcc3365afe84653c3e3ffc2e9c2bb83e9cd087ad2d176e902a182a7c272affe8427ba5a3f65ceee1fffffd99c5816f08aa09daeec8e04fe38bcec1b767f9e76705b4f2be162eac1d9eadb3bf79f4747d894a4835a60200f7e0c2089f82e4ad143e1b1b35bf8869489155922e0105ef09874500457c8cf9aac27362726f50303a973d6ca5ce130e5a736f687c0c8eff5762805d74d684f1fed297676c40fe4eea725d6557febfad6132dcd2f5131a30ae836778013a945b204111a591403ef441104b21658efef2783b63a97f9ee956a83a2b4e05d121b6cb2a51df89c9c30175b5c381a80701b3cd4c132eff21896186b3febc11408e175097e868d7ce77de2e6de1d65e9015da6147a720a6f81ffa1fbf46940005439e151a07c69d91524a8ff811d80da68781d519e84a938aa5dd00aad1e705f0767b7a519cdbbca23f5f1a998b5f52dd10b09e682d37e63c9525b90d694902535d1183f36b769e076488e35f71d1707c2976b136a73857546ebbd134e498028d52a4c550ad0a716c42afb2056181dba661b8970146e7e9279f5011e3f902817209825f4565ebd96efebd7e9f7881172623bf3c8b3e2fb67055c59fd90083f5fd83e9af4af3b9e87e6466d0e791cd85de941bfb0d3772b29fbe1fc53da8854bb519eb723523d46f9502252afc0b7808f949e0865daa16414d9bfd16ef7a950dad30a900c6a11d0a3a6de023d8f9516ee95450e64f697675dd63e77573b87c34d3e3ee32555414ee2fb1bf2876d72492bc33b50fdd353efe9259faddddac930f0f31c8c40f485eaf26b796b5775cb699cd82937cc38853bb28873e7b6ee9212b056aafa409d3d1b2d20049eee5eb2e5912f155e0de8bbecd2cacb3a5c8d54546edaced48803735b43318771a2e0fee4a6e5417d58e5abd7009080f3a3a71cf4114ff81da1dd43382f105ed70c94140912e6148c10b62a7bdff0eb7d75a4ca2b1827ee23178ee0532b5b253d72e5547c1b91bcfca995d43f84a4b6411ebebcbfe3ad64ab52da6bd1d469521eddfb2453f599aad88e446fe26ca575c705aa5560a5a68cadee9aaeadefe1e27b49a9b4c91d54aeeebd899b9d36a6b064ebc70f3a39dc5b8d432c883013a7d242d0970bf026509f98e6e4b61e154b35ab4d9bd4afbc780801da8aa61bcb56e4272d5dd6955c468b244e553b3c8db807be55b6b795f33168f11bbbf0a6c26dab56a7ba82edb7a3d10371d05c45b6162b28ecc0bab78e732865c683399d451d2eaaf402587ed92d2b0b184e4dcf02e6d9f5ec53da8129d6ee8ede12ee17ec71254293e65ab31771f3ecc0cdc037ec41ca24bae3f4a071c2847f8b827705aabdca581ccb608778ad1a0771059763af6e9e133d21040c27059c7af7f025a5362cc390eaecb3ca5dd649e2ade2eec6eb0ab207f86d880543cb179baf3c7a15bd3d33fbfa6bf2e278ee87ab9c9af06bd54e218e081ed46a0941a19b700a9aeceb4f304bf7fa16e3cd26f71abf8295e2aea2fe3801e749625e5ec94e6986b9342881edf289e3d23bce2939e6d9b8ce55bcaedca0ad487023ac05d836f956091f8e2406039fc69fc23a19f1d9d12ade15fc0af48e88f4f85dccf79f4568f62d379de52140ca69f5467d98badb363288b1bebfd42013a35c392ddfced735c9cfb4ce93c9071c934741797b73faa6bbd48d98c44bf5ef09f026a8c9a2090ca9cc1ec2847f5f40b9bcfc35ec9386cd9cf997d742593736f3b0810a74825b205be90eb6a399563fb608ff8b6653ffd5ea8cd7bd4c72d027d7685c3c108d4a3e1c7895955bfc98ab1744f106ec7d1626ec75b2fabf0e5febca3fad46003aa4394e98d1a88836b6141b321dd59143078a662bc6a37e38f080570cc5f340002e32448640070e8c74268831a8bbc8877b23000ee3afb3e142833f5fa4d16624f4de1e20111d782ede2c7fca8d08699cefff001e439e5b9dd7e57c596e2d3771f8d3d08a205b95e415662f86885d38f648339c920cf5b5f452ecd3424aebed66bdb856edbff4f398aaa39deb4c92976a826f8bcc4ffa6dd4384fe1bcc28a07f8cb3fe5725fe283a853944a52db6cdab26e07e0a6e33064cd4c2a0096e776a92009c91335161c7c1cf1a1856e91a4b1b5b26775adb4ae1b829f1966aeff7113b693e3a8f21448f4b2776ad9a1ae92c2a3ff75f704747b9a14ac0bf6ea3f998edff902215cd816d2a3e921ac9a465747645a3655dc0df91788f3189514d344c7a6c6c889653ac8bb9bc8412634d5537d2de3048844e326126c1bef4666fb683e50902075257c86213b36a8714e66023ce93249012d0bee5560a2f9f54a5dd8a275209ff06d042f1f208b7019fb004ead3381605040e19837917c633abf5cf31f661aaefa2500b06d62e68db36400a755c95b5a38f9795683478049632eb6afb1b52084c4cf61088b8c5513025be5601b11042afae5a4bdfb3c9a11d046868b107917c54a1f0859ff17829ce15d72a16563d1bc4b04b9875508730987dfb286d012d85c2b9962baa776b2819739d3f583e73b35cfa93f09a5bb2425b393259b109fe9e171c9c828f7b85e276733738b6db9c850e4fe20eb8c5294ea13298a9bc0b535b571487812c23a9fbcb2d224c6bc4fa790446ec6a33b8a25e18df9dbcef69f4c6c6f7151997b23fd5e8cb7696f9ff06e0fa2b476e98d929ad5b1d358a26f407a57a8aca3fb08273b7cfdca688c0f789c38175d18956dee9837d7d4ea3a06d427dd6129ef198ceeb0e51ec96c69c1a1e91349878d264f8217f2b11616620112b83983f915bbf6fa2640bf86c9971c6f485f33f5f9a7b39c9adedd2cb083e68eaa1ad3c83bf3ba70e268f5cd48b329c48d2be9b7be96533c5dc47a948c17b0cc318e4370182032580474de18ea4d21162bb20cc1ef62c41660f3040bd5c9253ac5c8e1a82d64d93522de0ff1acdc9ca41f03b3b41fd2f660779a9b8a9e86909dc9d5857e718227765ab0d205100ff3ace0ffcf7cfbabaa7cef6dede322f06deceb08aee6d38eddcf9fd1ad0ef293e6a666fc1fcffa555d4bd7933039671026363286f0ea20177a2a851c52bc13e3eec3fa7b05472dde8c5a664edca0c24facac9d9db29a495ed6885a8d05843a601d2b8f63068c2520ff320033abb0f340563580ae4ba29127e91691ba22eee76dd3c5517650dcc7ee7daa33aa397c55b076f4510d20c6c3d2b4e8003bfd862f00c5c96ed5887f23fd734b1b1e8d69d3fdf3fe5cd7a9a53ed95db2defa8120351cb688aeb33abbac7bcbbfa5c7aca98a71f629377c0038a8455b1f89759ea50bbb997311e4b130c1cf04fb3de6900e106da97927221a01b7c94c90dd14407463d71f0a2203f6f99f2a5eafd6d50cd8e14200b02ef6e06f4dba3b233a6d3030208b2cf737eec5f8850d5182f50de479e505656c8b74b8034e9825d7748416305d8c8cf64561685bc16d9e52433d516234605d2700bc0db195e32650e9e577d1470a0c7a0452378f6ad5ba38aec20c905b92a6ac1cd889483fe41db91d942b644962db78373b5f9a86bfd031029989290cae2e64f6783f03da25d443f33c7c485012c7d2100824cf1a9d28b0f8bf7eb4288585410105d4f7cdb0794579f8df857b2814b42af899df02ac810106dd8b8f082f6461dc248450430fc63568aece2ba3cbb97d81421eb70954832a906914190a9d6443f3894219002cadf916349bfe82322fbaa8fb9ff3b7978c33ce83922ca6e0b13102822dd143c9c2ba39767070a84cd296fb1cac419f9a66868037a923282f3edba1b09ea537ca6c0bf279629f3b09fc3170b60b22f815037e3d92f0f3b60b42bedb77be6a62ce86a30ad0032f18b753cc435e3192cc58013d32018d916f9be95e217e4e5eaee3b2317ad0f57c21a55c3dc61dc504d8e9d4479012fd13fcc4a065edc4f4686cdac304919554cc7859abb829a3c76536786fa7711b2bba80b5a00217d8aa3443bfd9dc20a75df4119661629865c60ae2bb51b460ede131b090b46e6362de4bdc0b70f34298b0f1e202508029c168c38016d6001f584c052eb836e399df6aa2ddc6d5989834fd705937ebe7806103d7003c85d23295a80feb7c7c03b5d9b286d316ed401af8cd04df45caade506f9771380a2c78f8244692a31dca92107a78a5a0a1980bfc17cd1e3131acfe52baa41191a4cb69ee196f1e680e56d34b6526adff5d4ac13f73804791a3da1e36bdffc4435ff6d434e410cb304832495ca95d4bfe1e229f4f36388a9f27a250fe3603353dd753c38172c03cef3c7e8af045b6513722f30f6073e21c2293200c80b3ad4346e8ac3901100709a322f2bb079ab2bbfb04590eb6d0ee0a555f6641b1dacd1c5828492f1b5219c631746e75cd8bdf533a61c1c319b97f5a616516c5bc186b671f368eb75fd2353b49ac7ff4234d69b7829c1f9cf626e2064378c4bfb671f224345113339170547eafde6a4d91433b77e1ac23cbb16712a2ef9373a8ab60d98fa4c265cf0cea223e1bea108bc3660f7c2af40bf572b1604d274f3865f0976f8f96c9b8cc569ffcf9b4e7642c52fbb56fa1b763efdc1cd9f9227a07400c084c7ec150d1c04cb7b1cb3dafd680ad3e418451fb0f722a04568b4399ff97211d9fa5016f6c41ff01f5adcb8c5d72053acf88bf02952ee444403682a64eec16ce67430aee053fbdbf501cb28a2a189df4a94b7845c1d5ebab45bd440355a5c907cde115c18fd7a64cf0c50a9ce144f4dc5a08b89594793d6ae8a2bef6dcde0362105aa9bad105153b72d4292b33d820e81d565e6da5dbe975ae1a6b31c6c142c86cafaa3c3cd1d366491354159b6538caa0f2a7b1c317db711635058efb7716d846ddb9705d79d01204ec8a1cb6e5122461bd2ef429022df2b7273df2338ff80819f9776ea6ab6eab50e897ffd7f3dee56507fca2c693ad66a1eddbfb47a56c22c3b629a6bffb4c88fcd31d7e2e9633f23ff4a53d13ed6a6a63625f191a583c8d2162f2b45353913c9f748c605f7ca7e5c854432b16593835f80aec9017c013d529b444af2e23d582301996a3fcc42e9472452ee77e2617181dca840fb884cb61340510e43b77325904df848a69840096529944ae7a06288fbf206a14facc26775855b5ab4d682101cff7a9db1aa0972bf779d91559d30f8fc29dfd709ad0551b6fdfa912609ed894efe7018db24b26d00e824dd9d6b92ebfb38665569775ea3f8b3d6654ef519d895549ca365acaeb39bb778c98303fcbb2fc44f3106c350d14f9eefe9678c5c52f0776592b4746007731a62c75470dfa699cbbaee0ab16ce37fb107035ce48d81b0929c813bf24ff0afdc17be465cf4b5370400d26cc3e7c0617d5a83a1e12259ce7bf4550370be0528a6a6866d81dbfa1280862c0d74641b0fcd9a5690dda6596c68b0fabd5e99213b109425f058a87a15940c92cf7095e09a62fa7916e59506e9078b5c62549e3cba72f5e2a03c6289707654add41eb2e03f5a9a6d786c00c951ccf4b2506632fec15590f627dc605f27105c54e302a1023a011db2b4c7de63da00327d36067385f111733d0ea9975164ae0b0fe196183e1ea30e8a9daea57ef66fd3cc77c6e633c4b6dc139f40302339fe4ff07312deeb63dd1adc93256e8c728933ca12b9a77111965399945f7751d8827f10be763f17818d74843b813256da187793a9a68889f2e3e6efb237078cfee086faa4c396b7ad1f69aefb79b1f7f7ef6c75b9a8965978e568ae67c66e5ef66c62385e1a3455da981cf0483555fb83278205f55afa1a6f625647baddd564b381cd140d0a1cc436582364737103024b580624ad1c66d093c145a0001e5f47f1ef22aac9bf6b4be3540353b074ee16672111829c5b8daea813de19d7efa3a2a81976c02480b9621f4315d20853d3f64041c1322344ab6f008de80c11568130ddd251d6831455625c13d05052c1dfc0551cd5560940c0c61bc4bf88c73a8cc4141168421d893a8e3ba6a49b867df1800506f6685d15f4a22a3055e7497c7e18ac8e05bc7f70774b7411d88f09ab3714fdb2eabac238acf529c15cddc6b1ef3b39ddcf8fbf9683a65656b921e2f8e20cdf863eaf12a096f354607495dff4d8069bb418cd4150028e9398635f3d4ae66ff9af8428149dce220d2ba3cf1f7f1f4e01270baa77f5673d52335664edff836b7532d0fde8be4a1066655f7cc96884a0c7f517fb44ffd67d510a0e922bac172a263ea0b48ec084dd27f7580297e57d7f596a7017182ac8650f90a74b72f89243bfdcd9112a2e11d15ba1d197cf49cfa0bbcf1e1dbc03156dcb4fb6067e576682eaec20012ccd111f76642c58f5255a4cced8ebf199d5e243855063f67b9b6a9bf7d4b6f355fa945ac540da0799272b0ececfde2b18b046d520547e5965e9e39205bda9ba145167ad50d364212d035041392f0686911d3ba2552191b723f703e65513c62b001bff21d64b2cf1e16de42d13b9c07460e4ca6f9b2aaaf05d81a7552af56a0e9eaa9314bed95292e7bab447a819f5b3439fedcb6d37a203e4e9c0d9ece9517bd0bf4040f79629069ed7b1dc7a993d99e2bb872a303e0f7afc0310958d5d089df8e959b97097042d570a3e092c3d6bf6100667ba8452d545cd6b3164fe8065650c58345c11e0a2de4757aff9842445470f5ed709a4a3b1d99ee4f47cd6583bbecd41fa80bde86c6e14039cca2d87915a2117a5de6a3e6e8179a13ad1179fe5fd88102d881d6f2a10f360d674645ea2c4ca954d1edaa41375e60c1c2863d0a05d6ef1b9244b518438fde75b40d3453e5da353882e4c667faa60d562285a3a72f30fc05d489aae5074d7f350284261c9cbcdaebf0b61c47bddf449650ce2e4544d0e55c96236ea6e26563643fdae0b6bfc3bac15b8eb37f2298768df9d23c1f4853a5a1712cd1beea656b7da5daef91226ce2aa52187ca5553ba6fb1dfcd2a5ef44a149eb874898cb39f8a56c5e13a5ee94a850aadcf8aa094bd4eee4d0b74d70f25c445c70284cc6375a3a0169eba27b46585030836d6170fe8b4d8fd8dd5284a75855a198327350088ef894ef5d90f0c3426298d4dc1b2b7f114505784c0631255f2cd1fb7b8fb32209abe8cc642274dfedf1262b20e129c716a234785757afb529a6f561eaf202af0f10bb7f88868375ca2fbda0252a8cf13dad4b0f0cafe0cb0cee9208f750b3dc8103275c1db7caa8bed8026f20f8de8c7e7c8bdb50b551281778ccc01d708a8bd9f5c72f62e815f121e4454bf30b184421d31e28e3c0ed10f146dd6a70cc4859754f83cd55ec34b286bba8e98f94a67549db8f0418b765753f7670a2775c2e7e41318fa1b20d676e0508cf8d2f0db563bad00f481a4ce43aa4e9ba6953addc720f3a0c2b98d7ba36c8bf7e1b42c468f3948f65b3e4cc1b644aa4ecf5804fda4cb6c7cc5e3b0f2ee02aa0db1c2735e09fe8d2551a9537319024f8f9d4a412e05e1618e1189b48a93f135124af51155a0333f420d27bea83b91cdb66de713925ee59e94e3833552645e98d8acfca69b667ae5705717539ba57b97092c5097eb93066f1cbc06b5576f93e1f77417d857f9ae4103934c50c62bbb47a4e0a7016e9d1c32cb827b017c3e8b1edcc3bac70f18b2e57dc59813603a5739b41e0f3b2f449f126d2326039f3bd3cd9970ed187fd840590a801d1639857add946812ef1eaa7520ca96c021420d86322c0aa644a348cd99f1d72cb55dccf0ba8862fc3cb9d091190174c325e125dac814f8454869d3775de5be67fe240827941b6ed940e5b06591f8454b12958847ff006a5b0cdb500cf8bec001501570678f36a200fdfbbacd3c00043f76b2373a8aa20bf88a6faa071b49021370826b27cc2e801f6df891d831ab1085ee62440cab8e0b934fedf845a7961e836a9b8f7dfdb0c20e17cf94d76c3acd04f45097239fdf5fea24128543d727746bc6407c498f4e6dc327770eaf237ec295a0efb3ad1d91b4db19f2a1673128b21b5fae0e48149ccea05bc33ce60694f9684569d0d9ceda8439f031386e88392905878bfd86b34b6410b4d88728ec4a7b4dba91d043affd12da9687b2f1e71061cbf85c9f6c211806bd39a5dd14a298cca97d8e89623c4a41d826ea7aa7dd08082711c2b41c549fe7af7f47127a428a279b9ade201794a580fd194786f1f06cad0977098707bf61025ce50d0d5de470e49c6a98f44ab4405e6bcfd7570dbec63f6907163bd77bb8aa4623969f9661c85bc1f114b2df4c7bc5d5844560f0da14325da1eed40957a797fd0e6b0442d2aaa7ec191976c11f932ff372579f998f9164ee5d2ff76a7c30e79188694f1f53e25919d142a8449c750167a3e646c9d631766b1b336648de2ece8a712e6a00051db64920a8904a352b73c11464f22442877503185991efcee7564b15e8ecf68298cbf02d5c2f4c6b1c0d958bb8216f1e6633485a904e66ec6830c5049c9919348fc33336a59e87f1d4d51319c9290d66c385e0bd606865b1201737733f592e73d03fd71ebca766f867a5b33ca189012a08f8af3f6d803b8b23153bb90a14990d357c4a5f8b0c961b0d2dc223c9b0e16f71a82ab0de00851ac8e51be971635637c32b721157aed4575c49c4dc839245ff643025990612133a53acf955d61f7ab359e0e5c839b3510926f16bcfae67a534ae28375ddbe13620e873651c17d26df24247422a48a73e494b9846e403650d8a13f00a40cf20d98caac14c48d0bfe1ff95e40f12056a71e6e2581c30bf25cbf10cca90b9bf6cc4c754fd1a22675d722eca376646e8bf3b55e18f31ee4c49b3209827a6eca5e3caf8924ce01d27c9498f8a0d570c4eeeab33ee4538f92dba24cbae8987cfb64e14e01972dc00bd29b36671db32a7736c6f84aa468d0f920a754abf0b1b99582aa191e6f68a85f2bb0af552608be99d2087edb5124b69909db2ba4b50f6a6cc0e001a8f1754b04e6ab05e9824ceb865f1ca1179b54088c2a9c6dfc886afe1b8b984305ef608e2709f3a37821907f418e997ce09102c2dea35cca4e219b1ffe592d4ebedff81ed527a4c1e0be06358802c89c7d4d4d9984584ab245e66d8a528f13abe5b7989b7a579fa071b4fffe60f535ff8145c75f06a2b199aa0070188e6d015660d6237403a5949b5138f5a40471e7285b6e740fcf3e2c1c0c8aba77582738cfb24ef7bbaa1a9e191a936bb1c39454e35bdd86c33121ed25ff9f2c3eb38251a126cc3aaf51af0f5c603469d43ac8b91a70d72d550748f48bea76f73801c93338e105906f443337248a853f7be97ba0acaf06af8aea3c53afc4d5387ffdda2d4fcdb038930d4d67efd15e88052fd2abd6317b87e404ac0e23902b90001cec3a6c026e9619fd75433662283584f65ab7b567dc86872e8254cef30b30053c72bdd1302c6529088c558f33ff706c421168b830aec1d18d3fbc47391a556f271d0896f3a960319ea211c64c3b6836190b70667f866251fcbf18898754cac14c65787c92440303b0fd1179c3afc9a8361927c88092d23af0c71e95b805bcc9405016b28de38e77e61f049e98202fc651051a730e36cd9573f4443019e89fe01e6dc8ef8430b610d7e51fbeec6f7d3ed1f9c16eac93438454a5732585714af4ca3fdf117db3767671278bb8143d0f62da3e95a69ce10354d9e47c97f35c9d284bf12e0d833e20fc6702452cf8dfc8843f32d435ea2ec3fc0c4bcccfb262c46fa5022f1642a225b50b6e1b6c626d5ac0bad3bd7592d34cdec6980d38b65e2d32e12b28a3b81e249b2f9282d7a6b2cd90c8617e7adfd4f002f8c798f10065084fa5c9a9eec889acfda8159d0aa640e96269efc53a2878c258acda089208dc001c2e443a55a7ac3958469e719bd94cdc960c6ecfb6f6234c10406070aeb240e0960ed835d43a3e15b3d7bffa3051302ecfcb89e441284a33a4a27ee33769ad1b5cb33180546985a20631aa30a372bb5f7936bcb2c4fa609aa1d91db8e7b4f0dcf06bdd7aa337139392834cd5f23d0f2ac5d6aedf588434fdd32538f87de0f107667b6388c8fbe6440320061c6a6851dd90c84bffc97270a1a06eb6e07fa6515fc03efb185e281ef57d1f25c488bbc1550a075f1ff627464bbac235588713b2922708b7c662bb5788d060223299722932e8b066e8757870f6a16896b8c05a7425702c342c55c8c30d072888fe7be6778b73305a33601bdcc855782f2ccb1c650e15b30f71c84ec5e21680cc119dba0b11508d0728c45909e895c65b16056d317ab6bf6415a72773274805d7fa4e6b0bdbd7ee9a92acaa7b0ca14d8a10f94d12df822032d42d67422fac335d6c7fab3e8222c85be84e9d00284689278cdb69c1fec294c7d1635d8ec130645fb6e4a8a37892cc5c7a7e8148b20c5863a68f8a33899aaac16a3cf34e8258570efb9c5c4ee8a4893c7964d9a098f987c91755070cf8918b87453c7e003058412d951e37808dbbb2e3cfa21ee690a75a8b8783d5bee187dba7df21c334c7dddf4d67fad78d300bffb86acdf419339a4d0be203c09649c4caa2cb47b55e64533b70bb8f3c386aaaabd9496d60149d1ffeaa018e373ab5889b572bb21d9c3d02f8008a405713d986bd9c88a4813cf1f7bdeb4797883668f45a2b967f882ada3cf63d11e243de0fae0cb705173150a557b2a4bd8f64f87a8efa5fb576cf8da4c4513567227897478fa5b2ea2918fa1eb74c37d75dec6c8412f3d743d7a17829098d3b7fa144f22d78dd3f73f262bed3ed4662ea9f22adf92bad261da6b68534840f9737828260efb4524b0df8f72adfa2112f0dff69ae7fb8cf98e99d2be0b3a18e72c44bea09715ce8c56f860321db4e7c82bf31d42123c06f882342f7da76354f44b45ce0c30c8e1efad22c45b74a5c60395d437ffc393ad44dcc037073a3a9179b400ea8d6c32b7bde6c37ba8c47b9f33e370103713b9da86e74d08e393120486ebd7e7b1d7b0eb97fbbe89f617111d7b0dc1fd946a4471ee796f54c502bf275443b090bf02e5cedf377d8888e5b85111d1ffa0225eeaad6487df9801f5d3fe23b09c012c72d58e1c5610f7a38af239eff3e1dfa1311b2a660c0dc070b02706ecd164081f93eedd938ceb07d080530f758eb64504e0e772c98c41562a8474a37e40436d62b7ecd7b381bc64543325d3d24da60a589c5a6c1e06773d983fd2f161093aa39e6cae0772e2cbe4722f37cad2c05628b05c164b9c693e99aaafdbe926d3a0f88ea2d7c5c8b01463a6da8672ddfc780056811a36b64509a0bcc8533c6adba2a000255448613f43bf51d3097de6a345c366415fe344e2d16758c99c3f4774bcd63f35b090cb03dd6eeb0002819bbb179c9ef7a2cbe69aaf8285001b65db48556619f137c8eaa4ccd997d667b5cfd5730de0eba33448ffe827e853c55c58a3cca15b9c53ae4e450ec488adc0128aa0b5810cc58022d7c9cfe160e19817234a5894f02026709283d46aae1af320fc567451b1b9c79f82016c8ece28dce24777901ccbb41a18d377565e5e96ad20feaf32f75a03e8933500e775b3284245c6409e3e5f5c74498e864e862b231a20c013e253f70e7e27f8d35ebf78109f42d27a608162b9e960ade4155d4ac9cabfe3408a259cd515c2fddbb4b021b1dc17c5cdf4b68a3f6547dcf9548e3e3f825aa1c7d481ada9bc963dff51f1a588ec99c5dc20a4914e3a916c0d38bfa89091f9d0b2d5d077e60a3d5a54aaec8c2d3adb39aa2437ac1a994ad2304a6eb4f4bd5dc7c44443ef3494b36d73f17f459470ac137c9c09f3ad44f0252d4cf197dd92f9d93292e55a27d1bf76636568b4d86daabcca91fcb642681421809edb9b110ed68d19f5c884b090102209b65e9855c2cdf41ccd4258dff97aded92e06b981572c5b65dcd8cb9124c8959584438ac410f263edfe476f3e48acc9b76f7ed58cbdd97f656957a0a11c676ced3430001eafa0b40061181a190ebc885b684be765824a3b3f59e08bea1c981fa5ba7840d403cd1103b50c5de351f00bc22243a6559ad5e7cb865bd442babb3a502de025cb52cdd7993a85a99e03a196430504bd809386d86f67ae0640530b1c3945cbbff3a54b1623e420ed81647f1ac1633e2fb5a0ad2dc05994df303ab088cb23ad78b3866c647435b3fc9f96ce4533e459d4e0b3a4a928703c827ff49f75714266e4c0ff3a055a6bae0e44b027bd84d1c0de3868d976436bad242e53365b8bd40a2da6392d6de104e7f2455787ac51da9e3611838b638896d2a0498a415a00016b61f75770e79f41ccb710740ffe2216d25de6fca690335c9800bda325732cc95abb4775c8da6dd216a7256de90f7d482d0f5c701eb2b8bb3bfd7c6537e8965546a358b7d494de07d405c66861d99b03db635fb4ba276719ad501db21271c2e300e7f6f884606934cbf7d4d54bd59b7e7d19b47549ce2ee5017ef1126bf2a230bd7ca66a3fa3c4083f92937b587276aaa96654a86ae6b05ab1f4d066985a6fed95def7b6335f212401c7252f3b1eed4a6f9cf8e7f3c8b94e8307daf1719dafbd49ea46e1b91ea6cf00307cde3fe2a3beb4a85e1bde585364130b07a83e4abfa1856f3a710586c2384bd9e3bf3284ed6e293b5f35f9c014a935ba790e04f99cbecb2fef6bde470bf007a366fa0bf9c6bfc28a45c452c8889bcf55507a01abcd30a1bd6acf935b63828edfff8a3f8d20607fafce0623cf7b547cb1047dfecaad6de1f0a8524279f02a6a5e06d23ba80436fd83f733732602fa0a0580c04dd3207017d559665ef8274b1b1e3a44cfdf0161c4cd23b7fefb6a64f0dc54e5e1809c09827e9d56b63d0a4eff9291ebd378dc171ebde8be5e6dda2ff5312185c82dc504ee51fc96010c3a388a80ba74594777752c100ecc28fbf702e9c04cbede03f3f78a29f872dc9e71d4f85335c7bdc059064af9da61d82b0c3c862183c59885bdded2af491a8fa6988f3ebfc5de7d12766046657b4dc3bb8ef7a48488458d31c5089fdd026f1f7b3548201a477f7a65071f6f150a0c092d951480c9d704ea95c598bb92b4d4b698a0b559445d20a4c4b63320986dedce8be1c4c3391b2650672e263843ddf45df89f89f89e43c9ea5790a65227224cac0fa9a958c02e0f7a7e45f64a8dc2cd67488cc9f4caf20201ab9ff7f648455739de0c830fcd50596fdad4e1781e5c2695ceb81e1cc9e0aa35f41940114298546258b6ad64e6232879d3b2d22a18b023c4e13761a206e7b992081a3174a82e6a71223f847958cc41bc1c59b2baf9195a49134a70a02c458605af7614500b03d8f49e021f2f51957e4f41844f2f4265209dbc18881278e80a1a0509f108f4ba355fb492bc125107498ad8f161590614dd0945d2d2af90fa067724117e4e0f1a8fe0d5baa159b73e53cd1cbd35b813bc0e5f1d75df226fc5928b60f0981e300cd85bbb1c9588485c82175232e24a9ca168c3b4cb425e45b482d7dc222f7717928552ec9b5dba2b3383ba5c9e6c64ceba8c6054461a0eb0b1f3b90d092d5ea852daf3f8cf7b04695e56c9bc052f94d4cd4edef6a24e77314a0eb1fb9eb37cf73ae1c44e3f29ca05ec4cf8f3b155c028d8d07370f5423cffc78f2306051bf753ca12532b99980234941196c6faf3084b37df659a7501b43285cc54561f8b3b8295f8b8d49aab879670a1b432cb6b517a2877eb507d1b78be05f066ff1024b9179ba599c13f2b9a79030cb123c1eb630f65c9d41c3468353cc46c75e6d10eb9f46d14c25186967195112c1f797e63a2d7b73f4eb23d4670ff8f2db9822496579712583f12c9204a90b15160371310a78c99661dbabce4225de4157e5e971473304efb8220f4830dc9eaf0544b16baf904e52bad4416ca8db79193f54f19c647da05724de926dd3d0bd7b428b5893c29cb5250cc433a10c77282363a6af7541b27df1b47029cf33a9da73865e2d2aa282db3cfdfdab1b776191381540cb19cf1cb34a957dc3bae0c89ddf329f2e805f6055272055c18e43dd1c6286212f0b1eee49a986d489185d1be79e093fe6016bff57d12f49838c80a5dc8040e82a309973a830c188664053a9710ae89187cfc8029e1c274c12c8c670a7c70205c28e6b83db3a3070a7ca7001f643e43896314f8805ea21644cce4eaf8d14eb41f8b4087546d8c566b3ee6c21707d99ec5b587ba25f091262d6da157f0c27f794682cd1344f30d6b6e20a50b2fb66170a90b90ca8dfb8b1115dac0bf029ce2cb82e71504f78c6379a6da98218fd779185482ce9e75e06394a40effc3bb5506a9161b2957e7ee55de90500bd6b41fa8b58cd5cb0610f798c984410e781a9558446151e60c073566bb8702642bbee81ee6642b12ec33e7d4eaf30c634accaf0c2f16a73f1729d83ded2b29cfe5dab6695f49215c2eed98f69580e7b2d2c7695f7d0914fa1486cf84edce1fc1380bbe0009580eb28a4d04be88a4f18b1a9facc7a88624c0dc0c07a82dd838cec862b2b9ee52038e0a5e8a92441f53a0b4eb7ee9ad06df437d5dcfe6d9eff5485c0589cc066e76ddc887523778b8c7f9e14bef3b1a14d52b5e10c4ec812646d28e6d7298efc6f4a25351c9b756b20d5180a2d6be52434b4ae643620e0af5b2cdb988cc86cddee311021a754b253524a3d0798f25a917a4db0b389cb80b0021234cd7a6aa7c62b171f2102226ce2c8b0c9112b9166495f9276c390560c829292a5001321cc6481abf6f24977c22b86e405f0d8d8f73029e23ad8860dafc0a6fe15dd8bc1489887fdb4576b5293e2cb93766d14958c17ef76a76cef07f0f742603f91c7f911375b3b85547a584b095d6b7ad698e57cde584b5cb2d4375c280f102407916d70a21d200b6a22c275036ea918bbd52d78adfac41f35e04c6bfd71260ebe67491391532702d9fa0840d5d6953bf2ee439ad5a54c820d061e32bffa17af340849cca133b4c30257696381ddccb07a461c500201258fc3359e9efe9cb3194c637ef5d2e2dc16f16bc30a863aa44901e4c9717323f062048fdc8fd3a618c6692b5b22f546fed93f71fd598a559139ec5f89eaafb2ec2382465ec5a06ce4273e2606e755289050d9e909f6255fe5cffcbc3e0872d7b09f7aa9d930ad6cce511e45d6af8672dea40caf4a24b82c6d68161f0ceb787c8fee77941f4d41f7eb155512b83941a8e7b2f14b372154c03a610482ec417dceaea630c7e817a360a7810d0f7ec665d3beda17934172a56962017da8e058bf99c968f04fdc4b99f5e32e3c301cbecb42c87cd0ab207d50a929a82f79ca3002d3e757d84c3ddcf8f1051f51fc00ece2d69d85cd6eae969bf11fed9d01c3930a262eb1a52d9d29a09eb76e21128a617130d2f7bc5fa82dd4e0961eb49b07feb22371d189333bb6c193146e3d0cfb1a917246d7ed33bc37aaa179c49a28e2d50ba9fb1fcef7aea82164d3214972d5bc6a5c68cdf4714ab9821e528ba02e24deb076fbae3a6114e4fc9ace12b2eeb6bf06585ef309e8c61b69089626dc0945445a7934e9350b33efd80d8983f6563f399ba05d835692492eb0646979c5d7dd8cc1b8f985c4eb254edbf11f97a67977be9760cc99d12640bea554296f8db0dc9e245eceaeae7faa3a1d98070963759adddc0afa21cec8850c3c88cd2f69521eb0ef14e8a03bbf2f70ca2375c1e44df1d1cb3d4b45aff18581a7a76cde0cb8cc7e32c221918de7acf20b8ec6e3023c33e72200bcb04f3698ee14da536e50df99b35ffd2f3668545cd140beb4c9557eac40c1cd0480d6a9987bcee8fb77b5c7c8aa2cf73a69dd879909b3f5d639ad218e43123757135e105fed3d075424282d64d2a0d1a325d4e1da1425d1383ba95f9416c244d4770157d830a66339fb86ca8588ce2aa970ffdb0768c7f957321d73091025d552864c84a12ae98f446a02b09bb357b8d905e02391e8d2041d56d1f1aabd39745612a172771e3ab1d704b4fdfd3e82659caacfff3e21c912534e660e700e3669b3ad814846925e2be9f894904861905e9e53c34f0ec769ca02794e9c76247105198132338eeb2b3345ada92def180c07512004b089465f3612aa20ba0af3a44e99b2218cd243785df214eae4a241a4396deb9eee947fe22c5b6cb7347105e150470bc3c9872ad4dc6f93e8c24982ad4f1562a29b3aace693466d0dcd9a5113d43532f311145d2bc47ff97e65e42e9ac364cb674908e17118137e7a62b6560113f4e1034b34d789155c304c50d892c879860cb2d3a12dc460fa4aa3cb915a1e6630481a957c9766894776fa7dcb542182ccf7b3ef40d051e64acd554949499e031eb099ba08de23c204c8262154ac18780d1c643c2de55c03545284ee1282aa0aad3d057d879f944397d1694aab3b93455b43f5f1745b466fbd80d12a85664b775207c6f9f9232e6f094a33105104f6cf0c3bc69183ef5f1c3b35cdf896b9266210862f08ec7add11f00f19479a4fe3e2dcccc0a68e426b476915389d06cdf4905f3895d73483d59c692b73df32545d8ce04efe006cb5e79fb94cf19a717a9b737c8ec39c79cb6f9a5a038f3de5343a6d202e53c877e80b0808527d9afd932220ce221c4f0958ec349838595735f19bd533d99f1c61cfb13e7d44bced9a239a7a9f84e51c80f74577c38e11f77959c808b8690ff3c7b8c6fc4ceeebec58455aa411cb3fd35432c43f84676944367716299ad96e1c3eefc8db960eb454800035fb2df83dd1d2d86547068243732ffba48a455868219440ccbca0b943f6fc31af9adb53ea0eca12f64dcf6eafe9387c5387e0bce6c9ffce8153fbe31653128db54a6dd213191ff4fc004be58ca2cd2a02331ca5184c9b8cce881e8d0422b269ddd764efbe6c62b831e07c5fd57346a96a334a9ec8cd687992d7aa7ae014dd4c20bfb62831e786808917b6aeb9e344588bd20d4e11f4af1bad67e0dcfd8e23be57b984362060efa6a6421a19a65a61fe5222603111a922e6e10ac3786930b849cb6f2d54f435c211e9ca9be27222f60361a8e30c0b1af53422d29e6da05bfaeafab42b33db76c8d77b3b546105eb7ca7d7b0caabc799faa3b3c24000e2344a2f781325c46aa70d336bdd51a60a5626b7081a69fea370fee6f8920fc5b32c2230676007872dc54cca8e303a290e3b7a488127338a8b67cd4970fa9d7d1dd282ad50f0374ab0cd969aac8eb3cd1bac2d62f0f97e6468e200a1b961b7998c1f82129ddfed6bf5eda1dd3aedf5d91ef60b063907088d26b48396fc239381931c0495c99de4627a155a8f5472334b80b252040d2af44fb65adbe47372a6358b45add78393256a26c8920fb66fd90f86391206c36dee69db86412b6f0506e37b4aaf14ab6fa0d7188d1c5caa2a03ce0e73ae30a7748d2cb6ff973ee095900a3792a4fb6cc56010b2025fd99035abbbd2cbe520ad62b48ffd01a0edf86f697ba425e45f39aee15df2ebcdb50e47001326d1831a869e55cb98f7f378a7d015c91b30f68dc42f46db406b36120298fca0a7d0b6ee5fc925520837819835ce1bd494b0f68a10b7b11194dadcd6324cb24a77c50f75e357547a292ff545ac3a79c25e70985febb627de24a92e71b755a97582532a5b7271b083920893ed97a03f46507cc95edc9dc0abe22039c2895a946d373c2437a11f5e50108db1cc4ca988eac93c51eb89406f02926fce101be8d7453aea52c03428e11d578d3d731369972062eda26c445723eeb1bf52270353aa2b533a3b5f1b6715256c854d1ebc224eb26bbd7e2cc9f5e337368ef4fbf907ffa6afaa703f69f5eab3932a680887e53fdbee0a475617e2f0ce56d29d856c4a2f02e11437ecd31ae2eb8136f738cafbb07e6f84efd27bd12585f54271b25096a67f02cedf4f49084056fd2e0e885247bbd84e0d71631cdd3436b78865ba39762460619e202db1c92f1e2bc464dfb337493238bc26c31cfeaefd696a079c30e1bd4a4121eed90a1c89684c955da5604a5b9f54d0e7af2321504dc2da5de8f82623dbc2a213aa7af191d0d114f8fb24118891fce8285cc9b990ddf0fb1c8cfc295776a37f4f85b596f0db42228a98c6aa3b88780a92eeae7b54be24e1da9bc910ef7e36521798ac0e88f722b43a997e1695595fd660f4f5c4c80eb2b975f6449c22abed461e415f2ec57a8ba55c03a90f0f23de194b6f80a60763bbad5f52de6146ce6cbd8ca3df018800918690eb91d65d9c0adfff16cd01af2696499b8a3d3c5c90ccdb3d33a1a0e640ea9acabe115e270e74c2d4bd531975ef6d93b4aa57e5350b091651f110c65d658da89f74f9e180ad8383ec187b005989b6518d70749da1c3a9d59638d19cb3095c0435f3c0aa798ff0b7262900524308108c7527fe84adb68d5835b055628e6692593a4af25761eedfa596a8c619cb94c4ea16099621267455f864b052566af3a9d4c90c27b0d60aadb51e925310ac9f7efabd775759100d0faa5d5bceecf2c3dcf7699f4dec56ff771e3c9bc0f47c288b41cdb469400c07a8392fbecac9a52cf185fa973102610c9a074851871cd5294f23aca2253cc712cb16682def632db5c51da776ae384e77394d250b8e0d6fa1dd2850b6a711f2c597249c095c3b665ab069c3d79284b2eeb02403482f0b4b3791c70ff4b249dca4d94c984500ad46579d052de4743bc20c3d0f987eb589f97b5c5488f62d4abccf92254194ac5c84e552e8b912ad9edf0fc7ea15c8a71758dec124b2f3a59af28df8554362612089e04a1c411885ef8e4e30a62bf6d0c71b571efca18c7765d8d26aededf87d5ca015c3ac9ba05e4e2027a42ba7a55208e61351dc057aff100974b26a31c20a6f48ae019c5253c8674f3c9f0a5eb686e43e1a6a38a226e9da9b2baf75d0e64e7427103c0d0c4a21f512874b8e2e9dc64be9b365bf6fa997ea7e8de25b4a4ed2da54c49a667086b0759074b2740999c10a819e4e7862a3caa2018d83165d00b44b080ccb101a473c1e59e9398ebe172cf490bf3ec9f908d5a8946d4209ba800e79ea0ead387fade3ebfb370d1b75ea23c183ec0291f54bbabacee76817e48297d3fa294d22808d486802b947e8b17dc459f02b46721ba52c048943e535f114bdba5f403c0f46df4e8d2d276e904f336211bf50d698958df3a8d5157dea4b009d6e271751022a20be8746fee05c011a7bbbbd3c04e726762ad881244b47fdf9c20846933e702da88955a5bab53aa66d24b2483a8dd47d4278ddadfc8013cc405b8a193f25d801b71be3fc3f83bdd79158a77656d44eee976f776b9ebd0901bd66873dffad4eb766d04f2861f4e1b6ed86037f43823f77461b7b4b73e73923b6de1f9bafcb4b289f099b42bea2d8176027a691f8e59b7041f2eed434bfbba214f2622f77459de3ea3b3d9acdad96c0666e0a16c6272c3e7917b3a37773636dd92332865df1ef84bf0c05fcaded6caef6b1e9ea95330cd09d4c8925ff6321421d9e3ddf06bad7584d09fbfacb5947d0932164d335c6612a5ecfb692d02b277d93bf82159f2cf46be4cced4b3b15f56ba099a9aea93b764fa2100d1a6705a1bc01adc890943be44f93ad3678a0bb42f18a07a58e982f2452a544391444005204880dc79e33487d90cf90a53a6cd92242de400c572d834ce9375b1d0311342a548a8e325488e8e427fbe6c00ca499917c6b07400a255f59b0e98c903856a87951f5a5ea0aaf6f8f9b1cbaae3445001aaa4d9d2214f9fdd942b2c52909ca19ac24186968336c1800c72ca8829b1fae1244e141c52bd1c5843b472583b3964568ce696363a3fa8b4f152652a8a470e5994f731e282010e122657c4f819c0d418296c785598c82015dea086080b0d47e27061f215c30570e8c400c5ab0e8e1648d562a0503f88aa0c9c23527d98d8de84d1b165858b6a4aeda3e46a10171c2b1f7f5018a4e5853b529aecb0b3044b47101be61ce293a3cc20233ed8ac98b285ce1c2a3b5447742dbc973f58429a28a9936766c4ca9f1d0c7139d3458a66c6ba6112a8e969ca1b313345ee58c9e101156e8091faa2a50c140dacc9f41125769658e964d891004e96144368c23859410a8c7ba19345030d607200549525055b5e08bb51e78b470f19540e398ccd0982031e272c17b27c69c5b93af2ddd2c6719696a4ecac17292c7c5d66091f0f62e8cb22f3c9fa8c33589f29d9ebd6dc95f44c585dbb7ce687940dd403c6f13c27fca0f2920256974250b00cf1105465a7aa4e10999a06734b1bf3b450b9a093287b527310fd72cfe9ea7a6041ac977b4e4bae079dd8977b4e4a984248c1828673da21eb3909116da2ed724ff7e7d22ef774766a975a551342e185254aa1385cd2a0f930c31e345f6e8862648d545803ddb9b8cae2656a4d112d3d42a27240f3c2161132586854f46a022e180a031507cb8908873113a5cb530bb60cf1c821f3ea19f4e43086a3cc10373ddce400edf1da3283a54e9f1c568e773131a4d09329532d30611301267cd8e40002c6c820a9a9e6c3438812dd9b1a9ec6c84801a363458cd50d4031e8087b08f9dac2b503cb202c303abed800c667b747509e40211eaaa403ab27284f507a98597205c81a3351ae8c9112fb91a6298a0a847a5184e8f66c99c3eb5324cb0e6258aa745825aec20db4a3b30548080d3bdae0e80ad4478c93950f54548da11e60be94c123c3202ecceb01d5440c49172b563abe1d1cceebf075e5278dd3561e2b2573ee3871112a42050482c50607205f47921852c1cdcd088e1f5f5e72a6c8911571405b04853944c315317cd2c8ca5c1133667775054ec83bc280a815c68481b1536690913538e0485909c94187b6a32db8e07344ec0c1f3432d8d0b463cc912b215276486121878e042091ecdf8823f0ef24193f8b80960cd65a6ec93caf262941459aa4b08393d8921c13baf104caca48a0313d724d06a2927a43a40bd098273909e090840a57979d0d8472603d1b87300c0ba9c6f3e437f8a2830d2f48e9d85287d54c29f30503973045aa72f3438ec0e51a17a007ab88f472d721203d9ec479c5ae433cc0ae433874b41e500a061ccaecdef0047d99cfe07cdbbcc1c80888943d94a33a2029a33f7ba49c2945837272dcb6bded36f97d5bf3e3ebce3ff3438dd11fca428c52e4f653b06d6feb9df931e4ca2e9ff9312690981b5e5c58a255a7e763abc9098f2d50b24c51d3260b188a8562b9f3798636554f63ba1d7a68d7131f4e595210c4c38b1f99cf2098ae3343898e2c374a7c3c514d2ffea5292a074253dcf060c2e60500102ae3c3c9922d63b67c99cff3c12f6ff8cd9dcfe07c1b9899838e0b470e85b06060830205203d2fb1344258b8ddf9afd3e96e50273a245d3b2e5df27c72806cf9b082b2ab12168491e8f95248cac78ea814ba0c892f2340903c9173a7498e9f4140a12e7f8b15540cb6d2d4e974baa8dc9c1b084157aa8186345d7ec394311876c8f578620f584e0145a2f0724d26ac8a58aec7222bb9b076ddb0e7cab6d90396eb916b6400e5834cce060869e05401a04dce49b08a71e186a99c0ddc95162b599c3c5380e89240391f6b503a40d0b0c9d9701d7ab672dc0c08c338553b9a7d02e3a550ce06ce891138355a8f9cf3b186028460c5c9d9e0af1c390f364cd9f940f3b183363a2e5ca12eb91004cdc79985c64b2c04cd47366306cd0544083d99caf588b3930b893c8c1b407472366a79c4721041f3d1730cfab3c380e6638daa460c9e1b391b38ac235f72fe3dd6c0d9c9a1d039276933607e08009a8f22f0acd19323d723ef202417da683e7a18962f5d880118000de60e32e0b1d1b33ab9618f1bb6a0a73b137443eae7869546e7825073c38f46c799981b82343a7ad07243198d8e9f951bce6874f47075c390464710446e48a3d1d1c395badc15c8e9861e6874a4e930e6754bca5d7fbaee1445163d14b9f890ab3fab648d14e4ba767de4ae313bd7bbf184dd3483d33f81e9d66fba5c43313920288add46d7a5e8907c535bba13f303be274e4cdb095b939336a58ed445c52646a8064e03a6877a8ba29cfbddf9237874b185c0748241dd55c84661756badf396d8b94e8210d5e5a04d3171724b065b22e896acc7679f28e79ceb3401d811fb7b4bc6acb53fc2bc9699d2f8466daef47c449ff98832313f3f0bfa3d9626884003afad716b25adbe1fd13777ae9a53958a0e2a3ab07a3bb07a3b98dcf9443d1d7a2ef750c8724b3e74e717e0724f479714e5126d7ed73c48412cc58b9bf52f0083c839d9b7a09145e0bc189091508a564c1a6d269bd55a1105641ffe8bd9d39ed25a8bda8cda28dafc682251116980a40962bfd1bd81b7bf7ddf95d80d96311d6b7cb04095959b7f73a526255bfe7851d96395c38ddc1cc15396183835a42973436e72d9aa7a03e584cf9caa9cae3e09298ddb9fc14da11601ff24e4a4f47b9ce129fa1642df265302f89c608687c5cbd89e392bf0989015845c09d2c506ae5a8367f43802f6ba253459365ddd7e1e8b58108b56d8f0ba4e9e982dfc887fb2f01eedcb8041b55cb9534f519e68f245271589e2f75c13817992d047b33f104602c4884da660ea5b0777c4f2c4894e2a71a7c41224c498253ae93a11e7e3b857a5ebceda04f87952a6ee181de8619ab7059296f8574c0b67bebe58f50471e170b31526064914382ce4e6c3981fa3c85d6926c9babab9236b3edd4975e77b274d127716fd350a619a4003468c49a293f86b5d5dd74f1c9a553b2617ebba6b31c9a274b967c5e4f61cbd5b2032f5cd8b569046e55290236239abae37e08ffb7700479cdfbc9e9a5c7de4df35c7bcc0a28cfae64b17c5d295b8f404c5feec27d5cd8f66230a9f8362cbbfddddfdfd1c4b19dc75c1efb16cde6d9d4e6ccc0ed8d5ec25109c3626efb1fe1c3f4bedd71a8a6f5a5c28124da6a1e812cba5147ca2419851effcd93883f491fb738025ce2bc290277c0e611db2e2e5fc671c274b00b1c043072b39ffe93ffd433017740ed2c0b1bbf4cddf2792292acfd249dccbca727da98b33b925adab2765cb81e86e39a9b8d39eee2e0bbb3ea76cbbab49e51f7677e9bf4a44a34eeaae0bfc846c14f20632887eb7eedc724b0f97e7d69c69cdac79b59b514dc9e84f9d6c8cc56050ee62a2ff375ced6e9e5b97a9a7ada1004196f482b021de8aa2cd66c7106308fb4444f45dc43bd1bb880ff15c1b81e8458c1f9e48c4e8e189448cb4271231864f2462149f48c4587b2211442323798871f6761cafec735a88b1869416626c5a1b81bea5e0dbf16fad8d40df8a407fd644b8808480f5031546e752722bcfa10be2796b6a0cc418e38a63f9e1fa7f18cb29a59c3e4ac6e1ba999283dde807ce993d32b29c3a313ff0c001c992c1fc6871738779d6fea924a14efa3bbf75eeee8ce45fce5e4779891e6239ff5cf73ffedc499f801ee2f4ea9b3ff52f3d5cff0ee888f34b36f20be6056cac949654562f4acf2d69d6e45e54d89d4fa94ccb437a41e4cbaf45fc67de1228862f3a43b81c01932dc1a13546d00b6f84d49ea95f4bfc4b79ae6480ad222dd08064100c51b9e954c662c0a18e1d2c7c7293863b75b0747692e828939b4dbb2a7da41882d221ec506efe4f8996246292a6019658d219f5d22c4aa593b468283e3be1aca05fbc4cf930e40982cc1ff991fe5c1b819ff64c0e8efe1cd21a0a19f3d758345d266738cd427221ebe70d27ad36522a632f47d4e59ed4d87c0e2ef7a4b82ea572254a8566b97376b9f3792cbf6ca7fb7ddff732dae982cf6339ab8df3826449ef58824ff7d36119b353c4be5f02b602cf09d70b1cc355f22d300c4b1f7f633f8f331939a35e47e17b2ef77250dd599b9134ab6ff3915c10e7e5cb64d94e973fcc20a9899855029058f6541623cd47ca12d94c50eca9f920288a34a75bd22c1ad368ec457b663b97c5c4b14ff7f7f3b27589cca0962d4bbce297f18c9f66791872b864c38935e6c9cce3338fc1a66eeecac9039b6f693419ed74d9f242f4a6ed9f7f9b3cc76c71fa2380c9c1fc2ea294452b7d602e3ae9ce1e8eb0dbd4711806733e65c00a2ba914c09d3fffffdc7ae79c3b6998bb005488d745df5ab0980f4e55de07ff4942dfe6c3a01d041239279bbd55e8c68ff8b79cbbaa3b1f83361804128d5a29fc993496e823b7a3cb946664095c89a510c0c452c6789b0418319899fee76f4919e3ed2f2ac382f6e0002486ab05499ce4e6982439e6280993ea01c14d9c2b718e0ea02a284273c474f890e1c953143d586168961495c175090e9b355a02874446fc4b43c342971e254f3b6cd00085386d5408c343e8466e3e8cf9316698f3dfbc36ff461b451a083944eea170e4ce8985ce146ab0b2cbf1edb19f98e130292a5ce56c24e9caa61dd2ec18cbf5d85892e49aa68d6e1a67b064391303d701429e5f227de7335398dc12bcb44eeaafcf46d503d92d81df7f3233333397e04f3f64a416443ee3657793f88c17aadb4f3bd3a5ebf613e97255c94e5af6e57216d1afffbd1d8b2829c2bc64d452e3fc463f57bf285bae7e48eb08f67a9498abef3511beebe409fc5aa5a0be1da3c05cfdaecd5a25dfbba279f3c62807d6acd88fe6cc2da086bf3c00126c2071e2858c9a393ac668002509941b0215f142a58e13b19a2761036e717203289383a3ddf9b81201eeeed3a70b525e84525a9bb2bb57ea94d239fdabe539e7f45a29b5b40164f90e717e6843ef199425c2950912254a6b484e4ad68e2a07c52b8a2a17450403455bbddc5b410be4c9765baea85c1097b758f158103f5ceed2a10d1c71c4e52e1db4c8b888175ceed2c1090556c8e2d1eb1ac4e7d2cb3d25dd4a349b8dbb8e19f893efeeee5ffd9dcabf9770b7b7f57b24ea1b957fbbae7528faf80463c0815dee9d386a606730e832330afcc6dc92e87e23ee6774bf5b92b8df7390fb95b9df835f9238f7db45b9df6eec7e4abc5cdc06bc1c58cf54ca801e121f2087e5b0755d7affdc7a891a0f183f341a026e49a4428edb2a8455a1b9fdd5a644e896418fd19811c14ab7e431546b8a38b9fea2ad4897ebff46845cff9b113bd71f77e4caf55fc271fd99b8575585c2bb7a611fa88e7cd0a29fe162e1eeeeee4e410d8818bafd338e972883c2380ddae54af1ba138e28b02d56a8f4b9e3052b2cbad3231287a943ae22ab8f8bfc6d238a26d298f9b71e97c888ff37d1d673467cdff77ddff7b148d1377f109cac087b3207f567d82ead2ba82bfc7edff7f4ebd2c6a5ef27e8fb95c0ef471ab95127559288b402df5f742576b63bc0cfadb5364741a8fa543d5503066fcac506bc5c117dbe634f3555dfea7710489cd5fa483080a24dac5634ab999b2aa6e7d6c7a08d38f560104864b189d573e74a353a177efd7935eb183048e85b9d3b6ead4c7a8a91ea5327429e9c6efd529f288918648a4d5081cfe4d6ee39e7ecb73fc9b2fb65cfe428c039aed8a0056232dcef69cfd426d0e8243bb3f4519d5a75f2a682345557bd205bd4195963e642b2a87bfc9b1fd5471af31a44897f7b57bfafeaf754fda9d5c295665fff458c4e82513f85bb530688d9714a29a529e658a482c36ebf085044fa5e7f36e27a5cea5b7ddb4a25b29a2aab938650b9f5b9d6d91bd2a5a76ead543cd4da5cb7be9d258e57bffe14ab323bb76acd392737b9d4224011fb1b2c04940ff8ce0f682b09608cce77436ed9585942b26ed95a42a26ed95d9aabdbebfad39e734efee0043736d10aa8d2e5b85ef9911fb158c78c616299f4913fed12d2b18e0913e997b5cb75ae3aa6b4ddb2ee6aeffa1321114bcb64d74965ddb93feef6e20c49afa4a539ffcaf3af5cb58b4d4c23d7bf32e92410d79b729edb91225810999a3656fba3e0d394ba7bd7ea01384edd9c3e7dfaf4e9e0fbf7eec13712694d9f3efd51f4f109b4cd0a5fd05df0861ffad9a8b43b112c88bb5d63f17c147cc412e426c1baa3bb5a270c1ee846ada52cdcd5aeee5ca9d2dfbaa5077447b4b484c3dd6eff28fa88ba7b7768683a435621e683b552afb5d65a6ba5d5e7ad9452faf5563aa9d00f3ee2f67f947e5f0dc547bfb735145f0d994d74b77d02b406b7c76bc7f1daa731d29c97d64bdbbbc9ce1ae552dc8839e2036b28beaf7c3b1a4da2fad6edd31a0aabc19458d29268257982a85faf8ff532a5583c6ce5f9fab6f27c05a102b9f7e3cc9434b704afbf3fed44095ebc4e8ea0554246e2f263f7fc4c4da3939a2c8bfc9936592103c80b4c8c1cad3d574d006df5d9218a90d4dca262a689570b43ae049a42a78615ac44c103454512204a9cbd14c65cd6e1720f489a9bc29898095f339ede7084fab5159f9dab81232834405094d966f397b84bfbf071372469cccc6459f330fb1e1bc000240218dd704b01b8202e87f872dedaf3487bb771430fb49eb5fedad84ca1449bed7e1f4942d0d70d12754b1eebdbadf49e82d89d97067a0a69cf2643987fb32296330be7470e25b289c9d682d792241e48975bce398164b9f367963bc5fff02e44f20359c42e707e34bf88c91620c4716af9d12469f48d7bb2c902868310d78dae34e29dbd1f60774e9a9befcd34e6540df08aacce9d3f83741248e8ceacc9e3917e08f371f4e72fc9a021ee430556e043e887ae47952d5c28ccabcd953a48bc76c010c59f1f669c2653aa4491a27565e5060c6b0d99305bc40f233b04d848f598d2834b951d4c10a8c90c5c3140b963870446e2d7126ffc93d734e409ab909c2d2455a8e4669316ad3643b8109242c48906fac65997377f72f5f8a2a746bc21e301efd0ae4b101899a6167ac09982a148a03c5a778a5cf962b34309a01bb6d09df3a2b2a0986c15dad15600074fa03737bcdc61939b6b046929a15ad2e59087b39b9d677777777777374fefee9ecfedee5e492bfbe0b71bd28d605354584476b93a8e20920b27cd714e073035675feef9984626afd7a3caecf5889a73ce773aa311c9e8dc6eb26845778f14bc72751c91950b39450d6239679383f922e811e7f3ed152ef77c04b913b475126dc3c30ec5711766fa23f8a5585f123f729ebe062131629467cb99204678847d31a4e6cd9d14c4e63c71c139d9c108941f14b078c9cd9ecd0f9a44d222fec589224ec4c92e6f717a02e7071fee7c9e3a70cdb43bb142bb2b3a1bc02f496aaaa85499c2414a4d53934052513218c9124383ce0aa452d3891592ea1ad35101e783535b4ced57be93ced9b3a9ad14aa41b193bee79c6cac7c4465d752b204c18e21e40888469716f1108b401ac882316ed26439c1d1d3e7035788d84992b51588506e3e6e4974314cc21295441fbf6f13492b056e29598cc3eda6b4c5052b97c4e4c09fadb5d65a6b59a46822daeffa42108928c16250daef0b7181086420428c80886ff569e3130a6206b7be8d3ba84fa2e8d6771277267ea40d67e26c763f3e5f12f82c8a36dbffed86c3cd481182647cab5f33c1a5eff52341190a2e7db7c0063919a8a385114434a6948b548ba2df70beb4d4c28ffcead653a14d003e9325812326074d03bf04f0c1b72ac07fbeb36fba5f09e6d7d529f55b6723e51bd3f85647d4cad61680e7ad94fc9ed8671fbb001ff983e40b46f24f801171e92be83299dde193886c2049e3231aa39c61819a189435316099623ea220a8fbbeeffbbeef330282b60ab449f307dffcf55c929c538cf4002f31d804c81363adb5d65adb4a29525ca013a7a8ee494cac93cad68dfd11d3d9f9c1a43339f09f5ae65c2db19c766e7646e8f9a61636d13118dd98367edff7cdeffbbeaeadf87041902c4db8604896e29d91460e92b7beb1e85b0b94b6d368ff2599935229fc7ddff77ddf079224488448412c495cefe04a7491c23f26dac24f01cf7de4fbd105663cb7020efd3db76ec95c53c747f4a3a2a6e8d58cf2184e960cc6bc29508c4c6187becd767595a5c5bb2ac65bda00bb75eac098772d8cfec6a6744f6226e868f89821a6fb7f3e3a72d176f9c89fa9088c58b29d18329e4d74c5ea499184fedd3eddd979babb83f4f609d332ccaca8aeff3458837552d9651fba610dd6627d6bc015b16caff6ea2fd71559ea2466ab547b664f511b714dc292b06d3df8e044080d7880cc52eb810911661f526bc9250f46b83485517d4f71e9db6ca2c805b2ec6f31ae0d1ca94803fcc27009a4616a84b5d65a6bad48641bc13622912d398291e8885b6d44d75ab204e20836d17568d3a674d2d994523af956e957bf1e23886897dfa8939e6f5ce3b93c8e795d4b4c22543802dff956f4adfc899a92ec249300146d3f458c4d58b0b0ff5b092616b38bd3fc92b317180e37cdec02b3ba274c4b3e23f96789e5e4e29a63be8fc59c80b61b68bbf104e1a134e196c0845b5f8c63dbda69675b6bedf78db37ee3aca990ddfad48325d9eafbe8e581a5085bb86825100f82604c220cfef020c659d547a14f4daa1d965697ac2c3cae2e1831742480edb0d6daae81e4a46a4104a940f0fb3e1004bf0f04431004c913c2ef036760187edf8c2c9bee389ffac8dd4a14c939d547fe369befd8224e19486bcc599b00d5e926dfc07f61dfad7d3f4106fe0bf0fd3560df3f2b035f902f3ef28387510337dabfd70b0d4c2a7fc14203b4f74fe14a4bb425ae169dc47769098ca663b209dab4840f1c891394525a5301d27182f4c609db8d4ba24b712596be71894bf08d7eafa0276e5d2a21e3d6b20605c113532cc847f4bf157d2d293292786b096880df27b209a7515e388d71ccbc16fc9ca25c621959e2baaefd16b7be091f86605b393c261e73428609634aced331c11a9b55bbaba9011260f017eb39d123f3988b4e024917fee128fa91ff8bbe816fc492d380b2d16a016062c96968b892ff8b7711c20b259c0c77824d348ed715e6f3d29113a0f703c71354509d2eb4a30a7a29a5de93ed130740ed28e06ead9dce5b9a3bbcc43cca92604a72628984b5d6e228f0f6cbdbe423fbcc4ace6cb329809596fcc85780b8dff30b3ff2074151f4a6196eddbaf45f80e0df8f7c462a39704711fe65320ab089ded9fea4beeffbbeeffb3efb81b046fc464ca735e80aee37d66bc3ab1c97c96432994c2603c1671a9b983dcf4819239d6076657d656389822bbbf4bf9186e12022dff77ddff77d460f4eaeadf8706f7debfaa982d615d4ebee574b44dbd64e3bdb3ef84db31f8e2cfac81d7043b4b3b662662d790208e2022219b6846b4711d782e308ae1d435c5a43f181202982f85c74994cb44b421bd2b1dea6dd5f7fb4f956b9b66205b754817dbf61fbe44a3d3023d5ef6b0582f67609d98892d0499cd537f7b7b71bee440a175fbc31ee6f6792cf192e93b99b590040412c2795577dfff194d8467452188eb3915a1094c99ad209279408a2e9eaeb4e1627166e001932224e1043850ac920240cd309645843c3133f67a8b879294750c082a2baa183cf34c98186c8902d3f066d00a686a92239fee828c3cf0e0845e667e6079952eb4f9fbe25a91123313333ed1b4edd5a6bc9b29b7ebd81b825db53ea2477932ad450e3cca4f4c85cc9162f2d0065e5edcb872b382485b7b4c5595a6263d9844b56fa2b23f3b38736182e5261a8ec8c0db4b9d1edf62a6f5d3b644b966081d9de56b5646a4f918af9452a4a7a9976999441bb932c52d1739233549cd0e7363983faec2661d8cf037881c8aabba7842177924c2693595b7ff3d671825fe9f7a57dfe1ec3ef1bbb3e8f80762959ceb820298376fbef9ff60368876bfb1bec1bbbbbd7c7a1fb5ccb7eae9d6193e5dffae5572959d22fe9f73dfdfcd6d12f9383633983defa14fcd2beec7b0cc1b14805d5e93e1553a7bbb207477a65a45f5a3695eed4d650d4b763d9762cab1d4b7bbbbdc7b25eeee91e9ac009228bd6a0cceeee3e7dba20e5eeeed327b3fb9ce4bb0798bba8e4ec56453d2a95b2682000002873150020280c0a8743029158341ee7715c7d14800d7e923e684c9809648130465110c4300cc3401001c0004088310619641043e800a9ff087fc73ea4573c88bfb8d14860c8282e38c60a5e10a712d2e79ef390ba79f26b3f18da56941976f2c15af2949b3db4c51eec95bd345e3c1078f22a14f36d6c9eb9f0d70e81cb1d63a8f490559e447acf10b27db147344f6049f52e47be67c62e89447ea711213f8746351fd10e2744b70818204f4d0bbceb4efd0d06bd8802691dd25167c4237b7c00451f9ae17b746349c7b1e5c90c08d438d634e3cd02a891e29c87b825380cb444ed27559bc144265f052468f9c50d3cbeda13ba331ff57318fbd49513e15e811ae087b885c3123ff46792a280b04f40972793f0ee665f2b29db7ce8b3f07462618dcaa43c20dd488540713aac59215d3d732ba347582f9b00b07bd9f487aed82471603daf3513a0bae709587100d1d10e44be80237150dca53a3bf08a16e3adee6cc60541a85b9aa2f2fbe761d267d9c9c402a8ebcf81b6e8c083c91e5070408c462e9f9fadb766a5f25cb9119dd9ec1faa797b78408540c98584327e1af8d59f041460386291274f35450fde1b1a3eeb8028a069f442faf663d389d472a5668e8db87613002ffa171e6344dc1930b386fe58f66c3731a17f8eba8d4ad32d1ea2711ff80a600708f8a6294eb6b1c8128c5bb61b5c6d95ab8da9fe50e8d228bb2a980239e1acef3d4358c05c35ac2dfd533822f196db9ac98abc91da834ca36da19129f720f7932052fe293c426e1d990925d08c8e126a68cbe71033ab068951ad43a9bc9a900cfb31348a95388608f6fa2fe924fa5eef60289198627088cec2cb9e0b9dfdb4d594a5038670971d6894e8e1c1b92d6aad697ac45108f1c2cd98ae94f21c2caa2046439a14570f89a5b44d4af1cf61ded8826a5c0d459ba078c390a6db4c04ee818fe258d4c3146dfa519bfd6485ea9e04d98f0be73fbb4bb8c91f08d1db7e74bc125ddd9d6c51f035b70cf031a3957974ba938a8b20d8d8c3df0afc4dec3714f999c49cd4918fd95941f7d91530c55eb2a1c9ffa6257a5407e60c9ec81881d48142d2e0d9e24d477c988c5c15834fe347813c2fabe84fc6dd3f893337f09c9971487c12bb154c340427b5028a56c81ca7fdd7f3eb2da1ca19dd7adc2089a5931c7ad785e83aeaf19dc421481b1ac52e3661a0747405852004c83a9ff0b25ea20c1aedd702cb764f2edccd23467ce5c33fce67a70a62953a09f9b0212b9befcbe13e677ccc90616b509786d7d66cdbdccc058ef5f25d50988e915893f05a458481a4b8363f46cd8646e1c3e35dcf245fdcb17bf37943ae841a07bdb7892b594cd15db273a826b074ec9b08aec44b3a69ab9d8c9691b41b1aad0aab0dcecb90c5e4b0771859ba65145cd046e48015cdb47eb1628a7214d467ff4b863c671a9165bf869f55860892e605f706de31e6678620393ce3d319985913c478b5e2c8d8bc4565ece78896ff0f260701f17fc19048b3171f44f563c10a311228ec4ec449c354da3b74af0206aebf975340e3f892d016358ea38b770a617e572254667f17334206debe02eef69eb8d81d46888cea07d833816bbbe6cf93f714aad1f874c1622dec376f18fc11b45ae9386328d3dcd76bef9970435f65f69e76863a819f6fe6afe3664a959670318cd173a60c94943029e7a10bf8278d2f17da38354c4ea1b49923cc14a9a2d7ca72fa16ee8585a24b20e514314c1f1dd5d24746f8e451311232345de71a46165a35dc295b2e3faac9572b4b429c2be38e250012e24e90c0eb07face99c35d9c4f13ed6562c38e662b02f36d871a46a7d0dbee95c6f63f3ffaddfa274e136e00be61be11f26a2534dc83687b8bc150a34f76ce6000d00442731b49d2967a2f1f727964f1a9f61bff57a5f58dfec1913c37e46eb656313735d04338dfdc0ff60ee7573f66d3884c5ff97a4de8b56d30e07bbb9938f75dab73fc5af814dc23d8daabeefc448525864d6937ffd641422670db334623511338a7d3c684eb95741917e3e291d041525abf4f43ef705ca08476651032ea20383e8c4ddaeb209e57d5dd50d0c05366dd2515672ae4338a19da536481a2363ae0f171adf1100eb5a71d5a039e4a59551ba6ca32077adf8d79cdd1aae6513273333b5bbc6bcbfd5f268ee4ef04caf790b51c884d3c9e6dbda2c6982834e070757d8690f24139387ae378a9209f41c29fc4350c24fa2f752e5386e04ae632c161ebe7e49efa09cfac1c89a8908bdeb593d399f9398da19f20335feda82dfbacbbbe2adf1e923e5d66fd86d2bac502099bfd1048ffa8531aa98bb68ffc5a44a28aa64909c1651fedc3bea7b8268a310039c2f5e4f24a63c0e660667a734f19c3b85ec31a3d44ff63683fa14df593683911edee980857d7a085c9908c02b131c386935d38516107af6e2208120c572251d8bfcda63064b8b388359aa0f576a7a6dc3de5ea6a9f8af3a161976b5598e1e1b91a0b4b9fd7bd64eb9b7ad97c2976369a9ceb1c8842a33d86289f6b6ceaf798b5e58af6c1e2057c2b57cc7df8002affb50ff2c347c9c7fff8c0791393c097664e1a653cf4817bddd3fbb0f20fa72fc7f0b3567560c7418d8f7628d46266c2ba8647167a479d45f2d32aac0abe1351ed4b6909dad7d5e184bcab360f2edce48347ba834727649a4eb068b6dbab1682ac617b8b082a071bf1b1748969c354b6a20b138cf4e3775381ce606a830f64880604346d4169aa375f970af219400dc9d2c1c8bfe100f92627214446a9167a7d0e58ce9b26c41e690f95b88d448ddf35ddf6b9aa574419ea48dd6e2fac4203e8762910b777eeb6609cb4356bf68e1ac401342e7be9831bf51dbbc9a0809d81f0d7e939fc13e5e8ada390b44e355db953afd82bfa779e54815425a73e4ccf2a4d51234ca26a53bd703db513c573231692aeda305084002af201fa7f96c814a03e2e1e70cfc2cf609e97cb33a64b5d6a2aef898eb61ebe0d720281211f6b1513891c269b6d912c9238a86d24b8fd07120aed15719b62443957ee88e5dc188cb3cef7e5ba8ba055bac560bc0be356df250668f3f9d7b83f0d8dbc327240fb201240df5e2887f93028ec7bd5bd20af5f27e97e5cdb110105696dbfc01aec8a7356c53fcfd013b6fe2637ae688b480cfdbec162e72161c262dbef363ab8cd28103033868b817545669785d229bcba1a7c5ae374a920332819085fa20b06c59543f1d28cbe159dbab979e02d6688dfc8205897ef17fc433aba17da5345ddb0465977c348801b3bb8fd5610d136bd80cb4579e1fb889c03fc109ef4b00331f07b64a935c837eaa1daa822571724046b2bb1cc2a33894e81f5271508e8bdd6499236a991676defb92f0efbada3f12b11d4f499c53ffb6c47e7af83cf2f788304d391072f5dfcf178658052184f28fe88b843dd6c2ebd05e8de2b9f85e3b6e922f55a3f73a736445eef316bd7fa1972ca06a7f82f26cf6e67e52a1ac099496e904ad7816698f19820c1677a0c6e125345cb9174329aebb837a9ed37292bd133da58d4d14f92a4e5b1b5e22dabf5598de5f486baddadcf3e636791bab2a1da773b9927c8c0087e48f1f23b34f1e875ef614848bb786f7536d40feae57790b8bb7f1907f7813716091b8cc56cb7a7b4e6ce0a8c865ea5ada18bc5aa69c7b01ecdea3a0c395d3532afccde97968e4560eb6f89a3026443601afb77b4a636bd76dfbbe12f44c918326ba4d8a8d826f5e935ece5b084541d49b023278b95ec421546528f942975065dbaddf766b0d7a6be04f65db8801765e463eec6930ef5da024c18076afb3d40ad5ec098d0e6e800ff75125a25299a0c08d9cf1fea17dc54eecab96d079138d696321404ce675cab67d98f81c41529ccde3d66f257d6b5537be364d68cd4e7cbaa41e6713b6a72947ad8f99f223cff7661ffb7f2e6f9514060891e1257cff66f05e577acc74d4aa2edc62b6cd7d67c88e471702dd2cf50e526c5499179ad77bd1aa19da69091c1642cc797af516423bd9a88d3acbe4f47137b4cb5eefdaefa1f78b9629b1e20ad91585eeab01f00ed8dca33f31585ae7c34cb6d6800b56ab821413bdc5ceb84198435f10aa8a1b689e99097aea79b887de2f41adfa31b48315e4606e0bbb431db60ae9bdbb5e2c9fb943c06c7fb4d66f969e289c936d1b1473bc4a794997cccbdb41e990589fe2d21aff396e125e6cd98042ae127a2e1d5e0c6dda88a2ec25dcc60664ba0c3f23d35164445b85e09044839610970dd8831ce182d53d188a490c0a43f2fb157851de61ae91f56d46227f2d758fda25ee7d2a1f587cf8039472fd4a5f0b9ef2e1cb322c9a95fed0f225ff9cc7c6dd4261cdd1ab5ad8b1cc7d3df50e6c999d238663dd716795edcd08af2b2dbfd4331f62e225493976164786e583892d4a83ab7385699cb43b829b268115ae92a79e7e248c828ace825bc1b322aef69334239af0cbd12b9e9a897e5bec9cc55acdb18808438f31393c0ebf00cf179835f157f5fb86be1c24730f227a6efc86914af9f4d3abd37acb605a62f220a472a9c83c0efcfd0eb16e00f2fb14a43a9db73fa2c4ca677f3dff20fcf293ab1c6b558ab0c1cbb93c33317d7192ffd5b9aaff79c12371dc9a1f0ce68dd4f311c82a3c64915e6ebaee5e6d0b282de2198a19c3a0ff41ad781cdf637fd7a2209114bc883533ed0a8c7cdfa34c180e1b4977f05b097d9448212325d9bb474da50a54e1d990e26f8f2a31990ef6a2cf6492dc4542397c2ba51812006c5a33e92f1539c6aea20f01a39807e9a0851f6ec3a3be7ba8cbc7f391befaa57b38c76a5c516421bbc960aaa2ac0a0ba414b43d02efc50de3c3f5ad6f6f2a8b9fb28366378b2b27938849f787cd5334133c2f61bb95ec34bcec8cc72fda9f59a4e766fd3418d8669f6194413ea2d7de5d84f9c0305c60452dfb4e43dbf3fa687854fda2dc31c0b258743d648dd0dd43ae76e58835e225adf161752947194152986d38f524ae33dff9243e2c22f4c3061a7be2d58aa208f3f93a4162ba82e082533520c9eaf816d1175cfcf6c34b71d9d5e7f127e834f6cc62393e798284924174f297af92dcea693a42f485284a24e568601159838f3a3e280140ffbdbb68f3c2b11084bdfb61fb91240b3d145f425416d995fec1b317a4f02f64429f04a1d1792bc6562a090910467e6a3b955184fffc160b18abc267fbfe2ac4bef084861a7aaaf2eea97303800a22e3998425ae0fed37fa74fb98ee81fcaa059fec209704187216af60bc6a164f58bb8d06e8a6aeda5ee4283b63bf5d8e28759abc7e0ce92828238a3f947715a7b35effe704cb1afd82c2b84f47b595e98d33e3e6d6c8fa3543dea74c30b2c37a9fda1e9c1f0a0eb0dce6c1467edc8393ce27a1cba77bad462c128ec82c970af50876ea6e18625274148d7eb5d63d23d80e81739a55f93339dee641ce4e188a0b8a962bdb08c692187c2911541293510915eaf71f9c12602b19403c4afbd6d6af60742b78d4d96e8916dea873790a107f8a17d27129d440f6efe8b6b723d35262882ad8b1b410f93cbdee35e5b0c51f8dc719383bc72811e9cbd9f4716f9c33cf0b4ee01080c8a54a0c5b5f09c604221652e446aed79e8f8e9dae8bf5f3b5f23e2fdfc9ada00067dc8839bb042687ae85be3e241bfbd4445ae10d7224a4b843233e451159090faa1af46ffa603ad29e433dd1a2cb4b9f7250bd7082addbabe0f2e349437407e63ecae4174006e5c787e11c967b57fa1c183ad1bcec4b4428aa2df2122326a15c335336abd6a44a48485cda0937d5fd019f92217f22a7c7cfe28cdee756cf6b5d4e1d61b603212a31f41eb9118956fc6c40e301b80f6de03f0bdc9688b84a7a168f884174325e420cc6c5d1a8d04ba00068f10f4eea9b17024d44b343504261aa92cc7ca6a38e9ba4a6ba648cda882eae92a520ea73d608719bc43d14880d89df810245a6a9cdf485945204e46d1b13eef6403f7016f8e93bf40c35c76029ba878145a180a116abd36201645c7eed9e56a75bd912ebd0a22f038c31874b07fa8c05ac6e58fc463abb2fb8cd35ada56455ef3b945a387126de09732c5d887b120d8edba7052670ad5a276454852599d8030d918ff4c10826489fc651738004ff57b45fe25a1e128109bf6ff3359c4bbe6fc9a350ab23bfa5187e8404dfb1b60e7cc6a5c5f4ff25cdbb7a9c58d03fa28e76601849faf9d237af4e093d7101c04bc6eaa1000e4289b9e08427a9bc340017952e136044773335310308f512f4028679385495b3fbe81c982a1c8e5bdb5c56b200b2a1a4cc6928523e77213d00b7c0e2028f931feda08813a4415888692c78480292d144128ea35aa4885d9e143100cad6308ebf01365effefcedc9451bc3873ee13c954531abba09597f540ffa3347d0ac34b0b5b827e0166ec2911381e0cda1d9b0a34460eb98e91a448839fa3c193f7f10772993e05818c2a51301784ae362da9003b267fdb073b57d3d58512c74dc0bd6fe983d6316c927b1535f4e9d864507d124fdd21142431f030cf6221d9a2d449185a71077532614104b97441a0ea26348da25f7eaf4f290748d1b16ec07965a8b43cc62a2520e2e4a7aedd81ddee83ffaa7f4b2b1a4c24118ac40728adc1e229ad8189d83d4b4ccbafda23e8f30f32db0b99e3e7b199fee789626557dfacb84e2aec8db59264f51eaeccfc0939e86f0134b302a9dc1ee3d7e103b686b730e92fe35fa0c76c206390d83162f9f947821b7f9e41b58b87c6e9c806e8b04abe88951a57d06db485fae9211e705493bfab080230a4b6988c6af2a6d895f7f7a865c4e742c4bb8ddb51a9ba21d0939641a2358f66dc08c75f7f9e1c4dc69f30ff7402101af97fef915c4391b6cec721dd0bea215764d93ea197f1aed1429a5e6757f37f652b30b4bcfade8b1e7578485583bc1f8274d63ebaa6bf5d55f171d3987004307ca4f64e9e63777d3427b2cf76eb48eea6da7f7b71a4c710276e3fd19b976f0a0b421654479b04f2d85e82d3d5a234bb340fc3ca2facdaa2b6c9fc044161508e4887ee513ef739eef009df9126092c9cbce3d1429113c6f98e0187aa29f267bb218c0af0ffd95241166194a673038454971d1a8ab26139856aee178e87fe511162d8e9da82914fca267ee2f951bd10ca548f51ff072be239f9816ea50172f8987e8ca0d4e728e2f04162aead3b14cff09cac713fdad6a813f7b890a459853bff88961e626090267aaaefd6cd0d28ed1b55ac3588879ba69d7a28493c6ef64e0b2adb3366d5c595473d38f6e5aca44c9e9069d8979a2c44076bb7f5a3f27b296973267564f21fa86549ec382ba4586f22221df9c08f60499a3adcfb805fa38e4f990cb2241372adcf7a2d74e2ff4300d42ba949475c96d67c097a657832c20f2420cb3323cbc66b863c6fcd23107f3d29c99683f319fd29cb168df98dbc1eb0f4fc27da44427a2817620a892efe64033528dab2a3f146f891ad18265c0b2e67ba6ec79c394fb83f6e4b7c6ce122a5e2ac70aae60c23ecddc2226ba0de4ec40c4ab34b84bc3e5328026d5b3f921a0142165da76345a321421dea19a4ec0f8cc324c55f7d232b9994fe3b142f0213e6229597aa24e8017e9c7875c993a66ddaee811c5c04ffa4366cd1ecdf2c0acafce7893986510b0f00d11af576b584c26e780c57d34b238386ab1e461fcd95028bda7fcb29754d22f9415f9a67a6f100f345a390fc6d950fb6231cd5ccb2ff3b0a4d0afc2f8bea3b3786c6998ab4e3829a542215e023b9815302e51ab4f11c99ea398a5dd28ca6d33737218f27908110729689ca86e845925541d732a31b515c472586a0462c374ec9ac1732d0a83bc2a825e15b5ad10c157d361b6e13704d481d9d8d3b761dcfaddc087d607900fd1e0939213f53de8bb8cbfaf7c6b9809f847fe8c013228d050d4ab08e229298fb807608648280a8a87f1fb0641e3bff0984d4fcfb1396eababed00521161fa141191eabade739f31dafefa52130419e7f16c753fbe8ac87cc3b483c6f02f5ae8d49e64e70ec3a61e38cb79023d870de025b4a6d7686cb420e04321e0bdb9d967abd179d55248902a9c0a2998f0f6e843c1db7aed3734249aa3182d6507d643635fa5a75256587b5f2bbaa15b98d120866639718cb40f45e4007d1ca1b8b6300a1b705ae2057b6df815cbe0cb5dd9330783517f233f59ea45104a47cdbc7e18411acbabe162967b12d98e4c1cd164dd750489780a60844ec3d436adadfe0b6044a6c690b0c00c04850feef34393db3290ffe52bd43f0414b13c1d3fd162c89f6a136854679cbe2cce58490cb80a55ae3b297c6f5386fd1f040e482bf7529e786e5587ba5b0270202563ba7b6b43d8723d42a5bc08ef34300ac191705b944c1abcfb4ba7a77a031b9c8d11a066fe61cc16b6b9ecdb40dd3bad235ab4d5aecac495c96ddf988324534984240f57f0be90c0a999cc1c6f82715fdb93d9ef12199cf299b84915f5e459caeb87bb2cface4253241a21c370333116568468b73540bf3a8ab35de8bf9e3b021b294bd2e78ea8c7008e9a4a495990554e344ee4798f9131f30a600d803955f7588fb35f490339bd2ee6b1130d975282866cdd58118bf52230fa8f8696a400468c1aa8b52067910522cf1afdb9be47fca78644cc5d31cdb3b379e2c64e346004486d1e7486949761b68e2d557132519e295b27300e3cd5c2652bf0b72f2cb520f44f660a3750210465bcf1e939eabd629ad06f43e48c1144dc88c80561af48bb27d930c96b8c4c00ffd92fd9d84b6869697efa8cf67425952bd865196d22fe547629356eab6980752202b17c5338243cff8b24288e1ef61c0e8002431a15452001b608d91e01d133740e172ef68fc006d291ef8c3543fc787422186150939fe155f9a3fcdf3158a3fd951eed0b2bc9975778916a0d434f9ee45c49d1036de5e05888af2714c493c0ee73a248a7fa792235979e6acfc777d92a3e0a9f54221bd17d1e2e9f20356a0fb75c12e6bcfd9f46b9ca5c18cde30448409c00cbd07601ad898522cb5b2e316a3c2a8bc8a72ac843e5652e76f984548d4be4834f8f0ec7935ed02f30590e478a938ec6f07eba7029b858912546381e743ee7b3f0cbc1eeaeadb4618ff3837960fe256043092365d7464f1586029f0c1215c0443a8588019645599437c24e1f10f64d73e552e8d9f38827cc7013740a59c4058583e45919a33d098291e1869ef07796608468624c3711e0995b852ea5b7259c9c5dc916762c1d8345f2ccb53f2e0094133dcc48f1ef33e8dc83259047dc2772e0cdf45040095eaa2737e633a348a796aaa257db04f1aa7d8a22bc4156dd77a56d8c97f394fed28e9c10c458864d90e566f84a74e57ecf81f1b961fedcd26b50476a32f9daaf41fd1e3a69bb4d8ca8eee1f5265e69b1740f6c3b5681f36b53557dd43d0ee3a97499b76e6088d6fd5ed66d06bf465094d353c6e357506ae28e1b1057dd375760c9271eff4f3df35ce0a3e214794e30a8a0bd0c1dcf421f6fdb4d086ea8e15dd5b81e2c00447e563824fc672ed7eabf2cd4818b26d2ac16f9d71249b62e861b4132327ba18a39d2d283f18da07703f1e5f5ec886b14bcaefe653d4349d65be6022761c5b4b40b229a95e729589caf61ac34db0e31f7822719d7d473d86ff0df34a80a7211c289a0c0768a2f7c4486ea10cf4678840f96cfc2afcca6574128c6895b79134ed09242e8085271602ec0fc74a32afb8ab47b0fd14f423b9c1c7bae6576dba4e6ea50383f525ecac121084df6d71da0f8b2ebbda65b84acf919af5b288df297eed91ce5e0e64900b363776e30a977de1456c0d1f544617156daae885caddaf920a36613dfa127a9d06c0dc781d2a8cad6c8056838d22017447b4d9ce6266adfff98ed589161e7cb222dd010d9de9cbdc32a4feb7d0d26934c426e076912bd2a0be83ff94ea57387bedfa51ffe0321690e3a88882aec199bcb2a203a10fa79baef3816a668cd039d86d0287245190c6c4a7aece1f3356cfab0f544a99b2eb0abe21fb017233711519f7be8def50193decf76dc48a54e8254aff4b6d547855c4ec706e139381f6f121874f084e195033af4a236bdffa28f712430749a5b6de1be55004f97d3e46eb13f6052b6a95f86268b41d328598a3a5983d0650f880d230df16b89a613ad83fcdfc853e88aa221d633ebb8d8717031a729d0de408a3dbce230dba12bc8fec94b03f2b15f691494de7f9221ec47989488e424bbb332a036c90c0eda215a18ff028e59a51f0138d02c6da286d5e1cccf245c0f3e53ca2690bd5dc198c5eca08e798a4cea118cbd7f6a5dd0eef4444ea434f48e86454d953897573755af938c161dfbe5b85ad354456237e5862648e981f3dad6cf9833b6e6b89041a243b23180b94eff4fc84ff2c6cb6f55c1eda2091b44242403591566a6f6c4d579944a132bd232da7e959e772da3bed97363843310737f406e52247fdd0a5293545a13bcb2b7cfcd0e14957dbb712c5241ed22c27bb4d4c2e86ea9cd291fbf532c2cb0a5c7fa414bfab925ed14488d2f2d81073d5d09abe746b7d7e288bbabb323d7d3e240292cdc69b5382c41e4124b50b8de05b5b6eef063d523449f190e1a409c0928d7cdd5b6e6c3c7e9c004ac0f3cbfc0cb5726c824588da698a500fb3915efb59a82c7d34f2400c96f1d6d96bdedf55434b8e0fdce37066395e057db754388e6545061b9ea244f826c59b9e5ad4485dca71d7247d0a1c1471402807a7e5ca19b49c79311dad45ab783d1250b56a5a48d59b7e53efa393fcbe0acc72b1974c6587acb589fc3e25fe2fc6ee8be1d6bd8dffef7f4b0ac655fe0ad04d2685f9a878f619af48dda9918233949c8256f8877e0f54b44c29845b01f4d3ca9a11c5e64706e985dae248ca9db70197f43d480b5b04a0f38c2d0458d330e1221ec2a93c3a90c11d462383eb5641747b65bf50ed46f96daa9c12ea372da4f67fd0611c0897873ac4489196ea8ac22dc0e4360577b50205c5a072fd6088c59e246e1dca86ceb33c88244111e35f5a503342e2ace64bf934d7cbc52728109123e8b98ca8a290e8be56a270d32a3283db45c0f5640bf8edf7ef0c4ed2011fec32ab5641f9b81d64f88cee88965cb6f9cc83730e26caa924faa52bfef44a51db2f7384f924947e35ddb37b6ea33e15eed5598cf54c2f5ecec69916ba344f4b302d1bc8472a6d6ea9550e7159170d2348b6273894bb384ef6d523f5c5cf0780d3eaee0c1052b4a707f9393f56777063d52f4cfb1636eecba087b56484ae7900617b1f544456869db99cd53ace5ab1219f71a3c5afa631b854cc887e75ab14c28897f7b88aa146bb0e1a272651b6ca0aacb35fbe09259bcf3060bcec6914e27499b81f19becd4ec3d7926b0d04c3ab59afb58987a06e1b7fd5621e8db165c229f2b1a5b842789d31e2d37aa2206e086257beebeaa72457e000a90ae415b3ef4d98510e6272956048d5cd7c9ca07fe236c62dbc102206dfa824e729bdc37030b6b3d4a402e8cf9ae3d4a9ffcb9a044e35a616e79164abf757021a7bbd443a12dbe993bfc4151bd45ec8297f479037c66d8fbdf49df353444f26471eb85d69785d7e8eb0a97298faa98ad4f422947f4c8af4edcb1624fb375357fd475cab97ad8a7537da246596b2d6d15df43062a9b676e16405f3d7e44413d311a9e80431e2fe89800672f7d75e7187489f2aaad00497ebd0b8a330842acdf40bb42b96eadf832546b5714bfd2a3e7c6b5424801e4224a07537faa85283893aac21ed4ae0255931d45ed90337bf4662e42641cc5bc8e196fd21fc91ce005092cc080f6901d4f2d450aa6fc582887906fbc4c2e0c0886a5a362b07c309029a8b601258942bce2b010b654341a40acc00d57b93a003a8c38e684e8a6878dcf9937049fc28ae78c1ac75e2bf75305dc6e2f9d1f6caefd971d0320bf8ba8475447f58ae39ad603c8639b262a83f376b79f62c6d05a59f01c2117690569ecfd91d869f76cc08d3b3f5a077c0905cd2a127ce6b38e51dedbdd58f02f8ba8b07862f9c99dfdba72ebeff51c25b1fc7a18dfbd834d117cf3163e96c8ad1091f46e85aaafb44d38d4db9543a5e4036e53060f4ee902d10aa8877736393605abbfcedcff37eec32f716a01a8e64540d7247a535d3a8eb1e58dc6687833f876db37626ef10ef45974359a1b4a09f7baf1caacab8cd3f46090d89135b3178f9674269dc056724a8546b06fcf3524f5922018fb21a38d446378687bd2459c30f5fe0f9191304f65f4b66ada8eb79f18aa3b929a6bc5bf43a0feb63b3b54bfcbafadbbe8422e1c1fd2028c3feba154ccf50f92327815999e42244ec05b791240d21bcba5a607613d9afad4634511911eb61b2b53dfc8af3062b08a8d497643170457037a454883273a246b24044783e780494d93d534842f6803464b57eb6c716b3ad890598a273e3b299e7a2ed097c07b4c1e842ef40ffe7355b9ec228428c48688dd4b33173b397ad79db41f3e11ed8722176767454594960b66a7fb0e0c0f6c096275b00fd338842b6db4c84347cb633e66ca8d197ffd44d3d2496b324efb82d05c34278b92d7317ee41b431a9c57069380b98ea7d637ba3684e3dd881a5292aca4880b41e6c74285f1a63382434d1e4bb1ea02c59521f6f8531984a02624b7f2aeb64d36c7c0eddf39b19d7f3cf07b6ed33a83f4bf4b9ae9989d88857537a7c61b65d7c746eb371252c6a5b6af08fc7296acd169d453fcb0737c094dc2c76e6ace5369c3cfb356973dc08703c22799aabdaaabb02cfd6ed15f890fe23d77f9d521668e84bd5c952fcea3efdefc31f2c4d3bbc102f3e2c1daf5b6279184bd18a77cdd39c5c4076311b3fdc19ba0963da1d1aebf5f752dd87b85be9734f0e53eca1f9143e5b6ac05857daa1466c78a0d03f4942c9cfd572013ec754e154229d69cb4fa46c8e14f513f3cf541f5113614243eb40372a73a6dc45039a97e964ef61947b70cca593117e8a8196446e12637f0cee80d7c0397c354218b2493574e28583c05c420788f5b978681ea9648e775bfc0b8af336da6d17bb09878a0ba32829a8096c0595c9589f116d6c2967d838687bdd86c6ae7a1457c8a760c14ea024a7e12836c9418b6a521c99646ef97dd53153a55ab25e5a33ff59643f09d2f2a443256d524f314f13c5626944a0e415f1f6f61da86600ace922a2fa8dfd7caa94c107c695e5757e6f5a0bacd69d53bdeb090c66d45fe87f01aa3c5d43a9fa59f2843837b1fc9bc8e6e87c02dba347cc51c1ba9f33e90110e7f813a2e367f78624ec394042121e9f8b8e44fee8dbb116f8a49f41625ba1a8d9ad1d4afe1a98eef0bc3fb1ce345ac9879895e47151d91e2e4eda84059b61e1c904812e6717e830953d58bbaad652227c1509767f387b40f6afb6434ca608e6fcc5d5eb6c43874b8262d4f56773fb429f20d3db499e6876ca9d0d83977ce1602db595b55626480e535158ad335a9f86f6ff215112a31ab488746f2542c89787543062cc553c29a69e417ae3c710ae87385e595a1f8605c7fdc1aa5468535d787b149b9c38ba8d81b066423d87f254c7c251444306d77d402f254f8e6313936d817e7f69fbfc1841b423716c194d770c32cfb261cf94c4266e660091d58388a6218c92480f4c606836f634384b1b378cabfca08ea60509f8c8558a350fc6e857aa3227f90181cc9fccff8bc6958f4e5a202353a2353251cda90e6a641f10fc41bc62f95f2b0c3bb9b72514724d16906d902103b1caf974832c5d8f4d7fdea9d5c81c3f8e1ee2f5095a3b8879bd5d111fffc23b61db436563bf596a8930056313967bbf409fd4ee69147f5b25c2eb32c7c396fc5e265b01c211af42b49e69d0ebb9d462a76223a24eb178fccde99cd76af91c1eb02ecad47ce8e8950c0d75f3779e9ba792fcbf26b8f63fe76913a42205e3d8eb6bbc551daa6d18262a334d303785667e4523d8cdef84a5cec0e83179f1f971b0df75a07e9887d95b6ae7bfb79d223eb2df95ba383625217a98b473a66b3fe6371d52b86592f52df0f63962355c5a9e93ade295445fbc1d2d6c49d4b335ed7c8995c662c9f1d8415049eeb24b559ac9d6500de7b828c799c001aaee043026f8870fd1160316f9ae03030c1b7469ef0af1bd83478e844704bde942c3335dece198b854ce0e96f545cd0b95885a8e97c1624f5da483de288d8ac74d1285d2c1fd74ecfc8cb57e00667876c0888e528a27559b12ca4ddc487cda36fa6bd2ff4f2c736a5daed90761d64d980a92b357ef0bc7210dec05699f81a10b29a8b784986f37edef1a4f3ad68558f4b38e543a981d51f44ef7ea8d7a058102c428c3593857c740a6bbb40acdad7aeda4c06c41a4e3976835b1bed5ee16644d554f63ca80f3f968896d2ec521ce91579e04a35bd1de50fe71cbda7986267013143aa1f7ca22e0d99c61e0e8a72fa604f69312000049a16440c35ecc882efa6930b5a0c187e1d1cba96c2fc04532c376d201ed31928f8930800a19092b1e7a3bc32b8f62856f8356d7d601bcbf56625404a3e60b3c7bfd95115abc50077f5820282701237c8703d26bd18c9f06a00f89ca39e416dbb65cbde86c3a4480cf4151707cfc2659c1dda31860a26afb022210daefad2369324c2f9fa48104b931d3b8a6a2eeca453831bd70b6c7bd565a747a415c22d9d521266d583ba0fa1756960c462a2fffc74d1ab4a1737d12bb7a7374a391544af69e6f36dc18687d603d2643d1e5748005356932ad3918d4949d744e102fd69244ef2f0c50302cf0cbea7e0a7a23fafd662616b92e15564db9a5bbd0ce1cb044e00603cdbe6fb4cf3eaaac2cf53740a31249389d751b9ab747c4debcdfa955926ad3dffb9c13a8f72453a329fd51ca5c632b63f9e61f33fbfccc4d68fe40390f5f14422c0634497ae05973c481e773b462a1e529739188983043a5fb9757c51a571f26b481a63be01e5b4ed273d34dffb93034ae0746ee952d7185293e8c393aced94b839060faab387187bcd507facd92d8f78f176b48276e298c1236d3edb8ad44a6694dc5a91838cbccb68502bb4318a46c9281e545f2549a5493c026fb762ec6284ffe57729dd3922556630100966fb982f88b940faa5049dd9c850f0e8ed9832104e48b9d8aae8e8634125a9992207fa9202808a5b91c30e2dfa8f1cb30c12b2f6c108433c46ac9f0eac6c9d6c203d9d96879e4226afad1046ab89355876eee27d394d09f570ae79e063856d7fbe65d004b70c8dfe47f83dac4b6c94c61dd926b43cb7a24306e90febcc2ce12498866ce3f36c1d32ba3a50d27930ae8a7c913e5c6f3a9e076be4bc27990c8698e6a9354e9a70df1f2db9e6d6a7b6f783a6c535bea065b8aece8f4d052591752fdbd486453c9c611b4474a1490d3fb862627e8825725114864bbbdab015f1779a0658848871f371f3576add4d3b61fd281f9e953466e043713a290202bdbbd7f0cf016c9956084d96c56ba0d2a1002f8bd6279ecb4a65d5f6b5f812430043e3f7527430310f2c6681568ebae64ddc48ee4d172d21d76b5b35f374246d1a0f111d57c8aa6001b0095a952b9c415e3eb0abb20391f26bf20c599f4fa205b1269d97c045068df468628d3860b7501e6e4deaa493864122bf31949366b4d846d9ccd29c73322fcc6851fa95cd14e1b576e169763a959072fef05954b37ffccdf234571789743757a7c3b1b76a456d5f9d9b35d1c4d27453875abb4b0f2e3e554608083443a0e0aa98878d4b1c487ef06da1cceac1b5c0a9fc9a988141ddb04770cf0d3a0f2a37a979254708ceab78a23d751165b09d16d400a0f32c7ca269836528768ba5eafba13d1005bb8723a910b3593e044909de2ab2761bf97b1ec5c714ba0d43699e347e80ceeb4d05dab9028efa0e107437d0d2b7c7d310b6ad07e0d240d0b212836bdab9320dc0454f0382e8b1c8f0a587a8a8720edfc8dc3b26fb60303df3c7b444a4499be2a4c5785cdc3435306386cfd4d45650688397d292a042a0037e75d8a716e5a47081ee905c70499d116f3279a4ed867d944fa472088e39744571d549b5a5eaa474481d0bb119e3ddb40a57c7ce47ced0833c2bc090f2f3dd2f5733a2a2b12d8c0dc0a098ad25185de7d0618b70108d287b13f1b6f26d45ec80b722b34b3b8a9ee0a3a2da158bbd064de77ee1b0f4e715fab284287d652b3e8b4afb1a83116d859a0701957f27b8e12e31a5794b8f8466bff8b9bf9db13cdff2f0480d82cb85c7afd805d8a16d85e0c5412ef2482e977ee4413b6c377711405d6b5d293babb05f7740e39c50e95f51b242e73e3b458a428340e1a4083ff0d8961aabbe1916a298ea69e17ab94b025d6445e20eb3d2103b8231c3da0bc950647f891c5be9ed78b06c6bed9b96df81a971f005168b4abba983cbdab470193aa2f0856b6924863ab9aadee876d1547f6719584f525cef3d51b96c3e840d50ca997905ed20c61291983b6993d6b8d0cf128166df37091fad9ace6cee727878f025558fb6fd72673d54f10ffc74cedecd1e1cf929ecf81195b6b69c671b2fe93113e1bbd1cfebfe627f18091b6434c52badf00d5f1bbdd69a8e5eaf6d8314aa107efa01ec55da0d6b1b49bcfec08239cda2e54c35ef14ba936fa077511c28790716b0bcfd1ed0b81e2396158ed409de0bafa564844902ff477220aad92ffeec987501717a725555d3e2b2d709303bb644ff144e37d481591a41a27d4a3592faafeb8fc8d8c91ec1fcbc69f7d2c9b30e1e56180b247d669ec60f2a421783e3252f4236280b418f2efe30cc55c87bb9655ac1484ea6bf77a23af45f8280d3c7831eed64dc1abffa967130559f1b2a11627ef23836d76f45821d99fadac20db1795debd6679c530816cfc20177c0e3e2a75d1fa159fea01c42db7777bc8380243c6621f4d2cb95ab64aba6d19c0bf9db12ae7c223a43c6fbd254804338ef370d0c6354974669bf1a49740e047cd732536f75b86b3189671aec46e80af1ddabf3bc692170a5fa61dd9db5dacb4c805371572e69724f9df5b4cc423173851ef20191f9dd3ce0d4545a5cbb6efe33409aa476dd3530ddf246c838b5c3a97cfc5fc03bd9c645290386d8d62470e1ffdb41dfd20d1a17ce881c871038ab0182ece0d40328d70bc3273c19bf75972f7dd40fe4bf38f902b3fb638fd31a534d934b1206c22fa87180196a0e115588d0115b787ea3a8102e3eab81d49cbe8caa130f8833dc3101fdcc5b9c996ecb19371c70a212edaf8b9fb0868c8d16c8942fcb81bb7a6085a81f1ad507fbf50ebc7bf9c6065b76b4def9db0e0df8a0cef58b62c8affb3604a65ae24f4fac7b6294743eda36ee40a1ab6d739b56011dc682ace1e2f905d677856105b1b50343450466ae7a6adf05af7e608ce12fa52b041155b31a26455b7dd2f871caf9bbc938f58f29b099b47473253c373ca0494df4b456581399d494694b310315ea275f306d8f5f1e40ca1b8f038f7693f5dd304e154f9a67bd201ca0e4889a575a1e1cf7dec0ac18399da364bfa7aee77b483b06fe9d975ab24d3a4f1d1455466086134c5f100e9586691be6679b23302e0f8df1d4ffbd256f2c6f697fdd546f668f9c3169c9793991d20b22ef3e86053fef1eba001b98d851382cc0a5f1daf00f7c4913f1661e98b65cdf3c459a9b4862b46461e9ceadbd1cce991b22b2bf91a91d8473cb2588a8034fe44b1a8f4254e7d8e83bad9966051e000b7608fb440d020e53d4e695a46d145a69bcc1b49e488df8c66c961a6b1c5a8f9a1809262c60c00d469ae4840210f224c0d5062b02d2e298c049824fcc8ad3de5c82f9091b6e2778a6a4f3df21a093c926e6e324bcdeba3d402b007110bb6c61d1dfb51134ff27d7e9511466ec9c14a5a66354e5c80b7397f6d3f9fb46322b9ea8cfa08b5dfa8ec6afd44b11af1a7d61f80e057418320f56e15585a99cef0461dbf1327bc2102bef09b3e8a118956629c141c0cb2a2a26be85e7e136874ae216ad16451e330fb0497cc9ed5bccd3c560d2d2c05cfa10df63511fba98d46f74101bcb1051e7f4d61000a4b95600c977dca618cbfdf2270560ad9dbaa4251f2c02652ae1d5d41521b3256142a607b3ed1f698fb0803d4a599b4475c305b6cef50cf91828949c9257d8ac1a8b2a2cd0b2949a1054a501f17f20c643201f498d38d3f69fe1652c93469fb1e0b6516fd048924a632a7fd2a53a29ab9b38d79379212534d9cc85f99dcaa8aa0e76327f05a8508b70057567d120b2424365dbc37e23b6e6eaa4423e637b856728791568cc9b91ed533110075765a283d2601f8374bcea84e12bca06dfd7598b1ad8c2818039239506cdb4b861dd6c7be86875bc64545ed9af097df9baf2ab7a9ff1834d32e3bd1c3b3ee1942e415d1406fed18b393980a4bdb4fc414a1d081b92bd64c13c5fb2fb4e89ba3c8b6dd95b957f61f38e1a8b0b69f5aeb0624ad27f5703d05b813c64ad0db9e8b5d944ce40a5f301cfcf3c649e407443b92b905762ff89f930155c66b1c76e99cccd165b8da867a08143ffd523846656f145ebfd91b4c63d0d983a5a57221b7cecf21a370918da336b411f833ed1b1805a3cb7a8fda3db1d2d034248234b27dad3dc4a02abacfdaf3ec423773fb357a75bdbf3766ccbb82f8d5e8ed16b5da8198938e394569cc23d79a4072b354e4cdd16415db8cb3ae5ed57dc92dc397ac73afd525fe02c7dbb4444adef0dbd7045844dbf54eccb6ce006d333ab7dc4942b3aaf61a96adf47131aa643a08beabc88166bc2a04a7164c23bf36d33246a4b493b69374861885b9075452fbba5f9a4dbe6173506a2ba33918e3dd04aa591159bba28bea84c94abc8cd09aad7c2e92b06e278fd2da20ab82e9cd1c348f0058afd7d7734b07c74f3a644648dcc1abde18bb7f4a0ebd5f0dcf18f4f2faf37fc7eaf174b84c7524600823a520bc32d498a68e281f0670a6b514f5aee8c248a068505dd29b029ca2adec44960352594910ecd3b8d033d9e80be3b3bda954adb842d8bb2e1260af852abaa6a802a35869f5d3421fe44e5c71b53a497f76a4267d73a4d5e9f13f976dafa3a834ac4c227a9e657d1cd10f81ca5e56573fc27e14649659a88664717130be2ddbfd4a82ae379433be8c8380282cdc5bdb43c70b4c1d6489d0c6927064e7b45c46f665df2cac9f0702a1cb46095b188381cbba0793e020b4dc482c576e743730e7539a98d5d508e2bef894778ef4a8c76b2a20934d646e9e19fb0bee57339a47e1f2e188183a9f22e66c964133d7421610063efeec360f9e506657cd22c5e18f05570b7b6f88f89cdd80496e01b12f24bc9133c421bfd8b654644916340c8070329b3008b86700fc390a10849d74f99abd8cc333ee688eadd32e98baff5cff6f45c7b349ecb49acefa9420d07300fb54100eada486eb75b24973f4c032e10f6882660903904f87e6f9c3706a69986ab9593a5fa4aa0eec3dbd7960cfc7cfca3ab32b435f53ba7d3e152522150dcbe62e3a8726ec7dfc10189c0fd5daa15b5b4ba2526de7831f8ef0dbc0889f85c48e1aad74c69dfc3363da0edd7098d992640836ecf0dd10eff2ac702213d14abc58277c47fb21d9ea676d6bd070ac8aca07f2e58f37c0f8629d8f26bff39ea549db90678ed5eb6380d005630451b97a7863f1a11df5efc84b24343e9cae58e6d35eb2fc76885007afbe447a2275c1cadd4dd4f60f6b58a1250ac376cb4edfd872e67249f24fc934cb3716a2545e5c0f31afd0fc2fe02925ae67c708303489ced85c3f13bc08722fed895bf2719e5c738f6e04a899dfec5d852cb12a0a9784907b83347c76b373ac4f75bbcb503ef2fd33f4a877a3e8ab7c4af54734e4bb440355a388a6a5019f288143bf1c00bfecd7debd4ba26f78da602482b175326ba7aea5e877a19d85224095008bf04fc4c056aff7c88b3e640873e4a42024d88e77680de2a25b8d1ba0847e78c125fac0e3017a1efa0fa9fcf6d14dcf7499c65409706a367efb56881f2b675f81321ee9372a051598b65b7eda23eb9da3b48aca503ecb3238f95d0efbf182b04f10046f5433c7d88c797b8750778f0400fb7e80a212fd5971dc7696d6aef60bc0521fa8c74bd543aca64238dba22e4733c444787f8bec45907f8e3ac7fd50b7d9478e5b6a5a2f5fbc9ace4e8fb670cdce9ba8dd0224c1895f8738ac43928516b5466a64790ffc0e35f1de0230a49284447990c3caaacd82c8268715c2f0dd55503fa1db4c0e1e3a7a117090428063a50a664e56cf8e076e67a26e2a493faa8009fbd5dbe51aff50461353afef4463962d89ef509ac00d65298e971cf2879f04ed4817ccbd84bfae5ba50ae69f265e5da0f233b51e32ab394b8684c4cf3142e7a820f8d21c1a3479e07745d50c856c85a85427d81c2570713feabc44b3ab833efb56c1a6ac0a35088fd1a70cfb219b5c49ba6b00b24827d930bd8a44a419cd9b8c359e3df95eaf1ff4ab57336eedb873d47a3ca2bced1f821bdab1865a85ee1733612887904891b00f94c3ae7a446390bc1b1f5f869875578abfd2ad341f790d06bf225d5d9387f8cffa5a005d88c6a916b647ea430c5a71da8fb6ab468e5e94e7fc2c4a61dbcdda14d7e09aea2f41d747d37c22f7dea11287ee2c159d7e908573a3af4fb26ceda01f66e23f1981e0d7dfdc7ac3a589da47e49a4e5ef12338d20d7aa115cb63a45e81c4cb59509dc287d045a99fc9823e13fff622c3fe04a7af00126f38beaefe074409d32faa41718f15f1efccad8e28c6ab9e83bc2f3a028912f9aee1d3c32578c08c5d277342945b811fadc63c2eae011a889f974f033c15e49b8203dc24be039abc3e42fbfc5a412a7c8fc7e6e8a1bc3aca619f1c41c503fd125382d0836b697615203b0e6b2c7880c888a79051e08e2ca82b6fccff71d2a69f09898203ca2bca3ff3644dc53a2b096e042a641ca4595eb50a51e3435df9e85fcefb8040cecde7109b7ff969478a2e4a4b0715a0e3824b6fab95cfaaadfc8274bdc03a4267be3dbfdc18d811ddc2f218722de25bae1c91065137edd1495ff8779591561f8114b7cbf311213469d04683955e23d8477692dfbeaf0ced6574ba9366ee0a91c9b9ddfe50930d50df45f1b4280156d793008038682dabdf7b60440bebef207ca1738e076771e469d79cff30d916d375fb3c5a9fe6edba5040225df066e6d7baa26bd710cfd38749a8381ef7d43e4a52423b0a1e340f15611a38459644291d5018cf53ab1659c9ca343fd8a3eb3a483f901bd4b4fbc90672677cbd7f771470a3365ca94c51accf8452d6144cecbefbe1ada74b56c5d8293b57e5aecea33adb38b8bc1dc9490e70532f4aa804edbae3373bd0a0a030755761171f7fba377baf63a167a1d562c980903116d400b34320c8687711f8a75d3ca5d70639125a70e711c43f4e5c4dd2409352e4f721bee08b0631eece14f2138487205736c3cdd46c38787ae5370bcdfbabe6ed7a5421b95bda188abd799ce6ec4be0759cbe83688450f7e1a33916c60d01029fe06e17ab37cd3c4487e800e3378a5294c571f6ab2020af18a837fbde99a0eb6cf44734b6f507ac2ab0fb07cfd67eaaa3c593d37b95422ee565aa47b496507291d89cc893159a446e8e8a713c9f06f0199db6edc62da25dae4e6334ec44312f118c744195c62f325b8b9193333294b4547d2b28d02ee694c3a9ab1ddda66f9f81c6946ad9c5f8e9ce1deb9b8251ba6d14d0ef223259179bbe6fe33ec79920c6d9433ae4166dab1656bda102074375e0c35fda7baa53bf8dea30eac0d45af6dbdd91a4a278e981e8c49d0e150ecb867c3be3948ee169899d61e466f5f80a7861484437c5ba1823a8e0d26dfae85e9d676ed2683a0ef5a8aaa7dd4bd6a72e41917e9c89bd9a0b830115c37bbfd80c2de0e0ae6510c102afcc962135b2dec901dc860546e9dc80e79342dc5118066f002908472461f3c5d66ff2fd4fae37f2683ded5a417f4b4ccdce114646210395e09dc06f985b526fecbeaa6ff5187da2e8651653ef8261d4ad95787b1173787f26c5ef46d8e93118163417b7f4976ebecfd7273c8a6ddd2ac242078c2965a873a6607626f0808ae2814da74e9486e67a6d280063566e360134ebe82a3ab5db5d2617e337ad942f985ee8fb705d91f42eea9a63a51a12920fe0daeeb0cad1b07c7ce9b66676e1e01f97d9265e7de357ce3531ecb8de3b6075c092b0db5ba706cf51fc46002ea89a5505c3012c24a076649d6a3e059d64c4f9e1e197bbaaa3ec587b77ea692677717512e5fdfb2b9f4b4ee953cc0b45c1d5765dc98000c00597408846113b005a29e9444b4210051f00ed5b798b0bd46c48778af908dec4df696524a99929401ee04e104f204940b2b90bb3ce773774e8eeb4c89a85dabacb25dddabaa96ea6404b9e7deb78ee3361e0d6e1fb8a3c11630ccccd030b3d65a6badb56ab56ad45e231503b97a5a76d73c1772f56a9e9335df4170db26c581020a068827c82571c7eb2795441d039880669924a7942d7be29873cefac508367982f16af50f82add60dd60661c56ad06d4a931a9096ab0b18ab1f35c6045e84b7d600991b5713244fcc011da05c1f1c70bc72b4bf5aa4f12e09b8277e00224f8f1e4e4e9e04bc7b572b4f9625c92a5e0cb6ab15c127c01c6bad922b0479ec5002adb5166c2d8001f1d2003b116b12115ce1ba6d0fa4b4daaeadb5d69bdaae8d02a3c028f0da1f519ef6bdf5422f0b71dcbd5164ed5a65955d6bad40b1a7bee2ccdd278cf348e8c9f3815c47cb610de3bc1871eca73c6f2153094b51aaa2d9b4146832c5f752583da25a39a56cd973ce39effbf406be5db1aa529bca3b62844b508fa01e413d82ecfdd5b6b55ab328abc7af2146326d3169e5e0e8096adad20a682bf6d45a6badb5de6bc1562b53211f85a6699aa6691a8bfb98eae9525df7d1449d1bb6c022df5779339eec52a0c91a4dd6baf33a6bcfd108ce9733cc804ad5f4cb961bb3d65a6bad0553b2d381b306e3bc1a5561f8c2d2d0859aa7c3b8948d3af31b3627115d225a6badb5d65e6c73c8b5b76dab75ab73dbea56b96f47e3f89599b560bc37f0237c73e335f3010a120ac21a3373fa1225269261b52bbc117a1020eb46adb58a69977c1967aea4793aa9a1be7c797a9a619cf55276f7fec296e5f9a1c766441d15c11995871cc1c2caa106a04224623225aa6910473faa37a4ea96fa94601cc1084e8e0b3363994c44ca19751040040ea5945909ca510b870fa11af5430813274b50a2644c36212a92b21d4141f0587ada82fc48ca0194032807508e1cf6db3ca0a41c37805adefaa3ea4509d32ce9e86886a48495a31991391b1c21081c76b7101d3d4619a5b70b017febae401dad1c1af1526badb5d67aa73079d86d160b04a7a4be2d3246d3a226880b203a2c5a98b6074a23630a484989d227d55e6dc71356aa9bc958489e5d04692890672af5456eeea28e8a489e958b3af43bae489e330450f886a9b9f42c4989c969c6a47483a419933d610c0e1b09098bb5503ec4e0eef50352ce9892d804c61e4da389a14387f62ced63815f8d19b6cde996974fbb7e85c3fb7aa93c1c150a101ac9f4722106b49cba2debd2b5d65a6badf284fa312a451639264002c99d1face5c2d463967474344352c2cad1acd65aab4c1271fcbd7881028a29a6f8b00c87d2c8884a8fd8d354068cbdece5f8319e002d173dc042bcd054e4b5d789a6e119c573cf6edb76ce3927f5e8aa79efd401052526987336e9232bb23ecad2525a7604da0f749c13a8c061775b585b6badb5d656a96f3f05d4a0d71490c0d188279c7234420750f95e9cd8d3f5c3a834800048171109fa0f893af90a4eec69223a82dbe2056b63ccc1122dc1063881b528d8c183282ee1b014f4eab67b5fe5755efd5651e76ada37e448ae600d9d154c58ad2801724d79b40b8164fab76d5b19747d2df2849627ecb4735c4dcdcd4d8e37801a841183d50db07972448065a854caf568b07cd478c0bdde1701fb9e04382fe509b1404db34b30d45ac10ab672c05a6b4da53e20a52d2fb7ffcdb7676975dbac7f974ed6fcdb48aa1d7a569456abd5daaab9265390d9fa74ca7af5ca3be7cb30033a422499de2f72b3dfa16db34a42b0c4e404253b32ca2245260333beb0738b17e10b3bbbf8d8352dde058d8f2a459dfefe5f010ee31325f344eea722d890f1e12aaf647c88f3ea657c78f34ac6afeec766c4f8b0b388f0b2fb89459d7e9ffee8f7d1127480c32e1a9301f0fd5d64f336ef7de1b5f9ff426cf333be7035635ce4df8bf16af50f82366427c217defc06002fe69b69e385538617b2728c198b853364b9f088c81a2fe4720b8f88cc21550a670ea952c8e5902a85ac1c52a5192ff42c116ac665c9fd292fe472536ffb6283443932e5ea838576c524282ad24aec915c54003561d1075e0ee3535c228be293110f483994474d3c40bd5e2f7fe11c97665872b8f21a5d6303d3a7cf39e79c73ce39e7acb5d63a5d065e2aadd48239b4d64a6fdebf568a6dcda1947a92526b6bb4b67a34dac0260c0deeb5f6beb5f6de7bafb5d65a6bf1bdd75a2b238ebdd7edc735f8442d6df9749df2efddaea5d6526aaf03b0dcafddcfa5ad96bb757777a7dd8f7bd95ab7b57aadd57d561ad0f941b81c3faea67b4e8eee9452fa855cf6201eeeed6830fe0c73353a353a6524817aa1fbb65d5d76b4ab6a3169bbc1a2353c38bcdffdc41002962f14ad64dfde67b5c2d8737250f6972f8d5422cac32c490d36c90854f7c9eb4ad34c0c4a15842e29c906381e703d53dd275696d0a108063d68c10f38b0410dae402145882641c062ff9dedd0c5053388589480468be204560575a625c592b86e83d795ab45d1841328982042cc0b5f9a9a76e081e6051fd0f0258928a00801ebd5afba1c9b7610c10e33ac6c13b3d60b6cf92afec0bef287721e50423f8ac49ab8bbdf2cb3d65a19e030fb09394e53100fe7f199c162e7136747483addbd1edd28a7942d7bcea79eb5564a2ba573cef91199b5523be7acf776d17fd89281e28e7fdcd1385a47b03eabd64c358f0811fb4476ea175965fae9a099b6871ad0a9158965790dae419334f50bb5d4dc34cf8c385c111fd42aba06494bd9dd14fb0f21eda23351a7ff9bc9fee0a4e15076276483ac179392b29d1a70288960924812399122155913094b83eed43c3e830243c65bdeddee2edb299416929456ef1079b6d72212d9e3f71c42bcde81ec4e9d2891fdc6b1ffb4620987144af6a7506e725a4aece97c2f95cdae4cbcce73ce39e79c0a88335aebc3ad9ea4b7731123ccba9656faaf59626d1344f866d65a6badd45e23e0648173b24016b86d330552d448a13b88aab5d61cdba35df5f399f2366d46b1d4d8da83e602c6eac70472f562e43057ef459e78ab695784c1ad32cf39a7cf39e7f576b4eb7e78644e6929ad37ac760e69445162cf9115599212931351bbee6f324aec897d2f639248c8e79d67e5f45904d206f98108cee73c199351a23cb1831049984c27512a25a3c41eeb05c78d1cee06a85dac5953c50e4cb02ee8c2eea7e3b6927fc77141e6c8c88adc12a3d2c4367b4e3965d3d8ad9af74e1b46004246e4a4634b4c4e50311cb277ac8994007f5c090e25193256b4ccc6f0708080949468f2540a29503f7c2dc6597ed82266d679743465528888644541382192c52726ac0a1c4a264c9a1cd5d4b5f57e33ea6c1fc16d4e497d3de04ea5c4d819605bfb6e1a0dcbc7bdf409140907a862cb8ccb0bc7ebb56d1f08beb00e58d230030ea352d0d320af11caaab5d2afa10bcf7ad6b3b60d4a9212939394524a2995fc372882143147875caec9379995e299f17c228eeaf3214684de5a6d68764dc2b471dfd95b6b174d98cf79313c8c269ae022874572b326639dc96ae5e459a62cf56d5f88b54fca9040cdd88ccd582c06552b5485aa50329fad563ebb71e693e9bbcb5ce6b249270fb15f6a913c9cc46995e491518ed31f5f64f9d4fd249fa2cdd6643c76a19c7a16d5515146b99d28b7162445a4724072832448ca442f38183194e573fd6e1bbbe0c4130739ce99a50d4d40c890fd0a01873738c836b20ba0091f209501a2074bd8a05de8010c141d644da8e800eba0eeee2622775393dc2c72777783373f958891e7c53f50c9fe2b2164a7b225fb0f4db2ffed7e1ce4b8161441c514263478e1cb9721a22380b862056178008417683b88c194f9ca21e7c392dc3ffbaf0f5c727f7d822904dde4e6e5244e0eb9fbd48307b237ddc0299122185d7f20f92b5f224cf68fbbc137593e78f3d2a869c6e45457cc2802cf124080a5a7c49c3308779f4d2f350bdf936e7800873b594cef586950ce321631443896a8f3399699191b7fb99361e43933133f1bff76a28edcc93d931d8b13111d0b1619d098f512234ee4d13e09a671fcef18ffacf0226e540145d471191575fc758e701781a9cc36f5e9c7238bc44346f9eb58c16ec5a9c8281b7b1c88a85325fbbb535915417325bbcd4e25eab88ca292fd25145146c51e79352ca366484556fdb0355bcd5302d32bc7ccfe3e50c0e4e397c8053669fdd64e13ae362bcc5c5f85996bfff7ce1238e6f83b4d3865b382fcfaf50342532e5dc6fa0d60069c5d39360951747586c0f32b010cbee955cbc71fa8f5721dccd0948f4fbb260f7edd4b57d8fbd138d40a095d28a5943ee745fa568cb8158994fae84b1670e0f01d3be8cf380629668d1491a152a8748ff62164dd474a29a5945efd1db6c3d12e0f47831e7311296304652cd6d2c891190e5f9952fa2cfc10eaf1f2016a9e08638a4f72b6fd20e304b3d4c58a9c9a3514928114991fe38e06e9c783d2203959bec799d3aad57f7a43907843a44f8394d62f941f06c98929ff5a6b7d9fae3d04853265aec8dc572f6ce59c1c0e1935f7b5909381c8af41b97e4172b2c6e55a670d65909cac7159fb6913c4e60b78ae9ff272f490e10026b02c9379c0d0bdea6bfd800c9162721199a7b8d0a9baeeebbe7af3ebbce88543b1da759eb7a341da43fe94ceeb4965d7f40fa0054fd92492d0e5fec826b2497dfa92a8d65a6bad9f67f739c9b6fb69d2202512124a09111283091c4a2e993e0d2513a72893dab5d42eed6d6c2c7885693ce2c958834a3cfb42da3524a4414a3f7bbb869e841aa44cda85a341fa3faf2170189fa0d06e973fa5af233e9a8520f1690a510e23191eacc8a18cf14c187da01d5442b50813777ac0f153ddeed1b3fcc223d2dd5531eac82955c66bc5742fc6abd53f08f6f6f3d11a29e5a4b266ca0f084d81befc42fbdbab7073f3f601e0853203e0250b9a8f82f1a576496a458d1fe17bd6bf27c2cfa87917dfe253956341029c0232054964820111cadce26bde8607838d079f47c63192e507e4029ea7b860e341efc810cc060f1b9f8d97defc6cc4b24f1b356fc38361283693113151f24292186cc9106c7a359e446af1492ca99f2bb0f62c94e01b06d9a8cf2853e68a5cf3d263ca211228aff95a884c391c3acaf30372f3b306fb280789737ac9f1e6b8d3836cf7973de7b4d141b3e7f98547322543c7449dfed782c32a65c62a95764d59bb1aa9c17e21600f083354a8c274d2e3d7f8efff45d841e63e093b0c9969bc7b2f3ed2f86a91cb56d1781aefd3744ceca1f1fe7484afc617ae58dff78538d778df17de5c13f6de5fc5fb31debff1de6f29351b1df7e9dfa79f4dfddbcfa307e7b8552318610a6c83dadd67a4e2c89b9098cc224ca74fa8f9c5079569c5b37c153ccb18b021124cb1058b1327b8324510c6304182301ce0014c0c49c88c467044822069690c12ec081202e4e08913ecc52339c01132e40006e3fbc80c1d628021b1e101ec088c4fa84de87ff1b1d0262800df9b5391b3dd4fa7e3bebfd5b84e01f57d34d842422c5ad4e47454922c5a7c21ae71fc3863fc31f2fcf8ee7eb0ac8594b1f8421a9a54d7753f34cf22f6a87273df3e854cb248caed7946d519b52b8c5145b34beea614cc3a085dd7e1a7c1342c884dd3bdcd8cea25976ee64ba1f34cf792a95db2e6895188316a576ca424dc74c54a96b0fe1955d7c4a57d911d21c98cbacf668599bb5761e68ef3663e86671314e35f7c8c7ff12cb4cba67b99596850f5dd8538772ede795e7cf760bb587cd7759dea83549e0fd587914b0f1d33afcd78aaef7e28a7ba54eabbd4174a1b1ddc77df7da1cd0a2894295326e3b7d1d18560eebe22d4c55754f3798b0f7fd2090d148c652f3e1b1ed871da014360186fc3038684bd789b0648d88b97b017dfea657c888760367f238393dd0f0623c6934c2e6592cc2c9a45325ec2b8b1f9e13c32bed507e3537d2fbaee87860cd8ba573b05dc18de108cf3629645d72b22637843b0d855bb94c48a6cdf01b229f678b63e6d841544794e16da1585da156de647d88ba7f39bb2fa0883f1d4a75fd17164ada3a125343c310412474a2ff0f1b37eeb984f1fe8e61a4c704ddf689940e0f0f5ba17e3d5eabfc396bfdfc8fe73c98bcebc0cc2caf4b7a65fd8d26b8f939d54c91939a3ea384e76522567a4fc1955c76d3faf68ef3e95f21b82429932da26372935edbf7bbbe7ab00afd813734ee215c55828a9c82ac23bb9bbb74da5cabd331375fafb55b97f015d62334945d68c196e1ef924e2f84b1c2e4ec4f127c0757739257beca9806c250d3a13196bd0bf841f60ff0fc00c3894312a4f3e2010af16232791f20519b2bf27e5d4929adfa38b943e847a74f1510196df1fe77b2bcf14e68cffeeffb47fda46072c7f4b2ab2c00e74bf0ff84683fdaf56834dbd9c0fcc03d002ca2f93b291cfe90c81e33b2b5a0008eaee0412344e292762f31c4c90d25254037f5db93795635395192cf970d2a0a813e7e7d3a39cdf93be1c27ba7dff42ff76a7ee4faf75f76feff6399d0775a278c6c6afb1fb7aff8d4ee7a4f369c7e8eefebdcf9e483958a34d93228ac9aac15ce472c8caad4991c35714295b9ea47c000c114274913d0993449826a26061cbca589517e4fecbd57046e42a66ac6c26bdb13a0d1b96f8aa0a0a7448514c69a4b4ae2aa5ef350dbafabd3d243d44bb8f646354b39ff82164b2a61bb63061419559d193097ab862c3079c9aa077368595b117704162c10a6a789ab243a988871ca06240c306727861e610838d0646e604953db15dd64acbb1a90a95a88b5bd01aa59d4d55a6e800cb7288339eabbf7885abcc906d8e4d5594e4104c928ad1e5d3bf2b6f7f9203581299af42cca9a813032c739822622fe61a3452e2c09455232d31e0c06484820ee4b8818cd10d4f72c8988c40d024070e454088b9f1c2d11b1343c05b8e4c3f48ca360abe3932fd000b93154d389137377d25b9e4dd0f954b344fcde5b7114a43cc8440922f5f0432af620a3250b88c4c2d7ff96422c63849f012de242ab08c32d6904ac50f5d2291650b64523c22b717c3a1ecc29ca9ee2679a4130b1832d99445e934533187f21513569aad8eb01194ec069704a8048d1a495a09cd0c00000000f3150000180c088482c17050302410a4cdf514800e698e3e6a5a3a1348025112043108621808429001c610408c31c0286488c61ca09c917301d80f7496547fc5e65996c1e8f014ec5f8e82d33961170e62825cbe57fafaf4abb07463e4810c39eb04b9497e6f277956a278b1c120fdc05aac2d1becbdf99243e6aa8743b00416fbea99cc2193e56f2904f0cc719a51ae96521768974fa6cef1e68bf7b3bf60ee2a5363ac93b826112c96e2d99db716a5ff556f19d1903af5b6e49a999975e5b8834b7364b86846ab7fc5045eb46a83a09c8a89e7e530d90bf33896c12bfc093c3a630b7fbb542336411ad8fecc6b4ef9675a296e665693566f1fc24b8a520addb75bc81f47aa314057ca3d65fe3393ec62e648763ff5f77ef7ee3d5d89e91e97dbc1911ff7ff0b098fc6c1053ac9a4d3fa120fbb47b567d80d096afef912a82f8f26d812c9d90c5b775b47b1d5157477756ff4571757fc682aefe749075c5326659cadf38310cc528c83fbc14349327995199de2145776cc498b84ea7f5171a42d7b5720530c3631912c0dd7804d7556dcf9c18a8c9a21f1b7ea78f07872ac57b69822f48c22d4ad6b4a8e9f7e8b8e94a1d7de44ea6f3ccb9bafe3a7d3eae94ebe0d826ddbd03c04de2e331d436dee7766dc9ba66711eeff1508272b7c13b403aba1d8acd1d04288231061a42e48f39750cd072f3db3d86cb5208c98375a09512905529074d2ce58b4d157a5dfdce10a09ab231c79091d5e8f2487487ac3d9ab1a588036379af2097a29632ff4513e89e92d471b04587b26cd3e724fb71bd3ce415edad7e4586e4c47c42989ad2cd1d54ccf45c5008cca5d81199fb77092ce9d99b98bd7c96dd771114765e3a6a04b1815575ae9d7baf30984ea28421da5e7b3f45a910ea906c9461d7b65ff972dc7e71a5ba7c10616b97857e0924cf64319d59205a89492e12b4d2615f8dfbf0be09f22db33447171380c3d8ae6de0d51455dc26aa64b0734886b96aa8f1306ae9a9b31aefb5974a74a80dfbe00cfc2f7fc81d5d8607b1cc28a70f0d437500e3f8589fd5e3218675f31a17348316e1543d04484b245efc97c1fe43004d8707b7a1f7c001775311adf57074929ef4d307ed34ce24965b50b2684141e5977b1264c560eaa3e16c284a8739b85ce6c1d0590eebee731fd1c3add9a3717b15970f38f65c65bd7822499f5900a872338bc1edf2242d0bec08cfd1e5b10d2ae868fdba9e3d5766ad074e2b5e42ad788cf2eb6b893eca2fc594ebd25a11cd1f84db830dc4ce1eda6d08ec94613e71e25a218975758f84c8692f0ec81e9e8b114cf7008d3ed27f1b3c9d7c5642cb0327600d0fb2a9e69ce1cbf2dae5432857284ec180b550a29f21224aff7a4b9bebf040e759b638f01a61778bf5f375ba10efcafd5c63d073a55d6618ffb96f0b9bb183708b0a21cb700699c98ced40acf48c91979668be11c123e9a54dc8c874e813ca66c6e71e0572427fe0bac61e4673613b25b50fa85dc354de1966030aebd93c96fc03243ccaaed71bbbaf0a57d4652712455071d0fddf0a111183aa7d0975d769583c1d521f7245b8e1f11da9a81ff6d022bdb552d438d3cbacf221be4d62bd9e68c61b93a19ed0793d51976280e828bd8b2c295c8b2446215b468460355cdf1da5ce52bd726cc340f4d4a564652a5c747338b2012a13e7e57ee939e0930a73c7e846d71df1f5ade663da30a7e5d5aea89f2736dd25e32a882bf6da3d1a88fed9abaf5cb0329094499c1c515daad81b2c91fa9b85839ec80efd8efa96bc7ed59e26b5734680033770bb666ffc3214885abd17a3d801f4c04a26fb0b34104d2cc4df87b5fabe38cf52068715c543d0439f47f089cf231783770388588e3028b358618c7c33455e0c6cd79cf49cca361798564bd0f7ffec75d650a80a07027293238d60e701693735a19b8e8bd8780d38e0e98d4742f7b3b572ca7f09c7ecfb62147f57833637a007d9883595dc62c265489577740c9b7875dcd79498e403483941693423b7cc3fb2e003a4cfbc3041537bae1d7eb21e3b341ad399fc8f83ad647bc21805e2c94ebb40b32934eafd61aaf4b534791b446519718d0ee5ea8b063787c3126535f12161fc112b6cc754909ef0c53e4b6ba132ea6c0e5e4aae5abbd8bb3456d7a45d6ab5a56a40f887e987b89101d06d3ba0b91c2b200cc0f4adc53555260d2e8f8636d8444b15e832a1c6a4c2b85ef3ba4888675251d578d72bb141dfe93216917cae092540db889381169033d9411425785b6ffad2e195a042594b7fc7c23f748627524037ab20b19669937a9fc784dbb68848b3e4271249c31da51ad15f733a4cef7701335235f6275c7fcb495f75516efe88fb93e825e33e742323b0568ecdb52b7e1b866c4d3da0caf2dfa2008e103060c93003730b24a379e756c84930e0fc39ca022d3102a275f44b6192b322d44cd8ab19cd2fb9cd2d4ebef4ee03f8f7a8f8c4342354074ba6119accdf1e66ff43fb80fce34f2ad88990d23825d6745a7872da341eaefcb375f5e82e89dc3813dde255381d2815877f267309671267c8b7d1819646bad4ce50feecd86fa1de176f843c3f09cddd2131df4de77dc20da8cf4476d3d5543993b03bc1ebe159f9b0f1bf47156e7408459c0408b3b815bf36141cbda19e33efd25ec843daa5545cdbbd5be21057720b94f2859ba4125e8a2faad083cfb6a3be488b7f6408c873debf64b5cd9c0a8fadb0054df46984212a5d6b20d2f0b049bfdfb266e9a331f2dc815a76283d0f9c5980504e5ded424aeed3ecd5ba7e693a0b203f286a49e768033350d789049042064f88adc4de650ea909e26412667a08d677ec516e8ad513ac45c528413dd123e2e13798dfac4c03f4162c1ad4cb121dc5c3fa29988682801f0acc7f5399248865374eb1c8140b9c88e0fec8c41df1cbf8b655fd61e790ccd2f7d04f00da61a990ace1e154f78586c32d06dfe5aa6f6447ee37dd32f7a8dd16dfaf82d1383ba6ea82d6d93bb768850da3afe3eb711096a55a60cd95ee5f3e13c185ba979693ac4e3ab496f96fa1a17d8170fd73fc7a4210df74bfe677714512c98a3329560821d0dd32c4c314910991fd13bee6b56c442f8d7fc13fc9a1860f0dc10d694a1c23118c4d372aa987eaf01e2b96a787a5b75e6f46927cff331e25afd70e95792bfaa2075667121ba652559da47ab4ac0f78438f4b00017b6b7da7e8489359337b3a09681d94868b1141988973d5f6f3e03dfdd259e22a6752fbbe72b70088d689ed6283c7b208b6db6ec074b6dc408b19ccd8592ad7c9fb162c3ab1f17cff355add75c1eb577e5cf817ca996cf25f8fd0906eab4673de6f23cb30267ebece4beabbe2452cc916b8461972ef6f863321d6087ca2fa4709bf219f3223e13172ec4a410fc84245b882cc70cd1f969387e4c78ed19b2f1f588b318f7e794a0321c2a4127982c988564060c872832a7c9c3baf5488647cf431c84e1ef8b992667cea04108f95d70786542831805858e6a9c12e4069dc629ad52a068015386bdbba812abcdf85f999064fea7743aba0288720835ddbb2e10917fce7535a03ac18d6fb90fb21c76f8be100f03a285e552e969a9e5781aa95c362c57fc2dc54c3cef0712294ddab49010d0a6be9c6b1e383f8adb0b901f06503261ac6c7fad1b4ccfe75660d166bbc1beb63e56b5c95cacc8a2997101d3acc4434a029c697390e605fbfa2ce88834487a9eeeafce794334d7edf04273ffe922ed56e570b43d8b8dee6743d927e69bab3438016e1ef69e179dcd71b8162d410b094947ff02a729759f07bd519b095ca975aa51663695d12896483ce44a836f1a0e89a4643c514d5f60f4e3a75f21280bc77af18e52fbe0b96bcbe1f82ae7ea9d764a4562f9887373a03efa5386ee07b00a28262446b36ff8e075074852715ca138aea023b0fc4a6da827fee203d1ed03894a63702567f8562fa33308f5293eff23651ce229c3e7a6dbb6a330b4e69a38dc5f104adda60a59abfa10da002f9700c97a8975a6eb5d7f5542484080a01b9591134376fbffc2093741e78e444d6633778232d520d8178b3b37f5e1c3d7211a4609497bc05bcfdd2754a110d76377a1ae279a11096747d1aced5801392029fd3652a35e13c9fb1341325caac97c548994bfe92709b0ae6d676bdb01efcb223c8b767bcd515c2f3d60ffcd79d0664d0f8682f03c3e51b765d679e4798165f7f40fea52ceb9aa62ef5b732cf6ddf25f2b772c4893e7bf1aba7286e750e100037e00a0446e61cbad914387ee7c107a3b5089eead3baee95a428170fa004214356402721cb9f034fb6c56eaef47aef486e5ca283673c8d4a05517e06d2d310119dbd963163982c846a7c0cc2e466bfbc8bf9270c5e2afc4dc766ae8aa22722364296e139081c320e3e83c101ba83a8e7a9e93d39afc1f7323899472473545108d93a45cf3d3c028e9aed5e2b3a740b97c8a4f6f6fa74c0ab9fb5e10f44b5b7cbb09b731ce442870256e90d9f128484fb1df5edd067947330fbe48cae595c8e55e243bc032bf55e4a02bd1264a25a1a69c043ed606c4cb1603de2014aa70e06a53df928d521daa8f2b21a7cd8966d80456fd6be1df80117fe8151a70c69e22848b5185d54e00c61001adc5261a5c731f5f00039c3810d0e1eccfcaa890e34d6bcae99501b5b0baed6913ed1bdb9e470790ee92976c2101c460b340f8caa2f7ed3fefe06b30a2355b3942cab7d9beb6739d1b38b5c9b008b53dd8bca1c6b37538013346a0695a09bf10a4c47c25b152a9ddac9f56c9947e4b70585d9b6bee54ab113845f9c5f5d61ca87791cb51dd42543524c9d5201b8ce1602af6de90ae74f3fd7e72b6f1272e65aca737c37884b46da67fb1d07bc8daa3bd1143ce0721edb2327ad35f6fc7aaffc2b19e24d65a625163207f0ede4cc38dc8860466dfdc873fb38370f6b85b418fccc7fcc96e54e665429a861608bd924d4baca9e9997021ccf135ee9419a37a970473ec8f6e4a855a635acfc7486c5f4c83c49bc7f2c02ff187c7572339dcf0d2eddde450361a95414865fbc44568a2e256540ede6ba8051d5e69fe9e2a641e1e6b371e84c9098e611acd3ab96fb379e84716715c7afbe1f10c6585b60d2f69e7e3e13eddd23c7a0ce54909135377188a4092522325c8eb473f7ac1d4877ef09d2900832c7c95ed5355d20492411240aa4826d47f23c8a20edd1b53bdb532c085216ec5d7009abdd2282351785a282523d17aaa7803c48100303e40291b24f9bdec93f1561c4fb9d131a7bf46c6c1770e01a4b750fff4c800d699e0c42ffbf4331bd18d4b2ef7800368fdbc03a01e7cec27af3bb42fc1174bbe26a542e6464651a093b69155f937797f820812de01a16da955a4f825b1cfadb0497e518d1937d4a05873028ef9bd4031ea1d64a4a1afcef19d7bb71fea19de2907bcb866a04de77d05d218d16556b626c74f4de6ab91869eaad0cf290db2ae1118a844dd7836a76caa804aed35757fbae07b872448ba8154489a9109be5b5bc00bd711be978f795dbd9d0f6666bfb0f315984d7a577c28872ba2e88585e639cb9e4cd0e13be790922607383bba5de6aafed4fe1ba7751522732386bf6c15843f0e1d0e81597dfc2368b2f538cd7918597d9ac2be6c8c0fa2a8f4fb8f0788a7ae3bb6fe255fb5158a85fa6f4b0ff00a94ed2d10241023dcffd23475bec86ec8453ee27d8c3068c227e68af055acbe11d1fa166a2a7a57d448f7dda4efa4429af5c6c39df0225d3c0349cec0fa10c554925af59967cb13526af3633c8f38feda1072f5d2a7fc36fcc6e597f4c9eab9070326705e7f24499916092b1fd5b9ae061e2a27b209d8612d923e12aa99e331765307bfa03701b421b8aac2ec4abc340d7e84ddb2b854ed79b548ae56bf0c67e8de628674cc4e46fbe5c38c76dc1cedb44ae5a007cc2165a912540b85d64b2fd23511fc596ca66fa6a067d7837036d4ae6eea5ef84fd8f16bd714bba84cc719b7600105d782929176a0c18011ef54729ba7e3d5fdcc262707021cc3fce4bd661bc0d4a84fe4b9ae97417c27f1ed8f61836080ecb3f3170f551ab948f4d92bb27fb91b080c15adc76fb415c2ec478394a2e083aa8803eacf5e7a4668c2f0f202657d1308c16453b5186e6e73d84d790844a13c4705a6bfe23db667c272570548409193d7b40e2b29e0ec0d87f23b960fbe02e8f2e12088f505c9ceebe2001cbef17fea54b77285dcadddf1d336d817e30880dddfa407e40c9f78d17a870dd28c0afb8cee3f6b4284dfbe84e21af30b5dd8b71908cb027325611d0aababee3592e8b76b28b689d5c1679880594c92f2a5d789e4d9519b89b06ca7e414793828a9ab52fdee8e22d3c3fa6501e54a88f3b3593dc1c153e7e9bf829e0cfb39842576272b942aed8c6fc846c06a4aaa7e40b7129c2fee92fd099aa0f8ff7edeb81d0b8d58ed9df6615373b482722fea658262ca0e24888106b0d3b6aac036d52e4f425385c3b3eddc0e7a7f464bfc67e39b6c07612be7ded270d28d3d3701f5f9d38a6e0663f98386b2dd05f48a82c775b130613c090304d078966622ae547812dbb88105bc50e69f57b5a781f04a3b023ec9c7dbbb0856a0d654525fd754e40004efa779d1cab56b23a2142852456c81d7310ee4e7a834687f2402cdb647e282204c5c670c38d527cb44b2e11feac5e4c9880c11b1d04c9c31261bf37a9b4daec38fb32179db7d38a9a87f37918950f59b863ce8741f756a441951193822b44d904a27118b8de2fb16a37be194fb08f7823fbc17adb596340e77f250d5bd59d4043d40410cc33499ee1714944e6f91b21f4beacd1201af961cdf44c297954c47f13b470ff6b889b499c7ebe172e5b570ed03fe5c0c2a9eb3d66f3448b74301e5f6edff2000104d9752304edb5758f30e79a7828702548a3884e5684d80719ca2bc766edf3c1301b4a7a69dc6792a37b113d4c24315bb6fe5ecd8d5392ded88903864f855d4168ba7554bc8be4a3cfa1c2695f2d21c1d0c3517fce04b99263ab3a124e9cbba3cc7b80a7dd025a0cc3beb413f1a403bed8a5119a384dcc0d2ff6ecddad59812edc8bbb23c61b471ef591cb11a9d3d21f15f30850236b8c70937ae556e2257a18c8e0dc4ed37b723c42aa626a2f1a32c3b5453c8c7ca5ae6ec6e51476ebfc974c98fa52db54a5ccb51c7c0994e02b37db35ba1b0271b3fad9f22d462bd0641a9b5263abe41a175214e30dc79405d68ab125328ae8a765b3516c7c270cd2fe02695b6a73bf5802c88786c20854596dd7bf9095e14c28bdd941b7e1eb392767a7274ddb9f073513ee4191ec59a14747eaa5bf8becb8f57694ae304c4ec588e3f6d421c3d530ad45111feb5a0fbabc54e4eb701481ff2a4f6928516620caaa5427ee2a981188f8a2275c181d54f99f138922c4106a1dcb6a211b710be73a546caeb9f30335232f978b4eb623e2419c64f1288dfc7686ddd641d3c11db8707e27e08050bdd878b092eff67adaf3381ed2723aacb549979e5523b207e28a1bf3293bb6a627dce25a245214978c3295f13891e32bce79096568f0b330ff3eb53ae6c24b7f0fc0168eca5784325729a6a88855b890ae2075f455101285ac207aa40ead9ca4a7c249cd3c7f6caa6a41e3796fc7a23641251349ac90ed2fc603c1fd67d04ef952166f471d805e45104fd4ae9476d79dc29ab6c92226e1ea8e65dedab8d80cee63913f8a560453de7f841b82873ba4f3328f0ab91d5c16080f52989e224aa3c2b4279528da34809d927149ff50ce3f3df3f1c3fa563dcab1441b0285afc629b50a06205be91331e5d45adec572c39c180a8fcfbe6758430460057ac005425469312228c54f0b21d4e76aaa2e7446ce6b538d02b9b60c7db5026ee1901384851630b761195e35016d1ae07806495ebfc6b1acfaa17d63b6f127c43f3cc0c6802491edfd11584aa7e6c8510277ecc3980a918025c24b822fe5aadafea996497e8bf08984a1ac91501e92605e7ddd5f7936cb7c9d98276162bb792096ec4dc58d0018de0f9d979f9ee29c6e159ddabc8d9034518724e970ee9ac88ebac1007d1897e5e6a341bf14b36074c1619d31e9ce89b429aa1ca862fe70450da442d3aa132c9dbdce2da5d858f34c4f9784219b7600286605101dfb1b3dff8288539470ac5ffcb838710c3bc8d2da4d523ca12c39b12f884ceae12af475a943ce75aac2e5a8dd31c390e21cf1222494333795b460a1ff660a2426cfcbf3903973bed7aa0961e5c997587312751a0c25460ee13239efa7aa9b12b051812c166e659dae990bb40b00eaae0586c95479deb8779129019c1ebca31114a3244d761493caf040ea0d5fd066f3fbe38e60813bd57663ccf9562a203b44364e005116af00b1085915544644ef98c61e6458357263d7683258d83f4bbefc2afa080cbc5862e89a87ed5ca846ce9cb7595a88b2c887c6059b606e63859778c0777c92bc82cf470ec7cc5458834f462c2e77ca940c81c35e5bb8ed9000adf11193aeb1942cfec4983078d38f0d2d7468425acc05eefd28220ab9c3c1ba2a551c3fe19157e8d8bc1b0513fa1d8a793970ff701d1c8834d1f6c4c674027c60c96c626f26295923ca46292e7397e93b02a8532753f48c2955727c68dfdc14b81839f5d534874576d43aea83f0ad010e6a1b0444f382aa59c11869e1759a66310fdc16c335612c1f8343fd37e7e6dac90a75061bcc5794367cee3ecc1babf91b99580110127554cc3a78ab01dd0d2102c1cbf1607fbd690412d04fbae196463a9a57179c5ea4c0472bf9cdc74750dd8067b6ce7fe796baf8c050bd8180b1b66c5d6fdd8f448d98ab8d97c8716bbb36daf0ec3bc273b0dd183e1ee94b019ba1124a5e99d72fd4553c7077516413d8926d0112946232f34aad057bb76e54ff748d6cb7d8d37f6d1461d3ad3d94744ff1b5a7da7283a89d83c08d86ffbed21a5cec1ae661234afe8e258f9b699830d99cbc3f04026957d834257290463ca9ced2fc4e51792d6e01b1af7b5da8e5c752581f10f045944573ad4a382a6109a1b0cbde6e166a7cb96469470c254a40357e6744a71f14891820cdd00f92fcf1974b2a36fbd64c1549c08a3eb01ad306cd83c7275ce5e7921d796f64f75ca0d2187744284e1f7f7581485cf7ece163b79fadc0ddb064de7b0b59fb0975ff36689ffba9a83f63fc1fb4501726fad79512d68d90606ecd50d7b8a22c358dbefd93874000b6546e0142cdd0b5cc7fbc17fb2f562f13c62b707f17e9b55b7b70578999ee4b1beb09762fe43c8a1ccba1ed73f84570d5d30206107520865e2ff11081f16cf66eafe07886373b297041bb3d2068ecbe1753c11f4668554780257dfc7a60852faf9b0cf4d3dd0641c5d79d25581f76b80d9f618a546e1b2cdc47b5b2fd212c7ec80bb3142917de7edc8e7342010a19f1d810c116c06088907b70a88918ae660680fe558df1f4c6cdc46c6de131c9a7ab176f508b4ee73c2160417f9f68cb72f2e6924410f6bcff8f465a07d8d3348338942d3bebec74cd56e5fc65e08fe59b3e515d1d8f7631ba6bcc367ab81fcfb86984c5134e070c4f925988e030004249fe77d3b06a3f52f2e0427c4a4cde47c99ad1f70d128c2fb78b97601889c0471996c16f3f1d798a38c9f2db4100d3f9f668a3c9c722cca03ddeff2c9f0196b8796bfcaa9c6ab45b419e99f82814e14ca528bbda90f8e7e900679d68dec197a90a652140c1a5648c3b00160466a50a77c7a7f13f6fa64a925399a382ae5c793ff4f94df8640513dfeb767b442dbf8b8a32e77a20fa2d9349a3484d1ddabf49c873d5d90951a17061880be83ffed6e4d5c2a7d356a1b80698dc99e4aa90b3870ffc2fecebf2ba37300d0b2517762b177f917980cd9a909f2dfcf4215170ca186e60de5fed2003fb09af974f3c41dfad752a2edefc28dfe452734e42e11cd7cfad826622e183eac8538b54cf1d0b3df074d2781a35dd8649aa5ceff37ac857f3479893439ec98d802d181c174aa946fb9c86c6c70d131f9531ff76fb920affc8d3104a33c7aa7762fafb539d08235e75e989bbe1ef91d59c645f34215b02e631f91ee1989af9f053fdd8155560a82e9510250f9d9d579e6ae68bc072026f7aef04385d17843a19b86a415c45982d7939fd57626bc8f361a98a83c8251c3a8037b9abd42aa670bc4f30b1bcaed9d06934118f5b85fdaa44a630785c644c95fabc3384b7b021d2f0cfa1e4439620624ee1b036dc535adb75ab857d056bb80749119846e0344f4eacb325a097f6831cb7dae2e9a2a041d6d657ae0cf013a481f0eaeb3539b07d881687b62f7c6b6b8f0ddc892ad7af14160b04a639f7ac7dbb8f480533af425e5b18c7e2ded0a131c818840e1c7593c3cf3e3e836103fe8faa9efae51b4c542b9ca81bad4809f2ce6bfd25f5f43b4f627e7125651c6272d040d5bf5afb62797396f0401ed31710d36d8b11b4b251bd7b20d2b118d4dd3e36d5745cbf7afd4d9aab0e73c31438ee9d8ad5def4da33bae2ab577bfa1f911d7a14bfb0dea9d562be7ad06f1f3423a21b341b1fb40295c07bad2bd42662ce4eb4c2182648dac36adea744c1662165b8753ea20195eb799a9176e140dc71f35fae1ce3d4035630c70864fd7daaab81dc87e79728401fb8b5c01cfcbd617d472d67b1abb0db41d6a6835a2048e6e8436d1b80b435c614cec873b21d9fa66fece3fac468801a82f0fd2487494cee976f0030f21b0848b2df3cbb29e1b0d1a25e679903c097d18c1120085aac262092b1d8409f427e0172884c3ca1033ee1ca8a03981745cc0b34622b24e2fa997700bc90be701b16930512545915618a29184b17e296419df6dce16938ec43798f0c0969b9c3e4ccb61be5788706d7cfe642328d35876307d2d21b2d17672e9152417e1beaa7ffb50c4e3b554e507d9412987015e289677f6612d6f1823aa72e3fbdf5d1d60d5f7181aee4da9c6cfac008e57f40005e8895378b74f09c8a4a1b3e59db6bb96ab63747e08346714b75a045a1301d2c5fa8be85f5feff1634c823181257d49055a564430e7cd3450f059910602b03705195605c54b4aa6ac1a1278e6083fdef02b616abe64f182e58067b87b8ec169e8cf565a73d3528b8599a6234e86484d65fbd7f3c33d51354a245753058e8fa3a8c548dd56f080361e52667e9a543402dbf2edaa0f93202982118f08fb80b926320b079f193fe8271740f0b3762d3fa47c67aa246bbdcdb1c2adffc1adeac89008ecf7d55600c1828809284dbb646ba2d16726795280679a537cfbdb62fed6d43d298a62d43e1b24850527be680a0e924fe454e63375a9feb31cc30e7353a9e1d53c16097a27e7dec936683f72e9c7dcd8490d98cfbda6662204423727278dbb330b8856cb1e120db75fc3b7b1515c7ff393cc7888b9349b7996f50c86d3c683c950640f95508af8ef919c893adce339cac4132530e20e9c0a5482d6ec02f1c89fcc38041096a1c26bc349e04da4181280c1c7e3caeba86b0fb7f6e206b4fe99d609af04ea228feeea906d86a7a2c5fbbac8981618fe59ab35313f16b3db296f619e749e89fd2339488a0b4f0cb07dc00612a5b65e596a6b41d6450e67a3370aae671ed12bad11acdc56ba38860e661c09c732967dcb9ea9f32341aca45cee0e89f4e71eae8f7425af5e6b92f89c578cf10721fa3dca59f04590f79d5b09d5fd88e5329588e50bf03a6ad1183c6ebc9a847d1ff9f5b44c98e6a80a0e8a5c5c103cc633cc3220459569d31ad835cde37a286687945173b688ac003fa4e666f23c299525b44b0a82c6853e51f68800a0d4a12a6b3b6436022866afe37a9e225ee9df9539c946b86528997ae910b1a8fc99a3c8e331de9d6a0ef088869583f26be07106bd074b3f5abfbe1746ae8d4660b492f6d82179fc9b47ae833f09902a182dd64a15dde64d00fc7ed07efbd03f57840200203eca03454bdc35e8196aa3fc2be778743142b0d0d9833c0a6831862f4af79efcfd93b7393a070886f21affae1b2c7ce28d3b8bce26f5b4699c8250dee076392962ebe80fe06a761838c76e7370ab23d0b97d15ff6c70a29b44683dacf82ee3de3677041022041db1b1cd5b4480d48cb615f87b3b6b8f835b9904e2416a9f71d6bb061b675b15d50539a44adb1e1a6b1fe29b942c3695cfdff11562b4ac4738d81ee3a9a448d435016594c4b1c7ac64c66d1d5e76f32fdab51765c1f0fb3627a93a5dcb02eeda86b65c619e41077475ca4f01db1320ae5fc9b12def2366bafbcdad733c12dd8976a90020218e64ff5a06078e07462d543f9bb18e788c1c726c17e78ac21eb4942d0be4346350edca7ea8a1454b7a4cc9ca85ed68ae9a49409fd8f6c72be4919b099caa4858398e50825404882fa1b2c6b66cf91cdcb5becea1fe08b368a8afb4e5dc8a299718e70a32b96160a507b7876195e3ccf6b41f560f148e112a57374a4f6d0583d16e419bae4634e7e4b5e09570794c11db5491f73fe4ba537f4984f4294f066e765e9e3e9bc9b3482eec8737d9aaa13bfee9097b1c97d0c850d20ea256f3f54803416800e14e9180f5def17fc09cc160dd2cfde2d3a348b1e01a984de7925270ccba6ab4f8834a1c01b8bea2071ee8e8b9becdbd872cd765aa5ec95058b41e05f416a4a421ccc43f5cf8f6f0f99bac5edf33e18f68a2d0e0c936c024ed50007a4c380e40861353cfa304010f926ddaa528dcfb821b27b892bd6ebe09f98bd2101d4ecac344dfc69bc5214b519c339f96882d8876478b29c2f6ac03e208477bd78e04ba9260d51be6460a2a75471b92a149ea3cd174989bfdc55b4c7db1bd4462d645c2762085bec0eee5e2e3eb9c9d4933b97993bba0af7846f7bbea179e0bb24726e3ef2cba6a4196d671b2c08ebddbd4efb4a2b63d52ced242ae06e05a5947681c5da0ea9b00de19c25cc8516c2736922114d2b7ee8bd7e7be61d9015dc72f38b2c6131cbc66615e22cc16367ef111004d149a2f1d14283101c214962551fcc322f777e927cc4a57a46ecc6547b184a4510b8b5aa4c886964c654ab4a1608fe32948cf863d71803f106405aa0d00af89b09d6b2be5f49814de3bb6e3353cf79340177ab3d19c0e386326bb41507297c5d3b825d28ccdc96d38b2ee8ef2111a40a6d8c44a91dfeb4f5dc064f58b2a78377cd8dd3b131763cd3e002e25148eed8b83724818b07eeb7a61cd667978239813d8ed3e8396125b8f12c539852f6d79adf29966055f14951e22c59a0f61347bbca4ff472ebdb680079abb14b6b9d4f774cf2c8e4b791d5b4c9900a2e0ad1000191c8dca90f98d86968d18d040286d445a2cc5d9eab413421a7d3c4324fa50b37375f45b5130102442e39f461ce2f80825cfb14133cdec4e4a5adc0cbb83bfcd888414fe60a818fa86aeb7221fe334e99ab4612099f774bd8f3e4caead15f431089d62a466b030326f2383baf0257d49b72a41a1510769369aa56bf49eec61e1e2cce8290571c71327bcdff54def1e6ca63efb98660d4dc67ad64277c5112e59e395a423081cbaa538de056ce7db60c4b758b88b7a17c6422d3fdf1c831900e49fae32614e4889ea0d498488d527233fd8f27f39ae3e5e57cd968cfeb67d2c99b1a1b18096c91f53b13bd3051bc4b8c348f50169dc5d1be800154cd2cd6765e9205da78af10a3cf0263fbe518d788fc8707e8d77081591c714fa78e1867ab1fea83a30177fa9f8efb8ee219ca4b047da0a38947ad2004adae87347839b393a84d60a97978e12e9e58a4724b75582e539049ff4d8765c8d70a423aee30c4de1c780ac41d3a6bc3eae97da10b6e4857989a90f8083b592b59b452163877493aa532795b10a6080d11668691084e2619764ecfacebf383371e430b5e5ac3ee008171d34d9f72b37ad9f9571c66893dafbcc8c0d929fec9a57bc4a9951e1d0574b85ac14f7958f0a4d40a735a21b90317ce2cdb6c056e4dcb5299449ee1b2746aea915f15ab27a784ddffab756f7f4493d949eeab1444cc6d25bc1d5687ab5eafe15a957be0417c6aa57c8ae18b1cf0d5899acafd61302d13ec7adb1870c99d4ae00c61cb348f3d57b2a00ca1931cf2e75b41d6c6e49d6d933356157a07854d76e557ac0582f632ebd5bb5d2dffd0db9b58e229d9439e7b63dba426abc70e9df1f33e9b871cb0c8ff32860265b74ea89348de2982c0e4c871dbf92c1dcc226a3c081900f03eace60a8adb4727c93d033caf57ef9a50c93b17657814c16dc994510f8b890252101f6a4292854829fc4d2f0505073e7c154da792f555b09312b994d4894b322bbd8bd3b26923e78df768776b753819672378d12a297646aedc58c3a7d205073d2e3651e473d6ca5cfd3e3c6075f14223d7b3bd0b5e9095357d2bad1f8c02e6109e1a28fc3874eece1b3338db7f836eae16df7ae2ffe387e8844d6f926cae76098eb80adbbb0edb763003a0defd710a2270ea5f1417950cdbb81683167aba57216650ebb2cc7c8ea7f233d36fbb233d38bb36926f2a21c99278f56fd9378914f78302cca80f71af2eac431eb5737802f5498087092029f78c90a77e8bf4995a0d99dfdd8f4ac7ac16ba34b2d7156882296165cee0ba40adf1cba069d442d12f12a3dbe48bcdbe88d131cac538982b141820f71e620a12399e771af284b6bc8718d56c9a52bdb0d6c28c5815e1dc81a5dccb1490218dcd10fa3b5d2daf25f596804ce33c72bf9b718bede8b415fd4500dd9977c95af685c0487ded39723099d3fc772f6180d47b387cf3f7dacc2c7abe72d48b9bded90ce5141b96262b1c96996eb525362597eea501c9508b1c25e965bf1124813e578a2e6c0f385bb03e07922df28c5c03a964d74637f18ba137cebc13364405e436f3b2c401dd8466555abf32e0d6c5ce90d317ee10adc35cc9008853f98ce1c28633db6b414e2e418664e731175ce801faf33962a2d370981d22c3721320d02d60f54fc5a2a890e06e8cef8f6a775a8013f3f44d0a9e16856ff37e149eead85e8502287df627e7a2f16b95442664c4dfd50608b9a6aeaa440a0cb3c8118c3c88a38494dd27599b3a1eb059f49b59bb998c371de82207c4bda53f139581d68749d00123283bc4520f8ac530732bc66675e622a604ed5828547ef0e2111599074bc189e4706df6a98c50025059cefbc507986880857eb5ce4c48ae5894748295ceebe396cfee0856231803230f882c2cfae3c3779541f6eff38f00debde01b8900aae4a95a234654e24bf0a884ddf5eaba44b0faedf27dea9684d13b0e61c83507cb9b60629967e3d791f8889fd479fa18201015c85405c7582a4e37359696af941887ce5a462fb13157f126a6900547e890170d7c3193a0cd935493e04a45194578bcc9bb62a719091d95431e950d407859d924e00f5cfeb98a450095398e3aca922c09a147f8abd9d220c54e6960271d57883d18b15c8626e867bd45ed46e8bc36623b7d6fa7f82bedc2d7e7280b95d3209d33d19ed93f1f29cc71cd29f026c6e3fe0538688a2081410890b5a8ec4cde7272369a4688e53af946f2e76aca4b4422f0bcd8008f5750cb8e0fbbb2292a7581b5f94664e5061e83e3a8b928e01ea095f1505b042f8a6205e1c3ee95ae7bba813804ef08877e6a548b032e5b81731207eef558fa0e1f70c66597df861e12a53e52c2340c169ea59c5d371811fb24a390c25d14f531f2d82c55efb4973532e68c25bee1aded3835eaceb4cf42e08994f99c865fcb3ad5e68e456d776a19b33a2c7c7e2069a469eb76c5c8e43d1065d50526de282fc3d655e31c517ea6159dbaa5e831a75deeb914fca7ab9383a4ced678e574e5500b8be6874733e8a9110738c537255722619cf3070e239a5b3cad30be6e30916f9cd084506faddb188330810c45b043c014682588b9373ed5d84260646d5644aaa2fbed7765259e25e51e58044bf774251b5ea79bf1a203218b1a5830b4f02a0a3fd0bb49a65966c95732743785d3a124cdd43ce545510f8fb0093fc059e14094941ca2d3b1e50a7d9cd3620a5624e4843b4b0947ae66b680806c2edbc26327653edf4cb410e0e5722173afd2769a76c811559698ac4396ee7e3c6a702d4f190170fe9737c52a1fc29764f6e04a738b7bee733bb8de34d5241471a70df8ab5ef158ece745324fddcb171003eafa520b38081d2953e86865f4bd28986e900a199abe9eca66285b03c5d238f8c232656c8b0e1dfc3e07f28da6b85551422512729838c3b0265a556027d1be44b01407f265a61105daed6101ec4df189124fce4ebecb2203670c1813090d7abfdfb543e2af39f20e35e3e0a7e5d8bd4ef71faa3f7e78b8571bbe78f9ca9e42c788392d8197dbf467a71a8d51938a0c07f972949a2232d104d878a3420ac9414cc4c7e9bfdd71779cb1c5e80d966b458f4f58c0dd0ab4ee1c6d07701c86302bf60920df7717db2cae1d41bd5dea32e5e09b0147c42ed08675a3ec17911895bbb80c63006ec875d89e6601d9bb301cd65a2e1bf7185c1f1f525dbe07966378182b6b009062b48110085e140ada2cf7ba14e8a3e66f9eb7b4f5d54b24a083e3a556bfb62923c5419098361332b73a15a01958639f9b8ba4090ddf852027898c83644dd08657b106ae231fc89d24b4238280ab3222c7aa240223bb6465e0375bc5010cd56326d7136f27e4da977a9ba28306176b28ce8a84a721833e0367194574e9cb4ce8a0c8b5e6c3814bf87e10c0fe4ee901884d27525f19c0466bf11792cf0cccd75a462e492921cc3e03d3744b6ee1db7a7ae26041c7c5d08517ccfe6feca335b42b43ec24a18e1f2b2920052437237d42529ad8a0f7c95eab1511ed294f3579f2447ebe6c6fcc9498da6b5e2a858314e93e74d77c3d09bf5195b6b04475194001afd78341478b245d7feea9634e04fbc337c87f307d1551275b495b5afb6f789e7c9772e279ecab4ddc7d1377499bcb1e63f76e55f9d7306a4b9d267233e156057410accb5941881b727be66732eab42cc53650a35ae2a5381ed2a5334e59fbce10a6a03722f8af4aec1345075661c87870f9f5bc27e0caf0307749f3af8b041a84fa117380137fa6bfc183da3acada5d308813a20a017ccf5cbb7071bfe2c8f19c723c563a3475af6fbc55b3fe44b04010d63091e954dabf51d193b45e45a2b57f3c246eb02add24868a3b4e08252ca4dece66e6406079215614eb627113027782aa8daca3098ec2e729b44b41516cfb24763f6af553b01d27f1b4ab1ff936968ec284814f362261bbe73d9209a7e2c39a9280b211b0e147b98afcd89c97a581ab5f1eacc699ea264aa14c165d67801781cba80ebd002d211ae55415e6981801a0cd14abb4d1c64ae55c2219456788d2dffe957c354e32fc6d65a5d3137d9a1e45f47945128c97e1d47d57a948f6f22c7add3cd2967e6ab5c00f5dcd0c4c3028745baf43095bc540e34db17f7f5aca4ee6b149fb072456a91e1dd5a3a23db2433d52d491c3e0c68d3e4b3e82d29e5600b8fbfb0b92c6ff3aee044f7ce235c32c60acb15a6775c357354711fe7e5e8620084afa95578738561446794cabcea11c313d3479ee319745d257860316a46f1602401acc717e9ef84e1dceb418517448fccfc8394196dcbc6f7b34edc975966fe42c5d23adde78bb778376cb3f8b523cf172df9d5984eda0d188e4d685020f08960c6d08e59a65c4729aeb180bf6f43a117feac08cc428e931c2237562f6e4de7e1d3bd205ed95dcb0b1679c81e9cebe6b58cda38cc470b3f311e8433aa40dcc50ee5b5ed2c9898e4aa7d33552fac7ee4990980b809f35a4593c89dd0ee13bedfc7def36346d3f86d7e0fcbdb28034ae286f36f12866b056608d5e25596b3b0b92a2bc290a4e289028c589916666c716c44961d3a41272bc20692092ad40b733fb4861c1b29d3c6c25c2b81d15fb473a14c4b913051d4cda0fa6800a61e470a1a63fc9a0cd4351aa867c0254490efaa38c15ffe6c5f522582a5c18e70eae9fe0c28923ef75d8b573d664420fc7aaee06f3c5c9a8f1409f49022b3f0af92d0eca5389ad328ac5e2799ba78221e337317d9596e8e5e49f6c31ca023c574d781fe06aab5c56722277eeb8abc66659189cf7195d154eae6b6c968c9cfb8edaa7371147d853f38cced024a0407ba0347e511e50002f67928fcead46a9c04632fdd91d00a0beca6c50607a6edaf99ee9ee75738d3abfb61f61ba08f37068335c385add57af5c487c8b81919b495fd8f77ac00dbec2664644104072461fdd6608a6459420efae260f42dc91ef956965661d25f696c56f1c491536fca5d99701bc24436dd734e6e45eebcfebcc6858a2903881d4ce0e9439de9ace0206be1b45acfc34026a1b26b8c0bc6e40582a1d33b0359a87343662595289345df1830218f1b2d5bc7e4804ca63c633b98e6b442a9fe621b8287cc6c01d4190e1d87cd7e00cdeab3c659f0849f774f9e4885cdb42ff56b08450008cc574409d9c0ec6847dc93ce161b7cb10121568e81066baf6ba5b93d084977559117ca4069bd67ab1860d3cf584e83fd1707485b15b62eea875b6757db56b2aa97ce473ffb9c6da7f4bd27a4ac6922b42950e91c18d0a5ce6e5e953240bc8b8081a7f5a6cd3e95c68227768d6970c43756037bd7d91d77af63b49584ce64c564adb516a7d787c8ac0452f22e603446e9ef3aaf75a9c21dbd4f8354d9d8456ec2656bb8936e771cc1e7e17878669064d37fdca57c5383f6792535c0b820af0f341886fea7e17749e413090e136bf8189790c6380b2ffa7238ba671bcedecb9142ad66be26197d50785b64b8742e43d430b3e512596df815c5390d69c4e93fc5fe0259a5d2e1390816b3386e114365f24af95e00f41cd937c7dc3a03e9c19332199ee1e1d876cffda1f51ce088eaa807f94288ef4f211a51e9f67a000dc4591e8e5ba097ebd8712703695f02c8305e81bad7bac957158ad748cf4cf80548608cdaa90f56a118b92fad2e08e7353f85b5eddea3483c00300e5d320e1e7199b07e62090d1be9ed4d24a830065735b629b1ab077aa3fc9242db7ea9a094f6360784ab171412b7b28da47fdf2bb7753d41a6dbdc98f69b307942b130d9209e800e8280be91b00d0bea586cb25a41b984aef2664a4652c3f7d9eadaf7292caf2c3b1a6951e83c7a75cc588e11ca45b7253635f48af475c9fc90076938889b19a7b028135330ecad92206a8ca0fd7a8ca970685af5d0d1ed6d076b1e2e88eb7970be7c9f4ab8340fc1356c224d4b8a4564c923f06981b2d6360b9bb613302c275fb75609404ca938b269f9361d0b9cc97c9dc2510c53cb0001fde7d3e88edbb3a621e048eadf8263d24ba90a6baa73111c8f36ac478d40dad98369fdd9e4089a39dab3848d05364ae0e4a36dccb61cd3c000424a102536a434c43306dc499793918407310b828cd94a6604535cbed41a56ad919c37b770a0f7ee066beed02bd144fc857e0bb3bf443b6daf9d335c5ab300f87910481a2e20d9047587d04184841084f21846a3217a425866187fa473021df0434edd459fa99e3912c41b480b10b2f0582e65ad83f4a1617e2bdf300c265d778a15e197fefefba73f37a76b3975fba383cfd056f8915fec446d96d3c99a6e3154a0ff7edfc4fe74b3dae01c5e9b3df644182363eb0c23bbe35e1114230f7f512185d1472d5c9be484c708d771ce751f91840dad826a5752f3d8d08c502ddca70890c930a0478fe125d0a3b7fa8713938da28f92b20f8388e90409e510447bb607283017a178ecd9de3bc09498c6ac0943463552d42c3f865cb42e1364a7f3839b1ac6e25d0c59e7e99c39cdb5669c107c490c40aa3598cd1508afe552f3233e0d7408952bd80c109eb2f156aa726ffc8040f41f100bbe31715e1f6ca8d11032b6827cb30ab9814c403032abf0f2684840b2c1eb13a6212f4f275ca131bfaa4ccc8721613f95a55649eb6f825bee72b4f6b4ae7fa311060d931f69402db25c2476d11a3fd3fdc28ab367a432e974f8b593aa287f92f0e1f1ed4936d85d1a6f37343d80cf47a5184076632db4bec42ed0ca27d4be6bbfa973b8599c71d44f6baf3d7bab243336c6ece6690d4007f7b4a1b019c7c03aa5b9bdbdd9682645f94006ba6762ac7a6c525aac457ab4bbc92f5672c2c8800c33bac1f6bfcd0262f9da706ca2034aa8ba895b304cb34a070d2b551a0cfa41efc570aefed2f24e0ce2a863d4272c41261893c8d650d25b42c41fb9cc950bbeab01303008664f9620bc1607d30eaa50d0c0311cbb84f982e544a25c321889b0fe92112409d97bef2df796492629032e08ed089e08a91bdc433d007ff0518ff3e50e6901b1271925e16394d47f30cb28011543b02327e0a1d4a7f00947e695071f85678ce6f8d7a7de691023f5db3ceac719d382fad4d744a9a9c14348f54f802175fd2b5f9ee4474de4df51afdffd03f2fef6703fb0a35f638967b8dc0f8f5588ecf5e88ba32ca9457f2fcc68c23b263bbe1704ff55f869063f75383b6ad1ffe27073b8f447fa5d105cfaa27712cdf1b7f6de4e52e2de20eed8493449ef14c99e7bffce6ab82b62a473f61a96332cd2cfcdcc16c9de036ba4737f98752f9b4c8b4e936427923efd3429fb5317248f7f91e444fe448ddd49ea3811e59930ffd7ebc89d64f7a2ec477dd43fbd7405d3a2ffc4b54b8b5e8fba64af445649eaf8d7a3fa433daa4464af49641fab13d9bf12519b11d11c222fcafd1aa645ef945f40e5d631b83ef907c172c71622fb0d599da4287b4694fd9f64070aaa4f34c771d020cafefdf5a93e8d36833b62d7cb8d4706f4572c84fc844069d11fa88dea53f6cf86fc3322fffae45fc7f8b710f689eb1e6db494f9e5f2e578bcd9c4b79de089c76e39c9b4982651c4c0e89fe104a3f329c87cf2319f5cadd4122dcaa646e42cd77f3ed127efc91de5d393e04f7f4e21e97ff10519649c71c6182a75e84fdc4a52c78728718904b508846619c680cca17f0392f074c693f4914f4f4f4fd60c2050c88c95654e29a594524a29a55e29a5b4d65aebd34a29a5d5412f404c702b58298e75777777777757eaddedee5eb3c6fd5185b5943645419e53faa86e9e9f237de6cfef163ba9339ff2483092c4203f0b90d293e76c92ad79e7f6d4f322a5ce258925b25c4a428829592e49f1d23596e9cc9c7a287750b872490930592ac125cb2529493e592e256145ee58ef58d4534ac59009ae54278a2915cd27234be4402db045d4d21355620aa5f389d665229135eb50e64deb6e8df5aeaf40dc573c8690ab5f302e4e94dbf459093042fa606066ff6c86a20fa943ff470bb795625168fd354f69665238a570afe17914c5e65136de37b3fa3dbd620b1499dfdf78ecdefb6e2249cadad784ac4a13b26aad7848cddb6021f06b5ec8e6691e09ecde709fc0b06dc279b4323aa2e25628781ed1f9f43e8aaf1edbb4e2110467f0f87ff128e6a6afdc28dc837f7eba43ef693a1b7a38d2785f134ad85c32891acf22a339b3fcdadde79c39b39936b3a9cd9959aebb1b08182cee94560a22c5dd79e2f6c76255fc18b92bcd776baf88750efd0c8fd6563c9370aae04c7169e311491099fb2c3287a7931d14ee389b7cc6ac7e993d0cf29a4d84c8d44c676679901b73d063b56e7fbb797777d7b6592b75acc5296608cda199a4c36e12b613202d6c7287728a32aee4ee3ae7777777d79fed576246b25cdf9f3aa0399487d5f80776019518094678b0703dd0bce428440fa3e9a7c1b27362dd5168be86518c340fcd53dad57137712a464e4949529e88806044525393cea1df454aeed8313f638847c278e613234ab94cbfabb11a6b1ea924732f61446977692ffd549d1502055aec62adc4fa4a3775ac95bac8521df4c314eed845b9c654bdb346c7c4845296cf740223b2c4461a48f77a89e2bf17a924a483eba0df2ebc5e5c9439fe9b9d0927ac436900365cd3b44c2749cb2a980e6304267b9d4afeeeee8e947d6759d6f6189a4f938c7f13f97713a527d9dddd6ab51bcc549a56c87172a9b5d632d2a7be0365df607a472e19a144f61f57893b4e2f53c99f86ddf70bd1f77e14b1507ff72e44fffbb1a79df4a3de1f159a4045e8f142b18fa8fb8f19f3f4e4c58b935353d3952b4a4e690d1d481dff0d09687ae9f944731cb6c4a5df3fbfb3de953e55ab3d69450540eaf8df0064ff49c6f482373c6e7646d2a19494a219aa72a701063940b65cf94cb8f7fb98d68a1a38c8936a594bad62355c93c695ffd340b4b8b2054671e58f202dca9287746ae59039740b135d6d55a794524a29a594d2ea4d9f52daaf80995bfaf4d39a34ee7c205adcd9ae5614d70477fe4fcb166b88b1e5a43dc91430f3dc773b4bdcb187e60fadd43b359fcd2b369f7db63dcbbd6f23b6f0b6b87d0f35cf3c6249f6dda49d64df46bde339fb86927d1ff5cecdd9b710bd23978a5892b39ab36f29cd5361d9bbb78d69ea9d2c1b5d934cce3e1be70f59dcba70e99dcd8c2e60c2642cebe924d1ddbdbd023c6f349eb78ddb6fafd9fc16024dcd86419acd4b9bb7c1b2c59ad08416b3a7c95e442b2cd462d64b7ca872f64d247da8b5cd3abaf4b36fa225bd2366ae76d23baacfbe9f489ffa997b21a47e0b713c0dc71164def068a4f386b9efb19be4ec7184466a66a15421cbfe0c6609a11fa4c5ec53210bf533a3f02b04af2e13b7e73cf0f7f06842f67e0b4713b671c34668666d2f730f6b7bcfdb77216bc32f9983fca0e15593428c0834ba1803c3972d5998f83282325d50e1f231c0bf7b960763079cf2f632cbcffbf086ab16b3d749227b2e7b2060eef6f8a7c5ecb3978e94970dc116b3cfb2efa2ecdb49f63d947d13d521d4978e15441f09ccdf462089cb922c89a3d49f305690fb8451fa134631f8933e4c933f94642e0967110934674e2bf38a6dba4e794e2fe22b88c84f074f491d4b886445e1f00953294f5c0489872c2159f697b9886396075e84651fe79a3bd9b3a5a32e50f27a151957bac4b7f4e595f982ad7fcdef99ffa22fb1c9231023cbb71eccecb698b5fa5d2dd6a0e6916c38d12b62d5acd2cbe58365bd1044082262adb51907d965054c48819d807ae2c21b309510eb081546b24f0404b742b8f7be86339ef635607bfb9d6b66eb5554bdd57eab4597fdb1f53f1d4479c43ba412091232f3d45942ec38f3f691645aa64c993265ca64edad1003646de6999025a4be4879823aa7ffe2d15a141e3d3c82a20d5d566ef6d5c8ccdb671fd096bd677fb33272f62de9237316b6351fb6d0e008638bbb90cfa4fe76b062fa21fc04d3c5960250d9e285153fc6dcd9a2945231ee947abd01b3bb7b08bf861a6128ad957a91061a673cb9538a25a5740ba5748b08cca0744e4a84535a2bf582d25aa91765743932b85a5db0846a29c27249b17eb73812c9e1bb726d22caf3bd4dee3eb3dba7fe2745bb7a03a418b9c353eaf409b97f72d64e29560f548bb3b073e65f3d90fb673bed867529990a67fd3b936b4b4a6537ac9bde9433d92f907b26b75771ffcca0d4d0e05065b95ad9b0a23d6710d2e76629c5aa59eb457e6e4915e0872c533a279196d9d387cef6a8c4f94e6d47b11938dd49e507983b5b997a3f5270274ef6de99b37aa066f526730fc19c659af7e3cb9d2f7f9071e7fff0c2ad8804fd18c3f37ea0e0ce47793fc448793fba5ceff3f209dd023a587952fa703536cb16c6f00232a72f2075a0dcf9369e943e5a96df81de8f30ee8d57b3ed69b129e640eadca43b7fecf1f15a59546ca79627a50fd53270cae1fd0043878e1c2d164e0e1467a5b3f40937505724718571ef9940c144145b4247964b2d90612232e24ad3bb515f792309cfc7ab793a363434d4e48d2f50658e52655443e0481a1a1a52c283eafbb1a78cada424c70c2549995efe56f96be5cf953f1f41f2c78113dff7bd7c227fefdf5b15f2f7378afc7d4c2b60c91f0b31e48f85a5fcb52043fe985ac0227f4434e4efca67efa8e8bcce47ee82e4ae93dd77aeee650cb97bef1d1fb97b7b516022770fa6d042eefec51972c794c216b9fb9e1e72f73f1d930a25c81d531225b97bee03ea9a7a2873bf7d409c6f5b2b6fdb56464cde988694c85b1924f2f6f328dbd73e20ebdacb37ccb03bd5287beb8d28b2ec3e4fb86ca40605c08076d980d228e84cb293e57c2246854ce9db2bc6874c1f14e394e9ff181e327d714c1899fe8b0d2332fd9e1f36aac8f43b4892e907b5f144a64f248436d2c8f4454022d327c10437d018228304510a4552e4d20a5690e9b71116b9e737675ca0ac114ccfab54c8e899be3f36d2b993402570daebf63a68bdf37c0d3965f79f4eb267f0afbd1774d0e6580ab868138012c50a3a8060045c52404202252ec2984146098b30ce844a17289f99850a2cd408638d24d48021f76bf00135789364b1210d269e525802890f49482041310231496b509f454343432e885b1ab999a2e4eeeeeeeef980dab916131772ca13972d671c71460c0d1cd058230da53022500385eccff301b992952768769ccbd3901952e4fe017c400df698a08c29b2bffb5b339c64ff205704575861c10927c034b10209c60a2ae050430a612c1dc17c4abba1814505273fb6b8e395403e203a97caf02103db3242055760f00179eb87561e3d305fa8a088ecffba54f3a20a477f7c40ee19fc90538019025344ee97294022f75ff001f51391021630c8fe3ab68a0a70f8f880e8ddc07ea9e20b0bb9df826b05171c734700ae411e570520a30a1930e4fe1c1002438c81822c4655da580236de5c858d36a808028c124444e1336019637dc44993fb651bb93f001f50db21bc31ccf04282ec0f801e1c5080c6183e64ff1e97670d2531aa400110d9df25458c1cb2fff3f8809c8913496ee4b0e5c9964b7924e0c30d5b1cdda0254b0b307fb14ab75ed44c5861851ba88a3f20776e854c3ffc80686f41491f3c5d48200693dcff62bf2493fbff03ea03207119c000f2e8030c165e601c11860c6150c9fe3b5e24b0228b00a810208f728a16799458749164b84002001758b23fd88510d9ffc52e5e5e5c91fd7bbc1893fd7f9ac8fe1d043991c9fe4442f8024bf61781041374cca1561373c96a8b054d728a15120bc9458b1417680993fdc12d57b2ff6f8194fdc516b2ffabe7874b11d9bf8320225cb8c8fe399c5a3120797465e7400b157468b143762dd86812a2894cf66f7d406eb4e2208fad2c70c8220b33b23f98854af6677d40fe6dec50b4c46444041428b0f13ec0061894b4c08395299860db1957986c38592cd8c1e2062cccc01246eebfd981933ee05cb59ae94b6e2c503061c9fd361f0512354c2de47e9a0fa8af74d2d0d0d00c306f6c6577b9f2e823bb73f12ddc251777dfc22f705fa22229fbbb57c124bb57d143f62acec86ec512d9ad70ca5e2589ec57d090fd8aa7ec1f44c44a52f60fe10a51f617218cec4fc29537b22f2d69c9fe936816ad3e207722c50754eeee38669029a648cafdaa0fa89994bc98f9801cec41c9070dee07e4a00d5ce471e593c796142758a20243f6252a60b27fea03f2f73cf72c927ca80f88aea40841145d72ff074ea142e54d89828a10704db93d0f8b15ef2298bb7b6e3d7b95a614e57ead27ca1ddda17892dd1d0a2ea0fb90de7117ab58c1dd5da43c978a1cdcf9d5b138a194e58910e4fefbc419b9dfc12a5168e895d8189f2207947b6ebd5e8a2de56ef716f0839cf3e948eabd22fa738cf4b1479086a4defb23f73b2ae57ef71f7433618f2730552834935698d205ec8446830c0ca9a7d08228cb29b28ca992e5145980c8b34bef58ea3ffa55e252e9e3930d3994e9193287fe5855aa9f5161a47e59e5f68f9715f4bdcc43500f44ef1d42e4419016dd22fb352043c10260765cc4be8bb777b8776771f755ff414a858f1c51fde5f0cc9ce30666ee3b6b5321cb7fe625ec86a9ffa09bc147ee7b4752dfbd8439be3735430b660e8f22e40d8f00e68983b4224a33ea25d32610bc1715fe844344738c17be680ebdf68a40bf02f7de5bc29cb7861983b437c81d32b57db9d0220aeaee3de79c73ce39e79cd2bb534a29a57c570b049d748df629bb4d8d8a0695b2c14e746912117523e9238fba6f0ff73b61961182225c80dd179a6738c14ec87102d8c548da8fe0cf0d37f535df512ff34aa673fce557ffccdd23e31e267f507ee59edcab9e43fd90140a0b217178484dcd0ba132dfb24cce3b55288bc352cee628a8a02128fc34c7efd33cea55efa8ffe03e0a7f40f32a9ce43e4df79ab5e3ad6c8c190ed99f3e75ffca4686c3e4a128642e643164bfd90dd95fceac88ec1910d9331e9c88e6b83b913afeb01f562eea859086a45e2584b4fa2324d01c177ad11c9cc7818f04cdd427e9a3cafed5fb29ce9c64ff0e5b881657ab5fb1fee6c7971616f6bfc17388e62471338483917ac470efd33c8e5f3df8363fca980d0e81e624f1340f90c6bd011f8542a1f010cae8e6413c6d3ee1eff80748d80fcda1effad67fe0fa16fe233bb050889b3ec01f7e888fb43011cc03b32c2e6148eb79fc3feb3f78d6ebf8233cb090f8818e6f7d0b1f61611190c046a9c4e3c79ed64b186bd514be84edf8517c090b3112cb8322aaf79779945ebaf670a89e47b8e3c330c7bbc27f1ceaf8d9e3c1971fab7ec541374fa40746f20701f048603636363d1e0058c8e67b60a455078636368f5d7fc4069b801ffc1e1f012d3db0a439208f6fbdebf18f93c8f53c5e02f85b9815c483c74f5818fe8485acfa3d1e09ec266455cc0abab9697d0f2c74f32d8ca47a9c4702f390e51d4e28843404e76fb010d203242cc911a42137afe38ffc1fb9c13a1ee75b1f012d77c7b3702290c4ddf1acffd7f1ff3b5e023a9e8559413b76fc84e5c8f1139643c26ec26933979852fa49ef34a69c932bb12b4a5762d3a9c52e2dd29f4edbe6e2b1c281c31da1a439aa702674b5585f479823bc2388965a40cc45b8ef1a8f620d4724b922094731774f13b2b4bfd1b4b7a1f91b2cc4d2fee6258ce685c0b7f90f70fe061f693dcedbe02348435a8ff347580f228175efea9d54f797f2dc7cc77af089b4f0c479f99530a4f52c2c34bdd01cfa2d4cff0112369f581f4cd8cd4fd8cd4b18ebc739868591581e787fffe222da7b2fb384d9fc38bd747f404e51a8ffd0d5e2056d1772df8e3d942d7e19ab29479324c5e888b3bf7de761ad35fb9a7dd98674ee68fa8464af619be1562151353883f69d6c1efadad4dee61d4db751550399a36959825ab2a6690f73e2f6644dfb1ee9c3236bffd301e569ed25d5348d7ef768da6ceda9f63e5ecdc341e768402f2677fcacbdf6a0c63d17765dd7596bb3d0e6db3bf6b6a8556bed5bca43dffea53c2388d97e67b55fb171ade6012bdbb7da6b58d32c4cfbdb3bdfa2a6fdf4b4a83d9023bc1d4d55c3456892460508a48e6c97edb388d27e32b36c0e39ce30ce9a524af1ff8e3e6a4d9525131311b4b1a9c0e1807a8288a3eae5c8f3318cf8a6f8417bc28cba313d0185968c06a28d69264b26264d7e40e30b1bc8d4f0e4e88924438a3086f8e2430a4d92c8e04935b068103d28265e964c4b56a0ad8088a4269ab0b14df16264cb681943312d3183264ba6255b989658a9b265cb166b6f0bcce074c1b9304ba8745b5c56964c4b84b861890c291fee4c964c4b5010630a252ac8b889064e5ab7612451316ec6b4c5ddb2645232856542891315cccdb264526282573329417aa1a2c0a99d2e4e964c4a66404171bf2c9994b0e07d2903c3b559327d400c0f1f787ac007bcd42c993e30a58abd16cc1163a2098e16a556ac0825374b45ac180f45a015229c978dc1e6d5f30ad273a5cb153037d7be624331d4d86bbdcb25898b14f03e15d1c46cc670619565a846cb0b38b078a259225231495999a086992c8e70f840c3d532a46a220725292b334d3079014574ddf896a4a4bec0c1c3e284b222439725f641c135792f7b0493edd5f30ad2b3055107c412bbc509f7b227c0a1487bf5bc82f43419d1397289ceb14d533a6703edeb042ec490d96bbd8b458aa53caf9775e385faea7905e9b17245b3f665c612b7d77a778b239a23c140c0154a5930414016a32a4408d0e285891813042c3909e088ad4b199996eb65b994048c4e875b93e552122bb62c5795e55212258eb838592e2531f29ab85d964b4968a86e244921cb72fd0dcd04970bc36971b3326c1a17e5f4657169aa4091b92b24b22f4008a1c20d4f5458e2b970bf32dc1097e68bb6c305993a362e8e263c145c1411a819ee76c455b9b5072d4a0e3d5c9be5520a33fc7067b25c4a2185266e96e5120a645e455c2ecb2514d020c1f52c97502823c6a5ab5fc30e68ce7cd0e76660b1677bc3bea99498fa07412f959aa1cc99bf592d95f2148ef95dea5eca49a17965c5978ca1e8dc7a665eb529da3d2d76a1ed3c1c15973bb7b73d9a63a6d297d25b2b1eaf7358363820cdaa06c6aa69d1e4a03a76fccef65b685fc70744bdf66096a16e3ff4ee7d5b5fda0ddc709d36f49fa153ff54751e28570f0f009d88c3dfa1030bc002cf1b280577f4ecc3d3f1bc77bc45bfe087e7e281c3775514a76a633600728fdc3c72bbb04bc6729769d69ba1f8c220cba58ee336ab7959add5a382524a29bd53a6286d8a1aa5945252b1e7f7bf63b499525a27ed324ecaff1de1dc2c683750e3dc1df44c4a29a547fdf328ca7f56b053524a293b70779c27bd2970fa5b795333a8cb22339bde3ca50f0e677257a7f4a9a92c43699a9dd81bc26edeb5d975f94ed20be7c99917cff69a79e56040e45fd24abd52f73efba134afd42b45a5b2eb957aa5a9eb3333aa55ace54d0fc011777e57ea3e339b954df7f502df2bc5b1f2ac00469f2cef8bf2109139fdf68278e64b40cd447cb8f7fe6d5ad178201712a139770bad13a1994111914d3844742fce197eeeeaaa842975fa7bbacc5aeb32d219892b779e918a42a152de4ca5ae37c3d1f308ae3c5534ab707833f4dcad56ab158d47f3b1240e725ac34a0075fa1cf0a64d1b0739b5a9a159e150d9749c8dcd66359bcca65b2342b6e664b5ad5eae3854de504a69adb5565a416fce596d32cdeb910368b7558f27b11ef15b945f63351a5b3318c3e2e0aa8ad2aee22254d6998f4e5b6b4d81178f52ce595f7e0cd8918b542a1f854a7dde4ca7e270789bbd51b41a50eaece0caf26d2af8f68b3c29a594e234cbb3b3e5dd2877663006a594d21c3c6c68d284490a2f79b460eb79e4901e82757f559e59ae08fdccddbdd455e190ee61c7795de77137214e0eabb6727852b63875ecf01518a76ca4b1c8467af62865233dffff7bd46070e662239da5df2c67ae1e3d5a5e8e0f487a38eaf09c467a00c499e309c0024ff68e0f9d258cc8463a4fa923ff82f9f2e497e111049a2c47faa3fc5ae977346465b9d2ec5d5134eb5e1f90c45996490c2c00a2b343c7c7721c64b1cc5a7681273f2965880130cbef82782f2a7111aa23c7b519064080d4f70c17a99ee36379eb63f9006ed2e8628b10f5fe10bea37428cd52afd9c67d5e6adba414bb7ff6fce96dfbb656eb9ad55a6badb5563ab30b39c50d4ba1e8c775e1ed6e2c03f3c79b3cbe05c5195bffcaf780e09372c081061203a9410f082dde4ef3c4bf28973eac9d30b0e33ca033ee68ed0c372802657dd277791ff64cdf74b803a963a289c4d1751bb5dd8e29a87556ad7777b7a59dd59bd1d9fddddddd343674b3a9d7ad66f6334ed3c07b2fe8f4876696b35bfdffd84f2c16db38cec5ffff89fdfc7fec27e6b11868bd3aed38af6ff823633f4f797ee8ffd3ea1ef77d9cd2150ef513933ed2c926876e3675960326cc7fe699eeee9e9edd188416e597bd5cb95cb7dc652bcff69cdf3e34cfdde675e85e67cd0e7a2da7e40e5942ba896872e3123c8f209572922cb16db1c395d77d3d25aa56a7ed81a093d916b4715a56dfb590c8c2b6cfc2242cf4c036ac3d9185713893443db0ecb930090b16963d510f6cab9d4dad3bef43a5bacef3c69aecdfcdba72afb5fa7fa8d49d515994dc3e20fa63b291ce99d62eeb913af24190f25e9a99d58ac6fa40a9aeaa7e148f2664af8512b669ff4369880130d3950c31a0658a8b54acd9e780f6374b1f1afa5893d32c96608babe9fe321cbbc51632e6caff11e4940f48be94d26e70c49d4fe56a4a29250b676a9d829a86853800cb4020505f778fb8881432e68e3e3ae73277770d67e00bca9dbff1586b35ab795a4629a594d60cc668776a0019ee67f0c59ddfdeed0d4a70e74f9d1d640a3522c9d662210ea0a0d4acf3cb715ccd386b8db8aa65465cd5b8ec021cb8aa6546465dd775ddb6bd9cc9db05541df77d401af6ac1ab9164ab16b31d2d2795ee7a4c583d9de99b5f3bcce494b125a2c4cd6a881eabace888c4d0a955a0161e7121284dea91c029a270427116c83831f0de40626f4481fa75e8d280f0d8c83c9af1cc77538847420d3759d0ad60aa16a26dc263eb2d70f5e6f9186358ff2ccc0e40b91f9325885398cc21ad6cd70dd2541f509b9d9e2506928ffef03b249e6d011f9a3df0b923114834024e559eaf3294ca6280f0a26dfc7023ab833df4b147f663c98aa83c9e7c29b8117ae16bfe98a06262454802c3a1a0b0b7369ea03a2461ed01a98773535300d96047c514888f2d4c0e47729231a18ae3b78af13f94eca783730650eb8cc3c4942818088cf4a3926f7ce8e3c7a4f4e90bbee2d0864b82b874205d6ab64d7987038226b39c090352e324885e90625730456ba60233604f33b002754e05491c10d278cae93dccded8817c137224bdb07582280ee960d2ae47eefb73664c9fd17743294fbe9f3bc41a5e5aae1850b6a5822f783dfe20a5e1330723731d1a044ee9f3706bef2b89ae14bee6f62afabc009c989f0b6359abca17d68440163082942ac200858145f8af0f2841a2a8480098e8a013631d4e9dbd6c8a36cea716292218b262280618c2f4e1fc8828c219c38220612c49ca0e83a297db2ea544a29a5943d7d074ba5fc1df2fa6acb9c73fa742c99cc96b9bad7e946ecb670b52c99624821c8924b83d081040f4b5a50e2850b5c20b1418619460004d20b5f6e282a73c19bca92a9e8293b25e94a706f964c4527c8e36b4bc14565c95494d4e46a6268f0356299174ea81a46358b0badc6933b41c31ce3648c51e7c83cdacb04890facf1f480a2234e8c0c8d9b23cb2b62c2c8e3cb062cc05c9a2caf8869e2b3222689488c0f3888e1218d26ea547c3de8ddd566bdbb02b756d7d595e7d52b827613ffd571ee57a967b4c09513e449a7a720dc4fa7f96fabf636488f2b8703cfd49feb348e0be716a4c79593e777bf2c0080a87dae9a7d6bb1f5af55ab5eab66df5a2c7af36b715e33af59f64a3f73b75e5d66afee694e37b0f34757d18a9c684591e3369f54a422276f9ee8a43775cfdc33bf29abf9eff8a4d491d469764f7fb1a79b5a50f2fcebfffffffb5fc69ababa92527ad6bab2c45d7737a59f29edd923cf4792a59415359e50b9e83a77ea2ddadadddd3a3b501e28adb343eeee965256183a5f7976364d101fa2bbbbbbbb72d77453dae1d8d4523cd66457f364d82d3bec70c453ab9ed16979d0414eda830e3a389d4f9dd2eb3ae83083c826f59a519fb1db36cfe418f07a40f37aa74a71db80bfb679611e4c96b217d0d2e583c772603f8c91f9a3bf7b7ac811e599b7c3a3053fc8041e1e6c2562a49bbe6a9ef50ce9b1b867fb80b2dfb8fe97f6e7fb8c55b9c13cf2efca1c3badd5dcce0d38207ff43759e281ca75736812153931c18431a921bff2098631f29cc9730c0e1e874d39bd451f06a44ced7dca3ee90efe9e77271e89f040114770e2126a1e41b43b4c70be8642b0f2648c0c2880c012061136e820b57821c11165b62c412104cc5d8deca87ee18b179e0057ab55131cc820810217b62841164fc450228a2a52f0448b07c3605981487bcd7047579e4c2f2cf156354b7737edeeeeeeeeeeeeeeeeeeee6eda2df18e626fa1cc94520c7677d3a658cca074d2d55540e6f84b0df898d792fb2dd2115a1441c91541eaf88ff263002b0329c1f57ef77183ec9ea4c07cbf519a7d0159448a199014709ff3680a31a1f477eea4ac19cd1a95e1aeefd93b14e92c9b2f208b48310332c745983f7c1c4076c3ddbf7d011760b941b883161d4abffb8fd387ecfda19db3e6f9010525e930a6346f623aca75777247d39ddd39dc632027782da562a654943e3c32fd97f491d96bca9476ef89f4e51794a4a3df85adde691e1f9eef0ab4fef6b9b00423b7db42eeeb076439c76eb316aea40efd2ca4913fe8d7f0255ea3ac874eba76a6dcd141d617b7b5ba33f4ce915b866fd8ecaad9aebb7b7d96575cc2909b77bdcd7f801f071fc179fc36183c0262a11b2c6136d606e4f192f2e0af6f298febeb5fca137e7d1cdf75d84f5aa4bf85dd848d9bd130c492e67440736e9e157473835975c26c9ef5c1b49100ce83f808d2109c07df06b3eab39e858fe060a4156679b07afbabb798e581eafd55ef0fdafccd7f003ece832eccaa18b3bef54358dfc24248de0bb1ba6769df6261967d567d968787f078d7bbb010abc3250c09a279a8444d99143929119124040000f315002020100a880442915012068220b81e14000e6f943c745c3417c9b22c886114838c31c6100280010010430019a31a0bb068798f26b6eb7b7b2214da68c9210398e08d5018fc9557a4d31382e2d0dc2ed6a715f8c1a1fb7b6ff6e9ec4df0a4ba83fd7c0e6c5e2306c71d3eb0851dd72860f2ef5f530d3def372bbe8deaca1d9780b0f42748c0492460002dc926c2c01efac43749996aa794f441d7fc0a33e30a4431a24520ebe9bf5e4ba10450c9333f1960c3c89e13450c8c7a00b63ea3e03a8b4723cfaf8eaee7e9b6bd8dae00312997cdcc7d52206df47fe0bafac5103ffb9ef014bf821f81da829e815fe5baacc6c0d36b480bb1051dfb0115924d05dd1f4f64d4086dcacf8a1535d94cab63814034a348d7a57f89854eef08a6c276d74a61a265e16c8ad0b9c57934537f2c7a7bf55b5fd4913020a306048f3e2e5df9297968048ddd501ca4e02389348d1d8002bcc887640e3a1d9e36b66ecfe1430c799bb991cc339c1ec405221ae8f30ffc0a7eee8a8e1f4830f71be8cf38092accbf412ffc20d6444ca81cf97cdb7b4eb65e6e72729dfe813fd5d5e60137b01932c72bd92f0a06cdc86b92c82f5e9f91e8f0e32bf447a5710bd963b28d5e33ef0e421f2ab5b720a715b5d6ee71daa0f42afea3970ccaba1f3a1f40065cfa58784761867b4ec9565f4c7f1f5c53c7d937c3edbf12b2ce0777168ef12d98ce61125019af474290462d59bdc6556b6ce364b0810f8e1f6fda56aab6c1d5e8d8b7400c984af8e739186f5904f5d19d76b7dd7a5848a3bd6af4e732df46eacf0816ee917d16095c836a7d556f13f537b592ff4d800021856f33869c7b832e82f843c8a939a227568e55db5d26ffc83d0bf751065fc2d2649abb4c9344a6a6e7e49fa8a71aa2f28effa83fbd0a146b5220f5a88b1e271cfef190170341fd5716625143792521a06bfed477af0ef6425eed3c2709363de68d738cf7f71983a777ad10b9dae0d7be04b7a68538ba0309599a546422080e4cb28cf21c5d6f3a230298b5a896e65a5f347a585254651b391c36225373858e71999b349f3cc948c8b01a360369d4fd3a91ff5eddbb71193eabf51bd59f60a4c0e2bcf8e8ec0239b855ce53abf2bebc19c29cccdb3df333ae7590aa367910e5677f7a6cb9fb45ce35455465c5d4a7b6d4ba6f44670b7cecadfc3aa3c7eda122ce216c5ea5fb23b110883e8fc75f42246ee4607ecb7b68bc966c9fcac67a0e89cbbbba75b40ec4938cf902fad3b05d4051208628d18b088eb9e474512794193a6565503d974d120714ae5604ec12f843971a5377166871f5ac4661149cc4e9c1e5c89c9e2267c5c3c03db2fada49dc8661461926a33fba7c7b99999a8908a9971d1221d0a62ff4440ca91c4c7e8ceebe4f5a46f0206def27a65340329a5e4da2808763b0c1757fe6b0c6e4625c8c7b8c73453778a7320bd92e3234ea54fe05d97b738a06feb082f5dafd087213e9714a445b7e61d529720d58c4f7b35d551b872e25fcd1781af17691a1c1fcc0da37da42dc95714e1546a6de3118aff7d5eed565babd60c656b7b5ad3dbbe8ecac3ffb1ca2b00c458f32d57f46504b0350a1b4480a90d87009aadf6cab76196607bae32757f6499c2cb435a1d3cc16709764f3c449d556431b5aa06ec5d005ed9146f8d2c4fcd2e880694321987cbc989289fb25af74053363a3de5c1b065bf02d66a0c16a845ffedfa707200bcf32c4c355404a8a4e45a6328b0aadb6925a42e2a176415f530aaca2d25adf002b03d1d94518839e8be5a3332d396e440d035494ab851425405db6b83416f102823f4b81b896b9cb96b51684249e93dcd865b2d9b4c3ce04a67d326e0a6c20dd3f8a036e204f242605f974c7f0b93d4d447d60a8e1e2076ca6c396422fe0794107d6ea0dd855f2d82491eca3b3f45d61f6f21c9dcca691d741102d54c9549ebdc072a60801fb7de16e4b05956028fac6da64346bf3a06ea5e77fcb9be372e3cff820067dfd5a922e2c09c953c91ddd08c5b7da2c8c648498d92d6cb884f0dd3be8c1e05f301fcf0c44423d2e10900e4962a9a24a983b01d8efead336ea44a52e4101287d10f76fb0d99bd0bff4811a23c163c2dfcf62d7ebd1f39dbbee2ce6a4149c21397c38ea17e58da973aff284a766a3a1464699dfdce72faceb54016c9cadacf729948266f0d620994bc210c795ca22d08d061954f4450eb646a1c5206d4176ebfcd17199902e16255a521f7d83c29b295e799b0c2ad308376ea7893723a05e45f139620977dcf1625a4f17add07c626ea3148dd8469d36785e8300c46943115aa6db1711704d54c2d64680e784eaa5d629d90b28b5a4c428fe76a3c33fe978f3812f34b36eac641de8137ac856863fd46588671b1c025c47ccc900a7fe5cfac3a4b5c1ef1b39c45f0b314cb2e27163146dea9e462b9a0918652b3bee489ad4184a1ba57d91a2218c80f03bbd79e6ae72349a895963cb3f52edca69a54dce2ad3d682e9ac448d7399d88702795811661ef370e03f8e7357c3eb4bbfef159efb5825c22e339215b7773bd12cb57b1323391f85785bb6eba54cba9b0fb524bf2f71e160c7f0ea20357b187d597b910d25aabe5e4266d31e1777eb71c3b4dd34367a6786fd04b65911027bda56754067b936ceba16bc89221e7dfa8dde48fe767aad4af3d82616091460cb507dd43188dac603a37055974e1c1649bec338d3522f8d81c266e53e43d3b4c5bfdf01613dfc64c7eb4b9036080eaf62819e96411597a7c897a10d6e43bdf2d8dc8aac3031f2e18904e77f4ea34f6ec60987db4fe2ac0c2ec69df63b9b26a74c0d48b27e26df9c6e8454fb70ac92f225264f6cc1e47a5da6433fed44ca74f33eeaf144c744c012995e30ad22a32a682e481119f1c0059eef98fe35d8a6d89e5b1bf07e46aa2ce30721e19d56f12f55f915d2f4d8ae5f052a9fba6cd54bf161351ac8fb76986fcc0432de32b7870baa45c484dd330d409d9367cce04249f5f4b44890b2da0f92f855472839f121316637701bde0ca5290c0c5cdd0a1320dd5d81ffce55f2ac0c832e48ee09db39f8f96d6e8b43ffa1b14d65f32ad9ac3656e88cf9091e40d644f5c68511e266e9931784604b8080e05f27eb1688f68f220cb6c9b2880c82af62f98e72146aa68043034fc8ccfb75fcdbb04431d835ccd0fe453fb89d25df4f3ed8abde79ab885c29600a2a37414208fd9ab8951d44933687cd574ee32034b153991f166c9f0e52f01413ffe661c0c423c0a45e9890cd7ea63e015aa61d8d1e60ba1b783499538a26801372a805196def042dee6d2773d6384e8a518e8528309df76640f1a14ce26951c0c84a3cd85eeaea71ea8e7d0f2253c8dfb83873ab5340e509e034087d4030571421cc2753fcf2bf693f6c59c42aa61046e440256a413fe8da9a25c37f880e4327f450711d8582e4fb6bb934ed24f7e70f0191067cfe7d6e578a5402c933c2810b3c7cc91da1be0caea91bac13920f7b24f4bb72cd0ffd91748386fe8b273ce8df1e53a067b900823d8935dccc3084db03213e1dea68c58914cc0cab307915762a180feed7164f7308adc27d911b07c1bfcd80978e434cef226b31c98a4ed21e60b1e4160fe9c02196988e32a13f44f9db2b2ae474c3f04fea6830f8a7ed1dd2b30d4c38d9fbb2ee12fed751493fde323fdaa8b4956dd2d774f4b5fb0073f74a1bde189073fbdbeadc4f9b5e20a14c8ae683a695a031cf44afc7674c5c9ec436360053fe71865a6986e9a45db651dd81279715c780a43ea33f1524a80b705c9214b3709abdb18d0aecf2f8b3a799906d54ae5cf83d5b32f085954fc9edda6754312674ba5683d22dd8c7ff344d5e4d0a2f1f8376e3700a757c019c12f3c7dfec70d6a9f3bab3433871a280b8ef77db1d3841711e31c97b609571bb01aba808656addf8859d815227095d705bc1aa4ec69e97c55c6f7b6c4802cd5dad03099ea4150fc73fe7d1dc33aae6769a75f8d93afc9447f4f8902829f2717a171511f325088509bf919ef2313a6caa9b730621b57d20a045e8f205a8d83d9793fea401b446003962683f4347615029213c742ab8e891a5e78975ed5827f919cfcddea1af76533f1d904cf1bba004f5e76944c36bed6aa9355c6ef25a5312b98be891d56086651d1a9790b4a63fc8d27f462eea81db7f62d4de037da3ea8148d0d8fe2a7902b7a1b1b9267500b1cdf35824c28e04e9fb5ae237bd38b4dc8b709fb40d6d8f16bb4c68fda23aafc8725cbb3f8cc602b4540c7b4c3ad1cb18ffb80a3bbedc01cef75ed632974b2522925596be99ae6d3556d919194708e2609c3ac51f3ee5db8d9e3d43cb6727b918ce892b524cfa4b78f245bb1d1d78ee63e6e1b5748629b49dad144acde8e1a735ea4b99e02b00139c4004b5ec79f2c6d78318e536c145eacc6762ea90296fe9e8183c58a00e7b6f0b59dad8a74dc16a410e0e231ab2d46734476e7489962df8724d79ac5582e74e02cf3c6fe73cd06296d80ffa5efc1c507f1ea2d4e77e4634e7e6a213a18268030f5cc7a72509a406e3b7bc7eea06006accb28b0ea058bb2d8d2c39063e2cf752805e3cb8693fc6c544f033fbd6a32ec6f535c8f219f93018417c045b23e1edb615a1683c61c8e1c84832e76520e33a3d96152b81a59112c4ecbaba5bf868bb05dcae48474d4a750724d5f7b3eb6ad7d6a47b561b046bcb811b952e482b7f3b057acce67eedc11d04e0795dfd049aa80197f7385eac27a518a827bb4e314b9b7811feb3dced3f92b7f0ee5546b7b1891dace42fa0ee374f84f25eff322311334429af3eb813129b2a5777fe715958b363ca5595e7d1124d1e2a60a9bb6765d0c8bd2f305ad04c1cd41f01d59f67f50a87ac47a0ba8b68958e58447b0a9496464d33317594de5e29aab517366afe3865c0a46698a8efe1f366f8878c6b1630f7fe60bb104d7a0d3ce3645b71f6e79c1b2e795b95954e24657fd6bbe0ac6b11244ae06157f2f56a0fa4dee9d5b1300eb8072805668237b5741facaa866c80933ead7d32e5b080ea9112ac0d985e9f0c8753aa693884598b3ad395ff3be95888c86cb5d514320ae1852c08d2e0ed473aade52d3ce476681838b8396db01f87e17cc4414f3ac05dfcc251b9781260fec220e08dc15fba501ad5343a5d0850aab278ca22b044e8674ce1c83dc45328735f107bc1d78f483819475a421e0142146e44e0f18deebbaf12bd24488871f84d387dc7e36db0aaa1c388089c49122c37e8fe0023ee3df0378ad58a59d8b18bd1f09d4b78a0033406e10b63c1bce0fd46274ba4bed3c380b8daaafa889f17e930b9107778c35b45c1d704ae6602bfc5498e858214a34a74514842e8def320b00abec6fdc1e967d5fb7ee738111e2afb1718dbb656fee3df8f1df0f53e318e18bfdfe35f6736c6163f430af26c6219113cb27798badfbd11f294a059e49f3ab153a9ade3e3ec8dac4586ea9a6b3ec427a1821df792aa311bec35545d571965a97391e76000206a0a6d7caef36116603f04f2585885768394af4a2f8c8e4edb2d375a06aa94f75cf1392551e2b61ea90cc80ee9bb6bf1f273dfe90502517d1956c75ad87d7d9b86e9cfe2ab21324157eda30db8f82d6ff6e3055ca96f643182144716a50fc9e26cba66f4808ef7fbb1f74da4943b5844b4ab36b7f043d68cdc56910a02bbafd34acc2292a20fb2703cd4c5929993c841207f4121ab4da4755b2648e02bf826f4745509694457f7ac8228e419ef8f16e89c846abcdba6f36f137a3c88aae6bef6dd7cbd9e7d0d04d8e50d180c0b515881e17bdf2854beb00dc01b08dbd493c3df48c558fc02146b1002674af6a65b6ce53fd90f5a22dc2a8d6d13c2ebf521d95494209c3377ce25ac6dab939ab21d63e38e00ea1ee79fefb9845200dfce625e364ee0fa662bcbcbabfb3b149ce52859f45e7f3e2608773b9bed15346fb4e5c2dd73de000dc0249f20554674a733b31fcb11557aa5de7799e917da9350615a144497975625711e8ef28147d18e1ea58b6344c979ffb9ca9c84c557d872e271670ee2003b904afbe664c23b20d727145bb09f351ecc11635a3a30743cbf24c092d689cfe294efdbf07adde46fffbfc76bcba7bfe1f0ce282046d6086a9ed9afda08bb411ae57882074b8b37980a75acd2a449f36b4c0a67e9ed81dd93258602a4ff30e81b1e887d7f212b5a7575ac8b121daa56b8f19673a68475e77684618d88487cae09958f42916b07ae99cf06c6bccd9d6079b8e83d00fa94c064bd8659267c11de9ac5ec5327ca416fa12c661c4964747c7d0779b91577c6805807626e907fc5a32806bbfb37410bd3a7da038dce9dcd9de5a06e898c0fee310e195cb37086fc92d12a21ae59895dfcdf45ac1234a86218a3ae82dd395d675c269873cd3b2c98a120f42bc51a4320588c0412c6e3a075407f13049c91e7d8e1007df0a33e1e23cfb9a87ec1938f460f0e2d5801445f60d598eceb0815d12715e41bcc70d8ab1ef9f8508832d6eaf9b5349228a80952c39ebe8ae9a3a292514e2b3011f12b6ea9f4dc27a3564398a8ba697ee685c6d6b8547d9c29a98cd7d248f559bf3b8a7f7ee52f78a06fcf24f16b755ce12f464f9d077f7317e1a1f052d57286c5c38bf240bd1321dfa0257481b189c226242fdce35a198180e25f971130cad2e16295bc872698f9c1725e91dd732cb7540f748d1f95fbdc7d1144aa89dda555ad082742a00024f631c4ee3fdc85f11f3de4779756b7429c68ba55cffff1b25c89ce81d13cf8a3246b040056de0c9e936fe5721649fa5f4b7182234be1d9046f08e24907f2334cb3d595a9b9bcb1d19f5171b0d74a17cdc1d40d7ce6cbe7dd9e20376502694e4c2078988ed0a2f9dd57030d9b33988ecf95c090822043d749c9152f7330b46e22b4711a5ec034a2847dd7531611ac856e65c5b1ad8f154cff84bf3d5b082f61390ec2cac209ab202237217c3e8bb5b450f28097801452b2e1c1b953b836d5c129d4be88edb18bc2ea997cd98cc191d37d0fd2eff1ec2ef526620c3a0400d1129adb96047e58993e9251dc0c47e00c94b8427b05c024d4b486d671a731e6c86fbfca49129b0afc90a3ac8d42f8f4cd281f8479fe062067f80978b2891561eaa5f6c14d655eb9f86273efdbdad15fa65113212b9bec498927d7e118a25ddbeea6e200079315832ffc0ecee75a04dd2d061dacfbaee589069b0db296722119acc664a8ab42ef68962b86d8577b722fde121979099fd9b10bd2555fadd80d6212291093edb60f07a4516d9c6f3ae1c23c8cbc620dedf8454e83318e7a4ef29fa34518eea7766d268e83a343f61d77162708e1ae656075ed57315a0dbbaed93cf43fc9693ce7c9310891846cbfd6530302e92ebbf347945e45f1543a354ae7fc4ad5884e0738499f9a742c183bc35c41c8faa3265edf3bc2b34836acec425c010d5241eb2223b5be80aac2869c0be6ed7c7d1d48c6938402f83f06850b311ad6e090a42211135c0fba6dbebe83854c1929568c8a865b94b822c0ec36d470fb1136a71250ad730928a29e85da5992536ec9b99b1ce2930ed6bc9fcbe00ea1b7556ff30de9afea1b8d9843a7869d2737f791958e8154021579c38c7aa150abed60d08ca7dbb0afd42052dd0c0fa77a1d9ea831d50dc92abf554083c30068c97bee8aa16642e965e68a9804f5055062d6629c43148334be6e0712eb5c77fef2c8b508d869bf7cd696d1780b064af7e68a6105172c5694f8e4265aa8b76da3115b102e13020df1f38ab51f7e5294aa9bfc2d2e41df33c480c3f54267ee85325fd1360c20df0dc31dc02e8c1b58c9154d4cd3640fb86bfa4b34327c4711acd63c5bbd0211551d42f7bbfd14f822d03e1f4c80c50bddac451a163172c42df1e0a26be4fc608034b5b43740b1e202ce00c079abc9825bfa1328c799b772084e12366d261fabf0a62350aa2bfe1a8d9b0ae13f44f8567539806bc5348337ca8add34585dba9164c82080e6420a3cd804afa9dbb2509c396ab237ba1a74aa443f008248146bebdfa14256d50c3ee5ca0ba0533a64014e1119a805f0c6ba0345dc1d8827cb8eb2a315a91dbcbca16e2c22a97e994120e784a1f3703100d5a656bb0804967d4461ab37a6d9a24840075bdeeaacc86ae780d4cedbd9e5bd3ce7b1ab32ed9847ea387999650529e2ac6c694e6aa30370f9c41b79a659a520b1ae7b046486a2480429580022322982913b5b9eeb190e6567b509abc4ec5998e58159835f967d840803cec045884476898bdcf7fd49aa546b49c6f4b07ae76e85219420b9f740da060e4aa4479e894421863d71d9fe0991b66eb55805a26dc5723dcaba72d780e1796ce7d88678b1d142bfeb9feaab04a3dfc52a206b3571c088aa7b142593fc24cc71948066e9741a5356746b2b0489e782892125d72f2dcc116d591bfe20ab1de509c7bf6693c00800580681fe9ac7695d1cb2f44a08e7cb3303454bffad00c943b9745803333498e3fa0be6472e1c8f0e37956ea62a41345dda47f9a9ca14f08abc3c6f2b9ba79fa88131186c74673423025d3be43c42a0dc6f47f1c40bccd4f51dc8fd906ace6f87b530e7591b80601c88a509bc10cf1154da097fe4d68bc49f09ebf38e4cb9f2b8a012ba8d318e6bdb23c39809083f118b1424987999197d515c30805ab978ed09ce9feb90b3528cc5e53b2b5eec23a3156ac8674f27abde912023ede407123cf1d7735c468a599f0b8004dcc6a58d2ad03027ab7d4ae653de553f80a9f45585261f731afb21418699ac79137dd3758891260b75952035b8916604cb6aa2fd0332b1551021aa714543b5a0a21c8e8e0fd07e0c9b0f1c72c14b573ddd4c9b3e4243f7b336a27cd94f4ed567ed2e8829afa01e1be1eb44a07b3882e0d93840cc36d574e901dee4ecb0c3fc11b3f74546cca384845ef121f1f74ac0b257b029db3e8d8129f1719125f147919063d44025de2039e5fd26d6b39250e1889976287373fe38d667e259c5b61058a725011694d6fe0e2832b12e2f227f74d08dccc8f6abdf29c5b00e370755c5de86c4e34e9d8579eba569c17f4d2a1076a9f31bee0842294761077dc5163aa7c209bcd85b2d2d944d3ff857a80af2972c671dbcafbd301dd0ba0aafc5cf585f0637158435adbf0e61d60ab29418ddb1389609dab1e2120df2f91468838bd804bd2b13cd613fcd28e8f33f6b89c6b02286d938ed222491dea1df3203442a0699a1e27bfbf4865a8add602b1047901281d7ffa9390e2b66a07d5584f32060bee4ad19f2df8fe16e0ea5f9be1a96cafeadb72a9dcb0b7c96aa9195645923042618469ec3647e8f296bb68c56b944fd84ef738caa2261f444a22e704d994eaa82ad689a2bd540b474ac43e75e2e8dba1a88f8f007759a867f96d31ed11f3e415cb5b7f33d4a04de58b0d9f36618878d59d418dca9623623d7dd7a9d4547268d01d63b4b66e5dce2c823a21d22ed67f7ec1525d3e6e5d7f9d8dd5e96d710a9d405a31315a30c4cda8ff1a21e43b0dece3ec26785abb3e83d42cd846f4a03c71f23b4f027461997df1a96c828e2b81295900e77d14196c9eb3f89753195d61342ce6123509f40fa24c0fc18fefbd445a6cc9359fdcd3b7992913a8bbf95f0aa4c2074e78e280dc8c8239fd01b85c66e42e9e659f6cf7df3c1b4d250b860818a5b23f84580899c3cbf6ae7993d5c68d74332dd9ad899a1641ad7de5e804779b698c281f4f65ae9713a90af7d68a480503e43576a1a4fdd09c5e7f352008d1cb676368b560aabad7fdd1a76d7d09f72c6836dd1133d0783490d8b704aed2be4b9a69467c178d0e96e1143f0f17fedd53951b5427c1c42f46a84aac987882f26ebdd0500be0fdb06e4ec71182e4c6cbe508b41c851b9d1bd31b0ea02828ee9cef5b2ee157b6d360f0432a586e0d4bc5c8916d79223b2c698a809a889b9906f68543b603a808771962102b3d12d2c123a7ba259934952659fc79ea19e4ed5e60df0a3ffeae5196ef81cf740cb412b9559c872b436a9f3c0af9cd71411f16100490cfa3b80c8eb97324fee245b42f61197756bb11a14b2784e1975f3e382f1080b6d3a0932a3d08ad19a32b8f8229a52effa75e539026575944fde603fc7e57cfaa9694d7cfc37fca832d01b0569b59f78f5a911457ea7e5bbe2a14455f2e15ec03c06413ab9416b19ca92b232685c485c0bb7991e12473a1363cd70529be70f89835daba03741634a754b852be0b3af2dc32d0e2b56eb8adbbc042672bfff4456a4303a9eab8dd2913b177a0859a48fd1da32b31589c3982d44e6c8ac76a81c41b9e52ed39b465ac9b311298f3e9e6124435da7c9a0fa14d217532e8add241d846ee1bf9d7c69e963cbc502a841c0b49f1e5ce6d0622af380a7ed081d2427e44fc435e5341fac8825d18d963cf3de81a048b4fb92f83b13c41fd97a69e20f7ba988e76275624f8e3a60b7f6eac5739d78cbfac819a941a97b376a534d0f50fe7e6bfdc14fef08937a8c4d1a2b706ad79b9582a9d3b8c1ee22c95c2d0919961776703a40c015581babae011c8c6106f77ffa8c4da1a197e2d58e17ccd1bb13e1527f9f28bc350fc7bb47eebf1a807bc5f4c54f11ce04f13fefc7d74bd130b84fdecc512061fb9f2472756fcf73c0a33962d8040723d37f9af4c32a039edb8549feba7e5c5b8aa446c996184fda22cd2c26e5bbe8297cc63c0480f7715538526ab17b28e856d3d155ce56e5ce9f62a395028bcd27ed8d90baaf29edb4d7b1ba97ddd4caa50882ede22ec272df46aba69182e4940cede60c66717a4aea261157444bb8b926cd609b3232b1c2985401bd178bfe26b8fd42adb61b7bd02ee824fa1dadab34eeb655289fc56da997a63c328f3257dc1a836c55e3909d8122b316f813e413e562897c00f77bd7206fde198ec6fc418b5e00f9523c7bc302324a9c2a1bc31baae67e8e9e704216ca41f30a4ce8b0d951964abb182d30c0b401bb886f2557519872676aee195b8703492c39a7cb9e1eb559ea5c6eb32faaa201e39cd59e1be1937c69960e3b3851a362dd27a9fbc6c4b7508dc6bc12f3867f007ca9a1fc49ca0c637a68d077f6dbe991e721c838fa3b49c90d22ffe5b7858cd220d7ab7a62814d449571bf0343cf59cab79e5892ae7245a7ce9285a0ebda87a4e524671080722f18699bed10a450ec4c203efe3bf6df3240ab183f5a2da1111b811f8ea8427a9c6098009bec08c3fdb25cd04e21dc868a0fe3906f9a455380a487a9270cb87adb4bb21460c5a89da3f48aa4892ef5bbd4c6a1d0d118e803c09c1d8272943b68c521686ecb3612a7b0b79b61a317bac3786294dfdb6bd13f8fb73bbedab5042b1e4bd36c26337a1f370b149a6482d3fab6fa6396678ae40ab015eb3513d5864047898ea33b863ec78ceefda6e8eafb0b536be1e5327682d6c908cc2da6f0042db40b610131e515b438ed3f6be66ad1829fdcc35a109989f05b3728b959249b917fa7bde22ebab1836d82c878d27c4a9c9d5e0bf906108b79ada9faf8750c5219b83e0ebd835106d78f4d37064b0c201ce56944b31042983dffa1af6892e025fb3342a36a58a59f582f2fbd7873746c9808fad185f8dc349532cbfeac692d96998c4fccd2badce67d62be96e57df613268a56e6b39f685294b2f6ece7cd55d3986570f1d8ce41cc1a7bd03f9837b9300e1983bdcd95e3c91aecadb8673f0fbe0534473d55627b5850198d9ba7e8737a3c26fd31585ea0cf6b26d5eb652967f90df570e59e4ab882c573832932cee06651546e39b21379dcf6fc2178b64dd3d73424b9fbe6244d4be81e0b52a27af28abbaefd266940dcb61d96445cd478093c58860e2bf2472b08ec7509208a2be82ce532200a2bfe3a3cf6408c0e7d8004bb20b1ff8c3c25ebebe1c66d296326803ca7b46351a35e87e5f8ad2fa738f6721b7da1677b8de8828b4415804c28f5449a7b69f41283747c6128df1e2868b90c6ad7eee521b726e9f6068305ae3c219c6e613d31185c8a45575897ffcf5a97dcab47059b6e7c766fcc5123225bd96e65dc73e3ccf9ba1ac4a2b39649fdb52413f9c06cf49639c0a3236a71d61055a5a1b60495bc743d6137b77236ca2dd9893284964ebdff3ce759b7da275c413203ed7378891563adba5e8db88caf839ebf3d78a10794fc554f304e044ccf7f3a19eeb28c8a3be953e32e95f67cb239e93594fe77405201b52bd1d349c1cc4ffa11b53ad560f5f9989e8c96c50a8298f385851a93fbfb6083199237ea789167c5825e40c2346cd610aac719b69cafca291ac9cdcfa353d0705f76d56251b08cea3f17ea8102009a73c6490b9e70ade64ce4a92ab9a24434a85a7bc2c2a2901cbbaf524441664433b6cc089264a824ba438fb3f3e410f14ec31aec11c82ec0676a30895dc6a2f9cc62d4fb59d68ca53511169fb1b96b7c845731a4f4c2ba6f4f7758bd554ccb41a4da3bf14993752f703835e0e92215cf6594775c449288e9615e2419d68697448e79a8f8bb6249f48b6ef708a0eb054a0a256b5d8eb9516424fb23ccef93d77d38e063d0ca46c053146294c32becd0540a042238d7bbeb8b78938b008b3b78eacce0314a4204471bad29898d538f2ef0580ff4751bd10f584a077f9c4a853823877f650ab18ace0f226530c0666035247ba137e6e2246785ddab39c8799b3a10a3ea1f50c62696595e01ba752001297d9168c22931f1b2d2c986388c95131585602864c9b4f7dbe92b1ae1af7af94c45e576d79b5e642e907c8e3819b805b5f86b2158d4861153bf5522668307645b20d70abe0e3de8ed475f155ca35bf25affaddf4d281f0c49a4e3b87852587b4a7141841cf72b0a99054863a001998b9eb13599b778be050cc28ae5c2db047175e97682dc7e2ea25880d1acc99ec6ae743e34013a8d4031334f69720e7fd293fb26308398e1c56c33982bb1decdb12b194e3b8e78e02e907412bd34ac1374dad3c0cdb54cad1e4ed61d9795e36e39532e6c4566c8f6c991cbb0f30d770ab7eb3674eeef8c4e57f071a8b65bcd88e0038a5cc78dde770974681736df1b5ea494d36095a5b08d18229b049107605f0f31d6483ad6949a97d422a3457e8c3853c5c583a0a41ef7e02a4625e36e2150a138402c4f5b01710a5bfd6109d0fd55f4c53adce16d00fec66b58b1c2e220c4f597ef6360c68d5c165b7ca780e39e6af3164db61d9439fa22a90c6df86246f4a3d01180d739cbcf7d680a1385420ef84563f358af7b2a24d0fd9ac133fb386e6d4dbf495abc5b609576948fdda760a1dc46b60e85b270902ab762602021eaea2e64402385697dd9d9d26d362881566a49dcdcc0ab547fb7c1e5ade15d5ef538581d5b52f8bdeb5791f68e19e9fc3eea77403bff8b3b117d95537b7da0141243c8665dface445d42175e100442eebd0fd45fe069be449b2c7f03db7d6e43c5d7fadcd96397984beffa31c02dadfbac0a7b4dda03dcc1ba727f7f06647236e75e4fd98a0cf1ae84d712a04fd0b2ba227bc0ff59c20a0bee4081fc98dc1f5a11820fa01d85a68cd9a23141a22b8f951074886aa29a49a85830235ae4ec3932aa8652bfd3260154b7e78332cd4a231e6e09f200540a58c5fbd4fff3a7f3ebec6fadc25b18c017d3c0bc125c5d53ec0298e1993116a85a256767a9df6c7784f2b699211dbd990ce299c3e73b5ae2c0d6d90a526b0a5573e8823ec8b66a9bce469b199f0253acb36aa47e42b11287af8f269de8176aa10d230c841ca3638c87d0df1a33f60b868747025eaa21fdcaf120eeb52a542e3a2954fc185bc135fdbea0877c5601d582577904e4ffc430c18a79ac8ebb1aedfbd0661ba84e36c51782f1a48dcb839cd7c0327244227feba557c4abe8f208dad71f07df771b0d887981631250a984b4245ee568404a5bb96c5471542cd9f475bbc25204aaec0508872d1ca32238aa72a553691b9f7b6246025f94c0ae11f8455c3b60372c2524edc41bbf48f48dfaaffab213cbbd0fbd4c5aaa7520619f07db51b89c6c12ad97ef0b883dd58c2a028768752bc4e76a3708716d2cf88b5a312c9e22a571ed5ed6b07ac670b23a7343a3b9171aee8ae9737c1a3c5324da0bc12fd260d61d8a0ac08960a9b9578d08438c1d5e7869e005fa7100b22383a54fc0920e71157bc1fba92c9e534d4020bf942687f9c2cb06e26eafe3c777d778597647c386acf43698dc84ba1dd3ab33f42e021c00b53f66f6fc733f627269d6c00894557ca7750c6eaf588e015647a4d4ef424008ec9965beb8db3b4a730af2a3065ca62506b9915f5eb0dbf9766f391ba890aeda9d8051c776bbc059fc598b9684b29ab4cd352310e3e0b4c616eadbcc2c8604a6f0aefedd18a2f7859656cde4e055014e7401dd5a703ff340734a291e46959350ce629606ae48b9a6e3a4a12f47215093fd1a5069a4f87348baed94ac3ea76dc5f9c67d00fd4add3d61daebcbedda2da0fb14c5930492490897c4bad9b5e3556bc73583bb4bb33b7991cdf23734497bd23c18ad3e25b40dcc9ddcfa6354a3dcd6a7e58b0752f30f0f062079e6ca986e7e2a9a52f510d8c7c807bb4136594621e676d61ea52f446e942f9a7d0a02d3256f2d9bae517d66fab642585a4b391f0b6d8a2f4ec374024303f7c1672d145a572bcd23bb4580218839295c9ac9a9946d180b2bca6a14433252f838f97e3985cf1cdef8136f93a0847cb980b2e11398189fee9876aaa6ea3c9333e37ffcc20d56bde47f973d1eadd4391b9ebd2e9bc210f957d09e5ed25fb4a607d6de023f8c80eacf1949d9d008396a7a6163f0b8d6ef37e800e508d41dc04d99d9eea5794c7e61db95c64189c4e4bb90557b0068046de52a38f6bf094a0cc07ca953ff29fb8f4c6c6b2abf74256a23552fcafb0a089fefa2547d5c3c0a85e2c31523429d66882757d9908ecc7cca8773e94d327f19c6665cb2d878d8e0b6ea7d2611418cb41b6fa80bfd1f13319b312d4a6a02b2722d9aa0212780cc03ff69d044478669f41db0ef5e5b1f807c439823e3efca6cd25fc6bae13c1710bb3494564c5c3f540b66fd8834e21cd5cf78a488e9368729084d0c8d4651508487e86ce96d27e69c2c111b8612c82d6edf1ffd56d57e374d9cef13ed58e44c98fc8c5f08dbe75c8e1f567ec35880229d40b746cf81da54aeeac3b79f2694435234b316b95d64bdeaf020391ed2ec705e2decbe16d8731d60d239e0c122f413c7495fd132251d606de285995f64ffd3708e85b31f5dd82a4f2b13a2d76ad3c18814ec98d42af63008917461d44730f7554488050fbcd3557750f704183ccd6ae51497104cd02538872ceafd2c87680d1913da2deaa992ca244fdea0349a9f04276df889d57941e259dc0f57194e0853f4da8dd057dd80fd4fd2e2e2ca17d4a9efe34b6e7afadfd7bf0e49bc1207d22a9e9feeac211d0d5df323e76a53603900e88eccfb81f74ff868b34c7028681adf48c2ae087c0249029278cae2cdd0fcb240b129545463fead16ab7c36160d9d4feb4d35cc143eb189fa9500c01ecafc5898a0d9711f135e7139f636ac08d4df377c344f61bf6fea92971d93f8019bcd004ceaad08b234f8639856505e11bc78fd6277d0a46531fcd9a5918189dca36654032f44a3ed0d8deeb1f85c7f49ee9352ee6648e3b0ff47bc3cc8dac021903579597a689ea37a40d6ae7230c5c3bcc629ebc300b016c8b7fc7ffdb66e4ea7185c8c3255a0732a1c5cc00f41f724a5a8e4fafd9e796b6a4773737a54b2687a4f224b70b3c0ef2b6272a0fb09d3276da096511f81d25dc5387fe8bbd07de56306f67c97f2030e68f666dfdc38b980637fe5d4f877f5f29b02f0e2fd5956694e4b727899f7030eeb465e516110b41057879edd80ca22fdfcce8516c82bed2f942a13af33d1b78ed3b7455dfeb3b1e40552af1ae28161182ce618e8d90f913cec790b1f0af29ee6d3abce7ad147777b21749eb70b531fbdb718a750f9292f31d1070d0f7e8b168d0ff2b7527f047c9d171e14b19bc151f3f2818a2f1b04aaa829a2c55e2ffe6a7119a88285ced8badcfbc8d14992912700bb45709d3aaf76c074d0d84ab1c967dd644775c066cd8f7bd065afaf3c8f46f0b254b4c442de9dc3b328d660382e78790bb18a23642b75aa6acec373eda87febe5ed623cb60aa0e7e2484137687b7b843766bfbf0a9c8e6e2b2b72af407c4f26615157b86b0867cf853805d3d49827f5317efe0482a0a59b61f8cb21098288b67346602d37e7ff6e736b0ab770c8e7574a972031c34fa84201cb3ec68c7b8ed1e0892de4fcde3dd5433b1edb6ab6acb3858873465cfc75a844af5c72e47e463d85597c1a4487b363019f84c8e4214a16b8e27d2b883466e9fa0192f2cd06ab55188c81601250458a4c7172582407ab6dc717674ab4771b1b4055102941f8511ec7c1a710e7b3fb40094a110ef6883eb7a2a229b2320255c58f62d16e353cd53362c3fb9d2ef8d30f6f092a740891c550b67e1fb66e0b9231960521bddf09fdca19397511bade335686281a824807ebc6eb73b0eee87a9b3b57a4035ac3b3add7f90f6a1a19397cc91cb7c51f50b4ad756156c08c18ab2e0cb316b0b703f90db682571642358c2d27acc9fcadc0d9b672bd1bdf89f78c74239f1b5506d799780bc5628f8a443780d22bd2f033dcbf4af2b4b868063e728b2299248843c86e971f92f95cf87bc1de177e797870c47e9cc666a482c18b6977d33ccbba148f07148a1dc1df5fe2b4a6d537b87ff9e540c8983ecf9021f221458284c12e3dcf83280fb1fff38b847a715bb0489757e8fc82963fd3adf8dfb8931c5f0b18a20114594a86fa8f29b077553d5e745fb05d10d2906df7d9d4b6ef5c37d9e2984905c4675ce7330715f839fc9fba5dcff6b4d3f9860ee270b992d5921a804668d1163eaeae24b79861ea912ef8c932ffd8c3eee16ca2b913d055a4bc1d31de75adbc0396c04e0457e499e6e060f8f3c114970dcf3c3d360383cce389b649037183c4265a5c1c47e0941996b492b2671de618c41d6812bfe4adcc586363fdd2a2698c2aa111b39100b2e12836102e915437b9bdfce72d8ecd9a8506e61647357b6612ea6f9b7dc720f0dbc577a1c7b1187f784d8746dcb8eb76610e3cd9d8d3825259e4afae83d96beb9b6169c43b2fa87755bb0dee879390925ccdf5ed4c545d9442b0d6ed0d21c7109fbe8abf2245676a4a6327f3f110565d8d113725d51facb5d5e2fbae55ecaf4eaa94524f5e012f07803e1cc81dc18ee26f7a6f9cb2a8e7bd4ce650c101b400eb6680f4abb2271e8b8a1de40b99e1a81d33b315091a12cf74bf9835b81f3f47be6bb16d1cb79725f0d412b10c8fce49cbb121a3ab603b8c8a96e481546305255fbcd3f2fbc63b2d197f4c641d9246a8cffa75718b27f01eb25a077b4332f88e2612947f469a19f1bd9e501101e8e48808e20f46368e7d1bbca0146af4e805d6dffc30199a6bd879d3334535d249cddde8ef98915e03592ea6870f2a065d106a2f74c6263c6cea58e06b35d4bb00e36c258fff38f8d7e2b9d7541ead2b4f52f8475e3328fda11b8a015d3918f5f51149306fa3172ff26692904843df2e5e898bfc330b2c69c32a2f86c327adb760c0e8c2efaddb7a85e233b50f29aca086138a8f9b34324f3b5f29e2995d454927d16f9cee6fceb3b496897af17c11295c61a2ab1f07e4063ea0dbd72f5b8e0479f49a6720e70cd8912d9a1c525a38bdc30b41a994c38b1083230a1620b08a4a62ef66fa085902564196d9c072d8caffe117ed77686ea7abb6ffe71d02622ee1dab2ab1f18fe2a09930eeb72cb84760bdabece292bbefc441a285108d764bb0592a03e4c7efa2ab222cc2a92a0ea27c7148a4bae1a5dc5138d8bb01dc0ca3a01b4db420b84ebf34f61ac5cc8757a623906ef4d7e052b94fa38ea9ed564ce9dc16b80066dd5847a8e59711e09c4be695ea7467273600df73a74b4164b3e0a3f116a62fda9336dce35e5065987a2ed7de6f0bbe772ab76ac98bab0e967e9d5645119a1bcf3359954dc377594769b55f035180ce4399008e471b5e1c0f512ff762230d17183776ab29ae01c0675c9cf2b4b48e8157fb58412deee2406e41ac33f2e8c7dc585272c31f0133e3a2d977432bddb8cf5b5abc7bf0251d9ad84dc241f1f1fb6e952aca45aaffb2283fb967f01e3cf8197db0418ff6cd785b69b6dd2f91b90352efa10f18f989d7beedcd7eabc4ed1027955c0e295b5655871091a2ac8c227dd9d76df353763f7fcb880ddd9a2f5f40ed90a74f07e0f7bfab0562001d6b8c479ce66c85937dca5a13bce99737b1d8d9295bd2a9b7faed750f1171ce1e8ece8005caf71f67b859bdcd2396637336ebd7e61c2bb869bd7738d7d51414462e6c3c0b9ea934f4ba6c5fd08cdc8ec25b01c5d5795474ba6ce5840cc479d91c206ca09770522dd4e81458a0a5836b3ef99ac3028532e1422d6feec7defa1e353323f4e908e17e60d9c7929ceab4514e86564e78c97572925bc15fa51ffb86f7c0b0bd5260f3009dd78a43f4d5aa02b3e01817a85776cd86186867d3449b88d8f076dc5a64eb006f11c88015a60dc41e3b413209f78ea2161b770b083ad4b0a0217ebb91a2aa396b9eb31d310e7f7a3f4c919e2a08dbf14f56c1f41c0c25027d29fbe4cb7184ac10d570d603faf908b78cde93ba9a33eb483988ec2364058929f530d5b89ade262cf762fee05b0afa79ee3a8d7238754e743ea280bae2fe9eaac6649d32baaece75a7f0efb4ba41c0e51c58f5f5c3f7f4c2ad71ef9dafaa4acf26617c40ebe86857aba475cf9195d4106224101929835b1b39ebab6e0e6698803d4ed0604dca4e67abfb466d0d05871c218def3b28a8c2243177ad937448310c20e8c6ede8727df1971523397b9fd51900958a511c5579f9d550410b7dbb45425a2b937aed40143f4dfe368af93820a34ae43f4e27b7aa7cc746a364880aa0111d08d4f4aad979448c674397f2dc080fb629856a8d4edc2ca1e4b320627b3b805ffed97dcdc79fb547b43a650eab3e13880cce07b0633404d5d1c9b035f7a61ac4c950d666cb6666da9052098177334420046480a75685eaa1a4f8024b8a47d9853eb6c933b124353712a9d73e2988ed6004cf00bd77c618467ec3d9783397ff6b093dcd36c5dfc247431273b9187a320dcfb7901747376252e08e9559ad9950e9f5205401467ab12c6faa72b66ece6de02578904637882069f9ec262ddaa87754f4b3fadea89ceb5cbbdeed06595c8c2f4c3400148f9109e6bec60a9ecc52eeedce6cf22685d2c38d058c1ae67c737be7f3e47fb814e770edaa72a9c147114b85d2d55ad82d6c8be3ea70ac216683faf524176d511bb4dc36429a5c7df1424a4ad357942596b0af95deb6c85127c8e2acfed525b8c1247c706c11e9557096a9d91baef164960546860d9bd8699391f35a0705a44a2d94dcab827d07c790672711900fa0c344aac8cb6c2aa566e4c30305e8e9e70faabf42e25008278995f613ee8b19b64a2d4044fa2c95d1b419d64c4ba47c86d3637bdc839cd767a1416f28036ea2a2259dad20e85c9d4aac05931273f80ff09e7a4208f3cc126e9f435af39997e031494fdd7e375420df15dd2194dee085e90161eeee0dc5382c9f40765bb5a517f4edb4c1bdcf774eb8b5e7c10982446524e9a9fa043f8adbcbdacd1e24b049ceb27974bb1bd5892c7b79fe6ff360939497a53bf97c78169f59c3011030c648a0eaec919fea5127726ff557d70cd9d09ed719c96b43c4d37883aa6b384d2f802a5ff83a3b5fb7b1174bf19ad7af2c2033eca640abae67424264728ef7d41dd526d00908e8005f48125994af20af04312f80d5ca9f5d7bd145d889f870d99b51c818d0f887f76405167d89085569e6517ccc7f5ad247d53005c1c67f4ea399e8996071f172007175a963381d8cb5f8e820032c75344d6e4723e7336ed45d1d3255bf6c28eeaf7f73eb8a58e7cc75d487b71811ba5318e8785dc090dd03552b6e7ec8741cc18c8ca50c1227c11d0a2ed79f864e41b5f1c517cc1a7b55dd87598e397239cb0a679e76991ac511527965d17068548ddb6c181b1c179b9f3c8e1a48923b23ce89101b3b08081a085ee99e4bd9d29db4d7058c96cb0300e48d077aec68bd97ea0b9c5516522227bd65262b4ea35439cebfd52614f15dc8e875b73ef50ac8a33970fd7190c4e17541450c7200ed70d142f917f0afcb35d94a6266197eee23ee40547aa90304d3459eba8d0593ab52803fd7bc15c798f67ce95471c3897f424ceb661400b8755f9c38c117ac9188a51c042e53c854d15a9b9906b8b759f4a206c1aabb14cdfff3993bee06609f138f0c7fda4d141961dad0d4b3684514c5482e63857b0733fab52e9ec1df74f15169217080de27a1c8c2a1178df2461ae6019369223391f934a11798660708686c381670881e35da28bafb4d935977dfebd13d226a56758621a9c23ca557617b6433eb16af36f21914e44d0c1e9a2edf7b55ed1f2ed23d1a25e27fa85280a010438c8906a8d333479c5dc43262fcac80b66e41a9f235311aed29f0b12a1aee119015d02d36f245ba021fc5a67b6c645543855b924b813bd856189a2db1cd0a3184e6162eb44c95182241f56926eee5b48b7c37e0cac909570bbc9ff40b26e366dd9488eb92e1a02a15339f2e788af938172772e303f4aba9c2d521a1e975371c4fadb7566d1fc56a505218e8bdd2b599680810b4af234e7cc26e5c74da6682e0b4a0f09f4f3c7955c8549b9f8737139f8b339d6c9e6422524f28cfccf0325d35b5ca3f438e6bd9acaf332414e7d4865f20ea415f405a3ae6073d219b05b10669d736022177cb0c5e57e575d963e256959f714d902c57cd8b91a00d6eea564dcb5ca45e916173b0418a8ff3f0d9b995ac173b2b6d2f4aa9fed9b244f888a04367d6a6f0a9556b75b90ab897ee4b65947dfe62424f64d8d3adf13107ae09e8e4778571046eb121f9b091b674f3611a552a50f0353c0c928f60e586968b08810b296439d3ab4f751909823fd72d6f152b94bb4b4f871529d34e43eedd494c1faaf058931e934b1103f47faba5bcd2b86c9dd0546090bf49d8d6bbb34ea0df94b9d3706f3fe7800d0d60ddcebc249bc348924d5a1bdbac35799d1ed23e7f7e68d0822d7bfd8e813abe6a32fb2ecc10004e6763e43fa6cd6912a2ae8f66cd27fb18d55cd8e0227099978023b936130f2d6bfa6998d7acc49a8f95226fbaa614a734d5818273f8151ccc68e6c8456d0f2b2b1cc16465e56e6a8e36a9fd4427ddad06ce8d74fb564ef4b10e4f9bc2043c96d85fdc2c0841ff9a01b87f2a8cfa12e9fc6e49ab931d49d59fd9b047467537aa2b2a9ecb94b89f0a961219e207b8bc8448f5a5463a94100bad93784cae757836ca157b5b0a4554af813a911ca9548d61d5b15e374fb32c70f700fbb5c50de1c8be393999e1c5175dcc9213aa2c925d93b068f870271c677604e2c5b7bcc99515b0e123d209aaa183d39492117a2f2a36c16b5c6d60e45d23d7fd5a809b0e03719e02b88777cb7715fc5dac750e768dc76c990c3fa469f839ea95b366c87345b85e8e0a5220d164396974c449c8cd843c91500120f51564d273d922ba809f62d837ee0aeb985d8d7c597a608525c8096be9a439361498d6f45dd1b24d803460ff94a01b282ab2b33f4e0583ac13f3fac7580b5a96f7cd2f758b93c939f102aa28f96119d5050687241b34306150e36a8701c540c516cf5cb0b8566ede314fc94f48250b388e6247eed571b3b59c66c5b0cabe4637636ee9784731d08d7487dd2f9dfc445c595b8e6b7e23cae39fd4b4c1f7d1679d4e5ed3e0447f28b9310febdb12de1f0e3201785e80b83fd128e8cdb17e70c58afd5ec02da4546b4b2a46d43535710763766e0fa2742a0566e5b8932139963262c5dfff110aaacbdec6006b4c76381537697208026678b51a4d5bbc327b2e371817a11de42e19b6d9e145aa55084814fa43a970dbb29333cb273d6e9a8d04ef82bd13259615253603c7301f2f4216e34563c4239938d480b0f500dca8468e65f7d0304f68dc94a81caeeb6e4f99a3735f13fd94d0e527bb61e06f2292a3b6c79598530a5c2c07902212622fbb2017126fecb8d07e606c935c6e92a5eb10be282d3489988e365842caeadd663110e98c574251719004b1cd6bf63d013638d5aad005651396ffdb3414e2e746d43d42799fcab4d2e2d50ae25250274a44d28c4a38e4f03f44dc17edeb7baf90afd8d117870b9f4b5977336764fabead5fe50e4253abe6e008264a69979ae35c633443c7511ac2fac8559ed2c3e1db0b8f444c469ced8e76f3693551cf860bcef840220a052ef7a16aa378ec823f0aa95268e356e385c1b3e05650953cb02a9c9e1e7654f87db322383d0c105104521994b13a5e018a0065ccae933f7426a6e0ed933cb1e10b7761d11267f0901d76b32a2b81919ad15cb21bafb46f87560a0253b54212b55b1c81459d6eb1f15132a6da4d11b322b8417c58ea3196d879ba8b650911c256ed8bbb113bcb9b986c15a95aa75cb2f1ce13b29b80aa71ae81dadcef3ca464c34d0a6910a5a96e177d869a9b1b0e10b03d4fe4c5755ab7869d41d3583635bfeaa852b88ca17a3519afee5e7dce3a55606cb82dc17953a358c066f598d93ee6de52e27d8dbba8e1a316b783c64c509c521384f50d6a1372ec8ca407c4e423f81c7dee5106d57f739044202cf70298f9b1f2a4cbe10d82f5805a74c288abb0ddd56f4a9c5929194a2dd4847f59a5bc8e278b860b094f936dcd3c6f6c39b8c3acb6571e3c9c1c69a6163db23a3472b2da091d2cd422fac6326edd75bf5b344a1bc9c9530531ec7131abd3fc271458c8af0f6e7b056d8f589f5f6ed398160446c2746ad7c2f445c65fa0c6c901b39328ead2778c1f54ec3dbd5a6cdf37d8c63e9e4641fd3a6b47cb2483a6340b895f51c727663d86a4a1e8356965208a265c3bbab986050657947dea6c928e582b820daa5a17bea45ff04a00bd70135d554d47e2753cd6a9b3e06523d1b30b34cbe3f9d2ed9f478418e66eba52b718a594006ef4586c54b4e1c3732aa7b48d3b3dbb160a5f233c9d0628aeaa9603356ba133a864f3d93dd0091830fb966bc488dd34b741fe1436bf23218d28ac6ddc00ede14734523ed970f67648d4cd6f8c4a129353e9b1d9c4de0942210f79372c9a2dc79c3587b1c3aadddb88d78859f676ed9ac3e6c3dad72b6f4d1c6028465282325211ab94280f21cd0f1ac42811d30e2b2e1aed42cb67be79ac7526159da0fa3c25a35a5b3d89810fcd7f1706774f8a3f9e9274e8b5439681e11b2f8267722fd510d5700306eb600bf7a51e7e2223b12fd21fc18d5dd30c0df7b152cd4a6015e7feec1635d02d31e579700b338ecddc815026531452900ed777c47e3b1323f46b7d787f3497c2ef2a35abb9ecdfab594368d1096ebda8a4e083e60ddefd8a343559e9819c66ec1830ffe63c26153d97e6c6afdbb4b8c0299af151d2f8b8bfce10d038ad54f1cf5c81ca23d798f5f4c2b3425263f7df02dfc5ce1e34bd56d99f80d3aec136930b1e5b6682b811fdbc9aabc5371bc1cf626d05538dea6660f7e32d1509deb0dd363f628f99b5e0a333363f53b970f614198b3b09a8ccb2ba5401cfcfd781aa26c5714bb3bae0f12f730dfe4e9f469c218fa5d3fbf1ee669b815ec8764b538406a3e00f96fdb5f4704d693c3aefaf3d1ff610946e6911329a465aca16624b34c8cde2a38fa67036de22600523223627315bbc9aeb2012d2ad0e55197f72056378804239622c9db4eb62564ea5eafaccb23f8ef87905f11d677637010a14035a15996945a2bbf07033cec92da14815dfd58be9f83cea6b5c782309a152b419e6ff34c5cbb84b9741ffc9adbcc3763a88cbf34d919de5d0585db0ac28e0828cb5c6045642d67866b8cbff8328c618a0c7ac59892b589d1445d251169b52e2ac5fb7a38ddf43bc3d0ec60e858706c03a9f14392c91e62727226ab3e89d416434874c11ec4f5bd8f0c08169fb62c707a4275bdc8578b887ec8d2b8ff247eefcca7a886b1238f7803c10c2016d93f1e01b3d7d4601c6e514e77913465b4fea530a818c35e6157e5dc5bc90352e4af899e47445e9cf108ddba86a87b236bb623967fde721faa71d93a5a861bc68c82f70ee7d9f94ea3cfd40fb595b5787672e1150a41b674f0c26ab4a5a113609a8018e9d13bd7c0f5c8baaa8ee44ef2f00b2170b2551ecfa6df0a76b89f1be6da1ac3fb86da00a5b63a58b93c65aa3945b8836269a6aaad033c5486f33ad732b168c3f36c7869bfb2a4b1b1b7b93aca5ccb71f08659faf8badceb8af4c2f7fdf718329c56832d82dca75120c9d40e78905edeb2f7e24cb5a3bf4dcaf2ad88e7ebb9b28ccb4658058cfc58061a10f419fdb0c8b865ba27629486e191c3369e577504c2b08720096afc14e248c36f85a2f58088b7a9acf2c6fb2c53ea548c9b65caf7a36f9b787ca9a24db39419efe98888838d4e78d4c2129d6484425ee5a5fb54b5a6f602556b0fc2e8dd5c036b874984c0d192dc779e1bd6f734a8d54b5301b97e386ef66660efa3a9e7fac34b2a104e3b0fbad3b84728400b97027450548006b91613a2048b5c729902e52cd967571299c00af581f08d564b6e125c6f595c9c26700977ba98d0ea23bdb0903870a2c3bf3443a87f2d629a52fda02c7567093f9992e3959c82a8eb4b00dd9620da468955c27e070493fd40e304f8cf96b15f3f24dae8cd2430cb1ff7c5b5792a590d8cb6ee724e9e65d1d27683b69b5905300b01c83aed384a1f83439c7fe2c1453bd5bb3a6bb6be24b8c311662d3b020f087eb6ec83516ba672d3c0ef1075583fdc22de8a44512820d6d2e18434146a34b2ca8f7cd858bf86545bcd84c3e224418927320c645793bc25ca0c4503f1e74559dd3a6994c2d0f78d4d01332b72337910033cc7f513ed62024c91a566ac35c20f47e7fc49c754b8550f7a98f5c429466fa8a50a98e4a4a576abff3c80a2b41ea320454c25cc95e0381ca57bae87fad86cc1ac43cf55282ee8242af80ce2ceff5c0a14598d92dc14eb8830ec6c58071f49fd476530eaed59d04dd0e213f41d549c6f2cee9079c744c131fe436246f0f09aefb43c5bb74241ebd45db5848ba507444774113224f39e5893d70363443472baba6f0abd2363e3884aef5502ae6e587bcb75f75890634cd5c9d4a571600ab5b6ae95481542ed1627fa45ee2ca6419eee101ca5e3b81e40ad51f945e21aa49e28e715658c8b459958dabcab6e2cf07d4e4ac28d8516e776e483d28de9316fb76b30a2b5658fa411ea95e9c6f15cc3989c4854c0586c70aea65e44f10ca46f095e29985436c83ac2d443eff3a9a3d5133aac936142e872976e2775946281849814deb88ce7c0cd6b008c95b8dfa0e1c237374343c05f848c5b671fb48b671c55d00a75a08c72a4ac6ad3c703f2d330713a6f44740e3eaa76ac7394f5edeb06a335ea4e15d3543d79111d77b94c69530ccbf0e6bb1cca1e882d2751621fc88479cba553642b49721adbbd9897d8d09a1bf1df2630922c45317f5fb435b214f85fb5adb8434433e79f43acb1e2e13b55faa398874282189b6c2104719b3b0a4671518e945a47846eb1f59666a9b70e9fc6f647e3802567628b99d26b5d63a41b9351c8d672d14909bfeecdf779a89d6b2275b66aee0b050b585e93856144d3b01b8d73222c3e9412a041b0622c0514c03f61ef938ed3cfc4e22a501ce9f880e453154abea45598ef94cb1eb6e349decc0a5abdaf3ffef367feed04b85e5710e3624c9b14d1d7bd4bab7f91ef4d2ce0c7ecc13f16ba6bd1328fd460fe2ee40734061bd8a11660cd7727a0aef06fd9f844d0d88ee7ac3624eb8e13291f8e9f440a1cc662c92c8bdbf0caf769f0a86c40872a0d05f1951608d603f948317ccd4597f18c72b1e81efbdfe4836a329c22ad49b6734d0aec37cd0e1507d18406e998e914000e4859a0261747c08da77cd48bbe45154e9b2b18a6efe91be4669476b7051d9d64b3f9e1d4f8324fd28ea5f80639780c014ee3af88c3145571ca8690aea5a266045412ee02507b4c13f1d8f7089d89b5ca5ee21d84637cc97c63c64c5df78a7a05050bdc4068ca5b758255cd6f4a8049d6a8bb1983c26f6bceca34abd5d1fe890dc573f92cc5ac4c0b4d6d2258e0ccd8c03badf120193a1289141cc4c8e56c384697460a68fa1f4cabe296863bba61328209d600fd2739c0c57dea9b11ed2d1e9c271f1cd2034278591f54776a3775be1e08f523001af6e1b462453a160a6e5d6d7b133c3be63aac219831f19fc39a947bfa4894e83e607e2f9ecb014413776100048e5bd10f929be9845070fe9ddc02a13713e49d66e33cd35578045f01b66a44d3b9014d4d14f28df0353d73afa63d03a1554aa160702edbb514a6da4eb7c1f622cead5baf2c1b130227acbe958dc8a66dcbc01a0067203e3e40f226f66c0e8fd63bc68d1e69b681f9438454787ea15a80749b58d0c90089a1ffe41e7a06a26de1bbb412e68f406a009ecc3a4a68c7113441f2e4aaec6fcb14edefb69e0962ffb084cb923bcf63e03241b6e11fc2fc495bbac15071e57ffbd57d2376c6709a44c29bce4abda8b4840e9826a1f40f30532d7e65572c336f45983aaf373c6e062df8cc366a77e324b5341e58d37a340d1ac4ffaac4f0ce080c1a4055131551fe2f49d7042d175cde9ab99654b1645e1c1e14f7a5e1005b222c70ede57b648413a94bc26ca20aae379e7fdb80491ea8438ac54a8861734f97eed413d65170a726c67c193dc3027776e2432c44183d1aeb611a44144c5e05665b81bb7245eea43029078f75d473817b328345ec14829f21344154c5de4049d09cff46abe2696f9edba0647a62f9b7609d2c319856b57e8d2eace22c321d12bd70fe6b41d7b4437ae962f0800c7cf9795afc4fcf2a25235ee3713e0af3224d4a6f530bc08f259836654456b29116c21606204d8966e37eeb0848738ea5540e3429782974734faa0999440c915826f5b52120ff65f8f82f96b4123791ba89e4904b20cd3f61f9e3ee2e99c58168a67518421ccd7f790d330a317516346600a062aca85520dda25fbf15024a37448af11d28ab715827674f58acf31bcd35d7e66d70e7013a7bbd0068ec43841a1a0a4febdb630ad65904fb1adb8b06d3a6456d4e861efd7e32eb7e28ee49ae620efc3bb6b804a9e671e47a668b86cba6b1bdf97e826a90f72e7c7cb244c06f3b54778aaa41997725ac81899d4b3f05fe4f3bc649c2b822c624f98663b885e6540373b475d31a41b981af5d7ac412f687efd13b024838674c672fd71407260757f02eeb9f7c56f9c5dc7e07977347bfc60d7824b4bfa8699334193ab33f2d5e1061af9a5834e11a3d9104d346e4a94cf056f1a06e7d3b569a51acdb1000c1c725d007c8dfc31ae6c7d802c4aa2dfd50f0b5dc4f90f7a35c82de969edc3ba6e95c5fce57020cbfe08463154af261d86f9de25ce2c5cdbdbf0d5e0883dd32c06d1b4451aadf658db68c5eacbed8c68c0aad66d11624e9439de63532b3a04a56f1507a48d0a0217ef0bb5abb735ab6acd62c1078378f65faa894d112acbb36cea2599580a9b62de030db87c32c327e87b9df8d171a324b8cb7c8c9f5f25577c437eba53e5423f933ef9a11ffc2a4e94e4175188a53fb4518f01e870e7292c798f9f3c72c30f6d66fa63bf2657a84d1dcb60940fe387dd760ae1cc6076d9caac0d5a71561560c385e3f6e9eee80959766e2512133c38176571ef7501956292ebf0738b5593657c8e2feae65ec9a9fd53005defc3058897eb766b18838b520ea4d7548b379235e837b469b817c8f76fa1c9c9e2a6d6ea9e4fdd8c5359e35d649c626e52b38bebc3dd19b2c56f4ed0bfbacb45c33cb3c25ab3cff8e308a9ccc84b7882ed512eba3170d29f7e7c4e35b2bb678139411f6f3dbdd5b625af48d4726311476bde7afc17b20519d2b17ea6fd786921960a9cdb7239595b564476be9bffaee775efa0e8ffd64993a52c32591b1b922400f7a0bbf5b2a121cd583cb38228ef8d0a1eb4cee553fc85665b73029fbac23205da4f13906e38e9c74f1398e577ddc66005d3a8d455f65cf13c06d19e8864252057e0c47745402b297d4197599109430e2099e55882396ce3964c2e941e1115a83d0c209d6fcb49c34b17149d321a9c8e979d3b3336547609d4e208dad9689d7dc312d660f823e8c8ca9309f9768cfdc94976ec499d9ed086be767841c6dacddc418c62aafc7354889e28bccb1a9b4ccbee680da9a690e04b47689d25c05f1e9e85ff7f0622a84f3c43a5125d0436fc03b8ec3a1683f95bb9a3ca32c7ff04531d85d0630e1eb224d47b5815e5c494e8ef9a3d5f3906b5003fcb4d7197fd2085992d3354ccc4b7c871d4a4f75b3eb137bbf72917aa737624877792218043e7e1c5f8aa276832e937f0ab7d8a5770e21d0e4146aa040f62add2190902c08614a77e6c15420fe757c4969645252fc9513001692b28f21861222d454f8a582bbdaf2d2b17d757168e7f7194c2d98e23aae2865968157ad535033a7cfc88ab3449b719d4967c98a695f2e539a710fc94a28948dca158113f3505978722ad2f4e5a49e0f50c37d6b96a8a1a7e9ca1e0c6c0f7381f377b85bfb6e33c3144d4545938cd2a942abab4336e54d7a4ebb9faf3ead7f772b5e14f5d579749a2a9520949a2add8e6d4564668ab16fd9d86093f5449df4f7a3fa93e858da4ac9af3356d33b35d8b09713599fc235b857b16891b9298ed4d348ef5ed7c338dcade5431024582ce0771a260fcefc31b1e3c7d61d2aab84a0cfc23bf431c8343991d08209b0b7248a956bf0c6531002e7e48083c9996daa75b1fd9dac9e28d924acf7496fc1de27fc6c777e7cf31d507866a0075c1396e0dae9f9cd85346873ec3d01e319f610a1fa85298557c4750468b2f1ec4664a6a04268e961f5fe76a79ac6a72b23896eac36224e137fb7cb347e4e5bac73da347abbfd0276fb5c4be1d08a1bbaa7f652d919a47aa390cdd71954c77995e82471f7aab4fbfc6fa274f75b39a906e53e6eba8e388da65252fb3cf37cfbb861771af511a735ab8639c7ca3946e82786dd607cd2364669e3a7b4d1897659d1394e044bde97618c7602c8465b8e5f626f31847fe8f36ee3fc175ae8eacd41a49d4d70f39ed8fa2c5b06b86957f9c1159c82ae9ef775bd97bed7cfba18031ce0d2c15ed793a63baceaea90fc703e1a30015cacea023656d82e768e095a0d6ad71e24c6ccee6bbb51d369bfc1311545e2bd15391b3242ef10bf785da4ceaf335bc742c8178280deb756e4f4b5560ea19674792c48b54535abbe50d6845d564af8c93ceb01a805f726014e7c9d8f1701b4a115a1c202cb3e47b0b887dfcf95fd8c9c295c1ff9fb6084f674ce05de9d32fb766f771f2915ec75a9ab5d22336e80a7503c9d1d0a9ad3f2e82b714ddd73a3db688241628e13ce05b440d42c448903da8bb6815930d03a4a07d1f733213d401a51053c3ce60aaeb3a20756501e3ecd6393b7ce808e23cff1312b29546b14680b00d9f77d2f3da054393f1800969127150cd5b50fccc64f71048be52d6d4624b1a4d9ca6f646f42a49452a624530e0824083308ecf37e0c6b0cff9baba3b20f122b261aa411ba0ada3d123b0af8fe274ceda0e62f7fc11ef6790f8da6555f8093da694760b7c00c0d50a6762c03e385f246dfdc474791d1596d7ede83e6427b56fba9a276103524be026e4d9412dfb3d5c623a45240db0edf93dd1176cf399f7cefbdf78634375b52e12114517f15b5e6569a5df1736fefd8dd7d24caf8f2e7ea28ec7385db685121d49afab7e5b96e8bf0dc312a0faea3e66e228c51e8c7a77c10ccd70179a07cdfac1d32adb4ef3ddb7daf43465b8a0a21a4cd4aa3fe7ca91d7c4236cd3bdae8ff6ebcaf21f4716edf6f4ea867f0dcbdc88d3a66eaafea4bdd57f4543e207c720cf89a06f41e7e3ff81ebe2f825d7ca9adb4ae5245c2d17dde6448f870877dd8bafc1a659492e5596472b2ff8d4e4af9453242f8cc6c331affc7fc2bb7558c317e8d939db8d116d12e7428dafd1b5d8c1f4b805f14a17dbaf9bf47a9cba53d4a298d0ddb9ba8b5be9d569beb1bb721cd3da0083b6e8a60326766666edfda7251df379d0d21c32577677e2f7a31a7d69c0f8afa0e16a17efe5077a80d75e3f6832f7cca3c9e84167ecd55dda1d678bc63882b2d84222afc5503c9a71c445fda2ec69dcb1fed4f94da69d7570e1f469631da5790f80a22ffc5ecd375942b95a25561755d3e267bfd54b0230f0a4690bcd8437a4d5e1233970f9e5f7eed59151e0a3583c467f3544bfc542e15056a5eb34a5e441e4cfb07d32c9206ab7924085ba23d130a7bac03f5aaedc15a4504613596490b3652b3cc3a503fd42f437d134b3c55106ee2056126800809fdfc70dcbfcbe51d3371e9cb15f8ac49592b230f4faae91766eede2d8c6f8b60d71b641ee9168bde77f1514f1f155ffe9413d052a97d05913fdf3f8b301280050000e6ba00dcd3ef41d08dcfb3085a515f423c2882ff972fdf0edad75ff93006a02685679ffef85e14a3fdc1175a68adc860651fa613d2f9927876561a7cb71dfdf934a393524a29e5e6247ce88ec317b1571b67244a7f60407100438622d638638b1db4c034b0040d69fca0830d5462b0ee6700585a10038319622e7881f5731e74e482124c44e1f2450b4244817503c12a5ebee84408db69872e4f080628508b8126a5a6452dc2ee28b4e133e57662e3a39f79dec61b4fe4deff79fe79b8e1bf1ff2a1de71bdb9e93edee2436d0283a37670020e1c59d46a33e184b3d6cb83694c13178c3102333228230416607411451531e00256536716b3d6f97456192185c1d53a58e033bb70627c9da794524a5fc9d579ead2f98bf3ae4dc7d2e65a3bbc04f2d5e6ed8e96946c4c49c460383ec381a3d3790f1cdda863a3e540ead2961410ba2a8d34cad085194588f10206c6152c9a74418416345cc06c9ee18e140cb5306c740b8c46bbef128e1f6a4a29a594aa341d4a359dd75ee755d0f55acb653b7a5d8f03a95657946aefdaf8e2e8e8fc50bb36be2d9d8f4b1e6854a3544747d3f9a1f6a003aba483efe0b30e3ab0b12a347eb445fcea9ca08383aa542a1c2a4ad5a04f59534ea965bf7a4dc3d1583ad1155b91a2a8aba543a9abd6f796ed8e6eebe9d6fda53adf511d9def5cf4551f6d47df451fe787bcb5d5a72e1c174ece67aa1b57a59146aa5d1b0cf1e505371051822e31f0028927548c40238c1319301baabd6a6a68ea860d574b27526abb22ab87d4c6d7344dd3b456bc3aadeca16a84d567432b4a29fd57ea860d17fd167d1d6a571f591bdfd5363f07a7fe4db5a95169f3b3ad2b32638aa250daed2a5583026957db79fa9481e053aa4d19777260b0d13a5ab866185839f30ad6e67c15b721cdf1dbb041edb455037594ba5c5c1b48e563be7c7924be82c08fb72bf273e11f41088552a807414a4ad4c7ad2f87b21fef472fe0cd6c863a9b5bdfa51d96ed8e2eebe7368bdc6984c15ced3300a0a969988707d7ffa5e15d002ff55dd667cf7a0d7647fab65ea7f5373fb7ee21d5eaca957d6be37bb3a580e4b25857674b615ed6c3ed85e3973af86c6693c5faa1ee608be1b04a703c8ecf706cd95311e1b0b12a733eb445fcb22cc0dae17bdd7d67ebd13dcd3952acbe5893cbbd34748417d4ee48bc3ccdad68ea733edb5eafb677a9ce4e733cf3294f1a0f7a5eb8c79fb66c47ab8eb36ce7ba5cbc88d11c96fad07cd15cebdde6816cde756c7774757eb258acf9da43dbcd6ffd538d30ffe6875c67b3f9a9f2d1baf91b1f389fa96acbe6d3c01d23a8ddf39289f08533939125ccd20f2a78a18918bc34c2b89245931b50a0c4175ec06a6e7c478354ffb220f120b7f15d757de76a7df73adf713f69e6c369bb22390f553e58599665593675e05f960eb445399f7aa81a2167daa1e626e7412274cf7c9f7fc34e1bf65db625a4633b6e3ecb4e9bf3d0764277c8571bdf9c4d3eced680a37b63f375b3e9264f4b6aeb8a0809a5d11c92eef1a7410fe64840d0a276ccff06940ac6891a08f5f839e1465f9b0bb5bf83aed67962a58ba48a0306d5825a9dc8b01851440d6584a8abcb4e507ae852712e3b41490a020a0b2833aacd65271dc688a166979d74381373a039606ea84828e160d1c1e688273756906ab2542098a89a6c66d08ed85263c31312645a905436c420432a09256d8d26a82c495918744aea87969961fe08fdec103ae2c97bd889061f58c4e0020399257c6851ba02838f2c4f54907c20b1254acca9861a6af091c496170c98ce98219271c612d50c6aea8c1a1ad4398666a5aaba984cea4d153562d4541431064a6850ea3422bb624acd13f5e672931926d058506b2e3799f1020d66ac50e343d52e37a5216336a53903011dc8b42e37a9f1c2163032661e284ab9f8139211d6da1cf7f353ab92f7680bfd68e7506e41022e027c2e7f74f6a047dd39a8b774d62f6b72049fbdad4341efe7afe3d57bb8e66636a8abe41d75bf25d7650dbabbbb43267242c8cccccc3af287baffe67acdf5577cf9f4e7f68a760498b44842fde31c7c98a41722b96012daa7227aacaa310c8a9aa82c6816d563948f85d7ce536a584c2c50cc41477d40b67c5036fc2cdcbbb89e8286f2e4f811eaa247e425920a13b7b3b8dddb72032a5cc03484104ca828c18e8cb0e206193891041034d002d6bd58d0bb31e7ce9d3c2900a349054bdc3955f074271513dcc9ed7806e8a2763beeb41405e9d6ec3d28db71f7dd6ca63e15533f37bfac4acd212e4fa376aebb80dbadae7c4ee3ca8712082aae4cc1d295ae17bb71c5535bb87029cc8553982ebc72210763b129d70c7daf490a6d474be572fc5083f501572b29c464fc0a20658bdbfdb058eae28b3284f08206089c8080c1861a2cf9e28647068d0ba9403273218410421c2af7de93c274006d258590f2a9504fe31fc1f8d9835e43e0436bf460f08f605dbd2989e4d56bc2b6634c7d4f6a8025c635107dcac97f3da950a8584a03831b44c111b0d792da8f443ea54222b89254790fadab7ad08b88d1110cdaea3df219267f85a5d2ef842e1239e5c164eae53f2d26b8ae54d25688cfaa21f0871af51d3f69cdc91ea90d66ff54fea9ed9559154a18d29c7cfa3ffa530f6fbc29fbdc89e03eb7cc2f04b8026ba97f5bd1fbece9f60a423bfa47d755419e65e6509fd94e04f7bdb30fea7d6af379e50bf5601e46ec235f7e023828c9ce0e8b25913427a50721f11ef9925697ac574ac95d29a59452bec63c32c5d4efc9f7210f9a307f20244014ca0ac15fe150dd5f44b457d1d75e445449b457590a833e24d49c9077519603dd51eca29e57287a0929829fb22b9475dd1eece3af6d401a01fed23f015c00178a379ed4fe27eabbfdd0d6ecc7dddddd6975a2e67c478e1d63723071d3f78370a6922082f6fd5c7fed77f57bea26d4698d5e48a828105f5a23ee62060f5b9aac64ccd341251e3f9edf9cac7f286c469a8359d32b907c842fa4d265a71e9cdc171f85223e70518a12e17b435f5412543fe2a59186312ce820031cb048b1012c1e557972010c616ad082140c111f88a9b21e4888cab2ef4900b203b5a792cfaa1e0dc477fecdd62352c001f3a781e60feb86c5a2218975d303989f1ded43a8815e42583f7f5aa1e6228b95dd6cfcaccc884561b2e24f20de131ff5885e37ff62fdd165d9eedd9bcf9cf52cfb0ae297f57e5956c97dcf7df35e38ac241c3b425f9c1771509a42c5a987d88dffaefccb12638c4364b9410d8b8fc37acfc97bd240ec1485e9c67f39c4f7dec3f9951115e7339ced5d2e49959c6f59ee45a4f5ae7759a32358cb323fe835acaf79ed5311070785cc7150b0516536d97bd25c7c1cfb9258db934d601a68b2b6ad6fb4e18aaf964dd28aecc48dffa6d48f28704f7c94ea993bd745d9b841040eb9618d1eacf5ac1a62c31a3d984bca129cd56681e670a8dd672c1d1dfb949ef52b1b6ac75c581b0a9b91e672b65573d1d6e6e2af8aa81d7369bd5b97a5de036df5c0098d2cb016dfbaed3447d41c100f42a17be2dbd88eaa6c5735dbd5c8050510a488379e3011d72382efb24610054728a93004fe107f56290006317081b97e763417b38f4f69ad2e578c313e2dcd4510ce542376c798daed9c71bd0d22446c5823eed2046b594ad47a97357a6528adb105d66aa00795706041d27e286569d4c6f1acaaa669ab9d9dcb538c00290dfa1aa539b878f881e7c2ef5add0556e4101fad95ae78a8c1a964ef852f6e3febb213d215f73d4a0c14f4880b84f7b3d30b3d40a7175688aa179c4c400c1214d721c0658e2001152b5000050cba8065363d0131485f4cea5446da4c29a50fdad47420b8fddec3961cce6ea741a00b342f804963458b31374178f1e4a44b931918306567d41e5bdee38104da4a0bc06527251a288d81c290bd07fa2aa93e2ff27d728cff6ea492caf729df943baee67a05529e4ad552a375d1380a2b27a842893296ba58c119679870a046143bac8184154fd890c544994182939216cd4909ca4d5d76527252461a7f2d619ba81dbccd49195500ba47e485b11261630cbf817d6ff06735cab1cffb0f9ac0f9540de809fdaa115fd3b4ea311ee9245e5d9e7d96323640170ea1bb8435860a21a448d40e6a903297e836caef628cf159ea453496289496e34a66f928abadaa269fdada69526b9274fa0292e04348abdb265e4a09a5fc28a1fc0ba59412d2e65a07b472db244bb96ddb7661034929a59451bee01fe032153f0f609f2568e30690c6bfa1ca2a4ddd13acae74aeaee23f5f7cfce00d1daac0dd2333f38331ba7ba550f43565f46fdd10361d8cd8877d7a34d75e125084d0a5cdc939e79bef56befc1f7ce77cd89c86baa82b5197551185bab081a6ec57b4b93557639ff75672ac785533fe9ead64fc05a4fa1e05b0338e6ee65bbc11beaee992f42513021921e0a03ef61e1d2a9454659f2d727ed8b991d55a5e51b0b84ccb8523f0c220dd172754d1d4efd167fb3d94d5e0df401b0fd6be4a740046ecbee7292e57711b8a1714280d4ae9b64b89f8eb3d2dacae77f6a92cd426202d425d5645188306e01b27a3006e0ff609e35508815cd5197637f7357c373f6e2e6d8e550d7473731f7caaf838d700d7c940cfa9c26ddc23f1fa3393e3d4bd849a7bf183eebcd9ebd7354bf27d03baac22f29e191fdcc67161c78a1ce46220a1e6806e0070c81e1714fe9c71ddb8a97e5a641042f89c187045092d58c41863941709f721a5c6685580b7c8cfa5f6485fb74bf1354dabefbd7eb1bb1b4523dc611fd8831995c11cf1eb96cc96ba02157a5ca94ee090f802b8adab73bba3bbf4226a98fc86496ba404165f4216021004b7da618443aa2306ebbafd21b6fb946af4756f5bfd751e60fdae4aa1c30f59f61a420831708fc4dbfdaced52f97f402d193c026f11edf6fb0d1d54547fa8821042f6d7393064668ef43b7e5601c66e0a462bac71fb4b78d6037ee517f1fbeb744412f350e1e7d2efe477b484d47d2f511d3b1161e61e793785472d07d8cc3593e361c76ebf7f6f1d7be6c831723f37f77333c76c3e4f397fda111e6c41c60ea8ab0b6f66f3606f759999f9ca951fb78c36901ab77377f7f80e2184d0dd5b45a3477777cf713b77f7a32bb7087bb9eee5c2a6a77a56c714f4dfeda494f2860f14294fa0a6885d81621ff6e91fea79790a295b9ed5d1545197a79082e5be101a0dda4059502c2e4e19ef994a0172dba43e95db0eb21cc1c4605cf9b1980df7c814d2bad3761ff019f2129e0c32cafc0e1f3bb3f773a2942133a51442c9324efed78c71d3d827298b11ca09e55c39b3ed26cbbf114286ac710ff47796929da00e7f70c2892b577827e3ce1807059527d35c5a3d8aef75c9b8b3cc5b903fbbe594527e6ff087bcb7f8fc5ec68db91bfef3ee7e1fb71494dcbe293c17c27b74909624c2100ba0e065b5f39a524c52b818e3fdfc23eceefbb07abda362aeff80b7a90b79b1fbbc7869bafe90308feeee984f691058509d8a4769ceff005cd4eec5a25cff1786832600bf4c192fbcb0810ddcd99a7043ed15fcf10b4c02c6e14212646f04b52f3b119174df734df69e79ba9fb702b73dcf1397263ec685ecfde3e794458c1aeeaa3978b9698d19eeaa46c91e30028d75d9a94a0babcb4e4a5cee6ac70a28bc88bd07a5be95abca509fd5eaf773fdd52543c63c52fe7b22f8f65c73dcf517612ed2026976c206105aa8ec60030b332c993082d8155f9ebce0065c9c8888719fe6bee7c9719f37fce67640a92f21ed6f5f75f5faf1ff792ff4fe392db2a1335e438caa10f5fb1fc11cbe7fdba1211ed4ff1eba7d3d1f2ff5798b90f73c98d1118cf39e67c2101032af9f1af25f6e8700a15b6af79c78b94239b4d010dd8c8cc85c798ac1e4cfcd28043950023663d05b420ca108bd7948735b68ba13892b34019bcf2a22df218a293118e76a989c0ce3ae410ef367ae2d3ef119d4ce63b43e0df5e6eb6b9f7a55cd67611e368f7373f3381096818ff3cc2c66d623739f3f7ffefcc9279f94f3792c8d4b8cf7f1c9d554b9ac561e839f535fa7fbd5d6f11626137b4a5b70723ae7e6fbc63697de62b33516f6e9f7b1a562b9fde6bfd7d24090c70fbeefe7f67acfb79fc840499346a3f111a2f2edfa3e9f216a4d3f35508d6da6e63ef5fdb485ca7e16fa9ee4afccd55e99fbfc95b9f25310fad6cd25d793484384182a38137d20d3c4962e5c9cae8b792af35e5cb7c175a1fb9e34ba9ae657b32fd473596a7ba1fe5dd405c1044f1fb05017804675bd8def7f9da6b9f69807b5fec6f7bfadd1f40e2aaa8cd97886b598070ebf97dbd7036cfceb89b87ec72669b93ec98db7e172b95cefb24a92d878d7bf6c85753ea5d56ab5be6595b83ec98bfdcbbe7f7dab65877e8caa10bddec6b3f774441e18457489c158683d075277a9659360e06587784f01ae6822067bbd0d1bad7fbff3afef3ecccbbea4d81116471037fef5cc0418675ecf04c25486b9c87882064c6230576b7b4faf07c213af2986f4dade19046871e645c4d5bac1f49c9070024de674c4171c349da6df4bd27ad76b88d111cc658d922899676036def537ec4b33cfc01866c3c6e61998cbbe7cbce4cc50b726e33dfde43dddbbfda4b91c9a438a35d707f8a276ef2eb5bef3586f69d92dfdb4e5ed20861527dd5bc8f4f7f716a528cdb5122c87fa6c337951e306820b8e96761073c509a4a8c183930ce060050d9930a820810f99bfc73a88bf24c562b1159c3410df7ea7b2f4453ff9954766ca92db7993db4b686ee7516e4f8175eefdd4402833af9ed254fafd49ac6550df332cc66a01bc90b10731d70735a711f67b1bf441838c1f7373d5358d1fa5fed86bdcce399fc0db3ddbc122da7d1a9f9065ae2eb67ce8f1bb2d8b1142b745b4acd99f47777766d67c43dd271fdc21db6902363f7777f72605640913c661c7f8de0be3689eb43cdd639b5db502d73956b53a6c7e1a0f0f0fff946008249a34b7aa2b204b9ca135300c41c445b9a0cacb4e4354b99da6ad785655d3b4d54ea44c2cc020020b69ac846143929531363059918206a41fda440cf347e8678790124f28fa334492a4956a1509264aadfcd00488124c4dc85831811517928024412688343400d18214040d6400824493f730a5d5b5a2e208a4284e3ba092904e602f4f9134e53aac05f5f55ecfbe1e303f3e91f9d12649427f5a2232497c695fcf3245326409b531244616a0467d6c847d4650e5eb01f1e55781fff28f60f3a1258a46d1bedaaa40c4d13f82bdef388c0ec8ce35b72521b9457f23ee8fc46315b0ce80f34412dacb3e18a283200cbe051a886f1a553861831b9eb60b40a2763cf0a2a017262a6da5d5958685106308519d64a012071ab73fbed8142998f0e9307171fb88da693c1cd3960f2e844d740063c5982dceb0a1041b20438d19603983831c8849638993a6c385666ab2a3e64a143575d9898a19a91ba8c8e009151880a1f2051a51331d6cf801c4142935c4309d740fe710c575c613ca53e97754a3b64a79ea1e2643cf4811c3d57fa686b8843463c0042a790f3bfdf8210b142ffcf0e189054c7e4c698a9225062d3fa238d13d7c3b5a5fc86a68ca4109ce54d4e5a61c345963fec85a5d2eae07fb6436b50a755b2311c07a0c9ae387cb6cba772184b0c2afd9509755446f9b17ba0a021e2f84d6480430b72d86fd27073b6cad07fbf0ffd0ea7afa3cb8a1be67a1e6f82985352f2287a19e51d6480429335e3b8c725214d75c2a73c19c6b0e72283a334de3d88f7c7ea11ecce3bd581d23b75f728da91272cf711ce7faa9f6c55ecc831254873706ffc5e28bf98bc11a8e4be590bd9f550d36d090266a0e662af8f48a56af057911e7531f3f0524f7d5b779d6dfe86cb4399c3fd24038ef6f44e759c7b2659c0dbaaa8437a5b9688b34a7fa814273fe481a285309c1b1b43955909b8f9fb315dd7cfc4c5b7d7cf8d92a0e3555055915c5cf79aa0a123fe76bf86639b6cb799c8738399fe56c443a549ccf2901e78b721e3a20c7d2fa38b6bbb12f2145ef6bfe7db41a540579b6c6428d93efaa12844e68ce9f05d29cfca5d663a07bde67361a6c200910519f0cece3cf58921e95cb4e5890ae5f7fd2ed5095d00349cd1b69a09a8da8b9ba9960811c0d6e431ae875947dfca7d48ed3e0e4bb9a932f1ff5f0bbdabd262f7bb5b9f7a4b921576dafc996c36ad61d78e476abe6e017d16edcf155dbec90d1679e54a73ec888b3432219aacd96a37b76b455733ccdcdf946502f4604982a87718117be461a88936eaa553efc7d8b5b575fa9e7a5761b05d87c076fa44e1f030d447f4a4b3532a95817199ebac8a03406b54697265792e0a7a5b25316a59b7ad553939818950b80cb626248170c18540ec4cce045cc0c4ede15234394f79892c68c61427a549e30d04093c99cd040118b3b1f8506d29e0a97be53894ba6054f5a9014c6892c619640ba338c134c77de69a3d1ede53f8f3437d3b8f3254044a57fa3ed345057e40f359ba7da31983b2d5173f3771aa8a8ffa982f8438e37abe652dfbdd8a780e47647576b20beb33be257f535ff96dca96db4b9d49b405455241c5dedd9da947d4a25a49ebe051a88f296d436e50790e6e65ba06653a984d04fbda60a927dea555bd14e7fea535f9b9b9a2a48dba2d4d3d75441524fe1a7b69de6e6bb8ef83de2977e25d2a1f6d312fa8be8af9a9b0ea0d6d5dc7c21dfdc4c7ddb2eb32f21b6c89fa65441dc52225509f4dd8ad0dcfcf974cc0fb7dcdc928d85dde33fbb6aa4b9f90648ea588cec5a0954a9d97790fd4b38bafef3fb07dc692023b5db32260fabf21a6263f966ed369b0dbc9e3a022fecd1405ddd116aa06cc9e6771a88533f9fa783206c7ef5201b6ba47be6f3cfed680470a80ca36fa483a81335a97ce9679b90145d7510ec9ed46bda6ad5d53b53f46173ffcee345ffc170e172735c06f3c496fb0dc40eb09dd1fde652f04b5d77d2a7f6ff25b5b65083b5cb53f430c6ede8bb8064ce9ed6dd056e91addb5e10fdefdfe63d9cb92f0418935296803dc69823c61823478e31c618618c31c6087f7e628cd1638c114e1f787c014b41d2ebfe4a76766ff7eef6f7de7b46da9dbb13ae7c6e7728a133bbbbfbec7125b394ef8ba67cf3e17c38df0efbcc7fefbdf720fb40a8c241084a6a708c8fad74d9ee5252f6e1f9cb9021171182d279e23b94524a2993be5cf8110dc98c06a506ac4b4e1710c2c7c4f58f30c618238c31c6087b85ebee36e818a3c718638c58308f2a692ea38132c276791ca3dbc873bd5b4a296516348d075a72b67c59a2c9e52f4a34b94197bf68017359f246556f85ca5fb468b91dbc90e372c02bb6f07221849007ec3262af22703cb1e17b398a169a5c7ef831ac902afcca3e19abd87e70820a9f21e4aea2c3a9fac31b3f15a3bb7cdefca574e9996b730b216600c69dd3dddd394a89c58e5e3142c6d431aaffcd65a717e033ad173e7ffc2cbab46ec5904b296560034de5974fa57caa28df8a1baddc4868cec1cc1e6a9ca0b66a3f3841e5efe2def0819225f15097a1a862880ba1a8220517def081525397a1a842e9c28f27b08fc718638c8c64c6853246a98a568753ede718638c913719635c512899555a82e81125470cd8f1d3326a919c5346c8dfc90899a59531dee4fbb7bf9696031ce5c6a93ba5bb6f0cbf4477e71a54d565a72a4bcccccc5576b891a39452ca2a4f5094320f9652ca38a58c31560980171c32a494524669dddd3df2bb7656f2bb1574e7c8ce9193ccfcae9dd50a62e13da58c114e2c32e92b299d9d3d33d3b1dba5f943edcedc29b91ee1f4d52a42e8ee68446686f1a98e3315c5eeeecc91bd88bb84cc247394cc910168a4845c64f13ac618238c31c608b7ae88ebf66711638cf1c518638c1c638c314228c76000941e593040cad8dddd3c374777777777f7ebeeeeb7b64bbddedddd30875057a4df7bef6d0f8855c13e0f884dc1b481e27d2f8b249054411566d05c78dfcb7fefbdc73cecf3e69c737ac31a27506301512be0c3995700be704a19234cf220880adf75bca0fac30068a1230c7d7777671923845b304e195d045f00b7285a149652ff733bf6e28f9418d1a7298bb24b98f8c0508f9403a33726604585dbea763977a2643763fc0eda256634f8e34604f61ec2b89444097f4982b18df1972498cd7dcf2a0af09724d8b346fcae4b460e5876c0c244867e0caa60061f58e84109d812263eb0f74839305ec2a461f49114007b8fda901400a3465588de1b99e05550d6a80a11fd678d38e7f2c465b800c5520dc4a4a08c138c617c54022f4a4081c2c4d31063c018c6441f8bc11e1d9375f4f1bf9745fea44c3db79d92cbdf51ffa427a4005730b186d1e5678e6e39c05f3aa30b6dc7a9fb525742082384ee8e464c298b314620f73d672ea574e9f23b132e7f46ddbddda584ec5202b94584ee7bde32c92c7584a9fc28f8fd999452ba949bd63a9eea37d7312ca494f2a9646e4e4a29259c52c658ada8f1902184b091c8c912b309001731c618218c31ca18218422e3cb3cddcfcbe23d9e0fdda7bfbb7b0e77f964362d07d84c4a086f71a3656666e61d02a0f2a8a4cd776439e914d108000000055315000020100c060422c150340d645d4e1f14800e7a96446a4e960c845192c3300c420618430c21c418000821c418aa9a32005db5b6e153fa874f6c0fd58cb3a24012b178105999e335931a1af1266b43392c68d3eefca7ffeda473b2341c5d2cb0fbac776d17d32e09136429ce8d9338142af5b4f7de44ae361ac4574120bf3a9664e98a8518e63c8bfeaa68577c055b847afab84f00bec1580329b06d85e7155dddbff686dec120df6e1b50e7bbc087f608fb166cdca0e3cc67ab338acd8bbe0c1c1ea7954aaef3859b2babf3550b574e91658f200a31542fde0487600fd530fc6d3c8fee4d79cffca8cd9f5d82d5157f0e68ea6a9e3a41660091d3849279f8f359c0f51b42d44989133b2c69fc7bd3b538f79cd8ebecc1a5143ad343e69c893b21df9629eda6fa685409e8e0a3a7cfcebca1a96c4bceba22e960bcca3a8d2bf67dbbeefed1be424d7d0359ad03fea8f04a516c3ba79ef3e2c3377b407d8eba19de79440317589f05d1b4a60f356fa91d02bdbdebaa1facadbab2d610efd0d6ceaf5f4ad499c439b98874f0bbecbecab3da7aa0ba64568845441d4dd95a7a539be11e2874294faf1c337589a5f94b7ee151ceacdfb43d7983a996a642d3364e7497ef42bc4511b3102ff55a6fc895888a7800e1e1756694199df7e6a23382042b8302b31a8f039041aed2b3b15f0d6d7b40d951796748ea24067a9f6eaaa97c8fa3ca7e60426c90b7b53ff9a638a6e0e54ca41cbd1f5b3d4110945c3b03fadc187ab79258f11ad9105969e7ca103d2107db441d95353969b92cf13eab69546a6956a523ccbf0c7bae38648069c54aacf17c0f70fdf1f24ae2b351472d17444e394d439b1f9e730b68ee8c3f7353aa76cb7e597703a987d4a136c619aad00f1fbbecbf45c408668e2ac12de02757b00f79e9288df93ea2f4d8c27c0b01e173fbfd78c8c613343325e08e5befbd1f5739acbcada3a725061c1b9aec8ce879a77a60f8e11bd6b4856031b4ef3f2d3fe35fca47217ecfda14f8af6b9c78d541d0d0ebaa9da9e6ff358666d372cf359ce425073826e6e33e86e719323eeb1a201c820b006c50aac07e0afe8a4a6ca7200be6c84b9b7751faa1627e499bfb067a92d3e796c1cd47883dc4a36043ccacae86519f0830a7eb999997b5a9b7f7171ab4afa3cab224cc53672762b937559bd78290fe86c39ac013218b233209681c5a5994070ed4cac5d8ca5390721de5f9fd1882d0ed20c0335ff92b7d4188193c03b28087e5616d9c7be915cb57f3f55987e146bc543c84a1f0368e333bcd0f0d930fb786aac1858f806a44230eb40910786b2e3154ad63b67bd1b3de7cab63aad335edc7970ae60b10c192c89ae564d49295ad2e952f93adf2d823546874ab97f7df96367c4fdcace98e077b6071c13a0b90f96203ee4c04115ab737e4b3f4bc195b88049516803b90905ecfc9ec5ce80f80c8b8da4fcdcbf4fef6baf5490b94559e6dda0a23377edfdd1b82ed32acd35de57c53c6e3d55b6312591fe12fda09952d11ca2ef71008904d0d8263c4c766a0f0802781f146f9f3d5f1ff3e0547905b511ed9dda0d4c52aa52259a8a52c52ef8a592bdc2b1ef85bca33e8d0da3c277cc6af8e4a24d0c9aa48315ae0355ddb99967dabda37708e71e888363ec09c366fa8302ce0a8d7af19f620a085c01bebce107bcd3e5d717a058734af81d5f224c1005e96a46233259fa2ddda3c4b40ee5e834ef91cf97c9b7fcd3c94f18de5b531001a56fda02b02683ae64ed5353acfd4dbf96cbad78d10e90c47398b22ea4d4948c3fcf1b490b3041e205c9b0af55b469fd83ac176921431b099bab13ac3df0949d855bcf0d6d8934fff8e58ce738a2c91b032b7c733c60b433d2829dfee630396dbcab6573fe506af44dcc16532027f6b663163d0a55ba5860ee6b23513a1674260196f2ce598a540fb9a28a3b87491a5e0b9c2d9a02669884148da3727fad1c24642e63840729b7b64f56b84f137cb4f229af963e92e288367f247c845c71cdab9079a5e1c9f46bf22843ce236fc91129d6ec87de684143a27faa49373c4b5d1eca62b83ceaee434c883d947a2543e8c1f17eb09275368a04305095a489e70836c268021383c32c9f883667825b17275b95c9c97ab5b018deffa56d3e30b609c136768f1fb47ae8eec1955fce90f2ee74bfc572f4872d882af15f8b18c103ca7d9fc707ca1e1089939f7e25566c7bfdec2c71d4a490fbbe902724d8aa32bc93bc8a28c859c899aa103499671d0c743470389d6b322e98fcd2e3a3eb54bdbd9f645e8d72715aa357fbce4913349b4b37328fd52c044a967601dfef021606e599a98cb69ae80305eb40c5efd19fe754eb9358dd08463a7f161090158396e8b0e6f7140d55a7e1e6adbc2e1cd9181f51d86df362aeef850b3a8bb79fd4c61e374ba39403e24f7d779388b04c1716d298b9bb2b3e78fe3420aedb65dea2a3b6cdba71187f0f6ceb41dc8cfb7e9c0c099111ed3412640704d788087267f7d30d040b22e242e89450f04d480f45ba324162b2680da0452b7f4aaa4fdce0f00f19f7c3818383c649a94a2bc7625871b8f425b165bb6097194950b1b78326e5ff09af1be74e08de40ab97064c15c6bfefef66283fc91defa6cca900438f916a2b62c0341dc6fa07f974c41af7804e4a6efcc18b564d001f394c7784207078d670ab28507092e5278bc78f68d8230a36928a11025dd15c593176751f294642482bb64f9ab263bbbcf1f6c6b8c235fdb7b83f6a1954449a2f0c1f003d4ba57beb4738f08bb02687f479170288a3bfc933d60595d149db20d7120a8e2b037b72da47ef9d3ea09af9c39d36f37cc60a2de5a941eabb1b9126bc6deefb357a25024a315646645aab3226175aeec54d5c98e3cd9b3f64306609565153f1f3900704a1a5ad5b0c8c3a2f896cfc9c739ef2ec0c4bd2060965b413946eb37c3822c81e214313f51f6bfc88078f335db4ff2d06c11798cbcc17ba077a8ea1d5bdfa2b93c0bdf4892f29c1b2ebaff9dd5c172ad3371d95f877e849f8dc8af6484c609acaed6428ad045e46ef8c031c0df355adc34f099389d07bdb58721f6a03387a478433c73a057234422a59ab3f1e436f04bfc5cb8f9a4d8759c3b3d642726bc56812294404c9488457e83300405717f71abc1c0578855e6a46001cfc3eb823d3d60827edec2c05cea8bed3df4ddc619dc429b3c3bcbfc8ec066deb5dff38aad16c5f89acdfddd219847a82303a70540a98ccc6215c2eba47455acb05a9e5dccc185a302e3af9496b58053c2f7b40996f55fd9dfd3d7000f8fcd4020e32241447b800253c1afceac8cd9c49e76fdfbe137ec0697c1dd5ae3448ac7d22e3e186f93f9d8c7215a4ec9bf86121c8c3ab56f31fcbe0eb6b9205a1dbb2c25dc7212317e91afdac359597ba85d7dc19c7a60d9ee047563c5b189a8ae802f83c474dc840afdedbc66e45a5997cf1114ac86bb6eeb22be35cba06d3835f614e5097094f53e9a7002d22a67e6c1856aa4129ac3670c1d5ce8fb898cf253d949717e193630fdbc10411ab5d21fea1d1e18f04811bfa2d5809861e64554f1c586d81e3f57cd37c6f50e037da474c7ae69053dee608267d7eda26f420ab374b452a3b4b3089cdde99dd3c550aa326b03760ce978337100ac30fe942b1e0cb70b99313a25eb507631b6f93f911218c710c72e8a49d1506e32fa0ccc3c343f204a2e5a30bb5d787662b2073690ce90ad7bcdd6affb0ddd558f2dd9a2c93bd3910df525a75595815ac4c0b81e54d082b102dd1e66a43f411608214416db64d109aa26460856b5010d6d05baeb49922774bafb2ecf188013aeab6d02dee5bcc0294c501fe1789510459f7242ff919531cb8451accaa4c660ae0489c991dbc31167ab75d2eb878da7cb78577dc0d9c628d89764e31eb8b5582dd5a4c06289387c738fa79cc961c530d7d8930f806fced08f7cd3296baf78dcdf0f892ef2f56bb675716e9b0680f5dd5c288e87087b3e76fafce1fcf67c426fdfddbe85475121a0e802dfd72ee25646cb5f7ff64d67740d55ed843184d89bf0d2cdac33cf8d29a2eba8e11df96f088dd46b438e8e654e802bc4b34f3fd8bd2d5af1d93d94bfed164eeba0c2e97744301d58f8b40a4c10296cb3d7e6e46c452b70d882890240b5a0607c38a4ab5582074e06191f46a575eebf0e40ded311054074b01b9f52a8e071c2c6b2c6df888d4f23021bbb1bad1d32027c8131cbc96b0ba7aca99e1240955fc21f3dd66aef9e7ee9f533ba55a3214a0962d2aa9b41496025bbc7c95a6a60c8a33f9f7f5272bfa914d04c1adcc58ac3cc94055b6a3ffb76e915486326ba0f16954d85430ffc6f7ea619f7efde232a4630fd7d9693653c92464c3466c276c50cf9cc2a2f13b7718fe32a8c4d6fa692d4ebee100ece83b37479417e54dedc1d96ff3199815ba73aa56d1bd9bafa0499a358622fa8d544da8b8cad968b5b3fdad0acc91b4a0ad09856a8bec94f351b9325d98e8116e69bc3be63fc5d49f247a7ca83b00ef31734e3fc43756686c744b19407d39294b46d8790ceac6442c2740e9230df011e2fd283987a5ac1a02c611d14c2d31801b6ac54a8df17665966df48236baa1a6baa95eded8d330025e0573baa33bcb50991ccc6d1f0a680df812e24c3712b3c897e571955acdbf480ea39f4aaae5589e6af06965d2f6adb4b75011656fb661b1ec754e0a988d538deeeb49459e9ee448174a0ed9f3374c7b45c676d7210d39244eb466b762a106171d76e3f141ddcd4af49657dce17989a40015defce5a61c9061330154e319909d96dbe4aa65d74b98377931d4699d9d4afeee4bfd54df663ce338e348dc2d5204e4d26e10732102763143bc558517b6f5f7abf215ff66b34228e81b40fbd498daac1d9be0008dc64473b559cb6009b9e77060ff070e3f3926f9e31933e82d15a5b49abcbd64c0ea9cd3e4129f29d2a548846d3ca51bb5f915e41d730962febeb463a7abb372a96aabc1af4d0dd9a4cd87915d9f416fed2fe0a6c5a32e906310fea2ec1de921208e536442e78aa04ab7faac6e1bea5ecc2c5624956630cf4674ed34b3e6670bbd8fe0a0e3dda01603187c0777fbea1a1908621da9395952571a56a478383e408cd3ac039a4ed983c143db772a793be6a33176733ebf871633d51cdde740e596423ce173016d2cd6024dcb0f9a3149e72b22fca10eaf6c9b7ddb604d9b4bce54165f8e635e9e66e782dd4292db9fb3d0db3c74e5391bf490bc2cd35403647cfd6a686cb0abb6c6f316b9c9ff018cae0804d822c1fdbc8f13c94cd9476d08c8deace3c1f2332bf324d868ad31ce30378d55ba9738cbe270547492bf7836918aaf35c2de6c1fc0de01b3b3f1b6c004b9b044f77445d185f4cc126fa6c37406c3997821495f05436caa9c0b5e0bdb4d7bc84024865c0df923b6d7e136628f79a500160a4003ef4aa0ea1a2ff72eef5abcef63c7a4847573428ca8b77c58a74c1419451b70fffe4c5a08b1a0c248131d75a30a9a302a7ca228d1b4b2daf33182257c9c1677aaea673bca8b4fc31fafb55dd4fd9873c693f2bb67be77632662b0ece6143aa7578184e592383f209a12ffbb7364aa9ed7be1f1408b5bf83e58397cb871cd24e2a780f9ab9287bf7becf7c0d796cab4da0fc04e616a5a850ef580f44b58fa1e8d818da030c459aa111a66903363b74267b403eea61032e7805d53901fce3a599e9a5e31451066f0286853a17d13bbfa79dc27c7d806b318ef35c2172115915b597b5339210eff3f4d006f3f05b1a0ff43d677bf2239a94ae130263fbed4255dfc39afc922b3fee512ec859b2dd2c909a1a97f246eb1594ffa640b023830bdf0e3fe051cabbfe72517eff7e389f2748122aa75230932ce1d27822f40bd52b80a8995178ff2520b065d91a2dc541163727a4102f8bbdb9770e5e7ace6cb770bd69d2ac9157aca24ab27f701af9156857d0f953b3177917271bd12ae1500cfa1cc9986a0003742909696d506fc4354dd08069d642d3ee669922779b032658811348241340a807f9c30ccc26924810820a37901f6a3260206695891c5a98828689bb85875f950534b0ada027dfcee8b384f9535191ae0f949aaa176e01737be18021a32818983d9d0cfb18a49c26ae65d2d22f431a063d561a2aceebd1f010aa7538c416b430771a695d19c6d1917fd14c34df610bb1a59e070ab24b638fc7ce1501e014fdd778199bc226600eb6014463bb5477c37e26f14d9a4c2e86cb02bbdfb04f900e23cd78084d04fd80ea69681c539a03df69f84237301ab5263d520b33583654b0ac91bd1abff86c2357034a47ed7451f180d6c198212567b17e876462abdb680f0d32fcdbc3a581b613ada3e3c5c7881910800cba3605c33875aa111452062e8ea62682b7aa141fca5e08f3c4c552f0b0ec6a6e8908e3f144581e6c134b818d2e5418bec9245ff031c3e4b1b792da12c7b015666cedaabfdfa9db15e9afe946347d2dd6890f53f20ab828223ec5535eb2efb5dadaff4cade57471e602797d9a3832761b57d8665366161ed937fb9c46be8fa7f1df59039484c8dd761538968c10fe0c62feceaf5f3b2d8c40a12cfb04059f88809c20e5650209005d5bc72390bff0755d849593a05f1a902776d4124923b8f3fe3cbfae051a5ed6d2dc2adfbe358971ffb40c1e74ca0f8d9472f9b82262c92ece7478509a48b4d0113c1eb5c1919656ee92079febc72d8c081f540cb69b88131340ca569f4fed0f856478de9293af3e2c4cc33ac94a6b307162b4a52c78c153515523e0d3649e9115ac887e2044ee48a5ec8062cde12fe8fa8f271dd0e4668118e5aa820753fd6842a048b4e096d0044b31df7cba2d88802ca834640a1438d07903face7e8b343d3a988ae59789b0d9d0c1154164261483cee107e19950514447cd2bb6ab1934524d02fcb851b3b78cb6a76635163e331ff33b5e635678ec947f156fa79597d09c90697380f2a6a97de3ac74038e04454e3e43f7ea6d93befda232d481057b5efd1a868f8c3efadb122b2f49ac1a6c95a7085dc8c08abf6268141ba154731a457527e67a0f92dc2c06cf782a1419091318632a6beb0c6e08704f4d153e9dc80b34966a1f91c9d69ba8178ccc1b209280b99f89d7fc4251ef6527396b54396a46408fa66103b9a1cafbb8514cd51af15f67ddffd120afaccf022e0be15217a3f79729b88bb6d40a611055f59d4620e08b4e6818014653d9663dfa0d266498265b48737bbaf78c77836433232036700edd374d5f7a37a49b50f255a1972f408ebebf39c201bfb0aa89c33d9b3ad843d4632e82033f20228faf072c629381615fe7b3b00790d235de5c82a9bd05c348c3504640a4563c42e9ce070ea6f8761a78557cfc2fcb0441465bccd43a984f0d3feac6aad599ee5bbfee8c4de2bf432c12b674f81afa312ba99327ef30218a60adc3d49422fef76aee346332ad648a0b17aa905c3343dc623d79129b0f277732ca285d84119d5b568814677943b7ccd8c8d9b86d509b18313478853de55622b4abdce88dd0f3a99d17c85de8d9b67197f029b5c1574781863717083933f7fbf75a9a89e0a5e3c32eb3e2c94378fad1f96ba941a38ef3cdba5f8004f69962be63464144b27d6fd8f09c5fd96563de77f430cdb01857bb24a8b0f4f71db0a4ab263eb0755928a11789d9595afc9f2da4d7a7291b0af7ecd55ce921308b2f763a457cd50cd7da2f4ec060380cfe7aaff2a44c5155cc4050f7945cf6e50c102d806c6d862fb7303b2c17cebb39ab8fdafbc9dcb37f0d2510bf97dfb8d3918a6f70f4adff7ac2a0f5786c48b5645cf9ca3266f680780d3035cd369bf0979a2720d7dfff0247141a0ef1fe2647ae37112e87b68aa58537f81f33b19b7bed1be3300aa2b85124bb5f8f87e7bf801271b8b0a82fa065ad191cda49990c7eae4ce17ec8a98c88cefc7c5d6e559de7bbddb8b1d755e03b2f11912960f4907a890aecd8003662cae0ae931ba2f789cfcda1265f8af901eb67c601d4e6d4c36423aaa02def1d06e100aece649f4fc9e62a94dc65eb8354296a7f30af2a2feecbb317b3a6f45f320ab75183140c25220d49933c73466c0a3e84b621495a0711295d63ace60fa84af825947de6556dd61bad5d2d9c30ea2e15390741b77655871c20fbc9c1122fc2373c7e9be0ed2c20b7d8621b0953558ae372b2d59c0c6bdac9dd8f41237d24ae13c09d8b4da401c77afcf5e55e53febee7d5ea1a65000ca5a11340f6fc42dcf4d98d9bede8629970864e59c95918a8ca620c116763fa2f4efef93f0d6ce538d9c59976c3f23bf156e18ea8bdc27a0b238073fac3bec2430349575565a1fac82e33daa307093a9a2d623b8d4261945d801dea6700cd89bf4ccba4d1c84aa2a45876835b2c7043aeda5928e20bd6ee885fa31f6ede66529c1fcde747c68c83a7c1b48e3a05b83e4ab645ede1581c9e7923484e9af97b9480c43325880fdfe1ce99052f63931a3746e3fbc55ef0d9e048c5ae6d6a15e2d202d88d0ff8a0e8a303a9e93450ed5f360e3a882ffd4c8ca6f1e160c0ec950999ff75b5b77b5f289700cea5a6ba3f2e0ff35382e75e887cc61baa01267c5507a1b97de680e8072f3b935517e96e8f1b1565fd790960cd5b5561a585a210c003ad5175e30eb2c165573de68480b300503456c762df2b3b02596b42548a5245cefaf16a33d946a548bf810d0843370b1b800dbe5ff7a4ec3d3311639944edcac077d5c7b08a9cb44b48cff26b0e3e41a15d8880c21e1fe256ed2f3258e70d0b0e0fbb0139ad6b15cc06c90b221d5c79c7d44bbe3f9e272100d1e48e20b7065acf6a4f04b8824b3f22560303537350e3c376983cbc2152bc0293025862184c24eb17bc1bb5b1d012c3b25b61cfb56bc7296c70db18cae58300303513f6b43966bbbea555a9113509494a5d06b0e28a67f1aa2254e741c489fe0cf15e11461771df2aa6fb45c25a90410ae9f972f542c6a4d0932afeefa7a212fc6ae982fc9e783e9b3f8f17a7c0b52872e59ba1eba64c3a09434331b5d9c2cc161e7cc2d544020b99cd4f7ef79243a25bd5279d080130e25bdafba91b176685846797c34316a3deb3e6f69d6780701010305e88896b850bee1413577e28cf0994b3958ac82aa56750b0f34e045e405cbd1ccdcf9515456081e1b0e3901e29a5d6034dd0efd096e7592673d6c590a3f605bfb1a4241cdba6b3f1d229adff5d7f517fa7e51f7b147b20e1bbd6b85a9b9b8a48d0dea17570f48eb3669e14688b64fc62adaa804f32b00a6664450055458a0d16f422d8a96782cab0bd600e6a3661e69d6b0f9a2c5a4dfde33e67e9888d238d6d09fb26e3f4c7fd672078db9f71842cbbfb327c128560bfadebf4fd625eaab25f528381d82bf0cae0bc140fa2f48a746aecfb886935f12b65eccad902801cba9195a4e002866ebb48012bb3dc3a0fe73610bcc7acbe162aabee30e3107328e072467690f9f02f022ec28dcfe9c69066dab843925cd03a9ad1b9d5f0d41bcdbeaf562bfd37b2f32b3887c0cec0c8bad6158abc21fb16208e1a11bd02f72f2b17d210789cbc5d46e4a2ae7eb94ea04477e650a6cf63be662a914c70efdfc9e3889fb7e594e5d9aa7e16ddbc6c3684218705659fa1c4a94059a5406618ce75b85805e6d3547e2b578a7cd5c7bc9a958073219ef17f6a9beb433693924b7159fe43d42b44621e95b28447692d0c81cf5f6d6a9e157c2f6f6c4e8fd57d3d1ef52a606e653b8bc434874b97ca22d96aea640ab83fa707cc4163fa392c10ee8207c049bfbda820321c2d2357ae2702dc89d4838a0db4cce62105103c18f1f972afd4dd436a09ca1fe7a46ac69ef51a725e2a908e4bcdab609b17ae49c28d8d9133cff227c80195892e5677517a23f8c27d569ea8506964d8012d75456fa81bc110f865a1b363bdd02f5b32503b9bc7b7aa178f706e5f1ee61c50bc61700e286fb87df19da82a9ad16045309877876ba6d81d3c842ce0f67c15412d02f0613fe3704d85bc6903c39f4e1a93655eb810423d69872a8470946203432ef539db70f9748c9bd2cd1ac9be10e9390a687749737fb6428fa9ffb4838b9dc29836a50c641079b2e7b6c59af4ac5bb340dd8cd3b31a99a1762ed34a40b5a726841251e6310ea9bf12f4fd74efb97b09119ffd6a9e426b8b2d0babe2a5b976e06338326b6619b763001884f03df1f3ed9b93fa80c39d3c2a0f6181a8130691d0b5fe249a4e1e100180542dd3ed3b3a340d9f241a36b59ee037254cfe8c96c5f58e247bedf00b18cabd632e17741d29af737b58628b794896817cd5d7739fc4ce3896c8880518eb4c022fb29745f0ccd7d051fcb34614d0c83f96c8132740b3727ceae8e9f9c17c598b628b72c82cbd0d4ba20ee5f35c910cda2ea3b0186407e7a178aa700c83f87becfc6fb87987070ef5235234ca5ef934bbc5057d1fa41604b1565ec4bae6c153635ea2ae5a200ce75c297a29426b8d4b0d32947fcad47a680d57dbda41fd95dcc7774689f85c03707616be010be7b2aff958103a7a56d56b248062e27c666fa1f0ff534f8bf04e3db5e6dd0355b8ec3967092430ff5ba255d2179cb0bd74b4ed3b0618631c811a0e088551167cd5ff863359194ef3b03a046e1e40e02b3e8e369cb3714c0a584a034d51d7f68f8c5735323f4db32d5d5067d57cf6d9dd50f68167a0420c22e4f0aabe006fb84ba21a23e8bc9c0d69142d4aeeb84e4390653e0e0c4b474b1fa9e8567211088dbd8e5376265418c812a40bb025cbe2f5f4e7f94f4ea50b2b54cf39890610e23dc68758004057d0057844600725745cd64a5151213f16739ce89c39ff8df157a56110e610ec29218d24fe58685009eeec5fb32e9de1dbc34e4cf759555020643b4c08d29d9b577f71ef6c2817115738f77595d423be8e2e18140082ecf868efd36b8e17dc0b233ffc5c9a9567be1d233b27f401a4c9fe1ed6fd36efb23d89ed61a5d5268d4510496351a2690514be2483296e078811be21060406b91a4a37ab9e6d8d57161a9de61e0453769dafbfe68aacf8af2138f211eaa1635f80cc1d94213de5ed8cf2d13d4dc902c42bc53fb7ba566a03cb8797d36be2fb18a892f5fbc97deca64b0ae52bb3a36ba6dd13f64f2e115a3b6c91e96406fdbf1df92984904b66f13fe1f8ee049cee577c08d3e9debc1f6245406b32390432a91500f56d48737c71d4a1c44bb50c602089783485908354bf156c989b0f30383b7896f2df420560db4875f55ff9d56053e938228922bdbe3236e72ea2d1d6b87e4c220256392f5d83fd4a94ea89da2d4d28f6a4d8c65ba3d1574d1418a7abeecf5b8f7e759a74249c9a57dd1ac0ec544119f144ad68e75047097070329b44209ef21e0e9cd3ae2da357357a72e65180ed0a9c9f699880db5349c82319a793b43283ec81787466fcd680d6b88379e94791700b483c97caf93b5b219fd6bb230678f2828ba107fa002b502d302d889edc95ee8b90434400cc2b5a5e89a7c34e5d072cfba29f1dd1ccc6ca90a02293696a40bf3b82092f0f80efd27b56bb4039b419beb821cf9e6a3c79a19f9420c5a8c4ca626e3119217e6e18e8f7150c6f9ec8c7c2220aca6146a0467e1ba4b67e6a5c62abf7747ab094a18e2252c14e7a3c4889e781a7f0c94f1424aa4488a4f13ddf5e43d9d25aad0b5765964b32551f730dcbd08105ad85f6e250a4c6d6520df9d57529b6147a260896f2e6ac799c144bd8d8e7de1a26786ae57907a5e7de94e601aa7420961e3d21137f578f9c1826e215dca856ee4bfb47ee2ba7c7ecf1dfbfd4d34b8dcacf007c5fff136a9c6c0c52bc4acf2bd48ab81be57d458436085f7874dff72662ffd7a12275b5edb14cee8be79496116a09db521346eb201fd15735f54c8fb03a545af870ca8366571737016cd69879385a95a700811b9662e560b71eb556075f6c851ad4e5ef09efe76188a6690bc4e906cf385325a195d362d42312247d54c7862b51eb51223f6704efe89f0778447d9bcb79272dad18fe77de3009f2eee3e0247ca944487e9975189b07895cee854537cece69963a7394a4e9d7964b1c7812eb8d885d72d066f5a57482c466a88064b80e239d317bb8d323318eb776a8aa64c432c0a8154b9ed518c7da60e8e2facb96ff83c652fc5603a408284a104a5f9a584a85189077a0bc807103c36c7fbd2abaa970444ad41969a55848352286e42b4ab979cf59b5a2f00cd7391c07c5deaa728d6e62f7b3b4a0febec155f8c7da6628d6dabc0d7bc68177f921a945414a753c7b88f73671da9bb95bd9a5ebfbdc6ea1f4feda15331b1cdd467f0cf7aa6a0828dcb20802343bfa93313380de74339dd100cdf5cc7a1046d457a63f65256f31fd7be49af2a2f1c94a28cb49fbb34f0a8cdf2f9e343ab20d6fc0773fde35b7a7f1ffa7a44414c401254b5da62adda12c08bdd48c924a8bf0e5d6ffb981dd1f82f10ce36208aeea7dbe494ed540576f49357ccc07912ca8cb67a2344e3c8f45eaa0d153f52958eaff8c502ba81c533d8f54f89b2c8bab96ed0397bbdea6ac3a03ad6e3379d095d704efafb2b507f84ee0cf89587bda0536c073d0b71abba57881b40cc7d05154efa2f42bac7544e554c41dbc25a13ee2c61d1172e90d900302e0412ac8af5bfb89913ee763842ccfce4e75d10115f280eda3167a1f1c377d6d21e291587a3f4fbaf99d985fa2884f74013cf2b52fe25d2f34e111f10cfeb17ee97bee7ec337ef00590826ed1ab067fc264e2b2cb5b847064e25e0b917b9dd5ed3884522ce6f548a0ad9b0000305647e3573c597c1feb1c1be6dbe09234753df588dae8dc152fef226901825aa5989447b43185d216f97528745d9542977042bb97e7c3c1e3600f5b7a2d67fdbfd851b604866e0363768b2b8a3eccd32811b3ba19a5de8ff6d469ce01d431c82f6b1ce252ec64c5c8829dd2fa353cc37452ccaf71f45b558c119dba5a22e84ec8d2fdf5c23480ba9218b799e2218d5e1b5763ee4786bbb5cc6b8adca3d40abdbd3bd7a950331600f79cd71c8dbe8eb1805ca9008c61bd771154788c4e0e407759db825dcc93a2f691a8621acef40033568d5eb12745fc30c8394fe1063848802dd4c7ae585c58b678980a12809697a55fe3e58d75b213fdcd43644002fceb9669c11444f74ef8a55369d0299cc2d5da14416519b0be36a15863dcaebe1a233d8b81c18c74efb652c84344feaf964617e3a95e2a87278867a55356872312ebf73ef4dbafae206e433f107127977f6f311f600c47c4eb70808d822250c7a89492b912a0b8cf8154cdd9f1eea0c080f04282b37a12b32ba0f685d84e3f4597c30fb0a18f79f34234ed3955ea1599bd8776e35de1a814fc68b8b10a898b48d0851f66754d0e61b8d1e220dd50ca0882dea0eed2449871c2147f36ee4380c1912c3c40f5a1c2d8c951f54377a01751e1ee2dc8e847ea1ada4fef10c6c5fd7d0879b1f19ad1c83674b488dd350c4eb626db66e40343bd2eaccd2def12a2c16793c2172ae89ca30555d34ea73683f89e6b8e11cb0738b77081aaaefb9b9b2080e7700de29a11edc66f18740cf482db816485b14769c4bc73e7b9a6bcc568084c55d794ee113bdb0f613b0613ba961492daa0b47ad202049184c230a2ff8439418e5dd25887c1577a5024b09ac13a3c88fe7ff47c4ad537ac8df87185ff630df4f56161c7fd4c50bee6437a3bec0a9065dab22693b28f45d4ce76baf98daf9031eb79e7bbb0ec563875d4cc2f886ac388ee5887f6e0a85e6570e94178754548b924e076be52d83091a945476870d436f23a687b80d270908ae14afe7e6211149be07c4cf21809ec96996ecfe473726ad2a2646be4e371ddedbec2cb743a43a3230964fb8d34209c2b75294c7ef279cc5e1cdfd0e189f59f49618634f8ce798d72905bfffbb1ffdd0ae93d2f1affe34ec6da8a4d691eff1bdd0636960f46eb38d5710ff773e098cf0a5c31be100527088881f00c4a51c87847075c97c74815c97bbd41a6dd4039891e8a2f66532957d7eb88eda41c622b74b42703e1652ae120a28ab64c5ec104fe136a322fada09bce61048c4625ecb61b140c70415c6f2d56ef5cbe506a0aae9a5d3e62964b3d15bc522f5924d43f3451ab1c72c804aee00b1e70bfa089d939def7d3d95aff5edead90535bebfe88a9294779882c60841e216e6223abf4250e086e3f1b34a720959e94f6745261b89403042090560aab2c325791c110c1c3abfe45fa0e8822161847041c01dd9908607d918364d36ad7dc8711909f9342ac66089d9009e8275d0e8e89ffcef710447321504b0f54901d86f0151c177b9a747346c9940820a89783caac8cbb0e4bd14620bf3d5173b5f9780b0801cb2332c2428cabac027c8f4b287901b33e288045d47e20c2be90cd72563b096386248a497a5c865c66467830c596a07df10a93bf14860038a61832341d72d98764c7a3fbebfc340f57c128256e6b55399ce8272c1b718fc6380479b4cb15bf1190c142d9922a1b077a9adc59b75867e95ed048bd900c54bc1affd4e9633c9d429cef1da0f0bdb707be21d4c8443973e1467f810a1eb6fe0066be652d8211e0af53cddff5fb61dab65ba948407b5080bc8241ba0785919358c915b172090b93e91bcba377d72370adb89781e1b291faaf6e4064cb5263d3a833ff1dbca61dcafe231fb42d4c88434e5a589e4fcb9779cbe642cff2c3d263affc9e4888beed23bd700a4aa04ce7a39e739e8a2d5e86a02144d585f5f71c5d8aecf9fd46f53cd72e338eaade0eb219fcf9c0154d161297d5409961d5db746429e3bf8b8e0b63a329e0f929712d4a64038de7f275b3e268e4b524353a5314228f40686334b84207e52041629e27b22fe84b25da0f14c7244c2d8b48088da8c800119541291997789f266732884a821cb2a9c8edf1e21ec4ee5769ece9a6f1c2b7ce757d06396985fcad37fe37c2414f9acdcce4593143e5c1b8cff8eeb31ed41335cc8e0b0ac653274b3617e8843da69c6078978e702c773ac8e19647e4e6fa7875745d3465a35615e19af792f965d87d01589d5ce823745443ecf1e55ca00b8b6bbf0acf70e3559a57b150255d86393bda933f08b34033db2b844acf67d54a38187ce3c634883b638db2528a7e3cf46c4f3fadc1638a182b2dad2b55802d33a952b06488cba2cc49b2531f016d8ec60014e346d36a0c50b059106dc81ae724d199e602ba0da95b44d304173e30ea24e02757cfa094ba25a441c2520832ba7697774b593ef17e57cdf3b11fb803de2eec315204ef46d39a6f5880a45a16779afe37e4faf284cb88238ac1172dd69c681983e7a6fa6c107dc6f4a1cc8cd88c66743a5324416fd6accd33fc2cafabfaecb88d3d58c89b76915fadc8199487768cbb4859595d9658b9a05c67743f6c54a175915f65a849870b076d1db0586a94fcaa0d5eed3701b56ba766562415964a36b96920272b7efeae04d6504e5c107cc1cfe5b2f54503e7bb181ca29cdfe68325c7a16ce4a9f3201fd5f3677ac576fbf61c85fbde3dab389b4f1286bade2754ba246f8cf5eb9c21dfc1542dc105608ddc5f5593fb6823cb13132e4639b548e95047a22ed0c2c5ffb0fa735df453453f85cf3dd0060b9c37ec814d00e9bd9e0a69c667b2b6101c3ff7719d0be3e5e63f2380f666a6b1604be23948782c82f787f04a795886ca1ceb620f63ac92774203ae77262574ea85a0f047e803412b7441a852399a6376b4af9c759a87d4490816d92876f3472966ed2f63d8aa850cf9c0f49d245ef410a12ecddd44d6160e99302d3b46bfd8136e82ed6bb2f35d2937c588b4b1ea8c58bd69246a1543a8e59547d2f01b8959498b740dc882d09471c3603eb3b863c85f66b07c73b39dbc20e1c2c3f3ea4db5d60eba99e7ac1bf4c3ee648dc5854427f4f40aab3a42dd19ffc2355bc62e204d08dfe607f767653f61fe7d7ec55fb0f9c4155ddb716f3b8866718ee44101207ba7c7bcf7a7fb34309f209488e6c0d84a32bb04d03a7f90686adcca6adfb8139a7d845cb1a3cad332c21dc3200535b437422d8d20951267f011f3f744f575c4bd6edd2b3e987025c11e427d780a119ec1270148226ae7de749c41a0e84769cb6b81773117c6c7fb98ba4deeaa001d04a05a1041ae795650a0120abb3a27060d41b6c51c3f3e699ca5e9461b22bd4cd9d404781819e4774a4202e7c83572df486b4304e9b9ca6f8ae9125e70b213fe79a3ef6fbf151461571b79add16ed0484f4a2a860643716288dfca4f9b7f31a5ad41e573a271e124df3eaf0471cddde07c5a13e874417502c278ccc63d22e60a0b1d8c4d03c6ae59ca225278567808c8ba324b964e77a5bd01b0b4b329f8a104b18c902e3494c52d186f0b6dcbf26ddbc35083338c895c9c7e38745536e524403269079e7d768f4ce2da59119a98c5a8065d3847ecfcb769c65eef17d6ffbd2c9e4d48f152532cca742b33450b5f46651f2e05037873eb08125e29e4d12cb299f849e8095a352323e3fae036b3d16983232ee85d85c314497ffb4a625a00b2e26b6e22b221c3e5a4d1d45d5225a634d34a15a960031bcecb7e035bab1533fbf755d00b0e298839222641b3e0acd26f52d5c3b70f377542d578faef4f0d36036f56d3c12a8cb398c091bcf81c5ddb9740bf34add0f936ae4cbfb5a87f288034755c56fc63aeed91a7c748c24a95b9b2f74c09f5d37975fa030e19c6985d67f7b91e8f96d861bda38a546597518d3e9912302cd2e8c365a6ef8cc3e226acd057c5855e30ae0829766d590dc6504d19d41ec5c957c873f8de54a3068fdad7063b94d1f0ace17ade48130b0edc438bb9d7a9da0b493193618bd2cb17549d83d4424d8a7f90542588bfca023173543e584048d058f076e091da26df3e166af9145df3fb7a1b2f5389cd09e7e2c750400d23f74dd51b4e3598794881e60def79f6f9cb08ff2f35be2ad48fd609ceb7b2d343db15e9eef0b23b3c63ee29f9a264fb3103573df1a95354b9051993acc08c80e62f835075cc958e8fc1eb8a68afb5508bb07cb6bdc7e0b7736accb51e8b3fed81d84f0383359e38f5dd879d42096ba146b20e35c247c78d59eaa305db89662b55645deeb96b0e9368b3edb85761f667cdec5e413e130de1759acdd3ed695d1cbe02f045968ba37b91e59431f6661a2de217937a2cea617f1c11e2419b572ce40167fb387480457cdc8015556d636f885920223f891c4ced227561885e1b7291ba2ebcd608e7b22a40c942640da3ab41fac9c096d3d624d970d227a4807403a6427dd9a15bee91660be4fb0a29558b0921bfe940c6ba3af383d1567e826a20e4fde099572cf8c79a55a566fda13fdaaddb3b4623384f3dc9a6bccc225d6529c0e2b12eff805613c2b837e11ae1e4a1946811cd70b2bff2e116439ff8bea85ba390dea3352f8ad6fd531aa226d4f903306572f5f0f496bb62c9bde2cb1b4f3e6cab64295be4e44b01394fc552b5d3ff385317a7b8738782e7773f0c4cd3a0993610c2f577b63ce2a992dbed4f14ebb9ac0575641daa60073036b6c7eb4637c4887e2cb3dddf1536898077b107eea79e1cf0dbee5730beca6e1ef97598914411cd0c45eac0f8f595d9e7b8644567e875a4277405c5ecd79b06622bb106aec43d8fc8ac267867598db479a715157816fa00e9b1c636ca42da9339eb42bab4478760e82c514ee40f092194c54c7729ea01840388e4fc384db1c2b1a96592ab9c2a9df76adcd58997dc6b6a2b5bce2d6e2e2f2f6deb4c41081f7aea47702f1759cab870b5f4da39d3cf59c9e76551845b9713a85b070dbf742a6e680ed9184b74d6542d8ae1e3fb3013ebb5c491996de90a063877f8ef34beae835717762122947bafba2dcd69888638404d89d819943e48d45a1101bd08bd833475642d0ccefe2a9dbc5f0be419bf953ed527b4d9cff8820b2bc6f336a614166a28f5efbfb0a00d20d8f1053a2ec2b24a2b85c9a0bd1526731c96033cc968aa32848c0742f603424fc95da4a509ba8b565f56d1383fb5e44569191c0bdc9749c948fd09a8aecc4b155254d3e1180a439124f0bb2a76ec113a2702750b987a66fb290ce387b6dd0bc468e6a263e46a2f6fdc971fa33e50201f035876a59111c0feca9d1f848a2d6e10624fea4e403ea131410e0d8bf3aba6cc8cc603e53fa30dac4b31ab9efbec40b1a234cce7477cfaad188b491885279c541b771615f0d4307fd8a67546ab86d4c8ecc60356414c0b0f19ed624f7dd7bd2785d008349c25186ebded50d45944cca2d666dc5c432ed95db2b3ae2f099e67f679c1f8323ec4d90bbbc1ae7593e4fecfe10db7e9d57445a2f60756a35bbd27b444635b4f00ded169043ef06baf728dc67a1492b0ef58136a137aadd4c6203fbcb584cc6f391ef1ba9bea7388614c331054ca0444899f84ac8e423324c589eaba26bfb6ed63a0d73f279e1cc36003aa8b0686e9c689037d895276f10dfada010209e4be363d4ee7e659dfcc13719d2d95a2ed8ec9f6d7485821217c1a518a9d689393732ce2755459949dc981f6443179f45135b58593b4b71e30dfce7928dda22df267b7367be67ddfccb48a98f51e618dcd9eac7a3d14cd8c2cb81d6eaad8cc42b2c2c75ce35d6a986230ed369719659f92d4531573ced0f495fbf80aed44f6ac6bfcc2b74869fe8b236b52cf05d1810650f4e875ff2b08cb58afe6ab3f586276be1a8e1c68f72277f1374d153c8eb7e7e1e97ef044f334f70129c6ab1d9bf64bf515599a4af2598b814ba48cf97b37154fb519c13b45037dfc5509e46cf78663ffbc9884ab688567191db8d4925daa9b39ef201d2e7714407cea2a0a6fe063c93e8e5a84a487771cc13a25de1f513e8b4334544b5e3aa8ce441aa82c2b75c7b6da52bba4056b65e3de6038afbcbe43519211efefebd2b53aafbca949b43b43030a3dd92250bdddff27b40168b0825341bec009b24bb9a5e7f5fb3b98bbf7c60e52869781c9a90b268477a90c1f682f245d8cff09aa8aa7209129b517572ed29d5d61d0bc474fc418430d098f86838c8401415e516322cc17702ce43f47cb74255db8ccd62f7e3538dbfe0e981cb529aa480b84bf71e2708a7054ff7d9c7afabb12b3e76a5ad067f1b0de31d1c6f5e8705ed25064243401352df977b19cb3784de9110d37dfb9156ece8ec892d4400711045e284811aa536db782d462501bc65539091284f0dd69de26538a846d6e82aeb8f567347de9942ca262ddf5f460dd4f8992f43fee8752e336ff95216f2e9232a6ec295d103876c9fbe8fd15ba16f574aaffa87e72d56afa02d5e32260c8b750335c68da30c8d4ca6f9633aadb617dff0286a2e51e581e3e2e226494c89ef4a7b5115594a3d31714e8906d5d0dd281daebab8157df39c7b30cd9380fc764eb3579a889d230ec8ae6473752ac7fe0e19cbbfee0f7841894db7adfa1369a1c8cdaacdb45a4810e677d781ae647f409cf49b11c8c7f178ed0c7d168a8434b6096d5cccf5050691010e093dee02af6ca962013167f56d415937579eadc25fc920558d890a51cb1e7fae5623e5d889efee7859069677fb9a1f0a5e640b62841d397bd06ed46ce54578f8b079042191a4dd77044947dc279fceb9bbc403917bdb596e9f80e77a832ea3a83638e098e241fc05aaf9a64c74c900d3eac83e09117d9c7baed7ad4f1af2aa004bb3976941b775f7c2d03c0464b3b68a0c75a4f04163f7776a125323c3ae6a81ec37284b91afe711b9af41988e5819282a434ee7a7e2e4947b7298b269397c344aac8565656c236fe62d7637eb34cef5a10f405fcd50ace068f671c039c1f5384156eb8b17fe8f2da899ba3fb39b8e8615dffc30a75ff8a7f748f4202af28a38a301bccea5f6c4d57b374999fe261d462f3713378ec1ca468ec6ee0592424ae489a280fa51f83d264f4b9e511de71b1002b06249dc461418a62bfd99921578378a37256cc2848ffad4920b5b8fbe93a9c4b90d50eb6aebecb4abaf4829a6a35093e8d95539fcbbe3c8b48979477c70d0f879995686d18c81acc1a3634c01768d02f82741c2e1ac32b23c5a59469586a1f4ad072a794d7454a37c3c4322e6966954b7b3612c7e8fbad50196d4928e0f787940fcb47ee92234b4e5a6022197810a1749c245b63673d1230de8b5cd4a253de5469fd1ce8422cfa982c9ca7684d37abc498801488f9561208b6c1ca4b234abc54124d0d4a1b7f9a9ab8fc0d031d036dc7160e5a62abe6b6f091e0433a5983fea47fd5814f2ed8b45dfd325a942c18425e3716be38a7272d2823737d3f9bd88ab2fb73f59510c8916297e2aa3da25435dd24cf24270c3f29007d81739908e232204948133821dbbd9fc52ebe925a12cabad732a90fe173837fab0df159f6c0c5eb2c46db6ff34c56f843aec9a5ca9f3d68577c4cebf4ef85735b5270bbea0fcefe97ec5c9a3623bc278f52f41c255d2b97f93168077b6523c38ae99bfe94b3d2edc9168b4e741ee8bce62bffc6eb667c23888ae9f076d0846ee35418eb58ce3841a328ec725bf4340df4d3c735eab1415477570206fc7ac982b75e83f1719863926ca4b77921e77f4a54d01718d550654545f83e3c5803e6a30f67e28652fc07b566897ac4ff789af19a703755c63f60de953ab5d34ecc5cab9657ce897ca8482d11be5072d605a04cfa73fadce0066152d62c338e7cd04f6d62a1ab859c5b3b610a42a7fa27f0de92b10cc94dbbdaa1960e23a7aefa9d290cd4074df9b1e1b10b990a8e8b4be5435f7801c60df2c54261437d390ac5015fb1dc88a45a393d211c3a265938ab114b50c12b44ac6738fa53055bc8fda920dae15e455b8363c42a0b7eabec3b1abbefbc475eb57c375aa07850214d6e154fea826d51685b4fbdd688875a0d071640c8a963facee6bec8866a089f6c625384e65f48d9294240f21ddcc365237bcba1299a40124694ead7c2f7de68c0ebcc8aa392df66f330ac2658c6e41091c789915f935ab2e1987605ec64af1e38887a1e0bb25943bd57f099233a4b963c7f15389ed8e6fe93a0c340e35420e2bdc0181ee7228780749d25eb96952e8081eedd08b472cd95dd99dd94ce3da35402f7fdff75a8d596c275a0f6f8185877c2733a60e3b2f96db72564624bae4c90e7b0ce08250d544bd58b7cae04af17d1cb7e59f5c8ffdcc457281ceadfe98c63074cdeba5c436e55c51680bf7e450edde41a1a3ba7b655c046da85c1727dd362d9881b24134de9aab1102e86acdd36f8e5086feb8f8ca0f222bcb231a010b2679a16050cce6702fbf5c096df14b6491ca007151b5f5235241753192b36bd9fd5bab5c8ba48e02f2b68b9b23cf28d584390159ea6334aa08acdaf503311bdfd3da309245a6387597c1480590923f70ae6b8db420c0a062e0e31eed37476becc87a64b7acd5d70b2fc0b42f2a3d012446ed1f586c5a654c0fdbaaaa2c5be129c6ce6f7fddf7f904243232a87ac948abd00f2df1afa28b76e1dd755572d2982bbb9cd9cf6593c0afb9e94986a93f067fe301dbbda8574dace5e8f5d1080f32d295a4945d12f8c89394e2f8d717e560fc54fccdd306086f01f8d96dd144cff175f6131a8ec8c76e08212dc9d0264264c401317105fb3e81a50c6817941f6c0191ac62c4c07162959a01cfe89c0edcf2e2b7f2669adb990e1b5e6d43b7af959319d12dd4a9bb45f200e35295e7bb410e28eada54e8a5aa229c143fb83cd6f5336156378312e6db6aa1dd8e21b0bcc6220bd73054ac1b45b59137ef259f0614160ebf5993db2be5814cc716710d49813204a7d78c6370dfc2816f8d50f1e6e8b7d01b27635cf2f0e5996957e2f1038a29618f6ab1f784220694b1dcc017c2f03cdaa5fecca9ccde22f2f7068bd373d3f812ecedb6370b3ed06322f2f09c560f2d455801c00135c8f8259afe365548cd4bf0e5a8d655dabaf90deda8ba460df111dedbe6e32f8cd1cbfb08246aaaea3cf09f9f18a82adf9295c7f47c601624382fff9b371412047f06ccb532c0884b7bfcbfad752bb27016850bdcc66091c8a4d681b84e796a5a9a339e37109311685d2f73f321383e2fe7fd3aa5434b4afb882c9095578f9a7a61a3f76a8be54b6567181634fc1aed9fdbda8d42f762ea2362851cef7eb28202ea0a54484228a877109b6a8da62cae4521a9f3d1a058b7b276ec36059cbc0ab4bb3ff12baad82830354b97d4b082cb3ba71df39281943109f3b95757121ebbd78f841746d71e1e681c8ae3bb0180dadd3f9f909a216c0e159ad600670d08ef7d3289370030635fc723c1710f0dbbff40528c4961f1b07c385bf00c058ba584b2d43d235834ad1a2abfd72db77d2344b33f01c465f5c1f155f29edeb0af85db000e02bb1d9479e34cfe1d8e380d6211a11a8eaee9e7bd77ae7902514e56e58ba852505b0ecd45447023d6a1415dab52d57eba4349e3fcca19d1686d6a483487692733184b96354945df4b73383cd140241e6d2c170de21ac89500feeb80cf556bfa0f7971cb13f9935892206ff31ad18435daa5f3e64df8aaaaed30c4572fa281b99b6ca2c3bdfaa0dffb36e18403c1316215d54b243426287cfe268d6fa22e7cdcec6aadd94449657e1d18f245fd2042c1d10fd1f16d27a9b00250521b569e66c2ac6dcaf5d0988632bd5e203e3f047c2eeacb25423a5aae8fa4ddad06134b126f1eafa2111564e220ce1433c96b75ed99955b6bfa20cb8e4a4b491a48bf72d7ba0fc380dd9c839cbd82bb4d4c4eb9aece98d979eb765f03a13bee3b3b90868e9e64cdbadfe46757719a21b0a8b8123a45825b0c5ea0e09ce7aab2d0ee46d140ab50169701997806934efc494e65d33c0c3a8413dcb4d2dab4f21d5282f38896d2692f66a4c273a14c37131f7235f72b0eab04e25e7223880e980917b89b5cdbbed060c927da241112f95a1255804f62397263594d51869064cca13cab795569fe7d12c96c860ff7e24d02dd0b5278340193d5d9e69e67db8d1acf4d717a5399ddfbb110645d9e01417dc21a903c3eab56d15f75384d7c6d2578e5cc9fe263c5a00bb72d9929eef7e1ba9f494d852b58b740db72450ab79eba58795ec113b0b3a1b7778ea4c1becfd1b37782f8fcb620484d3fd244fdd24a4302dca13164b2aa95692912ab054a29d4c79a1343403498f03e19a0de6972e389a6cde8183296ca45b2f36392678b2a0f276413405e1fe199bc8396adcce57ac87bf154577822f7969f8fa36bf0b9a6b5f8c490b164e0d79243fc2d814a2d31133d727c39d1f49703b8d0afb6c44af50f2ab5d68c04f9c2c0c1a797d2badd558c8af5b51106cd03bd1b41f3a6cc15f4bc80c4761b72bc089e567fe667d9f174a2a0cc98463ca0475263e25948156eae70521f05792603021d62c0398be5ee63b62691a90630b77a3d05d7f6b4ee8d4aa280e76746b877edb493e65f6aa76271487edc366f74b415896c9a13d1b9b05523ebfbcc4c981610603ca0f7a9f0d48362f00482b0918ebda9ecd2e587968e3c2e804d182457ac2d07080ccaff1f4202c4c67551de00d761974e443c658c49a9a3d55014a0348bacc8c01bd52ffdadad37bbfd4288e6972e305cb4d37756cd9b6b9819b5272cc8e82b62668e070f139783c9f0da70737eb25ccec999f1490b6169b44532d5edb330457fd819a7f184830888bb1c7c979f8045bcd4d040c7b5a26e75c2eeca4f57f46a7b829449027eea3324fa9025ac95dced8146dd84550e08725ac58ff29130cd867374265e0cb90bdea8a49020a02f351496439c62e300d3060a253b2b3910504cc5e521aafd6965cc0b1b31a6a215bf334a88b55ca503395d3bc06eced56a43c0891d2e90536af031c1d0a9aa1349fa35c8efaa37b0165d36169acc99202b5b5dab0f658f167f98ab380f50a8097c95b11df42dd113797208cca4e78309197ed8cb2cb3e4c968757a244cdce34329e753581e38b9ad3e2af594b7dffd813ae8e638fc0a88da61938b9ffc704e05cb6609dbcf28f8391a144a9cc163034afcd216264bea2b3de8667515aee083710d16e7e3d1765b41ee4e24035bd38d7369793f1d64ef9a5213f89d1724484c3186375e0a8aa7927d638ac2c05829f6824610db764353fe7c907bd55bc4e474873b2f49a0c7d7f31eddb5a58fcc381cc2265eccfaa4978ae5b26bf9c116c4a822b116b91b71c62f3db478db932169aea2cd67a311ef885979c468e70ac90afd08a14ba80863b428d326aa1894bda86d60748ecc216b6f11d27df0f3f7665c4ecc0a2778f0534993da61b329783e4976f33ed82f51c958c7246a5a0acefb52458df822ab7bd65dacde9b69ceb97f018075b953b21d20722a85f10ded2a88ec59d9d987f57c4be7d5ab4dbada96ae63981262474bc1013b83c447d6942d217d01760a4668f329a17173a1308fc4b33b8c3fc69880d04cbfbcb5293f8bdf41723c3fabaa3ac80257c1e671b54305f3d770bcb842fd65ab33c35bed4b6099c644a9d402fad02103d3b5127d074f0147556970a3f830290628f2ce76d111590720a92da39088d5297545f5554b1e7e14661f999a3b4b5d4a93482f1c4cfb9f7992fb54a20697024d059e7224c494e835ec032c45d0e09817061585738bc666d2b80e5d350aa9c19f12e3746ac78ba84925cef0a7d7f9b8b100c6c99e2085e565419ebe0fa23cbe8f45ec7252c1406a82ed88fac7beda0f484cb817868b3f4bd7fd154f221a6f1da49275dd0e2fe0da88a9cd7c28ac4f79c800c85188d105de0048fdf42ecf65648de27329b4017b0d21f506dc1b3072079b7d58488115caa9dacc9c03346978ea8b130ff3e91191c175eeea5eed83c6573a52fe74bfb98574339ab80c4734179636f3d7cd6f18970bf41b8d891e777cc3d6a748be928ed386f270067701bf50fc4dabc65905ffcf49fda692527181a90bbc9630aa97d867ec04dbb7f6f45199563366d85c4af914f6d70077e6e3972e8c8636163f0b51797eccdf115a0a4b9d166798dd9cded2ddbbae53f5a0e7957ba35cae533540098a66041dd08254e919007a1a5d3cac004419944cfa94b0bc00dc9baf140ae73e5d8a9b2bd6ad70dd1616bdee7252168c62337f5c5f42193bdaf3bd9d397b98e2f49b3437990634f8344d551222d0b64694642ad8bccd754d292d0601c66220c9344ea6171711ce4349820be427b58521c8fdd1ae60843e2eeb97f55919902cafae3a332219e22b5115bcacfdf790eef0707b498fe83bdada328a6eea2dc6eb626a839974c02af2661555c553cea701465b41211ac55c57feb43a0aeb0c7e16363a3b21597d8ce7fa7909f3b13d3cf422959c80ff7e8d3613541087eb9a05ab668bc6cbcbdf6b99d283214b56a2f3c5c43117fd25b19737a4a673d7950893ae11f6a0aa4500a05333b9b68899b835a830f84b558a27940bb5f61efa2b4917b4f8d5e0174f994948d35ec23b0fbee5f3648cafec35160054ff812a94c0a659edcd497382b62422140c9f5e9459ce481649dd40bcc0a70a08d79b7420e9236af2a886a8f8be3230bd9e97529bb5b5f7da4c1c1a516a3b246bb6739b78adef3175b4d6bf02cd356d34a15159c834f023227045227b2fc2d40ef333ce0ff182d9ea7b227d3798ca658e8f42f9272977d7aefa9bc163c1c303341c0598e969d723e4693cf568e23d5d881beebcad49a53657745ca0bbfd8eabe0eb46acf198bd2572e103a4221b42774f6c0457c736998391ec9e52efe143b99c70c931881d62db3e9f4b2e06cce1fb32a8230812caba8654a321f29df60b35bff1786cfc0cec5fbef633702e8ff5b4014633ecd972d8438f43fa037288fe57e6e294cc625b20f946da6df7c6bfc707b633c35cb00e8dd34db71220caf55b35225588583a41237fb539d372977a095af4b92883589aa402b2528285f9d61b87e0c2a838b5ed630115130b38bea72504cd641c69310399d688993a6395b9d8221931139183b4509af1c50dab195f3ab56277efc34fdd8d93145e4a6e2ee7b6067134f5c6d4003f6c25a7da067e1469a090b6aca3d52a588dfdb19e879009cb807704729880d3f97d98ee06635c852dcb330b65eb4efe21e291723f727dbc3d88b0bd00831064741d822a6e9de9d67af25b433b75864cbe863090fa6709527d1446808834577f47190d6db58369b7d674f28d72a7f09816db0764085f5f4203b902363654526260b772c4464759a6223452a657c633210773f1bcaa6183e6ba1e6b772933ca8c55937932cd5035e0b99ac125b029e8bdfb9078712c47548b7e0c680890a48660b5521f2c73636888d32c00bc27b6220e6126577b20084160aba8cfde274ccee8b6734c69f9dce7411d1282676f6304addd4a463b1386740f398b703f670a0d7929efed77607006e585b02591d92ee779d09929a5e19aa7271804ba06d3b904859ccd63c46d8212ab1a5307c92cf22c90d3bee3fe72ef1153206fb3f6006f92488dc287e8085f69298d4cbccb4255b6a6ea259c5d047605a7d9ab20514035b2e85258e9cbae911ee1201462fcf955fdf69c8d6aaa3ffe40c751124d9bc574f3ab902638320a8df39ac80792c72968a63a8d8491314a1a8b26ad623202c71848c9c63fd3a814d585bd2104950cc60a819f203cab8112c606042c8dee288ec6b5b0ec612cf311b1bdb1c3c928859db6046372206e8b708fcc3ed1e711aecaca0b616a5d528bb3b379c725b0954ea5d5b688287547f967e5217a93d971b26cc0c0cd867c30766773b9d5d950efc33a3163ca26b35f13392d7ac78794c44cceff72176901381948ceb9d5644aebaa797dc0d1bc33915cc61d051a6b7d286db8a6c6a09b0e15fc6b0d335022993444535c02dfb0d833c98832c9e1ed421785abcc57a50278dbbe08f16176d7a06dead2ecba8f1a65d0c63cf5588fd791e97f55fdfa359e9f98a321ea087b32b186e48c305cd10588171b40357a5970492c907b4889462d74b88dbab98fb402f80960a08d071853f40f2656f54bf1f0678ca8e170e9223016467865d18ed2d9f3d4501a5810f9e02cd50197d2207957d4478fd117f64f7cd053eee52ffbe349af44cd8f4fd877dbe405f9d8802351cd03aa3b5c84c69e84cf6af49f55bcd617b67814671257dfb8c452f43dc68a12a3513bd6ecd335a9ff4daa9706b94c4b3d973cc198ab9aabf8cc5bd79a180599c2df30749a46aa5a8f3ee1b679f2a81c2bfbf0809e17101c34eb68c61ac3dd652f09f88748a32972b4451c416bdafb71b6d504c86f00bf007b062b165008e8c952d0f13226381d9880629374642465b27495ffddfbccc483845b3e9188fc392a2564650f91c49ad3b188cd5cf919e35a60d42a5010ae8aae635ace6ed8bee758ba800f47c693083a93ceae866a6213e25d525e448317dbd2dbdc68a13eee1ae8cb5b14e8cb04f1e0df0d0085c0036ceb1ebafeed606fa02598fd717541389c0c7076bc5611f1275fbe1e1e674ea1e9b66b246b691c9a2464fc1be7b17a1f6d0e6c6f1e3b525b47459f061336ee5e82c5b90ab1836ab550d5dcf708042249659d924c787cb0fdcc25b9510e2adffe737c3b835ff55d31feb3a3f849e953c55cc294196398ef62f7be63a7f358cd6e8ea194c7329d8c5449e6cd4cd5360dc8196de3dca70f0c4359384551c98a58b39f7d5cd922ea7113b0471842e7a84550ce6a7f12a0cf901f8ab1e311d71c30f1e7a2eff0ce29efd5bbcd447a89b5397dafaf133d1a8e0be1c719c2e874c35b2238f31b2e4d9d3fc5e4e71c7bb69060bfeec170a376111a0280bfd4c616e39f03aed46fb260d0b5e4eed3522069188ed2ff07cb97fe8e88cf59a85677332d9b3b3c651f46c72550ef4bb82e775ff4e2ad9273952adb1ac868c2de9014469b1624c9e29cb94e347a2439651ab635ee71780af7831efe155f17b95573717ee510590d56355a16ec0e705f88d8c4ea4d3174984ff24a9a78d3d094d2646524e8817d0e223f4dd3c6f919047ec728c3b4df5df610c3d2d765a6987b14ca83f5c424deacf91ef4e5d4b80dc9cc4daab9de8b225145eea6baa1fc4c85ab21ec2b698818f4cb03e2689bf98c82d4ee87f47c1c889904221422d678d6a8f2255225e3bd3f3ca04b2ae1d9afdc8dfb075606bb98ad117d866d797c5d00abe213be8892c36fbec6087289602e976d86111b3654ff3ff90d7c6f399b860919a88539eb4ccfe7d2a33f7637f79da259e04c525d11f4b7ff847d1cc2b5b0645685eabf0f891e9dd71823fb8316f190303f96fa8ca8f186466d07c12015149cd9e78c74410cf581c1da63505d5bb13ed6ba5e094b2226252e36510cf8e3ed59160bcc9045f77e1506fccf8166b15ee71c5466cdf14c2be70a5a6a10fad6821e767a57b21bd6dbc6646013c6a712f41572c8e0d5e2139a2d404b3b53d7c3805d2df8082203fbc8dc6689f656060d64d45bf35202fcf92d3a87e20eb2d87b7e80a29bf6ebdfe60de2e9735527a762a3426ba25882fb5f376dd52ea97bddfb2fb4ad4376f395409ba6f0bb62ffbdf45bd8cdedcdf5e79cb5b357ccd4bb58cfdbe2ec798f883c9de72bc45c01f688b203adb2e8ad3545f8ac32f88b1d22fcbc31f89e5d3a98beb329bbdecf79b4d704fbe1e2fb334e37949d063e9fa7c699227f6edb52a2bcd09203c6b7f8ed4a32710efe4414579876c89e24d6c8035b0b92c2b2f96286a144e3cee7f10c23de64d70ad4721e660785cf14b4644dca41d7e11beef3a12bd84046e942b1a34c4659d41a9da18eeea5eea04b821517d3036f8df33d8b60f9b4c5857557afa0c73264b7d25be5f422dd99d683ec8c6ca904368652d1b92588fe0ebe5d806d47efb25be8940bd7b8c16458e952018d9ce17ba71a908c5a3bc9a544b6e104899585f1405917f4b633b2a59d17f40a3384947a75d68907dec98d2494267db60ab9c0460939721381bc6fe968dff8156e48be505aeff7ef1e51a001704fb3fb2b90ce223c701efe5b56879103866042ab4cc7c56dd45c4e89d0c91fe93b80cf170ba9f394f380d717ace1dddc67abcd8f63734905da68f69e82336f6782af1b92098cce94c8509191a8ab99d61d29004090d21e1b9aafa46d5014d134bfe72c7567cb16f70c70974a9020ae2996456204a62950ed39ad3d17f97d649564acd46eb9b4c4e4789b5c7541ade90175db26ca152d9207d2ff4e656f1770d1c68284db7659c525cb7a2624a648ff5293ad41e1c66c122b33d793b6cd25bfb846c42f6de52269952ce052306ab066f1bdff64d8b1a473a6fb6d1026bfb0a460a2cdfd1f2b5b67429f7dd091aa74103cbbb0c3020a1741e801082085096773ad26cc9f9626206c601e9d68c79cbc1079e51c3819d6a8e347bb8fc33066eda3dffacc24dbae79f3470d37dfe99859d3c78fe09433f1df18cc2332278fed9843578fe69359b3078fe69643665f0fc33c974aaf1dc017ec23961879d725b21f3f79ed9b4c1f377d86ce2e0f91b10cf90e0f9bb8b9b583c7fc3e126089ebf87e0a6079ebfe9b09354d96cccb09354eccbdec24f365a697e6bb9fc6d85fb0b3b75f0fccd0337a978fed6819b563c7fdfc04d43cfdf4cb85be07ec24d52d889067f5f750a97bf8bb0138e1925ebb9fc23e4e0260bccdbe4a70037053d7f05b889f6fc2430153b45758917eacbf01a3d17fd53001e6ad2a236f8498b22a29134967d93de3f34b2173c69953e24b2e46f608d9e03cbf421d1332d6a83675a14d1eba611f90f58a697b2535fb3f44290e360165af25558a6efc04efd0abf46ef523664b10f7d96c2922f64999e869d7a715ea39f371c007ee453cbf45176ea6996a8465fa3ef6b547b1c3d3cb053bfb3e45fcbf411d8bebada514d034b7e0696e96bd8a997c0f6c5c0dedca9bf705f385c915d7a281be39f2cd307c04e79c9e0b0feaa223fa445f1d8d181eed2f7006f8c0f6953e07df12d9b1d0b7af1463401ece84017c6bf78a64525bd8cb1bda6d6e4d24fdea495e6e3c672ce0fa7ac6b61a41af8367fc9ba15eb32f06dc93a1586319fc9ba8bf72aac3447c7d2208963c5f09aed937aa55e25ad63d11848ef57b4c69f583dfee7588e15c33a3d936d7a6fd24fee8495a63fe1db7c77f2e496b34bd72d1d0ba4d1a077e9c325ebb52a8615af052fb9647fcad22e8eb4044e1c53ad562d19d52a0e7dd66465fc929dd7b11cf72579b3cf5e332ac1522c6bf7677cf9f79ff91f009fb33300909311d6e46df1b8b1246fb7c5338de5adc5c718cb6ff14b6359331ac3c8b1041b0c83b94bb6e7acb325cbd729f74ecf2ce34b10f7a558d698befc185fde96be24ef04465fe6ee049fb374074bbbb4d2fc264b79e0dbfc294bbf60b5106f0bac168ef51ee64eb4cb943196a0ed7163295af0e458d6c8671acb8f3196b7a35f1a8d3c6c7689ac356f360bc8b182e7230a3e14a25d18c67cf0c5e8580c637e632959f22fb0460fc3be48b27c5f58be5196772e6ce9566eb6046db6142db065ad025bde8e6c495260cbdc1d6de93adcf9d6966f4be7baf327b0a5db70e7b7b0253573e925b27c25b07c23b07cf942c057caf2ee766079c757c8f2a561791764f9d25e3773b391837094928d361cd04f7ca32cef7af413c74670fc466f9c31bc40aa0de6edeb07180461fceab2bffb17fd09cacc397d9c72e6d3ecd94aadd43cb4424fc8600bc1a194524aa9f70945b0b5d87b7fcff2e7a214cf09389b98ba573d2794b2bb4f2f6a2895d25b75c6df0aff560c0d5def87aec7338631e7e5d9e44966b32946cfb040fff36afff859773690e96318863cea84ec4ebb5a6b5dfae0fa5b46b23b2a6a42cfae132a79097e7f5806d82b4c4727e46c36eb1e679592403009dba698408a3995bc577762efbc5dbb10816580cd12f26c72272b22bff3be7a2cc35fe6e3ce6f5aa78ce9466020649ec1b43b4a961f4453944d10aa97de91eba5a25d81908f5aa9ca647564ee27ee38e117f3d9b5ce1e2f6dcf84ead169e7939a58bb938efc2f3ad2aeba7f9390afa8805ac71e99aa76cb0985dc49a84241f38a3fffeca7a0569adfb4d92576503f318d61cca7d1780609211fed7ae759aebc6b1442da7cf3a6f22a8b351f42221ad3fdf912d1e8eb5da208f2e46ee35f5b504277efd69a2e256b0ad17c3a3e55b751e8f4515188fc09ae841506b16368559044ec39e79c258811fbe79c73f6ec5622acba1da389389f7b7cb30484cccf3dbb67fb122102ddb9df5337b1286e9e24fa0f0981f51ec089481f0479f4d3087f36b361dfb6e508b7a98dbdccf6a03736d23b6935be918e363ea87fa394fa0b211f51ae1cb2aebdcc8503961b72c81c868257582c908aaff55780c5a2001ba1c39cc1fcf3ef2b0f83661cb789b0810e123d6e38306577013f3328d1e22325871aa8aea0ccb9c3268928c050d935d3fa0cc82c66d3a823379f654d40af52efb2c6f58397ac1fb8cc28122177b94b9adc1ec95ad11f1181003e5f1bb36a177bd108b82392db816f04dcc562e18356c623c462cf44c42365a2e7ec6e724a9dc7bc3de6b5027a8c06ceb0027ee9fff173ec751eb39e2d2d70a9f75f8e1e13fc159769e00b3b88acd5c4cdedaa771222e6e0aa79598bc9d7ed1a5d45fb40f4412f655b525da64f3425f3673897bc2507ba2533b75233b596f75574a4fe3a12d9a85feca976543bfef0c806b1046b31fb5e44f0a3e08d58de2e910def49cd16ad9df754bbf9a39fbe9b73a415c450e8caf5c8a1bec584c953403fa6538aaab6ca6375db6b9695c7cc2dbb491e0ddcb2b122e8b2b1dce6d2d46b40b0319b846e7f085c60586ee7c13253e196ccc49eaf34bc01f4938f307a10ff36202fad4fcc1515ad1d0b4bba64eda625b9ec98c8b97367372d8fa1b36b732583d6aeadfce431b21be2041c273b2d2941c076e1379bb6e8c8ceed8f3e620a9f2d3b1320b8b363906380ba9c38b39bb668879d09b35b8ba474144a422c41fe67db7788e9d31875e608fedc12323751eaf369328fbe3d9a9d99c6a31749f3f5c3390b3dcbf7d5f298a2f7ab24d459b53c426f2a76fd777516dab6b3d1f3a6525caf968800b49ffd0dda2c8cd1ffacc299b59abd7bcf3be6a5efc1d7f94cd6d7a3b682b131f4e88fce32410f046b6d433abb6dcbbbefe78df2d87de0bbb5d153bcb9252240ecc1bf111b6ff023408cb883c3f8cea5da51ede667adbe17adc0470012e20e0ebb3d76cf4bf3e93fc8bbb2466b30f56466a77deddffcff9ffd3c8349224eb27867e9f72e917aa053affe8e0ee4592b6f69bef7aedae974f4313d90bbe7341014b3c4b2784f2d0f3a5e1b3d3623c52a3015bbf36f18c9b2237773dc2ed52ef6e18ed22af644b2ecc8dd1ebee4fdb42555e5ddb4a509b4c68afbcd1a048e02f841e9376951348b8f79bfef9b94099870aad2f61e469d3ca6280f6f8a52ea795e04e0b5d29ca2cdc37d843df3cba36f094e5a54d7b2561bbcc7598efaf4f22dab8312d0fb3dc8774707721f938235e6fd3cffdeefc7a3eff4310510ce9ba39fdfab0fe6a8ff793cfa965e5fcfeb27be6d7dccbba3015d4a549f6ff59ee6f0be7a95d63fee35c6c9ed831ff57ed395fa7bd4ee58691f9450a3fe1c4b3afb678f34a8ee833e4b6f01507ded49baaec674a5b0873621a3a66be71627c6852e5e80f056142f4f7c466d3bd9c344055b16204042d42e3d5e59de0f4aacb00b3f38566d762138a396b5bac0c4d93110586b54900911030b5058b0041e259498cda8fd613b0149d89f1d7db73fba063e3b1386a2ece8c8534629cea8e5343ea08064e79683f8b3130ad381268ad8b91d0ab3732b215f28bcfc996680a09d4f20e423719694fbdaa5a48acfab54885a6b05adec78eb0cdd12450038e536282afa6fc2c9d825259150339e282d084ae7010818a4108554ac18ca200411748cb0e701085868c0614cb618976906a5d1a080820ade662db0fd0c6bf44fd6c58c1b1294d57d9075f1d4da6824140656f729ac8b17b2b6172716af171958dd0f5917afc2da7ec50d0904776aaf10fa6962f17aa181d53d0bebe21fb0b687e086e4a5a39f2616af1700b0b6cf5917bf81d53989138b97f8a2a8c9da5e8675f13babc3d977a7f64aeaa789c5eb5f24dd9ec9227d0cebe2afd5fd08b3a9b792c0bc386c66fbd90de967e378f423055bb36966cd5bd2d85bedd54f9ea495e68b118a0beb5848f63d0a47d94677e2a47d52af46d433aa9f37b359e69b11fd01d2a6e835b2cd6c37fb310cdbbbb0a11092ed4156b2b1f024b6186deaafcd92efc22ebd27e927bf72265749986439a141efedc39bf5abb3cc4846344bbc0f5ea3b7bd91cde88dfe02a38761f44946466f33b26539cda2591ffccdceeb4efcbf5613c5129ce0822fc97f76174e9094dee8951c4c032725db042cc07cb9b63702a3b3bc9bb39bede937cb77c93adf6cafb31f23d99eb43db3924d88916ca2db5ee9cbdc055f9230bebc257df92fbeacb9f852bc2d909ed9c9c11c697e8b17c16953ef60b69fb6571a1dccf61780d91e0698ed93c06cff02ccf62ec06c8f34da8cde48776d6ff41fb0d6b519dd2cbd466f64f4b697d1a28cc2701c99618ca32d0ef6644ecc067176990b4e1b19e09c997989b2cb5c707ca87844ef32179c2e70b21814e118b9658d16115b63c411af0a5c33c491eaf5ade13a427761573c12f4814f1617247daaae24f193b5064a123e70aa8e5e9c81a058ab97b9de78ddf22f6d0e0a666e49062521c67cf8d088ce831263b8641943830d639e30f866cbf38aa6ad81946b6f9230b8e2d2cb5c6f8cdcb2a6c5c767a5559cf68cfac7aa839f571dac0e82ded75abd5a1dfc2a25ef6dc550ad88c55ad117a53872ffefa345f57b5bf08b52dcfe49b6e8afe0477322a41ecae6b4b2768f81eeb1af36eb9c734e0eca52299db47a9ddf7f55c730e6738751a65ca97fa7a035e7b6ddbd6848644ab5802018e3e67010f43c0b82a047c137c6665f2c4504fd854215d03eeff3fe46d60fb200e83d68bfd924ba8f2213f137e61cc9d6ea43b5327f8a07541431f3d003b3b2d61ab485d66e1ac38e486bade0e7d5aac7b02376999bb4d2b15677ea5f6badb5babb17faf1dcddbf5ae9dcf1e8488933a5c4c9437986e731c07e95c94babb1130e479a3992c4512b1d4bd103415a54f820ad8379aba7152b4a21d26ced4bc7bcf5981160a5f956bc95c3081af556af26dd6eb29f0cb05ee3b0bf73bb8303878e11e66de2c8008df7b229db2282629c155d6454b8b9320b02082d08314341009acdabeed277e6951b049c4b0b9f83502213d5b8e13263a8db74c101eb545deac585073442a14a132cd141e702d286cef5894516d64c1b6b0ed185444dd1d884bfcf2d1cc03645eefc294ae044d614288a0863626627d2254a582993864a9e15eaec1a6b9a915db10a42f9d6483da2b3b9e56c680d9e2b04179b325b4b8864df75aa6ed975aa6eec99524a29dd11f5818fbe5d356ffc443c9a373a54349bc09fcda65226938db7a7bf411b11ece6f764cc3296ddaeecdf9de6cb3e9400015c441de4cd01fef7b20f1903f17bf0fb4f06be77426540319b03b43129beb3ef80ef6c0c636309be0f99fd1efc2c306f1c76b9a29957dc5beee2ceefef6b67b43ad49d20ce2bfbeff94bf61fd79a24973ef8fe579f2d01fcbe84d898a5ac11e38ec046e818baf42550ef0e2b2588b15136b48b8d46ec64de560cc33ff6fe3a32e2ecc32ff90c83e12022806c6447fa461bb15137be23f958ea203fa0efa38fbef42be841f4befabafa82e2f55563692afe3cbb439434853bff06085ac492bf3ac9fb733b993ef6d5066dc4b2af2c30afc02e94c104c21394c5a5262c8bebcc912b2e3168c004c243b9d618a9009c179c84913264072c031033c49e3f2e64408827aa6688020eddfa53e62ac43a228c0c6cf0043182094d9416ba204981035cde65301dc052c1b8d2dcd9e2228304d7973b5c64b6b0787d147263613183588252a028d66a6537b9dd4ff47d9e982b1042c0d1e34c6bd1b9b2ac384bdc92bfe26c85950cc8abb5d6ca4de85595d75cac89b5f2c63b4a5555eb9682c145f4119744e42f67595e58df38410475467c645241fcef1b7edf0ccc0a1b6b3e8de6fd4c367addf3f2fc0efa50369b4473329a2cbe56144d11158820b76430345b75fad1ad4db568369537a8d904fea93ac8acdc92ddb8bbcb6851440408fa146f43e8c579fd6ff08ca25b5f049e1113af80583d1639b9d59b5eb5de60a4fad5eb7c6f4e2fca53547114c191ea8d79ab7d835ee8fb67fda6816015f4420f7a916f09ad30d740c0a3cde0440e579a314002f1c04ed409134506fef049020f58650f5694347ef064002b0a2b01a78a192d2f90d1a3c54fa5b2c1961402e960070a297bb85475a100848c0e390c11f6c91074c64d0e5bb2903c3942c88ed7135da6603df1339be200262880e1f0a6c91e265884a933a7093a4698e8128a810521a0104245037dc8905cdc6cad90652606377d82b08292d0b2c7881df28069594aa3440c94212a40d9e30295e200ac214d5439c205853132c450c44f9f27ea2ce11383a1024644f18705353fd861c2c50961d82c5981c90d6efa7851261a2e2d3a2079c326870288498189227a9ecc691342a17a928416d80d44d89161871de26439b2c5ab4c153f7e644fc0a620a1812659ccb860c400605494a89375a70f9bb0f9828d24b82c31e20f1426498cc0e68a0b8e92392964e983431d3972c05a08631246e6c2651a1be0218a101b9841c915093869028636298cf9f2f5029d5df9363a312c818498346ff8ecfa493ec367c2be2562bddc050487262278b90b4816d6d2710056856bccd685e0721790166e78b90b4892302e038e27809ca00186405fae98d310a1012e5f451ca173552686aa3748803842cd12590b77e60c7142cb98336e5ac0c102e76983f5041461021d29d3cf60e906c806705842cb941bfc0904bc07c856a03a42060b893529b4d0e7cb97049e9d24b6c81ce955cfe31c8923495c8ecc25d1f72292e410244872cbe15871a950428724fd0879820b9218d240d1c5e27217923c342486a460854544181016beeb96af65450488982e3520997343579019822e770de1225231e8f67bece431123fd1139620291e2b279292a80cdc252409903d5108e922a2e4469239f2f3be8fc9f9b8dc57bd4ae66ad211497ae1b0789124091a21495ac35152122e09379bbcea798c4b229392489ccf24dcfcc26942a04949494945f49449eeba89e473eae6cddddbddbdeeee86fa238a47acee24724bd6aa0a72e49f7e83555555555a3b7e6ac97faf76775bf9d1b21222a7034f10b103260a2f7d41a75a5555557565c7b77e4affff0897eb6180e4b9e55f1c8a686922c4090e77c4071c4e2b09932a244c1020845801e140913a5f0f34b0305540debc31403f155112c51c1597bb92d8207363454997d50e6b5a8d9530dd60e4340f3d747be1eabf2195e4d14a755274de4a9c07385ccf36e24b77b7191ac8dc7a4c0da1160fd57814d174f77cbe543e9be987a6534a1784c8df3db9bbbbe77cefe97cefa5babb5baae7eba43c5aa9149ded3dbb3d983de79c73f697b0e76c8846635e91cec7deff68f6cc4f47ade43ffbf0b6f404a02a62734ef7a0ef20d98b70f9fbd2be654fb37c190cffc8dffdfb4866c5a1da057c446f9ccd1bed7056265d41ce707834fe9c8e0269fd4a9dd8abcf102a746173258ed78f2a1cbee6dc71a28892dd7c3267c5fb3f4222fa5834c4c425f2974375c9eb98f0d0e1614a9f3858f45c3a7ae8444125cd125e522b2e77196983a54e66b145f4e76f2f576badcff5abb556ae5cf963f6881ccc89a228fae43becec35176b5d2788019b4131a201152eec59b3220368daac5942cd952d4247d499218733377429a36606ef8bce9cfadd9f5a50dc41f42c75ff1bfe3a7f297fea551004df1b752008be078e0e3ae8e0f7a0bbeb3870f0f39c7a75eaee4e9d524aa93fc8ee742cc53745dee84123829f27734e10228b9d313fc0a0f5853ed5a537b146c5377385c89f231ebfe65f7bff9092fe39ffbf318d11cba19b4312ae1b0785f3a072b886f2bc3a94f7a473e272d3c69c3ee7f4d9c34ccae1a0705050b81c0e9783f28983226f5f449c9b1cbbe99edd465cb813771b47c7293be94876229f9dde91da4974a4660a13a526063e668650034507a5305400e9d16a020b09305ea78a3888ce41057944a951c7f44564b03e55bda193aa75d47d56ea939a4d9ff77ddff7a167a558eb93fa6ad54955d7ca4979c0ce5ed369695999b93e9f49a879e39f63aea976edda5597ebe6ef87ea3ae96c6e6fee6666ce81600e945dee42a22497bb75032cd2116b23149d7f9b2fd698bc88e5ecffddbf4b089cca24f480cad2391710c56a852c68a2bc6961373fe74e7cc4579e383994d10346a78fdcc7dbef308b684ae6fc3def73ba3297c3f346afe68dba1c54ce3f07a5f36a4e87a35fc4a43b198b7be7725c7a005d8f22ca2d735f5d9add9f9cb71ce93347e2feb20897ce769a075497ccf598346f47f336ff8b58f216081310a5949224d78618b93e962249fd84627f1f7e968e3cbce7a134bf47ed12318ce994463046c035fc7ab436ad83ee1b7a7c7dd2f914a82351bd51ccb799729809f154083d12266daab6b0c5425c513dee8f8a58b88890a3c545441c0ea43c108960138ab5092e731191450495bb35a6c73ca2c32f7d1db50a9229e508fd1edd53427e3e724a9de98d1bb389bfc913c492e530603af15cc01ccb98080ee019f3876ed7e8d197be0ebfb57ab57ab5820cc326b5d3ecca33fa2d68a7b191f8259040850a59e982328c7e3a6489e419f49bc17c0980eb3edd27dfe6d85e95315fb8a039d3a68f17223b187e88a850a70c0f35d0b0e367e63041980461dd9210d21282c94dd356b5204cca8809f2c2135949809882042684d7102d51862833c6d1b816856327dcf24a82c63958f3c7cb4a1d3c80bc3010d275e48d9d255d358079586081fdd0431ed0b398f842c3136402c9d08019601872e62b6bcf95d09cf4e79cb5cef7a741469cb53943887350e4239662918ffaf5c7e827beb82eb154baed7dcf3efcd63187cf0c847c74e7d21b3638fd87a6511fb11cba7e54549b77263ef19dfb8258329beb5fffa394becea7f74dc1bebeb4ee9c21ff46e6eea474da2f0668ca6f4975eb0ebfb50609810205daba5402e4a5638ea39834a854ce363439e990b911000000010053150000200c0c868322a150240e7461903d14000d6d8c426856329688435190c428088410630831c6100080318020a2981a321e01136e3f946740d236a4c3301551effc995d03d7c388c4f09e029d21a901e25b03e3ed8593a58ae20d7ad631f7d419298bfb103f74670d96df9296db0c5fbfd9ae2df8715a16d768ffd8f5736f493b9c6951f188b9b27eb899e804106a845b4a1b0595d2f635c494eeb6d80a129c10bf9f9c5967e5348c9e1e8169bc9dc8dab81a86b78059d6c247cf0cd39f232b993ea2401558afdcb829976c5c60a2a06b482558e305d2b12cf09fde9ccce9045355151202dfb1ecdecbe4e6876fe0ad3668fcd3c8d86bc7b4d7cbca27b6271bc58a9e07cc7b39e1efedeee4cbe8e85665ad54e9131c899b1fbe6d1632205829dd2f5bef2d8e769856102e76d3baa2035ac69c15dba95b2b31eb890290a16a4c1f6f53026c64364b0d22aa9e94545df368412f7717cc9d1a38eb38dac9aa241ee5cbbc19a6f411e666a46dee3070d1b99752024c43cd20d12f0df405b3358f41e6c8c33b951306e4ddeb9cf040c18d8b8937f800b3937a2b3270549b6858c2a2f713f2e8866e9049983671eada74fd80493fd3098188a90dd354d3de31b6899e493ac74275a09c2bbe6c1878e20531704362c0d7a3a43cdc9c36186f2e940c10452d67e7bab1bb271d46d8e88533c133e62fff440539a310a4026309a6049ce2eafeaeffe81c94484d133bb925bf7b8387c3d82cb5c093d3db546914be7a3038d56fefec8a576bb2b8321a798f11eb0344d3bf6210418709ebacaf73dbaab2af72848c1a4c1d3bfa55847476f1c99563fbfb21a0a3757f7d41424c6abebbbe942d0669f07726fba98983954fad0c91de0e8d342b9e7a5b2126bacc4822f0af5ca5387ccc34c32f93422019c7a31186dab2616817bb98526003396c2178662cfcb766cee5efca4012333580a4a8e8a1c804874043c1807dae320b8b7fe242cb7bb276a8965b206f13389bc194df2acd052e5078497034eb2e8257b249bb3f9ac11f24a28625b225e4d7a5fa0bc6ac3140c8fac8bfb1b4a8b8b08833b978b7c234112e275618b5bc9e1eb7f87239f0a2e75ce5071af59600fc94a5d56e0e9d2ac6957b061db96da0ae004a0aafe414923e82830b4d40758eb3afd00dbf77e312fd31d35fd305ccaebc6308d4c46ee7a4bd4614f142d1c1c1e2e4f78fabcc1af194fe736f1bc130cd621d955d1b9dc6ae09e3efce321ef34d527e2450166e6822b15654f7542f4fc860b046dc9ab2649ddc70a797cd6d5d1e49eebb5fd972a0193c63238a1c971c5f04496247d6e2e9da361a1a0d85e65f23e24260d9071748f0cad967cf7e5f43e5c1a44665ee45f65d9b621ceccc579460e961be2f10407ab70be952d0987bd4a3968fd04dbb313bd6393be39b9d289642b84a3682c63b04d03ad311deaba08c7604fab3ceb4044b947d035170f645c4f6c6e1846ac284692eda5357b936d2bd7931ab9b5e9067b4181bb1faf150052c631537a8cdeb06efb1da1c3c7d018df2e747d245859c203fb8b23f93967ee104beee58be8cb2f7c2775afc0316fb366e78dbc0a575029153e70f7e77ef8586202e9dc3082a4cf966eb7d73c0e9f7e64eb363dab1b9fb85d7c87e392bedb67e638ebb18e15f66b32397b9a077c8032962853693406926d52524e0277689b3507c7d7085ee0ccbd8f4fec3186fc5d17d10c36a6e464c9fa15e0187dac59526a61d5bb037028948e6d8ef4bccc8806d9e0197c380a6993346fece10e1792006f8ff03a5760ac017d6a93cc110c8004cca909a07a691b1cb149723a766552ff30f447d91dee7dfec1e3e470449d215e6491f77ebbad4e2901e7a20d24354693a43d4a48cb32486588c5494b1f5ff4af7683dc772ffaa30f0d74f2d6ad53deda0e84802b7522d92caafd0c4a5d3202ccd25d580a8a69bfbe36bbc557c94d4138e66e3e171780536dbf94fbb24d5e0f2c5a6c26eed976c2ab50842eaa733d7ec68350f84a343d34c725384be634790b1e93a1737ac001b17f92969733535d5ba0a7f385baa94b5df0dc263fab3f53bff7a164112014f79e86a0f45059fb39edf4cff1402f34e85a77a0832c86c2a726dd00484d2775e3520a0bcb4ac9aa590fe3ef71ad424c9504b739e838bd748bf0340f5526974436a87df59babfc714aaabcfec73d8b0174167bf6a8855b39dc88da86213d92c6b2c74ee8553dbc1a38fc86c58750aa20d129dad79149929311a01b8d95565d32e9449113ef66c25d8c1051bd4e8299c16f55ea0ac9d5d0c64e01ddbdf3969417b0624c11c3629cbe70ef6715bc42cc92f1adae8d9c2322cf9ef079951360884ebead65981c1d675e31e81ff4e85e97c84f21088066f94fe96a1038bfe584f417924f6f31c9a633e9455e750072bd72aabd31a1e6e96b97a30357c4dad45353451630dbbd561df4025adfbb581d432df33bc327e42eb2b05f47ebac25b654edf4917d7b5487698faf7a31ee8fca50e77815ca0792ebfe2db1b5412d87b0d05aa0af506016549e0b52ff1ca0eaf53b92b6bb1092379312b590bca4f464c6cca430a053b4e20cde4785a6a0bfd6eed1178178c03055e2729b491614f38e834ef91df0ebcae516c6c53d07dfb33de6da79eb93d27cfcc32c59428b2060bb01f4bf798d19a684261d8ca027c86f43212be78be06c02628a287d0088fc81e5ad2fb08bf44c81ca5f0505115aacd17c206b564154fe82dc9001abf07ca169b31298f71f14e749ffda172b13b8be806ba1c7667a8c3e22d1edda77ef8458308eac4cdf48d286ae33a6e0fa6e31091217d856dfb487042686a11c72b8a7fe4d27b4681120bd435f611cc1498bd94e89eef875e9e9f01aca86e5d49c62f2af10d8cc184c4c57286a8762eddc052a06ccde495b928875f9bbf2c16fb84815b333bcb902f53314b25b8d29206fd87ae10ed19b74d5c4d8b9c56a3f3ba1ae8382869ef1ab7860a4a4108025acd891ca43dd1a6c0423e3cce378246c284a96a9c6035a0ea0de5d4aa39eacba23088024dc37cda9870e6ddafa10c696a860c0bf214f3daa96fe6bc56796926f08a2c458707e43635f6e11473abc25622c54ef7198d0cd94d983e4b6f442f7234d1af9d6bbb3f31095f13e63d0d4220a3374652da0c320e81b40de717b55da9055d1e75eb4d09e983684cd00506fe65649852687eea258c722bf963aa02e800792d93347051294f89cbbc73c2235076d0f1f6ba268695131af89f4d5a4c9e7884353033890437e8149abc4f9a6523e93490b1176b3e383ebbd74cdcbd067785281bf8b236e8ac5078fe9e9ce9c4293b838e41b1131e22f929040017ea830f15c02249013801c746ade797f5758d59215e44938691ace887a06a6eeab08441ab9ff69366aabfdc722d79fcad94776ed3578035545383c67855bb5a03661db499e1878d6e14db59c719551a991543b6728c8ad1addb069df27d739179aa5c42af820169b63dd66d33df76320f016bcd15763e6069399a095f6294a25fc09dba378324545431c6f5d9f32227431c1c0a39dbd346e9cdd5e4f5cd5b48a955981c00dae0f3e5b0dfbce5b9fd3d331cc11615374aecf9a2685b506fc326be9c8fc7ed336142dd451052cf477ff28b1ed78fd2beb0cf293956613764ef9acdd2e03fc12d9586e92e612b37e273afda4c8388687ed804a2e19638aee3867224b15248f0eeb94e33dd57adb792a5f9d79c0d71a25ec568d42e70580468e7955d4818be50e79193551868b71fe0f32756ca66cdb1a8d18e4932e539f21685f2c1f085b5d6bad17a033789e709e3c934ffda5a1b29614dd9252c640f217818b0087bfeab6d4d2c85ddc471f30eed476d6177706541e6ac1042165d182aa85eb8a43acd1df16e45d711670a70de34ce2f6fa88ed6db2cf5e99853d8f9d3694d599a2a977cb583f30c2d0a250b0eadf57928e625b6186c8434bdd14415d14e4ae85a952c6dfc2fab7518dca310e10b702892cb02b0681a12d33884e589ccea438403ad033dcdf36c5b8b00fb73366d9ed9186e84aa55d23c779bca4c2183620f07818acc88f558428558adc30a448c6d54f2ca138cdfcd2ce273755a7fe49c28eaa44501672423edd691c4b9af9adc997ccebfd51eaa0b26e77c4762afbf59a81ff8344acbcab1814a0dc5041f7c44ef900ee4d4ef628e537c1a47f5bf5aa7395c7c80219356a1debeb9e8c3d2d8de6acc8c809e2017383a5c8809a6e944de4ff9fb0f3c4e22682b4361074da148137be0e8dd0e4db73387c9269cffc4104cec446163477a8d22116d453af080265a060326a28d48e1601e9f95859e43bde1b5ba00c160481b05042d1c13659c2f64c9463fa40c58fd43f520350149c22605d6a47bb870f853022e37b3c31b8f03a09a01d4b0b0faa99bf0d4cb07e2fc49e233ef8c6948af1d4d5023be4e4dcf1955618bf44eaf25581d7ce744ca5bcc16fb829948e316937bfe12babf2c2592369ed9d0af78e45256a6cd2e8239eba16b5314457cdb0452dcbe1de725ad206ad3de004e93ddef0bee85d3c1750b211419546d593358ffa34f2393b069e2b275aa367006426f3d9296a2c1b82c3262dffaa2409434e1fe104f18c70f44be20b86c3dd6751b18d69368551b7d53dd6f49eabee50053a580ea1559d781a8f1bc05e7d11082d5bfbe0cf22c5e654136b16d8924996cb874e6a0c14ead42ad3baffc48be913e0dd2d85c4c8b2d25a45c4a8e9f7cdf8b25f1283945f039173e0f8c68bf2a9115403210fe04c9a05bbdec62f8b2bb1385c778f48cc9980b1f0ad7c46f9782238a9de72fcbec49496f6a6630ee3bc120393c884b7c45485f37bde4e25f23314f1c903570f0945901d9ba194f2271a6f769808e46643441ab765c033a905b45d8ee6d42ab35c741a8dce6c00216d140ee781b5ae2a680892c4510663fbabfdffe3b1dd21e1766cebc19687914a286136ef25d94bef992e108d14f173cacf5f18f31bbfa63681bbb72fa4d26ea03eb8e8939b2cb39f64bbaa4ee6633f1eb369a7476571c8b4a6921d281b50640df9460f62643d4051a0eaffac9a788557e223184fa5867c3eb5a89c45bb670b1b0843120fb4ca46fd338719d883a7aa243903a351328cd1b55cede70c110991c763216634dc4c0da530a5264021fc7a39562f43811f49fa6aa034866868dfcf2d4bf0cd11a701b80d0c0307495d89cb34d03f76b37dc2a5d1f02d61377f1e4502bdcd9e470139971883b3129ec0781cfe1260201dc118d11b6f78eec9c3c5228879f030340a3af04ab2489398fe2f587cc8a509b8dc0824ba42e701269d263b94c138b86f7b8a56282e920dcff490007347aa765a1c038380b0121400c9dd40312fcd7ae1b69e84a2af1b0165f05d39e6d1ff4cb6d97039d7269af8576950c73dcc182f110266846719a84dc2b00129cad3c3f8930750aebc53308238301b76d1aed65701eaeda1af4a1b89521baf64713a637b90ca4b70de9c941b5faa8f99c17120962dc489443693bd77b86bf4a4104562262d2067367e523631d003f0cffd599d7c31e2fa210311ce68f62a3f2c56f766cd7f9a2b816592b98df58046dc7d90fdfbd49411a89ca49ef8f7d780cc1962649cd99c8cf1eca47c7c568e0b258c1f2a2b55df480c6b1502797bcf77095612c02de0bd0770fc23a040c968b3639a77dbe417aa3d127467a413f789897487c2c0eae07b01fba20f4d160c2f5111730a430576857815810899a904ea2b22d9e13e4d5914518cb5c50ca6049b157250fc0ed15d0f9e005bc12185acad37947e3e5377029b4a7436ef004224b58ca5f2b8f08c5f1703af892d20b05900420c9cde6520832cffff88c494b8dcda77dd9e09679fdbaac41faaa48eff7546e25423d15f2c9905cc87fcb3a28f52b768556e63bb9f523a02f7e2ac15acb80b7703ccb1cf02afd8a22715e58b8463ad11fdd6020709d5bcea7ecc970967b65739b23479200b100267d4959a298006b43ff61a0364624b0dc1e6238f563ca7a47286166532a25eab39c34866ce8ca38634d3ae4278fe1a7d1c2584499ca0efc673470a0848962dad2be370971f17b46c7a0ba0c6b0d63d73eecdc2e978849d50f06d305862eb9b093abce7722c0afb4e0a78e80de3d342fe9fe13ecaf3ab15ae3e3c38fcc22b36757b2eec924be3cdf423c71b3c999ca1d6b4c420c1d61681a2bd6e53441ca7ab8f5377fd48829b5c33e188b78297c66535a868401458b639476f1065971e6d06009bbe4b4eb8293be53cdb613b392e71521d37d7aac12cdde5d6dc6b900439576daa92fb965c5097f4c2c9d3043670e5843fc5ff487922ec8b2403bcff3f1105152ae389e2f8fb34ccbceb93ad38e66b7d3e999a86eb7c763e8c0fd78f040fb7fb38e2d27171afcb81d08efd2f3875319c0a85142ec38bf509d20999fbd3b98445bb27ece81cc96dac062c084bda53891f829f21912e6adeb87a18ee72de57a455737b0d152aff7c12998a94d6eef459797b27e1ccd95bb7a971e0691ce4811bf41b16e5710a6b14114068c3828a393858c185ca2e6b20b19443529c03473bc06a4bcaa092dfcff2dc7003d5ee26614c3c18e29ae47821a3b36d6cddc2688fa6a27237061c31002e827f33fafae6b2def8f328fcd4f58e5ffe8c092390a6d6d6b1b5d48376cc0bec792e88ed3a4f785c7ce56f85abd18bcab67de1ff80baf5cf984decc7119de0bcd2988a4d0d592260387d927aa38ca48596c3adddf10471c4acb0f6eeb2b7629987853f51b9d6efb9ec5019d694e3b400fd62f18248e506d0fea440dd38872d532688a8abf85cdae436760e0e0b8a7b042029893ed0ac6a5c539e08f6a85f19153e9bbfabd05a34f532521c3c2ed9197fbff105c688d86f802e5d9164a062b954e49292ee949bcf8d24de923e019d90d293723191bb71ee8a7760d6a2d34039bbd53cd9f5848a01b42142b7f162b2203a2cffa77a93fc92507f523d669ebea9ef257458478218b4bd5f996b39acc8cf30bb50211d179a147c290592d5c90a175c01c7726ec9f944df31d29d65ab4bea0d23708498080a165aa337b5ab90d87da33da0b15a211d7a916ddf80ce477f32e2b8fab9a2683e8a085befa0587b6c4037ee514b47cb97e99011dd82a44f9717d7992dcbc31e8f9a648bc06730f45777965efb50cc5baa5b4ed8580e6fee02a182b21524af8f04c811e85308014f9367f87eb1ac0661a7b12f965dbd16374b2087b1cb8247de0285bf8cf731dba6f46c42befbbb3d07157be79fc0a058b1689fd387023b44d5c720d6e695b12b92df4db62f66e311bc6e19271068098e2649119407c734c6f03e0b6ab82dcac85a8931f861963c0fda2a5b298a0e348a3d58f9ae0a90e22deb394fe2447f124fa99f75d68e9f4cb9a3766f29a27c671746e061b7484b52ccb38f86a0f51d4f2284556f75039a4bcc2176b8269cffd6b8e1fb954d718e9bb186fce8df13a1ca616a5dea8d4a7b7d3eb4e0ac1fe7d79866bb13108328aa480b15bcf26abb23af16746832e381e724658aeb788a7b0673961044ae66b14e8fa3af3f075016d4f661abbdfc586467a8f8e83160ccf119aa085f642fa6ec8c2f4b81454b75c3f5e39e62e0ddd9b21fb2157d4cc629f982d35500d4b564de43a72da2f1c60b620a9eef0756de246ab341501cb3bb6e1ee6eac2c1006ec968fea524530d2cf912098455865ea253d85d1df801ddb0a0b041354bc50c1af6e1f94945d7c150a6419ad421e70d8f20f351d658d0ab8f16eb2aafd49130ac6f20c5d8b6dd253cbf51117cd35a760be76e42c90df2f1eb941fb13c4e749ff5440a3c42ac1ecafcaed609375f006afd6ef80c0ccc4c2f4f1846dda808c7e865f3fbe20990c2c6ace1ed427fcfd3fd001d527f7ada19a46be6a4e8d9a193bb2ea62a42dc76921c2fdcd1aff25d39262aedc49e8e126118b1c35ac19d03ed70e850e784e2ce66d5d14727e9ac6b55bde3400be123145aec6e136ea47e10bde174cd3c8c09483aa5ad92c87543a990a56116a8e434d0213cc17ba53f3a1b3066496a5d453957f609280dea162342853dd9afa7a18e4433cb0b968149cd5b12da89cfadf1fdf7d42471251305301ee57cc1c175cfd167c2a58a5ba331c98163a3ac0cf2b06a013bdb55f3d699404c767491c48cd688a6b38ab690428bf0596328c683d7ee2f08eaae1cbc1f953230d40ee813265dd6685628e66527cc3ff8226bbe8ea02134d9644b054c851507041cd198a390e29eba5d974b0982591b9db7ec30333d9c8b509ddf8bd0579b1736d422c9a5cd5538d595096268c8732329f67ada3a93adc8867bd5916f2ffbf04015c9046ebd126d7660376892818c1f486165c7fde0766f0efb73ac5afb1d6996feb0e2d1fe8d580cef9cd0f54be2f191ee68370e1e8772783f736924d9b8613d529de8a056541b95342119e6ce3bca0fce55362a816d3d146889367790c02f36dd41b1ddc8c89e44059163ad104a927c29d03e9ce549c65611d27261076ef52b18a3ec6b0ba85f142e8a2259736e3c22b7d29ae831caf998239fe0df97dd5ccd0f654b7550775bb3610a4d29c6302a082a8736825a305d95988c8064f03041849a6bc83d0607feae52def9a269cdcc44e2da8aa9838ae0f0ec0b01964b6f47c602f247f08b9e6697528f47efef044bdad99e467f50fec1546ec8c75ccf9b60e1d2338c8a39a1fc6dc466ce6213ce66ef10fb6cd226190120208eaa8fc043c1afbaf74d752e6797317f756d79737075c5b4cd17ba126dc3256d6691f4d28c094c73048330c33720b024a008b8e56f51aa246ad2ef33b114bfa9d734b05e4f47d9756d9fd6c8037a8f620cf59e27497a2ddc101afa42bc8861a09d374c3d710e26566f965d6d69149782beb006b1f293c1540cecc99236cd70ec45c21dcad967aa4056b44a85350651ddc7038dec48acb7739e8f93e976e39689c60378db31c48845b2ee0c287c99a1d183a322b59d58a1306490185e8b2df41d60df4e91b6e72ca4d757aff4f385ab12c7b304ccedd6e7a112705ef9a1ca7ab8c9ee68844d3422c3a12c16ad43b341ef84d9e04b0070633e23b9b3d99e3747b15957fceb4d911a9e283cda9030f063023c68bdd555c5064d6d5485f33b61ba3d905d549b61d8b5100e64d6c572cf9d38891d022d8544008e8c4dcc7c321c862566d540709530ec17ee0f382a0695afbe5c3a3cdc1110c55d91db326e853318810bcc1986c83a270d08a70aaa1370c8a331530ada335a36f2f811fee72bb3fae041aad9135156c3fce683db300c53c2b8265461e67667cb5b319512f019b5e31f3415b5ca46b2c2ed5295148220ebd7d8139b7a12976c88bc372f302e8147048a7172bc61abaa662abe04e37904b42d22f1e4fa92d25f348a453cb315c7047b195316f3fc9d019bdc2152fc06b863ff4c6807d87cc1892df46d84fe812dd445d71bec8a24fc27aceb93600c20bbc668f7ef3c8095611d4718c0fab9900d60521f3752c80eee3f098015a4e0df6f22d5160dc81618dc1d931e281cd4ab10018cdf70c890d1dc13a9329e71e7f1c3067c94d1e6a34f3fe1f0723c7c5c571895dfa844c20cb837cd6d70fbc8d5a994d34757454366ad6a22f72755886676d0d2da30c68939c2a0853c788ad4ee3d428c7412f7394e51aa80b717330e17054f160817e3f4870e09b511e8dea0ce788d59dc3f97806217221f26085a9390a45d539a9e6180c65224743c6ff1c33d1a32dd03cc3ec8a54e808a8226439625ee8583320824a42f93bb8fa1349344d630d3d2a4caa5f62683150a546e5cb5fd0db85041e9899ef5ab44203aa36758e49e346f598651a47b63296a0f95e1f7747c24115163f2074e03f03e4da1212d02a8cb86d4202583cf8a4afb031d1383d27e600c77df44ff210850041edd7a58be45bc944f7e2d88479e2d72b35a9afa6671856e634ab8dbae6d1f4a44579c8220fddecee3369ef576995b76d6d39719053648df8a27f53af0bee7409bb4dd9397559dc7d2e69511d39c0cf34470dbf02f26719762c7111b9e57f3e3280b701bcb436017a7518e720aa598fd1ade7857413f32185bebe41470bc1bc3dc53536c0be2d96a55135ccd1e767b58a38c5d8465272cc0ec22d2557796c8408ada28da3622a822ddef6cc4618aaceb337b11fb659e4cf7c25c6561e881c405af11eca5fb5005f3aacad6fd6a108406380a73f957dfee34e71d859cf254372d8a8af41b0b1601b234a45fc64a65ffa1e9a47a1faf368618ea5adb8728737b2e50228c647abbbfcea3d340d295ad6335f10b60e21dd8d25c18b787d492eda744483bf5f4b7ff4c56dd661afbb9fe02cc0a42009bfb1f5c017b8b098adb9940fd89c3a33f9d27d343412985bd210d4e1fc665069f0e5a23c69f91361ce0bcab756be91b6fe194c1721ec9369ca87420632df11b4a94c20ec2d8067bda545dc2cc46f33c15f9d2b38db7ba09efd3c0440319e7a0153703a9a1ed275b98c5ec6c343c2a7b67ba436e1598cfbd525012d7231c184b0343c0ae112156b9c5c47f822eef847c66aaecf91dcfae37028412b8114a2e9a7ed645b9e8b89b1b0f37c6d6c906d89ecd1901ad218b9902f6b94cc53007d455d3b7b82a0b96a27400b78b79ff4e5588e18fdf2eb08b8515787ae83fa82b29dd655c81bb154bf66d3e32ba678ec98a4689965203776548da309c990417c05e65e0866b8028ef4f12de6c53addbaa90439da5e236bb00a5e337f2aabe9b972204df415028a1720330bbd9ef57395d28305767d2904db41cb3e4c0fdceab47f7924ce020a238308647f601f51ce8183d70ce5ce32efae790a277775914c9963863cbe8da1251fbbd66c80ee46f2c71885a4e308246229b9764816661a1f2c2b18f09bb7010c82a6260def4de2004ea6c405c0ba8c2c074c1d07490e276a5eb66d72dfbc526c2c019552cb4402c07a77a4c6a050441cd892cd82bd91a634b83a3ff7d4499a4c230c654e1c1f7a17b9dee1bfdbb283533a75b44970d0eeff5c13acac91167b85d86eebd35e54e7d253a99620825100fb38b3841aabda70336c654f87cbead6f66274041e9f2656ca7faf0e4264968143c58877b30dfc37de7fa27538e80172fea1b0ecfe2b915cd717e347aec2031738f621755feea81c80b0e8427e775228913baca1de8e484bb8a2d17acac37979ab329f0b8459dc388ad606b8317d3d310e69e3db15b42f53f492e54bf699f02d0caf916d769a30b111242c9e82dbcb9e2c0a579b3dcc02f45d60e1a11c893ba829020130ea1d3410b2d8de64f723b91970e24fdbd3f231b45da9c2b6e542876995e5711dbd1f49f94dbc3054d8f3eae708e354329277f8288fd13c57a86f47e8654dccc2a3f769ec860bb047dd41732b3e986af53fc6c60e6a70f185db2f6188c21c1a972465409507f65acf9f4812c4edc0098ea6b679670b6399b3e6aa3d5c99172650151dc78814d78eb23c713c06568b81416dcefed4a5bce37cc090a0e1acfa04b0ae8e224715c79dc3f453562e84b701920d437dd99d6c9b52fba79fae3a8675542911acbf523e241a42831294b03a587860d98013b627c1780c77c83be18bad284e3fcf3f9c9f19c18c37bf02e1fde6f66f20b653a547450ed03737284f39c6b3e834919af6569e3ed6c575aafafbcebd812c72f0241e35c83a6c5fc6ce5153301ff556a821de49bcefdf1c33b7a282bfe7f644e74f80cfa9335cc5f8b3c882ccff6b6ad324be01143b62ac4e749f2c00cd0b9423e5dd95133d8b955f031fe67050d1f70f563c9ff4c7124d7cbe8accefcafdc38f1f32970ed985e124ad3b9b67a68c9350add2fdbf68d92201aca379d12d3dd797273f9daaec45fea323416d3848375811dfac56b04a7e40fc4584c277e5f9774039876467b8b60943af7808da07fc21d88f44455a39db483020e7040d633ca94a33c81f54c8c0dfe4563a43b87e0d0a9dbf34c00fa42c76ad6fcd395dbf337911c691d5a3decc77af4006ec2f7897115ee7a17ad4729265b60414b75a9c966f8e0b2647e2d8ee916ce7dad603d3863ffbde976454af39a35a69d040075c4d4a5b946f352209730a9975a017c173be1a0b3a8f2c613e8d62292192d1f69938aece47729e2c8a628e706d6bcd41da44843877679d5e7ed49cd0f49144962805c360e720176883efbcf40a00d783d6dba52bc7511fc72202e08838985c5a42a94709b16b67718248fcebb92feccfebcc4d1fb4845f408da1818bd9357e991baf449e33516de72e1029b7ba3cbcbe9c54b4f30fa18ca998c64793f0ca317322a5a1c95b0c655988ae41a93d71b7713ba59989fbd306bd894c828b0c9035c4494a35a28e459f2c0ad15465ab71795a1544d3aa14ba5637e253e60cdc9f35e8c65a827b9635cee3821d3bd5ca5828e0197c47661716d344f0d81856897ad0aa104da512322de3f2b0c238a9324d3862c54e6b01b48a82498cc78735f19ca8c0702f35d4d6a8a9ed4d9f1608272bd78058431248dc59740fca1c1b1d66a483478eeb6c0ec05d5e11960e95070b62ca3ba10238fb4c446cfa26d09807c1fb017b16e7dd7dc31d06c933f19ddadb1db25b17b7ab6ab3f3149efc7dead18cfe152c6d0c838fea6701de619c3ad8a0e20de27e9ef2f3dd718ff2ad90ea3c9c65540341e6308ba9a6907fa796487b70cfa6c6066289b8133c7d6b0a54e78a65c873bef015abdc4da9d23b7993f523670ddfd559052ddf35f92de70382de5f0a0dbe0152a9f806fccffac2cac018a285fede90a4731150ea678fe8986c68b49454d883ffd50510b13b0100a49d43b5f476256466eb2e99213b46e2378ed99637119787c98c4d8e454fd5a2b1bb3f3cc5cbd281db0f98aa5436549b8b4d452c45e1018f06a7b7870ab86b9cde8c2019be51162b118850df95380fced6ff92c9d9d60893254416a84ab96e1dd7e053f655bf883a3ce41ba5f8d116902961729e8dae063afba1ece1a63c4493cd4745964234fb21609ed538fb61726e64cc0ca3706e7cb57c9929022a0843396996367e24f20d20954ebf304f1d76e7c37f7df7334de7573272f975e4e95a089bd7ea5a4882c4f1222cb7f28168da73982a28ab4ec4d068ba8880292a8a6a378340e1097b009f0aae46cab7d9329e4455d8023fbe2e18a73cf527242a09a1314d180c8616b2473958b991d486dcfbb9733d66c2d5f1da40722b7870ccdc10a16004f934d290569920b8d1e37142797cff330e03ae48147c822b67b0e05909a14567fdfe46979d25cdb7b3b8b3a13b013b21d96d988fe4edf1432d4c262d63b27dece90eb4fda0fafdf53db97c0b18d54b18384be41afd49a23efd1862aad9a913dd273ff7a92ca2302e85fa6e7ac2a1ed4cdffa7e2b04c26ac788d1fee72cae0b8a46ab3239ffad16d55f11440e30532f5ec39758fb86d17ae65aeacb32068f27c9a03b2978f57350881e2e5deec10f6a82eaf18aa961dd55aeba275014594936e359049973930d000b0f98ad44781102464c9c9706dc3692992d42b4720d4ef9471937fd5d0422531b342164299516d984b9351533f2cbaa22c186df85a6d025fd0b77bdfddcf9d7d52e38bbe360d3d116d22a1e2abf45f95a9ffc36e5b33d2e904c251b5e616360c42d97a39731f9034c40c8dbe9a04a164866dbacf6c7962ef91ae7eb0ad2e080f25d329cc2867076a2bcd5b47b7b5d751106931c9f53acc607a491de7a057b41ed307a28e793a6087ef4516cc3fcf427a275e044f1d82b794a1bca99b9ee005c9f7f000fc718521dbd131bd9310fb659cda6dfd5f50e0840f3c8b03be4a24969e537c9cd32e697de4de1b0de9e3ecbfdb207ec7f878a0b72f303cbc801d147ed81357108e1a27480ba3e2cee663ee46f1b77403a71203ab515d1798ee30095b2267bb332a708f5a231b55916f1d06a9af448ca1ac240cbdd467eb6a4fce5da007b37e9b00920a51505e986ceb45c3574fb6790429cfe0d8d294e7ccf02e557a0e6aae72afe3f781495f46261b85b16e8b075444807e2b8e26ac31185c61a0cf9d19cb3fbf8a936b875983332145af9bcabd5c1d0ea18c481654301f55a3092dff8217f55edb6b383748b0dc4aea6a245df51adaa59830036bcd7eee4b9f35b68dc0f9d2a1383d8495079d898007cd9782f5148177f6fd940a505ef50a3223ac5e920aa2b9ab20ff2249c69669c32eb6128856e577081204f740f725472d4e08d3671a243003683c07293b5efa59c94e6ef62cb2e261b444bfe31f9c7c4849d610ab1a8042c5220d6a5c53876c003d349f11eccdf9eabec1806164169ce519652e77e81b4024b952babd63676333e8cda6526bb98fb4862690a98249651341de2459523e9e480c3ff1a8780598bc4016679001b9069aecd12407ad033242cf85ba05a28058d0cc804e46bc0fc36f1b1ade00ce53183c808aaa98505aa766d98977a24c401ee452836b194c44f79c4ad9b9832e304c8f0ea6dc62e512ea3f96d9667262e4a8163c9a94a4be0dc806de5c1327d1bac8857dde2eb93f6e73b8a974877c01a0eb0e8a2116cc986f4df63c83386eb68c84e19cab55ac10f25f7122acbc8cf343ee191161cc563f5a780f67ba272ffa45f78e36a56a9ab030a1ed4369cc8e7f244b7c8a46500f861e194ddf3f5af30d8681994a40804596dc677d9dff50676ab8e712e9e3fe45ea1de627f130e60efca429229971bcf7b07211bf33c41fe86f1ff0a5574494b85bc08bcb8247e88db881ee83e09b8231494c3f5ff9017e506f88a0840fb2eb1d987a07eb0222ad75129823bbddcbaff7455739236cf00ad50adb7d0577876cdf3a21bf5cf47035f363c633947deabd3ce29f9b533cbb6202c567cef79fe1b4c16153ff01a3be51ea27663d166cb9d17e8d71c8655228b9eece14b291766bd2a472ea17e8d9afb5a1dd71649d1af87a95e7a668e4c646fb9bb3e73ac521dc81d58107543fe8134cb2e1de1d3d0d9c56192e29e8c7ad8a0d46cb0f3fdb662ec5d701c449edee4c95a84827349d704fc1c3efea0205d090122a7bb51dfe64854a69994f6a9ae2e4f8359fd0c2992676d585f314a9b84faa9a06acc2487862730022b4c4858d46ef6e61471be858a7dd64871a6ee5ef1d53b9784438a2724cf464fa7065cdac7990180755c83577e94e452b91e858322f9dcc893052a3f805cf6f403f0e46d8f8cbe2dc2927970711df54de6623c1a3329ca4a9c6053116cf00c7e2d0d865f2bea9e941eaf2caad551846b47e9abdde7099e623f51a5ab21bc014e19a8936b56dda4988c32e37cb10aec8ebca52d33eecbe55db2aaab9df6fd14fa35afc368db8f493927d9b5cdd4a6a84881e4469a53aebe5f976f94dcc9f70e1226e6e933e89d007638a82ea17be45d9832e24f6a3288e59513bddf5b2c76c86822b05a9c8336f7ffa51f1fa5fd11ea675a083af38139e506cb4ccb257d862b0ffa0c85bd08ab23a80ff0c31cf8ebbd6d251e95ff991ce3913c7a300d6a690c4a02505a4f81bcff03e69b72f1e78b300a19ce7da56ea1d112aca8df3607508833141854dd17b98427c7495e491c821204e3cef2bfac2f6eae6faa61561e115c385a43a017f6644ee0bd37efe1aa667b7526d03f20df6e875a4468036ab5eaaf196d06dcf994c627f5d573f2d5670eea2b3462295686b6c9b9301bc38aeeabb5f2148de8fce0964c90957ce16783b5ba3445046bdfc55b43f00d336ce807af211b0f08320d1b9a0bf1aec4f738f852956cebf53d8036c0fbed9847050d06e1fd360a7f2c5639f20935f26aa72412213907459e4a6bba0511b33f3f3686b92fb63cdc7193ae319ce77d2feae5220dd6fcbb47481328ff0d518dc66001a77fb26f2fae466f3b6784ff0b7b26c271a8184aae45e28fc031b90556d4ec72dc345229a2e972dec4f61e4f368dfc8bb8eee1b27092b488b271284b9416712b80ccc519fe6f599d81e0e4f1e4199ac880018a25f5dfaaf8c3a9060cdc1d30e469eda13f60e87367ede5adfdeb9dbbfb4aef14497e0a61b52e23ce06bddf12435b692017d60a578e24d0e423201549136a54f9efe4a999ffc848f3185aed76be8d2588439e47aaa84017ddaffd465a9a4ce34fe5c4910386b05844e4043c3d018d43577a0fc52c9410356da0df216c529d4e04e986265b317b625b059c21b999c6879840cc799aa1b038cd9044e3f51c30c2d98bfae8a890c2b039a695afd0b9e49e529947cd5cd5ab279958569c2116f261b02b0f8804477647b7d633b4a30e523689ae7d7a49130d6145f407e600373ee0ecbb9770c00ced268e746ab90487e4a4c54467eda9ae230531efc7ff4379ac1ff522a02c4c5dc0c8ab3fe23e27f9101e60944855d28bd3e0fa10da087de22414799c50d31108222034b276d8464408bec5682c70da995e6f595ed7f4cd412aab92339698b7c6c24a1f6d80bdc19363f643d106d5790990cbb1f487c61c59016113db15d5f7b02e5417896f743800982124644d8d18d6614cf44ab581c84628c3741c3819b6c6023fe15168f68685110c6beb59e8d243d66b12cac715a493ae300395e766b819fcb7ca27115ab82ad1e93a76c02a59124666200eb1a1672dc5b092c3f39b7a04f1d9cbd0a2ee2b466b0dd7510679f0e46721dfc11d268863cd50b7062c963564de92f460f5aa41ca3b32fdb8bb6af5027b7297b898ee315ba5634ba84630164a416be3250887e41faece44da8b8d19033fcf27e1eea20353d4aaa6540a32b227903f603a04666ec74b0efff437e1b37ceb7e98339151fbdf5d29d77f2569bae077f03c3b5087b88ab7b58de9d1760aa25f358451b70f67dea0c51071fcf07a45218fc1ef4ae064d68850e995fb987fe57b6372f6584a5e79137ff67e9d24e4d6d9b9b9ebffe8ffd3420e83024442ae2f7fa8d1f916c515d69b0060697e6bc5095513c51500e45320f6b5a38e87e0c358d4908c2c98a03118c9b2c0dc0516826424ad7d00d1e64c09a8f2bade4210d56accae91364a7e684619a1f54c749f77d59c2808d115552f0f923fdde3a04422c7acce81b4c3d6d2a3ff846b19430376c902e9474a0d2ac798dd589a6e4817f958f1a96bb32c2c8cd6a5eba256c5956730110c2ac93cec14a7a64e043560ee806eca870d7c7b6d89581a1e79e07ef7f93ac4cb2b49217ab9a2976451de3a7da8ed5cd7e05c1351719dbd11c23c741437b480f81a61eb73c96ddb861a6506f116518bd3b0b08c3696ee90a64a64e08d1f807af42e9570962e4d3087261c1ca3cf7624d83ea7439011eb5013902bd3d44e627bd8e50eaf29eb5f7f130d708b514fffb363e9f1a49c8c7990d47b528e199c9bc079d6bf980eede646ba9743f70966727f217589c0fe46673a482f49915d856ac8651df4e388ce537b144f98004fccc76eaaf7554e9b228916c99f41877491959eec2773b3917c58d90d64fa905afba1bb5f40222fb65180601030d98590ce8e9a30fe77d681624a65b92b88745bcba1f46dc0ed54868a9361e70064869fdabe6a69aae743bb0ef02ccac2b36c20039ec87cf2470fc42899fa4c8eaa1c44caee41b77e5cc1b105bed85d499ce742f719edc54bb712999eda4704a034f5c93912ba62d7fb9ce48474e6bfdaa90c4d3726f31901d3bb29b9511903f176a79ca87f393ffbb8f7b6b993941017f39316e63ca250120bd2dec072fbb0ddd66d1299255643299e67a44cbe5ee78895ff328233ceaa6b97f15323be89ee7ce9b1af8c1f510d3db08ec0d9003b19fa455246d4aa0a6248584e19e5eb3f36b193ea739def1d4b3df559c00fa2618c6978cff43771e8cf141becef7f8f12f2b745e1308ae1eed80d0b9abfe901bda31a22c90fc0f71402c22f8874e57fdc80326c3f4f487d819609fd48aa7d3be1fb6a6dbc61af799906ef61b2534573ec12a860d8efc381cd2c12fcc56d20e6300797ca4d9fd373634e1c8a0d4eba006250f23208f57e4eaa1dfc9e2891ba5e2909ab78b2dda2f4d4297a1c8cfe21e35848330bf4930682336fd07bb812fa1f942a28fb830d58c1fc6719d038417b8829bbff04dcc6413bb0973ec2a9ffce14f26be6259246846cb1c6b323aa56352231a387823522a498ed6f4ee02a1fc38c15a16edee70bf575688b8e173aa63ec5f526e20c7ab7c60fd53ceed2bf16829b886bf329a823188ca63d7c50d16ab697c7ead9ec0aaf39227561ba3581060e9b21dda8a109d10f13af8e27178757d146c905f117556128a278324031b1d2fcdfacd4f774f0b869aaf27095dac4ad0c235433c93efc4a6a04a679b21c8590cb3aef6993a5243072387dee1b2fcd6a335cec47c563d372e65b1e10a1c78f68f5d1c164009f466c2f630af5f3520b930d4ed43a18b6fefb1c25c8c7f842aa406204ba72056b8135f88a58ecec2708a03eeadf1545f98e14f6406eee8f145a35569cee5c019191d854925a2b4980b6cbb251ca878266ba14850f7bcb47274883de7690f2b6bf14a809aeadfa8874cc1088984fdc26c6f43b291705f8f1b533a6d984d623e2fdb33d11038e3a347a7e5764e0ceba32586f4cad634359216f96bc4d6161617b3c6487783b41ae028d92a365e16b1d14926478d939e76d810f93fb305e7a34eb309189bc88ab699def5def70406db6980865131cb79546ef9159f9986ca411e635d4c21129a18adf249d25364519d322f2357904aeb5303720a0591e0996898efc937a32c0138d323a478599f6ea274fc1077f108104f4776da5132cd2f8e8926bfc32ff0904ae18480b44e3e39af3760b5c94c36dda70502e2dbc95746b799deb772d04acdeb035f8b5de8205530dda81e38c683e577b313595538dcdf395cc1a54c6f3a635e9e4cf692b589f8ca88efb9e2bd0d6d9f4c8be300174ea0a24b6f12fc4280c6035cdf4032132637f8d722e0c80cab4514f53ad82af2bf544b76bfe9b699aa72bc85a1cc6bba762f0bf8aa35a5890c8ae454a10a9eb60ebdf7bb1d8a40339b13bae43974c649346c1830d5118a739b8b873da352cdf6f8f9f188ccbff257940e6cf551728ada3b9ece52d45cd2398e9e260682fa4a46f1973c6804ae164343523ff1965a75cc9e853f65f349a5918cdb5b6ecbdfa5e5e0f741db8ec662d07698b5e5e4181cb082d58abfd1030cf65d8409789d3f2c5e09c7459c08d49acac6233e5d504f6481f812d68629e3b18f954eb09ec14e6f14ca8219eddda9f42c8ac2b2bf82688e5dfd04364d1b3fd9edc330acd7adfd1c95a9dcf014761ca67f2a964a07cd22041a6c9b43a0232a947a0c18ec8923d06735138a59e458dad64188060b9f453f2efa92ef4536658659e48648666d5fdf897febd23df088b668224276ce1c79bdc180a56821f90e31b8ba552c0fc46dfc4eb8b1248b57dc7cc7647c8c43b727bf975a4ce4097f1850f74779d06b5fdd3460bedd66ea4f6bc23b455182daed3bc331b3d26b2f35b53722fe12bab8d1968d78961d4186f3ef839140a82d4beab99e1afbeb9c9811d26ef6b449da8e256edfc3a43d9758ad9131a8ac3d080d8e5cce57e8aaed4add435943f3267f947a9bbfcebd8b7fc2545e0a407e2bfc4091b9b60455f45c4d8e5ae80df8501e9351e97e6c5119563e8d7c759c1637b26a1557017d31bea118184244737d1ff259893c9a45e431ccf2a1a9fe3a9a745f260d09186f231b14de823733f9c7a5be9e6003c0d711adce9858c72e757e4a9e454b46bd6d70fa7f2b1080d7e6fe6ad6063f75d9be0e75dd86d60bb208eb2ce8d0748274e16463a21428f86aedcf4f3426a6e5605b91894cb154a963ea977bd5cde8c3ad07203d4acd77f0426962cfc05f03d3266441e464367df446586ff26f1871d040a426ab98a5e6a6195895617b74f59bb3f61b5e0aa7cab5ee3f7e73200e0611a41f6085eebb9392b05a0402bbaaae5021643390f965d05b6b7b3059cce0215569d95385ab3107be5192f0a1ae1723053213df655873b3cec7b24d23f8a7475b747e1f0424dda266ec94a45d9d6f58c62d04564d09b435412c041c999b52cca88fe04a7c90116cd0d5ac20c39e49210278d9443d12fae03e3ee43a8c8bdcaa975eaa894fed6957b2429e0f59dcb28861508f904f73dd4268b86556d6501ad75f24e17b4829bb6ae99f3a0c6f158cbde3eff64372d26c3c136f8676ea16673b24a2c4b75a9da1a48513617e19d8ee4a8d9609e5a413248b1226909c93b168dc205eab3715e772c5d3bcf9dfc58d743140816a1f87055415df7686bda0ca720d4462d9feda6a5dbd87289526d72d3d20a1b625019e74f0da22d45e3af384b04c22d92be07ffc56d246bf4c675ff66562a525e2db1587ded807d964a11b4e7fb7c02f2aaf1de11ab5a804681de2daca8a9de9834a370a340b261ad66ae5d90f056c4f2c69ec77729a664f52c5b642ea600a12dbd4f0088182493b598d3a29625773f6d1faa2e397d95830c5087d4cbc824443bf4991c1c88050f88ce96f9b4b42be73ba82d3549b9eaab5f921d390ab011da33accc624cdcbaed3ab1f48d76efd5d41ccb590b217db748f582554315431bd18dcef5cc5abe75f52125606291554b68bc17626912b5f122b95a84a2cd84616144b8ea309b7981f137a9b200f5ce7fac796b39c14330e2b421b021908827c5da6abb9dcb1c30b34102013faf06d650e345521f07103855e396490063c0d183a663f02b33461b4f308f74b46667022790b21656d2cca1ad786174cbd74367f10d9afbfa68a9460d8b05eddb5a2d72f09f078855b15c8808c675bae20a7c79c9ca84af58052a9ed61106165c7b53b0cc668c91e483400bdc190c497e421efcc407cdab3e009b5c43b39f0496bda435549d2274c87938950f24447266a7125525e1aed2c49b2cc91b82df7e27d17c42acb4a8a6983fc88f58d46b7d9469ea32b445894f8e521fdb27461c7852ea353f9df4210065dd35e2d9c75a85f2e5111fc3e0278711d6141fa1e21ac0ecd1c1675a8810d0e4d6247b9f188672863e6e790f18d23f0484f63989724366fd06fcec43873502181935e4cdab08b64609cea3a2b2331a070c7c1ab6d74caf676358beb4edb96744ee336ad1283d92d1877a9b86587bec80d582dd49040b8d97c388f1d2f88b973f44d3c2492ac786146d45d3277f48ce9b225240215dc04aa63dda3d6fa380be35dae9623ee3f04360b252dca1158084de417f80662f35d36aa17e4aeb14fcea1287c97de48621979abc751eaaae7c5c85c87b8b8e162de1b32c2bb1b8ceb3013b6cf582a0c78f138708ac02f82ba5b86254a804d62e15def2ad6ca1a7b4e27e1cbaeae4ff4c0ceccdf1525ebab522761d63f73065a2b53a352291b2712f53a085a6a69ff8160598abebd0d3dcbbee356fb9c72304a5fc403b1d0866df1ac25f10a781b3f5655784f5dcac48b098f314c6eb5560a7f91ba7d88626a262c3a92e9efb3c5350b97017cf251472eda927c9e2a208578d0da0fcd369b39f6222f643323f863003198dfbb48e7ea9f57c8c9105e3df1a00924f2464e48abbc92ef8dc6e193fe1f76401fa299d85ece1bc623de68cd575adb3d81ef4fc8c897aa277c9c8113dd49df3b89c71c04b5d052033cfb58c933b4a3b1db7a102b1e61003b1c9333a22981013cf36563c8a01740bbcc3337cb3d557f56a21522459034a6e867c5d3014565107f5993a3d7ddcf6e3218e3f4d2808accdfcd8523e45aa92b329bbf97eb808f7d7d8cfe55cac888033dc770106db6d6838144cfc33784185bfdee2b544a210ea5856d0a9ca261095cb90fa64a0a6ae0421bb84bbed2d534a32d2079d078907b41b7b161e27f62c3c3f0b2cbc8dcd9179163e07c7c77e08ad66ec5b1f699b1115c66661ec15c646e22eff19346237469dbb8a704dfb30657640cc977fd94e53e1b28097c7796b78c57214cb50421b2338e278992f411b632b7c3206e7c6c73e667358f6c64f9acc97e40d8be34b568acc8863fc7036b6c28fbd8d4f616c85b6b5e3c6cb3c8fd8dbf81b2ff3aab11543d812c0a98c00eb0661ddf04fb64533e4966890f4d46c2e312fea8d8f3d8e8ff9d263461b13edc6c7c6d6e97de0185b275b030e8e8f79034c5a8ccd1942fb498b7d3973382c0e7c04da92f027edc63b2ee7442e9b410377fd6323df18a7bb4e238d07c038e3e6c6dbf46c64264a8155a3921adf2705d49d9d9d1dda0dcb3877eda4549efd55e3cb8a53b1e209c78da71959d3c5af14d9084e17ffcc88c34e77a13e66c17bc3523bb60ffd03cbf893c698b16f7dd433c6fe7197ff6b6cdcd83646ff1aa33f2c77fd65c69dd71827ed354e5acc3869342eef9046f0ce1827edb35dabd10127fd634b2a7f39b970972128b40bceb9d908b056168bf581cdc3bcf355567da64e9fa8648ba8d6f26f9883f4b5d676f9c3909599197cb6ac5593b53a10c249806a63320d0d0d3903bfffa7cce4dddd3668ba344e1a6b4eff3cbf254d8f520eb43fe6cb69dcbd9da64d2d1bd14c63f9ea55a7b0e47dea513f7b86e5576a8b651967932bb6e423b7499555196793295b72ed565bf24e8a9d4da26cc9b6db606871208bfc7974bb64c58ab034f521247180fc8052bdff2c08e2c08a706c60e4b670a71435d8b9a18b383714e1f44c0dec8029e31f84751f305f2e03223a2d87aaf33aa4ff5ea7f4e0e7e0d7f99ef43ae097beff7bd2f300bff43d0f12cef7e0f3f86ce5675a0907640a5de6d551e52f61b118625cb64abeffe120c8c2fd6832a87a3606e6060e60bc4928a0548852214a29a544454b6813244c6168eab16dcf490a81ad4914ccfa2227e7a7f24ff5be9c5fe4d838514f8ffa7e8f06bee1b59933f1fdef94fd07dacc973f6af4e12ed75dd9f5098312e6240695eeacbcd637cb41fe2d48d41f73e74dcfe32576803c9e734ed1042e82f83667147402035610f81cd4320eda0df193a3db4c2b8124128934bf1f409a1c5940f587548444e28f3d8c1144a5f468c781ea7de94bdebde0beff709f8b102ae9bd2fbd34d9b15dfdfe7b1e2291ec64cad33dd46cd27168dc45fa5c824a5058f34ba537fda48125d3f308df14da79bba43fd96a69c4264d26d1863a263b69a02d19c975520eda6410d56fc94f7c67a39f490d3a413d4a29a594524a29a5f463044129a57169e9d2672e7a666868bee8f3a8baf3e450cc17fd6c2c5799ee947020667ee6259ef4c74553d01c9aec8a8a8a9aa350283a0a4507a56758d7326ec24dfc889baec85654a4d3cd59cca55c041de9703a5d8fae77743a1e9a2f286a1819dadd42ca3022256168abbb602c772f954aa5151d2aafe6f7f2f27283caa3ca0d59a422c34a2593c9f49594841606e3ea2c58106e04117d54708d222aec639b821acb75ba1f6e229542cef560800f197498889e73fe63befc439355b9e5d439e001a5f7ff3167a5f707d232531b71f1c365cca3ab256c51c7bb45ed1f0e983276c224f147ca8adadfcff56f595299c85d8ef8f78f3f8b556b8e65ab350fc2d9f077c2c9ad33e1889a9cee124d6fd34332385426c2b9d46ae93f9b9f5ab2976c6d72c81b576a9c151b17f2cee802c15afdc4a22dd4423df31500fcd20906d4b53dd4bee19b9ebff465e34a263b4f37d35d2590348e2e970d1b29340ee72effd816b5641ce37ae6b337ef2ef265f557ac6ad5064dfcc6f5c99327ce64f42028b5742007927193264be6cb59bb2741545a83274fe60cc5bb262ae9bf1c43e919b1c92753cc971ba9946140041108f4435408d7a43fac875a52212a447158541c03cd173f10e3707326733dbcfe5cd4363e32f213e3beec1ec67d3971a52f9ba7645cee968f9ac1652edcd0593487ca6ab2a50a35968bb95d56b1ac77759b6df97279c97cc950a07a34d6a4f2c3b8c81fd08e567001480885b0199b53853923139f41213edee0f468d26d58ee7277f7905b36dde53c32cc19ea48c89cc1ae3fef7ca96d8ce4c60ff533996cac05f52bd91204415b49b664b98ce00889cad73f5bc2163e6f6a50513dbb12593788bb1b4c3db081891206788082e290a0001138e839c31430e281d24411a0b8e17004d0f77d4e934bd2c30f92a46ca0c3103126484b90b881e87623e265f1658104053f12e67dc3fa4b583f6debcd72fe86790f8bd134654a433dffdc73184e0f06c0bca773a6dff34077eaee3c46347104a05bc2a0589243220b12113924a183d00e067078e2861d5040043926deb40406eb221663a2879f98981da2888949527988ecc09999ddd9dd9d999969683c0d908602a0446906ff4f29a51406839d0006cb75f1ffcfe38258cc168b318103096e446e44724cec60831ea6a84011bac8a1e8f3d979d4fb92524ae94729a5e14729f5cf632a38ac47a7a076ccdf320027c6b1580fb65811a0dc32b6a3513471230212518488a11da2a0906401030333e3303c146d202686879f9898243120724312277888a20230033d6cc054831e6a497c3840229764870bf4e7eecc4fc3a38d10d83a3b3bbbd3b8f3e74edd73ea6ef35dfaee43fb29fddca9f3c0c4a534378b1824660c762002c5f1081d818a471d71cbbf11d121872e8c409dc6e66b6eeeeeeeeefe74506aa383aae02450a0767377dfd0c5e522acc0bbc88188bf1199312062832439a8a03483588c482d166362061ab8de5db80dbec3751fc29945399f2865dc169f6d0b876afab25bef2508e3c79f2f6e59171084616de9b329ea8c8afa82508539f87e432799333a674ef4118d035f31654c88de4baef710d7cb06e2fa770fd7598b5bb20fae8fb764a3463dcdd1baf9f29f0d55bee1e700c15a57966d3d582a5bb2546c596f10088a4629ba5d0aca3600a7735106d3f4020781413abe27d4986141c67cb5ce6f37bd69b1b564d11b72ab4e39a1214db714d53332f57019cbfa0ba84b33e78b66ce405902686c2e9bb3bffe3ee68c74fd7fb8ccdd7987a7c60a7f08cd1f066b5201a60f4b259bc3b2436825fb81244b3609fb60f01d213803e8a1b62d8588ef3656ad9ac2d134f6608b45e509e57e5689e9592eebe16ec422270d0834109dc8f4015a29a5b3288a7528fc2d22a8de03632424ec49d6e350d8a53f43901c37a0c501fc9c2134b0f47cba29591c746e403b7bdc457ffe70179d010623c97f16ab4611d5a35588beebf67c6010ac3d1dceb448b7fb69e69cf16677c98334397a608222a827b8dea70fadce129cf0c5d7317df8a29d3dad18baedb4e58c62faf0bd6f3dde0382b5b643f15cf7b89115d78d9c3471fd430f9aaf13d4cf72ce0849fd8cc492e682f3821696b2a2bacf9c91da091193eb4d4c977fe94bbc67bec026a7ee368fc2db7c718ff7c0f0dbf5f9ea27d9d27ffa76e3246a6bd2e9116ac47b3ea736060676050c452216f96e356c5c68fbd6427d732ce6cc731dcc991e4cdac3a417981404938660ceacde9f4299b3d6fbd31c70cdcbfb534a82497b2810334774a34b5ca7435c37a23c0e84e94e78f0028441ade20afe712d7640e6ab87bac33951af1a4baf32827f1a492f8edfbb3b9117f58ccb116af8a5f35cff96911ae2685cc6ba26d23c3c466d04cbf8774fabc6469aecbe9dace842a3f7abd1f4479efae935fc3c960f5d5cad300856160b64befabdd1c4054f8aa7f2944070164d27294f3e9257ad8eb1a7ad98a7937705e9fb64ccd9556420f73eef46791666befa51a3f3cc97c7f80ed3c5c3352ec4323dcc19ef5b064234910f0ec494798f5f60ce7cefe510d75d89174c77c1243d06d3e58e6319f79c1234b8de02f7a3f972cf813cef7199385d420dc3fd89eb5acc390bdf95a49c08d7e0b08c3f8b712c3a3045e474db08ae0922c45d8e32e2fac9fb48e097148bf9f27f19690e58c6bf355228f3457124982e7fa21234bafe306c59734bd0dc4e7765a42098a4ff6aa42198a4bf6aa41798a4bfca487b98a43f0ed7d01eeee1320a4410aea13c2ce3ff81eb9ff2afb63c0d4179b8fe28efc1741d4c17e23207823b992ef737d9f274cb79e4856b71ff5e713d8593a180e39a7c2efc2b60cf63a0a0f621236aea67e9765e897141d5fbeaac5a71dfd0056adb12e6368e6bef311065222f6c405110992b5fb98bfdc16e5cab677d94395181c0ae67579f574ea315b8a254ace2672b8dbbffaa4190e5b6a4d445fedef34e39e88bd5db47d83cc1e04e982ee9c2f0274cd9b5eb79a0e9e7db742a4a93deceb2ae492ff645ad99b9de7ba6f71ee63d560ab326c632de7bafc36532defb1e2e43e1bd9fc165ae98f74ef8721291cf3c63e967684bd80d5f54fd34e9d9d0785057af52a5de7bde71598df782dce5fde9f5f5a73b0bcba5f52f3877798ffae97d8ace5d35c696cac37ed25e634bc5b676bc5ee679d478588d97a9f13af45f3f4d78999f3415136c6b07ec659e07ec65645ea71f66c1abf23c641ef630abc32fa3f293a6a2f25eea6dbac6cbdad196e04d8d8c43a5bc376d0c5b8225d812bc294f828d71e7b76c19e396ac73b1306cc96ab17ee7afd812f4bec610eaca325093deab2cfba4be649febbd4a2a65cbf0c1708e3570cab8134b73e4eb9a316386cbe59af193164383068d989898d7a14fe3ef2cbd8c134e384106bf0c7e19afd37fc24f1a0a636b7e8d9f34726c4ddbda41feeb79a0f035ac8e3f0affb23a4b70fc51781dfae44f1accf8c35d006346de7197f7ae710677798fc2d8c35ddecb1875b8cb9be13d7982cbb816f39ebc9ecdf36233c649738d93468e9386c23869278c9326e3c24c4b335f1ec97a1f5b721a12a3c55b28e4c89123ecb3fafefd03d7984834efdf473da37afffea267409bec0580f7d94c13c1beec5c0a5ff66e9cb4d93869b071d200304e5a8d71d254e3bcaf71d2f80403ca5fc98db7e907a2a6ee913943ddf0fd6929a8ad8b839f274325f042891640a179ecc64a57430e96930f35e94e641df7ab8f7d51cbae39106d815b9b3366f996af79ffd6f9306bba08cbf8db789957a1853f721cdfb9960fbdd6a4bbd778505d5ec505067aaacdd9e963ef369275c24f37e1615aff52c2cff9e3db1e77f98b3f5de6a9f0c3d8d882f12bfc10da8db10503060c8b13fb156c8eccc73e07070c976ded58e159f825aecf89b1257861bccb0ea1c1b02d1af8c2f8d27b8204d0a5ce3dbd4dc7c63662b945c17a8fbf07f93bcead0c5b826e4bf0a6de041b34ad2d63dcf0475bc6785bb26ef8316cc92ac192605f6ccb96608d215417eb46ac17c9409d4d9ebef422d71fc64803df932df93f4e8d650735ae75d73f650402bb2d7c63c61b6f635ce1718cb19719595081060d1a2abc8ccdb1f12a7c4eccd3f821b416647e086dc68cc7f138331ec7f3e368e1656c8eccb7f03938e68d19696f630cc0e318efcbcccb2d1f00167e088d76e363cf1f5be159b039367e85cf89f91b3f846663f3430226d37f365d7ad3587ace51b24141473b5dce888871df085e06621f9d0faa5d98e0b0a34401d25c1ced625fd49d3923d23290d6cf457a86e5fb5977e3aed5f7334e447d8e0664befa81a8a85f8da9f7d133d4b662a01f3eb52d01989eda21379c33d4bd115fe5fb7bac3ee57988aff2abd7099899635ed4d58b7ffafa25d7d3eac52f6b8bfe10da696cd1fa069834d2e69cec10daa48927d34fda8ac8129077e2f7777fdf0adb3063fa4b2313e121ad46aeb9cb961af93406dd6e206abde58c422defb81d800b5d2be110048d9ccd034370c2160595c28911774ae1c4080a774a818b72f90682b5defe767b1819d39d5cfff2759d89e64f7ff784c21bdc576fffb52d3d38652c5fb2e5edf3cfb2500bcb09088c6f4d967cab71ffb8f258275b5f68504bbe9d9e6ffe93e46c5b31d832e7da3408d6ca62fd93e43dfd3c9dbe84ddd369acdf1703298bfb3dd79aa4bb2da30eeb5b9e65d45982c3b22d56c7345363cedac68948bcbbf5560ac5efa7f3cd8665251453be9595adf774fa6aff9e1e65cbb725794f2eefefc3652cdff2e22db4306e13066b64b9b17ccb8335ef992395de1a76b03ceb71582ccbe280b692749734924e2f9074f7fb7aa34d191e8ce84dd5a927601ba069abba7a9a4a69adc6eaa6fe6875d90c56c5963434d5963052b4e53fcb8a947a49b82994bee98a8a62d82a65a396ed38ca51ae4877d4b58fc4ba263d6709cee9c3cf113f27fc936524a527f9f35193fc0591e669522772dfb07d0841e527b121ea674b98a2a218b6ca74474a42997d9875b026fb8be191e439ddc543caea4dd70a09f3d54f3f0fec58870fca7d3c0f36675336695e16ac9a22f2de7bf6a92dcf5b9ee9747a1dd19bb47a7baae99dc1db9c353165b719461b23992fff1b97d1b09b59ccddcc4da30134e9a42068e4fc08db8caaf7f5abcd51b8fe4c04f306e6ccf49ca3228a27405b828ce224ae97e0fadb380e02a68c8560db2c022ddb7474ac8d13fc8ea3529f77a87cea79a8d89c253829170f95b549d90a0671fd4b142ef832660d6360caf883a92fab0af83073667af055631da7bbc8fb00feef417ed8062adfcf3b1120c6fd9e6dfe2c56adb690a21e06f1c507ed9f40f061383d6861e62b65c82d8ddff3f72793686793a1355972be5aa753529f342a493dcc6529cbb66ae9fdf8d5831b506aa73ed5e00616151535f97c89fbb84f03f9fcf8e87c7efc88aaf3a2a229a68cb5d015e98a8a74eee33f3d535607729f9ef1dca7e6b2d6f7a59f34ffac8eb55c03df64d9c63ad04221d20a03ea134e188f529bf75e5a40d4f2e5d26fa63636ff35a8df152948493f95e402147e197a86f494d27749526777bee8d31f5570e9574123c5a55fdaa05fba2e9d2f0ac4cad0247d979fca4fdf4f2ff093accb0eaa7fdbc932cdb6053629decfb26a0feab7d3a4468584847a47a79833f621a6173167969833a614cc191ab81554700debfd69d19cb5bcbf0b316bc0f777db9c95de5ffea9cd1d0793fc41c2aa551e1db891af60720d1b9164ca98c80c885000029bd07c39b35075f910144be3caabc6d4ab8cf5c331e54d23eabff1f4a4517c705c3d0bb9cd6deeef46f40c1b1919f991e37eb87c03b17450505017b18c7f8b6d9c63b751fb60ba8cbab87e6483fff79d7a17825aba0d48bbfab900ab17691bd00e8611a054ad4660b0b0102a25e562ebb82be21a37022388a577416ca4c88b983e04cb68c008ca08d70c5cff301459483c710ab4bb365a89274ff253041ce386d8b2904dfc928576de45b8fe2b23cf17cbb0154f2d6ce432b0ae74fc7017d7301196f13f3af914f3e5cf1a29152ce3df32d2176721e9b9fe2b3fd77fe556380d26e98e83e922c2356ec432fe35967fddc1ed4e3a98c1f51753307d896903471762fa10b38849fa0aa6cbb9c68358c65de649a6cbdf054428b8ee20b8fe358c548fda86be5a0f61f5cb135c701124c87cd1bfe5e422c64ffdbef75aa48f549f07ea6bad8ffa492bc9fb7d9ffb7fffcd977f8a7e1d83cc194a082dd224a594a23e25c64fa56dd3e2d3ccd9e9e9a73065ac791a69e68b7e0a7d1415e95b932d652e2d91977e1ea51489570224cc840913005cbe5cd33c7ed43b2e763b2edcdbc17cb9c7c4fb929988cc64ce9898b2f6c18e99ec9830f1bcfbbf72869db2f01bf40070bdd18db8cb0f6ee47aefdce56fb23624a865efae50cf74ef1cf4909c6c4ef8a2e5d0b626ad649d0a003ee9bdf174e72987c73d7dd4bb988ff7eeb612f3e5f150b9735cb302bf9f6d2b1f1f2bf73932e7e3875a6add800fda1ca6813f84e663ce50976d3577f5afb8863730658ab8bdf297102ab515cc250122f98117d650a5d6443dd424fd90b62431c452a9d572ee2e9d01993eef3065acc574d1a7d49695f2f0cc17fdffa192a8330feaf4d3c5f7cb2f973eefe6ccbbb43d70291582f60e97b60d975215fdb24f70296d279772937eca5496e52efa6c41cb9644fab05627e56aae824ffab7b9acf5425ffe9c21b4fa93569ff2d36f243dc3b9262943992ffa75642377d1ef23660d633165e8d39e16b8a7a78759c73d2f2154d0b2117ca449fab124ea914b9f59375ff471e4503ba749fad241fdec4abc51043117fea45010c71243138c67666671d4d103308d373830461ad6ad0557c216d5c994b516d3e5385ceb4830770efa12be0277c1f5f71f7c306523607da076e07ae901b2395d258b7a9679764e2aa030f7cf6b21af89d7e4e320c4a07e9018d1fee319c0f430e8b7500ea5674a6fa1ec0b7d513fa9c021d7337de7153bfe1ec4a465447c2709a19ea95df1c4f5f7a223d7df7d4a6185ae654df347a5a823e99929450e0aada2a767a6145718b9148beb4f29a52d1baafff88a8ac5f37c8741d40fea276a045b5051288a84fe040afa11a29258a7a3485a31a8fcea57b61c72552c47b9f14375252ead7ff9d27f52d45342028fa691607326407379245fca4f47fdb4cb3ff525489f2271977f09861bb56e477c568b65b12b2bab52b11489cbdc7fa82d6b8aa3ace7284fe9ba5bfacfcda3b958278aa282f6484f56501ff5cf51eb884ae242e57210e88dc54411736be994257ca3a3496f018b5ab2ae4f9c0c2d8b791d37739672fd771860cebc180ccd9c7d76ce17abc99e7976ced74b9332b14befcf7219f830b7645d2f46c37297df528d1054ca1cb0400e8532d5b40d2827ffa4888da0d422366a7faffba71d1a731638bdcfb01ebc2ff3e583eaf6c611e352e0032666cfd9b37bce9e73ce6e1b179ab999b97904e014292d40b8f33cc4433cc4433f343444446d35235eabf54c7b05c896e7f3064131655ef34a6fe21f2cdc6d5394ec741768fd87249ab30e4215fec50ea6cbfda7f5281ea57679e7dda6818ff0b43667df13ede6cbbb89f972af68a849971faa13302f240f2f7487544510346a4104910379678b51c2d6240aea4747425cc89ca9e88aa4fa78e55541bac72ad730df71766e21425cb65a59b6f51cd58e6a47422430655c85d15115e2725455fff54f50cf4cdfa9b158beabf5d490d46c38a3d54acd68f7e44888cb5646b926572ff4e865f524a732325259d6a77a57a9beac2adf09b9664b61f2e4c9ef72d57ce747cfb4543fe4aaaca35ea5b26c345ffef138db5a06f5bed21168c2c96df01d36f21da3175057b592fad24fad1d2bbffafa382c0fbaab7e68fa4ad8a2be6ec946554c99d19c91bc16840ded2825abf7138fa6ad2cea74b3ca4169d25dc6f5f7227ea4f4b29aea5bc6366a5793290fda00d5d277a6ca966ecbd1c58e6ac72b10c23ba6934d07aaf37891399bd7891429f98e0a6a398f5a4c508fbaa84957f5cc6c52e5b3e1402d7dc789f44cd965175dafef0fd6279d76346dbaabfa872962095b54a6816f6abe5c7a507da76752ef1f56b1842d2a8cb7b3a342d5ab1e1c5b5e739bef388f4a6aac22db42a01f9f269d67be8498b71452b061c3e51ac79dda8ea6adacef18f98e110dfd7652eda2850dc816454e48c805a32745464517e49acd87cb6a65b19e795cf05a9394af0b463d7ccc99cba52f43ffe819b6d18791e4d32a3c77a709400827cc0b0e15254a420c46c54874840951f96f9c04f3a1420511944091830f1c410716e726e5514f535020ea9d887d42b9cee2f3f39c79cfb60cc2371c57620e35fc1a60084f31946e78bdf9e2ff38c7c98a76ce979d41f886d60f70821c0b86f0c31345788086001108c186274458d273019aff4d0f25a8075d86b237dd44b5460e6ae9c1c769929f447ad0de90483d48a41e3738373d43f29b1efec22f20039c32e539e90d114c87165c6a2751d8550b916d968b56224bbc81ad892d8a2068e45ac8619817148944cbb869b480a982eba20f19bc2660d6d8b08ca75ef52befcf4c804896f70f4516fb94e3f42ecc192ac7879b2f9fb71c724b9ff2a52f61b77efdf034ce1bce1e414df2a03613a00c00e9501f8a2ca6bee575549e95b2658b06be3497bce2a9e57556cf527d8b9d34d1b20b5c03d2bca8e534c28195c507a29e74b8560c6cfa95b1253eeb579e656c89b6b5a3e5599e07eb57bee559809c0a203e0d2a8f63cf98126c192190831f8679c113385f6c4b20b0907b36aad4b9a12500bff82962ca7798f2b61543f8a787a1da949427fda9f42963e9f94793a5d2cf57db64681f0c68926714e23fdce52b5265342299c0807e01a5715ef0a644ba84de505bd862c0d4908f607567e9e7b7789b64b2718d0100442db946327dbf2908e9f20b7e412f6eb9a260df10045b00422d63a092908382903cb40e922f2c1f54cfd6180e49efdc45ef3fd22934956e7c034d1c564ba90e014c197b00a7a3e4532b1de91d9e1b8b55eb8d75c43b9dada7a2668e7b1afc2a7a3831a5863e750453c6fac33d4d9a7a4c162c3d8b552d6dd207eb346f3bda086f2c00f7cc5ccfccf5cc5ccfccf5cc9c8e79741dd73d3d3da59d26bf68f2e874c3b70af372c54bef4a9d2245e8f3d3dd517661eb7cf80443b74f18daf073d8862dd0045a3227358416822e4b3d087ed8a91c1595e74fb18c34fd2aab4fe5a87ee59be5576c8eea4b1ad5b8ca613295b5b543a55a49bd8acd61f9d44a05fc9cd4aba87e6573545e659f65650459c8956791ac9e2aa4d58cc991384b07b62ec596ac684d3c52a19ed181f49d1186e94b53d63af04d0fce99587a81bff41f96be8652fb700dc85a812a959405439b7a9d50c5eaa82ce3eca485395aa657fda4a5522cafb23aaa67515996d729499e2f10b42518b6b05a5a58a0ca5cad4cafa3fad46a65649b4acba85a7993c559fd8a9dee52fdea4be6619b6a0cf967af5ee54d5f5da6b3726aed58bdcae3ac5ec5b2565e65abbb4c29abb3047c9dd4ab5efc77198bd5517996d68ed4ab1e27f52a1247e5596cb832f6f0d4ab7c0b7c21ab51f5ab37c0a4cd90a35295f3486571e023d0525f4e9d294c8d25d13bbd80baed335ffc65fbdc179ac795eba517c7d685a5eb70c32ffb28b46093e19bc60798c2d11483f8e0c3205ad80d9db8a8f40d564549eb108d0c0000000053140000280c0a86c321b170482a506269ef0114800c819c467e58194ac32c878190328c10400800600000000000800c06b60067e52378efeeef8af6ce3df661e3d0a0f6bc2d9c676f5aedd8c91866c5a8b36e1f9330f36dab32e20d9c683221aebf27eec3ccb6206a3ea81ad132ededf6d97e8735864bd45153fb930d12d4825951010a8fa3b2710ece8b44f8d8864f06bf5c0478811239162c6369d95a3a803fe7ed2f73833d4e5a64fa1d6757cf72785fed36878ea961f20b2d98dbd74785d91cfe0dfd1e7130d20566a5e599eea541922d9cd3c6126a21645d4371ed599ffa6760de6372935f202cf1454fe2cd2cf5f3c8d1a35d1149ef669d78810ed02892cd4329602180340d81b1ceb45dfdf5fb3584729f941d81c18e7eb1d1f53c15a112ab9471fd82f76a3953ed2fde2d2caeef31f4e4d5205219476a1ae5f687a6ad65b69516e41e02ea7405f53be2543414dd41667b9d4077405f8f81cc77acf262b6eded216b63983b03985f1988b9d79bc8fb2eb48785916d82c8f7e1258ccb94791eab0643b282491fb13bc47cab4d8b2734c77f291f86af4acad01e6f48eda0a19b5a43d3ac8e29df630389bc582543d07f34b072d282e831890c30712daf5a0de16f03e4a6afb25de6c6fef1ab0c2dbc7faf3861c5816a6ccf54f83ce53d998eb7aa4216eec29b3cfd8b592901a693d1b093c0c645239d1e9f882a6ea669dc84a8321360fab16a5f76f6f6646db277badc0b9ae5428f217f101cc0840790bab7e4aef40fde3d9d99d054344197387c6ea74af118ef8b5c885d555dabfbae5176561d768a695f2fc79a76ff36766cfbae2cec84f11dde73032ec007711e4960ddca039de2e9c5f84b5ab2d5b62a12d53a54b538f60b4a30adf2ac58676477f88608c816cefda72131e03715e670797ed957de115feb2a3ebe943f481d07bd0d12e884bdeb27046d1bf42fcf1b420d5cdbb9a3b00c12dd137aa5e6ca099058a6f21347ddbd607b2a7f508906a95d9627e228348e1e76c34fc094ddf8c3e14e4013b1476ecc64cc7343b78919cc43c91e2a8c768f75832afbe68fed0423cdb278f5de404189e14273e8ef87024735f04a6639a0abaf0f29eefd9fff8daf7c6f2e06fda1ee847d5150d15aca4d1e46bd240c372ea158e0c4ab630871d02a2eae78f583bcfeab966e1ea96ce3744358ddb5557d1a3fd3bceb8bae783e023211d96bd5f046f1d3bd295f4b7dc440ba8310ade9ed912ed4e882749f9b933c7360a32a979107ad8ca61a6f522b03f09fd6916c15d7b61245366683c8edc7adc35965cbd202ca4ef79867cb3a7c172c6db131d1d63f62130066a44a1e47f8ed86c46ce84e3cb6c54dfaf81177107a551db08fabbec332e7abeff4eba6a361851fa1cf4fa70f1d5d55f39cfc78b7c2795429d2a081f51d8b82e1796e67d5773a4d95971a83c268e71552bbf4aa42de5728846690177593c08337b8f6ec630eef845df237efb6b056b11d87416a1e1fd61680ccce4ac7cce508a1b9475a5a2879caa09ad4c87dc7a9abdd8838eb6d0e48110bb324b18221456c812af5a20b207ff9a91148f04ffcc1ce57681fda296c47860dfd76d9f0be05cab838f4da4977f97a8dceeff447048b12bd17c0e46d42656681328630682f42cc0237ccd0c32ac6110f4db38c48f8446f44e6fef0855e79bf71f9e6672b36b811a305d27e67466ae89104f785707ee0cd9cd517f8f1f3743b516b4d1a1b9344ba634faeca04bf953f819e4d2de32cd40de424d8c3850761e4b94ae02e2aeb8be30e6fc9b83401fcd5b911471f98fd9ac6caf0e2a6307afe2ae4e0ddd145b5c227a1db4601252c589a2a162f94020994ec15b80597f8f386dbdffc7f6e379440e344f749a7b069fd8f0356faeb976202e33e43ee8f835722e881def7c15b4f3e44a4dd235fcc367c7718d8ab4e65623ffa9728410a56def540212101f8c21e2ba766c32a7b5d9ad61e69bb75af1ac697796c12626b175c13c6f1d8f2b2d8a4dacf800a5b79db7ad58d97d810549750620b17e4763f83af65a6fbdf8b9a0ebb0da34b7ddc857fe715184bc4054a7ea7f1195ef633a05304cc3fbacd3906b4d63a6acd33587ec2db381208eadc3a4e77205b764504cdbdcbf0372b4c90553cdabea89ab8164204287820e28722ea5d4967a3841ab4fa042e7924aee3261697a89fab6ef86316d8d4785008ad5cdd506296c67982fad455d00d19fa2f180b93ee6277bfbe4ee644b3d966d00b5803cb6007ea1df0371776a6875c4d090494c0d700150367080373ec8ee0b2e7c03c207cdb8b968a3bbafa8b1f54629f8e4b0a4b81036c4233fc3b98a1613e56b4bc4968c98ef40c64a71310c60192daa8caffe129efdfba9112de9ee00454c583382974d2a9a1f27760e637a1b9ad0ff70191f183e73dea290dfdf53d7c00af2334a152215e7650fa00a3c4db4ac89c1ffe7a85e303717e442626f5bd45de840f8c37235d0e1148c2dadf6c82a8eaa4baa464438b3a7c095cf616ecd7776b3a608e12bb85545fae7b6ceadf800e3ed42ce02c66ed2d932e0f78220eff5afb2f941a86de118e2bc93fc7988779afe8298eb5a6c9f7452e454111cdea472339fc47680ab31d11df60312e3b7b7a32f9896461e5c380737a2ca0f14832879f46b4091d76d9578d17a5d126445a147e183eddb775c94117ff14cf9cdb317649cc8f13a8086ac1f1af9c33330170ee13314ef210ed60437bb7a50b8894f6804dc9641ee24b5ba164e9e284954a9e06e72bb41c9d4e6c7155226ea9949492be681a856f312d15a438ff75ed07c2b9b2a6dbe18fe4cd6f6957e918a854e3933c0f0b45122ed5ef46da133300b8e413c014742f5ee650a37b328b0c8736022beed9821c88895b847cc05e5718fcf398c78b88c0df2570987d16eff86cc0403206c9c108d907018dbfdd23cbcf9369357304af2575a942502232b4cefa43fad91d81329caf0f9f2521eda51128cdf43d23675d04a6ce5d64c8914831335c0e15817bee3842a2f25a2c5d3d9a00a39fddd45b3078221a1b0375d2293ebfb3dcf8c4a7bf17d86c82d44ca87379f00cc7603f619178cfc02715245a42088840122ff7c7ab46dba44be3305905f570970e3ded065d4a113efebf67b6457d0b7b928c3384b17ba00010a947a40239a759a8c2e07ca5925213b8f39af2f8877bde40586e50f30514a78885fd2676c80b5a8af5462b033e8b5e1865756d041fdcd8faf34f20030c6f43b85eabe5b58fb05a9e9f0d3e92e7c6200e8f68717e1ddc41fbf5ee9fc9c1acd236cdafdf17d5407590be2b3cdfa8c25257447cc04957cb1ebeeb813a43fbdec48094391ee3fda6b9446c941323c7c769cc02233ab2d3f21f017b89f7b9877900851e038d108829f69af3b27734f344dff24b0db9d5c1fe3a78d98d24b55ba4a1cf1a045d3e03a37fc031ee1b07b33c01b03f8eeb18ebc5c374ff0f20820dbc55c798a34d2b7677b436c07aeceb1fba096a84cc39635f7fce041db69fe6f618fb77b7a1cca16b0090680cb0b4a9fab3e50509838ad4e351ccdfc8abaeb1aea2f6c30ac89c81bc196e29a709d14127d11c411b0acc1c2bc90555abd79b08e5b474692d8e0f261de10563db9ea05af21527eb93ff8849872c1befac504e2d5a7c2e7b2213006dca588a2b2e4e3bf92162a10b6c980391478cbf43e1bd27445f45c8d73f6809bdaec0af410c28009f22b557f5e5b504eb62c24c572ce692456956c2c146a154b4c22b5cde73a486a95d0ff03ff92850b2ab66c8854efef002d2670592818d7028025f41f49a797789dad8d3b309e783f4259b1c3d7753c5aa10360ffc055a8b5c8193e9af879358a6c79f30a0eabb11f113c810594edb9c6b99b2975b27a31e0dc12dd7e18015f839ac0fef2d3732efa2a25673aa6bb023c228cd9ca6810b8e49ab8fb91cc400bbf5737831a2b2c1f2ef2b3742e735e7db9860c43c17a6027faf3c2f9d1bda2253f569113e4cd18af6f49a3fdc869f6b91e7b7b252274af223b81eaa904a00052433d759e0dca43c49c360793f1071271ab207cc525c773b12c8fb60ea81fa9a0e48e1b3e6f051815cc804b17931701221d2b4da0df958654c70e13dbcc1436834796bfe3fec59f3752656808b6e3d2e6655904b08218de8ffff318e5e7d02d9ffe49ab0a9ee1d97fcc03abe938428c266169f8dde85731ddcd39a00f6040d665580cff99665d16e3afdd3418f45393174336e246ef64a24ff9b1aa2d67c3f559a59126ee1f2ce24103577c17ec41813c8968421862d91c87fca88490cfc4ee3c0132b20d151c502cccdb620f483e8493d85a037125a19caac11ff08f089c278b6909ec46af983b65aaadc12ade3524c9550ce188a57ad752f305b170f5ac9ea826768053d09813c60d474417d85458acf9b7e9da9bf4d13050a227f8752365c7560cdfbb2b4d090d88471521657468884bb8b7468eca49a5d6ab1c03055752b2b07fa530fe587f5240e24c677a8155e118e4d7aaa91fbf9a8b0545952aeb182d9990f7411d8d5985af6a17029c0b4b990154984e36a5056923cc33e9c67dd7245e68a65dddbf66e8983f434dcd5adc75cfb96e06d849ce7ab54460a86bc390beb1a5b8523b87eedc8cf06295c1bd66f578c55f8d170f4f71577d7ed0cfca778f42c3879c83e3a5da4502ec80b1e6eb8160515800d7ab0fb52fd2274e7085f64f3f96e409a0c3b4dcf6ca4cd35df427430e498a43d324ec3820fc1fd82b0970194e4efca6b8fa13a7a814920c42d9de73299058a21423d75c007eab8b5517d7a3ef9d9ce3e7bfd565d1edae3c359e332dd9f5e4864166ef6c3fae19909bb19e5ecdc19e185eb9a0f4962ddb5e6c03fac1238590cf852bc2130ec080ec44e1fba0a8190b174b0a749e8e781f83dc9cfd68deac743a2f21027052cd93acb95ecfe45e04618374b87329bd6b5627c63f8293c16f467fd2f1b1c254ae4a29dc556bd1e829eab4c6439f1694701e80bc59e8c70a3888b3d2aa1c7588eba84847c07c38991c3eaa1046d890a14866cdb297e1ea66d924f666b5707da77d0e4afe79476528c45ea3ad5807347d09650730938ecdb79654235cb045e1411cd4a24afe9ed62732ea5a3c3bdf434f8671628de56dccaa0d873e907b8f1facb82567bf091975b19668f96289cb75d7256bc80c8155a4145d0616a67fd2bdec45ad325e084d5205f5871c6059ea8029169222d050ae10a9ae3a112ca428b2a16481cfdefebc0541714660dfb57d45d7957b457bca71efb5ad380adb8f478230fe3ce44c06234a43d8427f0909dab0f4d75c2fd19642a77253154ef3ef9d849a43dcc79c1fb69eb96c02805afa44cef945f6e281d1bf656285e1e00bc58108bf9a44d995ef3507f118e9060cd4269b44c06fb258204f6bda39ba59fe4e4fd966f249d71e9c5497f099ea46ab3c911a36c2c248e0da5a244b0016f338fe7f0b64f98159dab73177adff94c6da6a87dbb685e226688d63d184c94ac58184111f29bd4eb066fa13701d796ffbf97d1bc94dcfe94976299e7d3cec55a59c0427dfe025af371347afb9fbb25c11572ef28023cd5400cef3e01d4ba851fae1ac9ddda994136e3d34abf865246275037ef5b858842ab0b4da1805d7a7d24edb16f7949df58e52dc40d7a9bdc01307674e1f0dab8d22b6c245a18a330c31ff293e6536af85e625c672c8d4d69d6a8079bd644c3b7015da2c1be27aa8dd071219f81575a42a1f17a19f589e00a3a3a8a172bd2f7e3a4ea092c7bc77af3e6f095e36d90217cf8eaf28dbb93209862444c063b242955d271490db4c6ee2b0c59b17bf87193be75e95fe23c411a5f285e2537d5a18b6f63b492ece22b8bad1be4d53fce6d52951349d9cdc52c558b375185d5ab692b2f3bc742bcd3caabfca80657ebe5037d9ba32c065477fa893ca5c5cf1dc18070b67f295fe0ec0d8bcddf21786021454d3bfcb5a5fc31aa535b6fc43764d2db31234461416e0ee2c887e1dba873a8a4f943d6b04df983ef863b3f0a53624d2ed09f99aeaf8db381e0982ca7c76fd277b830195a5aa4fff040a2011851ccf4d96b8cf8614ae0d974a7455f8c9afcd35e54e41944894c9633dab9cd027db7084690ebc49066840ce4fa0d8862c883fe119c0e6adf3e669c1482c97f12cf1669e04cc47e3a0fa10f597abf2e62be06fd50423da27c915dca21d7cb1e528a89c0b5c780fe62cd3b173fbb0c3f6d045ad66fac122c6e83c988e5cb6e9b3ae453c99fb89967d14ebe87963440c69a39b5e7be89ab6e0bf1d77ce7585097e575304489ded53a39e6152cd2c44b0f05e5953e15993e6627932679be6dd8f49efc0089db8f2330892114d862a5cd3e07cc4fe1257731ed4f3a10d8f1293ba435fd3279861aca5b4ade68ecb3e9c143c31e916bbfa4a4698a49722d4282241e07909d04c9b3a9ada31b6f4d3a38e9c5a1bd4c6b57c45b88ad898a9f96b4055a00a5354c1ba5889cf4ca8d7673496a36fc42c72c921e6ad3580cdda203876891fa882cbf7d2b9d12b9d02782e23d535a67921d3b9241285961902bc203f510579115260d81b34f8444a1ac09b329a91a4f53f499e4d3c0df8a927d594b1a259326155ba9fe4eab4bf9e03c6d175e36a6cc399ffc09784ac99117916c9c9bb053e52c957f492d797a97c2ff6f0ccc5a539473ef27a206d2e2d726bf28d2a41ff0302989c4a5894a024c0d9a5ad9d8de452ac5d4bd0518dfe2758ccfbf25e490628edd1b73234f7c4375b1bb162e6cac86bf3fd7615942cbae34adfd0d3b57c673b5e3174d7e89d700c91c0c8d05c2dd4118eab3628c38b1d62088ab948180f4d7e31ac279dc7d9457264643389fec0f4e1559f66017598a7a9a3ef562eceb2f276ccaf48fbaa928193ca3fe7acd2b2feddda03226e9494f443d7a72cf10f141ec0884eb5dcbc3ddf0eca2697a3fd0420370b12277eb8fd474d26350b17d260cccc18680cfdff3d4e81843089f700234cc62cf677e4e7293545a1828cddb1d8ba48e766bd0499503d13a2ce7096367a28db0257c8ebf4e084be2808c80ca48981af432fcf3ac75d9fc54a6c0721e2cc92dce03a589a5f44e11f07887544502bbc1c3b3ad7f8de00feb283be936ba2680b7a5874361de4609fce9f6077414bf92c7274257fc6f0e21352b68134af1b1ba7f56e0929b60209a3d6029d15e14f639ae2d4233b79e2fe4f240d49782ffd46b57dceafbcdbe7abd257570ab83b449570d1aa4cd635fe4a7b4a3ca862c29e3c88f834837255dc793ad868d110950c13b0f9f3fec0f7a1a9d8fb5709b512f28fcb3666e85fd3d9d8a20854a3ed73a7569fe06254a9d5b04d78a10d03bf558f07e34c3dae486eed1fe8183ef28353e4f47dc2779a4fd9e36744dce91249481be123118dc923475efd8fcb4cdcf508c7011dcbc3b32ebb1aced0be69c53525691438c332c83397ca0353ef0b2f18ac70fc4c97b630098bc2d0d438eeb8fe2f91aa15024dad31d396aca897ab06c1bf4de481bf62bbf6e3b03232c636c66d9c84258649c0182b015fb45e2cf4fcebc968c6253deed68c598d34e7fb26a7b1b3d2c4eb3c1a87912fc3039c9a8424a926b26745afa5bb5723aa775afdd00ad101fdb69fe2d8a031ccfb13da4d0725ea480173950c6f347d34c9744a969a630e8ae295924d7351f4c9462e12ad58e34ca6f3e0b72ca25f9d4df01cbb6ebe4ce30eedb3d5f6a61093343cb31a1acde763ac0d085661fa3267d79605ad09167472ead9a2384f72577466f71b1ab5685d809c8ffaa8c99c55ec2acaa693da121dd8618b5491503c1f6b8043b2352adaeae41de25e9a1faab7c649ba04d9d90675644cf9c0f747fbf3dd3314f3160f6487ba50761a419edac2d73dd45a3ebadb01a000675b2efc25dd3f36255c3b192026dbb73bc4c061e1d0ab76c30a5eb9d42136e278a4eddb42cb7998c39ce4317cf89cf8ea190b360f7ca5e669015b7bbadd316d01309d7b838bb81d3b4b3f4e76d2f4dea261ed6d6f4ca16687f41aa8147cd4dd7a86f24d1dd8416cfbdc6a3c50bd995c91de9505cf44037bf6e5ee995dedd808b1be50f2fb715bf6b40ef8abcbf0803e45a8fd9b6130d7b18d63de502e79da1bb64ca44a2306f08cdd6ba2b4d6642927419fa0d02887b7b47c8eb6e335aa6eb70afc128a80c2d8e7a53545cb69aab3118369b586e6fc9d4ec93c8b685cf44b99c166b6a4e2951b780bba42bd382998a03d4b871511a243a0d7b8d363efa2150bc7c179b96783df6256ad7b9218d2cdba7e8ae3c6320da173e3391bcca448793da34e59e75ca613f3d19b13da1262caea79b358a8ee3e675a7ff15ceda90398739bd7f9d4edea3fd994da7b1d245bbc1dca9fc3c8cb30f77748a2c5adf18eca3a8308801903151532e7a37e7cc9c075ed2018c73a7623bdfbce442ea4f24014f9f6fc60b43cf7a8e10a2f5ec551760c2b3b9a1aeadc0347f2df42d8144cd2ee0ac431caab05aa6343016586383740b6ae99caf59e505e9da9b22e72f30fb3c1624c6103fc3d0f67ff1d532801074a55a898dd86beece6332d5450be432840292b5fe6bb2bc6ad08cd7093dd9cb0963ed70aa6cb71f1c7f096f66177f316a0fdc37f4c83a2e0829ef94b521adeecc2ca701122d15c796899202e4cccf9a80036950424e527225bb72f10df2c12b0196655d660b0a90d9eb4fda2a02a5d79af36cbac46c66878090336acec46ee14aed34a4ca1d7f188bee727b9f41a7c625eb5946b50a7d1a6243ad33653488ca0778021276c03b74c60fa88b987d27bf707a7a01d1caed95e3538be2e307b028d45c5508f928616fd38cb3b1863aed731c68edc2a8786593c5914763c1505184c4937b79641888f2697f6d6cefa55b86d1d55706de29bd2d68819256cb7b12fc05ae6a9fb079d3328fc10fb909ec3070a34d3354545afc765fa084b3fa8d54be8fecf114cafdf20918c7c71422aa29698003b75e96f56b5e4f15ca38d2e127c85663f64330df1f6413f1437a8783dd01507510e5fe35a18c06327c25b701293fb1ec10c0a1f7fd3471d85a5df3bf0eaaa53d419876a2b49d9b02e433505ae31a1ffa63d27f4451f14243aa9fe22b51a5c22e38be9f853dcc0b94f4811a0aef042871cc30e234540784253efe4aef7359b5310b40e5c5b4591287e9252d9bc6425c86bb838bcf0be9bb59a457976e40aebdba5ecb22f76756411aae38fb5a485c732d13afad82d444972ccde77482954e2568e37cfa1dd292c51c0a2f9fd08537fca06446f9d599ce16ebfd31468910ff384dfca9c514118eaa870a2d73a59447b6cb96e7c7d327c5e77a76e0a89cf6a10a827dc59c865fa1ab2541800f095e8cb465c66c58d8d0e1a96840efa2ffa93ee2462e93bac23b0f58d0ae6ade498c70d60e635249c07650f0ead0703d5715a2d70464f1d6fde6fbfa18132e09aff1b0cf26121ccb03561bf09b2f7f0df8b0fe2c540aedd071fdef3ee77b68cf00f2d68b2f0d13362cb49eed516ab6a2665a302f212c5e51b36aabe8ecda78ea63e3b58108aa2f782ad76528269dd77b18c84bdfead83ffc3c0ae6bb1d575da491fc27e4ea2ed1887e81aa415ac4c1d75b8888af0ccc3ba1f8ef0dfade0b4218291ea90873dcbaf763fe73a1aa7c8ca05f6f3077f3aa96ab77626745b2d1ce0f676c6faff80ed30bd032f93e01784a7ee8bd36801f3aaf1bed9dae520933a2071a310073776e380ec79cd86485e3799c99699dbd717f971e224d4330ef953dfa78902be01e4b1918b5dc068315b477daa2a8e7f9980fd725c51025dbb02136056edfa02dd5d61560973dc385787037940a6ea6317456e26b1374e83b3bc92a47ea3ad5d143a76ab1bb7dad4b52b69ef77b4ad5557ae50c83cc9d34c372d5145584d0e62455aa148b015d8dba210bc8e3309d3f9f88b45c97ea31115e52b2f79bf23ef3246860b2d3be34b28038c0553e4f6a773731dd77e8ebf749458019fe8d2bb0edac7c6dff146c28098e9245660a921024f91cedb21a708f7d5c171c8e3fc4f847ec3f43c19ef9175f7189e2e141158db7e1134c0f18074ca4b7b31fe050f6b4bd264a4921e2bed60e34acea0d844030383d847ef7e61466f9744a366813da144e455cd623ec16ce50e8063887c13098462180e13089914ef93de635ec66a2fac382828d2d6c9f32a0c3cd14ef5e0a378f218678a896fec546475c0cca0ba7d9905c0da0be2424a622c60958459785913e546d94f302dba5f00bdbe4c6bf37bb1eb296c435379beed73562c3f9ab35e98ea1608561df7b399feb7b4437110eda32e29129abc4bc38fe33b68c08117b72e0c10d02dbf32f4e30b93f0635d2dce35c1791114af1daac37ccdca6ae1b0415f635c140d1c9634ad8b554ef1cc2807a3f1c989149ccc36cb8b0128a305c984e22c2c9906753a5eea1000945caad5ba676a5a52cb46a55de0a9869e23fa53d143b07e3b76b134a569e82aa618713592eb4b77d7a1c7670524fc9d9f10e9eb2c8edea4ba42ab509168a258a8d2a28432050cae78afbba6c667d2d6452c0a692703924ae8ddc629143d823f8747efc0187d5d7ac9de8d828005db78a6aa6ef69819916a287162618abce83dd79dcbad8baf8e689175e29048bc330a9f43c0fa5320f0205625bd6697c9f1133c58f0cb8c8bc16cf5d901479b3854d7526ee32783ffa21f2f0ac83e0cc3654a7cfa1d814ef39735f693392407bc304793d2e918ebd4cc2bdb43428cf932132adc9fb845cd1d3f5b8bd951dd1b4e766eee775951598c4675569a0f6d94e8f42798f4dd2f146085b86099086ad72d8c98785b97daa99e95ff2aeae0967cbe61448b30dd34e0269d65f32e0a906084fbfff862c084815d9b67081e719781b1e81f873968730d576046d8408f40a5aabcc508084a6bd1de8aa5bf534914fccbada5e9fd93acd04928d5b447cc504d19b7c50a86db24c4f9d98a2a6f8558a16cdc0de9d5095c07fcbe147ee3449197563ba00bf0f3d09f6b64ecdb3ed0c407da82869ffb5a4ead4bf474a798a55fa1c5fbffe9349ec40771b6ce1cdf134da3ff8ce1c4e933ac14782d8744bb7281150b80e118833f6d9b016524d2d0aea4dcf01f7ad09aede1b0113f31e2e9deeac58bb438dbe6e53a1ab80021e1c2c561b31f86d0d97f3cc955ec89a3f942dd0633a31c168be06d61a2ae6868d011103923d61d4bc66dc242205a0dabf02f827c0547963cde934515989eb74e3034003582a2973d960dce8a33839f0f75e9a798a4760a56a8c85ca4dc92c62621dd845c76df37ec6c7a812556c3c1fa2ff42e6505309838270d657d89420f42ed1312030fa14e02b206e186b8b401a25fa44366a96a48511c474848c940bbe38200b3fa11c23097843b585367fc3253e0cd2c8c3a33a61505a36742f5c1e68e59f9f01bc6da2f92c37afb37f1627ff23626a818c87d25092ab897a0190118af5541d75955a8c191f1f5022fd173ecf60f70e40db0f9e91175a72bfc841665fff2298e67151a3741213969ab3a94f4c8426e98026e3bced3755da255077e67983d77e937fc4e68ef78172314c5bfe766490d079711b9f7997072891fe36fb8581930e8069934735e6fa3cc51d105ddac33d99e04381d478b1e580e7561c0bb0dd4bae1e88f958f7b23471c56a1450d36fd24105ce139d897d7ca406a297d170423893f66686734543bc420c42af17b4124cf8d5049b95d805a770dc51b377c6378493d67e0aff39863e27273229d672e9b8cc25ff752596031cc0d138f31ac8330867b18c7f8380a33ed0bd1cf8137947752a73b60e6649a03d1e0dcfa13315696a73209e1fe61c32a815c84715d2442163609532d452e8dd8e72532e4fb30fb29f55c591c2f3bdcb20e08f008de25683eb291b69b2e41553db25f1d0efcf94ae20687577aacfa92c267309a28619f534619ed073fd491584aa38c200cb3fd969501597d793e46140379598728dbdbe77c6b0c87dcc2e5aa254955e064b7aaba9dd5cb42c8892365f43e555952c3577d27998500dbfed6f5b3d15b8514504d0331b4d01329f623f6dbe83451ff3dc3107aacf886b605d141c6c9caa73f8bdbdef9b635098178e9beb7fac5b4b9d878a2f2db85a3582d01fd294589fd7520195ad6ceee4cc8e2eb34eab7a47e1ab56af079c254608487a81b720d3f454033ba4e4dc02463ef8599458d26632333b0eef932c53f112a19562777a92bd126c69bdae75709d6a933c3b5c5783c4c4e00bce7120866a360df59e70899eb880d74010c93134c997ad5a5196386d803dc7eb3642b77494dd12a4ac3c6d96f6521cbe12539b96c778251a51ad3c4b9a5e68fe5c810858dd1968c5f22e62c737d16a6133c7907bc0a040362b533c5b5bb1897816884aa6d0e3cc34f2fe6d34ccdc30dddc2441740b1675fae3859dc03e711278d0669a823a80915c97f0a5be8ee62b6fe309e13a1f374f16618e1f77339f3589fa64833fb38537dde719b5fb3b2201f8dffb2ac9261466353f211a7bb05bfa839361bd91c04044ed49400170c2a3f55e891303431166bbae9ba6e1351d88499accfeb764c9d003af29907bcd8079ac0c0987bd369926e95b92125b9ee286e36aa46145c481d1eb2ca15baae34f2c72cfe33d5f36d406b10c90555fc1d6902c47f89471a9fbf33825e0e5f023f55fe4c1a833242cc67825a1a9f6e405aff1bef24259ab4b06c180809746a697638fcf2b54dcf27b521ef9f3a0c940f965f52d393d4de253e49ca583fa5fcef9cd8ea306ed042fc91708a7b1eab7d8bd2f0b35fb8a57a9b0637504d6422164a1b6cc6756b7d1ce0f14a9502dc5029b6777d14844bd2a75ee428153a390ba4b86a889bb700f0b4f47954e3bf145d98ddefe75ebd8331aed19e759d0e939a684912935f5e54b163121b8e9de88ccf2e1c4d7bff015dad7406147bdd82241355fbd44b56347889fea1429586c91d458ac283c58c7048f7ba0322ce181b7a60b3658914a7b6e67b63edb877635358dca4f7b5291c00202dd0feed4116dab5c545a58d63a4e889e89cbd85a408b50f57ccdde3dce35e1a4757a51f5e85c6a380c45c202dcd6550f962939c42098fcc05d538205d25eee891811f0932672f3701110631c9106c84111361e491db0dd9a6b9784f22a385865d6cff469582867859ba9d3cded802f18ef2f7b03b3fa965bc849d06ae5e9d1d2af7e4c1553b7583840c93ca8c95c4dd9be48a197db703db0aef4954a1a9ce75e8af074fc8a3c3b61dfd455a304063b7f7bb25a83ed14c6632a7fc4812178f83262d7f61142ce8317905f69bca34f84f7dcfe56b84c69d762866fb335c7fd32395692820647709fcccb48414a446cee5e1e096624b5824bc7207c52356416be042e2e58b9f59d03e0a3d0f3ca851ed5b07ee3524f8004bffe265dff902f0512f153b06434c87f52a2ab063b54e138867ad9f2c83920bfcaa9d078b82de1af553c48960634bb701e0bf86c0f9cc6525db7fd69a69739e6d89e679d4fdd5fedfe620079916b82ac66e38b8f7935f3a54dcec2a4f0fa751b07fde39c9473020819a0b573616c4481234963992a6028e274478ca949e6b5f0846ef02f2997b39454e6e0e3e6cab934d52c993f1114e1c761a6c7ee4ab92a36abe971be6365ca3f4941643e699d48bbeeef8c8b14d11a4b2374f99e0111216ce03a5c0e5361f512b29ebc146a53062c3b839f7099126b24745e1a38bf7df726de344c8b3d092bee26f64ebc9787a70263a51d0d7b981f5c6e44dafadd0f0ffbff5e856971808ff49755bb1311a6cf36f8c46e3a1c39d9f8524ecc43979072294ef8016f28aea7aee490c6431637ba1f5d42bfec420a0fed4c71c2ff9506ce23f20e079558982e18c07707a5261a03deffd40cb91026c8b7a5e0a55815d7d9730b5c9e6bb4e1466801146d77138f279f2ceb04bf67f79151561da0e71c51cd7551d1c60fc2af6080eb0838f43609c675e334ec3f98f2d9d471c6f6c9e52d84c5cd39bf069372c7ff83f05a842b4581e7411bd42afffb030e99870a53f9bd3ecae37e096769ed4f2a57dfd09bfcdc51c7b738334561da05ca5da6b9d7de49b8c7f3a4347e9859d8126592aadf90988c94f883e9f754700082595c30af2a90ea039d847c2786d324a7dc9d012eb4fc22c5024b87313fc93bf04dfe97051a7e2ff91b108298a6bb50384103776df8388e1c7255235f238c37adde2226e288d6f02f12f990a7e25c6756e2ffed6a5083f016129e902c2701c8e5c46f66bf796606c64592b0f34819c1b744f9d7d47ed9e175f4487bd6c1061e7caa9b915dddac496ed40934d4f8e8fc7f2cbbf01f9193e28fc8b20429690d6ffe69e1788103a114f4925441da8a1e86a148e6606b0d30c15b702506f56155223e4a3e2ae25bc14466b404d5365c631a4f84558b49064b517d5fdb525e1a158e738cf85ca7fb659e30a871abb7e31620c902396ec059235cca065aa828e458f7e119dfc169c583448b389a4fece68f227cd487865846cfc6b971d47ddd49469a4bb32bf49593588bdd95e1445153843b319e20ecaec52d0e1f3723d030c6a9731a8e95d033aa193ed1f53e3fc1537f5f193ef50b42bcd0678e61982e163683f73d5a687f43555531f3e80048b926b004a0c50f13177fc857b9a88b3234f779609b8dc7524c603b51b2460dcc78b792ce141bb8d459f7bac1ff03288d96fe13e0bb8c96d6089a3b528787e646826b5d6c64563fa069d662ff5744d20a4ae86e05103dbcaf7764adc707679f986ac80a7dd1d43d157dbaecf08a15e78029750a8458fa8cce5072a5c58142b829c79c3d71c29dc26219ba38046dc6020b630f8d0e6a5c7cf2092d20634651de4112f4095c149664bbb67f5c45c4e78ecca6aa43239cb1e445067198ed7677aef0c50d995412f77ea00f89110bf54e5b32c931d22fa982a476f46ac3bb7dcf76c5ffbd74ec57a9e79d391ef719e08032e8e864fc9c842df8cd4452294d0548e4290003dbee0b212314a56af1a4e45f464c2b64460cb70e9095942f69003bb37481fbd69272097a61e47d0eb54ede230cc7c6b74fc44b10b0bb79376fe9b70b19bee4c5f3f33a10690e7a4d90d1473d7b42fda4655a6e28dfac69a6db8710591a0cd1ec13ed5ae4fb33ccc1f1ea4796510a15ec8f269bbbdcb504430949d966e9794a2e3e1e7766d11fcca98871cd7197952f789e35f3100c22e2a0d192a31c975039702ccaf988d255b682cb90008a52a00e425f2c3be5541708b54484d15337fbb4e84f9ed3de03ef64342e3e1b98bb8d67fe43a11e689ec8e2892a8a77390a1d60b656279239f7c683849ddc7e0f1444d7ee2788ea7d5e74db8ee50e0ae1d1f9a6b5ec413985093c10663b9344274fd7f5deb0ca0eba0d680c9d0f0031c932f5ae9b04a062688f010aa66fc728fa78709464002cf5412206be7ae39945b433ad184ce613afb406a83e35143e028ec22a8cb20bac9662a9f3b1789ea1b4dcdf3b48218699ea0194a07082e61b890c7bf343fc8ee93768c3c8759f7380abb489d9d47be1a60b65a1356fdfa93d708b1c7af36d6178182aa212e9a94ecd6db721800c22ab38c8d21f5f80399960893a8ea2874a483acea2d4e0eb9d6ce9f2842a21f84aba14d5509938b602d16ff239d43ca217d92bb512c57ebc7461f73e0133c968e527cd5f6bd6bb83e9feecce7ead5ace1c26e1b07a9dd63a93dde06ff775d1c1d7d37584ec2817f4f4e92f91df925e89b0cfd66a249c5478423e93236dbfbf9e9d11e25a1d89796293cd2845011babc3c99b60151d567a57469a96597530f785f374dca81a08d4bf895dcf7afeffd6830991feff75f3d55934340b4f2ecfe15dbe5de28b3d8798969dcbfcef88c40a088857f1e81e40f7cb60d103ef22d9cea672a01611cc005a96c58e67546d783fa666780b6d12babbd33f3bda612f67dfe22775b578439f00cfd4301043fdc237b72592326440309ad13a7f4eed69ed9bc488b51b9b345720f02f987a08f4483b56defe187ef07f39e0e4880c996f844a3ac108af298416087095cbe19d18229daa290cccb98b0c96eb83de8e8dc54259b73f9744ecff0f0a05292b1075954dffd108a5ab241c13d1d5fb915ac470b5050cc06b659f485cdce74ab2eef40cb723c791142af5caf1c5654c2e1d11d4231b9d3e4d7e77de87106e8d33ed0a64ffb95ffc86a4af0a72408520a7ec9d5a39c6adc594c66a25fbeb3fc95bf1eb706d0d11dd3bf919af4a74601d0ea4d396a4fcc6c2063ec89aaed2b8f7da6bb6450072d88ed62a223df53cb42c59a591790bd3d9707675cbc7b2cfa1c88a35da8698b448d377af72e23ab273aea50bdbd2415d78d3638539de03b29f67a34fb505354b32a9d96bba7a017563a1ff56acc22a36645931160f3f2e6d2cc639c9b948ee8604eedd005424e0322e848cfebe1c7e551287e322e02943e48ed39e48ade42b1b3c70934f13743924aab27041a7b56e70224c23684ac4583101e02fdecd426a39095ec1d6b73f3c23e2ed5f8a3c2cbea3a51d9132e670d05724181bc80cd5a6b14a6500eeb6ce7e034e06b111e6ea53dd4047b2d5b094bec246d4694e6f392022ca041b4e34e0e41fd4a66d0b1c666b6511903f81900af3e2817200d86dfd66081e439e84ca4b2e136526f7604e38e4ab07e87d95b7f02b3e3fdf95b624103d0d1ce551fd8b9d2e960b088e4543d12669fbbee7b127fa88370456a586776b042911388402e7865d35a660ec6b0484620a2728625aacbb6cb8784a7b9c1a387930f46e8e268fae4885982011caced53d4d0b75ba5381893652ce1a7ae7b7426b0d497813a4146efff5a0c3907b257f9a0ba2cffced716da50362086f173a9b0245a61906786556a89c12ee9569c7566add799421df144038904cbba86db67566852a861a71dd5db80e3dbd65de9a674c65490cdc3444dba54f3d60192c73bb1ef48edb9bbad444abe6459b9e283c60714231f0899a67195cdb3381ee1c314a03a9594e4f615ac1fbc103527509b3cfc26ea03c5006ad5f043d0265567df877e114fa363fd02c984b64a2dc0ba9dae4615fbbe1067754947825bddc2f5fb7c85762c30768a932aa1cc73047bc156067c6093e4e0caa0be72fe29afe838801a975e5b148fa51dfea29bfcf1c9fe7416d00a6fe12ffc83d68881a82e7be08f2e1d3043c2f2df3f23498942e086c41b12b6030213d3b92aa6e7ec4fb7d26ae2ec2c09ab22164bcae8eb4f2be76ca973858c0a025c61a303f85bf3c736baedfc16a7c4373c04479f34bb544543b1215ced247916b8e8381572f3307a4e74b1049497bdecad8b8d1538a0dbf9f694dc80d5cbe5bc015021f51c71ce9922a532c50e0be43a3dd0ecca9a26cdc7c2e2f6aefcd0d2086a3a8d05b95176ec401623630448e68497c2814c9151bef55935454cae84a0c7d06eec7fff2879c77aa6a734660d883fd330321bf2412421c2cce789ff9ff5faab39d39bfaf157f780cb560abaeed002487c61ad6c8c3914c27eb4c33aa16eef4c6891d0864d4c08a2e72412b2b52ab8fe1164244ed6aa462adc510e97fb258e43efe71979b200bf0e4ceddefcacb08f4e3aa2d7957c6b7b7581fd05d27a56735be724953947dc0bf5c29c117cf4cb9bf74ca8a81798f928bf750f6f8ea309deca5add751d79f2e97694c2e464881c309d31d12ccfd53f42a1bf19b9b049126ea0e040a2bcd532e76c301606df779717708b75125c5c0644d8c381fd87d1cc28091e3b5ceb82675ac82b755058dd5210f78cbdaacd8312fe316ac4114e42eb7f20d0145402b99c7def6907d1c74fd968740ccef398718db3b2be687f53f721fd350f40e7d50a423d90ba51efdc544c82191590089c7d66d4ca10add18b41ab9615bf7b3a18ccacde3280e6490cb6062246b436227fee81cc82a031583135aa1e4102df5545281b1cf2a028275563abd5326a9a1cb47a34dd200cb1b814d127075c1815a3de280ca6a5502dc76fa9f7f935fa50f5afc567783db61ebaaedb162dc9af07065bc0f393fb1ef03a6233c5074d6b0716dda86c408b653c71623fbd59fcf63b730bf18e1e49c7b908aea300e5e111d7a7962aa3c123b46aa8033f69caaa41c2bea4ff09cdf5a3691a407a9fe36a1f230115cc79de3d4cce5d61168ca3a93fd2dfe5c2f139fc1c4856df6dfa2cc13c492ef7420e164306ade9673ca07b9d952be094d1800643cd3cc490f12124e8c93768da91c6689d9c6fddd9fd35f54212d16caa01a24258ae7e51acd0b96a3873aece050a402d897f4287640a6bcb5c7647b870e6c2dbd4150f1260d34dc24104952efc8b6f2bbfb2555362074e67942c718257d3bc088b44d628379274b92665832d3d6d4f077172cf8a3848ef35d4dc888ca7e790ed9c3c71fbb3f37474414e63fc96e628bc2fc928eab55c2f210e178c5017825614c3ae984cf645a06dbd2ff550ac1f95aa7290deeb1a340a1cdcd704abe9fd89f266a794831dc444391b3a6e4ed0ce54f6b3405e13509f52a72d03fb140f6fda24995caf0f6b327caa2c16bfc31383419deac321024c428ca26a7f381c956347b16a4f40bcb45bd5a98be1f394104ffe0e058486764df7a59c335cc05b86ae4330665ee289c4c32b829b6621d173c2552a304be0167b59010291daf849fd38634aa9531fa966e0eaea9031c2a5ee80bf26292e9a4a107885d1a39a3bf35224a9e69844df83a39a22ce1dcd9ade97e085c61e72d362bde6f84d2b222619ce314d193a0b5486734c136c0512209873f508f16aef11cab4509ef0aae657a86ee4377952b436425fae087cd7f2f2e1f3eeef00ce983bf85b72cd618af0f3eb413638179556f62f80c6e26a08948b7587ace8ea193edcfc8c21083eb6f772d3e2a2e1f167f7199c6367ec8252600e0ca088f9a7b7663c0dfdc0b11fea5e673e23cddba65ae523195ee728e54616d9c52d3e3fbbb8c4822c27ae30ff7c568d247ac58cd304a012f3e35c60784b6213e7a299b1b40d41f0f8b1996af714ad3911bcdf36eab49149275ba8d27400007302ef59ddeee795f7858482af5907e66c5523de26bb93b1ce08e30a453e5445dba8f5ae0b5135f3cb643013fc7ac27c5681674ed6d512bb1b890aceab35c14d298181c034dd69de59205e7b09ff009b4d81e5b61ed8a2fab54ec6c6285b90227d66b91f04bf9bba04d6a4f5252e7717b8c7010c49a2868587d6446913db0ef2bc8c17be2993d05e871d67104b4e16d425d2a749c6968958959c06222dc28dc6c1d8c92236bfc041aed2ada3986481a034995f4864ff14bf4d46c8e58190d0faf72ef2c42e615077f4d0562c042e4cea97ab5af84afd7815b42899d123b2bcf4ec476eee5c2cae71f8689f8c49c7b8edf616175fdef2d6c1d8623dc9541d993e6349e7f6cf8769d6aa6260b818b0bb48de99487c6ecab60986db520feadd4cd54d006ef17bb0a5266b7e5df5b902dde5cb130e8559ff7d0a6323ab59fcb5ace6d6cc0b611988613f7eb26b6888c015f3febd1f6b6265224af1de4499e8428fab6790d4d57468c5ecfce6a263414798aa6111a3ac1de5743fd8ddeedd4ed2cdf256ec300edfcc610c95e4e7db83ee980cc143d38b72eda3985d8177c343368b9ca395ad9cfa184eac6f751c7753e1f1aeecfdaef2bb9cc656376c6f0d430d943bbd830e48e5411b34e6b1ab6cad9dcb91b61e52007bae45630a935000d944b142d10c060bfdaea7aadfc730853de0fa1179a6f887d7b4c1de19886c075abf752dd22e9a5c49b9a37b087ec5141c845f1227d97f40b70554e700f355917662046d950b990454d435a2647b650fa2b7aa3f45807e1ec8e0ae1a3decbc98ddd5e01d4ad9175bf8f4c23ff986307b12b803c460a2f276541d5d98c548daf187efa11d675d89f4cf37fa87e9ddec228c1c19db425c46276b5fe6af80bac64f9624a0963365fba8098c7bbf2b23079d6986fd4bf35c90705af3fabb7b2081beb612624d94b6fd4246b093989b910f5b855b22ff65635de9a33d9c8cc449dc584ca1fa8b16036cd5389a259b966bc3bb19f193e56e4c4073cdbe7bdc386d68e4b572e4cf88a7d9759f1b38cde276c12b002bc6eee106c75fde0d34891ac844c80866d47f192af11759fcfb6c4fc901a1239cc8561ca25df6ae2c1d880cef1822584af380c98b3cb6567dcf8196295625d07fd59af862a45da73f20483a19da877d3b27768f1f527476e2594a041052df198e4d84493366846d5f2c1bd8e13732541532dc3bfe576c54582af41200cbbd82ba9cdda17e819f6300d2ce010685e7bba2d807116a73cb451cc2e4dc937721525f6a0bd5d1cea9e5e6d9091b48ba4051e861403275e94cae0c8760c0d69f3ea64efc73696176af1754195fbe5b87f1b32a814eb3d34c40657ec492a9bf2c48746b3fd045ebb4c464e0c20b5c11f740d082470dabc140f9143b6d0820d98fa1ad8ed39a4fddff7773e1cc575617e52c0b118c0c72fd874243ddd3842fdec0a52de86344e48a8bb6112eb4b500ec057817dda916d0d68ec83382ea941e558bb827de2c2af4a242c6ce73e4088657d844ab76760a0969244c6f7c7dd727ea9ac1284af9ffa00b6965c094fef0ff0695656e087b643c112cf6bfa08e86e9f71944da6fe37c4f6c3cf6ace9fb73cd9649abbddf644f8fc0edf489647c5d7bda3067b5724f618bd46df115cfbfa9fcac3f09b91bbc0a2609c565620bca657e16f2369970199ba0134480ddcea277a906dff96e0868a08d36dfb473b19887f1779f1412221074a5443cddc1fd026b65260cffcaec23c5a0704732c1f269b179bc3db5a13e05172764c786dce5815f063bbfced5fe6d93a803d687ac346c53f87c31520213f49ceda8d8ccdcaba3043ac826758bb410ffdbef03409c5ceb41a4556c65a23bcd258d61a7a18bdbc1055a8b097656be46969d64303c60403e446c4419ef04055fe6dfd487096532094661308e344c0ab776b88f56f9721fba1a2c95faccc6b706dcaff1dde50952208d797cd75207f7555243c835e98b1a84509a1eddde40aaafbcee7e4427041ec5fe0b94c4d6146eaca10d909fc0fa0b6e7d9e5d47610028506e2a3f38c4abedb4250c1c21a169a39871d7aa65daa2960aa052b630a9bcec17f3f0b3a97e971921d57d4d94fd02b834c64750ea2fa5e4501344de9ca20a7f133e466e90dbbae6ee01850a8399017412e49b5608c9f7eea97b6bff1952296ab417673cc601281d380398af427bb4faa18beb1fc4cbd3d6acb3a90828c95e2fe765ec4b67481ca2141d121b97dc0ec10dba69f80b3654381fcb78db2debe07ead2330af56289bb18625b04cb66a733ea75f46834a478e6f82f04fa4fb5aa608871ab4baa9d101ed115f895ac236d20d3673ec6390b5612335c4b4f00fa9d5a1d78c25d4b4f472e06f746f3c8ccde2e8ae2be9d4361b5d8d3b5c45f15b27f74273ba252bdf2306b47e6175bbadf580b7d817de25a170c0e5165035ecb1577a8f486a4e199ed1086069bac221abd0a40d459412e9e47e441b305a90281bfdb1c5c7db4841c8f07c22c429641176087c36422936a86dfd8c52033ad78b4e225bcc2154cdcb6f2b6482eb9423408f392f154123bceea525aa1683a8e602fdf7aae60c5b5024ca426378c811acbf77747cbc53b1458eb17141faf9a7ebcf2e2f2fff41f4ad9fdaceb8c0933933eed90b9b2cabb58a4be16e559a734a80600a136a81b961a82b4ff36d49d12d4aa2393f254dc3427588f8f870f06d38f20bda26d33ecb2463694b89cac4b003cadeae13fa79569201f37b4686be76e708e5d8c3488f2892a5d8606b9d5117f0978f3e4e31a01a9500640804eeb2a3513a76c28f00321d5e6d1a3fd3cec9dff2a29a7772bd9a75f6041f5ad0e91d8704c3eb14a29a124cae029ed7e81a644a71adf61419f8e5b2f26d11a3632f3aae938df70bce6c00d6429f5978a52687e0b05bdf6ce010338c1ae439c6e05a31c94d9343818b8d38db8fea5d026e03999aba91612f978aa0f1c952ade0a4540830308cb5235c586bc790b09a60153532d89ff957b387bc59ad51ac8520ec0f49b396c606a6973249b1d92ac3614c5a7e6024d41a24c217fd324c4a8ad39e65f3e69c657917a79632b4cf28338269e1a307d9ced4a23e5b22dc3cfbbbcbc426ab07a02a68067ad6578b0d82e26432ee05619ea4ab50fbf6ea6fb31aeb5526024c685eb9003103b85b0a10f9c60946d4452d72d402aec2db7102c8c61687e35a3d5e8d3116830e388c40acf9eb008fd5ab24d545365eba744969dc9f248e509bcfa2a1c26a74e1004590cd59dea47c052f2cf70387af770d26d0d451464d05aecd5e608928db180fe8d549f64aedb9a408bbafc48f003218908d06368195f73f1b467647c5bfe275c299691648f41e254f71381b317536b6a3796320c42f81d35dfe2527efc50bcb6b3782f256ef68c92805da54ef7c6311fcba028e4c49df01196a15c0a567a8772444582d4ca3d86128738d0258410dae6632cd33b7ea849ceed60890ec60ac1d286339a6889866fd59702588e3bd5ce89152a103901052f4c248c3f3750985d34e2f2421ca3fbbda523b5635b86b952a1a7666863795a1094bfa80102673cfc34f9a356452bba7ff2f9a2092831a2445d00aa84914b9fa080a5bf9e96fa72ab0382c259bc0214a62aee9e3ba955c82ac00da810b28d2083534bac5f14b57963e89322507964c6cc0f4c5afe5872dab68a83c76ce3b1f119c0c03be558fac44cb9c1d3a79b32a4673877907033c7588505cad9dba0b4b5851dc4c14d47320e956929e95ac433cb9520926c98f5ce9e0342efe60f538c154e4a2dc1557224c3b7040a4785aeeb37fb29b54178b8a778acf818dd9b82c9c2a3296f6fed785785abc13f08aec18724f33705870ea72586c9eff24262f898cfa74a14bcffde26eab87eccadaf5da356629dc30deb9b6efd131915ff4d9ee62818074e682f4a964ae8877cbaf8ffab12a8dc5ed10865e208aa33ec9f6b8ec239e2a06c79907145072b52efc5188a3f4dfbd3e122ee9668c4ad10264534dc52e905eb13e1ab89f2092e18b4d1cd2d8a7a48a5259a61cb9dba30512a675adaa486eb9dd173495089cc7d3ee544f36b0ff051ea74f08de11bc30c41a8783893f4c84d988f4fb13f65aa48e1b1377b8a7967c45c1e881ec782bf394f01b310deebdb829b9848648161444078f38cecf64b3e730cbe0fe0c92922969f738543e05728fbc8f7df47af0f06d6e4009a9383e6346685ac4ec8afa45bc0673deb9d5ceefab816c862910167ae2269eb8198b9a5d12d9c6c2533429fff1dc0197761c4b9db3c8e0f547d8cecae6b4257d670a45e949c1c388f83fcb6489a61882249976634596b824519bce0dfe5515e52eb08259aead997542bd184b3dbb296a111e3975992a6ace7216c01bcc2fbb32b4fcc9bfd062bd5117f2d166a5ed22c7bd254ecee5473be417bc1e1f34a442ec8e42a6ab951842e2f4e080204a267cb8818a43978aa99b34ab4fe0c76f640295a000db5dcfac7c25c67afb2e0a8f5d9206740baa26e7536bf9db587e4552cbfb5ce3d1bbe70b58f7bbcfe3dbb6cfed23e98d4ef04572bceb3619da5b9e437c60032aa7d003607541415113af0c38d9278906c4bc1280412aa9fc9a95531835ddee53ab438e31ac14cd59c82fa689c3d13e6cf6f181af2329eb5d933063bea4d3cd57da6607f89c061717083654cfa7337fcc8d782bda54fb852bf3608649e5147fa4a245de4ddb9ab44f8c6c069355594f22a86912a028d35091007441edb088e10591cc53ddfb80e092679d7da6ef723b9225dfcc29aad154e6a16a7a1625ed7c8b852ec183f9758408841af36765ccaa11310fbc73533fd70dd367bbb2ba8818ab50caa516b0353d7f0af7d8562707709c57bed7bdf2072cf92c6837674a753906ddb1de177a669c7b1bcdc7e58b202500b3097262a2e84d9927171a8820c0e7c7b031969b5ba4e0755c0579b604ef4bd26a7bd269464ea7126f19638679a53e3e355d88d84334b3763312a377d341570379b8594c9fd37d057f775bcbecede22a3a035e82ef3423a859d72439f7fed32a31ec734568bc3d6749591b4555135c910c5b6f8720f8908e9c0c4419c3ba50a549ab574bda45f1d9ad3b00c0553f6ab58d88e802e0aa0b3733802a8172422d1beac485ab8e48eb0d704c32a1ba20da255fa4fbd2886cc3a72bc76cb05f3cde62cb585c8fe83a42ce97dfa877b1def08fe7a3fc98f327f6f0e3a659f94433919940e869f7101511233e09cc55e6d775d531344f6491ae6dc353925c4e52428e5ac138b292f5b711892784d2c253db39cff1fe552f09191e0a63ba697cd120928cf5061646420f27909b49612b4605cf2cc29fa121822441176106d00c064511b9a7c19ecc678719144d0b2f757600f6495a9a5cd2a0eb213e15e395c65b89eae1de7039870f6ce612cdf5bbc5c9526b15bea055a1ff001b573c694d6245e66b798ecf962d69c54ce753b4acbc54ec687538fb2f23aa076565f7878f0e7784f8b0eeac85db77792e37a8e51752f8c9bb37ec85dbe187d05f1d423232e7a02b2cf3c65a582753a9f2edc284668a785974c458a0e18191a9445cb8f2c60eed9f1a084a59baa376250957fd3ea31bd460cedf70b8346fe733b174b74514fb8cdde059e4e29534df3767f51795301e1df2bb855af580074accd847665c4e278a38f52d40afc7d1b1237637bc58c354769f482a79508d952c9120d10f5ed57edf64abe7d5e5d062868014e8bb43a216c3f67d9727a53b0b66c657253ee64c57b6d2c078280a40c15f614f0b1867f1bc5d3708159d5c2115d3cfb28788da8b18a31d75951e98531218af0c96188ca66c9dd3c2a176cb2710eb936565f6d41ac445071dd310bc3da710706675590f0e9d65001b44d31df70c3f218c969c21a34146eca73492518e0f3e41a9e5261553ce8f27540ca0ddf1fd782f8010bf58772137e1a9c43ef55183adc183d6072db31e57f25b0b7c0224549b75c33efe01afb4aced72ae4363282181d395af626cced19e217f362e0b812db8ef2643c198ee335f93869ca7c194c9ae4c4335657368a3c993de24467eeab7f5e62f1c7d30f54a188cb0735445c3c0483341b23da57e6b0a842b0eb34273636aca41adc7ac9f5b278589e6f4133d58c2e2c23e3be43a6b62e8c93aaff6cc7c224f0f11b4fbc5e150e4e7247c5e45e159cdcee13513d9612d897514cb6c031cb38c313d1178dd638507dbb4d9fe7b5b4a59933e640279b0d709d05a615297344d967c7ffce35bf2b7137ab5369f5123a66ef58bb22bafd62620bec56aa57c743ab5f2e4664dbab031e3ae221f0ad11330d78d9c3b0e9b96d04dcbac8d5cf4be1891b6af41392b0f48356a05e9300f52b264a1c8b0b983fa56e3682520bd83b4eda5c04a4040a31e51965e12e8f02726b9709fa949f5965501dad43bc88ea3e01bdf3ba9062ad5bb5cd2f0762aed759086902b6663cca361e6ea6a1d9c97b1a3d48a8d0f71b347ee0376750df7e9b9b7144979dd2b2be94bd23ed389c82fffa439cdf37d5b383541f57bdadb532207a22f43f586b199d6d93b31ee3b97227e746f4cb064cfdb595705610883342710dafcde08e694ba32bfc0724fe2322cdf558313164819f54c7956a7ffd522363dbe86e910ff85d591da66e46e6cb11f15c12c46d9072db79935671317c87ad78c206b06287de639dd0b31d4dec1bcdd89d33dc2642b7dd29d8bc2c87732902dbac706a6f73658d9964dd7ad5dc65a8e7ecdd1e752b6486db44a6627e8a1093088074db20843929ddfecc1d0d9d9cda92d8e5e4b54df2b992c38d93bd46e46de870410ec065ccd649b0ecc00752b9c22f1931b3f4690fc46083dbf668df0dae261ba92136b1446d42eaea1e0849554a27e1b3356deaa4274188a63510faf2cbca5b8dd8e5b1989d84b08f9fb75d6b09ae06b05053ebabba7bb285cd0da881073225e125d1671b5b918e0d5f636d1beb7f6830cfd043e28eca17426ea1cc0c33d9bd9d51f9e5d241f2b2fe06ecc76849345552739bf3dc6f16743560e2a1cf85d86974b41bac75ed27b1256636d670834996dfee7c918d5a1db1aa9ae7cdc1328a71aa8fd0d3a7d38576d7543c9fbf91cded31cc71acf7a2738c64de69367498247c3021a90fb4e4deddad0859695989f815422fb6e7d4c5e7417b317bd4939595b881c4fc2305951dea124d73497563d3437e0278b897de3ecec1b0ca7313e72556b7cea888df4f47cc6edb07bd021ddbfd204a6fef637c758b79122b10ead02319e3d79c854836197432da46fd0eec9340980d8f567a805218df2b54aa7a562a9db2f7745f7c6fe805f8eb69c5d22b8666f2bf12d1be9ec696229e82564b8237f4caa1f7021b8d9e3c0cee658ccaefce6e50df8a52828c4567fb04aeb17a6066eefab3c26229d46e4ac68a5082e243b8ae5abb71eb92c2ea24e283257cffa4da63bb98f6c7dd1a5c751513c702a11ddf13ca3df7b41f07e28c5245b2f10d826f3a3d5f164eec9fa7bed77ffaa48539791a3ec46a9d7243ef5778066a628615c5fe18cc7511fb5ae73009a61045ff9bac3f2540a15c2ce6c86b606dc0ef8e8bf1715bd94ebb898b9ad8bc46aa3601c3be38dd9861838c2dd396fac481833948e9e11ccfe7ecb0ab9506c0f670069cc26a9a3c2a1711f72c890488b325dac6cd488df3f1ed73c124d7482c3d6b591bda0bc22e1f1881ce7e428ea9c01452e74ff949eadd11afeedf2f3b8cb6b51d71ebe3ab8fbcf4962cef8f3b55cd30f59d47a6ecc5033222bd3c2cf06780eaf53c4fe0405b7a7bf0c9f5ee79934c859bcadaae5b47709fee355c6a8945417d2d05f0472685304d9c8b3df98631b939965a86c7e1b5b26c4e3e066523a91ba1e1859be6f82797a8b4ff04fee13551c55524ef6777ba8db84d3c7b5c0bf75701dd5f6308404a8a07d28994b8d20a62958bf774b83cba460736d0443253f13eaf4edd547e0c47b20ae213797f06207899b1dbcab76bbec102073383c39e099615c444b3fbe3c7001b59ee504b33dbb2de4623c90b99d16f84c4f129828f8d2f2703e047ff3da1af2069c20ff9edbd6371f9baa0bef72c860a9a8f6bcd984fb13e134231898e8e6a6545245fee7dbb7cc7b34568a003bb1d43a00e2762acf1ba194ffada5a31a3386463012ba98849c05a6c2ff02637b50bbfde36f2c8c214e2b29a89a8922ea039cc60ff03b87d70a0badffd0061ffd1b71230b6f4e5538db6f97018dc371ec8238ebf4cb25ea9aa38f3a1da2cda8dd090e0f353d0773f8819150a49834c561a514832f0c4640e1a576006e3b9994ed123342a479fc22ac31b68ff270590212e30d06b528fa6aff610e283ac442bfb6d43073e98ad22dee32ba421860a09e8f0b8329d4a143b04eae8ae94572018564d07fa55238569078969d54cf5cb956ff35fc8b9c5b564e27f825af35de81fc0b07094e810efc5ab07d28cf2f5a1afbd80c17c7b2e6d475179f9de2591d9502cf82c962bef9411181a59acb5dd6dcbbdb74c29a5490911090d0993b2fc0cd3c84bd1ca5c9ee57fbcd0d54695a47e652f3f5fa7b50eca522b356b86ef5b7e0367303dea353002a647417901256864fef728d008939e4957da7f7fa22b8dae381a0116d37b6fa22b8df2d8e0c1ec25a524ccefc3fed1a4b4522f292915292d152941e9a55fb16a8d66b5d2942a4a4b4253a477ffec60223e02c13882da8492e7c3b5a98b696464a494f42449a594f4847ba86c94e4b0af5bdd9a524593208d552d8ea7bc55b5244646566470367a01cae4dcfb1ed3f774ff9d7c53a53e55135f171bf753fd63424242422e0483ee2acdf2188322927e2db5fc8f04c5190ca6ff6eef1cf71b8db318146741fde2a84bc90979ab7beebd0e8c41cd9a35eb489cc5593cb23cb86dd631688b3fcd72afd2ac1947a08db36df94b29b44cc359e38c082d7c31fdf748b3fca7591e756c3043aff2d3af3002557fef8fb366b9185eccd07ffcc7617126636cc16c2aab442a5a0d5da8af70a1388b41314914cac2199cb3bd6f9192ce11b4a8831beee7c3c2b2fc909d701395a65f11475b2529b9df9e7e0c27ee2568921c2b4d21c6274f80c4620de4c993053223ea9d955444985c84bc8537e7dc5e47bf76541d3f79c2465e1ee68da45ee663b38cc0fccb1b91f9d4cbc37c4fea657e5f1ee66778791815ccc7a45e4616034355e1077c6acbbbbccb7b3ebf9b2def691dd812c3a9c7e93bfacd7259c5c0f29d4bd77d0c5b3b3a0123b8b4d090270bea44570ed161e2e0533a500108581b1d3bdef2582c0a53a337506accee90e0f594224588908874a346234ed3963e17f24b98b1235b71c444cd8a21ff082d4e6c212da64685842ccef6f139b030664268a50831b130ae824868c68d32d1d6c487e18a19ae9426444d84c8cd51309071a36c05142cb4c50c9988ad581c260a9a5b7fe3f38f941ea8e32d9e98b404291f0df16d8098dc48b33f0ec923d206330aed87634b4b4b4b5bc34b8bd3df42cc96664b356ac84b4b528ca8cc668be3aa5e7b8684830a43b35511ec5284efbdd94a5bf3518f8ad14590524707ddb3214cee48d06c0593e3244f478be9fdf7212f2d2df9077690d4fa286c26aa7f0b6dcd13ffd9d1ec0806ab252647bf66152d1135ab6753aae6ab583f9b813acdbad17e502a38c2005118200a0ee2274f8000d91a8f271e4b63cd5a4101b238a886c97720fd1ad2467cb6c68b00591cd49a9efb0671d0a15bfe9ec97bf93398e49b3caa7213d73eccd65ea7794c3171d00104fb42c0b2fcc10edc898c63093138e2080328f16fbcf5e0befba9841939ba1ceb57a76371341ab7c65f4764ca71dc33c7711cc771cce9ec881e63748fee1e9d88230c10a454a423e59c2ad53f8ba507c53e6a2747db4e5ca7b5cf6b2350403424733591715af5ef21e6d6ee4ddfd1557ff74d79bc377daf9a32bf6828d5fb49f54602c35e82802a33eca33e6a4f478bd9e2a28c656ca48509866461ffd4991bc8a674d0d1d1e2b42aefd025256f3594b97dd8473cc5c4d2636cde50ae1ba4a32ce6ced6f8efd0b1475e142495514b8d5f437f8cdc4b6e084ea4907ea0a4aa3175b498f181bcef5e8240a697efc51b0ed4e181bf37e277601052d6bd099cc5641d0563ecb135f16752cf44aaad708401a8503aa285338c60c20b24a446ea21cd356f248f48dd410efb81c443fbba2e8132bb1a36927f4fb31ca92a2d212525a1a11c1a2a8a485b23f5775bbb6f284da36c458acc13413dcd6a169785c0ec13fb1e6d38a07e6b3179df694a66217d0275c4c01b22fc2def239bb4e57be6b7b8fca42c3fe9f3b77d38abc61b826df95751a2cbc2f23a5ab0b0fc747996f92c2e39ccaab3353c321670653e64ebf22b9be165be0b9dc1e55ffe851a99ef42dfc79cfcb29d9d214c8dded4883951a3dba27f544e9c38595282c24a75abe69aa6d1d048d59efb1483564376e25b8d4e9a81a834fd5a699466259be59fe42aacc44bac2255a31fb989d44fbc42697989a548696f5efa56ab4070575a1ab26285ad100d790fd526da568c8d5ac9c2c23a8a1e622b435678d88ab7aaa9720f7537f8a347c5c54f0d555cfcd4ed63f5099aba0dfc8afaa8879aa8fb8eae66f8154ff7ebad55cfb788810427ce00faf99175b4089350c98c65dd03000b2159478dbcb7fcbb1e0200164232ef4d1f4e303c6a726f2b50241dc2f1b7cb11151aa91be5d99a9a33a616919a189239883b4f9e00890199b1e030c340a849b37828a6b3e38387838275002af2b356662fce3910878d9bf87047bdef28ff3c01528185b110b327339e99fee3ef4d6fc4fbee5711f8ba377ddf77db394286a2b6125b23f3e4b70d7bb24f80c4138f06f2645b71dfd775ff51fef1567be0ca767cc47a9819ecd1686c891a5b9bb8f0c0096c4d911f220a186386aeea355441d2b0edaec13db00f8bb31c0dbf2a5562373e4c38ebbd8b860656031428cfaad1356860612180c244b6c6bd3722df7b55b38c98be7b23decb57756f2a22dfa34578093488e2c40aa6ce0e1f3cae184f60719a01a85ac3426147319dc0d66891099a29720aa1f8b359cf869634144b584bfac55070cf7a36c6d6f8f7ac972c599c1a8be335e917d146a559eefdf258bee9377025c3f6de7b5b57a6f7a9261d2da6ffcc7ac6ceceeeb3da4b5c9266c84b5b2fe996ffd2d2e2543139863206cd0c6b4613eab62125a5ad7125d373e553bfc7b589884eabed4fef23dbbec8e93f1ad48342519fb9bb134f5af1cb4ca07ff14ee4317531b6c65fd290a99c86f850b358dec4a57295c5611b2cce149cc3bd0fe11a3e12d8c69fc1df1ae7236c8d3f539949bd93d450b452b4f546f98bf83951cc90bf78b27decf7daab2117797c014a51d1e2a0166085d9af6a500828b0a28546568cdabf15bd00e5c88c553ef73f24fdb1de6aa9ce5035a104e42d4dc8452626e296a3aa7b0fd68be52b22c771dd640ad7ceec44324e10d560c316ee14efc4bd9f780cd99e33ad4ca62e0a2477f730a8547777f73675ccccfcb58666b91055b3b478e49b4223451e0b1340cd02e1e60ba6a1a1061d4d262751d5fb68f8d1ac06816c527f566aafa77ddb27995d4f3c4cdf5dbd1c24f3fb0f0c53deb2afa3beade9dfeff9f4dfcff6de49caa424076c34987e00e9a84eac595cec95502de19346ec7ded46d2e583f71d3b5eb862723bdadd6656d70dd0ef8ded39106816936d14dc161050102ed9ee8dd02647d8aafe3a16a7b759ad511d5be36f34232f9122427c2d06fe3670c7d6cce21f49a499446977e2c1ae130f66b96dcf9d786cdb8907db1079c7e2b4941dcb5bd186590c6c61c7d6c4aed69431b748fba8452d6a45bb928692a352aa543cdb56fca805ddaf728931b5f86134751169b57fde166c0c31f97763de92287d1122448af08f91d37b46beefa51de799c358a75f92b12217d1906b9774b458f17ce1efeeeeeeae0d2b634939a74af5bf446866669424099cb8b6057de556fc1f5322d4443dea13ba56db9b561b95ef99c0d5f6dff6db468b98be4868436510079a6675200f7bdaacda8a1f69c5bf490d549afdd674d0bf644d8a71d0d674a4374c3622ef6dce6f9af50ec66e629cb7129389ca1b24a67ffc7d0e0cc25cf731f87734d4c12be7abc464a237373753e686c38c1b3feb75bfd6bdbd473b1f68c314163d62d12c9d39da0f67aa7f642f52d55deef939d5fb3303b13929b6f157c9b04c97df599c99da55d3661fb2ea56a9301ff28f0bef12caea12ceeaa2727917c01930b65e68285d5cded2be411d5ba37d0b28e39aab744c3077e8786286aba3eeb8ba6ea8bad3c2d3786f69df02b8c918887f645840ac8dbf3309faa3d424694d1993a333786979647a2e7edc623c746851e3fa61fcaecaaec6fac5a604cc5ee625c07b36d155b71addb1fd72ccbbbbbbccccec03cd81fc581b9ad529246618abdaaff88178ac63ec0907a9e8540094c9fbcdfab56240d7fdd027523e622726589ca50c84ad218273980bb661227e1b48a653a57803cf7dd09db8d32fed9b3382faef8d30e941f507808a2fcee27415f5fdeb33a77349e6c4dcba32145df19cfefbfd69a29ce7799e4783b04b902b03bc37bd04b972bfda7ba14fe5368e934de639b548bf18461c323517448c1e658c3146f931ca788af251ffbd07aea47bf74254adb4e23c507e1feac4f2a8ff6c60097956dccf80a29f0f91cb1cd63b08780d7d6a0e5e25ed80aa863654d093d473f09b153d468ff1fbe53488fcce412985d810720ccb36a65f55107feeb977291d0c55cb36fe72d9669bd537dd8a1fe3c78f8f030a5e87e4486a9c2f98e126f120491224c6e43a3defa3214dfd7ecef024294fb3ac70c14993aeebba8652f953fdea14cc2b356c65fc5e04e7700c7f0c98029154d4ebb40efd42bd783132df2998972f1303bec36068b74481486a880ab28f7acfbf17d09f4f2cefb1cb7b2e2e2e2eef53437ed4cf6ff1a90b1a11aaac835627f522d806f53ace82fa667dfffd995e7b0f1c126b381769a180daf4e6b9d9624a2a562451dae4eee006c2b407fca16486fb45f5d7ac2f6ee6e68fdba9d1a62b3dcff49e27e97bdff4a5aa41fae5cbef972f3fbe17411824c2f7aeca20bdbcfb3168bfaadad1b07f07aeabd3f257c957a7c35c27579d3f7538fa451c674ccd33ad121784c7cd4d554b6716b34851738cb9608637d52b3355e2bd4757fcf57fb35c7ebfa4a11055e53ebec781af82c2e47e0602fd9c0e2f549d1860fa659b7d1398835fb952a51015a7e4f42a879de80ddbb46c686e1a0e28cc6d6e59352d3c1f5dc3c54a1931c33df278c7b4dfc1543b683548f7df2fb8835655ddb7801df79d0a0ce2fdd7f21e8d0f650bdfefae5aa001aeb760f6531f0306d94fbd27f31d231313f3316c8da1f3431db42a43c3fd1db8c63c4b0a44c580a86f01c3af2d3f659d3354d5f9ac96ef96140d676df917ba2ddeb780de4f904fbf27d469dffb408feef8e0017b7e00d9251b227e9822d3ddcc63d8babd1f3971a3973e95034065f27073730f590e048f8eaac816dcfa2c57ac888b7e84a44d295aee7fa8bc25c4f25e6f5a64fa43cef95155474dadb434a58a49d54b7e6c520efeae686b8d8a241c50d6b5c5f2bb16e36fee1b75393b7f6467e7d57899b58d34aeb81f5da056f9635cad4ebb2a9229518b7477777777cde0f6398dbaefba8edd1b1debbab9315215e166d67c848754184770d7e2a4dc592e4735d77cdddd571b82b34bc7eeeeeeeeeeee6a404042c25c1a6ec6706ddb6dae168744a761aa2e15a2aa38ce6816444d8ba9d4862b0d6c6d4da4b2c492ac9dedc291f94525263f043cbee1647e11c73bc093d0edd6742d404249696347ae5d17ebb812904bd0ac61695b27263303978ea5bbbbbb3a7476b8bbfbe60314ae9ba4a78991a67a8cf1638cc1d3c8d0e0a607252abcf8a93a626e00063ab81951305a23be99a1492dccf5f1a5c346d19166f4216e6c61b12df221ce2913c98a67fb01d4980561b86f19478bf0006af54688cdf02dde6cb7941d28a9a10a6614e10a71ee608afd82676b78fb1e2da78c9c2a2968c25b1a568011532ae1015309031cac3afd38c6703253d9a5850b82704105ffd6dc0c8183b66d0ab8c18cbe3726a0e2abb9c643c9905885a8aaffa41207195168d68d2be68a69ac6dcc75e372ddc45c31772188b9cfcf4dc3e9428000ac4000025ed024a5d269275430bf206d0487700d573cdbe7a85a5dc5aa5673d41b244bd1e7ee461007737f079ec7c2271e2c30986086128623338c63c030c40c250c258041081866b131661849304309431031284000cd30fee0430f30fcc49610bb123b23968598951816625788592156256646ac8c58156254a83043398526cc304a21c684d89458146250882921f6849894181951624e98a1bc39f188ccdf64e77ebfc98123478e1c07b8e1b2b15153c300390ad06211600002a0c911000ae6f81772a8646260523972787302beab4d43239535963ad81c4f981cb5d5e2af0ba1edd220cc6528cc80363b989c52f1e0d97eb9a836aa4e83528bb940f038a582f9c5a5b919d826a8b85c37cb6d7477773752a10d8185629527e62d33263f8d8e984e4cc73da6e3ecaad1356a2c165b72edb535ac4b49877574474bda298e757deaf0bb4b676773de7c73cd9db96352ca2ddaa21063e48f1c9963e418636466ce821243380942be7c2edde10a5d747d759e309d7ed17546e4333a2abdc5edf4f0fcf0cdfd7ff0f420f1f4fce0f9e1030724a4f83c8fb448fc53461939f0bd79c2e46f245e386bcb0f63b095b9e4335339a56f344cf949f94d3919082808498c31c6e8302957ca8d0a25ddaf4cfadae041ebd8d9e1c3c7fa30dab1e363870f9d98d18e7ef980b2b3c34865a4325aa3227cc082e5b0dd90f56f2305373d147113589297a50d1bc81d3c3e7ad649cfff7f8f0f76e283a7c747cf8e0e0efd6a293a48f1e1e4df8976c4fd87c9ef3412c186121c5c6c8cdbead76ab491c5f4671e19bff8b1582cd627a36fac71fcb8c7474c92deee1f234b13232a6d4adcb88026da2862c6779a57ecc10a2ba0c2c60473ff071c552633c0004744a1b4d42db9b7a4f4abbf593e4855350d4ad84242dcff38fdb7d250e04a5b6dab2db1f6018bcaa34ccbcf6479af4fb55fc775246b37c76aa140b3988ce58390b20ff59302c50f42ca58bebf4d3494df35fac6bdd7696e6dab73843760b571781efd28138bc93c1c9cd1691cf4c7bade82c02923cc8f4a0c1145255e49d33f7c21a1259cc352e3f3139ce3aef7a9517e441cc672677b8deec075d563dbe88afbaddbd7f83efab59acd8aa966451ecef19faa9966c517520d11092d89ff9ca37d7cba38b2002c6c01db8aaf52bdbcd4f0abe7e9b04d7c1b38101af2f84ce4424b8482f00212932bcbd788afb99ed53199bafc3d68630a734a2bfeaefe58ffb3fcc767eda9e21c2ff6c7bf45e6dd969999b5cd81aba6451a75ff5953e55ebc80c48cbfcee29c53f5afa1d33a382b0a5373075fea6a77e01a9bb5aa3555b862cf72997a57ecfd59bcb3699d248910e74417308c7fb8d5a4a578a2c6671faca8911a45258492fca49e309224b29824c94eb84f960935fe326ce3167fb848903df4d6834eb37af46baf759224499224998bb3712fc40492193d9872c552154a5124c50069f6d3ace82da9107be80d3f2d16718e56e333160cd3e1567c980b1f67102afb60f5213f6961e6439652e3cbf8a30b9448cf502d52a73c537d7c3ec239343e3e13b1381f8879993f81f6a80fe5f62c1f320ab89f1f9ae4b77cc829e8dee5c3cfa402ef531fa23ef03dcc877c84731165a270abc4e78161bb453887068d4fa45f2abacd42559515452aca44a81eea9aaa9b7aa84430028a2afa4f1f9f6fb03839a070b03d8b15dccf1cc86ff9f8ac83c5c9c16507a67f29f23e75c5f730397cc0a7cad06d6bf863e83e0cd8c9adf17f013970d34016d0b7c61f05f6d6f89fc00fe45012111111c56ee1e3cb6e61b265d25081311e891ea744c1094b62288191e4458c417416d35f0e3c7e9e718eaf64a041e2f7f3125715f974f150ec8807cd9aa5c36d0ebe8a67fc9d9438bb3454e0b79675a37a04e24f90bbbbbb031569160e2b568cd8c5e11805db8abf48ccae2e1293a5ee7b1e3bfcaa86c3e93da4a8bd8c204db4ab818666c5af3e4ccff5d9a069b4039c13bf39686be2bfc298fda737d5f56fbae27e340bf938c15c19939ed3a3e429744d000c23a713c7bd7c8e0259c9c00591b32efd11638cf1ab21dbc4df6807d826be80c4f4aa4685b04d74c5162716bb71a3d5025d350685ae1ae4faa88d247c92383185164ea0a045932059dc2a5cb4808c2557e0e0891bc8e2e340445b23974bb68906dc473671dd9bbaeebfe7388ee3b837fd07e6c043e538990357ee5f4062bad47d9d18e798aa8e1466e8aa526adcc7869d9ee35e4e2893fb0fe8f441bcec449970d444439f6a7a0e0c5395ebbe5fcef13e1a76affd09f4c0651b8e6f02b7ef5275d3844487a53c153d653344ebf4eff4bb625e6f58cc0050994a04098acf4938273559a294482c0e72e962a59ecc9de810e0a8ce3f6fab254c0eda4e3c8666c84040fc31a859364073a3374accc836fc0ed0bee93692242e8bb12588c66c5929d761a8d10cf99ee42212bb665c31a58a1ae3af8d294c3e121f8795189104c5e725f139283e270932fd00ebeff39f296b3c55ffb83832d6d4c1e92da0b975eb0f53e176e3930924c46165f2f48b65dceff4cb9f7b95c3b4e77e9d7b710e3ff71bc37c641caa72abc44ff091f100adb75e035ddee27e6abf71b408d57e651a35a2f137ad21430761552948f9230054e6141f99cb6f0f38e7abfe6c04cef99e708ef7dc6f7f7aef4c9407a8e5e5c39ed140e404ea0032122bbd802aa992a1e4aa20c2921fd9ca989c7e654c563dd80aba92a1fbd39f681026da5a7d987cc4391f0d95bcbcbcfc0be58189f72fef1e5df5a02b193eef3f9a835fb972a2abef7deae99de3baf7e18273b6ead02c229ce3bd3f5bc1433cb08dff067e1fb86cc37f029b6d3807bf8e13e6ac5f414eff3d17640b7903431dbc6e1f64fb0f3cf10686928714336424cff70c0eead609dcfa4559908d2fb60c334a0086951d9401c6139900a0d08415bac0011144f081d680209e89eb4e2ca7ed4fdc7bdf7b1e0dbfe728f79bb76d9e89eb4ea8cdfb8e3bfd0686aa6f7aa733ea29d4a1723dd10e7c75a341ba97f2a5a77d7b8aa1fb0f5c79bffdc979e01c8eae7abc5fb9523f1af209fcde033f707aef17042fec7cbfd1f0f4df7be0ced6d3fe706ff268e813a6eaf6de096cc981af54d4e9db3e34ddb05b13deb05b13b2d4ed4f7be2e15125b397bd6ce5a07e6db0171abbe5bd7ba8ff3a10f51364241be524ef6ddf076ed010f36bc848b032927005153680419426ab841fc0200a298096b0c18f3f0f9cb3d589f48b8586a6d7a15fa6979657796bff05dcd5f63e32565a6d9407c847e6e3042e1ff3963f939e1726ac17a41770fb9531f1be884c862ad3eb0f7ee58a8c4990cd01ddcb16cf034355dd13cf7a8bc63ad49fbe0141b647a158defb664199e84db316c9f7811dd39f7e673f4004042fd4130db73751d37bbffb5a9d7e2beabde7130fef8b66d950627294930435eb6668723dbacfc1af5cd940eeca952b57f88b9ded4fd48523939342d37bcf7dc8485f540f94265007dbecef09021dc5619b7d4913c036ae66ed03e9619f2a1be623db361f474b4849a85ea9404a541037378722db6adbb439c5ddddddddeba64530c6186560a9fd8b1486fbec96f60ba5c666d69a9bcaade918bbbb3b0641f62fe3222366669927a1a1d9dd5d9ac5e16ad55e2bc275d3215c3882530f8ee39adb9ae3389f1aab772c32d25ee02d4de8e9f42bc66e5fe73bd0ebd8fe1287ea34723d664d400c66fc306adcee1fb5e81fb5f6f66fadbda51612f9bed4d788a9685c373a8a8c3ac618635ca422efd4e3e5abfb77463a7b0034981a8b8bc050412aad6aaf83a86a33553321b1aa76c54f510d6faac657acd03c7677779f64e0aaf64e8427251226901e2a1ce02a3502130863f211a021cca01d9a631827b839f2021c55b8d1220cee066fdad52ce6e5756f6fd7da63edee4cf33d3f802c7333737312cd7d7384c9df492d18a2956cb05f9cc9e06dbe1c4310edb7ee6a52b4e83e9130b9d7847c4c982be5dc7e30b9d7e4aeb6bbbbdfaf6dbd8171298aa58d4bdbb631d7bc849716a755bb3d93ec31491f99f60ab0c264216f45284a50fad54afeadfeee5efef61e7f14f068c84b28d05116d2e9d8d6d49a336613733fac51e517a754b1126899f731e6d26e5cdbb6aba4ebe86cd06582d9bde97dbab66d93db6a15810e0888ee3d0a8469db9e9578ef710734c8224551b471753f72ceccd2d4b8792036ed3ff6cbbd9bffffff976099ea564f17cca4d9734e9e9cb3dd02eedf55f4ce5ad8ba5cf34dd1c5361d5d2e971833b022263f0c05931f1634f9612798fc3022263fcc04dc073b32f961434cfe602598fc3021263f6c36f9174682c90f0b62f22f0c88c90f039afcb01f26ffc27c98fcb01e5e3a548a739673e4c7360dd3301fec67f2bfaebcce98fcaf2cbcacb4f0bdb0b0fa5e579833dfcb0a937f3967a6ee7b2a99981994b735fd91086f8bd395ba01d342f5ba8fc154f54c1f83aeea79dff79d3e0665f5501f83b17a2ca9ea427da17a2d73b2a04ed308fbc22e1d3ba7b9d9a6c54377779688da628c3146e73e4df3a2c9ddfdebbcd0dddd552a29e9ef0b13eeb4a13eaae57c739471466f59efe5db538cfc4e4dfbbc1e5d5ebe1728dcdd53934610cede9c6bb1456bd96e70f20031759bd560b8aadbac064398da6078a33618a2be06c396da60f852678b97faf6b434141233c6e46f21a9130ff697afc1d0851aae22dbec73f5eac1a450a14ff524a478e897eacc436f6cd9526391d899a677727350dbc0b83671fbdd6a14818c5b6494f79d4c1dea047e9e89673d9d4c26936b3c3c2693c9b5e839f0155e56d462d7997630ed6e4cd59ebf4f8bde2f4df540909d655c9bba6d9a465d9a877e71291787c99579a8fcde6dd73386d7bdc658247631633482bb775d67f23c53f7448a6b0040f13ae5467c7ba9ed9193cbe242b01fdd88c796aa75a669f2d88b0cc6ed889abf21cb355940d449fb5a4cdfe914bbd3a29626b53c370e50b507c88e3acdd34993c984faf673a95e35f18a015cf9bb324c4cd8413a96f94d17afeb561ae8e26cf962ea7e4431e774bfcf60cbb2344dc6eefb4e3dfa3bf5687191a18b5cd8e9b7c6077a9aa4ddda68f1970b41bb70b53987b57e6999a9af39a7656db4df97900360d7a879a0fa738ca6695e8cf7279b989ad468dcc621000dd9c21380daab97da2724baed7a91c1e4a79142ed94150f6294acb4483c03d221a5094a8a122aaf748245ed3ef6ebe573271e12949202a9f1d86a542da9ca1afdc948a24a1eac543bdeb2e004e6b879124855f8f852df4cdd8812a5f6d330820a520d9c50c2063750410d8a28c1132bcc6e009485144270319ba08a720219d9105184a8e044141c4491610a25328e18c20a2abc904501c4171ec74898231ed4fe5494217c504609a2a0a207339085aecac3145688baf8d142c90c9969080846d3fee5c44363172327fc50fb5bd893000a9233ab29fc5c82a208b59fc527882f9e98811432a848b1d4021d0c018a2a4b5ca10a0940c21251a43ce1028a1958200c29bc60ca93283d8862a28147c9817482523ac90b48c18ca01d486185143e18c1c4193f48c1628b2dac38143318820ccee584a4967d3aa8ddefc91563698a1c28618615491061937eaef003458913b2c0820d23218ac045942d66401416f10324883822849312c8927e30a92628841044120bab5c66cc50a55a1cd38987731398a8fd9d4f0ea45005165c607414831588400a2394a8d00413aea002930c8c964879e2e15b8451fb3999a31368f1042f8a4812e4838915513061450c846a607aa28b24b64d014c50a2ca052031c34f353306162a58635c1f2831250b244800842b84400329cc608c2e8c9658420f64f1872906677c4e0f20c614d22f7e1b54333e860b360c283041e5092ca87cb1c411164064d185135c44c18127692185d37ea96fa6b80050aad4ee2ff54288ee91dbfa9d8b313a07b66cbf5713a67f8c9b16abc084a5616ee666e69cae3ad7b2cd8adfaad60cb8b0d386e1c491ba812ddb530ca81ae9f78232fb8b1f9f0a9ef671abdbd3b7a12122ceb901e76c1f61301f1f06fc91629bd8d33c78b626fee9b5f7ffb6dfbe0fb77722edb7d798a85f1b8d52ce498486f237a2cde326871ac6518bac44b3a2c643bca4beb4d7bef75589388c87b65525ea1001998f61634c5cc0c25831be8ec35e728a1abe34d8e20c7991a971888baae20c9134701667c8f7e1cc599c21a7958ec519829a41c0e20c617121018b3364be02166748cb2fce90d4c76c8df72fa0e95db697a0ff07ee2077983ba8769075fb16708709f3310f84ea65feabd203398aad896f02598aad89df815c83ad69c24530473f449a757384c9517e09b0b6928183cc6645cd85231a11180f45ed599a4663b8151f00350ec5d46898eae3d768d8cae2125181459888879a45c33929b689da72b34ab3e2cb807ce4adf831e03ab71c050ce522908788b04d64a943558a8e8688865a966848d55195c563eabea77dda89477bb12d7fced17e1f89738cc039dafbf79386a1be2ad587196e12f395c5ece79eaee27fcff2de48db9a1251dff33d4bcfe9bfeffbfea33ccc3732bde5275ae4fb165ae4f45c6d212c8c81bae5db61547f16d0f50263ea843199447f3ffdf74ac1e4817392d0482107853ca58be09ce61c8d2609c23dff56e75165860c249bac0c639efe439a09b12f329605c44bfde2a06691b12f4ec1b224d2d67c91d44a9d82270dc6da109a5c85f29466f5731487668980f2c036ae15611b5f9c4eeae11f8bddb8d16a8160232175232531fd9bab68403648e214b6710da9ebd30b62e46afc9e1f0e53752b3ef34c75ff3c0261caad7bd3378006d9efba27f2f3f3c39d26a316ddbfc5e5fd033b2fbffdced6a5e10dfbe10ddb0b5dc9dffae2fe02fa68566ca13b7434eb66686a130440046bfc8fc6377502a8f1b701c477c5624e3f1792aafb315715e6a62425c3765137f5b0d4c75f196531860070b292611dd401ea742bbe0dd0e4d96956fc1b23cc90558373663e3e8d854967d9567c961e2e4bed3c99fe7b5464d2028659da616a7f0118b607a8dddfddee3745d1e9aa07f7da733e35721fdfc6125303c2e4ef231f8d4bf58f3d83511dc57a88671202a1f63f5ea7e316b76621b1bbbbbbf72be4a1eda2072b358251651635fc6a0d4aabc4838621e6d69887f93036f3a5199525a0548d716b9a0d69667d61316f796f202f154dfee8f25e0bdc9bbef35ab6a7f12da9a711f330cf8111887998f7560a1893a72c358b86a01919191a345ef546522fb3270778cfa55ee67fd0785511261ded81f91668111a0ff345521f2303e73d470354adbaa7f13eb2554787f4a49e062d2253bf32554a465b190d8eb250b37852a997bfdf8469f09a28938986b0985ba4dc73ae3dbf8e4bf006eec31be48737746ffaf006efc31bbe0f6f387d7803eac31be6dfc0f25ec3c4f478a1a10b85015746a55f3d8573660b65a9d968283fcfd4492ee6b0d4fb63806129ca4343af52cd145d6f29451e72184b69b672c4c6124a4945b3a55f96f055f52f00e7d4d05c6ba1468780bbfb07a6e6a8b42d175539eb14cd08000000a3140000180c0885c321c178382012f65cf914800d7f9a447c58970bd42488619442ca10630c01000000110091c1b409163b9551ed98c769e7d5baad3df3dbbfbbf24def67e21a0b9e115e1a782e8416f7b6b57d48f145cc2a12fd097deff5743a54a891d8d2e57f635e897d73790a349a29d7eca5e5858a982dea74c94af7d8f43e45b63de070b5ac899aaa188d342abce80567f699c4e22a94d56771f786873262048753cc7ce88c530b67e8a06a8a370723acc2d4c68fe41ec6d5bcc6602e66e3cd81f05836a8c723dd79f70386df2351b416da86917fb50ddbc47a723b7371b7db83e5bfda7a361ef5ca80918648670528357df0488bb85b968c590bd10274fc8176447871c68f9963a7a412cacb3f072a44feb810ea520ad38bfbe13032688262f4ee380fb0264e23f82bcd28e6f58be5f860f18329053035bdb5d201c943af1c0b323d771451bcfc5ec473ed518bd5efe2dd2d2f6bca2cf0b03c657e4fd7d5ec6d39bfa44fc728206c55aad5af535b5f75feece4fe8d51a19734c30588d9a9ec7b3fc6e3c82bafc972a343cab48ce4f2c6774752b59bc77f7e41ca57f3fa9b2ad290e5f5fdeb10ba8324948aa27c2c9278b296b0a530d4ec2cc6d36f1f53b36c120979761998841ccd1bbdbc21d4c168114e64c1aca2a501f502f6dab1c0cab6b05e512b029eea7a1773954f4b8beab37ed17b74734b5491c21470291b137b0b3b7e5df7dfb7850669465654f33b62b83149decdd561c402249d0731dfc333832c37df63af9ed0a4030d09b98ff129e208efe8699a220239c68c5ed9a8c78f0a707a9cb7ea5670681156e05ea31fbe471efd77ea2d9999ec66a7c09afb2fda4bfaf4c3d49035950f1cc2ceac7bd2cf4f0a932575448fc057d5e56c1871532941a9661dad7f238191c1c3b85d6ab499f48d82c70b47840337c09341969d2cd9638d9cb96bf4adeb1843f466bb8698340fb582b1210eae7bca260f989788b3848883ba8b7019ffdad50e043969bf4bc8c8e2b3933c466ce1f738e6a5f550f269f004088841a684d0237cd6d3348b18631aea710e34b3527c90998b24fbe5762d83f01ea34612c09b6bdb39667d1330919324ac0fb47692e9355ae6f7f0b961901aadd5c33f8b4e9b877ef73397c376ab40d52178829fcb6e62222fcba5523e204631cf4016d311ddb54a0e90b4f2c8c7ba2199d90713986a09e2294d88a2e9e0fad835ebeecea744eebfd98b4e978939362c71ab1240e5f8ad3e380079c3fbfa9b1845c025d83c73030b9457a46b60c012454a5544efc258fb561ef68e8e63efca41cd53cd8eb8029885b21c23b177ec8abdfbe820ff3e960c1791232f17e20fe5127d1c64c985b41b0a64d386a060fc66518cdc65e174d66711d5cef7bb2e64cf414674d997244f5c1ec7ba9193eef8f455eca919fc520abb06086b47ad21c0bd77f470b709707f58e7a26f0534e95155a9f63224a7eac807e5568c13d56e3a2175ce8a17743282cb4a0d4320b336c8ac71827ff36380abe25603eb102023d5c865e1d56b76f6fbd638142ff74e1e32ab9d790c57b57f30c5930320ed6c136c69500413fe9d89c5ad94a9139d00a18bb5b5037fe9ba9ef0cc4aa1cde81eacf75c466148890019c503cbdbd1b107e44d1837b7a33dbc4e76d45b8f10378fb80ff2d16578b7dba6cc9ff02afc8789d0e6337d09116d8a9185a301b91f2402da6c553e707dd651b5db2d2b2103d6fe048e7f972048fecc6c186a0871864d6ee00dfae7eed60661143c8d669aad017ead43a54d7af299d102d8f68a5b606e43a8ae1dda702a4aac7e87501831d8121228b8b63022b1569d82a24da8b9505e7fc8cca9cfa6c2e2a02e3bd5b3e393b3ba1b503153dece15934015085c788d9d8e5d9cd0f05182449c81fdaf52fbe20cb1ab40ee1aa0a76ed786f58b4c85593905ef3eb13bf3a17f20aa6686e91aebeadb8c0b3db9c52c8dfe34506a546ad45cbd628332fff195c7326ce6a82899939f9317625fb0c273ee4bcfcddd40215fe0282115fc02fdbc24db7b02763e382278b9de87f3315d8fbf050fa8291fe7a4e1d258f9e48e57621c62d7b0326a905769dd31bc16b510749639a2860babfd5ba5e95a710547368655e5161954135b1d29388c8b2260757c384f118756859ee612ed16061474525821c85632bbda6011de4066dafe4f8ead9a07a6cd144e20c5e2e6d5a0df53ebb8ea3bdcdd509dcaf872eb9fd875f90efbb389a8b37844ef3a5cbf72555406130f18384341ccf2cb99d484d91e11d64cbcc358a82426b19f95cf5d0b71c21dc4f79498db48230e51e1374b51b083f6b1a08788fcc666ed2e3fe60f5d0fdd1fbb370d0a0bd380d594713391457d0122acbf809a27f931f430da415c8721cfd225b2c84449c8263ef762bfb69de2fa7aa3c9ef844a5df40b907e47057f796c458c48c4c9d08effdd0963736edeec26d50c5190c3dd66d0ec378ccd22f46e1006b124d4ba3245080331e265acb929d6ff82ff005e980ac4f2729ae3349760e86dfad094cc3efc86337d53551b80900fd2f285bde2f103fdcacc612d7f9bd0cfd97d2d5330b27288ed8c58bfc9df0066ffcc0845db121a18eacd47c20de9d270634eab27d41ab26366f6c785843909ad8b39e1d26ab5ed4d04aa17c390a41487cf9627f63838f38a20f3910405b35e6d62dd4e3c29965a633d60138b04fa059d99f968e509865f67be994d7e3d0d5f2e45252c49300a5eee88d03996c633af0fae56ada28db32eabc4a87f5240385b6b4564c9f5eb8a9794238a9186c813ba6dfdd1ba4bf0df12d4b7f29507241db2d42501f1dc2569024c32b03e522564412ebcdbd1c7566620f6374b46b8a64a34bc8b56b3fc3614af4454e29a48b01324724a4832aad425226e2526bd8da4d96280c24a84cc811c756748b046a610f46d9803ccd88b393ee53ed6015b5dcc81b7d031f803a82b756868417d9a0072b69e2d92dd4598280e15d244d3d045e82c22426ca42b20a4718e21de249202be4bdfaf9d6d6808ed431f094e011774f3aa8bc87ca7e1902f2f0e798629bde55cbe1076eba40a33ef51ee718f1c6ad4d8d18fd0410c8001b837aa38f86043abea8615c5eca52951a19485e248f8d31a1a7cd12e23041f1e30412fab9826002ff7748ecf526fc335598f7b888e3ba0f995eec93363597e01c35029f1b98554e5609cca5812a4fc48914e4629ec6641401b98cea0a5d5b58f3371ae4e4f492ea4def4a7bcdc31ccdf13e90f7f0bd2eca2cf6c1dab1bd0696311b3451d8cefca57b9731a8e89707d4e3deb314ace13805e56b037dcd3d203e21d8ca8f17038d68ab9e857d2f0dc3dcc4e607edd51cf7e78f8e0d136fbd7935c94317d26a45d09572c90f5d98f800fbe57ff10bb91f3b63fb845d6e734fd56a7e04ef851a0460d2786bdb3d6a9857931d8c4149bda60bd4f973b11c6e5107e1320b81888411a276024a068aa37a469bd1953a4c2fd7130233497d2efd40492713ea7967fb6e2120fb83f2614082e77aaa20127e9f40f270bb2530f060142402fcdd1e8459a2a214024bb20f8f7f9df1af41d34cdd37733486783800443e05886dbf40ff24854789aa6883a0ad6666006a3d4abd229e7819c65e04bbc003db109ec6573c975631223716fa01aa86dd115a3d0724b3e1617c044127611424881c8bcc3c3a708f0f93358cf596e499f8974805d03065120c1d16bca7f95a2b679cebba8f0848e72a50453fab75b27eba407ad0b5b71f459072a715fca0d5b22ee8e8062b405d0033178b19f0e2e782c8dd56cb61273e2fcf54ce9225ccb54dfc60c78445c2276a75774d4a2fe774a907218d89e40703fc1395482a458ed11bcaafca04240ea2d69857e01992dc11a510f7fc4cfeefc7176187aa83a1ecef960e174b694663251dd7d98ae0daa99361fec17e9d8712b9068a7bbdf4d987befad6efbc428fe846ccc1cb49bb8cfd05ace50aad173ec8048c72a15e24d5d20e6113e307ff31145cfcd058a06e3bfab76b865ba066af9a9ca9229205fa52a3b37c0854f804438072e84a053f10f8e455585c8b371fab5aa3fd4c4d2d3d4401ad29b857bf88d8c3eb01e729fd767ac660466a2e3843faeda9e98a4ea5a035bd669ccb6ffbaccefe5520f1479312ede3607864bd4ed902066d86f06875e2894dd78b830d56ae5f03744439c87a4608669d137194f7c5f9feae11e74f1b184500c608618a4472f170a246346a792336327c665c13b3f82abcf9b79341ee9e71a8070834f41e58d5e98043b4322d4c28839495804c26c6ed220908ba8d9d790c7ddbe566ef69adf0041030b0a088e458812519044d2a499be8070702293eab277dbf536102d27e7d91702a92fdeb146e46101127f13d45330a028ead79ed09e8e13cf49e70b42d45b7cede0e1364806112bae4ab2597f404d1adf96b5d5958cdcfa4127fa968edfada84f5e5fd6fd3ed5e677de045d5ca94b0ac229307b56461305791539317a91f1847d119a159eab42d6c02705bff4b80a02f36bd52be6cd794021740a385a8c35553af243470947569f2e8b046d751d5baca7af572bd42b1518a18cb0a46cc646c7123fb76d7cc39a86d23da74c0ea36960e57672cd48672207513c48bc97d3ea631244d3f97664710c038ff16bee3889d4ef98b097af3e48a7d22abde3a7d6348e5741eb00e2480aafb7ca43a7729eee7acdf5d8cd37a1db3ea591870204fbe23e1e796528b6d3e8150ac1707e78bcf1ffcfd6f81af4bd35d6d32b4c8f581d95fa209a861d46e5e6c66d2485d982142429837e02eb7898230715e3651ad3c6aba53042c6c19e44bce40cc214383fc4daf4510da9e765cf8e947da8d909c0c2bab24b39f4112df47b24332f60c20e53ddec8c4abe1eccdba244039b8d02d4a28f18cf3eb8a3e30e7b1cb3bcf5d736581691c7410b9f419b3e6b4fb00264405786e01d1361b4980d9c5daa50d127a4b5b9d02b939f92e96d2ff3189338a6e5e152f3150d9b483faa5a364d883cdb3acf930ad848a149b1c0a12f1192dcc7f14144f9864e66cc328f8a8e98163633b08c213ec4788a1cc5601303e969da4d626fc5edc68aafa9f40c24e34bc20aa0a760e28b3ea745bd860372871113455dbc2a7b167d5ce4acb6621fdd085e885defc6c6a183b478dc6a0debeaee59bab7a5baf5565faa2250220291757a293bbecd87ddc1dd52df0fffa7b53764f15d29a81bb572533ea41ae45a6ad355454f5ce13b8a78af78d4831906ffe6ad22223813cc89999d901ca1a41cd4cb9004375228b8cf559cdf98f9c97b951a4504badd94e2aca27368133d68e609ffa7aa409c58ef8a244a119f3626e4e5842b54f9e9958caacee0af2356561293cb42c4ba169ac4b0bdf661e5c887ea2f1a6d1762eb09cccc7849741bc853838806b329d8f2b13952b49645fc6cbe71e73bb12d9746557af5fd9fb5489fa54b870d16ca9ba7f18a6a3c2bc744e35c9cf1ec74c232867340ea55cbc8d8fc08cca8c5d97fb8be303e237a590a0405b47c0234fe688c667402367d66ada7380ebcd4f665512dd7ca7e8f9a133f2e07714aa8883f173e85df2b2b4abe266bd6ce70d2fb02ee337b87c6d0cc4de5398d5050b0ef159cdb3f1476ac6a981dec4f2ca533f472aed91c3b9afc37b93b86a570eaa76af9adb17113c4372ad3caa45f78a72cd99681777f39d391f7a12b584bcc953d52185e03eb64816310a7fa42083549bc2c1162e15c48c66f5c5e52e98879cff3d327f51ee4d99717941609caee4921d463aa760733aa05531d5bda5f3e1b391673111ab11d8bad50eb32734dee8411e03ffa78942ab85c60e484eaafdbd64bd8674a3e1a5f63897266595e45a96023a0912ae192c092566c7688b9c8d6428d33f1dee391d819f5231bb0f2d5fc192bbfbae2b5f20b8bb222bdb673ca0d1ca010783323c8715b680c0ce4d76504c9f5e612143ebbb16a15a3cc35a7c7149a9f3f6c2185eee67899c59bb32522467a47f31077fa42f76c28670f8553c5d1d8fbc520b4de29e3545c5f950e66c854c02fb27a3c3156b4aa9f334bfc38358d56cd55a1082111af5e2030d4f92e253821861ec469ae1f8915875e3233eb1c997836948273d3ec822d283d76fa84bc9dfc30a426147420485ab30b18fc0a3e04397015844df6b11a73cab8648c63e59342b96a2ceb570229c5933dec115f6f5040088e1d1f233002f21ff43d658e45e1a045f72d882620d997911be4a9aadfbcc0ff29780663c210877eabd8b9a76ce52780acfa0841341f156f022d784fb9b42a308b3795a470467edd54706656637887eb9f722a99a9a3a3fcfdb112ec2fc272e46510b930098e4c4b47260ad9d1d66a76951de51170910cff8f10e697fa59d9b88eef5cd5046077c029a218779205c0f5908f73bb4de227b4b95ce4729a3cc291c991c26e97f111b06e97df7d4cd3706a06a02045fe26fc54151c01394cfb37cd49a5a8ea4c8b6f1534cbf7facb3891036656334c6145090201ace78238094dfbf803107ac6258e44f73086ed68a0edf8db2ffe75db1c0ad0cd5655530d035d95f32a792f1bd7a26ca2e8de477dd1c7200b2cce99d6c704d48ee515086f871cd3e7eaa8fe48fe559f24446ed6a44d1a4c898bb8e89945ff0e2a1970d4810ebb87ddc33ee9f87384bda9a8c80bb057e0e4d7b2cc77b4dfb471a84e334b7c47d14b9081d485b62e8ba429d0f726c6277f86ed76c2b6f5eabcfcc9213c21928081cc0d981b81cdbf429a967ea41c89f4079aff0e1ea54742304294a3a2ab46c8b37b3bc9ca8f3364494ee7cc177831de0f26d065656415a06413b4f27893f20eccb9234034d1cb13543225b194e9e0d0e573a6e2c5e076525248ef77beb6189e239def236cdee368191467789e8260a71a018e478d44d8e2e521a91d9e1f50d717a743b183cef1122b5f5bd1c255a0b1bed3d8367a22d6ad54b637300e5cd808e52c464734a2ad874fe37d0c6e1490a7e76ef1be8e34560be0862d144c319847e8c9ab7ba89b7c48f30eef64fba88d84bebb1a3a8843930a8c2dc965ddb32c51c3bddfb481a0d98b116def393af00912bd830589e5f057699fed9658e66cd153cb3d9c370e17f7fc377ee9611cd8a5e818d9efcb105de8fa763820f763342c2b2335679a2c1fd47de39737505cec5abec0e9b04d0f2dd476c994f3b9948ced2db7192ab604a616682bc5d76aa01bec6673a3feac9062da82afa3bc64921a9f70c571c1b33ebc24a8d57d1f5cbba8e774f6f81f6f5e487406efe4768206e07a8626bccfbaf945f0766550562a9d1011be8e51902e88d9403b5aac7e3933aa41d43db805253c472cad605faa4c6f74880d58fd576fb59ebf879d62529aaaf9ce68672a2af567984f56a006831835a7918cb1f5c76974206b1218276799dd6c1472e54c5ed382c1f1c94b05960ed783f7b037253ee3c780275b5f15a94be48d90398d16cae9d5c59f3ef582d0d1cf797d37fb31b3cb50e6e495f2b25ab0d40c251aa7cdae5af525924e7d24e7e2c3b1d21c309986bb1bed6ecb8a55970d207a4c6c7a6b06b16da7b6074ede10bab972442a1cbc5239e51d893fd01aa36401cb988a8a102955879dfa383557f5558ab7fdba5be959502a8b00370a01a900ddaa14e0db4f08445b52cff22b47cf40b58d563135fabb052b4add1737076d639017d0a7fcbd100a88482f4f9ff18d67fd49eb889ba42411532c47a04cecfb1f09a6d434d3f7d0a365c8f20783624f9c05bfc4d10ee0dd6cf75abf7a37bf5170a81518b5a55adfaeaaf042eae912fab3850df92235a3e36c214a72dce45367361e41a4c2749ef272010c27427a9140a153e203937bed03cc0e5eea8aec73eb552eb3c561e511b87bf80ccb5bda9fd03dd08ab95468bf14eff7bfbdad8de303838e63d10624cb99af91d2bd36e16632e68dd9be51273e8bf6a831a9ac44e43a2fe6983e1467b551bbec1856937324ae22c4fb2f76c18d15b3140d32e2d5539711081bd1a8b4bdd63ac98ae596083bd3f3a6b5fa6d53fc611d2a08450e33a5d52c513d81e10e4bf352d02851d7b00cff3e122786cbb40a13df6b36d2a0944162ef2a7c00b3024f488f8a6ced1dbeaa8388b8589ea5b4895dca6e7e701db44ead5bad532c6b491a8067debeb808371079da713777c61bad7c26c9370151f3cc73f0e755030b7a70d58987773ed9fe26b69f50005f24cf9992d12a1e0a24d4f9a8ec37d88fc11ce6d55ecc41436932a6a335ff29344d634a701978b9b561cb2d0644ce15c394a025c31bfad0018cb7aa66cf721f44f6b22622c384493c1dd112c473c514d08225a390a5e65a3009cf977448e99f9f9ddbe182b967200fbd1dce112a0d5e98b80d1a45e2236dbeb7f3cc6e726bc53a912089e15008a3b14f47da5fd9614ed7717f6eac49f8224038bd4e0050b4273071562094c1389884f9f5dbe2beaed5cbaed27f675318021de2edb3efbf9205be8ccbdbc1a25524439b0756abed5e5f2c1a64a9407a654e0d5e7ba33049f07f18058b4d5bdccbb62a63cba52c752fd289a2e83e3d0bac97a3437917e62598f39840b5580dd7f4dd93d3cf6f485afc31290d42bc781c433f5df9cbf9d81b8cddebe27d87469df606c01b83389e52ba51ce0cb2fd81516072ce7898f92808950d63f3f73f5930a7cfad1e21637fb4827929401e66e639697bc06f0060c9bd9fe385fd1c9147c8067bb0dc58e9e3c2d70ea67fc54efed440354b1c9aa19ec86e861abf5cf4545f04c917052eddf46e71bdc737ada115fd68906a8e3056dbeca11f3ac01e0bf980cdcb49db3f4115c2aa447e26856d0580066c99417dd6bf51f03f16aeb8a7e4736fd1e7fe5ca67b6e1dfbd0820f05066cf7daaa00bb7392e0d5db1f581744be14ca11ffe0465b03e711fd5a278f90372d2351ef2c2f1784bae1be838bb46a94d4f2b1bcc5b84fa328beb5629f0fb6aedb24c468b4fe73865638b3b4a271d63aa2bb04a7594ca82266c6fce6d3a0bca416957c0368c18be540ec4b50b8a18773229d76fffd4c5f679cf64cc321814910d1dafbe8e7699b708624293b6d54f074782848a9d7c1d15d52807413f2a8f37f244d751fb16b5fbe41f23007efeba9ea7de4f62ede5fd70abf78ab057e142cd9dae07e2c73ad0775c0c5ca410f6678644c003e5240df0c2ae16549ea6566cb978dde2511bc06d96378f5b525ee7aeb5786d7f80e4576e748c9e0a5e2715fa10caea48cd9282962522c76bc3476d9f87d328f23833c85f278400d3f42feb404b7bc06d3a875dca3070948668b7748282482a25384034e7bea66f3635bfb6b92c276672aeef00cb478016d6e7087a536a349696202981ee8ffeff0efc5d986e34051f1f60634344de04cfb21c8467294dd6784b819c6dfb5184a981cde8a8e536035ad93533ce2abb33210690c978e6520cf63d6e5dc72920713ab84025a5e0ba9b2636b9eee072381183abb7d222af69b8b5c3a6add6e82d7fd7bee0397b139a6de5674564cdf3c0d14c69916e74a1c3249a760f8c02eda8fb8390a40ba751190e3b290c38237322e5b326670b7dcfa6218e3481b7911ebacfd0716218d5ce32e45ddc4439d02aa135fb440e0d7c3d1b7a09e09f485578860dc06ab94172674110a879a0893c7106fe7e1a1cfe430e644387b1a24e10e2dc1097ae9d0ec772cb9f1ed3be167a9ec7c181eebb28cd1fbf87d7aba6eaac7f3f3f9d7fa510ec7d6e535c1dd6064399129d9ce805f88420489df336fd17282cdda256a43254e5bec8d532e9b69cd9f6d6270c7405021c7ab1812adc751a0befb952bc2e7eb8fc6fa51a5d64d3ca8c1dfaa0495c8de1df47f382caecc874422de9cd258de68b87bf7df14983994e14a85d0bb1cc437669a90f3f7421a38e9747a4f4a098f8fa59c437387b8fd811c1bb2d8daf1bc015c5d02da80a7e16e1854005c5ec25c8c17e659011a7c9fef8a45798cba3a0f5a99598c500d78e640864117d765a0fc485b1b47b958acb9be54463b0e37b134a5014e11526e54f02b50ac34321dcb69077f5fa1a2c28b82305358250a5c0ab26b83409ea6cab4d768609fa5a4d639dd57313fd20ac3c0652aa65681527857199ce7481845d89cb4fb3f4105556702dc56b2727d1f8931d04c2394e74c5c576dac1987e9d8eb8734f8949b29fc0daae39775b13467b770de0cf08b19b3d516a52eb051f3072b395ce9b1f2322d6549ce28aa941525444c26b6fc66b1047bd7d6b092b39c41fb0b47c1ca9130b088b2afd06710bb2f434df132d1baf7808fed4b16c2338faf1bdafa0b46da98dec25423599b0bd57d79f0fc1d3222ec595e9cbe4565fcb2a42a02ca6288e8578de5e255cc42f0a1359e06efcb98647a4194ed4d3ad9e9931c50f1db01fb896a90cabf9c85d10b4fa7fa20ba6093993fa3f2232246e95a36e888f4fb3532ceb03708b44d56f244db525b8e89414dfa6f43bcb0a3050a63f90706b862b77b4df8d4ff558737d9795bd74e36423f8bbecfa61b3e531de9ff08070194ca7823162b390235a6cede75a01e5a3f9b991549cdf8659b5b7452a8f1d765a5677e14eb615445c72952d1364bbd07dd44b5186567a89bf2e5fe82a80ad1fcc69471d4dbf3185b7e5652720a4c9bc683bcf3f790dae8aa8b49a91420000fbe254256bbc79c5a1ec43c4bff7e1c3a44acd1626284c076f40fb7d7477eb42d9f4cf40b756ef4980c694c0b21324ebe61a230b6408bbbf232196022940f736de7f5d8231e2060f901cdb3c6c318d59896f40a3a48ef3f33e2d38dca409e9128adf7d9443151b750250b9e49d9b263733d619f91b97e108c647f576ab3b5915618e51917bcba094f45fd1f506effa0f983ad6797576be0abc27c9ffc8a4abc21b0afbff13ce097c2ba9184fadb26893d8fccf34e56f44a09892f6e0f3089a08ed9c9b6e48754a0d36982764a03a1fab743f1b24722255420572e753e2b49afb5e4ac3748f0d9942c46c59d993ee99e96a5870b3300686c9f01e8bd2297b98fd2e9b47e90433d041d4c8f23c43440acee854753386447544f0accf6ca1f72499846b750379f2d9323266096bdc8cce4171222e8f7d0c01f75fdc7248d405a7cb41b7ff93f80d8235c9c472ed41eaa8e3d259e4cb0c99303e7972c9385ac989a530911c94ae62164338072cbfd07faae834b90650703ec10ed9d063454969182c0e604a4f579116a263902ff095aa8e74248d6f57137ce0cfebd02d53a28ef380b901d0ba181ef6fc0c878c13ab7ff6ffb0cbe35780f694b76b208864f773404060b7241139f006d99916b3868fa9d15c620d720d112000a42ca5aa0000e581aff6ee567536d23ff8b7281ae4fe00c9528ea7c1899f8b1f3eda4e8a853416fe3e82b8ea4694101a030479dc370aa5fcfd1327e9d3dc78113f6a98519a38e41a3d36f07ed1324e44337cbc5abdf329afe51340587014410114441806bc5ff3da5417fab1921f7c020cfa943ae1606b97ff20147dfa2626c19d93d88ec1f0980ec7e0cd8543bfc2c27e6620af915749143f021814cc594de1cc7cf606be1805cfce8d99aae54392ca3d144550e4d25a845c4e9db3be45ced948d422e667bd27b679eff42b7081edfafbf963a385f019ed093224c34527616a16678d5e4ad727cb0b1a71b305e8d451c6e5ed85316565740e06689d514da85fc1491b9785214da6792e9aab636c4d60920b67108146bb781ecc2a38c3fd207b4ee2898e0fbf192680837b5e544a353491d6fb3c200948aafae854d2e98acd92aeba71d45e44126e7d35326dda2cf98add39ed8c9272e02bce44dcc9924129e72b157217963b160ed9d9b406c270105620689ea34c800b2e17249c2137034cfdb528f5bef811757a8c0be048f3a980278b8a860285258ced11c1404db8fa00263bf700d0d3a6a9008b289fdc11e9c04b1c1ee03e10503e155949e795b29d82fe4fe0214ab5a935da5f90c9e358b501c23c3c52b90623a0673861405a6ac9361753c1e00200a80023458294bf3c000eddc713a65b9032e4082f00900cdfd24754dca8073f8649715efcc89908c3e69ef1a83005be23830c43f2776efa7427f716a468185a8034b691e45c71827b0015f14f98f5f6179e9e4aca13487a34db7141d696734d56d6dd92e066180b96a009b48a5a2e41278e0d0702be034c8dfda80f6ce841dc7d1b7b656c197eb9517465314e2160ec583d5689cce9217646e176b5a18f03174c1814945ffd3a9bea481ede27f4fe43153d00d571c5a11d3c4fdf74583072fcec06869edcb3fee486c0698063f824bf4f80d93d4c0d239518cc5905d0e12ee18d2f9c8100e9bcd21b32005d96a94cbac2aadc41880b4a03444c920af1d90d315be7039de945d8474474f0685ea09562018ceaaf306350c8c335e0126d9f6e36d5ae98d4d2a58a028e1e8d2bd9472fd6d6480cdb7c330b5f00429d290933d3d3f2ef925b5ef948f6a1a9c952609a956d39e1e3667805b496e7aeeb21e2762e543c4ac52ba4b5a23b1e8a2ce11faebb7d82b2d3da7ec60ce2006cc1f74fd22c32a947840056f729d018c4e2e0ebfa4f5cfcb82d9d7110decc17e8526dd21c44c64ad397270da39adf4468b9874601f608a000cc7471a0dfcf07dc0bbc3491f06a4320c7796859dd035fd6d0a3c95c3dd8dad98848da817dfb72d2df6072e6e301e768ce2fe6942f31bfd974c1cb3fe251cd04a8a0b06ea7cebd6da2ab0d1a821056b4f1b9462ecc6d30788d12ea0d52fa8c1cccc75c10072f84ef9417db944f3ca210f5b8a266cef1efe90ac025b9e6e6cd45f3b93350cc2a9cdb1d8493f052985b7812c5281ddd4566cad610f71d89d78f6735f737c10984b239ec74bb1e8c978482f30d99572f9144fa05e9f9dde892755fa5be02d70f6cda86a46e646a06f7e8a42725dc62d87f9d49073a0326986f295fb6728a5411b44e8299c90f201767aa2940160bd100c6b2cd3c3546395d85ce55a4f138b4b51b79c845b1f87db5ae753213af0419ceaa1365ffa8a687850ecfa14491b28c40569785a82cc1faf7aaa8e261fa2a9a8ec237e353e457c005ad962f4c89c677c09fb97e7971ce6bec131c7b01c86179cd0e728567118c779283262ff496352170ea6ae6fae346f6a696e96d8e4222b0e4e819e2706e238083d2e5b702bf3d411ec26313e583d601ea3125e854ff40b0460cc38e2eadaf46b19e8be7f24484aff31aab00bfff82b16c766d50f1c013207a7a3c01102fd2774d34d293f83fd1d5fcaf6584aa0edf42e9cfbc83cc44cf1453403ca3da1b1409341c2ca610521be67863525dab21bad16a0b5bdeacd84fc0ddfae77dbd70b4ada313bdc42000d62d611ec1f86d3a67f76937576c0ed11e3b33fb3cc36d23da22d5078288c1ac600b01a6a57e6daa940790c9e1f9b00e29c838da70e9f4f764d34734c37dacfd4042ef09e115f40ed6b6913af4dfa7d201b4f495f598de24a264c2e053d133b1bec45e2acacd7dd8d8c108aa7587b121741a5583852cef66861eae0505cbd3067062a7f8d3095d560d3b22cbd5c34057458380a7d03c1fa42dae75a2740e96de29952923c02960631f7f328bb32911a2d42f755241dac633f797266042deb468aaae04335bb769a40909bb7a271d95b0cad0c9b4797221f591f000b5ce20e98a81caceab42ff9f5be8a9c713e3a0b47fa1555fb71f7dc00dbcdf243cea9c3452e101ad5349505745ee218ef9d114253d50d08c2bad6510035f4553d1b7cd7d4db59674519b93f4ecc3aa4ee5b1b25582b74088c5ae4824ddd7ce8737e38f45103e7aa5d9c944895817d238406a50156fc0b483a9c3a5fb5f72aba96ea6002f90b536faa1982821d33b74126228e5ae2c9ab9378ca2c82e7b552802f4dd2e4ae317fcddb691c5b17fc89efd9bcf37be5ed221749ea45abf994c5be20da0b02ccbf6f083f707ba7b2ae4193ac8106c060a29111ef67efb9c02a334f56c7dab37533f75eabcc62b3c9d8145474a857932b77984745798c743e15286e5f5175e849c70bd3420a0282e140d8f98982dfefd0e8044fb7258c89af439eeec93db7feab8101c908067d1384908dd0708b310664cb2df432431a0fcef585478a2b06636fc4c69226f45ceffe9ebce98e4c9815ad858ec0d057ff35b9928f3a56407fcb712be32898ea45b9bf07cfb45ffdd76bb3a6b1f7625c3349c48cc49f322c75df108ebb02bcf0d8431f38724f07c52ea63d39183e25561a113fe470113328e5c21dab7611e0574985cbace51f28368f5f16906da62dbbf4a2b59b820536e1cc51c3186f4b124860d2f8fab7b425e3d69993757e13e1e858e3e8fedd41704b21446a6e3ba40ad79f0009ab3e47ac07b7d5eb8c1196bc8d5f7ba336ee922f1901ff22e27c0541e8bb1332ba3097967b2cf5a25423c083ef49641ea40827d6ab54453b6f391b1ef671c788afabc53784004e0ac3055b7404c593e51ef303786acfb66eb3b6fd18c605a0c24a321d296ae1b1cf4c828462dba46620726a7300cd7c0ac296964519230bfac14caa3b5e55e1ef81feea6f5e44d5ce82e5240968ad1d73013bff8ac051dd08de376d7490509a5c70fd73343cb4a7f9afe3a410c3d29b5233f0b9ec5dc5ef05108668a980d121235196b25cef934f97db918ae2b11805a21c60df916ca627d250a8003638e56590ac28f393f809fc7fb243cb4db18b73c10acd69b6cc62f23bb51432b1167d33137d9710c9941a32ce27c8514908406e2e1e4a4b0070790098a812ff4c03651ae3baddbfc0a34dc3840fdc39700fcfd985978537a1760f182da49c74a3a4b0798a2be03ca633211ebd17c41d63bc183eec26df59683f385a2a80f90ef1d93add32b09b6fa930a59c5bcc2ea2a9e7dd2da603bd88a6ceaa9c0ad45efa70592a3c2c514be4a7cc03e2942d13fe37eb0c9110f1ce94abbba3e3d2143c4e9a04b45113bcac509018ba5543b1e657830e9287b6a18e51eee27d6498000187c126553eafd6b1329ebae9f514c6553c28acc94a64a1b44b14aac16d870038b232eee457742e3bca1a3031689acddb851f0b5a85111b7311c0514a6814c01f9c594999072d3096b7d505cea4b4994e001705a6cfb8ee6bd14fc6cb496df24466d7bc0fc60c6e0db1df59d92989ffde46abea4ccd212551895f91d01d1b33c49f64da1637988ce13b82421d6443b922bd59726716e0defa2b9db4992495c229a196c424375fff4befcc510d691b2870cae58dbe8e8abe1d966689f0bd9191dc599a860127934e847b249837770eea1e0a4dc41ba7fab232eec5c15a0c4f035f8c627de68d5ca13d7135c0eb5d3715c276ce8bb99eae28a8f0bc69722ed8fd78418dd3ae99b7390832fc76507939f17a3744742f381526e1c160bb8df8f3a07773ab575cc5c09baf2b9f5e07c4c6321a8f1b879c62ab607de1d2c8bdb2905645b512406e5a905719ee8e0b3d71313ba60c8cd4c39b4d0d470ecaa44a6f44ffffc1080d255d824d76979e7d9800df8c6a123d03572999b78ac3dacd188a09c7527218128a2989de2d55a6c1f4578fc10a91b797bb8e36ef3ab00d6cb123861a8acba84dff41456ee16c4658dbd5d272a37ec3cf784e2e1e3686a4911b8eaeaf4350f1af36c56a5702767a0ae4be41fb8d1b90728668ff6bd59e42f1210ca5b149fb88e5dc2a9aabb032165b717465a5873b2a0650a23ee3789c70119e1264153638e84dd4f0f57ea4ea4c69da63c8c49ec712f86501ca387d1b50d7bd0edb138234791cfbd7717d7a3e8a914a8d9b8a1408a901d74366306e30805681bce131d43f19cca17bbd6a45f2345188b822f522d71b51b9b789b1c7c8156ddf1bc82ca702671918fbaad97b50246b5008befb786107970fbb5afb2f9a8eb7af54408fc07578b9c5d9e05c9874e16562cc22ec8504094b987337774ccd2e0fe0ab231e53daf8b17371e0ac24b98eac34e75bafc728ca210667268cd0ea9931fe2203f4b82f8c867c6c267b8dabba27f830bd3093115bb07f299067101438b11bb9b6a28e3276e2ef55fa41c965c3d0125a152079d545edf295a738eaf960178e481e202be07876257109cdb685d8ef807dfe3ab5949ff68a7af248e5b1a7ed2a46896ce3280ec961f41a14de69b1443463dfe33f67efb3dc653fa1e32d931ca564c76281b1c8b8b89c98b5e431169c223f1a55c662b2de6d512b27961bc45fa60fe0b10a1d8164cc3f54f7c7fffaf38df12afe756c98f8308afe695378b03e45d6c7bebb77cb03ecd371c3eb4b26fd15034597e6fbc3b1134f97b0b092d3ddb1a1ff6f5be9e947e03c33276a144771419e15a38be02e510c75e9ef28ae856135fe5fb51d72bd3bc761b257fdaeb5ae3029f486cf26213f33f0bb474679c46f47e8d2e617fcbc012d054ef4d45f0d27c6653e0a3e5c3de49f0c84be2ba54ff56e2cd8a1055eb3cbcdf0b1434d5c7f7d2597e561d6ba1b7709886a9b75db967fcea762c0882fdf4c447ee95e9b70bf5500d94ec7e5056290c500674f2eb519d2b782608205b261af2a0c59e20fad4388b89a394b502b254de69dbad983e56d36af0c12ea014949d4752b080a43021af12b4a5d071065719c8dc59f70208e08e9ee8184c820d2900129e804c7da1707c2d3d341d77f6ae2a17cc54ed8de049c45938a6bad99b411e6705f024168dcfac0b0413b28b50f7b47b9eb8a62954b3058c08bde5e381e232be760313a8d62073f0bbccbae0f91f3a063b6a461c7c8a7e390a01f3c58bdf453280f395f4d1e48bb29d8d9b75d35aa14a547f4ae86590ea78d97638ef4c3328124845468fff97a298f591d75fcfa144db31d613b3ce28b64604750713ada3168bb1a1ee6c07804cef098574d451465976e0b152587fe2f08b3b7402542c6a88120107d69c787e526ad9267c03c889b57c4808f8790ad481a68c34128e6bde84880286d552a2a9315c019307acc35f2589d12ed7923f4662cdb69863da80f4e71cf6e279a9e451d3d04f2894473f480767c59e069197d8e109c86e5df088c86dc07135af9d7d181daf55552aee19d1ea2ba3702d2c6fed065167260ee4c8ba5e7e2ea553aea2740745c990e7e36c0c31ccc9ced3c51fdafa552f4f077f043dcb7fc1d4087b4f56eaea317a599ee9470c9213cf5c10410d906b8dd64c86125a434042197ec269211e0c60ecddac6ff2dcae4ab80b115807f98488e8a7cc88c18052966bff92fb15c080680d9ccf4c4f65c584f5b8b23b4e024a8c55d52ce92df8e1b20eba0f2531b411428cd26f1d0f00919d86bc5fbbca9b94c2948043111d5229548966cb67579fa792b19dbc4bcc14c9cb084221c294405200cb69380f14564e58d17e7a527e855087af61a499e619782a53ec75ec0370cb2501b71b1c0f839565545b0870bf7ecd70ae34b0259ed206766776c8fc989bac2f58c495b4022cf1d1130560d329ea0be40d464642c229e80a04150c04f5897e6a3195ea6051555d19a3f49f3c456858acf5c5b18523d7261acf1a489108e73f78efb02387f49d90ed59c184c541770d3f773d695c632a676b3be7f3855da0d48504a38ea3ea643367d46c595506906255b889c4806f0281992f6dd642e3fa1f206e911c91030bf0314cf798e64bad41c7f1f9a175c7ccfaf2d197d254139d8de32d77d291e6d005e6397426c9416eb1986c252db5121f1aa261665a796d1595b18535f824f9c8002230ac194fdcab2542cb49a9463c60491e043a9de7431d6d209a6d45ae5302927936076e3394bb6ccd525abc8e2d44800fba1d600cb7e62fee7edeb9792de45601380e7b933839791e3f7fd0b2d477cd21ceb338c7dab1ed661c64989ada48f7a39db9dc3886e02a73caf02cb8c35542c6d3b950fd3f6849f52193db10322b0e03031effc7b841aace407be6cf6349013891ea3f9ccc08afd339d27c4a3d5149ddecae5ab365420c67658e42caa6c391ee0db61090a52630e7b05aa2ed9e1817fd4ec777ab97bd7c5f2743962097a16b9ca8adb77cf51c22b237758b31ff92652f0010960f809a998bba1c99d20ef73283fab9fbdee0fc3e40ee4a7b115ba0d7e331b20a59d75a86d7085ed4f6bcac9120c045ba43e53adb3d650b60de56bfbfd0809e34fbfbe13a949e2676ce226ee745a3776fad32975f01d4ae7adf0753a6b080990d8e0cec34841e7fdd01aeaecddf87d2b151d70365b4bb3831b4f635184615a15ca2c0c8fd2ba4dd1a1a4f4fd5cc9140e9e8b45f44a2ee8e1b390cfff95ab798b1926c994b82bcc98b17ff08d7fac0764da8a976eb0428c078c4222a3774952306e821fa323e844a8043945fba2cc732dd3b5d9cafa5bcaecb60502be1eddcdc969b8cf00eaf40dcf65a16283bbd94bb76a72498938a41ea504929d18a28cfa2a7eaa87061c810d6e238c4a196302a2cdc4c69be2e858a00ce4479f748a114f163f7c728ea168f25341587c225c112660324ea95e262184ecc46ce0860d21c40fbc5bbf3f7e4bb0ff2706c914f16a27f8dc047b536dfda6807c7a8e71ea723f05e2ba920091598d7e85e46760ca9d577b98c81d2f9fd0b732d616dc5a9ff79ff2342b83ffd1ff7dff7adf9678c9b9ceacfd51924df3a3be1a2d45cb406439b9d5cd05777367dbb68dd8d68b6f8c1fc45557e4863b5d538d98ebd0753172bc67c07c7aff46fc4344b81e552b93e419af640359860074308b2cea0b9c5ce242d2e7867af5b66515da7be135a58544eb4ebc2ae788d1f8dd64f29433f4fae04cf50d53762c7a1afb3d50870fe1c5c3656c96e8498a8e11407ce8e1464c39e0134243a9ac6b95f1c380136107b32de4270f791e5aaed26d25feef42df909faa691fcac41e66eea3fdd93ec4e9236a89df1ae62491253832669de318c699f8fe6d70e1408c2e06ca9a7350b65b8c0087a746999bc299d17b259be67190914b044d4fb52ffad0f399ae38a0bfd05fdcea8508fc9120f1f8bc5627c1634f2a221a92bd14ecd60011973e64bc2c7cc52011b4923fb4bf12a53811e0fd58cec288f51e21603a54efd881c1736a83d1980509643bc7034e507b012e34dcdfc51711f22e490833f4b7ffaa140d518840a706081db6ba52e61063ba206c9cf42261786b570b97b18a55817b1829eead8a8c07b50a7092034388030881536edabcd08ad464b3ab7a8381a2046e18d49d272c7124c4accb6aa6c6194ac0eed39f4d93aa68c2c7d8c1c6f654bd1022b24ba3c5ea4da4ff31e420a48a4477e8de2d9f2f203c7e8675859b1ecde1c12e759cb86d30b097c34af934454a620ea2a8ba8d0c9d3b791695ead3efe0c16ed3a7860b9e506725edf1484ce90fdf64722143fd3827b7c8c9cf49d7393060351ef028b25e1d30bca587ce79fd82dcdad4e7f9d1ffb7e5822442855e5640586c85dd3bd9c14ece4418256c496b819d5bd5ca176fc5ec036398699955b536c0b04ded53fa68a53792daa4e2bfea05d9cddf970cdf6e7e3f32e70872aa55b9d2df581a9c1bbe9df9fc80b049cdffa87855a68516552a204a03d31e24f40be34d6515a2b056986fe6095d9fb634b76da28d79ea224c64cebf4f0b6f7b2feee4c603e7c454180a206ae5e80a6d087a8da8541b425fd6506a11717edec2c790c84cf48a5d850511488a705a7aca9ebcd64b79eaa29440808d9861ded22b243f8e7be5d34dd73e5dac40069612813b97b9bbf7e04711f5b7e279fc4e0f5433fc55f8f33ff91b8524fb5fb7f6b35782b80442cf059e325c7bfbd61e716dab507c7767afa3c6b5e06be16a3c97c235b6b8aa866d751d6e382ce470660541b804452511cc7856d8caf63d84cf1442705beaf0b68461dd9be8ddf197e3b904d49937f263d7cbf63143b316f1a00cc8270edfc093334b1fe8b35ba8ab08c52e1383ca2f0320c1d6c777087cef03fdf5ba558c8e58ae14da1adfd756341a6c1cc60e3ab502c0f158cf8c47a7f1f5c8e797f1eb4371eac51bc47447a96ecb0652cc5877fd66c36f58efa849f6c49fe1ab3e68c49abc994b596c5a6079a4841b49877d4262e62316f45b86c2609a59073a0c58ab7ad58e7f0b0d871a28a5b3adc9f65aeca598b9e44a34a14813d481a657b58c33fb1315a64ccc98f19c47497bcc68fc6610dfe805a5a9073ddc4d58e316334553b1dbac645f7496d132df0777f6f6bc1c2740af80f43838bbe232047f7f647cf54f5f6bb6a3fe6e6e4208bde5c8ac3aba8016432d3c81e5092818a1397046ca305ad44db8d0d3b0f4ceb3ccfbcd6c922030d3a99eebc98bd863deca919885fcee6a09e35cafd2b856ea4d4379db71b92bc19cd6a343bedff6cba68a8efc21ace3d4df198de7c130d1e7d09ecb3a078ee35440c36c952ef8ad8a61f32bde5649889ab96a52716ed9e1dd6e32f691613f3f9dd817283310249072674b21e4365d3c8147bff9e260d0e03377486b995a856ff4ffd1698f4994cab3125d8836e6f528022514149ddca6ae53ab81f488f8d603f1bd368b48867137a83a104425fd8b670e9943d34ac4f87a01a7c5beff4b0eb93b732905d86255ca4485be323085f535409fb405f7489d4d5a1bc58727b7ee96cfd184282b5854c9d9665e9f8eead54acb8f75192ff1d64822bf9d3c92b5d46d552d44f708187186d17c11aa7ee971030da81d4795da9d6789b567cc9a17245b030fa7c450c7e5063495560c53c272fba270fc15bc5a2f9c4ba8bb52860a6e6775f03076b9a8a75b4b644f1727d08315df5e6c5850058e7ae0f47f8e51d6859a8542bd0cc9d100bed01d0747753d9fc21a7771625e30d9c885609edf66945a7de9895aaf599aa6e7f56ce6831e021a26fd000722c3c0cac91b258869850f47f504c3d1885ed8c4536e8f792dc42cea381685e2d767fc7e88d5169de239c33857270f6882a907e0b079fa457df3ce93c7fa1fb13010f43d51afbc7e4d2d5aeb14c2a6e8f73e0510e6052aaf0d0fd7bc7dc0eb679db823a3802315e9e2f080d7631f456467e3dcca31982348c5e16101bdbcdcbdf402c80b8797b7d7dad958e9e989b2370687be99a9fc5101d2234869cf5d481f3f490e94d151d6a353e9b85106ee5f7643fa529262dac77a0b951dca94880ba2c6bd57ce7305c7b87b2e5f20326d7751ce7f6863dc1d0ee2d2862517d4fc14a1e4e28c14e93e59caa815e9deac57d0990836cd379f3f7ce759beb2c31df6f9504085c9ebd3fbd63a160b8752efb18b4c53ed060490ea7955c654e345cdab386ba6381516c8087082ecea45021e856c2dd1b8a53d11a90dec4ce50409271a05f0166f2c3c060da4c9f02386bc5b21df3f63e2f40204464b2235b25ae4257f3e476a34c951a2aeeb3e62a36f0ee48f754ef4d92325ef710bb2116290c8d99b3e9671dd47f12de8ee1c546ea803e02b67748b96862ce36b0595933a4cca66fa47d8335f729e3b5e5627afad152bf1bcfd46880be45d8c3a59592b3a2374a2dda11cfc85e5e45f6d7a5a13d0ead624aad6d52f56312603cfa472fb0c17c9e07d6b9c35ed7be8b626461c6725928727295d02467ed6d652d64856a0c7e58edc60819bfebd165dc6fd6315e0afda1704d2fbd16f7eca9d7944494bec799a47246dd3110a3e3a925be26ab87218151abbd693018f73d5fc510598abc258d8a028e938221f7abaa051ac89799af54bdb5eaed3fbbdf3ae9250d1044116fe1bbbb116d2b9dd6befb3df86efb1c2f6857fa835fb927fbaeaa0b4ca08f2058c771b1122c7cd183b24f9bebaa1853ef5a82c275ea3ad972845805ef73aea0d31f7c469d18fa99f348f5b3ec40ee0256a305683d844b9427316f4a4378c4528314a051c62e6af2fc23bd030d9269012598f9e97015c19eeaefda59fed31b99970a10775788ac10af9afc96e028fbdbc0436b1a6d7aa4fcacd39cddc7d99069db99a592b934f83cd6605035abc844b88ee5e1448ef478ffef598149b724f5cf5a36a19474792212fabf5bbd8cd73b0d2869d9341599a2bafedb98366f02d410635c65332ea6d723726a9ec498ba4f00aa68efad5bd8317191f842dc27a161ea9ccf8f14cc31c65b1b90195ffd698cbbe9463dea8ca01c1664945476b87a8d089edecd365032e2f28adf6b72f2db9aac8b0bd941240a16469ea3b673052b92eca94a44bb3c3b6ec9a6b9bdbd58d0c6606c7862ebdbc539b5d224942c84cd5ad9649d9371e2145cfbbb87c96a864d7efbcdd8d6d6b87ad67b08db55b340a4401f588559dd160dd798df67478e6400ba8d270a9e9bdfdcb0db6eca513380cb644ad9ad81e66d3c3dc36e989e8e6d39fc6c7297a339f105df1f34f103a9c898c7842ba7e508200439e87c83042d2a0c33d826e9aed4088090519e8180bcc1b2f8df581f3ee61aa530d50e85e4fe0ca463530bb25ff11aa5c0d8cf1aa6e6a1ccbe507649d9506438fe72eb823cd8bd2293f18944e068d2bd0f928df0a8d8f51e5ca18dd8064ec1dae8a22731d10d8e7fa86b1dbaa0774987187ebec97379ec1ea0eff5546f2e40bb5883f51d1dc258b8e512a63159e2a4f6c07b03e5cb98f9bc0020cabb4d4901acdc7e7db10f26cdf085ce6a490c5b222ea2de39d56f980df007c4f49b26b9681e8ca0e6bb9c9acfa27544c7bb44e81f70d1b036b9c5e4815832aafa1614affd80fa93c650214f7936be6f006497bac955a7b0117d70af7427a7c5ceb3c3d553e7c1279375cc40f2e62a108491229425e704080a98eaf57a4001826b0e6f36a0e8983849e5b265b8bb5e8e5292586d5c5b5efd5021d4afef17da779ecb95244e58eabecdecdec127801b5f7a8f89e236f3d444e626f822e59832e73511072111c38aa422f2b27aea325de9be50a6430307a5381c58fa8aaf9ac29471b51e84f754b2bb8696d53d85f122bd84657206579656c56a46a81ce031bcbd2f53adf5b0d64f888177b3314fa6abaa107edc574ccb5a2588f2a325efed1bdb4ce465831ee934cbdba7bf47bbe6f9e4d5174379b579d301d93c9a565c544c865d42ece164d60fffd02d54571da523d6e742634db2eb046d24467bb17b1c519cb0a6fd6687712a68a7a0962cb134d3c84a4b37e66ef91f1c6741646ec108d8b79ba321bb4d688500c3dc9aa342d9e30f13d01e3346646617849e96e777553b2f8382bb971b822cfcdb6d39e02f8c3baba02dec424814cd6b1aa4599878f812f6ef0d87cef2660504938d1cf76388d0fd1536b5cac520f2801bd753ade9d2773ea771fdd8660b5bf4b021d05045116632156767afe0cb62aebc8cf6cf3ef9eb319b549f78d6295e016c52fb3135e5784c436735064d2cb7b9660da0e6313b3899e713fab12904fb90fffda3dba6bf36f3e705d4a3a43698d5ef8b08140dfd877df3658e005101fdb7da97016dfe0e0aefeb450c19d0124293f20e5c1acb84eafb4417fbf395ff3f7a084c8a06301f82e9d17af935b0d25d3a60aa4e1e8f772f49b4dc0499aabddc6ea78c2507bdb944881386e6cdc9223e0cd4c2c28c09a53d472339227b8279c8acae45d5c0fa72aa052e37d2da71a8cea72d3c1760779bc8c5c6ecc3356a55952806df8ddb05ce2c70b4dfc8c9e01dfbf1526455c99c9790b8e94cf807b80cb87135ab10f036140bb59d0405f0293104bf69fd8ddb2b897079cd7d4eced62bbee6f27940c0904c396975ef4ccca8cbd90e74b9e26af701e7a9ed360c382c4c03612cf76c3b21591000207d24861cdef6572289346913f9c7b1ecac1c834672d99e64335cb8e96e8ca2d7c3deb740e16a7fb8536f53f2a0f69ce0ce5e1e0342bed2ef63b31e4be6b0f0173b1f39c2a1e8bf0f3fd2f6ba40568bd66e1ab7d8b7a1df566e36e5bed31fca141a0425d5431c8b1a339b2f842c878c36827633f997d0445352cc7e0b7725ca3aa2d0df3f5bcdae04de6d6a770051ca6bce957fc0ef6fb055811d740870cade3684286605982ecefdde4b265b3f006a1fc1e0e770dc82fc584dc5a56a7f4ceb57081cdae127db995fae2f8089c873a0bb91f3abf4afb0b85ea8a000ebd84f31b3d710e71b670aed013c63683a10da7dd6be7b72fdd42a33c0fa684e2df8ae68fbee14568326e189616953428114de16095e75f3931703782cc2e9f8962cabea39d6d623405892f655efb2c9a6b12edc150bba45d9809375d357a6c230cd37c458f717af0c4c47914115a69da752cb8eef4ab33a9b7a00ba9dcb92d36e996c32ec35961c830f5ba76a1dfeb8e56b491fc1a39d25f71e3ad7c3887193704f82abd2738a57e5e32daf94578f454dcad93bd6be16935331321e842e03d4e6711fbf0f296873bce4c21748bc58d18091f4d9554c6f9a401fa04d61cfba1b963f4bc890ff57862744717735717e67d01d8b928344d88006e752b5c83a41974a2932b4e7c3b9248f2cc4026dfe26b8f20804bea892ba696eb7ee24550fa6787169d3d04ab5d00963d2235148d69cc32d5c032faa0ad7511514293846a482f669df176d6d91f71f75008a9823cb5569b5aec62f7733d644af3ecc6672ace3b04db8d18e8427b48bca328ffdc11e99bb36a850b06bd91ba0d0fc915da8fa08671433bc11141113f12eb7cc4a1924b99460302be1fcff8069fec783cdff3aef40d193d75ff1795dd23126e08e519827bd545481c7d42f76715c8b484f0e7a64fffc9b7c256be7889fff0e0c93016191081e8b3a2979361c5d6ca5564388c6d25ad0febe0f0e2fdcf6cec819cc6a63ae701a4301159b333e298ba236bca1f0004a5ea1c951ffe69c9a95c5441e1adcf8d86e55801f69f2b586e0ecd84ce7bb8db4154037bf869c28206cb9534d587b8d221ba14b94000e24f8808c75a8b7ab7d8a1ddc51295add39e7a7025e49850e4849278bf91da299ba8c09c9d3eea217981b1d16f5a4f815d4dcbc0410f387837fdb4d31dad7b278c1544455aa516c2cc7d10cfca2f445c346a3b157c9552d41677019e945bb4a974e4eb7a3b9eb697902fec912f06f220de50df716ecc18b29917928f982f7eb81eeaf5d4b4a613d577eb3da10226cb17f98c67c6180eb7bdabed1df1acd8b8222d42824c1720d14142652b5a17698a1013b7b3bda3de0a67840905b54c000bb80b44431483305f2d8b43217f6c2d4fd78e9f8390ae21c09e991fddbd9e20077609343714b353f937a7b76956c770142b670c127f2a7e43772a0901e462cbf699471999cb17199f3af013c3c583ee0d7c6b8a5867c3f8dff99983213d086ca3484a5117ba91e867bfa2b334670fc73394395b488fe60eeeb7fec8b94971bf92c19bbc2a825099984c744083e765950a87d233999c8595d3f3c173534624678f5a5809475a6e3f4e572be43f2bc5134e0bc6800cac1f271c3aec750bdeda9283c30c452d289daa596b53ea39a1046258661212c17002bce1cb36605c2bfd1118a112fac641a2e0453542f1f89b2e19e301c37e9e7f7132433af941ad7b2f5b4f6fdc34119d2b112b15924e6d2ab09090b15548d99e22952716892150e863b4ab6654204355a36420633ced3b66653e56e9e6ed03cd566d38cfcac766ea28cba05d5464f97115d7992dd55c29fbf27410209498e1941b625438178da867b94502a9474d21bf6102f75ff5019de8aa65212524e8a360eca96a521bb3eb74e1ad592b996e7c908579d5712957adb6c4ae7b5ba7b9b95776c154a5ef2943e6a79c8240a4c36f8c6c8e8393ad0a4c46fbb3801915a78917fbbd8d85a58587d802b8bc6bf8195e2930aaca1ea07ae7d0474b280d0478bb7d5d0a6ff6c63914559e6e7a2afbf95fff70a95ec03e116dfdd47112fbcd3bdd72c1947b9fce911d02c0394e17b1d9c06dcd0fafdf8c72ed72e05ce6f216e75f34c5942af47557d6f48decedcef2c2674b9d03a8eb645a95106cbea64e8964d73951fa1a9a555963d370481a91781371439d5e3ad04b7109e6497fb64a383c1c9459f07dc3636538d3141fdb6ecd50f952504b495e0c0b08732e7feb68b342c6a457c48ce1484799a5745bef5a664ffad022e72b5740db1595296a2198f5928db4fb252a468fe939b9b37bcd04feba0e1095aefb1cda2d47a979d0d5029b513b83c1973c5023c5df17eb2dcb53194565f658e851071c261b7bd92d4fe6392be815b18ad3f4491ab1eb4c614933bd98eeececa7be290e474a02cce21f91895da490d3678674c12255c827dee2be59bb5f01d731715d1aa276c69c4230182de5039004a74a424b3e23297e1533da4863c8c7d4e476869064d3f6a405adddd63bcb8dbbc357586b42102b1a7daf2a5a914e26d4861a22e7c6499d88606a74658fcf0971f7a691b9b44ca216e3c061069611e6408d3ef194df156d548661c5149b06d2d0d03e22bf6058fa361a801ea7640edbcd6e1828473ca55d8f4d69d08b66d61fb3ef47660765d5c1a1f5d1fb980c119464c87d269c359d63cb99b08537e77f6f66a8c549d28134029fe54d943636539dc7512f5f0bea1e4d8502ffdc0edeeabe450c2a14ec9761fe399a77aa06b6b91da88545cc8e02812c6705b84b202c32c9862df5c4a495e68ba0ae04aac527735789c0d20160b6ef5b31b767c4ea5b8985f71c54ddd8cefdd4e0d83b869df222acefb51b63aa68492c58f910b61eac1de8537fe0c9bb15014ed4e1a2f483353017f84b2f06d58f929cfaf0654e39294054b1f0458b984b6df7af640e81b933c41cccd36f30eda0498606542904f5e83b48620396835d2cfa3f8825c9f73fbfaccfbdbfd0da4c0028094a47cb7ebc9ab13da4de9361fb363511be1eb951f6ed8b3b461492cf53e31fe4ae852a29e8a95d19392e63853605f05da998c0c86613cc46d15aee670f14399812beafe3184f3e302958467b55256c3b09dd44779f67dffa953ddad6df534bd883154ad873c134c37a73d1c1ef76f6eb25046aa8f47e7b97c6b859a2223ba0fe630cd6d604b0269d052b7e1b083830cb6373224f44f10c9c918ed5c14a239a478778b49d75c6585d3099a12f4e1c379f97b5ee1b4b4d6ba14f35a312132b480132a00b3700ee388e6b034c81e2d450969c0102746a88231f79dfe9db701eab943efd013be57458f5143c08394422bc0ca81dd21d5cc80e1e242698979814c18bb36c37c5709cbf2a47465a5b0c3d655bc51f27e3ed9f7388c0ef5effc845e037c9a2320f94339eef2092158e6f9312917df96bee7aca62c6f302df9406073fe8c347788143a1e55edbbf62e2fa006310c092bfdf86a3c7839125a449c25c7a9280c04310fa9556f0b288d99ca823f218636470b4c988a8424263ad01c84d0a0a1b80fcba1b773528ec93a2456496b67050ec143f09df7aa90934ffbc73d5d8fb951760b4dcb8669b3435653a5d5df99f0b3bb836302806e79d0555286937b85d0e8bf19828fbf617c519358e439302c996b2827aec7ade1ac00ab15fac850a0dacce2e4c3daab540f602e8eb6169f26395b843fccbc3634b093f8e0c5026a664e10590a17f914e869c6c65a74aca3bc8445de340fa2162fbd6c6c6a6581fbc104d2684daa6cb88700b975f1de9b15bc39aceec1cb2bc1a65eecc9dafff428d367c6a3897141ddefb7bd70b465af48cca8c16cfb5b811d45cec33f42dd680751c3ce6d230f5c99c9b8bb36b05402f268486cb2858eef58449c8805949bb118f658835af11f610b75e8a0198762153680946fc163bdfe27e70edcfb9bce728670fb8526435fa8acb37acfc8ee3f9257ea3611f0b4a96995f42ce402421820b4a50afdb164b0864de3d4dcf992c589fb84077902b8877e6c0c058562da84f38b03920d2a5b341d856bea58f010f64b697d597e9c0eb1a3b604bf79844e841359d6fbcd42fc9887ec941dfc3d075cd46e6e9000691bd6faa24d03fe19bd031ac682fd5e4bdcfa8757439ef7a5daa6194e852a08d2705e20e8dfb1c2fd598b8b6c790a4a10a6f8778a8ae0710994deadcc3aa47be07807d3c7864fdd032b6e4910aa1631d97428ef531ab8b8fbe7bd26c610b483066ea58ecb3cf92f5e8cb38472f8246b6d026257747defd7a0bb28318ace949a2d528dbfad53ddd6ecd16bc674b567b60aec0bb774f2fcfd94a5fa43df3a9c022537f3ab8081ecdba67c8daa4b37abb4aefc9c272cb2bc9732312e95f3e3a787f9773721c515cd9bf74b9f3e0eeed7a6c563c7b80738344a2ee7717adbce6cc34a2a265916ef29e9160570538e8ce09268cf1fde6031c5230f03447dab3c4ffd3c69a2fdb63cdadc71a36ca7f38f46f15a31a34238c320d8517911ffa1bb2f3d2fa9c10ac6827d23af1e7ed304256d17b938dd01a4c5affb5eca32997091170d953dadd612a71f0d1fb0aee51e627b73e54e48e950eb26cac3965d1b7f4e430de11becb25ae3307b0a846cb8622b18931f55b7d8ed268ed6998d192771135834f6991801fa6cf737b9f4ca95210c0803ab1494fb4d68586fe859635e271489ce3201a6ee0ccbafcb51ec10ad563945db51611ef70bdba34c4f15d3f71326f7de7a99871fc52956527136857967c70a9ae32f0675d3fe44c6421284f88f9920c97268c8a54e610c976f8aa09456516d6782a3f533bd200600cec671b63c817c087416094789132000900809b9287d984c661f84d3032d380fa1f1b5003b1bf81ffda2e874b8a7f6b23c0d7f926dda479f8c44da7b9374552379185011082ad1dac54e710ada0ab8710f166ef0d5b5b521ed51895819b7389b52401046e9ac55e30005a70c3c09b9aaab66334e95e530f0ee03ce87b7082f7a6dbb1afabd564758a04d109c2773636aa2470443d267e3921db73a2102e5a3d60fb539d4b2878627e4a3ae05a6645ded88391fa845d52eb7b603108badfb55533349f7dc58963128fb30d180c7650ba5bc4aeebd58d678f283c1162b740674546797b937334603305d6a2e6f8ea6c31782f72317a1f5854928dfa15901897e243d80b080b1803fddc7510b96eb88dccb9f4fc9cdb78611dda5b0c612fccc73002ff43be7bed04fcb880ca8ce8ab840a59eeb14306d619f51f1c2f6034ddd04ffcc9b5d35f6106b92a57d10fdcb82036059bc1b4d6329c378d19bb7cd699babdb40f02531743d19c555fd65cad8808bec7920224449baa4e471b14024d147accb8f2e0940c33aae1615f3681a42f9ca4e87090b5cdba3d42defb00f3ba247093ac29ecc76189ce71d6ad8a8087cd0e44cc9c60cfa4229c0cb4564cbc9f20a5e5d7ef4133f45809fe9381a5fc961ff3b4fbc0cf0eb26b18fbba66f73c09662407e907b330dfdf1d40152aa81fb82c513edaec32e7b964213861840ae9aa4af3308afeeb1e2acd449abaf466a55cb0d1cc0b73fe7f44a864b6887ecddad534fc0380c7c1e2314c42cb345af8d54d3aaa4d4cd6d4d184633d3cd1f8f2e40b65e9bffef01441d3e9763692b1e291d009735b3c5a80c7ada927933357e8914c49d6ab5629894caf13ee0dbd71f3878d39828c6ab722e3fb6730152cc08780ad327a900cc336add73b14d48829794f6484a16f045664f97bc12aa563d76b7630f190d28aa9cad2654ccad584c6320c7e0686e29bca1b77913e32418d583b63c9a5d874b673df7b67c3fccc5b6ba79373d688c929b1e6b8a1546a3cf9e113e8dd6bea0b79659386a78299f0679eabb3c02e5194ffb7b6f201e6b91e2855282eff037e1106d92d850362b1052f2300c77c0aa02832ddff4e544b0afec0580ce75fcca3222ea657d197d38fc31a2ea76b9bbba34d12566a0cd7b5d13e683d0ce49a944c7bad1dab1b24b3e05362bd330c3e36a676183b42045cad7fe3da8b6a11a75205e1d54304926a3cbbfb334da00a0bc466391d9968d541492dc1a9998169748ac6400abc2a76ee0714274a07bbacfcb254e5d30cb57230f4a0b31804d6c58e44722b18e46060a77fbc0abcd74c7fef56a69ba22932820139b79d792753c667fc32e40294582feed1f6eb312563d013d03b7f73486f4ad0db758e34c60eed54c65006bdcab0ce7b06e74c529f608113809cddd34d3be54bca3e02016d13a5b285fd18896208c47588b287a0cc5faeeda3e4a531d06b07dfa4444be4c956c84b35e3152a51475316004ed821c25e7508d34b4907c13210aacb41309916ed495479355bdd4709a8a0ff9f4a9dd9899e33601483c1577b4b397500245fd12992da3602c122192596b6129a2958e73807043d3fb7257b4f603bf7a51da513b0a9782a0b578619454a83f51aa4cb862014b0684223e01592ab3e5acf7dc1b434ed68a5dca88683524347bd9c35effef0d0bfd7f570159679a6bb6d274f099fdcd74cb2df260152934596c7450b08f9045238570161c48c36992aee35853634356cd8aa353af157b1f70797aa202866d7de6275f4033fcc8500cdbd17cfe83fcd309654c0f55d8f540b9e2a0d341de6ef3e667cc31ef8cc387bde28159e42531cc026aa7fa51d84e108f7bf19c5881c3bb3e39049f658f824f770442c84b3fdce8fa22c90b51212c7cc69f08d6adcf35d8dd52d266e0c3f4909817afd723bb69f461bc3244a8895448dd71d21491b9b78e3a2a0d89ece67af43aeac0e19077e956b18fc15155634cdd51d3d4f9c3d75c2d6af4f749c7becf89b8110046877df480c04f726f6ef71d00b24da23d20c47c529a60059517c2eed1177a6da51e3eabbe73639088a8d73197829c4dcac56f5155f616fd73d4b4b908361e3cccec1dda58b9b33fa7ac987b0f7aa6625cfc2c7307a2952bde2b117a8d4e7411f6fafe682de5c40e675d95f07c1561df8b0e2cffac3059ae535abc4967357e30c59036fb690354dc3de047bc0346b537583a00a9ac940237a2b453aa9340c853da8c51c39d82bd1edb8e4e80d1e1b8b106f41852e641e347bebf1fb4b6cff977a81378efd1e94daac0855dc012278709b9f1232cb4dec1289e7565794e6c4655fb5995196502d33bc21518d5aec7aa9a5bd227e25977dea08e1cd39a7c279ded7c681ad0cf228606744b64b3e998fdc8352ee41850dffbb2a7febce10a94c7bba355f1f538dbbee222aafed256153271148e7ba456a9d25e75c56d3ca740a4eda7416d001861039b2ab10bd9d8b2798ec426f463bd8f488bf2dbe1f6ba7ad1ca69aced3aa1044b3070c87a26bde94401bcc8aa0a476df387effb433b0495ade2a39c11a4cf96071f7b65393ac39c11cc5defbdcf7d90512b4eba9ec24c2008961ac37f65f41b889e18c703ac4e5e066d27171d7d137cccf378f1f7e20f23c9e2249c9ab299c2c138d5ea84e059cce437404a635d03acfd267be1ad40fd8a8258a979bb07b445a43da0a1df03f20153ae3ec2a0c91a9994289fb8df6864c1f29b4b06efbe8312ed0a8a78349b549c257bce034c71b28de080a8a64e4a5a0c4de302d410c8a23b6bdeee800440e28e281307405fe5cf5eb7ea1007d5fcde1b57f895da36499834134d265198a14f907217c3d985f54a4399843aeec79a0e819e06163229e1c78c2f1f8aa325a28eab40d532720155dce911170767f561aac640e8315818f164a0933016f1bfa8b25985f8b82525877e1458ddd2b10f6dc779b8e9a73b750565511021659f309ab131c2043e1bb9c53f2e2aa5593687a1f7ecd7f7bceed0192b83afebe96009a431d896630c86b7c564e540fdb70159a9c76bce8f61ee781fef82d70729b2762a60d848bbf4a31c463d1d90e3f50f3c2c98e86a597d44cff511bbf4c790cd7ce5ec7283a8f54246326caf61c043b2862808f645ca119a4c2b61d14681be1d4d46c616fb260757ea2207050dac43bb5905c35721f4363d452a3cdbf693b462c3906845eb4ee046fe15e6854673d7830d15f8aa23d1ce75fd7b722c690bf074e05cfd6e926e03d920c37dc4897160bcd3490e30cbd3e903c22149edd61b28009eedbfca4c102c09a64170a3f55279cd4b6981d13dfc5d6698fa37ffa02c896195dae5ff2648a88e2ac5be16ee3798436272a33c174914f1c99d68473177161a80a7ef2b5a643046d7384481217db7bd11b2ac32a533e2a182f82726f083437eb5bc1372a115f80db5a21d6c4d68d03babe8b81a57920516774e65ac730635ae94212c6bcf69c2f33ebed65cde426b8f2e8ad16c8db9ce8fb2327fe4870d78f885f33cc609386bf94dc95063fed5565332936722dd1d17435b1912a439d33f3a56cf6b09bbc6e06aaf689e92b84dfaa299bd793404bfb927f41a3d6bf63bfee9bc068ee1ed8041c0a177597ccb134151add99d253676470261ccd280674b8fbb68c9e0bd2953947ca80296244689d4d8589a630309c02e453918ba95abd65ca7264c5e874ef99374ee999ee816a3363cd58201e6fa587b111a88a44a24e418b4a86e7d4340d960007db0452571b55d755bcf61e5a9e94f4d0b26a2db86cd5c4072121f4a3266ee032252c0957adb20ccd8bd0ec85a9e1cd50ef0c24d735c87a12f97be65e256e7f6df351109ef87777a12fba916378b4a25751ccf0c7b8944155bf7b94207fc31b869cb01321a498f96b5e7ecb6422cec5a83bff548c776fe8fe8ba30d7a8f4b9efd9df33f11ee85ccbc97191cabde4e04d926171c5f530bbd864ccfe513f4018b8d6d4d649c859c85866f9b7f24730e376239ea595536011306a7763a5f55b3b7721f28e038d39ad4d2652f82b073f9a5c9e5f3b4a6bd0cd228570d5d7e9f54856135c084231a3d151316dd4e2a230992d7df2003a769ef1faab4738464ee427ce1de5c31bd4a6a2b414cf5f2098f6e26d1708277135e6903c2f59cf8f952d826688defcd48e4088abd5045f147ca7e3cd61b0e2ef6556096fbaa3631e821cad12cb71c6fb807c0083c433261acb79977ad7624362e3da9951422acfdd04d73cb92a9440f22b55f266fcc9524adcaa8bf68d2b47a308df07d9235a5e451cb12742bad508053030a804aaed1cff5926a3ed530fad8464a5274efbb6ad4aa69475dcd0bf944a9dbe32c93b0f353a391bcfc3e3824f91e1482b9037e4526f0f81030094aeb500a41dc4e249a0556c371899c26e5e143fa0535b77735159fcf672c352ce416b08fac2cc9af559a071d77caaf3220ef50294e4c222a6e91d322b468f4a4e09c80bc97ab2c3db207820e9d32e50894cca3dde0d98fe59b51cd128428345d4ab83ddeeed864de06d3f0d66c9c4a340254978693c284c60f99523616426b69f20b7bc03ab08db3a2c436108a70b2ee0eefae601839d97a8c6563f44eaa8dbfd35b7b5ac3dc59fc120a0eab2e9668b1cd683e6931b84fc658916b2145063dfedd319296b9de68c4c1d59eafe9be4bfe5bcccdc5c4d63901829ad4aa776b64de8c1cfec80ff6c2232505d39f72d28f4c14af0487ca8e1e220033af17fd3d2e0881051122eab0d9e1e87214ce583a7b68e6ef991686b67b791cb1828581b039aed0ef6a27ccfa902522451b58fe46a3803a795aa9ff9e93076e50818f1c9fea40003b3be863793ae63159a3a296340a8a8e22a44b4dc5c628c5c2590eea30d2486f4239198596d87017e36fac5736bdf325baba35ba2d2e3d5b9f3494e2fca38fd0d173ef9de94d145b5aac3357fb258e8f54284910d6482827bc069ca3838a3c6fa4abe2d0aed62f3ca747c41cb5efa5b4eb7594d0df8ae8a434382f81205d38cb869c81295adff4d518db66f18c1d74a9e2f07c97dbea7c99904a8e599103c5b65b83faa611552be5b4e01f15eb2e38d7196bdd3dc0ccfa799269eee1454dabb882109ced7905a37d4badc3cf791f73d99c7bf89b4bc1507d4662b704eaa044075d003fc042aaa7992d42f253151666e990c3b7d5222705cc27719f5d4d2810320d4329a7362f8c38ed4a9983ac410c09cf15fe4c665dbd9c369032f307167f113e4a8eaca226d5fded90737eda9fb9be9f60e4bd98285178d525bc009fa360cd146e90e11e3b2e1cb4f1d539cfd5ba95e86654751d3d1c4753f41af830fba50b322ec1df0db640179824b12a4e9564478ca00e0cc017dc889d14d7fda24d2902eebe396db4134681ba9cbe2d624ceaba47f4700209ca1630138bb48a23291b943894881f175d2948ad7b27c4feda63b9e9e73e8c93458dd878fa3b8bd780f74928f5a914c6ba775a93817b01008a6d6e789c39e59c5b0b85e5e6cc99f7325beba56dd94d5fd6e2f9675f0209a5df82ca72e8eb211d7f3de0253e13e91cf2e2cdc68b130a04d1dd854fa0f750215cdf4489fc3517e92cc3b8b94f138378e51527b983732127b39519dc27e95f677cd73b498e8a132678bfb22f0de41b1ad63209aa85738ceb1cdfeff997446f49c94d57040210b7717759c3fa504a822bc16e14840e6087921c3f2764e4a17f27d3ba4fdb074c8edc24792ba325578cb47846898a8e1f307a8a7b283f11646dd0900a5e5c986c75df600c87421ffc70230910b1834a27c87646b43a2ab2acdc2859b7925ef9de782d1fa0a6a834b7354139ed87a0abe261b5f2170addb51e131dc5a95c99b7c6258540d4a236fed506dd0b1d9a08ff1b8e52c24b5db1f782712a3303f615a6cb079e8753613a2662015feadc348671a2da674786c9b957ee21db8254ee20cec1fe64384ecd69c637ba75d9780274f4b5df56bbe29cb58f3bf5045ba3989caf00e2a0232f106a0db4f2eeaebdb7ca35adb28d874e4df9d6208fef5be54709e5b72447039fb3bea29ff789d5008bec724a6cc2226b428332c3858a2d5cd54eb49ecefe67e24291da5476c641495c7feaf4b50ec41709287fcd91f995275b0e3a2d3636e8345b6e6e20e5758f4f3dbd5c61457a924d5c1f6f4ddf143e18e5e78b9eb5595afd2e32ad92e396d06c2c0575b2912472d98d0eb903e2ccbd5c3a919f692bf14036185dfaee6447d1a9d144e776f43245b6e230d5d69f4e68468792c3f735426d80a1d4a0a2a3ffc1a01371799d3f5e7afc358f9e2c75a3ddd074fff56cd8c91ef46589d3c3230a03b78197d8292eca3726e502888d76bc37f314ed64922fa4e80af347b43e13e84f276102f63a00daabe099a8e6194e80ce208a024e46939c67ffb036879606f7cf2b982c76e895feafc98d7ffcc9270880d74acdfd96e47776af607b1a16906c7da9dd78a3371af51816a95f366bc1e72b7f1285fc2a775a63a5ad5f27c97465c7d7a4b36026627f51b4396e8208bb43c1b61d5d477dec13e8ad0ed1e6f6bbcbd967a02d0dde8f3cbc7094eae563e52ca2c7ef9408a92d2dac139fccddbec420bdb4e2143d12782aa4580bc6680ce3428c9f3b21c1ef3381e85f0c8e9d49c7ff495f8953267057269380a1254b4d849d75c6907ec4bafbd237fec07af879597f408e94fad5931ca335abf0f5e0b151bf16ca27d244898deb0fd843156443a09690fbcebef522b7e3d25d8afdbd7732a2d271966ab88810dc5e437490bda7dbfcaf203be2bb2e53a6d782762100498a7ffa55685c67ee5b924bccc082e8eb9644471cf8f7b7459c27b7f9aa98c5fcc8c28453044224688b18ccba1b01f6ef96ebd9d41e32172977f6252a987ee3d0a3ce9d994a91f406de62e1792d07031d82f83cbaf37d7ca6346cc2d47585aecc880709368137b2b4e00514a4027addb9665530ce349b0ed01c7e6a1890a5688e53991082529571bfa2cb61cab1c68492697ec65a29bf5458117031fc23a6d36b1d843e8ed3fa8ec5ca02a3669ed0104a1b839345bc8bab08c8a7815a48db7bcb2da594524a290323061b069505d46ba259c2134d49f1833a7aa5eeb08fbef17fb0b8898185c566414a8c95dc2f7db4dc3fdf6b56c0df44f10ee3afb0e429841eac11716690a8a366099b404dd8132f2246f0a9c24fc3e0fbb3eca054c5f2d351db723ed5d9b2ea7cbd7a6c9a8eca19a1ab43878282825a1a5fa9feadf75a5b9e2b6bab920622f8f48b288a22c65c8734c59fe28757ec028299f43d955f561e825f3fc025f8a11e9970fdbaa375d7d350290a481075f775c64bb97fbf7e4bfaeae391097f80cb0d64247b4e0253ac43d13c54f3da4a6905a658118deea3464afafbf5e3aa854dfaeadbbfafbbfd1bd6659bf3a5fdee8495b467832c5f0ef47ea0f5afe49cf3a89b4b77f737f2e062726749dc051fdd963ea45afa9e96177c74fa2199e88582a6aab2fb9b2a7dd34e68c7aaf451a83a66a58f52d94a6aa3a4d7566bc57a2bf37546abbcff25bd35a91ef110708702682ff0a1ac5ddf9fb5f734dcfb6591703fcdf975bf6fb78f7fcf0b15ef4eeefa745f506b8df29a4bb35af8b9cb16d73e8ff6579be9d2937dc1add4ca8f8b0626c43dae4869bffe026ad139933585c285b5a89c5f6553e59fd287f3da3af4cc3133e2033547ced79c362494f019cdcc1133e2f383a2d5427d5a751c70d22dadba4a3bd8db5abbe3f5fee25e00f4da1714b44d9feea89c3e06e0707defba8ff7e12aedb00f6133c59e49c0b22e54ceaf395a4a1fcf68c99cac237394f4103282e9b4727ecdb1018e997362fcea4179c2177d74c397f4da182c564434729a9c9023e4841c1c5a859c1723999c1463913f638a7e7343d3d26b636a357ab732e6e8404bf29a9e93e4a9be8784643adf1156e9610c167150f0883342f402870f149c12f69d737730267e5976df7df70f80d89bdc561900caa8a0f04447116f8b69513181d7e325f5b058e49eb8c05529a3c0db62575344bc1e2fa937e537610b3931b415042716a34a088a179430445d2ceac50d2b6c88b7efa808e2f57849bd292ca6c810ea642980a298ddbcbcb069b108dabc2e147df72d762e1d40bc2dc5448dd7e325f5b2b86c7bf3464841db7d8b5d8a59df434e8c5d5c3535214c89558e6ca8a2a41ecd92d6d5d42821430d0b141bb8b8d4489dd830852ccd5989b034652b36445192464d8a0d54ccd28899dae0840c4b8a0d527e697e29363c214b7345b5c18a8c34444c6cf81d49936343978e2eee0394d95d7cf674a0365dcabcc0da026ee9b6727e61fd6a34b04608adf45a39bfb07e7cc19a01eee8b79c5f58303808582b42c092ca671df493617047ecd2719938a56f329a991e96a189e86017b08f950dd67539bf7e5afaead764dfa90137656c2bd45abfd6b8397f403dabc59cd6f9c452e707759b66a069a8c34fc512e71cbed6ed2996d88b102f42ee28fe4fa0d52c887537641345a15b90ede7db74db1efd5bda1bc79aadf79048ac8dff162aedbb5cd87b913879ce66eb000005206a31eb487100e2ed1989dba82325d9a24a4eae4a1bc51d86b61cfe7e5b0eb9ce62bbc37042687fc2a5e9aaa8141240ace5bf1d04b5b67dc8c390f4e9cf6fe31bbf0ec99129ef7183a7529314f08849da75b50288f67f0a60acb82a3708c85676ababd1cadd6e144bab0bcb9bd5f1122ce94d0c43d1eac05d222115f944abd365aed10cacee9656674ba0276bf9831ba4cf759bdacf9603213bdaa7f6dec737a806178d6e62bf4daf5c02ca8905b493ca70ecb45dbbe178b34b19deeefc09512829c9c16d48a4baa955864140369df1b5307293088758cea7b64eb0167789f0b4435748dfb6edddcb47a5dafb5d206e0bbb581b296dac19eeb5706dafbbdd166ddd8640360e06ddad85ac98872ebeb1e8f7e2e69cd3f6aedd96c2849169be786d864a69064a5c45e5cd511899e65b0bb766b834d76bf7debb2bef2ca2f5aa72341a8d66400185a29bd88dde6eb71bcdd035c1ce7ced0f4734545af1ee7be78a5924646f5119529a41a519ecec56b71bd4eb93f947957e4abf5f982d13567a0454cebff4c2fefab85937c9a1d2f70195be5aee5a56b2c7a1ee7c740e1c38e038d831dbb4477393e835faf8beafef29da28eebd39e8a2fef925a519549a01cf0a6e3c67150b79696ff7766fb75bb53071d03aa4a91d0a19888a9dce4e7befbd779a419db75ae0817fb7b4bcfa70b8159dbe0f57621c0e87c3e170385c0f5bce59a7bd5f79af7bffad73a51b5f5eb510faaa531b75a75f2751f54dfa6855a92798ac1779bafed49f4b77e23e80a0af6bcd3fc26954fb701ce95258d3355975a8fd4836f5af7d13a5d16aed50f4e2579246a3353d3d0505017d177dbbd1f6a3ed6bb6772a7af1e7124d3797424bfb59f4b5f740f434d2c9f6445f13bfa8e8c5f74044fba7095f7b4ac90eb8a7914d448ffba6225faf1c75b9fa63add54a12bded9b8a5efca725de58ab8db5a29ff0fc3b0cfdf84af56f3f9782bebf07a0bf919d74b272126939f03bdc9ef61d8438e0a7644e02f7e9cdfff49fca71ac51f81a85afbdd3d08f3f977261d1d0508e74aa3d85272229bcd3f8439cc4c0d08fdf812132c7c7ef000532c76b148628100d9113c82132c78168e8e7128e1cd2e5f8cfa51ca79f8974736928473fff2c431aad0b7d17fafe4eb7a7715d8e93390cdc5e7c0f42fd855eec2ff44eb4bf8124066e4ffb0edc3a20443ef5db2b8937b289f70b22772299e3607bf1ed5128ea288b1c086575ffc8428d65565f98346101855fb45d9243dde5286082fc5487027bf4c15e51b1321296292992db92390adc69646d4f60ed51e1340201221477d033605ef8dec46031fe6d2fdc1e931f6e7c3afe2c82ba9b5b0cede5fa8d1ea85205017e18ce2d18636c31c6a42f7cfe6f778df4ed910c451d2d95ec96f0f587ed40d4dd7ca1137d3fbec0264d30ff43dd8501e9e8523834443414f440a11d62ea10f4408f491cd013bd07dbe348a7dbdb6e4336d2c9f6b707babd13d007ddde36a49b4b4d410f24f44a35a41d887ec8369d887ee86da493157e27db0375c06487493a0d3dd1d013bd1310e98188dce4b64739fc43987cfc36db0f914dbb098803d02bd59b4e48679581b964fb205d68bbe982741794007d5d02229b5eb0d45fa9761237c55a73f225065a47b795930b940f1a9e5e2b2717a818bb4aa795930b9489eca7d3f6643970ce9c7973f6256e9dfd380f11a69cf5c05cbb8f665c52701da259942ad02b9cda5cdc4c84149a09881914d8cd829cf899d9a082c1cf4c850aa6206579feb060125266830a4f589e1286e8c8f3c5060cc8bab86b90d6ef05953be29336584f17cbe03e54b67c65b5a092e409951e4d628477a898202ae75795273ffc23fcc7e12a49e9ad412948e9cd2313a696eeaa2dc5d9668a29be9fc39189524c290e004e9c20cfda7dc38145e13832d91b5e7b6fba7bc31581bb0feba6bbe3426e7577cfb12a7461a2b47c8276eb9927ae75beb5e4adb5d6ba2dbef8565b6badb5d65ac95a2b07435acd0eadf6e2acf9d4e0dee00635e7390cb178cbfebb8903c790663b6ecfae75bf74640a431a1f4a69ad75ce79efc51867ccabd55a2bee5ab5d6f4455c67b3a9ae19df39e79c165b5e851db7faae02d05c3bc510dc3e4271666bbb734e0bcee9bb9fe79c734e5168de6a734e6bed9c939673cea39d73f678425457c39cb3b562cef7e6fbb9acd9c46c0337aedb2320df53892badcb0b304a2918a5144c0718a5148c520a16a6038c520af622ccd2fd276b900310647a8be043d8d61ed80028e6dea9f4e8c5f1061a84f7014aa208bef8250fdfaa6ec7ffab64d4143383fa942aafa02620804b4b522a4aa5a1572dd45da75410b8d1e9eb3618d640da9c15ee8351b8db6d252dbf5bb3f97bb2907842706580fcc8c0dd2122feacb1553295051414540baf3317b54b252be9d7b26a81f6f4ab9ddafb6a1fa892be35d19fbe25627b9fbdb24a4afaf61754faac960d5352a0a76fc582de67e194f4a7cf9695f437a5d30c6a06d90e1e2ca0c890b3e4a3475c2043c5151b5777cec2967c540925ab80133153c66a7841a2650d99971533376e742cf96a901aa6fa2c8b925a1996cb7a95f483828282828280de363201d96cbd7f6d64eabda8acfdc153d69e3632d568b41f47265afff3427c6afbf2736483257f3a2f70dbad04c1af3e23f8892ac1391f00293a727ca4e0b240dd2f7bba60d83355daafbb9b9541b4bba19747673b25e1e1e5a30f191341f48471b2c36c2aca9b38f78d972e3d6a34e7863e52960c9516f666490b367fbac070d84231d666cf0a162a7043a84200ed8c7856bacfc8484f910594a0270b8c4f16570c967cbcf2820baa649070e5cb08ae104b3cc9948d2dd5c3a2ac5f6f567a84d4825918170b6705fa4433e7c47054e2a7611e7f58714d12ebfba9d6151cf23024f57afa1c7f06243d462f866486db2aba75715f05a0a95e734e250dbd241ed2cee88b70b72e5ec8eaf4ad907bb1bef7627cafc618b703cb6bb2d6fa5eadafa8c59cb31815fade9bf3bd99b62f4d6b0d160324ce6fe69cdfcb79be57e9f7fbfd7ebc5f591818dec2f9cd9cf37b39cff7222589091be3fc66cef9bd9ce77b7fd70bbb9abfa2c7897fe3fc66cef9bd9ce77b77bbbeebb89d984cc6f9cd9cf37b39cff76ad092722fd6f75e8cefd518f3923480956daa1bc84371c4341a8d46a38de3388ee3288aa2288a62188661188699732e66a4e212ce6fe69cdfcb79beb7df8ac4e4369cdfcc39bf97f37c6f6f4f9525f590947ebfdfefb7e3fd74997bb1bef7627cafc6185764a45bfc909234e0ea5c9dab7375aede7b5c52536bc7e3f57a3f7a54b536dd53eba9966f6af1b47a1aa2f411e08f90ea4b51f66c84d4872fc55bb2d2a2a8b50643a1efbd39df9bafd65adfacb3d6fa66ad6fd6fa5eadefbdfa5eadf5d55a5fadafd6f76a7defd5f76aadafd67aefbbb516c3300cefbe5a87e1bdfbeaf0eeabb9d6376bcdb5be59677eb3d639e79c75ce396b0de6acc1c8eec5fade8bf1bd1ae33742621286c4fbdbae8867742fd6f75e8cefd5b8d7ebbddeebbddff59084d3c8c72bdabde38a8a8a6e4560bc3c762fd6f75e8cefd5183f4fa3f0da89377a547f6ffa3c71abf042dabde370ff3bce6fe69cdfcb79be1709090909f7a50fe98d90c4783dc9e2fb78f93e91f63e5a99c1be7beeb9e7de6bb55aad56abd168341a8d461bc7711cc7318ba298b3b8f5bef98ae2e7bcb7de3767310c2b40cfc230fcfbd6d63073ce6bb4f6a64cc3ee38dcff6ec7e3f538bf99737e2fe7f95e0d1a3468d0f01a76bcd2a78197a461af084bc2fdef76bc7bb1bef7627cafc63829290997f4bbd297b4432a73d6be247eb1c6fc62ad39bf5883f76aacc17bafc618bc142c4c8d071dd80f7a99a9d6fa6a4ef7d6fcde0f33ff9cf7d6fbe69cb9eec0967a829482e2b8bf507a815ed8f6889e9574d76a61cc61de4f3f4f3d6db57be691e9d2a3fa9b1a9595ee7cb8d2671481a212d7327f36da7bf37df3dd7befcdf7cd79efe7a48fde5aa1ca4b7660cfce4a0fc0af50a9072005c2b3b3d2d7a4f5cfdb54821f625aa7d5e5d5e9aa70ce0b5bdf7bffe268b7d75acbc14b36e79c73ce39a7fdaa70ce0cb5d659ebac348359cb7befbdf77e50ebbdb7fed8b49782d06003663ccca33b565e1ab89981b9eb5f848cbaa5aefb5544a7000c7a4a7982525a8dc904cc0af76fc7b8e38efb05f69fc06675926f83127f68348ff4f3acfbb9c34fb5a63aeb8c31096493b78ea557716f7c6fae3a0e852a77d983709e54df8ec53a0f0b63f42ca65f0a057ecd30a55795b2be1297105f501dd77d3baf5d2dccd96b75777befbd18aa07e5fc0f74198159d25961faa863e134f2f55a75de5beb66aff66faed7927d4d589f6adb3cba936350812ef3cf5be7d1fd3a31e424a04bfbbab43f7107f3accc249d156e7d81ad4fb856349a4225f534689e85dfe24d0cc12487cd0e740e7f875bc2975eb203c8ada83f7c0ff945d209fcfc21f8f927e9941f04df49ebf7007ebeb9ab75b94b76f89c3f249bc0cfdfb45f73fa1ae4f977be5c67abc5a4ce872b2907b302fd5a3109b95ab8bc6f5077f95df409e5cdef1bf3fb6e129847b90782e0e34010247d1c7ca83b107547ffc6a7df4b363d2d3585f43548d2d36d1d35a8bb5cf3dc960cdf03077b4443fe4d561dc2175fc95ee06413051766486484412df1cfc0e4fc39f902279c3dcacf7bf628ffa52ba4b6a096c0c49d3dcacf81259cfc5d9935a80bc85f5bd37d338cfefdf94110041f04f5deafb7d6d1721a65d204536785fa437a010475efa2e36698f175b9a93af8e3e7a807f04732c78193390a7a183283248aecec6c097c0f9c73b0a9043bb2f401010a8a74b2ea809fbf537e0fdc093f2773147c0f34da7b183999e3007e2e0334e7e1c91c05490fe0d7be46cea5a9754af6488bfa413d974650377bf6283c8d0bb8e4886126058d28267af0bca8b886c0b96ae164cdd94483e206cf0263e30b892e335684d0d3af66852df56a62a825f6eac3c18f911088d8a072d586ccc69d104496ecc07141e061286460263e6170aef8b8281185460a9d165bc0ea7829416b161d22dce653d0c4c7d4941c297a8ed83370342082551656141e5f63ee3d51a646a77c4dcf153b533b688410d247068c2324b8a9c2b36f703327ba8057c795293474426061a3038e06115729d470d1190335a7b5b5d21140c4d070b30576e2480734579a3c21db03c34f6d73e207b7704b1b56e0c4e08e99b113bccc891d988483034e1834584ebe54ba2b951332403e3948ce3d813fb7b933e9eb7705afa4c3a74f913c5d582a2c99a93d1df0c8a155428ccc902046df47cd0c1205e55545366606cf982938b40dc07820e1d2c749151638b10ae748084676143931e7a70288181b095d497cf41993c5450970ca40e0ec919e23374e60e70a19167b82ecc0c1c1d81051d3830a90255e4660a035ebb70e3a429c18a16a9327cc9419d00263b8cce64c8153e28a8e580bb4a8b8f25244c9949a09660a8a9b155c59586682cca812457c636a09ae5b533f68d34f082fc66821319324c597291cbbca559d1d6366e46049ea73f3e2c25921bcf944c2cb1629194aaea40133bd4cada87df0c3855995b1116cfaa4e9be5e2b6f1a8dedd8c346c50e32661cb242f885d84286a607ef323522acd265cc1b144660904566f4444e1d2e7ec8c81192ddf44142e5ac0b0c332db898f093818b1aae255a7490cc104507bce83e719762af423420c1c6911872b030b1f265a26c1c4dfcae6c718132c50d1b1e9e3008fcd1a2b145c5620d19be45835e429879ddf8814546f443a94fae3a04ac534c58c926b43406cacb01829716322dbc507999784202860841c8a0802153a7da9966f4c2081943b6b0e4a003c56e6931d1836785980adb5223471409fad4e289932c116a90c06162ed94408343d03507cd1d2a35c8e8e94934686298203c3d620387122c78b6e84c99594a748929282296a70e8a1a7ec47271e63c9814655bf4e8300347c9c652424b4d082845c280a8b032bbdd14f0a297b7bce1ae5d6144480a086040162682942f48c2f02b256adcb6d8d8c305889728656c645d5a42c568e1e21927451d177bcc8ce16832ad942001d600fbed0961850b9a2eb75e7778306f0d9d5276349542023934fcb41053652b8a7749b129a16b4a0a860a1d39a642c841adbea80911064d922126661529242fb2fca863a4440d319d47ef687afdd2a57004ddddb1953a5360e0f9e5f86d308e54d538c308923e574d4e600182598c76d288c1318386ac8b4b4a45b670f8cca94a23c28d3eb382d0026262a89505d56cc057952e5f9618f192e25448fc19514648d5189337584a3c6e56e0ede93e1c6e62b8253cc9e0a233a74ccf902f1a7c8bc4d895254fbaee4871d1a2c5fca9289275d504ca0514fa85ad9038a377602ef45421093b237237afda2a4aa5b29132d2aa0565002222e2700df901828fc9a790b8a29523e01af27b72842beb0ed90aee7c606d1d33768b44915cb548aca861a0952ea0059912949c3023424c8b441416c0588e2258a6aaf0ccc8951555ad2579cc48e888e1234f6da38747c04f96ac335fb4bce0b180383c3e13c32c331800a4d66471d2c525c2889935c20cd3991d7bcc708c5539c1df012f614c767b9400157aa95a18592310c1f233060a9a1952f2069a009931429e3875a8ee2eeaa298ee13c52c628eb07a5336b740593191f3a607151126c71aa143b7e047086f7e70411146cb87ba1341dd55ded7077c82ee6801f6a409913d5454b6325a606250c68091b3f9ef8ae8d3011920564bdc08d94a43022c6d808cc1f86285c918c5139042a6c80871b6b2c8d85146c8d81f1053d2438b89951e6146464c41bacfa8ac6fb4ab14572feca58ac3c29f1237a0bafe5009016584147ffa01c6879aae3a28e868fd68aeca07d5998f1b5cc8267f92957744628080670c8b8e2e77d7a4926884eeebf6025dda3d0ebb18da7166ac44095b58679c44d5790a92250b4c9a165b64d4993c32dd27224d0cb9d2991e88190242941b47beeca112c54664c10db039259449a3e44bbe958c85ab4515d0d5444a981622b0ceec26515bb669e7c79c1f79a2f0a1430297232b729324a8d2f2f77b13c2961667bc44d1c144c40f004491d29af1430a888c0b49494c40ba2fe9424ddad84ac9c01aaf355777b66881b1246ac8eec3f58746d61454182495f2a619d7901950be623c9932b992281f398a840c1c547facc4fcc9c9a9954ffd9a316ae16acd32c3a2a85e830db2a45230e14203454c480fab256ac49ed3858bac8519235b515b45b09489327566872a450de1e6e9aa45d41cb03c4068dc5d319c12c8b080e2844c8f924ba336d1136a00cb903b25d8d07073a64e21d305260b11212498f1a016499bce01ac245578aae8788933e5c9182e2c3c5eb0ea90a0267f1d2631209b42020c123c85427905657da8d205c2092d118ce0a1b2e4e3c54004978ab02049c2044161c5a4aee9385fcf5a2b2c5d5a5c94988115c4c50852f21483126b23078b1e1779f0748056952e527af2906959f2f1caef502bbfe222c28a6b40116248193b64988c2dcd7db7a5554bac416ed7094f848624ab6357e52459aa5d71f46c8c17d345089a72a8e4ec1bd92c43332a000423170020100c08860462c120c9d2400cba031400114f8040665838960763915020075214c64008833010c4000cc318649c831022b201402eaeaeabe8cfc4c7118253ff80fb509bfe77cbcbe70caf2aea7dbf65886a20cc5fc52629be1c846eaca637b94a878826eb05e64c85b14fcf74a2cc9a1538d617c93bcdebec14ce2124d6430c468a6e4411c92e0ca78add500af2b63a2847d718ab9b2d3b0e7a48e80221ab14ddde0bd207758a83d3cb8a61ae939803415eb4e5996f49832798ea5bb860d0a8d13cc879561d4200a24e13f772d13a4bf749d61440d9fde96b3bc27d33149266877fd19afa0bf74bad62b72c52f468ff0345e5209eab2e7cbf773ad04021aba9ccf8e4d969cb7f50da9eecff78556e1425cd02ffbf938626866e31f5e69400f27439f2a984b8a83a4bc60a6378083b3490c76f4e4da6100d2f78a524f887b82af210d458762cdaffade2329ab81ace6778df010c0e7df570d20f68da9f5f60b0071d192ed2b77324b48097e1c934c71e2e06034e1e5db92c60d634914390d4dfa5b99cf1f8dd430fecf105dad9cdb772576bc411f97f76b2881695080644405d045f7dab7cd633914c9e9b551d938c3a40e05d908016bdee2ffa9edad0d0664cc046770774ba4d96170d731abf06685a7938229081e0f3e83f3a11f663dadd608407564e848337d29ab28a3023c72d118f237cd4d476fc574a6e93c0b3bd0fbe6b95ea1e3edd9b4d245597d0b3a8283cae7e2975e29d228fd9c92cea368f7e9857895c4621ce82ba91c8cb2a8a4f6bbae71963a98f82e9908ea5903a543d315106bb288de0e0cd7b38b9f866e612236bdca296220aac48b033926a7e3edb58daeaca2e3446e35db2e82fd51ca23b9ffdce3da477c155db2232e40b8e8fd43eba296fb367ad455225dd8b140bfbfe0060ae913cc5b1139106682da4af713b91b19e1fa955e18e154b35c7a4cecba870b1186fb3a706f6dd38b0150df6a238c1e67e5ee9bafcddcda1dd478882ba54ed3796cff518d203bb73a878bf1d0cb318df3159ff97a17e955c281198375ddec3633a3a6949f4d49a3d0e22aeb97475036771ecc89cfbe16864203d1460cafd25bd93783ab66882ec5c8a77789afb089056c716cba0ecb718e007dad77577f355bc43fcbf373f9bf176351460c2340a991c31aecb8a59dee94ae10ab18e1e5a9f17098f8fbed150ae950cf649fdbf38a3af29cbdc501e990cd9fff98ab5d1c1da6ab9f024d5ded1f7612c25a34be9bd8d83f559e9624a49efab646ff1d39621a545e311584beaa42b870fa590a23c9300708075de5547014c20e73b020ad54876de32f49a345ccc5de0fd2d23d43463da3cd034c65b17bf7050369a7e8b43045bdadd2f741dd419b18191d9126f820f60db20d4f20ab85545030e8883e45de59627e798970eae4c6f0fa45711f67b6f6c346c803d671b7d6918325b7a4f3f5403a14786863643ad1a4c187ff131408e4972bcfb775403d95c738c6a726cd1b03bda5272dde7b74424a7e48335b48e1f0e7047ef157d60c946c75c6f095fa0aaac10e723b05a0f40b87271a06e930d139f8197920240728cdc4f656af12133bd8bca2f465a35d4a37bd5c077eec893864856062a08c108c22aebfb14bd496130483f92aadadbac5082eb2d4b0be561250779baabe0bc00244761f099fb52fb94a7ebc67a43f782cc2ffd305283818c3475edcd17c431057777a7909648143550591f94bec08a166303a186db6d287cfa9771eb5b261be5e9072ae8a61c5a402555d100111af3c724d8a02d583b0e2cb44491f83216b2107f912ce3eda189d696f0c9da21d1c497d03dc1bf0da0a05db64280b5408b1413b2d37fd9591049b78428a709abc116ee34416838ce84a8b114f15d1b78b69f5d237f2bc533d6f32e5ff291d12c64a9db647c8396b8a18784d48b31a1989dbc849d544d848c5c4ec9656d24a3b1c8eb72f27a7d0b80c612f7c7f5f994630834854d4b59ce5a8ae617d734011b7c8a15d3bc8673ca271e1992317a7892e29b1996a309645960aae2f5efe180209aa8d074e2d5c3734bae379a512bb65ff878d8808e2b719ce5df330287c7d823b648208048f5178d1e86438e2647cc98030fdcd91cf61503d92a382cc15548784c7fe0de97837330229a90cf89737a709213efbd7ac688595a61caf582464e8d12a49a3287b7f355e4b24c6f8b2f4bbe9ce396705e8705edbb264081136b0467d5b8b3c494392e63786389699ede25f49401374cb7f0cc6df8bb01cc382eb14d756e072fdc0e203d5d5ceb11b5595cf369753c6d3b879e9ebe7cb757514a379cdb49a2c09902338b1d8a39383f86e2563f26304e2ec2ebdcc4b1446163e95fbf988557beed95fb8bf38002e2b01b4b1ff913d0b396076802119940d066d5d10490eaba34a6285d8684c7cdb334c29eac4e32ca33d5833fab1e02ba4026687b0c7ce23e9b9d957420e915df37ce511f54e6f53fb7c033a648121a764f2b268faae1ec77ab73716c7f117c36ffc710fe61041277dc4eeb236a12c39e99a6163f3a8d0033b906b26b5271af8ba3e705c21d44475d8923ade714d3e99ab489a48b8c88923f7d63a45b568e2e1a8488abd71348200d2e5c22ce7c2e1109e78e1f72370c3561f7e13782ce724d3a3f7fbe41734988e54e7daa5f61b5a94459378412d619fa289e4f557fa7043272ec740baff64cb96b17b35c3a044353a16f6a3c44a6880ef80e93e0c1eeeb24b04039691cde73ec272cc2017de904174e33cead3e843b5cf298070938f33e83515760949ead9b6470af67d68a8b5c6046cba491e6355062e2bcd5b4063553698c52a8cc052ed661973be4d2689970f73a4705e4df5c3a52355f1eac7a06bb63bce11ce86446d4ef4faf4e01f2ed59bed150402ac7f7b8298fd9b8ec5017adf56e45dd2690e3528023ffd49bdf3aa20c4da6773cbe96dea0ee5ab4b854bfc19f048b5f7622cf43c1a1b26a29716af7d6cc45f4af45d03a46d8267fa6c0d77412cf80368d07970966636d421e14a0e31b89d0e700aea491bdd0b9fc515206c24920d558d690729657e62de018a4321e574b1a3c71d31eb4dcd336b8ba56ac35342ae2cebdab57b8f94e6d99b57c1e084739b6811c80e177310f71cfccb43a3011859393e01ebf96122d5fcac14bc761978cd6c5c915ac93c4b7d0b3c253197681cd09c1f91748381743e49b921162b06d5dd18c3a849a546caf8db88532dd7f6cde502cf4a8b1e79ae8b43eb7ef2d41bf0331947e3294fb9108c3a5b7cdb438bd06d4217df2c31a032b7e3918c09953cd9a84e5d92ab13a4134ac4d74fcc87bb00fd009922954b666bc33c4911109d9cd11fe13328f69a22d0e63fe7de627f7b940fe7bc06c44e538250e78a8d05ef573a2058ec0f463907aee1544d9715be3f4baf468a49a62a88859c59654658b9cb4f2ee1ffdb47461c054d180a8cc77d58f8aeee5ddf6e00d9c5f461009bcd245073a4849755aaf0ad3aad2c0e8b3d49f5488a35e6f9e8ed729648f0f8bac6733c38b4fb9809f2e9aa34eac64ea51e6d92913458045539f546c2b309e3a3f2f968016bd28c9677437c7e864d2595db9d6735ae826da883d498b15abe18b28d11ecc3787b6c54c9e4e283eaa912c891f6fe0a78b90f9af23c9c5c797ee382c4eec2c1016a1ad103f6ccb5a0b3c51925e2205eebfb8e3ba39541ccac854b68d5aeaf62cc5519e92c99b969d5eda23abafcccbfaafac2d34c5093b968ff6c552c07ac59558e214a7d94ef56ce2c17877f8aeac578e16b0d6ee85b065d48e565792875886f8d60d5a39c9552154c4e46c80569389e724b110751d96a644050cba5479cf72282fc1647536ce9b4d6fdef93974e18b2ca4e9a5383005d353b1a50197b50eaf7eac1de76440cb32958308023bc638398e09df844522e35bf8b9e125dc199f31e546f6e948020e6a2a6c86809675b11c1776d23254972711cd6b5f1e943442377f0687a0432a3f44926089cc8130283e94b0040a247ac16c11d985f609858d59547266552483e37d8005a9de669888030c5816f344e79141e0503b2b7e7a6cf745a1b2b63ac04a1a9d16c609e27f23979885a75f5c0cbb7e0a514d30bcbb22271dc2c67c3ad065a28c52f1f9bc9e1e171dcfd236e9f3201164c8dab180d762fc45a001057d03d6a59f4fbb3bd73993502f2e8dda64bb90ced3ff4432e73d8a9760055596238b753bada91113416b9aef4d064a6ef806144b67f7cb4c37a05e4e55237ce9b36f12b094898b5986c2b489d2bac09c546948fb7a22a7506d747a55cfabe81348c37849bb18701dec74be5532620f8865290496052b6bf20e76dd2b578ff806dcbdbceb8e1cef2eee58f025f0e0b21fd312d310c5086b7fadb31c29d8db9785b1a204a02fb0d94f142201b8a006df71d0c9d5d6a0a690c3ba33cdd56e52ef314464d3f4d44682032e7a797d47f0ea120c0585b64b68b8e703c042839f461e120e82902b8116dc2ae5f08ed06b5cd07f965719c261ef661e98bfc748fdb07ab81a22239bc00ea2c3272639b86b234af3f034dd3ccb053aac794d20285e76f44ae7a444ccf8349daaa50402536a39fd56d5a1218a99e2fbb31bbd8193c00e00cc5363309f74c57b10d7b2a18573d715647a8ca8784a4a578f480aa257948ae9616f5b145dd6d071699e6ebbf596ceed571c341ba1fa011997cd49003f024ce835f5a93282a698be54790fb34d9806d7ffd0d3ce8bd733b7b7dde8c912776c9b804d47998fce0418f4e1fe370c0874e923ea08470f23e75f8ea653344d17eeec40f4042817571e12a669d597ea65e09883ffa66e0937d79a65fed0dff170c05d3aa7528c88eb9895fb47aebbeeb234e03ad52a80599375292dec8cb0eb275b7fd3db98b2eeeff390c158473b9b28b3356744f042ed532ead4b0a9149380f6e8524feb1d3586b8033dee12a5fd1a3c7c50a7b6e4b74eb2049c5348272b53cf8ed07e00e296d0fb28a5d3dade6748a73d5f708ab14af377cfcb32d747e14a9973b2c62c750e1703cd8a40381f67caa035db3a3e10c3d5d50c3e91390f06ad3512706fca963bc84d6e5cc04d4383b283a5e80a49e0c4f3123f7f01031102030f961c5edbce59c13e83cc893bdbea9557bbbb0fbec310012a71303bd2961e8894e464ee3b210fb0808045a05938e08f595d651450a7e3910024e9fcc1257913015f0d5b9b13bb1722854171006177f33768d4681a6bb21d968ac8f3341b5a75aac9f5267c92d3484ebb624d9b7272461dce529543764bf41b4d7b8222469e552ab66b30d941ea33279c5854bfce8d75968b94397192ffb24afa403a5f994f8b839a2a81b9b4b60de88850a8a4e360cac5ffbfb07d12d788629280804b81ec60e998002b7e3323663bc5042d86ffe6563dd872702632cfbd00883865560616700520e1b7d50de9a481b3046a1e24ba3f886774d8090fc20fb0fe6cabd2c022cb361447bd87453f1eac5da203c05152395c1dbf701edb542aa77ddde9b4f5ca888ef5c16c8ea5698a9643953a84c6e2a0a9c8de69771c019578a8fe7e32f1b349eaa96806689dbe8e3364b9c19d787ba2188b3d564dae83b87081628e2201b2a49c8a32d18f4843d5970c3e96890f0e8c3d0d47df842cb4157f3c7f7c5f5ed1b577579d71810bbdfa644e71b03b6a086ef78f0e92bc300ca39a32167459683c60c958637832e687cbf3e46c53f6ca204e297b4bed76561976beeb65067f85339f0d1bdca78cf6d788b8f93302c68a32293f2ee30124914c60eb2cad44f332bce596f66c7908822636434b0d48454eab12b0b68d0e749f17827c8f8b0ad6bb8ece4dad1de5ef302a7cf00fe5bd2013f5f2f81030883d321a49533266c76eba47bc3a2c8211ab5358ee1abb4c408a84cf806c05ee7280164f5b15582a1253c6935e424701f82e6c43836a44118b3337d0b46d8a60e8b66572adbc3406e19f33b877e23bd44a98c3be7277a0a2a93cbc51d7b0a7509a5a70f20c11e379c65505311d407cb09bb008faf5e41c09e6dbec50860721dba6ded18dba916086b4f8649b5b107c2ec137119edec80d87d53a199ecf646310a0d647010c54beaa2a889184ddf843697b4619cdee898599d881646b384d5c26cc22764b2ef8555e0694d0b3bbb526ff88a29abd98f43ca0f12ad460040b25f955820469b11270cad46d1b8e849a5c10e02793030a5afb1218cc2ef843b015cb19c7f0df1c61d9a3c94ae622b619f21d70384fbc03af1ad08ac926365be23217fd049f5434e02b900384dcc81210c3f349d0fa14dfa6d6607b71a95709365f8b424c596d0f6cfa4587393c964d857db71229b88ee8102d307856d0c51c4c2e2e47be6f5b035a22212fcd36c5762c1cd0f5f55ecd13daad73735b0b17d47b7cb396f2277e9acc2bf352e97a649c4501227ac2d743724f9159dfd4097e08350373511df79824dfd619fb9e5bf162f137bb3c9b6e0aa7600dea756975293c1c8e1b1363198cc4ebede62a07439c6a2f745f147436b1f521b8f8af89c2fcca2c061962c8ac25f1343348ed456e65595e120c71a18be8435f69f19cfd01f8af6a6710cf2958692b8ae7fc0b04d1983faa67ed4ddc5742643a10bea3123e547caeb0059ebeda349ce3048085f741c775959f1ddde0b8bfa52b77a15b0707031009a048e91e2eee91096ad95687f970871a6ae5f2bbcc4759d35e41ce36e4e64fd5de66d2dc99006273ba96ffb63a9af7b0584e4057d01df331dcc4f1171d41112e61f211b2f420854cfd4445a55ef1bf3deff265eaba1af3382f3c32d1eecdd19c08c67a2a0c4e2850c597e255038820ec43aab689320ef5a55dee45245c035ad2ab46926dd193dca0442614c86dd3cc0e2575195e3047dbbeef1e932a2a4cc23c47537c1907312c6c14ea4459d824c04f5ca59b9b1fa1e1242661a3465c75aec5aec5c77047650f0dfb3f1f82b3363689a7f94e9428d88385f218e300d04531d8fe0b945c3374f4408f5b9ae8643b05af9e48e6bfb7fdd9025f3a635dc2d403a0f69cbba75b8e76c4e3e09d4bc088ceb292252e769a296b90f236326faad10f58834eedd7cd60abb92abc8eb215b2c57b3888b51d082274d54f9375fde9f8462532edd9dd65b7ecf685ce1c8b40d6e7f47a85b9b9e5ecc01c451db39c32dc670834afa5d2060773e43c743fac8220e4a1ea31143b085be0782959d34ea536134f7f94667e20d49368ce3c7328c3121aca0cf9a24db276b7097a518056109f1bc8aa2ecc95f8a649f5cf39989c9ffea2a840bba9876927f9c11e9239753793c0c32eaaf5e243a54a67c2d92925916213a8201cf32a89bda80364ef657a876f61966ba89d0154f092e8c22da9780297c0cee8e28028a519580340c08141acd0b53b65ccaf10615df89e25ca780642b9f2015a7976ac121342297fa0f3cc1ae6bfaa31c3a51330324c8cfbd7c93c760b0d2a5ed06cd0a0b7a23afd57ff677e6e07104b53bb2b026345197aa969aa0d84c4be6c8d280b90dc182b344f7bd9c650d99e0100faa8c4520fcf892e42eb3097815123b9724df930a56b9438bb9004b097600831dcff6f2fd2bc9f43d2e52a2130bc47fd5afbfe009c8fb5634cdea59539cc74ea3054ca8664a2a49f07c9993eb99f92b95a298060f7e52aaa88b166e4be6b4dc986178de8c65f3fdb3684ab97454c057c172da7a5108a0aa78042bc9585ce4da446188c5aecb8184cc887e856189f5eefa3d0506d6f26cc67f0279de33c491ba0abfff1c30efe9436583098c3adce1f4a2e9b60eddc1e0f8f98b209ae8a09212d2e76aac32f53067311e23b931c3bb596ec346c2269196175ed3204d8cd13279a5e53ddd18e63301279ab8c9dc4a37cbbf6e2478204e78e33c3b6113c20761e44d52f724aa4a70d628c47de53bf10896232a0b265b8e30f03e88406bd4e33aa20fc316e6c9d584030a586b92ef825f0cda7a821af1ca30dbcf0a9bc04baa2476158d6f5ec177a7aeb1ef78f883eef9a4a7fd5fb9c51b8b19e1a3555365e8c95ee0e657d89cbebeb47a2ad21d8e5574a44901619b3a4e5e57f3058b36d3317e122c863bb4c154dfa87d061e3e1f4e74069cc120eba75c616743dc1ebb0e1192bcefc0d4b3999b0bd39110a0e4afb25974abbec30c85f8403f3a74368c6971d3f096ac1d0c305aafbd1381051f3739ef07ec74b8ab977f05b0bc1a1af1b346d61d1e712a660413075a191b997f347fc1aa9115a7f2f8476e925086df11c311c7665aeb72eb3307ea734bd19ea3035a091ad27403253816f172995ef7d54bcf2abee44ef6e9beac1805c18e77863bfc4cfa828f2396d96f14eb583b5e335b0a8fe2d724e5510c6666a4971643e92fca4841b2d33e8713e573c33d531c643c9f1b3ee5d740851ddc48ae1c6c3a2da76f2ff3bff6bb3afc5a2c3df901963e606c2066c04bd092222520d077da0b8d1c83723c842d2156f94306085c606ded8e17cf885346c7b87db1268ebf5057c01f7bdbf275d5b777a1954e0d46ae4c819ec69243bfe270e22f8eeddecc11edb65dab1d1adec839dac2354e5fde6775828763a37f4b5579ce6d30b453ced773a65adc297b3e9590dc2facb2f1aaf6750ce1f92462faf6831bfb18ba74ba6c16aa595736b7fde01bf066401f5b996d3ea1521d9becf31319143d4f6fbbffb10d711a62b70c0b938702170945d86d117b6d37218b44afcba88c95e548f5063c56dc8a2aa08f146d8c3a7941db6e12b4513a3754dd487d120d0c4aff3b580063b8d69993c4fe1fc040569ec01d32a9834119670e3c8c12549ef3dc2fa1e40d9f4caff68a1967d528900c55fd3f752b8617f03203f282199004a6bdbed182cbf73d17672d3cea61ba9886f311ddc255860809f2704aede2dfb87a7b296c0916ba9086b3a5b279718065182a29a49e9adcd7931d46ba05b6395c99912d73c1161501a25b3093d845b0512b9e19271d1ef018cde0151a36d6dae73f5fc2d60571002c2682e5807d84ef6b03b698019d233e7512d085d7d5f99656be3a92129f04a2582c6931b4d6805e47cf260c54f8ab933ccb84e8e019c23c6400e5801dfda3741c14627fb0ddf3b429c63b16c7986552f71c1087ef80c1131d840000177872f2aadbde83774b8f6f698058380f61ac396ecd6c283cc8f5b551bfc8978e6d8ee8d6741d37124e5f60f890c4389fd1b9a6fa2430dc24b1de40500bf7b323cbbe8332c73f2387dd6f5197a1e5345e926bcc880813579a1f50a91df8813ca8eda5cb99de51b02357fc332d8e750b9f979ca30a6cb9e0897b1abb54200e4988264a83707b7b6b7286c3df54e8be8fe8ffb31daf5dea6090ddcf5f27f42e161604fd7f19edda800b0e4c261b58794a2e1a79d687aa8b8051cbc79f633b33511b2dbb09c22c13ab71fed1cbfcb32fc7f51c7265447be5ced7b45dfcff91e4e80b98e6622cb6c978c631eb0eecc799351c2912dfd09f266e9178da94c97733076bf9ee138c96bd21c954b61b1c29772111fb0a722bb079a6959a5b9965a98bdfbb9f1b8fcc7e6d4e1cdc230d76ef1c31ba3f1d5cb3244374fd981a23e649ece107597361a3ccf30a0f2c980d7ec68f839fcce71fcb0132b840183732353efc76710a5d0939faae790ba4b5a7fed84aefdc0b738fa811648de4a0787c0f01e18a8c98db7343c6c42c876660626d35b9f2353f488a039dcdcb17f1f3199b440d0cc52ce5193670c60be645a1b7989d116510cd19af3b7339e3e3b971d3745cf97b58a50b31cec86d4961b6426a99a76652c2448ba857ddc1c07d37dbb7a241a8957440a79a06eaf1c45f962ccb4e39e3e285a9e82efa58db5c9895fe4cd8cba839e70b07fe1766ea64766f82573386eab674a5132bfe415da59d2ab3cec3dcc6a1f957abffbbcd273fcc79f5e291bd8d19109b02761e03149e467e4adb5797042f144c056279ab1f92519dce440eb9d98d3abf552c1ad27388cee27212e4021ea207283396737696f6c0b51b76ed2605c15fb283f41ff23474a30bcae82afe7a3099c2e13581ee6c4eec5dca6adfa7a1dbedf19bd77a356cc104626dd1872f4de66dd2ab03cf0de6aa627c3efeb2899efcf6eb362524263e0a6cb6dc2872f6fdfe7831638cacf7050a8087fdc9f77b3d31c602d62c2ce4fac27898108b1e9e8008ec97c9a342c51a81a827a01dc7cf0683d52b4da4c2168e3c3fb277e5b44473cd4b3367b4d3ad698a52495a487ff322c4c41a4437c0d814ae97294260d1b4ab5f8e4eecd00f759aa1e40467d134dec35dbb1407ec5864d4830bbb9236dbe447e6b3f2d168bb1d4a562c12ed1d048658f85af589e70321f4a97b68b5dc0954c4a8d3ae70e5c6bfcf2717f784c4be8e4e5484a62cb527902cf2d7ec56dd68efbe09c0b7065f533a92f498b963e4d5601fa44a310bfe302e70e55e44243c38b93ae72c10b5ade2c4d25a5dd24b441bdb6af6e98d40918ed2dd69824465cf29d3c89be559c5ef9f5c504baa0f0cc419ccd7fe597c0781597f4a110e3f1f427ffa9be06f4ab885b555cd05d71647134eb5fe02a04dcd14678e1471ba29b76408be083603482d5d8ccd4c098cc9e882fa505c051eccfdea7a07134a204bf716e2890dfa85c243f4876138a9fdb4325b19ed88e9aec66fbbcbc27a075155e7d1ee4b7fc074f9faffb2fb09fd55724ab6036e385832c2af61c6d8e8045fa3b0621fbe57a2b3649f0f97901119c98f519b488da12c861117cd79368a8c8233d8552c6e359ee6261174e2199474a03ac0a9e7a810a652b91849f52cbdcfd4bb932c414b7834d1ae7256788bcecfbe411719d380c85444e31ae9557f3b94904a2dc7d53a99c875f49c73ee6d8ece37d0f804542230aef226b502e4b0dd7dfbe4945b2ff0e61e6e87bfac08bd842d22296db8dcab51b9d50529c1da4a8fb3088e331d2de3fe5488976b7730bad865ca2e5c3dbe78863e2cf0d00bebfb9154c4774a676535d9e6c464a3ea57b11f75a9ba94e1710b88a9d697ada8274c0dca117930654b33a313eabf4fadc3ac9e079134a011c67bae1c3daee0d8c7ce92f0de160e37725b4e6280fd78488966bb5532f43459c49f95a43d495aac55e81d83e9d92102c874af7398a6710db73cc0455d0b6381ecec6dbf736e338ea3eae5a5339bcaf8fa1cd9cd92039c560ce785393e6dbc79f2b2f4e322c98018e86cfd4560268928d52d19d172ab95085fdd921136e73edc09bb19dc9cdbcef7b6ff8171827e29c0321c47885b0ad2e6184f48ecd7424dcf2d84545ebfa5a70d133e2166681f7c8a198ae21b6233959c19f3ae0671ce82a139142e512e69bfc878cab36f6f5c0aa5a9a1b88f80102a112182fc888e55530d71ff845316c251cc6cf218b64f5a518c9286d4624d875152291866142872c662ecc90fe73f19da621c42fb142e2be9ea78dc12c0fe245c3361592fa1421a7f6b7610f353ef2ab39cf1f3a30563cd122c7151bfc1fe41af0af9d245f94eaf3cfaf7e79279fc6b79711d25175f606c4abe1a7e83c8945dcc43de5047be3831ec63918a5e66a82b0cfd76b781ca8e4d371b3f425b1c7b9f5d7eeed0d62a990dda2a7fe1fe2516875599c00df541a0e203c1327011e08e189f808fbff2daee41151a1217b575d73299d6d9bde22c5cf48afe07894c42537789bc947570cee465e13cdf65e16ce4e9aa24d57d0f5f5c9d02e4b4e250712ae17fba3b06da94a65c740e7d3c29fd9be112a56836c9e0208fd7293f7ee302b17403b7bd182e81c11f9b9cdd4422a68be1fc715243383dbe0ef444879857ae1c080f21c36db75377412a15bd899d4d1f0019aa8c6a59d740e70057b73c8633bfc92e52334ea5a50c61b0032072cce68a732fbd1858622db3319c6f1bdeb7798d809b183ec3098e8dfd453337f3e52ce0fdf830cc0f9feb5ce125442888b1bbba5e2779b6b8dc826e4603d888d7c722c56871a231d3cbc061affdb2268bb1b208887c276611f3b52feccac1cd0d2bdbeee9eaa8687b9ad37e253ccac302efc6d1eef3b1c2ec5eff3a57961d6c44b43b4380843e996f5532650433e481c16389e693e2b5d5b91cc60d04f3374885902f0e32b1e049b85aa9a553085637bf55a3622081c6ce439069e54b8f654f391a3d5c16986142a183b6f011baaf9eaab4259b7b7488e60d88d4c344f574dceeea24ab0c2a6eb650953daeb5eadc788f488b9638b796dd53652b2c9a087d4668176f105025ae9a12049da199c027b9a9706f5061dcd934b39f15d00bae8bfafa0d3af7dc05798cc6c9aca22c68e9aea703d8fd4b0908457df2e4385caa35605ed109e4e7f0fd8181e6bc70a9397a663a3adbb9c348f6021c812e1114610a6d8c6f097819ede8074e7727b558bc81d3a3cbe50acb4415e98ce26ec9d78199629bd9d090ee10e686a0c91b5aee24b592224815af0dba67fc9164eb9652b8c7d0fc1025c67f9bf8f78e3e8637e9e9d56592940949b2ac9c845831204e5bf8c48a0c5aa5d43cda3ec68870274de6851fb768457363e5ceff8b94760b3883e693be7e8847ced8ae87c94fc2e69044e163cbe1ae8dd1a099908965c0b2648934411d381bd55c9568751d388f7d558d0cc087c152044dbd7e8c4b3de660def06cb164c346c38914cd688592218a7a64cf65f5e7c71d7fc1a2c5f30abf193a8c381e7fc2c70771c145ef55e2661a2d10cd48f3b4467a2dff030a958d2701cce704004d41d80de4e41d60e6b311f7fb8a88abe51b70128974a9c34f66124dc300bdc46978a182e27f86a9757d80ab28ca7371cffa459948c4b93858005ce478ca69614abf90bf62d95c3099ef6e3739b966be59776ea1069639af9659c1528c270011cade968b2619ff5e81ad9015cbff8566d1ab0f75ff9b0ee98019c42ee9eacea82266e954bcf662ec650a09c488aa667aa9ca898da73f033eb4ebac4a2bcaf19ab529af4efd4024baefc28d952a8277bb3756e31f94c133d54481a2fa85da605e562a0e8963171a91553142ecda4652e1a27821438b051c85b94962dfa4cfe2c961c438b6867e8d451fd29c1aaeee6b7b9d0d563798c9bbd8690cbc1e79b7bae8e507cbaae846c9bb1db4043a6241959da48ea53de5e9eff7ff6e2ca8721b1ffd2229af4d490db9eac6804cf9bf68376889f4d6dfdb6155b33d7a1ec800ef56ab9bc8e40d20486a61bd0841cf2f2eef2ec6095e073b399ce2f9c43a86af27835d7824bc00e3258c4cabb9953ede96b04ef00b62185c99430ae420b1dbb1e187e97d779d69e7199823898e1b270637818a7226b9619b0c025190690d1fa6c3528a1039c625b4be077579ea790e9fc1121681261001082bed042d39cb4a30cb9667492000d5f12a48dbb11e1cd4a99412981e014850de0868defdacf1c22f068a3bfa7c8ca27aa78595cb3c48260dbb4b2d56df59b95e9ec13b91f0a1512d05fd79d179085c445337b1400c0f989d22402d5405531192ac9c3e3480005d827e03de2b05faa156705c11a9d891ee58d87f56a3d1810495766db20e76ee4808c5983eb81079da1ffbcf0ddc2e288053b99bc4eb97b714ffa28fe07cced4a1db15726eafe097230c3642c740fa57c18d875d6cd1064619f527ea76ee46fe8cb36ef776a1f39e6c19dc06b721bc0ec8f3449c92460cb6ccc3aa7b18325f23329ea8ea861f834eb69dfc7db0cb814553724089ab316421be448454cc460b5a2e369988efeafeefb8f2c72288aa41df4926f15ec97db005037903c35eafd5c58003c49d72a3aff42bf72710b8fe74f9b0e231c63ab8550d4026163bc989afc796a0a1b60c3e89c3a898497581372e4af5930a1b82776b8437a0e6ca48661be07715ab492879ecf267fef6aa47cc181d5c78f983f6f836ec34e9b9653a8e3af41e1e89942cdfc191063197ed90b190d158f19aa124f8058b24a1593804c71df839cc07151c023581d370684f06290488e2af10bdbbc8fd1b19b11e9aeda79e25b9c2226c6ee8d69bc6c826ff56ad804da1ff70162e294ef03471f1af4ae6e96f1f88f633ed6dbfba35c7320a8b3efde124561047e954e1876375234a3a8b8afe70d7dc7919ce6c42a3e432cbfe9f99c3ff56b24aba148243848a76e3584815b4caa2a6a89f466e82232cb72c07dc0158f3e1253819adf03887d025389f05657a46260dd1f4786601e896e9c2713f10f46586baf3b33af6b81fb87e9f1007c2d97e247adc8f059f77cd803a1a0acf2bd9d82203427f6800e9130326b41a86a483306046befc9798c0b97659f7056c27442d1b5ce7d0191a12f864b9054c6bbf4a9c75bff639025e636ff6db572295b08823643870aa62108f84947b73a35ee621eeeb4b5342e6e711fbcc00218c341ee777c38c8ad978dfa9501c2c63a268e9c9317120c58d0caad49c8fd2057d8290066e314e30d64fb5b2bf0d999e2bd6a952e145341e737f5a450765e6e778341bce4534c018b96637af1066d87d40ef2e6bf89efc4a34664a7d87d13ce12423dc7fcf9360e30404c36a7207fdcfd4f4cd0c16eac55f43ecb0858ce9ee6284c1888ab838135531cc7b656b368c6710fa0b0780ff18673bf37c9abde372cfcd2942663af8a13344569308489d9b183d43aacc1e85d5bb70df9e338a62e2803b3828af6520d610363132cd74415cb397d2cb7e1be46e2069ca05f8cd3cb8b0588922e8b2a998dd1cb8b33ac93d29aeb729b665fb658b1731ee6f86d2b30e91a61350c2adea749b669fdce8af12f0d4f06c1135e777d4a1a7a4b8805948811f6ae7032a583048fc07a0aa60a81669995baa6e968e37de369b192052301959f8798e2bdabbc8018e9fd36dd43117edd191fba5d8ce40a02053ebb37bae198f6c1f708805405d620c4d28727427a29334343a6065436c506b64e1a2bdbf446ee1bafc9212b33a8d8b756f97b778380d341ce84973fce3bc143434048c84d3a84939ae7fe6e176ef730c69442e431191ab662d93846fa4c2059b848b24eb6a519245a94000a61d14ede7f653390ef9e2af5a8343ff2c4ba1630d7c23ca1473959b1da9c73a89f9eff8420d3a89b89670d022cf9b4601c8c4a83527eb5e85437277efe39c76b1b81b133b2c501fcd83b35dc909746bd71d8aef7c8ec0279a401a940990d8f651c32d87913774e3bd7050164f9183484b526de9fddf183390bcedca1231df76c63eb541c494fd4db68ebfa5ed32b45079ab5c46f1c31a5f9e44c3a616982e9f8ac71f2eb7be05bad8ccbbf7e158646075708ee4114ac4a57005ce80cc374243f067cb485ba1aae2e7333c98b35c9f4b211187a26aaaaa84d52952404fa2ccd23ddf67dd1a8e24ac2e683cd75bb801d376f9e8bf2bb5e52d0d3ec700a1114c9a55086ea11036dfe2bf1a86c7293b69600765bdd08f430ea94ad6825e8acf623f9aeb67fbca71f7ab14a142dd69e0da62a66a3b4f03166ef9012827c90228701d624fdfb2dbe498e989436770cf46fec6a3c8d7021d95606c8e7014e90b31f2eeba7768587348bde1280f8a9633a74501a89086a7d65ac572391c9d4318b9483974df8f1239ecdc1737b5182cce3bc6953ddf6a83fbc3192f4463ff3748435c790f4e5909066994da53946a1bd88f0d10e5ae9b1d9f00aa6c1cf48c7f2852d025acfbf7e54407a772708af7c41981af5d02da2662a71f37c52ab55c7e64f154df123726ba7b555f45694e8f3f2593ee2fef104df79b00031fa82ea132f37672e2a6d5d2e4e074d3b2f25bf98226d9f086ed2bfe963e8ecd664215626ed4c391818a20843516ce51f2b2038c9899cdf40f3249adffd8968c72424f7a40070fb9e4760a2ff760fb355b388611e7df7c52e63d71f2a3d40402e9fb14a2ec0d3a30648828c1fc7e83bddb6887564c83ed609db60a131b21cec45f8a9c0f6bc9ed6bd248867b4159a3d1e2393231e4995d22c75fc6a87558508cb0a96e4612c0632701a6409c7d4554870b949f29717fdab4f089641b90f4dcee86b05379bcf80b88b12ec1c347430e05e265e0e8a44c5bed589519c6aa719d638fa7882b9301578a18cc6ba0d8c1a862c06de041c87f80b53a50d21884f131aea2e69af4d7ee2a5abff02618b6e5d733b04d6749833d61835d4c5981ade832d4b5ba5ce5174c355176df342289dcbe323a8780d86e49bc9bd3adbab40440d60fa538211e65e10c83ff3931085af9db339ea68e601fbdf7097458d912908e394b06b1ef2a7a38103910c82ed516e40aa145dd5d14c898c6a1ca56aea6ea7dd18bcb621364720ee858b326367518d6bd694e0acb126252a85bf19a4211d4f9b94a4bf7fef1017e3b466bfa5e4e3baac4f7387c6778d116bd7c118b3ee4eec56090d185c5284aade38e18a8fdb43554b3cb0d5613488eed290c012c20d1ad77ea399fe6c572a6d6d58f487c25ec8183ff65f8cc4d5d7534f825cdec552c9778167a65d69dc7088502e11f089f96fef043951adaa37c8558adf2278ac39c83ef133b29889ccfb29d0be008f74fd3d2f583a7699aa95c15881b642d926d02cec45603512a118f26de10912cef08aad0eb908a485115598c7d15f3dc54228f3cf839004498e1e571a6c0c446940f46dd42fc1c2dbd4e1d992c288f9140bcba2b63a5839d627e585e02fdf14b850826586ec12c89d29b088cf41b71d9ec5b90c893ea404c58f3ff4ce8866d3339bf333ba74aed4088908abb214a7bb1be10f56fd7270d8cd70b05e1bf0f14247a6fc88ccbedba7df444956e7f352209a4a7c588b54e275e3d4d75aaeea447b507ba9646996f360123651aa8e2e776d25e5e3d66c25ac0de777cd5274cdc82665c5248285e9165c8d8d4c583d3ca8ca9c0cfaa07cd4de88ad6aa9594e61d6a1d19648386b7c64324445396a958583f5c28202f5880dbc6512e440afb848e8ec7114344ed8b55950d9360f0b63cdc874b2d9b4e51027c6e5f44946f796d108a84b0352b47e3380f9fb1b13840901607d9089205c29039ae9d941d211371468e424f0b4de6a66f2bf06a309d5ef1a4bec519dd61b1730247ae5dc9d637ac870759b093c70ad946c8978d441b43611589572549313161d27a357a5ace143014eabb64159be888539aa7a2b2b0e270c0d740ba4d4a7edcbc5daa3c64285615b7f229f9155e060e1ff56144b9ba49ed6056f9d5b255cc49b2e78f03affef1d28a0307d13a13c2b87661e39f3c1b7e0978fd5d47532d2e1cffe244c624a9ad247666287c5da8a5109752f0272f89f30aebea1940ece6c0f5f3bd759a6d0cd28a13f0272b52ce1ff86354f8d6da32eec04e82e4dc1025b354c8ef092b533d1895f0d0e2b97e7ae1452346739d2188dd14b0ba9f93af9782e35f9cc49cb29a23bdab3f56e54cd9da52d309d9a2799348eb10ae50a616112389e8f79b0d4bf5f30e1158acaf42a3a70d137f428cd03e7ca6a650ecf796db5085a38f3326a78d1e3ea246e88f1f7cfbe5de3a3173c4b571c78f89113ac287b4152a87afad6effcd288d531af9ff3fe7a8552ce8a89b398a9a5812f5b0d31a7efcb74af3b15fd8ed73263b4e3dd11ce5eb45660c638e42aaa8c54c36b322a488996c2fd392b364592b1cca3d7d72c985b66c88f030199b126f7b1b39842e7ba264364a0e45401592cd5e0eb6f8645ab28aaf0c2f1c14e54a4af6b1ccd348446494790a52ed0ec5fe83bfcb5f4d60dea55283fb9351ec7c053381dd0676af15451216ab48c530a3243965080cdd48624706e840bcb18480587504f26e570e4f46127168557e41ec514c890127b1c928d641be7615c6d09a937704919f822d5427986fdf130cbaa09a2ffc8cad9e4113f62934ac4f4a2e3a0bc42dfdf868ec5d1c3698b2f4ca1063b1ed35c0178d381c76ceefaf93e4971715e126ecb8a3de6745b864ddc9cdba84cd3692a40434942ec105132b886b85cac663ea1205c9131e45393d8b17c8728f233f4c3b34ffd406ec3ad75aa22f684291561a111bc78b9c2ae02260fd0e674224e63ba03793509ea5e76cff0036003f387a79f09309f54220be22c4468b1233a5dae575debde4b10898c8813d83ee317cf9908a0e915ba2aa9e2f7a8e61b23353c8091a3aef0f57ddd78b3c87edfb3d8a1918f9b783db03580f5506b833be41291a85083e8abbe620436a9d359c943bba747bc4d34d8f1c20320f8efaccb27fb6e887c7246b51728067497c13d417588fde6252c6e9dae78152aaf3d85359aa128d769b248773394685c2f1540a99dced487be0c16f2a76dabf6043d0c59974f6ace0ec4d268364a51888efa102d2e8fea603a26efa82fd322fea359b6f671033b00d0ebbaec1fb1ac3e82b92213641d581f2f3d20ffc17a11c33d264d29cf0de92332a97d8a13023a749550e7fb0598b87929cec5295d188c3ec4489ca1154d86e8ce7b1d2bbc4dd907bc6e880a9320b12286025156bea997662765781386db424b71590a6f0067f6933d1360e2896e0c9789af01dfab63f4c60047f3387720c865876a72c5ca32c6a2da740c567cb266b7fe139f5b3beccbc1fda2fc721a5e10604616e80cd9cb4b4609a91cfa2f7d9a2e42d55d8f5765cc42fc9d8102bc87d9d323cd7e7d3ffa61e22c16c7c5acb4e08bafd4692fd77d82d48eded9d4a26eed1a786d8fae806597922ced03844853f8871a77338e38259379449b670305628a53e5b0b9a2f6ed36014530237a28c047f5bcb6dfb8734b95757191cc7e094828bb76e0472cf1dbb46ab8feaf4087313561be3e2db80b6778731de3e4407d3acbc5c63e6171de72bac6d9f382989dd24eef994888ab86c01da63276618c14314799091a2934e3a675b41e56f81868307b702ae826c8b22c6e3f7677d2e89aa2103dc29cae5dd2524a237564d5489ec575c64ecd4e15a084787f1fc4d72924b7ff7e924ab4655cfde41712f437e5d7be900e52d71bb4794103e1d73a4725beb145879a7062d9542b8dd8ec0f741882b46bc882edb79738f61933f4ed70d8811fba361c5b38cdca09b1971e44120898599004e43f245744a4c4e6f85a9208a89ed13407d258e0b757a0a411f6d443f61974624a247a58027fb05c5be9245c350c16fee78d447103a1f34313469d682fa7a4e6911f97bfaac723e07ed4e978bb4a29ef1a042cbbfe212f6277d0e19383311159958a717ed1442289ab1a0a724f3f5dd785bcbc6d5a640ff067ee32b5f70784bfc10f841a30f12aa8c45348bf969d5223d1b7a846d81c8b2b78bc7a6f55c4d69adf1ab2edfa0e9b445b269d4dd36d801f871a8488590e1c864b87b2c4a3460f9ca727e1bd23c8acaf0f566a4d13ff2bcab3c4aaf99c046841c5a3fe1da5496c8a616ed8b4010839022398a591ae131915f48876c40cc28c60e62180a57678521028037208959cb767783150c9689a06148c9c9dd8bb14463308c538ab6f033b3920f7d36dd376c45a1d4db5ceadaf1df6df824ba391c7b610dbc7ebd0edf20af4596dab34fea6fd56acb826db6b8fe21cb8ad1cff79d2f1c32c86dcb0fabd9b04e86df55c98f31d62fb18895239ce640c929c76933ab2dcca8b4c8d8960f4fe1dbec711277d226a99f2176405b191d00df744afd972c258724c2695f0e596557801005a722bf27822e62a6c97bf780c01459a0d268a04a1daa42fa3d9021af49629ec819febb0cfc78d976362dce3bb061ddd24c43be6c8788261cff13643a80cdc1d1829d9cefea93549b8671ca5375080af1d6e3b41686a33ae92729f9fdd08061bc425999843da024ac6f37e638feb73d38c93693aa2db935fdb3c62e08d36a836c25e86c85225493f50771fb81c1f352d320c86d22450e772b7449c91d60e04c02e6a6852cb566345c69ef831f9304c159ef48fc3a304c1a00212c7f695ac8dc8558ea310005f1ab65ef80adc4787fd118cc25260e601557b113ff1b1ffe478539a64d568cb548d03cab6016232158a4818499189c1b7f2399b8f2bc77b5ee834c71e893bac609935e45699d03ba073fa0e125e1fca699b0450446a9a47863d25a47b8570cf3886aeeae5de867b72b93df3f6133025ffd669613012a56fd03150913139cd31e8253a7c7b8046c4262d11a1cad5e692ed71bcf39ee9d26d2dbac29944682ed5016af0ee8d827afeb67801be87bb851ad98b9687a184c9640ea5c5461fd6d1eddc5419d6ad07e6f0c90225a2233a0fd38ef5c6cd50ae10760c1f6403fdcf71a3e83a9701892041bb810f0da22d7e9f4ab6db090be4e4ed558f88a116082594677c1fa85f775d57635d694e43eb4e21ec8800ea683b3c0de1278e7fc44bafa436033e3871e0b38f8930cf5fb1e30c1953db719aa58cea218acf3a8b095e5060bd40f3c402d34687d745f9eee7a6c9288b2705d7ffe962ea8d059473079735a6ecd9c1bd1f4a36a9e20210ce1bde8f5b74a0388c61a8aa56edf2b0aef737e3df0c3cc3438705b8aa8777d31a39ae650098bd8dfc13be1dc6ac368cd17500e11a3331d352ebe4484051c842d7073b12b38ac549136380ed0218310c84bf3e72767cf4b1dec7b63d5a3911593a2a8cf1c5454bc9696fd8705d97a54002610954023a4368003bff7ecb8b68e49dc19b638ab6a970809fa069e680c7a6620898a533fc3fbed3f14026f79bf29e53e128bfc7e90a98411164e3cc30e6c6a4e8d9f3b01d145f42460d060879ba0861ab9992a50b850efe80af5f4cdcd384e57e98e12ca87f0cced6da40b0244547953705e3536b6c88a5e24a3a68e4c3bec45f4935380d08898efa176ac6a8d6a7eb8e599f7e17a9fe48490dbd23a21dd34954cd457441fbaf57866dec09170d5586f977f7cb43a93b1b8f29eab8171ca31437ecc12943366dd863d3cfd2f79373cf9b4ca0bab4d5f1e30903874052e0d6afc2b489314268b17eb3365fc89869aaa8dbfa3fce4b258d99d288739cfc03b1aea60f335a482078737cd3e0c7c59fe310cf3c4a4b931ca14fc3885546f597cf6d547500e96b3421df8d94ded91418aea45bd7cae5cd66978d083149e032b7ed04006a20f01bfb94992f4ec240cb2b8a2313381d5b91a20e37f7084854d9ce443ed0c663292819ed2a8927bdc4e06b20d89e5074966179b59a8b0d4b1279bc5a5975e92b8b35f14c875c628fbfdacce8167947fc3c41840010c81c62fccd54b813211fac10f448cf432aa7f909aaccbf877675b94c201c44a97387198d54f09682e2bc04db4ce4bf55414f3f6251307dab1d4d4dd67e2374e317fb76ead5cb78f89e1888792e55ceac5aa5eb15aaefb72b3eeef8c013c7b03fa80868457204cda4a072d6644822c9c7ec79279210f48ba2216b84860323261eb3da988ee61ba5ea711c3c8a6839e7473be71015cbc7691d537596c6396e339ed1ef1b86c9804bd1edab00f1d6872fd7c4b4bc8de7bcbbda59449a65d089108020845ba70911ed6a8434e2a1ad65c911e1a01417e1e9e394e3e28b2d2648146ae70911ece8e203f184843a721072b4e480f8ddc90b3aa089715e9213e42f6982c240d876c2800228b8b7ca2a44f00ccfff098285ca2480fbf28c8efa7873262b4da072678f0901ed6b2c88f4506330c11457ad8e4934fbac5c87e0775c58a8a8a92423aad8f5ba9567c4528c02cd3efa0b3ad327bffbbb6fbaeb541b8ce76dcdf6bb7bf96e3c46b37fb36dbefa0a2eee27383fb5d02e1cc2c26ffe4269f50b4f97f991bec5f6bf5f2992203e0d499e34e1b33644012b8ac5fb4da88d95ac2954b30bb0dff92fd41af3c77fcecc03b623b603bc0ef2ff21d3bbcef37f21dddf78fbee37e3f0ddfc17d3fcd776cdf7fc377d8ef5f8a85b0f0c3316ce2418fe6a447f5a908fa08cb9406731c7670d8c16107871d1c76704ce151cff33cef19f321e77b21789a5e4f30f29152998f4d7d76f5c066ff9acb99bd1cc1c4f281567b9c26107cec3779031dbdd4481d7e1db7d9da35f5d979e4fc6e8a439ec849c134d83e52ea75d6da5b1548a9577f4b299d7466a5b4ed04fa4ef779e79ddc76edbdf5de4b7dde7b1bcf3473dbe6b66ddbf6be6ddb94f271ce24426ab64fab6f4ead95c1dddddddd7dab1cc7518e738ee326c7711c575487f87a4e77a7b4565aeeb191bab78de36adff0359db469ac7c7ac0679fd65a6ba5223ce5497d76e0cb7d76a562d3bccdcac59dda0da4c0ee5d423d0edfe720add5fa7cebb4525aed06eb3c8fdbbce9d13438ec24a5301b4b8b88fd017d94f938b58a8850735123c11a89865cd9cb9d264c10790a813b4d982fb9bfcb9d260c965cde0c83e54e13464a0eaa138aef7a52b7fbe6d5bd525c65f4e82badb5563ce6ae94525a8d989f3b1eb3fbf6fd3fceaf2524817f6a802dc1b12717e44ec345a76b5073168005e8d30de5f90e8238480606611fb7503041094f5875605051d6c3aa70cdbd85c29239281ca1c9c89d86cd9c260dfa913b1886e40cac56907a09e4504a29a51998309dbc68065c824678345265f33a195d34098f4b5b4786a094524a29a51cccc94e23255fb2bf2de2733f437d88e359511b8278029ed9527202bd94523f41a648644a29a5d4e8ce8b335e1ba57406791215d14459c73e40a0e22ebc3ea26f371f0c5812f0a40fccebe08479f0bd08f48a2b72ec67e1ccc76c46e979428b9c3d144914ce7c107dd11789438c8020891e8afc8862efef307fd85782b9defa9c58d2ef7e0befb45169d7d53bf44d5e5b3c154b70aab9afefcd1cdd57a92477e628b9bfd386d00bddaf3e0a6ddfe43e0a8973ea4e1bf4bbd09b36e83b8c039ab716f58764e1fc4a32a7c21ad2af4574706963c8fe538f27513d330710709c7ae8971e0dd027a3b21e1f7d4c54a6e26cc2090d9e4f34e149a28c78d28c439ba02f92500fb4321527d7d4e2800a2e27950fd9df4b204119e883de7dde7fde3195144f62f11ee443d76a6d66750d88ae71ef3fcd74ed8c500d4dd786de7f0ed135d9bb0bb184ca2e6a18a4de20f6836c4f9f0b83704fff8641ee07e99ebe5018442896e9b70883b478fa436190a1ef4692854164ef22c44f439fafe18683c219fd9ae9b3086714a86ed6a38c6c29e09891d0a5845ee55345978a7a8263ef3d2c1432b3f7b3704863d9a04216399b421259696145df3ac1ee54514e9e50ea43b4cfe33951ca8c7ef8d91a4f701567d5a49a8543b617ec70fd400e79b27a7a4c1692e893b8f026fe98367e4c1802dc732a7af402fe3ce5ef4ea2a43cd100f4ad1567485c30101f874caf24564491b3270a87884c48a2ff1a08d91c2afaabea02460c296d709d45ef5f4eab2fba0abfc9172ffebf01451f8a2480f145ff22096ef001e38b9e0431fec537f9d1281cfec3b0e8bf67b9871f7a153da28af1309ecaadb8f52fae253b0c304638ab1fe3a1c8591583f880f131c42130c4a6fe4bf4c8bfc9a22f97608837d46ff245d8248c4d6c72eb30a2a2a8bc6a283b5580933060844e154595bccaad4f5119792136bdca6e5dfcc0cc5ee523ac8753d1233ab874a250070ee42c1ce252504a58423ed1482aaf9a39baecef35fc20c0b4c163daf01a34648530734ca5dbc4c44d45f62db987d42c9c594720c14512855f86fc26ac03f7a86923844945959c0810f72fe716265426740d2f1ee5369a585d517995cc6580e9ed3ed7fd0c6b087902e9baefc40dc8f2fc69e7974064b9fbadfe0d4b5abe7fefbde5e7b247d7e20664b90ca1fb12c4cee5ee2705ec1fa3def7f752d689976e62874064775aa91cdfcc032ef773b945ae690b052e54d0e1091922b85069b976a4aef86c90c70d0b414c8152050e402de0b2b1b4e04c21116a920492395298a820e6aaeb94a0888f0a97198a70324396312f6410e56686b81244e97542c10bc99715154a9ce8ca0649155ed79b1968b892268c0c4374fd201fbd16e14672d2ab5b3765de088930e5083a5dbe88a8109502233f7099202a89152b98c1010bd6e1082580e012d41c13335d55b8002706297a091350f06448494d61c226cacd185cf45544691d336c5e4811c1224b4b089f226c2c103f54b1689347892d2545c4aca1d21e9d13c87456c43c41a60e192f17a23053d34c21d4ee17ca8529146cb150a607203c2fa916be0044a1b0a58936327079522f9deed50722403e1c845b31c8fd4d2637124aec89038589269210a3dca0c3151368a8c8304b012e8328ad779240613126cf1102073d727a08a288372789091a6bcb962876c29c004ed59ef14e114e2881e28b1e29cacce0c9f9ea8ab0b480664d0a54c8c963c98c600a365b6e10024b6b89122734b1ed9923c50b66b89ca002875a7f082f4b589922a2ab0420fa0e0953605ae487234b5a5801061436329346d6992954649c5499e2ea84352d7ccc09562c922a991f6ed8a871a14a8b1216dabd385c05f0bce99263268a3759ca4c2f514ea0a45025052b27c0a9d225a1250618b644d163478a7b191aedc104363610e1460a263cdb57580144a0dbd848f5b7f082698306271a813d9763aea1376dd4af7103a68d505019513b156456549a743501a34277d55f4ce410468d1226dce12104689690c107384478b5a922668f1798d5d6143d5e5ef22c12850c971a52d8c1090decf9b262052553e6309912e3339b6aa2cb04512418e9b680582778010924174a052e2e479cb9da9ac325430a0d26c4d9c14b1e3c5566563725654b4ad6d60a57595b56b47c40c7062f546658d205072a350a686aab062ab78232b50505cb1614a9d693a71112a2f20c41979b266caccab8f0869c4f86f0b2031e3a4448d14095a8d3a93b45a848a7e2dcd3441138a487b3305d4cb8a122270aa65898223d9c65b9fada49169395a70862272f5592f958bbfbe047604a9956720ade077f04a1fb96f1138129756a778fb3a8d22ff5bbc10313e3a7632fbd0eb8ecac0f9c07c632b17c4a7b24e0aba4db174b21dbe5dc37c8ce71224c262c78f3de3d71c813e97d880483e0a30f1f4324d815c0919ef855e012e320fa3154f0ba8b9f084cc14e952a2e00fd928e4d7d9c774e09622b8d2a9e2c5f9a3b5579981061c2c31cad229880e3644f913d5d8800c1584f8aad2a82c818e1b3a9105bb2cd5027834e4e407fa092658e0e7680008289deca6ad3c5049823a2b042a64912d507355fa0170527de70da956d5b6dbe6ced9933947b6bcf0fb9cbbdb5e7885ccab4709407450f285f52d081412b892ffa8208a4f2a4a1028938509cf01f7ed021678d1d3955c4a942e33d0175c50725ca60e192640911a35abb067effd7a111a5ff2935d2fdee0535a05aa214fc94cad7713d2988f742ee4f2cf6a550ec4b988e58d26634d2e03e302cc70cdefbf1e091c1a70f3e98056665f0bfd01f0cb9efab4fdd8fbe9fe1e5fcfb3ea5aed59a9f2ad5fe82e7074f2f7ddb36e86f30a746a2ff7120e7654f5ce2e00c2e3b6b6949497fe9fb7efbf21385d0aec425068f409122883d0946107b24938c894326f96dff85dcdfb0b3d7fd154273fdd4fc5fb106e15ac10c995123f8e8b3c5d27a7777571bded935eab58a3f7c746bed971d6146750df12f103492cfd99c33892b6940e557eef34bf659694b41a3e1a33b8d31d70a82ae519a47a04a3fba2e55e2be2033fb3355e1ce5cfff0910d2e5bab6b478de4efef53e98279e4ffa38f3e36927b7ee105cf2f472deb1ffd267d59ad756a40154277759c3a753a06994669c8a8d29049cae811a647f3a132065d9b11a862c547fa820b2e75647ab33057575425e26b234a61ffd5d18894d4bd629d54b97e9fc8820654f37a4ea29e38992cc060b00ff6b150bfefa0e66f46b97f16f4c269a491c40eb83ca35e84319a55b5fbf51fd0b50c203095349847f5ff89888080bc5cd2726d2e2f9c518d54dffb72567155ae0400ad9e59f5a79afa26d7ca956b7dee7ab4aaa4566bf374526be40ae3c0e9deef60e63b59e89a53a51bb429d23cbfe882e73badc146b97a5fb9af9ef7756a7df9fe8a6572fd4efc625feb0fd08b259031dfef40d87bde7f61d958f9fb6e258f297b1964ef287bdef77d9fe779dff77ddf44bf707b2fec60db5fcf134510c015575c914bf7bc6feefb8af43bb4140f100f6ab6e8519325882421ec49b3736fddf0c651f8b6a758d7895c8213fb2522d3073d69c847cffeb6735a009b5d6c7200e71c57b9ea20b0f9812501af899adb727efb39eb4d8dd4b59b038056cdba3e55053c63244e2e679411ae5cce2499ce399b4bc24a32addf41cdb509044fea2d2a5eb9068c03afd5015db336375125da16de68243a459a185c36570642e8dabc79a6c8f4270999fec5b80343128ce07b2493fcfee3662bf9706f67d95801c08124231b8d34779fd96321aef62be75e75989375ebbe6d6190d30fb86caf1c02900e08f1a45208cdf55da96c3d408c72fd929bd6ea7ad094faf3e395ba4fffe476e1a21b69ba12600b50b8980207680a11788a98fcd5293ce4cf82325c199a4265ca54c6334f719b6242be028b0babc9d3f0081eda904f3f7670a8017d9c6aa88e60c983877c7ac103391b607fab13a5c817f934e486b44784a1220cf95444a5a91358486b83162c279035b4400b49c39ef9b0571cc2c28a3c31904f3039a47d28728613b28a18c7b4a291e398b6ceded8ac51320459c356a30349c3999f5e7dfd849a306a68369c5dad1790b8229b082c3d5491dfa48287ae2984950c57e447378083fdbf2aa70623a4661920ee746da00ddb4c145da6c81abe90c29360c9c18aac216c8b160c5c348264df5e6ce6c1cdb34b9819aec88ac3d746dc97fc4d2c59e849ae4ef29dca9f8d72247f1b58c38f8adc224efe3279052b9f4cc3dea2d221b791bbf03598ab3c9f8727798a42bc2fb002872bb8663e86cc189c905566c55903ea5b3a328861433e715590f5ad3864e2b942e504f2896a9155bc8e834a0d0f48c827ee8b080c6ab2142983440be453cbe9218d73b1b026ca89cc61d345d6f04613d2bb4ca1e68aace1e4b285fc38d08693891aa6b822bf0bdab0ebcce024ab036d38bbd63091226b389544919f3726890b541f68c316c315658833e4078236bcb1440a2fb2864d7e3050006ef0cc030a95a718036bd85d66481b0e99607240b3841cf2c435f102d98ee3a9b35a12361d29a40d87b8093a9499229f3625e46ddc3f2758624417b2862da7095975f8da2b0ba1b91b69fcda8b579eafe64b559ea2109a012dc281a450bde7cb16ab49a1c62eef323674a9819af9a0436edc21a908458b4c51468aa461fb50822216c81a0ef12498acb1229f6a9a1dc8761c5b125e4fb131643b8e279f265ddc1336d09e7cac20db710491e73f7147cc90ed38a0489f3877c81ace7cd0a745e2a8c0455291b665822d265f9eb57e440c113c240d5f94b155ddc40f5a8c203d7cb10299c60621ae203da43186d4ea62e585f490861452061b928643260954e894403ec1d290ed384a30cf941cb133851bf2298806dbdb1432a4b99263258710396091dfc422831912899a2b3660d128a8de4455af1daa6809417eb60838287ca571210929d2c3a212c821be43172827904fe00e597086d0b450b13a0e1a3a985f81749d9e938edd111a083a08ce35df57ddfd27bdee5389d77df78573ef53aea491413a7deabb1bf5f964eded2c042ed989dd477d7f5e4bb93eeee9e6a58f0cd63964d346d7a8520cfcfe0f3c09f698c4a14ff87d3f3990bb9f3fb98b7d1d2cf41ebddfb22702fb1f05c5d9489ef7d4fde7ed91d38e2f968a40b759de93ac1b376e643dcfb89198afba6c86f51f1708812a81df78ccd2e2820955d1f5d83dcc0399fbedde46ea361064eeb706c42041b1fba8fb3b42e67ea31d95a961d0486e94c70a86e90e931da63a4c29605a82890e9317d31c26394c4ae0f9225f4fa23060b0080632c56182c3940413124c5d4c28603a024f90c9083cbf99de309d80c90d531b262e26364c4530ad615283e7336de1f94c69f07c2622f07c262d3c9f69083c9f098d11c824840c9029881920d319fc59003299c1235881187e0c18165821aa01401fe9886543265829562e85b8fd3cef3be8ec3d54eec2f273f71e963fb2ff7caf7f43a8eca1109b3991829936fc8d0d7bf8dfe948607cb7a97cbbfaed136ef56c52d9cbcd08971a7e8c68d096b87ce9e852443fc135a9f202665a51d3f5856bc6f9c02f3d49e9534e9864ffd29ff8957f897de9655c8b871e5c8d7be527f097ae874a4991ddf31f2b408e6543f698fbd32e1ae74b5a27fb37fdba939dea99ca424f5a7c59a5545969e17259b5d4acec5fb53c69e8fdab1ad997f54df552a2d689729184e84bdbc40995550ecaa59592dd5e657f8be549b3f7b7658abeb44164b75ad9df7279d937d9bfdcdd3dcaea2afbf7c44355e55cde35e51e25758555f1d4afecdfa5adca6ead32b8a14811445878a10424c8d27665cfa2820f48bc98d1938709b2b45ed9b1ca64a3fce26730a717f35ff47c219637cc572eca454f04732a9abd0b98d38cc84b267a19cc89e87e794565173f04737221db0a6342967d0b9893cccb432f04731a6ac125b7f82098530ba1670173120ada0243420e7a209853d00dca2cfe07e6c40288072132d0639813d0cffbc09c7eea98310f3064fc319813be58d9e76130279fd8b79c1c7b10e61483fd077382555a2ec10c825faa32e8254d06df833981f8fb0ee6f4adc91e9decfd8539795df71ccca9dbcab74b91dc16e6c4e100e48d8b97cdfeedba44aef56e5379be982ea2f0c559b9fb6f51159becfef8005555412c59b3030a469038a441862853286162cd10a4b70c88ec2e042ec7d1e72a8c2cd38f5d2a5754b07bd76c85c9eecfe303107eb8bb8330a7aa23574fba71767092e97f30278a8bc058e1154d59a21bc01534b7280a17a1eccf2d6dd9120351f6df8aa8ecdd32ea40e68614d9bf166131d2d2831b1df0006c98a929624b4b0dd9df3109594c9825a0b195431e174a77c62ca7f495bd4efd764295aee8529413abfd4101ae4f7812cdc72f4fbae1e313575aaa75562ae585590b98480ffe41016e714a71f55d8f2fd1257a54a9915b69935cbb50b694a9156edab284c7a388e8e0f206ecd223985315a22770d406c25802f72832c9260f8f32a894d6255addcbeb7852798336f1a4d28dcc239da3045dc353299d4eead75a2b8d7603bbedf290f8eedffb5da3e52b94effcfb8ee565b4b852bb935075bfe4eb5612b8f76377680b2e65190430fce1e3fd1b4470908f4d3960eeaf57e53b6f90042e10c2e7c39366e043f910faa02f9b0b8414f2bdde42bed7a3e47b7f0a8951f97e90f89f07897dbd31b14ad0836137d2b492953748fc6f84d17c2655d36e62d580ddc8fdfbf3cb93e8dffaf73dcaa564548902f3e8fe95e12fffe7cb1148962f8b2f973205e6fda06721963b841e482c935afc4f733d16cb19b96cae98587614f98262d977e40c796239ce6821d26a088949e58efb458feefbfd26af51c47dbff76fdc7b450d543c3dc072996c6f2cf9e84934a4ced1b5a6ae396d9a0137d19ae3862719d1255c1e271c9eaeb5c8dc539fe73e055a42e62c67b98d7b9f90871f715fc3ca3987c7cb476e684b0da714f73788e00d7cfc9a7ac04d8fdc8b03614d3d6016fff3e5d4e266d5e781be01183f90d8831e718fc5490216a28f38bf32f70eabef493c898fdc77e6569847dce3d8974bd957983e1f13cb1df83fb14cfa794f2c6be4d2a7be13cb19572cfd8a8c0a762840e38c1f5a0dafa4a9e42356edf0a2475d3e72ef717ce4de457fe3e30d2470d965de644e96fbbbe6a346e2c646e29e88093ca5b82f52c9257ac4c5f247419fa24a589c5357c8bdaad0e811f74453dcfbd4d4cadc7fe023f7dc7f1684b104f6e951a4924d8fc2a329c5c4e45e8d35bde811f75a53cb93b81ad012f388cbdd48d6e93412f7b32606ffa41389cc051182f3f75e8fffd1b5fadcb5402bd112fa887bce8b4e0b99fbb2f344c91c47ab32c7fd177a0a1a897b2f743a6d83fb2e74af46e2fe865ec747cef1d023eeb96fcabd8b25a66279392ad5485770e95399e3a63ca9893b712adb85a550a631b8ec0a7c031e1f78d039dacf645a41d7bae9e4fada68d28af2fca207c572fefc713e96d1f0b5d198279d755a3b77706973e5073352477c214bfb53b497cb1ab07fc1bf5fef571febbd5cbe5fd7f4d8b9a4490bb8214d8f9d3bb1bcdffd7743d0c73ab9dcb99c7fdfab8f539524de4f04a8c4f1b167ed07b80933e8fa95567f2240a58e8f5de2f6d97509c241acceaa28028dbd1178daf09fa1376df8d7b8014381424765d5722e9b39683e5a7b6f77853971f665968e33fbed485c9c09bc7d394e5807dbcb1e0361ce84995be6623cfb520dca419e44bfd65a6bad33e0f941321f67f4bba8ca98c04d4519145394eae88dc09ddbf799637b7a548f1aa9fe4741ba3d8773c533c72696505c383aad52a51e6b5f8c6bd6461b7de4709480b79f3173044a4d8f3aada66efb7ff7a8573b30b028edbbf82fb7fdf4c2a74778d62c44584d6f877fe89c7f4536a435a3b6b8b104decfeb3eafbb5540d0dd9d4e9ae7d585ea30a76e13a295c68d251d3ee3cbb047956830f08389e5053fd1bb8acfd37c6e016a5789bd065c31dab6d92ad268b4aed168768a7abdc062c68c1940b4da2a041640125ca1c460f3be8e8c8368805b6822ad0787b1560f2d2dad1e3e564feaa1d557333e590e006090df123550f6babeec0d56636dd04a4d03e8daf6dd5d6e7697f36d76ade9e95f6ea397dbaa9d7e2fc6b2effad148febed5f5a36b3fbaeb07a78477ed147d7c7c66d68ab1469a5debdbf7d67a04b7595a695091d10d1dbff9d329410dde2cd639e9cc98311bc603d68c195836b6d2ffb5bfd9fa1fc58cab1db6e8a0254b0e58acbca23a236bb005cf1908d670b87283151b6aa0a1aa8ad04f0b2a433eb2da949a94da0c35196a515e74306a54b5186a506a30d49ed45ea835176a2d7c33626023f904bbd679fb419c75bed9e327cf998e1cd2298af927dff2270be520350359ca1be7ee0ef67091bbcefb3e1016037d6045411877f70da0d0661979f6c3472816e00c671e88e5acc947281d41e00cbdfc09b5e864181c9ad17c94b93b0665e00c73973f1741dde025a2feeebee4ee4d7f7e73ce393fcf990d026f1138c39abf17305a14e231bafbc119defc85b393753706457fb7595d386518ac009c61e90e76f9e6be9f918c20330e3c67eceeb74ea8ea4558be227166d08fd164723f0cad1646f0fc0bc82823032b35ea0aaa0665686868e2c64368cf9253ffd370c3f7b9095e90e6458b010ae981d1f58b4c43538bbe9e814d046b17b10e0293aa0c0f61f0a76f0865201f3cbafa6962eef7b1d65aede089552935f291c5fbac55214c4333655937e6e25618d59af568a47e1a34be6af3ad49e0bdf4c87bd11d8cbe31c06e219ee96ba069e5ea16b615c1eeeea6d1a3fe4a695e9366d44d438a826b123502315865cc19a0901e1a1a3c7ba34735448a620107537c5f7b92063ab0944b1eb9bf45204b65d9a3e91137d3d1489c73f4fecc03cf734c6e3179c6818cdc3de4bf6149bfbcd45a2b247b13f5b00c02527e99d66afb02200773e2c01b7e17bc6119cb9472e205bcb22b9b03cfdd484079e6192db7c81f08c2604ebdb968f1d3dd3220c7ce02838de46517cb590f1abedea4e5acb208023d2c855a801e96b10cfb82bca1ee2eeaee202c7341342b82e1a26ff86889fc878f62238533b7b97a697359ce9a7c2c023d2cbfdc61d9c18011e382978558bcc008ec62cc683ed65a6badf5c7db34d63ec242b10223191678f855e06f64549f31fa377905300e6c76b147adb52e39cda98b341aa9cb59106841aef49bfc36d296ab580191d10c194133400b661c5d9bdd0826c3c3b2e436ffef488601e89e3f1aa0875f8d2ebbd8dddddd17801e667917d0e8d18471810c5f007618f8db6ddb401bb6973b0fb92d7f3490400fcb9bd5e327cfec36fb9733366b1f67b6b5d68a6badb7d6a0350655e69c73ced9f997d21830d3fdde7befbd2dc613b79f1b092d4cd072b5c9c780e93193d66ddbb66dcbdab2b2a0c270627fc38664c0f49bbcc99f789f87d57f665801dc48d573ed80db3102e9cba8f8d348dd036d00d63dd879e7f7760eebb1fe0f07b283b05c3d90fd4121b6162100246db04c16c2b57556f1c08f867773766ddf050632fd691f04dbac5342547cc1b84254db2871bb6a696cdeed3cb176978b519d6a19ea3c4bab3b9d67bc6f6bd3e6a3b4b37613b7eff2566d6da4cde68dd2c738cc9632e93ccb716d7698694329a5f727f793b322b53d76d972b591ec5baeccfcae916abd8d54bb11ecd402fad9b86a37ee5e8ac7e36ee78917d6a3b5a0f540edac1592e94f1262b77a5fe77dddadd65241d1cfeba8a8cd73ac5435b4f9e601b5ac156b1f55305721f5521f81d7b1702ffd2b34ca514d126a8fb58e402b908dab76e3c46c5cb51b77efbd62e5b61e7fda276ddac8dac8e8f4e10bd8791f488577efcfed6777efcfede7c74daacaa5d6a466821a935a0ab5a9da921a0a3525b524b513e6a4b386a26a6b26d44aa849d54a5043523b5233522b52235223a1167585157bf45441c5145f524401c5134e3491074f95e56a0110a56ddb46273f45a75414ed00dd36a5ec5f237c7d7d7d7d7d7d8df0f5f5f5f5f5f5b5893dc2901945fdad8c52fe89b72082b1a2504a29ed166ffebccec8fd17e06427e8fe01b452f5ffb81f0366cc74077950a5a5251aadb338dfc264eb418bc9f6da3a4485e9d3aee782e864dceafdd0d9b4ce4c7d528e724ea918615aab206fb77bb0fe389d3f1c7028a7faeeb452df9cda3a25e67a77507925957948ab57f7e1b9fb3464bc68a1dc0f43ea237f1c38003d4c1a34bcfbe1c00fc9d9b925c6a5474255d43d30664493ba9005d5a07a7f4ae15919fd7eb695d1cf7a31a89921adda6269bcd1b4ba535be37c5e9daa0f102ec0e3831ee0770e006090fbbd8256c235ce470f100c7dd41eb5d268349ae779dee7cdbc55db5deaf7f6d8c25c29149e6bf57537dd91e881bcec0e86376c5bf17b0ddc609a92925680c6ca54a49446691f8d2a759ddba7f569cf396bcca3e1cc379cd5e61ab3b66a592358d4bc563ae7b6bdfb7b9ed99d7a7533403f176fde77679db62b0196fb346dd094528aefcc5d57ee5aceb376845cedb5268871d4ab85298df4e83af6beb491fb919c46d7ea1bcdc143a7bb4dee4f40f7f878ec9947bae6b559ecea49b7fa78c5e6b1c1387add065d6d9eb7f2a0e3b4e14fb38474c0c71146292d0e5c903d9feea894ad975435ea14aa110000000063150000200c0c87c482a148164569c4a60f14800d6b923e745436150a43490ea330086218c8186308010400648c514851d10a00badb33f6415b41bcdb8dd500d7ef236ee238dabea1f9e056ad9de9ab4dcdd34704717d0060f8659b906c85f42f22f1824c9cd8f6e72b4e09ce47b2c721a784a458911b83db15fbd1f8fc445ea283bd730d21a820516ba0fe7ba0eddff515144cbf138d8d09d5c61c30df43adde7d3cb4eee73509e4b0cedb74efdc86ac4a2c8540b306824e06050eca84870f4a5a074cee2e6c4195279d7f6b7964134ecd424e30b6c6139e6ebe2d302769cca02946c89f67426a8718628f5a81138a2177acfe1966679f8338d7b7991a7101c249890ece5d7eddfbd795d92c234d9d83458e580be41a622e0df12f79fae22980fc779a173f5131d69e5b2f116b2f6868dd46924465290b88e92b9a98eeb8845dd64808188c57a6835d4b8203925da83c8cc77a7e911ba26824d20b355f0974992c2b30c5d4f331a7f2ab38363702ce576c0eebe1869bf57fe94c7e6dd628fd087b94935a1620bd878cea5533e4274d76de4ff6be28e09084dbc828dc4530735f390db814227d5937b0083d3bcad5b71908fe83d3ad26e2e4a81c1eeb12582aa71b64450057f842dbb017296db401595810e5af55b91d76c36c82bfe6cf3c95db38792f31a01ce82ffefd19d8a0d028afdd07b3376bd2540ea08d3eec5eb6a4e3fa0d2beac05c597518f85d047f57cb7a30f483af88446ab7f7f024e51264a209cc12dccf2e6670f1595fdb5ffaeb0bb0a3de1d6d042c42dc5f30cc46a5d326b6d4620158ebc7540b9bd058d1ad17782f3344af928af48087f2ba60fc2369e3b313fd8ca46817bcabba5210b38bf1d640a11fd2c448b903130338c414d101b3bf3098f3bfd2eab4c96bd87661ee8f644fdced6a238fb9b81681ff55fdfe38c21842e7d27e655afea803b03f5fded418ef820a413010b187666859b2a85914fbe24f5d9815dadf5f4dc1d12501fc01df43049026f8d69bd9d55b06e1231278d0f90cc1006937dc114ef7790ef8293444f28a157cefe31b33f0af4f5ea9bd53245c0d890519d6908057a4bb5901434a97b687d30526c5bc4888efd488b577e0cad8531e1ca150b27f07a9c9c4af202974fec6223d9768eeca5334cda603394b81770fb1d6529b9a762fdf7e622343f46f52a7b8c077f8800b68f9ca4c653b69d3aec6a4a44933d4c41219382d7ea4e831ac66fcbc658d213ea98ad008d0cea66171cd0fcda0cace04a923d61cead1b5728a64c8c737432686fa3c7da8e8f9ab6ecfb5eb30d9167887519bfc2e7ae3b1b5f9cbbeaf60da9c085a19417422a45b6aa454c774614a92b29341d16a26b2c0f409cd6f384db5ee7009b6be8c85f38eb644a0d6c6b0fb15f3f45e2548541529a90bee945d134728362a512c9e18154f77343e34cda253e32982c8497426b007fb0e696ec2c1d9a53b5499a9c4fdce4306408815c29d35d49a9794be547c888c54b8f66ef963fb4035057893beaa6b48219c9dbd4f42b7debd8bcffcfdc679374108c076d78035193531cc7a3d74aa95d3dae615d92ed4f3dfef15afc74da4099779331a976658d1c6f874582c94282e86c9e1ca0695f3b6bca6844cc4d511d5e576f32bf0a9d49376d40300c79298a1dac07a4e352f2af09e0d6f8fe7400736109b88f03b44e07f15c2f22a8ebb0a03e08c8c1e351e0cb5b4e976ac208bcb1beaaf46188dc5dd5901ca3030288384dbd9592056ba92685c003f7a232908b35783b467b9d604a1c599df4d025d9ea261465fb8057cf14831c2a09f50c015e825b5587ffdaf50727b2d02198660eebcf60b8fcab34d18e9b4da7bc4998bac545716da3b9035bc36ce4cc919cfb046343e8dfe7ad5f019fc9962ef6e5e04a1fc009a278197fa04d53e3fa98acd09a7c577ea9900f1fd1b8432f1f7e7195851c9a9d12e26a8c31be11c6ca593cf968f68b89dd80506e319f9f5a8180690f9358aeb951fc255beea9a4a6a8a6f9555047c914919f9d787701595ca8f67f8289c7168d22947e15410cd483cf4de11ffd9e59af573780e8126849b45093bb15991fdd4fc1ec1ff5e2ce731a054f7bd7ba6dd97d5940a8af04ce3cc76b42ae328cebf69fe17a02747e6fc96fae1e2e5c0f0daa81db3dee9c02ed9b1405776257da8dad0e854957934cb10083df5e8150c03459cf7a0c901a6cf9e4f530302158e35c20d6be922fcdc138e0748b0ba0d0fa118bc41598c21477008084dc87a4cf3aa751bdee89a2b29e10f167d407a4b204b2990d348213f42bde747c878e4e70acc72ceb176b4e4f4180a2b0280b60cc890824031c71d1244e947645933079658be24d43d4f4b151070244a33b0141a80b3e3935584da5dbb840e9a2be85a2716ab5439be436c87d3baec5291a56903a7eeb3e16411d27ee86b33c959ef0e017f874b104c870c4e33818ea033b81cab5f753eb32cc1c51508fafa475c98bd8f270a966504529e3a7e2970023e628aafb9924574c62d8cf162fc29e70afd40cc11fa0ebd002e36b6ce083845b14449c050143da785940a98a169e424b5d4767d1c5eae52449362b410dc7d90e3edd3874056fff61c7b6290eb869025f02b63c30ce9b8116efc0524faebb0b617ff233d0277337fa5d96de1b33187cf5c73fc26765bb6c6194045d0576236a34a56c520702a35482e1d3fdb04468eff77832ae19db8a098528f099f051c68320c070c8c6ac28bc2bdef196f8f0d19768e57db496e69426dd28d01d61bcc5cdeef4b998fc7eed94a311c68aa19a386eebedfac2f8a2ccdcce524eecc170e65adee08e09eda9377c19f6d8fc423d0a8a2df70fcc34663fd0cda659a97180653b084a2f930f1b175aba79e61531a16bd46a53a45e64dedfe0f55dbeeec571752713e3c9789074d1fa85453009867a7492678eba7b0673d7e238743681dd6fc07bcb32eefc3b259f2b75c81fe5d8702ada077ae2fbc6432149a070b41dd28a96f705df97bf91c90553616bf52bf1593f520fd20d06844a148e1c3fd1caff4dd8346225af88e7b29156fbd9b8404824c89687fe1254abe6721ae03e232f2fcd4eb745b32c2ad3fa075eea3c506359de0f4b3cac706a0e046a5815c9b232b14c43fdbd2c4369409a24a0dd84d7578c056a366231da931fbf900ab704ede6da8791824394d1f73ff3edb8a3a7bc4cfe982f7461cbcd415ea4ed524f188d632217f8d37474f4b39f849cbdae5a6842b31c93ea9ee1afdbfd31a41b53a29ae389ba7dbbe861a0034dd28877a8e2b125f6310ce58c99873ea0188d4753222cfa59838394c66a73f7e335fd6f60791998f27c57356e6b409dfd5a53432a58958ecfc8978d16f57c692982ae64d3568e05229ae84e68e5a3d792f03feedb8e463ded8f2c20e57c8deab9c0f8802d617e71467521a5f36b67ca2e548e17342220d2afe3a6c54854a7aa5210e1c648215a1e8ebc0822d0231a1d34384e3b364a11c205aecbfcca0ef4259ad6c295c9abd9821c3b8d8a9467f487a2498f0edaacf834c65b6b480b5307916ce9a25a19cc4043eec7254d2f01963ff873b3890ab49fce61ed0c5869eb7c558db1052f9960640b3dc463e8dd2244728c324126495bae0ebaf73e708828de81f1e65a9a04126b4fde0ef098b1b0f8859610cc099a7cd479e843b24e0b12b55c70b7273a2a5a50867817580569209a670a9a31160291976c399f1da92d22a97efa488b4fd0e7c6519e1c84514d8387657b088e6a12a96481c599cb686b633b82bccae367a85794da2d0e48bd1c00a36f58a89c21b81087e39745dc09d2db50d063c5b877c782588cc969feea5d22af4c087cea693d0af8640442624153279ba661ded192d853b2d4f1fd913795a721343a086318c0179405a98a0251f3efbcd0f2f3ced4e040f64020881a7fda55567ec6b219a2cc3be4fd264ff561d7f1b3a9cb8b80af9b4d446c517aa65e727714ac7ada94260d262e3b982beedd707aaf1fd4a87803ea9deb8a109cc2b00ec0ff282589300bed360a8f76fc0c3c934f2f11efb14311d8528616cdca55e9d15194bcdc2b11462f52857eae45156b70c83c69dc1941cdffb5cfcdc8776be970621533d6989ff8375dda0e63d35b0e9172c0e5345f9bece7f4c88b940854d84ca30081f263f600cdf9b0d7f3a6600d00ace13f5a33748584287810490e16e97aee8427b9b6b6595875d8cfdb5815079c79603020e51d76b5003b63c22ae005eb2697cab613dc70f6a7c79b2795755325e087ea0d399f019a2e03112471fa3d085b8ccd3d404d6e50d6d1287383ce63632b29c6d38dae3d4549461473844b030513dcdd328410438ce0d03bf58ab19cbc6d49af0540e85923dc409c75163c81214638a4b41b12c197a47300cbc05a183533a54bb6d3f4f33d3eaf8c960748ceb2e6fb44228da826c0336f407357e11fc5fe21f0b600053bc5ebc988d70091fb78b850a617775e0f65bf23a803e44a8d20aa405012122512acea55f52a30c5d9828254b0e76ec51fe8b93c4ac96a5ec83435afd31f51f36762b3a481924e14bea352b6c7c1e611d4ca602af05bc4212ca27fe8cca1a1f07581c4029b66a4cb89880ac3755cef44484d3829e0a7739c9628e3cf4b90e9058efafa4497d18130a0fce72328a7ebf78969da13163b192397a611d43311319be578380b25601793b8a79a00b585606025dc73c62cb284963dfed198352967626d2045a37ed0f572ad969681d8fa9e63e2088eff6a69de8a8b9f99c758c6ce432eca959f8885f66b00072143b33456723cc147a0d885ba8c622468b84e1729c050f40d4f4d206e7a29fa3ca43d325ae583b0b857d90f2a71eb9135985dd43c47c0d02a29a67a2edc961e8579ff08a88d3237558df206d5d2cad79f86085caa08f211d79e352157a28665d731fe9778b2521fdf13acc08616e0dad1c22f2dfdbc50937b896b9521707c6ac31ab6a334bfd9e6877f140ab2b678b95b5ccfb500c700306509075d4534020126fd331ba88666d90739bc87ac35eb133bc9e19a4e5f57e5fc42dae3f0ba062973411f5560fd1849a2e33591d09e64c7c9d7f38f5a210c798615fa3005657cd66dec44982bdceb64b253e8fea73071d60e041b9d23842ea43549172e1bd90a736b8422ec4e5ebf544dc1d89b67258ab35f652583153d540da33567f393fbde163167eaa69d9c32d97c755d8c1e41da67f59805f13b72b6fb764f295f2ecf2391813180d1820e72e0f2f4eb5cc13a1bb1deb0efc7185bdc18af4a47d186c18e95c2ed4bb64fc0dcf94f0b418c2936a94322d6d503e30fc169799f3dcdec4699853ba9971813fb0fadc37a8ce39ab636027f5babc8cdd934ba9ffef58b04dfaebe6b5086dc883b2c4af4feae432db85085ed9c8dc4dc74a16bd4a2ccc265b43243376ee95ce906934d72ed079210de6a7b1528028055d408d2cb91ef2ae13a83cd336b2170ad08569bee58d213e2e31399d64d7bb8c99c2de590f5188d1f920c3d09bd8a7dbed3337c4376af957e6309bb784fd178a134f48c83671abb4d2c0aeb35a90860994d7bf6e9d3d8b5a30c9e7d4f0a3636f8c85750e9f63a7bd1a8ddc58fe4d7e10e952a2324286a68feb4ccee064a4b6a9bcb4ebd5783974616d5d3793bcf1ba2b6348915b7e4d7803e2bd94d74b4239bda918d2741aa9085d71559953448e19deb4c410d4f40a941695a1b3eb9a17d1471133072200844912505245a8d102180a09df1c5e4fd4cb17515929ef0dd23ae8600c91ded40bab8555949964c0558fe4b328e4beef046fa5edcbea878360fbceb316447121fcf2d06d953a82ca7c0ca2cb83cff1e5bab65e998975b4a46db6091d1e45ab4c1eb6e09941c13a827a286dd80ce918ebda2905b2a9f78e400add531bb65e7558676f0b419c25b4f012b642471e58ab6cb307621f3bb44c707a85e99a4bbff61aab74d63d7e4b94a98e6c3321df898702e306f20d78a649656eea4f5126b0a94d719714e32a7b14d4684ccab7e32c547e727407b6a2201360d960eb9714be444012a506cf6e3c29ac09dfadca44b3da4f585982e4ba5cafa1678a3ac5f32693fd84068cd7bef572342a62f78684d48f4f37719aef875cb2a7525b3f1db24b933f8bbceb9c2c61c376c2fbdb402e06bff41f6294b92a604260c72e3643b05e536ea48b9ae64cd8d2aa05d05e528142ce3fac20091a349092924b909db56560b932eb613b46472311a2339f3587e34df6b4cf95ed9600b185808ac897dd396029b1eca26b074133e79cfd29ff4ab47b186928722019b7f5287e31bd127c8cbd5bebbdac3a47015799057dc3c4f6abf1e3665f4bb26ce98d836c67dff12aba8442619e28d37bcbcac552c5a4bd170ae33e7159c1d27abdd4db271f36f323f77453b2bbc4d9c8099377c0fade6551ead222aacdb0b246db7473af40e3f2331b91ae3df6a675c578854e5da186bd0ff89df59720da881a4c8e808945746bc3979415e5420a7a7f648b0923ac9c462c401dca2b7ab49413e015c1d9e703f3d5e5db21f2044383817ba1d1b1815a51b9d002fecf1824b0f3960f78e9fdf4a043a4ee8b0488077781dac045236c419b202e92042d6df54552eba60b140df8bacdafc5092aa7cf01668359ad24c318dfc80ae6cdb536f49bb4e03996b927c8b82633815181e40dfe41eaad4806e1b918fadf04dac29d66cb60582b40bd4798e04990e25c43fd9cfeeeefab3782aa7b8a5b5e849172612fc01ac581a5ef5a72013bf6074349c5b562fde1e214b31e6a0eef9971d9d24bad5d5be3c9555da4c814a81623eb69bcb58326f1c57953d7af48061a2552120c8f2f9281c4d085428fc55b96043a8a2a02a8e95309688f9c0e0bf7cdcbac5513a28cc13e25675c3803324c9fc24ce55ef637eeba46e793c7d1c23d00f29b1ac35f1c07527756cc7ca88429af009ba97fa772085c02da4bacae1d8b25aff21537ebea25581ff067d27bbaad232e2ca778b53b08f7dd9ddcdc26c99fc7822748395ba2fc1b06c1b7b0f83a4709421d1bdb94d83c655fbb2fb23455e3e76b762728cb50fa084f8bd472e3fdeb8902e1f3c2105f2d7fb2342c2bc2a6ad2345ef1f3250d21a34f2fb21e33c3534bcd200b756124ccca3042f9ace34fb9831541a60bacffda7806795fe1dec01e0490b6c6c12befde29a691f9ba0a614466926dc859460d10c77df205857191909992ba91130fc1503caac1c101a621128900eac6332b44929f26d56a5243be1b096d21a545e31cc38135033f1a756f84d37a456989596d316983e5b375498bf1ad89b405d831f3c9081aed5de443a1e3c88011a20297d39c37aafce8740d8369745dfdb0ffe652ddb0943de30e826b6bd690126b40b229afc8aba0f9323e12a83b8fdec1b96141643860daff88dfed8d614a7130344e4ac97de1e07243e2889da5e7913471a6013a3e020d3caf4e03565b238c4f7a1235f798700f2a092e334558a8280f905cfa1d7865642e0a881a3ddbc9100e5422f45d96741b43d59e4489c5eab4556b2f333bd9ce3cb4aa440aa78aad6f23a64244c0272f94be6095e3bee10e7bbaa928ac485d7fbcfdd89bcd10c723d9d28912a14f8e4c4844e83ab47405c9d1d6cbe47c2ba8c9bfb2b5e0ace3736da5658c2855f22c5328702e9dae7eace2eb11c039a3bdb0388c693444c09d2854a3f76061a47f4c1003cd5fe6b01f3ce0d6188a72443a28978b77e5223bc54bed8bcc91a9549d9ff9bd88bd01428fab213bb1fa585c05190dfa40f7f7d66e783bf574f757a6195992e21999fa92ef8768721b498a10f350f94a64b03acbfe78083b05cc1115b970bab638c7d8f343c7b92c590fd5966f2ce0c542be7723136ee94a0e36578d6dc86336dd15c19bbe2b35cce196f196251a0e4e7ec6d734c40b631708d06e564a1e7a4440a257fb5644c9f5883cb5114ba256b320731e3d489991bb4407d2709fed2d640dbe41de06cb1db1cd90e6a951fa779c71b485265aa5410146d38f831db1527b5b557138a03236545cfc76b590aa35c2a379e28a5af83c31bb9c81e734a1dd3dba9c3d94f4549dc7e0eefbb5b50824e2586c64ba6b116924861ebc95860f24be76e8b5aed4afeaa819251352ed8a96d2902f77e4fe0933fa2f669d1ca54bd684cfd1798c3fe1838167efb44f5f887ed7b6ce184af514da19ed69c7d798332365b05c3d88a4129c1418fc3ed32007bf4da04e9eb7460009c7a10b6fc001c8646bfa874821002528d26d880f97bc0df8b7e66ffd5aa11245d9e442eedfb2e1e48ef8f4b7d48a35d2da77c170a9861c44b27684af4ea82f4584a98a31ff415c775dde831594f1c7f385d238d3e8429f3ab7e74ed17efb4c0da7ecb0e7597924ba9b9cfccc8fa6dca2dd478b8e91ee06b9a2752b08b874d90de91a5b141f451d166d331e8c30d0a9e78d778709e90c8dd8d8f857cc5b29a4a63c302b3352aa6475c8b101b8ddd321f57c3cbf6e6273f82488cb4bd0a47af5cd3a57eab831862aa54b12e2891709fb2acc5b09f567bc8cc4aa4a16aed1aaa71002972cf0018c765a8295b5a7d36dd30067ec4ed15c61f7b9282c76065b39de7e1649b35a19a2a9f5a9d0754f5ed23ca6c2740e8efdecfcfa0be1a8436819ca8153b6e8bd38d39407263f7dddbb02b885447b6eb7783ae5a42ac5b0e08c4b6c843f27dcf93802a41efa7df69899b5bee48ba0330a2b1bc095d04c82cc4a209b7dfd19205ea325be56f19e93f5dba4845d18aff5084774a183bd665e3beb978c937c253c2b6a3893280c653bbd0c6ba7859696cf7ce1d7113a472711eedae25ec246adb182581f488b9c1405224b94e1200256d9f29825b26824cc8eb4981daf9f12557bce398bf5501f5dd458df46bf6e4c98458a5e2c630c10765312610ba5c6581c9416e4f458969908a744f66c7a0cb7cfb10761b298b41b26c0c05dc1c4630ada888615baf509512bb3046885f5a96862b2eafd7f081d840596045d3a3831bf12a7279c4ae913a3c70510a698c0d295aa34156fae56b85b4f182aca0b10f15ca119aa5bb58dac9a0c0b8469041ff195e02bc671c40e3192bbfed106fc17afd3e00cbfd15c4cdae33945a6f96fc3f0a8ec0617123f55767b586b2fc9f9c232e32c95c97879d29093fab748d08a70520ede62ca285158229c87f30963ef9d88f869f32ab96d6890f44c376df7e4723fd92313fbb7351767dac8f74fb4097f6d67e72bb58c92add9bb531b503d7349fd69f1711543389f6b4675bb41ad8a38f45afa637dbaab5da0d49961550e8a9165087dea51be981b72cf25813499f7e267b718f794d20a912e46b2c28f1c7011d10561e8d6569d326b4327f90448814c2a3aef73af077ed3f69b405b54107b0ab4620ffc06b5e271c1f018c6bbfd0531acd29d4983302221dd6250cf9598ba7aba18dc4ae43058344eee8b3b02ec1cf9018f8343c4ffc7b58c128efad8c072fb8fe7a19840f4b860b1bcb580e122dbe5ca0e3e4951eb7f68c6d3c387801d45ff1ba050ebc1b0d779e9810707c4c818e5865759343b05ff00b84dfa6ec7d02bf44f1bbb128f1df71c18fbe9c97df474ba88d4e37fc029aea110c2e8013e60020fd1682bd1e7e1258c36dd85eca20edf434d66d8ed497ebf3068175880c6dca31bea15aa407d5a478a6029f00a8dbcbb4f53c6f04c6bee51148456298f6c1d7c2cbbe664dc0a7bf9f098403c2780b0b472322a9167ce497f78dcb67361ebeff3010ca817dc32e4f5ee8d2b7323539c260c6bbe84a173046a34e7bf037d66b11246283d0ebb3275278b3a54509dbf07ba3600a34a36aa141146f47f906a54f9fa9cebc8952649318278486604cea1d8a3466e4d306e0f7f344c6325215a368f6d8ad9d8a38dac6d633e23f4dd76d4976394eeef214833da79e68b0aee3442d9244bcb616f916954e59ef60e25e22f728a1332992b6895b8316d811d3f777d5a9f4c9362259ecf85c819fd1de269135e1344b81489bdb237c9ae722d2698cd724c0dbe138f103a16d96cfaee2516f47f9f8df86048ff425be1cd28f0f69265839eb1cddad6b94fbd1c41f2a5eb2aa4c6aab4c7aec3cce33c819ea5a96535d2fefd7c97a8312bd763d98d6f66193b3026730509c1f0d47112ac7a04e50ff03f9ee075b38a3ccc656a28feadcb79b745674cd50e587584c8f206b03e9d3f0c073e4e1bc1a12f01a944a6ba427526356359042a1515c3f8a151227bfeae0b7d63a50acb351d2a6cbe61ec0f7a93635d0f801bfa5f01308b90e64695de982085170a812a0b69c4466f97b92deae2212a7aed72e42ee4e5a27aac4c45a4cc64850fc7b8994101ba80977cd0e4c25b6454ad01f8be8b843f15c65859f4c23a6ef580f4b11a97d03c5247f0b8b216625727d3d5419df8997ea75245c69a66a751c5ecc8cb59c6f5fc99ecfc64c5b4d170dab90049a776dc838f3dec2f823fe9d5cc42ddf9354399390024b200d2c8138fdefc3581d9351b4aa872b8c01b49e3aa3e5cf1e353543ff3e5706d948986ab1d34025c0069b367d7cf4d7e874b735b1ee74a6bf9f51a5597460f2444b99547fa24d683e3cee4f81b616e23032f9f6e4460caa1d226ec7fd5c655ca774118aa47750cf173558281c5cc214921ef2b66a20fb69789617cc1d1411787a8093927302b1ae578a983b326c5c51612f38eadf7f114e9e9ac9ec45d3d53349daa66a908bccc34478c6c3985c6a464a1594f7cce51c5793f514711fbe9d90185ecbedc0d0438d43edd30bb53cc0bf60e3102e517f1923170af4b02728ac32d98f1d40616538042356102c8a36ec656388ad5d57f5c98d5ac6a7a6aca1d36f46d492630ad5c51c3e1c83586aaa6fa653c0dc67aca3cfb691d2bad0a3c74d96f8c048bafa40e932d6290b0be66c12f4aa622be87afd9ce9208623fc4a0d80a3c724e86ceeaa3c2225a5544ffaa26b672a83baa189f2cef065a808a05cb51539edc1c8892f213915a09253293f3955a0ca11b8eb855d5d3fa38d313187d4c66e9d0322f1a4bffcd472b921ed6837094e9586ed5618c98f867809408ee97ecbc3b0adec73810897084353a87e6837caf08afb3c48b03e5fad4d3b51aef146cc59e7dc585ab737b5b712d3003034d4816a4bfd6020530ddc2c4430ee3e1136b31d89a971a19f2776fb1feee8a47f58a6e66c86ee6bfa72037e9822569e37af9094546b5d0998d0c93a6837ef0daca1142000463d711d28b7593019f14912a2b1b22957469c933511ca44995706a0ffa2d1cc9221e56badf88ae39460b6aaf13267cd43db8e40c22755a87b5b034a88ce69226e6d512ef6e86e6aa370ca80bfc6343d4e1d87c0c1ce8772832475c1497e839982809ff19022fc4aaca2ca86f573a4e9517d44fb94deb3b3d7336377add288ad15a813836f29da496f109ef2b2995f10b288259fdda6f921b45b6f021d5047ea922f534567922d6205a74a96140b67a92ab25e2840e26554278f160612dfa00e9381e165849b09b33faedf53c646e81e111c3d0c64f009914530b97552f7c645aa5ee1659fc8673ab0912fc128aff79660b5ea1ca3bf7a4339e3f5bf937fde436ce5535797fef4ce5cd10007ad435d16f543a348d48aa2579b0871acce9ccb24c854f18ecfc1b4b559d978e63a14d25f45013cf302ca6a35a769d0c317881a6b40db7dd5a244c6254edce3a1ad9d84a5a188405566a2ef2873e37fbd7331769c59e345ddf3f18a3579566b093ec5c076f19271a418b483bf18f7f14ae6e02284e2621449fc158951df63a322609a2c951d84749c979f663e0af342c1c98dda1dc2ffbdc42bffcd7036329d4abbc42f6753bef6687f8145315295bb424fcf5b65fc89f305012d03804e481b4a30b2642c55b4b2e845050180a4902b113ccc408f43a25b7b99a47cd8b4a95741d8a173327cfa968ba0a19ebc333335039b5b38f369a1d08dca6d3eec72781442924829437b0a6018b8895cf6fa100e1546e945b326b0280373dee741123893073f635c75b1781715e16f206f25e86455aeacd4dd3be99f85aed426ad90d881fc40235e09b0863ed3d0f90a55aa2390fbf99b043189bdac4cb819382905f13829529565c69989088d6c999852485c8937bc42c87450339810097f26eed25125a9684bcaf06a50233d72d5fc1dbbb0fa35f5dd010b6a52e3c5704e9465552ace99d1654941a23234f681366533674afa3bd5f1eec7dfd2932ee84db9a19f0629170c9426d66a5540428b03ddba4681556652e74cd6d514e36922569512f8b8babf20642a3d380c1c97961df3a997fefbade5b147aa3e31f7740b46ab8984b91f5b545adb829f5cd6dac28d4fc2c900dcd51fcd44705e0904166e2fd18bc71e4859a1490b44f3d517de6eaea6fda737c36b17292b900682758f2e17fa1c027eaddbaebda10411be5a24457a6a823c210683f260ebcf113ce584ceec21b0493b4fe43e718352b4db75be02397f82f75bbb5540d640ab1371eac84985c38def65a4420e856b1fb859c67a0b0bec597ace6dc5c57a2936c34558b6e2cfa3e3739e8d4dfff09070315faf800031f63c4c38d0f594988437c52d7ba45ae001d60443af6b2048a6a3933a5d1f6cd57f41942196b6680d62d3fcea3e3e37beb1f354584a87898c26959641c00f2549256004a8d961a423cf5e78ba556f2b5ee857b611d4244a3e2eee524519d954a746d352c0f355e1776c91c112ec614ae03821dcf3c7d2f23e8455180e982b165cc274f709f31fc7cd02d5431a25b87ddc76abd990f986dc6e35c3ae21b133204f1fb5375089c15d1ac2a5c1d2894b4b885b973ea5cb379f8c6faf0cbe3d72a715ea293098e2763200cc2369c3ad74569dd0deecf55973f74e63764ba02b5513945146fa6d58a071346aff31e842488ff53bc34ce51fa8b3b683a47d9759242b8ce32cb81a573939167b66640712adc099132fcae260abae4ca0a2475ae72fd2c1c243a1c3019eed2549833992240370e1cfdb37b389f83d86e8574599aa7aa3aca62adb7b4e4425bb5a3a00212abcbfa9bc27c257c50c6718a12c79007953e526a9b2cba6c13930ef896bdb38798781493f56fc0f9534fcd411bd75c0491a241f023359609ccc124d733bcaaab523565b726df92be23a3f9151377c71d1f2089cf6af01fb4768e45baf84028c19d0e84a99404ab307fe71ae7f346661b72679bee7765f06d749c5bb8e78fe88f453195e9d33aa970f1592448348a45008e3025dba0988db265734f1d0947b12ec8073542ae3aae0d74fea0e2d64f463667d10e49b9946b46489ca3297a5b4cc2a0fa48b2e65773aa5a92c8f9f3ad35d697ef89ab1f1571a738a5882bcd3b5de19a42ddfab2fc25d28e32063996c51e468bf08c98717e7556afb9296f5f6ecd3eb139f914bc8f770b0d9d03fc92dff97f08893fb2ebb9c38a31d2a5113e55cfb136e89d3a6102088704b206b03082a481d52d242c2acf40b6707aab1ac7c3c2977e110675619fb48006c0a6e2bd281ecbcc2a7d84d48d66e23b681849ada2a4dda9c7b0ec69c0eb3d70dfbdbd5afb0baa472faaf16dfb6cb4ff14c7d81202d0f4bfc3244d30800b20b9b93a2985d8ed0d6ba0c7a00426e6d54b7c5ab0a14745470aec89db6b58887e6b37e6262feaf55001d668bd215bf33b937e9d68d64e49b5623df3716138ba33a0dbfdd03b404c17c45893c03879ff2974715416cd3f613d1e11070f7600f64b8898c9916f8abcd82653309ea6ff70aff124398319a7546668be4b9af994006b8ed2e02b3b28fe980a57b000fef55dddef26d1a184ff7b1090169f1feb6b7a53224898e341406be08607fd3bcf901291c0c0ca0340c026cff383397325b69db04ce9bd30665f726d3f265557120cf2c89123b443a2af27d892b387003e3e59b6488c7376d5d240f8243acb43f0af9482e08666bdc000b3d31b9ebb0e35e6d1689b365e9ad59630e851c652ae29500fe44da8ac6bc83588a3b06f3f36472bed7797ba21e171e6b39ee09945fe2c2b7809741f8d3364ae33c990ff79641687378418d2d2bb9a61c3edc44b9a1a7c9a1dbd91878b9679a430480c6e9654ebeeabed6cfd1c9d309c77b425d826f6d77e156e5aea7528bb7b4268d51000b40c351d2c4f3f1723abf6ed4e3acf995f9b5d336c9a1a869491240b11a02352cd168597c01c7cb5a74936d8c6337dc7c95fa783dddde2824c1f401acd04c1ee80bfb23caa4758ee63f1ede0290ead013105cf4a4f85468ef91a8dfcc92afa161581ed9c9d4479f4c3c3863b2e4fece1aaf09f8e0b0b3765b0dbdfd34a5cd444e75347d39921d60775c0a6089f8dd31a96438b45f2e5c9a2f443ad315b15fbbcc5028af75f1519e30dac1121fb9ac8f44711973e980a8d4eed7741645b3468213c0c4e3e26247006c4dcaea5dd87994d96aaafe911fe8528f20137db09d9f7c5348b5807ae262009e6b397bab5fe5995ce475492213d716a94372ad31ef67d5e32e25c1ae838644c0c708066165b5c8fc9040cae991c63e7a337618eee3565fc517116918430ea51ef715d98bb0e4f3276111f321f6ef8d31e5bb95a43652f3711725148fbfc4258ab671aa46c765c741fd80f3a06f952a81fd1b5b899f932bfc9afbf23cc046937f819e31cf0ff143aeb1a9325046092adad6c1f027a8758aa9ee13c7e287b037091dc74f9e7e06664ec6440988b10900ed26ac4ef7e036c45ac85e13c8dba7e16110527d8340db7547d4f80b06018fa98a2c99767f15f266b5b1c9a4085680117edb3666f18b9cec75a7e731ddf9a0c996c062bbae0b39e52efae80ac4ab7b1f9e33575821408074137f9e44b6b30e0e6f6e797467bb3fa3c52970e8ecc588259e9b1c185347280cfa3638d0e73bae92a079dd7f224ee595442ad1467fc21e3cb9f99832e76393ef630d4391e14fdc31fc93779e0304de0457815422a300d9030e100f4cc4a18205cc7e1f7290a0a86685171630a193f8bc96a751289f143e408ed08ed516141a7b7bc1d944de2de6ab5dfa7fe297056123066d63484a80363557427dc9b7d340f0522c8e9d5722b344085e7fc91f5d7a36be8370e4bcc56d366c5e1b56f8770de03ab8f3785cbc7c538c6c7c71a8a011061cae412a84914055707f4f2a5a4060a7b264d3a6f7f602b34439e4d033580d356f8b3a2b68c8d770e4698de2eb2b4c1e24d998b130a107be22c1cbf9a30707b052f667634e214ebcc5ff1a1862382bee937f1d1cd98e5c452e29f5d4a8e9e9820fb92cd886b6d663af42f42d64e7aab99e72ccaaf0635dca0ea434f441fb597c34013c6960da9fc97dc0982c9434d9c2c7076d8d9d37ef9c46f2510d3409cb0cd9790ce172f8e106728d66a1265ddc3c4be28fca22ca2d433166b2cd00bc250db2490fb4939c76aa501509ee27739931fa3c3abe1a55261d50d8c618ce0414f2d0704ba4b402b6f6e56e140a49da9c90c7d51a644ad9fe875f5039696635c55a76c741f0bdd7f5a6ba571dcd34076f0ce573e2b8e15f25426b348b990bf6a7509b8e6ae2fcab756498cc14e77f7654ab97235d9d899ac582e724ef80bb29686aa951a8a13232dfea5a87d89034936433ed3c93bdb1ded3f87356fb7f5a1c2d58d0092c85d7ad59e8f4e49185e72456206f018302e89143846d5dee7cf6e8619bc368a99218034ede8d07d587e22427d30720b188a17ba2bf5d46662e15a718d6a5afc1d332a70be410b9459e7e393c9b9804e99beb40c7329bcef63602862cd20d599d7e16bbb76958307d7ce117b3257d52a9da223002d1535b4e7b70ede9b1e74dbb20d719b245537b4a4db90f4b26d3cf363bc81d26c8c6d525ee291d19cc632f943c3a65c6143f13d21bb950228fefc223c392ef418ffda1e502c612c721469ced1ab730a280b75e43cc7155f9e9711f2a25d14f534f136108ad7338316eb12aa3233de53cb16b617af41dd938b8484737f6e909a4a4016ee82536dae9ef5c5b74d6f83847875f54f54ff61bf38a4eba9334d7bbea01b8cdca7e6fdc19b18e2212906759acc5ceabb269132e0c91c8d0f8df336df6f77c8c4a5c2f3336c364fec236cebe09a524b3ca332fd1919c7ad2ca658d04b9510e968f22541806aafe76c631a223012382cbd908b0ba94cd6523071ce2fa42282ce0e02afb3c71cfb77003df999709b8188a4a92e9d3e40340ae187028ffdf15f41c0ec1edd4f96c503e445dfa123980e52f26f8ef9a40fcc2e396d2a7ac00af6ec2ce006efe6a60af85ac7c7b6aab4e90c4c062b6f7a4c3b9ea38c04126b9be065600de2eadf31b9327a01def00d54d31d1c4ebc6a6d48889802db9ddfb5ab925652114a051009df1986b83d6cc11feb348176159489411bed29b9f3a52c8e16364b521f4acc3cba2aad724f1b2be58b571655a0149a70b307560c99a84dda385d1152661a44ba18fdd2a705e3f2b2cdbb82013153859029c9f6f417077c708d2b5033a8b12806d374e86791bf13466fb6e61512716b529d41f9a123e574a9e1806ba59fccabc43ec768e4b9a0c8f2be2960bdd1e0078a2233f088081791f9bd2ce6b11e8d3e40d2d8c7853fc6975b2e1e3070c5888148726483150a7f1a0f8c577a22f269d54153e64e2bd196f27007ac060d2b3fc0e81046cc19baf02b42557ceeecd02bd2ffc276a600afa97fb7f7934c4be8a5f295295aac34412a5c7cb9152e8f92655d6954010a63b2ac76d761fae97a95544a0f312666031d2c61d1596a0425b7832874ade37c470e16b47896978cb0e10e4fa0ceb5c5c7c5f50bc65339ce5e01f9956c4a68e994cf986a044ddb651bc5a572cf2310d4b43c5d2661be5574309b33f3cd22198ca7d8959b83369f0d72985156ca3c9f91bc11acd402a2d960479ddcb68a55229d294bd4f76dbd6cdc91200e76903c1154a7a1ee92245ec71064e9c724f169d7607a77487eec401a3c38e61062c7af15ed343aa3b4617dc718d9a98d01b0072120a773dc8ee49bc177e766802f3158295ac9d8bfc8c254f202a0b57bf7631fdf4b35e001ce0985534639b85834d7323aee44f7de0696043efb21e983c161a9aff578138432b8ff5d016d4f587d91a6f5bf29e8f8d165280cafbebc10a70d85d7adf0e61dee964f7cdb9b068bc243f1d9f513b26437eb5db1e4a86fa3c0abedc6359f413b7fd8d692c56e380078b383fead9c52a70f4c139aa3fbbb932c20e86f216cb98628ec8d892076561ed6c899ec63432dc46c917d098f94a63a7471f0430eb8a80a941d02b20997e6069ef48953cbd2ee814cb7cdaf3d380d70382f5e9833a63a8f5e6856aa65df1e98cc3ab2a603553cc64da13926f1ff45e8fdbb3ef75e55c86addc23b97bb1ed00c91439d4da8edb50f375e5d0f11a0455f43b3ad017065304a1090ea0d36aa34cb4fe8ec24263c6f36dfb6172dd96e43bfe729baf5fbe2724e7ceab4b504a32e1de60ebca2ea8c8d6fb4d24f355a5bcdbe2595b1e1e66401134cc1eb103cd5ce1508567cc3c5c5a5c4adcc00ca0a49cb4ba88b95536f477812cbf2c5dc0ec9c068a9f8d01d6617336be4a21b358b6f5ad32cbc33c0ca5918e8200b52d7c051ab00df3d83d99ef3e597be9eccb7a11b9c725a0e03c2d46bab682f6bd8bc87913567049451c29eb2e313930647882a0e7470efdefd14ebbf490e7cb9e31b5bc847ec6ddc08a67c28dff32a840db6ceb08ba12b66dcbfb47dd87c0703cbc170eaffbcb97331af757a39c15098c521756f6030c2994e598d8c3430067915700653998952d6f55872be2d17c3cbac08ea060705754c9b2ab5bc29fa134b9bd7931a2e4a47dc78853f08647a3307fbc48ba8174fdff0f0d8602af63ac48caf76b289cedcef2ebeb912d3b2089f5961904cf2c30b0332c59848d934cd9b3cc45041b464cc6fd8004f1869106ace06b0b63259052d386b2de1a53b0d1b5ad82085f98cb06a1b2c0f61e6c7580f6c90119f9d8c15080543ac45ffc8365e1b602a71c3ba96e6ccc2da7349d2b435cb18d2c76206bb828140fcaccd80f0eaf7bc0344e12b730deacf4b53a060ed3f2ca853ed4e5f9ed7a786b96473aeee04137006771bd9c33ffb1246d83b666673e1847f4ed45a7ead0744607eb280df3e868b58f301700d8a11fd68082d9368ca46bcf2c25ebaec74600903043b0fe654a6bdf5537abc4b94fd2b7e6ffa5e0140d52a8efb09a1a1f2d25b96782c04d9712f53c95147eb00cd91ac2144543764a525928497d026f28316e02c028b62cb5cfb8160d28e42f1d7cd176fb90279e027393fd551f59c98ef34cd88d4f35b43c4163cf211eb1524380b7255a3d1fae9460be142d81f69b2ee2cc45795128381c64b2d5fa0ed57dae19dc853e01d7303332472756525e7af5d67cdf318c7531b82aeac59c5f4efcf776798c00440ef318efd93cb297b7218d6ff833d0c6e4863066c8b5681834d11c904eb455b4a0e9c7becf22b85520976d45537a00a704366f08bbdeb6ade34b45c5606e6c295405798c181270293851881a386daa5ab98ff92fa9568faecea51d2d569b1a5bec5d1d46238f5433681814ca99bc5c2ba3f0a8e88d5e5929e26c38031b3fe07ae7ec48404424181984c9458c7e153a6866b62da184a6ec5cd2aa1d4f960b949e88929f447344f2883280f60f03ab18115cd007a03a601be18c75405017300f1c4c62c19c51577e9480fd7a3ed014f17785475bb0b2ecb02155d63f8997bc8bb31a1845939c56c7283981565ecb7ea5003fa891e95a75024879856d1b37374a938fcfe7c532abca991878b87c0d430943d42917f65a47c8dc28ddf6dd4c8c5a1020935e796768fc8e0cb3b5c0d10a5d1bbb03b8530cf2c9cf3b4e0ad7bd56e0a9d7800aa132325ffd3028c4ae5f3aef500ad1b1b27a8f6a82a9e560466195d3a4a9cbb2e50cfc7fc01dc45074e52294cb1dee48b6c12f9f483093f0048844ddf76ac38f57627b137e8ffa12e044fd8868693c8c888d5b67820a9c40662c837e26c64528b6151f7ff436d59e27da786eec6aa3fdb7274ef7c0d6d1b8b28e170ea7a4524475b425d565743b4cda3b8e49c7c3def98fbf4667a256541cb08d60b41833d1ef149341bfafd3ceff148f57562ed8b6b8fc06ea61a808c10dd00919fb9aeda928b88b86fd1c9b087bcf73aeba8b9c9a2a07e60c4021485fa69aa272f045d0d93be4d37f577ef5bff3629576f93b4bbbb2346a725a2e391582885ea0dd3dc0bb9511b500fc26fe2e917ae8125a13a0cc1db4137da57724ffa6be85c09292beccf2023a61a1b4c12e11d49c0b24d172060c397d6f1c0fd97e10d6262eac189bcb726b2fda5cddfe097472cf1182ab896fbf322599f6b308bcb5f89e482a96c2adeabdba2ed6867f519697ce1cf76720591e619c8cc6ee68aa9c0d3236e3840bf21df89da12c6e15a9550550aeaa3f5def36b24076b3191088c426369032a5d5a7db66a2a47755a4972eb423f07f403fc535ec9a167052dfa3b6bc1167077ebc00b0972948f7c48a98c4c37f0242a679749fc5884edf137a12202059f1bbc52188699a45eb42111688a8416afc2c22f4ed2b3a9671adbb89a14fa752d59a659f9f6fb53511dd0f3792ed00047a0e9d5839edb651404eb720a267bba603d5bbaa7c0fc1cfa735785a69dd53d104846e2449f3aae9b0b32d58eaa37a1ef907f434495e50967aeb5970524281fdb596b4cfda99049a05d873141b1da75a1fa95b3f3e7a1b95a4192e9dba02538eee603f4bc57d80efebf00247a378b00d3fadfec96b684c3857afa47ad9783ef1d51bf02b0c2c1e552b808c886e197acaffe32a24c8bab158e5d34090f3702530780e8089321b5f0944916de4ddd76fed48f33591f676523246c709b8aa0df52120a5cdfc827c4ce9ad38f62f5534e9f0e6318217b0de0658960873dc2caa31d0974763a7fba776d1466a9445810844237f5247b22f4e1045f3fcd195cde093fc3166424db3cdc6535b7ad39d1393111e8f5c1c09f67f501c2f5f92a597f9f1f54cbcb90338417cfc17be9b11357119c4b87ea2431747feea825963754d4e71e396188f2809783a21475e9370199490aebcfffaccb90452489e0c6502d513421faa93866bc0d3b5cb29fa48bc40e88ce80aeadc1ecf2728415be32d23a8c9d80c404a260cd5435185d6a46bd5d6788f888f26d77c0e2b58ee61bf502138cb92538409df8de0e68cee22018bf97a293fa855c830ff611cfd7fe9d169b1de1a8520bee360aa7bd966e0885e76126e406271456effb91086a7a9098ce3eca83e7e2f020dac6466988fd6544ec48bb6c0e7db7a1af51511487097cf5178907941eb84886ef8a85e8243f25ac1a23d561738b8c6293ef05aed96fcafee3b67e13bf817c8b4e7f8500b0d1e8275ec277eaedeb1eaf43515e7953acd028f31d452aa4ce3a1d14b2334cbf5f23c45b1a42e40b2d0439dc9bf32a9feef0530ed10d2cbb275fb4f9e5aaa4f98570df988b1578a4637921b92d2945482073ebd19d06071a5f7bc5e3764594ffe9a203d995ab57e95d608447e18c46a56a85f43864ef55142ccab0aaa07a140b6bb1ed78e3140087d42bf40cbb59e347d9375ae6b2892278717ca80ba4a479111018c5b33bff75f372993e967952cd60980e007d4bce9279bfdface09fc2708341c25fc5c603d009b75730ee3a19784050d5dbe872af33081139e13c7d14ae54414a07168d3a14be4338376d5818e9c2436490738a393849ec6ed05dc7d269adc2acfa0b193d238f7298fabb85d1c6ccbd07a4ea1e95abdeac116621167108e75e6fc4a8603077c0cb89732e912a28e20df79252223fbd8e77f247106dd20a505cf09592c23e3f0e74eca87a51a103be9b5e3d5d145db05e04ca60a6e0ad18274341a30282cf09926b95fe506de3375d7060251163114ff922b3a59775f512f470318b485da93daadda6b3fe158aa76db2b0524a8c25f6f834b58dea983e8313654b2000264582b575c68f2d0d93dd0f1c13532911ea615559d9c614a85574b309592da44964950fdb5d937a033c876b5fca86ff6003a0c6a03532531009b05019547ffe48403552eb9c2816cebad23c3f705483544ecd068e2ca837045d66386e58df8c48201f1368375272ffecc5753b7d64360350622393e51636031bd2100878b976975a2a38566f52bb5f66df73ea2b820e108df1bba00fc32594e49186d212c4b945020c29e1ed1e0c02b79d50f50835143a683d42ab26ebd7f775d6970a1713a8bbbaac6c27cf45aff02272d77f7fd98b682371bce7246d8f5ba04667c8ad44bea7c764998587386ac688e89e9c1508f7a3b33a8ef46526c61588ed45d80febd2224f757403e76eb126b73599b78be2bbeb143edeeb732b6a5656ecb867fb6649a83afd6ac41869f5de68ae89f6ad3b282c1f308996b11770b7af65585413bdd5931a95ac2eb45db0e239a056206c50effdd72f84a85c708600833c25c402abb9b4941a5e46a54691f03b8f7459406dccb5cc1616c5b4dccbe138215eb850d47cdd153e1c3080ec5a653f89865365adefd37220741c7c47dce48a3e3533fff8c344a78f1fb794f97a501512fd299f6d874caadf86645f847681592c7024f7cc15e2d645037bde537d4e36581124c2096eb3dd840dfb8d00dc6a502685bca96dd0a48a0e79384ea1bfb7b410265f44f8a00614e9b112e0844908427680159240d33752e69de9dc2dd17722240ea0dcd127cdfc490a15023d9be7b52b97ffe2cf35c3c18e6941d5ef7eecf6ad9bd8a93a2f8937fc2d18f5d6b71fe2a4551b66878012e2a82f411185a641f0be11f8680ce09ed4947b497e44f1cd7a4c9894995cb705e3274955397fa65d842e769697b5650e6c3eb2fb1e75c835de1f2bb4013cbdf6ca0e010665a3790b4456fe284da350812f2568018711bb1a93ff93e31bb4a950c8c4def8b16155b6b836125ee1c8664ea47602d028065d9777ef4a9232a7681c67b27b520c0660593284630d132d69145c9a2195149503d5b29d765e4620b006f3b4da155d16bd1d283fbb7a71ba0a47870fa262a6283ae72611584a35fe3028e301c2a81e2ac6d0d0d5cba6a2eeae7c1ac231cf34f376661e342a20523a1f6c9960c8c8c3204b2cbf6d2ad1542c73b68dac1ee2722742e06e87467a9e911e5dac93bcb11fb4a9a3eef89c302dd27ad87541a5a09f5dd8418292da26069c52edc9a2ee095deba8189591d2cabc5596f142629d434f2fb32c2e0317c69906c37fc733b9a3707defcd5c7696f9ea1b87f76bf3e89902b2fd9fd8f58885e02c58fc4beebeaa7953ba3544c63ddc29bd136d7fe2b178591bb1ffd0796c523200b21bbcdb58114fd70b40503232c3adac184cfeb295836f2220a0f32a3bd8c070116fef0386114c8e7718d2823813ed4239c41b8be0d964778475faeacaa8669921f37fe882ef428151a7fefc07e14a7ec518f705f2db44af451f5005ee05c824cca1f3386408a1b8a0acdac650c8dcd53e12732f29cae659575031475845d2f220ab4f7465b80024114b6454ebe4edb6579c5e54bc6c90edad66bed01ce07d6eb85a41427abca64195f262354d09d1f0a2fe5c96c59cca50b36c9d92938d371d4480d5be3c77d55bbdba173780b25d99f22c88f30033e57a02be384112874776c04de2399eced7bf90541d507b85669290d5449fbff547d365e77cd72280b9cb81ffa43abc4eb644ad4d40a1af902bf312be7e3bc764a01095b1a84263de11517b9a4fe48f7e8cacc6a1e155611f7f8797208f5683b8e3a3916ee8934b193042dd5e4c5b9707f5f555c21679400263d9ec7053be6af37aa5a4b661fac7b93317108dfb7d2e1671a5720b77b6e60de607c4e675369df2efeeb266ad29778c349c43f9f4f84aef1a13f7d1b97b71623a5da04baf80caf181cd524964b3e632b2a8d44eb5fbdb61faa407530d108e2b00040814128417f5e0d632f37797a5c37f47a74865967de7e9792ed6d661908e66ec50f5a367c48b526935c0d9c3997606637db51020555ce6c4baf428f4b4bf1e9425d080958c310b5925e501bb0e14a0931c4ad047e548af3217487c0cdc8c4d1061975982d3d8035853bcb071f5cb27a0a9892927835ced2cb393d9600fb106363d52ca4bcd8464f1dc2f6e29d8c6c00b3c8100d7717ea16bad8c30d91f9348d0b985bdeebf85089a65433e7de73f52cd10b2c6314f007bb03b51889b8bf54a0cb306d86531683e69a28a5104972b2975df67e0d328c8d9315f1c09aee3983765171c8a382d0eb3125bbde8a82a5d78f34ed6618d16667478a113217e4a25c0743dbdb3199f1f93d6de178d2369f329e473410d2ec7cba083d340ce0dfcf1babd292d3e458abf2a5ae6c7e17503b5795087967ba311b4886914d6ecd93abf2956b2e974b797b35a847aa467cb0c03523fbd4e15aee8834f1cd327338eb5f8e05ed918bb313b0693c0e593beceb6a616ed46074fc58baab840be430f89ef0265d34f7a1d6d51327cb39c2a7291d8100dd5d70dec1137dd8cd4b2e7fb66a9349647b09515826558ec2695db2952e850cb1e728e9167d47859bef837f9ec08397ab61638c1bd75999ac3291b6c0273068433ee6f0c80f8c4665f706294569181d2187511b23629ef9acb12036a4fb5c94d49874d744b3fbacd2df364bb91a00f8749e8e1d097276e527c7a39632b28bbc8fcb07a09fa033d2df40ed0646c5cba6f01cacb00f613241dc0414e3ca3670ddac4cc15f470bf44df508a4128fc055afd96b685b73c9c68245b4dd72fe9fc11c419086706cf9ac0863672c7fbcb03a3f7e03095673b51123746a4f5f3e5cd0fb795df56fa8ca30fcb5ce06e491e544da6f686bd511cd8521de4390d5a25498bb31133b21640940af679501748dbdba231f23e599b0fff275d08cd6da76069241ca0652d81f410e8cf7062ed24754114aa9ac89738986b53e4072c61960028b7d1640c2f189788c4a1819ff29737e3966466231d73050f6e6e96e2884398d9ec410bc3808ec934927dc490e90ebe4a5a344cc28a2a21f647014294c12d7ae18706b573e33c1940738a69c3a67a0b0b3ab54da36a2ed87592c27cfeccb1f9825d6cc3f6f0fae1403440cc1acc507a46ce6ea09d4be529587fc08b191c475edd07f49179f34631e3d2869096cf615ca862d0a342fcf7398d6ee07738a494a938ec8a7f3ff709ad2c676d16f9273ffb39b728ee919bb8587b57754eb5b10f016b9bec33d8456aab9e2d00c586f344658899c211302f5383f98fca34cdb734c9a8b6faaa0ad086ce87338ea025f059ea721f03eff9bb4d2c242f898679723b6b89521f0ef97e3ee5ff2cce00c9cd52c19a7f919572ad23006c121f0a58132cb6b11216866193328bbf730f898e697c265bb1e72833607cd423bdfa634f2f8cd0abfc26585ced3ac8a19840e794a62cfdd2ce56afbd9e6661c7ca5e634e972c8f30b1ebeb83d8f2624644cfafc3227ef4a642e5f7433f9c27334c389ddbc20c9c242c929f2ca58ba731959d3ed5a1ad4385f7c41ecfc433f14523c93b8f32b10a6d3a34decd8a8caa2b37cf4a630544abc18ada3d2dd67c579597aa21eeb4dc73be047e2dc7857468a0b3c6cfdb4804bb13d516f4a518554448bf1a5ffd1bf0dd52f69f317b30a065a064163549f86ff841d62579bcee64478f8850b2cec589ef0e078d7314e15c895eb82620cc4d10bf7859004da910a4e02192c88bb61821417245979928b26f7cfac45921abdedea060b08860aeb269e85b49e10c6e13b87cd55216d6824068077f138e40459b1285321edf2c70dd30b18ded0bac9ec47ab6db6b8bc0a69210cd0ada77ac1d00cb952c653db3aae5c8ab2d9b5ede6b45e276ff6bddd13590013eed1603bd2000528d52e355aecc1917aab6e382d0269a8c16e3cf455031dfde70e6b6b7934848f190999d875a84c40e8531f30f94702072c201ad01dc745a2d7be62e35632c5e2e23b55978c0fd8b01157b099265ba0d8ae58c4e87336f7f6e0a349843e2cddb3f0b4d1c77b28ed1bed6b1a5c9ea1af3825ec77ee894d561c4c523f088eb82a41d472407390b3fb87958d890de4ba414013ff5fc150eca7981522dcd6659f31b730cb11216e27eea6cb0ea897fc9e192d7ad7dcd40564bcfa1479dada527cac05af369296fb021e9cfa4383ba7661f9c0be5a386afef4978e26daee8b9df5d8b8716aa8e9645eff1aa5dad156a6179dac2214b76652285347b6a30d980324e646a6c97020f0cfc524c5c86dc8fc9880b5b60c0260276f1d46dcf0460ccef67bee4306c11da5575c4bab151a4742dd23d03aa617faedee28b3e02a1a8744a26a79d05351d31d2dbd3b1dc6182d9443350dfc7a70ba419c924e3ab441b1e2f26219c40f19136f353f71dc12272c7a3e860fd184b6afc956770825355f9e243874181509cb0999dfb9b85e4198dfaa0ef427d739a45d79e8aea5e81d3194510962c1a2504d067848b9f2cc926e5311ca754d0a9c95231a7388e9fac77c6c01d2eb0c0227eed170e3f07d84ac3f9a70cd0fc544ecfbdfe6cd0980def515c566f365381e725f0ac195706cdc35bced7d120d2ca013a60c1413937e56bc6e8d3a4d0f66aad1c6a1d16e73dac5767dec9ce19f341d256e95d5846aa89177f270eef9772cda8603b030cdb0b50d113df0112af871948d497db825205ba6d4078789183b323c2099b09bc6dc02f8f8957517f2afd965c2a49cc67e187a00fe915239dce84283b171e18e8a89a8e9cb2bd664e95d308c03321c63a8f23b86db44395783b15cc4e21339feb443ddf11896eb93b27ed0127c99ea40754a29ce0e9ae148785da1912349135b43b83319e030a6fb83779f4cd4632bdef3385dcb227cf337751da95718025cc8d9337325c12845c1f9f8131a02c887403a6ae059889e21643ff1fc8d3a334f41fe918b1c3a5210e5c321f640b0d1fc0ebd7c94c3087dcfa8ec021980607ab1951ab4165215da2b17792d7b6c12c0d70f284033bd690fe97b19610953ae12182c4a5bb8f674086fdb71abc298d94467477e975fc030cab077b0970311907fd55465056da42d2c4b966e9aa38137928d0dc391b7f0f53ffd164af315c4e3439b1e5526cca5083ec08634126d03f2db315caa359cfa7bbc07e22c0e71e904bc0c03adc5e568d6e0857f6ef805dae69d5483a004b025e962efec9987127d3ad1eae44dbc20cc4ed55975fa8069fa14a71bf0555924515aee5248ae532cf79b32445f7530226684d53856cdebbce88af827912bdc7629e9afacfcb24e00f63f29002b733e3406f8044db2229bc426f60d05d92053f08eac503a06c1f57834c480d793e5c1917e14bda1b44be10fd255612a667235502b3268287316a2a5114431b65b11a6f473c2391aaedc8b924783447752793d4ee0ebd86759c02ed27c967240b0342d6f5680bd286cb5c691ac07c9a74f614a4730776ed0c01b7464983efadf87c34437e3803a93ab8e0899bbf5eefaf74044e617ac2f4221c3872695ec7fd9a25828b712b2ae3eccc24df2a3c149f61449c8b25f7f6dae9656ba5521bd9c1339871a856fbb1030cb2a2b161ea6ceda6341e95426a56fe9dfb1a0ecc41d6ba303d2c864805269f99c00d12b2907814bc17edf2dbf46f3b8e2d3a6a901f80bc72749c9959bc7a0a2e44a942c8e53a4f17b94ef31361cfd86f59ae40fb230c4a0e4fe9e86e7aba6482ce74aedb3f41a1c30d22cc0538d02b570f4f5d5f7ba0a75de05e38ab0873cccb1b2c54b6011b9e4ef33295e1ee935775337e9b8ad4a5989ae5cdc44b3db118888ef4c5732ac141dac928c8c2657859d188f63916558235b8a05667c9622963093cd7aea482cc6483fd73efb9187a3bf8a5ae1281f328efbade0fddb95c83cf21fb226bc16be91f12bb2d2709fe1cf4ffe0a866b1a72d12834d52b54c6a7f1eddbbb4981268baa040a90ffe372b62c6fb9f74f274aea5815e13d7da4ddc06258339d4be886e1bc37693602f1a296360304f0f1cf7b5a7aaaad291dbc9a42f9b8e2e73d2de4081c166df9666a9a8b17a8c95e9dffc58c7894638a22c7029c8cc7316282c5bad57b3ed4a55a09199b0477388ab4a120dfa379b2f474f1e335837fd7518643a5667c4778cc23909c2d4ec45b59bde1d2991e527091521c1a4ff55d7fb4481da07fb44609dd0246e7f58fd3d54d080062de44ce33dc91a468ed372b1641febf4b2a3b8e7db8671780bd1086f604d365e66f0c9f8fb2f965aed0b9837223f9fd5e69321a03399a86c98d1cbd85fe490462a354c6dffcdec14bd177a38c6e6f7c49f3e8b855117b4abb21dcf52ed36c35e8124ad8994d1677348eabd07b836084a45779afb7a4c18e2d90d39a3764bc5162c239a480bdf171b8949797ccef665160211d530280aa24890d4bc5e56f05524133d8c618addc6e1b2107338d791c9492451a0931f357cd37798d755c8205bdb808a250defb51eed749ff7d2c8d5b93fd40eb71dba905e88866af1d41b1abde438b85a34b830c494991031d5763c2730f75617134676e79b9f92c2f44e534f25322e11a49913203c74bf719ffab9699458ace6202bd3dc2f16c8ead99f8f5566f7eaeb02b151793bdc6c9fba65246b627fd24ac8ac7a6d00a3be6c44d01beab1321e70373bb380855ec89f4a679a293d8319be64017ae340c1edae89624b574c4d5697f874453574878097120df200a6ac87401eebc96463c9166a13e488913f9152c1d1886724089d069fa6a4ca53deb6616891dd166265134a80c5216f1c1a6f26da1148f80a1b6e8b2c1bb684a1ea9e7128e098a55a85c6b147d2d0fb5c580b88f29496db2443219ab1c049fe05c988020ec3b8998e1220744b2de4ea069ad0862304e2bba2541aa76cfd01a475b5de560b3b3a38d80706a724bc1ce5503fb13fe00a02c57e1985e88f44d87bd1ce03a60b4dcd3eacefaf42e9329ccb2062b05c46f2938a80348a95bd02615127220114bcd376fab8c8438a92f91dedfe2a2c9f9534a1293b273c270d47ae69c4fa0791b72a1e9970f57200a507b2b936ff255a39b9f21ac72c7427f5a49645cf13f46828470511ebe06da372f201c7bb874c9271eed3b682abd688e7c1419c433411934a428fc755b3bf13733b191ea74d4012bcea36b8990f73b77a75279fe1f93dcbf029b24aec864edd68c08894a0553b71774da43aa6a07264a9219d0700058615271083867335f0302222f0766faace8e671c0b6347d0358c66ac281d6832781014dcf4a24ab4a40578e6472b1b909224b0b7f2264f403aac1d28f5a200eb39a0ef52ad6b7edef94d644e80a77656da101a6e208b8e2d96b1d117acb84c5c3187e637c4d0d50ae670a3bf75c8003350785abd111f90fa62f4a411bac6e45f95dc6621b7be98884eb310db590b677b72db7943225290355098108e708e175492a7d62985a56b3b2cc1b2670958e35ad2feebaa38cf1e68a7445988be4b0ea535aac1fd4403a50df6bfd9b2878a4b97ead2fe99c7d452ff971a1cb3474e1e7e7dfad7694817f64f913fc6125cff0d26943fd4e2607bcf513382a71cf76873844a47470fcd14873be3d0595640b1ea9990b5b8c0964fb20bf607369b1b6528bf56fc2c0e3acb1bcc0165caad205b906f54d183cb672addfead8a42db8d0b9059a39b953ffca9daa546ba58ecdd932e38ef991c7d1c9d768a50fc91f9eccbd13c91f9acccde7b8f7247f82c43997cc516fef217396fb0f9c600c067c02122d2673db73aae75c1e824b82bcc431e99815ea312d66c9efc59843c2a1b0c261922268a87afc49be6ee6e56c05b25833f86570c801fcac70d675c520128771bfe26631e00fffea471f7277f7eaf58f84590c18fff71c58bdeaeffb074581bfc797a38f02feef5158e1d0d000f8fb04ac5e55c42c2a7227997b77222fd74548590a0ee3fe729845a5ef2729e20b4517b799aa080c78f63d48396e42398c7b0cf692b9440f2e0cca59cf26948e4d28610b9500fb10f7dc09cebd739f82cb261013c6bd749a404c991379e118c20acf70fc317d0805993322737388cc893f7836f0894d992a0ce12b428f5ae49468917b1a3695167bbec0dd4c8d32b3e630ee555f5585f3c961dc731f576754e6385596efd46b903bdc53d06d903b9c7b60c2b8e71c88cc7d87e384ca9cca391fca2e749612e430eee537448a8fc3b8e7de6716756c6c2a997b0e8516b9e7bea35e7f22f741ed1f1952e64f248c7b8e4603010410b4b161cd5ae65e0e39aca70cee53e818f519268c7be944ee70dcff58e17ef4a1ccfd091debe7be48c7fcb947a163f4b9972f2ea48015aa09a344962679e4f1827340dd2bc220028b53e705cb1476090b96d50e38952513962adc0f58a8dc31588c68c012836d82753c7552708e2bb836f00d924a0bd6912553143f746a609c2c99a210ea8e308602411298541a495eaa24613941d212642401c11d25396901146b581b304d964c507061a76056964c507059a3ca19501cf1048a117862a0d0210d2896dc1d70eb8caf0996f9629fc0c25e9122892b494c5c71228c2b26a8625c9972c5485e1c954717b703907b3ddcba1809306ed06182da0089251c34a062ca0e12573c908197211d2448d0030c8b291a2051f444d46228032466f00006594c811d11070d3fbe208947ac61838f2f350c2e0f98d7c5d7c343fee3882f4e7a6c99e2e388293c106a71f43ae2891b40265a8f235030f4583c854718edc0c38a29e011506ad8c105ea8f68e2011d5740f1387223678b1d4765dc80e3a4a4e3a8cb4d97a89ca3299cd83015e11c41e1e242bb3942e249cd17219ba32088723419b98e78a081468ba59acb7354030dad8baf87ff7e8e379ecc484113e606992e4aad2d88584d4a334945d8cb910c1238acba10b14c50e483caa9089b8009946fcbd2ca05de15482aa819ba29689f1833a4b60c795e6ce0969c3a2a68b84d51a926a06c593c71247862675e9c2e08ea8c8bd17679749861b644c46444931baa1072c386d91451f73e3d993c3e3c3d3e5d38b36289a9882d6a9855a10475b1ab66c96445298f3f4217463f285df98189aef68309b210e2b600775932fdd083089e746bfce0a4b3e107a15593301c104c1e0e3ea8e093826db264f261884ec8871bba23b02a4b261f963cf5d086bd827964c9d443976f053da800861e8e544f78264ba61e3e60b9e02f4ba61e882e0db7c65c1e704e964c45b57b4391159d0830ce92a9c8cab604d764c95454821508708e2c998aa07c5a14d56069c0322ed890f0ca0c2e0edcca82db8265a2d8963057c5e3025f253ea623550a7818e2033c04d139e12d4b261e7e50d580bd2c9978b8010c1e9c20c00aed52f9a289a1b5917b264b26219498685042509ae7ac9e0ecfe76e96ca0409497a790eaa758ba62087f574ddc8a45e865c949ab61841ee44a0c5f9228fcfccf24eb9336beb6bcdc473b656aacf5bbd5a1daba5f0d43c3cff37210ef83a3aef3d25a5a02933eb9b72e725b6c8938373237bb5cd6b0155ee751e7e9dc78aad1919562b95f2419fd294ed5edf10fa2fb1b5bdbe210e56905ad84c0632d57ee7e31b627bd8cad2c13fbe21d5475d6da002f29dd0b2131a369f8354071edc0f62dd7720ed9e1e9dd7abd502c1fbf1fe5d2e8c83b85c184b1fb5171addbc73fb34683eda726f6b813c0e93f972d8e779f5507beff4e69d3c2c224e5151ae201e68d0a37b69efdbef56df108b51b82a6c89800030c2513a8bf4c8f33570f22007c94342b9335fc62342e2d27d8464eeabea1b52e7ec5940956d73d67782923cabf80a6a71ba4ccb2fa417f9b3bd04fa204b1e2ed08625ea1449e3c9895caab9735166f1e1d1d1913b60118f274e968010041eef953b15a435af9c6da625434f98a1d96030a70ed30619a68884438aa99dadbddc2ce2ae4532a70e790e39038f124c77d35bb630e529bf7c1941c266d7b9b3ec3cdf53dde4f938cc3303a30ef29c8f45f629a2c8fe40d2f53a3ccf4abdcfc880ac222e5b855f1822a11f85d01459c8f6f739cee6271d720616797a22e023a7c78e1bd26f8133a0cc06dea75dcd37a4baebf0c9f7757c029011420b0ef9e68e87e772f91db823cc79e150c7e971f3c366c3ad9c6f489d3e669d18f088ef51707aabc5b2016158acc1b9b171e1d450d59441a60432a3d3edb0745e1888284e178f8a034f7c17967f3b3addf3382e0a8ceac0eb3ce87a3eb81e5e4095ed33d87ab61e6a639bccf3f1745e2d8ffe77809ec97c343a3e1a1d3e30fe6874f8f0ba1f4f06692a85d8bca4cd8cd2a9e647f9945d36a0e8b0f92eb026070dd89a324439421e9d8ee4e62417c90664cdf25b42e3e4098f063f30c08d001484234e2b67622ec3c4c8128bdcb974ba38361984dc5d7a715e2dca07b38fdc791f8f2a5c6196d79299992d9a1c35de04714e6851bed492e51423ccd0e6062747c70e6f825229773cbc098ab97bd09be02b77614f4b030d1a392d9a335eaf6e39514c7bb84743efd24aa953faf633a53c36b983c78b3b8ff8e272521247f250416d3e77e92e95d39ad52b87d7170dcb5b32333357a6255912e790ab1a77e92a970ea54e3f1e2a30a5943aa5d4e3f182278f9719810e2795c3e9b83be4c683da77975e411d4a432f7b0fd9eeee4e7db88b94de4c7fa80c60867cda72e55ccfb6bbd56ac91fd935ffbfbfbdfdf9b41ee387ed51535852baef9a46aeeb87cd6ef65623d4c8ffd78cd46a35233523466a132ac4a0d33a5d52ce6bc199b729a5cf507ba7a017535cadf56ed6063d18d4b4a0205aa32968a73cb0e80aeee4dea7a008e6802e3870d418f9d3efd291c78ec236e4eb31e42b0447be2de477bb77fbb18b868845b0c3eefd1b317816dd0661f7d27acae8301dfbcede7b83bac3b478efbdff2ea37fef7dd165f52b1427a452a98acc80b47638fae4769ecc7dea5bbfe16fbb45ee777e0291996fbdccb37017b67a6442d92a0cf21e45222abda664d84afbc9c6db5a8bbb267f7864fb0da69f58503d679d285bdb516ddbe9c74ef2c27672f7097a0dde8bb3740b5582cad257bdd357b593cba693c3ecdf8b9d6e700c509f7e02ead390c990cfeceb30b2ed31b2ed2fb2fd04d057854cda497260bfc99d7d617b9130db644839d4025f02e546b6568d6c7ff693dcb1473678032361e1091e3d276bdb7edbb7d6fef5b82a3af922a18b69a463f81b0031d6cb3c412c3b31b984faa9f0e702dd4bb933e2bf41938a105a08d12cd099a7795be00c38c5e4587f0464be1f002da3c9f1333fdedcfaed73802e103bac9fa761dc7728db13a37aef3f705492bf11bff79d7b32a0eae7f77da702470e1465fc2c16eb4b909915b27ec413c4e038337e1638cef7561fe43d469ea0cc2b95f741fe7921f77227c5813209cc0ae0d6c58e327098651d42bf1394f4653560082679e619e6b464be49028f18af60c32902c39cd587c1ceea8fa93a54a4d466eaf239ab4fdf1d46a5189c93a9ab330b8b634ba4cd06fdee832578a4fdf2fd837a82207d7c5cf431e7aaa1357256876a60d201dcef93288aee7e27a73875baa73bf7ba5a3b5b2df5b6d3ca1caa9185d474b20d0ddde4fb13ca6c41bec01c923f3c5dbe3f677883c4740fe94c79c006be384ef036dddde7f542faa9af41014e8149c0c9e4fe1c429a535c56ffde7b6feafe2c86fe52cfa586aed0b562adb5d65a6badb5d6da0f76c096f674ccdaf76999b4d6dad0c9977b2b6f3412b6bddc84b4287f78f2f63cf2c7f3f63d3eb293b86cbfc9b02577b60fea0f8cf028066ddb13699d16226b77bb9b1b8940529e9a9bc761f47d94a0cd2a4939522240ca6c78a46b281b4699aca0ce28f4e94789be2140e4ce10549e04a1c06594c3e3b216287523531684e8f8ae29edfd7d81c89f22f5e9bfcb6a889d052a97a2c490644003d3a888eb677323b0aa30b48fb3d7515ab4ff819dd37953c363171d8df2c9a8632306482d93b285a0bd64a9e4b0a082cbbeb7a36b1e3169d904d3b025f9e39f2444484f8f8ececb75ad3d32b242da97341040e08003180cb4a150b2fd86d2d16f4811187a861d66a5dc88c12acc175d668109b36f2f16b3b5c094b591c3ecdb4fb5e29e66936c5fe016ff586da02a8ad91f43b0450eb3ef16a9c5a26cad7d0ce4cf04313069b6913bf6e737a405fb454a634e51ce770d08e758b38501c81d6f61c6b1a323f3058f5ecb741ae62937b2bf989df6cc14d44902ebb80d71e0f165be9b5e51d194f3670a265668f2675e0eb368a98f754fbfdd905192256d90746ce6e977b5bbbb5be218a46cf6e05e4d0d424c32d879df9094844232994c2633066e86c98c7a42a265fc4ceec558b2def325de53d5e77dcb7bfa9d23794e5e78e1e4b2e98617cea8efc719f581decf4fa5f2fefb26d265c9ae978ca9f91c354ff32d2485d4f837c45bf5549a5548d8501548a61b336a46d5d4d0f0b66d5b8dcafb66728063c790e9d38063cb90e9b7c0b161c8348f738cf7d3adc36ff1d52211b94347a9f495a0721a4dfef03417d98c72187da12d869ac849a9870ca54c67d4925353c74609354ea52427fc9faabd64fadd30e1fa4ab5e6e9cf288a9d883f8b62ba0abb8686345a9417d2a268519412c99cdcb9332aaa63fead16692f39d19430681a05cadd5c0690922d26a57a4ba6df5a64901b8a35df495d033697865128e40e6d2b9dd422a5ed288396e2b814084b853c3eeeddae3ad336dd772c2fba97b2e3c91d98bbef306252df71dfbd177914976ddf755df713aa6604788a9961a8381313529daa351817eab6efa26ed77df70dd57d4775dfb5eefba9fb6eca9e2fb07ff741ed4f2d76df61d75accc9f6bb9fb2fbd176b349ee7efcdcd51cd6bd3bb5d86dd162f71e76538b5df73751702b779d0e1af5b424a7baee5d1d7b7521056acd1a5167d7d0b10b6c4b4ef227ccf436987e12f221da51deed26a71b2a4b173882336da72d5850a453cd2515765227e148daddddf439b0b3903bf42fd85848204d7287be05fbc903dbc961b4975aa4134c48ff860a5daa27a0357d2e4b4a8d643e35556aea1876ea58cba5b404c599b4700bbb5ad87a384aa84c5dbd45cb66bd605c62dca5346b32caa5d4c24a63ab95664d69d694664d69d67ad6945c4dc1048900d356ad36c1cca719c61c63a91b49c746ac04663e515c695c1a2c2ff0389532b7b4c4f5c89c9273b9cfbd37d129f2873ea7e2b89f208e72271711964b42b796391ea8ebba2ee75ab8933aa9a3909df4a384fbfd8ef7862192077653ca2847426242ee70dfab7e74cdce1940fda02fb89bdc5fc0a39e7b09db7f1f837dd56d91cb313dd0ab2cc91dee1b74a716b9afa06fd122f72ad0690ee33ad0532081709f025d05728773a41639a50daec0cda593a874d23c72259cca8833c78d96eb2273480ee33e498bdc146a917b0f913852e638ee5bf87a1df323ef4a676f9ac0a38797acb50d26db0e93ad7dfb94ad2b5b30b21d93ad75a4166d95d09568d1dabf8982476bed7bd8695fd0ef96dc49febc3215ea9817e9fa2253aa068f1b997eb7988e71324df0d861c6707094c07d8ff9a1e1b185684499fecc388bee95b4edd2fe6e5b10176ebeaca7df35740c3f75e5fbdecf256a91426991dea3259638bae0fdf9b1581813b98cbe5c11b5c2f1666b9dc81086ee8ce6e9ea29cdab68fefb1e924268debf21d7c861f45d8a84d1af60134919ddc8573fa4d07c50d3cc801e7897969cde3be2d1d57dca699153dab07e166e8dae5538b60d63df909b860bcc6a94998c4e3b4cc7da7e73f57bd63abf9b5303991c702f91304f2607dc427287fe4f121e7be95ecaeac20c7c81b961b9e34d2bd42265e28d3d26d39c9a3ff9923bd91d65e00c4ce8720d482848d584b61875352945bca00a2e238e1a8cc841871d6448411155e10217a8a14614222b32439b103da2d2846a890a1743322658b2c1280b1d88a8c2440e4fae6083054f40392308a22b3256acc8ccbf5246a09a7fa7d08d89a6464482255020e88269439a7f392eb8e0e6dfc9a24d21a3f6810ebc00864e015b4e8043962a52c4a8020ea96484105f7258c387378c9805b591a589158480480435c4f00697a63cbab8e4f9392f0ea4c092890b943cbab264e252c34ba6088f547a1e48c1e1fd2c1a47084aca0e4b3a4079c107ee965a530898645793d198dcdf6a24fc5584eaf7d270f4af3fab57f7d99fd722102276d164d8b2c5855c080cbcfa449842c8653a77be2a8f2e2402173c4a9acc851a36ff5edc09d1e29cddfc6e12e9c21e1a70f72a1e60e0d48f3a5a9c6ab264d27294b2f37f5a80fd7bfecc730a4082c9f639ee6bedba5a6bed38d082476a4ace4f4a6ba5209262488b9196223ab395c2294fc924c5529e33334961942593162557964c4a5cb20b39131ffa8648e9011296b9f51d28c1f14723999352ca0eec4f81fe12a4cf81476a762aa9f46fafc525b0cce3cd5347fea8b20853e0ee53e02acfef0075e67d0a54651192c0f7bb09439de138183af3421ca7c99df9de33e99917165182cc1e45eecca6b9900accf454e8422dceef0902773f3a98fa8e03c7cfa96d08275fd62879fe76a4ebcf4a277140b9233fccf24aee56579cf2912641956548e58ecc4ae6ac40e75282b97b4715b8bbeb134ae9fcc91d6400b26c82fcb91b5a5b69a554feb8fc80541148ee20b9d3bf830a1c04aa72d0936ef421dcdded4d7cbb1ee7d3ef57923b4ae774b5e843985236a894f3e53b21e8eb9aee04cf97124bd7bd66bbdb5ca95773e0b992bf33c5b5722d783e75a7549ad695fbed55ad4bb7f547eeb72c5c6edbb6cb717733e252dbf59427652ab3c0a4bb4e4068e0f19e81478a250c1eaf194065009181058ff4098f778c28c408038f14cc0ac0f8022809a806e4055017405c006d01f405480b202f404e4059007501c2a2098f9749098ff40aa02c4056002d015501040510154053007101da0224458a7b758c764eb7eab66ddfb62139d262926e4102e9c7000b12ea86774928162406a4ec7e3f1197ddf0d5b09e39e4fe71d290270cf28dd4bd1cc6617fbfbacdfb4103fb5fa72e7fe8d3ea4bb0a55caa691c169d3f1c7452da348e4c3b5882e57b964c4a4fe4f1c6fc86587865811279e4692e2cc10cf2d23b53432849c9c866816b964c4a3f6c5bca4659c1a4444483378372f25a08501a72b5d7caa163fe9a8153593265a9794b5e544db25c31254b0a6a5998982e2080a0b974fdc80ee487e0c5ab55eb7eb27eabdc54e6fec0ae53365549173397accca0008f74ca741021cb174204f610b29cf207878409e41292e57736c80f14cbc97d8190e503f1c0f9a464433fb2e862597e1012781f7c3e3d59fe0781c7abf220cb071a5a75703d0eb27cd907583c50f048658064f9df84c73bb341528d1678a4ad1d251f59e091661a9d2c9f0325726890e5b7a2a8f1640659feeca6875dd5abdd54a3923ce5ce7c17ecc7b0118d7e9cb8c16016f1980287c6099ce383081daf1d3de694dc068f50c98310bc0c093c5ef0dbc0e30d792cbd7a5c0fb75c39419270373d771f3d59880af0487fe04445c1e0864bee9741b481b96a4764009b1afc8881c7ab430315c4cb8e8fda063e94f07833101e25e0618d30041e29072384d1c1ca03214f3db4113ef06e80288163d7cbd9b1028f54965ae211f2019b80e0c99b19d38f47afe7cae18114440876c9a801e45d771f4a84e05d777731bf7408014848901f107c64b10f7a3c10c10411b8ece1c8818c4114ba94efdf3aed6faf56f6ebb4459f955eefcff9bb23f7a7dea9d37fa7ff4f9d52ea15a4e0fbad3da6ac74d1a53cfe8c81698b7389564aa1ba2ef8debee20a215cce2c45d46b2eaa1d6660f91d0b324a684801aa101a62a11fc915c5eb740b20777260c1d373987e9dfa3b7575c1bda4349b94585ef8cb2a9882c39cd226342e2da9abb448a911db869325f7dbe6e56d53c291b66ddbb66ddbb66ddb6af3693e6d357cbf6b5bd77c4b29c9dd9c737aa9b7a092eca13fe1ddd6ca1bb7fd05714cb0b8c5edb76ddbb66dfbae7b6edbb66ddb4f17ba4279db9e2608e300045a37e5cd6edbf6dbb66ddbb66da96aa1d42fd7ef30502da665efb0fa543ccaed315576ad5f1f8cab0beea7da0c33c3b0cac0f4ed4f099bcf3d351497e510ff5a104009b5d6ca39adebdcbb999ba9ed3b5049f6d4f65c6501acb5d65a6b7d574ec7bca6ca2cc9932fbd3699fe66ed04f1ac1e2761d486d78d8a7ba4b849d45a6badb5dad62261b556a73aa6d65a69adb5d65a6badb5d65a29adb5d65a6be5d24b4a2028615a6fc8e8b65aa3906cb5d65a6badb55697abd65abfd65a6badb5d65a6badf5e5ab76a79adaebbc10e3276a20682bcb9f422dd2a6955abad14b39ba03d19c460c01844afcb101bd5dd1a5d489fed842ccdc990441188c030e6e7692f4e917e9d891bdc2d5b4df0336f0787b5e97a173aff3c259d485441f5cc1e3159dd5d3693a4da79e4e3e61fe8e7f14471e024c59f7a9700c21f6fd0dc70db650e9c57075e15d54e28f8f67032f8c6559174a8751a2e9e430ef292d3a15215a74a7d9fdbb79930626a27d14d5c9174bc6c232566824349a1fa40057e949bf573e879830fadb4dd9bafaf97388299b50ab700c41158eb169348d76e4711ab5d08c9a46f4d08e3c4a27a24cdfa98b8ca4139e52643e4d252e610b9d8bc81dfaf273b96c1a3d951d6918fd7e2a9d8408e9e9d1d179e5116728b9431f025236d5a08100020730d009d34e5ad129ef13ed5e4a111d794d4542923f3c7926cfd769918a2dcea62121a12a150e392023f3ac1089c3e87380f5aa28304bb57afc32ac9f3548199a33187ae672d8a454a8e8645a73190f4fcd796a2e4b81ba3efa940b479c0a698a76d4a31f6dda4767dea31d4d518e5e8a87a0117fb478369809636308799cb522ddb4a988f4efe591c759e3e1502db2c06642c2e86350ca0f56609628326d2d4f717c41ade85a49ee500f6f4680fdbb0409ca1d4aff260dfa355aa5ce51aa3d2fa0f2fd6e47beef4c86eee3f480a90fdd8eb2b46dd843f4debeb7f6108397489974217c4a940bc91f1df9be1f8520dfeb4f0203c09f67ee56ac5a5d1b157d7e03478abd577474c02bd7e71141903bb8c22bfbabe8576bad5baad69d10d45a6bbda9adb3b5e680c2b3d6fadd5a579efc2895524a4955df10f72a6badd57aadb556ee8623ce750b4757aeaf2c6badb55677526badf5cabc3167bbd3d101afecf447e9bec2abede6f95cdd6d678ac8e3f316779ee7b1be211d7e74a32d5296cc0c6e5d1ad9a2c951e3baa1a9719777385de30273649a992c5d32b94129efe8df2ecfe61b62e33938d61bcfc1d1b2bcc72bcc52cac60f8e748727c1b1e29ccf0449732d587e833c58325fb8eb85bb526adbbd736af172ef9c5abcdc3b2f974a71771add3b2f974a71771add3b2f974a71771a6d5e5a56888f8fb5dc4ca566085278494958fdfab325acba90fda7575bbd542fb5da1faa2581973abd7a0165aa97213cbf7a095d4373b6d36ab9542779de01294c1a5291b9330452048cd4b6ce5ba150e48610073ea1c5fe4ff5a9bc152bc592329c0c4f4f4f2a48d8447219174e28920d2850a0f88402054a9ed90010d4b2427c7c686abe2e4bf98be00a5285a4ec610f0f0f2761f6ed3b074e09b37e9dcbd4da2ec7bf8e28d6b8dca5c20c7526c7e5f26c24544a46b90aeed367547097ab5fe633e16d6ec7bc0eb490f986782823039e4f41d627d353a6b6b54d07a8bb67c9d4054ceccb3e6b5d0f39600166eac24512f752ea459eb368468b6e061a2a567342750141ee9e760c081706ddb020226f1bae6cc49129c5c2d4d4032dcaddbc5ce07bf1d21d0107a6313ac8fef6480aaab421e60b33a060418f29baa421861710403d316907aa08d39a3862c8e66cfe7b4c30306d817d88ae10fa72c597ec4fb18f932ed9dfdf7da61401f31cf0e859b124a693dd26092d556c0903065412b311672531acb1858d2e61bc68a1032dc8916882862dcf87870b1c5b9ad263694bee1b65bf93a9eb1a3f4c42c3249389863126982579c14b7a62e69fe4859c2166f45fe8a121662d1c146892d08449fe04de0a8bc04f67401950c8163c62d6d795b2306ed6e7d525f73cbecc5ffe284a4f42ca3cf426ea5b38119b211828b27d99970993789864d6a8acc06896e4050f8b11cc663ec90b355a68f96226f34a66491cc961f66998e4b5cc92bc20ce6642a7f507f693bc20afcc64c222f0fb2b9909d982c7595b3dfe699f5541d9aafa79d5a83fb07ee43de66a38ba58e188f3178eae826c435f12c284e9bbd74926153284a16196e405ef8c2d33997fa1a34049c2e30799b0080f8bc09f573faff6e755a91a57dfc98ff52c70015a78dfe068a4b76fd08f5ce65648987d2f485f388d0ca56c2930aefef325b9639de64a47484926cd4a0b9c66495e48c5f165e6ff425b01664679c8304bf2c26be66111f35f905666342c02ffe8474576f658c1a31f2d6121ddb9c8d6c33823dbf7a3ebcad66bee4bf20728dbf726f963b35dbd552d61285754b6dfd52d17c07b9c9b7798b8f671048029a07afc3207f5f7ab6f0cfa91d7fcc997dc6905ba538bf655a083f1302ddaf740876a910aa6ef4f2d5a6f923bf653d6fef52cb27dc74202b1bea404100fe02df4a316adfd1e3fca76c9d581ae86e30a2da594324bd09f5a098e1e7debdfe00a1edd429d0d9050120413587a10238511516c388203175d6c18aac28833fce93f0932eca73fc779a4661c0f65d6d9a00dfc996a415fbef0f4bc75b27febafaface3347c992ed805f373dadbbd8e49976c9ef92d94207309327bb0842711c043b73bb35771b32f9dfaa25178f27494aea398b67449576e21ddae76f59ca103e4ce9c3d34e0f96060ef97f31d5c65f90d11810b9eaf1ac3b72033e0faf65d2dfacfdcad167d8336f0951e2061d96346189d7c1da0679d4bc2642acbf166ca0cf223fbcf12cc4fd1701465c29b3cce29934a18d383353e48038ff3f651e7b294cba9037be6d3a30f386735f778bc813b8f7403a73fb5473b36f1a4d23012482044c81d7ffa91302506cc85a94f8549aec3fc7dce6fd9ad92e27d507b619217665d3897fc48c9b585feeeeedf0305bbb2fbe8e2f1460b092d9938f44797edd40b7ed0c0f33bb99333236b64ecfe6c2d2aebbe86fb91c6bb41ead310bc6f72679d9021d7ac1367102ef49940ba8600087fc0d4ac03e54cecd60cd23373f47421118771a1d8f5bad146ee4fc1ca17e4094858ff6c92fbab149d829164b78f84333c70c835f3be03877ee68529388cc8343281f483913f12648b25703d29c77192e33cb5028f37f0cc7467032d9129e178808cd57085389454903b61727f901d3a30a76152ba97ddb70a4e54f0213c9f5b81cfa1ed0d206bbf816d2c889e7503b95e0f3138005326256c06a143482d7283d103e58416bbfe093324d2a20b60661bce212672a76f1410354432bed8c2200084425aec8182e7df045902d7b64974f3775280ffde39e50d1d96418288c1045184e14410209849a143932b56a891e58b338218d0e4430f514d448c40861d4d4d9821e68b0f4dba902f43e8b024c23e91343c30847d22698c476a877b9b5bb76d175f0fd76eb6fbd673f6776ff7532f73aad656c5f1b004ee73da4edbf2eab5d6dad559fd2380dc7ec8465338fd1287becc5e6bb551f63b5711700cefbb4e7e371c8de4fbb112e00d7cbf17e323356f97b6c8eda0813f8f9256c4653ad0f8a286952c5ec43034b334174469c287254f7011c7cc7e907d22f66f487dab63a9b7efcaf13cee7297bb5cff4df96f9eda52dbe6b2d984669f887d232b18652b26db6e32da9247cf22596b9fbb9bbcad8e516cb76ddb5e768d0e5bda8fadb5b66daaeb5236c80c78befc9cee9c14cedd226db972debb30453d07dfbf8238a9b084fbfe204e87256ca0f71109bf0eb1df90770e1c8fd4d1e2f8e7fcd0e1c8ef2c5fdd4a8672257f240a9d7c8db89b4d4d4465d9d4c453d620cba6256ac8d7e3923fcb2627a8e4ce61f7714cf8ed6fa5d7a3dbcf2f004a72b50490f423a11f961b675a1c133af7bb20815189ccb400f63b0cea10c77e7d1ae2d8500062ae2fe61a8af2e5583af972224a6665d9e4c450eeda931df57ebcf5a9a435880cfe38742301875e2ae50eb8fd9c24f44f9c2bcaed29ce7d31d32c0520e62d145b946fc31a8e344b244242424b320d83c8804b00071b3b50b42934c0c1860b597010fa6249972652cc261459bed0218a2e02a573a8142db84539e9d09000000000004315000028100c07444291582ccd4345181f14000d7b9e427e589a8ba324c8511032c6104308000020000001022456340e0ea3b75018128b4515e620379ab624902391998b432ba3d170598d4d8e501be4e488c29f0cadc2adbefc2c5a8aa32af140d2fb6c7a2aa96605bb27b36bf8f9901edc0c0186c534b914b572bf0c81ff607048f51ed1b034f2af5a019c9b09f8e0d0d52fc621c5326473fd84452112e72221fa4de9871d5311c564ac84343dd3a739b08286b5381ed6b812545c10bbcc1445213122962ec6d4f72aa1cc9b7b8eb4a45dbcc2888917b3c1e62685f17134e8bf7ce86983e3c2546211ae5653932e75dd03c9774d697399bbe3f8310570c969ad0d3e7b5bba25f12f6ecc48a6c2b45517a1e609c744e74661ce722de05147948f6a82c60ef9352a62139a48c0dd8c391cc19e0251d57394d013df77b75067dc386068ff8afef4c2d7f2501bee55c23d85626bbe006ba5537afad72e5968a17f4fba8c2796cbe070192e42b72892a78529e42039ae1b2f613e3b836a2450642ac767316197985ab8733b1ba9e6a908bf5860e84e324f5446feebdf9f87c672db7d072891abcadcf99671fd3e83d46855206ab4c48c170f34d64e0203622a7668f88836a3f476e6c2bc254ff7b1ef8310848842880b9f057b5ce08a4e498840bc7ce8822527f167d9f08a665d4128d50f5d2e51f00e0b32ea878f8dcbe016e4e9fd7e486ed7a3400d6a9028df2d925c4c1331e4ca3dcf645c082f5110b6173c7e966a543177a1a9a2e33dd532240e15f80e5ce95a6cc91906a053072cd5d73e2017e000900f6be2d33ecc87dab10e0db4c33b18ac5cbdb3d6d419d857e06684f426f835fc813c5dcc98fed4aeea363be3be12defacc52a3944c49aea92781fa779636bc8879466758d550200c100dae08495aa8342e87644aa78b5565693d9b58a5e514934b2cb1b4b27cc1b051babb0a5d38b410a9e4e50a1cf6ae17af947259d3197736b1e9d1c395f10fae487956ae838475afc4114e191066d61357642edec2d89642b174d782dd8d47fe94c3ac07baed965e394fb1c07ef60d4ebd10f32728568ba6394eccf795dfd134146068af2032ad31f17c8014db954a925f6578ca0588f1888c5387c8f0bc9e3256da3c635341ad3beb72bda9d197ab95e52b0f52da2593d54f07eaf71d83d92128edfdb09a9ea11cee80885d41bf8c379091d0884c87d412233c33944b62ffa0303378f1ecfb054d1d4be46bb3e79e30711335b13a1037e24fb3e70e0937511399e075143aaa2ff8411fa32632c126a46ec2f152f8898be1603be5631ba7c6c18d131fe00d5446a89340424feed48e0e87b0b03220a497a4660540d35f1f58370a9b5ee9d69ab6c6fe86156feba27a524ff5d1b629e6732c88b2942a1c9476fd9d7268e96db986a82b89bc90f44982a4d00fa960ba4c43418b2c67d9209594bba10b7c47ade8d0349a099b390dd39958741c430b4e8e34d3924becdf1cace3d590043c0f770a661a9651797a2ae34084434e57b4d2d296b5dd6245a01ec0a60eba82df2676cff5b80d98b539b70c976ba9dc03544839aa0a47e64b022da9cc7b84053161751adfae439c37e0dd621a71b97885d5760ff42a74dcd9035c2a07a4fd79e7b97ea67c971cd3141fd86afb611575684f1be1387899e14aa59e41c1b1617faab172916bccce3ad7a083ed8dbfe3159bb1a0b014503554f230b79607a3d47bfdbbd5ce78b3e53dd6c09fa2415497e2b9e2458b3709cc48fae204602da146706bbd4dd1e2a966b50fa369ba961a94d702604fc541248df64bf57b8961d218a3685f7cefa5b31277174d46798af7b263524f035a4a06d9270a4e46854a3e026576692c9ed2e0d24a9d5466d8056ee79f059a6e0fc4a1a5f43c06a08baf899b6ad1ae808f7ac2d509334d1604959e6578329345333154ea6ffa684af6a30731a68c848755a0b3d56d39dcfad69f44270d0724fe77cf10da0b9a9355275f1e2aaa1afa28b710a44506a2db845a0cf951a0006ed229480da33b3f57f542becca06c7c84e9cf11c93f4651450106ab26c555923d582a80b3a07154aad19251c5b5ad633d60413c9d4803d496ceba0d2888b9a4aeb787550e83ff49087de8a9500fd5f5be67b6b13b8fc341e54c1e7d94aba023245a49ff4013d3712dc789a8e3b16c4c83116f159ed2bc17c61a48457d49f0dc944368645b0b82601a01108f761b24a7f2afa6373ebd11ddda4c457d8cc79b9768a06f4236200ee21a125623ba3d7da004da6b6b88e7e2420035f97e08876ac601a09f9ece72588cba59effc8d992095a38f892c9679581010097bde0e211eff753c172f1069189de085f45f9d761ccf5979685f725121e4f58430c2910c608415e903b5d8093f3d936fc148e6756a108a23561b2f8d74257c661c76a71cc9197ed03351bbb630cea4c755244203c46425e9d5a1345a44c106b9d607959f05b1e288ad43c835295175e10d756ada34aef6c3682ef8024b876beed9f3f3e5d8099767d0e36311b3a83eda1974c4ac2691291147cb60e888c1081e994da585d20e252fc26779c4efe403723cefa36ee97851b4dd61a0f307bf8b243213749c126ffc86e68fa47abaef4fc9edf3c9eac359b38c5e37a452e3b7df47e92524568ac031a75ce170771e4ea49bc1a705ae1e80f13b131fdc33404f3b4efe647760328b50b5d9966981953ce1814a3b85d57f834fb69fbce62010054c554fbe0c003ae32bac51e4caad6259a02d26f138cecad8867b7f11eaf1d54edf0cb3225bdc5bbc22a2e16bd078889c542661477f986e4eaa5dc238a58fdf0af21510c5f481edd8a61735da7038a02bcd1bd4f7fb5202cdda574c765ef7da7d1aa1f9268d338d1895750bf922fd80d39f82eb452dfdf567f8d711055dc3bd797d5b9428fbbd1461369bcaa21179612470ccad83ec72e1f7c65a992d4e727f239a33da7ae1c783fa12255640a3e11afc7031057022a4c8b707a5710c1c11cf7b064d0c138daed8d999e2b8a3b2a9f719501800a9c0b60e980e00d1873645852edab173384dde771b1a7ae144030474dda9e336162f58f7545269a54ad75287ec2d9f738c5a1be509b8b82328b08029fd6348fc2e7a2791e52c700d12c7f4500e70112e69bb239585b19a000d0d4fdd233c26f9fcfd903a3af3156c482079a368f2414f12c2f7641b0b53ecacdfd2c8e6feb626ab242ab878fa54542074196bc2135a5e14fa0cc4f2f16a75851a8a99af35194f1f4a8708998d33282288980e61759259413c439c67a066a533e8f5f5de55e743ae28458cc8fa378ce59cc877cc1e786908be5458ddad3e537ecb7dcfb27a5fc8a677c872578880f8ad69c2168aad24ad3a21ce66046f1bd6bc57548807d8e072c3e28642cc06bb364af12225c2bf412b81950cccbd402b5dfd035ed34cfb27dab6e5cac5028601a573f3e8a13e01cf81b87acb91cfb18c3f2481031b49504124e2ca9ebf44c52c5e10c654fc4011ca24e1d42ba8c27ffee08d1ffd549d8b3226a849a248b340ebd5019e2cdf5d3ced0e4621f50c463d4b3094bd038b9980b9a901a375c17814bd4b76290219a58820dea4e3992278539472c40125e4f2289100b60bc66155ec9d77c96bf8938493d879efbc1d8014936a74fbbf262d1dddc4c96434e334d2fb2f344c0a543c78c0c84f00a802abd4f0843b83e23e2750589a3a61d7e6745775a16473f58da25e77e0d7c4dcda9590f3b657b9f5232f082285a7c4efe975c4f806b84553da01773afe89c2a75fef94167bf8942acf96423c2314cb977bf50702302f24f6d5ed04f4d7faf0611426632281e3b6789f6173c20cb2427f2096b8e92a8f5ea6a5655f9e8363a50e924a959126c7efd4ec119504b01579ec634d66577087cbf39caa2db9d187b5eee4bc086daf81a83f9318430b967fbf8e92e184f140fede03446e3e059ca08229c3077822903b8d58172a293629ef1783b7ef8974f42c3e37e398e21cf6020b096eeafe7d0f66cdaf7a100a7db98f380e4ce6bde2c1164079b6802a7112e95dfa743d7ace35b48750be34b8434fe16d04bbf05ac748d3c7c8044a7844fc8deb8d1ae184f0a6b11dd2f38355ae5a78f348a5391a148c341df9da895839ba31134e701edc91f853abec366b7825ef6e294cbc96231b41327abaa9929a6f4d15227e2ce3f874f59e30d5fba9365da21bb989061af97c91191b128ea0ebba8847aad0c1fedc6489544590ab1750aa4a8bde76784ecf92390f0af465fac899b093781ac7e6716b4bbdcb4b53311354b9e02569bdc934ecf847795701505d7c7d646dfeea4d6427a732b1aa194bf892af3e1afcc614014b1c04c6e5841ab581588fa9f8cdec9be584beab7e0e433580320d7ab8acf94c74b7295a04ccf2a0266adcb672e1b000b8b630a39ca4b1f60150902f29e4cd5ec64d30b37425d5fc99f1d9c5d9049a14d19d57c8c71338f7e40ae17d6680a2db01b6a22a34b7d379333bb0d0c824b3b37f45d880bea63cdcc6f5754359b80f81a18e9bc0217d50f9de46f6c5884779809ec1847959c11b1781d1433002863d4680399e701a865a2862a380ee0ca973735f2d188faa046b82fa59451c98a53d8ff48625013cdf59970082c030d583624aad5660b8ef5ed4b7104c30a54d116a1f6beeedfc474190d8e0c4a8c443a33751f7d3a23dfc5f9d208a6fa08d8238f12cf4f006f349946fd4527812c4f3ff0f3c6d92509a99b019e8d795a0ec66e1d6eaca898fd4a540eb03cb2e7cfeef05103d21d479cecedc00fc4a26459b5693bb02e18820104a4f9e53e3de6f70a82554bdcd01fa3b292ee36f4d46881251e681509595f0b005d34ac493704fb5a3ccb3dabc6c1de1ecd2ffc399600bc314dc5762ea4c0b7466478876226e1ab8b9e2b3c44a29dfc6fc8e1f8c1c88569ff5868e8b934538512e1994bd599ddd0602ca45658b66281e895440375451d8e2e7b469ef70c0fc4eb3f8843300a2711e4b5ac420aa503d50e72a6283dafd77482b195bcdf8e62dc52596868fc53cf6b2f5f119a4389233039a1694a9e4cce87576c3644e34a93c2634c9c228c12f04a65784175c8bbb815a1430147a80dd14e19a44cc3ed7a1824dbe0b2f3a080c8d1d60484b158bc65676b5ec90e7f254764ed41fcb9978a65eee98a70d30cc0d6d1aa3e7ddee0d4522f58528086954e2389d74d548d0b0aba30f90459847691d4e1e363bdb331da62a9d81c1bf383286c36d8c621ac01de359d699bd3b4dc6483833144defcf22454ef9fab4096b395b88c29ab494d0c58a46e65869473f9ef7dba0a5efd95ca61ffab175bfbf5ccdad0d619f123bb0d7baa417d2baf6ac3d94bc107463e9b99bd3b4ba2cb88e9600551e2e88e5abe65368800f50868d7616d095a7297da53820ecddd86c96722e2c9a4350f8ec53da2cee08556ad9ae6db884aafa6b80d0ce7ac1d625690ddef953e518cbcfde37edc7ed47647f8e15d3e1534f84adcca27e16512f3a57831e4703dfd792652419016aecf73d41524e092f6fdc49de4be39d701ffe0b5e1952c4e82b02c9827bfb00da83545129f02254e3744920e5cc4db2c353ce45b45d9072e54c6794f3631d5c61944869801f9e008ac28ff652bdcb64e822b4fc52b486d35da6aa47e6c18e6860798af602db4060eaac1e3990bc98585dd66ac12f749d633f0329b63ab826c24f130028dcf549a4fed12b733991c390cb9df0fc5f97ac4f3489c06f6e374d6bed08be3c1e35d093d86a1ebd3127e0f24fa1671e5f5964576bb161a8e4394ca33ba5d53af6b836c61e2400654b32461aebb56e4b4009cf343507d86c03c1c2742f7a34f9bdd5c8f2d12c4a12a93e5db4cffc266b39782be799e90fedcda6bd50e74cdc326feaa5722a827121f193c41512d95122b6f3092b8caa0a60331c4fa8d05cc5f8b59d483637dc882e6f1747970bda282b742e3a01efda79cd3934473b4beeb44217b4768a16b4502891a886da089895c10fa94cca704d28f78b4e424522af43e1a827a06e2ad97b686d2d79db4b4c16b186d15fdad83cc88652004965ce80142a6111e9037ea51ba26b599e6cc5720adf3c06bd4ca2ff5ac33c4c919091ab6a108a6c69bcfa25286eb1f9a8daaafd526849730de535d89ae6443015e949bad3b41c2fce05c78284b92cfa6ea00a77b6e3e5e1d17c8e27a4dbfa8b78f542094bd5e30cd92ba8f9b09b7d0cb8dfd1a741893a4ac740045e840276c59c662cfd04e6942565fe2aed972cb97ac3af773943608a15203e55841c50a15f59c1534c42d7e3de87c8217323ce1ce33b24a3672f74e235dc49c4f41fa5448706af9cd521f5b9857525234e87d40f5e5ee9c892088c3fab30e2abc8f58a0fbc715b61accf99d98ffc6f60cfb98dae742e4b6fafc0f8b282115bc14d7fc6e809a5ad30e2de6208fb129674475ea797ed05c446a0a6f15cccd2c1cdff7075fe78c3d10fe1601035c12096cd8159e406dd04c79eeaee23752e41f88b1e8e0b12a92d1a1d608bc17609c19e1d2083ae8b179464aa7fea8c1a51876405c893970140bf8a4580497c2688695b1a69231a5ed28637aad9c9d43c0e540b15d66b34725a1cce643ee11b2b5c23261120def97f3a15ef96fd7d4499c3d5fd57053861ca970f7fe30d7b87473f8e26c2215dc96ca31abec841202b7050038153cea7cf6f900f33cfbaa1ab38d4ad3703a7cae4b7532af6450947f7ad82cdbdb19e0a1e2b3806b4130c9f1ebd3fd45bf7288199e2358bb8870a53ab891834f297f55e40e65003115bc89eab09324f09da0c12ed16d9d98358638c30e387832332f57a69e8ee4681c29f7292af13314cd28ed25109e61c0882e51f0e86d36d1bcd470bf69859bbf30bb9f6c35d3675048d42489e92046f0b162189342d71b8ba1ad12a21bba6e3116d5f9178cc044c93c2632bf2317c08069bc92597dee98338259971672f4adcee46b2690ed1c7e12a991504c2836a8223e7a8fa818d7ffe063e226800d82d60e06dbf83b7bbd115ab66471c522e4a768ebeb592269ba03bf18efb2d88913f2a5772e39ee9044ff11f5a70925aefd979cb3eff2b2ef54e18f862a7ee3b6d3a410e2c277e50b4f2cb45e4b7a71c7c809b0e223b9196de8b6f237fe92442e219d218797fffa4f255f6154f6ca073a477a36a5d8802b5c4520125db245508d932f64be97e976263880caf48de99508234148a9d22804d33e63010fb369d7572d6dc5adf0ea2cc9dd8054da07d84a2a0e83e7f59224cc18117180da459f7821a17b18bde5fbc2ed6cb22ef2ef142f71124fa95c9885016111f4db4d2dab842ecec92c2b08feb5b906969ce4128b458511c0df56b6f09efbd7dbe9fd48f7bd6672bfb60f6651d1f163c3ca8c56ade0a3fd52d0552afa8457c9a2965862c4eef39418a6eb9633ddfe1f0f33796c95e4c7f41be968dc0b6711b63c27ceedd0a04465aff09b5e9fe16e1a62a3040b8cd76e253a2de7143b74e283feb47e384c9fe1380f424631d9e49a745a3bec7ee3ac9bdd8252e0c660a88d8a3f844e3177788f697dd5899362e2792a03e742d70bb52e5a760707fe931bcc278cf0a32b4a72ecfab78c7a0fcb6a94c112c1d6f85ac189c2227db8cc97376c042a25c9da6534b756ee4c3326bc331d29f3bd7a6c9fbe2ffd2abf573cf2de87ff9b805dcef2d367ab8d46d68fd70650ac9c6a09d5a05de777aaf7b8892ec5415a1bede6f8428848c4e1102ebdce3dbd75c036c818e6ee8e1fc7749d468c2b7764e8e2b9d5a30288a54176af32eab8a5e5db6e4591ffe0aba9ac1d3422d116a8280be5e09ff7e5811d926ba2d791a0850cf430172193013a2b4dc9918040a6bf16fc1dc111f7f4a761800f7c80f00b1089a27dcd0581a3bfdcf8381802a821e67ec981d3d982a482166f138b879d0587cb2600eba3d2e2c7835c027e5d7f2f1484c45c209f84e48ada3faadc10a85537361aeadaa039040567a10c7da68bbe856eaad99c8598ad68bff9f5a7c602bf414f0805c194ece4b2c314fde9efd6d4144233eed298f331cd7fad5103ea8ccb49fbb5e812b56e7b7ab7d49e73b0b1f11dd0aef8afa5ae29888057c5b2c17b430ecbf82129796498cd25ac49bf6041f016c3fe737f9bd791185639474e9d90a0e61ffd6b04940c0356c4274406f1977dc2299914e7abc950b1e6586ff01b0e608cde41fc0eb25dcb45947d887d206c8081306475a32fe4bc6f4310a76514bb940179f29ce60f32f9b74d5cdd3d52d4f73fc18a2c24649add0863c7b9eaf60ac63d911b9594f42e19fe541826be6d0f975e39827206c934b40c7d65d1b4ece675ac1e167b15dac7eca857e72082b253ea19295c68eea7d87406a46b08d3c070a208f3ec830fbb5747614f2d4dd79c54a4b0838b507e22c5a578e257dc266949c5a8552beeff8806cae1703148a5e4b00d553a6b601e70333c4dac9294a6911bece2c03c42508c4171095cfe548e08d95e5a4ba0913789f1faf9d7433539ea8a8e6a13246defa08983a79461213af5799fcfde39331619f3a4158fcf77a1477e69f99bbaea1b932946b54d58d9bf2aef70a7eae0244c71176594e5a42579f7973a44d7004fc7ed92fcff2400057542b52eae12e56856637af6f9fec452a3a6a0ee7328c196b37e9d3799dfabcf687253910988c3244542461bffee6b301926b8f4006c212e288d645ea941e3511f208c46836e0ab6abc19caa81823e57d98c3f671d172a8b5705b6536593e33145b30181fc8b8c92267e02e1ad301889dbe7d771acf31a8721c1303a5336886e574ab6b7add60080ef7e817aab713edd9d4a971db7d355f54a47e18958b34ed6c66316c0df5ec5ecfd25dc7524b61b31bb580c1bda29704c34587a6380c2af2b1a3b5e33af3d604c99a6c96325c33b2dc89fc6d8fd0f3ac07cff87dc48df97186d530208c5141f63a936a0183ad5769d45a70007329e172b3c5175f0e569f0e55b45498f0bfbc7c4bf99f4e84dcd1d0e9f74c4cb81e05e73cf9eb5d5839862a968995836360a5908ae511ad0284d222f97053c7204720fa3b7c9b1ec2c5b7be01fadc5b06ee159d4d99670622186b2ab7f40146ec8f665f9ff14d0de81904198b313ff4b9ef6eff995ad408a982c3e40407b65fc0bd72303dac5a3e48da64ff3ea895783d70a13bfe783c5a40c480ba313db02303ba95f3b49edfe8426213d49b4c21bc1110d5cfeb9345352816b37ebee3082abb38873418104b274f71cc368725bd5271ecfc922a631ab047604700e2f9f5c6e2341071708f9e5beeb43c27ce33cbbee13f6c714b091cbfb603e4a2a9370be590855bfff20bb336aab14061d62f3f5178fe94df155dc843872d32b0e74a570a46bd8d3d5ea397bf163007e53edbeff5c08fdb58900db9ff42baa575dddd4b02597279e47449b3afdd589aa4f85fdcc712a582b6133d6101fb2b422cfe0c4548273056e40aa46907ad0a0a755d9a2083c357d561949d8eef9de99446b056a4ebe8dc697066ece796f4ce8c37956eb1c81ef51ec10f50a3dc18047c907a45ca8e33231f93ab622978886c10bf46a58ca8c6f9d320b84aff8900701455403b2362e3381f1605f5c6c1ed545d9724fa8a75bcafdbaf133e8809831044648192e5ee0b7ef908973814777ea7d711f6299f3d8b4cc4df4d50cef64b222807b6785e08e91a88793229f8eb47e75b10c21c912b31c2bd501e1749f575155f3694b5384d21c07222f0793881a025a090dfa6c294b2f85e816b07d419e7bed7b57b5a8df0d2d609be2b68e2bf2af1160c3305f6b07b3465567002d5b8635926bf0ff546636baa3101d076fd7f59e7b62d755bc11365048e63960229bdb8d201d639df4c744ceb9d1a448a15079294438f92901407827eff280707d01886c7ef09315945de51d27a9c0521a68923b53156f7258215d0da07673df27e23016a04ea9d25c32468b815d806e6d8df5d76c0f6663db1248415125e628b6ceb042ddf5020e00575d69c3e6d97419f59ee49e084c5ff0cb1dc3d73c47495e04494a631e33067f9959b9471ad0a642162c489ac8dfd87597ad64fcc736abb88f61380aa37552f5f6975db40191482e2341ea65a53388217126c2bf7fbda84a56a4f5019e00b96ef6fe5a7ea887a051ffefe14075801ce12f7beeb7cdc7bf231e2bd4058b71b34109030d5d4d4d42c384254afa8fffcc9b3483a1255c4d2a4c871eb1105c60032fbc879e9163d41f93ab4adc4d0b8a418b1992c11f456e3faca3a2ab5871e7b0cb5ee8c700a93a5f817e08c431ec8b27f8b9f6c991a51ebbf437c74087e540ce8ea71f4e67432b0fc08d46ace193a69efc391153b9cc48342333a2f222e327d24317444e73d8d75052f5e3421d0d42f92e352f33940e147d58635c474ebd27f6f910dfe258a051838e35bd90ac4bed0adc1b63790570c3e6fc340c515e264768be12a2bf24d13c4173c25ba765854d8d14869066c8a49103983113cb6eda4c52bfd44e5c321414b17211662357150aabeef0a14b8c154fc695cd3483dd4045d5d7150b4c9dac8781f0bae4353dc598b58eb50499ffd38ca80f17bf3a315b77674f9136af7c73a43262ba40d85afe7724ddf5c2e31fa1aea092a331c0fa4784d3566ed7574bac4609bf966e338d5f4a21cf65c412a73fc9fe119a0680516931b030e6e4d5012db339193d385ea3dcc0a48049cd4832c897b58283c2e0cd238e09ec0e70b8f87a709ef3fefc9be04d411ca228e0e2e4817f69ec7eb4d77477455d24ca0ed2c3368f786a14ce4b2da69aeab81456951e73164e9f6c9f06d985548b6a5ee1379b4d7e80d043219ed0af6705e7f5cef18f01d7f48f916f8708a11e6803543a9488882d83319855abc41e17611d72c6978f8645eaa0706052789a13a966d6f1e12bbb2b66e9e3903b8a35c5ce4bd97d8e114993be2664cc0460ed4d98854d9cce1bda25f878bebc7b3678ee28794563f27e1ab0136dc42132b3154c41d682b0455af61f3b010e4e144d168ab7e9680c852bdfb0f530e7bad3e79b146dcfc64f39855a55143e49cafbbf91aafb1d7814e5ffc391ec49149329657b34017f859b19cb48f1e196dd8b12bb93d888e61980204b43251dd671e67518043c0c7583d26202b449fe922443b0424087c6f4d0ee64cb6d99e282a4d93993b29fef4de798a8b4802315f464fa09f81cfd755e2f5eb603de1c06a722832b5c45514d0f2b7a01c9c19daac99d3a9105910068545581f28f416cb1095f564b640287bc6566f4c7bf50606ebed787b05d739933519f6e2f79ab9bf5a0e951e3585ca06f8f47ba401a5f0face1f589f76468daa63e0ff02f143a14974f594cabd3a6b0f01c6fcc38fa0efb95038d7a20f287e70563d6e3db82f64dbc64873cf5ab980379a88c701a477a044621cae8e0aac578e4bc56a8d6787e55c908a33c5f7f91678c02eebc412c7932b197225b8348c7e658a9f808509c4959f4295ca52769ba7c7e500d3cb3a50fd9c640cf3d459b9548800a704f5b670a5045a919428c4eecf005900c9aeb37811b76a95de6f0697063267b4d4befb7d3aa1405036756de41fc25e47ef97d5e52e9bca3d3b3d9832d01d0f36d0bdb5934206e5b6bd55d9c1159a2349ce0e676949f298493297c0f6f352f8a8dc917931294639e0e796f57ed399d719e327482cf9760e5ec8dccf7c5e05d5d52d0d0ceb8b5ebd93182ddc3a43d7d68bc7e76dd34a93f283032de65cee7bf49f491a7debe6f5004056b00778a1047c92785736e95ec1bf1d4507f5058b6915707a78cc38734c53c5584248224ed1fae2ef215bcd292abaf3874301ed93407e672c5c0e19e3321c5850912207610e8983bc14cb525e28342b575030b542cced396480234e1916d8500cde06f4ba3826d689698690b9939b2305ad9ab839101ba540aaad3272fc779cc118bd7ef83fb0e9fc9641089e47e39b4722ba7e4074e90ac70017f8dff3868097f811dbc51404d704566a8130d38a1716485d031e33a9e379fba4f5896641bc7874ed978b7f7b69b064f0f54bbdff960ba404d77a04b85bcf4783476a280e0dfbdc4cd441cacf841b3906108b9bf25b600faf3dc32886502676755e5362fe57b8f067f86677bd827459212dabd962b18084360d444c85669a198e8f9a66af73a3071a21c060d3f5f92f158c7f59b9b923e8dac59020e8140badf6df3c4b5924f224bdce719c78a0791b12b98ebfdb4a41644d60269ede0e03aca8fc8ca5621ca22892148f20d3475f960ee968112f36eb53aaf2a76a8509d41b13e88cefc4ecf41373071f09ebf41b48541629525afb74d568163c3cc0eba7398007c02195f1ad2333fa546dc5bc79f09c9cf9175241f8dab12868c32636d2f47b3f059ac344e803fded527339aaa851949039e20c9d95788db9eb358254465de4339823d67492a27a07c7ad936423e7ac82d9a6cf67afea1d1c96a2376a45c8e3b5424e1d5cc091e7a20747abc23dd969456f848ba095687de03a099eb25d54eea1964b2cf529074c7c36d81a7339bf6d941cf2a69bc5d3f674c0aecae5db031e4658f018f654f4ffab87006699fec9102ff47157c43bc0e0cacfad541df1a981ad42fa12db72a7a2e573f1c4f374ee0f96f086d263f8b4aa5ddefece8bb5df02aa8c20e23a89e73e4e686d728f99865407634dd88de08d77a37a33180af6c56a932ee28e4666663fa314b7522ed94125e1c78ee3ea2be3145768248773b45ff61f803c4ead90c31e83ea1994167a1d2ee3637720012ff26e4beebf0a7aff5e01022085d2057c85f6bc586ff52bc8c8dc799b1ec4502329236870648700f1fc8ba765e5adda77b4512f5d4fb8e0dfea6130e62aaba964b334ac61a0563410d5b70dc51bed53d4a05c56e3800b516170742f547f7bd0cc763da36a1ef60003ae49af014fab3a335891bbfad525d6cd6836f69446e36b77592c1ece33d82cab16107c52dd850d186e98fa8d1b466b182ad9bb6515b7da08d11eebae6441dc009dc9e42a0c7511999819cfe404297a09571d9824dff381095c678a5d110c99d51cdb24cf9c81a51496cf833af6b03a456879052b9bcaa86095e02b034336f78dd40d86b3ad31ab04a6abc361ba2db49145c369f9ee6be987cb592acf994721518698a0df3aaa20a65709d85bc4501fcad0e212343123c83b8ac1121236aaf75b15a88ec1922a17436a8b164893aa23d45ddef6f145d6138a1d5f35c827fd935e8d22a4e7aeae3d2151b78c14ac4828d741353ed7adec3b4dbb023c937d12960ce40e6d1f3031fdb459680f12580a8dde2ca7e7d3890454de6b176efda6012c04e61441e357e09452c6b7b2b7c689b7ce1fbd685c7db47a2ee3e1949ecdb6052ade64081a39b49166fd1703dcd0138825c545a26ac6de23d6c03c5e61ee9eb1e4968a493d86a08cf1f130c9f4ea605b559c38232c63a04cc47a1efced834bb595d203d8ec2d21a390d25588ce682823e752c380f9563708e334bb12a231e7aba465f790a9879d435d2bd2c8319c314d812a18f10497bee7a46c7eacfe2f9ed44992e71a8793471ca802960186d967a2cfde2a85adb3afa8328308b067fa63e782a98d578540ea7dcb1938a20c4732f15ebc342eb086be23d62a3a692dc5771aa69e8d1a00b0788614528f8d15127d1924f82156de7935bee5bdc031483fa968b28abd131a9c66200898bcb3bb35526fd24c857a1738ccadbda9604a598ddc234e99c0cbd51baf7490ab3a25bf025e1dc07e643913ff9e7ff7e34bd1e1bec6191fb8955967f37494f05d31228c1916e87797ef56e254faf0bb624158368ac9682fdab2b2c46be30c89fde966a50246c81643dbdaff42b1c02a6d15ff9b1e56c1ac1098644e11d064e86d6a3ad354bfbd0820e418d0b850a20d82e5ee7d56dbf6c3585a0a620a116c23b1aea6ec4c3733d77513204bca244d5ed8f4245cfa7d5f065441fbcb6d4979a2b3439777b6bcd7a03379367ac88ef4fe1aabdb2b6bf406c6af5461a25e15b2767d381ce8f21070454909d6a2e1f20d2d84924e5d9931aaab5f849257bee49c6157c56a5071089b23ba28152b4be4854d377a4256303a48d61b5c1d175e695a88800a1b0cdf4c7cf86eef5cd9022d6f83f9c3e318c78708da80d72a3e8012861afb22e09caa8c1428948965ac6b629a9a807ae4d9ccb0e19a5792dc6e19ecf0045489b250d65951c4dbaf64d0c813dc1c39820e69fe6867b0a64cad1359102925d0cf6720343551ab98d23546c63c8f63e7974e8cd7f63802d05d054006f78031e8134efb1f629b1330c0bdbba2ca9f2207a6d4cf27c04aca9722316f7676656561fd12be26fa3987624a3bba1c43ad6eae4621725f040c60f231d0e9ab1f023701c600f41e2c91440d54ce30a6409a85d9d7e400d6bfe7361091470f96e135bf92e4b3034d31dd9a1a3345e9deec2bdef99af6643dbb7a3a4293a51a9b443953243a06a1168ab3c907bcc1a1f7d07f3882d0e48196cf0eda75abe37601f7fa8e867e6552c947883c36140f10cb42130811a5d74fcd9b0f6ee236104e4680a641624532ed706020a2bd41004c34d7a83970b6e209978278b19927a429f127fffffdba243763a43b9cb8db59baa4f19f1eb19d580a8ecb8e87d70635002567864b4260a98865c2c40c8cc100713c50d2359d38257462ad3aaec9f4e19d462147a5f0732aea711b7c7c03f888bc70df0767864b1fb79d6819c342a1e39f9a9271980e0d57fb6d7d6947336c61f011efcc110a7f4428e4499da71b544fa220ba9d8bee14d15f55a4cf67c27a9222a17a079cb1c21122234de87f7c15b7ed27703e7ccc3f1c6fe13e661484deda398b3477de532071f2c8d3b1308b27a7deeb829ddb652d246f7535a5f4ecb50349b812e61b96daeab1d224e311b848c52a4e39f9fc5958b386b6d98a2983097167130d3b9b62037b9f275f10c8b07564f841fe3b2f272c520b38c99ab3be5ada72ebb2379fe58924a9858503977b360b873f0b966654c36970f9c5149b7f16639cf9222814157efab198a137eeaecfb5ec5a2733e1298e803e99ad97170a9b17ff320203025fdd8dbb242556201764836de8632e176f60f9720f0dafde309f9f42a78e9a378f756ae4c1c055b184afc1e76128f0b26ed2e731380e8e97f6cedd3fe1601edf8ae2cabf4da00294b3a035120b0dc36077b433b3910004e8ae2ff5d03bf6fa445cf9f432e5efb5995dc2f06523933da1ce4a8b18423c0b3db421dba1d7b1fd8e7f69df26f762fc2b6c47dc34d643716dfa6cea734b86a7a11f2ea0aa57242c861b9f04b3cb6100ce80c97e100cdf926547947b183450642794e0333176b7997c455ce0d835a1cd2efc0340e868d88cfe4ac4b85324baf9f3b984c7e70a71bf545a80c470a0d08eb58224ae26b2cc2bd192c7dcb244c08b4491b6826d8bc79903f85ef3b203d74f21e8c95a09d7102c78e9bd691e8c4db00d0385d2c3f23b22d800b0b688997a190199738b27e9c146531fad88e619bb524e9e6403a3b11b76a87631b76bbb312b0f00a4d12d582f40660ed75a062b7dc584c0210696e5ace97eceb8558ffe5938e183ada62b384eaef1dbfb74aa55e66d574a484103dc4101da001786b93de5eb53c9cc19705bc36591c76ef0a3f5f33e789c72d49657edf56d6921998a0b1d3b74b410c41d203825c1d4c0bf86021f05e89d752459058cbc6a441f32a0ebaf9c71e1ae8b79c15b7427de3811f9b7865837453877c4870cca40774a539e39101a12ff686cac4a3599fe942e3fa169b7c9cb45d735fb958f81c2aac1cebe40dc6d5fdac9ded4b6e0643e44cc0be78f9e3bf07001f3dc70f96a9ce4b1d5e87e9ee31a4b0bf8031d10cc1545739e50809667960c9aed7d3b05e81c113b64ca8f1c38950d1c143f984ae039db00c83a0f1aef3ee1e2a8b1149de70e9c1620f7d4c61b4bd4342a05b3171d8d0e28b4f6a034328482a7b861eb471f23458e091af3adfa7a4757dd2367b63eec7b21009838657c235d5c9abeaf627081184708665780d7dc5ffc02da4d9a8add4659a309ccb52788b7234f28c040cb3f98d8cda6f2f0cc87f6eeec978c208d4a2c9a0c064b566a7085e9255b60a04d19a4238cc0b340194b06e35936f7a35887fa119ae10ce5102c4c10de907f9930dc29ca22dc9dfd28faf8521e58b9536ef633da0ba03efbcdee0550988ad42058607dcd7e2cdaa99077e157c3618100e371f3f4d186fb8f4678340ed40f8bfb32f7ddef9786d5f71abd1f51dc65982c64bb18c9bb066ca67f864f11cdd85017f4118237b739ff5200a781e8e13902566f95e22424606eecaeca08de1c82f2a7e80ee05dfc6dbadd94f08bb5eb237f6eccc2c47d2a2546dfb4f78223e1836e3a24333b37dbdba7d323b233a50f4b1c570d0eae553c0aef8ff05bc5379c76631f0f24d7378752706f81c9cd79e6a984d650f43e4b59f44d43427378a726a360835c03122bc35bbcf7ae47cdc32da9c4082ff00e7101fc1d4fee33375ee7239e0f7ed561af1694ee8ceae30e9bff356bbf3013e8815a8666c8dba44215e7b7a0e86f69fce3a581c24e9842d1bfc2cefef615346db0739a2e67391e8c23142386ce675276777257dc6dfa050e216aa17a6c09d921027987f6dca1cf11c0ae7abe7429461f209839cc13ae9d3dc2f0766482f8f8af3024a1c9286affd481d27eaea7d00e3fb323b9d8aa930b3c980e1fe466d2f680f8e0534080d519f1c18b5afc63bc086e2186355eda77a15ee7d43864ba49c5815f7fc634666e2b31beb443c15e40b1bb4b0dbc5c10ea1f24d5f514f7f354122726b6621cc19aa07e3e2cedbfe9620e5762aa88c0f284d43aeaf283ce779ad0a06979be8a8b8f41970fb278b68dc0fd9c2d14e6a9a1489b83ec4bebcdd7f8a849e49b7701bbf6350ca7a1bd0c5cce7d34a5c23525fe4cc32dabd83705d8492ace08292e9d8626cbf87c11375ec5b158c20804cb621c292bf2b110665063a20309752515056c2f48033361db68d97fd5504f84836f0a56abf0bb920f12aba6abe2226cf7fc8a8fbbac09c8b31c6ccad2dc6fcd5849d870d924abb0c0d89f3de475b4c1fd7b113f913cfb2d4901bad24b3518970a049ed058979086deae7cd9551ead4adc6e31e0547237d84c20bfcfad412d51382ea60bd9cfeed343f1a38a38341965b944b649f1cfdba2a9cff2ee6baf0ae836ecd48024d9919f329920c4ac65b3a0fcc85a6df02826ed8ad02a9c00f7093a504ee3b1f2ba92923c9651b229e0d452ac98f7f4e1465004ba7c58f4318b3afb46b786dac61ee5f9de665b2224a953a01bf3e7bccb5945c14521f03a7b7e6c027b2b5a6055bc7c35bb4f8dff0347781eef7c48ff37260873047eb353a501f601182646c0b98f3263f92ec2f0eca189bfae6d08c6ab972448728431a1475bab095b0f0331abcc83831bf8ecac52889cc1fa8017d458326c2f4df7057c649776a6959a723dc2e04f72e8fe9e9b040440fee53b4cd972d1df96fde30eaa187ea267825fea8b61ec67d541c01037db7e8529c497fe9a14dd3669a312f89844e998ee4af5d25d5fe396ee0eb432beab53afa9fd384c412b53ac200bc4f1973a8d3006e62ff07c821c2845c8b04234f63483224ede35e2d533935ebda751da22ac6343e3e25568289769a84eae252c401705aebd31234781223a2555f8f9a8246712b17637f6d193172c345f6f520873952b9e098a5631855f0223a6d19db22281ef4ef6bc3d37c169da9f8892fe9b525e756637ed605e902c90f7f3b29e6d4913e8ca1d929e36edae28758d1dd73214f356764cf31fef48ea9dd1748d1c1162a5a42a2745b77f542f238f047d2b1b9eb885d7dc4bd402222a62ee6c03c05305d3e6184085b6a338e35a3d5108cf95b2f184fda3debc4c153200a9cde374ef10a1b2aa0ff5f0a792c8d42486b433ccb62f003f5272f00b4fbf6340c6cbba7c5c50c75d03046426d47fe29f4f7f06aa64d2ac540ff9a150ef01c487f857990dff510f7bd54a13e35ea16f7ccacd3861c22f3371d39668e5f00d6c7a82e4eb743380143631a10e48705d2e702d66c48b4108ac5fb9b2e5cfd5a01d707158ae416f5cb5eeea81451dc8b641b6604515b88f6b940ae254bf4587501d847bee9eca54f151400d039bdc9d375b6c7ef8174dd4f793300a3860a787540f82c09f014906c714d8852f393759c3ab55458b8293650cb8886a60301df4cb7c1076f71713c53e4db0d7fe6433b15f40cc269dfbc40186f0e364430e8b7d19fe86ec02b1983dbca702ebc2563c4756921d03ba913e897164e7216cbf90147832134387ffa104519ca76aaaf873630f1a4e39740decd24f85514228708ecd597413a096fa073a2dbdadc9ee0f078667154d10cb172df9158d6e32770896be2b783b289aa40f72f4d24e7b4be53dcfd21625bd15c0a74dc4370cf8683ab3218d8dadaee3d8d59908560ca68f50e860b6acef0d453f8e20de210a89856079b88315788425e1e52fb9bf072e684f6102081e06a02c80eb2df8e37c25502817f104acf2336bb4b64fe51c12e73a22469ebb157006597f90bb6584889a975cc65f03b86be0b80471dff850661f243b126c83db741ff70dddcb197be9717a59d51b9701c136f590973318fd2c8367639cca5342c3d3fc5d68feac316f9e777ecb25e14e4fec34d69c2fd95ed0e1a65ca9ba871418c0a90040f6d087bc430ab034886bc4b7a2355432b93baec160e89a763a7650e48bf4d5e8a11b4184c2bbccf584c809b319b194438baf37f49fcf3d26ce5aea22af60f963a93df3572c28d789c54da3144882c9fe63a8d8e5f06291492ee1f73f7c4f8e33117ace2be40d63e74366194702dd3d96f7650df65e9d2a9ce9ba2a00887cd11e5ca537fee370e2d7481a17ca3a84604fa1dd1a1cb0046a77a579e8d51d261d8f5ab70a6fb93b2c0c25ff295f99e9eb63e2060f1a6665eab0f0fe76742a535cc895046611d5b779887e322d24bd3b076f44cc90dc11602517fd042433100f00f4d64d45040a1d8779523fa7eac6e1e90eac72bcc8d257d05ba2f3f5cfe3ed65256bfaab55caba1547526ad1be6c1b99eaa878d0f374ad5cfcc060f00970d4b2436fd82cc46183c7d830a2dff8c8499393c957b19b7b0f64e4555a39a3526e9811e4c28c8757e1a1dd9187247541a3b63d5b4ed338bd9b0af9952dc2f8f614224f5311a2fa4ee7a10e73451773d2488f80f7a17562968b2208e813e07579ff1c023f317be4d1941b97504e4140d901e55e020f13e3749559b1769af89809f3e972ab74478b0ccebb23c584c8f2a016c2b41861e178025d52cc5eecb111ce0544af86617ba5649f79b575c3d19f42311cb0d14457561ca28a1de43c2ac110c2a7602dc4ff1b679dd641f567ed3b9918ee3a1eb906d23e1915e900b11b23d08b31547ce0ff23ebcb05a59a1bed9ee1c1f797210322b4e16323a0f595ed50ba4582d7475a0fdabe5dc81649835db099ab203f54475ea5b3341ac0d11d0fb513dfb3301eaadd16a1e68ac7db1b67af6c8e5dbed1ff18be9e653cf179fc53183654da6fabe627c41633fb82569db301ec3f6a0871e470659ac2d9127889734086ba6266a638ade10a47ac8edd791e55077e11a10f9820b7802c877d15b2b3131d64da76ffb9dc431988e0444bc5bce97be2e65dc560b40795768b3865da5ff9fe5b768c7d5970a13d1a9c5777686b2f56518279118102abfc39a41320c3e8acc1df3a574fb5aae71d28a2572542ce082981da933c9a975a8573307a41f2c76a0d225f71a84c17e1e228ac3f6a1f93d250fced7132b0c2d379d48574ead99b89d2d00592c456d59462f3391fca88d4395b9c55e76fa8f62050298995fe212dab437fea7751c7d925b6617484cd5eb43bda330c210d2babc9d4032992450daefeadb61ea031537f015f5de08b5ca7e00abddc538789ef837a674826e7a094c373ec8e893143ff46db0a6dc9bb08f59adf1da748562da0d0d230af6977e4196ad2670c1afff201e0e6f43f7788f0ad82621a3c00cf02879f98b4117ea1584ca9db0654caf9354827afab5b24f07b09bdfcc82ba121067139795d2f7cb25d0afcbb93c290f52624450643e6d537c08076c740f8dec75785ef797fe13bb0c3f03d6eb2d85c5794bb2ecb145c29fc67b62d7a3625beeed45d687fba608fb20b51617243d540c1070af775e71459f6f0f96695a9ccc9c8661696a4c6e23d1ac056e2fb439af2144ec828d0a12231821663de6c2d58b4f422b465c0054ad55208087f42d4ee18868a5500a20e025886b2fb921779d3d785ce3d0184a0221e2fbbe50f8779afe6dfc62306709ba4fe165b389c91822a51eb30dfd051d14ee694339bec0d30879d0bde74c3c3aed2e78bb6ef19e0fbe23b310d2f6e28dc1c92f26261c22b9fc61c69252201fc38aa2437e61670317d060d667e07f27916b488621b9c94c666085b4be68998115c248c01521000ed30e03be3bec336763f0c0d4d552a658eab3d470415f4f0c77bb29df80b5c3e99168319b6630db0d01979ac130becc781f3bf4c395b8bea74e2373c89b19b234f55ebe1ad8c5a0ef7f4ebc5c17cd0388ecb3374a0cdb0829c96bc8972d695014fdc1ddef1cf435975c1ef3ac7e93af8ad832fbc7f1dea5006c7bca66a0c9e78e59c17ea3c50587862132cbbaed01d3e86c73aac661e003d2674a8e41c8e7e39eb0c3dcb8899ebd166f74191926e550eec404da0bf5f019f158206b8f79efa08024044d9cc6c697c9c6d4a14287e6352ba93f9d5b991ee8f44fcdbf4a454e76237095c6e01e6a43c7e575c95e13a4b35fe377f79cdd614923c1ebcaa27b5684a236142e0dc4f1de146ebd96406a42003b2239c80fc48271d43b961e885d3d7595e149dc7387bdc758ebdaccdb743022df3e5454595e8eca04c2b6711f20743077c48733380e2e557ddabf21464673551b97e6882258ad4a5d86de9cdce94c5eba1063593d9ce01a379f7803978a16377d4fb40bbf4c084b572526327ced816ed5ca5931132839283cae0665e8cb85cf70bcd8d70784b3f6be4e012ebaf8ed44c7c89ed29828bcba0fd64bd213998c122b77f005265536b6db525c005e94b6b2de038d8aa66c3d299bc3e66295768984fda24aed3096c4a5896e2edc5bb1891ade3705e4f11412e4543c5f4b845805cffdfc980aa2acb799a7f4b1ae23480cd9ad70979cdcc0857ab218aa424d67256a7f5c5c2fee00e54cd85270332b3780d09c97b81db032d9fb418960fbcd7d5d63572c1e8500fd8bf2bd9f1d8b999a0a16b73ca0ae8b461e6c4dbd38d3c7a0279c7665fd7ba17d88ac113f3b79a4dfe73f994b4779235db08ddc59734c8242bce09e59207aaeb40ef9d6f66dc2df505012216b024d39a752e437776069004e0418d9a598a7c703c11b7fa964ad2110f615058a55b1a482b145293a2878d92f82682b09345a8a94d8d657df1915c6a778d46e2320e78beed80b7b478a0bd436822f5f987d2f8600c2494865ca84de67af03c319a19c06a706129137f95c49a5d191a46e507b8b44a5c9f8efb833fa207b0dee8d0be5d11ed1dbbb083450c7f6bd517b34566ffa4793beb0a8cc9d87c8160c4554295719e92c47e06d3c338911f33294aa147621e19a715cd86d4e279bd0f75be5dea179147b414d44a3ddb264ed559f85e73d006419b19a5f32afb8158d13ecc05e605012c7bbd26a9edce02a7b8adf15a5a775d3173caf7596338ad3072ebaa586f93a4a3c68c602d4fee6a770b9733ae4cca5d45ad7d94f331d3e7352049081bcb2e0f5569e7b97efe33ed73503c38595659afb2eea465d74145aa09baacd56b42a9472011761ba669aab829aaf7cd1590813ecbe44008d255c3aa0132cc79989e1ed592010d335ecc5e59bcebcb584a1ba5864e79fd929e09f00d63b11b72b92b80b77823b26b117e250fa6cd1bfc328905d67419ab31e9bc7cc57ea7fb276cacef0f5d03b1a557e68ecd270d63a5cdfe3ef0928f307b8242808207ba6691a9f8b04d8d682d379875f3b827c8954d123392badecccddc5b3b23d647cf431ba7cd4894ac33c12b5356dbd543f53ee5c4fe9512bd018604eec88524519d4a8ee47ad9489a143cf209e988641fad0a9b38c1335aabf4b739b5017fa20285d5ac50bc17bf87382d5e8de61f046672b9b12ba7147e9a9d337ef381ab3079276bdc8c0946c955f5d8ac36cc71327660779258da3eed2abe521fca31bbaeffc7809c3991612dd6cd630e72a330185812453b703145265210a9256b1b711e21381d11b41692319c31a4872f19c4f88f5e6d6e5e7e01c5bbb767ca3f076b737bb894962eb6b923b82aac900548147fcc0c6d7b1e65b1b6ba483845197d875d90e9d66041c3b3cd7de2d28d8a954fc0818c4b20630f6c73b9f9ed7374457609ae6d6e16dc875ab42afabb026c2d79c6657ddec293532da9e815a86051e7fa8b6d0cf954ec963cceb9e03fa39d2e372c3357e02c5dd1b91cae10d2addd609cced16671fa20495b29a77835bd380aa0cee5a85bc2408b4a3a01dd1e48c249405d700bbe1f365f087eef40d3a4f7d5b9bdf5a386f704663ebed4de70c245ea71f34443340d3b8cf8a1726017ab4085a6d307e843d41d5f2e49906d04a8ce7df613258bc0f71c8d0ab5752ebc691a7bca7718e83ffb7bbb5f57ccea0e4d4d4da5e740ad0c1ab06a54a5c0f5dd769a6d8f3a900d3ca83ca4804aa966b44e7eed5a55450fb288067efbb94dbb4788cf2826328bae0b1b25b38d51987281407c08214a21583cfa199cc54223c6ffc5187af70a90451048e756cf96521f6bd45b5e2c98f812d77a40a8aef89d0fa87b97293b8a6407f06d87c5656592bd623293c34f99d8a5b744a36679d112c92eddc4bc0994f7fac718fe2af55b388d711f03f3b06831f3e66922e3f862b733591d7951be19e043a77651049e44bd2b032cb8a3c86a45f2c50a27d8a3fe8bfb60c321d4bf1e143f05190ca1060898701d769e35c1fc889fec425e548a619b095438ebf1915d4529ea8b88ad8b75386e47099448671c92c6f06a102c4023f230e6d095038659df9ec3a8883ee57e6fa68b40dac98a120d3a00e4bd6d3369ed7eda7761f9101da04eff433ff9af4ffbf52fd80dd6f05f220d105eccbd70a107db3fef19ac56400ab333b448ce27bbd77f4b5500bbbf466c0b76993252c373244d016e16b13c8609e720304f9537894a0aa99e0abaf59463912c4047e2176c6d695ec4fa1c93d21c27dd527645d6d2a846f5ddb810358efb72539108c8894843bfef3066da6ab170535745c0b1041162e04ae81af330be21aa0ddfed7d59cffed2b8a1673af89eebaf3b307e9a429ea76bd5d51c59c711443a21377a518c3b304652805a17a407d7f49592ebb63b945b536099aeeb5f21f117a4a7e342aeeeb833ab239fa35f12c00c59e6440c93554e3515ea77d0dff69cd6b48a55acc60cee599c18caa2a73fab6ea405efad31919bd401f6e902836210192fdf4b2ac4a1f4e66e3c1ca17ecc8ab52c4c25ea7f2aaba9a8e3c9d3221b2d0ac68d9fb289f43a6c96fe1f711fb32ceb0305f7ff62025f1549b779f4862e07c12e1557f9d40f56227f7dc1cf3a08eea6537068e4f3458b61ac8bf47db94d996c092415367b4a6b7af06b598e693dd4580225fa83c7e5e9830eeae9f566e12e2dd281081db3f02ae0f5622fbb28e167aefd3bc52630a0102455e603c7113f37d051357a33254bad34856a0c6cd44cad8e5a7569c46a5d59c8587d51c7bda30a7cd9daaf49e1a36bfd675264c883a23306a070cc690db61a5506d2bf742008634a02dc940a4bf931609cb644e3cc59d969643cfa46111a352e4d12fe435df2e8499206645cd9054ead001dd707c0f51a3e52d1bfa38d93000b2f03b2e73435229ae2a87b5403fcc4c256285796763fc9196caa63886bc30638c0127eaa14ea2a5d60352a2e2c7ce5f1e34efd1c3617fe0ef24269f62b8bce8aabb8ba6a7c8cc2079d14500395794b7d9e46973d562a5c1f71859b71aa095dc3a6f80178c8c59b5ed78adaebd7968643707088b968b33b1821327eeefd38ba08a79f373ae93707f3c6226a23e9a9bf9556cc9354a2b0a84b084eb82bceee23057fc159d128759fab3fda75519dc049cebe0b871a21a5c77c22f0974654613ff7a0559a4c2c6732313b253b7223b345a0970979a9e236da1d410efc816c02bb6909c8f893a44afda88e4cab5151926a2408b754f8c1dd340f6ee739694bc70891d5ad47e547aface76a6b29cf1844855dbd254f7c7d0b10ce7feac0d9b6a6b04500dff1ccdca496e998ab9e8497b2b94dcd9a58b8eaa903a52da46760dd46730459d4ab89abb30fbf0e65bb4abbb6f84e9e918cc2e15810825f2e2876520fae1456516c98abc00d2e0f40638dbfa81b3f166648c38b91692b1b4d547190a0b981a4d7577dd94e69d3bf6e3fc79f23fd6a58a1d8a5c8674c383692d17ddf8ddf5b7eba1c8fd5d159032c3025c4d82a3469fdda9ab52464f9bdadc0a2ba8e6f4a0ec372b1c889b35e7ab099593b35436c6b65be13319357e1a2541bbc27d27853689171cb0ee89b786b4ca371059c52fc51de09ec0a9677d0a4e52ca4f1688827397d9ab359c7bc41f05fdd530a185682496b1080caa316143a96832180a0d1cee822c0268374b9ce14fc2a7b697edc8354dedf51fb8f6fa24ff31ac76b94bf71fdb763b05468ceab1ed7a73a95cf7400fd2d96e82c2787f0e25d70e02fc2c4924c212995aaf060f0cf2bfae0b3e0e4b31d8b2180ddbe9305d4c0c4847596f08a753fdd5e30398d5a9c1d4d84dbecb732220553caee4f950745dd5be3d032cc871b834ab7bf9ae194ae394fa99140a5a754a2d20c0d7b6a36ed7baf1f0a77c4ed4470bfc588c9e7bd9b6969dc8d36ec1f7e763f79057077dc995240d88ed8c45f91b129a8f764eaac4ae05205e296377832f1ca750c6712036cad6a8263157f53d801956aec48c2460277fa65f054052b14a05ddbbc690fddf3a489b5a3445adcfad14a91d8724f26a594c5ed84f38ec3be7740c1fa7a884f9b4f62505b4715bac7538197b5c02c3307c1b8c9fac9c0476d85decb2e605b15782e6cf6f0f08aa7f5291e3942a2634106575a9be2619055a95c8e84a7ff2ece17e863f5ab3fc5dd6cf5bc2e29e713fe6b18bda72ee02fbea902511dfbb8896198c8f83a04f51e5d3247cd227ee8f34e3a15cf0126aa1ab677ccc0ce4252390f770649d765ec4ee3af9ea9243eeccfe5bc68b24a56e2fa337da06c2fd6fc8b050915eb2427bf2561d67c78ced91f331201c5e3d8fd3ec668cb596cb9c3415a0224edf24a554044f2a4b09b6192f9efd2134104228a0e5276164e91e2ba281452445e542d6a42bb141b32013f58715c87866ba4dce603e416cf04dc7f0921127d66cdc4762a6bc1b89ab9a339f78da246b21f0197a0677e110c8bf8cfae19034fed838ef46e769b08a9cbc3f257064f1382d81e94843fb426bd79d84126f62bf44f0514dc232a8991d6a0b310a965d85bb4e61c93aa7ecf49cf695a7a9f0f4bbb637ff87a318594c76af4b4a76f3839bb3fab481a3071d5701f4f1a711937684034dad3312993233dcd01610e42bfbcbd763002a2aa3bed1fa33cb8d5376ce3f982d5692d8df4a9e271f7cfbec2e29314856c38cc1548897b33e23b51880b43627fae33727172fe103ae307666e986391aa82c22e5ce297a4a828744c222f5ab513b6488cc1e698b3ef969cb416543c25e91ea728e991b196ee675e7328e58d7ad7986cc62fd6101ce64e2f2cc5968997f0e7a11b8fd08376a3add3d9694b3df95f5247ee692a8cefa5ed02919a7efc8cd2e11843b179c483605f97047f9233f272b52f7774141df8642c9b58f9ce9862b9df609208065ef4cd8ba296a229ea587ad829d0e9548e467223f5afc094c3ac9ac527146d511fd4626a3e8cc153c0b65c61c83234fa2143ca9eaeccb2af601c0ea06f5aaa5110dd3200f154f792a70a97118b1a3f289cbe05084af962b325b1280bcfdf08a837d7044ba544df7a1a482710e019bba7541a15de378b5524a5e52c4b117a4b11e77213eeada3d4432ced2af16402f4abef62ab1cdbf647cc24cb1a909ea4a060b9a75c44181609472fe721e6352d8f08dc39c9ec56d2b7400143fb99f97932ad4b345c7a1283b14e2a34eb8f874d17b9f45024c8dc3537c97af4b107c624039d87aa3590ad9d0a6a7257063e692f8d2b723ed6c8cdd4e2594806d95fb83e7fbd2bf705954d5b2c959ff9e2b048a6b2be687dfe7a43ee052e4b9b58953f53c567914c65df0b8795bfcb636c76d6bed2e6ff165fd0c98bb4ffff7e9b0c052c63db59288359c5bb7059a470497dfeffae0c0a28d3b6b34c0ed38b7361594873f1fafefb4dd914d4a76d456fc47470e5bd40f6a25cab701002c82ac54bfae79f776558d09f6c14bd47ee852e4b1b589537b3c5b1980cb27d69fdfc799b9c5b88aff27f7d84de161e4a8503f4489865faf7bf373d70e01c17c9543797fefae75d7a28ecc63658a20753e75d200bdd5cbcbfffbca93705b5655bacea81c9b961a0322e34761bb2223b93e15d5016695f9affbfef92bdc098dbca52f94c0d7751594a4d17bdf5ffe71dc3a2a00f1e3fb2589e987a4c217f1769bd8ce7a1e0e683401e6e312f6369eee59e8a8ce7f1c759146bb65761d8ce74bc2306ad0e81ed430233bdfe36c126f092174963e8c91a03a141c42b472f03fd0a33db87a856b81fe2703a2da67253e150c6058d646a7fbff916c332be662d5e1c33f14eb811e72a72929009b7bdb8539422ae0c31b01969818628efccd5c2ec7d173c2853561a2b8a2ffdaad882fd0e577de86e6e869e803c26cc42dc9bd1a11a2dad4edafcb440d6db4163b4b09d61181d47c1bf9c8540cad30300b3d829a5dba43c1d553230c5cf4c44b8207107431b8b1df8baa871b358d3e13c4d61dfe372b29f325b194860e8e2592626abaf450990833ed60a627603bbafdbe9484216a1fa40d8d2740a2a397f52e7dd2c6ff9c22c8b73bfacf52b337ab9dca8074ebdf3c48cc3ba1105b9c42503a40f66b6fe724217409b1dfee2430863c864d9e97ef10b8f4f030b82d4cadf23a4ffe3cd4602134c60e6a3f907a83d3f6aeda5ac6e5741f0289c319b01c6263050b277d0f600eddc36226e94aa2e6860cc650925150ec59b53294899ed64741422aafe5b0e47c8118f13e7b2a77e732809dc17aec952179c00e862f8c036f85190b81fc8dd39065cf98aa667102ec571d0c225c778d45c90c87b627c2dc735d0cc0e2dbc6d6e6ef43d13b7515c2844898113ec8a0743028a8c2b40e166e6e0f04f0804507c75a00426287226c768ccf27830e6096732d9972e832813e67f5dc0d3be02aff1a12f17c4c6acc10b3a02f76575acf458ec98f313228a61a6d813ea48d7e8c2b03b3853b14250d49a8fa1a260fcfa518bc30bce508b45d71b52492633318a3b01993289eb0f4397f7ce08bdab4b00d4b0a1d23b240495c1f6a107d265ef44e7b8aee67571485ea230fe5888c75fdd91c34164e7bd896f6c7fbe6479251341f844149172b5f20ca6af0e77660947335530d05aa80fd7baec12f8468603269488bd70c5962c0e031714d61a68801216a3021b2d317341c083596594e2d05de0b4a72f26a9f0b18d03fa3692c0c2e00b2580bc646136bedc6ba07f7178e5ea6cb8491d1df3ea4af20a3acfe8cdc0e002dc39f5d7cf7f3d1834bf192b8bf87eb64eea2ccd247e34e08f32acdb30c5f0c9c3e142c09d7b728afc31d2231b3ec1031a607ce7283be54aec768816df45341cade5c78a324e23afdca9c705e558995a505ebb00ada0374a0aa41c78cd58ab05037798125ddafd13d151914a159832ffd54c82a1f29137af38bbe892243604a72212a4df02d44200d96c1bda6d288d45023212107c38556b5a0fc34dd37f3e33877b900c2eff3debdc159e98b881e856c32a985a9289d82fcb40c90ca3214d1a44166f9d3a209676ca8f8ffc74d050b179b20c437d27b03ed804fc4bc74d800c99ee189d2fd614603b5d35e7ec3293c08a935faa96c70462904bb39d590a3f8e7a37a721904430fd621288782114c8ae30a824a379a735cbbcdc1c8a860a1593e6c384dac1a7c5abc5dc541273ebfb0649a34508af12e9ae30624416560a6631feb0bfb51809b7d31482e2c9d1a730173aef164852586eda4b528e3314476406725a248e6045015907c2d21135d8f0d6d7dd9998d6510adf4653d4165a7f02457f569f0623f7c171daa1a9c0856f1030bae69714a153e03a680221114d6ba50c9edf5bd57c7f62073ad2a508c35b51100d61eb23f44c53122d6cc64eb3ae0cdddc6a292aa6c280db4b688bd418a8c16daa6cd340fbe94483d4422c9368b54fb140779e374bd64a2f4c0c088074b3408da4e38a9e14c41cf7b56014f71e741f1aa610cc188202b03667f2d3ebfd61838fa78eb206e2ccf002a10d54a028d86e1a9ad86d18e160307fb903eb026560fa524b0a8a09f457e21790e9402405aed90c790e19ace49da0adf4df020de22e7afde87835c5a7b771ac1b7113aa7a6d6886a2a1d3c4715af90e16955aa3236f201526ce21230f3100d5e27483ce0ce0dc6b0a4d7e2488d0b000ba61b7c3839eb0bf83ea678a6928804e7da93059503ddd91f1e46026a385264cf717a7c0cd2e61b37ea6f374eb3fd189e3262e91ff02ac673adfb8e4957d32c47de740e075f4365c50545929d38f2f19c4cbb1c3d049aeda9e5b494f09bf5f9dbd5f22bce66276d9191265d2d00013eb435c92f35306c089875e61290d965538df08a43c32b1218e2e5a244f6431adc163b8a2b475a51382cb600bf78294d44fc655c62b8a8a977e5f191afa1257e471c4125c00de8e401cee7ba2170f7ad134908eb7fdfa7a92656a0d4493e43c35f0e6914d42d0e30951f8b5b6d073c64119ef553485188daf4227aca8739c4506e85f38978e32aff740247e72208ca3f4ed4de7334d5bb29634d03bea3ab9aac44676594c41aa0104e1bf3fc0761b61be6cf27deab505522ff8507e39324a0846e1f0c04143b8750ca520e95bd5329157211d3ed15199594dbc55758a9ca9a9e858273d6e13ff62a944e8173377a87f4c78796d61dc09abba47ae8d84323ecd94cff6650bd3e4a472be133067ab785d72262bf9aaca18eeaa82820372d5f8d3be0deba37d20109d4dfc3f69e28a45449c16d9a55ef371fb07227eac8051d22a83ac5cf347af19102b218fe1211f15088612db1d7ab93c27597adbc553119d8d20a5014122d109173b1995691a2398c905427229694edb16a5b495b7204cb8027ef34c2d51b39193eacb105bdcc28a6f108b71c5fbe04bfad02abe2700ade8bba4add370b239a05edfb4578f155589327d6d46b505c6d5205624877df1eb06bff0a57ba8226a95099000bcdb2162d179433a3018917f706b525a339fda60f54a32f5054e7db52ff1817dd7c92594fdd276177f91410b221e0395f2bc1f8629462c00c2095d14ab8242997c96d5249212171d98ebd2b3d044561288c7f54c9ad9e45907d4b59e8296df318792f727a71fa6282218adeac14ce2e6c6618a56abba30dbfee3a6c80d7a5ecd2e1346731513c3dbc3ca44a612538b38413f7168cfc192cc65680637f81d599e3a5fdf24688d29032f6c7fb4f7344ccd4035fc0535775a5d370b35b5949a1e22d0a9ec675e9015234201101aff08f45e62d7fbae24bd06eb642b14840417391f25a7aeae4490527b260f55b4b0fb8bd6288741ba1a5dfe0834fa10c0e734a8b4409929987745961d85706c0fcd540a212b7e136a0354ac4d30ba5d94d466559bfca90bd625b5e36daee76f60446e06fed0d0c2d449e04ff6bfa962ea6bf0030b3e94afe27d150a5c6a03d96ef3e188ac803465201a263658599c97e423caecbb980439f6359027292a64414571d8c18fef3e62fc2e9455c86631450fc8371e1ea300fb54ca8f82fb5b791ba425560875655fe26d1b46692caecb37993abc6d58801d30b0e0cc88427d82bbf327674db57cff4cfd5394223eb3c1a9d884b2f699a500003812f334f53bc893a69d59f46a283e5afb86d14413cc0e7e06e5377c47c8c881493255b3e0215a0afc1a10523911560834f43b298bded7550ada710fad3d553d0ec09e6cbbb38ea12620349a8babde71ead7bbb448098359c5a47272e5378a71a03e37c06df4a2761b4c9ab0e2d62a2bdb6d42e5238e829d1fb961991da9e87031b464010d20677f0ff194787031f4583119f3d931e4633ca01620ef49bbce6313799d28d020dfe853e459f6a3848fd59d22c3e2a37a809913a7380a774d47152e40171ee4c8695b98e210d15995824b012e67457c6f9e07529e34f5de554877d2f4dcd86ef14e2b67621cc5b610f01653a91ca736ded44a19f99b27403834de60be46be7318203078344ea032b48e227db8476fa2d5e795297985750c05381c28c112e7a9ad81c7b968c2e71280b9935aced3ff8f9b26cae62cd8663a09b601606a69f8dd58184e1938e80ac7330fd3e5d80834b2251350112728f69c137b61ede395a0c80ab408f664a0ab40af51183b6425c2a8fc834f987513817e089fed1bd2c7006ce1ccb11924c79660f73fb6c1fa4a1e5f094b0ee3b0c3aec4779d8cdb7267b3483e66bac980936d7f93e68cec3bd4d917f4ced9cf134b11e6740028214d0b3cafca96eb56a55c94d58222add6b4ab93923745dbcdaf9817da815b942469dfd167c26c56fa8a25dd2e41fbccd1473283bd5b65a296a7965238aa83ef3143f70f5da604b92c821ff70f6d4c4bf9fc518428ca3496f8986a22c25c65acb2e2f4d1e420a11d0ecec67e0f654f9b38a09915d006f0c2b8c4ed8cf009fdd8e82604ee8526030853ca3386ce3964c885bb7bdc8e94f7aa5e0a46bc7321d6f6c738162253c8fe649135efbf51b5f1738e8000f9d02f50b9e1c4feb6754368a9daa9870946c4e3cbd1c2389d84d19a15d469961017176b3bf9389ea18b141f67f2fa1ec8c63c8b7f5415cde30443e1eaee92f6473e8021948f5a6f2b861f15f2f46fe79a427fd3b71fd576f2f2dcca1367503e1b1a8588eaaf6785fc06c0f14351f6d67212159e6b8fa3696e0cc435c0f90b25f10b74b7087e8a1efa7f92250c688d1784a2103464096770931487be767b8b996b7cca4491da6339dc5ca3acdbbd8270942ad2185f78fae4cb6091411d0bd47f2c236ea970d3466a043de1c0caaa1b94752af6ffe59358f135467d0e15c83a4c0bd7e573839b03d5e99429279e8e8e95a153e2e02bbb95b5a2ab2e557b33447a2b1fc633d37d5a0108fa2007608a293ca04c9284414adc730a2b313741fe44095ad30c0c5d6265de0a81dd56126a62b3dd732fa13008bd71265810d6f147df230c6946b663e06ac2f77b9d7c99f0cba72084cb5716b510f205482d45c17d9938df1a100a55f96eca4f500af0683f9483790b331d98d3a296ac257020f6c805724d24ffaa268355129fc1a71168ea1458317cb3c494d503121d9166407f5d087820088c90a44622c8a0df429d15eab8376547d0a2f41653bf8090af7b2da5b70e7713fb16f4b48128a58ddb504fc3ef2fb1011f64347abe88cad0107c7c5cef4e3089e7ee544aab165e2bc611d3f359843476be5173be39288863eabac59efad0171b1f0dd283c2e65cb70ac27df3133d96c094a08b88c3a39932c00cdbb5a590ee8a411e35168645b0f9e7627f6fa23aed8bd5be3097e38c11e13280a80b7a7c18cf10ebf83e514cefd08ffaa2663f0b98f3a57a18f41c7ad4020dc6f5e69757063e1072e80f4a0cff9fdf284d1f3e44d1507c74d1531df0c594af5674e6081ef7414eea7f6741a343afe66b0b253d0ebdd176093d2a2410aef969949b7f7dd0af8643d9f8222b049bb3456ce36608f169e33be1beaae5312615c0e335f779d1bce7ffc2d6514d65f32c407fb0f38a6ece071d078293c35e17f819e5e718e1b0db33f3b3afa19f34ba1ae355b7456c584e04c0ff10873c6a3ac45e9f490706902302946f204f07014789c13f0973c986714bd113bc4a1741bfd5360e112652a820ce8cec8b5e0541ed005be3b52f510427f80ef383a80b6526a5c12358d869a2202313130650dcd317324615da6040d5c88f82637578a5a5b464ef1b042fcccafae4f2c870228ed6d2c9b7c5dc338d33de31078627c9a1234ecb0256e98d09fa4b7667098b5b1203f082d42f8a798fa115f65e0ef511dee73fbcccbf470d3aab50173389a2caf56e5487c00c6ec74600067200920792639389f2ffc544f1d7613626ad08e377b8826158ed155e45aaba2c3d473a2f6f1b8ded1ea59d26849311a0ccd65ac6e6e0c8923d3f99b8da19c6cece181b21e6b629994a6dd2f32b06898da4eb55ac546fc54dd4feaf62a3859293d6f4ff8c21b1782c4d2c6a74c50fdb8e4ba9fe5b4424996dec328c687cfd631b0ecba7c27ce7254e0413f940c484f4c7c401f349a618177230ba248bf4b3360c786052e224a20e02021f4678f30f1993f13346cb27573e5aa91be95083d0c5d3bd50bc5148772186a9750782f4d3cf0911e739baf5ee538083885c223f3454f05675737ebeb020df96f5133106f7540c37bc85409aea1e040561bc6a0861ac536ca7c0234f09793ce72d16b703544d941e4c3d03ea98be8b5510302c391df01b829d4d5d026102aaa24d3545b3ec80f49dd90592a5fb30565470797b78386599a193a87c0e74e8076de98f161ce0f73026af9cbdc0c8c95c0753c4c4646008be01ff7193ddbdc9967b4b296592019b086308a708e19cd37f4eaa69b55c901b2351187d8c2975204ec0392202cfee00b142ddbff45a6b1b4cebeac5df1f821a829944ab905a73abd607ed9056d35a472ee153f1045a86afca3e7b213b11f3922239215d6b0d5ddf0d2ac9911c082d824c15691ca9caee634c223dd14ee8aba4d9f565d2bd5e8f54732daf0ba9c2a893d80a399f084813e4ac507688d0845ae22322c8fb3e4b12be83b9db0ccf5a61f6d26775469fa0ac50db14fa44bbd031774a93955a0f1ca0bfffc630a66592eadf6a95e0e5bd38a2666e8ed7d17e5de7bbcf3ba256b4bfbfcffc3d8a871fb5b2eb40fbd3a79944bb509997a13023fcfd291233c9a3983cfcfdba569a0652e57ac17fe65290e03b59dd751e655dd4855d7eeb000c92dec625a4c4d4f73979455fb4c8941212b4ba9973ba94181f51a4fff6a63933cad67babfd6aebb5362a8a1975877e3c84af1d56095479f80b59e46a14797e7e8a24b8eef9905a0fabf0d0635189e8b148826b20baa2582610a00934849e33295cb1c8e7f9f94cf468fcf94d7a7efafcfcf9f92ec66df468e8e7fb187a447434a3516e54e6388f6afd76dc121388ebbc89d9839eef57a8cc6b5bbae8f95e65027131629c509993d9fc15a61519920aa3ffa68815312a5b8383b67e780f5a716e8e8ece394443385d8d966b933f5ac8850b726daa815c3e2746c66d55e673268cfe9c39de1c277eb2d7f1c9beab89a1d159edf688a313b732e53c240b4913d1b5e94caaae3e8c74040929ace33bfaa25314e664501a9d953179b8cbe7642e455f8b3e4686f42fcabea330ea739e207d8e1c1f5b0c5192cea7776b8c4fea72108415ba2a689840230541c8408687272f6178204c0fac2da44a05b90b25054e05e342e9f0dd60ad131a7031441939b513fc60c437874e1753c00431732a636608951450628c54778cb00943d5fa179b2bd844a159558a8278c677f05d7f36dd6eca82dffea6e8b7e76efc763966d89871a3e79099e9b6a0e93731de6389f92e662611d1a80df4073d9fd266d20f933bed9ea084e66fafb53c8a57f1283ce809f448ee4499d233fa307132f49c53869ecf6426adfe8339820f4820959b1377c4a9b022497c1cb307fd3da5c031cbccd7ce0124c97bd0df38f4fc3c8188b307fd7d41788dde359f9c320fbbeed0a17cb51c9bce0c9ba9a8ddcd0d9aa16cb51b3443b96a47a369519ef47523bb4d67868df69f8a7237da876ee4a2bff116585054e492a3ddf550767de38d1451be3657dd041335c6687f1bd99dca8859620d94197f6a82c8460e0afaa2aff1e14a54aa11141474ab915d1365d74536319387e7a987b26ba7f953ff4d7fa04d1e7e81b2addaa508659e3ce9ab953d8a57d1fe504f53ce03502bf33ccf07bd90100fcf15edae81b2eba0ec4d9387eb55beb6ea4947d3b10e923b4cc8f0293a8f922b43fbca278f63a812957ac671ecc9ae57d9354f6622e66bab9e5ab08e509c152299c1271a9fc5025d8bd9f548a4e66b8354addaf1fa918443fbd332b11c499a5e5054525def5e5d8d260fffab3da775e5e1cfe52e4ddf127da292271a7962b3d721b7dfd1fe375c4708c210df7bbd39a7b59fe7bdf4e779d7da7aaf67ef755d4b9fc4784efa7a0b6aa5d6291dbd36a9d39ae8a5943a21b157ef5f302fa9b049a9b5ae6bc337a15de2648e44e6c4397aa348b1d6b7e8bc644098788f2cf375fff57a75c08d6789f30e85063b168a92f9ba4fa4ca964cd8772985a26f1aba3e7625993ceeec42df21c8bc3461f759794e58ce69cc4226ec5a285d3facf32644d727ef92aead56927715e60e3441ae5584e7055e1c3141d244aab061072b50e46c3884d9314185d30cb6344410450f47785518a9ec4c61cd607d5268a1539f89568d169923bc5c29b6cc3011233921b9d6b798d0bb855bc17121d2677a91f6f7568d203fe8cb91acb03142ef793b838d16bdc92f0a1b2b9aac3a48a164ab0ef943b291628dea902ba0915466c91d3f642563526348954053b2e546ea0abd5fb82f0d5516244b4f3552b732248f9e6aa49250d1400ae9a946aa360212484f3552330c818234c6b06d7106b4610b28c02eb610a3c242f6e8a9660b225422d8820a972da40ca1c59d3130498403428806a7211c941f8270ad2b465003529a45095dd186cacf54d00d3e2264d9015d3185959e19a07eaeb0e9c013e5c9a703a494a99e2b76e0814543140f8e9de0ca8849bc22a3e448346cb08837e05851ab1976239a26aa845068228e0d51536112af481b9a5668681c006f211a543026f18ab4e1061519060fdf0e3cb30515ef86cf50a1c35592a1e9c3313235585a94e7011b2a94dced920395e264d59cd90108afc10c1a3f28d19ec815c6408691cd963066b67809ad90437aaad96245750519b4823b061996209481f4c8c0222083b608eb902b2baa0001192d604235a48f9e6ab408b14aa3c58791a6450724b4d4f0051176be108102700622765c7cf8124ea3eade6aae7e42116b21cd24ebb8e291f495d20e1c31165bf77e5ea8fa1cf6884a9ea752b9eebde0db8abfe2ef5be15f91618f157dea7857e24a2445a5cbba2b718a6f3517d1f5420ce5caf563165e71ad1612126529edc86dad78bd4f65145a1eafd3dae9933a10b53104aabe1e9ed0eb5959d22b8fa814fa882e669c47900c436bad0555e0873e6405c22b952a0cc3107be0f7b5a702017d9febeb444e313d72fa3ca292e5f151c1af74486bd112aeb0f91be8ac77d112459a3ce6673da1d0e15783c4a0ab3c54a9ea5bcda5ba5e88a1a42e1a45e8ee8e57b5865555abadb532317a30a6c338a6b3d6daff3caf5677777c6b45b2b556d56a8a73cedce47ee89ee7595b55b4d65a6bad551c8b8e88e5f75673f97ab2705aed1d3d9189be764c4c4cf465bd6fc56489eebb914a926050b544840596f3a9cd6d48311f42d86c365588c3959d4c3fa758e494b23e8420fd774b63d235846aa62ba4d72a553d93dddddd4e14956e258f98564d9cd0177da62148921c599645abec6395a1afbe4ccb59774cde1454863832ed987cb2d8f6ada59456a7f6ae486cbd0f03e9e9029daa564dae76570b5637b93a0c43a355a5912e8af8134930872380a3e98f9104fd1dfc756774a040b7281a3365d0dc6c36f3c16228ce64bd77fc202a9a66e61a2cf49e6fb4986b681abaa26ec5af68fabe65486fef92b383c92ec868fa2d2f66d0f4df8b339afe0b084d3f86e4c4175968aae68b9da6bfa4464e1260cc34550386169a86d145d37722c66c9686d6c485a66abcbc512306189aeac4680ab55a512f69484981ee092d3917ca50a28b9c30bedc8c28296e299c498142a529a594c6c8208dcc5c14bae228e4b6b9260eec2a477a80f574a74787b2028a0a312210234514e387841e916212cfef790b41cf9ffb033d81e0bcc7b88324853f690b060c3e38cbd7fdfa3fbda223e0db07dfbef7403f6948334bc5126209b9480a1b7dccad0a1b5f951d28ffe48abb9948858d379c43b146150b6a8ab9e779b2f89e795ea57a9f798382522fe744d273d43eb9e757397c9ebc7a56e6894d1ee3af7ee8f1c5cc6307d1e3d3bc37e8c0033d3e4fde1fe8f143323bced750d8f8740da5d4e803e4765c4b8f4f6f6e469b197fc8620498fb565ce31feb8f2fc594cda969999924fe38d22cf448cfe8f1dde6fda81af74a8f4fca66397ace758e7329ba138908a7117ef1db3709d69ff778da37d69fdee8cb5d73cce4f1bd100aa40a92cea8bbbbfbc7f4bd93ef937cbf845a3446cbc27cf255aa30742a4367b222ff5962277a34be12123d9a73a797b46ee81d041495b8d06f42658ea3b0f1e71da79c93942e33da82e8ddfd1370d1116fc7f4a4474b5a30d8a213beaf5f5d30141db195ce70e19a30fc39f10c71f448057ef8a1a8148a283c292975857835240c29040bb91de75bc627a76c82a104144480b1b363c4ac647d6bca5090f3860c0d0929368c29593f27ebf1647d1595582f8ab0f1dd35055d61768dc452bdcd37cf9fec6578ff09f99feb052fa4ebc8f7dfbfd0f3f89fd87bedfde9c945e47f3f4b9f5c44ba5c307ceff3f87b9f87017f4fcfe33fc167fc57858dacf15579cf9c1e3f1cc707f39e385b059deaf8e3bb6dfc1aa3d1f8e38faf6fb9ab6554c38a1edf5d1b8f6f0402d28d16a8bac34d55333369f523f823f9e3cf8f413f7ed55599d08f4fa998180b36d3fbf1e9138502fa51f5e3d332f4a888f5538f7afc9efec8e3da64e8da3f8ef6c7fbe30b654c3b083f28674c5faa07caf5cc04e236ef31fef8013dfeae57e871cf9d0e7ba8f6c9b3fc2a1bc1711c2d7d8dff93a9aec2c6273395435fe38399e6e86bfc2f178138e3fff913be0772c1e0f3dfff7c0f43cfe39fa5db1c0885337b8c3fc6d1e36f3a8eef93e92e8f4fe99bc9637c20559045abdf568f3ff5f45c5e4c98de3bc624393e09fef823c8faf14356768de91457a46ba6c7d7b4697c5a1b9fcec6a7b4f1a7d1e852c1ce2c0532239c463bc469fc33fac260148dff7720bd9f9eebef8b7f82fdf1bd3ca4b954b0566118ac3279e0a62325c81d96d1f8b70a179ad995a1471b9c45d1a38d6f2a1c26c15d95912eec5461f859188f24e984efcc24efb10aa62cf43261f8311860ccd9d849e337e02e859f9e4b8523af0b6cd2f843fcad9e7eb8cadbea95063598b4fad54a95b758a4ea90d25fbd90ea59f553f45c2c540d8220f8f4c15781be4a0e7de1d94c171501df7bcfb5a90b74a974f485ff890ebb905090defbab701affa7abb21f5a89ffcb5519084bfc104589ff93aab29f2f25fe0f5765208411a54cd4adcac0236e28f17fb62a7b95f83fa82af359024c89ff7bfa9caa2c9c218912ff57fb9aaa2c864389ffa355d9dc95f8bf59951175918b52e2f7a6aa4c4789dfdb55d965934410257e4f5765f34c89dfcb5519101a26a0414a4ed4adca6e90e00c1b549581613c3955990d23a828f17b35afa9ca88d294f83d9a37abb2d81d27a6aa6ceeaa0cd329f15f5d95e112ffcd5559cb036fa47055464e89ba55190b8912fb98a0c47fa1aa0cc89930b712ff7daa3220244afcd7a9ca6a193980c04d89ffd66e5395e12d4afc9756652f1294f8efacca6896345c6628f1dba92afb3953e2b7bb2af32a7020b053e2b7ba2a03ca52e2b7b92a7332a2a85051e2b75255e62355e2b7b82a9b67d028c289a85b95dd196c505506c21959b23c3955d9774689a911257edb5465631a20ea94f82dcdceaa6caa99da55d918751381ce96f8ab5495d12c25fe8aab3210ead48828716b87127fbd5599371561c61325f6f2cb93d55262da81128700258a1194f82b0da329f157e23752baeba6c43e667055f6c197204210e5ba31564afcd45665aa124f1550d1a5c4b01d4afcd4a9caec9c33b92d257e5aab3594f829adca7894f87daa0d19257e4c569908a7ca98f2e74e39f670e74b09342bf1c7aa8ca80738257ea42af364a10f3994f889e050a7c42556419a12ff12a62a0bd2428b12bf9309060e5e683fe86a4e55f6534598a79fda16dbcf1565a2a654113594782c318f131725f64a8caf94f8bf5d95fd0cd7e811065c349ecd66b459b9bfa98d671acf66331966e5c6b41994d9acdcb829c4f14ca93534d5a5301d88bbed69bab6097d5526211dc8ca54bf899317a88b0bfede7e2e979a4ae891cf2f76f56d669a3c743e47ce54811c3dabb53e53adefa4eea88853dc70e08c3666441ddcece07920bd61954eca97abb0d9450d6bb2505333630316b332342ca29ac88186449a5b9b0e48c141514cb6f06867d5e64a1d9cc5152f5858aea491e24a146dae30b1c58ddb23fbf5439aafcbadad43d46bf544a57ae9ad6650ea95d6ea391d624e77ca43dd6752e5803ba554695eebda17bbe657eb73ce09f20c79b5773efeaecbba9d53d585b51893ad2b2acd17529d525a35fd59e9f43ce9abde7be6de5a9568636bb5ada1e9b5d67a6fad6dec3d41a8855c616a6bb5f4be9d4f6e770abcb3485d62357054ae00220b203cd085155da4d44c704bc3c59834681082ac53a992303722a0a0c0860ed854b73557b001f3a6ce0daa15e060068c8de16de818794b8495921a9078b5a3923b805a58034d2feb5b249e1493ad0f55e007e2eff36ebdb6de1aa313bf1295bcd72735d33d1f8a4a3d768befd3dfe39d1bfd3d694618fd7deb8c28fadbdda0bfa722658a99e6795054e2b1f75e7befbd6538a15f2329d2d9428bef894a225eadfe8a4a2b727ed63e26ada593031954d85748ca660d4d0617ad22d2aaa7a2920a43f918ed8fc7d0a3eb7d1854852b7164913c3d3e3f404142ad21a2a21a366e58f0d97581110e0c72bc603a32d8c143831eb10d7c70f0a383231992074940827c004208427429c2084a43482052040001302280011060a904130a70c40027a080e4000848400a0a5800039234008a031ea004021190c092096c1598ac40810a30b1d082059a5c00031970e2820636f0020c313cf1197e82927d969fc49061c82fe40d640db8909de40c640ce40be426d902b9057f163253ae40a640defea4fd57c84cb20a396f8fd2fe135892259023902190b7efb4bf92fc80fc0ec89bd2b47f03fc936406e405e44da1b4bf02f2a636ed9f424e40de344afb23206f8ad3fe07f0479237cd697f144ec89beeb4bf01f2a653daff482e80bf09b984bc6b4dfb2f6502e45d9fb4ff00b200f2ae36ed6f24ef7ad3fe01c8bb46697f00e422795729ed4f24ef9ad3fe24e45d75da7f4856cabb4e69ff11f2b633ed2f42de96a6fdcbbc6d93f6d779db9af6179243c8db3e697f10f2b650daff83bcad4dfb07c9dbdeb43f90bc6d94f64fcadbe2b4bf07795b29ed8f94b7cd697f99ff51de76a7fd3bc8dbeaf48fbcef4cfb7390f7a5697f1f79df26edbf41deb7a6fd63795f27eddf23effba4fd35c8fb42697f1e795f9bf6df9133c8fb46697f1d795f9cf687e57da5b4ff2bef9bd3fe39f2be3aed8f41de77a7fd71e47da7b4bf51dede4cfb5f90b747d3feaebcbd26ed9ff3f66adafff3f69cb4bf05797b4fdb83da9e4dfbd7c8dbbb69ff227fa2bc3d9cf61fcadb93da5e6e7bbaededb637b5bfd9fe68fb6bda5fed73d2feacbcbfa7fd41edcfb6bfdbfea23e9cfea4f697db9f4e7fbbfd4de92d4e576a569aa660a82a86565d18caa63786d2fe530c8e62a347f608cf1e436131aebd43ef27bf7df61b86df31fcdec0ef177ebbf05b03bf33f0dbc9ef0bfcc6c06f0bfc6ef29b85df2dfcaec06fa6df2bfca6c06f157e33f93d81dffbb7047e2ff90d81df11f8fd80df4a7e37e0b7037e33e07792df0af8bd80df09f89dc2ef03fc46c06f147e23f96d80df27fc2ec0ef23bf4bf86dc26f02fc5efa2d80df03f81d80df467e17f90d80df24fc26f25be9f790df22fc1ee1b7fe5dfe0ee1b790df1ffc06e13790df417e7bf03be9b7ec37d2ef0e7e1ffde6e0f78fdf1bfcf6f1bbc7efd86f1ebf35f89dc1ef1dbf61bf75fccef1fbf51bc76f0c7e5ff0dbe877feedfa6dc1efff6de3f78ddf45bf6bfc1efa4df45be877eb37d0efa0df3ebf7f7ef3fceef9cdfa4dfe167f8fbfc3dfabdfe06fd5efef37f69e3c79325561339fed7c965d3f810106183e5d0c31c4f0e562c8ae61d8c00636f049bdf0c20b1fee85ec7a032eb8e0c217a5010d68e0bb6920bb76210319c8c06773e2c4c907e524bbcec0052e7081ef090318c0c0e78481ecfa0216b08005be5a93264dbea626d9b505586081858fd6420b2d7cb316b26b162a50810a78534c4c4cde8e29bbaec00a2bace0e92840010a78390a64d72ba8a0820a9e1413264c3c1c93ec5a85094c60025ed4dedbbbedec7a02129080043cdb92254b3ca825d9b50420000108784f118840043ca70864d71078c0031ee0d5942851e23529c9ae1fd0800634c0a339c0010ef0660ec8ae1bc0000630e04e254992e4ee9264d70c5080021470750b58c0026e6e01d9b502129080045ca9145248e1e252c8ae137080031ce04621000108b8370464d70740010514ae0d091224170a49768d82010c6080fb74c209275ca713b26b0314a00005b8b523478edca623d975014a28a1844b33c10413eecc84ecba0402108000766a6969c9ee96b26b0208400002b0ba010c6000363780ec5a0001084000ac941123462cce48761d8022458ad82800000000f60680ecba08092490606d448810b15044b26b12949494ecd3902143acd390ec5a49041144b0b5114618c1368d905d8ba0b5b6b4b22cedacccae7508218450a7840811527742b2eb103ef8e083aa030104106a0e84ecfa0320408054a9204182545c90ec1a88071e7850a3929292ea2d29bbf6402693551b1212528542caae651d74d0417d3a3a3aaa4e47d975071c70c041adfdf8f1a336fdc8ae39d860830d2acd870f1f75e623bbdea0478f1e742a168bd15d2cbbeec183070faad340030d7215e69a4706196420b563c70edc8eec3a03180c16a543878e9b8eec1a9623470edbebf5827a65d73970e0c0f1840106183861905de3b8e0820b6a4646464d46d9f50539674a73b95c74e6caaeb305165830f5ffbbcfae2db061c386eec68d1beeda46515191548d1a357015e63a1c1a1a222222d243424242b656ab05d5caae858080809e8282829c82b26b201f1f9f5a85fdfc34fd64d73e3c3cb49e9e1e9f55180f8bc57242922413995db344515c328e63920a73d76218864856abd5920e411024a252a9845498ebf0fb3e8c6315f6ddfbaa30cffb0aabb5b65c8607f5148fd8d9cc6578eb32b8c80af36fcaffdbf97f3aff2f2785f3ffa2fcbf9bff67fba0fcbfa7cfc9ffabf97f4dfe1fcdff9bf97b53fede4e9793c245dd6c504f4efe5ecd6bf2f768deccff4ef9df9d2ee7ce8af2bf37ff6bf3bf50fef7e93af9df9aff6df2bf34ff3b73a09dbfd5f9db9c142eea6683f2b74ffed6c9dfd66c93bfa5d9d9d4ae569d7fcdf95729ff8af3af51fef56683f2af4ffed5c9bfd66a937fa5f9d7d9d4ce9feafc694e0ae74fa3fce9cd9fdafc29943f7df2a74efeb4e64f694efab7deffe51ff347f217e24f64c91f4912ff254cfe4e66b4a69a937bb65b144eca73feaef3f79dbf4ff9d3993f9ee12777af6977d2aed3f80685fa0c6690de82821205ac6caad852822eb732a03c09238517da4e0c19375496282d03a529a594d21fd28a1509eee8fa75ce1a5d1f1495ea6a85439c3366e83081458b11e526672ecc0f6634f18131333a6508650d1b4d7f044a29a514ebd0f53109d2e8fa330d5d491c6a8c00091f0149448d60a6f809338518a6ce171084f9d2fa8206ebcb0f2d306d585fce0429314584ca61a809a22f37c2680993a0fd88c142288c0fbb99f522078bb901484c1aab24aefc84791342ad60c8cb1d12cc0882a68011bf682501d552e287f0cb1741524cad00ca4c90189d5018314425b67861d48049d8612921077b318281e22a718478432d33a3b342c3f2a286878c22b012703ea8dd08060c3945125a8864ee8801959813be90d0214ced16c64a1a47044166d705bc2386de2ddc912e3e2548233dd5dc8942ef18983b5af01972d453cd9d1e9eb8434574227df45463e7ce78c68e1947d8f1228b14143b685432902b3dd5d821f3183fc6242649fc38e2949165080db738b821a4e200e114a72644539c28568670e0890b33781822a5c6851754866071c231acc594a21852ec0752d3ae69aacaac0aad4ad357a9bdaa38c5aa3c51d8b4c1c514443e34f950f3c1c98727fa5c3c61c310ad888b2c575a5366445cd07045874dd014c483190a9b6bf01b0a9b3cc869d18f612e380014438afd4012628a105684b822d43a53e5671604022a3e43aee08070ec4b530f26f18aac014761538ac2a61e52438ec2a6fe69c5309c2c39f0c490623f9086dc90f381938315f287a79e187e93062b8614fb81346416c583df88511b67709ae1897cd3268737565019e283d49b277498bd0983c39020de10d134c406fcc68729b8a653bdb961ca17a5294a0d4c41933704081b8e613178b831a4d80fa49a53ede973c346070ba5cc102866286cea8d49375258192243cdcd13b421536c6ebc340dc9a1c98d105486e000d53a4336c658cb32060b3204630409744594226d0d2c224b93195968a0810cf554e39482af062739b808f2f554e354068cd3123f9082b4f454b3e58c2b6ec18bbd9af19cfe1ba627cc1fb446d641b7bea3d27b5db462ab577fd795243d6b6fadf35f3171fcbe5aeb57e728a9f5955babaca2631923f64d4e64d91c92d1ae3162a3840889c249d5d7b15eb4d7472ab0702ab06033cb5081059b15195aaf2b7225ae56ab15f692764c1efeb55aecfa6f55657fff8d12fb81aee48e600e0946ba1d79f6ae91baa3cab3235cd5cd22d1d58e5cec65edcb49e14195f58a6315842483acc4b9029a36260effa80d1b26eef33f99371de2cf71b0a0abc06af19c737eb5d65a85a27873ce69a9c05868d8ccdfbdadcf7a3b8c5a2d8c3f15f8d605667bafb5b6b628b60ed66aadb5b556950d1484d3c869b5a00a54617b915aff8a2d911463174992385c7db1582c7655a2472ee19670385c8c2449156e0987c3854b3e93a66af46003588cac308a412ab0d0ae96a623cbaac87a6dbd96f522278cbecf94a99ebef32c1569ba9403484e598ccac8798bb2d7e6a5ea02495aafc5f55a9e1eef51f94c1c0eb7845b8a5519adbfe47347bfeffbbedc1c2ff6c2f85b15e6b446e5eebdd6dd2badb4d2baa2b9d6fa7ddf87546b2d42dfddbd9a1162299d73aef05dd14c279d742ee10aa3393787e69b14a594524a69f5eab5a8c89caef9d37b6ef55cb5f7292de10afbbeafd6ac82f7bd0bdef3d822fb2d792f770f027e9f277402eb17bbb5602c8c970f31700ec91a2351423e6be728410a637a36c88e6bedb5d5bbf8b3d65aebed983c2689df35bf394aa6adf8e2afa52dc5480eaeb05b6b53a0aff9a10f3148b7d6fa08e33da65281a40b4d388d2ebdf7decb63a5ccdceebdd65a7bedbdd75a165af662dcaaf14613d42adcbf45ae212576d19068acbeec9718bc1f8d2cf15b71c8a7ef477d8ad81573d9bf734ed6bcf7decbd393bb6becdd75d3baef75cf02ade6d4df54cfbbefbce1281c5255859fea3f55e8fabeefa3b5deeb53833c9ec295f7f61d671a2ec3077314294865e8c24fc3e5ca05be900a6615f861a6214591824bf0694865f821f52a595bab6a83f27812455506c3ac7a90c552a954af72b578288fcff509818484425bab108bc1a42fff11a4cc8efbd65afb736b255b3f9f28ac61ed9ca058345bb3de7befcbe6b7c0e5a2388c6e8e1c2bab03cc9f2a83ff650c5bd57087f7d57361f05dc04f56502caae04fb1a8ba96f0eb7d870a3f1843f97dec52fd031c385e8a8883050b162f45c4c1e2a5883843d8216aadb5567bedadb5d630cc8ef3d2a3e278d51b635dd5d6060b162f70e260c182c50b9c3858bcc08933844a174ea35de7b4d45eefc35715aec47025f2f4f8fc000509b584888a6ad8b86141be202c71ad332e74cacd546d12b9545a85511f6e48faa191d18b8cc291acd65b80bb61232aaa06d515895c688ee6721695f06300220919818891a52324ab88883a0dd11aadb528bd71a150503ac70ac79048d61b232310d133a9be6dc712124ba0e5e8729daeae6a90a8b45433a571a1b31c3944a5fb394412a8aeaf55a8ab981d3f82e8a9f2aaeda7ca54d92bf194ad7eda5519c260a2927d1d3be891f57b55363bcea354b88eb101899ed3a14354b219d83a65d566ab51b556ab5d711295aaab565b6db548b2b2b2375558adc8fb38cd69fe5461f47b442eee94dd76e3e250b0154c54c2bfa322051172f187bf3ba6de4425fa4b2c918825a3c82589132e4c19f05889ac51566b4c7830815431295059b5555bb58d59c44490fe1baf442eef062914b9c46e754ccd81540fcc1ef4d7e86a46d34faa4e5426865cfa3c9cc89047a8fa9e60fa64b09b32c27480046edeac600c08536e8ed072041a1f7251b0d290a1940b72e8c2881054f1849d207a7ca1b3c4113cecb0841941f87c010a69a04f9a0853c50c0f68ac90428ead0d145e7270e490808a37c5123d7861143c4217e4084ea4a79a3b7534d6530d19507c373ca39cc4afb72ffcd2e11bd454054192829c329e56621977c671cd194bd4a864284f942975c650f594314117d28775020f08fd80684c11a2625439158d353c41a49d26c270068b6b501909850cdb75bb46695a71339ad63db4514326ce0f62dcca6db380a24c1a3b54be4023556e7b03c3cc07b250628c2b53bc287398400b175de8e444304689cf600c86c618a7e08bc629b0a3f103894af84934b468f27f44251207bd8fa814547f74ada16b9d5555678d6112055674fd160abed0f55f8caeff8aa5d1f591a6de9c00a76b14d0f3884a406ec1c72790a241138cd1e093a21248befe7996a8f4c3aa5347b37e14955878a67d5e14957cac57437b46daf3bc1240d15e09b6d05e1d1ecec0427b019eaca8a44b5b2b7a549921110000000082000317000020100a070402390c647928f8f814000f5d90465e5830184a05418ca62886611896018000820000c618830c535575008cc290d61b918a4e087aa931bf74ef8baeb4206852228a6390269ea2fe0d441b68a34b082942e648d4c413d2bf23d2d38004fa5337374a26e4c723eabc805c6910e1a442084e459db821edcb22351db4147dce48a343696931bd07d19a564842b6a8e044c49a0e9b88faaf216aba4419f9908223912d2e08ff9a68a1878652f655cf443a0d883c89f62bf55118e231ab49a34b260e10f6adc99686521173a34f949180d4884336256dedf49cfef82c9524a10ff534099c9dc462461eb2a9fde3dc409e5de333bb37640b7a3bb056eaecaa86dbc050b573ddb4682ef36737ab803b5986cd5e324c3a9ca6e1b0a5ed70e6ac128af25db56988f6a321752778f9ea7bb47bb8964cc6707d4cdaaca900fb45daacb51244644bed3f97ef4e2ce43e5d54a34627299610ede6f6e567237451cc4a45f7a6bbcfad23a4243d33a64c53465c74f5c5d2b0cbf21c62305d38ef79fa3980e3a754b397cb37615b96aa58a19849338248bbd7e33737210355e254fc1c69f634e20a99226ac4fb248af08334dabe2aedd880d30777ac8f38f4f5c3a028508d1b6c49d5845ceed9e499e4f3a3047aa5e5c2590a6a95fc886db8e1c8ff393a8a52f21541dd5e557e8a17930bc0c45c2180f9c6b395ed1d394de14fa75c29f97317eb658414b9bdb2a5b17566a5066ed174f3fae13b300467a3fb2303f259e26da6204a04a72ed25e09a28af106ca8f887ee1955da2d8f110b00178cb79cfdadcc098d856f74613a267e8b6a9a3224dc43cc270279a617a2e5bc320d5d181e4cd801b53a098ce76f28ac0f40457b29deb5e7008635fe2dd4a0fc09afb9dc0e9ab042abb77d095b29c9a7c85a01fb0cfa2c6d9f013a4ddc7a0720b27a2d973e4aacc221878fa1ca13b4d53af0a2eb30be5a250117db0400bab79f9fa93a9b6cde1d97370d7cd9815acf1250ecbd5257035235b31d2319ffeee7551241428e98ae34f69b367918b6482c8d147edf4e989097e39c25e35a83b4d549d2741198482f5bb845824bd0c05a1e6c7319016e2d3fd759111083cc60bdb74c70682782f45d3a0ce544557576f3c035aa478f4a818dc3476452f574505a81bf91740973fa3eced2cdda5d176ad77ccf560bce5bc87f09b0ff830084f3dda0ab593debe6cec3d8f9bf14c225130439d791fb71a6ea98454e17a8eb0f0ab8318ad12c719a467e2ca7ac9343472d22832ea5a6768971529330be76c8c41b7bc178e7b1e8d1155d89d7a42a0ec9098294702378e8ad32469800dbe9468c1986178c833bf55c5fedc7443d5101853c53e6cf64b7de6458483a788b4d3d334ecb9a91a22ab01d86f25500dacf520864a4c9742ac4e92f66f2dab032cacdec6da3e2e367b453d8798772517a1da5e2a4610d929e0ae00e4ccb2be3110570c05fd100dc9d0946130a7b6acc39b1b1438ab7e37889fe9377b7f3db688bcd28ea23701a63e38083d3c1bb3b14512d483d3040c6796f0354ed272106d84dfc48e99174331e22725998610b3de20e4d82990dd1ffa3f809e7b4bff1bdcc783880459aaaa6e176e6a8eb807cb67654bb3bde86bcf3aaf4224aed42bfc15786f5af07442c0cf0cbd9b324ad7cec4f7eaf5027c9d5c8217f0f569f9c97ff6820371ec89c12f8d8e40adcaec0d58f6d4fab6ee48d7c28d5c928f15d1e9391dae726d7b662e49380032702d9c9abd93b74eb900a615ed374af77bfc015873785f76b7f35ceecdff4fdfc80bca0097f99affb3261c371e8c0295bebf508f56c88bea34d4fdbcd41ac4510be34cec9051eef01d914867f58674eb53a322b92d9299692d763e8172a23e963f1f73e0be3b9220634cc4ed68b4389e320823d0c6f428b4c583ae50ec35c11a7cac882e6df2b267b90ef111120ed08b05fb547b3192468dc0f8c06750889c4112b932822af87d54bbc9da9e6cc88d737f861f5ed3ee732a2a0cefeeb3cc32bb1954e55d6c831afefc8695477e85aafc9366bb5b4a6ed6a03c7f3e80bbfa4749013bbe57c0452ddd2e65c29e89405712fd17b36da215c7955e86fb151db5f7c364f9b912b1bca9f5082c7a5297ff0180b0e8dc87b9cd520c50078445b00727f6724bd4c00331c0d022bd54990e87d2f33ac7e72c170d83e6d0d13a0468300186f49b0d90c549825644791cc23427a381e70943e94723c78d505f5f1833ee8cbeecb514bc98097b4c8b0236e01256d30279c1ec2ac53a643d30fbba52efec9a8e2b2cdf05e9b21cb457a9f958edcbb6151d407c1a5084e9bd8ba716994eac520459e2b7a048fa01208c166e25ef2270856d737c3b27c5f7b6f1f76ca76493c1949137022b74b7fd3a2c24b614e2e4b7e2eb5da021679af56ce9a1d1aa2128c5bd4870ee8d5644fd58837b094a0991af013f3da923b474d6775ccee3fbcb0fd68c68c7af121abf7718f576f6cc363fde2274726df5ac6e17513f028524517179c728c4f6cb11fbdc255effeaea3ea471520008b39e46367cf3337a4c8f90a2e82e1ad322fcef96a9f0148e1394792b5f7fe5d7ad89501e696e6723ec997cd19c11d6bc442b5c09fd650bf1425e83206b04b362605f07a415e3fb07432a11a596c0b072340c06e8ab6a3a7a68fb0c237a048f4433e8a9d328ec1be67fb3b4850eab5ecb7d7329b38156f8313e964b7e84bd803c018cd2b69dc0dbf573e8cb2642732723484939a07ad9d63ebbb5877999dc4f638c3e3c00395f3ae3e0bef89e6aeca814381edbc1290a6d60368673310a839e02a806b91d6644f1e44c107d3416a8a1f47a98b2bbc54b4b66a824e4ded4a26e1a37da1f9153e4594da9a9260faf15ee0b7696b5c3bd04fc3a45d740e5991733b921ad51867580155b1c60f39e03fb49b1d0f475b8407c16301e1c0dadc9c5bb5d0d000586dc63e3016fe8d0072d24c12478c721aa891472dec8542a5a33692b3967967736168a51b6e5e5885e14c662bab3c3e6104efcfb4a64030a45a8c324bcf57e33f273f102233324f0de3e25e3aade968e0286b641206e9668499f5404d27120d9f691a3d131d4ea787ac9c8aac80104600a69df13afc906c182d9b181ca0a5436dff90ea4dc6c226cb95f0f6d33e13e0a58bd94740b8d82eab1e4a9c3024b65c8f4abc9086ed36a42035525503e8606ba28fddf31e6d97874b341ddaea5c3a0c92db09fcae87de65ba74f53d264c70eff8fe1bf1c8b45343e2cfe8ff54da1758ff7900bb738bc96b7d0c09626b6bd07490a3ce961ff100b26bd70ab885f817c4299c5a386f0455fadcc45e1021cf87fafad73f42bec7b4ef6049860248da26e7a86251e9d94f7c4952d5b65e5bde1970e987193b5b63ad45e2a71aa1ec364c72a9ca161427740034e3077b38c5604d0cee04cc8f0cdefd1216de08e5b93f505a7e41da5ccf8b3c6328ccd57aeeec14401a0e68fdf4d04422ee747fe1b2599aa6de69052af34001260b959bcf288ddcd0ddb772a9bb1c6a83dda556084559b880ddded3e6d01703786a219937593d985edfbafc19f0e27110fbba5d4861c5eab6e3b50a814b888ac3c17608b5017ee229571ba1e6278acaa15f74e250b37bbb3b286336e9ae660d13fdf20de10c15b024d51440df24a208dfc2c96a3d3b38fd9a0a97e534d522f151a254bb3d1a7c959bca3d3499c7d911db0825315c5f258eee1b2b3857dfdeaf2885029b59548e9d5705e561f9999dc6122789533a71012177a16854ab8fa123c476309465bad9bceffbaa189fa42ffe80b1df0b657de27c082d6750536cc68b9b7f34b12d725906ccebb6e550ba90ad32edcaad75d4f0df86efffb48f96191a7e86686bba66f29dfa6d6093c87d0671eab1c2e51c44a955e7c5dead497e8c0f7a76b71eda23ba11bda48047d22bbc0c81ed592f05beec8f8e7b3b55d4946fd55fd62500ea0cbf6d9cfc463411873baafa6b0e474c12549d49b3e7ea8da1049649ad2aac186e42dcab3a9f34513e37c2fc8f260a5aa4ec1febde68370bee6b83f76147693187d5e84986acda408986bc1358cdae09610960bcef430ddafa257390dee0342b2658714b060182b2d49f7e0ab45bba9d3deb35d3aef0b08a2901d79a1137c7055b8aa9e5e4bf585e5b0bace1e315a3afbd848e2815e9450ba65618bda391b7886f64a60f81ed4738b388e43f1c79c87267dc38fe0929ac378ba5f0dd96763f2aff8e64ec2e59416d441828cc549268ede896d48d07c696aa279cc60d9edd71702770d1c673a7a0e78d310fbaaead33662228566d77f60b861777b6e78b10e5ae3cc6849d3700850bf171c5b1075109d443d51cadb5021f770f5f91af1774d3b1f5aa2192df26f11fe9d9f4bcbe528b2a39e0ec6a34366f7646651735b73ef21ff65e4baa3ee69e620dee5eb4b37dd678efe763acee0c239efdcd9efdaf8e7b9440adc758b469eddcef37f5aecdeefbfc780e4d04809c453f9f5c31e9736f950054b79222422d4514a74458894498c88fc369a25b0021f60308e60f137055af9e67e29f3d17ea7f6e52279246543b454518dbfe92ae1f41f797839bda2cef50a19eca8ff0e48902dfcd06d52f2c9f8646e61d62471b04be73de396db20d74651a129243f0b9ebe9192785fcd0d2a04e8ed11f0ed90006f80a454324835be9cf1c19040c1ee2c02ade37eaf1e4f05198092e51b1f82884827223903cc51f2d4c3afee4e6c539c33f75ae34c1d75589ea5993a66367a00662a761a726928d1816acbbcb96792f6d2972186207bddad58a7d7e4eb8bacc4f61bd4e118c442fbc2d41609cc3af81418ab916d06cabba306aec1eab52191777497a84e200cf6bd7000196fb494e2e3829a8fe7b052b3c5040d0765e2b26dcd767f83c72149d45b2b47bb838ff7a448ba4205dabf9b878e4bb8ecbe9b883d52728d5d7511bb5aa3d36f42b5a267e055c789d56626d50562a043e4097a09cf9c4c0b40197014aeec6e8cdbc88479d2f7352e62f0367d2776749a9767cc749921f6f5ced268b0c285108bfdd2943f0a5d6ab4f512d3244c92f01841f24586cd9139f8c778501dda48ed77b523835b1f4b7893ef9cecb9630499585c46c0654bf47ae9dc87b89033bc8b0c55cd66302fc5b919b75a88028c70cea280ba2b0357f9f5b4fa920056810ff0b3ae795c2f731de0980843ec6db53257f270a039cba0472eddf1c335544581edc7db602b49353936a489b4bdda1c7a714835f970226a4a5c81e89d644e86f145d1673140d701f8c28feb93abacadbe5314a0405a3cad5fe8b7ca8a9f41af97f6dcc4e24dba5eec13fb948c770b77b4d09a0ff8ff88d53a013c0aa833363df6c2bf6001bb8719f7d4daeeb24f6ed05f02e49786bd6a4ae593874230314b358920b0ca6f4a31e25f5c8ed352f419e3123ecf2cb86e5d832337a3ee2f1a4ee7721b1f6e764147803db8bd675da75f89fa9a4b211137f798faaa41a8b0c5a529efe58e5654466ae8025fa55467a5769cd93d71465edf5520d84de44df1c297f8919b4bf281e4f13a4683b20f42279dfdb875bb3b4d74b320780fc7c66a26553805b50f89a64122e23ad91925952a0af0f98e41bbcfd7862daec76aad5a1e56e40e10f7d06df66ab76a38d24108c6787e9fa7ce47afbd74c146425eb9456caa0e0aba1f1b1b8dbaa98e88cd5d6dd82228943114ae35ba05ee20f95a5aaa57a891e70e205f1a49cef574cecbb865f47e180a1e0b1ebfad2072dc44a06d2a792e1de8d3dd9badb19d051bd668ac07c3352d0e4dd8b068c74decfdab930f6fa21ae5cdc7c245b7db7777e364b9b5a5664f43020a9efe5640eb81359d4b51e54b112df2eb5db810194bf1c440c9405790ec126414e76585145f532ebcbd83ad6d86c939f7c0f214d5f621dc0512db229392068c0f4e56751ffceaf6bd8fe5713518bde488c157657d0ecb5a7d76c9e13db381cbc854b64873a90eefcbf0cf115a6dd5871633ca56ca2d5d6bbeec3563f4d8b846813baf3b6890d2975e696dda7407c23696f9b214fa52d1a1b35be9e43eddfbe68d8a144ebd77331af8e8ddbba05c97b1b395b82d7e5fde8c923115e4b484b11d86f075b1258ce27a1b1daf4110edbbb22aef92a7c56ff815b02058795584dc7b04cebe35ac7378d5d4ac2f1c973fdecd1b17f37b5d4505202e86053fa11508feb0fceed3ba51ace0ff91172baa0d5c20176f8b6e979d6a7ae150478d5fd739c37b0c3a8dad2183b8120ddea6a90f54c0174f6214f418e854664b6f05c3e2e531ab6a67b4db5b0d8d5001855f4f89db12d1288b4af728386d88157b85146826710e3a0dac8a267fb9a9e0b69a999bf1da5817ae573d0054e3b18c8683aed7cc73b044aec5f87b026d0b1787a8fd39dae5060ee930cace7e9915db174310150f314ac0c9a098994bc37947e0e46bf3a29464a64918c9e25ffcd8fd8da74f422a02fd015a687b17455762f651d74c05889a5643f6ac35ea23ac7e3d98a36b2eeb6ab4e66428a624ab795f17f919e961b7d302f5286ac05f52a9a348a3a7f3f45574579a22da131301c679c8ac5b8766b8217ae2853694e3f016ecb209d6651c6742e42cf2f7e38614a6dd9e638401c9d69d91e322ae92473a402d221657b0a25d213228e48443a8b49f0770a0192aaf546c0767520983ba464297dfecf93c0f09cde0e2983e4490a3433f3387367b9861e73a2c7a58c39de181dc1591263f6af3d2f7d09607a12ba2e5948567e3a6d07b93974a0fc586b03a23b72ea16c240c8f7293f953f0b54f445f247cdcd271667ae4c974bc4fd741875c4fc935093955dbab786228add7672b5d5133f166583871e8d86bca5b9f0bded7df5aa298404c603fc09da7d224832f4813edb9c8835b8aaeb83cc25cc8db277b977143dce1debfafe4bd17e9b8554be27b93280948d3b5d9ab717e3f060a53647a103808c043212de546ef3c294b9c83277e30748ba46d627bb37f7b9e02b1a6324f44d1dccb83a10cb5c5d625937063ca0dd382a196b8e7979306f17f28b8a806030d62a5123407a1ea97f4eeb7f7ab81b1de46bfcc388c42744be21714f3d88687dbf389770d1c236e2eac8268d34aee8c772bd3752f999282b15c934cb5d477be14644dedc3778d945ea84400f8eb216f40a4a753f4061522ec092392d46d5ad5c740a8c054c6ce71b55978f34389fcc78add545a3a59a32b750a8c3654d75cf2712a7d5df0947159d75bd7cce1a0472d907ea3886bd6d85762c0bbcf052406b26e1a4e93f96fae2faf4edd1481418c64ad5825c6fd1b2e588b878c513767d3043aad336e00da660c1f2c92ae04fc2b3e8a50339d3468d74a1ba1946ba22bf06ec46629d68fa1581c2b9f7162549affe234a563239744c48f5b91667abe030bb1d094a23c2d5bc9f5c03c291b6ee9d48f152b822cafce0faadb04702151c3c4aeb8c89a1c9e4d438dc0d120f56d52ca2996d43f2748f3e851f8160d0d6feff95e9d8d6b65484dee938b331faf69deabcd6b01cbf95669bdd9c64f1135916e26660ed8e12d0ed80bfc2bd78f992e749c2c69106e4776956df95273bba0b4e2f9425da364dd86e436dba304d6cfa05f32e5cc0d90a3e839cd8b9eec9934c3c0c18f4476997ab586630fc4151935cd8a5e3fa1c28e8a3121eb5d57bbb07ee1c51e8944ecf8e130e00e03d426277339cfb2243e369b2b357394c29a3564fb591703d5ab928311527428bffbeab4e7dc822d010d0628d8e97624caa1ea1f533041a814f0d14bfbc1d5c4f24e9462cbc37428732b9b8ec4c2e86f4124891f4cc4ed346c6aa186a6bb70ea5a3ebe5be08efe643d58ea9564e1af4f33ea0c291dc76114c45f3fb016373d2051d1f3c1c6b6dc0f293e84a61c99b9965a2c6eea16c283108b964f8961391276475489e6ade7ae1ac725d0791a38897f5e3213abea8c03bc723f6d89ecee0308ec262034d17a8d04cc24465d09b100641b9a7257c91c0cce9fc60e28d73ec073951bac8301682fd325ef74e65f6ef60146a69428998d084ba9fa7d9b7feed9bcd318027a7d00b3f609dbc2a9ac76352366aeebb714f1702e8ff46007f13f8665724c7d00127608480ede2ddead0fc06079a349bb053f708d49093eea03183ebfc3f4771492ddfb0055444ba3dc0760557f4472726a283acedcaad203c8a8f061bf11b49e046ce25609c2757d08829add4f028ee84aebcbb07e7a050c88449d804a02daecff15c50bff177ed2bbb4a0164319bd786e94fdf92468ba26d4b603d2f0fd9c1c4556fb01f3445453c7ca16b28893bbbf02128e076814a850c91db7e420f247ff76e042fa75c4b370a1d6265e9120d16fae0d7fd35d333272387bbb2210c4ad8260ea7a5f2323fe6df4843b0596a26387ed28640faea8172e8e986d50beff47305722aab779c21d88d28c3d132f41502a5820bdc983b8611d2854d62121be0b4c1a65005a342bba05003a9212de6e8183a05a17f9be59cf30fcf211fe431d2d09412e4a34d19aa4ff48f98479f023ae019ba0479ce1ebc1d0572269009055c239b6ef4d90711264d4aa002459279624a77baf4009372a43b24e22fe6147243411824a4d0b9e8e128d72dd574dc49b67c6fe634a6db6d914b2f50820f1aa01af062403b260c60004623a5a6ec4eda511562b2687b488df24ac10ecface880effe4017ab71a0e48a0c6f7e77864ee83176a31834608b49c40270f584fa048052ca750888316d3508420abc9857c400a5b398126072c9e4290c32ce620c8a116d39024418b0964a4a0e50c219c9810b69e81200b594e421087ad4da1086156a69084d0961348a290a509f412906171cc1b623987220eb498429105594da149822d275009014b53d0c400622d68924d089d30dfbfe6f5d0955c0bbc066f0fd8cf07d42e8efb9851b90b711cf2ad64a1fa296de48f29bf3e1dbd0a5722204ac3f0c9afc725c439a6165ebce6cb53e514801f8ff59021eb62c1a050ed00a8e320a59bc24f9552150d487acce8d9464e719dcf87c74d80454258c3885282c49ad89da2fe1af207e14e292ddd52bb87e7f8932e0ddec1d5df34c065ff5fce36f4d29921a007684cfdea01cbcad7829a5ea73e09f50af1dfef3befe77a5f7e7d2aa11f78d24fa7f9666ebf9024eff9651468e38c0781bf77491ffe00b610c57b4ec0cf80b64678241b7e400b4611687fc64b6d83892a7ed037c5434e63d8e9a2941941cbf52cdba602722b7fc0c52222c6e1c2acfce514ee019f8b363e3cd116a834ad0d7572a95c958b721d4a62d029c3c9a441640f71d7d7be01f41d059fddc6a4855bbab57019b065eb39d45f4ad581fdf25216ee0a92cabdc2140c11a67a2ce1d373359700167269e665953e6bb0972d0b40ff16fe5c09378b5e3ba0ee9d2a6d1cbaa7fa7a13dbd0ad0ca278271f0322e54e72ba605b8a0919c5be2c55f45e8c6681629f145d7c279b6e89fa4e8cae602f9d9534f54e2055b025826b996a5b3c55b811c13481722f805eb8234b9c406927992ed82ecd844cb1278b2aba17a3b948b12f4515b793a55ba27e2f462fd849c74a4abd13982ed88ae04a46b5154f15de8a605aa0d8134017eec8265ea0dc49a2156c4b3321a7dc93a58aec89d12c52ec97a68aef64e82651df8bd117eea4b39250db09a40bb6457225536dc4a30ab722982e52ec0550857664891728ef25d1055bd2989029f764d345f662348928f6a5a9e2f732744bd4f6c4e8853be9594ba8770268055b915cc9a937e2a9822d114c8b14fb02a9c21d19e209947b49f4c22d6926244a7bb274917d719a448a3d6954f1bd0cdd656a7b315aa19d74d612ea7b0174c14624ae64ea8df874c1560453228abd40aaf0ae0cf102c59e24ba704b3a9312e59e0cadc85e9c2631e59e34556c4f866e99dabe38ad70278d3509f55e00d24a2ed8be4869db8b104f1d0f65f35eee3780eeae4a153cd4f79f22847e3ae442f05055d9511ca61a09cb361e1304e7c34c4546b265762f895eb825cd8444694fae4dc8dbe79c554d1be0b984ba403136159c360e8cccfb743ea92004ca6047c40c0d16ad68b88503282032840c5145dc6fc382e9d5b0b3f9d3b79d7cfd9f3c040aa2381fc18f57a381d47883e420642cd0c9b7ec80224194901f6945039fc609c84321041f41c7838473ee564816d90a948928f652aaf81e840f0cbe42727651a8d84f8b8a9178999b492fa74328d10fdf0e28301751c3b9a8eec9ffc704eb462ad641778196f72199ca5ec1812c54c2610cbe4553fac9e0cbfb901cbc54b5b3e49fb4066b10e73820fbe1870ad350d890ce5dd87d5cd630a5bb814a27ad9071384a4964bb6410a5f44375056b0b2c0650ee494b7b135422cc3475044d051441665d116eb22b4ae95d6331504a32bc595b13bbc17684a3949ce8a20c04acf02c7a3810a5bcd9a8b0c135425346292f4c14734495397e1062112ff336844e0b444626157a518ac9868206a5f4f9c70aa5140e216e794e49f462ab0dc8cd510849748f237a422909df8072ca7309e6a83cefd7d28571fca8da9ef43b7a99a20fd2ae0c82f441290f5fbfef4ce41019510aab2a1a4029833ed004a530f7513c0ea5f4a01a3929e8e45ad8c2ceb16952f20f2c87632c9fa78545f14a058b4caa1eda128c4ed7db8e1c99de4c908c7047a5c821a9904b0a9d4931950c7b12fa8344cc3d5de792fa2a28cf72032380b0fa76b21a26c618d7d1e7f76233874b69be048a7e205b9e8ae68ff98d00e8b976c18aca39715674ae451cd4dc278f255e7325325c5fa68572526627d35a75ec513640e0e915a32303a651eff7012cb08207721eec44736011acc809c7ebe575d2785bec69e72515404f7a2f2045da7928a94653faaf146f69003b21e7e9f958de9b7a1fa625f8c989e2cf5f4cbc90751c10b4384f26fc164628cfbe4125235fe8d7645067c264e323beb8064ba81b671b84f0a10eac4e82817a1bfc73526f40ed59ad6b1750447810d65bd0037e344421a3be49fa697484f1dbdf606642193f6ce0e07dc8a032810b2259c3bf4b441d47ff05bd907b108b286e1cde463accad82cde658222eed8b10f18d559b05dbf3e1450555c9056cf7c33a7528077311dda90a44b7d4a097f58087f77d2b2180ba82dee0020873a224ba21a746f9330554802588a3f841bcd9cdc5a9bfe13bf9ecea251a7d58fe3fdb7b48831ef2720f9b95b0075c94b8f41f1b39153ff8ca223984d3537be04c097e27a4c05c59bb16bc5a27222b45c6fa310687707827f2b36b87368c610726a905b67b9f2e88bcd9ca7496d78ff56e2b854d6398a568916dfdd70d2aae90f958f51590d9e8e0947f02df54cb5960da00bc3146ee70ee2e8a783640027c6d4396c4da2902a5982bfda171b600bbeb8e0670036279bc92f6c9c8282abe8af045a0e21b6081ed4e559899f311f94dc63f9fc09930ca2abf927f664938e50c94ff02193fa551420d41d40abc56c062ed9d0941c849e93d7c0c92df95d89f3adb5d96a4d87d1036b3c7f7c4689bab7b3e980e9557a0d5db44ec7c4be2f01922ecbaa4cd2ecbf0aaa52947ec81be27a2115e481ff9abf781bdf49026230886a604f6506b6c2c3332f709bb8bc1b16ffc430a4bf210d0abec009dd5aa2eee112383483e63b44f0b0940e0bb035f7b3e8f82325495c76f0ef477d308cf7e0c3fea72ad1f5684157fa0ec87dec0fdd44527b7a2e5bd3bdb1ad73fdd43c69fdc24413beee00429e77819b3678e7485e112e63c9e9c1e94ab7be2b5682bfca82397c01985c7a61fe49e6549527860ab7817b095e03d899b5a9670f8ee86cdb92e9c213038c460b4990a85eb2d3e1d273b29d550e536c2a82876b406ff8d816a9787807d1b16b8061de8c8d85d518b857d1b94f5cd17229660d3fffe572d4c384708c720339510228718a7255141ff0ccd45c05abf7d84b47d45c6737de26b567e0abbb56adc7827ec2a5e9016696aafce4d5744168e42c509fffcfb084f207923972d8b86022f2068195766c20222cf617d375af260f3edeb793729130e8ecbd3adfecd7d3f080270e87426eb80ec918d16a0c1de54f7a0b9fce8c9a7ab2f6ed2a035ccb6f382707e19fe4d397233ec086366e7c0f64e6bdb778071d085b29674720683429330fc5e7a81eb77fa0333881bb6bb2acd977f46e821931da30e9b642f435b0a155ec3d24f3c3247305c36db6ed5ae90a34333c82e21c7f1ad80eaf5f215ad9a96a236768eb0f154753a2497ebcb6078e14ce8feb90b9d4fb0da7543849e007bb197bb9a90bda4cb1cf11212caabd0382f0146af02a0589394e2e3a4b2485a45034607e98308f3906773151efad111dbb1437bfe247cfd659edb955fe0958c2e7b1bcea8f95613c92fe7223f8f608e4fa69fd768c6b3079e746fc5965958495e0b1f2202d256132d5640a49ba7f1d9a563514c15c8c02ffda354bf060dfbdf4a0d181a25e14c47664eee4568a56352007b6c0bafb7eb7941d957059101cf58cd20f23115dd1fa3e62d37fcb20b76b182dc448914798c54fd67f67509c5cdee6e6d09680d12bcfe1d746262e1265be9dc4552920b884723da4537dedc668ee445b5152f9b6cc7292072bbe6fdd8965b0ecaa03828fa9087dc69e2a79dff64e269896780bdb71f6b3d5bdd58e9e8c9803d8d63654f40d87c02deab5dabf432e17ac46a1c25f4c517daae8b81a81b4e590681180c8db9c7366e6d5c5946d0d01fa196e857e1203a86f2da0401b7c907a37ae17424dd3f05d8d356e9c5b75e07085b2599e3fe7f9dc00fcc2fb19d6d7c1ef2eeb96f50ea7f0c7703d8734921b60f3c4f89b953f814afa687f002ae5fa7227fd7552120df63330c66bf9ae852dbb307fa0bbeb3b266a4ba7d44739aa26d75eded566cdea454abad840e73cd8ef4783997c1cc2309863263fa04023018811bf0c1d134f7e0eb224db7fd17d100eb1db0fa8f33f0ac9c932d4b73c8793d9c53a5d7ce3a9064b1b7814b6306c3b89c40338016fbce91bcbf186f5feb70fe5fe46089e1e2116e24dd6c8a21448fad31ebb165586e8220347369b1ab3b74e9158a68108d0efa2735b93fc3de8dc031f359a5605d5c9d76a6e6ab1c8b26e53e4031053a4c8ab65c2098a7d26196cfba1466954580232a792d7579196e217c938536697293e5b26cfb057570849cb2f718ae025dc730ed978ef06ae44db476904f237ec5c620860ff3665518915132e710f52970516cffc1f1e6569afb7eaa274fc37c6f13f7624b8c469de6159273b61a1866869250fcf2e336ff277a4453c2aa309e969d17b88b51bc1d8f85e1e1cfdfc04238f3126457cc541935d8ff32e006a874ce2f437f2f1ad692b1b10b2147eec4b82a8391cb8c7acecd49d58fff246da6b1ba06d7acedd56f365ec3297f96b1a3c2b8021144ff2ba5a7b56f807295fe8ae37676f07a75dd6837a489e2d3be14d502607382060ce91b603ca7fd4bbaf1b18cb56f665c7792784b0767e08f30b4b663fdc610b02f7f505fdfd8ce7398eb49f8fbc0fd678b9909c66727081662dd51145acb763fde61fa710cb3e75d6284e342888c399e9c70d3b59e683582c3d1cbc67aabdfbd21a7c37ad9436d305ea38a6b70844b9567e0956fd65a864a166a0e01678fcecb74c9b75b4c8ac14567b166cd6ce94efe89b6dd18debaf73e570d46861f854fe161e7e2d7851b4a22de7738b0350d9fd3148ab518205b30be577815b5cb368df665b77d4a7816b5d0979f9d2894d3acb55e166361f6d7bc70319796cf8f776e6c9a95701ac8fb5ac892efb47947e4c6a2f27418bc9599337ae31a1622a7f08d1be1f9a77c96b55fb56b0dbc8336ae10638aee70831f120e4107324dfa0f6e3831dafaf32e1805ff8eab7118bdc4ae07a647e970b06f97f83f581c072988f24bdf57c3d5bf2accf742bdd7f40235fe0c9d2270f7b0ce51eab8a443515f0bb933d09ac26ac857a0043d7b7fc97a849b52c729c5e3dc450426305afcb6cff0b0520016b57e8fdc202bb14870d50b64f1803e4f106a384bb4b80fe630d22067f18db351840da16a7f8efbc7810cd62789f388b19fdb083f73b39037ebb7f45c49c3a592ba6beac017eb4b291323f3b22b5f77373c0a2e1b910a36d1cf504cdbd3e6bd704e37b93ce8a999078fcd3c90b499417ac01534340212d6a9433c3379dd934f0a363b4671549416d91aa88c953e840f763de42c269731fde6d33b025ac6cd20ac22d46b72329c815771605def684182609c8b02ace1bc17c462bc045b9610e80acd37c58e569edffb8f0aad1ad779c573e108f71f8dc8e5ce18f99da5ea60c1731ee3097346cbf5751002c12dc56dcce7211dc6757d0a02768ca66635d706a77644279c8adbf2edc869193d179ede4aa31a6e4666f1d1b06e0513bcadd3e4efb6f8b36739240ecaeb3ae132a8729e8f3fa39b6a7704d835883b1a92d7b95f0b72431e48056cc84b1d177d814331ec9e2ec24d109f2f149eabb46e8c437773971ae781ca34b21d1c0d651ff4d4a37a408f235e4360830aad5f84d2424108cef5c2f645e8345d00076244160ba84953010ac346df9c2a0576c240e672b0527d64bb79106d7b688aebbec7dd7653b20d8c158f6bde36fcce77720c5bbb72c0d3ed2b01d4ae8f589e82d8d63746add07afdbb161f7dee55a18e8bdebe64e02c3ff1feab3a82e507c17b5547c4d25ef771931416f71f23e2a78aa029197440b39769f216206ea861e3fdb5cb7e6be3bb896d66820e77da373835c02873a73d0f4cd50073af37ae0e496698107bbb9b4e84ef0ab155ac9e67540356853bcb61975b7dcf4773a7e19b2cf9434201b26b41ea0bf30485ed3c058bef82f1c1ab749aa82c546ce14b1ff74b74806de8f2618881f164ed3bbcb358fc2011568564cf726728b94f937c1978668f6c80a182b59e15796710a5063630fd37269fef609fdf72e78dfc9ec8919c92742fde366eb797b27c32205656931ac26a75a03389b35a4b6ced3ee1262bdb7a8689ef3eded0fa971d8caa421b673c913e4a607fbc08d6dfdf2615937869ff132273cb0beb622cd13360678b4c4ffe21fc4285c62f4628d64fa8a61f231008acf39cac53fee5096f980c98c3ec6474eeb1eb5ff85f475424a77c7392c2b74bd07119490e4a05d5b29d6712cc6a4a474c2de2f22dae90db4be802829ca13b7d10414f6d9e8bb8fd845a53cb821421aea32d073ade80ba11eae8ed7f54a3f5818e9680407fd0dd2f3b6a99d06fc657b00649d2c8cfb423c40a83bcc6f0249d1b8242ef5df632d5c70a994b790eb7a5c5de2be3cfc1e81acdf43b98138c025df4802b9167f3f821378816b82ec276d7a815f78f52b5c0603ca6bba9bb96cc94f731c3701204d07fdb1c7309f96d946d255816df4cbc5be67279163d5258881b746aee91e3546c40258d8da8ae3af88e60b8c1d9da24378482544621c3178015da828487be77ce5053480f01f057ce3fe4da3daeefb0776c2071a64c5cf9bbd035fed1dfa22c3702248f098605fa44d490b8d75f937d27cb67ec09179be0cbe8396b98b11ef7430df9d846b46f70fecbf7f7cf7dcdf154f85a0aca4b734379a17c2ea6b722b3fbef278464adaed697d59a1141e676fdcceac591b43bc32e57dc4b1366e2cedc599cc9ea3088a2eb6f197a94247cd29e3373d9ddfa3500e6ade6414fb4fcbf96081cc5aff4f7746bdb30a2028f3c27b66597fe47b30a90f805a86fb45755cf46518067e74647aac7922db740b3ebf555549ab64ec212896c78bbfc0e033ab12cc83f5b5d0d12abbec9591b4609d1fcc9c15ce91974f18b69edf3c39e81e12af656551acb82086062ce04d1cead4357f32e2e28d877f49096e225354a6846d210cf257b00d7b13f0a52d99af4d362e6c57d7958bbd06faace30870073ef54c127cda58d84fe283ab4907df49db4eed54d9ba59daf12e363b54e8baee6377515e17c316f3abc318e75d7fe5263673861f736f12efa90c571ebe20e9eadc0daa4b42a798241b880bb4caf765b5c2abb3224cbf05a906f358faff69b49a42d94f5d55afc746611e760a0d6dae13e486f54aeb6f55df6d30908e35b4027cca1cad853f12c1e3304c18da2e5a6cd964ed3ce7307e13b8c79963820096340675131ef2704c516e84e14b0b22be4222fe6acacde41ea536b344a50afe51a7cbdc976179ab84c7cfa80bb93b738a6812f0317d596073177e51e466ff0459c66a4bee900b764203d173c9a749d1eead74955b396428057cfd9cf1ba714628c4312b7eb786598b86dbd37c66799b051874e96c58f8479be09246cc5a6b69050378a18dad75950d174b9e8ab6966e2f453d24ccd2a2fe6e063408d5b1c7efd3228be18bc32d96ba5afa89b4bc7199ebbfe721c38885ea0601939bb2910b9ebd09494d203dd2c97a2e3943477d385a353b3460d10a88e777122e2383232adc77993584fa8253d7a5aeab4659d8665a18b8cbc1d3cdd0dacb24bf6e104c399ea11f0cead411f3a930bd240f95de6bba58cc402a71b098852a11c74d772abbdd2a39be03cd93fece377be55e011105de400f6c2b878b2d03d4e7e8363f0d278f59c48fa1411ddff5b7d1e6bf2b40e6d59991f174709790b27363f1f581e7d39d3c13b39c204e474abf0ab41f3aea72ca0db9df66ea714b425463ececa1c7d5025ce5738420434bd551996bbc4729cbe9d6827cc0bb68630edab465b63859b555b411e67f64059193ec14a2d5b3ad0097ee8ca72c878d57d82ef8d6655ae7ebe3f492ab9e9065d747314df9b69db5a9f7a7047a8fda52f025c860a1cc0c3766b6c2ced55083c5ffdba3e0b88d7c450b3d2631bc2a099e29fe7e856e82984084e86fcb70847ee69464a24659aba3f717584dbdf5db738c4312c090f3da2ef9dc7cd3eaf17a17913c9e916564a0160e6ae8c3d0e3aa17adc290cc569087da7d9f2bec45c36f3e0bc38b0716c7513483dc8dc0754b7ced0afde800f61cf0bffe03ed45d8a70ae57175cb38f4dca8c759b895c9d6cf9b8a0b844021c9198a42a379783347e13609c22f461b340412f916739735e04aeb6250df1896e267faf1d1efa6bdca4cc1a29ef04fdea56e1afad0d695215c8082aa69a731be4100b9af4b192dae4313781a66ce400c2b3951ee612b50e0557b996f984674f6e5bd62653da44e63b753bb8ba9609d16b02305b68adb41f7e6c2dce3134d4046806008c7c9bb05a03cd162c358baa7a1d178da680a09863d33856bc30b684ca8d2f15a01eca10a630ef9307fda7289332d5ae061521176c3a5dd727e9417654bc1605ccccc6e52b8ac2736662e0acbe4043f095c14d838bff683ae4c5751578e94457da431e4fd7c30e0e24acc06919fc3d93b50a84d3fed4c1407ae8029cffd605d55c1e7f9d96de84516e3d23adf3d79d1d36bd3694f28f374ebecf8a6b6d4d87a7f66e42bd2f60efcf4f775349d802e982b5bfd4c4564d181c537606b94a1a6f59183e56bcd6e1ece217174e1cfdb3d177659ea6082fe1415777ed54aecce113360fafaefc1ddd0005e5a1c50a399dc3d1a25535237a3834d998f9bdfca2aeff4af23f1cd3b27748d9e631a07f8aca6f530e8d9e3a977f6569651c46a2a75b78d9ae36398cb7d3d172ea23b0764978a8b07d1f483dd75070365de20821621704c0073f8021cd8dea08c1b985b008a0da1c2cf98fa9e198e3744428c4cf40e0e0243e03182128005a0c9f6eac8e7110e007b59ab81b83e4b26a8cb7e63ff8c695ed05ea3bc6a3d398534ef9cab986dbb878c0da7f2284083f2fa4a1662618996a856e2f0a056ff47323bca1fa5a316d9b4740e57420f651c8c2b9ffbc0431a7a13dfae2822550bdad1b717202fe06e202d5665f79dc6069c37614bd8d4a02e4f6dbe81088ad28a52fe7f9b22b3a58090f46bebe2409841803e9f3cad7fe16ef070509623521d055b20c33b506d30453c9bec9383fc411dafe9c1e8f3a9b58c88a6ee2e1a28ab0f8725a690c119296bd891b8f18d9166e2e655430acbd07a84d8c99e91bfe4c7ef54d35be11a07f959c92a01aab0a0c954ac311460ea41b72c1f74705c73954945c0b58e5259cbd8a6241bd79d47330e5ec4f92043700d0aa9290ad32959ee320c41e995c174774fc2a5b1dd44aec31502a6490f04d384adb32019b5c5835c9153f4515f529a2d6609b2485c9f0ca0d4caeaa8c6105923f82a32431ce7615f245daca24f54f734ed447d64f68ceb96a3864d4e5f98e0ac65734745e5782e620f896e1b0e488ca3fa7688aa21d8452d135cddc4d6e42d99b2e34f642f078c90c50afbd3982f1bb938fa778cc2e94b2d15718a91f4e92d28949ae0117ab9a0b7b4508a6aab9a18baf3c7041883ed208b15872a3ff2a0766df2a2a5535540b810589e7da3c316a861308b0bd5e17182cdce3bf1195905978ed3268fe94d2b02e78846b17439f5a1b1e35ef5a842b4699eeddfd8c5b7147b14d4f05d1f7d0662ab7c86366575e6721245d3281ac5df875284cbb50fa973b35238e21c00b129ea332bed49d1de8545be2b484e3c0b457e5800f86789c6c3b97235320cfc25d1f50d994a782fcf2368d3662b4a301f40bb5501565b943127dea31778a98618cf2ce4ebcaadd03cd05f8cc94d412d4aa7b915437b0a9c168a53a3220923ae3b107664e165baa9e4bcdde838a2df39674c1e769e4383d2df0fdc229d44116ac8cd20d54c1f21ec19869336570c3973e53cf5df5305af112081a682364a26491521063ea1ed0c7cc8cfea82afbb587aa5eb262d9afdff3c4591617e6eb3ccd70760a8bb3d3b8302b1c6fcc83b59e683f8e0b9b4d89d1d74628318a28c5c795819a8fcb5d918b39858f1e90524752a4e8df90503f6a4ab26def1e02042db4a498280c092e42c8be47802200fa193bc26c005ee0537720ac66f579aa509f8fb8e6d714c0bb13c2abf7ed7d1cd295fa1ec849e46c4c8c2f222e8a1038416bb428f1d4d113e577f9579288a53f16f56de07313f1c389a18d4670b91101f48f044159533fc1beeec4ba6b7a5a1a4f3a8313e8b678811486dcba62b3e5a7c825635d9cdb10320028b397708f083fb4503f5b044144b8913b66f5c979745c5e090ab943643860a22628bc9e780801cab7614e2260811eec1fa940571e9f2a43bafaff264507a9e837f1514a99fd07453cecfbe53e9e93a5f9ca57f53e19c3dd1ad5c27b2aaec5f32f1a5a02a3def897a25eaff0307e96fdcf94e27584a95c7bc3c276d26951d1e3d901550b173b46b62c68c8e6dc6d8237332cc6000cc5080c17c147873f9383edbc234816c10bf82b7c4fe09da4b5eaec1e7673b2268c634f80f45eb0129d055e81c321175b4875468d3f512dbdaa3745f4f89cafdadd16c403801638bbcca6ebfbef961e88a6c16e3ba2d8f3c0e4929b8742740e782003ff7148950e17057101ba42b23b5df430a955474dc636fb1a3934aad26b252306001ced50271cd7707f592136310eccad4c8de0db2d650099a56540f923e8c9585a397b67f3a556584eae9caea02fa46e124f31fe721c994bb5230f5b673607f53e67a2074a6f8b152d349520a27dd95f76a85b619dbead014953e4c04a07735d34f3a38674427e050ccd0e30fa82d950b601201d728afc72b4da76ae14d1ec25d759264e39da1461cd3d7f516a6530e2c9763f905d99fcc4a19d6ffb1dbe78ad5e72da15012fb3553348d6adfe992c9350a38592b96d942f994d9ae8b41a7a8ca083a830111104b147d9f867843b56feadf4164d1f03d5b24960179c4ce06efda17278e512bc5420d4850b863c4068c305b88cd7d5600de0c03ec437db37094e581dc1a1e70bf6a5d2dc50f5ddca451991efd183d2066923c0e7a5a45a8e173a0eec31ef9079d1d28eddc2ab87bf19a5f4fb671fd5b543580fbf786d3d8487275424783ddc86931f7854f350589770e840f6e39a575e9046d7216f202abc0daf64fbea7b524813468af1339bfe7891b4ce5fa13fe8a465b7c491474310610050dcfb6139d089912e31e188efc225b8a99243c77204ae947ff2218fa32a7bcd640eabac0f77f66bd4e061de38ed0a4eec46a0d187dff904bcbe8c16be2ede5979beb2f9a01bef7b191ab4a12eb60b39909fbdf3dbc32b800957bcdae58234bc264ee6a7b96834932dd67707cf5526e6feaa199d166ea306434f43306db5805d24d7fbcf240210051dbc78eaefa1fb71c11691d9a904dee71abd5ee06d117385f2b478cd05a1da4488364f95d6f92601aa9af512bca807b22110e4fb98bf16e96ac8047a72dc17a5992d92cfc4faefc700dffceb03f8e7a715305337e6c2745eb166fa13c56921888ff23385d93b6f4aecc7137913b1318b6ab6807cc8e88ed5a61c457df1615d043dc0eab236a18752776da0804b7385ae016e0797fab6739f69bf3c69a807f83b645bdd0b560b0bbcf3923bbe52e2160ae7fe37acfce286e6950a4ffa07ae3ea0c3886c741bca74009cd78152d14d04bef51b72a93af116e1f538810b984a20a0a9f76cabd06e232661ad04d7f801ab9423d69f50a439b4ed687cd05d6d01845ff10a74cf815d323573042f76cf713f60339983aad2e942f6262886855fc63ded31c91ea981c8028d805cd84a61ff14ca4120706fbdde3d076cfc4fce3b55a3bf49faf16874f66b9baca308286a1df0158d472633c8929add2a52c5c4afd41e5a1f73f49cbc70538d80cef957e8e775805489dff8059e0fe838a3a73ed60838794be4ff7b07c7bd515309932214e13b1958f55d26fbeea1d602ea7794e0c71a232248c88a3f1920afa86c90aeade22760309ed5aa330e96048e83c595b0eb482fd41f74bac698f1e809378580560090705f129989bb8fe81ed8c5634a9f78e6135533d066133d2ffffc3a623b223d723de9e8f8075ad85a9be81aaa30da8a60bac548efd66dd8980410476a1020c9444f7357034e65a2f65a21a13bd681dbae456a5e93fd60e1fd5d05033f20f70f6acaf448e3b07aa3c6f3401fa0ab6eb92837c958f1e79aff0182599f962df17d93a85a1a2b722b1ca6a157655f5a5cc7e40b7dc96c00637e3eaef6d932cb40c747505cc9b9b02b4e3098a7c68053366b0f7ab87423a1594a099fca9255cd95e456fcb03b06af4df06b7ab5cb8439eee111f7f9993cc90931d1039af9e3bfdcb943bbfc125ac4d24cdbcc03cbf3fb10c036733caab550fa13280136b7d3b688a3a972187c5ac80acf69b0edc600849e160d220eed917b99c42737c234975677be8bd5f4b8d4bbf8c4f4f0a8a6f7236c37b330bd8bd20ee93afdd0b98fed9425341b7beae423e3776d94c1ceae2908af60a6bf7a0c4eb47eb976aec3d98e7b6ca7d0d1b76b160ffa4fca42ce96742f06f6c5af04f856fecdd5ab7afee3d06f8e9756a54337a62ec02aa68b403dc10884e3b7c191a89951a4ba1fd01424993557062f7c70b7b51675828d644cdff79b822efc2185c2be6917d289368b04d9d300b6ba06e0e15fd715dc87a9d05736085e9a97ac8ca5e55b04cf74c35649a526617faee01c8dd27dbc497fc7196ddee25ab0b1fc8f3fbcccfe791d09ff4a9ebb89eb82144aaaf2b7d48a16ee44e31beb1b07537a8bbbc40556add6f5b4baa191ee62589f56699ab097f9a79b6c27c877f7b70414d312c423219933a6a42dc3ae7c0211f45e25ed955759754638f3f716364a5b27b2f51c519c40253569a69139aa731f96b729b15d7b509dbe6b0ee42badacb52bc7ae1571d1037359ded2839fa5628c514110b084b301dce26b4bb1733adb957773d6f1a7e544966988cd576127ab93660f1d87540568e8e64b5325e9073ea610aff19e1ae3c1eac6b0f3644aa14ce3a961e460ec48f517e2e7eb20bb9d8e043ba3dd00f7781ba4713c5a6cdb874ffabb05aa5b954fb1c5ca077007bd11486a7dd54a7a3bdf0e458b9f1fc015fc563099bbd40e050bc901d004d6cc02c8dcc5f6285a540e016e56b98fa23ff60eb51ec199b1d57a73b22e580f604b18190950b6ebdba170717a1e300de672d7f2da8dd542db4f627276695d6cd90bf303a0d584be93bb41620d095108b61c2ab4d49527b82d872bdaa5a038683850465e01ef05316f5c45f8498e03ea6bffd845e503ec952fd82515940bb0837861975a4c5f40a5f07bbb6e3bb92e6a3a0b0e27f40d268d0ca8d575245bcb12a29404ba60e86663fbd99b5c5accfacca02bb538080ee314b55c4cf2594a4b895983a6496caaada31ca2e37becd7c24351c2c403a704e1a68758a971f2111228c7f4f3ff1314584ccbbec3f1d0d8b4e7b402508ef30f3a3ad63b5f38efe80c23cc50db6fe09e596617309dedddc09aa7d0cf564a77ae18244fcf0a6ddf283beddb856291221108b057089c1c42cacf3a2bfd5078d81add5c3b4f47e5b44139e7081a15309f5f93c2b252f3ebd3eb9c23a0080d47d72db6cdc7292645b2786d64b2b86afeec30d31055cc4952754366d7730128d3232a0e8e3df29bb50e560835964a12fdfea65ccc4dfbbbb827a91e4a8cdca2bdc049af47592253d2982576f43e6059c5f6945a67db15ef923538d20ef106a1a363793e7e9658351b6abdb47a4d7bc149e1c2df2c8d3b3419eb6b06d1a027d09cc47f4c8887478d0440cf3cad46e083c24c087bf069c08f342d41906d58c16760522931db3ad6ca94ee9dab92ded1796bab1427219e455d3919c9d8f790f6f71c9e7b5f42ec4d1776d071fada167ea23fedcfaca0e3f772d3bd8af38b6d0d03c4903fbc9b1b8e29b5ad28694e3b2eec75cfe88f2c594261ecdab9ee9b5e47b080b9227c9ab572e46c241ad8ca310fd69101421204647784301cfc9ec13aafde221134625b0edbcecd986fed91fd0e1e163b400d21f06dc0faa055e0a1535a1e0efd98a982bc2dc8811b69613733e93aac8daa5109620c797ff794b5eb822e7ca2f01e6f2d6e86cbbea296b3dcf8e610844b5a80966f28bd87967725e66e9ea2e47c514bb9eafb5ea5f947d0595f98a78c7976abdc5025b7374803dca598420e7ab68bad74155f945849e96f0c9f866aec9365d20a079c9c2aab2c6f3236bab674e7e54a3a651fc27c7389a726306c523fd699fb1a59d67068b4f0a1d5b65b8bcd99ea4a976bbc2d06d501eb89c445614ee5fa84d66138115db0976a6a97d15f7c364c73b11abf0131cd09af62ea099cbaf50fda60b87c633f9f91c85a1816e285e2422513a5f9d5b22331bc82fb56eb22ebc9af1605c8206b28c260bc5a2c598051c7ead9bc5970ade41e716eef185228b273dd51df16b2b4c64ec823e66fe170e021bb79d0c6305a6ec418c6c31b9b8d299afe98784e6a0f15a933f34ba1e1124c61a615257cf52325dc695871bd1d71277e73e1d9b365c945c0d60ea1a20c450afc0ee8400b2e87abfa1c0f41a3510fb73769d9c1e1796a26cea174081a1698924c761da1e15949a6b27454be917e4867d2ce7f9c3733830617b484fb7d895a3e068c1196695c17e50cdd0c510ed9a6342a61282fb4b4280fb265005a48703a135037c5af89fc2d014b570b61f5b1a87a71f2f73cf75597546fa144bd566704b7542ee001a9386c9c013da8d67092ed61a5b06cb4a865b85fd9286202181a8dd2c643b7c5d758a615de8fec451583bb9058aff86d92920f5d59a998dfd34823383a0e9800cd92b3690573d4120885e5f588e7f743734b4e0d29f60ecbb5992198258b9d3772ef216067cf573d3178beed7a74aacb1f141bfe00186e1791d446082a0bfd8f940f1f0d4f33f2609477e2032e11bcec945244cc5ede4090a17768f7f8327bf45bdf016164f846ee05c17c3796bea5a2ff45d88fcd9592d4d4a8e645aeef70e4e22fcc21d90a2b1eb344aa613ced9f532fcda9bd4e0354834c6ddddfa56084b156248bad0ac2e012555c463742bc82ddbe2e08ec0b9984672b51eeb2e6ad20eea61824289086673422832b4b1cfc0d7722c2490f19d6d93aea01924aa141d1e148522e07aab975ec540049524be56a2ce241ad3446108e1b336becf4c169838ec30863d90e8e8ec76ed818c2212f01a0884ce5322679db35d85a7f75bfb423dded6d23ba2becc5b842e2fcaeff66bd8ac2506c36fa95c020e79d16d5b190d6a69c9545355b34b7fd8810728f3d24102922d9433a83c055df4e8a9aef1453b7112a96d2c3824bc594770c40383d76d28312e8bcc1131745913a31e5d476abeb6c28064c838313f859c34277aa9e093cf534725d6ed6b6db5b9020e51502b460b471f5b2122ce2c2bc980246036561a6a75900a8197ad0125d9a494e146a580b60f64f5e4818b023fb119a5d77dc5efdb7ff87117069c3fe11138ce7e2976dcaadeea8df0f3d370685dfbf2037c2ac323516502e61f72923c7a7d7f3be200eb62bbcd64a5e60eb8e7c187d8024d7e027c24730b3ef4a64eadb09c3f52e0d2fe17fef2f0d213a62055af037ebb2d2b4c2396990cc9f3e61ddf5a97bba6ccdc682c29ec17d481d49e39f9a1348f2b47e9b6cac885b3b2ed5b4b428962490612298f7001a60b3e8924bb8cc41fb3d7b3083c1e8cc670490d6ff955700cda360647c5175e1d2db9d979107a3388487fc37ff31a709f434792e3148bce6dc207c52809e590e061ba41ac6217f8f0ba9184ccbf7136b0b9cf04b6f2743ac4efad11306adf914c6575d1397b53f77c4e8c549ce492f3ae6530ba4e04bd20eb4326f6a01fd0c192db110a256db51d264ad9640f376dc69650c4b7811eef8f6b1b6b0b5712e4a51837cae771599d58a7bba0aac6a9aa9249f501faa1ecc7650586cd771f9756108a3bbec81d9e6ce2c1f03da360e735a300e3b4a0703750a22239ac4fa911476dab487af0e0b6691c73cd9e02458ec75e7055a30944d1fdd1457a9061a15cab000c86aa03b1a80399338a05928ebdaadf54f21f4daeb0d31ecd5dcb08869da4a42f6de7b4b29a59449a61907e1064707f177fce7875173da6fca27f35edbf46ff538788223c501cf9fee8a3d7acee9df4e91b86f6614f91377b99478958c8ca451cc5b3e04837174db382de3baa9695b76bb9384c160b0680483c16030180c0683c1603058348a303030180c068bc1603018110c0683c160b09899335ff8130f4253060683c16030180c56e4b5bce5239231137de4f7ed25df89464611c977a2d28a49a65e6e914a25f09c3153c21831b78587522ef79a1aafb22ea5359e656d1b47b78dd332ae9b9ab665b73bc92cd3ae3d59947d899d87fb8e475d700d8f007d43df86473f1ee984408009e4aca39f68e3d06f56cd345a2a0254dd6e17c4b30727b85f37cebd4ef84d529823cff283117c992413938d2f1e75a9e1ede89bed6bbc0d7f98daaef6f1887bfca13eee4fdf56816e70d3be70e6ed48be1f3fcbd77eb70b76079d4862c24c6a0b16348e3ffd3870126f3c727f99a47b50ceb6502e0024bcdc4023c3c2062e5b94b82229880a214c6784f9228631d0cc30460a1d4383b7316972a9124555507964a30a164e7839722599018829c0882186c885316480e56a09c036f4822c525046972698d0028a8ec10c76b86225091133a4913402ec82a0014821a6a851468585142cc8969e6001031130207d890196b0480a163154c0822fbe187344b6021b394589a62a7789314653cab0a43ee9b6173e29aa502970b0d24af693fa541aa4d48da62ac64b02c6249991a58a1746a0826bc3141c7e08b28204144e1cdba0b5a39d2a2ad23471ba01890c863445d82dd270c921ae45f8e61633c592ee0731697c48f10053365807bedeeab617eacc61cb90c3660a9247398c4a4425d412398c216e6549a24c50104ac2c860054a4ba8882282921841819430c6c00086284aac2f86a244e1c2a1290c56d8b1a1e83a428c2f4e20e9a0c58a195618b3dc0044165cb63c21040fac3086f12822c5589a24565a49c324fbff98f08aa59921fbc7571a2bd9ffb6700a9fc9219841e1a630556963808618331a172f361c062b9e550ee72b3133a0dbad74ca9c158f0fce864ba388bc857e871c9e9a165b67fea059ab54b07da985f3b50f28377650eed8f84dd73de487146573d38ffb2ab0fd40cc29cc0f6318330af4b58e3d3899c3995bd3be9b7df6a1905da0fcdddbd3856d3e2e07156cbff935e77f82f61dc9246fe4cf56cb558786865c43ae21d7906bc8d53d3c535c4e1cb95e4abc5c45595c4453fc4a963664e9724d4972a5ba43e54efde694cf956558895c6670286332d63d63441f6926f638e33aa15cca32d63283c3e9724d99e2a09c442e195c75cb7dd2f2767139b03d193c73d7d7deeb6b4f42b5afa986e08febdaf549d0beda6fe1defa5615ed93a0bdb5df8246826d21b3dfb3709ef55ec980267088b3c437bc4f06b72725614368a4d56a65165299a6a6077ec4c699ef4f3f6f9c39bfd9d19b0249af513629570012b3098d237fd20f9a70386180fd6555aa4aafaaf4aa4a4a54f07c4d25bef96a07630ec4df4c960e73505ea4a9345ff328caee699984caa7b40b12b333358e9c5ffa46fa5795aa52a522fa4ca34ac6752491cf1738fa781c7250aa8a5016fd96f368bef0cbdd46a95163e3818a64dfbdfd0ebf8defc81120568d1a201b3650df11d41fd91e6803aa9e09d9fb3b5b0422f6b07f84dfc46a1bc77e2873ffb559f7b05f4f9b8f11bef2c6febdd6dab8258b5b1ac7c88b5d80883e914bf7b06f85681cfb6eadb56f3f2ae1a01502873c72563ce250f7f460c2dbe7f18fad14138ec16cb5f67a219010cfb3b3bcf7de304699376bff6fb6af1272558d53047efbf6e32b1ec52df6a391448ac90f6de4fbfdb57bdce3b297d917ded0e1a0ac1fbbd838219883480f92659f5d903b71348efc156293cdfe5bf5d8b55659ebd44efea9c691ff44d873bc5e8d3d24f5b04de34c1f41e0d494456cbd23a41f34e19f453194dcc18fb79ce41c9a44b1bc85c3dc8c17dd8b712af560c833ed536f1ecd20279f2e706ce5904ec9924e9930b9335f7e23ff5e8c53a9396159fecb870af622bfe23a354b1f2e30fdda01b1612b594fd5398c197b2a7ffc2afbdc372bf354fed96719c6dce36f8155e3a9fc6b7cf7271b8ffa54b6e6374fe56fe3b3f1364fc2f6a8ed6db64fe52d6c6fe353f977ddfb16a322cf22956abc08f32293bc913fbde889e01eca6bf91d96379e82000993957d479064dffd823d8be748819b03aa9ebde0b6a79f416326f688612452421107a3b32470048eb1ec5470cc0f2061b2eef58771c1d28cdcc241ff9c2d64cc9b408ae12497401aca386e6b80eb441d7f32700f4591524a29bdf46b943fa7742b5bf73b5177bf1b75bf1f75f73bcc63dd43ddfd328b51b7925c92b07ec9d44344598cfae7ab7f1e7577ff8c757713157577f7d3a356eaa7b07eca344494c5a8bf1ec99dcbeafeaad4dddddd6f89b274f7dba3eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeefecec864b4da696f0a3cd9c6c1219c4c3959cee305f49b6893cae1f15123b798346058cab8d09083880d8428c3460e292d663097a6a636014263fca0f309a12912fb6f3125db172831c7d57dcd09e20721288c3ce79c738681431d3272d973689377f0c8ee4a82c8fe38287b52100992849424116385c3272579cd4b2400a433f2fc39ff4691e7e3241762797e171dff449e3f5d0727cf5b0254d4496ab990fd75ad58f950fc1c7dbadc8b533e94a3e4b13efdab1f10563c5f624ee455a20d7e339fe815638a19213a138bc5bc4af7d4eaa134a5a125174ac66a75291f9011739de12e27b231d648b1f8e4d2d793ece8e56054625322bb9e4a48967dd9561489b25c0f679ecd0b2329bd8e62b1582c4684098db70090044714ea6bf1f58abd62afd8eb7526a52315f3a018139a1af31653f4c9d0c47832986beac1574c75b34814331289885e44af48f48a44b1d5992cd6f2a118532c07148cfad3fbc734a6d8993462f5cccd2276021cc61893dc89482e25bb993723538c21208b180092e0b03e7ddb0da94fbfad035285d4e73e435d4dfbadeb6a473ff350a85986f163a19a7aa241fcef9fa069b57adb6b5ee74bbd1452998b592baa2f8f2faee8e5e08c4c5f8c3938115006d393cc3ef321fa286fc56a7ccde3b7f15ab4a03ed4dbf88ea04edfe779fab05f353e157dfc40ac9a4f455bde14391d3949faa984cc9cfdccf13b538f250346f2964bf127de923f639aef685d192d57b9fb5bb4f1de7bef8df2defbf77ebdf7defff1b8e5de97392bd7d9fe3e0fd7c9fe7eeca17be8df8f43291df2c555f2bd3732e1a9b7de7aebb5d75e7bedb6b9bdf7defb4d944dd9fd68aff3a6697fb5ab5d6dd3ac66ade6b9bcda4bedded7fd78743f6eb91f8dba186d61023bd2195bac7b3a40ffbecc5e7ef2c775e8cb2ce74b23b33efde982449d5affc789348eec1e31ba87fe86f2288b7aa8b824b51562538e5bf5807484a40f1a665ec36124c6a24f0e17a49459525bde086cebc3051cae16905543b2a79f3dfdee3cb3143978c50b0e6351f7f3e315dfc1c19a4f5f2584fe7daa1272738723ff786cf94e9be185e889313f3cd10516acf94696b2ec9f4a21c96fdd2124f9218fdfc88f3d2c9551a01c733cc11105fa9d0f0c30d294458d335ffb7ec76b52dbf2f562d57ecb38942759d43be5019cc14b33f3e90287b1a8355f95cdbf17e354aadf48e3cc88c493a7f58948d806092fc190947ea447b38e2af89ac9dc77aaa8d438f36dbeb97a2aa01c93d0605a91941cac1e50ce3c9973e80c81e90423cb2e1a43e2d74f25a48633d707ca99e779dbb81c4f70e801a0dcbd11073b07d021f4ebb77540a89011baaf5f6cd53cb78f9d03bad367decc9bece8fff8b6753784a240bfc69c65dfdaa71aa2fdfd205af68574e33ef3b80fe29ffdd6791a05f2237f9c7adb7761535353ae1e0b92fb62cb33e2e0a4722716796c153938a31252511977e3328fcbd7eb4cbbd98d10bf1ba10b58ceee773724fb544372f68532842e987e7ff16228ff789548d7e30185fa5a5a6e5565df2974193570d1caf4b509aa8464fadd8f1f9522124895aa67bffb41a423188d23df7a610736b472fd22192407a9fc89f465642c9ec9618cc598112a32c82d8cb020e7cb6dc86187d302e5693fa21970ccd489ec349a477cb38b83fe3952e0facd2ed9ff86f7841c762acb9f5e08345f25402aa19e61bf02fd659f99107d68f63a9b80810cb80e51f7684f3fda70c57538fcf48dc89dd3530d9ef2c42af4e9873cddc393698b526a85e3e1b898398de329f2ea31f2c6a5546f84fa2174c15af578a8a9f94e9037b40479435f8428d8c6d7780dfec66b2962f335aa07d4bc065fa4e635a8f98ad4fc8def48cd07ca1bfa36df45e1ff54b5c6035035df112db57e45f0d76c1815232c842e58fb54952503be9fbb628ff8f6d380ae673d64f43fd06f6816aff54103cfbf8ffa90c756554264068032cdb47a9dc1ee59459f99e97b107deed3cfa1ef837e03baa77bfa20b8cef6f445709dece913719dd3d32fe23bf47fb4cf8ed843524a1fe58571c9f3bc259db64d92d9923aa5bbb423962315438980d13ded8d607ffe66adf6dd0d89d97ea1f6dc6b43b6ef3a6bb010bae0ecb9df361e30fe5a5aac6a7b95fdce99a77913a708bcfa40048481ef17cdc41ef4ad67c2d20ebab965da5abeccfe7ec84376dd5f4bfd719baaaec37e36fef7bb9bc0fd5a5a6afd544372fdc2a7dffb195b7f088166b580e4befd90876b3f245ae26b41218514e217df9f7e1b909f09ee853004f60f3f84213065c980dd12c1add68fbc9937f3458882b7d7a2a5e5cd57c4fe36eb17ae72b3eccff9a968f600fbf78b58fa473efa15a93f3e3f147ac95d5ab1cd39e7bcf6da1d7baf753cfdab71ce39a79473529f75da285d449a447ee44d7f0761cc3f5d072affbc95b51ce577906302321199e36f118d7fa60212b319b93f66cf48e3f4cfef2965990806144b1129928966363aa57bf005ebcc69644e000c8163ec39e7cf9c521aa79f014ce0e801181cdf832f38541211c1c1222ea47bf86f416648e3b8fc4000e1e81edda30bc2d1d1516fd13a51440615bdc411497cc1a4082c4c88c40451022523965c6982e20c95d399117070c524038d7b46498d7e017765cb17a41ca800d343bbc088305c78085346931690e1c55d828c30b8b92445776c5dc33a36e4aae245caff7f4c28d32ac2b993aa4891b3dc4955c2a490b8a3546a721cb6497d816263b0582cc624535c52952e502a67c3619b318cc6788d7194a2e224a50a968d04b823ead0c03587dc11beb993aab8322d836d0eb91d3698e3381b1d4c1c1af7de21284a4c2e206596602e206030397a0114335b5cb004480c8ac2bc00c40cec6f874477c50e31e470753a03a3728bd9218995810e619cbc602db7181db868a2c3145ae82026cd11ea074c738bd121092c68e6191b9dff71eb6aabd0d6aef3390c418ef1025b778faddd54565aa994eeeeeeeeb1dd5bba26c5ca49279db7df7ad56bec52fe3ffd6f1cffcdfe77cf3be83777f7e31b27feeb76d9da75c22f68320b1e806db3f50540a7f4eeeeeeeebe64ae95d4bd1b4bffd892bacb69c4b55dbd0667762d077952a0333baf990ec8c0fd5cee24223468aa26559392a26b72eaa146181b61700e83189ba915b7c46dd391b7cc236f3979dba86091b79fdbdf1984c8dbe39450de687841de1edc7e45256fcfe33a9d44d445eb48245a59a3d9cf2c9b9246cea61891b3bfdd8f8cb27ae72259fb788a241988521aab66522a85884cb748d5583a8ac2c16babe1df887b751081c39bb92c0a9927925c3d648f6149767f8c997882bbf872f8664713305c116508062a17cf23b68e91739df8a984c8e8ef23074c595d460b29563086e8253dcf646cd2533adcfb534da0f666f67f10a7e4e72307acb12200c6044e80e082b3d4cbf707fdb17fcab582cdfe67f93922fd83363aa6e0ed6dfe11c2fe3636dd5383bae74ec861fda617daa72c2e88fd2cf35248a9ee7b2a5a77a454b7c70c187c2ff0af781e9c475b3f4f37189aeb77f7169770fd885042065ca7939c2079129414e49043820244eea5a4274cd993a05cc9fed9630c12a2dff246a8fe4f773c0ebef0e1bff5e1a0fd7e78724cc13c5b2895cd5ffee62b22124c96f4959678564beac70f7b64f93dbaa78ea012d23f9168e5fec0bafa0161c5137fe483207f259f27256fe453cf710e19e028e598cd578899872125b189a5a53fd56ab55add101fdf17b6901dcb08819c86117dd3b9fb66c280fb95baa85eec15ce878c064dca9684932372b8ea016fb9939c70b162308edc494e883431706de254029c156186154cd78b9328659cb8c04941c64d8251b9939a6ca191814fb9939a8ce1488037c89dd444055a13f846eea4263e6c5170963ba9890e1725868b43e2758231d9aee8ae60a21dc99bfe71ef936c69cbd6e48226d70a97d614e605204b4d4938b122d6e4050a902b8c80506aca1204e4054c4d454340aa689aa10910325b9a9e34016285910657761003e3c82d068b163d608962082c5f68195850a02dd9a104302c24c84e8035c82d068bcb0a2c4db27cd1496e6e54abbe333d87c706d8d6be6163539f4ae98837727ccfe1b181cda986bafda752a914c6a7d50a04ff31ee243737aad5ccde54ea1f0457abaad1cd951cc927f7d1cb474702786c4df7c3561f3e742821f9f070ffab95ec7cb50241147703d0967af4915fa9ed5a6dba1fb6daa8d5524bdb0310bf868c87a3e6d6601c5ebc8d636d56272771cdde75da7957d7f35ce7e79873da74aed6bbb166af94fa1881a983ab30386f5ee36de49c934a29e594737aa4148c4e8ecfb3da5aca39e79c724ae971ce1c1540010514504001858d44f9a4d5ab539f7eeab84d6a32bbd2d6a60c6082c7a7948e316a4eff54969183273ed23df6909d6389255a5383ab6163b361a3a16c6e6447474da6937e7cfccc89654abe04895c7973f4f3ea23950eff51f225551ad1e5a4d5de4cdbb8ee8442459f13adf3714d476b6a70b7868dcd868d66732343ddb8f7ca0deabd130787a3fb411f471724e6f93966c8b3a2bf41eebfd13ed386014f3898adfced57a3e21c58a5d2e1353a00802ff62bebcfe88303e0d1673ebef75ee7a0498de7f0dee823710d3eddbfddb3419aadcabca168bf679a69ccaa0924c6ecf9b78a31d2b06d1eb0405eebe31e638f4aa774777777af7572f004872c0c02788de3707f2a51940328f40630fbbc98b47a0004388fcc7ae791691d89df9a516d6e721e991cc79d84901c3051824f69b6de1125b5186c106cd08320707c692f1501bd36cfe813bb876c416655a3dbe4a4e6799e73e6ade3baee87f65d1724ce150fd7d17e3ad85a067e06dd87013e100cc110ec9d99e7073a8aebcf269216b32f3e66f898216366605bd8569a7269cef7187bbc808629df149ed38384b0983ff840a2664c97d4c44add9a5c77777711a400ca0b430441c60a90605f58d1831098325678c10a636c076b91b7df7eeb7e6cddc7f918c2f1b7f7000b8c63cc6858114d668560deb6edcb9628797b114c903bfddafe04b9f3dbabe03a336fbfe2b9adedb10b600cd1448bb56dac2d3369dfa14dd65e1093356dc887ac317121956702ee0b4c929674c11dd8d0caf669f7233794a4f1c58b0f3efca0c11133c04910f1c30f5bb62843e3d00f25fd18ba07fd7e9ff4145d714af774761dfb4a2961a47c449f6680d2cf9ec4a024e91989adefb6cf9e05fa978b560e2f17adcc15a980fd54f75b85fb81998e7e9a6793791853da501cb143932a4c80254b162c202e626071c28b184af0c40e2cfad1453f1245171238ccf16ec621079f04b500d39cbea17f2fa63999da49e4cac9f4a717a73021a2365a39846586faee48f88f2e1989e487d1f54060cd25b38b1382fb13eab9c7df3951c284c32826a72e6c58be91e9736558390201310d9a6840bf55b2fbfe4b4425bfc6d7bc4a7e0f70d6e9f1a39ecb3060f94d34e7778283f473bee0f6b0e7ea9ef9f4636830454d6f6d1cfa3cf4e98a3e0f9d4ef00929a8e03af1e977de09dc7c82e70fe08c06fe84ee5140a69f42f778a65706328d4cbf3095a3505e9a668050809316000144163edcc8612cea9e1b4cbcf8e0036c73975ce8639503f2f81d291dd84616f98dfc5ee5803c7e870e1e1b971a64f9f14af7cceef1971f99e81d1564c4d23ba9a628ae163c44471494d0381280356529a59c5170131fd2c70fdd223f1ac98f45f26316f9def9ffe41081c35824efc55266294a5d6192e50a75a75e02feee48b8657078ab379fe0f8612cbaff03d672884728924ce03062b1a142ed0b6f77dfd9b80ef79ded77a74e9f92d38956ee5b21fb703bfd7d7a3abd1010ebf409e1efbe6f85eceb7450856cbfe601f518f53139755dd7755dd775a7d3e9743a9d4e8fe4d4755dd7755d477f76a7d3e9743a9dbaaeeba8e6b54c8c915a0760778ff187749734ce68e395dd0ff9dc8f23d9c6415fc0110e71fef8f958f174ca07181c3d52ba43c7ec298123b07d95cc7e7a61cc31b3d98a8bf4558f69a5f4db2817638c600a3cf28de13837d002ef70d0a3bb0eefa6d8b0dc995fa842f68f9ef633ab94524a29a5da977ddb17aa80c272a7524a29a5945a6badb5d6d24fa8fb263472859ac9062c2124d45a6be79cbf8487355fe888fc94bce9afb5d65a6b9d9fd0fc5a6ba594fe121e16fd84687f107f1e6904740721500ee3bbffd7dd41644daf599e91b45296348492b670411a2dac235afcb1bce9078a48ae6b556cf325f5c2ec0791233964616614b4efad39e7fe08108bbb0ed20f051666d6be15ee87fd1f90998710706fb94f09508ba5e4089226155c11461968a4d1c4e25e0888c57d42dd6fdfb7c27d6abd50855c3feaf1c07de72189ad57916b2828890b2c25ddc41ac2c1e23e26dc0b211102626dcff1b0b847c26ddb965a817c2c778490e0a8808b1e9008238a1d9458db07010d0505050df1b0b81f0259dc070d5d16f7d488a34133b458dc8704880729929cf183151f5c68012be8269125cd155650d092cb5282626ab5522c25164dd01290a544a669b1b617da910315510c697912831896161b4fb258c192952f5d28c1925782c204ede0041a2d90589286148881218b22a660c292df5fad6843493980d9bcc0a7227ec8c18721b0963b298722ad8c1c88aec0457270dd6b6b6042a88c17115298946a28a2a18c560d444365c06a187231b9b431560a6c43664c980c891d90e882d8a14b97446bda81042498a2b4d1193fc838fe17e703ec6383faf1d8211f5cf1585b2b9d1dca4651279d33833b78ac7240ba83474e8eef397a31c7eea136fef74e0723ad150c59a4caf24d9461dba8f3c83c3c48c2a97f759ff4738fb2ab7626ba9cd5527be7cd244f8ed5f672e7e7a7239d59d53c478dd70f2aff1480cbd79f7a6db594ce39b52d6edc8f83fdf3d338fe4bdd171124403e4006ba9f8a3b65a0ccc4b649ea53823ce6949ea5bbbbbbbb7b944cdefdc5796f5db6cd031dec50c523bb35872a2e8302d753c76db8866edaa66ddbc6d53ae9a435d67a1307f5ec94435a91d7e09cedd64e10c421ab3538ffd401af3638b50fd0c699b54e3ae98d3abb14449793567b336de3ba130ad753c73daea137dbb2bb6d9c7624eb84cc9af9267c0dadc68c4e57feee403cefc832e7957176acb1c60b385e4a4190d1fbddcc763f68bd514f67c058be2d7180814d05fafd26bedfe024fb0d6d76dc4004e6862b32bd818b4c71282253d083b9c3776c6cf892a5fc783b1802251838c6f28ffff8472ab97962b0d16145872ca5b4724596360c917974a8214c9662ee18281c6518dbfc4d520b34c2fdc29851f8ed0b815a993e0b56f536a5a2df3d801858877f3947b83fb47121daecc8f245f84a5ffbfab375b2a7defda0d50321470b1cde2bbfb0abf0a14ae2913ba0dc344dfb1fd791210b36670f66de8a0b2c793c9a1c4ecfda679e9629a594ded7bcd8ca7e6406daec41aedfca41f954eef0f080e08ae700626022201c7915681c3b8327c26e6bb49f3be137f3eb9794e73b1997d18fe944f744474a721dce4717ecd173b4c0a167c99e05ca162a7e439eef418de33305c738449ebd6344deb84efcf845237227bae4cd7c997227a6eb031af0e4f2fc4fa53c72558acb792bd042f7d4071d74d077c025baf66980057ae7722183eb032b71b403020849688359068229821c9d26a8e4ecd84445cad0d4000000008315000020100a87c3018140209446d3aa3e14000d718c42785e361808a32047611003318618030c000400000021c8206445370038cedca38aadd0fdf7d1fb804c5438ea82341b231000d17d7441340a1d119fb98fca621435e2feb16fa3b11907643f921b57717d22c6127b9625f0f09e5eee0170fcfe7789766f53bea69cb1d399da04e621834296c15ab750ea1ab8ecd8341a2cded7b635d3a526d85fdcc330b258e51bfa7d5d0831e00a7ee1282ef90e1f41932ffbd2bceaeb60fb22181effae6cce677a0d2914ff90211bc06a07d83ab134ad1ef249908e461e3796460812d8297d62314a08f9149502e738ed28187b4a3b9b16bf45f4d965904dc87bfd2239ebfa7f8b4b46d1d013859db7ca12f13ab39542cc9e9745252a93e559196b5a162392ff149a03a35b91438d1329caf8332aa8453b73871ed8d6a4236f125b12d64444397be4636956e8e71e8777b68e1a85fbf341152f9e8c477ee6d3fb775c3526a6f66ced54ce2e6e957ef9283a0d5f8a880d689946c561c7f8293b103b2253ecaea3a3985c3930d655a84dfbfc9fe162b77b4f62b7d96f84b68189f74ad659b242dcc5ee4ac0ac01c2ab95cb958e67408c5e78110fee097bb4873318ac56f621c9508b49340ad1d5b9e1bd8e893d0922d2a64b388753cc5434724c9056996197115a17b9719955c530e6851882eb25597215fe529b45d77c1472c35f0c92e238e8b3be23e411f37ed9b16081dbcfba6131cb0966d619cea3198a41bd8f8853e0fa47e2a770fe94707d92d1378ea88396209ecff732348131a5a4267e18eccc41a06de78d646922ee4b93175d8aab7a3975cd87055ff88632d9fa7b0f854e7da68ba34914be2a6f0654f5c5d7718d3a032ff11915cdd2601b2a6696676dc06c6a20d85da2887edad17dabf4d35b7d6f7d9d2d6b39df943d2c09e4a57284dc7ef7c112c03d546daae98f1cce5165677ad8b9d034b1fbfea561cf463ed92ee3f290efc81f21c05838bf2a729e1954ccece93850728ea2976ed01310fc0ad17ba317d4ef848d694ffd1a4fd39d2b983a473ff536d143f4457e26b1b195eac0516450637e305a87218160f03837f024f7b24da1a61a4378bbef74c4442177517e2aa9078d0e9f6f1962a48f3bea5f42581bc904483f4e907c10f223b573fdbf221e07f5ec3cddcadebd447ff7df3c8f79c442e4d604a26badfa41525c17a05e71b8628e2295095ff06c1d455108a7b788b2b98c40d76dfe9c31849b15d5d52db2cf4446abeeb1f093e212cf61ca5b3fc88ab629a5081b868b619450eb02e20b1ff4ad29161121207978bcce86aabd5e9493b6b125ed14ee1712421d846ff11859f6eeed56b95d95b1f7511e7dd696238a6d3a64fe25eaa11aeaabaae98961a944c6c9fe914bd738b86c73b11cf3c8ae03e107b87bb3df1c7bb60fdffdc65ceb7d546b27b9ca2d76f4514af20c77ea003d7724aed69b06f46f3018e13418526266a8515268c05790cb201cc54d2920a8796ada92b9117d58129bfba0299066de27d56584e77ede28dd5286383bac30f101df6977b63d97d809699fa01060899d473bc45876027848c00738196679c3da20c863448140e14e9eaa100d8c85453c0bc8600d7b10f0b9a878c81ddeb7667187d0256eb8a1410db65cbc8454a0265ed109f70fa0e7e84bb2d1235fc90e141520c21632a19b84b2f270581821667df7e4d5d74e5c31f75c5fa8f6089d86732816dd906559faaed4edeb060ef01df23ad99b958b9055760e1bdfd983a5372c5677e98e16f63adf6831a812eb3d6f1aceeab7dfc024716a9cba4198e930a1664fa4de5f4b7a3cf7227dc20f64d6b67d147f914fb39a9f66c5b7e89b458b58e42b538f5b13b839df52e101e7d58323f06be245c34beba8d91af857617d1f41676a56f7ce8cd6657e27fc0f83a73931bce237fe8b61cbcff9537f888e8694522745e641d334bd400b88a9a9fa500c20a25094fa76f21b500b153ce5141b97e49cb8ab368e294c5e8a1eb4f58b661f8dfde62934d250b734b6dc0d5adac396f5373908909fc955b9620b418bc39c60119dd6c4d427c477ebce49027e83f1abf9414aa54c1f628473aa300d2d8d8accc124ee57774b40c622303a16bf85229dbba65989f909ce9041627e7db315ac8210c18a5ce444d74881d1f485841b7d01d537ef1f503f463ec4d7ed9e2ae50f011e1e07be9cad3240f86155dfef00546762c3ab1805e8a64b644aaaa44b1546012c8d6db892ea6d2cca89253c5f6b12ad04ebc740e9a804976ab2d973b874b5f744754950d5ef7865d478f7ef4b7413361a407b03a3c771221583874e025d769662a5582d67ebf44f5f2c1da0cabff898cecfb4f5fb299d8cf914a7bd27f80a160a862a6cc16267784221e955e263155a1a6ef82180f5e48e7311bf92760c041b1d63de2c0480c5a224676f4c2773623612d4bfb537b0f4678b2ed44322a3d16ae072e0e19a54d6b812ab40682c36350a89e2a7c16f1d946235a176f2cc12cc83cd3c6cef99b327cc2b7bd30ce328dafd154f827f46d438ddfdc0481e507d3c70dd8044d4a7430a0a839660d5268af3870d516fce2a84b233f3b24f84a92bebb104530fb5a1925100231dd12f3a43aa8904c8b4f4e7035642f6f6c70cad9b008159ff759d544a2e188525e5dd98084f41c5bb429adf765f4004ff9a515e5526bd04980cc74b8f8fa39eebcb9bacd7d30c9eb4e6857dbe958b55f4917b7027eae674c65c4ed87261ef370b10bb8b596bdba750b5c4216d0ab0304a5d5bc5de113c5c1d6e6fe2dc01e723bb124458f4e7915442070d0466097694c5dc18008799b104032fb94751bf148d6b1e6a206020dba7e4c91f24c749b8bafc221d974ea4520bfdfa4f536794ffb258d9ffdc8dfcffa01088f514b3b44e89b3a3178120ce49534f1104d7b3c6de28519669e08e3c0a82a8cfd428201b7873948271b77c7e3cab11cb6b2fbf5f49a6aeb31d86384abec3f03bf01552ee133b69cd747f7d3e59e22a3d3f477085bc9f2e72d50351a4830eb1f36f92b300c00dfaea747e0f66324993d5dcab203bdf2bfc320154776843187ff014b8b12e0161de2dd304fda83bfc4e0267a13b1ac87f8cf71c3890a69b7e977ba473531c21f304072f4eab677cd63b7fba72929624cc3144e5b512d9c9aaee3d5b35df80a4d392e252e9e09df7018ac3e5fc7a8fd7b449712e592ce50e922eae90a69019bb3ee2ad85176593ccda502af2e12cf3e34f11dede2484eab4aa29e4c30d38fa3ae90e97247fc25b474d30e81af54d9cd36b4aac7f21cac0bcccba0db256ba7b22aa92f86db6ba0231b244a8677223e89c4659e95fbd8b6018f5fc7f4cf9d7fa5e796e16471e49a47b8683d3b05e49095389520f992da4d77ce3e434734609bf2319c688765f0206d37a25370f72ec15ccec96462d603f5d31424420abe9bacb35bb87acd4137322d53620c3a1758395846c159d2c70c87542c2514c5df33681f219d121e2a30d4505f9aa0c4efc219be4f9494e88286da114ea2264b7a10ddadd12c9b6576506b55f79191557ef6a5658b3aebfa42cd0db1570f0448a65138fd0f1780b30666e402e8b1926137e1d3136815734529457cce4d6e2a3084d2be429c3ad1fa39227a3b03da59d5252b4badd12c9a797958fd5a81efce59f94aafd09a47f27fdb0bebe45b14f19e92359870d4fe80c071bc736a1f7adcbabe2ea112035ce199a25f8191a3b409f9596817eb0f5f5b0ebffb9dd06f9dbe5ce259e3e1cab1474e864bd6739f3f9a8dd65508ec557d3e7446bd3933ec6dbf848de12b21f87a367115f87cde3c17ec6bfef4ea71da299e9a1d2441698485f9c241add886b62648443a592b1f99537873489284b64144ddac2331ace2c2efcf103686e46dab0f23760c6e36073a26aae2f283436c25571f299fa9db7e495d6519dd79688beb01e4362d54fcf4e43e1616ed5d400e63aa0fa84a643d95c977fbe665eebc65ad362434cd3a86b6c8edbcac4e1502fea9184459c6df589173d8903167bfd8dac9734fd331d4b0140519a5b68249d3bcb224e50c0887313286ae804961e411f60aa0a71c4bd7b3b968c14a0e710304697c34d1078c6580b51e3c8aa3f9f94f731b947014360207b8f2f2e086f4a574c8fe5da11505523325b38c292e07ea20c87b4d1c792fa1cbbd14b2829a089f281f514bd1c0c915a1f26451735a6c088158dfd3746ba2cfe172eeae70f721bdd0524a11b8482f9f3160ddeacc65ba51268015e4cb47bd9547fa516585f33172263eb6a76884949e0441087dde1b89a033fe090829d583615bcc9d6532a9ae2d1e50c0bda9a38ac5612b48f59b61d956d3c629ed9eaf2c5eab00dd4a73e2c674af4848ca5d2b8e9ee2c84c7f4b710cb9808fed5389c10347feac332c4bd56f842dc204e25eb548b7983ad1159feb559b5aaae025eda544395c6479dd978a8a7eb72b1b3df7b10a01ed0e2a2bc0665d0472f8d4fea32ba52704eb3f0c167a1ae89b56a3ddcbcf693dd9b19017984943c171402b5b9c31efb1229fba646906d46907108987d4d26947a1a8cb50bb7ae13074c9673a5bf0244a317c612adb85cee81f115e471c508537071aac120524812051f641aa409d9fce3c341dfbd6ddc38dc642ffbe1934ea60d6a8faf1851a6c639371190c2e260235b052dab77f509276c0eeab05afb31181c7279e2498237127dc11860075bd760d1fbc96ec8781247bfc3fa665d580378560f92dd53abbb59843327a8ccd4813212381fa6a93ed55b213308795b76a4c8bf0d857635fd3a946742434c63bec395667805fb3ba6afa94b50e1a5222ac96d4830a059552ec597623da1c120b54e0cc1075ccd44cee46ce59f4d71dae96cd7385aae3ea8973876bbbeb7748942fb6d857b8d0d405f6b90221f8c7c3e2fd214d356946a203a7bfda0c58bb14eca7fbabf59d0ac72d7fd1187d0cef818ab17bc1461762d67ee9d46c15d2f600b62214ba52778ac70329b3de93569f39cda41ef7f110968a70813d8e4f0b6ae71a3c2c06d9c127bf90e13d5259db0ad67c17e3dd16012c00a2f594148e84107935a025b32837a74cb3b7208170f7b585068bb7f638097b57519002e134e2e19fca0e3a02336f2ecab8546152d874d10941acba8a6f3686638f0deeb1ea5411e9e07adabf9ed1daaaae322e99d8d873bef2ae749ffdd99fca290b8c849a2333a9f9ce2f8819bde4674e991412f620d665a962ac121fb55d18b3a45d79205fb5a4144c9cc48769d45cac04bfc5cd916e097d74c5d636fb9074915ae38f3dc97184bea653726910a470ea49ee6fa196aac42c8bd582f3b736c436b271bceca30918ef5fac324985f5f158f54d32da5da70e0c0c89f845a88205b02f5064c9b36103575469bf23782f7adf5f0e97bd258e873b92219a134e299f802e042274b2d1309f11b4c9adcc9ac3c9f8c7385e6fc18546dd6590d8112cbd8d2b3d9cf04ae05b1daefedbea51f5c81c158ab0530bb2def01e53666c0379ec8dd9a670d648dedfcbfdb4ba6b11ba558836d25630c53e2ea0790076b9e9ca8b1ef4311eebb06ec7a15e9a7358b3e9e2a1b2d3d21aed22a4956d2c2bfac2ef7c1083e5b86151ef828b8a69c4bc9d18e005b52bc75308ac7321869f88de5cf3cd6538c6afdb26464ec72510ec35465dc53f08f08cdeb88904085177f8483e923781e583ccba2e964e283f2c9c9a347e661311b55e3ac1f43789125d429e2439660ddf965c278ff0692282272214d4334c51a8b6842ac66e999c41b924aa01de3a52245e6fe2cd08b353ad10ecbae0be62778fd683e72f0a57a0a2c15abf15152af5a4d0f1928a0f19f56d97cb040cd12faecfcef77afb0131f659854d7e1d11d45aec35016cfe63676be1861fdada7b3e06cfc5e445465668db7e6ea04b9f3d416e2b32a67efeef43235c60cef7a1d637e75d69e272941b9e7fa9e8d5cd7913affda7559d730545a3affba12bee1b4fd41a183a9e3a436c7206f09ae054d1fa6fda377436b05a84cef070dbecdcd24ab29ee82839a0f5a6d828023e442c89d9d0f83e5262bc59635cfb1b69a4c5dfef1e4c01704b954059a7bf28f5177e5002adca928c8eb11378f84256f9d2e0c448ff8ef8b620486c519364699a6782854d1fde38601bd8238a7579a4ab48f76e130e21ae116b5b4ebc92a3c1820f7621f77debca28535b8b1ae4859a5e720880da0a5fecbce76c34d1f5c5d162d25c2869e9fdd4c7757fa575df49d094fed2129ed165945e09755707d7cc831c56d2db634c2c217a8372c30f26104a67060ff53dd6a67509b15acf7554f4c78a795ea32106954056be37d8d921d4da01951d1fb83c048f2b23418988f9c340a854b2f8a1a074544e28d3802ba49df810d3bf869c687ac8b2f3acad46ee9218cbacef65b7ef79ddd506ad4c58fd64f80a1ec53dffa2d26859007eb00e2bd97d68451a148211a5e034f0ca0962823540d460ab6d8672d3bd995c0a003b95810cb2969e5fb53cdf442ded68fefedb332c33671f103da0a9e0289513c6b14f23c8347418eb53c924a36e56849e8cca43a4a66b0c3817c770d3998d7f960cc9b7674826d48589b1e24d90b39d6b0411269227b9e260e0576a729bec63106570ee1e8dc091bbd55f4db503cc054b8afdbdeb5f5a67bb9b09cf5abe5a8bd99125280de92eed7c0c158ce5763ef55e91a5298de320cb118858a71f28e3a35fef8ea4a5fe59581fddd2fe8ca7fc9de4da62381b0223328e6312101aa0821a5c2da32c104a22d0e52e5b0d8827489816d11ccd9eeeb71db5feeb2c3efe8ccdae0a39fa714624c48ac81b893444b7890518e2cc6f2ba449000739d0149b1fee33d1ce58847493989e2866d619a408ffe4b6677ae4d5ac392d0a8edc684e49b1ce628f283105208dc0bacc94688238870450a711813ba57f1f75543569b20f7a14dfd22277340c12564e96f095df110ec851a9d3b61f2a03b78e3f7e33143713236569cbfbd992141361dbf2b61566303420667085059356e84430072f450a2005d940c6dd1dd6eb91afba5bd1f866198344f875fc3a5b246b23cac5246cc3f23e9b0aaf016d487d205bb37b39f94b255646df780aa4352b707b00a5b311be48afb19abb028215d01481325a48d8cdc05e5d74bd5f33dad3f2ca7a0292e74dadb2b6567f898da0fa584ccda7a2c376584831e7a86d5a32d4eb9820ae370497edb5ac7727f7d3f4de41abab70ea325b26ed867177d3448fedb5a97e57a7d3fc173f7f28022a4ac54359818c7f5a04243988d39662a8be8cedd8cdad07b1a2066994a6168924b1ba056c32aee82663220e244237f53fa30053693d9dfe83030ebf92a7f8d3fb3a38480ad0868ccced4038ed96e1efa70d466596ba71b0860b6def3b8f57e488cbf4d9ca8d3f63cc7ea6b318b4edcaa6036f0699f7a0fb7826a301c14e7730f4349d7bfb08d119a2c82b4a90c7fdceb97bba0a8fe6365382bf9aa66f8a2bdf28eab7d4035267899934bb0af330ba648a6a4e1aafaca90908f30912d37ad72be17b9f5ea96f9ec318e573268a9d1d7c2574cb7013794792152c979363009ef97e29e394a590d7c726ba6409ba2cb1d995d2537092107412d2784b388ebcbb4b671b6100922e34081740402a48fe9cf555dc3d7ad40fc354312f7c1665bce46e7ede23daba470e250f6a38fd61fdaed41bf18a4bcd0a3449bd9b87a729d5678b3d5aaade4242beb6dd113e801035458ec7b50361d709f3edbe9e9e854bb887eda939cf2d702984d4feabf4e167584eb37e8283b03ee5fa71d704272bc67811c596e6119b554e24b8955190a4f91f475bd8b1e93a6b264ef7a02e0c2ca08ca71b9a5d357acf6df24d56b8ae26b38009ea7def70759ae96bcd59a19abfcda881d4b70ae1e3efdf73f29b483c64c3e4b4685a143245df3687f996ed4fbc63bc83ac9e506f55594e375d5975371286dfa05d0ca0c6ca1c55f02c270f4460c9401c4dff12723d0897f3f7d0cc1d565a0ac3c7a03e29f29162bfb17ea9c99513b02e93cc7a2d440f7c35b8359a95c3cac55eec0b7a4557ffc0f2eff1a66a48ab705b4574fe996cf200dff7b4d19fb95f5596d9e892d3b4eef55b44a8bc2b4ca4a3281c22fa9cf34491938b4ff8887b2227cd8530d59619ac362e78f15b7ff8792eb5b98f1d6e70d4a7d4e44652f1489d5d88a7e39e1558cca6f6948d9fa8332e1c19ecc73c717f81ce417187d5edd09a16a2a94d523d7e0b26ba4650175c9642a70ef1a71c65e6d56ffd40914aaa85cf7b0a92d060ca04b877f60536f5acd6e2f1213cd60b3316f333358030888be6495082d66298ec3833f68c59ba9de182665afa53689988e39d67022f248176494044970a8b86bf1c593be03f9efc577cf138eacb4703087a3d08d7755b3fd830a1a233889ea2fe1c66afee017997a3c2af8827b2a570115e3ff9a82e1aab007010dc482d986efc4e2910c4da7e223539b922f06a06c802bc1b00c91abb2ab70d49f1cb0ec1db739aee3ea35a84d8b601c50319fa3a53c80a7302fe68c71228908b6bf61994c1a73287b725c46e706c99b8f481f85b154785c5818a3199a62fcc0f4397fca0b3ba0b5870d85410e0de1f3956ddf2f5099bae06bbf1b28f2fa0c1ff59ad94b83a653b1fa6e900158155778b14571a0e1d9688e6b1117ede26e93604557bd28c8c007e78176815162edc219878e9477629c1cc062bf0bd0595c3750f38a2f75d1cd101edfd22f78a008c0c2c34861b8547a770d6d3ee7e4fb689e856df9b8741d68892f40bfb4ce458e4dfe091d8c2bf4bf25362451c659e9cadeab1620e96bb733b0043205ae3aa856267d60a9bef2dcb9b575d8792efc1bc05597bdfbcb3fbc915a13a4a591302aa119531bc15b9f9200823b8d225cf34b8c04fd12cbc6589fd0b500fa19f930f5506da87c93c262b8eff2fed015c912bb4990b9f6eb70fdaa09fbf69fc3ddecc99e02c58916383abaa1921b4f61236b47da80547defa07ffbb630c36c7947f5d697d94efa437eebabc21b46b36d8c20254d19be11539935cb024e19af22b7e5a243e163bc22f7f6e6c49cf26938c7f31fe930201bfeb74c8be4b52e713c9d01f5b5d4663c00bb51e097fa89d95567e7657996d580745e70a059bb2356261999e08d499ed7ca54064897bdef2c01bc1c707e8c394f01af617a906adf35cf494fcc930333bbe4ef985d0f6c0b258b4397fca2662620054199e3e81686e7586b82f759e498aa86cea926dc68264df3fbdd424614056f24c9c01be5739ef9d582d6a3dc1b41f20420f4e4c6849291f72c5dbe93fe8e25c9487a6fc8551e450e48f9d631eacff02696075dfb3837bf23837184f76166942dcab9f33e8a4c37b53ced11088c20618746ec2f22015f657489ea2ed12ecd42a312698af850ea2ebf19dbb9e7ec01b2a64a1468e43730abacc2cdb136ac74a72d21f0f10472aaac1e4fc8c273ff9e8aa5f96f36f9e587bd410e3a7e2ac3aa44dda79974813391cd1e2b433485cde9340cbb77c5fa883334d469b89923c80593e7fab86660fbdcfce80cb2de6238e73bb726f91d15a23e34d1b9e9f1daa8064ac5c0391d2da4789dd66b2e50659fe987e7433b8b1321a0e0a5d55542071fe2400b405a06653921f0c32db69c11f501d38faabd738cfedcc35a1ccfd34fd9ee9ff7a22a564979ad784a790bab20788222b56c2f211532fc5341daf36bdd6f7887e1a2922799127d6ba750abafab9772a674bc3867d0b8199e7937803650fe597d6114c37d11be49f2c699c499115467a1b16f0b7ed17a8aa90c31e01381bda803d5ee22f62f9b68fb0af3a7ec5d60c956df5865616a995981e0306278102b4ad1fb047a504c640be40f88facb053f2d543c173c642f8c52474f4ee81e5b7a142567cead6ee306371da72f13af6079c00d18689345e6c1dbc52d765d161eef19f6f1e024c2cfb2fd19a78743b34e9d4135547667bb2fa11a6a31ddb74a7034f6c652bc50516d780372ff25ce601aa04acef46e096998ac3b33ca5a4946638f56d71098a84f5f1e465f9f33e6a6607904ea73e027d2f793c4dc24c767472e94f7f386dcf14074cca1e33708ef539d20e3443a470f5c9539e59dca5ce54fd97aab167a3528fb65d533582bb50af7ec3276e6d77059acab04f2205cf5a91390c9af0a359d804ebc99cf79f9c5db8c16e339841dc157d40021bc8f9e1411e852383c903d5a5841ed1f5a9f53ca38db70fe3ef878e9fd19c5a1eaf9e39ef9eb243681709be69447e8e80b40c82ca8a5c745423725013227d1c82b1791aaa7a1b508b8856cf4b671d0a21de9f2026ad6d0a58c4f382f004ba11e9eb55e4b58611b1bf70e821b0e50401b12a87484c98dfec6c5f2764a14f8b4ec70f8a6e1b8f3690a17b4c201f8653010cbcb0c925e12a1c81c56e56c5214930356a0548b2e56ee9518aa4a3eed11ae6c9fdf6c3c93acfc1a1e1e634151c2e69c72fb5a2fceca25dc1418d850cfcb1d771bd62e01b4390de8ce6416e1601443ecdfb0da9f56a6722448f63e92be39c587256dda6bc1ef20e9b3dd26cfc582c27050fcdad4752842c68fde370701524c242d43a36f51e2ef18e559e35eae3cce5cfd9d035b73a5c4341876f2699027ba2963bfc07ef4e57a0fd99ec4bb05f6a694ce730932397cee5f348a1705a007198fdb7b68d4122d69a795ffdfab08c886ddcf82adae36483af83d58f815643cb465947bc158d309c39fce63e366603cfb614ce7ac23192bdb2253b2c184368c8ca40cfcc2a6daec95d4f8b10e2d59fba2f6cc59ebb5208d7ab9c8dcaa8e830621b43559d6de5066f2648beb38a77ccb00b5b0b0cdd79e69af56441afb51614428075129fc4ffbbd9f7d080b0a26aa90d8524a7e3ff0a201118130fbdfd07d3389aa314c06921c9b920b856740f42a67837928003f7107a658c58ebf9c1825b2d30511e073f8d126b459f249c8643f243858fc422ed79940a96486188cadf73034fc34ed1d8741f59af6acc17b360c941021881077d59a9d5e5ce0c089e14f420c8f3ea6dc0436f4b32c63b128849564d8c91714b1f1bbb175fffacd1205fefd25b133e716fbb023befe75b08111745c2ba229ed252bb71620608e06b91166089e38df053f36f67af78fa812aa8a6848392ad69343085819cf58454623d9c6055a4744f402e916443250b9b61473cd5fc26bd552a3216f76215e864b09a9eef72da2aa7cf546843675f95393815ff8affe6171752a9968c3548280e0cc05fd55d8f47cd08e6e1be86088949f1651c7127e5d7b2c98351b5951fe88f189a24dd868404421e8bfbf93715b34c28a815cab22dbdae7c9ba1cbe58a22fb298ed54b4839a1127832352bd774f11b422ba56edde7d805bc095c01b5ffaeef6f5144b2dd5d59c3f4c8d8859487565f1ecf8b7c86feb135ad5e869a2c6eb42794b065e68760aa1b1aef911c87c09ff41fd43c11ae442dab881dd01b61210fba28cab1506ec23dc5bdeab147e98b90f22435cb4de53e25e6460eadb02afb1c5e7658ce2608092923b8941a2f323e9a951186002d07041a4580c883fced5cf5c269ce8c754fe4de9da54eeaddee0753a816134325423110ae8226502970d4949380ed1c0ff2c2f08902371c3ff5c700288a73fb4a8b18f1480971c202693eac73a09354edc3eef6003304a5c2fe04eef9ff321383219217a71b389847dc60bc07d1f5da9769f2692b86e36c73c5e02a570b48b55a16ba41da8514792c8099eba99b652138dd0ec66ccdacddfd1900cfa8033698e0d74f72577bdba4fdfadd229618193727838e0d305c3d1e46eae29e886908ac709c6814f8297786f24dcf8cb00ff8ed539940d56fc216809044222a4d14ee30e5547a33925aaf15befc680d834318f7074aba5a57d9827f5ab8007108664e02acbfa627e3fb4d606e8b21da6d80ab4abbec3973cae03589fbe88e0f0108065eeace7f18aa748fcd817c6c3ac8483b9c8e1a1dc04af38319f196726842901cf7a0b1bf02d0b229c0effb2a1371729f4495d2058862af597c10c8ccfd8d85d831a1613cd41324f958e7636b3ef0c2b019f396cc82f8b48333c5ca1f576085dad6309e450407c0a43f6ea6a3338611d5136f8e21f2ab4b9b01c642a1d0227400aa2b5ef990e642e0803dce65d8316c97ca82368e254e1706890caabb4b0c7702f26f9123f4987b68a55f46da135ad653cf3848f71a70134ec966d921450e572f2127729f5c9f3dc9536899fba778456c852ee1e483af7d353126dd1eac7d81104123a97b9a9307248fedcaadb78e3be14a092f66ad7abb7ff9ed54be8943f210f95214674f8672466dcb6f0c314c1c31c0b145d45b48e95ec31b7e027948caa10748a76c4eaaf2835ddba9d92793834274e687cc566aea512acc3b2d43fe81439f8ac37f63c97ce089224a4525505825536772b65b29348932fa8c0a408979ad6a4846d70ab90ed10ab335c43a255df562fd619ed6914f0fe39a202c2c65c2a18a80b00ca5d5ec51b66eddf60f0372fa6a3f4f5b67ab20fcc841f65f70455e190c27c53360a8a10beba9670b3bedf28a1002600efb01705ec46da167ff1fcf00a08477414c8a968fc64d1103ce1ff5bc9e63d1114edb1b0b35fa841e106f9c5a8139939b69b994236c4b9566d3f0ca2f2bc5d7ff764afcf29be517e2259d1f4ca22da64beda4edf40505c6c370703f3a18cd8da94b3c420603b0d19f471096e1fb752b7d87b7fd89f07f0172c0f9c222114523eb6ebf753f125a442ddd9e1d544e159d6ce7fa7bffa5b903975c8a288a6da0f3b14970db0d2100e64e57e1f71a9d796449a294eaf685a7a5f1d97ac7925ab167da367ec6f4ac6e2fa9c7c5d964aa6e4600095d607e916e3dba588a6b0f5f638e99114416ad8e31ae1b3ef37244012340527e1a87037c439384679350c56df8c91aa0a2b08d5b2fe482616f92067e122d1eba3ac70a0af65f0e0147af3c948b95b50a56392d439ebad8c27be7dc3b4ca5551ca5d4d06540d8b405cc9bcb167001d06884068692b21ef868418d8353502ad4ae78b4d1ab066c7d40a93cd53035b1943e1edc28aa2c3c6a6486b1a193f5f8c41506426b9667e32a7be16ad58754926ea6c11e87ace7b72713746e38bc8075bcef2a6fe590e0fa146a7de70d36e4e1dca59ae0b64184c753508a5b03d266ee3ad607d67a5e48a238a0f74557ddf9133a7a458669d12a2c9f98dd4304f3a31c26e88d7b75156d810fa9a8d9a03802f5e369939a606253c56d2832ee11e176bd5a452144be2e3bfd19e0022651507e10ccb42a4b3ad4f3cd18e02b384c9c7fdd18d19109c3b3fdeb6b1c7e73100636154b22ff4b1eb5396fc6084c2d1d33ab0993c0aa3a6b4224afd6de9365166afcf36c76483562cbf70a2e912943468ace78b0f3c79b918575f8867d443c1bb4f063dcc88178cdea23f959a755e7bc984426c330fc55674f9720a956fedf154e8f599927b06228bab55d9e5f1e68be5aa917fbc483ec366f912a67d1e0140e8f85439e7871409a4372726d0bf964cc282c0a111c3f801a8fa79b78f75b2ff94571abe7261f29f43d65ccd6d4bde63f61b56995b59cb74be34d0aec815890f2d23db6e022a4527f5e663ff7a4c01f67d4de193078f20fa301400de418ead52b3eab2ceb1f523be00161bba3ff82531cb9c15f36ae8d9aeccda381be6ba6c8b8a3f98fcd3f9cdb1d814ef6d25d480d75a3477451e96f5a2b3804c86db3ac562d4907badb944bc82a98f4ce2bd02d910b05dc762f3f53cfa0303ae7cd56b0dce7285ec9f2b7d3160bd516558b1912d906bee73ad18535b87d892838482a8077bd8a6d690942e364db451567c496bf0d4b0c9216bab94b0776ba6d000e5a11d558488f4b9db407fa4546c996596830ae0869c3de6bf3e915ec9209607666a7efdf154df2d0d49e3fdfc4005225a5f131789b639961b5198a00daca75fd773b778ff82220fd46009b8769b98b2b07cd5901dba19bfb3636d8b8848fc26a26b73a0db9e4a3188c53bddd6045217ac4aaeeb6bddb64740bb38ee3ab7a9ed21ede92375de57aad9cae8b6a5759cef5de91ec5fb2fb2f97af4cd2375dbcdd1b44df0875c51f5211884e904c8e53b6cc1b7c4c3bb84eb666c8cfbba640f92a7ed3def365a535cd69d34b889d4907ef242e58b16726b2a17eb612259041eb08668ac53fde5830711a5ee9b6372aaa436c00f8700256d932d17ab451598b22e662b535111268a9cd46b518a27f6992bc2e1f5510ebf4f14b11232a393866457f56dc959dbe1b2abb2e354d6e89e10c1ceae7956809754ad0ae1b148488e83baf285a18a43036392e43610235101b01a6d5a313e4a754b6e776115a863a75c4e0cde215a3ebd782391c03923934f7747e51765620ca76a683936e2133a60cd0b370dde8ef24f95b73cfdaae5cd50995e94294ccd8577c3698aea97b3b5552418a94ef50204e9850bd65b6fb4359b4596ff41b8702c6764dff66cb68a59e0cff9d245bc243155ef7c173c616b679db270efe26f8899e1282d2c394a231933b41778334a3fa006e376704999ed708e5c7f6428360879b30adb21572463bd6244bc82a2673895a3bd0e6b7c753b36fece55f16601d605da3700c0251076bd1a4e68f78c3f4be24036b9a77fef2315a2abff1651692e49ae1dd9abf6d973b333f752fa82adf3c7ec4e4755e26f1d448b078257679df6ab1df040de253911318cbc115087688fd73776de8b254bf869a881fdfdbad80813e7a83cdeca2d6dc9ec359d54176be5a1d115a4851fb819dc2e238c4dbbe88308f604a1aa8a0d22df93cbae5a5f2090af6964d74b4ed42a940f3208ca045b79b953d9654c5f9d896b9164a16df1d92505bbf27f0a567cf02d5fbc9090bedb3273e0a0eaaa53bda3eeba46e613176d5d8ff22770565d83f3236ea2aebf5039e99baeb49efd2c91c351ff1a890a83ba8c37692d97eb1a938dc5132488e8bb8a169ffb4e83af59c81c05b484c1d26c1e97e667622836691fffbac633cdf63a7a8dae4fd8a530453a463683e2c7567b487c456230494979a0f5f6a151c3a6eb43cf8fced8cce4b720bf753757830e49eb34761b47883856827498858753bab01712bf52c8171df78976a072fd71aea05b0d6bc2aac960d1e471cf15e8b8470cd628ae2e60df9412521d8900198dff6f2b80960fc6fd1979afb7068ba30dc00d7dc06ca88a8e71fb05d69b4b9a8082118d4e5adc14428a7e5b0d06f9dde3c07a10badde7ae630441d9de0ad45c129af6dc6d6b7f2b067be36846ccc6f8207f0ec597fa65913c1637c5952ba6c09934f4be1c50e980d4d5abf9fdf8fec97151554bc3daa4d8b263998ebbfd79b67695161923d20d627e0c7655bf81e6c2888dae75c0f44caf47af5ea38f80c6b9b5f5da0143d8a4d46115a3f40054e3a6621337879c3e008a492d7beab4ebc6aabc2a24661826300d06567de5bb4efc325a536880c6ebec7fcba8225bf78afa2b70a4615ad4aa12261a60e6716af9b3c6ce67fd1b3133ef50447b84a754924621b487f8413840b292bdef5c40c89da7a4242019cf13fbe6e1c4925280ec8db2035102c44016cc42bc12ff7158ba51a19a4331cf81c8d35abe671cd6dc1ed7524a2463f5385a7b8ad911cb1ff32d13d0e7d8205c65d1eba0d512ffa0496ccd236198712a075b9fc4690cff9dd72dd5ef208612fa3f7f7b88d1ed980f6534fb2e849e5fa154467f011e84d86918fe9542d76c3bde34684fda19b7ca9851d3833c0c30a01af7261df7c9ac3605e9cc3a8d22181f003ddf73910a5f69136e360e05cbf8b8994a1e9aefb4f2181f43a8e1bbb2e283737db8b12aa8acd3d2f59d1afad435c001c70cebe8b1209c1675591ad95d694dd27640eb65526a6954eae5a4c7aa382f6d590c0d6d4a87d50fc7b8e9d616741fdd9d53114e467447d18586a9f048028bada56b61569c37332721953fae595a570bae924c2a7965cdd57867b337c6ab03da5f7b4ab7e386a16002a178a080abd65f763b8c7bfa10d9136ccf0484e1f8ce16f2fdc9bba29e7f1c7758714ddb2f46ef95e696f555118bf666b769391e4ff066d4804b4a855c01cabe6c367245b18804aba5d045771fcf1d88d8df19eb7216dcb02244a2eaefde4cac5992fb25cd6923e59636c53f03865dc63d907870432e7ea76a3536724bc90530d74ed7be3e819931a21c51606e9d28cae905f617a83a9ca20b711773f573d00d03283acf264baca200534260cbc7ad0f4b8d211c43b3ab2f0a49dc9b238c10fa5e7631acc3fb3ce6bfc89f40d04eecf60c456469ee96b8cfb763919bea01505a204bfbe5598b1ca54b5952c1f0e11c473408bd6cf13944381732cfd94198669131dc954ee9dc69a3e14b0ef5c743a664dcb5f66c9a418e89f2b9531afa95113ee5f92680783aec0bbe81c826a18a09b610916f85fd7810f0c015920c031d8d8fa7c31b64378d93ae4db0910a1b93d61ce32b6f6245b829f3695d41d72b628e8896cb95ea886be023be35bb7d202b0a90661846ee9de550251ee06aa56bb9a94c29a117ec41ca1d345b1affbf22440d9e1dd0bf5a6e8ee62c72a68b234417e222f6e300125873557b878cee1278f963153123cc87d7d7fb02d6110aeee5060e1048171439e3d0e6905518c480c1b1769a3e94811bd892f528336c08ee368e57eee5ec7b2492a8ef3b384331b905daf60e87d0d3f2eae621fe9c9563ae76025caa82f3a8019dfe7e8f71be9fb2a0ad8968d20d892c9c9facdb140f73d012b0935b5d781f51d370d2c778f7231139e6f08ef85333a39eaacc9164fbeb7e85348440b6ed818e64908928ccea3e62c327b9c2c5bc585c3825c7155771dec4a7ad5d73cddaca2c3ab740a409c8b1f328f3ee5af4de3312340cc8a00b9f0f0dbabe98c3ec3ecdbea63c0327d6eb45b9b031ccb95a9cb2767e8b2f1e51631c9a43bc5748f88bdad63a86b94a14d9d7e1a06de5173de0d56aebf32b6d0f8bd0ce3b26ddec2158a0c7a6faa4808044de9e0d22f04f7f8106c6c6d6406d55c6db03f0620e33a6ab723e23b23e48e1088b7f61b925ccb01aa1e41ada27babfe2fd84edd9a57c5efaea5a3cba191359e0638c5b5f238eaadc6d3e7ba2147ea93b2d97557b0ec89b8b0983eba44a610684531beda3b165cd7c7783467a61095576f1bfb34227e3283ac8de9972fb90679926fa18ab224256c06679f7b8081aa4fee1311a3adb4c3a241f56ee9fad7b28fc5e0754cc6815325f4a34f57ec3fbe04538cdcdc94fad6e814b272d503721889b1858dfbf5dc717c7b02040c24f2679d2bc61dc75ffa92f7bd735eb1fb7cfb38fe5a5a45c2356617959c43145a4329e52f48411367442a9a7e6ae929eb3adc338fa6c3ad6a8fe5a8f039f2a23af7fc33d4f643128ee07b314e8c5c04b08a267cbb5555d71d2964955561f64fa84703d7d04e1006a0a1a8e977134d7e48175cfd4ab41941dcbf9beb3f2539130459b42d36e462753a72e91af4dcd025c6b39e3840b82a897b0d3672383e08f31002fefbf3980a003db96dfb97827dba69bdfe13a63fa39662cd37009c73100801b15a8ce798897eb0853b2ead930bf542ae2bb0ea0777d82208ff44e3126f5df53367bbbaa8a4c3b9f088f6bb219791e7b3ef7f4e20285293d56f26437eb8e1cff8f4798ce693faf907a803042c6244593e0561904d087d097f0c012920413063d87bab79870ee00f2294dba984858756635f435301c171095b15cdc8d27926d10e99fecd28316e2a4a55ad136a65019812bc96efd0cc741e7fd7053761c2c2d1439a0fb43305e76775a7cedab8b5c64d8c4610da0e7984dd5cd33943f8d28c51dd495e26e403083e83172650d664645c1436053c81260de47ec4ad6d28cc5e232f2bfb495060e0d3cefe997e3b2c2dde7f26b50ce22f94ecf0b96004976941ecc25396461c96601bfeb72a33366ca6cf65e9fbe69d97d7050dfd64623590ad2ca479d420cd5c483f600400bd81ccf51c6ece03bdefdff4e78a81c818a35b097327e44e840b57770f6d1794b2dc2214bc73b406f34715afac4047ee11dc5c0ece5c5c76d7cc9a9904de3fd0d6ee4371a56b141389a822c66e5747d9f2f5fe7c5224a0bff2ad808b214ab167b9c5f31f75ac60a78fe0acc33f12ee1b7d2ba7ea598cc7b6f12279627d3df053aa4259db989969190cacd1cf00eb7d252117582bc781bd9cfbe327817cbd093d6c753d2c123f38eb51d7a26c6d05fc03aca6dffbaf250cf670dbcbf956c44eaa01758120f9ddc9a50b765e683565735321e5a9ef4a45899e9457863d12b3ab5546c7cf346db92615728fdd08d17617e7dc3951d92d3f7ebc19fefc327b81a0137c5ca13375789fdd8eda03bc016595c7bf67708610ae78b939b8ed4314657630aaefa562601184ab1d50befddfbe3b5b9c83e3320b714d20800e88ff46204c87de887fd7ad12bf8b8e37cfeae91d73b6de6e766d7bbfd8b4e3866b61b9b00d3474572d9be074c7115d530824cb387073756500d03e666f796d2fcc8ea8d24bb3670162168320ce50e3ae5c76a346a7109afce5da1305d7757edacb0a5779f54c7720004bbe82a893018c1ce48cd1a2904361b6e62065a5beb8983f1a97b782478e644767a1f611b0ee2cb4199716ed04ec16e80b6bed883fbd0913228ce44c2faaca78451e723c69f1fc5c220dccf1db032c327ea06de00dd2740dcd5d6e55dfc1194ea6d4085aa00c115817e72edef85f0af9e320e107af4fdf671e1308c2ff71bd2cf616698de9e9501b9356baf5c443547ee19c13cc7cfdcbedb5bff1c950a5f554091a85af2a89bb59b1afe142f956403057ad18e59a86d65bb5516a5d0d33551af94826f6c9e0c4b159ac6154d9243ea01da91fb9540f19e42219e1acee909c64882f6c108c6d380673743b891f053ba14cf20757eeefd8713b1a139a512dd8d03a0cc033ea516bab3a109fd3e10ec9e68318a1d0e09ece3d8f4988aad4887e7d11e709ce7e82101f17d8d5caef497942b3c08122dc9450ac7f3260f25f0c2abc00a58b86908de57378474cf5796ca023ab3449914e2ace904b916d03de348b82a838a743c3104872e8dddaf7da944e205ecdf987d266a0f20af547910db7f38a35e015eb6bda71d9b4cc5f8ccbd1af6c27d6a151291afc0d872c7568aeb7d8b4082e67208d04ef2b53049d8b942d7890fd57ed5d97ee8cef63a27a47119da186d608e733723029473392c2c8b0820de2cbc14f46b8a6a7493c6e553553cf3371b62d75ba481f742fbde81e911efb7b96e0c445183d1f122059b902d135274c1a12848f90dff21318aaab97a2f1a9188af4d220540f49838f5211041f1dba8a548cb7f6979b38d54650ce92ed4dff9b3ad3fe01334b2f1074c5dac6f464b903ac5fbc42c296bb85b7a3215bbb50c773f997ebcfa1f284e6712f83fe68f40d29882a42eaf700b8283faf49e1be99fe216c4e047a13bde18dd8c5731cc6d9d982900b8bfead7115e2064c9ebbf86183c942c79c7e28bf434f2b46263c9a1a77833756e1465de1200a2b41f05289451bdebb46ff93a42a7387f08ddade52d30ba937fbba67b87e0ea4c61cf7b8ad54a6279265f53b18708275be704983a35e08510a32c79cd89ada77958ccdb56ccac70dad38fdb0c0d42e5b844eda92dd94f6af6ebaa6899a3cc6a01dcf3eaa0be482f140acf209bd5b91f6d61f4622a7fe68e243cdbf9f0e7b8b83858109fc1de75c8b2cf1372cf1763d73bb8e071e8fbb599398ac02e65a1f0c790390435e480bc4f8d12799a13e7b46cbb0cc49c092ade5e0d8ddbdc7f184e164255aeebc724b38d49dcdc3d452a8a05b1ecd5fe647863272167904a376adf5c1f0525fa26cf1808ce18b25a2f4fe26b52a7ac5cb45a4f4f626b62af2cf5e21b1ceb398a882733217aaec01ba0d5da27518800f15381334726afa0e186a660a58094f351ac98dc1b0fd2d91425e2c808a57d9901498154f7299309c0e6cd71c6683de28836b2c45103277d0b4b48b9a82fa8769284ad490f589f5e1dac007ffb1f8205db389f0041b1b4e27fb434f325da3e00befa06bd733a5d3636ce1c73986ba22ae310c70f7d90dd8bb908f8637be764f458c1f6764c2642b9ae9833ee29773fe82307c2e81c65b274ad8f8e5214accd0e2aafc45530771efed5ef8e3a360570b0bf257d3580019cec03e14b28e196733895ce214095de1eec0da0b62ab99e2bb6ce408b3650cfbb4be5dd9eb17e60211bdcfcda3d7679ca5e7250806b7d8fc34ce909c0773896d2d7e413100b3c51620c00abd44f7aafb13c03217452894f46758557a3af8c0ca14e7352025d7b88fedd88fad7c581113137ce935906c04d37e790f58bb1628d77200c258cd47b4543b8344765a6f6a97b9942dc34066bc3f6a97b9146dcb44eb47101c33d88634eb13db3d70b812603824d6d352aaf03d664695dc6c7b3f626e255e90f00657acc05c518275630e801cb80aad12c92ff965ecdba8019f0f3df4beacaa423c7759055398408a494843b586d4c475a02b31295bb957ffa020c988b529afad8a037571cfea3523a8ea05c331246a53302191c15bf037497d2dbbf94bbb2ea48021908ebfb95a0b9c0c5d782e20b4b908a98a26b73a548d0e88ad33a44c0f00ac8ea791699a8188d620984ca04ad411294780d4f528f47fa68a7f84692ed16ce3328422f388243d6907b94d076cb402347373f6e849a2f5ff6fc12a992c755d3067f8ae4c08e43b1366f93235266779d54d063c6c24517bf008a1f657343aa1552d3dc5ac0f22c3559824b4043ad09281e8543d90bbd88d8b7e05201940a0ca9f1e72e8916616035abc7333a5273e9618b41b0d81cef8e9e50c81f776fd8249f00646ab6598892296a395a51ba7dd843b8907bb34c3a2e25876482fe1f8b60198859db033d91fa583e418d8253655b9609eece4a933ac3214ee340700824e09f4c8aadcde30c3db88274a29a63f43271c30522809b73726ff45a1d45011868e0daca6b36bc982e1fa9e8687c71c7f2d22e9ff919c28d38234b44bc0d07e74a1da6d9a380e019504c53f1012a6059701d8c0f1fe2ed664346a92d39e9e2b3697ddb590ac7eb149c8d0b7c15ec6596d913b89ef0ccadc8b30d1e00a3ef7c2f2860f1a05bdb19a0e14d60d1fe1ee5af9e1082a557bf29f20b2a37ae0b274971e3279b8d3d611f3acd8b9fc7420d0a7197864c47e409c379be03c97aedc94cea9a0c2bafb9e4d0296a2cf12a3a295fd6547cd819c637f693aaf41d768cdf33f950490dbbb0c9bf8e6ad8d76397de47094c4b952a86b72f7dc034314ebebf9e639ef498a13b7dadc79ee00dc28568948daa0d8e1dfd7942897f74bc9bbd8ced31cea28438403ec4d6fec3a79c13e2ae17e7dfc308b26f8daee31524efda5f7dfeaacf462f2a90fb3ec43a64289129c1664f5c11c9db90eb419d93d11e23837297c1b547b1a29f4f6f5f189245ee4884e61849ea8996f08c8e0bd109aed93c95706b9c0542bb95cfec0ec143a202e57d517982a3d9357fd04d1aa5f2818fd14699202030c8ae72facf156213928c13d241fa762a5ec4f2c796739542f67777751201c1cb3099f93e5077d5f9df31d6615ce98d79537761585fbbe25bc65ed716fd0af00d0622cce848a2a64b2cb833afce97e5a259c469e689048782e65109907518936c173ec22ab4de23dc7165fb676ac27d6f4778ec17387c812bd73f8609cecf48e6eb831923fde8c9f6be1994ab7ec53c1764cf0f394597aeaefb1bd2b4f0cc67ae05ea8772137866c4a1ae397daf82e849ab76af00f5bff937902f37f8bac95d82367565d9f085b8149092192d34ac1fe197a9f4b99e1886c03195ae2e39ad3b3fd7fb3e3518eb1e8140b2e6bc4c239067b539fab50adcabf26cffa9452a9d0a47c63f8d94d377d8a4458e4d0d0f5cd366c7df1c3e9b89fe57525fae571b59add570733957a9da8c6d57c187ce5bada9f3efcc3c4e9b887b55dfd3a06b3920f3332748039a13efa3c8c25a613b5f7dc731575a4d0f040a41bca92dac218014222aab3af10cc078c83ac5f4a7e4c9e0d396d96b9ff22d68228a3885b92282069ba074e63ff21455a2725b7e78fb8b542ae865f31bb46e54785010b3d87db2cb0c44e2313af4ff780055b554ab438673b59d20e5ca835960231d0781029616991f811c0539530edca704787a710d8835502568562c95f86f47c9eb95776e2fb5a301067a4d70667134b448a8cc330f7df046e279779a7143ff010f5e61f07e5c579a23659dfc45bf3e96111708b8c1262966385b7ede95a15d5132af34a3a7178047eefd14feebe7a0311201c3e9271a1e5c00eb3ac7345dc8e0245a4360bdf1098916908114333336a7d396249992eff8ae96db9e56637190c0f9446e5a702f4034ddb9e54e9c50baaad08de0ca1648e45a773a41c954d8843416beaac5f1305ba6f377514b4d2617c925ddbb4353b65822ca124b7b4bd36ad7e2f239a9770d5d5d0a6c7708246c02f1f7b72e3b98d250cd22dc411072d1b527e2a1c7b4d7968e4b43292b688eb0a1d6a85af93caaa8b7ea23838e1774afff1e4ffb8af322d0ab827200e717eb7f23e3143102d1fd097368a918cd1db71b7a235c3186ef158740130da72c4a06bee3a2d7c059a9ea503a3c4d34750c516e35256bd3b0fa4de393c1a1302f2c3def297f9b8391873337b9d14f3f8d7338775d0da6586df917a284583567f1333a40d959d269e824c8b71a8227670c7758146fdc822819082f823e57384be7832b59565e34aab9955ae67af0b63cbae5984063fac305701e7734d079063440ac8c1f14522a37e2b48cca49d140b93c9779d3263de579b1e6dd70890fd402ebb091ad7dad99bf2b521170d8fa7650e58f631c1343adc2e50c5452ddbd7902247daab2fa1ae7d5f719cf05786c1a5c28935a0304df069dc0bdfee92d17604bce6204b089f6105c068928d97cdd136b47af87aa6276a5645dd29562d38c418365a58d39522e40952a580bc56af6a728ce0faeb557b36e2227f881466c121f3d387b381b73803e44b46c58ea67dfe32c381b12a320c0394e4b975d7d7fc6584ccfb72c1c52cae146b1206ada0a8d9ddb8645a869a2d9a7bb21f36ee1e394c7284b2514ae77c4782fd69da9ae3db747f52bb8a1459581beb786d6a3f5cf50bd01a20948e74ff42f7dd90d6184237d7ef8b8d9f5fdc2092160fea89eea42dc20efba09ce641ac815931075f161df1dc2da89dc578b6e06bf4b47f557f6e67dbd0f47b6b6018b8dcad4efa0cdd41477b0bbdc42be30d54374ef9c51f65c23d1105a8a7e158e7ab91f41ac632d2683976143aa1dae47edf8e87d48a2ae3a2dad9a93d4ac0dbf1146540c5f2a5e860ced1bcf62dd44f843da8ca5003a6649514a53cbb001d827d912921eb38dcb3080d9931ccfff847bc88d22a3f0d0301bf42a0f48718469a5eab4fd61e2406a47b10c991c5d3f3e901c05d422b1ff38fd677aaacc7d6275a76dd48d8c5f7e9da66147a6061eda109e87c6b054be36f2dd3b6bd89699adc29473271ac801bc4b4e562967c054e2be8d6f8b12108506a8cc5b50cee4025c4a60ad8195e78575a77320415c0561050792609b07b5b0456ef2e129d4ece235e131bb4da498a2de1a6ad05478f899e1cc60360cafef239648cd8b9d6c13efab21d4490df90e19a0c9c66e076d69d06fb2ac7c4a60135300fde6eb91cdc7162451a99a25eb9145497f4a4f7e98413b67cb1057dd7c239539a7e836ada95f9bb9194145c821124f5d68914a056b1d0527ef577dc4d2552852a09b4f76612b1e71f51806874564b9366f476e4baf9020799717b798af14ca3fab8fba9f9188b630805fe601d027c3a471ce6e454e36169f591145ea32d97d9b18e72607907d83291c995cafa238be2a8738f3969501d90cef7147d3a564916f0121b6e99aa5f948318535ecdfe4e9a834dfea29ea39eeccc9e9da1dd61534453b0eb12e0e4c5c853089afcb35ef710bb0215294a8531e909343e96c66f0b76ae8ae7146458245989d9a118a35d1257308f5fbc658a047f4224b0d5f1ecbfb8fad5c76d6d91edb39abe10d057af9d89d0af2c359ae8c574ad4053ad08fe7723d4ee6db2c2f5f2e986c2208abd909fd2cc8e4702cc5ec111d0f9c2067ef214ca2b6c7b66cb1591169f82982ae24f933eaafc08168a02a31933aa42f74112c47ca75811a2574a272c56a6d30e5ea1e1325cc01973d188931a830ebe86c374e90b7c1051f4de931c3c414e8e2375e5d737b2041242e043c0cfdafb4245f5d74e19049a47cb24748b8db88e9836242050a753ed5de29e64b8660dd0cd0192293c11e230c1960fd1544c1ed670a6cb8389dcd71a7b4accd9a3ffc01a47f51cd2534a1a0bf9936682164aa2dbf87543c6e25d176179cff4450b6c828ab5ec605017260b1dfebceeeb15c886fea4eb89ea057cc7bc6bac8ce2d82a44a2136338ffea019f5f1d118fe419bf19c62f376a6a399c16d1f1629808ebcbcc1969069d1da347b739bab76e17eb442d51d17f82cfd1947445b1808f8e50ab05863b39da71b2a24b50a45ed5b70b024b256d51790cf93e75d8faf112910e5d25f55994b13122cb298a0f851245aecd3e6ed384391c9c750b44bc9c3aa23c3047c042f9b30367a528ba71e12cee3f22befd69b2a723c94fd304c08c046019ca250073957c603f384c28d45e5ec6f71539248f4f37ba5f57f10e1b84abf5721ba186e4e673db5b909121e507f0e45f7ddc5476d046087628249d1266ef83553fa4ce4c679cbbd4fd387a96ef1629666b5bd13b0f18ae4fc5ad187078a4f6cd0a230062d3fb3c35ce6200e9129b8c5504f0ea779d8f1e157d248c27b22041c4d5e4a4ef92398af429a45d916b27d9a59e2a7573f97e1735d71495c589e476ac4aad31a6175746940af39c5efe23f094a640aa65b61698e4a99447e945491d8242559c312e727786f519abc49c64413fca51be6f13e10b683b81602acb41f174df8d47cb89cdf18e49a8c01ed2cd66b4be994788a97346c942b490cf1f2948f7a71f41474364f1e0696463ce1f99d2809dd696df0093b891ec753399d98213a2db59dd3391bb22e2987414e9e304e4fb4101d06a70bfc26db356f9ab99548dc64469093f5d9f4a0d8e4b06b1aa2910e0dc285d3507070697ad59fec43686ac66472a69698e5cb24ff318ad564fa7b60bbca64e3d3c9e216a19f98d674981e2e61721c04d390b549c67c89d9e8a555dea54fd52513a27402309347b825bf5c4b1391965261b30423a7586aa7928e5772297556f2285795623a15a25223909729a520a59092dc0713bb7d285d913f6933b52cec241f71d268b049d99d49ec149336da25bd812cc9f0a4d9119414a0e2b87524c95e48ca473e123bab30d4483760a48dac489f98489893ef4b2017bd67798926526402e30d94f37021f2a9c5f653633313ded671085cb68d79529ad525917c4cbd1a51808fce2e9dab3fd82166c537f5cad5ecd725354933f8256da3e9fd49dfa3f309f43859f0a108987b2106774b54b3831c2453846c4d739d595c97003ef03a3cf0d56d383e707581c26de03399c5706af057044b33230adf6e98387ca40ba9288e1705b1b94d387ca22ed4908937037a3d2501fc15038a35d6725a3090ba4a07b608a411862faaf59194cff3b18a9537d24ea9de745fc59116240fe5681dbd7ada68f40b95a97369ea6d44588e6c9d5528c0ad2ec227f01cc4b621b08fa8c5e3a0266b2ff4a10a6a5abf88dd7b932de596292529030407f4064307d24bd5d7f48c6bacbc5ff152e393910f35116a69ced695285c64dcf92c2c5fee7cef844c9d2c82bae56345892b39345969f21e34a53bb1c5eec00ab95511135708314588332eab6585c5e3865c1525b02822c1ad96882b6ac0b8c15eb844394137171ea0d84b94256c700b5cecc5dea620b03405212508262ca62bbc6a4f35efb5cfb5a9659a46b3e9cdcd5a78fcfe65bfdbf2ab27bb74ee73d862ec6129644ab90a9d8ceb36f739f8c5fd64617ede0ac6c5867e397642daade538b461211bfe21894bb7ab142e57df0a97ae7c661fdd6d4a6ab24a49bd24f34ad972f76c4eef2ceda9542af5a1a73ef575aabba3478fdede6c8332aebc93d22ff48f1f673f8e8bfa261eddf8b63fcbaf8ee257cdec0ca5d28dbf55fab0252efd5afcea55131bdff20eecc6f81f7998a86fe2bb997813dfcbb8ed65dc327ef6b7fcb8e77afbe637e75fee7ec2628f5256675dd9b55a1bbff0ef066cb19b77e8edd5e5573ff7cfdddd6f83a93fbb9b7da73fae3fabcb9a5d2e3667cf97ffb3a15f0b43b888dff9651ecfc065afb89e3293547ef6ec711fdb1517b9461ce99f67d28f66749f73ae7c224e7c9b24eccf67b13349c68a730037491619e95ff6f7976d73720d95a6346e8baf8e405cf65bd63014acc6ca56f0ac3533b9810041872c20e800820e6258114a33ad0f655428a1747c289d84628f8d9d96524a29a594524a29e54ba4d873e3e5cb24dec9f1f2e516deb17919255912876421d9817c761279a49393744a9254249408443635e170e577404a0b4823b2888cf11c9100884092c81c7e066244e6f0cbe6277cc35f757c61b51e7ca16d7dfcf19337c618a36ba9acd24d65399aae8683558d1c36379e7643b26b938389584802611a7044b1be0e3e16ba01631a7a70b211c28a83a4a6a2294d35380abf8688901ea9c6aa3a40f399e1380a0f311157ea54c6168587988869288a4d611bf8c9f4aaecf8def13021ec10dff09311cee027f1c37ae4015ba72dbef4e28d328abecca4f6526eb9a14b257ec5d78c296f6631a16128689ead2cea655e9c1950badc35b0f1c30e6a1cbabf90bbeb4be72fd6fad52f9bdddd5e13b3babb735679ba7b65cd49c20fbf5ca9099bddd804441af4091051549a80801a03082cae6468d8796313104ed40ca734aac7c9a4db41ca9017988470209a010e4e30181a020316424398103d71430c4549d090842403111036043595200a94214d9e9c0c8921a8088d864c4b1049644b4f2c8d7a411028c01204161c374e21840b34d866075593ef00c0d1f1cfa552a94208a1c795ab95cb153d9b9487c9ca5183c58a59d7382d9bdaa77de19c4fe767d369d024bb7adc4d7573b7e9cd736e60f39d55cbc565d333a7ee349bd3e59a9e3975a7d9f4d66a7048222430f788917b6efc8fc5aa9525f30ebfc7c8eddedd3acc3f6877333333a5b981c5165d94524a5fb058e479cfe8a4b1478b3511c7c5b951a5c313635575d55aa329a65b4f083d52353ef67edae57d7ed5e2629cde59fc79aed21a4eb09492a5ec2dc6f84d9f9ec5166d98e565adbe60b1a79b862356666e66e64a9d6ff34bda1591b5a613d2cfccdd199759b594466bd63d6975af547677b7cff62c7377ef9e5e7777773b875c08636477777348442dc57534aa8eb3a2e3b82a5d2ca6e2a2560315e5bec2921faf392704bc1a5c8bc562526b58675263a5cdba69b43da35b9df3bd5b6705bc85b06245bb3047bc23ebaa5bfc626de3624703f59471db0a3a30d8e6fdf8c462345365a17c851faf17ed3a212cd6fc7e9aa9af517542ec538db882c681ab33ff99545ba159ac9a7d67b552af02fc6209f08b57e0324a8f54434d407889c506c2881a2a6134018695312c53d023615e90420467aa6879810a6230b941162a3670c2073080a089514d805105132d351c25b144071bc218410c2b30a28ad309b5c2587063e45c0a2a9e60c2a5154d54a25c7eda850bf510c6fce01de94ccceae54ce71f7f40baccf549ff10c3ed5ac3375d11382e053158e2053d08f1c30e5a4425b898a245072f94ca6001b6ad5578a14273ce2bd77a32366c591e093699e0c8b954185f6e4871e5cb0d2976b801831b47493b6c1121eac68d2b57b6044161038c15286c8099a1e36c1c25cdf082131b4c36acb49395179a6c096fdc1076e3ca952d675eb061c5ca0b3eb67ef6edc3afa98345c2908abc3ee257d19d3fbf566b670a7247c27406107bbc59656c17776631c2fc285bc09af6b1d89a6519fd1acfaae8c73aa113d27df57ec53bbd5a518fd33ee48658eeab8fedaf2bdee99f95f585f56bbcec8414f7b55a9b643ebfe6771e6bdb366fdecd37202ff7b21342f3b2a3d9382fde154299f22afdaa7d5c6543fa5d7e391b7b74224ee41940bc99df6a759d8d1bda80cd2dd9d748b0cb1f3692d26606162c58b0e8b0e0ca952b5744888a93fee49aeb29a3ddd0bb23fed24c9742bf8c7af2f3bdd8c33fe76b806ff8578c8823a322cefc2510d0b0fda5bbf0abbbbc159ff1b6f835a558b90136b0076a6d017d3e823d1f3b23b10ff201d98490f3a91071fc833c104c892686c0201ffb1f963788c75254b104fa784602c87998176f100f4806d120490954a2dd00fa7c4639bfe5783d6e3ec70bc244e9c69ae701f1c63fc70cae3f085fc80ae3fae37cfe3fbeb086aceb3ebc1ede089ef38dff8dc7451c7f494502e9628e3fabaeffeb0b595e0fbe505e0fbe5dffc3feae2f4c422f8fdff1b253808ee7f1c5ae840fbeffa73d165c2fef4f07e07b00b8bc25f7032f4cd2b7fffb9867e3eff3b1eff16cfcd34001a08441031028f64a6c90c00834ea0ff23ddfa2c286f4bfa741bc136a673eef5f54d8f00727a157c7ef78fe1fbcb3e3f9753c2fdef76cfae3750f98ec70af757836fdf5d36d287ef1832086a5421f0de217bfce92cd3ea4412900f9202fbb1408f03e2f3b233d1fe403cab4c801ec79d91989bdcf0714bd24d1a004c6fea75b5ebc36de929bc30b77e0f0c22886e5850c832c2aa241fd144e3045e1ea86f3285cd17861d779e1d3e52c1a1873f9b550164d4a83625e8fb78101637782ffe468101d6a9e0928b1431a4362cadca006203f256a9e0fbee0e288a0274d9cb002e4a741fc5468030302f9587dc3dfd3e380205f70880209f0c5bc0876191bda54d00efbe0613bbaf1bf6c6040a52730108136fe95c0d7c53b3ebc13a3086aa2907b5dd6892979cbb073b8fc613f6922de8951b880c6e56f1e78c7add86668a2c6d239c49e27bc139bb220f14ecc822fcb21dc45d161088cd2ddfd3b50b04557363d46cbd280bf3c0191961b3eb8710a2c48b878c52fb731c2401d111851207f11887301d85fede089ed2d6e2ea374a7995f0accea1bb03d9b14fafb06fc69810d63d3f5232a380fd0921070698209e4f7088001fb48bcc116238630d21a02ec8f79bfbfff4f3b331b19200a2bdf005facfce8deb59ba3ab5616abe5337f5ffe4225971621b927f7b296e5a3a3638027acf38e9c99cf963146692d0cc6c576262ce2f0c3982a957a6de5d9ce1fc618b999999967185fa831738cb1ce99d1d4cc68addb0d2ffcacf65cb76619b59abda05d7aad53a49c22e51429a59453b6246ae6b365bb7bff64ed48751d6d7524427d7c523537b3a6cfc251c345d5911c1e7747079c8ed3a6e394d2894e3a3a3a1ec4094103668c2c55ccf0004516284a4ddb132254888ccad4c0c4851958bd4286098bc174624b7d138da0a0818809a6a46125861fa6187191814809a09cb8f04483926d628a2b3e541858afc11250c6d8eec629ae30e1bcb03434c8c49051d279f1bb4b0271c91cf91cb75ab94ddffe422565748b5e9f3e373abb7dab3ea7eb70f64df339dda54f9fd37d4bf99ccec1176bc9b031245a2d2498df2b9668c51063aa38b2ad238670c2459e600b1e35f6026784c609c25c6647c1d075f75a27bbb73bd484f20cca33280722c5c2aebbbb4f6f67a876777766efcc8b0c2a870a6c987511664abc13724cbc13665d7459f22f5917128827c91c7ff7292377fd61c9000ad66fba2be9546139f5f58f6847b437425fb399f4cb3e23dcfc50e89e4bfd0f779e2bf58d3fe7f966a9e78f8364e7c745fc72f7df5e7dd39ffa8052f49780b57eea8dd44ffdfc54eae907a47dea81e8d75f02b646393ad4ac9d1163b71bb7d850f515c8de3d9e2273b297dd0218b47d938596524a3f2eea9bec79895f59f69c65af534597aa8a3df39d87f8327db978fc604963973a40f6489e189340805c1ac7b8347e71e9474925b59445dfbd578e226c8cbe8af321426f9c6f24fbf9d9b891f936ce0f64e3cfbd3fcd47903f23aaefbefb806cfcbb8fa0eab3f10f05bb04fce18daa3a1c24fbc345ffc558ee46df9c535b11ed533f440b93788aebd56efcc84920fcf455b67966763439ab61abd50be58c31562963cbb031ff0b16e3d16c0d0bc7cdb3b78760a32b6e5e7a37eee6a45cd918630d5b9062dcb0e62671e946eedd8d5382d93186e084f5eeeeee7ee194e0c36e698023bf319eb16d31bbf1adb8af4a19da5499135f5e56bb7c66aeda35b7592e3bfbfad04dc2dd5e734fefc832a3219b95e38b520f64b35639b3997d4c458e39f31dc8252b993d67e633f3309ed129b341d0b787b022db8ec8b2b89485f3fc4c1572e8e7f49dce09844a9a65dffeed37e36eac3c9b8b7df9caec5371a31f9965337055a82dc4a8b0f34705253125ccdb5f55c21beb5fb0980194acccb82711786194e4c46a3736190da1c5aa6ae581853e7752b9dd5a39bb42426823c2035437c40c29256e8a0d1a17a68d48a876894a55998106aa94a4b560094aa6045185d5346898b0184c27e625c98b12dfc41b561b069415106561830f4f96600a228c10911ecc10f1816875835416b6e6c629acb8200c2b4ca92dac38b1155951828195241efec6299e98d2d667b79cb32b96d6da36f7e92bce39e7ec8aa5bdec365babcab9acadaa43d656ad3ab4a6dd33cb66d756d5b1b5d45ef35edcaa9e758b7a7bd6b555ab777bbb675d5bb4275b908886a2ca4012719837e6a0eeee6e668f13a2754364a4617aca48d1532666d9c7fd5996655936339ecd5f8db2a3d3844bae7c9692f906ef597b08005c58f931c6e8dcaae5edeecdc4265fba609fc53be18b2ff33cc84f0401af2aa63cb97cb71ba494f24a17632b9d894273a3d2192635d88aec50444a104ab8421a75fbb7286d1776b67ab0f2b72049369c474912acd6b258ff9a4f50b73f9c646e73ec6cb6d8b8d4afd73f8b556bd3d7a50fd3a19452fa9a54b289f3682acda5793493a2c2905f0384ad93ca0dec0e141b32d42cf249c34e2cfc3a616cfc1c508c747390b9611246c249377e138b06fc860c35a9f0eb0636e449e572e4b8bacc9fe557fc6edb62a713c64e2a04c862e5a472e5a4c23ba1bdd10659a5a72e4b5fa4138be11deef89795e4b364179b2de45bf92cf9711e51223a191464c3c8f4d328f08ee4970a488e48a002dd33721c287aa2d4451630788812b7988284123628ea12c507a6255888a6c8524498166c310348420e4ba4314317475a9001f95168fe23cddfaa4228c80536ac95f562d6894a506e1897b4d75af64af7314411444c7cd8e10722c07e56e45932a50b2f465fba404171447f8d9d7931a2e9c6a6229a746e6c2a62caadedc33bf46bb596c5fa072106cb5fbab04e184b73d48c0993b0e6b1dc3e1b13e8cf1f42812ecfd492cb5e12bea92f049953bf55036543bfb59b1f162b7726a4eea4998702e51c0d40b2486237dcc092cb9f7d96f11695932ed1f67c74e5d7802d569a611d9fdb4cc442bce5ceccdb8c0b354ff7fc4ed43caa67f6a1cb3ea3906614bf10a0eaa7e119c5725a8e956a6f9f931e45d1a31a58f9213dbafc5a6d7f2226aa511994a7d6bb7e8890f0c40395413123ba69092b4660061a4d8c3873801b4e20040dc698e11466490a2adcd213151bdbd05116da08788a4e4d45105d7efa71631312996bc5a44410638c71c5b93f1131963e896c3daedf5cff81735db217c290c4bc90b913d2efe1bcee92c5c0e2eb0792181104cca7dbb305192373dcd7affee057915d590b6b1d3629e3bb94524a195b5012c6a8ebed5337d8370fcd47f9c1224e1540a8809b7d44e1662f9fdb6c4ad3b48fc537231461fba12a654f41971548a15d92f882a64990a3294b910e63801183267cc874012385135cc684e1050718b211d46c36b856968b1cb7d520a58c143001834b0e59cce0a9e0288b2845445001c3c4458c2d39dcc064031644f12207141a64ae9811262a4b0d4de812930caa168301285cc0524314146954e1812f98a85c01c39723b688a95c0460a3e1870422084869484774585cfe9c3edfa7773791516c5b8c3d1d63cf39dfc3fe6c6e1d638ceecf5d658bb9c40cce984c74ad34455d8ac205f2c9f6e4b2d118274da6b022240618da26a42b4688e102991f7238434888edc626a4292ed8e44b767257ad1b9b909848296756460762babb334ac4179b1b9b88389a734e5a8998d244c41321372a3109dd15bf687cda55ad490b1a396e6cd232a60579a6057926a4009581d4428b9313ee1f224348204243460bd36d9e1f279ab0bcbce02ac39bb42c71f99df52cd78d4d5a4a70e78d4d5a78b8218b291574bfe7e36ffdfd6d6fe3854baecdcbae085f9bcf6c0290fd1317eefdf475efd8f9e76f28ded1b1e36527e4757ce192abe3bbbb7bc7c74e888effe1ee04c8eb7dec020080ffe16d939d0734c8df5d1e0b1e7c741e1edf9617cadbfa4d729ec7a4e751097d79d43c0f6fe2c0810387cbe5d9f8d8b5caf09bee73baefd1bd8fcda5fa2d935b864817902896070faf03d72791220e0fcfc66f2c9b9b86c9441cdb85089b223284bdfc25b708e6492cfc6279043b415ed8278ff8c5f1966183628febf25326b48862e11d1ecf4f8f628feb19c7fbf8707c8f2f64dd0dc7e77ca1bd61bd5bbddccd87aacbe1f88debd1c3c7e77b7a7c011efc9ef7f9d8fbf8203e3e0da400e47b3e05027c90ef8937c8c76c7a7c557e7e84f7792ecaf9c27af3852afe0df4eebbbcc91471f869508de71a1faa6e48836a7c587dbcfb3f9ecf83de7479343fdf3cf2f1e6f5a6920d3664266f62431a74a9107d4283628f8fe7a72ec41e119e9f864002e1797eca44290261313287bf02f91f02fc7c4005f8a850dfb09120eff33e1fd0085f90cfc665538214e1e5900b9240698397207009188b77f3e1f575ce470f4fe67812ea8663d7f1cd8db7f33dbc017c8ea7f32e4f5e566a1e1a34292b89e1f16416f2c9935c7812ca939706cd23fe48e7110db7d54dab3e6a369b463e451cfe1b2c220ebf085ebc3ebc786d5cae20dfe3fa0802b5b68041be27c64c220ebf8fcf67e3fa7e8a3d37cfcfc1c7dff8368dc0ccd5f13c7e63bef96850102f822e2fe6bc7742aaf8fce6f2e48de2ae3e9c47973b99f4210d72797c6577f3d1a0909f6ecef333173c42904fe8419f2f2727c8badec68734c8a35bf8e5d1a4b845a6a9122405090609723114db781bbf45e9b16f6e3c891471d8e5d269c2b25e4808ffc3cc24f6e4e4f870c765b158ac8f9175a3c7b30fd7f308cf37af0ff9daa02273f86dfc56b90078a1bc01f8adc7c74e888f9b2304f8201fbb1480bccfc7ce48cffb7c4001d1c51f0b32080a4f2a3e6dcc35c62a2bcb2a83fae90f09f4ab01c586abcbb2bf66d1e94a09ab1f5b90d52bc02f9600dff0536f851400c91ea094e12108045212c1141105a65e894a0c0b96c0edab27811586b0e13fe9b87884c803087d2ef3fcc0b844676234bfc983db67943d0f13a3fa4d1e4c7d46f459c886486217e7089c31f6ea6043186c9b419412c8c384824d1e34aacf1df1a9114140f694bd263f584e1356057e19e1172fd9303ef553f745ec915cb378ba78d3b1c50229792746c9856c2fecc0955cbddab3f492f4a59fdce2a7e733194ddb9da3977e985dfae1bcf43df6744ffbd2afbc137becd397b147f5f439f620e12e7da75e9f6638f3551e8dc71e71e6731e4eca9baf79b3caca2ff7ca65944ae79fdc751ae9429b6f3535db26e7a281e914f1627c31b3b7c58e014b763872810c113061448516207bda17729ee4819070d756a9f1b6c6f7e21b7f15cde77262397e798d2f4dab1e5fda6f3ea9363b05f84da576522ccc4f699a46b5aec8fcba2cfb5969f6f1d22ccbb2af05a3617a440d97dc55b844bacb2ceb84b45a3eb4ecb56aad58ad17efbc8fb8f381f641dca1f48b31631ae39bfed7e1573f0931b0f235ae3b054c5aa9d615995fa65db1a566aa59a652a9a8d1f895ded9acfc922b564b32d324e7ce32f739e79c53864856d2e3cfc52feffff103487c452ef274ef1fe34e8c5f4856d7dfc5af1f33b0fea1ebf5030624ee8810a9173df396772c96538faf56e996daea2a353bab553a3b4f8991bf08b1274b7dbf003e84d853bf9fdb5e7e0eee8bf3b5ef8af8c76d59573d8d33bfee59f6de794c8ce6bf9081201122cde817e7fba77c7eee915fed1a4df4ebd9eb4767fe36452eb0ba4a5b14191465431f5a9a435366d1f5f7a7e64952e29ba11964e6ba475d77a8ebdfcf9827be89f7678c33dd9f314cb19f314b44d75b483611e5928c3dfd2c564d8d6311f22811c7a5c41b7f2ad77b10e3fa902433c4dcddfc320c1bca2519d8b0854a20c34625216ee843d78788a65c0f5be828296ca5eb4c43bce4745b7296465437442e5df985f34a6ff6ffe9e85f65096480d57e4c6463d86eeaa274fd4b10a3cbd1751eb67ec915e009db802df665c78008ce4e48d74f43e3859bea554250b0df0bf6b7ac2ba13f6543f3dda370bbb7a1a1799aec0b971cddee0b9144a6cb420bf343ce7ebcda4b14ac7d189680f683a1c6abbeaf85f90dc58d6e339f7e26bcaebfab4acdd7a8f99cd88741a552a9542a954a65adb5d6da6f1203ed2bb12a954aa552a9be490c547dac312c3f33775c83b6d825e892b9f26b81a27193f0070ae053e6892250491c238b2b37b49c804a564dc0fe9a98b9620a48051a5e1001c534ce18830854428386f43863d8f24212175264124e76c00254129f90924315910c134374e90254129fa07245524e127f25c02f39c60f608a1acc1827208a523471010a640f4819709b1c7b91064d60012a915135b0c0e328d2e0218a6661460c946a151f8840f66ca400374d053a38815b4a89a832a254006e1bd75e1c63872527ce0446433081ecd93c815bf7431292120dd79e1ce2053a2481ecb5a4809b4aee6006ea085432c20ab488f2bae02c5308c2305313849427a06a30e9c1a88803ae3d8924831822903d1d5ec06dc5746688241b529e28dde8e2844650074e3e24b1b8f6a21249481481f287303118021988282b4c207b3949809b0dd79e1ca3459623706b71edc5289c8832046e1e1859d1c1b517c164f1610ac89e4d0bc06d07d71ed00e14ac000a5412b98c3182081b2c402539845e071b28795c7b2d02a22e86be1bc0487afa806b8f71f0c28722903daf0b10a8ad40aa8109324025236cf912a5db63285f6e180279f008cea8a204b2678305a8846536464c41031b03d92c801755a2c04d3a8941c9c5fec4b2b2f6581187bf064a13336006b48501662ee35442ca32059cde1606185ddccc489a9394923b05623abbb1498b13f2ae22a7b14517d338716bdacfaff5ca6e9a409fd2ec047ae6cc193345e8993367cca822f4923e8d13123673b3a79c0ba922f460ead9ab92fa94b019d0a8feec4aa845b25bdfc68459fd6357699c1ccb0916b6c98faead491e3112432da1228bb3455b2ebb2ebfb8e988a0cb0cfba25fbe4d7f26bc9648f923cb6a85c11a060b63e5c7ebd4f9e5c702f317d266fec9ff2c64fc82d5307b58965d16b2d789d1efd80d613acc23c1d565be215ac98a60b78afbaaae3fc7efef1c5c7963c7c1b562737ec5f826cc2b3f1a277ec5af222b6c661b11ded13ef2581eeee377dee6c9a07e1a237520c9440ab5fcba0ac7ec194bff2999b9f97540061bea705e05f8a62530021a96d3e122842b6ca8a3c42c3f671fea43f418dd63f4e8d1638cee2e70915f72d5b2627fdc79711e98cd360f14377e967d310a208c5f7c96b0f56de8ffecee36aa9f0d7dfab53f3333337f9318c80f03508a04252862045256f0c41410c83fdb37d2dddddd9ddd4eefeeeeee6f1203fb8321f2cd1256323995c316b9a74c4f999e323d6580ba03b75f973d299c1fa844cd586439e81091080000000063150000200c0a07c4016138241652656def0114800c6d8e46665e369849434110a428886108328418038001c0104390518aa84c0022bbf2118ed4465a27509d35a67b9de8ee7649978c1b15e92f2325e8b7e0a9629160286172406da3f53e01b25c592b01f602458f56546a21c20a9bd2cd419436d6a58f4aafb7a581c27197f703d7f3c807dff3702785d228af3caaf425a458fc3e431d3d51642d780d78f0e195c6a4e7420d43611127ec8808aca7415b61a41ff60cbd38d3ab89871ad61955e3c6650f22ededc8e9eb72b538356323d7255219755954f055c656fc9d747c4755ff022d7133d0b1611e8205b25c43bbda8912dc61be8aa46845f2107026c84fbe8dd50c3e2dc310ae392d96ee211845740bc4d46ee815eb6c2f816dda4f47d8fffb0ea6c27558750601fdb524050d94631f876b863cc6135ff4cb5f22ce7c1165a3a1e31b97434179fd376ee3108171f759ac0f01d33fd3dfc211bd0c7f156f1a244f14394d0dd53fe1882757e344819f28703f2ea37cc1a3e105fbb1df970b656c40e1430a78d418805b4a9e197d5019199158314908c06d2475a4401ec1028631425d6546e6516e765571c7724328593a541e43b19d1a899a5b2264feccfe20f44d6dfa26e7c378f8fcfe1fd2f30168bb4a12078ba43639276ea6a1be030b4f79ef985badcc7bf6dd2b371761b440f891049879929d4d3b53a659a23194d856ad3be2bf318883c529a5e838bda5a574eb21211063239ce3350536c6c6065d44c45558aeb5b7656fccc293b9ad81c11b9b84de943764db4871f748021ab5c459da42be1972d372f381129a0bd3265b16cdd4ab1b4f1cd89f10ff7f0189f1414977b43d97ba77e327e27c3ca057431658fc2c36475c7885694aea2fdd7ab82b0023d55dd9320b64cbc6ea32622bc63345482de4937104545b2407eda05284e3cbf6564db49032530d3490947457bf26a2f30ff90a6995b270c8cdc1f40bc15843a3785bc5fc6192108db6759cbd115adbbce76919fe4d58ebd9940a770de2742c1d05fc0b461980b3a2d1ee8cd23cd69c597b86769e45a5e1c8df97196f01ec6ae6fa03f2096b144fb2234737a77f6e11993c3ae1be76196afa77fe8e53e6ca3df0af994ed698e026c654fba971125ca1650221f16b804224b038422db9f876ac1682849b26df7b00155b57db196b28ca21ad4fe53f1c3aa1b71a8a75faf17d7c6ead41a5980259afc03c0228814b4bb3e18bc19b693c5a705d161634c9b8757c43b3a2b7d224962bf12a8f166df303402d1e60033a2e2ddf105010970165f009eb7fa8ca0e9675392552bec667e8666f56b355c44aba6cb44c1ce75f983aabdd1ca45f740222496dfc9d3a6890d07046332e640f4fe193380a166d31cd1d1b48e27290961691c4dce37860ce89a1f2197e753e6d46125b11ea2bd68eebc0d88adc80f1c946cae6acfc69c71818eb5f7e0af66eab9463f27df9650ffb6708625c32300d07f8f3d07d0236f00f8ebfca9c0734558ba5d92562c6b6b3a27e0b05b13d337c84dd74a8c78cad2b8822be32760ab45909d5669ed9d47a898d6a2f07be67349ac1a476a38cd54045aaf47ec30395430cb81fdcebb47822293a8f0ff122597fb91e6119ead869f6ab4a78cb8d21e621a1de43dee96dd71e56e99eb1fd0377ab8ba9518eb68da2eef1769a52f2c4505769b7a1138b109afda393c7aa5e3e90d0f14a4c9d9da81084ae585bbc48cac00a41b9c18e355f81fcb5ed73cedfadabdef61b50131a6e610751752f0f34ac69f6ee963cb1bf9099e06cfd57c1d4f1ca5073383d42e6b124fb9adcc6c108cd9d7dd585229c4328855c77e7f26374eeb4b2f09222db46b5b83be42839ceddc108eb5eaa1837083a96eac2be4fff0c6e6cf3c8a0a07e89fcb111ed1080896d22a11146679aba3c08e108d7e043cf0fc0b57970f70e274b408586050b29f0255f22f962a6f13a89970b5191d4399ebba6c5e6b9598e419ff8361a958f6c2e123f96e20a523c8f8da105f0be0df778c4b217974dae592cee9012b8de42b9d64f167268429147bc280f6e633703f60e4f268037813d96c9d3b5d8d37879d814c561981b536ec423b9b2214e19806f2af53b840321182ce4ef087250d61caa1376a8a369028ed8ab344960104b717ae84f283e5a579d65af64d50b6385f36938805ed854d250e7a734e348ea20384958ce872eb60b06098ac9c1e31ff50b1b08cf3c06c3d3325ce2342c992f3d441ffeb4f93aaf29f853c8a67aeaca76ac5d67e123b56b9f4ae03ab48cb190e15239c6af3694728f52017f4d15062740adb52c5aabf97feeb7fdb7ebb0f64bfd02a320a83ad5a29024ee5a361fbf194eae4f694665a3684e8874594548180ed03e482748fde598caf700b1854b02c203b30d11c87d5e1bbf12bb7dddd6933d66e6f8893fd76c0e69c2a01db8406830386058349dde226a0bb411ad0f616ac9762e444176e3e2acabb21b20993d2ce571fd0f820d3b3f8131ae0fdcd0930a79e2f759a24e70fd0845acdfce54b2726dd0cfea10a39b39f8ca37615b85917a72f0481843411fb325b214421c418556c7b4573c1d007cf50c321d516ed82742e065752284d2c4c123694962fc20b22ceeeb88959743d6cf4ea6993ed19ccd2c9531c366ec47d087095a0f5bbaf19c0f2868c3493553e9235924adb142213af378a5ad5784d77f58b2e4166dad872f769abae98922b02088b035f68e8e62f7b517a2c431eeba287f0ab7b02913124d23ffd1454734fad539770ab29d593fad65b78f66ca33a83ec628da80a1844ef4567a657b925ac9bb1dac8cca067e911737bdd1abad80b4e2de4b25ccd7e580d703ca4d8db6d9105e55409acc17bcdd37c075cb38d29bc0657343ae40e34db56b5fe4d30d93b0874055c9a2960340634761ae889ad135b5dcdf6907ffa685cd25ebd89e2bfd6a05a4bf7490052550ad80f1c7bb946ad9d8af1c3635277cbb57bdcea20da98aa30375c6f249a121f3ca941f2252b2ef9625873f2bfaa6f79efb174120be2644567f679819e501964e542fedb2f0a65c0dfeba047479a7c4156183b13f53bad4885bd5adf248fb592862a186f9643940b34025aef58c402c66d3f3bbef9c8260784643bc255352490a2a0f9d06bcb7e9b388eabb53a51ecca63bac84493c9bb13e05cd1c73e48a7342d8314c8a84a81f66bbd7b660ac61cde0a8b4c13b514e7b5650eb040fa8da06da9e4475a3efeb35c5721429f56a0e30bbe929c923b3b247a01fc00cde255649d27e61ea9cdc7e42133cf156bdfc2068f4dc085c590761487b223bf1ff99814085794af57373fa36d4fbb7d7adacbf3daf20cd31a5ebac13ba2ec265cacd5ff08a873a53f1079a0475cef685fafe4ca7c15d2c5a80c7cd37f5cfb3fb581f06be2782a05f7f32c55d1c5f8a9352fb1cac91d6862b1f1dde0e47e6efee6f3881909f109e3589d37c0e61735693e3b9d60ebf4f4e048f8126323eaa7cba552c5ca35a2e6396566f88620d559c5802a94f1626b2fae62ff150fb137ca8a14fee18f5b801fbbedbe997dd3fa5a071f38636dd598af12abd62311970e672eee9ba24bb7f7200fa86251188d67c3a9b386f95626d21e17f0bfecc6348ae297dcdf2f7572275051dc15c382044dbe0c958c8a9f9d3eeec197da486405fe3fc2313f2b17d8f6b66bc028f65894072d706b50a92e08b781e1ed68fedda5b0abd04149c0192c8c525f7201c692be21e9eb6fc0fa3f91df4ae7754796f6438721269c0c1f15a01c2ada8cbe21b0eeab860de60fa8e3c267970311f343f721fa948ec1d7906b3a420f86ee2f08e2cab670995402dd7fc8ecc3b96eca1aa9f7cd5471e69862a2db296cf047dc812e84221c382fa6ba1080bed3ea2738c68a17ed1c1e73a8450c39ba5a76d95bc1c0480310e91aba6ede028966a2912b54f32b6a26c11a381aefa35cd7776c574c532e9321d53cdcf9a676c2726bc2b2751530f8cf4831011fdf1918360b5203f607843a47d5751ea3c100e8bd282f5ab0066127a943947dd417ff1518102572aa19cc8ee1809f824c4286e4c801241cb50d00e16c7e64e9304c1824afca814f93d4b850efd865e757926adbc71994429f02e4e3740f7b3ae401701f3772a8c184ea4c1f56b857c962977d9d16f0b85d0eac65790bc205643ae6d7ab1eb81269e52b68c1e8293bb4a806f98049eafe0e2b05fd935a72488a6598c53db4ddbc19545c3ef99a40bd1b3ecc28b8d17a7f0ed4ef451f60728e00d40c7438cd74c69040fc082679a62b3141e258911e2f87ea16a76152dc61c201dc5046b7ad470e8dfb9f0ced081c9950ddbb2e6e0c3d580827ec41840449023fa125486673ca89092ad84e2512da95b4012ca1fdce9a24e8082da0484011580cf29731075bfe104bf47f80449c3b60916211d1969915b388e27074883e1726808e4724e903ca327c2d80d37743dcc2b449a49e8a413f208b07439c578a0a96a5427f7939693ae72173370d4953ef06ccd987600a055fcfb2bd16dafa020312fecdedd89d39ad0e0970d8d6ecc50818afff2575e1d063e2579249a8fd43f9c174d8e6cbc5663f05b23707d67ce37c48e9d84b4cfdf30b0d25cc8ebc408fb957c1df338766697df9f88d4f1107f9a0f020d0c0150ab62815950390446b2c64fcd68a0fd943709e396b6e99bfb512f8de00cbb12100ba00f09addb7f4e80a22cadfdf5de41f21dfda398ef9f494c3796c358d88b246eed4177ec46c34444486684fc8ec842afc9ad799cf6f3fbdff7610987964f43ead0851c70fcb5fb8a3288be904aba9d9fe14a442e7d565af7549cc80d993aa9f6cd6df644e6e93b96e0002fedbcd5846741ee031f92d8fe894d80091120647f4bb619e7c32365f18a0f1b40fee786231333c8e20a5bf1fbced0864aa01152a2c540a9fb3764acc9ef388d855cc0f359487754d9dc1d21129e5f532de3474acafc6d86bf85b1f297bd4a3b10880541da0e4e86d6b93810115f1b18c0cf8ccd8a9a9857db1fb41a402d0adb94d9069080291276a7b0f5ef841bc7d62b7b96ccd6f2d5185b563799f808af7c99ceb33103a203a65187075349269edf54bd9f76a0dc764588d0344c674719d4477b6cc1cad7f7c3bcca9b374a61420b8f334eb45cc9c1f6b6c9cbd2a4a962a8704f4b8c8a08d3ebaa7804cdf9b2caabcc9e44cbf4d3cf1e7b3e5343d240687b7107bf1f1825e574432946061089f6662dafdb66366b0ab6937b3ae8f0c941c15d06d64dd35140559b68f6695889a5bd987df32d24174495ac456c88453f09cae14b33d436c7c3e3e53183ffa64738ac757742341a927e4468890c3dce74e7cd27b74aef63200604ad78ebc758470bfd3a821d82b0eedb7aa4c93c1025925e047bac6d8b5131bec75e7d84bdfc196f51ae2270bcaac5822604cb0d44f3a65d61d6cd5d70d38ab5ec6272527030441ae8decdaf594c4ee69e334998fd9c3e6c84a6dc5e941144ce450ba636dbf18146cd3318f3777095cf4a432f93129ebb1384f088b21eecef0665cc621966992801b32949aa303b0c4e9743a2de30e4b638b98b5b1cc430ff5fd3b2293ef7e6d798e11d6a42b6ac9e81273471c4685aa2a20fd0b01bed53a7be34f16bdba4e92741f58aab4c0641a6a3842b193dc3522dcfe0b10bce7cc1643a09bb7495be25ac74c50970e1b79f3f1014102186c7c3b7a1346d7e10af3591d7f953581d0354ee48f93358585e7f87813b3042030f1b84e2804ff73a5c22f182ed551e5452527fefd7729eca8269b7585240149c11b4989f33c58df511fae285d89552b0cab6845413fb9f1e34e945461b59054d1f88f6c69a40694eecf211af999ff32196ab306a4d42db703a00a35f2f53222712ea389e1b87daf63e03fbb6affa17101ca21dfb56e16b8a680435ff1bf1bb519229fe33d11cff647cf63debd64bb4291ab5c74fbc3effb965204465250675184ac1543a19a47ddfce78e65909add83ebbad357fb0451bc42d156db031bdb044328aa7e5624006af128c229d42fdcae25c9e833acf89ab3a73c53ca8459671324f5afde61e6e23f6530207b1ac3dffd5570b3b5faacf64f0a9aff3fefa21147b8fc863e824d10c764fbc48748dce0a9b74cb25138945984874d36b2d1e3b749f26b05e962c84836825c55fbede0e9cbcb130a3bb9254a90c753f4d258a2b69a114cd456aac018965aaa9f478b6366e7661b553e0cae8669cc26834f8f5b0d2cfe6bfe8aeb7580a1338aa4114fc513813da4e9aa2e3fa35b8a24b7337d24499f28f3e518bef050ec499ba239c651fa99798496285065d3ff0c161466cccb33f452669cd53ca3ca6e5f5de49eea71dcc6d23f730d9919e1702ebfdae2018c200088b8730a5b3a5532a55d5b9540242a17b10f99ed621f85411df1311806e4b495b0412ea9897d94ba140b17d28f73b53686ce0b693f0c72fe47e6d8e73a1fb439c177ec7d962ecbd72e2c87da21dd5f36a9b025d2616f73d2c01f004bdfe6c1f9b249f5d5e5165f1c867a9163f4871d6bc526b1df6dd66897ecc7f8ed687d4f924b5d42f3935e00fc9644845895fdd098b61079e9a3fbaea4738eefeda5a4e9ff994bf74ab2cd5a8f3e0225945555b14640a4e04887289e15f91fabc868824f7f01c6df86b235b7ac69ee925493491641f6e6a3a49adebc7485a2d3af2c4ea4eac3727e2626fe98255c0c39389526c8a7275227957c7881816d9a73032965e0dc6a87d9b95b073478ff3eb94d95b526031cef6fcc72a1623dfc45116e81f959eecc943feed588f12abf1de89387e77a4d211a8941e38cf24c389960a03bb9cc256c3f9ad5c0d7c88555fc0bdca5118dafd15d76301286c6e178f441442093175d0f6a3933684032a7338fe9d8ae6c661b5a8eedd5bea56aea5ec4dd06e38c0c7fed69633b786d89ec3c78d77fa6b170664ea3e3eaf81186a5acaf63989cf59fce66af1d3cf695a8c4c3788efcd2d8d9e4da5a17b9eba6e7b46f2dbc44e8f74c6a7d494655c88bbf79e247239fec11ebb58453e79768a43d9aae22769b1ce4a375d621d0b940897d4d75a77821007b5c9b2b4726bc81fd96955d0d0d7a7d7ec94822b7c5cb4247200e47c866634d6aefce92722e02e6607843811aa8b3fe92187eee62aad0642a60930cfe33890c9c5838419e96dbeae63955472ef96d360da2fbebbe8ed21dc111b10fd05e5449d981d0db5f539268afd3e08fdb6e40e1819d79462902f9f14a9f6882a294c45a8cc8bc2c3620a2c9e70697f1c9c36d2ee976b6fd63ab6f2a99221f0cb2431aef9dcc821d8ac7cc085476a5fe6c9b96d2b8dd7287958161df25032654c355795a914bb7ec977a2c1601812bea5350d9cd8d211584d8481c717c27c7fd5b6f60d9163a7f1cf57fb83217909a02997cc1ac3544fc3578992f75eb1a09ec245dc47bc868887ad3353dac4ecec0e105fc4cb40907358fb167927197ad743965f88ab1156dce3853350fc4443b4ea42ea587aa988f8943ca48a32455ce51eb75c405d3af73553fc70e0969a82a7061c0689f86664aafdd05737458a6c4d5161ec202a95cb783afe0bb2072f0cd785f972d96349465a3191d13491162a19d13252eaac4361888ab289551939baa3fe6fb7435ca83469c50dfc487431159168d00ff80c0288891855e9ecc715ee2bc1c403ecc1bb37d2e7cb5a108a358fb156a4798877c30cb2442ca07f45dcc45682552b890ae827f40579f09275030956ac07a87c515e84558354e49791d03f6ca54c65fcfce6c2a58d7fb8cc25e0e413e3b72296cc8f76c4da23b1de8d67d1632bea0b8be518bed39902b8d2b15642ce1303189302da80214a34b5dd2adb6890963fbd6f903bb62e08dce0bc8006cb020afb8b756132aceb1569dc179bb71fbe1eaf89d1d8dc8848d3fc75fd958cac53a0f708d22bbdd581871e2a31bc3b69d869ec529c71603a7ab9816fdf8c1edad61798a447a41bb2b2ce24db6043e6aed729aef1e2875492bc4e89f520e2f31dad69805d4f753c7a920dced593313219aa16035e3aad1f6abbdb21bab680ce9080ccb5ff66ee36a804349e124876673f07c8ff793034aa5c8f511a627e5b29cd5b86348134309f6b38c2af09eaafe63c0017af9dc0283c4364aa14ed894e20996fb52bdb192524375ad19e209451c65d957ce257c791b33ef75ec0269f316a63e0b90e9cb84f639f35b4795944e9d8aec895f31a101171d4086ac37346de12b89ed9ec5fa689b4c5f03c9a59a8a2e29bfd15557a303d9cd70d8cf48de7417b64f9fbd207d616b586f23198252cb18ee71b79e63b95382e9186aa93432e4a9cba0e58ed7da3d84c070dbe09701dbb5ee87372e14473be46124a468f540d27747a887415cae160debc68ce35c6953d15ac2705b36b618b3527c70ac60c19c3eef75b74e276e58462b37f5f95895674f33c5cba5cf4c87434c017935222a98172dce157f47ca7fba3eb9b6a054529a6bddace09248fda91d0e603f8933eece81f5ba768e149748ee89dc41081beb2ad5a72292eb58e52a31e07609c8a6f0327bce92216dad5bf01a901a9ceea9117bd1fdafd7dc3a6210ecc79a8523872ed3944aa8f00f189e45b2897f8fb9941e6f629b206ddafd60067bdc3fc7b0072ccb9059f2b3fe61c709ae1b51163858176a2f9a6353e0530055efd4e81d0aa29176d82c5414cbbe0e2731c6f9a3433e26eca43c739e19a8738a45f9c1c5e0c4ab4b1248236da287195323521b2798e906f2ec21df4191c7652058da55554acc2b4e13c2cee52f7252dbc90ed9739f3000042a5d8efed741b3497e34886b482010718ff89757b74361d51eba1010bcf40daa2afc6cba5021b0d7d743f77ba967244a3f64eb4437177ff05e9a02b2ea519e2324b97460f1c3bf2b936345d81f56351c9693f349ecc0295ece06136f4de4b44481e7fab156526baf2440843c2a6aef8c31cc1e68994886b6027acf7a6d88c1e1056c5c023363486715458d5e7fd0437a004954d92423d88953842907f241d23e37b6dbb0a45d4412b154682aa3783b203d6e490b40631f155c965f69dfec5022d193df9b618a22359e1ec7549a1764ea43ab9190548b037de00a8c440a0dc3000e4187603d990e3ca805babbd1a0fb08bb5173e91e2aa3f4bb0d50314df1ccbc9aa51b381310b2b2cd004535306ab8be8bde9da6a7d3468c4157208fafbad34634b9da9a3552353a47f0808390961a011271819e5f4fc13821d85e83a6002027650ae5ca04d042d552db861f5b4f404db0cc91d52931b65d48d465967b6b6391c82770216c3a047165757fd8d6ae8dbd245e350b8c07ad32d3998749badd8883c4491537652b186306f5e139603402867ac3c05c959e00479cb49c6d0312a8dcd9aa9aa6b765d9e5dd8a2dd1134ebde98e7b9e53315026d42be448b2bd1ae1c5f690af16c22d2268bc64e375a8932781382502fd7c383d9032d5a8541b510ef66266128d2f4b369a65cd86352e97caa1969899adec41e9be292c42185e77f540883084a59fa3302741f1c7400dbf088f5928a7e121f6c6b20ddcc21a285cbf96ed4a5a06c9af10a90288ad38ad3fc638d9b5483f9b410f73716ba7244d84431ff37b57b0c564c2d4f1d33f69b48728ecdfe7441fc00c8a66561c6fbea11e109b9eca21051e8573b86309fb8f128969c516af94344e413fc9ce53c12ebe1c10e1fd1e951c679680057f6025caf3888be6bfe1b75121a40a1261e4a5a22172286c3f246b012460bc00cf4138d44bd1d656f0c455113b20ba8a540beeb7813ef98f434d73d8c2e796e786630b586115a16feaa5b2664fd7cc055beca73dee1ff84c2627963cd2ed1cfbc27f1b5a7497e20110a08d5de3de443e15473b3126d751bf5d05e6ad5068223b61fbb4d76a1e2039ae104a8eacda2a83e2ca44979cefd2ef925edc8945dc0405c1e87d6f88dcee41a4a1de4bcc102d1f7f0a178017008e8aca0a5f3f40af31050dda06de0681ca1e04d41c41c2e5aed4be6dd749053759735f3a0f6e93e34d7f7f3b15c041eb400606b20447c710aa5963b0a0d111d2e92f356f2b1301b3463102074bf6e1d0d75b9222641cf28100eff7c32d78121e173eaa1bf91681227049f5ada3698ff63b7d09aaf19339dabcbe03d72f00a3d0ba009c0ceadaf33bdf85af83bd4b7fdac3ce1de0f2864fc885f532b21fd571bce0488004cab728f10b7a1988882ca5da89decfc01fc0e6a3b1fed9dbe13f68531d0ffbbd477bc3ce9e0c84cde0e3c1e8a7f4b2c0a3e155de913b6468c4860d4e26048afe0f703ed2f55c54cf3a7e0edb7d39ea4be8176b53f19ba5d41363477e695d513b4110094d13ea66a28e66432cc5fe4398b50d43d2f6440b12204ea3c9bce7eb3fb8900bba88ece7248f18d9c79e185261277fc60e8e6b31f558d329102846ce07db97ceaa7089c13de6adee1122ce5acec09b51a78a453d572476443a2c1e720a7b7fad9b782e70d60f4b8e37d0003d2196bb2d06f72a1f9c3aa68f10f11916dc3c3e8d1bc60ab6f262ec498713149ddfcca9fdc041b9efe35488efbd4bf7a0ae65b719e95e9b3468022b9dcfbe297b3465cdb4b71f2a8cb85e23cd34bb7068322ff2731fbb217b1a26feda74894d88589645986f8b565cd63aa83f77dd0ef9a3c385053641b13a4d92710d9432f7bedc7d78dd23e0dbe0a07e141c4e62861a0fd3088fb4f0d259f4f09b012bb4c98bcf461500b8aa80e93d264c663bf78e45899bdb7b36ff32b5c47ecd5f94fae177a7a956fc5a408946e60ebb5fda1efa1d63e74951c1e05eb06a6c0ea9f497dab49d9ea25a5701397fe520d270a76a41bbde614523e7fe7bc710a766d5503e5955cc5453031277427b83e97353a18bc4ef4c282885e50d8eb2d1375245c4821f4bd72ee0da7baa6ab7bb23f92c1756362ae647b7e3b050de190d240d76fe0f879355e71a85424de25b4f86175942124507cc18a090cf4bac8cf795864de6f363134d205d17892499d32338daf0bcdc92b485e1778e67519d8e22b73b8c5876b5f3199de921aaa191295a090565c9e37ee58fca20e8b7f2e7af855187aa2b38eb5e217aeb506a0fcc1efa1922f511bc5f2c556b7809664f651083263bae2583f5fda3dcc986600687529da546766ad830fc16408d3ec7917aa22f098685ae373255a1109930f9b8534464644a1ae1228ff47724c44186b9fb8724b8fc59daf8bf6a2a4018d1d28fee47091d4d5629f4ccfe0885893c6acbed612a359f0068928b893731b9d1d856546dfc4766608e061ac859d730cc44362710467eb3fb77619f8fb1f740db970c1d7c25a59e3177ae7584f0108d5d5bb999ea79c6fc07df575a10bac79c092f897c65b94f0d5bc1b6ae3fa1bb7e70874137391acb9f75377126931325cbf1e999ea8407ed607c5b23f045b57c22088d175a22e31c91abd197056b887045cd662f0bd5755bfe3f808462a00e4d1cc4aed188b254229413ba68ef61d125f67494b670f89b5c0b673e655f13a0d321f78dcb80ab706a968f8fef3dc13a764b9e87b0a6826619a545cd133e4e23f9dd2f5e9c2e16da0601f2f68480d7a0539a7ea9bf16d6112b57b8ed8ee8b567f4002d7cb55bfbc2b598ffca4c1565b06c28e696fcb1843fd27c4f3cf7a344405c8f896a58c49950b9f897e75fb654029e7db5a74367a47b23ef7f1485cc6b28fdf34717c47265706dbd4cabd14d02e47fa105cd04a4dbf6f12cb9052303495ec84b3b51ca5cf66f4a948f466d5ad633a1bc5a46338632dd967cff67f1ebea432a0300adcbdbe6aaf84778aeb0acd3be2b9f1c51a74acb6bed9c4b4ea14416c55d2dab26af6e9935fa303983ae4740fcf75eeaff6cb9f21bfe7fddabf679b7271692f018b7e01944bf4c81e594ea4597a02b9fd4153f6207657cbfe6e54a4d0647d43a9941f7c017d1c225369b244f8c48f4386f29a28f9a7ef7bf34563e975d4a93ac7679d883d31c081ad5ab9d1f87d4fb511aec8f8adbec4d1cbdf2059f5315ae846e6220282f494b26fc7f20de9b2537c0ef5e37aefbba74197ef7bf64127b3129c393d187c9285f13f316e36b5869b0825b3c9c3479aea30f03527653ac9d7f7e469a8c4624020aac76b8d7f0f782818db61d0965ed15faa3d8c1de31498057160e615e32ca80edccd93ea890335a4c1b3e5915995e2fb9dfa54d319ee9181eef8cb94a358406007727900f0fdf7ddafe79b8f8047cc31ca889152363dbea34fb7038ea50fca0180f79e234f7522911b5589e0ed7729f90ba07b56964713ec312d7dac905e9fe207f06f3acb78726a2e16066ddc295716754a465297b6ef7a6fb8203fd5efdbe1ec9b56d3631dfa25637f3e8bbac3a8b10eb4bda599294f2b2b50ce5dd33ee28829a6b109c99c675c0b711d7ab02837aaacf3b228fa1ef444674b05e8c7ebe919ff77f3efaf4da5c2f02a74e82d9088d53f4eddbff86fc76b43d46137a3e586ae7c31c9550dbe452fb20121e47268956d743249323ad1f4914b97ae171a0eed2d0e7452c8ff78fe470be36ef09f8c3d0e61e1f990ed1e01f83590e450a74fbdb011512b0d56d631b8822d0a276d5e4262052b1c1ea109956311fe2bcef7c7b5253525930b464dfa4214d4d254d4d07d94537328ee0554b4b439942255fb7bc8f0e2e475c262f0378cd93fb8ea1e53b1b86dd6a48a100629af05961e7f296f5f12bea98007424d126ebd07f4b64e1cdee4b8b1810902cc4d28103a111708dc4f9e62b3da4b35ac0d14f6cbf470e5bbfa513495cccb0acc3c7b7cb93a25f854e2ca702575758b02b4642e4edb7bac99aec327ef52926c72ad28a8039b81215c257260b941001639306f6de673cb32916c9e2166e746e2c5a413f0dc38f0b85d856fba917ea40bd577aba8e4335a2f37f49b83605aceedc9d16a32869d62c00b16194d4889f80d10eec591f51c5886ee5eaa9e8438403704dd98f1ea7d8b4fda10f38985552c315bd67e428c4e85d89fe64412e4b70b6f06f6230cb97359b09f4214b366ae1b850de28f360492a2cb33f9599d1798fb46997bad99f868247c87cb80b5e3c3bc3128f2a1ff9b56bf651e730ccc994fb62f1d4ed60335498ed2a344166e17f985b91062736fabc389bbd20a9af4eb839d243bd9a94006b7b5bc625f1815b574432c519c8c0e6d325d0d107030321e70dcb6f63ef5b207e4d4c1545487a0c71eb540d8e1b29447d485dd0f66200731526f06e3fb9b8b96723b4fc8d877e5cd47eaa3c523c24eba4654d561d7ade42ef514a7d3307d0a8fe8e13bdd21481242b3452a498d6f9d0d67fac861ae8695df2a1bbaef22dd17863177b63c990507ca490ebb5e1129a4cbcb758e41e6561ae7e88a2be31719f61eb9986c545285f10bbd96e7ef76dcc3775ce60c80bf9b62442d6d993dfd89c460a8e726748897c47bdb947f33c1af4faa5f87309a6d0bb27597bf5b34bc12e4d3bed8bbcdee3e7f3745e9ee88cae4c19c46caf54e4a523ef914c66ddde554a844c694ca5b97bdb452a9bfd9a208596ba3b5126011f476493920c0774bf2e68b71abbeeeb0bb72a80fda166f640bc39d9507a362c5c8414a53aaa2e8a6dc294992a29b9553111afef8a3303ede244e6b7b5714083f34e126245b5ada38fbecc4ee5b875be0b3c30af7cdf3c5b2cec98a812eb09f1d279fde9af444769b42be0cb3ce6ebb2a46d7d4c72aa0e48aa5136f8899fa02d2db11da1fb0675bda0c7e7dcc760b782938503f64443377b69a35d2f05f469b1d38f93f046722dfe013a51f1513adf2617a4ef896abe444bd698e2fcb4d45a33e4aa1f3024ace8a071aa427e4a9591ae83d155828f9f51d112236f3b971034bf2d3b1fd797d469ad1a7114dc80734629322ad682c0c17031abcfbd41cd0ccdcb45cbc7c2d6cd3018a66c243f167760ed901921b0b14a2f5c985c855478441c2c59d146ba6782b77ed16b8b70a866d3e92545d36821fe24c65fc34f2a472fa878ba161aa74e7deda8f1451418ddcbf3dda510d3ac9df2046e1dd50d306fb283837db400005c129eefb64509f37d20b1bb9f40bb1c0c47d81b3334a04775bfa8a7c8a04c3d3651eb2e9ee66a97ccfd4866ebc8f9e6407381740d3f93e12168d09dcc606806350fcf0864e1e985c7b031cdab5dedf64296df04402daf680e20188df75e2371e4ebcd4cb6dcf044a8d2bc8756b04865addcc7e5250888572f5dc49603e323f346b50b49359f0775b9b440db3b4210775b97f5385488bdb4d40913c9b923b7b6f218f24d74a6ce19f6553a3e101997f141c708f4253b704267832db9568b4152509bb3ce0479429f1a9a3432f48a75b36e079086a17232c1577664155314be45ea3aa734f1049934d60eea058134c07907f149894c8b350e67c8346da2a46ef92afb984fb6c7c709bdd4e771a153cf50c6c59a884866b0b0ddd7996262841c7ad6da9278372319010fe8435df4e51cfbc3e32688bd1f12324408f18446d67d1245c8abd346549c2a0c488098568a4968cf4b0131558cb15e3f1768fcf1d1d44aac5e091e6b74dd67440b464f228abce75142cf8b8592f4f206feac2112eea15e6c718cdcece796bc71f3333b98fa79993d7ab0089ea4e89c65e0a8f6e1bc4807110b491e617962a8246a444dcf9e2b90df1bb53f02a21f87a25585baa444918cf2fdd251c37898684b53214e596dcac0990451afa4db62678c028490f201eadd1f3b9c70713267e8921a7064bce82d54661887e3ea4a71a71e24eff11fa164543ea458f462b2f4b1a086b67613d6b01bf34af9fcfd8968035797c041fb8b2306a3358174a743fcc0d1ebf1dcd253f34f4e46fe538478fd240e648ff32b06243217fe3e15c2596c85830a7f314c050eb7e7ddc42a9b5ad57d662602b1f8ea508963a0aee242f254129eb4c8e3fd36421cfd0de080aa2772140e59aa7312586d1ce2f60a7f2b6c5c8bbd9e5ae01a3b57e3e6d3ff753478e382fb01a9f7abd3dc648ae00c781cd30dc844bd6435b403c08a504f14f8aab092728a89b5b5029b0d27e25b667834ba906faf71de932be9975660a3a316e269ee1e60f0c5e6305523d4b78ad230c9859163ac611ba8223646e3230b7d2db7a6cc6c6eab84843fa27ad58f27af001e5c66675d997afb3569567ed32f04281b3b6a3a14880fcbb7f22300f246823feca2db846ebc38b5310a7b014af7fd004e8bd4d022d504a6d91a0efa107745e865e527d5b76a4253a8f44fe7083690c67a97bcd1f6d4c2cfa992d5fa8bed62672e7b1a149ad80e41e822315790187d63c91aaa027ecaea77789b7a2269db28062ea9e1581c00fb56eab0d59c87952a2f3ce13cf2e222dc3a5e42a5f9810fad8411af0339c6fea6830cfb6de12bf7e9e255619b273678f46b748f93c0cc7781719810c59fd520abf723e5971dde1ab490afdb0d5777011f7ebb31bc31a36a9155dba8fe0a589474ef4a4b94e807b76ddb9a91b27001340ea012df09f8c0d6dfa057b0525c705dca2c786040a5326e960393df6da1faa9211dcb18829da89228491eb0206002d5bfbe57f6112db6cc57a36480856706a460761de80a3d709723122f9e38e2934b46263b1d6b0188cb9af04cc5853d0dafe9f305e26bb59fccb70a2002a48fe82451367a38014c110c659507f8b2f9744a722f52cf5e5de606b33dd5d046cd8afda451d78344cb4fd017bfa2a364c308cee0ce534984e19622607899559303e953754effc444d3a24007cc026ed0687017faafffde13f4cc052f2a47b5156cd45ef017880a2204ec336854021f6e8863b26b62df7439f528b202741820be46943ec8df1385a3efa5c278272390e5006643e9f6c9388a06044a1188b25f4367e59f5ab41c47f52e4b2307aaaa241ff269b28d82091f036a13125314e74af603dd1b2c1320a55fcf823b0e496a0fcfec98c87172d4f507eff2840b634bceab89adf042532740b4579fb557032344579fc2ad1c994238cb8f7aaaf5ec9399cd089f6cb88123392a6f1547f199309c9a4536fe9a1fba3b5558042f1ec04612d99936e1ade2450c6f0fb12e8b7a544773b76b0a755c4cf348b88498bc193207dccb8f018873a87051d2277712b2f156620092554de7fa3a301cb21ffc5e722607bbdadd47ea6e50a06f65e46521833c49c80bcec09fa66f909822a2f79bd9fb23d1fe7060fb26bb33c8d512faceb4f1ccd403a1992dcff688cd71aaf425a338469ffb2547e4fac79966c118c17948bfd3e9be4d80fc288e76f26745448f5f4982df4de20232c749b8230cb6a0692c67ab656e5f2d6b2b2950c7163c5aad52fedc0211d81097b59cb4341014563a8689c2106db6157fc5b3488bc02ab1adb6312b493b64c48a1802694aa605c5941fd10d14535e954d46264405353c3c6a3516243f2c50f73849d24c556c5761b813507e8bd50ee7209df0529537d5b9a25496d96da82cc1f163cb68eda9890e9971c6d5b01c085cc585fb9896c4c1e3aed110ebf648f31a19c0ac6840a763483aa51a2215a00823aa58f5b14a94fae5a710524e239328d810803ff4d55a1693bb59b6a084854f9a89446066954402240537aab1a74947c07451e76e20d7ed08bd26243c84594caf142058484de938ed5a7269faec1373f5379b0d7ff4c1e50bbf1e6ac41188ccdaa269b36005fac7e8f79814e9cbdbf7f1dc39ca1ff7e9848ea608dd729b430a8cb0b8443301b777884935ea939bc48951226942c8eacbdc918dc155173af2590ba543644d77eb5904ce9ea770429942e0def0a6737a176b8260733993232a90b3422e28afcd830ff5a356bc2b268489783cb149b569b59f84cd40807780d67a7ec011ecafdfb7911ace189565538f867c76caf529f544b49be6075a112497a7590a11d6ec757015c0769385f08a4a93b526d1a73d585014a555f237fde5df88fb67c8cb00304613649d5b76746dc9d04ef0c2800a7f7d44e2692eb90a04aa19df09f6e89f843e7c5077484e33e8188012e5ae4f9f0c97a9eb331839c92f22bed91e2077852eb925df25f708a323283bc149a3c30c24db066f8b3fc1fdc7b26ef6b10cda4beb2b251d8b1fbe512453bacfafe30701fff72e706189768a8f21acfb84447e6ea04e30b0d39983c21456b96e13f62d0a5bba669fec1dd66970700b52ccf926dbd29a696d8e7d73159f8df214dea95ca22d8859e8e54c9a5d615e81c5906303292e8da4c2d57402587dadd2525235a09be60df89dc601592566a1f98dc60ac33248032380fda0dd1bb02fba8e9229291e1ad9d3509e65308a8ccbb583f638ca9da4b4b8769b7fc9b2e671a7c45d1f037b1270205ccee945aca4fee73e4bb1c7afd4119b4b97c84f61a8ac4e0f893cdc031642853765b9acc83364dc6b4eb60687633f835e6217be421b33639e637f743ffe1f2fe7b72c2cbc320a75ca2f46f5b1e90e89f53bf4ff3f20ebced71f4751b0824dce59057c8ec03cf8272484c2bf296c31cf1ca89c609f7f060ff3ff2d49a59fb96a4205f23abfd617928cd8ed789ddaf6ee4c0d9145d6e6eb0ce8e6b25c6b541e4f80ce7a25bc7d98270252a163ffee3b35b5bedacfc130f22f8f2834e1224701a4cc29d2e4f04bdf8e449af93a873ca6e6902fabec04a617be8220f22f86bea8f0ab2955dbd506cb262b63b0cee0c8e6c0c99d6ef63b9a31ca78a1ccc1e31dc26b51575a038f8aba8e5122b4693df8daffe2312dcded83abc9cd3d4c9eccf91a05d7472a3ae12af7498f17a554183dcef49be6e6cdbf335b132bd3f29e9ea48f7d937b407799c67bc896487ef77a108723349ac31f8b0d86b914374858590c2db1fb8f5bf769d7defe17d4058915061ec07019750f8e2c9096dfbbb4a1deab5e9140f7223f37ae980813a01dd6297d1d5b05a251212eca298dd853f56ef59b81a68fc768040d99dbfffa3545ee0607e21d42d95b32c6b1baf2e9b5aed56c57208e223e70ff6f0e4e5264dc883e5b09febcd36b8caf194b997b834373df5ad622407d3a13c370378eac0457730d3d5ef30c1802aef8f66f00aa751e148d53f29178c2944e391c657e1315536ffbbb83910089030696925d2ef3326523afdb065b024d28a62c0ed7262054a9f780a40300928066074a5d8e0f83030caa8d596370e63fdeea8f6d0215a02fc665f77ec5ce5d9d8159fa26623c46451472b905a366d6b1303d0c30e497831a1007916ea01e40dc8f7c67566c9fcb0fb11cf27a75200c8caed5910514c6e824e3f03078ad4ad5570f397d4e5e0831931adb8ff689d6afa5a7d4729a100ff6b2766b7b433c0747c6cedd34de9c7fdc3b3f47ef8340a88599b0b9e2c08ca41297c5ad2a106e98523d486bda9a0b3e02d970a4051aa835020055ad1e085cf37ba6c47c60a4f1147a07a7385cb0e717bf401c9a3e7500b393ac17ad5ef3439a992ff5f844878c81107857d343a9e9c2d6569b6c4b80f0852a92899ae5a9095db732b03b881153a4cc81112c9ea8c52ba245321e80859490b6612d3ff357cc44c6139d3f70f9a6e749b3e8a334d5a21771f644165719ed67be1c1d6df45dc617714932724c8ffa0e59a01442fce40f290ce05821a74d1d51b545fb42f23c30f807bb2a12870ac789a0491ed78b3d5594405175a1d1deca132e7e977d981a87c2c6a58a588b37b2c38dc273b984d5ead4f48a75bb02c46c4e70f50f31798faac6f9909e52d16473ed4495f8cc4fce51d2025b91f3abb7309597611970ee94d2d09d8fc99ccd422de364940127b26b35fc45b4afc44bc22120f59a30d447225f15d855acd78bc45352d0e2c7aede8d0681ceba3ded26df046f111b862fa226141d5ecbc9b33020efa88d91d60fe6e15ed38c36989689e94c2c86a2db8f9ea0f14ecbb29e147c2f9ac08141f8f922d0660d5439d65cda48cbc162fc07a84ca831f202b7bd32517e9aef51ea319e8905bf821b9574d3aa8bfde929ed2ac77b66369fa274fe8fbf58727b1f65ed4cb008314ea9e435c157269e041e3a909c9822038532e55ab152e97116ce97d0c8e600e573d509e367ada90bbe4d2e9550527702b281c2f5cb6397c64125e72a10570cb01c92da4cb881211bbee12843849d72b4982961c19873885f450f5c29f63439be48974f304a0b0558e055b5d3bfb0e4c25d44b2e17cf5523f4f381231af012bc2cd15a5008ac00269a9d5288162c98c7ed60817559e08b89718af9e8222bbad451c2b28edfc3ac768773fa5a268f4954a794a5162f76e02633096b218716b9856075a2c8cded9ed51b709b03e95a330491d705aa3e35b7f3585455083112a96291dd7659159a2182dce7e188b90a0add2ca91f2b68feab401f85220f6e446d5cefd128e0fb392fa18ec06fa07920544b95fd0a3cc2b3071766210729c3c23c0e6848a66362dfc2071ac0dd436b09024e9e168a8105221fa427b7b702ea9f8dc08d18d9148b7ce2c336ec7eb9804e7d3448c4cd6823007747306faf0a4cd141a70c59a51d142d177619d6da9c00a0d79022cb983a1484d4cdd3bdc62a782b1b26111d2af599afb3e011e87263a3a70c65b3deee151fe4811e84fa4a4a032e15b323b1a4c27c40c10d1da6bdad5aeadf143064efc1f3f74297640f1a850e4995207012c3a8f793a69480ca3f2f5a2edaa625dd9a649a73339c3729c2f072d14b94bd4d985cfe2168eadcd3b97f224c0c8d70f19ecb90f528625107849343a2c8d7812288ae59012bdf38d904da205bcde6bf2eb62c543b30887640edfc89e2f962205c402330208209b24eea35c4dca2369940d7f42fb7358907537c20e2d26d90e17e539c9fcc4de44630632ebbc5f39e2c011112f6cca0fea667ac63de1bdc16f04400e4f8851378fd1006c918686612b513044ff8c5fdb0b3b6c3720044472f33bcdc085371a70b7dc830a092854e04b59d613e8868732268d2a277cdb07a27fb5889c7771dd58d8eabf6fa3539cf3811dec747f7e719bc9a08daabdb1129a54c4d0e8032edf40173c15118fde0ce569abcb0ea7c4510c0897e232cb4df8f55f0763a744e9629d0556890dc21b07e6745d9e10c49f7ae8b9a3a0491e058fe78369347b18c8494f81e764777af299b6092a47ee0bdfc66ae11faa872578f843c4e7bb049784d3ee92a812ce269471939cc64444aa96aec686d2e2e231be1b65dcb3282f4615e973f7614369529a91955fab55a15cf2dab802186ce9ed2d754cdc50f444a276cb654ef7286f6c88d9ab89f930e29d0484de9e7423dc2d904d943f0c68420ec1f2c51da5678f4937662e73b3ed4d14683e1167a76e448b20dc0c8d23175d1b57a17a0e120b9f020fbd8e5381a9c8ba139df1f9c2e9c0e6650cac0e6cba5a6cec0bd362f114c3f3a4d6fdb518963b90557975b09a0a0fd23efd6af2bbfad048193d006b83be9f8b7faa05020393e831c7976ab4a280318167428dc943478e29d762790f97d00613f3264c10ae034edc1a946d54d8168ed8fbddb301e93c55f40a94d2178a89fa5136da8c9d212e9c749249428e8bf6c98980b4d51e475931070249ee9596ed414d0e0983404e52c195337637d89e015ed06439a2b714c74b322be48874c8aee7e639605db493921e3f5c21032b11734818a5c958511f31e9353d816fbb4fd0a0670a1dc96fb68fb2504a063e66efdb25342e327f77f391187c3f46537497f0901440e7df941d02f6100e0805f7e22a9973080c8e1971f38c03f30ce70f0fe28f81be8b02540f1f463c9c0ff8f7651b34b696d893d09c629aedf88eab6b347fa1fdf19ff98e90da56c9ee84fb95b8cf51bd21afc3f3147053c9eb8e386eaee83842077330d08ac50bf3d03db993ae1024f02e1e07799525732b069e2950d406097a7b172656160b64f05b1fde10e17ccb703c2cab1255ab2eec43028894840c33786e1d7c46958de9e49067025994b1077b4b1f13c158ed6c784361ee53b9cdea53dea0d7a63a471af5972d8830156af29fb32779ac6ccda05fe2a66ec629875335efaba054a90532fdc7a7611514d0c387e7fbbbe3b9fb5081f2002bdc2476be7472cb6748fd0036f53f3d94fdf9571f7c4e832e18490189456e7bae1f7e229e0631a9ad700a2a29eb30bc823e64c142bf1542b0b49e909cb81bec0444d4f921f661e8aa489999d4777cbf1771b5284a2060ab67803008a6073b0f125a979c58f93808ac65aa8119d5287ea1a797777c24cebac7fdf8ce529acd8e1f4ad92a8feb9cd988268833113144ff5cc6d991e95f62a7bd68095515ed90e1e56ae32e126de38035faddf2e15e6d031c57621f548c1f47508c44d1000a54b3fed71a44f5e875e0abb196b8637184cc194f6f16b6f1dbf2e17716250e5db2fda5132b23ad61f81ce8f0c2d3b35fad555ccad0c0984234c7b4e8bd272f7eb504ff1bf68f69dda3ec1ef1fad2dc1c1ff5cc4153ab0a5779c257aa9d7ee7293a31b034b13eb6e921aad550a08fd7af282fc17fb111281b087ea6e69a01d414a20281d57a13fb1943fb5fcda73f486762930da310e449d52dd48110baf91894ac6318ce17ad66de18bc45427ddd70886ed31611bd0b585c8ae9b1e62cc16c169f340c29ff3e6838700e831db59486af9d77b40384ffacf5ade05005f07f27d4aee0b421f92294fe6e14f65ad6ecf706f3cdf4b8a1c0797f85e9d9c9c3f66ab53c949d039dc25ea1723f45fb14a1a807f08f8b63bfa9e7e4ce234892ba52da0d46cdf0045421db36ad927dacdb931c329d9a231ef5d2150962df6adf8ce9da57aba00652e48d6a25b1cd5dc92e361a9e6db0087866b1c848a0968cc4d82d2a5b108a0d9b51dd51424fd1b939c8ca373034d5a4c9cd9d00aefda82046be32ecc3df3b0ed706506af40c0e666f7ca430e688c36bfe961c4cbdae6db508101d00415cf4ee4d909092e77394ca064e62aceaadd746a139fa5c5e76cff9535499d1e71e680745a611ab8361359d1391e0713ea4c69c5f0b2bc18da1c043bb99480b324492d0db7da58aa72c8801fcf3227cec6e0f9324d549e35da645ce863d0cf08299c28195d46b2639e985cca8ab39568bf2174d0fee689990b2da6aff5f1012c0323f83ab48ac1260127642e4e520e0bb5f75a031ad4b6cd8290f344ab1eb6c82dfb8816981321b425f80a891c8a3d2fd326a148a6807d673727511a5120534fa203cd1534e8a7d25b9a10783512ad40f66ee768607c20548be579daed9448bc7d82ca57328d329d214efab9e27de2d8b03ab4b22a05b26fe5630395fabe644868f35998b14ea43262d940247b58834036ece2b0027464d2f19b30f90eac84fc5fd0efa495e133c9902e01ecafb511dbb837018ec40d30c9a50048cc3869bf948e12208d6701e3034e4313209f633412df04a9e74d036d963862fbd9f15ab8fa7d168615bb4ddb2a5c6aef0fae57c893da9d20496fbb9f35365094688cb3b81ffe492c54ecc68adad8b489af766e86cc31605b0edc0ce563a57ecec2b907927f8afad50b78cbbd8396255f9181b482c6174a9457175e2684cd8a300393b8ae20372d1269c5e45c61e8c4cc0486293d1381dac765f7d7a2adfdbc162d5fdb8ad6ea53dfac9939a3151c39060e1d34997ffc8ac01c1b069000299a880cf3ffcf32c93b18c55de1780c86ee972df0022719e6eed0bf61c46ba594d0904799b37433f3b2c5ddb6cf423200ea59b0c6241d7c2347f78fbd706e00ebd16e0eeb462b07f645581f4b7719f9ff2a6b710620090fd5a169d2f5c9856015eb3281bcdd504c0c871988bb1152dce5af9e2642cca3f8477970db55850bd462ea31f000d543da8f48c6334e4f096edba137eaa161abb44d6833c3c57eb61e80c7ed25102f285be0e1313fe51b6afc8eb5675b758b65726c18df08bbcef42ffc6e8e994a8d1d7c73566d331659ae5ad4b954a8aac648c76d4a2ecfa82862ca324305474526c50f361640010d20c36925a653a88b6267ca8be1bbe32d6503d382d0a51f6aa89ba2c2d1b74a3083cf0dcb602ccd22b9a367adf54e468967484123b6d3aa9d5304e813482b22e8e6134569589dadf6b4f27fe7049b0e51dc9a09cd85951c9576ab5da0d34df19b321440da8f1b5a91954fe6cfe940cb0fa8db84a472fdebe1a50c1f778824abdb69b6ec6b8f3c0b805f208c22366a0de99afdfa2123e74c252ae2a53c22d52c8321acac5c6a44db98e957cb776dd560d36346394fbb611b223421ceb17901345a555560bdabe9ff2f1ce90efa1db64f7d1b2fb88a84a3a5c2b041db436af519db8647e7581ec29a66857d7d862248c1e8ae1eb70c745ce2ae117ee8b433116318986e63fa5f8f5066da6f2c587fe39551ce081d7fce4ca9a20a813813be898b6c072748861977c95c51f8f49b5ce6ec7a11479b5facec6ad030f6fda830850fbe46e235b5d39f2b0d9784361040ab1a1a92f0c99aeb3cec24c5eef0b48e15140e3ebcd1856b7f792c42390c5a6ce9f6e05e0cdfddc3e0919a31403d8523fb4f884f935c2b341a15dcdd4e8b01c1c926e1911e7cbe034c382d47fdbe5e1fe60030aa2a54791748284546c39f1343859b4d4748104a06cff1966a52a96cfa17ef272943566a5ae69bc45869662757e68f3c82a94330bae4f81ec11f69b50ca2d6d3f9eaa679a80e80f465679d690d51568b296d9467b506cec0251d5a8d0a83e4e11682f13bdbd4a3d8c317882f267019bd36e03928a9673101f8a7c157e954937c0139b986f748a4c5083bbf60d1e85f7511ac677890b04432a0fb30d322615f4e2b549c156817646a76bef66fa18d35396625f62c03f774d33bddb4b37a15332be4b220b6fd17071bf190428dc4b5774cd8c3b7c43ba66a6ee67eb42ab77497f0e1f12435e2f90f1d33fd2bf3cff000d6d9111466e67ff26b2d76233810f983ef589a20b134fe9bdf231e490402224507486855c6c8ede59141354fb10fa9e786deeae3d93a608717eb462205e30736b8909af472b8e5d0aa0bc9a55da593f1a4a0889f0caf869231c769652065a73f77c06fd74aebdd0aa58a0875ceac6edf1bc9248a08b30d06933d33a6aa883ac2b44d0db3fe46aae862feb5bfc197ef1f4395b8845ee1b3b8067199ed12e34b4961b68e21fc899ff028663169961cc496d419ee888c52e45c2c07f58a56e2dc44bf33bac7ca1cf7389614debf2b4259153052d83bd572d01742e06ec9ca23e2566716dc282581b5dd64a0b98a1bc4beb98b4266eda4c2257cf42f309f83f60a2be3bba9df29fde3ea9cfbeca88dc58aadd716088cbb7065a16b2c764a3e4e71b72ab3e01ea5152b3616330d11ca6a83e555ebd2662bce6a2cf061f468fe2b068b19c4a187562c2bbd0622307d6b2cf006fd98c4ff22fa36e0c298ed946cf9920a430df3f35b046d0544bde2b21fb9416e87316dd20ba157b8f63ee35f01065d19080fe0489365d838d9fabb692d017246a20b8bc0e0ee947b2f57a84026e650637599a78f22502837062ba10ad168ee1a99838fa4bd2b59e8ad6fb2298dcd104dc7d01be2737bbbb835bac9c221553a2c9256446f393469d9d0ae3eb48570d9933865c246fcd5ad73e8993d059cd379bd91fe358c051d1700df621ab0a183d976c3752526386035fe2cce2630d05b39af73aad46ab1f153617bfbf336afb77c9e8ed2b13787edc665a7917dd2b914e4a2b4c6a32c598c1b8b0eb477cce570427c789e874b86185daff150d8c60f6d9d5d995b0b84a4b989c0dba50f9ce39e64db11706e1cdf6a715d65099b94b42b7c1c4b421e1c542eec5a0ce306337641bd7ea26ecd796aafa3fdb3957fac69a54645b177c014cfe60a4f26aca750982d9167041707b162b127849cad20367b28e26ec35c905345443b29d63a097875d9571f00db1d10c7f1525ca8e319f8467350ad147936f5c48de7242058b98210e15ff50dc8f626c67a9cd824cc1b58ead4d4c8811a1e78b294cc7a7d795007835a552cf6133a3fb1c98dffd68cc0478ec07a244a5db73fc5ec5a30d08f4f706c7a0ce75c455b77d36987d608a9e4ff2c55425fb77bedd59c8eeb3eb3f9364d7111cec7782bc3db08a54ff40c6e9c66f4abcc7f80ed650ccce8f10423b86fbc21b13a4a64b28211c1e66f7b437a2b34ab68e4ecd32f2302a085e4dc5c480a7b64dcb017976a227d0f1272e5ae6ce5a27bfb325664236678c34fe486639e7b6250432aa39380bcf077f7ad708dfaea88a815f9b9d1aada247d8da4f77cf998910925496cdd3efd02f302de6a1802c4e4deca88333a7594be883ef57a97e7ffb9ed23a9255071a3ef586873cde54a310728d6f9aa9be33eaf809807ba5cd0030a9fa2845b3092b24a07ca0127e063ae6c8d369a35f26ca411df7492d962d008c0b9362efe3527dab45512e13c63ae808d3138ad9ee6fbbf872a02a1658dc9c927e63498df73f3494381914028c843300e2c428b2811d972ef2da59449262903db07ea07c908bf62e5a59d67e2d5b6ec174aa0a0c5040777af1796e9dc58d2c98c30a3cba852a329de0d1184d062c40d5fe26e67b4547b6d70515eedcc0d4c54f8c175875be4f81d842d1b34545bc516b7c8f46a5b689020a9b672645282f97302a156faf06d5629a534c8a554ca39e95c452999bb942fa59c52ce39a764b5404eaae9e8f76aa9d0951ec9801e6d78eeee8eba59a5c2a856051e549b7222542f2cb33c7098c1e3e8e8e8e8881edda38bc2119384032e7008f55097b20bb3574a29edb61369e2ced5da69b55abecac212409629fa3397522ac6a575ce39a507f294adf990704a5f11c1927266524a89fdccb6cef4c527cff72bcbb22c3970fd6343f27cef8139ca6760e4d55a61eff39aba81def7efe67ecef5f4af97539f3ef6722617afa7ad883dfddd6c9490053081ec52eb71b30d20a73cb3376dd394e5d76d08cd5886bb10b2ecb27f0f9ae7d33c7dcc3cb1cfeb92312c5f0dac1022404e97f46a19c4bf94e7b521ec2dba27ec974daf4b4ab7d3351d943aac9a8efe884ac94828faa1bf8cb2ff757bc323d5522925adb5594128518dba93dcadb528540376e25b4acaeea82fae7bec52b7282665563071829a641491aaadf2275cdd7009a7acf55e5aaf2bcf6879f2c9274d40bd9af835405c58edd5f244284bfd9bcbddbd6fcce6f589ef7d395eadd794ecd8050e6bf556db49a18b6a776cf62b164e165e6d0aa7212842780ad96790f9ac745e98e4e2b3629792baad94686bb664cbb7953f015f4eef6951d6fe08a7ecfe3e93dd61b45c3769d60413e23f9af8f23448bc79c118c04010de95947f34490c853a884357a150aa8335d88b9a917152461733d136dd32bd4ad93fa594524a085f42c7edd65ed41717faa4103e28e68479be0d1ba853d891dae9d047ec4229cc127b07a1a1a480e386cccb0c4e3d2a8307a210ffc6bf2fd5c688459ff11d33b39e50e0c74ba2495eed51ee9f4c2851f1bc7a9442ba4bf9644cbfe88f7fccb3cb8c3104557b294d5b11ccf459966d93939c73916b0e72da7c9a8f17122270c555f9780122ff4aaca22f67b0fab82fe7dd464004021f7e77e57488535ea509dc7d957db2d013f304643fc1b77773dfdd3ac599a6ae5a134cb8f0cfab893f629c49393accd22d9c4bb4942d1d768be146b4ae5067547bb7b828e910ee905db463bddcd3e9bef4b0ea55ddafcb8429591ec455270b47df6842a686a5ead451610906cedab93e64ce28e6d778738151a7d7eab5b51d0bc8efd5d4af9e678e49a75f26ac399b3a9e73c64c42adc7cb775a9dd2f953fa0095823f259cdf5206a2503232d55e59e274522add7ffa805db2a35232318bd54c2ff7946116ca96d37d316936c357adf77a4baf53429948c839e79452bed75417cfab7bd1a7663f8412b68cb4a9d84b948c0d21544a66897cdf62a0eff3232494fdaaf86573caef21b374d99ea34b972e9ebd57591a21b1ec654aceebd220989d6eefa99473d299cabe02a357695dbd6e29646a00538898926a02bbacc6e2f276855d17cb59ffc2d349a9ac1a60b53c8cea5e234c0ca5f459f1e63efd98ad562cb7d6f7aebdd9c5fc5d927ef66aab90f9d2a54b973a6462ed585c6b51d57ef7a99e0da586bda9542ab55560b31745a506b618bfa82814c513cba47d7f771d3c9b521f2a31067a15a1af7e64f93acfdf71f2d2a4417738acee61dab68e0a6da3f53b2a23c35db53027dcbd560b27775785b792bf635b98d77aefd4a9b276adf5df0bff8e4c3f3829e31d65c77ee1cca2d6ef6896334b99a58c59ca872fc7f4f2fbe5682f3ff572e895ce14bf20993eac996fdae0ab99af6dfd6ae6db2dc3aef9755219ea8c5f2d95124eaddd09da03bbdeb7895d4ad419f761d95bc97ff1c95e2586b12c4b0e642ccb2158f6297b508e5d87e72e1ffac05bab5b982ba821ae7f3f7f39a7bb2d4156694d597ab3abfea45442c98a4fbcbad7f8cef83ae5e63146d3c4ac66bd632cd3d789d4ab7514924a34b37267b1b2fc991b5c665637762cee2a66dab44d8901b40892831b64696675a3875535c022923454292d465f588da36db20903833be7b6b2b84b6954f270c04bc69e15a3093fcdae7e649bbf95c42eea137ba4543eac1ac07902adbfeb612f938295e1ab639c9b570b553e80ac2096a1c1ab4f29a59c737ee7b9da9b74515eed157abb796dcf979bcf4f963e51cba490ce7366b973da682fe15b51979a8eda5a867dccc77ce27ad5219dbd575786a1542f0ca7672506ce4de1fce70e27caf3ea2ef4fc4929e5acb68abdcfab10e943a416f0797d815b641b45ee16b9832f49d089d6e21aaf267ed472e1c7244fc5d8c53572d4e13680420908b7903fd47aabe4f85dcfdd52edad82d2c1859fca6fef83f282c3135b3c2810490ede7a3d3259ca205c295ff49abac141879299896204495c261ae12ffd6f4effee1efd5dbac026f5a57f5e3fb253207bb3a48f8dbebd5b207845e1ade8cdbd58af267e086350dc9d90e37bb5ab11a27ca1445d65a524aaad3555efbd3d378c6a2f0a95a272eff3a8648b2d64acb55726f56ae2a36cd4602f093a5256dcce2dcaebeb00e1c75496eaeeeec1ed8673abb8e5f189468245cf90e1773d3d43eeee72bb21164774d0b3a9a183a42ae1f33cfc1d0c611a173edcf5f873c224bf7f2d1f3e1f889279b14d1d506e1c0467713b8b3b54df542ebe8cbd2e24454aad51d321f36ae2c7540afadf94141795d2e1037309af267e0c9d3b19195cc5edeaed6a5f4e7f1fe17701fec3401868094f04822fb12abec7ed7bf539b63c9afefe2fba5d8efc027c55bc91a63702dce07eee72308088dbe5c81d6dea88e489a19096858a22eb3ee351b0e4cea3283d28837e0d898aa1ac7d265bf0a17e0cfe3eb0cbcfb40d663f422df946df5c4a5efe7af9685471b76571c767edfd7d608f4d686f88cf4baeffbe75d1281a4549bab214b90c194152841328ad2a58daa6737cd7d2365d6489f6373cb7c43f368173e6805a63d8f1f2f53b60f6ceade978af005de643f30194b38f4db48df6f135dcb58fe913e49a0fff0bd7eced06b38fe8a4571a8e4df44a6af78adbc526ef9b18027307eb06331547e08bb225377c0cfbc0d88413afe67984d20165ff178d6e48b95d6c92e3c7266de324362185aa92c7d3368dd4bda761e3ee01852208e0f51d5cb170e4a4af36847f2479c8688413d27b3314ec54dbbc4c9c120dff1d88a0102ca2650b962c55945a4829402972312c045fcb162c59aab452b71a690c0c8345fcf0589df231ec319e8c5df2eb0f32c9121c9ac9988cbdbd4326e3b6911782b40df657af7a7edac6b197b1f797310cb7932d5cb22c295d414a3a8a029b9cc4b8d785bb6e92553d88640c17e523bdeac14d9269b81836d2ab78c44f59a291f88314924532fcbf5082f4482985e4906bd9b2cad86727242ef670909e0a4397ca5ab864882567c959dc4eee90e17b15a5f74eafe2fc7a55e54a0b09ca9193268a60822409922223478cfce0433b3811975e5d18db320cc3b08745328c4b19462d36904e51034ac65e36049edcd72477f14af6737eff40addd56908fc9c75690f281c8c71e834cdc873445932c1ffb296a34c93060c9fe2fb4cd9b728652767f59b2bf096d2e0057ef050bbc1a7f0838713b96779f6baa5a6c933f371df3e30664fe7c0ceb81e10efbf932fec440b0971f9fe236d22b7fd946765efa87f9982b797920d8f7915eb9f0f2524db87bcde28e35f10bfe3faadc975f86197e1be91f1a49096b486114c5263da428a2e4f8f5ba4ea71146d83a967c3743ecaf267e4a07b77f473e864018b77e0320a0743104b480af94e4b39757d33cb2d759f6de7befbdf75e8bc78d18638431462e11462cb2d73618969334c93939fbcc6d46647baf46734d874fe7ba754159eb361094b387df5df6f16d8dc59df6b44b972e6b64f81a108887c0fc18866b97bd7ceda1c6424ecef07b351aeeb08f5dfd0a25fb639f656d61fd88ad50b10b670fcae03e241b2065fffa36b892fdada63dd6232763d9d7b7f55de598fd0c77adbd863b98b32eebeac70d484f4ec6b0067232f6187eaf267e8cf582ff904885728dac7328c2c2882636f2438262e461914496ea0416463829038b24c6382d81a9e0941f12142058f54a8c6775add83a1add3fa577470c21cc6ebc8111165df8acc8debb89fd10dffb123ba8a104b21df1facb95fb8e5b7b35f02d9cb9c772e1f6458bb2d7ad8dfd1e3d4a77e91dab401cbdaf8adf4b7c2daa573d29e932f7a49a0c0977e0783550da4c8fb1d2d883550ebbadcd4cd5d94939e786dad9c1d2faf3bb7afd97ebce0eb743f9a0e14eef3cdbc88e7b6cd334babb5b48ccfd56bc748b72eba89b8a53ca29bde3169225e9854020b63b486ef7d93f9b691bb7b0573633107773f6a0327454b5b787e53cb84dafc88059f6705761cedc6c86b006f51dea7a8695c27f327696f92094737e67279d7462219de7933f6fafa095120601d66cfd3481216497b2bdea24beb6a65cba37945964591624c7963fb3e7ddc19ffefd8e85788634cce47abdf7170632bfc7965b31c5efe14bdcf3a0f410b627cfce24fd2cd2bfbc620829a55ba53be843e1bd02484971cb2b039172eb4165597bd563b3c8fcdf9b1357ef183bd8b0e17baffaca5215b18c6aef948bf26a675a314226b28e107abfe3e8f168c95e297b09c91bb6b23bb1286b1b8bc7a148e324de64ef383ae9a51be250bc8943350ecd38d42650497592bda85eea2b2608a29796b47861a8e08557eb6aa050d3bda78e0aa84aad663255fab088abd92adfe5754a8a4ac9d025747503895c628616cbeb8c2c1c26edba4124f6d794d3a55f11b2f6fa8b327bb34e4ff76546b3d98d77938a34d1a662178d62638679c217a74c9acd287651eca202d061267914ad89961851b250ada1560783a6ca40abf3602dce09345b66af9733b1d49aba56ab02140033e00804f451b5b2f29fe8d55e2d2ecaabc5d18252364b88319e5725affea4b8b94114a2219c94460abba13c08db75d89fac164caf96a6e04d3a6308247477772aa4b35c3fdf219557a5754a19825a5f8d702e65ee98bbfb4ebc527eac3a5156ca2a72bdba5bebbe0295d85970e1eb44aff6ad71e77bb556ec7d5e9da5049542d158fda19cd3abf4c8030ae5feee2edda9f44b52e93f7148c37e71baa623252387c416017a20400f5ead1f65e1fe2c16f63eaf3db82fb5d62afdc724e19332c3a451149e8219adfa729ba9b8c261616171a6ed8447233f013b345b4f60a15620fbc3cd696df9a4aeb28c58fc79cd3aeb9474522ae5944217754aa594524a4a29b537bbd8adb506b9fc290a8cbc5a2af23dc93c672f317a8c110bf1e12f5f7a3483e5b5dd5ef16a676b373bf06a3bcbab2deb856556db11327970e77bb548f63eaf3168498f3f98cf5fad172e52a47e0d3a4242373c475ff54a370b0f10bfdb5a6b75e059462827ee01dfe14b88c3d072e77bb557d8fbbce218c9410e9cc85e082184288bf2c248a6b18990209a9e271642b37c48b3bb1053cac7c5f34ab31ff106f5d825592f38302cb8d89ca86fa5b44b665eaf0d72a72d5b91e511d91fca1a6c8f3b6ddba539214b16fc2b3027962b8b12242a16ad6b13cf3d35c68d349166a6ea1274a7eeee90884ad3abd0abcc6a41224d0b8d1782c49b2b976e2af5012db4f550d733783948e2cd4bea4229a59c73fe3cc1e0f76828ae3038ee8008690743485a2821593942d222a9c8c599cd7020f3853bc804167df73c2231b596e42a23089e1617172cf181346820220d248e2869811431aca8c0bed42782bda8140b07479106858806f882cc08421c3829c0294896e00d7eb094fbebcd6f0a12a54cf39b82848a960cc9154b208db184075d70e0bacf700727de38074496d285162e5c2cd1828883568048e20524f00287308ce0a0166354e182055480d08208195c9bdf142a50e4eee629548c64975bf39b42c5099dd291b03441b272940190df142a3d4ca1c2039523b29523467e70c319527e5061931bd280d29a820748504cd172840bed99174588182c71418ea5062d0c2e885573941e488084eb0d66065cd6363003290a212e08e6600c17603103022ea8041ac097c9817bb8a110a3881097d383144546425ce6b13d9a70f8c00c4eb8de485882cb241823b0010a1744a51089400617c4eaed47003f7041afb5c560043330c105d927a070fd31ce400639b8c20565671cc1f547fc036780849224b820cd8631b8c6f44d1f5a5088b8de04f0031714616791bd78f3d368a08194c4fdfc04bd1d1c514488f30fcace5832e27efce5fffc0451252b4538ffa0192c4170f283ec096e50829bfff394a4e07e8262c4e07e265e025fe225fd412817708e97c47f1f14e105cc28f201fd7a31aa6d24edad6375f5259b15bbf022b63dacaa015606d2117b902472b56f91bd782382185b08915046d252d294a51da690617403a52e493fd7121a94b8a0f7c4123a90817201143ca4a088cb22d192235ce64eb0605202182419e27a6335e11e165ee0a005d9cbddcdaf84d74a4111475c066160c41097b525c2e8499524489e5c395204450453b4b86c4ec144042daa240726399080cb10975d573c192a9a6288cbb22ba088b185cb6c15344831830b42b5b8d708e864948888b8cc74c5134070e1b2972753cc50c465b70a132841c4652725b61ce1329827474c29e2b2182078201aa208212eb361c3133e180a81861f9cb124828d5bdb00a54889eb8d65c4652929671071d9083d50a1c46524583144e43c30c1a18823ae3788a4c80c4a8509204831e27a8340c8e0092e2be10a2b454f4c2005132e33e16f60c28922ae37191d70410ddd04edad179471847b4f6090434b460ab47153412a4c88e008f7b230038911a7f27f5548b10225eeb598584112d79b0abe8a069cea0a97c523425c6f389470198c0da369a657f07dd8018b1117bb304388238a430f465c506fd862c4ca9554448716604048e27a7b2728e121091e70bd9d8c10610026ac504308aeb71314455ca6d9b8bd333eb054f4248b505103b1058c25ae37150db8135860c411d7db3ba1088c21aeb78703101c6971bde13882ab811768b4b8de64a470bec10c7740050a25ae379c2a5c16c229841838050862b0c4f50643a00347040675c72ed915f76df6fb673e3b62de71e30497e742145a28475c82940e8747bc49354efc2bf428d037379a06720151b8927d43f5ea6fb03aa3584e8e1871031f5e20450b17fffb458bdba172d4fc5b5be1467e18460513ef9859e2f76a8088724f2f3da071902c45f05e0a4227f0e183eedfa564fec6028fa64510e1ca2d30f06e66525cae9699226cba39c711ff0df7655a61608ce26d3b5e0d937b91266e2fb3921c4adcaeab746beb24108decfd9bc9722871fbdfd682e4aad420b924ce45ac7aaf26c6aed2495e0d7c0da58ff07b213825ab4498e48aebbfec52b840c60bf35dcf6b65d9fdacc63c6377c6defe7b3970bee963c45d7dadeb21c2a46e4498e4a7adf072aeec7d1c0f19215fb07ecc3c8bf19f9fd5ffac629f0b8542a15028144a013eb8f04f30db6993fff2cd5eb22ccbb29898ec8a898989c9ae8c849ed78a89898941a15028140a8542c5c4c4c4c4c4c4c47c500c0a8542a1502894027c705bdadf784384899298ef181cf45adc1298864122b340e4c7ad8b5d64cc5e5e5ececb8bc9f4724c264d7b399af672aab52fa7e6641986bd1c0c7b3533e7ba5ecdfcfa726a7d35f3e9cba93994cef972e694f2e548f96aa647f872b0f8f1e5c4571363bf9c36cdaf97e97a1f37d5c7361fff0d00c12effae5e15fb7cc51efb0b4b018a1b6dc4b55756fef57603f22294258e7f0591f2af9756fe55e34f91d7a5063b20e30769a8b14617eef435406e88723610e14ef8e12efef53a314eacdbf1b20f8db66a3a3cc3b6b8ad60374024c7aff57dae68fa2ed6384f5f4f78d61ce369621f135692c3e9de7befbdf79e4ea7d3e974fa1b70b8d3079df08d34f0de7b5fa75380e2ce7ff7743a9d4ea7d3bdf7ced71e4208ff693c5e7eef4687bd7d6deb82646b3720fdaa1e578edf43f39098e35f11b8e25e0fbbe4ae3e864d16e64fdc5db8ab425c55b36727742892e157241f3892e1bbe6e3453c24031d91ac019ae713c9adf5304121212121950f070c819962558f9afd7ba863872f1d0210b2da140311e216087d7f1ff99d0cb9e221236cd7755dd7857d260939a2b8efd18afd46573185f2b7adab4f6b86efd17414fb4cac04c718c017438992f852ca88ab6c8f31e277376f54f647a5a67c331ed748814da37e8c9f7df62095fba2c0602893905f941764995348f6b557f5e343391383140273632f193e1b2d85a7ef26156966fd3c3f859f26ac6d291c88bb1873c4c95f9f840834516b6d9b09f3f3faf7528028e0bc02cc9f9dbb14f2fc54bc81c13a3875f1c5d534b5894d8b31d02ba9b1f019e29ec75db8ab54842eee84b9b75a6b9d6dbb7e39e70cd2363a92d639e79c736633cb66ad55e7e5c4fce4556b9015945cf837727075200a30cf57218890b6a93f7157e7552b8544579b96f8b793dc8fc9e0287f9e12851884605f7be5032863df5bf68dbb2d86fad7d34d08cc34bbf1650412a1648d852dcfdf893295e5cb77268890e3cbc767333fdebf1f9fbe7cc4dd755dd7a75e8dfc930aba07c5be10193ab0d39990e1842ab48d0ae64d3f5fc2601fab0cf330f846afb43fbdfc067cafb4d786d45c3b06986fcab4759e356c7764d8aff46eff06d26f1d060db9d336f2539bbfbeb76dd470310cdf5ec9a7313fd933c078b3235718e2c2bf9183dbbd14440166297f87e765779e87c0d70151a74fdadd7a5259fb974d65bf667bf5ea7a6d53598c815e5dff72cfedd5bb92af9a1fd657cb210a3d0455b5bae07fc2404b8080eec77f2be458e3ced3fbbb70615555df6afdf1d7587b11af17702a72c373f1879e3bddc834cdf702fce590842a2a70256dbc6cd9b2e595529e7e0876712f871d4d4a4278a8b9d05c08781569e4fba6c3e2b1c90070b90d8ff4ff8837301ff3f2619041661343dc41a28c7f96c0ffb91ff14ffc7be92665a6ffb8e85f7d035a02fff410f3c4bfd757a0f821bc6f4036b20cda9e9f1b10f874ee14799186666ecfc6b6842762d5f5f16d7c0858357f03525d58059f874735fd437817e2db78ff101e7e0836207c6c7e96bdcff5f67bf40a19ce7e3e84d835ebd69392b3ab72550013dc177ef44af64a6e2fc4937c91daf6b898ed7130dbe34c44847ed434916fab980e51a0f9fd9cfe31c71ad7fff440f1eff43f3d8f63957c7f55fdd3fb9f1ec33c11abe4ab5a38bd3f4ffcfbd967a7edc5bbc1909fb62306ece9ab7a74a6ef63fa97efd119fb17bc42ca6e8fbbdbe334d3e60366ecb5ad2795b1aff99af30f00c6ed8f56646fa612b93ec33f3f447ef52af9980cefc2059461957c8e935bddee6cbd301f86f93bf37f4c099fa77e56c907eaefbf206e217e7d9ef8f5e5032d9198a79f3e5074cc43b1ce03553c9fcb41c6952f045b5ab1810837bfdf06229c54b9fcfa3c723ec53ff0a75f4a16ceafaeac38bf7a5c6b91238ddbbfa97c3e4fff7c57490cbfbacafb715387070bc7274b87070ba71f7e1c41461f6a3b14ab76e484f45f98ef2d0440cbfdf172b40c43d27dd8b5e28d1569fc67dc78441a7f999aa1e1d61feeb115d7a0ffeabb009f62a0ebe1570cb48407e8a5fe85fa44b8f830f4c3e781f02bfeb91e62d5fb81dffd44b8da04b841fc1f3a3c54ef85f0549855ef8196f803f5d7075a32310f7df840f5fbaf4df5b04ae216faebf3f457cc039f3e10c5ac1c40602dc920b2fe2caee48d082d2121a11938c883a788faaa7c5165658dbee892bb67f44594dcbd289e39ef47461619feed6a86331946a2eed6444872fb9d28b390a3d2e5440422a79225ade1e4024a9265890c2bcc68c285833c0c7981c609a45092822394b8173b641492174532cc2f278d7b03cfbc24713bcbca7f637f346596bf27330c219944a22a464b52889861889828fd99d632436d87bbbb9472851d33be688a3bdc754cf86a1e7eafe69d20c57d48579ac81deae52619feccea46c3d6fddc3d0b3ece4d0d463eb0840f4cb2604247d2932e46e0c04319495c8e1a37bebf4c0ff73d8abbf75ec68fefbd175f743168986204263a00a35585151aa6a8f385d42c3fe9c70bf1c6be0b59661f287bdcfdc73dbbd548801bc88746f2e1917c4cee60f146f51efbc7496a32bd3c8681b07fc1ee1017002dd7e8e5dc2c1f1eb54d4b83ab192e8c0287b27c09956409a1c81f32f46bff38a96aac6ae174d2f08d799807baf27150c9cbd9d243b26a3a5e2ad2c89735e2eee224550bf74fff23e6615ea7b51d2a2697e66dccffc8bfff308f06b73c11ae1ff2907e372caaf7a725d5c3aa16ee6bcfa3e19f250ff3687fc249506adbe38c228d84bfe3e51852afa6ffb4d2b6b765d06a9b8ac7f4da9bb086efa6e2d1febe76312b3f8e0e0e0cbd7aff6897358456685cc211d73fbebc94a6aff5627946f2ef3777f14f1087bd49db783c9a87b3690f700ec39d8d3022b24dde0b88ffe67777a669e6b37a01fd1366d90d21eee3b06aa7be8a2753d22f94fd4c692d3c2e005aae0c2f47cbf3a1d0cb199a708b3f184d4aec3fcd85e62cc689343b9b4efc116188383342b77b5b324e856f42ed00309f046e890be77c135e8efcf90078391e9760cb231944a1857adac66f9e120fb75f5353e29c6d91d3b6bbcd9fdf35de6091dbcd0f865ecdcf41c67d59b553e4fafaa70cbb88697ed45646ee4fdb74af0a19daa6630999f62d9e0f434f4fe8244fc824cf22fce6d45431a85a30bd7d1e937d1e15c52a09646f7a1e8c3ef6a637e11f229cf63ba67fdccf67b1f072609e2f5f6a3ae48c3473bedd6a9adc1fbd9a2ff14eafe6e3d8e1367d9a8e0cab2416f916ff40244438c78ea81cab5ac8b2c7de2dfe09f2e2fc0c13e188703a7660883453e99e70c5351a755f2ae81c24ada4032b8caac8416809bd32144514ada229559e706184c5c50e193e8e14bad882c3ea6229c3c7914286aa9d17697cdb3ed2ccef82283f31f243e22209cc8eb6c39453af06be0066b8ff020b4e126c86b8efdf4bede83f000bfe5337ef08891a40586305581061c1c1e7019f051f27feeb58f67b5859fadc3a6834ebcfcf121efb633f688908121a9d48379f9fc7c9ed659fd8c3ca8deb5b9a53261860cc0ff8c088152c21e20a1296071419a24b193618010a76180109152b4ca85072a28b150c891d7c0002113a18a14405078568d23aa2061a6cd1032125f0ca8204a12221a4a42f949070a00452522b8b0b49a9480b129724468084193e2081153f6021b2c20a2b7610c9f44f10abbc35ffb7c1fce4ce8d34f2a12ca2932499aa16e2d777a1ff52b5d01f9fa73f7613d58a7ba88fbc1af96f93b91569248aca4df54a92e0c3854778b0ffe9c73024d221a97835f23312018c5c988461ab5712070e6e67e5bf1919db6d9816d2bc1af8a88eddab5723d34929e59572ceee5019c68f714ed8c4abb1717f3edf5708a3bf86f3755a6e7006af264624453146a218e5c46fce984ac59731c6fa85951faa0421672f6f269a1010c4ed9a684b07b564086de00ecff1c58519e64f3fbffff43a0db770f991e3c3d3c3e0d306b5b44d5ce554510849adc591fc90b41842b232467e3e2dd476585ca5114d939fc38bdbc1233edcec7900b1c8b492da263ea44a57a011e7c300ad3dcc14a5f930409e0df38c568eac18c5efd819b66fb242240db27f3469b8897a05bf89da080db24e6f01a438a8f4ed573439e8d0cc000000004000f314000018100a05c341b1784c26289ade3b14000d7c98486c52194b44599003314a21639031840000008008c0084d6d144000d297fcdd9f685d7ad3f019449d5ce087b404118f2ee5bea739dbbb9384518401c443e7590b026979b9e80c1819a6a4186f05715789eaf8032accf12570201605e068b89a29be0354469f4291daf82d1798b50acfc3207ad4c1099f1a07c649ebc74bf70d1ec07f66439b0e24cdcba1e550be9fc0b4ad8d8852b13fb3eee083106be3fad5e10efcdb087618fd8e89cf234f4d4440c524722e8bc064c623787894cc0a44c780ec2480ad0d1a3614a4f6d76e2d1e27ab0faa5800c1be9750f0d9c43d698c7f2d36f85914c364bf15333eca09173fc910e0979a93d4ccdd9ab6553e691234e5d0a760690c667a89462570aa03d7e989691ec3b168c7cd20617c884e6bbf6fd9e395369114c395997716ec8b42c29e4a352cb33a48216b75333fe2440e77698947ca9b15aa7199c5a156339fd5eae6588b152c1bba776274c5d8e081bbebc519417e87515066547a5df6bb9a570d37f62180fbb838e14807166e44aaf9709e83562374033901f9e2da695c6d9422742de1592b0f5e8612548d40d95f772b0a5c0a2fd882b56ec333b889813062f8ae10074c909effd8dd19548261c50d1cb7593c1e181f15ac73ff08e5b45a42345c1036489618c2f94f784bb35225fdda00bf7e0414d62b7429f82fa4852cb40849c6a5db3038515aae14b6a21f2e76435793185205faa05033926f66915aef3489b98ca9e5e813f43a2f0addbca9fe2c05573434a0340b95de74aadb6f0aac5bc44c661bf9049d25df6e69f1a7c1f736fe55b8b2fe91582da0b8592bd9444f0dd1e88193ef63b5ca185c824f4132a349dbd0460ef9057003b0430d6e2fd2496e0f8d8feff2bb36002d13313023af234500fea7565d05205668f304f4c37c3881d15b9a25fb4ee260f2bb253ba844486880731ba1e088d2bcf60305d561a03917678e08749149b909aad47c3e20216f8e00a183aa44e653057a11b83ec36fb7766a769e11fe3d7f7b98c17eb66c660d9a0e687ef5c0971d96e29f5122d90c8072c523265284b2485b007e0591463da1ec710cf620e3ee834e5d6d47710c43a258e2978ae0e1beeb77ff9e941a3e902c1b18885c658410e9f35b6a838e392f5760b05a2d5a6d94d6ab2034f6c17215b60fee55d473728206750f7b011eabd44bb53e1494cb5c80f24bb53af45d07a782eb07f4b36dc043964e000ad70009217d50f43ae39407b708f4b9e47ecf1420dcf9e4cb4e04bb6061fb06ca04955e0f117a85e38eaadef2d36b630451875f37dcc35ebf2e285fa704a392e031ff6615fe3c817df1c0f6814ec57e860cd750819617fac370bef6e4f608522e3d62489e1c03ce85b25ca447fbfb416807f8e44c7b174ad51b7366b8e022573cac97572c04e373ac3e1f1d5b2b3882b7a3bdbfbc2ecd8e786ecb8b3d66a7625fb7299ff260396956c1f1198acb2519dd653b6420b5ff4aef8e7e195e7ea0349544adda9b83a343080aa6589e75130558e0c4c85d978afa26ccda601325af88aee9ffe458cd4ff4115e510f29f5e0b11f5cf82d23509891bb1d237cfb3966d3564e5cf1dd2e8128837ea60af471945c17654460292c89cc9d81f90de1b832312e9c6b3d87f855530b7dca88fbacefdda855bbc23eb95da85cbcaaeab3fd5d3a1a438be64ac933889e4289c6a5f1cfb5eee7ce76a0e915fb6f908bff77ae3a14d7dcee829d02614c41a5240991fe24d63a0e788cd2985d59cd82c052cc781e254b717f80327eeea247a24aabb1924e6f48608a3e4cae6ab69a9852704d6ddc1b6cb1260b1bd7f2b9ac2ae2459ec6d68888712cb75a475eb3155562c610a8cff66e8d051e427969a9657b3a2c90d11e0ee287a40c97830848f85d026509ca09408b2b4ec33315eba36672234c963eb104a4f13a91961fbe6346fd3e578e67d6ec7d4f080eea91d18e7f7d1ec557d4106b44634b6530e93d86a9e7d290abd22cd85fe6c02c71f0f2cb00ea0a3b802f107210c2803235af5994c831c97440974a295d4b480748313fdfc59eb825645726d4a452e09e97cc1c3c270823a9e8bd17340bee20e3bcc7d06df209dd4f3c8e8eeb7bd8a859365070693f095f3d925a355b40deaa113a52aaa2eb732698d37cbdc0b580b8463d69d5544880050655bac9e13b5a42a286e79ca99550cca58b925416013c0a084c61c690ffd837ad36f3e0332151e1bf7ec533e4ce97d7968101ffc129f818bccce918138c5b1746fea04d03d6c8cf4fd7b535b43ac164c3fc0f1c5aa21cc158bf03b1917b4ec8785abd0614cf9343fcf2be3ad2e37ab1a5548d75969f13f05849b7bb6760d311c0fa13593bb44c17c3cecdb101660304169da4161fc1fe71d1216eed8cb405602c3cab5d3683c69c00222de9f2b1deba46225372a9d34ed713849039642d7b1d12771d9e09d6edddf55d217190b4f9016b20e3e8ccbbb8969707ea16fbd4869922743a71e264d011789ddb5b309151c166e40ca07096682ebc716d1f15538bf0c796307f33181647854838e811b0bfe0dc742786e7c331bca52d347bea282b3243c5d114970aaf4391dce67489c95da90575bda2e8be422a7b68169725247683fe4d6be2d2713d71052d0d5c6d87117c6fc8a3884121ba2b15fd74dbdab381065047d080f9baed169a9b4e7fb16987071cc8706bcb7787a3b626a8ec1d222dd0108c8c2deefe259d607c5729f05dd97d2abc2ed7601b62b9f964e2fd4dac38d4604b121cc2d640910f31e8e38e4d64fc9842513e6e385ff769ae328d4e0229e11dbc9180a5c72706f9ec71c32534674e433bcaa5946d71190ac8e670d0919a0a51c2bb5b6d4654797d384bb38d63cbb733995ae58ce5ce40134114d2c43050dbcff009afb4ebefab830eb297f5952fd080f5b2e3ec4950bc7b094ff5b845968475d65864895e91a95745ea1924b8f52dd4d7983b9900a1219d2a0d7992fa4bf56d0aba7ac1c01b852e64bfaae8747f4d2c8276bb9ec9fcc2b72cd0b4d443cbe8c50ecaf31f99e9600830374f25c6113d4268c8028840f78281cbca2a3fbfd3ec689b0f80611df44e2476f76720590f1e0d5865d9618cb792adc19de768e693a449f62065d8e9b3896259bf6610825ddac2d4c2e4e6e06eef342c2e7318875b3909e9f237f17ea29135682329ad20b493381e8c03147d84ccd626cae2b74d49e208a11b0052e0312e39bae78da55c4a9039b28def56a0ebf791a474b293d6e358ef2cc1e4d8c0f1de1980f19f4691d47ed441780dfce823eb0d40065827e947452f0e8f18b5b26b071fc43842cfae238ee5aa0ee019eff551195761f1ae16f07df0cd41c69e778d0ccc93771fc3bb0548e6f0c0b86daf3cf74d5f4a12eb02a3611896a83480c56b21ca1509af25cdc464686e0d993624a27b206a07a50f6ab8876e135f51ed14256c014838c296dd9b93369e457cd29440e6b78450945d7d14aba3c1510aeb59d4ca2b967fcd90aa252219f9dbeedc63d024968abd601dd3f600491bd26f4447b718c0d690f909398e9cd39d3a03bd609962e596368864a76c0a83d8740fd0973e64a1526cd4d16dd106979012a1ee99eaa877dc0139ccd5a0a55f5dba610c80c2a029b3df435a909911c989e84a9a83ffb2f51277c133916d1cc7ad97f8d3a5bc3de3d5c2f4e1fe046e9ed2ffc8e2e0cf3f6e4ede21384f99e96cf65443e24d88c14574582751fe612da82af8b84996c2710791493949b625bc08171326650ece837ac9a6e5e84441fc54091759ff56b0a3fee5ceb3a5ad1abf058091c976c233ac80155ad009d75d03bc4eed91903f6864597b9a4e4736b6802cde9d6c2d0ba501f5a4d1572582803cd008dd3c76c26b3b66f90777b495c0f9cd5a0bf64af2e59c60c5507114ab53b1b108c0c66319020f9aa013624d49d6c279c99f98ec397d2c14b1e63b03d0088e6da4fc8d7757224f6a19fa841d1c461a52057e4aa344eb76ae10cc8a297967df54fb1b712aec3c3318f9517c6606f2908f25e25506625df043ecf05abfcb05997b59c4cf7ca5d0fb758fe1d4ae2acfe28e2056f7103c8e4b822b7e43be017871511554a0541670ceef9c07a15278714401b5a1221fb4675aa5ab041a8071fa4ed375163e619163f6e2c1f9854d12f4c070b5b2395217d7154400c23389dd2d1da612d2931f16f04de62663b11498f3b70866bae6e5740773729c9fdeab5ea94ef6f5683284843d2c0d9dc7b81d073d1761c3962a085eb0b76a85df0decf6ce274c8d19407c0032289c5327569fd0d6a664ded26f89544086c4f79dccfffde4edd96b26b68bcf0ea95fe7c456d05892accb837475444deccd61e40f6216593f705049c2e29f72b04f378c93c10adf45084045d01b71f72af7df743858d87a633cd254d35b66c4a2b4ca863564e93c48262d1c013f27b409ab00f7bfeb24ba7e85bc042b31542d3aa85ba1a5efb1d248c6e146a6a7d967c6882205784994930c048c4ab6135a6ac0d6daf1c914d9efa68ca09c0032a347663898f1e3e82e0f95dcb369787b06f8331224c6415ff5f5b8fdfea4287307e412b3f5d23b07ef9d2f462a8e5db5d153cfcc7234d46862e04f23a07d98ac68810c1771583f2eae208e3e421961639eeea7931ee477e388c7f105b8675ea6a8a7017e8e3f25d4f828dfc172f97e10e06498c7ffe6e06c89680d9c17a6d997ec4807f69d12e9210a247d5a68b51bb07c39e5cc758da3bc6088312e5eaa99189361a21fa9e9932f618fa9a399e102de108f3449b9d880261c7f8c31498552d4920f3a27f0b1b074911c8a649a5686ecd4c9c01f4092d2e5f68d85a3c7c60497a1830277ab0b7b1bede62c597fecc800ce932491d9ff40c518de77b9b283a55606ac4a2b104119cccdce41c916ceaf77dd9ad1802eca2a92cb0a0cdcc4f08c44aa24885880ad582cd0306b8451135560bc3dcff017ade001a6892ad4b80b13e5a0f60c6b7f981876bc1f6e1beeb3ea1ad91e3124faec8343f7f21979d713eb532a0d4329f69a228843770ad39015fc4f507211229f4a2d3c197262b98f3b22fa2735fc7a3d41f0f4caa565dd5575d8b6aad6f68022e4d4232abdc3625f7ec272f3d05efcec49d74bafeb45526e7e6c315e6127e676921c536bd44276a983f3d8c6abe95041ad01e19e10cc878f29b067eed6beaaa53847ca879fc44bdd8acd0054afa95b4907a5fb565a2044e1d77f463ff62d9286da05ea784819909bf8afaf2bd1df21c73a2156a3d0227b4d74b8397437c35027a92f1afa524946fac6a62f63837e763ce443d076913b169d36f31333d3904ab87a61dd47e4145e9af688be8b7dda74fce44a6c36dbf0c4c022e5ac0c088fc32b0a93fbc6521c197233e5088db795410c60db739ad4a78fa6b64edaa2f21e2b5d9ca470db47b2c129d5df6586c12b97fd90929352a7978052abfd23fb04da6206d3ec750d8c95b4d79c2c0e4825cbbddf2e05660c38686b688cfba9d4312501106d058c2cbd6a7d0a4916a0640b614a55481887e908fbf490251835157d15f4d14c8804419a31d46ee5da3529e2e3459cbdba0d359c220be2cba7073b6085fd9dc0dc1f18b3c93203ea55adcb15094119a8864e98f19815b31681bde2587b424bcbb21ca0a0c84e147f27243b288eb3063214ef178027f18402369cabf5596fa0c800d5d2b0cc99c93e493cc0acdf4dca1194ed3582f9f70f51da4657b31678134a7dcdf831aca9820ccea8419612755d51dfc77f9f8d96b91bbaad34c5e6e6b3ef454fae918a337112f1cd30a2e48722dd1a61aa03920c82c33f42e034f525383ed6c1fadf20e7a445303a7004056c2d01abde6313f87e1cdd7980b290b40faac75c7f40e8713220629c77ddeec3acfc09f5df757c4381cb6484beaabb43afc4046e93d3b0d2d2dbe8ef0910a5b8aa2148927fc6b9f51e6076da633755a2f97273294bdf3cbb849834ac9890cc9755c556976656c056888920fd36fcb80936104f7dc6217b4b4762da97205cf822521e1441c9b984dfd8f218641a22513b76fa9da5becb5f7cb04132503e04ef7b8c8fe2bbdf1407dc917d14088c55cd82980c28a2b1ef9151ce6029a4161419f145870992f81eeb8bc3d07d42f2d0e8d7c27826e11946701e3ac592e6b3a527b86f047c25a5510d9cab18cece06f51fd27b06641339639a17a580dd292d49e9d9894505bdd41391d2c757967f0db8c03617a6ecf99a6aacb752f18e339a1fc318616d59b2915653eeba4a116371ae5a0816e41316108d6a30881550c80aefda9e347314731259e049f33a716585ea0ab1f22a41975bef288dc721ac896d4fa0f72b886fe6a9407431bb3494170ff770ac30fcecd2625c0e8f91affc6dcabcc7b4b8ef22bed169abd2cec1f4dc113ddae97d61f21e5c887393c65da9db34545be79539eab42addcc068c46b042ce5f6c1f4ac38c2d0fb768d1ceee2f859a3af392e5faf0d8464ac1dfc3c1b100188d0e7f0faaa55b965da48ebd3e4fbb4b96e5f161a165d9073ea0afee3fd73ee006e8d16b0b8fc54e0907146dc8718be7852bb1374b1387132f5645fc7aca9af049834e43343749ced93d1f227a0552693ffbbc385a27c96064048442a672fb63089414a2ba39ca2122a153e162fcce3a02b444cee46a61e45ba49e50c3c4e009a33431bb929fc2eb6762bbc98a821bce5e81ab0f89c1c67f7a4dd87a5372e719e42441bc43a2bae14ab93f82a4f99e4310ac799e1bff0553378acd1601977a7434efcd24df500bfe6aae29bac55b35a02432e0ea826c78a3e15edd580574dbb0eb2d86284310d60d587506c16965e6f40fee4a93a85b3e8dd781ccb316b442dede26400187bdd4732fa1b7db3f84b43a8e4611a3f8a1b2e1f5f42b2a59b8fc7d90ad7986291c1e199dac8e3f64bc6c6a3683cb1a7e62a29325d4fb33ebf8493973f00c738d052486c71269ed540b2f68c52635ae7ce00d79d112485e83746e0d54bd00cbe1a1cbfa3ff9f949de46fe3a91cb4d38f78046e696951fbe8fa43f69177dbfeb61b7b02058dde4d80cda6f57b622a3606449efaece5d903bca2589b35a3e87edf4e1e2bcc6f14dc2cd8542da68a8849ecb491bca5064a323b85612b4de0d84670d49d7a72c14e418a03fde0da1e8e38bd0486efed5e92fff4d2413420ffa4eb39e921c4746e7c483851b4e02c8b9fb8553923e76a4d376f2b909a4e8b8519c80008ec389c5c732be6a19ddd83264109e138e4defb854e474f279ef91a83b4ecc2c575267238dc1464d2513a54aa659ae808127fd2ba6172d38615b05872926200f97b097302806b525375e61ed6b81d20d71bc4f4e973903ac781e362dd39d8f47ae5acedbe233330a9eb262087e0b77e7d3d72ec9ba707e59ac2c4fdeae4983c13c793bfee9e91b83bc06fdc066d8bc6debbb8fa56b73db18c28577812ea65b77ae7472d83f721df0454458c06f57265b6ad2b682640f2c70425912d1578a628e15fb921ab8efac16e560649e667de661d1de02e60bfe2c125c6a7f1cb8b56b3bc03370b7d8083d2d6e07063d1836e5be12d0650beddd7cc532f0917259d306937d35fc12df035691d9463bf88faf997cccd7797afdd926f0535ae07e4893a909fc1bb9742739059f21a846c78a59edf9bfb25aac07f890d5eef9ed64c96a81ffbcda43ec5e2d562cf0c016d17b1affbc5a923aae6d89c3d95a23ee83a4d332c97284362b95a211a6b0cd002c215edf5b890f194a3e383f189705abcb5ff65ee7d02a3bd7ea50b824a3512c781a0acae0ba87e767d00d313cc04e997439e4c8f05274193151afc2162ae077e33f45419dbe36ff7a79568ac24f8f09e859af70b62cea6df58f0bb85a26ea604ec5913ea2b9a0a17800904bbdabb0da8f98b53e2ae27d288371d970e4e53b88e41de38800cd3548fe9bcd02edb9236c210aa29ea03b8e88bf28d6cf087bb3ddacfbc23befcbaa4ef400942ecdd45101014e55f5865fcf0b900f68c3b9f4e3612d0de40c8e13c9645132a550477d62fba962c2069ae468eda656545ab81b09e37bf1a2cd29af52b42d74b92829e1555165e548fbfc29359553012d7795fd823e28dcf54e2b1681a8f99e380a377c984256e2ac6c30d469b3de2c7772059540a00d2f5d757b553355936a69f0cd6a64d7e1f36c873fe6ce18a108f6219478d4f2cafc8910314a041465b85605d50a196b872fee11df5d86db84f448798df9a6fa1b0d3e2b8b3c338202031540878b4c4912a1953e6ca5b35fab313617ba6f7d3495db7c6cad8f804f5f4d4aa52d231279c35202fae6f4c3726f18e9e159affcd355856cf24f7afc8e53708056fe7a663398527715e437d096b49b43cc0a12fd81a03d87b5c22207f4b52748a94012296b3c39208c9a6001b5b44f57c50426b982a2f91716563181db7720548c096ee34594a402cc6a4c90a6be02446a1d05709d4b05810625cf2134e77b65d513295d4ecd9cde2608df67ffc55933f9028c4ebca0625889007a89b5a2b8138ed98b14d41561befd0374db1d92753f171447d728ba3a6d3bcdad5828169a558604fd628bd2a5016cb156f2125a7d2d2b0c5dc551abb54c0448cf3d3703da94e54d120731603b792ccdba85f2ce47c71a983d04ce230f04c4b1f84097f987231678d2d2b26003c66e783118a1ccf5443aa7210cc1aa88f8da248b6b1b402bfe3b08e7a4924c00b132b1261107c2a470294a3d312e4ac9ede00faeff5197e4b893c9fcaaedd9fcd16116cad21bb0173371624deed36b38f5708e42454148d94ac422832eb5a9433db1cea90a2d289926efd678ddd0f81333507f9b1f83f9cd942155ed891537582a267e1305b09a6e417f4a67d769905eaca9981165ac2f2eacc33ca9f87c2b0ae9b294d6355200f2628a946288f2f9e20453ffae2a54319c89ab722ba6b024db8233a8f3673f6c4ff85a41eda38a8d2093686abfb6a963efbcf9c021105d25d7039fecb3248439a89722d06d87e0e0ab6774d5425d4ebf63b6e5d368fff1c0717430ce7e6fb9c0441a691b68998a7a6afb03274eb4cd21e7a9e872ecee0879da2f0756833b0e183f4d61c8c88fbf752734e78900a08b53e9dc810cd83e95f56c4b7e1177dc274e650cf056454207bb47089880760fef50269015dc4a8eb279f00deca3d2e72db6edc3fb81cd3ddd715d510c6f977f71a1b80ffb472f29a78755db8759e9543242135b07581c7de5947602a08e77fdde8706f36916b55a703adf5c44ee494325b27095fc6054a4421c297c4c0a140e8dc8ddc31f4d7d105aaf008d33dd636aa1666dc0a638595f03394d1ec7e4e32722d69248080a7f8b574c19648cc1e200041f4980b36b5d69f5cae51583d0960c3fbb3d3459dde41b29920fd9a2b5b73b3e3460da38084e51f4452fcae41f7de803a6a21d3cd2cf4e66746a8a1ff131400fe3f36094fc63a6bb7a6fc7ddd3d209c0124c8358cdb24c633bc3056e704af21420e34eab7d5d878ec34be71cb2f30938bde984f1633bdaccbb71be4e460c2875b34b467bd8c271810531f41fef9cfef32f9a48d34f032df59f7ed2332047457c29637e19b2b5893cdcdffeabd4f911c569a49e009e40c36de672837ab9af45ccf76ac31f48838bf3563aca89263619165a705d3da6cd396cab9bdd8ca789be4491a2089315080cfb2531637cedbe482c99ac95fac81389d6a37379cc509291123692a20285c77e8b70da1ecb699dc62926f7efe02823775152f163cd9137b162ce817a73292a0df95de97d4e5251123174a8cf590dde9da888644862d5c1f99b1ea66412cfe0f4aa63c74b949cb53a62ef7adfb5d13b20c8ef175067fb1f8b2a71faf7b4a31f6b6724b643a4eedc8f100b6ba0f701ee7579a773a71f4f428fe5d65f89beabf50e06fc6608164c82d65c2350507a0a4d43a86ab340b8365e11b5f39358c0d2490fd217f060e2ca2797a5f9aab874d97c2063ff5503b41581f59d1b4aee5a40fc92a42ceb2a2d1174c480513ba9cdecfa6caa5cb055f2c9d0ae8a224a93b5f9abb79cf56a882902e6931d1acf4f28198b01fe332c0600bf5f9b57e775f44cf223459d531901aa3c0c52fd505d9c70274799c114f2fd92713d79addc013ecabf2f96462f47f2e19053b1299d0fe05fe600f1f6e2ff26b34e8c99f771d7f6e5a31e742f35bf240598abdd8d382cd7fd5ca2399d32b442ebddf8ef97442007dc6f0a44346fd1caa8fdafcfc2c52a68904cb6b38d32630bd4b96e00ce7dae5b442f172538a5d49719bba0583c726bb3440a66750a5f0a340ee2a9b500c61a3786cc7525ac917e16261ae11059294181da6e6a873563891a64bd37132e4ca286d2e75ac19271333e6e115cbe6df05176b7b2522d208da0838ecf2a49ed11ec980cfe430718c826b9035f884b7824b5e48f2c1d834a75cbf46ea4c770efb104ed10d7fda25f5e2362fb63589a98162baa9e8c454a436908508a150cf42b03f74926b02c0f094f646206a472530dac15a076d00174e5bfff6859cf6c05f721f51f3372f076f0a3d7b50941d96f3caa5d6b38522a8067a05b81bf1e0549cdd4472187f46ec8e1de6494a71adbc500e05091d22ac5469ad679afa06015138e5cfee417c27faf6ebc9b281bc12fa179e8602bc27136bf13fead3d18039d82187a504a797cefe9e9e427681e420659016cd9d9238648b6636a12ff4df953437f0e9e63b273d6ded3d435ae52438ae5a7b5eb3d34274f1ce59f0603422f8ae4e5fbedeac8156f7bcc35a15fd5f43a20f985a73061dff36ef91260945564bc8f482e7bde4ba2bc9c93058607130e29159e642fdad71f3136108076bed2c33a654dee0c5aa0655a54c4016ac0ade832e25189dd0c0349cf28d8f60d2ee14b53c9681ca44ba6f36a72f0be7232b392c4a2d9bd058d304b5f4a2010b92935c804082da300905589f3d2237e0e9920a276e9fb24b8f35841a64ebba84af6c6543d155d4a8664472e5345d33605c4460a01a575b49dabb637277af61c93912d7bef132ca1c9b48b20a76684e5e6576a0d111c1d5932ee3b0278f022b001a423b76d4ac4078a94a8d66398411ed91b875d1b847ad6be154cd739cd6b01a0c58577bfdecf1a3591dfdc10758b95c2b4e0eb5f4e592872df78c9a101eaaf3a8577f856daff03cf0db6ea88a576e59a41baa3aa08a0601ae6fe780ff5fc80355bbd9c0852760221feaa05cc28ef2027f7201cb279884a03ab143577df4aa61b9da8ceecce8a90f5c05cb3a9f4cb015010722928b50f9cf763ba436357d1f079283e71fe6cea28cfd3826c116c10ea26ae59ab4b240b82618ed695bf87ee82692c098ba300d929cca420e9ef91862dc45ed550499e9d0a4117145762e73114ae9bb9bb81bdd6435c457ed6e668ca6a9ddcfb049019a122e4cf999e9a4c24d59f22601072085b6f839256d74ca01c1d1afbb4348a46543a9bfadf63e4fb9331b735dd4ea4547396e9b8206d43e21b288bbd4301e331f8e23ed1e0a302b9a153a89f5597d9379c56fd96f57afa424a9de045edeace0e2f7b9cca84ec3d044b5790ee7eba30b249f8b1368c64acdb9ef8c6cc721b0d2160eea23476fdde6398aa6339bead71abee27b562453e75b1c36f9f5077490568d1b29a01280c53b3375e4f8940389dc6d8c0c982bda8b51d567b0109b7d5165b10a1c8863cd1fcfb2ba0e8febf252c7acf71881814e693c74be38a2560f868b48320ce19f66d7fe3005b051966d00ad72d4fbd411ea0bdb89de2bfb8e67cab6607c8c4128efd11fcbaf9f88fea7f679569bc841edb02bd5a330b2a6faa4217e62acd3c2b51e5ef1bf4b78b55c4a9c66c11d2a41ad5aa53ffde97b134893db6f7ba185f360e53582ef9ed00d4e3d18d3e072204be56d61f5c33249b5d5fd601d1fb08053501eef0babc73b99980085c9beade1ea236a16151de9ba9c1a5fa2681dffaf77280679aa6af7973713e1053bedee38e9f45e1bfe54d5a4db26a6577e469e873d48c020eaee14d2cdcf86b4ea2488759dd141828f228e7d22a5a9405f4f3f804f5d2404d11af904e4a1ace3f7507f17487ad2f65f0a9af7eb34185109071c272e0e281e780fe00a3c62d7fc795b63ad504044e7a6086ac11093bea09127ca8da310de567337d31e0fba32239356d31d84dfaf5ba5246c84008727a6e15f80c7fce826fc48602396d3af8c230a7de700e5bb060a8480ac47670a4d21f9b6beee83f1dd56a9cc2471ed1ad970de11b1e6ec49e9a234728325fdfc01d3c59fd44a251061f1f82954b4b698aaa29b2597b5c4ea403818d57256ec975910bde54a086d4bc578ba9ec15a45f69302044f4371bd3fc3746ef4e201dcf5d20fefbef06296131cbd246cca7e75b34d1f9a7d872dc63e1ff18b4358bc324ba21f668503d89aaa777440c03eb7b553d7f86a5d1704044f9161835d6c1b3aa19719539458452ad1a654d97ed1a46f54caecda5a06d7375dba2919326fd9606527e88351d12b9485df10044013806b078041608b2aa5039b354857a60fcbb629201b80a54a7df5b001c1c3afd26d731a6f9c047fa715f6047686a138df46fadd795986ccc2f7cbfad3bb7d75ebda8692b9d735b6356eb8db61708a8073dbbd2c11f3dfa2ce2d786d24e7b3ae9a9dec5892bc51bc49f84dea31b36beef0bc91433da27a4efe4c858309f52d51add20cee1e48589483918742ef6da03af5b64fc0c28fb11714780c59b2e860925bb2f0602631e169f9fb1319cb4ba63381191a0e02868538295d995aad364130bf1b31d1c4ea5dfe4d9e802b05b80c7b8b7bc0fa461ff1da67958f5922bb192bbbd5cdcdc839b871d0f727bcc97546cdc8a292e68b429a62971318a6a84f430a0e58b9549fba5f7f85fce62955cc1f62f613c8a90ec3f1876195e9366a2f8cfa325ece83a1a8353c4ab66414028f7bfea98e0507354d19103b520203a6e2d8b6e5d59acde8d4e03070fc01c8ba73efdd39519b269ee9d5b2e4bd2f462c97edd243c3cd5ffada122681376b2504b48a163bb93aaf5d8164e0599809fb45f39804a51de0a5564dfb8339c096ec8975d9fa5db8062c6910a3ed644aa95da513a31e8acf2495fc68118911a0cf845c18fb1ca02500d350f5e0f3ab767c1ef8a92bdee44a2af05c2ed54a1e6e71942abc6ac22d33a86ca00e634a6735f13f185d8282ccaa69c9b4b5c0cc78d78bb5de9e2a8d1f823a2b8b865e3d952d525db84493088e902ef1aabf84e0cdf71694741c030f73274ee30f579c200969d7a68c0c5e134403fc54dc588657eeb006ea622a128ec772ca0c8341b183aec28069780fbb69f05ed7d408a4ada34ae54b78eb734bb8f516ef7f1e7e64089c20288b9550bc794b9a5ced7c36ea06ca4f5d134d238b4067ef551cba2cc0d6f94226532eb09eec397089d8eba2e0ffc91854612a26487e67e603e20183d6442a535c226eb459956214e84b348791298259c3d97621ac746d69a0997160e422a4860823f0cd416025d87a3d47a9e7e0ea112713b11865d05f576a7de806f1e7e013145be60d5d7bcb46fe6af43db393850a7dc83c8431097694cc61e962b1d9c1a692747ae6301f6e24496bd1c6a5af1b9c55633905d4a82cc3b49e0f3d0f070c16d632b7e1c1804dcb267c729abae27d56aba119616d1f7596d605e414e8d644cda1e02527b643d3369bffc75604a9e0f3d8ffb662d59483d4c19db5ef0ab622d76df142dc726e6130d4cda7a8224f9312cd6682d579e497a7f765cb6aa4ece260682aab68cc956d69f871fe783471a742dfa887fe48e7f2858282acf65c0da824042525e2e4be4d06b5b68ec3dd05ce6fbcb59de1a67cebda99e334e668407e54383061f6194f86bee556c325d6ef9d07965da0e4f1d92b0a46555b34f8a5ef542104e9329432d60a85c6716f373004d255d55631d5bfb3763d1628fa2dbce4cf98dc7580317e59eda722189d04c4cfb3c021682162551399747a6c1578217730ad8b2b2aeeccffc3a3bc5da181986bdcd70b7bd285b6ec4c5ff6b614bc2e34a49d27b2e591596a8a1644230b9d1da95642184e1e42cc4c28d1672b771b32a2d2070493563bdd0e577c4cfb67746adc702dc6d7122c70750ec8a0054762ff377a133815a368f4170ff4aa6111301d642ca1765d600b3d74c3d1d48d1c5194d6ba5c0008b20091c183a243c000e1497e5752ea6ff87aeb655eec0d4c93bda05600c9378d2ff19d6be180fabbb7546510b5032fd9c4f5b93afa2deb491733745b92e96d7fa7cedf6644bcf2cf486eae4901c0c210d5e85383e238a9f4e69fc5e06e172495a6f8d25c747b17ba3d5ea92ebdc3e32a99819c1d700ff29fb007542e397824ea887f23902e2b7862d6a8020908cf35b58b6b107ecde7e54140831380825d9734f8192abdb58527c5f87a81ed2a7bbba6523d6b8aaa9f1f6012ea4e97aaf1e739546ab0020fb00a1f8a7a655ef9cc253a234348ea2115a900daa37f5258ec70799dd9818d02b59db75e5784b4d35892aad01e0a7e588f47d7e5dc5ca3d266da035ef8e0e5fd27bce6b4be227a95bc2037d1fede8d40de692b8a41495971b525d6c80a48bc227f461cb163f79d56349038ff005978a32a9914a6331f2f9e31ee6eca2384fb7b312e68a0aa29531174e0159d744903705c3fd20761ba301632675785834ad4dd950c5f7829a16260e5e95e42c8207750b58c32bd0864949ef93fe6119790ed92e3258de2fd7877342b23beaeb2ace8b43812f687dc736262bd3b847e5d403302daa8022dc265eda6ec7fcd82fb14501adc1f74e0ce54aea7bc4dba51a06ffc9de62d0fad6ccf26f5cb9bb16c3f070a61680d80d874038e43fd0e2f83710ed67510305390416e0280b6603c4898a1a6854554b5558158c837d13f3f6a0808ed800963acdcfd7729122728ec8129cab2049792774524501b680b4fdddcae21f68aefa4f1a840c858356e3e60e296c519fe6fbbc2d83e877ae44c2b2ed05eab17dc93504fd9758603aebe1f3957c40ab0397663de01bf6fd9e19c3588da28b25dba93f040dea874facc09d8f8e225a356a82ba22b680cfeb830c7907521be98d3dbae8fc6908e0d2f63969357a3a5e5b7daa041d9e036a1cc8de70f900cc34a8df1c367bb0a070ce909c5561d7490f82847303d76a2ac8d142f1ea08cf24f13f867b3aa44ff4510a823b53e73808a167b86e1eb005733693a83dd293e6e1e0dfa2cffb4187505b34e835caba770280933d70ad81e17a5617343e6dbc0d2953ed462bb33ce59e9a55d5787c78abf757d32dae96e4ccf1be02247fd14bf6dd680aeace17c205e0ba3ae2bbb9e1a93a6c4573e6031f9012c108f46d3c4a03d54741fcdfb0917f7cda12ee7e10fa1c9c5abe55937dcd0e81ac7397fa1397a4be9507cae6ec549ba721404b91c653499beadbd65b717f125661baf50f10c1bbdf47bcc87e9baf08936ff39e0327d3a9f962c4b0a746e18f1e280151b29efbcfd6c577bfe7005debd84b1b710157b7b80778982be0d038e4005662de5c44f1a79de8c21deada909daa490b39b03ed9c0234841805e7e3f59cd6b471caa8f3ee3c608793fe81b90fd3cfe898c3d887a08e777dc7449e9db0569a5fcf3bad028440c01e519594a09178241db24c69db5a05f0bc6530d21e9c59df37a001461f88ddfc7884ef3adda46a571f5238b81adf05f07d9910edd0ee4c3b1ac87e0ec0b1fa12ce9457b861a259709d1a2f5c9141331fb20f4cbf414de29403153ad953812c05f23379b498cb8867494fade94a29d352e7a3efc7272ae97a4d67540927f0f8ed1c18366f852cb60267dbaef2c6e22a048a706714ff090f9b80d1f225f80bfc72fe2cf82d10fd4110cd832aec83930700477af3bb5bd949532abfb28a4199a5f0c720c92c0fdd221daa58a972b1210cb9e09fe56de8ff22e6acc125cd602086e82ab0becd226d5b82eaf56f2d8cccef9eb7caf968d412360664226baf43c05eda89d87382a1aa3ba08bd5dae92583354128d331697eb813b68f499193f948286aa8e39fbe5e18c16c42de1956638f1761d8eb971c00ee7d8a0f79781bd380782c7f411a99c4dde1846b206677c3d3692e916c008185389451d2460b0b1061d8b590fe5d770d07fd9059049c11ac59ea01168bd175d76c0e91e631b4f97f9fca40f2001805c418c82bdcd427364ff3f9af454afa8ce9eedba72088d30c7b96bf34bb9546642e2a200a692e091e5fb1a921410536d77fc03a0290c7086d5ac3552e8fe56be214f33dec5a936eebc43e2838013bfb011552f512ab1f0c7bd722f21cd7d22c0ef718ef98e4dda9822ff1666e2418e859de43f23b0d9c7b34aea83ba462e03c077c3842cc583419018154d4a2b3d63967d4dec9b6d70c189cf03a757a91e977392a4b049fab292a78318138d88c704f6d533d31a82b4f8e7cde8436db1a7c9d8999ce9dfcdeb3d3e93937a4fe478d4b5d86ca5b0881f6bd09b0df5013b0fd0e66eb8463b2d51543878797ef1839ef844665bb7164aa9f0e844a290f1f2365803dbfc4e44f7ed19260dc3c282eab19a382cf917dee1a564450afc00fa97305fdce3224130889848638bcdb2952833129568ae0d8404c2ccdb4df1394ae43f3fb637b255a4141c0412fc1ea4511ce8b843e1eea11cccabb5531ab10719c4fe46ca460485ca5dcdd879393f192e66f54ab5fcebf01ae40b6ee00700451fd96872110b7247569a278a850980b61b5d0d5a31c383316b3cad8d999398eb92d7ba9f9d99d92b2c7bc4ef231372d12206d4d593911507d363df14d2cecefd97c017237de799e9f71f03c1eda7975f49cdf67d772a8ba18cdcbc5afbbbe57b7f9b3bf0ac6c9511fbada5fe368cf75aa586cf0989602284b716f962651088835b7011118056eca5b326aa8f90e3724963c83cd2f995685990b5530684ab645361c9c163093c0d0239a0a9c7676790a9e9d2d4b94bb51643d2348eef255d6451fcf3010908b857f6b8a4031c70545fcec31ea6604fece13fad6ca8e262e794c16b3dc1181496e959eff1fadbc1f5b31aa12a1def3f725a7219ae64698b92316ba5ea8ca3b119f2abcb911178712eceed9b7408b001fae8919455c5236461ca7d59829751c35ea78a36e3ceaaef2be8611c963c8d2a2696abfaf02786bd5f7e1edc9b61089df1be0a677f9c71b88f7a8419dc767a3d904411b97f9854901627ca75379e8d1e2c16149a140ab76bf718ff7e87ad63f9652a47b45e67d0903445b393bc007e548c7478065359bf8d342deb6c4c7d4682b126585a51bef14474f1520731a064bce9ca87e10b103dc39a7bd62aafa7abe53aeedbe0b36cf7003aae99b7c0a7b24f30d42ee3b0d981ebe36ef3ace63102122c05338c6b66df9ba9d15465bdf50583fbcfc8ec0387c8189aab47a03952e025d4d01c48fa3c8e6224b2b8eb257f53a77477a6137b04447ccbe98682e99d1748fd5c7af7fc8e06d2417a901f8f926509b35a9610cda2f77344b2df0399d42b8fb7ad1b2b7f18814cdb0eedefa42538c70b521fd7c3941a41bd8f5cee4e0cdb14706afd03358bcdbe93517350c1a33ea10e80662596d27c5d1483b39633f8bf41404704dead99ed0592ded5b685de16c634ebbfac6a153357117cecf517b83a9c107aeb08e8ba61a74969da9ea6e5d3306afd18d763ac5279b9d657d788dd52fcacf76a6bfb82bbe3192fa460f693fd44e7545f5376853654ebe9df7d3736bad1ca9da5ad7b735ea8be4edbf85fe85c0af720321b344b01daa21f3c056fd5efa7b3efd158c0e7f93f8f3d9f912e6a3559c29e91df7995eba5934cb4380d379940c04b011c48a52a11cdceea10040494418bead2982a8db39672c362a486b8ddd7e56adc002633d9a304218fd4da10a5540d6e6000da35b277e6b3b7c1934e469942110ea55a2870db902a96c3872f6a39b5eee33f4ecad974da84a58aad5efc6a5a4d331a9c3db5ab002a4076ffccdf6def114e64158d29f99fd20067ee184950629a568af2ce18d160a66545bfb295a4bdf5cbe1b7359b0abea3f47868ac6ec89dd00e68a45b9544d245005b80e0e789cbc75c52351b4220d77d2e76da2a298e6a1e27e07e97b83a00feac8efd7dc486ae900c57eab8afa0c44553ed87917ba9e847d11fa4cc5027368ae22e139e3ef33377b3a01aa97e4514405c012efc4c5fea9b3747bceb2ecbb52e7faf150edca74e1604a15458bf41736d514883d45d4041d069a7b5781a852e9733acc5e281037a86edafdc15557f0bf90968c60854156a4df833716dfa345451f045e8399f305efe486f9c94c69544886d567f927ef5208bfa2af0c0178380d6060e376380f6ba01489a40eddfa08ea1be471f3e47ab2a14204ad2044ef4e380c304e75fe992379ca20a6b7c2d0cba0b26eaecce8103dd1ae2fbd3db313b10b2b9c65aeea125f99325df7ee7028066415c569e55bd20ea72ff79abc2e1465fd939d9be6f997a23909a85c11e29a35e723e796b5b60f7f4005814cd37a1314f5d77a93463e2f31945e8794f99e1c9c08161226240dd5d16b3026089dc89336ab3dfcc072f3e0ea0cd0221883dd27cbd3209b167b0633b1b7a85506f0d2796bec61c95bd1060dc17a94e72f2a4cdb6be96066b1e420d238d28bb5f8f7de2a8ffcb7d7a456a1ddcdf8e0028f54a29febd91be3c2377fabb674e347e7ef74b4876f4c4eab83ca8f328741d8a579e312fbef47166abf128c4ee1f664728dc769e715ccf12404efb2b220976897150aa6e59c53db96117b1eefd8a898b1ff03a045c20a326c3302dc4729a96e6d5408b6ae06845c06a28528d050f360e72ec1730433246a4c4a967052a9de5266d144c7158daa1795a5e703649b8b7fea96ac0d146715a248727aa956d841876b196ba91b70f34fa35ab230bd2fb441f93d87afc60835f8ee924988bdf5be74153a08f1152ee061fc20b70caa4ce9978014db908c3e619d1fafcd06f44d1444b3458f14f1d71627dee669d4268c8b9fefe5622d6f21fd7a924221ef6cc9bcc4a7b8ffb311a9be11a1963218d12a9b9de2d926c92535d63d91e9774fa124eff3c8fe2265b00fcfbeb410560690b13914198ab29b8ae4be12d60d98960623476139b3665b915d3ee345ff8bb7f6fe6ee9e89d4a2b8118d9a6ede164776551ee89a998b540bdca479817b7c7615b265f8fec17028ac3029575b06ca9fa29f116d778d3822a08b91837bead99a62cb98ece13868bd39a5d85734d0539a4f536094317954840bc9fc0a45d0efe3bc0b8f4b2ade0ecc7eb5cabfd537a33c85508d868c96828c2c896fc3ff403653e91fe107e186ff2f345bd2327f6bd372208d408851b65a291c9c86c4ec21a32b4a224822bedf7ff7dda041daa734a52c9b6a41226f4b791c8b0bcd4588edc9b0685f92ded290a924a546bc27cde61422a0830e41d2405dbffa1525fdd60688645ad36bb56a69639292c8ad606080f4a91610f769f93b7811e70178ad9fc0ba9e644817d7b77ce4d65d5fa6e55953607e8024fce418e35bb68935dfb32725aefd59aa9caea6129eb8e1ae8bcd8722063c1fe6056581239520b6b626a07ba08e78a29146d3d1fbc6d149608d71ac0916a3fc17a381c13d0a1770a734e8883861c9abae70a9c83053b16e9fb81513cf6e903ce25645e2b6f423fca91c97f908a231fc21007fd9cebb6736d2519a1831330144c78ac71c6739554b95c3429ae8258775ecd12b1ac5e895fafe5abd21e6e0059bfe7108cf5a149cbbad118e59f04571ee7031c429affad4ef411ae6015203394f8aebaaae2997a36d67edc1326a8a3353b659a4af27d4d24b0733149719d3b16cd1229cdc917dc87a8dbbb721d9d1c101ba534725cc5ebacfd6bcbdd25333cb63cc69f39c7989649c00220627478d436640955e6b792fbd96aab321088c829cf405793ce49f830275ac91c52f8dd993495f74752f9936508b2101705d49e246de57e406808f191cce9ac0b63a3482c4e0c25653658cd248ac8a85c1c4562e3162aeceaad169d583045734d598e46c04957c79b02cc8d0e633ee6b37ac28d1493ca01b1aa3d5c1145869322c7862fcfb8123e180b2d44712ed1c4cca1d78140003334c4cddee398c59b712b768eba17968989d84ab227ddc7c086aa7bdf6e450fb7ae2a597aa817682f7a91818630f6628f4a816a5beb38787051807a66a6b35664d2c3ee0e58025dffe9e29135516336ecb32c82f43420d4ed0c72243a9f6724623cdfc90b15194cbcf7fc59034fcc05708ed761503b9a822e0ef8f1825f893ee8114ff6b9f3c62b57ecbe5066b3bf5c2a4cd6e8f763d877f97c3ae8b633595f52acd1a8508e3d40f32e0100005110b0f854e07c5aa91fc789848f834f62dd981e1253e4b1abed2d36dd3cb5e6fc3a989aa343630326fb59454c6ab0cfc1c8edc76cf57fc84b695899a9fe6562b3ede2f913d8da35908209452a1fa3027c01e362e6dc5351d973ad465b59520c03d73398e6460703fa4290dff6dd9fa85326feb946d432fa4a4b6058b8c65ad8b641f3f244e76b393bfe585400f1a11eab9489363c371e9c61edd46bf5b2169bf5dd5141345631aaabceccd4a5264915bd2737a239a5c8439617ac64ba93c75f4f6252751e2435c8895cc2c5afe0cbea561d2d19bef9a3cb4b2d1efd01c122715793b7f98007bddd11a7c8a31d5887852ea60c009ea81136e058c7cd89880c0ea9604a3cbdfe44036f079eb4eb15ada8a5d11ca34b4a3f397ce043ef0ac3c18bbc70fb2d9e008a2f1465ed0f97e446325425cc16842f94d38d3d2d8c09e84ba8e24501ff29a22996a3f020a5b6023ce42e3f5a2d8c98036170ebc22516e6fc691364436613165e8209208f2cb0c9b1706a8078c187ce2dd0ade59a346244f89eb162e937d31cc5607cc4a7ac9f087ad90003d83e7c5c243b35d46524a111f5c08b4396ec344dee60cb5d10e139f634cc6f85122cd8b2275319a678b0337a6c8e373c750e70b21b6c10ccf437805e145e0db2e032607e4aafc61393433c3cc4af77a0523cddc847e379f52d2b49a2ee7da4c39105be552ad9b08b267e241426dcf677391ece65e5d44009ba704a600b34dec7d03f7ee851e70c1def90247724e1440c089fb49b906aceaa477f5f28f8c0c7fe7aa42c933020be0e01f420faf4e6f54600ce297860755d62844983087feb6f013fff6a0d67baf87b9b881fa5294873f3074c836bcaa7533fba2ad40d5c743107147fce83bdd679fbfc9279247774b4b784017d23d51143629667549451d1c3686f735f2a5174ce9b3759603add45bd033fb17112b978fb7d616c8411f05d0783caa26d71f48225ee7951d360e75837c525ccc3b17a65d8c0853edd36450c0afb00a5a745b40a0405ca4896eb8f9af68417208eba12c8f944459badf62583c56885772cbb474d896ecbada319498b082d7eca422ac9d4291138cef114087c0643ca8c9b8687fcb9f86f208190be8a44c8f362cfaa9bd692f300758493d09db79fd42f3653f0a0055616509fb0169dfab3bf9f696fc08764fe188c1c40c8d8340c43f0a28230f22f88de14de3c5f4754983713545cf24b4799b359dc9607066633032c7352f9ee221a662f6b0e006e6dacd78df49944cc3586afa6b1921a35a8930f407c548b65593ed1681991400171d2cbd72e9080c3f15d702a2afe1ea984d2479bf1cff1e041dcac36127d0eb8ec137f004511ae9c5eeb13a0a2a03186588cb7a5afde05fc8b3a33d2186e492f26b4a0eb060a3fd8127457375bcb74f94029dae8d0ecb004dd930b6ced8dbc8022e289fe6e3df2b8d1d360185045c5fda9f8f468c0c8f33a5cdeaf06f2ea9856481f42a34cef555bc380a70dabb20d9a977fdfd5e921794eae973eff84d22557496a561801c2a1d1d0d7a19c509941055572f1de724be8848b59ddfc72a382c5f998b35a3863d415f83ea2bcaeb1f59892b2b1111bc451a1a8808127639ab1dec57e941f3a6fb16572970187cde6860b70cffeb19b33f22faba862bd23f13d9a459e005927aac5a95280c5edfa556056d3845792f8e6959fbe99aa21700d99d487b579c8d6bb6de3329fa8287887660d6f55f95c413d8d46165fcc45f402aca9852bd26284a247234fb4e3119f37169b58d6d31e8794cfa495d17980543abb593184a047c1e023ddf5b8186c2b50e0dee5f9b1036e9360edbcd34a3bf8e94267ad570ee707694d380cff8545537f1a5ab2304c57fab01970933003a40ec999fc622162f66a1852338c59d6c1626e3ca4b0863c41743c6e473599de17e831210d20e0a5498155a27f24a1cbe93c5da6ca2f15610fb06673c5a05b132474514a55317b827c60137d2133d6c5ed1be0a94a0145d60ba81a415b1f38001fe6fa34188d89cb144ca64a3efd11be95957592b46037d37c79ec95caa0a4f1f29e91e768bc7f1736524c4f89a10b3bd998b682ec9f2cb54038b3f1d7d953ad72eec0d5bf95956df53ea8b37055ff650602d4191ae3da88807261403c2bea571c9ecdfb372f30f0418fa4dc6ca5b652f550ff1e08b29bdb9c6bd8c9f29faeb18e347e0bb998db9a908b1f9145d4a470eef540470279f554888c1df9d8ebeb45a4377cd2b78059073d6b3cd092ab907b057e0f537c65fbfd541d23f0fc3a1c16ec482223c3c2d5b5319566c223d13b3cf5c00a4fffbda5e4ce9cdc4990f177e550910097659f56285bd0e54de077b1b134885a672c27c30fe5c66fec7f76a59596be1a482b4dfd7ef7570321e5d1406a947a65e226b5616cc1d0587f09857efce0bb4009b153fc0fa1dbf69dbba51df5d885fff8ae306734a0c3521152586a44afe5be1200160adb0d644ca66a98d1299778b42f832237c52b2a8ab809c233d51b344963e96d80fea6584e683be862f4d66a252e42b9103e569f381eee766f23de8aff3458e7146306d72232ec00088d77a35868bf8f1b9e264a7969af73a802f297412a990c8ad5ef0f5b17d86701c773732adc8ea0202abfe4f9e4f3757fe36dbd9c06f9d09195153414d35a2acb6ced98b4cb161d6e5e08b3d4afc1e3511f0f39d019c53858163daadeee46ac19a97bbe69f3bb87f1352d6bfca9104f3a409cf7df94d68e018b7df786ef9681a32b77d69e3b7269d8bcfd014bd95f8784013cd5360c1088e01c616ec7fd62bb02799a72ac74a9fbf6cf93af54340d3588ac083ec050eefc72078a50ef76a14812c7cbb282cc8a5cc12a382fb1e6e23962f514405535200fe3de3f323f7b8721918be098c58bb776a7ff0e3b4022f6fcab2be2fb08c159b4f0e2c24f1527ea8246405bc1f6e6285dd23a5ec01ccbf9478d959b2881761208f2bcb84cfdea82c9bb499ce551317d3d704b3f75f74b695fa5124d88940d6beb569c54d315fc0a6f07a9fd1114e0dab4600b09e195ad949d04049238f9e437c4d6a33fb7fcda7387f948f149c5579cce47ee6770bde492aaa8276cdb688c2602f9b3e552d9888ad08f300c02b909f04480d9c8191a3e4d3132c4c699d815d655718d6959aa702b0440cb1909b7e92095c3b92a7c16da84382e691cb5023340e2089e2bececf24843f75eaac6d1ddf3e90e4fe4210724d0ffa67551d45cbea2ae82171b41e33b5d433f733d8708b809216de3de15f4529cb29545aa6dec5768722a22c1613efc4256263bbbb748a39869061ac2a203c14b1d2fc31de818998b4a5c0a40cb445f96d0cc3d410f25456a696799d7f7159d235b1d55b1b5e56938e1a4f42a7058b5473d0abc47c17490ec764f92a2c8f3044891a3316a532b42d28ff7e39b9a146802b24dd0d1f16f14f34b970b971d21750733583af9df02d31a599aab30780b13622f92006e03eb6720f6307158b1a7d3c9ca5bdbf21d9fd71f3ef69d9dd61e3408b0bf918e662d7291b79b8b3ab828310b8409f546dc96cba0af55e1bb7ec398e9e40054b5db1591e0c8443c4fa03eb49e73fa6f80872fc43e4e45ec0ccc9337ab04ded428e773b5eef17e11f362391fa8515ddc50c434af3c386ae2cad5b7252c492c032c4f5ed1505e8735cb090382bb3313308d5140198eaadc9a201206d3618a4d3abb0aa91304cad38526a8140cf84036ad5237b43033583547375e81e9210ae360f11e620ad03fffc68296d2b798e548fc65b43361b9655208c8306baae0c1f037c4c032c27ac6fec2438322cd91fb45d0b13023a24ab8b5918dcd73e8053417010c81a4bc19a46c7ae747f18a842d8e1421e41a9988b8f5aebee2742d736471462a8285e9090e33736f07798f94d1ffd92e228586c1eff2186c50c8f97b854e628a6d617401ff33fac1404f2003e4fbdf76714ef7e761e49b8feb2c8c827c6ef7faad19ca04d98470f8ad8dae372288e55580cfd2e50c09ddb78d28115818f60c50a1ebf2cb840fa16d075ef1ec8a1d54ad8c6b27caa2ef73da83186730416d6460bfc2ae2c71d6cb6fd709057982775961c787e1a21550415bb1f2397801fc45011edca693c0340d3b51de76dc11dcf8055a9ad21a9b2301b2c81c567080cbd332667bdeaca9fa189a1a446d676ce82c4867d24ed4314a2e387c97f231629044343fb94a118bdccb05097ba4ed6c60a8a2fd5f5c169877224b59fad41f711cd8d3cd16c3f85dbbbf253a60010b93d90509f6343edaade417fd876fe578ef9f0ab3c90681978f4e393a4c48025f56d3738bc4e122dea3b2ec94922ea0d2da980e4961360cffaf9b8a0d18b02be4ad282183b0b21b1cbd6b6ed23c5acacb9a2e122a9fbce30fdce4ed793f3ea9e35bc13ed39edb6243c4aff8d1b705755f42437acbc2aa80c4cb29ee8d54f4f86780550f28d323c750045335fc06ab2e96350fcba4b0e7c35874d276e40f4c9d974ccfe2c9177a07aea5a1198808ae83f7ffa7c2988ecb9b9d5c1a640eccae0965ddd4c80dca1b99bae3f336ed5805b83d74b71f425e020882d563d22e9263929bb3a3282cd62b80d6298c07a76665a6b328d5d91caf4e45b6e33f199cbb406d38c9be4616ed6bcf63b907c416fa5d80c83df9f31669c116ea46fd8c8c9ac4823165dd2189abe3f17d4d5c29cd2039458f73091bfbdba209b6b57619493346ab02a91bd9c6b6d219fefccf291f965a70843e58bee5dfdbaf670ce10b66d1ff4db8ae45ec698da85ffcca25eb20d403ee4b16e6a67e487c6ee834b56a7d560ae57c7b1a674efc9db4813e8c2130466444d290b2670135b318b24b436fa5069b83f4b1524d432a956a2eb2892adf8a675b525911229f0b616011783ade0a7e0cba664564b9a55b3ce3110f2d7e18d440946a7f43840d4c524e9c3f49cce0722ebb39f756c89e6039b6c1e5681c76b5937013919b67122cdcf0e83e8c158df5e6ae7417bfbbc08cec36d968a8eeaf2f912c4e151338c557b7a40ef6cf5a4f18022280d5621b3353543c893cf9a77c4fa4dc37dcd20963ebbec62f39562d901894035b2cb9aea5e4d46b28a7c5ae8b34fb94a0dbdb2349caad46aaff4bc9ed4d2d1950583c56f300619b18145d94e27c145a9f1b1e15fd151c242922bbba2d70e41cd4c47b207c6fc46d7695734d73474bcb201f5670488c180dfa57b02471af0eb45266a858488a4671c672c94350084c1b4d54c46624b22943a509643463d6ce31b9c43866d659d1cf046e942458815cc43d5063b9218346cf680cba086633c076fa00aef7531e8599c9ab44de90071cd852f2075fc3bc06503bc5db2949303096e998eb20a3983c059ec69f7a27d47ce8ee18401552d3b68e462c34f8bbed513c5af046a0668db14aabe85dac7dc86203eaddc46eb202c1d6fbce44ff49bcf696ef3a420038184986ed1f66b42eeb3bd4c0609eb61ccdc20436b901fe6c6f58e62b0d40f73ab3764f0c9b511b332b9d8c662f1865c92100308f899da659284c63173a99c21c992a1983b89696f1c33bcfe503533ec30737b3414d8b82fa3f95c1a156943b8c33ee60edccd1074d16562517ca67ca17c4ad4ad82ce23d7b35064b6eb37ee9bae6e5caa983ad18c7806a4d4da38dd9606355174db9d420e4f7d57e15896b5bd5b652eeb01b913f03921f428490ea3581fea8c65dc711618b7625c6770111229296f99e3eff098eb68cd36f748e0fbfe732d87f596ad06963e3aa766615d55d28b665d780f644692a08d2f25ed455ea61443d7462e6ef85a45800d03a5c8c8b8f6cb5e355380c3ec53ee8220b7c400ab2ccb311bef6b2e73826f376fdc89e39bf3f9919c6441599ed6e5c89f661ff62f1a57554cca3197c6e6b226f56458d096570af35410e314d55197bef7daae7ee1725175a6c5e53681b5cc1c05b8a2dfa404a5f50586942b37c4b46574b712bf8b95cdd6165a78f1bd210303f53c315da7574740f064d819243a1b61858dfc3f07b4793ed0a3692c32758224614f0a10f8c42c055f1d2380e9b83decd4d446837862be7e47036acca002ab5e5c8960f412bfc9259f2c657ed06901d9525ef7d0f77500cca53b241d203fdddd36c8a819bac872f44d8b89bbb498d76365e42ead113e3892b3c85fc63c081a397950fdb5a3c63f7d64d70f031fc4db642cb836ab7a5d76538ad5c3531df9101e9683406b2629891095c77ce307f76985edaa2dd01078ab70b57cef0435a5ce65b6e050afd3b1ba547a2f70fe4031e91c433ba3f8d6da801aeab8c34e76abe5d866696b9c486fe5342037e37c8ce21452d3c0bbd5491c2ce84e76ffd8bb7c1c333c3236ec1eb5c6302bcded2e63f68969588279b57a97b98ce3f8b481abda7e30d1e75e557375f6c688f2277c14128a07ed5253425c29bccfa18234ca2dd69791a94d0b10a5282c095ec6f289629eacc0f04b73840677a52bda14ad9c5430a62e4ca5e3667bd56694730e3e13f26cd875deccaa46dc4262b591d8afe4807ab201b54ca6e05e4c25e88714ae795020d2e0991e8daa17455cc759edcde901ed09ec9f2dafc8c90f6fb310c1b8231dea0d7baff95eedb03744ce8b51bd9bb37947793fc93ac5323397572df2a7b51d506ac121ae4f53d99f78ed226a9dc7df070ffd988e0d679309e7718e292981369b6dfdb464e9e9da866b6f55f43f6a29f9e1afe62591d9bd238690178f7cd2bba51efedcb5910d98058617ff3059364418ad3cabcd8afb1c40c1cc0b16eadc16f2c0cb10c44d74e1cb8806725a60ac492673db345b849c11a37f11c627732312dec92501643c15522208e9d73195a33ca625637c966786cc1634c9b924f05096aaf5dcc4a51113ffbc1a6fc5b03234784689fdc0dfa562c4bdb6976429d6b6d07e0b6a04688b85bb16fb81ce958c7752c500a80992072830495b947c5dd20f258a8eb8ab9d1f3d7a22d2864898b95e6b4076f07095d3950ea101d9b8f1558ed4b7d04f888b7d871c8ed13b1317c09c3bd0ba2a7cb3acec440121fee87fa80c67ccdfeb01b1bbca754d7e5fb5f1a85d53645579a961bed3d5f7f589cf809a1cfe1f6e0f43a095d22e684aa54cac400c6188141036c97dd8b730533b254983a0360d91c8485088e646251e7b011c6fc0296f68cddb137a93049638764edd123725b91f9c038eb96e9a88c8252377f8eff6b3650ef96c1283b6bc4b54fe8e40a34ecc6ccd9053a4dbd1d6650468b314418bc73a9c6bcf19949876936f31ed4bc945224a8cccb25e34d16e813321a13005d1ef2fcd919cfe4b13653c7b0fc9bbe4fecda89db713bcfd8add43792c34a9ee4ed73c42851668f8d868fdcd563848e1d63f003bb9bed97b162caf22d92c39f25564ab11062958d5f10882d2947e19ee2ac08bf4ba5f4d56dd4a858f90d7a068e85876ca0659c0285a4dfd4ac6fc86cae998c96881108c15da2d117dbb2c4dafab970f54d23d831ba64427366edcf6c8c448fcfbfc582daeaf393c4b2fbad86055b69d81e1c8cd9dbabec74566459113e62d78af2075e2ac3894684c5a8abcbcc074ebe410a3a390ed8c6315cc22ea0ee4bbc886e48ad3ad73da7da60726341d52234bb25e7915bcdc067afe0228cbd08a9ad5802dbcbfb91c28cf3cecfe0533023a971306bc148c8ec7ba05d08a993adec13b49f9e07aa42a0d27ba2e5b7eddbbf4fc1f80e568fbe8da5ff6ee39440b396bb948afd072c2612ba5e31f67062cbcc35dd216a1c070d50cd8aa002acdf41441b7525d025f20c06b802e451f6066dad5d2ca4f6ce59e9d5802bd5ff92a33370139b7e252018621abeb73bccf63002bb468bab922f22ebca6890155ddbabb2f18184d415c1ff42f6ed8bd5518b80d99a95473ba36842494936c7c333eb708bb5f46b12a936e34d0f3a3020b47a897e128fc7c069cece6b0dda58cc056c8f1885804d9422edb765beca251560a58810de6a68881388054d0445dfb14fe9de593916e66522c8787e2403b1850e433f1a925a69df5aac4d1b38b20d4aa0b6f98f4597572ebd39fe3dce6b288b7302c6c5eff96f0f52e6987a861e5dee7ddb4835960840ec0f193fa2ed09d780ee47af96a490f28724f57dc289ecb4869ab1add410157360b8f0e97d2e6ed6b164c9a5ccc1ea5c223e67e0863f51e96dcf41d6fef8c2c608960d34e507cabc4992402a2ca1c24b03096966db914fbf682da42111529f40a0901082029c65ff102beae2b082e6bbb9c03ef1c2a3e451f835b3a749811939f59e5f852fcebe516a6bc2133061e34ce24385bd71de6101024532de26300e8769e0116e53ce12652d65a442685c4efd1ba2c2702b155ab7f22f412a41db77e001fc01d6a33b8778c9b8048db5bec3f1d4be087f73e9bd1908ce58c98bd7fccab7512db3a75d8be389e936d4ccd1178ad15f1ec05b9bf9461472a057fa6672a60bdd4603cf82d168d60a41b93eeef88900818cc5f0793c113f9161d10eebad5e6c3d5f0d8593f913e10548305ee373c0ce2e81fff96c0a5641ee85d375357759192b6f2c4b7f9711668f4d5f436763e89e878dc130683f60390b5ba042f4a4d6d6e20d5b2bda4100442ba02ae8a905020e74a724f521d707e6a09d443cb4611a292f3366687a2c6691bfbd1a7aa15d9343ef3c06568493b7fc6881623ec1cf3d346f88ec8b6c7f6b1e0ee443309668c0bda21bac8984aa978e2b6af57c2fe9850c14179795ba0060365422a14f35b7ae4f833bce9d80aedae0e1656958536f9da212821711ec672eeb8b44cb9a5bfd1c5729ad193f4f7e137d885a4d9a46020444ec81544126b71d1f291ede296d979314a330ec79e3a626442a14c1ae477677aff364344c537014b4930353350d628553a9b2c4694e6f1e2e6e6b8ca5ad936a1fe864e5d9ba34796e50eb30b20a6f031979c898c608fa98274e865fad24aa2d7c3a42bb64e3c9d2447c35be5a746392b1d396b82eef90612726dcb3adba7011393741dbca499155bec6784c63b4749ae67223f16e14cdce3858e50f0d449169cc07a93976a28a2996ba8c4b188b6fbe43a8aaa40cb54e724fc0454c367d955bf75622d16459c9af6c718d7cd04faa8dc408a91834443e395d31b3aea04ea0d324802b91c46c28bb2ce1f27e90c3c9d5848d2864ecb4780db75ea0fadddf4ac30ccb98c84e0430fcd3c8347b95ac571d3dc96c270d0060698ccf07c13180c225cd1029bd168ecac9564e017881d46ae0e10228299ff43e0aed83e677bd673a0b1e97f2903a7b6d59b20d5b916c067aac8dc4af3287b5f7212ca6a6bc3511266ae3be89b14d21839411b1537b7549c8cb2f3491b46354e6d2b5f358ef91001664ab4936af8c13338ab4e830d3d559090a6fcd20470ab7a8061b3da188edf5662a65004cbc6f5384054ba3a3f6913fd6299027a4a0119b1818273ee237fad1b33e8dbc252fb3823389ff0d99db64ac45e07bbea76a20dad4718ebaad85d550ba1d8a28d76ec68ed99e7f2df393596392e835856579aa5207bc8828d11144a08099e3773ebfa7575a0c239697cd3cf08b64222c8a93c51904245a17296510918f694096f83f19d88af479c1142afdcb93862824454fe33f64df1100b5af1232bdea59416339fd45c779ee3667c0bad83504e8d128188f288ce4c8abb1b49f8db652e97511e191a1aeac868e1a4a48df26538d2d36ef9106ac54eee5da3d9724c793d81dd2e616ee66c3b8d0832140c960f13af1fedc199e1d278667ec2ed2370aeefecca7adb206301850ed90422a68529908e7ebff9ff6b0c2739818c7bace2972f1a37d1bab29d673ef240f55554d5def6597583a43a46e329deac53a4d8d76d9ba9aae4874c95df18f343d903f0bbb8ecbd9bbf5a049c46f351f8c66490478b21ba625eb19807c3d8b72d9a944eed8e4336f5403ef2100b9f15cf3b11c797414bca717e551f171efd4999b68dc8b3942bdbe74041b20ba013ebff632829359c6a1cb4a0c4a07540203e576c0bdc613a9f5d16364548b3b8c8dcc7074ce740da110a06c78a55a4ea2a84968b1bf30b358d95cdd6844d9b4ad827d5fdf5dd6a674485ab05e5c2dc0403e0c493275996c153b331e19e8d9e5883b24d4d33be686f959228051e4c5af83925ac668596fa269b1ad92bb51c05abac2bf35a3f56166322aa2471894a9fa3ae04db6a669aca5418c490769165427012bb43cc7e31d34b02ce48903edaa4e1e6873d0ac931dba0bfccdc5913ab28dc339ad53d1d4efd1491b279db814ba4a153a9d3a2e3f3c854198dcf5ead06cb79ab175560c56c47b8b8e65b356f1ad318c9f2166923f42ac6d29e5207048ebf5b239153b6537debcbfb81fbeb6a8c9fa1711b7a0e147e900df9c3a97d64b3f53d9bd7567a6017257ae336da108b7ff867db7b0ea86cc221419c2de3db26f59863145147cb8a10781fa8343444ad804f4e2dc7ed739b84047b435076518343bdb18170b4a9badd024f038cfe06eba44f33cb021722657ef84dec87d4801cae607616e293da4ab971f72faeba20d9724bf227340c8f4ec48412e6bb8ef1a68bb2e48fdf5b2fa7d8a6c591598b151bfa5fef249eaf6560de5657a7e975365b0425d1255c5d4786a5262a1d39607f73d249f5bb8f1725de8261f045b0adf654ab186ec941889f0cdbbd2a6aa66012b0f8ffef9e3c38768f85b8306a77ea072f08190ba16b00c9b12b55a7ac320718b30d5422a8ab54f60bc22da028a268acaa5920282e9837bb0371981a9170ef298c3dca2f0529e2e67367dd8fc2c4ddb2b8ebe2dd6b8b0e811f4407fd033cf6fd019ecb80a0a1e45a08389b750834ed6c38202c28059afc890ff186c25852800b3e54d306514b18abce840d329912420626fd6ac3cd27d3af1249558e3221cdce83375c16b78408ad2fd80772a97d521ae42feb9bd538d9a402e75b03a83f2cf9817233728dd110a8ded735c820861ba2382088abeaa3b1901e1372072bcfe3283fb7fe57a828729d4c8e34e3741fb7aecbb08a36cea27cfe68e585d277533df7925c541431288cf101f24ec5922738806f1fe22374a592120c5a52311fc2688f8c8786c9ed1287a4417b82130f2dc69e69b96f2d2f85f3e5203655a2e85b8143623bb4c05e1572bd278e0c8a3a783ed989309bfb9a63e696dc5371de8988a45a38f6c2b4267d8e353dcd35105f578a42186c5e77feb49f54ca2dac3e6a088882f6ba6e7d3278da10e464f153212bd8a3af95fa38d8f091af606afecc43cf98b6fb082ae0862bfc691b758dcd473772b9e74806e4c9706e95e0a2fae95175c2da96a6f6ef8a624f7be59bda42c05ec80b9abfaf41538ffd602e4c0d52f3f52a09c88a026d2e290257bf3deeac872f89702e25e8c32b21235b9377422665ee414154c366ec1f72b3263d19c41274feda4944efbc8af0b2b00f23e8aae80013546e33b2226c2a039890b3e91c26240cdfe6514cf941a53b551ad90c5cb76c165cccf7f5b65b67a5c49222abdddc2407b6ac7800977c0e715c6596b195e70a2941bfa71795af7a50b265be62d9eb513a099c29ea2ebca00b48684f2d211263f655179ae4d2d431a910610959197236feb14f1165f9fd34a2bc64a4a55870243ed9316d3454e0aa4869c815d6b2142e32146d2f9fcaf4e348a26c456d1c78178f7caf022e986bd6aa6332e77eee0080ec531a6e053ea52da9d5529d25b4a3f2ca52ce83b59283bd4925f16d5cb9033a8cae8658204cd2d21cd591465c6b22119dbbe32cc6b94323bdb8917b310900fe95b96aa9b3a0c04e9db4f571d037ed9ee6c4b9708feb747be667795900a087abd95fa448921e1fb8428c90c9255a39143c2ebf979696369152a69402bc07ad086d081f63247fa5973faca520790d15ace8497cb118bb116bd0ba5f5404de5a27e5c0af433d54cdb9a2aa56a5faaf2258ad15013ed82febbf5ed38850a758fda65a2d0013d517621c75234b26aa5f14c7d6ff2037eaee474150f3da3ca9d6da6ed7afdc77cfc47d57b927a2b19932852a68b922ac39ab60eccfe694324d22ded3777a6f047f8e3def2377fbcaa88fb5f2b755ba317d0f3281df43365d57f57adcaed36f7d482a4da1cdd668d356bc9163f4bb8f7915136df4e7834049574f727b103ad2d5db6f9bddb6faee5ead4849b920d5c4d4ddbe8d529140eb6f5ff9680316da7edb36ee653f1d558f7c8128718ea1bbfd12d38f79d4bd9c3b08e8c1ca984a69691e4d90fc9ae84fd2ea672b31d1f645605819ec6522d0d111e7f0bb44432527b62f8336a4accf2581decda19868db810413ef2602597911aa18e58aaa6c3f088c46c9cbed975898dac0c0bad40614eeed99b8faaefe8f74cdefde7b1ff53fb269fbfadef69554aadf9132a7fbc34ea12b2b5aa55dc544f499a051349931b4b1daa70fdf4645202afa1461e2f6416ed4f43704f86065a2b8791e483651da34df23e9f8225fd1c5c4d465984868b33fe01c5ddce8e24817f74cf4bd67f2b84adf7b10e87ba48b7b8e8130c99f421b13cbd797d419e4dc6ddb9a6ede315794651b6bfb2d4bd65450d15654dbfdc1d6b701c5fadc2f4c048689b6ee2cb2b1389f79b6ba6db46edcc817c85680bb6d5fd44ff3ce94337d6e5f8d1ead5b32d1f64571ac0ce8b7ff205efa1ec9b7e76d05ab7d5fee9de3babb3d6edc9d610fa7dbfda4611012ebdc23b9df1eb7fae0ffa034ecd1973e4886a081b3e7b160e703791985971c698d5c0e41003f6c7d53f84df45bdbfdbae741a8df43b6c810a610377a46ee2773ba237c5063e514dafeaa460bd63fdcac3ee0d84742d5a75630d1f6f77b102a08f47b0a67a4d93011b759cecbad688c9501dd8d7a67c4c7411dfb1a1caac1365161aaefdfa4fdfca6fa0540639ba8f437cdd7bec9bf6acf345f9baf7d11ffbad5a9ab4da127a7e1e320592f71b93ef8be7ba6ef3bd2d54cdebb9a0c7f7e934cfedd772411f0fd9d623d5f3bc6f51b102675df336a31adebaacd6f00c75a5bacc6384ceae9215ddaf7b83419df649b7a5ec6d7e3f3242471bfe4f3ae256bdfe563f3199fe30deae765b8344d93f1e313a3c76afcad47f25a7a56ff5033c64cfeae4a7237c2d817eccb2dc66112059daa7352f8a3dad0043520f348a97c710ebfdac3d80a0dd209d6b5ab75ff711fe78dd48d5cbfddb85d0f9392e8fcf0919cbbdfa3852fb08405019540577bba8dd6c8fd3690ba916724aaa36ec419b9fc1bd7da2e5292d65c2bf2b1bf8feefd7bffbec9bf7bfe260886cf914df3c3f921e9d29a9cd229ce91fb6ff47a8604657b3285a4ab9295c91fac3ec0a69e07df47d8d4faf0057bb55aadad6774e3a69e9f5f291526ffefb5075ddd8dae26bfef274904fcef89cc9e4d859cc30ba9ace8b7d43c7269dc33b59e7bed399208158d64e2de238970a44b039f48ab45d51ab1c0b1a7b47ff8fed5906cfadec91262332bf45b0bfd9ed1e7f0abdfe8d2de237b4ad733927e4b2da133ea3d553088fad88ea8576cbe4c469780f9b2f0b214ffc4fec063feff2d9192c2bd3686307623144fa1282ec6914b0d88023202e79847dc739694d875e44f21fab059224d21ea05a00456c6591788e5c47934a77b53e722412321a9fe12b70501d968578346582adf671174bae6f63ebedfbc6fda7869dbdee543e3a06fb7b7437d1af412f7dd50f3b96d74cdf7b17df73eb4e7c826eeb5efb46fea7eab96721cd3a808d40a964389688d6a639197dbd36f82dc3ca2bd641eb9b49f2fe54db289fef720fd8f7469316ddc90b657dafeb53d6c7b3ac25e2f2fb7d77c4fa3a34ba3cfe475ddfb00bfeb3cd2a5bd8bfbf0fb2697e67deb7d741f924de177df229ba83085df7d53ebbd079f639c13d80776dec873e358f79a42db6ba695a17d9d52303c22e177a48b7bd00b9f43fadd6f2493f72149646edee8e2344e7b4dd3de7cdd3d83b52f7da89b846482f5ed76cf44bf235d1ad37c97c6bdf73e3c6e74096900c738ad56cfb5bd9d4275236b0daa753e0e9adbc631f8f37d84936ca2c2e41f7adf6ddf914b3f8536d1cb8d6ca252bf693ef84e36f9871f922e2d247d74691fbe46ba3e007f3e53f8fee0cfb16f92eb83f9e033851b525473256cef8de214dabe2b890cf172db9e8336f7a966ce097633833c567b4a567242851ec9043e11fb604fc8a107be4732856f43afa715825e37bba8db66b471b5bab6ef36d27f7eef7dcfa560672dc2fdfc22ddfbd2245d94745192d26ddba891cbef61926b693e5f26ff49643275ef2411ff8e7eb73da7553b2e71b5b29c29da03b9d5b5815ffa42f835a0e4067ee70be93c97fe24818938e86bef36e7bbfab9db2006ae08405ab0f6006d6c73939b424e74c58a80018ef37d235ffb71d77e95b9eb19e499f3d340a413ac166e75cc008c96112413ac66e4320df13916924c339ec8043f83747dfff31ce3d0b544832442257c22f5677c4832d1f8094822f4693c92873f760a754b9c18ce4a5b8767e4d2d6b1b93ea8fff320d097517fc633d59fe1fa5ec6cfd76792f194a4fff3959cf1f599683cfd195f5ddf8c51fc1933c807c004dfe4e2def591ae0f687c8df731e30130e36bccf8a61a4fe339c631f139f60160b453a8fb1ae304dd8c91c6c81ceb7a5ae0f77d4ff8debb84f87c8cf063901a78df7ba3ecfb9efffc430a4f4dece8f0c48b07761832fbc59f47149072478a0d5c9ab040a5cb192a78c42ca1ca8245d50e3bf6d79420892c35587cf1c50ead2c5492f8f0c4841729317f2bfe8f38010f073883440c54a88a18c2ca046638a4a9e2898a144bb238c17295a44e93246d98cc6ce922cc08b078e12a26b2d17c6868e876919743238883950dddee7f55ca9143fc3aa980294fb0aa9a2cf14591189e2c31459c2b80c0e14bacf14085e1660d9d344a7401c68e952c29c8004395113c717e24f7b1f4727a4972564ca18aa9157098a289162a624d040e5e6210a208122cf49a7eb19f45187a2375c2c8caf366aa8539b166a24e94a821dc5ca19386033f88e9a207189240d1c4180eac18b343160f47aea809e2c995254aaca498c022c40622c898a952024587993d30664e921d5290810623bcb8a2c6ccec8a304f74ecf08bdd5c501015a8b30516477cd1448e101d7071a4cc14292d607142ac9ffbb986c25f7ea003669228628919138a9889759c2f44c8c0c2123b272861335992584541b3450a7130a006071a961002ce1739ac10c41552d490c5072c8a48c9627c030b761aa28d0f6fe24425a1429b18a70902cf124754e0328be2a598622a073b4dc08921c679a0a8d0408392333330f9007fc90c821b4dfa4510be39fbbf9c42cd59f1ff8694fdebc4450a2e4e302147ce162e311276b8a2031a1e92b0c148ccc6183150c000a686199ab09c19dc305901c91369c274f17190d3130a50c0305bc34211a920255eb0410c961aa63089f55b31c8c741ae7779df08f32f272579de44f1e2421d293dc4fabf5cf2b97a24da52c1152d5362ee203103556c088c2d4aa45a3803c417b105547dd1c31b2d50ecc4899d50a5c59a24508a781af271100e280cf0e104294eccd0b193c4112aa20083021e375fcac422d018d8c0444e0c8422c6ff1f2b4961f93f1eb5c6315bb85c468a933baf66cbe0f0c5752bac681d4cca9ab60e2675b060fdc6987ff9c3fcdfbf0cf26943b791a149e406e91fe29f83fd496ca5cf5e76b7bdab9797e57860042654a16526460b1129e4b0c5104b44a9c18b0f02b88282840f26b4b12185983fec09edca2ca4ef645abfaf568fc0605d04100addea7cec81a5e0f6fd7aacb50dc439a61115d968fba6c076b17e6556898737bea6907bebf028cb5150cecb06bbfa4252823975247f25ff176c921d30917f912fadbfe8c523a1699af6fdf6dd7bc041f8b9ff78946dda77a48cbd3ed7d736185b97a361861124a8e2c487216470c2664d163765bab431410918b621f5d607fbf3405236a4cefade587fcafe6edbecac2328a0277f7f201362f67b0b3c64ae9c4042852b40d029b26d1fd00bd687d43ba4ce305239602be653929b60173587ef0bbfdf4aa6e0c8d0d0839ca3d5fd1cbbaf630bfcf0c39f74ce6f8e32114472edb7ae73fef7db1804fcb981dbf63d7abe8784401aebdae0c3f7be45b2972148cae67fe0ab32f0ce1781f3b247d7bd0184bf92ff0b8cd9e4effd1c3d929bcf532804ce51ef04e291ae256edb9ebded03d6344df336e76600f0581907c5bdf650dd6ff44708538866bd9774fad48acc09a6d8bffe42cf3926a0d70017dce66f19d20d327f88762bf773b457f33009026938f2ce211a90fdb9e18501ee685165061db258998af59a254d906c61c78aca8958ff977336cff0e00f03a2071816ab39a186866afd1d2cc75951b4b6ab185e73a71365e1afe4fff28701f179d0af601f8e4ba13f8f28e9201b0b5e19c8395a93e45eb0f2bbcb9f2c3bdfffce9feeafe9af98c77ce248629d5c78c28a1916b600238c1992a474592305a7cd953b31ff178c091f7a15fde01c9ee51fa0e62db670c36a26043cae1b4518818c18f0b2c27eaa0c267b39e1c0890787ef25e555fde7e7e7473b82dd61194c09375eeacb2e90fd0019808f20c04295fcc14461ac0cdce14215e6657d28e0d35472c3f8a4ab0266c430fe17456b8f82bcff08f15d04f22902cd496522b8f4db5d14c9fa9bd6a1141695e65150510ddfcbf1c9fa776da76a6c78303c298238e646abc178ea052b5f5f2e4da1faf60a19e1d2a5796459a83eacd6b06734c1f6f49209a686cb6d341f8873ccfe306c6b6d28194ab555cd995651d4e9948a1ad9aaac5c65ac8c9999d9060a962915330529d87e9f4e2251a7f459c9a92b79e9ce4389f2642425de51411796ddbdddbdfd57f0c6c3d475865362d2c8a5e7e7e1461aa969da8f716964d2b8f2d20feec04b8ac732b5fa7eab6f92d21b7e309112188c07abd7ebb3aad2da604d9f3c6153e8c693ed9faf1d3024d81012c759cb7148b01d30d80e241852911df7e94b34b99394591816dd024a898d1428951615d4d9aa94d830d255e13df832f5e1bc94a2bd94faafcec18829c696937cc1ea3cadb556af934e6ff7c2b6fb3bfb7cc5a9f4b74ddbe8f695be921b6d24dde8a6342251ca836e55ab9456308732ad94a7b0a817456c447555701779d9f35fb0201853ea45b0176ca8823b67a078bdea689ef6de5f8386491ce713811ca03a188f8d44e246a5d7aa2595906ae5a1549194ea0e2febe7b175caf2d4993757ab5851847030ebc8c19cf3e92449a83f84bb17841ab45667a5b3bfb4332c73aa8451a40b2bf2c4ae701f3bd07703faf401270147ff10f1ea60a29e5f5c2749a04fd45ec90bb86ccdbd524ac298a87dfad7ebddb0de71fbfbcb7edb2ff67350bff074db35ff3ac692a8eb72f80e85b9d10a3bbcdb4b96d95b02bddc885d1bd8a04aba6a2535e8cbf96f4f57eb7c2290037d19070133d63edda78be47364610353dccc19020918234fdce83266872d3a78c104074e7b9eddd3d17bed59e64ff4092b4b0e9a3b565453535456530acd5c32a3e6d36c8a15345aaca8a6faa9a37a894bb594476165c94173c78a6a8aa7a43a8abe64b0cb31731cc7b92624833c79eedc8ef3f74621dbed4821362837929044c9212ff993daf96f7861f945e6d7e71c1904f860d9df49d707f5b5f74129e9f26fab29d49574b91226eaef6e8f812cc2b24cd2ff49fe142227e03245b125e0470de7a7390b21d064912505e69781340a7da77e7ea6679208954932f15392085792dfa9298359ea1fdc64533ffd4a9be833e99a01653fb595d64267a0b7dc7cec79468270cfe3f65f90217eb9e7aeebcba38c1a71b14d72dd3692d34696c3a489294768e1e48a33599c9254451d9162872c5d149956e018a1031760f2d860811ca214a1c2b24267c9d4d7455e368b65ecdf28462821042043f3c8e3e1475c5b17e2ef466f98971cd7ede414ac114a08014815cd354dfb5cd3348dfde946376d1b800e5616e49b085c756990fad4b7adc76be357a3eaca6422385de9edbb47d77dc7ddd8832365dafbd79092431c444467860d48a4c0822a88294ac4fac9cc123162a6f082c4484ca3d374d65ae7a4dd93e3dae96ff53957b5b456a1945964a379a43da5149473847959f4f2f25fb02fd98adc826cbe3f7d668ae4eb114a9847f45dfcf5394647ede9fbe0be924d75f2f3457262882fb7e50c4d6d69e2ca6077cc95294cd5d38d784c1053b77f0837d5e79e8e4ddd6f1fd0d71e84fadc5361aacfcd26fa1ae9e21815d59a1bd02c1104121bc41798b89282eacad40eb1fe2f2b9d4eb598b2e2d45527b283ba2858a4cb473ca7122c2efd40522221908694cd7eeee6c944632c2bd1e4e50f739f5e50a7378a9dcfaf438975d5e7cb7959bf6fbdd185485f5e66b73e433163ad7640f2f0b295a4d80e782855f1d6524ad77595fca68fecfefb8f6cf2c88ee4624cca4460800862d94c7252d5c4d7652ace96cc4288cc2b13c1e5641d70ba22882e58eeb5ef20dad70fa2695f491eae0dbc87cbef3d5ceee19ab1b0d965d8ec72c8c34b218e188195277ac0c2872f4bc4bacc183658d854a13ae225d6ffe5c894cb231503d94e7ea0d87eeaa8114ae81867ad283ec75489d0af24c7f8edf5ffd8dddd6137aab07fbd099624aaa83063e64acc5b68420d132d54d0e2853b317fe626b5439d7b325d77f71e9d2e1dbfebd3a74f9f3e7df2dc424a141723d2796254e857fb2ec42f8ad6725c59be5e53843a9f5677f7cd4b9db47bd39afe18e4e5d7b1759f8928585f1c5792378dab314c70db285801086c1d406d81988eadfb9a47dd3391972ee43f328e003091bf7765af912c6a3892581898e7738702fa7a041e73654edddd56b76ddb2e82090b58aa08218495392f10408b0c3554e184942a26318f9ac2440b175ea02ad325e67388c0c24489246fc03ce1944d7d246a7bf905c1c0cea773beacba4fe766abe90ca4ea68c11a978519ace370c2f60d291335d9fd0c9384741e6f9f2d99d3d5805e219de70612beaf0ee0c1c108aa21a8b8c98ab96f20f3d1596011f3143ef8322921f90492228889c0638c80f174b98d923df836e93da5dd7f9d12dbd7f30ef271c03d7f0f7e8efbee9daef7dce8bdf5f299bf7e03893f51fc61ee7e230b77124830c505cc9d386c6a88f99d27353c11c2c99729a862fe5f524e888f338062b5be9c0ad6df6a7e83b08c7ac0cf4f67a860fb4e0ec2affdc75b0fff5ac739e9288523e7e5ec5cf38122cc28c103174e5c49f3556040a1872252272089f57fe9f48a8f3e05462c5025937eb0b27f6bcb2538ca1cf84f265bb46a2c0328bb36a0181853a589138c80ea220f1563b6c83913c50b2194c41e7065030a61ac90c4912ab12b664c18220c385d6879220317ac8f16bc4cacec79e478c8bcfcb221d3e918c4bfdd9ff2e8eac1b2973c67b8c1f62570577b9edb36645e7fea0169b5215d49f0e7a7e27842e384a91fe64c7167052cd298e982850f79a6081345acff4b4ab52e957bac2a0192c9cbfee1657f0643580930fd70a3f1bb30d8ab2cbb9b4919ff6c61797bee32c9bd1ac6714c75f94390e7ca883c7d97e71113cbb88dc9cb8efad28a5a19910e992b7b7e4e083655d77dfa07861b4cdb420ffae90fd16eff5c62fbd2ff0ec291ae1e7c351202699a56291ff9e3424d7f5efe30fff72fbdef9436828f83ea1bb151e5eabf605ff2df88c1fe95fd3805d142141ca0c043840c6e62ad15f27cc123058b306e88f17ff9e69b4f01d40c52f9e3b82dc8907aabf70db23ddfcd4159dfad7f1b8368df97f392b2f75b71ce33333f07f1053ef6b1bd02554ddbb620aef3a837dd6baed192395dcd9fb6dfb81e6e7f92c40d44706521d8401f3dee031b0441ef033530629d948960f8411f1454a98f8f8f8fcfe7813e8254a08f61ab5bad16d716370e99f531ecc15d211db67a2c6c47a5d1928dd02302c9a0d37ffa87b7964c488fb53e61d22702f9843d7aac4f8c182c234c9201faf8e3eeeeee6ec59fb0875f2e4a9a11f6987706e8a34da211faf893344118c347b4a2d8d3124311143f5114454f143b4e14374dac229da28b628b7c8096ac0397bd5ca1eba4ec0365d9348eb0b2a2db93c99e5197bfceac8b9d6c1e2ee8be6e911b5110d65e24db71db49e6c260a1654d9e362470812887302740b903c50b3ab17ef6e2c5ffb7ffd9f291f6f4f9f905070b1fce0c21439d16e224cdae2041d3444909c088dcee65aaf473fec307fa0ff98bfeeccfb92b2143870bae1014ccaf301fcc18fdd6ed2e5bcc60820e2a7881831797053677aaa8a2c2093452f495e1c0c139c42ab4744142668e973a2a0cc0cacd9ba8aa2c1c8ad8c0e7ff2cdaa3d784ddbe1c562571029514a02c21930587165937e0a1426205c61b9f3e9d9178bc76dcb932e7d4c1a78cde210cb0e2421d2de08489424707a820b248020520e82011eb678f9a3e5f4dd8202f876e49ef0f9d2e2e2770644e16178eb48153e54a183c20c96ae189257066d49caf2b6c5019da575fd11d5117eaee1cbbebd3840a59a4d801ca08a07228819d2f5428f305cc149a46ca26b5fa2181314e49c8a04005082fe03ca921d65358614286239c949943c5ffb9257e340184541549cc04f124c917542eb081014f1348ca1f360a02f9489cfc6549a6d63b675041051628b3365151208ca9528526ca113048f052b84faa892e4404ee9c8b8a7ed186b1ef0400007cdae7385e104465d982ca1460686105a60a2b2b30c07042c30a2a689ac6815a7d24ff6677bfe6e6a6ad4ab2c59a3e1d8c7e71040abeb462065c24602468989af2226689355f1e70040c01a58cc95cb0c444fc3f208700a323d805396aad46ec46cc0cbb20878e1d18d45ae7053974803f3b400cc604d45a71e8a006781ba18bc9258e5caab55658adf53564c18e221b15200083a30a28802520070540b5561d19500c805cb5d60a72b5d60c9098f932738cd271c6baed3b1e3c6a6566d86b0af177adb5d65a7980f307ac9526f97863a3020a26033db3ab86264ed0d1f02c682335e3fb0199889fa332c21873ce3981986bb7408d6cce392768e7ecf169c50043f09bc1561e8d6e024edc5e5a8deaa240d30235d482366de3454403ffb7644ef69b985dcdae66575750cc44f3ca096b36bb9acdae665758b32b193de387db1123867d1f192433518c183ea4cce9daef9ff133f214c29acd66b32b0feaf340f0039dbcababab89e4eaeaaacc6c36bb9a5dcdae665758b3d915d6ec0a6b768535bbc29a5dd5ad6a1db76d75764565761595451c386fb0e8ee2b37596dae60d3dd575674f7d59a2ad474f755775f6151318514514091a6bbafbafbaabbafbafbea0acdcfa939f1362ab09382d9290071d3a652030041b6e48a767cf1a1c98338c1c651ad863d7c03ebd7d3d1b03effd3b37e72673b97df03aca3a54a20328473f4bc873085fc0b228dc3ff07d312e7f0a290c00e9fff7c7c7c7c62c4b0ef33fafdacb5d6c7c7bef5796b7dec8f8cbe61ecd9534b7d4f2b0c8108f86179b5a7b40cdef50d332fa7b40cada5adf40c3b3a868ec1c73d2bbe39eb8ff7f5775dd7b147769fd7b97727e11c836adb5052e9a5a7b135e8c75a4f33b5da559fa397bf7028350e7ffb3334c4a161391d74c0b4f443a97578f07a3180aa832a262f7f0cb50e0fb22c9665c05007552087c5863f20088220650bd2d82d3db5dad56fc95ff565387610b18e1f8d63e376540de9c777405ca8754c8071f86b6425652ca7024ce43f25509f3c2e3a2eb83a58db731dcc320fa00cb0366dc27ed3601c8f6d44aa55d3941cd63a30601cfe5e66c044ee7787ff3cc3cdce947adf96ebcaeec6a29797b0b2751091387a688e5389d53563fb6f19db7fc950f03e61fbaf139aab03a53be65ad9fe4b02db7f9bf8c0cb04388307d2ad6ac9d801bb4b5c3157899ea2d74b466ba8bc5437cc4de282b95f6c5f24ec3dc2a505fd03552051a480fe58ce91c60678bdd8fe3b654770fcb7d2ce7cf34b0ac2f6653250585df6d20067ac4c4433490b8e58ab0ea9b0fcda65325c88b94870d472d65ace8a334aced3d393112d8e582dd0dc1d72bcc8d862ca9c1768dce931e2632caebbbbbb1d8b0b23b7e75b61520fd7fa304c6a8573acdcf0c13029e4ac7765e0fdcadcefb9394beef7bc0517db3d93b95dcccac1a28515d626408b17383bef7c9b051171b2c42d2beaf674d8a48d366f8b5c1e29bca32ee238e1041ea8286ca008c3041131a718b290810e9d2c4cc0a14a4cf69a22891d2894d8191346ccad84c943c4122f4b74a813dbe1d36189269dd7be27cc1c57063a71e97c0e4e1277be8df3f446ce1481ac0871c1f56f581022993735d437dbb66ddbd35a2b27132beda931939af69ccfde58e3346d5362a24dab9556d752f85c1bcccb3fa78eafbb187957dc886a2182737cdff57cf7ecc91038cee29058c65422ccbe4affc8bbc56ee92eb722716763d912e6f60f5c562c4bdcd9916d8589ea0f24f0197bc653ac58b5a4665877f6939ca727a4d798e8a7164ca82da0509d8b93162f947c3933664b1830540022ca0d557401e2082eda3c418200df940e4cc14203104bd274a9d3e34d0c39ccae48b2c20fda133a9f94381bed2758752e7c87ad388be5707123e6fa87d04f6011547c424255889b47de0785cf5f0a718e9ecd44ddb31bb51b85a4e842ce8105b73af8165cd9518cd79308070cb1431b26cc90897a2a43a7091330593e44916707cdcaf7e5c0a63ba20476be89f5840b379f24095df8b61b362d8b0a2436284e2cfec268ac90b860892f8297c9b80142fcf182a77b7202124f8e38175a15f48a70f220861a88824486333a4c3163c50988999a19c2387103250497961b1cc417dd48796eb82d6e94706456182b7067b2b8b832ebe6889a52fcb1a4ac446345db73994c96125756be9161e587cd8a112d6deba71d532d59f9dafa298bcbcf653259b3cb5d269325a5d581c2c51826b3bb30913f4fa1eea6f2d2bbaabf547db11241b501c57e1b888027ac4369afb1b755961bc1e93b1ed5565ced353a5f5ced899bb7c3aef2b9967378af91d0b7ad984853c244da94f2529b314c275e6ab2e9e46aef79cf7136a058eff26f70805bb7aeceee9994d450134d7c36a058eef2db80623598a6b5aec669da0779a93d47027d676085f6ef475d444c1bed28a2a16c7aca3c92e2b695152d1d0544899cb5542fe9a73b1da3b1fabada43afa231565666e19eefa573920d7632bdfc9242691b37e23577cdfd1c9cae39fd8899e021012c3856b4152657067a6a62b832a65203759ddbeffc1e7ee708770825b907afb9fddc64c84465921c84bf92ffcb1f9684b746e7618a893bb1d0c1daf3fddd14840064e9c7b746cf5a72e629168eaf2bb117d19610dc7fe90791dba76f85dffa2408a4097ddec1f7de87ba530a4ed1a7ec75656c258019ac8cad469842fea1931e69255e01d060656ce54173cf91b28d243130f68c617feea9a9fd1c349d8797fc7f95bce47f5d61fbfd88a73ef0587d59035591480b3f8cd90a8e8f26f6d1c4969b9ac73ecfdab8f7c8267f6efef64ba4d87b1753d7e1071edb3a20239490259595f58229fdf0be39d681f29efb6fe4983672ecf3c611b238c6e6630facf77d41ea799ed669da73ef799ee7799ee6cfddceeba78672236f86499ae79ee64da73bbb7b6e7f57f91192b70e7c14f5c3922db75bcacb6daf6960a17e1d6e776fe9ffbe9f238184d0c562f1e81a9afdcee08eed79fba40f6fe48d75cfdc6978b6c49085141ab4af6192365a6e9e778a0d3f46cb7ab08e62901f87e40dd537f4142d1ed9b31b6eac467654177db17573ba728368dffd367263f7dac8b3d9cfb33d998350a5ac67dee8df51501ea1d1a864ae564435ca10dd08032000b3140020180c0a060482d1603820689a247e14800d80903a74541b0b855192a328ca2063082104106208218608cc8cd1c601485244e28b35ac1a40710843106203bdd8fdc8ccc04f0a9e3caf6e3ef05d32f64f27afe5b1122667bd452a94746e11160c66d5850c102f2d3616a817d6f1a998a948868ae5cb3a90eb0a884ac5471715a59598a723a6199e44805dcc997fd852744665209e36de8d939e09cca72a264e3b03fd627921d29c3eab2400e50ee4ed98089f4798280bbcbdab036e82596240bdfe76c61b6af9506f6f9c488b5a1ff4da8b13dac05a5d536f225a30a000398d229b363beab23368517b52c125b3bdeda2d860ca81adcfd29d1420f262131633a10988f9824f31cdadb0fe3903d09db37be63b03580a858d94c13bceaeca743b561cdc080b5bd1025e40577b560a954f3dd18e49568afb0ce5508f584939e6466b03da18cc5ca6713e12602d2190e07c3707ea02a94726130a2ca2b69ae1200410d2674291ae86d70d46579d86a212d1ea9808148bba821a14e364237e7cd23c002d234cee844b7fbb5f818e41d94bcbf3a80b138c9bd60e6e5daa0b5c64c252ee00ba1d75d5a6b1a2c411168a780ec05d3cc92a4a0293e79f5233407a439ce3cd36084c7b060250f818dd7cc605a26d253688601dde693398875807a1c77949b3049e934b1004fe6478bd51d350b3a21f82fa1a3346c4264a4d35db0fdc7ff9f241f85aa5cd8384ba7f7852a72bd10e5498adb4d906d2785196523b1c3ff03dfe5b0f52435cd3f343b8375c2aca17d3315759b14764296d1c97590510ec3f428f32052dda600b43b0e50d223b2e16f6ba7923b57b8c5f586f240727c64d481dd26cc62007a73fb3310673db0fb945f3aefada0421eee7072459fd1fd7360563696c715a2307a081ae0ad0773699480431758016348c4318c0b1d853268d960891518a77b04d1fc096f498346eed3fee94362c51b879f2624e6b551163778a091451f11a2b7b701c3c0e8e83a71d8c1d672c859db4988d170e4f323c345779270997dd07eed01e8043e340c661ea0aea247963fb78cda1559a6c906b505ee1c4d1b07e25a68111b6aed9b2837fe16de6e3e9ba3e48c7e5eb1a1f0bec96c93f0439233b42e74ef2b4754c87a5455da79e0767142f2b24e26bd46523a9a24f447bb622d0e3759b6ef09a8d1bf0b51755ac94a9e4c4aaf4ad6e028814a359e79d1a6f1e9a4381499c07adc1098b8dd954525bb65ed24af1cab05e516faa9b69f87043ae6db9c971330d924c5c4efad515167a5f3d85e67ea467bdafd3da2b9cb93f8b31697b7cb8ca11ba2a53bc66988cc1d142ce705b73e372ebe246fd5094cc648d5b4bb1bc3839d46bb9266195166f0613fc9120df148c3a88ca325ae60da3b2d6b863d953948f4c2287fb77d2821ef06bbf351023a6fbb6ede603ae4a45247c322d7c68dacbe066e426ac3ec5ee351b3772fd861bb91e8f1ed24a919565112696b3523484bbd1e9268dc2dc88b8018d6137bbdc40936d04d26289e903ad2e0e8a9ac432b622fca58e5d82395e6350bd8dca37a359b64638c425136c7de1053a42dc8e58f5251ae18eda27931ea99b6a6cc7090d0e77c70093950ac45a992289b045a11a8d51380411b622e640323242ff00525ba361fa5e59c5a7933f9930bf005355a3235949981f80a9ea29413d95e95359acd58093b0a36719993e82c98da7bbf88a5d985e4e84acbab2f9f312f061d1d25dd9cc4dc6269b616afab15ebbef7f747126514e56912a79ac5057314ae8ae899f3f91d4821f913370b5caae70f7550cb50d12bda09f181c5a86103b46bb81817a6ebf40b8f328c35e8d19c341dc2f2a64b2e262046cfb865c0bc1a0b96da6930895221a55b5851ecf9f520b0550c074105a24ee958c01d9561a5d4389413ba21ad3cb8ba507554c0c5bd04d16d507ad5000de701e05dcacb7cd27a1815b171dac5113f2da235a18edf5aaa612235c4cb5d66c1840115cbc329e4806bc8afa0631d850893bacc499ed4e3f20bf9fbe002a2a18bc42ea1b8ac188a1aba428e23f506f94c95957699bfab72e47ab9a5e46fa451c0f1358233df327c6d2c62f01e683a3ed54ff637f138b432952f2d999889af870a7b67469247315b8f1b80b1243e546ba793aac6da275aa7730f1d91fd382e44eed7db8da0d48dd39f2a96abb21b92a15f3177610d1b90895ccb617ae6d204ccdd98bd7d077cb150ed808d2a00a60d7960f11a367fb04a87a5494d82fa6c02f5451ff2dc45f0c24f8fb36b94744450684439109ee664e898c34fc3337e5647b79def320e6c26f1223abf08b0c64ebb80a92ed9e585c68d005f710bb597c1efc7da604b7e53e7e2bc0e0ef8af680131b440818d34b01413012160ac880b7a61c2834f81b3df9b3a275b4d519138db07fd6cc01ba981df4b5e84844ac6c276a03d74a90f701af4eaf9dbe9e29df111185e16650191c35a63c9b671ec9ac932a0f59cc8d8cb2a305f92ead9195dc9ccfb8fde428c945483d8a9283ecbd1efaa4af2b2f5b593a1b9244e1734857fe969310693bfdb5ed4cb13410cf630383ec8e7dbe4a87a91d5ea78bd76253e00b3c07ebac68182753b8dceb5b16c0eab2ed2869a03e4de001222bc3cb11389edb3f4a7bf66601270b97ebd9beca42de060eb8e66222420825a28a7a262d67d6049b1aad1ca50906ef881187e7d150be37e5b5674240f788c846d1e961020d8f0fb6294db254a4a82b933a2bcbf69c85ca45e108042d5a0ccb1ba4ef477683e112e15c02b49cc40fccd6e0a373f325b567e07b902695c0e40dd25f7c19bbdb1b671fb850a4dafe4da2c336bcea52f4db65254f8c0bef9387d7efea94d99f622f00e40833c4aa580cda8fa01d604688e04d2cc4ae9b2e2f0ed07639543921e51cc0b8f5f71abd4b7dcab18804049191fcc94dbf52c9a44deb9df94a102e24f9dff6374ace789ea6fe1a6304a9906ef65d583f9f8c868b0e7805ef30275aab876819b3f77b730f55306498ca2e054f0a82dc81aed069aed06352a953dd14e2becd286fdcede72287383c1106550c15cf0dbb0464315478dd60970216f3dcbb576934f532bc73a5b835eaec973303e3bb77acaf261684ea29c5ff132e6ccf53f0e06da905944f763ff706fb38dbe1001e2edb45a1819ba06b684d5dfb3636cef50981ce322acb937b371571878e5abc2102cd705d09ee9211140c6a1e0050834c46bb376a30508f46d5f36d9fde6af8c2c8d989bb5e31bc7680ffe254739dc05dc7dda2dcdfdd137b5b1eac490d0ebc5fbb94480fbd3edff9be3a96524728627d67386624d89a11208e96618b8c110324c99dce3867304df18328b910f6e1a3e3c01ba37524433101b0f5f2b91a3a3d5a434062c79ca2fcbeeddbf2e0ef13d31d34c523d362895eb0e377e9c0d7f8d577fa61c1929aea196ecd60675f2e18ccf35b5d6063e10812101e162d0721202759de06daa65edf8298bfcbe19a2b79204b421e4c63c1a0bf1597536de94057f689d460af94225b8601bab25689ff5b447add86962a5b0f3cfaaa3c9ef6bb39371f21ef14b46776ff968496d30720d0b99f25a8fda1546e8c475e8016d96e3cb9ee01b9caa586fd3fe1405d1a6a7f1ff71c2108699d67051f2d6ad759b1d279871b0d33158e2a90ef970cb7cdec6286e298750a8f0cb3171d10eff373e4d3f5425c3db5872bc044d8a283f5f25b93eff4bdea1c1b5abd9ad11ab4cccf91cd5fc2943159313ee92bfaec8a094273ef5fbd570a3366ec1f2443a3f1bcf17b6b65c3b208a3bd9237002c332a148589c967542c4cc4490c6336a5c97a0252c7bb714276f1c6936be174ace4d80dc437bd76f1a6dac0723f7496400c8394010b7bb81a96468824354382cd9063c5ce22948f2c4ae87c243d7f90eb2842bafc2d55fc43520516caf4202a208b0c391a3e9b2011a8fa9a01bba10f03a0f10563c26329665fa5daae4bc31e968a4103506f6dfe6e1d4b3d46ad1db675933a3641bd778ea2249a46c50e263de53a96bef2ced11b86aca7468128e75b1d072ac74a05fcc914453af634cbc0a4b9d269c194f167a070cb5f266f8924a4bf51bd29391c09d476336cfc8d89286ef2d46825134a66510529ad1b3ae5746ac60447c020c4959e37a4c9bb386856cab01d1c4d5a3f1de0fd60a61b06ee129221537b7e041dd670e735b5599b0453b131b62efebd9290491c1e22b5b01c365a89ecd508dac118c379ce3af5f6661c4ca7f9865f8d82d7bd95fb0af06e94b3b3964d0b083381e18b1cbb16692dccd29e3e520f791f1dee7f35f177a65730e1d6bba7fef4ddcb0d2dc3dc27349d550e159ea01484af2a1862bf14dce299f12273a0ceca14f0dac4e0f1f993eaba5fd55adb8e051b0ccb4355588e1fe849ce602f5fa09f9864e10e41122f722875716c8bdf4e0df886707971f1a26a39c99f4db1909e5f98364b53d84379a11c51e60a3bf636b30657aa41eb8f0be9a594c26d5429554981f5479be68d185677d643d7d5c856b46889e54e20e4911676c3453c7c829d8559ba83aab301d1d9ab3616bb7744d9926921971375ae11268159c7fe916a5ba6788cfd12d73b7de199b7658cfb12a117a6519b5d04198693eca870168e07a2b25d885d462cd32bf99e09948cbfff3277930a79b3a0f0f15192840abb6a4b006f386c44332b2ba90b4c57e0f96a52d4513cd00da99055818253e1efc1e3564157197557945b455f6ab61e8613587d3e33318d6ade7472ddea3074e2a29c90e16808ffefafeb41868a05f5a1f2819a800f6b493e8d43528836112222b700db3e0d861a30d9efdfda27e8fb44637089c0933c8015b85b079906a1e0aae0a3eac0e02a7e8d089083ebeb5f8d9ce72139d36c8253bb634da21e65785d2a03f46a9ed96a313fa91a528f5fef7d690f508808ccd95875a3734fe8954b0b4af31b176d546414d93fa90c2be74ea235c4dd3f3be1ddedaabf750a1cb45d18b1f582dfac660a9f9e64c8cb18823b4342f665ea7c39749db42c915f1144753524788c4ba063e868f8010de2b193f4fc0fc035371370008f5b4352c72b717be16933684f7ffed89ca3dd0ac2a7f71c04bbb39231b7ef5abf56c54819069c929348f6323fd10fe6c3354223d2c45b19901a3f2073ccf7eb4e56efde7164e4722510853294539f6ce4391495b3979a489b6699768c071bb2d7090ca64fdb9a573809088d689b0064922d01e20b00abc886abbd6fef1ad3ebea920f7dc900283830517fba8ad2ad3e24ed2d205c96a4a58b6bc67b1e79f8605efe58bf981d2ff34ab3e50481c61dbbd1df428d66750938791a0128e66b8b641d9b561cbfcdaac5557c97c20b6b16e73d20912e7588c2e58821d9f6ecd16045cdb48a16931783674ba167f1130d1469dc8656290eae00048a8906c1249210840b2d013eebe4c849dae08985a53ed4e619d103c3c0dafe161d6bd32826e5edb8107b500a23fe93154eb554e14ce5b1ece7671f95e3f72d226bd52ad7fe9482907691b725b4b41bf5061fac27645cb899524ae2818b529370e5342d7fb6f0e72621aeb5ed44a5b08e35854dfc34f7c17df870621e61d0435c4b7f983d7974393bd260ea70a42aca0b5d269fb28d3344e9d253e2c3d4bfef3221fc90a20b6e5f90b39f3bcad744691ac2da5a822f31688ce1313462691e254b97efe90aa245b5470c8941c4fee0152cfcb87146ef9cc781688b8b801b2c9b4ede1e8e2113c5d0a0bebaa32d960d8336367bd91146932c4b121e84d523fb7c146b3b805e88baf4168045aebeee51b4943df32894dc821131fe4d00f4cff0a0a14165556ceee211eb51fa55d6e473f8c3af481338428211464a7668dfc7cfdfd6690e593b8f2057c9b791d0937a674cff53e842e01a778f29b3b17ef1c1b8f0aa5f7705e4f8f5881096f6c8dd3633a1778cb0c5da981e9981b10117448f845aa662af6e30fb7e1282adb987bab7f8d49bc03979f3f3808579871edc7baf35c7ff20ae23c4dd7916c3db33cff9a3ba44be4fd03dc2c9476e0256d6979ee04616c62ebd200df96a693056ce8ecc4bcf830f9c66c8d713e34aa5b69e4589475ae5c0914ead3dbd60e18f02366d097adce64421df3f77977753edab047f6f6fd1f7152b0cfd1f225927ee2006a024889f1565bd07a47017b36074d805be22f428c76a3067c53f75879e5f4d4d65cdfee0cbc6ba5220b86aa80898fdef77ed97d0a8c9b4f1695886a679f3a078de7a0d6b2091aa898d7ba108db296ab30b326c96b7931527ad0a25aa6fe4ca7ec106dfb21af027a9809f7922dc3878c55edbe9d0ec0591b60126b0ae8c013a20c8270f13fe9f44d87d93e4d4737d0299da0acb17459fc266da3c05bc04916160ca9ec597f2b30be587f85e3153b7c630a5e3c2a72b33da8db443fa52a68a827420ecfa25ad69df9d39570db0d33bbd93e97a835aabf4e50c1c945782de33050d80845c1083e5cfa49957eccd86542dc01bc6bc52ce235dd5e99bd4f218d16f0b081138c6a7a737eae626e0b3959e33d8dbae1727954c7616ab8178dd83f158b582ca38fc14a8cf9ecbc516c9284a2d211f3c1dfb88c8592fa10f9e23f30496b1e52631e55fc1de331305c013627b4f484c99fd2f9aae8f8be38f55b513782b5616dc94140bfdfc2a16b594d13350eb779a7140208b8e68be9e4b1cf0a06da3f21ad2108437a2bcd13f3d85438ab72d319edddf0ab1409468e40dc6c5786fda9fed56c19dc3399846214fd4a41a188eee4707844c4cccc1ab9498d7db1ffca7500a712306fe494d651c26ffcd198bdcef8701fd31075be710061f95490eb7c588e6bdc270446afd54dadd744b526f0f8b4ec3133c0f2b14d8d988b880b1020f54f2ff768a60c50bd25a1977311846c12898819ee9717a7a256b01df081b262718008fbb048ca1a648b348078315f078d5d8c08ea4ab013e62397c4edc00cc41a83743c52e477ddf84b59bc565a09fc925850ab111146df58f8302c973a296c64747b345242a3632370e9e88ef385923e8a60fff37b348511fd93228f76af7b2c20dce5c6139dfdaec3a4b492737d282237c111adb0b8604b9daf22f7bcda693df990116d7e303d8e32c9be8cb5f8babf9a6272c6ed01a3a082cc3cc0072a55d79da7d9627506842184a666a826fa1f8ebfe44579af3e5382030fa00eb8bdcb3852e8f0904f530de64ecc16d8bc9672437d26493c4670679bb2a712ffacbee1807a50ca2744640585e194893d4c4a6089082e5173ffff4be765179d051506ab68c6f09611601152342af063a07331b84ab90c19b4b828e09c1b8a9caf3741ac9a4527683881a43c98628b32350848252e49509cffbac7bc94b043a7e0c489fddb448fcf9a2a59487f98cc20e4dfbb69d11374529334bfa9a61418206b0aae7c0ed42692f1a3c0c390c307289a54184f70ab8817bec81d1ab1c910f1636a290a54b12a4f3138181d224c53a347a78dbf3f7ebd62051100160ec29a3b2b98b5bc781218d65b812f2dd26b55d8f4a1469af6cbbd7c21f07e0d8c201ad74897439c9fb669647d11f659deead678ffae12edf07a66792645d3749c81d37274b19579d6bfcd7ef447228213148c04ac1792bcb9cb02827825db8e9ca3abab681e83745e3ca292e87a6077a6fb79b96994d0037b11c5a6ef32375f19d748da8fffe82f355f1524b4030f1b9687c53828de4ad18ababcdbc7bcfccafb47e74125a0601980549bd0b1a3a2a0c585c7e73f9042c996d4cf4edb26781e8ed011428ef359d0c5804229a18c518ae37ee2a0bb50ccacf01c406b7ff6af8babf0e8a7913f228a1fe83fa8158318ebb32274839d85ee08ce7920acd84746aa7ac867855fc08a5a9974d376a7586bc019e42334d21c858bfa8d3a28fc990dc4bb48c5ad190b0b283ead788e3a1b3602c418179fbca5948facc16d6139602da2c1e052bd8bcd112836b2a2818132d43110756653f465ca21ccc2104b8232889fca97f1717f78fbd1f478c16942a4f5c11fe9c9fe8225cd67e0e13a28092e79183e5cf1904316cccb7af46c99600abf6d34cc3cbc47e26960158fffa91598f20c25a9819c2686a0eaf8a10dfd362e5010805950d479ef060d17920c029fd0259f865cb99e7c7cf040b2f07957095382702dbcaee94a8d3b849146b2aa7152df48ada73e545b1929db68df10ce27c4ad362ea2763da652881ab260a2b6aa4060ced006bf022b4880daca5f270df904922ea8defdc57f0f87b2cad42f640a546d4582ea0732b1cfb973e87200a39bfed500ca9fc1e3599fd852036ec240a255f0bbd6de66a9367bcc1216f34441ecad012d5efac5b4a49cc0820d0e70a1f5094dc2d17a729e6fc722c2c645937a4de337f7aa27e40ab3f90c2573da5a7453affe88602abc56abeec33c05f6bc1eeff233e52ba8e8d5ca1b5a8941ea4b087656ad9f8c7dd773fb07d3ca0b977f6d9add6492fe7b5411257ec7e6e7a3f20b61cf10ab88cc389bc6f3ca11b87ac197f9e1c4090f22c86ce0525b2ecf3754f99e29e4b407205beed200e6528fb6dd135da161a0b6588b46e8a7bff1070a90ce20313d89cb7934e35562a1fe39c384a5ca784220abbc3e47fff101536ab0534600663fa0b9eca1cabc554391194b148f4950bf7e2b171d5b049f6e6d31ca9c01bc2ebd366decdd21a5b99b1a25fced80b250a0bc90ff03a695ede0b536b389c6a6b4db5f9046f11e4ed178438556428c170d1ca14996a3063d10c9d9ed382a472dbd24193afe2d1a13a12452b50a6b3db01614949ff4a097ce44e4216c668427d72e46d03b30fc13b420cdc72e9839a361d25c066e3faee7a9365041c77dbade52124f0c010476e714091432871e05169e10ae5dea6490b70ec0d05e9dc0ca091bec74c1e4b955469cadabc262a4f3125ddfbddc45780de720c50fa870331958177fc86750ad8f579d3ff3ee143007382f92835a0313e067207c880fddd87cdd93096024427773a21d86a29881b9b0abf1915fbda498bddee0a6a623a0eeba3331fc9c2de703a66e2c7700b87e1f857b1cd5df0f5a37d4eb3d8250b05566cacec86d808312afb1d6d551f7d3e48b91b9f99831f1f60358ba3fc47bfccacb9d9e5fa5c1bcaa5beb9d034acaf1b67d01d30f741d74dd5ad1df9fe733f64845fc0914ad3875443ff55243970716dd6f28d614a08a1f76c2c0987eedae57d6a666cecedb5516ce827061d5d88d54405dbf6689a3ac45a7f382e5885b88e2cc4a831015a436a571ab0c1a243c56980388607689c095628b8d6b5af561175d9e7e59f7d7b5c8bd9d73934e890a131ca6ff6e95b47e8b2aa8419b8ab73b0d26c60ce9c472dce57063b0b3825c69bd5f7c2e919f55b3befe12ba35106d455400da7cde5ac8df1e39182dc509010b5cf7bcc013f4a524c7dd87da2ce8b87188eddae093166398bfd044421044a5a145175a97b61684b6090c93eaa946cc5771efa9c445ca7a58b2a48fc8c2075427d0129f95a1d1123388b7e3ae457057942d38be4315e89bb70b406f8c39771cf5911c2d04adc82880d0455e042b0680deeb57d5025220aee41cdbef49bdf6b51e8efc9cd69efa57f2f5c4e6112395c6d9c7b6117f07aebca097527fa80800501cd777d6386ece1646e946f6249f71bd6437e53043516b4dcb807ee7058c88b435bfa3010eb860e1afa555c26ab81f4e6a0e61584537fd76922c4e8c17309129939f55e840c562846ecfdf902d0c649984b8610cc4a7de671ebe75a2f678d565687513de83fb0df11b4a76837b3d7566ae18325d9ce084e0a52ede90c152032dd0bd480db24adc68bbba6816e9ced3947c701e7a8c3d45836b41b89b48ba92911878f7f7104e35fef82b892f1c0c77affcdeaeb7122c1e9c3e8ff914c224c2e5945d0b2c64e7a61dec2a8a7ebf64ebc1ca7acfcae30e6d10f4bb536f24dd14801afeceae611792762460f2f35ccc794f5340a85f88e3cd2a45f7823e8472e70e34c944ccb405a807b57dd2d56dc7d1fca2ce175f3ea282f46e9521b8d9a8758726b62a821a87a4c92e95bb968b2f5f698c011cb9cbfbafe864f91d2c99b107e184e53e8146ccd0cd99a029ac7946753ec0981454909cfc97f40328408fe2f52ca40f3133f126cec0090c6260746377095fa3f1809daba69f0837f2bfd0d5db4fef1c188a0ec83bf61935c430df2686036b0e01e56aa2e0f533121d0d5bfcb53d3acfacbc8caa5040a6186b7f748e1acd0d91b365a822e65279544dd653735ddc4064714b4ccd38724f6829f058083b2c86dce23422637622d1b7043d87511844851b5fcc62f23a4cccf119302d54548cb69bc3d264004cb4c530065b891f8ce25c73cb848768a16571986630ff38712f96bf4de4bc7dc3af21aa9dde7548ec73340a0e549a64f13933b5abb8c28e4af97631d11414e7b9be40c1eb77b9ecf4be0c206269b38cd422c78603fad76bbf7760e8cee8ab77b5a78ba96713ca0e9b3ae8190c4b78a65539cd1a4c73636819cd0bbc1f9391a9582ec4668888e4c2c6b424bc4fe6f013a3d17606ee58d7111be021acccb19a4d2e0047a647eca360ddee012e85a5a19658f86ea06f37fe1b560239e489bb74b76d97c66ad640c4d5809eb9a2581f42c1e0dcb00c9d0db840b04b140b8dc9525c3bb73ee1be5d9ea49cd7d577576cefd0a220338cd7da482b1e5ccd934a52defa8c04a03a2cf2c677439e2059bdf0c04ca9792561f7708be81105b2c6de8cc0e4c9e7e5a92f5aafc70b0b1095abd63de7a23d64697d25cd79f781bd58496689890518912b9fe4708286643c4357804ea66fd3143da2127581bf961d650547e6e24e487e8a859bed18187098efb62e3ab9306b12f3382424d3ed7018b48fa5eb2cb08e9505370baac810c8c385ae14ec5fabaee0088c0b7fe0a77d711ce17e5e77f2fcd1d82a4a3d3bb19af63b3b010e8b3322c861764e8480abb8901ab5ed82cbd35c78a3b13541d9872603d375d891e724686be08462466636ccb0a0f5ebf044ccd8193eb222a3f645795566cac58aa8871c94ed46a711449384dbd29ce6433da465af9d913d68ba9a88d488d498595110b0847c4d841c0982d85b74d852307d4bdb8d61148e40b5565ccb8657a395c36cc1bda682ab3b1876f067dad9c0e102a9d292ea6e774113633584593534716f7da0662d15b7a8fcca8af71fc7f2edf75847d83a09a9a5eadeb7e788ec594f89523592a6349b320550d6e556e91421acbacb6c622b0b98e55bab68a61a0c782c4ec3806022d4d532ba12656d511880755dba6a34cf93154da6b757e024576a434b78e0ca0e980430aa2ecef100a4b5b8c071e1830ea72c348c15b95dd7b53d0ff66e801f98834d756abaab4128581130aacf0f257f5eaee62a92d7bf8543cc8e721b1b0c678e08307336d04e18c0863365c624276ff930ac0aa3a689a9971847b0448368842c5a97a504240b43bc79320160194259543e91abe267b70bda8a6d1dd6881d5837c3b3f42f89b4b4860b314919a05bf12d070ec0042e5e2728f635c32ff031bace5aa0bab6920860a867cfd0a9c41b96960c3aafc70cb8692ee83ae5ce68bb405de4979240e3c5896f031ecd594d0c02b8b9b5529d7a214cf209690ed7e180dffd842ff237a8d8a7b47d03a9e8a5dd104027cfcc31648084a8225d4d9b0d5b81f4921fe1abdc3efbe4f7670f9b5c7b44a896327765c55bdda7c04c0c67c24f6b15830b480399908a9f339288b6f12b04e679522b762fd6ae2fc0128bfb36613baf6d082029418378b016bc11c30a03af9b5e347202cae7fb61507e3acdb97614e9e598c16f444625e036694069a533aeec4c31ee434f0952d803147c3b68bff504b0cfa5bcdf77b0b8b184e74eab949236c38f61e6d5798abaa6122ddc5e3b058f0126fd1ba723b2105fb74d994557aa6101b1cfff42f5b3cae99bb6631e9da877a79bfb57240fddb481ba29e750b244087feecf2727ed128723e771712c6615a7489420463574830114f61df7b3cf7b824dcf5dc604ab32dba66109b6037a1b91b8e4ee276607efb653dabf8a58e1f20e12bafa559701b5a10678ea1c2ea8d18b5cd544194092a541c43843b01ad80a34fb6b553a0c011d91b143a9f2024202c7cb9549c06891ea804a521ea57c3f45e1f80f144a3190fe329728460f86cabcd04b3c0a303fe924557a1b6ab33fb7ab1e15de5b374cd7859507ce516681d2a08408eb45d9a20292d883d4fa6cdaffd53f99d7a0b47c32d93bacf181a10ea8b5500ba37d9eed4a7d4a3a2a89087498536f79e1f0aec7cd4d13542cc8baaf5d19853e94ef0b973fbb60f9d5f94b8d4a22993ccea22fd4ac7a4256ca19f60ffd149a9cb96d24b3e8ff5183a2c6b40a7abc14b568fda34a04a68ad5e906c40597394a263129943211df877446d6276a99294d45aece254e2fe9c98aff3c38a42faf2654ea47e4ab2e56823e8a6653eaa3c9f07e7c8ac65e77e442ace5acecd335eb470ccc9163e62a35e1e7c9b630be7db240a13218edb4ca7560e6cc6a4156499182052db31f4e6168117389c4925fada91d1e9a87518a7a9f21e1e2d27c934187b53614e477eabb8e1ebaeb204d2330c44a2c5652f4238a91054e931641376739467a0a4697aeee44070564de48695e5ba63a6d7fc328b4a7f6bdaffe1a75451ddab72967b854619227e2b7318a7885184bbf18b0e8007440b1a5751ac352341c428a373ce1bc19f59e8692b4775ab1589153b33dcee3a9f72eb951d59d806a729cfafab2fa3092ef0f1afd803890c7b71173b9a5ae2aded56443f7af1c920bf0282cffb619313e7018482ac8cb5d041d396c8fc5e0972ec8f16cf824e575eba3913a043c368c3589bab336b66a879f3119450065c4c7bf14547bf710ff901e0732cfdc35aa8d3895ee5512b70a3e47d67f7f70482c7929178f7d28b26d9bd2b81b78edbc8c9aeab4535a9cb8d7d80036915eacc2c30658e17e977f9552d4776b29919f9dae8390296a1906999647aba8bd05f0d16222cc69f960cc3a842741e39be5bce17b580eaccb8b6d36df95ded223f0813e7a27a085268f43ba903f42b100d79e8187b5bfca3654294e0cae2739d6278460834b58a21c863b42f8606ba66e1bc88fa102e56cc872650d0ce35a28150cf911cda99b3315328581366d30f4bc5f41621bda2d2d96cc4f8fe888a3daa35dfb24acb168353245ccadd7c02e80618fe1b710d788de60eda2d25e4856ad1cf73c898516df05fe50be81563d06e4521f3cb4bfd3aeb62ade0539f62fcbea21e00107f2571b4dc206539da3d3f59c5bdac6ff84bd4f697cedac0296bc14d27b24d51b6d1ec3a20436cd0daad13915dd84a9033b17155d055e398c27e79c3f1227fe4f8ac07aec976b2a86e778557b8db579f05e6d17a4cd9d7f20e295630520f40a750c823a67714aebfe05445274173a83d053be484bee06a9a62778ba9e420d640a3751f18cc2ef2b8644380d834a21dd3a38a1653fae9953bca4ad99602ef0bdcac021cee334297abb42517e31938ffda68a7183f8d6d60b89c2205b1d1eeef8084e2ac292241726b3fa24b9dfc2e856fd4ebb43b6fc4f6c515a2ed6deba619d10f09bfe5c9ccc0fc284bdff20df1d6aa31fee2d36178f3850ea916968a8158721dd706b2d72f579bdb27111b6e7bbe9cab9a312fa1d8586c82e9d806230904b2225ad97e7ecf62cc7de056f0b24662b3170db766b2770d6437ea81efd7519432ec3947f6c3712f3f6468a01ed50b725f147b658cbc9638a9388ab71120d5384a1a198219803ee2259520696d38a73efd6deb990a3cd5d9a6c455c3510ac303e15ef1702ac70744bc7b658ba2bf7f01e28a3087b6800c7899905b8e50ef2f86fa8eb89d15e4a38ff5b3a21aa1264e8fcb731cdacf8304482fd50570774d7c9c9c678252733d78a3d680d26ca3d927ac91dd5ba3ec72e79f62aa21ab0081dcb853f29dbb184322c9d2a50eaca96535288f7eab014636eef30d498806d7845e7b775daa3b5b7c861e71f3818fcdd568cf20009ba78a9e5cbe856e876da9a18cc0b0fdec57e82cd8af990dd3c361227b71db436e1c1be5f23b212fda6cb324e2675c36ea039ecd3804f8a51c8005d99ff74d66ba36acf35a22de7bf1b9ebaf1ce88668a5e67f996bd26856d2f9be5e28c8dcba3440924f82828b515343bce60f889ae7ee25c57b7ec6f117fec203a0971c86e641006fac84b6482c2438fc046ab39510bea2cf480793cf55d0edf74cebccff3b5eaa11b7be1891cce11410197e74e50f4d8f89b0a30899ef9dea779e1a2b635d083db5778569d10ff10a263a5eaa6f386619185ebd7e05170606cf9649be75cd1af00cd3408ce87ccecc81c59600a5b83830fd5eed4d66387280ea07e591d3c5d4192bb58f439a490018dceb38a1dc0149272418a7f49761cbc8705e6357931c7a7cce66c5dc83714090c1d416056bbc690b4b488468f54d3fe0674ee6b7755ae6d07673a643cecce41f180deeed54e7162fb6611c204747735bb89dc25c92798c8c902fc5583726d2e700a68cbd1f1a3a2dbaee35985c79eb5c4e43ce7bb3296f6e23cc4c9da6365dace6278ee608293a80767c0cef9aaab826b5cb06eaafdffcc43848a74a6daaac5656082a8250398670a2d440c44ce2e7968450d83b2b9436df4519556d608826076191f441657a42c6f775d067af8fece3f34b8834ad4f7f1038fce286ab706e5de946b43c08a300449104bb80a38f428c9eea2f31461406996ce8bdbe32adf5f61db4385bf5ed5f83f2f4cecd3a88200eb285f04fcad220dce231beb02351c16299cca3a0d7cadf45300b0fd7e1404854b17ed074b001c6f65a8b2fed9ed7bd020a76bf684f3a4e0d45b245e83c3d64b6309ddb6c5e223eaa328047cce7ae3bc29db063de57b2e6e01de967220b29bbad0b4b667efc8c2dfdbde204ed9119cdaee4f9d4efc8af2fec234089da4d750d6f5333c7f0fcd30b46a150b265f56039fc5855c18f98590ebc7aac4faa0ecf063a390ff7959c8bc246278c9d1caf1b6d25db924acd731fce52a320245d94e0e55e4de801335c23a598924f8f883cf8cb70f9f267659bd390bb4be3eba7b228aaadb504b76ef2cfa3832c1a87b4ed5b08fc433dea34688f4ac923692eedf6761ad908e168794ad8efe6688aa8ffd7ee9f17276664c0526015ba2d063d6a534a1b5b580b79be10884ac9eb7818d57f3f4fe54c070a1d44b697f9b933ca17ae51c8ccef76b825839424656795be577dde824684a71308f61b81d4dabb59f2d8590037a24e9f7fdd251207e041667ac086996b10e1fd351c1c07da74746b36429461de2df2bf17c49a93efbcd59bfd1785fa514dc2d318c4d6a1d4038f5397007cdec1e2802d4930f536b61cdd474cb3d295e91c6f51527a61a4736665b017f49a7a3774e34cadf8fa15ffdf148dbd53d1843db83914cb1bcc93c60b71b7e5a0ceea69dfb11a8e5f8b5f3ac1c4faba68db8b9ebaebeb51db669678f07ce3f123b626113ddf91c5d34dd57bba4fbc8baf12ed9c5b7c9b871c5cdded75666086cecc190f39447c86a1238dd300ddb71a6bce38cbed525d5ab3182d06492c06131befccb4d189077e2536103e68cf8e76ac3d7ab8636f93832af4f6518681ed0bb9264f39b8e05d926683d8b3c068e3ae0157684e8f3b2a95c09ef1cad8e2e32f296b78cf4fd07acb7e9dc5ad7a4f618a5ce0303013003ae6e3802be24bc6fd83a1643924294a96f5efec4bb7f7810e96ea627a52571a6e8804156d464cd21e066a6002719c0d0690bc56be4621d676682c61d1557effbe9e7ebe6a86ef22371a9a37cb5b03a8b0a3ea47deb8495b56eff85df32fdcf44d56da2cc00bb2d1bf9539fea0e82c58584740e3d5673b578968a9e09c2642721c3c9c24f50354173fc6cd7d731c1b8c8c0d49295133f93caa1b0c9e06f1382a2d185220a0bdcbc5cb6516d15ca56a504f17347525df9e884bef05e81c67cc6c86fa362cb321431313d2b9b4c2b924ab247e44f83231bafad5882feaa0f1fcec50f09599c84c9b582383ce87be488dc1f44499d9b037e61fb6c376003a19e9e6fe524d17f7eaf5c57c01e3ddfaab55bd539dbc0e6a7d4a821a975c0f5c75bee8b0e5dfecb7830a9d86f0daee9350c70286dad04b4b6842b127932ad55a58fd8b7be53068f6f7e7480fddba52f686f6d21997173dbb25654949fc5dd47779851fd36cda13eff1f3476d28f8c27b0199091eac0bdcf67fef67aa7aa8f21e0b670bd7eff8a80c2ca0f844b4870a171115be68d72aa97ffbe14ae051da6f6750e7cae2a3951143ffafd9072ec8ac4060c1652d2342bd628ce3eac64772c2618142a16315e4a71980bf8987f35f1424c4ccb8065da48a47d3457e4236f76b3a6404e591631ab1d6a21af4407587996a40cb4dd336dff867a71b8382af844c954c62555d890af1ea25a189f51760f653371f3d16cf29f76b8df40992069ae8e0a83de21636c6964f2291117867abae66dcfb9129896bb2d26d9e7af82da5cf3086b86571d50ad376278822f8bf44ad8986814e0673fd82dd78b2cfb50da1641500496768b439e81736943a750a5ab29543b2979358f745860cd9d01208b380ad800c55b9e2b4f3a72b4ecb7fc44fd299257cbd848a26a036a84ff3bcfcfa3800f920c22b7d00abbc3aa6fdbad09546e50166386464bf30e1ebe7e5a83cc67f8ee16e01777849f40b0b526047ecbeb6edb200ab14f277fb83f26d096216ded6dac2cc1ec39fb869c9f340d51eac8404f939f9458b1be2fc37a8c2635b46062ea1175b0a82feaaf6d96b14f14cd7a821bbf67697dabc4bca5316e0802b88f50034559cba3707f02f4b1dfdfc19df9059780bb54f20a802cdf9e05f3570692bb9ccd681f88fc155e31b75debc0bb76ce07508c1f98830b4ae730851d7b851ec0d420d55bffdf7e2b5e4f469af1e358364d82dd2db215f96c1045d6c8386b209168a62c441f4b21c3845fe9a91fb5283b813742690460a1ef8f6aea01fa52116b7fd004bed1366a95d697b5c90d24849e6a4e81ec9e2cd6a3f3eaa2dcf964df8ce809d0e217d29e5a989ad5da1a77cf0b02ab3c2252cd3ee6e5cedf6eb1e7dd8b9a635a0cd7433f28f89bb965929109448914ecc1a87ba6742fc088f833bd92f4a90e5344c4ffe31daabc91b42b013df96a559508c5916bdfb8444093413600299d89d072fd7d3e9ea0b4f61d03f3f02aec633fcec7fd4518d08a710d6931a409a168cdc54b88fc02365c75cdba96e83c256c8648121b99489871a440f3a53a8c1e839f3c6735eda9b08a9ec78f3de2bad9bff45b744888cc24b187370ea12e1261738583f2ebf8428cc44dc7f6832360ddd81da3fab24399bbf522242ee034c5a42215616e256342541b31640447de487b81d12261e65839a1aac25218b5c0a6fb5090ba7da5d144fc5807534b5ba0c9572f9ab0e5ec87bf1d79bbb2228d40edec3ce03e02ab3b286888fc3ec35c3a819d9b701c36a47c08015cf350adde108e903a276bcbe78135bfa62f209d0519f10c5778742eb689ed055e73adfcedd2b83ebc40c995d419d88fa667869d2956b4d3172e6fa5cf1aaf3fabb1040ab7406c9fcd084d1c9070de4bfe5adf10e8f7d86f70192dba761979d355f4950deecd794c6194d82a7e6121003f0301767635f32e942c4bcc2208a55dcc5689b61dd367fa6ad9d559c8150d281f13f9e243743bb1b20e466a1e67b165cecb2fdeb576dbb79a7e8c1bc443c47f66684f5631d89988c9c475dab6532c345d3054e0e8e74bc9896b989ed12f2da2ac472a412ea31b40303ee63eb58fc808e518c784ffba5b1280d44a94df9bd7937a1651ffaf3c0a3db9fa6c56630b9e6f02960d59eb372bc39c62d36c86ba4bd239fcdae182675b305a4fb5d832d252c6ef2d200347dac04b47d2c1aae1010a0bc10afa6efd0d26cef9a9f39cc088873b9418109393af43bafffc36e49d82a3929532da04ab1aceb53b1ff882560d88cf6daaddf961abbf49f1a6ab84347ddd459cce43a1e6a76532a9ac18811f70d40020e000f611e75bd8637aa48ec5e4afabe8026cb46a04ad204efdee2e4a98bc09c895c67d1bd376348447da2f4abb7971853fa9c631b5dbef922403d0c6ce053e2ae19cdd41fe8592397cfdaf5f24016ae71f28e8f1ccabe2dba76a84a554413c0eaa0103db832d626dc98c9cfd41d4a7ae6f004c4b80edaf720fb95222becc8da1acafa23ec2baad49acd23e704ecf2b9214c53ae15e61efd99a34c533261b706193f18349a46b868b3940fcf90acec5c3db5db29213000b9178ed9b8d5151955a4f7daeef49b45e90b2f1c9f99a2e17df2320fca2964295d3cad5010e8190b6b6579bb75cefd3ba4150b37576fe954eddf46855dc6f47f1e5149428913f3467fe18a37131922f456a07a369e90392b4e717c1a9085dcce9e5c15f1d5c82cc4ca96d122ab2016bb52b282ae8c7a5372bbcf2e928d7f3607af2c1f0ec7dc793033fc82e0fad1c60ce2d542ba9e10558d90051386df12cf8b9618d1303c334f07e3b05fff9c4ec11c84f861c2ab2eb393b9e8b66490ecb2406884ad3516ff5991ba195421784c9b09f8f514716774722e8c0dbad3d842045c2cabb2ac39d75a077bd20005e56d30b7598cac0653a1b4ecf9f7cbbeb8e4a8a81d6ca029332ea03801ac286580c1d4c15c7c55340c6709d34d92b3fd25cc924bdbbb4b3c88979ace216e11a779b63dd4bbbcec7e16554f7822b0a8b6f11069a60936222562914c395238b8a598af8785fd728ba9a1229d0f688f1ae0d8884336056ef8fde7ffbac14ba461c9adba99fc3e4523667a5006cc91908f2a3a925ce3ae7045532119b62146e5f6ce88959bc6361876377dfb55349844ddeeb3580db16028b34f7a672b5eab7ffe02eeea90dd1acf835abac8ae7221e01aa495c3600cc458ecd65937c52f0cf8a57d7ad8e3cc8669452af2eed9dd40c7007fda69d8d662fa4c92e93b417eec7365f29f8127100fdbb233c0f0235f4766cd79c1fb32ee355b3ba5e47aa69ef7635edd9cd61ef593e4af2a3c12f789be72aadbec560199064539c1ac204e50a81ed8e9103449675630ce75291577516b5bda6a86ef66c25d874741248b8d2c68abdd976758a694675ac6e9563438054c1dd12c52a046eff194d66a6812ee528fe49fe935f009480565d4fe1e7a51b882ef983900dabebf7d3b32dd09400c2d1d68aa4bd7999b0fd27ae5f1dae818e349161c545671dc056449f3842e8e58ebde5ddc740a0548a557433d0085465dcacf982d50f5c11265ffaf31c2f65c11ccda58a3806edcc7b4ffe368b665737235cd93f14072c2e9866eb296c1ab524a9f0704ac04eaa6be024c84f340443872a95e80001a9cb1b7bcf29edb9cd8f4a758ab7f60bdf67a992761bd15fb83b3e9a0082591d2c177c559ef75857c0ce69a611be83e10b29353da3ae75db4ca25b5e832b9486938da27d6ebb100f4673eab6e187d3add2f48926d7340d4cbeb5627b4fb54fe52bc8ff96cac845c56ac6cb222bda6654772fb9c7aff9817f43f9f7b138004b075d2212480ca4df28dd3b60d3f603efb861e014affdb8604bdea9ab1a66a77b260fb333fae5b3f527c924dc5e6bd6ebb974da5e4d0c6273adc5a304b621f7b6c0a2ef68c4de750b1da3e37cfd96c3ce5032cb1e1766c9256657066b139369aa0c6168172514ab40d896c3aea18efa229e104094c673fecc279a01bc8747615300d2927c0117722a4eb270eba5269d1a8144a188ceeba49f6bef0afabfd0d75978870ba2627a68c4e5b2730f0e6902fb919d4fd3c19cdeae1a71f81106ed19d045880d3e527a4a874843a195e83a6b2d784b4cd09303b445761fa996fa5c8c024ef00c9c76d928b017ec518c9b1cf61e4d511817091e828b6901c8379eea99f92d77fd9041f096fb168f4df37fb2b5f44b586cab2ee227af6bbd438c028330a385c7fa838534e0e1041ffe6f9de4da2ec7c08cf68f05612b2259b4cc0ba65c6ec6b13e1329d690d1d87d2805cadd3373d428addd1303dc5d2f5dc136c99e5325d6e0d8d436900aed62d7d89deb1ab0816876f20cef7adcae9665bacf494d3c27c534943c70541cdd560d62a168796fa0725c2981a0aa0190cd6ac737a91be75699b087e933b29fe8fc8654c29e9c3a6914b0a44ebbae74452fe3e42f9ae4bf9d1eaf56e223ec51f0f8ab255973c64810cbc79276ba949d5301242e65ccbbefe9be98963d6c44b55cec3a5db25a1fde84cb36e00f0f90aebe861a968677420fc35f409b9dd51e8b6b01fe894d0de56f53792fc374a95e7d3001a6af8851bcc3f6be7f4790112923b579ee24c191621ebf01a58e8ab8563339ef96c37056986e999a56589a68b46a04b27c46c61cafbc73a0d873c3f81c0fd15351a98d2e8e294deb49cde100cfafb5aa8c648acbe1644bd367490e1d677ddf85a47721e81ab31d9bb5be6dec37cb26a1a5fbb13a09d46f01879f7a24fce5d06206d74b3b9edfd584e2b34424799620dce64f47512125ea1e84b7885b7b38a88d3cd39d7a9e8925429590eb6b9a45c6850a38742f0f4edb5607041396a110e8c35d64f02963f7bb5fe9407c719ba03607cef42573390be073019853b15565f46da773224a20a1f3e86fb3a532be3a4f8bd3a43ae06dcc8e031d685701d523a77c9867193d2ff1693091feacccdee74ba447064b3844c910ba9b68d35bcc9ff945630d07057165e883998ff357fe287b2999b71901567f6baed1431406f011133a0d96b5827fb39bcbb35dafa77ae2a33eadf6d81d3550f655710aa24013b824007bdcad5fee88ef04f7b38e5196c9b451dde5d5b5825e5a284d1c2792f805a54a19aea081dabaf962eb8815feb1b9a940d3b15987bd48e93c6632ea521c554c7e52643b6ba43af5720099981d4738e0380eabe6e6f5edcad60275ec60c345ab319564ba59789c07938522acdcb7de8fe812b1d1bd3a3e5da153563e7bb4f69d938324498732dffdb8e2f7a7cdefeb0d60c6db25004bd61af37ae4b5dbd20f0421754e73113d9a31b61fcd73ddf10fafcd1bda0e8c7698f9ac6e650350b0e6b2e372aea89b48d212efd6264ea1ac2787f0d4b7cd32fd978816b32608fd5d7f1bee01183cac475cc56c0ba03aeea0815548dea16fbd914d198a0ffdd028140e20a1cbe056cee6fa7aabe996fe82e233adfbdd000caeab39ee1daa0175f91653ee3d0a7b341b82db368efe54f104ce8a4fe69e91187c8286bf88e3b3c5be2ddcd641f0033b50ef1c29e98fba0ca306e5000e50dd67163f8519f8c25c48992779d3986929182b178dded5f6d0d2254caf6dac6700d2c64488e0207e47c05d70f973fa074c17e589aaa80e362c280ad79bdce63a84b92c230e56a2dc654b54bcf839e66859056fad85c220875e40760ec71be179053e6487481cdae9c5e755bbcf114b6569011a225c5837693023155e7b6b38fdc74814f54be0a0dcdb4648c4b4f633aa70f27d6adebf2d6fbc5a7fd08cecccf05a3690f05740194d476fbf664b6145b440dc3b23dde54f2e0285e930ae3ec2c9684c22e7b77b6378d04d4762e577becc27f90dd3bbed53ff8898c4a1cbf028633e695c906fdb91afcacf8be882e2567058c553c328c340728b93a419b2cfb5e7e6b24c91b555401aa8db26d1556c24600632153a6b9c8ef245a799db4daf17c5c90aa984b84c1230dba05852968568307aa3c7324f935fbaa0732959de83a8a73f50ff97d851a0e23f134cdc9a82002eed30b944ff920eba994e980124e9ac854e9119c3454a90a2b9e8490bafc5725dfafd1ee8c29b821b53fd57ea65fa17cff67341f2553a30471e88c4c062c222ed0b74b2df6ea9a5f4600a50521f98ded7f0f33f3b76edcafa4a58c55ed1abbafe4c40d8c579c3751814d0e9a2a0a444e79fe45932802e1f0e06ce81f09a660c3fd45276c7cb8458499ffe7338ff12363e9764259791ccc4f8a854898c7c38a7339afebd753ff9399559f5f1bdbdd1c8f26d0f895ffb5f78a1ddf32f9de8bec1be2217f2ffdcecdb957851bcd13363a49bec8ebeea18c05ab306a7437d57f89038a37f32151aa18fe4d2a1d23f32649cb9118b118c2edc719d05cab36d053f073ab2946187d90e5ca1524d434aaad5451995c658f9fdb39870e5906044068545547211fbca9c3f646a1af39e8ec3542fbe730c2240d7fad10cb9d80bdcd2bb240014d00179e3b310646d06f001b120ec8c05646b16cce2a9e5d6913b84c61fc0d6ff6a114abe003bcb7f9a60aa9dfabb7f47ec30fa95ace0133f4b4bac11c7b391c054b63e6d0ebf0d302f2f8b08fe4d49b15207cf092293d03dfc622d28a53b424ceb4bcd188665ccd9246c290e1655f2a4fead6991854cf2862c5e76f0c1a887cc88e77cc33592c91f25b7a74ec5e9092d523e1ecccc4339403bbc794b58f3f6332d04ebddf38259da8731d1bdb8a8a49fe8423bab39879f49e1c02deaaca48397714f7f9aa69da1bab9b6400093c646998d8e6eda8da85c16c0ca2480c801ba82ccf5065395bf06e093f9cfec96358cbc084fa528a2ac15e549db469e97086bf69a0a27a171d5ef0c7ccdd024dd4eb42183c9b01043661dad61b57b9081c675a273156b6b8cfe219292899ad322f4dbd288bab925df733f35f09968ef1260d18e84844b62fb64d2adc097b8f01a81738b453e6b87195032b112beef13a017ed8be53891a48fba8538910acd64d56e6fe073d523885a5f992a17789ca61ade8bc95883993c679b5c9bd63cc13291ffe9ad1541fa934fdfa4f1351aa39613f289663f709deecdd797a329163dc7e102842acfc22877276060bca275261a99a196ee8dc568983823adf6eef1d60472df124b9e31867fed5a4abaed6a85cebb6d49a00f98ae44fbe20b53c7336c94c9d4f87de1d243c00266186acca139faf5b9deba541d9020132da0d804a791cd35e81e45f5e7e3dd00fcb515cc7381679a41c580894c0743affb31d3a4cb6f62081c664647ff356c99c9f26d6cf2e47f349821739a223af320c3201a2d9b2a24f5bc978e3d8453fa1316b2645f14f4a0f09d2770d59e412c82759301dea8cfa32ce44579e73ff49536dd6446746b2662133ad723ab2ae167012e04f072786952f2cf89bad0ffa06ab15e074f3e5e88084f338efe5eb8db15bb725a169f83547e386131c5242741f3881149b59cd0c487c9209fe87fd9497dbf5fa6a75bdd1631d72f24f0c6850171834035268fcf7a4209e17eb2cd823b7683300387a86f8783e4e15d3ef63a24689bad48f98226fa8de723ec6a908cc627b7dbea5b68fe299d5ef2fd2e7906821d49a9faa36587cdb793005227f67abd4936857437869bc6c3f493dcf4faa747a44a06061edda3b5f155debafefb16e6f7ef189a54198921e55656db6a152aa3c60a117ed3fdd5d6528a446fbcb5d399b426965fb0cb3738f6ea2405a1cf1ca52a26d7a7bae5515cc7375eaad68ea263a844f4560c9f6db0ae4ddcf3d95552b5543f1e4a9d4bb21c994596627fdc222c9779dee020f322216f664938c327a1c2702011de1e9260b9bd034156b7df2de087d9414b965a35133bfe667058fed01446d1df94fb434be40f8e5c884044248fbc2a8dfbff56a0a93e5ebcd242fd5b6fe178d55533c689e6e5442f3e4260dccaba68af192df61cc1c1b6a5216d48da698f729c804e688344179e50e38f16b474066887ab4cc027e3fd406dd4e0219478e78b6233c3b417fc458d070ab023c926a21322f815f9b546818a1b451585172a28ae34e382d3a4593dc1d59342640f127eda3e7bf25cc86d9d74639b1ee0f5c4dbfc7bff51b9edf7bbd91be43808fd16be8c3a811aeaa3608964f3512e794f6ba5c47c2a09317c8e12caf0c3f214cb410676391061b2f52407e07aa2ea362e444b7b2c8c665feb4bda330beabd8d8ca4a6110c6d93067737835c752ae4cf45bc6c2a41ca61cf9c43a0b344c432647ca63fd32ac7d9fc490c47e35abb8a84d3e8dd875c860d4a5c86b355f31f4b647c00a94d9ee0316948590c63d490b826148af26b35fbb3d6a56a6d87fdd4e7d30064d5b8da9fa8c75819b6c7211e786266864f86f88a8b9e72b8fb2400d1bc57508137ab4d6d6c922d2d8224999ca7d1c92cc550aedb54e182ccc9afd9dbb9ed572f032c9a6768b4ffb8f4b4c03f33bff89de90e5257a05317c0c1250849c2eec208fbf2f1180c3e1e6a7f0f407e7769ebca1bc585804e70161f5552d753150b2d621734ebb8952e85b5c230c3b601f6909807d268dd9c2a3346fbbf646b0576e090282b551c0e30dcdd7d0635278772da2abf2a522859a1fc9cd2f80a25340ab2023f4996720a78fd092a3512678e41aef9920abcfcc3fabb9ae4dc60437cc26792e7cbb78b3159594e0e4a1c26bbc7a48293aba1c46b3eada411f565a430c7a10c30e1ba5924a3a8b8bd8862af8664bdfdc571eab5dd4b21beb97162c437eb5bb0cb4b5cbb73d9bddb3ef971dc07173fb7235ce381c98d60584c40239932153e0f007367fba9ed3e1263d75ac3d59c11cc79f4aa14cbaaaf9cf3bf31abb313a89f8a0fb189785154b74c8b8fe9b08c19b861ce2aa1ed701f4af3f701d49c1070600c80e25d644cb9129246ea665816836f5d0a6479faad95b29567d398e8c7e8f4a9bf2f57bb93d1d5a53feeee7f6a4151f520e358624179e76c2ec00931198dcca9b4834b610dcfd50926e445324787d556332f7372a6a1a40ff34e417477f9a52c0b555c2a3183a22dfcba6c6a8d903c0866830f36fdbe6b135316cc43b1f219356f150341e23162e423c543ac1b36a975a8cbd58a1406f63372a33615ff05c191a20be8c20dfbf23f468f614ee1e8e3a7de604ceb0219ac8277c089c630d15472fd4f502523b8c3d6ec92ef50fe3c1ff4409c37b9032878c424a8352513b4ddf472d1768bb2832d039de456ef7a118bc841ff49a9cd5de7faab31b1f363a2f3454e016065146553d083aa6fb1955e015fad2e468839be4fc73c4ae7722d357fa409602a24eafa605aa9036a5eab25fc7de79d4636f4c3f67477590e7883436ff753a055e80fd6db4acca45b77b661991a3bd403b8022a2a247085474d8fe484b48a1586baf85d60029c6960c82574683e82af0903f7a16a0a27684180403e049ffb232747d03bc9742458c9699acfaf3ab15ac3629d097958195f847a7d15bc4af3233d5957e090a4808819865fda9929a2976253028cb96e6392a2c8d008916872229c618233a2028ef2d3b0efd4cf3601a10e26897b376708f438b8d1d00fada4feec098a90a90b2520b06564d05489231d06104cd8e906a1246d483d2f7ee79723b451dd32bb97eb100a0034d39880969c8ba9a4c1ab06b59f101081268815d573fcaf204b968ce8238888afc6db63146cd85fa1edbed3b3d46e711bbb72c9e50f42d67e6f863d948a07630821df176888f389414b6f1e231ec33d4a1e1a75f9c13fdc1e8399faea14208d85cc1ff1174b2be0f837f7030b11cd0f43ca11248480cfd9500298c9f3ed78ab51f5178475f3dd769a8a3b8c5ca314303e16680100a150c316a0907f454d232bf88d36b00ea0797aec498375a28dcb74867b5b6c0bfc519ed0d3750e5073a332424f93247c77ca43de779de73ce8980b87a80682453a6c86c163e63a019ac93618189b4f3594054de523cd1415f3c2a33aba2a0172c2acfe7e37f33f47dd44d642608326779088450cefd1a78f7e4021b94929e299f31615210fd35fbaadf0c51dd54c41b166d4de2dd37f90a95bf114b15c7be1b0e46ef5081d76b63ad953a22053150950e5b618ddfd941d73007a1d14307280191bc714104f61794c52d6520870420a619335f29203ffca329af4b9a1b6c8987591d2a376b0b77975be9c3db0691fc0fe52f9067dffe5094883ae5587286fb2e0edeb2fac62e14de749248066cc7c524f3c2e4163a39099002bd586c322d1a7c4ed19205d6d90285a925bf7ded076bf72dbee812ea6da01127630e31162f27f0c644501ad8a4b326bb45f9b42146f25f5bfa82f7c16bb000d5d86efe0ca523e26d4ca80e897058ec04987d628ae2f62b11d3ff0c59b3d36e82a150594a9534f651187fb804726c73898b68b24fd908f75a3c1f34f06d5d87f8737c24d604288625b9c132783ba3420949689e09b4fdd8adff17a925872910a1c2228ca1f7f7a58a91054c59e5a3ee66e8b8080395355397ed3300fd28e02ff439ed031528e276a271d882e75a2174fcca7784f799b41b09e2c67c04d5b28e28196efcb0783df0271b7637c8b96eec92e8f5764b6d59f0800359e59d3ffcdc6e6bbf529dcbc396944c94e6b89945011e3424d10eabcadabf2aa730c73ae6588641664ced272ff5eab52a411728dbd7e328165a5ebbfda518344e22905b67943b17a3e412cfda228cb341a0848417fa1a9f87bc8ec100679d80315c8ac2c4a97a12b910fad7c85d7525bbce4fda4c8616342615480704509fbe0bc622345e6a00c4f481d05ec34a4cbee7a7fd6b3ea0df455d8c06f174b0ee65f5bff32898e3f8a40849e93ea4d6f8695c2e59757a9c15ba995c23efe35a7a1ac01ea4ccf67775fcff3ec2a3d6b5588f19526476ba8ac425189f71390720e6b4234f179029c2e9761259d638d501894e60668a2f309917b6772f0345920a2d15ba363468c20b1cb8c04e9b058044832339ffffbe93f44358789008b6fe09ae3f2e92bf515c459420965e791b75cd0d5991c064292143c74d343be58e0dd2c59b8e10b6c9348d33958169bc4b20300bf69757cac65d70c57b592d91e8ce0c20884b0de134041c8e4da034ee7e3fab7af62b0b727a0e1f3059374dc8de1f973a267a9a8822408fa141aa3abf9d764e72e7da75096c236b2ee1b76734802c658edff577ed4f12a8cd0c57f6dd5821397a729260cf11f23e89fa51a4b0c247935086abdf3845930d1a7b0a3579fd3aeb518985d0ab5f0fb9a594587a225a3cc6518a571103fef4890f0fa108af52aea47621d7fd9cd4231563e2aae5e02483a437a3b23fa54ecdcdb2567fdd84a0f496589861d0a53246155eccfa52174b95b3ba0e433c907e8328f37bb2565103d7de35eaee9b6bba439c67c57886ed98a456d0adf4229c934742e20f0969d14e192de1791db826185f305e61df23ac3f3a0ac543c6a7164b3dc0a68f92e560b5cb2caf4e14c2d745c97a7eaef8960f0edf10c68ac1df0beedf8e7a54d3df8e2f1fa950d091ae8f99797e6d131f1aba10c2b773221443dba51d79898fad2df9c0db992225e3f6af8293af9cd8d7c579be5a2c824f723c53b386191432b7c46008985054a8fcf9b9453be4fa8030a954ca5595dcda38b85242f6470b24ca9697b3629149a227534e978d3feb7bb88c711e28203fb94fa28faa201f507df51b8ac70e06cd6bc26c85e56d29214348ade72ec9f1e1e9b04ab7c0ae5220e2f9d1a521317b81b1fd5364004a5627bd00196c138a9c85994e2f70ba50b1afa5e9dd41918dd90622321e40a6f05d1f59a8309e0d9509ccb165562a79049a2422dda8db56544fc86db051997c018b073df647d18c5472fee5b156856603da56cc41c5df149e82e15626705c0f269b73c74a643bf391e30b4f513cdca383dced5daf64f79bcf2598af3da2a8e5ebfd3cbd617ea77c141b9c9b166dd9f1921e15787a883ac02c9e324455ac86176f65be8e67454b6965e66238c5725106e818312da83999649c47ae10fcc45d934bbbb85bb48a3fe14a18fa0c3dc63c0f8546b66d38e5358dfca308f2c78aaff4958304b6602c96702197ea59f2e7286ba40833ef233b99b8a9617b61110a41f9f2258033d24bf57b88433ced429b9e95e8b3cf3f00fd919cd6cb835af2ad1e3f39e3174c49e4f56d69376b376b14560501133ecae0302b72169e4257877acb1173ab3cbe60e5a0323a5ac8c9878a127302fef4ac923d2cd0639fde3fdd5c7cb5b4456607009c3fed3691636cd8917eead9599df30a1dc619868708ce911509919ef68004c01806d81ae1c55d05d712944c0cc62ac1edcf4bb22614664dc6b7d22e50e7824f09dab24ad29a704c04ef4a91f621738517c7f4aec3e977c354853b9cbb18f7e65a01a3631df5eddef1c7b9b06afcb6065bb189c4075de8b94025c3a635b256a2ea258f6a760a7c44009a7dfc51aeb0fedcd545c79f240aa911bc9624ce1b85e3df942bb8564bd575db48afed5ff7ba34885b4ee8d3bf4e6096ab05480b2b0b607271ffeb5813d0a5ebe7cf0aca6588525ba4909889c477a9490f59502500628e00cac22dd0cf5c952f59acc201cfb0916c4124c216b8686f55f9a2a7888cca5ea2f17791ce204ac2e81247d38ecbc4458d81a80644193a491854710f7a4419131cca3ea66d92af4a6c3d075bcea1b76bca15ef30ca0f614ae52979381278195bbc8e1ae8106ec9ad82f7e0f82e2e09a48754860eb54707b41c20485b6cd3f74ea6f9b91382a6278ae9698ea90eb0c540970ee11f856a46b8cf760256701e6219c016538521c412122f3f3d72db44c922a0dc5fdaa08f96c5dd8a42316bfb2d65c35e13831a8e3b61e38c6ded23955534431491ebd31993e2dadf2064735cf47c852eb937b65729e81ac6ce5abbb498df1d6fc2adc741bb6d32a8cb02a13c3fd3e8cd9417667268375eebf3b8a02d695903da527baf56d450226aef714e60a448beef7e4dd7ec1ea6ced02c5bab316854306b8444d178e71d631611a524946cbc75c19213aab0f605c860977ec9a2417ece00c47b69b14ecf7add1689cc527fd0c67ef1e5a888d79390d8829c28df3abc27b6f1df85f3e8364ad02cf4e20c3b57405187d8fc4054557b6507079e9f075fd4198a9ab04b92e56214eaf5af706159cea3b0c5eae0bb9fdcaab40311494c13792cacb51f4f4cd53cdc1e426c3f3d6ef8671991778ef808de73b640a51fb199f6a60f92baa04e325f97262f3cc3900cdc8213b11a3b64e459ba5428cd8269a1416732e93477b3f3ad86dbdda94237dcc4528c2164f1814c227ffad6c61deb34f15452e9bf4ceb063e69812a670286c47087c11d5ff6993a0b940211316f27d2178e06fee9bce1e689540d1d28d0c33e5a3f72e0e303ca0b15254c8b3df52188d75632c5635aedb9b7c09ca88bb9b41cec675c9d2f45606a39c40a4edd141d25cb91b6d2b0ebcb21b98a06fabb204d1060f390326dc8cac0a18471e3f0a58d4dbf8c4fa930a7bdb0972ec36d18f091bbcbe09e75d0b5167e04d728ac133a06dcda6454dc00e44124bcc98b875c3329bcccc193559a6896c8c1b7c220604e897fc32be6fe92e1010a5e887e985ea9534b30884f90c3b80186d49b55b240b22d4eeaa5c80f989d00780acb776fccd54cabdba263c080813fdefdea10066a6e071568ace914648e5f818935f5fc72b25ef746e36227d0df57f37b27a38e1d7a4a3945886a65c6fcfa59aa8100586869bfbb0aff62a9dded2c6d19e251fde98fcff9ceba70a448070bb3ceb79a2f1a0922b1c2f22fc357c8cb1711cb36307c706c0a49533af29bf05cf5cb4360b94fc60595b9f400c7f26f7a605dbc343547f3e52b75dc9d19961dd8bbb58db7046490884102b6c8de26e47d3f1b3a6cdc1fcf7317bfd878368077c7dff08296b28f4bb99ce14d29b4c358a3f77f9e0c8ca17a64f5ae1c2c3c646c0038b89fcf47c7709cded496ced8816f30e015fa56f82511a4a97dbd3d2086ff49d0380604f7121ce870bef98dd134a67619209892e2eb6d4fa3d60aeeb50e1367ca9f810e2fb34380ff8cc28f507993c5a0d5dede589e81c9a0930c61911429c9dd99127c725e93dc9a693b1df387af181ab927a7600b7d172570b4c2047241549ebc23fb3f662a2b9d799e61f4fd6d1af82fdc79958b0a04812d2a310185461e0eb32b9e400c191f2589d01fc6fb597c8652692121fc8fc0d8ca896b04a26a7e60fba616e3448ae7289cb7032977cb79f806e6adaeb9000282c71af2c6119e6ffe9118eef56779bf9405087b67cf2f09315f821ada15d18d4ef84a2fc847605019b6501cf253bd04814a4fc7098925a8bee7e9f779886a76b36eec8ca66bdf7b099147c0322ee507a3832535687a1bf19094e3a689ca218d35ad69b9017fb438389d9eb37466602f36d8493a6ef629af9dc3047ac182064182011c7701129e52b83e3bc0baffe66f0c91438cebf74324878bcc044fc62d30b2ebffd3c3269c918d5d823cb8738413280ec02ebf11d3e89c32b463136adfb9085a25655ed21606d9e94fa579c855f1fcd9627f3049b6011f541fdf48036cd4040a2ca50ff9cd784dbd158819d7a1f8763f74932596835bf6c4b9306e8635703807f91b356c0d9f488e8c6956340390b66a2fbd49c18d02cd30dc19dc72689d89ab04294044369732478744f21550f3e7bb595f73e84e6386f03ad4f36ba7025c090565c69f47b1d0048d057a947b8d6a7821e9831e516c3d0f617a00e770dbe6dfcca8c1e5c2506c9c807936dae25e95d067ad1237a0c800ee6ce539c61ce41c3d77f592a367691ad74466a393cc7d720931d492570b148679c8c4643ea5000d60022ecb35dfe13dfacc82e7ed26073a69ed9f5c4504750522a0956d8871c679282f40d53c87ca231176e6cb3f16ca0f8e15703f69905ae71b6a86144333a8c2c0b3d81e460ffe03ffaeb7b389f556d57836999e562081434c3125f105e97612b2cde7813768be2763a76632aaaa9ef9885e72a9855e2fdc101a0ba18d00573283bd95fcf152dcd3ff2a157c57bb292f097c7f24547697ffd81fbc0207f07841953bf3c72c024d6d17b43f8d52b58433325d41e628c7a4222ab4e7a3e6c282a39692c3034cac274cf6025a013e6a5e30ccba9a0e851a92145a328fb222d12071c03e2b20318b1151dea729d1a3e1b25b81767871f0f441426607c7eb2388f0ceef57510c33bf0eb32ee67708171b0a3ab99f1f6cae2085d1c7bad785e75b8b6e2224a4edbdf7965b4a29a54c01c50677068006535c80addd2fad75f2997da74b55469fd0bc608b2e0f207d7022b9931389c60694f6f79f56a6150c52a034c80d970f4e249ad33d9df9d6bc6dcbdb73ac7625fa46a0b2caf097c9641a49ed72d6a6159a33add0e400a1e70391ab0e9eb6b99bb8dd706ea4506503597a9edcb258a49d43a83fb4a9a5b3032ecb34777a7e80967964815e1883cff27bc661e7b1406946d5aa032bca4fba6899f3d49fa5f82cbf8d2bb46d26cda4fcd9e6a239b69d217034c706bb4273728ec1894e2f4f95b44da81983f3d09d1fa8eadccf24d8366f2f55f1835bbbe4ac614a7941dbf4ce47546788fdeff3d190fb605975549ff38359e480c8f61e4f3bb4e9d8a53e7c1eaa17eb0b497d48e6afaa0fc9095565f9e990cff2275559fe184d8d31fae0df8e0709b4434b2fbf3852a72acb1f8e5e40780be8ddfda4746727ff474ea5bc71d016c81b043ab4bb0761eeee6f085efac5679982f159fe9979d032ff2481689973ce1609cce2c3e1b68d06468509417ea265b63385a1a188302b845dc220e994f40a4c6782d652e025b48a8b4785068dd0801641642edadbcea4050f4ba48023d022052b5a90806f1ad4a253c20a11098c144c50002673a1c32e1f5416f008ced30018203a26c0f4202ee96e3b1318241d60a8308119eaa8640d937972428bb643b3b1c301a757b6c20496ab8a314e56ad2aa098e827162d53a14445dba1d9d8999234454937b14114a72625385c132225a20da450e121ac820613bc27f096819c750eb50b382af3bc810b4e1ab6e4840d62b8315531c4c5911b18241b74a04805493698f20405135c17251bc08063428196251bc890149535ec6e67fab2b46dff38255a50a1c32aba1068d0890e49ab96f20f1a97a08988224d56b034b9e0dd9a8a86681af2a254104269971262124e6c41a77ec8421cd1025ec294c3129ab59d89290a13143c02a625494c48b6601ac225e8d40a3e2774cb09510a9d93c0f229c1848416308c4e6d674222043908bddace8404920785d6db99908832051219e8aa60422289f845e3ed4c4890a0e30b2e8b315974a1a45fdb6e67ca224a2923cdc8bc5c5ebc3c3d41b15694e24ef4b91efd2afa60ea51aa714a0c412f77f8c2ecd2929393979faaf35365953e8df63fcbf27f678746fbaf254b4afda05c0e48502e970b82120a021294cbe5a68ca05c0e48502e970b82120a021294cbe5680cad6deca5e942c7f9c1e172fce070b89f2b1efce4f8c1e170191694cb0109cae582a084828004e572396fe6cbe0899e468200d1ece4e5e91be7adc6840da1818df26f1c4c17f3485414982e8ecc26417eb674a93f573cf02d2800b23766a5d166370c6067756b7d3af872a552e2addd63dccd0aae449f4e83aa10283b3d5d1942e36e7e6eac3f312b0a8298ba80790205403f5bbad49f2b1efce4f8d9d2c59fb0b3de94657843e3c679fce6e646eb554b74852f2027efca101ae070389c0ea232fa3f76565ad0cc6f8031c09e948823397e70b81c3f381ceee78a073f397e70389ccc37e3c1721946478363b7c6d2202041b91c90a05c2e1704251404242897cbc9c8e572b02f330848502e07242897cb054109050109cae53c372d046c0069bc1c8cb841d595a26983aa1b1b5439111bd45d87f1bd5aeb69823a3373ac0c7d557759276b5b37b3b0b579f2589567539f8ba087a105456b6b58ed97724fe55977ab5a31eb65dc16aeccd6556dadaf0e77d85aaa8375b5b3d67b6fceb1b0d48d12d06a2feef20786624aa557ac96eb2533038331636560d0c854191a58ec6585aa4c47c55c3535362d1894eb00396cc9695aeb779c334c6b3d83af95b189c1baf85a7cad4c0c192b997f8932f4cb0865883e1d6c546158cdfc46cf67d4673b745e1d838820d444cfc7ae914c611729ce9811dedcd000690020141212028017800064a11256ca3a990030be9646001684308fc2d7d258806377bc74d892fd797af112993b1a1838b35a972cbe306617d0dbb90e50764b81966a15b2d1605c5043106829d4d4e26bf1ad01a359fd99a67784aa4cc8fe0b61a80b0505b342b4d09d079612f2192da245014ea794ba7b7d6dd7ae15b4e1b475db7b2feedcbdd6306777f728a595d26fde6aad416ab5402008864ed688a2980a271115139076f7d56ac562b15a2e777f596b31d04ead95666bb5b56e9919188c5a2ba5343434b158aca6a6c6c6c666c698f7e25b6b9541c672ccf92e770fdf4691b3a8c5f9a39e6ae55d77cffb9eea8dee795e8bbae64b26749af36d0b83d2cc18ad993634c694417f8e949c33ea4de8348706000250ca040080009432015810805226000b704aa739ee0e0327362343c37185196776c14e0d1a6d00f7ded90535680320c0bd37460dfbb0997cef1d67843e6346660e450561a256a01d1a8e2bccb40150026010daeeb6b4625a6ddcc8a94c043ca95d7b41db7e8af6c7580773079935d6c1b66490b92bf943cbd0675868dbf7f88c041b0c854ddfd2a9645325288ab6187a8188221338f126b218651165850722a26af47bf8f019102de7c77cd05f447fde28a58fd402483f841c5705435b086462685bd75f6a18069cb44cb1e2040e2e28d5a60a4eb66822c414286851529baf614db4ac7be9fe66c075bc665da5438c095eaa72748821f2d2f7a4ad9e676249fb64dbf9d6755c0a2b4e2908b302102b80f2993daa4e6c4e323687d49ae5b10514314ed4d005182935bb0108a42812c56986255ccdfe1cb23f89ece754b11af8cc1a9961a127917d0ca2b4db9a2fab4e8d82bfdc1bc579eabe4f5f701da82afb46e1b0ef78c77dbf8ee00d1ab46de2f67dafb2993441a214f801a5b7fc3907f9d3fef17df7b9fbbeeb82fc097cb9a0e7eede8736fed448b47187d451a9b2d1db1fadd53035d617c7ef728009f8f6f74d2fb4b2fcfbb7ede5718ae40efa41fee4455909b874e36eafbbbb7b757b4710e6f7a0c9927c275de3018df9fb86d11c4ac6fce77612c7052d4c2858045a34b211850212aa61733e25611c883a4299a24830a24b984b4f0dd3e076a6305ae89abfe9f9c1910516e355312e6121850f4f2b38e962870d909045091e4e187282d34338718ad120022526b845c289e3c7831b062a0c164aa9ed4c61a0d85a627861117305524dc808b4870f44d58eea8fa03aa24bed8a25a80941726b47f447b0556a973c9aef3fc29c3ce0fb975c07377942d1928fe8524569d7d9a54ad2aeefaad9f569d7292903fe3b529bab0e3e007ef75903ea9ed42bd502fa8f32d4f7a048e3afbfe3bec53127614f02fdb6d221232324508c8cb61841b1932ed1b609355b6f9f12559d0fdfb2de4641aaa9350a085629954aada11e551b6606f9eddb5c29a6810e3edf3436a0347d0c52d029194224b926fed17d24b9b67afaa1f84868b5d4ab54fa59df58a5542a63b561d6b0acedb5069fd91b36143ef299fd9a543f50ad6cfbad91264dd64857e314e332fbdabe8a846d3f9564db178f6c5be4befd283b37fbb67287e484c2616b32c55f8c8c2ca0f142ca1623a32d509e40ed2bd3040e459e4a20aaf98b625c762f258a721e9c7d9f0e512333df1b2341db66942da44855c76b3a738916d5a071b66d462db1b02f55da9726edfbf3e62e93330a0151e8a831ddccd1f20b2da36a47b4d72aec6a6fb4353bba97d5d6dc70c845d1672ad1f2feed2e659919541e668d8b6546f9ecd61d7c767fce198567142defd3aca0efb4509e9105273c81b6df18631f9fe1d75587833933e0b2f17b968d3fb531fe1e18638ceb483bfc37368031b6e110e17f001e83f10d73ee689d7ebb2932c6760823230b966c1c8cb6186dc939832ee7999fffe53a3e2ecb9fb1d8ecfc005ae6cfd9da8ab3f3f7709ebaf34fc047ce19b423adcaf2d7d1e27041f3a03936da037ad01c1bce04688ecd45e0836698139d4337ff063b3daac8e389ee1e7fa9e78f0738ca9d7389336df689cfb20a3ecb2e9876a72c75890b2323a31bc6602a8cb684e9aae0b0bb2e29cc98da54c05dbb6e4ced8c801874605586e47a42c366ad7bfc610d54870acda14cbaeec11ce6f4a09f961d909123f8c33f72bbd0fe398fa7c61efce1ebc01f923aee8324adca4aca8496ddf750cf7b1a077cc0fb4a969e97bba775396b6d83512a0fe691369638b4ecbcef1e874673bc5a764feb66f745dbe698dd7565594ed2a6c7d01cdb0d35f2a017cab8d11a2812a5f2bb7b1ba5b2bbff1b9a43dfc38283546bad16ecfa341bf35db41c757923086d83d9cafd37557bfd0127cbed33c12d0b887fced0da6d5f044bca90bfa44094d227a1ee2fc5b556dbc3634694b61ff464bd5ca65bb4f127b1f1c4d11b754aa2371ac579561b3f95522b26435a628c332df143d1f28996759cb94ae93871e3ac4b95c9799c87cbcc203ffeeebf874e5cd5994f13a752e15fc165f8e90b94ca7753bbfee73aaa181803c9d807a9175fc74ac8fd941d6b47f490d57b6d88ea6bab51c8d10ead7f015ed324fe1d2a92225559142ae013d920699bf456ff036951183e0df8b6f03f324afdf0c3ff28135a8638e727d2067e1865a4b71a3ef65d6f340acdf96264a16d9309261bff7caa3af4e632fc394f26a2a039f8bdb12ed192cbac811fec7ad821cc15bdf90cbfd7269fe19f3337a1e613c61fde2211875b5296dbed76bbdd62476e8429badd6e59aadc69698a468cb6d19a24da46976246b521eddbf635b47428d5761ed587cf6418e9d5f62b34cbccc09e802584b96db3882ef9cc3e6de233fb4f603b15dfb1663faa5b6bcae6eeee5d98350cf4becff31e5cb5d5566babb5d61a7636777757595ddd571dee94b4aaa4ee2d77c1aab8de07baac10eb61ebfa9cb6bbdfe359b58ad6d69a0ac5943886b3c7c32ae935bc135bdc6ab940eb02288637ff37bab5d65a212a3187bd2e58eb42bad659a7ad76ce5a6bb52e5c7cb118aa520f53a5a618dacebe93f8bae0423a86eba33082002daeee7de0bdfed65b9ecf7b4b8fb5c530a5b74ab5a7eb88ef9e3b38bef6b591c0ae2f7a5aacc0aed7bb8097175fdc6ab9c04fc6fb7a70a58ced6f5353862eeb6c35b609ec9b59620e1d06d9b7fb9598a313615f2de6b03b67d15a0b523279359d67c20861c0a0b9b5eaeb19dccc1af6316c656331d1e77eec6bc2d4fb4d8dda6516b4d9e64ee635a806ac4a96259d314297cc0d4a68ffbabd890913174dd66a9b6dce511cc87605548000b42264e2022ec1a272e1c3d255a83993e6d39e73ce39676d625265b7ded29c9bdd7a96e8d362fd4af4615911ec1513fa55a28f5699b04228c390ec899caa226968db1089a6252508e369d99e925b135111faaa60685b237697851662df0ed0ec9aa4c8ae4f7356a520dba9ad9e33773540d826245bb625c0b62f43f4b15774988289091bc44071000817365c11e68b156240026fb89201cf79624c2e367d1bdc0bad1acbe5480736fd98e7a07092240b0d60a0a480410a8a405a01a9051e926aa00d50324d97996d7319d961d3a623271471f2a1309d2d8a6cc000db3e4cf4b1f9c852b1adfd1912e43ae79199af128ed8f45f59d0b294004549133825311f00c20927505614f14592da048f9a46b0e4aa3baef93f34c75da28fb525dc5afa0a952feb1c6a96e8534980da1489129468dd4402924aa70b9fb26d12db360d75b1eda7b4d658b4803347b4477cc144f3ce90fd8203dbbe7d50f4b1564c61e24282a32b460851d32b60b901ea87288e1c55b086ce8b6fdaf469fe990f6bd202e5669d43eddaaf6d0b739b3ef542c360bbc9c2a68f2dd31653ba2bfad4d9c5924ddfcea12b42d459b52ffdb0e953599123253f7c0113c5113d96343541e56684c2096af50a239af8acb5d6daa933a6c8a6ef339a2656520aa25fe6571dac73055cc76b3695adb587ea4a6bfd8e147254491ddd6752887fd7bd904aa48647ea4588be08f47bf8180352ea6119ae3ade18be37aa3e8ff9bde6efb10facadd57a0e33853951c80f2b8116e2070dc0b0f1fb9c81c418ff1d6bf80c7ffe18502a7f0ff5c818d0e7657208f8f93f32d7215e7b88d07f1f9c77d2940ce25371c7ac89e4041f2955a4fa9984b128f210528d3f3daa0cbf378aa053ae34a30b6d9b44369f4c6ae04cc6baffbe3ece998c75ef6532d6e5df017ef63219ebbe1f12ebbc9cf30f1141dce159f4e1ec61a22ac33fb4c4383bcf7d3bf44571e348db60616d8af69dafad4a4abacb33ab8ae7c667f4fd314ccf0c2a49a3c5da74e6e535e8fbe06dd52c22045dce87e433ad74d8db794c806f9bfa1e3a913aeb39e0a7480ee8b69fdae216470cb0d0b0bcbf91ba5cce93523da53b1447cf09b3869e2f69fae03a228cdb36919c67dcf435a54510b9ed1ff583fc69e70acefaddae1dd9f345c54948b47c9a83b669a0bd7b3f7fd7c1bcb1c7de9f1e5adad841e3b73d175f24fa13879444d25463596537bc860e8f8d99845482dfa64840f479d0eff9b1482b2b41e81a6a3f67188c5e1b3b687aabb5df398fe7504b9b9a8cd99ffb8e769cf91044adb49efa3ff5693bb5d6d7f561570ce837e29e5152368ced4c514a7b6eb0d608b8ccfe047cf42042cfefc1af312a922139644878e97bd9f31c6c451f7ac7494b3cd65ad0e1c728f9f52925717c66ed4f293097511abef8f3e9d3d80d627931d48147b141985f78f981490ae0af489676049c27a6bf6c5bfdb25d554cf1459212292c61e58a9a7d72858a1121929862c90b4222f4f051ff73eed75a754fb52124420f1fe01d73fe5e1cc1eff9c004881ddcaf245195d9a21ee3cec36017300154752600820e58a1c30a8eacd054b3cfa3ea68225270240215c2c880829afd9e1f9a5a14ef518b41d79f48210ca08c20744d107ad6a4ecf0a0358c34fd92be86813950b46d473ffd1f0f8074ec80b98ae2ef587d480e097ff562f82b7daf8f21ab0f5f1c532fd62992e27fa48e15996d7ae720980db633908e51539d5599fcc144b32622a0263ed1ac85b07befad3dd5d6bde7451cab8fef534fa42604246d40fbfb2f450a095f487df189d47aaa387a0d0421fb7eedaea8000b42bdf6f3b6ef41cc923f4029f042ccf169d0b3a3f513d974c76734039fe93a057019b5edece0f059856110a5bf20407f1d1edb678c80894c9a4740cbe110f47a5ef798ccdda8a9d0be6d39a4e5ddb521748c83fc239309f0dde5b226864958d6b4bcf8decffae2dcd0f2dac841df3a439752892d4faf58b8ebbeaffb70f7fef75d30fbee2ee33e535de3eb65c69f21c69f3369833133ca8caf77915e6556e4a06e9084f9cc76e14b9512bfc5f256afbfdd85610e5bac9556a5c45bbfa6a47fe0cffffd1c61834ae1973b0cc30f5cd65a4bfef80580e30fff6c6d33e710bfbfab877ee0fade8efbdbdd5b5818eb7c74eb02a7f85f96dcd594f40feff1e711b67fe5f7b9f776013fecdbe6f77d3fbcb71f04b93fec63fbdeb4a3ed3ff02ab33bd72e3ba57f63ab2f16eb5be490d7bbbe450e39d2f17a5775d5d5aeaf7791435cff7a96eb5f3f84f5adfb3b58dffa1dae7fbd8bb14b925e652c72c78b2c49589555d7930fa2657d1b52e87ccd22d8066a7dadf58544a83aacf2f6d4536595c52277aaacbe46d738e30b1de483e6f8d7a75afd4b1aec833238c59d1a2468211fb4ac6f2307ed63bc3c89b26badb6c9827f978a3e6077bbee93297a32846db26097904cb15346245962dba61149986a51f7ddea24ca7eedda65d77b7360b069f77d4f9d47fff7adfebbfb7b1bdedfdbbafdbdd76fa5477a5fbc309f7d2d6f64e1f979a4d4ee4b29ad5e5462c07b6b4ada3eeb56cf3fcf9e7aef1c7c0fdffd61cea3df49d0b2465714bad5fa1a9a9380ba41985f6c4d5ae0ee1facb77fff3e8ce6b45ef5fe7bc6cbfb369d33c3835fe6ed8333abbfef5a91f7ebc6638c838d5f668ce9a72ff3af31a6c9d807f55fbf83beccd77f3d1539a875af46105c5c80eb675ece7a1f59afb2cf7ad76804c9d73e2f7fea8f42082188dee20781edee83e41d7e6b8cf9fb5ebd1e63f8f5fb668d31ffbc1db61ac331e664f6ad39186320d07d810a5a25450c67eeefe5ebf6aa286e213441c7eed3eddb3e1667d18c30da1694bb22d64565f69f1e80bebd19635a3bfb7d64f9933b8d6f8a689b3f05f978b2515c5a1f9c9da7ab4c979536c30b6d73a707d01ca749ed09a0df8027d074d3efa15dedbaae73281ac00610a9d99f0f8a29bf39a24b5a0f0c9c31b514a182c4a24915a95a99eeeeb7aa13deb6cfb4d0feb63006f47d2cb6c39df0429b5020daf36f4c384d452b4abdde688e2d5716684eee61cfa754fc1e5a2bfe9bbf3342446480d72c0be337763b172fd5ec486468d628d50613edaf54e93754bb5fdf6bee23d771523a49e8bc7a14a48fc3099d6d41371b87f4409498a626586c79ca573471228726487857b4ddded4448b2a89feb637352122a583566d6f6ac2836a05cddaded4444aaa88866d6f6ac244034d8c846074d745a843d4a785f6b63731b922f582bedb9b9854e1f1a0ebf6262654801b6862e22567724c121936388d56a0102387a767c226072419589cd4dce0148308a29895281b0f2ca1b1e156938312183410c5684802ab124533e5c8cc0d516070d102918c152718174f96bc70589a61e23a8292e1c20851ab869718160e432e1598b0b232d4a222899e81650215129515124b52549e340998883644a97a280aa928a58e9680558ac429493ea4a1100623de5114700b2719c83a50f9b61872d2d500e561e104d39094c59ce0e2c001aa13b30491c541831316a38549c55105e98a1981128a4307229b7d6832c3931824253866b80d20866ecc11e15308be1392d061862462f0220915c4152461e448eb2fe0924e4d919fd029a794175a4608718ace3f381d8563b8c060051716a670719297580a620917220c059722495e14a1eb76a6262e64b6332db145298a5438fff372c733fa6c7ead3773de3b6d73cef0d67f1aeddf61c098ab5437c2a46114f346eb7fca5ad91b8a3af4c0ef0335b081b36bb08ef7b899c369436366436376e3a7b5711ab31b3561a7baf6a626aca118be6cc4f0654323d43a145d7cbd6c68507761baca6265e3429021d81de46e956fd9a06a001b548d1bc4f8da5a55c87a56154dd5f0800deff6591db705f1d74d2fdbec8d39c360160443777f6b7dfc2b0c9633066f68c559533bb65655b5d3da344d5a6d4803a2a5adf7e2947b06aa327ded8ae67897c315c833bf00b2edad467d6dedbceffb400f0c73288e9ed2eada2aae52b8eb6eba3eb535a5ba2a6df5ea572ceab0afac5589d3b4d26840add5067a2027f7b29f58ab79694d11f9a6668396484929fd1adc85f3896c6ffcc239ea0de60c821d06af052b052788e44d1a74acd38e1bcf2edb786028a6ec57c7fd316cb6b5d696d6daaf09c554e82a9bcca60faea86eb974b63e822df75ea8ad69597455b5bb0d9c92a8148d5aa85ac8ccd00000200003160000200c0a88440291389003a9bef80e14000d698c34705a30974942a12087710c44310cc30006000800439021cc40e7c63a00c05c9fae68fe2eec09d90ca7bea418fd2d40ca7bab4504005c71cffad36fa51977e464eb22f419424c2d3d38f04e34298664d9abb1d4f8793146e0024afc82114fca0586ed4a70cdb96af104519545404a66004e7ca34eefc301c384b0045928828390d0894e0b4b036e2a43af8b15453edc4fc1ffb5161a64f2a9dcc7d94c8c0a01d8da2e27e719b74e5a559470158960b8c27fd9622fd38fcfd27b4f940f63a4c3790a16a53352d99bf6c42af6b4becefb7773ced66e134ae83ca5a9f67ca25c260011aee88e76b3025f9326d7a21cf7759ea5340ee32badefb1f59c6e2ba377425db1a9ecef9bd2330a55f291f6ee82401377e692ef69d1497a0ffdedd9f9d781caf6f0b63bfd243f04587bc275444ee650c3a908dace285f08fde0f78ac6bef98df1f14e206f2e68a0898bfac46e83e5f2cf187413f2dac0ee5cbee1b1f43f828afe3d03f32afa3053283191c2b6349afa65e85c5e3ac66981558bb7e9ffb51b9d21215e91f7a26838a221904a728ba1718904cf4d4bf2c17c5ded97678a7a3c218e2285738490b2309b44fa8ec610c01f27dd040fd9d7882c78ee6c1eb65aa0c47c7fc118d218034b3a29e85c8caff92b424dafa0e5f42a53917a1ec69ca6b05ef986f20c61f2d90cc4805e5c9da9d1522cf35200ac67e178b323ef33cdca54cab19fd6198e89e42605b94b32eee8d4863625092b1957a8bda4119bc5eb483a5db4c491b0e3785f245f2875cd0d54f0842f0ed32392388cb2148dd3be9d6c57541a9c01650403ffa689bdc27dc94622602408a00da19a0908e0076909e746c3913e72ac3d858361102ee9275ff41c8a593351d6d83c224eaf0b7e74233c955fe1276d2248c6e19557eca7a9aad99aaa431e872246048c3e22c88464594f1aa3c10dab1a6984c3189b5a4b6d333a133db28431f820a8d4f7356204d5adbcffb858db73676e34819012ecc515279c0be777417485b1af0f91f29c0322988d04cd46e43fd72832fc153fd0b2a7da1b84851b5a621f09b3d74df82b808814181d583d34fadd488456e5ab9f98f93037ff9aa3496bea5d2a90296b78f188d53c910455ed591f5a1b74e3ae3ae131485b1dd4097416c77e4f20c90267f9ce1973884c7a05aee79122694f3b9c546492965e95663a6d6b980681d31bb97f30e06b44251da99c4d32d7e520e374e910adc0c57faf158b79824aca3fc21729011f5f6c2dd41196539896b95f3417b022e481f59e734e13d1b082d478924910ae28f864f8bad74cdc15e3aeea0f000ee20e40482dbf8b3e98a527fbb5066e8260001394b262ce1624242f0c9b2c029631e89f1e65522e62f2ca1c11639b2340c87eba922d08a5a187301e9474dac2c0119446b8f6dc5e38f761f7ebf6050b818091d14953a8add1d8777a591ea067cb116a76d87ddcb53d6c3a3a3ca1b77af580cb2f18091b189b8dfdf28e77b41d8de71ea6e97d423f179b3cfe9b2c44df26e3fc24f133a2df5fdbc798647e716b34ceab3ed7c4825183e96884773c7085ccbaf4da04dd6a854137d61e64f7deb5a15466414322c261dff15b5bf86d7e838d8bdf7f1abf731c6c1027d44574c609d5a99fd5b406f995441dbfca3df6d23abf7872fca24aa56f3268a601f827e265dbb1ebeb13ddd7b1f0fbd9111ed2a97286ca5c4e02699d50c47c5525b4a510db215b5e157a40f24536a2b2fd7fd3c8635f5f31b81bc0ce7fe2b1e5b6f49ac36ebfc12bbef7d9537e7a4afc748afdaa82daf5f67a607cb290e490dcfa5171d224388877f64ad21c3ba123caac2c449d9ea31a57d7e0ad4e304859c275689296cc76ec240d2719913c40fd512af955e3c029ab57085e30e1b6de388cd0f46814891205ed84a83f34f8a1fffce1ab17e98f8431985aa536ee8fe9a82a04e89a53de058de6d1ef971af9ec530908b0bb7a4189e411f7c9eef192378d15369a577eedf46f7400e0bc6199fb1f7445e882bdf01a22b37e0cc41f12974804ff7695cf12e8608cf62d831dc168f511798ae79a5bdf401eda80445b9be2002370f2acf9d3f5761da380f46d8ec4f1f5a8d7d84e7d7fb5d6b2018e7a1977591d03d7b25c35242b3a348abf9d9c64f8982aa1df8d56e91949797fe91eed66c7c873289694293e7fe14fd6a9ceb936a22a4cfa42151cec35490a5369020b9012353a5061b224b06fde89d62879649c856e0ebb6db9a039aecd92a0538c861abfc0072e1ae78b41836a28b8e2e03cc37819d399419cd2f0cf22b255ea0d19d1b5a1bc0cda835040dd6109f4517c068ace45f5c88ea2e2b1d47c44eca4456985a0216a2481edc1da14fdc6bc463fe39099e3ded34ceb8f7e4a7d9e491fcb83fb1932439c84a43e1acc4827bc8cf589910acb9e3fc5280e25eb7f6db74f73c62aeb4b0e3b28d55932cff89808ca1f92793d630194e127417db59c3665702e7b346ffd44d37a17e491d2eac6fa7821df12c5e8fcdfa7eddae66ba5b6cdc2cf9860406c778117249b312ab40bc635c9722abba97492d2651cb93b925ddddef15d17101366d85cdd6b2326c93dd49b406c556baa0be9b6667551b9d27d3f7148a100ae111af8d3a1f80080ffd98b58c1e48f6d12c7ffe5adf69c4acfdf7ef09f4e9ab3424b851f2433d9cced9913c38173868e6fc11aed90ebd9b7160b314594fbf015ab938680cd9e828b00354f05ba2b61e83cec61dfa5c15a11bc06cd9464e40176026a05906a7186ac5899134e7386279cbd4db0abb3959cf66743e71b4377e9db9ff82bc6994e017a716171ffb27e84f90727e60a681f76d3905395b52889902a6be781f3bb17ad00e8be2b809c8966905365f5f607f5e2289bf9fb68e7e67b288ba4c7799beba3a32d7ec047edf7120d03c0f8eb60761c6f58c532ad6e9abed19e6aa308704fd0b67ccded4cb452078073b26e2b498f0172979c8a3bb19907c1673babc1e8c64e7a703f415316483ebc94ebd8c364674ce6d5f2710b32db866959703cb4fcb70a0cc4257cb65e22defcceaa24326f51d1df9685aaca9cb175a2c78fb93c4859bcd936ea30df2acf3a890e1c76a57fba1b72af4b31e5125ac28f33b36fab69e7c1fd62ddae3c0ef678d28a95f0fc6672d7bea727b6c5861268dc47c412b8809cd55c7112962f616fdc61401498ec81650bfa8a4e9c8bd1665811e44e5a0e4c46d0afe7c142c06dd33136dda860dfbc7179403754f58d0297d3ade8203417a95edda1e26cc002fa7d51da63c6be97cce2f3f82eb98043e46e3ef044daf07d6d925615f7f759b3aad695f6b34d662a695ed53c16b5a77cbfed325249e3aae6b0545b4afb6c9729f53456318fc5da57dad7da64a692a6555d0e8b5a56dea786de6a5bd5c4f7dacaacae53e1e2feb9dcae305fb7cf5c3549aa9ccfe2b630c89d9fd1e943c44a93b7a339bfed65544947aae662695b9af86c2f53f57450558397b474db57d4bf7abcecea9f5a797c566dd25635f3abb665565f2755f363b915cdded7b38e9ec14522a38af259d68e60fca86da6548f8caaca65517b83c8cfa410f388d4add6bb2067050e2dce1cb34aeb1c8d46df8f9276804e3b510fd118f2ad5b0cdabb816c3170eb118ff3e9b4f25bfb7106a7c4c6c1a1c5a040027876c555e0b632cba2ff78864d825a7ac1d8659c81af9534ee893c9a71e9611d2cc8884bc1b907871dfc3a0ade3c3a8257055780751f1f834e14338de51b6d70189b6bb00a9a9b89c841384112b88eb7095ec4ce0e862d68e3014092e1d96f545102147a9fc551159626b7455119c105b25de4629ae50299857084a7b845b2357c1a5dbef18022f6e3b00c091b7c8bd3432ac8690d28bad157ff4288f4110e3434bd50d91e17e2f75b0f66b4e50e59d78790f693c60846ee2813a8fa4a2019765fa609da98679a61adcd22bca844fae23561260be80e1bf502bc179fa98bf1f24cbb107e1db7581b84adf5465c12cfa306420251d58cb76c8a2e7d21a0e5fae71b10ae62db549a4314cbe13daa8ffca28a356e8331208b84e254dc98d1361050e81948628f0e2bc6b2a2619dddbc71058b9e0bc98555ec0ea11e739be82236cc0bedb9c6b447d13371005e7cced2201c467e590970e4c95e7d8f175e072d68a60f9bd70fbc4d80374f29cf963201b66680653ec46d485eec6a48ea94fb3899694a2295b63c7a2f63d549e6ca71f209ace3ca0000fc8d880338c1f6134f17548e838cbc0884b886a6c4b52ff6c3a6ab1da3645caaf07e8eeaee61b33c6ec9974570b5620644feda053bd155addee87bb0b36bcae9c817a0174479032559dddd2c3bc2aeb15a8391e1702168e1565cf4c00408e76c326a7468c26925910102cecdc07e91de58e55e415989878e10985bd4dc592ee4ca6a07e4b773ca19773341f675b0180d8c473505250b18917f10ad4d97dce1c0a322c49cd7ed0733efded126442598e3e29a4785462019e8c72dbfcea3d9c050163d04505011a630eb8fd7bb6fd9f186e247dee811be8a4d81035d51b1eb60f0d5bfe3750af257b9fb9dcd860c7e284f45b09848d764cb2fe4efede38caef95e89713991e3d85718c6310237af0b6787b2c86cf945b0b5c7d311e03e1a852e7940ae8a2aceb77a25565f079be7947e5946f2a687f904c7c7b2102d96cf9260f9a6efd4b2e4b3321bdecb52399722756418391deb8bc27ff68d74bd062aa4482ed530bc1044a0015d462d9fb30c05313e0bb2169a930fcf51038a5240ba0ce0aeab00b1d125d2800eaf4d9525020a9da0f99e138ee7e7bfd181c98166291e2c058be05be63865f4fc628951e4221ba6ac6e374ca017fc22e81fce555ad5467727e18e20af3d053eb7e9d75262b793b16a64e53f0837043c769680eb5b5f4bfd3630a16b9b1e9d639070d27b25432636e5dbadad7c2ca9596daf75d9dff269c469f4ece6e0f6f8466a143538d3ab3b0b4b0df284f9e3b71e83968e08fc9619f07c88148de67111aa1f9e6cc79605bd7cfffaad1c6bc49a492846d11603392cccf45ab4fcc86b4e611e0607832ea79e26e92133adf5ceb2c9830cc93673e47c13ae6acfe7daff95645483c4058d0eda57443230176280dae3fd404e04692a7877a1509bcae0780442b1a5d336bab18603766166569636743df4debe9d789f013e8b7e44e34bccd2c14955c948095ed4fd174127aebc85eb647333766511e3b2ff76141889966195416dbdf22579953886e6f205de687ad4d082056975c3fc70b41704e98b04a0dc87e2afd0b44b99c5d8deefb676f855b3202ea8d8fe96328bee15a199a044d2b4dc391d164973198bf9fde2c7b6fe58903d5772b8e39ed46e4219a6a39b4dd9f331c551d16ddbd4f1a67ad1e91b49fb88736f3d5b73add1c38644131198a0aa83e114ca4cc8d498d6d441facf05709602b1ecb53ae833d1a23258d30108df7fb2ac283cc323487d956616584d26c2a1faad67e76532b26b638ac3664d31012d5533e934ea31a597abdae1619035198e0b5a61532830e864bc3a40aa3102837271b847a751beab1834dcf7624d9f86edc8a2a26bcaa219ac72b605fc226e33b0a128f0df83b1be42424d1d7910d3c440b8cd89d9f9b84a64144762facccdb937b8331f521654ddf0800bc15cff67e2661ea83f4c63f7a7aa75e00dc413200484afbc10a2b3b93f2f89f2a61f82dcf48263d43743fffa3b75be007167cd9fce0034dd9d72bdeb6e0aaee509981236978f2a73737f1adebef0429a61382a8a98c528e678d4147ae0de22fee1a75f6ac5a6bedbff95228117d99f718ea0d97aa945f62319e4990ae547bc227e78f9b05653ac448ae6da8c3117b0003820783a8ed6461ad548934343a92b8c1aa2e9638ddd599f2b4b1c6b51fcb3d57604b8278698428f77505ff86857128b28f820f369aa354a0d7fac8e3635c1d99ff5e3ffeac024b757a5059e160bbb0f6a8df941ae8384c5af3af2b926f719d47881c9d1304702a550fba4b17a3b0a88fc0d44b02c3bf3505e96b8218e96a60a8d8007e374bbe1c0abdb36dba28bc0e3d7860ba3143b3cc20e61e115dea9f77b39ff4642654a66d97c9e2be6c51b7fcd75cd2640bc2a0a1ea239d79911420b76a8f9032f4b86f98d49fc974194d42d0db35b5fa0e873f07ab4c7dc6979fdfc44f3c46ec3bf265edb57607e453d8f47d1d47035f75c580c76f964b014c70e4a63b6a5d624d7e82c631e256fc7ddfeba480394ecf50422ea120c59e9dde518a08e6b43cc93555d93173a586e096be66994a913b18a7807bfe53e20eb3d937d08e2d3fcf883e52d19ad570978a5959931b59e6bc4b296de470370da85b24cce46fb12ae706c44da0da20b17e787949cfc3e068c970f2d29659038c1984f8c649e0f8546cc229b6adc8d04b4043073dd3f9e5deeb4d679332d000a70d18dc78c915fdcf98dc9631fce20a6ab3fa974bc2be84ffb65b22cafc8a50b704b05dec39d27f22c513306ac32bc5f0399ed1d44db340bf55465ecde7f3a954079abd4161811380c175aa6cc0af538f917c048469921e8714582f9378bc107cb30ef27dd7a9a72eaf3a804babf4cafeeeedbee6980a9da17c378329dd81cf43c3705b2f8de849eb5c43eece9ed13ff1516b70935c9b705afe42bf31ed703b3e21c4aecccdff06f9bb42f338fc62471b11f7f70de32dc19a5e9b533d79deb88e60d391930c0cc46edafcad0220ee80c4d487fe3542c6f73c0e2a6bd3e791223a7a7d6886b815f2a9c086d7eaaff35e4e3ece3d8b7b71d828b15a7f9a0498dda30312f9cf089272690001c059e7d237c7a9ab077ca214523366612ad9ac42eacaf7777e5e2848d6d53aeae9866effcf64670820b2b6aa7d9ee3ed5f5bd389da3753d6a1da51e579b3f270c67d9edc9c945bdd0c8969c27f5130fd100022b430a0321f7fbf6c37878f5fa687b93b62f4d13e1e83b13774db76128c70029c1bbe907168407e029dfa2f4596c11f3497491bc274692d4a41a72b79621ae1718d86cffda72b864bbd6d25b2b72f5bcd2cdff70dce0e65e69e1cd59caf4ec6ee7e9b70f3de5728952a48836fc1139ed57cab8f8063ba495396324e71f7d6f4bdf11eed4d577d286a91eca4c01a10e2d3a884cb25ee20a72bdc23eca56f9346d1278910754659cc25de978eb6555f18d8632897acc44ad47cacec94db57da064d86d0ad98f92b129f93149dbca98b5ab3be1fd75cbe2160482b0778496871fe0dadf7b742c15b3969c8535145c11319d085ee7ea9c464ddfc5c15a64733ce21faa066c4f2a5bb752e1bbbedcded995f23b80c7191d91361657a5d68a32ea3bd64289c3f403dad87ec948049c574e06446417af5c633d455285cf92bb393728ea8f7fc113645c7e26849c74ad4466dce3df5dcbd61941f129ea7b87b54908f05866b81c9b109192b1aac1e00a0e3d5cc7babf9024cba7bb53a6cf612318633fd6a638f3c8d64c674be54511675812676a5565809c8db11ccc6a45f927715ed6275cdbcccd8a77069504ea08b970c8c19ad7806f4516771fbc7a0219c72c152debe06d7ff64c4113e984c80dc31d298ce4535e845db36c9a9d6d642c0923b880cc6ca211ef0049b9c7bc35844bd39397af7c03e11ce868db71edd188a1d50253971e341ef9a14a431fcee359b384ea612d2564856cb6152e58ee9ea19b6a9b02fd9016de3b306e34404a827549493c3427c291007e7a0c71c82f2ca37717384bfd49c89781b5e70e1a09ba4d5a6ad0b76efa0434d9dc48831b6f90bc5a0316d280e2816f325870a9c2301b84ba2e1ff961843b8f9e7ff571a5a55f51837f555635f05b288296bf16e7d94d5e0e89743030d82606fa4accce391ce90797d129e188b090af6f786d374d9dd41645cdb84208902a7b0a403da09b218179527ec2d1d7b7011433e5cab1d7b493e43f53f14b54304d32ddbec48345e27b2a71bebd4e07206ceb6d0597329e646ad29026d3e3dacaa03ec34b6523bb9c7c4d7faff0b4c7e52d09782aff6c966c2c0d2368125245939a24c4c69155e922edbff10e69a9dec9333e25b0e0e6f52ea5416b0004dcc6fe7694b3694240a07488c81f117fd27bf3842f83db2b40693439d5a349f85f68a31e5b518ad27fd4f2b9521a00fea4ab71042ad6fdd40e6bbc8b9a2da0b4c5795b45c828ed4ef4a3ee4a0395fea7d39246279ed2866b2c09866b44d929bd883a8c0cb32a4dda36dcb0f875bb4c0a2751072883a3709a4b43a7e450690f231da571c0371738ecdbcc864e372a1a3054f441f5228a34ebc97bf4b4ae256f997365eadfa6401db437646661c768a783772101881dee1e4ecd49ef1857248f157f73103d46a3cde741f74c7a512525eef969be483dd14120b16a8b5e99adcb2b35f682f937d3765d1f495c822014b495482d7cb64947aa1b9439119c9d908f06cc500f82595d6b31ddae02a5e812c54f3cad946ca94de3d8ed498cef15232321480f460e7dce4e4387d1112a0989b039d2790a2d509aaabe5076044831d2b303ad3c7a21cef0c3d090d330add88f7d7e0807b6a7474efc6489bbd3a2215289256d893c9858c9898202195e20fba6291db5ca3463e21137b343d7ab2e120437306cababf4e1f80d89558f19ecac8e39d9c7ec60966d7956517091e48eb4894d092f2233540678ace202c5c896316f54e848838705da9a7570e85882f1b384393ecb1fe1d78f616a9fd399cd283c02ff5135da1c29676e2855fcee32966daf1bf2cbc1e68dd468ce65749d9cb740c8a3ed648263f0a98ac1d69afef1c66217ad2232f91df036ab1d811897af1c1714c66a22873b9c0cb47067572ade0ebbeb575014ec89eec063e42939fe0136452cf33caa6a0084671c5128d851b3fba9d135dfa9f12adfef89c28a2815ff506e0f156d13914ede5fcf6f3842acb4bc95a9e516588edf01af08d8cefb1117c843a9e69e3bfdd8d4fd36c7eb0242232fc4abafacb2312b7a1efe832b2ac5f16fe11564b8b16cf8bafb01847a93bca4eb9f53b1358ad94088c505ed2bd88d759f783162bb59b220f4fc61616f641f635bf4c09e687f6dd5506fc5d5e5532cda1bf4c8e7338c8b90cdb010e2bec7926d472bad713e7b7a13c9c6cb5dcfcbbe331c0a389c9feda7431c5f2f88b3b88b65d95458a6e4954a87a0998918414e8dd8430ea0282286fa017dcd343df1a1f3cf3fe3237b76e122ea163e5ed43f9f2b1358b7d4df8463ce4a8f77610593e35dcb599e589e801224ed1a584614523d14e66c3fceb906307b2f3e5d79af2e8a8c10c025b01020b46dfcc0ef31b2de4537ed822ff806e994cd8655f9fd56c586d5a0058f281a42dfc73e627302d5b54cd7a79d9b3c1105cab772b7b13738d44c1dc6b73587c0e1580b8e522ed68dfa65f0979ac86d5c27703247a03028e41e0b7a1325d2ac6e045909faec6c79bd6e6ec895b30eec94a7642c89b543e23efb6d6b32080b511c44bb7360ee23a0356e4d3193b5ad073555d5423b2c6410f5d7151cff55b833c46003dbc06f2a13a8f796c8bd4b2fd1b3520c03bff1b89f2118b13e59072c96e9f678926026a8468885b86669b86fd7ef28a6971c5306acc8564321092298f8258cb8c03c45d5c55e65da669a58e76920f3026e2d5dab0230276a5262412756f23f532300e8a1cbced2028be84fd76c96f607dd7138ee34cc0155540292ffad24c782768400a27d9e3425b98b5ef928e729a0ca671d1f3e81bd45cb288839245d6a65a2da652df68ce4e274b6b4c1a561af265310f0e6560d90015b44ea429f876774773b564aa06a832baf836a6864899b2940462ffffea8aeae65167941b0e3070fb9f84816ad976eef43a60d340999e3e396d3bef011436612987e605b52f20b930a4724f2016f8a8f01d108d752ceca680bfc5c5c087a3c280bf726b731fc94db76d6431dddb97d76bb04c2b7da222577e90a763752adc146e9096a03d962ea68972abb024c10daad602598cce873d3c9b231f300c332497968c3909a6b89292590feb8936fede9a2be06f832cd5ddbd14181bd04d2d5536d28f9d1666c0c506f83338003545f22a01012d554f2d56812a8505fd19f7e5e2b9d1e6302b188129dfc886e572719148ac520aa2996395f914c379fa145ba224a900cecf494e23b4b240a319e9191908205546672bd0d88dcd2a2174f60a6e5354a73e600f2cbe9259a84861e09f706f23c04dbc972e88ddeac7c830cf86ad66b38e307c5f1beb6913dc51bf82b8e5199bf572264f11ce48b3846ec17f1d438be9ef2261d43412250e9ef540a5defc3ef7198eda74b7a7461dd785cb98e90f492ce4b50744101e8b0709720925b8bcc256092fe68b22eed2f31f880a0a8fe715c38112788a045ec89bd6fcbe33d1f50cdf6a1cf7c3efc582bdd4281d781a74f8b47cec551f19185f6d70990705f1280a685ce20db4ede6d9e8fb838872f6914d0637158940c0420e0d16feefffd59835ed468fc39da6b76d1ce13db53e3f28f2bc8dfc603398cf8143478b2eaca89ac16c842e869af85a030a2d98f8de041025e5fbb26d80290c2fe04a6cecca55faddb75abc08c0fd4ac07ff4967f2236abc433b6712a0ece36518e075591cc37b7673b32b556737d01a5b907523529365cb39ec8d231dad2bac8241aa1d392a8b3ac461b4e28c180bc337925e863077809c9ac507e75778dd0e251d4b62ece61e62139c96245dfde907e72dd7c156df1c94d803a77b90169c919005228a42c6b6268ea53df791a5a9b2ed05777f4eb37318838336784834b617b608b43a3dbc720bf8e151bf6ed4b0580c08159005ed9dce9b0061f774c4d821d3eb955e46cb684f4fe387bd95ac6929bf277f9dccfed1be173de9592016b5171f15019da6923ce6e899dd0c3b9801cfbde7b9e8967e8e29f9b6eaa2b6fbc525a53abe87b9d138949acccc2017c9e9df65c0a6296672677f3b7923bc221cf316b70cdf87bb735dde3383342178ce64fa3ae64b3477c339420ad0168c55edd007e68d10e887a3a41274d4f64af1c87df8549523a9107363dffe410a00b87cd8ea044aa742578832447bd915ba4037ee24b4da4e65a4c027d53f24531d9764d36b6978237eda9e51bc28ba75b995c5d52e298bc30974184df39cf22208a8383d3e238f35d87e579f4148a6b5d1537d793d3a9b112ba9227ccddc8ab0827471bd880af59d20f127237a7e420c89e27813e8fa988dcf61145df12c94ed2c5e97840fd1a3923d1e286618471cf82e3b15325d8e7e7b6231efbd0e300a929b4fc93e0352e0d360df27c362ee1cea28b77505c257d777dda1d1f02b71f868f523d96b2452cdde21a5793141ba400b053a1afe0db98c576e8ca9ad65bdb5cd8fdc84beb8bd90c41fc0276304367b036f099a1be4a962134ca9b48fc1ebb028bad4c63878048ff482d3dc95baeae3441665a419c43cf9f2fa994a2b01fe0a90c529ead926a83ed074599875237cfb04363135a539e1261e0b2ec5930baee63e8d5ab730a04d4d2a82e410db89507260d227f7769e396fd204afb4dd7530ae8c54a4e7ed78b167bc051a40ecd85b01e4f0034878927f6131a79cd73c6f7d4ee92e060de3484de0a6fe4e4262af80712f567a58c4058c09c38031e5b0e132efe0c7e5a5b68f16443751dc134d0700276eade613407f21156ccd4670d5b83cd7a1b9009d33e05b2036fc7fa44cd5599f0971c45d72e65a424c2f6b2b84c62dbdc689593b3b680fc2044aa0ab4f03b0a3e09c28114c9638929daf248d89180d51cb59d28b1fae86d59648529989c13bdbfeb1d83e050b1967243597881e1a4e54b16bfb1918b4d6a0c0025ecae036c0f31a4e0b55b87c97e25a45db8e2a6debb54f987383583adeeba6167c0e3af1d01d662d3e349751f05a8fe351e28d4f37bf0a56f882c71018ccc01c8e6f059451937286d43871281e65196925ce39eb00e1cefbb80503928a44921883401bb08e91eceb9e7b80aad06926536b44cc14acdf67ce15a4f83273b3bff23380a26a699626e5252afc33b70ddf85180fb980972862aa4c02acf3c1d9a2536baeb3a6b3344047ffee982f895a9b93791dc6ac0b88f957e48ca880f9911b2f6d870a4f07a13e37d99b774ed59241e30eee656fb8e5aa21645d7d82c3cae04a66cdc73381e8d9fa52d7c6e68180ee89b3813c2965edb23227c7dd6336c5ad4ae811eedb0bf14ceb8bdbd41787ec00a824f3b7d86ce9b38a2bb8fd364eb175d12f6ac2a5640749cae40de910f27da199673d5e83ff140037f2d82591ed04ddfdf0db78174216ecdc8d3beea8cadeca650a31ffb7a8120fd20ef337aac9b00ae04656bd0632d71b33805ce2dfb5c3ae3a95d6f09bbc459263f7ff2b295aba3393d5e07c259966caaad6a4a734316cede8fc475963d232ea247e65b32a6aaf32e49b1e20ace67a986be6de43841017b8e90e15be551021fb032956914cec09a849350dfd1cdd4c2abe8d08921473cda3dcbf9db85dd33037aa468a58e44559721ab0cc5e20b271fd254e03166a161b14e0977695506c87b320aa16a2422f0d4203ccb437d1b5fdc97db79bd8b80be01bbb6ef8d7f92f0f109f2f61b6a83f473fa98afb7882b2a7a45b490f759f755bd260103ff6b8ac729f5e7ccfe8420e37f370b392a92ce132c0a255e389068be67396e4886f3c03e7695807783b77350cf6bf6168292ec3b75cb43384b96b716d5b1099cd767624dec7a0fb231ece6d04d8ea06304aebe1e7a10a30a215b8fdeac98dcf67662d883e2743e3a56d32b020092ea6a0244ea2b704f062bc34e259d1546d78b22b48c9e6e028ad1a5142ccbb829561de55466e5ba4b3b2a0ca025c346ac82af8f5379e4caefa928e8dc9ce7cffb5ceb0a0102dabbc2bd0c01d974a6c1f873e8163ff9a40d8e482c32a448102bbc4bbdef320921052a7f66e351f2132440219c877eb785ae8a50048b8de6611bc631694fac751578614fc8fb81393bfc3aab34f59d9876f430e879041ca2755f0b004e8e362d58a14e65b3ef4cae0c1615d5317aa99634a818eb50b82303c489b67f681133a790f3d1331babb2c706d2f0bec6dcad5c39c1e4387e93eed0eb915a852bb3d218bce32aa62cead41ecbc383c60744ba25684148384620d9e548f33cd99ad200cd93004c0dd988c6812732b73a470c66f44c39182404d5f761632a21512a8588642cd8318fbce108a898b0b530bc68f77c01e9ca09453caed7f3cd0bf61a93132e72f4f42a7f1872abfc921fb66ae37cd63c1ddee038316f106b012be5aa53bee645df8cd981d22abc141c8042c89c1ba959bc7fda8ae514d555ec58632913bee3baedcbae500ae352b47bc15ff03390e00e1e0e463a25c5eadcc0b2d05be2c73595dbcb39cd883c6b4ad0341cb184747ea81ac8b93519d41a055d43e03558900a378b217c096f3b4f724ac8668ede2142a4d8e2f75e86e8d4e1f5c29a3f38a065a1cd299d33c4a1be48e100fb380069b9875658a14d020d182bc9bbc5fa16b90ce1b6dc30cadcd1c68f11df688f2621818714634e0eb60fd1b552275630e627452305c39ec93f68f63d01b1ba80a0261ba2d0005b09846905b197383e0ca16d6468592ad3bffce823b4f0826842a88f33ec90adc3451ca7e5fa2030758abddf5d363e2182a892ab8f00e6fb5d6a83f96ff89a24552de7fe908289cdd16aa686472762ae2226a31b430ab855f355b6961772b21ad25b7d29763b3eb6f8f587ca28df4652b07e16ec165ffa94408fb454372033b84aabe62717da1d268808e7f179d9077051364a7c6a37489a6b9e5317342baee1cf3ae14ef4328b656b5f6c610d989bf72ceb97b439ea13a8d9197ec64024cbc0ad456c4c957b829c34ab7fa6ed2655b1848f7397f6ceea55d6173eabfc7abdd6ea0b64a6c2f745cb76ae037c62d0ff78822720e6e52f548c9d21d3312576952cd17cada685b90eb55c7afc0deec6a3536adcde91a1f3d90a150f8c2f82dd40b6b59901bcf1c4228541a45ca8c2f77a3bf186685ef6f565dc13e5341aab50590f5e5a5f783c5ca618dc77c6a3dd7379c2fd3a61bb89bfb19cb8c47f2422ea213475cebe964861166b1e7985f9e43c07480c65ebf7db81b3c2a163982d1037d96777ae17b8cabfeb69f4f7e68349e2d87d0e7a6ddbe87b9d9eceda07fd5aabe3a08f030291bbd7f7098eefa61859002344a178edf16ea475606f107280483208d2c51b3b1a20dec03e4c87b36eabd80fde487269381bc7c2c20a046481e267c5f472a353ee3cddea4b0c955129f7d11e8c54b43fdc84ecbc48b956f7715bd7c3614c5ea63af1f4a9f73904bb16e99659952326e05759b57d1601a2622f7d09d8bdadcbd33026ab8b043659a7ac7b7f690ad87341b5b08386825402153460f231de9c8d175f5d1967ff684f0bf3d6258e88aad351c03b09046ae75b43d60346299ba80f43d0abec94f1b7c7b1f1df5ff3ad02e173c404173cd77c2f0cc46d166a2eb8d4b05011dee2f1a558ce466066905f7c64d7a90560b2003a33927e4dd444dd6baea7372a87bb513ff962782024397774269c0e8f58d4bb3288df68377e6348d428ef53e6fd7a4fc9c3445bc39edf86d24bb2124bb18405ece731c0fa3166ba5557a627350ac062b419d328b900857f795cbb674205d36a813c6f928513dca044e1e708e2295db08c44fd59d40972a7c22ca7b24a097bad055b4ae0cae54516821af60a9fe1910998bd3a543f0f3ea49261813172923ecf2534df50ad41ec8d51864971efb8f9ac96084b470f5b6ff467429b8e96fc009f8778e481f5abdf28e1fd8441fe51be17dfe53af80a33b6ed1a71446f0332db884a2bdc3589695ee4a02b6a1cd37edeb59e49f5e36f513ea6517ffb30938bffb34de828d9401c968b9c3d45f88f14a92c67c40d4e2bd190752ab7295b16affc87e087b26007d92e1c2a1851f9183bf9dda53c626264b00916cd00ba2d9091097d9a66f1211a86e6c87e34747a5972cd79c66e2ac1bcea95894fab5190f131d2a03e8d5aa1c6e64dbfac84bb6c0099f976cc9abc72d98cf5a8a7c41be9570cc7e57e1c283137cfabf19b48cac70929cc130ec883429fff8cac82460dff10bb00b6293556237ce8e7625efad150b4ac50cde2fb33d9d8f8156be0e1c5fa45eec81d9916a15565959954dfa9a00fffc5195928a4c3e418a176f556d69d5e220afde0a1d3d458f131f393f5274bbd6645626dea51a932f0fa1de52b85f00e416454da9438e399f4ef6bec6c3dc7d26458167d2ac1cbf26ed52dbea56c8ccc4363a68b9f2448932f911bd67f9618de487f90a237557d15a25464cb26edc28ee0f99bab36d87f1c3fb539b033d4f969796eb5d50d037138366b2b723dfac2f08a506c5ca134adc0034b23bf446689159558752ea1849ad157ee626d59bd6c798647266d45f6f0b15999b80620d9a3b8692b2d15a2a986a5d6eb37443cba2f2eff19102ed3c32a9b3f2449b2a016570cad62f270d04861809d216d488bc660d83665f7f0bcac95a4f09287a31786af4caa746650fdae9524b65dc63394f54f364d43f509a4636213890c082623daaff17730dfd36bf12f7a99e3be02d7bd30ba1b7cf05ddb70d517bef9d9e3985b706911c571266d971d9bd31f478a2fd83feb1e14f2bf48084a133f4bc404b9c8bfff24fa405c857482e5f2e36f8b9e4b1150edc2f772392cfe3f386bbfedf803f1a31bf65765d89a1e15993b2cf56527f25f3a81fd6b474106a1fde938603fe592df79b835b67225c093b203fab507a5996a53fe1a015799d209e77a967b300aa534641c3c049b4e5c8ee483c5f6893065c9188c0235de14dbc1b89902f38f72808ca52e17c85370015c149745793a058863bacf14619df43dbcefa407831fdf21216ab3946853b559f83563324a4452657e8a7865b985442dd6c972bd2f99b226db820cd18373488a9a7f24e374c216c41f9295b0f707d1e65e255cdb0e9bd45ac2553e822f49fb50052b52f6e7ebba45adeb34ce38b546d56825930155b14d72ac5d3696e0adc7eb4b9bc2ab278231956ee6dacf2becc09a77859c3011c9b4a5719290abd1d7434ce37a3e4cf627d616f19ae5bb466ecdb02097b450ede4b38bd2bcd5deed6764a51753f36b3939cd2605a40d12b85ab289bd2643173459c01eae6f46bbfb4972045211d582227a23932484419179053b1056eb02706129d18907b1bfd6d5fd15ca7577aed77d7a019ea16344d2d50dd0f2b5e51e03b994898df1108344c9afb6c59065ff33bd761f2fecfefe0fb2c7ce37914a782299ec50aa91be0388896ab0ff08535fe1f9c7838aab2ea5215f50ae0b74cf004b2778b7932ab137c232e1eb4c30ce3a173b1fb90c6d0da71e614802e79f949b6f941f2addfc02cbefec932140c9e34e4c4a059a7fd008a911c5af3c4dc3eaf400172f0d9f022635b9fa5e184561a742f73727222284416592d65c905183cdf07cf0c9890e8dfa952a02cae307a25dc4944d5d6215ae43f4cd6d8ffcf2877829a58496eeb3de047aeb20bbe444686fdb47be2176313fcf7d47740d3dfe463faaedc01a783c232cfd11f11836bd1358c8af08ed3251eb4c070bd21469d0e5fa584ea69ed94f92789566d09d56817251699c9e7ac4ab5274585eda22a39a384ab285bb36ff8e64bd3d9abdecd8b353f69ffd20f3366353d33e3d28b9b7413a608b43394afae3c7b6eaae773906fb285df33132bb1a64cc991bd0705dc3e76c8fdcad78d7ddde0d96d0a27084c914b71aace7ef58869b8dd1ce47440ebdf4d15a6a9e0f64cb7c0c9fc6223fc9ca7c2f01dad07c75eae0e942aec78e7189f9c4390be54c123ec91ff0e81309014ccf0367bd0192e2a8563a324e2fac01c8057a676942144cddad4a54180623034fb771fadc3075ea8190a4a9e094e96a794e0e06c419cf326d66bfaed6698bb52c014e3752b4811a652907d1b8e416d2ed3d4c5a1e781f9dbc30ae31948567d826e400f8add09595994ebd13cee926b8dadaeda306178bad4fe4cb128377aeedd766d4151439fe16345f2c2ffce350dab48e59ea854916723081e4a7ec50e15a684591ccff91a2a7f5468271c20815abfa4ae21e74989ac57fe1a24d3d53222f40d384d90632888b008662903eb0e43b590a83082c24e81c6d6dba2cfb06d5322b0f2c5be8a9816cf4dd2c388176a04f52fcfa2597d1c4892ec75a66b66cb779adf6dcc63f95e37618079ed0b409c89ecfe27bf7b7cecafc58b81c3f52ae9f6ac65801be66b961f08c2ff9e06ae543163a3ede2089c1242fd77abce5a80f8f25ca53bbe32adbeb1fa7708d93d9cb546d64b9b17dba4d2369212aa672a25a03e6a58a7e25dfe1d24ae12e935d37dc1d0783556a5f577b3f2a96df2f7e4253d873eb67a63d7871a08173516165d4e2a1629c887a096d04a31a23ab7c2e64c88eb58e057f9f288bc01c7f5f27052a7bc8862fc61b4c400dbbbf9ce7ed173faebd05626bbf0fad1a0a7262a1fab65b66d6dcf8436eae896e821b1d250905b02bf081557b341395d158d128c7628d28650e6775831aa0b483d33453444143e71624977fd09093846739880bbc11c6edeb82a5520db762f7f3fea8f50c1824e2f62880a91d02237e894b8fac953138cf162511b3659f6b7a63ce7f3a0e32e336b0e00addcd1d7ac998a4535ecdf09123336455fa4b506aa970a7bcd76e3202e1c8d2abf9b404bf3a2dce36562a680674f54e3f1deea982c1bff9b985f993870cb3537dab515ba7d449e3d14845333d657dbe9e2ce1f0800ea61c365e7d14cac5926d20ab49e7f2603928080b028d8db50ac137800484805e349a14fd75fde8654af5b1e77ff61eddd758006335604b140805b2d1fa4b8aa3038dc3759e070f9909bd546732ad4257f64a96b1d11de08dd7ace4c7dae2558b3502d69f43ab75ba87c4cedaa71794ea805da0ac77eee6081d28f4dad1681f941d2fcbbaad4f85cf9acca0db3835729bac2e49b12a46a391f87eb12f8168f674edff1dd7bbb171ce100d31f897c43faf45ef42db12e485dfea49b0ca47158dc7a1fefd5adece36a28169e2b99096263ad302a7888c25e67bb695035c3304a31437c72d6687c71671f4937a3ac9b11b3b85b348298a3498c84491b0606bdacf1afc9339373006bb36e8efb4ea3bf53491f4df67e5092564bb6e42a044bd2470ee4695c05bbbc10a76e91cc89004263b25bed8ba2990562e63971f158d51fbf3434fe6cadf8e01cd38ccb2febe0322d4010223dd0817f1f6b12ecbceaa9804848b1795eed604d5c216c25fbffd4e97ecc1aae93892eefa33bd62deaed805c777904acb18351c41c1d60baafb541b454668a05bdf21b1eb5d41b9dd2f6f6fd5ef4d5266eeaf2867621fe91d7b0276c4db0784e7b3a1c1aced8bfc496412f0b7a78899332a84c95037ef643b63038c82d122e6e8458ff268ce03d9457da938124d3250b74e28a3318e19652668c6682dc5414cd0ab3114ef5554d3b7bbf6110a554f691d10bca0f502c2968eeae8b3d22a08b4fa0e984c3a2d41ff1f6fc15f8a8e2a25ec0e4c9a341d4aae5d6e0c6276876cb4fa1ee4ca02014fb97785804c5e815d7efc1acdb1e40471d734a1d07df6da55c9ce5d56b4ddaee573a16e6d62d47e3b2c1a51112f55f413713f31aa44468556c29b6c11812f63850575f387b883766446cdce55786c78197291aac637b19852633d0f2f7237b7d88c8fe5e318ebbf39f73fbf138f79f1ba5a70c740bfcc8b7d50ae2cd10c14211bdc6a4294829f214baeace35029b95b1c704648b2e1223fca730a81a3343c0c825e8f55b7b04b16e194bfaf1f1599affbc1de70216fe0f1101b723d0193f874cbea86dc2ab90246b540b2833372ddb7ae2cd0b950c701e067356e584fc918480f037c1a4828e85e6abf9566b012c006ee15069ff6f361e130a878da86e2aaed3fa5c1c4aba6684ee5d513ce9d4ea530aa0affa6424176b977037057144c79277647d34847e7d07eccfd4f61872e3c20016d08e46bc6e105c2d15d099a909b4b0eb257484e9b86127a21dbb5eab4bac8544f60ef62ec3883396cc4967e9749a045e1d75bb9a16259ba9cb3724b46477ddec1bbb430bc8cbb68afd7dbb7551c54bc77a726f3269fa8a4d6f9efa822eccdb47403d1ecd09c92a5b3922e86495cea03443285e8c852342807c86a75e819882ea2fd2fec85e1ae04351a7c495f1779d7dc2a4123da9a2e25a0ce600edccdcc280dbbd8d3169b7e2a24652023912b84da0545bcab4c1cd90235f0fd173e4e3649e4077653372c3de7557c3036712cf736136bf76cd53e962ae4d58fba71a38e404761c0f4526903adfbbdd9ed49f66902149f2ccea75d7004c9d7b0368fc626d0c618a18e3901481831fbdeed2b05a2fe324fe3a144acabf143411522f8f6e18b9bcf8e5bb40930b9d337479326a5fb4bcbf7f36f75b6f7c1c4676beb38d47a31992b4c33286b8e33cc43c7ae5ca6694894b6f3da2c26870928bd8bc06a18c7c9b8539157dfd75d3c825455e6ce91c6666e957f8214675b08521842b85a7a1c20cea6ad2272bd24a624565264f03be1e933ce411c1ed39a8c43b5be832eca7e4c4e60bf67bf70b354c3efb386c36b75f4fea31e604ca8bf7e06ed16ac9f62d851427848396e75d737372738b3c65786e9f4865d0e845b26996a8d3482c4ca68f3fea33fc628ed60f0f266cf5b1b8dbec690cc9b4821601fa3c7888db8219ebfba312043c2f29648d0af08da21bd36d8cc2d5821d5db288ea6e2cdae52f9c0fb9819b60b77d10b0017b26ce4e1953b10c66d53f550aa9ed190c8499e1497823b35b6d2aebc19081f8f27e0f7c6598818c9c150960e2c38b1befcdb7d6703bdf0d0ce1a808d55ea680f5f73d8e916023440431884802ccc7084a8ea66cca10075f759d3e5e381bdef9ff59d16a05d2429c4892d158cf9610d97dd15a088e597bb4bc45a582172837163dec0ea540f6df76c74356e1c39d47f850031471e25b1462bfa2692c0d646ef25d8a905129d314953afb16906191829e688f4a00e77961afaf0fe57c6f60501734ecb67bc185058ac831806098c12c34994127f4ac0222542943d4fc412aec104897198478664540c3a2be7b366cf6755221ce4bb068f16f0e01198f340f2cbbc28f7c576d2ea81314f6aaa732c9be9ff77a6391e2ca35b98c3dbf6046fc03aa323f4ece904131e22a1e551bf85e0a3388aeffdfb92d5b177d67742a534346e2b42c85daa45be3d23e4aa78a0455376ab0ab22783a5ada30c67e220edb2b7902714bf7e3dea0ef2b3fe3e2e8e4c906bec5698eefc3ec3c96ecf0c3774bc7177cd645a0c8c91bfa8683c9953e708647a82561d599bad6e79d5fdb673dad1af2ecfd8588a2d41216732a30af2181cdb3aee0c42b8d2239aeabfced25264adfe40e083ea70f18b748fa9bbdcedc03e1d0d9a6a29f640ca5b0f43c3af4837cee5bbabe31ff15c12fd77ea6f73d0e29675e199c43ec12fe8a281c9af84c06b96c526c04694f774031f102e60824669d104c43cc73627b32b90bab77a86c37c153887a4f02d412a82e704a6cf2a5ce5047425d720f8fe505b70c3e3827ef507eddce3f6260b26169af0c34a9bdcc2d08a789606d727b5ca792a29d9fd185e22eba5a6b4ad114980468f048d72764d5b0bc30753cad5bd3b65d19b9667282d3d5a54125f8b72d8733d759edac8e5b3878dff613829fb387f9a1cae9a7383ef33af04f9729c13bf59ff6962dbb4ef1d8885deecb08480a03f292a9667ec34b4b9359a8ef079b5dd937d948ce72780e0261c42b321d6e28b02bfe1a11b53fbe942cd2be607b7fca9b45f59f32cac236335fcb0691e633d745315edb50b0d60d2e1c57c2922ae2da21581a920e26d32594a96af466ff10e12e4c54411d94bb0a1a796a2144a1ac44ddecc926bc23a54aa12537041425bc42f5997c8ccb5e7e8f3ced68bf4d93a55e37d94c1f8e1519cb186a6bdf4f5a11515b8dfecbea5f5645d5f965d943280722bb4fb43b44d80388b20d24e8c30eca10cea030197a8a08f427e3930fd9e133a64f4f028b39498046d332a388da9dec4945902f451a3b62911330ee3e48631a977eaab62c19cb62c45e8db51f41fdc63c2ddc993eb4aab5eb000e3e14b4e0f62a3851d927b4d3c8fba0b4bb5eea9ac3e3774251d8a27e40929d4584436f629af3cc1ebd969e67c7a2ad97b47d209e22056d8b50696a5977b4577a3282a21103afb7a11e6a0570602aa88f8be685aae5743e900ff935fd8e1c124d40578a4f2919ff33af9184fe91c0b12d3352c4e961ef438308f8a3085793310a4a32e56d92e508eac8413644de29381915e5795edd24117103699b05d30010e8400f509c19d961760f7101822babff2b7165bf58f4f50ccde370f7002d8b729f7f4d04e0026bba6da3d99b3e2d457ba2fbb1e8b8be2919df10ae21bc3e0939876206ed43a433407fccefb1c24c175b3d242e879365c73e7473dcd0f73d3f33d168f22403bee234ffd3cb5a4a58a86df82d2104f568bb7ce48b62b0a8dc72c41e7e386ed3fd1e9c7bf17452920e4d9450be31c48b23ca39d3d1eebcef85f9665131f744160133fd95f7713e6adad5362931715c6628d0b3f5adab3c993219fc5e53f717eef55de01d499292ebd7ee3e232683a0fffd1f5cefd455b561fda31de7eb9516a74e2d205866183a7859fb017bc0a3f7075cd3a3d1ecf4e0692c3b08c42066bacb53b92360a503582d3962d137b0443eccf7baabaedccb5c1d297fa5228520b3f1735813854cc40582999c34835b51b4ac8591420bdc5bd5fd68c4fbc07fbe9bd6ebdf072cfdb74419ed7ee2e9b80ee5a8e7eb28ed7e4566de7753fed365e67d95c29d7499f15e8502ffc3873fff803bad9b7b57dd5e2f7734e912a54a928cfd29abb5885aa2cc72b78fe2afcbd9f75386b150fc98ce8f70de5166be2b052077d5b5a3db307f0a8e54dda003537bb101063b57a36a9cd23085c338a16f24162f79ca6d0a0354b684c5abf9fdc852d9273ea863c2ca902b0cdb0a3ecfd8d1d10dd3baa924cb49f1fe39f1794ec03c3905570711bb7c6c5e151b0ee2c12892d4280b78fcdbb41a02364902d8096100fcc32114e953085804fa03383fe96a2dbc64410c2aeb3e91eedc54fab9c9e892bd39fd0d8d9a3c78eb2a7a0d6ebb36b3ea697c56e2f6c2490e6171dc64851123343340b35ec120fde5cae1fae3a6a0c0fab55c3c57ffc26ba8bc1af5d0dc60a66af06a71cc238d9644a16d1f417074f9fb8371c265f29ceda1a56a801cf2902124a0861437ca90c61d09246993c8a0ff60e9009652bdcd090644b03a2639948ce40e42b4dd1115f11c4b850d0da2f7b21c1464ca4c55dbf6a450fe712cb292ab15796e83301f41e59dbc6c62352f07b381a52c03f1bfd4c28e14fbde78ee5250842627464cc1cb1eae6a4f69828b720cae2bc382f69e9ea05868bf94293b16421c7504ac2686e7142635abd4c0a187d209575a8b27e182b627e857243db3e016315972a896231231c6f3de011c96be9c307c39a0387bc899d111f06aec9970c42a4bf054938ca79e103913c616dcd51568f3940cfd406c0e0e9812b46946fd537a3307347da1e4024a2465f8936befe9fe853c986b6bfb492f6f4aa2fc6a2910b86f411296b842e3fa3422c367a715cee126690ed86d3653142f181d03affb808659a5e7331385c27513ca38b37d98dbd27d18a05c91365d8d06a83119422044d6a6fdbd8cc275d63f8cf873051e3ae81c0d468f2472293680d63b27f6e2b982507ef9f0b679aaad0da59f485c71219a9bb3dbbd616f3dd49a45cd6e855420505296570b7322bb3b7857a93e1cd4bd689fd6a2d34d3f2f6d0e763ad195c2eb9ce08081b14b9e3633972ddd2e76f85861bb8d240835ddfde4c6957bff7370bad72f11723bd39941cf253c14907712d71ddfb1a3fe897a517e17e774e963c1c99789094a4299c0189b77117310343d4369dfe7801a4f3397a436cc64029474186c57c822d217c547cbcb4f6837a128bb8a3f7139aa5d179d5520a9776cf1ab93ac89d4453cbaa76c74998883ba8c51b47e7db9b69190ef4219cfc7deaa46c51f8856be25d38435d31b90464e858b7e03351b1f02217dc5e06a18c23c3a4aae45ebd829de62b26fdc2125943fcea4d30ff927b959a31901c704039d03af87a3efeff821fc384c165d630c63511a29f2373918d23910f856b0c7f2e634a23ac3895fc6a12562244638df7c62d4a240b7e625e5647bd1d64fff9952bbfe12611c84a85ebe1705c6db0730a8e549c1a29e0e6a79e950dd10caacbfeff416356ce45a0a0b55c0fcef68c6b5ee059a9a422b172173404a1a4c4345d71759529c5c980458254bbd34a4c7520a6ebdb2c9a5517d57180535180982c7da97000a942f10d61e29eb932ec3937a5fa1fe7363aaffcef84da34e0078494020c3e4c12c78c832fcf0c506144751c1aa540ac1d9079f33c9c6fa37d887e476c354718d884065cccc22c8a2217c5e083bd9c647249473a8ce212b128b86841e0424c9fe8482c0c0fad8ac30614576fdb051ebf19e2ad34dc509487003bcbcee2ff76dd280317ea22eb7c40a65a4910164de1e480564b735d17e21fa5e205b0986fb401e0e037be5de8c69ba4fe4e1feb2444ad0a2dab532058b31afb81a07f5bd6b4297e14231488cf70f3de005654a684004af016c14b398419617078e6a0415ec4c05a341e0022422fc63340655fbcf3d7fd201e5dbf8f1eca3fd409d14dc14eeaf1a97d88f1b0a34c3d82e41942b9772857f99994cdaa9392c1fd1a0688761b245af16dc0b0acd01d7105f940a70b7218b8b1b67d8bfd1ec7d2f50852dbac97f4832d817a4817255f6308c98616db92b105091a3b9fc2d9a0161a8ec9d50a8970b10dd6b0eb92701888f050cf0777db483963bf118bdd4f8f00c911e0fb967ffcee4b175304a65e7f31f1f8cc82e624324ecd04851bddfc0181b7722a9a29e2ee90c0c596b88eb4d50cde915e0edb40fecd2d6adbec87de566456f5a98e2333eb8e9d7e0b10dee51ea3a6fd285138d716bb262eb736479bbb8b1b65b812a60ac3310ec8a9d88ba5181bef810cc7e91c018059828699da3d7f7874d3e5af478e8bf198676722afd81c8120faf17740af0902576097c2cd280110f28014e76e7450be899835d123a34a941055f32c81d3b4cda3e0bc14b3475331d21128799ffe9fe582747031b78d00cba657af26915dc8bfec97829f19a08fd224fcc59d5f670848be7073a6676896ee307c6135153f42e159b8e64a34c2f343264aeb46be102d632ce17e262c0a2b6f8f5b2264c5f685fc235a879f98076fa3cf259b286796e507c0a85881199b9acaee8224b4c2de04a229200224a2841561ddf13d35e8b4dd43b8622068815502274b00d579db863f3f809f27d6693191b70a11e4479caeed8bb84504a06d1ebba9a8485630e852ba5f7e8e966689f15b51b003074ff662538193519357a53d7c9de2715f20b62df0762390a5255bc99049d852a0585533f3fccc908bbb56323de50120a32e75746899915e4298a3eeffcc81da3e577cba4c0334c48051c43032a5cca7c5e300cd29a0e4b1172ce70a7d28adea8a89898351f71d200f689174e1cfca2df0d26b82c280e4ffc1d5dab5f0ae0d661281b38ccdcd7f74b35eeea905bec192f916513931a2843bd4ea6b1be091b706079eb2624a4edbdb7945b4a29a59401c4077007b107ac2f43a8be1f0441281b12896f2f52dfff3b78b739ced2f683563328fc3da68b40bb08349cb5a866cf7efe240453c91d5655723f1d43aa1655df9f0026781952856fd5f78356b676e2f78357f5e7e6f7836aea4fecf783fb4136f587ff96cd686e46d5cce85525cf40695d3fa8f283eafbbdb1deccc8990ad8cc871abd66af17660f50496d32f043d6bb9e83a38cf55e25bfe7b35949d7b7fe078997f62ae788973377d5f7a4b1fe4a647df97d93b5ce4a7a95c1cbc68f8ce8588b627d56a9d9c3fa1a52600ec1b034d628637d38ca38eaa52c7cd7585adb076aaeb3be352b6d8f4e59a32c1c39c01d7c709c95fcc6d265d5e97ba38515dd19bccea0e4e827222ce41788f8d0716f9f53446e48a19fb7f7de9f67dd9d7867f77aecba518ff8da592b943927ad47984c364fbaec3873b5650c8ec98c15accae038c146921fd480550110728181961e4c4e49141982081840b083d40c4c9290e1614d9427f1abc16628f45b62e58420688ed071631a2254a2eaea0f326e3fd08842a105dc95104a192e4a3b9e7ed000d252e204395f9315256c803923f2dcd27d34c8804081062d4a43940441a1068d204ebe0889c244070f5a98a28c4c40c404f45b42a48409e685363228e191e5cb9a23c0305d478b76ae8cee7cccfc4d9f532e74c969f16c5b6ea0924311294cd43092440c34d8ce14e9f0a10a8f25723fb4ec9316224e9f532ee06ae8bad8e04293387738153917f94e9f532e2475569f532ed4e0974a56223e95904606282fb6265838a93212a6860a3768513244f47c54515500c812391e369248f181028d10358e9880bbb19005f79099ac30c1a29f8c8ed43253c02a45567607fab940bf5b9fe1048815486982ca94344f4325ef754ab98042995eff8f7a758146873d897921cc982c5ec20c554ddd96d831df49e3389428f5546495cf9c38077438e78e2e59db4307a14628d2bdf78eb89edf013d84fc9dcdf776f77e972f3969f331c673ce2962ab75f79646ebd601f6f83eba64e79972aaf131d2dd7718638c31c6f9d225101c4b12a448e0f2657cf3ef8c2fcef83e257bfea0df89bb8cef1de9d08c4d42ad79856ff2502334086dea734a012119916c5e8d788607a1b914591aa740573e5664d553f53929d49c57b6a55bc5d12512b87c7fab0101f9f890e43f52c724a8e9d685888bea7846531645ce279453f742f59fa43753af8247ac261a60095a72e8a0e4462537d12404c286204bbe317cf7c945892b59053a0acf7d4edd96aef017b6949b100f08dea5d1686e36402d3713e02594d03144054b43a0c051d0ad991a4265049863078eed43eacb8102924e82f292c8d1e5f6191bd9c74d4f01c13f3aa81b443f8a7045781001b1c2e183a8c7158e221c4449493943b8dac440452447b5e3d34265020d2f49a48007272f637286984131d8cb15829fb775571f5f4b2709b4b6d2586cbb10e77b31c658e7dbe57cadddbbe2ee929a243d7bf52535497ad786fb929a243d8ca3021ffcca02f0ec3c0fed628c43ec61bcf1b5fa7a17dfdbe9d77acc2449e26bc94b6a2f939a24bd0c8644f8c318939aecbc0ea7c2d7d447a87dc2becfc6602febaabcb66aadb556560856f1f3ead6b5d65aebe862ac19d76b816ca562adf586652b0194a0d5de18bef66218ceafdcb93aae3516da37509bb55d425052ddfbc20f04c1f0c3d7862c0f5fcb6aed16d7dcd5b95ed9058b234e35bf16bf60185f0b8bddd88d15e2f8efdbc70961dcc559dccd0d4e857a11ebc78d38210cfb6b314e0ecdb911e73fe71687c3e16e84aa7a92a8b58a70fb08b8cf9873da39e7adb55a6bed8a7baf0a4a29a794d24b73ad3e64497badb5fb8e7cf3567ba7d6dafb2ccbf5f262a0eec290c8be0e37a0f686cf39e79cf325c6b6b6d6da6bafbdc9b95d7e127459e7efbad1034b9b7fb342852567cf7c8cefbdd75ef1c43de1737d449bae36576bedbd16cf5aefb4b693ea74a73b9df1add25dc6f716830f2191fe0fc49dfeca7597f1bd75da52db69d108185777f6d6e94e677cab7497f1bde19b3b8d6faeba18df7cd31dbeb74e773ae35ba5bb8cefed09d5b7dabbb7d781f04147c3d29c61d6bcf74618256dd22b8c1757dff78178efbd370882e1d5b7241856d39bbe6118b2ac101010d0bcb2390c35a8bdfb15b5bead2cc055c62c2812bda0760f831e91ff9922c1d4565f7730e811654191405de1aee851eb7e8bd3cfa7564c6d30e8059ea64dd40906654191cc0bea43511b9d61f654bab4d4e98cafad9a6e29d81137f8d4101cb6c76b03bcc75a83e0016b2db6f63d60ada5faf6ec2d0dc845c697c78857295aaf0f8e9bc2c1e4556d42a6e816905a00424f0d81e2e55a10a27f54575a0092ab08c1a26f8d011d0ba911240b4700552f77ba0860450ba932dd4ead90d4ed932c14d1edfb04d1a1c20a9d7b26f86a0334edd6ceaafb0190900b6b497e05b0042f815a581bc571ba041df491dcd8efeb1c40f4fbf7682aa9a9df0b046562e92508044a37001033449703f5a07fbdcba382a2d0cb15d78a374315bd9c6cba05dd5edaa3a446faa54bfdfe2c6953bff4c98ea27effbee6e293738ac709fd3e90900b0f7aece8f73f00814abfef011851fdfe0876f850e4e5c8860d47bf4f936e3dd428f980622ad2ef9cfa81a6e3b45ce1517afdcaa528e42974247d6c3e5ba3ff3e404fe670fff362fd5aadf5e7da00fdf36b2d6a03f66f58bf9fb3f732b21d29d59fdf027ab4340b78e38fdcd26e8c2fdc4507452358c2e9dfc7fbd2a37b73aebac818ca04bc9cb992e77ee82af5473647ebd4efb3fa7d5a84e7b74cb7dbd7e0763bbe8ae8bdb8a85f8c54c98b6d95bcf7666917060553c949ab2a3961807b16c2fceebf193e0957bdda906896328ebaac7efe590878fc40cd751c12cd51565f365e76b97e8d2a798ffadc473d92b4ad923727099f6da38d54c9fb096082db2fa955ee6efdd69af0faf6eaeb7a743dfa5502bf216d53ba373595bc353755f266a7cc64ebf75748e1e536eaf782e3bd6d239cd4ef5f5c8c18ae7ffd7ce170aee7afe9646bb217ad07bff5e0cf77cdf8ec6bcd580fce0767b2f0c1d1893547d9f78db2e9cd4a5c85affa6502af7aa9711f90cdcf3fcae6c801eed3d662cc18a24333ac52b347d6fdee46991d39c02eab4ac61cd0ef04eaf7d69167f61080077e6ff5a7ac4d46ae92adcd7aef5bfdd51beba19b55a9d9a34799fedd7dce9ff1b6e97aa3c437794a166ebe623fdf65e5ba72a971e55c6cea8fecfbf92a7abd30833cef7b9c68ef6f91f774c6454bf3be278abf2701325461a628f5903264c89b714313406e599ae030c568c84b63e68713362c0049e16a08031a5233dc564084106686bc7f194d8df4eaf10ad2a7913effa5d4a7b5b234efef113896fa1b2f9ac9e24333f391ade5f73e4bcda0efbdcf5a6610eddee71eee950da2d6e690f7b7aafee8eedd7c6854d0bd6c3bd3bd4bd5bdbf4cb6f65d75539305ebd651d59ff0bdefc0d41fd67baef7bee33283c0f7fe8a50dcbb72eabc748f8fa5c8c1e45cf73e6f9935cfe68de95e36737573ddbbdd9badcd213117f15cf7bcf2ced8e3bc056e3e679491f3378f33ca40f222e76f5e06cec7fe6626a39f436f9efecdcde78c3172fee663e0dcc4f28d09676b37494a4e194aecb119b734d8ac0e692b5b8b8df7c8d22ccdaa7b9f54f7622f543f0b42b0ff1b35b0fd7bcf666b61ced2bcd79a73d68db2087bd00bbc67ddca0da6fe54d95aec4126d006dabed6ec7b584c1785395b63b182505b04daac2eb261ce86391be6ba67dbb9eefde71de9db57f581a9245525bfa9cf4b0be0f871993d9efd7217eda25dc4bab182b4de1339a52dca0ad2bde91975efef91ad7939b1a87bb0191d72cdbc234bf39e35f38c2ae97d38f38a2ae93d38db6c668ff7610fca6233312ff0dedb6dba17f6e8deb7c2a4ee3d68b335d66dd2bc1745ce270bb475af0499baf7b1d95765695e4eeb9baded9ba579aff5cdfb9fc24bd6ad7befb129fa8aea4fb96f5ecefbcfa8d660effd87546b0f9b01bd66af39dd45dd0b595f90eedda3ee1dd9da576569de7bbf6f9e51fd69bdc7675e6ef678adf1035349afe5f5a8a4e72555d2fbd6e8d9bc5cf73e014cf0d2b375efbf0afead7b544da71fd2ab339dbe2eb25a735ed4bd9fb5c81b4360e16439bec9531280a983fff1d7afcfdd7c8db60ec67a74f0a6a883ffdd2055f2c65649f0856aecc6801570ef3fad533891a50882b5144e9506feec29a2668f15d75fd26c201d65f5f97b6389c3d4c1c761aa24f8a38c8f1ce0ce9fa338eae0e33489fd666bdd835fd26c1d3ceafb614ab6063ba2f595eb7b2c1f76646b30a5b1e49ac38e3af87384dd2c0d1c1a82cffe95b05b079f1433c9aa19444b92880e7e49a6e960492ad1c14f51557ff6839fc2aafef0079f749a41b6832982e8608a331d4c71d5c177cd7425f5f34f41656bb25949f0e9500c3a047e4f541579656b0568e284440e26104121cd10f864ced684b054e5586386c90f1686c027abc027adc04fe1d41a4bad5963c9793896299c3af893071c432000539f02d051b00dcca08a671e6dee1e51599a47d5f7d3ee3deee12c6d2c3f5073bdce5a0f5606ace16025f733800da7dde5fa594917f8b8875f47193872807b38ce6f795495aa97dcaaeff770b666bdb1e41eae5ba85e7eb754b6667319378358bf3f4f9941b4efcf546650fdfd38676bf6371da9fafe5cb4a6972c2840f4fd57cad6f4d0de7fc1cc20fafb2fced6f06fa8beffde6cade5646956260b108a7650f527e7f77751f547fcfd9d94adc97e7ff73483707e0e894e9cc949a9ef1cfafeb2c3a1eff7c69acb5566edd33af02df9871c0bd7f763aa2b5ef19d34d3793c3bf1940273685a40e7317e19275ee72d806564f0f5eb3c1e65a0cebfd0af33cac017dd9ff8ee4f8c3210ff0b9dc7630c24e0c738f13a0f8e2f707efc3386e88c8296067e9e694b035f07fc13b36969f9084cade97cd22d2b31f59d9dfaceb6be5f482f23366abace97ae337dbb82e85b86ce9f78f02bd3ce83ff511a1289cf9dfae64f7d972d2a9b7351d99acec8d5d4fae53dd219d954f5fdd365e4a2b257610670fe9ddf61eae0cff0850efe137f62045b54f6448b5a80f3330c8106f3f5ac5103fb72a22c5c5ce805fb5daf2a5be35a7b571fd4cbc9d65e2f30f482fda2685f4ef6e5645f4e3da47ad97819e2fafeefb392cd388e3fe14e95e435f026613e2b9c9137cd1e2de09720d4abea0586f5afaa57551f4b34bdbec0f4cdfa194a8551f5877e0da3fa6e5159dabeea2d2a18745e360ba52c6dbf380ba32ab93f67164255723fce2c7471a12c422bf382fd3bc4a16f1797be5d547d3f97b2b557d5a4ed1745cea57a4875d5f707d1cb1655ce0d7ee2b3b235d0cad2f66bcdb955dfff5378d97a55f5fd2d305055f5677f8baafe4c1e928efafe5610ad33a518e2f6874da193ade93c97eafba70db7a007cc9e6944af0f13c2c12c68d2afaf48357f4d5e7c7382a453ea040910bca109d71330ac2852587508294737529008a728699b3bc2b2b937c8cd97d748a73f2fd3954e3f4a719ed21c4aa7aaa4d0298b52f129d5a1f475d19153a7392a5abacedffaf3d3755e0c8974c4cf0989c49c363de77142a21c9cbf0989706ea630f59b8f8544373af6b09028761500b30253d161b0e7493aecc5311d862b6106412545088b285970910bf630d6c3bf2114293d8c02e4491991667992c32526cc099a30e27b6f9ebef7f32d7dbf78c3920d337c376583097ad7e99c9d3ce9584771e9e9254fb74daa9c96bafd7752d4e40424be751d8ae344f3a757e4e2cc51240d135b901d47e0987182910e48669c683861ccd07d524837d1ef036d315281e76251c353af4c7ef45a9938f5dac4470d347af5e1d124a5dfbff7022da14149bf4d27f4fb2c0e82239a54787265873336a830fd804223446a8729e4646a099c3476001b38bba3a4ca12157a9d5a5244af3400e9f5c3af437449e12608a45e17254e98c6f4fa1f4fe2a5ef245933430ffd3e678aa1dfff412509524f1227fd5e114b55a843228b05c91412a45ebfe39a6b90e7250c2464fef4327684887e976af4fb571ce1c9aa85a8226e8092e201252a2f446e48a14b1821271e6c7c42b1dbed11252b29685d06c8600667ead37b4f0b8620186a5beb3ebffefdb3fbfc2fbacf5aff1e6f49fad45ced1e45dbd997e17db73fff8bfd79ccaf6574367c915f8f77e7efbecae8bfa555115ee8df4f813924c6e076c650f97a28537a2bd6e1d3f567ead933a7d4b523797d36f020cc9ef9289038fd0f2a59a7c5511fd49fefe7833083f673cd6728264def28800390b6663793a69f35d3f7a762dd637377430e5a2834d0319e372168ed6109d8be759751d820f1bd95d69a858828e8c8342973311072d101ee734a09d785117f278c103160c995a025051c88d4b082448495a321301656137c62c792238cbe38b190d4820f1d3c20cdd0840d0f4da0d94fc29be4a98d0ada8bb63c86b09f28bea8c4d44b51ea4b522565390ce749bbcbbf2825a522945ce07656e9f9a484e39b5252c18a8b5ca9a89764962b4d4ee8ae30b1815b4cc14044fffa9c8221cc92aaa6923747af906cf4a8d4fd4ae1b22eabbf5f66699d5504b3f68d14a9d2eefd929ad0efb8a6df7f1edceb22dc3ad3b3e7d2ab2b9a2603968f3fba3deaf3e02d4d9164f869ee9bc9f0e801bd1afa5e96f76cefefbd3186f7dfc7d0bf7f86ede8ebb1bff59eb5fa9bd298b4cbdbf4bbf1284225d345a8bd86a16966cfed75a45716ca0049701b659f7e3cf5ab91d8aeebf467acbbaeebbaaed3f9f72c040168d3a689bea37a39a3a977bf4710cca8de3d3db5e85df7e50a9edeedf4aeb32a664dc5a4cddafcee27cd33fc5f37ee0ce89393ec3eef999ea4ed5ac892a38a7c3be6a9647d71ea2bdfe4e140adcdda678d5a2dd4670174c55802d19fb785d08a1f1ca853a119943b7d0c98ea122e46a8b56e02574cbfefc10ce2fdfa70699776efcf4b3798b47baf8bd973ed88410b289cc7ea8f9d14d7a700ec9a0fffa545fd1ecd201a33a83efe7b35a04745dc0373a8e4fcde7bd9c4c8b72808d5db0777776b9be938a9cd96fa00e1a8cd7476fbb6d7a758a2be153e94fad82324db07575655b6db6b2b9d41b4b71873259582124b486942868e1cc2acd1727444d5017cdec7b57be9d3ad66cf882b29aea45066444162a306ab1f662802c7100694e48852a54a1521b20cd5f701fa4e9877bc434bf0f2f60fcf6e073388641bdc05f4fb333abe20c663ee9cb2f9720b9ec1fd39d480e6fccd9979f0ef4cad855f9faaa935d65720ea03eff5972a355269f57106c7528f4038cf28ee5bea74caa4d5c7d2ab965e7de8f57b4c71b3e71be913da448d3419a93f4a4bf8290b8bbf023d0d15c129146ec50f8ebfa438d906b43c4090a2ba224c1108b48836e131e32aaa00a6cd0c619a92b419aa06a052c39a2f429890d445b4b4162c7e16d07d15b9d4188daa3f5235e32f359ed9cf21510bfac49a851fc555b20aad78e29ec5185b10638c31b5ffcd424042ff7a161a812a490710032f817a15fafa2dc00b8233aa97e0475612acb41cab5bafa02cea4f8e401ec94ad6c72d1b38970e2ae91ac2edcf4a7bfdc08cea7814bab31695c451a9fa940af7555898a9e273f6a9b4fcb409cc03cc58cf394f313e2c604ace4b702a96ddceeb0c5c2bb32ff2e0b03e6710aed5a2f9f4e3f76c089602f6f72c04fbb86abdf7defaf7d8e19fc0b4346b67ddd7ce23caee18dbf1c1c9f15718e1f3cba7c265ff74fe30e1f39dbec953d270fdfb4f83e058d4ab51afb1ab5e636c2a598b2a596dbd9638b75e7fc88aeb126683d9aa54aff5edc3926ced95b3b4faf7ebcc8e258ca97ffffd2b676bb0244bfbfee3db7be5fa67b3b4affb1266ebdfa750b25a739e42a97f0358ea5f492a759a0cdfef0877eddecac2ce124104b4dbd75a145f14cb8903e1844eff86f6d1e94b48a7ff329a3df4eb91a5754250f7a332fbb3cb38eaf9cb6aeb5d37caecdf3c967694dd9103dc6d51d33779ca0d63efbd4b6d71f72dd47dcba42d6d66dbe46499ec979649db7452ae35e1b23a7a00e6910da5b4247dac2c932b5749fa202545f2dfd2b8a5cdd1a5864b81502e5ca7617562ea34bf65aa358a029375aa3f4fb7dfb7602e1135bdb44ffaf5a68ad4e8a5852292825e5a2efdde4b874a6bd5efdb3c3353fdb99f9beacff5c1f6b6698a488fdefb881ecf0cc224bdf46252931ebd98d424e9e1cff729fd281e6fbe95a4176bb292dec4f88e16187d8fc16a3178473d29cdf2cd9ff3739f636bf650224a3710e1f61170b73fdf67ce49de7b2968679e7169ae622fce9df6aac5b9d3bbd67bb37d3c70ceca5ac91a3e98edd5dbfb58737b1ff896652b9d20aee37ccfca179471bd179c21c6f7de7bb1bdf779e8cc9de5c163860c09f3455f7dbb8c875cdd653c64c8900e0afdae77f1c63c33486bada2ebc06e8793f4826a55f0acd8c117db4e671e152a54a850a14205c8d35129ed34d585cd0bb01878a58349695db610551d8bf5255aa8a1a349083337864a8e4311545f4c38a1c697a112c8d021dac5050480b12d1b2c1159c14a102d4f45745aa6d8cc3801ae0c9820296c71a14a842d648e78a420099b995965ca0c6bc6932455369401223584099f1523e49eff5a5a248481b557fdda99d084bac1eb773083b095291d7a22b164869c18272b8859e1a3a226cf40c1881f5d8cdc50418c113290d7c748a7dde7f6f001a4091b58c64449c272d9a15b3b8990ba51020fb829430419b2d65acbc34304032f796a0dc8c85035d27f6c0d05aea8a884a5a1fa76265485aacf0ab8d01053ba1263244b103694e1e123048d125c96a4d880e4062a3cd7cc0a246594d440e3cb94102af002440d34b4b92a5204990e071f687ebe293e158ced9ce8738a8a86973548bfb528f1a6a543402c1142093329f0c891fb705245683d34f1e0e40586a61e8488d26409187cf8408608295245e1067e2ca185082078d801f7f7c230ca7146054945b838b9519aa80107131922587821072286eebdf756fb38df7befbdf7c664697819abdda701cb0f36344e6aae38a5f9a04459c9e9009a1e44d2740162a4c4ea940815a498608997a5312b987749072633765039a172e35665052543d65a6b2b09d630c859e235d6506575a1aa424a8616be285193a609245418470e45f94c0a8418b1c4c6121e483c60e204dcfcc71a1c0b251c5992443fc1120317810c8d15ce340121a688eec618a8ebebf933a75045c1112b4bdfb50a20a288981a88b449a3c210082eec77035453b7f64bd392a2281f5bc4e03064adb516e44eb3f3e0290a0d1c8d1344a161a8e4bd7b105e546da70dbdbb72a477dd0e48aca0043246640922ca507782af761deebaaeebbafc621b5e8aa217afdb55d7aabd241cd6e7d4d38d3d657bd14b70ce041e826b2492ac39411855a6bbc273106017fef9b08190fa98e01b074f07df51b40e4e66aa28e97bf4a95204479dfaeaa8249d9354110243151f3ba2beb33ba2f9891f6c3954703a51383854895652b8b972cb6112c3f1d130e480f900f9ac00c2e56e861cbd9eae623874b8a450c1b48f0c4635b8e61ae419e0f0e249b45c6bccb038191da194a416c80a73f44d910ab7d8f0705420151dfbe9f6d5704353b9f28ed4e8aef62d8329b6a91872e85062c323674647064f38303932c01d65c96153b2729441142b14436896ad6ba1871ca18f1e50f88c701712a011fe9501a7f01c449681e3ecc0f2f194022d4fb410eeea938b96233cb4b480464b0f50082eb2e94ce03a633c2aceb7544955c16a5856a49c9820b54414fbe4424566c9376710f751814715956cb1485b3be79eeeb2b6ac6c5916143ff1b9e8e303044423802669042067cf2d75a7dece98f2d972b16aff904ebcbc59619a8b947ea4b5ac3bf254928714bfea4b2d086aad758b833196dedaa5b3b54b67a641506fedd299851ff8e9ad5d3ad46a0d825a6f97cecc636ddeb9f24e5763e0d554530d629e2ec3629deea8a7670f7d209f52a6c99dfe62ed3bb49d5e7734d5e9f42b50afbcccbdba5e1376224829e391a9b83c0ae8d34aff3248673cfdeb403afb8e8bf50fc4d7d65a2938712a386d553cbb393f002c1b5e5dc371aab5287e597b1dce18676b4951d45af7bbadd5faededbcfc81d75a6bad65d5395b97523a72dee2f691e0dc69be75b7bb0eeb9db3de2d97c7ea32f6e9403d5f4d67b5aceb85df07821e80e1c7c5d73e4056fc5a94ee3f6479a44f6b03f94ccd279fe2ad3f535f52eb16d723108ebbe8764dda3cc02449125f4be26bdf955f2f0c8391b11b6b2d50c2e90d4e0e758993b434eed3a74892a4ce12194fcffda394ce3e0bc6407df99c53df3967d7e9ed7dde07823cbc32dd672c16ab55ef38bba53c22e75b73cd820e9c7eed1068c36f2f3140c369c7000d9ffde5d25ae711637ee7b4ba75adb5165b6badcde09c736a6f7bf35a7bb79e136baae7c55aeb7bef8ded94e283219105738851205d6badb5355c458098478164adb596c750305db5bb7753248efa08b57be0cb78b64b87e6ef4ed05eabafc5214ebfad392738ebcfbde3c86a8173ce39e7c4f567bb74e853dae5997f3f7651dcc0a2ac7657c718eb50d985bd50dce03218ab9cc1afae159a6dfc37d77ec769adfdb2f1bd42f0dcd38e0fc20e37f87dbbbc2fd65adfbd71acd68d71ad1db22fde37e79c654bee1e62adfd62c1cf7b101e9c35a118d597da160e8763d1a06151d0d0b931ae942fd6da2ffbea2ee37d5170b7ee32a601801c60ba7ba83d5d543a5533042ce9667592f8e2dce9ed8512b83dff0d37b893829645bf570b20bb02013270fa4277e456cf368b87267d1d06dd7bef89db38560b9700e71647c17b1f087e1e8c2b0ebe4222fc2f18783f272579b4cb9470fa42351482792ac818f873ef3e67ed9bb51aa34228268969e505a650d5408b8593d3e58899fcd99e0f48f2ea0fbd6ee95587f02a2909060a1b5ce784cc42e1703821a1d903e515beacee883be04e48847fc782167d4527ebf379b2ce640103d70e7a109d3281099efba8348db9f434e9ccd8080000040003160020280c0a87842281408c04c2a4e90e14800e65843c78603818c9625190c3280882186408310418428021c620c3584d750004df988abeb3198a56a7683730dc5a2d97d20be5467b9e09b554ed8621f6348f0087d2b9ef1de1d411fb8f88ab9ae4b2dbff687392403201af1b9d0924df9caf1bfd1dd123ac273817ed69bb56bfd151770c7538e069dfbdb40ee2fffcd2d17202a18efefbd1a800d3ec26427c4a4a7f94a16d11f78ac161a20c2c28057df3c36ecdfdf60472a7327c77758ac1d7d597a6a0a6dba2d97831fc28d113c1e6dbff3d1ac6cc457e9f11559937edb5f3853fcc77358bc76ea3ef9e877579dc367a35e26a6e230076a7b1c142cf8148910a59a0fb27efb5a6abd77db7e3700d7263b798b7fa1c2f21bed91b48c63aff9315fdd5ba2977f2332c57a29ce13bbcb891eff506a7eb9decfa74a8d270b9819e4a145b00e6dd0ef2ca188452646807db3e074b9f9a2ced5c432fbe8ad8731a1b35927a5e06d9489c941c73046834f4577e804dd915d5b750220f581eb34a66edcba0851fd9b810e9440de6a88ce66686bf1d86c6505f7e0a73dce605284b75a3915d4c44e6f517a3752fe42916b746e35853c938024578f6585e1fd2d8f881b134e511a9ccaa7e22bfa155638d812f9c2b0b186722be88da9272aeb442ed1cc090668144fcd9f7f7ec960cef7b66cc4748e75a3156e81e291da60c0e1012501994d374274d4b40e9efb780878fa5615802cf905374cf266af2b6297c3a0a18975a3ba90923913fe8c538c6f8088784a3a6037da5e53c1bc97501f31208e285a20390e18d7b4c183845dc9a6548f932098a3f7d357407e7633920986e7a535ac8339de87168f06597c267dc7025f7c021b00c4fbf9c9e421cb199c734caebd41bb955ae452152889b267c020576dd032b163f8868a79586ae1257947ef07d1f46db9c754b050ac21463c3d246646718e0bcf7bf89d30c106b02e79dd229756c00cc2e04e06e37019f92bda8c4308f206df4e6697a9751c278f41ea84867f0bdb35021216ebd877dea825e1d0428f9909bf35b11f057946d3fd0012eaff18a0a49a3413e4b0d879bb97696b50ef0680a15f5ae6b52959bc06828a76469a040f6338943f4c8d19a6d3a8d1cc6702f1ef788bd2fd91068214e6a710ee8ae0f68e9123877155560cfe9998f3bece6f52f68333f135eb0d00391e997e15a247973cb2d184db9345e0dc0d226c7153d1b08e8f10322900d17b395159ad2e82e1ce99048c8c2bc366f22c1b099aad619982b850f90a4ddfa52c98cee43e8068e050e56aafe801b744186553b8be6043a4e3fbed0b8bb8a348bffd888aeafa846fb287bbce71a3a5c409abcb3701b6103c53e66e210a290c978211d8dd44529e0a33b3b053fde907f5bc0c8041383d9b9268ae652e7b9af226a695065996052941c43a8d234c23da498888a46c06e44202e73b02163ed971c7e89b57670d4f80aba862a041f1016dcfadcbcad253388f026ffb7dc962342a2723a4bd492c3f7ca196fb17714a459490e95f9c886c97a847cffe7a0544d8041a60edb3b76e187ed15e621c0c4da8b21c189d3a6683d37e3d6c7cca7563d4b38f1fd3c64033f4ff2a5c6462471ea1a4fa5cb0c58d9d5f88f2d6592e7e00619b5612fdd162d8e21f6426b283e2892a84fe8963efb4365fe6574d60d0b104a11d5f9c9e9121d1bd803093a5cf415c8224bdd185b8e8c70ff59502c9f90a58d4050349ecd88646a4ef8616ce23a6838e1db3b23c2be20d2c6c602a7706da4e4a415e0351e48453701282b45f361f36bbf74abbd097b59c8749a7dd7249e17342635e208b55bb23c2291c62a10ac8a0aef9b2b912eca910e94a724d4f1a0d9aaaf6e0d52cce355697bf8d285bb401b747391210742abf71b9bfc7ce1ea52c23f3a4768098c8825eea612f1d072786e42f601bfb84417e782b0976055ee382f2dfb4be92c3222728e532dd3a1485081a3a4893ec143125808f631300eab11cd4ca265b6ab75f03bfffed06f2e2a1a89f03aa13769ec0bfd8b44ea93227c01bad7d34f25f92f8b9e385cc6f95f61d2c6cf23a75184f635746255fe2e9410dd512d0bd7f947384aa1c0d106b2f8bb4782cb91518cfc4465371fe914be58805fe4b9ea13c2974e3c1623e326ad3092235932eba4d38016d1605c8c879f0e612730e593aab098a2737ffdf4da6eb0b0b3105b0e666d961c517ec47a32c8e82bd7dbd125ef27161b8d4734eceeea68211619222e6e9924494720005c97c42e2d72cba0876fb77130915122cd0a56c26dd163c32ca117d423fa7c2b27694b63fdf14d6c9b99d55a5db19de45bbe8e4d8830a57a391159cd956578c41ce8a9df760cf63a0fce3369672eb9f6d1ddafc1b6efc2da762c34d6b152112e96110db72af67c1821287df0b9a9d392f04522042d7353b2e61fdb2df725c118cf9c4d37c1751b6f62598f097116c4f5a6a98450fd702226248abc8d1f98d94438842dba65b6b55bf51c4bc612cac4d7acdf54eb1bc2432623abb30e7ba7bd3f9739cac9b40d0b34b130a4028e44343bc60ac2d94be3801a6fc37fe009f44855d07304d433399dc05e0a68c006654eb2ae0277a9e20d92a8d2000ffcc68ab47469437b6a39966c88130dd0057f8b43381f4855ff2d6f02a558dc455e2cd1dae541b3690f66e528a7a716e97d5fb8fbcaea21a5ee9ecc59cbbd7647db90519809aa5fced2ae3e20f492b52be028c6b7bc4bba24d35a646848ce689b554fe20a04d1d9d3bc2ba06daed3c5ae091a08af2eec8250ca0cfebb2e3402d958443086dc81744673bd97a0b56fb1c06ca20815aedfbb00a4749bb70ed02d30dda41e073508080df185807562ead6ec9021e8dbb3e3c157d2de021545bb1fbf2a4f220851d9e6747ef34b1cca2dd1a47273e62eb7d4e3308d00828539e582b7b28274aedb4ab70e0c9831381c5595ea768b1cce8ba0332f35c2ee12b1462c8d28e3b86c5920da8b1728d5a9951198746d0f8d564102a570ba720290aacd83d1f8c26d01520ab6d7dfb68d5c35cc64f8088bcd86fbc4f795a78c1576e001c3bde028ab908be55ff9947de42675537825b430f1361e303430c28edc349f91ed140aad7567e4aabd8afb41234c7ed77042e7705121ef4bde82aca8ecb2569118cf3b4f92a125b50ceb0113591fdee406af568f8a3a911d1e2b26845ab108c1fe5bd0a30336d7b138243ca2d0b610220b5f765487249287edb664ce032dfa763946f45dcc63177cae2fb9758e6c4cf0d667f3e1e5ac82351f970c804dbee9c3461833cceef0efad4ee4e996aa2fa54eaf7dc7c73e462e958dec905b66d3c074520b848723b4b55ee9a33a0c6847d714d13e0ffc4ff0868ca4159ad12336c4821ba54a6f5a86c6e8e230fcc3b2fd301be4eccf3bea78b66623c4e472c7b41e2083b25179b1f7fee52c1cd183cbf2a1237283e72335895ea17497dfcf5cd269348971a1163a886f1b6eaed77576916cd9c999928f5612b8de5f324a17884b8a3bd7093fb3793af287bd0c38e3fa5eb583ed5de01a66fa24cc04dacb573e952cfb8d2dd2060e934b6d26582979056d61c9b6bb6d426882b71d2b8b09e797b8b47b3d252b2d8446a52001573f95e45a356af3f36b450091303fbe08115a9a28060652c5441a2878af4dd95d8a0bd5b04694ddc52b34e9f714ca88350a235ba5525076b06af20ab66e2e0055b6c98da419a5b9592b58b67547913c04206070a44a8af01c2c515e327b066d95ee092d581ce86a36894fe5d4324592eb7ab7715ab8b0ee16858636b0275a97822d0dee104dd574fb83557adeb93f27c39beb28cfd181e4f9dcfab60562ae036573e69aeeb40872da22de8c8d57ba45c446d788173234ece7b1c359ac24c9f02c34cfd850e353b30f2fc6581a79b4c9e48695d5a5078d94698b64508800ad19889d083ce940f2da9e740876bdafe2da89d4721ea72d9ce9a979545925faf327af232a6e0385d6c25bd00a4218666e72a54ad8a767277b780cc9539674d34559644560f39d5dacbf79ee4538b88f591a328f1080106a64cc3cc4b1afd7b0759b97c5947841e5f970a1c0871556ded01175d5cc159a137ea36331c88bf9fa80ef350016d6c74f4d503c8938767e992848337144ff34047d271897e15d1f1ed12842d543d35b5c7fe30233265802f8d28f767e5bd071f367ff62065f3f84a4d30a5a18d1fc7533b4258f1d951563fcd2c037b5dc51d9822f97ec9e6588b24052dd30530124f1671ae8e7a138bf752431164ad1e83ba5501aa0edc80b73aee438093f0a7894b98be84067153038c7aae87205ca9e7527213306b100833f822e84bf8b483280ce5a9908203f41c7e1ab242953b9e9176587e9f42c3c0570aec0a8067b2e8f89d619bb918ed9063503239322082541089b08c563f5a28b5f15aa9a1752517b181d8f3d8c2dba8d5c5d1dc638c5e44dc6b32e3382dadfa1f6ea6e38b684a2e41b42f3b7f911b940b005a7c81dc284a28b87fb0cd9c5530edf14eea3ddd1a3fd7501f8e8b360074269ee3c40feca9ac79a810a03e2e24b3d65c5b80917b63a9c51b6260c8f57b88149a25d2d941d89a97a31d0b3409e478d077bae0bfcf98a659b5a56dd7125fc10d452a9d46ff6184e2d02dbb24e852924c681fbead04cd8613050c628d3744735ce2078a76e5e068d7993a8576b51cb4e3722ba3ca1a4a9fc8899a042b0d2e4e5a17a71efed3959027cfe6aa6801c4ce4568dc2e86a6b0e1072744d8cc7e5f35180d86121ba1c3e961aefaa721513cd309c99796bff03b8ec4d2dc70431e81c722e355dd6aac6f4cb413207b4c05090bb75bce8330dcac28bb4033ffbc5cdb77b0447d3f9bd9b946edfb30fa011511b29f4f467313dafce381e2f0963445bcc5cc2c45c5626786e2a57204ce06721d16fe6806cc75a7afd64c62c68715ff2c8ebf3c00774fd1c482c0fd539c9f9cda349a55e43b87d22a66dd7173f286cfed6d4134479fe814c493659eeadd3e7e53fddf61b9aa173d74186c98074d95683380af156a2b1800a75ed99f18d832d9cbc55b2f8870a1a8812095e29ecad70ca72cc1cfdd3cd07380b0d0d392627846f655326d41db34e793a34da5737f282c467dc189730963c1c97d93cec026afbb665a529c80099cd1b90cc44a3a29f99d0af615e5898d82ec1a0cc4a5957f911d9ab912c8bd0508e5e4385fdf25cd9f4f78bf8e962406caf21d1428f4978e559fda23718be33d1a46f04e8f00fc81f283a97e7ebafb08e36bdc9bcace258413814813cfb744408190dd2c07e2e62d18eab456d386595b8df44983c957d01794edd592214d4d7db8718724828680121ff9b990f983dbb55eeebb521399d8551aebd403c1facdcd932d61ee37b6c8cfeb44b0cac005290ce89772a37fd59f00868cdb4617b3a271ee98115253955b472b36bf51fd6fe0af837d3ea32a0d0ae5d1f5fb76da671135ad08e44c0d3d8f259646d916831bfc908505b1215a6a4a9531eb53e810f2abd2e317b570e7ae03c1cc69e205f1f99818721ed3b5efd0f96b086976aa6bbecdab417437d8d41fe5a8d25a58b67c92fa21f55e827746000036e1b6bfa63bc988e03709f597b65615e79eb67e8f7529be9f1d52e641527bac2bb2ebc66c42ae47802dccb707f4b301966dd10ff811eb2604250d49c75fb680e49d4ce9d6f08342c1893a4eb666e0cd450b5cdf8828d2b7969a02c220ac4ef001adee047dad401d5aab038c66e9b4aa078c172ed91b86b7f40807f51319853ebcb4810365085c99f6c28fb3e771eb0cb61855a0ec984fa92fd525133f5f260df1fbed423bd1d70877ebd624bba8aec941a427a2ce41ed72b680663eb51039d9d4b4df2357f0620009e0b5e4f6cd711516988f42076bd88ba69b49b70da6d474ba7e9aefa46ecf0e826c4c7ef1084cc755a74bb48dde29d3046975872640977ea4bc0e8bf3efc144256bffa9332e216667d328536dc2999375e5863ffbd776dd5c4dc0ba0c2845bcca8d443793d23b556729842d2872d241065043341a7de5cc5a7825b5f292ca34f42cfb083774255c11fac944a448433e5a7a9f341e4cfc480e5cdbb27ca2d1d5c4c4f526303e7298df9103dda916180d90a2f56ff663e431ba9289687e76c5f740d089bfbb8f38c0b91fad1f3d3e6539fc9f9c53f5e887eefe42de9cc06533dcbd8b6b4fc51bb8f754cec69286aec2341a8495463ef0d2ff8a88839ef42b1982513638975031807d10b3ccd6b8d8934360a4b08e236f99e1bbc961e628068c9af62b465f1881423e22e5b568fa4b4f5e41717ce39d9b519eadb94e97b83b9e2c31b76e1ae2df06fe451e32911be846abcfd78bc511eb390e7665fc3f10b3bb3f35f84d91766f85623af08998a18441d3c2b6b67a022e160b5ae953c2811f34e84a430f31987d8199733a4a0218819ea9b1d1ebe225627c92892ae4b5a6882a58f7a51e41670c4436343169dd00213c5cc8908d4055ec0017014c789a4abd63b899b0885dfb2f3304f2fe6182feb77c82c2e8c65370bd762ce502427a49cd4822cf89c05ad0487984bef152810eb18312ac9c935342f53f4844c6de0835321944c5db9606f352896c9b8c3d884a8cb31d566a04828b7c3aa3863574191963fac0af1ea8637a9888ee3ed3957b29c7d90e03f5f76d234021b8d9dfab71b1fc535281c7805fef13ee905c10d8dea70052a9dbf0a8093bac934b48d8864ee4ee5c774a66643e261fca29b23a35303c1813cf624c561eb35e2e24e61a9c1ac86bfe288c16b9d8b0f158f12c54a1c1ef2aa72635a8d82e8e62116b1458cc81479b9a4d084568983ccbd415fc1aaa45b0bc7e3a04f79b0d8a8102f000c8b2c3bb24367ac5792d4db8fd3ed4944ea04bd0767f0e941715516d571a20413d376d045c3f378568708d5c038b3d277ee2549742a8583e95eb5bcb50c9b7ba37be0b8f17d4bb948d97103d66255ab63904a5af9344db685dbe739e544b06a5a68bb38313ea91f42e1976726d10fa06800d8b04a584e66354efe95d42a60b68a070dd16b877278ad75a04824aa727c8f5cfb0ba66baf24ea8023ccd91a5c0c1e206a474efc56e3081b85fe4477e2f6ef718406addd9d8d6bc91956f28bf73fe0a45180c5a7bce5e1be0527d6dce44d6c8c517c0282b3e372932ad9ad96616f36e501a2b9a97cadb376fc53d47c29f165a8f506bf59d2474c0c1eeb2b3d1c200f6427622de294a769e2d921a3970ee8bd91ec7a7f1a5f1f02b817726b94e62061574826800bf98b9d888af9a2fd174061c383066060ad2bfb892620d5d7de83e8dabb402e74b7c23daec8735dcb4fcdae2e9a04b0f0e6ea9ccc1bc1159448f463bbac1ab7745095c9766229f2670037e337b9ac64c295b1b587299cbf857db8706d74ffe07cfabb2b97a496d8ef5f2180355b47fd24baa319a0001a88f24850ae50a691945f22f63d4fd57a04797b1d5dda54b4b23a2b088cd7d794f6677d31062b51152cbfdadfc70069dd97fb2fe26fbe4336be570000a24c9b464d944d9ed4dc363b4cb292286eef889327813e5d0bbb68db728152678e866d2f94d06051ed4938ba070d4b767fa9c09659d31102db316744f51713bc798232758599dbdf8ab45d84369d61a11f69fb9785930802ffa8f09f15b4e1977dbbf8d5426ba21336a81e6ec30fe608f1b5595e9ba6f82b6841c7be44678bc31b24103abfcd3e5db0f52bf12e070be629d3ab7e406c3a3a777fffbc38f2a8f65a901b6e3d7da119e2fadbe176173a161c0abcde10b7add2a93d9f6f7a5de85eb579afb2ef8d05712de2be5430bda8d31a82121e4914815eb1278d4b2d9001b7ffb1b0d4ef782901a1fd1b0d44571165ca49e340b38403cfe202823777d139114810fd766d9937ceef524411ff006f61ffd8808c94173ea9fa7096d31773b7e57c23274830778176ad1abef6cbcff5b192746d590606a4f02f58ae38d7090851bed54aa5545b4f8278afc2ae4dc6a6775b30a0779be44ca30abb1214ea219b3b50080ea9fd22ab6cdd9c557d9fcfe2b686237d791a2f817a9de6c7dcefcb311085ec653fa2a525a16653580be6238e030889056cb7e1dae855a0aad650c732f083d65eabc5e345dc40e58941acf143589b97fbad235fa9b400d4660ae0beaf21f4a2df9f41174b2e64fb99ac205a6988e42faa6ad17f62aa0528317677e4bc7fac01cbbfefb38d4100be9762ea419edc9e1a629322df73ae6debbc07ee032f9ac5462960590ea8b3ad16f0a87002f723ec304d0377a9abf8dd2db2d51063c517b9d4c7f59f3d6394d583fba07b1656055417d1301cf86cb87badda69c3596986621a8805cb04c0a2508b1fcd7ee8fad80dbb144a603b33879c6a8e82e1f430c0d4f020affb816f1cf12dddc7b7ce4a7e22def39be9ac3e027e25c0e570d728d18233b9d649e1ec77934edad8d740b646513746a8d138958d989d357e6b6f892ecaab8cba266d248a06ea64bc28840ee35642a28a45e493f58b7a46c81317f50a966272c431342bcc9b500743b53529be8204c5985cdc13dd4309814659fdeb63dbf3160d92d8806460580afee027aa21fad904cc1c3a779a28939230c24693b66021b4900928be31cca9c005f9c447079a70d1ac400d2f639e9e1e4f21dc82b845034e9b62d3d24ded35a3c71313ef5c23bdb2ecf49f4c98ccc77843961330a1207d0251c69efdc10ab271db361cf153f6498cf35b807c8ec595ebf1dcb72d92cdf12f97f7852fd2fee07afa231ef9461e9980c1f988bf04cb6f9f38d2b6f088474f706d6c509963f26cae82d27d73ff2486979610f7be786a4d2bf7048fc49c31457c0a360c4207df78aabcd2e634d828b40819dc81dbd33fad76b477cf2fe253518e7d7d38ac68622870f877ad69d1c9201b25249fe8a4ed04e222ff1edfca0ed0a95a81fa1c274c745d2e5b2c43e785c15320a8368cf196a1ebb0a906d23ee845ed18d1875d56c39d8585a7dee72a93f478a07dea41ddd50facda4e94fe56604164a87469978a9ebd98eca6d8200b4e288518d7d391ed542c0c7a5c21f3b6c2fe273bbc8b82ac99fe3b8557617fb87ca9e17b514c737ec098e3d39e709d3c87b0f1df29fb9ac0daa6304d28924acda069f0b43b092a0cb541eedf12668daa0c40fbf458233a9f936db49d91cb330633255914912a019f9a63c52faba7ac80e55837174c4cf6bd784703f80557d4ce5e7104a0e422a39a1e62e635a8414462d000e00e08626f92f7c8ab63bd5f39ee433d2a0f5e3cfb990e5794543a097fd21b355fab3828f4a1bd37abbd68506788b6b55d9c3a2c007a745660ef395e1a3adfeea5930205ab2414c01dd3bbd9409f6ccb3534948b1171080551d9afd50447b8ba15a7d777cb95c2b329389dc1ac7fcf1b7b1f134e020360ccb8f06c42e879e5d67e0625ff27524998de3a65f78ced944b1bf72117c5c8fd8f029decb7762b48a90a037288ba0b6bf1174da09812cdce65b82c0861a6bb639d6f1c6d0137475b191df73e9fddefbfbd734a648b331a37a7fadfb1c0f2def581c0e92ad98963184a0ec8c6b2c804db815d9cd2d5c89fb8c7f4eb279202caf0abb3357745aa25895a41a79e49b024bfa03fb72188bf919fea4c3e611198c85ad42bc3cf941b07d2691eed4756e2e90500cd704548910b19f36328cef41bc982984d4fda903c83a408e466b910f39ee3c64295b7d19defb08194f9e81504542caaeaf70bada00728c353b94a58caf992aef65e0bea48e0fa3d68b1b4cc64ae5c07593a72b468d14318e34d633316b216a799f48ec121dc79173f54482709f6bb8a1ac61f98ec217c71f21c0b30eae12e32b10d33d50c7976324754955efa646e909cc4d2fbd45795fd889d687dc71c18c4b278e19872e54cf0fbf3e24507a2092c0da2b26e8b6c24fa4f0af5e45e81518e9740798591f21bf5cdee4441a31dd77f9c451fc895f55aa644b0235f6c78ac7302167e279c657df833573734b8bdb1986f349c9c50573850a41c0cd5234323f955c4ddcdae94cdf6b8c2af722e1ab2200ae500f6c3d7516509148a7744f04a50c46818feb9e1e42f9c496bb91b0530d63cd997a7fac5bbe8960face443f7e365c48eae65fbfab28f91de52a3489dee9f4a37ba581481a78905971cf14c9ad74fe13dc2abf82600ffe1f90f637440292585018cb5628c744fbab9ce7716ae0affa8e79e0de3edf6dc15c729d27a376b96e3e3e804506d0f2cd85c4b89aa35921c070f5a2c0710fa10a59927febdf434ca1892e2d9af5c91cd1a1f043e81a8efb0c88f1af3d6de469fb20cd8b7eec54db50ad0f11b342035ce0da5598d44462c70e0bc0e62120c45877268bba9361bc14451fa6ef5d5b96465ec7b090ff753b7f124c68212d3f15374b4ab00bc5d6c87b4522c1029998f9218db6694a150238b6ff4dc4895cf96cf8ada859447742ae5b656ada2bb6d7508eda67a183af84f15faf1b71bda6ec220eb7e422a1ab7aad3cdfdd78dc82dd2c94cf6e61bbfe16a132530802f72790bd7cbe1aa452c81169bbffba489b8ff4bfd312986f80cb2ba2a6bb0300c8d72abfcfd2af8a1671199ba512d3abc3eb8860254e650ba2fb1834059fb8dabd1c3a3fe1a150faf1fa62480d210fe503968a2d67aaf273b75406cdc7ba96633641e0b8d8f3e69d2f0ebed46cead7c9effac0ca37123e6160ab5d2df53a87e4b1dfa5c3ba3414ae6d88e59a23a6880bd47918c078efa22b8f4890951072bf70a34717c57096976705a222c70016eae0c822c9dae2ab01f6fbe68b54e1965b71f30011239d0015773c3ca873df85c93d5cd05b66443c46115fb69d08fde41bb9435a72345d108061f8f47f4d2b06bce8ccca919b053594e9d52dc17185fef53dc652350b2c50cee5c5edd48b458056ab3215be16241b2c1b16b31e430d8084923b880e92107c22a7f13871cad42d769a96230a68973e68ebaf399b9e8ddfc0d1f747db2a5f35a3a4476bfe7c2e9429c63e5e64345431ae8499aae332a10bb389e2165d37de3e793ded8d9a344850371d0b3f20208a350da3f4d9aa0ea31f3d3ed06431d859ad4c242d80c164a949ee0ff9d3f4754a64020496e26a5729d8158f36b66d2babd92647db7a7bc56bdcf130a7f40e54b5d1d81a06ede8c1e52c3954ce83374065dcff8ac73c480512ba036febfe59d6d626e320615272818fd6e17bda24cdaf0a73b9b61489e40fef6abe980f9d20f62869756e0b14ca43a7a727cc0f45b1f58f419d5b1a6ab7d328983621f42c9b3e213d61b4b7364d317e2638499ccf534e051a685b8799f3b277268b12734bf751157b1b6d3cd274debc10c182d706c1b637187e9ed082be4347982ebdee23f49ef253191f63b66fad65be6c1526c17469371fb85d76fb74f2baf054d5edc1277a8cc0a2badfe263122fb22fcf7f5451417dd7e6a9055f240b5064552b5adff49c787c3af15dffee1779a8b340cb66be6fa0793d8e0beefc859dfdfa5ee80cd592001b0df39c4e762a8a2f8be6c09f0abd51e347070592d9298828832548cd1acbbd863e49c5500efec495f6c3d5e5f0a1d72927be9caaf19ad5f79f7d86174b2d9cfa8317085fbc189b918a5d08778900e876f4f01c0dddf16e954d3aa302d4f01c031ad1dbbb913813576bd0c317e8a76ec06573f043a4920ca37ed25dcb13d5eef51d0cfcc5877a0d75980719b8531ea88bbce32d94a76431cd27faef724beddbe4094c6a370799c23761546a643737ff87e0ef9eeaae83374671ed1c090ebc113bd00771e6de203ffafd51a2287e49a55209c09249164b5665edfa9d23813d065c968c1fbe8a46d7f9be270d337c1413f966692aeb80b3231f24950e014241c3edfeb203f773d52da478ea585f68dce6cef3b13e356e05a197cb7c9563cdf6e73a835073b142bfe7fb121f7d5875beb24c580b841a69ae8801fb8263a724e40ce60cdd02f4a3f61c3133b7888cb5258c18688c276cb072d8ba8fbaa21c7a50265a7af5fc2155a0efc3948ba9590df0b822ba288b5a981395a11a721f1b338bd548f953ebecdbdea79628c215b31a3f44d5493c42a5ff2c26fdd43468b89871d52b9d28a99be14f01c5a929dff61fceababcb02fa83b25fb2cdf6a847838d8de9eb4be35110c8530b7bf888d16eb13dec597cf1994724d018800b30b1bedf0822e50272016f45b73342d6c737a857b872ff7718795f0c643589afc2955a4720d9155fd5b0897584218fa83bb4b087f89a1d72b16f58d30eb84e4153706d9cf1fce6275a0dd82173c146cd2621ad541558fa30794b1875fcb2ed67412dc87d63c771318b6f67cbc2490530c07b933a48267e0eec3e2e3b386d018e67b37224951cc6f75f075f6142aac2c3dc382780cdbd39d00dfab65107cde96d15cdb8ec184464b05869c64bb64b5a1f94f027ff66f9aed8e4103e9afe5c0c38621660b5ac61749076c5eb9716a3a1f263e8a0ea69215f000ebfbef93cb421f32774f5babbf803a8f4833aedb5bfe88c2904e9aa6a8231b1816c4bc8d0152ddf808512e9c83eda316cf72c360f976c13894761f3dca9f924cf42a1a1803c1d546c245da60930e22b34119c9694653155f0dccdad18b59101498c76f99be8f08be498783d854a46bcb38b2252018c90d453cbd9ff71f912d109778366c4f579a619c96b2f85a7c7b66ef9fcffa6ab9de7e959863ae7b4857a9f7fe59ebd14d6e37a039c3c70e2d788e2cefc54f1f6e31251b9210b0492c83f073bea0e11dbaf099e478819b9a48f0d2aa28039775f3bb083dcb0fabd907676673c0c241a95dc480fa81339f45e971e92fd5553d1083680f44b907842ffb95f8533245cdf8894a8bf26c78a96621f27d4db5c376508e21d371e0a2efbb263e53096bb6a5b1f5b154e5defb182fe042ce2154ccf90cce41d0d493ba9823578d53adf237f11ea4f20a247b5e2e1d89943ca9dfcadc8506fe004301431cc7978cc83a57e7ec9c7c789bae0aa3617c2f60bda12ea56f90958783897e62838fde05efeafec353fa958da0deb130cfe7fe041e77a6edb2314a96f8660aebd0056284b00b45b85cf62965e439b537738cd8f8733d09a282231a56c3b6dd1bc57dd98fe368afff6334bec868946aeb9c1852e30b2d1ead4de15b0a40e0007bcf7e974a31110c4f203ce4be43cc85303858d5337c2b02f70788b4d93fe8518d02c0df8c54476396a8c8ce5909b3b46428803f8e13bae424527af02ddc8127c1d7dd18d23fcd0bc7b0b457caa8701db8d252de83a6a08e07b924a4e15fdde638b5ee9d9c6693237018d3fa9d2a6dbf06aa4c33231e77187ccf0b69365a5c1a7eac06b9ccb80947b3b6dce1168c50fac8dd5bac2b264d4700bedac4286f2689f04f35ade225edbce7226dffeaea56d43cf41255c13599cc990713eacb0fda6352556e97fa47ef1e7c96bce8b1dc841486e0004054f1a4ec379ef371d6a2dcc589b72c32f3d00d3ed0fa373e88e6a0bdbf40bffa6d6a4ab2f743dad5ddb90830b5b04de37420f46f2a00251129ca181099871e1ac7f89ad9827c5dc47e8d5e8273d425f8ddfa0bfb79026d26c88b5c4bc981cf03b4cc8b50e1c9e948af03431ea6cf109e641f9218408b8101c98db2954401351d6fe089dc0175ee5040de8e631cf331f4735f7ae321e61ca619e119dc76d8cea73e700ebda1811113e1ad0551cc28e5d95f22dd74993d3070fb766041f69027a5f86cf46e94bc404d38e63bca3c7dda97c0b83b486ed984f1db608bebcdc0f98c9161d6e4f4f0349bc4e58d79f0ef7608401adc5500c00a6dc728ab2b4e4450f83313071dc63720851ec77424b219e5e5c81d40c44ae828fd00d870e3f0c5bb73a08160fbb92f92e018c876569fb4e97b560fb55ef98edfead006e72cf7ad0d8c4dfe157c0d44fa748c953dca494c33c74b41bbe6132088facfbe0940022867716974fa913cce0b9e80956bfdb792dca5aeed0d624b92256c977e9d2a9e801d3eaad543a03b67acc3825e1bf1ed868803d4fd9ca5e8a42dcba757d39350a02a5e87145208c0b88d9a9053fcdda8edac559fe712f4a44a9060b7b89c5fe506924208e00468ab2692784bc36e0702237225c5f77123e717f04b9cac5ca13580dbf83b5c40ff75cafedbf049c18b1240c064e544d352becf6efa861bab9ff9704ede8ed88cf6660775a7f0e054a88af36d998a563b80001ab2ec4f719bc0c3e07a6eda11025f37a37b924ee19faa7b2de5308e9700f610d0d3d29ebde7e4d6ad735ed7738d40ff5ed7b61f86c4eb3ad3081b13f6ba539bf71d1d60662450d753d0e6f14707a712aa132152b644ddaa7397622b48a4461d57b7d5d3e38c458f35e13efdd7f7087ba2876164d661eb5c27c39079b6c4f81b79c561717b4d2fc122f814d43bd11a4d9310dcb68b3d5173ba633e618deb11b1d9aa602c61c5f9b5d42e627d986efa4d6ad9fa271a87d166696c3adc8245ba97ef6e71e9659dbb31662adcb5d35afa0f0e82f663573a20ac7fac6cb6a90a05f510b0bad7c3511dae0f3c8619f8b9604e64ca38727cf29db79e27dfee9ec17b2503bee2e441043de70e97b1d77ff5462741194a8eb86117dea99824f4c63e7746ff58810e2be95d62350fb77693fc3db29240c17e1b1f716fa5a8a2cc3839ac952648a56fe63477e5d090170cccbee345182a6c98f801c1b928d3834a658738f605b0ad8b7ffd1bebfb4a7a0e053c4812d25c4438eca246c590e6fef6ee9adc44e53b41c12c039740b15357b35eeef461d3b6e5d3df0c8ba27434f3a19a77c6ab80c0c5db321d330785a5b8bcd023a35ea406d4e9ccde51424fee20276d08e11173d37b86cfab13cdf4a262e9455797998dd9e44e684fec660a450a7c8b4e7c0c59eaa6bb46757fde3d856e39ae472c545c1b80df14e9eb2a5d22c471740d425d23782751c12e16d65dac7161530f2b7a71d87bf00f72e66289f458022167e982bae19ce81f3ae30173bbfa1176e324e389c88afb7daef339efa90e59b6b7e1c7cee2eac37b4e3ba8d2542805ce49a3093b0ac552365a9df10ce752cc92e7b49128c469c39fd810a2e24633fb010f230926c7a3a64f89f988242f127df25b6ac4608623932fa079e3c5b0a10f898400816f40a4310fc8ac07afe75459fe8cf1fad3d97a99249705fa376c080b543c8b7f1c7b06c91a878cf56b84fe54bdb43538eed959040a5595689c2b4d647246221af176669b489f1e5b90f8a8c9037c4ccb63067605d777776d097dac4e13b13cd948df8b9605e6f9879fd53cd4f7710db253ac76e46e538c9e66f96cf79dd676984476c9a4733687c9f1dfa54d05a3993cc70ef74ca5d5bbd85729fc1930a2553b59f2350b67a60809b37fac8535a4ad525b6d95d232395601058189737cf29f22fc5faaa573d941aa74787fb922317f3773219dc04b00ee62505036803dd59a2c95c697726b0767b5546335c9b13e2b01d6bf8cef5f79d45f85536c7c186c3eb0a261e5af5acafc0f83852d195eff38d553642e9d317bc5a91c014ca88a362305374bb00243ab6524c8801d5890d7f3c80287cba7ac135325547ec1b1c8213ebcb989f586ef802f85220300fcca74b677ae73913dcd0fc0db722784abe4e83eb93c7de56a8ef300c5a51372c8681b43b03fcf62354e7d4b1df5e304a97c3dd5849762432abf3fb31ab47982f46b1c4c33d6fa8eb27c39f3456760005b77872717586e74361720bfab01d4906c8cae2da6b9e4be45c41d4cc7ba399d6882992b91219b7a17ce3f29610706e419cd66541745f68c73776a60831da00bb0fce8439bf3e875ddd77faa383a87bcf554e9a9cb3766238657551c736fbf9c7e733a1f5b2e620d53bad0be4587c9db8f4940ebf5e4c2e6afdc48208a928a0275640e3a08283f53c48a8896bd46f42601650fddf1d162ba28f313497c6d6e59467ed89a5bc70f18095dc5e3122017dc42294cb4dfb9d887ca20075adc07c911368e42bbd8ba15eb5977498874e61fa6b112b9628bb45f700034860ed348de0bafedfd3f3085227a5f0b50ac9ec82ea5f2949f3a5768712174322b76309e4db3a5f702c5190212ceaf4d18ca8f98a0641fc0adea7a5c765ddb8949d5800eac82e00e68a92e6e6acf2e26daaa3107de7545bac0cdc81107b4b7a1c83a91063c283ae076a871ee0816fde6097c30e4ec5532d751c1bfb484be6f0c71cd1151041d329f12576e36d5609e3cf3ea20c631be9e19f8c7c11208e555450366dbda3ea35738166f6cedcd98ae64cc86ce3243e9af29070f97704a277adc2bea8de8dfd17342b400e9f8f06f07b10f373f650034ef03f568d84954f7b159104596ba95217550019fc56f7a128f16ccb8f1336e173ab7c21e40e5e6ec38bfd1ebf5d63f865fecee5459c8ea0c4791d4e7dcd3675790da546f8b95e77935da183820977d466995a98c8aac594a65d984dbc329c39aaf808ec6f9a2a405b682d2b91b480a6d9269ad8a15815f4a9fa16a7b7b432d4346c6299118e684c01a1472e22237d6a5f30706badc40168b00120747b5796d5a9ab294ea9a29f868140abd99ff9bd7f77f1774b6de0c4ce9cbab6ab673ded1c462301718be6cc6ed6c7f47b7f09524918ffa3f2d972d524e5be14145426c4b66d1563b10b6f0e16ee18b8a67ceaca183c1a969f553388c0496e2ee6ba7b329218b2fb4885e87ca9f3425fe3337db8883964334913f711644882af10ba84b2117aa3601b8fa9dfef76c6b7b50960a835af9a905336e1c6206cab3001a488d34a2478758d7632897ef4f1c220861da9a78f30b9f6087df7e940b8d802776f55216fb169e17620b14dffeb8d55bf6b94c18ddf34da0c3ef76b3e3c40ff3e76f81f750098b510dfbc2993dbfd25a2c42a1e3be148625b3397e44a91a5c229e3237e0e93d7b96a679d0b7e47a6dbfa84b9513c98948e6c5e2a4aab7e6f7b73e0e9055fe35b8a9b5980cacd1fef3d73f8cadc631e493345ca78f6a4035abd398d98d3c5f83a5458378b013d37286b0c7f6616f522bee5606be1e61510724210b5d46bb88178acf75bfbd041cc0302b7fa2c08fded90cc2043888e2f9e87a87c2dedf3b75bdb176c8a8beb7e39b29b09f7419f942f59bf816edb3663e013a0a223009b4c6aa7a37048706446771389e0cb238dcbdd46265da21220507c0d8198a98687bd2ad2e20c3515e1ef27242113b50d1d36ac6da26ab05b04f0e92501d713d7b55d946394fab98e8f649dbbc1b3998ca5d9627eb13bd046c0a79c7a2dbe411c2c1c9d2087fc24144f60996df3ec69b9e0d4e9980416d064ddc8e16409548c5e734fcd9faa9de2ae300a5b4d8576e800bf139ac21ebc98cf01623fde0a6fe4385808fbb31591393d594a2d6300e802e7efc639c67c4f21bbfc9b9fc034370bd18c773826713ab2b5cdb5b673b53b63516a64217e15857fb273cc2689f4a4624b6e29ec2be3fb6e3069169e30612f11079249099e9b34c33a2236783e243bf6441b48fa45ef1c138c8cee11cba6bb81a16dedccb6ca52da04bb3da24c88670b46e5148c5237024a6f0779b483b180c5a7403c53f9a795a4654f203d3243066445d6ed29f2453cb6ab322ae6386062b330ccac20be8c1a32a62f0d89ea972c10e3b1a53d298ac44b0034f669755975da31e574bf2428c2f99f21601fae43258287d7b6e4562ee036c75a937f5bece87a2892ca048f75823586b5041e3c6b4e915cb76cefe7776fbffbfd7c87704dd164691708130c98c407a890a4f089c6cab2a01d3631fa0c8c4db192fe055ef9cc113005a22e2780d8f23dc087a1ff01af5c8688adc9aa1333116b44f1cdfd8071a226b2c5c85214c8faebd2e2f34f70ca14c644eaa2c125f91e2d84bdc1984984a4beb85ca2ca886f97ab24760f4e6835ee6ebe3e79d2def0815e9a54f24baf7af08de72f2f5e9008f99ce21781dcecff089065dd4737d3bb51192544eac668a68ca35a9fc56a2ce1a35065d4b721694fde5b2c889b2bd8063824fb4ae881f693724293178b8bab33eed5f254da82f9320b70b2cac079137da816df46361bc6bba9acf424a7b9e3963fb8579c29e2cb2856106da96cb2a2ec9e8ff0330a1c1dc6cc795709a909c3ce2c4f1ff037ac2141a3a62d24af050e3cc92568c137ac1a00383483804f7bc948c5dbacbcecee230c685c13de5a232afa989cdc2dfad4857b936c7652fe3de8703fbea2917a3160f76fdfdce3f8b21b433a7fa972e583607b8766ff83e409aba7636433544561ade48d44f52a579006aa211a98e5522f7b62ee5e175c8e2908b5d7b81da2d5aeb5798ba241558cb7ae6d6ba10f63aa3bef507041b2e4ffebb4a12a34f0af0e50258e6e5b81561c8abfd0ae61a53519e3e6d4932f2ef458b78c1a4e67416c3490c4353c452b212725aeb90f7921031b5215830e03c43bfe322ebc20ea4e38b3f16d73f4cbe981ea709c407d57cd39f77bc714c74eb9971665005b731603b0bc7ae05a6bc6fe0e0851e06ea20594cf83d9d449bfd9d94ab2f9ed87eef3541c9ea308600266629f761df2eab779a563ca30717dde96295b25929bcf5ff7dadf55a402c5e883fe828117a3789bd3042bda385cb07877e4c7cd0a9566158c7e822e052d14ec4532b32a06206574805eb283332d52a223a6410fa215fc065607b09b8ff42b70b261254003524a7be1f3db461887d87956014fafb8b6911c2ed6845c5eee75ae72f005511a8f540805e4432210443f151292aa1ac09644941f3deee5b9d35958ed1dd05ce2683ffa68a98273562c849f10fda3bd62dc69e68ca58d4bae32b1f459018c8e63936c9189df091a37aee8728f88626796eba3436099d2802bbf384bedabd9367704737c9ec421a15e5e4a89c064b2d0b0343dbdb06c2b22c65b0985135256df260424e4d486ed021d51356b81c197fc942c3e47208bbdf269f5e1849745ddd26f6929e3f1553f4a7f666947738937e4c283881576d4964414dde9a1ad7efab604e5980bb25641918128865e77719ee46c0afaf86f1ab13ff7e5604d0f287de9584b23363be92c25327bb72622de13e129cd8368931ebcaae24c8a52c0a80fee2d3c999b8c424325544531db04282dcaab440a968e7e09c5c1124a0393963c86c8bc9a53bc94a5a53e0ffd6499ced387ead6309e0d9ffb0ae50ce3964b306fb43018d5530f183cc9a5c756e58499e17f65a9897a3e2e45d05b5332c1427ab6d68f391941c65589eba65faf4f0725986b93690e906ce32d7cae275ad0a66ed1ec7476fd60a4ed7bcf4861add8390eb69b0052c327126e5a70bff0880797b6463f247ea0e170edd42880476edd5ddefe8a83f04c573b4102767994f971b14ac193c4b74d1634be6fe22fae43abbc6fc71ae6e1bc1cc70914e5f7e1713af20903b6a1363d21e36b48a2cb584a3ada8449746b8381d00f7ec1f323cf41ca9dd4c0d44c8bfedfef097537629370b5f18d7dc75ce14153f65b052baefc0f30101c81075e0d9b0e12c89906a46afdada97f9d5dcc7774160e41a2233f9e51a49973932f61a0e454236c38c7464188fd291c8c473e7a03d4835384ae5eaa24daa0272855080147e7d7469b51c7e41d60ad1582e5c08288a89d636a91e561d0afde75b45c606aa1814733e944525f58c84c49c15e33f9d41cc36a99af19b646cabbd53e9edbbc19cf4071d345b4cbd53efcc7493686a28ba0a1ca27bcd35237e7af020414dae9999b9cb28c966d379763a313377d17b770c3a1cb9c1364fb185ec1f87b68fe03926e7a8f3ab1c449c3949d7b223f45a3c247fee725d413c64cb5b19a1c961733593f0affb667ad44169db4c24264a3a98df2d8cef772b79d4b8468c9ed659195d35259cc8973c0f60a2b216f4308a7b99e73c6343be27544a055d08a8fd80d1bc0a0f728a217890eed95d843025caa8a4e5604437b23c729f81c7596f3da183d1a25fca0f5320d3d41befc1f821d30fc230014f5844b8e8ef7cf8bd6e5a807a68641ee05bf63579220bedc59a7255d7c740a3c4f88300bff0372efe84ae8308b0e24f5389431ac13ea05ba07274309406d9649459487ba16043201eefc8b2213a7ee83ee607a2f8877dcab5a8a1eafd16c6de0b5e13ecb164feee09d05d322d5c5101f348464d91ca6fed48a990338ce600795a639b7614486c333d61e0bc79d75251c0b973f3199a22fe5ebc4b090458bb3f4e2c007ad1b484661b0f5ce3d3ed09841ef05bd92963609e87135cca6d9c20d60efc4b83fe04cbc6847ec4b3afe433ebc952039bf9acf57cf51ef4386191125df79ac7e333df16c24e9658d707c1def571712782490ad4ca8ca09fb20fc6c6c8e81a0a1420dafda4a69cfe301cf13e92121040d2e8772762016fe4eec9a8cf8c1ffb110efd4be38f8664fd08fdee4e8c06d7afba674e02581b52a3ae2b0a0050ee6ad64e40b12a5299771cd78d921589c87b618f57d53fdd863ac17728bde946ddb61c48f58038bb66ca761643a7da5198ce3a38e5828a408c23bb1e0f775d20b2c95ea3ad5417a8b445208bcf14dfd133321a18f9267be759ec260b06b5664abac287a303c366cb17509432a397042b00beaa047be30564aaf5d24c543194ef4d483631de760e8ca6eca114c8eb0e6fa1217edb76168cdefc448ceadaba8e8439f4ca3588b59bdbc8a65728c188ad38aefc5ed261ff40c887990cff18b3d9bf787379f31827d8d6ee5ebcba992f470d1aef8b37fd27947f31325fe39bb65059522b42af4acbf9c76607a186040844105e48da1061a9d52c010b464decf864681be2e27c330bc5c3cdf1469a50d5ec902e6d9e207c72c3c849a33421feb6fc43f1a06e559a6e8750d182598c52aa01d295ad18233980a456ec60af40873c43c4f25c8b6335234d7948a7b206245729d56feb2721fde01422330694aeae06dad973f2612d3f21abe757c399a606bc287ab74c01b2762e7549daae4249cdb93016f7d593de48abbd5a8a42538d3107d1298fa004342d985bb6b379126407f9ecd08e8e898b2957551590546c75475d3ac54946a8ccad4efebdfbdd36a2534cb0a1b02ab7aa3c2d487a0397a6ab841a141da54a41b7b70653b983a46e824e64516840366240b6123031e6db3424ee114a8f4ad6ccdc674f900c84d220e2701e185d8ba31a564bb59ca4d91280266eccd369428dde30c877af30c97e0acf7095cba1308f28e2908c2c1c0cb476ab6b237a5c47c345c16f2d6168e5b58495c83ab0a78977981281163570ffa5d838cf97d34e5c268f501112a7bee21a0f801b159800693dbf63374f6b0e63f04803d133eb5be9d3805bf714faec589987c75674c913131c6d5bde7c66db8d7ca71bc21cbe62e767f6c86feb699b0c8ca7c498c036171e440bf2d9e60b92465a18c562e77e62f38de2f6a67cd2d7a046f4b88d6250f76e08227291bdb152a5bf719b81b8267a70ba9d968dc385044a45a1952f40692d2e88f6a241a98eaa6c01486bb940b41705ab05de5a81f3c5afbbd6e5354291bf1423e0d74387297e49a92966430bb94c16dbd421ee9bcf046f32e69d67612496811ca3848ce663b3318f49d3f850647405c49698f9dec58a1081da7617abbfe3f24a4baa15a5e5ba8beae49411d891448e48700cdbcf2ce943ea8fefd2fa45fec1cf14e86900b6744e2abcb8c422739b7dc8f2f91a6c8aa70fd93e7f3198c122fb8b614f4be866b58caf58d8a48471ebaee405020a1022eba9a1072d7b26e6222f9e7bd12f83dc22c7b115befd369c8f520323bcfae691babcb20a92f899ec22b216b173596ef544e310f12a0960cb6f5c90adc5a76de04a3161d43958bb3a7c22bac9df86d56c27afb9db14245a6cec46833425bcab611c02282746237405cbd75348aff92a050179ddd7fbe6f53574c516b30c2f3628fb39eecaaa58f1e639159aa5d72b56a48ab6807b16cb8fa93e4cd98322d5ff9fb6a8e7ea0d3325ee4de732186341f6168d93690d4cd98b2a55ff12c4c8c5fee4622c862d9584db43950afa9f655cf4217967069ee8806e473346a877f3a21f440e8eb9afc9e062e27a132771d510299f1afd71e170ba6361a4a64ebf90e742fe57da337b3dff4b215fd9651f34ba9fa78c70006d25ae7aac866bcff927a03fd80c62c53bf27102e6c323f69b59b54fe2aa67f17dfe983bc2c0ad3c488f3d55759e224260734b80084187fc883126b8a92a3b8aa219c5dfd137a8be64c5ae84eadfb871df8ed3caf22050f99150511aad6b56f1fdd8b3644de61409a0a56e29f168fef317e3d941a5ec0776cc4af56f1dc99f4df2fa67bcaeb93f8cbb8d59ecf4f6b52eb3318c3f14755bf6fdae18c878e3f14e4209aea9cd38c3b7d65b6804c89040e0edffe65fdfb6b1f9bed50d471ce3168b8fea7a9e4ce49940bda3722615f72a1431fe6ffef4062750ec545789fb376eb838a5437ff54fe9db40e88ae2ea6ec0144eb2790f94664c133e9d8a40207401bcd0d35c99b438e6c60f2f3ac6dc5635a2fedd08f62d625583a97b67baffa86d08d972623c3ffe98582456fcbfba6342ac3abbabffa2c3f69333ef97f8a33b7473076f54852ea13fc78338a58c69a88aa7f04301649ffea718571b5478bea33c9879f4ef5bb44c41d462524e5b3bf1321e92abf2a002ba0ab93ccc043ecd9134a055da32b80234068102d7e5e7f402816d9e217155e051861b70da986a9f4dce0641148da5d2eb96beba7a09b50e59c2625e83a228f2dac6a21c9e0f3c51beb6a966cba0060683810eae184e0e6ed2f5deb182e69d41a279286fb4ee6018a800301a2c81301ad04209227cd4ebcb5a48895d4a054a683e8b7b904be469c02235a0ef266bd6df6e5f9001af603e0e1a688d778cd397abbf91386b7097d7f44e5a730dea2bb749f74c0d3fc4ec09f3a02a155c2bb78ea1b1b962905b3a12826fbdc6619740988cf52f1fe73657f926532b91960a6cc098f7cb780f924cdefc4f1832845a914f356775e16657aed485168d6fe116079eeaf8bfa066ed745a81421494e2d5ca4e230d4e060bef1fad55b9f9722b6f0c84df2a30cbd5fc426879b4122c1b25aa3abe9cd3b761018e1adc310f6621f247b92a0a1a298a1b649da4c50f0bdba5181243bda13a7f6df1040ab76b820fa35135c1ce203ddb826605877714a65baa3833f9d2d8a69268101b2bb2532e1109483a16a0adbb8f0bb81ade207ac158402b66186fe7ed01c533a71c29d92afcc71943dd4aadeb5b4134efa6db00ecd7776685a72a2c1503664334bc916f419e83d800b08f9a9b553c0268574d314b42a72ef0338626fc58c3e99ff413e2fbd347cf4907f0205800f701034219a09514ef0fbae6e19e1dacfe6beac2e12d43de89fe5c1bf19f3a35f56d36a5ffb05d2a00b595ced1513673115b1da25debc80076146ecb608447d4db185e6f29897844d686baa57b3fa396faddf030b69f663ec96e63f13edd8a6527d04268b8ea4091b42a078c306dcc719b885458382c1e5a04c46cd310cfa604445cafbcb0d76f093e94478e0c016bb66094687e200cf0f20a3ef9519d8ec1395ab78087ca7d1451bc9d97ac55f1b711a20935baf1f7157d6c3f2901f815493b35751802323cba3a30239a4d6749d6f1e0217354708477a3cfd93c2b6f8ab0ee239a1d19fa10fa04ceae60e46f750d894b1664cd850ad68fdbfab3d49ebd1d31a7a1f6c488630325d528ab38574104f85002f40422c28a5177c010cc4d6f277d3eeea20be1a8049e9f93c6f6682425646ce9ee4e45e3093c0620abb4d2d25e0378667e41239ca04ad8ce1a9662ff82653f8a0e8f71a7012af5eb9b9d41f5617974d180e695ad5a2d28686314dbe6bc78628796b82168aa543e0229260b9290867e6368ed98ad95cf9db9ef635d93dae715475df751c43215c06102fc1d82aedfb94daab9c67b320afd81c66cefeb127e48ac0409f3eb8cd77dcae3a43ed6db11d1a4a960cf34887e2a133e9f22fc3b604d1825c489ff8fab0a1bc9844937c3000097cb7edd6c82902c579a1ec159a64904e1a9a6876c94cb77b143f852cd5cac4feadc8936c7558213250b58371b743f5d7138226b437931ce5fc5c29ea52539696c3093e729b4fcf26a084d8b8af710ebea40f1bc6aa7676053dc0067a64eddf51608c8dad6e5307799eedb2264a64e9132c48c9335c71d6c1696d0e41c92320b0bf09de1d4badd0cc1939d0f1549cf194559fc74fd1fcf66f45a5c42245be5990693d4cede8afe094413fbe757e10ec689e1032b73903468eb60669369f9196fc3c3522995b8a448cc6f0f7b1609d31c84590235eb1aff4f509a5e5a4d49fb0b70b38726d525c39747b44116b886acf1637e819378ce94a66781867c3c6b92f32bed869f91c8721ded694ae8840fe0258239035306ec4475521e8d04de097d25d044a37eddea3a1a725e6ae6429d08bc0d06a793cf901266a65066acb086904efcf8f7489a0a4a8ed788e00895112549a39ccf3b9f458cc820a36c87dc1690e8df4c3f6fafdffe1f58b5cb82928a2054e1888422fb1b57826d7088bd7111a878004aaea57daa1e85d50ea561536321984be6fdb3297d8570b5e3915e5873ed295959a1ac9bce01941f5f9af03ed4c3a13428af028342c86a01ad06e3dfd22b3743fbc8b30a4f08a604cf8aa7b98db5406b26c388c06b2b5d14e6b6020f27eb2627670d6ed6739a4ecce0662ff173d3abd9072cba91f19257cbf84e23d3cb6afaa56ca845be97c4beb7801ac46aa0fb2c6dc98169dcb6e10a6c345c4f336dea75ec2c9e0c37de9a332d4c7efcb05d47ce0a071cd73dd0d7d85fcd240b28510c1717fa99ecf463e9ca66d6e7b3e08d41b61dfbe5eb206b36ea54808f727a4c9d2c4c62b7106bbdd4f90a64d518325c33944c177342290f0fb04d6016284b40c1912118f58896316ea1e4b84de281c04c4cf4e509207e4f7bf6c5242205d2b8db1227484a61b86dac9700d1d5bfaddbb61c851cc44422c581513e865bc7a250561a970513057bcfd60bf4b4973e8aa04888ea2f408d0cae504a590cfd25180b0ca047d8e696534f686995382c81b70ac31eca56f1bfc3da72f6b3d422378f82acf8c46fad4f0805fd2d0905370c9417543fabd609180b2ca96f5cd56f71e0f9b694b8768528fd426f793a326f8d92b371e91b1c69e50c6d3e2c2befa84816bf6c047ea3776779ea35e6aff7324f1481876c0f02ffc27a170766042c62bab5582be0a40e03b7c58053203497beb0065f4ccb5ea4ed38b568a46b389a4a0bbbc4d26222210653bfc17d79fed01283fb86c8f29cbcc0cfb36bba15e0f23cea1ee4ecfeec5add477c1b24ce6e4400473966efd2b3a476d3d89812deb92bb0ba1d0c766e5259eea187b6b548ec6cbe67f784ddedc1c06b4356efe780cfb7b44f5aa6e2643fbdbb367430ba5c54935fc35871bee5ffc3b263577c2c26c640bc5ef893fdb1c68f1e1cb617afe0e633c3feca745d3e78726b3b5fbd57a647bc5f7c375be991b832a04ad6f268f915b1e706e4f4614c933f839d2e0c5a588d0649527df54268172fe891b95886b00a44ee2157c5ca5a669cc1ac5baea398e9f1aa2ad5fbdaef419d5fd062d655b065e1a401af65622a97fe8b769d237fcf47abdc6b605d0ff33f68e9508dc991762390539680e5c0b45ba8da2cee1d5ca9166e002fb53aa3739e9f73c1ddb762f854f510a350e54d0b72f509fe72435cca64fce5460d2a173868bb7f537fe8c168dfc656243dc7f09b82a6a6583c2cb76265c71b86edb592cb6c67f7e8dcc2980f783b53bcab040e7e778c0367c0796a9b84ebfe189781a399dcbc6e66e7037cbd0c6e2ebf67ab08ed12b75ccb927e602c21cc495a7575fa8160b91066becdea66a5b994321afd3530456ab7b957932d1033a5537c0292a9c043abb13484e9db893ba56b13d67865fd0ab00e0951781910dc77500ef39adf751b02ebc2d099a77951cb8ec21b7f228c56417ab8437ab99ac69154b45ee17c22af5bd1c824f3020b69ceb966c8b865112cd0f307012581607c5d880bd8b06d84d693a1a98dfcdeaca28a79763e854f410361bd26fb8b4af03b955d192a90d13ebb6f8e2a31d22fa4012221cae36499785f13f448251e44c63230b5ac2e777f9bf33bfc5fd4dda342f6b699b739a7eb023101ce47e333f6d36aade497925215248eae14dabc8a025f64325a7a50e16cba3a266d692a42b5f824b08c3854c96524e3f547af132d9bd516bd959d59a4c8df4f16a38856be90b488eb45858a5f0bbd384ee09835a287372037bdae8e2cb440a3da94dd6864cbe5e9d108b085c069046821a3d725aa94cdd5747f74746d08d80238ee2911d13087d16b92ba99e5531d98ea6778e9294e9e24e173780fc59f5575ed94269f8a9f477dd3ab542d677870807ac16bd3c3bea4f3ce5244a9da29a7291141a6c8bc46043a7677bb5520885a351dc7880b8d93f406740c1f96c08e077c6dbe79e50d9860a3615e8260bdf2e0204b0f77e725c692aea3eab94b3176d4a34cb00178f1286ba146f7c89c9315244abb102289a1916d37b2db9adc5b4a99a40c450b820b2e0b3f7502a9a6c7c09f8063a2b7d35bb497b1ef9351507ec91f1a1a82f2a287f2152e3ee9a15c9cb528fd50ee668fd8811facbcd142050f3a0082e0ca963349c4e88973a5a45e79538b47fa5aa3ca90a59395d9846c7e7c85163947bb1be7e50843960eb6e997ee66d3d2cb6c7a949fbeed412dde3aabb33a9b893f18bff452319ea789f03ec62f69225b3d781f43eb2a91180f43ebeaec2de51cef050f8a07bad0bd679dce5d7fc0866a23bd6724a47f914b72e772893705351573ded83642d622b306fedc1392c9914ddf861212e9c367a1ab122b9d94abced379369290b8277aa40ff3e7204c5b579f4832970b2b12d28b746b558c2b121e0b75f675e12eeb42fb309ef74a7aa7a4c4d33aff180fe395b4c7d09a8773f9b5ed8fedf795b20e7c18aff4bbccfbdd4bc1d04acfd3bb20b99ddb36a794715d9afd2ecf30d5b36b6b6d02b85d03d137877e165576ee032d4842b8c1b77917d2abab365ddbafb8542eea5af8cca6d5b5bc699723dcfe63cd8a35d189638d4af98129a65459d5fbd66badb5d65bc10dbecda00e04ef579f3bcd29ba7c3e5f112759de8485ac4d925d5625158bcd6f9795caae5a9b56ae4d2b17f05691528a77c5788bb531cc482c5e7fcd3a69e9a1fc3ff7a2d253f5c0dd2b7d8fdd2be9eaf39eaab7237bec5ee995f494aeea127a283d4f4f855097e82b690f66ef475da23fc24e631be3cbf9d35b2f7ef660d0ebceb39a0ae92bd2e774ee5f6420f8c90d557339e97399f4316054b1fade92a6e14b35cc483f6b499a49e72cd6a2907eac45891f66a4d7b9f62c722904dce2d7c0dc51ade4aeb5d65a8f90909082e436d20c49f72e427021e4822e405d8b67f1506e754f6b512e6ebabfd532d0e5ff9f3537fba4ddebff599d6a922e79bb6a9d75895fbfc869ccdb95b607128469b378309b40b76eeb1eca5d64ba8f0091487ff4d5e74d9469ebbe0cdff6b6163f6b51ba179132f831764a3c183078b55ea43f42ca25f836245de28df4f6c15c56df06c1c4c6c87e65653fb2313130cf722d2e2f5d5f5f5d5eb87e65ee732bc7722bf795fdbabec0c4c6c8c8c6c4c0bebae815c5a259548bcb8b172e8a55ebaf8cfaca7e3ba6fd34bb62f09e94bec464aefca38f0123f332f8b687aa48796e700e1a34a8ccc1f6fdf792ee0830edab4b1e9bd6a28e8230ed168f8494e73e6aa1cb405a68dd05b5cde26b9bc5b3d01160da406c7f796cf069565d2aa1c7ee6160d525fa2578307bd4aa2ed12741e961e8a9297ae5d3b32e51f54ade85f1251923571f8cddee676f89f7b3a754e351a5b4d35f977cb6afd9f6600ec2b4c3e7651d8fa5d7cdb407b3b7447bbbd749d1deee696fa7a97af4a9ed0eda3467f4d657e4286c677fb3919d596c84dd28d3bd02e756646a34c3657fa51dee897045396a86d325deb8779fbdf5d65b6fadbbab7479b7d6dfd5dd55babc4badeaf3f67d52cabffb122bf1947619aa56227712c2ed9a88ee22e7721eae28d38dcb731365bab586b20b6577e23cacec51b267d5b257b995923164e9577bee6864de34cbe33f6f0a9f7e03d97d2e017d06321d7309e8d376f4917220bf2af1d1b9afa0ab5dafe84ac0ec5cbc6839efeada35c44649aed2dd973ca5afcf44c39f7c5ee53c57424656abfae53cfa4ab966d525fabbab5d89f328fdb2fa6a97f3d87479d3ac89ed94d5a3ef5eb3c6dc5cbca9de0b88f1fa52270c1150fa1c9901cc106532cc49531fcf5aabdc95f828d926fbaaf447bb8a106f15726b2e83b84fab2ceb773536d6356bed62c25ff3cc86547546c59c47ab524e8263a6abb7cbb347576cfad56ad6a0978ed50fc2540661ca4549c8fa545720a0a6636e7ccea39f630be95eee74facea5fe7c2a04dc585fba97ee3ea557cee55a58028954ac3ab99618d6721efd7a55b1aaaf5a81be247740987881dc6b77cc6d5fc7dc567fc0867c7087f62dc6ce24bce2ac89baa42a6757f97b16ba28d27e367b3cc3339ca5c525e605ecab8bfaa815bd722c8ae557561bfbc6c87e6265605f78f635c16cb5118fb3dacc369bcdd99cb3b7d5c60c5543da05e19efd8bb41988f596e13cfa7857bd732010f9646e623375eccdc2dafe95252547a77b89b1e9b273cf0b6343c34f6c233a9ebc3b0af16c3105a82ea552c61147d11c446c6bf55add5d10e76eee5a541815e220d65f9d613ca3d57e3ea5d16a8e319ef3d27e16020f3ca6750f9ae66922e1cfdeed6c4c1c4571a4b55a0b9ff6f36be34ca4b45ae913c1338ca9ee31f31a0974109e61f2174a21626fc2cef30c8338771787b31eceb33ae8bd598b2229204ca9ff5cc25ff23c477188c336323071affd9241ec3e85b17972d3441134c1a7bbb9d454c350fcc9035fa41ec28f59030c79bcd95273c97e8ebc1bdcf6bda3782f6d76ef054910244192835dadd0b612f85125bc20026896628cc3b7ab1e9d67c71fb306f6eb6117cdea81844392334cf60b8166913912dc336c8d9f5df2c0ba34400bd9972a29695a3843bfc8f913e58624596cb85f50bc9cc4247276366796adc1b3fd43f0ad99f362cfb03581f4114c8079028615ba90f990a10a2c459c30d2a50a89bbc40b1189a4aa3f5b5c9ea0a303983131d420860a2346aabcc0439e313c448113cb50c0c48c152086c8d266893659539a90a2ca113990f5a175998256a3ccb035a3b1c982251447dcb8c6cc9838ffdd0592fe888622316738ddd3d19821c7314a84f814d861801fee15337d1295a7017dc0273079f7710d7188432cc50af64f121a46a93f4dde7d5e75baa101fef2a95e3ccb84ed9b43b5b699a6214106bb4b43835d71f7eb0e01bbdab9749f96c98d0b62a72c1876dc82145534118420365631f491e008b23a3dc0c1227302dc4265493ce2ea22b6c4501353e508de4d3130a8b1dce7aa7222172db46113b2b667985814b628c4faec92acfdc4e2ccc2c4983082b1a6ed98bac89cd8d716da334cac875df2c04015c48c87a47b862911dbf4e7076c48fa4d969cd65a4be23b77fe8b11b416bc548706b6dca75ff54829d6f75ef05e0d0c3066b1d7d39c117e89260cc3d0da7b7fb728221a0a97d411004890e5b85d28419623edc52167e56c36239ff64c97b3afefa3f3a69fd9d7d903a9b330d415d73a67504c0150872c475ccd3faad609d925dc1da45e6d41544eb610bfa1bb20b45d4fd5beadba14da25f865f8330d8220d30ec35aeb6f6bf7e3195e08d26d49ffde2fc9d944ff5e7af575fa46146d2e8771a5d47105ddbdd65aad056dadb6ea5afd5af2c7af56038cdd7b6fad3b9aacad1498c1709be6684726bfb7561c087e2d49100449ba4baa5d67f94c37ea5fab1e719ac4157091e5b81d07fe0866dc086a1c54adb914023ee166b8ad8339c26df58f3983feacb34b08c01602ee9f5df9d3b0fb57b22e4d9a5b5bc35cb533ebd63ebed6ba1e248a733ae19067adbbbd61ffebd4e9ac178b68fd6998e792b50ac0b5566b2bfd4a75dd56b163379890a16187b026b26879c091256f7e7bc888f90157194126ceec8f2001b326861692b44900970c4f546db921e2c9d39c01c111b2cc3d5955a1609f90e20e146990a0c3a48733338d11487e90723565cb145f45e0217351a8604416953016ca1c11449aabb12e3cd0f961f71028799a91bb6708cb14352f00813503561460a4e89304123f40e9954cdb5a718c28464d9cd93e2a63440a5b7cf89386ab6797f0c1cf1826a2209963a567adb5d65aa6336449d6f7aae7f6c29120a24081c99a2da2979a3661ce4e152b209933a84c49cf3e6f628bbdee4abd8c48cef9b9397fee100c79f70c539366974cb50c129b057629a94cb86e55a3c5e2ab31cb54f10d2c34f15297b01a2849e6765d06d9ede9bc999e3a98fca687210d1453b86a942cd13a62c5828e16beb091315c6a5fe42c075a0f244dcae5c3c6891b3647c624d60872b3e609167ba271d375efb5f7525a0df4592d042dfe5c9d2068afbdf6da5bc17aeb9df75eece53768f064ec063e5795668fc1fa21b6bb27bbedcfa89d596a9966996e4ab1f59d57030ce0c25af787e00cac153fc6fa826538dc8d7f8240974fefcec35d5de27e82fb5b0dbc007eeb49973728c843c25d650036be876640970050d2e5d0633d04ef2a03a0e029025dfa006cfcd60400d065048f07f05b43bac44fc100867e0b00363c8800630c00086ee89282b7e1c18ddfb211812e19780078f05b58974a7f3dd046aab6ee43a04b00fc8ddfa2409710bc0d9e2e697c037a08c6e1089e9e023d64f49f400f1929f8ad0968e892f711e821244e970dfc901e42e27e6be89f7449e329f82dd765043fc1d7dc8176f1441b10553d64ac80c8852e89de6eb9d8a0d6c843c2a7dff2e7a18f749941c84158418d770e3c035db6f8500f21f7d6912ec317e240e8b7a25e9739c20a5ae0104759f015e82163d56505ef7ac8587fcbbf852e8f3e4a0f21f756a8cb166f05a08d84bf65df025dd6b7e0b72ad0a57f0535fe490f09a330117691e3a3f490b1862ea3fe490f196bfcd6d3bf2eff5de821e4de22d2a58b17d243c85d65036d84e8b7843e872e6b7c8edf8ad2e5d3473d54c52007e02fc84ebf2337bd8e2cc1e788b2a0825e0ec0efecf450b9e97164099e821c809f203bfd8ddcf436b2045f2307c0c99eff949dae9a9448a0ddca79f3694400000898f28b7f2023bd0359f733328b97915f7c8c8cf430b2ee97328be7e517df40467a06b2ee95328bdf25e9fcf9c57c1719e928eba2ecf92d328bf9b94cf42bb2d01b65a22f22e2b2e70f6521e7a2ed5b069384f9d1d9b65c9f14f9dab36b393cc28a8d963d66704d1123fc6c31d3f26c83c71c7c28800773950df414ed6df03757e1404f796f83b7b98a00f454ed6da0aba64b50f56ba055f8de74095c978e65cf9fee13a2cac0957ea03b8b3696a7c89f1a5f88be05b329e79ee6bcb47eed31b25983b6fd433bd309cc63b346c6422cbadc79e00ffc45d12fc3acf91fc2d9fe33a4126a8559be31d8672ef98352881519db47fa4ca72b064a315664fb253bb2fda5b8f21af89b33aa034d2ad5d85cf29fb59ba33e60b3cb302b2aeade92ee114afa27ec306bcec8fa51ad23f7512e176679d305ab4e20c6f782c1a1349492e54013079a845963643d2964098255fb5edb40fcfbd5ce71a08a0cc9c231e7f9b7b8429620d80ec7a89025c8b57506f7c5877210ac3add1f069b815d855c988af3b4361dbbbfea84abc2283927a492f2fe04e5fc5c8579aeb6bf037848aeea44e5421c1870d80244a74c142fd5890a8958152d332ebc50244a96960c2a188cc410041d16e6b8f99a520320af21bc76a0e2c3086315dfa664c889a6ac6c1fed89a66ccd1e7db86ae5c3f52a0866c1df0de1cc257f3bdbfb845284637386fb715e19f81ba17e0578c8b25ed1701e131397fbbb02afb8a27420c3316f2ac1393f326f2a6f1e6f2a41b0f0e74de52db3fd7d827913e8457781fd0cc0b76f7558e63c0f0539cfb91e8801e4aa4ee00f04b93617e8c59be60ffcdd32de74b5ae828162d589bcf1f4f4bffab5a7aa5a07c2682379e87abc4d57a980a357d3ba6a457b359bed898ce4dbc6a7ea81686c59573f24ebd5b2ae6a1ee1585d02c54030e7f9833fb0edffab4e35f0970bc15f98270cc9daec9179475d2273115d62ad5f7f615656750ac942aded64eec3311e561966856375c90137e02ff4f98756fee00f2c4380f30ce03cb10bee1edfae7ff7f8f61caf9e41bb6a5d0823886e7cdb01bfb02c1cf30fc9ee95375dacea547bb7bdfff572b32ed7f6aeed2d3e4843ba6fcf5dd690ac2ef9db72f8ab4bfeb51c8e8565db3f57c9736497e1186dcc012f716e408efeef2396d5d6629c736f9457fc483002f3b781842fde5eb4f9a6c15c7baf45d5dcf3fcc8ae668d8a456997ca97195605cba654e60cff1b45481c5b77012d75196cdc3f61a22121f22919b5e1c69be6763cf425e9ef57d59fe8e7a4fdad45d1469bed71d9affcca6e7f8f82c445ea6e7ffbd95bf157d5697a8975495e913992746297b36d7f7c9a3568efe1db7239eeab1d64cc25d09d4b9a692194f3fcc65316b2f42bbf7227fe944cfccd30874c0e0d744912a3cfe5a22f29d9938d4f0e3d7a48fa4fb386cdaf7a7c48fa7f053a30266b6a1e516587197a27d480f0814a6fc5e7f29468a67702ce4f6f85deb21044f1e932b840783278391da82019c361073d717a4eb482991a5ee8722106197afe7ee55846d96a15592ebfda442e84459ca48d0712b7271a375854c8e3068a203748666cc8714f346daa18bb9056882e3170db5a99e6ec69ae4bf0eb8f9932d5a2aa874c19145d09bb82c119da6e0d0f621778248f30ed1eb9b88f69b5a8d90defecd26633dad10e1fe1d085b5ee6447af78dc39ee8757c418db708f08c1166f798bb712ee0ec2b49dd25a6768132be85eaf757777771a75c3c66344913ae835f74f50f5bba06a575757b5d686b75e5baf1dc3b0080ce28ec00122b15808651d8ba9ee5e6bb5b6deeaa5ce19764518100441d0ce504abdf55a3a73a5903ab37eadcdde446fadd6cec09006ead5ce8680d4da19b520e82068b340f0aea194d23597265edad8b556d6803288d4ab05dfdeeb5dff75efbd985adfa0b516bc645dfe54cb71a7dd16cbe0dd79ef05ebeeff6915d7259fae0158cbe566f806d28e5290427b86e1299b19419264b718f03471d3c27366e319c3c2af3a1e304728d313138d272e2cbe3437e6e2e24b7397186b21c33dc3f074f1bca62bd442d4a60989a56cc80826b72b5c423f5cd9b4c64826b49ad4aafc6ea38d89255044adac1a13be2534aed18f92991532510e135c569726980b566292eca8e2ebd2c28e2b6258907c6139d9918395921d5b5a53085a6187152f616e7c4a7660e1ca7ba271b3068d1fb06762ca614c3e69b9ae0c7272d8f4c61c35363a56483a61b63a454827c0463b65b53b52ccf0e0405aad02d4c1a2c24496335128d1a3646220c3e6481144504abfa8a8080f0abb68b78b8a8a9e2422222292b1899e888888e89f7787883b469884705b484848c6167aa1c7e40b5be8736479b6d0bf901d2c4eb861c2dddede1ed3d93727bed461927341470eb647747cc0b56dbde6d08971268a375c6418162a854a3b0ce530b1c3395ae47879366ebadc69618c0c13e70e9e95a411a70be6da5445144785e9bdcc702a4c087689db158e9a5de318d93527068d6dc48d24cec25961fb5f2a3077948c15d1e60c1333c0e841909d2447804521d6f31e94e744d81241b8bbbf1739f70b194dbce1b2eb93b931b25dff7995e9081966d51fd8e5517eb3a6891dde78d9fefe4e7b8098a3264dd611afa5234800c14216b02170e8894af0ace6f16450eb00d2f6374898d0b37da422ce5d09fe1bb2b627a5521b9f6e2314cf84744977e572ae1916facd19d4f6f56b96897d0813850d25e42ee96fd6bc09fdfd6af6c370662d0e7188431c86427808e370180ae1218cc3212efca1f08542213c847138c48f0b7f28cfe9847b8ccb43592843d5f0fe0c8b0f5a1cdef0ee12a2c2a85ad6d11e6f5a081893642ef7cfe3317169713931f1be562effcd19d5fb686d2729bb3e4d974c4f784cb0feb914e1eb40104f3b593e9faf085875d3a66cd72fbb7eed5a6bad3d1c86a196375d8c9f76d163fc2290f0698f439cdf665d51715e2dcaf52ad7acba547f280be56a691fd2688eb1ffaa73b98bd589fe9c9c989878bcff5c8ee4aace559dfc47e6bee43171ed3afbb072d5a5fa1893375d92b9dcbfff74c9f454b93026c95cee9fc7c354e55399f3aafb715ef5ca356bacd8f5ab975903dc75e8b1581dab64bbfa0ff765d5a9c8e8a58888de88c8e889107d91d6853f7b453f7ba15151edc2e527cad5a5bab5847ee8a99637d1663f9499ea12ed85322d7cfc6006123a884110a499105e9bab08f9cf97f4a654fce7bcda55bf2a57ad5e402e9b336045b4f87e0568c8f9f835f8f84908b875a1a6b16fbc3fcf9fccdd0a9620678efa93be838db43ef8d873b5d65a7777af1ecc32107fb056fc13fb835eabbb9f2c6bb6c6e44006ec57eb0e0b34f05cdd9169fcb49ac90117c8aa35a051849c140c4b741bce5a062190f0ed8ba18318bf8eb9b1d665087e887752fc73ee5ae8cf5995f214ae224d9db21eef77798af6a7889e12cd53273ca066085f8f819f9a3a616af70cfc093094b8a1d7c09f80bf580deaed5e294f9d30f61a085b9e6062a64d1419f4746044155104a100e80c11221a2f307c00857142d00c6c04d0050a2496c8c108170489679c60b0d28488296eaac07af3a7084b6c9aa543d71b3e43f850438fbee1e186384ad440e589208a986d7010bbe4a5a1036708324da43c41d29ff4319f1cce5029f2429cad2d3e10a65c89e24f147fc020d12bc96d66e3ea44b5258a3b4ee83044941d94e8cd9f3efc89282964a86873e6872e4dbc0f6e02e7cf9e222b845942410e2834214bb3040d572aa082e68da02b489410549da66c5d61c094f5c09f9a9a3ae1013543f87af7a7a64e38a2214e0ffc135ebcc1eadd3fe1263605949e3d02a2377582510c3d506fd59f3a011743ef6adc0d3d5ba90962bdfdd0156983f26d8fc65aa5a07da8992fe91a0a87daa15f73a9d6173508e66cd929c618042d9a5d5230fa45cba0d915d4d982207803c1cfcdfa2008f2705390e03be08713f9a07d3c9489886e4ffed0cfdb902632f4424f6a225b44c8bfddc80741e8e910d153f5c8a1ef41fed0df1f1a7a223d25f4433f757b52280f91b93ad1b1f6e3287ee99b263e8dea9ab665466dbdea53ad5a2758b526a0e572823dcbf72687f46529a151bc09d4d3abc0f726f00716728c0cff867fcbaa934e2775bbfdecddbebe57cd1a3e6fba56ceab57c99c51ff96afaf2ed5cbc27ca07e05c3813149e672ff60f42bd494cb477d15e35a7d115041e25f918494babd9026b2d543eb4092870e24f7834feaa92d50f7205f484f416926aa1e55cf7eae0ee53997dca378dcfec51bfdb2372c208e7e59b09b1ec18261f0bd6c831728db6149c9b6d5ba1b6a9dd5574647444ce6287da6ed4ee9f4f0f14fa13d59ccb278ab351de1d7fbdbe24ff14bac1b9fa4fd8d467b9a38427572b1ba243e49f6c8c899a5326bd0dede309d2a0f73497c71e611dba2a82b9739437cfaa58bddaf2d8a5fbf3026c929be5833ae4be287f9eb9228de2cd2c4a7d5f278d3dca28f7d6980aa59636ef1bf09b962d71ccea64f69ba2462f5c1ae9df0db232dffac4509695ded6936f1c74cd3370b5ca4b1c51bde243695248d873b3d0d6fa22f8a8fbf3a852f3eaf3ae1179fac4ef6c5cf55a7fb39b23926be9b993568afb33df9c370441d7356fca33bd12d603e9faf488f0f975d7736c4a9d56bc573529f6f4eadcbc0eef93aec9e78d674d01dd65a3a755d860f7e79dfc18bbfd424542aeb1a3b6fa8da334f57b450bb881ef5011b3fb3c36f9393b3433c3bf41faacabafa384779cca7f3e7d3f9e05095482911ab5ab52eadd6d54a63f0912cea3e723bbb3a9c5d2b05dccc7632bb86d9d5875dab33d9d5a5ecea5676fd39c5c0f0fca2d87356e8003754d1eb3ee7552fb629aa9eed67cff6f5dd6bd6a05f79f4d82166da20c07ca07eaee20049f2e6660022b1f62a41392a2668570ad4a5fa18e724306215fef8a1ff29379deebd77cea67f6f94be4894296ef66c3ff452e4e32eeec9bfe19e7c2243a21dbf0939dbd3afdcaabe2ba94e481ba9dd6a4a0dfdeda5702fa489908ffb9bed876a4dd781cd463eee45702ccaf4d66ee4db5e4ae86f9ac8ed85de26f4446c4ffeec897824cab3279475f7966fdf63e86f7fff867b213d453eeea76cb416c583e84952d781edc907e1f642194fb7722ba18c572021ef2dd3a75814cdac01bed59c519f864d1b2e663ef0643af991b954bfe2787a820082a5a59c59b01012722bf79a33eabb0144d231e7e9309b649df76d99625d521fb622e755a5d4f37cce797afc2624d29e64ceab55fb9c39a3be0d41ab75e1ac57ce7322fa0a24c4b9a394526a2d9d963aa594523ba7d6d5b25eed39ab10d99ef36310e7ae0cb9b67522df4681ea446a2a26e66096a2c1cd1a37db4dfb974d63d18e3d32b28651660dff7086e9e43c805ddbb5f7e890d3fefcab3ad95f5db26f6d0e0e69665b1f996d2d0f16ccb637af6d7362996ed0579dc82775ce3784b11049eaac6dfdccae0d19d914dfa12a7f91ea7cfcf069adb6ab7d8939a3a6753eea32d4ba7bddcafeec6fdb2b1eb61747b0b9ad62995d27178b8ad9f40854cc9baed6bafbd83f747fbf612ed9b75bdb72d9d6562ae0e3fba106b5eedebfce25ca597145febdf75e8c2fbee0bdf75e1c82e1dc5d2ae30c17e250fbd8cfdf9b667835fdd5a5f1c73a8eeef4e3e57224497fbe34fa585d1a75f8f83d3272f6e5bd7ad26623fa9b67d600ffea994e8e041d3a79ca7bb5c71fbd4c8f4ef8f4693f823fbe1d9b356a03b68a8a3dd63f7bac4af6e8648fd54f59b1f6f84219cc730cfc11f7e013e9d2cbc01fd225a97542e0df84b40ed453b4877b1137fad8f8eeeeb82ebd9b3d82994be38f62f658cbecf1cb06f638da74fd72d3b5af8d815c338873b76209e9f3c36ef0dab91bbe4c1e3d1214e2bc6aa9125a250449ab7605f5087549ebee5ffb9686a7e7f9542a23e797b8fa5e6badf49f9ef746a49e4df0ed3e5fd18a39c36bae8b6ad19c41bfd67250af396a83f2f16dfcbec56af73ec01432fac0ac1b296764db13dc5f3aedc08ae4511be0579f4bb4e8c5beb986733e807fce074afa0e84fead3f6b1bd08d35c843525dc2973c0736097350151b7caaa3d46258020974d02ec10470e317e224e098350ca8f604725b486e830fe5fbd25aa7972f854dc379516f78e50d1a73ebf1ea02b9543a751759d2080059ce2e0378d3d5210f18dd4cb489a4339b6dfb6d2ed92a0044ee709e0d4a5f2171102735829c688ae0da134d115931f64433c6cfd6c365fbfba65fe98bf5b510e40cd3e3b5cb7acbe731e1449ab36f8a3bda806ed71ae421e9535d7339cf819a04eb9c354a985ddb04df2450417bd628c104bcef0b01b76fd0fed524cc4183b65b207e82ee6f5f8a7ed55613a944683febc0be3f08f5b77a6422f6fd6310e7ccba0c80cc5a33105a469c3b0c82535b1583f7751887f7de7befbdf7de8b43f05e1004411d74eb3af0b7dfc3c1a7e929dd83fe4c4fd5a75f95803dd5e8329efcaf35b3a5be8ba93f77394b9c1397735e9712536c5c085bc8dd755e21ebdba0d5a3f368ec99c6ce6f839a0905b2d4e9660dba7df4a639afd045b2edcf2812ec3e9a33287885aea64ab6d5b82d66cf30b129242ec7f44483882c2de022ee386931020c637470b3c4135bb28c6e7c30b2a40bd8d618af2a83ea9bb15ed9e1c8718e7acfb03c5b1bb767589e274b44ffb92bbdcbdd577ed1276753294113ce291780f2a8a964a1f3da21f1f60ba6d954d6f8a7f7a251a3aca1cb275dd6f9354371f0f4ddca9b5a3c59e2ae9c820df414fd7297e514782000fd250d0a9ebe6b390502f8f9d329b0fa9e00f494ed6da0ab36780dbec51fb93872df9737367deae54db45fd194fb79937d5cee6837f4254f068da71bbb3a21e0e953abea04c2d3a73d9ef2f80fbecc11e04b5e07d4a763c75f80018ea71f8237d978fa2378933fd497b832d7fbf2e8c697bb09bee451f0a58c92c6d3974f35bebcb1cbd9f5f42d1ec9f72608be821297f4656ef7e51100bedc45f0167c4963974f3936c8aee512cce7c0852e9dcb74de912e9dab46eac843c20b328e3c24dcd9461e124e903d0f099ff290708714089a497c208743c74d6a070e1c3a747993da81c101743c02b403ba147f851e8267e81283a71d8036d6741c40c76f5d20ea727cda016807107580a043d443304d97e2e740a8fd16eda6878c3b7489c1eb0061c76fe9b0e9d281af81f05ba22e673c0d04da6f89a32e6dbfe3b730d0e5ed755cb0b1140e0ca42e90c2e0b72ed8ba647a1c520f48e57e6bc5f818d4fe8287f2e0032de3c11846fbb7a070fc53f640c6d64348280fc0df8a814397323c80ea1500c71b40c3d0655ed265ef6705b0b14bd2a53f8e02e0f8ad9d7f5680d9db2840110e291c5997fa8bf4100c4ae5df0265e8b2084a97bdc72105f55b38b42e617c96faad992e971e949afd16f8bad40ff55b3d5de6c761f431f4103cc1dbf0a0e8b76cf4f49071eb2163efb7b6912e657c911e424ea0cb186fc303a3df2ada7d2fe9f7df10000134ef6f03babc1f1644a1e593561fc95aab572f4146fa4e6b39407004219776857a0e4bff52d71648415a3aaf581085e84eabbb3b35429cbc116aad73da398652ea7846d9a83bc36b67750a868e258ab7a8ac1afe44d140967886a828513258f0872c2d14b2c4514f2cf0831503595a185e7012e582055034214bcc842cf11559e216c8d22e61812cad922448a28e5891255e214a0523169455010244963805af18316a3ae82d0a05b2b4457e51be41108c1654418520b2c47b0ad22918c88228c89187af4f5a0b20d21965a79dbc399dbaada472a758449152f75aadbd170c85a0d93cc2994bdc9ee3ccb49a0edf4c3464d044711c6b4c3a7ccb9833e678bb91a490d0d010112e17611c919191d19010291a191919397d11b620d6a36a416c71756cedbd200886e1c5e08c4669341a9ee59c379fe6ee9627c3ef572a8ae358abd96ed7de6eb7db0d04316d4613997460717cbaf1b6a71b77acd56cb6db8d2485866cf5213a54b3d96cb7db8d244921a1212f7b2ba5b9a19a0e1f8788886a3aea9e73061985ab4de7e1a28a6a46434246a491d1cd6654331a8d44232323239a91d10c1b1985a0d135b2d5c88d8ca811d578ce983f94848b172d2c51b2aea8932ae7514050905f08737a88ed2833bb9868ec7839b1e2112de84382200882f7576bbd59d087f44a1dcbad7d9be7d35a06d447b59d26943b6da65ad3813fabac70cf0af74ed8f36feee1be1efe5956e1a9579a60f77ddd05346bdf5b3dfcb97b903d0c829a84dbbeba0ab6b5a8f9be9d2bb074ddf2309d6a9dbaa43e13ec0555cd66dae51cb4cb4aaf902ec17c5a23e137e9498873d6987302dc48a9069fe28a031f0805b59db50c6ebb56afee4469ecb282b386b370166a1e343d2b6df615a0813370066a1eb43b079784a47f6b18864f6bb565c439dfbeffc5f4de6be55cf05e8cf5fc1986a10def052f08d60bdecba6878b434cfb89c77bdff6b466a3b8d27befbd955200d7469136cbf886b846ab0d75535a754bb3f6be78adb5b7e21c669f33ee83598c5a6a03d330d4d3799603faf652fa38cff9c0d5d6b56efd59eb83f5b19e6158c35ab5b56e2914a2a5355d072d1ee90da0fba3b779f64748ffe2a58edec523fd0b9d1024ed452cfbcb0e9362cea648f60c2b63f355c6cd16272d829c6181a26c510c477ac59b7475d653f95f87401fe3ac75e3d5ba712432c946516ce093f4d4d267f2031f949ef7259941153ff4602dc77cdbdcbcd953ca3afa2f95ff3511fd494c44de83d9e3d5257fa6ac75b487d2e7a79f779fa4a7f2ef7e2ae99598485df696f40fbdd7381873159d8e7e147d2906a844d1476ad3cda4ac9b3f3feba9ada97be47f3dc5fbfc530d7cd25329fdbf94d2ffcf9ed4eef5ff4be9fcff44925e3f554fea7fe9973491fcaf755397f0da83d9db5197fc79cc1e94ffecf13418030de85a0655943729cfde9d3d3197547bfc233e6439e70cbd03bcc9dff6148a4c4aca4f4497f3933e4913790d5597449da9b0f3e8d5e5fc21327bbab6a02dcec6592d4ae845a222289fd5741db4f8170f428b7fa1751404ddbb48fafc3d923ecf24ada39fa4fffff5946ee69752faac896cf5f8df3d91fc5244fe77fa7b5aeba8fe244d648b88265f2ae9f56b4d444927e9599748f126bdd24b2529bd14037f59bca84b4fca4a3a33307f7e0fa54ffa1e0cbcd6e9a6eee03ed18b445fab3d0937a59cf40c642d12113d0ba2cf3a5d07fa935e4abf148b2fc95df4a42e7db378a3a7b97c9df8f475f7e793afb34e4cca3a516bdd7d0692b4d227bd1403fa95f4d4490f55c95cf42cf22c7aa30c8404ba8d9e8415245016796e5df449459fcb24d04d7539070d1a3488cc452fb28b4c7b91d6c4c7d17c7f452ee95ef146b9a4dbe8837893a8e963f18b5e2ca281a45ba41c50cd03ea6af2e98ab9c5a22ffaa29fd5a28a349ef48b9c6181f26c5abb80c7acf1a8fa9ba916e9d0cf6ccb494f1f27853c8668267a320fbd08d6a288b01662f7f8b396018e418306edf1b38ebea694fe0f7d7eaa9e483ecd5977ff9faa9773d2bff8495a775f8b3aebfc49df237fd2df4ffad77a0aaa2eddff9fd2f9f3d09399841376ceb337f3dc4f8eb3e74228ff98e21c6db9b474dfbe968378d3f8a510dfe33b600949f758d3f1c3793e9f4ef129b96dd9ee1add0ef0a6eb446a6dfaf7d6a2fcecfb349753aca4d2e2201c3468d0a03d1faae672ea20536cd3683f031f29cfde519e3da86a4b9c41adcb73925439d709126775f2146c889355eb621481a7204f3244e0c9840b0563132e0e2390f1cfc2bc677f8b9a90f8a775273a8b40dee1aed4e608ec36100fb2db4547c8f0e77d289f39d91ead716002dd54eb08ec36a881d89964acc6065fac632db365f84afc804d5657ad6bcc7b80b36d0e0d86a965de43d91292c4b56cfb475087a4bdfbd5cefde65275af3793cea37abc63d7cac91250c4cc5973a68cb80704397eba18f9f2052805724a145c73beda586922eaf1610d162d4abcf400a60505acb0039a22ba0c12e3e5cf0e708c3c3196e54ad71f10b898294226cc141a58c8a3a4cc0b64bc02bd1004d7123fec48e125858a23d49c411226414483105e53a4941943e3e3833129e80102ca147cbcc2b22a55b869018815decc20848fa933442001458d13236e443c3c981984458531265570e698085450d6f429a3e384cf9ddaa708962c5fdc7889a325830f0ab879120686df9e22b6c22a0e60e54bd70d5e390caa12610054fab8006789227cb0846df40411674b063f37d4c9f26113eb810d16132c28d161f279020621eeb47963e585277c3020832017da28616264cc9d2a7c88a8a14816288c10416acb9c3855b2b6447972ad605dd10153e74b136ed0f0f0618622509081f323e3513ca04b9a15be06a55153254a0c081da88843049a332e48083d67c634a1039434225c912150154db889e2e70f5e61caf1e24211b22850cebcf961aff86800cb22c20b4f28a7499816aa6c65f130c70901ecd4d9c3820f498a3811ed70ddb9b2120316a84e1b1f0b00426b890f331c49d28348968021c0c08183c49f3d604478eac1ca0b3f1b8cb0908377a940e688228e3c21abda814b861b6a88d3658f135044c952c44d951a7c5a7e68a9f3831b28a460a100286462471424659618f3458f94098c61a1e149201bbcd488758e58a28a3842583902cbd69712594a18192285d04e1b167aa0b2e6cb1c1b7c5c20568787346337fc2026d2f9e345258e162680ac94d9f263b380868e117efa042168e67920105712605a646c00e3a2071b94ac90a489234c00f1e2d28587c9113556423c5536301142cb1f414ad0f11143505694316c7e4fd2d82a274062ba3c9982431b2718e0e5c588335581ae84854e54c04b9d19c6ea48298325021422e2f8e0e54f1910e15813577ab89aaca1222bca8f0f5a00e4848e9e3e5cacc43965579e78020927eaf809c2c7971f970c5f557298c18f2827022870081436c56b09d9c573e749561328107185aba6ec89a2458aef6b4b880fa498c3040a5f9e29c8c23de4123994c9c1073a6ba08840b505c31612314a84c911140a0202451c2e4037d0a0c49c212377c28e84b103840f21147bd00c81756507ab89241e280b74e7c8923d7fb0c4385a02a500c5d79f1a8e84bd99008e151d9cc8b3840e1a383ee6a8e0e709b1417e9088e06de61d25b400e9899305cb9738b694421476c2daf019228c8f3ac62b852a48c829224bd716b189b9664a163e408c6df590e4c72e8824588842501b3450de4c3f5b8c7801cf153d657e18a3c6862e4f7e592a884cfcc6f0bc50832fd012187eb81d1d5424414413699470610a0d6e7c88c3842025b4d484bf15543831868d1616d668f181825513587af064c16107186e74526833050a126260f021812ac6ea5011d4c29614ee9511c67cf121d01f1a5e5842c99629b4c480a5099d991c08844d0145133c7461391121871f9e848f3a368ce9b2c267092561ec0e4954b44cd1c2953b7bb47c247da5c07567cb0e2bac808d28b14706416c50f8a1aa888f013c69a342d693185c808291ecacaa9a24f91979822542035881bab6f021628c1b371cac10e648123230f0f9418424b05461c5c393377b6010db8c60266b86372b88f9c923c2708394344cf8bcc004a292f287893150c6ec60e60c903128c01982ce1524e41cb1c49d262ba499e2f526900f0bd88007cbc80f525899c1280ca5500497122a5ac4b411e10a09104a6cc1724510a090ce44c386862969c8a8c061881f5284b08365cdd72f0929d8e703cd0c542ce1a10928bc269b1fe29209f664d09d2f4accc0031d6b0304f864a912e68d1a397dea9d69041b2e5bbeaae8038585352ddae851e1cc97415a3d6c70e7ea852a47ee3861831806585a81ea2cb932041811aa964db584852a8e1054e54543113503d00a0363840b191b347d70c8e2840b3c78f10121a629810c0c75e6d8f19d1944fb1224852a5bbad8c04213416159965439d1a70c192f28ca5c958531d246ccd4d380a4cba8240df664494a2a65cd88000000006315002020100c08454291408ee5a1aaea3d14800e7a944076561ccca328486214a4903184000000300080800cd1104d035360df3f0f5522f4701ad499d7e338bacc7de485eda06454eebd43c7b9adb9a101170bdf5928a61bf4c88b8a7b8a3c30af5e252606235ea510b723799402e8436b05c37020467ecce66bb46caaca0c7384f6998185716b9cb597891f5cad046acad908f48cc0fddd0bc40ecd48f6fd51e344d62b98f1c86fe0be226cd2cb45c12b8ef9e4abd4a6376798da9b768e36d12b4ef6a2918f00c40007f56df3fd743e2a7a7d8baace25df92786251a2fb5cf37573c559355ae21163595bb38cb5f4c0e39d91e551fa8c5a76c3a53e14cec385d5678b79a009dc6d6576dc472978c8850aa753ba565e96076db66bffa3ad66aa127293aef28ea4d4aaae160284fac55723646ed9a1c095d24870ac5e2b96900fe1283874764e50e98817b4be4eefbd92ad392b8e718db34c155dbca1f7d46a64340436d9092addfd75a47905b151283c86868bce3ec62b8c44310e7f8400ed53e0b90b92e5fb6c49700262b8bb8899c43e73c100734a39a52872d3535a85469f7b74f90789276ae99cab8513fd84dd5cbb78e5f2fd29f69ab9106e10347abf9020ab6134f4fdfe3b8b40da6d5e034c0461685746be61f8ea09f7298a7ee7e51c81038682d3ce497054f95dc311e2f4aeffbe52d63865fdf7469bc6ed655e3d657f81b94c922238ae717b7044bd0629391d5b1c05e6c9018b036217a08fd41b2d19c165b59fc9db879c2e4c4fd3f8b0a11a5ffd7b328895893ccd96654ed727dfad3b2e093dcc18e599e44184ca7b71ef921fe8d7906af1a80c5dcd216bcaba22e44ddef4ef16275e31578a837dd6fbae6bc7f2f83b3bf9c066fba45aeb06567e9de506588fcf6ee6c63474ecb7e721eefd44d93312e818efbb8ff171b77091941777993e218bb507289aa55a5054933e2524aeb652d5c9c0d2f4ed0dd43aae7630993ed259dcbdb83f8ac064efb27ff67ab82bf645f0d2d66ce9df954f9d6628bd616b7e7543a938d1a14c3e1580f3c0527fbbdddb5fbcf42a32e891d1d5648b62b512cbb4d768e2010ea64af719ea0d056fa49e237d87792ff9919559dadf53f2b5a825e7a63157bbf740edbe2cc4428001e70e50f987b6132a9f095a30cf8d5ccae26c08a3a5c10932ebf6c1519f348f7888f41ddd484472bb9662a763ce459e93f72d9300fbd68405f18c7b39ab680193040d7f51f6b54f6aa2ae177a67bf4e3d1cc1a9e34c3b5858d907a4bbb99c2b13e14241116e7f55b7c3a54d9a243cbe60bccae84af73a82c21592a14647b80d0c69942488ffb1e0f985a43172f5bb7f592e684e095299de1f0edf29188074a6aa67cba5258fd184669c99ac6e7ea277c5bcc07498a852b0acfed811642bab5284d585130c561060da55a88fcb72356b0e17fffbfd34042238abb247650b9b97e52238330def4204c4f286ccea2f4de2e6c875bb486ee4c0fd19a6d5a1ca0df7c6d75a7ceb216704dcacd781fdf988f4cb7213fbdf776e5e6abd868a06797646c9dc8977291ab78463d3968e241914b631d8fdf3c8155a48403529acadc87593990f9e973f8b4fa4e7990b9653744e276016e7490290e3638cee63e4483c6d4e42dc701db44152834e6174b7de02dae1357beba68fd9b7d61e957a22d1b2e2db20e5c092d4df45af000cee8ace8792fc40d2c6e45dcaacf4c37a4bb3ef3a546c97bbde2da1b4f6b5701aeb7d891d28a6c35e30ab0b1a13e1cbf0168eb2b3a4ad3f3f77d3e0207ea51b373bb2691b7c79f770e2697a1731835bdd8c591928e3ffca2b089bc025553ee3ec5497da979af559041ea96f8b4c6cdfb348555bc742a33d19e6bd16b96ede85a2e0320bbff47359d860c08746eb26a628c21f4ad7f117db70f0cbe19c68b4e695eb1909a4cfb0248148c831663d681f7c82408812f0ae14629322a56be66a9c11171cd220cb764fa2922d69690e752a1be56d87c81c219cfa7b18555cb61b2aa196a9c71d15abd61ce2f90af01ca5a99ba60202bd9caa5d65a36ec440f93d77f7f7b5ba10f8b663a0802627155fd2681bd5ce73d4a200ecd5f4fb9b6b2f948b6a86528cedf7f0560f46fe84f9d3838475fea04f97eb8c2c4a4920b3585a8882eb6066e4d665ecf67c9ae698d8764c55a3933b8b02e2f0d7b20059a0c9ac4b1a92a22fe30dacfab323de5b44c7848d034e642731cc59007bb1bd0ed6d64a564b020af7b9444949f6776b2cbdcb342ef321d12080693a40b97c61948e1a7609798bc93d97295442ed80181de69b2d2f1144ba75075571736dd08714391474efb655955a80eec17ebfdc2b75aaa037277038ae6dbd674d3956378305b278bdb577a5a61f1ea728a912799ff4c80ef7604716fbdab334719d1a79c746c2884972eb08e625dc180160a55213b502cbaba59a693fb28010104fc954090a63f96a26f6bf0d80c026ffda06224b7df62babfb15ac63e44e1cac0edc71628e97c4f7cadfb4f4a3e3b232d487166219e6905dc9ef016fb6886db392a0f4e75f00b4a184aa82c4f06e4f75d0878b303eb61d30ff2be60b6e8627d17d5859fd71581d617f7652651c75fb77417e82cfb9046989a056dfee4930cfb4e92dc9d661f1fddea5b3fa960096202dc77dd71640c7253f7554ac999012f02e82973626fd033845c630f47a15d8df70d18bba481abb6b116ab1186e43f8faae928eaf883533131fc416dfd2561163b408626bc3174dc40a3c30d1472e4bb5f571a3019688f60bf70c21a47da0575dfa1a361073a4fb76c4b6b5073102afb3602661a4c0da9df2e3887e4288d6058985743bb3832e0a927d0575c2ad5be524cb50b645057e55c0e6f2aec1cb11145c64a9bc31097a0e4e32c872c9cfe17413f7addc6f0e5320e64c3fd60d3ba782ab183b33eb4d73d4c11c159c3fc636737a5aee9bd6e65ee6341a609c7eedfa4630491e6e99adf126f67e0a046f85c2e4302e2a323dfed5fcdfa8f5b3bf67d4b3214519853a9f946539e72a3be6ef8dc30962b02a4b62f309a25f13b3075f599f88c6fbd1ce9afe2bc95aa81f65857ee415a3ae460a957d4ed3e0233968f7cd9351cdff98680453e129f1d58d3207fe10ae12b0c9a1707225b231298d90d42526a64e8c38544bafa4130fad0651b7e777c493e6774629ef94e4829adb99190afa79b7b8c11b4fc39828302d7d6040cfe04107624d85d4d220920bcc63e1f1ce32293f7960df2a1962d448082c4f6cff9a610bd45994c95f738f585018a1d540165c7b142916cc4890419081425397ae83b0c70a6e6106e89133d3a117bc5fa06e216c7d9c9c4c1ea833bcb54b0983940a34ce3a6daa560f1e3562a281206cdc22430a42de256d2906bed6c18b2bc2f3bee165af8d45e8150c16fc28aefb5b434507796afbfc4572f65184670c0382c21880bf5711e0c796c0f08d0a6e2dfd0c1defa82270b7bb481bf175412ea196a35b1d082ee01d2f50fd8fe14ecff81c86e25e559b4326e00a5bfb22cf54c72b6fced27ff51a0a059e744de77dc61123ee6009cb1a5ddba6b9fb669b8a2b5de9d8bcbba67b3a55a504e196a98aa3ac12aeefe8d361a0ac5b8a6c0301a36f349b71f2f8939d2a98af3e725507c02c23f40ec0dc030ac3aaca9d088e82dd54762e2a8c5a40134e48d709eed643abc529449309effccd0ad335022005fcdb3d38ec804548e565019797c602c3ae4c60ef4ccc03fcb4ab0a3ebd197e721e27e7a758651542e9f88d4ecbddcbf7ff0a8c67c623d60b11eb459dc4d19d4bb70a9d9c65670d0056e53189cb1c99c6add6aae8f5c07af35e6ab5800f2860ce9d0e2e1b3462527d1370a56dc6da1d1a814cdbd139c72ec43307819458ad494f7535dd35b66627705d3bd6fcf0b5482c7828f0f97b98949668efbc6f339a35646809a187333ecbcf33d8cf6c9d11005cbe0b3cca613b621a5d8d81806daa8940f3d3624b12b744845a4018875368cc3a5971a7e19ba143d8fb16c02ff38b323e1eb6dad5879ae723ae710f4fcd1b7a8a0ac6c5e2e4a2fb378486d27f31c92753f1d50c2c5b4d9536659314807afbe74b4bbd03f115f9542d956b1f9c3e30000abecbc3ebd4331bfff45a804344982af4542249ab76ef130c6dcbbefa3531a3b800b1c9c448fd7e70055428e7e589c732ac9623bd5152d2c74721999a1dc61d72ab3eb4d72b05c853b778395af1766abece4d679be3048b3e24d322b2d39c8281589db0536de5a20ce4a220d020225b0969cc532c90911012c9ec5f2621ba38df861d467dd86d3faefefea7614224f3d01086b77fa11f66a403db7506d4040338b7165b8f03e7d7909d1f82586c025cd6d227d8bf296d80bd178af665e4a134f9257d5a66f2d00c9da1e8f6ae67a4a369848491b8b31c1030dc3c8278a016dc783584e27ec0e6ff51051cc8d469722c8d2df9158d5cfeb5a14741542e3b747569251742454ff453509735d50e35eaf794ccd3c11177b28c605dcf77f86f3a41686bd745f8654842153747d9b4cebc0d28561a37ba316392d84ffeccbc10eb4471a8bd3406f4bfce86935c6f461043112321b7e4e4be1735f9c6be25924528bb8db3a7547d3345f50d86eb7a592043253f838edbed4f257ba2faa1af00f60a4ebd42f7007c2a07174a10dd659f83ffadc0a9855ad709d767f62269524cfb3a3d04ce0617301b82aa98ad2f654074ad32393d90ce5430c1f5483f5fc775d211196b5473b64766b91969be392ee2756ad5b1f095960aacafe8933613623b49a70585cd5c15145292a167889ac2a933b3b489d44897a53a535856c3b91a837c9cf63664570a16e7df54bf2a233d1df88a06fda44379e69d2113c0ba41e5794320b923745b16a606c34846d79408dfc0af5e16580c331b7b74a36c67ae3001e03da91a4587f8bf211b2f0ce5afbc4408869270fc216044a45830140668e7e7f7c9adc288eed77ccdd366fe21d77c334f05d56a25fec3b839af0cb2a3944f7dee9eced49e884355021d162620213603dd9226cf22414bb43a8d7637a4d834654217dcf33958f6187040fd9abad950dab911a7d24207d8081e914b7fa09047bab535f0513a3ea7d6817671a2be74a30e34820bf12a2d42d1b4f31329a4ff0a0023c0a10876d2904080082b44aa057695947365817804ed5a9c40c8de51250ab6aec9851d53df5c61ea075e39ca83d486389516aba0135835e4bd475a73dcc1f747a1baa318fc9ac829fd5791313594ae936bf68e0613e16cd2cd2fc50282ed6d9bf39818a88bf72843e61e7acb11383db2daea7e6be5ebdb01c34a0829080554710de03d3e8a083651225a8cc9410ea539ebc03e58ef7a456515e4dd93484e4add34dc8c551011dcc4b7b4503058231c9d9b049b5f0ac50282e96d8bfa6e8994e936548c8a15e629f01f845e8becb0d891c3363550580bc86922d4c81efe1dd445352360774f9490883ac1cc46d2764ecd8def1d52b0a92f6b077522d1f2924cd6ee48f4db0458fb2476c8427fd554280a98e0908d08e1b640d5119e1233862085de81ea9b9e88ef68dee3abb12389ca5a590339ea2532e2a81bb5227c482d0424b531559aab4162148ad50484cfde6783cf7d0f4acfb25d9c113efb0e6f1ef4ceddd63f8a3d73d277147906846af2cd1fc1ed6069829d34641b6084156152caaae9d9deea4844b78a1507912044374c6d82340525e8d44d27c5b186b2da121011e069829d34f044d8b60505158b65172ddce2b895c27b3562a137d2fa43b3ed2ad557157665d3f3f04eff4697441eea58a89fe191c84e765a2e997088349f6ba145d56b8508a60d85b68423557371fb3f5aef67d45c451e01b5d5860ea64cc8098d3a9a9676ef90fb05f0ed51588a912a0cfabfef2b9c56c1a95dfb4f99013641269bed055546de6a8ed0cd63f031f9e48921840f45bf0951dab2662c59a9d00798664056839b91b3dacb8a6584c0d243820ccff9029e47187ee2fa31f30125d1bf8dd1633df1c2d02ffb4c9379d8a15aa61912522865a15902b76e310ae430b098fd7408bae698d5def41784abf155eda5f9384345c9eb16db8ab3ba757cb357cfcdd6c48dc1347fefae0291959fb2b08439d546c790990203c09723ce9c59042e192f7f1e1677f9b0f8e404712f347a564a942da2bfd21ffc6c85faded49bb220f4bb78836f97a3f0c62e59b29de4a85ad33e8b1758ee27a934db3d42d91328dcb25b062a077010610038934e58711c378c27683df4f6cc81591dd8071dd39c2337e25cdb6d74440085b28273e485b5a9129c8311a6e9ffa0a5e23c1035b536f8f092a70a1533e825ea80fff6318341dcb260cb480813675c38d05ca1ea8fa021402caba10ed2fa10ef4a97dbfccd1c73862119b027084c7803ee40d3873c63887cc949c00adf83a86afdb786a5835fc514446c24eb50b93e4afafd5264227b924bb7eff1fd498a72aaa7822ef648a1aea79098f4cb36d18e71f8166e2a80a64d89767c163918282259c695ae2406f8526ae1ecae7be24826897ae1eb979654f5d13d13db3a40b05c763477594756148abe8476c82314c1a82d7e67c198161ba29e016229d1d4b653aa548f09d3ed6a6ea7a36f422ce9caa1e7acd8b8562b6197b5de48b3626f994109dc18a972fa8d532ef8027ae202e5c856f848fafe2f409fe10cc01abf32094138f01a4bcc829b9248274bb29d99a0f4c848b99d53fac5281977c9003253c0da7d457273e216135752adf22cfcdd151e0762010f925fa24abe685d5b03dc969e21065d45bbfacb6452becaa6c85194483619d6b94926e86f628c3b8b7e684d2e786e1e1fba56fffe61d17fe797ca8310a3e208bb0f6cb97ff0f97a6ea4fd44e366068ca1d7bb406b12dd52aeb91032eaad60265b3589719aa8066617b299a8399c1dc5a18d91f08ac2f7788d42ea9d7cc0115b1f4cb0a76a27b1d3509466444184b918a3b090a898148bc02190c1c46ec0a013f2ff98bedb560aa99b13c8cf4cbef7cd49182a49ad22a3de15089f17154bb4f0b3b4206da00314c7d04990f76acb1abea04efbc8f1ffa09ee78a3694a43d6db9fec409f2f192dabd3894fa3985451599bb201e9dba6aa0e897a4ba9868e0cd6cf56f291c97ae0519620abd494f0cd147a98527cf22ec8039d3b8acad6c82b0b951006e81d8dca4ccb745e3ef6bc62997c483aeb0c12aad430f575c141d84930455c15543acc3bedeca086eac93e1f9539e84ffaf8345fe3b21cfb09137e2c14282b66a3110ca67f743180d6c813aa9dd676f2bf03dcb60cca44e395c7834204936b36ddf2b3be58b3f48d58f2f4d9d9af95efd0a7cbcd45347118ef97f3a0b13216e42641ace7c6bb627ab3df43923425c0453158f4a3f4a84bc1013e6fce725fb70852e42ea8d6943bf2869970a77a4859ea4832f07a65a3042f559ef74cc9904c437db9c3b619134f2b1cd6fd9f948d78dcce471a788812232a11c03d9d18479840042ba3e77c86250d9c10521e72165ceb45e0dc52a61a42613d4378e5e0f1857fce344ef09f4558a204fcaaf673cf81a3ea41a9e06bbaf36e2dbb924dc5e6a7f6831e9a5d473aa1c6dba8b5e9d0c299e7d5421cc7f262edaa94be4a1628173dab827cc15c3b60b097a1857d19f3c858a0dc2029aa7a26aae869e80e7944af11f732742a1a10a3f0875cc5a04ba9e62a577d48ade996694dd5b2b4d2ac6cf10439423e6c938181d712ec337290792ea05ceab300461e7cc11cebc206cebd5036e09994cd6632cbbb82ef994f101996110c3a80b910173cc3f13ad3cbb16a9c2c5e3adc679db04096e38d5cbdc02d34250df77a2bc0d3c24aee66ad84f3c30894f473652e8cd3e8fd02fd7f148e2581357afd89c52a1d6a96bac5a0007a60646c9d8e1f3ed48287ea082e47c3ec2bd8dfbeca935d81de100317105efac6d3015bd1fc57b5b41d78a074725054d31b5596f0f763857d9503dceabb04059468c4c0ecc8c7435a15446272d1c155fa4768312c70aee6fb7b21096b5b5efd6815305b56975d8aa8210ebafe20f9cc8822277a72db4f9ef61a13dd6b2b053d5774aec25c099b36238dcca066d69328250f891c25016c30e42d48a586a9ae63d9051084b3152e7decff1778cedc056a61c8a05f29713b2a10db1c0874c3e1b5f087610c7111f0b26ea2c0e0b8836750971d8110c99135a4519400f86145836a410701f00120e7d8984350a4633332e2af0be24dd1d628742f63dde33e35878da6ddf2d87831489087550670fca4edc2ac159c81045d157594270c9810308748141028344854e520021c39edbdc2408fe9a781224f6a03a5ef61b32a1d8635449ab42280d98266634a72f18ea382b42090d52378e485e6fbe45fcdffb5e1b01d086d7371ce8f6a4e7b1bef48b52f63c0a817acf83d95c38b96e2d800a5737dd1ef6d15a8d427e396ccd31051b8b9d9401d4b79271b80c2da418c110f84fe5ae1e88144c2b07605dea6b88a41e0287ff84ada77c1985842dd881a88ae7b209dafb66038c93811f242af3af505b087c60e0e31ef51ba4ad413d2abc6a570ea20ac0c51a7e6653a41a17e25137e294ef99e5d9959b9c067a70540d21eaf44c86bd5a76a95f47ad05ac338f30faf6d77d2718472046de2402f2df187590b1933781db2156359a3f99a413e19a7ceeeca638e960154d843c50e456d53245972c102dbcd9132bfeff72450cf757a9dda83de1c263353e42f27884519badeac26698b9bdbb95fff3e01230763d6d4b78828a00fc4c2f98ace9b00d22a6bebde88da0ae9c4014005964b8229cbcbaf5a525412f33705f34f0c151796b08b7954b34be07110236d316a9e05e3466c08c5fecde37a6f033a5a7bd5834743de73268b616b0d8bf53175705f6b848a3f09da7760155faf0835c036bcfe9b5ed2bf7f740def0e0191104a1474c18d0471c1fb2dd3df57d593322deed0615162c858e00c804273e0bea6b07a1a71a854972d9f4e71fb2027f844437ed8f0c2bc9188da975b9bf154049b45517610737e269ba6ba058b3c3073d2d8e580e118f3a3cf1f718af07d2683a5bf2fb850813c6e04e7ecb862f2872b61a8ba1af3494a4189043142d86ee08fa16e1d95344037d4dafad4f3492b1a92f8d928ccaf8d192613c8171344ace9b4a30bd18be7a04d714127fe1bed795922e4a808642516b6f0cb77fcd3ffbbbbf48b413075c3996398722fd97f3adf653b7ee042d3e4dff003d64bc31c150d9b710706e46731423b68885140b76e98f61143bd1d4466ac4c381faa5b7cb7dfdd8bc8ec1a81a3247470c3a4a15371fdfc2585db0714166256f094f50638249f7e2dee33ec450ec01db14019f4966596494534a1885e4112be455b54fd209080886e8afba813c187efd4f93f35f687b5a956b413b49b5c6dc8343c8514c1130585969bdf8dd4f12c3b01ac4121c318cb09fd9973adf58a575a6819718ca33bc4bbd040862754b50affde976a05afe0866a2d0e8bdf2d622d3905917ced04213d07e6b008223b9b22028fa550c1c970115ee8ceeb98ecb43ab48695e23bcdab1cc30cfe65ae3fbd3a101532b3eccd53052954907223fee50a4d7b24aa2d461148483f5624ba9ce4d88b601bb411c0cdfbc0b75b9f1b582512727afc03d9cca1ec38346dcfa8077178cca789317dee466e8038e5557685393baaeab7f88f1bdfe41565c38ebbc02861a43e44f3275b4313504b9a6b2969026387d02589a6e09f5a8c434f539d7b174780864978283e72191c686fd175ec41c83b185ae12b1cc4ab0ead5fe2a5fe2f3bf8164df5fed2ade8b065f216cb14576e119c1e29ef61ccbae37a01d78042ca4b7cfa97eab2ab7c040522dde05afd1a8dfeb73ca7cedf18a415121c2436ceea45bd7396d5f72639e7e2269d8094285e203005b654b988ef48e77d9d7401867ec29ba7e8355241abd130c6d6a51536294e7f816a8ffc8430f4ea81c4d01e499506430903868a2ef1fec10cdde11e9083b412c9de8b10c4893f41e131ee379028d7ea013c92a3788b7b5712ec24707242acef4f4c114b7a96d7b2ca9f6f3cc2d672cc0a618851a4b24378a1c414c2a69f13c653b1f8bffea2035b55d607467c9dfad0e561482b012ef667f6802411a3a267873253e94e703439aa017cc355de63657ff3d0f76f9a04fe7c0f4dd3d3a38fc29a38c4dbeaaa072dd92ef86a42e11344a64211090f82d00ef844a857be3f137ea54bc19061d71607f22d007dc8026cf9943f00d531a309d286dec5612c9408d45498f015ed6ffc6a3af23fdec55b2e480c8471344a05555b88d6893e4d98e66ab9e3179c169bf394c6ea0123ce6ceb5db23f58f5fd051ac0787280492af7d705d7cc1b7297919e39260322244caa4b6a4db153195d23244516bad65403967dad029ad26fd043b8a7aeb16730c2a36e52da553c899a62ce514a33b6404ee35e958fa328127ca9e6ef5a073c70ec947b0052b8c01df534192016c9b38ab9f42dd803724de8f7a91a65ece9515306d4c1743acff6dd681088b77ba61f083611cfabcd32de827d81742c462820682700e6cd2f74c0d06e5d309427097a8f224a7fae82ee62db8a22be6eb444e9a01342583fc62b58012e4e75a84c2a65e59daa4761e583c4038d73b48d1654c02f67462ee823e0a52d0320ff39508e1fae8c76773a1bf0e0846952c9edd50cae6e1d18a77b32a278eb736b465f1de033f927c53889bc0c83ece7e8c30e521b903428178a3cd863517beeb88eb045452a6e8c10f8fd2c71856467af4d903fdb13832230e79a772a6ceec4af29ba3128990698342c33583cd8f87accd8c54b9cb565f0b3441a7bd4eb1f49ffc1c13b9a70e18e86ec3e4e759e35d4f0e17928a27a0570c01a1b6909bdcdaccd0c2670d3a3110a81fd418229090ff65a20d5f2770747bae9f0f8520f51cf9155c744460b853c84d669f80ee5317115c3d79717143f21ec271db7c14aa7aa20adc3a911fb63dbd2c3af420a85212cb25cc1401462204b7ade9f81c314cc0d7cea4b1f3ff7a5a6c4477f6ffa49f6d67ced50f210a4ce4d4cd6aba81069ad45f12c93c0c2be51f4af9191b413e18b07d4cf444a060a83d40c71242f2b6973424892a10977ea920b2f95a31818edf39f6cd7efe035e6d739755a2e4dccf07e0d1f2d5323bca38197090c7cb585038fd0585658abd4f097cc0944299b8de83ec00a9fb56a9d189c19195f2e739344cf1110c2c7e4a8d28ec7520ac29faa2512f08b2d3bf3a2a15e463f055825f7fcddd27b4c59cf118637a7fc9f0fdc59dd8b8ef7048f51750c80e80a0ee2f389542d6f51f315c6ad2ac7e59a9f71781878627a01f5dfeddb29cedcc73ecc8f48446e79eeefbeb06061b60aa94133d1851a07a19304d2d8b91908c3efd390dbdae274c4b0e70260b79992bca0b995864ed42039a15270bfd3213c48198fed4fa65110796a4920f4d214034c09a6458790e15031fe94e90ab888d2188a33a200aabeb36030f744a6944e7d1d0ecac2db1ec19dda5125af336a6b5700807e8c31140ff568703ea073155391ec7fb1211697e39ab34cd53d9837f2b521d75a9fd22c348dc8ded7652f6870877ac74571160ad7a705ead71203b661b28cb7800de5ade1be69dc717463daeb8181b655108da7e4e133ba488b40134684260a667ab39c608a50c5f902cc959e1c0c9a2502e53bfcef1429ab2cc59ad1536118c720e61b475f98bfca71aa55dc893c660339f99a7d4d9a16bda53540678ff0b1a2ac603b83d7a63bc3f3c05ab9669e27db6374d288cd98492cb13c9927784b0f4c0cb5cdc322031c5fd0d7ea25f3c93c0e0e04ac94d336011cb2a60c8febb28c00bbd5a6db9f04bca7006460e785e921e2680c829e240e37e9ba4ca6c6dbd57e70aa81d5f1c6bd2ab6c30375f70e55ed615bdb87d5f6b7dfe92292a510ad8e6537d76c238f370b8dd43417a5f53963942d9b61eaf12405f600830cc39491b8e3f322c92d1875e600acc6de502ed060591a60644c08b53e4fbb96927ea0f9099e84e8e83635605244cc6593d0011b1b53a2ad0353956601dc71122533a17e02e8421f0ff6be0800bda0218fc711e2b89166358830a10b41f6a6a3a6d6e71a68333eb3d34fa4700fa538742cb71708638b421c99ddeb4e88b4e840f540e8c9c5f2db4fb5647d37b39f84f32640fbc7199210acf03c1f7019265a7e429ff86644c48a3388c47596fbde5705afa1554b065ca7ffc0cdd0d383d6710c73dda8ace9a7db5843f1b83c91de82f168538d6d01fe7742e68385db28b76d78624e8fe940cda7bc3e84da4b23b23af0fd1f17515036827f0455fd2ca5dc5d91dbcab9fa49dafd6ec4520060ebd95b42a44dfbc6f6d1d83d1f4615fabc208bd5039d2956e96b6cf58d8f2b9e856853b4158b25ba07d0b1d14884ea347a379ce0778517f945880aaee93cc6f27377f06f542b9b420253ec7c7aeb8e8472fbebc7a795baad717be7f1d3c3c48f03ad51d400d6f8d40c13d55987ab261566e686aa749ec534695f11f663ff947b60da2022ce597fc0fb34ec15f3e3918897ff5eccf1f07bac2e362ec7c86aa73cf85944bd1e6ecb20c307eaa1c649f4382c932530b0c4fe8264764312710083d456ff2a47bfd1cc78793840c83037aa3d59c1d0f81cc6d9eccd30ad57a0c0e6d13983798a996a80905a0c8d90a37ce066f73693332a7c8efc200522ef1e015d69360b8494997d333a4f4cad936cfc591a5a3330867692b3e26f8bb810959ba5dced6c3d3ed4b7f5c636ce9c04a84e4f11f929d49d4d4511e5f21969ee445d0e0165a8afd473548612b885dda606ffc7c625e995c3d240e27552f08ac2b15cfce5ef19e512da9b5133e1838c87161e93b24e0522a760a1f8c48ac5a4e4d28853c63d9c26435ab6cf732cf2ffa8c5f5c296c12d0e22a19837c4cf5a1b4be55964fa4bd75c1e6bd46f823b1d7dcb9fdc3004bb589633a5112158b2ce8ec0b74eab43b4f99afe9bce21e88c703046cc0e902abe8940462090e1766ae49dd80a3d5c10592f67b59d3049ef19b4aca9703677ce7cc7538481eba145af590ce15ee1963807c51deb81cf9658f2828f0ac726074ac72be304288d6e0c6a640108383ecee783ca6d41b2233e0850005022e68bac2ab4a4865f2fd9e967689315e403e330169b530c9f1b5a5016e2ad6abda1fd8f3144f5f8bb70c8a10aab62625b930624bff0ed2cb2bcff5ed87b6126d77a7c4762321f65c2a284005149073bf312cc9897567c569f49a555bcc5dbe3bb7c4e222ec34fe623ca6bab2a5f8b2dd85ec3a321b57685e6634814f5173103ffed5982da3ca96abb2598009b37d14b00cd3588bd9aa522746652e93241e31b7484092cf56d8b32cd31fcb56f60c7fd26091175dcba06fe59a0c5c497c6f34ad37eae4c3879bc859504c09f0210c1e1b7f5bb8dc67ff3b9b596b3601f01920b57fe6a4e6de4c10f7aff55358f9f36dcfc4a3f4c070c769366bd02a93498c226bb2c19d5c36317f5cf50c6ebbb0431db02d3c0765e331ddb16636c16428749ce81d0748e56cf2d3933f8ddeccecf1cbd36ce0941d5c948bf7bbb94c9cb6ef0a9ef4ce346af930657bb82708347e47eee4c42370434418b279a80464a2449cf99d725f15975facc1b236218c4641878c75d910976070f13773a5a259470497e848835025954416d5e37b1aa1fa514855818310da5e68a4492a093c7afbb4f792dbf1df293ddf57066a85f80b409ae4a7cce42cf67363bef90eb49d439f82925b83b92a45715c3c75b98a552128c36f7d2da06f077c33d90250c98a0870d17056fe8a5f13b836ca7e5508adf8c8277c6eccb3c0698f071bfeaed4293caea8ab6a5493eda8f32df573b786fcb38a2c102399276336cd832c4b2790922b127dde5d3f1f516945470e27e62e34e7ac04bffe2d2b3cfc22f0df40c2fe939062f5dd3b9d353a529e2837bbadf93d51a5ed13fbd7abffe068bfa30e205b320b53040ba9e64149d40a392610754cd660437ff3b48a29237cd14dc0e944b0090270af7fc8cd4beb764186f2e6e13d0fb9fb73772ba89678010cc8ed65b30ef5de7d4a3e40f2113b4dd9022f0df50cb7ae3b30c96f16266ef381f86ad58b922f6597f2d1a770890b2e81f9793ea185a8a162d0131992fcea24e0710ab467a49dc02aa631e2ea66f7eddb5f2b2a8bc3064d34a5798843f2454e12898400c2c08eb89e0b70bbf65911f75ed06a5a2966d5783a2406c27b13db449f8b64508cab6c0d3264d286897739b101c4ebc90b0e9c42ebe9726cf26d173f2564e414c58bccd4976cb550810c12d9f9736368b2e20e020240fce9b9e0adc77f7479b1f7fd67bfd672fa34c95c75546f19db2b47cae86aba52481b449340a7613fb2a1322f2558590494847e931452093b234608271c462ca31a972b4b6a2c1ce102878246401748d9dfcf86ab65577e4de1c018df6a6ef889b3990486fd6cd1eea6dbd7d4596dc9a8706e615931ee039ceccce7ed5394a1ce33322880130fc6d82d70c54667753a8c3dc03a75bbc7c1830bba73009250cd9f12fb175bf208bccb8d6a43829717a7c26fccdce67dbcd38a707c5be3b3e2ff81c30c342c79174f37afebd8949f561856601aba33afce703db49d086fe5d7d9b2117ecde06e04ea6518d09592f348d23295c631dd8bfc4a3afebfaba3a9bdf441c4a5bab5f8e7d0f2bc43822b7b4d40a0f68785384f5800809ed7042bbdebc18b47ba7dd0709927165897d26e0fffc280496b8989a78fc82a3922827134d0379e34723732132439b069285bbc3225b5c69735d947910238a9be754fe3fb55ec8ee8f1f7ea25de2f63c5c25ff893e64bd03914444d3f2aad3b3b4928811aec53699efbe9e2bae7ed9410341813522d605b0456f618d2bf4ecf185dce1578856ecff3e666d2ff82152dd65747415480fd74b724c522aa5e4eb1f12014a9201f9f284a1fff0ca605737e58d7f3c635bd1374f59533c6481b1c69d4ecd5b751366782f5f6e1b069c51e9c92ccc7972ac708a135555f4bdd9e80a0f0dc828a26cfd1ff7547121364fe626fe00f6efec41a2fd33774ec33eb94b107fa917f86d8db62f833d23fe42cd237a91a4074d9a1645a99709d8ab5dcc69a79da584516d16d283f3ca89b7a53ad56ee410848c460874cb20a7ccd30e5d6492d7da04f8e2c1fbf26aa0506fe7f471c7865b926a0a1be1b0ab038e655f71f179a08ef40998b2df39e6b60cc7d796d6f99ffa92aca33d85feb53d93b5aee22e8c408f2f34890dc352df3297ac88b05c539aeb5b9d4c7702a42d2ba45f551036d9b7c9a863b6893af9d320423aec1c8c974b9f6a38678cbe64b94ad350127773b0fff9225dd27bdf124a38692ee280b7e49d0d6fa646d81c5437f9a95e555770eb3b5117ec72be469180991aff029ab20f2f91de973dbb5ef4e4f69ffb9f75bad01138a8e9fcb0341a35b1edf97087d6ecda132dff5d024993fddaf763375e7d4383600e27be7f618efb7a89fe2211c72833395fe292965febb7a55a22f306a3ef82325c281fe5f271c750c80f4b45d71f7b0bb887b2933103f392c891ec7f53f22baec770b82be68367f6455b2c697356536c7754e74d873cd0013856c7e08f81912f50cbe49cf0a0a108d2d94dfac76405253dc07b632a32a953da5275f46faec723a770a9c7c87dcbfffe87fda95afbc92439536b57cfb2ab16cb71bf85ca13d5a96823081373989923be6515ef4f047ae78cd37fb49f366f16446f793cf066639c1f205d565287f64936d70ec5587809e96f8ed83011ba5658ce0441e560cbcb8060563a973e93925ad6225bfb0b10e2405ae395ef2d16f973c298e891924208c5290a851c82d7c418eef4e5a09df5d8ef2f79477d9c993182f97898cc0a4563db3f8f0c24851426e93808674f098b1ee0da719e38e45d6a57ec9e151bfc4943056bcbf45f05bf1e94ff3f1a72c7a620576a26a742951ccb0eb5525114a2a0e1af4c8b5e32b7f6fc285da2c62213da4a000c250f46bc46928e65334c4bd63afa541f564c7ac72b4c486e1235e714ff418d55f05cc349a30c88217d46cc87777582a49a3c354172411dab32f317a36b4bf15ec8af8e5009f8cf5bffeafeab6629180146c3001eec45aff0d6e07207fdda676713f699fa58560bd0559dfc614820a40749fff886b8c5f049f23b415b33073c131f3f5ed9f875431aa4840604f651c6420077a9c8a67028a071e3b09ca5904b9dd2590b9416860c05f66fd50305c33be05773edfcec2f72f847ba18e2dfb5864a170e916be5e7cf727d8d6e012eb6e72c4a46425a5f5f0e0946a86907890aa7bf188ce0748a508dc2329752e2d3ac6a1d7a28fcb7e41e83746269ede1294585ca2cd20ce4aeb3584e551c4cda332b5516f121c14181aceef9c2aee1ac20711a282f848ff61da4190def1ea872769a7578dc13b92fdee4d1b0225a94563eeb34046d8faf62de039e45216ec7d4a76a67bbd9075ff3efdfbd6f509d3b63ba0d152dca69c04ca21014c448e25a2be2f33c4b9fb1237e57d4687d7554974a1a3961edc607af8588dc960128747cbe7a75778a3c02554b1011d5e0f978c36823a4ab84378b6d29aa96e8b513a04c56d2ed729186cf25b51058399a4451d44c36a8c80efa6421d1614908638f5e1d1d324f97f8c4f0898f83403d821fb9a3c0bf02b9a00764c7c8ebbb1d347471403ab7d5475975e5e2a416e1857621bccfce9877b36862e031245c99b228036b2af0e3815d8bfd048a1e1c1130f146219402d3841efd4e8e0e0f2769da99fa10caccdf3020050f73d8bd03374864daa2a8524257e04016007fc0d79ab03dd3480c06d6226ec46c485a4677f90fc2b197ce238ed4b97efdb1176e99dbb86e84c7d8bb2bc92b822d6326a649861437c665a27d609b91d7cf94384fc177622347e8da54b44ec3cc3ce1eac1216e563c920e786e013e4ba92128336ad1c6fc0468eb580ffdc1c42575a346c103c44b27b8b1e0068164e7b882554d1f4287f3f3e104b7de6b9ac7430ffa3a7f4ac0f068879dc464d402062519bc6207177ca12a386b8d49e52945f680ba93d8355108737383280a1030f806890141d398c6f347c66e08478db52f98c8db96f8ae9a060aefa4a9091ecaddc5b32fbeddec4bcc5e30a8024355eb951fbfe5353357e98902cd458d66f15ebc9f23708987ea1dea707117e9d0c308122ddc533a68ec8ed060e27a351e712f8a8319e03b194723d0b5c9f4fe3263b0648257c017d3ac38a103595772ca55c7a1980646385ff820564a087066a9701acb4f92a1f2ef91d24808dece54ac72099d82c89352b637fa6efb3b2f8f6004c796d6ef6e3286b146533a04be7c3c057f14bd1716cd37d7e96bd5ff2ae6dfaaebd496d3503a7210420a7f0e9e39375cae789ef91623d739a7e3c8c82e1c73c165c556470bc2bd784683580618a4083dbc35d330bbc34732b20c0624ae80593a899dd4305c63a985ce292cc1ea03b69bc226761cc7bdd2833025bbefef9b9e4ba3befeb2648d75f2757287cf6f421f9acd411818e17fba652718d2cfa50eacb2b920438b25880aa9dd5c1bd7bc2b1db7027807ef313f3d74ca897a3f4962d45b07ade0de23ad87d367f11e0f29737ff51e013440de8100f645014939a31b46c7335a41d9e3e7ecab6e59d1f3fc767a9787fdb0a41fdf38f921f6e2805cb9c39ab68714d07effa2a8c265ce69343a9ced22e57dae6a6d36cc0916c74c3a8c8cf88f69f449efb2aeab9414b2fcb5586bea0e873de68a51e96a95b73b9bf549c9b87499855d73b861c8e9915e66913b9f5793c43b119cdfe031f1ce9b9552bb51e3e26b9baf82618adb386436744a3f80039068429635883c6d493f12d23da32fa9826349f1768837cb592f503e5c299229c0158375e04c44ef71548fec1b4568012c7ca6e3419607005cb079f451cd42d11df57fd8d32cc9806b1b98d343774822b0b9266013350fc32454b137a4c27be3a7c5de5cd986f4ed97bddfa2607e861d5f5f77818bc930b470d2d06f55799fbde53fc32afa38f89b7e0cdb1fcb19d72ddb034fda134b85e57479389bb81a136445cbcffbdfa760b552f8b827470d13f8b833287bde84e2933547239f63c34b44a60726ab4709223934ffce97eeca27b8ad2e48ee3648318e91bc9449e3482f80ad2b100dda5be18a8e154f5075e26fc3062a06123b2f667f2f709e2370129cf5c99a68878133fa67916d0d9c825518db75ced399af4763a0175c19ba1220b7bb10918150fc6cc581887ad0f78e3b37951a01bc293af86c1e458969d07087a061e0c0e4a5b07bf3ddefa7ce8ec1b6578b2e584f522b9b268766e4ed097eb75b37f1e67f012457e916d1b3b1b15224b1a4746c1dfda43c83814df20bb65ade9ff3cb37cda03900bcb7d64faa5c87e390f933f0dfd64cd821730202479106923b2f2ebd57baa8542b025edd2076951c38083cafe9e9bfdca1261f56c4820034bc4da5440a93e22a1513536983c3782f2d3c4178eddbb8d5c59b70a1519843a7351cd973e175aa17ee117f9635489b395c5b26119133666d82a4a32c53f271798ecea55eba81e9d876b81b52f2c8a47cd9d1fe7f088eb0c485182b8ba44ab1ce8d37b850e96e6162cabf0d7565dca3f2947f9a0204e853a15107e3b8ad113878c8da5905d42daf3b2be2db9c07bb79d15240594e95a988daf425461949daa0ac78fedc28b9f04a2d8e9412141cb9087e494551ba8c9dcc0b9f0bdf0431feddad7e9eadd457c60a4cd8d6aeeef6f6fafa9c50b3f32805e448d277b99865395a9b8afea114e53acdbb5849ca99b3375677d7916aabd026aaae0e440df5f114962f8ab105b6a2d3964ee85e4965e7270cf35d386db3d02c51b69ae6081386c3c700b33052b5c581d076759f1d250a6917a51976e5a56855cf79f6ac9e640631319dc0399c61127fd47eb4e0be4fa59356fb8268323edfbdc3a11841fb592175cd7f98892c9f8d6e3cd9713ac135514867593843f7bc93bb82638d2fece5d074af1b35ade1e176d16994006d1d42bf0df55ff169099d57d9d52c9819e477e5925f52116c97939ab1af1faaa42b77e4521a740df87ab6a20d5624978aa3c8a6df579a67174146d6166396e71ca971bc1775110dcc0c690b998fd1f5e5dea9b631cd3eb6853a1619559790c06b9c53f6b8b09f7f53a65c9477a12524a4882921b265cd6d25d2700212e134605ab5009870d8aac5a23678bfdae47e31636b8d8582ee1322731619a167f21eaaa951ac0ae22791b8a3bb259d38b3d197be249eb3e06fd36bc2f3146e75075b5e5587e07082ed457d45a30709205f8d52b5b7432ab85d9d47993b546c1911846e33ab3cad2331a2b2d5c88783479d4cc9c2722ea2de9be350673c6760cf8c0334a00cc9a8188acbc152509cab6d8152ca3dc05cbeac31d6183f568f87b47d40aab909eebd031820f4bd206822223f61100c50de2c46e9534345ddd5bb14a6860b7840ac2d8f18a4f001783ac7f7c4db7cfc3182f2a1b4fd083d8428692b0c808c2f349471a19190f52fccce24f93d13446e1af745f3346a61d695f4741e98f4913fbba83d47036dc39b15a8f8ce4b2f20081a8b3836e83447092381355909194cc026aa72501d7cb94ec448993479ac88c1308bf627fe47698db06334613e2db3bf4756a2d0341d9337bbb98550fa2cd428236661bd8ef06ad21c8f16b6ba87dd7b5694d4efb15f6ef091201d15586692b2ea84ad90166a7b4c02b92df270b1d4a203bb391139e981b2e5430dacba359018b85a1517c972e5514d30e9efab297f29a04eb8af1d86d1ebd504d9463799529653a13f7620a99377af4d248dbe2bdcea5cb80116a6af855408eb6463e89f27f124b331428b138f06cc8a30b5b9ea1464cd403433f7eae101d437c395edb3114f0d0a16a93e08f72ad6543ed3b5b6bdabbc59893c16523489ed71b55b08c09f74fbcec227604f6977546d6f8faaa18da7d3481f198174b05c952795c76adc80bdc3424e8cf707b9dc828f4b54664207ef9d972decf16967e979a79476106558b225957d40903f655234ade272afd6b19abae2d366ff98243f2868cef3e1dc3e6a5916804f3c057dcc4e679d6d63bd4d2765fcd301190eb2dc3de0f5da31fed49be2ae35a3100c51d966343e88b3b0c7c638abf1af094b802916558ab6e91d960641957b06d2d4422e7d560f0c6506d6cbf061ec68ec206f9a146796793685c967be1db53df4d5d831675a1d16a27651504091fcfb71a9b80adc75e672eef2e633defe12c715cccc67294e0f00610722719ae635da759f83960a1d8137d8042c4577b5c0cea63cd982a3b07b73986bc6ab04ede19e970b3190b3f04a8d2a5a70e55768a95671adabb4138831232b1f3d9311878819c8d0cb0c8f7f99c18bc808c468c18d87bec9c4c9c40ce47c658e4f842ab491969084b52731f8376924f4b48be239b2676d6966911f21394e0f7cc8d08f6d3566403656d3bf1dc5285d212d23117b75568fbb27ac698962cfdcccb5ea2a9ba279b598d00759e115a870723a5893b5d177ce767182d83c764439ddcf5aa330e4214edeb5ef9ab7d79a88b4c898db1ddb2135f3620953b64c8504f5bb82980a34252222a12adc87d49d2eb16354999ea3605fcd5b01efbcb266253f9646b1f6db5458d83a97607f8a9264a374b6c334faa8d946f27759101e46dfa45c0b8f255dcd16cc2a064c737628e3f3f1b018009263c40c83b3c8efc40d01f5234d51f31a338f698ab0c31b6bca2b6117484fa4c9c4a390b419cd3d192facf7eaa4813d1977704f41bd5b0bb7f707417a5e025f1851dc42ca08b22be2c905b1b0e022799f1f66d305279981faedddf6fff550d855560b06fc1f21c2839ed41952d051354f9ab83904e9ef7b818376a26cb06a36d1308aee40869838460575f58a70f06671b1a69d01f40a64b6884d93f7f359c971c75b0d5c5617cbb47ad4afa554b93055ddd9c47e8bc0e5aacee15aee0102054ac5503bc1da1e4da5ef12322f5c66cc35b88440c2cfa59403228fadf566e815f7d7a2ae45c3eaaef13b21e774f3c0ace009d0a85eb56715cb74d061cac3773d1dd25fb33f3d987bbf252dda64d14156c4a46f3906523ca376e30dcfea6dd8c2560dcb68e226759afb45b20d9a21fadada9ad1eda91c0fcec2e3f0b216192e5ae47fe8ff31a8c1f3e025e7e0fe1bd9ee9ddbe7954c38b2b0bd01c4e880d0e01d3238debe82ea2706f38992913e0d7aba43517aec891f8c24a73414c8d9e1bf22a091b0043e9083b80405a28b644b003a4a7e12ae1d944c3fd6831b825aa85d6bee7ae7f99d857244cc3ce301f651ee71f61e9bfd2b88427c5733fc4695b42240d855c9fab2c842396ec0fd15e9ced8b85b2bff84b3ca4782d7282774e25c5d2f43bab2d6d70f1c1d2b6210d89776a722efe97e6f84125f89c7dbf8974120ef66d615685cd62df6215ebc2fc5ad7621e5d6bf2153697cd54c56adc5e45fa36156ee84b3d770e97f085f55fff9b712503616a411e4b5dba9903301fb2850e5505b354e414146b68ec6dcc2728d8836aca36d98c6df50b542af543359268ed85bfcb7fd50c08a0e4c3d725cd59e3c2dcea3be9c41a35f14cd5f7ec47c46a0ea0b493977eeadbf63959edf75cc332a7ecee656d77bae600c6a71b48613ff7f6a617ad5b08c4b9bbe6da03b36aa9cb20816056cc2fa33d3bd6295fa8ddaf0e2d1fa3a96bf900a3e4cce1be33836f0bc5ea2e3ffbbd29bf2238056948b546f4d683cd2b480a419f4fd800880de87ac69e0b91c6f4e5dc0899c4bb58a3a9f7a7eab4a28a2cae798a988678ade1d233c3055623fca2b11dbcf29e60a275b963e48bb68a477dda827f5b545f4429dafd4f09c4c75a3413e6f9572ef9d7f1ffb6306b84d6320b4e4ba5d02034549e810e65705a78712a15f07acd38feb9110ce97881b49843fbe2ac05f0769daaa6876b4285be5b08b297d730ce06a7058976090b3b12086ed5585a5106b66e9196bf8e82375a197e581d3304a7fd01b6976bb6cc37236a39d9745ba67385b8a89a08b3401333fa5a3c386d491c3c43f1e3fd6f5a31cd66876eadf2ecf249808117e2435a236163d0f2072dc76f65ecd64ef2826b348e8438038c9b023889b151d96725dfe431f793ec11786a0a9845b9279a5c957e747c1de588fcb2cc8adc5871bd7e7b674316745e43837cac7f93bdcf169a47438988d126c0ce5f32618d04e4d53d7cad337b8633df2c9e29a559af3929a438fda89f7c1be45accb8964a0ada5512a1ab87f498086d935be700d0dc8693283d91ab003e42c33750e92942b0ca240a3915e26c7d8af711d48b916095c281ad17f09c5ce078f9927ff1e3251386b02fe2e13641fc542a85df3bbd8b94e1fd91bdccbf256666dc506e6a7118bc674edabfd52bca2705ef42b9cdccd5716be8454ce16ab1eb936fed249f01e17b6935523d73dfd022a873c0cba8f06b1ccf03849453919bd10c025f7dcfe5abf9ce47dda71f76944b83db10c6f86ead0dd92c188fe78704cea3a3d343bb403fd9f5d358960e3421660373d20cbfde28c26239bb15d50c58845c1c0ad73f3232c8ffdbf11f689a24ed8b57b67551047a4c9290deca236a096415217c234f598dd867ebd98fd61206febdc7584ff3085ba2f0ed3fc16564dd7c0f6c8427e1c1486648f727759c3693d8a8e17aee846f1e500958e65d066235029767b43e8f423f2dbe144a39b292f19fbdc348e5df3040ff78dd2c410a03f9d678b3ac16ac19d84b1d5a9ffd873080e5369f858c07133cb3db6ba0efbfca0e3b0ffe05db70aa70537311ca201e6de3bf16bc68bfd8ecc995a72ae8d28a30368d2bb435ebac1f45e31d31d17322bb28b18f9c8af88d2944f78660b00e26f22b186b7f2843fe76762d5c3bbedd1c334285fe1f4e8c5fb687862ac366b0089182b64a16f316eff471af59ee2af56080521f7f0240727c7ad8bb43fd724c8d5c1efeb7e55e209dce43720c2faa428014d07b08dbec6e7e6800b92d0f498a1e23bb815ff77cd3d330591524cd041fc0e268a4e94f706800af7256f2baa60f2fc87999b1774a53885c174ffc2d33553b417ce47294e07072ace858ab547d2b078a3bc789604c775ef89a19adc88f801f38458eb26e8ceb610abed0be0610ba72089f3c8919e30f3149b199a11d4def828f444b603ac4ef5e69b470e0ee8e06a2cfeefc1d593cc1cfbb6c30506c5d2ec96d326c30da84abe4a32eabf660b2b871adc41da4ae70317bda6bcace7d28b4b5105be15e1417557d467c950f874c51d50cccd720935457952e73aafa15e5dd704bf56c9a7fce9c309c57a103e1d031214cd9ef8e1b56956339e8124cc8681cce5ee84c13d561f2c970d719db12747c66c4caa3c7858f7d17d39297dcb1c2f30fa708dc4bd80f4083eea6a6972503dc5433a0bf0b27b2172b7dd4fd368603ee51923fcbe6c6adbabadba04a6bcc1ef0ed085d3eff0d11dcb81dbe322866c58d93c9e0f7f532154437a96a80ab84822e4bcf7c644bc0c5d9a320b9b71f84ae9e9aed41a53115b07503fb9dd37e31c7e02fb0ec10adb5e638ce5403ab0259ab8bd581979f6b8ca684ae7dea09cad901868db54f3b764c6d9e865b9e2cb2f93b75c4c77413a325c158adfb22a8f159625bf6541d07803906c121d7387b3c6dbd67ce4a278e943540838289ce6e69df593a5fb7d2a47c9a853539966423e5f237e1c6b282db3d555b67ac493aae4803c2795657ea1ce0698d9f2143b6e56b9d3f745cea49a9d3c2827faa4c629a3f7fb4784af695a753b7033ceb48a7687054b1ad4af1a076d0d84dc13d21a92488d7e407a44442deb6995d8d5c5eebf9e8a88079810c48e394b34bd4371890bd1036dcafc751d5476df0652ab1565fed8e852331d52ec1eb854bb1625d0c8dcb468a578d157982b45bf0e111a087508a879a1e73422146896b194cd39479dcccb2766968c8314f113c151bd20ed0d6e87a1a1ec492e06424331186664f7670f34abcc91ee0b0230d6fa75bc034247f81024d8c72a7183d930dc539453d9521fb18d1282da1f10cd3f815879e3d310cd33e36114cf3a6ad422fadc3a38463f240f7c7084c609d692fb051c4ca7dbc4460ecedc7fa34dd3773b7618fea51f08237e6f69fbe22180f10035fb4b67938fbfdc094e211b49f5c8381c5417902af069ec7f66001e5a6f71050ef68041eaf0b2ce0e66e3ae5bf9af8279a4069a05fdfbeaf49d0935544af142e1134f2516ea4e231582b5c6bbc7be033c0f6a708a2be9525174700643306c86fcf2092881f3373d059893598fa6dda2e58f887fd7c0fec0e349400aa02c84d8d0fc32c598c461fd0c4fdee6508015d4bfafa52580d3d003fdec126121e1c4411b6756b3ea0ef3d274bdcad48baa2e64c745650b22081f7f8ca597f03a757924cd2a7630210479c809c7b6a001ccfad2f09e2c82dde0d1eacba427a5fd7a908f588db265b0795728026287831dedc81d1d0fa8a628a919cdab9e0c9d41d6ebfbbde77cee514f98ae8aae3ce09a063e3cfccce9585b176765cb5a11bde31ab2975e9dbdc02dd315b9cad54c4d92695dc3434654a0d4e61c7fb8aea717b0b4f151170a1a76c6508be74dd46e1045cfc24a7486d2cfba048ae8baa28aafebe16d7e8605eaf5811473c9f1a2093efa8312fed2d68902d619b8e7fcea13c6d04372246661427a98ea654a173a931f16f69dc9ef6349e85710beb761ffc4d3820d8fea5bbfefa556ddfeb180b6d695f26f07e9f1ab820245f52057a5b4a56e19b36d671635334900d12d37f1db77060352b3a317f9521b3ba46d6f12974279952bf540f7692dddc6359a5f0ea9288cfc412a654a092889d323b951c19238c555e74221724418ca43927b8755a62fa0f4393bf242e9eb438d538440072f8f65c6cba1ad201997d73d5a0495b5a86a4c4d10b010dbb703f2f112707267efc656291a232307321a30cb7b6702d4a9ebc4b2c954ef15ac00d4540de4d8c108e7c5fc1262d58de278e4a581d6d3f971d82f65a00544ffef1341696ba4edc7ee6c4d833272c56870593f22150253ea751f07d517e5290258b19dc8712b1c6ab778ca29fed71207265639f85a034a2e018528f70236a7a5b2a6dc15b1184cacfcbdbfbceff32cc5c6886aa8d474419844f1c93f3ac8f88fc7c8128f133cd6c27f0bcd6dfc321c78438086fd0bca2739d0945213941f2802a48e8bafa3b9325ea796ca5caa7c044e4c729a738ddc850f4da4dfa2031bdafad6243ebd950c0d227f6237ad047cbdce96a7f768a5b29ccfd628cf69fd0545891d7133eaa0a23ef348a99a76971ccd8d94e5cf5160fb27841d357ed318cdde1a84a89d2632927eea4b1e26bda7237f732240374441155e13155ea77437eefe6321acafc5c62b664c5e72739a47aabe70aef15ab564317a6e2280d2b8dac79cceca9bdf10622639e74f34bce785ff4c8edd345ced2e33724000bbd931e2650c59bf48e8543ec44d37dd4ce2074e4198e1dbdf6e4ea59bb696bb94250c847319ae1e11f36bf2a83aec870bee10a5152b666400edb7ce39c456c55c11aef9f4b31642dee0508d2582d275043b68532938f7f94a7e1ac365fe379092ea852e61ba198e307ba71d7f24fea3135966adb11e28b601f7906aa23b14656bff94ac16fd26865d0be09a67a4e1d434d99622f783e0e9853f278fa4ef3750911d92e3b3ba9dd7f86dd94f7d96a1849ebee4c2bbe1fbf174fcf4fb7df8223fde793330eecabc3f66f39feb3260950b51ec0aa19b0c5b1874a01ccd5e2a19f10f10febbb8fd8ca1c09ee69bbaf2e79f04be4802828bc0e64b6b0bd55cf57b12db8b2ae9837be2ea0d5cb3e3aeb80c23cc4e83d396d2914b0851a927fc4e7e2e45dc7dcf2388eda72e31344f20d9be44e3ce7c1614e0dedfd131ba2452d924d1a3d7a0e16892710f29ccf500219ce0981cba52781fae9e450ecac54358c3aca75fc0bb1afa43ad47c638a5ce19da592656b16254f6b74332ad0139b454e6c74c82ed09da304eb3c206320ed41c447d0e26c791e6330aac86e5ba2c86ebbc04527d0d697594c452d262ae8ca873e3105c9766fc15c1fba05a39d35af63c0463727d9e7f231189e6af342293cd06acc92b2c585f10dd842f1c9ce961e1ad7394b72489fa75a3b480476459b5ab42d50349d472d33f0979b1b3cbb016824b0e20c715f90c1525cd43f6d8fe13fbe5da5d3cd7b4daef1b3911246114c7a58f0ad5454f5b102ea1c151fe0324ccbd0fdaf93c91065842cc69c67c44a977f4e82ec2e66c4238cacfe0cd63a62502af2db91919f81fba9dbb15f2ce3ce2878e732e37788f416983c96e86fe1c912627ad9a1088a7ee132e29b1a0abc14c2da7a33d2224216c9bef60c4163618b19f4a99ce8fd700182318f456947ae0043129e5e9870a93b5e88b66697320f54878fb230f176af42bd7c511d22604e3b1b60c7d298bd1783f908590453d241e3300976c162950ec26b1aedd83992f877e9406e5b21dbe3b80f23a83d44f1010c22aa15ca1af1251ba310837d8811b27813ed951e11ee6f8efe11b2581b4a201b83e90a9c5b8b88ba3e007fc2a11da087ccf6ee95d720e5e6fa181eaeb7c90b636217d34cb868aa74203a6451fdfa4f49b345af930f9eaadfffe6e116958adcb977608cc58332aa0138611a18f837646d85a84f0264b158326b37165014cdbb73e0ecbe41d7a4de85d313b291c5f1871aec8480be7914b78d062e4e93431d5ae0830f1eac3ded695eafadf4d1b34d14b56318a36577b853f2d20c5fc6873b243cece275d21988cbdd60ff4ca0b4641688d814b6fdd7f6e8b35f5f492dfaaee36928e3189c71728249ac4264c25d1c628e56877a3fe9cd950cbc0e98460ea8391e26cd2909471a2a0c0dd5d222a1bd1f04c3d0f693382ba2485ac910f4603c18bdfb4a9b3fca1b205073bdb0701b774b11406199793f1381743e0033d62d498a0944085dbca1ab4aaba454abf7d186834631a17653638cd0cd16be84c3c99a34c643af2c071f30a6d0e98aa7dc29bb379ef70de3f18326859a12bd9d1cd0b68773af1b2f482e58d85427935ce30a3ba71a39514ac400a8824d6f15a2cd48d89629a98e5e39632497f4c716102c67281196e6f2753b91f0844263349333517ba569c483954e3a4af7bf7132300e914ba6815d4f9d07d113b72710c79cf8fd673845e10040fed5de6046ed9ba625863e71b2a7388b3b52e1b48026e7198f6382f6d374389e67bda5321ecea975011380f112a4ef0dfbd9dcb9e98c59cb26b8fc18c512a9386671e80f2a7a02776e49251db1d255719849138d9ec21cc2ff152025f32e088439b7032bb39c37a0474bafe18799f4d32b927d112c18eb5ae565f5dc2bb660bbf7232b7d7bacbf79fbb1ba1fcd600a241b61b6c0e00553e2787cac5fbbe1ac8338e14f55290611676169496ab0bd04d9da86fe7c54f265ca4c0eee865ae01077d75f1354e2bb43e1a265caf29a20fd6c8c7e0a706f317a3d8c65ca26e0b83ca0ede45e7a8789c192fc63362de7e76eae54acfcda396f0789401f5885c0a43f751bcb2275c7eaad91757f0815ec04c9db3a2ec5a59b039164f743ffdc46a56ab7d2081ae5a7d78740b6ce2231eebc5ec531f8468c021787d192969a1c893338b5a5c15f1c7d89e14b29ba3523265e228da863a92f27e4a8feefa25a6dfa44fd7627adfd04d3f0a1be452b9cc48143081503e724af47526fcbd610ca2a73de36a926436970b1337210f1cade2e91d385e0b123f91e1f06c5350afdfb402c31449b50c849d424a9e235649f904434d8c0ff5f85a6cba70007cfb8c3d2bfd65066afe8a0114e6b724c8675468aa7f2105dbb925ebbcd5c31b9418904d59714b88e379201b5c19163ff33a3a66983caaa6f3ed65345872f4333dd52e28cf84b303a44299084287330c305673a6726fa9414f419e7daf94cdea20fd057faccbd2c6e38329a43e04c4e17895e0f7a53eabd628cfc93d778d9a252f5d3b808a7fffd04bf0f0aef51d775eb1c4481b93708aeac67e73c9a9db666ce1603fc98bf0bac76a9218b854fef0bf957c8e75c611482adf165232ce1b7d7cdac92b4efb5dbf1ae571424d5e7c7ba8c9a343405dec67322e44e52519cbba69b21a6fd361b279fe3c66d1251cb08f91c26eb97b6bd8ab9384edb3062089a91c7d4423a3178ee911284615c375a572ec4cd77e8062fb352472e61016e8f7d48e43fa150f561c4a1f9d9ce015eb3b47b3bb8daa4c97d024bcea9a50804120ab29860c0501e039921addfd8cd949d6cb04dc32a0dc6685d8b92952f5ff6c49524ea32c4e7e7c8a818a906e995549965bbbcf11398b401f1dffcea887bfda5770d0863790550e2c2a9d38b6ab21e363ff93159df21b10187cc149cb65923b507ba2bdaac43ed2d5655d4cce9659888f3018c928cb17c1b5b7893f4fa26f3db479fd0048b8e1aa7a667c057b7cfb85a7ac741a5f37119f3130c95dbdc484a58961b9323a256a8ea39806e514dca792b355bf3567fcacdbd4f86e128246a2c317721853ee932086a3da1e64c469f15a90e9112ba262b9dcc4a171452f84ea9047546d925f1f2a89f8636041fa505b1208f94af2e3abe3f378ceb145883062f82e768d2cd384d5bf7e3bb613304db88aeffd129e4849e36425d14e41f8bdd87a1b4a9372eb46ab103fdadd084e7aac3b788b0c7b6c42a120263dc6081e6dae1f403bd180566e275ccffd99fafb55239765a4c17dbcf86bf776f68492aad77830f3d8978848b757dd58c31df1da38f720d53c657ba21238d18e15462d6c82c11ce75b81d8ac897dbafd921530403ee9c36021ae7759d59bb43ed9d64f064bc0178c9eb9d90423e03681f2f837dd3a9574f76c5ac77c51412627d0dedec3280625c3bd8739b7922d4ec95e63f62e5450c18f78923f30208fa4d50d5d485e7f8c4400417ad1683c58445812ad90d83e077600e1bc587370638caf873ba43c5866beadbe55afc162db30ac5cce76c8dcc9d801153ff86ad436b80f15b158d782219479e863242446e8fa569e6e2b6c9fda9cdc32f46403142841ce116b2428ce29b1f0d8880880b4ae130d0f869d18f93434d24a7b9b6ab8b6c4430c77bea6471ba4fac862e32479cf6d4c8820894f404267228982ec13b3dc1aef5a21fc5a1a8ae621e6b386f3e1c522aea350884eba9faa50a4d8ad32e33a5df009516d1655cec9bfd178fb12c34a2c638ba376e5c4e16eae698cd6829e7da4544233c0cc4356f1fae2e765882a46ae1e35b28c0e4615fe14eb0b6972f950ebb9f2f58642365faeb6f4fb35d985530a8309a08fb6201b0a440a15af6b00d75fa4fc2928334613a94427940b4231afe00c5fc0847c4619a92188b79c943859a64dfccf059ffcfee2559f8e22d535d2f9d979ad83faafa75ed9170f31e35c322f11bf17d397bc449aa8211d2b1291007874602d28829ab92451fc754f45d605c0a7ab5c8881eb88b2f9b171c4ae7791fbd054011417dd3e09997db9004bead72c7f09391dbaff80332e7143e8f8d8cf1773b51044f9b9534cbf10dfd9f59aab09857f36017607bf2467c9c920c71dd60c53fb452cff77ad2ea22f9d8600a4017a0ea2121289e19a49ec01f38c749ceb8ccd148e48a000c976f34462df34021c623550333a6b6403ce40b53c37c1c3fb886e7a307a71f3b15a6080fa8f60f6b566feaaf1e4631086e06f3889313d34ed67a34cea12d53cfed7570418d30889c36e18a4714ce7a9c636beb40cac9257486c093224c26fb2dba328f0a903603ea02cdc46ae16a29a6fad406c81ad17c69765e5b7c218afc862f4a182a8f41ba5cd395fc145ee8c0c852b36c1350485262bfe7601147a082408baef83a8f661587cc6805d781547af5e197e59d58c1c6bb2b32d46208052ea882711b419ab02ebc485d987952d839b0c23098ba1a9bfdf07df8c476a4a15811c81506f79e07393ffa25ab074a892a920eb1b1b378661577f4ad84c10e386df8b90105f493925819e6782da71d8b12c31380368cf293bdebed6c03eb401a240946b1121c018d4000da8ce39708e73f629ca422cddefab5a2c46a71ad1a0d382d832212673c8738c191c1b04cbe925909ebaf7782e6c2bb926311cf6707e0d0fae6c7a8ae950a0d59d76d8095e9f47c70645738c1118408110ec9aea086d673502b7fbd0acf8c30f00a1a18a170acdada314e83e156d2e66147cf7a696614a67e31be00f89f000ff67e9fa0dad44a31745c9cd3f21f56a77cb602eb7fa1c2d8777cd6f565601923e098ca852c5eb41a9cdf2c52d293dbe0b9c20e3a3296e6d15a366252d354072b5a1e9b0a1cd91a7d27a87af14e57e23b9f153a879735aacaf4afc69ccff1d818ef2b28f6f411863754e2099df2dc3e31479458a664a948c1f9afd202ff640a332beafdc2b8f76cbf907b6831cf555854c0742adbcc5735148fee72cc64db2f962699ab65b04f2539e726cdeaeabf0a89450c8a96ceb908ab1d2afbbed0be94050d82e282e0eee85403bb32443d85bf1246df604af826febb9ab0bb2f2c67f6712bd269bad77be8322594f59d6c7f7e825ce21b7ef5523bbfd6045f1cb97f33b4d6334956d8570dc7a5791eda292950c914fad0906bb9da480a7f99b37b9846ba6e09ad001eed8870a8d996322c058b1edde2580bda085ec371cd0851384eaabc819247406862987aa34247434c10df075489178b3e2a3607c1edf5a91fcaae9c446b6f615517704decde29259f09eb76b4a655478abc2445a76b8d3f27852e5ba1474e4a8805bc2426d5d62540fa54e03b1a7f42fb481adda52b3ae4ee70af7d18f6fe176d064114485ace3bd3c572a5d2d5f13e7294497390f7f6a876844138ef21e1a81a7bb8ac329c47ae5a7dfa49593a7c5f496a8592414e2e3c6a6623325374c701a9e6d2ed9ae04ece59880910b84e330a3674070d8b1417344a51237b865039e1ab4dedc13179e487fa476af856cdc0348c16c2ba1bd11e6639d480cf1bf456a4ee4ed2bae0f2bc5ac491517a06fba40ee8d501309d668b12c18209fe7d920c884f7bbf8e5214b967bdc183035b0a85d3ac044281bc85adbc263990666b82956dae078d276879ec6c96a2710a3c6fe25d23d23d8e63396445f0ab37f0377ec9b1a79cbe6e96ef8a99db3fc7f0a3954dbf69cf79dc9bb0b9087119342b0356edd04ac97b01af9d11055549d75d8cb11b3cf8851be573344ef676d24fe805c25e66a1160f808528e19490990e1991bdf1641cdf72234176a4d879e23b75d3d456bb9132e7dc5f09622c0c358adce7c04ce90d2f48963a9290d980ccd05e86c169ac2af091889a6149f2becfbb1d33ac5d99c78c7e702e2402f8bd2662314337e1d0940583baf5510a376e884957365d3e415e6f9556346e1f0224c3d30840d61051cbce2aae1de8b987c6e918222697a6dc9795b5d344c9203aaf1872dfb263aa9c40f26f19a3a3fbe325943a8cf006d4664d60f08f90d007cfedc3770620263a96d5f0c084c8102a728ae77b5a22b7b59e574e0b2a65a01921d491ae334c84962874f0c77f0ba2145db7a6a92757ed271e3c2cb1001f1eab0bb9bb0283daa616a407145bcd60958aa395d65fe54e41459e8f283bbee217dd10706011b4e08212d284a093a4cfea975036c27bf648b0844938aaa0110b8367bc6dc60ff1fb8693eeede426f15c70109e1975c81b4c32e471d7e48be36cc17bf54d9eb59c86932861c2885132eb4beae3e1cae086e805c71365ab446f6ab12d57fb07384815af8b7cff51e0056e492c2349fd229852a7c58c229d3a00b8f7145b0ffc5a93b2acc1be91d8941c2d4029a093e014b020f3f953355935fdef76fc1cc0c9dd56b3380df5fb56b3f3a8dec5ec14b91a5a771da8329a81184fb0c3357e522bdf46052b6e4f01a9fc032930b5ac01b77702b5003719e2ccea851c7b705e6d0b03f75a85fd6b340928e4403640b259e7259308f364c53acc70bd8b43895e46f5cb7e331ce5e85bb2c5470d8b388f2f61cb40169567e540b9c9e934e21ab5c9ad201738fbdf0ced0068e57a152555736c9af2201d9957683fdef1e81132ab60bff2bec82cd09e20518bb1690c100e135f7c39657ee4971c6da58cb92c94f640ef30c6a3c6e5435c1ae87214804425da7a58c244fa1881cc396079d260ffb909f222a0119c62842b5027132547f1c3c4774f17d83abf3c3e0b69ee1c944d4f56f024ee502701e13f6357295ce2a4452d9d5483aa0cde59f219acfb778f98679beba3c24ac1de4d661932abc8c7dff298c8e55c792378f386c4e88cdc320ce46b017ab276a7a5f38035207a95f76ee24ef0d2ce9b7cdb9312b8c8f3bbd2bc5c1c1d218a609a955a577d121456b6b5320f5c4c14d981b1d2800c6ffdf57b6935f8e0d74ac06612a21179e72726ba2f666ed72bd021cc06049ae13a8f59309c19a5038d6e1e413493ca32049671ab75b5f648a9e5e3254b8134885ac295e5a3472f731f8cae3ede2fc2e3f23e065213f4bb9cfe48715ec560fabfed52b0a795a9927ca9e0b711382c89254492bde5de5b6eb9a54c4906b30806092e09230a50b982341e5d2030f4eeccdfb15ef6cdaf48ce9b614636573c5a1982fbe691086ae3baf25de9e6894bffbc745b48948442fdd5352c44a7254b48774e13be7eb837e57a1ca7353a0d6a83f37a8bcebeac9f1306671ef30281c17d77ac9751b3ecf59a6f2d33053bed2bc43bf7970ed4ecb56f20a741f9cc4c9d3ebbb07c36b5f84c71ee1fec8f23fa1257dd28d5e45dbf0c832d59722d0971152d90d50a47b8ddbc6a9b53b8356ed41bf6549183f1b73b5f4ca436bf0cbc43276b4fe10848e1022982b0253fb311c88a3a9cc273d953ac83c9e863d82885fbeed0a7b22986b99cc2d9e873d72e7093705fa0272702a49f8004488f81ce21dd219d43fa3cfba9b25fb1efa94a36cbbe8ee87d2f26b3dabfed86f6d9a58fe3d7579b3fcbc08e3dacf9a673f5b6ddbe405278875ed4753102e21d6c5e7ad989ab69651d01bab88cae3fde3abc7d5e61193ed7e08df4b986d31cf120cd0c9f27deb69f410697134b8b476d2397d1e871bc814ab5c5cd28967bba40a67b447dff476f466925121ce2e01037f49a0669cfeb45453e0497c0251e65d69a7594a028411d25a8a3044d3a972c71b104d54b1a67b6888e225d9ec3288691b08a8db0896558876d8fd560580da48140b486d6906a6acda80602ad806aa07fe7da05ca267781808080e66fb791d400c50c45a9813fa70fb9fb90fb90fbd0d08b2cd4de1ec7294c628341f4422015d4ebb50c8170cc146a8640d7b77cbb40b5bc98d3c5bd56c4d9838a8838fb107620162f2101083b141999dc8304ef68bf83bd7ccbde34e6de4b9f278de9bf67ccef3759922dd9d73c176f568689da98fb2c53f338ee63ce5a6fd66ec67e6427a594d2acd26cf4d99c6f569addac3d36b2130772d8dddebfa6b77fbdfdf70cedb77fbd6d4073a2344dd32e0be415799153ab7ddc742636833ddc3ed336d6ee1152e9818055aae490ee43150f41a65ff99703ab5429bde98128bde93e10a45fb938506595ae15f2ffaecb2ba18b5341128e7bebce36d1aca0ea69d4c610d4c6dbe7886f6c8fe375ae8c68d17a4d6b9235e92b64a49b68287c26eb2746fea3cbf668c8498152e00eeb71e066637a0a538d5ef429a549764095ffec24aed25e96f50eef30ec661ecb02f2a0609a28a16c7d89c0e6d5847749bc7b42e70715a786e715b93fca7ad8c3f2f0ce7a222026c5b26c486b739a85c6da28955ac9d4dc448b41789d32501bbbe39830eb288fdb7a007b7be0c5f8d758ad52ddc4715d3e38e012f8d1fab61d4c77bf95c25908695d20a96aa2e94d8911a0001e41b9079a54171860f74092ec0748b030843b955dcc7a8be36e8eb8ab1db57337f76c37a3b49f3e636d3622bdd96b364fecd9c4cdb3c212099e18bb11a37577e29d977e54828888e8fac1ed429d657dca67b20a6ae3ee8e027e9b0e8d17e3df751420bc7e66d37831359e4003fb4f21888388b5918b4f0ba3e709b47bc91f90268381e1b70ac326126f3ae8b07bcb92f74195d0cc30fe07a4e9259ecaff047305d8db8927300c9c5f94be4de4c5f80faa298adcee5a5f56205ad5dcdcd4ac8c9098431f3cb1d6d4695c5cde0b6a22413f3e73c516c24e1ba8fd1f853a493f8ff2e3513c8a47f128904813717f077279d8cfc3fb77dc1aec6f59d00708ea5025470dce382e901adc7727c66f5ad3176ef2bacb106aee24409dc47bce5a5128e8ff3aefda6a2ab01fc9fa6bc54247784ab2cccd232ad9e7aaa7e4eac9dc7970832f2d628d62cd843517ac7d4e913ec36019acd5682418ec5fad8b8962bf913d997b0bba4fa5bad883796361852ffa796e19066717b31ceab9ca557ef3051d092782a647ad5e780da7f981d3625f581716651f5495be8569d2cf3e40eb11f29a6ee9926e16f5e69a1fdb90bca32d0a763b0bcfc2bb28511cc84f4343d71dc281940aad4c6a1d651dceb28c0877707433eab99bbfdb6eee70ee1cc9aaa606a3501955eb35b3b88e8039d6cdbfcddb4ce4a0e60ebb3b1054790c156a762418f59e27cb09755bccc972ddffbd8b5cda11faacf88604cdb508dfa123614e254aa0c8bebf330cfe934a66431b73bcb75d126b9f82163ff3f44081ad8f32462bb447a3426df47850fef1336a7ebcd33d02daf419f8f0c11d5a724058a50aee9b1b479c9ec161af815f033fa7068e887ba6a5ffedf09996ce1e3e8562caac0bca3bf874dad7a626f4adf14e56d2a3a97915ea80e1cf7834d155f0e1f30186bf514bfbe5bbc1a92952adbfbe5e37ded8337a704f4ec47198240a6d478863ebe9afbccb974fc32a86fd9015ecf5e46c3daa1836b12cebecb18cc3b039b25232fb22cd0e74654040cfe60576c7eefff277dd6ad5483c3b132bd6c463e54d2b73e575f8427d500a543992a88a714ea0f4a4bfbe579e87e9ae5cebf228dd26dd174140e1389e0416d5831cc83b999faadd07d4527c905c5789075b1f1b3f9b20f31bfb95ec4dda9fe8b36cdf2208f7a8d1bba8ff02fb1776bab017caca162c369e2c34add82edd5c39ab69a49b2f37053145cdf05b82089ac0b2befff56c82e0f8a320117b3641e26fef9f519b2038520ec7cfde7fc3de9f7b3641701c3d9b20efc564128e7f6d16da682dcc5e2fc6622f46dee7a22d2c629c13e359e19dd8305a1c0f6b9acdde7a382bc0c3414c511bf2ac7ac2ace113b497daf96859d7f7e0d1cf2851f3bc9ae51d856bbd48ff208d0fead24bf6e55c364ffc2f8280a2669e1e26f0cacab6fde962e146d7bc2d9713d70f314129b1dc0755190e2465f78d6cb493de67772c4c733a6794a8f2ab10fffe9e454d5dcd92ed1c1ff0661f50f20e2c1f079625fb725a0ec0f2a50782a564fdca6bbd65a63ffd5cb92dd9b37c4f4ebc2d198fd2af7cf62b2bcf72879ceeca0f31c587576229d744581d9b81367d6627f3f420b9aeb703dfad7f3dd8929788fc9a3c9f428c733e8c5a47ab1a50ef6e4e619bdf53f83962cf3cd0f1bbf3c76d5ada745ff103c79be55fd684f3e241e1f733132394f3bafee2e954b0baae9be57bf3e5673d0cebbdea3498f3bae675bd9c89f2bd97f03517665acab7de5f775af3b2fabdd7535018e60c1b65d6e7f7f37a38f0659ef73c03da7b52656a9e0ba9a8ceee9e420d2c6a6051038b1a587cd1c23ee433450899f87e11f08b1052b1f54250987bad2aa9d6880b3512244248643082e486f5f0be1773afafe0c51879312f46de1fa4d0d87150011cdf877a86fb3c1b62580d00bd2717600248e85d94b31143791d095441eab99a5034722e4376560f70fcac113d1be214128dcf060ac908c1f8b82a7e76e1acd74868255805cca0720fed08bf208b285e00a5096b0738be2379f97682a4488848c80892262d48a25bf083c488b685234f4819c3142c037e5288210abe02b3340eea7b52840a76f19048129cdb09154f42b004ca0f49ea7b52840a9cdbc9c3edc4675e92a025d193c0d17da870a0263c6962098eef3fd4d201ce143f31c213d805bf274518c2dad35e687c361307f8f93ccc9966f8d0b321be56a22fd69510490cad86351ae8103e83bd55c57b1f4f3c212f7c224692278e38e2e5e5e58978b14778a0decf4fca8bbdf7df7d1b31bf3cdd7458d6a7febeb5e5e0fedefcf2a7cd87fbd6cba75edeb4dd48fd7d274ad997fbc3bb7bedf36ea508512d6d3a47e61412fae11de792df1542ac217ef4c01ebb0e43a21414443ee4507817df85927ada6e68dc75e103ec82b2a2661f22ca28eeefdf9be56df9a10a35fbd01119cfd91fa6f08368ebc17aebc69761bbd1a673e4c5e0047e7e2691bb1614f7a3cfbcb8fcbd3fa47f94a8f2f3a382ad96f75f2cc48ffbd196a7c3962ff199fca208e183e7b38dc7bbf84314b55f6eeec12fbf62b3e395971609920b8590c86004890f197fef63cf86fb7bbfc7b53e4450e1bbfcdb6e0801af8ff762565e93617f647ccb0e1957c6cb90f1daf3860f3ec9712fc3669bce911554c507420bf54951a5099cdb493b696ee571a08b959607effab6e4900f8d68bcb3f2594863faa5160f6f91221cc77d13f1ae8b700f8309ee769116db8d895ffe5ac78183e37e724f7dc6e5b997e7643cc73d0e6771c4a8712f0eefacd4952eb6a1bcd8ae228aabe2fff0819a5dc84772b6866c26fcc769e2e963d8fc8858ae4d07cb9fe88bbdf04b79c703cb928763097cd13f3f524a29aff53f6d3726c78307f72e2e3f9d46c6bbc8777993d374ef72338f0b76791e5c2c8f0fd4bbe371dcc5decbc3db0927c336145745efe277b6af70557c209aa8d999f8e476b2a38bdcbfb79978d8815cc88837f16ce4cbbfb76128c3f68bcd1b4ed9fc98b878a8c3c5c33b03e5ac63cfc19ba1e1230d4fc36bd7cad764a0554995c127280828e8930822826f7d6f37ae65e589537f6d9e98861897061be35e6fc2810400826a7dcb67f7f1e1c697c0ed467622ec4a641729d2448ac060a2089326a8edc6c4a9d75cd0de6c4c9cfade82f410e36f3c9c6ac2c5e643f44102dfd75ed0de7a883e3e38c67db1e9883e3ef85e8bf2ceba3f44a9d99930e12cc42f3978332f1f5f9b81f68f35c4bb1feb67f0719f1fef6e4cdc83fc18d28ddc265e4cfcd4e3b82371216bd311e3ef0b7d31d6c7b8d6fd610a35bb8f8fffb850ee5fac855f8c8f71fd5a47e25dfc94f5266cc0171bb16b3250d760d018d68db40df15face3af81724a6a11d1bafee35db422f4c8b5e488f87ee37b3305f0cb3dd2bd0bf940554c7d8cfb2f2fed11196fc980d25e18db7a784d7aef8470f1d2fa1e8c6d3af0f6b098f0cee26eee9136a8831e0279c7c30315fe27713be8da9b1befeec3bf5ebebbf1ce7a1e21a8f0531669d371b979d3bfd86b4d8f035336cbe870b7250734654fe2b88fef423e03ef8ef6d90f1e372286f748f7323ebe13e9ae0bb92a7e8c9b67eae5e67add07cbb0d15596cb5b8f39ebf23f28a996ad6f6d8ef82d0c9bbb19ac0cd685fbfa2d4e3a4afccec2674a2f5c5cd49541ddcc4331cbe9de78d791c784e15b9f67d17dd2e74afa587282e35b240be3dde3ecb4f9a9767fa0a2f663972752934b8a48c6716a3c1b9e2178bcf3e731827afd75a56c928b7743bc8f48aade59ffc367fca1bcb8cd117a5e92d68c3ea4377b5b9d478374fc7181dc9dec63ce6ea6d3e6eea893e10c4be970295c2085111cff06108ae3edd11a5201646559281ca872dae2ade7832613a5b5b01d44cabea544fa9ee233d5bb96d2b5e1b894bd2048f1f1f14182e60726290276ffd182c210053bac62488a30086187d8bfb3701a98e35f6a62a6e56952700403d6b4809b28cbb2bf01712624d492ad9c9ee5c4f21338bde9b6643926cb622b54ad602415f52d3e3f281ac9e688495fb23628a9249b87e0ec1b925a90ac8f167f42e50eb7b00f55d985aa6d85b32bbfe363b67af7385e92634720aa62089e5afad216c481ea8f056df7b9f7fb7574fd792749d24992dc217e38c183fbd1cfd11d620158a54a8e13b95f4757a982777880f4e5e93f3281d17377a569413ca9cf39d15f6f1037a85abf6e4b4abfbe7dbf6d6842fdc262dba494524a4d4eb96ddb9c9493736a94529a4d999b0aa6611bc661179661159bd808c3e46318b6dd3cb97bddacab2347e2459cdb681bc9a2e6ca28342bc6fb71a3dfdddd188c8ef4371ba4313542e24764594f1f51dbd150f5cf5e7c6c45adf6960c0eb6e46bd84fdc9ba66197e735d1216740022644b28776ec8290c9f4a98e0242a82b14b8d4984ca81e353d8a8a8ade18607f6e148c0155d3a3a8a6e6c5497b409a9e0c1429513482220abc181f09a1c2cf8d823706ecff845c90fdfb39b59aca8da9949cac92244b72f41390c0e831d039a33ba473462fb1543d954f950afb732a18d8e71c5118ec16945266997c6cdeeb4aebce1999349519ad9926c4d558bb4028ce3f70b6d257d636a368bd7eda205d85e22c24a3d77b3616c62c4ab3cbb95acae245b95197ba5bab0f9fc74da7af76f36c3c3b1ce31cdd8c72e1aea96e2f379d2da81e59791ca7f6bd6efe0ad2c4375f9b9fcdef951b5d6539c9b12cb0a8021be178076acf9a4638de99d34eaa49ab6afd3de7cf39affc86f09f77f0be9ed92e86201cdddd531a98cfdd7dc683621c55a962240949c09a086ea3da13c1ddede63a8af53af698559be7358124604205a189bb8b4658419bc323c8c0ac563299fb12dae8b299f2cc1c81b5cf43b0f6af6770afdd7c9d4650736320263ca7a671ddddddddddffa865c2d3e61eb1b78fb36764afd11660edb6e880587b88b50bc48477fa66531058450ace2e8fd504670790eae8c558ef006ea35af662accf0e982fc67a07602fc6fa67417c5d6b0530a90e26734762ae2c18d49c72f9d876e2965856a952a509b6ecc4aabafaa959c9c800a9914b74a5302b1a4534c630058d1a4c314594a217ad189f18c17add11ca1cd615a20356a942af9085297cf04449118d29532451a483125178f2683ce1e1200184af97717e7eeb7590418dbf23ff82f2afebbaf275fdc4ae9fd7dd87eb667f697515ad7b958ff8417befc57718df7bef3d293487317e775fc1145f8c99c784fd22515aa29696a8b9993cf10414445dc4b2608adc201c631654ae9002a58a185732a92e5e2153f0de7b0fd0e047cbaa7179cbb2de93ed5cbf4cec6030191829715a968c11fb793d283b785c33e5d2e138df4a93d4b23a17c5a8bc36faaec7de7b19b5acb6e9508a3d9bbb47c4102cdb9e7737f3b860ecaf29ffbd37047e3ff0c39ecd30f8ba2c494acd262b42e7e2e55dbcfe8ef58a13de9295ccfb14c947f0ededaf9d5425f5868d9b3b1c5f0c4c61ffb8ddb829ab9d836f036278df8bf177991c2a1cb9963804bf17e3b7c5c67c9f630c2aaacf009ad6f3de8fe743853af12def78c54aa64688246ab1623ab1b460399956e4435507e7c82395582dcb826f59d1fab6cf82b1c3d031bef5b03bc2f8967dd1ddea2678d61034bab9078f7c88e6d5f05d83ea1b004e93f3fdd32afd981e0335a7e67f9c5879224e0535e50a219ce64f31dfef3d0386e5fb2ba4b9f919343e8797c1a5e5858befe7e133a8efefe1332dba096eced2d899d74ef6f1e089d424b1fae9a8fc14d4155856418557e13a5da8392e41d11a77619fa3ecf316f6f9235aa2e629f39615c0dfd805fc0c1bc4af581c74c0267ba4478fd764ec0282e8619fe3609f770260b9d13b79b23494ac44e16473c031f6c6fef033ac026eb0c91e010288d77eb015aae42b0008fb83fda93e00f9c38c8b9eac0d4903274b8015db5578e75f5292c3084eb6e6646956abaea381091a3dd999192d38d901dc5804fc0c7b001a3601cfc3e6f0272b834df6c88e5fb1477c7892b5ec0d3b5ecbc1f278ed050c2fa0369d12dd617d48807d10425ab2ef21e0003bec7baa1b6c1142aa66830ff6e7bd1b2c40019f1c1f4e16871c804e5600256bddc03dcb6b2e361d16140b899eecea8648cdf1646d58a1271b0052152da638d9185215319850733cd193855172c3132cf4640150524285e9072cd686bfb13d3c8c5dfd0ccbc39b6c006ac0963d628037c06b31f6c25ad3182bf1ca0603f4c043001ecb98989898ab636c630d454f565505cb1eb1a1c136393859193634308ae0426fac8e93a561e669665e83d1a23a0660679e15a1cb7ed7c9c6000af2814cb4cfb3898dc4b3a1097a36d0c7e7d938f6d7f1427d0dd2f6f969f2fea92395864dc76a927bf094819e6cea645f686c00603dc76da0d85802d886626b6a56abae83414ff6621c52f0f4642d8d0c6a9e969eecc3e842cdf3d29385e1d2f2c205a98a140b5ee8c9ce50523243498a9eac0cb80096e6351a5b80d7fac662e073660c7ab22e3f3dc507e039fc4d1435471ae8c9b6e0af4564d0937df1828acf40474fd645ce0c54f46451781583936d8159deb24768eef3fb5ce5629fb7d8e72eacab665897e1b94a03003d59161b2ac0d0933d61d4cf7812434fd64414034a00e8c9aeace88dc5f1336c8e932d618da573a72c386c2bf1266ae233f267b8f7d7c942cdf40aa1e69e153d59d2153ec5a9b8cf0e2ca839de404fb6e21dac10003dd9110ef464b99b2832f46437bc03066a9e3394c5d2f031b6fb1babf33056c6cfb035be859de15116c6bbd8976fb1f75f58fb2eec3f8d9d7900d8184fc3e2bc0c36f539581d3ec7de78cb1eb1f1267b64875fb147f0976c3c09efe03e67ad28d47ff7edf3d047bb617f6a721e03ab1c1a9fc3fb80340f894a3f67ad28d47fd7ad563535bce955bf83fdd961c663609573f334afdd6c3aaa1a686c3cf4e01a6a68262adbf8641b77b65b867dcf061aec7b9d0dab63df53d5b0efa976b0efdd90d32bc0f2691cc1f273e81460f935f6bd1b62d8f7e43f1222eecab72e12f849293fb7c0f367d8f770c831b0fc1bfbde0d5906964f63df1b00b6efe1d8f774b0efbdd8f79eb5ef756fdfeb60d8f7e4cf60df93ef49293f57f9588ef571fc641d6b33f464359a1824d41c4f36c32b9f1a7ab2182641b1182000a5613b07db32d8cec2e7c73a90f5243cc8bbcf51c2c49a0d3dd98b85893b7125aef22755e154b8ca1fc650cd71063d59a9ddd093b50850222a2a6d21077a3a424314e3091af474c4e64df608cdafd82304f81b3bc3769392cd6d2202dc860255fe3516a8e6d0dc2e5aa2e689650e1d1ec3dccd13c075c6d27c5b0efe00eccbe17233e92ba2fd01762bb0f78cdd4447f442088a260ca2a107070f820ae91b375e79bfae4dea519b4c3132140a85aa7152184dcbac1521ae24989549869591483ffafa9ab6e954521d7529cd5a18068542416b8bd821d620dd388a8241699462196d4ca335ad8cb0c8d01656b5370fd0582d3aca66b4d7f967efb011c4da9b09028a4a7ff4189d943eefdab10c73edd9641ab7d539ca46a35ab9c69b968d1eb3c1b24d7bffd173a3d1d6f6bd98cc6211b70dcbb24c3a702001132a58315fcfc86ad6b1b36e1bac9f360a89d1df6bc0450c23aad9ba0cf362f1cfe99846ad152dc43385df0866e544352f7464b9cf7edb388ce360de06063fb3f2b1a704c36879e4c2674fa986b38e4b703f7387530387e9bb2fa6e5151e59278bc56a61a12cebe6d1d377816ac1721a3db7fd8872947bf916679956ac9570e2d7c41ab9c5826ce6e3531d2c629187467f77e8289899cf4097719a708c37cb87d2cab2d8d863ec7879503548e1022962d63089d1379e106a2bdb7333dc778d2549a452a954aa1bf7bde96c741bd511c7fddb7464e315fbf2e62a6d587242386312eddbb23288fbe6d7cd88370bb1f69bf673d3a1daa5518d42bad9c6d43efcba4c1bcf37257c6b069e14861ee506228cb4b398c91c168ece65d79226ef762466ef25656f524757e9ab734813f627ca5efadf78077f35af0cc3329865ddcc1e0d2ad594e714c2c16d8513217289154f18d9b1b242c9aa01760a8ff5f1555421c412427f78e89068051121de282741d0e20bdde87f84fa9854a10447dcd67b16c9f4ec235a824f917733fc79c3ef9c96d6f83bf0e767f87fcdc7f1a965af6536cf25d48733cfddd38779e17b29cb09d4fbf0d1c34711155050ddc40fe69c557e5043f054f1a2a070e0c0c15103071344a8d5aa5b996056319ec9e68e65f570a06e6e646e62d4dca45e0c9b655c52162a9572497dca65f2e0c1030f264d9c388949e04704d749813663a05e7cc8bb38e339785df40705ce5e7b528409a62f5f8b346e373aff9066fbfe9aade09cf55dbb19b65dd7bd6043b81159d8575b0f5fbe25038ae9a0e63682bd03f55f33f2330ad7a07040815254d4a4c9922519852184a8eef6c4ac961cf3ad9f77e7ba2b1914401fa7132302c3aecf450494f2861c0a7fc29fb8b21b89133e2a2adc21a51ba1c27ad1e4270cb5817cfa02d58994a0412f5cf15d88d20528d853d0ba7908b65e7e9e00f6da65e75bf60a02f17c400f966fedc8b7aed8f1dfafe7900f53a78939b107da4bf5503d098e5873ea4e65fd7c83a50c9652ba6069c252ca978f159918108a77e65f52429394524acb5a31addc1df8fd905a56da39bfb4c34975c46d10cbb5d64aba4aead55029ed6a14ef3c8cd3ecd0b42418c7a5bc59ce87190a5f432e218d81a030f697d51808c5d8cd42f07577e45f42f0359fb675c121f0a33dc2bf7d5ce53f8442c2044a48890753569a7ec063dce84322755a378e73adb55618ad3c7116d218f51a471d38de96f83df847546a3fa7f11115224aa569c48db6111d8d6ece34402b0ae350a8a6b5ce793d7ccd6990d452f8b244a89c56f967b3f4a2cb9726f70c33a050b5f2344d137195cfdc265e18c9ef0add45f2bb02f668ea4095d89a33a8835e8cff0808f5c16723d7d9075638e2be3b4c43b0a48dadcfb45e9687ab1c370fde3946a1508daa70855d1c1fa13e2860d415daeba1c98da7502e2470f925cd44c96bd24adea33e73272922765dd7c146a2110155b2c70e29b8f3fb3ad376a3714d41859f6b27895852e1581bc197857fe679100a9e1e05cfcf520a9e59cc69fb3d088c2a55a8600861bc421a43c76e1ff607f2b2c03bfd3e831d59f626da9b3579c8e87671a835b1069a825f46a1e644a1fea59cd8cb9b3b4cd33e2b9ff1293d4663882e05c32944409a1d3f86dad811323a1bc60cc4894df91e67736259d57cbafbf65f3dc50fd5b2df2c8e2088b3fa8c5f306b0bcb3df8baaec93befab5e0fe10fee96f75ef1be1763f15c1b98472956b4fe61b2e535aff9bdddb0a86f12c3b07949695119ac489384e1a86572b563d404c26dfe4ffb4f85fd6677b4a5056a03d435bdeb4aaf6b25457bd9c581317b6d07eb01fb88697fcdf9f2bf679c364f6cfea55d91f663dfd9c74d07fba8d538e9bca426659e2d39fe922d39a411fe0fcb8ba93cc26b827db4a62c64088d364f4ad4c62d6b44a9d767546373f6cf2638e52af7d835a2d46b0583ac4c5edfdddd6d9f678581acf00eb6c2d75ccd7fdb0d4c83af65cda2bd75634db2dbbf47638cf671a33a9915053cb1f5a2454466b79962b75aac7fd8a5c5ba261b4c502b76718042cdf17dc7bf2f4b7e4b6fd1e16fbdf5700aba0d20b47cf0c451fe654d4bb3a83564590d4508cb256a63d943706630fbab879e5391e1135c99f800ce328804ce1e028f26fb239e4dfcec623e183e41420397cc0e8506c3a975bcb0e8c5c0bf8107b5fffba38f4585a969d74529a594d28b5ed745b1ed29fdc78d2a690555f44bf4aba53fc281add948237deddae865512e71d2e96284c43b3bb37bb5ca1258ee1e84ad2881ea4e37d6018b9a2b6e97504ac9038330f42030e102185ea8f58c0f93507275c0a276131a40ed512c8b8fbd6988477304f4f166b66fa0ac61f8f4cdf48c36a39d4008e9d393506d4ce911a4794b9f1b68e56e36b08fadd9d85a3b65b7a1683ec5b378b17dd6349fa23d159fa197a679bf46ad53f129768acf74f654a7339fe24ec5a544f1286af6293e85092a3e932111cfc267eafb431f9f19bd37e1ddc39088cf9c6eeef12590c6a73c954ff979739de2171803e6b24f31add86c82a2e2ec5320139b0ff1b31fe2f97833dc67269bace1ece99bd93efbfa66e8678fbd1942da06ff2cfbf96cb4cf324824a46764d9dbe0ae0f7515517e9c802c780258bb0d454b22e836d0bda0c0fe50c8e454071afdcbe614beb85aedc862dbcd17fcd7c5cfe237f6127b4a309dffafc3fe6654760991c2d87784d81a82654751d4ce3b37410821bc3446d760956eaeb7a61f2fce0f0c51a05ea5754eece65a6f46cd9b1fa8c72557343ea455fe3f495811681ba2a8d5bb06837cc2122cf00476819f1460f0897e59ecafbe30ccba2d39e4fbcbf78731c6b8c323af0b44be779ced4978abd168f4a3d103416d197d0f1ec55fad56ab95e556f3c5d799f21aaddce2cc6119305aac56abd56a75d1408bdc4bd4108c614fb27684dd2c4f10638c31c6183d62187c4c30e79b0ff0a5ffbc32edaf0b7b15b3afc36260ec9b01f8fa9eff62b0f7f17206d74f22aa4351cddd65510db3d4f4fdf2750664e5919a5026b7aeeb9252da2cffa585167c6845fbc428c33d1733d02316cda25af445327405c36f21560fd3a311c255f0a7c0c0cf29f8d905ca14c914c914b58c0cf6b97e66600d93cf701c37daa80f3ca249d416ee7b30775df292b2d6ec2dc1972d22ce39e79d39734e795db74547c4f22396f707c9ba350a8fabe0d778d443253e6b7807ff39296e7ee100529f81d76fc648501b438fddc5d79cb68c12a27016a7367f421a1a9f0a53651e7c7d9bb4a63a46780ec1d7f715dd076b1ab4dcdd7e8bbc3e93e0f84238fe122a10841f7e395a6ee71d8c311621e4faf7628c90ff5e4cbcd93f6e3d780fb9c78888df8b6999df326f908b7ad7a2a3b3e07d1172c184e1253f7b36cf667bf9f4d9702f7f7b36a397cf3d9bfaf247cf86f4f2ebb329bd7cd2b35979f9a59e314d589e94a88da5d4b13ed3fcc5584fe18bb1e28bb19e1bc9abb472492f063ef662acf72f91ece8c5c0af96db36abbd18f8d4662f06be66b1f962a62db50df032951a6e4183f3cdc6d60565c90bd15aef177e0c32c2d6d367435fccd5fd8538a3e597457d6addf3e963f7480b8f51952ada4b4b7f06e9761afbc5e9da8d2ec30caa13337e748a9a35472c7d001193d24a41cd650b1c4b18e7162f6dce8861727ba772c6ec61952a92beb4db53c1923ed6f206815536efe718b30fc74d87de386590410d02238c0ea5cd421afbeca5cdb34a1ae76b1be4f7f56dad0c5af8b2b1ca2148e18994299240852734a6d0515a710a293af84cd182272498c28a272808a4c8a8748db694450c159a11000000200043140000200c0a86c422c16038249336397d14000e88a44e76541949a32446510a21840c21040800000000c0c048da000288571df742b7621445137b24b3e80261382691c04475410f524bf395691bd49648b9db2e4557c9633e6151f436eb6dc76645478374880cc1b4016c8f822e7a57fe254410fd296872fd0513632732753e6dd064c353210c850213a8ed25b2097cc60b0d04a5aceadc7108745ec000743940a2490b95574f6aadb3355519abded4df4aa8f957693abc6429c80f4c2c033026fc78090fb285d0d6c07fccb8179c04cb35bb1c1ce0368a06c6b6d57bd75a813a8c2a9aed3a96cae795ea2458bbf0250a2576a307c1f4883c3db847e604f2cc8d5978f6c9d30ede379b00393708d77d11daa5794d7d93b40be9879b3b73b91cad933a57d30a3b6f85be5334f399064bcc6a22a77ac1483809d664e476f79d1c26235cfd89c8e455c12221d11d6652c172ea1e24bab81a6adfda6510e2796c9c6fc04e495b08e824fda29e38a377415c847265f088912a4854e7c76d11fc8f113d9b65e62406ec21b73cc1a11328143b01cc630aaabaa68f9c99ba9f69b040eba9d67d4d0f93c3881fe6a4da8a72779d9dc8abce681f0d9523406ab292d22874d32710434ef06bb351a745e4b2e0488ca56910d20c8f2f6ec381c72c6ccd3e09158e68ed297aee61f21b7b923cd13e157d849ed6ed7a3d582a2cae4917c10a2e7e2a5485ab55c9e6b0dbef5323f5657b4f48c1ea73129cdfddbc646bd4b15028aa907af2f2127d19b975b341a903607eabee9115255692e45f2e2c1170ed9a7b586fb1e4aa530315d6428c191ab235e3fffa9f5811b87a668b5c7e2314872046e2fc1244598cd2a552009072115d937f8a27aa0e7c133724dfaea717fa83b625d28afb94b83331d0f789866ac8de6271922afc88b4c6586638546f1ef0dffd84303e9910956e76982b62e7fa40d802b8a2dfed01c39216b91a3dcffd129b7107fd1edec3003456d752e346931db25edba4b3dfa368b5a4c31dec8c3f552e1c21390445dd347c4669e8644d733432ce215a99fe3d1d9c8847a71f2fe7ef5a23bddd9b91e0f41eb3a465bc4478b270d5636b59eddc22e9da54d430af6e37bb9eeed034e36cdd8185891f61ed6eca3a30b30a8f788173f49765db70ca87fc1d24596a7a6e46e99558720e6f28f5d986d532a841f235cf46134853a87e91c783431ccc96507601e8ae8e89d6c21aec575cf98c99089587e59f69e6b3268264932c95776f9b7f70a645bddd2e6b4c6c6f24fe9acf5412a07d55829ae44d95637e790091da7de1c3e0423963d84ed82997718e637112b803860bba226aa1c5851b3723b65b6f3261c62d062d6cd213379170d116dd1519320383a99b543e9f2cb6c769c2c438ad4c9da6c669728d9ebf302fd0491a014c033341809c626397fd05fc20c97e04314f3cb37fa3e4a56e1921501aa4920ae5f27e3d2a69e35bc0558855d63c1045c3aeb0e63a7ed13224beb0560254b95d1297b649f9162582691d3609196fe3fd6516a83574f3623728ad6a4f0cbd9d53ae263e91ab4b84291cf2ee8b7ddee8f60356d8c1f36468b6f9b43e5a659464bea5a999289863ac39cd80cce03e2057175857eba116e146ba84e4078a02349c4323044a024809de53d8d142d3ac4fcd58c8c0e1810a32a63ddc7ace01da4b1fa102eb044bb370bd0141720034868fa24b971f634b850609e4622079ef98e312a970caeca24f49e5e4c7a0fbaec4d777b5f3f2627339a4a39cf2065145182a0a40c08e7eec98c1c0b9e64a5ff118966e89267772b1dc06679f53d5c91681650edd8fd9e0e4f206e901f88de82bd6aed42077a851afc56359ba47440f588ea7d004826639c2fc47c68854ca2af2698dc36e82ad8a9cc5ec479d2b2143833921e3c8dc488b0792e860216c5724b32c1fc9e52098781d15b19191c400771189f94931c7703ffbe793ec08537c2408a4aa8dbde39b7b864a5a2f81ac8f39c0454f4ce86e157a0d428727c849c242323fc6272d00ed09e060a338549cf98dc997a865841e4781094796af9218926f1009a3749227020ed62e85f6755cfa46dbecf2eb5f89e22a692466c6d3f89c69c5361e54006e34ea9c1f029ced0b953d1fdda777d94d8a0e759f5e706e529e277b5608418136e5a67b4be41c0d1e4e2949e4e5e90e84ccf50296e80e3101247fb40ce48c4d31de576a4bbdeae0e1a658b56802552bb2cac74a0b18f1b6705d727a67bdf596ad6619ac0558425b184106468359c63638e82c4c6dc959d8dfb5cf93eae82a1c1102d1625a7f21c25c2105795f9c00eac98194bf5d0adf859454ace477b5fd3df314643ad253f37ad13d1195ce40eeeceb059a50e8476f87e23b67e18e46813086dfa33b46aad4c9eeb462ac93daf63d6f929dc22f01c4c93706ce4b22775fe31581239d1c661a2e932197f36175b03b2fd86e3fa33690116b0c5ac7c7e0f5a2e869905427e3a0145c0c20bc32cbbf748419ffe01213912e6ba38edaa5a8edb408d614bd902600427ce9505e1009d3cfecbfa648ffcd44c0ae2df5f83ffe4e572a8aaf7575680b8f68e96c5266a67291fb923874bc574cd36a1a7a90bd4329b97cf2638f3eb26f0615a3dc761096b3d82d59e1460587d90ca0a21ca60704966c82b1b1db1d0c4bb18b4f1231e42f26ba9fef781d93f988221bbea620c09be0e24f18b781c33060b900335ac788619261085505f2043b50def7c71f6fcbaaf8803227e65efad97069ae40cc5f375c4652347c25d974b12a603244062bdfe3a5c8619998c44536b152bb57db91419b52244aa2642da0b3a0b3718cb69204ac19be0addef6c54c678a1f7325b6eacb8eef179a85d9613b808e253ec0901fc696c367dab9e26fb0fcbe121182a87f3f6e204b12941bb43c11f48eb9aaf97c752e2ea8679cb9ac245c91d1df512f11e892d9958620a8339a58029d0bb2e03ccd6b3b1574439084df9955c5c16b7e2773062604000940bb169fa2352ba2a442b9e6455d26921c48cea4fd7ff26ebdf0dd983add066cd2da073f0d9bbfdcb381adea7042199476bc6e51b99d4bebc811ea6070993a05a73f50e73111ddf527c2fc137da73237e2c00a58edc5d1f5a89ca21fa10360c1a561a4c8b169e4b3b12ece21a4245276044303b1de9eca008181d76b75b0f8d292e0152e34e2378a258db08fa9e57b5b4071b86065f7eade542245a36a81afa2dfc16e60e8d11b1e01ff04c3bc21d46c46d48994ef6270e7e49d0b0cbc0d2b40021efc5c86eafc02a445783d35aa94a2abc40aa77addc99a28cdfcc8dfdb0c2abfbd9598d7f70e0790e90087b422917d10da45d510f306e378693ca5603512d76aec8514e9c1386e3e544d4327b52e2228cc848f89d142db3ff21d859100d764e8e5dff15873d0ab1d6af630b8969200c454c96f12f7ff887a17a0c1cf65ca0d3fccbf9538cb125bfe9ea44cdb1e113f48a6abd98a26b73233c9e65c6dd67ca4029adb9293f762954865e4de2cf11a5db57ca36e66b20ea6b99e8fab4c79f231a28e3d926f74993fec84d1d475cb3b21167f9f2062c9dc046650ada5405e109157a9dc89f965db67e3070b2c6519206372e034f1635b8d1aabd66555804ae7a786d2678dfd664ed380ca00380686362568f0fb77e6869313d96701cbbcf5d01baee7f389d5813c10f1c36389b80eec69da59b79b49c5c6f9af2804a8248bb81a9acdeac0b488553bd7a700465176cae0478ab8e19449ea14f0ffba1e76312ab12237884035103fb7dc0c72566d1cfc72e4fbc71c425242f0d20a51235eee9fb07420762f148309732a56909d5ec9a8f01aa5b557719357f86d506c4b83eea07eedbc666fa66a3b63ca4a445683f511d87d455e36712742219792de0437c86a12581c093915987f0e79259e27785167117a9cd0e13d9dd0a94c7c4f483c8601a0b01ce227fc5aa97493601591b0a340154b6364e12ab263dc0543cc1f473559599cc820937391bfa98119e8c0dfbdd03a559464fb6a1ebf0cbd544d4b271c58b01aee81893908a0ea194476f9753a1755cc1ab80aa6a4f940a25e53df205ef27ca663432fa4e14997618326a10fdf82a4c2d8344319e0a32c5b73cdf6e7e7e83715d43c94256b414c56dc1877271b32e4d6f97787a5f3fac82157e1c587a8b685a74692da03f53a6ae42174c1b9508c0b2fb73fe865ac421633f14765b410204eb78c225b988d076fe43dd35294289210870782a12253313a143838f7640a72268699b63b0aee5e816f7ead6c1dbfa5c02f98683142b4fb681bbf0aed686280b6575251b26086320857b0cc9632090a4a04a447b9b3e8b0a3f7814dfe4a086251b84ab955d8f2c43fd9a70fa06613facefa0f0ea8be8b5c1d086e848f80ae67beea86998ae34e1559c669fc5bda5fcf43d8651373e16868b7922386e90fd800889ab5d468f043652e9337e31f0981cf7d3e52590822e4b32fa710c691641bb97f439fc4bbb815640fcf0054cd7e60909de63d01835795f31fc2a7fbd8f5a4c3557084097aa4fbd273d57a21e5b5fd03517686d4a01e314cbd1dcce246c8ab86c5abc94dc8d0e3286f8b29a295c823e7a58fa70b2991e37ec535a138ebcd7b3b9df99ce264aefd25e0040d9afeaefffca59d4e1a9904a9fc6b64a8c90711242d0ea1e3a3a4898e5bacdfeea17078544ad8ae287aadcffe0403dfc1045020c1dc92f37e43158bacd6138eefb6341fbd92cf40df462d61f2cbb469b313b814176c1a34faa421c719ea808d407a1bf1399dd72a2d5b7e2f74143b1cd4128dc67fef887626f069a04e7e7e9832bd567a0cb94245bbcba5634e5cf2dc0930b099b888cfcaaa2881989bddd435f58f0ffa266c75570dfd23300aead8eb45ea01254396091d0c7e781312d84589abb298396e33d8f6928c6e0371dde12865f3889239eb6eb7da35be9cb3bdb036571b2477369f7003578e129d6077e8fdd82192f4ec3893aee40d122f811a0a99a9067e4065f76454a7d6fec37ae3e6342fa9d62c68cc1865d77f0186d3d27a2bdd57b26feea7173e264752c4c7fa265f783d111e95cca1cc6fdba79023f51af732c218ab2141613196d592d48bd81d8975b0ac0a382da22740651fd8bc969af634d7cbaa6ebf20f564047feaefd16c2f61af209aa7e41c66290985d7af6dee3bf06e999d31499dfb5abc34cad048342d27cd90c932361957f7ac371fb03c21fe1a279721b7f4b4f36615ffb7170df145b6d3f481133d3085c8f16a824bd6fc06939a9651940ccf186727d587f90ff6825a8469ac812c28b4aba1cd1da8b372154a11094ca228cb637d24e701af777f4800680e7cbe36f0a2cf54209f7d08e0b57c02227dab8c67013d0b4a4e9892e9e055e76e3929d65953b942ef91812a6f155a8e1c8a9fe198f8affc8901b64a6fb3a7c11bbde7969726d3c15d17c81d2b2186f8292fb93f6fe6e3e5e58d3e6332fea994e22585add86938d854fd8a731a7d74da20717b8b2435a492235bf66877eb03cf0fa23e120a43854a1c43d3d35496c11689b8ba97e8624fb441b74df56a0094578a582f33c599ac279290883a647fd2f89838303095fc4f3fdb9cf51c6175bbff186107efa04f14ecaf47bb4a9822123dde96807481ab98d7540c8debaf4b8aaa0b9e8ba680bfac6b38f0c17ad393944e737d99047c4c7d530389c2691201ebcb730c1309e462a741715fe800d1e35b8e0cc6dbd55d43f38f80e3f82e6f0b0ba8c2ce7ccdc8897a2c497dd3471c7fffac23df8a4f6690c7ef2d23df742ee81d9a3f00e36e9d78c64f358a84a69392c55151b8dc4cbdb9d3b72c80ae1ac157d9dfcb24b5880d4f3eada4cab6ae5fe9a4162fd3f0d0196fa423556c27d140aca265e07ca746d9ef2c840f0f832adb2e83e27f34265d90f438836dace0a2d485786c8f7b95b3494a6fa2ae56c9a1b1835b71018d22c004044fab31eaa3fc2bf313f3ffa8909b73a862732abc52fecd4fa086005061c071e80e97917def80a9b1b7fc08a0b3747668800a52966a28d437e22d3a22495eab15627bd1d892ceb349b8624212533cb043b40d04e80570708ade848786e888f3dd1331932ffa474054dad9d8462b7954d5a9c92f71e548973148821f73f55adbfca07d5029f3d26851d96c531f342429eb69a6ca3d95ff8c19a60c4d48e1d1c41d31f2c4cc154793414a9d25e64deba08d698ec0eb669203145a9996ce314d817eb125ec14acbbfd43bb0c165f8228898347a8dfedb6d8c6f0896d97f60c95a358898f16347fc53d2878c328b4e0808ad96450ff9b3e9ef872ba0c9e4281e801d8c3d5e9828f179b0a226ea8a15bfeaef40ef2d7502941eeec9f77dd9f767d9b57faef81274f38b70c74659e329bf355302f86f17fae90a2f76626473ee841b39163064bb8e0d70fa8c568e89a6962b2a0a9946dded5e98f182e648065120f64b3fdf996fcf14e207e905118fcc9f452fed26a2eeadf0c0ce4845d7677f1c09a798cb6e54fae517227680a11c86ae4b3cd62895f227d21c3b65c1e47858882544ece8b8861e85b7ee708f0ad5f854f1dd039fdd0c1f05c3d337515001e0f90faa52b5aa18e81e5bbd403ce30fdfc480a659353e2c04a3bc67c31d7066ffa9dffaa5231c72f6382f18478a8102e213e64df2ff54e342b6dc8c4badc6e58e3d85ee195112edebd9be4e3774bb2e8bd8ce73e55bb1ce72d46aaf168c60140e10574c043d5cfd235946a0180640737b3b03b0f76668871eaa7eca75a680aec696afe44521e6e6ab05884ef006b50a7b51d36b258f8cfe9acc42a0d8c825f35eec13e5a86831071ee1e3f93c6f2859a392ef6b8c6434a7f28e42ee5828f30abde08c4d88ccfa1328e89ce2481d11d44936b0e8e48a5210ae5e061f4b685923c7315265adeea0b6988c8d584198ae443553f914785ddf60d940f993ffb270df89b733d6cbcd62d72458a6a642654e4d00f45b997b0755797ab6dcbee1bac6f92b026f02a3a194f9d28503365d2aeee48852b430b3266254d823b3b28533322afa3d41960614188f0d128b833c19d065c89ceef70c1d2ce6245de17a09031db89c2497f8c35a0d36523033767bfbd33caba6c2c1b7b9128fc0945bea646674b2b889d4840dcd4969ab34facc3625464e47e2be225cd18e2219a7e066490658ba685f4ed54ab2b4292a49f57ab770124f73a73d0c742828f17f3db23271a6891d8622b151e01f15351318f783d27b869c7baec8c1e70a6b3f6e61a38ed5154e316912ec1393f6b3d99e160c2d419ddfe81ff45d2c7cd441e6d07c51907a0eb3f12fef441309a657539919b1709a455127a8511f7b3901ad39b9824ef19181c82692646b3572f3f752a8c64f196c99b8be4b10af119e33db77b6ccc1eb72fe769306923ec04c98b669c238be4d454a4a4f74c04fa83e5158b8b23ec7d0c22873463aab9a26b1db770e1297c1cc05cc13012afd7e92c07821346d08d183ed09f67469fa71b1b653caa14d87f558c463a6675ee8bb372edc70e1cb8ac9c5e4ae6a1fbd48bc6473ab941a532f4e76eafd8567b13bab7788dec8619e49c2267d12a4f91562947e2483369cb15ce7258a57d3dd4f9e807e2b17b4124e49d2ba107b0091adefc627e8264ca08917e2b043820153b6c675851596d4d865c362c2dab1434a0aa49f0d2e2c8cd9c9d408c7c80133981e7f06c642aab25097e506bbef782214fd6bc4902cf3f8c0d7aacd5efe45bdc8821227dbb9157f8763728ca68179445644aae6b799c8b908fa36c230cda34fcc00c5a550e6e425553e9ce84a8b955a530a1d1a09d044151bad169e9076534751f0c2641b76ba53939813ca6fe100f4df60fa30f4f24f9da2d58b2405f4a20c8dcc8f8d13e4618925a3d4198acc5800066435c12919d67badc0f556f54431993c86720173ba5d75da6d26e04b7279eb669939b0c5346ff2452e2ab7b553b9a1a89fc4b7fe39512b799a437fc2e2b7e211379f177ccae901e998b1a8c516b6e19a24530147c73172efb6b36567f453af20338985dd4b9c71e04037aedfeac9a480bbc055f5b166e7dd681d8ff72e58b2535a6a3629e58ba973bc6fc5f920dd5122fd4b6a969cff1746956d8d047265791762d50d865856e437c18f7fce949d819764f9cc83f0079d3b50e5af3995b7a750e80236fb0fc7279b5180da8e5054ba16a4bb2a2b3ba4549ebcc7ff5d595226ff31e81a40d6d03deb28ee0e4c3077fb0bea28519d890693c3b2cc0e33fa02b56862fb00b9321d2525d954a8e11a2a4003ac84a2698aeb32008b4278251d8caa4f65929fca5862a3476cef6abd543cfca380ef61573c04f68455ebc69bd9c6160d7372efb2bc0e18a268d92855235dd1b0f27ed6f9b28f36565b3b9ac1b60f2cffa97c3a9986ce6a1777d36933b245b66f968cd2f231889367750c4350232cd5148441239e3ca3125db0a803f8f5eaaf294018e0f137e9bbd3c4cfc211bd6e7d981ed37d2d40bc26ee78b5098d278a0bdd433557d9eba64b13b8ae09b66f11bc4d3b6924b22f779575f719fdff42b5b4498b2a89e1627734e0f9d7d420e4b1e0ab0996dab681daab846b5612387d5a54219778401129001d64c2266add4518d5776c36403610365863e06b8c062c6bde56ac0d90df572eda2abb09c6ceab2cbaef623d5722f7a4a70498f8bffbcbe4b1fa9a5d03ea949b7b787348b09876b1b4dc9afdfd29d82641ca501ce852cf4223c99b4f58c4b155b81eb02d14c0d8cf86cf891b7f03fabf2086b721daf73a00d4409adb6e136977e08addaea86d40b4a7ccb91e18c0254c816789b786c9b6c7d3d5dfdf63a6946e8d0d33d94c1588cd2afb2093a1fa89337a47ad4aa67b09a6c4e157aa84b90662e81dd354cb1bf9b3b447aeb1f41530ede531a1485f39a0eda7c16d71914c36c2dab9c6f4d38bf5c0f7ed73094e688b474cfb1255ec4a2575b34cdfe80cbbe328525f63e09e45c7debf79897da37c94cb56e41c55c02b38028fd1cb71153f4bdd682fdccfd10bd7abb23e413c64be272c24fa019623ead602c22929bd54f58f7e88309d5747ed19df368e22a249756d68d93b656a05e22c4498df95741a1aaa50c9acf0d41b281b61e1a5ea9951e22065b44e353b831a2f6a80ea84d5fa4e7902f3e621c7837649cd0eaf94cf3592ada512599d455133f58cb44e5a3ee67fbc471da1a5b6adb5f0da6d20c3bb317f8ee4f27cbcd67f8a1885db7982b19d5e8348a7cf16b816bc075e4c87fabc7d0fa13376a88ef503ea24a3c185546be46678ce600239f9fcdb901b2adea05e8b49b981995ddccda91bc69b0850020015b16d68816f14d59db9941364cde7b5a5509faee174294ebb350833fc9e8572de0fec4f832f66f116af85bcfb83da65e76120f7bcee2cea65fb2054463202fd463f2e264851d4e8df7eab31b2d1dafa5e66812905b2d7d8465223426f0e07826f4e62d13980f43b8d1034e12f769d73409346f367f2a83ca7a2f84ce86e22f7af67325866cc449e09e405a282ef4ca330f99422a293c23f5364ebeb5ffd8980c08b33abb64051f546e974e97f78eb571c171e1c0d3c6979478047da91235dfd0208fec2c45fa2ca08a2b01369a8fe63b3a4c97d5900d2f91dd43046922567bd729273d92c2e08207d382c4bb6d8281ba71c72ca1167610154ecbb2c08d6abaebe45571afd12d49629c3c2921a9127f1c2f55b6e139f8378e17b64a8aecbc9b4aafc2b5df36a0c2016aac7906cd5dde3945dcd7c943f59bc203923a776d3b07ca0de19d92ec2e735abbf496822350956d14142107a14bcc57b6dea1f9379cae88faa326bdc87e6b53aef8f2c4a7321fe6d0e42d8782a96d282339b59fef2988900f040b33a562384463f7bb765791575fb86aa3b749c05111ddfd5bc7a6896ecc1a8e67b6b8d11f8f2763693ae5d6d0a3560ba12bcc8cee3f805267596a81c987af3dd776522c6066c4cfa50628c37a6189b28ab844d8f3847a0a05158edf91e5ea7094c41030215ae677112c2d0885a2c7effe464cb2a0e6ff2f8a6cefa1366d6ff5bbb31258f8e27a7afa45005ba15a41d78439f2744935c7fd528f77cf2f87aa44e03fdea41d3f0721fd114caa3226853b7c2c74c63a8228b0fde19fa53384c7950dc6502a5905774cbe48b0b359a886e96b20108ff69c817346ca7d944c0b9694a060ac6049dac29497921078a8ddcd021c7621684606edcf0d4290cadbd5707d8ad73d4268946a454fa05e135df2ce28c68186a79d2ef489466185543bc79b84ff898d5eb6b6811d51f7685917703b1ee752146f579a0f5a92ba40304fbf777b21961a4b1531cf0bc1e16115378ef4146632c77207c78c645114fa16d99be834463b7ef1f70747fbd17070bda07370e443d1dc07a3ed0f573206bff01abfd75850f70fdece0b82f35eff4644af871d73880126e6d790cec7b55badf1d5e5d326f2481f820e1b7d0f31895952a729ec1b8b584c5446c35b8baab2dc38f998a01273f2226c8bc3715c8f5c89aede9063735e01ecf092e19282812a301b172601c5ce139224559cd42f0a6627da60e7e6285d35acadc01acff035d3f07b0f63e90eb73806b9f5ea11e096cd615a297473215337acecee5a9ed3f4f858cc135c0788163e1539562d36f7511f1c735c98c1adc7629671ba14b4ddf2042e37bacbe904ebee8352e7f2d1ab0cbe228299c6e3bc65be94f8ae16ef8d683578290dbf54a084172a658241e9e1bd6b13a537eb7e1fe32e61b7022fab70de02173e0de1b243cbb4a8fc1e8679af94a76f8259161ee9b959101567b091e0e051bb275a517c6a1b5af32df53123c239567bd7370747bc14edad086242dff44876117ac578e4b165c7f6ab78c7091049afe4cb399d3499d269b7474d342b351b3c1ac2390fbfddfc5c781a3c2ac86e284c450b178b73f32ad90e5e0f13a0f47fce0120db2fad153c4e7574698a7d6dd4b7bfb4ac3de135c40b37b8e96900d104a7c6b38511177ac13a178e5a24aa2f5d22df05d995059234af60fc196065a262bae2e175144d9e973cb2a20ca0b260aa0d211ab48241eac04dea8e712523bc81cc4a1d77fd339ce1d25eb795a8ab1d4d9b87be9f15c4f0cfda193c58224c9fb8d69f88b7a988ac21d8d65aecb5cd45292d04f5d998dd929c89502330c67a0d57130e7ef29f02223c3a55b783c266b155f0c5c4a94467f42ddfa7e25f3c4498ca3e46b65cb7e57aaeb44553146d3c22b150f9035720e9092d73d7128c94fb625b1f5a0f051b3c0c90e9134fa281f46f5698952e7c65292544449deb73cb1ae87bcdb643a599ce5bf27d32c1467d304c25bccb953379171ee11d342cdd2e4c97574751320a1be1e2ed5fabe18e5ce30e3be0990b691b61f723fd903ad95c93ded7d5ce99ed58140eb7e6fd5117271d2c899fabeb13aa45b6d8e58d2226c03a6ff67ee0a7585b26dcf8c4eb308c912c9e3db393b361cb54e1e65f428578fe3e37984a77ca851cdbedb372258ce237b33097bf0e70f5f05e3ff158cea8f63ee2902af4f0742bc7d6afb585990f06b4302eccc249f168d0c82fe8fde5ba156c1e63489a5d3e2702bbe4879894d28372009764caf6daa29d3d5039d155ef481d7c02c6003c31d45965ddb6a30c1517f6ab52aaf31285622050888c38b42aef66b96e2ddb14fa08b7c33a197a801f4fb6a09c05f32006056bbcfcf58b990d3fa9a780811a4650932117ce35184d00ef2fef480d9cff2cee99b6f8e7e13c8588f6d9a0dfa0a4569c55882f0fb6f1a2f7612766e977ac619fcdcb2f3b0d17cd8d602a6055d4c5c70f3089f3ad59fd1d4fd825238fac323faee142a0d94d19ba535d3bbd17185b99fecf5a9ba8a45049be76198d754ecf66d64f0f8068baa02727075966cbe8c6b2c4e6795e98ce7754eeacdb87710e4774be942808dd2368bdfa5b9e16b0f4c61742226645d400825961099f083fbf98064117c6ea9bb2c4c36906e2357de393d49a648e7e7ea17d639b8d06d94350ee6c8d579e1812784ce7405481ab234c15d824288cf201581f48c1c91f9ea9063ca2d5fd0d51c4864e190df546cba01a207fcd8f608d1e83710abc2818053e8a4969c800f3dc457fdc51cc7d61d1118e6442000c1ef6244d6dadb54de4e8ce589c8b65a380945d873970039373382da6584fa2db4d202a756a464a82a2df2dc62791049f547ea87b982fe4cdaede3ea0a6b10d84e865ac3edbb69cc58f0f8f3be7464583c6eb8e3be0500e9bfea8db387bc98692830b809066b0cd229a155c420d7e6082d5d8f47c84bed4664705250b5caa0a2e3785cb9253a208cafda192bd332a2562f28ff701633c02c960bf671711e9ae17e4d58ba44a405d4b64d969c774f5d1586dfb0e5d114f72c0b0e97aa3dd0eaae5c7fe767a30d83b050298c86c0c61696602c65527ec0f2a229bf02d3c09b8895167fcad6dd18eabafba250af19bdaf8d059355c3701f1b3b19553f7efc8eb929a431f605d00873449e7f3cadfb26ccee76f1b860849caa95cf586004e085e9032cb05cd9098cd37bf8187ac46913504bb5525ea302719be23536a0f2fd3f2b3c38be0f4ebc66c204dc8ffe3b26dfd3f51d99876ab9345f707d8bfa41cce59a192273283b2d4f4744109e8c8c88519ab079af1b38e168ab0eddff858a7cd42d8c517f06e1bdb6fb59e36b582efd8c810f60d01c687a2f638df1f68aa1fa46280fde591b65df1bc90ff4d4528756c3225950a0eab9f5857022bcf6eda682122c322684e8b91fac2085ffc1d810021c73cc2e773b114d766655ff882396b7361b330637ff39d397b0fe1a9dde502d7d3ca9e4eb61561ed9dfdb58c78266655a616fd10fafca53ea49a292011c50f32e1ec20da880251de179e4c26eb4371aa605e034c1d8cfd213d4ed7ce03809cc9ae53f938def49cdc10334cac97ee2c3706967f8fc4087c13d667087598f15602d75552884ec1b5f6ef02ef414077e780bfb480530377dec8cb110905f1753311b332a10b43c5013afb62045ea2846dc80dae67aeb41cc55148a0d15402d645149ed304a5a5bdf8a50b338a5cbaeb0f420f8f616cef170a012a305db7cc877e77a22b7911d24e307113be69f6207cd9ae3f2da8f8c240ba601e2626906c65796ae977b08726f2354e1513fda1d02c14129094406da363c429870b32e2b9be49192fb46dcbd24678deda2fc13e92e2f6efbd8baf08449cd4a9d4125715ebd961c1ea1778aad58678d8499bd1a4977bb8b53bc03e9e607422325c55996405a4cfbf3a6ed7b3062828e6e6fd1728fa4b3c1bc58b709e771f143859e4ce7d7eeec84dff11ecd2d751fd859b861580f2caae105c78645c4dcc1faf439a57c093eeba590fd9eb7943df77f9f77b50cb929fe74248aab653c1371f13545e4a8025d59097dafc16b26db83b64321ccd9faa4fee04a4d2ef21961db22ab41e2101a2e2e537f21b44313ca6b7cf3cf890d8f9b887fdf00efa52ebcddcf60ec0108905bfdfc25439b150b4f3a0a1a92384d3ca93cdd0c61b559757f2f19c752c2278aad4094ae2723861d0b86089f2320db6dbd04dcf29b054384a6c189312e6717b11fa33ebba831dd3ffebd31b0af46b94e2480b9a56a5107f1a4dbe997f371b11ab47205153b13320605e49641a493b1007bafe6436d4dee2b52dac5d9b5af0a122f82d73fe0667c11b98d06b94f497edd1763922c2197a4a290992cd8d6c0ea67dc1c30de4d2e970204ef8859bffe8334b0b2d10a41a7d1fb453f81a5726f75bb23fd2f664cf73c61c5a82ffdfddcee1ace440fe63a4af23951d2f0eb3d2201f023c66f18732cd3fcc5a868c2a89c56667888b9571e80330e0418b6632fb2f65ba9f4b787f10f0dbec6dc7f9ce628c1595790e526b99f66db8f44f0adbeb522a06e99836510241f1b0c1492d7b8b11f414716d33549480198d227f3b693c602a1cf0878c8bab60829a1c84b434122faa40d9cb52f6b03ed2e59ecc8bf20f487bebfc319fdd781320e08d224d4bdc0edb32252c13a5cbabdc771e0ec87addded8e1ac94e74b7101210cdf4747d8f9a9f7db4f62470f917a975ac5cabfcd94d43b81809a51f3d5d91ef5c1b34d6816acd8d46c207b43ef2fd5473c97c4f5ff188d7e8d9e83b0194f1c094ad2002cb840fab2256e77ccf968eb2f4a7f87f25f1571f22231d2dc50969fe014c918f9b6dbc1841742988c6237182e762ed05973eac80f240ac9ba098a4bb1c8929610cdc34f1e1ca03c802c5a3d70364e38a31b22a40f09d519aeb92bc7e4e36363ab84f7976f27e68819ffec250df01f51bc523394c36011d431dba20691bcbf63bc7cdc29d68e601d996613597ab49a8810db82992e541cb54dc645f6b9e07463833135db607e3aae26e9b82885fe0a0159e07785e55959528241b22c7b5030379b0ea5a02262440a24835e5e503c8fe6edd0f5ee41ef605b7d551c2b9f86c2e14dd514a0e06674bf5e11dd22c72cfe9c8fd75a60746a960654c122474c8176a513c1ada8b4983247dd9f8e8919fc47625591117164051094d7788014eeb0553386ddd670587da5eabe8f05c319761e1e52986771f9d514d3076d9c41ff612c0ba8888a140bfb3d41a0b537221a3506866ec28ac037b7fb48173b93a16695b61bbca559bf7ce583320a004f2edc9fccedff536d757adf6868334bd303e386440d43e839409d43ddac3e906b7579be931db174483e737bc70200ab9de66cc0cf5296e5b9e0509faab05b76fd281852a6f42c885f37479e49f1b6c2bba41f351e8ed1dab676d4d1b3cd2671fea6f624054b4a092526ec43533fb37073a6c3fc2e07f7265f0c7df480e05e18ba18beb02c69bc2a8848bd2ec8d2838bdb6ecb4ee50d0babd8f3d356fc5407f77d6d3531ae6679d13018a1894ceaf89220d937c51b778eb287984988ecf23d5cc9c61ffd8c12b0e6f82177154782ab39c3eb1c98bd0f90891b2b46aa74cad4ecf8fc4355fb91f0dfa4dcb50ab895fa869298cef5d9c354237d96e9240075e07bb91a4d4addb2b9467d75b79376921ffc64f102121fe7b524e309fe3a3483b515a32e4b5f950f944465ce6a9724a7c7d1b90d062acba180da5d48e0fd8be1179ddb6bc0f387a559b4300946f4faf99a8e642507c40af5900371e6e5857eadfb5d09865513102e65b82f579dbcc073ce1e4abf21a1006401aa1f45d0eed6a0858be89d35011b36b689a1bb9175f55d5c15bd9bfb67419b3b350a1f20fb52077fed3ff00fb41e69451a5805018f4c5704bba9d72320001ddda7a040a4871130baeb7c8687f018af23a5406a323f7a3f82fbe17c17511db15c724f58b355823abfe073d0760afcb03d0d2e8960122ca769c093474a7dd838534770c79fa08efdecd9ceec46e5f04bbb9fd250486f7bf9284f1fd4e8aa9c2c92ccc3edf1587193468214c08448119e4d842b09f7edadec6befdcae85545c8f9f453c343f3509a2a1990150ce171f9c210eabff156e6e73f6b61ee99c354c03bbb5e2cf479384bf21cfd7053f86f2e91dce89f9d5a0fc193a3d991eee3eb9f4a102bfe1e7f338646b2ceb45061706314c2d74967600b0ddb974de10115a48bd6e407b65b96fbf68801e16f5676c80f909e8d8c44bcbb59d1fbe816aaacbda20fc079ac463705265eb3f5bd6d5abd526012e1028d04d5d24267e3dd5461eb76bf75cbd23666f71e4475e5f4dd2569e55f10f2f62535e9e870d87526806f24ed1b5ab23ae38dbf798cc7975a3ed26e5f8088986708624ab40d162a06577e1747bab0702c45180b77fe3504899689ff66bb0d9193e614db0e37f35a1a5d6c25029d431158bd01c9e816960c7fec92afb2e61541603c4166c3cc771b8d9671f7ed8427c703acae392c8192e7a7c9ada887ca4c672a518f4d5a694829292130b5301c5fad9c9246556d57d965fb34bb287bbe7ec2a6d828443e3c09b9ba2589a40dccc5157a8d35c531f21bed419a893940b6008c09b3ea261c54b37106e8d3ad5c8c3ea601ae7abb381c15ac35caf2994784835ecbd5b267446bb6741a94620319a945424fa09a31a8f20d9a8529d5979a8b82a1c3684c907fe17ad4c6cb9cb7d2e54c11eba7a2d064bf8c9c44fd636e5c83a6c901cb70c36359552a09cdf10bf1eaa884b590dc56bc280df884d5db035a089e42547bf73e58d4e920ffaf971920a1d5d36b3dc8b4addfc27ecd64bd8bd5108b8d750be0d4d17ff84cdd83c05b357659fa604a9ae226bd4f29fefafaa4a2cf7fb5290c273ada42530f5789f335701aa06d0e60337ecbe8e53add6a876b8d2d6424ae37540e3701469cba69d1bca698763a2d8eaae7efb9cc746df6fb59f70d38151c36643d54565fa07ce651a5fe66a18f1e517f26ea4d3e33c3764cf8d52898ba0758ea1abb93930601de3efa36a681f8d3a82a62e3d6f36029c93a04713480d2f0d5063f1a5451cf3bd6c6b243647a06c051c8ffe72e8649f0d39419d2f65cf88a35c7c3ccef4aa40bac1fbb1839f02dc0f4cb058a0b46f84910cb5a7b4a1f67e128df333f12ad6d1141628fe8087bd478ab2a43ac9e6b5539bf46b0d093201b0b8b8172b29ef5c727115753bd166debca28cc46dc28da9a71091052a6fe4050f2ca8945d421750bde5b3eb674dc875dcda387854e86cdaea3024003dd2da178788129701abc490d2a60e65cd6e58668f3e6acc663ac5a582e15b6186607e888f5133227554cd231d65b0355caa0b0b30fd609c0007864bae7dd4b7f94b075e892827eea01b48e145634a961b3ffc4668ee70059f3302a9c75027e318bdfd90ca0bb494385980f4b07ee641a80e3796bd8026cbd7f3397abb27daeb2a6e45e64a09c7998d48cbcf51242a81136253b9ccaa550b6d0d738f41371d1d1374e91ff953eb06d2994347c611de66838785bc490d4fb43efbef9830cecb99b9c28357f407a33940d2741ef3e1e6d610d623de8f5e869f6a369cda5f07e5a97a9404f39aaa9514c7c5f5cbd15dd6d48d656773c388be6c71e16d17533940d220c6062ab4e9be25914ef67a792908325e195f22ca7af4fbd90c7c513fc5f6a7b1591c2b08864b99055eb97d28a985397070e0003534b74a73cfc9b64b6bdedc0e7cf413a1d86674c3069cdb7d57f19671d83773c9831cafd8bb5deeb2a249ffb76bf926ef89c5633b7cfd6ac915e1e3ff16fa47e0d5cb355fa7e1dad9a17533593c00300c094d7f47e7ccb7deee9b32ab6c3e7f82f3a744435e3edee259df40c0693e8348322cb221373c7d680d84e36518bea05bf899c14a806083da78a9ae98971ae80967be23917d82a7d806315bcdc13cf70510ac45bf14133cfdfcee61c26523a1521bae66845b811e7a8ad000e6e248d0b4c1621d8c0b88b7941431061f2591bed26af37b311f8aa1f2bcbdb89f9bd62824ae124cabfbad8df5430a5c5f62251a159848164eefb3f67969c365232b806ea967797fa94f5682c622afdd3d32edb039569e6c1fc85de75b6251dafaed7ecdba1070076af31d879315d968c52191c85aed0811bac2fe0997a223990188c897b5c439ce9c3942d1214f697c11a1ce7880301910609eb2c4173d7bbd2ca8df3399f181fe75cd0b9281b949b1d3e95158d806a51c6f1515d65bb9122dcd08dd18bdf4aa94ebfc25efd0a18bdfddfe136b097556f6cb445c21aab47f1c20245b9017945f3318bd7200b4b83f786d30dcd6de0de2ca60700aa8bcaea7b5f90ca13ad2e32b2d511b719b811552beee15cfe03d266e3b2b86f1b07650ca2c40f1b597e5975506475a0bc571d210e584d952da10057bee68ec05ca31a4c5685e82701887da45a0d73a810f2c68cb1aa3c5b7422c45fd1f2a9a1c88878e9bafa1b3f6219666daa573a15287ba59f39d52110aae65e51bbfd8a05b3d8d67ced74ae9bf1bfaf568e3cfa2c9a4f85dbf428d78f166c27abd76826a745ae53d20ff771f8be029a55b21cc3d342e4781b021d9545207506881bbfe03158ac881a69fa158c53a754c18e13ec8ce7da8d9c38aa1b02cc2d4791d7808301ccb3d4326123305520e8bff40e5b236d2352a1e5e99415622a9faf03269d5aa5c4452631e4f0c83145892881d489b86a60c02597f26db2a71d644f6888b95691a8c07e1eb59e32b0f3972b7543c5ed30c461e967f80cbc254bc128979da7ba993629fd87c6afb3b7ff6563398737b1aec41bd769b645c83871c8a6bf6ca942aba777b175c6f155762a85883f2ebafb1f65ae5abf6e84fcf06a301f9fde430b501a34ed171479ec48da03d8519895422906f8e6eec296efb83a6317e19bba83ee54e7deec75e6cdfab17e46176226e11276561f66ab7e5be588d5bda4f6c92c9aeb996cfe248a563b3c6006eebd1779ea6099d4c8ac3d0c70b231d7dab7f33884cc021e7e997a121b776526473d0702bab457bb723dda06699bb87f19ea6ac0a6935a8da8b92db5e55420ea9ecfc5a4b8f85f835e76eff1e92a5e870f2f7643b04e80a622e8a41c5709619f65a11eeebf2902dfe2c6322b463497f102695470c44ca0360fc78dde875db9530d6a24cd16d8325d84fce0724961cd2927cd0d0680876d60e1490c15c28a2c42255868f82e0e7007346d6ac2bb8001b675a92ff87209b83ced41ccd9143e0bb4a5ee445507c2aee73252b13b2cb72b578fbe4dd49fff1d308fd8c3965341ce42616712e8e42020828f3739a042893bcc291bf8f7be2a25223e0c9d858308eded7a86174a2cc164ef3179cf2d9375dc64111dba695cdc6e2d804de67b721971953cf4e9deeeecd39f1b627ea990728d2805811e4533ab14b0a14c54f18503ed2b29d32442d58c183a47650ff5cbd1e777e9705674385466d036c8caaa16ec08f668ba1e8d5096765453c7e7c63634bd8a76a1d13d9370120058d0f85ff1433f4c6c0a44c765d21fb378e04acd2b4bc65e36e0c21f540c59aa4867bbb930a13a4b204c24c1390042cd703c1da579f5825e4e8a40178b1574c93be497b04fb0bc0e6d121edddb6bba84c2a5642ba8d62a661ed9e56faa665e7de2022891ee3b09394ea5643a44b5fe8e7b6564bd0227336627652b25872d9b4f0d75d178aef953c97b33d876d57141c4f1b34108baee98d3a3ed0d7247d15a42f630fffbe0c2544fa69a197636f9a105588114c9c09f029e4b57ebfc1f8618b14c01e1225fd5c2accc9cfc37e585157ae1827bd94c5c778da377b6eda86b5443f6fab6843ee658a0909475ebe5604193213962638a8073e039a4d03f07a02b63cfb0abc64056d8ca7b59e71ec05f034775799d2516bdc4085abe23433d529afa0ee6de9d15d0f0838849eec5424d4b89b68198f7a9e33f09cdf515adcf0df72a72f811330b0840364a8399f6cb927cd62dadbf0152720dcc8790acada951ddc4023213fafe40adb4c30c30523a985d2907feff0a0adb56ce2006fd5545e848a94e61c5f235e1432bd6647d6b7a29062495c858a2a2a5646eb0bf9cfb45638002f1efa2260cdf248648aaa126d6a81073c53977b5574cd1338e2fe9b651b970ce801335f83e172d19ee1965ecd4e1ef46ebdf7d2a66cd7dc353b196737a9cbaa21f371bbd259a0f5e81cf4ac1169810254b2b4c18227fcc755e854b1f63f7ab08f2d98314692f8e209506b0c25f1f1f954d9c44d8abb4a55acef92439a0a1c47ded26251a0371e76bbf838ae424cef55cd5a10cd0635c70ae91aaa7357cae751dcf65a74dfc132b4bafa982b9e70e0cd008b8a570170d1c6bfe7754cb694e77b37b9ddf88fb6ceefa35d2200b273296cdc7b88ce09e2206a21e0d80db147b00fe44764b385e29b34c45619caffb5616543134932d8fb56c9fc68b6e19565d9fcceb2946f909252fe50f843a55aea15c0396c64c46c1c81f5b3bae1b1d9ab8be2a49eefff85bb76fc0294a9241649c9599f10b7c790a3b795001d7a742d008023554703c41f7f976fe8bc1bba829a7a59982bb813fa1a272df2cb689fdd877b8266df380e7148e0311dc482d2a893d9b30670c0d95da83823d9a51d84aba252d584f15287a8cd4868dba90a1965b7516a056506407101bb4c361410c01f44ada2b50fb148485cb6ac863736ebe263bfdb51bd7d1166fd208434dfdc2d416f8ecbb250dc20e64f79143463e6e619a4567dedd0c242a6916debab73b45b8d1eca850cdaff861bb5af151ba00a1180d858332c1a81cc5bcae9bee2b0c23e32020ac9f592826abcd039d5c5626b85dbc3955abee5c27cc40bb0c88f91320e1fa1bc5773ec4e84d305cacc5feaac7bcf829b42a0ce8a6aa2a187d3b1b17317997334424db6ebb11599b1ca4ea8384ba8afaa809f5320416aed186183c0214be82d6c3d49442780551cef74a138fbc2902791872a5025058cfae15ffbfddd602960f635232e557b4e3e24388080986b63a32cd3ab510e8e57305bc7ca3db7a974ed4174924191d6a5c25230921a871c385309c9148c574b36f811dbd7b96240d4ad5debf356b5776797d56e4fcd7fcc8e1755d2e218af5df52f81d8c1b316d421acdbd4eb1788cd3ee83b161e32f4750e3c63acfd3e590f6998f5dc8c1ab982995d31c8511ce743533c0fdeafe10834ee574f0a3072daa4c271c5d485ddce51e5b7636bd97f9e087d4e060767ba2f08757901f39056e0e3ddc573b6e469eb82a0f1d86c47da50e860913b35e5a3c66c104f24cc793b0420db26b687fbc3fb6787c669a20cd5bed14c563601c3bf44f53e9a8b83828910c636d98d880411f741787cf19179b44b4d8d9305b9f83ef00e49ef1bb36404748c9cd678523f7605317fb1413e1626602e7990de4b15a5d206028fe80744dc8a904759c0e691342123f68bffd6ac3d64e08b778c2c64f65c41bf13cd27ce92c4fa10660ef4ea2fd1043c763a0679801b36241c1017da492afea213b82d5a976fd6b0cc6776df52b25703b698aec8dd2ca7337b517e38a78f5bcb86d3738725e30bf4fd9e3ef8fa84c35e16231d94a4209dc0b001da3fbe13baa9282dfb61af5d98920899c3150880532632d8401e91660f44eee4216a22182a806a0e8ed6f32746f6adf6aee162ebd513ccfb08540603d67ccc5fcfb238e12946c9973ad4843300ec8dfaa84e4b3efd8c3606de70bcdc2c762d7b3ea6ed387d854d81021fde89709bc935bbe683f722b1c50a38b443c8d4913387b4ec010c9287afb919aeb8bafd430f148e92659946e8b176d18e54962323f957fe81c182a7f9a21a35bd511b9235e7e53e66a9f9bbf22346ff325aa3e5e36ac72d510c21e1be34d22d50d0a753cdce6f97576ffb7c8d200b935f27b8d16a4402e506684fddc2348436eae57a2c87153058aa740bd48422599175e177c6f01ea203cb7d5baff31bc72e42ee19a5d8b32844eef7ef2daf54956d70eedec85e5f9b7d114f06f378c3940336f99314ed5fbdb7ff62ef9e6a4a0ab739553e8f9e0363cf02ef2365d16497960aa93571a031c7327bccb41f466eb15c35b74c221016343cb6eacf721575ba74c89e2ebf70d3b3c65ff9fe7d341ca4f3dc7d5076741c329498b8f165f33593abed24cd20da66e14be710b86a738a3b945e73bb147d304c0d0bccd09b03dad138bec1fd44e751a65e3b11faf657ad5aea85788baa4ae1d25a4421554483b3c6bfe11727771c2a3d4acf699518167a848a1e48b9105de9ba5781f69e451edc069e004d0aa342650b8f146ac97f3ee37e3acd9809ed66260b30b69895fa04874e507a74a446fe9e9669c14a05753cbc37198f1dd97cc529c89f65cbf184c806c025ccf245db37c19c5a5d74c03a2aea7cbe2db5def57fd804b0353d1bdab3c87b91cdc159753878454504f202043e1ec4f9402c6833a31816b5f60a19eaf378a0f627e9bd02b050ae0d8dd6c19a1255122a82f8ad1e4716d1278c01e8b17e44ad9d3a087fd5cd6c7e9d3ba59216a97e089bf41774b658e73678734a0da05579c84c6cc51b88a98c4e32b5e43a2ed4c2208c7c3ad42ba7d02348f80ad8e1588b2214573518f241ebffa4efd34070ac481300ec344e9059c5102f6a2d03dfbbb967ffc5e84431f298cdca963141c6b195d9acbcbe187d73e0b30fb11531d797cda5165097ed81ab2bef2f2dcb974a74f5ed1a64a2e8bf7f5b1ed832cd78399cb5b989bef662e04eb0e7b65747ed8963a9602fa571e30d141d5234597ddc1fab265d04ffc61fc0e5146c74b9ef1c39b8498b4ebdbb1f4aedfbd418463412b39bdf4d6c561f9dbf2361ab3e62407e029c4cb2bd43122568f02423b463c24d61df2472273b20e60c5455c66bfb553699eaa587d77dd435f573c037704ab182216071a168c60922bc47351fe35c60741cc2bdacd685cdab70f5baf74887fb9e089057d6c350515d72aa1da9cce97d1a64bb184bd671c154963849f5c24038d3564f2a42cebb6adbdd624066ae9abca3a19a4238e56e149eb6348388ceaf6bc5007d7153f03c69e79864a07cf57d55e086f0fd806110edd51cd31eb80f82b791c5146467fb67377ac3970185d1bf09e2c2606d9d457b637aadf664c74ea125b5d450a708ab1fb62ed4f012ae37303d832e9b7d1560f72ef954b52adf477cc90f9259dc2c8f84a4bb52c5bb95b9d9bbc494f4f42926bb56f5124bb226ab13e24fa2d2a258f2c66fb49b9c40a0d6fca07be48fb41bf05aabf454337fc2226fff3a97b005cfaa0340bf68dc5f65de108d69f82dc5042c657f42e48db7306d273ed10e2621bc70d020275b788864a5c2c32c169cd222c166e4f9812d2dc2ea8b65281e2332ef9719ca67f5306d0b8ac8e52c2d9edb90e95697aba48f8930a2b70d364d11b73e131de32243a0149721ad78a6fb5ba0806193253a0cfc4a78b4fdb7f14c1091aeb7e360add5ba00d66de109fb9a5fa75f32220ea58e4b2ced6e62bc816591294d915df551b6256b60a87f7898b26d2eb0c0253012dfd65d12080be54c3dfe7d1348bc77bd135651713123451492e8282d58f3f2c42897faa1983ad3e144e09e006c3095555633a41002378dbcf82bd23bf66a853eea0b9817bec31ba4125025a3a32af2027ed0200b2823ed1d4782dcc67503e1a3152fc46a9ea53dac194c9518a636fc065025c2b45462cf30b31b877695e064f2d050bd6de114f17cdbe05187d760d4b9916d0644d99327db072c5d1eb650d0de6cc829ac62e4a0d477b52620d8f0dc20aba26c171e95176e0193689e41b10db92298c181fb14f9ebc30acb25501509ace5eefc025caf986d739a6ae473f14320c632df0b2f1c8436ffc9c5d8c2bf3698161a47ff484d569bd208392fe20b950ccfa5e5a334d92091b5e33bec8c62b495625411ef61dd54ccd8f79310942676e2ce51fad52f443bcaf428427dca416b285253508a5ec7bd0a34ee1bcf21ece66a8d33da8520f80aebd315cbfc5575adf760a591d1ee98f4895ad464e0e7893b7dc323faf655351cfee326bb6f7f46c6ea9c6fc0e52633a5317c5d38eefc61c2a4e382d11520511a2e14bb0340a09bf43de119191af0db09938cb9984bdadca7629845a621b996ccc564c63c846848302affe8c54645d8aeebc7b5733b51cbb0a17b1043ebcfe0d5692f7b5d5ab437e1285ebe2ddde51bd1230823a2fa991b5128ad3f2f40c114f7debf80a8e695a7537f7e22e5b4f12ab0d399e536d79c43f432a7fe92bfd366d7175ab11487de00f26162411683b93f61ab2c819a5b7d53e798c8592d5526444d83ffa590dfbfedb9fac2dd5d244bf7f7523d15f4ccf2d148aaf3a91ac5ea4d554fd9b5ea8ff929bf8cf50826fb3fd9b091ca67e697b75b27c4882fc39fd0bbad2d2b2ef66cbe30771aadf6dee8f3ba625abcdfbd19096b8a3f224a2e1f7f350ee4658b487bac55ac475b96a0723a8b1380892663098b8bc383480ab5b1f4ec53ee1a7915321f7eb9941a9a9fc3449227febdb030ac11cb3b58b012b3c23630e7401efd33b451b8f4b46e9a62e87291b9b8c57d11ecda22c3da2bc1cf386729381e7564444c74d87c8a24dc1d5d13fcb67917f06be75f41162752a81132d7f0f49b5c9a12f7b21f3d21cc8e295f5201ebf506c754131bcaf4b32151993eb67f0801a7330411eef24565a355c2ee2d2f4e1603e3724f99085ad43db0ab192b9b82bf67e42fea076012b73cd7c489c911abe2363f94942272028215d4d797af06637a2b27409c9e27ece956f61b2c0eddbde5f14a5d7ec4995a6692423a3fa6095a394ee36087792bae88a8bf9f543ac4fc8440d3135acf91a3bac0b1bbdcb438fc7212acd3541236ad1a44d18acbf1da6871153a644b19a7015527e07bdca395345ebf8141731d3b064900e082095c3fdc2a7c01ce2f5c640a42b7b8f860a372d41eb314a348ba2b1fd3d2836dcac9c5771726406da41320e13277516d3beb460614ac3d0283f743eca2075bb8444e58d35d25b4bc93ab7952716bb2145170e1beff6a14b44c3b9b345fc2ae8e2cb73f1916999e64c2c8be0fa1096594f1a9beb36a70a9a94d11ead3e18679dc6c70fe44e355ad4152e5d886f195e698fb83579ed1c77709349875176ead0512b651df9ed87753af3073c4aa94b794719e55228260b9aa96929cc827961fae2453e735b43de7db5c08c5db0e18b306520a9cf9ca780e29c6440a0b0fae533432e347bcc4213027ab677a8cc841ad43b662556f58dc12f7d4e9226dc48cee24e38d454ded9e2612b23a9251e7cfb4138a0b80655485b192409d7987a5aead5deff4992b0425e176640e838a9afd2c01dc5d6f9b729be44c6e906b031d2eacca7d195d0f23f7537b7c784588591be071bfcd68c7cff4f24d9ba21c94f1570d6300a679c20f9ce4802f6c146f814cae8e12d6f781e2e2cbddf71bf5836b55cbeea5808364951252e1cf9a661420ddc8b015706d09da62e91e1609f1b65fefeeaf62c24bb68e342525bddc8f7403a94e1a8879dbb1b14c465fdf27fcae4eb95d6ed2ffc5f377eb9f2774028e5446a3b417bf0f20975bd5cf6fd9cd31460ed8334ca296b77bf923441f2851c82e680b0d7e2982372a894592c756138c0f67865a85c73b83d07ca92c309bc0222a3ba1354488d66d0c8b68c4615f513ba29eaba171442cd9cd8cd17675e2de4fa4b819c2332530ae3744c53504dff0f7e52322c9c793c2d363abdda780246b88a30452428e22cbdca1747847521672782c0bfd907462606c2d7e2b5d3acabb36567730e720188e66fbb6644171b6a4ca5e8a8a2e682c942f917cf84a2335298dee4f45fb4b5f72d378d8eddc2ea0a832c1671d5d9f5e1084fadc1ca57a3f55b9165e935177eadf26b213a6e42e79b91c6435b00831f9d5310c767db0c507ced63f41c84d752501b9d4281dc14a11fbb00f3d0bc24a6cae52cb4dec60ce06430b48fe9bfdc07e8a3f9fa56249d767181f549881ef6122ea5fc2600447819b68a763563739647e0b81c119ba9c51603b05ee342034934661e28400f8ac7cc6bd2b984885560f6eafb86047e6688967a497c8199224f33a0cea627abb70f6d29725521a396abd345919c253c4b2899fadf68ba1a29704c3ea887ac48376808336950d3160f661e69380da3a1c09554566040cdc4d36341bb51abc3927f3ee8edf3c048b829f6d00c732dc593791e7859a24853ff8d741e1881a0d846d733684c322c81b9c952b5221bb7c98e92c50bc73df7243c443238c4aecbf56853c8bfabd69685728b8b999bab13ed60ae1c0f4345409926132f7bd8b58f0277a46847d545faed429e03fe767496099560cb511def501034c80c45a9ff25380dd28ce3bf335a7d0a4b1b8216267ed0462e6083a90fd778347d0452aef40ca4e906bb54f8a77179fc8917bb306e2092e77a934c8138244c8f51f93fc896a648f2337fd1ff0cac747e423b4d85a6bd7f138e7afe3be58326f025c34748f1f1ea0158be901e91624d221aebf1a2cb58cab64d66fcbd9d77614a521563328ee761835cd70c276aa69af308cb49479925c542468cbe3e94377c2fab76db1121e852b896669b051d1a5f0df9a5e61e45d324ad0b7602c4c0478316cb22056a3943d35225169d9996700fc24d58868f7eb540bf256991d75c7c256cc77c77c860486ac70b58cd9e8e81c122f7a5b5e1c39d9ab8bf2f94f4a75116c38e6412ecd20af6b78525327c7aa703c96a14132c795f673e95513a43e1b40c40996773f3672a42ebb682260101d8ca93e6d0d5f1737420b2980628cbce2c4a464095258a1d976af41e6e05ab4e3027bfcc628697c5427ca38e44593948735dd9dec65adf9a9664dc5f177b83497959bbb4b0644eb3cb640ff16c5932f34830023c44b634a4c3668697daa3c4b48e4ada781400abbad5a92199cad5a508b01d432de5247b32474513d1c5b2b3db3456d3b8efa21dd7dbf19d64d36c159bab4a6b1a617b9963da24d2fffb3f3eec3e84f6c277e837395aaf5927d26130badaaed8d3a0f8e714a2efea51016cc469fc0265e8fa7829d722199b03bdba49ff2b89edb791a4db2e770edf26ac9ffcc6ba75616cee1778632d06029414707f5f6b368bdd398ae56fe0781e05518141e4634486ac015a5c9519b3836163e897d1fad3a4b84757be2ed6c89aa4e1fe8adea21e7a2c14354126d3cbb2fc98613a8fc7ea1339e74afef8bb4ce8f76f4e4cfe41f75fdd69aa1cfc5b5472d22c441d2e9a829a92663cfe815e7746de265693fd7eeab23261eb32ad0bc9f219559882963a959540439d5681c79a91953742762ce9cf78a124a7c5cf218ac18ecf7586897a96e4f20ac739c52ef7d01aab3a95436e800c1a5ced538762d23edaaa92924ee66e27b71f411b10643465c542e6ad7981d91215a96c86e0739688b3cc121e33fc322b59c813b261b6560aaecb003d8bc98cba970683cc40c65117de212fbdbce8a1aa0306d564b9ce41ad6ab3e9305345d958d115e7bf74ca095a955a8e56472cd3575aa77724b0958ca0c15392425ec9a40e3a52efa0ae53767a1df5ff5e044ab4879079ecda1157add15173631339ad49b78599ba78cbafb248dc789030b5d8c77b218f864d0be4bb5a2cc68c1e62b1050650a6af06584be07708e071addb87e100b1ba0a490b14c72478fb5df1aaf407a6685c326b44b75d6864f1c586fe3c167741e5a09672f45345457dfaf076dd8e4e320ace19cd56962fb4d2b7b2b0da2cdf92c84431b1d48c13d68c484d495cdb94fd80b8149093f71377aad1c898327b30d33f87984bbf21b7644f86e2a19d1b6e4d19cfd1c6b7315be74292fe99475b7668b23230676ae4ce45040f9bdf82de6ee34a2aa55ee44dd7d4a3a1dc58716b61dbfa2063badfe34495b0283839dca7af8b0a673fba79c59b93cd9758cb98d49c93391a497d72dc36e53bf9a8c0346b5d600500366426aa96572523fa247e06dae685b0d4a594540201806a40ab634864437a494d84361d26102a4fe96c083725765ad965efd04f297d63da1a359d4d22456aec0d2a691bf42ed908c4fc9f43a027e77c4757fe94b451bb5affb9ddab0f0a828f24f608d76d14ee13f3caf0577cd9dccb5966bd25e409f4d79784841c11074e8294424734c7890b56dcdd9809be7311a2728cb8532a5e757e0ae9df0b09b6a6320fb9d5f950edb0c83d3251ff01257e6cd3bdd46a957dea7b48843ab1fdc398ecf8040c2ab7e503ecc1c09c5d0ad3f71fd3374b5b63107a90b2e6bcbf25391b687732c683e8e4f2dd97ec76589070260221eaa56773fc874c301ac264ec81eea7cb7bb1d2884de9a3409db788b8d217b784923f100cc6ed9d43198ca79231cf4549bb3743df9698530134e1c4ca85c9ad34af3bc359356f87e8a8a772f73ca67b6c0ee35375a022a0cc1d8152320c0fa57eaaa81dfce540882aeef1a2dcd6d04a614ab863e1db97133d23a86196618a9097bafde0511435b28c2e36c9e475610736dcea9debdf8caad79c50134862575aa20c4959751a60581a72a51d612e06179be0e9b3c3c9b74ecbc20fd0863c5d000612396fa307e09b17b3a8433832c64704bcbcea6a44c16effed2652877059c4161df64a5a494e5f6313e871f91e261541ff829a144dbc20c6f9912e3cb11d6b3ee836bfaa963f1c4006fe9653aec0fa28fa1dc498a94bf82f91494111ca3e728072ff6352f8af1a39a7be20ec3421df866d2f0778b532970f9d7256a30a23249c07b91628b10d87a8422e464cc578d7c14e71dcb5dae772c51527498eaa33495f8f78999fef8ba499b8fef88e75e7ae4d6ce31867a447c144aaaa67eb87b0c4f49d448cf76d6a04455786379cb87f6a6aa5b1a0330865df5509760c07383243e9d03ebe5447b61ccc1d54de96e2bb3cf239e6639474425c44687b3b94c9fbd11385dd744211a299c0105927662c1ef765d0cbd0a8eb45a0f620c982e8423956d413dcb4a59989a8720e0740573147fe0350f158f67b281072b468f93a4fbde3a6b601468090f5b1c0c570bddd4be80701b950e6750e0050d53387c270fd9f60877ad269b3a6753b508146a43bd38275e028388fd51c07b0263481271253a755e93080877bb4e4ee25904365e2db67c104c6e0a124e13113d10f27837bc737f2560243562ddcc8a2750b96694632dbaefd32e04ad9c6ed82c3b428f0f74fe3ac2659f47e02b07db110aa444fe70dad05be53e2810ba503fa7c01163d010e2e651202aab1d36e9004d4e6bad308d2c716bffabff8c134d0de7018332a00e0d4fec11775edfa3b247831ed10de044004c99d507615661197594f0df9c6f8634db962289dfee05860ab557ad3469d5c8315a3f9829750efdfa5403ec73127be38d10a18782fa30bca08052d9206bd269112d7b174a6c17b30641e990ee88f0835e8adb471cdf42104df06efa56b98025445b8a3889e9639a6c7186e14153601689698233471fc31d2153591d3f0927863244a4dabce648aa8497c855803b5f1246771b9ff399d60a030b855bc871a6a26130626cdfc90bc820a88aa592b134cd9677a8beb080ad505c3f213c0693c44eadf24a0f31b2b5849aff17a726fd3f48156a3e92aec248916fd4e0a53110ed4475a50abdb6b582d7d6dde8746baa7a2aa859cf49a753ac5ad609bea6f78273c5b6b4798ce2e08e9e97c2f77474b27abbdc1f8ae2df844f1c3c57f6ae71a638fb17f9a037a2e9a4dcf32836b43900a255d69aa0b46e374baaf93dd2f00be110e3be7f45d35faca73fd63b7a8dedb5143c13fb1bee16f9fd96ff49144d3e897528a207bd74281861de1a00d41e7f0627c2183957be936764a6307d3983cfe627ac5d181a2ee2e43c4461b29250a4396944a99a1968022dbe2fdfa2f9ab0ec4d090f5492ad173545c379289b889fa394394a25f7d074ff9efc1504167b0c72dc7dc4bbf9c9e2feed26c6e69a41cea92354b1228821aaa479a3aac320889ef7968c8d8ab698f91be67a428e1cb2bc8e221c1082c95bc42dbf4672a8ae814faa2e1db905b11621cc1933a13eb32c3263ef193ca854d27d7ba05e0022712de952b16f6c4464129834ab02eafdbb229166f4e29541109323c1c0d229ad3c1eb56e096101f9ceb45427ba6fc3e45511d016f521fe0baba422b846ec176206d29fe0628fa59d27f801b11f8a2ae79645485296d8aa65e04c36a9c8a60e84fc0b1ca42ec1ef58b700ad8f72f17bccf67f0f3514f66ca2cb192072e039c43478b0818e6c90fc8b4f0b40978e5625d6d045ff076015434ff120cba585bd251fdb281cf41b24d70e317c92a9b849dc82fb4908d1e823291e516666f0bb6b4183bdc230c9d88caa30d331a72bcb4a742970f2493d9d38c17273dfd31c94d43a817652aed381436bac530899f356b566df43e4cd3ba98308acb9aab23ae739f32463e150b0103331cc8336e3d74a59f5194a0626710f6e6ed8565fae41b89d3330f5cbce112c05821f4495071d91c3e03fe41efc7073056b43e55c128e05f11b443702f32c35609fa73f747825887d1de47a83e6c0a5268ccadb05a120819de8f32aefad8282d633c5edc7b8f29070646efc7a7deffe545eacbfd98242c465a4008aa7208749130aba8c1b4ccf010ca091f4af41eaa7cd638966970a99e76822dbd59e3932aad83d42b37d6b04b6b5c84395ecaaaf212d06aca1e4e63844a78413ac1b52c7b2d6607ad2e4e82bc1598d21ef6d3e1dcb1f3a6ae84ab58e1a6c29385f926476cc0486ba6fb8cc137d0c4ce3fa31c6bb37884e5a9dda6c79f2c3ca7f49a14dd849c7488bc0f4f73f3c29cc232277e29a947cc857eb2f78ba900f727e891913890ed204e63d88c6f69118d480528c5e4a0d91344d201dae535b647f604ed4d184bf14d21ca366cd4651f0f70df7c4aaff880d65cbcca27a83ccc6c544027149593208acfa4f9cdbd35cd2efc94a7fe1b6ef382475d8a5479152d8381dae8cb247a1e9b8289beca33a45425c1d9216012d179ae53a20cbc77d6f9a9316d9f7cc2b7a691d82a90905a7a2d54fa438f380cf97e8186fa1c19f240dfb22500f2871886a1aaa78bff478f12105dbccc4b9a216b91782854a348776f83ba2f31d60aa6c47b87243cf3d9b2c9054db59a0646ffd54fb6bcfdbeaccf0a1c97074c7951c31a796501cdcd857e1d53f4094f89e09d56f424517b9767d2b3f48c5d064ca3cfe59805eceb9153f268f41c7dd92d74594b8e4c544b86189ccb0e384b48351a268727dc7fcc61b9f2cd7de7e3c954b7f3501e8f033f2726cad2865c5802001a5cd272006e0555585d272e78b5c883c42391a88756270f29bd8385bcc03a280aff67af4209ef75b449486dc6648ac449765ce12fdf476b6c5c1424923a4566b7d9c389c26f44b041ef68f531f4bb1e5b666eb06d3145da5835ff77627b5c0050df730ab36c9d5e764508fccd0e8e7b2d7c13f07301dc1f4354c6ae863fb6aa470f7b684d950e2e1ffa99a8d539b7a63a640dae1dfab9c13c89540a8d287805df3b8f426ee1fbe47b241633ac55d8ab37c575e77ddc5cc7bdbf7a47d5ce30c64f67cb3cdd201c05de8620f4a7a5b61106008984f1d6fab0c8d8f9e0e96d06e5dcc7a8bd4c0e3e61a41a1d972627b619aa08152f8f53e86d1e3a6837a77e8d0d20d43d6f3bca966cdf24f13a5fa2b352f4afc3ca54345aa8e2763509f62ba7b0a579602e9af18b1cda6b0f1bdd12e9256bab025b364259ffba7d0588bbbc3c95b7aba257a55f2682cccc53e80315181f40e3f6a4280b28a078a7b529ba50fe22b98df61310351ae43cf475f84d7cfa025413b80102ed9db172ed71fa9db750b800476d4bf4c8cc7bc604e1be6b1afbbb05e6a12fd18de6a991a610c0df30c49b6dfd3e18e18da6cc50d7ea202326299f3bbaa411fe5d0fb7a1ae8e54ca60c27619d25625e9a0c202ca6d22a8debd07c196714f112a399cd85a53a79da938fde91b37419e6b4473547057a3199ac0f378d3b3377b990a88f24582f83fc495e7938de7bfefeba9922dad98ad199d58ad55caef030007e5496b3ab5f1634928cd4c081dedfa1bd3815cdead98b74b5d9d03184b1125222337d922179881b6aed65876e021a4c411fb15a578dbec3cd8e0e440ee83b2764a08a69b0a10bcdf676b6b60fdab0036abcb7a95ac7f7f64a53603974586af87c60d5e4fc94c9b53f8b87fc0a783603d562b29c1a660651741694c4f6095938eacf4c92b02345138a349370bedbee4317ab42c4d7efc9a19fe41751980dcc3c9c759c4050d5ed1f8129e72a040985e56a787306f46b2198dd3d09e192c436108cce320083206d35bf217c5e70156554feb437d421ffca8bb0baef75faebe4da5ce78db2c51ead485c03c582b7b9309b7869ded9f1536e1f581cd9abbf34dc3159ce52f2485111c2071884b8225082560415fa1ca2492b7af0b215ae81ac5638fc4893ad94a56494b4f7a25c4c375a0e8be9b36163523e6226a35fcecc3d772c6d6dab0ac098b336c577c7bf20a05164c092518c8eb4e27998fa5604aae7763c4f21a7676593b9834c9bb11f0e1695454a1a6331dcd4d2f9560939d15d667a63adf594dfeacdce95fb465062d0e0051c43421d84c8302d38c2b904efbdb7fec011702c3029b05c47a69797c77ff5bc0c43e566ebe68b22e47f4282ecaa90019ce041623a1c6d3e53c0e84a404cd45ece0fb932ab3e4b3b666ec1b7311fc73e14ffcc71f6f7a52c09e766e294d42cb6f4438763906858dbec7211dc87acbc7f55b440f5d69a9805980d884433f7ce261ca350906617753561d9e229f2c5f8519a1829f4f94025c6e99d403627cda7a866a9b8502c24348a413c609b4a02001bd59dd833dd4550174b14ea8c36279b311dae5f40ece78e66ac812f904d2b981e08391ec8f66553233c54d1f7f51dfcd8c6c610b6774128ab618e7b1a17aff7aff89f4d53b39facbd02eca12635d7dc74da1e8b6847d5607701846a9d264c49a0ebf04aa9f2117df24c9e6e89ceb30e7277ac34159fb15f2a478a8063f7bf2dcf25ecea2a346d5be84b6348c7c955912c8c8fd3372f3d3578d82866ae430c9e070cc9a2f9b26835d4bf9c904ca0b10fb11bf6744ea6215f127945ba264679d9e3e12f30c3f4a997d2195da8e2e03018a041f761086cadc49081c34640a1aa6bdd8cfe21b6d95f4ee8c9edbbf34715f813affd6894354487ac35ed704a5e26483af04c22a2b741508f97e5f67e479f5bcff8cc7353dfd866f5b68a69c5903d858553430bcdc1088c05d33cb8b070d6a8093d46569673020f1432534bf86f57b0810ca779bd1abc6d40397c2723e2563418822ab7c0df032d244644646495c8a58f6703ded851ea42ea1834af2ff298f550b6019fda78df6fbcfc10988b61dff172479dcea861be74ab924be2c1454f9b17e2e08c8be44d35e09383071c52b49c7b321db49e4bca24cd5684e3c205a2a1f1e35a474f835f2c50ded2ef0dc8f14ed16ced62ad5e804a17e3b381a61da9b1d05636b9c5f6420186b26a37aaa2858d639d3385f5541874df259ef5b954a1a30ed06cf1b75f867fe61d0b17749335283169af187fd21e9a9e18d90afc5c522c57bfeaa2a28957e8c8eb496e65c54e1146600deb178ac6ab17a7753fa8bb3bcb684bc4628b41c950d2362d029c17176ba2bdc4e4677e09e57d143e162b38b5b889ec6c2b19f4e84a8b5b62f02218a2c218a9c100466396f49966a017ba30a4506ebe480d217e5aea7ce3ecfe8a2e034b1a431214d422f9d8dc53d256ccf2294d9262d595478054a462a8a76ebf2367f865281ba6b0b8de8af107efe0b3a7a05041ecb94ce04a11420d1f91f64efc1407eb914363dcd58c02facd1479004391dfbb373eec7b029eee66e099d76a4f43bb28e0fc47b613478c9ad6d834199924accdb623cd277f5387d599bdace578b855dc3fa116f059c4be5579248621e91f02117d5933ac27049b46a434f5a4b13cee56286c353125bf4bde46899c4be71eec2aeba082c617489946ab1ea57bb58bfec987d01e8cbb7519cfabdddde81deed345f705da9f89b39c69fd54e76d2a03d8565ee7481ddfe80a1e3786a4195de25b797c68a2c66607486e1307160e08ab576ac41074e4234dba12081c1f494435c0c9b0398f4d5e91320cc9e02b687da3858470f175561f81597c29a0aa904253f339fbbec634c4eb09cd7ca35e309301fc7a01ca1dd13d5f404e6951073646295c87158dc8be6d67aba4ea6a80c2a5bd2195def525a157fe6c0bfa4349a32fdf3cbc3589fe94eb888a683ec8f75916b4ac07b06769170a4a0f4b0235bc492b21fb4d372d08dda61114b6cfd5d26bb24bc8de5b4a29a50c6a03bd0302042b5e042c0838202aea57187081a3833d67f4a01ab15ecadcaa0b45e9a27469faf664415582bdfaa73c018a87699a3ecac23e9add9533465d7761af3f828b1cfbf944f129cb8ebdbab2bd386b2bded166f292a9bc55a497bbea4cb7ab1b63b3cc25d19d9df70c893a0df6e0d7b3eb58d67f7075aa0efb759d6b5d672783ff009f3bf657b8b4e37bea58973e3dc88e755cd6cd344d9ffc209fe806eca32eeb22a469faf5f1a9735df64c914ad3f4f3b9a3f33b2e125a699afe6e91a6e9ef68f0f9445dbc78173e53e4344ddf3a8b0ddefa8a7b7ac07aea4b99ea657deda85e4f1dd5eb58571ed4b739aad76ace089542a9be54d6d84edda31796becc26c64232a935f93a8157286e3e2700745d747c492f4f147bcacba06d5ff562b15f87f49dfdd55af2c38589a4abc8b3a6ae35c162bf8ef59dfdd684f5546abb4500bef6b4610d00c7c69ecfc7283c289ae64ac7b2afba8127cd4d3af613d5ea74963c4510ab0bdf81fda23665ec2399bd96c03ede1b7cddc2559fb8b55fb4ec0b9d38642457905e7a89923e6ed1d12cb6f851e565f9225df4725491c27785339abfb4235013bf4cd75ee6e05f615da5729365a6289d3c51ec52a1b2aef2fa2e15e3eb5507aad4686e96cef9ae52b8548c2b2cfae8e3b9227f99730f06b381b96020ae880bbbf73f7061f76e8034c90a656d0bd626018b30b535cdfca4d6a74b855b8c573a2613dcd64bd1bcb007dc3ca08640915f1f46206d54c45f51e5a28f7ad5c188c2662f3d96bd7417af5faa32e575a55dbc7eeddc4f9d0ab0081045dc11f9fdc282363e51d8dbd2a6a878ce26916d9f7421926f5f771c4772a686b8aedd5ea719da7567d2ef0c2c92dcbbd5c2b02c92362f1a49f9d5e7de39e79c372b9314a8383754369a3f0a597aea85c23e959d3cd1107c8ef10f7cf6c919e72cc2c678d47d69fa4ac649f2c67aa556e64b841feb2ac5ce2db29e717474e46fa6529e6d6492c4e71db3b5aec3986692acb55835358331c6584cb9d633e6e37345ca718679d6d65a2b8aa6cccba6e68e98d9d98825e65bc59a3b22fb0a85fdfc9a49d1783e519c5d2952f9447362f563f5b7e7c4509b49d1836fd167f44bf45d26e0854dbae915b8236648dc552eed6ae65cad665ed96944d14fdc0eb69fb8fbb55f362fbfb06ab45788eee2c5bd374cb4b924687c3c715fe5686ed1b1b8ea605b4bf3b2f5c6e0d2c63170df981f3246660735f59e3f5151785bdbfcb3bbd1fb8182f133fcb90146acc60fd38f5f7d3f3f2ddaf8f9d07043860fd63672f011451b5e68f0d808cee0b911e4462dd750563de3e4abfb6e187d3d590b88c168818c5fcf4a05a2f599d5a8f9b84043747cee164bb4dbc7043d305b6aed43021e983e6329be1cb0befa7c887cf9d5e7637b7463a8a81b127f0a9aa1283a6ef08a34a136cafacbaa22d43cfe9be2439197a6af797bba54d8ecbeb2de11d69e1fb8f8eb3dbc4d7aebc30c21b35ba3c38c1f3c353acca8f5d4e89065befa66c4c8e1519b27b96a11373566e6cd0e23c081e886ee69880a48c2c4d48861c288a981b7c90f2d8f29c1c102edc90c5e886a7037044584060f0b55b4642e29135a4e833e21d3e7cf87530c485cb8c189072b2cfcf09802acf18295b105a3f9a2d56a89b021f157df4ccbf3b4cd372282d96b095ba3437ec167137072ce353a64a6476bdeae60eb51d52f113639449d30c3171fa0a208ec90c078f284e58ad213d1041fcc1476936d6cf68ac2e726f84ec127ec5583490da27c4a4743f4d1b0fdcc57df0c22b301bb6ae64d03f7b98cfa8c93f3898a70836207fdaac9f904158b6fd6c25f27552cd9d5bffa66425ef5d537ab3dda7ad47cfcd4136b0d31923e23d14884faf1b5b6b1b9b92348388e7eed1f4cc0e9b59bacd73f123b589d5e3bec8ed0ee52bebaf61a0df52888d7393bc658dfafadcd82fc8c45511445bb5bc568de4aa921aa8fb504cdeb5b8a62f52b5617922bc85eca388af1ab6fe6f3167b697380043c39972c4e5f680873c3d410d84b8c807d3ce5d3564b645b45fa5a43a0369fd826dc348f5a9ecd9af8514bd8dd63172d890bf4f0a81cd40bf408a9b06a55f8fa28cde31e5acdd6c4057a6a1501155f6baee064a8a2e8b2ab4f4692f7f5343dea9331f4d717c349c5e9317abbc36e8da49f5faf2460779f829c9ab7cef376674ddca8dd2a3182e5796ba486a85e620422a2c7e7ae9618217bad21b0d714d828b584ddd510d546a921aaf55a029f396436a1ac766963bfa62fc6d03f03ca7a3126512b96c066913f9f1557bf350156ca7d61aeebba372f3acb41d4ead5d1ba4bd55c0eaea75ee49863d4be56f9ea83b15479c15bd6afb9acb76c814789ce0e017ec45122b03f7ace8934fd1d0f2faa3cc7be2ae6e2551de86022d5eb19543dc56b8785fdbc82445f688e072e3e25ab4fae48413af615d7f54b7b75c548bb8a79705da73c9f6425a1ac2bd2f38b8555614777a5524efacb953a3dc8bef3d2614180c72e9e28092f5e3a5597a69fe380a8a8157927ebec64bfce62453e5d3955978ae03d90e380a8f2be58949f62a73b19fc3d03b7a1dbcf36c48674bbc5604d6c01fa0002858043a061308844eb412bb215f56eb6db928e48a7341c3254f2e1834a0a945a6011a012ee869b0199f576b8dd8f1f47bbfe96d98c7684a694e2522b3b243b1c119cafe884a2deccc84cc9e6c3d613f61062d9f9d8cd84cc7a454145f705951fd14f0a0c67290824d8c30d713f704a418228fd7afc9e824682bd14497ac5c3934dc8a6f4a8ccd3efa7828d92598043804833dbac472342431af218f682e0944eb829ed76bd1e3acb13c2fbd990d87a44843d223aa150dabb09b1e08ee072457245428a7a3e723c5b119b5291912225a05d15225c8f0750e9888e0a0e88f4e3d7b3059178413c2ac1a1a012905bcf08cfcaaedf0b06058342825476fdde905cafc88e3754d42b9262d9f57bb81cd2ed8704d8137243b201d97a4a3f84484333dfaedf03ca4da96f47d497790a9af18efcaaecfa284ca9c6e603ec8a286533e4acad3d2ba0636b473fa0565fd46acf3abd302b43c1ceb9fa826e7f735abc05ba9475a51d665f9f302c4bdaf55192ac26549544c5a1c9c2b2de2d217001660186f0a5a60b086140f01202da6a911e82161050f78d396003085d0d351a10f240780a0185597c43c058035cf6755d0186bc2cb02d30e1be5ee3651b20ccbe6e53a3655faff992bbeceb354f60481b4c77dad76b6ac84a720ffbea4b827bd90dfb1a60477b9aa63b1a5b6bed8ddd30c6f8deebf9efb5d6fe6ea92a6ef0b11c23398ea7c92ae14b1724a125df0947381b9370d1c40b16db8f051c704f38240c3fba69caf8711cef19c37163dd647d687df5f1d8f1d0e59e2b8a464471870eb3075766d1144591cca2288aa2986342bb3e9a499038f922c1e529220f223a2583c24c47561136374144183c812285461726341e0b689892b402120075f048471e323430635c2153977d789bfcd0f22f313baeb45258ca3e32b36385bd6388aa25c2863479b478a30d5584cdcd0e2059474f9e318ae26bb76241f60e1f03dae3575f8e302060fbab2f070c1e85dd1fa15c7341aebd20858108d57aba1643aa0285a82cc9312546500e14d40822bffa7218391113b2f3575f0e22398604e500c2130b7a7df5e188010ea7476d785a3a70e4b382102a2f641886c0870b744740609890a5a633797068c1b1e52f0e29afba2146243654cbe960a18426a5a0179ca2c400aa4f56825060e487684a915a0eaa1d317a0505a0f04b41464d052635aa93901e488e7e5ae002a5d625d76c20f1302684439763c99b5f7d39b0d40a82ab4bd3b48653ef0d5139b80e02c425a1caa569fa02e7c4071930bae915958fa6e5d16a74f468e5f59668b4472b105b1bcb6feddb95bd55364ade4afe97b262122dc428493d3a9c1625d813b46096e228b95e82ca8a0d47894b45d35b57404d6cc68dcd256b1eb18f36e3c5fca228bacd28ea9375c668e0573e33560992643466b666694f98c862581a90ad246292610fdd9e1025c970f686b3164732a52acd558ccc9ea1f1c0ca40830d5a000880eb830006208055f60f49701a7cf53da111d9d65d4e724f7878db6a0f0094a255181bb60580918e8686dbb6de3ada9931ccb6f50d7abc0c8c86b6d560e947d3e467db0c9a8031433fed2ceb64834e6a494bdb03182b743283b62d8d85b2435554926c891dbef6199e34c60b93976db56f9f598c1713b6d52e53a331c1407bed3140b62d436c687bedaba11b4d52120adb9a4970291898806c5b3ac9a56008b3ad0a4ad1aa04493eb6d59e32d2cde092b26cab9d3cda31f5b6d53ef67819e8488a5511977e3219bfd7ae9b8029c0b0b2adf6ec146492dd08be760ce60a9b788951b9c20b75874d329e3be449b70c4c33529f591319624cb31a2d005f7d4d52a0830664dbe0abaf490e06b6a19b87afbe2641625c6e4970adafbe26316439704e708ec90d49b11a700e4a1113196448709191ae7705ebf011de318121490adee11ee63129c110ccb37809ff983099827fb809039910c574c040ec84834c7e74c1410c060b99d8f88285180a0f595f7d391c6427e0214faa456623a73e332c31a83cabd1724735320dc8d642ec28db866e660ab21eb7241997236282d3d949cee56c483928454c4ddb6ac7463a9aafbe5ccf8f6dfd1eed989e76af732ff35450b1a8cc5bfacd6c49f26b02ca2c25c56e0066a71cc45f7d4b6290e572104506938522152619511666a83c14a9243dc9439e74e685242cdb6a9fd96882a4598d46a6107b010d03d9c814622ab00ddd56444ce96d85dd26c12d214ac2817392bb30bd64882c88ce41d145315f7d4b7008d14517672d8e644a955a616da4754b5ee4b0ad8f47bb1598d80cbbd72ef678a92d3130bcd7ae977e2530b6c3efb5e726a07825c9b6ad63a760995424f8da2f18a196929482f0b55b0da5872917644ef4f0b5579e34e5428c05290a9f59932c68f6dacb8bf30afbadd198b46cabdd02d94a15623118baad8e2401dd2ece5a1cc994aa3457658c596f36b01168041a878c4363105fad5024c135c948807beda6935c2e12655bed2594a25c4476a4e8b5ab8c7464101c74af3d75b43371c894ec5e3bd9e305b7d53e2efdf6571f0a2f686802964f3127e06bd74ec1f209187ced5904230a575998606cab1d8b50e270952529b61387affdf2a44d3cb6d56e7d664c321566afc57304aa21b4cb96f658a37df529e9bdfeea539204f4da633edac8836105253ade093ca49c506e05bb3e4f9a72a111d17a372337a534150611f280f0b2e87ee8aa0c8586ba9b4e7844b885c7ebe17ae0864586588648865b70b827219110490e4b125a957448da0302017f3f22bf222045bc21de95303ba19da505a159098df2a8942b996f7214a2a1010010041443170000100c1087c381240bd42c0f547c1480126d842e56402a8b442251883410848108844008030000000008c020000440100364b40e68975639f4b1d279c6df040856dd27f71f43bbb9a107565bd0e04faaca28f26fb812267c71d6c1d75022f42753acb9334aa6ca7c66960c9df9cc5c3255e633b364a8994f66c9783593894fa69aa9663e193543cb7c324b8692e9cd28195ac693f9d252bf9bad28304c07af36993acdc37f7d41a2eac65a2046a59ba6f68744ed69d2861719b0e7e6d1718030655459a8bb393b80c2e98f511644d3310940c29c2ceee2f697a53acdde3f307288f60201ebcb93489907b22cee61cb3addeec9285e00e5b1aa2c5402cae139568dc08907d61b8f6679abdc5ba383c360470d663c1e2d1d9c333c2b3052c12be3cd33d4453d0c1da6aa29506a8339221e224655dfde9598ab90ec2adcacf442ef2a477390c72ea8bb8318d6a2c5e23adf3e02026d6a317bceec97c08ee50fa18986033f243ef6b212c33507fa2de80eb74275a3877d44f67e7cbf93a2343f034648b03364fea10101ac11a0114c6dff052fbd2cbc1357443d03da3eeab795ad3803eebc47fb257baff7d4b55d9c044bc336b96b9d8427614b569f08c263db936f759f897c4cd374a1002dcc2e175010769e58e261e2d1c281e7a2827a22657fb1f25069b41e9b3df833637fb54a7cb48886799f1df78b06ada1818d7e549190f70f4d3dd1983ae81ec9b54c791bcbfa76af0d53aa5396eec0f8561cb8c02b069687006bdf9181d541baf5a683c7129889ca1155b213540d8a7db14f105343fd32760b4013a077460abbf0bc502494a603f016461d202d979d2fab62bcbed65140c31ee9345a365dcbde07129cb1aa2db453507e4f016fbd6cc0d54cbd0d1acac3d89917ec993aae15115fa1c4aa6ccef2dd5fa2b1df1d4164e51e74fc02ba342637f99e3948f48c2a74ebd831809330eeafeae173bc723f613cd6becb93ad7b395e8b30230daf5b8d5d540003c2e7fa07d07ae44d9cd44a1817324d7a654fb1bcabf906dda5d627a91d3250aad6803abd2807a101b6e3a63084f24afc87b604e598206062b7cf9fbe072acc0791822299bbc3a0be1a9dcd9467de4c9211c9e43348463c631d37434b5d91f406bfb8005c0f5b4a7fd6779d667daecfc2ff4199733476feba2331f2885a1dc0f33e2900a28ff4cac9fc52bd5f4581abd2e9e0c086a9eaa5dec22d3c6b9944eec4974c950bb1f2ad0c8065ee1e784833cd99845f88e1a146c797ef6ca581d271ed24c001541ffb136a28ae11a4f20d0e9ea311a88678cc677f6b040e97c464129951a6cfa433e24c9799ce8c327d269d1165aa130ca86955a3430a8a967a93f126d0ac1069b9fc0d3715708e8936f4554fad139bcc7a31c72c653dfcdeb40df30df01e21c2888dd4eef31d9e026d806f5c86fe2bcdbb3e600c2bd15fa2add4cf2c0ed86208db0a09d2a87b1bd93ec01a722f9c009788e060dfb2f32edc32803d097b4e3dc902f0dc7255aacb90bb5ea008228258c079625bc7d0a85fc71d80da2057a648008dbb4b34e3c509cc20d6a2fbfe435c2725e6ae9b5e248031fdf085988715724200942197df42107c13840d78fcd988197b2b084b64ddf1efd2880e1142aac76195928137e3008564c341b427dbbd833378591cc2a63f72aa69031406cb321cf28bf234c76305589406a6a31e7848086a791a3e2576db52f3977ce2695450d9b28101967dcbcb474a056e89c5b8bcff20d88999db9f32a538044ce97d5189700aee94e527f03ca5631d80c602197f7f1ee5c620cbaff8ebd2e28afa1f8abf1fa2a4c1f35dd1084c1b1dac9168b324bced1f05542b833ca4bd8f95f840354ee38fb934dd10b3f8ffbce4064305bae4a952c5878c03ea1f0ff68477e103ccdde4d42f58ba235c75c3926ebbe58745c71b9f74e260101545f93da5e2167d87a27fb554584396c7edaf9258283db09b262c66c93238154b4aa5fc083d3180e4fa2c4833bea1373a9659f9f358f75fc0acf480622cc24ef9537a1e63c9a2dad39bc2507d4f63d16c7cfff2b6b5d9882e4b4354fa403b552532c8350ba501fa6375427fb0075696069b09b1f3b078864c3c80a78c685e10ab38eba779b2f05d4db2b86e9cdfee759c25ae48fd15a4d803875263618bdfc7acf70d445e2662f8c0f5a458b1a403f6bd20598a24ed2fe5d3ea80a0c982c0217ea5346c915fc9f9af3d8e585e1e8a172839b490e57ad6f8a512d025655161eebec8e9fd21901d96575e7ec253d6c939682c08e5f7f3121f166d1a4a1e152a3e204c50cb53fd3f25f6434159f49f8a4fb105acba59dc11f31e9b4b0debbfef924901c88293b57e9953ea1a99ee64ae33cf037fd665c15966fe1b271d429774451710384ada9983cee2c73e7f64cf681e69c3c2618bfd3953aebe2852162ceef4aed2a8fa76dc533996851fb4fa71257610732d39c9c83267164a406a9684e7d406ed929f034d935d0145bd2c118dfd4f97e2d6124b9a7ef341a57e1de1ec59fae9dac39772140ccb1a5bf247a7028e6b3c71e1acf5df73baa22b71c2edc4fc753f6db0688645fd0099aae2d73c3e217672fed83c5d5939e858e0fb7989efa109a3f8a753ea638b929386d15fa5519fcae79287e1640cf58c3d1976e2f63aa7921032dd495f273c0f2c756421cbafb2f905993de02d9f341d301455287e7ea4fa89bfe684dce9fee14b330ceda7e57ff4e94a1c71b0a466888fcad33f65014e767bbf2c01fa503d6fbdc5a55685a3e684dce9fe317faa72e3c68905f1034a5c2079f89b4a7b1f7f4e6e5e59ea0a8c364edc3d93f86089e3c3b16445c9d3a5b80961d917653c1a4e01a5637a32ccc9e4f14e65199d39a1d479e5ff61a556143fc5125738fcddab31965541f331ecd2551ce84faa3fdfff6753011b359cdca43f58eaf90843cf50daf9d47bbe7dc8b23405c70c272d820f2cf13ec2916f9e7b7532f1ea4555c5bdc778c8ec133d27ce079438b6184bc00a3fbd34b079ac8f93b5f0cba5a08f57273baf702e95cc5973d2ff74f1b0a5313e322b85117e4304bd630f8993c9c6374b3b9ffacfb70f7356bab2c73ab1cb2c37de2f834ead43a9e02a5ad339f83c95b30c99ce3593ac5730b7109b5c4a39636c52e2fc953b8d8c159c7c40aad89a9bd534bd3b075104bff917bec04d6288e7bcbee66129083968d9b971c25de1336ab77c1baec3aaf45ba01c533a0805312a4646535fb6f4bb2b6a48839029b4459f2fa8cf08b1d622f43916694504f49751e47b2a2cbcc39d0af25c09a035637e6d2d8ad179886e588389a92e49550a95e1cff1f9fa0c465f65336410f9d979981d9c351ca8391fa1e5449ce55928e883236d65f60d009d243a139891a1305e218daab4cd6b84e535cac8cb9313889c5a833f271b2aeb6ccec99e7a48902fa3f8069f8df22e2594a1186f0e6c44b6f2c7283c569ea740e3b9f965c6b89225e691a366ccba2b965e768c2361fc9cd6df1fb232523cbad9632f80a59598eacffc8878a90a23455179051ab769854eb01007a5d1f629c9e9b4475fa3caeb6670557e843935ae4778dcf89c666beeea00189c54e8e3a70dbee1b3e2566df6fe0bc10811b7105d659d47b6ad14510ca542501af59801162c72b2280f4f921a0bd69fefcf3f63f0f88e245956f67a6443f3263c8be913a7c6d404da48ca97a0bf7ee6abd64120d56d8bec13d82cfcaa4004f934b6ea7a0bc119d30b91087356d1dafdcc492e1659ec0a2bd5e1c475803ebbafd4f9db29ec67da0451d8be454cc28a94e7987ccb9624162e23084e5a4b36e9956abc1b826a2a16e83ff40a0c278552eaf6ae88bcc9644e7d64b982aea997b8bd62d2c9d3585fb6cb61e9325e0def785acb678bc048bacb74e84b6955ed9aac81e0c547ce06ee14d3d2da0b84d44d6ad2a3218cf87876af09b734e3c6cc907c30b66e0ce17208b882ff0b6384229c1cc35259c6ff7238a2d7c31dea5fdeecb6340487c0d29e490e208a5540634c23338e01999b77e4e0d38a247e60192387e7fb66343cb2f79a89efa645def7a641672be2d1e230b8e20178a317f6cf02d8ae50d8db07a670846d37b1ae09df889d11206a678e2bfccdbac5a0c3814102c84773df043f141c76d85203c025e42339d2a020f43f854405ec284e6aab1acb2ec46ac8c6b1b3ddf0f02da83305c9477597fac751a4d5acff13b4c65ae1428a590a76c920871d24ff1f0d76a9d850db922ed21e204b435cbd26518411c3d6e4f311787040ea6a39828a003938132015819fb9466d3cb720f9d3421e0403a6fe24299ee08a3a4c5f8ad82a71c841a95acbf82b9ae84d4f96147d293977b80dd2750acf2935be331ff8a517e1e1823fb0c11c0d9cd5432c28b94d1eed377463996a0807861a68a70aeac6e8c0d20c21d760042e81a48a6a86170fe9b722184b6818da73072a2b15f3e6005dad252229ae214ec980c12bf614cfee5fc7777bae061db4a4c352a9bee02b0fd33932644df833d6e3455886d826eb5fe82a47cc71c65eca2e594d87bca9659eb5a8a754c74b927ce93752e2e522daee5a0daacf3512de983c3f70cc5bb7480f82ddeb0d80f28eb1f850dbb1ba7c1a63181dbc781a98fd20554f3c20fdb4de00804a916ef8080a6db7b01bedc3361bd8263321ea707d899f6b08fb0791de5cbca273782282209fe41fff535124a05376004f00ba4238584ec32f251334bab86375eef582721d4538a44a843545bd7098a0bb0ebad0cb1d1e3826d1f10691169f77c61c1b12eb683c749dac4c91a96bb18dcf71afa03fc8511ae611e00e8f472397dc7ede8b959b2e225c1ceb811ddf8edff74e7cfbba90079f706780803b142607f290d6e051813ced345610a6e1c1c7b4da4e162d060c38cec866f92b21f2c7b69cbb5245333420e0bbbb37b0aa1662e6a5fc81d4a2f68d216ba5f671c0a24da13608beca76a094e5c2f74608e41a97a820e1e378de5073b1238082984b8dd25da307665304f650586efaf37fae9de8c181c9c62232caf209bf322a2f9fd1a53c18ce53dd68ace9230832111358664d75a9e8229eaf7717841aa20150a008a1b3d556a1911c2d19b7f91fb11206fc52ec35b808c09f03f21479606c9b6a7733472bdc8cf2907441dc4e8d155ab026cd6a8ee5736a6d716559d84a53449bc3c58e02d3b9708cb9eaea0d7fc69ea52ee816e826baa86bab6bb0dc25e2bf9930e204369e4a21f208b366a98a51c9c1f68cddb29d35b77329127aefb1b7807a03c30239b27dcbbd40f299270e7c091cf5bb8caa81cdd79dde31df8bb92398e7a136a269fc205786f6c61894fe77ecab26023285cb0f8c46066eb9eef97641bbef707e669e7a4f7a4d3feaa3151a490cf401bb515f0eb73f42a842dd1572ef7172673bbdfdcf0b025c1849af38abeb8c5d54ef570f9d256f2b9cd90c08dfac6c2b6115cc0f5d2c64d383ca0eb54c23e1f1eb2bef842130c6093f58bd533b2147c6516a9dd813e5ef29a3b83f5bb91815ff15f2bb1314271cab0637cd0f3cc001de7e890d8a75bfad4fc1ef4f3a2ba6911dec3ec6e1a4487d0b761c2144aea12be720e8f5642a91c12e597fcca76e8b788bc3b5416d5ba451db5748e8af485eb884c6cd17061d61ff243aa3e6a37d5da9fccc7e74f67bb578247a08b071ef63b7952ca3e40979784220877a09d08a8c6e756905c836ab292e90bb9c4098de92d3e56e6ba2b3cedaf7f0f19bf17a42a599a626d69c44d2573b71297cfbd59decfc603ed29a3a6a2b2c2d7520e4f1055154b1e14055ea557eceaf38c3d6cb56875e027fb88fcd073fc97c9f60d8082726bde67c4610af24f7c21ff0840d005931d4a0e2c16af232f293fa00aa9dfd166cec107cf870faab86bca5ab1d43f1f2117d2dab02d67c900d1610e2ec5333ce260c2e48d925bf0f079bdde886acbea4c5da637bbb840274811cf26c7faf54be1db4a8fde65cbf4a92758e1822f4168b3d0ccc0345e1d09dba57f9d1bbd2f836dd80ee3afc80bae5e33c96286faec3c7a737e7e2feb52e5c8c82286fe2ea34ae106ab4bf163517d66f7aa188e6de54ea7eeb402d29ec95b004cf6c3bd326bd989a5b5d6f2517c4a4b5da3c2deb01e48454d512bf0dd86321b264a1fe74504612b36f69079c8c363a951573211470e6401836447430c245e8d6148da01326367b2058f3c374639676afb4e4ad5c9c5c5bfa03a873f5560857e409c367e8f5067bd8c7169a0ad0b7bf04503c009e99398ac56e8ec73b4f77037950de04a1b37a1bc4f3131e2174c8ce8038496e2a13f9ba07005e1484bc2184d448f590efd326bc3902893ce391ea6b21478be796782af78c01f8155adc48e746f09bdcbe346ae75bb234ecb80f6bb12d2b4f49bf8749132c430c87130227b880a86e2404cf692f281e4b37f213b5c9516066c02daf02038b21f27a07c5f747a68cc1f4f3791a7339fc9c975f820280e38bbfdd4ee54044cfc226c738022cd86728f5219773bd24ab827c3025065aabdfe86fa9fbadf1966fd7f32f4095a5918fd1c3d0e8f2826c6e6181f53ffa845e0e2ea97d18832c32d6b04e5719b2679dc1920a20297a2ea6e460e18bcb80adc74851ee850e9bb2c2d349368300a212aba0400cf12f649c67a7c6d0f61d45cef863a1bd04dd20051f6718b4eb45991223ce098d2bb341fdf09560d939760141c06dd919eea0578493aec0baa09ccf1d88acd6b0eb60cfa971214b661263618b162b25173474ae6b0ef9de5e388919b0a43c59a9a660b015837f4859d19be1560ce125e54441dacb863551b3aa7db6fd9b050d2388f943caf045333795a643947399726457ca46249f239fca0dbb3fa23b6881975393a40b3d15263e0301c9e0ace32d1b52b31443305f1f18f2450009a67b7bc8520dc534af5a49cb22a6a0b20a1b50c4c79552b905cbbf6ba9dcfa85679480a77e61f1dbc5d8574f3b233e091a866810b5b5359431f8681efa87015d540abe69a481704b2b604b4a7e0ab872b6bec5d6af119d863c273c1171f687a8eba551b0e23ff259633af5047e33123fa231f689743a639493c447ef4f1350c3723bd9e79b7e9a013c5b70b5b700cbe58215ff1604cff138383c9f83e79537e840ca36dec21e241adf34d04b5da8d1959d0462ed6f1215b898f9c1ebba78f1ba2596fc5851fbb6ec924ec2f99104933a7710edd90b5c9311562c026138acd74222e9119ea24bb08c7fcbe6544a96b6779032e3254c68725239f83ace4438e8220290fc70a31bb4fb7a4988e79c61a366a5a9f76df77563329d09731e7b4d63a19ddd2aa9e2cff2354a7225db970c3b2073219323cebad2aec72d8a8177d16c8f86698f30d2730014263c19f8a4e1405f25ca573797093c87a46c2d57979660bebb78fbc3b8b079eef5c3272feee8a6809b625d0bfcfc399119d48b384375347322ffbbd4a7ca81eb13136b05d30a63b30a26d6126298ffc89bb9014dadc2298732229cf9521b45ad32f917539abd144f620e0b2d8f4c3abcb76723e67cf72aee3c3afc9467aaccafd7e74f40ccd9a98c883cc0320b10734ea91be78586c9009158227e0973d28af5491d95f9f4d53f7a9ae729e57d3ed0d64750b4b8c2392557e473f212c281fb077d861f4009e90a7c0425c4a07b7d589cb7c7dd0b26c9fd50147fe96a1d9e09a68d6921581993598f8ac4a443217064768e1e8aad8b03f9e3691c83767b60eb2acf208d0f3a8f848740b90dffc319dc3b2f24dff738cb6bec8d7e994c5a3d083778fe5c90249b997310a36eb656d76e1db2db93cc3ca524639f52bec2b55061d61ce2d43a1ed187c6f6271c238cb830ba95e986a22ab55f4da82c2e87f76c11f5f065ec1a5081ad62eb2484daf60bfe46a932ec15940b4d1d6246251e14634d9920811166e98738074c28f34217873914dc913c86dbeb91069f10cabdcd3cc94ebe9f7436c6644f2561ec3042cdbb1d37b252d02a3c7f47756654ea84d666a614a2a05610219cf09e9ed2b13d801b0d629b9f447c81dbf4ed86e5441f254b523f9ed93f416908d89afd296c43b4de045ee36ae36cd69c40ca71d73adb7c2720ddb0741e290c87258e4151ac923a4d332fa16e5164636106171d38639cd1ad65160930ba5b0bd1a6ed73952db680eb85f313d1389b0877b0eccba71009a3818cfbbfb4115d75a5b422ecd0923c6c20851d8fdcccfae59b5f188176e7213dd84e4e56ea347d8f8e6e776dcc6acd72d1d4d99b343eb4adc71a50ee22778ee5876908e60159de5b343110b08b3c56ac2c8c8a688400fc4372bed0b7f652162ce5e7a0304428b0bed1021e5865d7b1647f57514afbf9ba0d7133c23c99c34322375d2867c4bf3026517006fb6abe1e66d00c5a4a6a2df7d95340f5636ad934abb505912ad8f5f5ff4852745c1527c50415309c184016293d04cdc31af7dc7c2c148fd401d0636ab9ab2f287f1f4e4f84d405c4d474cce9189f8982c00e2529349177266ee53b02e4b52273773bee56379b1d7855a4b50a90ff3b48add3831fd124ae6514a789da25f200346a0b0fd50fd9ad5f3e838edef6137b10356f459590a0fd6d977639937434920d8d3fb3d9b49d569933579992382a6cb0f603d86b5f95412d4d8fe286194b9822af40825b861341a4426173d93b1e3f493afadc02eaf33e8c133a67912e5b665b62fb833322e6351c411b9aa2500e91b4f1900e59aba51e546d5a15e67470b6e3f4623d03fdd0a7f7bd05ad31cabbc329dfc88170a7da97e4522062216f28ef19c93b8024ebc99745a2f846a9aa5a9738237e898598f5593c2a1711daab78bbbb49ccf2214b041746e6143d6c0f2e51ef2f63d1e8f9ae3ff5bdf4f7f07448e45765e5e458f4f4713df088fb82e67dbcbf16e23e240cc17c2bb6c1ca1871a494902a7658922bc0f2b4e2cb2c32a6e71034e4cf67136e3fd35a22951fe5683b8c4bda7e2b5506bb7a4a1abe96725e39e685f9889ddcd012340c7b64da8a9c39b16e2c0370b342a6f6d864c63c47244d4623ca066eb2a648369ddaed5172f8df7c58d64586b91ad469873179f836e341e2ba9457fe2237bb66e1e8a6e6b95a068e0a28d24002669fbc667f170880fad33dc72f4b0a0008dcbf514254517b5d0bffa08ca1f92865b7735569fbd4053cc8a467050b56254787b493e73b2b291a5794c95dc66a7a3c3ab406b6b8e6b4f0f4028abc44bdb44c3df047a036f15839c6c016ba50ca7e04f0b7c228de843364df9db92f890914ca25d58ad4bdf715309bb4cb91d4022d413d4af71321ef256f6875dd34317eb547c7789a864baaace326196fb5bff96979ab2e693f23621aa2610f1fd705dcb6df6397e60aae9b655779c125267eb07e783981143ba059a91429c5233bd7fd62cd65eaff270aad67415cd7ce90e578c8255064b18fbf665642f0badb4d0c0cd4b666f356916acdd5f25384603584522080c667676e31950fe23996c15d3a12a0d670f4820236833513ad198ed22305e5ba3b148f8389722d122d909397f604f4998621ed5f6da5b6fa079502a9d103376e16ed454d1e8c7eb1db80696f578dbcd61c425b810df751c9ea8b5d3dba84a231c23b2beef89a06b7714022f3327b38157b3b49f5d2f2ac90f9432b11d7bf30c2cdba302cb460eeb47d328d866840acc118a37e96dcbd40a49ed6e8d881036acea16a06975fd204f99a07b4027ad29912d661df7c7443da106699fd52d4a73c362c3237f4760218a8594b26c91ba8d0404b26d18d0b438a425d14f01f7807fd319a34ce39c64acf7dd789457eedcc051a29f03ba1e94371ee4571a9d3d939e9281465d8bcde9e86c751f8738c0e143c7ebf65ad21f09e0e18e712b81f7732dc364f070906ba968cd25db71f347ec3d9eda165d846498445592a1a814ebb01a065e9829e87661b0ae1738e8cc09340007ca7d25edd9c8009cdc1642e2182358394f55a52bfd3d4a401e11d49d896092323fe341f78b87416e2ccea28996e5a18e2487db581e4ef96bb0a58b2ee47c26a7671956ca6a01e7806776e1051b496896c0ba1068b4aaf1e30d705f6c25ed46e794251d74c56ddabed67fa41f518930cb9972dd6a477faabbde0e69d90eb3bb9d092db1a00a3a9589bc840130fd34c45d257527d29dac1e676bee00bb6269b030b3bb0ddb7493dbf44f002b2132ffc7bed0af3e019a7844040cfe6217fc224d19cc19e838f4f84126aab8e7ffab854bfec275874a1ae58026f155d3a85e86738ff73798c38793136003c19d903d270048e2f5236157b7f21536d12e960466fdd9626fffbfe514ae211359996ad375b219de5f4b138857c99098cb45ef89e4d87fb67cd86682b9ce736fdf7421ebd11cca9f7e2f1bf70b710081f459548512fe49699e92d8c46feae84ef1785fafa352eea4fdf197521417e4d8430bc1018b9606b977ec058e1020077dea42830a0d090e19458811e9b2a35ef67bc40df70d72a57d3385255c98a30b3d3e554a4226566180a4e5376397b7005a9754cac2e81986c3260440ec871f6fab77a39e45c7ff28e81325ff30524aca58025972bd5e4b5dee89fb0746de30b98b4b3c2e8713138bf70230f22c8faa222f9d14ddde049d28730724cbcfc092408e2115e642082fe17b88cd24b3571402ea1c6db6fe65f6b1a2581496205978a500a2aa09924eff0a4063c0c41fbfae630f034c82e5a9005f90bddd0e18e3725e0ed6c924ac77c54166855d9abe32962a1f09ef6b4772b7e48703aa8ec133393c08390ed1f3af22fbc92b0ef79b88addf691ebdec2894aa3719c238827696bbaf79b66d973895ba260a26adda8a8f31e0ff501436240dceed94189b14d55e0e4d1b9ced679a45c788fbcf69abac59378abeadc95f2d9a155db296d7e6482e539656067cc2b2525827b9f781a89ec921d74b2db005d963031f18551dba53c5ba05609c43440f0ae6b2db92f759ee3716953699634c30c489ce34ab4df084bce47e3af9176b5f146abd3ba0a6e837011ef3891b6e14302a468744f17b35fec283117dfe559729881b45403f9b1a0985607fe144398232b13c74de25dc2e5be320dd5f163194162db2108f1dff823d71242057b572018fc20c69111d73836a9291573aeed200471d43bc13b069c78b6877cffd5aa6f109acd8ff417842f172fafc457924c42fc31e27e249faf50dea285a92e1326a54b5a1686b8cdc149d10bf613c7c5d9f95aa05bec095be6f37eba3aadbce7ca55fba21cdb6dc0367cca7390b4e200fb15ae1d68eeb104370531118bffb53857ef84d6501800656313bbd02ace3f936cd84e7d6db9a723bd4b205233ee71ced7ec72c6380849d25d2d1b18cf1abcb9fd30f5282e625ec5119b6a7e571112986145e9ce4c8ac239c285eac368f0915fd6b5e4ac6d35f409cbc02050163ac8ab6d121e128faebe0978c2d30661889eb2eb8cb472ce7b4b4b5098651c53cd62d77cb49df359ff5e3adf249be8793d52c3ea612ad0cfb42403ea7f168859308a69351d0049b4d61120f028c0e2c475a2940ca8d7c65416aeff140d8479bb2b081ae0302b62fc4b8cfa70e03a0c1c068e358cb87f116f60825ec7fc141b9d4204f446301f99f207dfaf5a137f5bdb7b77935b6e29a59401280864097a08667290503263a38a04ac8b9ef2caf8293306c6fbd240f738db3156a02ea7fb502377efbd63b6fe5eaebff7ee1a1a74c11b9335c6ea2b9792f2c2f83c0dbbf3a7be7ec3ca7cad8e8511036327ecc7958db0116c84cdb011765565238cc50b1b39ac85b02299053254c884594a7b63bd30f329afd7420f078f0748367edff7c9c239a519100443710b8f97442693c9c4911704004f7962068dfe9427260de9e1294fccd76c2449929cd19e7e15a3f535517c15751007b22622b5d52b8713786444e0915981f57c70ce7c6dcc171004b58c27a66b8c95312b8c01f2352ad3e1ecd6147af0588ad824020d5c130d1d0aae720c8ba1556794d5e9a64562b276db1118186480e1a205868916981c60b09af054a5481f07de7ac5f5b31c34e1a9a9e720572a016ec26f474bde0eec675771ff93f27aa135d5e53ec4093f9bd3e53edcef0b44fb94ee56f3f8b1ebb12a317dc9231662fc42c60a873587a7bc2f53be2801cb78707fe29e1ec9433e1ff8c6fd22e34b9595972d2a5c9355f612c78bd89f39309d824871676e031db5d84b16180f0d74df74b5e129cf4b112f4198e0dc45ec853936eebdba89c558b349d52f188cbf57031c52138b922675e992a7cbd89f351a4d2b705cd458659b1f3109b291f9be602d978b142b5b363d7371c14ae9dbd2c6c62408c43de571b9c105cb851886c28e5fed875f30c325ce5312dbde4bbc990295f44f9c7e3a527678cadb52e7f153de96387fda943001d2f295658b96193e6bf97399fce0b494d102f6a58f4ec8a9d76c478e438220f741a794d32931a170800448726c2c6bb62347aa693d966051beea0a353d96f7c6508279c4a7cb7b63c07a2c7569f3efda3a88623d9635db919ba5cd91723aad4d804024c750a61d87449a54973647cae99464d7da16a82e6df8da7a67c457afdc1179c4a7ad187d43883392ead2e648399d1253185619118e9069307f5e5d973647cad7c6e065f1daf2d6cbd908da0872c4386244384236428f0047e4119f53cfcd4c72346d3749974da68be22661bf4f3e6951ea5a0b46a4963ab5617921c2153b38705270952bbd2b5c5668d917006c38db911f394e89898445aa56664dba4420648e18a38eca9316a18e4aa0aca3b207d451019db879107482e7415047451b3de55d59e1f353de152e9a1ef156bdc31ffd67deeabea9a8af9df2aaa0f95a07bdf9eb62dd7444a635e5755c454cab9d5dd1b3e9e18a8ccf804c999ff2ac5cf9d04193ab488b34916340222586a71429747d33bdb373f7b22856b8bc6892b035df99e8d934f2f3e2be35e1df2708142859a4af9b0153ca0eff999457e54b33804e7996650e5b6ba37f35b048d55d9ce2576b2710a1acd33fc13fa9d056a1813fa5fe560cd427385c15252f72badc87b1ca112b9c14ac1b6b4755705489f1270e0b12bf28a5390ea36d2c6b4ec00c8248d50c160351003d67912a0882590a489f3f28c40964a50aeb859b3532b0e8534589d612e864cb8320cf899707c507c7131e0441262ab85a396add583b12f4a5dae88d8650b249d5992a08b7d689971796677a026610dc36b748726c589b6732344010890904410d52e9f220086a80cb4c5270fef0b53826284c52c6fee8298fca0aafe1298fcad69f39b06f10151a52c4665fbd224150a3e4f95a675504f50cc0c74c5fa5f6d36bafbd4e25719ba41d8455894f741b22a7b3eba39af6230b82742d9ad422912efa584973e6f5b1b5b666e055e27bf1ecf2a26cfde920b46b4a85c982f86278fde5f5da717afc3cdce4756cce4c13e153e8d7ac4fdb9814fd135de98ae276bd3180517e8ead89018cf2bac5e90d45c1f21e6bad084b9224d8f7913967046403586b29bedfa518638ab7b6d46add7baf8bb85d30c6780a0681ab6ef8d57507e5b5b592506bad52643259962c0cc3adeb3aac135451acf8abb5d68a71ad9f78bbc0c7188b96a7b5a634a96e19adf55aeb28a2fa2b59175f565f4fbf5e7c7dbdd07aded7d4531e94a93f69bc2761b0e3ef53b1c37afefcf0a658cafadf7510045d6bd0caf928d8d4d4940b8c41e092022b5fb27ee211d6fafd0e500b70e2b7b63ec1b7b45eab5405a1da3a43a416d70e3c3c06a4744c516cd48dba3da62838982cb1fadc539e0b61cfa4c813e029af053d633f7e91875f8fbd96fc019ef2bca6be09589322bc26622f7e754b654e7f24c9289b159e35c9eb8db7cfc813e28724698228c434746b95359225aac51629a4444e35b82886fbc4e5e31abac6d5f5c5503307e1f106adad15f6ab37dc1a6e3861b334847b56abf5999f759f3834cff243506a074288cf0ffe43cbe34fd0b50945e4207c35cffba163b2e9fe0d41d7a16babf52788ef89d33e9187a076f03af69da4bcd84f4ce4441e9a67bd1c7cc305b36aebbecddc691734855e3dc4aa22aae37dedd713d44e44234d1479dd50d5897c56649ef575cdad0c1de210bb1612da6714499a081d0a6b1fc913e387ee779f1a8b6409f26726fdfcb57ac56fcdfa9508eb4307491344d56d26e91cccd23798421e9ae0e844267d6b6591c0da1eaa435af4a1a15a75d532aa88b3bef68a9fe63307691b2a74eda4d35cac24e933d2dcba3e891e0e793545d743fb26f3ea9ecb3003af320a3f19755ffb8c7421b334b145a2ed33ea9eb5cbc4593ff2c498ed3ea3f0a9eb3e674eba25ddcaa822e8938ec91264d68fdfcbf2cb4e0f5e3c39f0a2286e8dbf497cbdad8c2a0198ab5522394c577038a62a18e398ac6ca0ab35ac981699215256ff5c366a2d68caeab5726849096575f0c8d6c2102f65759c173de5b51003abac0e01521f3965c51f7235365565f54b81aee6e54b59dd925082d28549c911136ab0a44031c4e34a19018bf4b903945c7519534e4002694c8c6960913eaf000b322c89a2c5904685b27e1aa0c52002e54335b5818b56e9018e6f3714d9174097f2c6804624ef0f906ed27dda53d2ffc0a66f12c5bd3645bee8698f8d9849e4439180199f7f4e97bebd43ba49f6694f597f57de24ea37145449286e299ce6ad7493ac7f9e8019e54db27489ab9ab7a7ad6bddb7a77b2362e54b9f7f1b04ae0db057fffe1e809644a640c8fe1de08cb2ff443714f56b9d2e89954c517e7b8a0b3b084b5cd7e6294cbfe4fb4207ae952faf90829d7c5d4ac02b654e0541d0c7d2820041a7252508d6ea60fcb5d1383bc68e339e401b3a4dbc8e74b5e942811677ec8c70644d921682c21e1484666cf32008964c4abc844bc7708838a1900315f99c8c9ce0d495c32985f23ee501ba01011220acaf11280b108f405b9f0305713252d27ff327cf9f37607427e0fe18f1e3c29f335645fe58f9e34524882e081faa196ad8bef4a7f96001b5909252d9248a85811f2dd0fce027881f238fd960ec87c7633f5b785c438794f42bc541c0e7cbc627071fad3f6d5f68aa3d8dbee829870d445fd3f05488f4b3a4d1fc9c3d9d40c8a99fe4906bd050abd7219396248d606656274731946970c357cf1cbebacddebebad450bd2894a140c9db4363cf1e1e58c79e365957c79e3056c71e2c58381d4774e8d8b3952bae8d7af2ec692103a703eb59a327ec4f5c933c5a60d83c535ee481429547c99f3930219f1e2c79c2e011444389049e37376c78bedc70d281c70a96930e0ce6f99127ebcfdc8e1c383c5932f0c0e30563043c27e0d9ba21e3af8f314c50820947e0f47a70697900943d2368c93023c4c797311a2ec660bc18a3aa9aed916105a9c60259eee0e14166861d49340801cf1e372da448d1f2854989849d3b2eecbcb9b2830646ef05a9e54bf2699045c98f332990f112010ba9d292c29617805ca1a3f58c5f96f0eb8c1a11060a7ac4e1f1e60915a016940d0c5763a6e88191a5048c9d2458764c50e1031bba187b8061e6825fc6f9bbf8de81f257e8ef884ddc1ec514b0028f8c215d5338bcf0ec5c1d408e083ce0b4b9e2076cc9edacc87d012b659851c24043d7e952037705250b7755e7080ddc15aed3e3cf5c3652e7c68b3a35a89caeea50ddb11abbc14268c27807c7e33b43ee9846e764a5879ef2e8c840670d17cee985aeccd56a3a73827c7478326c7b74a22acf1127d1a1a3029d227fe2d2ca706a81cb7d78aa41d828cdac4b2225156037bd4926e9593bcdac4b3313ba9266e8b4baa42dd0dab1197ace321fcdf22894edd12245dd77701b4dcde16113f32de7af68ecfe7507f0f92b76a7b0fe1cc92d3941ae9ca93bde9b3f8c33f3d72140c4c8595a3fcbeb35bfa2cd611ad0bc386151370436adf012f66ba62897f079fdd614fedd2a684f04db3123961d5d5e7396b8f13365880cd7d51db12f7764f0e812c70530c3117b53c769051139348680d9b8b174da3e0e0ab4710c911f5853cac8f1c2829ea5bccfda9f12bc0278ca8be302cea04aed1dfdd45aeb8daa6f377629f7c3a576cd9618c2723808de84bd09f367ee48296651a1947d5179e38257293ee5bd49e14fdb58e5842542fe1c9bac6cfd691bb1ecf873b4a570e34fdb3885c69fa36d05ac3f6d63d78b3f471bd71b167fdac61602fd39dab2f0f9d336ba80e7cfd1c6a5ce9fb6d10b9c3f479b94357fdac6af347f8e362664feb48d5bc4fc39da9080fd691b9f74e0cfd116c5ca9fb6112cca9fa3ad49f979fd691b9d2cf973b44149f2a76d4cd2f5e768eb80913f6de395227f8e362541feb48d5db6fe1c6d5a78fc691b59c0f1e7d8f4821bad1fad9b2caad18efa48c5e14c2d2bc6a6194c8a65c537cd509ee38fa695154d3394d6a935299515d482f88c7006bcf2faf5cf7393ff75ffebb566b244edf39d32ff3cbcf7f3e75aab8add7f0e9ed53120f55706b201e466ea4fdb1a3ebc3563d7de3bab8d4d7b4a99acee13ea7a7587ba7e6534820a6630676fc250178f57d308a890263c78707874f408831aee0346b60d99760b85661d3c901f916b59e550d68aacb8c1d00663cd01305a846d8d00088e20307a449842a3a5ca46d81876458819356eb8c040a200ae213ae6a440e76a47cf07fe92c5c79f307d786409538444869e1867ae005df16a8f8a913333b4a8d1228805b87c8159e9f9fa73430cd1043702a1b0429609417a1704a9d38351e38a8e3f61ca4140c664a18ac1220ad70362c0d123060923648d81f10146d045a3cc113660ba4c6831070715921e566ad4f9728db4b6a848c983644e9701783c7eec90c14b1e3a5e7a70a06b50381227ce951156644dd0b3b1a6cd9c2c3ab2807578c2820a2d64b893b5e78d01c64c8561632584333dba64ae376d90d8b0c282338856315205c38e232fbcacbce0c126a408a030535db0e294c0a5c58d205df4d0a1c1c5640200263e8e30f0e5042b429cf829b34304096964882226479a295b7a68c87205c9972871568c99f005cc980d1a6239dab8e9c00fb2ca70e1020f95979e370308240647a0155880e1444b8f210d4d90ccf011274a0c217642289205c78c1c62c464916199495d8dd0012e1673ba58397380291750c85123cd982157429a67889733488a8085a06343921472784d1149c18a95cd44acb2819664461b292bc431c1c7d71f357bd870c942634545688a0f8f408b313c884859c306cc07ad1a33ac80a4469127527ad89c0c92c2c29031557a4f3288c2e7ab0a989217b444f1f195a0a3cc95ae2654e808eac1c5470b3c364db4827cfdb019a8a2c42a899a11b2aa48cd10abbaa21a41498f0e141f9a466122d6820c2190996243d300116302551e2980d83cf971937ac142cc9dad15e8102961cb40c2571a2f5780c0718263421bcf8041f2c29229407248364576d40864670d1aaf1e46032873020c5c704a18244747d599de9b1e42d274357980035c584c413921ce9a315240ae6c2122468e9729515c0800131f454d7a928c4084aa6bcc0e231168c1841b6d50c81243d7b8a4294f0f18a888817dd1aab11a23ffd99c4e0776d50cf9efabbafc308861cb5a3538fecba07f6e7322e5e767eec3b7756ac26e1205cd516a2b89086150e8b3c29a3f4ba7ed3f3562ffa9a143fe931a61b6a684d4f15afa5af8effb7491927e4ea726cb71308ce1c110467f1df9ee77bfef9321e1ef437a2adad266851d27128df3d569755ddd362a19a21b820302e4cc9619ae4c822c6179d0ac10124c625b59ac881896ef86c8dd1c9a2b0d423ee8d27ce1325daed418a20296913020560c2a807932c38b491a2c609a2efa6ea519bb4af60c9fb1acd9a8102634603789ea124d180f0d9ac7b80629cb1a0669b26e12fd4fbf65b2213038337693e8df8b7b4aa1a46758f8ef29ef4cd79f38293f7ee8be7ab12d2346668e19126424603327dc9185adfbe97e2d325b54b0f4c1032e3a9fa231a337477edd8add1056ee37bfbeeb91d646e5251d3f5942e642e6595f48030f6ab85ecd53ea654f86d8b5a84b5c433e245ab36637072906e0454e8fdcc3007607bb73907e9d3991cf6a33dfe033df706b9a79cd675ef3a36d734a96e0e04ad6669e1afcac63509f7fd9ad596472e1cd418a22f7e0293a78111707296e5ee41db687bd3f28dabb22bf1d6dd0adf965134a4505830609fa5b1391874e54c4c15451bfee5b53e81b3cf40d5b4515f2d2894c15b529f49a875ed3b0a3eecb1ce9696ec36e0831300960b9c04dba5eb4775c298afcc8efd1ded5ac0a003fa9181d0bc09200bc7a9179e4d54c51e4477b677a911b993ba925a3232f720c8eb63fa06eddb6d32523a57b333fa85d198ca137c968d7afda657a911f7dad64be97fa4a367d0f3087aa9129b5b4cf99cb7675d285caddc1fd13e96966537ed20560d6005cc79955ec265d078059dfdca4ebe636e94d3a35f0e759c140f384aa3bea9e750c070e1c76cc83dfa31bc2e8e6b7c8afcf444a976e5ee54e6f523d3277475ee56eba91b933f22af70e451eac8adcaac8cd4defcdb42ada5c78aba8e0f1691f4a740a7643d8254bc0a05a54b074e41dfcdbd48bfcb6b33ada1f3ce074c9c83df868cd0ef28fac17eb486f882af7a3cfa6bb54974b3f00fdd7120b82f67e785179bf213eb8f99107a74e731dfc68fb91dffc2c3d28dda4eb1efcc8cfdc98a28de2265dcf804949978cfc03108cbcc39e32f2222f720f37f3c8d4a402e892116902ffb7cfaba28217ddcd16152c3de01e76d503de61d39b947d043707f63fbfedaa07dc688f550f78d1a6e38eba2f6e220f6c0f8adc2e09f7a96dd78bf6d9417ed765696f14bca188dc1cea73faf595b4808807f4265928221e18f9f775e447db66daa917b149bffe667a406fd2cdf4c0c8c54aa230da7aea8d767993be9e9225501479d1b69976eaef144d6a832d42227ed51ddb10aeb170231eeb4a97ac2bca33877d1879dbdbd27aeb1f282087884f551f919e0f1ed84570501f530a8203fb9f7f379bd466b2a97e6413bef7f2c05eb4db64f729f5d552ecd73f87fa76f974024c23b021d4daeba1f5b82308ace3226f5ddb51863f478cfdfcb010b548d422551c42982f187c9ebab6e4f7f9b5202a79c1f50f04c67e9b30d2f979bece81ef71935bbd4adaf381d5843f9cc90b8eaa04d633f9b4a23caa75027b6dce2e9c043905a25f6bbdf52d69dd4e6f47584fc79a1e8f29164e7e7a3b04b170f253abd9768ced78f3678d86531fa73d55ba040b75b90f62c62fa7cb7dd06d690a46c8181e5e991462c090a348eee5383286078f1d536d7e086231de293b106ac72498724c91253ead9fc4b838ba6e122df129dd21386620c124a6afc62103e3068c50e4fb7a225895b29d9b217703cb0d30124a37c46eb029b1eb1b61df8d333aa76b8008531e9a38ad2c5a5a66695d6275b1f6741879b18e79fede7b2dc677f772783dae1e8835f2de59590afd776da538cf6e4d1c3c0a3dad203d1b2b6459fd2e56d251a0f5e4af63a5eba78e826cbb4f3edd0d41226f2dafbf2142bf2466286998f7119f2312944a0e02edf789d00c32f006312983b5b5d4a7ca0b5a7d4e40624584a533a7e5826dd2d36af2d6b5236925a9c1c85f0d311a754c08753b663aa7311b367a36703cc6638f31761ad3444f7b3504d518fbb3c477ece8f247732f2bc7e78c8bb39ff666cc3083ce9f3814c0ca4fdf4c0347161135a34ece876994798c69a4798c31c6ba9cbb8c3a2739b6a75124a4a1c23f60afe8e48054c0cca09299c0d1c1994125c3c60c282c9cdcf46628717253abd98c9ef666f078fdb43743ebcf1a8d36b83c633d2cb1a75866e80c1d0c32ac704f06960e06dad31e16974031f8c4a0c2ca4295d37d705293eb614da91a9dd46010004f7b585b5f3eed6165fd894b410c27a6b360a526a1c44480337a960ce292e10b9a0d98308707902d2c2340ee7c7bc8718e2e4c9a215d183153b42e8c5507422b1664ba30faca2b84375853606e4fa5570c653dcb40994ccb340882206882aedd6e4d7e6ede9e30d487da6f6128f3a34b01d387325dbb6ebb5a6ba8ec18f3cab3fca3bf51f6f3b620b0b5db29c864c4271cf8816006f3f77ddf87b1fe4cd1494c591fdf5d5a24ca13bf7a30eefc898341055f0ce7de7bab29f594acf673e2e58a852b2460ec0b575d5727bcb1d545892d92904871a36982beee40598a55c416e7a7ecdabf5a6bcd97da3bfb2c98535624088ecadacd39677aefec73257babe06eba649cbedc7bedd4d4d454941df3e50b18a73060a5665222f1624608174cef45d51518415660f2c000033eed55d169a157c5c2d58fab21547854f1f1d5e388981120516408a9d3260a982b19e1150e7094334bf3a5e9879cce6aeb85112b2955e44ce942c7861b2448fae800b3070f9222564fbeab16e218278c55d767354587a9f2f2e4d35e15952b250c4fa97f92896ecdb3be95faec779fe33deb537ed182396576fa15ccd35e08605f710f86d708e7f195d763c7f7de9b7706434a3ffc0216374e59aee8ae9060aaeafac65c25268c8d24d1d3674d0a4b88c0f10143903e3aaa9c003a5243ebd830bed165a99a027b552f445d163e1810cea2f3d8c40696c5d409d9c83ee4ae19191b1995123079cccd8205ecb9e8a2cba2f157b18eaaab0a4b112b2c56583d2a1d3d174b7a5457403c964e5a7a54547fe67239877b54538f31c6383b61c9dbcd5bd9f983e5ce955e921796cef2eda0b773d2bc28e2048d0a76bacafcb4d7a2cf08070a0e8aaeb782cf0b3dedad705162fd61fdf5588085df1705cc26d106b408d3a089698b5e0b3aff7ddf57035860d9f0b4c722c67f4f7b2cacfeb415e9ad9872d1e78553133bbda9ae41507a536a623429e9db9ef6a6b4f4a6beb25c68a1850f3a0a046d05e242328805a7154aa1a7bc41415428cba7bc415a1020090a2488cf9f4840c49bfdd6b489e40d02d706d42f17f6dc8d3afd4b6f4f17db038839ef1d1738056eaeea79fbadf7f3fb5403e563a716c428ead067d92fcdc4fe912566b8745c96a318ca6cb596566f0d9a533d96355bc5fd679eb86a6a07c91263d6d8b3ed2bcdd3bfd41ace1a08a2a122afb9cdc922d3a6a3ee131d346890cdc4cf61039169b3486659d2489ad3669e7f34f18b269599f4c1efc3b6fad9d900875d87363d92a2d88fa0188632d9e7e0a8a194a34502829f9e7c3068d0202c38a9dc4067a784d413044160ff3006ea832e1a3549e02f0427ae50d8eb49c37c751416091cad0975dd82bbb71209a6263ac18c4e503feb41bf3d55076b387c4464eac1de90b19789df58431ff24f9b1e41583367aeaf8b66e9a159f31325664e9e68519764a336453dda7d4abdb84f8c7d1636c91c43cd5ce635f39c79e81acc73e6d987cc53ea8299cb662ed246902c714d4cc53c52b209f45b5da8f46b9ea45fed59932740d79b3c2173f2047671864d501a41986bfbf624faec9a54948de7dd43f5ba062702c913e0751c112b4a0b706acf4e249a34d7609e43fb94faa82a6442cdbc7e69429116483d8dc82cc913e01e77f52bcac6914e508394b44764eb3150bf249da4a054d2444996c015e3bf6f5fd729910315746c6aeaa3865ef41b35be7881e74045056f6904328fca1f9a1c841e954f48e0557878eda1a9a282af34029953d2490a825c426326a5a71402f18e778321798ba05a60ff3e08554a832579b57e5b8fc9b12150043de37befbd77e74a92266af9e6ec78cc82a89e7d244b644c96c0a41799a5e79aee86a0456ebb1d3dd0c12d6981cc56f7e9779f489ff729c17f2e8a325114c5286a248a32997b158d8cbc4e15217a8df270c2689ff6b42fc3631df62981d803fb441a73b44ff772dba72d8b4d57b473cebbda53830f35cb3c2a834e4aed6ead1703fa9374d084aa39089fafe8f84907afe33c7f9255ac39071274528fe592cca25a5df47abdee33f762f5d3ba11a3dfe76701be9235aff935ab79cab668bbc056bfdb779435aa456e0fcc88dc37345dcf9ef39c2a227bdd623e8f9c04bd66d24813b5e633f204b8c17d9f1278d81dc6ee03fbb6edce4e56ebb7a37df1935e9a943451fa58eb2e375c279a5d1fafd36ef6db3e734fba0665df1be53732e9cb7276b1cacc9c8d6ae49ccf0e92266a2e3a695e57ba4566e93653c83998a0d788cc994933a9ee8670ff24f853a7211cf24a9ad0a5d3cf8724404272bb4fb7919f06915c3354c90d15bacc6b9d2aa2965f362c37179e1a7ca82ecab6e8a7ccbaa82174d9c675ec0fed9b76d0b35fe07e12488084e46eb3956345c6649e3f3ce9a7061f9ee63392e6d54f6c91766952d204e950b47d56903c313ee9b5c8fd72bdfffcdba7061f729fc93d6e5ca74a901dd7a922281e1365611886a10cd7f98eaa0f0ab2e5fd69af843941bc3ef7b41704eb4b30f30478da23c148901f5f3be8737a4292f48450f58298e909d17af3fa85b259ba288a3350ac1b388420cdb1e3907e08d63716448803832128826005c10ad6d1417890925da15fb0466e5da1481f871cdca77db2b6cf28fba09f600541bca1481f1d74300cc11c8279fecc8e4d281aa85d04c1da5545808eeb9c1c6a1acd41acfd243df453d737a10ef729ee287b923bca3e080e35d1ce2810f44a5e30560ff7599f74d03ca3f06d74ec190441afd843af62a1d6279167ec3493469ad0349fe10afa49b46b18d418d71ae8501a8358147190e368d2274972a4553113340f3d9bd53598a20f6df06b7270d0ccf46b9745ca5e9ae158cb5ac7524d1591b396e91d7abe21ae8761c55b6799975e655eee9b769a67d0f348dba467179d8349a3ed330acf32b9c7aa06f4d145faa25735550415dfbc89bf2c93c95c26dbfa75de1a8e3cd978a2f1444347956cddf227adf21cc71a095a5b5b9884207acca37baa51d23fc747c2f930f263ce160f35628d235c2d62bbd72ed12f4c96b50c827b97f76e377a06fdf314420ebaf825fa6cd73171ef3e9acb66fe79ce2e7a0a0d9e7ddce0a3872091832e24e443bb7e098db2dde829b47f3e1bf299d3b290d35cc306a2dade6998cd2430baa6f99050b977b4bd1bf74e147df4998cdcbb5194e90fcca1cce952ce59a6c1fc6990aa16bc23529ca84b290df483cf5384bbdd2713fb44ff1ce7ece157e8e4ae63e1de61ae1433d7a0a7201dfbf779e82986fc73b18bc84597ed1435cf5ecabc74a15dbfee2eebbd03f76e173ac62e7a0ad0b1935b424efa6c57b09b34b477d9879c68d7f6ee730d7b37b477b3bd23c14809dc24ae14da4507f70ef4990bedbab5c34edbbb59b877bbafd04527378a1d570aede3de897ba7b4cb8b77fe647bec2bcb9613ebaa53a50603eb563ee91876baf46d2d06ee122c6f7d93be4db11d92aa56b710e90d01d21b02fbfdac3577dab3d714a0e7bd035da7b89ef72efbe59265d0efde9537c9eeb864ce8502ef5d5dc25c32a7648aebdfde5199b9d337e9665b0521fd58f396666d68922ed29cead2eda5f9e80ba0f93873d117307391f4d017407ae852370cb4cb7c017a5bd5a521a1d267a55755b03473d2a4b2aa4b33afaa6069c8c54b5e1f32b55f33c590ebbd237dc82f59c912a4f6a1bd1b32694ed27cc6759df4d9de913e64ea68e68eeb3a178a72efea529982e6427be729665eee1dd2d38bd2ba1d7d16ba3665db45b7e25251c1432d81f7eef346dd5cf5ed0e96ceec797700fe47e4eab4075aeff2267dbd884714da175097747993aade760abc225e29ad71d83492ee5693aaea924f52389c1da844acf76549ea948208000000042316000028100a08842291204792385bb60714800d81ba3a5444140923811cc7411083310cc4300c020c200018830832c84993560010c888823999fe157f5e5dfdbe04bc4d1661cfe86d00c4d34434681f1ccd230431bcc75314adca758d6be05d51e801904d9ea4b392175b54b05e5d54283fa78b77f8555f0a360fbe54afe8aabc4e0dd36ace4866a77978ba9d6ea9ab71d1468e9af14307ff7873a506ae5cdd1caa28aaf2301d7d289df50106050b89caa874e4b8e8f29cabdee768d0c4a56859825c88f9a8171b5e3330ee65f72663d8ff83dcbfe43bca0fc4fb1039b85adf13adfc160fe14da62d8a2f5c6cfe0e0e52c9e6e0c8c479065a045f641ec3525b8933962c1260d442fdcd759227560f1ad2eae72a75852188065c2a28765c7b8b0e515ee9e40e12e7071dc88425b67958b2ee7d98eabc83313e8686f1510e00b5e0a92e491146d6730d677708cb09768d526ad83f881a395be7afed71484d774a1fe404b11d4a92a1245179bdc491b5afef7d80e8c4453ed682f2c00c75afe2d18c559207a045a8517b389a5d5f1b0dd5fd8db89d9d12823feed4a7d62d5d9b9621502968061a7a604cbb269591baa23ad261054e612053103b26850ced7323e962bea3b8764ca6611d3eaaa04103308e3bae821c1b1f5729f1f96bc08baf03b34251c90898da4732596b61abdff155e8b3cd715b1922ec187f58a5c49bdf9cff8b092e61f494f875b92fa3ea13e5e417f7ab25283be8f070a632f28e81f598d20d08bdaacf9a6a6c5022373562ec33c415d6b3d4b5fee547d8a30d6a92e8636242ccbb60aa6dfaa9a52991f521065d1482f4802dc24523247a4358f3cbd9ae89219813ac3ddefe0e4c0e654074facb3a26e8ee08719d976437ec724075fb8c069b2dcc6cff0816ae3689433ba379a51c8152917a29e26317a0b52dc8782119b77f6b5d783377dd591374c307d4f0c41c367ac5ca40fee414499f109633f48394df1f082d18afa974a266b818bf567e0739668a2f0557a17ed02d3dbc69b155ac46f7467eca06911e77541d8e6cd15d5064f80613aa3fd2e7edb1b2673b6ad885dcc177a5d5ab3451eb971fb577d0c47f89c7b15f43f924314619a3a977271d8d9ea3a44ac307d218bceb55efd7f0464bd006c35244fcac360219dbd2150926e3fad649701f6313d3fb3e72810a0868b8b7720bd0441f2fb88e229a1b3c54a281039fc6397cfde52c9cd40082490113040f48e64ef489a595b099b79afdbfa612f9f30c3f9f73d6f39e1a66cc2ac94e1b0c007b0ddc90282f9d7273bf2e068192a3445f69f81d15c2995a1a9256bfb1304c7e1d2ce41ae4b6c23a07c08e2ba97109056a847c6a8ac5eb2b28fcf56fbfed41da3a6f6e3d21e1d08dcb7deaa759e256e9db7516555230ddb54a9ada989eacbbe65826de75a1ef9b42a793478f756e0dd7d8bcc1b7d72eb85f4d5882e8f0aa08ee72f88177043a4ed857248c55fa5831fa0947b2d647b5871a7cfe3ff376d23f52ee13d88f63d2da8632926f3a84beecb67ba66ff23c34d07480ec53f162665b04a27c109f10029f7209d6ffe2d72a7c90ad06024ba392596ad14d733ca13f0fb6348e4c2e4edbf4f4bbf3870019760bb5cb0e814070b5f9cd52da491b103660d88a7308fae60005470993fa06480497940aefc4044ac49df5776baf7af0818a1c150caf6cc7b7694cf639b10664f143de8fb41823c2b670e808c5a05cd408b2694339c0509655d8e5fe94908b716740ba6937c79ee2e3b8b5b385a58a1bf108ee34cdab7c0def36d65d534031dc3fb52c5bb13a8c85911f4be1b2ef7341ca8f6ab8bd9c2f7fa6610c933ca3439c159ade413ff63758e81e93dbf436bdced6befa7e6780cd0a65e3e334dca9c66a4ed01b529f92bf7b05198b99a2084fb166e8abb90e768f815b5b307d38f95db4694bff5b2fa0256b5e73356270939e06ac52fb4fe63d7f3e49b5e4e869240f80785b9da92a69896e18daf2daaf84c9b60fdc107ee527293b50ad5b95e213c85b291bc4850e645c44adc9c25568d0efc1e863e9087df44566471b9dbacfb20fd28034d5b886e723b019cb3e0ac9f4af968fc32995088982a19223c2d7a2dd339236c4d5a814ab02ecba304ed16621c9f159af0355e662d93383a58c67dc1559c387d93c3918c7a4fb86150d6263c48ed730339f0febb56bf820913004a46bcc404f4a4eb559054fb7ab77d4c130ef079a13a629870bfbdfc567e617400ea5ced037f3fe997591808f55f1f4dc0bfcad98193f448fc6f71fe84d819314a497e2eef0a9b3d96de8ac4ee998b1d8bd9747e83f3afc1f29beb5ab96fb25ad470b93fafe752c6e940ce9842971a1e8093c88a81a919b3b2c7a1cba435844a6b95a943b7fc21121f7cd0201a276a59fe94cc776397f731997a0096d5e1a7d5338050103b10d854ac2602eda101024d13facc3c994bd1865c2389e4e49c6c0e8b727f98237da6ba40fb2758a782151926c572f5c48772399fd918ad5d5cf97206e7f7901f3d8345758fcc36513ae1b92b13740f6b477bb91aa61c90f9cb2b9930a9ba9c6689925592549e7730dc6b60964ffa251e5f2a794269c49cf87d3d261abe3e01dc6a8d077811b61f0406d84509d64cc73dcd5b2ab0cc3705fc3dbbde56a207a9b4978eb4b4335a158dd0f4231d44bcabf2c4cb4c8381d47ce072aef75d14d47b76ef224e4f9d4239b87e8b019cfdda778380876783af519787f77ee88220cfb3201764f69d2a16347638500968991e5818a4376c3d5a9bc35cf2c4906311b136555eb8cef94e40c8db848f91f4b2f6737bc8ebfe920d72182aa43ee76b0007558a5f66ad4ee4245d85f0af8ea1299d4c8794399c3948d310986b4ed51032e04097dd001ff4745fe28659baec15a773686d239269015e61c801300bc7b47d692cb28b7d7de83e48942e75d0e660ecd59fd26520362972ebace1c28f7c11b2383ff82677f2922023a2487c9ba3cb6d9b11bebe514e09bff1beb572287750ed8bee28c84b7fc890d237fb7cea1a288e2b96cf9f1c217e079ef858a094eea750f42620ea736644ba0c78947c5ca07aec61de570437da366cab29f497014a6821b32ada8fcc597cefa933f25105bdce870abdf10f0a67d5e4b777f13c8af55f929eeefa1cc560cc0f7be536efea6e0f2c388185a22b3097047f7d262e1bf3cb9f9117528117e0b48831d7128929d2ec712e295b2cdf513c3ad818307a82a6ddf96920f9a0bd3e3572c3dba08af52f7e27cb7df6d7393c7fb9812e6c254f2ebdfa498a913334e4f285a5b228dbef0074f80bd812b31f7d5a26e6e496d9fe34aecf1c8fe6d4d3807aba3d9e3be5fc5bc688969850f88f2624ffbe77041aa4bc2c45920a6b4f0a4c4be2627970e54a48527fbb1676cf6fd07c4aadc8f7961b34c06e4444af130c85c9d83a5de1381f139b43d773582e673bc2721a0f9ef97c130357babcb6d30bcd387aed5928367950d86836414d90e530d862dce9919d7a405a237890e83e19789a340439c5af87e004f430935479201deaa7ed2560b111976624bfd1a9772440cdc86d549b1201786d3726322a0ca226c782ca5fbf9def9b314d95c42a8bea123e240a3b2003e2c24fe07530bff68981e2a7c46b2951d0d43bce91579f1b8aaf2755daf14a202b158db19a2cbeccc14e94d95d798be542fcd245cf54d199c86d19118046bd8cd5d2a3e023afe6219eebb359d75c3400954e3ba614c8be7f901fe2dd323c793c820ee28cda7639518c634b7bd725c4de379b476ca60145438b75a5c08e43b1c0373e4b394a5fb27b394815843c620f00d9efb22c96ea9f97891f2e45f587bb801887fd7e53f777ac8d7d0e6e368bb0183ee8f14016a87052bfc3e859bf890ac8d7c87adff081c543f64ae298adf8588d87782bb134a9b4e3b16cfc3934a82696896b1b7e3a1b747a83058f11070089ef5f0266d731e5b0f7bc8fe30c51653d19a133c022715a9f9da42a55d6add94ac9591b3b2b19115fd4d371ea10decb40b24398a95174e6c0125fbc38b19f9fd3947e63e28468a674800d63ac2d1147d0910c7090271d3639f80c3b2bd438027822f75b838702a2d03db71b8fd5d94a329a71166acc0694b50460f0f3d18655e4c0260caa19444b9bf732382fe4d18a47559aff60c3f6e6ccdef561100b99bad3c1e63f1061fb72d4fa182c4e5b5c7e52b7d8c4c1399d1ecded3064a2805477b6d6eb946686c2a0b9c8fc18bd2b5a30a8510e3c476236c9c220b5e858dbfc8539eb2114f6505cb115c0eb4f2ef6b5d6bf552c16b1a7835d71a9da095a289e704ad291b6be6d047ff1accf56c48b4a1d6c637b47f636d466c3e3333082e6e69880aa3bbf6d2f4e1483bd95dd692595790d8773ab558cd827fbcf3e385804f6627a4c201f952a2fd8daa69a85bcb41570a54e2af2736daa9148b6bd71b8831fc4445f63377d3add893653b260558e747627bb8db027be68039822d1c32e2b5fb611debad5f4f86a7b247505db015f0fddcbb42fa18629102339912740bf9fec8cd38aea8d3033ca657afef2825adbd59aad2898eb7029d61afa00d6518eacf124c59855faa17bc547198fb53d3b73f91919b98d6277fbd266f2ea71be66380012a9ab223d21108198ed60d90b6fe0550577b4cb63912a473d428695e93ef1b3dd1ff1606e974b847b6af9ccb20b30c4fc3520ce8feca1215a09f105357d300c325f40cca7f0654304f595a03dc9ce3c4fae39258e961ce536d04b95ecb271be25afb40a6b04978e54e49e62e41bba66015129ff7773ec98469dd75ac4d772039f1c99b9d4df20d67014dc586c8bbd17bb30d653cc85170383bd5cf289c6ccb353b05a818f0fbb841f0e72caa57dcb640dc18b8172f3e1c51934fa3a6233446561393d09e05c00ad0eaeca001a90a7eb1df6579b93b055af63b2c1b4a2acaaa89b97505570312417a5312420db26af57aceac3936bee04630d470f1a6ae0ac79dec35788c60eec592fdc49e2ddc84670521e9553f980973e782539d945cde352d7a721d57035d1395aa0f075154f1385dc4b1c683b8ae342cf07109e2352a7dc1e6c8ad739dab14d712f1ef34e56e164d3943d037ff4a13e1f0fdc386c6b7d3f66b617b4acefb9a3aa9317112d5283a540ed2fb0ec0cdf43c87dcdc2a0770b9ea6ce83d6d760c5483c01aeb8bd7acddd3ac0a98e8ab70c4c281d809c10b72055829d1cbd6fa937139a0eb6eb18a7e77c052d8fe3c51242c47d83a88b6171b890e694d73ca73d1256d22d01d00ac893ad8771695a4687cfe77f643d181fbd1f845d55e9b9a1b3328c7bacf0b63ed0987458276867463552086f5e2a2d6a1c055e30f69482ad2cec8a41d0238502a8da5d292a6c10fce44dc9f6968dec86b8204d21a8d2a2a6351d622f0fe1617d8164a79509082551e51118a1d1a54322c7b9bb50649610583abf4d1cbb9cb38e94c503a73601b0bde3516746a59f43bc870a4468f50ba40f91b33dda2a611712eca6e5b34b25b3c588964467ff93a769c96450d31a6a27b18b9bdbc3a3d01052d9d8212604f8078ad38daa23e7323d6264b5a776bdfeae81c0a4614af6dce689566e9550bbd5a1191fa6d403cf86766494d0eb85c17bccd3a4a8316899fb5755d0eb0e05411f7db889e565a15a14c03b508baeb9910e841b353a42117d0ef3665ff347b74dcc1563a21c39ee5aec6f64c61d98b184b189d465c9eeea7620faf6c80ab36c268c2c0987e8aaeb3b0836c1075ccca7f9aef7838620a0405e9c7a58e41556c40d01394f9a9e5dc87149285e546748df146adca4335bb22aa38f9c69fdc0a2499914a5c7b0f57ec5475298a443673c625530086a151b0668ad4ea69e2cf9c37852b18a084045aa36e0e7e211b3db2fc44cc5ec0867ba1ed3ad36ce4815b163263dd373add1fd9491ad2f6399204134f5ded1f00bb5e509070b2ae1a8c134e1e424d99098657db889031f5efb455ae40aaa78dd8d1b3d1c5ffbc23ae31573b16c747b27e65e59908c7a00e3cb8cb78d22f801f59569af70b01f205a8984635e8639e80a642f4c7ae1a9eadac36462043cdf0d5d4b89e76d42adc989198b8f692cbd89850ad4cc6d1689b1992a7dbf605a955b25592f6e5881a59cd7e07aeb484f6a54c1d24268d32480c91f3f92f38437162a3ae8091a9956d3887397b7dca223b748d8423ed499bb7d2905686d05d79d0e325b7cc97d5a56898b961d65dba916979ea1f900914b355dd588f0ce4927f82f7dcadd748b31bc2339d5da499e3e8004c51d871c35481419badb4b597df1656fb57e573b8e150d2921aa98b526e3133be578efc16b3bb2b4e5b88bcb2467e54d5700a07a4819133f68c837ccbab6c91d7c4003cf08f87eca6c85c95d9bdf218ef7a5e077ad199a103470dd8014697c5aa71d3d36fe9f27b1d4cdc0521838630a9ad82b3237b1548bc677c1e9b0fbd48183fcdc4c56bdf820b365a1c936c5907a15015341c693f9c755871dba50c8bba35b34ba3228da38eea5571035681d071c72d58000fe95f94374a0a82435ff5f4e3b9c22f88539a6ffd454e1d4645c6d02865160c932e43cb142ebe67567c007211fb8691245ad93a2425af571d4f80d695cb28afd156df853ecfa5bc96cd905e0f467d9d452a073a053799e129364a0f4d71e5437f7102f442838b5054d974b00c1c752dabdfbb0bdeaa33cd2e8578f80e4415d015326900a26e8c9e3c2872a821b5f827e49963c44a10d45585588364e486865fdfe7b3f3b65dd1b6e2425dfc8aa614d5e07db640a0b3e56e3ac1edb0cb119a69800db7e12d3a1412eef7a236de11d029fd788eb09da6e047d45e7fe145eddfb9a388a0ce64a41823e2bcc93a27b0447c182f7d52a990d6d20d8acb81b1c0d1ae8a9864fcb892be1a2ccc58e0bb481bd9a662e7e62de8218f2c0261b1001d436c2f2173b640e43b756473afea47a8da5e849afe962fe905e291138261a8aafdd0c336b80ac098a982b93ab5e1dac349a3c18b74533783da5c5f4ba6ae31884e8d9cdceb0bf311369c2ebe89777cd15f040cf3e117eebc244af350c9399b31a0697de370ebe338733c7689ac607260baa0b0c8bdd04ea2bb35f40cdc637303877b3fe27da076bf68ff59c668fa044cef8d635c82132dc34257b467916587ee1865a3ec20ae1b8ce1fb021f7dc6d217c71ed65140018ffae90b1932af1280dfcc4682d6184b57c7bcd5325cb787348107eed15e3bf38d6f59dad7bd2e6135b0921003402425fefc0dc4c845b4d99bd50f69fe0a499a646f184dfe645cfb48d4a07ae85710b40b71822ec42b860ba39227d957866d08915604ae98aa7f9ed7dcc54ecb10746d18bdcd8427fa15e9e580ac764b037e8f14b3bbe84872b48be10e355bc88c3ca48c703e227e41bd96afd2fba1d2ca5b561b2ad57e80a271321fba46e8015628396f46842dcd7934486c178b4cbb1e74689d1a7d563e7ebe571e0e15244c54d341368bc2b8a4e6890402ff4c533c73a509062d08067427090a99f4340456b7e93d207be6661d4cfb7017d28ac4e04b956325451893257e40bc603510240656f40038c7c4b289ec0b5363ca57c6c870bd1d1f4b22d9a12f1fc3cf09af0558e03dc5b310fa434a1cbc7e7a49acc0a75206ffa818bc9efe0e7abac983639b221d502d3da6279479ddcf8f28f6ccf524920d461ac69fd767845a1ee32a76a8ff8a9134d17f396c4b55c4cd4feb2273a878e8e2ccf24923e1966d571f58703bde5173ac33adbc132a5784133c6dfef1c853a0f54e5b68908b528030f897772d49a29c70979d79b932ce930238cad324e6c41aa995b88ff29dae8addfcaba961bd81a60b9218ba0aef7b87613fba903955d04f707e3e8901eb4fe16cf794678f89209d5eb7c8667afa41e5a359479e6dbdcd95869d3309c13c5d458fed2e2573f67601e0b9a3606884d3b2174094cba46ea4f2a18925abe35110f37afdb1659fe5a54595398031d3e2226e51c88ba766471195c8f1793be49399042b0203b143050a6eacfe9d07c48a82c18d31d2ae697ed996c5e9e622d6741f7799e6eb9292189ebf24afd26469462e631241274827803502c61ce1c674f06a89a0eeee00605514ac212d0410704605c60aa078727432b8c2d594c686cf8d32bfae40748c171be15ca541a8c15b4ad92f95673c154ce2c01180758f0704f534487356efb5ba5c352f3245ae098ba786e60089813d99061437a0f42f244a9b75d5278056405da75bbe0e81aa3aefd38c730548e49e066237e371be07c5a530d57d5ad2296feed6d50c3eddb3628c5f3d0d3e6e9c37008c222d30e71d798800546159f86e9826534fb33668a8a3e3aaaac1df46bcc3f44ffea1f1bd286650da5a4c8eed44c9438b70a588747a8be72311f13f6ca285194a6d28fff9d5fa158fc49c031a45ae7366b46e25330d394c9e64ac0f23bdff69cb3ea3301b93883eda59874b6e263110bad2bd34949df619a143c7d4cf0302f5432df81482e484a922ca11c26119a99b78ffd6dc77c8216bcff215e9140595ba4aa86cc15001d96fb5e583f89407a3434bfa564eb7ac694c1a545aa19749b7367f3c947580657273309a51d9bfdf780d06212421d0a23ac52adcb6ecfae4f87104b47c51d39ccca207a6f5177fcd1044736d81d407aa6dc097dff86a7d46d07f15b78ad1a72f0e515047a89d0842a018aafb99093deaf2920a296ad65b217dd49b32cd09b59ba0a916df86a1edca5cd02bf83c58d3de35e09bb1b76c8b2a23db734ec07078301c4920141884604e0809a8cd6de4a0c6c8612f90f21341066967076dc8d4f84137c2a87eca59458b8c813c4275836d4955070b191729f9915c04b3d6ea88e8182f8941c9561981c8bb77ce9c5c166a5f6ed369d1cd5dfb43cf383aa119c86177ac4e376ec6e5272219ff3387beee9a15f20322c4c1916b015384249d9472cbf40d8b041ee268d8af755cd98f4956fb508414a717de845bc015e8794da0e062c585b05451b4f9f83cd5c56c694b888faee81c369171189d6cf087de5ad214ad8fc3325ad0793fe7c510848671a44b6e45fc8842cd15c017bf2512be78c74dbde4117b5c867d6e434bb4347c6d9dca13c9a725c361e93f79e54772c436aa60c4459112d0d1256490941b5a930950c243e412a41c1ff9110e5e90e01d063732f92c8b7b79667893f7034e1d4ede9f891492fac80ca5cde874e29dcc35425dfd1c8256f3e4079076ef956b8a52cde6fc783382ea383071a61a616769c204232282a39cd5ce1ea042e50f2fd4b53ee7e3483628d15bed17844a9904203230eeb6daa967108f804bc49c3ce0719a132dbbd33f3d5bdb0ceb35537d935bbd9d2e23bdba7b4ecc3c4141de1fe49c4d023c6eb75f8ffedbf27668d1572dcf1c12e087f90502d48c097a6bccc737fc059b4a1843fc14de5a71553bb5a15896f1a862624936649d6715d1e8e061df387b1f61410f2adf09f1a83618053ed1fbb0b749beb6a0874ab7efb16403076e3c5c99a3a3228c1a1479a9b3e26745f13e92112541415abae461be42f32ea4c304faad5187a5f455283b42876c172c62fd9af4bb1cf70fd321a14a3273bc8f3e8ee5b9e25f3ce9f29f09e9b2095057bf5273c34f35b74062c1051cbb17f99e72c7433208ad652ab4376d96e49c228f6ced5373070c7823cacb6df851b02d2f6140a022aec492da18bf70f8a154086d1b7507d8be58b232660b94f552eb9666fec61e511a5fe4188d53e60328252657117a3138afb62029859cf0f385291519513f238b06130b36ac3db68673cb087d2c083b8834578eeacfc75aad78d163358a065cfe09fede0df4b4e0abca15b00d230fc1cd508ee22baa2b2f176e165adfdd7cedf82095a0ece6a2514dae0e328071c6020e1848c84bff1e7cf0d0421a0a03e3ba7ba97c2ceeee761a933e3de4ceb3af17d0753eda2779ab6638775158642aaef1e8149327922d772df067b8398a7295475ad6acdbcf57d679bce3f4d3ffdad43b68bcc04f3ef8d88b3a5ae1f38a4e205e0b61ac3416ceb3bb6c280d7368f6677cbf74cc70b4b3d238b9f3ccfc13312375cf75520d245c7f11abf3f6a95fea7cde28b040e1e20b43f41ce81a74e80df72666fa379fc775a1c90217c7ce2e9c4f45c018c1711b0a06f778a5a84034a55d3a01da31999baceadc1f220706c80785eba89e8b7dcb319698607b739b4af588dc2976c43d4bbdc4abfb168bb4f3de14ea1a6a03134405b80f74467c0b942fa56fc2f53d1da76d10b3ec20ce6696cdb2a316bf0a62af6deb5d8ba8001ab064d2a158ab69723e1c44e3f5323fd9c7edfa1af1b2eda7d496f9ab86aa8c0f2eea9b5a9a80fffe8ddddc384f1f76c3288b589058a64fdf39541802e3e6069c0550d10a90a16e378eac1ff93349638421e0c60ce94a942a7af7ab9b8131ac10624c958a8895b3d1b753f5198770c63fa78db2222eb86b682f4036085dda9484a80b68c891ded1e3ae670d69109c4667b0691ed2b4c703dd529032de0a197c08c8b998078e6c74db4c694a46f6313326fb00a1f161c4605fa153469f40edf53452868ce0c19b22ed615512d82f021c3b520dfd5a627dbc9bfaf900c52676a40c79ea33498dc252a6558d8f59b0f9ca9c8e0d127f41212dc7d3ca55f76e8c471b78a08a2a6039705877df38621d1b61ce14e7aad45ecccbab09ddf2611b0d36272fa0a4bc72c9978a997669b93e400eab650d47df02aab5ca6ca3f97e19f7df505cea1ae2bbc1f3ee4bebc8614b5cc360e1615f71ab24dddd737ca82384af029b399ce3a62a56ad7c1d560abc6cf76a5a36a36249a37b027f1924201fc4f7b99953f1c7cf4537306b5ce8c25f77d5bbbefd9ff5004f2047a63e7f4ace3d4a4e04d947eb49181fe4278cf3e293ac54ac67f02011780473c7e6c80697666662c7f731be4962fd8e00710b61dd3d06283baaa91c1d835a387b908fe429fd960431c2d2483133f7208ca01d729a19da6c097f088cc6f385d79680c351dd0010556f8e98d346f131ad96c5de97d9ca2f2fa2df2f07bdded4917e83768bf2d20ea2b02dec55ca152fa4eb152158e68c28bda60effc2ace7a9d1372c4802cea25d78855665e5acc56a2dc9dda6b87a81e2dbb32824e2f8af61591cece25a846f493cf92cbda3c49f241f502debd85952f39650f10eebc0635854359fedc0abdb7c6decd364e1e8f6c89754f2116e848b29abe39cd4406f915783e2224d5f2b72e0ad94a9db41ff923f9766ec14bce715e677c8bd7e66c4b13fc16933b334a9cff0fe200b378fec47ea086fa87e4b84a7b61714dc1c29bb28e064316a7f6844f04b8c3233466a176fd9b57b4e672384a5eb9ca8dba2c8822151bb38d42fbdb1001c84cfb090a517eae92cc5e203f9a4d3dac246c15b2a4a3e5db9a8279dc8690ba6144f345a778df40028d3d1681111ace433644701cbbf8966e7a32f1ac058cb8af2eb1652741d0d2f9f8abcb95697bee42c49a455e65117b99c9641047755e6a2b4ec072177dd4b352a430fd2dbdcf89a7e5774d31b42ff654417011bc3ad7e586a2cd62bff5f182023e2125b5c64346b208ecbba0121d5e81def317f2657caaad870add1dd9f52aa86c5dbf1525c6508550488fcd0b602969087116010a98e87679bf22f41f4500ecc08621e97d124df2bc92a48525d37c50e4ccdecf5eb4a08dee3af6aba6caa3cf0f9fb13483d16fbc26ca63b062a7c954f4f6d64f43a4196bce635704adfb9aa7ed77f752e513ce43535cdccc4765166b016f5b9054ce91652e1f12b37f65a883ee0161f67ca1daa3a8ce4f9a983f6dd9a617ea52aff8fad3d7172d8c37f3a03438e1afaaf57794fc86f9d0f4fccd1c564bc7e7b78ce9c0240c751624508979d086edb6acd7d814581a4e2fe75b677c556e23451dfff67f36af9f4aeb56c92846aa0e585f696dccc8633ca82456548086c0d7b8bf2c91c39bdaaf385b2ad8304f06b739267bf8bebc0ee7db2168643b74feef4b3735b0c5920dac8796f8bf01c9f8816f78a1da42ae8e7c20957ba05c7cffcf9c8c401f2d00f392c5adce9cdac857a1a21c94bae37c4333dc32b3e804ede35db817b05cacf3ce1f5d816f444edee4760c8b5ad0f10dceddd143e7e2e17968266bbb6723df8ba4f0d8ebf045ca6577a3992ac012aeea57f80fc89ed661084aecc9e808e280c52ca209a5cad02d790a404b9eb13aa008e6330cb2d5206701b642d03c5260e8d6300906f6746fe299bd3df757dc14a76b8a42e6e54d93ba8f4a08294c37950e4c22bdcd1bac1a06ea3d182388138a1a261194a50fea5eef04e3ac6c5f63d4afc9828d26a17323f7f19b7828273b507d7103366957f1b651c9e1566fe9b84861bb5d67549b25f2fdf822599df055d72f3cc46adba3d0cf3264c81947cd6fcf8c7cf74a2761b5356753359060a80462aab8502582752dd7c8091e2ac188f85e661c7c4221a2ba829362b77e6859b6c9eb2552971a7e1ce36c7c706ee400d3caa5b8da13449d08f63e2304e9ed613d3c26f8f730b509e96ffddd2652d74e1f0864d7e9c9021b00aac13aba7929c5dfda6a9b4a5fcd22f2cd474dc1816e985632188b0aa1057107cb45a63b6a87024e30a55255ba1ce4123b573ae9b15d9df47b2009edd1088645635912ecb56b6b658d2d709c658e4d42fd5b4e09b7d9725a9af014884183cc58313669b9d1734a215c2d8b256b06b3ff75a6a7e0c38451799673980e4047d94158896c062238eda717163b546626ceeb53e38c325df3cb9632b5e9d1833fa1b7b95007504523c65f5f251aa9dc970abbdd9f769799d933b7dca120b28964cbbfcd903bda0439b1a0cb15dc914d8b6e99c9608936103097a0d155afb037b41018d12f1ce08646b9318ac0aeeb786ce5ac0df416a0e512422f98c7f2997239395e0ee04b5d166fe574a8295de01c10095eaff37818b016e4f8bc394ec31d0c3fc9f288a62002890adeceac6762acad7f45e622b05557b9a3a249476956594f302192d59d9f02ba513eff50025b27dd12e4a826774f3049a68cc5a4f7dfb21353ea20fcf01fb2c873d4e66f827237174caa6dc4ab93b66a7195988f177e3be4aa0e1b89f116fcfc94aebd149e1b4c35ef77bef85a616ef9a3eff5ecb5764ff2eeaf22c4900feb3466b9ee0c4cceff8b02cbe61516b15dee802b9bf0f1654c1d88adcb0cbd6193009cc8710370d285c8a7b34c297cfa4c0a750830b87104c52888d7f71257ad360841b7cca803a3ee09d25b1f9d0b88178d788fec8e14b2569a5ba8fe19a82f24236793b93e2ad8bcbe7dccd5263f04ec39e424c338df56585f7db4f695900b0dd32a4aad812be24b111e5c67888c1fcc63e8834bd85b7b129b291faf8f479486a5438b1ccd4a2d5c80209eeaffcfaac00a5ad009aad1c864623ef160b62b430cb7109888b9a5646eae7c6f9ab635b58fe4791cc2643408c8c9083a6153f83edfb3edd2740e9754d7fcbf8ec9becd0fc204086ce6697499874306c5852d4988e88840197c929ed3111f61d945812a9f705dfde281f3c5213000331c32e148305c847d019950b873d732b005ca4a7d9faa1a7b682c475bb2105a00a2e502f5f1ba93db6a816e328fed80236198da274243ab6c46f3d453d243dad0f8341526d53d476c9652f16b6a2d4978ab4b7d52e8c723c75e1ba882b2cb9528059b44be37c37060f21186e166e2f14bbb883b588ffa55e99bb2225ab0a436ba994e8d95e488b18dd3c4b9e9904c6378b211cdd6ad96cbfc1232deee920fb2ac6645120b81c93afbcf749dea6380b923af7735ade5b44552d6604d92b280bc61f33a207f4f15bc2a6da8269709067e0d1f5d644a647a47738b39ccfc5432a2a719d6594e8bc15fd16e323325c670844749e5210dbf3085eaa4c5afc709850b323e8253c5c92a594c96cb9daac22adb9542aa3ab334802eb3671a7abc9313105108a7f8ea16113c22dd3ba953f42d4afe9179f49c51d1b2ad423acfda2fe685e3083b6423272436e338706f03c6d487bb8835a628ab109ca6a1413b20f4453084cba8137e8bce9c324fa3743a70f6844416c031e438f008cab59b174938a19e27dc5706aee6b726c91cf526e36d6d81fa506294b23f7df28aaccf0b21d172f13f0e7c0d485570f11c6d0463e0ec6ea950b2be0f281401d6cd71152a4f12199a097516dbf1281ce2753f8a85663e65ba65d3a1e0264e02f51a15d24c315bad0caa8960e887546e5950d6fbd69eb25c25519ef23fbca55a7df1ac2fc6e81517027c8e79f81f1ab4ad1b0be1f94eb9478126b52034f19b97a03ab85255f34878245de2d02483380e577b0ccde72ca56e5e86e6f5be6fece73d630359926f99f90d0590739aefcd81ead1774f2f1bd00d9390bb0ab7e1343617f9ac4564941618271bb3b821b3f96b00d6f40afe0d3c26177ed4d994448f9422844059d0c8818e36d83b7654a8e27cf17e9de7afa4245ed315d8c161a65b594055671c7be538e91498319a8a71e180d7699979364af1310e67a93c9a3f366afc80d39fc98e90c0e7f53e9547a7ad9d60e0aaf384f39a67c4e1fe3adb8c7fb14e7ca1892276edc244e42525e58594f2176cb851de9b7c0be60af224ae2b1c1533a781d481e8a85f64542aad246566ab8235d3093901fb8cbd3b2dd5bfd1f175919d28dbcb0c79efcee67da0dd3ae11fc9a808186606f68c77a3034500c0d6d8120ac7e283198adce81e57e631d830266eb102433bdb6c26c753475e004806a3c0bee01a56605660bdae593744e4e6e48c50e8e25333e516bb2d99422cbf88937d69fe8819790bb0e691806b0c1fb9dac5092451a50cbc69549123ae234ab5af738bf98ed4e51738419e954e5078b0bfd7fd66a0839828c2e923fe535e5ce5f5d87f4dd6dc4f6b8662a18c01ee0bd353c9ffd16aa9b940b02a6bb3725372aa0297c9f7d512ee23d6adb851232ab61ca51e72fda32e44e78a18557b862867a79c4db59aff68b190cd6d89af743beed7de80907427dda40e927aa177eb00bcabcd08f1a045cf784ff43670342b217ad00161a984d5344f0c4e568b30a2090208e5f2bb6cb0d47f167c924fa842139918cd75b935e55184ac593e528aa656bb22999a60870a940b7a8473f60feb4a4bfc589699902c549919d845bfaa04373a8873c429e27a6cc8710e5c06ae4a1c2f85025dca81a420e5a98830ccb629cfc10791eb8521e521407ab818f14e247a9f29895b4f83d8a70609c684cad3667cdb74966b2abdbc96a081cce531f4886db3ef2cda260ba7b97d565fa07348f353063b5522a6c71d114d175f92a7a7112cf9cdcf745880f13d0f99676b597665d3b4f85aef8cd59cbda4055bc82cd0cbb9c47aa581624b3acef0e3b7dfd71a9408c0f80edd32b72613e60a5276bf6a58d6167ee857471a6c997b8e1516cb36967e73874bc15388a4fcde4495e71eabe7975a84d6d4c29de253314b6a794d0c8ac53abf184127bbb50a77ba7bc804aaa23f60235dbef854087f74c92bf9807d611c4aa9c6a5616b68327637ad5227498b35ae9731a6b46aafc3968aeaaeecc95d5ae0f660e202ae08be94dc6fd1ce0bd3516696f33c6a82026fe9bac24ff31983855d2819bacbe52f734aa09051fb1d42ae9cdcf1568c607ae89d4fe9d9b63701e09b0ce8587cc7362082b907be195686d91c69159b595d49ccd625a21c0c1fa6dba4f756dc89329c8a38b01ac96e2694e24e7a68156e3e97f32f8b0e9ca5090107a97108e0404e20ba26cc94a5843cc5f178e8448813774587e2d9fe5c7f25d3f56dfe5b37e2fbeebe7f2b37caf9fd577f958bf8b8ff5bbfc5c3eebd7eab37cd7afc567fd5c7e97cff5bbd28f32e5a5182b466064ce60ad01630f1012d30c59f20c94345c5d25745841e6b2e3b4e1487edf3a2e2669d481f80c2de30ac964da4aec265e7784b68ab1ae6201a3c5d801ba71207f3cd11047f3d27525560c0ad1dc0f6f839c9c9452bb3ddf51326222b6c578bcb792c6eb4b8116b7e2a62c29263259a55bb1583842c9d555448702a1dc6af227f7eb28724a99a7cd2349dfb7a3bde10af9856b0489991231bb221ca40d47f22b310e77585ebaacac42cdf7dfabaa64bf17e0f4153146e2bb2374f440fc4468eeccd1ad702c245ae5572bd18135f715790524e82b142372443097d838dfad065d237a178ca917082ca686590f1f723f9422879e69da74407e59d79423984b9b47e2be6fcb1a2e2f5c7390a04c8923d8dd119a7924f1cb224973cb9c663e12fb6551903db790cce9562c160a92f2abd5e88ec8a2901ca4cf07c487720d7ac4ab2eabb8a23864582cc9a7f756838e11bd2b52d49ef194a231e06e44ca880910a09e3b041c715ccce962be07f453e0fd61400069180fd055dc60519957af053724be41dd7bdbe2eccc1717dd38e0354704ec8631d8adfe1b6f8588a30d6b8cbb43072c0687f4e6dcb8152c497dbd1efe7b74f612a20e23a4187716ba13dc69a06e24ab9d1285b428b858b682f0a7130cec103397224f3028a89e370ad95110fd46ae4244b98027a8479c6f84a53a812a1b8d57c8a3d4164ca5ba138f7164bc925d4c3c8691dc2f12474e4bf8570313a9a1db804c6b8e62433ed1d8bdd5fd43b02d0845c565b4b7482262df0e95d3181ca1396350372047e99067da1b7f481a37df520fc14340c931d677fdfc5c9df904fd8d38269c016435e88229202643f1989a96b7338d2d19c40d9afb5a5f544b8ab66912ca40940cf62e24452328fe7527f231ae1a8cef6a33087c3bc11e604abf149301a9224f14400ef10d0198cb4aa9240ff84821601f3d0251bdb234e726a607c2d9ca9aae4e1b8f028e42bbdee50395c582fc8317c780a5c0b727df98e6479a03e0b4b5241cdaeeccc3338761eee4b941eb23e05585524f55eaa6c54a3ae34a61e7d011eec946154b3fcf076cbd264277a9539fa8582b4e7a9ff2c3711b0b264c9a3dec38ce4107b642f6ad8048a1c385c5142abcff1d7f6f67e498a92492a87e2ae744ed1547f88c2fa2a646c28ec165cce29617c61d1afd7604af5d8686ce9a93b528240b348833dc9f92f0daf303ba32be541382ddfac3d0c219362eceb14cb704093e37ec94cd2685cc8e9c9fe677af71d468eac18bff34191c411e4cbb0bb709c0215a0da0aa5187831ee54be450bf9533e5f9e8b8355cbece40b091daa5294bad242f5351661386570550d0c9e262a7b03ad7a910857e09009942eebcd43170effe1c40f05a91813ce95676b57897bc1e08266b1e2eefa5e71c2af8b54bcfbf042efe9967495c9cf042029939353fafe987c577191915cf0751cb71db6a8b8d2825e66489f34b741189ff06910e555792490467ba7f434f028dafc9c9c2caf0f5178d9a70e43012cc157a65c4f1a0555a23777a27bf069ba5abb4a2acc4e94c7f0400b44a2ebb88b092991c32c1aec48012ac5b6cda56f8c13a753c0aafb6531d9b137e015b9c0a63411227213723152f7902a07ef0425340b6d82349f2178ebbcdf671c21e7ba480235bc8e68a402044df6705479b2b9a6f5a6bf9208cfc7dc0eb5f54361d8fd938464707b4ceadbb51b2fce2145c612ced71cb9b40e852e2c705554f3a4ccc968b76ea4413c2c2b70d084017a40a43f754cfe2702255dda6f49d7077e7c3cb11ae6d796efb3334fbf372bce7175078e9437aaf81d9f2acb19c6a4633b93cef7b681d347f43673ddb9cc2c9e1c6b8617bdd8910267bef60737c065cca3a58c13f0152eb0d99ab0bc34c5cdcf13f37930522665e62ca22f2c9a8505c59e994b51298de99c310b5b05fb3d66cb37442eca52a8c3fdc899d723f38a1433519a2886ed97e713daa2b3c441c2d2b958748a987a7841183a22ec76e25b22c54ffb0b44b5d090341b672e2d4f80dcff6eccdb4e0970d2178daea22e184144d800802d98d32c60c1fa52da16df8490e79b52203b44431da7f1b792ef4c9a1ff236089cfc0aa4522d390f08ebc2a6453ecf1d651ecd7e5384302f2b90b24c4e9346bb9016a9e1727abe1d88977878f755b722bde435a4b2c5d64a22814d0fa9463bba5ce46167606866cee9720f6d2e7820d765042b9affd08512888514b120ae48ea478df4802b6562b475d0504f7883f7d88c927e392b6b1ea7c107d5509595011109dfe6361f9ed16e68c4e8bbe4aee980b4108a475a2e745a4af1fdb9012bdbd5ace05b641a39266c6681d16023deba07d63a43bea647887f93594ec0647c8a79835151f42b63ca26af4a09f494dd32df42356b8b1ec81425e911bb47bb01cb48d7a78b3f66ce5d60178bfb01d3c41c9324629fd8fc131bd4aa56584fef237b6bb62b15c739b8f2a6312a40fd6071638fd0667abeaf5bd92077b463c644f519bb8a04dc1241f739f10abcd9d603fb5bacd5e8f8f06e533b6890f6849775fd123d0fc598d0660405c897f3765e15f4f67ceda39fa0d944213e671e8a90953fc66909e1a3c8a6d3ffd2ce70c41d9044921657c9417f95820a544fc264125efdd431d017d603aa6f7a9da03a6e7f5dd4e69e9682ff3e338e24647fb02408132d61b1e4e8b0be49a1851bfa71f17d7f7f337dd57f9255f62ffd61e9b558cee63603a934a2ae10b9e7df322d8319c05ab0fc7100823d43ae25a1433f2a51bcc0b95049ff7b8db3477bfaff7f78b423e1db0939f5237790c0c04c1c7e41ffc0fafde82818e8bde129594adc63c0421560cf9d9c6e628faf75d3b2976e8a9185a7e664cb3c8a3e6c912663a0537fba5a7eabf77338e2af39ce62319617f183009f641a885a3282f7198fd25e432ed7d9cd347e5336b5270fd12ede32807d8a080b34172cf6f19605af24ac52905ca5f5901bbc73f17c8e0cd6199595c737571f915d25cc2dba60f40cb39cf0434fb7780a2511a250d510ef48cda83ed9943d078839f382b3c8498b3e62c7a4320c49097a3a84e109ecaff09e38e6bb64473ce55501e4d638aefa26b16a9454d25574d95cf33c8b2267a12d08ed26a5502074e8eb8bd3be1dbad12ed72b9f4708a34fd8c41b10906e41fef693c80f105a4075577c630f6ec40e697bae890c60f85d21449fe8acbcbb6bd4bc8c028005a5fbcd65cb7ea4f37bad765f87083293770b1fa33a5dc9df2b5ddbd8e188a53d68c8381afa10a23df35f3dc785cf8ca973b27874209834dd25d478d8ec4851f43f22995dc0195810839f8225458983edb1ee9e859248ce19f00d3545edfd1beb6fb62b32901c1659fcbb82d39213713997153999d42f2de016ac6a38feb9aead0fa747f08d29913caac6b7bcdb77b62c3e420efbff1cd0724c287b1236bb38008c6cd1bdf2049cf388a7a21aed8d3481fae924d60beb951d107f76898586717eb2de1da2e047a2260755728d366dc6804a559865cca9cb42527d66c4b131f71a6fa4d1e0f506b48da77cd65379057e5050b88465ba322e4c241ecca5bfa55bc9ca458e78f0389710edf8844ca96dbb329be32706125ec3149f667cb445be84b2de1c0bca999d7f225f29312731573a06c5252b44c7333254f92b46ab1c040149e4fdf1973be2133025e0e4ab5796bf058fb07a29b3d4f08f8b7fffb260c90b712c2c613400026d3f764300f9a05beb204d3341308c641b53bace6979db9cbdb1781987eaeed9180081d795971e43096152ccc1b5c2564dfe61ad4fe25c0099665321e2fc795288d1451460d85fc184dbe8828e1d801b350377b28107f2a6a6d44b003604850afc5121ad2d8addd899dea71a954b9b3cb909b1027c1355cfdb4a8372c8d5421a2a464e14d49aea86161a162aa4ff453b8f4f016b4b53a84ee51ce0170e7172b39d6870b5c4e0a8dfbe6ecb10b6f1a3d1177ffd9e792c06cad98b3adb019b2492784fc5e4327f09bcbeb06069510022f459efb425e2d6c67df2f0ff44b764a51a65e7bfcf26a723b1b6cac65d746156a39769d2a0dccaeeca2bbfe2741c42c44ad3624d10d2ce1bebc8b3ca8cf6d4e52259d595f6044b9c1a2bd08b19f44ea75d630635a87e8f2bf4c1ee6cd5514f7203e453950d16e84b0da5107a0ae4bed67f2c81ee91a853b7c2f967a483b5deb12891db0be7553448ebdbea36d37431c33eab85a7e0265f4546b05d59a86733111e3d2a49b3b1c5ace33a6609266b6d74f50a793d633790b04fe5da6b90273b04c249cad06e8ec19c1df3b844776d7efb9395ed151dd394c0f879f7306e45691008b438684f16b09742f0b4ba4213b7ec085668273758a267560e523ba8ba699e14ee6cd95a1633710b8d74cf2dc0c86ff17e26eb508fc885c91f4baf006f362fd1c10574fb47aa74cd55552747f9ec2cccd21822210f08b783bb7cce6d723b8f7ae55f458dcf0318fa674f848c2ae4d97314c01f4da09e0f9300b657f857419daaedc9ea9ebec3e6660b6846d5a7944bf0da820e7e5c93dc7c12177520ca3da6e6ba7c1f8b213a455401d8d6173e392e263e44a77f772716769ec326628bd8b3628942b0505c4c7e3fc6abbcbe0b1d06607fb0b135a706731e4422043276441a797cce7908416dddedf2b761a315047dd34f0a44a8daccc611c0476a21daa67c8f137e46b74a85dbcc9152dc69d7d87618d0e3d590e53081d4fbfd61360ef718782ad7696744625b0a17eae873fb740f872cf667ad76ee3bd157b472ae18d2c87a4fa98268bddbc4c08bd91eea2650fb8f87ab1c0e2671e603bbb9a064cc18d24ff9bf2da02e546bb1aa812f85a660b9e4c07d295e89b3960f1d121ca367b7004eaaec8c03186d3de02998509769544e040a4625d14ea4b6f33778920c33f97d9ebd8b70a41c7c25a047a95bea62a0fa9e9504528e7451f4ba7b3aeeab7668da320e5245e2e706ae4de69c848934e98e2d3a831f83b1d98b4dda2381e895541534b510b459929c0f2104818a4444fd260fdd3114b799bb38ed5c9f729ecba9cb7d5685983048e8e3837d8c2ce3942320de1b5fe0e03c3e692cae43bfd1bdabcca331811339b52874978c861b426631273b20996201e8277a3d5d519f0bf86833f1a8e54445bf67cac3a38dbcc6a09080efd377b9ed6b7d4c1cfe60414d3e193d439febdd33ec65c74c78dc6d30b8394edbd7a838c6a20ce5cdb8c120e298ee29ff82eedc3587ee6233828a92e9f81955aec661841618136b029315b3fef4d3172498709b925112f363e2b2fd416a731f7ddd2f16915fafb82dd53c335a8d63be30dc8f19f41f29f77a49290fb8259c2d1ddd52969dde072e98aaa70e502045c59fcf793c77492f1c798902902610010f70dd5d7881528950f119a02645f60a6b56698efab72174c75fcb0a4243b4980d3913db8e6f5e3391b6ba1a09c75c0ea048011fcec9c28312d0d58ca137779ab7e49e035c2320aad5d2306ea8cf436834253278568648b23c1b7ddef1ce39ecd7e12653fb90456528dc62c9c68a78ac16756b61e99a114f42d3bfe4f3d0673b62999a8172d791689535110332b3836469d0e860e2bc4d35ba61970cd0ff23109c0feb40d1b6249ec77a15b2e1c7457c9e33f2be14af8b0621edf4d904127072da424564826d7117d8e32c6f5bd992ae25c3171f3c4c3c138f07bec1d22b57bf7771211a1e2cad8580c91310efc1d6b07918b4dcf58d4f105aa48efc535582b16a4625dd98158469133ab2a68b0706c218c93185d997993648f8d06d66714096334d54a9f6868c8116a3d5c85dab5a4fbc228453c2510864c1d2fe81422eb52fd388c483f7a2c3a0a0a07f2c70152f57d3b45b4dc394a07c38935ead75b880e38a927a83b08c7743d7bf2921fbaa017292227383c6139cc023dc7bf48eef38b9f02d92e1a91b738594b8e861dfa5c3df2be9b2a72ce51c92d7b489d772c0755f7d61491f0b62c6b82786bcad1cb385cb7fa7f969da2b8c5db5743c296869ea3897653648af75b01e8e3c9379dbb20152b2a6c54d55a9af416664edcb123a35cd747761ac2740064d41eb2fb540f7c37cafa6ee5341ab20779d48474092ffa03fa75a9fa804a25720e368a14334d2572bfaaab8ea54978a5d82fa4e45d419980977bad6728c9d30a749becf6a7a8885f29130d0457a0ad3310b759851b28a2e942b6e26dacb785fbc9bcc1afc35f0a2cb50bb3f77996940f4686004626c56fffc1dfd4d0fd536cc6ef1a2f3528f0b3a6be665909df3b201db747bbff146ad835ed6bc24eabe71aa3fcc610ce3ea0bb13293effc4f2f18702f0ea857e4671312f380600d7ef5c6a6b2877b4dff968e02bdf1c1d03c37d9e11f85ef8f06a4346698c20205a937716dce641a4cd01077360e55f144d193662bd09321fee955e370ff326c62023ce5469cae59dd94162726fde7191557b3e410d193adc591f0707c0c556455e3e613416c89d26ffd10a0fbd1c7d9215570606487391b069c5d5611d27569c0a1d650e67b7b4b18c66fc8ebcd889c5b23ea319f3b16e1121bc8b72f551fa7f48f09315320e7d98c77400529a11ea94dd68e9f7dd10292bfcd5f6a6f2372fab1882e7c55bf5902192154aca0845c857635761cd17ebcdcbc3ae3fa18cb971561c4091a3952996e7023f5f9fff92569ab58f058dabe2ef681c85fd00dd78b60f63c32c74903bfd7f0c5f94065a4d87ef50c6cc2b8dd19d154ae541a1afe2adcf93ffaf4d99d20f8e3545833bc78909525422b5f77683f0d297076f19687081541a0ebd2bd8b5db729cd79c21d8cdbadfe640bc764657d57c3a90e5fa506e8ac1f7812dbfae616e9611c94692ecc8fe8bfd207f8b72ebfb3e5fc0716c331909f6df684ade7f456b90d7b1b55f801213e1e6a26906ba0c99c170b4e5a3b78b480ca3a23043882bc1066b1cc86718cda270a8e17e820d8e0a42d99ba80ac621622dd24fcc21964006d39d17182cceb0910972dc7651bf2d85711410339832ddcee8066635a1f232efe7d6aec67de1230939d1abaaae0000907adb4130370845ebdc61ed449188cdef19d0b21a1f852a595ed34f34c4970429e83da880b4b0093eba55b81f617f0edb900cb30ce6f3116051cd39e1de913d4fbafc182702eec3b46c2b1b026a0419115ff57e51e1cf767686675a5ef02bc1c24ff0f60f9741f9506f20d895860fab69c2df7673988a1c8a9ea470f35104db5e172ae71710f7a01c8ed2b1a74649cf9cd32774f1eb98e89ac8b168ac2b077fd58af40ef34ad41f0f8a873bcf1f4da053c547e7112d584306ddcee98cc4849ab5a9e8b7a1b78e798e8e4e0c3b2b310e1acad634d74ef4dc36d53565925d089fcc6fc0449309e0d534a461095207a6497ac75f21c983cb3c0a45d24f0740b893b52daebfccb6ec312bcbba50fd913e195bff25c6780244d0e15fb85f01b85d6c9ef7ec14dac0eb4dfdd320555a9cc76ba608130669522ee015e7828fa6b22aac5611ed2cd101db57a2a98e631052b48e2a94a7fc9547ef928919918b14fb09f824c3a14ea93753b3270b53ea4c2a993c51c8172400aed0058298fe4a06e10206b60530df7b45189b1ecb84788b4d311aed84e23c845fdb8c373f6fdecc80f4ab6d23fd282c76a59fec52aceff0798458da6d6b02c2d0b5ade52b33e59ea47bded95a2f1d8a9fe1d13993b67f01917353e12ef164adf5bd69a55e93f14a8502bbebd2a6970e56b14d5110da7b99777150494eae634f58e72f448724a928e31f9b300705b0f4a886a2fffc66ec0a040db7ebf86c94d6059e4a761b14c1888ee55ed795ec4cd416a65f3fbf2be6975f4c251415fd322cfbca85edc2947186948310e12f65bc69c48322129cdb2243f5413943b0fcee468833efd1a83c2568016f04f2ead224239e02777bc7ef2e2537d8cdb81795f740663dd748486fd7e1ee093a10e6de063c2c0afd1a7881911f2a0847bf726e63c17df7407ff3bc717d6f6136795792daf5351d159bef08947dc70604054cec71a9edc3ddcf87c0727c03780783e3000e6295440a2345f170b4afb6e40e851b568b025cec5f1ed1e2a056610d869626820a6214d40ed0f26148e87ec6c5b7c629040de3c9818544051f82b8c1b722f482039ab8828d59300c434a07471c7c5c549861390d03d0978e09f57a8f0e2367f25390876de7e90749f9a9296a2b9e66bc8861fb2830308e729cd4ec87db918297cba643ee3cb0ba4f9511d7b834168921cfca6f89dc7b6fb9b7dc5b4a29a50c570835089c094e7d3281e535af51bef36c0938df7966a24975cdeb0e41b7ae8939f34cb061a2cba37428535b14afa7bee3d4a7add86df65cd4ad96f210f5d7f39179ec74a84e7a3d3ed0f381e75c3bdee3a04742e6be7ae8b927bbcff3e1799ee7437368769e8bc73d0733eb99a691504e5d869e8fec7687c7ce0e37b714a57b76887ace3f8d643d7e0af58147aa8ef2c08ba8e1072ab6208112545a3102818ebd1ff735cf30061d779df47af0f8d0a40e5a476d1e1d6e1bf5e91161df7c80e03b0fb7e740f0d5b3b7c3edad5724ea16048f75683d1e1b8947abbcea1aee69a41a1bca339d7940ac6b5e8fead9add7a3fa059dd357af5ca0f738e83d8eaf5779a8bceace3d8d943912e8de75ceb7cd2510cdab4f5a2d52adde79b657aadd43e93f5ffde071d0791ccc9c477799f7e8ccbb6f7a8fe699d56db8d5d946eadc771cf480a47c88e2daf5e8cea30fa523363c498c0890ad216a435fa4cee3ef68a4cef10e9a2c89da422b57e7a0770eeeadf3360494bc9c00012522252fa0e7c36d686bd217f9b879d527fce61c87b7ce89643f444bfaeb6057648805bf79797cc25f6e6f4a7ff197c3bb216f1f61619c9eaa26ca05d7ae2a7258e5744a6365408e11b604d3d7984fe0e6234c0937bfe3234c09a7c7608482e9e7d24f9feea22287307584d1e928c8d411df5f892b1faa648c6070742d51c8aaac3af261c8fc942a1c2e2ab2ec640f58750516a6c9ce9b6fcdcf09707c843d51438e34a9311a7c848181a1823476d454f181e99c82f8aa38d1c28e9c6e0c1b652af0b2fa086ba2ca83b0269a54e0c2028caa9e1a3ca91d1d1b5fa60447ef52f1e7fcf8e3d3a5264be948d4c973a5c994e2d93dfd10ed4bd0f140af84ec479067be84eee508f2f5433678e9af9794defdb8e24ea75edb3c9d9352971579ba6440a506884952495269050e92413801a2cae3b9b7fc749fb04bd5a8a3915a77c4169a9feea329f52c553d147e0641e5a7dcb1aa8288fd749f1fbaab12d8022c5d4699402c5136958c75cab468572e942dcb8b6383535a629df71223bd395b3e392288c2804b0d0076717235030775a380fd70e64654063f4f87f34222c9bbc60f3e781f613f4881fd0085524aab85fdc0b4b4dfe038b174e3fa9223aca9cdc39aa0fc7c693b589287c82741e9edee60491e42bd8325d9ea21d63b58927bbcf422cf19679cb1832519024a6f41c42189a84ebbb71e614d4c1fdeefe28fadf5abd71c6076efb3f86a1ebb6d4351b794cefa28cdc218d4daec409dbd673f6b192fa0d62b987af3cde3e16d1bb77115d415d4f403f57c4fd7c902b5ace17660acae28996e7a6a1dcd75f49d409b7b3e89d4efa6cf2652bff3eab936e836fda00bb7e9fa95ab97c69cad911f5d3864ce25fe8121873f40d5c31cf5eae0ac739c7ccea9c783cba806540326bf3e9d57ff993a42ec59d6798e3d4a277510c9f46f2bbda743ce33bf9bd2632db33c27b5901874320d8e3fdacf63cfbe6b7da7dba1bf6b861ce278eb9be3983a74503a1e0a11b29e818e46e96e47c729b153bfdd0e7d88621d3fbcde65f69b330c1c7f622844e8a56b544af79e3e032f2a3979cf853ee4e0bd8dd43992e63714aa61b74321893d46df228dfeac8f3bec5cfb9fbb8b350c96366f5dc3a0f5f8a387f0e0fc0ed90067a4ed503e0f6e57ea5ebe82579af21fbd1e110524287dad68defaca45dd3add5f9e73f79c472371cee33a3ae45c070b99b71adef1aa95de06f6182fe8fc6aaa3badc30ac42aa5341d4a7cb556bdd3dcd53aae5dcfc7f58c7ce6f4d147569e44b636cfc755ddeb2ad0afb6613d2076f380704e37d63afc833ac6d3f3e13a1ee3051e90caf9f5bb572eac0dd10a7ce558c7dfbcce63e62b1f9ad7f371bdaa34128fc7eff4082aaf81dd860e3fafaed24038cf5eb7e743f407e73b5e43fb88cff94a5f24cf773ca5c39d1d2abdb63da1ac4325a46f735ed5abea1aaeb57617d7cef17522d9e31170571d5f1c97847bf1d649af87b6b975cd3ad59d46d25c8b59d3d24ba75b9bac211a26ad7a44ffa169bd21262c1941e1f531b2628c386cf522e9750f49fa904ab7313b2934597d7a782fb51fbbd770b5577325d00f4d78223a14a2b21e0f6ebb95be7671e160ea1892efa2e12794326a598644c5b3eb30fee2e71f96b873afdba6949c7bd8c97f38cf351fe938eecb9d7bc85446993b4250e3ea72e593ede330875d5c7274b90504f59d409eb7551d0fcc6922f67e7d6d1f2d4d54ce7f9d72bc66c07c7082f9b025460df3c18a0f502a92aac6d7713743f2231d603fba51ec5d50b2bc19f081e93befca780aebc1cd534a29fdb13cec7651c9a18a7abd2d2ca1f2d1a6a66929970d59e51382c68120d201f2351761ea90af391113b4d76c82f5b0e5238c872f9f808f301e5cf89cb259add32b09729caccca9dc52b2d19105a403a4d421ddba7579439e1f613c38f9ea7446c171c6fa645d3ce4a8452db376d614585b9fac9e16058c71f43c0bc6d3a31ea29d91de0fedad9a900ed15e9ef051ab91aea5161283e8d3a58ed3e311a509536aa926ea1a6315a376384ece7a4cfacc6dec3edb91fae8d3edf0e7b31de2f86c8741f7e5ab9565599605cd2ccbaabb62c861c5b2b34a9dfb98deb9d25f1d56acbb4c2b7d2624c76fd64a5b4980a5a6d1a17937ffb99366d323629dfc67ce58ab8c3646a54ddaa588baf2c4c3cb4a963989845996e9137864da13a51e3d4bbdee2831c87c6a36b5a6406230bdfadc115b26d4a7c99a3fee675e9f4225bb87689f65b30b95aa12d66d4cbe6819d70d75ba6e20528954d8f5faa383c6af9c166aa4a75a76d9d5768fea7496911e0e2965c8ca6475e560f4c372a1f774a7c34826874141414141dc0ef3b643d5dda1b3de5a60d6eab1c6eb3a22fb4cd6cfcb1d3a69d5fcfce0d07e7e58f7b31c069da9659cf8b864c8d765e675fb54c92bf95ac9a5c9f2f139ed9c7eb78ff3d02a9ed57e5045ae4e3d4bb964c8e1ad53b22c676ff330493729683f55ce634bb662ab84cc696c693a944c8fd401eabee9d8aa63449961d06899618b2868aa582ddcbcf51cd6cff8f020b664f420eea426a39d245bd235bf1dd04d013a9d49b6a86b7e34a76f7b29c9062dea4c4314c85a8f5a065120eb442c64eade74a42535c92c5297d1a94fb77356a76c233aa2691a114eb66012b341891f340e2848a30c27416401fb6206ea3971c9c9420d1a255bcc8182e90ee92d3c75112d7a1e4cadb9f44898406c699b2351b2414bf36d73249a4fade44d40a975b79dd464a4f9d6d25c7a464b2ba3e91ec4d6740aac3a903efd48eea6a3a36c271d91adccb9cd245b99cb3a6b75a98328d0ac55f3ea52c7167d2c67ed6cd649ef83d8ba8ea5cda6466b94f7b3486411cd91685bc906ad229923c9b6920d5ab335678d0253f3044b03876889cb0a4230f5b0e4c715a71219f13ec2b2b0220b3040b226fddefbd18bf1c94f9f9c8bf09bdfaa692235942e357d6f100882177bb62df19773a9ef0e833c0fac518dba9e30ce9e75912623946710d429d26404fae7772729b58c96be1d29a0f21ed7fc5ec7285d84a6bc08e83b8ef2241dcfde135b1fe89f53807acf2eb253a467e9a7f7e8223b457afc73e9f5e826b98f769ceeab8be838b835bd79a6278f4b8138af9a9b70d8fcac9ed152de459a2e4a833b49a985f2ab8d50df077ee0f48c96be9dd464043ab893644b2e6547b908b33ae820f4dc7ba6ca4fd7ce98f9017c849dd1f2d2e371f43998a4e3dfcef611e87427ed38b82f05bad3b595118fc73faae129efd1557f6084c57e543f778d9143216e0394ceba488f67c7778742543dbaa9f3ac8b64e7d9ae0e5d1537e99ae6b26d7aa78f509ee234ce555293357ce703239aa6f3ec224d47d9515e64c7753cb58b6447edecd5d5d92b0d49deabbb57d88f8e507ba5ed15de1d805e9d024ee505c087378b261f1d737e3f9d397d043aca37dd41d3dd479fe79df47952a49a4b07634b8b2da76de618be5c90af1b76103855a4b67aed1c3b0899b641881428e376a4404654499b730a32b0b739e89b7f8e37ade39fee76bcd3f1ce330f08e8db0ab57d9fce5ea17cf6d1e63776e7dfe63b3acc1edd73d4a637cf87e6b63f1d077dd36190a2cfc31cdebd42adb283b0721f0701007ec3e3070957a8bdcabb8395fbf891cf1100b608dff98d2dc2839d6fd9b3cd735087a0ebec0fba64707bbe6d24cf51b9d321e87d5d8731eefc73fc61ec5fc69d83fe619c71f7e1cebfeffbbe8f0cd0e583de752ebdeb400c7e9f77dd0ae5abaffbbacf517a887edaf32e8320083aa83f0902082008ee50fae81bbed200b8e1473e7e631fad4070d5c10df7f1a31b3b52209fedf9d16a0ba9e67726f607f808c3e2ca6310cfe8350209f2995b5a6f90ba43212e44f53354fa39ab74e95c62c89758b080f2d7f11560ae78bdfc544882d2f3b8a75a798fd7a80029fb86b3def14e834f2f7d3b6346cc6730567c79ea1d7670c7c10c44c7519ebb6e67ffd0d971b2b2a33ec73a44797408ac5c27ebcfa31701b9ed0fbae4ec9dd7a21ddf3ceb30c867cfbca2cec1ec31ebf8b6c31510947f9b833b5ce9ec1fa81d27ebdb9bc70ff2a0e710e51907f257bee970f39dfd4197bc6d21aaff1c04b2f26f23ad5c6723d9406921aadfb610d5abbcdba110d5dbf0e815e8b07e0da79e4bfeb0b1eb64a9b65bdf76d8b3e364d5f03a5935c0227087f2798a78dc731e50da6ed39e4baf28ccac3084ffdc7a45f43de91585a067ef367d9e1d1679cfad5baf68bee75b11e85984ff76689d087d2fac9395daa1d27b3ba553de79b74322b4f3ce394d44fe46a4fee62e31f2ca253fbbfcece046c21374f918097b3fb8cf170ba6c7f111768599bf1eb5f46bc6e9afe34e87411edcd1d9d961be911f7494fbe8db39ca73b004f9d9abf7637e76e97787d8f30724cecfdb418df24e53ef07e8a8f99d9e9ef5f41cdcaac9f27cfeb791b0cb6e0b513dded763be615018e4a3578f8715a2fa12e40f9ef7486005152ba058e10466c56b090909ab42cd478f9fab8b2e7298aace04154d9efaac585a4b698d9652af35d65a6b8c34da1ae3a4b59bb39b2c8981f428299d74ab71c63867adb5cef8319bf407f56c73d5bb4a69ac91d61a6bad35466b87d0b7d3baa8ef9f7b4faf3b4a4c254a29a58bfa0443e618638c31c61863940e901f6747271551a40342e944ea87998744ee6bee72f3995d7a3dceeb91cba6ceb6bd72d559a70eead2ed8ada3a93aae6994bcd5a5f65765aa9636ade4eeada9529c03ce75d9e3a34cf324dcb344dd332cd87f5eab39399a669f53bf9f8c796d1ccc480deda592ef342ce916a176eae3419cf5a6bd5f5533d9a567d1804dfa5d48585391f2a7579bd9e041ab91dd6d7ebb53dc212afaf4e8413f3caa9a76e5e61747a7ddd352406342531a01ecbf8ca9372a538aff2539a6b3aeba478b8b89d4ed3ae2d72cf5333b2cb78e349d5c05c8a27bf2c27bd9ae995fc211aebf5155e6d9caf2c9765b26655e37e6835168b6179e90151eae2e4f5242879c9f27aceabd7836e797dcdf2faba875037afe7f6d7490ca816599ad1a15b447575ee50cdad0b9bef72a6e59b73de329773c6d9cb5dfe8ebe50031fde6903acb5725ce52ae636cf3c209687cc21739e7abaa7ccb22c73755e7df378647b0a3858d5c5a9a366d5eeb0820fba84584d46c2dbd5adbaaae757cd358dd361e6dc2a1b425f0b57f8fa6a5bd9eb2b796bd5f1b9a4afb5f3a149bf765c8ffdd8cc630f398c77c879845181e5f1dee6d77da98e8229a5af74e5649aa24b0dad53bdb232dc3cbc1e6a1e663e9dead5b67b70efabbb7b702f7da5ed1edccb7801f7f47f88da212ebaeb7e810c98677d848d71faa8836386ea26aba63c8f3fac789178ea170a364fbd0bbb32d9a987048a259ea6be36c1049cb75ebbcde3d7acdee93bd3f2c53c3d751e27cf33a9fc8ef70499ad74429163cc08950f6bad633ae001218278e9f14a5709118411506a48410634504c0f8868822a528c11e28527c050d18a1e83d0988646fb61ce171ba899bb831c27738698d3036c0e94394c14c7a972b6904326f3786459a65d989c2f72788854a49623c3a7262b4a0ca2c7f0135a2a4fa7acd25fafd7cba915a5474f8aa13b2a156e8742db0e833ed776c8f2b25db798a06f47969779e8aa4a85ee984242412c96ab54934aa5f254a935692c3620be94fefaa4a6599dda974c92afd61005a24e89689fadb4cf36128fb987c4393fbd0425252f01bb43f96ad1372fbd6a3f5df1cdcf0ac8711259514705e4bc1059f1c3e8c4530fe5124fbdea0fa8c8f1cdc70f23144fbf587a03660e0c67b8b0448b7211628d98d80e3d84e1d2a24574498108da8c79f2a1455d457728e960258e151ddcb401438c1675a73b62144a9e40814618342089a2456b3052450b489479139bd2a21e4477587084194378a922091a6b5ad48a27217268a1063748bc69511fa23b628bca9d17081c671742445d4ca955913539297cf863648cd624e7c87f65448929c100cb0287129ca0882f2ee010660c228c48a20c1173e030b1000b166c68886920c90c492c4901142796108d0007296a96b819420469ac711fd27c58c48ea82c682f1375d44ae78f20bf01516a2253c7f4307aa4734697932a89b3c4cf8f17b5fe7ca186c279b270cab83da481530507074de7f190c6563acbc411228e9527acc49142cbc4ee0e69cac479c559210e93130b5ec627c779fdf4d48f77c5ea1d511046e18418497c91a20b2ee03861e50338616e90228831395401070927d240a34c1a66ee0e69e0040107cb8cba8218134f624cac105b22cea7b0a83b9bb1959a8968bc114144838ab75688a8898bc61734b2f040c444126fae68395c3766de3c7113070c19148e78018c2fda30bdf93663886932022fe6fcb046078733a4b09d1b306758f1c4142d69a66cb1821671b0a0d104196c98608121093766bc1b9438a3ca19469c21049921b4283a1f6167b4f03d684499809532348031c5112d2e2000a6268c2dbce042a5091d32152e42668841b98c600d1919b85471821adc2451f20225892e496498e10a29cc80e24dd1c2c58c2e66446186139d53a5617289b76ab0329680b5814534965428e2862f62d0200756061a00f0a43481a1f0c597248e2041145a6e19282823f60411424243dc2b644311657c710a22f6e68d0d3e60505922a5e989112978513e64bd74e9d5f0d2a3f42b5d25a51242082124845008491c298119166658a18a0cbef08105187038e20ba6a730d913991af64989fbd485ab639e80c06da458f3d48346431b2e3d9daacba99c520509e510ea523e6d98a08842861535c04046096c80818c209afcc050c9d8818ad7d43dd19e62e09ea87033a81c831bd818d9c204b1a614e29a2c48a85892040e61504183c3208007656b9ac6bd10eb6898210ec258228c299ed8c040c612c7065fb9c20c232d40818e602246914116c0c70b3ee6f80204e0234b7ff4209fb742461ec40b6293b5791824cf58210f62038ca403241c89814fcf05a83957ef76586378873e67e887728e84333df5a19c037e28cf781fca397687f4e5fc9c93449ef3d3e596cc04372cba43d5674ec50256f5310f6152e9e47d6202397979c14a991c7a906203302d7828a3430a6d584881173d3258a1f1c98a262728399c09d3e6470530a23882cc0d2a9c11c68b27862b50a2842103a70997265f5290614c162c483c39a3a54cf660c893076badb5d65a2218b2b59d76660433b4a0448c2f28b05bc680e2081ea6c072a6150695309abc27b793a206229e5c41030aceb442d55b2b98b042c314629894d1a515060c328c18de5aef85b7d612c59063ca7bacb06913e6d49924c4e4bc13770c4599adb24f949c52f964b073f090bb8f303664887ac8df47181b259ee84ad63ec2d878f93067150e962a957d7e38c82a6743c4872c31340c2ce79c97ee88b95a5a83881066305e309dc8872c3d046d04aa5f49781959f5bead96b66aa55a5c1bd8dce0260a09ddcc563a6de8f90863934298284548288ec185044ec230f1448d0a5b98625872a50c297480e2e43dd1792e10514416304a46107b938291238660b3d4851723b6d42e758e79f25a0a72e0b93670b0e6e9b34a4c96860d295802c30529b0308c784d238ac1863567d8c061638613d9b0a6024a608982c9182e2824d152ca22839133495cc1a586245ad355412fb910128272af10d10c3f3f32d4fae3b540f484e8c90f910b423183ad71827df144adb03562bed65a2bd10b77f511f645105f60099a4fb31a559fee192d49df7cd541b629d0556fd541b6ad1f59eb5ce64cb2657d73aa65cb6aadaa8d740831354314e8fad0246281f3200a746975ea95bb9546a739bd4a8f2d9ab9f54bd5e0f8535d524e635da4e988db514bceab1f715ea773beeda3cee94e92deb9e7dfdc395320cd1d44f538ca7bdc939a8e6af874291dfb91748c5dfab68f54aa6d2477521005d21ce53d1ba5b94c9a3bc92990e63536d59dcbcd93b257dff611f56e2749271448933b6bdc9e3b49beb693297792e733e9f34881eedcd1743cb6a4b6c393e2f1d8925a6a88561e9dd4649442f98e2e829d731d5da4e9086f49c58b7c5006b52305ca9ae61f1891b322494d1ec496f5cc638bdb45ac47cdab839afaa763cbeba64bf742cd17afc771c6f959710ac89675a253230253369e6347f279e7d65b75e039f623efe8db423ee88e4a2f7558a78ff00752f5cdb98d243df3ccfbc16939e7397a9dc8fc6d6790a3d61887d039994c59160b7b1ef6e855aae4d775b4235221872c16abfb3ea2263947cda1410635003560f256cea09ef39f779af7ed4891743bc76d6e52607cb50c4c9a2e9f656a3d4b9a5987499f1d671d2ab499d7c33ad2ca55fdf3ea9f6747f9d448791399ffb9e756237d1edfbb4e64864426a8e3d440c781643e43ead933d7d14cded2f14f8749fff9d4a15292063a3b29ce05584fd2f113e25c00cae35cc00724fb5a1885f2eb9d9207a43a2a7b75cdebe179de9d5b0dfad41f52e79b7b7ae5aa5dd28744e6d32c93568b3686e0b431c0d2980171a5568772ceb891ac4bef87d2cbea75bec20e7f847521c6c9a8c809d5eaeaf4ba8aee30c2b5b4fdaa6ee6886b59affac5b564b68b9c106f3443ed7ecd49c76ca9ce85181e484264d4d269979a3ac21f9f8cc345e05edb1e904e7d721ee03e4aa1189a9f9e632309a12e6475d0d4313d47063fb707aa164daf8ffb8b76459b52830e94d6907d8475318396c36baea189bd8d8fb02e5e5cbc89e29a438402d10b0e1c22d605c7f533a5cad70646cecfb14bec494c1bb43a9f3ba9e968fab7933e9f47d2e74eaa3b692791ad6ebac49c5e5d576ac9175dddadd48a1448033d040a54dd933c4f6afa76d2e7dbb7938c2850f56d9f0957a65c20c5c94d9229d2a5e40a2ccd9b335e78934525a82002092466de7021442bcb9c2cf9cc937345b610ab90628a3c430a1253e23831458a04134d90830e535e53b250401a4152cc4c29228ec932650052a66821d74434ce4833229b23809003c31429924a2c634a97292829d32849166301cc8c561821f114728cadc0f4a834618e3115dc7c74ef3df933632a2cc59abc900685c55634860a48c4548042a8688cab02102a54114368882e7260d852e0e45ed182164513274aa0c296244c8050a28649d3929a18131b6aad456a543982aefd186302e5c320ac432c852d5200b324968219cd7be3051325bff33196421ba13454fc146d219441996ce3636c89171c2cfc31b644cb872c99468dd647e561d040022742a8b0254b09bc2f9a28824a0d66e2201147878985ce732384e6e98c0c0d0a3635d73b038df631b6a4c9e9d6186d8e20a12ed46031440b478a283384078028c2cb9614b668fa218c1dd379660cf11589cefb185b42650517624b8e3019a3052ed0acc045fe186322f3ddc718d31239e854b1798929598a257121a6e449111a9e8f31a61e3efb1863aae295e1b6888b1b2c530d6f634c528ad04429a594524a4d4a29a594524aada34ae06aad95d24a9b655266d2da5ac29d5a5213e01c387c52d64dad9a46a94629a59452ed6ad56dcd649b2a19ca4b974c1428ec389f1e242936a0fa740bd01dd86718dd681edbe8ed5ea754d3e48b6a6d67b6c62228f2119d32e0f813cee873871c662046c76f78060ff871eae33400db6974f20ac43c21e439e7dcc7397523ba43ab9cbad4121bb0e3d439a03b809c7a087407cba99b407710c0e900e495a9636345271a4a2ceea15be0a1d08712cae69a16222444e8b16f5b2e417ba4ac08965553870da78e6de850beb0f50a4229a6884cbe1c101949adeaacb3b143bb8968afedac5369961eb280085b4a27c9d78e4e16b9849667da4837120e0134073a0401fc68498502490f80965b2890f42d5d7ba44016dcf0b9f2d2574f38d4fcf8a438981c983a3226513401c6c78f8eb34c4a39e79c734a4d66b34adebc02f7f1508ac932d63975d9e686d3cca51ac9e6a97390edcc8ba0c8210e1c2111ede5936433592f6d424e9a2ce9d2372da14c96f4aba59bc9823359d26f4826e944ba7919ddda2c9b73ce3967b62b9c972e259ba228f21ce1a798acd433412762121b0c4c20e941a6c097ee586ad23c8c668ee68ea309c4010592ee814243fe75ba4ed6c7c96be5f3ecdb9eb6b186102f907e0255c273522175ccd8b9e72a11620392e205d2439610063a5fe9eb3e3491b418fb1b72f0a13cce1d3ebec3737b3cd21d007015e819e8e19d40aa7d43c709d4b36be838593c3b54fdddd961fdeb413a3bf4f98bda71b2baeae9f0db4284aea7bb6d34592bed928cf409347d1689d134362f7b66063313c56499d164d51863bcf129c864511c705413c9587b79443558d33eb05b1ddd148dc99ca379ebd7359d3a435b984eb4ac2896c33b75d03a3fe8928ba4c8a174b2f9ac6f47a8dc7463c2171c5a78dd973aa6e2042a419b4ea240aab5d64a3d20f448f76a38e60e94671e33576599b3b20ca5e304ba38febad769d5645dc7fa47df09743d84c7126f22f6b1739b355997db3e59f36e4ddbd7d2dd512c7009f69168c7c56d0f4d8c31c618eb30e8ef646d9bedacd78bf1dda13fce792b0a933d68eab89f4f17ca204f16fe743759d8b147ec9d754e677b7735092a43e64a7767ae599bb9cd9c4a0ce68f2b8b9cc8954791135d77efbd40cb9c522f587afc4152e5636c09cb87e047cff13176e48c8fde8fecf702721cc23986c839af1590807d337bb3d4645d0fafdbdbdd7bef66b78d007712d4c45a6badf52226d9c77f5838b24931086a820f8024cf8fb1244e5e7afc36f84933c7318644cb4b1caf8ce3679571aaa6ff8c209ffab6225973cc8cb2cb54fa9a7775f5509a3d2a9722cfa581af4e75b89fd2e9d3358f47dd3bb7802fc0912f36409ece15e0880ff15b1c2fb0452964fcd6ba1106acd3492b5046529424b308706f7640c83dddc145202e5e80a3a80439c4f1d47104e510ca600079ba2402f7902f804c9de7de9c553f5d70f500e4a5264b8b98f27430b887bcdbce9a67ab797dbb77facf25826bd6e56adf8aa6f3f455b655b40849b6fbfacc0247a969d62bcab24ed3b43b71c0315ed405aa8099acf85decc8d3cb2ffa2187f9bd266247d4481224a59101597a8c1d51f35272c16e010024e823bee6f1c7f3215ff38a5a59aff1367e65b794725bb92eefbe91979a668c3e34d7e0ed9389f02ac71bb5d65a6badd57fa4d711e44b973ea59cb4822025b887fce899d3386de4a5a66a7da969ee24deeae60232d7f465ca34fe642a6055f621bf2747adc60f4fea003b3af74615ea68c60834773e00f879397acc709763c55c5e6a9aaec2716a30fdcebd9d202503f0cdb1e22ccb3c4f56e6a14a173549c9afeeb34eaa65eb4b4dd47d26c11df5e83e3f9345dd27ab88490e7d9e5297d3ebdc56321f9ab6ee2c0719c1455eb2cd3bb887fc9a698e35c9eb630cc91312279b79368bb2e4e97604f9999f7162c2e6ad683e34a58e31245a3e7ada9e79a989bae64333cb8f626203a20e89cadc7ee671b0cc1fce4b4d7227f1d69d0b98bed4143d89b79aa4471d73ce39679c3fb7e7a3d24c4a2d947e17a150d444deb98c7c21060421004865e36eb1c678c154b27236812595a2da513aa79c73e66a5fee1b671938ced891d8c79891337f808f312359fe5e23997a982a613ef5e9fda835697a406464d910505a696a9ef09407d56145fa943e347f969aa427f168a5b6b8ce4dadb5b6084c0ebb9f4560e8f4a2e8480e53d54a3ba668299331c73a6be6144f3ba7239d80688e5012a233a2d3a55acc729752d2d2c598264ab8a0f202194a2ef0d0c51364ecc0041a3e785b82a24c771b7efabd1f63469e04259155bb199d48f4408394131c41860b4dad50f54656c876e88e38b3c60c21b0d032822a53b4543ed4c8116cadc734de7abd73dece34574b7d8ca190460ab637568dc65e4eb0394f28f5c0248d3170b21013c3a2049fc5504042005a945690c28c355f6448c20a238a5e417cf73186c20e643045e18954218ca1b0f4d1bf8fb1579b975e27d39cd3f3212fd53ee20f9173648cbdd0c45e62ca604ab59deca8c4ed74953d0c992a1a091080008314002020100a070422a158401e51b5b0ed0114000b91aa3e6a4614899220875114045110429031841062003004110308ddd4196848475aa04346e6d0a02964d2416e3a48eaa3114b3c332d0dd54e4a0b82d4a039c7203b236eea7808c2671cb37707897ab4dc48c0b74604e8cbd347b869126d39ad4c9a25cadc3a4a3fb20bba712915c5907369a399cc0cc7373a76ef0e92f469dc5d318d0f0d3a25ee1cebe928373888d04b0bb1c52c19694b0adce2787a7718d28d26e89291b969a01533ede0160ebde2408f8e6fe7a0671cebe978a3e31e1d434f0749b7344e5f46e2a4811e71996a24ba2422d6e671234442c75e2db46233694b1097cb230831c83e8bdae9b1a3e5b45c236432644d99a8c61cfcb10583a2f5ff495f37fc62414e69b1fe128c30d3564dde2e9c2a6dbb916003c0da62590bc5d6e2ae9ddb639e83436e930cfa1eae990f10a859a6f741fe3e66ec57882b0b7fee9290d97ce6379f49b4af779d5892c4864b8af68cbd59a4aca8f086372387f6919df163c6f332319a7011b2a425d05d45024de8c92991f63af5061dcd6480c80a32cb44a0b6df7973f3ecbccebed66cbf1614651e6ec6d3d186fcde6ea8fb15ac67efe27cc2433f48e330015fed674d85056207bc0381b4dfc4338cc0fdd445d904e9987281f78bfa9e93f6de8d12b14c6e2fd2c175edfd370f556202357bd0b8665d9d50e1346b5b4550f05395ce39b2e44b5a047f4da46d0794706c49943887262d42a37eaf1c500fae87e796d1ac027df39a03697fb1c669ab2f1fd12e015ad2b720388bbd4a8f3f47b7094d8f68e271da274c02396c0243cf6ada86aea7d6ce757d13034066df74ce68f1faa34e181fbcead5ee32bcc7a8acf982b7b6e87a91bf6709c900b18f89224a4634dbed96d3453e4d2a8bb7b27dc8855464e5c13ba49c40ac5c9b37d7779e1e92c1adfe4c900465403a7c5f3b60a74765e1011b4ce0cccbb4020c58ee2019c15743b993b297a4cd8689273f8fc850b0d4fe9448c03442a2de40dc96c35b89045ce3b485d4c475b05f703a050b765466c2059b5f485fdb57e07ceac3f0db3cc9fb4c056e511226cf4f11ab5cb5bb9fdb55648115fb391eeec5aa37c59f214e08ab342d97f6d7cb5c6a9edb0c333ece03d6add53ec153a19af47788f53266788bbd6a1d19b812a121f6d006495f4ed1d3f36a09b42a919ac575f09ee2588eb0090d92733ef28dd6bd13d40e5887aad52f3969bb7bfa2f9b14ca21b5873fc6bb775f2ebdd09d59a9b4820515c1a16d30ac24f7a9f25ff0dea765b257efe9dbdeee5d308628dad008e3b15a4148a01a90d273401e4860e0d9e223a5e5b1f7138fd9bafac6dea98bdb051c8047ede4c331c461c5d12b3398cc8761fe50c2c9c286aa5d209e7bc08b8101835bfd633cf5ea20d67e0342675fb45dd6b2155df9448c76cfaea0620a35abd63c3f22c1506d003f3442e815e8c727cf3cf893d1618e669ae144c230a218ae8079e46f98bf47fab03f751b49186951e75184d2fe1769e388336c5b763168ffcc7d436811d04f49c70d78c3f447a6ea44a309d414353d5cdf5d0f8d5bb72f38a430fcaecff4e686fad995bbd444e8e444b43096c6a803cfb9126329e360d87b25d6d9cb5896fd07f1eec41d13656f7703a530701f70499c0bb23e815e7018e46fbbc1f95fb129e9886443e7c6412f22541ff9a713e1ca4ffab81d261b0f3ff3bb42969bebfdb9ad60dcaa6801b0ac2bc2ddf54965f40e3bd7629cce327e5a607cc0f2bb0ff1957de2093a524c7199f9112c3d220b302b8046e4a8dea51622d9dbb0e83f95e42b8a9da43d645b4a5b49182eea84cc7f95393e06ffebdd4f0a2f8d20d3e24234051ddaf91783c5b170b3b0df5dc123a49551b4a2a3fe7a5f8e8e1d2df6874d306c47bcef399ce616f7d825a492226a89523bf5007bc6992611fc003472a794102442c0a59a6dfe7605b6ed3b3be61da126441eac9b8f6e43cf72d319f2e00e0064132388b11235713d68e2d0f0991b31f2f3142a61f860c5607c409c309f1c7de9f3e6e60f7763ab90ab2f72128a2109e25f27ed588bf8b5bd0b7e285787f0469335f3910c70e424b8ba10356dc32f5ac6167d48218316906f4e996c3918043e18fa9b67531456de1c63596f3b0e50eae11a620be6247ab10d8bfff0b7aa24c45c74ecffa3c0f9f86de75a0194d1e04d27e156766873d4325cdfde96d2db77ff94d5ce96663e562da39828ab7550c17ea9d28ba627a8ebde0ab216033522c1c14b8c63e05d44d4444b15ad10c89110140fe56a889f30e031daadc1a9575e276f8a61d71bebcb81e351a3afc0f54ed1b416ddbc61c0ac510a988a2c3cf1f63751871e19209688bfaec5b65476daa90fd383cca15f714623047013312d4be0c8d72edd68de079419daaecc64e52193271e3a23f3d5e048f8f5f341f7504cdb2b12251ffa75f2ee8dfd39edc999a9737b8186181a11b068a896c8ef93803b6a0ba87da9ba342141a9e2cf17e36bd1d0deb6c62393131528c25e9c963376f1d5567c011d1b5a3c974a3ab5275c16a38655234db6b491bff6b919112b96459d061b67bd849dcee27135af3e828b8c34c0a7f702e3546ac26b418f589a109450dfed42895996cf93168a40802695fc4f2d6e2369a131bc360cb75c95bcc462659b5c10a48d290024d294c54b3bbaaba064e8700d5faef9bd031c0bac46ffbc8c363ca30943aecf2e4dcc4d89f4f6b84a4382d9dc4d7160c4f697e3e34b0f3a23761aea9cf43d029bf2f5ace4239b4cd7edcbedf22d14954e2c87eea66f704de4ec845cd7b9bd638472b08850f1b331f0f53c02383a54d04335a665d5519d0587dd28f9f9f61a066a2d7a03dd201d499e5d803df561796b32b02baebcbdc50a15bab66db0da763fe101d96971f4518c12a6d1b40def959e569340718f626eb28bf0ad6def27746a5e6acfc903b264820e63e94f375d78a017c7ffece08bb051ac74bfdedc040e402619d4527382f05209bb649e5f740c15792858af8e33d30ea147fdc07c8ae6657173734c0b264433080a4ce26bb3cbd7ef7eeaef5766c9782f38b1eb774f9ea9e3e030387255e521278f1c51bbd1bb7a5dd415934793003b62aa1dc43ca5c72f2afa39da1e4018f10435cb443f664c7129ee93bd57446abd495f57d6847b622f1f659c7c56f5ae62ccd39d3cea229ed1fff4700fc7bf1a08bc1a592905b248fee77f8e5c9748b53279f17eaae614cda198c71e15bb46253768205958b169f8e936d1f57964bc6e447fdae3497c4c8b540ada6e3cd21a96ed3c28f64e20db3e18982592cfafa4289d822a40512cda5e5fe9024509179fbce8fdcd85c2e89674798edc04936d5b8debca729dbaedfa3c3c7b0e06961e41714b19c18c22970e9556a30ec669163f9b5ba2d83402ac32cfa1c5be30ea6479c1d7f9684ac90c1bc84665551506e1ba1904e7a229bd2260e310a296a555f317fd1704a0f4324d7178db42e889206a1773471ba8288a414b4c9105ad4c13972fb34c6321c256a5d8e8b53d354bc96bb6090f7cc749a0222879b3f56ed830ed85821fd5977a33e7302fc8de709bc1ffe442b1b095a595717b15a97e9bf7e34d93e19b025976be6e351c86e5315ad08dfb082c25465887468e98a854ee077af2dbb999ae818e0532d076379aeed6c8b3983c2866abd4537d960a75009af078d9981f9f3b5b88d308ea9584f0eadb10eda9881ef01b5392a3a3a3e18d592b9d8c271fb0b86168852af5d3764889e5b46af61a2663f1cbce7fc9b3c1bfd0e1fd41cd65a0b2a960a0cc37f0323ae1841625858117af39f388ac773bc1804ff8c7a52bf2e29737297e249c87475fc16c26edfcfe623692298b19f2da4d456e0317376ebe37b68c15b0286697a9dc5963040415a655e60cb60c35a62bbdd3c72b241b2df063cbb72dcd11d20c59994d9a433dcb3f12f2a20f17ac15e7c15b82f383b3678961094704496ce3fd6e18988f17e85ee3aff946f74babf72181e3260f743b563fc0a6cf7a717d15a5dfde838595ca129d5d186c3d9e3166b3c5a6e0c704812f818c7b2fdf3b3dab6cd093e599e2f4d79919bd6d5411106c4ac2e2aaba36dc9f460f3b461dc74747f783f666d442fc75bd7a454da3e826d0be3152d68dd464caf2c9b6a7f4790852fede4cefc144d9da20bd7c4d88fe1802130002c5746f16e96fe107b74fdc9f8312e2a3413d41ee6c42c5236907a06bc2df01ffcc91e3ffec58ed6a3dd9df82aaa7e81ac9b41a04335a4fb6aa7ffd9f40aa85ff06b3f692831a49cefef7ebd27320221efaba069a0a36d44f3373814331e188e2586c940a8b58b314dd7571ccdea00c42a16865aa9a7d149aaef405e82c689500525d063ea7b2bb2fb7d98b9fdef637594ef0aa123beeef7277e2bee8cc919ab9d0a7ba7b45a8b65cf734238614ac881cbc3709cb68dc066c0fee3ae02ceaa93bed500f671c1976e9156167103e8e0a18a8f39b9c1bc38b3dd8af353582995deb568c9ad2a8df44554d9924002a791e7de8ccef2dc219778513c4ef0b8cf8619cf4221685c2692f6aa82c8b249ac0a2502f79912ba47b735c7bc306f9a9d7431bf22ade854f19a5695ceb376de3353c54df37074b2f353df366b34b4fc78f319b5c5ae565d0e40ef21251f94082d6398070d3e895ba62e624803c56b4245ef6ba3ea3602daf70be38a64a21e1443cb678d27a2c142829cab825c55cc7c63c003d6a1b3d63abd1f288cfab01c86903932ee8a5433357663f154c374b2a253af08df50cc71ef1f9963ba24daab508bc7205b3f4acb6ff8482e2fa10141077281f7f11f9ae5bcdadf21e73b30e851a6666449f556e19945b9123cacffd0fbe83722ec0ebf3e6ee947e87fc1c9fc34e8cac9cb7de278e241a8dd1fcc69b4c5d895fddba9a95f0ed1e0127c28215f61f3a6293834569a30e265c10c51a13dc40dd64bcc06c8df42a446051220f11789a0cfc2ee550d0ddeb89f6073e022444be21b0075bf151ce007de4e283e7e060cd2fc2aadf2245e6ee6efb1fc4b1cd650e24f8db0ac28feaa9b84a593d94d3b0ccd0e31f376ab8be494586f04ca50d55b69e4811ad54cb16e609a441a91105cb06a878098300361082c7a3ab14d15af1300893309311c74bc741a599e9d4ef277aaf98867082f419d8bdef642342f5e51a2ac75b46ef37cde7c44c292d27e982481917f869521b225a5bcb45d5c87e4ac272f644ea4bed69607cc16e6bd8c897579fcffef8e5239398c2f86b5824d53a0847560e58d39785cd23bcf8ece94ab4084510d1bd3101455e597f12bcfcacb9b3508bf00aa4c7fab2d0f72f044db8cdc3d3d817e6408afc4a69b2f6af13c171b84ff00a6caa6451c478d1748a9b3a9b82e2200105a5f28584024c43698b85b08933a2210ddbb7b033e2da46bc7b125a8f9cd1c94502b1a30203ec713aa9b83fba7ed000af2012b2199094ba8de08e52cd120fd7982ad274a4b8d054bfe014e050530dc4d463af707c64b8cf4a21bc7b90e6bc40bbee1178c725b2149821e1eb90181ae2fb8aa72725109de8f500c72631242094933649b405215650d514081ec4dd2826ffd8a2a519525d2a2ebce1b1cbb273fcccb26bc1290e3389d18c4f88e369300825f70dfb4525b2429e0282e5adf86882bcde7f60f4144c3ebe73d54d033358bfdd7fc6ab0323ca9ad4eb1a3ab7c74a5dbfeb04e9de2c597bf0a0bc6c3f222183a9c2a086837508180e3d524cd455948ac93a639859398cd21b332b16ce2181bfc3cec321ae67ffc0f8c3efee3478091e89dc46af93247a2e185686b7d12f09e2841e75e4530bc57cda750a4e84d100b29ff047036189ca5fc86348e588c92c2bbb28f6e5123b668ba1b5844603b08ac529803788c18d0d2e869c5056b29708989248d494d4b6fe20ea1a9742a9d90f07fa9140679c5b862ec1c1120828a6d28916fa650639847b2ef4a3fe436ad5dc15960989876eb29d4c021c0d775a11925915f0d57061f5d61a5cc935106810dbd817abbb418bae6abec1043506df9371d33f574c56eb41aff228b73455f6db1ff2490b55c699f88040073428620de0034e2064c229753b1c185f67ebda092df9190dd1e983eb4f0ff814839c0a8fac6147c8f2666bb592a3bd2ff297eb915409ed0be182d44fcc1353149fc62b5851b4d017c6541ef18aa5e5f6e5fe2eec8f9c40056034531581c5ca49cb83bb0ba2b4c488f7b3476da19e5bd2ab04b6b59570a75d806abf8467374f6dce0e9b1d479d6d39db8e7d2ec1bff9f6fecc49604ac3facfff6ee1da02086789cd9a545cc783b6e7124d3f01a730ea62382f89e078af40297046ced302f04012bdde2a73814e6ecf6049a1aa7e5d1edcad2a4f9a80082646c5d79477f2d35b28013a55e3cab908e505a7090ae486981b863056a303b911bf28baef5e30f1f0f76f2770c7a19751f9bd76be2b9abf604a5b37b01ee1f63345059a094b2bdabd4849db9db6bc4d62bf3eb8c41d8493c57c4cbd018b4ddca19b2b7c2471b8e1e30bb1e267277ce8f7dd9f63806753224593c3834682e94625894dae5100f457cb5a554a766787b5f8add37614c7fd424bea617b03c7f542cf52f0d980868bcc76fe7e907cdb30e2297725a6da77ae8d8ffaa00ea322add32633cbb53816e8e72d7821f470835a99d1f6258d6f4ee73661e08e0f141abd41af663566b9098ae9d3974792a45c79611039ec4983d52dd33952515c1df684e0f474648c9b6df72de3664e61cfa04d018aad76a7c14c6f301b3b9a301fb7884a5ad8c8f654b09275b7a2071400ce967c84db5cabaf98a950d7b0629f274484cead6236bb7c2d62974fba67840547fe735a8e74690691909b016c538791aaecf1110595088615de4c08b0eeaccf3e2456355087f95c542eec793f8ef6379de2782e015abf835196e25b8f1954a931d58a5a13d3d70920b9facea2e36362144df468f0e9d38b9502f9f94d0e0b18a5c8b0455d8cf03c9b61a19edce72cf3bd6861a78166a4c2c2506aee78a01a589ec283cb28430e0e1dc057b01d1b7fce9e891af1395a8e27a36c0a85fc7f21e3ec3948068dadf782ef3d2efa2dbbeb6e6c4a6627c5fc233408b9de440eb94a8b05f8d46b9b01a175b2ae9a6b3b77426078f0a70edc0ea8ac101d7f15f69d80acc39499aa32a45c15e1953020ee39e4643690c7ef15c081de62d07d814c13ecb5dcc10aea2445dec791662b9f4a3452142f1247c95be69a9899337c99f56e10577966c57cd5e1a18634c126b04dd6d70cf6d5386fb1d41120c3404bf6c4aa690a27730f31a5ce69dfb3df9b54a002028d7e747c8706b1762b2fa53d5ccb835abd43c7aaf003dce2d8591c80ba0d0a85e8c16113f5662a1141ca3beaf4127bed23ea8d1dc7cae0527d9f22139e41bfba1d9460e887a3cea1c58369a5c3e8c803b9a44526d3006891387fcdcfb84bbe29bc31b4effe3b5998f9c6be9d49ac30200ed1f0f1d709063db35defacf189ea8f1f1d6e62f2c976e49a40915278c7ba50c4d358eba14daff8c4f3a15c4a3c957e66f406cfbf45c82245d08772d6d2b5c9a595d73e0c27239280f3b362a41f328e3244764b4498a93cc7c618e76eaea09bb08b6679fb9ce55e64de1fbe29c0471f536f0eee461bc30b1c5a1ad99f97a6ec0d1f9e83297436a43f1fd29c5b2712433c69dd63ad19080cce9c58229c2c84815207e77cf43a0656af3e687509c3e8b12fdd64a61200f1dbea9a65fbfd31560c9b08c7502458205bb73c47ebf0cec3b8f3d51b8be243fd0158a0821bc4f8eda48db3e583cd99aa3a01fc2c60c82f0665067a6af8e4dbb4192d1eb00e2e5093d0ddf4fe8af0c737817801bd2ea8d5a62b276a50aada5e9c7fc87fffdbbff60bfcf5187bbf0ae7adeaa8daf148da1850ebe83258add429c938b4bee5bdfb44ec237a293850facf0c3b35ca7f5e5ac3f35047c67e5032383b0ada32b20bc6466513330ca9c73d323bcf463a26d64452bf16f0778f2dbba3afa40b5d4a0e039961608847368ed851bb6b65a3627d78a806336b2962ed5fd195871da7942f26d7c05ad188637d90976626276f0a86bc3865181c28e626d8061773bb9b22a11f542f54fdbc626c4f53784994705ad50207b9af7f78d2e145b7c071752b1607cdf23bcd058e96b8b86058af5c148158b8ebfdec7d095834ae16c95a913261203ae4420872801684d16aae59ad138d1fe0d89882b9d3a3f32ec5363b78bcba54deae7da56c97b7101c1119f1525d685cc5e1d19a6ccf53e99697e46f99fe268b61537685e9cef8f3d1aa9a5d5b8e173f681c5830bff6cd283a86c5f18b35d4a6e1849198528e6ca2f9c0416ff38db6d424f88440ad6a788c040b87f5400f3d46e4b6f3628f6fbc622d70e48b8ecda8b304a0b2a9628e01ab19410ba2055da429dabde55efbc07bac25eb83e938280739e8b4c173ab5c44f3d826ec6abcc639d0f63703e4666a386544ec2b0dd0003ebcb8983d82b688d435b126247f647a2561a46df0ff3cb718cbefe07fbd67ad29718c6a13d3a0ba9250ce3172bbf1f42a38e74098334ffbfc8630049c9f2b49dc29f32d9e141fd2b5d150c0954eec582c047f52763bd2d404ca952ee038adff183c537e95898a9d67d3d8a2ef0ffc8276b0e95f54351287fc6bddbe4a81265e172ad1b5d2a2650a88c812eddf43f70788453862b2440138f0f41e622e4422af1913dda3eb158f63214feec650499b080f29886c4fed7c7b40f64d62925542d71b62443c943838b07e9e03e9463375e86e6b7d8086621cdc8d911cde5fa71ebb0e969420cea12d1056e643623991766af16ce9a2a8eb18277a7f937ac86cb57218c01228fee52839e7c02fa3979624979bf912888a49dac9c999b13f68fc7889ece24d93ca2c935ee0e02a170612fbc73e391c04c36fa146791e768571a8d6e39f45caeee44b7c4c14c24c00b10e3030ce99556ee03cbcd2e5087c04f0c3f8f7921bea9da1dcc2215637e83b8f209d4f2240ddda8a797ff3c7bb0af66ee66e73043625f73865ba87a9bccad3119e53f2fdcd7e37106a9bbabac2331757405131ea62fbe117d2324e7883d3a77c9ef54a311a830b4303fa1b8d457dbbff25f843ceef265c19073d9ea7edde1dec4039e6aaefb75e3e4453c5506b953934f529b83a88ee26ce17577e773a6ba30bcb8621f8c3d9fb9943dda612791a7afc30a21fc4f7f480989952397c39c5287a77688035a2cb4d9073a148f7b47356f77c8c718ae0049cc881640a6e1d99689f737c40ae2ba6e1ac9bc6f2bc64640f764be5c11996d28671ee5880c94a4bc4770a6d77629ce3e0eab8a7ace1163869ddd9f9a049578e394f124a0bff24755ffdf1e785ef465d9f48a500cd509724ee324f0e31de593bd10e185e9e3c67b03b4572bc54f1e1557232dbd32c857978ee030e556c792c99493429c03c528080cc3ddf8febb44c66192305e8c0e0ac889a198e3a3942d311faabf2bd0df82b68466cfd84e3b3fe69cb71ed75573445f1bfa1f4635eb664c646abecd4093952c4fa9129ab04ff84b44cd10341b67c4f56bd4a78054c65a548b89b1d580386bc4b310a3e3eaa2a419ce6e3272ae03cdd763e0190e785ccb42028dc6e85a5a097321048f089b76169e213d77329171de3f48ffa9107f3d495bd639a5f15c572d57b930c64a64a24a6a1ba1f0f4b58ca2aacc050c94263bff8e226172daa322182a46d64c2b2e6009dc1dd0a66894f09a03c88191325a9ccaa10ac9f8c14a649a532514d19d9e76627fd00f6f04a44aa618b7baaa88b2e7cd0e2a1b5fde2f99bc54110ae4cdcb4964bb8ee2127e27bbbd10a3e28894942e465a8e20f0caa3323de84f31c49dc95c986d2de343af96514b4b09b75d4f859bdf02aa439ba67a1c30a4a38b1629c76138c91485c9836cf6afbd71a39bfd1ecd9414cfa1f16fe5017d7a2be0204b6eb736dcd09c0c0726d42f9c48dab672ade064e6787850286147ce06881f0a882312a3a53adda882e64891338b6d21818f1c04ec8b5c6ccca14cf873b43199a8de7b282a418e785f085dfa22e093896c43e64f1a88fe2ad09afbbaaf7942655dbd4c8d55cef2b30e2527020580cb2dd8aca10178f9bd84870fb081721c8dc7af960c529463fa65e7fb339b0a7841a567a3b2023ff021fac3a5bfc548c0c105008c78ff29181ce6115383e0d314be1272b511087f4410eb0a8fcba55181c1271ea7412213cb564924487412bd83ecfe2a657f3f0bfa381f220d0c860e26442e69e4dc3b2e75fddd975911e78a2a8f918e2a1aa76b591d1fb6855968f32c57b154c478d096a1bb12324583b0874422171bc0f7e54fb27b15855430a04658f939fd05fbeb687b4eb47f92dfb685d980d59c8a97b6cefb84591c8d3b3b02139118d2e7397a3599698a96afcbbb12cefc2fadcbdf462d2f5cde2bbb404a48b3daae284dfd9765611ee6f699f8a640272369bdf6921f24a4bc4ad5f607b1859e0dd4ea8512a95d7123bb5b0b9c6f4a5da63c3f740049d0f78f8839ad2a150a6f2a10fd9c54de22a8874087f56ada5ca6beab0ea0b00f9551094d4b057464bc85b0ead0b43750d55845b8586ea56b9ed07581f5dec449aa9562b1b75080a7861f300413ee72e5a0579e072000cb3f7b6f345518860f5fcd3334520bb3afdd7f0d2444fdec1e0d49e4a5411bd1f22ca39264f5d0ac1aeb3dffd12c77484a9a0ce31c095a0f704e5a3ae965b976f9de968f99a5dd149ee9f8a497fe90f33dd7f7f300c55a92c4a436aa32ab40295e781fa9c15154e85b7705ff70616e1f4f0076200cb76d096e601d9d54cb25421facf390fe9318a3286dab12633a22c6ac9b08e3b6183aab53870f7203fcc07d18d42bbf4e8652e6e88287b0c38a1049f7765146a9c874d5e5c8d434ee4843d8775f1f5c941923b50fa85cb8dff607bb54f3760b5ab2a7828d0aab482a16a77755b55556073c959d3fd31608418acc129ba0162c99410eaf0c1a6f8ffcc1c619d55888961a25f52080c9b41570be2eecf0fb5048c7a95c8f55215a82f94f962a92fc18545bbb9d80e12c5a897139749ab4763a3d352dbef696d2a8428413f2780d6b5d9b810724d2c88ebd94bbadc6251e007043ac327ca9b19c21c9910e0e40a71eb53823fb0daca5b3479afce9340dcccaca4faa47e83c04d5d811af27098fc81122cbae542682b30703daec0c5e55417a7130fcc42fa03e221cdf2fc2113293945077503c030488ca7d11c02d6a0b59fe0127fbd4140f607a25b83b184ad06fb4d49998d252a4302e9c5485555d1264ca326fa0a3935e733d2ea220b32c888b44e1e4c4d830d94ce66e5b8d920f4e68c4c87e2ba3d13198c2694fef41dcb879d84f76b5b899f0fdb7d22661a6770c1d6183caeca3a1e9ff58ce4e6fd017c33f333429cdec7b05afa425f72757bba4fe80f3ce4cb40a036a454797aa333e308d3e3165892460a6703526502709d6bef35b66ba07a299199922a1f55e620374b0bb3f1f9b39dfd5393617596c15f83fefa44959bb929f625e58c264b58bffdc72a9b3e6e82e79196bf07f3d781d95981aeafee0fe341aa46253709fea5bf0cc225c728e259a5a76cb5dae371c3ed66f2e7f94370340451f6914c5e3b6fff6993876f108ef1e51331fc50e474f96244eb5cfceb593a12f75b9f6b731f5babc50958bf17e8dac6f5cc7e056d8444958e311eb2e095bd8bfba1106bdb986e32b8ce30b45af3f0febbdef1aa9a943b29e0095da95c77bea834ba82d2368478c9f239ceb5971b05e2229cbc1ceba224874f468cd4d3533f13511af3bec0a69e6409ad7102ea4b92e779d6f1bd4eb419f6b8d1c41157ba304fd667c0264018502311eed6880cf00096bc985482febfc104181eac1ad6ce73ea5b8fdc4115284c022a754eaa374564c941395a6a913afa8f262aa9b691077c472a04c0e191d9bfeb0aeec0049608b6c278da3d256d5435940752f460b5c9570ca14c524110bdd3553ff122fc1b25e3e376319beebc37717adb9ce3705a7ed20a98c9fd61409d0176b5058150cb65dcd2d30ace606526b4a492ba46d75cd96c6301eb86faec71a766deaa182a14ec5687ddf80b42b6d51832ff9e520e46bd7c94a875de2abfb5450034dfbcc66fdecfdf40940ed7a8792b9e34acbae3db27fa460bf90d22213dd708284de867f9154ed633f41abb8b8c8044d7caf7e01cd04159e1c6d0ad4da71643e1675ee385c6dd8045a0803cf8d084028ce991d0278fd127fe2e82fd2715cf9e16a651cbbec951c046662344f417fdcdb61f9d5209cc46fe7c5dc3fb10ad9a08e746170b4c41144eec03667683c0009e4619b094bf06c87c7b19f466f820985ef4d3353ef0a79f129f4d40095a9b4862683b38c9e387e010ff41e484e76bf4aef15525c909c990ad2f7293b90a23622d018c256497c91bfa39a112443b5f831899c1242039efec05bcfd87e19005d484691c39f6712f8d4a2743a51cb04b7fbdd19ca0dbe0d11c8975828bbae3d0cff4a417440b8c35a180361361c3833fceadb558a37c0c379700120f113ce70812d426b80cb52a2071df559f4d6faa4c67c2dd36afe6b08a829825f4329a3d61db08f41a2bcde7f8a1512a85a001c314d776d49d4a6a00af1d4afe5ef8caa729d3bbc907b421c16901d78228889f07cd4043a4b087555a579f7a84d45a64e3e3b708321f861d42599b03a2006fe912242ff9ce5caa23118795dd6e0930773bda3be8fa8e1095383ae0111f95674ee5781a652ce963c2cef8db6bb02ce04d733809f65b855d90440ede3eb517d931d05e66ecb8274265922642a43120311ed21cc401587a2c1a6a42b64658bc33340445ac4c43017643398423f0cd2c579e62438edc54dae8e013eb6c9ed611b527f677d98cffd1314574add5d3f4e0cc8c923159d4da323bf42564a6863cc0165e126b4b718a286a1ec06154fc201b35aded917b25493fedff1b31270d83101721732c228010bebe3627be325ed4d71d9b971fd11291a4f9514d40af7f04ac5be20fecf4c01ed2844a494018872d941a03964a07d9aad65b1fa09f9305c6b40f868d5501f9a68708644b1b7dd6b67641545a16c8413924252dfd541dabdb8c293ed3da35eba12dd931be6e6bf98f6e353e99e9161ceb3ef240359d16cc32f1f8aef86526a6a92056709a0cd44eb89926c57ba89ff26e1679e411fb25422aa08a45a519a7d25536c643a5a95d0122a8822e34c3139181b41b8103912ae3ba10d9f644082b38515d727032f13cbdbb83b35f0592beba09f84f3ed5f72bb8f6237444c2cc3f867ed81983c127360167509aa32cd13f23225d672046229978b2c35dd61759fc1243d4b97b097642fa3d66e94580e73f07ed9469ff321b6ca6d517d90164a2643632033f661d384f10225ced0189214fe723387780355b5168b86ff263ad56bb77686169e24af8c73b250ec690c9e1f1bb4e79b3e84ea82b6c23fbc09617296d982093b90f9d49aaae4d1b52d1ecccf667221338f44eb124a7b5721406f420a0699376723ea13cc2fce062486d9e3c2bc223848dc8bd85ce2f46221a1ff19d9d3add31010c84f3dc4617a0d3ccb8369cf0c726c323f148e4a4d00c5b06e77a4286e9c189db81a31286f27c8e6ef0172b68630b944f9454a22846d40ce9d7b02182effef2c3b605939363b6c841daf9f6281b4aa088fae051323bd39bb88f78caae5714a90c16b92540204c93bf0c341ad9f8b57cf00494c714efc5bfdb39c648a2b491d5946c6f515c5e4123a9272f97480980fec7a2bddef53dc24fb86bf76af7fbdd8447162c03da63b919905f71930240d12c673a5c8bc18ef888c08890e8a80397023ea26cae1c7c2b23285b0a6fc2c5ddcc01b6754fdbfa80acd514bc144b5cda665fad0f41d7323d0b2e25eb88e1eb17ddf1c0621066f04349848d01d932acf583ba0599fc8e12863fd0dccb103ba294f8767da3429566b1541c230b7c3533e5a8f62c24844893b0b719550f778a97768a0f4758afa115e193e8ffa337cc37c519b3d207ad887ef92fe7f8b618f892fe79e836909626f12373f01dc0724520790fea3c358dc5dae0e4fe46cbe9aa43439e0a072f0e86d969b95210548428191636d5ba95da6836291d80a947836ab4a39afde001706dcad525605b531e0c9756543db96743dec63b78c56c3a92b6b57123df8142c73ef4f13408e70e2711b943bb91546f2168d11d7990198f35360f5a48401ede8c971ba8e47583e8a3e240ea7be7f9ef71100c314aa5d2f251bc190d34d6f86ebb528209c16e378533359f25985e5a23c8a846a2a5b728e1abd12d84e9f55a4efbbb40a8a3a9152b6f86587ec0cb4a1f3148f6ec934ea41a4fd8e11dae7beb0ea512dceaec47c4846873cd9a44c260171a9812ee8253c7bd3efade0d0198b03798125e7e0fbeb0672531cdf3c3162ef92a17a46ca97c74ff3cf3152d98e2e767e6b405a5ca5b0b6980a3ee4f1601958d629e5511a4851655ef29edc0795369e0f1d9efbffc83e047d2e55fdc3dfaa8390481f230ed9ab39e3eca8f0d620504ff353add50d2a7daa5ed02bfb7e5e61f18db03b2eb8ad7af04362350b1ca26cce2028ff6b8a2796ff9ec54666a2df80da961f6c7d9210cac4469564292c38b9e8a7aa57f5f66ebdbf8a542227b480fafcd55f7a262690343c9079d47d2141ddff2787bf1ceb4a97e3bd32c2234409f6b14cb0a606c2ec6122c393b7ab1d07d115c3f38b804da869501d70fba72837376fac48d70c8eef41d7daaaada9e21fe5b3e258a71bb34da4186a993d5cd980f7e43ebe8c83b1c700c5b91c7ba0f35c4ae80b63d5fe14b2016b290496d64cbf18776cafe72663aad6e6ab3277f1079002e31d10998928d09267b2cb739a86cd2472a2364c509ac1e6b7b7edada6830c2ddef676c9966d03b48da3f0f4f3100a3b81d4f865273b6db7ff59a053a621808d90f03505a09a7fbbddefe13d9a5b63879aa4b28fa416db14e79210cf56080bfebed8ac1114b72e85803b60b2a095685f610508016ffc180864113d63559aadec101312613979a534a53d3a231d14bf8079b249cce2a083b901656f1cd658b3386f344bba04a9390690f077bf6ae3a718b2a6af1303ffa0d89a91942982b4343a16754934b152b6826347048c768a8730f20bd9afbd0dc8b170985e6de69694956a860432bf1a4b3654f4312036764651c7d7da8f1cd29a80060ca182c7760aa4292d6abc857b8be6a7917c4c5d2a32d306dd776bfdfa8a5eb457bfe8a72c98d54124cf72d3afc50da204f4a3fcfdba4d2181362979f6a25a090cf7a0b736e85de272c308b92307dd3ff84877ba300067a96520c67e5dfc3f0a47f2bbd96132c04bb8a24502b154122e859cc28337ca3a504beb0992c8c98e2156d8044f6b858ee1a1a0a18fba08059c4b33f49dae45e5f0416d3ee892cbb29e4d1cabea1ff6083a61b462717633ee629be6b2afed2d4ca97a7ebc0f4f4e0c958f372162866ee3036af138ba0caa6b47768264280e5994db1873a2fd773f50d6d5ea53cfe26a13d9d213bb5e0d970d84949d25589af309a4495f4c616275144fd46d1bb2e149f6a6cd4d27d127c1630d33ccab6a94b65260051536ddfdd9dfedabca84cc0a2e69d1e101262f7cfd76551e281a3a169c8e824ede641827625efa83eb94408f9ed82913c5e2024af570100f832db65dc94c1391e6c8ab9d53ea0da20942a7fa301d0cfa51f8c9a2e211f577acce290f68975d6b3cd979cddb1a9bbb115ec1a1626b559d2a1901f748a51efacfe2614ed7d3e82e7ca2b8b65e9056df096fc89ad118e695698d40b3f12063f89cbfbda71d9696201ed21ccea3bc5f603ea827e66e5c95929dbebb48966c026880d7c712c4709b88ff554e7228833173b2fd3b76f522612e19f9481cc6078e99540547a32754d2103ac49dfeb475fe6d43b99c4e54a97a4bced2ba7f39731a04b6469339fc7ee3cba4d522c37dbe19240e5b93a598d803c05d5881482d3ff09de280af99be658281b0d0a9d712e11348fa8ef3a6a03de717e884f74f1c8132d7835b75171958d8f66ffa773117e2493ae30b537db46e86089b5bfa94521e27138a7c96b0a13a552569bab9d7d4b3fbeba2cb6f2355a49fb5487639beca570a502c66fbdff2b3f5a6ad0a75fecdb842b96b39e8b0829f600463718725ada5d69510cd53cf09b346bdee5d188f7b4eb3e44717e5d47d3e5641532568e9539f74044690f7362a93a4493b2d174e3de177a151f2d6d3d0b5f4749b1cb6e1fe3c09e860e7b5741c99ff32f3db9093daed2991bd70a59d2cf5118b56b729011e0e357ae4ea40d002f787e39817001bb88c319d92d8ca57645ef3ca6fc17ca8a7bbadddeac3be907ecc77f24fe0e8c8e1f8558dc9ed683bc9580b331176531d87cb76e02cd9a89953c7951c6fa47b0dde41f4d8539d7752db99cbc81333b6999ae562cc292a578e6c37c09a0c9394c95c0197bd6aae582638af08c9bdefe5d1e58120b642675ea04e1913d2d800483452a1f8f0a738160d020d56ac71bafeae0ab6c08b234baf5d2eeaecb1bfebd64f4722517d075127f2fda4f6530b8483ad9630b68ea826765a96204060a0f3c4ad8c4847e9706af00b13ed7d3dc40b539eae3400a969ed73b1508a056b36fd4d30edf9249c2c0fda21e7d62be24a01290c02c8453cda8c98ba327506bbcf4769841da024536c7e93750e3f512fde1dff623cc175b7f03c82577f4775e50c4e430571e0c0010046cee780426075a3b387279a03841e3c5c5b13d01d90c89c1ebb43772579c881511a2170e64269987be568494e9b02f9c78df92ae491ecce2072809dc08a04b32a0629e5a5c208424e0414cbe722bad9c984bb7dd011e124fa9a08ca142a5a166569a5ebb3019d75d46856dab93521f5fe43068a9a4102c0e2033d54438ffc08c14cd93d1ddef82e835bf4a84abfce0fad0bed7ee434ddc21f12bba44b90c54b5cfa827da1dda7c6bd43ffc9064a8b1f0e50307d3d28889931c21190742072df297a3025449293fc3a795354da846728f27bc8f4d7c16ef13e50570f03328f4109c02609470a3643be206d601a5075735406bdcb15aba2ed9bde334e967e051711d71980430876ef80c8446c968da3396b14065ca32e0f6dd9f2d994995fbf7874958938975c2a8d14677340d1815a1e59231c6db37189adb0dc10d09f853c97fc4244a890ca2aa9fa779fb1996ddd4cca811020a75d1adbe7b680631f49a5fc4b2ae9895e9ed23dd6c15ffe836ade3d71902346398bc4724f4803d8cb7d6b2ac954931d29e84024dd1fc415161288789f7a2801fee5ecff6f0450a1c8863976884237600e2e7acaca69a46aeb08840cc1ce1d0507ee246afe88abc8fb9f40cd3136789e9fe5144a80663b4d4952046fc4b2c3ad4c9b67398080fb795cab3fdcf674cd74265b08141e3219ade141a951983d82ecfb3ca685e0876b7c1b97bd177134cc25c049b25737cd36965a20d0b06f92339f64139648bdd8e676af01695e0746973e762610efb4ca944386ea4c7a157edd8fb65843c8267596e938540efab57b3d90660c6cbb663309b777cc5e338b788469aed12294fab9387c4923a5e8f1308f4a401137872d5d3e6a7a9ec5c68df56152f618cba360e4371ae140785a04c8ec8af9a090b7c57fded052af15a2e02d7e8263dd565707082bd31e8b5b43d53ccfeae12cd987b8395b93146017220a31cea8fcb7ea878065350b1ceaf86f251650bf156dde21900314e13991fdec74ccdbfe761432415222daa3a7480f00758a2a0f2e54eb891a02a42741c90352deef199ffd87dec06bae1dbbbdcb193812707bd05b63f7977e40b4766aa04ca254398c001e461eefa505021392aed384ae57252495d851f51ab176c4684af3aa93312f9e7d3ea7a5e12421efd12687773147341e53547930e83f37080c760be8ed21d49c5267dcc48c117c278c3a7e2f4e73fbedba5ad7dac3ac39cbfe77508f2b74c58835648b8d4c4e0ba9410b2c9486953d51e6f1d8de43a1c33bdc6be5e40f5682331d45c909e6835e6796a81f6977d10acc564703493c6f632d85d2390193e270262ccacd6a8aecfd54889312f02d2913be27324cc2dd0c187bc222df027f80648af90329c23871b16f8867854dd07384a41c7bc6db25dfb450f5385c2814de3ce9f38acd3e44e0f817c24b6fbf460760506aa524ff7e71be08f7910c6b38d0b8139296bf22d144f87e8f1171cd983fd7df0f91ed58724cd503b72de7e1bacaec836622681baab745f81f9950a095bff4ff6192e0f0e34366d19069b5553e07c62002d54dc8d948479c635e8ea91443743e89980b4d273d52e406be33a6953cb3148c3746029264f868d9bdaeb8e00347ac37bf2c97e89df7e19f58532b8770e4ada5e8fb1a58739e062be189956ef84124e82f0c0cd0f4c8682380c2828b562dabf047ca0131069f9b8b2a969860dd846b7051a2a2be67e05da9824f85109371becc87c144e909284e85b7912e0993088b561fcf3190fc62857522f54a70165aa7b7ca3c1fc9806e1aa9af0aaaa7e33e90be40a984ee81c05c38723a14867a7b82ceaec74d6c8d8f7e5cd4e54d32f241402ca9465b5fc5245b01255607680180e86c26a678c6d14a2a832816d4072f1b6bf85f7ec08a64f50ec37a4c6ac3133ec366e62239e784cb6b5aa259ca3e02a55fa6f304056616dee673d1ec0c47936b0a5d4908efc728f0638c1eaec0908cd2e5f57d6646c14d7cdfac683e2ddc0b5ea4394c49e5aa2e85b515880f3824014320ac65505cac85859a0d4ce527ffa087196249252e1e5d641c72061a0f68bd7723009fad9359ca1cb617c1d6d26dabb2e3ab6905df780354cd376b585dc4f10f230f1267b457781c71f1e71608074c5433872c62ab47f74a462705b203cb7d38abe841c6852ac735b6968e73a150f29c8789ad43e5cc08a6dd04786e18137208d2929e61816ee0fdc8b8d0d4b35eb0babf282bf38bb9d995398f5740145b990c86967c526e987a4fa5459968d6a9dabe4e50cc344a1c838915e79d0858404b0888aed43432363c8986c8217844c1ee2ee2ecbbbbec00e2700dbab6e9b8552d38ede2b3e825a5be233906741999ba096b30bcfe9016f74eb74d6c6dee96ce3248d5d7ce840939d369a71afbded86f5bc19ceb26cd9306cfd10962304aeeb912c0295b66f3ecf93bfc3698ec0c522ced8ece5d9d3ad5f0b858fe4d0c4cc4c8a4e0f3b94442a10948aba1b8083f7865c3930291676dd8d79a97f4e09bd442263cb3908d607a421244c0073a5dfa71857c9bf358d9f4212ea4b5efd14662ee4e7160c869421f9de6dd70922aaceb499f42b8759c750fc282afd2d8715f8eccb40c965037134dc2132f74c196d4dab70b0dae42a4adc06f234f356c71d94bd9571d9921397544adf8a915c4ae20e86c4c40b5df82fcbdae40d2d32a6dd35f6d4e4da12648be7d150bfc0f136bdfef6f5e158a6178a2f3c07cfa15a87089a45c0ffcd4c1e1cd36a5f1446938cdcc996fcf168882021619ca51bbccd2acec8d95255c83217c44d29f955bb12c97d5c5ca59f20860fab5f49080d8ec6b17268f7e74e754873e00ee040d54dfef921dc1641c2626dd035c24026f169e715fa065c7ae3b16336979b907109045969a541a5e5920ee873b3763cad199fb46fd41c2e35c93a0c55812237dee8f453958448b229fc3d346e64bc4d700e5a37bd564b5659be1f648766d50f973bef47b14137af92116e5d79d4884b0daf0dee8f75ef3a8223e55b16359d3f7b414a98393ef149b20d3179eb1c91213dd459dc95e23170c8b05803b9aa9cd37f39ae06649ccecbf98c5f23072cbb9be1b7f7e6a9210e80eb88eef79000487f3aef5ccab8ebcd9482489fd2774b3f6470420b53c62dd1e079b6d261f918ad062d28bdc16464a25e61354cc1ee75cc82049fd215c8d89e46f088ef7d577d5fdec9fe1c8c9e9a595795724fa89e17930ec8ae5ebe5732618a65f721264c62c08e6e67498d84150ded8831d8b8279dbc28f2389df2e9f797c96b498f9bf834e58eb145986738d9ded82e41985ce585c56da5c5616af9826fe1619d5a74c93ba6bc71de39561e95b488fe1da7f60954e29a90926dc4efdd21043a8be12635ac7edfa99aeaa9580ce17c6336155b3eba91cd020813aee4f27bccae731bf2befaf8dfda329929744277ef2a9be10930f4461a0cd6734b8beb18062818856ec75ea35f0db36d850bc6c5d27021dcbe890964b5eb7ed781ac62c8dcd182772a47f37ab8987129c89b81e9976fe583f3be49a34ae4b1a2e89ab6541601865c58562ff1cba3819ee3d8b8ad2289a90b8ea9b8926827e09b0916a93a3a1b9c7c9bec53b0f0f07b247df2879ee17ff19123448c5764f918c215d215f7552b6f8222e320f91e9b48266cfe83bf7f9e38037c0f14ad98f597c565fd1ad9643fee401a1f815253fd8ebaa701b196791f14f0213463fd739b12c38c10755228d86b0c3761af0b3feabe7d10282503aec93206da9f8ebd08c59d9e872b06e55c865efe1b0f119f2173ae70672115de102303e6a9e98fa219495588ce0e5e813d7922fd18b60831ac17c3d6efb9a3dd39f29a1515f81189f3fe1bbe70e7d9f1f6221c79f6ef0941b342a0e07a0921d788dba4b70c5cd1307b85e55a837ea8c4eeb226ba5fd3dee6bd2a7aad8849370617fa7cf8d99c4fcb94180103b685c51066620a942d1bec678c638aa00992d60fa599b865b983e2625c65589742afa521b90399e00271ceddc520120f4e75e10a4848538b49246468945026a154b658eb504208a79478775931ee1fc6cd04cd44bf63dde63f3815888d7bacbe75f7fe27297948fcf51a8e1d8c95f3685be1be63645e87a99e770ad25186d2b1998b3d16f7ee7743470671091e900de403c64da3d09d00ba0f5f471211b0d167dd5fcb6a919900be00cca448447b164277519c448bb4cf2cbcf8465b8f788bcff22926e191a243c3cda75238ca5c76230e708f5155c2d64f00cead769570b91b447d663825925ec932d10456727f2eb2d8452ca810419ca9836eace87571c0dbdc471f1c55b07bf38b88df878871c13cd5b7d54036aee98afae717f94c3e90381fed08db7b661683e1dfb8856b3d0912c05f4520b9ca4d074e361a1acda0cfbe79d82fa683ff6e25bed08c7d45bc06df18985275dbe96b8086ca7f29b01a0ddcad1a79359a80e69ee5f284a68b03e182c89f7c7f1849037d4bd718b496a7def80a2b86e9c16e3c7e363912a4c71623be9b270d2f623f6c9025147e3846aeebb6111eabcc177ef638398ae605ad5c327d7fb946725f284ba51a4255105421c81e70e6c0f37fc8695589a0aadf21ab0a5df5bf4f564ded45a30a8aaad3a89a2e54f5df54a2976887f7650f8775f5ae70f921d3eefc4158f9249e9e7d64c8560ddb6db66018dd6f07c1f8db8379ea09cf0d3face60370da10926f4649d0ec9ea226d1a2187a2b6ecfbe1fcbe1ffea53968b44086780df67a93415335e40d944fc41596818f3f857da7c635099b4082e921166f1df4d49bb1c0ed284d41fa87b2a6ee027fcd17e116023293f095c06cc01da921dbc559bf22a436f806c167a6eea5e8d43c4b9af1c84be3d491d364162c553d1687f3e33c753e9e4415763d491ec69f5ce8ca11af4036aab844f22686314be32e6599d242cb91052f2b3862c56d8d2c663e23f3cec51d8ed1516778497aefd0dbbad7aea20d6b06e6da4e924d97f0a2d26f81717d3257830341028be72462312a625dafdc74dfb935778202fe5e39b6ffb5bdf187e61059b31f3112f20f6f44354100c6413843068604119cfcf5f57b1f1f1ff2740bf71da84dc58471ae990251a63a95e263bf0c4e3a73a91f2c60c5684af95a1d218bcf61c93e11729fa1ddd4b8972669f5a13e1e1803d446bba2f68c909c5a5726e85ca46fdce55162feb6e6787c4727c9e07a0ba56c500a909851195f2ee57ecf8370e42acd645c5c6b071d06079d7953ffe260822acb92e422bcc6c4047a50d401af2d63e0b08d6c2026ba0e26fa84448bdbca9e44a6ba3449dd0507ae087458665a2699108f18621f4caa8c925d3941a2c6ce7d1a7c1e5b9ea7d9190a83e0ae2ab6f3be31ae2f54c9154bd2c2d20d2735ee9038edbe756b69c0fb78e719fe2ca146ced748792c8b749b6aed1ebf427a10c52f358a673402255283f47ff0637d086ac424a19c4d9f2cd6edd182536ce6b7f278cdc4389cd0761ea642104df2df7636c065b68746363274525c3ca9c4fdd7596b77f1a46637606057173c456304879ad36a945d7f68b268d78359001667f75a763d4aae49b1630f527314acb71de36c592bfde0518fe6f63bcf5cadfcfdb7ac1491b83e1ff6aa2a76688447c097e9198530d82ab9a385c31f624d6ad7827193b733b76f2240b42688b140ef60ade86480bb77a0a63b4649aaa264ec41629499936fe81e124291beabb399a68b05a302d5058d61c0ca4557d85d2aa4d59e218c196379d483009a3cf1e2170eda93b8ae51555d1f1766316b48275b9a4bb471f2ff78699d7158b5acfd3b1490b8aaca8fa22e0ad7c0884191da25136d5a24d4af3da1086154902528ad29ca2514c32bcee104e9053b1a8766b85b31cb91a6c63a931090d854b8206c7002c3bfb55c67d7bc4516cbbf3c52217428b593f823a3fdee86a7d3e96508737c6e6e35cd841f4b325f5b6ab8afc7823681b7ee293c0ac6167f7c1dc2c0f659acf682ddedda04ef0715d85cf22d7f4127aeba860651002a766920326b7aa56972750db222aaa4eb31b223927f2062d4998520c6854570ef27e1edf4333831a8e21c73d90b0a0a466cfe667433e8d8db1db430c4b20c58e7007be81685defdaeb515d81d8ed40ab278e466b87b4186a885133e0a5d407ad339cd4b48851115896c30bfc226547ef592fa0746741462a7fe6f01ef0da35cce5ee96be7d815280b6d3144d380d6b624188b04e0c84c0d64e81f0343a879cbb600befb4bde8db6c0ab55db322370c4cf60023a0de2c7929572702dc831d496db0d48dd507dbdf51d8f0a1d37e0122fbd83ba22c3171cc1913a7088b1d97f2955ec74b220df5f7bd8e06c14b3c05f293f9f612608b13f7216be02e7d58683ec0429bcf27746d561661233007d0d0d7915ae72ff80db18edb6258b0230d0c1ff1b794ecf2d52f5b896eb719c6c68197a4778ea9ed6416666b646b9c9757f872ad979f331092980da93b05215f627dfb460111337cd7c30c19f2c99690ed09b234bff8a522fb09484680d6783123b936d24de12ebef4b4c8cfa0f4d7a35bf1649415ef5955c7e8621eae69452a2e89870d7968629a61899c01422421d2e68f4103537220650f07a897873f879a8b2b399f1be357e52d2cf7293fb76f624b492ebce9d1c13807f72021eb72aa3909a2c1f1faa47683a555e8a99efb79255857371d36f85ea7819d3e37d754a9341d3e7515fc402169b1bd70260b8dd6f2f5ae61fafa2a17bcd9f6f086938c37ef09432b3b3def176509e4caeea060640c08dadcc19806e4a1a4028fdaefed95e2748c404fab39d70948520fa3c7c14ce8215121b90b2513b73437156323392660eeb514c9cf1cd25a09ee2efa0eb342a3d10fc919c25de3543f1f7c618ab5d33751021e30496fc2f962e911337ae99841e2c7a1fce7f411e4b800733cf809bfbc848de5869c1b5d09f909c5070f3f69d2282fbe151d5cb26a1602ebf5c6a8b58fe13adcd03781b7d15c8237b50e8c35a12adf73bf92ab66b7dd350513f4bb82ee0f4a44f6c718219b438343db2a55f2387198b32aac8b5ec8cc6720dd913779a38b22e32d99e699aa89800c3badfd91931b6bde4ccc7b51c8ab6ec87b5da9fb53ae482717cd39275fc39bc8fa77e38fb0c080661e8ad5270fa83f5b1d28b16119d59232297acf25048b2a53d45b91496f14afbc6915f2aac4a6096070cee9c0c4e919345a565b9099f513195cdc7fda5c784515ea0cbb0e615c1991794d0d30ad9609555338653ae31ca24e4010466c11afb05400643bcccd8eeb2b536c11aa4a1c1573c8fa66301801c24e36d5565efd0754b31fe4869cb05bf933739a826ee104327bf6ba4d85fbd3afac0a0ed4ebb4fb4afa6d7ac52f3e5661914ce29c7edad359c00c26a1928637fc656914647ef34870748d8a6312135889081a4c3e8bdfa873239d31ced9e0e9456ca7e8e7c8d09e3e8e2d12ce845d6a1fadfe3bf14aa44c694b29d5fd69059e308bffc730ca12c129ab87412dba6428fa667972a6988ed5416af328d294bb70f93dbffdf02d1fe0bd661d54432fc4c85fffbbcbf6d987b06c9539535030690b112120cf357381e705514387f04829989aface27c2438a310f32eb74287f845245fc1f0aacbb65bd5aa4748f78d883cd24dc044cb26e27c654e04a0f7ed113644ccdeaded70197201c08bc8330b3e2a9229d05704a9728219748737c85356196ca55aaec070d27e8781c4b9c48aa645994af8d7c58a004cfdc7137c79745394ace3011e91bd8796634b8344a5eebe73061723e357c89113080c4dce895ba1859116a5701c596c9e6a64ced296efa2912366b53a25bc47e1270c1682989b6fc3315d6dbdf1defcdfbde716f09a30121db886a183d0cd3a102af10988e6377753e03eb082cd07df8e85a439e0d7e8538467da72411c44422f0fe2c9135e4c67d10a119150de43c55d1068a59b5f5b43610cab57d36904e6d8b138c83056254ef46834b213d34713c3f245b5e9c70b836e2b4fb001cc32d54ba189a5241f7395a85b3461470b4e5f17ab556502a0e46a8d16457e95dd67bff9c789cf50293e42e297e7aedeec57dd042d37e093808d87bdd885e148e4901b2da15a2b97c514eb0f3e4873ab66bcc981e15ab657683bd503b03c01043a1813da6cc16bf8b99bbe39f684ea72b1a5e38d46e202c94f0e597c1d0ed09a44156844746e4829ab9d28af7de47904970eb36ec68b9caf771005b40d2ca5f33d052cf087700fca6a5a5edb17a5b082c4fe5a2453c5efae64aeaebb7057db75b94982c63c04c8546b1b889cd995960082bce015883df4d939ec28cedbff1ebc75f5d5581c30318a3fcbdfc2efe38edc8a46e3229faa93be75c7fc7e763419a01f691a3c76add5ec13e2a0120cfa51b035306aec1ab94fa587007adc4451561ceac4130471b85c836045fb1873df13e619f709d789389af384d40a80f5ae4f650c2b2e0fd8a0d953bfc9dda3743fd7caaf9d775ddf7b1c2819c885a7510bfc81c0909110fe8da0c47e4847b49020d8f69372441b7e705e758e02013906439fc91e374fc21333ffc0a9b859121c74d972c4b1f6fc08817710c8fb193c5ad1c0bfc92f233be85d7b398a402b456db636c2401558d070d30065b5af4865148155ecb249e907dbdcdcb387d8af02da2db584875e8f0261f69584454c8ae589d774ec7907919c74a6c5f1abcb887e1021e3d582271cd8527d1f9f455b8629c6f4890ec465e8fc25f309cd316c36393962ac6d5a89e48bdbb06ba92fc7a266a7d1a74b32fcb7bf96e4f8f666e9695791e7a6df76d77dc00d51b2cc2953f4316887e26c131440cf14699cb2ff6ca65648a6a32fb7bcd3ece522372067e75562a951eba95a78de2ca945a8e8ff15c7af0cb902dfa3591ffb1909645f644ffeed0d3cca4083dccc5cdfdcb182386028a3242e9fb5156fee0c66495339ca753b46344e3dda2a2467dae05638a7da4f40cef7d486d86bd8dfd869ea1ff76b240050fc03635dbc27a197611e39ce5283775876c0254d5cda38e0ea016c3ea7e69ee46909f917f7a19925d825566684d3a1c800ea7b17ee72279845ce60e78be1d34614cb959fa719eef4aa5c1ab60f10adfa4631d7397f6a1ae361068403554d9e0af5845dbe71538d50ed8a376c74686090e76760cfbeeaebc5b91079f889b8d75eeb0427484751fe97836da5ebcad432d80982c78fed71720b0c3e0afca100c087fb78614fb23c134fc0fcd5837b25b416c8542540011acaa3b8958796354c21bf90c848c62110261630ccab788352afe6e78db5c1bebe23706aa0f9ab93900d0a20e36aa30a3fe813bb88d5e90aeea7a6ee2c057c0425c9cfebd856cd8ec050484a2e01575a4ec9a85b098634eb4ecef5053421721072b170af23717d8a20658c51518ce8741d94c377e926aae5a17bd3ad04c9b4d2b693095ec4f6176058c962100aaec933fdb6c0dae80599a6c58319dd0cc528cfcbb4b504eeacfa47506a320100ac51853aa524465c2b77b43d2df2ab526c00b2434fc0e8f62ff271ea4fdd82335e1a87c0fb69fcda339e0509b27ec8f2c2792ed0dc9123106bf7ad07b7819f00834f356daf3657e5262ad3f8fe9e738834ace594e84666016883b600214d97405c1cc6019af7e12a3dce6dc63aec6dd0d08e0c27a4e20652cbe0dc90ea5ce37a78662c150ab8545ebba21003efc0fcea75f928b3f68b308aeb897b7210ef101f6f1c45832eef353e2bbfcd98ae5c4e5d95f61756c0c0b2a3079642e5267da82c05564b2c561a6b171ac1cd5878af0e179dc84a04414678fea7cc2e6f6076d4af290f4947e032c697b575ff600ef4e199a7426fbbf806d5c9f6e6423c0626aefddd5108043a8617d4718576a3da7eed721d502887bbd4d8e8d1fc2c973ef89bc7c6e49f4ce2e5fc92e2f00607874c6c902775149c057a6e47b74567e4d6c84f3ce61c884cbb560ce7e2f39478ceba5f89836ba49dcc62073410cc904a30d12c9d3ac3c3279060978242c17d2f03ac24777c0f5bfc10de8cb7859bca22a97836b70466c379408bcfe59f0c13bb6a2ef96a052dc8805a2c1bcae61564915b3183e0756af3eefa8f78be6c3374e14a04dddf13c83d199c20d6fd4a448c3d4088cdbab8a937b05de9ffadab77c25c400baf75cc602761f3a8b60f253395451689ed4d0d5b8bd607d0516de120fb374c485368f789c3d2a5af8f634bb3e42ea3fc0fb7c42ffe620c1dd1d1ab83676b849bf5a6f8de8cc0324919850461e916f4d9e8b88280f260d7263b3b08a2311a041d5db23d6def6a131b444521ca31b5ef02a056261021c5d46d26ee06b437be1a31f17f5c427032b43cdfc30b572a88ac6c12bb1e9a7763c8278c01fc457cf43cef4eea1297205ce250369d4f24b86b06fe96f5d878703d61080efdc1fbc2cdbff55e6a8eaaf384f1a5e7d1d53a02e345f7cf2bfa52f11b6bf8f7bc9ee368e6475132daf7db311911a0cb25e59173e4ae9be2018736157c840e9a02f4e10ce393d6436ece222874737dfdebdb9f5a131aa2e78255b2e0854fc231905899f64cb3259b9400346f43e050623cc9a032f8faaa17d1b604c16cda14e162484bd1a3775dd0bb7ec5ec02613263e375a17750fef0e61af3384b2a31c907a7799e0c260566917c417c732199d9d92cacf38ec53dc9da1b86c091b1b0769f908b56f6e71ec7e7175d69fb1a9f02c72ec5f1ea20f1417a0f884fc2a62e9991efd5cc178e04cae8d7b9229323c9497db6e8b6b08cbff666141fcffc3487a0f28e4927ac4cad08f29760b6cb87b3a72e7e601f1db8652d5625b0b045312ce0177cc79c6f0d95aa8954a5bd05a80afd8b7a6aa54410c1c01769c95ff036c1fbf14c468a4b25298a5f1273fe92e18dde7881718ec6be99422c071cc5cccccd31f42f62422c40d6cccb02cbf4c8ee035beafac7d7faef0d087b132fea473c00720dbdb9f28cc9d22936dee6fd1366c66aa34853d6537c0fef78580036814b1018a3fd9465b400c25d51caa17d15355dcf5c73e0731a675bffbfffefffafaaafafbfbbf3f0ded1d76b6b6bffa2ddf814db66565849983e7744ce6906106d423935817485e76794819739d1c2caf3a900a2994e82245366bdda889881029a594016f04a8045604c20d7c8b5aff5201cf056317dc5d5c7a1af2e75ec1b680b77391c65b84817d1a45cb42c160908820cf5bd409f2f0e28a32a1a92f09f0e50c4d5992259849c37b8941c1b248a1be4dd18e5ea4c423629ac274a39f2314ef7bfc1ef16833252225ada3b9876bfbd6447bfc1e75fde3f7c8eaa8c667d503e80f77de97ffc3ea5bd479fc1683fe4501fac45bf1b1335715e50caa02494a60949908fae90192e240542d3e12463ce88bb6905f72ce39e7188cd523fef20283db98d77dff8bb6b06130d69b8fbedd43d0bcd4e6d8c7b2a761f373d424ba4b31d65014e5772f43c6c2dc33de1d4577dfea0c2d0f6618803d080e799f3577c0cc0c0d07c26861d6c15db4f69a8504b4d6da847444834ab9194b979e8fdf22b0678dd2ab0ffe1ebf4548bf7bfc16117d0bb3e7b2993137f5b839b0dd39dbe4adc7dee69c739b55b384c2276868ca29675d92b5d3c8cb0f9a1d1c5816f844d0ec18255930dc619173761155e92192db21821341c4b6f9264dd35c8968df622d362b2d1fbf4464dfa6e4c8b79aa6301de6f14b74e3dd30482dd0bb24cb0e68a610210da52a8efca4693af2add314a613057d2b8c915fa09fd704d1502818241231623737742af931fbca24251fbf2b8cfcf600e68710a9253452f5f0a89dbd2206cf9288770592ce3048c591ef8fdf1520be82c7af8ab86f67cc7a3ca8fe5dc0346f74d7805f187376b39b2aeec16019130cc6c4a4302d1f7b0ad3936e2014f3a29ca29fa6d72f0bb4d72a8efe127226e1438ab510630c70169a8b7b85e08a01087a59b4b030f409068723380f0e4970a0a826c5554cb156e499e9c193b3634347c6091ff0e5f038e77c88a3efbddb863a22e0e134a7b42711f05e18c0622cc94b70a893c6418088a11820970580c899a4ce82106188380bc6022201616e317fa1708948dcd77da20062e631e6e6242e314301e637eec443a8b81f10e17cb85945aec349f01137db20495228c59364d31317934500ca159ab93a2c1069965c341257ca0d6c90159fec88b204a20beaadc8e5c3ebeb84db93be9d26cce612ab70151858ad82a52d26436eae8d120950fa590185890ca320202a3e1d277c820088515c0c886998ee440b77cebd801886e7ce097c882ac194250dc855912040c89094c8d1254248882f44130aae1597986f602ba30ff78aebc2f5297189c405107390bce666b9ec26c4258542203d6123278ce3388ee3c833c7711cc771046ae1e203d1f79712977c85988e98cc5c6c4297ab01d1893bca103f64ae151805351cb90498dbe5ca7089580c03b952f240eb6a8aad4814255056a0784981e54061e20448c993be0f4d5f2ecf6f1b10a7b80820e6c84f4b329221d724b23519e19a58e212cb3213578a5b368970b15c0f0078b8790792fb8094244992244992244992048af1a42fe7a9014122462346cdc06d1dd7b1708bb22eec04b92a91eac7157339e880e800627672c4d579730f4004c24c7eb829b86944d86b63285c4a4baa58fcf83852638a0e1e2933da666c9d3dd9ab8391b18878b9c41ce2870b969d3c201680e8e64671d762642397888968b93eb80808c4dc83cc1d82b78401a699a61dede80e05feaebfcdae9f586c77549f5bafb1d6dbe87eee80eda9b5ce6ddfed763bb53d812fbcd3e6ec2f9b86666646283ccff354773b9b5d4737f8dda9bb1e2ad1807fec2d6976ad6ae07ff66de20a577085dcb50b5c214e0bb170850c2324181c82711e1cf2081b47b9176313a5bed7be7c49c497fd16bf86fc58f56616bdc6b16aecc7aa3413c9ab6fb6fcb5ad8a50ab17db4ac4ce4a886ebf55594e5f317f2559b272737a321557a541c9dc0aaaaba72224be23afaeb76bd815eceaca81820a09498b145f0eb35d0e213c9f3bdc91e3aaccd135dc91e3cda1f46dda9f6c1175cf1fb24fc54bf59371a059bf536d3f84c3b8253f0f5fd0f86918a48537fa78a729cc3bf54e814d597d2bfc11287eb2b79a54db9167c02a1d752f81e711f8ce14d48f2e82cd86d80258e6f3e66c66c31140a0c166c30b8cb081183df31dc03c7ea74efc7efc4e017d0bf3ef14cfd760c1b2628e056bb29630b2638da56176045684b57eb8b13681c291542c62ad7008bde1e81982a863974ca9e144ec08cbc6a6036485e3b152d16299a64e9031e505dba2058fa1ba1b24766e7c00aab282786285843d1af2026df5e9b1caed707320d13081894d229648b16e49fdb03ca442b05552588da0ac544aca88b04f6a6c16b2a52e14552b938db50c469223a9152c8928132844edac55575815726c10932326d4d4bd451f6bdad77a75a5235553e589e54262c95858b111b49ad910b192c8f22385950167e56d6d13c2a6fda8c91296c586a327c60c25d6cc68ad7202478d115b3572d6242a6c0a28889d20d4c686385b4f88ad6f5bec13aa9a1466ac3c4b2b0a2e581828d8291a3e32688050b3b206895bb592b0406e6b693557c69c7049d1c152d570d104c45dbd54c4cd28c1faccd0597dd0394561c39640299224c89232d7ebcc6a0d8b5a7338b1518aac10d11a2403687d65f0cc61919b639d9ae430b286588b61c6ee00638760ad576ed4588162a3925625456b8d1842c39c183d45eacea6b0269cb0288ee4b04501b276f1589f68154d0591d1e4058b959e2dd4d273680583f2615d40856057d0c1905ba19ad87873631372c67af5585b70ad34aa9844517962b592581d46abdbd088279f9da7102b171d4b2427a4c9eae48d05c286e44c450f1eae13aae2a2a69e3e246519b12386869c7c889c42ac4a74eb931cfba3c9f0c39b11b6a6b3b5478f158d8b6dabea1175e3894d2a62b48e0dad2660f8b04a3042b04ae8d61f39b22650de90d8d81367743dd62fae354b15eb238aad7b1291b44a1911199ad1e4f3a3298411ba754d2e45932b6f576c4b672f7a747161a962a544553d2149ba61c462883dc2e4b3ea600a5143856e18420e4b93a6b775081b0b772622357ba4909a5c2c11abb91b6b0a196b0ca6a1233687053be5c41ae5f32d36aba15bd23133b7f9beb8d2d37b2f528187128f8833c94a093369495099e4e64326bd3c63d2d80fd7fad949523f494d4944414a25be9d799283c12412267a48753e3c2429245024b8113bd646ca82485b18f62b45ea09228b587cc6229c10c74ac7823c45ad9f0c6327c8c34580e942d74a18baf7de9bf3f69b4402a96e03a5ec17098e73cecf5d5b6f8c244972875aed6898a669669487748444b45fa41e148bcf05ae85d76b49db8a696f71ec5f747d57aa1e3256dbdd31c6bf0d65df1d273f69a33b4efe51e5196ef273933bf15ed2f89a57ec153be226467356db1f07e1cbbc99418715e90d5751ce39b087813c7149f6d88c66b07923de426df630f0de860d3eab366437b116f26e76b2b781ece697e56833aa264e7ebe4726af58d08ffd26ffcb4bf05b99c7bd438bb41db3cceb9e3978c8bf559db7d0165c21f7167c01f70b36ecba2c7fb3994660e404571e7feba14a6bad73ce59ebacb55e80af2da1e9ec7a9c018ff978dc732f03fe8a7bdccb80a32cc148ac1e7722ae1b1d922adc0685d7dc70590e4ce6e3f1da10b71472d88b0eb70f887c40621c4b5fbbc1ab88c9ca38287b6194c75d35a2c192104a063b652e2b347881e1066fe57c781ccde1e5b5da92008dcff8da1264b9a8b0e0f628dc63b5bd77bef60466e5dbe3be7b19c814dfd3301665d85414205198691ab612e79b73bef9de9cefbd39e79be7325ffb7bea716fd1baf058c599035cb6a8cb1c6406ac1d79c3c4de30b4c7dd7cfc866585997162bb99102c7191f6e2f8a193c23621041622392a4b6212c832b7541630b8b030a56e0acd9fd79dc7dbfae7a05803c12358dbd7922ae3304bd8dc1b06f67befbd69865954fd65f625a40e0b69969afb6babf755a62780b564585082175a33529c205b2b416504aa88c44cae684912672a7d515f2b785f3ebc5d647b5171f9ea41611c45e05eefe965420fbf99a5579997168c199ae563ca02920488a7ab46093e42ae44d9a9810508960f48f1a2d165f5a48fc6708a8fc64f49876a6a8cc7d28db7abca0334b2e2122d33a3acb78b8a379385c9f1ddf16e71e970cdf8bd67fcdefbdd5137be5c4da54fc6f049cce397ebe73178fcee509272de35b7c0b703c6dee64c427e1ccdb590a72deccc4d0c3ca700818c210a34c3265b635b568f5fadaeac55e2d1963df738c769217ed542aa1343e706e43e544bf1e34ed4ead9d1fa706527f8c5b39c64b4b46030ab4889afac35115f593f7a825f1c2d6bebdb1910bacbf4aaa23aabb676112f341ade4b8c068fdf2ca42c1463632dcc92c48ecc42d8b9dc9d649a87696559253a18a163ee262042058a593dbaa7306916881f5d98f0154d8cb63544c362323c636938e98858a2028b8a0640d972a73cb140ea79e2335a7c4e1d82008198d2c2896d880059735c387888b481b83a415e11c1a0f1da573cbbab202f2b39d38a0ef53579590d29ad8eb4307995563a7c5661173079a96e6a60625b4e504e28c352d4ae9ea008794184d434c6e8f99668865e260c4c176259218156d5a4e346dab0c7dbf047ea7bfc62a57d9b0e7d60950dc9b0c0d0b06e60d1f85668b683e2209a978eec5c34c0f463a67b9be69c0d937eb0a5d7c2f206fe169202c3b607f9438e2994e630e087e51c5c81bb68604967840dc414921af9cce4733f876a2dcf1bebcc7d3bc79d43280ea2198cbdf3ac72cef98b75f4fcf953a02ecd8f2f98bfcdca4d83d439c8ec2590c7551cf79a739224494d344dd3ec2dcf3475b94dd3d45deb8ce573374dd3345b536bddd334fdcfbe4f9873b7c0df052e9430a096eade8220a4a80d0b31d2fadd43c8a5368b5ea603106282276f344da04dd979e72846c7310383e7ae9b642ebbcfd771cf07fc913df62c37da511eb0d751b43d7f64f7f5cc2b5b8eb6a5da4296bd6c01daf43aafcdcff370aa3f928781ab3f72b741a1b0a792fd57926a05b450b7c11db0d41fd4315de6efec641fc936f83af87aab37d997772850ac5f35b8c7af5ace9b8616f70631dbfbab830b1b279477d344f7eed216ca30b3a3e6366b46dea89f247b267b2ecb6e66b38cf639e538933d0e596adc907739e7dd699624d947b28f2874aa762fadbabeeca6d4ee639ad28f9d74a9c0c5a50763308a7916f43264ad2fd596a7b6255027463b766d93f6386492ece686f1eca7fe10360f263803820817e8800850a013d4a2495b90425f7817e81e4f87779a00e08d5d9bbd24bbee678f434e93faddcbd2ec6d307b99c71e87bd8154f9ce588f3e5f4fe658e51a6740b11e5f34a2c72f5acf7bd6a67ba3ca5111f0d58f3020448f81f43cfef13eeee48f2acf7bfea1e4796f5bb8076ef630fcb80ac4b86760d9319043fe8cf9d9abe9d5946a5be68dc3c94ef66ac88ebbcc8853f6b22c7b35b9a6fd953c7355e64d93fd3d4241b12e73e741e9eed8a6ec1d86d2963fbe6076de477ce1ecdc86dcf51378d372f60c6c776a9bb1c9969d2c3b49922539e6ce339dd2efbecb507cd9cd329dc76f76ad1fc0e337c8d1e3e46fcbf2cc65e627da71f8d84bdeae87a12c7f6517bed979a5892b946ab9cfed817fe6bd1ab397ea2fab1d43eea64deee5cfec6dc8bd547fa63a9665b97b2e7bd90a3b04a5372d9f7185dc7127a9a032da42bbbbccdc91c78f1fed777dec24ef42cbf94bce6a9aa299e793d7f21ef89b1d87ff1863c2c0a01957e0bd3e661f093739ee31aec071851e0f7893bf25777d5733aabbb39f26efece809243bdf71de7fa7ba4b20f9e325171291a1788ccaa03fde5be1e31f573908ff26c7edfecb5cfd6595034ec1e75e96d9d4bc6f9bd604ea8f83f073cf37f947d52677ddb52a83216f1fdcc974fec2e3772cecdf20416a579e845cc2b7bfdd851bed630717697eacc78e7f631f550ec2c75df8fc71af71b6642035e0f47a197ebd13f71ef026d79cbbc772536df35639901d6b90797d3646f5683779069cfcb977f8495bfe5afded6ef632c3efdcf59f07feb8dfb43c563bef26d798aa87ae7b2cef58f590bfec6d3543d977c0dfa97210bea90a65b430e3e44f35588fa06fe1da02c6bd872f8c2d4ffeee3d72c6c718e8219730e61c55e477e73ac47c10fd38769bb26f48df04baa3a806a26d0abe445bdab1e3e4adfe36ec8ef6addaa83668d7c016dd8076ddd1cfbd9b963701c6155ab48f3d567714e821bf465bccae7b1ad0b3ff6ef2e3ee817fee372d9fd59060a894eb59525ac7466a000083170000180c0808449220c771184ad9f614800757bc344c382016cd258128200883188861188602108461000682180882200a6548f003f85e541411b6f7471b1a1ee4a6cdfb49cf48f4591f13ee874fa9f232a5d44eabd4c87c1d205f6a00903ecbee47122c5ca0b18be7b0fb818f9d756a30e9e00d404cb5ea46551bc81c9e614c15146327275bec97ed50c2f544fffee7ff8ed6b08061e9cc05c10153276b97f0ef17741c1d8ad07eb404c309f8652872edb0d39444a00990803cdfdee637669f3fae13e4935e2a6a922d8a6f784f91152674ee3855b2e5cd1990bc55cfbfb873ef857c87578f6fdfb90eef871d3f600bc7f63d7c3aece8607286d531557cd220853fe1c298de71692bfe0c172c76f9cdad8826add82e8c4cba238a7f41107ae9af4f8783e606d310ca7cababdc418df67b26369d7de6b88d571e50e6d096d8e849f2dac495e5cfc6bfbe5663f5006b0caadfc8ec8fafaca1ecb8cba0be08d4c060a33c993b87076841465f7f83293163db7addd1af62142e8c6cee9bcfcf81c399b4ad3b9d62d5ef96cc04104ec77ca640757d832b922a1bc2d4095096faaa00880cb112a2d8e45007b619d7ca2361a405ae4957cae8a2f9a03a5608775c9945c075e6d5c2f41d6d62b948c0e42dd553515b8df55644d651ecaa7aa601823c22044529d41536eb8567d41a18f24cd3fb09d4c98ce54efaa9967341800ed6a8185e3069a96d8a9e697a0ffa36db4aa3d5c8cf23e2ac00f523668a74ffb6a1de8a072727909826e428fc3fb762d392a6dcec7013a0245e6eed232cd3e2a18216c8641b1755780f521c34f8de2da1517a10d5de9ab515bae26debc1f3655d3f813776dab6cedb4769c95a084c5d1925e98c775c46246625994736c1fbb896a097662ac1db103eb763dc9a668ded22c0cc21acd9016d88343f52287687616f0c38e319017671b3748c6c0f30c5dbeedf58f12561379c032ca14bf017470cf31a23d074cc489db23a6de39f0c5e18e020f20a98d7f03f61f53d256182da606404830b66276c30831daee9a91f00167cf5da9c9715301619240d2226883cbb92fb79d02b5e39ebef0f909d03b7b27ee5794c3b1bfc078a843c4ecc4bd2f915f561119a74a4ad8512650a04df8c187d046d31b2fa3c5e862f5bdd1e973d39f681b6c891cac92f5651e3b7d4e4f30d3239474da7d3ca70bd69546f9d3f6cbcc7f44cc6e59f25dc9a1272eb84d58a0a7ffbd736ad61c13fb3163215a11913fb41f99da192b475c7bce96e4ad03b5bd2a55a6d766be94f32ba27a5422412c316cc7c28721457a22ce80ee3f446a101a1034bcb73473dfdb2a8aeb1f03850a5cca5761c4980826fbdf51af22026a280dd249e792d378ff671cc22b90824a12568a73cc5f1c868de07047138c9129d617fc017631a884db3d64ddc7e9a6231750eb86a570cc3544c6f0eba237ea5c774d003c6308d2f88f70f49166c4072c80e2b007d3a4c186928179147955fcce494d8c9c7a408b5357774419d1d2a1dad407897ba4b05c68553660a0b8b065d9ffef5d075e3d3d14b2ca801045fbe70c58bb68826d2df3d6f528003e3e42c5f6d3b69c6f35646b174b994e34437e409c1dff487048dce054533f3b7abe0283df9987766c590736bf63489ab8b19100edeec60c63aab71032644d90804f4fa2ce97392da9967d0264288dbe71710b65d63cab3603f6c2f275c97044f524e365a1e1c8e81c7b31d5717eacde91f43d3013f4b070e7bed17ee79d15e31228d57f2fa216d048d4baeb9262a5f61f84192ca7db26b15c967be97c76012dbd1e8d43662dcea6fa741352714be061339548ca0c68378ef97e13f5261087c142d5683bb8f8a1a28f581ea059eb0fc38ac923cb0e8c2a34f05e10402c3c1293bc1b7924ced9f2bc56b88bb9c8fbeb8bbf15bae70f683c206ceb4eb5b359d0b75eb634e632e19b5fe557f3b65578eea6be42eebc61dd0879fcb00ee1333783b0c79f2cf4da2a9d461681cfa93895ddeaa9aadbaca8b45e22b35743277b045854ac7f113516a72bacfd6a32377eeba0e52bf0c81ce4dda698d6e3e20e9c36be2dd1f02e60e3bf2ef444dac33e8fdd7728a83b3ad3c8d3db359b4fd2501c055d1b1a9091d2fb73d6e28b48f59b7066f2053775f899a7e14ccb57e1f5e819241193da229e854acf42e1efd30536f62479938e929b53b48b8532a731754a72ed8522d680064c99264a33e56c39d155d1968b8e8d95aec87a4837595ea5041e652ec56eb1b255debec82207006bfb6918f64f7ef0d0554b4c0afcacadc93fd40b2d25f255eabddae6403bec77066fb5ffee53196efbe989abbbb5bc8121764664cce7cbfc7f4ec5f3fb222c526bc0d4673c613cec560a34ad303f815b555ca5cad5d11a16b7d81c4377d95802f446d056a52fcc2f3c2f9dc480425540f84fabab01725ac94de46131cbf4f833cb197ea434d1735bbe866dd17cdbbd60236d4ec00ce03873c2cb0040a9b3165afc8fe6ce46f541f9059b855587f8725e85145e21200883aafbce96b6a9a0aa78aaf7c668cf87d4227fc207636d5da1688f6ec2d1c2215e6f2a9782190b53cfb3fef21d4781ee6d5b85b37a346a8a9fe2bd9fd2d2abca315e3155c8f13bcab490b0275d51b0ed05c53329f3c3ba2acf7ea62fe944cd35deb84551eb4097484bef3293c615326d8eb77a0362b7562a6ab72656f08236efaa10f6154b29ee1482ed768553f1cb0c926882ef730153b16a1c6db73829ea65996d033d4ffccf89502f6147489e90499f910163524a86931c865e50b8d22b4830278d87dcf488d07c85c30f40f422a7638d050ba3992090573bf16f4c1941e27fa89214d6bd156cfb1164ce92fe280d0491ad55b2a857d34c4aa547a275adf2204b9821acbc184c3af85f12015fc8bdc0adc09ce428a17296615430403d5e4096d6ed61976605dcddf5a943f5801df3f2366128c5760cde4b833eeca14d98d9981c013ea3dc7780046f05158a83cf200464865fd8bcc27698dd67eba35be00a775c953dab80b385fb7b9e25355999fb81eb15f10cde7f66f1d56e8af346a8c93bc03b9b37891221e8ed4c60e1c781e8fdfde083f27ae4f2bee4c0e0f0d469717da67e7609a908b59af2c1f2b4617bf7258c39ba34bf2eb5662eb139480d8989605a5ac63443f1df914230d683dddf996d97a030f730b3646282ecce5533c775093988f6753a04051f48d6e2d2d31e42ecc855dfaeca45f2cd0707ad29ccbbeb09472dcaab43ebf3325c9dd8f8fa68f42fcc51b3c0a96368beefb39d048718c23ac99f7daa0eeef195c1d78e2e06c98847f6b442a9301705d824987c126e89af68c6d59e59f9e693e9882309885bf3edeb16f13cfc50fcddf1a69e32f44c19031ddc2091ec09b3d843a92a95daab0be16d9ffad2ca602851b90e0b3649a03bd3bec5a2da2c6e56eeca2631c5b3fa4e30ebebee3a877436bb558ec736d4b1b954f7ff5993c93c5c1ea199ea1450027cdfa1d5c349a3e48ec88fe22838beb2915211c1dd1a78472e467d8754342612b1dc5f9313cdd01c88557255edcdf36d907fe2afb8e2b714619a0a9756a138cc4e69fcdd4ad308215e83ea7f8086464ead1ca4597d16fff994f238a641355ca0a6c4b67c16437cacfd82e877c06b3099c26c36c9ea20dbddc220eb17c6dad630f6de63233687c18e512714e6c6c71aa83e5b9c1a60054f35afa4efb75e4c57b63c8771febdbab8e178504f644abdfec36884bd6fec33f2d2fafc6768b9b7c0df3e2fb75345e131a1415a8df35417257dfb6e01c4165be8f04fb71da80f1719c4452d5c89972e4d06e190460681c8c73192a13cef98cb6b86381e665e1a469b1dd441b8ab24c3e4c9c3a865cfab70001dfbd4238a9b1d8db81b81735264fc72b0559483ca575b033677d9dec4b0a44c0c2912812d4952e6bc947aca30fe64b4cbe88af69f04e31eccb9036c51c7cd79a03dd3f5190ca9faf87fdc12a0904e7d1c31747e91f59e75bd718c98ce219b4f7432237a8fea56d2c96f102081dcf576d423180918971c1f9b33df51b596be0483babf01129f031208904b88989cc34fb7b7ecc2bd2b53107eda07d5b90dc38b416bf917abe71635239988aaab931067ef8605739aedd3a4da09c41ad4fa46a6b2fc5028ea2f9f2bc70b7082cb67ee88bfffa32c8c2ab8cc5def1668b6f8a7ea007d21bf52e564fe1dc38677181b277a8dd7061171fe3b6cf3f73757042785fe354ed07c6eae19bf9842269fb3f9b374f94d32734bedca9532153ce78842b48400100c0edeadd8037f60193202935e1383b95619931a62fbd307f8cf2d747d70576db8599605724960dc1abb6a54481e0abc72ef2701aeb3b5cf0d94f60896c1c803ff84eb4ac92fd76ee1509aa6e9a6c4c62154291e4dfae4b39a4322af6789d4a3ca01ca7cf2a1ee1bf928995d8034e4bd0e5295858cbe29c3412c86c98de2c8fe8669cf6fa27ded9a49c8446fb557e7327780b5fd0dc5a38e9ddb10ddd303e4d4568f768150cd508a0cc5404cb93cca261cfaa8e7d018ed8b2ad2075ad1d031b75a6557262afc94b70a9764d6b84fc7b166339b1eca91f1ed848b8142464c1eac0ea57d54d8ef9438dfc8281db5f8ecbc81a5a1b18885625f3f1e399de0db5ad8aed44e1243870429b92d37f8c0c85e333f4c9ddaf79be49fe4b28cc328ced6cdbd960aadb3724fc1114e4f1ab1075f847bea2954252cfa683ea416dcf5c05377855881ba6261598e51966d8264123b621f77d555a50b67532aacbd94c47744fce402f356a67230620a87bfa7994541bf38b0cdb18ab7064d7b5cd4801d5e3287878cb42b9d8fa614f9a5752c01448f461babb7e9c52635abf6d5c0b226b2d6446504d79f1643b8fc97b424a407443c3000df11e1a25e443a36df0c2b6521844e3c21693179cea564528a5b3010292cb973640f9aed827f8c522a1882a18b2a2c1796c4ed4084dd1d7b55cd0657348d667fafe6891c4e6770ba57375f58c168d59c7113b617671473089d4c0ff3fc7ab805bf9904bf023eda650b205f7bdb9be8d70a0bc034a6509f3ef3b1f91b76c0b25203426a200db9410892bf2584ecf40632ff40d951c9ee4970b61555841a51d376f0ee593fbef34b9107f25c1bb4dd0b2acc100f824131e167c98d3aaac069719a4b321339422e8b35c039c897790cb95929a20370d810e8c1266d14038537e75d1d336504e3a148d2497d2a958c819d20b01facf9d17c7ae62e4b7f10ca931a8500a7bae0c288ed4a25121996262505538d8c41a92a558c5d84814f72e9db82c90391678504a9a43787c0e6e5bf8f07b6fe1a9f905d346ff40aa4603327474f085ed20d6b988c3da093fc021376063205f484d8b7d8460538a923d78752a5db048fdb34e424e472af6e81aca7619dcca8280826db0131c2822c122f3b4f50aa4ac0d0f4e9940cc3c36281d3b2445c7ae154aade364e3548c9bc2a040d7df7360dff1081a9dae42b0ee1e54133ce0ac294e38c643751958e09793abe0f807e0e96017714daaa5f9b44b3884e4d3bbb0f62a5faa09bff38cc7efccd3ccdbfb7d18ca228581e2733cf023f9acdb57e359a3ca275a615283dbf75059c882ef7fb5dd86f059d4345f75109151844a7c7a596d84bef5751dae1a95ead41a883acb38a26edc127b9e6d98ad42b5927e6ce36854fed55518f428eb023e0355efe1964ea3e6e76b6bb3eb6a9dc1fae5302063b136ad382665b3d53020b7e9b2e70a2ff5a1e541b6cb62b964401742e2175e13e0f09db56e10c8b4953dd20caa072814b10747c0abd89186857a7a9578906d3efbb01d6c751fee8537b9f607277a4a189a98e0e2242eca51006b2671a05a9fc4756c61c671aeb99bddfda0747ce2d17967430aa9d860221bc48c2f3bf09726886331f28a41e4c2c020e4ab941bbb53d63d71503201225c9e284427269571f80b393fe42548b5325f08ea9a66bf83395608bd8668b1fff31b470da7fd42ec24fcf438beddabc8d3456355b21b961d591b5db1672af40dc119414d3380ed34dffc706187a4ad825b0ef493535741c4d347dd59b1f859a404cabdd51b288440fd4efa9e8718230ac9714545bfbafac6199a3821067ea237bb4ddcf741a8aeb4f4d918f07720281506b4766b2c550bec69c711166f5517ba7d29b16130176ee8ee1dc4d99ae6025711a5bf571570c4fc412ce30067a29151737a6c2c9407df073e7e1a42d8fa6ddc0dec317dbb6b97800d43f93e5db7bf567e4148e4d78723d9d64fab1eb1ddf3159c75cbdbf50a7e5c2da56637cb1f57a5d71167152d72db070a770fc54b3b0f5312a93a7b0b340b3e882826678c6c61bacaab2e07392ace388ade4dc8e2a504a34ec70a07f5579788c704a7ae0245842dd06cce582bfd35f65c654fd36645b08c3f0cefd3ff43bfe34a383edc76afe867c19de476bcbf0ac515e1308ae34677200f806123c0638170fab2b5b640c1e91a0170ed607f45e409106c3d4639608818d639908a191f496ccbd98ca0d2d0911707fba83f49dc877ca680b562495ef53b1f42e0e86dc1894c7343a6784a1b0f07aa51c9c1bc0dc30d94b2757ac33d42572ada373468a18f830fa3c4df19e22686ec005290727db611e25501c5797007b24131bcd1bde4b600ea0a79035ff9936091ce69c63dca168cf15f42f18885fec23bb9424542aa0119201001a89a467f63a193a0dc8f241f280bf86c3ccf27f351019f343a710f9056683a80017fc2d6757f51bcfba6fa7d130dec3e68bcfac06278fd35d16a5522a210a590bb1a24490215619375bf9310f246e9c713732144294f4d038f27c3d90f93a86863d3431578eebf654b1afe554b2922f876db57ff0dc61f9113b203be2433f43449788222752528007236b4b3d515e103d8b24b07462c2be52550eede51203cd50ca7da875012f6036fa1b03f1bca1680349487907aa4740753c30543d99d2c0946a217bcf41c124eba6b187b8cb63396eae994067cbb26734a6e1777874ad5db918e9d31a93c5a4ef392c7e4342816c84895be4ee0147bbc6f8c7be189dd688505ddf515245953d5742ca8ab8050597711515cf64888e671aeac186d961ecd952170781e960ee711108b85a2ada26aef4f568f109de3fdd58980e770481902c3043acc8901f9c9226eec1090b6f4dfe5e910d812e20b9aa55d0f673414d34204b644f479ff0d0172f4001dd881368635e19feb7941f349d906fb4bf9cee20be4433e8fdfa19174aae1bdab52ff40d46d287211d77052d28da524517715d22abf12fbfdf4f6257e1158ead493843f6abbf11942bc6e39b97e0c1f3998289a628b8ca837b113addbe76dc8af626d8d3ca408fc0028f65f9f1ed2a5e7cb9d4a79c126a2135e6a746169037a8ea6d0ac3802481c17b86348c739f5a2ed30c99be2292ed6c6c224fb5c2d594ed113d64278143fae4e04dfbd009a7c39e165ebb01f264ad74bf712391fe9a24a85e023611c926d6c07473ebd5de6192913cc7280446c87a20aabeabc869ddd8a36aec71c11e070672d9312d8e340dc117923f82e4049ec4f47e46bb7b22fabc721426ac04e91a6555dd223859f3c4f206876779427bce66d4b23e52d44563799cfe0341f396caf0c8be4a051b9515fb45ee68bfb9bf1663064ad10bf6e661e0f2415a0e135082d441b930ff4d4c0b060cc932c80efc9b4e4b17cdb33033386ec4df00bd1d3406c379c49f104d1a1dd88c510d580ee305931284df595ad28d8d9f8bf182c9df2fa27e0b2f220dd5490611ec57118acd4f6f6693a53ba757cc6f5a18f33c309bde7e38f8b1228ba24d3fc520ed6ae4f424d90c7a206b5bd55c8baa51fcc710885f0797e0347a6a69337321bf406ce0fa5e70fbc7631d14f3d2c2bc14726009e1b8aeca3581c407a0df3e3820f3e60bc1e2d2c0071e6c14c65b385673ef6d47ca4b90b643ade60af3a7c597734eb154cb9e9452c1a1a7407d38a58d28cc76777563c90b980c9522359d5f0c372dec7c11857212e43f7e91667192319f3279447e09709793aba09f61c5dbdef79e524be688661fdd8fe41f5f1b1236f77bbee8c87386ae2581dc19cbd3aee941235641b19ec66b7482ad96128dbdb5a88b6fb828b90a8681327aaf2813a44bddf12e6640a814ed6d82b04fc19b05316118854c9f0a080d19ac6aa2c01764e390f92238a5457e2a8fd3415e83207395e9f871c91b768d70ca39dd87eede26350cf30c67b79e17a024576223364b4a3400bd9b7763ca216d28e1fff2e3853c963c37a7f7bec0183951e939d9cc9028cb3576c17dc6e24be75c027e1d524a3fbc39ccdd355873a810bf68ab37811f2d36b24a7132daf0eacfe568456bf743f3546ca7ec2f158413ba7034a5e1c28f9694119b650baf834fdff10cb3c2d8e786c4453a44bcb533003dbabc326072d3b4d01ed6f0b8e0f1f7e6ea759987221fc3bbc57c14353bba3c2b257ec6f24f9c8ef4dcc265fe9b05c89b5bcb6f0f36555d7432c6f171dfd6a58d2d835e0cf4722724972ef8dd2099397858af139cad5a1c1d0505ad925cf93d82823a622590c69a81624c31733b88b59fcc5059d43ca84df2fd4c5ef65b4bf96a3c6a94cea950d77bf31e14b15fa67ac4e70cb55f118c7d1af0e4df308b097af4ddcd4406cd2d19e7cc52fbb340fb1eaf964411dd0a05a6050ce8eb6eaa58ddb1f89f03850a43baaafc729c05abe067d523b3d8981be298b5e4918db164880c74b82ef23b09d07313a271a88f9d2410ff2acf104b054ffd6f2242cc1ab9808bd381d2e16d439120dfc7ed3c02a5adaf34092cf488ade99cbfe9995dfdcce6ebea7cd1330c5199e06868472cba671b315ff8c6f4a94dfee282147980ad421a8b98712ed3e22db2202d1733287ce338cdbbb6201faa1379dbd4cfaea3e8fbee6880687c928e5f7f8c1a82c5cc9d349e717b8273bcf32507a777e81c184114923304fbb539f4e64d49731a7cbdc09f51d51ea0f6ef204facd71b76aaf858ab63900112a15516654dca80564a5877be01868f72bdaec9a307615322712fc26035b1a73f449f85a7be7e67178382eec981f741a2472c33b8a159ac39c7f7a1b5498bd5251b396e497c298570645219aa08b0e60964e35c2b4098ba6dac114b3b080b5a4425cea270642784eb9fdc1facd64b44f17e108795278010d661207fba8d11e5d2a5d451aa3cb930bb68fae2e41aaf7321a550dacf644456c0813a05a0fc9581ef01f4498e9509bfa54d7539796417681d89a467d25ef5f839dd473336e892c1866902ee6ce6553605039851c7faf9453f08fc82b21063c6fcb4c3c16072d32f864cd9bff981e541ff6b471fbe7f7dc5f11df9382b08507688857f6b7916f5dbd217e013c18d910afeca7463ada9aaa1ddfbf572a4d6ab4cad4af1805fcc77e1fe215725f37f0e0f0bd22e6895c20656dcbbed077de8c044e15d065818374bdc2a3354e9005d7c1831040503b4e47eea68d41b168a6ba77162d98cf271f560f0da1daeddee0945bac29d0163d91d5312ab4bedf01980301b267346cce9ec31bcbbfe3e10611de415a91a4e4e3dca241b1929e26a9d811e147bc26138de45c97aa72cdc36932b501476702bcf55279f832595babb0ce127b2983186b39dc95fec0909311a4fe5a106e7c9a0f7f3b64df3f8154b19ca5fb3ee82aff0ee9b1f735cfc877cb89c3f72c9f7e48c3b22f48de8796517e2d8e6ae04eef599780c03abcd6c523d603ad1c45577d49c2e96b7f40014f3fd6ac53496a2497f12a2bfbd8dcb4473909bc2989dce3fc2b612c7ca05f6fef8b9b0c15d198cc9d8d789e137de0be0583877380ff185787752cfc93bde45b990400a6a0dc301982d86ea16c1ccde5cc7541021574543afa2467080fa60d31139aefb235ac8b1949eff26e4bad2dae34f0e2413540e0b70e3b6766f6597966ff4a0f6f733de31d689f061682e0d9905374207e968cfbbe9d7cfa8f9c60c1364258246ae91f7965dcae324d907a1084c507b1cdc3a14c4336ac8a29b06d69570e3686d74668166309473163477cb9056284deb36f36c01a6cbc61f6b3b827493c7d06d60b11388178b7cde7781ad4e238d31bf0c060c92b03276d7415662882d85403b922b123c14d2668dd90aa5f9362f9190ae1599fac2863bdf8102eec0cd2a5899ebba7463756e9784313dfc86f2e24706187ee97aff80cd99f5da8f57ac0a8ac8a7dd46d069b7ee055ea360852b5a6a1cb627c5a448f21c2e8f46ee34529280c55474ebc0d91d51045ff9dec7230cc5456fdd985635e44f6f2bc099016d041c156ad03b2ed011aeb34d0926b5ea3990646d21f7babe63f92ab35a275d9d990d5d62145eae6e52f3fec08862da741bda2524a1ad16db2fda0d122fed3f054f55240f0381df87e86240ba9f1019c0784723daaea09394be95e57d6e8ae65cba86482971044a764a7b8503b3d228afdaaecf5bebf704b7661e1d7f187b1fc6d5e66ba52c4fa672cfc8e04b3a4f7d6e798e96966272f7e571747d559f1ee15725a07a98cab3b5f9d9bf6a576626bc00c2b34981b01858c03a61fbc34b4e04513ea6bac9fddd44244a85a64db057427c9b8525e74cc3a0bb7f425978b046b6cc203eaaa703a7ed97cb8b1c9d357c001b3f6eb3f86134a4c57aa9db6d6535def3567e4a56a29d9bfe65544c49c5914fc9a5558010af3445b92660f6ba08108062e426cf5900f49830e12df860bb2986cefc7df4f4ebe2438e894dfed41518d0110ac3b2b0fc202a8358e1ccdc838eecb7d7c98035ca06deeeffc1da1c48c663ceb58787da54ce7aba582b9451a67d89ef43c705b6f798c474fc6e87c34fc598c2a839f36d464183b904b525f4ca8811da45e0c5d4bad44bf6731b2ac80cb3599303a4e2671404c9031e737d0de418f7a5cace9945ea356bc88ba53a3de26e1995e46d8591709d3cba7f7204b609c5de55914d496809c970d88a1e6e5b35f704eb0ff7a8dc3ee3a06d8cb935a4d075165e430b2f4570f27c02a0585c5eca052bbe94176227ccd4d99d4282dfc70c0cab0b1dbb91aba30c7c1f87b6dd9afb01907fa3e5237c1cc7434480edbe3a06f663fd406ade1e9d983faddf7be9b29336bd15dfe037f5e139eeb04ef24547e6b71073d1c6c7d3752a3b4c5c57d5c5140ede07f22f833f26b392f7e6887e25f89961e4accb362787820c58c4a360b8ef352b54763857c660ccf5206eabec98c7bfef9331cfe34af7d1542ad0a6c827c89afc375490c2966d29144577f932add267e7e8b990cc6604d33d5b76e14846be76664d9613920a245281c82b0ec6a4571b1f65bcf4aef283e9376e39cf32aba9cc4ce95950cd8142dabb0b68abc4c16cce9c071dd359450177bafac59c72451594f494b3702f435c690b645ec3dc4e11d33d1538f3b228f3b33e1eb2b0aa7339b965a7c95ea0f7188fcae85e975b7cd7d011a11e0757bb53936715d83c99e4881be95856c9a876d35e2e218754becd86f9ae77a7d758eac36e20d40292736d182a4922c6bade054ff288c03958c27925f2cd9c21e73bcfedbb9d2a05439d1a2ca6bf639bae68659a4fe587e536872af74b3b5f538bc92d25c652a0b9de5dcae80c9921a6b4b3afc4878ddf826ba1a6f2d82e31da4d59725e9624edf6b4041f91681c3d6e0914d52d84eb230c214471d52f9c627ed0e8fe228249ae646be3940726088da1cb04b16589788ade063627b05068d4786bbab3deb9576477407b463a23b6aa2a268e190b22f3447e29a03a403cc71a18ed342d29ee29623dc1140220971401d450582195a570b4919cd28cb62e7344a093907114b5a0522eb4857f720b5a63c8173a48524d29a45dc0200cd1bf17388e310ef107188e6087147d9112d7d93913fed53c0bfc3ac88f69df8e118c7318a438b1dc6809cb824e46a4ea41813b32f17787b098707ae9785beb13efe59484034a104c411b51d44ea342119704721b4348332200eb2b534018150c7f869698302eaa8eda071d43fa82537cbafa42efd629e8085a0f944525804f906d26ac137009fb62df839b81d1c386677c87de12eadf1add6d5576f6ba68c494a74c741a495c6eb729a8ed6ab64444753155d1cad1dc8ea20a92d271105534b81ad8d464f32f242738b1b0e1047288b1bb15d308e886aefcf384ad9681aac4034122db8a95a68b16bae734967d4481b0e280784748d4f44e99f4351846178c1f58c569585c89c462123ef20045946462a315531783ef8c8a5d0688d62fe3d9026dec4227f9a47f28b0347ae800d3131c95c0eb1ec3897855694145a94039359b98af3fddc19457e6742b2eb60a96d1df9e4b447be3b5fa57f68d7fe34d768f1488d10e234162601676f1acbcb9543f3287ea7b5b7ae7f519dc1622fb39c47b9e7a5098ed65b0334e7fccef4011bab138e23dca711d3771c594874692ac8e83a8c65d1548d90b5a399aa1cab475b11d8718cb468ea451707bba315c77647bb833d87b0761461d3685dcaead0685d6644fbc8d4d6d1a344d19ed1a890f91c571d2e1d65f1a8fe9568522c64512543019fa0d49d1984529a9eb6263a39d81cde1621bb2a21445b9376d8d26a14adb1c810988a3c83b31360a3133443b9c291ebc8c9f1381d2b82a785818c58d20cc5da91eb405c83daf92296d775ccbf4d5395dd0e761ccf0a56b9dd7247b20d67711245831188c28281f01b82721a8d569ad03b4c6a2472f58ef9cf69e588d43a2ccb4c2b2549abc12d9346ed81f1265bd55bca156858552c9fe47c0548e38cd4dba896d12316a3a74714c041768ce641e02f8278f64e54f875a4310ab7c31f8e1f0e3f0ef1ed38ed4f6314ee8e1fc7bfe3fd3bcafe69cc202339348692dd0e123f8d980a215d5a934817c7881f0d18a46c078d91405747fa7f1aa3206747d91f8d1864a493c628387280afe310f711d25bad8dda4afe56ac3958914d46ab28f20eeb1c568ebbb20989ba4de41e70cc28774f915bd016773283487d87b9239823ac2693aae5f56a0e6d93244e47912e4d5bf070440747695cda96a8bc0e6f8243f36d21c1a391b69c96a76d0b6e47178ec08980ec066d1493a000da77e2fe8e2263344ff9cfb1638eb223b49e647c3acc8e69dee2874334fade6b455c6d028a923d4c5b50d41da5036a7830f8808fcc72481756b74e3c50ec1e62685a639b979b0d668e54de513942b69d2a7a9a2dd799f80198376b14408c31836c420d41c0035f92a6ca63fcbf5fa9e26c953c947198c6d16cf7277b6fb2a59432a594523805750457044d449198d6b4dc66ccd0716f25312284f45b3db41efb4a83332acdb2b00aabaa0aaeaf55bd25884088ed90be7a8b84c1d576a18661d7b5cea9ea077ef50ec301e515311e4b0e059d704a4f924340224e49faf001e4719c2e801f880d0ed404f0af36803f6a3372acaa776d17425f391414714a4e66efc395cfc18f3b500ef9ea563d54929c8263ddcccc7e3189882b32dac2fb33560c136ad5b47608c3306109a6e5239896bb4230ad079f16192999abbde99a56311234a1d646472602a6166539c2b4f85acc06a6356ef9cfb822257a4cf72727d3892bf3f5bbe9b60bde78328763444ef9d6c27b1bf729f7348e63bcef694116ffe9c409a50a7bc5f4ff79b28bb591537a59219244097c6d8264ea43f8fa55b6bc11284274a0615ad5b599d6f0eb2892c1d77fdf3d23467903670ec7a81a7a4eebdf70aa6748a635640ea77ad31f7df811c3a1f2da1f7803be62382015572602a61671842073b11c580e28bd6fa686e5580931e5940f0c3baeb9dfd8ceb6bf213b38710121c466599e5c4008d1d3a387284864d9a1079accc40b84cd0e7f42cd645b663aedf20a21824a11459b44d681227091e2888a234c61842e3b4042f3a05dca0671c58699796edded527e444104289a60628b9656c20521106558b8b8142780e871a1c785279e5862892774e7142874a50ea34ce7fe76290ba6ec1336bacb595830775fa74ccde10a2b8ea40445f143101453b8e81ec124c77eb70538a59b3a31f38fc9d6e4f7fe61da20451098a8a2c50a910e6468c2cccc59672c430e6c7899b034313373c6ccccccf105d304cd87a982efee97a2bfbf311bcafa4ba8f6767747145c331be0809979090e4afa067d744377b70dbe8adf245c850d7ff435e03faa6169d8ee6e1a6cd6249bc1365919ec22591b8666e8ee8ec11166e6ac490603ddddcd9ac8d02f68231d4317691734916e010bbabb7b05dddd3da4bbbb55d0dddd29e8ee6e147477370c275813fcd812fc58213f96043f76043f44102404422008fa2a7e3fc0ccdcbc581540f6c7fad817d603ebc2f6b8c28a25ac12b68a4dc22261a9d8234cd1c408bbbb4dba14818b1447518080083fa0f8f1c40f277e34f183891f5b7e68f9b1c40f258c3a0b8e2ea636dc062c495c41e20823daca10aa14516413c58608b6894245084304418820a60021e5878d2283ec03507ce8e1090f40d8c1890e20b841a63fe8f191e904810f7090649bcfdd0f644f78085abe21d32838467c8097874ce793a02efd5abab71c75b710acc5ea29c2f6f0c0cc3d4be420882b91f137c9f8bb3b885116255894644149dce04a1684c40d8fe48fb041f6488c5062e50643a85244111149a82411c21041b041081b82a8c1141a804822c5861f98f06e86c490c97f45c9c9f1b7f47b8664fddbcd6cd92d2d0005073e2ce90107de23800061a877c836356aadd9d75124f387935f799453db063438a1cb1b4ec525da8562d9870e00e107d90cedddddfdaedb7d3043b65d52870b7ac68c120f9c50c21b8d67113249538398fa57267bb873e2a40e1d64fcebdc931862faa31c8a2fd11fa1830b7430838fb5d9dd1e1ecc20dbe24c4a867bf68561b3577670246ba26c5f470f82b889d4e183e8c3890e3a7e90698f073c12b5d034cc2d2a3a32777b72906d6ad46fb5a6c348364fa819ad21808e18b26c89f8052639e0e005bc4bb22d461d30c8b6d3a965f43313714a9f61c4c0294025d3cff6e32e510f0ed9a6464e30456127cb2d85b9d978105467e440806558af16b800cb28bd3e0676b00cecd59280071a46378c7e4b23691b6018373518467fcf3e3dd9ee68bb991dab10d9321130b54a0b9e4cabaf2632b70b154f48c003d9cda67a6cc85c6e6a34370ef64d3fd72db09cbe74295c395a6c07befec21dedf7b6dd9ffd7d11c64bb1851f372e89e41e8f191f623b108b5ac34b22555bedaea63bf1498f184f9443500e596fc158edd3a7d129d47defc1b7bbfb225f5d987906cdcccc35d8a7623a3e9910e24a90bcdfdef78db17ad57baf77e1ca1c19f53d793196e3c9c85b0b53f6eb28d26f5755d55909bc3b36d84d2d3930bfc32a96077e93d63433af5badf1ee08ecb22cba724539d54958feee8e61bbbf7edd1d91285a5983398b298b5984316a10c6f51bac185f64a6fdf66ab51817fa6ab1f4fb6ac2c764aef282a3f95ea566f13cecc67bbda1b30f2bb9e9afb0d34ddb7ee494dbf490dde95ec65caccd76dfdbd5b9bbeb196be9eed65e44ad799abef73558dd73d5e6c6c1d2d774eedfecaebafbeeaeebb2afbbbbaeaaababbbf3bda1957842d7b508710a50c9fe94315114dc4f003b694d0e4c6bfa2fad69f72c84e5aeeebeebde53a7ea54abb4a6866c85c859b9a5d0db23b0a00e1a64fd7ec3291b5762e0eed1ba184d218fdaa8340877611ec23c0c8cbfca88f1b8219827d1d0b8199a2be58019fa6ec6ba5579f33ce65c0ed371d239f7d87e8d76339c721a8ea1349cf298777228c65d9bbeca1ff74ec695de188f5ed9dcc7683e621ec8e3d4f02b5d3ac6e386622c388420bf3a70bec8a1ee55da80d60fc5c887dde069dd64bfd92460012f2fcfcf80f7f2d68ba63cf07533d053051e3de6cbd790a138987ba8551f0188f3c25e8103f32f72e810ccab1c9a98ff52a04bb6c567941635a7c16835186ad593e48c1b184a6385880045610587eec11937ec6486d6f0cfe0179609c23936122c77226857951efc39fd5c84931beb2aacdd730e717c0ec78e4b58474fc61496425b0e426c27bebe735bbd35c3b9aab2a0052174eaaab98dc7acdea95b6739cb22399273ceb11df8e370389eeafa78edfe6a03567fdc6503b2fe0ce720437e4f2f27bd3c4e9d5377bdab0575e1259561ec6252ab18f87d1276ce39f75e13d0eff89784e1e0ada22e7749fd693b81441ce79c73f9ba7ba7fb411cd7746a4dbf23b21cccaf1c7a51d5ec4536633854d6688510bae554e550e90a134f8eb857393e20ce0b3c7ae0949e84dd805385a1d25b7b69e959589cd23bb6a339d6c278e450c961f1316df32d4eec7acefe3488fdd330ccdf93391b7ce594fe0ffc07a57455b94ebbe2537f0f73ccb11b104ed51d7d88e580d265e4b93e0396a6028f1e93245fb8bf993f549219c3e0af64d41183ecd21af8ac345668456185d364a73990fb43e99a99891c263374980d1d451ade70ca9ff38bb11fb4bfa9302264d7dd9d479100926c0973b5024c86b258e66a2f66635e654a0e7335391de355750e96566bd6bb862b498c08f96bbf6a52a59122a9d262bc2e7fc776fcab87aef1b0d85d7ee95c56655555e59c7ad53f2c074956f2e2d4c31e6297f3f7ded3c664c0a4320c8bdf0c47fc57c8cbfb21eba3e6e38514486f69418fb3cc9035affe613bfa2ea3bcb61b9ea1a0134ef52a87a2041271aaee5f6d403ffdd72afd77fc955335d8a915381c83dd638a82eb3141e6749c330cee611db9d9a5a551da13fabb9f1330043146f8e40aed092ee3981eb8ea3ef8dc2e1596ae0e8640e0d930e0bd77b914de63e0fd8e7709f1ebb252294ebd5df9ebe323db9f49a150a6a851e08a2c7ea58019258a530fc894b94ff3fe886239dc5fdb6fd1f5ee6c4e0e5f4be3c669399c7a3753f630bf6cf676c920fd7b0cb40c929cd902c4326c6820c0324e37ee379db25ddb23e28072f78727d2bb138904218424773ff9bb93bbc32a9e5033eeee2e83cd0816aef27bfdb234737b0331795b8bbf26821d6f41655996bda7eaa62c7badaaba11505597eccd2f0a3333337777373373962106d043b6bbcb362e836e6e2f62a3edee45d4db59d0ddcdcdbeddbedc5c5c8a8d37b1eb9899b915097666564581b50c7b9d83ba707763177165e6cefa08ee1c3bbb6aa6ba0276e79c73ceed093533af58cc0b5999e1c2558e7021fc279bdd99ddd904ade93fa1fc994ea8999662e4dd5b7298ddbdfb6f7b9ff61e9c4fd739e7dca53571dd09cfd2a454e44f5a59b933cf6832136adb48486fe7f0fc4b09bb2c5215e173de8ce51080ba2beae42777d309c54e0acbdbb3eca9ab9b32cfdc5d992633a190b0ba93203277954dd01ad4099eda31774ff1022589b5eb1a333be79973ebfb32e7f8ea179d99af759acc84f2d84f8ae5aeeaaf5f7f96adbbf79eb4869979d7693213cafae1c90b9dbbea1c43c8acc1c91e39f23b2d46f742a7b2b2ee8bce49eda6c94ca8784561ca366bc7349909c549983276ddcccd349909c554babb793233a34ebcdddccccddebc326426d5b76f754ea5c94c282e2ea58bac5de5d4e2a05bd7d9d9fdc4bbccccbdcbccd7114cfc74e5c8ec476d33b3bbc7d7c4467b77d77442cd4cf102c58d685777f7554e412b1247bbfceaea7b7a27e67ddddd7d839d5e5ac339f89d7c6d3aa166baff396f67659a32d70ba335a62c459399505c5c0a11ebc549278a53abbbada853bbbbf69efaaab2a7c0eaeeeeeeee3ec248e50cebc0bcecea4658d1c829b681e5235e4be3cd969b4df7bb1bc1a45f59982d67b4669f00eabbbbbbefcdeb025e26ac6e2b4370a05f6091e25ecebea66a96a912684ef102858b8daaaa3452e8ef75d6b5cd59984afa16a6babe54f5295ea0b8234a921811f25e5555bfed1e250b8b533dc476fc7ff69d741ddfe5502581449cc8c28526801f461b304d1c43bb7785d80409633c976236541dc529f6573404229deeebbdd74e00ad393d20ddadccdccaccdddd7df4a25572587d1b07e6a535fa3a2d6d38d5fa2b7f56794c27d40cfbc0d26d82446d3ae7849a39b96d77870eddfd3117116432affa7b9aadaae9849a794547a2bef3e1c8872b3696db7d1ba38cafb11cea2e3641c43c04f7703e6386c76b6938206f13645127ea5a31515a1300add11183a3c94ca82df2b960711196a259948495b933cea8eadeddc5ab8467a87a9643f0df739b43c9c2e23c7f87c3653b8c6788e5d09340220eccc9e9df9c9d9f5c21f23b77ef70d48d5d5aa9c348b64d7dc0fb7d3569cd5e0c8385d6ec3f1e60b49a490fdfbfb92149ab2a12894482ce3d84ae8af0ba2ccb415845e70e3af820f65c073b5226445942c98e54912bf2ee227697bbbb9d7b42d0833e291161c2459f14796f333313713a80106640e5e440be0335d3830962b00345c5dddd1d0a6883d87135113d21d8a8c4b6d16ec37beae498989898189877fd3072dbf978fc2acab61d66c369efbde7fe3dc76cc0c824ce39468c924dd2fdb6f0583346db245da601a6161d4591c2c834616a91143ea6d5978be24fda09e7b0d3c9244e2e134ef503c06d3e1d4f18ecc69a7ecb9ec52bb388f97dd7323112a867cc93fee5b7ea49f2e55bab00519649a096403dad5f9d1f7f9f2d7f62beffe5b7ec5fe4a645f35912a83309d413e6dd7c31f207e61b078cfcf177b3b785c678dc74d94cdcbb786573dd6a15f48a2baeb062f6b75cc1adb7beb10a54c9f687643efbc674de6f246995e65ab4b421995f997f79d14a5b76c37ad7e297a28ce6a30652755d596bb2b5257b427fbbf7741edd42c62f457a898204a99597f71612c27c848260bd3e413e413e41432207350c472116116e1c642e472eb9fce18f2427918286604d2205092161ce414cddbfb12461ad564818568a7285a24f106973f1efb1c65a48c8450b87edbe2d5ac8b22c228ecc1cb107b127596fd2ae97871816532a758c905ab1482412894412827d9584848482545028666560e8ea7d99b82cbe4e0b32bf5cae647409138ec15b2aae54e615e62dabd4ddaca6ee52c985c9b46469f473e95bbca985dc786adb32996c7221f9da9661b6f4d76fc5fcd8c98f4c55550a7f952c8dea2111b78ccc57b07f2b3db3dc96c97c7f3db704e29204e259f16fa66596f995f96a6b98e5afe46acdf2c5f52d23c3aaaae25f25dcbdb5f8f7db3299f065b865bed430e677490b175b0b17d5fff44bf5dfd58bdc2598b4b6944aa5d225f394ccea21a623f3cc428395f6ac97918991312bed66bb25b9a55db21b1073694ba56b77c99eb0e3f29965d7632f972cc9abf4ae84c95db2347697ec125f26bb8445112d20c330dda8b27c3806fc5209fec2eec5b272b1ec09f0314c677de0fbfbc07ef81766033a66c3492df8b44fb7dca3f98379c9dd87fdb95483b194e243c858843062fd1b5cf8f1b187fe7cdc7ddc7ddc8f7e18c2f70db73c8fcc0fd7a8ff45b846f3fde9fd4d3091599c7ed32b97fbb70661de844987fd0f42e8cc4646b39fd4825b748b86debdddb285c310b11823c6fb241f4e41f99e8576fd4973f126ede561b4ec4b9a1523b325e6a7baa6f5db8e6bdb71c5df803a46991898c5be04d3fd72692e34df71a9151f231896b1220a22f3a71641411464da4c2d22829509050d4e28a1cbbc26fcf745474445473e8aa218a2280a1a8aa2301292bd7e7c798b44daad5e29c6ab7456affdaa5769a5b7acedea7ddef78ff53ce6abaeb7aa0a5632af82fcb9dee281fb73bdf5d37a18b9f1bc6064e406c496bc7e576e2db0c0e3555b077a730fc4f3ed836f59414be37dc3e02a58fae700500125bf5592a42483f2b74b02f17cd56f0e0647e9fb696ced57f285f58de3fdfe56bf4115849be9dd975e301d58fa52efbb078049caf4832bf3fe07f6939b0648a4bd2c4bd3795d572968be87984ee9ab188df4301af6acb1f8a7b9571f4ebd64b3b2f665ad17a1a5b101c10aca9ff8efabdfaa5fe71450c77fe917f04befde3b20161aa656a6bba425643de97d849686da20398c0199e6a874eddb26a95323020000450193160000180c08074422d1789ac549d2e50314000e71944868542e8e47429120c6410c06310cc2200860082184010090610a12c406f1aa297d7058837f8b1b6ba6a3b8da89d1f84a5aa68b30e13d60385e72130b19bef353782d285777e3bd89d566e9052d618c076c4c808e8500728c8f263a684805390b015d0acdfbce444428b4cbfb0f86a096e182ba0791435a78ad3dbd979bf5724751718fc17e493b7bd46a4c5151462999718751b334a9b008287b845d690e402665510ae7dc076e317093071a124bc8174783f64a5b7d8e745ae5c15166fabedb2bf5b747fb077332f64217482da436a5fb07ba04a95cd6931ede4c49c1021eeadd3b99c01be9461087682e8cbcfc22e0356a558965f15425002f19baa154a91c6ff1fb49aa6e207ba3d6d0741af75ac4034dbbefa51eb864f631084ae52be461002f6f6e8208539d893d6672ba87cf7df15a40878ca5f90782498f7a24db0365ca3af222b1e5c51a7065ef2e582a19fa29cc43bb45d58198ca7179976ad19587758125487c092826a557702c42741466d2d6a2d4e341fdd4fb54ae27b63eb3779151a080d0f83d01bb1b6d17bc62a79aac957200a35828c9c2f2c4007d474a70f84bf8bc5e099938c89c821ee590c6094ca0a1bb517b2f5375eb4fc18f852631266cf9f198566cfa47c02c04df6489964ba4e76012a1ef892d5488256fde05fb9159ab0df7f5be07661c81e400d9dde857733ba854fb80b1d0eb88c08490951e422e08fb3e8ff9c36587d2a368ac38febda8643f72ba3da01ae40e32bda8c30b3d3e04f9316c4d0218c7bb76e38c00666d68f5d0f851081cbc539d666f27282a877c33926ec27b1a2a72f53a6d4f49e924cf03b6c93234e8addc105a576a3a245d155571a7e57ade80a5eaae159affadd15307a1fdf323ebd23bfdd0d41df1ab9892a1bc612c95d85a73749e2577999523d279015efea0c24817036df00c1d3b0e0f24171651f8e371b98c1c041698571975608392b8da919886024c379bcb3bd654173c928b169d6442dc342d87a587c7098b6b1fda20fab51f7490a56e2110204efecd23031460ed27b558f93b03e30316436b0864d7ec293fb36e78c9cd36c48c6e348b38f1085c2ced5c7953e8944ee44094d88f46d159b1e356650d22c3eae2510c821ccdfa28f074cbb487abba532896739b645a4084556515565fe82e0e94593cef402bf53b290061303509286c9fa877e1920b9feefc52697b99c4e2e2359c86e5d380123a184ec5c8a539fc1c14b4360fd0a1701db54820bda9385cc04ecf9cd839f1855ce143789da8752b4d10f49c1625745413776030ac05ed42e0920e1f46f1f0fe9a07e14220e3024e8f1a6a83a4874d840c1e92064360b25b18ea5508620952186ee4bb268cdcee469e32c41902314b6808341ee860598eef790d81a3aa6dcc817657d882e1530a41e0f0c8542d71f0136678678e4f6143e00a3ed6566a56f861b9f1f16bb854a85b3719fda4a9bfbdb021d06c157023086ac699e1fe5a39b061bd2078d2d0a8432037902ccc2499e61d02338139509b232f18702102c184fcad04767f2a37c75fdd34e70e8106fb4afa03aad5498f3a7d2fb07505e7326067bbec08ce7e77ac46d662952ac54edc215056400a9f76d86a007708dce721707a61c0a0a94ff4e1b6fe98c57cab0d0f814b7f58b76a58e2a78d831c5e97a41f026593c41b4f6999129485c1cacd6522b7301a794364571d8d5a601a93d1c4177263e19876c77e4cdc38154420d854e1544c8c8d260b15040411c820f838bfe74b18f69f26eb2c47b35e9d85d3e48004f942474544203218ac222210b5441e1b9b8e8b08dcbd110bd5f2cc214a03801d657bb38b5b6e6fe250461a5d7953372ba5a2bc70aeb37ac727f709bd4542bd3e491db35f39fcadb71d0b844786e5967bf45bde123f4f55163a60354f52c7977c270b68217fede7065d8be2bc92165cc567c219465ff22ed01012798b33b5747624a60d3acca201f1c5a6bdb3fa27d06315f58a1cfbaea4d1c465e2c42aff5b23f435a0631daac354bb2a25705df2bdf38ef57e1ffca72bc700e163293633940990b038e33d7e995d953aabb74bd20ab9785690f07ac424dabb6fd8b302c5abee19e4a391261ed6289ab4a4bf6070e8176b92a1fd8570b2ce3bbe1e767eaef77610d549edada1f17fb6211c91ac71d38653810bf6c5680a2de393f36e9ed5b0796a08086ec44691d2e31bceaffc707dcdcecb3f862122eac32dad881177f2a4515a068847bce0ee0eacb1f7c21de6f98910a9c490c28f13bd2e80134bbb6699625caede7908fc03f915c2f66c20d65633360423f2a67871bb2ca104b501745a6fc388e221640562f9cecf92c0c7acefde7ee1bf21f58bef2db0ea057f697aa762c0ba936ff7a5c21d5ad98006c532dda13e3201c14df00115fda881f9144ce52e2d3527c7400ea1d8a396767527e8e7aeeb98ee81565dbffffb40911fc826e244e9a87b06d2076ab72ce7f49a2a60ef4e33a58b5745c7bf0267614e4a3fe21ddca8ad2c5fe6385f1101f9a1d3017772494607bffe0858ec2fbb17329e13fe79b007353df199e0ac836f8c071e88e776952c35e4cc75c161bb3f9eec6d83aabfe464b244a6f7e6d74096badceb9011498f1dcf4b788a70d663a2180596afdcbda721f720ffddbd7732ee5e144bf7dad078aadb8b9a120577b8c8f47acf855e707244a29437897a129018e41053f5d7f55e89737475dd2c97f56979eb5d79761cbb3994822ad2becdf46c2b03a715428c76fb5e85a0bd870045f46999471b4dddd8cd65829ee306d414a3824085a0413d8a4fc51f1e5588f71d11fc1c756897b7db57395c75613b29bb769df7a63bd29e5be3c8a5a3a63ab1aa3d63df63eb34fd8f9b5bfa86d074029d8e3a9254e795e1d8053085504adb3198ecc0a5155986b2ef0d153c52a9b22be2b7dd548dbad72b661029bdf63d0377c3ae55ae9c27dbf780300651b46310771c32e9eb1d930380b187b4b37d4f522ceaf63dd9dbff8bb69d79f81caff1a21a6b4df34c19f168f3e451c22e02ecc9e699f81c80fb0728a7c990ff22db1199dec04a7490cd48d048a10598fe928ad42908f6a9076614e66a0dde42a3be6764c3a7be37086077d8b95e570baaef1d5593526879a24e51c65e60505281a52675e64dfac36972f5bda2d205aeb24b89fcddc89901a0f067cd1923109d9f3a5a790987d69c9eafb633374e402b7b93d0f7d4d4ddfaacecccf41ac81b272e8ebb1e766e944e699b481b8ed4d3915cbbdf40edd46472a554a6d3daab6ada0265d16e4572dfa07ac3180234c01eced2d9841ace056f5ef5f0033b4abe77bb03b9b91195b55c7f7f6ffd810c98ae44cb3b55c7f73c26707cafb53262eb9aae7e3f03ec5f90f848cc4442fcf1bd42a67944a84d81b66ee0ac2106dedc0aa03f15d4f75e18b10fcb5443ca40c48df85d853bbd8ab9ee10903b86f4d226436f3c7c8f9c637665e7bc5183cf5f696bc82a0c09cc2e790794e507e7fd1569f2883364254a40146aa627eb762807f0d961ce0871eff55866bf37c97056dc7b32b3e2422e575cbf1fe8fb14f7de1151cd3e0ebf3a0adc1e9481956d71c96d94bf597befb20e4106db7bad51512fc3528559a37826c26053485b1e97b6363140267bbc0fc087b7bcc414125fe1396b1f0efa839807f9b89a4b4df103e0d4f85f3aac66e55cb614a70c619b050d997cf7d0342eefb45e1918dc39ff576b59e9eadc73f6e1d8767cdc006d15f5be80dba6cb34b2c9bbd511da8b12d015bb2b3d1a6b8df0439fd50b01cadb346847633b7e4ad74a1d52ef226cfacf220128c61c67540031ea32f3950e57e68a9d4121125bff0cb962a7879fc89a3ef1a25ae9cfcce3a750e46fd17afe1f31b4c7ecad1d1c1344664c194ba21bbeee417899ed7e8455c5da0200ba6b19d5976db63e86a947804f1832f8c7e3542f9af95ad0213a012c719d222101772ce158cac31155f4d9d0b871efde4e1e6c07db8137eef554915ac339a19c8ea83989eb74353135c6382bdaee017424dff859d29806dad02e4f1eecef495c5748264e658b2b8dea95def39a0a5b745834259635036c67940747d7ff5764e5ddcb1b4ad2916d536092131f90f0669f885fa2a198c3e85399489dd3a22d3a7864c925379d802b031970d327e679575281bd2c06089156fd18ccb57b04465432877c4b984f6004832a1cbebcd0e5f40cb52ff89ade584fc991727ed45a169d96a1cd1ae511b0735cbcf3ed64a1c21455a7b14665e62fef750ae87b139d328d36bc9d33598dbe69306fa9135b862536e0cabda9d55f5ef35f3fee55054054d17a0971343cc8e5220284de932052f25913d1aff87041d432156e5b9c2b5ea4e7b47f04f4aee8473f00f769502884b777522464efb6db63c975f124f85f7a7d820d35a9d3f53c51c44c567b913182c368253450af440ce169f251f3308fbe85e0615ef07758a9b90eede85957f551d5dd1ab8289e42c7fc1aa9a98b287aae5ab60dcd4e163e3d0eadca41c5bcb70279888a79c7dbac1bb214bcfb1c62a2bfb6ea5058ecccf6d1d4d8ee030ada008b3e745b82ad23bb20bef8a5a7b43d660fd4363eacd8bab733a294b6bd08bcfa2781ef286566740b629b2008ad6d7f88988a8e7eeb90499e04bb7c596ec7376855b89d62bdf040f91c360a6b5cb44da441b567f5fde1d40067267561a985dd508246f403308a3ab95fa33234e409b8827421f3db301fd203b39feb11d55ecef8b5c8ef5833148761e1c2638d6a500d00d09e78800257c8bfa89980777b8ad6f974646ab90d6dff4fea9b41a7c3aa091b82e7051aeacce5f41840b9fc023c50a5a00319c4728de0795489cae16fe5c4b7dfb9478e05015ab7eff3660a73fa8465ab968cc78e1f1cc840392c0ad7963d68e4adf01c3de3de5c3850824e8206024729a88808b6c37243beb2b739084c9f8d46642b4bac269fd0ae9a5a149c559dc63cb90359b2f5abb55d7b3b43a64a8139261c97ce14a683769e12fdd61eb0a3600f3ea8e6601118d8a3d70b1477a9141143615bd0499ca247b0bb8f54c40077eb27898e2b5c65f898198611ba7e36a123d67bf3a730ee23ee2c24c5dbbaa9729801855a18141988b69278241dfaf14a5aa05f79a872d6e1cc567804aa1f3402e6aa01c076a1ab90e2437f4fe1c5b23148c29dcf3b95cd74b6302a620d8f78794c487863e06d08b66658813fc595aa9982233e541757c4f578767586c551a80294ae773f91c004549b4a254350c7fc446c350ecdf946f945169084fc9a106baadb71bf1521c0988617b131008174afe9a2222f1ed3096ae52bf430c46608b919836842300ac0d4eb56cfc3ec97ccc1f4474703b741e68351e9a4282cfdde6a4266ef65bbc586f80899e0d8aa2711bcb08ed56189bdae174057fa1472bca20c33621daddab6352539df48ae4d1d62bc7adbd5c5bc3f9322146d906be5aaf96cdb6a807c65873f68e4a82f14ca4795dfba20fc59538eb0c32066bc6a3231f0b3e50b55ee4999ee027108ba4f94e7aaad70eea4a8554ea6b5b01d357d21d0a3d883ce9371e0de95a000f3b0c5472fba931d2bf72b12529fe89b01099fa552ad4152607eeb61fff9115e23009eb9efc97e5c1b43fed8f2ffc3272f251292b5f8c442fa56d9931b1fb8a71f659affb0ce803f4add86782a1a456384fb4c37d4803bd56a832253032eaafc4766f875314885ad271ba52b41f2b97ed8bc184cd28ff12636108c9e166ba00c8d9b59e67e70f843aac8d53455f3414eb14808ec9624807c2497c2bd6b7856edf3dc97a95b37e43756d0581c073d4408123ff55b2e4f95f3584c2a218256b8d458c9e1da4d4d6612adbe236b9ad39f21eaad1d7bee0606e077d5fc259fa8e4922b74e13fc2961c4fc4467ece269be8213eca93eae941a9412e00622e6bf194157a26c0909de8771e9fbca6fc08f05f00c2d30841fdff46b425143e84c8f426bf134337852b7d6dc827962095960082d5cf43fb0bfa9e2cfdd74eca45a418b91d778bb4e847d3a83e22e01924e74972f61b004ca64d9424207c18735508fe86426b2f6479ea65a7ac009c223ac622e4b2efbbcbbaeee5815b59edbe9c113d4fd959b7173829886936e0db61e0ee2e2f34b374eb6f1dc066f61fa825e0a3dffe1943bf8452d6990c1d1301f9a07cb4f3ffdaa600433df0506b2da25936cfaf521f384d66b220948ab035949a21b22194be95e277e8b2a1febce1770751124815be31779dbbdcc8a8a4fb0a21d2cd2d38d0e282fa307c012523e4e748d016c5439a7b3cf9040d10101677af34d1c186fb05f2f550c86c7cd6e5f2c95d8f7270ece6296837b72e18dd5e329bf5bc3b5f148bbe2549c250afdc0ff33fd1496919bde40bf21ac1bb93fc134eafdf54f9e2ef548d50d4184e38a24fa785c38f3d0b90ec02b22e4aff4791e0d84f44d79bc2943f3d6ba05fe81b9e8c29735d73785a75165b44e87f97c855f1bf2243941a2476b7c546e1bd111e8f32d23ac04295164a30ae3ea323621d160121315fa477a009e0f8a3631a8bc0f1fe1f31dfc98c6194f9efaa4d1e11c456c3e168bd69a22343c14b9fa941dc2b4f5189f661524d16031cf4b80ded9ecc1cfd1a63ba2cb48f4f205585c9210fdcd8f5303b8468a578aca753ac2c3718a95422f90978484f6b8e75971df8a7802437da2471cc0d32e4f9da06d16f5f378b7a07c9044265ccc30d2f41a1d9438e698ae03ff1091b92318bd03ae352aa3472f11a92a5a4c4c953ffdfc9f5f2535f32096403073f577e78d53a9846f540ccb4014619cc95a510afa1c2c45dc9bc923575d99f86336cfd6533a17fa163a103c71e32d184044478436c4478cb4c0aaef9855046077bd3f01a658b10ecdc906f243b6ef4123180a6ac5f6c5c451781510550ad0b3f776a403bec80f55595c61f5ae9fe907e63981dae8a25680d32cb6d79479293922723454a9684843c12728d0472039494f9768162f7abd210842535f11a37dac89963af80755a33e8cb09dcb392c4ca679e4bc7eab544a2de1e356f231f485dd6d737dde8e761403121e1602915b27516e43f3d09e7d49c4f9d4a711d53e1709cff8168058de9a6d3a6441d24629549e314d0a7ad95f416915ab7f9f9b5c64ce3769ac82a513dc0b39269c476a6121689b77fa09e4ed8b57f57ad1e454e3966fa53df61d9481e38795ed03def61e9385ea20d777c3d0c4ccf4e7dab6f8647ed4578bcc3206889967c4a0cc01380f51769d2a05485ec3b5ea8b5f47a7e5535f8440208af7475c68c74887a235ad4ec67cfffb955996d405fde307c0224454a26b57c019163ba9a98b1af1644709ea283f9958db02faae7dd27ba56cae4ba0fccf2bb98c322837529080f85ff8deb0f52fbe82f363ce746f265da0656fb7d7005b100c023f2c6b3b307f92b77653c32b5c07d069b7c4d15ccb972ee8c25a193404cebef7bf3443d5be6dc253ccb7b27ca9ac42f286d959372c1d86833c4ac4ed5cb09409685306dce3a3523959710e530e7aaa346d468f30f73f3fc1bbe95c10677ad977ee6a6f0843333d9830fdc7e3cef52824d1bbb09ec9c88352d6fb4e596bf4447617472fa0c9f09729e8b84d48d507aaed8d9579c5b0d5106bed65287549b49b88a9be1fa79b46eee6f94a143c3b83f6cf7ad2f8e14ab566bf7fbc50048dbfdb489dc12f20a5625745ffb432acbc42ac2dc9545cc8254884866bed6f19dd620b78a3d8752cb94e211dcc8d157781cf4f98f3df22db1926163c44d5cbc11ffa5b90fdfabf97d213fb25d0290ef5e09a085e2a10f8b29905040489c9b928670bb0ab99f2e5f6692abf674af09dfe01a8b1b2570dc20f316d57554749cf73ca66b8e60f9e6447f6c3acedbed20e6d2946037b1dadee565781040f2de70ff082e4e7f7571e47c1fbd9b94101bca4677f1036bb5481d9de3b7dfc07b63896c8f30669ed166d2235c60328fddc9c5ab42b5429769c85e96a6b9eb6d97b8d12da6f0c2b7b4b125f0cc3f9618193d9904db3811e87d324c0d4073c209e10c0bcb572e855cca92d17c8329198b6a6256149e4b3c6c317228594eb2756b6aa1493da7b0bc9057cc1abfbfb8dfcb67b13cdc83ecfd007aa2f605f0b29b60ec33e9a3359e494b5d798f89671c56ecf004f45ce37d5dd2bac0aa8dab3a04cf3d683b1fa7d80d0e20844a72416783e75ca09cc67ebf808293fccbb2e4521fcab5f21438eec964cb8250d17613a8cfcbdeadb8ed15b2e10653144caae8bf38b2caa15465abca16e79258e84f8bb531262ec0040f378f58ddceccf4b320c47d04abdbba5afc26a49c7cd2ffb6b96ace21877c70a9816edae02b0b308067076f1b6675ec21ed5480bed64384744fd808af4398d4380effc261f080c3be8242c91925d2ccb7edad2a3dd2a55c209d40b6518d8a55cebd2fbc244eb96bb5080dd82f918c5580e86a12b847501e10ad3ad03b61ee6a03ed628f8d7c3e2ec1ad73b0bb5789bc6b27a773807eedd88c4e92ae11cefdb3aea10478030e1051f85365b6c8eac24be9d003dcf8017c2e00abbfea75569643d3ff59db419839bbb3aa75a9380870929ec1aadbf6e825132f2255b93901957a38d3a77f61b05229942c904a38447c102d8b9c4fe19061585961f3f938a814902926089c222f70d1442e0d5ce10f87bb590733201815942cde74c20509e5a7e5e9011bf35c1b0309761c224d663661adbc10cc56f5324dd2b5a509b672fc54881810c22235756b749caedae0858a4081afdcf86fb47306f7d406a61f0e019bde2de7b83b6f5f8a3ec48513de8328d85d2e3c8d97a6cf9c2ba6318a818a5c2f76d9cbf98c0f9aa17175df68a3de374a8627c5ffba3a4d0498cd563e9683e9f3ced7ab3fced4188c2fde4f8dac2b40e075d17f2cf69dabff933bdbc9189e3108251e803094db7a4e25b3263d8d29cc628ad3ec942a37690202f5a14524ccea7fbbeb17887d99b04b72a2784445acf44044f03f92fc297199e5032e336c0f3f24ee3785ad4dc2f156a5c451791603cc30b545ac85959b7f0c6e076228b017a2ef2d9fc3dd9defca711cdde4a322f65ea891c1cda8d859bb36e6b13fb45194053250ff13f10cd6175936ab8ab94230db48beeb2c01742c163fbc2e8cd61727754542ce781e141810ddba270484dba7ff9a19cd6bbbaf91347ad10dfc7918c7b3cd08d32988e3f0285eb07d101e2d488be85639714d337e95086150735b08ca8a8ebb3f972940beef9e6e75c0d7e746f1fab476fd2c9dd95d4e66a41180ca87a6d27fd8b1f0322fb6a267eb1ea2f93493a9f5eede015a7eebcc36360a62bf9982edbf8f5065b008a74d56aa152385273f06e2bb88a5a1a61c5759f982637ef908d4410e342ecd03968407f24fa2c3ea2c2b7c536913d231aca1d4030244edce9e1f0be8263bbeabadd8c6673c88e70bae8dbda922e4204eb99562949fabd097b7255f89e84f8e0275568b7f643c6c4c7f823f1673afb25682a8847bc0c57ae84aacbf84a5d3ba0d209ffdfcada1d64b5be347ad0f9d40d7ec05f72b91ce11ab384c9868097ac7f0488003fb086f9ef9c512b1c1a7b0fe5cd99ad528844ec922dc3b7214de776672332ff0d786e865d27fa34eca03a3aa2c49403b139efa949677256f87d06059f0bfd381484ab9c1731f7edc19688ad152869a3dbabb20e2c3df9b289ff214439c15b21d79b152f6595a2e421734dfeb17ffe9db0566aa4ed4edf8b1a740d0251530c8d79752c592d9038a1b1506f41051a9c0f67b820c5c592a98c3000fa59c7be13ba494e9d9b6fab0ac0175e50b88a72f38acfe16915faef8db303f60f1be4162248690355823ab15a742ff15fcb293fb096ec3e56c77181e53a3a9a8216a71e7cd856b8e6923211384bd6278c779940fcc9bd9561708127e4559d0728db2c912f6bc5db394f771a031b78d2b33d862a577928e4976418c2354849b5812a754a83eeb0967e75a9b8e83c31c47cad326ce86ae74b6613d596b8d121b564c36a0056ce4a14996e4a4b9ec4e43d6f41ee02f6e8319fd1711f3527e1aa729daaba201553e5ded94ba843bfa74512e7be812e34420fe6f64b829f3c9743c5b459d559485a82852a60abe83d423d71c35634b8923ca31b3b223d3ffcabb8231b5f3b427f5929121c581a1e75ac35d1d6c0f2bd21412309a3192bad001fbdda9b089daf33250c02de79770cf29eb1b0bf7c2e1e48e9aef9aeebdd1c55d1032baed57790d606f1118ab52ef44eff45c190fa0c8619983d6ee3779ff925c9022602af2b4e69a01ef3e18ba5eb2ea401fb77fdc140df2ecc7b773a1efafe9d445f44b50546cc49387f0e88ac357e677b58fafa7947283918669464214686093ec26a830e465f3b84d395f5100a6e13a16b3aa297bfd42e94adc49a95b2ee085bdaf5ce06b59578fb047db6b2122dbc3a90d7f3755cc41395c8c468452697daf9b69a49edfb787689b54dcd036685d7ada809a83be54dad6b5f61bae0c3fdc934b6a8174747857f2791972e43f9d6fd276708456c0586c34101c846ea1bcb799849f625c2efc7d86c7906da8ee855c77839c36703f8ca5c5d1652139c3a89d3b20e6d2ad9304f66925b65cc3a484ab53e4f97896b828966a791a995e17c8a371492f75bdf108c9d4097f3cda84a723109a55f54227bb7f3bb1b8de473a1daad80496c8ddeb7f3a81db77b23f0a017d78761044a3721310f239bf9388465738b1145e0885d05e9d5f13d1d4e4bdc19d588a1da36067a32d504c1578d85131b324f6b57f02dc1f8d8cd76fdd870b0963b90cf11e23474dcdee4bb3f47e2ca86a2282ff9710caec1ab54b34ddf32816dce851f81d09d269299720a1b50027a48489c515f9e2a938ce0e38bee651220dde2998957573ec2947114b3f45ce9fa875fd072e86df856597c1645ce5970fecd5e83c0c1741d0a864a903c139899351f9352d261419d141f235d6dc2b88e7ac82c92735db13a4ac61b1a339341c24deaa442bea0c29a9a1cd37754def2941dba0175d14739d07b5fc799c3303ed6e9bce1e41209430484ead526fb86d2bee5024804e51edb07be4b922341b80719e56ec9ba7a3487b0e56efbe3c44a2b5d255b26a288f9cbd14875bcf109358f6d94a2b187e8c29c9e0e41b45cbfa41a57e59283e2f95cd09a44d2273426f781aa13d127527adc23157c233d9769def98dc85350b890441444130a6bba5dd0a5a93eaf6570e6d9b1d60112cc12746b14819d481ee156f4ef1a5979bcdbf41d0b63bc59dd3496131a0a525a53fb462d31245d83657185a1f25fff1ba5bb4e025e54b122a16bc9a41ea06ab7cf7116e2f165b035f0c8c5bd1b2bf9501f0cb672f044d1269bd0cc5c3194eff5c33183433a808bcebce0b63238f382e3d0e50a6c3f75bb3beff915a75dcdb65cf4f4ebfbad1fd3818cc98021b97ef82719880e3a543458f670ef2e66e659c7ee3821a0a5f7477cbc788450f8c1ac17f75377a008e874a871f270447082d13b735c33fcd64e893b4543aed7aa884e49ede04b0a5614d690054598c396a8553adf8cf04516375e71a97b5dfcce23997010bed2407671ccd6f5c5c34dc85f37b8951d8b8c46490f3f1f711cdb54351c371127b701ae90b5d348714fe1deb44a38016b260062297a0570382882456d8eb966b5642d7405e67b5993acae0f4d15c0056961bc3312c83e2c239c8e50c5db9a040474834b2b27385abfa722b3f835f36cdbf842978115a1ef4619028885688133ee7ee296a8ea8a376fb238aaa9aed3eaad7377d9eaf999c30add212e0cc28879e8abbf4d6bc6082d34505a4a3472eb368d6ade9f5ef218bfc3b0f4b79c5d64a595309ec4a458c365d7550b046887de09de7da15e09dc94ecf8a81645290d7c1d827ce3a8d59d84e0c086174547b4986db83779970073d853cee80b1405b3eb135ed0772ebc36e1b0072f4e4dd89e72604917ed6a1a09721a59fecec341b88fc71ac1e1202f88dc8c8d64901e1c22bc5121a6222d77d631c75a952b86076a884b58527f4d3dd81a8fa2000c8cbb833a19a96586ed27f3453fc133dcb4bf4f950a2fb54015b6504013411768187bb49c598492996830980a6371ae895c39eab3b68a9e26105b63b2165765d9ab9c9c1dd296c93707a25841f2653c7ec810a9e89ba380f009aab99d3aac5a55336f98cb023ddbbbbf3fb62e820805961d2f7a143e848245fa28a023c8bef25288e0c32b9259cb9651c6e8337b2c9221ed24510bd6a75b48d11d6e15f88e32958a2d36cd2706a1676778e6770d1a16332704b3ae8ed081c3a56318610939f982c22ca64632cc2a46daa4e88348fcd8aaed0a6084bd1a761fb42232f37d25d4c141b80efacb88153b622be74d09c355d39958764b572d73a64cfb5ffc87a5886a3a6c306d6635e326624a0df57e32c7e3c8440199c2e402688b22c2224477a6810213a9d5b85576ec0bed1cfd3690d8b54f22355ae79e2bfaaba2e9961c523bbda57306ba8076785bd191d78bae262bed344de3d5a05629c3b3a63a1ee42203c0acdd8813cc7e6274375978cc0db3d55358020ba6cd237473a28562f7dfc6db5d9247ce3e515e48459dfd1ee7cf4e799d536843cde88a778e77eba2b604c747605e24dc513825f80e47ea52887c1c7ea15f623af05608cb8b6d289bcfd4d606bd7fe56e550698ebd801ad51146056e2856c8aa9c997a87a7026b0bc015fc31aa6cab23fce7b081ed2a96982d98db58ec622cc9f11e2ef00e07253e5c4db2ed5bef18c70a6740852e028bb9e058a32729617babe66cb817156a86bc0f78c05cffa62c81981848d056549f8b1dc64e41e7e381ae3798d159603d0c61b20f9bb5e447515e65f3861cf4447bfc5adb01a26f4ae111f85cb587e4717096cb5a8e51b037b04a3bc66d88b0ddbdfe542c502da96b077d82291ed1475621dd916cba0890e78f52c782f89ea92f462be2dc644f461951583558b774c0cada65222fcf8e14a4671e14a3cdc48bd919790b3a9d1f597f3758ae9daf3a95814a9cbe7329d7aeddfa0405049dd4c2e38c003a4efeb9a209469c2fa21386c30b01260fb6874ec62d16cde0a7e5eb690391de80c0c31fd3f8af845e089a4657d28e20ee19aed1780efd5448136000df9b664e29a20d10725609dd0b0a984e890d1e47db8798e3817b1ebe99688d5ce182e7ce39f894ce7ca8001bb761fbf8ff9b7e5500edc01a12d7022889fc3927e1d6e0604933b93368261315ba516c5bab6dcaf3e32f25fd3bee28c9d8eae48c9bccfe7884e91374b33cfe412f1913a088573d15fbddfe164fec344605ca1819240443ce2ca1051c8898a3c2b9c2b01d8f8c3747d69e26d9eca69462c8a51cc92cea240a08ba5347f0549287ebf7288f5ae12a67226ef20be9b9ed8f53d825a3d02c1ca8693c4b2378057c3438138a19a4ef1636d3a7778224c6dcd0831515fa10b0ed96a7926d1ef04c0eb2eea7ff08333a9691f4970a5a44901a7ff9d26378d1d81c2b2a50b3c851739b5ca54bb29a597e5d3d58a9734e6627dde041da2817451fcc18e3a2f95b85662761454c716b27a1f4f8874380d3590c60046d98925725a068433650513ce2b2be4e81321d972e87bd6972fe16d35619907a5ad373c9b7ded7f2255f142ea67e31c317a10a33c5892f1d849a0ac2e59b4e346576b9aa8107e2c68c3dd4403f9d9041db3b5c5739ca9966f0814ccef447c69c9d724cdb2ed8ff56433472b317ba3189e3063e1505f6fb2e40ba9f9d6bfea8c87e04c3f4ed6969c58c21437066724103a7564c949a83b04d65cf5fd512ea8d6bba2cff41cd3ad1ca305ce4d94ccee8cbd0f73d0c77855933c0c329570e567d0b9135a122dad6115162c33844c00424ebc53d1ac6f950711e9801c5a225307e903755405a3aa0b0c40dc8fae59f4f286f905f1276f90d6e1f23274cfb54726fec389543779abfacf69a57b2f3bd84e05291843bb7ab724293266f8534237b864c58a5c55e497cdd429b901268b02143eb808aa76b2f806f563511813fddecf2127aa69b733ab568d84c1198af4f265b9014774397682cd35212a09526661552281340943040913a69e7113c92445edd73f18b0e642a06d69c80bb95ed3a0b34dca92959fcb8d6647471870ff16fcafe86194fbd45519a116b003313b6158aeede3e7f654d8430d0e4350aee2d952a2f6bd00c00e58a0590f1e4431c21dd444f01f2ad1d8aa2f607720ba18655fab147f3f7c10797dc82eecda0832947814f0a8bfddaa314f897cd38144c7d7c4f8db7e1b7170b1cb6024141718291b55871c74c5abb20b39a138c827f31921212c5d29fb51de02a315d0904cd39c382277b4529b36f8c7a91e0b25161b008eb617f4b0f93c0a30289ab849ea08b2a04945ea5a43344891bc1aa74573d1078e474277861fbd63074301a366c550549f897c8f897c341cee3f94a2bf786fe937e9dd528842547199b6368ab957af20dabea902d0eb9ea646074743b97daa0ef46b8094dc836f72a828ccdb174b09dd8212cbe7a2d2341aa59886cd13ac88f0d99b8f523eff0e99111efc687fc0967f92bd9353a494f21a835adc068d6c7b80f94ef41bb8803e50e10b0369b2bc797bce7e77115e6bc45d0d11477df845b56c97fbe220afeb296680e5ee0489661939e25cc1beb580a7bfac299a370857d57717e0d932a059c807c42fc713d2e80b464565d2324d6edc8b2be606c3cd2ac1b07c78e961314c24b162076fcd728824a861d07cb20d1fef09fc1a2d10e58a62b2da500aa0dc2355831b452e458d5bcf569b52c870bed62af7e585bdf5ca173706af17793a34c622d147610524bd55e459d0b311f4d797b803d6c71dff0f40ba999eaf27abe3cf0c8d5bfeaedeca4550d6d40e9742a8ec069a29b07a7ed27a2f6afe92f0f9801a1a372fb818597847303a733af21b79a46af56fc680f0561b858e72ddf1a357eaaa4dddf0409a5fa573b0651c148e24bf1b0d4ce29d06fd3ea23a279aef4a45e0a604b2f3ca81ba45b71ea087868e4c45957bc090e0cea27909c80f804dd08a35cb7c3eaada0ffd26e1a1392853ce6196f4eeb8cfb28d748473f99a3bdc2d4122b8e5e209694ef1853462080dab833235a726a66c628bb7bdfad07ae93042a08ab3bce4c819d73d399b1841f3297018d39efc5f8a8ed65eec8bef5e8c44462a0b43f3fe59550ba09f91b48659262f7f68428cd57c15135ab97288f73fd893896bd8e7f9a68953b088917d148a1d61e5a9729ce52e0cbee1f605a51f0cd17c56ac6d9ee450684a53faf7d87c2a2f36121eec289ecbf96b2b0b88847aef2accb08ac3ee4ef75e7be126d9c3dfde95f7c2888f7ced25fc097e9d77681c05be95790dea26439008ee49710984d26ca312faa33016a436515fa9ff8c0ae7ad509606b44820841768f1c29de61080257a3c66ca9d29b1b62d07dc68c43fddd8883fe56545c11cbc418428a2529ac08745fb270c7f4816d69e3f6bbc1fd3389ae59653d9a39f98c8c01c246e53bb49afd7aec93168d83bd149f8af58d0e9e56635972e4e1f2b2b9b19a451776ce694fe764a2d2f4e63989d5b87766eebc9e758c6b08911e20760f85e36a5dc1682a354536c1a8efd1fa573ab17bafdc04f418396b88fb7fa529597a64c2649fb488d0efd13846dee12b70ecca404c8a0fde255a2b164e9e97c1cb6472e1ee15f78a436468a01341800d11e140f4614b254f3944fc04e39ccc0d9dd076bd1ec4834354c23b3a6d8cd17911a04dad7def4403f90bf6601b8e5ab28844ebf4e5992ff4a576c4c7a00f252ea068865be3301d90b8e842519660d94a96c10056f85d7885f154be2b57215e688dcda1be9d3c473f9fa3e85b725c76e962e6afb88b11a3869e283bca18c31dab157a5040ae8283a1b6df63cc78dfdaf23346a61e4b7df597169b6f6b9bcd24300234be2ab9ee8b67477c36f44b3f36ed9bfd7c89070cf0ae1bed6ca6d9b54b46b251d984209f151fe21abbca0ad157ab94f6d2e4cf92767c792b3bf941d84d1323b61595ebbb98c5c4c1277b127ca4607f0a53e6c78124786aa5a5a29652cc6abb557c998ced856a18c5507abe698816fd113b816911aa0d2e53d1e820d1aa7c73649f8ad553dce9f5901f9374f32f02149242e7730965d901a123b43cf9a442cf7e86600881bc62471e46c922959e3155fdd44080f699050c072922bdb033144ab51b549625d327b5b4c3801933561b2ac38e3f8977d0f9388af06feda81af5eae07f71f7a8ca7e72b9def229c18d5c5eed2742b12ae3b47119fe08a4ba982bbef40286e80878b700de5872ec415998c120470b4fa0490007890466271bd5371b2a95401fc4411a1532e8078c08035a25edd909241e7b707c2a9b05a3c09ae1ae14f16a1596844acb9373898d14531f12755da60e28e6791ea67f359bc3da6c4fdc2a0c56f882cfbaf8aa02b953295bff3e647aa8bde1742b37194392b09ad9f52bc061badbed7647f87b7e2fc96b097d636a6a4d46cfc9605b6551aefddadae20e90ba76b63539403195a1be5453c22d5c55ddd1fd6a1b7aeb72b17558df47d986a3c70923f55151a61a651efa0cea684b11e8215837b03fe5498b49dfc7fa4e5d0ddbc25d5d83474446bbe7b7dbadf174e9eeb3547b547a2d216cf724809de28f79841f14cbd7a1c39b64f6d0a67b94b6ba1939992a25f63e1c220e1b1f5ff287b20d4aa1f5a6de07ba3db23c41a632af4809d425f1f2cc1be8e6d3871eee9e7834f139ddaf3fe5753010d9fc8a06a59c54338fc38fbe0646025bdc6fc0f77827111c5a23635212902ef77c3f1d3710f983571469f01f3865e8109d9448cd91b4a28ea60b4f1171b39d676c61dd19bc1901f5ddf34a4c8e69fbd0051f5eaed917944572cbf26bf822c03ad3d429ff70d170fa4c94f178a74c5c8b97bb658e4a8a871b1586872239ebfcffe5e49ba74289ee24ab071a34ac3864aa880559d42cbe8654cd48660a269f27616e03faa270dcb1b59bb4e0acfafa942b1460ad10c1109b8c5443943370a7675d9b3cdbb1447ef7f0f6f66e939b99522caab61a0463612955cb282e311162c4eae124f8596047006ede98fc3d9e34688f5349b6eeb2e5d70a4ceda2ea51ea82f732a31321970e195ee6605ce12e341b83340bcb8a70871828a09ffe37ec551851e5db8c57d1fa60219ea48b68a64c1f844da223123f604adbbb91b00dbdef8ba542266997755297dbb16e63881ae972270efd917ba505e815e653f33b6a0a11b8258cec370119e16278c45d44a81e9a37d9cb0cfc61e3f663e5a6d343a9323af74df531fc734b377354edb75d2f7ed63a0138120171175e5dca55cc1a79832e389cfc81cda97a2ca8f2bf6d34832bc74702560e2e11f11bc45a60a2446e0a85b8308f6e7052415da44f0394aa1b6d4888485e8f7c306ab40ecc36fd708cb5b3e42b1472ebd75cad12bf17b06aaa6cee63527fcd744a836556132555d9f11a2d74dff43fc38834dae95b6d0a9537ab521bfa4efd6413895d51812aa879725b06492c984054a23a2e12e8a1a76e40abb2b2a436531b915976ba118fc8c40ba629ea418d9cecdd29b6c697c823d044f74d765a8506ddaede2f50d4eca8214e542827d4c3f3445ae7085c2507853bf20dae4e76804a544653a690323ef8aca5655546919cbff0ed78c46fbb6aadc13275c529bc41617ddddfeb89084b1fde69164b809c8023eaad739b0c07696be79fceb34ace1039ffed753110211ee87a782d88ffac45d47fc2aff8a1ffc75ff39b4918186ba2d83f18750b0d8a04283868c9108147377d30373adc9aa00e863b965257b1128ea524ab6f2ebc3aad5a96795b3443bf71cdef03978f19a592ebcef0351e8b18cd767b3484b83bc57bc0e04c5d150c5984c875cbc887ea35c0b07719050aa69c0f62bd5c4f9e60be30e432aa8e2b3d84594487a03fa02f2a8cd1deeaad2198133bac1fc6c5fe0cd0c26b2cf06ccf80f57d2169b50e5c13d57b35f1ba81aecd1b17c4362e6056d67d9a7ae74d0114ede2a8e1cccfe46f1e035d1ea4575a1d260ce59bd4953c8814670fabba5430ea861ba116aa483fe7f014e8220c3d74b71beb91d4667eb9905173ec07148415241ddd72cb816e4713d59f21e3408eb366fc82c8e3d6b1a9e1b7eb847dd0a50f9de6dc660c53033aecd5d7cff17bfa7684aca6987826f23673d8fa28ce7d22f3da9ac5d0697e2d6482c52c2067c0de818750340ed6111a9201e506b8ac88d7e00fdb11299ab71f2aaa07868da8c8e2d9cd5a636345087e1ab83fb232232a3627062a6849ea1361397c0becdb7f6e627880b61669126b40868068c57b52ac919b5278ad45f3684525813eb65e85ac04fd3140edd3d2a7fcc3f7ec6551389f9f12a5486bf8920ed78abea852e68cf0da2c450b72939129db52c06d2aa46d620e550d5ea6ea1b1ad370d9a900ac305343cfdcd12703f4b4797dadb8e104013c1a97df2c9d3141ef29e2304890858106940dd6dc79e98d3f2af7e148f216c0a2d7a190dc613a80325369b43e4e08307ea7bc8d130297c3e863c6bbb669486b4c7b0c75f5ef2b2e222a9847cbc3747a300185e058b69909fa37431d4dfef30ab136a522018b5ba75bd039281b1f5743135eaae0ed9c78f03dc2a2760ff5d5e37e9cba10ca81aab9920b475d004d44219afda36a45135c44d467a91b9ba7a6e6fe07ed6363702887dcf9e4ed2cc97732d9ec580a3be27f3b1fe3b910e0109db5261e74c27b73684c663fc4ca921d8332a36858e38a9fcd81094c56e2cfa61d4c5eb395f867a863936f6e2dd619eae0e5974932e9a2f856b69c2830eb7ca5e115eb8e17af671efba53c5110cbd96a339091e7769e9e3cf5e6b9c9333d2f00e9bdac2e88d13f4b5dfce53ad80c5fdaf85e7ddd7a43f911162f1a4c5211c4e7305119ba0f809497e2a8151ec2e875036e0d7e18a08dc167435a0dbec3b407f49da2d951161253fcc714ff30a57f5ce91f53803fe6db2162c1d9bad00ff7df8fd2caac8cd7ef127b9b16de3b435efabbbb8fd30fddc3eca1f2007d301c0ecc95122418b5f38446ded30224f456b7a61ad29d2574424f1f446963a0687cd7a2ae344d2ba4f71164e6ef66bb257418e5bc97cc18368ce1a43a0ce092554a74d40d65e713bbcd21caa0d711d99ce9344f36effb1ce71aec953f253aa55f394de9c3df2d2b452b71953e654a83d10a9a0e1779ead5c1b4b58b195d03cac8b9ada249bfcbab63da6e916a6b06d191b07ff81fd20efc87f4c3ef21dac17f400bc62af963a052bf434a13f10e8b43f401eee1774877e83fa01dcc071cd814d67e2843d16a3e178ab8b0d8f7aee7866561e89d8de1d410776a0a2225c6c609b54a7c7f80480c9afe685d7f4c4fe824ece56d7cd47e382f8dc08763373c0700174bc86c5e5528feeadf321d7400623067923f2de02c3428549036e8cbe891c668bc01ff0c41f8e578e2b4a46aacbd3a1f7d73884046fe9453037e56da4f1b90114ff388d8de85e18a9b06d71097e2fd5c08cb3e6ee06d2e0a5833029d3de98d39a8dab875919a91145bc7f4082ddae63ecbd723c6092fa961d5e279e7e5c355aa122959c72d88ed0a6cbb060d0a0394214e832fef75cc731d0d6886bf3cd781e7edc07b1f78ee47c4e30b9a3e0e7e4d542473e0885bb5ee8768a7260bf4d80fd4e28782b6cae2722cd210846ebce9a87ec63c87e1894e77cc09b3ac11c019232b876ba5649d1cdab92755757a3c29c946981a8e7a3c06370bc954b8b67513de0900d68d1cdd50f31643cdb707f8221aada9c0f5bb4ed794ede12dd1db0e79b0419788170d382fd4ab570ef3939b8c7b3888688c640f2bf6a8e862fddb3cc249eabf24563141e4fe1903139afdd60431cee36aa25ffb32d6a58d2c2ce103f384dc0028e708bf473dde24293d5009c9f67e494d404ead12ca3414dc05838bb75693a407408b971b1e850b88bb3d1c91ffe25308608ddf7014483899ff38d79afe319d15442c2ec9eb41c03a5522540284480d8cfa11f7f72e85218bcfa8b49296c0a1527d940afed95b03071ddbd84250466019d74bef2fd704c05517f37bb91084a579764adba08936fd57587e4f49a870baabf0cdb058d557853f750e3d6ced9b205c15989dc3b26b493eea134a0d17567889544ac59162d17e8fcdf56d1d5afe3ef2658058cf89093631e0f41d3730fb351849f6a71046e8d9bb08afd58497bcfae6c88e3c533fdf2664164432d19276e05b87d6d29b2ec00036a2b94a1f82e75988a80b612bd30d6d8de73d3cdc8f6599918c4ff1d5167567f0793768bd3e64a859bb8b86413d895e91fe12d909ed1b78d6cfb93174bd6bd4ee96e9aeda900202c1ad416a96f5f31221fd98b72c5de788b4a952075146e410c5767c92cc2ce363ecdaeee68d87abac86355af56994c192f52806ac9812a9718dea8005be5676156a9c57f0a8be7304fee4a6eb117b683de734f745ca0cd707b0a77894cf5b84be1abfcb949ba9111d4c83343a02769bffe277e04de70270fbc3c44d43dbbac02a8a9990f20c8054a0c64bb93986fabe56b482cfff5eb296e8c1b092e297d912a9009ba05590c0072c026521450f571f62737d58ddfd2692a57cf2155ec9b4c31406086a27f2de857b6e9f0823081bb3034671bdfe1bb3d2f85b91446ec3884c6263c204cca6d173b452cdef7035e5bf24c0a202414cec2271a9186773695ef75e6beafedc4aee5399c706cdc4bc1d5256854c80179f4765675d530cda0c48ebc1990d136cb5d61f32f65da02faf65c3cb9f13fc9b511fb849d3c6e5fc7c7d707e5dd4295c11448c03dbad978294437e82b6f08ccce689b5dded1f7fee2df43fa00482fb8c264b31084d3c2d041096d7a2cb2e1924fc55ff26bab0a345288fa519569b2323ba4f8ef589cc28172e88aea2453fb5fcfb60e4cb18edd3ac2807db3b94574ee48593ad022aee9ac7237682d36c2fa570ab5344a6502bf4622d299f4daa84efa17d82eeb60b5115811d9b6afe9a99a6da7da8c2ac51afe1767acddb12fa18827917027efd63f0f286a06647c815698c9caac06cd931c8f0ccffd5e400a65afd56123efea8b693e66931c2f5c5a155041074d8036a4803b15310282d2b1d613099762cbf801591ef8664043b488ee9ff7409aa38b00ea422672ff2d955e2628df8149f075b4121cc7edd76785a75f615ce76ee4a15d5cb6dcfb6c8c8268180022dedde7213b2f79652ca2403390b750af00abbcbbb840848a26bcef97322d981820176f04080274de3cffb601a1d236965ce017809ad3cc979093f78931b9df0a8bb3dc30e7ac0b5f16b0408405858d8111d5fb37dd00769a69ce3205da5e3679834001674bc1539569e4cff127e20674e3fa2e36dfa6ed0c1609beeb6073a5e0739690f356b5e4a930f5b6c21a5e9072c6a1082df71040741e40d260852fc5abf8705d8f13b7e860680e02120dfecd06fb4950e6c72d002040e414cb54912469ed5871046f810afbd7c6942aaaa164c29d13291bc79285efe355953f2c290c87f322144d2df84446af249081211b67ff335e79537617bb435f980d823b9a5276c535de11d5e557dc47e87ae8d9f031defd0b50340f03b7e2a83afa91d0fc1cf50c90b43d27f44bdaa5a000189c38eaf8da49426a4ffa9234a4c293134756468ca07049226bdf484213d0929c044b2837c23815979301511c66484d3bf176f7e5ebe2fdacd175f00a0c98fc0a2bee38342afc30d075b59c70b81d4c30e74bc8e9fa107422f442221da9080e10d8e9ab4470f2c32498c99809b2414c893f65002532922cfeb704668da3624eec7eedbc81a9319b683be8452b66ddfb4836ce3141ea53c8708e4c961d4733761028f6f7b70d45b48d892638f6f422e97dbe5fdda9239f71c75cd43f1a8ef7bb8e57e1059c24896be839e290440d3be4ff32ada23f65e458bc6442037e7111d4de6197bd4a191b80ec31e83c8126e6c5b13f8a3433c262756784205289ee2a410051829bec871d2f232050a54bceef20f3a15a72295fe298ea449131c49d452454e4a38078bfa36fdebd73f435c13d2ff11d5595670b9020b13b46c45800b020f98950753164c751ca045095b9030e9edc60516b5b834e9edd6f5a50b2c6ad169d22174887b31e990fb930ef9420b939dd76b1a607b7082e0542c7ddb5e4fa4518381457d1930fe150a2ce0bef8b6bb9972b95c6e8b3f4325363ad8c730b8789de015d06201055c2084496f97e94e0226bd316120032040f03b100001b9839cd5871807f8ba32ab0fd7800166f5e1c3c728c0ac3e7cdcdfc092ef117cdfc783e92e7dd7ac08bd8eafddda253f102275904d7b6e3206e0651060d21ef727edc1010fc03a98b407ed6186003ac08107aae4a1f281296748f130a5dc065d702844999587170c65561e4c4e4fbe04008c931434786aa202005660c2c292304ac460518b9f64d29b48b680935c78ef0a9f787f49280b8cb0b4c70b960a19e37388ecc98c2f6a591aa3bcd8b9e2c117435e08e9a20b860df4b001327ac013051543f63278f032661e1378700e5c4159b579baca75c9208e2f92d766cbd942c8227a89e24b61dbe777184227b62d4225414134202b57ba6c33780ca11270db1e04e79cb38b8b2a1ed8b66c2e80b69f349b8de632b80c93deb8089fd068b62da02869d9a0b04fa39800f4937f442fd697677f1b2a8b680f248a22ed471a592e5520bdc5c3469b06b703bddb34ddae45f8c496b3d5b1bde76c369b5ea2812dcb66bb34886f7bd0f3346df06aef42b1a8dd89de62b93a591c219958e4fbfb072c56a3a4ff6a4f533581c4fe88566541a7c848d119a1927e92d43a476a4d5ed140c753d6e4efff47f1694fee5f2534f18a7a6848d44286c4515369b286d9a6bdf83e277c12e455844a6c4f415ac88f30e3a86f3f6eb70c2825977ddb9ab68d1cc923ea555481426f4efbf13d37dee8ed8eef5ae1135b4e4ea884166a3092367401bb404155ea45290d45e13ef9e2f5aa28355256de462497a4280618e88fbde7280624197bad658ba3a537d90d58d441e0145a729c9c9c9cbcc891220aa73659fcf23eedcbf169ef71c4b7bd431136b13dd0fb132193fb406429fe1d45dbd32f36201a49f5a4962d0691650866680a2980a1e01f519ac2bfcdf657e4f183bebc3f8e8fe53eede953c8e43e8db4f4b6419a8d5ca2377faa27c5203d279051974c5378cdfdf141ba82ab30814c289ea02b986167cf2d33e6c4cc38b3bd6a1ac576ac1239e15fbfff24e7134e501642a57f4dfb23aaf5eb9cfe5a139acb6ddb7be909cb93cb2181c948ff9f044593414f67073d48b187f1a70924f652c6e4ef6d5f66193d2b7c42fba0f7dced9b087a5ad0c79e060681ceb583c8251b49f5e4ac3cc6a60d521c667448d08bef70c227b6bfef39254225e38f41fa6f33f0419a43993265eed5c1061b6c3873c30da288e6023321136ac6cc0e46f497f7c7f7a92951a4228243c8e4c301872a0c720899d81c724843448790c9a7830eb69f18e82fc51fdfcf887fdfcf844cc4bf67c471d4fab5961e86a04183468d901d422676871dd654404545358e3e50505555358e3f4c9026cdbd563cf0702f9b0a7a0899d01e7a18472028501332a16ad40431c19a35f7b6f13287cad187f089a537eac3bd42f0f82164f2fdf0c31043ac4226d6ca8a081e6c42261f1b3657780e29efdb3ee81d88f1fe483a102193f12f5952fd8f0fdaf4a437a533d96d64d02d02cba83e23b0a847285ab6f862c9b44521a86c5b0ca105549d3a51e2b58de338fe11b5e932b3c13ecebe3ea51a9f52854a66f9ed496fe3037ded6dfadb9e45e824e86d16db3b9df0c9f8f7923fef5ca1923044326a0d6afa672b7c329265d3c62254428ba25461d2a53d25ba24d58f7583b40adbc6eb57844f687fdfa1ac0895d8a272369d7f6821392750d43f86fe6a2134b1fb42f46602250a2263b3ab7d4ea8840807f2ecfcb2f736a193fc32d9d3ff2912ff87de32bdd1a769ae38277422922e4438e94df65345f864a4377f51fc2431f64e45a844f662e94f3bf6b117b587a1b7d8cbeee5210c251a3ff6e0a88dcce82df6a31ee92df64a3be4f1fdc717426f14a46f70cf3b156193fc32dac3141cb28c9c2274729fc67f9fec2d25b2bdec3f4a34be8c14955cc8a268d3a32e3f3558548249a81bcbfcea438e35366a33996c8a1c6459e3713cd0d33561520d1fc2241c4037344d2b544264e70944f62e878d959c5aad661526d5d8d890a24d8d20a400aa410ba24d98f4538b42092c6a9a11a2288a366ad0226ae39dc97ea6b1c84829806ad09e161126d920dd6051d37e863f479446964c47e019da6c3299ecfe07d97ecb7ef641bab43b68362b3359ca9ef6972c650ff4473568cf6a359bde5277ed3d8a3089efda03fd90658d567bf1a99b30a9464e0f428f08936c90d483c81ea44b9ca0ffdfdf8b08953469e910d93f39a904b03781654b76d7988c7f7f24cba67d65bf848865fcfb228e4be1d8c85fcdc6fd9ac652e3c51a35deb56ae020cb1a144e9854e388fec861028b1ae87f92a0ccca03882c99b2f00c83c8b26907fda8afae17cbf8e25f5dfe482ed54d0baa3d4d9776d36c5fcef668fb32efd1f6e5b747b2bc0ff42359de9ffd51a5e9b9ef961c615d7ba96e1b36fe88d2b6d46de35d4e98c4b78d9fdd204b1bfff3e203692c4b75db78f1691361920d727a109a1526fd90d38394b22dfb1a5a8a5009b8bf09e4098702cb6a5066e5e171b04c9751306d29f0336df1412a078b5aa6cb0fcb52ddf6c507a7c371257c029e8463f91b47c28f70376e8417e112f02b27c2877021bc8d07e140381bb7f21fdc075fe36abc07e7c1d3789553f90e8ec6cfb80e9e83e3e0536ec66f701bbc8cd7e034f80c2ee532780c0e834739191fe32f3894bbe02db8180fe32cf80aae823f790a0ec6bfb8937b7114bc8be79ab89c60420420f00026079440c2d208226cd1d200062c200b96520121240004045c3980010a60e503020cc0830e04c041152a53a4286d808b02e549009c68d004004c9628499284e408d23ecac0971069e8cf47cf1f8d3f7a2bb3e49d47a19809f404caa536ddb03e4613605e087521546bad5ffdf11eb1c501a72a2ab1eb8f65e0d9b556276d51158ac562b16a2f5519521328e3a9c848fec1da22e32a896db7c8a812b1acb5d60e596bed6d52fa6499859256237902eccd0ffdb166198528517daf6455d2213b165b78b2b0f8660b0f960f5e190c1fba7ecad9b5b329fd1bfd1f7436a3b731cb9154b20b38a90df7c9256439e350ead4dddd9f6813a5d4cb764e4095d6ce524b3b928e017eadb57af130a43535fbf76d6ca7355bb8e4b62593f8124c64e59ae8daf5bd62ed6eca9dfc7dadefbb7a18ecaaa9be9fe1941e13bed934ba60d30f9a187c4f6b49e8f625b6910d565a3f9d2b0f3a458c3cb9baa8b32797d6d6ae64c9446f7602f1fe66795273583a3cc32775894dddfb68bdf5de7a6fbd5feebb36b4d65a3d093b349b55b2d65ab1844ceadb492b1428c0d9980b0537d6dd2d16ff5abf4259426f5dadd5566babb5b51bca8091eb740112980f698dffadb4d25a69adb4d24be99d1f2477f749b93875ebbe6b20cde9d4adfb12f7ce28512cd65d1a9db6dddffb1d96119af6b55f7763f77ad7bbd7bbd7bb37d6dd6db3c8a9d93af6a4937baa7412a9593bf95c2cf5ab576f9522ab17d0fe149a57f6b612410241d0c9dba3bd076f68c17bbfeb9ffdee97c31dbe16b4969ca5f5ef8b3ddd31fb59b05aabbb3ab6c9b6ced85729b93c9b81c948dd0d91c03cd2a4434a7792552711a97e6d77124b7daf7a329d032f88045e59d5a575cffb3c295a9834f320746c9371d5aa73c0efa3f3b3144c46a23ec4c32496de9c40245a9d3a24308f6429988cf4d1211e840b753fe327bef75e2f32b717f17ebecc8bd49f5ec4bd48fdd9751d5942712a3c64fa1efbef63ffbd7d92e641ae7d0f671ee47ed5239b5cdfbbce7ef767f7c7fbd3fd2d9776d7e99269775dd9b43bb2d26e86dae5a0830eba137e301f52adb647bbe86dafa0bc517c09244cce3981ff5215426fd308259a46e86d7ed83a7d48fec9b02329615225acfc420f811741bad1a74f8f3c087da537ffe5699713cb8828c5a67ff425b7e92331420e0d819a0a9e6cc992c6de1b1f3ba84beb0e3edd6075fb75b52bc60358ebbdf72b4d0a9717d65bdde6fdb9bb7fda09bb7db7f5765dd7c51cc455bb95e1aadd6d67adbdb6d224407f10a449c12297b71f6edf7329f433fba149d9caf53df00b9d949245fe9e4a554eca7d5f98e4e99bedbebc7dd6ba757b3ff073b7650f0f4229f59b07a15ff50f2536745410a3a0a38296955dbf64dab5ded0897f758f02dfd3a7d40944725ab394b77d308f64bbcfc97ecd961a16064546fa94873446a9f75f69bdebb6d7c5a8254b9907f187d225cff62e78b63ff6ea41d8644a964db708d03ec552a0725964e7d32fa21e39290fea787b693faf64897f7ec6d26edf16e3254be86d2a4d232557c9884c7fbaa7bb234b2edbbebd151999db5a6b71a5e3ae2ba8d9a52dc2516ca7b3c299edff155122ff1eacd36395bea5a4634929914ba26b837a16f9eee3973dee79eb5d17f28c065139b36695080d3d8b6071090d99885fe5fd08dba73cdbe93ce1d9eeddd71a39e71a35665e6b90b3f2b815e3bff7696a5bb0279d14ecec20f0ec0bf6e402026b8317633c7d66919907f1bf99088dbf9fa711ddd69bd1598d7bef252b9217cea8f090bf1cc35be3ded0c925e77d905e7ae9a6b7e96a97f6b3086dfa35aa53d5767f310ed1e4729ada6ec12c923d880b29e2318bfc7810ff2e13a1d1f35eeaa8b1cb598f8cbca1128af5beff71d9352676fb3cdd3e64c9e5deefd17902b92fea9fd9f813c87d992e7df6fdec45f48f17f19941eeebd8f76379dff77687c52ee094c2264f3a29ccd9e5cd3798399bfe0f3a5fda6cfa427abec6a651f77932c731fc222631bd4d2f4c32ebd1be31d6f57d7c3e1ffc4714cf2851257d6aad1f4e278be4e18d0a0f7956c92917c83e5f2ed52e7452f3f7f43c987b724faef9e9ce3db5fa4cbc6bc54f8ed8b12e47f065325036e7bcb11bbb5dd775b687825a6872bbbced198562d333b94dc34c75ef1583310f6f586f4c8758bc172445f136df0b93a6485e12df9ff5ea5963b12fe6d7bf6277f72e468317acf1e6a56ad3ff21beed7e7efe99d55a3ff6cd72c4126aa1fb4734d44c645f49296172697769b76c09bd4d4aa99ea0c6d665e1d31d625916a12dfbb9699824bb7bbebdd3a8fb6262f28d5dbabf0e3be9484b6f3fd7e97881b3e9a0b035a9779474f75e7050691acdbdddddddba57b75ea953db33f70cb1bc6875a9da3df6e4cae5d9f4ad755ad6d9448949e7ac35a9754917f529cdb316327d72ca05f2a54e2869bdda5aa7d255ee4e6e8e57afd38b78916edbea45eccfb0b02d827d4a62b14f9f54b2caf45d4a982d454c16c1eef2dbeeb68a96ecbe23eb15f72c56a657b7a2256b74db4b2d598772d80acb83b7c2ee5021e60cfd3897106e663d58e657304c2acc696bd9be5463b2275972f1603b16ffb9adcd4b2a0af6e96b29743216fa554acede3e8b040abdcde954a099e26a5367cf2bf6e46ae3b4c19e2917c8fea4756b6b4cf6254b2ebbcc825de7fca1d02193e4e2d43d40f534ed68a1444e5c68f2ecfb592e94fafe6dae26b4b67da771e02643a957a0e82af4763db0426ff7a5b490bfb9e5c4c9234b4eecd3886eab24265b25169ccdb2d5b36bb5933327191298478a9d8167cfad0f7c6ddb9e5b1fd0da212059a51c23ed532d34eb926ef60d594ae4fe92b9a7d2d1d02d7fec2bb4ef58fee00de58501927383d958bfa8e8f63f8a8cc0296f3f868a8cd422ad293ee4496ff856df0805dc85c659a787b4e670817560ceaeaf41f5b8e4d45fe2734e29a4a8be91251ad436396442ff864dbcf726737af49d56249488864abc5caa37efb1ccb7135b2cee1f956227973f6af7439488cc56fb8cdeeaa88426dba7df5dd2edbcde8df1d5bfbd998d4375066e5a39bf767f724581edf27bdca4236b170bbdcd6bc9e95b4a05f2b89574c87476b3debd358eb55b66446dbde71658982d2b650f8a1ae81d6bc7ac37c10fdf31c9f897a461928c567bd003719db5f7f9dad39045e5b208653fa24c268a3799cf572732f169fc14458f92611b9f0d8d457cd0622f2830a2ec4465e1051565035b4a347e9068fb32d7e6118dddf19b405fffa3fda4b7abbffdd16836decebef6a113da5b7ab3617b227b9bcd5e599d9165d31e95047d61d2184452e518be3f32d9db9e8c2f937decffda46992cffdcc837681f7b1048033dd8899ef8c5409b2d0402ea11459f7b6bd8c03e8d621b149a05d16aa30d470eecd368c45b829e841cfb7e1e3c778babc506b6b23690e505c6939d9c5754571417515d515c44754571d1c50598d8444e64626b0c3c534becad3172e21b2f309eec60517a95556e738d716384ed813e106603fd05cbe5de3c2191c55607d4cc3c229cad0e9c01c34e16505d515c8851753697d5934b95a144378b1d7b9fa24498522eacac4de3ef831de481caf314b372050b03680ff4e0080ec0403ff340996db5e581a81d7b57136bb3630f32a0015ab6406004bb44022e01fb34b2fd7cd0a6a977a1a5e05eb0a544e2485f050c9ec0c291143240fad2548030b623623e68425243428e0e5ac035dbf801175fd4b830425301a0a852c8c0004d5fe40c3b5e2021c71ea1a9833135db28f456e48ce09190c383a6dc9c4784481674fc11b521315e32514ec1fdeb30c4e012c830e70f292326ed314311344860561e355c95c1444c7ab36188597ddc20849936b3f2980a62d21b130e404c7acbe1ca1131d81c212104e1080925e870e508174876581d510284235d0e0811a04497339d21c00748ff4df3870784563ec83d00026808d084e4c3075c58f92002e1075c98b0c3102a21f7abae6c31c2c2c2bae644b2a3871d20cc79801084fdd51422e0cd57ae0069ae6c2ec2c2c2b0e644b283871d3fc3a403ccb0038424400873cee93dcc39a7e7e038cc39e7f4a839e774167c8539a90bb4052a8686a12cd015a80af489a640c15028f7329c0cc7e31bf0315c03fee56278061c037ec72fe016a03088b1bfb55a2181015acfdeee8b8138ec0963b9f3f168d4f8b10174631644ab8db21ddebd210801f898deee7dcca3878f087e682038240012265d09c2a4506fe0c5dc5e900c4cf10d5de0ce894d70e75221a3a08b21097c801574652c848b20407a8443bcbe2c44a22d80f8b8f510b140be1f0b43720328f2cd9e5784d322cbfefe871abfa7655a04d92f79df833ebc98f781a43f8f3049f89db765de77e1771f7aa40c244308c2279d4f98a97091c3f7f07eb5f049f7b2072d3082635444890f1431320123172491e7020cb030c8e08d07323842e2084fbbb1a70444f62390ca69272437e8402e73a63fb38db1d8f673d5ac21c63ef6f641d9dffb312d42ec972e7eb0bb21f6fe73d0dbb1fba0ae35e93cefe767c91dc02954d6af5da31c91cb09c694732472e94f4f50f44d2e5d4a6aaa62e5d2abaaac6c12b9f4ab2bac3b815c7a569656a7442e7d6babcb83934bf7f2f2af6f895c3a9883e5624ce4923e3d41c99ac82595929a02b37249abaaacb013b9a4575758e113b9a459595a2214b9a45b5b5d3d717249bdbc7214b9a460142ce723452eebd313140d39b9ac52525335b47259abaaac7ea6c865bdbac2b241452e6b561610b63a4a15b9ac5b7babd62eecd58b12d5ea55ef50a219c5ae2f38edfa48c0203a794f2034ae2858e4259587ed521c9ee788cd075d8793eca93a7ca8508dbac30604372208a2b71a0f9bf7c8e143cf1f3a80ec70092208c2630ef9a81300a11404a91384497432dd1560aba31091f70452f7e482aab341220f95d48460aba300917d88557690085b1d654d2e671d0f96489845389841acd01a2e27168e2a13c811952c88541561aba3506523a31d72595464c48222458a9cc9e5d09090092a306244875cde6e3f78f8b03a4a0eb9fc2d448990e859644f1dd3e8c80452bfbe934754ee5c807784f9872a638021083fbc43a619e008c269a5a039c25647a99343bbb1d5518edcc2a4a309a43e075f8e60ab7175327d1009b61a9745a60f2661ab7174327d3009b61ac795e9834ab0d5b8ad4c1f5c82adc66191e9834cb0d5b82b327d1000d86a9c15993ed8045b8d9b93e9831a60ab715564faa0136c358e8a4c1f0c00b61a3745a60f3ec156e3b4327d100ab61a2727d307a360ab715264fa200e5b8d8b22d30737c056e3e264faa012b61a0745a60f4ac156e39ec8f4c129d86a9c13993e48055b8dcbcaf4c12ad86a5c13993ec801b61ac744a60f0a005b8d5b22d3073bc056e33cc056e394c8f4c10160ab7113c8f4410260ab714964fae007d86a1c56a60f5ac156e3de64fa6001b0d53824327dd000d86adc11993e78006c35ce4da60f5ec156e38cc8f4410460ab714564fa2008d86a9c04327d3001d86adc55a60f8680adc61191e9830ac056e34a6c354e884c1fc482adc6b5c9f4c12cd86a5c10993eb8006c350e884c1f6400b61ac726d3071b80adc65965faa0166c35ee874c1fdc82adc6f990e9832260ab716b327d70046c354e4da60f2e61ab713d64fa2009d86a1c0f993e5802b61a9726d3071d80adc65565fa2013b61a4795e9830fc056e376c8f4410860ab7168327d3002d86adc994c1f34015b8dd321d3074fc056e372c8f4412ed86a5cd354ce4c971b50b0c14b19a71abed000668614a49e64502186156060212a0c1931635a78c1052828175e68618c183261a258806185185490e1492a8519b0d53830995a8dfb92a9d538a74cadc679c9d46a1c0a995a8deb92a9d5b8dc54180e67e4f0011df29cf1009a0eec600615581507d294c103193de051b3813563f8a0811fbeacc4609301203010c49d361710c20243548008afab3024408122c030c28e9b2f8ef002892ede74617191c41613d0024e551870b0d551b6b27d4b85024c204913261d81c104b63aca15d9fa20258726acf8c1ea2873b2b572e20b3656e3bc00020a3741c431a24d1445082185048690734584d610530841459b2a8230c20a336eac60734468b1980a939c0a972381c50f6fb67ce05293049d1e26105aaba3f090a9d551d2c009ed16fe8e264c3a42a243f6b73a0a9a4cad8e8243a60fceac35b9470c3dcb79f0baeb59b652a7f22ea68789dd27c9318d3af2d6af2119402b72691fd31fdae4ae51120074d020b1271d3465b6176ad0f454979e08dd2fd1df32c376ecc11b96b0c5db58e84f0d669bdaffaab73bbd6586edae76a412a0a5444e058b8ca97c914908da4b4164e90ff830d1b539a4f2fe7a3f7b864986badddd6b1d6b9799a81c9a6121c9d4abae5279d08762cbc9852c0a156797b905385c2db899964a0bb9cc1edcaa4443f62abd744e52152973ce99dc94b5cf42ce66f097cb5991553263bf1093fe556442966462c14cce397f5be34f158fa9f2a0bff53d5325f24379d08e2cbf4b82816d5ac9cc82993cd50571dbdd5309f3d4ffa8f2e8a6b2ef2f167a75fac7ae0e6549aa1ed0a17a5e687b24d6e8512247d39be46f6fd70fa19639e3e56ae8aea44385f1370e851552cf4a09153179466ff4876ea6ed55a90cce326d441fe925e3a6023f52044bce66b3d9c6b35188de2af954c4e42fad0a4c219860e50abd635f06ad092605570c739cc9d21f8b6fc8d493d85d64e50a25b2afa401147af39db4444a13df97f36c7697541ef4ef4db23683cfee25f436a357ac48690205a7294eee947e0d006bf7e5d9df86acddc2b46fc965fb166fdf72a96e251be80a25fd12ecc6f238976037162157ce17169e3378e2ecc9b5c2d62eb227d70a356c7b37fd3b16ecc9a582179b8b853c7b72b15087823db954b0da61b2c2608989da540c7d073b27a9eedb7a2fd57d1a0a20d7a00964022103aca33b570a75f6e4025367973936e5026375fdfad5b5e6294e546d29d5347270139167dff6e41ae26b5b2e15a4f6f7344cfabaea3d8d832bf2eeea7b64fd1263a9dfbd935a3b72296f9aebb2e987754abaa736a6c16d7fe8cdcaf68cd5aefb5a13ba94778cace572bb69df5fca5f1581c97dfa4d6c2e37b31900897cf467466b13efcb9f4924e6f3f3fde472fb8bf9607afbc8a5bcbd6742735db647d69ad0db2de51a45f71e1630fcb223a9ecfb6474ee4f168bd1c7e27d0782e42c47688ae9cf9ee9a916044b0fc4a1d893dffabcb59fc9b26efb3d6469cbbbed8764d995deb60f7adfbdd7fd11f55a13fffb35d6fd3bb5f5afb5d6da1ebf2f80b3d65a67b8d63a3598fae696b47fdd3ab56ead15aad38b00dbfe154b7df2b364f89c8d6367d069214e0b511bd31173a6c749ab446f13fbe40233b57feca744f3e96d4bddb58917f6f3bd6b7fbb9c60b34964c9149ab73a5464c4be065528918965df4a085ae81225aadfe349c422d9ff994473dbaead446f93d20ea8acc80ea8ac9aacd33276be38593c4e70a2ee759fd39dcecc298565a2ee3398406fb72aed49a79e378f532efd69fb157af3da7ace39a54b9e82422e5d6afbc7d1c2125274fb312a9d913dea7e8125b8972a1377c74e4ef192cbb1c9fd0a38c54b2e85f6945243a664f9337d3a387307b461f973029c149c94ab0529ae16a0a69491fd7be84465d1895282ab851c9798ae5d7e5c62aae012e3044986feb8c47089c1da3f1c00a2f3e5ccbd56cebd370337de77d63fbf9dfeb05fcfefbdf78be27f84111e39c41b7f7a8237dddacd90c16aff4e2ca40ffb673fb2a376e68401129847f2eb555bab3f0d4594302ae2a24584e8845a6d572da8b676b5d6198668094102f3b456a0c404b5d65a6badb5565bbb5a8728a594567a295da2d65a2938412b0852adb5d66a25a8b556fbf56dadb5d65a6bad407ef8e8c1e31601045057ece0027585900e527f0e1cb6b1460b9af90d24308f148f84defcc36cfad58d67a9a93694d9f42b257b2625ba7b96f6297d3438feabbdcdffb928f379bbbf18ceecc905c3995de228b00dcef9f3952811ed3da044b6cfe34fafdc81a5d09eb73de4f910c98830fea9f163e3817ebe0694e8c64f1c5ffbf1c530695cbadbc71a7966fb4f95a9e1f8f171fc4866b9edf16b6ffb304cb2e120b3dc76b6e5dacfb04926c75cfbfcb4c76112ad462e519a48d3f967d8442427bd3dd972e2f12acac31f14ffc68361d28d7c03dfd0e2cfb00926f33081f8815e1626012df99601c98034fe1936919178beb2c8444c66c11bbfec6d7c2c4cb2219259f0f6b1e163a3890f89492b3eb22f4cfa91914b767b3fde8ff651f27cdefb1aef854935ac777dde7b9ff7c82c3fdbebc2a4cf87ccf2b3bbfbd39bf2f077f41ae9f9fbd427fb944b76d320e90d6b28fcd1eeae8bc5625b9876096e8f5caa1b874966585858d813cfe5dee6221358d895dca03d0d6140fb242537b6fd7a631d50b32797196aaa1425f2bce88d8b863a60b5b7f3be98ac07cf79c19a12beed46d694309b444bb38dc1a6b375752f9687f7411a787a11ea65cf07cb80c9e58502cb03769d6c97b54343fd294eb9b47776fd395b5971dc6059d936f68cadaab6ccae36ccaeb9ed8407cceb4eadb36bd5da73e0d42c2928e4b2c2d9d5c90a87deea5553db9ca1b7aa5dcb7a66d7af5265dcbdebea5495a244ae661aad99453c2764a03250a85dda5dde3665adfb925e9627912dbdd1496f240d2b97454513ab863844758a12959ed79e5c35b4d97557cf0e58c35753d59ea69f3ea41a098ef8411b9e61e713a321abf10302dd9805bd102542fb1f4345da0892255094b4075642c8426ffe34f41253ce9db487f13bbbbc58b70dbdcd904bbaf5553c94c88b436f601403dad7f7ec4825a1dbb3e32597552aceae5f7a55ecfa73533d3d12ed4bcfceaeefcd99446855f5aaf0eaecfa5e1c4a14839202bfa627964fce2106a79def4ec633cbe34e370f33e451ef200ec5efc93e4fb72a59ceada24c96536ba8872c67d6edc9b2686b680b24ebd3f4bda23cead3aa4ae4263179542d22767562d7bff5832ed604523fa66f1b7aab5f05895c52a8cf69fb7bb58b12957e237c72c9da053585c37604a6361c3de40103039bbdc9a58381d11cd8e77093e379b0d3d5d51564442ebdabcbabab7b50e334f97e59ed746495226e1b4d56c5c9cacaa24920979e95a545eaa06a63656545bbcaa55b595d59ed102222972e2535e555423b767027cf79ce7343e4d2739ecbed80004d9610bcbc84c8e5f40ae1cb0b8208ce2841a1b7fa5a53ab4d2ea71694b915c14d07a1ffaf0591cbff1b4d571b767d304348734e505633bb7e9d610e71b24a4d20b5ee293964af7fb5a6d1dcf5af1b4a04df3694e8eac6f982c24b560122971f4d839921adf1ef11263959854d2e6f9b7ddb7810dae8c3265af2c3ba41850c013a943f790eeccb6bcfaeada955b467fd26a4f9b50bab5ed13251356b4fbab5d8b3c6d9b34651a5d855ce9c6a45bd6273edf965a5b36759b5b298587891b9cb4a859a3dcfcc20a557b1fd3f2cb6bfb7b5fdbb2bb6ffb562fbdb29b67fa562fb53ad55ed50a2e9f505f6219537f7b4eb9dfa55c1724f505253555616a9b457130b2b0ba9b45a7be6ecd69eb62bcc8ddaf39b3cefac488395e6aa4a2b4c1aa74d691a3c4bb63c48736753fae199142d7239b13a2146e86dc8df88f52e74628b8484fc8fa1395df8ce88b327d707e2ec72c88cdc96e2424acace7e1ad5796d19dab5619293227cdbbb5dacdc0f1c7239646dec28e675f7eea22121462a133bc5896ca964e44879785125c36dadd60c1728c54b76cfb27d5bb23461d7d9ce76de90cb71a4434675532f70d2211144e8defb89652f93ddeb1f7b1074dfb719bc36de422a0f96e536587197db5d6e839dcd6dd0c31dcd6d3016f3c4eeabbedb6ad0e23a521e949412e5b4e63e7ecf846bb5b086fe62ac91407bf1d34d854913b820ed294465b4ab620a0ed7949b3da566cfa91da6ca906498f9e232d33515866b2a07872b0a0b3261cccc996301d7183864cadcc1f2b4e8f410a78726e6a4d3c3105b8cc9e335c60e79862bca8b2bcace6c5bff7e56ab143885ca4fcba1a0a468579757cde59eac16d5ba5f5f601d165696d7d5e5f559595dc5b4b4b66453535520d6c5ba59505052565657a297cb3df54c4d55e52fefcb03f3818292fabeafca0638eb82f097fb72dfd3b64f69b11aeeea1a33904b4fcbd3f2b6b6fd6bc3402e3d2c0fcbcbdaf63b1c9e9567e55d6dfb5e8e9ef7a03c284f6adb8f691ae4d7978eaeabebc2429d56a7d56d6dfbe18e0eabc3eab2b67d11825904dd5437d5556dfbf956e3d1e5ba9c7d1a3dbebeecd7f071bb6ed7f5daf67f7e5cadab65df06102dc1b5ba56f76adbbf114468e8425d28fb4113dcdccddda76d9f46c1d717d8b65fabc076d92eebb5ed8f427a0cb15816cb666dfb38888010b15376ea8b2c9485b252dbbeb6c0e66cce3e69f4f5655f47910a8c602dadad6d7fc705441854ab6a55afb6fd0832a85353f66ff508ca3e8fdd03c9c811dcd5f503490649186b5b9ab5ed4b90e44e2ea9955590aa844e4d0d2da150db4ec0240900f8ebab82264b34c05a5a439c5820978e8545540350815cba951591273e355504250051f0d5382f231cbefa6b436ff6a38449be01be1a178691a9e475c16725250c0ca65cbd0046815c7f8654c038aa55ec6c0e2ef05d7d5848e167050a00df0ef0fdacb6fd2febbba244e597f5c5f9acc694d9f6bf369f1bb7953e11636fe90c5fea9f169031e014a2b1271d1ebab6a77162e432e799ffdfe8d05051c53acab25a50b66e9795e9d5cd2f2d33a6815cbae79e6463e4d2a1a05c0af4a929afc26e657515e2c9a563618122f634ee03b9f42e0f631299bd7dff62d6a86ddf92b6be3083b818db92f1a22793e15f3efee5603e65e468e47234380055c34249d5009bfaa153553f6658d9c85615eaca4607b0803e2c8a05e4811b566b6bdb076de499cd234a450399d22e2fa00de4927ed12ff006f634ee2bd72a5579d82febd3b60fd2bcb006de0d58c8f5411cb6e6e8e87f5a46621da250ae3b6850087e3c02a0795b81870a3d9e7ca4f0030c902f123805f13284c2041474a9007b7a839c902161b9be30818044d8d3b8337259a16e9846e1dbaf364ca31b6fbf969946406fbfd6308d6cbcfd4ac334fa79fb75866954631ad178fb558669e4f3f66b0cd328bffd0ac334ea79fb356a1a896fbf92a963ea0bd3087cfb156a1a99f1724fd823de1043a010dbc0e00f28ab218bd1887d3e9f97bdaea7bbe20d2d8dc56cac8631b2ace190b0498e0d92327d65df11b98d918b7a580b7e1849408b0cb9110ae61582015106454746db081206f5c8119d6c9124d59044c91226006852460327017802250a6e831a94a44ca142439519381040071e0c80001f58912a80010e70050120242084310a28b148655900031aa0658b08238c5922a1042907303d00021130e1042e4db92e28788972fa024686149e5458810c0b616210d3021917a05e1843260a861864909a8186a81acad820c30d66a6702093830e319c41436607aaaa343cf4a0668d0f3f445949b101228836420c1145c495046428c20837479041e24d145612314c204a09384b30d144161927a29e9082224e145244c9d1929a828a2ae6587145141658c8b0c545270ba93a5a446dc1450c5d5d7841e60b3b5260c4400118c2f0aa8005a22e40e60e063220c69706c6d8001e32cae0c01830333ae0813c1f38c3c3725d50f0e2f4054c0a4f2aacc04218312db800f5c2183251304449cd4069a8c196b181de60c64ee190c3a7c31934358adeecbb186152859a40ec53d140cedbbfac50675e40833dbd0154ae9edec0855c3dbd410bb97a7a0331b97a7a8330b95e2d7b272364f21bd332a113d977d7be6b55294a54bad69c0a1567dbaf51b696f10ab89787e1147030dc8e7fe15e7817dee55cf816ae85d7f12c9c8e73f99663e157b8153ec7ab702a7c0ad772392e8547e1711c0a7fc29df02c6fc299f0251cce0ca2d7a8248bdba8821c3234230000000004008316002020140c08c562519444619e15db011480117c8a4258489fca03d22086511cc4514c2144002140006004464846e30031c958d09429e149380e9a18cd10b66149860fc81709b6fcb3106ff15d15e8809fb4d3b65810b5e72ae8614ca4e35351362580f4271baa4cdb6118e0d88bf99deb30094bfaea69e1fdb4bd0cfa20bdf0668e64302cefaa268d013a155fe8ca8038fa98459b9b136e5816351d546fe02a1a33c223907753f849294138fd03f7a97a92e633c4b1fc57619ffd2a843f1bd8d72ef8014cd705afc876838e73a35ae1defc600950e14a7b162d5e77577a919edfdda6e175953f43fa8541e6708029a6b9fd7417693b483792ea893b5acb712be59d948558a39e0d2ba59b65fb3e951239232b54010b60a88d3f3e278835ea536b770033bf530ab62762e8cc64f199101369723cf1c423a61001c2691e5c2b23522bb64f8852d5dbb513c5b3bfcfe9eab2c7719df6598e3d5facbac5cbe8f144130088868ace706fbec9a15de7694ee48f45b626dfb952279b1930359d5f32ca664b45c04d3a05e6dcf83632992740734ab80a2090546a5d6de830ca8104c1f6e1a4b32668848ac09edb4a96dbfc56d1fc24239fa40ee68b4efc133ec485230de8021699de9120bce4c91161295bdc2bb71a12f50c2fc2e83b1de8403d5d907046d201823379b82d75e6b844d7135e989df130937785c0d01ffacd4e12251c2a0ceafd16f07bfeab933faf8eb857795af9b9006c27cc255fb3cfb7e49cf85d8d6d35ffa0fc74f2e4f0d3b590e0c016c0123cf6ac7075e3ebc94cf6a0e737c85213b9f04a181287b6040060d074238c0925c634e6dce05f36176a041b0ab6041ca4cab69cf16928c09482bf995429abfdf58584f5c53ce5c335ce0581f0c8fd5d885ec559df77a639489bf5c3a8d5de45257527aed497d03275c517af187c53b86fb10442099ed8c01e42be1df4099489d08e89b92864db9952c165a1035cb834039301ed50db574d2d8601aedf672ab89459709c678eaadfa452f6f765ac56ab196f426bdfa3730ec4896d166d303ea04bcf32802fc9ddbe3941d3ab49b44295f1c7a92c75e99f2207d38b2b980c1c80fd0eebad869ace5d36ffd9ea235a141130c9da20b68b791b0f79a9eb2c27d392d4801fcc1decde51d1417a51ab07544fa1ef17e1ea471e268a09139ca475ddea0f7f10c2f4dcfe2a7ce79b25622349019414d877853781c7da18d10a3cfabae15a8f4145a50ed8ebf57efa4fd23b26d6bbc43723108c24f8dac105faf0f03e8f553b53ceb707bdae112c5410d9c41b27f6037a5d0ccf28274c4c47ab04f23781044e08f0c454a157e8a3f44e145cb15c0ed715301f59173d99acf5159ab6f6d088ad0e673d466cc56805105bd1807d145db5ff5d97f3a7d49c21d0e53284bd73402ba57510f5407af35946e63887a4c6e8276d300ebdf969aff306d66c3b867b8215725576458b1b84a80b9ae6d643e92411f04992df9cb16bcc45811b963982156de46e7e61425cbe904554ec19471d7757ccfc2c4bc8d14c5c1d8ffa06624d8e70ce40bfd524ab8158f4b8584454cbeda62621c5598870ca2f5bdf5da726c35262deb2ea38b3424dbed0af2d3063bdf5a349ca11a593853fedd36d6dac9cf3f3d6ffac22bab3b46562eeeef9388859a9e12eaa62c64a01fd3b43123c7f34e3e3548c7c4bb14e0aa2fe8a9a4896c90420152896a4e2bac528f22b0dac9a07d0c6d23bf3c8499f4f11045f747e0dece08ce9231eb0012e3273eb7274cf6a6fae44cf951e4040e3eac08de3e680f0f0368cf8008b98e1256cd52c16ca3d024e9880aac39c7bed0fa891e6779df0e7610c4316eea493de8ab0e6a539ff5e8fdd016a8ccac2e61509f450d7f5583d6b02a44316d4fb20e8d9d2dea203b6468d42f9382bddee0274332776550db14b232563a47e9b664933393f666fd1d071cb0ed3640f2a8458b7a376a9848173d177de607fafc743acec9dd26b774f660f3f45024cae6242949c4e498b07cc7317c971cc0eb4bb9dba941274cdc8dcf45ecab42820cf9d108e34761d8112af4f73919430ef33691725229d1e2799dae3b674aeb39ae6dcfe48c673296fc1403cef48bcc7b06bc4178fe64e810f604a5a5800debb929e64ed1a81a02a0db88ed30d9c6e576024057fa4642dac75f5876dc95496b799da4a83ba4721d0b91e3a354691e2e9cab7b87f24ef269bdb2c88f63355698bd69fb911494bb611a73596629bddf36890a90b485f3f0e8c55be05fe242fb7e704abfd61e9bfd23745e1e6ee87e6a6490ee3d39d3e34d786d55ff7e7c2b3d80ec63b741edc324fde0dc6bc3d60bd1c8e9c443827326276c1ec47550dad3fcb0cb46ecb489d51d80cdf9583e204b8ce3516aa7eda3bc4b78b76d0b64ac54d12ceea7a820c2464fd21e3cdaf15c5e6ada52b67746b928c04a3b28fa147ecc3cb545a697ae6c6e9279112142335a011b3256f40ec41913472e2a04e41a73dd3e61a3678fe9501cd8e570a73100b15927a65a51a7faf7f910cc91175aceae154c7de9c88860653115342f5d1393bd0b5a46b111b7023ab206ac4f4a72d3af287018d10e0c53610edbc9c05f3b19c452e6d5027a2919a48338bdb417d98cf30f0ae301a7203b77ad0c6eb2fdb148cb45917ce765ae9913784f30a2dae51ccdb68395fb70456747e436d1600047bb6bc8cddb69382c82e5568f6ef38e98636cb0245de35f9981d24d7ea562249d84039b42bcdde774934a9266d220b8a5586caf07a514abc8b16cc2f15cd9fa0fb28a5c4a5e05d47465b944a0fcbf920ccbb3010a3ff213526547c334367d6e6482dde56c0fac6a88709287cb9cec80afa86a8164c68f55fb19f4be3ed65ae432d86d2586f290afbdc70f54c5aaf04df79300761afe1d8a6156eb19e1265ff6a990a54304dae285b2f0235fa163763a2329e37843f3259106bd738c4e233ad6e20204144de83cd3358bedcf4738537ca5a4a69e0da203720197bdcdf71fd48c1cf3031219e1f054e6f9d9370ce9fa19af1d4b3e3e9d88d1524a9269a49788a0709f98168c7e66d24bc9b28f67f06279f717a85554d289acfc512d7dd2a66ae78cc7f3d39e2e99af82c5aa688ebcf2763419b77055c64c779fe7a9a40d6d3267479ed9b726f4cf92103284b25f595d88abb47094458b697d410fc441e5975c87816fe527af711c8f7ce32b1202c8b1402ed9c59f9479cbb5eeab268a77dce7c7a539a6bb537787cc6e3d538be72dd1f41e9fc3a1858c45fbc47d79c212adcfcddeb00a6b5fd462c309a2077ccf1dce75a3ad775e89c1e3609981d0c37e8d7b55b7742308317c018a2030186c879485950741cc1ae5786bf44c87cad0437d02db4c19e88615b85f0efebc4f9c2db268e92fe82ef84ee277dc8dee644703bc41a79bd7b8a2f758ebb02ed665475c3c6f12f68252b74242441cdb7bcef12c4cb21ce92e39f37b8dc8d86d7a570d86c3fd4c2f76b5edfb2d84fef641533e9e05ceb1960f6882997309a9bf5955ff17881fa42e102836bdb395f41e46fa668b67305a844f14dfc0562996b248075bee4a7f29cedf2a912a7d87e9c37f99a51eee696c4d3d1757039935d867519bdc41d97cb2b498d50150b802303bf8b0ef1cf51ab081aab88277b93b402a710c30cd4073384608110d19128348a205036f59acd0a586b086b179af7646470549b8b1100cd48b31dff9b8a1c65178d431d05a74b8a7e610202ce31cecb004ebf56e027690a91a67af95ca4cffa670c506d80b785933b28811c34eeceb8e7eb93034677c1b7a5a341bebcbdaebff080c0b5daa2a9e81fb608c4fe2bdb74685f6326e4568416dfc1949233127f6e83dbc4ab62eb5415d1135c1f6592513123d51e338565006f11c30bb3180507ca0930edfd183288d887e85701853c9e6fa24201671788459b96eaba1823d0bacf4ab44b4f16fbbf889ca0f4c800ed3a9274c12ff0406efc40348544ebca6c070e613ddf5467a0d4ec464cfcf659bbe1d84119ecd5a3b10738686c1560f5c3754fd0568e5c5c698d36e8c7c808c7bae5fec0f3c5bb4981b842f53cba0014c4febc41522feb1f0c811ca83f17a8b540331b6ba4e1408c291dc53412d9579fa03e2361229fe49829bd09d727014e573e41411f11e01eaaa087ee49a07bd3162d40d028214a91674913518446baf5aeb67ccb67e426e4c47746093a014ad1aafc37508722f7ad3e7c213c870c13fe6cd114d4b2f0fb629a00eccffbb91e6da06c54eed86bb979f7b2e93804358fac34d23ddfd7df0138a4d56f6c26385364129ae00f84d105b2d25f309784808b4a738e974c5b298cd568b7854aa3982e99a6d24cabd12a039526a99482a652c8cc75940e8459e43bb13a78402087fb0ce0531a385ff3dc482c26be647c0df87ec924456ac8770fc60c27ea716abd12d7daaecec5fecd7d55e2e236d4d425c96aa4ff73063288720af97b79510e4271fd9b351d2890052923447e91c51f960ae2b13a2de2eb4c27dfadca345a6b01ef9742981f2555e7a99f2403689ac25464c521cfde306a36c49f67bf955b54260309432e5a57c27c940238f34212a48923de5ec903682dedf387e04c26c18606f73360a6404dc6d9645d16b905e8c7312beac50c216b479c3d12ae505561f39e41333866d9a3b52178da6dce9086adf3d44f9201344d612ab24212288e2f90c10d8df0f2571470ef2a6f6fd138d87ce608b6e229c10313b60658e3e91222ea6fd01af0543584ac1d2d2bd81587e12ed239f7f7443246d3b4e74d7c0e7750b22112cdc23caf75425aae37f20ba5ee4bc015bf37f69743f820322a575698f38724cd01116655cd50ec2ee1ea41838a6c71e2e69b2b292d0f11e08ffad1066e2db09966e3fb7e5bd521b0416c0d45f6ceb708896251296273993ce20c214a729d59970014273f5dcabb122f2565660e31c8aa2f1f219e64338647cdde4531ba10a99687b8d9ed1367c806f1042f7e51cb699af5a599137e549ac07550abdd3213986be70400af24258b92afc4dedca6fe43418c1989a9e300cd6933e3c44518f2a43c132a842bf0877d6f44e1afdefd63abfaeda904f3316b6f15fe5f90458eb46a71b043653d95e7bbb6606e38ade3dfcb400096bdf4cd0cb10c9c279ddd83f257b696ed1ae2459945aef06bf4127a662bb150b6deb84433e489727fbcc9e9592f45a436b31d0ab0e0f769b470f249ca03c75b88b8d130c74363f8789c75ee88f78cef9ea4f39c79755ba8eb08f6f298a49b371aeb862e0c00958188c7c2c210bcad4915b990af6496b3555759cc5e81b7f3f45df7fc84a92f26cbb7ad6a86dbe11ee4e0a3db6be3ee999e22144aa14fc8f3290d717bd73e57ce2b918f4cd4181538b4abbe5f9acda9f0616bb8ad2b41fe4066b91e001c50b9a8e57db50716464698b5213895261afff76be308536944e6f3fe2d1c75acccc96f0233093f440c759dc543072a5b5a0ed82e8b30bb061433aadfb5ec7dc063afa51906d0c7e4a3d1a79c0842bc77a1e50336b60b7ad541da43a5e2d94b70a8dfc0a9575a63abc9fd221f0f1815f1bd8ba043899e366633877bbf1a038fb2d7a7cd74e8b8842fe165a97f50fba5f2698a8b0b70575998affd80ec42f30213a1b4f4e66b72c7658f4f831f517c7d6dd8ade7f7704766ba0fdc6ef1e14a9e7ab927fa201716cd0219b276ad6cd08fce0a777d6dc1dd638d97cc2f5cf9426f4c7c0940e255b33721bfa0db133e2f389c126162d5262fe15fc137b2ce0bfb03827e9721efdedf9d3270695ea55d43d60e78a75955419d070250860018cbb479d2711a7dc0110194c482d7df240b60c6eb6050ba78c5d53fbba5a5acdc232c5514ac1bdcc954c682696aa297901dfe52f9a4fe43eb1e8506ab2e65f5ba71bd86765021c29a5a8df6e5b80ccababdfd46f51149e2d6407200fbfefe3f5f0f263a56a8d169e8c92fdf615a00a2699180dfc78f8d1d0b1081c358b6dbe9f52eee2e3dba4790c40b754f09a1869b727d811227c4b08d0abf0d3c5655ffb1506c5056fa420ab4299625af1139dc8b6551f9d8c3727d4903075bbcace24ea8b9165d237598a4af222a81435d3c8b928fb1b81b9c4158a3fa27d23851fabbc570a2bee0a7fd8db75a0912ceec36aa95cf511e472078af389ee125e23868c7b6565515007cf0ef6d54152776d96da1d0176b9511e001bda766515110bb521d001e90e3f9f900039e1d9605d4c312c03d5002a84324807ea0076580d50f54e1d28841dc55289768b94663a1b50e5a34c9ea480b1bc33490d8985ad5911871a8b3d32c8969c29ad9a2c465d50026f6d9d2a3e7710d039e238da646a2ffd59c0e83358bc4f87bfebca8f0fc3559e6e64f229abf68cf993f98975cfe0abdf2b709dc4195bff9048bbfc0c5a6913113aa5efad438a1e3b72a58847103bbc4bf39bd8f970b6b320687b9b158f5f4342f7c8f18c2dc196f63b8dc97e60d1799f67071d5914c909f8d81b7750e8e1633f05baad9c49001ad2b8709ae1abdcc7d91244356a4416aa61545e2559afab74037d718c959acb87341ef313552e3d9dcd910473b04d188f57d8ccb21b2bb21f7d3487ed2183163ecd023b25ec167ec668a6d0f74c801255d003f24b901ea15400743617efab095b3347093e056d2207eae98c1a098377d64f528833345770f460705cdbcf5512bb7d4c2e5e6b01c90c432e55f667e345db979c1d7a9d415f7f745e2e188ba314ecc224df4e65763781506f0362211ee84b39083639ce2df0640a5a8748e2eb3a499534436b00330bb1921493d431b5318d5540adafcdf5311433b9b997c117c642fa0ae64a3ef96477c296923821509d5af589da1ee98d9a14e6d4acc0dc9c04d1af23c3dd80d49e02e0de93c3de0c64a06e249d02d2b29548e9791108a356ebbc09dac1e7b1f52df987e3cae0fc84d33254374cf27eac79a95c5e81d7f6c578f1bb8570f62d321f3ea7dc8be00ee03eb29c97e6d3e7575c75c80fbaa53be5980e5cc79a6097d12f06bf389e5d66b23c75825e3983e2961847bff653708c0da6434a0071de5b6bf8599a99f2c2d9785c5e1c41753dfa62ab742f28fb853144def7f3e798bba26430f2d58d6f0041f39100d3bb15fe2bbc4d908caad20cab07fa60697dc712a751c00256e4e5bc325c79842e4ec241514174094f1b65c0d269deb54ea56004ad8bfb6864b8e31957a5c80a2f4c7d6a0c804c9ef4ef8016ef2212369cf46288176f81a7dae469f82c16edbe8c655cf0f867278f3b7955e5a1db074d3e1be7e815a94213987d3a748dbc4c9a2537502321ab67e0716c4b339d590fc909f2c4668c507ee45cfd1ddd01a26284f58b8e1740ccac1a3c1984ce99f7018d81c3877979d17e7d2b1f3c83f3a063cf8d73e8b07cfd567e413a804c76cd5b139579c4557174d2dde99ae8986804321550a0da9d0fd534522bea7f1d7eaa57e1c3ecc0303706155c85ae8883cf426f86e8a08a37e7aa5cc7fbf1af6f9d4953e233cd365b9dc8b6df50e2b3a7fcd481dba2726efe05afe2d30b0110d8824015ead8383810c0e32e775d875668c894224f7eeac65a2b8c87b6d3b7310405675cfcb221e83206b14cfe7f5b07901dfd1afba40645a2bbfd78d7e90c082d43f2e6ac58f4d0f0946b629a89fa37fa022ca0ac8f23334ee148e5b16adaf7aeb90e9f20ffe1284ca6f42a754df22c0ee44182644860e694afa38c779c7440a90d0081bc128bfb8c32dd608794210868faa5cae575d86b6a2cc2041b519a2439d01b4f819cae6d0b06bfb7a53641105b8f48aa150eb7dcf790a59c14002c885aa99cd0ce77a13c3309119f0a8dd92e73dce3b1b1190da842f80ed61d1ff30499340653443f17611573c1d8d53ae2681e7c8eddabe53d95aebfd6210b054ecf5cd745da8ffa5bdad2cc6a67bf5412dad575ee71ad551281552bdab26bfe538eeee7d814ee7a1f76170e170ebd197fb210abd57a22318d8725bebcfbd669dc6198118451148a77e803ff0ebab0c22b1cb1849713748d658a55451b0dfc774893729fbead8725b7f19ad03cf0c2962554145a6bfb87021aab274fa55be9e86f4a9f44610a87028531d1ef84a74ff088e143cf8cfa726de19ecf7e78a5741d068e5b405a95f05107148182cc1c1be7a0ae2dd3c27293d65880d274f08f25169a714d0686b8812c8aa048f487a2971e87228c74ec82de7014641b36b56f545a337224f33fa016350da6d2770fc527fc52441d5a039ec3b0ee93f55efd917627ba1499de40f68d63a3a5cd49c17512ed33c2a9006f51c327cbce74258a220d36e29c2813e545c827c61e2e041309928a50b36fe95cc58867df0af623392f5797862d7e5ba3b11a4eee93b75eb5cf1f635a061a15336db0f65d07a6039d2490dcff3c971bca2e526ab0a0ff4d062e7c39284c3e9baa36c0647c94672606beabc23b7e5fa793114f4ca90b1015c6efb6890933e0ddc1dfaba192a65ae10c50d298e80c8efa91b07661d8fbe22855a36aa3d69456fdcb642c1dcd68c6606f28133f3b8acc7ff17e2e6d53003aaa9569e3c7d5f080be51d27f075fd6d368f889dbea8abfdb531ee31c1be520ffd8bd18f40871658459dc98ae8596f00a68079b91dd053e2569f8ea65e85b10d208a9c1d5d236802ef9258e06891d069e498bc52dd7ceafc993d66a06eb9a8ad0d00e467882227f50006dab3ff8b845d61a52b3fe63411428a5014452a43522dd62dc9810024ceb8e1b63705c506c7de2bcac129b9444131213f6ba237671d06717b0fdc72127537a2ddfcb4d1dfcc8aff018b2e56e61bc5af3493b4a38ca7d3cd403e11c34103cdf5169610b8c4b076aa155d2ece6b1a0470731f8f445a33a8a9d5c114e31ecad4dd4176401f00797dede25c42e0315f27017cb12411844360ed8fde4ffca6bc5635be89661faf0dcf0c3c26754a140f0ed281ac28db1439666aa7975fba94a7752f1a45bb492d3ae3d4d6b15e26ed0d596a3f3c1ad21ab1964dbd3ef8c0c372327ebc6abfeb0b88cf8503a52d3b96a6f9382a99cc518bb5016a669bfab1b5667f1e52379d3ec00a97c3ad3cf2c0e467273e802c5b926396f7325067c65cbfd2ea10bc4de7cab68660a6bc96290411b21c829ae3576530d2decf5bffa0d7a63e53b9fbf949fdfb899229d2b752caa0e9cf983b907f2632c64c1959cdb3dc390dd9ba2b59bb8eef73c1cff51666df19ae8a735b9f720d90eb9006434560934b84d83aadcc421d04842a48f521d8ab9821c2d262040a085a1e47836a669d86cf8ebf453a63db7f49b7ea97db50a03e3f9d0eb7039dbe92278b892ae9e936058c183df824d4adb6df21752d4410d8638bd4832db7e1cc89d92f2401782f8406c1f01fe04611d70eedd144b861ea971cacbd13dab54859f3732aa848d4967bc5d7528cbbc12086cba7ae79333be9857cc3508817973d58bf7c8ad38d3dc890f3c361d221f9d20e8e1aa6bcb3805e0a0aa11500305920453065d99f79fab02e578ce99966bb74b3f6e0fcac6fda5f5aded8fc41e6e376237eee7c7ac003f9a9b4333baab4b133e66064a0dcacb74d2dc40891d1e96707a4640e40f77369684db3a2b3a97c7475d889fe9cda45eef20e52b7d1bd14c85a81199f16fd08f66cd233cd5d1b348c20bffc0c176c57c8db8679afa37e6aca9b5b15ea7a23aa90de20848dba78e9671a2e9f4b097aafde4c1d03e275eed286113dbc026936d8b2d6f93c1da1b3b7749c83d5948546bb9759f15a7ae40c031e243ac65766f1b94465048f497a3e7527c5432aee7f2fdee6dd2cd9dec3ca95d249360716d7bb3989f94c6504d3b4c5a64c3117df74f5073094cecfe8f3b97af404ecb5162c78336a84e580b28b4997cb07872ae42f00a5b6c19323014223ecd77b514742338e8af234eb64436a44604d60bb7a6114f3f00132ceaa7d7338820460184c7e009f52383eba240c7a2a4e1b8c1bacb026d173b5c9fa43b2749040343e7462158c4aef4662a19071087aada720a51bd827fab8500ca9426064f8105810211f13042dbae0e4acede26214946b3df0f4abe0bc5ae5b062dbe161ffc50ed2abf531d2f60a1e64c795544b7e7e1893db30b375bdb824733f3c5570e772ae5b70392010f280bc76e135837d00c2cdb4bbabc00391f960cf86fc88a312d28892ef0046258110c53ef0bba3628201f06f1bb62f2824ec1eb38f9a286bb07af183ac916d273cab934ce3c6dff9c27ba787e26109d4a6d01d9cfbe7126d918bb6ae028097145ec972b26531e52fd308cd060c1877dc35497a65b7dd4a9b82f31b5fc70adf845c8a47d2bba1561de03f018b4254e5cd47d760f5c5496fac4ef1a3e034c400769479679e450b8565257f622d57914d37c75b6e105bae1177a707c4413b295e3e238983fda01f1b9c65c359b3ffcd5adfe431e584ff38103fea0843ea3f5ad085378bc5afc6f06185a86114d2bffce38b2a76bf1e7a5720a6efd649409a65675b07749d1a613ae620f121399c5903be1f4c6d9af626dd396dda8826d50d84b6ede79acbbfbe612b7d5296227b36bb73fa459616954bbfc5823e008466bcddcc071c318352171b848432f8f30fdbdf8502e675c49e628cf1bf0638837e0b4650a48b5b948137555d28c7445bf2315a8c5709d943a040194e8f2718cbf4d0eed81f75d9bbb3f1e47a421b1b150a0b688b41d767541753f99b5d19c3b7d95c1a496e7df175a81433885dd4dc8d5fcd525bdc8343cf089703329d404c7563f0b0a5b8d6acd6b57a155c2d08157a0dc52b318f7d3b3a68fd891f78aeccbe15591df43371e1469812a04835b1919fbbaaeee21a743a88bb9356f5e805569b0f2c93362327e5c5a71f362566660fcbb5d4e01b83885ce661189e46f3d6fce925407feca6042db3be79896eccb70bf4a328d27d3a2799c53354de88d893524b0ae309ecacd19cef53797f15e2e79661386dc431da3fb6de38e7f96326b100cb4944e85f79476a03a94f6f438511496c1ef044955c1fdb163e22a14d5f64f5b4633118adc48fd346b61b60583635bb6c300a6e6f38546aef4a11735e6e86da43a083ccc6d485c2dcdd37855767579ee3649e5270109b749297b9fc2ccce94edcdc67a7acaa54bcad9b8f214cf59279cf2975cf6aab6a6d2afc467f359a242edee73a371c9a3177c923ba7e5b948fd8e8fa9be482972a715e3e929177cfde685f7718f8d4c16edcd9c0746c0634356c49b4cd995c59da8347c42e3125226d45c7e563efd505e59f4a40b80e8e5982eae4bbfb0530780ca1fff24bb19bc6cbcccaad4e6cf817d36ac9b1b638851ed9e83ff2281f937a74e620a5ea9be342c805a331d39bbbdb7d6d356e5c71135e13097829a5b9c2c2e66acdc9ce19a131631088cabb7bae260502b9f5dd3c77fe50a9a376d329dd41e2d1d78d5858461b45a7ba5fcf615f81746c77920ba6eb241b69e83f1999118166c3f34ae1549c1848c6979e66af6cdd805ce80fe29b291a2f39080a0c490de071aa841d3b9c8f9cd8edd0b18c68ef63d8d2ee49cac01280a9cf357655a238db61087280765ed51e670bc68995b5492a9bd4553249f4dece62d4957316abbb1ec7308713249f405b33625ec8408b299d7808ed4c6c65255892bd7c62a62bfe2b85ac930a1f010d1bb5baf321897bc46233e0573750a9282c3faa686f132ce007f5d39a2bc5936152f9425a6527d61415ad88988565f62fdd48e9afcbf85b39cff92362b15213066e8a0cf0ee0d933dc78b7a01e645888b69385354c74ea0289bf18f0a5d35e587c4a30af7b88cc4178bf2a48b556868dbe9564d06246639f5f89adbfce65a959bdbda4a55d9d461539d0deb17a132d85b1c54f7577d01812c0a6f20b4ab0efb39500d48d82d873b8bb2fcff29fbdc75a4403722bd199eb63effe1ce1881ae447f0332bb21163d95af8836e5dfa3dc83defdef31ad44383c531c4698920acd74d970fb8f8db1b84993055b5753848c3fbccd61076b09528feec91ea75c0a2a45908b28688e7b0bd2d9213a32e0184b02ef629783632b637d6761f5381b35f8d8e73eb5d7857aecf4bde6650097d84228cc463e74005c14c37b4f1d667eaed57f018b37a76b6b016aa48a2aae5ace098cce3306cc7797aa6a9058b36116fd3452f862fbd3cf707830bd069bd6965ca66d03aae6196caa8a2a8007e27703329a50bdf350733859f395621eecd1ab0f5c24f674393260afd451deb5864134914893b0d787d9d00f5fd1493c083c9dc05c44b3d4e09a5bcec135d5309e131d2442f6cd4e8c452f30b8b1c4ac41752d53fbbb8bf62da5e06347054ea05499c4afd30405f0841fb83d53ec92411a1fd05958288c1bee73275049f5a8c4d139b9ae9e0096cd57cce3c4cac5fdb9a28e67113113a771cb597a9ad72d34790b8c0786792a43f881bdf49465309bf9f30d3380484eaf2e8c0134564d5490b7dc539476e4e344f30319e00de61c6d5ee5d94c920a648fc434ee2baff8252efb0d28feaf2e90a6bcb36967a3a93ce315fdce385d177d63957bde5f0f7d4b261b365156c9dfbe583d3eaa90110110e9299989e24719565264a29b9fb4300889ded004b3776b9c8a04312d57c1c793b795ea81a52d0eaa5cd6b8fcc2273ebf58f1478fcf7927053a6596455944e7173c1e3bc50dd02234e8a6a22b7480a5a3b644ef5270c1870342cf2211da2db54108f7438aed998f70e258f8318d4eaea701085454f73f4592052baf4d995976507d476589f4c031f077867a40949658d40881207d07cc42fce1b8e07870d3654d708119f35fb040c0e85b03f920171ba43b6dfccef6d8117071e62e27afda0c06efa0a10aec13630d2a6cbc3f02f8cd1b6ed35256a141f7d13b43af67986fd6052f09381045404db2f5dc217077fd48ebfa7d6e062f4904a995f0f6b50b2a470c67ce46de38ef1c768c943e86b1541d96750dbe791aebe10acf7adf7cf9180e0aafde689086b557862884c807573a41eda8bdfd4e46246f5ee74526a32e27e8d548713711d35860f8a97bd70a11bbe0e986f7861df74ea9339eb8b1c9c47a71f595a6882f7e17c8086216d61f344f4294fc98366ecf7ee48f351262dcc480a0cb2606e7647828ca1b8d7ed6582f857057a558efd173a4e748aba439c58d6c7243f7d6823c56f19189ad4a44ea8a72d83ef9702c384afa7b1e9ce0cdcadde0adc56c2c6e165cde32cb468506d7ffc1bd7dff500e6216bfd3fd881abf16aa3ab3114ff8b9d155b0355b7a2807c4971baabda9f6a2b217d5dea8f4a2d29b8af6d84ae3815e4f78777aa7daa64caceb2d3d6ed0c4e70a337a9bd563a65eb37acde831534fb37acce831a3c70cbdcde831fb7ae86d0e87c25ef4a11af07ae9697658a081a58ee4e98a22d316140a8011e6d84f619f332e2d0c51bc64960550e606b7ba5195bb911f7c0d233848ef93d1afeb8379e4aa23a9b781714da7ed51c005d233379426104c2252377f9355b2b5da81b504b6d1ca817e81ad40b8582e12e04c9bced64700f55c50e784b8e891cf5bfb3694895e352b834cb8b97124676f56352964fefa554dddeb2c2e7d2c3fa9550689bb42e3461e7c12420d924dcf07aed38699a5037f1c6229d45cef12c1baa74f5854f2e68078e3bc13581e08a0be8965b34dc86be33f1db669e7c1c18b13ce79c1f23c9ed918ddd607bc3d01a87bd4f7595ace0ea2a2f81ab676e55d53909aff8911fc461048bc42f5d3ee36d33620298f82035f31ce3717c6fafeab4b88d30840fe60afb11569f83f28a1e007c63461ea701809f05ee9946e0ce84a1982a76f5204d59ff43f6b3d7ecfd60365d367dfe4ac9af4625193e8904fe571aa04effc02a986e7dd5d64eac421dc523cf3e97f3eb56d20a949d0081840d8d04c59b21b163f5bd5620102a970e9898c11e2d03ba3adcc3d9dafa7c7bb82f0ea03009af8c97a157686ec6dfbabcc302b0aa3a05267c2bc99e861f5eaffab25ccde261d9626aeca158fecefb227b5fc257d7be083c227362d4790f0406448438de62d24e3bab5e776d90f5adcb78cbd2349a75f55e74345adf64d691f4c752d1ac24828bd427a9a7b23e38d02495bb6d9e308bc6459df11f9b6ccea7b8458d32d34707753a9ad618f8c55d47722df02a0a5db7c339772e3244c5284c951a4926b617fb625da45a55f5b0b4a0cc57ffbb9270453558350df31c36d80f0319837069e8b70f0db3e22d25b0f5e0d6d4ce20730ca2c833aaaa47186521d678c17987872039740b7dc32ff1107367572a3e6147072e47b2c1b3ccc11469124ddb4c0516d944cd7e276e7dc0cb70bbd4dacf580be8f032bb4759a4bb18328de658d414e48bdb723721ea3ff59a01936358dbf89fd1a71d46044520cccaf7cca036fde8970bf449339f4e5149cc52099d7ed2f5995a474a2fdbf13fbac3046a153f4ab8bc0a4993327ee88161b37086ed02e1a659f282a2df632be811b2c0a04e52f7b9617d5d73e81deafbc69ac2abe51b85e79d485d073854f809418f4b9756646c223ad9a0d2b1a581c7013f187b14094222d5143b6aa1f0cd863013c4ae51589e5d9eddb03c17b892d64872b39d38df012a637a84ccfedc7343bd53c7e8b8866b1b4659bdd5f751eda0fc0c8547d29c914eb69d66e937a6c7afed45022c2e276a1f4ec01b88d87f99778e7f86570790d9de0be251689163dcd03602050fc7ac0dd3198d52d94b09de2b76cf922d784b6235f799cad59c26dddaf77e78e0645a8b5adb331f6c0d712efabba3487797d7e3c35b87ca5c70fa5a0b0d28e423ebac834f60032c0f89bc352ef26b0941cf6bec5211f7524fb0f8aca84f7b7487f3532fbc96377602497790a7f72e7102b3dee6dffdee03e788c004e7fb3d626fc85c9a8006ab39134cbea5c2cb968a0f3bc7df88f5430d9d1d8c61434dbd4dbefc923dda7086416336a86f02a1e92a2849b794d7655a629c162af130ddd49c980022ab65e34a32062214eb361364300fb4e942c34e077f887af7511718bf7b100fc1abfa92141edacb505131922496f951195ccd54177d93d139b43fbe067d110003b7c7a0dd432d50145c4ad2b2f9ccc24ba358a14832946b858618120ad4d82da2f44101329024876d9f12bc172562e8b23587a780017befa7cb9bc4daa7433d3aa69851d20122a99908d10b8de2a18a812ef5410fdc6dadf3f0927724112c3d723253184c47a088a4c45b4b7e0050ac81a91b9dc81f052422ed40be17c4390f21bae824894e9fa64d45572ec9d4d82239eb25ab9081f56de23219fa49f43a129cc240d49c169d1b83160c0026a474a9319000343a2833866ac5494540358437bc2a9d05b331567dc7fc27fb51a4c0f8cd60a6a2cdf74d145ef46327842087f18e7510a3bb5e3ffa16d37885d77f10b7c1806330ed2b02525e4e86248fafd65056c0526c1606ed94c93cdebf51c7048fd05e983519a480774e53a5c93bb51c839b4cf89aa45da91010a7ad37077f4e274b7a236c1d506c4b42825e968d0f25626c51998d783c379377c44a4fa2c4c4ed833b524f3b193ad6fba0e68eaf7a95f82b82853d30eb1fd7a88471471a3350e8532ed385d1afb1f189c685e52aa8849537cd005373dabe5ecd5bc516f8187226db69ce2a191b72833778da2ea07cfaa9f5d84e288c49fae3401d1b7110ebe99a54df26cef989167a6f014d8664f23b8508919bdfd6b601b93a3a9af7d6b956b3f83d833517044dd8cfe0b3a27cb8a44c2d3a455fb24a53c535958cdc79208121d35f90889b51763f47bc3ae83501d11e8fbb0ab8bb83bd453de623277f5a9eb36ad23ecd4d6c3b500e488848e921031071d979cd02afcee5056459637b6187b968046f3aa71365e44ef9273cc9a6bf4de3c7fb29fe47ee4cc5e509dfa24bcfad6a4339aa980f26047a18dd20337da976cdd39a0063ab3772c78be7a8be9eeec6347128d7df5c996ca35173e5cc627b0d3e670b948c3eb7251305459fb8a9b0bd0889d59f932623304c49a3861743bb4283553194300f54a188691cef065e497293159a61639c850457314914db34dd4f0af256c744eb6138b918f7eca30f1e81acaff24763f06fcc73cb5eeeb6536a8558680f101ad8041fca948599659cc40bdf3f9ea7fb7bfdce8c0a170d65326746f64751a3e99def018b301f6319fbd2753972f0323ecef243858c40accc1ea56967f1dd63fb91479558808ba17cee57a9d8d027e5c7cfe391a999a7ce7e432a98d0a836f49ee3fc9894714f37ee2573b2b620e1260f36840ff1ab1ce09fcf8d5137dcf090b242413e9e2ccf50f752319690479eaf6f4b19d8a77937ba2d43401e012f18a4e0da00018dc4f382abb1102a2b927be5cbf20790b919a351186a97e1be665cdc40ec00aacabc6d58b0d8ba569ef576fc65f13e05752abd72bb19ba59ee6a3b8c92dc16773a238ebe4eacda758253fcae1f42e491ac7caf671477b7c1c4b8c156ccc4a702457e5eab400dd6e08ad2f90a9a56d6e104eab158ebe13456c7a8a0c279ac6fe6e2a6c4dc1cd2646d683a03dc473a2d9e062db818e22f356e9455257818cf5f955e3797f87785b6ad8cf56ce725510b6c598723d5e7a070397723624a373296c6be0843273457d5d247c567baa8ab3a06d6da10d0da8048074924339fabdb07577c337a378c25eda4c013efbae09cd16d872fe8c31ff4a66f1a19d5bd720df05dbe7cf0627959c5d9d2ee6ca25c9162b2206fe63ff0a916c58491afb17047c8a0d186dcf907235fab4d4ae566ad83084301e592e404237f3a98089834c508704d95dc51e2d474242439a073004a88d73c1700e10105b851573e607c149c32b6708e1480f6fa5f62e490e282bca9e3f7c2c7bb9f31081eb23d398ced1c65858fda3dab0041578e724b582fd306aa0a512006652b35bff018b106d2d8e4746ef2599599be81dec1f6796818d834b1d61065550a37ecfe98a7c546b625c0ba0b362eca4953127fa7c4160ff8405c871448007bad716a26c008a257237ba3517003b3470196a74683ce6b701b918352e03230d901ac5a23b86343ffc4e9608d1d65e708956185117e02d1b1f926f2e46b73f7a50407d93ebe84f8440276c91d70bdd4a008cff78fb2d4465e252ab4573dff0a4ed5bf4b4e6f087a89e03adcc57b55bf30be64039ebe9c6ade83102000b4bc67dfc602dd2e93516b65b6dbe1a8350a180f5187c251ebe14971d7b42ab05b809e193a2899e3347221c1308ca6d89723ff96d341a23f89c24597dd408b4230edef83d1339d2d8d362f276239520fb5ac57895204ac88b2f376ba05d7805de2ace9ae03728ae6ddb6126a260f3fef35add8b305190e66e8dbdc3cad9077a76becbd4354b83ae994e3e54ae53423c8c0458c04c20f18f5ee9088ce6c918388e5b33102708662056688a26c238facdaced8147569c3bb558a1abeeb8a1e410302a4ab8ace0f3cf3e742c48d3b1493d0b8c4b5745be684381ba4a6fca3469b515317abf81506596407ab50340f71b97c1d08c719195c520c31bdf10b1e3d272d19ae4245f8f6522e388ef3c99debe69ea976a220b08be355146f4012d0e5cf501eec4774a576904831d21b52cbc94beb2e35c78d548f0b1cd848392fc55dd5801467c7e225f590961a4a5c8d73394cc0c69f50d2d913ca159d3b83e98cb9618a938488a5135793afe36dac61ff93a2151e0d6ae321e7242fa0e6151ca074bfc377ded90758b012ba7a0c6cd319d033efeb359833f5158ca6820e99e2bf6c3532da96ab999080a58d2ec8c8a5a1ce849bfc8c11ceeb69364e37ea7a66de1654dc2680257dc972d85fe839412431b1ab2dd7f32b7fabecff91798d75ded7ac7712665cef00f156f4ba9430d29e3e5934a34f92cb59e29609cde2f1e56ec4e335dc212d00abadd6f736f16d13d36e915087c8b65f2d91425e0a977095fec06f18984690a46e93fa1c2b3b92cb6b743a433568ae94a78b20d77fbfb28b6f47b09b1ad57c45af9fc92cf4ebf2e982035a4799f3456ac1e47f790af3b9361d5050b7d050b6f34a534244bb3821a761d9d593640f7e8defbb06f2ea8cbca4049ac2bfcbb62fa7f15266070552231186d3d215858668b79e5cecdd998898525b40bfa97b48b2963170397f55f7db39bbc8cd91fb56e755702b7f1c9f73ef36111a3b6b58c44375dd3e41386c8b5d7377983a0b53595d3192884f142912a38e34abe567aa10459492f4da1e14bed288e013dd1c94663b4bf49d2096671f2070909a7c3992a2af1b612d2a45d4a016089e0c7b07ea20ef9e209dde51b22f14330d62a56f178c1f9d660299785a5942d4134ec98b3f19e350029d32e39232cfb3e4a3acaec243938458884a262619f14a84617c7c6d4e0a1f0e8c22d1b65eff14cf6c72264ccd377b63e56c061b191eb8c12a8bea403a6ea74fa3db8846886182ebb36ed2c0e2583232f370483e8268e55dd648b9c92abb6c0290aa68cc5bf7289caec68f9ca8b2aa5f56fe8d40daeb3e824d3b48283f9b9e898cbf8ab44b024980e26e307c9799283e29d2b239aedb98b8b2e9a79b97c129a3bf2438f7a6d00045967ec573e9091611de723ebe72952c066aacb0972239e6b2b4703c4811fa57e726682e5103fbc609f37ff042f675a29d723746d054359c5ab0cd5cfe0eccf01e713e6884522d9089d31b3308957fec8b393d3e871e0b9af81158e13069a5d7b87e0a4954bdca1dc2fbfdcb46b90b828832235d87e5c1caac76f6d972599f2d4c94ca08e5f88619a6c0c71d057274dd63d0eea150e43b9323c90463576fbd6861bb35d286003a493741987b91c68868fe2f84a4e9569862df2bb0fc7e314ef685c3e4a233bde75f4199e89bf0bc2df77976d247e890f524deb58edec8fa6bf22acad27bce53017476f065004847a1551b209c730aecc618c88205767cdb8a74e9bc3f6769e651dc61555aeacc2d52c51530e82a3e5dab3ae035fcfa7e403a1ea33eb8d81857a14ab5dc119906751413126a556aa691de92fc073ff169db5ef28056323b8c7a6da27f5cbc40d17ef71949324a10039ead10fd3fb14f263e31196598925b3c2b9692bf3e25a6d60f35fccfed783e89feee8334d443c346f445a7b8ec4c9e2f3832029bfd4145bb1698bb70ef32b043ee71a1daf39b0242fb9d1d12e391d85803201f0d022cf21f85779a6225f3f7e50ad565d84f6a677f704e8780a94a78982f8bcbe88883a220aa37b5f0322827abd2689ada76b480e26e5ac45ab757e561a33c1b9ee4e0ae4f8c506fc47ec4a1862a0cb8c446ad822e9b6be05759a25011234897954ba95094083d59b7bfc9f3e0263f7d8331ea6cf519849c8a2e1d036e3c211532448f5b49fe56b81089acd727aa44a4456b190f2f8fb30ece9d534cdff61163f7ba545126f22c3c6ab9b0478554a55c48d3d2b444386ade28a6f83068ceaf23a97aa9dd88a39cca55208475b0d3ae5078da0e783bb283616792c56a326b6813cba889762e485e111fb9d6291d8b35c1bf1f6ca01f84d1630614140c4991c15f9922bdbdfad621f759114dac38475578b7ae20b36c63231a0d7bbea47c28d5620db82380c9f562eaf0ecc08ea1419415e75f6bf79c3c7ee42abd2c02934415ec43204c056a9b64f286ca4a899813a138c7db34ee45c062c795cb36458efed1ce860ab676a0b3876807cc2c852559b38b296d5d03d7e8603a7a9ee4141943ffa4f0f91070a9e081fbdd3211161096bc89bd87d2dc0ad210e428122b57d496214f2a529b256e273bb00792405994327c0af71d73b22190cfcd072b38fbca3dd4da737bde5b4f49b6c6aee37f911178423d0b91f7f0e065618b21dab5f6ef87a19c44bdc4e4a423430741f932a417a52e3c7f1415c88c8d83ce9eb510b44a45d662418027d4613de6ff041f9b77a4016c55d52b757efb75f2834a627511d35e796ccba1a212b9be5f46386b4bb9869763851085539d054faf608f00aeb60a64af5e90d4d36c5af9a592e51aaedb34b3246356bd24a254c12337bc6436e7e2d4f8e28281a7514959e93132617a2a2b59d2de99426303870d5108bb4ed782dc6e68be83390a65c892576254dd1eb563c5b156b245f22e6fc96b68bf1767def69b733185b1ab49f875b2caae471c7910659770f8e0b4948fd7f7e9462034b37e0c015818eb0669655727e769157ce312bd0b7cc9886eb15bb9d63e15270bab8679aea500842c7115d5d6733cebd9ad6a42fec093a6db076130abbc5d8a1a35b17a85d060fbbea545a0a9a2f60b94e9094cc6bcce98966a49d51c866f88c3e04a35015844c2c26ee3ed7b77bfb5dc4cf0ac5d1a09b6ef4c3d965b64c32cbc1f7098be51abac66f9b9c542175b8f62a88ed53daeb69f8e1e4ae4e2ad77bff16264ab17b5b8111e43b576cb4a3fbf6b3e1c4bd32ce27e8135bc2cec2df6a390f7aa072865956d290f00d29f902d1b5caea9533e95ac3ba46a7053b9a0ccb167791e2d12d7702c32fe2c84da1109f83d1d5d402bd86bf3ccc62dff530fd4914f8ef888292dfd7aaa66ac513943d1c9996406a4aa46ebd74e248a665454f4fcc0467543dc02bd36646b46e953367fc3924769155f6a8803aa585f5558068e88343d99d5af0e7b5d54a08acab6af7e7881bd66e4be7d16818a9276eb52e5b5b2962e2b9854443c83dcd90e92bc473055187d69a3b34ce436c570ac9365703d65b507a7fdac0be144cb8602ef751a1b1d1f1179386c1dc13b913359e72c43b9e90bfe85564f58ebf7d338d56ed65b1f6f3f7c018ae40b23b294423267ae88ea69983bd1d50af6a24a6ba8d28057d479d0d7972d567f61d737d618d6850c768cc252ab4cc7f7f213597fc2fcf28bf01a5428487dc4c212c6aabb2c5dcbebcc2ca961671b01572c3d4a519dd91500eec411966a1e517fd45ad41ae96d269393abcedc893b426c93c5f326d03b6a1d3912d2babea29723f989f4481ac2fe7ac12562ed9880ee05d097530fb81fd2afbe9f002ebaa86152a9971f01bdcb0283ef41262257b94265974b5e4125dbc6600e8ba5e42a16f8639aee74de2fd0c243aebb7a584b315e28aab5d9f2031d2d4ce0b3132505ed2dcad84eef5c48451a11783ee95b5adfea3af90387685a29aacbf9fc872c8cc895bdbe90de15a2ca111dbd368c5850e3d4410f731c4708d314cdea0777d1d43b1fa13b14e2b27ea559da1b21c1dc0c42cd16191ff9ba9653507175afaa1ba8b6e2778f32414638bae10819be0a1e5231c3e09f3e9a4a3608cfc7c3e43d45d10a59689e768b6506e4f98833ad136bdc99f18554563b969961aa1bce34f02846318898d65531b7f3d6942a88c579c0513f024a1366c8b63183b32374c12789c33374a2d5774ee77e7f2d603f6c71e0011cc01a8efa21b7be9f2d1d32efd8e0c53a712c803806af37cbfbc17f11cf114d14828ea37cf23949d34b007aafbac098c2d4c0ee8b1d7993e5d098184b333df4df9d023c322cef19056162f75d6477b66a8e202519e20407dee7fd8d10cc65f2272b5cb2efb9983d6c82c27d0cf9d31e1ca77619a18d3e77810ebfab2c9ffffe310e998ff37413c447c1e65479c3c17ccd6ef9b68365d69ac642668dfd75b2d1a7fcd59dbc4c7cc3fdd9a4df0f775b93eb30360cb46707d348185fb1a1a1264c6f061c7619e71ab35fde183e6d4b3b291dcd0afe49e4ba98f4f66de8e5fded63fdefbd3458abe2a885a24af427e011c0437fc0c3d139de6dd7f9d7c3a7d522ea53fa9134f5006944b345342186a59daffbacaf80754f93ddd3e0a3feb4e40aeda44296e510908214f71a03c0a5f042b76e98b351e5912f4f504d9e52a02a9d99ca76a82b04b3ca9c82ef14cf55691ce3171d4cb2fa5e23d5256328308f46168d72ed74545eec14cd74787d1569bb550481dcdb14cd1e13a6f6b429e8ec699d50c020e07b84d574a12d0f15a263bba987217e8d6ea2494fb3410008a0aed156b060551706b4374acc8c5cde4466c98ac86d1aa4e86ff779587118df2e0d276a5bc124f790e29432b8187ef5f213ed43e2a03f6a4c257c89b0a5d074e7ee15a282cd2cd2ffc8e8f672d3fbc0ac4f70f2908d13d28f8e9e23758bafbabc37a927e8ad6263edbbf95fc79e727544f24e90f0751e9c041b6149f68ff0a9f534a379d17ec51a63703876631c9127cfcab4080189fc083e0fbfe1c143c5f9b31891b8b99b3ac9c0b0206e76577aa387583bf13833e01cdcc621dfcfcfd7c5520a1759039d144c04913d56fcbd27005c3c4b458ba0ff6044e83197c31d93ed41a8afb80cdf59d64c6f551f94e54e646e6a59e2815b7e95d33f692dacc1d5af2cd322e2120592fe24a11405617754b0a20eb8a040535ffffadf590cafc89bd4b9e89dd84c37eb24ee7589426c66f43434791d8f30cf2e0c461d8fd6ffcf791952a7a9512d7091bf7797e85050ee87ddaa9c7a2817b0fd5411b3bbd6646cf3bc5627a0b744603c57e37c9adf486f2176e15f4922bc87033543da38a859126329b83162ebdac52296a173fb8c4fa6eed64e73302afc8d8655f8d2dc007a85532e6c8f64ed782bd20a762ff2b15164839eb4a8a9c0b1a880ab2d76474a07a16e47a037ffc7c2c4474cb4392b0a008ea02f175477c92a9143ce1cd5e3dab4a998c1f47814a978b1d78fe0d3fc5634abb61e390e547c605af54f29b132134d11aca02e6bc1ef45ab8601347dd9806e75b42758d267a45b7c65135a7dbb2e97633685284829c245c69a5ca6fd1cbe0c4ecd91e081cfcb64c1cf141ca190aeac67f82665c9d0368b0a6e627492d446be2a6ee729bd3412675a33a6d3e5150773c728e5335152c575c1a5c9ece0e3e3af653858057c641a08086a375f0ffa2ce8b7ab1c615cd26a3dc3acd88e0a8d0b788706b685f96249a0f745012eeb371ff9902c3fa9432d2c52a8a545a57772ab4f68ab51c096bfab9d24d2fa778cf178a14d8270f97bce776b1ac39ef924ea31cd54da9ed9504952a2297cc1733920e74f0e440cf62e2a42a5f19b2a42d38d6a1ea71122dba0d2a7fdc15e20a6953ff07dad51bf8a7b9d603fa09690ce81446b3f1abc76a3bbbecb46d80d4f55dcc7c0ae40fe57e4c90611a4dfc3d3259d2d80529b2bf7b81251c0b08506f956171b17b1a2fb794d001aba0b83eb0c5feca019d8be88fe9fe9dfd9c68d415440054f096234521a93e4ec263bf61cc33e99a004bef2f0b494c63c35d7c439ee6103947a4e9ddfbad7722b995df1e672a91f458a43345d245de330a124245ba4b243462309f005ee880f32c562fd2a2ec13cffb21c1b492c24e0a10f5813c00f729fc6a44f44c0d407179b433d25dd40d207c85299c8de5112126645545e34a895015b0e8e5945bbeb724dd97801c32962e9ed459351b16155147014fae1138a802873e10d37894dbf9f97f6f1524386987bc2742b831261c302c9bcc7e98c1b15e6ff3126ab4775924c0f7c624c37092eb3ad0a458e29396661813fd841f40d3554d2510fade0195365249132f83ee8fe9458928e14b17f4c3d13cb774dc894abe1a31f03d78f619b6aaeeb09e4f13463e16e1a72c34500c31e405f3f2e7716ad46a44b238773542c4a173aed0207dff0b9a1244e40e97b9b883b2884b2f36c4956426ae6dbe14eb58dbde21b680cb631571c00fce45904639db555e0059747143c5419c6de57e46c736df1724ddd9976d08f4f9738b15cc825b278ec7298a281edebd1e7143e41b6b4861c00b95f6d5526c730ccde5e308d586d35e93713e6ca3b832d1d40f8c207d325086db4c838e33e1ef7d64d166d9c40a8fcb8b54662b467c3d53eb9fdce1a56f2500dbba3cab70360cea33d35a06e15d409435568b317a074dcf3abf9c09bd6aeb7828bd6e0c98c6390a8492a1345819c7b7292d280a08d1b0d380522f220e01f0d934a7041cba13f80044a531a1ffcbccec20eec9410bdd799d82e02fad0fea1b79d158dcce658f426872709f28d4e9cca4e4e62c91b9ea3fb04b3112f3b94cb32573bd86b07ceb44831ff3e63c23a132f50b897941dfdea5a050226e0346c74e6dec3ca670d95787dfab932bee4b81e0fd5025cb62d2ffe30c1889a5e193a39b1f41f613b31d87a0a17f5535bfd0e2bf9c9a07ddca761452cd7e99640ae26c029f4ca77b63c0a9ebeeb5123d5f38394432925db2733b8f0f90ca1195e43f4745db1214668495ae6eb3bf763ab1353f3079ea7c23a99314682aee642ac8bc462ae9a067c9bed12f451eaa02c787a5e62400b9543608941a8ddfc6afd988ff3f73fc7197f02420186208b028ef66e29f037eada4099f64451f66ad7c2b7f31fdd607c06f2aa212f5b1f4f1b67f45aa6d38d678d6a1b3d3db58ef83e4b213119679888a4273170be3efb4e6e456ebee2913e05d1e1bdf3aefadd0262d041d8def1bd52cd665172775f4069beaa9f992a969079f4dc6070fdfd43822968a4089235564f028ce69dffd5386b19a8b72668fc853c9bb3d640e330cf4c0ececdcff447b37938fdb22931999197058e82d54914ef3fc20fae27a95a51179bd483639a0d11c82997dcb04946bde680c1d71c6aeb1bb1c081434893bee0aafa0d2489cb16fdd4625b886e8f72a1799d4c84ec13558bfa32c88286a8a77ec9a2e658042a9c1b863f6fa6f4a13c923f09bd442a5b4918a7be40469799694cf9f2f232ec83d7310805b57c0f8824c41b1c737d6bfc9d7c32bb776cbb272cd2674475326458e09a17d9b755125d8cc3106653bf22a06674f7fe9868956370e6561761e07510626249d5f48d3242ca2adbc750545f18e545ace6acf1cb6dea2196101ba006b6c69d33f24938e66db12c156886e0b23729efe1c37fd291cbf8c1e31963fe10eb0cf244503c005315c88a0c940e92e6410a7c0299cd359d6f26949cc780ae1655036f580fbde64300777ae257db9cc0742104005075f56510aea80c04706bfffef1e9dc795025a482b2dbd8f585b048a1e7db7311678e6ad988d2ec13beaa233075f335e020e12f84cea6672a9be82170ef04bc2d46740ce199654845d517ef164e763f260a6bd201d40c1b4d94048f02be9c9e5ef62f82780da73aba57c122f0c829ce6bb97c58787150b8df29710c3be227a00c44e3e3e2ac82691d6f9084470616479c5f77769fd9005fe109f519f2356adce391b31691c74c89c70c87fda1804d5718749f0f48a7831a7957ca9233af84679ac156258ba1000a94f652abd453bba8fe6695c3cffc91405817cce351e3a3992285279623a52c99b414b244074dd4468ee4aa8764176edd957d2f5f148011d0dfcfe0595cd43aa136985cf2352c35c7f10587da8ff413aa6d9b2ee157a58ea1ea892cef577429145cf0c1ec6df5ef169c136aa55ae0a99e522b116bd7baa4571a36f37a86258b9cab11b47437d42d84178506ad29302371cc6a5f46d4ba143e6b78eff1038c39b12a5f4e2e9602d4e41e7a43bc2d6cc37828e88669515a81f5e33956dabfdb562d4060a75c864881f895e4a563f082728f92eb474c6224c35b07eb5b6f08a8c6fd5dd64ec819010ec93b0019977f6b48f558c6955170f7deff41738a50b9876704bb6546a78a28175a74bc7fc9ba9659a2b7bf2eb2442b6dcd9da4184041b5071934c463df2d6ebfa1fb1a15f35cdddefd3c0860115a56b7f58f79351c906fe7816de7491d66bb3e8a7fbc2900d7cc1bd721a630a844b02dcb86058acd1d2585159a3391a7d4edd0fbbb1371c5da5f7261ef86a6e54f87377363b30ffcb1b91033bc828786789e42dc0d5952d02a3202c69f4198441c7208d9807cc3d18ad862d0b9d2c6f2d52dee51966b03b0f01b418dfdedc6bb95e470fccac99b740fff3fd5385576c854df68a812107645e975ed4ba36fdc3311568797729a24d8447dc3e8aff6cb9214e6093006cbec0250c093d3da982d3f3db8234f359d398fc6666967f85b39b7278433cb178afbecdb0a5398cb5cbb8994ddcb7ee798a5938de50a56ad8d3afdaaca54e8c2332b6631166733ce4047d6904b5df1bb467759a16614f53a8c45068a0a82ae4a8cf333d3b6c0522d413f90cf994e6b13949f8d39e118fc30ea69ff30bece948b6d3b0168c3cd3be887c568112f18abf9111bda5c400364ce41720a40296e80678d912ace6478f21c10cbf701b6bcd412ec9b8d9c5445e243064986061d9b244554064f8a33778efdd5ef8a6f7724e7af15adab3a621dde0dddf9b3ab032f246cde5cbc061d86c23dab88d66513ecda7ec94869523356c2c918c7398a67e38051f2138cda5708ec36ffa5b94314d5200871edbda492a2b3dfd8c05dc48d58fef172a1e9a5580349984d2011422bb34e7357b799956bc8d93c6b4f9ee949136cd22cb53ffe661361b752df80d944a15035f5400c7ac9fee81b68ea5b70686ab3a72e916d5e6d7076ec905f9b435d2fea824d0df4c44ccfc61792d0fb4c259f5e955a62a26a65b4df1ccc0b255256d3da3390b4776248cd976411d245275738c51830ce705dd6c937eb66f320d7d1c85118efcd885a3477e64b52c01e0ccc73d1a9d9ee2e930cd368481ef0f9ce3ca8864856a06dc499ba2f016c96844232002ea2db6a4c31209e1ceb845ecb1fa838fd364de87270dc057b4618ad3722a7f5ae8aa703b7f3994078ba6a8a4cd56192a1e79fa8fd507fb822ef58a0bec958a0a613a240a712c7a0fd54de642fe92f0bf9b4bdb256f40d84e49e25f04439687a1c230f55e685d0490b19b4bf538ee4af32c04a1d1d1de81ae5ac5dd26286a445ff47a087ea420e89ffbddd31b85992b0e77e32d74458d31593981148253cfc330c8b792d12bc78ee2d138604ab43cee7ba6dea36fa80f70e8fe5517e92fddc44e21a26405cd3e8c7ff20a1f0634e2e82c8fa82aaf19c4f0df85bc86c69e492bc697827298cb310ae9a153e164907f81bbcf1fd10e6c7b18d23ef3e068b0ca5d448b5ee1ac98b3a1a0000865cf01ad66c812c067b727c809047658899e18ad6520be4cd9d98621f68a04a9418667bd8bd87c8d330a07a6bcf22841b5fdf2cb13a5af968b2b4c25867e34a2605b41b6da99178b86a5a5a706ce9f9186943316f04eb8b54ce3b048e6232b483db2e615a76079e3221046fbcce5cd47a8b1f22b658df91323684b5fd96656eb9438fe69d0f0ab15f7eada7f912cb591a85cd46b0580c5716381fb9a7b392d76c5411e05fdf8e8687ec28542d08f99624b44dc7c8de68ea51db2978addafd3aab988664f5c0ccdec0c57189beccacd56ad87ff3ed750a59a8548081685217741e4454928a3a6f88f6e8d309cfcb6643816b99a1f4cd71a4203f5546a9b8c5e0c3184c9922513a4ae62b7892a9febd425b65f831c2dd11c0dcdad8add340a2b16e2ee241d61141430b951047878ad4d1fc97bd9633744c64c3932f4227f2cab0310548bbbf909b87701aaf4a4f7f073c0ae501d051a6f1743a864ceb503f1955c68f14571719cbc9a1a5df223e8f18b0c2aeb0a7ed3886e89bef947cb461fd3d8a60f0128b7fb23ab7d06eb9dde4f14cc5c2856f5e8dfb03660863c8796f5e4dbdad12c92c4807bcc0085a026d7a737b51217abda524b206f9826d9a048aef3661f50d096a322c4e6cda480dd1ee52ea3f6a422b550052bf5b38e12417f005604df8200a18ea221992810295c8e868c8a1180ab39b99356052050bb3e3da9912cf62245e1405798416603a797b9e64b1f6a3b6a1f3c012bea14c33c14c9de21f0db3577890db35ddf9951b35a98dce01576304a61ce0598d1d8354e9cbeee3052d7ab1b12dbf36fd2979d14a5486cd4e0632fdcdc262fd2e4e143208d2bc139e4904b4b5142155552b16637bc9b9e727a9d5e1609fcbb7c834d09af01dd3c72a8698688343341fc28f4de9e77e0c1eccfa82cf4095a3cd504c367af9d7f23e9ddbc42c646f1595534a1fed37bd8bdbe200083fab4d3c0c59484bb6df5065f66a4f2dc82cf771626096599a9c83af8f8dc553a7af4f9a4ac71215c0944296f2d0da8bd75dd5f6922b53320e217cddb22b1e3581d075cbceaece5a23511cf9729ecc49aa6dc14db75cc9088404f5a949752a46df7e1814ec0ddcac261f84df76159c66912316aa24c4a9d12dffbb3ae69d700975210cf3102ad8d33b2130886c104df8e885e18257c64f44c4d31100d2b123bf1ea95999389d2e72f72f2b9400c632610367b08f8ae2c97dc9f7000ae3a8b4962791da09ce371dd6103c5523935d9db9fee6b0330fb135c9227423dde2d950850717ca67d2d8579a2942adee5d6665b483a6f19a78cfd10270508909a2e318d6af860e9ad9465cacd82c57ab396648efe6c06caca38f6a8b22c7e1b1a35a8464a78d35159b78ab8513077d2f4f89d62d692cd87fdd0d29f38fdbb8324bc3274f98977113162fcd522d2618798b2a7f1cf691604a1b8801dfa730808e975fcc90485505112c601ecab035ed95a44fff83144b7030a33cfa35110382c291d3d54d9ce12a6a23b6afa87c752eba0cde3a6a6962875fb9b5a375535d9a9ee7382e3b9178e474f7259604d3be3f37beeceb82bd378fc3ac346be15bbdd8cb359b209d932edbdf7de52a624032d0ad90ac709b18718197e5c4dd08a48ac7e5a24bd2bcb02cf67dec3c76730bc56c3a3e99f6fb59fc1200ee438b072f61a48b3d904d066cd71def9a669524a29a594daac50b4d7c050ca779d7f40407c9d7746997326641950611610bba863de51924c30a88b020589e69c1f89df793f7b310e615ff7149c9953a7ed18872473b0073679f8a861b3b70fc85d449db36799ac50b4cf406de3886ddf48dd091df8cdb2ab9b14eaeae40fb8a53cb7d1b0e533488b85a66331c846a1e911fc64e4581fbba6e6610bdb343082340eadfb1c588cc1c20b172f5cbcac091307282e6d160eb224243d85a62ffcbeeffbb68ede376e9a8d3768a2f8f9c3157abe078fa997eef113923b86834c5fdf332a4cf9c21d03543f29247d4b01cf17f278c983254b9649579c218a578c79e9736367973c32654ac79d60ca0e30b06b8f8e360e7172c4ae9d9e1d755c05815df207bb2483442a54f1858e61e0501c921be843663ee290f414ac704c4e303af668391f46a7cd55c40a382f5d04124a686fc105762de61ae8820b2ce402bba4831cc8f2491984bac4381264100fec40097011058b486e5b2106a7c5a236212e3b1bcf2c7a5a81a4c733d2230e496fd264723e1d85e9da9a991e3d13a68bd9a494eee3c7a41886f9acdb06ba56a8f2651ebaa4f4946c8cd3230ec9cdc7a453c598afc24b90585405d36a2391f851e9c8b54a59bee95ad22afdf8e103ab3f263338b7134ec0a66b4f60d766d864e70de9f7c9c52ee9a16bc61e729edd67029be7efe3ec1b878849da8a5a47ab4261e963573d3912410410445815e97c82ec70666fae2870c00521428884508dc5f28d83ec7016cb9ba5390a583e966f4c5860131f3e7e7e7ebc07bb7cfc3837d9198c580927b06b7deaa4ecf2719742d2811ccbc79ec9fd1f312ddf517fb050cb49ab728085a4af3bd272805d92c116983e222924fdabab1a8230151285312adad976ce03fd463812d88a885278faa48744cf1b131dfde949ca27a79772a6b0c6170ad1187405e15cba0f76495fe20303c9f8844ac442d289240925843e5efaac21ade293dbe745b5d102390fd50238ab7eba469a6b1e1ec9cca54723f97948b017626e609b3b1f02b5916a137e6c981e836293f498f7701a83ad6a78a72d992fd31be9fc63209d639a6fd873669aaf77643af5d6c69ee6ad9e59e6c9229cf56cf5f065debd20df6882119c5d07729fb7a623b3e03c614e2f443763249d04122c8100cef8e8b4a58a95e1c33e3a6d71f3ebea08e70c998f505ae0f98f5070c67c848233e5430ae7cb731fa1e06cf905370067498532be75da851651f423941671a0d660795e9e4fb841a26ed069da02836a6a0a4292b14b2ed154869bb87c6cd2d2a4e44c70989c3edccd474a6e1c37ad8f504f9c717ec2cb135b3e423d91f433d5434ac5f93e42a981e2d7b7b5414dd3472835653e6c7d641af33b3e42a9c9f2db03cbb04c0dd287112a4d969ffa100652b2e6c41863a6d1b8fb264d1ba83465b2283c4adac640c0aeeb3cc6b8d5e098949d945de7b30903d1bc7326364c973d5e769d6ab5f28060d1bbc5306f22eafd23141352df926a55ce0eebe4ecee0683a81bb5b35329dfd570cb36d6c9aeceb92ae5b77a24b35a4462441b958e4b3f201e989c12939bc496a3569398bb3c3a77e3c7e55927ad941fc3beab733ed61dd6ddeef42cd3344dcade994646c30f88c7ac733b58ef88bd144ceecfc9d84bf0db5686515252b221696d505aa51f98484949d1896242476a0bf69b13fa430b2db010e7b0d0420b5c4cecc7fe600f883c60fef163c2e124206ee22656c34c9cc46ab8899bd02c2d53c68435816168b689658a980f4e5ce4f9b0c747272de4387181e7d95d70640c3cc038c41e87d83735beb0c7ef165f7c2165f985f3c51712d287f1a904125aec52e38b1bc123f137161121fee6d8d648243efb00e2901b3ec2b182020d5fb8853d1e7320c79c82d49b50ead499504aa53e8c6e9994a6699ee7f991f81e18a47223cfa57b2e5d456b57b71aaaaa5727bb689775f5483eb7d530c2c1ca74fcd19401dd294cf9a201e040adb9b3c6698d124c4a4c5ba0d67c7942cf1370a441628ac1339df9703f32b5f1e1f6cf64077b09c514f5118aa94e1a2e6976d85a845d22380a367c617c622212f6ccb7c317027dd4e23f09b6d8c514882f04d2d3abce2905690e1fa5e00624a953b047d217f608e31390cba31f7dea93e953ead333428178b4a4c81d3b5a985782945d4ac1d8254951d1e79caa7efc88ca7f5ccad31a4a89433e43ac23abcfa3475d73560d375a833e10c9caa7af38ead9fe7a4868c6791109ca6d8b93b6964bc209fd2a2545278a099d959272e345893367a2be576078249769d16c13cbb44c6b5acf7d500423d419a78f5067e27c2b0173cea9c337cfa823159f4478b3a78d8a0ad5146cdc75829c366cdc1506184e6813a9a830c0c0304c0a738a61d8d3761e1df3f143c9e6f388e6b1db5a5c15418299c4c2c81335e75c33e7dc68af5a5b7d346197d41b483c7d08443f2498a2887e4c1702c403888839f3d6fc6411516238e1e1e3071d748e88a2ec1f6fe1d1fce8444ac015c2aee8c475409d613aa20c9d617ece39e79c330c9144830b94993bad337e429991fa39897ec8f08542bc07108fb8a540e5dbb8d104f6f55674c6d874ec01c37a9442118a0c17ae80f409c2b07117ccb7f2daa7cf5f695c4717210ed96c732206b2f2e8f9ca35cfc8eadbd5ae360e1c6fe59eab3cf38ca856ad6a55922ec22e26ed791ba11e47390a0af9c1b573dee091ec38cdb5b9f48c6c1c385f6be95ab6daac05ecdb23853abed0f5aec99e916e23e408b1f3d30827333e04e1a7d46394824124c4a77e243e05833c370257787d4148a8bbe735dc4e10d2d7bc1ad9d54e375931efaa94e7ea91fc0d738dc9745aa39fa2b8221c6416316120f17fc4ed2cf3f1314a297d69d5a4a67dcff7adc6e7b19e91f6d8ed5b67cfd8267c4e9d3d239452efba790947128967647359e7b6377d33a5ecc012be639a75a01895cb202af0070bb11791323efd0f37df8fe7cd73a6ce9cb7875b771ef8835d14047645cc29280251cbc79624c32618b5c54a8534be4d014bcf7916c7cbd78f502ed0f32eb8c3851c2f9c30ac0ca8173861679ed31c7331102830bc0a416831fa7e0c8f24a639e640aed56dd36ae889e97c862b884a3c241cb8b9e61d9790f95aeb699e0a23384107aec04c067ec07119c8812d766915a849c3649c33cead18b821654b44afc72d4e7093b22c583ea123439d190375c64b1c5b98be8c79fa62074c929ca4707ec9d3e9b9f3d1b931bc3833e85378f309c1f403f80825c4d36b92c7b36b60644f8974f618bd24d2c56c2bd070c408fcd499c91c5fb8fdb6641e71c846d1f4a79179c6373fbeece87929a5cb1566f8a6c7a8979b4bb952ded012d08a36df0c93425bd58abaa5cb07089f56b4814cf47cd335e9a1f7b0f34d30dc582b8abec9e82b7b20e24584d3cf8d1ad9d805cec9ae237387ee2518b703f62563600b2485315f38dde92314982d1f6e4a288f38643f0b3c3dba4c0122cfb3b7e212e12fdb20310e59ecb3faf9ac107360e5c330df2e4e5d98661c9a990aa8953445aed0f48e3a8f870a028e2a2a88a7acf61801ec4159663f4347de90fe06d3843c1dfd75c3180af5ec40777ece6cc53d8dd52845d04d7d1f5f39dcf051a08fad8ff195c314d6c79715a9232c4e58dec868263ebd96e6bc96baf8c5e28baf25367abc3b31eeae8c4861b030edeeaecce2852589179632df62d7bcb2b9716a00083e9e3ebe969280ba3a5aaf1ccacc570e4b2f2b6fbc10101a1087bc96cebc0f06e23fe636256cb578f4e0f2216d7d38993ee4f1e17c2d7979e510e7432249e775e5cdebca1c20f98a618b967199a6f9b67d72398ee334e7bcc581234837c2b275ec5fd3a4672493124b92a6638f703a8519f39ab7c645d3344dd362d05c6097e624bcd1344dd3b8cc63e621f693a90c4f3190709e79cd359f671808e79a4f347c4773c6c340f8b533413c0fbb34b9539b8785348f532c012f5f283df390efd0c6e8f621f6f1a3cfce329ffc1d3dcd5308f385f4b527e99b67f5c89dd2988ed881f6f3f3e14e2deb89439ac3f14d0ff94e06a270c4b739691e12e998568681480c5c3245d8d1acca05194f1c8ae30b778a91d8a53956790abb342f22398d93360f07613c2ca4b9e63bc5406a88442495d881e61a0df98e26a7c421cdefbcf14d305cbef35ae4384076ce6bd3f70905335f36bb305e54b27cb8bda828c9181e4dae89ba8f1e7a8c43e1f4cd7f08e9e16a71cc41488c42cca387d3e311f62c033129c180a2a3098a0e25cc330ed2fb5df804fbbabacf423e8338e79e1ccd168e2657e18568090f7a96f49c818a43e9c763b94fb3aacab9faadb3f44c79966f80678ea887ca23e7034328dfbf10f4ed9f679e121f6781212b88821090f2cdfafc7396732c57d5907af415abb258cef97495fb38ab864f9ee5996702170401294ffd033ff72181945f812510c05330a8dd88824fdec77d3ca42c9f1afab80fc8028d3c5f81461b38eb68fa80479303c3a3c9627ddfcfcfcfe72c6fd6cfcf8f8fb3e88f8fb37e7e7ce8cfc7fdb0582c168bb584071fdff7f1eff3f5efabeda3e7cefbf808a5c7e97b3d13b6bd7daa6a7d9b03ce6fde9f470ec2c383fcfb7ce53c6a64964766b1bc886455cfbf1a1e4deae3e3e3e33e55b51e04a4f8f8f8fcf857a9b3aaf44888ff39fd9cfae7d457fe03c3b3bc88f4a9fc2c1f12e207f9b80fb8c2eb73d0f3a3d9e3c984a2edd9b307cf1f49d51468669c579595d7a1e7a77b345aafe3ce875f1d52df0ab78f1bf5ea98f32d76a5e9254b0c64dbddf51f67192ee8235991c562adfbfcd4f0c90af40137f04786797225a7fbf8f06a5bad563edb6a864f7ca4cface37e346d5bcfdbc2275a33338be59f8f872cf77c556b6cfd78387dbc35dfc7270359f90fc872cf49ebd9b7276fe4b94a057a747215a8f2f01e2e1f44ec92e2c31d13b4c54030ec7f0b82e4f90c5e445d7af7e6bb65ce99779c71e75445330d46d9765acd64ced1a715c94cf64d397ae694b3f4734a4ca57911ce3c231dd771200f764df70d1c017b0dec1187a6afaf30e5c33c046ab18b7eecc2269c9ede737ac8636a98b66d1cc0d8c949d334ac72407b0d6c81cd3725b7208488c8e5728f8a6292e7c3306ceff0988c35d1b1c746f493721097149ad8f3f08e64bf094d9f18066271b52902bb36b0880e5f368d1461d774169a727cdacc66b6fdc6373fd73096afb55d7c8b4ee5f3409723b013b8eba16bc6f785304ccd3338c61aa21b77dc9003e5061400f808e5469839e7dcb82c5996719d1b4878e2b66d5db711d5c69baeebbaa66d34b581266e4148b687b27b56f05b171b17aa8d30506d0001d5060edf9ac37ae292a03f4ca980c6d7fa80b68ffefc80beedcb8881e79b2595cd8e6bf97c91259bdbfd40356573bb969b6c02ed8052ca00ea8e065061805e6f36f862eae3e0a587067d3167290fa838dc960180cb47a000a011c00b89bed3ac46a82fca7ce43ecf885ca93c3a55dd7119b769d95461de32c3a69c2accb3a83c514ddf1ba7e4c554714e8f9e8541b39332688249883e48fa0c926012c979be98c55834b7c88ac86d9baf96aff3dd4561862f6c4921b9ed6e4bd337072479113b8039ef5de255819dfa04d8a9368994a0ba98e22ea63c73b303d62357141784e183c872f4b68161679aafd0f4c4c598f72617505c20bd6b3ef38c8025c17cf3173e20e583309fce350863300873f9d3b5e841189844fe0489e4988ebe176812df4c21c44b43a4844b23e39b104058972fdbb2bd61c5690b9a37aa3069720138a4621c14dc7c719ebd156e3d22d00fa90f81de98fad0913e7465f99028cc8742d07c189ddc7c189fe088f3619c78ead835384a6e31a3c096c8c2682b2d1b1b3570948eaedb685a06ed2f3c2f0b151ea7151e253e3c61587876f0c163c38f9e961a3ba2325071a1c114406a363882030a2648cbb7b6ae9104003d01c0230029a7726a9705d8520c604d0f2708904401c818600857168490b6e5009d1504a831838fad8e212d8e04b0d1419606514729e0e5419c0564f1e3e9832880644d4134268474641820c490ed07225a1610ac34204b72000ca884204711375ebb5354c603b22811b02f8c645d8c90c5112a487042a2a581c01249cc9490893181eb12812d4a322c27dc20813b4813a083021a1c28e04921434305acce924c0c267256d8a20256584093a2c99a0b38c142960406b8312d80c940c645033c6c000b0770e8409207d2a8f2813a5c880108a6c2358cd0705227045894085e2388f3240b284f51a22041d3511325c8cebc40c604181127f082021f529045055660485a011a31b0408f1438a66478a8a4110356469533a290ce80f324c3194c332c9d51868633b8e8b0499a520d6720d96067cace0d9c184a5ee0b06961658a1cd62cc191c3a1b9b295c162878b9d2b3ad8a1210b1d5adcd86ac6193c88b1a5eba207ee8d0f5d143f7069b8240144115dbe04b1f5e025872f66c800660e213a36c2d819821383882ec474578c89a2082e8d114a902153268c9932b2684a4794516522b1c5963a726cad33b5b50e1e25a496985168681c26dc28d1049c3c75c63851674b9d2a4c76f2701a293b52ac460a8e145ba5989aa4c66841acf1b0b0d96c682355c549d303c51db61345941472b6aed217a1c8782283cdaf5321675a053b2fa438cccc7b81de183be84e810a48d491b95590e18b1eb5a8450cc3b0a4ac22611812866559966172b08ca5e40fe8e3343eec0a9665485986a940db36243359a619c92ad0d7da2aa8a6fdfca47c5ffc584b86615926264aa1e92da01610500ba8f5b1184ee3b4edb9ba45bdd539b76ddbb6f87152c4300cc3a246d9f599d18e51ccb32dcbc0b96d73fb607a51f46f4e73948b1c076efcc1f42f9a2ce95b56a704e79c9b44471964a327a323691a08c41fccff5a5b45631e6b2b6a240c035bfcc194405268b6f883e9add1de9869aac9a252a8284a566bd7b9cc186f564995c5186e9cb08bc188fa211fa1e6b40903ce47a8309c7e011fa1e628bd0beb06f8f852c389b37c18edb0186228ed8e8943b00de3cc7318639eddc95477f83db665bb2bbf08bb78128db0cff219a48149e4af8f303f68ddd915b46012f927fcfcd09164d174d8b07057baa50f5d053cdf2a870f9d36d775ac0a55f098b76af5b9a0021a5f18edbc99e9ec2e8811356665e5d9778981442831e49c40066122859688511cc240e636c58876c76d5a16555e0854e10b2f3d0e3d9142ec4c629eb9c34bd085ed608cef041e7148a460b8e82032bc7c842203896f1d60e372aa37eb719ae2307d387f3b884e372ece19563ae3898c2532a84ce559e14c2766ca8e9ca92726b951b40a4ebb3be5dc2269a2d9dd9dd854980c0829a5c4323b535bb24c9b4a72638fc6d42ab0f181e2d21803cf1874a6e80f9b0e749ee0d003471b2a359ad2187ae824410016b440f3411fa1b4d8f24e1ffa673c5c0c2463da2cf2ac360fdf2ed0aef18b6f10d0aef1f51dd2ae11eadb88768d72be9dd0aed18bef10d0aef105df22a05d6317df23a05d639cef27b46b74c13714da3572f11d85768d5b7c9380768d70be8f68d7a8c5770968d798c5f70bb46bc4e2db04b46b7cf37d02da355ef18d02da355af19d02da3556f1ad02da353e7dc340bb462abe5740bbc629be5940bbc6167c4ba15da39bef9d42bb4629be970aed1aa3f8de1868d708c5f756a15da353d710be5706dad5015d1bf043283979484c0005e703ed2ae4698dd1156a60784a9cbc243f6c1b4ac6271dc8d35a820dfe6883a72ed9482eb4eb074fd90041bbfe78ca86cd049105125e68d7c522892fb42b8f25c0d0ae41cf041d2168570ec43841270cedba81983443d0ae407486a0402fe6092268570ddeabac38b4820c2bc63bb2afe22875558da2f2234aa9d7647823485f791149abf6aaba92ae1aa26b06dfab8576ddf1bd3bd0aead6f76aa6304edfa138511748bf0cd2377f19464aef29665ecbaa953867665c93153702a33b4ebf7aa223cafb6a0be5539575baa541ed71ce72bbae23c738e7baa7304edbaeaaafae62bca3843bb523158949104edda62ba76df0c6709da95e3020dedba711cbabb5c475955bebbbcdc9ae18d20dd5bf72413b4abf611e41de32959216857ec5b3a11361116af229c98e80e4c1b668558300b068f200e7677777793d8b46cb129970c0f2199768f8af3a01a8bf60c71da80578d35cd98771d6b9aa44ea7d1f4aef3aeb9769d791e333bf522520b4a8271579959a3cc75365dcf487cf66570c918df3ae79af48c3033c62c59738cb94d6325c93cb1e952f29c55dbd69040cf6cce8ed2e8f39bf1c39c9a60c439c66595db6a94cd8f6636676b5c9679b775599629d96496b961e648da1c4733ccbdae9d1645f3234e7294f3224cb7764f7bad4e6f4ecbdceb2c32108e9feba65cc765d8469dabda77d3f6224c6b8c3e42ceb58ce33c28c9e4b8cc356e629ac4c04dceb77d7c8571c16f53a6605c74e63d31954f06e269ed717a90a6791e5f442ca9f1f1266b8728405af90c66a084f09a57897b8a3e6fe94d20162599a9b27b4a10f255339ef4ad3b6f04e92a14fcaa56897b8a56ae929eb9acb27b8acc68608c3ee4363d48cacea398ff7c7c8571fae8ad0aa777beaa66bc8ee2a9bcb1ae53b5977999f432e97d71689f735aa3d0f6f6ba5554c5a293812c09a2d3739d3bbd9452252595526a320329656e4b2ff1e29bcc72e364c7cd6dcbea922e82e6dcba2e79c1a7f9b6daf30a7386a377db9cd3f3cee6364b00f44740ef8152cea0249b9c9c922dcc403ac964207d390847c9a92814c1e88942b10242c41085e287aacf2088b85a12e79b724ec960de7cf4a42a8a7d6320063aa17773d73705cc1ca9f22269dbecbc8278ca34adebbaaee3eac66d59b64b313e9321bef508cef9444bf9c5699774b1adf678717a8199d2464bf9fab2e44bf680310eb9e40f26587ccd7159aa8290f04f977130d9e28b2f2f715e5ee0bccf396f643b4b76a3c96d9cd434e6dddd5522c18dc119372e2eb76d522ed9f349cfb08a6572825382dbe693f38e7fceb9648e6f4e599138d00c2f79d298bbd29f080b425c42057789eab2058d3b75b2f899711ca7699aa67191779bd9cb87392f2f5330cd8b92b78969345b4285966993c37c623830785e4034015166b5e7d52529cb0bcc99d51e2636cc38447a648204f2f0d5922ebef5027c7cf930e7e7c6ae257bbee998120f3efce2f4e858ac05f88d33d6a0e73863055fcea9a9b8235dde626f40dfde8540f5487c15f5e845604e074395ca8fc45781419d1ba93cf34ee599abc0cda34bf9eebc885c2740bf49e9e5391ef31d6e7a4a358d638d63354d0c84bba331c773876f3288901f1683deb26bdcb26bfce455a395b3e05972eb1ee71e079ab71ab0f415b3b7924dbfce01181eb1c66b247de5ecab498181338e9d9f8c7678cc494c4b845d63276ee70ee72366359e87929b3e73ea1ec77928418ee338038ee3768773fde115c86aa42f18b41202e41b20e19c9938cf0b839a5ee33ccd5d0611b20190b79cd58441e011bfe71c68ec710086acc46ee45166d50620104829df91ab558d2fa5dcb1ec9a77648706957a0655e55cb3ce5ae00f186e200bec7cbfddf53e56c34a2b5e81469c6beed1f5bcd009d07eace60383365f49f73c64a55f812b347d4e9c00515785aca48121e629a1984729e43156e3d43989d52c116eea3856b31d641aac0650739b1ba6a9b6d958949aef71dbb64d3fe2c7b26de338a3230f9608e7730bdb2905bbccc306335fdf0e3ce270122d916d863f360cdb9c68c33cf8c14036c6364c7224c2c2e8f4461db6c2889608e699900f7d7ce315689479b7f26089b06fbbeab21fbf65de39966d6050e79c4f0cc38836e61f1fb29cf3a6de91f6058d38f7206481dd981bb11a730f9608068624e0b8289575599675bcd8e6b3ae7f95f355a58ed5393dc0547533d21cf30e0c8fd8f3c0a0cc399f1e2c11cca773c039c5bc6bb0f360892c1876ce71eec11289cffdf83a3ffe6b9af6da6718e8c17630575cfc34b68eed7a635ac779b8497e7a28f3fef1c543139727faf8da72e77928f308f8f8d2a2c707a4a7efe3d9d2cb87372f1fb2bc7a907af5d0f4ea612a46fdfc5651ac7e1dc735316ac9715dc749d068b328169648a8712a578121e72a8cd7b59073ac5bb91cc84d9608e7ddfc8ccbbac9724b1997b5141858d0447235d29c05bf59963559229973947a1f76e91cd57cb51cd1fb80a18f73b2e5a18feff050fa0eae056a1efa80a10459d80ef6998b4db8503ae6957a477c7c41a3ce5990deca4009eed8215b9d0ffdcc595822d9e619e996340d493f56d759b5f395e759d7f82c2c914ff34ffbf190ba8f872bf70143a2ff5860e621f5f590825f38ff038334ef1c6321a4de39185270e5a1afc0703ee62a0f3c625e1658e89c8525d2453d0bdb01064629ac65d9d1f246ea9565eaa5c5cb86458e0e5326d06b30de0d84c0cb6453a2680b924cb139412fd3316600067e991e24e354e2598b980662644f036d3c7a190821035750f315891a08e14b96d536552237a3739b27c1e015692ea5a828abd3370d4cfa5114bd0873b04904ac63b54d15cd659052b4f986f96abe711b075659ed29dac0a41f451ab80603bdb4410a618d3d7bf654f109b681414a91122ba2cd346950a6974000cfbeb5a4927f4a8cf1019bb14ff0053933ca1e14de6a1b0f02529e5dab31c6f8804c4b93361e3d0b843025c6076ce00a667c4562116e12820edb56d940612cf365c7e4dc6ae692336f0e281f605dab6ca0482781949f4e355fe9139b2f68f0126cd2402c6ca2c838f6ecd9f350d8302826fa0ae6340b58b082f575ad7d7de952c6c2058b9617162534af2b637677625bf8e36be90d29259625b1f15acab3748767e0f2d257d33bf2d8c223e98aec25911354e1cb27c1d049d44b29ead7b7bde25749ceafcf9db1d50269cb0a05a5b762308f1e0a4f6038c10acc489ffcc10ce174cf3b7422823dd375b9781e15284aa1d0b5e8aedcf48d24891772b4ae0c78551503000080310abdf60b09d4f9e6501a8618514b788c15968e0522191758290cc43a1990656c80cde880b4f3813340808611a711823b23581840518304718d12e031c1b28182365410dd58819c92c26f50915b45061a6ab801871caed4d1c5d7defaf82aa287efd5c2c3528ec183c07afdc24ab542f2ba78a1817aafaa6278380036a841b5ca131e608b85d8e9121142c0b37300bae2107f5f7c420c21a6882583436665e6f0aa28acd801fb11d0ffc421feee744fa179a389858329c6a166f334c518b0917238ed1c51e871b3744c11eb78dadd63459cf24652c922063855968b45da3851867dc1ceb072220dfb92493b876bd8306cd8a8bd61e944a5955a1cb68c6865edc81c160d5eda3b57568dc513dbd8a90887dc3cbc72f0ead93aa20f3c657fe0182217469240ccc05d9238081bd68b52fc6205cc92108c250c67198277602278cb8af1218ee1b245748946789164c07099304cc48e89466c9978843cc3ac848724f366c2095e2436420ea644a5f21628a59b3403553d00cbc640eab0737096a5436ad93dbc0395e5a14adc22430f34b00f35ec0f37443569989c688209344b2891c419248e3053e6bff05bb1562a1f95f7e3d116ed1ddd65d0711a6419976d401ad5322dc336c0e8e4a0bb254725e522b6ceabeb110c4a62e431196a94b9e7649e83ba8138c4be41e540ed401c62a7d50371881da87e200eb16b505d8843ec195410c421f61dad9feaa486200eb1b3aa085a8843ecab9a8138c43e8238e403571a8843389037101d90045484348317998992fdd25f9f7168ddcc11d0cb0fc4201f84fdeb66a24439fafe08e8d7a31c6dcfdec212195a8f7168413341cc23be482484e033436c1262a212452c41068d192690682209279690bf5b9989a96566993a4c2cf3ca3737d1ae73e99bd7d0ae33876f6643bb4e2bdfdc86769d387cb313ed3a95be190ada75def0cd51d0aed3866f9682769d357cb31bda75267d730b68d749c3374f41bbce19be990ada75caf0cd4fb4eb44fae62a68d759e5670c93ca37bfa9e39bb1a0e39bb3d0f3cd5accf1cd70e4f8e62d62f0cd5ce4f96617c4f1cd71e0f8e62edef8e6174c7db3176e7cb39c36be198a8d6f7ee1f9e62fd6f8e6396a7c331830f8e630ee7cb318667c735419df3c469d6fa623f5cd6490f1cd5274beb9ce18df5c46d4379b21c637db09e39bcf00e39bd190f3cd6978f1cd775ef0cd30e8e29bd5a05db9ce37af41bbb2d437e3a15d998c6f668376653adfdc06edca637cb31bb42b477df3549c6f7ec305df0c0717df1cc716df9c07ce37c7408b6fcee29bb1f8e637df7cc5375bf1cd557ccba76f49c5b794537c4bd9826f29dd7c4b29c5b794517c4b09c5b7944edf52b6f9966cbee50db4ab5cf32d956857d9f42d71a05de513dfd20aed2ad57ccb1c685799e65b2ed1ae92e95b5ea15da513df120bed2a9bf8963ad0ae92896f9985769568bea516da552ef12d77a05da512df9207da5526f12db7d0aef2ccb7ec817695665e967949e6a5112f8bf8965d685739e6a51849c4cb215e867999c64b212418f9e55b8aa15da5976f39867695417ccb226857d9e52510df920ced2ae50fd287973d7c4b246857b9e5250f2f77f8964ad0ae52cbcb2c2f759058be6513b4abbcd2552e7d4b26da5522f12dd3d0aef2886fa9867695397ccb27685769e55b36d1ae12876fb9867695687c4b36b4ab54fa966d685779c3b774a25da50ddf120ada55d6f02da3a05de519df520ada55daf9966e685799f42d5b40bb4a1abee514b4ab9ce15b5241bb4a19bee513ed2a91be570eda5556f9de39685719c3f7eaa15d2595efa583769553beb70eda55cef9de3db4abfce29ba7d0aef2f5cd54685709f5cd31d0aebce79babd0ae5cc73723d1ae4cc737cb40bbb29e6f9e8176e539be9906da95e5f8e624da9563f0cd35d0661b6857b9e79b6fa05d39cf372bd1ae1cc737e340bb321cdf6c8576e537be3907da95a7be7989766537bef90aedca6d7c3316da95d9f8661d6857c6f3cd5968575ee39bb5d0aeac465786c1f39dae9c465746a32b9ff1cd3fd0ae6ce79bb9d0ae6cc6370341bb7219dfdc85766531be3908da95c3e8ca607cf317da95e774e52fbe5908da955f5d19ea9b87a05d594e57f6a22bbfa02b77d195e37cb311b42bbba02b73d195b7f86633b42bc3f9e6236857d6e29b91a05d398b6f3e43bb3216df9c04edca6fbe5909da95aff8e6256857b6e29bd1d0ae5cc5373341bbf2d3373741bb3215dfec04edca537c3313edca2df8e634b42bbbf96635b42b4bf1cd4fd0ae1cc5f7c4c10ae7b034af60611db24c2d3bf0b06de961fa40d75b3c1e928ff7b015b42b43f1cd57d0aeecf4cd6f68576ef3cd58d0aecce69bb3a05d79cdf70c826ef5e4bce299e0797667a73c244fde7ba327181ae12cd3361991b4b4c5fcc2ab727ee24ff05040697b92aa64910d3b5c61821b78a8e205a52d549400871e7697bd56adacf8d0710b79c4658b2857e41b1200f1060a9609274a17384f74c0b48012841623c8e2e58aefa2f0a045b3e2c9172b44b003982abea1f4c003f73402219e42b0250c154f9ffcd04337dde54430c4144f3d27bd3e10d182f7a4c811789e47849b6f1623c5378f89e29b8b80e29b8d60326dbeb90c5d2d9b18a5f2422afea8385ff32dc8dd6541520fecbc893702e59a52e7e82a35e90a42114f49e65d89fc90d768d76dfade68d77de29ba35d57cd7747bb6e9aefa65d97e99bd2aeebc4b747bb6e13df2ada7599f85ed1ae8be6fba35d77896f16edba4a7cfbd0ae9bc4f70fedba67be5bb4eb22f1bd8376dd23be33a05dd7ccb706b4eb96f906a25d97ccf706b4eb1af1cd01edba457c07d1ae3be69b07edba62be0140bb2e11df01a05d77886f01d0ae1be6db69d715e2bbd2ae0be61ba45df7cbf70068d7f5f2dd8376dd20be0940bb6e97ef02d0ae0bc4b70168d7e5f2eda25df7876f21da757df83e00edba3d7c238076dd2ddf3e68d7e5e17b8876dd1dbe1340bbae96ef0e68d7cdf24d44bbae0edf0aa05d17cbb707b4eb5ef95e00edba4bdf3f68d7cde1fb03da75ad7c03a15d1787ef20b4eb2a7d0ba15df7866f06d0ae6bc3f710da756bf82642bb6ed23708b4ebd2f0dd00da7567f87600edba327c8740bb2ed27711da75ab7c3fedba317c17d1ae4be5fb01b4eb4ef91681768d7bbe8dd0aeb18eef1168d748c7f711da35eaf92681768d737c23a15da31cdf10a05d630cbe93d0ae31cf7709b46b8ce3db04da35c2f11d01da35bef1ad84768d53df27d0aed18d6f09d0aeb18def09d0ae918d6f0ad0ae11cf370ab46b5ce33b05da35aaf1ad02ed1a61f0bd84768d77be99d0ae318def1568d788c6770568d778c6b70568d768e7bb09ed1acdf8be00ed1acbf86681768d75be3140bb46a9ef1668d748c6770668d748e75b03b46b1ce37b03b46b8cfae600ed1ac5f8ee00ed1ac3f8f600ed1ac1f8fe00ed1ae704a10ea814ec582a631c2a3422020000001000001316000018100a064402714018e7a128b70f14001077885270509ec8023990e3300ae2388818638031c418831080199219190480b1405a1a38666e41a623b341afb10d99edf763787161538e975fdfaf633a22062b834ff782b15980e69af69f7786dcf9fe9a8e5e8977c17eea7b03c6a379366a833454f075c8ad8c9c0de8f49636d95279cca1be6f2ceedc5e19debdae6f00b7744979ceadeeefc8e6aa50ba523e4fc8f1b7fa7f90975f29cb2364ec51fd5fc84bf794e58e765dfc8da73839c4d384457eabb551dd4d40db19dae33fac1d31b31b70dfc13b8c627ec968024d259938836fe7a98706a046f567c123ee2674968eaccd4bdb4389e78cace562817234cb767f68aeb52edd46624a1f7ea640af01a16311e5d76ec941828e262ad495d439838137c8a6faa0f98a99e9407e64ed00b13701a74f82f0c18b45919a759a63a842b392c6a954bad69efb79683c5a75a9f6f141d4c32727bd0738eb26c2a0abbdb86897a77820857f04e19b51b3ab6aa3a8b4150ba3ba642fea005ec38d18cdda4fa439ab6d7342daae98e9fc5803b0d15c775f15b9973731cf72b02a9f052d8c2515f42b85a73b98d063b082add5979cd972cb81ada9cd18cb6ad4fa477ccc835ef131cbc4912f674bd0f3b2d2a1386751557e0ea2100b8d60c1101c0ac1412114123f709a4124e470ed4eb6ddaf467df7b07f8bbbf7c2732fbeee83eb7e420b2e646effc5631efe129777d07fc4f1f18444f9bcbb4823eb8364060846c143cf1b9ee526844cfc7c27afffe917d64de92407b478dbe286eed8c03d754a7a8dc8cc60101deb01b065dcd34ca19831431f73fdaa5726b52552b7dfbce9edace5b42cc4ef83d0a830c2cc22caa89ee9318afe7ce21629024c6c2af96176c68c52032ee12449c3560c1a53c5692e887d86f2a4365f42f3640fd8316244e50195252d12f6949a6f17b2db8a32468d6183e73a6e748755c0095329a8c52e2abe9d261179d2048442f2caa181863ab010ce7215cda5344c4cc9bfc18912a452e116517161bdf60bb51277a6bc07333710c87499b11f8d468c250835b19e1ee4760a751ded7aea43b4834b929b73a0ce84e7404a835ed0deeb4093cb0b0abdad9870076052405bfed276b5be3ec309359e51f603653ee1b6733b783bc812f816f8b2610c162c63d86dbc3d6d13180d9094fa47584c2b1a3ee5704d96e580d23f98a1ce39d9ef3df9c1ef3de903ef3de103ef3ff183ef7bf203ef7bf283de7fe283de7fd207df7bd207dff7e407def7e407debefed5ef1efcbe27ee2c7469147d917b8b4a0f4604bdefc90f7aff893d704219dac405feed0602f81e146858854877088e8913c8223da6679558326159ce2ee3a8b0468c8089a77c1f21c5fe4d3116a4854e66988d7bb3d9dea573cbcdf4fc57020582e1c142af4a4a8cca570b20c4e9e6d4ec6236ca8ec996e2bd388836b2eb3f5ffabf3842ff77e7f08fadf625d6c8aed61402730df2079bc7b247b13dbe19cceaf8ca344be323c32c8fcd8cb36c6c331f4b701dbb5426914ebbfc85833d0ca1a33d49dc1bb2d9c7578b4c20a205f415d39b6d144bcf2f1a07281a054b1574120206cbf7fd2ae1da3a0b57affaa10c215bcfab2b3088481a93e077c6647c122be534267094b4f7f32b29fa4a8a7b622c2532bc71a4ef787aa3ec7c908a0c1713d09ab8a9e471d139fb4305af98ef580a04fd7c2653c6035d5adf3525538d893292e9ad642f238b9a9abfc984bb569620be374a767636ef9a8aacb5a81c9191cf26d4d30f188ee0a81313f16a7ed1a923fe881793feba3d80a73ec111476cf2f57eea714d09e8559db564010974a5eaa716328c544a60afd5ad25058e802fbd3e5d1cc3dc5207f6b67574017a28d9b1938b4b822e83064eb2b784f361ccc97fcdd1b19803445a3bb697610447cb7fd603468fb6f068ee39335359885619c2782e2343b182158c011ca0749d823d51e7360458613ce5464b667840ad8201d623a34e0eeff7b5006f6ef86c0478217bc7c921907a58a13db1bcc198aa0d297dc7a4d538d94448a96dbb69c44c2f9eab9b69485384b56354b0651dd89ed6b42c1104416fa5b9424343394e46f6bb115e0c044d2bf2a4273115b5a11188ec65974870386923ee1188fa3d9af8146ad13aa55ac1a67a306fc337331c10316dd3b508533a01e480eab663370226cede37e16baab1971077af1af0a8a750488f269d02c47b228a25ac9891225a70c11416aac03b49f8ee3fc9099f37577849a147ce8d4cdcd7b8f86e6aa2d913a471e65315b74a9562aae0dc6f9cd1db7db0db34be13c5a415f53eead544134bbba2b754fbbfb482bdcbd3e804208b92208d7d974137baf370497ed90cf055f5cc6f80412472023faaae22975f8491e019cd998075b00104f9bf02e5e65c68993943ed4a2c665ac1a58ff4362692206aa9390b512d1c25dc8204c5cff8999ece3af5143540626a0367e9438acdc0527d1b967431a889d9e8c19ed5542b931bac7f0f3db1514227bfd6e568fcbfa26f19e3ca2d60aeac2ec417bb1733d3d447565f60cb0670f490a00f3b9f4de20b39538e8963ec483181e123c4c3ea28dc55f2c446727479faf0191aa98a1f1a0220475ff2519ea6ce4e143bad98fbe89858511c2a7c769b98d6ef26134726b1b1f0979b4cd9cfa180d297cef5ea24ae99a6433eb9c9789021d46b753eb3c411e5a398825c8604934d653e3e8f0c4c72e147f00381a803dfd4e9c6b49cba71cf7525e37577693a331c230332661277c9778a4ed7be9226208b70698b182d5b7325a7166a3c79104558c0ac8a870613da76e187cb5312fae9111a44ba05d032111e82a3fe343e8d4f75f6f4a200fdfdf46a9636f6582eb300832a2c7da8cf84b8bdece358a0a5fdfb88eaf5161a66029d93ca73036eacc816b311b96895c418d32eea8d65345c312a4ac393eb0874106291e8f9bca6430b9ad0279877a160383a0e746d8916c01529c4745c31310ba2bb47210bf26fe18759c86d44406d7cee265bfebe2fcebbbe263b55fb778b913968a0fefa9925f81e379627773aa65d6fd27256602dba5850da0e87055a5c89755cb545bc5fbc3c59c68a9bd411dec74b357aa8761b7f7274a367ee95b66b0b5cbc520a74fe6ea8fe9e11a99cbd5ef8e40555fd5acf710f23272fd275c8da450ff090feb4860dc69fcf6b301a3950da6f5bf4b8b7d4d50f535283cd943c12e5da69f28898f2b817c3ef26bb18ca14b0f67b7d06a2e7459a349f152197813cc4236820ccd579a8df888c1644b162396ec8d00870ba6462cab3bc954a361285299928cea770ed4345e3ae4614416c4fb6969a072921a768d0bcc13de06d8eea64a5326d76c1c03b9d78a3cdc1880db5e5049928808baca20d4a8621bc39023806c832ddafd93801984cb2214a6e031d6d6ce7208b9a12e818fb091750d8a3a33a5198a01145fc7e00f3a06ac445b403cb36a29a316235daac9c6e6c563615ac9eb95cb399949dc941b9549665aec5b18b27379d633b9c0cce706dc910c232caacc08bda0032b9b6b858d870eb9b701327060f3126f53d520248bd06004e36b1ae39287522213eb9e7b83871a588902d3c98dd8dcfbc0c010b1116de0d5f9a586d45bdc555fd9764b31ff1c617d8720d7ef3d1212c875736af838097799959fbe1ef1ed6cd1d9bee88b98796575860ff2a8dc13ed60f265f674f7442e1ed6574c08b70f077fc48255ec29218a452660a00c8a5e3510d491f845ce8d111fec1ebd2c3def4bf16fe9b273485a40b4d0213036a844af4a993522e149b00c780bc842fcbd2ad6115346ecf992f8406a97cb23f1f3d3f523570d35a0a048790b5d10fb3e2a9dce4c3784625f947ddef45004ae473f1bf4eb4e87a9d0242a6131e6c4c600c4a086104347229319b4e8a76b3f2fa852bcb0a26584cab0a13efc49010aac7f8b7d54692a34de6f8ef33ba43270e5e4dd3973a6c0c093a3e4f1f13fea7b432514e8617d9f81b30c6f3bd9927be188e0edac7c92dcd8b7c20bcb079ee580d4e27488d59d741bd41394f53c94cf8f195003dc4db500487223d211d1ce23995a4c8356eafd210f463dcf3f818e12157c71c5ee6a1a13b4a1de1c45112c723f9b3a2765e1f6ae09ed6ff075417d4b2e37d6415a3da39da52ac01be24c2aba281d77df068695f4e2b4d8e9e95e0d1a68957c489410c6640e80cc175fab9b8d5f77bbfcb2e1dc877dfe16dc761107af177dc8ed5813d0d17f42a1dd4c51e2f5cd769459f60d9f099a61b1d3ad5e64a58f7c267995aefd0f1c166b5d4bda504be7ccc4fcb8ffb96bf7da88c23b206ccfff10b147503ba2a1a07fbe12ac344dd10fd95482a7b6b895961dc160432ea06e1f2eb05cf47f9b643121d94a16e70f01962a850c66a2ae1d1a15ea739989ce5b36b09ee4ea50eaac05c7f95845b5048959b1ea2b7340293a71c9326516d8fd25a704f31f018dfbf4566e3004c41a2ac35d006c541ff0287273e18c7cc73dca9a604fd2d9329c4453ae2ee962d0a2949d7709a31257aa9eaf24c3af2e378446584f5f614499af3993d669ed708d35aad43eaf738765c7ca6b0ea6bbeb38a06472145801d406429b921e30ced4a9b01bd44eddb4c8e9357398a56de4aee380f2c5ddcb499dd375372bdf1a8d155a8580725b075cd2635e8348da39616867fd3e888810319d5de4705cdd51e2ce3860b48cb29f48bdd7cf31876bb457f19ea6d9286e60746889683cca0fe57824b9d33dcbc5f959ecb640167a095f090df4d315ff62d46f5569a56b8721be834454b2f4c61cc454a5ff1aecfce9437d9ffef0677026db1d09327d9f3ae0e69b4ca11b83872ea459b26b42a10749e3f3196d1c53e0099bb2a7dfe7e0b5e8730ae8732cccc360d2bb9320736de0e4ab2c1b4bda3033ed02a01ee0a3c79fe62a8d3f88a1e288eb6cb16f929349171c6cefcb6d326f5c48f177a6d49e34d53fa5cf4beb44e70d0c4e7c69145d44a7a012cc6d7da51cf5377d829b88517ddcb2d6b164acec059d2fc0fde5972064094e90b53f24595093ae4b715d00a316bc8cbd2717246b799eb25612012490eb254408279330e0e4a2a2eba863553ccc5ae3fbe728696fdbe396373bd762d6eb0820f83af19e35fb8d8b26e623a74915b483b74ea2eb6b4dcb583eaad49dab3cfc13c56e4620ba63e0ca5e92db6fb69e1db7147724238139b314e10f45f738b20635b5e73ce847f18c409892fbc7aa2822032d62ac19da222b079bacb18c2fee97e6716291ecf65543d3d29305321496fecb7c740bd1275c8a62f7aff54f2e0b9c77ea4a5732caf0c024169018d28e2fdf1554da8bf3b282d1ccc3f4a6fb675689369f79196be12c2b480e7610fc832a6b0d054e9cd58b8b6def7a0a7b5e00030ab25bd9b1ac5bac2b43c3d00608386233390e50b20031f9fe4dc2c4ccb48a127a057f681acd36214cfa95d92a39f781efd6f9272a016bbc49ddecf5c4f25d4a2b39279c92da9c5647f705e8dc0e282ae3ce79ac9136f6d6d9e61e7d43faea387136a99bd8da33589508cc208c17568c16e7780a018bc844e9703763f0cb60422e8ea707fba93afab542b2f902dbf23d4c209df3c698188b4ce3c5f6bb751514ac5872fbd4e8e37ab5779ff644c44e49c42cc76ea2b6698a3463f49bde432686001594119e30261b75e441524715e4da75c3e97d2ac1b3b4fcc9682df1d4494cd4787ac3320e01561fc9862affe98e8ed2d48584447e6cc75cf8d4223eb16e436aab2dc46a7a5c2c65146f911c338642c1cba35700c670f05dc7b0098e85b78c5f6455d71ff514fee9f97b1f249c2ff0a9236107eada62d4b95eb0b72468f3bdcd42da5112c1201705f9dda5781e9c8e2282cb47977d81ca9f737fd11fc4bed47f76d8b4526c4f2bae32e7073998aa33f14ed8c3f1c6482b0979b0d49a4995469af8d590a491f671b4ab9e3f3fcdad1f25ec84c19d5c5501fa501a89948c76ebb34c34f80230ed45fbb308a953de160f86d063926d9de9323d542634033fb2b3301886386709c59a7c145b78683b2b2d188136e0fa38ffa4def1153287b4d2193a08796e9e00b75ba5370fcaa24d994cb900a811424c2448738c03428be4e44357fd23ce54ba3b45395862b79f1ec523023c00d624409e255fb2fab2e458fdadf58d0fa43a9221fc63417b77084ab361f3074db3fd08b1c1c8d3f340378c65ecea09221b394bb4052a5c816a4ea96791d94826a5d1f129b0f7f587bd77b0f9b890129492461cb4819fbcbd99d400194f0143b77154573db5ef9ca6da8303a447b12adce0c8f10802e9cab545f8ea19d189ac3c3583feb822b69c6dd78aac07bcf7188fdeb7fd6fb4e6a200969bed8f9b5c2a9271fc5da7a26a57131f521682d02b765ff77d5e9d6108510cd77b6c9d48b4bb305af7b41970e9efc5a5911893ef021673258e93ceb5098039eb477adea77900f78128dfe58701a08b68c5feb638718db44192d358f6d2a18c5a1c1ed8268b79699495ecedbb48378f941343e3264ae5b9b16902fea417439ea3478c814e69856ae21dfcbfb9f6826c460abcd33589409146cc79e6013239476079e735a75276b564abfe01ae4b0a1f7b571b8ace98fc6d6fa1c7dcdecb1e223856856546ebf019ec5e4b3f8f083f07a5f9e8b050fbd74dd9271611a239deedce9a1e1be7060d122a9fd2640870ed59a4f7529048a1be46dd6dd3b9f33c8d5140b49e489a95349c6a61536b4e543de7ea9b619bb0ecc591927e6465bf54a43230b62adf2fa9d29a413d35a827599d69ce3c942fdd5e0b51b3146928adb284387d4d75e7143f25da3f4036bbe6595314367723cfe327f0ad1bec87b3dd0bb97f63119792f2c0e54e25e37aeded36f31f957affb2c9c01840a0c520d5fc4b87b22f3ac469d5bcbf4c03109c17ef9ad42c71e7a61ecf970da2d16bf681caa8053c0042c1c5c8efa797f38656b315fd54aa3522cba68dc547a8f01b8c32237aa0fd9616a989ac912a1492ab784f0ae8fe7dcd9a4ae89a579dd0048a6c883a8ae6551494f88f2fa9c54c01093c879974ebbc8867eeac90cf50087195e196ed14dddb538d0175823f9196eed8256c1c6d3fe10be4dbd6bf0ba937fdd860b437fae4217d6314850e2fa89f67ff35d4ded4780ac4b55f88c6c278764859903bc9aa21e1a26cb4e6d94ab29381828b649245c57781e1220322f039b58f6f7e5fc8be82dde673368a7b78487e5e1bef97eea92c0d235245137aa28d8ae3198dd3672da790646ba4c7252ebd4051eaf84d4708203092e0e6bfa577be0ecd821806ea5d3e5ee9098ced982dd89c768a4c363354beb400e868078b2962410cc82f02988a51322b05639cbe8f52a12181921488b91db2fbbb193f486517693d17fcf1181327878bab46e9ee06e165752460e223e6626f13f7c96139c685915688165ba124d8b2725848c134d746c6b8477f29e7dc352908e7d0952dfe5d27b93e894682360ff8851d58174735f02dbf6a19341ead2982002f2c389371d4213d551b2a6e2d9950e9e2b2011d368c3e417f365b01300fd187508183fd53aa044712e2c6173c3ff86318a1d9c4c8525363bf62b8f1da1e3083b2a3ca385c13052fb57c6b1ba8fb4a193a1d0fa68eae087b348d4f0a4770c3319fb29dfa258996f3ced72b503afe5ba9abf55e081c5edc7b16b01493d8dc98088e163937b6b1d17be8defcb4614be7381baf158a4e539a3493a7bb7dee69df54f6fe8d05f96f44d8e983fd31f41a760975d2d78e08a7bac69abb735fe5ce6b2a7851e14a49c9546d2f3192772445e8b86e529bd5f5762ddef881ef59cc85901a65e3ecea37eac1d7fcc1c3991ff488a6545c5197117b11e5baf968471a491e6eb309d60106c4c8d42e18664e22a2cf2331fb0e457131490d4bd164ae6b1ade792f256fb24e8e6e65dfd8cc6375f692c8817a350570a96cd21640bb3b4da801ca9d8876b9625b144493c1aafcae175f6a3f1366cc1a5e01910546066281166780104148be75db3e2b803b075bed98f97770f6fc610e2c5f3a37f05d0eb6aa342aaa3c18e839845427a0ee4a0e258d29880cf33776715bd21606878282d0c2e549b348e62ded1e2fa63e9ff7c2a614746f087dfd2bb650c1c1aba451676ffaf5b9a98e36fba502a3c09fe63d81465986267953d8ad692db33ff732b52ad98cef517d6c8339e84e0986675c74dfaa27d62f813aead19fd2b6280ba925ec82186892ec7f2c1c801abdceeb8478f979d08626eb61d63d4c66594df4e123b21ce98093fb171dd7152589890cf4382a755d88b6a62da05c6ecd92a5cd3e12e6f5a1e0b97d058bade6fa7cfc0c803451b1f1113e4d86314800e70e7bee3a3e3d3bad5fd287035d387fc8fc017ef78b263c4dd55b68a6209d8db6a9521c0b92e39e321637142faa4ec315b948fcfd9edbbf2974b68230066ba22f4afc7de0cb4acaf3b1d8169c71adb8a986bb6837c7c3ec8e9dac5bdaec8c732c9c7142e24c823dae80ed31fb930fd7ce4169fbcc7356960ac878d0f3ab928ab2da259c359347a7af2da4fc6512dbdf23f05e4a0de2e551d7128f6fc813e8ac3b00a4538eb1ffa690c5ffd5b28b44f7ccde5b3170799ae799563140a529bd8213b1958761a333bd49bb91746eb70f1c7166c017ce429531eb19dd26a426acb3df184aa03d815b6346adc30e5b5621c784377b09e13300a3fecfa78f19fefea732ed68ac6a72ccd0c9119eb5761454fb61e1d3752bdb78b8c2d1949f59018fbc7b9db0b794cd01e7c41d6182c2ae0ce05176e701c557d5c75964790148a7a3caaf89fcf0aa9e39525ad6b96e5276768e14c495b8cb2135559d2b2ba7433192ab3327b57ad3800ce6707f214c8b4ab8f81d9f273eebfb7e6a3507d82e2990d5788e03143eac42d2ab7b0fa73c403ed13cc26bc10fce475a7b70b574563aa167d6f9907abc7768005b4363ed903c617ef1e22a9455d2af1f1bbd07bf9d13fd892692ed0c034b82bb76134b0ffb9c1f47700e39d7992e163fd5d5d8acce481e08f83dce224309e9cfc881cf8389a423ef4caf98c0fac9608b3de40edcb209201ee3e6856cf190e90cc4dc90a117dc341a0d9faf7340e7cd3a4c2334e7786fa583123b583f7e183c6da07e099e137440cd5f2b4e48c00a55bca47469e2d8fe8cd4d6f3e8edfa16963b07c4f6209a4a976a855e6c0f50813eef0c0ba7529fe9f7fc85fb4b3caccc0ec08f6c3fe5fdd9ae57462a2a58f47895a919888086a49adad209044954114c78727c87007439c222196ee13bfb65c6950753fc3101afed5cf5c98227943ddd6678d32de5c8e2df0a2f95628534769b3057068cd3f7344f0a8c1091830a80b80545ce50592c64023964844b0748f2433501c2e65b4cce7cf406700cff4f312c5d3835664678d1d9491b279a3d6c40fe57184314c9b2239f1f9727ec10378224441b794b6db56335aee511fe3c8f8e6258391156b8a95ab3479cd6c5dab87065b8d05e8cf6af5207342782d97063227ab1eb9421855e8ec03d6a48a4e62b537fa7ef7eae969d2481569ad35bdda63ec05b8b357efbc69168304d6c326f3d376708c0d77f646b9156652dab731431f6b0f5342b17c631e24ec5311c1f95f07e04cfbe052c3cef014556099b6a1c9862d344fcd25d432401f660c6d54a3c33a9067c4bebc19f28567ec053fce4e1a105d7b142b4bbc99ba76fc4a19d727879cf8642ebe56b7fa3d56c117e7de2b94fc9cd5ad889233e1a880d21c436b447ceb32aeeab1ff114b7b7cede8c2eff3b942f65a2f2f3f5c42909c89499bdc9f3c02860c903df1821154608c75bf408a61d3478159c2cf001a449e6f930b4634573e5ab8ec3d7f6b6de03f2acf59384b571c51f1a9901264fa75115bd18b9085a7d45a038e44634f29e01d509c888919a8338b652365e8732236907877976a6deba1fa76064ec7ed711e4e01fdaa35b5c03f875b5b6520372f3b042548670b9c2e0de62aa67f2c328a2a891b3aaf98b139d5e1ba8a29c5aad41036894d566d7aa50a43d0568657f52236a8025ad15a56411ac68a1418ac65c03980f8fb3ab162bc8883e61347931706f17cd483e92b7b93c38720139af47c49cfe88a4912aa26dc7cc0620ca64a31e1c7d4bae84ae93d2f80c1dc49d08f50fa29fa8256e44339545ea4c41827a5caf3ce0f496ae8eabdd1c21a0cb1af79ac8e85f2629d10746ef6d3fb2f7a1a48372693a7e1f16ca76bdc41812ca10f37a56dd6a311f8d3083e5b4a667c5eda0793d03b2acef287f84f999914c334a22fa6e4ec95ba51e3859d131dd0f3da4898236b50ca93f13c370c655e1ffaa1ac2f3ccac6842feacef74ff30692da87690cd9516adcc8a10995741d19503f55e2be4d05a96f112a2de31c60966c9e7f050a961a6948784763e0b8d37c24b69026456074cf7be48d4b9e7ec3c7c03348cf7ef8600dd3ffc5992b4cc05572e6607482f6ce14bd7508142ad8a4b63314e55ddd97ac32c0a30c6cf20e6253a6384b3891c914407affb5f25e34457a935dc8f2b51f25de4cbd271fe494521c724fc97e2a709d439f0991432cba14aff95ec7ce37f43a7645dea96a28dd173735a13f896a9a90f8dc83c93f26cb219f0ae9ab47269874d9bf15179a39a8594083532f216698bdd21cb2242bda9ad1deaeac7ed647ab572a0e9a4a8304afa46586c17c239a1fbd71704b05a5d13b27b2b0e70891ba4878de5a764973227d40bd49d9656e8843e09558fe3b585b86652c7fd88a2cb1acc81df7683ed9a2d15f1597c53c155a784e837b1c52349596822ef167b90fc28446ca643b92d23a4088fe27c27f14e154f411cce627ab90c9e946720d5aa34993b145b9d75c4736d322f7a24b209894f950ede2ea7a2faf6115819789574fc0b41c8d66c2951c9174602b84e7fa85bb732f9b1ca496b265f85c987fb26345e71e56d48f9dccc6e99e91548de140d07031a992a790cc9f0e462f95398f040db3510c8986f07bc4483c417d862f83da4eabe574cddd17c64a45654812e8c1cf0198f1e804de9d222a63d47be748adef1de9f36394956c33a58baf48c751c9b9de62f2ef288f60f35c01b22f431dea63f0ec292da607d38cb458ea050785a527fe93f304eded3ea1a6a4fa12612a38bf98f6b7812d41af7312a9e12229f777da7d62625cc1c39f5d9fd2099f02aa1a386e4e326c89685694888f42297b0ad4cf407440a7ac0cea108e649ba2b32dae1b186a34d3780120a8722d2ba3281864cd89eaa84f98e13dd7132c2ae60d3a16f5093df0c46b1b2ba098d0287ec81f67db519f285428fc0230c0f5196eec0fdf6c5353357fd2530772e5716a5f9896845b3b8105d52d816086946a0022cf9bf80e1b5a4eadea4d960cef24b186ecd7c1a7e478d49f21047ee9b6c4792dbbadc0a84e304da3fcca677bc920d205075b9427bb2d4e8e1ca0500ffd75d26728402f0c4fdb619b2f124645ca3aec869f4551c16e097469c47a242439b25bc2a6b393089094ebcbda03f20d2ff131e548eea062e758c127fcc23be200c5e0cfe58de4363c94f157900bf43f479d2a26755bf431bb256efd3d710645c391f6f90c92ed8e7394d300ea48002e718357f16a88e1cc5fe9ee87128c1a79184213b8f0092a7267b0c221824eb20e8770247aa03989245b33b006f89c56e813c5c42c28a023dbdcb08054d0200be7b2e313054702b480bde3757613edd0ebd2cd53de1243bec630b15c77d12962f1d8c442769a2cc8ce193e7bc20e80e98e51ad3c317b42f14be0ab7482cdaa217b02e9c0e41a6b33632c285ac1fd5ad19d5e69b0321fc47475d61a97bf8e4aaaa4f60384a70363f2c7a12717a3a6d9f9c24797e531de08304aab6bf1d74fe804338065f1051358800305c9e4c112063d1a99229bea251d67d1428f14ab883c0f54e5a4ec96c1cb367d749de5061a03915ce6f59048ac2e767d5f3ccef800d2d6f18bf34d1557b4a59fb7387cb4b780402f08aeecc45d9a5586a662fc0f2aa5a474d555d75a6a881ec415a467b0a01b0a2e5ffa0fca08971984bbe8403641678bd124910a282ae99c6792e98c95683fc59f42bb9f69e8ee0d1fd18bdf617bb699a4f944255e73d256cc04e4965546400a0dff27e5400518e18e60a8af9893fa1a216f5a88bbdff3317212717155bf3a7e450c30cf332f7bd6b0a505986809efed4ffb122f56beb476af9ce4c78f5cf5d5ab04d879559506e7c034c9f2a39b6a94ba05d514070c673cda64b0c0d78d1f9c93a3f984270ef8657fe207b22f86b8cb360b4044761b2f7bc6333d50a293afc2342be60ba509b403dd45da1f3432eebd6fcff354cdba283d7d9c7f5146b9f0f62adf1016b5a8df5482adb21363e8a476df318b48896ba2b8efd9b010ce01eab0fc3298dbe3e3170f79d0e8d7ab6fe33dfdc58344eaa4d2f2aad005c990c90a4e18e0083fc0459550f3c55d073555cb83380e8a5c1cc30c3a80067902f1123365aabff68aa5d9f718d9ab1d7f362195f2bcd5129c39c51773f2aa1c4762bf454058fede5532010e313f664dae4b6f63e4a60a7576cebf04b15aff3cba9a424f152647c4048e2bb096e9b60945f33463e136befe9ccba87007f5fc016cb6debc3605bb78dbb17604124fb316d5d6161fcc8d975c456f1b3224011fd0544330834998932e29ee8ce54edadcbe92d0b69b3f07575f658eb66595cc94c1b79b00aadd9adec21730062ac00ee633da21cdf1f24a27e3ae6ba43d4df60ee149f0c4b481bff544cc86f351c0a91d2e548a50b041bbe06084086b44fce5de6732a6720bb67d1baa68774ce980a3ddbc06f8e4a0fb9ce55c71609788cff4e9fa53110156000469fd2132bdbd38f418f6434e0fa3b79834bfe1816ac5ce404c4fee2e5394ceff438f09872cc9deb9d9f906e738a10ca957127f617135985a29c81b84e07617573a077cf4e33c1cda9b9ba4a7dc54632538949c2f83374d219afa2d98b6b6a5c2e19e9670039909e26eaa29fab23b8490d9817bc394ccf86bd63a8504bbd12ae6af8f7b146b3db8a9d441be19e34dc360c64280bf8601815af6415d423837ce855f99c10a4299518d5c1a7803fd76fd20ab84b6e7ea17af806249704c13e0e83666191564fc6b7d0e63605910c1117e538da5fd5ec3a3b7b1427a8b727b1e4e83a74a7ba4461e878756884100d6810be95edadecceac5717dcb48857de56b7eb48628418a6511c2e9e01ba99103f6e4f9f756e1bf002f75e626e6dde6c43553d70e68153241e1a480003e6db707176296d68efcc595ebc54704838fc1a92651d8a2637e0f877301ad3d0b25be4ec82e30c2e09d739b5a586f2e835959a1cae472bd6a455bd14470832cad31cd3f6cfc0d12e99f7bbbe0c1c0fbf9c34390adb1219271b935d4016fd6408ddd1f014de03b7f3c892c5647b82493005b553f744540674e3279a5abe724d714f623c730056e69b72719c481b3d096317b76809d36308cde11c0884e4e9123051a77e218eb36ef61b220e895a0897d648c29d9e0fc19c6b38e84f948b1f1a76e7eba61c0f8b5235a836361e4d22715f294e5377bebd9e81f8eca3d39e33987a0894b64046d8d1142ba04205ecfe01f90b37e8b6d720118aae5dcee8c6817b236cff0afad0814c7e99244da69987e376cbb899c76b82a9a6c54b62dffebb261d8b11ad73f06912210cd0f921761bd23cc00aefcbf985175e338b735abebbcb8bd7fd2c0ad5c3ae8975289a494a8774d8a46c1e823239e1394504c269c23654548360994b5f0a0fa1f7157ee65807ceb4478db3afd04c6129390499da2168b5a8072087432841f234e8339a9d735339c099a8e4b902784a5c0454c85f857ed890cdd72d09771a928b9bb5534d45fd3387a8167fd6e8f8132fd5d620aa60200d7fbc6385ae22f6d3035dce7b8206d0d2803d2b2b47671bb046b6dd9f3ec33b6f3e2d7bba80c3178ad5f1d1f61fefab58b82c6d83f587b51a30ee7264440c3fbdb50600ff5d2653fe8d36480b2b3492b2725df332801cb5d68001f740d22df56e902b38ec115dd83e484ca525a16030593501923e64914bc6c5a03322e8b1b15c65efc36d9a94ca53707ddc555f9dd095bb656e1628cb731f2c47f376ee9251bf9aadec5ac1fbf4b162bb8f5282d3aadc49c3b934970a09e80bbd2574eba8d7d85b95efa7dc6fd47a1593c99afb0fdedd109f1012c78696db072d1e83fc873a4f763e43d9301ef4550e5b8780cac4cfc8c0f21ecbfe586e21849f79dea10d6c81dae18390a3c2db7a018dd1d40299e7f90d70d25d10a9d645709b6cc3760be72a5b7ba3018af9282b1de149dd707f3526e4c361e0c7707b22b7478e9dc8b20c865f81bd9aa0aff0b10035adf36ca56bdfe17db6ea1391cb3e9499571a44b4668cad42e4c12a96d4ba8242229265959d5baf8f9fb03a227e7e1e8db52cd628881de986f6ba2a704b739210522337d2c2e2011e6c0b876ab72686f2c7941a5e6b7aad5bb2e2e56f613054d8290ea803bb394d09b5d26858ebbdd522c12e7a24c0aa9b7e17829156c75b41e0882168ad159c67dc586647210ad86c6e5bbc1748edfe6861e12aa4a108a412cbf62b0fc4a97c895c08f0ce8512fd651270315a42c0d630edcb9f507f2ded9d0e6e47bac08aec8e6908a31a8f467febeffce7a76b5a50a1d6a87d1f0319e5eb6640860f29b50b6446874d0ba77810f62d830b1962ab90b3c219c211c44ead01c8909221ed0436587bae6ecfa40d7dbd8aefbfa07f999cddb13106e75d13619d500c4c539d2a70990a4efd28e686b5be3ba80ae9bb8970ebce01e534828f8edc5664aabb7adbbaa5bd5c7c25497626b3503ebc603baf0d1ae7cb00b1fec6ed52a3a6beeacb96d6b7a366bd7fada7a5dbd2cdc4d55bf55bfaa8b85a96e8954e97b567df4bfa68c1a290c9d69820f77c5075df1a1ee5b7d7d5dbdbeaa6ea93e03eace85bbf0c1eed7ad71c1ee98a04bbd2e3ee88e0975edeaeaebebf555f57b7519507716d88d0b77d5d7e1815db158577d7d3cd645b575b5beaa2e1fecaeabcf07bbf1c1ae98a8abb2beb65e553f0b7751d5edd5e561ddf960b75e5d16d8adaaf3cada523f1eeabed5c587baf2a0ee79b8bbaa7eaf6ea9130f75d9ead5ebe283ee9850d7ae2e3ed6bdababd7afd629d5b764b5d5abd7add6a9d5afea2e75b1a1ee4b5d755dbdbeae7eaf7ea953af170fba57eb6382aefabafa7a5dfd55fdaece6aab5489f5d7c47e5331211b9fc360ac4fdaa3537ecf0e2e35d574e64887206e88b42c7b47219e9ae272eab35ee72ae91453f73694c2c3efe879705e09f2da8faabeb309f7db52d54c1fd704449fa408991c1277cfb553cd91987fc49d9d357c509927fb421bf03bc313cab71c373c15d80b8bf8367cef086de3d78621681b6f3d26b00dbf2f2cd176b8ad308936e1ec854bb4097f2b3c814db8de23dc86f4ef2859ed247cf1a988722c7196c97f1dc7e0aaa0142764bdda38e93a3813356f09116e71dc7892c6baba2ae279fde3c1e9b94809b65f28b4fe91de81f6ff932e30d491775459e5531e65aea996f46f9c1d9f1d0ac52aeb0a2411c9b51e3b3f15f40f88a5dbdddceb3a2eafc4f636f1e531374e580a076baadffc32f2308cf552ce1bb22dffd6cfefe076519dd310e5fa01cda36efced9afffffca2eab1ac6d459110fd5ff8b96e6a057b85bcccef5926297c852dece99fa8e1000052cdfff2e956dfee138b796dfdbdf4211a1469fbeb6bf7b872630736d4643b05f5e9255c9684576985103d3f8c33c41a2d55d8395e015fdfe53d72a4af9b0e9165001e36be273e1ad735b2a091127989acbd2307a1ab84e89f2ba62486a34d75bb369953181e7bc616d922b9099c56af200772fa5dc2b452e5f51113c25b1b0bd5fef84c121b527fe80ff14eed232d28d81dca945c5b000aa5630494b25fa974d4a20be93eb2fcd91a60728746b5e4ffb824cecd6ed51934de537a7366f12b691d3d3b7a196c1be9443c1145e614be82da4f87c1e5d1e34388630b181432b61471717033b079d805904cd8b209d55c822abb3e91f74d5933227cfad56cb6f15fd2faa36eece58b9b41c8cb69be0666719fc3e94d81e5313442340b06cc2c10957b050861397b996a4f676bdc487592cad77588b3f3e308e9dd719c2aed283132ac02177df02c23eb010e07e9b3302dc945cc33e688a7be29a3c978e27a2562f8b34f38fc1fc096290042034180065a9faeaae84c5bc767535243b59fd5fd3f1cd544f6d4e3faf37980f3a93b91a61ee29351032408711be5acbe595c852859f57489b6159f0adb281bb71459723be972c518bfd8d0604527b6d1e1fc2fd20e1ac6fc06b40bea757fad0897043fc292f00b3f20f3a6e8d210605be0bb1d52c981336225f5cc0fa13421eadcd52048379cc4a764b356bc468d98e0d100c4003e6341653a8308f8c587a791663bc56a1c57548489ac3686ff7c29fc2854b5502922ea6389b12ed529cd2ea6cc8f418c90ec03ec8689011d29f202ca45227dd33aeb6089be3959ed0691f1336aa27a1a8f7467b792a784fb4b53e436ad74122c4e9d9b899a5a9ee524f4cdfafad92004a2dbac68875e8edf328b5bf23602a97e69668b6e5ff881293fd1c5e8322ced9a2f174094d35bf9bad1b13f1ecb82504dcdd400c3b74f6e75ab9ec00b8bde547e9226f5559f987ce793df7be83c58cd11ce4ba1e85974284aaef4bd955f73c26414b7ea9e2a391a287996d86f9ccb793cd28d7213f4a09d80ca1031cf273e70485fe4b1c548f0b43069d8010fc46c4ffe697b89251effaeb57a91df55333a9ddaacb1754c42c54631774b0a98b81877efbaddd9a463e817dbbfae7dd9a0bf1e2f947978b75d57d8a83d6c0c0ff2ef4ff6e5e6f9996b16f8f56a6d68d5c8bd597ebe47a55d0bafb20569e07284e57dd8f7edd4ee597110642ee9f8b4176d195ae10a39aa5de0d7c1ed15038a847e4f70623120406584cd0d9968de400958948448c0449875aabb0ad9e4de81432027a4aa75cc08ecae792fb96461a0fa9ea32ea6d32817dc171b0d56c5d67367180a466418392b5f7dbe5c23fb41c473bea9daf85e2ef9a1aa4831f0b2aeee4a8c62d8d0bf7322e5c9e0cdbfe569bc8440259df9dbe46ff7ab607301855ad4cb01a29df89712114d5cb0fc85c9286cb857651b976d5efe50332da3bb02cf0ec3a3c01fab252acb9d88526f0be8307c33782c5f33519c5f1f85992211f81e62581c4be8790ea169d1e34e50204e62ccd44a6bc2ccaaeef5966ac295bd7bf558a56a443c3f3b5b01a05fd739ba955045f01e3e8831115e13adc04f4d836e01023d7e67095d08f7a7efc5629930cfc6fe36632cb47a2453b374f77bffb8eb9b7a87bab02f9964c7ee73bd70a2d43d087cc097699fadb24c7959847799aea3d5d24534b29a62b95a6636c3a61cb4c6d5ff470fb214fb93633012e8345b7efc87208610a3fa3c480d858f782bb4318c3528866c8884a7c645226df5b229c68b194db408b41aa35d5c6199b1a27ec9930666e508b427ad833e22c347dac48d1e669d1e985e7a6bc8643cdc0b096e20da85e7971ed73b27961e88f5fe6c3001d771867f3b527c4c82eaf1d2bb6da54bdc8826b9092155f69b28118b5672c2f42613529e0b757417b250b5b76c827ab2113c5dc4d6508e834f31f27efd141281697c10e140f79c8140ed40a1017cb740e41aeb095c8f259ee8302b7f9ecbb0128fc5873ff4e73a54c04d6382d4c1ffa53374c30bffd331a03edc3ae0e2d42429da23957767e984bba9c6f5c2123ebd0533816f4b29bd020496623ef1ba84fcd9b9e1daae3759eae9175c85dcd03632437c806ae4a6007cb0562150458333a62d44e871f7d43da09b91d81c6891749fe6a445ad30497d34056d434f746d3eb89592a70549dcaff265a76b0e35ba805a0c8775ac20f6821c06049c725d21599a62714920e8516782be68d2833c7f207fd2e2b37c08011e298caee601a22be3c097b482f15e84f09ae79284368337e5aab78b19a4ae91b36d2dfdcd2796916872f0e70a3d123b98fad97ea045d8584eb5a2bf28856808c77e9caf9e5468329c6cea1d789350a8eca1fd1a53b4249d974356a4d0519a4e391912ccb698deb5326c6cb899676084a0193ca6d4adcb1bb6c0055ea0b87f5fe886815c558690e0ad6db139a058c01b2d870fd58883c80cda635719842ecf4ef229a8776835841c4b18bd0e043738b2fd8c47f540bd761e29540343081495e29421b460a011d233209317383224763af518b7563f8f451d1811e3eb15b6281b2c79823d9be46774639754b3562a8d8075205a43b1f115f1f59e601b7617255adc8872607ff72dd704a64bb583e524bcad93d56584387a3b77676b2c61b6f675b708d74701e05b011e2d3256aa7039622fee019b5537044414004c432922493d5b9fd106db5cbb0587826f49c5b7f70e93bd277b2d2cd8b964dfd689df4816133d7395e439b599c6a280637a1746a9e49581dc1950bd3ed80ba02e1051da955628c4606d175c6e3b03704788e272805cf425f9b972f1c5d992af6e9b63932e5c00e99c4c62aaed30bb1dc4b4d5a7dae6c32d656561d8529aa3f2a1b8374c82d904d8b8799e18d86add6011ce2b717aa337802766ccaa664e2bd3ca34fb93b3bf305468500509730f801b79a4a6f726bba171dbc34053f9fd2cd5d58f6045aabf34f74e55ec6a2c0072520ede9515b5553f4d584daed2ea2c536114eadecbf288c97efc16992d98e202158677edc0f2de0cdb60116a672a64c754e3de833b4c8f9ff4edd346ce2657347836678197f5a52703aba4fcfd3e047932a349171245b44d63eaf26dffca06980bae401f22a5b680de39b35fdb06cb1d3f20598e7cdd21c4198ded8c56bb8f687d8c375130237413f5806c4a81e68d79baf032b831175a7f05c13cdf114ffb0220101540000a3ad9f733d06c3137165d2f48a226c60624fbf1fe63fbc8c67513307589544b251361e0325a94638c890a9370d63e12561dfc632314bce51bc3d181ecbd53834ccbb533b8b67c79cf2c9ba4daa28b29af03b6178c8d613fb8a3811cb10bd76aee852bc99eb638effb3680f8183f16f1589c42bb93384a642f6446360e8ab2344c880af0a7c2d1683dec809ea22f30c5d3224aa77035671d27d3726383cf9164991328b99d99428a1def3ee3a47f02210ce0c92be2752accf4e60516095c2b1d1693a89612adb145d309b2b82820579fedc03deae9990d5a27b6bb2ed23d2c9405c73dce6e4cdfa0104485a5ed8956cc3ecfa576641201c92a026bd79acda01781b0283501722ea3a3e3a375ffe6a8077d958eb8a331f0870abee3d80d1711ce92286f8246991e1151e2d2402a518abcd23076c44428f0d9bd48a18529ae37eabb4c8304fb5561d0563c52ea9ed75642a2409b2b5418f090ad9b75e86954f642fe149f7207801bf6709cd563d6b41a0bce3434f8613847ca807af894a1f9e437ce1341ca7118b2a8a5057537f876f69902b2939efdd02d406512a2643019af2f5b7fbb03b350c5571b2b4e99d29201ccd58ac136a1253ccfc438dc806c857243bec155654547886eec7bbf61d08f88cbf9de49ade9ba6329f71a8154ec0bf4f2e3a7a491bcfb48b433d8be56a227d5493fcac557a2dcaa9b0fbe62478cdc4de9e4a566a9486332196392a4e82b580ea33c6a6baedf74b106fe099b8f78cfad7d331ee2610ff324192d10210cafdbf97ddc58985d9adcbeb79d4209caff8565aa8bbc6953c035ba522d095f1824a0a8cdaef6d7214269082063d7a71cb2428f4d34e81a4f29d09895a5a9c1d7daaa251862668f4c94644257c26212f5d88fc44f957c641df279a39acd38d4b939e71447c51c17647a94aaa4fcac2410963c6f36bc755a2f26fed79fbfc46abfe15e7724305e15f782ab4ce1b9a1bc57a8384829503df923497ea86ba74d23614c73eb3d8ebffa32401d7b19c02c62f4bb2a7c26bfb486ac46af4f073baeacacc0f0e6997073bf7f4388f085c20f2b0d0ebbf9085983476fe850ac46e3ba00abe579054511172d0b29055b2523dfca1d3d02d606521a60aa7a1795b4bc7b8f8679f89544e99bda932a991eb2531056b9d181316c28cf100f90613df40a2b72ccdf9aa7e855573dea8c8ce2c11c54b7c81d7d10ea0bd2a64a202b23597435729e16f28ce7ebb5e562f8e76e5aadb30636af8d2a535f2efa354246e6f6e7823a21207476159d073c5a452e247c2af92c7981021f2fca6e6f442be0d9785705daedd7a58b37b63a3b558ecdea9c91dd2ec9541d7a76b652a71310431f4e9deca61d4100deb05c68553fcb2168b2d78fca1f1a6f92e43e98dfbde1edb0c682ae7336d9685f6203c19d3b41e4a48223138a8f3d63d4673b166dd16e1a14456c534396ce3de482b9e4a10d08e0188617971f45062aa0079f65920a618df39ef913acbbea96a38c98da197980bacfadab768773ab1f2962b1ef328ae6bcb20b376d1c8481b88c0c7db89796eac8af5fc1cb58cec11951f17706563c885ecf9d04ed08ed74a9ae229dfc4038dac8827905b1a50a74007fd0fe083da1f16cf3cb7bd678728c564e34b5eb595b35d7b9554ed6e3616f7238b62f9070e42f776bdc316c1312253432a3fa35a9b6b6829569f30754c091d6c452f84e574036ea5109f7ceb2fac9b6fa400043eaa8519fb8f20f2f500359c1a70700597ddff9aa9cb2f08946c2b7674d38169f885e7704ebc37b582021091c1e00231e5f600c8e84649bf804db74526cbfc9abd7bb6f2f112c51a5978d1939a73898e2bd91237368dda22d1572e66fb0cba9a9e4285b31aaa48dfd46b86b41865fffa0ea5cdf1bb45f277aa022e02270b5eebadc69915ce411ab5a1719b9a609898c46cdab4f7087c84e8c8236e9496b7c9855eb945d40fd996746170697cfee9ecc5b7d6f63a8212bb10e41285d3cc1b9104437afb3f340d07bcf97d143133554553d7c378321884f8ad109222eaada366082ceadc56e9a0d39a3a5955d9cae2a7edee0d88f2808f8903fadf1df616e2665e9b28d4156b5be74516ee9f5b30d9be00a7ada7b856e162acb7dacbd07f28ba0272c06191b3c4aeda84bf406fd9af6b3d14988a581e5a02e591da2910b64992086769cd4fb6b05d8cd065aab53afa3a26c6cf23cb4d825d64720d8713e720dc828c64c04707984ba10f6c71b0c7964be941a8e966629fd4525937efc9f95649c7ccb3ae9dbafb76a7d0a2de1d6a5acac49af41a4899d7684bb8b9520397a9ad22504fe00b20cef688e225067766ea6821fabfc463a9906a0e80e5ce2a1082dfa76f314c68b5c6107c3bb502cc19af577f840f5ef66013bdefc22256a3c16e050a92f8bedcc7dd398b9233f805231f98833c7a43e0bab6103072dbd37324e4e2719a9e179610f726c1ea28dd0595153adcded7cc7e3ebe795b738b00683f30960e26115b6bbe8fe51c900070cb5b4f02f696b86951539482c1dc09f78cd110d0d4ea47e1179e8825fb9f5b331dc31f8058c535db46f2fbcbf81200fb8cf1e1925b46425bf9ccff08aa72c374a888670d82f00194e89104d00e191640ca70646efb85c4f83e0dc6dd2eac990588c089ed1af7c4850002e6d7d16c37087f61bc440c328ea07b9878769603017b174c3fd763d93d7fc420349bb4f97cd0aebd87168c1621c92ab88d072592205c820eb40a8c9fb35d2316d83792b0604979b2905ce53ca8669e40b002e680075740c4308aec370564dec00ad86da32df054211420ea39bc1233b62f36d7668df3b4ba80c19d28fc94d1b399fa2141666d4725f247d41691d7c398a386cde619c469667e4292ab9a33a3134e88db3b400dbcf522b4b1c028dc51d61d3ad645b59058d99d44ce06efb17627e37b7655ad711bfbfcb70f8be332a01280817cc491f7baf30be8bc3ca710aee674338d8633b7fb65312f7819a76e84a4c1df716c41f91a00772701ad5ac766983b00f4c356b4a98644e387d407ee44d39e8268043774c8548c457a0d89d14bf958677e5a5ac661d4b5c69f8291cd60a6789a08d549b81d793823b5afbfc0774dc4d16ee6d607150b30504bc6c462f8849b05a9c95b2308d2e054c9db5374dc6bcc950b2e212a91c494e9deaafc2b6f0425644d4090993adc75610720fbdb939fe3e6f0f88760d29bdbee41faf188d2fa4dcef1472a3ae2493a9e00d9120c54ee0a35bfd54fc49a8b89e7d5488da8f958c4996cbd38388a7502153db4abb571ecbee7e37bae84d58bdfd5ae358a3f9033db0014ce3fd5c13d7b69c35849af651dc17c64e84c1c33762d7735bf623fd5bd278363f59984215313ba0674cd5d04a331b264a8319cc5be454a6643a3ef299f00732aa972feddbe35780f3009333febbc86ed823b0a65b481555870d7d90b331bc9d8feff9bab899015c144e989faf7fd43a07e3a17f174b7df4c763cafb7b79376ae7e9457e9c293573f99bb84e221f8800faafedb26875c3920a2104dbef74d4e792b947c28dfcb8287466fa332f58d36a44e7c70b942050c80d3d97c3da1fa5429dd6b93e8721dacf1a71eb87e9b7e8aee57eb869ea6ec1ea39685e116d9a4ee430e81571d0400f7ce5c9d8eec063a5cf5d6a504e763940aa84db193860ebd481ad845daa8368d1b253acd317da9f275a58959fe60071530f3585725e75d0d771439dba09516755ac0e02f1e0409055baeecab3426bf2c9f0ea0075f8a8366e9b4d6db1300b40f44e8bba9795b9b05834253293bd44b0b81edc4944cb9fe877650dd058ab06dc26ee7707e450e6f68129599f9406f2ae8bff3f5e06ad9b943590cad277266c5df6849881965fafdb5f5ddb10a654941859bb1b18654e94ccff373f4eea305f063a63394c0f5da23ef75683c554ce1aeb20e36687c59781561d9e0c5bab41450d08423528759badce0191299674af7b921ea6c506716535ba73b19778c40924f2bc874364eba29bc1043621077a31694fcc1856dfe4c0d257bac060e42a77a84cd6f4cb11c476446061dd5e68a75fff917b3648f012e0be91dfa6a127eece8eab590993b67421b2d6c1c218363b3d3d51848681b9883cd5226d71ffe11fd116d300c5310f5f67719b27492eebb5ff2fca50af989f54dbd373fa4ce6b69f1a808b2a61700e6959e1ebf6ce70412c40d9338468ceeb79eb76a6d41fcb433381bc9ed075315c97799ada270fa54969b00eae7d5fca97dbfed9f7f936a7d27e6f7767a3e035e9e904f78b5720b2d45141810d31f39228df83069b3256869c60d344550f483d04e7ce64723567e09b08212dca771b7ea201171b26c0127618609f2f803440c7d0813ef1e4234169fcb2a9a3bba51d935e193496309650f9caf875e8d06fbb98fd545be405ad3985f0d815fe20c2dc314b6df049c2c3259cc498b5b23c9b8bd824086fb6806092f07b3fe3c94901ebddcc660310a2f9cd05ad874fe825248da97b2c3249018c2f091e8a7821ad1efcd9095c3d7e2f885ee863c04d7fbfa9d474d0e37c7e25026220d0ef3f9035712f9b29d098a0016ebad27e977a25192816666f2714f68899897369dfc317c80438ae83d5513504e6f13ea30f2414253666e4ba6b7f4ed034d9222ab2a85148d2924d43dbaa3987b5ea9e8b133b1e0b932acbbfde58a5b50d364dc171c7d0832a598a9235ec1c079320fcb7130d7622504ebf291ea9c3211c7e9baa968c26027c1d55345c439c4f245f72c000f384e33062e2630d2a941438bbf33d92a3ee84d163e45d90d6be59ef73eac02a06700f50a52df2779041ce4bdfde9399bf28ab286cfc082f5b2886aa4c56bb3f2480805222fa4706b498983f5a83b505f5be6f74ec4014bfb7bbb0d1fc242090564b898a691ccd071ac1ab14d6e1d9c9afea7b8668991fd7a893587204b43074a943d4b8b96aa5e73a0e2da49227eeb69b4ab98c3dc75d5e44fa232c9e2ca64a8e26c46e7225480165b6529880ca2da40b0082cc68d5385686b4bbf074d43d2e23209ba3278fc9d1aac01cb9ee926d51c390072f63710f2e317a30821551d8cb7e00e4c3f2ba08ab8eeda4569c2c831891469c934203ae0c5fb52780912fa84073500aa178420a80ea6a9715af04646177691f55a2be25fddc9a9b120d526a995d10527490c7a1914ca70691a2ff0f6c99b2f2a90589fa83f3b992505d8bcee70e513c144474b63109d0321435930e9f6190b8ca978795fc7f2b4a2364f524ed754825e2782d5ea72722ea28184efb8c35970b642b65f25e13e72e8a1444f36542b1a6a8895bfe3f77b9662205753fbc0d8257da71b82ffefe7fb5a42627c05184a6dc1c8d2900e5f586d21d08aff5d11f4fb13a636482b990677a6f908a8356d8862d00b95b09ac624b3d8b05f2945da73bad3863568563a2b99dae1e17a2d80de2a3905294fe1f0d783dd60fbd6dbefdc33e2a96d25754a944355adcadec93ed94adcfef2f4aa5fda624b32456e3c3b8fc9310ac8c9beef0da39e8caf9a8f02f8a2d6284ac4722c04ffe1852c2c358481705fb19bef04493de59b23b6ab83c096da72218576f5e27299d9c572034b32cad1a306e3a0bfcf5a56a2719fd50e66a088ec40f3b852e98eb2af1271f03aef7e45dc35becdf95012145bf44516df1290df48c420369ffb6e91b2aa0be90cb44b62d166fb824b108644495cc82d4e0d2a1d45877df301882fa4081a55038defaaa92c803777677c578c00b60269dbde4f3504be3167831ee5a8886511bf109038dc3180ea22c4d397c48e9e60eca1d2d46adb21f3ae828428440224df3a8617b4c887fa2c55ffe877ae9bde2a5740f40bc06d6e630fc06e2c7f5b8fadc6bd3b7cea6d8e37f7e6a354cfc7a6c168eb854e4c4899210ea8278ed2dfefacb7a15baa88c1624ae90dbfd49cdb344f87d40b20fd16ba705687b5b51d580d75f97e390b19129724845cc3c55d3c9c1b017daef129956efcda6c8ecb00270a19403f327dca5d8c50f3e4cc0960ef0a2ec34a251cd48924a14104621bfb54799afbc7d6432b32ec424a98785d7da4bca1f698cb7727cf2cfae88680604c8ea8b7cc53e4f75165559a8f35fb1d361c7610c0502717d371b5d3dc0864f223ee9269808387515e5c5a958df37c90bc483bec6d275c0eba041b0b189668078fb2f0f2df44518ef8584b35330de5cd3927c815a665940e0560381b821af835023dd1fbcacdcfc0f2aac0d7f7ef42f4a4044b151f60bf8eb0980f471b1207ddfc4279b7a211ce187a6546141e462bb1100e467e4e3bf6c1419d5051080e0662027a924b803043ffcc11fc344b19e4b22416b5e8799c9fcd70a120928f3b47d2c5cb22692d1200262d089e9fa89ba2384380c6b7a09997bc5e78f67a64fa0cd4adf6ef4705c34657aedc553ec3e223758840b3b48e23425fe82a188660dc6a7537f3aa621973e4cf3b4c8db0bc7b30fce2b7884085253c20c4b24a6b5a61160b82e1f49615ca16d0cf74a0abf9ca28f5254d03d26b880cb47c5ac199d43794f7fc7f1b6a980681d080e14422f0e588fc383c025c1677c258425926a378a206a03a9019b184a86e7a3f95be325e359e613592800499304268b0d46db897716ed15d381e04d6dc96c24b6a29c5247ef8f8b71167b29d2b76581aa9b2eee1548c0027619440c062c62521ee1b0fc15a23bb985cf93dca0b4eddd369a1307f23adaa9f2cbb88cb7b49d5ffbb0309b21322e35ea347bd7cbba2ec6607a1b27b16acae3500c21b04f15550cf6220c10766531539e79ff90f866e93f8b409f31213fd1b113c20a9435c60d2e085b272627f489565d261c5f92ef81f34ec05af7b08b15c69948bae87834f90212dc1283f709d411d875068ea6473f2e1c2410e36e281455eec1c2998e75931cdcb6513f8ccb099be8bfce4de017b0131383b6fb1dbd0eea185c239c8e33dda75ba749ac362f4957b8bb5506ccf773323fc8bf08a5bb4ac4f9d1545910670040e66f88f1ed6ab8b43593bfec86c08cd9e40e1db5a043edd56aca85ea83878e71a2f4166477216e2c4e0c290b722695d773c3cddd0385644425cbd7c8c6ffb942789b01e7280354d41df25d7bdee59a18aa079b15b8e327d3c3983073ab726f2b99717a6b0ba019d10362f4d9816e1c18e406699d14159dc290c8c58957c42d6119ec41b0ae6c0283143d6d02b2b9930555a82bac728f49a1a19e5ce4d67fcae26ae80f9f4425602c60a45e5e469b8dbc8c50ef06a8383f7bf2b3703cf24cee3fe599416132ade5bcaefe2dd214a91fc3621af3f7b8d0784fc718a32e5735ed7fbae5f842f85b8d761b6c66eaa64e255058cfdc2e251cf31a6046fd2e598592705a0dbfeb1b4265f1cc5b8f01bad3011798fe658daba8ca2cd65c9497b67a9e6d71d2f2874a8f8b200ee6379d96cd5fe30c8facac73b631ba647e71406b02608636596542bc032fed518b3e5c6a9d61e91f288b8edc8a6a44483adab16a4b74e8ed5540f8ece1057c81e6360567e4a736f2aa193d26fddffa1f97d20f0fdaad1d92240769d55f95fd9beceafe0f89ee3d225ccfa5fc7b955ad3a885a3280afdc36847d61b26267c193ed4bbd723bf64dc1baaa2ba3745aee272831eedf5e40f8dc14fb053a6aac72c2355516c8ecd9c250793a6e6e0f9133422058f37a2252cd34597db00e25bcb78ccbb71cf8c9ab5e94e7c8c16a99f46bd1fd698c9030f2a5ea578bdba550e25a2c9ee8ae105d530a26230a155bd2403d4ca0635d93177f1bd55d60b4317e24151c627e0a658c3d7ac38a005bf61afcf2a0ad03fdc609e753f4ae467edfbc88d9dcd6da1669be160fbd41fcfc900756b8ef2267583f572bd253645d9643212367302e3655a4a6d9de7b5b84526a28abeb4885d895627fe5bcacb802018120968e9ace8122e1c74b5931d81799cf6ec11180995d12aeda599e79eacead0bc89c8d6a1cba2c035db699754150d9ae8b3f45e67facfcfcb06610ac49ee93b06f1bede92d7b73ced7dfa2b3357ef8dd77237f62d33827ef47e05b88752fdbf0d601b85a83c417b3b6b85fefa9003fcc38a78aa07d97ff1c3e2e56325f21c9f8ba4ddc74b0226c121c595abfcf2012e9f538968d6bdfc06a7851f07462d60534e3e4a679b23f221671b75a8c88f40ad3826d184d7da988d0fa5dc753bc53a941f7abd3678feb2cf01be3beef8cca878e6e57e34a8faa0e22d0587b3d6c9a89e38e459efee759084a10d097d63af4997df34d31e45ff4f483aef95dfa1acbe511b07024b9ea8b2a4dd94cf0077068af9ac11580c1547f79bc381365b9b609d17ee7ab8528592193e9c9895c81dd0fc5c7d83541d596e7afee17c4d20f49cbab0c24fce13c78acdac630ebde1a6b770dcad4104d73b702996d15eb1c11763392312e581be68bc72df19e05358c4292d59bafba0c3a8afd221d543400965eb8f175cd279085e51600033c0b07b4e6db96542973e8336b0bff15b47340e542b0b51308c9479272a23b9a66708a889bb37b28a1d4a1bc1edbe0dbcf02b6d1e24e2645d9b44e21000c2d74d975c6cc4e8e7b99f9b8cf95171b27402366c1035e39eeaa0e854d4831fc5cdee34bcaca9a0ee4171a67a137dd7e19aa826815a69af58804e418257266c89ca5fdd88128a57a94b504648cd605b2d21b2f894716c68a138041083c88bd4789e80d174df410a2b0c2cb8d9e01c6a0a030ed600a58661115c9b016851634065e1e7c1a18084e7f01b8b21c8f3f4cb24182021b75b398c6e8b02643a52972e9bfd047f0975430a0a1c24557087bc346a5ddb2b2dcb5a77efa717e8088f62351b7d2dae0fb0dac9ed03d82818d3204fab3678358c80c40f6a88f3822106f823939eac4855cfb9e8af3755fd94063d93a8025622e9a3508f4f7dd3c58dae396fb0a46af4b9514b710f79fdc2ccc8beff22520e222a9ca6e743c250d8de832cd2fd06898840d5fce0d13c61ffd6c682f6ab116d9b4c8c6dea6e8079277da7aae1d2bad416d508fc15285edc85c11ab8e697a10e9f71b89752087f7f4ef659158aa98fa251046e0081a7bd1e371efb5d105267cc50ca72cefeae8c5b3cf635ee3f1108c26c6a2863d3d0798ddf021292263cc283c2ab8b3926729cf54c6409a4c2465e4109390f01fc0d048ad38e9152105809291d6062fda7645cce9068a4b2ad47c14e098c7806122c3dc8b4d560b1e37dce35fb45f7b0d79f763b920264510a7ce2d14398b0fedbf709e7e83f6d62af014f07ec59fb25217befbda59452ca94523c0aa708a3087065edcf53dc8e68c762e2537d11516ca2c55741225fc59def2833d23b3bad39d36b3b1c907bfc288e00391c8e3d7140541bf7996aca44e7a7da8b95d6123f9ed6b891055f6e14a27d779f968409fbc53bbf3ead42a67fdd6e98bfcdb81d51f91bf7dca7c5b8ba3ae5438dfa2e3aaea30743681304967b4e9483ffc4f75048a060fb3fad51ac278a2011f6f1f3b9589783ffc44f28fa0fedbe5abb322c2decc76e6e19fb7123dd253e5446c90a2b46259e036b8cfdd1c4e72e41890e9be05afc4243e3d13d7af402891320ec08d1f8f47c39c21a9fe8d18bba4db4820549e83667543b557c6185aac80c184fa413dc3d7289627ac2e9726b4b9bcbad2d54b6acb9dcda52a6b565ccd52eb7b684b9fdda0532dee47bec34f72e7f92232c74db53a243b9b0ab5173ef6e284c7c508ab8b28b91fba0f41019cf07a5c9a852042bdd978b95fbc4bb0f0a13773e5543c4edad08a37167e4ad888cb9cec9451e7748b9be7ed51823ecac288106adb870b95505122efb7fd083b8d0a7193bc8c25f7613e1eb65a487eb164ac66cc4902384b091a694ecb27b3a5358e32521363da3aed5de2e3661a7cc6a1067f31c93eb9c1a657907c746ce0d1d9842398e1d4fc146f3dce09e540e1c004801eae0f1ef712e477700601574f8fc0a1c64a1f31d2ab8e7d33f2b700b2cb8b003c883413ffe420bcec3855601310c4131bc10001e5048e532c0e04331345100b848480032180dc11e44eea3c8671040d360c435f4e81f3ef8ce0057340cc063ac018783e267407ec0a31b64155147d602c53337c629e784186683bc5145462985145248218514524861a66d2c15d82fa583894c1f9f8787a2c9eb1e3f3b5ce0a0f85f0a188ec5c9a9393a5107e5a81dbb63a3de80366e0020ea985f218779a7b50a26f6b12be4380ba8de6183bd9f165c000a7a81870a861802202483e4f89e4e26d3b56dda956d18765d5bbd28dde625b7b8399157d442140090d10b3d543e628842340cd550f4c3e8fa58d10007b01d79408e820821c0101b8814b9a100468e18008703e480001d90b0922440014a16c080062c71c00320c024021298c00e14f8786852010b5ca007273e60e049067ed000101be0400782f00084481f188288a4228c384209892494882205044b4c61a289105071e2091154190109a0b05202134471458a294e8005055464d192822aacd8c245052be8c28216b8c0cb0bae80c19718c8600660b0a0410dc2d8200b2dc46c71031c7091031d743166073ce801191ffcc08b325f9801e30c9a1610d2044108435013861863ac2102194560538611cc6873061a692c1d01094970a3842530418d2638a19fd06f1a0a1d855e03e90343109154841147282191841251a4806089294c3411022a4e54198193008a68a5046e8228e21529a6a827c002e46141011559b4c02d55f32d4bd886fc2d417777775bd1dddddddd4da5bbbb9ba384f106a5f60bc64bce8b5e55528a65da663a599c1c1dd48e8d1b291c29603c54ca1c590e00e8f84ea31c5fc83c38f8860a30d5367ce20ddf5941da80281666266fb4b083ee481daf6ad406d0cf85a2392d60dbb5f3820b746b1d1ba05c89b31901d2a4a41b679a66dab1d900e5d65f613332ff92dc052b6a0b221f5361127b41a33d9a8ee9faa732472b83b11d463969bdb04cdb4c278b93a383dab191d262ef5015f1206c0ec918dbffc341f0b314aa6069b1fe594f0e1dd4ff6a2ee36e6b154eec830357d0711676e08e1b1e8e1f1e6f21870b3a1a880b52815f5881c78e56fdc0e002c7100403c0c385608001d88e3c1986888ab4e65854580118f5f0f1450d3d030d3f8450c38f159a3b006f003f803000204741840c1962830d448864453ca12dd5b394ba4193a191a431b455f7d0b04cdc336205d1111c88b6230f8703e480001d90b0922440014a16c080062c71c00320c024021298c00e14f8786852010b5ca007273e60e049067ed000101be0400782f0801050903e30041149451871841212492811450a089698c2441321a0e2c41322a832022e24e00285951298208a2b524c71022c28a0228b96145461056b8b55c10abab0a0052ef0f2822b60f02506329801182c6850833036c8420b315bdc00075ce440075d8cd9010f7a40c6075ec0a0085ea46006647cf18508cdb1b2d816038c18a0391383edc84383a6058434dd1c5010a610c2144398424dfc9e623bf280d48421c61a22905104366c8c80023350d01c121d003913f7fc0c349a8aedc81382edffbcbbd44760e25e8b065e6ec6681acd0a2a9d8d4646d82970ee354cf1e30e368acd6486baa041ee5c6ea520e9f2c6f235d628ce2bef85379bd9a5d54adbe115e5c53f4cdf8f6b24da26f4c7184f6cc4ec13a330334f57be6c6971e32736b26d45763f28658512cafd341b975b5ab0b899d4dc3b819d382eb7a8207333a939fc24b7119952ae5cfab5d60a83c08cfba05c4c3e775509238c4d0051e13b0fd14810d77bc862527d236a5871f1f9ad2c665ccf008e356e8544475c6fc4c52d2d52ae3bd6455785a19e5aa0365498397aa4cf4e9c2e4018c3aa7249154ee95300abca71992ec330f646607f3d275d6f44cf8acbe5569619780672dc2738aec7ea3e3b2b2e53f2c7872eac2e2ee97a234c2b2e535e8f1d8d6175714944f01a2b2ef38da02b2e35be3c42002b2304b0e2329f81a8c33299f4a1fe939e7b82dfa2a28c0bb9ee3694eb5d067aee131c1766c0ff897f7d6e6551e2424e759bc61d6843764d91fe94dd3397732be7c3137a9df01a400c1f12c146d7ffd3e1c3937a4f495c4ccff3fc39b21c3852e0726ee619d4727034f48fbfc66551b2aba41ccfa57fe37ce8ee4ae1f44e3a4b4f52921176e79fa42eea6ddc7823542b2e393aafa45ae5e88cf855ca49af71717c0d6c64df9f0636c2c9d179ff1e6c847a7f2336da31b271e3fd89d828f5fe436ca4bdbf0c6c44df5f888d70a4f0fe31b0d1f5fe30b0d1093e0298873fcb3dfe82d3887127fa091701ac1247204930a1a0566a092e1360516453f099939fe0b27c08085603c702614f589090729092702c0a94947494947270a8983205e553a8e8e464a95265c756b182d2d172e58a8d7a05cb0e2a055ab4dc885ab4741597e543ddc5bdeef17597cf52dc385c0e2e057fb4eed25e76aeb8145787cba2a45ae5f81c2e8b52d12ac7a37672bcc5e952dc0ff56a7f83fbc15eed6d703fa4aed665c9d1a57ca86bcf594873e2f8b5eed15ffa0bd75e749929c678f9e2f266468231cf5034b57501014b93054113c23604939a5318560c9c3172d6e8100145c64e116cb0b95146ca0838cc48a10dcf193d68e44803004b3a8ef048e092d0b95141093e4b5881092ca8b1a3099e137e9ed0c21b17a0001485202de37a8d1790787c4035040c44c490148022848c90e188212522248a9210801246517a48f101821996a0614a0d4cfc68e28660a5659c5359e28007408049042430811d28f0f1d0a40216b8400f4eb48ccbe183967100d0f15ca742c6f9acc0c20eefa7051780825ee0a182218600a4e04fc611a5e04f2bd12af858005e1768292058620a134d84808a134f88a0ca084800455f56503b366ea470a4c0a3754f0e00e878ae53c167051676783f2db80014f48206796430bcb9450a7004871c746025400903963ce0f4191309ec7003464a2d1fb8b9f1db4d12fdc6936ebcbd61c05f08cb8d885fd9f9161cc4dda37dca852663a1b12c34f6eb315ebe7801c342d73da0b6e25e63c9819959b3f206199b3669d49029c30517ebcfa8cbdfdddddddd9d7499bf9e72f9bbbbbfb02c302c333333ab847cb2242ab00e615be9ce5255f4802caa072e719d495b2439b0ddac0307edc0b6bfd690db4d9d921d28c04154c067ee8310c228a6704cdce32a9a2fbb13c99ab3b8dcaa8114174917d0e8728b0645b8df93fee17dc5bdf831e6e08bbfd09cb153c2c47b00eb470e488c50763c43a05cd931ec326474c0542cd70805764f91996e9c6526471cacb9b03f26b37151046cb9c69c1c841f23f47fef7e4ca609134e3772728c5d67047645e017795d6ebcf1c890df6fd2438c8da414575f5ff97a4bf401e243dcc2410eeab54959acb9f4db1fbebc2c1f8ad63e8dfedec55a5950d8f89dad515e91559fcbad1b68b90f74b9b54515770b28dccc371de8eb40b92dcc5ce7764424a4d5c5714bcc9bebdc0b9737c88a7f842d1417227ab3c9c4a0b91c74b985032bee31e7b8dc1203e67ab7f77b478d83f8fb0519a440aa2ccad0f70a7fe8c3a24bbf222095900fc518ad54baa63bd63ae9533af4558d7e11a5944a89e2c657e243403ec4ad2cb05cfa2a1fa297b2ec8d83e0ea79d321ae6a17841094d5482dcd02c39f2fe7f2634d94f2b672e1bb0dc05cf851cc96dbef3fe5cab9ca4dc4cdc29d392c29acfc8d83e0570eae1c00360589b0fed960c7ba62a556395f39c7ed3fe94b7903336e8c5db5eecd871caa755c6edd60cce54de320f8504628e5363948ce8d524a4ddd6990f3f92c286c57ad8cd7fbcd72754108b1aadd749765642ca5853dbb2453ec97f2ae04720f482554e444dacbffd1e3444b525c0f0b487347dccbc13df99c42b2856df3a5964035b503f24e5f52fa18770379f563f46e0722d7f8a7650fdb8a7bfc45d248c96ae40e94ae944e95546e86a43037bbc262a5e08f3cc22253e68c7497594cb9f4bdeb2aaf70b96583316ee65928ddcad1db57ae0809d10a24c47c3907351032cfab1752fade1b4bff7b1fef8b5bb9799de3811cb4e6d6af5d45f2045b2be5960dc6dcca5db7b1602952847e11222c176358d3a4fc0a89bc2f957529f8239f6582a553994c6bcddaef6a8578ac1f58967bf3bf1ecb1d813ff3594fd83bad0f5d4feb6b3ce6722b0c1bfada111f9a2c26076d075aee7cabddc964eefcde6e9821a906b71f880fcd9014e64e1b78b9f38bf8906c1e6ae69a96414dcb9cb9dda5e913c2a5dca23bc7284d9f1027de86f8a99bd3b439d1ee13d3e684c7b84f4cdf57e34ea72d08a669bf853933afebdb8260af09c9be8f9a6abc098998c9b76fcef41b8699e076e4a4e99cd414b73771bc717cb32d08f6da67dbd1d741b2efcebeb9eba536398cfbea47ffea2a3666fed5e24c6b5a58811ed01413e5cee9fe50459f7dfac81102b877840b4ac6f987534a1f86cb2d2cae5c0723c6fd54aa22eec9a3ee80b827e50f25fbd92ba5122ede5c296536b54e81e585f5da9452cab1a0f0faed7683fff53eae0ce55ee55bb4f5534e08daafaff84d92844dd5970fc446d9cca80a975b58f8e0f636248ac1e50371a39f4f5f94c300c9819babd21e54edc97d5d3f792eb7b028e2f626392882d1c19def123b42b60e5855521cf43d91cfdb0d957bf766ad1565efed343238e54a29bfc8c7952fe59194fdc589769ebfc3f81013a1c69071229d33699ce8c6f3f71a364e64e3f97bc987d8b449a3864c1931ee311714cc0dcefa8f7c1b5c8fffc8df4171450ec47fe4d300cbe571b985859bdbdb510f1c243f83d03d39c4adf622bfbf84b952c6332c1be94e029184a4c4462cdf091bcd97df44b249d3a6db1839df276bda3cc1c2ff54f087b7171fe24b0404d01be94957ca06e38cfd6753a8eb25aa6b2b40582fb96c35aefc5e235fd6cecb950f0424d279f9fd4587eb2ffec3395bb6c2723a9ceeab9f6d3297cf5cfefaca95fc971abd74f9a9fcc93ec5e41996ee7e1f405845f868ee228c165b4c1f14bffed63b56150b9f85bbc1c9411e7dc32084d424ad4391a1509facd5da54eadff35473b286b0107e26bfcae3a4a1701f66f26794905297cd1443c18f5faadcf9d32794d8f1888ca38fe75ea7b49e5a2707e97cec8a17f7c46fac335e6cc618dfb5940f7ddd13671161e57f3e777e8f13f14b3bad13c555cf8c7bfca7a9cfed946629e7d5bfae7a03fcd96ba6c8cfa4111efc5b0645973b1ebc834ec4df7fc80f0de54291d117e3050b951824b959f3a5cce93ab1b2ed48fcec7483c641d83d76cfb40de1f720fe0366725abbe1102d0684f0ad9583f87170802b9ca323f373b61c2cfc49a572b62042f8e2e020ff231c1cc44f371c7ca5435ccd8ee1cfa9efdcea36c47550413a1b0ebdd2899ac7eb1db509b9ea9fdeb41d5d1d8b8a85bf6dbc1dd58e4505251fb5e9105792caf79b45764108b18a1d14023a6522eb353ed4f62f17852173660949a9ca152ddee50b737199532a27802f01624ab36123eea233eb43a8f93fdedcf940a6853f3349082651ad421ead6d73e7a3666b076bee9c1c661b32a55cb9d7e54e3bfef9ac068ec9ba4bcb622ba0e2ffa9d477d6d3b21891af6265351f2fddf9d1e7d121ae520fe566f171fbfe8099ca02476e773c365e07e7f499b448742173a10c9062b0f445cb3dc30ac6023532154a8b95db5728ddee9ef84d9dd658c19a1be3a738863f7635375608acbf7d7f1ce2a45a6f068074c3c11d6ad78643afaeede80811a9c7361de22a653fc3d150512c122dd872a3ca22d1535229d467d53dd497caa34dedc9a5502ee59a68d7d4f515cd63e73b09f5d26aeea150dcd7739ba9d8e81e0ad555f7be26ff59d6dacecee770be1de57cd694be10beb4e3a95a735b367fe7330eca9da89ddf763cfbd5fe89fb8aaedde97c8050f66393a2db6fbbe89eceb3cefff0de8e6c7441745690c49b4ec7a262af4c4c6bf1a1ea9e6433b514c77ac2b2e2771735b8a8b999a675cfdfb2d9dd5d392742dcfabdfdc6a5dc8bcf3263af6f245703be004c8c2d17a8b9f19b4afc4c889daba8ed347d945c45944e2a421ae5a59f9383035590289ed2e264dab40cbb2a9d3242ef33d2dc4f8b31ba00763bcf19bb591da58a2851a224a1944494250c60c0922552b24cf6f5026137840d9b9f9b33f27b0c1c43e1fe17f347937f72fc1c4f1885b80f3aa137f64f277dc44925b4784594327ab9228a762178d98efab38ca9945232d71fa394f1bfa4a9926683f47edba3b289633f6a5f73627761751382fde933de8e268642713daf53e45e5fe97634619683d360acd44ef2c46d47ded532d6f485fb8af893a39856bfbed9cbec66f235b91d651188a814af54ea2b9a47ffb51d49da03afb58b36b0ee5abc4231c64b48ff753d944bb92fce8772a9ec62809121bb1fe114b1bf38a0fb5d2f2f2461506fb32baa7c0832a07bf4bd584dcc5e887fd6650fe5f6f5b25e4ffcd28e01308a561a3745d88aa395c6cd999610cab4d2ac6901618c0f333333ea6eddc52e8913ffc5baf2225fa3b5a54b860515e572cb8a375620e1dab8dcb2228d04e49417dff941b915c9106ca55ee9ec2d5a9f4143d47f7efb997ba4fec3c0ed4f0357fb8ed06c3f9675776b1d1007f5e4725cca7d41d72facbb7ee31ea9e7e8da95ea1e3dcdc37f7e06bbd65a7bba4710f3f00f226fed8038c89f763caeffd773bde32395f41246d36ae47c7811fdaf684acfe283165ddddd92eb49b9b15f642d31d68e0e6117e3ff8013c9126c7767596f42fc4a8ec749dff8f77dccd8cff31ac64d08652561fbd60c084af13d46df8a301a2d1fda783f6badcb9f3308bd5142c901751e07215142dd52615f49d9ec3efa526cdfe632bfbbfbea50f33f94d5b0af4755d5e332787c1ae93bed5093e5c6ca8ee11beef6715434040bbf37239de79ed481853e1104b67b5e73eff3bc5a236482edcdb2740005332c33d07d6ed41e8b19f7fdaa7a5b4564a78a2faab80ea154f7a520e21963bca2b9e24b177ec6ea62c3f8d0e74917fa900f35b75a539cca85ef4968ba403fd3e66651630fe33f4d340f0a960a79da55ae775f105a6e7c0f7cb9b1fbaefaac272cf4284ee461e00f7ce84a562e742c177ebee542f772e17bf630ae321ee36c5a8c93b9f08b97d951da7dbde54230fe03cf5cd8e4ce471d41da0475e94724f7e01f817bb852f7121bcdafcdf066c341f15da97b7419cc233e6c336e947fb9ac990c975b32107333aab15650abb529a77295fc073efbd713690fed522c27ece74a5bb051ec584b58772dee75cca4165d064db80ca3907ee3decc2857b99aba5f4a8d1b833495d6959b41f686d1b4051bf9922645d660facc95a8f1141b85a0723ff8aec53dfef9b5893095ffc06f0e08769e7b49b032c2cd08aadd4a1fec925a2eff6449e96616556280aa563df994cde58d0865732b6573a6cb75755576d4b5b405aa64ba5c7f0dd5cdd0cf30b165cdc2e5564bcde58dcc6c42c6483c67677bb8638dc0c297b44e02c4d3c79329db22e7e3687645ee359b8ce5048bd52ae98c7163a38d4e2952fc99a4ed0ec58db758e443cc19a498f95c02184b9c9d22180773c5dc762f952f2cd7bb7817227de7a40f37231d0f7d89bab5b1b8e7473d67cb2eb6d61d3983ed0cabc669b2093094180c2c9863e4ee6ed5e759ffea4e58f86054b9bd1db51635a82af2c117c218dddd1d0c22228721c34c187733646e8cce71e699bb9bb9023b2253e3dd9b11544fca27762c12d87e4ea3c48776debfb1f850cf2b4b5039d6f4ec4438885278ecd989789ea76b2d29e0e852db7fa91bdde779b2fb54372e71cf773a25ee39a33a9dee5379dea9fb9e3b8ca586adff719a5a299c3d4436dec7464cc2ce2733e6ab4a96a4a131be192aecf530946297314ec344c91236310e71cb4c14d7517e99f9c24d9925334997b7231ffadd7a8fb9e2559d234777f75ac685afc1771f18a3e029cc9dd2dcf3ae67f3b8634561f9f64ba11e20d189a7dd0c4057a7ee08c772cf9fa5a2cccc3ed8c8f4fe45b0ec894eff798fedeb03758fad3bd23cd868037a723d733db8e75717445e53170407f9fb1fa14990acf61f2f69aab9b45d79cd79a2277a4549a21a106472e8e189f3129929e5cae529e54a1931aebf895de5dafe4780c8a187276f5469ee948b0a35ec2302cb5f51d1f5ce7eebfcea7d32f016d71f462124ece7d3f3952af9101346abf40b7abd564a6917f97cb116f910d38339843c7a0ee20ec51d6b0adbb293526ef29913929d2a899da5bcb85e3ce54f869e4fe4397dbab8945239797a2a2166201f8265b8289382cb5b9830f163849a7bde5354944a3d915ed11b1b7f138a5d51ec585258f86e03301cc4ff15c5186311243abd3f139692253f64ed7f4884d3edf0f323e7b33380af4e5d11ec3e5bbb2bc910d6f45f9189cbb8afdff00471f8b13ad129d573ba2212767efc4f55244463918fa2d83cc4bfaeabe3a95254ae01f7a98a688c53462923b389453ec4c4b8431928ae7f13242c8a6c9511c5e5cd8875cf51cf413efee3ef233920f958c7ba627daa7c4f0868832f61e79384085b31ee9a14beccde639447f85431d5c7f3e9d8f15c9d93be4edce973d93d662963f4587d3c959452caffe165a65cf72d3818dccbab1284e4a0a49fa5c43d96eea9ee9ebd550e328ae87a20d5452f0b049f065524d4834a390f940a9539e2fafb1853bb0951453da8d417ad712b3d41c4a16395c04638e79c4b605b9952df29331b80aeb08f5fbd955e58a7823ffe49a2d8cfbb8ebd8f0ff1cb6a3ca0254cbc4d13ae5fd1a245e624b96359b17cf9e38c400850e488b330aec87ffc85dcf3674ee59e6bdc1b9e20cf3789124044d8f56c54dfdf8b1c4b8a4d5deeee3ea64d17646ec692ddf441799612967ee5e7a17a141eeacf9014e6f2466486a430b72af177736be456838dfa421974b9bc1db106846af500c95fb8dce2011437839ae476b07433ceda217734753c436e04f262e9faab6af42d7ee0c67f80e5eeb8dcf2c19b9bc12ffe72cb0b32378b5e70d1a54b9bfb35e936b7dfb57817d6076cffe75a7ccbe5f72e4dd82f4e2fae0cd16edf762d2e771b27e223dcd47b4ec4457c84b564871e804072a24652b25d88380c174ec4ab5eb16d354ec4aba1197ba9975a3e1873b9e5831fdcc8237fdeebc6f72851cc8deec1cf9522d1afe2f73c07bc1db17bdf37841d1a3f208343c4602000ca2abe07e41721bb236a58c58f9d97e168180630702c0775b95f45438ba7804695fbf95c5f22f6b773613f1f1f59398efbe2653494ce50e38c24589c33da58912589820504aba5a1461a6cd2e0220d354a80b9dc5ada72f9270ab6cb4b562eb796a2b4968cb848b7bb274b6ba29a34b260c21299d61217b12394d72769c27e7f61c5b086dafb86035d9d3a4e02c6c6ac6e47a688e2b6ed356d9ab8be04a8dc4aa3cb850fc487e085ef03f9d23c9691b19f5efe151c9ced5fb290ac94ffe33f0bfbd9af916223751f0aa9a56c257924b1797d2abef53edac7e1e82a7b4884f3f17ddcb3a6d495917e0e959476f28d9cba7aa40713998d8c543271d763f527f625fbb81d65a7e7e1f4f5a1dcbb99fe64dafe8743b91bd744bb1af692fbe2c5b0a65734c7b06c74557da87e29954ad571145c75045ada49d5a7bad98bb1f25550553fd6eef3b9b1bbdc68b2f199ae549068fba8baee36fbfe53ffc9f66f9dbf09a849d1adcfded51d94201167dd97ba6654ddca5d5125d458b6dcaeb75653955feb51cd5e5a94f63146a2ede337e5549c5011e783fb01846b2c9c962b5bd84f75e3f5ad71f2b3abd3aefd54d7cf29e5c569421f5fcaed88f60ca369f9786b9675550bebdf31661fb318b32cd33ecbb2aca35cedb3e74cebaa9c73c624a212c05cfe0a26f3b9f5596e46b65cfe5a69965db0fb9a702c232c7fecaa7b5d4a8cfd2258ab7bddbe3dff44712519748fbede936aeebe94849ef5ad9dc791b3289fd232834ccb8c302d23bc699911838b32a30b904a08853d8544ff6fafae2b0b7e112452e23f6bb0ee086f15fe0ad2ee887b9e83ec6243c805d2ffb4083f6ef121a7b917bb3ab3389d4b7dd5a39c5dbc4788f4b31e366a89040c4be1f3b8d7eaee5eab76bdf5a18c62f36bcff46bd60e769e3544835dff4fe7f2e3708fda3cfcb95db3dd4393753ee59ab3eee508e217763aaebfec083fdf12df79c0a6cd15badc62f3e5c296b07f7e7777c38673567864999b63ec7a1c0885f2fee1202f63256197883eeef57ccfd1bbe7908503fb7940a7cbad32902e65736b1791bb330c1601a9423823572ece192b2402af1aa5912f11423aa9a6c14cdb7cc82e6da331a31f33396146b76b72d94308b16cced7306d42fa7dc950c3b742ad290c321c6ce4a4ef0f7db31c1cfbbcca3c835083518317195e56fc55bb24a49ad62fb36e6d4bc2d1f94cea70d1360d07c7b4e570bdc2d1bec2cdc87cedb7ed08d32c9764250ec5915cb6aa5d7203d772260d425b5b9374c3de725cb4cf3296a7cf20a52729a5849a9c9993769363583e8f9a1932a640876e620e8a7c5b6604e152de8a301a4398d053caece5f3cc5935ec79ce096bcdfea259f6db963d9daeb1919cd3dfdd1d7b7f8bbae68c5a4f9896194bad36517cf021fe93ca90c8f473053f8bb3e766e2920c61fba92657b3c2caf18d70b571eefd3cdd52e37c55b91faa93209090eefc0cfb1863166346b15a63fc4b8b3b3c7ff68fbe63c3648d509ae62c634a3aa1cf197c84db9c53b66f493e80c4fdd853fad867708bd9a454831af614fb264a32fde9f97bb6e7b4215857631acb5e5c6ead41739bcb89c35efb3038047b0abbc8be6d1a36b32bc3ae8d085b6eb669b03d4268ba780539be58d59c4ef1905e50421861952cd7684139b6947f754f3cca2db6d4e5d61a2b2284f08a18ac5032817d4c35c3a9e3e3726b8c18ccedb30d334d88a3414ec88718ab3a279c2236ca79fe2cc7b669db86e8689487d26d6bea58f6a72d08fc4a397a21d7db910ef76d43e089833ce250ceaab1391cce5604fb8ad2205151cab144b9fe3eb26d0874c2c97b62a31ffcc2ce4934717d71b86ffbd8691bf6d84664767f6d43b6c7ba7a63831dca360f7f24616c198665db35b559449bbf991e87633f86126e864383edc48dd47bbd8665d01405cb46ad3524e0d71ac22c6a36301a174a230dbb2f8e20631f9ab3bbbd7bce88cd39d9486eddd9166476cf0c83700bd2d30629bbc8503cddf0aa713a1b49385b62b05ef36343cb417eb5d7007e2739c2f67fd508d6c6e5d61827b8f273ae846468854fe2ad446a67690e62bcb623b91dc9ae49ece05308a57cdf88c0cedec0f6a0e8864af55c6e89e1844bd95c88411869e59cf01a3c4468652466d8ed726b8c272084ee268a453b94b4625a0af1290ffdd33bfbf4e509de74a7a57ad8d8d850421e4c1c180f9a8c953b1e20c35aa7949473c26bb44941869367fd7ee63b84d0c884df04085144e647973eb8f02bb492b14fd6f974f4714f6add2fa3277d8851e64aa02b9fa5fc232c5b542ac6ca041b3b289d88c3547e3ce588ddd2de2823e47c8050cee884d7a8dd171f12911f7b3694924908a3cb009f7f4c2b05c1e48afc274ef42bd94945a25cf947c0f0405b9b4afdab52f0c73d69d43de0f758d30fb6938ea2e69edc8e628e9be220a97dd6198fd1f552fba9695ac742826bac23408db5c44a8385c6d45867d0ab6aac369e0f7d9fcfdc92dc832c33b4ad792034693e1435356b52da8d6d07f774349611688f0f7d9aa799eefb5cdf6fb31b548c256e8669362eb7c458737b333279a0afcdd7beb71b7ce8cb5ed334fa3cb3be48c0b0383456193c2936caee4b26d8e556186a6ec6a3b1d8d81c3945b05f275df92c326edc27eee343f0777820276ae23fdb11ec9810c1668fd26183b5c6cacbad30c6dcec7568ac3174682c3152ac3052e034969a1e6f3b8a8fc48cc5fee335dc0a63cb95bf830f452972248b0b39ec722b0c301772f3662b68ac21642c682c21743b3456106cf63e9ef63ec405befc1ecab3e6887b140182837b30611e6c045f8ec1410e3cdd0a894e9d0770fe64bb2070de1289d97b2d6856c3c230c2cd80741a4ee9384ca6fa1ad7c3419dbd077072c0e9b8cc3f7d920f653e3465b605d13a7a4d3e64ff646ad334fd66d73604727390bb7f0d73a4d8a8e7663d39b62326489260b31c5a8a8d725cf97c51975b613ce142274799cf76581d42d3fc2c3a8cd034bb76596c27516cc4f76797e5f431015c603f16a6aea8d46c1aa872e814c9080000004315000020100a070422a16030cd43796e0f14800d859644644e9e0724490ec32016860c83060800800800000844d33612dc812e86c086694ab98f852db23941376fac464705ba095040d5b851e52c5242ec9a7aa39dbd70a6c3be4eb3698018e82da4857ab1ec77303819924c419e13c4fb8041e206c1abb44b59eeace894f59d2e91f51514aee42be8e048b0c3be04f3daf2830ebe38645f05a5575e852fa975e13361820a14735fd0ebb4ceb60cb4d49f661242b3d77a8b3a8d7434da7078cc15a165026eef548583ebbde6bb6418f8344bc3b3a6252497cfaa01011aedb12cb9e94120d997f392a234f738544f467ef8f571e954dea3f046d6a15e9409c63d89bdcc9eaae08aa30360b751bd090122b5ac066d23c3695af2f172e08c843cd304d66d037c61827a077bfe0441d002ede5267b676e42fade4717deaeaa37025b5d9ce48772a07655ff10c25b0d6fd4454bc6a78bd077c6365e16efb4c6e060272b6b63eb589edd26533f20774244bfaecf825bce795dcd5883e30005fd0ec8ab4148427a2b7387f34700a340e9ab24fe7ec1d5543f90379c672e10d313be7e9d128d06f5e413901bd8523c86369eee56464507d7e5c782676d31e02403cfacdb78434f2d8126657078383dc3052b9b35833a31bed312c0f25780721416d5defc8019f2545d3d3af75c636b0de0062381e065fff8b215416bb492ad50d4e8da7e3c522ee24567a8ed8f864eff783652302060c48d4811844d83a97d92c7ec6f6868a53b880835572cfc41355b21ab5f8f1c7f1f4bbbc3507f15827c432873c83e8b411cf67151316533b1bb5776e0e87d7a8ff485b15aa29d561584fcde6f8f3e99a683e7b175249474fd02ec2352f7f9d2e9d5362024dba136ab9c7e88a624bf61d1d00c4cea29efc620f2ec42e0f1c71c68d09b5c3554b7a699283993f85484f2a5d82ba5951b55823f96ced225cfcf6022300533bf1c65d65aa0afa42162430f0a97c1952de4a4fb7ac8fd4583af030b300d4fd65a4f4eb6c1c6e6cadcc222e30f2113c3b278f725f8b5c480663e796d9ea27a38b9e48e95ebc24f4772b91af245b49765701bcbf5e0aed2da26c0f074556265fe15f94122d1cd8c500b3c78d0e1a0407212ed26db7561fb1532d55692447601856d278dd8953139f8732c3212dde20c7b0a06c124d08f87f34741e1f26a0e70ab4953e6b876f2976013a71e371a241e9db8aee387fc74f4874bd8d0e603736dfdc9b3c6a7b05016fe65d388a00ef711f8e6cb019e8d2b755eeaaadba78d7ef2f969335a3be22abaaee1735f8f30de20b1df3f949276db6f2dd5913b7e1616116bc798e241c0944841ceb9f26b1ff7fff4041d12820d7bb045ab877d368891745f65a1f3c4168b979b671b15de8933d8324d105d102aac6c58cdb51eeaf92739784ac4c4944ae544ed32343e2164eec9e3691b271a910249de0ba866560501f034493fd70f4b16120ad21aa4b9c15822699684b4d1eff1b306c01035dd2c96c035d63e260d58f42ba8494470239155847e0ef1a6d451ad282a2c288ddba9b6872e4a81e43494bf2b188289980857aab6abba9c9dd910c23ca68359953e23a14f69ba34e8239ee36ab144a8cf0120b5570e42d40ed05c5010611a42144277c482557c3e5a36c84cf0cca4e2d84eae57820a8a7c1ae48841f9c49f742c4a011d7397d5c3c378781d99ed57a9770fe47eda7bad8763ad9de8a330e653630c77211308ead976a547cc88a44658207d1b5ec525e00efdf1ee61c57dbb4320ab9171525d9da613c8701d733209054fb77e29215d60872d027c5d19f6aefbf2ce879acd7578a28a2f8525b5e34125541d4020af429868012515b8ce137a43e847516a693f89bbe5970fedc0eb47675c6bc3105e03e2c4597cae0d628e4aabf07b251b772acdd4c00cb66c0d5a0a18b97ebe289c248e21d41bb9c74f6707df38495ca53d3f2bf3b4ca3976a5f013434d1b38e6ed8a92f584d4bc319dc844e6d27db8d38ce3999910fe4470b385813582682667001edd045c17ba0cb7c002c869f22fd14bfa62a0085089a74aa99e9077daf63f1e7f61d3f291a3e991a26824f3daf2483c30200d3a7301147a977b447294a56da73869fee73d00fe5d718e2b16801644d2074cbcab3a4199f634f37510d004860b0bde6cbfabb51982cb945ab56d265438ab724ff1e796a03a300be5da5bd8dcaa4fd8b4df459a1a191c4356ab8128ec5def547355115e91211c8f9aafde37c83a75d114c4b7e43d4553cf2320ba9620a567fb0923cf3f018e3f85388f26e80334e39b14dbd27342503406c188166436b848e58241ca8ea33ba28f3c967148187750f77339129df1415aff44b0fad44d92cbe5aa365836604976125c8c680644dc18390f4661c63129ee2da7820445d2676ebefa8419358f7e3503449addd3ba5fb6027f253bf26487ba60e3fb57a5aa75fab4dc67c403a5f190aadc85e8e6e7d754d87d80804a1bea9d0d98c2824ba9f9f773de903730ba6ef0425d55ed75002889283e4b13feae70f6b13f1fb1d6f329ae30cf773db2b358a6f95198cbe95c47ce4c5b338400700168885ae4086026707a37053d36058025c0c73ad0d437136ea0c87cd6ea45cf2a4b7a4fdef4f0d426158b8e7445ed771d21ee015c04843f37c42b14df2dc22ca6c45f6bbaeb28686b8e4452326369e393906338bdeca2fb07f9e7365836c2792d7132838371b90f742e58a14e75cbccd011457f2c0b5f1445074ccfdac682084a54c776906921e7e9b755a46b10b23be13c0f248b7d33e1da9867c495ffe808801b562f73c4a4c7a6457a3e4990398f2b775318666dc14f31ec2d07514a24918a05a137b49b020ec80f925f7b4074e00461b81eeefb5e9acfefb10e7d810da758978cf868a2c7e15ed9c45cb24929d41385a854864a236884631111c136e419e1d3f3d2313b176675ae96fae48cb2ca1b4c67c5f76b1377fd9bb7abd7ae013c4bf915c301184a77726495c49ebeadab10afc91ceb9461849de3c709761479b02207a10e8452dcfd7f0d6c2a9da3794597483217b363e06b2d5f07f6d48fd626dfbc070920a473e43ec66bf7c268ca362d05801718437310971f8c9b3f0d0a976fb0e7742041eb4a57a55cf492166a9334ae76e91ce007a039aea9b3c3e5486f6a78db58dc1c75200c397b0495cc43308732c622ae4c58251f046b38eabf1e4b0debed4b7c51164f91eaec6cf372ed18b1015ef2de7e22df8cc61beacf42804a9cc8bf8032a917cd77a263a6ef40601d05e91ad031a3a650cca8f6d438ec85a69b8db46c59ec51eba214887245a3a5653048f2b928bbcc0584c32993b27858870aeba030c365028a7002890dc51a09656f0715ae4c49e14fb779695f39b8d8f0c0d4441024dbbd5fe57aa67c58265321d9b991ac42c360a2feca4ba2dc1f2464c80b6903d874e28b67eac603f43f98cfc584b0330a40971942c98f50fe6eaac9188de07a8789035fa818f6e09fe314e541a2846bf51105a2245a84ce74494774891bc0fe460af1be5e43c2e4c1f923a1313842ef89ed1afec0ab3e91278e3fcd6ed8d181274f5a7e516f8f49dc16c11a5e2232c715374258793d1d39d9ab9f8a3bfb03b76547471ae2a2a449ae2efd17e5166158829c09418dec527db721c215426aeb25f99f47f1b4a71f9c8779c9f05e5bc8e19120972438151f56f3f7198514743b35c63ab38ab9be64c4e76d5972f729f2e51179489e16d9035e93c537a81f137eb0253bd1ff8191ef8c98d487dca025e0fc7dd225bda045b5f658e78f3980c6a26c3226a8be7ca0b3c8c31156ecc19ea29e74c97f9aeab5c99c09a41ea60c8f4638ffc3b7f4c648b07294ded1bff5d677ea686dc14b556952957a188c7660a8390dcb4f47401ffaa87a5439c9029171a7a06e934cfce3771fcc98437e4e969e95fa3efcfb4e7014ef78bbe0891e44df6f482e806a1362d4e8ddb02599c820b5ed0590eb9f4470d4af1200c0594e62bd013c62824050df3eea61860412c3d5cbb6e6be75a2fdc22a9f09da1b2c39195e6a76ec36a2e69cc4b917055aa2b64c1ee86be36bbbc800a120d805e5b43adbb60227a6003dc605662a0a9f6c4d71c83b2fcdc4d63e494922ae23bd947e14e181b8bca28ee3a9537ce2bceb4868043d2032dd531663aae33f6fbd02f426c3d142ac86c8653d17cd5adde09b2b45756a757843dd0ca5b1cd112f058abc9c4f01d12b6f46a0ec61c969f4846812c4f05002023b282ad37980675063b5be00c2267007411ea23c225fe648425da787d5ddd24add73882c06cb56ad5c87548e00a5d46f5ce1f1055b2924a4949ebf83fd6f298c0515f658d3046c370cf1477caf866dd884cd8f89c52d75ee033d680fe1e050e226bf47c04c6def9c11a830857d9bca48aaaa49570ec9cf87d8e41ef5510273155fb378a59c9d613b85ab6f65fa04144186bb552d1bed52b015ca468bfa572dfdaa573c2c1f9bec698a10c3440c12095f4292114d2e1bedc8c15917ddfd0a2f346e7c1a103973a8021e4941b70803b62e0b028058d1f46eb25a32928ce25e816f68eb167900be53f830f747f2c58a7f59e4c3c76b51e026a310faf8145e4562e4b989c0b9a525d8c31c4cb17d45ac88213445a7af1452218d59f6d8b7880f0bf69af24f459f28f25d6bf9677dd04cc6f132d9920c11b1dded924400d574150d0c42443ce7f3a9846a277bb2831d6895f77fd3216ee81ded95d5055b46b2897a7a0fed828813354f4b95c512d88957870bbdb4d99340cd00f8e8618a881374254c05e5b688920a74a5600a76eefe4aa3b0f914d38932d8600619052510b1ad540e502b9f740c220a081f13301e80816f9e394263130d8eae64eb5eaab694ea76c34275d9500f93ff5c4eac7f3ce1203ab30ba718b29e016de95c5533a1dcb1970b468af10b56249414ab51b8b65c9255dc9cb68ca5e89a654b694f30b80de347b5acc761f9b4864705c85b4b5af3d29c57e62d66417671a1713084aefb6aa140bc6b6b825a012a15bf4480f34299efd965218d4e87784c60e280230170dca481f0f7d27b26de497a370368d08a980310edf5dad0523514b9bd7ed6ddaadf041ba01353d489067275be6eace19d28f33ff09ab59e2d1d8ff6660d4f3a1390327053ba17e683e42dc8c71e3d3880ecb8581ba34b0b01a96086ca87b71d81a6ff54287485528a18fe08e323e41988a8395c3c4c057733dc03863eb6c006c2c608a1baa778b8607d2aaf4042fc740e6f318eafbb1aef4bbd6a9c2a227b6c33d2099b191f23cca56ae16ef113016cafd7bb8d152c46613625446ca1c0bf1cd56e7962f4a6cfc0c80d75fb5a6ba8e306a85f446a9b8db83d166ca3a3afa7cf5f3a933613c5c545ae8508098ce4517d375c518a1c30ed75041dbb20f4c3a35c06b9f38f1fc5ed45cc87fb00fd3f38825595f74c67d253dafff80a563d85c3522c35b458acb3833128871631eb656f8e66e416e5a538dd47837698be5b6fc5097ee01920f7fedb0ff3812bc290e7ee5d42cd5a69904612ca4b5540b09f2509d84319f00e4a98d50cb326da46f8a818dbdc71ca7a782746f6565f4ab989df47b5435adcf0221cdede56633285166149c2e934141342c73cad36e817966995225270f134a849ea7285b99ed3b25b710a4ccd45b75dad2211309b8288a266547c28c19e86c18baf4bf5eda0d40c56bc1128ad74a69015cf5df7dd8317efd5e42bc9bd240bcfbe9d3aacbbb1248272d2381db5d58ec5d380ffb12e6338afa50f36816dac641c1e1db62d4f9b27869b91b06615f9018453d0150c20581dfe10cda857dc1ed03fc5d419d6b328f04c1cba4c0309301335a97ffbe9cba91a115e8ce4ce7e93e8893fe53ce5953286446f6fd4818ed50809def633e9df59b2bc92f2c230b36451e5aa23278c41a8ad9b345ef1d0fbfb733ddbabbf8f2f81f19fa22e29c1fcd17ec0ffd9955fa8c315a4a15daa8723f9f3d05d8a7076bccae41ff00288a10a718c804434ca699d1b1a16857ed65bf7a62d84d9e163cc1cdae5c9b86f292895a2887c63dc7b7411edbc2c90a19a56b23f9810023476dcdcba21d34afe3bf5ef4e6b0665e33ddfde948d32203c40cd79ec332f8d67ee21d143824c48197f1182b176a9d3e39dbc381ab124e3e1b5638ec26c4fb0763a5b990f7f80a57b5668269d3273fa6fe3911a86a57464cec7da6c91d0a4007c65ac1267d7c4d051d3638ff46bd4255f6b0063964c2db91e62806539d3eac9548008b861f4b7857174805521a435ecd208bd1e90de3ba0a6b7a1ee22920a2720f19b409516263b6688f6ec9b1b6230d0c449422fbe0f62b0272f6eedbf6eb7aa2b462fae7f3811c57288c4d8fb52db6f1900f9808248fd537b89633a6a7b4ceea0be9d2ee69b9442f0a71fe41204021ff0100edb47d8e61576ff15ce04e8d6d0d630814c591a5553f99eab7de0b8561ad1f0b6856bb33c39879d5bdb0c5c42e681160ba987abf36e53fb84e0ee8cb3cab1589adb9a7c05995b04b28245d47e01b0e9019a29c3bfc21b00c4e0abb40c484f7b251ac32301361bfdc9a2a6008683fd3f17f2bbe54fbcf2e546dffc61ffeed68bcd2c3d3c7479bef51796de36db28068983120bfe777d07e11956285f26ad0a643ccd7f028cc7ee957afe574c04b7eb06b15f044d13284d49273cd3d1258666e333280fd70659d19c996224c2a6e621896d0f1e2d9e811555bec5951baa2ce91a27e3edb7e116ff0da0a40188c6fa42e04edf100e9908c5404552d65c83e9d56ecb942dbe91b22f50ac0ff0d5554ba022b85f9c1cebcd61beeae17e56acf71516d68072ede173700d786d1cfc139b5173a8b60dc4f82b6568c61d6883e0314ceba6d839c6950d378260def4443f3563d306cebecf309f6bdb00493907ac23964a69e096259454593056862bc788fccdfd4814d0c42dd97e781b8021145cce3392bb8e7cd2031a6ff6d047cae1b419a9e20765000fca89317219e018b92046ad441e0f2c837dba71bcb6a8deceff546ff9c1782461d84eb337f29da129624c43d5a1344104d11737fa187cdd48f2735fda5faf2a1423d12a992a94b67f7a28b2ccb65801665ec63325405a7645c134160615481762a4bf318b5440204a7cfcde6e8a80404020ecc88db70f5b503857bf901195301298bb3b49bb3fd5c0012453302a18a637d80444911dfd1e348024a0fc028219e7614691523c9b5e83e4315bf7bf420bc04d1bf26ecc04fd79affbe3767ee605c7008057ee0cfbac35b720cce5bd33724dd509717818969686c9a48a6ae7b4d96b6637eb99e1a59c63ab7e98feb2e86252af79c1e3dcd2072f7d6a12c52289d2ffce47181dc35ae60a50d8b5f98a58402fc8e5324889d2bf820631623c3586985bf3508ca81b7df0848e04de97dcd5f80e92895b51cdbcc0e2ae8c477d4e8f0717d1fec88972e29063171216f87382f7024b3f5de25a3f5097c5fca96161e9d5c1bc9a8dc07a9529c277aab7b20c3621361c1a9370ef0b5d9d6760e0fcb6d10ecbca3d80a24f06118ca6e34aed17bd38319876eccc981c1b96a1ba1d9b9653006108e3a60d368785c05442ce9b97748ac0ba0167d16339fd9a24a1f45160341587785bb9b03236295a58267d075c398c01a074be62de63ab462006f870f729b26053497c70c41117b434aa4f376211da14d730a2d35467f744efdb772b62bed359096d22e91b7efcad4ff3510c321436e8d0cd319a158307d2b30ed3026203c1fca30935494bdb05aedd97912d823c80f49bf08dc5bd17e9bd482f8b7b2dd27bd1f44620592f82bc41e076f69e6ad84696f700ae469ec9b2b112e585bb8f1e3dcfac9ec1d9376464701ef1d16f7cf076e1303b279bf0108631646173980659d8f859ae10c8303d172f90f5b96acae6be165a5f36a57ffee4b43402d5047bbf88348f7031ba868620df0828b470edbb0778fbd3cba1244c2c7d6315973f7c6d10106d023716ad5741dc7bdf50e19f46513fb1caeda3c0c05994a85697980ef74b15f9a97ac8eb9e33d5598f7bd220404bfcd2a3db773f5657d61f538c55b1f8271c34f8e5f39eee5ca5fda91f4b60b609b4e46fd20060a80c6a22eb6307dd3e96d9a0d026eb1121ac0e2a22981b09064c9ba7f45043dc39aa30fec9d4eafb0cfbabb3d9dc3f6799e234239244ba9d9ef9d76e203b246a24eb0303facfdbeb58c4013bc0ce46fffd5d102958d9459cbead7712562bc8d75f1c4d8947ebd130813618f7120323864f3de8fbf0e7c5b514d71fe965d2b6b896541cacaa5c5c755831ed0f640c6305b329b25abb10978acbed53650785a0a0184b17d862a98c4e7745ff68c30ef7058fd3ef7359ed52413df9fd599cbd13ef45feccb5c9b26be0c3d39d0152ad7e3240c2c2a7f19b56d8202f00e5eec53c45e078decbeb41cefe492b0b214a29eab68cc2a24caef8de8cd855341db8b548ce4012c4f7d4e2ccae9a751671c31ba75dec84b08a18bc29e931bd8beff692d41636c1cdc57a2fd6dbe2de8bf65e84bd17483e0da16e00b512a93100078209c37ac554b3747d7f96a10072f0877073819d00d0d9c1a6a6147699f26dfa96feffb67ffc13651001d358129c6711b766caaac69168839c1fe8091b875b34e17d5e1a77d61f71960e19c444845909b5a01d8e7866454b67b91f2fad72c0eb46a2bff448337bdacd1ce589c24ea66a2a4044acfbdad6d7cb9ee5f1afb5e346d4deab12cc5dd19251715cfa01e143b8fb6a7feb4ac9dfe23b5fd10cb8fdcf755db74233b3936b6947bc0b6211a8549a683970e7f5ef7d463cf0f6f203fd82d22c6951306d1227453f2a6acd6a072701b00354d3946e341a6471ce5a02c638390118a106c8c58c13595c8296463b0f99165f152f5c3cc91ac03af1c3e9c0d68d9979af2d44dbf2d54e00b4b8934a00e7d7e69ee0934547e9548b5ec23668c2d9528170810c4a4a50ead1dcd2de8f478180260191466036cc032813d47721a27965276ac7fcfe9d533ceac4773254144bada95b6defba612d5acbdba1686ed2e540ddea5aaf98c6ba07e9029e139f98bbab1940602b962fb48fa9fc4558c46bb50fe50561485699a920fc6d0c52ba3f4b749b519213432e2ce97e1ae1af1eee56f50d0ef88f3892a5ede72e7ef8e64c01085c08cdee0a788af9f6f43d7bec9802ddba4bdadb86a173895c160c3f74be1f196e0e6c7cc6bef43dd98ba71c2cc9912af860de6db5f7c130c6d091c3994eb49c4cb0f827c7f82de81bcee76274e4736e9c70982b5c63491617083482f2344db18a4392b9c58a56ca00978c8165f55f9daa3298fd748a6d2fcbd6aea1178532221e78f0ac3fcaa02c39929e232ed91c10ddb4812ace00e47aff381a792c4182b7a028d156f7c75a68f0c1482ba9bf8fe1bc874f10691f04840985cdec19715f230f0dfdb473d6f61521d743ba4a8122cce9407ecf708e1438b394260ad21b678dcf76e607afde52f8aea64d6e4ac8a47d84db5c0155660e663928c8135e76fb06699a213ae6a6b927824cac0fee0864e81cbb0a916d8586b2f6614103edcebdc6c98c916d7b81f281060143c00ce50c0a28b8da368270741a250a94b113544968a5770b6c582fbe16520522b5fccf82a26c855c880f2038ca5ed0b2657bd373f42ce226ef2f96a95edaf00c4a029362800f5b666dc043566f7c27a169dff14d0456ef06a5abf36bb2434fd587095e4eb7f99a2ed51778c5eca37a070c3dff26ef0f4c31c468ec7b596fc00940c172f6274d4a82615f46ef949c261f56fa72f137e15213a751fbb6e086b1894c4b74cb1569a5ca5589286937de180a39192acee9e67402ed82962303ba3bd3ce2a066c198f387ceb7c91d52f06c38dceafcb2072944afa19c4dbbe5ce348d5f784974ed7ec59a1ad6aa7dcba31d6af975438de2c9c74e3a02db49557dddf4237633fbf72652d540ea6440f3698b23cc4079870622736d12762a2133951133d11133fb113c3f37389acf99a92fc554125ba76c95739052476bde00c1652f066417e5f1c8321bffeca24c04a05396a2ee8aaeaab17c92e748b5128ba10d8e2a3b56717ba961e55fcc9e1135c149cd289c513aa00adf767f0fca78f6db10f6ce64df83cf4d0edfffee443d89fdc2161a28586eca74e48c01f7b38dab53299ff9014b501aeee837fa49b7ea46b5ba1cda42973fff1c666492413f00f3524c5d3e94a3d97127783c86c4a85ec5b05f460b471ee19a29ee1696b7ca2a6141620def034aec59d4c202e3010d172cdf868205ed8951ea8709ed19c464318c52bdefc19289f6002f91468160e5e3983fd7009ae840ea256e4e4aa6db8d820b4cfb5341112acade6d2d85103dd5937457bd73d6b13829248a10d615c983ae39bc153461bd16ec6a736b06432b14ee4731089549ec0b08fd87130616f6e536ddf472d62bf5499e526816ebdc9077144d5e18d10909fcc308b0ce64d848944f9a5d4a2a7632234762d4523d5b0bf092a530cff673c33742eb948c62ba5d41542d759458d558c7c6ec500d50157516658ebcc666451b2cfeb385123b40fb4038b8323ece9238ba214ea7537ea216276622831129f6b3a5ce7f38821f69e340bb4779fa69c4305872ca4ae65168a5fb4111a714a1f6c84b443511eb3fbd7d41c64a0460453b5c82cf5c7616aa56a2562815bc6320f916bbc430c0e36fe79a6017f689343581bcc391ea238637176dc47ca9e55680e70dfc13bc4710965b3d6f11047bf9eb8edf7bcbc08de23a775e5c3e34ec3d5e473e057e11d259cff5d03964bd9f67604bf35dc9de6841f9d68e8874f83a3d4284a00c41ccd05bb82c03a0f65b5a3b90e57ccf36f3eb33d353ff2108a5f3e3308a638ced21b859f6f26205b93f4de62c79b9a5c09ed7f44fbadcac1605a0b77a6122965df368d02012cc0ba457c1b26c960ca100040dc599699476ef787c8b41c7298080fbfbb3d534acfc4ab40132e13df095522a837355f8f37362e88e2b47a09b66da8526d45095ee0ed537147585ca681472175e419be9eb43b4e97f40f7226da7caf72144a516a3c0fa7d1f18562cec090d5151d7c2c47e98a04f766c936c82fb3590fa065b2f34f6f6cd3ec4945fc96a50b80c56b7677fa7b5d8ff83b0892fc65166f3f3ef891847b6995a0ee4888648365f17c2937c9cf1a6854db3b0ca313c0d51acec610403aa62fa3ff29d7dcf611420ff428dfcf6e13b25f856aa62a30ff4989bb08a201faa62ab8926f62c4299beb46c838ffdea8677ab6ea80a87d3d4ae86ea1cf490a71ac97747374ffd63e2c347580aee29c41cd76c17f48be50721944c949cd4fe268943958caea1d59a4957dd3be5c7f0b95512a3c7e65013024c85144c5dbf33e001ac97b6b8ea38808f2a47cba0428a904540dbef568b676a68ad1aab5ece34e01093f8d474853c9279a98673672d0578c50040d434f95776e5374ec8c1806da47171940972648fdf9502dea31783d20a000f6803376050137e287840b3391a2556db8734a5b32f0d9bbcd0df8d1cd3e8767caf20bf6f6e15f0204eb5b7755fbae546e02ca22f43a3b5f752ce0422bff18de13b2e0b29a9c196815b8095e0532577d981230407e5bf03bdc605b5da7abef1302b2200b33cef4cbb0bd793d85b6388a9cd670a4047455ff4e707731b29b25e016da18e8cf38fa674ed936cfd3fda91884d102266a4654af1556d8f471a46b530b071df7fd7849e4719ff861ac5eb450d2aab0b0566bb0f57aff3600b9a7748ca93e7483751fba32c40ccda929355e2dc54dbe5879a9cadebe58ac9ae006c7be0de4bddac2b0315f682b726108070f873e596f1c60df022d85001561fa780b84ad6c1a8ade6e1c8138503656f69ad21d286b6d0e11f3a4ce0a8705ee6c5463821e4b04818b8424d6d645c1400beef28f3290036b66d291e31407ea4f665f0908cf8a478ba062e170b930697ed3baf14839b33901be26b0d2d7ea222e6616227761816c1631674dd25109506640ef696d2c01a8c18da882dee8cc4fa97f07998c8ebf0be1fc6500c27ead4815244d8c40060316fb458ecabaab1ee1b97b20ed9f506caa91178d1443cc2c544d94074e19c123e9cda182c6b30b97a03960551f9789bbc7aa38b4c472db9c0f4f277683df5ecb924d9dd0223ce41cd2dfe95807c0ce9354fcd5031e876429a55691fb9ac1a31e1d6796a20202378366fde984065db56834ccf65b1906e59583cc9f3c591d433a97df6310c3cd7f86c9e69b50f57ef91853a1193875f1cc97368455692d6b4ce78de2202158ac4e2f5b81cd5ac188898a49ffa73556754dc82278c4986c04fe3a440626a70ebe45d5e76a8a2fa404f7d7561822a466b900a41fb5dd5ed72f44a8de571ca16efb2e1ab94bee4f0684a1ca658895b70fb10ebd8fe30b0eb620ffce4363da2064fb09712259d278b7f0b838b05e51e0f9094a23c5fd35b2523373864f566148f3755fe4ca48f69ef9182d677d1a543239f95125fa0d00d5fd41ab455a44bdcbc92f145f2f2d4b902f03f523957b6604e7933ec72bb4e66ae2b48358441bbb411e01f814102785e327f6f0eb8f07631e2c896f3fb067a172c1b94c2e1b0daf48c47e26e2b8d3f72e2a478a647b4f4e79719fb6d1464464692c991e36b0d417c37913c6443c77375f167b39e6150614e7bb8a303de2e169ed4a99ce8a92644f81b2879e298c642f48d6a42fdfe3347fa540c843ae43eb6b3affb3a145a8bc7ed5f016a4b2884f47808d82e391ec94852ed626297a78e621d754fac5bacdf863834a0b43bb825fa5021ac0c89c950b25096c93b371663583dbcaac7ccdd0409d679037d2b30f928f156559c17eb9c4d2c2a7257c5f9b1c6c2be8fe741c4bd324350efcdf41373b2af964b4a9983a8d825de9809e2ae365f663667b112ab18ba27680e83881266ca43cefbdb4f50f04328905b273a5b844645b0a3f52fbc41a54daac219111056807dc9212761af1fd3a756f8324d3d6d72ce3c8925b208bf7d4f220f0b2acbd6525d0d6aef1d14471cf901eeda2cde81bf378b2588d74bb12bb0379c10e37d37436161aa82c150b0eaf68b93e1c4f8b95240cf7ab9d8dd0ceb6d8533742ece3082c56b009d0355630ae65b67e14c7994286ae186bab9007bb46ff9b3fe9f0a07dd0b5421b049d7d9bdd269c65795fccb0cb3b6f2041211dc8c0f5ad2172c6ccee0d7b799710aaae48eafb33f22e2478d4d360db30efd1f835421b5f6cd802e0c9ceb8deb630af4f2fd4ad453db9c46451612530270ef5eb8616b62eb88a31fe5788d9bcf2d9d096b639677d4f332aff30b46a8b98ada3611fc42eab7d354ce1e5a2b80256e86d07f65e4adc1e65ac5f048583c06524080c71317d4d572104a381d2660c8f9e405d24f77c4040e0372ae418341a78fc9aec9e4b48563ee4220ef0006511ff7c0c46bd71331794391d86a6d5e1a4be7989e2572eb90bc4e0db146b3157d1a219e31d766ce44ec07b50f5e6890de73b2ffe2c82be24121404f19ff80013f6236f00838b96186c17915bb4cc5845d705746cd70201a4768310eb2340c130d5630d282425fdf72d190ff00271fb267eae05ba83d2906006785ee9fcce877fbde855dc9fc9556755091604beda8971de329097de09e4b53b74702d89ada3e3c635e29014d51ce91cbd4e854a89ede70e212f0e53cf553c5c3ee328bb6e90b5165a7dc00e3d2d13377c5be5093b6e69eedb604bba909879516ab3b4de758f9c62415f7138a6babfb009fb8a6c96c09e3ea15349baa51fb5d5883dd341107f4a9b4b1a313256ee0a3557a63df1cefeeaea3108ed4224bf2b3d0fab0d77316b4b71a674124d7f8e97c1a77b35596eed47ed55888e32f547c8bc5a06da3579e1265db52517e45a7aa053213e5e40e103450d09d9a2254e7c5d25dfe80ef0993a657a1046d5101ec94b31cdaa44b0db440993fe706990ed0cae9503c847f9d6829f7d1f28e41f65289a5ca68a6a5e40b07c87be4d9476c9dd04d399e27dbc1986bb545093e53c0730fb47b295526287c2fa89adc455495a8965c9142b800e0b9cb5ca8af359c115f142df904e068d0d6848d9ddeed508736fa9723aeb812d0cbdf1d29dccd174b2881879cb3e78b04073316c431bab1a7c65aca4949395f402c01baf4925b97d024dd045bd02f45dfa7c8b4e32050d76af5c360f68c853837f35219d206c7ea64fed3e8ac674bac5edc364acf859db599e0d1de466693065432b78bb1132a71e8e729af5698efc41ba4a765310ad624fdfabeb21a336f57a7f39a3a4d73a7933a8c33fd2afaaf2d1269edbc07a555ab76518b69afe03506178e12fab7e411a7201b78698be1066ac61cff4cb307ba75f77e15735b2a2757139c3e1fb59b6695f05449029fae82a67a8698a9abd5583f00ca762dd4a91203c4bed9d0fc2084a1bb78150d21ec848a835c5132813c23b0fe5353c332bb1d7aa60c42a99663905b8c497c8696ecfd80c211c15b18fda2ae20548bed70170238fca972df0a02c209b2bba3b0b0c1072b3265cc5b59e51fb90df6c4ec1c1d6f026ea93df4739af20750727cda9c165fd0aa67e4caf1766a6c0246d34c147600ad133f6354f02335bade2219331cc3f64cd9c27dd70847092c1b76ac570e10133175b9a2f0568c8ecc6efa364e48bb07c0d18a0cb5d161268c2255b835bc836008a89f0d74b0733953995fc0107a0b8889cc6509c70b0cb690dae5fe69cab177688a3afe5df196fe6acf86b490b9a7554d5fd6be731258a04fa35be083699716d471f6f073d166a704186bd927243104cf1c7e3bb88adf8da847bc5025fe3991662b0d0002c203dcf9afe5fb3d78c0ba3b976672a2f29503c64c518f0c7b4f9e28e308e21a7b198781170e25482501c303b3ec660bcd69601402ded90b341ad86a5e0ede43c25d27e7f476092d3acfc9affa09b4ba482c8c30eea448f565a5da1cebba0e3c065a7c3d3bb40b2c4923ad3d49559b90eaaaef61e9d8d03be6d85d4b29d2e5b9d2c88f6e5282f2de8532cbd51f51e7ca61d541a9ba573ac1121ec7890d5eab820900e81fe9159248a93d510c921ff8787235bc342756605de0c078287e143a0a871f98ea13f9d598c8a229527c96209865399f53802be3c9c1422aba311b149cfc9aa26b7bd95302ecb2a2921c9ca5233dbdd0706fdbc414dcc8c041470d96c7b8988c970761255118a393106826cfb317ee119e06ed4e4b8ff04141d7e65f58ef2193f7094affb570a33656d147480cb521d987fc4fa05a4b43e0c6939c097e71d0e073aa50329211db70156920a8772e1271aeb509712bd6627ff74f4805da45e1f1488c9201cfa658f977854c50e43a8bcd21ed84edec229ce437f3c020ca5d0f29f98be6e0c9b548ff89a1c39c5d19db5769d1f90f9099b1e89004f844778c65c53a8b5b839aee118e93671974be19af17209a0e1f45d9049647e0ba9d3deeee72df87bbc1661949b451429214e4984af938bf3fbdce674154db674f6fc321ca409e244927f0e7cb3f032737071ef333da24ea103214ef6eb55d1094c6e881e2a47a16a6c8c2107d1f51960760e5e52dfe76ea7bade4e85f67ad68c0fd56bd4c94d556d81fa849f5bb0e9f48a719d6bafc6b050d2ac6ff300057b42c1984f0443c10525134d69f950c11b8e9f2db0a7c6760ab766e8c07b36a5ae50350ad67f4cdde87e4d13addcaa2fdc9e746635299d57724aa6aafbca4e6bd30347bcf76cf9f16aef98a11b581b751fd4db2b756ae97269914d7a0a1f9d2f4ea6d44a49f8ff01c1f1857112e29f765e5ada2f7e1077cd8fb054439a011dcd42b7eec52f519037c468d3fb4890967216e585cb912b5e2bcb4ca246b9957e00b436cbe690b265d0454e52b9bb78928ef08b8b6d772b4b466c231fc32c254ff2eb60747a846423ad8934d3a545b95f646cdff781cf421c5c7e53af84e3345e5acad6864951f6a4915f223a6db58e983d1ef1442e6e12d3e06de0826bf796b13caec89ae611319a7c6094c9e50dbdfdb850b00892a1caca395d6e288f3b7bbf768c882d96f67fb2214812abd4e1dbd31ed0077e546b3bc07662ca4c94b86997ab50a85ea800511a50f51e9ca7c778ff24debd2ca5924c22b87b584c8ede39f78ac2d1ac68905b8424f1d374d424ff96e57b1e4339ef2f49e24a330d66deeefa271460b46a8685ae470ad93094d54b323fd1fd4150e41602b100fd3d467fd9a72ff8e23deb57bf22f945b104e34e979f02c4553a70da895e472dec7bd951fdb1f815215057836671ece421e8b3aa1fe4d617551e773d627db18d829a50eddd06d84f95860ad5aecb7a71d8efce19abfa2e3d31c5ce701dc54d5945203208d98945324944e2e3ff72bfc9608788ec427514f32b97f53e19b75acf91c2e038b3e778884824f31840ba934a787decb587bce9cabf9290142adcdd4d08f54b35ef7d618735f0dacf1f32ced922711d68569fe0c9a52d8b4b7022215cc5b102b0f9c1ce7dafcb4aa3a0dd8e7cdde997b886e4af91526e1c807f2b2963656016ea84c88b51ea970b4cc3c4d6d3570bd74c43273d952069c7bb330ffa17b924952a4523659c659c3224a1f698360e2aedfa80b3b15548e6542f3c2f5f5886135e03b022d8ff8d3140c4dbae62b81cb8fb85f90b59b3c6e9acb4c8ac5c57270e0c788edb303bc455d8dfa10a23def5f09aa041b63b680eba4648037dc503ef500087f77e23c4418ecb85eb2ee902224594d5551b861ce20777e325c23508741964114ea4ad003974d636b3176284a5c6b7c0adda1c5ec272bf59a2cba1f4c17b6a84041dd2b15fa3524c32eecff9bb1f5871ffd5942d34887472b4813ac85dc1d429470af7e305f996588812c9d516d0c849a1704fe60d22d27b729ef4b088d478833c71d5c90cc08ad0114a862c55b797910587eb767cd8644ad68b2e7463427cb3a477447fc0b704c8fa0d987571eaedeceb76456668866c02e520dff8b01560aaa8d8e63743626da42135a614ebe622f1550d800a2c0312e1926dad25e0812d174b3e2dd50f46946dc3bfc71d3ed25840c88864587ae3d30335d4dd78dd76e92c163ea25ce14120d1fc65de409f6985912a5fdf38dcd4dbefa28e20ddbebfcd49c35cb64e4e9f63cfe57d4a0268c3f9457de52f3e0d21bef3c11e1afb3265a92545742bd60c365a41fe204d489184727e3f381420ce9de3359e01ff96d0724c0c1a1c899d847ed3c50fe0e24261aeb9fd7bf1019bcd52dd3d512c1d7481f26e3e1cccf49ec9faad03347ff66e5b0cb70f7ed79ef397066ff368f9bcf8de9ce3b4816479c8f3963f8f6ad3a6712d182817b379c8c102360d5132f6f4bd0546b3d4a7d4cad098a18b3644373d05119ac4fc60739cc23257c38dad381ee15fcd476017a9e349e1312f9ddcfb9515f9773a0ec74f4bbee38084edc7c75c69f83d71dfde1d336df0a780cbf3a7d89e0ec6806087dbe8fae1461a3e04254ee3e2c8b51c1283110b72012d660c6939ca696dd59890bea3d8c8bcfa293e846a4daa2b51e4295084d37d7c8e1a4921d3cb5fb911fea29817d6a08d28dbc8ae8afcb2bd2e96b7a8a4d5216db3a51cf6855a72d2599364c5b0353dd4b424ab4ab5a63bf8c24c0aa6f3f4b7c6b6ced6d76b1b1ed9cc7d86ed38fcc1f93da0b1de0bb2d36c0e07059ea3b4147b6816d99bbdd16071a3e533babd6f08f3a5a7ce67fe516207173ee597a6daf0abd43f8db5594de12f0b35e385c0bce1d3c88e9e5b6d5edc115000e3bc813f4e8c7fee9acff606a241e8e39a3414f6b4d457e74008668dd25ef98f5001af81de8e1e167354a02e762bf88f1dfd78e07b2e5425d3f98c110290488f569c32e007bacf26cb485328f5d6c44ad820d580b6d7aa7bb0a7692e16079a437037d1bfb2af3e55505f3de43ea42d0e051e0d661b87bd78f260a8b51c1a6a2005b7698bf994b1f48f6e3984e115028d88397f6facf4a7362198132627856ab31b4bbec0480fdbe5f29ecaf339efb9e10ac60e74791198412dfc1ea818d0f8504f551ac54588c38c0c2dbb0a351796cb1fbd6e6ea31719817455a32765f7611b59a151be7c2657890c062a32729a9679d9d2d263fa4c9cff36ff91a52b1189b6a3549104b0619712ca935da93ae5c2f7039a1d5ca71f49258327e957ce655a496591ba92dbf6fe566845fa5b2b1fe5daefe2916699c582ee5838b135fbd1a9903d44a4d482bd95fbb72275480019da142232c8fc32d806f15d8f221f88d68f57cd02a1f29ec4056e30760dbe05f65964b8686b74cb7e0f8fdcdbd059278b32ea175ee9ba68430f685c10e3d61b69a19a2d9effb995ec3764b50ad768afdd164af7977202cfc1ea1db01487d5ba12e25d298e1d56f018439317b218a1d5a59b366a25ee4c33cac717615b57d15c99e8e5b187e0ab833650d4b4bcba8175e0bb8a72d8198ec9290a14b74ee4cc219c67c5d114a1f821b7fc4ac4e22476f1e1226c5da7eb9f209d1d6e912818b9cf96f8e5c4b8fcb5f9101d65919aa6efa239bebce261afddb4a08d6be6524c1ba7a53561d98ebbf061479c1fce5e5f132095c63f1407a496a52717c4d81e286de1eb3fc345205f5b0e66b4c0fcbf9aea3260971a8cc8b781fa11edbc81c460b38fa7fe3491c106f4e636e850cab003efa2ddc2ee82df5602e0b5fcdab1a6ff0f607cd407872a96a91671e541b075071d37127d2ac93af8d7e580223df2a8686061a6c62d2d4f926030d5b0c6662cd7370c8f173f1b76087a18e724bb6c70c7de02d3fa36d322c1ebbfc1c9ab5b5549878e0eb846bf2875b89fdb94d2d30415e34e552e9873275bbdb91290faff0c3314d5fdeddcc0b5709bf68364c0e8c2d5f6e0e9d550383e9be40077474e68b0b59e9f8acd336894dba1748565ff5f19caeb01a80c640440a663d9280d0ee55999cd1bfe09fc074835112ded64cd380c966e47b19a1c3294e0ddb52e4e69f2745a8626e34a1a1208ce2e849b98ca8b283e0a097605667baa55de551bfb826da6375225cc3bb36cebf8ae2db80532dd4ee46f194d8b40cf7626d15a01867f3457d26c9995e63143daea7face1bf67ea49618a9b8b1e20741f3c1611b51bfb173ea2790cb740bd4e682dd10ac4c5286a85e292d200538b15e8734f656bd2d3a825a6b8114a8d3cbfdedfbdaf13905e2aa2ee26a76591fae4a9decc801de894b20bbc1f738b4299b0168ed7333472aa899fd752ec11d401e19b361811a5fec071916c8ffaabd2d04d9fe97bc823337c16f2110e3f0cb2adec4e595e455d40b4e246e678ae1089916d560dd88c4985e019d2a4591fe6d8b369fde30590fe8188644027a8e2d115268200ea631edc81166a5182de0c7bf11155545e0184d49bcb84e35cadaa0e9591ffde9d78f9f4d51730a059a960cead8a95f1ac366b636dec821d047a112636c69343f9a00adce37365c5bb753b89bca90fb4c584dd409eb24b1baa83ebcf24fa9bca40324cc6ce0024b7e2f6fd25d0bba83cba32d24a0d773ef285558671ea926867ab7a04a4c513c1c6f2e82ef0992a28851302521fb1992ac3d706d80498290b194b4f4444d36e5d54a4269f4ed2770a2d3d3edf5e1d3921a146a3202fce4829f30af3566b3ff41df435de0bda7524e71d431cb11f84bee2bd70571c34c216182ce1830fcb70e32d063e745063890b2bdb9493e23b1ad65df1b8889d76ec1575a427869213e27bd41fc45bb18a4ff5806f62ff7b10a1335284cfc1a828abc12431885e3186b9c97261b36d593e92b4245f59732d206a515812757e8286f0964a3f5183581bc6a3adc863785af653bac6be8326d5163e5b17c63a4300533e73cb8effbec50b08b9a247b3108e55e668b77eeb84ce1d015e612a34c8172e85b2e199c271eb735993513f7cca2db6cae4a643abbdda35a67e7197bf7b190edbf17d352289af9762b864007e93358b3664bcd5116f2c94b711928517e788d319c0d138f95df511d85efc469f012fa121250a035a1fa063192174c578b383ae0b3b6822768e4702dc3a6ff5e31d03b64bae819edc090d8031733d0a837ce1d7009511069825c393052c2cd6c62e1c20071a56e201c62c2f8eba8f7b48fb3a45c32d61eeeda023cbd32d566613ada9f20d970138a5d811852515e844e7efa01a31c7343f3b8e0ea56a63fec6b33aa521615675c447b1521168af93aa00323f489fabca1af91d536e39595bfd83f3bda284e0c462da92681a4e75330b1bb458e3a18542f0e3308a50d24b2052a8fa9a02b80289ae5ac4ab69f7c0071fa7cc6ed6ec39ecfd438dbe8f7b766fb4beb3184f238b3170e21c0d34bef7940b0c71e461793ff414592751c8ddad4c10f88bd853402cf2d819573646091e933e9c774dd556638bc14c2c442a528638b1546b8b04218bb9a7886234ee93e2dc8f4619d7bbd435eed6d50785f49f02a396d03efd04fd5ce2bd189a9c055d34597527954d71c36f5f0ab7f41394df29792eb87e4d0d0767c122836bc110b0c73b7d868a297b5bb70626a9676f5be5660d32aa2236f3ebe2aefb1687ca12b8f46e7a137228ddfc9ac683dc1331a1a348c82caa68773f32d1c0831bc55bb21b429ebf53a7672748e24501fab4dde0ab971fbca773abbeecf7b4c8c8fccf8415ac1cdf8b9b6293513e579cf1a5dc234bf59fdd5400be8f2ada777fc65e7873bec2d97d8a6b8a99e57dedfa8eecccec6e87a35f09e7b0265c6c7e8ebb1921721ec99ed1c7127db2541c3cb92f39f6b41f5abbc965e419e729c6b37813c56af65000f1cab53f2147263ae6d469f86640ce70ba4a23d3c0792ab0f0336c25cbd69a441949fd10cd28bac898f82656e526fd741520909be033e63bc583f364803667236e1f9da3418c2e27866064ed9c3c292893e697d9a4e71376d0d802aed9ba1694ff82980718c3446d1ead79f101c53a706e095cba9849b94832be58fae431f851984986a2b9c50432842dbde0439a2a997c86bfe9e6baf5df52a61a2e1722744169605ee5e82b631f27e9c4b6874dadf3d7cacd1d7669e9383845cff6ca093af9b4186c160d020b5318aa0773ad72807f0d108a3a08f8475bfac707f51965097fcca759dffff3412d5bddc8f644f78c83916634ba1b2e8521a4359b9a7a766d6d606637e5d0052beac86f8f1283b364139bd10d7ae6dd6101d6f82b3b004a54a50441b4765f4ae44a57ebdc289e74e3e48d7fe83da5d9ed73bddc4f1e9fc4369741793ab16b6283fab4ad9a1033d766f591b16ce18c1007b2e99691587f49896d55f33cb8772dc006dbe8072ada75a1e2d8122404dd704d28b2fd725889a4411e51a975be61b66921990370b2ab575ca37d8b2ab7084128dee302be87c364196c456b47e3239765b7ca232df736c1fbdc54637e697311d52ded34ed47442e18106c312a0d08b60753e4ffa2db0b04e17a66f6693d016e3e98a0f99351115a0c41d1391b2db45aaf19e1642d656dd8618dac15dd1a16dd200aad86d8e403adb1613570e5cf09b7a65e1b35a6233744afaac61d874475196938eebf3a0c0806ee783f9a94469bb41dcc476931b61d467813cbfef58f59a8a3db3f522983b2ee2be896056f9a4880f56d3ec7613d2afe7232991e6ae59f1469698dac00ca907bd905360fc5328981315518f781f29d8dc8f67eabb059d2d67d4528c1e3922b5e8662f92e9b3c677f4d14bf1c451b9585b2f09143d8d8372f2e1d754e4a1ce472271b06b5dc47d7221701390e955d3a4a8de22795eefa9c500ae98f7428bb652feb02e701d7880d24b4691250c2c51fed5060dcf78e8302453ddfa97cf80abab6c7c6fad603d7ae74a550b368091a1d79c6360b6f2ad94b571566314b0e413bc5ff38bce3418f168e31e162973e995f663133f0e2b3a02817a3b7b9cfe29ad38f25f47f78e6a10dc51f8d51bee6286e5b8e587821473e80a874ef4f3fa1f256ce013b61a55b0bd8e8523bfc03d69981b8b7b3a287cb5feff331272e8f6b32e76eb9380cc832959d58c5f8a9566308b2e09a08c633b4ec4a0107dd43dbb46e127f87dbd1d4719ffae5da4aa84f95ef4f8139c68b2cd069d72803efc72b382851ef03cc5f1549912ebb3e4115029c04d9baf1ab2757396edcadf49efbfa56163669df9e22e17bca99a41b36499be81f45ef5dd196d46a23212fdbc05694160b1dfb240c36e9404ab3498149d39f411fbadb57cfe355eef71703f3ebe533e64ef373e36c078b98dd19f4403db8f441bc1282c1df2b29d59e7adaae129eccd9b656e8be44a7e60be373d5d7a4b97406aff04c83c4d37eb6489384bdcbf26d89ae654df5258fdd7636f38dac2903842e0bf97c8d22743056b9bb7ee06399116c1909683ce25f5cb15c9081f330f500afb12cf186b7e474534ac5b34b10cf55d637730a2fdd315a9474b6c9a7e13e0f1c10dbdb2fddbb522ee9797db37fdae20db64124027dc3157f459726bbf34a2a391ac1b495c309b02c1cdb7fece1208bec6d1595d6c374d122512e832e4ac1167a87d20d8a53f9afac66ae549afe48e933b9539a4a12cc08516819290b32fc8c47ece5e410dd6da7721f7b0a7e5da49aa1d7e8b8b1ca0a56bff9bd4f31f3633311979f34ffb61677a2a241b5a2c9517585ea0edf6b47be15315108717f1986e9a56989977b22dbd6addea996231bb688218dcd693a76b06cd70872ab38d277a1d9a86faa3b8c4066d7aaf0b72785b00dd64fcc522ecfe63f427a788812510d33fda5b606d03e1f9642d03e369fbe5655ad2c7fa7700f0a45b87e00e56a7bde5697742aa046f86136d4c926fe4776b9b18fa33229a8e8faeea690424ccee4e3021fa11358ccc1385fbb2129136009a8b6b00cff30b7c61aaecf80439e9dbae30fb8a08147da38541b49c6be8d221372719ceeb63319ed855bfc036d666264abb7e5ba20366d83b957dc317ee1bf1ce36e3a7c935fc08dd396a97be6e78fc079ba8d5c5a7a8bcce985216130540a252143be4be9ea3f623deded89c79cd3686e11c84a34f18e3875783d2feb1dd13141f0fc8fab3a74964e9fcfbab5db88b5f8d4b2d364e5d6ac1cd0953a0144bab9b9af1e6ac3225a6d169f3d16374bba5ba39ecd9804a0399ad59d30c5ba882cebe14db5f72f125227035c59456f0f1cadcff00480f319c9c6ae954fcbf300dd2d3215a97329240b891c29ce777e21c7514754009e159133e22827f07cfc5a429589073d94a6de85cb0a382bcb971b19c09df76095083bf1e906b1dca71840b76114381900de323c2e88b68debadfeb7f54a45d12bb728167ad56bb4fdb62b4d5c754c6444a1b2408308522262124c34f90d62a0111cf694ea98ef68d201a389d98e44120146a8f32a2a60fda92147a2a3c88cb37f97491d0e48953194d2865b33f87a61c68a428d47e2b9b61e28faadb65bfb3309dc9ecffb9f820300e8f431156ed14c514af3fe9f1d245eb72a075f614d6ce47c4a94c07a663edc39a2df48fff1c5ec06758b1ee777416a2f3233afc31ced13867a8a4733ce6b3285b7fdc1b81e7e97ea0668272db6e9000bcb52d20456274f017b701597b68b85bb350a66f780109d6c83d716ce5b576ba8abc45a078f6cde95411006ef7b0308e4c0d29ac3dd0d3aee5833f714d3cc0d35d0e827bc0bd60702527a7cd4b0a4149b7c1c44ab324667e03adaa87898da05ccc32842aaf67d957eaf64bd755f1fa41832214535e37fc2c2b3469bab332304e093895e3ee7dbda3f05e49286b637ed3f0e37718f1ccf4e6d2c07c54cbf8c5d8d511e2f113beac2673c3a2c7643b59f5428c86c996238293b4faf00c8c22bfbdcd40e12b33e950da54abca5b71fd29e813c0ec7fe374b7aa6a8fd0bbbe9d257268e233b35ff2e68683674c8e42e9e3c5261b12bd3ed12d326a2e3c327261a07c83413b05019d06abf6c4ca151f67ceb008d5605c5b4e3a51a502cd21435101d9edca440bf177b4f8a60e8990623466b5c0953824f4c3598af7196c35a407f64a71dd9c12f2b3221804a7855f80fc4b6dbacd508cbb304db9c284a424034f496d7d087eaec12243b200f85a8f947cc2c2f2132177a618ab7c05c35a6afd7dec6c0647c8c3aa23af1030798f0044b7b0b1930af3d4468b82a1bb732178fdf3d1bc9b2df9d355275cda6f3e80553cfed70763549ff06453ebf6215e941afacd9c4f08823332365cd065af4033ae63c2a389bc00052b94886c2da48000a7ae923eb0e31e772e7f515ccaf98b785838928734e103ab1ead67dcc180f6e1f364782c67db33b5c88601b9ddcb17114c3c590c18b84aac966dda0559004c31ac1653910e058a056c9e58012b49d9a717d5cb5cc4558141f3eac16943c4d23c862b210a0c04c451bc3c90f3afd8a8905ce77bc335bc868047ac6637b024e3b86b8d8d33c17375cde61d76af4718f7a0cc7c41e82760b380fa7ff5e1967d0a41df364fff1828d0a79a4dfad7921cea0983d17e09e9900619266f34dbfbcb4b2c30ef16fc13b0680e7707fc491f0ccda0a70622a951aa7a3dd04290d705a5219ba7218a8b340f6590b40d77524b2f355aa0a93c860eebf13e48d66d946115a2703e08004c5997e1fc9f78b3a2153db8d6b18547244dce58abd0c310da5461d8bfa602f9eaae2a04c8113ed1ee2bb758309e0ddf4d567b364a855e73214334b95243f91fa8de83ee04792d4aba5e523d52cc6a2147957164c7a872faab9200bf4c3b3f65ab6a78e2fbaa7edf49c0b7468533369fd63319ac35c4935be314d0bb109cd06f358340652b0604d6aaf3aff514296d7a85332ffb139e733d375e2a34668a6291f10189dc622e790bf004e4fcc1b316b0e559908d32c712ca84543bde895105e6e805f16c4a5414df6fb2e1d2d646933cac4ed8955d06388b6efd9745556dac66835cb249b269e1af24cb4deea03a516f97d1b126670b8256ff7b3471f752eb2da612405f7bd5f6905b8fa8976d4c4363ee457e7d95997f8f94f4cd89be053028fcdd2469f485b6b2bdf016cda7ec470c2de9898046c5a56cb1bb1f4116d8ce4d2a0a7adb41dea6326710d6687e0b4b89443ffaeffac420e11006c09d7f72c5b53967bf00f7eeb4979384fa8118f8591993a6f1a49fc1d265479102ef8c3acbaf18bb2982eebe4479cc83e1e7cf36046a817d108f2218b7217c6a17151e88a4b98f3ac835079859526f26de8f817a646c0528ae248caf829dba76fe202b87f42496ace2b60ec97979283b5933317cd8b1c150305205137ac90d442e4b1f208058e5e2667140f334d5c3105220bf10d4c2deb070f5e75a8603c37c72603c8d1f77aa35c3bd90c1c0e890711fd5b0373fce8dabc0c00216229563a6e48b13323d5a7d8806aec246e3e4c7ab46043f81be270ea73b2a0ab45de4461746cb12adf59b227ee9d315602b874930a1161c905b6067c863558a52159fb7a4729667c20cce4bc29409caef5359e67d31755a98d151a80a0485052db52e94e49869fa06d9b5022f6135d1345a6e2f935d604098f21eb452bf510d4ab2b35bca281e992bc92dd472707f211cc77113431fd22528bbb7ef4b238ef588acab66201773219a500fc8821ab6af9bdebc5936a3fb7f1f56abff42f4168b7a7fd60b139449d4682c0b01b33703f57a5c24a888ebf04157871f9602a0f689492b7d30acaed0e8741d6f8ea2f7c70b972255beff3e131a0f9b29b9177e8adec526e1d6273ea785670c34d36ca3ad009b8318593d0d60d2c37d4aa60dd62ebeef2b9f31011c4036f7a008a13e78eaeca3a790d0e68c80661d9c017a0b13eb739f007d60f0571d642c9ef4b472fa18d460ca0a60c1da2210b2e01762b4eb63f8e88bd1cc3441e388ea29d94a3faccfaeaf48cf9640331ce414f0809153ba18887e4e75344159bee975b2db89f0374c6dcf214f3b15386e876724b22906946542b21030890951b68665637fcc04a73ab432dba5803117625351a3cb0fc0a0f18df5d9e4d8f740a3ce4aba86542956b7d1e35c2d9e29d5fb6e4e02797db00ce7bae4e34377a70597a5b9440bc01479301d1c80bcb63328038caaf80fd15a27b0288030b7d009bd4e1e55f38561c831739c856bd5d0c6b75c8d631f00cc3d91df175fe11b57c01b2bc460058dc4b4196371a841dc1eb268cef19ad17b2de8f3c8abd4d5488806aaf49532969474f0c1eae0c52e819e48127d33500bb00e38241d193faf2938b164d9e137089784a8f9aec09499c0c60978289ac4f9c00b238660a214a1d3264b83ec94a7903a2ff2f17f6f6a9b3a0b6f2291424736ecd7ac1d7088977e1734a7f65bd9d6537d2462c4c9f7c1ba6011ca4f4124213031d6cd40fa7eb5e1d2937d1d24d30c7e48cee360dd5f0ece89d4ad6b7a28774259eea258dc804cbec821063266b6dcde9009b2498d4369fa0d54b44b7c6622c472317f1069f8c9f56bd13f5eafa2b9bb2dd4a3dc29301dafec9580121af444f90f512162952c40df0f086f8c18738e82dba408136fd89dbd53b320c3a56a2c6a2fd4b1ca0289e626a5fda093a193140bb9ea2e4e264eb79c831ff30c6d73011b810365a295f62ac0750553815f3e7f810498c6dece4d31b142cb0ecd5de80085326840092809fda9adee822e4df63afdf35898ae1ac20f2d019699b332b94cfd375c3c165e8c25e9c4b60392c969615017c778d4baee8f5b39857e4b327e2b2e5c949f115dcd95bdaabce6195d9433b7f98b67e4c5bbe4fcb01bf085c02b110764fee9b058547659b39354a25bad8bec4fc05ae78a8651fe569eb0d30d7ed42cf80075ca825bce7c7be68b0880149d23532d5d282d95b0c8c9623fa8c77fc12166b371e736c9b0ea842f0a8a4db5b6f0c6e986d1cc0843600c95712deda44d8561cfec0067620364a1f4ea4b5a567fab7ca4441e148ccee4738b2e897877ce5b7cbbdcc8d56d94f87f05818c2f1eb16f284b3c52263830ca4b42b198a43fb6d3905801905b115d4194af8e04ddeeafaa3c1307f3aea3e9d02cab3cbfcaf36724f3bd0e876aba6f155322be53fc5e11343d9e2aad9cb9133cd14d18ab6854b3721d1f0166a607e30580d95f0a617319b60e0b993131fc91344af7595c2a11ae2d1d068ff58f35b6617688222444da30ead11cb78a60b7b831f85e135f92f908faa95470d8d3fc8579dd2be73c13e63b5cedaaf600c8872847bd9a8a23029d892d9737b62e131ff58c066261ebca1d9edf5560018c2caaef9b21252de06577dd674e52a925116f3b8ccb921d574d6c34e1105db6b6651f32cab6d73d76a5211135ba31f5cc40ca2077668f81711573c31a5b208d28c2f7a5213d8428dc7c63f103a69f21e3134dabb3c56fb4070ba4e92c1924f53ed7e89421608f2e7f1a3c7e8fb24a845d1a42ff96584191c70be8989fd5ac0952bfe1b18164d628b6f9b94691da96f598aaef69e7b14059eca5b0fac25f50d2f2cd486e3fe04839934ae0d7b71f1abedf0ac4c3299abe1d3f9036ba2c1e34f19256a506575f03e79e67d97599b0ad89e436d43fd31457de12de8fcea3eb8f57e3eedda301b32e548220c2d60c216b48cf9b6f41ef4a72b89e5e0d2134a1d7b2faa7ba5d78e93c46a373a414542b9ee50d8b218057deece03aecb6c47aa3e31143ad077ae52582ced860eac28e8aef072d85209942ab662456cf6a812290fe6d1fa6fddf6e15971de488a3225d7e0f69450945205a2d48a022032383b43c979c04395617ad01bdc92bf6d813dff50b0c6c7c1aad90ed05461372ab752b9ef40545a5d29d62aa5955a09151b8f09c76ae5f60fb56ed4fcf108748482d716c7548a41c5f6256b6d992631ea34f41bd4133c76dd023ab2eb56d8d59c62940be8389114d19f2c46b7a2832f0ad0a5e961b1559bf419dbcb693a89140211e7b415e77b73393151e91d9dfa79bf647fc8d5a82724b6e0a214d5075596ed7180c733620886eb856559351adbc98af524110938a99d95852e7eb762aad99522cf643ee314e5a0f8071a4410ba11e5188c5a3e713bd10e7034d81e56c347bdc8ae7c5990d17f23b9b003a68e039a8052fcc81478b8027a59914addfa375e3f890081a3235efc5b389868af88fda6e08d82b4783a43670abc44e6e7fba34143c2acc65b82a06967b91d60a102895b9216b77b5a76073e292a15d04888940f6c42a16025ad20c0a9a013bd59d43d3716bf40dedab57b348f823955c913a7bfacced3a0a4a67ae6fb01f52325751a0386042986220a36d8084a28c91d39d93320df9323a9c6d0e03058a6f3874518c0dbde3dca0296eec8a8420e5d36ddf819eb87ddfbebc98f6b6b46eac6c3483a6eb5fcba8785caef06004284d980b91af2a1e5c6f0b9e71767649289856e48f2ca21d1d1299eee0301e45c7da94b8f135c47262ab4f2ae314e94f9a215f0a9bf03a53355982f31c18e8ade2c308754ee4fc1a31db6d869edad656ff94ee6615a5f4a876723552e677664b72e5e43307699c71bb1a2bc30d1ae4dc9425ec99f74d37352d4211d936d202d8fe23071d0d2fc326bf93df5042c8a19b4608278bc6fbef6a8d9a9eba6a2c7983bb6a63cd4a1e9fc5743ba8b57c04e0a23837d26c98449443cebf84a46f303ad4eba9163488c9431d408bebb48530d4ce23973e63c531853b82186bb74f33684fa1bd36b7fc24dcc520ae7487b7125282c1eeccf64c99b447503b7b4307a28557c3f145eeab47fdd875e60c15ca15cf94c201c83d91d46ddb7df42b05cb32d0fe5125c14638637febbd1ae80250888140c908040c563ccf062ff37cd01540e011180a025084864bc199fe87bafb88024e1000104540e8110c59acf8b7c17f5170809082c8180a4d0209138b3fcd1c34d7b0d120020e51088040a2e1663c61bfcdd68aec00204480a07914060c563261349f382e260b2060a4648bb2bc5f054f7990210c081a51060125b4f067eb9e710d2711c5b48cb005eb064b483e65f3f06108a484966cc22e7769f6d33a8de8fb0dfa95d342931ade2cf52387af00f9d8b436349d39b98b93ea9d6f4efd722b55de9960c2bd57f3f8c1dc5fdd93170341c241578d8324871d0fed81725735a99da57341016d4c6082eb1852c49c41315848a6d73151ea40825c94feb4cad5d731a6a67696e9cea708607c4ae5edab06c56479ede81bceb5f0db7bf59cd5ecebe28af539503d66e53bee29181b52e0eac75dedbe89f04d5215fad310bd60aa5ebe579aab3012aadf019acd0804c336816561a37e84b0341f792c44c4cdf506bd5960b1cba64cd3059f7148f441b9cf0fb996a250292b6041302a52b9863d7c08a63521d9571ca1ffbdc34f73c83ca8080121c8430d2b6a6b919196056b16172fdbb32b05ce7bd2c59d47e8f4c5647bd77c0c204b31d8286d0b6de6b8c58831f6b8d5bcf9c51fff0351d888a66f1353b8f85c9f1351a951412c6b11134940896afc1ccc0409baff11030f069c1e6a3e403107d4d07a4a271fa9ac56716d464abaf71c835c0ed289ce3fa5a7ad594ae9a252cfb5ae17a0df83a51b4af496f5f7b99054a8d115c5e25571c83b86ffd6d38dca4c8aaaf5f33e58033ee4fe102b48b61ae879952caaef80360fe27b336343aa65936ab356f968565dd376467a1f69b3258afe7bd8cacd57f47260bebde9685c5ba6f64ce42edbbb2b15ee37d5959d57e836c16ebde2c0bcb5adfc8cc4afd7765b0bece7b21cbcb3931e69f4579e8c228e02e25381ef7e5c7c7afff3e7e7cf8f5efe3839f4fff3efcf8f8eadbc78f3fbfbefdf9f1f3e9b39f0f3f1ffdfbf8e2e3d3bf3f3f3efefaf7f3e1c3af6f3f1ffc7cfaeee3c3cf5fff3efef8f9f5edc38f8f5f9ffd7cf8f2e9dbcf1f3f9ffefbf9513ef856489a108678c291466e5204f41f69bfa9fc52fed1ff43fd97f69fe227ed0ffd0ff49f54bf29fee9fe51ff43ff4bf961d521d533c3b6fb07fd57ca6f9aff947f94ffd07f52fca7c03f0bc51faadf4291f99bf3ddc488bc373192ef3906e473c4c8fc38df21868cfc8ef8dfcf98833f2315fe2cbe49eb1ffe08b4f537be609f71c6ab5124d2cf1c6404fba0742cb8b09116f29c6e807459df8894ad67bb02ec7ac67082fe71377f2124d92b774a4092a58bd303fb6c625f7bebe5ebd37ee2831c0647a401543c685ba73f776d5ff7f8a69fdb21d105a30639df96a655b0c350ab7a50c3137f26b011fa7649dc81d85d03bb69b82b1a76a951f735d25563bb69bc0bd4209be22b70c868885034c41eac82b7ef2fbd4f86ee5f7fe67bd0cf2e968852ea5b8f8822bcf1b437d03f00de2589b437d17884ced224da9e09fd411709b7b1bc961e74ab515c6ad89fe81e389318dbe5652981db1b05a5d4de88e6b80f89db5cbe940ebb058d629f2de1c2497d601ae40a576cd1b8f6af24fc3b44fb3568e5e270039424302c22ddc38709c2d95958f53330908b69ca82617fbba2824fab5851115b90f6f1cf421502809ca48bd67a1e6f31438a5e62ecc8354cf5e229ba7ab25e957d19f51c4a8eddc1b77cb439202aff49364feca369a1cd7a47bbe1f83ef1db4a85420f7bb124b01525bbf9a3790530bdee805052a292d75419f34c039c99cdb066b4e0cede8031d314f64c1bb831bfaced59c8a8434d227816dc66a8f635c7cc5866c9eda1f60704339c9b84489c3ed48ebd83c43213a15cb2b13cd38d98ddaeb0e5b96c5e5223110c428482840160290458000794e0004420881802161831cf137d5ef447d85b8acb05da23483c82b9a55d5da0de02e4104021005a80b0687c1098404d2594a7b93c31aaef0a82abcb9393fb2a9c49681425262670daa84742eea9abbb1c6c001ef8bd50450adf86b2b86f9e4bdb47fc2e31aee7432117f09311c66382097e64f64d4d013f3ebf47eb8eb4997dec28f66eb45561dda2f2c93f49dc4e2b7f670e444b21b2a622a1621f4ce6b448032c75d41f247b898d975b4e8bb253cae14a81b2e028ae903eadc1bad933d784866e47855641f03ccc76238cd90db0b3b660cfd08439d31ac66c5398f92db0673660cfd28439af1dce7c43b8f92de06736e0a6f3db9a57323a0f19da5ffafef840ff4bfb8fe287e67fda1f9abff4ff9afec2ff249ab42955545c0415a3e421a7f94bfb47ff0f5dfe0313bb6fcf865023afa88550308a1731c51fca5fca7f14bf287fd3fea1fda4ff47f343f13fe50fc55fea5f143fb4fbbfa1e12f43d453b8e0a0b86cdee92b921c7f1fda4b534bf56b042631b78310253833323339ee1e568e29fc6b2527a4bcb25cf4b33756d79e054acac8415e088dcacc15991d660e64ceb98c8028829083dc447bfdeb8e1a75c859ae3b11b76e6996ab978b9f322f48911f51c2a2c2e727a25b40854eb861f61902c3b69317d7500a0bf7f42febf1fb085ba9fe99df00a3ec11929e61c1e45f16a1525c814fd8bb560021ed0b345600fb2f1661bbfd18bf44a92dd88f07eabb12c772c403233b734687faa379c30e56bdfcf8e939c2573342932da5d6c13551aa177ea9270fac6c3c44ee5613b9d926736aa80d72e846bfa9579d3358ec934e1da65b8fa5ada3391395769a33941f810f164f6260483879881c0b4534ecb4e467dfea0e08dce2cc469e16e485798d87c56e8689ca1b838c2860685d8310b1cdef001cfcd13f9891d6190074f401430b80b22adf81ca19689b6123a471c5719874052d450190656866cd90840028130177d23b58c3b3afd7a651e4ad007a6a96be5a5f11e2c59efa8d089a93627d1808cba433b630d1aa32c0341392157a1e8f73137376a75b0618f8f381ee9a17e4415a70fb81845c8e308328515edff66254dc70a0beefd8b972998a5012071321b4c7148f08da86b626065f4140ac1dbd417b40f843fa7f3b10faa25aad8720a498facd61b17a3210663aacbe2473c58907f32d4f317158d2b0f69393e0aaa17fb11cc86115b2e0a9c9d5d9799bb2b25329957f0779f5c096538d03fc18d5fb42d8d5aae8284ad2663c11b5740475cc393e83c71f3051d874b49fe99b3ffc037832bb7746225bbfcad5259bb05f6c40f5c381d9aa78374cfe49865d323a67145a9aa829e2b7b453421cc21bbbfa85e106f0524f9a88c1c19d231178ff1f81718d8f747d5f9237f5c9659050ed2199a842dfb41aba4da3a3d784327a4c6a079d760bb8178bf0afb7180b9e0f97b3ec4a2ac2780d229aebb5a2710d0ee36714fb028c99004e4f0372236a793800a644f67ca3aea84ef4d9c869e247082580cb6fb334ada0b036825c7ecbf335a9f0bc7a788d38a151c767e7f420645c010e7a9d5a81011c1742d6aecf3a4c4b03805782fdbdb2c389234442479687d9982e215ec84d8418c7dea73c785c3902e563642672e8b5b0c493503a02aa708743ad743bd06e9bd23f1aaa855dcf1b8ffac077ad0dff35d0e88c646f633fc748f06e4c7141885c870862d090815cf4e03d825f965bb3e44825b01b5a2feb7abdd8115a7ae9e2fa105b8aa5347efa03470eceb722fa0e0110ca162e58fcc925f0a291c4be4da16735ddb71cad9ad003a895e0fbc392d1c64f3faa18e927a1e6bb11254eb0e587f76a0cbb1f487c6e7d74b226e68a022c6d0f9d0a130e7bac7765fe9e975a26b72e7100ae8f0a4e76c12ec35d659f1c84b75b902a09b7a5b38f55e801ee05285303869d0bb794d95d7c297ad15ee01db45a7f2e83babddac3b6aab3cd4d857543ab64a1215f7a62735c7b5a1c1bf840ef671a99f791cf764c3402d9760cc13eae4a972bc6ea11d74638f53073a077ceb774a57deebee5c963760a17f1786795bfbd8adfbeea6a5777b4af7ddb55fe762abeb48f01bde62d8a83298ee3bc72b35d2dc85d0b615bc70a4f50d5e37c2715532942e329d737300220e60c40b27d3d632ad94c2e57322b1f589c1502275cac6465a5ff909f0c165da08ab5c057b10f8bc92cc109296b02ab111bd06091942630a1b23ef0056205382c2eb30427a4ac09ac464c50a18be40fb5c968bca2df00815b4b2afc1ff405fbc7c1729fae52e55655bb870299619ab8dc4ea1671d0ecfc3b47722730fa3ab8d9f7d4208db7ace9d7a21eac4e6690c0c3ec6a12215cde2fa2078fdad82389c637862187f70f95c2eca060745261113bc6158e19612262ff4f2587d1cec3093e7a14473ce114108a37c47e36d6d342abf0465e8dbd60ce2ec208cce999ea30f43fb808e74427f823c8b3a4738443da01f401f221d239cd19e90cfa04f1187518ea807e807c88788733467c433f413e441d431ca21ea01f901f214ed1ce11cf5847c007d883a8c72447a403e413f459c473923d913fa25ea85ca729d45ed02fd1275416db166a176417d81ba54b75cb15cbba45e405fa82dac59541d8bc5afb20b64194d6000934627180883b1890fc4c04882036fa6caa477694c943213ee300a12e5bf200857785110ddc34541ba4a8b82607099d3d677a51507d9ba541c64aba53888d687e2205bf1c4416c4d138320137a2d7190e797c4029ccf2316e07c8b5800673dc4029efb2016e01c805880f3e1c32a80526733c021d0e4341e70ec3c18d6c534f15161e8b485b5e84a79d13d2ca9d8eeaea69a425443f6b2d6a3c821fe3b9c62bfe02e06bf26e300a9626ae96c5fbbbee7e059b332c9ca9c05b38390b57a6686c5c13367659d253bd38ccc59b267ccca384bb6c8089f7190c550ba838d80815297018c3037f21967cc148800424c6425408408137e04880fa19b3cf94e1e4334fe06f4f1059e45c60716491068cba603e4b8140152ebbaffbf004ee31f00a578cca099959f120552473a0a895b2acf16d9110b3522db5a74b2cbda69817288e27b5f67456474a8628862cb650a8d2008d4f6de296218f0141516513eaaec6a550d8ba2d24b776e6c3900fdbf5393b0a3c09be3b8eca5bb1d3166903a481d86b50d86b526450954d1485016db0a4322a225230496c8523341aa76632985168a3418d69a20019024008e2d43a42935084802947ad1d2d192a3a9a224f2088e24a22186476d864c55b2201521cd045ae233244a1b122de54062b8d479e83044c22163343a420445e481171b4a0184a0a506663863c78c1de48f1bd4118e5b9a1622058ea68c909033482447290c492e29a8a2a422354352a92847ed49498a146b4bb5a7a425440a184d29ca51945464658969890909071200465348435a8a72906bb410c9191e60a506acb90306a8512dcd28bad544f2078955f35aba51341a3d60a4c3a88bc8860cb1488924aa2d9124399246e411899424408d34826244638657d2cda8c848248d6a426a5035f12800524716a402885a18ca5093e55654d371a4444b8d8f161eb9fa6987a850228f9d3a41c8497d5f62cab2ae16485244e73f5a40f9b0cd3832a2028193ae343a778c28204c9459085664f8245104103bd800c319a8120110d21e866f415b00da83e78e0f3460b120822a104871d2c564490104dc00c04d0e586078c1820a720308a0730132f8347105384c3bf4851755a8dc00e09604103ff0b0830d35c41086830c72114c79c049d75611747e20e28d99969e258a00c2871d745821852f176cd90250127876d0c18d0c5c86d7dccabac5002445147c82f021071cd8a411b3c135731154a1f2c056d6112aa75b8c22e80461a68c182ed78c8081ad2559475e8a288aa023c40f39e0c02686346338e012c6c056922354456a9f2645144d0811c40f3ee480430c69c688e160032e4fe4c2aa2c0055160aa34903336430214019982f521e883a61832f42321790d2c843a321a23046308e5aa8b130a619cf88404629324a2c957e900a901580024601441d4639c800441cb51b2200483568d0206db5194b326c31722c05a02440d20dc9e8a8c8682c2a222222c52fe29274c01043232423a49a8c23224648e4004b6059ba781c3515251d4dd5966688b5a5a25c2d48c6206fb53c5bc80c8b648c4648b5a718034cbd304c8ab264d69e64641985e8208252138b90c0192669a2e4b665ac25d59a387d319c424b0275b2884454b702acb28cb51ce40f54dc5145a4009e615151015e5c6cccb8ba80649205836100480f2c312d3149b0c4067ac493bc1822e9484c74636c4648640c22b15a0660b21cd564140d20ce0892858a1390124082cbd1a010648c4a4456372323b5062e95355a6a1035252d4942a0a84a2d0123235a6e3081891616c200608be21283d744833843a5b457664b0c2033c4280290478c02209225c9c84851d2910cb2c816137280a4255e0c938cb6627c1d69e9c85a9284a4b5f46522b96178a3f64424a988aa468ca224a52c1e11ac304c3ad22260f7654844da88c422078a92888e14255075a59422f938d22a4a320a208612a41eb52ea41b4c0220900380048e1468e0090259928e4aa320318214d9f2325aaa19e520a22289202dd57c542b2324a3a41a145103b5292b914807b983088028a4231e6924eb088ea32400908a64c1ea521272d454eb51eb51c4c23001193525440a101180d4a326c00c2972002dc3124a247be48f1a4934018f083ad04167185ea883b606061652d0004b05645cac7779ba08aa4020250a942faf260c68514d056942e000036aed071fd2fe6041c5025507f0c81180d1191173ceace040d6025403d858522a8ae3060717d09c49010513cecc4069f20155962103f69556a88b1d047fb4d821a76f63c2e05ed59124233462ca8a202991270d1a2a23446e3029251d1909a0c3861aaa5cd34917035b4bb2a8844839d1b8c988512381830c30a0d167c81b185e6001cb03518a10c1c154b353878b28554988201915c5d00507194e00a1832f1394400209619c74551df1b124864182310eaa01aa5a8c7e6a548c4e10f511971893189140c2b37467b4331631ba1963206118c56a56c41e620147031009102380f1c6684364bad520a231de445b4dc6a8449434221d1d8d464644634d24455181ff4ffa1c36a624fedcd99ef146a1aea97938a73164880d8877cb03ffe2588f7ff1ca92929844d6649a56e8d474819ae7382e9d9a7629cf99578c777fbc92c8bf283e183c48f005b6c5644b498ec9d6574e0a8eab26a9aa4e4df99e652fdd054f74ec9fa719034bf3d3ffe7f2361a1f55ab6acf16589a7c9759fbec36a184bedbedee1c8a774d20fdec117d7d91dbf3874e17398b3dc33d407c01c54d53a04be8cf8d3950381a2f0d4c0692ab232018c006911e2efcd05b83800c57329e0ff2cc2882818c8a35e1f5030d1b5018e451a284adc3111850312b2910c7ae2a0a40805c21089600dc10b1668938b53d47471421080b037a1450336c4c1922f98880547e5025e2704256b100a12e9638134216792a0b73072b05885afc00e2a85ca0e64f1603ba04d23cfc078778f04a57c07951eac73f015c864fc6b0faefaaff4675fe5fce78848c104f24c8897f3310863fe3caeac52e67ff3e6cffa49fff37ff3fe9cb1fdff31650ef25c20df6ff4fff22699bb21df19eae3dd595e36a9b91c736a38e6d060bb61925fceb6a4f57a7da54eb3531cfb8725c3bae4784db9a39d5bbbaed8f576ded3a578e6b17ee6ed65dba9a35eea893195fb61958b6190bd86648e974d597310f9fbce6fb0b56a79a04496daa66be3509929ab1efeec2cab2a452abd56a2469f28a8634115dfd7f7f5b8c1fdf65deb7778b42edce93a86ab7d5bc623c9c2d1a55abeabebfaea38454249577ecc36650efad773abfa8c6b6c4c5877750c0348f6f5b0afe7f593a3521353d12d4ffdf74f7cb4fdbfb7fa70388b050ea511dd86bfa7f1fff8fc001a21546a46a55dd3be52550a9b8356264ca481123448c0c3122c4481023408c4819893262646a6aaac81491a9215342a6824c0199929a8a9a325264aa489122448a0c2922a4489022408a4815892a6284c814912244881019424408912044801091221245c4c890a921458610193264889021418600192235246a88112153428a082122648810214282080122444a4894102341a68214094224c89020428204090224885490a82046804c012902840890214084000902040810292051408c484d491591222235444a8854102920525252515246a2a6a28a4411891a1225242a48149028a9a8a8a85d147e029866a80eec91451191f97ff46d483a609aefd63c1b928eaf664e75affea8ba302241ea13102aba7a7dd9ee7a7fbd665c2f3e6be729b052f58c7364d8b43bb73bcf01f5ee75adc497f189ed06e3bc8dfbf9529db3baeefa755fbe4d4e9b769e356fe75d942cab631f56320544ea727be5c3575a83f1368eb72d6fe3fedf0035ff5fda8ccc233147c37fa7a67d710ff77ccdadcebb56764ed0fc7f95b71d310179bc79815bf74e0bac4ab69c2081fa0f7b9b91f9bc6d879446caa81f26d63f3acf9ab7a3faf6e5e277ccde26263eed58deda7a49be4cccdbb746d1f4abeb2e7e4dddd5d37a7b99b7a3e9de1aebff0b20e0ffefd6fdabe7db39e659f3f296b0a3c0aceca46bfda45f26fcffa5bcade8fe0e9f7deb9dfdff01fe5f80ffd7f1ff5bffb55b8d2422cb11c0ffe3f8ff1bff36fe6bfcdf8494523ff8edc2f3b4c02fadc1f6edf5d22b1115b9fc3f046fab61714dcdbb665439a48cfa313584efa07a52515143a4ec6e0704885944aa47e487c625bfdd6e5e29dc9d63dfdd50dab72d6f04a0e6f5ffb7b7d578f80feab3b7ef98aec28e7916b53cbe4bde1dcb05ed06f22fe6ffcf6f23eb7c1672db8cbfe969c7aa6eef2c5dcdb6665d754e4da8ddc19c5251f533e5f789ae9af73c2defff65fc7f8cadf7ce9aea752840bd97bcd9e18f086299ffd76f1be33cdfa56d54a1ecdfbc27b6bdca6f17ee6aede92adc1a78814a49ff8ff4ffb5a3a39f8db78d4ddff189f2aaeb5647e36d62a1ffd3e2b9f136d1cdff33bd4d44f349f6e519ff7f8c7f2235ff7fe56d620f5303a17877cc261e05fa7f00def67bfe3fdfb322a97757cd33d53f5e9d2ac74d95ec9a19d73ba68177e7501be4ff5fffc7ddff03dff655fe9fefb2037b3c7d9e164ab8eddee1138ab739d40e9f9da71b6a874fa834fb7e90a5199f3f725067b19cfe10422447648aec475429a4482905c533b63fdea9758742d3ced35d4265bbdb97435da0fe41fdbfd1ff8b5bef7d6bb6d5bc79a7fdee9a35eeb6e70bbc270ac4b563bb7bf565dcbb056eddabf6ff89c8ffaffdffd2ff8f3a5000a3f468c321ee491d67ee28294d71c286845691ace0c0bd58ff4a696907b924eed03256712487646d690909a9d67670a9d525a4da2f15f1d0b1c4a8168919f138231c6b118f3342b22e703524ab58c7b156c7185eb50a94aa58c3321c2aede8b2c01559937670f1225e91b5cb0257b54a2eedf82b718716b226552ff54aa91eede0a285ac4a3c86644de2c1c54bbd129f1ceed012c301b28ea317f12aa9222155a5a4ea45bc52aab5a5251e15287139aa48758947051524d5f168c75f29edb0ede8e2c29505704555bc9a32854dec8c70ac6784b55af31aab18438703b53a5630b25e55a23094745409e3c3c343439b27a29892840dc9861d6c6355823385091d3a7862fd293a28cdd06113d5dd6fe0c86ac568cca8a812ed30e2d1c5ad71381c1a6589315054491e56b028cdf8184695c888875893a24a76b1a22ae26a4646b5c8884747c2d5967880d5c5c82a126921e1c418642ddac1d545dc07621579782056221e6ec4fa31aa90633770230f375f8b44720a0b5cf8ea82581fe9afc46a3be3a55e9df9fa444a3625b17e4de9ebd7948ec82214b8004656b15230d61a0f0ac44a16a06441172f2e5c5900378e5378b05115d99c888cea143a453b9e7422aa5153eed8a6fc609b42c756aba4155a52ed52afbad42975745380b071f152af906a977a85c403259d88a61c6143aa561e9038249d88a614619b7354938698632baa48738e764c31c23665089b519d3284ada81aed984244d18e2944882399a68e6d4a9c20a6c4e132c58720e24cb1639be283cd8a15ee49a72942d8b80411c72646d647c34df1c146d629726ce3c7b8f26838910425b22a91319810f16840e9c71d57c871dc711e71d192451ceb5813451a945e144531d188c715128754abd56a45d508a96654bf46d6a3a35a13492b35b1d648b23652208a15a98a5b447b6cec643daa443cac50803b228f28303ae2d1492d1167c5a846010e898758511d2b11513dc22256c4e30a798502dc58c72a8a89f5abd548b446694a0e4f8e95b472544522a4fa5bb5dd6b63632daab51d5770e0c48aeae392785ca1e00a0e5c118f4e6a89b8239c68c4432caad52b244eecebe3c60a47694a1f5b0d361d55be7ed511c684c34634458af17b1021519ab10317a21d5cba08b9222b0564455e8aeac780f25764dd8265381c8f7680d58644f56348f12aaa443b8a8a78545023a11455920705589466103d80e5ca884705b54af4405125ab51add5ba545054c5ab9a91512d32e2d165e9aa6654777039da623456a5193a1c203ae1bf4b056415af462858882ab983022c57e4d5c7f85aba1aafc418595e6435da51ab1f430a512de2d145bc1a2b0a6215799c40c4a38b7855e3f146ac1f63e7c08cb42b92c7961969575e845c8d3cde7cb5a068aca5a034e58d92d2943d36243d27fc394189137e384106143cd073c2057a4cf0a28f106cf4984082091ca49dfdd173d6070e01b8d77396c2999e120095c0441025d07056c2972ef490c0c4107a48b861053d2474a0010959086d5185134ad8918366a68d19352798310b63a68b21415948c1041e22e2b81981cd0868481861842f5e3c5186883237c490c604b33261ca6010a809324190a1210d19331f90d9605014221421420e7a44702185326344c840842c84b6f063c6c72c09382f9889607601a110b290220426e284d042082084a005842c40500284227e78c3068416500801842f206cf9e2832ba058e2033b1f04c1e683331bb8d7f3c1173d1e7c31c5f086274b105a96de6cb1b9c045850b8ecc74f1800b06015ce125c9890cf26850c4971fc0bcd920060e9654087364a64c8c980e2e187364a8832e3c40bae2832328403022841b0f663488b094868c1209654018610c0766c66c2121861725fc392baac284243e27e441c14e0a42a8d0c30a6eced080e685346758386b410435635cf8f282182e3018195a2328862c6490620626d82041431135006143d90e6dca6cb8a10c061ccacee45056829bb210de84d1c1cb0e6559d008f1b0059c2a7a70228e123ed8f92108208e7890834310463308d1c21028cc2943440774be1411664b9d30ec1c7161041647184971470f1e3b480091c49b3c33884ae8e1208db8841e0ecce8e160833d8698c8a20926f810d1e78d132e3c61068a0d3688a29014b72ba6b0e9a142083fb71baa00c3068c157ac09881d9e08a4358fcc962461f2d8cf81307500d5bc84093819e2f29e05ecf170fbe7419b94032d4858c3f826438e185115fcce861d00c368464ac0086062284a101984231d20cc508241e5a9a626989e19111590070a3258315b66420860b00615c60638a2e476080e6a5860b197821a381172f5f6a080243038a0d6c477060eb210c8d18ca3028410c061c8ca151a883db151eccd8f3c10c2240b8b909a105b32e6544e8a201191b1865646031828c26ccd09843020e25a439bb2004132ee872c21728ccf09302122ac459618633344c40732b4bc3250b0b3302b5d0470d1d17debc40a305186e64d66cf912c38c42326031c31e3644d0607b53c38c176c386b2363cc0d5ab4e010280728dcd88e7833238e0e316cd8210b0b687ab294c043960de08431f640a38aa33831f6f870c40f48420001470e0e4120c52004129a12f40c4118e208f77a861cccd133cc20290d87e405116958d0c9204d0a5c5a13b83b4763116973c63a19a4c1496b33da4963441a9923d2bedc2984270b249a486246117966a029b1c46609347accec39248689435d9a10c4278a3e47387183f3440c1aa0381385085218fa3285212a96b6f003451578ac00e20a193760e142162668f1c19f4219002ab4458c3f81a0e022892e8610b4b4831749347ca1c4c2a014089100865918630a81190d85d1e59051da989624689845962329b41835b1250f9722232e5002a20b0f18e4e085860c60d020cd972214c0188db041d2180e3420c380a1a52c0c3184048d21f4a703427e3c20e4c40784960081d011211022c28c10102210824386909b3284681881d00b66089d2181d0590984c89c11f2c004421c9c40e802148ad25220a442a0158cae386314051a2326d224c1829d16e6a829fac1851d5e6803430c6b8c58882105194898a1c88c0d52181a32a861d0161b0eb52174431738fcc9c10a3752bce9a3839e1d9040b3c3c31c384440f4c0439c1c7ca0e10718804823078520cc085114c21063e6106d40040674bec85244187504d9f963441547407187093c4549206144124444e429024209b42596c41d5ed88063d263b466dc736676c484175ebc18360148909f233e82f2d4c11dc9a9f511a4c3483a91c112826a1034439af189a412a0f8200a4160a410a4650a2442546ce1a78a2a9cb0e248892b8ac0c2872c72d02229863f68002195b0c5078192be70d185962e9008090ae4c5155f4431888b3b4544e08c7e3822f4068ca518704868c2382b6466888b0db8b8803ce467893f73704a609069455d0c6b80b22c893b02f9d172d4674b0634e81c718973c19218884d9a4024e070bf44200f027919bb8081ab79814111202f7d70569632a82da1c198e70b89078c0c207046681be4c001920c382217c2902c942d893bb65841cc98c298da99e8c5f64b6c51b6c41618e08870bfc4165a70625d5a02501aa02e6a1fd43ca875501b5313532bab85a97150dba006a6f6a5a6412d839a971a06b52eb50b6a5c6a5b6a5a6a596a43328d3c441a220b916190609084c841e417a417a420b20b920b3210b9050988fc436a41664162415e415a415641fa21a920a720a520a320a1209f209d20fb907cc8264826c83da41e72095209320f990489048987bc431e411a41da21eb904590744822c839e410a4106410a41c1208f207d207320ed9030987e481442377207520df906ec81c481cc81bc836a40d640d240d241b720652063206720d0903f902e902a9866c8164814c43a221cf902b902a9029902890279026906764092409a4197204b20c498614813423432041203f203d203b20c79062c832320cc901b9010986fc426a4066407a213120bb9017905cc82da416320b391cd3c643a3a1b1d018c608c648681c347e317a310a1abb18b918038d5b8c80c63fa31663162316e315a3156315a39f918a718a518a318a118af189d189b1cfc8676c626462dc33ea1997189518f38c498c488c78c63be311a311a39db1ce58c4486724629c330e310a310631ca1981187f187d18e38c3d8c70461e46b471875187f1cde866cc61c461bc616c33da30d630d230b219671865186318d78c308c2f8c2e8c6ac6164616c634239af1ccb8c2a8c298c288c278c268c27836963092309a194718cb8c64461146b331841184f183d183b18371cc28662c1b2f18b98c5b462d63967128a6898744436221310c110c91903848fc020419e2192d8e4892249f24ffc927ff9f0423254f1e9b9438b6e76185690a0cb6a7232509b1e6d933a74e1c21534a0154bdf37ee9a8d4cba1d4f2c947e6b8ea74b65fe0dd1aabfcbab5db9fee6e8d856dbdb5cc2acfd36295f502b5eede251a4c87f6f4dede795a5ea93b4f8ba5bbbda75a6ded698ce27abe40a1f5bab797d33d97bbb7a77b19e7f23d3b598a511c3fb5f6ea2a39bf3c5e4ef75c2f17bc39a77bae3cb54675badad3a7e526ce9d5aa3b972ebde0e7881e6b6c1bbaffe05318abbbcacbbca5ca933b770baac3346715fd767d11cdf57cc769ee376dfd2eebbd39eaed76751bb6faedcda560ed479d7ebca0175e729eff6748777ef16783bc6282e6bac7e39c7951cb5415eaf54ad2f5a7910a37c638b5661c7264eafe0f34a803306e67aaa734ee5f55914c527afa7deba571d9905e632cee9eae5509a6a69de9ef22e1910f7cbc31bad374cd77996ece6b6eee574546ed7e9956abdeabdbddc357b4e35d00291ea97738b519c12216eeb7e40f57cf1c9d361d462744cf33836ab905f5cf6cbcd6cf7c53de1d8c59b49293c7b3d6d66fbcbd8dc5af34ecdd35d6ff472ddb3f84451cbc3dd02754f6dcd4f5c8c577bda52f17e79ede97a5e5303ab2fe3d3661fe63c2df9e53f84b86bdfcd785b20de28363137efeefa4cebabc26eb78f6f79e1aa896bbfbc0a2f1361cea266b6db574afde0b8f6cecb3bae576559d627200a5cd5272905ae9a7ab666be3c7ecdba3bae4f57f9fe1ea8a57939ff55a13daf597d19a7e6fdf1387a79643f8cf352d2857bc2a45f26b5bce94daff4f6edbd9bded40130f3fa7c166c5f73ebca359af1dd012bbf40dceb3d51dccf14885a6017b71c739d8ef39b75bd621698ea9dadfcc4b65fb3e66def5975afa7d66815d36339b2fe55668d6b6eac8c52bbedfb96e6e53ad7276e9e17dbbad3e7ae9a36d7cbed3dbd6a69de7d7b4ef9d67b5f7de60b046adedd5bb5e2bab5d953b49ad99e67dabb66e7c26c6bd6dc4a2e774b7e377ab74e576ddfcafceedb79e9ee7ca7cf5ded72f2c540b595dbdab10e8b89aef633b5bd6b62558ce284bd7baf4a13d77e4d9ceb97f7cb73fdf2ba75b763b8f32cc7fce6ebcb097bf7eecc0b9579caf3e559f3ea9425595957f5eefb0bd60de42a75e7fc9eb9caf18f3b1646256b5eaeb775e7ddb1aad375bdab19d77a81965f1e3633ae3d7bcf6a669b35ca7fbc94575eefeee9f2f4de31fbe375bbeb3c63ebb3c21ede374a3d2f3fb36aa9cbbada7f3efc848beb49e7946b121defedad7b4fb8b872b9ceef8ee77af69eb90d04f29eae39b781c0b26bbdeb132eae8a51dcddd9ab5fc7c12d2f5c2e972b3bd9ed59f3ceb477b3935a3ae59d7673db5fe5b8e9dc598ecdca7bb896bef2d6277e62dbbb9bc7c5b60ef69bebfd756e79a6d57b57ef4ee7a6d3f2f469de8e5e1ecfd6bbabc2336b33dbbb73d2e9cc9bb1ed3bdd546d35b3ddbae7b4665bf957cde58457ec9e3b7b623ba6ab2fe3a76cf7af9b97a7fceeb4a74b6a9975bd63f8ac1cdf5fefb65661b6b5bc25ae4fbfeacbf8eeaaa97ffd0275e5179f7757d3dece2dde3afb70e51768b7452bb755d7f5c97562b6d72d2f9c2fd5bf5ef31dbb952a0bcc49572d79df1abd7b0ca7572e06ee525eb7e6fcf26eae775b5ecb9d9a55d871f5652c663bc7bdf2abfb697978ebcef1ef4453cdab1cd77ba6a606568e7fdd67795aef89022dd9ad195751fce3fbe6a0eee9dad37aa3d5568e73c28eb7fef5d4767d72b29b4b27f3f272aa73b65578566e834d95ec66735b5fc6b95cf9e369f49a579f65d615ee2af5e15e29ecf8b439ed55f36e9c5eb91bad18b555a7abf70796b3bf5ec578f787c54bddab70dbb17a9e38586db726bfbf8c6fafecf9ee9df2eafdf5255578a2a82dbbce756b8ecd6ba6278fff78f817ac17a8793dd5e9c9cbb8665b318ae35825dfb7675cd3fd43b84d9ed62d2f5cbd3fb05cbfbe92e3fbeb77ccfeb6ae4fc2dd562dbb8fdcf1cdbacbccf6fe3aef1c93dddac355e7e454359522e1dd284d17a8bf9ac49ce83216ee9b3a5085578cf3bb4dd39661ba6b6a5e2ec5b6fa32bea669f58942a9408e3306eedbaf59eac230155df066dcb3ed3c6fd57e5a6ebb3d4fcb2bc374e76979b9bbed8e8a8a8a4a47a5defb55cbceb3bb67cdb355779eade6c53dccbb28afb602f5eed5f3b4bc6a2b70ebdebe5eb5a768c6d7cce5b8f5757ecd8c7d786b8ce21e705262d4d67dc5b60ee67a3d5d56316e7bfdd1ebe97a7ffdabfeb8f0365062d47ed5f2a2c25e8557ac2a508376737c2ac9e56ef7953c7cee52b49ab76635c1617d55f3769b6fb7bcac79fc492d79d54df57aaaabb672f3defc25bfb8e3d3e67d3bd9b578ac9a976b94ec56e115dbbaf3d2bc97d77cc7b08fa755789e5673e115ab5963ce2fbfbcda7a7b35efe5155cc124ea7f07581714275839255d509c3cc92dc93580c3c2ca6aa066fbeb75df9c9953bd2b4e48295546fd10b33cde151b1e89c3619661d2f07f38fc71f8e4f03318fe972fff498ff4ff5efe35183ed270986538fc32fc1f0e35f8a196ffffcff2839bfeeddbb26ad06e206510a932ea470eeabdfb71fbb3292954eb8f5b2d9b124039945fa0cd9d6751a0c6a2a2e25d53f3c6800449ab72fba2641628c6d3e76e9fb6eb9e23b340320bbcb9cbedae0a489014099905660d06c4faf2fb7a712a2a319e3eafbecabc288a77e754406e83484436b6abdf7fe7ddbd35af769d79ad3d5c2bc7f5fec0ea115d6eeb9ccebc577c97bc63203e7fff2ffafe752f6f5dd36e1f0ae549e7b609ee386f49804f9bf1121ee619ef4e96253c511407bc9d0bb9fd79edebf50f666ef57b9ed6cbbc63fbf2fbe4debd84c731908a8ae72ba67bda6dffbabc6c4f7bc577795a9b15962fcbd247bfe753b777fb6ad75db5e4f5b4f64c79a7e5f93236735aefb6f53e4075deb17be62ccf7677aaff87f2b605dc5859fd8fdb9fd5edfbd63f5eb5ee3f6e7f95eaf27dc7eeae7c973f6e7f56352c6bccf78df2f5ff09fc8b5b80885249fe45192291ad8a8ebdbbf3f3f29a04493531100a0a6a9772283193ffe8dab462a746a138d4e5d91315db3a0865bb352d362f10cabc3f6e7f39a5a2ba3ebb75e7545417887b4e375954552d09a0af543a5dedb6de6e3baf6153f5c8544aa50a09175aaf7b7b392eb428e7f6e43d20c3ffebde964408dfa579e2344aaa04f243f732fe714fcb336ff661ce7fdd7a99e7c553facf876f70df3127e6cd509698f68a03a9a8b8e5fc72717e797a77aebd742f6f09b7eed6cc96ebb4fba24e4e0bdcba8b737b6229f9f1ba453936a9a878ee02edee71a1f5d25dfc4e517272a4cf0153de76a4ca7fed019fed15f35df68c351aa42c5246fd90e25dfe47a8e4dcce6fceeddb718e77510ec5bb63546afecb2080408daa4976d47e79afa7898a20800002354955357394ff5a0e35176a18d4b06a5735dcd78418b16dcda16c535dfcd615e27b4e35af26a9aaf99eb9debb67ce3cb591009d9b354912dee6e3d9ff0fdf5644ce14b02d2c9c170eab22a96426fe1380186f44fd8f538838f1ddfaf098cd50f7eebe833a358fef9b337e40982d97d660ffff645f138fe9ed651de059e3cebb6716d76857bfbe6d7b695ef35e1ed9ad7cdfaec7eadd29cf59448a887ca5228b6af259b03dff4fa56681e1a26c3df11ab2e69f4ac5da5ab28595e5f5f5034c4a16589713ac211f0c0163dece4bf71dc31d03f1468598d986e421f6ff9b6a1895dae5640b0c87b5d5c4cb0be7c57585398e728118ccbc12e0d3ee9b2f930bc46058605086e0b6f4357114b2dbef79c1bc78785f60da0596f59585d59505c581ac2f5fc6bb7f4d2d0183a2240b0cf7248b0b4a5756135cd69327595b4bb6c0bab2946c5530ac2c06ae9c346902a52b0b0ccb0993aead27605f156cebea4916932cb0aead2e5c5613274eae9cfe1febff9534c04094ffdf9aea7528be8c33b6c0bb4ddbadd6edc21d13f233149f05bb3b60dae5b360d7d45c3e0bb6af69ef937dc79c38f165bcafb99df4fb75bbe5e1134d95f4fbf5ff5935aca198d80997899d9c9687b3ce969775d7ff2b799fedb7e38c7bd7cc5bff8ff5ff57f7ccdd9bb7965c2006bbdd2af97fdc0259e38eb946ffdfeaff6bbfc0ff9b198b6dbd771690332652f8810cd4468868230b15a305a69928c88ea15187b1a9d7e9813386008311a2213434c4094a1de23d810812861e9cd7722a33e210d27c99ae2b4806844de21d0222832030448cc28298cf82ab7e124e88f18b02559f830b2023142df83cca278a97a1888bf883952d46130a391147f47e8e8731512bc60ce31335a48974ae989167487210857ecc5e44737a2b4932481bf9cd1fb1b99053c850109d90a1c75701234df4e02a8f98444eda8b79acc6ee46cae36084d2f8c011467e012b671f6665459a98969646a6a56151a6c327fa004c134780428ab412069f0b3b514f0e9ffc1da601c6049890405c410aa451862da6d8b806e0e24dd600540c01e13bc0618400828ec8e285a5315f2b3480e8c4c5e3b009096218499cf9374bba1f82b17c181c66c42e411831ca385b1315658b228202f4ff19777ecd7ab5599d9a2e6fa79ac761f35fa96c5063a0268012fb4a9554a97aef9eb526e9facf8777adbd774fddfdf1ba0526d99124c9ff233902f564835afaaf1cff3ac7f7d72b1527bb269591ae26b6f25a7df672426c4201d31c55935455dbcf6bdedd04699517f26306d4f2f8ed5d93b7b346a68a101922240810a9a80734d4bd11d0e86b5f4b22bed1996812dd44a39f21120120ca108f80d48a3ce9418d00a3f1e888a8468ae2df18cb1f5f74a0b680f84647887e4691f8a2281211091995c61745911cb544d1481c45912c92601447d16804e089281689463f8a314a722c2a6a4aaa626d1c6b65624d14c72451d028223d91581bc92b8a5646511c8fa08c3a46712caa8de215a328168da203e20d5124c7a31e884823192200a2288aa391d1c611299a1147b16814c591cc89632d0949c8b824561d89443dc824a2d138d6a4c8a471149d66101127a849292d21bdc6affda88258239b6a44a3483ed107e213e28f6fb3d9c451d4423c1a1310c591681c49510c22428947e2d2388e631196e8631c6ba31845964a011c2120c6a091630c41241a03106b2229fee835d624b1f6232efaaa1337207f470fe25bfd309262915833126388a4d9381e5191e214298e63ad8e4b484d2291281a45d5a40a8812c7a4a2a3d14814a9c471d443168948638d1c13798ca928923f4424a5513c321247ab918091807100f2c917678845e328c6a8d9c8da18c0388e629158eb89483d4425a25124126514d1316e1929218de2ee68c968141d108f44911cc59aa8250e301a1905189546a3914824c5511c452a7180516934aa892411298a4544526c1291c42551148f88048c49a4917854134751a412c522004626b1368a4435d1c8a82492230122498e636dac8946c651cc31268948e2516d1445914a1c604c3222c5da514d14c52255c491c01112520122911491c41a0e1109894a898a0e0244036ae238168d4657b4d98852d212c5511c4551fcf1468f3e0458444053b4f83ac5043f75a6ec88028b07ec132f4071a2cf83ed58e2bf4cb073bf6c11ffc40437669eecd04e1c30c10a202f2bc4aa89090470a16505883262020e282356460b459c88d1a3c88e24918813a22122ba341288d4435feac220e0870ecdf8d46705fd54a31250e0ece94f01baba5440bd41e3cf6a84bd8e48ccd7da967ff2ab78d99cd0bcedd6cc5da0feba5977113973b2fa3f2db6f5d771f0c771c60cd89a06fd0baf58e51dd7bb75efeeaaad6492ad09ddd73c71ba83eac0de92b735edf89b75e5a9c66377a3f5feee890235aff654ff3a0e56e1eef956d4026bf0e66aabeed5bc61ff5fa446658224a7a7a4a6a60a6a05494f4913d4fa5427a8b5d6eaa34fa5f291c7e683cdb9b33d05fa30fbaf54e6ad42d3de7d5aaeabadf7ce0a927df8b45702cc7baa85b6c9ff03c9e99e43d3dcff43497d8d1c5f3c20d0017bdeccb7f674576bb7951fe0c6ccd77680060790d5b3f674bd5bf7b6edbccaff531d80653b00c901489ce630f03ffee9fa1fa118cf91c818a40926c43d6a5cb01263e87d25a8c25dbd261ec366d5bd7614787bb7ffff62120c4e52442a122455aaa922a95581175a60214d05ffbfe56d3bd09eef32e578fb9ad4665c01c20e19073e4125949082480840cf183650e84883845ce24e901b664600d306278444e3c0370254044ad2c23c912aecb0230a2b520d133f7a905f864a1a88408233455c200089aa69aa4aec8e74e1c44442a1c256260c13465832b3441e29634b418a2ac44839d53a05fcb1adf00097a74264d1971638f85383d50839ba18afc861ac4993332928b16131d609a30c054aa47046099228c61ad02861e7ab0a143380b0672cf3c4190d7b4228208aeace98c50c0008b89860c7179f39636f4ea553e6882a642ac4199b7829c4c58d403c704fb819a56cd8b3c31758153ad0613302e0c50f64360a66255451231652a10c1c217a8c80392005d189269694f04684b31c142388407c90009b2a608470368307a21a3943be7c900342581230e2982e54ba8ca152c607385cc4201bb0284c10328123488158251012d9046c2a10bba08b572700511081cc9f2003a7e86309510b3307ba8115a618630c177e5a41071552fe03c5091b80d0d59501c8807d9e2d401c7190a385aba7c9bf59d3c49d0223c705342764c13b41ea4e9c307cfc7b29c1890f046e90e19125e481788c984aa1852a86bfffaf301600a133811555d09f420b81ce044118d998e19f802c0b18211be40112977fd205b22b7c50b35b4af3e3e78e0ab6343a2358154a9bc18e0d37a43c11c07dea224d04306ee620692f2f73b048b3c08d1447e6985b8e2ba248e319c28086405b5e08197bd2b658e8d14304ccc71c7127ad8ca28a2d4e020a1c299a93c624c2024ffc5067022c6ae21c2244c49a03a05c29a91adc1ce2a3c111a0413bccb021c6e6509c1b94a01d844153a6083587d20c4a932bc24bafc083140e855981cf9b12da48d126cc08873a1f42c11ea893056f3c380401085d17801183030250c01c5a200837693a213c447d7139740006bb1cd14901035f28389444030d2ea061216dd8a61bfac3c513833a68a2872d10380de141a1859e9418b925bc300de1a047cdd9a3829d0a5caa183aeb40ac043a391c10040860862ef08109253e721c41040e4d0c89719173878f113f2c704489212f19a67c61243044060e90181af2474892d98d04d44821c4908eb32e451011c20e2174f164e893e8170c7180162a207a149aa20c042bf494969913010a0d01c7e60111ae30a214612a1483162434846135d07960a910082fccd9126345f6054cab159ac08a1178040dd0e2cb10850a593357d4847161852068e8a2d092231ca8d2240585cc162c0a3d6d50a70017cab014421245a19b0e51c4fcc18921b1b4270c2fd2823114d2c1cd1e2777c2d8d3027ae80610647e10e2ffffd09c30789822471164921c597cfe7fc492ef4966812395a85ec65db64bb42262057e9451a50e4278df167de3a34a72a67cf7c46378a3b7dbd3f2f8ed588eeddf342d16107ebeeb6c56f29e2fd0bc955f4ca637b06add81d02ab98f7bee70b7281007c411efeea7f3b4b5db1eae4fb81ffa544b76ab7244a4d27d73d0a29c8a0aecc7add6795aac1f7e3f58fd507d18f4ffa669e574deb5e28319f08e691f501fb4723ed4324c1747d0ef14cd5d2199dee8efc7edefb477f38c73554f554f5454555e288ab349489eccad38505f86e98237e7fae5ba97b7742f633fff543ab4ffff8cebc1ec51fbabd9490f64a8bdbb072db387dac33f0e4e9faabbe0ac81e3b579170cce130f7eee0df6bb03dacc039adfb79fb857b9dec683976fa7e84679bbea7d25f89139be7a1b1a17685cd8d0dafc7f19e56e8d85b3cae0d5bda2895da0e6fdc826e6e1f44b0891945f9f45ab7629af12de0684574c781bb8a6e6a11d7d9edc0e687618eeb0030e1dfaa439f34aa0431b32dcbb1bcd9d2716d3c1eccb309dd8b6401d50d4de5fae5fae43925cee9a3f6e7f5560a8ee597cf39e2fe6e15e2fe5b65b253da71aab779ff07d8129cf9a6777161515188a3bfac64bbea80edefc46ca9b263783de4d9bffd29731d727af727cea1fbffbd7f9f5f9525e51dcddb889ca416d765eb98f8e6d39f4f912c51dc59d6777b5e5e085ef8ba2b89b50d9f22a8a7b0e3f14f71ca67c785739ce4129d5fbe6ebab5aa33887e2fee3568b8a0aecc7ed0fedc7edc97130c301056a7e833687835719a60bde9c4371c721874312eebc1be5c7add6beb797e3b8c72fd727af4ce9d42f37cf53df60795ab5999e29bf01c7bf530f37056f9b3cff4e4d6154daacf9bf626dbc88e9d44ad566ca2b4e57f67cb305da601b20afcdf46bf715bcb9ea3c2d5655e5b682214142a6afced3f26cc8d3a60cd3716b835919a6135eb15cbf36fccc9bd39c36536ec3963653ceabb6def73c2f3771cf97d720e5bf86a8ffafe1bf67d406390d3fd0302c85bbaa7ba5c18b8626a0bdbdfa6c66d3a7342f9b323652b8d834fdff60539b41cfff7fbd6d062fa56e861fb7c119847c69dadf0c4c32c8d1552bdc559d4d06b2d294c14b061cff5fc6d0a7ccdcfe9cd86230fbd2c6f003665c0c5631d89e87e5e82e6feb253afbc3adf1629ad6b6c6aa34efe665ac33b7cc5b6d6bb8b0874d0dacbae360f0f3258a7bc5c18086da200c655dfbea79e26090f2ff250c535f9af7446d90c380e3e74bf50ef7829fe0ed7ac1ac6e5d75ba6a83b7eb05b2ffff17acfe7f6b1df076ac73c18f4e0999e5d26d17d05cf0527d59ef2077418a0b53a80dba60fb17eaaca64fe9cb6ada7c99af98ed4ab6aa9a32355effafa6b600e8bf8535ffdd6eb5306cc1abe41d73fb6b01c77f699ad9b200e8dfc6c29ae197e76979fba2fd7216bcbe64a12963e079e2d20c4a2327cd99bd27bfa7def502751ab234b50a77f70796c6f65f3add73677f649d9b2ac768f294be8cd1ac41a3fbd3a6576ebd3b3438ead85f306333d5b6335eccaafbfd819d89fa2fefd64061b69ad727f39af677e6ff7f649debedf7bc26d60a72fecb6c956c55e0ed2b90fd9728fe71fb332fd0e67a7f602b68fdffed3eb2e5d5159a4ecbeb06debea5429eff075615d688f1f459b90fe0ed5b2a947d9931974d05afde69abee4a810bfbe3c0dbb190cc02ab794d3c76795809f0760cbc1d036fdfda3d13efaa388ac1c82c178ac180b76ff5aa9e311712b2aa2a25f5a967cc65bb35f7e63d275f777b09af58d5171515d8dd69efd677cf6b026fc77c5f61bacb99375855d5733de51c3f8085835555682aa675938c81a6adaa4f55555bf5898a0accdca2a202abdaaa4fb633b4b3b2335d4ecfa61e88edc93bb309d39d1f8ee29e135ab404b412cc4a404bb02ac374b7041c0fb4b793d02747429bcbcb74bc8d84df3f095665988e84bad39d9941779bc1f1363368ca309d50efceaf6906cd9da73533f5dc66e6a80cd38dd0e77f8436ffb611bc7c19a6bbbcad7b2348f91f21aacca0ffdff69ebc3272ca949561badc7979d996f9e5fae565acca305dee6eb48ced2feefba27aa364007dc6403272de0679ce4606cd97613ab2cff5cbc96ce570cebc1bf36b56fd3a7e0078fb564e7866ade4667c9af69a55f50909ef46a9c25d9ead4ff5a967cc0524482a3cc92c10783bde77ec0b78fb16bfbc0ac94585603d63ae8b0a7bd5e5e1ed5565e6cb3907de8e71fcb46355e69692aa8e81b8497d32af99537d65bb35cdadacabcc2de0ed5bc0db71cebc39a8ab7ac6409c92cbc31b9bb6104e5c08361c087dbe40c0e0ff4f6b376eeb8ee2cde3574927bb5d555548b29090e92baf7d73d089f036404505f6ff3ddef6819f0fdae4b23dd10f2aa8da4ff635f735f3edf5f4f559af1cd4555548b24e9be6ad9eefb6a892ceaf0f9b4ea8a87edc6add6e3baf42c2bb51f8bea6bd5aba97b73ad768581490302041c8ae993bb0f3ff1d60d0b17937cfd641d37f29dcd9c65051058664eb25ba03f5eed9c6a060f6ded6a9f5ce36c6ea53ce71bdbddeb58df9ffb2e3dd35ebdd37c87b3acfff8b89f35fee9b83545462cafe5fcc6fdf1eb7419c4d4c9469811df330ce5636a8ac4ec2b3737bcfda6d53c69599fd7ff974d6bb35b03e655b7b967777d5bc28aab75926e54ba7a66adaca8e4edc735acdbbebdd092d304c9fffd2acc2f34c7b29afdc0671ff3ff5b630675a7877952b795b18af9e2d0ff7b20ff35fdf3ab883f5fec0c234756bd62b34b3beb271e0e74bf3025320ce1858efaf83d9385863efb6601c78296d1ce8bebc1c57301b07b572fce3d9bb6bbe7757cfde833f30db0679febfe41cdb3638cb1ae39d6d03f4ffcb9eea2ab4e8797ff56e5b6fedba6b83a9ffbf59df1f986d03a6ff2f53307d6c60cafe4b13efaa2fe36ced89de1dd467d5baef6a3dcfb4721f26dedd1f18182b5feaae2a30243d274082a4661598a32b01eef36ffbd2e6b45fcadec4bbdcddbfdbed18de682e687ffd8bd5ffbfb087730a046adeff0ff0b62f01fc9761ba8e79b877cd9c99d35e95537d6a126e8c925df306edaf9b1aef8be63ab7e779e29e717a655f2ff306752e6bbd51b26be6ad27e6a97fb9ac73bca3f8f2eed6bfa0284544c400272922a9acaaffc70d911a7176878d3f0069879894c58bb765c1e26d59921020060d73ec6998103c0d9381a76126791a2690ff5f8a2183090f0978c43c131e2ecf8467ec99f09c358c988cf8f14c475431d9419fe98822cf74c4d3fffbb85123490f5f23090b5f2349075f23c905ff7f2b3ac243e599f0783d131e069e098fd533e1997a263b411ab61935accc7c0dab2f5fc34af835acf0d7b0a2f235ac9a7c0d2b24444c4a7a3c9392029e49498ea2a21a3d9cf0357a00e16bf450f6357af0f2357ad0f2357ab0e06bf420c1ff232dd1502281a7a1c48ea7a104d3d350e2e869e429f434f26cf134f2f8f97f25a41a709ebe069c02be061c00be069ca5ff472295984e60f24c27543dd309479ee90421cf7482d3339da08306139dfe4c7476cf44e7c933d1c17a263a446c59d4bc2d8b096fcb52f6ff4c4b454c76aa3c939dae67b273f54c76843c939df299ec20f03366301d81e2998edc79a6233b3cd39135cf746485673a72c2dbb268f0b62c5cde96c582ff5faa41c5e76b50f5f035a8d6fc3f138d251be5d3db782af436ca1c6fa34c7a1b3f0ebd8da6194c544a3c13d59b67a262e16dff4b326c3cf1781b4f34dec613f93614f8e26d38f1791b4e81de860250fccb3812c1d738e2f5358e34f91a47947c8d230b084003cd99a781e6cbd34043a614a3069c375f038e0c5f03ce99af018784af0147ccd78003460028453ba6f801208708655f3658e16524e90c489d3effff474f4ca0ffdff31d33b18eb2ef795a2c27e769b1c678447171b271c9c18506975a20db163f4fe8b943440e3368b9d1429ab6c52c4c05635b803ddb58536e0bd796ac2d5529145ba678b7be318efbed3cf34a70ef5e9235b7f789796a2d2d7dbeeab6defbe67a8aea6c5a2ef89b35c7bde2b43e2dd1a2c4a6458779da6e7b35ebfc542f507f6933e539bd3cb528aa75eef98edd5cc7c07b6a33cd756e7bb93b8679bebd6be6f6f5f9f0eee7897bfcf614056a5eae5f7e6fb7269a7e093b3e71877277f60a05dace2f1083e1b678bf9c93816d2057cfde261bc825e4d9cdd3c0abe4c4bc9c6aac0bd45828fe71ae1fef820977caed7dd22fe7da4cbf9c00b7f8e5e5dbeb39d142f1b984f39b81daccf689b00bfbc53cfd15657f65dd7b7a32b93e0bc4777bf930c7fd4cb9388ac14eadbd84fbf6ae9b70dcc56f7a056728bcf7baf692deeb126e7bda2f14ff78509fe75d72b7c6ea1c37d9b7eb285963ae8b3718bf57e6897f58d6cc77dfde7d22b62df03ef18175ad9ff832ee3a0ae6f8bc1dff1ec81a77cd7579d9e2f3e4e7a9bdee189679c5b27d92a1746e978c69afcb53eb4506764dcd757bf66b5f31bdafb2b818b76077098ac5becafec5301cfc8b1bfc8b6034f8173310b778f9173110bb5cf02f7211b7a4a5a5a5a5a5a5a5016a62460e3406d07fc204010051c113f5788e9c15d9c0ced4cb39db53c1106fa4bc9b3848287959f2f3318cb0040b0c7cfecf0830e6461822db9b39f2c6ac0a2cff1d0032efcc1084d67f918ae106739fbd962fbeb0b05d4cfd0446c89e28a3baf31c501c548204d83c1080ad21880898f33d14b80432dad5d78d01b3004b13300fc11e2ee860c01bf4502a10944105627d2fb42ac8a34e9c6f00864f21893ce7990ca9e1ce55076a1eeb2bd48e1e4fbf401212243912b8fa235e4c6c71c404fa22746878b3400c805e881620597cc15be2a57c65d072809ebe9ca010102b74e1f20ab80953351c63be130235f0340fa647c0864285b8d88285ef916b90545468e2792c1902184505565fad72ec48a00a0e4f80945ba13e6fdabc0060a0307a20b23ec79e3c32b8a0078b0f608914dc8faa26fe06107c8ef492d81e00dd380645e8f336625819ab01c2f335e820f102173c424f03851b44e8a8e4f0b70c6c79603077781b161ad698b1b2c4cfe89224e3811d6c2fa34cf5208532023e860e0168315507f84b5a1840c83c7467b89480f0bbbc1860a8b4232804061e3f9fe403027e50074e1826f1786202bb1a3e9297233890b285e68f067d0173451a3c7f840a1185094d8c86465bd82e00228120684664508833f49802cdc8a8ce0daf11005915993997649981a215197982fde82d56447a0c8812a706054fa4e5022da810466844503d5c6080869f61ad4f0c63c4806133ac81e084191a57d6a0d51cc867462c90fa9a0d800fc29218c08a34a24c9530b644e9439ac1d98282105e86e40e4a92d893b44a421500c404a73d753c04a88999f79d8d76c864902a81e56c5c215011e9017cd0460bea8811800a297e9c12630511aa30a41b877471aa4097ea46261c4fca08d3acc42e5298a2c509351493589292eb5256620e4214987213b446344184c068cc88a1e80582423f6ed012255e713a21f844034391ca0356419af8b0894b8a0040ca53af4c0c524109759ef8d1893bbc2cf0b323ab23da888829b1a78733f10be811f61b327c4061541912436ef84fb87921852142a08f074a190e3d32987a393728217b02407d377ae6c8204a31f531c4e0c419d181e19f899a8281244678bd99ae261248c1ca790f465e17322c69fa2f57675bd69059f35b8cae24104083b39f406b6c4a159ba6e787f8d88034d83cd0000e0a45f1c108df5b237e8d1933f53a126a68a1c120db43e047245b02a8cd43f142e54f7d53e7bd24309a00cf973bdf409b2120f46842c833a9d2ed3f15ac79aca32536541083975fe0460510890664fc91072c20c235c5145f040f16196000238a17e205041f649246782920095e779ea8f36596142e1a222bbc023c38c1c01310b4bc9302365c01060a003c026e648803029a96efb1b370c95f58781e0c78d184a11a515f9514090508ca7902a8c0f1624b12035e80b22a3d6ea052fb1c7d06c001c103810f604bac0a18e6f93784e8a14e9101623c003b1ceae814d0f136668051430215be7c0d3b0b7cb91a14e469a85005c8214ce36f5f80fcb95a5cf1b62c3660310b32fd0c0cb2b0804615315ec60854a0395c59e263ece003153abc78f24b7f6a504190510abfa400177c7297ec95780f633a2011f9a41fc69c10b185f94906f8d028908a79a40c0a49f0c29e20fe88d009582835d0e68faed84133008bb4370a6494440716b47923e1106caca0fae28d8e5a40fad123f24524503149808d0a5f44c594646a088d27d2a3049bb42f5a9e688b140e42b5199e08ea8702acf89caf39b125dc4ee8f0b510d00cb4f84c7dcd014101a82084125fb37da0230f19db9347d0f8d18121cd932200b9c090929427773a00814821ed49282d5480e030e1c7342eb33354a8f9d14e20075ce042e8c73359beae1e757ec442001301a220f3e39428714ef072e1c7214208ba8d807f649a12c300a5265eecc2092b2e70007931892c1580e8c1f7620e566c94104190174d10c204a4818417bd685083164594bc78258a065c08b0f422952c5974d4207b71891749e4a912be180405233619f85edcc1d7a09d30f6a2ed810c7448f1c48b5fd5844b0a41feb7c0a1c6091e0bfc3f91074b861268fce3d15c4c0da6fccbb10383152a18f87713e807034610f41f0310587469e4ff4c16122f46f2dfcc4eb41d91fd7bc074b37ad4f8fff22526cc09f9bfe506902f0cadf03fc103e9093ba4f9ef4b61f8c824f90746e1996394e6bfe7068b112e48f8d7a5b93307b5f20f011736098848658d7b7aea2faed1aef18e8d135da947cc5bab2512e4c4dbc6ac440b3ef81d2123c48b1698993a327ce1275aa0a70d550b4854118b531e23769cd0885830309b2244c34fc45248ce9400467811871b7815a9e2d146cc920407111d9c3ca2961b798660c9d346dcb2834cc899214022176c16042dca947841188080f0d1a18a18f8a95269281c891ae0d648d5aa256ee0a34fd40240acc4b21a8ea02278004dfc60865769410c392299def08719601ff12c90d6939b2ca6443485fa28b047461d51863c5e0984f15526eab0c5a0047200a588440881e664243814f91cf2d324e5cc8fe80514343e8232f4196f6fb41000214e9e3108046807d0b0449bb1ca07688f3b837e639804d018d0850cad9108233a036a542b3280296878000132458eed50678703487464155f792abac44b2d8d62aa80305e6b887880a111f00204798804392156406695bb199f59e780b877ef2e93612036539b3510df9ddd65bb7d776777be8cc5f2be639ac9bebdacbb8419279631cff7c7eb58eca242302199de5e6397d299d83a16127f98247143d08730fe5ffc7245014e9b08490bff2f6ec040597df49084feff514a1146acc1c1078f98ff27d72c6900a603062bb6fe5ff40ac44587a503c864f0ffe414f4490b7898d2b8f87f118ba0162a15980c35f8ff1a9a13d278d5c8414e91ff1fcf2c10040f13c46a081a71e2a144c31797ff17171843c549590666dcfcbf0887c47204037724f8fdff8881014c254071801043fcbf889e99a00614a4fcc1f1ffe20c2fec3e869b156efc3f29288b086450e3830859fcffd8246b0129bef8f8f2c5ff8b452c19e608624d093afc3f69234c1d2d42307363c4ff1791f960907887ea90d5ff8f5108124341a110a028f2ffb5323a23117e4358e1f3ffd7d4f9c73575c6288e736e7fd5eacc2ddd982465c6ff0f40c4fd23648480baa6ce5019ef308ae32afbe5e9cd6418580acfdb81b8eaea53d7b91ed13935e974bd63e0bea8797fa5ee1bd51b456dcdb6b7557f54aa275fc6bf2eccb66ab3769db9e6aaa579cdcaf153d6784cefec03b5347959f7e0ed55abcbdd9dd0024dacc7ec4d77d7d527f3725c6ded6dd56aebbe9d639f7083e5c6ee46cbcbeb357526c340ceed0fe5e22a75ba6c79dde66a3533ee55dd6b988e5305b70eb2c60c2a3b3e71b5dd2a19831b23665079a262d0c4f47f6b6e3152654f94c911eecc6c8536782b33fbb2e2caa4bc509f68598d304184a9a0e86f618261bcbe34efb6f54c4f6c31b0665cd17bc50c08d3e33940820334bc72ebce4b399052561eee9c8326a0e5c292b2411eee036f60f612e02f5dcd7803ab6025d33b335bbec1d197b69a17cc9affaf5b5eb82d30e803b599ed4ef90d4cd4edcba02ff68b4e67ae2f516f77af1a34a101061a0cc9000b6eef2f586fd5fda23ce37d2fdfaa624eb0bc9e6c2d3c79c9fbbe63bc6bda7dcb60840c18f0c28597355fea5ecd6d7d779ffaa7e33f7455f78cc57876273cb3eed9ee9eefdd3fb2ce3e9f3d7b627acc0bd61f0c7cc0e00a0604f449c2cf1f3ae1aed61eaef7d43c6b1eaef31b4cb5d09771b9432ce3dad336db2d2f9ce63eba98fd97b72e5bef809ad7e5885b5fe51da7f647762f6873c1efbfe4616e773578018e2ff98d8b1cde31172fffe5dde95ec6ba8b8b16eeb6c54fd6c25dc63d5f734c9b1a6b4b9c2d57b6d492ebb3f27e5aac5a668d79c65ae4648db50879f99a5a6ac99d6449cbb2a6d465e965a9ffa54e8c673bbf27fe05c18677807ccb0bb7bb0dcd0cbdfe4b1f3ef24e6f2f2c5c7cdfe29d67cfd3725d1518927e5a5e75512118155515b75af501f37482450a96a9324c7781586cff16f469f36f8119ef668194ff374f9db3a0e9bf0cb3a07777bea792aa0bd45cbd4a6beb8dc772565555affaf2e57ce9ee9a668e5bdf8f5bad6b6a2cde25cb32712e7833053ebbab376bae09ecf47485c271930978b687db178fd9fbe3d8dcb7ff7cf89cc0ab0cd34d10e5b3bbbb27e8e95ccf7af77219e77a7ab7e67d515181ed8ba269ce67776377a3a6bdbf13dbeef4559fa23469fdb8fde5244025980aea2c010e611f219cff07daaef34c7bc26119a613eab699710363fa3cf5366fb7d734718e2c07b2df975bf72db2a99dee76aa6b4fdf82803e68666be6fb40d0ec3cf53ec2edef2bf80bde1cb4b2c15b10c797e6bd8d01fa726ccd677c1b23fbbf8d758d45ed9e0e4ae57c999699d972fb4ba54099b7172abbcd58ac2bd1bd943d5ff4fe7a509fb5ebca3ef565ffdf611f3e2fe672be6efd548584eca25ceb5f8c777f3c5ecb30dd1ef4ff26d663bbcee7f6d926db5e65982eb7a1deccb8013363b12a73cbe66e8eebf3caf04a14eaa76c8232f037d44b03d268ff601afdef427b766c833a2afb79f372bd86cc02739efafc9f2daf5a609dae33d0cbff0502b51e78f43d7df64efbbbbb9af569a6f7ae727cf2fed1b4f6cbf74d79fceecef57936890daa73b9161b4af9324c2716257664c5899de3760937f3c5bb77b3626605b5a295b19f7f5dbb6da00994ab5c9612dc13265e50725a5f38ad9c141c97aee6adb9f0d9eb7d2500c35a55676cfb49f003bbfdbc645ec6fcf69bb29d6ffb33fad2b76dd58f5b2d7ebb70e79393539f594e7dbff759ddecb391bb554e60578c97efc9f365eccbb8a7fbb257ff0235bf802e5af0e63bbc5a6f0271e69a2fb94c9dd08cfad2e96e0d6caac26ccfd362f1fcfcebcc43fb72eb0a845756f2acbe14daa0b03e55ddb50354776675a7fbbfed14386bf0f6fac55b776bbd48e5725667ed12ee670acc717b8118ac8acc72656c813a32ab239203842db05bf4ee1cdabf70971b7eceeb4b316e73b627f346d02fafb808c8fee222d0fa8fa009778bc0769784c9f917665b4bae30345f72be4b799897fb03fb8569bdee0a6baad267eb9e456bb63be5f174153965ae72564577aba2550547507f511944258f508c87fb179535bb9453e9e0ffcb7b7b39b2aaaaa65dca7729e749545455955bdfdd6710907d19a683c02bdf0d41d3ffefd229837e4a9d9f82668a17dd94a9b7bb73d34eb1fd779c5e91e22727052dd72f97725686e94c2be54aae771ceca7f5ddf3c416787737589f9c6cb74aea93ed5649552f87fa508d771577aa62a03eed26ddcb5bba97b1795ebcc4dce20f0cff01abffbffb1e79c056398e8216e5ecbfc4517eff258e32f555b8ab516c5000056f17142868fe6fef06858cec9a158a5729bc8101fa7f3039ff25f7b12f189a0723fb2f4d30295f3e013bc2e6897fbc8a6f5f387c95506edd6daa85f549836161c7658d4d9cfbfa6aca75b2fbf5e6b641fba4cea3793294f2e4c951bfb75725ec39d557a999eb36b775b73be539a0553a99b77b0dca537a99fd974efcde5e35aff522f3b2fa2fefeeddbc6c5f3a91a37b53359da0f17273f22bcd9b93225d7ef4597bfa945583fabcbbaeb22eab7dbb3db9fc3ce92c18179b7f2e312e1ca8b0a7be6d6b933aa5d3d678ccfeee8e6360e92b6f131aad7715ee2aae49b089d79716d8c43cb5d6a97f0d00faf9f0af6add1b9063e6cb1b18e6db805603470ce4394f2c06c5009aff52c71920fb1f77a3570c50d9bbefdd0c6ce529c3745b687e8becbbbd662eb7e5e40917e3e926dc67cf25dc67cfdebdbb273c4fab3534b57465bf3cdd372d1ca51314e7f6c6a4ce7fc9ed8dc999ee38263ade71aa9934e16e4bea9826dfaaa579979c2d91f28fabd9d6a0ce60b556dc92ffcf5af3ff5952b6ce12da13e5d8bc29c94289d997e6ddd5ad753f6fd02af12a755c49d497c2f3bc61e5c135636da55f61c51a9a58521eabe909d6559dff3b667db82b34a7e5b7ab1f5f7215f540536b1ff781e3c25de1c84a1dc769718b4f1c8eff1278af79b3f26325a7b42a736acad6caebcf0de501f3367902a5de8ef9ee5a25e15eab0f9bc2f3b4f74c77aeeab45ca355555b482cbff83cad89b19454016fdf82828477a32c10f565986e81a35b559db35e6e67abc8fe3bceb84a8ba7fa4cd174f3784e73a669abea99ee5cbf3cc9a0d3e6f29461bacb93acf9ff241b775f1229b98cb5952453b72435feed8e63f3dc5090a84122a529a7b5f7ae0f49d39754aad48cbb1de1e148c6be7d8115ab96376b1ed77132cb75448b6a10151a5b75af54625ff28afba2a2aae2e16efb57e5b65251812191d2bdbc150588113423666fe4971b33a2c5efd8cd88cd3796bb4d4991bbbe7d81be8ca756d85591e9ab1cb73a3b3575cd1cb753b6ff227efe7f1d078ba07deec7ebb6c85911b2ff225a45703cef4644ce3f9a1b91e13f119d0d128922b2f5903e43bcf07b1ba21b3225840a216765980e7d2138dfbdbb67de9eea9c896def4a80edbebe8c795b2fb9a6060631fb28417ebe7ab7f51164070152e7bfe498e36e4086af812491f2f316c8713df2e348bffb4a4971f9f2442bc7d5eeabbb6a291581d451b5fb3e5d7cd1a7a812a29a44e1f85278774fc27367bbeeaa168f855579a252a59650729c9aea863afbff1218bc198aecff6f5051a06c1d9bdbf23836edbef6564e51967da9d3dd4aabb272db79e5f65792b71f6bea8fb212ec87ee47fde7f6f704482ca73f5ecd16eba9ceedc94b59cd7a796a9f9aa4287a4d05b25080849b025aff2594addcc7cdbaeaf0fd75a7ae8cb9743a33ebab7b79936f6b2c059a6cd0eeabc051d9bffedfc9df1258f325c7c1ad2b2e01b2af5b0938f9e1fba2c25d159e67dac33f9e66bd4b9dd0fe4bee54f6e3f6fcba39716c9fdc9afcfc9737a87f17a87913da7f579359995633dba60ebc40ddf4c3479effb26779e515bd57ecfe4c7bf381562af151e6b328afbaebe6c3abd465cca5e3aa25968f032c5af5e3757b95355692b7381699e5a2a202ab02124409cf16e5395fc6c0349b59ef320656559959ef32066edd79b6c77b777b45e1bdbbd12a2041d29e2f6f5f2f24a8931c99051ea0f507d4b307a01e6d7af4f0babb47f5652c06e8dfcc7a97d35cd06ef3d771f066005acebc7bdfde35733703ccfedf00f4cb309d015a390370e4331dcb371e7e3206de78acf9ffcb2d8fb2ac773f1e56fffbe674e67194dbf73c356f879fc7623bd06e3bca72fdf21dba2fc374c2dd8ea91d369bf5ae02fac73fdeada2d9e0697376df0ac2e7508b5aae7b37d815ee196baf2776df1fb79d57fd3a7a950873429ef5ddb38a4311cbe90f0b8a2f631345535e554566b9ea93dd5919e7aa78378a89737cdfaec76ed76362d93e11cb7657993702d6e85fb0f67415ee081812603500a037f10073fecddc06d0cad8c78fd707a803fcbf0072fe376eba09704600afffaf02e0f8ff92e39b0e3fff655815b16c37952a6155a854a9b89b8e35ffafc77480f99b8e056e39fcfc97e6c6bf2ecc9a77f9c6f7d7cd6cab92adca7de05d35f12e071a34d53bac0aa75225c7f0bfe372e852bd99dc721c559b6eb481bf05b02680b22f034003982a79df5db3f67a192ff9ff227fc331e84b1c794af3eb86c3cb98e6dd704489dd701cdd40c3b11dbbe7bddd18be1ebbddd09537ea693baf1aea06c0a02f85e70d00343700c8feefef064054ce765737978d3e637adf6ca0fdbaeeb251f65ff22c5a33464d13efaa0dadffb751ffedfddd6c58a636159875ed3a3399fd97e8bf65d22a99eabe1c0abf67bac92c30b72f8afb1dc3bead7b35e4e4f45603cd580db21a5a5fa38af1b018a0ff7ccfd3fe783934cdf69e3c395f86e96e34d0fcd318feffa939c7260daf5f50777e77349a681cfdede627a7b75b9b2fc374284f79eefaccd4caadcca277e7ee18b6c15fd763b97dcddb6dea85bcdcbed972371b1429caaf18de1d9bd9f2ae98b5409e23b340de8dc2bdb899710326be32331613cbf17047af1837f1cecca97e223c4f0b263c4fdb6d4d5f2ad932bb6e33f2fc97ba03b1e6c2dbc08cb3bbadeebacd189655ae5835eb93194d33fecfd362c94073f9305fae7fbc60c5c990f2bfa3e26444ed9071f4ffb71868284ef5941865cfeff6e98d567c8b21e56f319a621cfddf96f694f59ebe8cc17837ca6da9ecb4b7a59fbd68e7b7252b311eee39e1528d33d7ed45ef5652b2a5bb92972f9d72da54d1b42ae9febfc4dd942a9479efeedd92fcdc92d092cafeff9604e5cbd3f2cc4c76cd9c54910afdbdbb77438a73431a964ec094df7d4342fa2f3bb767d69a57cdb16e473fdc8e2ef8d2a9a9fbc8153d7155554733ceb3eb6c735d555d483ac74d2ebe198101dbe2da6a9253f204a795cbc27a02c5c957d6131bbc192d6024c0736c51e1ee02f597aeea5e75badaef57690a2102c5bc647849f0e65bd1adc8ace7c4dca2a2aa125aafca2d5068bda8a8c090dc8abc1e772baa7a0b2dc74537a23a3722b32f6f44dcc78d68eaff561bd4d3f6c7bbc094f35bad4e69de5bed6cd7d09ad798c6bad56ccfcbf5dec83af6469addc8df973732aacca98ffba858a42d63405f86e96e639d4781e9ee36a2c9dd462fbcd4ccf836eafe361631b74c6cd19c7973daafcf4c773cc713f2aaccadfa840488ed89754f9e10cb121902448b8a0ae5e2f0bfccb8a7bf6ea2d535abae80bf8938bee26e3f4877fee4ff6ffcedd17ca9a3a2ba5f5c5bc24ed6408e4cccdcdaf77a9938b7ef457159fce6d2f2fc97419dd3ccd2d2b40e0ddaf6f2436d0ea1bb435a86068199a73684f6a52143ba2f0d15c282eb423114d2e97cdeaf5a0acffa749e97db60bd857684f14318644ee5a9ed596f76528661f5651834bebcc08e9dea53130fde0cc69ab26f6c429d270e8281c1c360545c090d7a42673c42bfff7f425183fafc97c2337873e578909aff41130c4ae08b3ce505f2acb16f6bbcd11abcf98bb3f2fc42caffff17b5ffd2c9977193576d62f3220a2fcc4a2f745e4c3d09deec458c9c796a414bbc203582221084e3bf74129e287af1b9ad3d4f1ceca24f176dba2083eaea22807ff30a4f0930cf9d5a73a1e6bf4c33ee59f336d9cd5c48792e627c29663b060b5427d0065feaeed63c5dc63e9d2e9057a002bedc02d097e616685ba4d5abde5fdf620856955354149122437a4e78dfd6ab3ee1eed6583d5f20a03aff2520b3ff7fa006843e20ad125b1450fd2f779dff2fff0c4fcded1faf3f362dea6861f65a5c314fad058e5297ef2fa8dbd797f5598359002ad1b2b0e0b45d67a1f559e0f82f7f3c8c451d2cd060a1fbc7a2e987bbe2079418b73d6bdc15e8ff5f31f5bf35ef0a1bce0a39a7d65ea61565e5b667cab342ebbfecf9660c04e2cab199adde56d882b78a365fc5f0ee2ab44a5c15f5717eb0f8d4e7a78c1fad3b7673fd753f47d6296361138e0ab41f59672a86af53938afadff1b667eabbbbeecbb9bd95fb3246517bee3ba6ab0ef63b96356f0a3fff53c829cd7cabee5394899de955ede9dac0dba6987ad33eb14901c897b11467256a93c2cbccb7deada5688a62d09751a0e9ae28ce44e1657927bb193745d1f4ff358aff87e2acf3a0208322eaff77bcfa04a027e4fcffd727ce9ed04fe0e0f8d779faebd5a95f6153ed3adfd37e3951e7df8921aef7b4dc3aa1d5afb08f9f2f2ff7d1c7ecd4daabf254df6cabd9e7f7bffb4ce9dce7dfc7078ddbf8e878363e584d00fa92877dfab4959bb90934656e027de1c61cccd6848eff9cee2660ed7a0c0bbb69f529b675d0dc9a779f985b62dc828971dbefd6bc7c7f4173eb8989735d8f619409ab6702c7e7740f20bb47ceff9e3d43297f5a9edbd374d32b7bf4f429c3747adaa4b9321daab7a9672ad72fd77324ece1aef3127e9690f35aa34b9c9561badce5f6c7db29ba44055f86e9fab6684ff505e29e13daf33eb93cdc75ce5d5eb663a6adcaa1c074973b6df0e6bbaf999ee78977fb7ae5c4ce7467ea7c735963dfdd7d9f969ba7e6397eda6be2549fe7e5199bf69e5bf3729d6fdc33b145cd7c3bbe12e396eb6e8dc57798874fa145b1b2c6396edee0cd79a6ca3cb64fc2cfff97499c7da9db5a57817a5b5b1252fe93684242b8aba7c521e1c5e9b4a6896b4242ca97483421b1c39307cde321d3553c4dfe1f4f8f3b794af30a7755a7abbaf7bb71cfb7f28e77c6dd4173e787ef58e95f5077e7e8083fa579041a501f718496115a1861e6cbb8eb2ab73f0cbc298752ad111c1b11f5ff570c9f770c9f76aad076def1d84eb99d333b28971d3b75df5e67d0d7a9f3ff5fa7ecff4bccd39cdb9aebe87ed4d915d1a7de5dbf9c1791411144e8f4e1641618bcbd9bf58fde79f98facf3be26ceb5cce7ce66287466f89ab518cfeeced36209b7cd779777bacb8179995b54546026a6635586e9e8d42fc374440c7a22f21081e6892023c28b88a6bbe70cfadc1c39ff73e60cbf0cd3cdf19ad334e7e883f6d787c833049aff21c8c6f06973e8bd624378fde78688faf152dd87502ac37439bb3b5996dd9dec56d527243cb22c9e3130c7f154ca4f0bc4bc6be62b81debd1cc7a7de0185fc026dd6ba199f792bdfd3dca2a25a72778ae6eed641a0297b57cc02332e082f6f0bc2ebcb27e1690621444e9a1c395fdad4877740cbb119bc79a7a81c1daa36a834efeb26b220051942ccc0c80000000000a3120020302c1a10c98452b932cdd60414000666aa5c9a509f0893244b6114448256190233000000000000001000cfac9db35cf110d768d4a827dd93fb8019f68198fcd9a9304fecb53cd5288bf79d70be24febac10a2a7525e7fa1e19c7f7b3a2b29827e0041309795b7a3599b9c2616049fce02bf6333962c6f907e4e5b8bc567c57d30ac943eaf83e4fc8079108e1ba612fdf642639ed3eacf49c122b03584857abc04fb613f28b6bfe9daa0b0202c142f91d003b545252ae4ed94fbe9f1269767a1ea9da2a83527783b5587aedd3ccc34fe456c37691901f6b32d904a926de6760c35c3c03a29663fe8f5190e89928ceaed7f35ab953210ad871874fb03a47fa2e951a49f4be7d67f505c03742eedac0e4db1fa76944a83bd1549640b26cd620f65fdb33cc862d214b6e9e2cd48e8b42ec7f06113e41d7c2fad7ef1267155aca815dc23b374b09f3cf25af62cfec597665fc71be4ac7430cc129c2899ffc2c35fc29f835dc7a6b6c7134dd0c28653db05d6ee2646d84744e46bcc6de34d6c4081eed1ce2284788d56758975954cc216ded58266fbb6f92bf14f0d39a0382ab61e480f5ce6035a4897466b2df9e883432e358f402dcbcff50036d14c770cd91abae82675f1b3a2a6c266d3e20c4d587074e704f48b864e28f2003ff7f65d9d1b3e2c6f20b113356633060fb088d726a6579f27e1c51c3fb1f04d60d6985ebcfe54e4ed1b2113092c629bcc687d0d36f7bb71198c2fabb354a935f6a37863fb895099edcf01462ba93e038984aaeefc69b69150a8266b9d01ecbeca4fdbf4153118f7ddf01477010fa251ebec6d6ea3b0ab5c8e60a1dcc945d78e1f1c5c2ac66736215d74e7690f77d51d30a20d4040e5ad0d4b7f8aa60b4c93f9e98fd6967ff1d3769f558e1c971caee9d163d8b305a174218ad9d205bffd4a98c0c8eb76d6d91e1fd12dab055aa82c6a62c87c40ca4448cfbb61d271651b4b9cf30880b64357c5998194c790d3ff97ba7780b1a65105b197888f58327d45fed7f4d29fbccf48f7669cff5348691100239d71b8578d0cbf6bc39982043bd0d6b7241d0fbf1ce3d67011ba04af231215f86c404adea166d45b68ffbc00deb2ac6aea9f4bd087561c3dff050ae0e86dc2e9ee88fc1b3c984b5601ee35dfa81734c2bef8cd66bf1eae7e672bc1fe0b427888a17843a39979df7871776d829c64cba8ec9680c06ba0829a8988b82484c7144dd270084d2a083cf4282de9988a6a7cb01e281fdc223a9e8ef013d86b32d4568d357d050f534b4c074c8ba9ffe8a4d334f1b90a66729d133100e02b012f4c1adb9839908baf8b07876d1378debecfbc8b896d41e51a2c0b1093e02a1cf805dcc8bd02a3e242d63b02d2b38227ddc172b0ae94d9ec2e05ff89ae6db3c9163e60e7baad85ea25a9eba6a9e9feba6de0cad24b65d7a7a95dedb3033c1a37322f25918564cc4a273d6de47160152814824f0e1e1d414e2da69d99e5ec34d40da7cc46df5466982acbfd1e098f311437ef81b5b113b99f7fa58d3b98276eda6c90ef5510379ffd73d18611cabe01e28dfa7d08f2173f3a9cf098c2cc5a838d4dedff4ccf3d47601793cfcccb38aaa49d89543800b447df549a343c14d89f4fd43d7d3302f4bd8a49f3d7bdfb8d85a801f964814038fcb6d035ee0ff416a6e81c6aca0fad5b7dd6b2465f1701ed892cfcdd031bbd7ca4891fc138b61aa61f3600aa728c83aa04e0c835595e5f2ec2040f054f14e121373556023a75a860d4c1959834b89e8f55fc2f508ec48161f4b3fbeadd18d5ac4a47ce1aaf3e62a18897cead919467daca0992723e2da496fb982ace2336f76112af4d485fd63ddbcea698c728668a282ecb588d08d7fc7210947818046ee51b042e9fae6b5d152ac6f52756fb7624cbd2bc31706b06153245670bd35fb1a1fb9a620b87a014d93bb34d00bebd46812ebf8235f815b5c8fa2b50b659d101ec8f6fe43424935388e70c7866315f173bbbb176ee1259b84470819ea27e06ed43852dae4fc8933496dc316bcb1628e8866796491d413e7446f8feef214847b3327f693b302796ac08dabc8633f1082c18abb1c31ed2fd5b3309681dcc141b8926a5bb06f5f65436c0c9b53507296fc8fec8c2067ce018a48200c7474944d3fd3f496a9f8338c977ef6ba5cacc24e84839db8c36c7c04a75f7ab4e5544451f873b48752f46a685a60c97428129e51ce960fcdffddf0c459b87b1e028c1ec878b1839ab86fa4465385156b4395c38d9f1d423420dd640d574ec074f0b07c782736b3e333a3698797ccca6c61206411929eec8bfd55557519d7fe2de317ff5aafd0cded62a94b2205856acaf64da0b6fc9e60b0d475531453ec392b3898b3419085797c0cc65dd8ae8091bb2ddefdd8f25f13dda0091e76e79541977fd3928059a83981b4c096b1a01620cac4753520d0008358fe44d5a1fa10e830fd9388e03a64c2edb2b6c2c02cd166e28166f94acb0aabf4edac637f7968e1ea6437e27341e38295e98bf80d4a8fda79a8226799f655aa641041eac47014fe70a9b48314fa9068453ecfabe614e02270fa1b9b414c965d40781c15a4c54f11ef7f0d4f6c5cacf8af4b5b41be972df7358a5710546dbbd246ebf4404d8a956ef9b69448b10a5392229e5b8469222133f9762dec76b955fcee7a552cb26ced1cefc249a19d90cf1a60dd797a0c3a521954aad534dbb5ffd68177bb9cd9e1cfbe1da6192424522b6719a689d95a5814b4530d54abada12280e1bdf54d2d15b81d36f0523ee66d82b03052e6f3b59b8546530d61418329b22124a57d51eb17b12eabdcc3e1fcc2291e27228d04558855e6f3efc14b83cb86446940222f6d8503f03fe58e2c74706eb7c55c31b1b8573365fa812bd7eb3ace5d3b6263034b68d154bef6c46bb22b4e639dd7457cd48e9cb6408340d82b6a3032739603aaa0bb5d142d936e9b1741d2661ec4c4c55a60bb8bb3d8936692285cd3f88832cb9175e13b19400d1e298e1f9644413fd09e89735eae1e756c3f2623edf5bc4a6dffecf05a23bb8049ce96148759b347a142264e070e2eae4a5aaf1b849c3d5324274e6acaca1dee0ad2cdc934edb08505d2e30525ab345c2289f256237b430a01f79835061d83ebf0de5b9830a1a21072f59b2494ca3730c704334d39ae072e4cc869febd179ffeb752c898149d352d348203bb2f128d9440103af18a169e2c2ce7d1bc90c2c977367fbd6df1b0fe0277cde4359c4e3813275369455f9817615ade6d8fdd0de59a4034c0415b8c96f74c6043dea13be58c4c7d6918ee44830f85752a9b135209462bfdffc7a3158631d8d750688452d3da544bafa45a691e99ca1f0a6090466aad4a3da78095c9d20e20a04273f10ffbd28b9a473ece3832461f7b89cfcecb7d1a2b6d721f7f897af75e8feb974c61e604c024da1cc909f8123859a6bb50ad0d8d68c320353030911bde39a39d29b8db6e4d7f04006912729c6956f3a5c4d06cfed1af0e2a78e3104ea39f08ee6ba2e60114a2adba156a8baf8eb69a385a73e2817199276cc1071168db80397204a471f71f9c31e60b62e10329be9ce9ba251d223eb353941b61116d83c3c52afd83e30135bf8bc9e14d1c336ec832f5bc7e07452bf731d48b54b55310fcc2f41d525da03074ce4fedc5eec037e7f0c408ed781da28d594f2f2044e8a80433328527cea3151be2670370605639b338fa506079a5214907c73c203688c6bc29fdcadbb4c402b061e8da93abad8dc194b24b65f7680d9d818b73d8cdf6986ab89b9e31e98157ea5b99e58e06acb0511d38c6865f48d2089d5aae48ea2562182f8a3f871800d96d42d44862f260905c11e9aa31ebc7f5d65df3b797cbdca17ad79d1e719c538861ddea4160975d23d5031244864e2f996264c44b5543a2fbd4f47a63a1f15c18dc0167a2d9a6b66d1b2b955aafee854c2e83da8ea5e0db0f0338dee5343b1bd53c208844c8b062668ff6b4663abdd3179c8dce9e07d2437874843fd6405ca6acd25a73f4214aa6531a661365dae75fb0c64f43505e387b22d49adf01b47a8fcf711ac0edfb250b602d2b00e5f3f2ddea6c89cea5785fcb19056bd744c3d236d86529278a5926c8bd54ec8b885e472b054fae9d205922fe2515ba9e9b605d3ba18552e141e91c1493d3f68750b0b6d6b9adde16fbed3b096861ac97e2041b1a6ebfe295176f378cb0ccec963d1918cfba2ea83a7a38364736a2f00816ca31ab0654c44e9839e9859fb731c1448dae7f80215f07215d29fd75b27bb5f49d1385868099cfb4fb2ffbe3277e367d63909c0032fb5570439023c9490e234a418233f6498076f911f8c32a85de9acb6ca3e7cc12161455d6db514dc23aa0bee7ff829db4d50cf89ae701c8c028eb3deab2b832d520c61406eb14b890b68584cd2512cb92f988b3ae45334b9c198aab6ba0f77c41013ad2adc7dacd582ae9e039439beb75254780f2745674667bccdb286fa5c5ddd1dbc0e22ba7e695c9e1f7312d7dbeed2555a6b7e054a5470aef9c99509c0df1c4c141b82196d53b31ca6e6823b02dd405e56ef9372b204daaff2b2b182be04a07bf76175605aa0e6197043194b5fece29b37739f54a95427e49ba5f089612543a05ce0d5d17bd372ea08a352f2d98b713e37d5bbd73a50d9dea52fea1aaf96ddaf9431c21bb0290846c66acd1928e18a5dce583260d84b8ef361970d8c2bc1b7881d2bb9e575fd0737fe60302a9680eaecc2740f3e415484a63533a4c6fb1fa54b4f001976859ee0ab4eb08bb6914c5cd4c7eb2a26efab3d8e1b9cf6df2522c9da340c6b8b513272d821bdc390e79edbcdb59da8445ea14bd879b6fc08f6004969a99e025b31b177df3689391135e034eae42d7d22f823faaa94b7d88446a467e7ba169999445b81af13945ba718fe641d756247eccc43672714f60db1c635c22e8d5b39ea0b211b21da33b0ccf198ac400e644917d9f30680732a22af3f126fe93f5e3b77de5b84878c06c0ec42d98aa2cf725e2fa7fa363f32896ac5222d92d1e577d6bf9ee71c82c2a662cd918fb621e3770c198f54080cb335779b933eda12330da77a11321fb3d1fd3e31c8c782be1e8b376af57a90087cc05e070984f08b8ffc6004c153804ced557566f1e96a77f9e8e7772f9f94e6d5fe033d30d057b1cc2a0f366d85d5ed5de792f71cd50382a844497575e2338278b2f9c523a9a95f67e2ca598ad569d25107952c4807d9398fa87981f5eb1b8112a569483ddefa39c4a3b3b43169443eb0e8d324869e96ab8b5e466f0caaeb0d2fca020768c9d130f040facf1026024870dceeee4098d1b1272e1a39356d831d6d337a42f0bf5b1cbb7ace29c5f2ee459b41ffdd538133cdbb51441336938fb2b6e0845ac4af89e5f1ee8d5da75c4d4945b23d48608610bf2b88417815f856c69ee81d89ee276c0ebfc41f6afc97e4c2eaca73015d6ae850dae4cfa6c44804372e66edb7f0eb3f28bbe8fd1c9de506e586c84f902dc1a660adb564a9fee70ffb3d083d666819e2a5d58504dc86982fde0abca1a6eb59d24d8e84c5245b8d9b512616d354117170b9a0deb908364c106ae8ba0a9181979b4e2ca61928163ebe776fed984dbeb8ce4c3b3b496abc974d3e9f89149619f51182a8c65d2b81a8ed267dc44a143c1ae52209a252653a736a4b0f21ccb89d7b0a717b7571845967bd9cfcc0edf54699b11b0a7e49f52580c3448c98132f370e8f370a8e6e5bb852cce4418c9e5da493456f6064618bff7fb27cb188a19f0d661386f966da50202bc0eb904866d4284c499337c0ce4f707ffe9aa225cba8722862e2ade09ddfaf3ba12b0192c1541f809dc5de0eb4751935f6d39c26ccc2478662318cd6bc706c1dd39b3e2ea97382920c35cfba049a3f21fb33ded5e402d150b3ee8800c61995d57e59cc173ede63acc354d135c99dc420372101a306d5932f6573250f956439a6241bb0181ef0077d6916d11f2b1a2c6461b1a0da652fb0947d9a2df2e4bfeb1a19076c01fc1d4c97a29828c313bb84c7d74bdba2dbb45457351a94371e7aa8739151d5b7d6dac3c4906932e4fe71c5a3e5336fed5eeb3ead5961538574225f443a1ddc6f28479b30ad7c22dc627debfdaeb87c13806153872f763a5c4906a5a4746d08f82dfa1fff34b11bbd86fbe2df44453f7a2f1e681cbca52acd1032f1d6b095f2c7bce03605bef9c8d61261936d313f6ac475d905867b69c72315479a850d136c7ab483e42ce954d5c855f14f30801bd7857539bb1714e34c6c214bac0b7375979728af1018f21b9c9228b784178b44b5a0e56478867be946cf20fb66ed35a9e4c0529c722128a43974b970fac9f39c67a23a63f61cb1e40901cc88fad1ca7926782244d8fcf48f40da4a66add6ddc829ec65484e149429b9982cadbf1527405d4599db0963f11665dda8773b9ee4f2d75139f7f5bdfeb78b6403bb27fff9a5e66812050c7074d6987cef3d743f8f6322be8724af9fe085caad360e4183860d6172ff7479775c8335c60167bc10cec506f11b8a701a690ccf6d2d75d83d71d60c41781e7058c0d792b2af6480dc2e77a2e1f3e477f72efc45d2d884bd762eca3af40b22267270c4e86185ae2d58a344f51d99bbd4113fd6ceba1b6f551a6e0d8e508a2bffbd2184513f7c4c09a3e67d1d60b5eebc91677630f2c959336b26376f26ce0c2dd774f11c2b8b76ba83550499e650f8e084b7e78efc87bd1205bc62cfec082b6dc2b58e3c3afd0e0a663be0b736516c00b8f677b67061eaf2fc7cff3007af25a9261326d27aa9f3d4b66459e9298031b83bde25791d41311886312f8155bc93deafcaea6e7ba7442db57ec04ab629fb60bc847188298f70550ce417c56f1e4687c1312f30766559d436a12093f4013c8f9133d8ae1305920b223cc95649813d62a05f3a22190276a96ede8e7320344dd66f20c4b2318830a62000eebfd7ea74d1c0a3357c9c987363822aaa07ffb03e771c494c3eacc6cde2c88981985a395af0f374266f4afbe5fb6d14e73dcba77cda208431a0ab0cda4e831ce2d2d9ba4feb7f5576a71542c90168fd379e091e22bb05671a2144c7b0eb7fa03621705a25b9e90f4576a8fe9801d53af17bccf405a853515285787abcd7da33a3d0a64d14419c80fbe9a3fc92bde8724268122c220fc17f05534c36602e15c36b454bfd020b531ff8651f3d3b0d91c2ff1e88690ed0befc0b0dcbc74a39d06810aaff8ab3df8e74144f923fde7981e99d1568ab145d890c088d9bfc38ddf50bcfb69bf270728757868a7b63587e96682519a0ca9bfd379f9bcb780e68f88657230d2248d93ef09f52695a71c376396da4bfca7cda8a01d2397decde907c56cf1f53602f3264f99e79386fde5c5d533eaa2b44f5bcdb66b2b9d1c6c5758fd3807e97329eff95fab54d6e6ca24d66d1d2c98af25cf1b651e7d7e19b5dcc827d1a3d5e5a4e84a6a3c4da3843703c56b5c25d0b80d619885b71e5261269fae1374f0f141c83b63e06c7c9c88bfdb606b66d68b458168d45792c90c42115f15db5f7bc594b60497af90db55f7960f172c19a9a64ead2786895f9d5acca87a5297b66e26745180669705b27ca0b99f3f9aefe35952e86cab1f75f163cdd10927866d6c95730ce67b852b9339749f19314a644fd3e682797c826649457ad8e2fe9f3382984a4673ef4714be891357bb3de0637ffba9d07743c0c56e58acbf01d2618a1c7c7176d0b8a1283a14d59e77cea2df59b28e029f765367cea17d9d5077c4271693e2741305ed39ccaf7deefb360cd3ea9e41db9a0c0256fb6502943b89575093aa4003421428ebafbca2a56be8592f755d4b14d7d34400d081e6f5c02308e5f8a3f9950633c390fbec944fd8820fc3aefbcc8ab58aa9773433466c80425941ede7b068679fa324bc96af7bae0bb555eb92dd6b1d2ce9d348ec152e703d20b386741f8f7b443870d84a4c0c43fc04957f6a91bc8c89e45093b158ed38912cd9b503b3c3aa4e1617e6f59e3b25848201e38c33d053f7e92c87750966ae5d62d2c8f95ed00334b2e584de9bf453d38a45daee6caac4664dee6f8545775d3fe92c2c456453fbd8b7455be24f1dbfbdbdabad328e705afcc4adc2c518cca7ab11b225a02d873ef35013675e93db46737ed009387c2c10e2c7e250d4ab1a878db601bfdc934a1d23acbf10ef9c4654d367b2f22be88ec45ea8c59553389b45359503c0a9f758215712d537761e138dad61bf7d8f7d3a8278e682a7f34be50b4f84019c8b2475867f9285683ac65b586cbe93b12f65f61c8550266c614910d71a16777e082bbe9b48bd4f482232eb90542fb03e5a407471c4b1ee6d2f3497f09e992054b7c48f747c97468cd582b04b8e76867c4e3b4f5465b887c6c897ce71bb1e616e89a20486e6d9b9a0a5d407ad0cc63808a40024b0a20adbc3836b24fcf59e3363da0eb16fab47d0aba95f629bcfb754bb0cb513dcad73990a87226d46a04b4d4d7ec377e016ed6137eea1b22679ed8ab4053f5cb2aaac3678802f98c366e80c41f4592435da288ed5b50db5bd5a3a36d421b7dce56da15651e422beab7d9a30f01e859836ac8b21dd8f6e53a6bb86386ef622f37a3620a2452875e8ef14823f1b78d46f69bac4a4ca0838ba53064807f6802ff28a2eaecad02c91446eabf427a6c2bca19a2d006ed59e481aae610a26f58b0a6b8b06e4d305f5b29029cde2015ad572c668e964c504e43c4028bf428ddcc76e6a97c659536e587f6c8664b2c9da03738c9a16e6da2db860c8c7559908fbe8030feedff6d2a58985bd53c4c8bc8fe49b80ca969d4c74f0c26ac362da34ca5b81262664e6b3865940e9bde7f740988816c6a7b9b989ecb80c27fce7729cb8cc0081a3cfe44320bba2e4a4827870212f4b4872563fe8afb25a3e451d473abb8f4253c2a361ead3ca40c7dea43df3a659c521476f96153b110d3eb2bef94f57c4c5e8c8397af30c70435dfa193664ba70c3cc020904fb9f3d74249dcfd637d5ae1e5526f25f0995ee6fdd1bd9a43e9a251058b6917a44926b3215ac18ed21d822ac09089367116de31919fe044bd7e85ed69f140b2a3900adb508cb98b1286ebecf42ee0436d6964e0af1b5869c307855e6927f5fbd5fae492c5a37cc76d15af8542f685d08839f501bcd32b771c7e14c0cfe73c843afa92b6dcd34576a1dfa1b89b7bffb3a14c206a112a186f21f7bf5b3d878d69b0183cc73ac646f6bce47db9d8ccd3a107f7821bdddf8061adf08a0e9c1fe086a406d81502e81a933b42aeb7cb1d26cb8511da5ec65ce75d7a2aa7f385b7be46f9576c653effc9a9c6182de6d52a98a332ba198cf83ab2bf735e3e0278b720a8411868647f6485da6bd4b8e3d999f4620fb616048250ab2e17394063b0e032b61ba69f8fbf5350528d7293260a0ea8b24d30150026d49c95d62c323b1a0953cbfab846bde9ca088885c8c6024eb2eee9d9fa7ecbb1a1b028cc9f03f478221121cda3858c992ddb7c6507f7e9e419f6bfc13454316ad833d2be16d284975d411e359860403e5c935589661f969fb26021eb8c3db68ddd54f1e767b3ceb5bf2a8db73bde0baf58ce5629f45e33bec22521e3b3f416255d69b3e80c9b3967719e25156d2626e4590c7c0063494c1391f3a1ff31e03a241553a33d1c5f0bc99ed76bb4b943c96665481e5e691cb5177379e168d9958d810ca33a4a7c53fdb698577e7b0befb50814ce62c4d0b6c9f69ec12b3219bde32822d3e2112c17f7302ba03b6af212788608aba176c742eece58a542ce85bf93d3c4a1b63e94c877527426135cce49187cacaae53dd0d053fd677915e0fb97ea9be8145f5976edb39069d02b2dbec49a99299369df5bb776deab539a4195696f116cea198e9c2742be2a6e1050fc8e196d7f7d1bb33109f5e0e082bda21bc0c248469f90c99fecdba7d7c8e2ba6d99a5d33729eb84277258cf3656c2800c531c42e3bc81a5314c441c6b3992f9a499222739e16792d87db7c6f500cd9b33bb2d959cce3c267bb9a791274ae82ad6f0de21bf78f8a7aa42b77d09895eb1a3905e40476cd459a735c187f05597743cb6e69e41c2a0d69af03f2811c704a3db8240f448750cc0640e0450903820d7da40a9cd1a1a8531be86141787f72e26e225155de7fa8374c80c77ce4cfb3a4bbd57ea54adeb7915ad6523b691a2abfc78a0cb7a76820e8a878a3a85a9de559e7e72c4e2413f1b2c433467284dd9be8acaa1ac714d4c6c58b4369df039e0bdb299a3442f93662b0d6d0fa0c0dcf0cbb1a72050c8153b303805f43001e47e442934ba41a5bf6bd47b1645c597593c5b317cee1959759ae33e615415243bb0a2ec6b317c14e9d1fe64fb47034a10e15b9919e45cd0ff1468ad3afb52cef17da993081163a936510a8845e303295caa89d3aeb9e0491b6effeb739dd409649ae42c6fcb330f267dc8c75e099b9df9cf0416c8975294ae661880dd2d72be00769300a2dfc1d4bada5a640f4726cc3c86edcf64eb315c7e6a1eec398440635e31d20c2c5b3a9cd92a8ed118ef79912828b60c02c105d693e060668f6267add4c1b2f879f8a9dfd24a96ad6c10b94514bc7b2b585a46f6ade16bb26f8e09b992d4fa28d8f136a43f3b978f84c014527e0ee4458d9314a29217e853fae4077123a999895622acded9183cc16efb5f3c6e6629d393dc26750baebc951ae9ecd7e95fe5ee658e52c16ba8b545b69d0503b0b0789a4bb64840f0fb1bdf1732c41fd343370d3e20ba689c2e501221a0db56d21d25d7d2c7e514b24cec474f76a05ca13a8da472cc7de673fb002e6fab454977956bce3fe24809f036cc949860fa4d8226ed19272d211c782432c53e072d21632d04e1b4c5fa9ff8cc51bf9d7ad1583311b519025db4108eb98ee0eb52c6d87231bf1f3eec9438df6936df49556f961d60aaa2452f9f832ebd03e4efe25de85adac2d2cc64d2ff4636214fdeb797cef33347b53f805e2e3a8f083006d3ac3640a4712cec909db1014bf34c89d22e07bcb5de42125f3f35aa5249b8b29a019770f3e179b6dd0ea991254515023d80135e4a5e02ca725a34b75d0276fc549aaab091665420a89e491b319c84a52c7108967d17325e8aa7b2c3bbcbfd5cd9003aaf45e141b574fc6f65384667058386847a443cc6a24fc9cd5baeb4b19a9507b78d8dd789caa2f8625d57a99b0fd07778aee33f92561ab1254b681793c87b16f4b707c4e5ad44fe1a783d9087e39bd3510b96ace37d8737fcdc303428b167b1b569ca87c40f3c4ce133ca50d913221f4830360e69ccbab03e9d0ba10b1d5d17e47843538757cd28c657a14a422d22cd5a56b8216dca8ae6635c813eb95b9c519772058e6ceea5a0afb61af68fa3231fe35cf36b6a495049849943a9400087e0678597b084056b8ddd08452e3ee6e3b9696a4ab46c9e9b8263da90466d975b8ceaf11ec9e5024d428fe73b0db420d296ce1d79de74cb8674b6c3e0fedc2f18ea650333f96cfd9968b7c5f5f3f2137164caa7e52232fe6629df450e0850c668cd2d6a6e7049813f4d5724d92f3bb3dd6e65c90273954baec227a7d4cdbb4ce72cb64f73a6a3f957a1c071bda8df8da3868a592dcf94b79d662e3bb028d8b4593423e71cc7d0fbbeef9d1358fcb9b2fb86b81e6847ea0b9630af821f8fb8f5027d922ca94523f4496c9637fd3d140617e930152dc6bd1a901325741c2adc768a80d00f9a53611f5ae5045263339c85dd61e372722f186495b86f6cb8662f16296554ca844b55a172a1896e8ca5e69cf39c71d0d837b455f2ec5100e4f5db88d142b689684b6a0e7dfa0bb90b53c09506f543d98e77cc94d461fb2044363865e354a22ff7538417f9efb35ede941dab54083c98d20c27bae850456bb35bf7ab16cfb1ffae2db0b87ef47393811f60dfaef8316b65d50af0290ae73ecab377a73d7fa154d7709e4d47426d57b04c0828eabc412086ffb83ae7c57e4c9f5c6438e8751d7cc9a69317b6fffe416ff203c4bde267512d90e405a364b811a77b4ab6ec01dcefd5c29e2d8b65d228ad2dfd9ed21bcc4ca4411a9b108fc2794591f5ec9cad80b4b382bbd601e49ee089fa6b8a31217e2c5ea26328a19050fbac11b39c0417fbb7bcacd8b536563dd50382669f230cdcd88dd0278687add815b539521b6f54c4d3b0245d666dc2bdd6e9699b3b133de8cd507a6e058214b2d4f0285160849ef93eef1d56ab439e145b412ff76667377a06f3978e3982fbd635e08fe3c76f6d3350fe2d44b85bc215d57f7f1f6a562b20dacae165a4934a9b5914bde9d23696557843b6df9a7e40cf7205fb5995bdb97b8a61357b5fd5e216bfa99a7ed123e704b055237fb43bf1763ef98e8e54b4be066428f225b4afbb74105a8beeb6d303225c6e2ca572cd47bfc6db1d1a6881aa53439c0da753a785753a0b8f08ce5d627046fa60685cb464a3716168d9a969f70939b83d92474acb4595fd9d89f7636e9a3e00eef2c487afeb5daa2147e71f4281a10955984b1bd53b2ea6df5ba0a5cc4804413fc25c59916aab62383994bcbe90787e7294549e3eb1cb96abffbd7294a157ea51f698350d71f85990b66c74da6a4e3efa03687190e5fe32b3c2f2c711be34ec029a665f3f60243b5d4b40470ef51c41379295e33cf34e200e3feb1dcec6802da5e361ebef29e92edf69790262eccc56604232a062ea61cbff82d789545358e7003f007eea4bf5b06f42d0deccf9d2f25e42c6faae278d3854953fd0563a402e598d8c13390668e838061f06330c492b0bb80d18431d210478a90beb402549cf2e93e768b04d1066a5d2298c361be21500bbd11e5c38677f01a0a9a6a2fbaa2213bad8a91f15d4769cb80980dac6a39fb9ac2e690112a0de87000e5334758adf0ed31fb9857faa419f2bf68e96d165038976dea1ffcf9ff381bea461c598d84be7681d0ae3b7ef6b60ef35ae1201f59326a7878e9d9ed0eaec1c3d64b9eac29493e37fefd1a0145be9b4ac61e76aec34680a1d905514abf9bc428091b7434c52897ca535604662a99495616871353d6906a7c90d976ac2ab6f36b6ef82a5bfc91a52ddc9cdc38a998a49cc68c3147ddbfc742d1d93667487df7e14bef968f3e090286971cfb3118fb8a2a13746a57f609ad5b4cd734109115fa6b5dec5f8111835e55b20251c96195099f71db24c0eea3e2e21438b29d458b88fc8cc22ccb64f5a3f9542183b7d651b6dab93a2f2bac92493686d41467460817588c37485fa799b30e108f44560c07f026be99cdb4c07319d2b5d3ceade68cd94b1ced683525386208f328571647b9d7844b5bb6fb3311a6dded1ecca22d330069eb305d29bc2cc0718efbadde24747fa24392ab3d5b1e63412f50e1924d48a54bd3cde4c26817d3e42bca865e7181078413c74df382ef2be948f1968255438479592e86a6e1740fe64b3dc79fd6b047580e81cb15d46bcca0fb0572cc80a51cb85c6f3a1da76695dbe17e154003481b271d719cb78f4927acb0380ee642777fe6a4b8241f3f909702b21f62c106f95790dc4e93d3a8ce0c614eeeb23f9ce90f5c752c8f96a2800b0fc3111625ab76d5e10dd02c2079c5dbfdbcad8274fe46741781658d175de29ddbed94784eaee410dafd6e59e410bd4113d684063d535c6a0e5be6a78a8a8f6c7737ec714a836a72cde8181314d90700edd52978bbb1ef8a5e76c89555a28b9ade3b65ef845f524ee82c543b0e5f09bc6ead954803ad5270c05f499f5f561757241e9ac630aa9782c48461d45911c1cfbc3cbf67dfc70fc686944d38a7dfeabe206380683a0a4364dc581c38434c4e7f6044d58c631993aa12de50eaff05230916855c2a753f615ddc3647f4c36eee6b3dcb796ee27fe17cbd0b9d2986c7b466c2a1ee15bcaa515a3d2e053bf6f213417359bce9c13f76dfad1cea35ab0fc8fe72e80d15ce9e47200f0f82ed12b86e3937acbc82d57b1bdf6a9ec11a2b6b2539ae571ff7495a8020641d18cac04328a04cddd6f014bac4ceff9aed9232b0167384bb8eb00417524fc1cb2d6a64126b959d0ee5863fe6ccad7c1ecab70ead611eb9d25c46500d40d778074e5c8f3d422bac228e91e8b9017adb5f33314c1e766019a62d73fec290779561fe8c5dcf2a364a28f7a0f1c0ec21e8309a3d928db1cb85164adfcc8d6d77ec4dcb52d168c66744ce14e3a54809d0fb249a6a68cf5221db851e9cf44a84fe9b9387dc3c55fa487a17a86549a6d90b8c2127dc5c26bac58bf617c3e2247faf69b6da9808cdf2251b3fe33732323701aada568da352a1064a1f0de629ee0f6ec34effbab5e6b9e142d47390f461934f370d3a1b42c823916fbad0a418286fa6e0aeb85f8f0f9a6ce7aa13fef92fee7ebbedc1f70c7ff2ada999da959c2959495fe1211f91b8fb872f2ec4c57e99ec34daefe9092f3869b49244a601e82b6a5aab648aa7585da6d93a6dedc5a757a1787d681266093b67de978dd19cb9adad513554c73be100ac0fc1268740e07b7d51ae9be26b52fe63925d22e63ef55f1050b078359562f57c1346b23e33793ad8651b20b423805ae9c2777a1fc49f1df115bd8835929c28377d1205e37698c713ed8b9490e5071a2ec55fa2bee8d9e75ad46fcc3b6d26fa5f443374474ada4f308ad4e4a7f7769a4c9fac0c1b9322f5363c7cff0a48b4d9ca49b6f1a31d8e8d4b1c66b515ea9ddf617538ec2f46d3f11bcc26029c49903e5289abab9d7437d49cfcc4a11f5bcf7232f6b3d413f12ad8f4a53bd0011d22983339ee30244a040a0b2c1f7717f1f21a76e9495cef6f1acc3b13583e3f3461f5c704e4dd5ca0c8d0e0d0a906535f18a9d8042cf9f3cfa39c3ef2e9ec1cfe5c707201c1667c78ac5df1d864d8d5ec39966c296e69c5850d329fad8f10ce39008915927e6ba223910fedfc747427a785b69ff52903a5e8efe997b12980bb8e092e48418ea4319d1f7eafd0b911a4221177728dc103a908afc3cc5eda2e5b2257c20b2ed42d626b0bec67318aa807bf7e83fed6ebff03184497d0ad7df0fe9f0856148d99252c524261dfa3baab54e74df4798f0020c0847e5fc0eb77e77a1a2e4b109412c8e0227833c569e35037dabbd26d5551673484c9c4fc5a1102bad2f5f12fbeb730cccf9fe50c3080c8acdee1f9ec26762c0e0023b0d48dcca8e98b860d39f41f2290ba1b202879f04e66942243d3b890299c023b7a76f315c94d669edc2d442095f648efff6c007792c3fe6ad0a2150fb1d85fd7188ebca6540f78b3bc7218026822c22de1039df01321f24670b0fd6cb50ea6cd68d21bb2a611b78cd6ba8e11806a7512b0b3822c9106bcb291e3b49828809dc873cc8796ec6829a4c51c26c35c33fc97f908960e10ee4eddcefbb5599d4eb2d72de4ca04380bde8e52f91772886b403151c7555e2ea05cd11215800d367e8707e754d612250ae2209b928e7623c21e5e483d660fdeb4452c5027245e6d46ff04a31aa68f4b47145f0bdff5412b4258ab01e45ff3ce276580ed7e79e58f64c9e56203f6e9e9f990d760e010b239772212d445d4c4c6637f943bfc4377dccb167796fb2f85b9de28182f20201d6415d369d240688388e30f27e0cccf2ba03757191e4a9e9c6d6cd40722cddc4185d6cad49e8d96dd79fdfa58ad917ce3e97f919030a19eb58384193bf405e09f916dae7447d573b07970b174069b79a0d8919b5e39c59567b69957f1d4952273ec5a2ed20a741dd279f39d8413444c9a04dd743a0973e38a29be38e06603e2ee4c97ea2323b4a09f393fb450c7ddd38274a7797e2bef23144fea2865723c3ad0a7c5ef844653f6f4d8b961a4a1c5f6541a9ed03f39738c9df0f66aa983cf6ce595f214213ddd63c61b6b57a939dfde4eb5c94e554474238d0569fcb994721f235a971a7bc164826bf288fb1ffc47d5f391fe1406cef2ee6d6a50d9a37040ef8074ba3c6adcd0c160eac2a73b9fd10376b898937695b871828c2584768b944a0c924b9866a57ee88395a478a201e3f3bf9c06261819fa74a096a97348e2be45c961e0be3b0f633aa98bd724551c8fce7f0fde3c667c8880905969929f44e82b4209758ed9bbb354e9e6a7f21d1d49dee5427530d645c07cf0d75fe15ed53dba78f9c88498e5a11338aded6a0cd97d0b7de81245b98a597a0f5745b279b17584c171f3aefb4d764d8b2b54d2779cf61731db9cbf8c6dcb9d858b7634d3afb237f54b7c52e670225f8ff6805f5e8861a93a8da2c8b54e2b4027aeca9f8dfee1697a32a6daffe1606f7b541cf5c82ebc6dd1f6a148d28396389bb2d76b644a76dc18b21ae630b83c37bf17230e6f2685cdaa8865042f3402a3aec73c17a7515a8b263ce04a12c028ac47a20d1e351901d7a8083d14517beb95157db61413c6f2185721caabfe3ca693d226ce797b93b1912c55e0aed2de0695f5d4e98a911d87b6aa29f1c285a4d2a9ba8a25a915a65371e6f55d0adfa89857af1106462bc96f4c1a1c364cd4511a675e77286ba8e5a9dbb5da6f4db9e12fbec6688ac2800d065e53d38fe5035393cca2e8c8b4b4a98a181988968e780d709874821be2b729276d4748850cb073c407e3b726d81904bb295046e624562fa0c829ecf44e5361d8c95701932d7f306c3bc0fe2c5c88f6b39ee2164bf183ba4c3131026040449218a2665d2521845d4d071ae58ee86764afc72038cf7558b82698ee0e32e3b5bfc2be7724e21b77e247564ed951cb52344982fb2d04a2831acad97ad04f6077acc331a79ee4ba6165bc24fc2a278a397e0134600f0cd9fc48fc7273f202a661e5c667b563663d9c1bda61ea7e6ce2d48e0881715a9121e1eeb056240285500af94e2c331fbc2eed83e7a72b6421a5277296bdef6213097ed355d7690b1dea104e86648db76fb27f6236a18636ee19b51b4a3fc595435f08c9784da16ab62ddd3b5cf25647fb2a8a65b6e4c09b1baa22a6d261462fb0f2631eec9f6fafed26226e5adb6c3b0729700e0dc19bc0f102393132321f50f3a637c80bbb86a6eeb07c09adcbb4dfe6000eda92e65d03569111121c5eb207dccdd170af5c93867829d0c1af992015a32f98a2616872a5355f49cf9f1dc318a311d8c3cbe37c85fcb4a232df0040377e522bb473514d86dc417eb7112f14245f8176b3f69524ea9bd1ff82771d111ad791906f32487bd220ff1a80bc1f28d479019e7253dd12cc71d37bf2550e73faf0da4205c6c288aab1524c17a79ac7818289d6bcfe72fbf746e1d92b064be5471cdb951d528701a2d178765922d247a4c1444c02bdf9a38d00e0ba3aeb09ab5463c5a28d461759b609952c1ff1ac15e497949bb1da603b5cca5d1dfc2e9e75e0e65c104dc126dbce4681167b2be9cb4d09a3d7c6d922860b179b0ba4113101f782a5e0524058907b07a2b5119a272285036e517724ad731f49dc83b4467a83c148d1612ad4e8a073e7007691ab8d8f6c6401dedb76303af230ed5c8cb692204623c6e35961febc5470e49317397303a3719ca6b2d6ec95b6297b346a938d52230d234f1e122cbca681a88de6675e7a62d3e3387d905e7a1d01597909e1171f8ee543858791bf01849f4b32be22735c799dbddeac2324336df7c4315aaa0df2a88865c3890f0a16c22bbbacbf4038b226eb903466e1a21b00d18d8485f4c5ff6c83de9948257636f38f8dd2c2ef7cc632f7c5388226c370620eb8427fe07954a15f7cbbe8936ee51620ecb47c106f79e6d06bc5b2a1ef47116deace5e33e55514c464fb584db3079d8f2876e22620ed4352c32aedd0f7ed4641f6cdc0b08c7a60ee95da9b7d48cfd5532012a6dd16c5cefd7d83788d4803931ae40231c51cbe8d9b4361d4e6b4b3f9ca5b6b90318ccbcbb07c8f593c94b67e007292074fa10f4e754f04fb898dbb7fae3a116fdb90b8a0dbc1fc4d02c8446aea376aa76bba5c1c18fefabad7cd9f03edaaf074b333c995a7b22ea3e3ebb475dd3e9c84f709592b8953505e065a712b2d63b05c1f9662e76306dc64e99afc24188bd05a601b7114c36ed29e0f717f121717de6ac35281fd1a6adc79618affed02df54b36af91f78bf72660cd45458cbc079e17004919a4cf83bf3607dd579560606abf5917f40c2e60df4000c5523ab6929447c563b32e853de8ee8e1ec8521d274124010f9cc0a20e25a44901eba954a6f267b7ae45890e7c8414886e39032203c6ca2a0f85b778c0525a78126ddd8c6bb3caf50a8da0c32372966af34c576e7017268d058f0bda3ae32727b17062073ffc65a4b836e252320e7d797a52f392903db0e0a872d6743c9fa3eff917e6f1b1fce37f00f4c1d67fdf4ab46639931f2626d6a2e81d6ac12149192f21c893ade20db44ac964e5f15146686d757fd18c3ccfae8a15f0eee35b5619ec15fc638aa433f3470311f4972dec7b694eb5bbcc45e0b1b08d1d2b5653f7795f898bc39be6a66295b5a9ce9b4e75e0124780e6d392a7b1e0acfd3e309ac371588cc88ff8e26c26d2904236ca45295ba12ed5b870a53521411edb9ff1e6040ca4065b5268674310bf3feb3af2fe8f7b816dd4fceafddc5d51eec3050340e1363b55a641885dcf7d76b3dfa2ec4444354930cb66510a0992d827674c2d4c8337f6c4b885c439d48c8c80c2fc391041dd3394325a03319c9f50567436b05e1413505e85ee77135f950d87b5928b193316e6195a325763f106c079b64ee9cc58833c00c9c5f3294730cc446b192987993f818a83a394b22c5c810288405fbc3080b8b7a58d0d3a3b7b4c76045f94bb709899c43950e4cc97385130ba438b2ff66f299a891dee0dcc10bc6db849453e37b9c317116f90aa83e906b9778af75038da595fe3ad6ba3da20589f78b29cc073c237a21fc13e87a03c8b2e02d9792f778c50bf4397859e0bcfd02f79a0e47a34cefc8c292145a4f3b3e18387257f162c27df13c5a89da83ec7814db28aac179d6c1831e9307b9bcbcab13d1f3575586df0568666b9e75fcad69fad03ee8ba3b5d0e5ff1df79d69b514b6698f638b57c5834630d117a1cbb30a3d2b0ba6645daf77661b570da1e9ef2a125ca1a10d6ec5107c0054ca2156d2eb927f0790bfc11c531ec981d4c5874593313382ca19d463cb42e35e233bd350b135ec872b6b6e9136d710cc033ae07e6752967161fc673e151d1c97638a1668b25a4ad467c4cd378af4a1ea3e1fccd24f0d1b371004659845e550efd64d7e3afd0768d88de0755b8ed536d68a00adf4e0e6109503f99e18d84dbecfd6da081f507d30206a6c5397c3302751d6a5bfbc50c09a5b7c48be6e8dc67bbcffd18833f88e728887d37fdd6ec83e4360d2c31bb6870caf56444e3cd031ba4fe4bdec7408c1b35175d7cf30bcf278873ffc2a6c63ea7867cf243cd3f2fb752e5e8d245c76ba8b6eb15fc31bdcf8ab5deba07658db372bbe61402721f1d8f9984d9bcafe0c8aa7c2ed42fa6c6d36a36b8c7aee31f91484fe322fe37f95e61d819099640c0a7a767853bf1759050ae1038dbc9e2f91145f4040b5534f862010f5f83b128a120709cc7067d541230c52ba5f58239bf5612bc2844250cfd1bdf5b13dfebcdc42934b7e9acf8ef04735e0c7c3ff9507f70d96499fa72a6f3bab165dbbe1936c4ba73393307932787e6a4981a1528cbc27bee0ded51253e8bb4722d97dc70ffc25e0acdb9fcb5cc2f753224d0d0fa6c7d53e6221ed9ca76cba29ad9e6b2506b68f3f92f84681fe872d63a0e3e089bc3432dd22a6fd3a20cad78896ef9779e7dbe8cbfdda1d3549a1f6072008e86029b1595986d9d677e8bedbc34b3607b868241424ebf903f73ab5517fd14e139277e298e8173dc1070cbacc6a618b07a2fbb8c527d8dd83db3485be966b70d0b5f08a721d2fca947d2ecf39eb78ebadb663f7b31251ac68dd76cd9c3c1bdd855c87db9b5712ecac7c3dbb828709d9c6de3f9e454a78e928df8576c0716f73f087636232554eb64958ac2305f10ca07b3e421bcfc8481574297ef38739e81642aef2596ceb2596aeddc6125ce6aab93f36c3f471f9b57af42bf819617de525b592f5aa9add4f3dd9eb4f165dd5685bbe2a63916dba6ca7329104a351ddf5268777661c661249bcb75b07c632bd3bf61edbdf0006f56d310782bdd624ae85d3d3ac3ddc0f2fd99a69116e66cf0e9f6bc79ea8872fc9d6396edb8671a5479b47d131211a56dd054fb80bb74ad20a8fe1f3df95784023356f0a93bb79a0ad772d449923d717e7e6fdc900111cced9226c60b1d95fa5aa9a330651e1182dcd061dc781ab54428545d8c9a85d61d5c59a38ab01e92bd35c115586cc580aa37a2f2aaf0b8d9342eee0296e2dae3f0d40cdedffd0bf5a437733f10d65d2ca6d416d650fbba0c331a4ee3fcf94cc79e4194a7d113195a7781e8e74afa0034a9929d5d9fd4e8e153d150854205053647f8468f7b540fb0ce467031cfe18be5dbd5e68fe27139998bfc0fb7e2daa4a0de048bebd62c916c7068452fe2514f0bf23c5b6edcb100162bb70b18b2c9b9a4fbf4b9cadbc8568b233f73caee542254bc4530e5680f11db844e86d8cc8000f39b7f5e008b2960510559b3afd869cc1ea7793b2506991717a5c04421e0e65132afe76458770e5cdf8eead8eff82c74ff63939784ce23e76db559b788e9ebf76d353fe1f3023c249c815c0d44438dd40e81075f9be1a59f12f6ec5e1006514024070cb83b7b8d024ed3214457d3ed5e3df907a618ea79c5f413e1c1a83fab910a8b3347a4d8cee0c4f1bbfded7742bf5bc68a36791c5111f2420abe3353eae4c7967105a3b180467d1519e68b3c347e85b9476cc4f876277237efc8e8151cccce685619e31c8b6a5907458ea3a48b7930a94bc2631867218f734f56d345d34b3ed3f6d1d55f97be1a164252802f516626fb78f33590f1914515ae96f4059b722a7bf0954d44d37894093ec9d527093f12dc015614843148bca6de59889d582f58579cffb0765fca88b75005744d784116ec5d04e369783b9184926c10fa6fcf8d2236c2e401093ee5f2f3515a511a32d99e46f083ad8be51585e06aa8a8f4db2c9a5799bb457ad3387076b1769a9ac1bb8371861ad0577d9e0954314d176c613d2a94dbaf66e7b21a29d13390347806c6eb8d8e2be293ca36100e317135e9b3598baa484b02bab3bffeda1544b091a1c7746afee81d7d5d35d00450448ed8836489c25dd16d1b11410df100691a9a42630971c168141050108ec2ee17a6e5a33e0e1846dc8076ae91ad1df7a91ce0eb40fc0ad2335eb804cd27523dcaca76a6050bbba8aac8a5510538f81d563a1311a006efc7e0523279cf8096859931d338c19073cb156a97d7ba2aee13d8a61272144e6b59057eacf9720cd6e7d28ad6a7118e6d39ace23aabdfb4243970394f244972fd6d7a1b180b280756e22085bbe2146f2476087737aaf3caac93461d26cd447e5889f029331cecaaa4eb86609c29466f45ea4b37c2ae3ebcdf66d43e8b4242ea71b0df9376fc39c078a3fde4b1069e99929d99dfe34624bca92afb48b00d7e85f33058dce5c65579d6abe13a041d5e00c2f91046692a5a4b5fa5e87560f631a36dce912937585eba7480a81ba91af6c2186abe8cf7b4e13ef86622c208e5653aebccb63130a71b7d7174b926fc74de4a4bcca7c8d48b0daf7d319042ad2a949c55650917596a9417ec28e4d3c90ec0801ec01858e5d13d8ccf3cb1f42e428817d2baa86173e4f9586adf51141bd3d08267813aa4b8d638ab9c111a6e69454ab558cde8f1ae91e0f1e941e849ee7ef53cc6bf1139cc2522ae8d682e1b6c4db888298b90c499f3f79d1628c9fec96c9e13a1fb62280e3464bff531f5d9a0217fb14e7257b512eec1997224175a26655aece977060c1de4564cb6159a433d26dbf2916810a6ad68f9ee7c58cb9028b89b8ff7854c123acb1660a1658367e4bc1cb0022c20e2e3e44673a8d6731ed0a01f6ee9c602470efa0ee4b9b3d8c8057dca32156f5dca987a08ebe13ee503e65b572e86983faedd806c77b23ee499edf47c8d9fa0586a301c553c2e66a74f2d604e0c9657589aeda5659e3016be8d839befa905b7ea6ee790d945bf18b79edc533d6c968eb23beb3cbc000c57e783374ba1772b5d82e115ceec461f581f8133189abf8adc9020625a1b843f2d5004f4ea2ab2adbb6f3701d6d5959ea78576f1d2fbeb792ee4cb8000c53d1168b12abc0e0654f2993716800bf35674702c9869feeef309f99f5829642376385423095e1e116cc690da62c6e343fc601c243669dd5164c6186dffa8c19471b95ecf47ca301eb6290ec3bf210a5a2c2720f3108d181b91d64ecc707a7908f43c7fe2ad28af62854bf7b08b6abb25b868fa0a3407e87e28b14bf87308cfc272b8563a56da825205e946e2a1199e26c1b91e2170fabff9cacc1fc0d36b56d59f5420b33324fe0342afedfdce1d7578706a4dadc90493669df4a9d8854ecabde9ed512ebc43bdbef94cf3aa733adf79d6c70257171666d6d3569bfbdfae0eb8b64afcf1a8f91d61026d913363b5c382a86b04e42af32dbb6f4aa20e54e738ebe1a8e7959309f6320546787a2e27053e1e0963061e1d416f71668259e02036c408c781b4fbf060fcb08558c8342720567a62f3e71fade1facddd1dd41ec33ad4a8a45a2aa0d5429c4c983abdd640da1d3cd4b4847b6b23622e9e8c291d19eccd292e7afc7b021d200027418851c124dc282145f6e06caa427aed0266d5b42d570f327c72ef7463c2d43611dd19700cd94dcd998a4165d0153c700a52d7df4528181b51bbb46d9aba9a2f09cb114119c850102a46bd8ce933ee967e78be73b553ee8f3c4efe701fdc3bf9474c0429227d380141ab2ba9db26be0cd05630b5c69b64547459af74cc7e32e5259d9db70c5e6057fc96dbf6e224dac421290bf64b86c458c14de9262c458f593a820847a972ca04549a51e9cb65a0b3e6962e2279b221902805d7e7ec8fa8ed1e450f5aa64efd293cef930bf494bf627ad9b5559db7500ae09bc4e683cf51b054962b78275a38bd1cd770ea5f3eb5fe6ecbb8d4a97da8e144fa4c1483c8bbf7f075d7eccde2344547bf5eb4e123e32b4e386cd5a33daf30790e75e241c64a422c5bffbdd8f0f7f1b889b6a0c1ce10b9b4c3d82b183ef19fe24f3d0a50e6764b2c471d8ffa0be624aec667bf55836a42453e1ef829206f83fe7f9b82b5fb1d0ed23aa5f0fcf080887ada006d788587a0303a2d01972d67838dbb34c6f4db16fabd6adf768a678be1158ac0f5028d8aa4f9c79c8a96e84850943036797096edc4283fe8de56bf1085c12ab316430919a3a4ee0ecf9a2c03b68e46f61c416e7bfc9fecf8f9a2dc5023b16ef9016728018a708073cf73923a9a92b8c02859f22d580831b9184b35ab83513dd912341a1da805de2b60601af2ddc3278acc150cb048ea90baec3f7d62abc80bae49cfd77c86b14bce26887d8cc5f43ee4a50fccc26308bac3c34e0097ff90255ad25ac586635cf53f11948ffed951abc762b13504ba0ec3e2130e79800328fc1819d6af7cdbf53ce6faa2821b6c80b118606f548146490e3318100250d38fa1d60970e765c36e8735599428109381426e81295e321c5b317cb61cec276010e6eac659f46a0dac4f1697d64e73b59b7d8a90208e7bda43ad698e3d7c842a9cd438fab919c37d19b92eed067de966aaa99b67330a19f6770e66eb74fd56c7ce5974b7d7ce694af149d475b968c3adbdb25801fb0cfe863f7586475e3f7f85946240ebb68ae3d87100aa01fef0b2153c4e97e8538891076fe31dfe7c7820f64f4079306f1ae1e545fe176fd42a1eb79940f3fd29e0ddf471f834c316cecfbbf57c89d87b5c0c6c7b87305821c08193f56c2d7412fff92bf8a1936b76774df04ad09d8cdc4c8c203a59efe638a348bfe19c36db386f037df7491e37b99f1d791f581cb6aee730be0c34c9d4a8ca95932cebda112ef6c6bc1752eaed5a0c7737bc87e9c65513359e2d8e50f9c1dec5e5e52df841fa79903b36017e29c131763632e5ea5d4b9c7a76ce59efd1c25f1420ef682fa8d3349d0a1b9d4adf989cab8c24a52a3c61c9b0ddf8f5f2e914777c39d91e0ee3c059376bcba5bc5e502209145b9522cc3cccc912c9034d1a1d1331201b5b5b821f27ecd74a00d7354ddc345c5525bbf6bb655a0270d55e383439d2c6e723d053da6545d00a4819ccc602ab36a5a991b0488cd8c3851fa5c155bd8ebd0cd25c4138a5e420c426772132535dfedf1e3cee6c5bd828d6d1b67c697a36fa8fd6e654940f464e9fe9fff9761b3c733ec42b97c3d8947b2baeff39bffcb465a6a93fd09323ecc1b4dec9b6d9247816e1d21f91b7bb3591ef24bfdb92df5d5f5ff6857affb13e0690fc5e897cf6bb053d9b8d2f6eebcebc07e6392fafef6c636be67a98bcdfadab7f3aa9bd20321537ed01645d6c639de6f06f7d47874dcf9fc08377014eedce74ec6858fdcdb146f03fe6ad667896844ff9a581e75f267f4a70f010989665fec476f58761055b020701d2a5379cf44ee1fd5f12e020fa5609b17d86fffc9f13feacfeee80068247b6be7c82922a02353ab2819ae6bb492456dcd979b5b13cbe8b14a606107fdfdbfab43dc7d2d353a050db90bd93b06a70f6caaf6cd6f6396dfcb679b577a687db46f043d8f3aa649676ae6f3b5437071f27d4da4b970e236334887f8ffcb3b5ce38e6e185362da12bd1ba655bc178e2bc9c81739498d8ad43cfa14c0d3aa8dc388e8e2db9e8d76af199138cf1eca9eb77480cd12fa1b791992ad1d2a55378724a371792730a9fc567cdd6f6642b99468842a794d8cbb4f4edfcf7da62f0a39137f0ac7f8781a68149d89db4693a58f17c1dd3a18c9d0fd7de2df14a1716649dbd829749c70082eaffb65b9a62d6e8c6c7e7df1f6e09bba8404834a0c955c46a63540b52d5d3429d16de1e1d504e5cd93706a9a756e4ec507a6ee47f4959c2c1d1fe500d368738e57f7f1a4b69575035bcba2f2f64c415be71c246a7b84e504088694d94d550afede42fab9242d4389d696a463d84d53d84cbbe73733a25b060af67a2fd2c04a0ec1a7bbbac6a3da27b28d70e7a5cba5de227ece49601d82f761986267e640c003236335d7c657dc4e758d9c9f93dcf0729bcb1f74eb9d8763651b49da33db4878d51ce45fba5d5e4c54f02c2b5bf01e288ccf143b7693698fa5baeb4fe55818dfc0b0e20de8effd2a032c5fefffb78c8e32f64809c5226f2d89ab5588e756c8de8d87d19b8a227c5b6d1854ba8e628dc0237d7678dc7e4f6e9b6c399b4b94c7bad0a76be55ebf4afcf07ab52108f203f8d86cd5b9e2ecc21a0378f9efb424d649f98c9bf98285935457d5e257cfba04979ad3b573f8ff9420dfa2236f6327daa75dea658e50095701966042b1162da3cee50be17fa9a6a9ef3f47d22cd487a7bfbbe119c6d41dc0ab25eb139169606020a3f45c40e3ddb626e7a5fdaa304b3adbbfca533be368b06263b84705a49d4e35572b6637ee2951146490df5c9309e0f1888dd970857ae8ea6f0829df2b4c5d0461cef026f11a745a30fe853c4d6a6ef044395a5c30e42bf0626acec35ea667a70e97aff074e3ba5f4e6879bae894ae408fc9ade1bdd0073e813dafbda09b0caf54884be0ab241e23ae024800f6aedb073c7cf1f3a2e143179c9f1f387e119513e84c441063d64fc15ed9a3076b86bf0577f577e7bd647581f9b4f2a105e21a769be2176d46fc439266a81402090c47c78efb9d1f678ef36e9ab51d99f0a355b2b37f3cacc1f39c79dd825005e2f8561d9c062b3d5c7427ea3de2648634aa9f51fc77e55fa82feec00bd5dadff349af470d458f5f7b68b6aee87c08a56eb780e54061166fbd9965a95f57b3348298e10f498bc2c1791b86cb7dc80b9fe4a465a65c39a00d3f80c05eef754cd1272edddf9c1c9ef3d2f62c2258b917cac6ea134c8541d96b443fdbadb3eacd03483bc86080de7407a6b2a10baa55da9b73328243f5e9f2ea72a35317dbc80697d32067c736d3c09f8f54761866191f4413e080aedecccb862f275f348947835ee74c37f3e767ea7b481dc8d474ffa9b4901d786b60ac2deae808909db2c9a557aee54ef287fc0a992bcf8eff2e5e5ba28fb0d3d890f7db7cfa1bcaba8eb3cc121a9bea3e8161dadab45cf886b93044a4e24d58dc456b8e44f26bba839aab96efe0c09b278f1f1d6c211f21a8adbce790ce6a82949c2a3bb4f06e20e59174c80da13ac17a33201613b80188720b89d5d6f6de42efa45c3a632eb451883d96e82dae06f289933ff6ba7ae0d2a6adb4c5f488df4f5641e208608e867c0890038eada26c1a091373a41c88152241b38a14eba2ffcc171de81386d4cb5ade563d181ae71b59524bc7adfa7d70c53cab23082d40533428bc062cc19012377fa04de3b85596ce05cf31a399bb4c6b4890aa8773195c3cacdf59f6dd171f64be4538517a58667f2885a65624b228e8354eb6d91e99a8adfbc714ff4d6bcc3bfc8d82a08dc503e3fed5e607b13101326c34c39fc40028e0d939b0e89d949c489d632e0e9389123094c34795a9672bb0ea29b7cc11a4aa5f87f73783fde9ee4749efb2bda978f73ce0e46897044ea1fb5fce1aa3025303d7a9c4e99c78d52047b3fb0f66d22603a0368323723c8a58178d21b07e5b61218fd87cf3690fb6b40aa7444238e40df6f03178c91823bb2885f289a85def11ae17d927544b52c809fc0659c80428becd5bfe60810d253eb6cc2afd35818fe38f4672d0746ee8e861c127162a86555866c347215c639d3d9c43972711aec4b35205b43235ce6bd354d2f7485020516f9fc7b9a4c21ae9eecb6364936f3e78b446890d20ca6c954f073f6a0cd214d02bb7d071107775a1f66e6ce40eb36309dcc7bb8c978aa5f9e1afa9cbad9f62bf813b4ce8f1804f871bd466e0a1297c9517c8580e2a110827c0ddaffabd3068748f0de6f9310650534b3834409cb0e40f09fbe0d735c2e826cc9130fd9d4d2255d184478e0ad4ad15c45c3cbe3bc4c927c99121104aee17d5b4307e70a1003b7e89004672b5701702299b44ea85a6f79161bda9b1419ebe8fdc816fc58afd661b7d84779d866aad97561a9f080c6a5a78a25ac5d4f8fe185d13df36c154098588bfd6448c94a8af2ee058d0eb323cc5082952f18c0c66459f01e2cf94b22d081d698d564bf9e30dadc7e0ccdf160685d1ae9b058c077a3a69af254f24f4a2d1b53722b3864d4ad93e4e6cda41b8d20312152da35fba6822638b7e2c5753396e10824e50a08b56d6239b11f2ff9663326aad07240bc4b3c71205c220046e30baeb900ca1f62befead2ac3ccf48c1536152b09a1a739e079fc0e3eecf0f7667b413496428aea1a64bbf36f4d73b969a15d2d421cfe62f12f6d62711da4258efd2e7788d2453a7959af2d5aa4283bee032c6898f6ff97125be79c3e1e58e5c8a65a8c0b97c65825fecb58e0b12d4b06016e879c4100aa5442c95e6b4e22f06b5ba1c215be630211a9117fa382ed6927f8fa00f299ca8900901dc83f6d15cdc073667ef89d9335a10f601b9851f4e0fa84fe0fa8d09dacdc16c7d30c4de35b3fa4bbcd8422ca931a43de0d6b4c7dfd3c439b68098c386f3c5cb53a3c99fd69bde15e101873d906ca719f9f786d2eec9cb86396caa899ef897e1390361bb4b634f140f389c5320b8cefd7101955ad2ce57c2b9adb5644233cf5fb0c5a4334c6850b46685e637509c555ed5b8f17385123179be235644f58e683f172b5e1a1fb983ea32d2d340cbb7c4eefebe33cca9f31a2ebc7a2c0ed9675158c341c47465f195cb6d603984322d9b624bf19d707eb3258994ae8eb961c02089699e338f5aad69f515c4b69c9a66ba3da86ee83243c3e7400433d70161d247921eca8df4af44653753402b9ac0da33ad613d1c511b32082445caaf5dd9fa55205a904498597903b6c34ff133055099efd694c1bb1cd75d143332444c3c797a9c110da818a4b5a5eaec7955c50db43672f694ec45d4df7f66661d2c2a6b4c3576baee7dd187a70b8945b50e6b71c53281f7d7f5bb2ef3811db89407521d41e4ec2467c75fbd65ed35e8997de081e0f10459c9267dbf7ec6f57ef83dd299ca944748a735f06ce6567227b660c490bb484c791c304ac6ecd3de111b5285371885a19b201d408ea884f75e540b73b32cfd732b3e9aef0a7abc83012b5cf7526ddecf8be70df2b1d735b1029fba36a8ade9f7012fcfd6a57763205bb5c423810632cb83d46fa613de42219a23950fb22e6c4286f8ef5405bfbcd2ad748457f901e80f018b481b1943ad0af8cc0b59ba8fbece0df00f198a902fc582588f80f3b5e71973ef2789692ccd34f55565b47b0dff5d7ad884bb2c5436bd1d1c0c37925792cce169d8a432df560c61392664eba771f829c9b30a69937ad7f527e51d1138176ebff2f6a38d2b0deb60cef44c6392ce292fabdfd43899a94371fa48233066d5655d6b34a94f102f8af5bbb210fe091086e605b9126451052c5c511c63847e5acc8ae3b77a71fc5bb665646c5f99796a7955edf77d04759fd25851f50f9ef06e9968e430124bd0c0df827660e6604df3899018a5ef0a4cfe02c4f84e1ffbdb159e594c161b2ad84cc41c4f692aea26bbe5823375f1f916e2e8e2cca906e3a4a17d936c72907d2e75e50bf18c94ab2b76c89b62f11b72c10b05cfaf1a06f46a9d32ccaf11573f5825af831a82b65c5a5d3b41566cce612604f8c77eb8e910af2d6e86e3d18bbe5f1b249a74d5b70213bd3cc507bb1c22b48a96e49e4af0e364cd7a965477626019de3f5cc234835f238623686cf87f2d1395ce90568b7b4b83bb863e1a92cbce07372a2e2e98303b8a23edc9030c23bf90191a1c08074545e52856eca92e6c885f8f851d7c4cf714a8e09519b38fcc41b71a45a93e592df934d1565f3589cff73c1558c99081cc86d85893b99e38b8f07c2769fc0ecca0d6824b6d630668a673694c4ebeac09773b0251c839bf62a883208cea636079698ea0923a0a65cd00cab9b0ae751f8764cacfc8e7d10f4ac4340a2de874e4bb102f6ef2b5f5c76cf4b83dd7d039f0a57f2d344e12ac36e05d2528493a54bfd6518e89ae547e92967ab1311f7c348742cd9782e47bb6d62791a8c5d3d0e07d750b9e7ba2e95b6045d9b96911d69c4ee6b38c0543ab5580860cb00b23eeaf1ca42de20195f9350d1191dc31d92068b1c1c654abb1f597c29ee9ca70384d58dc1dc7935303be6046d416a080eae95fdbbbc7bc3768844b363901ac24005e7193d2081516e2f65451824dab3c92e4cf271a1129698f69a94d34f9e94f92632c600a0ac56e6e77cfa2f08025af1dca0157867bd52f2ededd5d36dc860404f41c9ad5055e9a42b026ebc06b201bfb704a6ca6de4c25d55c322f381bcb010d29f95a02a3457d88820b61c3f449d21be6a35077f4753d45f85c5144e8bc70f9c37beec2250dcfad7f37d43be5f37897c33a5f90862576f78de3bb74f6fba982ba0138260596926b0ff46e5fe61173ab5e5dee21bb168d806d2ee6baebd11cdaff296f3d735b4635e66b0f72e568c150fd95798584152d1bd41cc53adfa34feab41be01aeef69fa7b88fc2fd461bb59e957fcac1124336751765977ae2d3166f5969be74c101973a090a6bb79bc48cfbbd7a90326ee9036ea9b952b3f6dbae2769ccc7f50e8c305627983a43554747cb6e758d03dc1cd013fa3fd092511877e6c97095713af64696219427614fc23e3ed552daec217f30c4a5df2d9cc143ceb916ea9ac9fedc2009745781bb9d1bff68ff215b9ef961ba29cc897617f2552c18ccfd5f57fa966b1b7b1e4f3352432571826eae9037c190edf02e564142fb8c6106d4908aed02062ebff97667bfe7d2a3fb119fd0a7d541200597b07e3dd174797a9064c98483eff842f9d799a68f0a7e6e5e2ba769381426dd965a05a3482fb76929babcd55c6ae123471aa05658509fc43f0fe2af17ebe499ec3d96bd0b40a3c763e14765560ced0778d3696cedcf866ff528a1d44e68ecdc980b1b806dfbae285da93f53d60d99f7b391ee08e6835cfb3b04bb086e062677f799f55c1a3ca7972e41e94212aa5bc066850a01d55974096fd7fa9772094b1ac2cf132ec3f391adafabde8b37fd9f2577ad3d48fe7d663f33c75f7f8f685e579adfda61513f7ed0e5cd50d36cc6bbac2c0e296f20f2fcdffba2e6ab0f5de5ff6e2c7195ef6bddc5a309d29e465273a11b87f754e93f7ddfd1c9f1fcdf85691a527f4e96a9eb1ff4d314e670d3f3f8b07e2a17772075e603f52e18cbc3b6aeae653fc06cb027939df48e671150835426aef1c0e60e70f2b63bf569d7e02c93fbb2144fbe55472f6ecc358d0efb8f6772c7e3f4c0acc2ff275bc1cbb7fc6dfb3f513ca66d4b49c98637db97d71e0d8cf8b952e3a2ed888ce7a6aa191dbc2acadf2e85a714765d066f6c4a08fccbe9c045b5eaa9935ee6f0ddae900598db48c61e6946956d23bb755ff8f5f1ad59e340e3a7cff680ff01e870a3b3e2d3c17331d2f63a5a37d4ed0554dd3efd88d79df328f853d59055ae8369b44ff192cfe38ef3e8d0fb60b4f0e84b7b742e2216a4c58b3ec598eafd6f25392f839a6749599aeb2477d24589d500d1f0f9fb46d7167d96b3ca918f64920a30c00a0fe4b72a03f9fad18eb751806b5ecd4e6f760246164c12f0a4e8dafaaaed98ba3d7201f8a8e9c01455bce3bda8b9b66606efdac76eb2fe7f17912a8f1d550e8656f1dd9109e5e6e5147b03c285e0c8ef8fdcdfc1e91043e11357d72cd73279f85e947efbb1144de18e7f053b037ad9c87b895d047c5a8b4be06f128594a13a76b3f59e214a52eb58fc544097d2f6e4bf811315adaaf8869897e407c4bf50331d55213fea7dd34c67e2389cd5f510a323fe8e3ff275b6f958ca00b52e492ac7a2a94075f58725458893f528c4bfb756228f10f156fa97d4ccc4bf8dbe256a28f14c3d27eb5184ae4c3c5536a1f15b312fcb6b8a2145c128db9fb75624829c74f87a2fa9a6881752847a8ed189c48faf1577874a9649db0c900533d46bcd2f97730fc3e4ed94ef70c8bd0f3b01c2cfc83c372fae415f96ba576f66c694da7c3b6ae8117cc0a0e70898728e43e3b99781003c241e303e8f5c4f2f49c7c6e44cdb049559aa01c0a4c4242a198be514be22e2aabe4fbc807b1e07d18fa4ef4df06cc3d2a3cb2fbe7042bdc2f470ce2c740d96c1d3fc70f76065da8abaed6b1bf29b27f417fddbde7171c0b50ff62f881fd4174a3e7f37711c2bc0efb7731b74c51f625a0c7c4f9671afa6ce1e38272309f3ade0b85b3a7eeb7fc8714e093dadd60412cfedada741585c7877d5a983fc7da028ea35b5ec6c73f8e442414402899c27fddf7320c3c680abc8787d975a149b64e20ff438ca39a09e8c2fd47e274f341fbe376fc76fb650ab21bebd8a84a83c94cb017d8a26f2c980b7644dbf1981aa2ff2b5dba720658f2708676642e80eb1ca6ff4509d8df1e013c622646bf77283a342f98450a4e9f1363b0a3a7cf7b80d307bc7f904bf2207e63de206fdf225cf393959d397e8e30a1bd063f7d197ec2ff2969fba259817ed9c73e4cd804bc43f69ec4300d9db04269d03b2c7f289a3fbc65cf84dc96087069faa1d27a71825fd2c56c59c531d5dfa231372c2ba4871f3c17dcf7f82e35a4c17326eb696859c0d3e32e8f49a32580d08a037908f88824c338a7ed2dda36079e435e238c2648b282ce971ae9cf3b5ef9e7d11d0ee0f161c726ee3ef547f57226ebde3409d2343ef7bda5de655c26a36cff1c2ebe97ae11b4f09a8ff7f3787be6fa42dd99c20b68509959eba0103fbc3cd0b85fcda59695747660930e71cfd17f52026429be673076b6e906c8137b556aeceb1bdabf7fdc17731fbbb8600dbf2f663ee7a977cdc7ac9d806a7e5115a8cfb22372a5ea66912baa88f2cc816a7801fe481d6509f007a8567953089b131df0b77707fa33682735917cdf7bbbdd15e8a9f9178f9eb0d98f1c5d7253620254103e407edae0d518be79e2542236a1929be3ed1db6e80e8ed27b349e93e816696a49916274233abdc25e583abf54abbcd7fcb2aa5b84bdd4a1b928be84251763fcf57471a851fa933a866d9c717cb49dd79704c8a17aae5f23dad3c03060e1f1a15a9aa8d425cf7ff15c371ae29f7a65c79bb6735645dcb2457405975dc2193a17c361a336672e9ab5852bb8c643e73133d8c541068ceebd3264955c86d82e0cea063be16a27e01fcc0ffeecf0776b1028a601f0d286cc2c7ebb077a284d1a9b858e750024ff51bfab29629cbed7024dc7cbd069486d8e728a2766208028053d9255d1b0919cdd9a9a22115508a8a7a742dcffdb1bcd54f17a53687ba5c06adcb2f422e3daa181c661909c2ff0a0c6a4c8394863e81f959ce80f0462a04f0b1fc589e517faf0b21ff51a55b24c88fd0c70f575b05027e78141f444ee24ca8821e27a3759f047dd60845cb07337c28d97ccbe8f4b878937da77ecb135cd0b975df8e41bdfa6bfafd50d52ab64ba7cf208acfe7e899d5b733726a7f138f3e385151fd80c79b1a8e530b16374e437c8bcaaf4302c35e2e8a08a0f6d56d822a81bd7a375c2fdeeed844f2f08250e2a1e21c28faedb20bd3bef37aa41292166a077e905ea7dc963cb002c8f8f8797405ac117e6a85296c6bd696b712555cb5f6b08753badabf6e6cd8a180d1d7ff4cfc3305847655dba6f86e63a94b0d305fbdca5f76d2e47a9a71a4e5d0543eb84b52f7e5f72d63eb798e3db4142f3b6a813b48ea07ed2650048316a968aab17b3f88de9b1bf31b6cb589014980860312751de6646772a7de7810e7c384fe0cf691ebef9e755280f2ebbe83ee0f91edfb9d606175dd5ba3afff4e1a973a0040da960ea1d6132b2d02e5e15599aaee96345ba18e2a5c2040777f9a6b8e5b5983778ff64a2f429e24fecd70dc17d3b0ccfbcfa1f6906e0241580ed52beae68adb287003b38b6d5a876a72d7fd2115e8bce66224437d05817dd9aa4e4e8b184917fb91127809e2f1f7b0f8305834f7bccda695428170040b0040202909d7e23e3ae28a06f38505a860a6a6d7b329a8f88b48e4eb14121017471484d1380ce43dc2393846846347411741beaed5441cd711e32ec06550722fd7c2e34606a17b37da567757ada31521b130d7d68c3d8c72a3a7923d052900aebdf7092a25880e58c7c0570f5e25499afe3205432500ef9394a4470a05a128304fc094c6ea14765a615c76129065a25bd42a52c70bb2052149035d44dbb27eb849ccd0ec4baa88222ba097fcf3dd06481591e418df18b4615048a3c1f6bd7b731d705f71539dd6bf7844ace455d16ba46bf984c5198fea58ef4e885f35bbe14ad79093a0c2fe031b84156d44dbcf0b9a50125f5342e1923ac038ad3e2c33baed7425d0200e4632e4ab098b855cf27b421d153ca006a5b454760e35b16944c77fa8649fa625ccd7a029772c0db051614f1a2e843132862bd5673a79537c1ae2a5cda1b23498e8d0b4c29d033cdbd7a426c1c44f3219220e3829fa4be0be07fdbe206d5392fda5ec97510be25ce457db8adcf6da9f25c5e8ad5fb6f7038191faa05952b06cb6dc2fb738f2d1998f46d9a425f79c7ba6436891741d1110f26252b37f7c32bdda896d39c8dddf5c69cb332958513ff6cc8844e3ac608770e6b3b0b7f1efecef90fe61a92ff3e932e91046f398a060101ff73deeb5832722a521f6383fda09cc158200eb0a8d1dddb146d16090516af44240a8eabeb36ae9f61094c3725d08e958c91da04ebc23524d0c82c69649194864c860c34b0b61ceba813f849cc0818d8423d3278799d874839da961552928889aea34aea06e63220f1a4f6a4c2bd241115cd25d61a078b401d9228dd6ab12986c8a864f1a574103eda1e730005ea4852d3fc0c353bdea272bba9bba6278097b296e489dca86208664b15da4808d0a11585031017250d885ae94118ab6056622d37fa4089f8a0500c48bee72b5203e12a41db928378a9e7906250cebcc784728004fa88c1e45913d9b11e030e9bf76adb05d12e0ac24dbd4fd694fd74a889ee24333b0236813eb239147f0a92bd1ff4954a4d088ca98f9d9016359229829a4ebc135194bece23756a3cdce90bc0a5055387200a5feb0d2454ec9ddd0dc29d32a897f43e5d4fecd7f116d5db3ddf994e01bc74d4049f24e461bf7e2a9b02eb6c1bd8671b940b364898ca36b857b011a0531641972a2e22afc1be47307af6457352828263e829ce94488e152d7bec4112140be0a5ea2779820f25540679480b82db28a951cf3dd5c9695d556420adf3048a40995c7320e283c9794569488a9c41f1811213e60715c91433c45d4a22a12b235e2cff6ab17ba95d6e4b70e19be266d9d08cd4b1e830668a54710a9222d75cfc983041cca5e4c92501eea41480e782b3d595e071943daa839e1e9c031994e42183c3dca97f187646feb878996386f86d89045c8118a31b123c4899949e4820a8131ab04e05acb74ab154aa1124069e1929f62d026757d08fdd6f7b3b59f81a8db90e4c3ebfc1099554fda31e261d4afe01221e20c9e197da0dedd099e411e162a898ccc0b59b30bc2bc973c98829cc04e8b3328b5949f67901e34b90fe1c50570918be2231764ada9daad4b03c3a7f48a29be45cf649ca8c14e607ac31c4a1e00202d3f12f05d4061ecd0d50b460f2bdad083dac08faafa0bda998bd51e1fd5ac5f07eaa68052ec0923ade6031939f70a27ef371eaffc29bc784302e04369a8eee31319787f42aee136484045d104c066b9e5609d5b44c58dadf4315d4b44cb8a4f784189d13a636cc0f9679fc71f6d2189d8db67f6e7aa962d7e09d091a7aa2c21fad8629fe506da6da4ba5fca1c2ccfb413599e3f7ca3201176205f466da1f2ac9041f576bbc949882e9d4c75cf6631599f9a7ea66ea0f2bcfc42e8d5569c8fcff553073ffac7a26ebe10aecc10affabc24cf596583e6d4cfb673532fbb7aa66e607abcf447f57cb2cbfaf10137d15cb497326fab84a66f879f598fac74a32f947d566ca1fab9da97a4d4575dd160b6ba41953fea362e6faa18acce073f532e5879560e21eade2ce5eae2817c2723268c094fd5dc12f569e69eede7673ec79c51cdeea46163ca1042ce21b1f799a98f1cf8a6472571bdeb4fdac70d736bd9165267b82c4fce223497b26fab9ba4ce8f8e636733f2bd2f90d6d70c9244c70f13dfd1875b9e105259b0485a29b89f6a142f64785ff5a0133fe404577e6f1bd4a19c8ae8de8f3f93b10be04032c7d6212acb7eb2c4acb9be6623bbb149435dccde9cb8af8b8a24ca087d630b266e399a99bff6d4ca524621bb0342557cab2cbc1e4e11bc218134b69bc486ad2552ec46acc2e6903040cc7de78c0f2469cd11e19b83e062398153dce720baf910302280cb921efb40a81510dd705928eb45351548f5fba2c540600f04403a27182b4289d905314cd100706ac3026512a867ea457885456209dbb064d52587c5b094b3c4062c08f7228c32d609116b4a7bacc510ac8f48d00c229c222da216202eb06b6b11a93b30f4579e13874c0be640f9224a0307c17cea80ef4d3ce9228027d8266d66981f9d024c6075d3b84820ab6cc7225f38fc237930a61fe736a35221f4e446d581e9dbb5ae8a732523c07c05d32d3af268c4515843fd7c4495138799ea2e34d286a0411dbf6d7c6ae6cffb8eac76d7cf8b687ee3ec7f687b57e68e7736f3d74eb43f63f57f3435b3e7cef39371fb2fdc3ba3d37c4cd07e711897fa181f1154a387e4d9c148593e789f48c9122170e18de5879a95c7026adb7c5bce8a5d489e80e04ccf9d3445d4860f035b599b8882d27b97c7c53ca2810b1d34168c60a0d581e95ce520ae8940600b302e9ac6b28b1622d41db105cc62fb5140a0600b8948cc0359831ba23912da02f74209d53488b6b83144bbc97bacf510ac8f48d006105e1a0eb6922c3b2af5299a5694404e726802a6e004a881efce312dc0e48d78efa3893f8ba9ec26528ed6959f05aea41c80075085a081918662fee8da92382415109d70862689002d942cad77427a6c663a629db9bfc286e8ca27756f83e59e16ef7612142f4caa42f57ca34f6bfe2faba427bb0c23faa30d3ec6145ef5305ee6f45febc3226dcc3cafc7a554c739f15f9fbaa98d057b151ec1f3ddeba6e86bdafa01e6ea6ecbdc49c1b06ce1eaf1c596ff8ca47aebf4d4d1fa8b29879ef84de7e3d560c7a8669f4f4f25ea93a6d997501db2f6d7016cf7876cc0d2c92e5032b5c33dc886d5b8e574f4f03fdd44b34998f43c91381b79ffa4b92b898208d58981057b2e945ea5fdedf546ce685da1bba8106222ad8813dc8972bf18610db085ea2642a98089a28af7d840ae22b9ec0b99a2d69a4c11cdc76e79ca1dddcaa82a35299f3472beec90cd767531dc851e4e1cafcb02a84104d94a1bb3432944ad7a8cb4919e3a52dad9abbe970005519170de8995d82c5c012f40530df0e40baae7b0448d77fc1fad1d137b24dd7ff5cefaf7359bcd29547623fbae2036c3fba18a8c78b29dac03fa311fae140d6adf68ea36ffbbe3f28e944ad9be8bf2efff6e7252508e07e8fe207fdd00d014355f1604899cd57b077d4f3d98a7632e423c54e0270b6180b379c2ea0d674d37d54e89fc1454b89f779513b521594f5ed369d9baecd5880aeddb6d72eb2d8671eccd9f54e635d5d9479c53e1b4e8d381019fe8ee7ca3a6ac50503e8a68b31eba03324ae36b09516512c452f005d56afda606a9ba45140a0ddd529794b0896b2c45e0c232e7f029ccf042a18fba2561040cb88d201e332d72fcf33a7a7b656bb4d8000740ec792c193711f8f18a2f7c8627cab599636ad4d93fd7e646fb2b96d5fd8ec6adf387d4daf78b9570054c11ca34f8f08e851ef92457d63c83ab6c3af7688369d02310a020a180aa530efbe1a9b8cda6aa6a984fb6f5ba6920ea652900edfa633945913c9cb644913e98a575b083787562b8f8a0a37914c249b8f494c336366ee889ddc34e3fa6f9a919dcda69771c799343d09d3835236cbefce9b0937fbd8426f1fb68f6b67f25a69b3ace2f9ac561e1559291f63fe1a141f59dee5c6f2081f955a1e44cb0793773910e306bfbe49171f92ca3dc2d8c3ee91821e603a8f5a02543ae4d1ea576decda79aded508f2c3e3f2195b6a547fedfe5c08fea61a447576bc11e80b1b6074d7cd5c6703304ad15f1572dcfad2b386316a4e9e431e5cf039507106a79c0030f2b303c5c303c8a941953c64b192cff7397a99579f29701d255f1300fc4f0800a18682d6ed8edd5eaa5a3936751e7796135281d174c47e7950345a664eab6ce2b07b4d60565de86d96aedbd2daba38d81d6bab00e688b406b5d3aaf1c9da6dd59bb23067758e972b154f7cc1369f6525ef70ce6c93b9ebcb3a38fffb7634b67b3b4a36687bc364f1a955287982cebc0420694ec9e49098234bc0dce3a6a5d1d367f1d747ce9427b6774f84007ea5dc7f04759a0b52e32612e844c1164a69009320716731cf1e4d166eb83923a2a5953296c07253b5af7d3dd467b6b79bae6f0f161cd01448e313efbb6087efdc185c801851c51ded15aeebb5abde408f22e075efc2f9c1c8c39407d757ad702d5b6d957964ddc8f386f469eac65cb23e308035aeb9ab96f4f1c56fe7fdf4e1c289950111c64dec1e1e57f111c57de8133a4592482e3c99f47fbc69837bebca1e50d9c379ebc5184e5869723954ed1d6a11b3837726616d7f214c784f9c764f918efdad9187974416bc7dc2c38db69438c9036b2882c1aab0d5c1b32bcc34792d86c330ce78686b09b3c5a9d3c451c36e4ff35c80859a3cbff35b07c0d19ecfb3e9608ae61f3bf4ba2861b5d0ebc754b67c9cdadab1a567e355cb63ad5407569d49196c60bd2b072b3350da134404063cbbb99f564aaf194c99cadce7badcccd507678de84a0e1fdd7ce662d2f951f1a36efce2053833a43cb3b95cde3b462c65694a93a7486f8d3267806ea97b6aaaf4b8c98dc39315d9e6d1583450c93bfc34119695b47b4768abc1baac201141cf4a54d109c3910540ddd808bbd81ec06a7ae6b6ca4adce8b92f427cf1aa6526a98de6036ebe4e02c8f0db41c771bb8fedbc0a6abe2b50d80d4fee851c3720dc65c2b86b40661603cc5fea8c0aa18e5d0da29924da8541a7e77dad86c66319d597b4533c8fc6674f9cd304334439e0692065174aa0fa4b5d747611f85d1600a0d50fff7cd3233504157c5cbc16022a4ae4ba63ed66a45d369c954504e182ac2a06460860c222003da73754776d5cafae6020c21c9810d5a8ca4ce0ea5602c0318b26c0ce5cd067d8d47580cd4f89728c159a2042728065dfe1838200653ba18b00083316070c53b3cf1a5a9bad299ec7aec618a56e672ee2bf6adbd60600506ae570a039b97010625bd6bbd3286ca9852a7ac8cd4ffee6b71be600c212fc0a2aa2f78f27747b7b1acd7056584b8800c171cb9402877735fdc4760e3f008b438f575e73aef1c6932db5a938d465d83b159af15c3ce1253212ec06941b675d6c4d997365d2d90e26f410f984aa3d5ead58222bf60dcd0d1c9c177b4b11a8d7685d1a64b47a6da076a24ce0ecac1a9018acd9525534c4671762de309b60fd4080c0bc0a096e67959908505f43af3360b80fc1d56653c672ba06205525660f36ac5517635599e5f6ddb9da14c61cfe8f3ec4ce2dcbc81730541fe4e055ffe2a8964a7825a0acfdb3115d878d95632c4bc23c30264d4fe6e764886cdffda3d461921637ce0ef64b38364a5aa3ac26c1e033746d01830b40fd4a84647e79543ab143787bed679e5e436d289225339c0b2058db205711be5daa623531f4ba63adb283a393db976a8e3faa60573537c7dacdc461fad41d9a39f1c5947d199cd16ca917594cfb6be7ce9d27df982fa3b5bbb35964d6ed8dec42873045722307f2ab4b9ce9a6b470c2c170387bf29c613318afcfb661864427ac3f8f28bf3868584a105f7308afada8a3b174610304800064ee2d9b773a849ab3425ab05a3c85f2dcd1ffde28b5f36f9a2892f5c9e37654d2e86aae159437d1124e68578a35e5c79c18b9a174fee85fcbd0012623ad4c59877a1e51d3ef2f0cc5e4f7621857011a64b496b33c84515f4ba721d3ba457ecca85f89f0b5757c5e302064cbf9e212f585c263837f35e7957c5f3127bc6d655cb548a97229d48a4b22dd9e404606a345a3b019613d4feeeeb98ec043dddd7b541d807dba2ccb7f8d255f1b6c0b2050bb65a6d61c4046c5cc786e7cb0459fe1e13b86e1f759575ca4c60a3459877f3ab4d8b69d1e5d3c23bd6a2c8d7452528c197125cf9a6ac56361e8594c0f54f1c3a9c2d1b9e5990f9b3f0f267c942cc22482797e96a95cbb4c34933c5fd90000b095ceffa88e2579732ffbb7891fd74b1f209e9c2640465422bcbb6f68c40cbb5b31178ff3f6b424660d37939592dd71d1180e92c0229fe7722104f712260226bae45494c553d9b180b2cb0c0c2ca8fc594ae8a07c3820916458470e1e2854b96ca45e4c2e40a317f4d2e7645972bae5c21c1595fabd5eb0a54c7b2a28cadddacf062c5954b2b3c6ab342fe9da5b90a305d155ade5521ceaa78f22a8a6c11f36e4b976e4bed790b934eda64ad2d0f81172121c0e142f0e4bf21286269d582004c4773750704582a083c1030e972590c6d3210fc0351cc990d3ff0530106d6d552b1e5362ab050e15161f33a4519d81465e8609d90be746a5077821356a94e4a84944ca5642af5b16cb2795f3a194b7c64065aa5305ca5e1a5b33bf6541a564b3195f5f7597aa7d857ac1d66d9ac0dab34a4551ade8f059b3a3aaf9c06c5f19523eb281d102fb3b5034528389bd9d48e14623aef6379b7ae5278f9dfc9cf470a255e6d2b8825850bff63f9ceaed50661b896c728c844918247a1e5761456feae1645501440ec111463baafa1f80205960b45ad83425a324f7891c91a3f61e55d3fe1b2b98f769e00f2738003300e4ce180ec9c18f3ce864e7cf9efc40f4ea0de89b36f1dbdd487bb966de79a136f22ccdf4496f1ab56d604ee4d04e1da58da66d8d54a9b6513a8fffdcd7003659e6d940d84f97f70ca0d6ce9368093ad0d04f5d106a49630efbe6b67b3a9258b162bff3d2db44ab196204c88f9df327acb92092d0769387e4c884c40b98e4e0dcf9a68af0b04670f6bd65703e235f04403456036f7d11264ba2ade125ffe53d0269b606c892cff12de7f7a2d0f33842d015b02c82fe69f372bd1e557024b1d95f09478a2444e563b0372e426cecd9a475bef983bdb283205ce4cc52993e9d86456e85a7a5d3ab8b38d62a384234ac707574b73b3b38d929b1528631b3483656c6b3aaf1c16ae96528c1bcf98ac6d33574b290cf7fb26139c9b5a6e98cdb0893f59e76014766917c3f2ac333831ecb678b3f5036dbd59d80d374a94e05c7ceb4afbbada254a7070660d33c1b981e1b46d82b11a9eb5db226c89121c18ac86670d862b9de3d7174f1ddcd44704d8c76a7a5f1f8535bdf976ae63e7dbb85224be2041440b09171248de799ece2be7de0fecda115f7e84125dae7d746f1fe11d51c4ab469031028cce6504f8ff88f6ac052bbcebc4957e0922dcf8f7186304197f6ce6e953c3f3be401822881148fccf8dc5708c197153012d2a40c53f530022e6ffaeb625bb26b362abb2b5b78667d06a25a3b85714598b46f9daa11f3a1e1f29bb96bf3ab16db66829a64543439fad41b2ab41c9a2a121599471e72924bb6b5f1e286202b45944173174b99279e6daa6c2e5c61d9b31228afc47504e7e52083ea32344163950da8833e39066554893c010036ac81c497cc81c563e648e5a00889870c3899850c2899410e6444aa8e2444a48e2444ab89d48093b9c4809474ea4841f2742021d341c910218f29916f0f8bf809b2410c3f1edc41992ea49d3546a81e68e5cdb602f9086f849420001c1f511e02749e027911a40c59530b76e317145894ac14a65c7b2b832e5b3b2d595205d8fded7f546d49f6d799f69c18e0e2c1304c00663314a8331a60790794988076c91ab6f66f5009fe3dbddd4d0d9a81e40e40134ff650d4ab6cce4800190aefca739090232009392a920a608424b1058644ae2be95cc4d0b225fae70d860db5965e11673d9a71be83f9157b909082e0ff80fc401a9dc3836a630cdf4ebdb23ce9bd1f77d3ba0b5ae0694b9ccd5f9b068144b9c9ab83934455b93950ee54a873a4bc10e7764e71292dd40dd8eace255f1b038e6eec43137ee99aaab953bb21bc825d4d5b2cd8dc445726665903b5204b3c412cf6b29189b19b79d55cf13e7d0cd82cdf3b16a79baaa6dd5f27489f366742d9051b62d7bfb00f6f601bece950e81f336ef5789eced158eb97b28dbd647bb127d7504ad75d56834c8da571e89f2ac85eced05ce3a6b2f8c5ba82b11a6d3f5f5d73f10f1ff3f5009c7dad2f3409b0035eaa4771ec9297b4070f6747594ddd1e2be56d6f748df6cb3abe27db3833c2ab2a6aa785f5391317967aa8ad7e04761d5e6292d8fecaa78b75df685e7fdc1cda118d8b199b291567a3699d89d83ec30bdcd6c57f16c96e258a9112339337263ac52f29b912377884d399b634a712da538e9f5df00377d67fca4205ee9a44718f70516261c14195bdc35fc75138c1bc405e176563659dfe6b8ad71e3e2568574225329e944a6a4d8c9b6353b28db164f0e0447a06c5b5fb6adced4f67f76d351185aa54eb0f0dfd0371df11cdf4e85ad589360b9aa657a331dd1bc502da5e15dad5ee83bf1d0cc5d7be4881cc2d8b6ecacc7668933b635f9c39103201a40078901242b3fa6f8b6ad52a19672547bcaced06ab5e46694370b366eda14430821841042102125ef68251e714b7931c1b9b9d90a0367370d06638273d3b23a61b9da8c63a1cd375b6738e06c7c03cec636e06c1cfe2018ff0f08c0b75badc022e0cc3db381612381ad0a9b14b62c4e2438573225e7ed2e1560828cac423afde2272d80a4800ecbfa487efd4dfc739bf6b5d00bf35082ff21dcc483153c7880072dff4e577beb56b6ad0aa58d7840bdf18b06f19fba8e6b60704dd63997e99d6292d0cabad858cb949624c90a8b39d7649e52944dfa8862534d04a6b945aef0ed54023882a9686bd0c8a08df1cb999542515e5216d1658e065c000d22aca0218122982023ab50d96931f7fa58b93bc1e95304b453c7d907daa093d2f80fbb69d6e52a3c0be2ef7030cd6cffc79b7a079db4597ec6d4b40d607327e513589820a3fa2a7079edcc014aa01125077c93dc30a4d57955954e5583b6dbe10d57ab1b861fdc24bb2659cb5c9752622bca556e2c63df0d4355cccb7fb9a2219e3769f36780e850823d02c562315788e72d96fa6fae3da380ff546e9a5e8ee78df4032901608fb34a69b5fbe8484ba19926093fbe5d1ec318139cce4615fb544d6fc658a4b6230babc96ac7322c5b8b73eda386e1320ca70698edce70c232a6200cd366ec5a599e551c91e61cce5efb8db876489bb726c2300e0c77c7666c5cada88db25ac144a80147e7a665329563b397e775645d47b63bc3498df28cb68444fac2d95b64bfd1e8e56364d4b1c9a36394732d1008ce1e70f6ac5622c0fa83d5fe3e5a835171c244bc5a55fbd910d6b389617956695dadf0929b9b9b9b9b1b9b9b1b98086089121b6ac0b9c9cdba7972727c726033a7639327a76333665f31483c654ef70ccf9a2b89149d29c90e4900d075d1851d0aaa38baae36b4f6de308d7972b57a79b998bc3645d4d130e5d5a0b0b7a3324265e5dd4727ceb6d57d2ddb51a12e4d9199292d7f275fa6d4936aebccb9632038a68248a121cc1d8d689042c395ff261a823c1a8afc1d1231bf0d4713922da73755ca36fb86e4ca9d8d64caf1ac9990e4a65843e648fde85703a6a609293d441837439d4a8756ab57ce8c28e7368b72709607769bb77da046d9d6b038abd1253232a1bcdc5c479809358399505360b0dcd88442f21c5947d1c1cd216c545379640ab43686ca62db60b023ae9cac52b973c47424045bf3accef0e5ef6cb2199b218b0f2fa0966986da5f402dd30c412fa0d60c43ba1750cb82d266b933ab1f2bcf5a795665e8220305de55f12c0c631d26234cb4b947b459e79523c38f18ba749ef7b55793126d46e11083f85f856360f2674b33c500248f1386c9038397ee03290f0c59baafbfc6cd21186a30043119b1c2c83482c20b3330bd80c40bb5ce21e329b45a7d331775b9cee186e357a7ace27954c0599378de449bdb078adb078a675f974d87c92bc786e7cb86679657a6dc669344957957c583d93c4e98c905980b59606d724114a9cd8527ef8c5c08d28298b7d0058c8dd6a7852c7f37d442ed6f61664d2d0471b130a688852eff59c0c2c294ff261698fc9d69051e8c18caccdaeb3232ada04557c533ad70c4bbee19ac7b06ebee994e03b17a060bc70aabe30dc7aac216930a569e4d2ab860fdc15488e1d6dcceb3710a4118a5e0ea810750808202cd3b9b535fdffeaa8d59da8eec1a5bf18ee2d7958613d7d2e6f0762e32c654244be785b75fdeb5d23315c9792d00650240c5df795e4d151da8e8800a6fbf6eddf2427b6712d39a6b51d2b602e00a00109132e0144715fe402b8eaa7bad9c8d658ecd7231225b885821c2e41da6f4ebeb22826b604c43b00cf1fe700893bfcbcd13c8bcf38abc2969df13bc0c994e383aa1d6e5ef04d4a94c8fe9d4a5a3a6d31599aa6fad63d1ff20379dc0ce36ca099b4c5d6c755e936909539037a5d7d97a269334090993034d42a4b84988159310d74d422a0d42c61484cb25085ad114c4ca4d41a69882a46ec521dcb909eb3b632613bebc8a0e295bbb51d141ce9a09564c907f173399605d257cf92f9a4a107320c5d354028f0f4b82a01575640acf1e5ab52e548eaca3d099716c7e5da9e5e1ebaf9a4600f34b2ccf54268e2fd3082ed30827a07013009a00009108799844e0e2bfcd4d2250c024c21393083784a08629040b8420beb362d898d5cddbb44aa7aaabf154a610949880e00048122620e2bb1b9ac2b19982e2494b436a74a90988f4a4cd9e9c5913101308606e02410b08a209041be68f34fd0863869b7e68f9bb9a5a038213257377e63a82f6c8f4a366faf1e4ff8ee9c7ef49d30736307d70e5ef26684d1fecf0dfc7f48189264ccb44a3e5eff0d8437fd3443345665cf398686c0225d090704737650acb8f0432fe130947c060247cb44a3b7bdb8713093e2712a4c575bcd2021c40e1a711f4f8df9d4638815cad56abd30857def569842127a2cd52b4b9c7be6c78be6c1e7700d002d60900405cae2cc00126c8c82a3a4964e2554d7aa452a96895e66e8f3d501fe88dcd5c6fb386bbdbedd68d8196dc60c312b9aa41aeaa782ab9c2b9512231a547df9498d22a55dd3eb2e0ac2d4a70f6a55e9097c159d3c1b161c9cd4d921cb9a21923e9711521c1507220ade5eebc99c66e154f9c432d8f0a6de251562b735f59b5b9b6fd0ced1401c9ae6db6ca54e3d1d616b621c5b9b6e1fe26cfd0e4a1d55ce7804f1f8cf961c8b38de8747503e15eb76ef1e026ae74a8738ea7ab96ceacccd8f674980ec953298e223f95c8e8249777353cbfc95352e293c74a8bb95c8afd0f65ae1d9e4a466e67957587aaa5b9c1f66931f7a2d14bd479b931ac26eb7ce40d43d869860b15a7190cfc05dc41af1f6973eecfb658b4c9739ad911c069868699174e33289c668ad0664ccaafab50914a508024c74fcac14f8a038ed3b9fccf980a61dae4914d6833d69f6dc9d1076dc6a4cd2a4c9bb18c29d8c71107e9cc35b9eac3f53e68fef311033eba9c0ff0367cacb007197b04f1ef91b307cdf5a85d8f13fee3f4e08bbf0741fc373d6062934799d5ca260f2d7f1e3e7904f96f838716fff1c0d9e091fa6a7553864c992d376570ab954d191bce83325cce83fc9f07363b20b30330289b1d60f90e72feeb408c0eb25c072fac832177dc815136770c71478e1d54d8917f3b6c5e871a75f8d401e4a7830b1de0e958818c1a64b490f94e26867f8e39e6f87218ca668e718ed73f07905f0e309723081c399e5c8ee7e08bff09c881d0cbfc717089037c1cf26f430436f860030e366a00c7113741ab151c2b4827b206f5460dfe8696ff6fb8febf71821b61b8a0dcc0b9a1c48d22ab95cd182dffc7dc31afff37e39b316a8cbcd9da46196f03b7e1fdbf69830838b14cb191e547ad56366c786cf8fc6783e6bf1103e6026b40600d1fd6c06b7c6b087dd2640a058253b6460b6a94417151e3891a7f1a5cfe342290462dd7b65cdb506904f97f830608d0d0120134ae87460b8d1d3462f8e50a75861affcf50e2677c674894183450622c204608536d106651626ec4c42086e629d46a457ae327b9f193c6b481032e7060822a70f0040e84f845904e648d5cd5066f166129b942ad5636b279335ead669e9f38362ec5710330c7b7fb58330bab96d671b5fa58b54ca55ca2d6677b7eecac1205b9ae386f46b9d2214c670e3bb3c2ce2c1ffbfa1a43f958d5aa7059458302cca0063320e3f5f58831cbe7a33c451fe5717d9467063d0326b28fc6c224f1519edbacbd707308a4c9293b0652dbcc95d5e5a6dd7cfb56eb4fda51862b1dca33ca53e950479ba9ae95b6708a9846632c71c48d274ff7d118c6f6caa60d436b6714a8f36c25026201c9d977266b0be1e65097eb31b7acf4084d269b299c0367188e46b2ab4175f8a3311b2f66ab95b9580a7bb8fe5a9439b0f19d2296cdbe163c9a46b29358ba7a321e7d70dbe6d0f702aa505c1fe5f9c9b6956d2b8b506e56c8dad74779689447b502a11530f90a30ad2ad062ea526feaf2ddd4e500377529fa0f4404238ab8c9082b371981bbc9881e6e32c2769311df4d461ce026235c371921f4ffc70fe44716432208a14c93220f40c3043ccc18e305680c0c74908132f54008270200706284c889f9ff18b238b9f2ff24115cf1938efe032161f11fdf4e86699844866938c6165aa55986f602759eb23ade1927ad21a11c08108403d08f4f0fcf4e1f7df431e4849349481f414c28a18f99590a703f0ac078876fd72818e197ab2f6cbc06d5c6172daff64bfd32a5937952db9727353c7e8141ae8a868632ae47a2ca022a8ad2b1c93343c5b0428c25fe37ebab7d64afab7d3e17d187c3798dba8e552ac3b1cb75cedb47b65a6b64edebeb6c5bb44aad8f6dd9ea2cb2d55954a1003163e500a62fb6f8c190e2af968ab36b7205068a0223a892d8ace5691fa8116dba70bff0ed6ec0d5aabcd8e2c510bf6cd1cab0cca091ac8f60b6d9b7d50a576b9b2d457eac5c6e2353175f1747ba98f21b865ddcd005935faeaebdb7ab5081dd3084897866ad0cc6e2020b2eb27031045051944a27e832faea4eced5552bc79d9903c13b5a03c80e8f79de298a532241d23cb2c3366b6b72da8c69961d5187d6e8b3160710dcf9fae8336d91c671ae6d503a9cca8d673bb2f3745e391fcbf3e4cc4eb9e3f52893cd58639bf28ae64dcee894d75ed1e6fe28f87d34046bb4d15e098273d6e36d4776366bca4204594c918510590051235152ae8a6415b9a2924455461636ff5fc8811483ef2771215df167109c3d20387b48b0632281fc5ba8c3e9f3630465c7258d76a4cfcf6be7a7e8257f78a490104b8a34fa19da69491c5a44429288e8253b0c82537654464111d7606c7e5030ebc32c2090e86b28b96d32fa9a79fa147d2cd308625446f0caacaf3bcf93b5fb1a678ab3318b8364d7329a6593870e2959229d481e9ac38d44226d4a96dc64df6438623c439ab194b2f1eb8b6dd861c98dcc538ae1c8834dc91269b311235d932a709cd12ab5f526ceb00367c6597a32d8d8dc8436dd8d273b6fd6d7935738715ce95017cb3d3b8c5d5ffde99b9ba1a5347736d9048dc2b1d5616cc559e3514919b1c926888dbc8efaba8efaba300ec7568d675fb78f6c8f87baedc2dd3e5023dc1ceaf091a6e2d877369951d93769b1acc966ee26596c9bec9b4a0d75b936f1682d7331b0afa442072a5e125331c29b4c01e6ff1454bcd2e814b8ff53184de1e3013d3225d1e0012f3e2c9903a71168adab5ada03ceaeb695ad2dbacd225c0ef16af559597f764831e66f29b69042f502c1d983afed866487f465935990a7ab99d9934995bcf13c9927716ca4d1193da2378334366316db6416fce1d9e1a1cddb473eddf8d964f4c62c96f6cb81194f30cf6c41dc219db8feea6c9bb519b78c629acdb2699e3715a6551b9b9b1dd9d5349e9e276d1e6d0e45a3339aea9851ce623ac5d082f26683c4316524bb1a7c6356e2e84cb4336bab14afe57937aa96275339e5c1aaf564a598d600154591531ea9f6abf44ed18a60533bbb2dca19ad994d94ccbd64979b364beb5c3d234f358548cacbb36929f2265354568964e705bd7068fd08c15ead9f211c7e8c602d22d6ab074ad1cba845d4032bfaf16941f1425aaba4c86e36b3aafee6cd72b694a2964b76f866ab4d55a995a9264ee5eec4b78fbe29ebaca580645783c196d74641545f396f1ff5cdd6640acb684d9c9766b398bbb24a0db033345a2aa3e00c65b5477006c6c24993d7ce5e442df932823294cbf48eb2369230c80e09926b23c3754fcb445ac37d6080498944a2c0ff192b763a4623d0f8f611ad639e362cd901475e40a893b6d25824304837a0d293b699bdbec9263459694d66c51f12195d2ef76c623cafec66c392b1abb56149f7750c8f3c7c73477678d656b44aeb9d524a422421742f6310e3dbad561debd88c59c05e5569928e4d1e248a4e03e50832ff6b52b9b6a14c4768f15f665b736ddb62025f7e5215219842488a2302ae99a7cf6af5f2569e9773aadb2e9e2ec2ab954745d61a94c4542696b7aeb08cc71026479b1b6dced379e5a4fa8e5936de7ab39fc434867ba98ac409b6122512d3db39374f6764c488c4734a1c52d9795e6e3c7b26bfee589e478ecc2cebd96d3caaecaab3ad12676faf6a4749abd4f35eb2c332ec5a06c39e797eb24cc71e3c5ca9e7f5f56a640ae5c999eda3d4eddaadbb591053710ee1ce13cb1c288614e329e22379caa8271b8ff98814d9d9489b5344b2cb79369992fe488f4ae3aee27954640dca2e17935deadad4e7c970f6cd581c65d5f6ed504633b69536e967ad3853cda40fce40ac797f68d5de9b8ca8261b87ac7d7d5d6934375d3d5f8f40b6d939f0ce9f4b43040f3f01a510840d3f659c82f84f7702c20112d3d467bbf666935930890a88151a20a60155346003a7060891ca382879d6fa3a9cad0e67056d2ccc1975ab93f88808d4aa23386d9d291f967c01b53860c509f9759eb14ed0e305c802c87c015680382d20c8cc185a42a0009b5f0502cccbabfcf483eb3f1f0948e30d946ba0ceb9d8ddf9fafbba6e76cf5461ae4776337b5bccb6957382e48fc97c38fa92768518b4d6859be1572d4fa56198c7f14d889b61187e3defcf2957f31a60ac13ce02d98a18a4b942790f6e74fcc3b9b669c135dc7afe9bd3ed74846fc7c2210b1ce57c860583afd21c88388d3eaa31f3718c4393f3d720387b3adb166681a014109c154ad366c8eaebaa50be1b5c38980b167a116bccec5c8f4453e62b898145a88718f0ed41b435046d3c509ada4f43fb69663f4dd3503906b8fc4fc20afd453d1506c71d187b499148e44bd2206553b26cc6d6d664df8cf598eabadcbce5c4d1e65216f3c8ee2eb91925a661387be6751e95b9c3194876b2cbddc993c35910a4d9284a6e82ed03c666bed628db166e0ed9db0798a9c9312aa2766fddc24098d651de16716ac8b5ada606859a591aa40df5769ee0ccc9f0cd0a59dc1ca2557b6dabb26e7f976846944722a35b0359fb6a61dbfada04ab191b714e043f1b8619e2797c3138408b1901c85e9f241e23373fc5640a312da68b89233fc512e01345ec49f7d1d813a798bd499c6696f7d169ea8067849439c220387bae840781f3849d59b98d768c8a721bf518f584b35f5fb5b7c9e3c3ca34a4425d976b5bf7e51ccf6d9711237536b6f99b9d8c762e49c3b1e2b031ad3501bbd6b64967aece06a7d10d3bb3721b1519e1e6d0d7369915aa50be3eb2d7b69a56ed9532c3801bba1031c00a277421bd30a5a804526a202505ff6bfb60fb029da430406657632895f575b6ad1dc01125cc4f513ef0ff1425caff9343f5517b8d478a9b8236dbcaca1f8824d796f545e2c3da911d96332b8de4c6466a688ce26a451cda6a655d292ae3aeab49c9d588bb6848092757eaa4202b1d7e9a0f37952b303bb49a7cde8c03c1d93342b10288f77c932797c5f0e7350c05b1dd19f69d61828a93840805bd70ca018c08760d761b268bd9aec53c489b73b82a950a9cc16a936200cfc58900404a2c9c581cf8e1ef1cee4e0eae2024da96a4cf021ce21069aee119245291be6a8b44f61b8d667a7010b2df8849358cf9f3ac2601c1ff02fc0414c4e967023f43c82b9260828cac020395cff4e987e8e443830f7c887c06a0cab31e564fd7b3c2ff138f12279e089c47e87265effdf969a64703a3c14283811d0ddc548b7980f5771b3706678f1704c71dee03c51dbb3355fc77fdf42404bfcd5abef58eb15c69e8e40d9afbfa7b9c9a6cf95fe53f101a1dfeff343e54ea8e0fa7d5082c985cd11cc000ffe9069aff0d830d8102f62150147d08144f3e040ad5874091c2874011c2873c91c7873c31c7873c91c6873cf1820f79028c0f79628a0f7942cb873c51810f79c2011ff28402fe8370326184144068ddba7e90811faa0ea994131d27b206f751549eb5d0aae812e5590b492965d5010112f75158d3be86fdb821841f403ec003054e726890b5c1920d686a40a344ac8892116c6d2d4adc489574e2a4d635edeb224e36a4c41af241c0c009478de3dbe53459a16e6042230092a559a2448dfff7a71b2fa265420365e0da95b44a69b4197bec53b4e24cd07ff0279b2dbf6188a38ad9645d270b435a7b2f6f86f1d8411c32fb852e37665428a1bb434673cf334e1d11c7b9b6ddc81c945fc9cc13627e1790f929eeb7418b3f851d7e1292dc06128ea606d2016870fed708912795cf6f3a9bee4685a3373f8dcd4f93e4a7e97e1ad54f93fa6968f84f4383e475fc76a48630e11f98f03ffc89063d40b065204c71a22101343527e1fc77c04f48a47812718634289a2334339cb44314d29218664c98912f492919b5414ac109257442a13e53e674240a954a95e4d6f4e8f611d18c28ecccc24dedeb63cdfb8367440ddaa20af6e08be7fdc133a28f655ff86b0b1465de9fca9a11cd8866445f0fdde019d1edcfe8f5099c64f061c0b1fc595c8c43b1c32906f03f1e9ff931c329062028793bdb23199be17f6c660b2e66ba98e9828b8e36c6e4a4b54cafa581537a3f423c3b413d3b3f452d287bccf4710309491f1e0ea4e99d640b3a0924d9fecb7e32228f6fd7e4bf1590063bbd9080d79908cc306066088cad586122c986a4e4249b936c42567beca1b19c9dbc758a463f4909e5e40216ff379e5c005da8fd0d7e2c11376dbafe5329210414b880a3820fc81b0d64c08686150029a34200c2c8020051061c133320f1ff2c2c2183f8d38f283ffd70f2d38f1a7efa21c34f3f54f8e9c70828fc229851e52633826e32c3869bcc30729319a69b68a0c77fd309ed03c535f7c16aeefb495cd0e0b033adb9af8482ff34a52f176d3eb12083e329645f27168448604e2c00f1e2a71572eab460ac24c65f0ae384dc91ec2f81f197be18a185eff0930a2810022d1b64f137f8d559933fa59000d7298527a7146c4a5e7839a52076f197b8f84b5efed20948574a5b944c70d2cf0985389e2fad6af1794e087142c106df0eaca941655ce72ee33a5583427538f16ad595d2eacf67ae0831e39d8a303915a1f9acafedda1b482bcd5afca51264f19748d0e52f8d40047f090b2e7fe90a2bfe52155bfe520840f0973e40c55f9ac2037fa90352fca528a0f84b4f70e02f39d1c45fda8096bfc48406fed2124afca50c60e02f5d20cb5f4ac2027f098923fe921115f84b14c0f2978a98c05f226288bf248404fe5204aefc25083ce02f392088bf044403fe1203acfca50528e02ffd9080bf84001ffe520ef7976e477f69cc7f09dfbfd483f8976cfd4b21f8976c3cfc255afb4bb4d95feaef2fc9627f697a7f09b6c35faaa2c35fa27280bf6480297f494a94bf04e5f5978c8afe52015c7f89a8f5978684fe520e0428b182fe120e407fe9c7e72ff5f0fca59d277f69003a7fc949ce5f6ab2fa4b3730f94b0258f29794d8f0976ac0f94b37367f2949f79754a9bf440392bf5483fa4b4766f84b32c4f0976030f2975e907fc985120b2bfc251552f84b2814f94b0120f297869cf0974ea6bf2424c85f32a184bf44c2087f090022944200f29740f8f1973ea0f94b25d25f9a2991fae0e327eda1c74fea411e3f098f323f89073bf8493ab8e327d951c74fa2834c09349460c229ab34a8d4f316fb2a788866040080008000d310603030281a0b86c311915c382cce011480015ca662a2604a960a93204621040d410608180000000100811031dc8cb207b9e67caf7dfd131f251f071a37d4b5b4b159ab6088e53238ada2392b2069fc0810a0e3f1a6d7cc9d3667bcc54034fcca1d7bd321116a8191ab4f7b9a6d08976056b23f4d0acc4f0f00663eb14b52f61215a76a7861adbbdfefe1867a9281ed9c34b70b23c94ea93d0cbeb781ae3f284b3419137cc7364fc52299d0fe8a6230a96ea57236a270d23268aca0fdb4f7b200599feddf15085a16a306738a4974499465a5523b429da9dbf39b6a6e36d21c79e2edd6e5666e96d6780519d561dd7de0fc25b5f819a5ccf04c4cb6cadd47ea020a0237323c0a7664cd109aeb5c99d1db48dc37782dedef81b93703c9c73d52461c9f6972f4f5030af27c5a6c13accfc136bb70de15adb315810109de1527dd5d008e7735f2759a82f6086a6c2e53184852b61c74a98ff146258fe4a645b84c96f61f56a36da2aea073e83972892d5988d39161836abc0333ef9a3047d7cd69e3e0ef6c692a2d746ac9df7f34b5e8aa31eb9cdb9f6c08ca930866125630e3fed917edee7212c0b0d20edd15362887fb74821cbc840ae3d2a1bd2410230a08362d7377ccab5b6558e2a2cda33306411e79ba3e3a09f43e4dd2435a4428ea3917305bd00d04520a9932af11d12768136295a657f0fb313008e73e2d1c8e89fbc461c4effe15486bb62394c18539385547401add1c6644a6fd0cb0d2272491916ff11eb61f9bf8ee1c8d77559c6da812f328f0a1a8daa47b8973e5dc36e37e0ded029ded51594828ea14593b866f54e8bc600bd9821004dac7d6198143cd2e67d4f5726fb083c49610a164fabe92c0361d90dad2bdcc75c7e1cecb8794cdb7e75ddda03d5b0a6d2a06db389f4d6993677c3609cc766007cc615fe3cb72e7993c87fdd8ccf08003a11c0f558d51dfc32779b082e562766da87fc341647b450ba1cbce3ec201560019e033b5c56591bd8d464fc7492f5d7b0f385d5bc37df20d0394b9321a771d01f8e2ba5aa798205e3a0c8d004d9580048b497e24e21ef00909994cbb4f5eaf88f29af30f4f03bf0f6cf18859f8eea2dd427fe8621d5b9100173be5d4d08f5fa32613c2111a73e5a2a5a3c3b4852f0faecbf332991ec0d19206ca6940968802013f97b1209d5df894e3753e7b83c83cc9bdc39bf151589244137074384ad71c8e8ea85ed96f45492ff5c2941851ff47ee31137aa54198c8787a0aabd89cd941cb0efd161cbc9ccd1c12fb2ec8f800acae3d5d087b87153a63c7064300fdffaa967dfc7f247de94b4a69a3b76e7df52c3df40e6e18ea4263cc9707341c84570fe508bd19a15ce70f546d3330c120845f007765cc5ae6cbdc00046ad6a4c1c4a5b56771322333ff7bc8715f3b7f4221f3f4c76d1fb8e8615bdc032d7cf63572961a3159ef3e5773990ad374af8276902d4dcc9f1f6657b2189ac522c925176c86f1eaf903f2c16aa74edf5310224936d89d274de1c9c62e22ee47af804722aae3b4777668348c9517a03219dada489466e05a865fea0b0f35fbb0ec0aee1ca1240454cb9bb5c83c5051fa76e896be03cf02ae728decfdac3adac6b3242ba041bf9cd5aa53c471025df9046c923fd2fc8de1ccc18d8ac5fe3c93be328ebe4efe965620aec12a1ee6d122fe799b7e911e3a6703c76dfbe93244e9d30002514e6caf9d819abf6b6db3dd230daf98a5475450490aad6c68e15b3b57ff3e13412fe10154f0fa7cbdc3bf30bccfcf4d839dc2c6e4f8e7b79d1b5212a11ba5aa190bac3ab5ef264602f429848062be4fb78787c6aa1e308f478d83976f4757451ad79936f70dc0e4e1ad0bc12deb81e48c88bf85b93cf75f3df563dec7f76a634a2e9756ea4aba5176aa5d89057581c7d2077ed9d4275369c132ad593f6a633d1d55af553ad4f2fbb3098f6cdd37356afd2e93053eb6e8592d72eb8c1d48c6fc438681829eb2533bf7c3f3649c406f0feed64a5ed70a7808b7fe1be883b76f774de72e9c79b6ade08a4763539b1275e88146124909dec6270dc736d2c8740a5b1891f9b893290b1e70964b3901cfb87fc1a69eee90af87563318258460fc40bf9e9a514d590c57e1e4d49407ccee3ca3ff72a93fa611feb4633c7931e39b3abb27be1e28de8cf72b3a77e3e59f5cca0bf22bb1b19eb6ede9f9f7d579783d8464cd278a142f3ed175e3efeaec42e8fe75a75745d4dc3b8d120c5e85a60a181dd43e6d874f228f60d113d570766e3d75a64c798b4c0a49730c178befaa7247688fe8c691d5370c9a5a4ea36442e80069ad85e3f5049a84ffe7814689509bb0ffa79f12a8ab2a25d59f78fc03cd234ff7a31d070754a7ecff2a9f1ad333219ab3092ed7d1f5671cdc728b53a29a7f8bd0e816bf992e0e8ed4078d5a2cbeee9fc268d7ab295c31de22abdc68d18f75cb70101c4e8cccfa269cd01f3c066968725d1ca1aa594c1b78b2a0e2b337660aed183b58986abea05fba9137f70c5755a35f43f233f118b8d0c4a4300900c7b342194fec42cd1c35fc61a68b14c4cc4cef18653549443b302e05a17fdd5be7c43aba5cdc8070f1d3fde70f0694ae760040f0cb7129f557bf5683e90bf2a3313f2d888919e0c13d3431084f9fe863b0160c829e74b712eee61ee048cf54309c45670738b0e07daee47358e137f0725b8ff714c632e03d4da7981214737556334cc80c22de5025859368e36c4444cf8090200377846e8bbcc14a8f68a90c766438dcec3265d62777e9b87fd0d941bd64b27bd9baa73a9b329897ea95ef8d5dbf650edf6fbf01c27ddfec49839536ca96705b85c55e64325ef4d637255c050badafd2b835f47899d577080a119ae5fe86f8f4b767d7caedede41c6288f733935efc150104fdb9107475575e7120e3e99d40038fb0986789cd0e39703826660e6d806fa7e66b2f03b76f9dabce89f02bac01657f4de732de46434a63d10c60b763d391c32a27f6df9ffb4b6220166ebde98656054d8db75f90298a5728f589fa8abdbfef075b3bb2659de63b785260d578279f9d21f8ce31f1bbcd256dade08bc51ff2d4e61300f04630d34a4431f36d8e003f1f77d331d836503d7c70aefb2bb445311246da102692d8405c32db5ef165d3051fea421387383a6327f87b1b059bde93ed3ba19ab90afe6d7f645817570428750383db0b7bc134cf19c7851de7a0da80224cd9e7e9d180c3d16e6c2675b2a032dc274be15234130eb134048f21744cd39ed4cac68d7542656fa3453f7edcbcf58dcc63eca4a25593f1f4b89f783f54f1a17d71f58f994b79c8768e1703c7264a2e1f351643ef2e65206fbea342590a9410dd497894396734ed6062e706f78328328f57a8710e68dfc590112a2c1454234c3490a032a28b4e156642265327af9d8fba26e9a6562705e75e88041260844837cd6630df9bef4fb8d149c1caf436f21b181dc0aaaf7a44004fc385129595e7642d74dc28e06ae675430bc0015f00f7142c06de1c34775860c620fc709a8b3beb258fac7a39c4c6260d095ca0c1ceae808b3cd0a1ecc185824287180ea798d8fdd7490930e6383282e084829d4a563c46f993e273aab42ab19ce86ed1b2803fb690c39c1e0ff15f5a738665748b1b720ef453fc6f6027296edf4e3c25c38cfb73c912430bd24f9e1db883fb5d1718e1776527969322a6940b5302553be7ad0d38b65439c62a60c1fce0d624a9bde9201abbe2383921a14badd2a03e6cda9a7b3613ffe1f98c0af80e01c3c2d33700316ec692998aa0257ba0a28e3db2ebee48a9c6b2e8d34bf4fcdf8517e6a4376b5d7991fda88b4e211563b4637cac372627b332a0bca95a509a02b53ff2da5e23c3f9d3819bd8fc901c1f01089cbf353c7bc81478d1ed23820c50873cfd182091c3a90855fdce96f95a037b372cfcee7cb3f3d1b354e8672e1edcb3732e4d2b6781f0fc3b017dbac9058d8f7ae79180b4fa65f7a89d3db38b18c02d79f3039479ee216175ab670440a7a01aa61542a32db3130e1bf5b47212a54070875d79897e1c4c16fbebee3d9c9efaf095a8f74356ff5fca156de3b9cc021c03fe83779cbc2a62035f7cfa821d13ae85783f2b4ce01d258bf391a270b7fdbcebb1bb34ba129ceeafc8f8dbcd887bc8a7f60b213882fdcae42eb2a3721df0c118e0bf7b19d6b933b54afa690dca1a0b397d92921691dc4f8b7ce47835db46843b7c743e6ffcdc50b6656ed36446333343e18bb9a14e3bcfb14ff775a4d29c6f5f3d0b8c1b41e02e3daf83c5926eba57ebbdb3d1c34b1202638ea75c913fde95c21f5eaa35ba82a4a2e19d86fddd48a81a818ca297a583f916569c81fac6c94c9ac6b8defd222dc17ab32f65b00008535534436d6f70e1d8812f646d8e29325f84fb272cbc320372311ae2ee3b1e3d9efd6ff5de51a72ec19f3985fc7c572911f7b4377bc32d81c0da10a1fa9d610a64840da53ce1552138c3b47f02960e699601098bae6efd8806bb10d249a8b9c9aaf1b163622629fb46de6395ca71d669cab3061e5511d94a17592571dd398cc9b4a8a0d16648b9029380af2d76997e01ec476cc526444d462bc2807c4154793450c1a5341e7d4d2a00259549beb4fb8d1059e1e30097d684c72176a9d2b0d30057d87e382392396abae4a434136a2a7736ac29be4b23d3ebc063f5703a7f058f4566e3e43329024dfea141f6f940b7f9929fafce472a89adb84390df134c984a707f5291f382c3f6729845d1af624330b5f27fba2ddffb46f04968f15e1043c5ac6577af6f405f36da4dd2e980632ea35f4a6316cc39fe44a9c2432fa0fa3c014f2d270de664a6b5b8b539dafce632c092bd97a5aa581a13b3c216e704ac057bdf6d0463de8cd2262461019bc8dfaf31fd079f657905e3404ed6746fbda32d37cc5369f7e80ff109a97a6eed9d424e9ba6f94b7f30997ca52d47aeddfe9f338800d69c342b1b4c102e99db4355017bb1bd05cd2b030e79469f5aab1cee53c6d10fe2ca336a51d7551a2d63dff7e4af84b68acaecd6aad85a26ebc9ea37a98574b7347c705e86325f68705a211c452655f3ad1601afb7bf27a934aa69c1e2cac70987a746f60924c4673994d9aa6126e6a9fa63bee0740e5b97bf9003890a92ce13181e8f72a999be6aa68e12f5e9640c590015a404e246356f946624f75f09501e4a8cab7fd43f7d79d4f8d667eaa3743918bb3a3d01e77867505e65d78945398b44c4d3c78b1e0837ab1f0d5656cdebdd8e13ecb02d740ac3cc6ca87ca8c200f44530e0469b8cb9fe7c20a1525b8c6a03ead5d581e1f2841ead2b1568962df0007048d605d1ea08d1ec16bfe579a99d5745b57d335e8e1b03f944be577a0443f882f800ac4df3f0d77c88b473a012fe908d0409db527d4b2322932181f11e7742d2f5cac4fed3fbd304de9480b92ed8ae96230d85b009460df7003c1bec09ac0081f500aba88a483ce6055d8143a0e02d8573a57af923617916e4af3e711e2c46f1fd177ef0592d3e0d7a6888d0337b4d457a626b45ecbf058fa07c9ac09a36141835920709b6a99879ac726842cc213c12784a7477718fe92fbbe2811b47b9c926b19e2076210fa007d66ed13a60e1fff2d4ebbe66a2f32e6b69b4fb09907e5ce0cce4ff24a48235fbb3f67011e7af78762e0df673f99308b2aab27dfafa7ce1742b67bbd46490e130992e06f52948d82e2c28c413bf347e7dbead023acafe6e2c8c059334c88afbf8b853851a3c4ecc8da4ca75249c25d676cbadca178403c37d02b66d94c69a53c23e9b559193414895ab280c344f4e25515993e97c0f3f85bd5fbfc323e5982234b437c91dd358c458c4f3a065043cfa078e0a59b0da688f58e033ecbd3c4674d7c4d5eacf1022d8ee428950c21bc1aa01831f0ea77e12649214ba82e494f6bbccf471a4aae53e03cb991825b1eebe41ec30d28f3b168887f73fb4728d7464c5486eefb14a2910df45893d4887226a1742d41f2208fa1f42d81d22d7f907ee80a974303b49ac71b18e7a4fe3daa5458ce69e8961fe147238160bbae918d28af219fce99a287ffb4013d0baeec4c6295876e8988d1f808e3a7d8a288144200a53e4a85bf38fc6dd0dba2b52c13d53e51e392dd294c9d59856c8fd8d952f4ff763d0d71b083b6f0e4138148ea29b69a7ccd3e7e4be0b5d117f96637a33ddc444b2025cc4e909f7e136884f19f00b681bcb7e542f8b2050fed5eea2d4d3732f6cfe363c5a40c548f72263d03a0493a004caa57f708646f032509c6480407fdbc0a603011817902f7a8aee3a4b1c375ecef2743bbf2e8449068209cc8f1ab5f7ecb2bddd81ba039e4e3c70069a2c1206aa2f02740fa350c917cd83c4c388c32fb1126dfbed7f1c75c72068eec139972af1acaedf3efd2e644b6b23cb6a0aaaa7e7b2b20c2a6f62a5a65951a098f13ad42cecd88e834b6700e24e6c703b4e12cca0a8abe58280fb02868dc2d7e9b805cab1eb9a289177b6d71dbb6543118c7d629005253e0e94b11cc02b269559b18cb2ff7d9ef8182347d4e2283b5281e2534228a15b29b0ab2d24e38701470a8540bdc34f4c35a2c414b5c93b4105129aa6da4e7f7c24a683219dd08da17430d2e604a8bb5ee0e5d965db330d3bbb657dea34c10fdefe86c7387fd97e42eb0450c07e54bb616e1f6f96a4db17a60b5d4bc5665e41f3868e869948f4368cd1d9ea1c8d17ef336644d4219a6e363f3e276ff485a6682c1c8dbe96325bbb943107f6f01fd00bb5e57d95fb7cba6627ff0498cda1eccf301948e3dc9db786028109c916bcac675788e529248abbb98d6b244fa048a380287a498563102ef1a858866047f281186328120650f730ddfd89cbcd63d7e4f6eda72b05cce0abead6b7af57a327d49a156bd3ff31ab2ccd346b43d6102df9d2156dc1601be94caf0ad6f34f850a33f0bfb60759c8ba25cb939bbdfeb8537d0456fd3eaced1e0d4df2b065f2dfe23af89fd2de4b1abdab4368cf23e4541a47f5b2d1a5239949e8d201fed940f84e15bf16d05bead1f6586aa3fd86a4fe0cf6de60236fc7660b76aee58b536e3959bb305f2ec0407ae01ec7cf0ed9f77ea49186ea6d3fff03d9a6fe14a3455dc888b640ea65e96fdb62180ff110c572835875c99fd5e0a10a6a384736850986fa1dddf5537ede38d6fc739a9a4979b301b645993d4c0ecf84e3b105ca5bd6943d9cecdc3af42550e9de0849f16ba4f73d8e5d9cf12bf99d04b95ec89f91724cce7efd83856e3d8c7a607f50f7f984dd3f5a3b19a463566dcfd1629037062333039cdfcb4a7e4a662e75747925c715196face213f47d33c2a6938132c97849c313bb5e8138ddc4f673606f95b50f40e08662d76ac8ccefaef56259b501f74a33382777f6cddb24ee96437ffe0632e000e85e03dd6e9b730427fb78223c6a6211c1c3a47994272aaf9c1d7509b5115d32d06fd2f30d6409d7ab07cc525531b666cb76e06e6e7173321b7c3a65f3de6a1f4cb22747f12630e2ba4675de69335261c7e4f799f409ee9b920eaf2e369a65a67494567bc26bbc66770ad4d26f7636774f0ae2c540620ab1612767e62265d261ed594d69c0b033aef00a2a9cfe1bdf2115dbf80fca1a478ddb279f1bebd152ff6047d403034e825720ccc3254bce6b4436ddcd74b31bf1c73e6deea0da7a7aeb07e97792196018cebe8ea004971999aa1d766788d24d9e63ce62fb0fff6cbe52c7bcf0a92c557bf4e2f5a4475c3cbceebab3c650e91090c456824cfec2ee0edef935f9d823989ef462c52510514ce19839f2f58e7607e73e717eeba758f3cccf0c6400c3bede65fe9fd213a17836828677ec53199ededd8445107dc1b919608da30f88ed7fd0d98ab08f8718be30803fef8aeddd8c1962049d2c8814508c2aadb48d72c4e6c4bca3de784e9239c95919d1833e8a1b785cf9268fb7a9631041b8fb258ccf5a7a6dae6379810ae266283fb74184cfeb6e6ec44288fa2d00327aa45883d81e2b23cbd0815b2ab53f85dd88dd7b937d14e80fc7bb4ec2378d0783830adffbbf7972573c75f10505fe49a6339978b9ff6c67e1dae7e72b118a6b8a8abd6a6f06f288037c835fc4301561548fd6f67ce41eb1d5e6d02265c9c8334920300369f2b847d75ea261191365bd711783c0b637d7ec31a9385b9e208ab90b0ed963bbda70f61a1e5e3db5b3fdc575dde27abf376f5f4eaaa7f70d50f2d4b30eaeb91146d27fd23c18ab934f2350aeb7c331131979fdf7918178037e6065b05de8be0b754a547819f1dc53ffd347475080dd09fb7cda754a87b1c0cc4663dca4a736a2c8d252e9bed8e855add17abbaf128801a4bdaf0e880ca4e73eaab39f8ec0e5b7dcfdb64a82c81c36c81e5b36a7750e885793a3b8dc0d5d528e358438827dd65d51133e744d617daca30228057ff7e970e2018c5b2a64825f6b68796e9ca0e750774c351a1c6d823ae7699bc7be19d977c916e6e4f2af81511fd3453a63d20c2ad3c51fd6313e3ad8fb03aa977345fd4cba79d302f935bb812a83a3fc83d3028760aa75c35fcff765a3b34b9fd779e62c72e338a528bedee867822a16d6f86d4491e72f1e362d9b4088fd3b90bc5643330df50fc51aa2e939d8d46ccc92fb1da4ea83dc0a55fc9c90db95e2bde8379641eeb732fd2778e38906ceebcadb8c73751d14b8cbe8021f212622fb0a7ef0c969cf5522cdce7825eb046931e4cc524c9eda21a7f2aa55873064dc5906efcc11ad2393310125d04d1289d990511a202e23355f88c34e3c06e69103c9502ce08a9a6e0779c448d9357ba1d8cf0035743cdeba89167585c678bbb0a5fb6d2c2d5575f60bf03a2291d29374427dcf44257f870e3b816f61484156037005669b05bdf0a9c99facb4b850bafc79ce30aedfeeefb3db1ed11efeef11f2e6bc905ba8694812b57e29eb80b714b25f945b913fe8b791e0e7ea45fecbefe9a42dc75a86592f955bcff87b383953c03695d9bda845123e679721c44d5425afc8bfa09e43fd9cd4b3b94c8161e283c4d44d15d96eee410df3a3ae2d86240d8e4c6ff4b06ff38932ab729e5b428a7e372b18216dd6f8793cb5be5adf2bdff3ddaf23439d5445ee03941e20e409fc080c32185366086f0512ee232efd1922e463218b45c9e07621dcded874e62ae3b288e2d897230f9318a8f8c1119fc913e0face88776204e63f6bb439a902ea5f19e94e8640fcc78c32274b00fd8b23b8931478ffa9d1cd090a7cff72e4771202e53f30e2397902ecdf19f14e8cc0fc678d36275540fd2b23ddc91088ff9851e66409a07f7104779202ef3f35ba394181ef5f8efc4e42a0fc07463c274f80fd3b1d90db34c5e408707ec6687d6203bb5f35929f1401cd6f18a54f5820f75b46f0932800f34ba3ef130ddcfdd0e8fd24057c7e61547d0201bedf33a29f1c01cecf18ad4f6c60f7ab7082e057e990fca2f9cc68eec40616be7aa43829033adf30ca9ab040eeb78ce0275100e69746df271ab8fba1d1fb490af8fcc2a8fa04027cbf67443f39029c9f315a9fd8c0ee578de4274540f31b583b69006f3433b1025b5f1de94e8a80fc378c32274c20fd5b23dc491400ffa5d1cf89c65da14f730c7721932500ff4523989314f8fea179b307d9c6df8e696206763e6bb435a901ddaf18c94f8640e607b399f4bf7c440f7cafd01741fe1662d385fa3df592b8d01ec7bee3d984da100420aeac319b5b39dc8634cb649be6b2cf9a14809c1a57c017391eeaf3504127367fe3b5df3c0cf37d0834d9b322841a760170fdda60ac4a2dc888ede59c95bb326377cd5ad1a0e727f07d69befa3208e82649af61b959abcc6dad7c1c4e27399a1695bf9b68bc4bd95960df52b70bb3ecba73f6e65eef28d5ddde3ed07fb3f9c7b43075e965576ab770e9ae29accbfce338d9ab11871c41ccfa5f9f5ae738c399a20d4280913c14f6d7df1f4a749e2ba1c838d715d958dc1ae6fbdd615469b60bd11a4344e4631b134c43e5713e0865d8e6a5d80d8257b1924860ef53632d82e03a8685e03542a8ac8d1fc1153b54c89dd9dc24598bda69906e3a459d3e761f4229bbf626d91a675fa1069d1bdaac424da58d3863343e639cd162ac04da6ed56771aa19ca900ca8078cbf0ad43e266cd5b95e3ae1d486c385e8f31fe505876b09e5129570417032d480ed967d8aa27573c3fff37732c0c670bb3f16995d1ab006973d2fb0ac7722fda586856bc5ec91633cd51d8f553303aaca73a8a81749ad049c4fb675bf31557858b7594cf07ab40eeaffba8cd0cb09b6dca8edfc5ef9ac12f743c5c6c1bf2ad5639e2650409982a67d5e64d134a40c9da9c859bbc75e3456191cf2b69e2167a480199117006bd42b758c95ad94f9605041ad7195af5300161998e898dd511d8d32ebe495a15ee7ccc1f402635a58bcb19436bcbd4f49a0ee114e52603cca546437b46bcc7cc3758132d2950211bb2216dbb4079ce6046d185deb932f404f5487dccbd86bfce13506e6b39fbfa49f5782eb99ec20e937fe79181bd76d609fcc3045803583b632ad33e8615b961b6d0564c591b45110b4b6579868cb204b3f16c48de813c54e7674543a9ac4e2e38c0546f90e1c291c26f2f50074127d57455f858c2d6ad883a87232f196396b4e11c98b18bc8bd6c648032c10c0162d3dda99672be8f0c30876769617ef31267e969b64bdd3f27aceabf2fcfaf2c22f852652b4265d7bae63e9df0dfb075f2a4f494bea418e75f8d62e1fc1d0806ec4232d510adffc047f996be360f55b199d07c0b06310b03220958bf324b274457d130fe2d65d5aabc629a471c5f64503d892f8f4da579eac71f32fdfd9902da0be72e5ad151bbb15c96e3d2671bff1e95134d471a62e6ef5b3e4ef16931d86120b88329ba58b1fe023b85351133a6fd15a7f91e250ba9cf2b84810cd9ba892fa57e6370fef33be22b347c2244412c70b9593aab15269354fd59fa1bd1b8d266cca007fc4c72f1e2a2a972c5015f755a8cc397a7e5bf4df8d589dfd0d51dd3e813e92213af6a67bd7f25bc5e3487ecfdbc7b9ec93cc0196cad34ff52128e8d80901ee0c13560a020d7d6a3f06b8a91b3dc32b87892a2e0697c07609c04e9cfb21c188af7232849cc2f64deb4dfa24192a2e1349f9b7679714177505a2fc5a36773aaf7b193dfdcccc99d30fb8893fa3f1db8ddff9a165f3f9382dfd9687499b1f5564b9930b26f96769f872281a104286b5f967a363b71d0fd83f4bac836888933939fabdc3ad5b18cac6326b23138ac5ee6600a7e711d67620b4ef6cd880555ed1d31161ed862aa10bb3d2b4ca865bcc8bd944728e847555493185758917866449740a4842c7e6fdd104ba0f37006470be077d1ed441f61b64bca852c714146ea7ddfa4f29146d3611db42ebc9fa7257efcbecfc8be9f23bfa6fef0bb9f964278da93e7ad4970b65c67f404be4fb5f582de9dd3e8297cbcd8459d1cf37de3c4c582d9dbfe0e210fdb556191445ef33f82cad653ea3f15d30074dc871eb67393428daa39241f2bf7f3398debfe55f2cfea97ba2a11b6900f1a7d5ffd77c5f2616bd2bcaa9893fb1b1c1737e8947d9cad6036b8d16fd71ec3eaa254272f59d1729d7c245243d1adac81bc57aa1da06fc08057ccfb2d303e9861fe470ae9568039b7fe88cd4b84896526949addce5168ed37b77e5482dd9b7093435fbaad26ff523250c0b2a676ea1f931d2199735b6e20fcc7fc59dac74bc689b79d9a4da49808cded710e2c966920cf27e1760c581f2d1b144ff0779c980f815f5f9ac561416574100c2242b2aba18661fee1f7736715724b20da13b46eaab83b618fb69ff7ecf5bd11afa52825e130aceec3ff91838d6beb7644061796fc3ca9655ed06f847a0df6d030cd2afcc83ec23439088891339db30d7e6f6e001906f4a43f0e2620e2d8291ff47733fa9bf8c8927373aab775103d33776fd21d04763334ab32668748ba2ace4e5f50bde05aae6fc49ba74233bf06dc562fd0c89ae626896fe318e4ffa6606bc3b42f73b253af9f7c0192971d24d7381d97d4dc47ae3c9079a6003f6c47fde554cb91e48b709421f1bad7fe33ed4306a33f0a2a1db69751143f690f7cfee360a7ca86a8179bdee868843247b43cd0fa2f75a3b43681febc10b2c0f2219e13414d86c657c77ffbf6bf4c3a6efec013ff035e6c23227e4e99b0fd907de9b58d02fc2e6ae003388720f66353f6efa8449ae7c0ac18359ef7ebf0c9349100c0c862c6ad2064f1e8ed5342ad701e3ac588595a6881f1ffa81e00ef4e9d82e02d20adf7fecb2614be72dc5b1c874b99fdd89af15853977d45e5cecd9c95ac2555b88039afe852f23ab56214555a46d14ef6bdb8f2c4d0d6bb72caafb0c21c17a3563e79938cde2edc8ace2389ba31a846df4c6bab01ae6d850cb1654d774573c71e3c09be5ce5c1f2214aeb2e6c10b343d9801f3627047f0af6c045cf28fb5dd845f68b247c48836eec19d4e4f7acb073cc38919608f1ca760c2352f13b64f8d4f6e1b0f6fb17f72c6c3fc0ced3b9e9a6a3d2cb34c641f895d3e65abf04bc4072da86f9e33d5fe7a3e0a10d6968804943ea20aed45b0d43dc0eefc3adf63e933f334460f158f731bc1915d79e1293f270d36df780107b2764840a6ca6c569fe8f7aec32c36d73de779c7711823e8e2755bf751bf82c25c9fffced0d79a2f4d03a3f6eebafc73bec394b4a4451ad4073f2f3a4c833f742ed1d21c6fbca6d8c2136363479445bf40d6534a0e027c4058084bd056168f86c3c60692672232ea0b33a7142b05e29a182116d48544f5b7a403fb63c82f07ae56b553b393d084c8400b84c3f4f5e3d0d15651c2457b7c80990852ae836bc8c67911d16603802d6e7e543f0d4477ad989174d895011c597fc56924f0fd4ee6ba651ef8ef8fbb8701b7ad374da677ba2beb7c96edf4dbe4e2b3d3df03d779ea0f7475ebaf7f487f5385f5c8547adc1dcf84fa36e1ba8a0af2851ac63a318d772992345434a89d635528167bdbdbc01db820707e698d1f89a137e1411f924e9e842ff7ceb94bed3935494bf98394d1b5eb25546daa0b3831c585a16a352b41468edee81a811a60b3851325ef62110ab0f8490b971ad4d0e8976589a0f6dd108f1e8fa3702260738734e90525cfb22787cba0bcff47e671e89268631e42450283778ca58c899544d6fb6f167dd90608846f4cc7114b19af5c2391228737c5feec1f1d1051e78c98e538ed3aa498708995ce8ec81e71bc9deb61e79c285b1e351a5175b205b238f2e94ad82c0f8b237ef621db9ea70e7a8ea0a2a66ce0cc92ad524edd25ad52905bca70fe75bf50d995b25617d31760b708f7ab9be267c722f37525801f31cade3e362d6b9d77c8dff400167660e49ada6db68d1eb90b2347c5bad0ac44ba6c6b279a9f90c49a1b3930763401b9d8c8db5b3fd407cfb96872b46ec2485178f6de2b9b441316b9c2230be5e4615d3f9328cc41717907516dd0f39a6fa0e1c85b9b931a36d520200787367a615157c4e8ee1248963c84390c1711759f0d59115ba1b838c981193f9f02966191b344a35df15769eb5d12b6eca768340541c253c7f588c621318bc3a15eb927c59b6a93f84d35d1957d9a9ea7c12759220dcee5a5132383f8a3c6729999eefd4ae99ed80d9c865bcbf403585684b383127587968bc39c3e1623eb32da8a61a63ff82e10ad173211c9b39637e79bb620fe6259afca6eafb8775512431d11be270290b11c3bf1c54e4f445925d2506d8554079f09d3d946e76e20fbbe6a36c8f4a64c6f7ed789978652f938ca59674793edceeadd14b317575c6fe5f0be8fa7bb28d3b4e675d6a16e4b37cf37bd1731f8944d249cdc9e492abde319689e61bf8da4e7cdf8bb67fa1f482daf064af9bccf24e983c9754228de3bada21cdac98706f18940384df099564de95d6451b9b5fa329c59643963a821dc8411fad299831755e55113a304072a57c52172d57c653f8eaf42a7be4683fcb3aa0f86a874cd591a423a14861c9375f9dad4995c0912737bfd8b8c14855e1fd6f85917049890f5f6b32489ebc9fbaa544ca73655efb55bb5fb04d92c97b5c1b6fae9d4386687c2a58f86fd0542d6feb1c45339bd70b16916e5a7950993a849450be2e6760d317f6ae91c4ddb480548cbd629404859b9f69cdd4c296bc832733db2a25af81187dd2f013bfb513db2f853f756252cfdb21ef2c7e96230b0817011f2486322e8ffa522bab945dfb2e9ae382d36f350eccbd1a899a14bf1a9202f8a593d3e37f67cd607b24df58fbbf940568ce838098e74f25d0ac870366e0d6ae095a4e0450847b4085246210422d954a5aaf81d6e858f3d4a26271c3977eeca4e34065b0a8b1cd11074de6e4e3cff49382be38e533d620542420a2afbba90b75916f7ae9ae1b97e7365d80d0998f24a4d6942ab7fa498cc24bbff3e093d7efcf703e991dc66ad5f533c7fafccdc005d04f6faa725ae78588abda3f07b3dc4f73ca4e1318b58c681bef3c505eb1237ad39b20223e045de9592a5b99eb565098010603945168ec87a21c04953b68a7eaba706dd0e01f8da811c8c7b27d2632d0810e814396b23a698f839444963d483033dc4af7190a67457eb54dea712806425feab6425fe94c8ca4a3c0c77723904729bacc47f5bb2124fa214997facc4ff19c57eeba25c5a5a1c39ce6e1753dd4629cbe9d7e9c2559142bc8086c9b9c0560dd3226049e32f42abe0759eaa896f39475eff00d5b9f8f44ef1940ecd78dfcaa1f35d702adf8e7bc8c8dfb2fa7d47fbf3ef486f9fad1588f7cb337e92cd363afd04194696e9f9f7e637f5f5296fd8c6e8e809a1d66faeabe8b2d7d0f0e497170366f1a6f1a0558823874f60cb9b799674cba9b27a63e30bc86612d3614d69540b59fbe2953f1b6069d4d886352b139cdd994c68b3517132177db0374a2b0bb832c63990f7832c215a596d2c814c83904111d0720167a709e580279b93f68a19a5b5af86933e074fea1b4b966247fca08d988b2432971d33f30ab7ae7cfc9318234103d40e5f0bb17ef1e09442e336d690b5605aabbd59889add0edb439ece48074e469a5186011fb7677ae93f00fac83497f7d352007effd6ab33e3b3de48db33b3cc6c31f9022446167c2fb06c80b0b2961384ab7085ad6e719503686d6043f629d592a9bfc5b08a992e6dfdbc1ed73cadeffe4c2bf4af6ca46050db82cc23cef1a35d39bd1e563a4e86568fff2e1fee722442a4c2d122ac4628ce9bfd34d612ac0164b4add92ffd56b116b61eb4068ab8d3ac2c3bfa93f48287ca62f8c87620fdc586bb68a354b4180682bfedf86995554ccb7e0eb33c0a765308dd0c63fdb525a27f71d9417dd6db9bd42decbf415ab76ded23a5d7211a3b67173c582be4a9e83a697468be3b7a3e4ba32902b35f056ed90a372ca4c5892c7406728ee781eb2d8606bf36e29eab94976ad501b47c9e1365f6dce9180f3666d45111f514f63503ba243e673d4a398afa8f247ea682ef97eed27ad05d6cc873e236fcb1a19e00d7d4fd8cedd03d6308d5c7b358b0efae522e6a12b499a3b463eaeb1458a21a3a85c210c170b746064f2064821bc2a9a2469e470632feed2df7ffab06c48acd788b9e8a8303b8092c4665156f5224f056ca099b3d49b900835987777884fc3512c9b4cc5aa8429ecba8252059410710a0f5cd501e9ccfadf7c58860388e8757c82864e806959d2f138dd076244a0b54a6329e03297c389934fd0f119b7714b73fe9a51a3f1507be73261d10ac609b91223e878995490c3b49e7601c1bb78f4309d9fb698bd8655e2baf8de94e81cdd1c703801f61b2f3e59894f33fe14127cf0a604ea6ed8766a0a67cac436328d9fc2d346a1797376a003c3148381d8584a0fece8a147532610ee3a41193808aa014583aa003a3ed5de170ed761ff8e9837f043c7915c66351cb4df0a449dc400c63d0b2c199e4553d06645e3f434309b72f70d33a59d419f743b9846f9e3c1e915c786de1ffacb1c44daf0895b143514d01158a7596f3b1673a7179420d9aa2f63d60533634fbc534a17afa08fb35cff925247df032211f63b3327ce39ae1f458b64d65271e00d77433b9d51858fd2ebc1c0d6c203dde0a840043e8e2e5060a711a6431c91361e7c545a14771f327eecca0ee396e761e90269e704980f44c35d7b3db45175298399e890894990766a7f68964bb7fd40de401558204b740166a40aaae728bb7da36f96e454e6a4d347f78205afc4fc3e85f289029942b6318fa0ea4da2038bb0df9db1d1cca0d7df6518ea9221478fee0b7738be0f0d2028e980998fe82530f678c5e555c2a1c2fa1213813aac90a86085840854ead8b69837ef64a53ac271b2e49e6e8aef65d88de96a472d8c52966ffd7e5d85c242ea05f00f2f0d26541ed4adc9478509cac4f33473705fa7b1b199622dd1470951a7e426835f6d4fc5e6e7b51aee57b79be002b3e8e05d0241e4d40a445b11f235b1da8d426590fd6f03610dfaacc080ecc439ecfcab9d314868462611f65015d2143cfc2d618f623a54ca8d46121aa318aa5718b23d985a8043a3a2b3c3f0415b130e37760312c6f9c9cb31e7c1df5dca8e799371c3e141386ab2b499193d4eb0815c9d1da7361b396c6889219d4f158e9d22d6ba5ade2033b13cd9776919baf1690d482712c712d6964b699d047b0ccb1424e8eaf50361c7094fd4a590a7482d5b708fc9c320431a5356ae67182242fd804e6a0c2e6147007d9be07a40c25cb34b9b500d21ee460947176051b8ec8d6639245737a064f4f359032232bc27e04276881576919e12d603dba8841e3948e069f4cb74daaea862652092506e270005448109e1e9918b14a47ef3e04647fafdf608c30d80a4e34e009b6035edcf78ed46e5bd44c1d47bebb0713b0104303ad56bf99a405f1cf06ed2c58143eb5701ea3125d6051bb1249a9d1e6fd46f902404b80ac8e3c34f678c569c30728ba95135181ca76e5fb05a8b941f94cdfe8c5604725c45b549ba52607d9ef9c00538435d0205cf5c4b6fc918229e9b5d723c8aeb3711c1cbe6cdb159d42e2ccefd142e4539ac0e722fc2a9593fa73b35f357db46e34eef1d42ac8a6f539957b5cc53e051de4b429a29a405e4d817416d8a2630a331e2581158bcf62725651910fe2427ba7d266fe1743fcfb21be0d7a49f81b6d9b60d4091a5ec36f9e4731bd8e905e43cf67fad87e049957f49d978f74af8012aefd7ac2ec8d5d784853b83be1602140e7cddd430b0859084fdb60d8c79e245e2dc9876168e0896c07405fa14b24d1f834d4096e4978f6c3624455e8507daaeab823098c8bd7e3a7eff1c78e9d1b98c77ec55fe3c49f6b4bbe78b0db47124bf20932fa954e97ebda863b9bb194818e62a349068f8fad107b04a449d5313a1a5fc8ca240f7a4e137105f84941b780fb8a00c62a7b51e988e83205728f731d8998924022c358f815ca5a2187494e0bc0def6e058b4467879226796005767f91aa4c724a06789b29e1797b2e5c5287c5d392bf648fd9a50a952e3e28a49dc1672491efcc33f275774a064412364058fe565adde7851fe6b320fd47aa733b14b1540bf66f12d1ddcb67e98799481301c51194d5cecae3d3a7592f9d315169e3df92aa88d2a824f1cb6a7329a5a58bf6f02686e3e794d57f1ccf5f9ca56c729df21845ad02b74669800c31d61efc56df8a5cd2a8469ee8b22caefe41da427c5764159d820309495f37d8644e5962ab2709940c968c48132eb6d4edcaad7b6eef8d4d55965744d296396b75552d199484c62f97191952b172010846b5c14635af795c6387d5c7257df70c642ad2b86c8902460a3895e63ab55305b618f5c42780cd00a5a76174aa05c5ae5e3074c4bee34c44b0d92b6c06d406a6eb4785a613fd24a1ca3bbb312544948c4ce9aa2afafa73c9319388f583e5b8afd161cf8c86be86ec52507f6a491185b75cfa2b2b5b0f1d408e8f2ddf139ab31d17444931f55fa30f1cb9fec3989ea3014d9ad3ff9304a2970d6a3b6bcc9b55c8ddc16a62800aa429a9137b0ac42925656c7df38ebc652e579b90f222e238cd6e882b3ba2977b158d4f87715566456f99845f4ba83aa1e34f0e8799d1eb7f9d2d59094ee722896694f4b36c296a1206a3b49a54be05620e9ed4cd87319a044a10414da2cc452660e461113c47576004faa450c9a2639f082ce3ba6b04ed1db43d2d3b306d0800b1f91bdf848798353490ae6fe79563a90ae472533d23f486f84b2ad6fa013e84be0dde890cbbaf69f91373191d5b704c4a43c2a6ae68acf0649e1768520fbe2288e40a540a5b6d276d117f858f7212530b0a57f042f8af4d423a53c14081dec031ad1187ee681fccca0447f364cf39da8d0ff2cd200ec1a8061da00caa65edcc8a48817000b17857a8c2dd2559030442c92c8889e82361c8e1c361b4b02b8250939dc54d0951b2a4256e8ed823c26c6fe00b4e12c5ffbee1a6f21e2febe48c5dd8aa3bd1ee59798e14ba1dff32aa9fa753cd86a39d17511c84782875c07e48ca5f3a8317647bdf20b5d25ffb48d346252a788ecb94e05822fa837540827503c581250a018533b4590dc60a2ea4d1dea98c943c2e0326de581a17ec26dda305de07984532ce00205fdf26fb3f2550f01e1f54a0c4673cf4f7c045f8dbf5b14cfdff6069708face802895bd98284cc18f78d6f9bd7f05d1dfbf889f18b1c040b8a3ac3f5b4a76666046b6bc8e447cff2ccd6be5a0b2f27892dd9085e782399fa1aac20270708144f19b98461762db06330d66619a46e29bba641784936dd5c59549fcd43335c5bb33c3ebc058b74b51a708f9f11def2f952f765b413b3404c4ab6955471aa479176268cf1dda158492ce488795d752ef8885aedea09840264d7985e706aa0575b4206ae5fa809ca675682a1a6f21cdb9f8e15d8ea6f6dd0b1b16fd6a9e25864c7622d7f79bb7e28b5a17da971a2bceeaa4f5238a11ab8ed5c056045656bb7106deae17fc6ec208a9c14074c1b5bb1ef4bffef596246ccddc81676d4ea65a07636a784c6260dc2b63c51a28b50b6d2f5cbb1cff020e1a9c66591413a02a272ab214b5c0a8663b5a682bc8297c01f63456c9eacab48234c20718ad37dba0a071fd39ed8c6568fc12abf7fd46eb54a03e49555df20a0314f71689842d82bfdfea6afd5e7d195ceee0d5c9b5cdecf7d2755a9ce87f8037e025830bab21cdd186db88a7aeac8c994e002e4646ad4cc824a52bdabb2ba954833ca82a4534e4801cd84a601b393160fb13cfe7c352988c14417ca1506849d9338b741d2a70185580f93140d9e5c646c076797abc371b58ac357696fbf47fbc3fa380b7d6fab93b4fe188f70aa48b88eeb891830018218ea684c1eba51148cb63e55ac81a7e1c0fa6cd11e6e7b0a0bd236d0a594944b1e2bc86d3f2415c33d0a2c9c2dbfc1d435bf2d160fd6a12e7c91d578e7ab1692fd5cda6ca7f44c6bebe037d87cc20fd4079475386c6ac52a89cfbef64f4b045b076a84d2425bd27fb72ef6790ffdb6e4cf891ff0d1bb63bfbd5e4019a8ba8bc7a8063af313f7b9d1f9ef8bb180d768218b66cddc80a6f32fd2bdd1b1029f3b6a6b4c5fdf7637213be497c6b93c8fe16e6f654838271f8f7a4353bb387037c61369e759cbeeaab92d75294719a5fa7800cdfd9d841f292b4ec224fae2e3f3db2f4ab44db58272493387708a9e04c6050f3565e2c1c8100b2e849280d6cc4da1e00aec31fd83ac6d2b06aa279436212597ff436199d667f38fff50843744752c061efe31ec9553b4d82f4dd394e5f4323cdc9ac62d0ad3f282f38950b628a99045d6b6d6ee73d27653ebe4b0a8edd4752ca7b1579ed76eeb73040513b9d3cd4b77d9d427bf02eac8a1d6d60a5be95f33a44923deff2dc81ee4754c6dd8700a3c65ef0f5f751cc276489f71322f163e87808e70af7f2f5ef6db63162e6751828151979d256f55f83b4b9a60c30cb0c61fe5cab4b66a410dc7e09d821ad1a55c753b03e5ff05bd95357ae4f1ab93861f8f509b3ca2bba955336aa4d88703baf1d8d2d92a08726a4c07dd8aaa5a562fa98896e35befdef34f4615b763b2c3d8a7310ba957c3a6dd9fdbb4cd50bec8c4243211c2ee41759378130b437c6e2c487300e3cbcee39edab41d4c39cadbfaa0b715d369da944c6a0659aed51cec735455fe222befaec88068a6fdc92ed8ff6b11950d1c386b126afe7f3fda01341bed833dfe8e0e373bab37765f4bc8843f8af526712eef88053a4d828969bd8f4925b08d16cd548c9e41ac9c037f347e6edeca1fd948553460939b6a76a518b877076d9864a8c2a2a51aa30a1d2a9a98075933a4e9c52bd6ad16149a699c6f5d04e95e11a3d93bb22528cd420c2a8ee145b440ec2877a811351c70ceb38030bb38cd72617e158a46275ce5c7baad781a511e4a3e9d0dbab98ed25f9c7b5530614e84defd7e5e3b2b5741c1b135508abc3223cc3654ada375aa1af46da90472268c0bedbec865edd34e655f5bac7017c33ff36b10dec4f8bd9f8af4ef4f6b6ea20008eef05e8e1d06dca8ae946a729a18e9c2c41dc6a7bea2c184f85db18fe2b1a530ec7e466954ef7a3c9cf93c33a9c256760d93a2f9e3a6161c3113f15f657c764f86354db09186cf8109794312dbe2be8e15780b04be9e801fc5268e87560e724b9a3cd05dbc60c5ccdd0670f96ece2fbae03c4fdaebd02f64523424c707132026895d249ce94e9fd61761da0ff34418ac3e40e774f783a82d4b9f9a6195204c229868b5dcf20fbd2fb7a540633f9bc3d25b4f36232191dc49e33252fc4a65d66396d2821acd6fc7d1a70b83ef4276dce08eb832782302f0aeaaf0e976aeb01e8510d0ffc9c867b3bcbb6e6c781952e787072caded1c329884cf0b2a3535a4410e2dec326bf231a9fb17742209a0605088b6b58af63fb11b1f19391be9c7079614e24828dd670b49cc3bc32d81e8d6bc83e5638b584f77b2da17fba9d3dbe32ee0b50365e0774731a3d5956cfa7d80e8506a98a52c3182db63c1426fee19ef8c170b8695afa698350f581031a7c5e235ecd9d80db040d3f423fccef559f6d255bf441b90f64dcc2a841324d056dc0df690920e60611e461c4aa86b388c101ad7b253a70817c4116693922120a8143e699e3caf161c89a1fc1c3d1c7d909b2daace187d2858de915884ab5c74032044a7dca58d23dc9954b2bd894ec2071bdad0f6cd703d9d7887fc131f9ec52652224f5295c1c6c07bb5729e3fd00bec1af321c55fd6f490e8cc9c25dd2cbf37cd006e66ba78e03d200fcaeaca94c40eba6370aef5223b6da7fd0b8354a59098cd9d6e790fb4b9e2c5088030aaef1ee7ffb9538df1b3f4b5040d6cc25c0e66d2207bbcbe0bee3d9070529a63c22e4dcb39105cba0fbaee7c01e1103d14875ce0602eaaf1ade881ab134ae846e836c1a9a75e3763b685b3b46c5ebaafdc59bd17bd46b0c76b337e596c7af4335dd65360efca5d43754fd15ed41ed4b1691a7e7bde5e58d01131565aed3c67c9be1a6965643ef7cbbba594bbf3034b5b0aa006a2443cb392086978d33c8f8525478c9102487cc8d881328c0a0ffaae1b796fc1cb3571b72581e919679128bbadb4a36a2b40765f58a9d5cb21d2fdac16f2feb8ad3d958fab7890e31e904ee72a56b189d978997985d6ccf9c7c71307274b553dc92e54619ddf32a0dab9fe3acd455603541dff2cb4c05d100b9bb6bb7ac64d3569b00b875779ab2588dee98778add304c6be5d78fc4efefdfbbf125e00db97e323799ba95a2b8a8c28c71ef3ab8c5c20ad5adc99f0b4e48a13c814cf9af312acaead76600733a18189bfa6641f5e56d2987575243461df61e8a01b383f293d8a7183e2ccf1695a8e8482268356344f9d01e7c30797475335a84dccad1afd75f65efdcbef7c43a23385066002c3db8d8d8f53128a5b0b310786b12835aee5475ceb18e416a186a021c94fa976229cd97226b8731a0f015689a91b3d3d38316bb9766b83fa294d63f083e68d7dd1bb98fae44c796ad82fb4e11e9f749afa50ef2ae1fa66507d0c6eacdd926ba287557b84bf358a15e37627c97513742b1cadc09078383929c4c03ab4decf4ac5c4c7238b696c5ccd18fa68d67cc5c13b64e559190aaca7abcbe48d698ce3dc65afc617ad07e30b90f3e11a58449e0f97c117e8c67736169b1514504d9d3b426fc74e2e73bdb5b5fbc59fc84103023c7c157db8b1cb8cde69ecf6fedadf11f72efa44001ea569a793e81276c6799290838bc93d4b47c813052d7a6931ae927d821cba357a59c8adb80df248a8a81498bfed5556d7e9a94bfb0180be09c5dae6064c49537cc2cb88fc75c58c27454ff374bc403dba61cac4321857c41f9fe2085662ccdc45054d53e652778ae2578fb0328e63190e6d16b8e6e4c577ed972d86566ba55015aaf9d44d79d526f3e5f7f2f5f7eed7a20062203f791bfccdf3a1b1d8137e15d33383ba7abf08ce343a6e1468145df6af9aef9e073c571820b735aedec4ebd3ab27432ad88e4a5720084c2ad323a233f0008031c2cfc90e37c76115c587ed0ecaf03812d98bca5b537a944ffe5878c9aa39f2cfff0bd41ead0814bd8f609502615e589a35642a4b8edca335fdf42444003f7b04d8e4fa08ba40600ed0be32abe079557117187d2515cf6f57230fb484ff33953266d1f318c2e2b819974999315d2b2c5d2822ec52c14469503a424e1ba27c3a40718b1f23026e48425e348de92bf2a3f1da8dc27a34d9dced1c57f445bce7ef6013e4e5f971958d8431685c8f6c50d5104b1c3160920b9fec11a847b0350cb2b221a0302d6875ff0145ffce627e38c09194de4f1263e4a846223547ce81d68275d21355325f8721d281e4464220c683be69548b5a9dae6d6eaedf94119291e9f3240aa17d5b5b32daa692ebf6e88768602d1d11e9424113b8a95d07e6f1969e5d87853c6aff3220d0e4eb0b3ee9a6038355a298c4ff2e7e7622b2167304a09be4c3409da9523f144ce7960f45e3b0514f6214500e5d83b6d847566842158d4083e18d0913bd9c6aacc612208ea6ddfb864ec74e277c10ed1a5849edda7c47904bb6e106e5cee54b3a2510996952cf895b26f55a55e0b59de26877a22b886fdae6f5aa12aaa3e85ae728aa8b660981dda51cd5610a168a1f33c61678792f28f17896057a4b3511f8dd4e94d5771fbaaad5741b4a80095aa513cd57305ab760afb157caa44d21db8a1153acfdb54a6457dda1f5531403ada611f00d0e52f2de19d6a6e40a52e60a3f6ded329e2c3fdaa8182b7ffb2447e8d7c0c6cb96dda21cc5cde0da0f17d284f851fcd9dbbe877a80660ed06a8e656cfe4e22be56be4e9aea08c0b742b6d1ac2561e21ac8bec7e0e17cf4671c0be35b10513c3ffd283116d9a28e62e33f37df6c47632d73e1c43704f0c2ee117729147deb778f302f7eabd35e75b0ef9a4ea5f7f023daabb7a02c61729f947412c47cecd6c32da6f80d34b054b60a51901cb52a0b9b4e2290467f744dce60c2a3f82d573330925e37c8fb7995fd67aee5566db6c121c34221d12a804985af0a4733fb1ac38e3057e9700a232a77f0a44e70014b3fb7f04fd92d7744d5f1cd3e2ac28b329a78b9a9bc42323bcf357939fce01b88a50d0fe334c2b04106d5a2a951e46e13e02ab09c0845f391fb23448f2ab22aa7f0937b17211cf51c965d6e1ce3a6972bffcd86584a696d7f399370cc1b4a5ce6e4ec2999233ac7b6ab26b6bfc70840905f2b5f8d738d6c5b34dbebae1e5e0500c0f74edac2ca52ce1ef0f68fa85858b3e8a89bb8c09a1b7ff92fb8a5c533ed83abc53e838eb740634329adb2fe012563095e087694959ad342d068085c1fbc22f1ec79adbb55736c99d0a513fc9d0c50334f58d6521d186bb67c8fbe2392ce2e3602b327c8ac5e4be810209b895c4c49a7baf8d6c20b41853d27626cdfe8350c65858b0726033f617eea2a601f0eac9940f9b477548eed38b7ff9b200366bbd6bd9b266747bc09b7686462fa309470ffe5abf72b5a7771b0d7a8de8c8dee6dc6b108c111dfd4cb24464bf69c94f2b97fead27dfff675f1a2efd7c4beebf8eebde3a86b7afd8336673d4e298888b642e98d8a368961c1239d17e6c8bdbee55ed8743d0b9e5cf1c94d2bf835c54abfa9ef36714863671d3d0ecb0447eb9b471072716fa603d375d826439adea7e0bce72e1d9964442617f38086903a087bd4b9ecc49107a35133aff7dfbfc6b97b613166fccc66f8cfed8fa50d70d369aa00ee3e03f75aafd6587eea9741e071fd81cc4e975b8053baf993d825b0eca062146bb61582604d07f44e903da78c206e215020a8c117b067a46e7482e4480b0232e4d5523d8375cf2c89de14db0995a7ddaed210a91bd1891328efa3adb0714223d4d0262abf1cce6d6d5ded15906650ed0b9807066cff8b083e8d24a7f110861e578b68f76efa780544ca10514a1f396ccb7e7531115567d71cf1af2bd2cbf2eb4dc87f9208ef939342be031271189893e085b406646aa31edc918058b4ca08906b1b08704c9c688035703117d7ef90691ce58f67d3e1f3ec6924f4144a6edcac62f56eb4191c62879087b57748af347e8f52304a10996e13564c4af223904d1d0c5833310d79d493b560d7f0c548ab06b2f1510f29f48acff79eb9bacf0c8084c46644faaa1df29d5382289751333106cdb4d610d7fb0db2887ec1b699ef15c7d50c73d31a94e44dfb104889ee8bdf27701d8d3e4c054cb978faf070b23a0fd656c8fa9adacb38233998468fefa0db451c9f771000de1368d21c05834bc4eece0c9565a71a18e9d648c742549c127a6d171859848233a9b75ea0a352c294974ede1e75060360fd42bc11ddd7573b890d3f6df0860510dd355b25e517a83befdbe20a876f0c1482b6efd07406d25d1d7d06c30bdd2babd234fc463d546a33f4282f9f60f73a03ea45d60e5b2406ac56aa8477ec2292a4636c0e14f2562cf1524460147774ea78d8b970538c22a920b86121239d8d486b37c06b012bf647c607c60a116b12f4a32c4efdb3940bec4b66d51443f461ee37833ef524ca4e0f0196ba1a3ca0301162372e3729647016ba9dbce164cfd43311aa1314a4f8fe57e66961b3c919371f2205f0f4f418cf521586fa6151c576ec8b980a05b426f85488f59d42284bd60684fb70701fc7d73625f08cd280402f66bcd06ba7b8729e8f65c2d8d861e83f97cf0198861e2983b5eb0d3024ad81b8027f106c9a1355d3d64d6c62397cf9e80a375ce4948bc933791a56662357a04adf368563f62ee23ca4c4e82ed37fa642273009aea91041934af7f2ccba2b81dd4e9d83ea5ab08186f94cd959accfc03028c88f95a92992f70680be90ac7b26131abbd206b380cb7f74a6255f132852591adbfd56e10fa6f8d8ca14611efc6c5ca27f4168ec42aa2438bc2461f4cec36853b4522d69ae05b973c4cef18587f3352dcc24234e34a374256e5b88c2b1df25a6322d9e1f66f790f32feb25b01bf33c05056685307db937580985e0257c02e2d146f2933df8d46c428a7c0c98a17558d9fa801e38b300fad7871f51e5e26a398aa37306ec05d9a31d913dae81d30205c150a89b875852e79058cfacc0db2e2d52206448bb47d6eed2eda9a8ec12d155958e8d6f79df6448957d7722b652266bd849685c00b9dbf71c2a2451125e2c5bbc6b240970a013b36ad316b87bd18f3072c3a9111255e54e9ac1315f1de6456f94eb05d4fbc7a22592d17743b231167bd0a526970aa3a6c7a250dc4b02a53456aefc8a03d4edbd6741b74fb2a6bec369a6aa0481fe24e861163bd631029a8181aa6dc5d1241a9ba7b4465b91f1e0aaffa15cc12e867f6a243429503f442edc1aa7ac96f544eddaf55a4fe67fd484bd6283c3a8d9b76133cf1bf5459a8c6ee61b44a1e1bb3f2554f8179d48403cc29c0ee031b33d53d469ac2bd09cc853e80f80cccda78d848d3d7b8deba0ace7bb2c37425610a71a501caf3dde72df653710de55ebdfb47e9f3576e5d0e98fd7a3962d990d2453d74859aee6d326c9437bd2c2b2bae966e060d489cd68a227262c245b068633ee4e54f8a57454fe0aee289d18d13b605bc3c8f8b2492c107223e75c11ca9c868737b03ae533e1edaf69b0718ced238916bb1e7487a1c4b841307aacf957cbf867e8d6c0130b7688feb77bb030071b5d603e2f2a04225f57b21fe0b6537664f163ebf47142bcec002d5167ed9fc6d349eece0926b3b68d1e06c7036049f3684b51cc1169a03b6629bd6a9ba50f5dfbbf1df583f3a2128c7b68738e64dbd27aba683bd39db57adf54cf8ee73cb617a664a02f3782592b93dd068a721f303f53f7dcdde36810aed18e8631d81e77b55e34cb3c9f98497d30ece2b4aecde9379e6f439a8082abd31c462f4c8940bb7bba7f8632aea009f2dc5c132c9bcae6caf591fe21c3f4d9936d2d1d24eec28dacda5b59282c6ab75bc3384df1c691804e762b42a39b15ef2dc3b3a76bcfe5fab682b1a94ef4909dc89ff85932ece72a6967187c2b71a2262ef2e90ad85ef3384db0582139a2af3ffd598d2901ba328c9bf21d7523bf764e06a6874e4f3ea944fa129ae12b1134bb15520dcc99adf5304c7e3ca170b467812e9fccc5700be6d73ebc1afc1b7d99870b1c47a8f0dc97d39eca05a6a9522087b9b6d4307b706aa3344783838a6a5ce0ba9bc27481eeb7930b790c9e4bf51f02dcb1a6f7f9355e357a48ebed2a9537fbeeed885ceb5f2b30006fac46ee93de69745f05f3c36ee89312e2ff2ec28b02ad3b2d3482ba1339732be981b3b874b56f12f41acef4aaac02edd0534d502766cb336e9d0a634b62ad4648a01289fb444371f9913a4cc8f14b524e064704391f1b9743e83066ca0e42e13cd7d65784a1bfa3b24bd984a527295570c64a0211bdd43f8709ebb467ae066b49177aa2bb4ec4d94bf9e85951b45393a2bb62e42ec9f1055a39028eb2ee884460009e4525ed5659584a5de54a2e714bb41bec850ab303dbf91b1779a03a5462449b0dda065304e33f9f93b74e8e3d2c917d7ce0e067ecd175184398122b92d5c32348dbb1c3535043d1cc0957fbf687a5858041e3b5ddc42b9c3777f0a9e5605670eb03bc891208c873942d306fb625e09a68ff19fc1746772fc3d6e1a4d92a23f9b49a808ffbde36abf1973da1a94ea0a8ffea73b48c490625790fbe8217f821ea63a36bccb66573288ab193838221fa72ddd65c3067bd1dec6c780d833773820a9b92db0e490b90db6385c2d5207049adcc9160b1926f95ca0f27891e621b093fc760a5d5693fc6510cd3f867e346a0fb14f8ed5fbfa433446bd23e1fd48b942d1f8e0f2373ab24e21741f3371379d47d4e82b95de64822b5289ba7bc12380337ba3a09ea420ca117bb7cffe31c3eb9027ee9df0d5196ed3514940bcd9c5e10094cc6d14a872bd63e2b4353ede38bd1bd2614b31f20c4cca80aa26c2ca64e3aa0a01bd1c289c283ca7ef26a2448e38a19db0d700f4f4b9e14ed7f771647ae7cbbbb44c870c33a42f86f54f284d03324c36ccafa24bc66c46b78a86dda676e532211e72a6334643438d4d899468dd82fe8373f1ece0f52245c7a656fd7c83a48145dd9c20d51b33e3b62e71998a1c170fe99af3aadbc76234c045ecdc93f3ca89578c4c1e9defc960eb0c1e797b156aa168fff72b9b6dcd61c3be1d344c02e8101cebf8624a63a095d9c15ab07931eebd63c29c801568187de7a2bb1c337050c1b2e8d9b6ceb4517d9b4e9ea4939e1ee322a95ede796b3dc1aaed9e17dbacff6423e3300c7c838cd8b1282435b98645dc911ee5d8b70907d8696887558fb506aa696f166e6b34411da804b1cf3f90734dbcd5c0075b108d92ca9974d798083bfb410c51526f176ecf5e2e6d790d8ea610153e80bbdf8207c6124e977cdf048c2591f07280c7b87abe093e7af17186f1a04f79de1bee852df6fecf99caab08df05fb3edac7bcd0b3ca9b6564ed7894fdeb2208831143369daa6553f9510bf105c9bdeb3444ca53e9c5ecc0b682744101c18ce21532a9a77d19917a046c7aa3dc3e78b3f06b5fa01f7ea3218054ed20449a598ed086cf35f34c6a4d4574b4b0122571880b81625e017c467e11d543fb6426f23df81e2efdfd287b4e29e927a270fad359158a07b6177876932bf96ea7aad69c6461a1f68c9262cc53222d955157dac9b7ff42871b731a46643df86a88200d378b9c3177d62a24cba00fdcc630d467ca12c8c00794c560ea830d56e6748410fe5d5864d76b52c8f35819f9e94f9494f7e83c717b6b0d516ba69830c6c4d8da079a631266f1319835ea4ddfba6d65a350ee2385d1bfb9d8f542df3697dfafc573198abd2f7f1dd3d4aa71fa1e9018c96063f89dcd2fb65d6605824a47c7452e60e2ec5562fdc9e718bca98fecae17bbf70ce7352571b5906ba082e20f7db811fdcfd8287faf08def6087d85b79e45e1f7adb0f6c5558e0ed7bdc5d2eb144b78beff556399adb2dff6166280d8042b4ad191d3727be71044d26c1360c64809f383b74456ece1f37c8a752236fc3e96a2250af1c6903578b4c3912ee9918d502bc799fb49dfa65ac7746e449342073e5d8b61639c54b44f6f04995511a6075d0b94748f048ce8694af0ee3a6c02413279b86a51cd6d66887a631f32c8f14c3d6be07ab3361aa6e226c06f402b395ae2ed8c510b7e65755673b8593a60cd8e4e5a9fbb64034c627beeb6fe34775d3f41f17506d287fd5a3b5722cb577ca7b589ab143aec64aeb655a9b3993aa3babb898cfc4e8f6bec0071e9b146880ed4fd096283b1da7d182b3066b0b362107d36fb3e87c1f14a4f33af20391408ecf086981eb59300010c5a3eb018db6fe2dee61896d3eeb4ab6831f09d80aae13ef6beed55c50fb1e934437a614be19a9ad2d1e33c043d28aef6ea50915a8e3ef06d79f803f8af90a3519302c646625b648313d804c3779a481b7a6f80866585b3a20e98c585d5440f5ca9d52a003d62d2269bd4d7d4a1d3e13a40f9b154e460cd3ce8ce3c4ab4f1e13c41fd0a39e8a87198c51cb3d5195fc85bcaaf066ec91c4af792639f56f8f69007004cc6757a824c406499658dd132fc82bc8fa63fc0a0cf7f79a8b083c7d59478c6fa1aaa3db1a0c457d791aea60f940a1e258695a959b65e458b64646ff9bdf27e5e6b7111d8ee7b240fe6d252136049b58c65ca74e6c498f1477e9632d14fb06f4dbbb221f8bc2bbda9cfac428c74b38800a19c1ad34576f7302152f947f643906d43640e8b503ce3bace0475a614190d9d5933eeb056a4f4721a130fdabb279b039df3b2e1f585f8823904bc013f8bbdce7032b67c9f1dc34ec556de2dd4448cb6ce7b79a20b90354a9eec6b909795d1697794ffcbbd2edf349f45e6eeaefd8bf69008366b7dc6c8c2f338fff181c5d0d4f2aee3902c27ff7149b98c463c6b114a25c201126507f14b2ce5957540ee8ddfdf1ef272f5415678f3a179c4b53b0cd683682ff5b1b625cdc7b136be0f860147d4f406862c70eeb01efad356cbcd3ce679fc5e8ae3e2517affbd69b428683b3d9839b6614e2de934c0d9922f80e4bb015534d1702a3c6e77d30334e2074f00c9772cb79123b7bc1bf467b24f1e9811baba8e510a563babf52a6b42d29866516611256bc9eadad9f4fac3310a348f661982a2a05d398d9b4db885d4ba9925cfdecf847786aa01857a3e23ff45120699f981d57632308a12b6b2c071ffac515102771c753010cf1a517023a304a7256b19237962d2a66c2064195ccbd35fb9e1a5b1d0db188388a2185e52e4419ac4fa5f3c56fc30c340ce1e7e954cced8c5dfe883f5940262004f678580eb00103e9cac983a3a533a068cdfe903e1c9bde731aabd825cc2d7903717cf28dcaac4e1c8b0d2672a478434f6be5cfb2c1e4d947173ecefd4a3bcc4e6114acc6008a8469bdadba8a459e4365585dc84f59e0409cc9860b0ca98a7ff5c97adc392b6b4fea0473f6bedddf6467f642c5e1739c0f4323d6c0e6956435f9ae0024a5fc3da7ffda5f92935ac9215c08dda59751dc3fdcd402c174635f83797980b01f9cb89fac450fcfd1e5105b66d50aec0296fd9064cd07be617acef6d85d0ddaeede84648ea6879985af055c5a0e92a8ca13f89b1e6b6c5fa38de020fbf28c3aaf3a112d9eadde9bd7e43256e01f909992f95497a07aa4f06a0c78dd8886c23a60d44acdb316de5a018bacd1d7308a762697a034e22e000b4d23005b3be316404d145562ced18cefab5a11e7aa8e9f5a12dcbee2870cefa009dd6d68b56a0e14297cd6df74cd4dd46ec1b9398ded294e9d43e8215b4bca118fc195ae4da7253fcaf019148f516b59f0650110ae1fedf3875f1259e13715517a80bf3a86c3ca081789db40a15379189810f38df20758f7704b7ea4f13693692ff6ad08eb3fec2565f73d0b1bf85a362d8e842b9db3f03d8255b7e54eb4afe3718818d26d9888c12f91bb4175d5066fab6f1bf151fabe6abc40999917625f89892a4d55204b8118f678bfdb0a0e531b267acb1af36c5ec05bebcc4fd3c41d0b6708c25386781dd4c18fdcb18786006ac1606a9433ae03da5d9baa2f2d80dd4a4fca8b35f350f36a52d7df7866f98ee2cdc9ff708e4b7982edfad5113faa9125bd41e7949b2507b241b104928aa0796e6956734abd2be426969e258072d7a36660086e2ca1b9cd5fd445a44881327de3c73ed65d690fdba9ea66c247148a0fb1edcab9e050b09819b51b3632e1599d57f6bfc4037b9098ce469313e570699ee7f49394061edf54ac39f2d58344bcd70ac8776caf0b38632ba8b638415428bfa2243b9d6405980bde3fa51a0bdfa72c3136f2220c17c408872a0a3892aff3257108909e621c971caff8d01a0ad853f86f4674fc753d1d8262926538c26aff9909bafa2ef5f8df4e693b312c8f4204e43c1b12eacbdb90d312489f6aeb7686cd5fb5e35b099b2b2bedb21a34130d03c2c8b759ac2dac68ae4288d12589f2080f947363ada602bd56da68e13603aabfcd739802b01c8cc97c476df5f0f7ffaccd8267f8a1172a1ffa84af622f7c7d7c1371c9f94edbb91bf737c534104703bcdae712ffd994fcd2cd1cabc44709ca2f3987a89556e761e498e7b0eaf64f358c466e28e0f0b4edbce1dacb4493ed7a9a76ae3321c7bfd53092c3f9821a9d189ef073ce536e4665eede26b297496be2b7f80de37db1819c681624b2444076f3ed6b388ea9069a59d1acdf572f6d62de14ca626c4a0d3e88748ba8830239cc52b6c9709a508076139a53ad64ce138a4f88a3deb0abad520b1b76840d6271ca8b45bfbc9656c02daaa09d5fba8d16f2dcba81136c4cfd6a8c2b58f31e90ce6eb6bdb34eb36550478359db8468b47ded3e09a28df9167da5be262c9126b8d61c5675d57059dbb1b3fdd690f80a5695bb80d51716347747ad0b3ea7dd98fe0922ea355e00320fccd0d6f8be70d2d2ca734c0f226682ef31bf1941003059ad9ec1a0e04fde27537b72bed4eccf819f9faef168325cda67fdc181e7562da7c19c7dfc4c40d08ae58df02a2f763fddf17ae70f1d79d9281bd0b9947205d0bb444216dfff9feaf9c83be12e4333464ed495c518a81ddd6b57c353d77e6ba0beaebd0f970bb7ea3d78d3b4d180e70ba2a91d2fe1e57628bb2a0ee843c482da3810a5a2b8dbb9699778f7f80a3b6c5e9e093f56dc56b1829e10d5e2aa0cc8646a49a5fb476b24ff1cc4b31f4e6c825b51a7d160cd8c6af641c0317faa3fafccfbb358af8cadf87009ef7619cc78f1d327782ac27fcc4530da6f1e9fd2a4c5a794be9ab4d26261a99e6fb8fc923e7261f5e4ea4b7635f39c1369d9d4c615b9ffd463cf24d4a675f99aa95705f9025ec147f3dae578f17ee922b867e5207b695270ed4a3508ed473b5722ad3895b21f496126310670a43d2dd2ead442e939f99c7dc75b501b8e04754bfb8b23714e79cb61e3b684696555fca3f8f5f14c526bc43d64e87a99382b55365fabdb2e849808d7e257b95691e29565e7328dfc61e6c47549c5ff8116b6739fd497323431d698b3f41f15c7b05d53b937e433b115d1bec0d221345b7ff1e9cc5709851c2e598996963253ab28e3372f44a293a3ea58360ecc6328e77c532b1333c1141368b01570cc4804c84140cb97a0141ce951f9c6bd30b55d580407dc40c498b8ac03f06b707e6cb4a6a8cbf109eae9bfffb7e45a8f334a13a94338716bfe812b8def3648fdddc20603b4f9aaf68893f1f8b613a71e1d707038b1eacf8692d6592e5d4094888e8dc4de1692767621cd620427bce6ff16059505c42277c4b972cc0af60b5d0221c400c70dafa6585eadbbf2a92dcb7f6efc499290b939c467b1cfca2254a44ff1c397873f7519b9839fd311682cfe1bc043a541ddab5f940e72e0917c4e896987e55606c1402ea54f5b46a5f14e57ca7397b1e103335033b42d84c2851458bee6d610c9af2410e13fab61fa60fc51aae65d501c55ea11f2ada2ee36936f25b9be0f4744c48af2c454d3eb18519e140fb6b254d30f39f9e35b8d54c49328a346a4051f792ad299c7c5f6d04f5599d90f07dd5a05fed4ebe9006e3421720eb4e469a4de6abaa1def174a1f58c844807bb442962904c00dca4591b37984b4ec851fe4710ef015bae10ab49408c3398968b2fa2e36a6eeb20798b8909f0ab324b5ff59cc42f66c68d4b1f683c1a05039e1358775a36954ef318171fad194169e4c69ac9138c606b8707ffb7af7a89809b66d0ed72ff5b4d0996110a48aaec702bbd5787c9c5d54bd66acece92a9c8b8cd15a48e674b01d3a7c7b410f720688c0c9eea9e69b02f40d327068e39d83eb7d5b1d21a7af264a60524fd491a9dfce4cb127465ec2fee8bf7a30ebcdd59263db85912c5c8d1e432ab0989568f27d4f47d3ce8ce3cd347f4de01295cbb8e8a6dd37e26df42a1e8b557b2de2f11a693fefdada441b1195bb4903fb277727aae88bdbd3c685301bde4d371560497b7932d2bf23a4a7bd02c398fb54c052b71ddc083cdca37234c468b155a08d3e6faa9617bc6431cd5f309d4035802de7ba406450fe2c2f7f9dfb6c80b2fff29c79428953646a074a5da4fc21ff2fbb575aa1e809c2376ffce2f2d2d86cfa7f500cfdca2a02f5a3800110905c2a91df2708d21388cb3792cddb355c8bc7b88ab1e30ee7c8dd2f30bc7249ea43fdef01c61389e6094fde3ea74f9e78aed3005ed6e285a236f0768ec632801f608f9a3210affb25b7d2ee8bbbd56b6ff1f315b0b0471bb1f11270540ab1b7e1dbc9e1a1c57140f76aa1700e00f85ce1e6a330fa8610513d4a3bb957adfcfa2bcc03e3bcc6feadf045195c3012362f2c76dc80ec36da93e01c8236f056ced47fc2fee1cfc02a4fbd054bbddc37e814dad523f24df4d103d6819a578b54a3d74d12ae261eb002ba9a813637d0a0f87441a2681f89bf1383377b1d1581234c54f50c22657459a89354c745409c1a686240e8ee5613b21530cd8464aef7911fb46ada7497c29654edccb14bc1557b92c9d776340716fd2a4660738b2d1dacc7bd60cd89d81d4e48813e49d2214a72acff43ebf57f59f50642a2b475e00bb779f2433967ee81934ba66e5116e1e55a927ffd2f6adc20a70912d3874e08e9706fb67f373cbf23a9ccd3c68c8208fe3ec5e22e44c00dfeae6710c15d67993a205347b9bf6704ab0ce5bc0cfaf13117af78f0496ace9712c88d2a88d12c07eba2cd77041edae5bc4148d08a63f56ca901437991e2f0c38a22fb98cd7578123efaf2f8d9a5b9e1e0e4e60a247393abdf5f19f2e5f9239594a450a605c6fe918c5a11091338e27270964f99c7c1d11d34d181ac3fbdf1cdc07978c82b64734b6ccf3778f875d6f1fc9d4f9fdf907d634f78e7d1a7c075a91469a4ab70b7c80a4c33b5c4dbe78011a374ac110475ac12d9deea420cd8ec750a019037aa0e33c813b69fb01c8dbdd769ea1a29f9351db8b20c1240b465b0a88ff5fede6ebd58c16b091a9e3a14f580cb93da271b83eeb6ead3a66323cfb8302865d309da6a17a969da2416c27f0d99f301e769e9490df4716a915641ab74bebf54d4e85d15219491021ba12cb21993a24a93c7bc61bbfdb06a8d7d4123f83ec84691c23962d65e610162895f59fec9671b810c167b72c147506cf449e704cc0ddde0005f11084ee64595e0c97663f114b81dff3e6778e2ee38a49289cd8ce30eecaa85e420b8e139bca9f8213b488b7d08a8668978b309bdf7ce78c48e2b2af84aa1d383a3e92305533ff55a267d796161c89c5fed7c5752a8cfb1a096660e50c4e2ba8f7de58b63cae39da2cc9623063d425a98f8efa97204cb3a3cd42b52b261ebe06be2f76e136c439fef1f9b8368fcf61a2bb2b5095abde2976f31a9e5b2e147cb7c0707f60961e85d27cb40a11e6b5940b0b0f963d2f949fb415d367f9422c1e46cb08677eb8f57a1e7c5ddbbbac20719b13964d1d9dad47f58f2b45a8fdc0f9597e46310656d258cd9c02cacb7b9eb0c21d38657d989e0363630f9b1f93947d838e67e0018e899db9784709105f587172c131624d7ddb46ad5834ef0267606f2fc4d6d0927676d3c45cd2993706332726e12bd956ec26aa5c9c0460a04ffede4570439444406dc7523e4463664341e666cdc818ca90da03a98c0e86a0f66c39b88aeac94dba67d96de0c5c074f3c0cfb2df5f319ebac09d54dddc61e44e9842045262de53601ac9afba451fddd085b20f380619103c7acbd8c7f32e5bfe2fb5ba21f81c45146338ac2c8d29d45b69aacae8019888ce7c227a299887676c7a329eb74a1b73b209de1b78adca7c7d0a325972ec404908a2c7ec08c0bb91737c0fd3ed340c19c5fa3af3ee75303464ceda11545f762d72c5207a3e2d22c29a1633aa662de31e6f95850301616a1169088443e2991beaade370c556a5c46bd47f2d6dd81c7ffd7341257cfbcee04e40048e4a88a8754b1685fe7d412980c117136a23997ee45de6a4b1e947163f02c3a141462a398ddd4eea1c4d0641cb507a33622f6127cdceaad2e40e43a8567438fd7aac5e2825112de80f08906f05462716c902ef9420267e687acf324ba9265f0600495ea0404731423f9e49fcae67007a543a7c13f2e81a9dd769e82a22b85f9db7a4344706b098f4279bfbc2590c058a3144ba79ef3e5b4fdad93cab0c4e18415735c074f871921d97c29d9eab4b75ed89b90f3ce5bd9d0ae3488d5d9261c889d0b2d41262e538f26647ac313f7d931df00e50b7115163b35c5b04b3edc6df750e655a62f7bfac23194c1e563b0a2e7a100e0dc35e4e1fd591c355b78bd7e19e35a1c57da903e0dfbb28a8b6799010c8ca27f362e6baa809415ec93d65d11ebef6e8749e321de258f02d370300a05c326af0fb8fd8690e15b062b9296f38b3af7d3e693f4a321ae00e640eb93029b651f2ba864ded425bcec92613c384436a2ee64ecb9ddcd132e0a9d66218ff334ec1a03ab8fa66555bab3867b74833364cc04b67846799e800c4a498c310d3cf7db5f3a62cc2f7faa4d622460b43012917a871c5601d9a74a31e2ac09c335e6c03793259db58d872321b4f8bc543a92dfb7e9287d361a8eb0147d073ebf00bce6960d98da768c5fa4c0774412be0b1613710c916dac3349c9469a0dfb9d6012045804d9b6e3d1c02bf45c8078c30021b1e749a99dd4cde3173de04fa6b36a7471f3b12e554450fb9201ed8a670372a2c67525f3e3a6c166f0e94535280bf00fdce22f135427e2a6ff9273c9f78f7dd792484c49a8cefe1443bb3e03b3f2c05d12700a1824a9092dc7b03678b4ee159e372af2441556eab73d68dc46bde1ebaf985c881f846c3d60dce7eab7aec3b9aebd72e1063f2a6014818c61414b07b9abba63aabe59d69cfca3036ca60288ffadfb1e54b101066889f724ee60a9558f0ebc78958f05f299ec2d073af978ec00ff2b7b8efce1a23f1d61c3613238eccd23b21be10d5b02cae011501d61599bfafd135084268b5895cfc5191bb3f12328c246a0beaa512903d79278ede3aa32dc4828ddb16689317cbe626b34bcce88e21b6526377688650741d776b35f765d5a5a86347107b1cce758b2f812901bbd5cccff6ff1c1d133132bfa3970a36f1f88301bdb7d418965685ac5a6194cff5f99daa8cca1e8975e5033e356695489cc022a6405e5330116e90ca5484a18c49fc382738f7db13a7bdfad068b4f5d3c94eab1f411d932efb41e45f6436ec67e9a153eb3ad6d0dd73b761be07338dc4922f0f870870734f28f126e0e1f03b897caefbcbe7e0bf3e0c17488a1415f0101cb59b2eb37aef1f60b96c8efa33baf3a15fe574141424c390b82b0db395d25392d116f7b8b08af7ecedb0f749636396d029468082b7895e15e0be6ce8b8af43b8de9e8874cdee334ce52546caa2b64331cda55a63224a3e5006b8e13770044ee3fb3685b4af733d36ef535d567c32743c2fb560190eb55b1a31c2f0ad4ccd9c5e8749b00599694699e3211a12f8c96d591b10372d01b53d4d6f2bc4f884ea4a97334fad28508a44b9f8b079a6ff1755e58b8788832186d9e99e70d36048efabbfa1dd6f74407eb6e325cc0c1cd17f1853bccd0e8be315cac94a08b092f40f953e43d3126b4f15b69d0ee11cd45d9b1775909c5cc4c0b9774ca32b4e1fff10d56362623a628711b9912392ce0291a804a7679071f96650286d2b6c0d2ac2fd268876a56dc6a87594705563259ec644d9984cc0aa36ada2f8ce67c53fd20efda449228674fd2acb99f2283cdd2d76f93465969621a334b453acd29b2734d380e20516a6ff0a6c0cce30ae51dc364d9db57d59a288f812a13dc11d52a3d9e263e1d14e9d6e0f6f120dd05d47e8a9f8a4e65499fb8bb4947f20badb8c3bd5335d7a32e8dcb18a4bed2bdfbf50c29d7b990afe4ceb857f8f2ac249a4a1374df309861cfdeddc6e0917c82fc2e1d2fbfc75391e4a7c760069bb64565d771868583db7ad75a227171cd62eaab9870f61bb050c60e4b33f716d986d35bc7e0bb0f78b50c5faad1c4aeb6c2430b76ce51b0f544d9c4e290b10339b215de8083af622a7ba1fde39301e7760778d1ba0a8de52661c6d3ec81d4d48afaffca72d36c7dc5b670cc36f5d263ad0cf72c3733594c1a3634255becbe01a91807147b737f53a0b2b9fbb63753e8e7bd91dde8f0c0b7e3de1885b72560f3a439c6a41d6f78c98fdb3bb04b1b469d8e9bf0ca2c86d8eeed02fd77c6696d2626da28b27f4065b5ae83c2bd76a38bbe8e5f59ac10ebecf3633b6a5d1517750785fb1bc14e9c50af6c0a3696bf9982c358e6032e30d7e7553fc4ad1d5de2fa297ec0351e5dfd8591efa6a30e1e631dc07256ff0abfdd8142a7540bae5aeddfc16b5afb2ae56d855ff082d761b86c935b9a4c7a401f949d216d4f9d68be98d1b6724e4e7cc536ba35b830e49e48c067f54a9fec319b2f1e6ed9c992db73f0ee7535c31064b69e31c4cea5c84df49ecb12e869a170880fa0bc1aac2d09be2c8a8d0c9932c00bedd74ef0251a302d3069d8acb946a6bba0557b5fe496d0a08b7f651cedee44d0afb4d9ee66060366561af051f15c40b867f3d2a7036b4772dd6ede44c859eedd482327ce511a3a3cdb1ce7630a4767ef086608e5ae9fd1f59e3a1b98ac85e048d8328b30b171a5cb0e871cbd84d9bc7aef90f744648e4f69af9d4b66d2405eb80a93c519b8bb0df64b3c0a00cdc0075ab6d853b716c5398384bc18346dc6c953d847c6bf3e9bc964bd88fe93d85956bd606517b86b7b329d94b4119503435297588e3fb85bcd9d32dcf4c9424de1160207cbe2b702ccfd562f63303850ab4b3db82bc58130e74434dcd9be2cc03fefbf3ad2d8be60e4d12920f51960b0a89bd6a2ae84d05d518c5e3b7b849ed2dafeb1bbc1bd6d2dc4630ad91bf4a5de86abe065df05259f84392744c32a3706104266fe3769cb3834567374ea7f2a1eae69b7bd0191da6f9dcb6a3d7a5c484170895a08e0ecf9aae702d9de7e1b5be608cd13814035747830c399da985a4891d9352442adaea85a18f9169492a188fbacf4412ebd42983ed15a29f5faf4a064069dc01465bd4f280c4cb3b405c69f9b06ed5d9d9724834693a0edc5b0ca21eeb9159c0fd62df5f059a0ad1a7479e3fafe7e0e7869c433bfd86a1def995424e0ad2ed49d26e2f2d708ce188b37b5e45a061a036916427dbe049f76567a6f8311ade3a24ac22c8cd383bd42063bdd6294cdcb778e1ebd04a76eacbddffc055d99ea7494d9d5f627ec80139ca6e5711fcc6b6e058c75ff0543ddf1b61e67b7605c9380b863f9503617794e62d3113adbb9891ee62677daad8660599ec3515d56311bde359466539800d8b996e973a3016457ac853c321a15b4a6495181c0c3e33d4e821f4e4669895032105e1be850f6421dcb4e1b7ca7252766ab065f3826bf8125f8c33cf4bb98d356d676d8c9175d511104bf530c9694f66884abab8837dc9bf0227c6947228e5382f952949ae740b141729db80e3c4dd295116b4fc3846eba8cb175ed9bb7dd4d3d9b9774ef2506b7c82606355aeb10858064f9c4a14c77521dad4ed859fc6de3f1db39b6bd782abdf1256712409ce725ba100391be253201524b2bd356ad612fa7f2de849cda61a3f1803651532d6d94622e799c75cab6d4ee6d35460b6fe7a3fca8ca093c251920654d56affac8d5accfa088a51b78dc86787c3746dffd5a534696dbf9d8bf54301e96f327abefb64d8e89bd76fedaa79336dbcda32a92cb7f61223f24aa4100d7c6f691ac0413c3918593727853a8ee1889623c8b2a870ec7bb23b96acee13c09759eee5aafce08301b3c3bedd39acba4c9adf9694f28032645f4fcdc77c18a1453fa59434d6ac3e324621f75e887800754c05278c4ddf006d1b016aa41b190d88d27bc81e89826ac27915a3fab1d8150de480a47ce78abda03ce32eeed41df3f6702d38a9c397f7d505a59e080a69fbb64d6e01c7f329f884da990092115b6a0782c7a404df7f714b847e047ff80f3f697e5c461bd8f0703b6d89c6b36e7a67a5155bb089656f0837c0d061b62e20746560260dfe5893ea69100f98721cd7378cc1d29630e241c08fa71435ebd9fe18776f0d0936d5e428ef9b2cc18da55260b83f9080df550e37b9cb2db7d34c6e6ea60bc33e5874074e208b02fac50ad1a138eccd36d1d604bc53e7633c370165d7bea099fcbe31a724ca518e1c89083801e6d8bbd36166a2d69c85726030eb898bd7231fb8e1b231f34b32f427cc4419dd8d2cc41da2fa827601ff34a17927cb25fb3d9cb1433c0c7a6958da843d74272619c91a7369854512502b453c146faa779c6212175cb6e45f196cdfb224e718addc0e2f5f2f9bba62eeb44985b6048114c7e2a8cb5c36f39e34cfbb96bc2fee1cb176fc9d3f12bee04e5351098b256aa217129206154cb73274754ad442a0fb98c497f6986cb0fdbd7822289acb2dc54393158f3c718e866e7d4f59b33ebd6073f1b94dd8ee5413dbdf0353ac35898a66e0deda877474654d9fc7a03291199395f38b84119ebe58ae0ec467b5a3485d34ba54e71a597b2f7f793c5a9df04f36d53ee5fa3c88c912aaa668f383b18dd04ad88e17892831de2e5011bcc4780e320273be92be1231ab53108368e24818671f618e905ac5e6a8af2b5dcd1a7b4d0f9f3c07a7fe6566c61deea03bf970ed385584fae037bf764dfc1cb728596e08aea92c4c4424679f2fe6102ad90f9d947710939c79eb0fb022d5da98018bc6419c5c3477374050b1fe0d07013d3e9cc584ad52712a21f989dcddf42bcf36b2d380cdfbda1acb56f41682391e9ac9e425b430896ea37f62285f0ca5f3785078dd62c37ba082e2c0d9c65a6950552e24f3a22164c4b0691ace5779c9c010faeee44989ff4c240b4c592b3e43742988708c8be22c5acd6db6f17baf8d78fa51053ef02763b6263949addfd9d5c98cd34c044dab81bd6a0216a93edd9819be6e9b23903d657e9675f2af8fb06cd7919c7eae81da7699b93c0e8d061610f5e99196f0b2e0eb0884e337567150ccf2627e5c1b9a11007451c0eea7f181b1de540cb8b0a4f83edc73244131433daf323bcd13e9016571e88ae5691a41b0eb2d9a85827730a61f6bf5b82a9b076a7976224b8492a46c2f15775597c80cf683e868bc444ea2764c8a04f49747be18e1cc0a59a61dcafa9684ae4eba675a7cd05a30b0e082b948020a95c5dca1b8d5bae0c4200307e02868b8a18c78715aed4b9f9f406c7e76de396e00f495d72d7a07cd5215d5f049c63e2c4762f462b62b3902e1319ae1911c3af54591692203b205e1440389a5870360d89513bd2f30e327db37e39724dc58b272ce54a46a25b9416f2756b512a8a8f4bfc88d18bb8910716cb6ad9f31522e73a0e53079760f9bd9b6503baf2f5abe365811c52d2b16646bd445f9f1200c8c84cfa6e532206bcf49c6b9508274e591dfb21684bb938c37b108e75251c7e3643e17b14e363687cc79e071bead8237b6823f29ab9e790770d113e65923340d23e3350ae8566879fe13198e7ccec8df44cd7720520eff7c80288770050e626b62b7beb35a1887ed9342ac91779868e969a2c854623c49bdfed5445472eb5dcafedee0443448cfd4fc06f92b4707cefeea89c3236f0fb34d7e37f0fa9322ee69ecfaf3f2538cc7e9788da400f34b0ae2a49dfd5aac92500565e2047835741d1689b2e455a80dec28da7b392070b4d97ac3627bda37fd8fe9296c391471e4d12b969e4920152db5ab358dd962b990474ee2d07b320ec2fc1c44648ba11fd876d7d211eeee361a679306c0a05ea45a7ae5710380b6b1a03a3c8c4786215cf5e6986c13dfbd16b0f7947a101ac0d420e1434e882b204e03c9d3081e296da60cbeec90a3522db9adc610ff8969a6b8c6381c3d4543bfd88a2f69d6008862ef0a16fcdfdacde40606d0a360bcf0a830a9535c2aa1aa9ac116a6d8d505d65aead11eaaab674bd52e58ab946868e71c1ab8bb59a597393d875f12c9b97851999496f4c15288a761c5fde18a8836344f80f0299574c1b4fcc18ffabac4ee35a3d31653c314afc49c72166f54f9142686a76012d8400caa2f5eac2ed1b79476d824634a0ffea929ae1bc000b33b6e004c142081636aea8e18a17aaac6e1c31ae66715e219b978a0ba699947b4a9295374bbb66a93b691b93b88a0fec8c3685d014194ca1f3df93628b14384f0adc5f5dd73cf5c5b30ca04126c792286cf811459020393c2d382049cec0e2468edf83c100f76070e11e0ce63d18c47b3048b907c309f76060dd8381837b30dcb8b72505f7b678e0de1632f7b658e0de961eee6dd1f27f031d1af8e8400b02ee69d9e269d974879cd32e6e4ebb8071da65cc69172a4ebb2871dae5885359cf69972ea75d6438ed5275da25e7e9f8c80efc23b3f84736f18f64c047d6f08fd4f28fdcffc8da3f12ea1f99f48f54f28f6cfd2383fc237790cfd163c78e0cdafccb608c7f197cf12f8331a76f7efe6550458fcf6be29f37817f9e977fde0eff3c037cde0bff3cdd3f4f85cf9372fa8606aa23e6548789531d089cea0871aa6380539daa531d2aa73aaf539d104e75749cda50c1a98d31a736c09cda98c0a98d1e4e6d7039b5d1c2a90d7d6a633cb581c2a90d28a7368a4e6d0c9dda18726ae3c769ce9bd39c139ce6a439cdc1e234e702a739459ce6ecf0c1073e40be9e9e2c63de938589f76481c07bb208f19e2c2fbc274b95f76489f29e2c48efc9c27a4f161eef798104ef79e18af7bc80c47b5e90e13d2f6479cf0bfa3d2fd4def302d37b5e107acf0b1bbce7851bef71418df7b8c0860aa938826010667c4f18da7bc2c4de13e6c97bc230794f98a0f78421f29e3042de13866ec0c29a7b2c8cb9c7c212a73700717ac30da737b0707a03eef406dae90d51a737309dde70747ac3929e1f3d5444bc876a87f75021e03d5402780fd57e0fd5cd9b6ae2ded4977b5345fc03d2c13f2038fefd38e3df0f11fcfbe1817f3fb4f8f7038a7f3f2af0ef8711ff7ee0f07f3f806c16ee6ddbbd0dbbb79ddcdbadff1904f97830fde351c23f1ef51f8f20ff78e0f8bfa3c17703c73f1e34fef17c3c1df8c7c3c53f1e32ff79fce0797382d337659cbe01017dc3c5e91b32a76faa387d7381d33710387dc380d3375e4edfe870fa8686ff3f3ea92affa49afe4925fd9352f24fcae79f1408ffa47afc93d2f92763816c8dec03ff641cf827a3e29fcc02ff640ff827f3f24f86807f322cff64b97f322bff644eff6449378050376e4edd983975738153373b9cbad972ea2600a76e68a76ea49cba513a754374ea66c8a99b9dd336679cb6f9c0699b31a76da0386d2381d336429cb639c0699b2ca76d6ea76da89cb68172da86e8b4cdd0691b22a76d32386d83c1291b179cb221e3948d17a76cac386593815336113865b300103e1012a4c70e1c6c8edc63b3bac726c83d363ceeb1c1b9674609ee9991e69e1954dc3343897b661c71cf8c02fcdff1c3fbe1e11fee611bee6118ee612cf730790fd7ee612af730d43d6c740f07ddc344eee10dee611ff7706feee150700f57c67f1c3a7afca06c70a76cec291ba953364da76c904ed99470caa6c8299b11c63f97bb77c5b8773970ef4a71ef2a71ef227183b87769b877a9eedd7befcaeedda37b17c9bd2bc27f1e94cb16a75c3070ca6502a75c1ac06587532e0638e592e5944b3ee5624fb9449d72593ae55274ca05c92997d62917114eb9f478c00303fa44ecf409274f0c9d3eb13a7d42c8e9133d4e9d58833a81825327baf8cf63c7f7e4867f4f62f8f784eadf93f1df13a97f4f96fe3d51f2ef4908ff9ef4f8f7e41a7c6570705a06ce2919233825e30b32c29c92b1c42919469c9271c3291953a7644c392563e9948c124ec900e1940c1ca76b5a70ba66cde91a34a76b3470ba868ad3354c9cae81c0e99a1b4ed7ec7cf4f000c80d0e680c2c388d0104a73174711ac314a7316020c84745ca3d2a4df7a8bcee5109ba47c5837b5478dca372e3de1435ee4d49c1bd2923b837058c7b53ba9822e6de142aee4db1c0bd2945dc9bb2c3ff1c1e0f8f1d1a129d8643a72191d310c869f8d399094e67649ccebc389d9d399d39713a3be274e6c3e9ec00a7b3164e67f674f6743a3b3a9d29399dfd9cce38389de53855e105a72ab83955418c5315b8385561cca90a52e4e8e1018407511aff884af08f088c7f4463fe1159f18fc8897f444afc237ac03fa223fe112de01f110eff8868f847b4e51fd1ee1f11f98fe8f68fe8ca3fa2d83fa227ff884af84704f48f88847f4444fe11f9f847f47f4d4ef0af899a7f4d3af0af49997f4dc2fc6bc2c4bf264900b981c18d1f9e0f1c54b6742a333a952539957d702ae3d1600d12f7d6f8706f8d0cf7d660b9b7a6bcb7c6766fcd94ff3d74782880700f057a0f051ff750b8714f4a1aff73e088c2e45e9410ee45d1712f8ace3d2816dc832ac13da8306ea809c13d355cdc5333e69e1a2beea971e29e1a0bdc5313817b6a8eb8a706887b6a74b8a7c600f7d460b9a746df537371f0f8a04ae44e95b872aac4d3a91244a74a203955e2e754890c4e95b071fae58cd32f659c7ee1e2f44b16a75fa838fd6281d32f0f38fd32c4e9171f4ebfd870fa2586d32f594ebf94a75f6aa75fa89c7e713afd72c2e91724a75f5aa75f40f8cfa347c78d2f090eff9218e05f122cff9294ff92dcfe2551e15f12a97f4996fe2539e15f1225ff9214f99724c8bf2418fc4bf27f485ef00fc919ff90b4f987448c7f48bcf887a48c0f1d3d6e7c8174ef0b13ee7d0174ef0b11ee7db1c1bd2f80dcfb22c7bd2f72705028644ea12c710ac5cb299419fed32065cedc2b23c5bd3215b857c6887b656eb857e6bc57a6cabd324d403c0e9812708fc900f798c87b4cb17b4c483cef8022219e2251e51489a853248a4e9140728ac4ea140921d40bdaa91750a75e189d7ac13af522c8a917189ca679739a0605a769c6384dd381d334634ed340719ae602a769bc9ca6c1e1344d0ca76976a76956384d23e5348dd3699aa3d33443a769889ca6d1e034cd8e53342f384563c6291a304ed1803945a3c4299a1d4ed16c3945c3c2299af2148ded14cd945334b05334ae5334ac5334209ca2f94ed1f09c76d182d32eca38ed028c9e0d7af0c880070dc201060702a48726ded34311efe98186f7f4b0df638603ef3103e63d669c788f1925de63c688f79801e23d666c788f9918de6306cb7bccecf798b1bdc7cc95f798797a8f99d77bcc08f1c8e1e4857b4ece7b4eacdc73b274cf89917b4e82dc7382c1bda235ee15b9b95724c6bda233f78aa8b857a4c4bd2207dc2bdae15e11977b4555f78a7651aee876afa876afc8cabd22a87b4500c84177e0f0a19383c8ac872b081213dc8cc10d4d6561020ca840557d79fac1858320ff0f04061d61fcbf11056c80c73d220eee11e9b8d7448d7b4ddcdc6b12827b4dccdc6b32c5bd2615b8d784013dbe238ba7f68ef822e8887704161d2e34d840430d08a0a1062e3570a961861ab8c87080196890610603c8c0458602c8c06506196280610b010620002d59b464d192258b962c5ab20c41c47fcbdda6baa427841505785ed290f7051d17bc58cf4beb7fe865c76b10260883b86289ff671048ec108641b410c4f8b7aaebd7c152420b2b1d16aae4f8e17f796f013f6813dc8d48d5fe3abb5fa7ead7a162ad409cbee2986b574a28b4a48e5043d3b4dbea7459b4424b621e10278040ec00498ca97e30f3c38e555b559a884d2a9be78399833e44c0072e58e70312f601841ed0705533db80ae597a3d30c0f680eba1c9ec41484e120f1de0210a1e2cf03fe75d5b7a1c6d8d879c2d8ec3b6dadba169071cb58b992e3898b8bdafe9758122aa15146bb6daba0401ba66a9031895025d7420428704e850e52aaad5a5c3930e4b6aabea002487315ad549cbcbc106b0958393cb85430e1e0ed7255e9b4c490163407d496c425559273064ad5cae5f3abd52b2aac6ab7abfe58acf159e6acdbb84789f40618a3fe7eed828ad8ecaca09bf0e921d0caaa451858c2a5e54c1429bb9b6742ec95a455ac5ca4f95c9ea8213570bd5158695c449529862b024a524a42a07c1a0aaf1ce53f696a57ded40a960d09a77891ba6607150bc34a8294b53904cd159410a65d014c8b02a89eb08a335af2b859d42134de1033b9675891b4a1d46018b4cc446b52b451f494143ef6e4e8a987f7773456a28325d28e1cd593d2373b8ef8dc434bccb9babb6ac7dae26f1edd2448c33f5d530bdbb50326c77a18822d32bc368ac033b9b20d0cedcfad6485b7772fc3b3b37fe1d9e7f67e7179bfb3b3a97465113a5cc8f9070da2e45d15170a75188fe5328332eedeadd6285ac55b8da1955d0688a5252929178f5befa383d502850228522048a8e9f02a0c87b5891056502a3eefca482acd92af7c485cb5574b535aada56974bd684a84965e54cc1f4e3a04866da92174b4b9c20e57f2d22aad575239700a3286709006f9977d6e4f409185b13d50cab2efa0402d5f524c9130e9ee0f8af73aa1402252c4ec8bb56d7717ea52627484a43f4d998c417d7d200d16002a34930fc55ef6e2edcd1603819d8b1d10516a132d4550692917f4850123d0a013d1a8facfc4f50570aff4ece0eceab6ae7b4dd46f48e36cbd5700ea733ed9ae4994991ccb4a0a1a12354364a64aaba2279c5b5ad9856482b362b342b56ac10b1d2aae2c2710cc101f2e8a04ea0f835256a821265306bf2adef94dedd1975e108e1d4842d6ea38723316c18a12313e39fcd4ce861c28e7f08216e630174c90a269ec26679c5ddcdd18e234509553325657e902ae9a2a4004a9e58ab3ada73aab256604df22509016892f2206bc55add48b2c2c9419148b161a748707f5113194e11392cfcc7d109c169678c76ea1c3249489d1e39811e61d12341fe0fa93114c6ababb6aaab822d9e9c212270046b93c6d1f766cbd25e9ceb38b4ffe469501a3408061ab4020d4a811a496304cc5f5d366ee4f0e0f0f0ec00c9b1a183c3c6ce07e48a7aef0a1ef7c2a8712f8c9a7b61cedc0b53c5bd305fee8501e25e9803dc0b33c3bd3058ee8509c0bd30f75e182bf7c2c8ee8579dd0bc3e45e989f7b61e8bd303dee85c9b967051af7ac50c17f10e80e0e203c56e0dc0383827b60d88051730f0c1a301bb807a68a7b6096b8078601f7c0f0700f0c0d3b9480e0032dffdfe291f3e3c7c17990137844e0c6ec8c9d333d44415a7ea431c509529c5049d141981db4ecd860866a248a2c126881841b1d681981880952a0e1818667c7c7104e2ce9800a172c41916809e40aa8257428e025051228580861a1de9382e75e1429b8174518f7a248732f8a32f7a200732f8a0bdc8bc201f7a210e25e143ffcf7e14531742f8a9e7b51e0dc83c204f7a010c13d28bcb80705997b5060e01e1413b8078510f7a0f0e13fcf0f0df447086b0cca62c0eee658fbd5455938bef2b242e283c6abcb078c8f0daf2e1f117e12a4380929cc4630c1081538961190e808f4af2e11c0f88c8a90c45f5d54842dc209d54545d831dbf706a6ba42c0525d48d515c28eea22b2c55f5d3ea7448a7875edea42aa2e4a8456171d52c638dada90248660f9ab4b85d321f4ca6985c0ff8a04c2163f0561a4200455171a7f7549f15717fd6086bfba3e905517fde0c70c00a71e3cf157970750a742c2f82f864075193915b25f5d54c89299109deaea404c7569da41f89f76d0aa2eca81149a72304375510e44a01b98413758e2afae1c3de80650348819bfcea42befb334aae9a441d305175b706003674eda158d6830010d8ca01a78a966cafc3aab32394c3483235f699109d479eb125f7ba9c2b0d49db4baefad956315bcdabc782cc330ac4c58452a13d3e95ea5d1fed4227555896a89f76c64c22af15ed5465b9b11ed3b1a31525b5b9f661886156cb14abc6b262bd06e34ed8875a70914563297ba5cb33a0c439d899478d7d19edbc45344eadda7b661c55120608c59acf0eb18f1bf76a7aade5d285adf5a55d24622b19378c79ca1a444729f4f22b6d4470c4f02c7538775968d106442c6a6256f4d575b71b533564121579050b565a1abcd4c555b24b6b820a15d83842a78036995aa6a1b8e53596b1c92b7cc61252dded604ca1b488b7797b99a78631163d3da6ad6e368cd3b95443b75cbeaf2cce6930a42a9b6bacf6c6fcdc4154c527ac5762b0c6b51996f262d8f1a6b4b45abba8e3913b93a7bc3394dc4c467992da87d42a030acda47efd0691c6db84ff19565e28ded0ccb30f189eed4e1287da7ecd2ce307d33d2ce30d21e6927f2964fe6937973350c6567d8ceb09d61398da3b2d18e7c5559a73167a82cd3463447643acdf9f19fb5a23858dc31ef71a4385bee72c9284e93ef48fbbfe9f465b85cd9bc54f678da3c03afcb1573b9644584f4427e6d6672ccb97a6fd2fc419588a8b24858bd89c0ff9c3314ed8ced1b2b7386ddf148df314791fa5e53698d24feb20a2bd6d0b2c6d2be3a6b5aa83570fc6aa4a17737a7c605d480801a3ea8a100356250a385ff699ce064b6461b43c16252a09456376315c99ab85c5147f5a712d5b0823730a982d5a9b6405b5adee44e87b746e659987b8a12efed6669376a6bdc04def06e8d9bc2baed98cb96d6b88650c1dabeb52534d40a12aa66ae4122aee49523b535545b4255c2aa972019028576635550d0d090c6539976cd53bcb51a2251526f96b6cf92b5daf7e672e99b350af51d4b9d256d4ddf2c0d48e7c29025548b54591dc89afdd42bab4a4454af08d5223557256ce98b4d735f5dbeb76a37998f6a0815dc8d996aefc8dc22b3de29d1429db6b62aa9865041f26669e6bd65dde725efb665d70c08ebae9e51655b4bbcb8927ae38bdb5b8bb89226264f267d666cdaa9abab1eb1ddfa6669374babb99acd9178ac30128b997c55a84d5e9d88b31426f296519b344fa328f17a273041f2561bae9a344f23f09ab6d450a016c9290c05be6af5a9a48dd5f6dd55bb336c6798ceb6ab81aac8042526dac0228b2cfe0fa958b054f156a2a28a054b65ad3406ef356d5e0982ec461278410233ff7d7c7c7c2a14332b95522e17097e1c149a9ae53d0b9aaa51b319a8c77134710de7125b4cab3993565b275b1671f509c7d11ed970dd91f96a7d8a585f73679d2aa87d70359b544171cc7ab3a0aa5e5570df5c4d9c92aa64921e470b25922493a8f114ae4647e215b185122fd3be37f134027577a465b334cf5cab601856709f7967a170a6da1976a7b0269976166a97a79923add1be537686e52cbbdb36e5dcb4a44d7056b46448e86ce2728941458c251f42e2aa6d8da4caa20e993143427890dbee85c0865f9ba3ade5231e50c30d6198400868b4170b31bf8e165884a1a28a29c24c91c5af8345155468a00a30585c41c515617e1d2bc05441c575a6b828be44f19a27d4aeca0341e88160c91225214edba5b0b6940895bbbdaaa2ad377267c72b025d1dde5055d689b5027336d4274e56c3b10459bb9b5bd596a8cbaa6c96b6f1c6324cbc23cd92523bcf66b39978c59b33ad0e0ad585c53c2f745e24a57103b524492c06625bceea6ea9c7da15eb6e13515a92446b22353b9675499258ac8a775bd0878604de5c9eaa91e7d2aaba340922c6853adbc89dc96ac395b5aa578f56a982e1d091330ccf7b9ab21a86ba66b26e32ac21abea8a2453b8356edf11a8ea5bc3e5ab892d5b56ddd156d53a8d24b665a07de69aabb2111089a564281b892dadb62a588661acb2ecb6a5d5ad6a05f52dab1e2d0b4462aaa494f81af111129961bb96654c59a6c57b61576761b55bc6784600c59278035099e0ac364f7c04191b0820003224194b860a9928649a90719131a1cc01b5d49d62a8c7aab16e0c5dae300cab0d8bb7b6ce5b2373cdda9cadad6bda343e61a4142c238de3a9245a23bbb4336c0747c7e9fff9245e1d96914f24be61f329db4826316abc4b22f912af79c57c94245e3064adb05d61b4d7244f5add1627abe46dba9db4db4993ba36fbf3b333f9f3533352ad21541d366f5975a7ae68af0edb3c8657ee48ab124258b5cd59a70a56d28a599378b5dbd80c733937559095abd91dc2ea4a1d475ba55edcd61657cfbcdba6add16ead3c73b5dc049e345bcd7b25dc55492e575825d716682f0dbc15dced6eb565506cd5ca17aed5965f2436b1b97753f6e22a9e4a12730deb8d5443204f9d2ed7b60f0a15bc269548e28a59b06315efbee315b1cdd2ae59992a78a482151caa2028545de3986b96555b22ce3f3f354ce69dc9acfbf9a9f68ad9ea976dbc31517ceda060249396ba495a244f4c5ea45b3333c9e47494425286e91a2e63514a5177c43814c42bbb48623eba623ec2edf22269fb641c2dd555ca59b623ad5386899bc4f585348e2f00ecc6f1457561baf18ca2ba305a02b104577e701c5fa0cd6c8a92aa34bbad79ab64266575977154b7dcedbd2381742e6dad824735a604c5542f4e06b5332cc3601aa7ed52ce4f50b891fa25dead71d3ce30bbadf9242ac376aed90cf6c4148b4a923273b9608d086015efad9d51e603221003d4393f8800f77f8893172a82201c231a3046191fc7178e123a4814f008fc973acd028731c48f51f44b6624fdcae285b2bb50442c9e313524d8dd9c9d65f1cce2a9c1d8be31bbc91b2bb18c498fe30b4a773753186a8431268ca95f368ef64809d4d7665e28701c6d4d9758465e0ddeb04d97964a57bd54c1506462aae02b6a67589575b2db22256d123b9178675886218919b7af5369a962ba497737d3d6babb8b9a680d54e29cd6b98fe370f1672e40d8c2015bf400ea6c1d479cd3e7bde329e27ba7844021a0da9d225306253300f22c2d959e653102aa012d1a40f28ff019f10b801271c62911233825c203a7449c3925a28a532228704a4411a744e8704a8497179c7a19c1a9170f9c7a3973ea458a532f1638f572c4a9171e4ebde470ea0501a75e6238f5e2c2a997f3d44b79ea0577eae5caa917d9a91728a75e904ebd30f90f44074f0e5077457933edac469eb62b9854d7589e5b5f599933a9c449a8dab211764252415bae4d494ed59ee2d192d6dacc4a1743d99e48ab6fd608691ced110ab68ce923aded68a4afbe6286d99eb4d666568ad2175765d9b6c1f4986df7ee2c94dee4abb44e1ac9f6949574ae969bb4b6e3911eb23dddab445ed3f65495a964a575926272122aad93eda9c9cc4a5a1cf392edc9f66466a56c239974a7d64e4a844aeba45128cd5b9eb12be6a36b4289a494ed49d3ce98de5d28bbeac2b4d646312d32ed76d58599599be79169ef787477968224326d3c9631d1b4226977ecee3ce572ed2c6501460c408aa49fcc58e38ec42b6544e22a0b8624b64edae2aa99b7add526d376e92a1d6d9a1338dca7b60470ea048e2a2bd648316fb15ea726b268228a2628d0c4114dcc605e1f9fdad2425343424c10e03f4895c7f12a854a61d5a32ed4ae21212726a49820a24df03796a0b2440a4bb896008b806aeda187204c701e1b8947aabc13ed8dd264c637dddd4ce479bb46f74cbaa2758a8a32cd7c245e6dc10c0592d88ed7bc66be35ad6d1671359beb1ded6869a7ae761c6f4d639dae2c4d628b3b226f4edbbdaafa9af988ea9219f6626aca48597623314e24a5ce2771cc31d1bc534f1946dab1cc9919855d9ea629e22c25e3bb779ec25064c6376d82498c439c4cc08c09a019022ae7386e2660af4d232f1d96e1e4208128feebd90daf70cdca24a81631112f4e9fa5049afcd7340269d82b424123e0e3ff295657d3542e8d88f7a8c4b212cba82e8c3e803ee00a7d000fa671b4476089b72eb10cd425968125de37df405ccd82f79e77c4b6aa73cb485bdced5541bbad88f31969212be3a86a6b158a4ebac4b2aabb261479cba771c43ba6b433acc4b21c2154882cfeeb1ca1c508141821c6f7358204238218c1a388358ad8e26015af5941d9beb19c225a84907f2700ff71ec9407c7f1dc156088247e15fee3532176fc273a1d2285ffd9bc2cec46bd31adda304e97789778ef9a12f00850ed8ab90674475bd340b5d99873b993ff9c0c907f958867a269cf5bd2f904080b573282100e109c2146e4a911edd4a8e9d4c8756a544f8dbe53a39cd3d71aa72f159cbeda9cbec2387d6971fac2c0e9cb01a72f1e4e5f349cbeb29cbe56387d459dbe9c9cbe844e5fabd35708a7af0e4e5fdee92be7f484344e4f40c1e9096dfe7390818701cf0f647ea0c03f8e670e0f0e1a2dec00f9b1e343a7849d1e383b74feeb4e7df0a28de4acf1e1045b234f5b585d60f430e63aab1d1e1cd06941e74938f1e141e9bf78634eb24501e989292a096a96f4e415f5248bcd644d522fa52424972bbcb61dad567d33edb648e2ed92e4ff06a75d8430a94e391a25827f67878eb36ad501091d82d06187a87bb350494f5020697535d42e973ef36ee3db1d75f7ace23d5be25963d9327825b43d91b7a9ca3a8555ea8e365afdba379b7149e21b6b55b7b6328d91a2c43bd2461c25c3eecd42655802cc68f3ac619a001bfe5bd1dea55898002b234e5f5329012d175198805359d990053865c6f6d5fbc6c09d477d7536f7aaa0366f14ed8c1dd11aa030ed58abbaca3a81bade485c5bb65c771b57c12aa8abb24e15c4e62631996db4538b35acad519849d65813c91ba66d53e716c6af0a6e7daea0cbe0c69508edd444465b366f79e6a0458c0ae569b7efc6dbbca5999568e79dc24f60e2bd4a3a0bdb19964d33e98c42959beeb64862ce4f48aa4c42b923cd4a651bc9248e172b894ce6684acd00fb2fcea0430a899dc03034a92e8ca9da9ef6f944959bf66b67983593c42b5e16704c4a6cdf1814b3a63192383e89175b286b26511898bed8a20126b63460cb10386c11c096dd96710b0a5b983e9b55599d1449bbb91d69936c18eeb205449a5929672fd5cd42852e97ccbcb68b044e91676ed9706ded68f566049ad976ad99645e286d4d70d7aecd469571ba86bb3c4d9a9dcd6e24defa822128de300c71bbbce20ca816d510bc205305c3b0b6c2aa2b6adb35a15c616d9759a9823b90f553659dc255ad0a7fccacb4c9d3485871fa46e2b0da70156f6d553568af842e5758a546ee7425b1b6b47de6aaad2d75056d20ee86cd1c5ea94c663712df5995b0bab413107982acad7567cdc4b5ba33ad3577552dbca6356f76920531f99049d556927647134b7cb350d9c816c9b36a922ac35615dcfa66a1c2da295e09ab68f1de2c14697555b461080289b695455b3e6dfa96a3ca3aef6c0b2b12a1a9bb7d486d714c2253cd8d272d676b5205c32bd64c6a2dc9a092906653a29e6431a6a50a54ad995425ac2466dd29bcaf8455c02ba136335315f382d6bc383363aa8c6b59f3d64be62ada3655d0bc3a33db5caeb0ded2eaaac6ac15c85a997763972b1c4bddbe3ab76415b3b6dedddc2c34f1d5d6bc12da9dcf286195aa7d80c84c9656b7bbbbb185715ea1d4ac4bb32469a956b45dade66af94a1856a93bdafe91c5a49c7e4e1c91ca5a65b2b6c2a070df319b448854f18ea3bde4d6d746b5c2edb4bdf59a3ebbda95b21b69b896c9f28a986a1c31eec81a694dda327623f1ae4989e4cbf69465d6ccb06b66272d5e135b9c56c105154a12ebaa4290c6fa0a1ae59532579ab8b2c41fe701b2fa797c48f8794610e1e70981c8cf33a4fe3c207cf0f37820e4e7e980839f6783203f8f0619fc3c1ffd79bc9e9f07c88f9fc7478f9f87c78e9f4707063f4f0e1e1c396d756fdee4b4dd396d7524be5dda9520212e64b23e774cef764e5bd9983354cddaf0aca69be1c7ff217bc990d0696b1a3bddab24c3fd3f196efc8be105ff6238c1bf18caf8bf636b3cc26ed6e8ea6c8c64c253314cfdf74ee1260d8311ffd091b326a5a8688992264347a4766bc9d964eb7bc3221225e71573ade8db8281717c298d390a1f09490992828bc96a77eae5d540ba2cce40002e3e023c71f1a4d55ae67ae62909f808707fb3a3adca4e2c33150650817f080c0285a6928c9ea264b110e7380cc0d1267869d9dc3a083c0244e2d1bcba9d35d4f80620844b3b1b0291804140b73ccea672a13e2dd0ce0bfe1d17fc3b2d406387cc7ffd4f00271c9b00048747065a76987a7d5a5ab92f8b142c58c1193b59767654f0efa4000537d6f85e787d2efcf0b970001768a83b5aad0cb8e1561e002e391ca1c40fc57f21be1654c044a8023119d2f726de14be16b0fc63a18c8f05313c394384a2fe0b090121f90754e41fd0907f40f41f508e160a747c4536f0afc814ff8a50e05f1122fe15c9e15f912dff8aec7f456cff8aa4f0af88d1bf22ae7f4580fe1521f2af88907f457c14c1f1af888d7f3f6bfcfb7941063c7e56f0ef8704ff7e40f0efc7ccbf9f2cfefd58f1efa702ff7e82f8f763c3bf1f2dff7ec87f3f54fefd2cfdfb71fd0cfdfba9ff7e32f8f783c1bf1f9e7f3fffc742019a7f2c0efc6395f9c79ae21f2b897f2c2fff580af8c792e11f4b003b783c9d1fac0ffeb17cfc63f1fc5b9df16f45827fab31feadc8fc5b81f9b77ae2dfea01ff560bf8b7c2e1df0acbbf55eddf2af66f75f46fe5e4dfca847fab211f4030d840874a082a1b3ee456d6aa227d5329907926de286d8a6638cb3692a9b51bafc647152473254f13ac56675e1978454ce24c8ea3d5e5bdb99906592b91cc4635bc497bc3b7ba3579f511b8ab699f4b9e55fb9455b7b634aebd44d66ceb4b9b8d96cca55405595baf5c24936e67bb2d925229655ed134dafa7412c96cb4b35054b9294bc932299d993f5ffdd23da12be207af54a99fae04f3349d8e6ee46ba7d39d48fb6aaa580e0b2845df1ab6475419c6a46d53ce515a8fd649ef2e14b1eac286ee7846ed2e945d756149bbeac29cf4c54c3b8f319cb64b4655d6e98e25366599463269d19a49dadca4947849d28e7a3ca374dee7ebd6481c1b3a2295654eba2c92d60923555d1dd3178abc4d49e3f83a91866ca614a8524a9b9724cf286dcda45c4daa299674b1bee4ddb6c92957cb636c146fd585edaa0b336d9316b191933ed24866d6175f6d71505bcbb49995cc2b5e53bc349b2d8f391f814062c65609046b6bbca4999b40f1e26ae46947cb5a55f26e5bae54792909bc53e3de98265e91b4a4ad35ef7163d64a34732dd46536a1c20a54cd5c9984a14541b6b56d0a2b5075edabc322d5de7837e65deecc9a79411eb488615e6b719854411a79caaecdeadbba361b935550aa829ab5326f594a5d32e77d330ca7ed92d3ad51e5261bc944667c7396565d514f515149f588e9c95353ac84ff1dfc8b098942bb36c1a816fcd7f91775c61735c60762f1b76e2417024429c0ff0efc8b1202f10680498e1c39726020e2cae4de1893aa7babaecb55b4444926d5e48b124294544c8ac8b42492b8a66f94181525b5afce4d5b9f48e2a5ca2299f474c53548ee93561b72c97c7353d65691aaeb9278acbabc7736aa60de365ccd53eb443c75e61d53056319a9565bcbb392b7ccae9cc66625a97235cfbc13efacb6b27959c03f3f439ea292a854d86b4956a39ed424a32a8b49395590bc65ae15b4d76c8561b5da14b10eabbe365b36aa6138a58661585da8b5a8c86e8b545b2253abd5448771b1d23a11d56be65a6b0bb5d63be252976b990cc3b06e4c9e4b5bfe43f9b764c20ffaf8549788672d6dbbe6f7c402ffab91bd4837128be42dab92f0263326a5a82e4cc434522aeff3256223f153927de7528bd8a8ca3a8134eb441e813a57cb4d55d60914afce62d2d640ad3bc58cc9acc112cbccbbb314f2d6481cbb356b3ed117ef8b6b2d5b5b6258a9ee6e6bcc426232711eed0adb969871cbcc3620d3def1a882ac4bdb59a7552d02aa661150ada058621c6eb156e4152bc85a89a46de920a01c69cdb05e11a91e55703c5f150c5a899856b5cf995ff584da198694613bc3447b977686997767183612ed5d32229f7686fa4e097646a07980e01b22f82ffbe7c3459f4d30f1eacf05c3e792fa4c5823cd678299cf842c40f182bad0bc25064d5c5b6118aba03eda1936b5afd6770a3791e669a43192389e1905d11a65f352212f0bd9a4ca4dd6dc554957eb6c2a8d77297634da236ab4091ef1e03b4287d0181aa3da72dc7c433f5457fde26bbd3004fb75aa3ed6cf378481ce27e46503960b95b57281b5d542ad35e3a8563d9f8f0782d81cd45f50ee0b8205b9c0e37c4692f88c7819c067a4bc8809f01959721c1f7080c8a162e6bf9179b43b8010c0c04742183f6b95cb338d41179c9ace9cfd0139f9d561f36b1db9fbccbba919798a98469e22a6e16a67de5acfeece533a3ab800e22c04e0cabf11c07c240cf9c15a86d5c44c6273e3f08d0055c227c216da04af591ab9463e1170c0bf4e38d3b17fae04d2914036738a47086650994b4013c020201297d766ed35897616000415384ce088398363e623920592234336e37d493cda6cd9b5cf0c6433a7480c6433a394a2a4e0b45d528a923274c49aa6ada43d5513c6a91a2f4ed56ce0544d064ed530a17320366ee48c4085021b56d460c06d54816a0a01500aba40635b09e3bf50102bac81c3ffa12015ecbcfeff04200c9839ddc0d006e8e999354ecfa4e0f40c9bd333684ecf68717a068ad3335f4ecf2ce0f48c0ea7676a383d23c3e999164ecf509d9ed9e03a32f06e9c01727a26e7d48c9b5333223835e3c5a9190e9c9ac1e2d44c15ff3f0ce8182c4ec730713a6602a7638a381dc3c3e998049c8ee1723a46cbe998f1744cec748c93d331249c8ef1713a06e754cc19a762ba381513c5a998244ec500712ac6865331584ec584a762a29c8a799d8af93915434fc5ec38d5c205a75a94e0540b34a75a5871aac513a75a54e0548b244eb538e2548b214eb5f0e1540b049c6ac1e5ff063a2808427a78d044ed00b205035afca84e69e4d8e1861e3e00c4ca17667ade58f11f2978f3a34a890384346cd040054170418cd0c00d93097e5840512d6dd271a49419c0bfe3030ef760c9fe3c08f2a3f109e9428898fa0919e21332c30f0a1141d90d20be0e5610ea293b3db8c09c996d60191f0763000101f1f01fc70e31b18b0e3a69fe9d1c70b892cb9564b33d9146dae2a0c47baf528eb4513e21080685f5de485b7569db6a1f9d23ad59bb39d252e5481b75742371d425332c4b893712ef2c051cb1dde4addac4e6aeadd19236f0e6ddf8aae0b9cbd572ae5923aded786178df29668689f7ee2ce5ebb9e2076976db7265d156586b5c2b88d316f7aa7a67293ab3ef8795ef87079f0f379f0f3076a38f17a0422033acd547ef5a44d49d3a8c64aa5e25498680866ece8e4648a66a11503d3245e67a336c6b0b4532f56451747516267e3b5af86e144fdcd63bd3bc64ce9ab4da6a11d45787b7ad57c21dcdcc9aeae2295d8e17b754c158ad2089ab58f79d42267d3c5a8ea37d3c3822a26fa78c6f478b2ec0c8b497cec4363223817ab4533ad38e2f50bc963c476dc42ccf9bb354f54edd7193f68c52f799af0ecbc8acf50edfac0896ac550d435bbe599a696fd58ed866e6ab6da854f537ca9e746a44040000000000931000303820168bc582d180503c9f503f1400025f8a58b666489c89511843c81863080260000080800080c0100100c0ba7ee276ac3416fafbca5a4b7a2609323aebff5ddcc4b1cb4a0b447f2fd611356135d6350b7b4b176474d9ffa7d3fadb2d8ad06b63bd6573ba9a7f4ebfe3ff65203dfa7f79f240af8ddb5e26ce93d54cd464d09f69a5b5436f4159479d38f4d66d9a38bfd5a89a5880565373e217d1fef7f337319456db26eec86a26d46a6e23706254fccf5e9ccdc8e96f373ae8c9ad1730eb34ffb3ed8e75c30ca0fd9fd32ff97fadde841d5923c67f3b5dfd5f37e93efed53d82fe0fc7674c3b16718896258491d43cc7b68fa890ad1a5f38aec58f261b12462b0aa4f08a69b2c05144c9d5612c3a0af8124a2e5040261b5ab9774e9953e10b7f8d8162b9ed785894178bfa853059a1d54386cb8da4e59ae5fd6353e534416e74cf8386634dc5cbd7930e44428b31621ed814b616921539d45a5276959c4c6cc5ed26476895ddfbcaf2d3fd617b6fea9a1af0ade12fb24d43530e5b878ab9300bf887798125eabdb27bc5e85a66edd2a419f10300e4923786d8933c4effcbd011e7b7ce7d33b4a5e10ca987826a816d55f093a6146b0ec2608ba0afa0a83b0a698fe6b3c9012837e57c98b046f9d71370c7f5b440823c3de6d2cba4d598106ce29d6fca7af72b4a8a44c5f44d1f3ca1ae08679a0e4b9a9c166d270139c83bd41a4165879d1bef2f9e48b3cbc37f86493a34b56248176044738c1c845b455d93c11b251588886574849ec3737579e9f0480898732d9ec4e7eb3d5bc757cdc78c3e11ef9fa535e9feb6303289e4cd4d67d117fb6e175845b5dfa55c8fe113ecc7665e6c30c560118dedbbe884d745a5300a27840e415f886f63dda2a7f37e5a0e840c5d83a9e1c05fc108576165219d51ebf8f9c2d3dc87e2d4c2d334e66527f5071f11fb324464eb55de91b44cee3f35ef7f563fa1b5959a59ba22b54f27b42c2318cfa0cf3cfec9af582f09faddf6cedf82b5648313bd18b37e399f8ed789d358b7169efea8526f3bf7588801239a59206f7de3e4784c567f09c379fbdd21631ca324f21411fd920ffd1c3fa6baed45819babefa05e056e0765e04cf26bbd58cce730ff3e497e287bf535825533e5ad8e1ddd688d67e35e9146a358947e00fa3848f5ac9d2c767ac6cc959e1fbe9f63e2690e1913aa8b41fa5aa1953c9923d0dad3634686a906d82aaa2d3abdc7a11059407109d6fda7128d03633eaac721ea70c74794550510f5b77a05e4a0c76d833b1a065bf1303ac13d8145ee8e30c3c0ceef9f23e0213ebfb672400b4c9215633917555a9c60879ae0fd14119fb0f38ef4911b42c8e74cfa7f85e12bb6f9e14d163e7e14cc47bbe2a6cf748e5b09d1c415d2f38adf7c8d035a7e7d4eeafd0564d8300294e21d75b4afbbaca56719fd36acdf21fda741c62873f46f39dc7e6eb7cc2f3d9c4779909de165787ab677c5a4f34ff36527df3e6ca3952d2f989f9762d0f947a7b2f911ac77cd06a636dfa5f9f7332c4fad0e3174adfc1861fa0b4bbfedcc0e2e551688ed416567dfd7ee6fbdd370b8c9c2c7d9b52bc5cd7fb27f8eb2e701f290099b8abe6f2fc0a1b005675a05f74c55d9ffad13963d5648cbcf92efe121c4cd4b432c2c13fe7e568c6654fc4fad2f0146d65eec262403e26aa81c270b511fd94208824a728020747a3147a43b703f234174c0f9fefb026e596aebd677a247e3aeea85bce64aa2bf95da0f5781d01d42bbca07427c1ffa01aefde87f61d2854f79596a3263e46c8fa431f9af845bb077bab7c3b41b14876be6ffff8c5f31b4f4485360d8b5099bad1a587ebeca3dfb304be40d8cdc3f87521a2f133218ebc2f2959c3b17204387d1f990102db11828f180ebccf6ccdbae54e98a9e11dfd906a20f0a4f953e3013f38053fa3472dde0bde6c43d71a04bee02c8563ecc39cf6fd36c41c4ac23a7fa4cb70ba29f6bcf3aff50c81b06becc78e1949e6ea9bfe1de393fb5aeddc372adc8d6fd6f8731551b70fde9afd52735e88218b78b950370cefa7d297ce5164e3839e695cb67720c00f9e71ede61380c638c206862db90a1ddaf351fbe35e41df198a1cd45e2766a91003fc5a4474e7414c2ffab2e1964103515dcea385a5f42e5fb109e060f5f5beae41548ebcde3381e1b6dc215c4b7bcc0c773677ef69158bd2d207ef15309a0355cd29cf3c39ab89047ea4a2273dd9ebb5986dfa9e637d6fe5a765d1c0cb2ebda506278a9e903b354d1ff4cc3c8857a33c4d8236840e6cd85b335f7a534311f815eca97b35e65d1bfec280e927d9cd3015e6460cfe51e6ac0730da33b58e08adc9675e7167a8065acc68fbbf57b6dc6b11a0b74d6cd9d39bd54306a0ddfda4ac6760c89be9f4fa7c4cdc8381ccd856b062bc28eb1509897289c5fcd17fd0ad1cb8ee5529ce5e250d0cffd747ea02bfb00dcf79eedf1b30e5c7186530b57aa8809bd18fb0b9529a02a9ba73d2b3a55dc0eb111c71c61bc0c14b704bc642d1f86e02371d193303eecbacc223ce449b7b194a321bf4d9fc56c1cf27194dfee95dba956f1fa1843013caba56936f64968a7c8ccfea1a60ed70135ffcf0b04bacc081ee7ebd1b4ff536577d5abdcb2e876872400c513762071316318b8caa7a9ebb0149e0d66c5b9bda2d8d9d6fe8f3e1a2c5d905ff90996e10e2cc27ec35c7a75a6012b0974dea37f40f264531e41126f4ac296ae08b2d07b9b9aa0101a1d5450feaec1f4b680bf19edc5ce3c1421d2ebc1c992e289531f9900ec7d7f0b86a9c0ebc167b718092ec67edc978775c84a192ca19f5c18ea2d2c9497506f7a2581bf9267fed98219c36ce7cae582d0fca4f5b833d7c3aff6a90c889ed2e3f63c10a541139926ac02038db42c787ac25b84c3101456ad2543c4c96b29bc62702fa88b45a14271b136e015ad1a9bf850e94c1474964c7ad3998cc1d18ea1f52d79a6b5aa014fd76b502e232f359056a7580d7022984adb4a82749ea2a036bef12b79ad6f219f74a04bf3d829bc24c1de1ad707aa0ab1d3c06b0c4aefad65e57efa1eb9637b94b5664d77d5eddcc0652c8211c40aa9e18e9d7d3103107d106cd511d34723f27160127d8952ce33705c0ca751ee762229496ec84149ff4dbcf36a9f74bc8f85c7159729b419a215770f595b2bdf74c6f41264242d8b6f884767daa4432dacc0695eaee3ab26b9b5cc75139523f2ad717d2f7cd2c5e5d101a5562b96819639a957c3942c06fe04514fced43a3b59498ea93a12c618bc1c0d888e6244edd963a61b3a93d6a22466e5777a693a1d50af961521eafd9fd935da8fd882adff8d512e5be88106902560217758699212d5fa074f87f6152c9dc0dfacb5b05a4ffd63070bfdb2562009b852afb4a392894536f85e09f465ac7c05a2742c08a4d88c24da8313e644e80b87fc567e7101426409c251cb76592e87e84faaf626218f24bc497d42dd1a00be24a90904eb1268a9c294b89f1aa1a320d46810c0231be805b9844da12d8bad0fc606421905b62f0ef588e45439f7900d566bd73f6bec57679e68e1fbe58f700de2baa028df9b827b829a01e7d96d4f80e42a1023909d5069ca77aa36c574817c01465dac4c342dfa24ca76fbe7867a190b3fadea99287c9968d31ea4c2d12d71bd0f47ce1b4b7c35e9482fcce2898bf178a998b084520c27225a4a14574cefc1825c55fec9e093801d87651e378ae05d13adda8b9faca6e5147ff5f2db69e5a2636be57f3e4dc81895d4ad7203f41672582fb218192936cf4593be6e7097652362a5ea44b2b49b4c0b36479ee61e85a6fa084fd01115a8152525546624510a0f1b017e19380152abac860e4859c7619602dbf2b8b2646a02eb71c3c4913383058e4298177801f58009912b5cecf03c5357869eecedca16abb8da7857d89e866b4e28b2d11415f42231c7e53f53f7caad37dca4745adb639eb53a746ffa36447bbc1ff58d52e2cdb445e85cf1cae9b272b8c8dd9bda1f277e53541ac5fac06be7a9d1ac8687897e91695a813021c9365cb9d48d9226c3cb08b0a5ecaa69dfd3fbe91487cb003c93183155d8336274151507636986c08ec103f2b54c055301723b11268e402ec25c342732e89e37bf8d026d765cb9d2404ef34ee2c06a3684d863e8d8d198fb17dce8ffc9fcf50c6f2637834662644154a1c84ca10170c32d2c7fbefeb881ff34e89aa4e789b6a0be20ecb54ef4cacc8c5df8414a3b69e2551a68ebf6d635b1ff30f9976f6923371407f069f96102ff4515144e9481f9e6288e12b5922224f8c2a472d12ea1635b11638ecd92d726b7f8566436ff1939428aef7732bbce7124647c82b880ba98423f959113fbe680e74ce7f58830ff9698dba9807e2f966578728fca8d756848a79c31b10388d135908a26940a8c753b7af6611c40204b42d5525d876c5b4d31e55a3dad8c5fa9ff9311e73094162c8b1365deef6820edb4db371d08ecc7707d916e3cda9eab3090064ca3cf9b45b2db85e8f4bd3211ac4296370ed102b0311ca92928455c41da4ddd003b03c8321d1cbd50098a744153db4411727260b19fde46e4616eec81bb64fdfb0bbc3969b98148276df1df60be4147802695e6962c1839f6430c9606a5e4c0fa9fe7a05ee9200a3fe595770825e712101788fd544c04f22a1565a3170a291621b0b0657d01f5cb5d54f4e018efb640c52c5dd917867081b165b0e572ae177b18aa6cbd973ce66e8eb841f0084216ef80ff3b5f5aeef5dd39df38f46098bb8375dd5ed2364d97a975ba78c6407f1d8801a9dca7f9fe46d1ada458b1a96be5ca0730b5c78cd43173459581f43c405b550e9c3a234091017153cf640646b9df788fe0112142c5c0b26d94300ab6f8e5da88f71670802f201683d1b2c18a5bbd15acb0710fd541334e7f73c2fc5f2cf5b9a3521fec184ec54468b90fe5fc2c9bc4ae772f9196caf689da9bf60512b5923a9d0975ca9d60c84a14eaf9f9189ef3c44361ae24706c38013253c26fe1c392ec9fba6dfda93de5a2be615b653afe590585da1420fd1684c56f2e18043b0b8af39e5eafe119551701acfb8d311fdb1b0e37c443fb295e00e83fb2474db5b4d12ba1d6c6d5b57b86d0405004e8b036ca7a334ab8f2ec145bddbc573647b963d31f0a4a0f420a11fe707895c510444a1108340b413727bc47635837524f1e4f2f849c1859fd2d7a80d4b0d627db81f516a4c1782739707b61fbba892cc770d9b97b12882dcfb6307a42757ca36e3b60a2f12025327cab55e9702231954a12152f03a89c53998c43d53a39e416a7c6b66b7f53c6cb5c76aac2a67f3c34dfb2e2e702d2c8cdeabdcc4c17015d6676f862e6a2697c675f2fd6b68a2aa5a41a57470c81388b265ee812225d51061095b757428cc4765c3a15095a3147b750f3e21590ab61a0745bc9d0d4094c6ae44eff9515a530c5e032336b8d36a19287951b4a4139dac38520e5efe2049a3b1629890712b0fdc8fdcd3a18f2bdd9851facc1631b9c0af0406007e004d4e0a98a74a2bf7bd03b2e82ed79123323cf5e4af7436bca10d8d5ad2c1fed6e3eee69dc12a5477a57bf2177ddf88f718a3f72a992abc6438657f486a99b920e6d791a3744a32352b540e5962a186be2065c811402b7cacd79ddffd7936251dee0aa0e67b5e1d54d2b679b10648cdf5ec6e90e71485cac941a6b5237f12bdcbefb6fcde03e646e8bbf35f6f9ba6cbc8ba50d1b781bf949ab7c5138bb9bf457ebf86a4f571aa9c460c5598a6c61509a58754bf406ef439f983922794d850720bde099234c00709529f54641a154896bf76ca2c9ecaaa53b943ee95c63e4273b675ff122d3fcaa978088e3549e3881d3b38f973b621d65c9b2a582b2b2327250ea59637c6f79c22950d7ff5b3e7c5d5a93ad63406809d884b6ecd1e44c91fec7935d79d060c498fe78101000ef84cf37e2a53bd387c694b84b166fd3c407b1563bfdb83a1746ec290ad95ae30082c1b7d611bac41260157e34aa2ce4dd4e81a2cac6434ae65811be54094d252e1429eecfe71af003b02931c08176fafc7fda5472c25b358e19c3b23c3129c078ab615e90dfee24c21bf24f81bfcde7d37370bee9d79f1d37b21f4794e7ef26a8cde336ec0c376de86cab2341eb4a726635af8fc1da8ecc7e9e447c04a51557e4d8388679813b4130302a8d6dc49d115ea82232ad8225e4331f16ed08ff1e41f2240e3b0115e8617eff524f2f930832b01f233e22bf2fbd567cec123c210633f076953cb1bb6671f7849c7e5070264654e6c41e74e572897fc2ffe1b4f6f98c41049733c49ee1127ab2735cb1780d6d42bc8f14f1856145044e966ab410f02229c08c88141ed9b8253984b071df0f39de2881969d6f95abc548fb2c8c93871d18930963edc2c1d1118fb4a02ac4a4975372239dfa92d501d81cc8c5d20c9ce6845cec4426e51fa2ff9e9736621a2a23346539f269be6020f985d9deec0a0a91ab8e9813f50b9bfc616e48123c4dce706b73eed4d56ddffc96fc64fc7e5c06752dea7ce886aae4e1c663188c59888b93242a74b7836c8eddad3f0e636183c70a6cc39f3a9680c7dd191473923a94615b9fe64c32fb96528d53f46a4220ab4911b4f8ef8a2883b27855bb4d74e1a6a21013e69a279f45bd9db7b726d2710911d0bbd1b31a3926a527a3329f724c126c7bc036522001921fea957155c77d1c9b9f0f4e74ac09edfe1b351aba850342bd7cec5126354346b68ce951ef03c04f0ce03d5cbca4a61e79a7a033cdfe308de1ac76d40a8ac96e00b28210748ecc965b9036379d734c38748d3ec2358a89603057fc5b81d7b9d7fabec9ef8630b5337ea85023caf0689d5e283ef10409cb9b77155dcae26f1bd2d9984d98eb4c051f35e9bac50449cf4119b060c8c9bbf43e1e66a15c67eb4e833e494a5cd053df725f9086bc44d502423119b980eb858f347aec8f1532277472472d68a0efc6611a0ba3106e3960c32112ad375b007b86193e2f9ebae83d04a7587a5247cff2a47d62766b4026bd821cb81202fbbe5eb042055ed40cf44a2e52295362ce5b9e10cdb65d986cd35af07ccd286742cfacc5cffb948df1077782dab50db3c8fe0d226cae2a995a550ec072e75b5411e186ce4c2062c5e49c619e728d561a62d6e970eacc89888a93674ea0628748282d12ec4290bac16f2978525259c15b2c5ffe0937f404ba345a64e8f132b62d5309a32ad832c8d2f989ccef45bd44c03b7a08cb1ee3baf9c063fc64f8a247bb65a85d30e66be87ac63354b7fdb05492c7a572328d11cf8855a1ea2d370839b059dfa57eed4b99fbeb111891861407bfe8ca94e308ba257addb4cd8ca3d4154fd2c50fb7afa9769673f66db3990b4067c8713ac8232e32e91fbdfaaeca3b2b4f1a621bdc06790ab7925efd7f57a30e3b69fe590970fb310332ae2ca97eb5ca6d9c6eb270a66d48fcb6dd745554594bad2dedc50ca3d98e8b383ba3a9acb2e0393933cb2175ab9ff3d5a455a3e9164a932a392257486e9e2eee365e40e6555b436a0761df379f21adcdc517c52edcb0c818ee3d65209ebca0f37c9a23672e2d3c92c2563da1596cb683bf7abecce0edda866d05aca899d78c27d3a4b2eed0d8a11eb2b655646d7d3d3d83039a1517fae3abd86e22fecf3028affce2dc81314bbc8d2de7dffd496c2ad238d8aefa1712bb0c6a4a951bad41a76bb54a34efdaaa645d50a9ac71bff7c3502e0dcf565311d63ccaeaa51787d59531031315aec746d81179e677ac99f36a2db9f36ff0763cfbeff58e03d7928d8946cd9ca002e3aa220fbf082627922f832d464e7b608e38887416be5b32bd5ada496b6851d163510e2349cbbc02b0bce4352fbe6838019c8105a39cd1c5d2905d85063887d305330833c9abf584c1199068a73bd253aa8bc84f5b89a822816eb6b320b9033958730fc34129c1fbd602b93a723bdac157b804539160a71033e4bdbb21e96b81a1f30eb1f2f06c6c040c7ce26870ebd07413d338b952d245613af2d9d94627954747de5ad5575b8ad2fb18f7eb241c42d8dbd56ff6cd2dd1143d57454d3dd25739196e47731fe9d4f182e8b06b0e4fba01a6544fa23737748b609c6030ad32ae7731c2540d6cfca5e85b52b1f5f0ea4f570df33d59b0707828fabd4cdee442bddb0383971127d7c4b7ab1e7e9f02e0126d74167c7daf57fa9fad30b130599d8e65846a8df9c490cb856a69716e1c2f8506bd48725c769927b4f61f69c5573d2671c4e6ec422ca6173bd184161ec0c0fcbf5fd0fb6c3e45108e8c5615bea101dc317a7cdb7c59b64b449710d8a07c46add6831dbd9bc96edf2c7c1e1d4b8857573dddefeb4d4495156566de223f69c97c16c764a7368f7f0b73770d7334f65db24dd86a29ad29cf4328fe3291a32e43f2116fdbb849e5c2d7226a778ef56079506505fcdf04ce26c25b02c19c906c480972733d596344da114ad031618e944bfdc4770e15e10676f92c63179edd8e1252cbe4a5a144e922a55c44d09728ba841f9c570c9a34d491a06889dc7f492ced4fe2692c664fcfa543ae828c96dbb0f7035faf3f357f6d54feaddebf2338354930ac27ee33bd2cc43addce6cd3a8172155b7313bcaed7a48bcfaeecbe23ca56c7f71ad199d71815ff5083518f799d45bea82dfa93371156c3710577c85f2c271a94b704d60e2cbc9905e63a03be5f981c1c4e22c38065108980634a586c1254bc9404f04017217d0f034688724acedee92cc5f0655a2148f843acf805d1c871994425481914fd0b5040395b86341f81eb75d440cabb5f6c6abcf448393faa521b68be84f28d197be15f2c02b5ce84a85eb5cdcb4875de87e23d7b58b82a73316d72959ce6d893bc6bb3833e4caca75202b750f9ccb8b27b3538f893729248a577bdaab51a54fa41e2569df42ff48ad2890fd0eb0d4fcbb0fc4e74913b370413caf138145b89cd039055474b608038ae3b60f27a540da594768c06e674ff194ba18c59b237b36e02b66dee9b1131732113b0ae319fb3c5a05be202aab3c163c19bc39bdf6bc50a77996fdea3a6a9b85aab0ae5e87cdc2d939948f967b111919e093cd5d571639b825833bd8a6a71d6fce0254c7efc902fcac24e55b1e7cd15905672a25dc9dad3b20ab5d3dab4b74840c6fd445b736e16389cffe657f6a54c8d6fb75f0f5519f9bd868a7fcb4b678e7ac73a65f87b5bb65c71060dce89263dceea38b7e4a88827bddb9baa452111e15a23c3ef62cc48ba612ceb729d7191f565576cdc98c50725fd0ad4749fb437f4f7caefceec513b1f501ae6d41f6fbde90b9bf783b405c2f40c4ba1c871ceb1fe1cd7f2780a43eb0567c6972e9a5d0715f1304c04336bcc1d9da92eb559216206c547a3209bb703be4be1bd757e760e0f0d38da7e64ae5f7060c3c2bc7f5dc19fff73d8d2b8bf374def6d30bedcd1df58896cbf829f3502ec68fda1374a707fc097ca6ede0991a70388cc0d0057a9a4e742bbd13a5cdeab79fab97bcbb48939e2efe77b66d7ee6e43e1658fba1ede85f26fd135aa582baa537871a869f9db83cc50e26fc5daec7f9f93a17ecac199f8fac861975c0e6be12b3f98e51bf66e6c4151deefbba3a16d8c3929aa70d0657d0e6606800400278b84726acef0cbf2107763d1e0472329834445374cf2d3080647f52ee762b24f79e71c918c52d15c614d6011c899322556da3e9e571c80550cbc4f4bdc6a3f5b4bcd92f50ee3f298875d5490bc2637d3a8c2b1bfcc1886dd316a23f207b16a1dca738852738ba2eb97c2cc394f1252da27a47e3c74f50477bf057d091d5d538f70d9591f180ea415aadb722c769939bc20c958b8c3bade1ed4e086cfc160e17bea165c11e1589708fbdb0755af3d1c803e266346255244da44d394946b8fb041fbbf7812983c5437af09907dd8a1c7a89e0fcde347f3c10ff11a0659585ac01a65de55f8ff6f3382edebe45fef66d2efdc89f2e21cc1d734e553d11a87ebb850572a789115b9252b65d490612426d0ec3d83831d5ff746b717a9f524716c3ae774b2154fa74e2501a2fed828d4381172eac75aa19ce077ae2979cf50a2717687107504b62c956f4d2f77ba06c1db511a30f0c853c8a695560d78d9f3ff42c46c7b80a920ea02effa9cbbeff442eb106366393ec901134876cabbd5a38d4c99c0925318e9195fb1a45363e55b91a118738011f9017cf4104db86ca1d6fd3c9c2dcb59d2761a24f081dccd640afc19c0968b8aaa3dd9a9b9f61d527ac8398557aed01e57d7ca6f2a8644379ae8ab287795923bf886c41300dea8ec065a7412f4fddf123ed270a1d3a248a093c3c4d7f4054eb1eb717649dd8bfe77564eabddcdfee00c4eec246d93224bd61753cadfa152e7b5976d96a9348c59f8424a0c8bad76b9924a88fc8cabfd889d638c78184a8ae86dc3420c29d472dc32768bcf610d66768ae623f4fb82e25d4402054315de81a17680f803f940553d2c4c441bae39635d62cc8dba847670fac2c2034301285a15722fb362b7b0a0a8c47913d014e5df4a0081b0ac40c544ef86da84e110047c64f172b66d2705ae693aae79346b5dd03fd9f64e458a759aa32b1f5052528d0d10e112583fa8f19a71a6452e6ab8fc411f825874f3389c9cceb18ca46e4450ddfdf861c69257e40eba16653a543d699f191ada102805b56464b63792c646877d21a7013aae2975228562133a2c91120590a46bf80e564304e43f55e890d0a14c58304b52377edd18322720996d74cad3fc68d4aff745bc9ec2e10ae25ffe9cf466da4b88ffc91d4cd8052f61b31404ed7b9afb9fc4ffe32822524e558d625155fe2cba6a91c134f36b410fd87ef17511935963ed9ba0c5c39d3ec522130da65a8989f8bb7ab3388ff0050634dfc00c6177ef423375c0074fb01c0601f364fb5fb3c39e78559792de486bf5a36f14303e1c83217cf695e13921d43308c2f621033525155dbd3c19cc9bc35cf591994542d4a397c24b2c73796a588e6799ab221060f74dd157f4472b6475588caa1d58633ead44ae365257694c2158132388333deb4b875cb15abb868c226ec7b84a6d0dfb1e2fa07767349712c3c9515744974f7d8261906e5035d10c7189917e7486062a844750cfc059b2be0fc6747a74ab8b0022b4ca3406166b0a2e2f8ca4a185eb4c263012422dc2eab26e250349e37f97bfc893f6d58c5070459ea4c244ba48e6ad7a45196e48ee381a1ee79a2a0f0db29c281184fe9f3d4c3b51bc19e89eac6de247a06c72a3f5053c452adfc318ba867af720a73618e6647c00dc5163778b6c3771b80ceed47ddfbe470cb69b7bd8ed9890e5379ee7414df41a803c7ae5d24aa1b5b50470e52a75a5f1c41402a6d5c1fde5f5715c5d40b7078c8a1ccb657981b913f1aff0d0bca3fe07adaaf49868cc3a7498492e2752cd335ee92f2c1ff9509927d626e72b83e45d3355a22772be39b6e2b222ad80b118ea06f8222909c4da3d5f93bf7f0fcfaeace7112f9ea90eb4279cb687ee4a0254bc84478d689b2ede881f8201d146849f66f4f44343aa84acaa160d9c9f343bfb8e07d166fac6a593f674a9fa5242370502cc7086ba4a5e6039ea2f3552dcd262feb66a317eb41c9baaa95edffc466fd5691013d0e43c1a077e27e2943ade0cb4ca9e008aba857827784073624366ca4e5a41b6385ad186593fdb37c5bd04673b1f0c158490b9788225601ee474cdbba933cae2bdb09b8be3dade9ad8a3146e81d55196c58a77a2e84191aad4a6ba34984bb781af357e3db17c4bf4320f3f2ee08358d199f31cc394371cfd5c8cee12590a3be4dddeb2bf1cf33c03bdaced33d028552801503d48ac7c18b88cef3142595fc5922e648eac146f9baa614a086135107e583dcc5850d7978a873c45c56334c4cb67971847b0ec389f6d13d2c78c90aa25af2dcc47420344d48343ac169d454bb5bf58405c344616308be43b54f3864e65e82e1f434c60d75f1b40e21acce3dfb4b4014dc4691beac355c187b66b7d814d1ad68216bfd0148bce32151cf8a68da468cf4705f7d9cb894a5366e56241baef503f9d0e8434ed1a337784524f2407996d316f1edc2fca533c98f418032e76b0785f77fe515044c5a8a0c5b011b7ebd5f41849b8c0437c9231351bba0770123f0194c32360c060f1021d5421feb47cf75f23856324dc706a70f25d3a36d3ea6e6207813ff4cc31633fad4c20475b252dabd0a49bd6b0032f19ea85f293b5702f58ed321b3c8011ec3c7da9e20dd26e147dbcc65cd5775fe0afcd082565769373ebf8f8effcffec618e62c0c5a9235a8432ad2f0ef1d055ea4e8e67172970ed6ead8018a5fa98850406071809c135ab805987c478932f695387ae9789dcd30e230aeece316dc95ee10ca6bc81741312ac6bc9b773ce2b129a814932457b48d51c6954238a566a70128c1dc136dfbb687a28a041227d6e43d59bed792ccc21ad228a7ae8b3cbcd31fc73808c2628f42c933b771b24c3ae7d139212c93b49c68e9c11c8b986c15454c16029fb9d15b5d488517a550cc564d6525113334572fe09a33f783cebe271ded439818e70e37a6ddbcfc0b84bb0e625e69c9b30531fadc3b5e79a334fe2d20cacc06b7e92aea52101faaad57f2bf84aada33975d68caf272b201bea808b7673540ff9a40717732fe5e14d6d76bce82e5236d7b33fe48dcbde056822273dd06998ec7b08f2fe195446a8353e3f7be069614a67a91f69dd00dbe9c0fb30b0efdaef3d7350f9ac7bafc9dd41a464e818e34ef94b66b9872270ad072d9b0ef904d77fcbe5fff3d3e96947bd97513778db38e3976f8a596ef80d37dd0872d60bf827b85179223da52275024053acc414766f849bc9af7ce057fa1bf883f9269794370fd2cdd72172d96f73fa1235c30c039522ab2fcd411b39e7c4386000e3b3a0c1b90a3a937bf83ac091090da43e7ea514fbbd910d2d28761e702fda8282f3db68147268375d2c0b70c88de297ee109b7ba88caf17031c653d5eba987372462a3c5e1edd1fd4b5863045ac495e52fd69f82901c693562e8b97d93297318d072fe3f55c65dd60c68a10a6a907b8a6c7383c9395b10d5c6a31a11dcde81ad11ca761a9d696feba6674c95ee793aa65c5cce53fcd0b11eb55b4cc85d3a676c5b62c3f0702a4c090b4aba6f64a29f6e8a239d25125c26f02dc767ed7be8f64f55dbdcba70713b9057ee8c5e876230d4541a12d488f5c153131d760491570e2a42b3db185018bdc955c516043d236a01ebdf257c12399c7df999171ebf3bdf19fbbed1432520eb68c7f29adb2c296b5d7102cb9769cbafed941b7c7e19068295e4da863d8ae31f7b9dae7ac09070cf466a7ca32b01618b4d94727487cf2904f66b5ddc814a9979405133f3aa3a235eecb427a84652083e257e42c30e53111b47dd43c5db7a5c0059eef5233b0040bd3551b155f08643a11f1e0cbead68fe093cf4fd16e31cb05b79d40233dc6ff059a2c8016d9c46e526fcc2837ade290e5e8857a6d86981d247a84cca4099e545f1456f4c1a594e362562c78119cea5f7717821a47d72a9116f388a61ac688f304cd4bede155fdc959b39bbcbe1afa5d6d20c0af5fae291f7e7a003e485a4456dc770168c5ff6ec0f70e50886269fcc7c4fb25a0bea33bdfd4070f0644fa25433b455009d8632974d95aea7941164eda22ac119da9ee879d2b8c61eb2c640890f82a26e7b096a687b112a111cef97e1fa8c0143fb3f9f5003f27c6350418ce38626f13ecb73a545845550f6e2c2760c832c3bb8ae0ea06c1bd856748c754b013028d13cc6da4e33b38b67b9846237117f0b6e45761e06f207222196c7082454940b61f10c9dfb21f953807905d41f0a4f4977d93997fbf6e54afed374e158e2e0608bcb75f1a588e42a4db0c7c7fc80a77501d6808281c5ae76762f9e0a1177793174d4871d21fcdd85337617fe6467c44e783f315e9e5a08ca013d023ffa6733db95ebe706c6371eec6d6705e7c84ea853737982a37e8ccef1597649c610169365e6fe44f0359e862d23ab9203d227960a9f0d538857d8bcf988e384bf05d0326e1fdd925e11f8905d5fee6c507f2ecdb7362adb7b7fe707586133c5ed84366bd4918a7e8193e9d182e259353e8862c331a1ae1bd89ee2714b7a576a74e6fe7b783469eb0d825f069415ef76e857ebdaefdc8b417b3c06f6d34531d40fbc936f320aab3e3fa0ce2be377a990591fb405ca07b462fff3c2469c86fafa3dd5387d5cbd8c8d5ac14071b728e1d43000d9c8fe28a1c15226225d4d4bc0db21d364b1053e7dd4a5b919c2fa80ff60a96d726d6eefc868f08aa000847a9ef31c9289f511438992fbf9259423eb95ed0d4e4fc7fa8dc75d24083077086b7c40fb64963eb97c0db0023fd3ce238a63f8bfd97abc5f7d61986313d6a870d5c5024c8ab4647da1e35cfdc8567dd8fb21766b7fcf8037d25043b3d792debf1e176044742b4887ad7a90651fa5b60814b6d875758c35a14c9179c026e9349c437295e8b586cd50b158e58a24ad12b84baaaa82c157630bc2a398a1a3eb1c8e509449689392268b76c0aa26f5e94d8d8aeb09147a71f4374126f1404b29d77d2104b21d22d5b0f3a7bdec3a641e27cc9a81a1e09a430f5e189863ffbf867cd1fd62e47a3db4e3a49ce8b5221e921410c5342051927991777af0a9cdc204329153e355ac76321639e9d23fc320f4900051f3b2177abc6f3dacf4af88c4bebfd986ea00631a70d02e66ed7028f8384ca5ea170a29f7ad3ead4e931d7a2b66a1418159dbd18aab8121bf309af769d016f7796b5c6c978af12de7c128c040f4560800d2db82a1ab68b7115d6a410423f6b970dde798cdcf03b6d986f09254a05b56151454031b0f8cab8e89d4eee2dbe1e6fd942de8a5a75e1a20c6dfb4152c7214b7880084ed0d45a7c5d6febd9ba4f94fb7a76d0c64ad1bfe73d421785d7f4f7aa8159877085d88025b8ca261934ee89a7c89beeb8d5ef94571375ace512b1f8b6c1c4b12db81c52ffdf38083136c74cf4f821d69f105ac6f501606c9acb67d7816aa15c38933a18d1bd8695e9183a3be2a1c0ff9852c1d167d0e375ad9f90607ca0e8036d7b69db030a410c5c779fcb37594c08ae6f81c1c72e2ed8216b6355fa204db022abd33e5d32462d2f4aa32bdd54f4f89bed8e3181037f933b645767595ec797f14356c32320918167bab7328d5ef41da00684ab8b26eadebd934c8e180deffb7cdf5ac449e2d71ebf8b40be9d50344a1451dfaa85ec5c40fcf20d4a8adb50057bb4e4206e2b067be133e0be4a4d84e786ad8b0036428ea6c3bce0916d2941f7555400a4a5f1debee17c53a0718dfb5020ef23f84e69837e251eac1381a86478c0bc562ffc891a3342f0838b1c4ad64c7bab1b6609b656afeed67f70bd51639ba57430a3f0359bb2d19a5ce8e9b05ae9259942ea5bbc7bf0764b3e6b9210ea8f6e9845f0d08c1bb591787ffd05e9eb4cbe5768b9e1eae24fd641ebbc45134b508dec232c6d9f35e31e4d15064bb029915df50c973b08fa9d3284929da512a1f4f85882154e09a27d8adcce8ce0bce2039b0e4ac0151400c01d9c80e870198b0b4ff856b1716d47bca29b32a43835182317201979bb5037b39d3d3200463d594fdf25c691ae08a3f70294151cb33f4c0bfbddb075112ecddde968303314f4b0165b5b011b94c5c9199a2ca0d69674dbe08e69d333b47ef022538c93dbdc16a819b2bae15ab614190e1e4f3b95a7d4cdd3df988b86f24e960abff2f41e7c7845eafa19d063c6dcf84f7a07dbdfe14141e0f4e81ddc843cec5c500a0751b81ef1ba6ecc205fe67d11f3828b8cd756f0b4fe84b5af1ee2c92f8275d53aa20a3ee79be9d36da9b8ca3b75caf8f02845ab4d6f03a7396f772390e0eb485629331e57f789fb99f290b108255660b2d486aa04375ebcee013462109967af73da460706ce9dc3bdd639ed25d70adb165ebb748ebb0b41d27ac1fad20ba7b26495b8136d82bcc20217d78f6fcb5d759d7b93800a76abdaf27290363feaa55fc0dbeab8fe85aa2de336dbe4ca77117e6d50649fa0d6d1e749ad4a74dfb3e05d4d265b9a27b23b0ac31e192559367ad9c0329d0b99051af161c0f9646b6f697fa5cb286288ea6bfab02f8acd7649f867f29fb8ce9e704baaaae56ebb4bdebf77151948677054e4a74bb5c32d5b90f787c5f78d27db9d7bee025756fd895d81dd515efe2783f17b403362241da753d53767dd801fb42d2faf20e052a7b2f8c57a4d4d8211e5bf55dc9a08a562242a94b421ef521994587fc847688a7af27e9aa73739abe352bbdb7ea64afc2d1facbc3e9a0c7ae2dcfd259b17c0e0f19f389d19d289698e470035fc59e3aa8887a8a582d73611757294eb7a2fe25c006f48153b0eb88e08335f009171fdda78e8be3d7ad4af73fb41b8055dc3fa4af11e694d1ddb8dc16b35fe6fc9ff0b25e0e821ab80bab3d467b06bf103420242a4869f03067004e244298b392fde41e315a4314e026f56f5f12d66268925dce92995320ca1696cc8556cc36a68b2651d202751b7bc2c85eb53cb5e6e1e4fb47ce4256a97c93957c2dab93afc2a1ac4472d6c444b9f5012891d1aae4cc1492d18972449ca2bc19b42898dfba299d2924bbf125a34ca9911cda8eb4382f14fc015d5bbc5b24d22cf2c7b9c605f1406c3cb11fc46da4e5dfc8814c8dff810347d07056d9ab0c874944a6bdea61844a6fe8038c69b923141677a509fe78b8a84a92c66c78d44ca0d36e0c978534d40916ad282c285d0209ccbfd40b821651127dfb1f87bd02a7a31fc651a162d5d347314a2c6687ddf6b8c0ef920be0fd49c7a8ce2ae4d7ec867eb235a1486a08335b026a3bbd90809bd663210c874239999b0c5d6a6c2d9c457d5cb5d033a1b0670bdae3e0b8d461cc401f907e63e5a4c1f1d54e0c9d5e12c32de02371e332edb8ad3cb6118db018629a7009ca5d788f3c98112eb5b4754526b9c9f666667282a225e21251d6b8e656c2d5919c6d85bbc75a4199aa71155a0f981a6df5c8f7841acb9b22f40c6b1c223de0902d73b8a162716c70436ae4a6c45587ac0f76aff889d31b4882172e018abc4b1e0510547a8d30d8db218cd981b3e2de0ff59e3645ae6d06c0cecd26ff40a51fc2d5b4a6f993c31e61f0daaef0af4b58ee4857c35bcf28f4c160dedc8c70a81cee36ec0188c3403e4df030ace1edcc26b59fc4cbe709f408bd27d463ca72e26746fdee1dd788afcf7df52da37449b51a9009cf438d41a4dd169cc05bdbb2f4a7138904d413f200dc1337850cbd6a84a8f5ea74e3005e46efb38047bb59e06e44179d0cac97c6387fa16dcdad70758309e4bb0d9ff7c9ddba4c1f27d96f2e231d42b4301dc18b732b10bad46e41b91f27bb4548bc6548dab8a433a50e68e2766a7d2046ab30bb550a6abc53e948556f80d8ad87ef7138f57d9db7504b1eadffb4a62b7bcc17858473cd36b042c9762eb720baf55fc0520a3a2e9c5cefd3106da27bd1b2617b19940879413a3bc9fb2a9e562e3ccb550b59078d04ce71f93df9bf7e568cfa5bcb8d1b8ec30a523b763a65a4058ddc0557dd7942265b3ec3b8fc89bf8740f38c4d9bf8fc742bf41aa4b873c8fdecb166e619ec09f19d6a71cee8b9409c302a79310a3ae3c81918363fe971dc28a1bf2920f35e4ba3b5a24c96ff11b9c830e32355b61dc50ac534a61b91821b88009d07bdbfa1bf3859d38ba3026f8fd8190f60a94d08ea2753921d2a7be13d8dca53a55d619ca2095e890e8a1efd5a74ddf8d5ee14da05e34fed87214439366ad3d3171c069e7e7cc016694e364285d12e0c9391d80940d720aec3530147ae695ac3bbaf2d28099cf1612ed46aa160ff52d0e3d4d2cbf3b1cb003acbd66a9c56b3e5d2b27ee537fefde956da284d4ebbd51624685e131a1bcc6205485ca614f35ac9a5332796bb8a698632f0fa94e7efe4d2cb1a9db40dea10dcd7031c3d4cbde3be6747b76303b0c6d37d635443e276a10bcd65babc42b32738781318a501187803f38cb3ad548b6cee1cb8b2330627027154382df593140c05e31e7390dc7485027bb34c0cea71cb6d8398b04ffa4982330e618b0a4fa61d7e892f07b0b33a66b7f0744872f9933694387275b9910911911d74274428287d684bbd2223968870406e44675c16bc414bba0fc8c2bf563b9627ea178287a4fbeaa20a0e3c828ac137ac048d6edecc01f871abd87cba00ff26a757e6d01a8004282c184e6d2d1bdfdc114e6f4230dc1461b85785f7333c35af4e451da7b629e80b0212e87d7d4078e5525225eb20662e214498cac292f60b94f5cc9eb9e8bcc720046ac72fffd343b21070d6b0f730a20b176d789bee99c3e8aef4de96b8bdc7a727fac6a5fdf5892e0e80bea6bbedcf0b1b14e3074b5c8a39859716b7fc61fa428e329bcea22197fe2ff14d22dc62a7b44818c31c2e4d2b5fce80cdb40fc918b9af88192e07baa47842c8f88af867de24d6ec0bc95d3a40f1814ac7d4be11c4feb80e2a58d9a786e2bc065ea219fdfaf8697825236800fa152bbd0750a19c039d7cba3966814ad3033b73584977cc8a08fffcaeb0d6ccce2bd36c764fc30b0426d3ede6c4996ee9c976d19d3c01a43c6f72abf8dab00d4e5af22e10e04bee3105c67b11f82c8095b380e57fd7cdbf49a0236ed8788d6eb063ac7719197db0bc3262092b542270a7c91cf724480df17e859899a3e964076757c7532334cff6db65ed8596e2d78157e3da1457484f58c7c00c5729117015103b0e2e282c778f4cfebedab8309a509863592234a93e703a8b58e22468abab1841b221a49a53183b06d3a353912489d164c3b2e5a83ed6f3f4e78527cf69223872ade8ce10e308e2308d180ae4e92cce1592e57ad693c8c9ff6ce9ff01a284ad2c238c07b1709ecccf8d4e72df377d1bf70ec7ea95992e846b280c547672c96cb63f2ec3a09f117a2768e5e9ed5f9122cf9adbaca55a2d5338b3b15398e8cde83baf954ad831683f5052125b0f7d3b9749cf0571d40bd0bdc7dce08eace6fd86a106ab00cbde0490a9c0f1e0bc2b660d13bef82e72d48e93cb7a7eba8492c41a52c0501d72724d19a917d640b5690706d51f23e3c005cce10c1253098cb6ccb75c068a4509a2a4fa157572b039a59bccfa944c17854078cde6a857bc22737512d41bf5d204690233492a5b7c973e843eb5cd30685411b8c71f0bcc0d680dd780982a76cb92e9f6afdf232859348351c6a88b24bbb7cc87877c28d1155361017034baeccd056280488540daa3e2a8886993d19ebaa9c48de0b444af7c55aad157eb266144c56b066aee84157b6a0c4fa3da57c48b9600261fc3aa49ebf91846ec45aa90b03da012c32a80c57a3675cda86523a4c56cbe1a088d82e1449bd9cb0d50abc7cd2f2575d6232d482ff6bee8f907100949843d08130954bdcd8758bd1d55aa1268285aa1e6055766dc8164821aa86e9bc6de472597e99d857f5ab20d7d9099680b478c8d100ebeafeb09b909c23aec536b049bf2c04981f7f39da20ea80b942f683e4ad26482f297eee7c833a97846edfe0398828ce568b5c3003fa6e3315102d17c8e8cc17b17c5af2cbcd11a138fe71a3436b321f346e1e34195182a41725e20ce03ec3085211fc1e74260e8429e95c21a3730299c7511dcf76b3e7fd6f332ae769a9b3aaeb3b39f58c3e3b0e5df5931cf0a3d45994f46c7a46cb40c627967a1aa1e16d252d67a11abc2ae99c8f12ec5177c8a008d5536fe215744c5793250d6fcb8b14b061cd937b8c8659781ea58d7103c8263cb4978bb87aa68c045ce78649ebe9f9ca50a5e7e15302ea0b40f7e9cb6f9993aadd70d2918f9ba9512e661f571079464a35e496e70283a7b322362beb5facf4f04fee5e4dec42860ac2bd3046a2d0fb71f4b67ae76b9a737dc38c675ab0642bc822586134139ef570763deb23ed17faba50f15a492c2c5e8429510374e7c0aa245c5dc99978bd22ee765bd26e69090b55fdb785b2a5620d1278d76a6d4f66712582d563c329aa4aa0035f9a636680310da78ee9613b26c6b4879d2b31467c71fcc5cfbeb66a910f3ec906840384e9620b49637e3bcb045247350da9f96c045db6b9e40dde1c5aa3ea7ec5cff453cfb0205ba311fd2b02226c1657a6178ba505a4b25a688fd6d0c7c19eb31ef41e5cce256458392366b9d7d6eb8e3e429589a138309d07c8aba724ac88a036af02d8032319f8a5c6dee9be0b616791caf9d970f19c3b44720fc2411eb11987486b043713947417b0a1245e6904bbef91588dc3ef0ddf2ba905a3ea740ec353cd8d6cac2cf8d57b802314c24bb5ea129c5c1c18c5a7a9945c417af0ad9156ea72a5c03c51e40a19afe257a301331c1045384b4a93e026177696e1258dd9af63f98b728d1145c41fecff569f03c9f5e826ab8b1a2560f8b174a9307779630d4ec3651a594a36a19436d696d6c71d3d83e20d5e10f07e1782f0277fcef15219bad0cebe32200035666a937d0aa9408d75fc1b49a8331995d267befee9602f2c9b58c0b0d780e83d0edff08ac8262e6c167dfa9398f066315a176f3fae13b0fe3027a89649f17779263a0e78b4702223c2b738e9177f686c52e4d5e005485e81f68576833b9d7148cffdf12452f1e932f9bcf52178b8455a45972f80a23e2faaa2a9e5525fe26ab037280919d766debd848dae02f0e77d51747b9c545c5d5f67210fde18188e2434613340e3e3836d1ef672ae38e9535ea79623204e1941eeb5f5994052843cdbcba9393f1c070ccee91abd847d74fec9a2d028e8de102304ec9d0e54f130c42f83e051de0588c1bf9a340c7090c9549e15330e438031bb1dc12ec717795f570f9362f39288fffe5667176c131f3377d88edab7633be6e5c9fd993fc1e4d2b1ab97c5ff0302090ffa59b556c37180ded0dcdf9923017daa9c939b574432ef8310e891a35432235d54de75120f32e3c137959b8a63eae8ad6775163f9f3ac9fccb0f18c1899edd1aea560dab68e87dfba89fdce4b71d66ab420da10644c4c419b2eb1996465dcae0a64b3e9fe4e8ca3f83238f1f7d87f040fb6690ae64feaee2b74c54d5d0027b66280902442357736a01d98173d251c795f80de13ea4c89b2ee31d026bafac9289f41a157df211afd5071af6e156b8c550258c513366454be50f4f628055b458c055c8041403e4347559c68b967121d589275c6e18d22b2b871497e260a4d52b8ded7489190f45ac0c2a894ae3b93817f22da22a62892e1255198c3ba90320936ee607ed8c48f0025d6c5c1a01da38a6ae0b572f3bcac31b5b7ad88898308bb7d0eb36e825d94aeb28e7a39868a7d437e6b789a41eb4638feace5fe4ad7ef8bd6001da2fcdb416a300cbd1cd3da0ded7df9be5167a0bfabc37c49c2d0b27a438cb91189980e8c948674dd0d2fe12974e14a267d625791635ea46364d21a22db86b21c54d22a2377998691f3d3ef8fd80d31aaf52125f62a68d3253e9204aec33b4a2acc41756c8af761942b8d7267703c09cfc5ef20678cad16b6c4985b080f8a0a68c7d58a3de6e0ae8832010bd5591241663f6ad97c9cc363902d0f9c7bd4515ef6e43ec0d6b33d22ee3f0f8c29e7047b67d2aff0624aa03406ab2f16115934aef0f0e77cb11d82adf255fe82cbe6e27c16ab1450795c09439f217f0d14d33ada2df44ef997c983040be3f328aecad76cc57b275454c42387d9d5ed3412904b022074ce10f0c7eaf7fe87eb02eedc314cb762162cb3906cebd1b9ccf2b9311f0442d2a53585865e27f7abe0775099c3fc655e46d1cf76b8038e6fec6a6ac012c8eb31749db5b8b83da7f42d7fa24d22af1bb45c4e19641dfb1bce7a99cf49759e474da1980b72a56ececdaef9b4b924054c66a4583f935e291f84feb55e82fc47fc5cea62642c44d1d6ee19724cdd518e3e7fee8cb031071fe46c45d15a5a1e663cbbec4144a735058e3099fba83f3fde6b0ed4e565a8af7c199f5970e24d73737eab9905b31a2770bf6f1b6ffe1183497002c7a0e6affab3e5ed8db9d8031a80f3fa498510e5e43d7b911faa994a258e22c3a45c36eed30d5e6b9e0ccf8f8a853f615e678ca72e56e79c00314ed01a37f93dd06261979d7eeede3387eb8918c0dc86d890fb90c1b325a398b4e4e37f57d73ca91f269b66cccd8dec5cc35f6868e99b7d51037e3661886e11ac3fe0dcf8149153be0e859264aec5d559c575e02750500d87bcb51d1954fa0806883ada2e290cc291e0975fa47a7a9ba413628e08edc304da45c274199c44dd0f1251a4d8041961cf7dc6180fdb0e85ff4c890745d8bab27c449623999be5b2e050371327604ce919a321634c4894d947b1e3e14d10b9486c0ede9fad956932ec701afd9997739305260c1fdad29678b9b4e4aaf5e47315ce5d0b8190ce05ebba4e74d04cc410e9930aee1e4c2a5c6f47f56185635046edcb84fd496a82c26b831e184b37f628dd7d785a51b73e370a7c7447377545908dae3187172a1c0335f3dd43b99e42abd876bcfcbf69f78e48dcd6e8c3988be5108bbbde8bd830274a8c3acdad908c6c914a0b57004268835da55a768065b1485ae00acb85b605b9333c616312a0241aa67c0dc98282feb13efafee65a64a72aa0654c5f9f2a63eea214a54f4693cbbfd00f4c4d06ed2b54bb70ed87d9717ee1aced97f385441e8a89ec5bc10a2633549a971fad9880e29de1aad02c240ef9129dab6ef693c20e2560c42cd1d1dcfe389580c249bfbe680bf885dc8321b82624b12a03c5a8a919d912bbb03ffdc1dc9c8ff8c2194e9010ff61f6b5d49433a692ef38ca2a74064989af0ccde514034132d2841a821ebb5fb9d1406107d3bccbd641d28874c072da3bd768e00bb300f206a1d06562a4365b2b98404ab25285c27c28f9f7b3dc7034c0873cfab7f7cb3c2decc450af7ae185622583b3b6505e9e4f47e6a7309ad76f5a71a27c4195329363a0cb657b98d807d187abbfafcc16064ea6980cc0f83ea569861bd949a7248317afd7a415fdeee1b22b50f8e850a9afd596114bc27eba1187051984f9c12daa042aacfab9d72c35224c603bdc5b21537781576df2e43e39240876077b0706d41805ffd4873a40e35c5da9c1c8c914eef7ca884fd7b1ac7eeaa3ce70aa43b8335c3b4209263d63c0f58bc948c282b88490135d933320d8d183ed2a464f34420995000a78bb6839ebf1bcaa146a4aad89337f8209c9bf075c82e1fa8db8e6969af3566d35f57411bbf550b6e6fcffc9148428ae5117b6d02bf4a8923b3e1380a07418fed829bd4acbe1e38c55ce26c1d2d334bae9e07a4651a71c484777d87f10d990968f36575f2784ea4f0cd0f8e9246fa42701b0402a69e9d986cfd6edee404f7e98a91ed93aaf293a9f649b6a50af268f81e5b9b6579e70c3d9ce6635fb5fc6aff0eaab5c747cb8f9ed182f314e09e20927c02868d48250513fe2a771804fde932be6d1760249032eaef85a23f3253bf1c548a0e9361b5fe0b2a9028f42c742f333b2e832500edc4c069406494b73833bcf3e40724d20df35b19b6d2b929954ebb4fea068bc27e69ce6caa62e6578d6bbca114847ab79e64ea998c1dd6a9eac558918d543aaa30cc0b4c5de86306fc075a6420a5101c92e1b2a92ebfd3726ffa5e9b6ddfac71e1afbfdb103a5d806ba7dbb790d8f1fef36a69d56fc9e9950b4927cb7217fd8da9a5bc271ec390401e9f91e4eec80c76be2936c49807a3d94ae1bffeb5c87df15ab1bf7693a3618dcaaba7f4604a0ba51afba6552c9a33ab9f13aca27259905f815600efddd4e0030d96ee0bf74b178ce080c94434de40dbb6bf04044048d448345dd05b45f820f7a760b06f73c130fccf25876b6388b15ba247c27d968cdb836adaa98b82f48d812f4d599935beb008c8dc9d404997c1b6f804ca93dbfbfcff0b0cd608ff7746b122fea1da60ad723fea89ebaac3286155e04b9e012eae94b569908588309845f12bca2b9be365fe380d3e98da5307dbb353072eb6945ff655c26cebf26444fd10c00e383546d6d211404c598d2676b523f49053b626f8272e4d068c272864208412ae49aabafe9f56e75fcd547e97c96bd3307fbde5421d12e52d9d6c6d669a49900f4190b690c01f0c2e418088f24643a00d7fb9ddce7ea320805e2201955389edf1ab422518c75dac137c9a4449ec4d23a81a3fd02c79d22601ce2938fe7b8d2f3927f8566dce876b58500f2595231090b54c9e4b3a8410abf173c73068439152072f185ed278bc28ad47887b977d226f92ab8a29911199ccbb65bfd2f0dd9d3581cad63dee5368527c905b34c6434b4b387ba68052cb045f534442b94e49df118959ebc429c16e10040ca9a9e0e669b3adfd3086082df0aaff50337ce00e5711910f79c95ed05e94ab67a5d55965bdb1170f81859039a1054293fd8dd14f02601fae504082d908f9486513afd97afca1eb81b1dcb005cbea767cd119e4cafcc6e74b62bf37a7e9a8370811374fba04b6a912ca29ed3ff63a8b51add822871f0648fb17e4a750c40bfa916c0a548e9dd0223e9cff699b1f9f216fc9e1e9085adceeac80d63ec072dc50c836833dc595114b3b2cc36d3b15f7f7ea1297b3fc852faf2504f21852558f0685c9ae91fa9f4f1625fb9a52249a0bd86f58f8b8ee8cc58f772f9ba691f3bc686d700b3e705744621eabf7bc1c3bc4f2da1884d3e4b37626d773fe87f78009995fed67935ef43f076c2acfab23cf05d810dc5cd066eab7ea156a92e217329834e5a45c9794c5bc13d8388dbf93fc722a2c22b9fddfdae4968be65c95943f3ef779bd131dd5432365e0c1211432af849d7eb42c752caabd0ae5c1f74ec03a84f4916826626116ef27fdc438176e156e29ca9bb48be5cdc3b0616384dd4d18fef79cf3c81b5f16156bce6a264a9c0fa70d6c9aef73e810b62f42f9325b44572e6b821e009119c2812c72cd9bc35dd5eec52384d81b475ab49cbc2417fc29202a834b29d1fecc1e801c00c570fbf22fc76cddb20cb2e15efe2431ac81ce43ed65d485637efde8c3b60831647c41a8f48752b0fa5fcb545fa430e10ece04022a763928c57179ed0f2a372ebc02f87f3d1cf5e7b8f19753897bffdc816718493dfa2dba5576b0633113fbddc676828257367edff49b8d44c87118ef8cc3843a4d70d5d6e5e708e04c1eeeef81b07ffa5d209c6e8250447a70dbc5000f7d8ec2c89540814b747ac9c8f4ea0e7afcd35a5cb47a6cce5e0884b87c6f25ce2b5231f67dcb063d316cb4a0ef3e90bff1603fa8dbab80b8e23da96c59e7e092c8629e0ffb0456d5ea79c942075430cf7761cce6b15df754682b8083722bc13b4fec5343a1f5235b222d000370401c1149ada3ba24c7c202afd77b66da081366d53e6b0138a8666fcb1e71065955589acff3f83b345caa06ade31addc5d851839b23eae1d0ced161ce58bc01ff2417243e9017dbc5bd720b65a791cad5310fb1afec0f4f5ee38874120aae08b53ff6e8e52c006c6cf69a0faea55de3df53e89680f728e05863fc7243914929af05df640da11a37539bd9a4affe8413840ce6e0fbbf73776e0f86aff94231f1cdf82601db51b704df6d76417b8e5dcd1323601a24b822fcbac4f8d00c027bfbecbb01180f429433b8b84694ea7284eb8bb4f890a8c624337dbcdc0f653a0920d050363a1c7d30aa3c1bd61409347d90c190e0b7ffdc6ddf1e7098e38d0b824666ec9469fc069d93e61e2b9cec2e4e74dab30411fc8fdd4fb6d866939ae10b46fceb9b0d6015328b9a2a2b34f7af1a3a0f4174a14e0d6c22aed401787aa2dc24a83dac5519e59fd5bdeadac8ffd83bec3f2fff864b07cadb52b4daf20ebc85de8f0516a7c5e6b75605685347fec7b3a8ec1066b9ed2baee0b5762c10f39eeb4b6e997240bb0f0b40b37a878b11bf4e4738f9040a1ff98997e8f95e5bad3d6669a64a0b82fc2d7b257637867ebc68c2a6efbe06cd46fad94fa2ed187269932c06c493922e0d7a369ea81cf217e884f33ac835d74ca5b774a59b685ac02d2063f9964ca765f0d3c452e71e41f84b4e26a3d8475faac7d5112d2594ef3fb359cd643c3e5dccbe73971839adfc82e21f8985114506e135641ec1b779e05df103cee5b5c3088d41f70813e448c967bbb806f3d6a302b83bd657dc89d259438899b908fa46072459d05ad6e60a926a00328781a63b97ef38e98fb39e352b9a3d177d4a4c118ee1aaa86d47dcf187eb85e362b979aa27eb628e433e912c6a5c34d605bd5f5e3754ebd3a579e9ca2586ae4c1d18c683104bdcaaf1fca925ca2dffa4dc361aa0c54112c650aaf6aa1021267c56c276746644af4371c6cdf559a4697b1f0d0ca110a024046fd4ac3397523067b520ee5967385a9cfdb3d822ee04770e9245702247e0ceaf85eff5cdc9c26420a8b83741d0ec9eec261cf96c2eec62bb86dc75d7d2b56ae613c0eebdae2bca0ffab9de4087c820f31cad314e320e978d2b26404b332b245b41523906213d274c97f482b6f2f6504197d2a2f5346ff8141fa51c734469857d1554802ab1d2c39582890e6fd99ab9451c8c23dc98f2e6b8c230d65675c0382828bbe0ce29e61e912647690c64bb377cb279571275405bca9c7c06d7d912d5f396a741700ba283d3a70521ea4b1c38c7d11ff51042202b3660931263623a23c93fb73c76e21a86a47d055fc5ca2054ca046fdf5be565cb110eb7b07e164e53458a32b3aac3522b4d01d42d4f865440fcd423ec0e068169d34ce5d1e44dc34d62af369c2b103bb3dc2eab3fd94aebd20c42324c6bd52d586d931d791abbbcc5eb97cf450b30d74a5353edabc8993e7c7160b2b8dea6724457eaa0338784bbe96a20e9c10f86147e687266b52f2ceb2536c55bd84794612164515fb77aef3a62d5bc89b527506d966b32554df4097c0857b48b21edf3bc741dc660e5ad7bce06b7b4ff95282d4ecc8495a14feb3432355cb47771f89f4632d119dbe75c889700f7f212ac2d9d92013d4424b8d985969e3c62ad9044786fe4c25cec8adb8cf505083bb498886d55c70db6cdfc949c4a98e911fc78c5de93c787004d4729d9d8ee8ba79121b6eee0b7793d98d9ea512030d011ef5615da01ee7b15897449a7e688c329b6488cb443e5c220bd1b909729501ea2a607d0ae46c76a35940f21f2a9fc0dba74ec5e7bb0400856bb81eaa97a7ed92806086713ba502ffe4f3ca0ba26fe9f4b97dbc06d947f9d3f7190b304ab52f96c0c5f0b6f340fa322dddde99fff595bc920de61de62e85a216d3ad613bb84dc76c7b9102258ed5d180b2b8b6a4ccd4afdf13ac1cb164ba4a7bdc8abc5ce0dda99ab833c433df2ba4ab73af686bdb4cee9d039e6428aec45cee01edb8be7d041045c9fb44185e5eb403f21e84ea877b018d5b554109f3db4a5b387b2e854cc9f38c61ec2d50e386c753b0f79e53ef31c38984c547be810bc5970645a1e3c1fc790dd4fc0905d9e853fe51f25512376c588717cb9a4a39156462fb28f79d9729853e68ce14b3ba5808df5bf6686efd68b79a39f44514584aa516babb952b9ca89360b6576f75ae1c76ff1f9cb76ee6a0b204f1b10f7283b027a00da981ddf48193921f9c9367593f1cd25f44b41d5502edee85087ac6b8e1675108071af5c61fd8fcd7876a5cb6c0eb5a7695f75f0503850a1b217c3331c65bf154dab73028ef382a51698bfd3c53bd89320c0eeba07d9f7f9c41ae2202244e8715910f1c74117bc96901b15bd5bf9c542a83cca65d004ca8492ad1d5c95d747041804c00b0efd9b9603f8c7f69b4221c1708c8bc816b0d9f4ab913f067a0a449437d6ee7da3cc3e7a8252c58b484230b14c5140d2c5e5ee32e4f56b5fdeac760efe08f05e78d803e36ecd6c48ec91489e203682008241ff7dc008818664e40e3eae4c6d9964cfa16be15d501d44b372776c13c63cfb115cec033d9b5c6f7b8044e4adce03110ea1860f859a216e014eb9df27ede8fe97f128c3eee3d6d0778799fdc5eef92efb5b778d85615d8ae5cc0d40f9d8291078b87e486bdfcc364f7b18db7e9b333c5d94a91cd6629f6194597a57d8b892fafece67d57c627e8f0fe6f2af109e8c1b6d473b59b29efea81ec935fd725398e4e3a99d825a80693c8270db4c6fb26f5ed82202bd3fe7dc602c07163a8a55e4028b3b5fa3744a7e0f9c70350989dfea29bafa9aa33fdef3e188e539889216fd8c322868bdaad1264dd1e4e2c0f3a09ab686020b6dad5efeba6fa688971f36b77beb03171b4439d4fc111c67784755ef0d8f9696b4f0b5f6ce921b27928cac0e18727dd7e7cddd4ad0fba7199ab5f14c56e55194800d40fc9d66ac3d800ce91ed171cdc48d7d2a53a6fd7ee7cc0648bd0d61b16c7e8c03eef96b1a228933b1513f4b4c877ca02fb099864fd59f23baba9abc9916cc2da1ea7e54c1f13ee075665946aa5b6781148ff308e2d41d7fd046de664d5e8281b0190b2c1e0f89cf77fe7bc398ffafc7986643bf3c6c84b347a81296f7a234de87d9adbd3be1abe4d5cd73b49681da914cae19d8ffc979739614cfd8ea622a3eff463e2a16de4977ffe59e20cbba6e5ce51918e40c5d195a20560ea15226c8f6006ec92998ca77e3fbc3e54361d39500329cf6c12af8a57926299f79e073ca3b3825c051b1f156d5c6c38a7c3ace905cdd5cd1cea47e09663c6334fbe4fc0a35dd96f3f850f2f38aa7cfbc09f0c996123cd496caf3e8503ecac86dfcce9b44ea017faa85b7b306cb63eac4f18d618a53e50048c1620621f196acf146e89af50ba4fd2d40ac5ccaf7e3f2e6ff1fed21f56400658e4c2a52af3303751793998eefee0f278c59c01bf583aec3a0981bef5305ec3828993ff8b95df2ca5e633481dad69163abf24198bf43751b2c79abe9decf041bf36b8439abe3abb91b104dbe1052db4be6a156c9baba72b60e8e799df01e83a01d8117dc322a3b739d8180e45637f2f977ef75f8250dc207cbfe04fb1de233e6307e3ef09636aef8342da36d14bedc7bd64e1a9317e47d4f4b7e05f17575f52922ddc02593f7c5cb8d2ffe0b143fa76c7b2f77dee547575cc5302792df1ba23da2b42be5a64429479a402c023093bc890b88930786520783b8f32191f856c5552f2993cde3886e8d223d0a41f8937e09858d87178eab8b2ee3b2417dad603b0f1a1a3e969c5d53e2da682a75b5f3244065a0d9a30d55371e7066016c294006fcb433b62795b15ab5eef24c745785f9d6237e7f688cd9778f9283c81fa73a63f1e56d3e7cb3be29f8d536caf1d13977690ecbbfdc7f8b2071a688831619f1d42dc548b4a93dec670aaca055ed78a3ff2786894045545c94815dc667074e992fe6be31b0bf2fa7f998befe7c69531c4a3dc3e751c9a899be83441e01b1504f6afccc054e7daf3e346a3c6d59fe26e91c8216a8cc0cf36bd9bdb3d2601c881a83c6e3a328e59259423ff46bd410ee31deeee240e8d6616fccc9271fbf98c398ccb14eef09ae9230b1cb10c31920be42c268121ca03cec38040ae66699de5e9c222587e3f7d2033c54ce603e13eed7af036cf35adabfe773d052fd7827e6b71828ffd2d0ac7e5429a193ae239f90553f821c7ffef986e6c2dbfacd0f376e54ed42ad39728d93d02a5782c03078b779bbad35e3a7d5f1d710abb309042a6c179593c4f433a80a0bb643e62fbc992f08d86ea3a9e8bc6511d05ea298011ba7bc6d68a6213b066d87682ba5b16ecc22d040370e11b5ddfe2125d530fde53540f6f28e416a60f37849e8cdd8f8bb03175c0ff3bcccd7fd2d7502a5ce74f559c825fb5be93ea1f518ea06152863ce825a25f62fa799dddd9a64207d5184f0dfdce3d651be04cc63cf9e1a012b78a89ddcb93e10accdbe56aba59982313a0e416c5ef83e0ae68c50ff5e01aa9333d31402afa54703532f20ecc7ca1a61b2dfdb7d0e4d12e41b2e1623a9416d9d4352cd26ebe66242512a1c51d1ca49209be0fda4180164198285a620ecc182cdd0dca5ee084ded325c4c73eb13cd62a722d718fbb7d8b66eabb23c37f95e83cc8db68ccd1e52a3fabefc73105691bdca7bbacf7e794a43508399fcf8eb225cf918d1934b42e59dacaf71020a5a76b6fa7a38822d7d4a890434d1081fedb9fc0c397aab28ba420db32106154fa830837f85b4692854e9d440d25643f0a1e051e4f2b8ef8f62860c93ab3520565b96627ac70a83706ce6d9a30222111e16f466103f84cf9d3123ef500da3ef206e9aea22b769913b3801d441a74a84aff77b0ee9ef5efb60841d226fe3a8138caac2ed850a66bfe1c87e3e79fb65586a342484e0c98175b60b6c57f7486474769ff7fa734851792d63fa08ff54bda93270522c5f04afa1dc4ada3f79807986088797bc47d80e5ff01d2a12fd2a779debd7f9fa837655dd3bc779ee5499cd1b33c0dcf2ab34fdf55e0a82bfbdcd5d253efce1b2f6d960dc762ed921e4573730706e0a3091896d16eeb8bdb96e8f65c7c601d46b1dbdcd8087295fbaa01af43a6026835e83a1f4c43a46ecff30ce60dff7c1badc6a8c314f052c0a0c11008000618289846071f2fad5acacf0f01e859e78f6df21d5fcd71d0f1be83d76d2d5dc2cfbf0948c170993a65e62d7a55d41f46ede5087a93f3098ca362dfae04d700e95ce609f91550630212df80bc50e7fa3978f7d42ce53f42c6addbc9c6d077f73075d6ffa88b5553eec6a4ff83093370982001f5ead5615cd573aedc7f9476d747f0873ce76b83caeea5701071ac06f357d2eb900fb7ad14a37726f649c35f73e08afe9335fbb01503c9f0e3d162c5ee35fb58a5b63e331f26f62feabb52da8ece02b8b319f6865d465e9f57efe4e08ada9f02eeb52353cb5fd25343f32115e685ce8d3fbd8daae759f447e334a816bec2bebfb72f8d7b2c33392c207d81c81a9b672d17e32fec5dda4577068ff6367cd5ed1ef59ede7c92b91503855be08643f71183dbd7997ecf97dcce397f95cbc94bfdb6609c7398328aa805a6181529a135877001bc365ca2859234c03291979ee678b9cbbbb295782dbae5789f0d2fe7089a0c5cd8272fec1b7743bcaf68b11ebadcfbdbfdd0b6134bfd14cc3d5dbf71e88ba17756ab6b96fdd1b61e64d4b18bbbe9f0c589f7e0c661b39d1b257b88d17616505998c83d6ca39d1c4696e50bc23f05e98eb449f957258e553de5cf209aed1c11770457e3f19eca077f206e81cdd6907d88fd76231fa5d83c7ddced2012d9865bb3c66f114fedaadd2e31bc95b228008afe157109d3ffacd1cd757cb1f88b99882ee5a0537ee7d352e7ee71b15bfee6e67f197db4d76e52f23816eb0dfe999a6a1f685087900da4f99d3853f4117c730ce745e8e024e25494f6a0238fdc577d61e83763edb09c141d67df27f3648a067ae805fb0ebdf485ee8a885a1885e335531796f01d02753fc3ded3f9fa3762e54ea6bd5fa42cb005bae3d5c0a80a665698682e6c30b4116a1c24ef0c2318504828f93c6299eb19d5c6178d5f57003e448fe3c179452fc7b496af084f32f0084d385b032b08f0eb44d89581f4a5bb497e2773ee455d5f6d3c2b93fd71ffbbfdf00040fd0c99265ef4ceace8d0fbee333c1a51ac62e0e6907747c6cf8eec86a76962a9717536e873c07cf0c2d3d034772fe9389ae9c8920ec407ea6c8f6213a81b1d1081bf66f5c1cb238ebbbf2099810fd204691e96ae1c3dd8997915e91b500969c120136f47124a1ef50124cc95fc9f49e6db4a8b8b4a652046798c1d23959582484dc3bb4c441662fc730f2069f6631de546e83aa6a284bfafe30aa4d188fd3a9bf12af84beb159703f92af9672dcc3508a9ab1059756918f3b8d5a295b823e006857d5ac2a8bd830e4eecaefa31039ea4c4c54b939e895f35619818443d4d4af0b0fa6651d2095d050328454b6ce08957bec3e08397c6aae23b121c0b598e464505a3e0bffb9ce4018d619d5d7592c742268fa913efc12e5dfca3f25b73cb88e86881259244c690e08c288b02384831556c1d30339462e095e51172128634fa2dae00e3f52ab927b8a5bfc1ca3f2df072485045058ff29a95aa42d78021fa9e9f89ec3d2f51c20f0d0c708ef984826209aee8e71dccb87e1162c05700f7bbf1295cf71e97691c5f57c7050ee5d7695e0a68e8ed2062bd9db0652c938dda80ee2c2cfd8de436dc0b5e76c0d8f8f1186a9bb756f2cbe83aa739cbe34868892ebd11cc8513e5d730d39c81502e7e7859fda453c2b2fe6ea1f4518f93bb5ac5b10e2016279c9ce1c660e6c90445c1a54dcac27ebdcba2d670e636cc64e73d50c3bc35dfeb2a5bd8ddd6fd28cb7b84d6b361fd4cca2a0431dc6432c2c997df3e22656086f78ff2fb65a1264c5970cfa7f69e2b3e43589e346579f7525c1442c4525596c98d857c05ae7958b7ffa54e36455a693768f9425d892bb41f1a49e4eb6300725db003dec8f7629a63cdd692f775a50d269321305bf5087786f0524aa0bc12ac2568ca27e5435411a54de2e832f803207d388a6a556ea9007f7b021a92b72b089009820f7d6b3827e9b8b7c5f809f356a5eb780d16153381f24d492d2e8f00b95ff304dbcef4944bdb1a64d0f43c5ad180c37123e893612c4dd61d390e2cf41c4659b38e3846ff4e5d4d7277cf58cae35550e70bf14d855d95f4224cd70e6cbad169cc7fab20a340f504e1427bc609535c802f06349513abd19042b135b31fdabf51802d6dd1c77b7a1fd37de5c00cf5538c38e452b6981500033d690dd187a935632ed168468e2ebd35548188f4182beaecd7b65412cde7a8da723f8868fa691cf701b9ebc094d6b3b76f67756ce8a9fd14b7caf20b689bafc9b8a8e37db8482126c0841c4379ceb923b1cc2415dcc0b13e02e878ce261caed002ae8d14ff771ee8b0d7213f630d240096d9a681a044e22fb7107cbaa6df2de363a28187947cafa440d20140ebad983b748e4b7b7df6bcd12f1f445bd65e6b487329b9050fc82305e100487058ff5917292802c490c76bc5afccef39e36ee6e97403df4aa529fccc497b00a5d40cce9f26eb9850f37bb1654d009974ee7ed8950b4b47f8091f6974fc024a6e174fcff243001eb6b41411d3d96e921eb0b8000404a0b521aebae9815f7f155f6c0540dc00040ae0494191e0e646a0e784bf5126547f0c5950a74afd4802644f2cbb1f1da03ea7efd619c0e51ee1941a308d18aaee81f4dffabafd9ebd8592a487a09ec4c0d2f8c9cbe97ba03fc00c48995f0675c3c1ef53ec7f2548b3ab0c668ebab011207ff7dc6903563cd4cfc435eca454e050987ab3e5dcc8bf6da2bbe33bd50ca630decb8b46f5a04e022c78bf8a0ce2d409d8c5ac77a82b119137fffb1d1383c8027109b9415f42756216d0bcc0e1f302bb96b6aee7c3f946460be2a73ee2784a6b3c86c83689d33722609725c88f0602832da1bcb87d4487c75b107880f13ffd4876fd5dfa0241e016eb74259b721ae097b870bc2b16963f205b544416a3040aa1dfae42dfee86fb5cb342f681024d9d59effecda549f77871fc9fdbc4791ac9236a855f11e795fa65d112c2b306a4af1c8643a954fdb8019a117a02e3405ac0f771aeae3c45126fd89314a1fb74475063b795b6d9687c13430caeffa3c63f5ec164e40b7b07799ae9019445d604802d479f0ef387682d70f5b5c7da91f1eac15dab5a943eb65c6fc33bcf68bbbc6688da6380792d7569680bf434938e2542dd1948ab2639dfeec8fb400d5e58d5e3df035aed3510eb6702a51f65b43fc641771a02150e4b9f4f9740d2c8dcdb50d82c18e5400681418fc04260a19ec2da7909d561be53de21c65605cf79995c1d40afe71364e8bbcd896eaf2a248cb189153572f53e00db2154b7d0a5d34b6df73c5a92a5cb77b70c654a567b67fd7abe07acfe6a39f53dda3891d15caa829405e914a099412f533e1efab7a11a5b1d8dbb932d074f1f761e6aadd5a0379d85ed371d6cbf1be84656567870fe2a822e4185ebac455d82ac032b6b403fafaf2304e274c1b00007e63c018fb79a42c575203591c3aa19144f6b34c40273001e885653cce0900b47c592f1c360c9a884d4626f972115e85ef89657e089b411135c8521a7c3e418dc383969b705b58d6330a907d40f54152c7ebad4828632dd55421ba178ab414b8009dafd8ab92fe5f23938fe415ad63e27349b788fb8364fa5f39b41fa4fa447dd554eaab7d21311a3cee53daf657b4d97850839dc39f6bc45a41a686556e251dd48125f899c1fe7678544f08c2c5f00733631062d70a6a9114afcb801dcfc3995a7e5969c34d2d29fc6d7c0af3565bb7b3106be3d139b3a4e9c6d2679e27f1e9f7cd2f73363c4dff93ac580bd3c2dd50a415a620272420f6772d7c8d3a1f017a4a03ea095df1f1fb09594d43967d36d4a47f78a6f6b2f2366bcd09a02267d65f237b632e29ececef168775c5e07986b94d2776e11777c834f020c3d5f6764f6ff7e7a51e89403819b1fa3a686695d98c7ae5a0cda21068730a7e8e1e21929c97af4cee597b62e9fa648dc6455aa118f88c3e6738db1b43206f1e162d36f68dd092f05500ff8b9bf48230c2e594f589f4562d1a5cb88d59ee31c459cebdcda455066f74fd7be7eaf43f1c709501388b34f5e3a5a17f2a38d6142e8e4abb96b0498044dfc461e88ce418c47b6e92803b67db5fd8617a963b417d7c08a77f431dc4b28475a4d49de25d2861983ee03b3972659eae6a7f9c6008b4cb2f2184ac8960d16b7331fa01a011f7b8a2d44f8c5ddb317be9a03ed86d19ff8b5fa020b5e9b32ac28fafb4daa754039446102a8def0d8e5ab127f8902ec9b3488bc54b7d475968809aa28c145dd1f13ad2be3689d19b24c7550433b5d6c6e6c962e276d216bd8cb17ecb0acb54bf50c92ea7dc0905441ab0ff7bd29deac35eaf0cb896effe3a0563445ab84d963d60e7b0a1441fd7ac1a372c9090c1d608c9668a5581c3c06b14e1316a5f746085e6876f16c29388bf4398b2b92e9fb0c0bdd21a42d705021c4ad2ed10436da83a09e99f8ea8275f96c8f304b9d336064e555ac1c8074992c742aa23d5c0b06e61570364dd8d64d8ba1c21aabf199f87eb7c4c646c86a1447f9627b03947e2c0c67547e201feebd8986b13108744882dd661b24154f765a1312d4a12fe8212455c7b825a665c0fcb6bd306822b8cf2779cf9b3424e72e1efeef7305a0124146e309c0e6cf8d1d9610021b798e50e8860575fdb0afece60349e704f47959dce7b8b061f93e496eac6c1acddd4e9af441b81469d202463083daf14383c7eb2b56e5ceb8a5b44f3482135fa6c7befa2559760cdb584cbc03c630025fa03991121c14e7070b8251c295c5bfc9ceb31810e92ef200f6c2c1c1c570cc881444c5d129abb4bf2eb23166a389e76d60ac51dc8f09aa25b9774e2c59636bd60ae529632b324600f93fee8edbfc199a310f4a016b1372673438a653d8166c1339f3031d4d7fa468841060ad849912d86172b4922d10b00dbafcc422a5e563199277f866439dd6d60c5ee1164bbdab3735ca18ddfad168b3b085a368a83e06ce1470f7ef76a25aa53408c24158fca54f7c383f00052f07cba12247c0718a1fc91436e4359cab87e644f7143c8fb9f51c018c866204b2de629b596d465f0a0a1c9ff9e7dc972d9677a064e87c9bdfabb2f18a48075e42b2b53a2b37a61c21ff01bd1aa3e7b0a1279fc127bb9036c8f3c86114921ba930c245e55359e3280e3e13bdc4b7c885517b07b51125dbd1676fb3436ea74ddc8e37da24b7c8e12f8392f7bd2e3e3a5e163491b491f87d8160654becc32e85744c231040ae35fcad92ea8a972f13871182dd312a5c74ac09bf2a5d9a82f20a003eaa86d52940397c060b9d9d3be6d3df86818aecb03aa73abb04c6b9a99c5a2c489ab0fb49a84321b95759dc6d7406ab0c47b912452f5d3933cfcb69f3b66607408a6a0a0464fa8d87bb11171716a23a5af9b721ccb250cdd490515516bbe698132f3d6b9d16baf29e22d316a25c431564cd8e84a072f2c0b76fd325168b54651fcbb471d270679008ac61eb63d8ffe37e4744f0c25e955dbec1af1c1bc26ca79581ae0afb0e6aaeac6f307121714145aa1b89b88b87df5288bf72d67e3a2b13b49c4dd744ad9443d781b87f4a87bc52a2c5becb14bc2a6c53feb65ffdf9e27105a69154492b39c06a9cd4e591e4399f8dfebe4caf6d6acbc8d58182c489a0516fbc012491a8080418218ede8efcdab3c79c4d206ad878b673ba0d73d8d03b3d50166c2be1ae9d0763cb31c844631856be8cb679b41db91fb8de2df4801884ded10e1d7a717f162fe0e98aa591a05d0b272510cad53212124037092e4863e81321bbfce00b8d634a1c4c405c7f5f7d17b4fbd09af04e0a86629cda631aa4a645626311a450ef863afde4d563456f037c1cbb8976e26244206443612ca22f62737ef3adb35fc431a5038ecbf1178d88e20944bdb8d0a0de69cf7831f17e58fbf83823c613338ef24b7c05c81bf734664d9f14de44b164afc38a8b3abf7496b10659f2e9dd744a2ccac766759e01b79b3b66184b07f49be273493787ae30ec7fe73709928ce07c863131f5da87284d8188d2ae6986b8fd963dfa01ec76d517e486198425954c8235a747b428b24bfdf0e47f7a37dd29a0eebe732bb20d74a501967aec8f36a69d03ae0c9e3a1ebec9531ef6e8f511d12f586dc311febffea3de0e8132f7c8b36bc0ea0a99b6a13917feee9433939d4586b8c80610bb4dff0d9e73fa7077b7d9c0004c6f9267be79cc6682f9467d81f45ffa1c7520f67b8d39053dee40871273e17eafdb20ff5b8ca0ffc612cf7acdff88d2ed9ec3a48d827f69581b56c5b2f04f4266cdca006fee7ff7820b691de6e55397ed36e73bf0b0d9356c10c57f8b0caed09df01bec56af69aa78a5af2d5af85f555b4adcb17d84a44c520b98b48a26f43298931c78764db1d1dc29ce285f9cd5ab88712ab1e837700c28083293d56fca0174f40e7fcca3db32baa3ea37c6ebe48e25e28d6bcc2183124c4dea1a02b80174f629935193d7110c907783fdace87ba5ec4eb5c3cb2741d0622599649a3292eadd20118bccde5a2bc7897e67d99d60bf5ba8d808d3116b5625a258cf1a8226e11ed6c1378c15a349089300d88f9756b04803db0cb6fe03bb45ac8f84b32f14efe51479259d324148ffc22a96f689c1532a5ef7d2525ecff4a871abfed8b1cd9a3282a44aa65b82779161c874eaf9a8cdfb39c08462f669118df365cee8a6159db22568a1e31d954a447ff487f0030ed24c37aa10f06f5317d252baed0aefb41966a6c66302c65675de6561ff22515998412b22653f9aca04d43b96cb7d1f5565c93a415c501f86887ddc3ef047b6a76278068fbdb86ff9a379416917a4e7c060379aa22f9f63b0083c9882c000df2b2abb2928692e2d07ae5dec70d5f159777eacc1b3fe4e55bf88e679f5dabb2c1ca60b0a781c0f58dcd01f18d39198dc931908803a6fb11d0812591c10d56263aaee0686510dda42373acb5be6b5233cad566bf4fb2248e36ca181a319a378e44863c1d1b72de4859679a2883177abd8e0fe23a5b4f02f652e0fb6408d304ef16f106d5d23b8dbb4691841452807ec2db38580bd82da36e8368b4806192ee5505716227574a9bbc9071c1370b292a14ca3c6d9a849c1f302cf677176441da6b0e09608e5e246e2d174fab979662624dea70ff40349d416b59e9a6c276a906c84bedd15bd79e63585916a5246b32ef474923c5de148c5ba51fd679d7cbc4d32e9f35c0fde99eda3aec46532f1394c53ef750dae421ec2102572250dafa936ac9d0d675cfd951b2def55c4e605291b28132577a08fa231c0d39493b08a0c8db96a7d098a5cb1d43562d97ebfa2f2dcc98a2b2369665fc96080d7f90adec7ee33b32562dbde1ddbbe544840b5427444d6e31201e1db12b2a131c8f2996e47b0afdfb09575523c2312cacd488e2d4934723c1c0a5ba6f32cc3d70b71b7d3da6161b09a68614f62af228bc06985efcc2f9d44b7722ded66693c25fcd1cc09b19939e24f8c0658536fef69e864bc7f40a69b826a4263a1e7fb3e41bcdc4d0dcc803cf511341a33a0aa967109accbd1c67e40375d1bde7292d754c7bfa3631aa0aca3f5f7d8986518d095f5879340e10180785af8be7bf8a41da3e733444b725c2d559a766516a0898c28e10f8cdd750a271f72b005c6f68abb9dfc0c50f2f660a04ef67e48f56a376807ed93564d61797d32cd68d2ef751ce4a40b04c4bef608fe6027427d231308de03f886c4cb03dcdc1ebd51b30a22505d13fb1a0017524277325cc3fb260f177136ab229a06b61449607fb78428901c08c91302415869f9e7ce379a4fb42fd8055278acfcd4aff1c470ef53833b615070ba80787bd346ed6c090a1de8e509b57cb7ef6d09e67ff9e2bc9e00ee7de3a728444eb20c6d685199f90114213b1c72bf8ea6451511667110f188c12e2e14f9125c805d161e67531d31e47b10091e225ec581b2a4390ca8142046bb8f087bd627bd690f66e8a9b95713708c0a6c6244477b61b92752e178b4bf9ce1bc044136f108e60496a0738e36e1c08895e043a3f4cebc7a38c5bdb17b2f959ec1d05cc90a208eff54cf0fe0037dc0d907f04c2b78b2cec92517e4a3c6ef3ba08530da7ce5744634962c46181ebd7a9ed10cd140661cdf43c054e114c2cb01d73c969f64ee1fd216f77fed4c162970801ae19b51d781fd4804a8bdd0335d4a644b02d5e2ce1f237e83b8cc9ff684abfab59ab7f3cbbd736f370eb3116433fbdf3c1a95088a15ebebc87e621e1136cb38ccb6fe4953f34b709a0f79f6ddc8a843f3fc4a327aa9dd0d0d833465bfd821aad4cb07deffd24ee98de01364e6f8d83040a094ba1f23a2af5a967d426c73f9c020fdee5a261ac2a1af29b9ca2e51f3c6cf222455135d0f38bb5800e37606c2e450b224a6e81116b4f278feca2691b557758c0822cdeeaaea2070c84fb8bbaf2b2addba66d8bbb95d5510c97f8dc1773ee6e418951e5e31c1ba15407bd161e0a0b6dd789b386559d745c4cc1709b419c0dfb5236906a8ab56336a9accbae0c04af06aeedacc4e26f695b8234b26e07cf5be2952a318c3786652ff664bb58338ceb9051d023173668e7a56dc9cb11c22a574394b59b224f9bc2ccfefd895e4e2fd377681e6a2802c4c7d774a399bba0159079ac4416e3be9337a7dd29ee427e2b21ba1ebdc1f0e7c3d73b198de2f217fa368659b49c27f99440d1e6582300a7b5d7aca57e644bba3988000f1fc02041f29700b933a44703bda51b1dc8ef91fd309d980cf20183353012896bab3ecb7e83b303854c18e105e8f0f844dd680f12e8239b868c7d83cc395d3949bed6f0aec0fac4fe969e4f64ec990a2dc3b73ba54849f9684353dc5b4a2c94e8a04b0592685bb84ea174c736ba108b015d9abd508ae550fdfa9b2deb4c57eb2aec2f51e151c2b145282ea9455716315d2ed583a0daf7eedad32c07e09670d4992957236b953dab6be3a80e84bb1c5b3d73261a778f824cc17e1ca2d1af8c68b3ec1339fc8e1399cfecbf07a38f18dfb08209e9ca0451a2b55799058114dc33f800840562ad2ba95610efe35be0174c18099ea8d09c04ba698ec539a804efd86f781f32fe4a7fda1c73d082bbf4a1aa81cd212004a13c330fc96a4af0715cf7f50d1ac442e8b90efee38e7f9722ff91f7be7c73cdfd87e11362d85f556657d8eaa7578b0cc0988ff9fc9aa13c22dc202d78dbe276a7578d0293fc8de7bed3dbd0ebf39fa38fc19dd16f8043dd07f22fd5bc9f5a6ebce6208c0218b48bc1fcef97f3a6bd4d277d2a36de93468d8a59d7f4890244dc176dad737322f7af211f7dbb7745069db6d416d7919eff7dfa20b7e184c9c188b6f2eba5d30be27d8c5692a7c7df4a539a6cc0979e77efccbf44566e13752401edaf3fceeb883f7fd23e6436ce4b018c1745bd5cb976650e7ec9f6316ed50d0a718dee3ffe27a8e31671c7565c12f98f16d79c1e91a5eef4df38c5fdbb0986173337affcffb013b7fa11a92f7ba77d5ff957a47326a64ac6bafe93d9d9ba87d6d0400cfec6f873b83d7e0cf38ace2cab662b141734ca7825df1fa0977f9d2e3afa10e603e5689de49d8635962d22587aee7f6976c6b501ee2cbe7cf7735c9faf9dc92db6a7e98619af520bf3b0ef3dfc31e872502d32c5beb3d741a98b9145f1dc23c9be37cc34cbb331836d79a816804f897e7d887ea2ffbccf3c8afa5cc07209ec43d85ecd0df6edd55ea5f99f97b994b1a7a9fac6ccaa1f1afa7cb5f667fcc41f1a376f42cfad7c6ead2dfb87501d653de57cbf97e2b3cc679e739c11fe7a4c141d2fb2b8f5740832e5873f925bb9f3cf383ca0937b95b5fcd36df634e8a894b7b5f0f467467827b8be23378a32e7da3be46a9fac76f15eda18d3109064a0339905ae765db253b1a7e50b9bf43ff541fcfb7274dc8a2fb84bd8dbf14cc603d7f62235362e8d6eb020a405fb33c9fc38f5aa81a6ef836bcdf515985af1a19e6fdf9b61a3b29a99fdced9e6670cc7e0bc6afec4fac87813c02f1cae4c502f7ec18b507510f3f9181d8b39bceab62fb836ecf83232bcb796c2459abbb370e4fcb8fa3e0c894d511823c22596e9fe10efb83f548529be75575ce72a2b8d3d977d1c4f7bfb6784ce48ed73ec2b5e3f21428b64c86364932f46949f2dc7bd633beb9c0c5b5b55d71ef3e66cd54d8c8510fe6799f817af3e703fe9f4b0ea5a1ce06470ec7a1673723b03aca59d074a73becd4483b0fd4fe2a12de1fb93d8c648fbf5eb353897b6f832cfe56884bae385e1893281babc95048a7d9909c9ebc5e70a376a8f28f4364bc1a522e46ceae6d8c54751d64793f1e3f03d21924eed8eb31fb86eb16726ebed0fe00c9f9fd1807416e6e8c5863b8f84dc20a0690cc8033669bd20e43fb5e05a948fabbf5f6704c00d5c323ef4e32680ee891f9109947caf421e84d5475aa268f95b67aa1da90da375898f518e6478332ed2759fc801590622705b3d4b3cef261ee6c317365cb990333bd6c9efd66bc0c3e2b6679592313cc5a9940d6cc84b21664fad82cfbc9f8185c56c8728ee96453ec1fe364b0b012968b353021ac25661dec3764ee0cdc26d00493e017e00370a26441923c038bddd441bf25b92cd69aff67d5238c8ae7d67b896f6f4da6c87481f15650a3858b4e2fb63570237cdf2cbee9f9be92fbb61c4f866fff5553065f6ec2c23c3ecab1fc3fcf420037b28ecc36f28a0d53de3cd98b2b6292027e5caa6e6419cdec3a0d4f4239389f6706edb22114b7db5198ca3606b00f4a1527efeef048fed372ba2a1734f07b43020679a6b2ba4e71207112929a5201e6c2af09163209989c98370f1af2acf22f37853f4d971514ad4ba32b68d5d392113ffc38a774560b983763d746daf7bfdd1a34bfc906241fcd27025408a308bcd51a7fcabef6783198128a6ba8ea2ef5425c08b377054794bb0d2edca57220e5820bf18e8afc9db0b61df8df3dbc44796690044afb4f97b39d701ced60c00c925f80c04f53319b5d5c4b84d3272a86b18abf3bbcbf7d976690594dd795f5261fae87f8152e7631f4aac6664777a3c62a3300d44e92e60acf9f4c637928cd7d03415065ae287e8cbb04d4d8319ce6fa4092b74a791a49bff5060e79f2c3e0c617dabe7ad100dc1208cb54d191ef4fe95bc43126f1afcca23c705aab2d97d8fe5f8177534eb7111f4e38c8b18814bd74d259d599d465609b1cba788fa2eb56d641088c067c8c93ef2bcc5c31880f506c3b2539b09847c047631e833d804684b0cb6ec3929dc5e18b44fd5ccd4f2e025c62aa8aa2ea87041b7ba5362e43a4e0149e386568a9e8e6ed613386ef5b4cc97da98f0a0a9d8db75c0e2594ce67423b423f835a8a4f1a167c3b0dde26d0f15c118a3e54b027853d74e281573c1ef6d91424f3716b9fed3f0d9e088e0841bfd285ad9c67d11f8efe28a2dfc0e2bd8f23c54ff4e54cc59f030a6fb9a4043ae2e1f6e8f3b197270a43bfc048e53ec44f8e2cc941574fd1c9e98676bfddbf9f4207c4c4d6aa04cd8e7c7fe774af9f8dfcd4b6e61a641baa9158f237e1e0c9b4c66b82794620443f39d9f723d0730db5843f7be2c7259f88a29ba8ac389cd8cfe67d567b43e5507836676e0d5aaf25e3c8537c82692a280158996a0b6295aa58af92b30094d911ffa2720954b895085ef6a3f6c719cb727ee82b96ebe577919f76086c603dd769e7284f3b76d99b1e00310d0adf3e08a2dae617af2dd971601e6df9f8cbfcb1dbe030aaf0cae083a0b23b806b9d658fcd422152db27548960295cd92cbe71a4e3ae6db55732d7719135fd0bce7a830016bd2bf7f2a96f2c0d43e9b515f900347edc427e5be7486d3278303c4681a000471e463bbd65adc92135304c90046e2605f1104b1030b33807ab991ef0d4c00f55303598eebc5e3f3bc0756c6e169f9af266f0a791adeea5fa2b7d4a4ae4c69889007e74b885b3dee0b10b2525252595b2a88b3d46d0e64783dc0a82304429461462125e0e14785f82764e5ab208b9d06116ac85829c28ec98e05b2d9de22824f915acf88e8209d4c2becc592d2727ecd5821d80e76541a1bc8a7b79305faad3573cb0e0bd9b03dc74706380f76e3878ef6683f76a0eb929c07befbd9b271abca739af39add65a6bad94524a29a594ce39e79c73ce29a594524a29658c31c618638c5042092594504209259450429973ce39e79c33c618638c31c6f7de7befbdf75a6badb5d65a5b6badb5d65a2ba594524a29a573ce39e79c734a29a594524a19638c31c608218410420861cc39e79c73ce19638c31c618e37befbdf7de7badb5d65a6badadb5d65a6bad95524a29a594d239e79c73ce39a594524a29a58c31c618638c30667c6da553462cac530ba50c529ca752caa0c92b6130c92b6180c82b61d0c72b6190c72b6110c72b6190c62b6100c62b6150c52b6180c4051658d0fdaaafb62b49ab5696d7b601bd7743800c6e3078dd055d57b999e025699fede7bd9b0108e0dd04e0bd477353c18d053715bcf7b4ee475709d3d22fd8eebcdfaaced37d925e9956ba6b1fe4392d3aa50a765ea9829a57a2408df75e014a202101b944c115af44417f250aa2bc120514bcd2047fbcd20465bcd2044bbcd20439bcd2045f5e69029c579a80c97bd28819ef49235fbc278d5cf1de13c04af3cde7b4fd705d57696d5d57d901ea522f4e554557f11cec054b7aa95047dbb62a4195b574a7fdd62b6ee3b817a7da266d6aa9a2207996eb7433c18d132b59767e3414501620200da5f90c59c98205d54507cb4b1b69d7c6b97cc2a060a4853855cb1f6d4218c6f2af93d1b64201c34e3ba59b289654f25e134a9a90a07b4ec3c074a82358131ca4adb5c2abf355bef63eaf6d037af99e5407d3e2cac2559c67c17eb4f7596dfd1e1344dee338adeb60af309ed3c27dabb5f14e65258ce7b4b4542c39612c582bb682ab6413421428346f8e2a4a35266c54d76957133ae6782ddd52b1545c89e690374789c6f5de9b62c67b57de6b52c604dedbb242b7d22ffd8fb60e0513f44b7757b7d2af16c678efbd266284f15ea75fdacaa9047dc8d9b90da9ebb496d44b37e9828bf71eae5dd75570d55534202db80605bdd755db16dd75feb93097d8f0defbdbe6392d9fdb82f29c8bda9c1ccf6dfc694043423a3f3da7208de81484b2a2119d7c744e405a10aa056d05d4cec9a7ca90166a090cef510beb5edbaa7baf8914665edb2aa89234baa76411974be73c8eea272d2448f9adabd0c02441e23d6e5aad341215935645a7ca7b2f0e852826291d8a8a5ad86b5b75dd6b5b45a1166692422d0c0affdc16d4e7c2441245dcc203b48507684bd779a32782175c2eedea9e9c301b6118866584510ba3569505121b541bcb88ea2009c0a3e9830a1e5e98475c783023d5eeb9392104abf7562b1b8738af85735ecb1c22745cd6a138ef7a128210742943ed901321de7b3d2787db7e23873862e63962c373c4e7bd9546a94ca8ee63aa8f72753a4449558618a1e259e1609c6f482d9d271f88e3035dbc264338e0bd15c7697c5bad74768478af49104d8028c1043653d4a050a3000ed0cc4103078d1b344f24e2a5e3b2ae3df73240e490d771d9a67a5e60dc87b55e1b06230901223481f46188217d1842872155bcf7562b58cb94e35d492f437230440c678829478a1428869c0c31b558b0d5c64d26df52719d7ec57ccaa48d368e8375beb5ada2fc966a0a950598b8cdf4a37f4cafcd088ac9d4b5fc51149e0821cccb140821847981e2bbaa052b0261862f528a728a8c5a9ba9a539ede2c9a201d147941694244ea3389de2a84e95fd95bfa4090583387922480f4d7e68e2c37b4d7a78af090f4d76a80190381ed1419133656ac82286049890c56bd610e60c211808614c941aaae4b0d0c2a10365d41000123a1884c9106368c04348100fe8e03c40031457645121051702a181c5c70a573c08d8d0700731a187072343838d0796e42446d0c50c721471c64b94207c664002a949171f9c40c10cfc01476918e0881266a0a2258b3fc61149649824005bc8e8207943863628c0c20d3648c0328c71e2c3d11c422490a1052aaaf06cc0432432e0e8204713629aa06268e4a8022f28c13e319461c58f062c40089e1874b029a4c68713361083963914a93947e81183010ad13e18410b2f88214407261d48e9a9418c17d7ca10c2ca8b8901881f8ab0169b189e094ab0610a9720c46050a692ff4316aea43de81b142089c19234c518274a78c0991392b800f850a9a24c4c32211002d4f09a3824dd7450250e2f91d0c436204375a9f082518c0908f4f0c515508a9891153951841e2123263f70e6830bd69804e992530ad49026bc209dc949828d4568e80209025b033268480520a16c84a650d20017129439c20041850c5198473ab000288298e149980aa8e1070c62b419617c30220404677ea884110a42409732280411c65485062d7c2eb90396888d2581688001476060cc71c90f92933460364ce12b7800cb08a6421476f8a1858b0a604fb2f051435701135e8058e0855ca304fc8545cf0d89680089265eb00dc831f412b3c14b0706868f48ce68f0aa80110f8ce032c50edd1d5d04c122098849f7c41f6280f0c68b8e6ea5041a4c38a11b3a1b08a4c3853019e86a7e84e8644055c065408518142141c4823ba275011f8a80c4076e57e0e6899d48ece0a65cc22de1842341604670c91a250e84d8030c1b92f621060f41c038408c322c21a28523305d1e4025ea68b0054c085588a0c6e303031723ddb6042d0211d704a228e0091b5708b972302962854c0f3b2e2d0618a263863c878b0336ceb0e18c971ab641c818910156298ead8b19343038199cb089d94ec268d2802236ad831c128ec884d92e08a408109c318394961e4c3e988104da8f9614640c3982921b6a68815101c88f4a8c926895700502e6146e8856930fbc58e387352c6069000c07d412e470b1c80895cc78802085b0be15585ca04a164558f2832d394b7421ac2ca909618c2464dcd51b149114dc98c48dd503c694a1047e4303ab2f607c61c30116e0b01a810d1a6c0527d4a3476ae07861eb241c5100863e2ca9a1c915473d0cd510e59119474148484002650b3c4a80086aec3045233e301ca2080dd641080a60f882113ae59a7102430d8498aeb4d0a483e19403077588391a02060d545b5439b3c502d51f4240a4ca58b9437585c98f006420c711d5cb900df0c06313a95220e38f2cb2f8e14245811a4662b450c18b14078c74a0040d0e10a59e484013fb122b5752471e03d7929c00a4aa224ea460a0083c52343dd4c1c50912018ce21000021ca10247112323c04880689103f860a42171001721a86087919432662004005676f89150724422303081ff1adb0f1098d1c5245f08184a3008ea86213e971ee21043027258f041a8e30e4986a8e0040f82045080888698f66470e09fc4490ef10de8c9e10248de58c4ffe451c78f50a781df400b581e3b43ec7441d018c11fd602dbb930a2857fc61f5b7a92a60110fc22d6addc9dd7236bb8d12f9052471025e504efc01f5bba5449e1126ee68b18cf124692bb8680c011173aa8c1736a00d20881620e0e0059c54de41029361d2208423162ca612f0102024a40c8b3637b300849228767c58e5f721043c7e3415372a68e117c412dd06ee4ec4819c2cb1d9a8833150d06cc10d35e3a1f32382881442b600d3b44d82a61a32804354c0e2d1c51538406085c72a038c244110f3f59643c8ce0451190145b8070020892a20370808b06c7181f4019c2871f4713a01c417d51004218c9f96204140d4144b1c1174538d415170e49839ce1028a0042d44c8b115cbce0c795a192215c6a78c18a2657c42690411c2fbc003034a5488f3b5e488189151c2c3260f1c20465584d02d1197cb1c3062e380c03c0be94f9594cf9b2451b5f6038e18f2b111884f5855e82a5491f5ab87c7970b836b04297e405037e1820910c805cf012811aae98a1a3870c5eb42c1301394ed0cb0272a020085205161722b1f1728818a6135c50838c0a416d1472840b414cd99940091404e1c2961fc81441a584285c00c1c90c3b5d2ac18168110f6c00b830a509a2319e747065c0a1810807a42b93c00348222c405021020ece64212a00148bb4a1411906b410c82168a8aee0208e16b6d0a13280304368d1428c8a2085249c232dec784944912950d4684100946010bba253bbe471c6036e94a1247489a28e40b00d51cce8b24d4005c9ab62812e597f30e6d5a32e4cb080d1cd2f8c70a10385282258c38b20b82461c9001861e2903fb8740c740a28c0076ce0029f10011904c0f95b4840e68c16c8c839618b0554803d6e1471c916229c28c0890d5c00c716175238218e06fc64b04584382e39a1e6218021475c70f40510800143661882451d3104606068072046f628da008a2116f478a4f405cf21431e4000013f9001a6132a648f0d5a9340e2454802272d4428828d198466a8b205143c389109f5a4800823fb8820944119137c79c38580203e2281ed3cbee0415448f2e5102dbc6409eaa614e0035c66b02008852d82d822045a8b202740445101283f3840754081889f401e070072e26800134469e10d2015081cab8c2d3210edc00114c81c7903e8952a80a38b1a2b162e70861f58a851c5b050c4111c6ca1249c61a1280608066c0cb15820c1051a310030148316113c5142122656b69634fa780201cb44075a7ea88411161aa104a565e80811f418814a0d5a3ed0c60844870a24914511282a4007074ae04216313a88830a0c922865b9818b3b161180061864f1f1018200a7098491a5140514303b8a20e227100f6e18011f3b54fc644102551011c816fc206565dcc1c71b27fc5401e20c168338d17f0290c58b27070927b0e08146140d9c11c30116282c31430099921e2caddd86204348c261c1596c1061c02422c062c3a978f89a089f390e0093c245a6031f240679e1008f74f1c4872332c8206b3c62c587ca1e4fb49890c15a619219b038c244119715dae828100d8285002b8cd11203d17282152b107180080c1c54a2b3020e203cf4a0c105e450a11130562b3e5a28a85046193d1a446006a8820e7a0361f8b0240d1558e8400016a0a12ba142072fd0e0040339439c0821249679e24c77f2228711be00a38c97930c4da4584468ba71e2391aa3911d2f4d9c3060c48d16e698c1e7ca1e12b823920dce245d994204b136fe28a3af705f48700dc08121574ee0511c61c38b14576e70e00112322a1ca0670372d44142e9092f7a9a2800193b5c541df4a43298648e2493203db38ae6dec08203cf25742c91481e32d8f09c99421010782e4086070264841106005a05e04109c1480f4ebac0e18982420bb94c10896890c43f4850081e1f68698c60089504647083e64307c00c72490e359a9016908c216daa6602820429506a88b092486c27a9034c8061258c29356f00a24224566c68648e265838f0002b2b1860903b0261448b95275c1c2016461029ec00d2659022224e783b58a8c132fa39f376c2502e3ae451e6ede8b09174ffb0e1ed5870240205d0f7aadc71461b0818f35e15282019425278af0acb00454071af8439e4bd57a5a60cca94810cf823f0c8816740c77befe96439d890822430bc14d8e8e1a530440a29b4f052c0790c68e4bdf7a885c909c3b00e14bd6792d2012daf033083f79c10f2defbf29ee421815eb3ef9cf741e4f17a2f0f2f795cc9c30416ace5f380cfa5594ff2c8c3c97b7840f2c77baa160c8f131e679ee9091e59bc2213e75f5c733ac5f108a2c8f5de2bc2c30b1e41efbda2229351aba5fd6adbb649bf542dd8f67225713bef35912186d8ea74fa1d493c9ac9297ef5da309af79a88497a2f048e0374c4c2bc3786035dec18f338a22776d8a15d54925e4d909a84e938affa1d0cc8d4552bddad563a39394fead0e352f1c1174f3650890682a0038f2f72d2116d95579eccf114308794879ac38d189cc38aa792318353a670dfa318bd277298795d0439b01c213c91a3e6994e30c164ca292a8a5be0960cc0de7b35374de2e8e1491cf8091c87e89449b3fc4b054717efbdac83ed277070a62e270c0e8b0140b257a74d5260dfd4ab743addb3fcebf4527149f197ae8201d405da28c13375da64c219ec79e49657cbab784b276e7903c78b51756e44a0c9d6a4c5f262545d67013016d862012baf8d36da38e3bdb7dab6dd3d0ad4729b8a73a53abd6a6dad967675da15c4061aef3d0e0513c274ad4dcb095b6ddb5ea30bb7f12a6a54f1440da297c13a934efda811c27befa561c47b5c960ad0b1d27ce35c2aee817a90b7c269df7a2f0915a3f6d47d4cc5c36d2faebfcbbfbadef22b95e7dcb6ad3e052830e53dfde39374d058e1b5ad823c4b25e46160b42b4b4b757446236744714696977df1f2da569d94de521db9e025eba24ce92dd51194a2de521d159d01cd882269d53a79ae5d41da6adbb494e15bde95e5ad563a2dd8e6626d3b9bebf57f541398f29e5f6d409d9c30324668a9585d87e3fc6a03d248419c90d04b55a563f9970fd35b3ea8b5a9c4a8ef89218067ca61b19e84817aafc90b5fde7b28974be7e4e4e4805183add27b2e25b482ad52a7826c951b92909c481a284e240d04279206ca1249036189a481ae44d240562269a02a91341095481a684a240d2425920682124903e588a4817044d240372269201b9134508d481a8846240d3423920692114903c588a481329206c2481ae82269208ba4812a9206a2481a6822692089a4812292068248fa0b0b9e046212f0e205225e54f1b2ee8598ac53f9f80ee5c57c2f43f23f48fea70b46bad0af8b8c0b49de7bef091778bcf7b2f7de08ef0917483ce162bf37c573ab6ddbdc132e16f0325514cf4179f9a02de0786f0b14e484b986b498218b04bc275914e03dc96200ef491613bc2759d438e1364e4ed87b4de87b4d662b0be7c3acb6a08ee3362cdbcff6238ff8e61361b7da362d3aada1f79a506992bd9c9c2bbc7f6d615a4859decb7969939c3093e9b585a9628a96d6e681545ca898e1bd292889d94aa7ec3efad6f6e38358bccb57717e4b90ee3ad7562bbdb3f9206d3edb86e2dd8605a1bc9cb0eea5da39392a9786a1ccf0f1c48cd013331ebcf7f4b6ea90ba56cee6b61ef331bdf2401aabd348497e059d27c4bc67da562edf5b788249c76565d828d3c57b9dcaf4a48c9527652e78e2c49828a8965fa15c2dbf42a1b8ddade48475af960fe3f54bf7265a7842268f27644c54583c8662f1d86bdbb827466809704eee67a49853211c1e201c497f8850453a9aa7df6bbe67ded86ece73eac617ebcf2ce33e4cb53f44a81752d0fef4f7c7483d87f8cf6bffdf50d98701dafd916ae8b5b6f046dc51d07495dcce2c2f8455d2adede9042d478d25ced2cff9e5853d75236ac6a883b383238423e483c3fd161bb90f33b39850e9be3866dae5d7f0de9eba91d3290e635209514209adc63df26b73ffa91bb95787cafea5e2b8741a074a180ad71f2214528e666dbdd14f19fd9fb7fa9bba1125a37db1feac3f44289b3ba4fe626f65d77fda78b32c93f4e368b1a4f65e6969bc96d69b6dcc586156ab4cb3d6ea0fa5de9dca9eb94edd8823d48393bd583fc311f2c141b55477722fd7f4dcc6e90f114adfcc461fc6af5031cd4a4035da56a8150774c239828412a5c011a844c94c53449022c2026408247c1025428122c20892b57114d75d0584208208382184400208dda3bc8a7b91f001cb143df751dcf6d21e24e0654240940378dfa140f0a083d2011403f49646510e48d8a0538550006a0f5042c093d886f4d2000104c8c05669c2e015f3a60b220803c0ff053b800058b0560022caa750af968a73a178a7627960c10815741c50200d30c1c691e0447bce003749fe08014d22ca1b710080ce0326118a8d04a1a6039a88eaa898f7e0b57008173172a0f12cdd62c2458c3234a8e0e94185199d77b300481e0981238d3002820f2ca24822881c624821840c22482080fce1471f7ceca187073a90071e7770c08e3a36a001393210071c1738f3861b1668838d35d448a3024d28d0048d2667bcf7487041ca7b72431befc90d7bbcc004890a9e1e5104a1f37e95d76625a8779d7bdaacac60ac1a598869eeb58f66b57834aba5593c4340489b4f8c276868e33cd1508c6728e814d32d958c51db3b0f8f8c511ba336a6450b8dc9190ba3b2c2c3c3c3c3138bd1989cb1586c2826a78c516be47fbaad2363d46e568686684cce582c151ba231398dfc4fb77586868256302c412b1896211896a1a1a1552a682865a4bad25b1e69f319c2311b71cc466e05c352230b46fea7db3a432aada5779d21ce288cce50504c6369a9b0b45458362c68c382867450ef3abdeb0c0571a9a0552a68280869e338fd73d469d64b5565b532f23fddd6817142492f5595ad0b96710b9705cbb845a7a5b3fdf4c8988cc9988cc9988cd1188dd1188d81d1827c8cda18b53130dad0d0d0500c8c46633d3ddec7fbf4f40c05bd7cfc0f18ada7c7fb789f9e9e97cfcbc7ff80d17878648c5a1a93f3a557ae9518312aa4201e1e1e1e19a356c6a8a531394f3426e7108ed978021a0af22dedf3e29d6fe9955ffd0f4b05d918c30ac0d4cae963634bafde7322c205bea57d30b51be789e4a4564e1b5f7ae50ac23226a78cc9496336d2988d43413886bbde7cb08c5be4c431176b474e6ca3518a77c14629de05dbb875c172622e8b8d5c16dc6ab55aad960eb671c382b08d482ca0de7570d7416201612ce7c9f396e7a1f6a5d25c92beeab5fde870ae7b759de55928ce755d3ff1bc3ce702ea4edf03e1501bc27b4e4070f2c1ab3bb13c8be5594e4c469c66799651f7ae24a1d54a0703ff4adadc734e12f04f5c15ae4a6f692820a48d4b09e9578abff44e1227e4bb95f64f4e10e0da7e9c1c00cbb8e53d271e50ebbd3fc9e9bd3fbde7a40327067828271c38d9e019713a2c8fc549019e130b98088d11c418408c61f4ba9c2293ee9c949c64f01ee79d3cd1e0bde7840019bce704830b6c6e4d095e1d5e8801c5a559b1ae42bde764004e04e05d4942465a48c3326e09406fa98ea800c38fcebb9262407527986042b5fc0a882fcc7cd1c37b5fa4deeb8cbe30418caaf39ce98b0d5e278149deebad9c475363c3a4c966c469cf3b2f4e5e5079efa9ba28828b4ade7bde88d35dbcfce0a29212175eded8820b271654c0b58004003459c451ca220d29ad8d890698a8d18b7acb1799562b9d858f6a8bd7d994d1fddb589b0f5e57d8c0c833d22f23fd4aeaaca8c28a1caca06f654a5a6d96ef3a9dedb95442c5982af478a69c2aa27826dd59c1720aaae2022a287919152e50717aef75df719a6687325390f19e9f628c147494a690e1bd2705258f090f13274c9a5492d990808e6723871404908289993bcc9c31b3849920cc68335a9e190fcc6060e602334e4ca6f79e141b2e2623fdf262545d52aac3940412e44bb5a7506be2b61fa58aaa87423199ecacd5d628e180474a4f1cf25e0d4fdcf0c4abf54495271660a45f167440bcd73921c8ea67394f98c8e2a15ab0ec83aee33a1f46a77a4b2f72a348cd249318e957d1a98eb06509f89678e2bd5722f381572263c82b9101e495c8ecf14a64ec78efd928a1871271e498584a34a1c41825b81242a62b9490f25e29891224d1484e12412471e6bd9c2454495879af171525e1e415959038f31e123d3c1b406cfc40c204244278ef25e0959060f29e491715151d6143e9880a1c61c6883f5ed1df4c454526d37baf8acd214754f0de2beab80c004e1eb5469cd64e6e9cbc26af962a857acf0900de73c2c489cd7ba7f79cd438a101aa92c379ae32d2ac965e45c084085c50c422459c29428ba457a988a32282de7b3108054fe1111a9ab353a90ca136474e188ad3613a4fa3d1e0941ec0c14a9b79ef6daf44c40f0fb552fd297f9bd25bde440411113e44f8bc2831f8d2504c56b09c822c5862cc9931488ce96f0c1421bcbcee575b7fcf6119c350fbe5fcd4aae4540d91c710560c81c410a921a00cf11ce00107ace180d87b6f01423c22040ecfca8f66cae980d803881fa6bcd20f38aff4c306aff44305afe483085ec987425ec9070dbc920f1578251fb878251f9a78251f7a98e082d2f740df03f1168c875a1e3979a83d5d6249f752b1543e429c3782fd6cbefbd0e53d53f7aea4977fa51e60afd4039857ea61f5deab0140f7de4d258a7857921025b17e72c1baff1e68e5b7f679ef060b092691e49f5cdbe673c4b711f496eae89fdebb894404be5b79ed53ae0d12d47b378fbcf76e42f0de8d2316b034c7b3da78c031e53cbe43166f07d77ba61c534b654ada7e1c3ba460cae17c07f3ef3d0e4a3a74d1715957d22187f74c392d980e47251d503a9810c5b4bda0984c2a97ca45430e87bc95dffa2887204c39a6a222d3cb1bd138c901bef712f1ad0dd5a9502d9f7aa1fe86ea2dff26d0002fafe3b2064879ef997a0b07301a41220f468e0041073eb088d1bbf18abcd20f47aff4437fa51ff42bfdf0c22bfde0c22bfdd0057643d10d505e67a93a1d6c30d371190e251b4c78ef3120a7d6d080d7715977930822ef7534ec714869062f7c06134a28c97006ecab610815604a3258792724760c630c5208218308f2de4d2080fce1471fefddf0b1c77b377a78e0ad3caaeb780bf63bbfdafad563fdb4430e491dc8e37b203ceee0802b49c80e7f5307b7719ca6574343433a48ce939c3c9e5a9ea1216a79e4e4190aa2762848ced35010b543a7a15310b54341276a4f2ecd7191f314d358a8e569a9b050cbc3c3c3432db5d4524b2d8f51b775a8e56919a9ba24d7b623274f4c639193a7a5c222270f0f0f0fcf8b03132427cfabf39c969387dbb6158f9c3c2b95df9193c7a8db3a72f270af6df5da82b8552a88da13b775a1f6c465a1f6d45b3ad49e86a83d0d514b2db5d4527b12f3daa1f62466b543ed897b6dabd716c4ad5241729eb8ad8b9c272e8b9ca7ded291f33414c4f240729e8682c2a8acc8795ac1b0c879dab020394fbdebc8797ab5b86bd322e749cc6b47ce9398d58e9c27df432d8ff7a196e7d5432dcfcb875a1eff432d0f188d5a1edf23278ff79193e7d52327cfcb474e1eff23270f184d4e9e21dfd3e37dbc4f4f0fb5a7a1a0970fb527ff43ed490c188ddad390efe9f13edea7a747ced350d0cb47ce93ff91f324068c26e7e9bd9b0d7c0fa4013a780bc6f33d906be3acb06ee648726d3b41be67b552f1206d5c8f5f6dedda382b72bc54ad53926bdb59ad543c481bd7e3c5a882e4c436e2130f0fb527394f4372ca69e350101eb2d1c6a1207ce2e1e97af3a1f6f4de4d06bade7ce43cbd7c90ef09726d9c9538e0c0c0cd055a43efdd9ce1aa88f13fffc455110346fb27aeca7b376f7055bc177af9a0f76edc78f99e8db3e2f27e85f76e2cf0b27818cf11df565562fd14eba7581792935a9ef76eda78ef868d352c71f500c8eaf5d1a5b80f3633a61c4f80adc894b35ac17ebe57c08d1a6990d06ae4216dad28ad2457cca35eaa56f79ec3ba0abc77430134debb39c38cf76eca98c07b37646c30c67b376284f1de0d185fbc7723811b2fba78ef868b2ddebbd1228bf76eb0b8b9c28af76eaaa0e2bd9b29a478efc6cc4d1450bc77f34499f76e9c884013efdd304166af36781d975139a2e3bd3782a32b474c9e29e79b29c1d0c32bc1a02527c7e4f2fee8bd9b256e94706d5c7779bf826be3ac5479ef039d92ca86be71ff4ada2f554b85ea5459aa8a246e9000802347dc181181f76afc7842c434aba56279579250ac9f8278ef0688f76e847ed8b940c9c84a0aa56f474cb35837fcbe22faf25b609262cae956f069409f7a8fa60025afc1bba49f494410de536f8d28fa050f0986175a10e25e58d88774b1abf05cbb3a7fc3bef2de9ba1a4c7684b9e90ae0085e45b45a5a22e1678657c514483aaa4ffa0c878ef3d125029a02c08838a570aa3cc2b8541e695c248e295c230e295c280c02b853186894d0d1f9a4eea85b4713defddf4c043925fe14bd0cd0e3ac07278efa601177857d26bc382fc6a6b1c6eb0e1bd27c45b309ef76e6aa0e1bd7733830c3731bc9ba21a40925eefdd8879b5bc2b4988d35b5e4937b19b30efdd2085b91182bd07820b48bc8ecba8fc95f762548d945c607285a80a221a88561d977a4da9efe94eafbc77c1520b33745c86726dae521720561ec68365e56f841ef7ea5aa739b8e461cae1b61a0ab87c51e2d2c31866b898f08018e195b65412c416301ab0a5b48584d2960d1e20a5a12cc60ca54c524c27e44c31642a0d958698bcf74c49bb07213adee391814c8f4b28f584e833e514156529059d41a51484c483a5200bdee3501dd00780ba784f4a4e2176d0500272f2ea5aaa120b8aa89e152c74794fb73ca75139efddbc3a0e8c6b6bb16e563747efc6bf9bce3d4bffbc77c37323b4df8b75fdd256bc94b22061e2b6bf258b96f7b494b25c4073fa89e3bd67e2b69fd19040a3009a0f2259e48f0dcc81658f0060e9a284658b1296d57bef4b96b9d0e5ac0291442bf9e4f03a2e3bbd920f7c53c09456e8f414114a2b78e9b86c05fa9e29a7e3b4eb63a102185a0fde82f1c4fac9b754abcdc5d29c50ac9ff8cd97573ad1d182fdd2298b77e3c505a29b166e84ba9c70dee9f9d2153bde7b45595117fd4a101bd699f88fc12baef762d094e3fbc65d9b29e9a5e274a9278f528f95520f941a0a6c79ef66a8f3463ad64f49dc7623c4e4c53ae0e9426d02782c78afd35c4c450a58c04dd0142d7503f49e504e4e57c9c9ea34d27b36615881b2b3c87b9deacbce8a8552953698eca0bd52155c64034649e78ff74c39bd05dbbec8c46dff121d234a3a449474841ecbe350d2b1e0bd67ca79713e0ccd512905328a90b6d56721059a820152b0e03d93cbfb235c6280074a0ca8428a2965caa1b9eff9d5d67a9418a0575b4b96f79eeff40680564281cc7ba6d27b4c986042020a26cf914a2764f19eefe9a5134ce036249b134c80e43d530eea921b154eef9930e56d699450c4eb5b0aa512a0bc0e72ceb4609fa6494e12395d7414a57cc87b9c3e2ae51c1e942ef982126ea484bb30e544819253b27b94ec0813d894c624e095c66cf04a633478a53118bcd21801bcd2980a5e698c935225f3de7ba5eaa566826a2a550dde33d22f5a08cde3bdb7caa92921f1de4bf196e6b62987c6ac603905d12befbd2925cae4bd97f4d2a579e6bdf73dc737a3966a22519a363c93d02b4d9c29af15acfb2ad7b6ad4c523a094949a621c7bcf7e4248104693ac1849c928c49914032e71df1cda4afe85a9baa3319b55456b09c824c5cca6405cb29a85ba104ffa0026306a7f457b7b5a6b03a8d04cdbc2925985aad602d54a72a419a039b5091c494632a51f9e3bd57a252e615bd7c9715e5c0a8acdecb2951b9f2a8704085c9cb61f9952f6583bcf74ca52c8dd73b53290be23dcebb322fbc9449796fb582b5b25f9a32659197539ad2c67baf057bef4179a5294594a65cf9a5294e8a4c3a0769e3522fcf95a4c4f15c545e494a11af5b69cec8bf5aaace945392e2e5bd9214292f897bf19294f78abeaac8d4d2ddca37216401170060899b1340f0011a0fa04173468904285f4ca0608f26514a517ca240294581c23d1e7a687835f400a5974618e4a684d208f439d104191eaee870e5c5a9aaa44a9026114c2dbf6af9552d89404798774224903c2d1e1731893143bc2d5a1e034a38666e72b27fa938a4ae3df7de0dbeefddd89b2ac394702a28856049298445a2987272a08420c6d561d84bbfb8dfd2a95c3a9dcaa5572e96cad58180e509216d3b3d0f85d20766bcbf6d9c90299228504c423753de8d94f77efea672e99c9c7864ab74718fa2b104010178e7dbb18e98c71a2034582dae9f53af23fc72eed48d2dbf426d2d548e1585c2f18708c553f383066df7f0ebf967d41df6deda32cfd2dcff214281a9f1c1f648b9ddf6ca3977d59a0708474e2f353dd4892f855bff8c2feefff28061c5f65a78258db046cb7fee70c36c3d957eea9a1d342c3dc6d15658e98457effa438462a14607cd6f5ff79491cbbd7fc739681ede2fa3ddb3537f6fbf5a08d63440ab594b3d39e6f84b3d21adc1418b5beecd7bad94dbdae1a7a79a1bb47afbafb2d30bf1a7d5fa1a1b340e7fcd13d72b6709b439b5cc7b7e1afdaef642a14b34fe7df772cabab1ae9cd7d48d937bb92cd12c9dd1dafa3bdddb6f6e2bd128cfb55edda1acf15a3929d1ece5bacf9fefbfb1f7e9b38c049acdf25a0fe7de3adbdefd249aac5fc66cf3add54b1a75fd214205d148a2f5bf7bef7ddf5e79af1ca7ae16ca32cbbd5c23b8d9529b71ad955e1c618438c689bf9c1d6bbeebef2dd50a3491681bcead71a47cd7f9a917816629ced15eee7be534eaaa85b22ccb8c74a7814483f667aaa39c59e3cfe97f44dbddd2fcfb8f5ccfee6508b4a9b3ff7c4a8effcf1beed48d11e5f2afce3aa2752df58d596ac8a1ac50a76e04e3512f5e71847a70c0689ea5127ab5749665996d44e3d3f65a73cf10f739f7e6b6af6ac170e442c3c89c92ca9b3396325b1bb7ccd956dea186d3f3d48ddc1646af3e0ab55a792b633420d036d550e77ef39f17d699e907341aafb43bf69cb587f66adf21d04e8edbebe5b957a7e2f2221aae7dd3a97d979a772f79d7f92142b56814d126eddf4fb9f99eddf70f5337f6aea796655de73452f7af966ad3d2adbceac787d9382d59d6bb4eec50325a4293489537420ce3c4514e3ca1c4305a7b31a6fee20e6597d622a26d3923855bde1c31ed9f1fa2718affecbed32ff5cd3a622d348668b34b79fd973347ec7fc5a91b8fb87665199465f4727aa579676fa02944ab77df8d33d6f8e28b378491104df64a2ddef852e8e1963d75a3916f19f99f0c81a01944fbfffffefda636d21937acdbb02041b499b1dede5a1dfbec76fed48d4712697355229a40343d7395b356796fb47af7d48d2b186b0af5ac6058b28ce23b6800a1f8e24a6f95f0622cf39d386aad3f845062db67ff32c640f38726bfb47b578be5edb57e9dba5185e2c07432cbb24c4e5896655996619a31347e68536e8e23e714e6ff3dbca91bbb4ee32aadb472c266677bcb1f71bdef915fe9eec370306e631fdaefdec3597f9fb272fb31aae55737a2925c1baf1147a8274b4fc38746fbe717cf08259e375a9ff7d026cf946e1c71e45e6218f5d0aef794e2ac27cdd457f8519d07b43ce1c65572eca3f7f4c2d48d550a4d07343ff9d7b1d2f8fdf4f1efde5221b5605b0b85630e4d1e5aac15d3a8f7e5dcc2dbab514b7594f1d0b8ddb646afabc5b76b08b79f2ce336549661313477687dde2ea7a4df4ebe6dbca91bb1e45e2e146838a0ed6ee1b75ce7ac6b8e96e56b9451051a3bb42c71cf756eda6bf5f9c33ab45cbf873cc6ba319ffa579a0d68da7e5879a593731879d5a91bab06b43ebfce92cbcd39debfcbd48d49fe68ba34164c07863453186bbd7366692b85f0d77fe7a5fd7f4f254fdd58e7d0bcc61073a821d475d2bdfdca0513827268d5f64aef95f2ce59bbcea95b8362c42fd6cf80b621a67f530b35cfb37eada28943933e5329fd8d3bc3d9697cb974d7e95a4b86ed0f11ca88060ead477da5edde6ebab7f777460c68f47798f1e6f5f78ba7fc336ef6029aa4f3db9cbf94be67bef10ace331ac7526f1f65ae996f4c77ea46144acad5ca73fa86a6f7b498e6effbce1afe3bbdd0b8a1fde8e5861bf7ac73e6726759e6391a0b6819c2ec69f411e7daede6346d685f4368379d36dafa39bc6c6874caaabd8c5547e9efd76b685cdafc61af76da7eeb9ed4fe10a1bed0a8a1fde77e43be7985b3d64f9346ecb1ea98bbbe377f1c25124d0534ff33fc96475be1a778cfa12cb314d0b68cbfc6adadd554e33f298e500fce29cbbaa3162cb583ff6b28cbb28c7b7517ff10a16034686875da2d23e7da46be29fe32059a33346bfdf674cadd61ff19f696a766685aca2a3be7d35b2f3b8d2dbf42c95aadd09441efac17629a6bc450565aa9de3a5ee9af9f7356fcbd18550793dccb354433018dfed9bdedbc62c9fdb4347563126d81860cad67fee5ae1deffd2f9cd78ea1d5d9fbb4d34f58b1ccd7b5a172ac34626818528963d4df77b8add7a817d7380c0d43dde3e75eff3af5a57f7b5530349c299cd9f7287de73cef1b4ba0f94283b0dfea2bbc11ee6d6f4edd88ea54324a60cf3d71b6166689bdaeae7c69bcc0534e1ae1ac94da38ebb513c72f23e75c7a7c799dd8a76e5cad34cf9eb7b2b4782cee5c9b104d171a9cd56a0937f4f56e5a398c0bcdd648319616e60b318554b585d66fb41f466d3dfd99efaa856663f63cc38eefa515c7b869b2d0e2d758df5b6fae98ceec6375b15453d3607161ad19cb7cefbdf8e23cabcc73c66d67d65762b967ea466aaf8ba59a57683056adf7fe98efefb1975668ddc20b6b9c744faa23ad3556a1d92defcddfcb1a7f9e10a76e84315b7c59b056151a2a342fbddd9ededb6bf6f06a16ac05ef0f118ad34ca1cd9aabe45fe7ed319619a272a591429b77ffcd67a654c37fbb4edd68a3a431a3c59f6becfadf9829bcdea66eccdd0b73af2e0a2dcbb9bbce70ea4d6bd6385a807070b4f8e0e0f000e14ceee5daa18142bbf7cafced8edbd23c917c6b723e887b05c5d8e2fceba55d977b754f6872661bfbfc53ea1fed9edb6f9db8aaa5b564d9f65b2ad4fd21427d9a321a9458768a2db453636c65eac67e5b3a5996d4d2d3094dde1ee7a4dee78aef86d4fe229a26b47afdfc72769ef5b6facad48da8158c05a309344c6874ffce6d8cb852bc3595a91b25d2e642ad602c0c694c4e2355156c59b056a621a3c16ca18ffcfece7df5ddd6697cb5601bafdcabb3344b683d535de7ad1cf64fe3ab935309cdcb18e1c41372ce716e6d2bcdda5ea82c6b12dae65ceb18a9c4dd773e69ac9f8c5a1a28cbbc514b7359d6b9b6787f88509d0609ad7b2bb3f4b0ff7b6dd7f4447384f637c5537fc96bce7d5f2334db6797d86ffb69f630fa0868bdfefe63c71fda7d67a54568bbc39febbeb64bccf79f3410d07aafba5efaf7bff5db497f885040340fd0e08efa7fad2d94587a4989d078d59f6e6cbffe77f3e9752a8ed13aed50d789ef8573c70e5fdd105aff7bcf4ce5b4fa6ef9f5b6ed2b340ed07297d1775ef3fcf8cb7fa5109ad55ac6dfed8f5c7a1867d56882d02efd9ac748f59539cbdc2910daf7bb5f4a23e4bdf6ade9fc41d3b84e8df5cf3bc3783f943e6899e36eb5a49c4ad83f2af695577d14caca1eb49bf39ed746482bf65df628756878d032bffac6bafbde5c6abd5337a2ba7fa1ba76e5c8009a1d34093dbd596239299f96e3d48d5dbb6646a383e6f98eb6c34dabefd25b9fba51f2d0e4a079aba787fafe1ee5c4a8ae5d32629a0668b3fb4dadbcb25359eb876d944b734898f3af3c6970d0aece564f4ce7ecf37bff53375605d0dca0655bad8c7e5efe79ae1beaa072fd214275a1b141dbd1ffa823df72cabd2d4cddf88a79ab53b2eb5beae55997d3294e836aa852d21b63c4f9624aafac97d2a9abbc5acf5bafb5a91b5b491d8707082753eee55ad1a0511f29bdb16be9338758caa99aa819346be3c5b872ede98ddc5b1b274a06cd4299abc57ee22f2dd4317f85f3489b8fac2fc4a04dfa35a7b346ad259470422f62a485fae75969ff18df9dba11cb0843bd581ff72469de6f9cf9cddbc3cbfbce5846d8f671a084ad5c2cd5aca818a670e67b73c6d45618ada530520d7fc6bafadca7bed4c2502fd6ff41d2a48e94f679e7fdd7e3fbc3689dd6a9abad717f18fddf302dff9a73a551ebcff5dcfaa561fe25a537d3ac7df41da76ea491056bc14edb34ff1fb7b71b4a8ea585f68708d502a7c5dd7fc4dfc2ebeba730a66ee45eb8e39c0eed38a769fe21425130dad57ce37c29acf05368f7092e2dc2acb5dc774a08bd8e3ccbba6a43bdbad6667f8850a88d42082b8cd3da4c6f9db062fc2fff7ddbdf21e4b6d2ddd2748eb9f77e75a43fdedf595ab758d7a871f6d8ce0e61cf4acb3452f8f78c9ed79c3ff459767f8850aa234dce3a29e6747eb9fbee31756377a4bd0bf5f246d9a250a87dc4abfc2142edc0c029ad7bce19abd65d6aafd27efff97a0f25c478ebfc65aae72b75ac11734fefb7960708c7aa8c26ced74e0aa78cb6562c27b453cafa79fc7ee2bfe3bc455fa37c5e1c77add64bda37b76d1d828f3cfe8efdfebef7eca30a9d578d77a770fefdaff43275e3e415df19e9c5b7de6b2d9591e67ca9cebc624fe7a5becbb8c2d6708f537328fd84dbeeab7bdf72c45acbbfd77b79e6766a0e3f4fddd8b79c22ad77efa98f9ed2edbbc4b2f70d66943679b59243cfeff674ce0cf30b9a9eb3fe58e5c6546bdb7deac6958ba542e1fb45e31c6eadbdf478d33af796b2042f1a8d5efeab35c5de43ed63aabbd6054d7a5b37acdcfe6c7ba5bfe5c3f88db571ae28738834ca37e65a53faefd713c3d48dae8deb11b6a079dce1b5724aaca58c72a6b6d7945d349c65ffda7aab6dc5fbf2d48dbeb5ad384ac6fa43848a5cb41979953866aa3dac7873d9a2cd8e23a45f62be6feeb16719aeddb6f587083534a45daeabd67efe3c6bdf3ea66edc5e2d152a468b6bb78534387f941c7a59a3d4f1dbd48dd873db0ea7b76c49a3fd2142dd208d7f1b2d95ddeb782d95337563aa83b950dcf66df4018ab6461c238e37e63aedb475ee6b63cc1d66bd2bf6943342451634b87f9f3de6ba23e5fed6d48da8ad47799134506e418b1623f5d3fe186facfea36ebc388b96afee52ea09afd590f2fce2700a3f1aad36ff2a2786f5629a7dea468fe3c58221b413c72827b699c65aabbd15fa89b5b5ff47aa7ff4c9b22c9b957bb95c3e1a9d315e59e78c3edb2ef30a2815be9c346c31861fdf6ead9dd5c3d48d495db7ad6ab4d6842bac6d43ad3a87424dd0e3c343319f53eecafd9479a62e86e1f000e1c82d9ac627aed866bb6b84b4d7fa627d68459bd0e7d8ebdedfc3df31c7e915862384b32b0c87fe10a1b0ec68dd7a0d2794d6daee61f73d55e0bcb8c61b6994b6563ba395b8c28c03ae8dd3d261f963a348bf5cf7fb2dff2f6f344fa89efc438492c126118de78ceff454fe69fbe63ce9ab5e55e208f5e06459b44144d332e32ab7d6bbfebf3d4eddc86d1f75c435b723e493655db539449bff665829f5782753fdd606d32e540c670707c370847c70b22ccb70b4643121f9868d21daae3cde0db7a653ebd9d178f2617e9232942bcb9278966599f73ca9978acb4a7b2bd026109b42b479eb8fd9f74f7dedda7f42349927d4d25e3ebb8e91fb4134eda3de5272093fc7767741349d299cd17b6b3de774f740b4bf2ded59db7bb584ff764034bfe9dd946bdebfe7f0f33f341dbfe4bc42abbf1f9aa6955acca1a475e76c791f1acd935eef29d65c5aed371fdaf75debf9efedba4a5bf71edabd9eeacb31fc5a0f8d5efa39b4bcefaaefc7da035ad598ea6975a4b55fbf7307b4baf3d45c474db9873fe63c347debf7714fda33def0633c34fbbfd4b47aac73fdfddf3b345c6fc414ce6869d5f05f0e6812e76b6bef7fe36d79b676689b523feb8651564bf1af7568dd53f8f99e98eabe3da71bd0f4af737248fbc793c74b35a07d3af794dcf63821bd95d2a15988f7f753cb2e2fad7ecea1599875ecbb47ece5d0b2bc77ceeca58e10de2c33a0d19973c53c77dced9d390ecde31befe532db08879677df7b4b0b778e105b88eaaa17a30ae28223e483936518d0249691661eb7949ff2ca2fa0e51d27a6dee25833955b9fd1b4ac356aeda9ac3bd32fa9cd1b34567cefdedd5a2cbf7db57c980ac6c60dcd4a1ceff4f4efecb9b6d2029af53bc6fda38d98467bdbd0a0ce705a5b37bdb857b8a90d366c683ed23bfdfdb77b7e67c76b68f5427aa1e4dbfa3aefe6b1ad4a96751fdb36be6a6895d67a7dfef05b49bfa5f5069b34b40aefd4bbd2ce23e7334249834d05345937b5174bc8edbc1f569c830d05b4f8ab84197b5c3df513f6db001b34b44b2fbc34fe09e7febce333344e3bfebc5728bf95f6eaac838d191abff94e1e63c4f3475ef1ebb7cad0ae9ed557f8a9d6bb433c012d477a6bd414cf1fa184930c0d6f4be9ad915f3cffbcb973a95e636853db98b98f565eff63e662685fc6eb3db7b7eebeafcc61685b4f7e6d9638c77ab98c6068dfeefc67ec9b5388a7c55f68957a3e29f5f0cb0dadff12d03ea47b539be78ebec24a8dc278a1dd0dbde4955f3867debd0b2de76833edbc7f5c3b9c9a0bcd57ebabfe13e2192dac770b0d620a778cdb7acabbfc7debb04e0b6d7fae7d945dfabbed853c0baddb9b27dc3e43bdbfbc170b8dde99a5cd76e62bb9bff90a2dc2a969c755578d29ad3de3606385d629d533f71fe7e518c379abd0beb772f7786d94be4a6a93bef754687be7aab78653de996bb09942c3b04efaebbffbc32b65b4311b29b4dfafacba66ffbf19edd20ca9fe55df0fa5cc77eb2d5f3651685f66ee27b776779be3de1523d940a16df83daf39d68ffd9d5c6298cd13d6778a23d479fe5f794fddb8b36c2a6253a6e21fbdee1657cf2fb778eb59967d54ef3acb549a139270d62462e344857dd24e77a451c3bbe259c6dab89f6538423d38f01662d384a6ebc4decf19affdb342cb8497b3deaefbee774b1b329af5d1ce9a3dec525aae6bf461ec13364b687f724ba7ccbbf72971fd522ba1f52ee397117f8e39deb496b149428b94c778318c92ca3ea58c3b5232618384f6f1d53e731ebbc790d35a896c8ed0b4cc1a5a8d75cef9ca5e5337cbb20c461b23e8f4fb479d77ef556ebc23e0ebce30c6fa2dbf5717a165d9ff9f5e629c71b4dca76e5ca978b2cc0a1b08443be787b85acaeb0338ee977b3f39aef6cb2989a03af64d6bf639739c694cdd88d32f0c87a54a7559189c7d613890763663fec53dca5a39a6f6c2582f1896164f65c166086aebcd95e21bafbd93563cb1ff5cdb29edf45dfbc97feac6d54a73dae2912ad83840cb30cbdba5949ff70f7b1542f3f1c67cf3ee3bce9f2fcc32dfb3cc77ce77364168bfc2cffdd431ffe9edfda91b2b0442f316560921861b7e992f4edd58658cf387081564f383b637f6d4d3dcf7ed915ee983866dc7f6f6cbafd45c72a8844d0f9a95b2de7fa39c39cff863eac6d963c383a6b1fd504f8aa9bf777b9fbad166d90f112ac966078d530ea58ef67edbc968a38356f9ee7d4bed6f859ec69d83a6bbaf5e7b4939d71b5f6bc56a360dd02eae78dbeb35a770da1a2f123638681cc31e67ffb4ca69577ac75b41c57c84cd0d5aff7feb083dfe555f8c69ea0eb5b2c8d85b30546b9b31c3606383cc34e339698c53c269219e35f6bf6bacbb6a3a39ed3875a30b856d0934fb21dc7147bf71dd577a301de5913a35976099f1b4124a2a2d8d95c2bbe3ff1fc35c3ffd51df6b890669d4fae6fbbdaefcf6bfbdec26142bd12e9f5c52dfe1ad30d759533776d6c6f150a2496df9c7376338b3e791a76e0cb29265198aab5e2ed56ae575b2ccb754ffeb1c99a8218186b9e6d44f5b3fa5d87698ba38aeb64e5afd2cb3551e4da2c50b61ed9dfabef587b5a66eb443359268b57bcc35bd9b43ade98f403523d0b0d739636ebd9cbdcf8df362708c44c3d87248e3ed7557da59dcd6ca5d6a44a0c1bfaf977bdf9ba1c7fe6e2f0c89e669c55bf68eb3fdf4ef9aba51de68650c46548c30da2a8fe8235aa63b5229b9fc3cc7aa43a0e939ffb5f5daec7995343ba2f98c3f96144a0bb5bed037a2d91a278e31fe4b6785b333a2f93bebe4fef22a6f8699824093917bfa2bd5726bece9fc00bcd8427c27b658caef67cef7c3ed7fa7d8cb45b4bb3fa4b8c66d3dd791da8a15d1fcfe9a5e8b3b4c44abd167a8bfec9df6fe637f400d22dadf515a4af9863547d963999a43b41a7195bbeb0a7df751c67a7f8850a91a43b43d65bc996e3b65d7d26f8ca271404d219a949b4bccbbdc7ffef8752a4b42b49a2bf792db6d6d9f52ded48db893d1ca41e49432e64871b6d4568a7185b0ea5b659fdaf3ad27ccb2ac722f578d209a8656e7af29855f76fe7f205ac797ef1967c71153bf2120dacd7e730db3bf7bfb9cf5c53fd4fca1f5ad3dc77dc73be9a6ba66d94545197f885049357e68135e1f6dfddf7eeff7c67d687ddbc9759ff7e7feb5cfb2286af8d030aff4ee8bb7e494675b6dde43fb916268b3bc93defdedd4439b7477af738ed5436c2df68016b1c59f62bdb9fd7dda888a1dd0e8a6947e2971e516730db32c83111579a762513bf3d068969d7f7fadf41ffbaf390debe17c92f659691b6af0d0769e18c3f9e3c4f2d66a5337a2ac8f4e952c3e3df615f336dea175a9aff49ec628b99d34c6349d202b3b5a96e9ae739f65626a38a0458f69ff557358f9dc17daa1754ffd9fdfee6e7d9db97b8ee208f5b85aa72cab4346b8fb9edaf2882dcbbf542823d59ef10573c51837f061ecf4432be9f4d3c6d48d351a80564a7829ad16df7e75a5316249afd4fdf71a3ab48ae3a5f1c319e1bc54ce9f3d2f0d357368b14618f59cd2f64af3cb1bd188af1c39464d75adfcc74e2de56a32802da4965e3b2f8d554e2c6deef046f873ac77ef9f69eac6984fc99ca4394ec7188746abfc3bfb28a9e5fa730b8796b3cf1f5b28edb7577f8e01edf74e21fc37eb0823ccf6021ac6d8573de3d5f6c6ade5992a33b433cb2a238c58ca9a6de71cd6de6795dbde4bed0a356f68d9de2da7ad5d520a71d76e6897db0f7fe6326a9a23cea92be483d3dd58add45840f3de5a2c65b732426d37c5b60dad6799abecb273eff5d659e6246ad8d0bea79ada4c7b9d58ce9971046ad6d07a8fdad69eed85985f4cb311356a6856eb7ff3bf3dc2dc6fbfa91bb7dfea92b4962ccb328c8a78a6a1d9dc61effdfece33c5d75680de1a33b6994249619ef75abb2d9d57776c6db4d1efd48ddc77937bb96a28a0e1b867fcfd5ef93fa6b8a66e445559838656bf861773afbbe4fdff9bba11c617b775b4e60c8dfe492784335e59f9d732a362113566683d4a2f6d977dcacf39a5a91bad65404d195afd5cfa5c779410eaf92fcaa5593726617ca566029abd9b7bd827bc7cfafb7367935e128a1a32b4a8a3e67dc7c8b7d578cf2c7b71ed62d1206ac6d0f8e59adf1c638e77da49c5d070855e66bd25ac77f2195f3561681cc6bf73ecf15f0a77cf6068f856b8abac556f0963af5f683f4b5e6fe7dcd6fba3a512d0b0af5d5bc9a78cbb423cbdd028f7f2c308bd8ef1dfbeda3e0fce0ecea9d35d683fc7ff278f3fce7f6fe4b25e51c38576adb6fade7f39d79c575feb161af633f62c3b9fdbcaeaa1165a97db42d975ecb17f2c71eac6574b95aab566a1e52e65deb15bfc39b7b9522d6ab0d076bcdc4fea7da499722bafd0ba96585f5931de5fc369277ca2c60a2d565f7b8f7542efbfbfbd56a165ea7f8713dfd83b8e11c328440d159abc18e6aab1ddf3665c79ad5368ff6bfdf9bf747b68b3dda91b51dbaba59adbab75cab20ce2502385062395b57f6833e717ff4ae3161ce94e8d19ad43f921cd19dfae71ac390aad464b3feef9e7fbbdc73b28cb28a55068df72dbb98d54e22badcc2a974ead5dd43ca14d9861a4d576afa5bf93673486c9b2185191c630738b9a32dafcd5c7be71b47377db2d04c2d9c1812ce068f1c1b92b174b65699aa87142bb507bbc39dc52469a2b3e5ac176e6b27ced7d767670ba6f2165c932ee7b20dfb79fec461b494d13dad635566abbcd30fb5d65ce354c6897c21be1dd7bd2f871e7a70ce58275df67153564349fffefd2cb6fb7a4d55e219fb8c4af35c38f2be6b363cfa9514b95d461dc5ead53952ecd9a3546588d121a87be4a5e65dc1bfb89b12b49484b966554e436172653938426e9a49c5b69ebe63c76ba25cb2a8ca878935e728a1a24b43dbbf7f0c73bb58ff36aef4a12cab2a45796c1888a492f895aa2e6087b259e74d66a71cdf6ca3a739f35f68979d732528ca5a8314293be77ab63b5dc63edabd7b22ccbb6e0ece0ac8023e48393652ecdcab22cbb70889a0868b2560d31bc53fac92bb4a91b591bf7bbd7926591462b6a8ad076dfb94f8f35def7c30cf30f118a46871a0868d1764c29bdf8fbba23dc0fd0f89f1ec2dd25f6b0c66e89d078dd306ead2bec98635c5d1b6725cb5c1bd77bcd184d7a8db3adbbebda7bd57c082d7f0af7c713425c71ccdb015ab4145f7ab7a7d5ee8f67eac67ce2fc8b7b5750966118398a268b1a21b4a87be67bf338e9d792ca9a202a85d0de8ca3c576de79b9ce019ecfa8e4b06a969918a4903184104090863400340013130040502c208e06c3f180a20b8af7011400045b8c6a9e42970aa5f1688ee32808828c32c400000801c000048c71a68805eaec43c9e0c6228abdcc306d12e8ef59889c6a2bb9538ea2ac0ec105fdc688a82539fecb957486b6f56afa4ae7ba7925320251b09540c9248128398e5402ee9f752b618a386237ff88c901258826c525180d4442592748bafd99e5a4a1cae09051719983d8b4f088801ee7a23f1493a1efab325126ea8926d6e6f541af6923e7ad38516708f5c85d5360de84a3da15959fe481f308b4cc0e6c4fe44d943b5e11c224a5bff1509936b9de7875e0a59b1769f0fbe7badb259eb556d399739805cfef632fafd509503cd0517254bb4906eb6107c81dbd6ee402fd68ae5281abbbfb052fc25d5c2bf35ec402f3218b8ac51ae6c7f3134ceaad11d886fc95cfb23d6e4f75a41a8de3a03113e3ba0bbed9dccb73eadf7040e7412bde75ef81de9e37e41db7d19b90acd8c5768feef1a089a73a7eb71e80ba193d2e6fbd7945075eb7f57227eff4f1d089271af77e5b0f77f2a48f779d7884c6fd1eedb076e0ee113b7cf316787825dc25821dde8180403b9d583440b4b036630df90a34ab8959b8940f458ba9afb8c669ca2b80142a3ce08081444550bd2c7e72d719875f04358cb3663bc49b8bf565a7d032174e491b6b956a168ff4788e11d17236c018cafff9037e4597455fe6fb002625bcb7e362140cf265d7d247d67b193ece67fc2f505221a85aca0e6fa9b787778f3ada851142640e8e4c90b683226693656e423c681ca8358a8642fcbdf8c0ead9c8af7466d48ad7d152443bb38c7a793814f129efa165070d15649b814a6283693d0a421489fca3f4b29be613cfb73e99b58fb941718e77f8cc3a36fb945093b969a1db043d14f565f97599b5886deda4d1ef7178ff1a49964fa36d27664dc334c7213ab38f557093d572af1dbc21eb183fd6d8bacf54715853094f7979c3ad19b32c92dd4bb1af18a595f921cacd2cbb3a6b569d557d9abca4f49761d22c937a9d23c1979eb19c085539b88d1ffa02d46f77f29c11fe3d12181727643465cbdd9df7d3e138b12e1b67bc76744627deef59ed81cb502b027f771ef6e3f3e57ee21153bd950ed57ed3a3aae4bb2b1df9929aaec509dcf95999979e6a760b0de69c917b3af714a1563e68d6ca06c155feb81c4ee4ccf5a4d59c1507907f34651be54941c1ca5f05e50e0ff59a653310755c051d2adb40ff7d22654bea0b917e1db6cec6de2da9166a0363afd9c4d156791ee9c4af0ddf8073e20ef9ee00dab67dbbfcc6f77a50630064ea4bc25b92038c6db218c52c2d8408e39c6c49278d47b6171ca29e43ed22ef7bf117c5dfb8fc341eb614971c52056d3457d19d9c36b508368a2c01859fddd73dc2d1106485537fca40ea7e4cf9fb741fc11b8b5d32240d1180f855c950dc8e8f1672b0950ef33671be40e4153901572f7d4c172adbe1993894edceac2231be209630246af4ba6575b3769b363dc82c3d408e53232c4454d8e4c993902ea7ff2821d9e8cb3e61ff54d1fb21dfa098afd91e6e3a3aec982eb0767bab9c0dc443e6d81ce2cc7bc43b1d35ae45320759348489f9bc89152cf1a8d905989983f172b0de93a7abb07b88b732493be2b678dc40b65c9303d01fbd9a89c02c5e500d978c824c2f18b83dcb58f16486d21b8f5e1a5f95bad2ac031e0d9b21d509a05cf9d09ad4051e1cc1473e8bd84c403fe7293b06f94543551363f410ae5ed52afaee565ffbb40633922bae1d5459424e6fca79a1351da356a3d1b5e422b9e7afdcd0936b2d39f75e4f18bc333d0853bb359ffd3d83607a6bb2e9f4d0029cfe0f1ad56a27dd23b347b1dd0f1e905dcd9fbbb7e4f223d4023641a3564aa922c4b744e42e110890113cf410f628874fdb2ecd85d3c404e8c7287a2ceb1e06bce7b8954b57fab6e084497e997aae33bd0ed273344aebbceac3721534319cd4e3b5e9e44e2e4d89194162207444723e585300f0861749769790199800d72bcc5b7b9fd71e56afa4fff57f2df3d32100f73b5665c1dfb781e2843cd01192f58df43229f07ed3b436993be710da416cd82fb6fcdd6f0988201d0028c87fe0033986cf229645f133fe39cc9b1d1b722f925c3beaaf765930a54eebdbe770430ac184d1143ea4bf332ec63bd1aaf1ab33557ff202ba4e398db68c00c77851d245135d1a2360808088838dc509a6ecb2297b1c929c2112471be2e26e6e4bd93821aca05e7506a5c6fbe5346a7c667264ab37c7088025e96e79d77d31f281d1b1529b857991f3b4a2ce11b12c0df0412f24659ed21dfe66524684a990d0276962c9a929e634ee100bafdd220291a573fe8c018504bbe0fa5a0600940d0b3b3945af142d36714189f047e36361567adb16afb345f99da96ff8dc38eb4fc35effaeb24a4f12efcbceddce2ee47dde7127c50c78e1eb2f90aad30722e794f30ab6be2da823fcec9ac5c062018e486583047e341c1af52bc79e01b321c0a3d0573434597231f3e0b48cac5d75193ac6a88600722d2af1d60b3af242c8ee583ea847110058825e89eaad02540740f1c7df76d95a8d54d31db256a627aa1ff02823800be0e61caa858da30ce90587f3ccfb5b36c54bff9ac114bea021ac1a10c83cfb600dadfac8ec8ab50250db370d1738ec72dffdb31e68b2d308bf5b87e51030ef448d5f7216d9a47d7aef462cd04e1d0f80f855a496398aa8e41236cf620f24415a81e4dc40df3241887649122ac7fb7e9ea64d7f89019256dcb78611c004bf61cf00a1d0cb602b05bda516b9c3b261a6b950522f4240ec0ab91ba60ca4f5dcda07f3a514628e3d3c32f288c57e9ff6a4e9073e1bbe097955f0420445f1030dfd60a7ecee9ceff6a47147722169461b39ab8fa0315581c0bb48748fb89194f7b47526b1a9cd15f1968d849717a9ce6e515a72f67920645b5d2e16723e948e05baf0ee11163a10573075cd752f4dd982364743b01991b35ef7ed151e3bde7bdaa1444289321f25d81004cb41aadb07ba7e798ed8ba31afdfb5009543e0ae2e3c6109a1279204ba032bf3adaec1fcc0221174f3dc0243e465909514730fd9ae64528713653a5ab205a2f5fdecebf104be9b5930ab463b0a466c14178e0b5f54ed841830d301d12a91e35db70346e41a371eebe750c1a2bdcddc919a9da76a0a02b39625aac2ed410a744e30cafab36c1c64ca4cd8a71f307a1948bfa235284d7c059952b4b8abba362ae884c6e12ab643323b335d9518fb625625d955123fbb3280e73fa642dd802b435bf9ae4a6958cf1f404d23b7a97b8b43217fb0da3f5a7ec6f2fa0accf49b2be5bc8e7353dc105e7352f4943c5698494d0f23a354872a02d49a716e6d35f5c9b706531b2bc13f959607bc7ff63fe0f9f290317a0acb767702b92108bec76e5c15957084eeb4359685ec1fa3332a1dbe56cd55445380cd51681cbd6e51424fa08c5f2f9505c93826adc7ea795b7063307073cede1d7207e38a63338438a544d64fe17e206d16367c89cfcb1f9c8f0755baf981ee4704948e6b4429c9e5cd21c4b407fcb2b49971731707a3f37242c9a8ca6994d96cc09b2b768273bae197470f7b340a9943f1b44024c4f9046468d78df1a1000b0dd0968926e9ffd07fa543ddcdcaf793fabaa646056e0eb4123a6df3e40059327e86777878d31874ec59acacb626169e4214dc35bb5d9d46d407b085e24d1608643b50ddcd2288996e23f167f1174cf2ceb5c341c11c6de6d683312a91f644211f2c3710436d50ff93523de76718ac22d465a73e8b2e0e91b7910581527e8f1d15356d62eb3912fcad2fa03287f1263eeb53e830bbc5f5b5eb99616167eba5c071896b21470be6a21d580fc2c731a7b1efd99e1fefc9fe9f331b4cca06d16c5981d3c5e484291e91c299f83eca075c9d287be36adae5fddd86554625a402f89e40a083fbe9ee6c910bc24ca098338ff6e3eeae49b89a52aeb977283e834047936944210be8560728cbff5570edacfd56afc82465f8da0b35f0b61f09fad8e24026254407baaa24f4a1f5d58a47b13dfdaee917f0bb82af5b17215b360a8ea992647ee29da827d06989616a3be9f429d680198dacd90c248191bba25d25e268a81721eb0d7df9c1affe607a46e6257fe8946f5c080be2023035aed710c1e1edb601dd145c95e82962cd03495732887da8644695ce35e995103f200c6a4ea437318ab603b5f6c874d168842ad1903a80966cc85a2277c0aec0da106d87d2573ec9b4c8ae29a88027874c518d96bc0b6b14540acaa6238c7aa8d300a61316f3449da7cc3b350c04bbda4246dbd323284a3514978a19c4b7c15ec4cd6c7a51a6ce9955f3d70abfb3908281541522d8c00fdf4c53eef5d8cf550562fed4dbe8e45e2669e42ba27242808e83e4e21a0467a3d83675c8c86c870561183b008578b044bfa8c927d40e1d5541bdf503513ecf4cfc92729d215e56ceca5c5f108d1b0452bea8e6473ad5674b975b43ecea5aef29526ea28f1aff126ba7f423698480ffd2c4e31e85b5373c7b7dd9f91bbae3646319a4b837f44994859806dd9f0470c30688763019513df8f68ed75f7a07f955e04891145b30ee7837a7af13a01f38f3da70626b080da476b2b6067b90afef10c65479ea0330e3ee04c2a219bb5cde88feaaabab8a20ce8bba912f6166666b9bd6415e943ffe866e28780d6aaff377019adfe3622fcf8c31f5534a4b81f8aa43371c3acf2fdfd7341985c1ea2302cb9b75cf80fc480fedcccb16970ecad05c3474ec0d606010febe7cb229633b312c0adda17f140233f6684993bbecf79252813185083f523054c971f03d34a816be38a4ce60eb74db4791ba5e85b4b8296ccfd801045dd0ce930455a42b78b058ce4c7aff79c567b755137a3697f8ddef62ff27b70e1d8de61b452698fd44305530fc945e9f1189a2094677fcd34757ff898e6c512e9079d5edca1bc292d2b41c3d91c34d7a0c8c94911ab738e2e41567534796e2904fe8bb0997cdce6c229a3898c060197ca8aaeaf44e1483d0782c03889a370cdcb56468491570eb8c73a9bb246883ccea621834ee92fee968a64362f5ee1642aba86db8d6663a8f31c5d14709e8ba7cc4017cf9e2288c15d462254c02c498fc1eb050eef52e9145aa5d2e9e37fc2e0e72f511253200b5285821018c007474910291ae4730b59f713a27067150564c2d2f9aae58fcf3581c308622a4c17fd0ee57ad4bb0161dfd68c008c3654842cb020d3e50caa937e08fd460bb6e067cd7126240a21e5b3d4f0803f5ade33fca99ad00d405dc98b3cd6a0baa2834a99a60310a50956b428450ef3e3eddeebbb2863e269102c652c21383123d6526b806bad20c6032186a0074a66515e286ba813262c145294f0c630870659b21124f640df1b176a62735bf3f021f4166aff5b5e94dde26140257deb159652bb8398b47a42568401fcc8855703dcc4258b4da945c1f87155311fd75d33f825b634191b5cb05b5dafe8978c5a2fa76314297ca3dc11de7426e30d77102e884ed97d3635a96215469fb1203adf6f11652ed00fa7900550831e2b761cb6eb1372bf117765244e261ae6f4f7e2d6fddc55004c65ef896a844b4c7d08b126db2ea25781792f7b7dd0a98809b0c0b53bf718da56bbc27fc43d64bfcd505f1c8e625c190326c5d29c5b33db01aebc0f1123016d29ec4865b4096d8798a77f7a4d4e4ff10aaa14634553aec2c7a5f4a8fd4184f525aa709709d9221e605ff28506c78e0400081be1b07b122a4a2691600ceea82f0bfe1170ae2f15f93b683529807579aee7a59f6bdd5a65877a526f4ce5b671ddc506cca7cdb0762cdd755e9ffed9123826ab3980acfc10fffe892c2856d03b75cb1f8f600a5f1ed86601af3a1fa57004140d026e0a10137ec42d81c1ef54f95ed4b0932fe44c79138fee3d74e5b30de9526059b580c7b8fa76e2e4a36b62d4a43c4396dfb95bd903ea34c88336cb19ce2aca0125c4dd59018c13ede4cd0908d0fe72382ba05b0fc2d832ecf5ff802171677313b12cbca4650b9ef1cae5bbf714765ffb16eddc19ced01e40f501345530d4f3a9e7faa30108b60a479e3371c6d4a967cd4680e75c933a1598e063b353a80f488bb756980dcb0cd8a8ce9584846be42cc226eb2285c6a470e6a9b818f4641706472a22857e4f770b1749b4431864f3556decc594f6abf922402ed9be87376a242b13bcb821ef2e4614a603d159806403e986e058dbc64d756b7122e90d4990d29233a4a0e7305893b91dd15964f3e3df763d7f3c60f16f52dec7a6b367135538ec922d333304e295dcb2ccd60ecf3584339aa5d95dd66c0064c5845708241992cd12da7b049d4881803659009e60ea2fb3e40e1135e29b0b5711f4a8609f1a886d25bc62fafb74dd7e457be5f9599b21f407101e4d3af80e52234b2e84f66f43a8a1546136340d770f1cf58a4cc2461c50154ba603c3499fc5477575277d5171304d60d04c42fa75eeed8a39c733680824753312a352c1467dd23536eb34f6c990e5c2fc3dbe8c3da7496811fad2ac9495bb4545b6634ca57444eb9a5a08c37f903caac9324cc9499dbe780195c4b7636bfbc980b4041ba72a431c7dfce0ff22de6a80e84a3f505c7bdfa14917c76ca582024b617c5696ccd3a122517e610235375c09a7866efa9ce54a7e506dccd91d29393dd98b01ca6e58e9cc5e5751fdc32419017c0dc6405cbd6a22f94f9fb94417771d485585d70abee80e4522389f0c0b798c30015a9343cdbe8ed531f2e6d07b1abe1827e4685e8798d44b0f88b1f57a30bb2c85e5319e09cd8c84dc16bf7e1022c3292f81bacd333e47b262e0cde489ab307b753f4bf5e66a4fc4dce4dc81e0a5e2b6417e8a57c7a7b5008187cee58c2925ef245f63c075368d845ff15d67cf9b4aece698c388169e79ca95a14062ee8aa9793a3795997f0afbb36f64161845502cab86dd0b49eb79351035357dad878658c9db4efe44e45212dc8f1dc7679bd0c88eee0c0cd67e92e3777a570d95700419be52f552ac4c91a3b96adadf6b2dcae1f392a39156c8aabeda4dbcc66bfd43e4d64a2e35282a259d7c71efb388e6e6f7c647818a79b243e2a971521d9fe27cdfe671d82615685884536951a75c292aa0526837b7241b7289981803971de709c00af886286f79b3828350080967aa16a7b3bf8a3b6702f76386c88784b77517c6c112f7565793a7d7860310199d633d1a51e40cfc16ed4ceba2b76d3209253fcdebaf2a5977ceaa08d68972976a3a75c3fd57481c2ea48667fcb2af301d88e5936d940646171dc627e254b0e4bc5f2543b0bdcc02eab24e717a2b2c2abeb2cde84112186561cbfa9f5d895ee8ffdfbc9180e9347a944ac67e430c393c5fd6304132c34e991c75b092c0595c6e84fd1496dcfe7d880f2bd4ab59a06c8fc7bbd133879ec43b72ec2cf2bbe5ccbe0ebd7a36fc0902768831cfb3d71b4336424581c9ab2b370746c3a49d8c00a76b493a098c3095e9b958a6ec99088a060bc177d9129d8630a61b2bb4fa7a63e27291b4ea796756d3c17023c068046ea9bfb0bd28fa39be36a5a48e9d47f9c27c6133e2b8c609d50134e4dd0784723303ec9c43ec0b667823b21b2d31e05c8e5bc33c7f92b484437492f0e073a26185483c433b1c3ca07297cc8c7c49f97c88071aaa4fab4b698b6856bf08f457185ebc594f1a4a8f6cd6e70029944e0f04990e297ce5868ccf4e31f52e734cfee19d6c5044a2998c7dc2e922e0600c0e2e7bb70e2ab8dba0cd630bd202cae7a66d2c1c2f27a9b3d113cf1ff46cc78479e105ec6faa7440b238ef18d0f101a6d51be381f64cf911043661122892a32c87b2bf99ee1f6e4dee4490d70bc4d3edf94ce0558f896e97f3da89a3df3a058c956b8c6da5774635d618b8fa0cb952393c0790077a1ea3f9371a0b67c2331a83d383a0514d487057a8a5524a23f21f3ea138d90cea8bbfbf6b14df84a85cd3e6309ac8035531bc17c6de6159632928ffcc18879ea88b8eeb2481379429026911c79ec3e72b93226e1991866f259bde1a99c868ca41ec890f9006d93a4c676fe160fa4f388a0121e9caf6257386037a70e77c1f8549802b48ba5db9dce5a1ae02a5a6558f15b5d04d39d0e247c4764fe0bd6ec0eded5239fdc732ce97724ffb3887a67ec8d7ee199ee43b93ee3c97f8495fb46ee7562776b27dc092acfb585545cb474bbfe85d75df79a5f30a301e6f3b68057e8cfebc0ec1953df74c800ebd962a6a0b490417509e2b9e26093d413c5f33a1d62bd096008964b7123f13d8b23e06e96ec27597ecf5867daf647a7de6b6909cea2b010309e9c515095e15b8787d3a8e1410a00af20067697da602f937f52680d1331000ddba44a3b04baa4d01f4dbbd591baead3b840c81e26a8f44f098f305159259d50cd07e023c3184a269c7d58926969577903ecadb967f9164205304d01b07f4f57d8925b3d978be7151d030ca794f3ef58ca8ba11db5b568fbb82c1d6841ddef2a665c206e3d4ae995c37a4023c0f0206dfe759b1d3e09adbfe22c2449849e5787c955c632a30025b7574349462cf4ee9d631373b2a7bf3633e765b6d428f0ab2321e6fe1e0de33b2e9ebb5eb016064c94e47634c7135666caca8fad6a94e7c912170bf98271f1ab1736ab40cc343652705c1d0b8a86dec5b665361c071d84fa5c5840250455b4b7c5610986b274f882f1d037d7c06bb9a872262e349df0b0fe1cbfa50c837a40f8614094342da721ea56c38182017308639522c6da18b88f9626694bd6c545ca48631f887770e5c69e0bf35b6c4552ce89cf7cffe03e2648e40ab7b2ecbead1d237fffd37c4a272872c7107e09e386f3b648327b6d7f1b1f151def164c5d7166bc27e3c34617073e7519f616f30904869c6e398fa16d264e68a66399292330d313972931cbc4a8ca9400652a6a3221492631a5095e2a47e26a53a86e1347b92980996a210d2e344c80990ae10db34ce30efc50263203364e2eed44a6ab5ab6e0259a192189251e50cc3e48a06915ada408daf698a988e175e5503453e220f04571b4ce060b4cdb41e9fa1e6e699db29be158d301850c0b141d774ce049a62cb19aabe368752c4d2325ef22a551e84df70ead366934f807457f11447256c1aa8161c10dbb2a439cbcd48cf15aa134d107834404f1747081f896bf49e44d31667fb346f66468dd2acb4d380bd4257b982463c80c2b11e3214187b3206710f139e78212969509eed91cfe54ada379dcd83b9014a3ba59eb660ca7f5575bf51d946c09e7d7342a15f2990f61b43d31cd798b4838cf1b36a613cdd0f8fdc8d48ef9d1ba2edf29ed9bf0a1fbc17cadb45b99f1331a282d568d555fa2645fb8564caf961cbd6ca964cb2ca83d40f9982eb282aa0ce61c0c8f09ca73451a7992e470224a2e8a36aee9ed08d9b6f26c879f60e34a367c4d47165450ea9affb0069c90179b0e5b0c2c7132b0e96087c8b80902a7ccbaae8a7363b4053c0cd641c4c60883607c63f7252a12e2a0db46dd25695cea1a77c853988b5cc086f24ba165c9fba01770741146f1d0467b37d545ec7cb81af6e978edd2d88c3dbebb2ee9ba642285829c81a110d1fca9f57ad50c397bd835461bec8266c8ca9c9e7936534706313f4ef66304659e91a1097c165e3b1bc1c4f136a473d8882e8d5cd06b0c41029b58c3d5868f805c3f9c45e583e71d8dfb193432f9009357fb9cef5e28e01f7e4d264f770720c5192e383c38a5986bacdd98f19261b56a1a2f9bb3abffecc236c77757eafec2e91822ec0b340889e7f6bb3b8abe2229adbe7d14de6c4faeae0db996e24b1c08ef0f74251780ffc410b53ebd757142a3562a0b5fafe4be062726a658b8560f55caf4ea492cf3de1eecba9822bfe8d9b88277b52580974161feeeefbe85cfc97bb79264fa08268a0afac6f37afaa913c21e8026ba41feb460e36d84f001db34aa9962a622c97ebb844feac2d6a457b46576e20a8b3f2468472e9a36ff05756718af1bf835d5d4bd4d96e25af33febb39df5413cec690255865a26afe44e2dd5746cc531f54673f6fc9f54fa24192ceadac37be45e63e843987b5ff949ed943d3f4b3a328f55b32791565e3dfb3f48fa41501d2cf6f17144a962f871ffb674a1152e67d77e339749ebe4ed3255a4f9082b77fea5ea65676fb4b20cd0ae6862a5c26f74b6afc2d1f87eaee13f16a9ffa416a68c814ae60893abc7db61daa0eddeb602d821ff26d0fb56252c3cbd5cbabf1c192af4460d2eb81a3343259533efef22fc45114c94e4294a8efe8061a1ee7ef1db14d2a4b36cf131ff15f0adbfb413a6b985eb1a5b90323323e42601c13089631f2a6e57b7208e2c43e29985353fd9553a4ad2458d5dd7f9d53e8406f340b94a0373c4e9d2e6ece05c715e88378b564e278a338c4eeef428fc4817630ad99d12fee5332b5a587cbe7ccf9dc8379633fbc4423a5a1c86f2ed88dd66953f42ff87debcfd3b9f7fbecb77ffe3082c2cef66b2b19f19025a561744f77ad663bfcc28e381947a8367099dd8643959d5a4a4052bb28d8fce241d8b42ab99d9c67c7592a9fe7a36f20f88d97dc3e38660f9b8979e5762b432ed735b0d6fe8456b1b5b5f8c8880472aa2bf4681f37221c1927fc1bdcbc0f1d0595ef0c01209602fc8d607a8b6b10e588fecd3c43d95a9119c298af86b7e201b46b5e6742967affca43e5b8b49d3f9357adca9f7fa069941e276dc286038ea99a1c2b9bffa54a50e2a6a6144b28c25139e529bd0754a9955ebe31a4e1fa382fb40ae2b08d664280a3ec96cf3aa81dcd3607aefeaafb454791aee51cb26eacc26d3ad5cd7b82f98cd63fdd86bb9218075e4eb6cc4206ad691b9d3ad39093bd6c880ea056874c430cf8538096fd2310320a18029858de21c0b522b8e687e7abfa138c2fa796b6a92fbcde3776c7b4d40f551932ddf746aaec648d5783bc9bcc81cec2d6d63b1f5ef376365c082cab80a15912c0fdc428e91f6caf170a9473e30002bad12743a58e9bf3a53b41dcb561d22942b451a96ce489a30f7ca30c48ccbce2542fe2b0d0d61a4b159ac320d882ac531126c8b54fa181215ff0815c7c653120bbd06bbcff7f37efd5a814baf13fe6d4778efada627bce194b8a55bd24db7579e687a961eeb3341c4e3935fdda4707b3a72dc54bfbc3061a436d21b0e756feea8407c6f6f18a9be1de75db29294165efe1289dcb0e45f3e8fd4a56a4de4574e9b417ba24b3c856ccce4bc76eac35b65f51c36a980828b117e890527e0e0dc74250a340df77a09548e832bedb6af0c93a2ded8ed850622531c81a842db58c215b4ab286ceea3a6b3c39fd3f0f068417472de2f87ab05e30dbb8c527dfd4cf83ff35050e0fa6765d845710a5b96de0babf3f1f2e13dd84f204c3fb018bedb9532aa41f1b7886c6646f7bf27c5ee62d361208f34986d3ac54be802bf715b95b3af362d97a5dbc3ec217412f754ab3f4aebcce7124bc7ef1170ae85194636956dc77c7479bf33b9502ee7e1914ef1a0ff374574d3568c5d04e7131a24e2a732fd447415ddc9430e0123457438ac036edbaf4ccb98004275bd0ddd7eed3ba900bf855e289db0e952a23acc3f0891d77ac58313ec7bf8e5e0c3152f4ec768b866399406ebffafe88e20d671fd752234ba7ea7e39180b5e73144b081bd7c71e96f8a244718aa1d76a0459acba2e8b140c2497833670907c9e3324b512e01596f669a25c3532f3865c8c6aaf0e1bdfd6107945a1cbcf1b43a50031204164ae46cbe609b6c533a746fe8c5a9bcc128fc07ebfc5ef0bd27cd6416ffbdd7ec0fa742bc21c08e4c1408ab061863b1618fc110ea3291ac60302dc5a8688172d98c39651ad8e804b0dfc234ec48f29580bae36ffac3a61367ee5fdaca68ddf935bc058791138ed1a38b9cbba91624bca77dc7aeb6cdc76963ed6c0ea1f3d4f3f09730eac1f371d318c84c2b7fb6a14859bdad023224ef7716e24892e4553782c099a79d25c9a2564c73c824f34c1051c34cc730afdffd3f7d1d78e05738f0775f17860bc143934e9a557d902afe4378dcf6d8a1f9d9d5c8f7addb2816f3c70ea57fb6738de5d118286f43886af1097c6e555849aa54e32a88d7cf41f449a9e6bc6ce533e09345698edd087262fdd3d3091189d0941be4d66412731e346600fdf052a6f7c4d4e046ee43067d36a54e46b634daed9ef31f7dc3d44d37b74f6210918dd0e8262da41b1d53be8543d0a57dff6c077d160e8f2cbf14d5a735d1f83332b150fc4fca7437876ba1954b1db6bafed838da8ff6f3a33c75d92ed55731767ce19cf4043f4eed16aea86e89f7ed7e7b29aed8afce8fece71fa6f603625057d825ef9d2b4ad52b41ea78cb4b7edbb3a3972ed93a5ae7e0a5056641e82598687bbd5a20a1ae70ae590c6e4291f3bdea3903addf853839403c8faab679819b2a56d1cfe7eb6326794c3786672b957317929e6fbeed803baffa9366899c49742383c7c1f527406657ffc10363f4b3d750e621af86956ab50810031f627dde8876edddf48487ef201ba289fc55a0f474f93b20737ec79d888ef807c9957f5f9d3cb5f9059438b95e72464afb94d1b607239dbff026425f427c1fba0f023c28febd1cfeb8ba023b063f91f3ec2e744428a2258c042e85134549cfb9ed10528feff41a62159c360d63603bb29580ca3e67816fad8bdc8a4daa71f666911b759ce0b07bd01f1bb25552729fe250a62ff439824ba94eaeb39cb3e8ce9e5471d939fb403f03eb6cf011ebd2f84ef180e66b0bec14c1984a8cee85f57101421111e3a253cf27166bd4cec686b0daddebe21df35be601e6d11aeaa6b357f77e27ddc60abd0c5443c39c481f9dfbf49fb1807d78e753ef1402979479745df1a9d9c44e5b8bfc68e22dd9f7c7f66a3fff96a179fed310bba55e56a6a3e9815ca3697c3f560da0b7e6b17dbc4e4fe6080a272019f7f25bacf4d349db7e31614a1573f6b690e55e6d2c959a2ee069b0b4eef2f5be47412a1dec920dd67561da8d762c6895939bb8cd47fbbfb1c1c8f938ec458cdc37b6fad272f4e030677026db3b01be7cd967d970e4e4654ce1048b051b4cf7d4fe84402729f0326a4e80f68395f9ad50ecc3fcea224ecbf5dc6216a3266d1f898af42db0799440171b4ce56d8f255ccabbc1ae7fc463eb0da36df29e1e4b2e08aefe51f10fc96e870275c89c71dc1f561aadb74b6fd10182f2ae0be313d754e99723b1ef3a08f70ba88c0bda8234d3a0a75ce19046ed62fd26c94b4e9125e9ee55ae43eac7a5cc8c4558e4f3e02dea53d9233e30bc9c770ae84577e729f3db9afd0186589509aff2af0b47d7fe2dc06124fe213f3642ff29e9dc5ac6492e3d2e663ac627519e93eca9ef53725d9ebb72a1487e1b3bc54fb5056da1e7140fbf24f243a24b34890527798ed361504f6e653dfbfd40f2af0b6cf194f545dc7530ec16fe49deb9f3d9b2721f23fe43917f6eae28a787ce23079531bb1bafd0fcb9b69f333c15e4c80cb93e53429e8c42cfe7476db57626adc5c0fec5fe875c3be7ed6f420be0d9dfe8a28e76ded15bc5af990298f74b406957c501f38c119ea7a0178fb4e6a34fa7a7a9187e636dc499daaaabb4f24010340568a55a12e22396c54fa0837588c2905bfaac25491d9756d8e31cca9250a56c2b2b7646d8f4b93d53213d32d1caf7d826032b3cc4f90a3dc58ec94a3678f0b8cf4598cfd73206d0376a22055f7d9c0fd13f7b108a6641f9d834362b26aafab27a6ccd13544e478143231b5410ff02c77fa2f9d74d48f1bd882f7d43b77241ce79e7719aca8949d5d7fa5a994db8ad7cb0e9bf4a99bacfe04776a4384d67c5fe57a1b6228bfa9f08ec64e198179159abafef41bc3dcd9b14fda3623a9f6cf5ff7cb0a9b019066c5781e4b51883c279c3bbd1c494f0cf051c3275a518c1dfabbf98f57cb7764b2b79b1413f68598fc27c5f375cf7fb4a2cf0e85adc713b6a9c3b81f0dbc0924019e2e270f094461d827f0cd038276cb63aa8fe8382690a08c0c22ba7fd7e7edc99b78b87b0453165bba1b3e439fcbc3ecc44bd2ac077e4e34357d3409e864e5d1264e3246b4822f74768886236842aa1cf2b3c3a097227f52808ca0cd707e8888f03af591fd11236657c4ef0c65fb19d5be72a01693f894bfb5c083526a00066e35dd340246afb9624c6bd9b052f2b5121d1f33d34977abe2e68ce3814976d9383fe3a5407d43e6a977dc062a09b56b7c8aa3cb2dd399f587b969ec1313a39f2e47067818f663510ac27c0412b44268bd10b22f4e826a1f1a03271ccaf1169472b088d076a7feaaf21d2ffa816b30676f4df835a727d4bc88e342165c324d720dac89893cfa238c342ef5f884c7c21cccbab330a6a47aeae65a88a73ddfbe5c89378e6a76d08511f33fe7826b059728125cc7bcab29242a5132ca23a4a2433f9832f47994b1795917a9713be1f02a183f38588e8dbbdf74d923d5466740b411776c00f9ec08ddb46ff942fd53e70a259c4a5d2e73c233d585d5fdfe29f2d528262661e380ae3e53fba7576dad1ff4dace9366533553434e5b2dac7d73b0e20c69be2f23a8c50ff1015c9e7cd14a43d21174a8182064d25127965228c08cfc5e4d794e243e0ff2c29ca06d64453ecce3e11f6bc2315e7bfd10f82eb97e7d8ed2d1f5e4de2c1f602b896ca5549599ddf9e81671e4a3d4fcaca9864ebb1df8a00ea57893e74f33e4eae5750563059a85b27fc9c6f8fc755dc9e21d550d3754d7c147f72a7531f5055604ce8b682fb8ed0c2db71d89e30897b2e3cfce06eeb9ffa6454a6ee195d2d4f7ea2f2a8496e8acb52665cc50d557d255e49a312a3155056e7be8114f72fc603a47f770502fd7bb24f91fef71644f31f9980e4fc1ddf5058a4faff45ddfb8f536fe33f6a2fbdc54c7f38f558fff17240dd0ffc2edfd6f88ba947ef1f193709977ffee0d4ae060b9989024d7f9550f5600a0ad7cc91465ff83f73fd7e8a804c0ca54640f2f36e1977e683f3b7511d5ad22b66708e980cced267edacfe71f97367cebf089631d86d21b103df18f53f7056efe2d1b4324d9cd77ae1574ce2e0a763bce02e37105942fb1a1e857f02da4a9110eb95a0ee49d6eb3fa0e29b0d9c2cfb5460ab377b2d76ee5eb579c8299919bd1c104cd32096497118546b856c2533bb3084e009839d36624abf34bd5ce5887f24094f7957e8f1dbc7499a98e84b8738e334eed4f608fe481b7a2ac24b40fbe7a7d3e25db097bfe695f16c698defd7e6afa55501bd5ddb635386cfbf9889d8c9915e0c1fc41ef1df9a0294e6e330b85dd991eb41c156d552290b28a4f570378a7d1509c8462a5d29ffa862d7a5a52eae8d6b1a0068a1fc1e2fe6dcb44053dd8a34d1e7e8796c5fd39d45b4112d0cae6628371bc33d4ca7f0094f8b3c6f73770f315b32a835aa70aff7f0c700f834e89ce48ddb1b14c6f6d3e79b67bc65d832d0b0d10b137a5b9d4d1a50a910e9d4f1f01b69b18113e165c4a8d193fca602c9cb154f3f621af9b61783e4b1204c00a7b987b650bdaba4a63ec3570e846634bc639e2789766eb43f971be5179dadc9cd2231418fa747a59fdbb35ad3cc17efe68e0b6237b70c370cd6e33176fa20e08a7cce4f8557e422a308c661b1cef4b466f04972ff66cabc8e69aeb743fa27bc8e2dfb59f71c7a4b0e52039c9ff13325d22dd8f287dc6568ada0dc7ed3e787c97887eefd54da918bbc5cc437d9bcaa0c6efa7590cd180202ab45df7637a3e454b9c54e68df2208b3b5499819d90daec395bfeb96b12a733432fce44062f0d8023bb6c7b6f9d933616ee11066ec2f688fc55896291e77d644c2c3059c9dd3851d5f035c105acefef3a77c5b9cef5233d540b7610e85f7b6b584992102777d59daa7d38b227d616b81ca7a24d3d74827ef05f12794295dc475ab21da74dbe4e7e5684ded70074c37aabcf013b7623b9aced14113bf6d9dfdc7ab8b5f81a63eaeda6633b6d8cd057b912c00cd30e1c27b1b7dadef9665b907d0d7bd01fefae15c52b5999c171536a8ed3846665c8d612116bd32e4e0a1df6b2ff9659069dc8c57d86a647ea377f3b02e4e4b800b75c022742903ced0d958d0de539a8c1a5e566abd833f55c2d8351da1b50bcf779779e73fa1e17634b8e617f08fe4ed35e9bada150026f282ebfa02a59d2a7de9a8e70a5d897b239173dfe75f71c03b910375edfe6a176e7978df9f3f8a1a8deef11cfcd016b8fb71e169b30476274967025ba2d6db493639b2f529df8dcb481bb1f391ef79cb960c01f405f21e6dc9dada4a74d3a9b6096bc872f4975863aa63e7da8b88c9b8479bcc3ce87c10bfe6eec68b1ea1afa2cab3eb85270c390be8805ecce70beb3bde25a4ba05ead57238a3c2c846d593490c92d5b27f2c7d41df49288d8f59abcfcc587ed4be296eb68839f0b4fb9c719ac7926579019db5db5bd00db9784fb0f69cd761d4147e47bfc3df71fa3e93cb2d95b09c18c033dafdfa02410159d3b4673e1346d5befa8bf04bbce7683b4cb492099f2d267e1b5aab5cf24acfc11a2c4fd67bcd8fcb055bc4593dc440b29484fbdf3bb9bb666d56a5413fcd31e9bc37f4e7594969fcaea36079bde429bda16b293ffda6f299515941e2eedccad9fe5d046649a4222402f80a84b254927d392428117c55d60349e17f6a2cbacdfd62fcca55d4828cc60a39179c8f9393e99778eea84463f58ffb302863a9a73267580616dc1e9c6653741953bdc35ef12ded6194416358180bc1da65d90f57b3d5151041265cda5f6af0a53599166f623bf013649e9b87c698491437245d517822b35bb8281f9da3ef6c1a4271020628a171169a1d94640e535fcd0ec7ef1864513a0b3b0b17793ff1a1fc97d205fda55144ecd9476d0c16b9d84d1db57b3d17fbf41d39a58bca3e320bd4f892b23515276068901d29847a29a184ffec71e2586c3cf0a82350e6a01dc907be5e644ff36af919964e519ec2d01c66980ca85f7ed4633e0b3d356f9b5add663602b75bc1f140d2663b7f682e633579fe659ab05f19d63de3703cf12f442bdf74541317df7b532cbcb55f3d01a0f719f504397fef3c315c26d0ecc98f9ab91b2098c72a4f459132ab73650bda0e761ab53276df8f2730209ea4550328f5f0e09906b433e73e391f4cc4ca67265a97ffdd07d5e675f0facf82aec0d1e7899e1fe68b9f1b97ded1b3e20ded75c78d9862e6e96f2637e10b47e886d6f2ff69799dd36f909149ac27633bfa51e50e0dd76c20b886bdcbfc9ec2fe312c3c63ea678bc834df39bf3a37ce273173619a6a6bd0af9231704e069e3b1911d31c61027747e978c2f6f679db1bc7f8496c3108787cd9918853b02aac173d34408f9f29d9b60c764c02e7a7b6bd8e24cfe76fd242448c7cf6b27859c6ad40817f8efb48fe98d11dc2cf4f46f31e8b1e9e0e8fe0cbcdcfbc22c9cb508d1c0876cae06bb3517513a6e0461a06c5be84197fb10eea6c8e39d91759b31843f4dd9af4d324410c44be61907f59ea1044bc6d4ee6d091dcf16008c99e6a7b765fd2852fcb7f7307de9a045e7f4059269092ce28fdff1769f415e05acf8e555a225c427bdef0144395b4c729fbd5627cb082552e2aa10c92b43a7a8b3b077a17b79727124df6bbed0182211cbebce27a3197e8281e8ce2baa8d6b01fc38db17286ed787667c3e7bc66a3f1b6fce301d0b3bd717a997c0ead324d73d5dda64b541f0dfb567186f7a38f977f8d9fd3dc12284b1f7631210add059e147317d5aae469a85888fb07778081af3c1ff5d205cf98e7701c920895fea550341b8a976c297a62b84b2d3b868b92eca089e7175c22231a17a1a88493605be02254607013b4d4e7b51035cec5c3c6a1afa2a619a1668e8664744fb3706a3b662377fc0cd46db5f03c330ac23d15dbc90cf7464fbc6b763990ce694d91b6d7e45045b25749778e7d4e1d24b120104bbe343009bfc74dfb910177e3cc2f2d0e8dd1253a52bf7d8d6e97cb2fa33147ca9fffe4dde27c49feeb310d19c35f5acada711f225f84e37e15f95d06335c83f90f21c5bc8c0a626bab89f9fe1f1f5f28f02fe278af80f131c185c6738499459fb87037cd33ba709d5350a6fd86eb093cf60788cc21e903b647128e0b44222c82b907b293f52e002c1b7b13c670909552a625ea1c33f3a30edabc0dfd9b29974c327d9703cf0f9ef8e791a2c6768235dfaecdc5b15f3d8bb8aed01162653c166abcf374cb897e2afa4ed78f90a38792870b17b25e973d98d1ba95d16258e42c3713465c5e0051d4afeda74ae70b8dacd568f36ab5c0b979924a35ffccfb1fdc94294898b7467db1d2036444cd56795e2c4fec577a4da5726824e157edcf6dbcfe041f0836cc3d2d1a792af959f6083a03d8db60a66c5e87abdc19a12c3f620fc69c88f30eb27f68ff6653f1fb9f8b9a003330891731569c1919b2b58396edb9d84336daa9f27b51d0643ff126de80001dff2a34c8ab21cad3dfa252ef18851e0b611f2deace48675944376d15a0d2704fbe0364baf3e21f2add2a59d60b6dc30196f1127a63b095770467a3a26747179fe6bf8fd32ad090b884b1a634dc8da1ec79e93f55dda78c302e08063a751ef3cc1830ef041d19fd28bfdd6a3629d9fdd9537eb962f77688bf4b9ede54ec77576f707b31d5cb1dcfe120f7c51c6f01fe54518515a81c080f3f147a9bddaa0313bb6875fdc7a701b95edb1200fb3c84c20baa81bebae8d21d5c250b669e95b30dc6962e3a517924d74a18df8b62195773386fd97b5ac4fc33d0333c9341cbe7b189e9d975d4d12007e1fd1e4e972d7822716622514ce6abcc5fd610abc5a397bb17c4b973deda3a6d467b5bd8000e9146849d9ee0d5e8731d9d26523ffd935338964c1e76e6c5ed4a2a063c5a6a630c15f0150f2e51da115849942f9e21b71686a21453cc5ac68e3763c73ef8c11c77dc622c71a57a451da8df1864cf70ed1f9dfbcc965f8d6c5c246a9c3a5032fe164025bbeefe72354c0072ed61acabedfcc23b9ed14dfe3fe189280168a25addc5b6be35d2f920dadedd5c9d608b36d1c72ef98de2324c7d9f60201f43bd0ae603503e4ccd4d2ae4a502590f68c2a7dafa57106ca025cd005354d499ea58e814f5c4e35f3c954df731b2d705ec022270dc1b06585ff2f7158d879cd6bdb80c22667415e4c9743d753f1e0ecf50a341720a8272160636beaab99cc675c0e7e907a7947935e5a6973a9cf939780dddc85ca8cf0854f916c72052a5443c413436b0d8841aa21b41b7685544b4a802be2eb24a01dee95d31625e5785643766b719904411f421140702601ef4d080b4198f84eb8d23fa1bc507d3e00dfd085e1103408f1b5a3c3e17ad9bcddc9f734164d402fd49d42492408826d167909b23e0116c6d471e13fe98fdab8d88943739a383a3dd0dd1b15d1ee06a1e3cb54542c2967087101c9e198bceb1e342a83ff07c4fe415f76edc35574da2ab768a5433567de2c06cdc9b577f917b121f4d659165e6015cee1bdcbdfdd4915b2d5d82ebc70a84ed5df8cb87cabd156dc16b131d2bf428596f83b803563925ed5589447a1db65cbff8eb7bccbee6ddf0716156fa5470d0fe4a3cf0a511453cb88b5befbbd34af1f050da7cc6e6ccd2ca38420d9ae52c91d2bde7e02900ba8e08ff7cd4863cccb80e55dbe0f61522f7b74db8f584e38a8ea8cb49f69ca36f17eac0d7c455817ec8eb3d159c1aeda6085caa473e89e4945ccd477e98cf2cd43fc527c52fc1961ce573c7a7540e0d5ac26c9f6c95d723ececffeb7951bb30d7490d2fa4f3293addba4f3159f018fa169c06a4ed1cbe20f5031481e5da88dd7e150840760779eb30fc1e50d11ff65a5a0ebab630fd8114ddacf2da77dbdad2b48acbd15452a8722eddc52c1fee0c9ac27c89319ead9a3d03d0c5daf9fd0e8e0d1e1c7d85e0676f2d5e5a4d0302973d7c99ba17d20161f0934bd6053e8f50f1471e10128b92952881682272478dddf4cbbb087366a87aa424cf7796744b32bbac89228db5119f0b0eb5e223160291825ab9dfdcc77c662f50d485c429f4f71e9ed472c246b15e5534a253ff61a7ea71bd447e5fbf421b1380db85643d4cef1d7076de2885e2dc9e6cf867009ffb8d51bbeb0730c3b7cc275ca856624e64d197d3a1419c9c729719aeca3e9a0ebf4dcc417cf2e5dbb29339807761d5b621f0834714cfb735cc041a67988dc36433eeacf99899634a6e14681f2f84ebf7c61137f4bcc6cdd6f9dd099c00b3a02c8ab57b3948bc5ed4e73500ac0b8b5e251210f43ff633265b0670814aeacdfe8695fde75775ea0df4cf13713c06cbbb0feebc5c9b9f0a3fd66da650f0855c72de64475a7fd3520027dd6077e33731ff2d5c2e6fd3542290bf2ee4e259bc1b6614e211d5c7c1552ce56924680e12d3673098816ebc68992348677cd45a905f0a12783bbad23ac98f5aa9871acf8d2cd45e9c8449ec4f5fcb270aeb5ee28eec2065fd778e2cce42826f308609eb34258473f61206ae7ea5c7e7aeef3de2e99f635dc7c0febb24dd37b8e80fcf7ccf2a3ac6eb3fc5dc8ec1bd7764fa7750d11fdefc055a958f704bbd8257ef2780d623ce751cc8bd47d27f028afdf08dae6ca2e32ced33ccfd10d07747aefa0413fd6319ef58e28758bd27bcd32198779f48fd0612ffc29addd8850e79bae728e73190ff1651f7052ef4c533dd33098f71fa8f489d0f97b66d29875babdbd2d1564436e8d866790d416b4aaa7d939aaf8b124e7325f913ec0cff60cdef41dc3df2cb7bc0937e4fe6398fa87f8ec5ec17bed90d9ceb733e996758f9ef087e67c9f54ed819ffc333dc83ba7fc691f7882ff785cc7b3e99e61cabf93f18b35b78770ff44dce4a9547ed41441ede39121bfd99e02d1907d8632348976f6c9d536a9ac2b4ebfda59d6eb2f2a52d480b72ecbdd8758a5e74c878e2a1fe03ce2fc0d6e9312bb78bb903fe1da6d5cb681cffe9e85669934c5eb198c6b1a9a3822e1e4aae80a6d72a32f0523d32f760ab0fec04794e7c1c774c3e3df57eee8e48aa0605ee0d5fba84b93c6bcf006c9b6bf644dbb85298e4241a8e57f1229ae8c18784ec309fc9e94ce108bef3555afd4dacb680a75f6bf5fbe3a89b0e32f8046fe8efcb10b619dcc21cbd8d08f8bf309415aaf17e8aaa7818a8572cdc8c4d855a9744e566f2a08e093d68fe3a6c5fd7159155e10c4cd9df51f13e50620db2af39ca7bcac953a63d7cd5fc7fc11f48b4736b429f8969e9e6a324e2092d3c4e4bac38c1d6ee4721455ae4159881fffe49395741ff78c65edeca1d0e80c698c37d95d6c9fa9194946560e7f8d51304386be680a04dc518ad4f86a186e54f3797d561a8ec8e75c3e97a3a3d0a77568b3aa10a03511208ff9f480e69aa21ee33e516ab15006ca13296cc245c95ea94ea89a65b35832e73e9baac586b429ddcab71386a9f250ad158d021ba8224cfe9ac63a518ed6821beee14cd2672591f4c33aab95ac1736d1936a7f5e6d4adfcc2e168785fa5fbf454fe18d15c8bc7602072e640eaf8470a9a7837d2d567e12699ee83e9858c1dc6a44d200d6a1dc7b3af546810d589a45e098d607e2dbfbc5075512e10bd11ce92d621d373f11f0f963ca600e518b3c15d2e107911ca2d6593dd1a73e0e65f8e966119ce9c442cd733ed6cb9ef7a4e1f433cc1d3b38d344c18341df44ca46bc38941deb0d5d42a2136a9538ce5e2de1438e34b077976eca68c954404f76e5d2765ac13562edefb6226c37ed7505206b54be7d7f7f4dbb378881affe771a735bc5154f2bd43400d8e9f487ba2611eb1a4e31683f1014dea227e389304764c879408e65ce67a3004cd12eae06410ef021b86db4ad3c033e93c9eb95201ce55e5153475202a36715c85881cc7e427b7a101719e94631d2ef47f5c05898503fc27887edf1d6c0e05a8fa4e08e5b81851e866f723a425f4267414d6977a1811a4c01bd491b3458c7328c2b9c3bf2e42996ad1951418892eef826d04c0964094e5e55f3b6cb0310380d49b9f911fe7e0291c113970c90587bd764d22ff57249359f363cb6659772d81fd146c4b2f0188d07a6737e7a2e0304e9e4b1a5fed4e4c480f395d20cca1203c79e50c644f40380424cf9bbf3b48e57cea25e7258bd0e42a79a04e618841151feb7ef2cd54929a82d7fc44738ddefa66157d07e570cf1e8e30c78666a08baea2725fada2b5e5721dc1b0e0d6ad8f45b934161bd30029dbf882ab4732e800ca2bf2f8a9469b5125b26608ee371cf4a944e6325b979ea74679195f4eba22c6daeae081075a151ab7129bf2d758a4e436a107d841aa7445e67298245983d19d6da82947d1cf8754851765c2aff167d9648299371fe7cfd5d457d89bb34abce63a4156a29ef0c06ec06ab7dad08ed6380f393d14946fca259c370bda56ade1fdfb425937d594377886c589edf8ac691b76aa5f601f4160ee3735b734f582958e9ea98875794ef890eef7ed1ff6ca8d178dfc3e4fde7b4d37c4f68c5cef11d574e03f1f96204eece4cc295db2359bed5bec49d2f8800f7150f0d0dcabe1655646bed76a0589f5dc1cd215def980912a61855114a07c3b6529516c7caaa0418ced58c3335d1a328168c258531542a244fc79d6d03001b36f42012900f01527c81ee1b69fe665949bceb747d13de22832c3ab4739a9dd60458486bab6d90d37e66f77be4208a597940958a4b56b56330ae69fd69e3a47749a9db66320397d2c68d78e77a5f903dc699b818392d25cab566abb755e3e8e4fe5aeeb76e1de2ad260c3d24371099872cea5dca15c4cdeb0657511abedd57a909064c8052bf23ef8d465830d841530a144f77b29884e8aa423be3d99b0e8bdb66748c4213f901822fabccfd08403dd98bfe3b0740db93b1f84c57eb5f0baa991e8c008e03cc75cde2dda7d591f9c149c5b76a7e27f06d4bc46d3c26d9381599a633c868245152670822c167ca01b381edc286b9660a91f842116f412c4941b30e61f6903b3f79c1b025f751e88d07dd459ad4ca9418c0cc10b7e70839a9862c4e8e396053765883d49ce2fa7958470409e50945534bd6ca2fafe919ba913e68e5acb3c5eb9c2408446f61cc0bc3e02c90a2a588c254d4b240d938ff2f1eb8170c1a31313ba2c44fba5fac29d88d23afc26af34e228f0515d4aa4f4e39830337e37f9cac17f453d364f6972868c442f12d2a0d0ba24b5bd359ab568b816e42b68f216337c2b3f2cd1d483298704b079fd588410a6d82a5dc528d660cbf2fe6ff546284c5f7f8a7adfe542bf78afa20a6106a5dfd3de9e081210e7037baac1d3c8ab641e2428a715ccedac9268296e78e5461ddbdec2ea373a9e243f0af9c777870235750c0d437e88bf0fdf7b6c5aac2682aca3c4532a1247adaff7402da9ae84d7fe639e51eee5a694b7d87c31934ab6b8e53ef4ec53edaff17e3b74a0aeaeb80e47cce8bf9825ac6f5fccb6a5ca5051837f3cfae59ee7389916285bfb371043cdda561721ca0ff3a3b6a89410b86822704ef6b9042dc42d2ec5d281f137de7795f5c1b80596d5a70e34b005c64cffb76c4c9d68c7bff1b57c60f080c780cffd8f8482e8c16f8e15a3fe87a19ba0c8cf21e78a65f4888cc9483bb7fa2399b3985c031338561c2c66f9761c29a7f39b5928f7a96fba7da89ba2dcb4ff28efc49da5ded0c9c6230c89d7e99676c1fbe80fed125054cf6d18926b7a1f33e167433ddf9fb2127f98fce0d8f70e9ff76b386948f38ee2503da19c87217dfdea6afbd0dfc1fae378554d55b425bbccc701f69c91be31c047edee9a37a542dd4d5ba8f77c6073727e7de82d2590f645b994e31b4e475ba13a52336f8b96ea23b55830ae79c751acc3ea0931b6e752e8fd2e6bf1b52a41a8e365f7a8dbfdb47fa047d757f4f4b3a0c2f90128cd7cc49ee8c20e883ffc937b53979ceea530fc57a67b65804838f5cf4ffbffae70d78f6c29e0d5f6dbf987c6cb9523557840964ea9e573e11abd44913135ffd658b6c5862279efb9ee4a0026a23a80b31d61542571e57385439293c62cf3818a8b044f0cefb78657765269e2a03aa20f070683a4dd948cce189bff5a1fee18657e3a11a1d9197006e95c17472b81d0f73625390358228262e71e20764a960c1761251f5f0ad62eb667d31fc796a273ec2c181f7e3b2e75c9268c28199548ff1514d38691e307ee31299795c98182638a8ba38a2f462f51396270c093d77cec18b4ac99edc3dbb6f2fd3b91bc2e47b922e1f3773002cad4e7e200107e365fde93a9b64fcec2a11cbd3a53c1e5c5ec0180c7dc3a88d81469006d5af37439269ad0eca11d54c46d55b7038716f791ec01a8251d00cb65bf73ac09707af1d0088f355fde1aca704d6d29c48a734ea8fc7d7b66c715a182b28d8c8a61f81518ad06c7e1ddf3c702868e92e3749df5c5c63bbe7f62d3889e9ec5bd5a3f21c75f9873deefe0957851d38bfa4452e019cb59f6704212cc3c9d5aac803b98e162f3503a7a19f50f5efc50802c001c0c3c861ede7dc622cdee600d9091b365681b1e0aea0dc3ed685c53d7ff8b7fba02c8de07b95d61ea7cf0270785897de290ab81b5da2f54f05638498a23fd89fcc3f93c8d7fb7e2efe561d2c128e119bd4c9b78e6462a66dc8cfbbaa98b406f59602070fc6351cea29efad12913429d1af1e9b47dfd9c39a0a1835d578d9ce2c66d236ed03122955e1687ed3772079e7fc14ff72e1791a89d8f4dc1b4ed1583412c9afdf69642af255d0a3d5b1184193c3d9d1c7f3d1b8f408d1a24458920baa4221300a8da6e98fb486992013ce0080be5f2f366066aa1428100b1f47f3d299d33f3a146b11f88a54d5c582003a8acafda7e2249b06fea31078791dc6c89c6073cbd17fee0a0178691f3a8bf6fc7072142cfe1097ed8f7b8a11cc7ad1eac2a3f0bdbc32b30b9b223dc6d2873b4e7bdd7ab11372651f6c7a77eff0f797b42fadd48e0cd6ba28e6779a5c50a516a75426da820fa9dda08788b4b3639ce7c03b21d644d8906970eaa1444d638bb10be3cf01b7e48054e04f7f03994305bdbc0e2f85b4e8dfa0a320e288e64fc3635acec94c1966d2aa3e258bf1e3ba7267a1dbad3fd672f28326ecc7994f99bfc33c3dffcbbbddb194e8049a0ab45f977eeb2854764e668f019a2cd055d24e837c261bc30ae2dbe71272e44647681857f82074e0258f411230e79eb3df49290e47a587341633919aac847b193cb9a3aa5b03a911b2318ad8d21730cf5457f8844f53fe887846611f35c30aef86f77e1c3dc5641a0f38d99c736b0ebb1bd0efd8842c6ea3e575d0fc83f59970a6a3b0b82d685c859ae7592e74db3db78b13906df5db8dbf5072cc46d9b73ac4857438f72275a754bc9542564cfdd1bbad45f23c03f6929a90686282d3ff2b22c1630de14c5c4140b63281ba06779b80aacc7837ccaeab72f038663c1365ad85e515c5951cc324c0df5fb94cf8efa816b6a8f50ff6b55821ed2e5dcc355b3b0ca8c6f206d5a33f30e6d51c49a6f48ea067f8d755433d660580fcc7cf69afa8b81afcea8ce56fa1358a0e9a0826ffed89ac0ab01c32e12fbf2f8938e7ed6b7206c8cd7f284faf7bdb224252601cebaf4708cf0caf79d6911e7b7f0699ad0403f629185424d03e37de80a54278810d4859854592c80a8d868c4261e85ee2b332ebb01ce4fe9979d31e41384da129c48a87b664081b759e8b2aac6474ee7840ae04b5a336ce3777720faddc03371a4c7ddc3112c4fee924d8b96002c2f3c51033ae59edd636e28e2eae168d5fe21a19c70d9d755481a21cfa2b45f7a1a2c5b707c676212027a2a70d1414d222b61df192284584f8bd3221f640bf27ce24a48a1996e52153ff1d71eb5a5848dd2fdaa5e811bec2db09dc45c09009d2cba298c768af14194aa1ce6ad22bf07d264055123ecea8f8552e20c207521340c7900f48ba849114b5e9b49bad485df18390c2b4b112f1be2080bc001404a25a50eab7f003773acb60199bda8cbfc1c19f14adf8de57c5d442299a4de5553d4b2a49caf6fc4b386943b12f10bf2654221abc7227a9393a45b72e30f18b9ad29ea68e8475cc3a4e7ae65107266fecd565fb7c62571f86bfd144a8107599130994473c05f718762069a7de8332be43a4bd21a1b7c2d0da562612a198ef7d23deedc69c10f29ebd3e5cc9bd1142f29799ff92e58254f76ceac7d93b1858fc44be0550ab70efeaca05d911b3c8730edce6f5dea8739daadd86d8c7f229405808434e63f92bd7a5e9bd013731ea63a5f5f96257da410c7c9e2f0b5eb4435346b2a5b278020e991cbf074452e048bbcccd6cd37fd20bff9c59d8b37f87028acbf7833675437e6a8f822bdbdd6d55ce78ffab18cddd25a0b6c6bbbda4a565983441eb0226ab1a0436746760b0a39de82a8d945f9cb2d2aa3f9498d859daa439c1e553f269ea7d54eff10971fdff77ddf9034e196214bf15a475db8c318c88bfc4178542cfab259842141242bc5457d3ea06c2f135f66eee45280cccf260ee3a3d942a79d0ed370bf7cf5feb147c69c59e59942e44c21d6decd8a65a120a7e0403d93776f7f141789e104a8a5ddb92052b13aacc4e638b273b7a46a66330c3607279fa9e18ef448f6dce913b9d180432126850362921ecd5ecee1d008591d439e0b327122a9d0446d8f38998da0936a6d5ba442074cf0d2fb551b806ceac5553a94b0db55312a847ca3c35a85192d685faef3f9ee305000b5707c67ccf7bf5316efda9c4338222198dd85beebb13c59f0234b3ca94d73c84bc0eb8aeab5b2ea129d6f05c52c7039489ec75367fb10662490f82e1e0c6af070361312e9cf79e32c91ffe7cf19e686317fd371faaf1e810801bfce726da49f90905feb71d63cc9a4205623e0bc3cd59754c6306ff8eda75032bd69237cbd01287cb9d8530405f0ab68877b9bd9e0aa8ee432267d7af5b9ecc15d9525672f12038425c5d7abde9ce0403518b70ffee4a49df2f5045898012ecf026cb6c0dd9cbd2870becb97820f6e3c1ccef5dee9c841386ece9846ed887a74268866588c22d753822d625e5236eebd23bbbff3ee01a92f1bba22b8a1c70fd17baf1cd4d820ee3c6ba0a52afe0a86e3fef037c42da5e24f3e6f340a24d07276fcfaaf8ea0102dc33b05e8ff21d466054ff7c8430ba7711608fec67517b5eb4ff2165df2bcc2ecece05d17e5969353270a53aed14332d7c4d912a99727276303fb9c3a8baea3dc392cf92b20dd4b97f317a248decc7ae80638e1be9c75296fc8cffc998fa153afcaff3a1307edb209ba18d6c917b25a40b85ef1300ed01c389bbb5b6ec3600e63c78ae3c1eb2b05d24158aa0a56510719fae621adc8f5bfc2e1fd26acff09f46fbc6846bca42509e59045e535d9ac209d9ddbf7daa963035f762c53e5ca5513057d2e6ae2a151c673429d73cb45ce9d58fe5c8eac2c1e48c73180d310fcc9990b5db47b2940c1542099e497b8f6ff87037824abecef984a3df9774b9e4df45b05b5afe47d66c685dbb9ba84224d82f5707b5bf4d6c23007e01588ac3f89cfb65c19ffc5187083b9e08b7b77c060f485cf8c63c3fb892fe93a2a77a67ccbf97fc4cba0fe84b6279784ee999850cb07508bcb31e711da409e61b778c9d0ae2b52cac618e3f5c205264a0cd586507713b56246b756297185dd868fdcd35ece7f769e70096d2ed1e31f9ef3b465df0a4e125d43c2bbfaf0c1779c0870b2f2ab65a0fe95aa742a371f34c4bda98b4359110a739fc9fee704a44f7d6268e01040a07ffbc3059d3fdf8ec39ba96e81fef35dffb7624125d68d14e015561d9699c0a403ff1d10fd500491cb252c2abd15f5c214bf11966b4942c4b5234073f3f7055bdb357df38cddd24eb18cf7969016f9ac489f40c365a8eddda1a6ca3afba9791f411c213ed178ff0dfb83945ed1288aeebd382d064097c61db6c5bb11795cdb7acb8e845bcd8610d7629488a8b4bf062807f8860dd36e9a2271d62b3ed052a31653764a0b4a561d22bd266878f32a56f95908163512fa75b4ffcd8a3b3586b029f2084938e5ff26dbfd27e35d79de0318204a22404d19185ea7ecf6a799127ab5cb5bf8f9c15b459309d1f9e925f40a30b5934947feaffcecff16fc33fc9fd5c8dfe5dfa1fb99f63bfaefc47fc6b99f79fc59f433decfbffddaaf768233507f66fe2ce177f5affdecebe77eb9f3fb4b24015410027e2d45c00c3080b442e5f030c30c33cc30c30c33cc5a4b2585984d994b45ddd62969a7faa4a44c929bb47f9292724bb9a5bcb37fef4b310d7f0c830c6883e52c052f2ebe7010b41aec97b4217ce935b892063bac3f6c0c32833dc7bf2138fcc24a065bdace9d0821e3431983256fe87e8a7ae34f00186c9f918b26cee4fdfc158b173f79fd43e7bf5db15ae51b73d405e10bd28a6de2ea9f898a76c1acd8c3b91e8308aaabae6271d0738fcbc18b82aad822478e2c7ddc0d612a96ba345d79f2622e0a2a76ca8c7299947a61e4143b97175cdc85606b9a622dafff2fcab8a01917a5d83148a49acbd0d322c53e8e6a572a6ef3e346b1895788d417a6a92d8a1da408f2a8e2e7e442b11735fe5ee9e213fbc240b1797a811773813e7c413eb1834df895b8ce943db18998a84aac7c56756287d45d58e5290e8e0b4eeca0299e8b8baabc2864137bc388875ace53a5269648625efbf83fc9c4f2e3c520ead9e53630b18a84d5f5788cb1a94bec11a526ffe3ef828a2576e666580f1f95d8211739be8d12ab9d634a25611994935826f57f911724efcb49628b7a1a97b98b6f9c1189659d72793dd4b21d126b6ecd5c86663f9347ecfc2036274c8889c8116b4ff408392f57ac1bb1797e7198cc45050923b6f5b4ad2ec905b62d62a9ce7e0ca6d352a588f552ceeb82e8dc906606908875af27848c1c95563211b1ae4eca8f29d2c5c55ccc21b692bc4cb9b8be92b921d6b5f988eac50529c4b68fd41e4391e7cb1142ecdf602ae30ade20f694474bab0ce63f7d412cdba844cc513c103b4a6692947f1925b300b1175d55e385179896fc87c5e2f9398e4809b5f8616d946ce6c931a8cadf87f5f24846de17be22271fd6c80fcbf156e5ee2ff6b087881705f9e2fedefa420f4b724c5e90e9f8c595e73c2c1ba2e618945aa4947858b6baa62fada249c3efb0c494f0eace67e0b0db612dd1bbc887f9a315acc3e6d8e0ff24432ecb0d1d166f94921a85840bdfe7b0c57c609efa8c1cb68cba8254feedf5e2280e7b35d4f4df2fec4876c36151bf8712a763baa6f1862d7add3eb058eda23dddb07833d85e90d0d023d486254de40bbb3472a67c362c3ef9c58c2e2c9e49c61ad67df8e18d0bf641eda786e556c531acc8855ed8751ad6460e96ea19549c09a3618b0b61e476baf9ae3bc35e0c2b7c3755b2069a9b61a7641e19a84733985c199670a152f4118ff0359361fd024997dbffc5e53019c3fee0bbc88ba1535f7e8618d66f90ccab7752cfc161d86e4f2a49797675a1050c4b6c7f91ed6d838afe17d6e98226c7851a0db242bcb0173ec686dcb491192e5dd8fa72857990e7c2f6a80bf477d4ab8b8b315b581acaa52f9e5ec745266b610bfee963c1318e956416166f38123ab77271cd8e851d3ac317aa84f5142fe60a7bfe7753548815f63107b152b053c9456b1596e8b0d3730e34a7472aacf538696bb91557196618c01496f853798fa1b7d1cd4818801416cb69ab9137d67746617998d8aa7c71d56383c2a2f1a0d224470da12b3e18c01396fdb3c9f4c53c51224e58bc60b51e1ea4b9f21a973080266c0e961bbf2849ec7c914cd881d95ec6188fa9834bd81e598a1ff6bd12564ba1f4316572f15830097b9117c4798183a59360226107167fdb0d73f3d51f619fe642f5a20c62e432232c16bd2cc74fa660292ac2ce1d8dacc632052d2f88b07a71e99e85f9e28bab0d61f57aec6c2835e34c0b61cbb3c6f45f54191284fde23c1c66751a3c03c29a5f5f14661b584891f2832596d6443959dd6dce07ebc373262f14e7b1abf4608b5d5c703a71fb1a55435cdb69b81d41dec1d62717274b2b6358193a58fa81e3ac982ff8623207cb1779a1845e4bbda6100eb6c745cf4076e2cf46bac1964243f2e2fe0cfd306db09887a5e8c59f5ed5b001d460874ce73e87b8670e1a000d96caf8a781830c2bad170398c13ac10b65e6baa8b71e320019ac5ea4e233bef7c8bce001c460bd78f31bfe8fb9a80b1b000c7646121f12673fe2f3572c9bb75f5c78299d86e35cb1e9e5c2cf2fb8882feabe15ab75e47e74488cf84856ac8e967285e40ffd1ab58a1dbf3066227a4154b143edccf96628531a49c55e4ccd209f1fff3292a0623dd5abafda49e3c5df29f6dec818bd5ce943ba30c5f6382f635c8c5d5cb18f521ccd5cf81cf720c5eab9eb5cfcf01ead3da3d851ec82cb1de1d138a88862d98c183f378d112617a158d782498559799ee400c5ce94bea851379e4859f9c40e9cbff0f2652e99ca3db1855c5cb06afd99eae075622f08d18bba2067772dc29cd82e4f74b4de475fbcd32616871352542f7c1e17179a58cb312e66a8abaf46662676d8051d79caa1369a11134b45d549f514b441865c62fd82d49fba9a961bc4123b173fe302dbf45d0da7123bead45d486b9332fe94d833a40b6abee021d62993d8e2ef5786ce10f5b04b62ffbe493fa1c2e9fc1e89c51aa567c56d4e9c1d12ebc454def4227fe0188fd86942b29e5c5c9be79023b68c34f5822aaf115b060daa5e5e297c51c3882dcdf36a2ea647a369115b9471cac593fa9e4a55c44e29f94e46a19be2c389d8a146955544a724b97044acf1851d8ef6fb436cb90bd5f4a46b432c8e0b7c279a776b532bc4d2c87131c811246e454e88e571a1634c0407fdd718c45edcfce8f29dcff3658258f2e983c6d493d44f09c46a96616699ff173c8d80d8ccbe687d82447d48973fac96a21bbbc8baaa8b563f6cc11e84fb8a72f85ffbb0d8c58306a1d60c3de1c39e528ee1e4973d2c3f114bb6aba40b75d3c3faf3053df3a0ae2995872d3454bee8db89fb0c1e364b29831a3309178fdf61f34effb094b9f0d6473bec79d1a9e13cbe3145ebb07a048bf9e9ccbe2e900efb6f17e3c26e0ef5c77f0e3becc529b12e6cbca3c9612fb114e743eeb4bb12877dbbb860f2d417eca389c061fbd1d25013c9f90dbe61bf2ef2d16cfcfbcb1437ac166cfbf9bef68bba6ac3d64556bf4fe6b1619baaf891d5285a2e88ad615f070e4e5245189fa41af6c2c615cf4feaf428230d6bd9faf77f51367ac4d0b0aa599e83cc20e93dfa0c7b79312ec8d7203ece39cdb0cf68483f92ca2e78bc0cfbde78319e7cccc8c149864d72918aa73e6a8c3a1fc37291feea4f22e4d5258625be48a57ca5a1719f61d81b39ca8314b6cb260486652ff6f5fa448edef6851d832fd38693341ec45ed82bc71b7d312ece49d77561092f08fda8c7336b2c5cd871a9e5edcee8af49cb80c51656f59bd23b0bb3ada711586861fd42c7781cd2171744860b8b2c2c91f6a2c157bce846222d021658d832d623d8d35ddd973a042caeb093dede452f9eb87c5f5861938ce22087c33c875514b0a8c2a2b3d3459615378229a803165458b4d6714efa6a8a2e060448030f584c61892e9cff294779c80317a482159c40052bb8c0165ba08004154001094880675ae8010b296c4dbde314aa32a9588a03213841035c50fe1d801739c0220aeb7df64ff44b1965170a02a41999c0020a6bff34dda4bbac9f140448ba000d448038900215941298168dc0e2094b55491785b05d346212fd010b27ac5e0cee6117983a2ebc10042960099c0d096cb1450a16f080079402ee804513b6f0e27ee0e82b56d22e1681051396906ff4428a57ce05211020d5e040084eb005e1b6b1062c96b0854d87728c0fbb982e1020d1165b9c200422c8c0165b7cbb40052150c1165b6cb1450a1ef0800a6c608b2d1eb0805112d8628b2db6e8101c0750f023e8770f6c715159d8010b25ecf0c5209c6869173dc5408084495852aa2f7caa8b0e2d6420407a149c60d00234108105bc000b24ec941b98a5935cace34080b4821378a0c641608b2d8e80c511f6eb825c58c9f4a24f835b6c91021198c0042030c21e8d1e55729a99f06111361d5f2f3c67f8dcbb614184edee4153fe7631841dd68b812547c962c7888510988d905d4c9936231020a120041e20c20e6011842de5d47b24fbd1dd0c0f78608c126c608b2d9c800510b62af3c28f5809cbbe418069810e78a00558fc60fd4e67b4270e233a0502a48fc0f8607fc6b16929c6c53c9082104c998008fa41f0002c7ab0e41b7ff0402272d13f1e50c17f0049051f81ca01163c58ab23bab252244e93b583bd31c87839177d917ad143073bcd85c385e00cd9d3b040073c100021609183bdd1f76737f3d2c48f2881050ea6495692634f1ff2cb031637e8ecc2579983918480850d567d985ca9ca05b9956c01638086053ae0010088028b1aac5b958ec13967a2e44bf08110a4e06680050d96beedeffc228bf5008b19d09043c3d6bfa13997011d29bdc6d471a48ec12893e40851a41c1ec8f1062c60b017af8374714cffd6f7572c5fd67026b9c9ab92aed8ca2ffd63e8f478bb4010200d290e04d08a1d7e41ec5d79d4d32edc060504c08af51f5ee53da72f2eb27b011a88c0029a51b082ee06a0e05560020ea8a0044f02c2820b0258c51af5552629df9978a18a1d671768989da35095610201a4623b33eba24a3e79c2178c8aa5721788a4a49f10a2758a2d7f51f8ae70eb317d5e100304608a4dbd20725a06292347469562af20fafb0527c161c3a4d8672b4ffea2937cdef851ece074de14721623a442908210b04017a08108a82004290801073ce0812db6f02db678087880100210c59e17eb3f24af20407a0a6c118ab50bbacb67f5bf51761020b5805130e3020200c56a35a98b5208b2155a810029891c20804fac5dbc9a0da236acb25406c69080003cb1a5958db3957e0702e8c43651b1514aead8e9c5451104c0892d65f062385f10e6a00b0ce658177c58fe2ce4a43cfe94af3decd7a85197cc1bedd2c336f2a7937a1397ab3cac1be7406fc7a3fc81872dc3cbdc2f4c8b8b8c3becb87b5eccd1b0c3663efa636b27961975582b4abf792333a4890efb3d58a4f2f5c645d3c51c965c908eacc4e9b9a30b39ece30529a99c3e358c2ee2b038ea828f7412da0fba80c33ae3685d7e710fcfc51b9610fcaa391b1a8673e1864dc2b38bd18b442c632edab05a2e0eed95e6820d6b175e66a420c9cf52d6b023c9055e9061c5492b6ad8919a4e4c75777117250dcb1764101ec7d6e455d0b07a7181431cc79bfa9433acabb1395e1c5d3bbd1976cac511950b3efd992fc3dea0fefe4127c38ee1ae31d584b0e118b690a13bbb30924c4c0cfbac6ca58df59a5c84617310d4b1c1d8d7d560d82464c8cc0afa51f517163ba7f38dee08a1f6c2cee9688274d685e5416ca835f17a245cd862278a3ea7e406d9c2328da37f3bba98632dac158f1f533959d80b8295748eaf6c47b0b06f44fca38c5c614bbddcd554eadf05b1c256c1e1ca64cd7717a40aeb7ee96765948a3d15d62f6a1ce19ca59af21476a4d9db9b4961fd229b1016ff723e1c857d7c22ea7f7158faa1b0daa3f353fe8425c33137d4ea84c542fe08996e42c1bf49fe74a24c584c2aaf4cf0f21475095bfa9f8cbe702c75315409cb17c7351c95a8be2461b3eae2ae348f815490b05f888d61329ecdff087b316e45e538eae2dc083bfcc90d2699852eb8085be77c8e1704d34626115627f18be3bbcd610e61e74287f8a02b646aa41036cb05bab2b6935224087b61f7c817e487095120ac631f16b33288ebfd60a9745f28e51b5ee805fa60c97b3c95cee146853d582c3d6a98e4053212f260cd2eec86a32ab9c8b2836df4bf1c4f84435c079bfa4fe4c6e497f21c6c519df145f17e2f8d83f56672173ffc459e6fb0996d3c8dcf4a486db09617fac503d11bb1066be42e861247527f7834d8c17ec1dc9c56cacfcd60cb789c5f5c600f42730690c18e6ab91b5ed4c5a834400c96a7d08f5176e144680680c1ba22711de5f54dcc5eb1ed34c3925cd445dd85b96289795dd43df9562cf705b7cff5c55cf05db0622f8c088b679579ba8b55ec4536fbfbd8852a36399d47c1cb71e3e222153b6e4ee58f861bd3052a9648d1df7cbe87cfc52916f9a22e7e7e9ac64529532c21b3b6c1fbca51aa14cb17851d47490b9b1729d6c72058a7669fe6358ac5b3617f777c43bb44b11765c3034fed2f86542816c7b8316c17058a352bacf1b3ac741f9fd82c8417173f9ad4e01e9ed8f24e2ebcfdc290894727760c26b9c031a3b36e7062bd09714d93f3cfc5d8c41271299a04f1427b0c4d2c325f5c27eb3c17a64cec5d8c8be70b272389326162b51cc997a39b23d325164d2771da98502b5962f199eda22fe8754652556279864b672a9a235251622f8a2bc9496bf00faa496c8f0bd5223f48ea864a127beca77731fa42b17e2a127b832f2e8af8a220159f82c40e61792f8789e437f5884dbef6ea8b56f2ba9872c4d62836de06a6b58da9462cc98b1fbbe3c288f52478ac1747a6189745eca8219848b84c911645ace760c6529e5eca4549c416c5d19e51b86b5c14446c51170e12b93852ff432ca9ffebb38bc21e7f436cd29712511d3306bf10cb5ce38ae9c21bb39e104b65e862eae807b1448894f9932964e805b14d7a10c7f4221ced81d8bb18c4f8c2887a0e71406c5197bb52708c22f91f76c6696bf9c2cd45ee87ed415e065e3c99c2a5fbb043fb505fcbcba79b0f7b819e6f45bc4ce5e83d2cfa999751a4d0a5133dec93ebe9624cf2b0c3af54c3ebafc7e361c955a972419434e47758f2a45cbd8f3aaada611dcb17254aaec3e28f64b67fcd67643a2ccd13e6c7e339ec60ab82a663fc1162392c59e705292f533ec471d892438613d3bcc153382c32b9a3d249b4fb37ace75dbc1f755749926ed8bc1817e617c6d98635b3a27cd2a30cd364c3965233652e9b942dd7b09dced9fde95e84520dcb04897afae242ab4ca6619547d1a8cd2e2ef2110dcba4d82faa1bcfb0a335e9fe88265fa319564d87106bd40d1f9661fbe29d58ce38a6ec23c35222918bb9482a7fc4c6b037dcca2e5b2f52d9c4b036e66260b9931a432d0c3b467c4f03a9f4a481610b17718eb20fbd18f6851de6d40bea51aa19e6852576c1d4e58889e55817965c142ca475a558ff0517b6eda27c0d65b94822175bd81b494ad5edeea2e48516b6c84dbfe92ec85fd84516965fed10fbb17d5c5c6061fbf00736f7c50596d61596d11aafd2ca7d66596153cf932e8ecb38b6aac25215b1c67fb491174585d58be24878d137372e6a0aab5fdad0f4c2497b9414f6ce9af0652219fe118555a70b5792e5922e7e4061c994e1dc642841d2e3096bff4dbab49420f370c2fa1522b52fe3a21c8f26ecb8e8a36922855d720c26ecc515191717838c8b611c6309ab897ecf9e77317c8ca184e58b2e552e4c93b04aeaa25e9f7534261296994dbf46b1cb23acab2112b374a43f23ecc5a02c3c99f3548ab03cd45eae53a67a414458bb22352e0cbbb279084b7cfc450e72d5e52285b0237b8ce651175f7e3382b04c2e2e1c9f08dfe403612f8a1276af71f1ccfd837d52ca8f8fe362ea83b51c6a32c43dd86189da455a78b043f54c700c698e2c3bd853b6be98411c92570aa083551f75d103afd4f8a21420075b34c31bff825cd14529000e76e8e26250952117aa540a70833df772338c8a8da614c0067b3f99ef78a1a5a67c016ab09e63f8bcca48f9ff02d060e98c5e8f4792667f0166b0c54a5d0cfbafaea15f00196c92a99b62927dc3be0031d8bfe87366be0bfaa32f000cb6d8d0b914d6a13fff8abdb83a72c52e9c9bde5db13a4e8f8be705f9b0b762af89e65b954d937356ec5b3f192b1e4de47c153bbaf14621f145c973552c12767e463245fbc253b14fa420a19afb9b0b47c5922145efca7c2ebcfc14db36452f869592cee1a6d8bcc02c4555a97ebc4bb1c5b95427eb9342dda4d81a8ae46210f7e75d8f62dbac2fb4919bb017228a2d4efdd39e17e5e2a290506cb75eb4162b17a30713502c26f12aa2483eb19405cb076179bc20e2894d57fdd252468dff4e2ce95fe8409cb21cce89ed9c419457ee2ec636b184ab340e91ba19d3c48e8fabe131218dc499d82bcf3dda2f92bd8831b1765ceaf1868d51b9c45e5c34b79522679d5a62c7bf8e233f4c17c42ab1daa86410bc504aec238ecf8b7f328e4327b147a58b48bf24762839e36019617e24f646218394143dbd87c4aa72195c849fd8fb23564d3d2faab423f6e82a078ee139bc68c432ab998d95c11755c98875ca8bea6cf7a39c5cc4f6188f5a38a9882d3d08b9d09bb7cb4fc47a124f322435478f882553c73cca0fb19a9d48906f06b930432c99f514bc53b31e85d80b2f7e8439ac141b24c4e2b95e78e1c50d6269a6d9c74f105bec4afec7b810d10bc4f2450eae52b0758c3b40ec859691d105233ab9b83facf27b978275355ae787f5b471f7e402fb7a5c1ff69595faa2c697533a3e2c19e50f2be57db2d81eb6a998c8c81a9ed8a68755b6cb6953c284a8e561bb5cbc37f90bce3e353c6c127b97c1a40bf3b43becc0bfc22369873d257a3166aa7c0cd661c790a3ac52081e191dd67a1e1bf3f1cac5d81c36c7455db5f9c585cdcb610bf1ba502a9b2ad871d861f6348973979d705872eae136e5e9e2e22edeb0ec89f817e322f3e2dc0deb7f31c685151a3c536dd8be68af31dd552e6a8a0dabfef445ee54ad94352cdecfc520c58d9c1135ac531eff78ce67b634ac7fde90e262894c030d7bda63e450bc7eff336c299ae441c736ee66d842468c24e10c825a863de6d3228744645892a5b01dd218966bea22877c0f9d17c35a3b21c3cf31be6818b6e78911e379219560d8d3ef2a3208e2cdc517b6e9b9491bd7459531e485a5caaba3aba19d33d485fd77b5524946d5457361cbfd613af58d41b285352e989e7a917717440b7b31a68f8b9fe6f14a1656a7702bd54cf9ac8285a551a35c54f65f610b7932194e8d0bd2b7c2f2c8b361785f851d452bd4197d41d49e0a7bf1337a7f71dc86e3a7b02589530e2a8ed67829ec5da69bf3f9e8178fc28e31ae5aba9873b04361e9cef99ac62e304b3f6149fe272a999946d24e582467a5df5907237713b6cbfc90fbb2528e9b09cb558a5d84f0456a214b5827549a901a2f468528616f5cd7bfcd05b13e49c22213d65ba9fc8b7b82842546caf033d25a869323ec2035ace7746184a52a786168faf317468ab0e4da64b8944af34188b054aa78731aba7219c2963e53b1fd28bd2842d82617dcc37d545c9383b0d59e17ca8388d9053210b64a7517215f10f5f807ab39da64384f9671ec831d6de6eb1ca5a3dd834dbd203546f35fa812e5c1d6b35e24217e31235177b0c44e443e2ec6dc40d5c1a6d1204509166b3234073b088f2746fe2b6d1c2cd120a68f575a9f6fb03586d818ecbfb8e82684cdf6b457bdb72e7a1184d5e7bbb80be6d38ba11740d88beb33f4622f23ede207cbed885afc7d34791f2c13b940a5fff16bac1eec8dc90b672d35c9583cd8d3d2452edce78b5bed60cf4d4db310a2d8a374b0d5f74eea62f0fd98cac116ccbb40471e6b263858a546aa8b6bcc627283cdcb36b6928514641b2c29f95452cb2f2a71d46011331bbd14bcd0c391050d16754629e6e4ec42238b19ec50b7823d1717c47e461632d8276cf47e39c885cfc822064ba4eea2bc73a7716701837552ea6248197931d5f48abdfeb22a23e48acdb14ee5d671e342a9154bf94a2ed0bcad5c112b965bb189d89fce0fe52a96ca7067bf12d3f293aad88be269b31c93a9d8312e486fda6a0a7912157bf5e4085f8c5184d8e429969e7819a53cabf5c5a42976dc2f922e9208ea6b29053dddf7b05d1452ac71dd202f3d8a2de5063d1e8d3131516cb9e217e759379df6a1d8e75234e74d54e6e241b17da32f2e90a673e8fc27f6c7208fbac841cacd7b6253cd95ae99af74e9c41eb9e871e117dfa7178513ab64d450958b60f94d2c1975e17f93d6faaf893d521739689e89e5e1425a3da7c605c1c4f2575fdc393fe5eb25963452e245e1617a6789d572e5a5f4c22bb18d2493f494d9bf9c127b7d5185644c65a47c127b43bd2e8a674b628bc619e11b8a6fd791d88b1f2faf36ba68584362d12c89fa66eeaafa117b37c6e363be919b38625bb3a015d3bcfd9146ec9451c5f5c24a5ee40561c4f20597fac6ef523a64116b4e9c8c2edcfde29215b1694ee3860fca21c889d8513f178f365a129111b1d6470ade97e231e4436c294853643418eb820db163080fc149bd301e5c88edb92232bec0f74725c43219a771323f5da883581bbd287cd1c959c8850a622fbc708cb6719a930662f16894418e14105b48874687587923fdc392a3cd201ebe201af5c3feb85e0c25bebb48927dd82383e31ae7a25c5c5cf2619194e634d6d4055ee41ed6dbc694af61177431a98725ee2a4985f3b043b30c998bb14967c4c3b6bf95c6f18bf966bcc396377fccf277e414edb07df1538809621df68e0c73c20b42bc07d2618fd9e72e09fa450dce611579102725b129f1e4b0347cc32ec605d1c5d0c561b59f8cc6e371eb1b1ca8b8387ae5db1b96c8f9f0cf2bde9de6861d1c0507bb204e396bc372e6055f9dd34d9fb161c9307f3562395717b6861da3320bfe118d95a961eb22eb48df05928bd18b342c8eee7ff78153662ed0b0e5e6af4669d0f3459d61b390c7b2e932c3feb09b317e72265565d82a3588b29120da0f322cc9f134682ece88eb18c392a2c5fee78246298718d6b18e8ccb8b43541c61582c1e84cfc1b03cd2959ddcc705e11796cf075d549971f18517f6829110bb384e1a3ca30b8b4fb28b4cef473d17369f3c2ff42e546d7a0b7b431baf86a3e1102dec5c3492d3fc5342cec22231e7b9ac99ee222c2c21835017b151e6afb0e675c446aafbe6adb01754ee483e9146e12aecf1dc0541367da3a3c2a25f909e6bcfab4d614baffd28098e5f486159cb9b8b4ea132a2b086648ce6d8201476e6e2bdb22f069fb0a410662be4641a17834ed8319635652ea8d028a509eb54f0ad2f88f8290b1376a07191d40b4f9a2a4b58ad4257ce473d4645099b67d65a9cbf46964fc26af98bb46133bffb47c2be5fd4a1169b2e247f84254fc898dbe0bf607d236c67f1b3b5635fa47d11f6713a9591d8940b7b22ecdb301d8f66e4a28b0f619d55077a92226fef42d84aaac2191d84655246cd0529f73475202ce228c5e3e3d4d1fc074b2ef82e0b5d5c90f7b80ff6c295bc865cf45cb0750f164b5d5c50c92cff71d13cd839b51e9ca6ce8b263bd80b52ca5d94a30e16af0ce79aa01a19c9c192e4d145788c243f0eb64c3a97a6df60ddee8bcc881160834523bbcb8bf1c18b6104d460592f2e48f277e6dd5004d060897627b3935e347a2260067b913fb29ceaa2a079224006db53374e985edc241110832db4247bbf303f268900182c2ae98d15756572be62edc978277caed81e4e867e769ead58beb8a8e2aedce5da58b1ea55776723157b154bd58833598c6c17a98aa57241fc825cdce97f49c5aa1321997abd988b43c5fe156cc3b2e3f353ecc51dd10bd20b1c5d85a6d8bbb850c4bb2fbfc02fc5d6f0c5c5b82817374f4e8a3d52ca4521fd2474318ab529cacce38c9e5a148b547e849a5c5c14d250ac31fff15fdcdd0140b1f9fd4df63ab078ee0ef0891d983f55d28a6b12bb037882bbcac65ddc7562e9bd88a2a5fd78334eecb89be471514af128dbc45ea09f16a33b6c1fa6892d38705c1869fe5d8c6562398f09f569e605154c2ca316b3c1a49fe69758ce2ecb9f1e25634b6cb9a2c41a7851892d4b561ac2d31e171794d8baf0e2e274e4d7ba98c4664126334ab50b8e0b496c521dfecd57249610baf192889dc50b124b1724ad8cf81d7ed72376188e4f2af43143cb11fb9d9564beb0625e5423567990517cc1a39aca60c40e1c524a7627f10b1e8bd8e7e966e2a188b58283584e4f32de48c492c2449f2e0a9ed20d446c9792f352184bb9c621964793496b2f171736e30cb15688e7b98f724e9eae107b783196fe34ac98d3116247e1d20beb192f6f748358e2c2e9c2cade6d7482d81aa3b8e485bb8d5fd005622f7cde2fcab50eb741078825452b86ac7fac64ee0f5b4e8ca61c12e3e89c1f960a91561123429f737dd8a477a6bf20f67235c7871d4c481ef685a39231b7872d5f3fc3c97e1c8f393d2cd2fd30ce79939fb93cec75969265bce061f3bd70753b65c152eeb0a58a36952bbac62e76d8263688678e312a49a9c3e2b0bf284e88e52faed0612f1a890d2c539d73650eeb5c5fb8a9dcc89497c3d2d12929df715862c8c57fc549cc70581eca8b0b1a9d7faf6fd8babc463ba72a76ef861dd3d6410c099beadbb0a8ddd417a5ca5f0c61c3da58a1cc6c3c42780d3b6c53f22e500d4bd843869291cf6d69d861ca417441cc0e8086a52af433fd7167df7680336ccd10277c418585d6760033380ea1a30fea326c910b2a6a6e438d0b21c372f9e05333a9422763d82cb7329c0cc2324ac4b0fa494488ecc7639230acebc5948fc6ff72c560587291a3c855f2470ffec2fe253e5d217f395cbdb0452f94f9e29eb290d42eec38db455df1c1e322950b3b38589a8478675ee81656ff6a5ce0205c984a6a61fbc26908e11c3f43330b7bc145569c34b1b076e13df8228b0fcee515b654933311252587a515d6aa68c129ce42335985edaf1aba988b412ec6910afb8fd8587afc34294e619df0b848d26ccf8d288525764dd446fb42cb6114362f48cbdb17eb8d0b84c2fe5319e8767ecd7e4fd8cb19a64ffa9cb066a54cbd1165c78b6bc2a2a297c30b92cea430615fdf2fdec899ff4559c22219175da94c2e48bf12b6abe8301fff0ce624ec2859c613a47e7a45c2e2a791f78117e77d47d82a4fe4e282098d42cc8cb05cd7e5cc7b26adac085b69a3f0a994715646846d627fa77d51f2902f86b0c7177fe13554a44d17425824bdc81e74713fac2b086b33b414fe2c202cc99ba7faf41f437eb04803df2f6c2e8c527db0e676e1348aa3073b682599f262f06031498996d70bb342dac19652485157299c7e413a58a3baa00bf21705b53f076b844891488ee160cb089d8db137a58bb11bac9df5d5a0b1c136b531497332b4d4608b27eb952725bf69b07ca13f33e9234bf20c7660abfe28471e2a83ed46825590993335069b17599fc5b01c00066ba394c53d7e4a2fca2bb6711cb1bac8b9f0328a2b16912f46b1648ef2c55bb168aa171777f1e345edacd8f2bbc0474b5fc59ecf545e4cc9a13e57c58e0bd69247e673f1e5a9d86caa1f1733d5dea551b1350ab26662211fd2a7582db2b9482b793adaa6d8c2852f98ae6429bae8526c599532883b0f1a3529969cbb24199517a4a647b183548306e1e28b43228ab52f45919f06950b23a1d82a5f9ee6d328c710502ca141f02f942d6b9e3fb17fe4bfc6912769ce9ed80b2a467cd9d5a4913bb1598595df48699c282796f80571452d5459aa9b58a22c7dc34f532355133b2eca5f705f97be28d44cac8efa8f427ca5648a891de59ef4f115f5492fb1864ff3440abd18a925f60211199f90e38b8bd14a2cb5132e6c8a634792127be15cefd3ce543873126b46a8ca0f1346ba4849ec142ce4bf31cbb832124bb464a71f412b360989e59e74b229698a878fd8ec52ff252fd4f2e2d011cb582ed44d0ddfc80536624db370d785215b9763c44e1d951e4ee7a4728b586a529c90d26a24fd14b1749aa3fcb913bd5b22968df350ab69d01343c42251afd2ecc34ed80eb1635c200e26678658b64b4eb39963bfb0422cf1f08b8bb9f21717a58c10dbe5e79ce4e7c545960d621f1309fd68c66e3241ec8f319d839c95d52f02b146cacf5f9093f1852f00b1395e2f98d470e4c48b3f6ca711eb50cce6bfb8f0c322f25d90511dfca52efab04dc805ce95d71759de85c713b117c5cb45aae23b611d47c4f63da315826f832fc60fb14ff33dfc8af3d3c5105b3ea65cd48d71173d4a21d6be0a3fe220ac6314426c258e17f6bc30c21ec40e7bf67e2d85bd5a108b76518829151e251c88fd0ba5419234aca802622f10b10e0971a1df1f76e6c96169911917e6872d177d17397ef17dd81c052fbc9beee2efe2f9b0eea3065fb8b295a3dfc35d747964377a3daca9a1795a9352359f87bd19956a737d3f88e3618da895e6461d950bbfc39699cff6f1943cc6edb05639fa82bceab0f9e547f9aef9c1d574d841ecba73c81b9b7a0edbe6d433e582c861f599a05e8ccb4184701c56bb248f8d61382c5dd894d629a4bd10bf6191935cf4c5c5a00bff76c3d6e8a18c65e0cca5b66149b12faa095f3d51d9b05f1ad187122d6a17ba86252223279906f5c2d5b066a6c307a18b4bd269d8ea6f92833eea4ed1b053f2d3fdf4e2f22fcfb0a3c38455871e174a33ecb82025b93cf9990bca326c9132cc51322c416239cee7c8938f61b3cc375fb86b1f2162d8e472a54a6118d6467932c82fb0130086ad62f45d59beb0acfc8e4db0f0e37961799ec827654f125d17960ddd8acdf8e282980b4b9687e4ae6033b92dac93b9b92825a33bd3c2b60d9a8bb9fe1a17645958f2e5ed8328b38bb1b0e5252fc6283aa506afb05df89d145369b5b3c276219e4e5b15f6c2cb4f6bf949001536dbd2df188994f9ea044c61ade7825cd4952ba3ae4e8014964621c9c1786505ab131085bd24cc4e9c0714f6a2ae07b95045fa7ec26a72dbe79bcde33b61dda87e588d1c3cb209eb997a9184abfc851f1316ebb2ec5fcf136d09eb69c8c546b5e9a294b0468a9ea79ee8820c2561ff82ce8a355edc057124ac5d5416d1718428f5088ba45e4999fe77bd30c25ed87b212e4f3968a68bb0a4a34692eaeeef89b0d77d17a7d663e4f021ac8f1eac43e6878c0a61b1adeb223bfb4609c2961abd3278e4627815202cb15e10d39ad6af1fac8f0d8f765e540ef7c15e9442a50777691bdd83fdeec9feb1e31ecc83bd276ee5a2cf6a7e078b58d8a6adf407eaeb606bf8d38b9df977c9c126abd3916a1cecc5946c4bd51b2cd717a29ffdc5356db0e32ec81872e9173ab0065b2efe6d86d2c8455dd0e03c95b88f2e270998c15629faf7bed642c3490264b0cc8fe572d445d6c53749400c9614b34130b5a706699200186c7954352ae3b30936d1e2159b794124918907d545132d5cb1a84c17757181e44839215ab462c735bdfbe851499a102d58b15fe4c22f483149c326448b55acabf2e00bf6325708215aa862a7fcb022aac8c409215aa462c9b5a37e314e2925440b542c67ba8ebb1fc99d8468718a6553524682ee48498816a620a5745d14e62bc5f264f18bd7b9b8294548b1837951c5b82e6c4679144b30d92f08592fca4511c55e3a635f1052482f2e42b179e3a8eb4d076a2928968c52f7da17463dc827b6af6cc88567194a2c3db13f7c9c7774d9543ab15326278d39b104effc89e6260679263ea6424d2c21582ee86d3013ab1734bcbed5db5331b1e48213ab242315b44bec615ed0284f47b4b0846b2144439eae128be4c39b0619aa394789552c238a4d7810be4d62b17c4e0d2677338849621b11f9997fc6c5a345620b292776f156ace41881c4f60517d39217a524e30579c41e11fae6b18bd1e52e8823f6ed2e2e4823b61afb62e83f5e92b9208c58d2d2e5e2e2a2738cd7228b58e56aebd64fbdce228a58c6fb1afef6ba602c9288ad31d066e4d7955211446c8de6fe632a9f2b831c6295b8b2465d0d42c82086d85205c7d457e1721ba4104b63fa824a21242ff06210426c2921bb20e32fae5c3091416c17a1275ff445398708622f797266b461669540ec8591416ea385c79507c40e4288d340bdbfe2ff8765227eece5ef87652d4ace873b1f731f166d8cce450fe191c88735f28bd71bbe20ddb6874dcc421f17e4179617ae87fdbb7eef1b595a250fcb8a846824e245c1c3faa8f2547fe964de61894939e951de8a54db61ab905f98111b7d1df62e46a99bfd0247163a6c695b69a7b9b81f3e872d849a91ec42098de5b0938c6ea42ed8b4c461a9a92edb9e5c2f8cc061edba8914f5c164fa0d8bcf7ee15f1c355bddb083c9a45f34a1bcbfe0366c21bc1e52faa2907b36ec59171d484eda8bac61cbaff0f56f8c66356c5e9032547ff5799169d8699f0be21bcdf987864525a3df0c6dfc8d9e61473b2b96b319168f0c27d79e65d8fa29cda49dcd2f9e0c7b5e88f0dcbc53f9183631e7b02fb2e460a218b612eb116b8cefe2300c6b7a7a51e57d8a5c381836fd308996715fd8428a23f90b7dcac4f3c2de29c18b34bb2e6c8e376a22e548fb7361e72fec66ee8228726f61b34b5f50651a6ba185edf3d7fe1bf7ec33d6220b3be482f2825c150bdbf58a7881c5875c985d6193132f982e883f2fcaacb046834c772ad122635558725d2e2c07de18a55c5061992ec80fd1b8d0ae723185254f6ed3f11752d8f285468488bf5cd44514f6bf1cd38ce2bf510a0a5b72ca4541f523d35f4fd8ae29e724fab968524e58766f232b17175d5eab099b35787591ca84bde48b223f3377cc252c1955cbbbf0762c3594b06d4c87470ac9d71949d8747261f78e636d3390b03de5e2c25ef9112fca11960821ec3835ce84901116b3b26d0c2ea35c5211b6ee46fd248dd45244846542cde3d89f8b7e08cb844d9e850c0b61fba2e0e3bf5d9192e1206cf16e7775f7d40b1d06c26297bb1b7731fc83e50b2265722d7e55c33ed8c2178346da395e90f6604d8b7bdf1832595978b0dcd88591b4f6eb951d6ca7dae3e02188648a0eb6ba114db1e659fb73b03583929fb090b53e0e96b52f0a5e94b791bebfc13697511a5372a1a5d8603fc71559971aec207e514aa970b6111a6ce6eba3bf3f1664d762068bc3a3c53f8f2e185d0b19ec64318d42adb13bd722063ba47874f6c574ddb91630582c6454cdb7161be5158b5855aeb85f50f9b72b16afa029d2347f7bb762f982f8911fa359b1c53cf1bcefe242a77a159bffa4a33b8b6469556cb9c71ca923a73a155b68522ff00641c59226a319eb92670839c59edff5950b35c5965fb45d107b32ef17a414cbe5620cd2d197da4f8a25522a6ccc7d4fc828b694e18b5248b310c5dabb3bb930525e47b166118af531b0d3f4ca3f21d62c40b1cac67661484adfb86a169f581ce5de1c3b5dfd54b3f0c48e91a21ef3cf733154b3e8c45e0c224206124e2c4fcd82136b434c8bd3b822526a169b5873bcf0b6c254238f9a8526b6f1a2886cb4683251b3c8c4162d43113111135b76815fda2ef0127b918414323fcf536d89a54ad5b367b6247295d8331ba55e5e89231e259620c90baaca319acc4d62d1cbbbe3cc15cc39496c4f167c3bef9c5222b1d97d716d9c64ee0824765c9495bfa8bb483cb6472c213a859c0ec2546a8e5852322e905ce8dbd15923f6790c152abf7139c6881d7645542c6d275ec4fe05a35e142757c278a1884d2ce7e9769188257651a453294fffe202114b7294db0cdbe9b8b838c4fe85360f328a6a769721b6fd862fbcae0ab15c689230219ea65684589ed71c175f8613b21ac4122bd85e7cc14e642588cd727174f1a4e708191588cdea0b9ebf8b3faf29406c8f2ed4f4c65f5cc61fd6f993b067e945fa0f3fac11b5e72aa8173cc8e8c3d2b8487ea2cc87c5cacf372ec506e9d8c31225176a359e5cf0bb1e76ca95e8b8a00b6299871df255252fe8bf4cf1b0a38eb2f8690a71de61f90b517fabce184576d87203c70df148d3aec3f65c345791a1a333e9b054e3824be5b38db639ecc56472d18c6621871df38fd6c676f8a564167158f3eea3c6e724bfcf2ce0b0d798463faef4433cb378c3e6e85f1cc96924c39e59b861fdd39ddac84c267a66d186f50bc731ac895d5c5c9c67166cd872c7a5fba291e9e23bb358c3b27d0fbee84923edce2cd4b0fe17d49543cde6a4338b342c9966c24e9a5c5c63671668b03a2cf93faacfb08df878e4c274f2a7cdb0efa64c3c17173ff5a40c6ba5e32fec2f6af03c417756b3c1393286bd28f9739153e7399ec5b06663948b520691be600ec3327f125d4ce1b2a10c86b5e28b2b4fd863a4eb17d65811fb91a817b6a95cef6d4a4d49edc26a93be74f7cf8b26e5c2f20f2be4546a9c8f6e614bb35e89730adaa816b6aa8b8961f7458ece2c6c1ea172314834a824b1b049549abce605df5d5e618fbcab2ebb0ab14a2b68e1cf28969155d8f4b9c3bee852da23a9b048acb4906ad47ae414963cd653f6f985dda414f6d9d91b3195cb4b14160d959959abfc3d14367bd4a8f9fbbff07ec20ebbb968e451d5d9e884d51ad74ece17176d049bb067ada4a7a4758e4426ece8297d95f3b1425cc2fe0de269b55f640d54c2fef9c55f187792d3bc24ec61963e6ad671d17848d8e60b35bc487c1c7a7784f5b920a346d11b3fec8cb05386d3e91f5f94a51561dfb554195248e12e23c28e0ba79f42a4786ad910f67a342fa849a9ce0a8750a82393401c0c8582a1402014040241e1acd701b319280c487220c9812cb7d6031380c086e18030100684816030180804838140201008040241008140201008040281205c0c195f03046dfdb8b660f01814820bb1fecc2a87bcdd0d6746229a07f674bd5e000feb36923f4addff2e52bd144dd2218c5d453176dd5ccc89d3c986c1a45db75bc3cab8663d355a532a06bb241d75a8984b52ec74a7879abe81ccda6884c480843a446578141c661b2ac66a975b8f4c9e399c87fc36ccd242903854d684c18fa0e1f0892de15e817086bd9907a6624c52eb89367e9ceacd721108ae8c4ac72ff6fb1a3e659e3e6be660f2b0e9807123c95c877b9cbb6d51297bc6524725e9dde1105f25b141e99f0895e462e01aea0dcb46f791b281afa572b30939f623a5d3011feed7b3a6c494a658a0fbca3382458bc668d1509323a5204648424cae3a4f73b7eaeab7dca41d894c5b588291ce2f1e3ee2e9ce10cb582392d6a0a64a4ee9df0ae94f59eb5133dbab259a9f9bf230c228b5ce3f080e8b3b50b6834db4492a268311c9fc4c63c12e2f3787fbceb7565877923aa7cb7338705932be0ca421a8fc7c63648e0ed32d62031b05f714084394ec6d40244b234aeef7d7f3c640482c8bc48e63e6d3d2a25513d74cfb807d3db19ead91616be49981fde050671f0abbd9246547a1a592cc416c84cf8c4e183739303d37b9694b0173a1ae7c71464d664a1e4f871d933b3e2ef649907d5086f5bcb8396efd27e887b359e7d575b8df0e072c4b66b14b9db326a12b50093b0ac185cab87128501b9a993c373b60d8e4c8ec04d289657e393f8fc76b70ec713abfdc4f904d6665b0cbf9f6badd1f97b9c525573c28e2d9f51aa0b0accbe176b9dd4eb7a3eb72bb0e7786e4ea769cd950b8cc6d2231bda8a9f3cc1a91ad47cf2bf62874d54a34cd5f085512943ad78f0aca9b4b86c6b394484c7e3d1dcc0804ea0b3f0883d280413038ecc4b2e9d0497872995a40eea5e1f8db79793a9d2fb7fbe9767c6ed7d779dcd19f35be661ddecff3f395d53ec813c99a3ddc02afb5b54180a2c3cbf57c879fa03c8eaef9d3fd7e3eb92e07c66b5532d02639dd8fa7d7c8cd11dbff3febb0b901854724d74047e20a6f75abb85501d14145a0139567d841e2500bcedbf5e5be3fddc7c7e977f444ae35fc4f2feee3fe447ed84df6b1edd42e2e154bcb0527898a316c48833c09357d124912e8ca8b1d2d6e39116c70d646a4b01716c2d05538c254fabf63e2d809b2e616f6cbdd9e2e7b1c7e8e1f9d7789f4ebe53af9e84fa8850cbbdedee79303e10202928edb767ab86e4b41998e96063d420a69325202a42d2a6f615c6447d7f3f176b9fbf9530d0a93bd36b0bf302203e66cb0a846c52ae5997bc240b2d60989df8ed7cbed70749deeaed3584b8673986375be3a4ee7eb727f08b9f2854f937a312362387c24737fbbee0f20c3b2616362b3f0b1a85cad70e8eb7d1c1d5debe9b65561446a6f1a44e4256a6d94c0bf44b7b28672ed1995eb775ee789ceeb79fb8c34bcf7297776df0f0ec7d5e93a3a4ea7d3e574381d5da7bbeb7076386797ebe870b81d2eb43687bb5617c3e1f17abe1e2fb7cbe9badc1de7b14b8600824a7e3d68459084981e2da168ed28bffdcd51dd6eeedbf96964f46429d6b219014d9dafe4d90711412dcf8cc131c50863ddf970f06d6647c38714873733f97d58395e4c97362fa1a2055be394412a5ae0d3b32f3bfed695fe01acfdcbdb618f41f131f9fbcd8c4625cf97111f4122a3d0f4db5dce00e986d9617f02dae8fc08b56426da5cf1c1753d3b9db7d301ff1e03eb68c8703dddaeebcb717dbb6ca3418e9280343192545482b2eca871ba3aef83d37575005c32867471fce578b9dcaeaedb81f13ed427e2a0da70885f8ceca8d3823dd4586bebae2cbb3a1e2dd983d60a3ed68d3dddaf8703dc5561e00b6af6fd7a3f9f5c97b3e3383b5c4797e3ec70ba9d6ea7d3e1c49298c25357396280036b255883d9dbb1b054784931acd283d66c8ec46e3886b29d5788d112502349214d8e9040beba0fc787fbf8769f9f8ef7c3856b10798dc22ab7068c8dcb9f2d480477469c8145af33c07d4c31227b5878a42a7e90cee1593477003cec6e6d883003df2f7e805c9d4db1b0194e53fabc973df3ae0ab9cbf8e9eebe9f9eaeebe33a3e915c401da1ddc442a6ad385cde82c9b770e889818e1aa13276015f6f8fae16f75d956c082c1e06023986ca3b002ee24717c68f07c702d01e3bd4d5f97eb9dd4ed7edeaba1c1d0031a440b5acc3fdc18acf5f0f375bde7539590834440ed63e1a3f979b8cd57e8842f07158ba0585c670691326d9c06167267ca12b394b182a69c1c2cfcc0f225ff333111d2f67e1a70c780406a392369d23054a9c528d44e9eee84cfc894ad16ce98ee0014684124477295de249de0eaa342c9d2614134a095aa2986094702578254a09522951422b699ca5ff2746bfc75b09514228812919951025b4529c12558a50ca29412a11a568a59c12aa84508a53424b28a68c52c2b5f485e38e9c9ba424a4c42a4528714a1d482946de74f62e9ad29052b64abdc7058435b2e5a79a97d65701ab6217433cb5d13d95b98ab347b2905322e4455b96201e950d08b6f044a2d1c8a828d25cf4023a54e06f0d5aaa2c44d5f54a884528463d609d792b9322702a090e6e495b32f0f64c41e221c591781248c98c84404221c195843961915048914804099a24b861b5948ae449514a192418e98e0475843c428ed0477147f40802098704894490143aa42c2899042b34240b098a94400a4312232451c038b7b79e123c1212298cb4234521259110a434521c528a8440ca21414994120c128e048f44214122a5248492e62265b1305b247820e191324860243b524385c47b4e47624c25c97eea06223512036981f444b220b99176482fd205d287e42d41d256be711563a420c95482464221219110a468240e298a9440824322912248890e8989033b14e487048f44228591ec485048245204098d8443429120907048482404291a0970483c4757b94219958ac4aacfc2002a67c92ceb3417350ba5419726f68d68a81de916f5ef5f2c016114ad6147047ceaf19a5268f09fa3f027167364580fa88c8934ab023d61ee5c606524725843c0674dc176c3b8ca1aca2ab5c16b1976fa5e32c2e7c259dba4a6290ef3d63c1410a0fc286458ad8b30b9cfb8503aa69eb1a4bdf774c5ec5b3701318a14ef7af7fb7e25d362811d2d5dbfff535d775150a1c4286ff7ed43dc0719064449ad0db7580e8d1910324dc34878777ad7ff00f8c078c6e5b527686543a6b800bbd1a0d3f8838ea98fb741a355a30560be205ca4f49846779ed2e4f389a22cf78e94e4ccb15b3353e43a6fcc7c6379f782a303e791e1b7f51b19ce2e50e26d5ff9dc8e61347b24d375bae048cf9c4891e7ca67543c2d2d98a84871b7c885d96d8eb68645baaf9a3800aaa501d1af971419ab0b75323912e7470e228d5a180fdec35a2f58763a7ab2526ddb8919187ac19b22c7943470611a36c47345c862d55f99dca31263582b42f5ee5cf1d0286c950399a15dabe14ccf2c5ce2d758b1d6ecc8c9287229290671e7c9eb79a977a4aee86d49aa6376afad5b0fed3f5cd4be830cba1f8988ee6c09efed2f201420f773bea9ec42a290651cf947c755bd9609b7aa4a8599e46742b73a89888b5d4cc559a94db46efb421e5fa2413570ce535b277700b5541b25efd06c2eb4486be1998f071cc50cdd544e8a5ed170e140ff41bf81fd713f9be106a03290ccbcadbc9d416fa95469d6e83b0f43a7cbca31a9e70c642312d514da0ceb7222ce0e73d2d238484818492b145e139ba122267d97c596fe383423e4401138224dcc2522f5365327c13abb6712aab1fc42de89d4c18e0db214b8d56cba90ba3d3fdbabb58f526e2a4f5db90794a42a103da5f6c9147638f67bb85e5f0ef91eec50b893e0db02c169b78cc98277cb4040812c70006adcf1b7ec16812068c280d9b3c5bd052cafd753c99eb1da99d5a320b76517cff6a45229d281beed49570a518114ef578a9c24dfabd378509edb0416ea1095345279647a3db0af872121aa20c5d13899c48857b23165560e4241e479a101860f762985b41e593c75faadbbaad38a2634c053584bff64a1ba8f2aaad5d5a322b8d786e339e74a089905a5af4305bdec65ca1f4c620ec0658d2570f25270176d4938055507234de364e688fd59971e578493e62a5003db0100015083b4c4609e5e2fd7d1698a4152879d6a60f184c9dcf7002dc934dec0140fc30c2b0650e555126911589f6285d479cd243eb294072e0444bb9101571f5d4e577cad9e81ddf1cd790fb5f57a377b8579ed7f80c2b3dbdb303250d73329d891315df098eb340ba256b282fe16a9dd881295b654d9d34dcb9b0f41eb1614db137003643633120403153a7533574a9938d183b7fb1e49970d1cb6cd1dde8ae88242a53c1a4a22bff2c220ecb05f0972f92c379a789300f3c80b5183cde5f35cfb6a1a659794ead5732bf7c7412a42d1abe56c35e666f703d98dbc0f1377cf1d6d5382d59b6cde7cb18abe8d752dd994a2933392cc5011f616bb04ec0cd882ec2f6d798056143e8500fe9f135fd85533ef8b32a44461cf639d60d9865466ae1693892626d5bd844d2e1d0b2e2ed6e990593395f25802740faa8fcb6a9e611a635a1197e09faabe6df1e60d18f6f9d0833304515a651fd4808590c2ee8342ee6737a82a41ac4f777ad02a9889b52f5c86e6798b515809780a595c1fd02e9cea9110252bcd70aa5d1b48061aa381abb4d4d19ed14dbd14d0b43562cf67c57c57d0714c43c5f82e1cabc16aa9540a0831b46a24cbe3da0ae27da86ee591486d32035f3c98ab8d0cad7baab3083890018eca415744de45d50b1601604146f1cdab801d071f1a137caf7164fe408665456814fe35a7f97f6876bc54e0c90e89e7fcca17c77cd52a394dd82a980d9cc795ca3484631f428b3992676288810cd44fbb339f07fe5e42281edea5fbbb04f059f1c8057d93bd313db4e9dd487043b6a891083c3ed8004e09c4cbb7eefc26bbe09f198224eb6036c15c3c8be05aaa94029e767c900ca23b917795ca6337e56003462f53c507aec1a09550bd5ab3e1f20843b120f19a0f9e8a3a58b63b816e9cb5486b5b0f5c72df09eddf930260ad1cdc49a1cd14b845ac7cd9d79b027541413863452626e6f941c9bc8537599f96a6451ab6929865aa570412bb375d8719abc4fe7e8822458fa6efaa6f946d8c3a424cd0c1bb938032dd53313727096e772ec80525114e1f28586484a3c20117732282467e3c37c93d361503ca0265d8c0cda9aa16e4a149205b5e47b3b220228894e9b450a0e956401c748c010cc9026e9144e60b3960b26639ff000000000000000080b8c9cc3631d2502538252995fdd10b65505e729229a5945224bb8377c199894f6739111121ace035d30001670b5e0ce60bef683325bc8451e49efcd3f99f4c3c4b982527254ea8f02425555b6cd146c0a212c6b2ac9c3a2499e392a784a9fc248720c4040f739a84a9944e29f9b8a550b148c26ca9927f12eb3959072361f4f89f4a8ba70f1d868449a28de6a41396d5a4e511e63555a5e242270f5a39c22cf93e2413ffa666233dc0a21126f961e4c4fffde4717901168c30bbfd6be9bc4d0c1db15884d1cd4ce7550edf692696032c1461ee92fa41fd5dae3c1e14701e5d7c7cb8179dc30b2e126191088369b7f8d2d17dded357c002118624b92ebbe9e343f5108611d2344c8ff232f5e2d83ac18e2d7af0388016d291821e58002c0c619093ba4ba658759fc875e868004e008b42982fcf88104252275e731c5b6701d801168430c7f06842c8d2777be1e124d09103021fc8c38b2e2a80c5200c6164f98ff09f8f20b2a30b2e72dcd0d1a8879505b01084219d7e5fac14a7238e40f2d43b2060b55cf4e8132016813075f57e0af963eec77c738005208ceea93fddebd78b5f204781f9f8f8383bb64000173d5a031f1f5cf4e813fc008b3f98c32567c7f6df0fa61443b78ddc2b797dea83592b6c2e7d944ad31e3e20a63fd325bf573007173dfa040413167b304792cf36a3a51e4cf1ff4a788a0db17d1ecc79f2541251ca4377050f067349c962e9ff87cf1d8c2d96a523ef5d4ca87630e89323b2ee6b3a9c590743ea0ac1c445ee43ba38b6b8f02dfc86172e8222021d391a60430b08e0e8d10ce03181f6a213a005046c58200211f8b8c1830b2e2060230b1b0db091850d2d6c64c1830b2e3e3e724d021db811003260410773d8ccf31447058ff61c4c91c3423998435475d221a9117f4227ddf01c3cbcc0c5220ee6b151c24a454b42aa8963b58080e7a8c5020e068bd1f5df6ffb26b63798424de4cc730e7b31371854b84e2acdd7c94d6e80451bcce737b26b7222517d36186364594a2adaf9f86b304612a7a6d229b99f763558e259c48b18556db1c517aff558a4c1ac9be7418c76133975349836846c6a842bb72a9dc18cf708d61272580a1516fecf7abb92dae3c6160514e18085198c9dc3c751736254e45019cc2363e4652e25c9d6218361e488988920a3fd3406d3e438a21616ce6a6e31983563728a1b6a3152c260886a5d796ee54c09190c86a8719556de3ba760f9822964abf420fe23d55e2cbc609c90ca7d537b424a2e165d30259371fb49a8b491925870c1f8a62c890e0fdd17c6620ba63aff9a202e24a7190b2d983e2fed7f5b2de59f05f3edda270b62c1a0468be98eedfd90bf8241281d94ca9df3fead60befccd0ba54258a70a8649c193fc3931a2a6824923e52a51217676a760bc113ad827a54494b8140c3766dd134456fe2898fdfd52769ba060b24b4a94999e60ae302d0b4a26a8607282b9c3fbc40e69b1aed404f36d4ddc581b53a9c4048390e4f951a49834a12598dccc7f744cbd9591120cfe1561df92970951124ce5b9de672357fc10120c2ab4b5460ad9f742473084f3aabdd908c64895d45aa67abfa7088634e25abc2f858e8960b64b91904fe78b3b04c3c87ee809316f4121983bb4727d4bbc6075108c1a5ae6dd44df8f180826dd49eea494fec094dec32525f481d9b3ec576d4eec7b605a0f213e5c7508160f0ce7f37ed26e6c266507a649cacae36469cd3a3086d2232fb9c4486d0e4c39957fb8fb9e912d0ecc23c2bebba4eff5dcc0e07b417d642d7db50d0c39c7554d6b95546b608e9cba91e67e749006663ff70e49a258ccc0a417c94fc85d0f7e6221039357becfb5768964621103b3a82c15b163d5ac88050c8c15bb44f8782f41432c5e60aeb1744a56e91c2788850b8c1a229458b5919ebf5618bf66b4322b88f81c2b4cbb9a2b42bfbbe55b85d1ded2c7247da7f854619878e51dd254982cfe4a5bc812f73a5418e58212952ef67b7d0ab39cfcaf3df1142ba63089b85e21772befa5300915f495aa5eebcc48611695a3a7e53df949a330fbc4b75799b4e5118529c95ceda148e7c3e29d5d7f0528cca9426fdebbdf5deaaff88421a4d9f2da39a95efd159e309afe9045c8bb6421f2577482b3f0f1a5644e18672e45c5988f2293df84214cd813a7ab445cc96bc278d24549d1fde422f94c98fe478ad9589786e4316152499c9abd3c5a11f297300813f549c912c6f2dc6982bef472254c695dc432de4789286148f1f3db0413f5e0240ca675396a9a94ad5e12a6f60f1f97bb5f110993e409da3a0e09539023a73f852a95f64798ef3545a4b3b5cfba234c5e1ef7625ff6f3bc11a630ab8bcb39ac4e9c11c69c53a192476599d222cc49a7ba583a8a30ac7b75de8f367127c26c55ae35c2fdea821061ca0942cc9cacfb121dc2f03af24e68e8901c3284415384ec8f0a613e4b214a2348ca39210c1792b8145992ae681006914c27eb20e52c2d08931619e79d130853488ac9f2d67bba0308637bdc47999c3f184ea4ba373d91a1f783f1e4c4f1be4d39f5c1189793cd8ddaafe08369d72ac9c88f12e6f62bf6600aa1712341c4d372fb157a30aa8474e111febfd27e451e4c498a5a07fd1b9e6abf020f06cbf693c3772badf62bee60ce3ac9a2b32d9fcf7e851d4ceea7df7284cf1062bfa20ea6b594546eedfcbeb25f4107738e52ca74abcb48d9af9883297da77a285d2672ec57c8a10fed252ac8380e86d149d2747df6990a1ccc99192fdada41afe50d46d3bbe962b5a554c50d66494ae79419e2c76f833949ce12d1d1e494d87097ceaec16821af4226c5cfb96a30f656b6381aa9526ed360c8e1933f77ee4eb668307d65d35efd19cc492bc98b6ed941c90c06ef90465e2ab9b1cb60528ffc398914720a198cd9fa41d49598693a0663abbbb9ae05df93180c96740ea5274fcc4f180cfabefec14b771c0cc6ba14f2058356cab8c97bc19c63d3d7e2d80583955a2ad70b9572900b26b37d17cf168c92f6c2e7685a5b6bc1a04eeca44bb79b2466c1242feb9665446b8658307e94a43c9676a7fd0ac60a9362276a28d9ad6074b19454aa4962ef2a1882f77e4aeed321850ae652f3c1df2ec9186f0ac66ff71e2d1e84474e0a66999073aa1b517a8a82d953ce90dee92947a1600e722ebde80b23567b82e9db4348312c6858e60443acf8fa53130c4ae809f3b2fcf330c1e859c277ba7c09c68e2d7247ab04b3574753d92e8b102b09869dfc576322c8c948304b786dbd541d371ec1902488d38a353978c48d60941c795cc4a7ce9e22184c63cb2ae553b28960ca397d0e21e88760d0f5a1e4952f04e3deada4fcebbabc07c1a0ebb2726ccfeeb803c130c1845d9a5c8f1fff812986ac7511edf39efbc030bb1652bebc07c6f55159564fa6ef3c30695aa96fe98e39edc01c64c5ce331f3c641d98e5db5bd667239f03b304b3c9965246da120e0c2397b3770e4a57dcc0a02d2458078bc9a693aeb08171429e554f6976e493aea88131bf5ac4af25ef7ad2153430df9795e48a26969d74c50c8cf2a19e92909f2475d2153230c8f3f93bc5c094add6e91d8447c98181e984999ee79314e117984f729820e74de5f60a179862e64edef29845bb1506ab144595b24e396785d963f474a7390d60154693b0653db92d89390d4015a691b816caf3b2a39c06900a83f80ab5fc719e2f4e034085d946267f302de6794903388539744ae9d2d6c5259534005318563d4ef25c97824a49032885f9de27e69bbed15749032085b9538ad7c1df51984d2bf96dddc9feac284c9782d2f28e8f9ed7501882c7299d2a7dce5550988238552109f513c6502a926357cec4d31386eb0f8d14f2cfe6ec8449cae5d071a1546a9313069596b5fa44db4f7213a6533144fc7b8e89a426cc4988d7ca57c23f8d9930c50bcd17a174282d62c26c613bd93d4e902a5ec2fc6d394fca2a524eb4844157c7f54bc81647ac84c1da939ccae8efec51c228f946958a49dfe24dc2dc327adbf722a7de246136f1b17c520c3dbb45c214943ea97d314818cf42259162bb9c8a3dc26cb9e4759aa788d71c614ef3f813ef456dde08933ef3dc18d58e38234c41bdf48953a54598b4ec3e6a959b1e5552847154275372e253d44a8930c4482ad58814220cd9e495178e63ab046e5b740e2f7834053e3ebae002414004314261d0b14ade77b8153b0d14a6511da27e35f285bdb8a18595f909c3a452310f4259126ff18441bcfbfbfec48beb924e98ec442c75937a4e983e8730ff126ad7f9dd8421491f219e7cb5fa6f4d98c4adfdc4e26bea9c0964793c915ef49830cfc534a54b9a45fbf8254c623d61ecf6630993472ea16584e95dcc043bb8701e953085abb0101f1f4a7a9e12a649522788d29663f63e09f3db8e1eb9de75a2744998edd48c52399eeef84f24cc5b39f442e80b0953beb74b651e7278523ec2b4dac992cea24ca986311c6150fb94ec2531e7c26a844982eca42b4f0a238c257fe48d5eebf6d42ec2983d49681991922e971788a1885e9408497d749097449e811ec4488449e343089af6a1e12d224c31b553b474bd8fc9310e61ba9c66a5b3970c578b218cded76bea3f5d340f2d506314a23e08511f83a80f84410c41d44720ea83470c40d447c6f8437d580c3fd447a1418c3ed4c7c6e0437deca13eb80631f4501f79a80f3cd4c71deac30ef55187faa0437dcca13ee4501f3de2501f70a88f37d4871beaa30df5c186fa58437da8a13ed2501f2c831868a88f5d418c33d48719eaa38b8b5186fa5015c420437d8ca13ecc0431c4501f99821861a88f13c4008349e5a38e7eca4e417231be60bebaf06166f17951dfc2bf50004a2086174c2f71365f4504c756b1a200046cc4e88229e4ca25ee92a8d24f9387175dc4e08249f80835ea796c745ac70dc7811a7d7c64b221c616cc61e25c3645e71467c2b15f6cd119d8420c2dd44716eac3041a851858a88f2bd44742218615eac39a10a30aa69896944e6933b75b4220c054c0f453e65d374ce98a0b31a6501fc40731a4608a7097efdf2f0488110543d01cad311f5b9be7e0a10542c13cb6134f58d0e76ff5134c95425e1339751e7fb303319cf0a72b29808b8f8f8f8f1e3988d184444f9425a56409719d550c266cfef7a37264cb02812f22808004780e1e5a94f2e20b2e4ef21c3cbce09540076eb020466a528a6c38b64a046228c19c722ebf5cba5369331c5bfa80184930e4483fff231e3752a0a30b09262d0b313c2795021d7da347023e3e7af0b8a1c51dc190b463c673529edc92838b1b5e54e5888017be4517397868f1f181821c5cdcf0ef06502086110c1ec48938d273509fca05c42882c1b428f923ca83758c318860d68dfb94ad4a8c21184ddf82b5e41c75430c2198654667354f9d263e8b636b6d68b100df2235c08a1a6204c1601fe5dceee28e1e2d0610cc29ead7c7fa42ee5a706c00c210e307861cb44feaabb4b03d6d64617788e103d3c5ce2df3e949fd7c7786183d305bfc531926baa4c4df5d016588c103939c79a55cd14c057f0706a97142258f73b1132f5588a10373d029d3a5428c1c18374c54124f7b3e4a7c420c1c184d490aaf30314b4b929d10e306a6901e26ff2e6703535ae910ba7476dba56b0c316a60fe1339e84e21a9c0108306a6edffd473ad24c287ccc0f86beea5e424f52342323025519ee3f3a6c28b6288110343fe3cb59b1b51171b06a63c219848fd0922b37203005f88f102738eb53be31741ec371c5b27681e098717394e502a10c305067d77d183deed8f4db01480d10ae3555c507b665a5dd2ac30888a2bc1db3c5b296f1586a0aa35c64accb652706ca9c29c823091539d07957bc4b1d5459fa007a6c2382792ae3d4c82ea098ead1b3b52e580810a53f6cca99168659f378ead146cd145175ff0d8f15d6c71036dd1881c0e18a730e70f31adb33cff4444304c614ae92a076f4f716cf198c0c787177e012fbc078c5218cb2a7fced1742c550b8e2d1c5e741737486152425ec5a70869278f46f198748932b91dc8038628d40f299eb2ac71dbe3d8d291e386173abed8c1455f280cefa32532418e63cbce4061ceea9cbe372c4d72f609d3ba58aeeabe0b793fc84d80e10993a754a62a9a5ccaab8e9900a313c64a4bda934e73519733270c397878aceb507977dd8439454ff932eba45f76760b303461be5cd1b2a9ef32166064c23c7a2fd257b2116135c6843953477eaeb45fc234398f8822e243ea060c4b98633bd28fba45e3c006c0a884c15b23b9278b6611d238b67a78b1031953c234d26487cfb14b8820c7b1a595c53509c35bf064f1a246894f12868f0b9ef20461a193aa877791022fd22261721d554a8849c3808429bf47d49d5ae8fec500301e61ec96db154ba336dd7584c1d64ccc5fcc64e5ac11e6e896113b4b25553322ed36f7a72b02631126ad10f3e2c58e1d3c9c8717058622ccd6f15408f1eec9548f638b1546224cf2248e8ee813224cfba3659e11c566a28730e64acc9d94730afb8b1b3dfa86dd086018c25841445c141d17c21cca948c0a49bed75c42182fd575e7fd76f04be1c1c3075102188230f8a98524d4c9458e6f717a3d002310e6da9d1c4dfee9c9d7b403300061d2f2d99412def726c4a37d0b74a501187f30a8fd0721596d3e77bc871f0c39c5be32ef1bbf14ebe0f18517ce03390abcec068c3e18cf447449e17289f8513e9894d4165139c7716cedc1ece97b2e5acaa1549ebaf0e28b1da62180a107c37950212d9f9ef4290cc0c883512dadef968824d7461c5b376ea4761eac783058b8e0af39b61d940227c18d3b982f7268ba6f6707c42389ddca7ab4086e78d1e38b11a426c6861610b0a15ac0a8433a9e7a8eaa0da1530ac756f6f0a287d526187430569e07734d8b306a9d83c9d453b3d2a4c09083f9f2f64c9ecd8ff8350ee6a042742909b26a25513818de6e3c96f8784258d20ea4c5d60360bcc13417f2271d74d2e91a99d201861b4c3d295eda274dadbaed00a30de620d4945027721299a52e3e920830d860f2584f4f29a4d316131b5964a105046c7c7c5cdda84c038c3514bed3978a3123c401186a30e4dc9d2b52781396f438b6b6d8220709d2604ef961753f6c9f8eee80810693120bd984089fcfa7835cc0388339856fbd4ed1feeb2f2c8061068308afbc3ec92feb5828805106834af6d5e66b6bba2a0006198c7dba4aa938722dce3198ff5330f71f99e02602430ca6eb11a1477e483977b7e891660646188c67a77b74f7e41131c46030cbc858ef4aad9d4be90b26cbcb79628885cb4dbd60dc519315a5adfe2c461fc0e882a9a4a72d95e4ea556e12e8f80247160c04185c3088bf86af564e397c10171ec0d882a94b7fd093e42249ac7500430b0619d3501f16a63a4453c78e2db2f8f8701d3bb6405b6c00230ba68be9a2838d0a92afd29103f1d8a10019c0c082d9fa552d8534bb00e30a260fae9a154ca284927e6511926ec80a30aa60cea6957ae269ae67870ac6cdd4d79ccf140cdb6a91c65435051852300517e177d2bb17c0888239a75d4f21a7dce95281020c2898dbb6a34553f539c1a204184f30cee88aeefe499755824780e104f36e57ae10ac2b766c0b46130c3997be907e774ccadd4302370a06134c19fbc9dade37ec8438b692f31d184b306ff955346d261c5bbec5692f5c046701184a30874b3c2dd9bed1c32a00230986998f16f3928663eb46046020c1dcf2aaa25b44f87cd71600e308a69c65d27ac81249e88dc03082399f8a5e71e32910c02882b92fe9a748f9be3dc4e4e12248be856e0183080651f2be64952e9f58e2d8d2b1a34c6033b0430bcd807fac093e3eb00d3086600af1736adf86c91149566180210453467c53512d97051841308d69cd4ff2ec4ecdf6a2bdb880106000c1a4c4e829bd1492942dd9c8020136b480808d8f8faa1b95021ebd455301c60fcc37e2767257c70726d91d0b6fb31a47555e00460fcc9d2aa992d5caae9e25c04616362c70001b5a40c0c6c707b9ba51850f3078604abb102ae96d4fe5a61d1882eb9ebccbb77ee4e8c0f09556e7c7e652cee7c0986aef31e221a9af1407e64f62296a3a7f8a29dec014295e123af8ad47fc6c60b008234e8cd8aa174d0b306a60b80b11a2fde934715483410343ee399d42533d2d7f1c5b5cdcb871b8c7019cc78e7730c09881496e45fe509f231faf0c4c61c12b2de48e88eec1b119801103733465219244fe605a2ac04616df00183038bd52d07d3a42e7882fc8b389ce6781e18272377f44d6d8fc5a41acd4b69025cc3755566c93540af97c1effdf2aceb1964b1f69e384852accf1c5d26252522a4c62cd74fe17f79473091526ed5bd3132946fa7e4e61b40bf708b2da930e1f53986d9448083125cfc7bb14865cf983858acea5ad26853162595514934761149143f549f8937417511846bc7d55ce3314c6ab20c485a474952a1d28cc934c567c4f9bf4697dc2d4a97d77ac373ce53c610a49a627dd5ec642c8c2008b4e987aaf22093949acb6cf09935cfaf8a4b73cb97436619a4941a8a950b127c69a3076c4f0acfa9cb2769709437c1515b473a82cb331010b4c18f2167ec50f9a842167e95421a66bcd3fce22cc9084b9db84d227845698467846244c172e8538952ce714f7fcc10c4898530aad6fb9235578d107331e6112d284163523a7dcb23785198e3028697b39be8ed75fd035c298eda3a9726a3edbc30853a8f1d02d9f4598327259b692774fcf1561da8c2c7a7d2f64ab2d9f302311a6a03fd6c55cad92d60333106194e8aba619f38d1da97031e310661fbd5762e9f8e2c68e442ad310eea8a4d1f094bac48c4218a4e78cba5c6a6df942086328495f9a323ac4fd6e0d330661109fed49728e96200c49cad7281d55c962eb9174780e1e0af8f8a84098c469d125da3dfe2a8461980108736e8d39f972416ac5687f30cfa5fb37d5273f182505154ba524d1c28c3e9847fe8918b12efaacb5c5043e3ef860ccdb9fd475f35da2d4c246167b307548ac0ab2427a304f3cbd7fba65943a551e4cf9940e2365d33da4180fe63415cc3beb291da6bf43da66e48588233b406ac0d9c1e019ba2e4a3b68568aea6070493f23ae96fb419674306731213999acccc1544a52fe24742e89ddcac158b99e2c489a94fae4d1458262461c8c5fba9336b96ea9230901708a197038f8255dbde6696a807791022d52e00ff8f82845021084196f307ddc7793ebf197201664c20c37182cc5b336e1f184e5df06636e559e7a8738e14384196c308add7dde1dd5d94c3884196b30e7dafb75cc450833d4600ed9d129ff08ed9d9d349854b2a0cd3be6e8282133d060f65c9bf9f717433eabc08c3398928adb16f468cf934fac84196630ad8912f9333cff57a58030a30cc671592bad5f63dea3a283196430e438b1dd4ec8158f7d0c06695ffdf129744e982106a3568cae9e981b1f1107668481cf31e2a3c00c3098c33ac57a2e474e23c5b185d5c58c2f9845770ca5e9922224b92836b458408e195e30fb9fae20b7968e1de500808a195d3008952174de9d9b685a916206178c1bdbb5dab136c28c2d9894b89452ea2dd532370e33b460f27ddfee8e21e2789d0583cde7f35423cb7c26e78619583058b22e51b5a71a665cc110d45bdcb4bbca0bb3150c5a2699b6afe5246236b220c38c2a18be739836cf7e79fa11c30c2a98a4f586988bfc36af66a15d983105f38cde3d213c5f9f772c0b33a4601a1dc1b2fc5fa953ff0a33a260b4504224dda96d2626148cfb41a90a298ac813cc5e49c8f93ad5176638c16cb56549af3bf558c40b339a608e2621c73f954c4511dac20c26182b3fa65cc5273391635298b104b3fba7d8f1d7267b6b25985ff55292a97949306905c91b1ae327a78304931031c44e12ee118c6edd6297a47529b51ac19879f1c15e846a7a59049397ad5e8dfc271f1d114c6b7a57ba7287aa980dc124a9f2577ceea49e243876c70dbf32260473ced62a9f354525e883601cd5b555a1f7bb3b0f0493e493edb3efe5419e7e60facbe145e74b32db413e30889952bb4e510f4cdb21e43011f9295d9a0786de8e2af2737607a6cd8a3e13c69ca103931aadfe21dc4ab7bb193930ccafb86c76fe0b75392accc081d962c4229ec88aeed40d0cd9f396876f5b8ec756336c60ac5c49cf227e6dc977b00d2d16906c6801011b6b1585193530bbc7becea63da850fb8d9d410373f8d6f87d8f0586193330a5fdec2148d58b57711918c5ca82e9cc0a32d7130373d4369194e605fde98681b12bedf4e68a9ca8f405e6a0738e73cf25e974f208335c60d049b885d051763bd756e495cdc57556982e545d4ad9b2c77e7e157dbafcac927fdb437a90a10aa3bae7df29b3aa49662a0cc944478e904419a830eda7e494240725459f4ed1e4772b1ddae6b1973bc83085414cee60a13deb876c955218921059d7b2583a395a19a4304b0a677de16f23c81885496984547fff79211685a992888cfef1514b5b7b202314668ba92e17e7b35abb048549a554397e89a05452131c6b03199f30c5659351a191d3e61a90e1096385ea904b88d49d5ebac0c7c7c78716cbe884793d67a57872c3df452901199c40dcaf58deaa646cc298a3df1e748fccf6c6c9d08441de5d10e1a49a9af08e2e8e04323261f01bd10926b3735716c7160e1998306b8adaf0b794ae4de8c50e1e379c1c0a5c02ee457391c38b1ea66e15322ee1b5daa452f91406322c61bc58935298ca38b6920ebfd1a3e830698b2f76e0b8c0c787052010322a610842774a95a745e31b3a76a0163c744ca0402183125fb887eb0fe9355c1c5b5b3790310993cd969e96472b1d9384f9363ce50fef6451822261cef952b8a0d2c4adf62d900189df44c7919182dfc4530e1378161f1f1f1f14b091850d0b5ce0e383a441c6230c6b29b76b2244c70e2b14c8708461cfae549cabf437e9c8f107483a7228e0e343c78e1c67d508b3d7a89311c6182d5ad7ca4ebe8c166136cf1574daaceb9a5c1146d3f1655182291186f110259e697bb31421c2582acc7bfefb7f47ce210c6a4379109ed527588a210cd24d569a4a9642184fa4a8c8a92aa5945b4218624decd2916162231d842945f018e229c5f01b05615e3f3b13e9be4010cc82a7e676af9bba200310e62041e4743b224f49ff602ee9262f86dcde0e9a1fcc27c25fd058f756bf0f8631fde6a53e4c2e6df1c11cc9472f9e56153791e5828c3d244595fa155529eb3d52e024c8d48351e455cc2c934f41b67930bf24d753a92c87a40dc7568f1d5d9c2e41061ecc71c2239c07515ff95325c8b883398590fa17420e2e3ab383d12766ae989ae81664d4c120a9444862dbb4a504e920630e06d52987af12a120c89043a125c7491136eb2ebae8aa2cc888c3dbab16a2d61bc5ca861610b071a32042061c8c3aa97527fcbb784a6fd126d8c1855b40c7046c6451de60d0163d4c5aef4090e106c3458f1f154a8e68b370d13a5a02d806d3e90c593f7223e932d8600c613a6b89d293eb10418e0b141264acc1e8bf3e2742a54c52a5c3820c35a4ef5fba112fcdb51c24fdf4291969302435215aecae141a8ca6d62e5c849f8f79219504196728b85bced8162d494962d95948bd297ee7f7fb4186194c797264f4d9c8102723838c329864f59cc969dab6490643d21754b41c978c31982a437f487eb9f04086188c1f2d4c08bad2a5895018cc755b912d4d8e7320030cc63bf3493f13c4c4422d07c8f88221077125dfa2ce726c45706e90e10563f667b59f9cda414617cc973b39b495def2e8b951850f32b860fcc9b7167c4d37aad020630b46d5109913f2b951a46468c160412f5f9e284ae75930c54e23feacff72853416ccebfe61b2fd87d3ad21800210b0a15fc8b882c9f3842b93e8297e5a36b250948387eb70112c916105b3ad05f91df44dd2552bc00236aa60567939094a843ced08046450c1a0dc2deb29d34bfd2a5740c6140cbedaedf3a95a54956eecf0e2c6d9096448c1d47a63da92f01291ff2818d2c75f79fd7cd9f799a07d8bab2c9207175c10195030555b57129b490afc013a90f104938f3c9567b282f4d48520c309e64e3e9e745e5774237f20a309a6afed9c73b20ac7167e7cf84006130c1f562ca41965d2d5ba808d2c6c687103194b308d6d7c30cb22164baf04c388882ba2a774e7ee49306ce82549a6428e5a424830977fd229a7b6e48cfa08a4d8176f66231bc1f4c9e3af2c8c88a39522184c4668f90b52f2774804d3e5a44bf7971346764330badef7d5474e0886b7754b33ff21262908e6bc16f937f29e2ec88060cad2397fd8a67ebc4ac60f8ceebf3226e739b324327c80da954ad2e5d38392874d90267fa2c8706c7dd1e3c6a91564f0c05449c4defeeebbc8fd0e4cddb115c3752d49fee8c0a064790515b5f2abb8393056d89691d941a71d7160f44dd141c9f02bd7f406c6f0c9e6f162d9c090427e9d1c94aae79ae0d84a27c0e2e15d74d13c34c0326a608ab10bc9a63ae9d82b0d4cb13a975d7d9d779f9e8387165ec89881494bcd46d2878b043a7043870c191842f85849a5e9f95f4a5becb8e1a8b7e8c2796c5140460c48baffdaf2a26f70cb8081212721e284687172f2d8a123c78d09c878415929086927ffc76238b65c860b4c41de43c9901f7aa52b1c315ae18ced47cacf91455aac30a48a64f9afaaf772afc22c4959d49bb3687f2d8ead1e050431546112294a440dede11ba954184ea4a91c41c59510725418e2bd7ace1a92d37d88159ec2d841057dbbfe4fb0234d61ba146a963b524a61d07145e452c58bee9f6290c29cb4cbcfdce754c4138f1d379001314661ca16c17343d493509e284c398924a3b36e96590191e094cddfc5348dbf1024f264b2b4bfe9363de24a29dcfc85916aa976442541f2c44fd39e346e045263278baa2c714628e716849efb9794453c222e7e2792722cab8855653dd492d05322b41321db997bb0191311350ee1492fb5f12769245da50507a286210c93947ea79abcae327ba1c3b928847184a768eb9d3be40b962ed42084ba2efbf164cb4fc741ec2342791a9d200c397b1c9d23a594321fd345f3d0e2e3a38b401ce69ef196715516824c0c8fcbfa582bea256c011b5964410108d8403abe50c0c78702fe500310a6a47fc35c843e6bfcc12c1a6aed94b89c66bb420d3f98fb6a82896462d5e883494e52adccfffc4b990f8614163172689e8e55eec19444ec3ed885adf0413d18eb2c7e8e3f4a092f6fe0e8d13816478f66006e8d3c18f48a681331623c98476489aa24ef3b184f5f104185519eba545737aa9c216ad8c15c17555d2de90e67921a7530e7c82d93d79699281724d4a08341086521091d25d5e9b414a1c61ccc17e22889217272307fc88c0f9311437e521ccc1734925de9ea892f1ea1061ccc714bbf8538fa37182ca78d6041c268dd990835dc60fc49d1bd4d5fda600e7de2d627726f4db9831a6c30eb998420d1e3b80929eaa0c61a0cbeba3fa6d62da40635d4601e49294eaab4d9a1621ad44883b1f76429070208136aa0c1b8337349ce7a96b864a0c6190c1ecae3a28e8c6ca54f2364a8610673cc1915569e4f3be9e4d0416a94c124ae35f1d2fba4c7240235c860caa2833421afefaf631c5be7801a6330877695ec23d223870eb2801a6230e809bd54d9d2d34cbee07124d8610218d4088339ab0495c382521f977950030c86c97ee926049d3474528d2f18f24aca26e9fcade1056359c493cf2273e4bc14d4e8c2c97e458ca9d2a613c4052f7dd291e5295fb585b2ffd3f7fdf288706350430b680b57a276c3b1d5811a5930957a5ab59cff8e1a58602fb85cb6640f439e766451b2c705589d478d2b18e5e254ee8578ab56ac6054fd1ccf6a74749d2018d4a882c954092dd74bb2d4e4e8d8912305ef8e00632b810edc10800b6a50c1d4a7929e9b5c612bf75330c92a5b0ba5c3da7518c7d6165bf41a17392080c38b2e3ca1a08614cc7f567a63740991471f05c309ab9355fa3e4df640c19cfc647df8749bf6f6138ca2acfabf4d77c8bc38c17821e5f0f939e2f2a80906f966a63d04cf08de32c1182992eef9e0b9a2bf0493a7fbb9c939243d4b95601cfd6b4fb997fe92926010936f134a662e5b9090ecc92172d647307ec9bea7d8d2080631a2bc845ab10826b1f3cf7236c96e44229854b7564e441c8251946c2dbfd0bb96178251c692de33ef1cd78360b620d2fede2711230404933ea51745429a8ff50f4c918376ccca5e93a00f4c2bf65b49a5247b52d603b389bcb9d3ff8a2e311e98e26fc476602af535d31c57d7560766d32367eed64152b272606aaf0eae37e2c01c62d609752a27d748ddc0a4ac267f6b570eba0d8c165e2ac9d2efbb423850a30626b32df3a0b4c53c443430efc67edb859c52dcd00ccc7931d499ac4706a64afb71467ed211942706266921ae99de0d037398adb8255ae761bec024a9e5b783297dc96308d470812948d2b7d36a2b0c177cd6bb440825c3c20a53364b13f339ec7d7a15a716152374af5585317eef826faba930fd575e11fb6059374585e14f2fdb74c8d9eb93a73067ed7ad1f9235bb4d314e691973dddca5218bd2d698c1257fb30496134a5dab37be57df171148638a745b4cadd5b0745617a91fc392eff6e9d180a73e8eca63c8c0e191782c220bacff737e255a8ef130695f53f776cbd897b9e307a873be9915a7266d709a3a9ebef3d6141746e9c304e741fcfa176fb9a6dc25c21a7dca1a7ed74669a305608a9ed1666b2edca84c194aaa8176b4c984492e894a2dee2ceba84e12f2e8ab08fdf222b4b982b5f56a7ee8e75b21206d321a976748a21a6849d9b99dae14998bceabc938fb624829230bc8e597e51927b2b120993765e15954ff3272d48a474b4567ab31ea1a5fe20f565a49d588e307ef871cfb16e418d8ea3478e2dce178d30968db2c8722544ce8b0a1a8c3079929fe4870bd5bfac6153d05884e154056dba534e6fd1a408f386673b11e6d0b93bba96d0aa2643844148eef472ff7ca7910d248d431865f55a72d43b131ed228d03044254a7d845b937f7cf0e871f20b1b361460011b557640a310e9f8bdd1f331224f831006a55bcdecfd4547f0706c7d7c98096e7c7cd018845f1a76e3a775d51e5df4483404615267d2fc258d6e773f10e694eaa7a5272ea93901c29cc422ccef7f68fcc1ece9fc2a674d145795861f4c798416a12da90f064f22a9c4d9bca816e48369dccf93ae5126a2321a7b30ed05b74ffd0992043c766800f5c8c1c51d68e8c11c3ee8dece6fe8d8710dd0318122071a79306a95ac4d1ebdb23c0d3c18d3f449defe3c8ead1b3a769435d0b88329dfa8ae8ae3aeb2e19681861dcc2394522162b39524290062a0510793941def2f0d1d344e7cc3e860ca11b6372731475d07051a733068f8f569bb942c894b0e067db9459f9ed8b9fcc732d08883419ec9c848c93eab6b28061a70309f7f349fd12ef377bfc19045b9ce8724ae72f0dd60acb6e8219b4e061a6d30571a1d4d7bacd26954361894279574a83ac340630d860f7f21dce764ea25a606c3ef7b7ceaf52b0de6cb6f531a6a65822ea1c1301f577d7c44f6d47f0663d5969b7b88944c84bdc78e2e7ae4486612e8c00d10d030834959f688a236d22ab6a38b1b5ef48de43aca9a46190ce222567afd21835994a9ec519475e9500f1e39fe0609dcbb20b596011a6330271bb7ca0996188ce71ee247471da540230ce69df3d02a419e34718a000976ec40c081c1e421e438ada2ad2f541b59d87015e4b84053e0e3c3be60eabbcea21d42c30b46115a7ee9d79f343d34ba60dace32a67d1ac1aba4051a5c3088659f0ef7a0c36db405c30497146ccfd22bd0d08249779fbc529beeb365c1f0214a1a0b064b1139faa1152dbf70a07105430caf8921848b7a48c8146858e15f13d5e39663038d2a98ab83485993af22a5ce5fa0410573aaa07d2ce5e7fc92730ac647ae4e792fcd020d2918457efaae94d593ec9846148c27d4a8dd984afffe40c1ecf1f2a2b333b71f7e82714fae5fab444e51b44e30c55c9967bbf49772da04b3779279a9ead2458909a6909126dcac57082a5c82a94beede45d3962cc594601c7fef55cb73128c75a96f29888c047388a5d4bacbc716ff1cc19073bc8b2e1e4d09518d60cef5b0d4696903d028029fda3efc28fdf01f238259276928552a8493dd100cb245b78588721d26b8001a42389f8af1fc0856d2523482b08a88794284fcd6f9f8d014bcfbe9030d209827a78a9eed3fc9288dc60fcc11b48e8aa7e38a901626d0f081d9ce2f6be6fbab8f2e09347a60122af7fb43ca567e120344a02347a9020d1e183d4465d297a59408be389e6e8860c7169c04a0b1034396243eaba78f0e4c93838c8564229d4a3107464f22e85121b5347060c8d9c5f2ed99bf63078f2eecd0b881d124a4f72a4b19020d1b987ef3d684c81dc374707b40a306062d12b2f6dca8a72cd70b3468600ee2bb5adcbb4e84926b0b3466604a95268bb865170b346460ba3c29476d51a92fe5eec58e0c681468c4c06cd1937b9e0b93914230307f768e8a0bc93ebff902836c8f2a8b5a9ef34796860b0c124328152da8b5bb76ff30a315a6cacb5c75f5a4f95956183ce743f477e7fae4ab309c98fa34de9df4fcaa3095904f132a6e9632fda5c220b447d979a58baf1b2a4ca53de7ae2e1fef0f398579c5cdc342f70759d514867df958dd2f77797f290c5b2149081a22a63f524a0ab3ad4748934a386314c6ba17edee1a06618628ccb699ad193967a7c86b284cb28448227ed27e323ea8a0307eb6cea153f67ecad1199f30c8e9a45310beb9fa7bc25c1f3ba9133ae51e25ffc08c4e18acc794e4944538cce084e9a37e2525d27feeb50993ea8710c2cbde473c8bf2608626127a7325f2054bdac7b13d72300e6664c270619d6285c8dc7d8663eb866f21021d397adc483abc47590b6660c29452defba0b7215b3d8e2d0b000d665cc26c71c2d584bd13fbdb0c4b18eff483c51f4fe9e62f05802a6654c2e8ad95d3880a9184f430258cf7a26e65a68edca88450a6226128100782e16010c4406cde4c01e31308001834288dc7a2f1809e27997d1400044a362e44302a162a281a16140a44236130140c85c3a1202010068541c1803018c98a998a6c001ebe7227d4ff4c893a1c064a21168346bd5a80a05e7fa38ca88c544a97dcbdeb3f410c15ad4c0f654f4481054f01525a7aafc6a1a6cc756ce2078c35b26381801428b4a1783f9700161e2a190df0430f5b96a907141cd86e6e49d0f4dc2b40c7bd8198b07905844605ee355a157a0a13506157bc09510879dbe28150eb0b13d6b15556d24bea44dc214d5c5c119c928761b35d0b211f453fb783c4a7868095ec02f22c443f29701609fd2566c2066822445123e254cd230e826c0b65aed9aa8ae3b4e9f3e4221442642ca0b6ad49ae92c5e1dc7cf84529751d0b5b36bd0ba903c0736cdad0e1747d3b86ddd59343269d9b64eefa6fb7e47d9635ed58b06b99c2c31973ec4de60866d9b8ea098769d6106fa543cfa28400e204a9944ccecc1cb41e2785b33b3e281edee7254bad143bf127ec98c8e37b7534485810fac3e2d10a030e1d1ee259f4c0ed454fff1515c15f2104a81d8082c9f74514aaadd1e1c4569f549942a71e21c164b395a092009a96763fa9d4d9b9b4b3946209c38faca2af0ffd709d622c8ab39944bc69720283e981d49b409305343449af35d4566398a1d57ddcabfb8d73b028ef67a2c166732f337821f39558173d877ab24704a1eefb07943c924799015ec6b1357db092fd68fdfc11685a4b2313915b24d63b2cc0a3e12025bc8607a79e7a825face0c33bde3f2bbe0ce8275a0c71c7bc058372f47edffbfb9caec227fa023514c84f9934fc3514af25960409f211c8eb8d43c671ddc616dabed06c3dc6d334e05f527d220ad5dc86d0d81f6c611a76d7b18f13c8570b138a6f120bd61a2fecd298238662124a8cbcf805794fc12d09c4d15f222b9f2ac69d44f112af67c0a6368c54ff3ddcc311c6dfb7a0b721c1b27acd6cc55657d755c9637d826ae2c26d8c2b9f710e6f3e0af2adfb4594077b53d11984c22b330461c57489c4fd280a180f85cc5ec9a608729ec7a67271b2aaf90ec612a9d5119df604f5efc9bd3da94922a8c58cb564747c7ccd10df70faaa424748158c2e07ef51993dae6b4fb963e7c6ee6bbf2facfcec6a4069d6e8db71aea211f43c40dafef579f357895e41d72b0184e1e51a83e3606a19002b13eab7ba2f9e0edc5df12d61f8d87fee5fdb0ebe5f640f6747453bbff5494fc684d6f68a4f5daabe277b404eb290780e221112259922f7ba497742341cc2cbf7fd92ecf37c5830a782bb763f07a46abaacd0d34301df36be03920921b9a82b84ed7d2998a6af50dbb3bcc461ba0001b3908d4458ddf8292f5ece8eb6086b33b5c9c4fbf35ef51e66347defc2eda3b73160c0d4131071e93a26ba3abd3d70f01f717011ef59a2ecc2cf1b79a4551ece6f31f8ef6cf5ddee94a656ce7279ab1b9781be0756fa3159b46bd4330a7c34122ac2e9ac77b1961d83be9f5e0c7844c1215c7781655e53008076727b29bf01971c8fc55bfbd398a450b0e50ddc2a791d042f2ad9550ea33e632def971e001d3922cada547a665286e7f332a15c3f8949deae5daa965693a69a32806af7397548eda04fd25be9b3f44efa34bd853e4d6fa14fd35b684f538e1d2a9b6c74033b9250f9bcc92e86fc0539852e49653369603fda385e8631e7b68dbb8fbc1bfa0b806d39be2d473b1b10a90b5d8256132ac5150a41c1853ad6a481ba2b819abfd0b8df4cf9f37e0605fb44a8b3324f4a31f85465c6fdb3fc78822f428c538a1a3f5078c9d01dc97ebd61c40fa62fb1eae7f221289cc140cfe87a8a269bf2fac8eb02175bf788735b8d74bacce2074a6961b5acc2cf3727a37d2779fddde632d08b608e4523ebde6efc8194f5ff272489abc9a03f49809cd64c1a8207c868fdf4863b8ae2bcdab59d07f0de58cbdfa772ed167329496864daa8a7d93782a803e11af70db5e2dfef20d1662b68d3a46b206023ea33c6721e43102fcfe974e7d8ae0ebad590a94b7d9b01a2e28b8dbc114698b897f0a5424546ceb14a3b67ccb20ef301a39a2656459db12f1e477c1c1610b37fc8d385a40f9d4c9f63d0f30137ae935469a8ed06ba9648bc7c0041be19c00df3858540fc779c9d76983898af01e8b3b256f4e870195e03cec88e8793d954bd6003a782ab8edfd419999d21762cda05e093ff3309af01cb9e7ce00c961bda9d5db55b1c4ebdf579bc1d932ffa3df1a1ea9b1ea467eab0134c157b82a99b73fa478a3932da10fd093d0bd1085883c71b4fc7a00b697cfcd475c38e36d2b90adb004ad09c4c0b2c3ecb3e78c2553bfec9c12023942ff556d9a6703de603e60063cfda70ce2d91aefc699a5cb0734133c33cae8c7ea6b4a6154e6e33bb2523e845b931f7680038b2c59ee74bcaf3d983e112255c4b071f383f317ad23c52eb555a150a3f57480cd37d8c9344a9af82d12aede763b72ce9563196d537710510d4c31e2dc3b81d1f22addb6908e33aa6e46483104728777e0e92f5fadf737acddad86aa56aba7de371ae0dd032c63a1344b82989142281a6274683a8605765f49f1a3291f881f8a8ec3f7c2d1e5a901f9ef410bc3ea15f12162872b0f5063375bba235e47c690188bca7723efb953f2972ca81d821b38c1c66c24f5a1f28ffe012a2e049314746971fe8c882cb6ecc3df93034dcc10e465468ace5250c8c0723f226f0af58ad03e9129e42cd10f4c3cc943d65c91983c0ecc732883662c92b54e52e9e316e12c5cd79a807102bd0d829c82c166b042044e73bb6e22842c0784abd1815933e9f5a09441e07d25ee9a7f72085e60181ae33dea35f7a0cd8a91329f12b86dea3300d8057b28cbadef556a968904d1f3cb4e9ad2212c73ccae654870a442e9ddc61c99f3efb3afa0c586a9176c586781a0b84161a2f4a45c34e095e2884d7c2b470b6308e102a44a0cb5a741e62a5d76c446a677f1404f5c861753d91fc613fc6e9007963a65ddf9ce2b871442d3c42ebd02f0954faf809c4df72eb0bce19705591e8da6c17f2cda563889b95a0b7d0672126ed0e0e18e269a8707cf87f25738afc92583c35658f082b91fa32fdd40b4acdf1dde608005f6e31b9cede6eb5c7171000603d3493bd9a0632f5068a922404facf76faac90ed6982d4b8e2ddab8805365616eef1f65890742ab8948506c434cd6f629ae37268f6b09e7ee3a28371fe50167313cc316497447fa4229e54d8ec7c7ac678bfdff7f8455600ec57f61a5aef0d049ce147b8725349f80d776878fc083a18be147ef46d45d8e8ae819bf9ed501cf0024b8b66489680f0df0284c4b0512550e9625959a5e415af762dde0d8ae9cdb4a94417c14202ebbb5ed65826bdcb6b4cf610e36a3a4fee1ef4bef0ca69b2546546a66ed47c6a2a0e1c42a21f2de434d5f3606ac2e5beeab92bc6be639096960e08f29f9cf3b27784087346a001ef01618a3fe14828d4a6c46adcfb3c2c73ee777a467a4b7aef867e713ef7d713717d2e85b60759364f97a2b1961d13009313bfd2621de3625016d9c0a916508d978d2689f902e7b6771c2da70236e70a4aee45a22f619c09ed63406639925b52d216a060e35150ed630ca240e1a063b7379b3e182ad8b684eea4466a9ba11d62583691458d91022a75d1de257f3e8b8deca30571cc18caf3f84d8c19009e9c17a2b532530154574a2b15a7f2589dd1da3d758f691d0ec045dd1a604fab4085d422f744f9b1740e9329d8981d2c19724ba17cbca91333c2ceb4a0657dc0b6278fd7fe318aef4dfaf05c62a31fc4c91209aa7e1bd5f53861e00d457f01dd94370860f7b4ced54f7dc2785d2f07b461f6f74bb63845d970485211d1321278cf106fa9fb12e1d4539f1dbf2153ef76ed8bcfe4676029716735c21be22c100c6424c022d40f4cd5812b4ee40afebfb6d067388723c09cba56ca16e3c20db67b92320e0b425aefef539cf24bcde020d866fc09da869770f0e59f68d20379986b6141bf53f1d0593e655250e89e4663786f83cbb68c77fe25033283f43532bf183ec2c8ea45f939fd3f20f8205c830203a90bca1d5aa61e6ad40db0e5781478faac4cd14ef9ab305209664fe211e05db04ec34e6114657a54779355405db2f7869f44628a802a60b2d4b70504458a3b271cba314628a866a394c2171988d314e74bc5c29a8247551b712e7986d98336653ad279fbb05f0950afe8cdfe789d15cec79a67c690247c3b686984ba445455044fa776fa4d58bf14ac12882c195f60b2f64e91d468d022cdda3895857fe00d756116190a4dbc90ab314482133c8ee0557690b610213bec0697dc09aff34d112f84dbec42d672f801319543df6227e67c9a2d88f01eef0bc36cb0bd7a610b088d0db05c0d4cdca415c35094276e287343312d57a65033201d4cda7c89c7864d7b10b43c4ec2cefc70b6420fd1fe77ae6d76650b57f8bcdce22818b0c65aab6aaa5a16d1a575729607b8f66ba87be04163a2f080f5651a1bb30a793437a17893d632ec51c7f9f0df18518298c85c15731d27f354b3e49266068b4365800a6f60df392f0f7a12eb0586f23be8d7052c59a1fd41095b69b3a2b9fac4b4518b8aa981555940ebd3f43a29f8004b8d71b2b2a9d63e0f8f8b79f5289c340c072859de132e47d8caad74b6e7c2dd5c9a49c57db5f3c7759f8b761b85d9033fd38e6cbbc7538890cfac798a631e9154302079c29a271cdf87f347a5078fe55801ea2aabd171312149ef7459f4ad27bd10c216e1d478678d25b6bfcf43a8b1f8eb9c5ccbce1b121ce5ea8536ce5f93af5e7cff83d3d2358292e3a847812efbfcd2995a3906c5c140ad70ff037422449c7d2a6b77011597e80458a3f24a68fa1a351c1cc9346b2a92a828142aa9211d9cde5ba6ead09014bb5cf2c0c652010671c36efabd10715061d92e2bc4f99e2229723f5b7cef0ab09a43fcc424e3ce955509ae2da20c8c865122953456a9668b15948447977b5abe75a98e379a0bd31b21aa14e7a07c30fa3072fba029a3e37de88f76363bf0609ac2368cf82b3d4e5f4c62a80fee81073befa72c6b57a06d138b9290f11ba37d2cb36ac47a95c007e5985db8c0f6cd8566ed85bfcd92dae01acb5f476c6d50603b0d6be0cca324fd6a18f0db873c6b9eae044822083d55ea42cc1388557d9c45ece35d008fc48fb28d8cdf27d3a328437afcb8dfa046c633e225b3a47b17898a7309f3ebd84fdf355ffcabdb49c22dbb474f2c1329d999487a1c00b581d771ad87703b42118eacf4e76180f231bf9b2c86bd019094a48d79edc9494e2bad7245109b7b7b59f9008f8d1aa0de33b59acc708472ec59bcceec9baf3c9248b8078f6287a939a297e87751099ff340d8c9ba26df39d3d7b01a531d89eb951ebf9d17af2c1d5e2e885d0244a680112048d2fdaa0da6b99c3b255fe40ab6c021c03864b02c0e7f25243057890f6b16b4120922f8b94c58535d2da119255c99eb23c12dd9b0c1e447da2b8c721dcb54e9b5dbff79a88c3f1ac6b4fa319f157d4c9d230e15b70efab049a76924723d81abd21dec20afa548d8b25578dc6a45db4b95c3403b1533e05ae1c9777eb55fc55d0fb3921f03bd9d15c18fb84950cb05cb2d0790f38861bb338282855c52453f78f3d77dfbc5334a944e93e8a3f46635fb083e2d7574f763f10501a6437fba2217245c47ec9631b447b0703f814f0c4c4c948cb1143b3cb0f843c2336ca0b738d815711ac9c907a8f05a0847a876f1629310370510ae31b29eca1fc4f68f6cc830653e4cf8beb0705cee3da157ddc5a63354b1c31599a943fce2bbc14db0d143460ddb01ff71c7a8af832be6ca2975adaed64281549e18da663aebadec940888aac4e2009d26fe06173a972716ae51647c0ae4094e429ba01d2cf5357c6f95bc292f7bd4f8a2d8ddefd25066ee7a1ce582bff5d0ccdb620e6e74c4bffa5f4521ee00313a08ec09012284d9d2adf4a7e26c3d0b2443e4cac98c63ed078fac70d67c9448e005343c4799ed9e0bc97d859cad16dff72a779839711546f1293da487d181ebbe6ad327498ddf04351be7c5b90219843883ebe6181cd78f590ef4c0f66ed9d0ee237d946643194097067330116ce6ed76f9c54f1ace30f3b66b37161a250d51581a8f0071411666710cce9e3d68136c2dcf7ab0ff177b1e9545273c48ed2f36d101e1ba7a09db9a1a1b2ad2f27332b9287003c7fd9aca197bac44748c127fd0420c7e71990dd2e3123b71c7067286c2695d2879d0a30748a873af90e4dcab6a83b90e04426fd448eef7d343264ecb853178cfa7c4d01cfe9002701caff8addabce47ee4bcb09d37e59c38594eae97ba5c55b44b17936a0f1bee7f625d620d0a6cfabdf2dd0e6a9cd62bad17ee0d40787474025ba132f537886fbae33c05d36f770a4f582f4379149fdadc76b2980afb2e01e5e8f3bb39e2ac4c2d11a5d06e94bfecbd27282013e23eb1ff0eb47f6442412a2e646d645b3bc0f342c7157a3c8d246bc5ad9bdbe34d0191db5a5f588b8d0a13b3fa67202b3958b567f4b5b65362d16353998193d076427b5e56e4e071aa9a9228623e1ec0ed2d395f58c6a57582a32d5aac9453723a48dc01220818ac17bbae3e936012b243c9dbb050520e0d7a5aa02b45dca5eb70b891e7fb2977edb97b13947bee14165255e58944f3e851a9979a99ceca84719db084c80a47d3f60c42aacc87282ee78de8d0bbfe7b88a5ec0c4f0fcadb6cab7b767e6e4a8f70af4f4a273e4252962da29496f1d2cee2a919046f22153eaaaea1d765d25c1f9525a78a11e2190f44630b44411027e11c566a6c4a0cacd4e45ec8e1d25fbbcda08476b90ad68d820056bd90b3573ce436f96c2041fb64adaf284938960c219fd549fb7472ba793eb22c5e5b84751b3d95e29727e046a1aed057ca261bb28cfb365fdb9e5869b6e4f2557c607516dd309b3fec718cb9a2e61fa48411acf3b08433d0f4bd015b10a085e03f04a127e18c774c6f4b13028508a080109d42e0380c13a1c81221d0bba40595bd836e155e3361b714386b1dc23ae8f248680f73e12648e5a495c3443a35d2263bab490e097160179ba408a93cad4878e61d8ed43642dd9c93f68d8048ea9ce03366e14b34994415972594a29d2fc036c24fa3149883a216f19c60dad940ac45f0068179856d91d7c37d58c00280a345ac01d9a1c530e1aab33431310ca7af84d96a57f6c45d27f2219f1477dabe046f95183a34e381fdb14730506b80c48b1b3c8b8cf719f7991f4fc87801fa690bcde01ccbcd5dda0db2cad234615be4a8c403d20511e7f574f06a90067107286af8b5d36f28c176f79d7af0a6551fcb0a281d1c5ba1c4080d86cf670d6df1e605370d6d3145dbaf2c87a07eab1413fe51e041139f887c51557266ab551fd59a256f8e4024116429c1e18d384a6613f53e72a2950c14b014df0e43fc7696684e0deb3302fb98f7a7123037124f8a874b084d1d5e156a4b15ab28f422bf8aa1a9592daa3cf6eceac7a78e3fc6bb1a35eb127acee608ff2591d17a7e1de90103692f7f0026c2869d54412fe296181f429c1768d9e83d77126493311fe5223853a7f10a3d80332fd886c12e02b05c22d8fd31bc343c5350b79e933562c3874df75c7826280edee110d9bac9fb90f9d6d22110dac3dd9cf55c087c3d468d2e84c0342098a79a8ff830b385f4deda0d5508c1400f7b1712c12d716f4d3b2f105a02220a502b581b0516e105237ac11126cef09b5673a32948407ceff73756d9269a12df29b82e623cf8b8c984559770ef92c7d08672ceaf580c3b6a8915680d2e18588f4baa3d2efe8cf293953c74770482c7b19b33df5a9c1921010ded94bd715c7273a82958e436f5d3a4656f3d867bd74b43ec15b3dabce1d90e91c3ea3c60de041f9fc98e6720af6d1b80b7ba8bc206d3c0f0f1a106ebcde046c9253111835fe06dc2f16d6fde93002c0197e73c3cbb2d00e6a71bb160264f879058115f8bb280014e8156db682cb355419c5bf5599fef3b204c3725e18c7da095bd77b878bc3021006ad58ef02bfa78825154b73e77ac2b60228d5b6e2064f3fa023233602d554e0844e386cb6c44de7c9d90f16e3c51a23e56c2937886ae920724cb3d7821017301d8f4c914643b53f40534435eeacb76689845a41721995e442b2df21872a398e5b97ba61dbdb69128226ace5020fc1097a96fc44d8758ef92384cfa1a1e290901deafc804c8baf96d97f54e30bbc3e3a2b1923e3d96463461c4cee7d0ecf090a4ea25480e3c2ee24f16c2e1cc1af5d9590ffb35ebd4f6f7f8624090291f69f81a334bcf719b087447bdab08eeb1e9796956c0af0248253035facb71982638e60bfdd9b24304a84b970611a7befabc8f3b103b244d401c9ae30b239103c41b0ed5a8c05c5ab66cb432dbaeda240b2a3b48263819e0059132b662e7416441a5822a1d941c4daecf3b08e3208e1744ccf35b6e0fca2c17170b22a28e39a3fef20095d92285c032a5a5baeb5f29ffd17e452957ab959a55bb29362ac0e63ae6bce63ccf79a1e37b2e321fff0dbfcd5c08fb70250c66a4c3717cede40fa888c819132904829e84b8b4ffefe30274378da8aca937a09a74976ffeebd0518f071d1b57554ebfd4c6369b494173fe116a6256068310262c80e0502e2ebfdf5e3e3b8ab3b72a42ea7ab86ce11ed5cb5ab09f6527d540245a1cdefc509fc6bce95feb87a17f785cbf203adf537d5347130449358c1dd0ef3f785b0552190fd6e20393ff053572d6d3bbadc2935b9a4182479b04b7c75d67563456c2331b951b3586306d0a92e5b31f95042968f23038b7579b919e72084b8d1f22aaacefa90cca0e7f826f5246f512154cb5d0a58b6a304e77e4837f44aa7d5d674c7bcb1807844ce0cb3c888e942c9feb72ecd4aab7ebf50b432bf2b935c05abd8b7abd607c99a452b6cce424beab4d05ef1e02c61f15d4f730c218664e111b2e449c461544f449c0241a7618683992b108d80dc82c84156ae75bce93460e90b1c6c4351069a1e31292038688c39c00ec02d4273226125150cd6e72d2051661177179f398c4021aec1089cf5cb7103f4d64a0a18d80fef9bea814dd1b5a68b5096fce55e76a9d33909ffb86f761893337fc0f78e1d90924391f88cd305b1e1b09224eed73df5a414030f11d5b6fceeaab72a080055d6b0672f3edb7a012179c750e899ba3d9f1460a4f0139280885e133bb3301012335b37380105524082247d88b8ff82fb34bf3dda0cc90cc6e67dc50043c66272bb0f295bbb55531bbd301bf8fd3757e85d965b2e67344376076bb38c0828d8abcdf3f4b3cefe57653355f76cc629c8570de65b7d998176374df5c76cec9e990fa2dbb75ea7f89d7b25b073cfb6467d96d07ede6f463d9991303987865671141b3615c5e5f935bd991f90573f3abeccc4cebdd98ca2e6d91cd2f338f6697d44fd9cd79f9495fcace1d9acfd447d9adf3c379f2a1ecd699ef94ee27bbebf4f124d1c9ce320289b90e50c0dfdf64b77c1ef08f67b25bde0cf8e7bc64b7acfbeb97bf033154b22b7de0698f6027d9bd1a3453db85c72c921d78a98b7e63a7bfc483f6bb4e444cdc1f280ca57703f48eec5a0e6df67f3823bbfe8d78ca5564f72f30c11f3185c86e769e5d7d6763c86e7755a4f8bbd90b63e8f9c4176cb1f4cd55760c0c1d8f0a041f58e2dc2da0200170d476f9aa73a063463531cceb7a95c1cc7509046e21285e0d3f7207559e5bc10e1b572f28b2e0d30b5cc2262780ce45469be3208e50dacb9f3d80dd3c05727a95b74eb35045e98eb69306ac7a88c29d75b3efe217730b961f360a73877c8557534f56c25dd5618abb857027f4386ba6ab737067b968d9f23e6d1a05b7b26881c139ac2d838bd5b12bb5a0ca5a242f8e310cf14cd69194858b6bbb3e6e7ddb8495852a2cfde327153bc21052850de3d5de4ab76ae1592d9b0b4f3791c434c9cbc735d2ceaca3b2bfd3fcb1af9428cb30d4f41a78052149b06255b68f11d9c82f0f71988a2845b56e10103560a29b2e6861a77c999c3f21c81d37771d4b244a9cbe6cab26e71d03c3158c3be2a9bc07a2289c15a8b30ccff1cfad9c91dda966af3b65114a95c3d160b102dd5d039fa6ac0adac0696239e15807d3815795e289591fb2993b2fbae6134d5ed2783ac3f898ce94327345aab123bedb068d747667912c532e38bb326f3ec300c4fec6496e9dcc562d4927d4829efa0203b083969734e30a9e7ea7893936a36d5908a4b07cf2311539f54d0fa69758493f57004b5ec96d98eb26657d945a8c44a1d6941ba506017054ffa6d5cd347c68a81250c57e90c5de569ff21ac73f8ebed491dd56de7b09538e5f82b95fe4aa1530ff39c51b7b12f7e93963af257e17bd1d5a8931f9e2583408b9912ee98561c8944849eaf4a36ebff4ece8f0c296151a0b0912e0b28a184c3d6ec421ceada6e7dcc1fee569aba411a67621fcd3f0e562b346b4072c44f318bc2fa7f5114939c661835127ad878a1807179f6b2781c1221561263d799e825da171f1ab7c6b09eae5ec4d664bf7d5a733ef7acc313899fadf4d4e80018b5a5302de7a1aef011124cf267602583b3533c4a84e1b69200b09efe6154c8cf6c00aa20ec3e3425c2b73ec5c8be5a7a82b265f195826a15f2ea7f25491e75cc5865382cb05681ded728fbe0db0d3508de8090e20dcf42c6329472413bcc34f19527e6838431a05aabcc40a17633a9b2267970a2aaf00c4d82f137354559538252d74f5942cccabbf42ebd9395ebb421f08f617c3ba8ae3c9630fa44abdbf1b7257ff66a1dd5cc8ef93f4f58749229f387d61ec83ef9f292c462a7843e80f6188af54c69a1626b9e38d66aca57225b30344142e4508fe20652f89a250d29abef6c52728485a2cded1e96710ac267665ef90fbeca7dd3e8c9597b789e34038d4c2103844f700aebd4fff1d6e5845c6dcbbdd84a5736f0ce2f24388d8ad03c89489f4aa5848a44e3e8ee7d502cf9ba2249ac1b8105ba956ca0be62522cc91983eb042ba4801a859bb17d227813055949d4b037f6fa96a870da0e360f9fb6e5a5994980019ae268b40397930edb870406811117b6b8ce35ba5bb61361a6a9220079e4b880a60595331340fe8301566a460f81904f231ce0a86e4581decda9a815e013b145b160d1c3d93ea1718589bbbd5d2a657df35c0b8e863d6b03190b7f93a277e9141390840be0f072aa5690de3e92ba55c3041ce7485dcc8fe47c2b5f946deed47380fe8060311bd456a4f1cdf7d2062c5e4bb19ad7f1b326665fe6dee892c5f76a8db8fd7540f390b2e2c32080772f6ac659503534ebe9e6feddef4c84a9367c5535754490ac41bbead31ffb6cbdb2cfb0cb786c08b504dfda9b0333fac951cfbeabcd2c1a4188ca7bf26f36586f529fa5d18bc0cf43620d0714f566692e3d70bc110de1570982e8b59a5c04e9bc0900cf686af0330b90ec1db55c93e68910cf4d4a512653a12b0eb8c169a9724a8fe9368785cf507b41c7b25dba35d8e4f8a8435f07fa64a91ca52bfb34e58e1756fea21fdb11634335d47a1200c30ef0e13390b90b797baf21e13456c88a7367ba3e0db9143d43770842c2b049f33c0ccbc1a4b727c279f259a22b8b5c6db8b327215db84a1506772088a0253b54ff9d265c0062b0d99510d00633fede1cf1c9ef92f0dc200a18e8b5266327a7564d050417dc08d42b70c7f2910f77d6ad672b600ff91803f533b2e2e97563f4bcb11e6e384da6765da425c3dcbe4f9e629ba767f5bccce9d4b5d7893e655f06941f1cb4e90e8f16b0963c2e5686d0821133b16627540325b398d0149e3b622fd7024f778c150aab533df1d65dcf13456121cb4c42bbab739eebf2f17b938cdfd541d59e4975120392f5df15447ad758c64984ad25b3421337a8a88b27d0a0d9a83fb552ceb7151c5e1d5fa258dca4dcc387413c08c8984a46d63ca7d9eac1c63d6f26ad47f34407cf3cebbc9c4e3883a5ccea3236608511de3da112b8838ec0881d19090229244999efd644aed2cd97f313ed102ca2daf074e65795ba79377b3015352a9d6ae7de0f92fc1d5f0ba993c45dd8c7e16add8f61094856ae5c1d96630825f44f285e0259b025e4bf0ca32e176b85ffe54fc94f0319f01b38c8b1578822f301fec67b22423edeef5a5827493e94b7d108b2209c27a9bada187d8ca74699a288afb20474c4b3f3080c30b6d9887a0988e59b112155f88d967307e512bb00a099458aea6f83e4f15af888db31de122a0569f68e849eebafe9d29ac440dc5d0f9a4c2e2333aad0bdd21f62f2a803582420dec0100abda0aad36649e33a5646e6518ce7d95dca975293526c27803fec6ea8bbbd886401b0d8fc6b7ba83082d908e4cf6d27ae405dc80b1d863f55a7fddfba48d016be7a2cf947b8ac842dbcb9950e6833500ac88042296034994041d217e1922f457536ef19e4274cbab05f378d0bc4a36fb34bad78dd150763b5dad2823cd8a000162524961d964f83e656c144562c28e2b28d9abf0e4510dbc62593ace27d0267732447568953019e8cacd0061fac494c71ce0359bba502975ad60d1be957ee9622c5e2f2486528fb993f8baa4aa43edfa6cac4afdcc16444ae862f8a99da179f7cc2ba60b54054953e00fc0bf594049496440fed02a316e1b0e0a5d7d8461fa1675420c389fe6d48c77044c72e5c0a30e2399fcb4e9c4c805cc66040677e5e22ec0df8757f141d7442ca07bdd8d5523b8621253a9b2bc04796c8b50f7844aa53e9a1604f39f03e8b989d3e2b536c0208d3658ddf76db120f08470805951a85ae267c1198d3b33d6b75389a7e9f72e41a425e87b7e9318dc01713ffd381b400c8e7a73685aa56f5fc344d6a5eb5f4a443994d0b4984571419daf0f2cec6030841c6a23df58bf07c048cd0c98f3e99dafeee9dc760ae812d09bc526467d5f0ffad7c364a919563db3309c16ab8d5677c31dce6bd87c69b3556d66bb297bd7da8223a0e74f2649ffb00d8fc71e1183ee8c36d9fdf84534440062b37e14170844542c58a59f88c8da9821056cd4400d2201d14904a460fae0950ef8bcac8fd8a30b2905a1c78aa73b4d67e528a6c831b0adaab3c93d1e09701a661016baac54670e7f67432655950d0baef2d1f908205ad461195c0d975fc91ae53efd5f599f3c9d54445a64c6a71e4edc4eccbeb895b83d11d9597c00661be914453ce9b8c10fc8c1ba5806d1cc63e690099a4deffb20393564fc8e26b3fc959d8c1e6e7bd548a4c62e354eaf46892e0c212c2c2ee35063757264c871cbeb4376cbb64be25444d906c7312d413a2e401614d309687697222b7d9049b0bd33148f7ed370dc8ccbe02dd48fc7cd1f9fa79afcfb257637c318fbb91663180e5e1cece4a098c8013cc85bf2e08262bcd54175f88b03c16bcd0c3011b93eb67b1ec72568bae23da446e593431a64826aba043d62b55e550f29402e247a8df8afd4c8d236877df8a84aa9886ef90d88e6129a5ccdbdd76ba385220f28203cce0c9c7eda4125d5a9f82501abf4d46ca94e5452fbdf1392bad81d5fad1fbfbf225ed45c264082ab151b20c4c5bb788725f56b15cc92cc9142a87481ed337b944789242a4c9b158434c088fbac1edf50aa867aa2002cbc296cce78142d66d64bcaa4c26c3b138c626fa8d309e91d55996152af61c803fff6eb75cc55cdb52903d7e83b180f64534c21694c00c1e23042fdac24c682ff0099a742d1747bf816cc49581de395714c11fc97a2cf38938c76723fcf49a34224a66ab986def170b230e2c09201054316bc2e560681d935ac544e30dff9b226a8b0db088c814aa3c22efa44410803d1f67df897a7b188095a0c6bb4106f8bc5d8142b412dcd2cbd2c440a7495a69f8395262f4c68e44ddb3384e6beb5bc6da6d47c303e589777f0f3750ac35e75a60e2a940e2a1772dad861049c01e3e95683fbd3a163fdbb05c5507f86b8ee8bf237dad1d928f19542d29fba2715bf1f5ee649ca7dc576e643591814f4d185258859a08d2d6a8e8b22f28ffa39afbee01c1c8e0861b52c9baa8c82b9472f54b41fc9ed6f05eb7bd00d84d74c3577310aed229edb650eeaf4d0b0bf516aa4d752af9a5a5f4d2d8a1a28e3daf31ae7b5a635d0d4ef2ba65a3c4ca9f29508316c07b98763462ccbb125781f3c089fe487b6eaa84c1bd63c579ca022acc15d1fd7f2a67323dd93dbf08e7e6f6e4f1c7dabfcf4234fed9b42180a7298afdfd4680a6351afa407f12b1cd225c524547ee68a31c52b73f0f61837c50570d8a8f00771031f9a485de9055d2520e8f56d798abf44de8eb8b45a7c660ce30c3e0eaf5ba1593608965161717e9b68ace84e9686e8c7ea603a8767a67376a76088b44a5bd0519a4565c66ce4306a08faa7a6617812329b42e9676a942cf20708acec86b8668ee20bf4c6a09981d744e9d7f86a667b469eecb88f7d721605d1fc0dd1e02c6364c552a566749e70d8820f422cc44c0591a82add2e06fe69964ee631669c479b313c6ec6f3a819cba3d1611f20dcfcd7d13db10b1141f303bb685d94482f38de9e579e5312dbe17ffdf5dbe25bcc525ce8ce312ef1f9f15754a500d63e13680a903925dd3037e7568cd0706b08fd5994575ef9f5ab4489d6269d771c7b849fe042bc7a9e734bec3e78503eb91d5e642a9e6925add03415233f51817e55f4b5e0d101b3df8c0ccec1b3d3529cce52e1c81af3d266b6bb7d289e63f5a6bd316f775c6b1d47a7266c68504b34fce862c55ea66000e50f612c9881f372b6ce82cae02ad2f6a66fb3e0205bd1a6082a1237100ff2c88e2e8675ae98a1f362b66e46ef1fa77fd9dc9137f38f05fa70aa477c70eecf3bfe66be536fc1dded8eb997f7f95b7c97de09376ace8ccd62017478086eb3760ce24462894b0e2153682985b5f25ce2eefa1fc6de4842ac40028e1784740a3a60ee24850300c3300cc3300cc3300cc3304215c2bcbc9fb4919415f27b81941aa16fec9b64a5ac484a86e799995ed1a2456d04efe08def585702930a310a620a3fe8d0c3238fff6ac9ac6eb1ce3c3ce8d821598fcc8a9b3c820e3c3c48e675b182a6f4934a083aeef03072548cdc526f8f7f871d1ebc4fee887bed1d9a89410603c610830c065c1d1e4c54f50ff67131573c0130860e3a3cccb018e67e432c871bc9d031870715ef2ca4d6486ddf7388b1812f74c8e1a188bc59de8958a1230e8f538e73dbc9f46df30b8707d9fc4357df5f868e373cce1ed93ebde2c4dbc5d0e1860739314ad654a591901b43471b1e7588c9c8b8561200430c312c501d6c7828e5a997e25fe89d1c47569e2a45c71a1ecbff559cf710520183bf68141c27235fd1a186c7ab73613fe5bdeb2a716441a0ac230d8f6ccd25e5944861dee2c852144c800b2eb8e0a20c08d8b861230c31be20c3737c41c60d1b373060e3868d1cef12a84018627c11860648d1818687a93a7bd0af8ad49f9f81081363868771239e36c7e7c79d65781cea7924427f54d508191ed79b5af6f18992f58fe1718cbf715d2c5d22753110f1292ca54f17324d617890b59579cd2a44bd0e181e8e84dcf169ec2f74a77e1ed3ec8507fa1fddaba39a8985bbb0d768c8229e11512b4119db453ea2830b0fcf47f384b877f12b5b78106de5b311a5161e9fbb25c90e294e0a3b175c601c3ab2f038a365c5254f3e3e161e456529fffbed7cb9ebb8c283ebd06f3ddd4b5b96047458e18197c6fe5499eb29540ee8a8c283e49363aa525decfc53e1f1bba510fa9b9ec2e35e0f9fe5c647235e293cde0db142da48b66057141e46d8105c52e8f28a5307141ee43cf92f2b4974c99b273c8e312293a5e69379d2098fce2da599ca0fbf8d7534e17148e76dc59852e8983a9860ea7665c4ba4ad66dc7124e7e96727604bf8f122a7b8b5975b1fd5a7561e3464712fa5d8df1b2103d1216f9f81159a5eac2c60d00dca0e3088f3b27fc5bccd77fd5a9247418e1d18f946876e8cb17241d45782ca94763b2905162f40a1d44781023565fc55b4977a563088f24f7377a88b618c4c2057708e1c15f75c7e74ee1f28438b2aa051d417850399975d88f28d0018487fdfa673fed6261c21f3cde09dd297af826d0e18307252de671a43ab63512e8e8c1a3ca19777737f642bf83070f3d2d5dd27995760bc191e55f9091c30b62dbb103b7d7fa2e667571647159870e1ea876085912e5adda2b52e8c8c1c3fe3297f911957c1b133a70f028742fe844ceb19385050c1d3778d831359727b16c6bc12e74d8e0d17952cb5eb9769bfb116c183b812d74d4e061ee9bda2c99b4eab283064585cb888fc9193c08999092c1638f386fb7e7f5665d0c1eacfbade6f94b88ca74c0e071fcf93029dc5532df5ef1b0455f43f77ee8a8c5158fe257cb6a87c90061462b1efa578ce1ef35e59fbe8319ac78705e65952e138841c69bc2aac08c553c0ed1b416ca72ce783b43156f7f087aa1928a87662d21ce3e3de7f6ad2061062a1ecf75ecfb687a3923c4051739caf8028c728a87a67935a74675cfb84cf1c0c3afe4942e6639e4cbf8a257e0a578dcb369e982c5ae28cd7be185a90dcc208512c363f5878f3346f13047e87f4de51b57641c595839caf84202898119a278d017ec443c4e7f481f4756190446b00b2895a38c2fc0b819a17810f7222126f63c856906281ec5a814747a369f7894d2eb623ab1bcf992e78b1b4498e189ba639bd8c72ccdfd7622d9b8963e94f44dcc982e6cdcc055cce0441a62c60d75135fbc797fcb932b21ac09d27a8a9c93945733c9c4217fbbef77289fbdb40b1b376c6417366ea029666042dd8939dcfb42ec5ca2f7def9aab47461e3c6716286251efd85bf2d8baba32ea9c4a3ed334d6aa5f9719202b428f13844d215f3ca21fbc71190a1001c39bee080f9c08c493c9c10cb39e92366cd1c10cc90c4c38f9c7b4f35d2d57722f1a8c2da84af0af519d2907818ff5e3a57cf331ef120b6f4a41c6477b336331cf168bb2c8fc86f64cfde8c463ccc99753396b9fcc59ac188c7792ac53f776d9d75110f53b62dc46c4b31353a43118ff6afc4dafe2e763c23110fc37cc893215c66b1f455620622b649113bd2dc357988376c3b7e9428d16288ae2de8a706bbb071c35c624621169bdf4fdba71bd213c2cecffc5dd9320d7d1006ff8898835ed2d65c1058468fe1f9c9724e20d064d65a3157ec00a21423c36a5eda93ff60f2c88ba96b8be9c27e6822d785bd7d504c7b64c667c307264befc44e4556f65078e631750d5b153d147396ecd9701e08b5b1a623f87f59f040659f8494cd9c90ebc2c60d2289197778545d39427acfe2c812a3ec0033ecf0386544cc5135b4ad5933eaf0f8f7dbb38cf53c9841878756493e868e891d312606059630630edbe94f5ad098871266c8e1a154874e29a6d34faea861461c929be4111787c32a3f53dda53af37943b925c67c54fbf6b8c1081fcd7b2fa5dcd76d20eba4bcf8b0a133cd1bcdac25de3538f1a9be3d713aa4ab86b24b6494f6681a8ed8aaf2fa94314b45c39f29ebc77a99889ee1f1dc93e19366e46c9aa1dad1a0f12d31e85bca50ee0ae99c2b7b0e153214d52a69bef91c231cc3521997b24c252b550c64109bfd5e49f7e085a1ed3c6e31d8a575606037afcb7c2a46c817ea8d0c9297bc62e685e2220433baf04cee34712293ffe4022b955267fda49513d2858d1bd688195b789c27639428b6c1673734c30c2d24a173e6bf593a643f0b97264b4b79d368261f0b6a7ec85765ca6cc7af807b97cbb9c690dd0a5e92dca6f3d3c143af427d5ee3361ff3867ba8b0a5b4b17d3b5350245a0ed1fb96c2371ff95d628c3747418999a93541c29cbb50f02cacc6dca8cd84fb84adf37f50ab5c95b675c27177e6729cdcc9724c13cea59bda3f355ac304f5d267713353dfd52cc13d4b271696c12b659480df650e13a349787fbea348e8d4337d18ed949bcf23187a625ad6e5ecd20855fc60962cd3ab7a8a80ed4a44c44cb3a126823e159dc56abfe32d43a8435aec7aa5d4280ac16f919390b2ffc44d10d67031cba43c9625048279717272e97e50ca5069c38416d907d759540acb197298480fc877d19c32ac539e076eccc8914290307d07c7afdd9027abdda6037a63aeafc2e7883939c8df3465e9e5690ee3a0d2ec94def6ee14ac1b78692feb1d1b9c935845af8de6af21ebc2c68d1a3cca92e041925b4cc81e2266d0e0a165abacf9236ef41443881933786cd3514276ab44c95f060fd7a6d356da0d0662460c1e5af7fbad598e52d3f3f83003068faedc43bb3d5486de4ce06a0f58bce2816c66ae8ae9b3738aef0e58b8e2719a889fa79249738667072c5af150735bce88e94c3d8373c082150fc4a3b8cf46a69eecafe2f1658b10a385575cf3081cb050c583d2741feb82fb062c52f1a0baf635667b6cb0970d58a0e2b145dc98f1a143a88eaa018b533cdc6951b7378f98961b637cd185093c0704340d5898e261c7cfa4e98efb182ce862095894e261cfc51862a327f91e1b376c7421011ba478904ddfc36bc76b148f64a3e54a296914c5c3b829bac66bb8b471b33160118a075d319e7b4a8dee75de00c5a3c908d375d1935ecc9618b0f8c4a3905a9a2b7647fbcec28085271ea5dbc82929513060d189c759a45e439ea89ce694130fbdb3790c531b39215ad5052c36f128e999dde8775cd76419b0d0c4839e9ce64c37757c88dbb861c3461712b0619589079963f84cd5ea7dd1928505261e66f7dfa44126ea44d5049ee3120f5e356e9e987aa9f252a68085251e44b4496b9d74bd6a458118262050c0a212f6fd8594901aeca644132b7346d32cd7153f0162e4c02205d0f0c343d98c713c84ae2f3d716491aa0168f4e191897d45fbc4866b9e0f565bfc1839de84ed3640630f8f3f55fcd54d71649503d0d0c3e3fc0d9a93fd85a4f3f3507e4c89f7a08187479a3ce52634fa3bd23b3c1219d16b4d115659000d3b3c48df949d3a7ada6a5c87872e925acd5724346598c0735c793a80061d1e06ad9014343b07066f17550e066f0e441a7378a43b927664afe3f87278f8fbe9ddb642e4cbe3f02088f4a756cd8e331c1ee5f4e17eec634e297ec3c3bd091f155285fcad1b1e59fe965acb8b9f9b363c38b9bad594142f25d9f0207f84bbdb8e395259c3a33c31dc2edefc7e6a7828fa396368f86978d0baf9f1248f8647e7693f6ae28f78cef068e492c7dce6fae99ae181e5464b6b113f53a60c8f3a53a8f4471ebd90e18188bfbca6f339918ce18165efaa968de19589e1c186fc193b1e27d5158687f9deb2212607c3c34ad539d3eae70b8fb3e728b94e9ad1f2e38507fdeaf1ebd635687cbaf0a0fa323f49f01d1f0f171e4d8c7bb62969c50c9e2d3cfe18529859f116fd8e161e56873c99da67e181c690739b85d9301a2c3cca2f7e531eeac22e5778f09d3b56ce826e8c5678fcd12edf7d8cd179151edb6ebca8a13dc60e156acf197332957a0a0fef2b2afb67293c08294f91fef3dc3f47e161c4e74fe529756767289091222fdae64f787c6297da63d4a9c74e78b8e9976db29fd6266ec283ae5c73f7b92e2acf8487ad6f91f37af4fd2ce1e1ce679fac92376f253c72999c2fbe9e2d9f243cec9bdf4e39f7afa68b844732d6f1e5b7eaeb1fe1d15c0831c6758cf030588e8f266b111e5f5eda4a1aad9a62223cb4181ec283b4dbae697762e78811c2638d9acb10663c356582f020fc424e5d0f101e7b96a42e32f7d13a3f785c97d163561f3ce89433742ced554f0f1efe8755affc10a990070f53455e8bde9052b61d3c4a9962c8cbe4996e1d3cea18fb0d1d2add5a9a8347a6da95248613078f73375f55556ef030ab26bb1ca653ca5ddae061c40dea9ff215f6a9c1e3ce61af7b2b57fba6c183ddcb34497d3e84aacce061ba328b11641a32786cc1b3a79a2faff0d288c123499d74e7b593e9d280c1e3aa7d8fd6561915f38ac79dc7f5dec5ac6e75c5e318ce275c8cd88a07e9d16656bdb2060f59f138489ec85ab15ab1c3553cfc1cf59c337b324f50150fb4c2794fbf988a07a335b9d23379828f8a0771a534678424993ea7781c3ecebae7892ee936c5231ff5898f5f134b97e2c1f4591299cfbd9225c5c33013633d6b46f130ae7f94ac9c95f3a238bd76ca259123a17894bc632a624240f1a09268a7d2f3aeccf9c4e391f1892e292f1d4f3cd60b9b663d072f773bf120064b3d1fab764c4e3cd2746b13227cc895d9c4437135a938c91fc29a78a479ade13da2474d33f1e0f3561e4ba121ddc4c4033b8d9ce2915de2519630af728f251e6bccf3fc714a3ed395786c1183bcbaec589a29f1307d8adfe176a2f5ad493cf0891b11aa5aa1b192c4c3cd1936eb128987993b9e3e6f45db85c483948f88d2ee231edacccc64b214b61b473cd27fb770b535e2419cc9521a221c59632c192a60c4a320b3ae1adfdbe62f05c862118fa3a5deb45f17453cb091bcb55990c33a0c1434e03a0c14fc11208b443cf29c226f9649658613110f2b5b48c5ac31a25339c4e359cd58bb4aa9c863168678541763f32926b2bb9745211e6a6ce9945b16d95917162c19642c9a200b421417278b41e05395dc439ace95c59145822c04b149e8ff330f37f517609471830b2e8e7f3186189d02c700175ca4c0c9483b641188e2228c2c00f170466a2b5a30b1cc0b4756292255c8e20f0f2fee237d2264e107d7bf3c04b95b8f6f70c1c5152eb810838c2f5210c683a8c8c8314600ae90451f68b7b5245af6eff3e1ac6de926e48eeeefc1bb946ce6743ef27b3d7439d7c4f11c542ff679304657cc5c6e5cb31e0fdbfe67895927ff7fbf0316f247eb1ca2773bfc16c62d4de27520b28f77f4cd11a60396738cb7da392b278b391cb243eecd3de3c9420eb4c44d1bf43e77e260de8544cf1d5672e0f0707ddf44434964849c2cde704fdefa6629d7dd709ce5e0773eb9e236a82fdb99626c77d9f04fbe188f9d1395ae2191ad49c9f4c14335e8d2a94218b9300d9bfb4638c91ecb3f3418c5f725c5f49d3b831dac2443244f489b819d30715a970149ed10b12603ed79f6791e83c17f72dcffb41a1683393cc7491a7437881c062bd467d19ed280e1cb0931ed9025f9c29664d22ff6c2afa721b36d2de22e6c5e16f31683e6b9706c8b36eab1d1ccb385a7bb6564a526a2d40231d9547c8daf4b168efc9f4b97381670f5749247422e0f5ee18ba031544abba93f2b98a5691e92c507bf0a5e956a324fcdd0664105cc37763cf369dc4c218b97979c31eb113752407724a9955d691e852dc5cf2c92dc365940a11027b2fb39c24fc8f38659c6b1bcab13980ff12e53d38463645bb2654f1a261073954fcb651acd128e5f6f51b93dfa4ae0735f489d847248edbfaab8f9374830a4adb238022d5fb6dad14423d031a5ca5a3a3144488b60a5cbd9397c309d08c4c921b6fc4d9c87c0de85a01f6724bc2b04643d7a2e8f25c10c029b2fe74c13202ca1296bd6385fa9fc81127aa2922f69ef0373df87b09bb3f33d3854c8265ae101d1eb5177c9620767ee09297da84f962c7460e7983d4cce295c88258b1ce8f3b152fa14e255b2c081b26add19952c6e80546ca02789bef01324bdaf019bae63d2febf21a601569925e4bb929c99192873163366bce8a5c8409b68562b662b6216317814268b743efbf908412fc64081172510430c30f202366ed890808d2e24604302260559c0e07184ddd48f69e7e9ef031daff032fb2a64637b5cb1c614ab424ab373ad78e2a4d0d375151d3c56201ab919f74a27b78ab6d62b63e4adea5451c7accd7a1a5d26ba5498e144a5720ce1e74350514448aafc3b9725a7c05ee42224a6c414a79aeaf54a41cc0cc99db5430829f21d114913320a2b45dd91601715c591455d4cf2506853c1ef75a7a2078a7e628add88465ffa89f24cd6e85091c9e3892468b8e53a511649363927f90827be3c3a312b17996d82787f977591dcd74441b46d627d0e7726bcecd7112dac524cac194252d81999dcea129c64c5649725dc2475d6a9accccf4abc394ebcfe53a488727450a24b99acfa39777a80961f31c23806744ce2d14bd478d29872afa1ea90c4c30a59da268287e43f7544e2a159c82178c5ab6a4b8b094407241e9684eeb21bb9e3110f5272aa7811950e473cf6f2d08e1352deb50b8eac33137434e2c1ef5dca84dc8c641b471661c483d4741e951f438c1c5e789599083a16f1e8fdafd357864c481a2c7428e2b16a77d84a711b516c6c4347221ece797ecc2ff97245357420e2819476748fa71f73d9211ee68c89a59fa555300df1589256f4eb8414e3856ce828c4c397bc92e284b1ae9609f120a3a5e8ec2893337b4b39740ce2c1bac551af0f71d2c65c1a3a04f1288987470cd265201ebbe778dfc1825c0889aca103108f75a3e5b35c0939a60c0d1d7f78e061e5b13f713f3caeb4497a377e6bc4d7faf02863baccdcc986c856f2e171e646c9cf9a2f584cb5d0b187c2c5ce31ec4ecce1d535d6f020bd4f0c492978867925a8a18607d9b3dea5c91e928687e5992bc538c1a25eb0808c1ca42c60e3469132b66a0435d0f038a4627ff2f839c383943cfbb2ce33123f6678a4318b56f60897e1c1a6e0ba9aced57337323c328bf6b1e2848f21158eac1378fb060851630c0f45826a1eebdcc92917c3630b221bebde0a438c2f72f4175c704155230c8f32f5b484a878eddfc191e5fe5e9c30d60bd245053450812e24c0821d03f750030c8f7f7bd5c274c595387194b1640da8f18587ba219468eeb9d85e768c0c58a186171ec6fc2f6f8d39a4f5338c1d230335baf0b0724c162e458e993bb864b816036a70e1a10749f9291b3bfba2c6161e861852d346aa753a8b23b58616c888cb9a66c41a597854d942f3e64e1250030b757d6dc4fd8c308b71b4c6151e8e8d55c7adb22973bd600118638cb1556094a108a86185071542929dc62b4d31af82fef792f2788f6454781c2dfb47fbdc994295a3c8fe2585471a25bc2f557cea7c47618b8b6de1e53739283cb294a36dfacbbc93e6277c21e50d333ae141e9ab77a5d9b0cc2c8eac7230d80c359a600a41df7eae35baafc184c71f21dfe793c81cef97f0583d86b460d351c283add07821d72d2aa693f0e82c245795be487878a613f673245d65f7088f6235eae7dc18233cea90fe5a9ae53e8564111e55e414ecea6aa2934478143cc4dd0afee13a5286f0c8def732e50ad9367642789c37a4f8dc0c8998214178d0f71a3675e3e3250d080f239dc690d773dd42e8070f6328dd0d29c929d9c6070f5c42a5d73c5e0f0e9d1c0f1e5eca1693d2a6a72ca11d3cd8b393f01be3a45f5a078fd7bef56cfccec1a396f388f1edf0e0591c3c4cafc982c44c77d13537781c65394395b8c8a4c6060f364e52640db5068fb3d36c5b8c21d53a4983c76229672dcf6db579a9318347eba923f3f62334a5d490c103898bce3c61cdc72b3562f0283654ef46354bdeb0060c1e9c4dff27f36c1779f28a47a9de7e17dc3e4d4e5cf150a3cfad4d58c6a7d68a4723714290e41a473563c543b352094164d2ba59abf846bac6b64254f128a5aa31bf743259552a1e67cfbfa4de7183c6a878f46672efd5122f644ff1d0734376c68eb0a085291ea5a97d90494bb039ae148f53d984d7e81469354f8a079e22a66b4c9656223e8ac7bab935e52cbdac9a8be2c14df6ea58bfb2a93ba1785061f773d81cb34957503cb8a87aa65bea271ee4d28c9b11db1183ea89873da9227db2bc896776e271dc48fbefb9f3641a39f160d24ad2ce0a6ee2814b6d9c1c93929d68e261e8ba09a2c1d6dcba4c3caae914e2591da26d4c3c4c933dba5fbd9aad5de271aaf1fd8cd029e55ae2a168f29660f613430855418b4a38a17464524a3c0e3937a77c5b6af9f649e8977636ac54522f035a48e241cabdc9ed3da77496d1326811898763969b337e782af340e251f09814721cf3110fcd4fc274aaeaa9f51cc14c76bfd9f8b1463cac8eb639d667c4a3a81f53d21833e9a68b7890d33d5b2c715d0b29453c96a0ba796d3d57a813f160d6ef2ba3afca5639caf86205ee4592410b443ccadc9761527ea51c1fe2616a8bac61f37cbf6788c7fa13ac2b75f7aa95857860ffe529e4f4b447b420c4c309f12d7c4a3183789016dbf27c6a1dad50108fdfff7c226c9c285719617cb139c21023108f63264da25da2597103e261b88f25bf3a21edf61f1e5bf458a14adfd6d6f6c3032f2937edebacb16d1f1e5b8707b78a2b1f1e4aebc667db46e97f0f0f464f3ed8dd590a991e1e7baeb798a32964a5ccc38309d54e951483794cc1c3a3a42312fb8216777838391f25e7cfdbe1c19ef94fa7754c15bf0e0f365ebc4899633ec49c0e8f247d1ec916a1b2273d87473a15aaafe36c889fe5f0e062a2d6c3e2367d1b878762f37392b6b1276de0405ad088217656dff03853ce951eed342126ddf0a8729e997fb9df0d651b1e6e8e17d9b345f05441363c8812e2f6aec429d16f0d8ffa442fb2cbc9cc7c6a78a8729d346987a4e1d1cf45cc4bb1d2c224687834e9f2662b3b99cfb1333cd68b8e9e7333333cb0704972bef766b60c0fcf72d8df9e3091e922230739c02260e3868dea8216643883c41847836ec6075a8ce1ec31e6f38755b2ec8be1c14c447f75abc79cfb309cccc6cd652a471e0c7d6cea9d59fbb1d1bf60f85eb4fbfa14722f3c8c542a65299125634e0e2dba60b28eb13cb9b06cde33c94acd1654ab0c3dff30a1a385a3b996c5578bbd942c2813a3e4fd0e318505bbdf3a487d053e4e1491143373ace0aeff269f97baabd0a4b8853c16b2612a342166696b908d780a67ab884d1652d35230c5e76dad3c694adc281496aee4266a730b855e62accfd89c7ef384ee4ee762639c8058d2a86162f04d4f134a7db91065c2ed49b2c67e092549b2d9cb2f85799540659094fb344afe259350d87427fe91f30609e7bcfbfed9536639026916c57e3c68088d6054aa4b1bd3a55c11d69c1ff2ba9162227496fc2c9c4f30878004ebea1021bcad7551daa24b160432255be54a8f1e534048deab3f4b8c3c92da183b810c941a634de08583c12810e3509121468e353dd0e2078f7c23b73aeab775922c202387b2808c2eb4f0c1e38b92e37d3e867b09bcf026438c2746ac045af4e0519254613e850b7d1e32728c41e5393687186414d482078f76227ec24a2d5bba706469392fab163b7814529e548d2595e344cb60417b01c61826f862085ae8e081879e8be53c070fece2eb5e30a9baf771f0d82e33789cfb377874ae96fe72d84f7d6f83c77b514da3262d87ef35786c12ca273b731a3c8eb89d381943bb3267060fa2443b05bbc99b5296c1a3d3a98c5bc9dea39b183cccf9369bfbff4675d502060fbabb2edd85941aa2f28a0759ee6316a3a4da1c573c0a3ee9cd52a615bce8c6ccee1269b0e261cc4962d0ecc92a1ea76da58a993f1793a58a0769eedbb388da5d94804023150fbcd2c273a89074410315042fc918424812d31c2232b9c63576db8c67ba40e3140f323c9db7c4541a833d041aa6783c61d5723445234b29041aa578a051faff7e32a61be2c8f2010d523c347fbf4af9525f4a0e5681c6281e8678a468971337668b498186281ee6106df2f5b7c5df0dc5e3bcaa31d4e755c7f443409d4003140fd3939574d0a02329cd051748a0f189471129e77d0841dc53ec868d1bca021a9e78903745daf2ce77e2c167f5968a9d2d23dd9c7828af9a3cb359460a7f130fdf439eab48cbd8af261eed844dcb336e261e576a184df127c3a60d261ebea7e9bcfff3613f778987af69dd2a916289c795ca3288640a4975aac4634d9edf2a588a167ba4c483ef9bd42974b0a8de26f1f05ddb225a4845d610493cd4cb38fbf29525b55264a01189876295ba43309110a5a20189c71ffa43b3e86c8efc88c623cef24f494d9a3bc54fa0e1885ec2698eabed9353028d4694b913236abc7f4f1824093418714aa75229d34716b017de616c0ace52191a8b78ecf5a19fe5f22ea0a18847b569255c6fd5be480c8d443c4a31dd84709fdceb530b6820e2f1c5774e8d1b755483340ef128794be89c99c691758386211ee5d4999a8046211eba7e7c47b85c021a8478f096534273a4b5a3b36280516a023406f1a85bbc7370f368e9bf32561f7086011a827898d64effec32543275e4755b12100f67d737ed348b8c677024293f6250e094c61f1ee50819444543de18172f02b5822f4ce005a3a08c540a7cc08b0108e00a8f6a42afda586d5c20002b3cc8cc93719e591e97992a3ccc9f7be352b8f0759f1300151eed4eca9039178e2c3e5e94b1546528e0050298c2a3f05952c9df367db92b1080141ed9c48c143df37b351a850741bea24cfb8223cb049e2a1000141eda448b1663b7a698aa1408e0098f242fcc73b5044fa97940032260e3868d07942100273c8cab9fb12db6da84dd46170ef02fc8e8c2040268c2a3cea89d2b6bccbff630e191cc7828cfceafcf97f030efb63be73fd7e4b0121e4baf7c06b50a493127e151c514c6bcd38b94ca487874e1fe42a47ff0caf2088fef2547ffe46329a534c2a38fa88aec5829c28354f5cc09fe1f7c73447850e5b943f768c8b4d5101eec55ec9c58b80889d4180108e1e14bba507e6666fe2519625cb1808c1c613ccc58004178b492df727a47889b231c1000101e966ce49c617fb743ce0f1ea6906b26d43a3e787cd371224c925fba740f1e6dd87f9faff8394794070f73aaa346cc1009dd0e1e8e060b615e738ca8a50e1ef84c8e93ed36bb37078f2adfa907f19a95240ebec8ab9b2a44e5060f3742dcdfe56b83471b82f6efc6a4060fa35dfb6850d10b01d0e0719cd857297743ffc6bbb071c386066cdcb0b1011b1690800d01cce0d18758f2539dc66dc32800193c12ed10728821774e591e631d870a2006e7cc4d5b39bf213e8e2c4f01c0e061774caac4da84e8498eff0247195e14bbb1c52b1ec449ac2467a29fe5dac2150ff343f0dc6a936ab61386185f8c6196802d5af178736e86201b2c3a2f4ab04e065f6ec18a87e5933da35b75395bc58318967663e5ed90e855f1a0b27c5ae76f52f140dc3536e6fc34768e8ac79b32ff844ce79b18728a479e5a62a4dfd11ce3c7140f4f636c66bae6dcdc94e2d1865dc406bdbe1015291eeffac61b0b7b140f6532ac44deaef7a011c5a3d9991419164fd7e7503c981c528ea58e2189c740f1d02e05b314b19dd2c99f78747739e67256bb4bb2271e6b907877af77e291f686fc7ceb71e2619098151f24cba4cf6ee251d214daff1ee1e27f9a78b8fab9b5daefbae5cdc4a398fe36e3745a980531f128672ced38329342b397781c6642fc48225ae25164afedeabf275b4d251e7f554b878447b3d22941f57b8e270d9a493cca185fe262efd4ff2d89c7d31d63c53d9dee1c8dc463cf0b49ab315d6dc540e2b16e1eb91ccb2143a68f78d435d3d12e76a6c790231ee5d092412ba44a4dd988079f3b93cb7bf3a618c288c7f391fb3ce33a868f8b78ec31f7654dddacb34d118fe273fab6a4ec1a1626e2f1fe49fb58be20e2512e7fef5a6d8d6adf211e7ca5e4f23a89f421c5100fd576b2e84e085129528807fdf9653ce689100fec63674aa6cf17cf201e4699b493fbbf201e790c2144497112ba56201ef9ce58bc102a3a670910c77ffd0ae993feb08798ad8ee0185bf8c1025bf4e151acc8b9584c8da8992df8f0d853f0c8de5351161678047094b10fb8b1000670c1051f2f4a9191630c3d6cb187472185b02fdb32495414984015906580318609bec01c6ca107db220f8fcb66a27fa2c74f63f0f020d6e650b976d25f54eff060926b8c22bd66a1163b3c920cfdaf9d4dd9e432076c5187c757d696a33765e14b3a3c4cfd9beeb5315888a92de6f028c947e8cea13757a1346c2187076e79623649840bb52de2f0306f8e8e7db96a35f37078f0d96dda327d7eb97fc3a39035a68796d20d8f3dc7edb42bf79c42de868797638e9d4dccfb420e1b1eda87dc888a0b113b6b78a84127c4ca65353cee1819ff9f99625a4ec3038f6f1a8247170d0f73fe5e093e6f31857b86475a29845e4bd90c8f536848ca9f6a5b925a860729d792b2e620297e92e14155ff9c75be8ce1d169cea2f9c22286c7292f43eaa670223e86e1510afa59c2a7c1f0c8f54e2584e654dfe0171e6806ff8ef1d2db15bdf078b2e28a56ddc899d88587db2127a6e7a68eefb8f048937db88d6de161a947a93cad103d745a78542b36faa6bd297eb2f060e52e6a8a040b0f7a42c7fecadb151e5a9209d1a294abc6cc0a8f3dc86af418f76ef6aac28398e22464c45478381276937f50575f6b0a0f3e8595dfd6a99f18293c8ed673a92d5178ac5796f2e97a5eabd001e30b14f05519366eb0800c47c1056cdcb0628193e116301f6c0185471e427e75480e056380608b273cec38ad9c62494a2ad9090fcdaf3253f0490e32c428233fb045131e86c48aadf1ec7aaab205131e7d9ebdf6d465b1e3c0164bf0ae4c3ca6a79c2d94f030c9b889dc5b340db9126c918487f729abd5d7e5ff2a121e45ba0e79374cc73a7984072a134e2fc7602ba9106c6184c71a43d6caf6d1d4cf17e15178bcf590a613e1514852164bb3d5a9c587f0b83453d449fb9762e74278e49d83daee67d3cc74101ec508e934e2da407898a2a1dfea2a46f1fce0c149ee7e1b4be9a7e3834717f2cb9265ffeec63d781cd39f273d479b2c310f1ee728ffbc95275b2c77070f6bce2f534b88715246070f5205f74ae5239595e6e0a15f456f89b2117fe3e04148a5b079f10d1e4e9db865b79866316df0783f96c6b68fd6e0f196ded8844bd2e0a1a5563891d2dca4cfe071e518925945788af8163278d83f59691a3e5ec8952d62f0b0aa3d6255784bd8ca163078fce9cf3cf2a4cf7795573cb60f6721226cbdf7e78a479691c16252af158fe6e43f72f818734cc28ac777125f27bca4c3b6553cfeac3147fcd254f12873261b8f10f3bc4fc583df9c2645fa0f2a1eacad4baa9da778545351efc7a258de4cf148426b64c643f4986a94e2a15aae9cbdd38668779382abce21a4728cdd811aa3781cd267cd669ce87ab2281e5f5baba74d9b503ce8fdce18836b40f12866c6e87fe40b26ea271e5e7edc7f0da1271e4c68eacb9ead3fd9d789075b6e92396bfca4f238f150fb654b26bc4d3cbcd06a6de13a3a6b34f1a8337d63ccb56d8648261ee9bd4678a57c4e18138fa35ad64cc94ec2667689871ea4ab63588aca33d5b0c443b1b2330f2157cbe62bf140a565327d4a1716f3947878e17379e6fd241e65975afebbd12c3997c4e39c9b5255346791bf23f1c0dc35fe45cf1b32dd90789453e96f0e1ff1282385f34a8b9bcb6a473c9e1842bbeac5aeec99463cb81fb7b0ea9e5df2ca8807b731789ead105624b98832fba6edac7851c4a37049b2bde49288c7b3f2b923bef96ea820e2417a6c64e4c74d551fe261ecfe5dc6c98a8a1ae2b19af56c1e8fe31dc1423c7ab5cb303157a68a90108f73baf3cdec591fe91bc4c378b143e74bb9f35c228807e121d567f758201e67304f39d64ea8d801c443abe87f8fadfef02068fa092926c90135fcf030468b5d9539deb35f53a8d187071af3ac7ba659dd20b100146af0e14156edacdbc1827688efe141680a6b0d3d3cce31ab42db7d8ef2538d3c3c88f943c8b621d53c849c50030f8f623a89ed9f5d8d3b3cb68fb8ab9cac6cd36c87c7efb2493d8494d56c6ad4e1415b8e51e6ce73cadc38b2920e0f5cb3d4e87d68c78b13781956aa801a73785c97f2a5ef9ad2725f6bc881d5c8b0e09735e7e0c8f21bfe5b46181ae0820b30c0f02e05861a71781034b7f63a334be3476ed480c3a369dde8c86921d623661ea8f18607e1c64a42b8a6ab7db9e0a2861b1efeea5acb57acaf7ce1820b23d468c3634b9dda6288b92a32044716199e2387b31739bc2046d8f030ad56f8cf2a3d8d8a9123038ae1a8a42c8962c250240e0884a1804838121c9d2e00131508002030200dc52191200f75517e148003482e1e323c2c142018100c0e0e0e200e04c2403040541213476140181c0685c20151293c83e3038e4769a01afe0dffa9967712820a93d1d22c3bcbf4e230f8cbdaa7cb1e84201435064c9bff13b64e4cf41bbb6e949c408c461dcce080fd3a3859a5c919c827ad7be0b6c1da0768929dcd03559c4a08f9bc7e30dc75c0fc6460245e2d0b8d399ef48d8f8a01351644fb4d743d22c1e5cdb225ed301f9cde41d5711e4ca558268ab2d003a966978983d4da2794d6c4c63c62198fecaf0cb797127d458be588e51b695a641d4224a669f1fc164bef313b83da95df584ba97860a44af233cc549023105d3fbb10ef5bb563e61441ef67a9474001044544419635212cf68e3590e7f85c5a30fd6be7e1b6dcb8f43f7b79f2e868da9075b93965e070459795114e47aeef92c237f33057027e98381118a4f51663f08ed1e619fb8ff6af1b1586c63aa7e5889e3d844d6a46a0e7593db94463356be43654b75690dec952d889eec34c4f2fb4932cf7cbab9de11e2a125c5fb4b63fe0d8442b6d8b94ed315f3d0423e608ceaa2a7c0fa53111409683834e4084b71adfda402e6f827378ad879aceca9c933a14ba82b61ac628507d0b824e2a06df09050b351897039e55524434b4f81653c7ae043c2051d85907616724009c654120273fffa4b1c1059d972af81eba7f914a34b8843af7f30f4878033ea86af56f14206abda2d652eee758aa3c2580e7354e85445ade4e5a2dedb36197c59bb4fdcf1a7f7b7168e760377e73e7ff4596ae803461d0333a8bdf63e700cccedef0206ef93f5f92be0cde7a1c0c55808b4b7f538638d1d5b9f7499012e0471cc0d640a308c5ee8bbd20a53c7e0f03ccfbcedddf332aced894538ee53ccd74fb272ac5f45fc5a036b4959ca5ffe2c2b32273a9bb974173d18acf4f81556c15dd83400e8a06dec8fef6963a2ac4d30e2df0744d85dfae172b124699480fd784f4476a9f9e7a25fa654f7f89c4ac6e537d2efd2afbbdc27f82428b5fd252dfdfea9f98e93b74a1beabd5cf193b6a1e50fd207d78a15fa11a0a6446d4fd13c78a58ddab5f2def7725a381d626bf87bebd3e96be02eae7f4ffce6400c0ff77df1bf1576846724165d5cf09dc592f55f493fa525b3f678071f3efe3efb25f6efc152318f7849cf85788d5efbc4bfa1da232e3eac0d7111326e9c30280e7b4b7a53281c035f3769789526f5eeac6737a7dd0990c1936b8900f730cb3ce1426e0f895f5560c5edb35e06d50ec75012dc1d17d9898d0669f41ac14cdc3c6175a451125bcd10794d25c6e9efdc986ba2843ef9b7c9c297a524fb8907c69d24e64745b239d90fdc93369644762029e493cab49e72f05666a30e64434bac7073a1ab7deef5f178d6e8db0463cb0d19e7c29059c7da429e90989d068c7e8c228cb68a42374449a6bb65bbfa022f512a35d845215ccbfa315fe8015d67ec42649eae8ada8a2e8bb116a1dadd886683a5e8c0a1af9c9680e5d53ef52e8284a9176606aa9856134c7f82bfb9a498291b47bff88ea9279f2858788aa58e060ea2cdcfdd0d6818ca6e2b8b46cd2b5da01b93106b05619c3292912b07b761209f289b126811fde053701f167c6303fe3545c6a2828c8ea90a52bfc3186bb57a5d29b1411685d4b00e2a81b0c56d5ea6d7a086d5890cec428d72964d976be56c2efbd9d0f4ba933aa7d75ccbde4975148cab7ffeb26c728e05eea365c5e0062c1ad21224a193119f00cafb623a49c7cbc975ca753a9769777f06f19067eb833864d87424854a9a0468998655c54287e3b6774331483a06a01b6910013e90c00bfab36a47948bdfadaf35dac1c4808fbacb038759223586cf8d04a6db9d2e14d308cb0d1bf086d1ffb21e0fc5fad9e0c6dcbef2b6d99632a48847ecbab392991f1008d34812fadaa32c3b97cab39d532fb2c1bc4961265c9a629fccd776b666f60e351884ede5defd1ad3da06d286fa24f81450b7a43929691337ade5ba013fd7f00f7c6dca5b3499002a4958feb029c73b05ddf68da245cbc3ae0ed2b7cdf88b0b5e7219f8d89bf68becb0e95b93fa53bbcf08c4e5cce26e18a137a736b830b69f07d619cc923cf019bb6a4a7230a8d2655c39a2da755c790c8b3ee15299a8c906203b3f8cf332841e0e38bf0721b1ab0c3d9bb2358134332cae15696ec85e5aeb3641e09145cd8aece114c29877a50c5685ad3e78f0cfb717b732a6fe6000606a80fdb9a53608d18bbb3c3440778857e2f525e41f0180cb374abfb1a448fc1e88c6b9681f9e5d7a0a3930bc2d554b91951a24049863a457aefa33d2c1e425c13f6279bdb5c648fb0cad2622e19ffd95f48a862046d13ff21c552c1fecce76cf3086dac88dd972b4e57e3da1fbeca9520458377da6b0e0f4e2d0d09f1648be90042122ef595a00d78cb1d5820c7f67585724ebfc7d1614f863039845237a89a80612fefe3c9202e5d165ccea9b913230cf1a0400ab2971b7c2f6e3c2fd719e498946958d663bc45c7f8f8e5b1be3235b113e1ccdfbad09d828e30d8319a3c96c12ca6d9c3a3e29760005beaf982614c66feecc3c97c5458e7adcb0f0ab272863d4d1661ea54482869f8266dd1d061cc1c3dfd4475c9e123a20ae3dbc9355e625aeca7342179a47bd2159597260e7bc54460b7075543e7d53096894237e838db1b361a8019a2d8aee15363e52bd9292212c502a1c2acde28bef5b275d7b83949174ad7652b07c4fc6874b1d2badc22077b5837974f2f38302517222efb5d8ebc60e7d87a785a109523db5e5e54332cc3e297176fded07fcc5b0cf77d758a636bfef49a9fe3d0b9cc825c2ab9e342caa5caa59b5e0ed0faae57a32e015cde5aaa5b6c2d865ab45c0c2ea75dc6ba5c7999d554ea2aeb802179092f46ddc1bc6a2f867e813d49592d5aecc73fd818b128be40ab3e830aca11947c285694982ee55400d06fafa168a2245192244a7e47956707de296f158d53d654c6a68ca1c2228acb1f320b0948583fd486168c06263cde459250b98ba00fae9d47036f3264e4a9cf92f742118f03798685b4a91384c331fcc468ae60f531bd46b78c76240f335cc88dc6c55585105d257522653e6a65d22eb96e5519b786d4cf6812341b28d57c6ea96ca461f684a4abd81e9bb7ff4a11697f818a275cf8e2a9519bec0a11ec0e0f494f20c9785e793279f49447b0c4c98cead1f3e98fc70786e7f5786c7daabcd18ec1c26e1b539e0311633dd218da88bec9972e4e194e189c058e349cc138e7e3a4902519ebe13831380670dc70b271a816c7c2521067dfc009c2c1163865d96ca5bd20ce4c3c341f399a04f5f919d08f553dc0477576a634d2d36695639d1aac7799aa5399dc4539f46506918ea9395186dd82580896d115d1824da7a9c1b83cf0aafac7cdd3364af192710ed6eb0020ec40c984ced61759cfdb4cac75c4a7efc202c0566882c18c87b024d1137c3f11b020a551242293550a9eb942ece1cd2e12c3bb26efc9e6b2018b44cf397c78d266d4312a4c11d5713f782ff3da117577ead0f75c8e222c86fa621a26a038a6bf84b37a491fe8e9c2937142ba4a98a5a8660f267356725d7ec346db4baac47dafbac8cd44b53d42c00433a381920d745826bdcd8d5a4feba8e9c0549aa90f3de0b3ed32efe811369531ec085a07a4d15345b09752ec550a58b4c32d3b124649a9965d1b7a6b5507a57ac3199c0519693749c2f570971ad3349d4eb83b876e225b00e3f1e1aa8192f3eb1f5c5a4e9abb748b2593068f0e7ccd3ccbdc3d95ec55d3288c3ef5f52172a6ceed277c76405d551c8fc8c6adbe346f34ca0e734d36c50949edad15c9d8eff9ed4751b22f51314d95e4771a0dd176b5db9f2e4d07150136e5c12122a7ad8dee8f799d58611190c4f03e24dc2086f9457d8763cb9d1ff4a09ec27f8041d6ffcbb4b92228d267df17c0f8cff540f85540ff513fa0be3abf8d1e607fd5057009cda503a1022eb2b0f993626ca23ec1468908df37fa970678a53eea64ccf07f2274166c106d8da1102e4983a5118c82a676dd65a0a8869097d41a20f833ebba30fc476c5e280307d1e0e3811056c15196c44c95fb4cd8969a6836bed8c5499ef672400f07c03775e4432d5bbcc58c25e3cc2d7f9153c333d142bec9337ce46e1f7b0839a1f0c1505961600886a25423fa74ae7ba9554cba346889dd968fefe226767b720250ca4266a9f1b3fa23952c87d9310c935dcb9cf6fa3943d2513ae99404fcbf1474f4d1dfeb11689f54be4a7ea4ea874ef567c1543f030786547f3fd14b8ba0711045267e2dcf32322f6640e4a149e70e9dde57b9a6bccc882b44b58f661469b42942c77d10b283ee91ef116d2c60cb3048a3c970c5ddd30243ce0889c1c7e8cd1933a50f819486581253109e211c0878f13f47a03be2b913e4ad48d560ec384e70f58e842df914f2e458edf279d56201a3e80e08b11d8dd96b34f8083c057217c18185658be252a4128eeda5688931e9800a54822f61b893b1f1a9695883578cd06f41f67aa09b2bf7b70e356393a01740b6cee49a8c7d120f6ec6b13c7980564f9b9dd5bf560204e20c451a6719c12043947c6736cecb4207f97414f57e550d1fd3081c641ec9238ab12b38c7e0b5930ef7488066edccb80b0a34d0a1e069b3eaaa20b291183bab2d0c5b2df3fe42dc10fe41796d9c09d76901d0d0b8ee180dab2c976254f7f4f8384321b30904d309a273d8dd30fc9f2a104d4fbe2252a5e63cbe19b3a0566012826130c23332b0a46841868fa8a30584c31d7e9622474f270e4397eb8ed1730cf5956a39704bc857efa0adea004ca4a61b0189a0ce7023dfb5b4342ddfa1909762ab50647163d2feb3e46b8b6f40809f46c69c1e4b7085c3f88031486d0b0883af867ec28c0d7528b103d46845e8f61c8f339ab4c10e0108de13c963a5c23ea437fe6374c79e8f892b731a0b823ca5e228042aa4654b7561cadffd05cad75c8c1e3a47c9191ccda1bebf57c4460a901e4abc7f04cf8f063417d5f4282d78c592fcb703f79a7358942fbf044a060db8c3b8c97064c2a83e8ffcc341454c4b6b7ac1599041fccccce55391d106d5362edb827d59807f8d7129ec66e65ef737080939a1e1cade191e1b50ab52fb2c447a1196612ac6ae88228308afc5160bf8a89ad6315f4dd8fd59517cbc218a7dd43048c3928980baeace52bb640e12ef298b82be899c19d9595221cda3605484ff878f42ae9c2a08297f803a845dd021f59b69d105fcf7d111c28cd8cfce3809246d6b9a057a5f15d900274b7b8658d44c6879754ac1768c1efae5983ae15360ba1131838c04faa94e508a2c11be8e9dae00f31521d6fa527febe697b466d672a6319386f886572d82c9297b53b43541c84d706f5e8066bd2b1d41b55c7aea7f21c958cb962e33e51f647d99ac6ce546198493809d8870f679bba861d0bd97eb4f36ee0749aa16ec8b3d745593ed726943fb54ec30267ae800891adec1030f8773422b95b01de11f5b3e73d88ccb85d5feb6c55fb8a07615f0b0dcb40493d371759ada13dfc82b9ca7ba4d9fc5357947284f6f924cae2a79721c931f2f541bb35b9a815d78ea36415133df848cd91d05075d5ee62581e7c03672a0aac2b59e3c133a86ad0cff228bcc0f9c8136453ab664510dd997c0a470bbf9c6cbf491c56cf88e5189f822def017eea9be0cc3a3916f6b7cb816401cc816b653e0df386c18df9ef37e28ee06abe1bd8863ab076a09c543a6ede238818f42c77759d8a049a615ef27d35461b3aa1c42681a01d43094d1272a47fadee80236ef1918b2f9f3b8bb8bd6db90c68b2a473cb24731b08c12ba8c4b9724dd0f415889027b3426809227d61028f56535dc120897ef012a88ccbc27370f1cf650b3ca83ae400c24cc5bed79fc8920953f158ace21550ed4b51c29af27738c62187a549b130c6624a982e4bc145c332eca0f7537225356df9c887b414ab4128bcf008ef61b40296616824ea26bffbe882ce827768d3d048f19448922baf55417d1ef5e8a2ff50b55be622836e0d7f8cd73f724f8e3599d5621b2214753e3be2eadc0e7fb5e0ef3975058bc974d2b755673397ae77311a97a36630442f79d9ad06719728702d283baec4552bf86512ab938246cb2c696f4fe4423cae8d7f9f891097bfc98a13df7f01c4fab9d219afd132af230eb3b2bbd3df879e684b554a65e29d7de964935a126830800be20737dc94c8f216cd401304990ea265a46ef42a39dc4cc424a23c8c9b7e686685331e366befaa60d66016e81bff409abc74c52a656651c81ba0100cbb3e58695babb6d971368e99953b97be6795f4e65bddd5732e1c10a17df62d9d4e94267e6da8b26b6c25f97eef3c73e1d84ca2471d7b2f0fb2673083a756eb79af0ca0765b58927efe711c5b8a4eb9977946d294d055c72dfab13952b82a6e434b37ba1c267936023accee3396c2529eeda78371e0a08aa18133eea23cccf0c426594a82c046098721e8da3668d5f3697858c73dd62c27d11650f6d3a8f4f57814441aa82595775e30b0282b5b306a9f5afcec8205d564cf40ce52aafe28ce4a9938d370145fda2d44faaf14c84e03750886919ca0949fda78262e4075e1e0cd6f604921730ae538bd7ef14132720e4541be4b421a67e07e7e6723cf5f382f864f48f064d5049df526959fad8b91c8886069165f6388186e2387d206f8a6b65a93fee51c4a88d2da8226f09092564f793b564e42ae0b10c4a3510e05fb5885909ff6b97accf5ca7fa4784957f3c78f534ee44b26ea762d2b133d826ca2a637c93869b972aa4d5c46304985fbe9f5e9969a2aa71ff64c6b8c0b840c22fe294bd5ef4ab991d7828df42086cbea04be6f09852e34a8adb77e781801cdd41b29995719707e078139f19ac86326f04ac7688f951393dc2ac913994e164920905d8a30250faacc25357c7d91e57caf451f7426cc8b678cc134b7b23908b0f96d2ce6f1b522998060f9330a5ccdde67996b30e95d3250b3ca2020d0a409d5915509cabeac64470d02ec9db21549538e0d779d230157e1ffd7a941d0a079607789534c443b9e1237c89a8e2d300a3c08df995e2022196765b4898350b08e23052f9cb196a0bb0c67506bd338fb8d39a640438db5909f1636d6755c6dd4d250b450290874ab194780266f69d3dc0a949dfa33f3ce933fd6eddc13d49d1100dd880a07456421681412f3a9aea74b350200e745792ceb173670b823b01a344f0474de0105b1cbcaea10942ded972be5c964a59b8e035c26702d3326003e2be4f6cbcc4a83028f62e15be21c80177c4cf38e460521e2a3770437d8a5cf7e4e560ed8919c0579721b77fadd6a3ad703a088e7ce4b26711b5abbcedf83480bb97b3be11d7d2c19608af57367d4fc9be5049ea44556d524b97fba79648c927ce375edf4c2cee6330902a65c3bfb79cc9be0e0a11da203d0cef6d37bcd18be7cc0ab0a348324e6d3f3667fc59a28e635a5cccdb2e3b96eed8d13b52f2640d5f6b73f6013c9b0594d7fd4a17938894ea22696a39b9a4816f5d59875c968f1da65e13a05e421e53289bb8a7847c6bd7d16d209dbae4ae4f9d029a716ad5c77e6dfad07840110cde2bec99dcca209b886d4a879f5af7b15702b4f44f252a3502439bb0f680b08ad3de779d183228c4aa47279412116f09ba4b6ddc11ddd5e05170d7a102b81ed07b81ae6190214cbb06adf91f57d485aac22e57e842d4afc3b94a90e720910df863ee311964a4425d02cea8be5c7145bfd6e2ba4b892a8444fa4910b5afee11479aff6bdba44cb4b5d437c50e7f647414f88cb283e44fb6c2f07352d6bf02cb62b01a3e5121e8a8bcf6351956d96091dfa0193b4d39de98a742ae4c023732224714a9ab84fa2345096b1e31b819825b6f8aeab476a850e4fabfdf17933ab8e559bc8e51e5cd45a9a760fe83c58667fdb684e40134fadbc6c64cbeee2ca939a12df45576fd138dda6b942833e02421c32fed37c1df3e7a79a58dad6af93ab486324baf0b2b2d4a15c3fc41c9e0bf1da7c9fab0c84de3305fbb0e16f4d60f42146343aa042baccee71f576636458d2e2e6768330f1c6489467ec4fb8daef4cda59d742ef116d724bcd4411b2d6c66cfe0bafe4a2ce92bf4e634aa19c69622da797cabf1ac484d6e11aaa443288da49cb1a42da234de86346a473e42c56bdef1eb209f35907682473620f82d3aca40f0c8a42e3ca5f083d04713914cf0d8d2129fe76414f88128612f23d0ff7483b033b3409d84bda585b9ce9f6ccf1d4708b2831af2e7479db28933de45e8d6f99a0bb0891ce97a0872498ddaa9f298a53b38d8e06d4a3394e8f56a1dfe99271f5dfaee646d73dd87af0ed4b8a026a3ed24f89f82007ca4a8939fb016814087865893a746c50101858296bdb163366bfc4bab1f9dffc62502a569fd3aa98c199279f5226a6a51229956fb9a4c5c0a838646435defd516ed22d4da9d892ff022230488bca0ddd87210b35cc3b09cf8f235eaf62d9dac210b052afd42a50270439f45232cff76ef35c32cd141035903d0023e1f6cb4b6c0382acda16a7dd2e7851113e5d3aae6d2c63dd5584f4b365e4bcee6b98b5d54ab9c5f771bb50889a10091d06f71cbc780b7ec42552db79251539bc241da419b413ccde35a1b702707c620e4071206653c5aa4f30880e7c75f6219bd8b3ce281989dfe942a0bb165a758a585521a22256f1fe3ac0a3a9ed0a7a3073f30f53b470ff6e006c6ae47b552fc6dc0b91c367fe15e3364075fec632e5e063944efeb21ee6c9d0352b71a8736fe9c93f3e322ee92cad65dec6cfe721c48dc74e92f14d990111c146951b1abcd7c3e50822eeb41d79a17a35ded495be518cba0b08d577457230c69a97132314a9f75e5c6bfdbc057b58cca4083efc28cf1bc439f60feba8d65cbd06083ab200c031b76759bbd6c1ce7dc5fe2544f1821d004bf5ac6eb72cf63280bc7273b5420b2ace606fca1ae5fe272a98cd604080f6b39ece5f9625726cc97c32e11efd9653f05bedc44fbfabf687825e3de3f70701e4a65bc963cd0818c5fbca32975b44df5ab5324930a0ab71f06f07b3059d79c0c02297345ed48515ae07b4d4232bca937fcd4a15065ca8ebb77e224f7cc360d1c87fb2d9da923a582cc880ce2fc66840493412c7001ef848a84130011482cc30094ba6d3bcad50f19179258a9c3898da66acb41ac36aa8758732f21136325ae431986faa839f0c8e6b971ff3dbfcb73133c5b0276619f3f753db3c9c049b5e95212647efbbcf9f6f3d0373f639cf12293bfd5d28a2ea7809bd54a9e8c8abd454fdfb7e7b6003616cb6961c2addf9b73b417e89636da4766bbb9d58a92f92e899b7a4615a78270ed664a5cda38344c25c87a010459c2ec2d61ab2d5497f9440c3ab7308d3b3085e2c76298d066d96096dce4168ddbd47280209d588906caa14f5c4433f2679ed8a6c9ae649249e80d5d522b19a0159339b288a962bcd1c7235bcc58a01e1b40740a7b4f8e4fc61a3ab10751d9504894620cdda5379d81cdbf12f02d05062b03fd93b932fca9f4d61db84598277b39bf97d39e28a6cc75848366b03d9350b2accd2bdc5259cb5c146564ebd027191a490da3223bf10e966c769ebf65c490d1094646d1b2f5dea1cba0491c99a9ced59af1974d55860c8be8971d8ee439b117327bea221364e7ccc4f9961523459f801619e06a3d9eb65646467f6977ccc59d64453f90194ed3ab8b5f884bac94a26764e202d8671c819344c0beb92119fb2a00612cda638105febcf2f43eb518a496b3945aa26169fd498c6b6e89557a0b42ed2d9ac2b90b655bcaba350e8995c84178eb2e9ecc5f11d15a87961635225a82906f290ebeb5ea9bbd0306b7b530f416b6d85b9aa57f5af94a3a42cbd21678584c2e8cc6c3f7f256cc55bf75604de8cce4694dc3ac0b73f95c88f3696951cad6fbb9751dc7d4ae2f315ec6caabda6339716b5cb9b4e12373a995530b4508b8fcb2864bf961dec13d5bfb5ded9a5d7bd74c60dffa1af6cc3ac14e1b46e0fa4a472e27b808aa072942cb4094b8bec3613929530cc6b63bad6964475de435e5e647824f38bd208a03880d3a954f3aa6e859cb9deac45972c92f0f7baed77e47593ba5d394e8fa9895c3b4562a56452b1594b1323a5df78a79301df9fa7af6f643faf6bab59ea3507e12f7ea4cfcb11ff12f898a70c9f98d25ee4d342e67d8658ecd547e607f30927b5dbd16252964d72371475352d06fd538c90421dceb0890e22f7f460dcb10668acc36e02aa0a6419128568b8497a47b191a5b768ca286124eaa0619cb4848ad4ce84b2aa86f89a2ecd0fc6be26ce6438a3689458a538df5ce22f956f4293eb78807d6785c3dda132fc03b46b28079cf4b511eb8402a84209ba32cfec9a8ccd3e98c235e57a5cb91c3ea7541640d6172e50b243792fba7d3c240546319b7d4650eaf2207d71d170824c10a01a521b72ab1cd85ad845bf6181d9b803a9b9cc8f4e78610aca12dc68102379bebf90c933c2a5c9bee4df85b764509ade03970ddf0a25faf9a9f37be84eb8f6da83f1425b555678aa6f6f405b5afc10064c2a6e221d04880ef30e97a26f8819acf7681a03e368009ef97775503959bf8e8bffa69ff416b0179f0623af6fe15a404d879c07f16febfbcc989951d0c2ee07908155831a5a971d9dc65e80502bc68b0d44a1694f570880596f295fcdf12341c20e9a5d7abecddea0ad2256a2a0a9792664a5f2f2508ed39170d74ae6a1a3997e8e271e6ab93f5e1752ecfee7680294e3076adb57898dc41e41cb0b4edb2bd46392ebeb694763781c134ff624a7468eccebc12e16920a7440fb9dc0c6801ac4c022a9fa7953870b46439000c30c000030c30c0000aab1a21b811b21004cb2493643c048c520ee424534a32a5d283c60566236defbde26242e36242e366816a09590959091c9568420afae45cfe9854f264c141894e476ff1a472fddf619e44a3ed129266de14a2c7382461591447241acf1ff4354ebffc277040a2d1d8d4a2ac8271585c400105c3c0f18856623c93fdd31029598ee85552669c9ce279521a8e463472648a5fa1da839828231af9cad68e6cfa44451c8be8621c19b9ad21cd02872290e092acd2a28e8827a2f1b821e8c99cbd9bb41c88a8f445fbc4d36f1617380e5188d08d1115ee4986307608a6648c1442a710770a9a63dc891222195cc73288d8fe0641ccead9d25bc213042aa9b37af0d4f81b5ac848008c2b7004c294749e609ae395d6868c2d00d1879857fb839c1d997b1238fed0aa26a53c89a032f77ece0d1c7ee8d22f2c68e9eb9cc7af3303471fba9cdb4c9ce914adbb74030e3e3439b4e53211731b70eca1d530f1525e9ff8bf68061c7a68947710224a64454e122670e4a18f7f9252054d4999c660718107608187f65224a56e0ba72185efd06f384939e998f2c585d902069af1db1c7668a49b86142dab52dc601e80a30ea8eb9bb68f8c76060d2d68388c1bfe213834e870fced4fd9b95113c8489773208acc9ba9bcc41639919c42ccc943c4bfb838c10d1822f8e7626570c8a1758b21a68ea03ac10ca312e08843db2f929338cb16b777cc00071cda2841926749d3aa919211e07843275b754646486ad0980102196ee8d763e88e19090866d0d0a25080a30d8d2a0df26364d7899204c1df9821830dbd9b1c9d3bc7e9d0096380630d5d52396a4879a51a7ac9222a85dc0b2ae4892602018e34743106ab68967a314243a35237291144b3893e1f460d1a67e8327696921c3d31d66eccf81934b830c1e30338ccd0e4d3a89943c84992d2d9a28b1965e8945cb6679c454f91c7587b1b350c17d6000e323439834eca67742a6037865e74d663566418ad20317432568a0f2da7c98481f6e838c2d09ec7114a7b88736ed6781b35cc04ce1edd0038c0d05a92177c2c68ee5ee60b6d88dd612ff4d1c5e7845eaf387e179a6c41827ba60c3963940b9d10123c25d511f444b7d0c860ba2f68bd145555390187165ad17e39beb5cbce2665a10f26b2177653881039161ae9bf253be7ac9ffd2b34d2cc6473c499909db1427f21c3fb63cf55e84dcc658cc54c852ec36b8e6ece513cb553e8573dd553fc989ca952e872cea02c4513854e27c50891647a9b9840a1ddd0a9ddb1b267f5ee09cdc43c219f5ba7c8d39cd07cf8b5ca48ba73fc4b139ad81994caa8694ab687096d3ed9fc1f82b8843ec72063d852324fc8120e25742a61e77485f992933a1b1c49682cfee74345d6a6c08184464542ce179f7829c61ecde01c701ca1099ea7345f4e8b18366a84ce52582815c225aa78388ad0488f601d43c7b35ba43888d06904d19798e121b4c18268e457b39c933884d09c48e2ee23930ea5bb089c86163060c011842e520ef98f70d2fbfa0107101a656131377682ca5a25e801c70fde0d258498891cf21070f8a09170dac386c58be3a51e34faf1257a924131d6ac04346ad4a061001b000804070f7a7d0fba123e63acee3b4065cb12d43449077de690d173f5cc77f6e4a00b918338f9f231635770d0c76b99121db49690b9415ba54d5f78502231486cd087aec89dc28935683362e413ab508faf62ac914004450fc14183e66334c9124d8510cda0d11284d24153535432c9a02deba89224664ba67b0cda5c8dba123c6970d5c0a0d1682673ac631049885fd0b578d008325e447beb823e94104a87f310f49aae05fd7c4a22f2a6a9942515638d042220960107e405200f1c2c683d27c95d1f51d2c3b48ac645784715ed456d1121553c119f49456b3abca8cecfa868a466eab78cef295addb61049589bd83c4dd1c61429968c6f293f24a5683efe777cd14a8b2a29da14117367b07014cde984a4954ce396eeac10459f64675c6a0bd3f75128da9c115227271d654f0714ad7a0cb91a3a28f58cf94467ed1bd593ee8936ec5a50dda0aa132d9d68c545a487923a49c518279aa49592f0d52432f3bf894665b81c4d341f9f66f9a654e89689f692a524c27f905a1563a215d9d1f92ade251a153f436fd25aa20d4a6b8720b92c620702f430f2685851895ec52a4c96ac94a39228d1fb5e6fbc8aa051339d44af71a6cf2a79a9fc1149f49f72d896d3cb23738c44fb494ac8f9b207894e5b10c9628cef1fe3f6882e848aedfe3d39a2cf293fbe062531660835a2b94c4224a1954afac519d128956343f474c630ea22dae8793e7bd65311a46c22767df444b4192f0595f923d6621dc2744b87e8327fce962a84d3967943f46551530c52544a15a342b4496c6e2d69794b258810ad4cec389d527c109dce882f419b9644d705d167670fb324ff96924e20da6c1ded275aade73f8068c634bb99f7085d21e60f7de99ccbca338e069ffdd02495734bb5c67d68938cfc30192fe7a7143e347ab2dd920c770f8de5bc2a9aea6e92523db4d55d12d6f7cc431b747347101153b23d3cf4a3e3de715d4cc77f87fe7d377a4a9d891a353bf411359b289134430608509721c18a3a7441c6cfa5bf4295dc5f2d594187e6720ef9f9934fe450c558834103150f5831874675bcf49f9d4b5dd36b01430bf3376ca461710105dc30c1df9841e30006e07b2be4d084fd7c399ba61c5bac41e3060cf437fc53328f68cc80610219c91002269091300340032be280b5e54c97ed508995bd4a92c8ee41fd432c25a002589cc10a38b449fecebb9ec9ffa0b1e20d7dd632f1212b276cf4dcd077524973de50dbd0459324c28636726b254d158b0b28e002af85086a3c04c81abace485a36bbf5c7902a56a8a1cf19f45b6a3c13327e3540400ad0c5081e01fe19b0fb2e46f008863f09780256a4a10fd3669a7d84fe1f049c012bd0d065e52f71fa4747eb7f865ef7934f503126cb7183012bccd0c8f0f5f9df0f05ac2843a32b68d9785da9838c8d18356080c01c340854000210a8abb1c516d8012bc8d09b882bb233cb25ed91186bbee50c03e84d2023015964b1012c0e8005040e8085050af09f00f4371e0435cc05aa13568ca14f7db9e5a3c7c5c7e7095688a189f39573e7896941e75684a189339a7412228ab1b6451733b6d882cd8616326e74916d0518dab930a95246fb857eb485b9587d9e2daab2c20beda99c09fa45b39aa614208b2cd0ace84213ddc4f47985095670a159b11073f5bfddf734012558b1857eb3c6b87afc24b2838f60901ae667c878c0db905182f7973181b427418d2e3c91155ae8921e33f9b1421615f21b589185de32b4a5b2d2cf11190bfd289debe6a23a97dd2bb4962b5cb4202c0691294133b0c20a6dbb898d395c468dc154854e695fcc1c926b0515da3de93d72723d5a9931368894d9eba37b72d2698c35849ec60d1830166dac8716fa5895af9b92e84515b3d0e9fdca13f984852e556ae73d612169115da13db1b14779b63cfb934282327858a1d7cda82124097f5a94f6021e5568dbb3f3446fa98753522c2ea000a5e1418526cb494f62dffa1ba6068c9d429fd43a8685d2661d742974215ed433ad643ac3ab1e51e8c296570822a87b078d081e50e884f0d36c3f5526e6c4fa038f2734f26e6dbe659e43aac5071e4ee8c44bc53525d1167ae4d184364faa929f52c683099de8ae0ee92997e4ef96d028a5928811424e097de81826692f21469b26058f24a4f457c6102f4f48682f630e1557953a22f3048f2374414cce133a6123f42ea7f13f3a3e4e5863accd30af857b14a1f970f1f13294b48a3c11faf21494d27d5af26132844ec424b3dcd5cb439584d09984cb709eca921e61101a19fef4b46b0a10da0d5ae112b7ff411772d2a4c26a9097f0c12f78f8a08fa765c372f4760c1e3de853c7e49a7bd64a57481f3c78d0289d62e7cc27c566320f1e3be8b3c6a786d9dca2831b630dc60c1a660548826a1e3a68becb924f5096eb82470e3a9d47c798ddac972e7761c37c8d3078e0a039d914af3b990aaa278f1b74b1c4e81864e3eab5ea61833ee69ce3915554323979d4a00b22ecb6e4ece1848e7bd0a0fd20d973b57708f9931e3368c492e88919463367e92183e6b3fc86882a412778c4a009dfa52ce409315906069d381d637c92bbf94b2f683d792679b8a08f964c82ba682d7d8f470b7ab310b3a4101f45a4d683057dba04ed4dd19672a7aca273cb2f6571365a925f053a54d147cca295d1628555988abecacf7f53306cc840452fe2f1b37cd06f162da768e4c591d911ca6252a10e53b4f9334fa70c5974ec544729ba5cedc1b364592da5ec20c5219b34d11d96e941c7288e1034788a112ef1157488a28f1e22c3c94b964c06f1a023147d9410bcc57c730a8b81a2ef205a63f6ff87ac1dfc447bfa7297e5e6f8b60a7aa2cb9a72660bd7e9eb75a2b390b2964ae9612ef89ce8e29b5857e4ca3904994db41a2da998cc4a4d34729174dc2cda924e5d36a12313a86969cd969376a003139d086ae1e2c55277c5fc16326ef08c8e4bf4293762d2abe13cc89c7658a2cb95b031db9374f7ab4547251acba3df84d01f25da1c4bf3179142522c91cb49349e4b83b84471b5900c184a820e493413628e399294a8a3f48b443b594749b31832f2e490e8f7c57ab457a58ea27c44aff2514bdf62cc1b2a00c2d0e1885ee77b3f85ebaad0d188c6e25e5261043800230089e86044274f4d434cde22cefa9e348cecc8c7f0bc438722301115b6e2c65d043468c480a105927107878e4474d25c2f7fe978e1598cb1968868346913f9629578ea39c69a46a1e3109dc8b83039850788714386066c68a14501b0380016581c008b0360b1c5dfb0718226654f021937baf037c1a721bace22f3a7c629eb9c4d4347219af914b407919b446ffc868d270121daf6e49d2429f7b0231d44bb397f2b8ef6249f1935b643108dea9452b42a0b51e426c61a0c1aa84e061d8168dd3bf9c66ca96234d0a9a00310a7de98925fab28fda19d753d93914b5683410399a90d4e41871f3a33613168e8b10f6d87c9cf9a63397c8cf2a1132293568e17ca849bd7b187fe3ae560a997da0f3af4d0c41893284997d4d4958e3cb459e69b630a311ed4d7de924ea1e30eada9ee185e339ad2ddd50eadece4554b16ad3df275e8f552980e5d56ffb63ce723facc8e39b41e2d8a8c513a72685e43c45f25cd79c78a4327d1bd634ad598061d7068940825314653dc91cb073aded0c851a5c47969acce508c3537b4a9aa175af35ae94adbd0b58b550c9528133574b0a1cf19fd677472ca1b5b9ee0c6cb701a6b68adf22f8ecebca587d5d0a6d0ed73912f77ee943474a55f7310214e34f4a9f409d94acd199ad8167eb263383d9d64867ee4a71c64d439a9f1538636c4b0f0712b676c0ac9d09b3edd2b2e49452aa17b42c7189a943f89650c91634287183a193ca979765311b2290c5d588f909952a7c88e83a1bf681a22bec75ff8e417baf82673ca932f71c1f7422722bfdcf22775a149e19d47a4c8855654bb8296a43841e231168b0b28e0012ee386b9618121746ca1cd9892d8cc5d314ae8d04227c45a65091dfe52e78bd09185c654fe76c530aa314749103ab0d0785c70398bad1b93520142c7159ad30b527cf4260fc9a2830e2bb49645cec9dfb3602157855e46c9f90f11bd4b9b3aa8d0abc7cbae3927a75c66c72ee359362934a6a489dc96936c33dd123aa2d0bf9e46ad1ca63decce810e2834274c8e5c9c8c3cdf763ca10d7349986c1815c4a738a18d5b39654837d178cd0c13c361a48d8e26f4a371f4ae965e994eee0b3a98d0a50cd3d99916be42dbb1843e87a4c81d3aae828e6a91603c09481d3a94d05be59479a5827e5015f2858e2474aaa5aa2d45093ab7c60c0a1d48e8cc737c0c0de5eb39e8088d67ce8e5f29dca36b4450c36cf1358cd0eb64193d9ebaca424711da52ddef1e3f11ba7c22a8324d95732a4ede860d835de8184297657b23f68aca2cc252860e21749144cabd2ebaa3044f4710dab914647cb51408cd65edd3d1ea3132257fd04e1829639e233e68a355ec0d1139da3ef6a0136722b435887606ad83078d4e3e17155274935359a063074dea242227e5338c0eb1c340870e9a134b176de28e1c744147eff78ed172651263ad58070e3aa922e5830565a542528cb5b31acf85161f030608ee1ed071832e2cf2a5f027345ed63774d8a035614af9e924b64b8b6ad0ea466df30fa7693aa141a334b257d4ee2c1d3383f6df3fe3dc930a292c83def2c9f2f9242c870bc62029c2c46845d4500b1d3068535ee7c841c8f75513ade3054d4c9ac3e8d39e0968d4e0c205cd47fc97ef907e612f2748ffa7a3055c74b00019636adc30416371002c0e008363155d8a9ff5f85e21b58b54d1850f162e267fa79813182eb63881994016599cc0705152d128d794234a45082ada8a49f5cfb475f4e8778acc3a3e6328e59ba299e09fa524b7fcc54d29faf45242e50933293a9fbf7c6d6a2aa7d151b42b792be46a98583045d1aa9838cf2d85a2cf563abb4599d0e021a06825869645ca9dbd165c7471012c26f0002c94c0f189dd2aa92415661eba61056491c5095e0462e0f0441fa7d282ce3b2f42765de0e844734a9b98092329c7bc5f143838d1a7e86a3a893c6542e85cc8b8b18936a78fc8c93363e0d044a74db73b59aac0c051b8a89db7735a3ae3b990800d2e64dcb0020726ba70e22aa6099d06eac2c625daaa1617d5a54a6ce8dc4896e874a8eacba3b3c2e4b059c9d445a109de1174de310da331147a8f39e760f99127b421678f4b41e51f0d2a4e68f362b9846839420853131a117d3c84dc5b1abd6542efd1f285cb5af293e72ca1cfae962839688a7352421be35a8ea163925b21e2a28b1b7b45127aad18d961d62b90d06c6ab618ae42769ee5088d0e31dba329d772548dd0697f132fb92fc7b5b8086da6a472e14d25429b731c93972188cb6c1942a32a755cd0a74c44890aa1ed55b31824c4d0bf051050822b82d07f705f09410f84f67be385251da7c4647fd0bcacc8f124aa926a890fbabe92593288143572a4078da43efd29767ef03379d0786508b2c327615eda416f9974d4f2cbe9a04b49bc68674df2939f83e6ca25e50b51ada406bbc041977a2f868f15b1acbf41bb1d936b9ccc67b16283ce52d2961c4abce7500dda54218504b19c4b756890aae4d88d13f119b4b1b9fa344ccc11b22883366b4ef0ecf1c7a0dd885f325ae3258eee0a1834b92da64fdc0d534bb9e2058d283915cd4c77850b5a5f794b315808f5d05ed1823e53d42a17cb5dc18246c68fc998a4584ec155b4a3352f972ca9a24f5611635f2e13715452d16e771891256aa868e49555c98a9d53f44967cd905699293aa1bd335c58c512ad97a24bde23ae42e79159448a46c8aaa88e6553e22da3e8f36263538594204b51f4fba362b8d8149355151b7c84a20b95347ee62c07f340d1e7de10a2941cd78f538cb5117c7ea2c932fae26faa19b28ab16723780b940f4fb4225e3226af76a2edd60bc9c3cd186b053f38d1a758c695950e1b4f63c3c6bb17800b0301de445fe14d49700f4d214d7415c388edeb1c39aec9fdc84423b64c46bb6a4eb2472098f15a10fdc044eb3f736e32455a6eca8c12d0982182195d7c5c624fcfa05966296a894a98e08312bd78859015cb7e4ca217f5ee9ce09d64583a81077c4862c929525c3dd9caf944a288a9264765d31143e24e2a89a4539b6810298fb852929c294b85ab8e30c34bd61ca2d63fb246206736a5550ce61523bcaedc91492a7efe5ca9f1376410181f8bb80f45dc4722ee0311f77188fb30c47d14e23e08711f83b80f41dc4720ee0310f7f187fbf0c37df4e13ef8701f7bb80f3ddc471eee030ff77187fbb0c37dd4e13ee8701f73b80f39dc471cee030ef7f186fb70c37db4e13ed8701f6bb80f35dc471aee030df77186cba2041f66685be63fa624f331d6b630376cb0053eca6087cc157398a7a9c807199aec1f2108551173b8fc3106b466650d22c74a1e2747fe430cc879d0d6951e5cdec04718c8bf1d64f0d279e3474f031f60f8e4578cf2b3959b143ebe701f5eb88f2edc0717ee630bb7840f2df451c34e1825de4716cc9e99d8197f60a1bf1c94906a651d4fba1f57e8c5ac622cd3a1fbb0827f54a14df9b954fc8a61fdaf2d3ea8d0688b7e7dc9658c35cd220bbcc3c714dad29e73d031e5a5d09ef2500f9f8d421b474f0c722ab8c7f5a1d0893f0f4a460ca5c48c9ed09cc506255d2734325a991f596f42f3169bc7727e98d0885ae887c75ab5c74be863fd84882107b350294ae8b3bf85c9122b75bd4d426b255276ab8e897814098d329d9877e3e6dc348fd0b985d8782d22e7196284f6943caf08cd27992928ad989eb5fa2042bf22b44789592e7fd2f9e16308ed99588b39eb5032ce0f2134f1d4cb62444d4bb8cedaf01184be4b52aba76992604a448c00076008e00c1f4068c464122973c69ef614184df8f84113e592cc5a458b493133277cf8a0c9154fa49431d8835e644af95b6724264feee183075d3c93d76831674a922478f8d8411f42666ab37c2fddd4870e2c8b8f1cf479b488cb4a2afe2ae40e1f38e8d37a25e50e62e4fb738346c644fd245ae134646ef8b0411fe365d233dd416ba6b4e1a3067ddcec9d30b162347cd0a08f599272c51413010ec090f13183ae735e7ad23339c3870c1a2156112e3e62d0a9aef89035061184b720f880416bc282aeeca8a01f83e4101f2fe8245e261327161750400d00fce1c305ed66f62ea5e2aba63a2d68ff63492c53caaf2405a3bc16e72b70a0f86041a3bd4bc83719efd09b55b49d31853ff5a82adadc34edd0bf165e2706821a0570800db3803bb3aaf1316c187b84472afad425234b631eb3725d860d730e15fd6ac754d1d3539c8729ba0e538b7022c70c4bd1882a2132a8927912181b6818f02045db5956e53fc8b7dc1b8c9f21638bb582c728fabc243e650eddab5cea420b1a366094c069c0d0420b1922581345ef1a840779d9c558b3b1048f507426a2bf1fa213648ac4585363820728daf56bddd38c49f464c3c4e0028661c1e3139d0e1e3d844d3d0de1e189468f45d3dd9311b3165d834727da8e97ac99548a060f4eb4e174628519b19ddfd944bbdf23e3e7bca3a4f79ae84c4e25df38d5e09189d67304d1b9ac212b7c30d18886ad205153ca25ba9c4c2396e82d864a71326a9a73f7824725da10f334e6cd9bad735ea14463c12c665149164b2f57f098449b713575827996784d0c0f4934f13b97b8d41d5167f788445722774b9cc5f4b27c7ec003126df20d9e3f36e6a062326f1814c8d0c294f3784497332289e4ff150f47b4fd293d45e2ecd188368c4eaa535c1791cff460441bb2cf72484c3993f211862ea24fba255425f11fb6afcb387828a2913ddb9783ff9612d15528cfd42d250c32070f4474b2b3963e99d9b443f8106d7e1ecf187574274d6a8387213a9d703dc14256a70cf10d1e85e852ab96ab574ed3202644b31a31454648e2721a1d44fbf9d33a964a21e6948268accd45fba8b062d193048f40b4f172ec93632283525a247800a2173d39df5953c63ffd432734757258b6580b1e7ee8ff44c83041eb04d5c93e3429ef088f3039e466950fe8e7d021bf6fc7058f3db46faa5a4b08a9f922d743f31b3c5f2bc62c78e4a135ffca272b67b764663cf0d0c970c1e4a83037e071873645538cd6f9ab91b33478d8a1f318c6f2b2eccf65609ca0cea30efd7b52ee22c22fb227508b81071d3acd122e625baf794ff60c1e73e874c6bcd27a26cba1112694dc0bfa3544ecc4a1d7244b4732f90c1d11c0030e9d7ba67685860897fc3734fa738af5f5fc9e8f71431b4c997eebd8b4a1cfe4be33f3153359c386b6c4f8248b96a39f45d7d0c885d8c8eb49659ca81afad829263557d3d0898c7ef2aaf3440f130d9daa201a46b7e40c1e6668bdbd4c534ec28312923234da2ce90d29e4e01f2183e5b17f6a96ba31f467a92b7f0a323134e6175f238919cf95f208436fbafa829216d7830718da141d553b973c2572ebf185de524609334de2b1f284050f1bf7ff348f2e34d922c738a7123b44c6830bbd27139d6554df7bb2850e58b0a06b0ba7db7592f4cee62ada5142bd3fc6fc99b02aba503a5b262525a9683e6a668c264245232687508fa64fa589a7e8c7c375b40edd98f3a6e8e256851e4b292c91a273f6ad8e149df8044b263f368ade228a9e8eb124f3a2ff1a346ed8b80070e18528c8e133e50999473450aae045283a656e41544aef0c1573a0682624311a624c86c98f0434608060868cc287179fe84c5ea7a07c339aaad213ade8e0fea792531297ea44179e936e4ffc1045cfbb87179c6844969f8f29a7a6f092179b68c474e42da04b78a1892e430ef39e696161549968b68299b675b0147c9479788189de24965b3cf1fc20df4b34f2cd52caa0377e2a19c1c30b4b34a2e38a0eadee5129568946a610fff44c4c923bb2c30b4af41652f582efe6eaf062128dc9a434e4de143a278d245a33f92d124d48326685522acbc3874497412d7e45490b9f9847743aa88a93b2481cd1c7043dbf419ae8f0a211ad0709594ccfc9458f19d185092252de2b2d9eea227ad571cba656baa46e780e2f14d1b787e4a9734f0a32c513d1a6c6ace4a02f882843fef110edfaef95885c2968f80cd128cf8ef2d9a27ac89a22871785e883689efdd3ffe77d21446b1a8472d3b9e4e9e7717831882e85b4a8be162b59a80cd827bc104497298b46cea5fdd4c381e8f3c9bc41c86f901c1f40347944c82571312fc6fed08e56cd661a7265220787177ee8e224cfea79cf73bcdbe2451f9a5f8917de6385561086d5bde043a7215f8fd29ba24d78b1871b2ff4d04539693a67075fe4a113c94c5e2a599d459e78e894d21264a70999afb73b14d4b243e42b931d7af1989e538a715355b40e9db766bd1c83f9861774e8fa54d2f9f26fad3bcfa19fb029f29c8e1047a5e4d0e596ed8f123ce48f571cda8e1613a225fda427028726551041e53391347bf48676b3e2659f0e1e2f4ac40d2fdcd0558a624967e4f833216d6894ca1651952fa2278d0d48e3c51a1a114df93c3db6c32c3574f95722a760691ada889353e9cf19ef41090ded6c6cee28992d3ce46d787186beb5aad54c28d15e98a1eb947abc53c98e0d2fcad0e6d6c831785f8e53990c9d32311d534f09770d1a435f22655a78363d152362684bb806553a05f119a32fc2d0848d22fca2e6c0d0752c2d5abe2735bcf8425bd9d92c92d6a4624c67340e5e78a1f79339c1b2c4a9fca62e7499e1f91d4e5710a343800b2e34eb723a29e1766ae1c516d8fdd44e16fe4bf783175a68945222714588d065e65916ba94d344aaa99ffe3c81617682788185beb4babb87ef67b56901581c000b051c0001072857e8c5f4a8d4abcc72252b3417735e113ae7203aa60aada9a6e8d4aaca9541546892697bd01c255246d114da0c22ee9ae7cd2d2129f4d9ca2526a535554d1e8526954aaa94f956148f43a1d132395589d84d113e4f6844081531730c4128df38a1532a8a9ece163c59c634a131b198632b9c52cac44ce84446082ffa71da92ca121a992da3938e1625345283c49d2841e55169129a91f90d493444421f256ac6182df3e208cd46c99a63d0f80b2237421fda5206a51b165d3459647145e8e322767569d341df4284fe3f99d4cf9a53b0aa1660835f0ca1ed8f3fe19f545a28a9103a15164967f1fefd3883d09865f86cd022101ad9d3783298dea41ef3e207ed58c58567ec1074a967e3850ffa682aa5a9ce98d3f0a2075d88f2a7c5adba24a5141e741123c89704a17496cceea0117aaa59935faafecf0c22bcd0419f24c868a19363237762ac95e0674cc072042f72d0a712a782be6af6cb9704e1050e9a6831334f4ab820d94520bcb841ea49cc660ea224bcb0411b735a8cd3105283d6625f461d0bd1a04bfa438366b8062f66d0cf66af9808c601b0b800125ec8a0724b357913f7bc884117f42de7cdfb23f75a187432948c5d8d15d33f9583172fe86298129e392b2639a446dbf0c10b17b4af17f4629e7e581f5bd09a28ed2a79f39c67be83172cd862f04f7e29b6abe853e51083b28ea9a2f718929b8a66e2c83c5a434b3b86a0a2d7532a7a8e213e45234e5e8ec77769519aa289a263e625a6d6a9548a4e46cb3e29f6a4e872fae4d310a551349732bf8fe92051f441455792ce88cbed0945df2ee2b3e2f787181750b41d9373c790df6210eb27baf8b3aba761f544172a08511d2984cc32e944ab21c4f0304fa2cf829ce8446b86902fbe894e84f829638eca72a226dad321598488e9868c195d6400055764a2f38ed91eb73b272813269ad46be2e46588534176893e567e082a714bb4964a5336ef55895573d23c2f0f314c09f73ca8d09337a47e127cc5371d3d8ac6a091443b6f1ec4547948b822127dcea455767488d26cb3c822d52041aa410264cbbc1a36b6085740a26df1de7c5793abaef0e08a4734333262b0181f255a7785239aa47be73cff46741dbf3fe9dcca231ac4885e52c9474fba63a45862ac694183c6511a5cb1882ec35a758aa01d4bc815d18c6491ffab62221abd6d16323488685288658ff177936ecf21ba8a79325ece72b2626388365d4efb256bc9dd0bd1e759d5f890e3e7728910fd68a5cf6abea8eaf120dadcf92b5490b120da8e8f2b297edd276803d149cf3f2a5f8e00a2df3e4da592c53f742975c6affc9f1f3ab3743d65ae33e7f93e34b219234f2ec929cfe34327744d6759937c39337be8f304bd9f57d183295a439687564353afe9666f034616593c2ac1157868535885dcb3a97468718b2beed08f2aff97fdc915a322e30a3b18576525659c822bead076c7d417ac64869e243a34d1ad93d4581637cb3e8756b3b724d929cd774d3974e2e486889f3bbc879038b4f135a3766ef10a38b4eb4155562e778cf7ae78439b734de5690ddf94d52bdcd08a8a6a9d3afbc957b4a193a031546e101bfa60163646be3bac4aec5cb186be2559b05c625383f1437c3f8f9a86360591bb6f794d7690a0a179d5f8b97aea325b3a43ff25ceda4b5e0ad19d193a134ae9c850a532b4e96241f74e86f6354e089a7268ef44c7d07b07718aa18d19cd4334193a8f8784a12ba1fe6a2a7bd8c1d06e47798d1df50b5d9ae9cd4dbe5fe1853692de8eabf0232585bbd05ff635139bfbaf94b8d0c989a95210e116da497e2d26628c20bed14263a2ba4277b99c1e4b167a8d3dcd11540c169a105d2f8f482e1f22ec812baed0b66c676afdadd024212965f870159ae82a32c6d7911397a3429b339ff0f98ea7d0eec9f8db65b262aa9242133537c4f6bc068cb9a874d1e561612c0e87c371180741088a8c0fc3130000000c1a15c7e2b078308c3369fb1400035132285034281822221a1e188c05a3a038100602434140300c068301c160602446743c8a871f071cee47b916901b6c442f1b767e7c4eef0639c903e47bf8f12e077263fa68da0f27e406775d71c091d91f37ff4ddae645f5e3466e53486121a49a1b303cbb2b0fce3446178ec1b96b8fdb5b09d43ad8b3c1918bf86c2093dc62f69d1ab1175a1ff7fb086c5c9eb6a4aca8d8d5356872a97bb582bdb008a5dced554494bdb4154d320fb4e8023107c8d1666efbef91c4ec69a0c51469496341775bf081f2e1034342e63ae991b2826b5498908a2d9e196215d63c3affad86d4818d957802c70095c89f3470a777d86fc58435aec0bbc041db0d39849349ec48c79d0690270251e68eaed547ce16b90ab22e65d84491e0909b177109f7bbd3f6152552905249ba9b047666536f1337eac42891fcb4630c42b8fd263283a066ee2d160fa481d75e2834d3b8e230b04b091d72a9f60ecb8c274431502b9f320175d202a2fe230afe14ae2228824e083f261a76171c004c827ab89b150dda0b377c03c2f10e20ee99459a03f150e52dff5b6c274527753f3f7d47957248e9447ca65deb56a76fcf09e90a55061892e5f523a5e69e1b1b850a3d5c648c86c9ea653ca62d9cd9f40e9b0dde4f9bbcc30921d67da5adde17092b75934abe033c976fbaf7672d53734c3f96444e54c0fbbe37ebd28d1d5d7d8134e6a60eb2b32dc613cf6119648b9faee935c1f29d5a1581c7c720b0c9cdd1aac897c4f4c630b03f687fc8d1932b9bb56e5903b7d7c095c223c1525241b2fd80718e0aa5dafbe55cd6717e14f8f2c29d43936720a8c7d7ce963c2c8449b9f9092b675980423602c64cee3003bfc3c93f9730f43345edd2492ec301fd0ee5437ef6ea88888bff74fde39557ed788e19cb7720dc6eb4236c4daf57fc97b7a06dc427fc4459961534ab0143bbac8862f3a6dc939d682de27c6ef4e5b33f595861ebea16a5522bf8f25ac51bafb3d8c1b1f4c5ac298d2990710f8f42490112148a5c6cc64de41d549c0236156c1fad8b0342612cb236e247b9dc838e9e9b1b537924a09ce6a56aefb444050eaffe51608c2e9c7a1d351e5594ff7686da548144585472bc09e28a3056a6d45f9ba22a5ebcdf89aa489a3841a0866401577c23d39003902b8a27803454bdcec69c0ee4e78196b0b07245410a51f30ac15d6efc0e1abb44397026d4743069a771459dccdb4e1552cc35c491b252d5c3fcc967e44087c1dc8f7b72c913262f355071add30efaf7215f53a0d8c68b4e560994dd2b4c3801e502ccf79a51fb711495c8043b3e7f465b0f7a5e1328a8c208923747b412a5055c616c4a6414179144492bb1083dc48982106f23d6cbc57ada2935d79ee17c0054d84f12542d08bda3ab16166e4830279985f54f0cc1a93030849241883be5b5bf4caedcbef6cd59966aed0e8aa6dd6776847c5d2e0ad14d62e3234803fd88f4b0e06d7e2926c12a9073362195c4f708ccc7ca12b7b924d48ae1f117c20d39a5c827a66bbc608d4985250adfc84c440470d81c849ae96ed07e716ac6450b31f8df39af206a4e71e9c27db381a608a78f05f11975fdae56158298e7b88e26c18c698294f8ad92f9986015f6dfe69d55d2e09ec90f2418f115460d289733c2ef7f39826aaa384bb0b4cff083816928189676f536b37172a1b0778cb3c990c2b36175b0f9b058581fb0b10a7784dea6026bc1651a430e12633f34d219401b1ef7716fff5c1864f3b6aad7428ff8edc001310aff13779af7a94f191cfdcd0042c9ababe8d2c55085e62130792654902262701c248778070b27324c65a995740d3b2d5089f55061e59297334100a6245c33ced22769c7f5b8b8888c5842d132fe19ac98b193f64a7f2260ec750ad8bcc992454d58b29d74c3c8ff09b21a9fb3ff5b5e6ef98de4ae5c56a5a5248e83e32344564434abb2254a9facbc884064b628e7729de8809a40fc3ca6678add62e9f090fba0240fd139e1d78c9878903e5433928eaed234fc294975258d762d6ba70ab1908433b90bf35412bd4c626af936c7c2d233209f9b951bbaf28cb70c49807276798a03cc58f773343b1f4071e5c4a8ce367ba695f02884c85c516dac4021597beb0c18d4e3c4902d488a9e76d5d92842104923552e50a0bb423cc078767651b7af77ea989393a67f2130dfd97e38f73f7506ce27d57677e3c4b688d5c8d37f3b7df48227871c81e278771fa4e120180d2980f1c127843e11fec1454bd26be345214fe35a71af51cd3ac7891655d569a41bfc590b6ae6617ffe1a99da18680923ec57e12f75e63b9285fc5d4672c032aada718cca4aee8c830a67a0e0f175a1c17bf689580ff9588a1c6709048380312e0842e0fed37bc0b846805562655327b76acefa2bbd383b4d7b0e72044882caf4806cea211c393fe4625fb42ce504e86035b3d258cf0f4b1a89b9618bb06d599f90755858fc3cf775d41c6fe164ca69f7466435e819171686d4cb1f66c2a736c0ea3e7172e783cd71de109bba952aacbe16e148b361e5974a86ee6e4258176be7183588f9ff4ccc6f5e9b1a989b8b8ffb189e203b9d4694b606c055eaa3e4ece2074a7c963cc77e0625a806c8af3092a15789821a79979d3fcf6b7ccd8e00f375c130790e1ab7bb5a829c385b82c71bef9b8b00a042633d38bddb56281f68a2a7dbd909313db7ae4a42fb11a8b0908a2bff089605e6bacc79722cc84a5fcc34e5e75a7ac963162456b6e2f9b1dc6b8ce8a5b942ef55faea5ebdab665b7a3fe92b944f9775864fbfe84951a79ca9189aa57f7e387f6e31084db2ff51f2cc030ebb9d2bf14db84292d3c9740b079b0d47de2c06ac52ee9309a3fda4c08635aa722a81c5ab630189167c71efc0e355a7146e6150ee629d9c0142be4c13f8f0090d4685f2cd1f6f87ef30e9ca4601ace9d5cd4500994d9f30604e2cfc29a532d8311319e3c4f820bc0689048bf797f7d8307611acbe8d9e08eaf133e321628fc57e9e6d9284ca1a1b1404d0a81d8c09178fe84c79c0d21ee297894a39ed71ff5ca22236bcd038239a36f51a9f0b0ff39c3532b820820dc212d57364553f429747bc2c332777f7d3dee5a8cc940ddcd77c50e666326bde837e80ce87a680e6cacc3503c355c52fc48759499803ab0bc2b52dbc2391dde2b7c4c306ec6f668e5b937ceeb29e2d2955b56413c8a34588c0ee32b70ce99a60570497bd275a0b74a491bc967d93b9e354886c360c4bb694b5a229fc89b2c2f684c5293de12f2fc355481d23d9dc584e664e1f20ddac651c5dce99e1383d70ca0ccaad3645d8a0e5c95051bfa0cfc70168daa78150e60bb659e8865ea852aeb31008d09ddc1c4672cc83de0ab15f7e4e306cd213b4088f0a1bb9cf83bed02bcec16fe7d08ca3955d3e8f1ce84990626e2732a9d0e6d6a0324f6aeaf16362b655c0690e939fca1ff9db9c18ad3d2564c26b5bd5c843c6227a25951d84ef1bb349731c5a542df2d05f4a7ee5011d93b4ad00cf4a8f7c44af2da89e183caf1a6d669e5007a92294bcc85794ce8d6ad98b66364629e4c25c2a896f3e8bccbc96ababf43a1c127572ac98ed826a63a54161b834bf1f7636465e993193d03c29678e668584ee3bb407ba06e1e49164bc51ed3fb4f1602b16d43b1249cfd78560a51364a7867741a04f86d308389ec3e70fc92abcbba1b7782f9d1a07aee5efde24ae6203d4840113eea090e8007aab94117d536e781adda30c2c8867800ed540ff7067aa8ca6bb3503cdcbe8f46cf78f5457ce267e75319011ce70ddef9953f366def49affc6e5acdc9a55b94b5e3c4de21ac71d903d834467fba526299a93d053430cb2abbff0a7a759d942b8256fa327f52c061fedd76d8b4a0b6944cd6de1239c96ba1421e0390296037cf1dafd4910102def3682210fe2f20950b8d774cdaad99a65fae1eaeb5a46a57c3d059b60c375f166b77ca53265c0eabaa6595116c8051b400deb7bed66d942659e81e54824eacfbad11a4b354c913063804608441d3b8ceeb53375035f7e29c83f0c735469c2bd21c8dc7374664084b7008ee85fa1ffc2f69c07a372e634a896eccdd06f7611e80bec33d053a103ede0e30fcf9d514cf9c02bd8063d4afb8cfc5837611dbb4593b1d44a0dfc689a20e34756ee8ad0ed2e24970990c90ea5b4fef4250b1a77974ffc3fce234dc0f2e899eebd0fc931a45390f940c639cc11710f1d1d31527b153aeef038883352d836f518330aaf6cb9f749e3ec084b87eacc430e37e6ce9b2d5942000ba41485d980683048d9f7fcb9362613a3514925823b6656f43b75f30fc7524af7a1e7745d837cd0ab5593dd31b17013bd8eb44239ef2e1b070f11b39d0ace00e93b2136cec66ef4407cf7cfbaed81ffeb37a8ed46854b0ef04fe69f5ff05a2e6fa2dca86636fd5edc1386179a2f0d83b2f8c64971afea9e6ee32b0166654a6f2ec4126121aa4da0a3d2870caa97ee5ff5547da89e6abddaa68e0c417faa26ab6668a37ba9b00c7bd769fe1bac78e8d98f8a30da19064d7547b7857ebfbae4b12bdefdefdce50ac85f40d2c201d4d65f86f7733a51f961ef7faa7fef0a232a9d661e24537147b6a1db5fce7fcb2e11dd6fd702337d01b155a2a62681261be20a0cb8487a18cc86d58a174c24cbd31b6456970bd2dbf932c07fc1a9d580a11e31c348774f523aa0c5914339724730f7add2fbc8bee88a800c4078fb6f85fc0e4855c99a6491fcb13dd082f4f0cde891460e9514ed8d00d45c780c2d83f4fb24c37e4e6b28e5a9fc1513441cc02c9718c32eac769e77f86d6eff9efc87e5a09c9d075526b1a490de7262be29fd5532e82d4a715130db0cffbeccdc5ef25f88705d4f36d1b81d2186a4f602267358f5467d899404faee01a2436cba0ea5b5200e137bea5d16fd6a056a0a75f1148b1c310ab014835344af441861a23b68001c1878786678996466761b6f4a1a24a03229723337b697742681c693bd8750848011735321439080645e4a0dadd02c7d58a4d4c42315400c149ba4718941bda07cc0f3b31a85520003de2d93e2c0d8ecfb4a24d819290738a3209e5f4ae471b030b9e1125989051d5249c1b8c179b1765e286e177868ba0e8e14a9525ae89f9f7c877b056d444d9bdb55cb450b50e3a2c1c09fed11fdd11f07c81937077c4333902c529898b3ec93d5136a30f7099a582a229eb5984c584d1b3657aa5da3597cc69d5f6801beb51578807ecddf7bb82abb4cba2ae742ae5689aceeaa1172965c81c13f21f5fd0ab7c4ad1c9a827d72e2e5ed29cffa768871eddfdbd995f835c5ab4311a56635c768a1f2b6d7595bd138a409d2cfa4362885998711f1230d78c45ec339578dbc99f8e3791f3f02a46f6157781954081f6f154992b775cb5e306891e0a580d07a500949a6d17e05abc886c498a693bd24220dfcd71d47e2aae65ba4d6dab19fbd26a48d42cb4989bb580c84e436446b1ac2093185a3d64ea59b98e9889a499b6ccd5a73553079ca36d2fd5e7ead74a753356165c1de07b7828dd64ed5d8c8b5a50177f8a46e8d9f5b96388c6116dde1c11d8b8f464b92893e4faa3aa2d30b0b79479758c1f6d410909b61c4db943cb37b06c94809dd4bee2c4c0b3f58100145572aace4bbebf29d9d784ee692adcddab02a8277701cec5b784a5029ff9fb9ccbcbb7000bdc73020bd16ad90ebbc0f73df2e359f1a35e7f55371b944baec8b4f260d15fe12a4907bfece9db9f2c20c9cec1f626aa56478c5e3a04c3a2da4850bca4758a254465f01b7a025bd3310981ce538dc535d4d8b65a2b683ce6fc0be909cf33eb599a1c3c243a9fbe24de262df15842588a3c70e05aa6171a32791e03240635e654395a51a82519047fbd921b0c954ba239a42751f2d586645576af35c1f1f81d4f71801e6cf14504fae01c97349521e52be37523596e09db19e4c895566c7d9b5cf1eb6e25c52a4ee44a42df0d7d182664da05b0b22d2207ddb0b06cf0f86e6812b2ccc7f1a031d749589887d6ee3d7dc19331bef157ad6a7ef68088243a3e79c6b2e12d2f290490b679fe7c5363cd58c94f3feeb39515d0d5c1e68001759d0714f3c52d084d061195386fd8730685633a000c0c6f3d6628d8d8b7bf17975960eea8f7b284ccd18e82443319f59cc0758db59008907cb23b562ba99a509034542f6aa9dd12de6f0f03785bc36cdd65e3c83b48c5bc91649ef1ac3188295df4e4a14e9f02ae046cc9384258c257ae4e46ee08a469cd70ac20b6a7d7c57708a41ead3b52835be7ae45e989ce0e1c7301b511bfe337180a4765c67fe19a32a624b1f4735a1ad6ed173d3665b6bc5e847930b49092f7a1f5751d67249dc5a0a5c6eac347b51399b750011b671b202a95614b00a08f308851cb551dad75ce69054061b25e2c8f489821f8fd64a43410443c8fe8af0efb8b448762655e660660a9eb1c171e8b36710bbf6e9cfd028b591b22714f0c4140290120e55e8db2bcc5360e581c25d1792852bb5ee9e3407e2bcbabac4e41202a7d639449eb07d70bb31f430c9f0b7550e1ae3d0230cb5815aa54fd86e4df4316ab1eda7357ff2472664f6ad28d046a7878124151ac5c750c8514d6c8e54450eaf25872b29cbb0917dbd71fdc6c70b15245de33113ad82f2ca9c8bd63b8863fd85694966332fbace8901abae817672a3728a133342df4d79507f457e731b014e34f5c5e5ea7a1527372a8956692f3e85a1d2ea30f14b22969b16cde60fb6772a4854d7c8da644f85c1e4a0b594ec78c074f06cd6425b5b389f9c7070f166105ae5d0755e67e136888788060697136b8c77a340cb94f71a8c31ddf1e22578ecd1b4baa0e460e48fc927f909158086395bc26bc0b8632e7e67685912d0860a3cb36f5c57655bba9e972d017e70b8c08a9fae904edf169890efce46250f08f8f1fda1a5bea875cd8a7419a1e08d4e6e098a488ec1cf67ab9366e5cd8f44d7c16eb872cd88a828dd0f32ff29514c56d9fc8d2e4dcdef625cc24dbf5f60fb8d408bb28a4989928c9bf8d8109b0ab5036f902c41de42bfb304dc219472116b05637d1e55bdc74d6077956170ea15a3857587b96981d4ccfed41963c1782239df90712533014231fe530b4a7f445d71373221da0bdf917e2b54b72a58025b5c95eb6124f01d8a88ee5e953b37c22909f290e8a0ac2e68450b2284cba2dbd018184c84a95429af6df0e9e8164d56a18da5e3c5472ab3ae930264b4d8d8147bc4ebf02dde82dd43c1bb49b0c6db2983cf9011a859c4f5eb2bce115c62f1fc80031e0d2e3a41db004be37a73014b288481bc81abb57de00ae3d0d894e39ed90ca61103a3d40248b2fc2c04089c86feb71c34634c9a1fb9feeaf80da562cac2d573ff67bd1a29d74df43f7cd40cd8d5c0c6fff904d4b749bbb85d5bfa4c4874ac4ac5e4a4220b7aee030c82253e5137a55c5ca8ec31d194b1fece46b3c2b61d96202d1a42aac60a66bdba5cb7d221b099ac7cbbb5d1a5d8ae6997a6e97431777a13753fe710810482baf8706c6f2a064016f275997b1abe6418533e218d76786e2e3273605652ff9ac4825a23b562ed2609340a847ab00fd7fe0682c69ffef059fb4a433fff469dee5b2c3da6c9c57c52a7534be9aebe39dfde4e0eae3b293c28649ffe4060a5f0685bee2745b61e99c383de35062da7a963f66f489111821b2b76482768bb0bd697d1c9aec16db9c41d886c7e10b0c1fd6afaef549fa287fa8202ac04127d77dc05e88307adfb1b745a8ccbb330b42501858fcc08be2ecc75f4be3df8b5ae7e833a12cb1bec8e91726332d9a406ce87d5b3f176c031857706e4db62768db81f13bc7017f95b825f5eb6b9bd0d2713297a80a3414999e7af5a1e2ca25c912d212084f6624a3d522ad169ccfaa66ec2e5e09635c40111f7abf54e639db33cb5017d73fdd88dce0cb0830ce14c42cc4245c1703bd55e17350c551a6dc9beb2a95ae8e862967a59036c7b77d4e94ed9dccc3ea549f4590eeebe42c27774a4cbc74a300e00c93f61f6e3be14eaffef2b304186e5d968a1c425c977702f3f402dd904e2c38ab1feac5b1889b27c49ee5bc07af81afe3e862cdbad00bd35d76035f4cc4582e1ef7b461ea13c0d3a35862ff36ae4e26ca8e1d36a83fe53ae59217e735f538ebdfad4f5cc773bea66f37580c906adde9377dde27f180060e093a3b247c20f2324e07ff34b4c5dfdcc887d28069cb040bb92c461afd509e246f325b9d998d440ffd9113f6b6bfed0abfeeb94c58549994dcf5f182d4613e9c94843f98b3b60d318ea3b5e029f4c8481a4529dc01741152fe5f3ab63c16620036441636bd8878d3a1e06700c85ebc75a205d98ca2c4b55622b9127d53c8089bc26d45acbe505cd7902d43c6a8e1534477548b4a2b24e2ddc17ca5144abb49c4f9dd783fe8c748d6a2060ddc5419f8dde0e5416f8994a120c39b82f762f86539f44142b405efb619ed020a84e4e4d44073a1c8555b00d012e7a8b07745b33bec16c7738158501f0a80a14119643de433036ff5841238c7a53f628267c7c62eed8c1821d89c42555352b8ec0159c9125bad3b86fc81a96e755933d2ebe201f586b7edfe014ca72e2eabddab12aca9de48a0d22603158b667ac2ebcc77c6ea027069e3edaa04da743e5048da501a056450d19c1e082e398416f21c91bb184bce99d149a70e127c68ac782de6630fb563c4eb0c6909a683d9525704244a690ac6c88a29cf6fc06b04576e7a980fcac3dac2e4ea24222416a49f06e2c97571cb8cadd1f384ccad60fcfb0f9d44748d9ce9ce8a23095adfb42f9b2f874f048632d1e68865b5269930d138f15cf13fb28273c52b7d58d197705251224a74618b93107eae95eb477a63c530c28f84ac098093b88cbd70b422a174c7e9d820abdbd13b4dd9c01108e22d51099969be4c065ea347b2340cf9976798c6adec79426ce7ec329d470a440cdc2c0157b96f81a58e9f1b631c151fc8e00abe439f47495d9a6070aab81542f86909549e495d37e01f037dd51a73cf1950b65c661ca329fa48104e2069800a645ad4fdb1c9de1a515e0ef2edb097893810dd85d2343b398bec78a119b042cc3726db3e8846dcec217f42d8440c599c0f6c0d0e85b5a31a6e3061bfdb710bff444ae03259ee612527244cf84523c7fb84fbabcb138e04a0508c2c66264c4ecf552a6361c87dc440fa4bd44fea5a8b30fcea0bdff62d2bb462163c94a88db6e928e3d8c333e32ebd36f652bae471a40fc26f4c7ec16ad09164e43df4a8b9f7e767198e640494fbc767c3a818c4637aad77c0b6a0a1187c0bbbb2e4608876203971a5c3bc536ae92d875bf74ba7ffcad4501a9dcff882ba903cefd1eceba256b5045823dfeabf46fbadbaaaa236440494bbbb118209d964df7e2016b826a821803492c0ae215be389c1f098916597fe15d6784c016c328d58906b8637b9ae9156869ed7fc5992ff5a1db63f15132d3755c2cbf871883bf0d3867d8f03e66764b785f9e43086c2121390673ba3f3f9508164a979a0fc2160c3abf317d5267721f4d9845eaf49d81ce29f3a591d8db9fa06cb8a19e4e2e534e103a7fb7a3203d12e33167a7f6c4b716f6e70dfdb3c8fc657349f92c416a7bd6f285756a0e91fd1bb3bf843fcacc055101bd9b2d5786ec84f8071a6dd653519a872fffa356e316967a94cd3e1412fbe9fc43023cb1f41b0b92ba42d9d7fd27667bcb36521161f35c855eb9468c1ea203a78d45d6f17e163a3f6930a8f3b2abb92d991ca45851c37518c32a84b6497e9d8948d97060bb2bd98d8e361f9eb8827cd43c3e81d207aa013c61b173b87caa4d8ef3f231a50f20d38195e31ab8b78de38151b4483a70e80f45a1a994f88c871203555fd9488dbb405602db3393408932be20094f84f65d9f44651d9fa8e008cb10fc3358169e12a6f3da22ad318d6ca477fa181be6d2a849a30ed43882b250e74372d4f38d92850d815e4bfb086aa643aaebeaf492ffb79055088df9c6bb9c85d5bed326632f34344defd5790d066e3ab1470117fd7ce313bc70abbb80b70143a35b81f4ed9b5c7201405959dac77449b2fe0621547408037069dce7341547b9a5e0b5db70f42b78f4db574407486ad470d4e2838bbba540c4040e6c7aae4fdddabc3956cede0ca8db3c886d4e48e2b856681b98b69edef67040d5dd21933b5935e59bc974d6d0359a1b7d30bf076602b35862a3d4417c44ec24b48d1156010e9a75cac77e73c77888563f31b0f1544e51856a0784b533d673558ed2f123a5f83cfc5ac412bbe832e90696d81d0b6e1394d4dd05fb611e44847fd951af6265d02a189b99f54410a275bdb5b008408dcfd54197760ce0071570539b6277d0db9591e99f2f215bf96e28145fb307c2e4151f44414085ad09e103b5aaf3a26d0c1d97d15ff44da25548f7801f00171189f68116c14caa0982ead57053fb69bd036efb8efd00ac298d0621a865d949a10c71be8cecb8a5e661d362c57f274d4b7456e9db9710b61f636c5fc3a6216c8cbe17b5710ea82f58a2ee6173d4b0b7b129d5583389b1ba6c5368ee25a22cdcdd062a0c23c75aada556c44fce4273f3fbd9b284b6e85ad9f7d17b35e0a9e681fd6ba53fb2010612fbe37fadf605d8bb27bc60d83030be4e58d70fc8be452e06a6f4f601b76b48d502b438b26376904a6058f5abb4113dab73e3f84c9f2ca2e2db0285375cb8e01ae25012e864c84b3e78dbac7e15da61d4488e4ca0df721ed406ce033b1e8245156a50820220b4f095212be626fb61d85afb153feecd0fddb1209b10a195830ef0cdbaffb73179446cc0087a5d5d008ef807fab3fb4b62ebbc2c259e211271803c834c943ddfb07e9d9630237b52c52ea7157d4e9157a030dea13a759f1394f247e5d460f0f002b36c1824144367243bcac6106a4294ef5c54b7b404ed821a1bc23d0f3649097e13f7aa595f8be10f1a0b0db0872c39dc02b9f4d9d3e755f9d0c3781f8bd2107d10979b064899b54f3098b4b64ba626807fd584b406f356af5d966d3ee846c72f69e1a7f883484f43a20245a353ec52a72b8b844cf2ba74956ad102891ad304948e6d51aca7dc6e624eea30f53fad9cfafe6c112d4177fa2c86e0157955198c28354be96abef237463960cf8fa8a5e7ccaefc93e641301ab3df0d01111bd487920413f4429ffebe65f97b1f28c25c9bc69038eb4731521c1c327ee227fc16b5ccb916cc237077f4efc242440b3aaeb2c616dca76c0fc9e486b0898177391d113a036153a76af1f0337fb26524aa3945c8eec31f846bcf95a01f28fb3ae9d244c54c432f0fd721426dec5be34b96f7ea5803a25527018396e1f71fe3d9e172d627249ae1a461d2c6de28e3ecfd1f72d0f22da7b3423c97054cf12646bef05a2459c1623682f0150591ec6278ea0d11c22e7aac2f2c77fc1254ad4ce14c11331d50165ac5bb823517e34d4022ea145b86f08e904417d110911dae8d4c34cbf19e06bed14abcf4018c0c0aa6594680d9adedaaacc968d2e4c404ea279b0ba3f55c0dc2131d916aa0066350d905f0bcfc0c3798500631d07e141c86d66cef60d7a4d3dcb5363301921ee9714eb1e96b640545556466870fb9a1a8bee7a3be69a258b346f40c37d9983ec15343c3011afe9d5f017fd4146ddd0a599a66b08d52508c4a068618d1c032a91caf83955ee7bde09b3174d85819b310b928b284c1d41cee93c321668b0bce26ab2da5f85b47d4172dafdef1e0cab94fd42023256f7137ca0d0bb7d4bb9474c74af5b384b45612fbd4e17d88242a892589522583c42a457310dc2922ad323af6ade89a4fabf0a03f9e63c4e31d787489c77af53c544a9b82462d11a5e42895dd91402d31b0cb2d34aa061cbf6341a9e8f27d3d5f18b67f11ec3be53550b97f90b7b67d82f27a9521db28573949655bb26ca7cc7dd7c4018610e53e3f925b31b5a0ad942df57648bb7b610e192fad1d7585c5f4a7579d155a2fd46df1186b91fd107e8cd13574a675d5cdd9e74c1882cbd5bdd752fe47ba3d9432aa66a6479d78dbd6d495a39821aaa3375662e5f6a4e415118b879c4891a09b2adcba09b0319931d263d6ee5ec24846cdfa2ea356a94f68edc150da00d88dbf6df036da6d81fe2d40d3c259d585614bf1afcf8f5b783d0bebb4602c2d78d78273050b43d240bc6a582c70775b18820ecfeb08c702e526160651778f9e61b290eb2ed81b064f9385918c01f271e1510f9d6e78c9b494287e0898d5e2c00fb1eccb1e06f529b2940af840a526af12208607ee4cc77222ad3bfabde5ccf27457f0a159aa5b6c3b113f03aba7969540137adf52d8a10b6976851728db6b93362cee979d9515d6f2a2080f159e45a3dd16b5303b51f1c8d3be35adb33e3ea305e01f91ac136cad5eabd3e47e5203b9bd7763d7f803ad65d59cf61a13b2893cf7b94570b7438cb37486fc38734a231963c32cfa2e28672a5827bafa7c6c73619d84d78978b531cf5bc2f9d512f9b3d2b9fad4288a98f8c6ba3cf6e58716c0920b00ee8a88a1326a43cb0312bc58f7951c0e129e523366abe28e27482f40fc5e4ec8046b05c0c300b261bbab275659d226522162fef396c46abc936c968c6f462b1034906eb8aed479dea56269c8c5d07633c0ab94a12833b4261066cc229c750646270f08ddcad971482ffec50a6610c0839d1dc91e0c813909b6027f683bf4e66f0580d904bdcf2d6de75c4574591789c346b64264e7a82c01e5ed11a7f22b4685ac0b69690f892347e26e19cb7454c69a15d928a095609332bbadcfc325f7b7a6162e86a7ef4f9ffaa5ffcafd0f13f24c44713f3da7bc45dacb41d9e1432faf479c919e063767f3369ba797bb34dfaf75f3f956d9830df3c90cd3b6043a45885cbd28295e1db6edaabe7911e455fa093d104c651bc4896fb0b184ac61b10e9f09f2ae1960e303e9fce56dffd7477de28a199fb6193eb2a57b4b22560a5cbb2293e67c08847a96e4f9fe17449ddc6102de5704240b3540b2a4d001ffffffffffffe725605a4231e151dbdab7b665da9749ca042f819230cac780dc29a59464d2761984d00b797b606f3b170d0be20b8e0ae5d5dc69445576c156122fc79272ce5c932ef8ad15a5475b5ae53c179cb6c91ba12b03c10597241b99c474b27ff505720bb64f27d5d70f265f9f6cc157e8aca72cedf67b4e0e20b56073a67e8ef9745af0aa9fbc63297d16dc89ce9d3e5aa632af65c1e73599b457d468d12e482c782ba539082cb89cf25e4e6ddbcfbf80bc82b516a5fd9a46617c140b3ec2f8a8157c84f1512af808e3a352f011c647a1e0a30529f8f803882bb89c429b98762738d65ac189ee3d963b765a27a2006105d7dde79ec4f3261564156c65d714936c62aae05a94249a5cd2c64e8f6105482a38fda6bb1d3d985892840a1054702546cf59526c8b51d4c929404ec19a66c7d8aea6162d17828f303e4080a3470eb661630763e4a0038829f8de35dbdccdd163b2147cde92f26ddcd027296159523042ba655dfab6a3e0a49e9c95c4749b63cc8982d14e82509663c994942643c149d131e69b89e6319a7241c1e611162ad52d557e7f3fc166d1f1a2768d3cc1e874dbb13dbe5ef0773bc1595e4be2793527597f4e7025694c9252696329b153d700d9049f8489f0a423b73c694034c176fcac62a9c4682618b7710f91fa266d00c10477426693f5b22ba5d0eb2558d331785e3aa12578d1c93bc9995e2538bb3bbff89d46e752b10184129c5d29a5e209f62412215c754c89ab69009104af962d4bcabf414d7455072091e04da9986d522a398ac88040823babb392e5a2443cedca03e411fc68ad182de69484eab6078f1c298081a92e401cc149a783da746a4cea24db08aefe93e4b163954811d10b208ce0cd57db4417f3ba00b208ee7bfcafc2a3208ae0b206cfb96a4ac58a3989e02fd735fd8877a7a6bb061044f09bfafea97b3729b1170d208760fb422bb433f977ae1882cd9f56195aa285e0f7d5a4ec9d54030821b81195337352cd20f88d22dd2459638b2e590a824d629097aa25760324107c8e6562eb68f9778ae70c4000c1798ee117db524a59a782fc81934cfad1c95cb54e80f8810ded92bedccd4afa65c306481f58db54bf9db32d08c147181f36ec864102840fac97cae972922b7f9b1c1b0906903db01574929359255d1d73103d706b2a9e9247e540f2c0a91c648c31293f8f29080f9ca0cc946d8bc91db8d396b4efb7036f920e11ea4135c9f9ab031b2c57050d1a3a306ada842ea5b5a4cfe41cf87ead13cc547bb0183970b9738df0342edaafc581d3984ca80c2d6db31a0efd9b50d76ab26b500d9037f0ab666fa9ca9298454cd20071031b33a6f1d4180469039fa1df2431e6b8d14b0e840dbc455defcdfc26c87341d6c0bf9f6c79b2e9133ac6d5c09f983da8eb9225774e4a039b3e284fa75e43c9f240d0c09752cba74c93d7691fe40c8cc97a52e9f2a4a3b6098819f8a4d42d77a53d49561148195853933746731d840cc56cb93c8aab47c6259031f0414fbceb202d1c8b3d40c4c09d947495bcd6fc39c343870e1c0777808481354f25a9a4c57c93dcc1b1d6e37e0002063ea3d567d56831ff461b3640d6e0ab34e36d8a96f305f64f3c413c087981b3d17f3177cc2706cf11438c1cbee35b60c3860d1b5d60355a32e982dab8c07bdc4ba9ea6b4927495a00d902ef19e3c68d39ea5892ca028816389934fa26abf30c2059604d5092acbc191940d4e02479a45baaaaec1a333380a4c1c61c54491d6c2cf0d9e4df0c6ea1712b650c2057e05adb4d7d2f465f0c767c0b92322bf049cc1fcf5cc221981480a0c166b490d67b4a3800a90227494acc793ff518809cc17daeacf64c55167fa3021fe47ace7b7ef9db537e0099027faa6e17444747d4480a8c923fb61583997c521d05ae73a9c92469ef126e9580070814b85056ea426b12ef35fe046ed57627f0d92a57eeb65139dddd043e9ee09a6c3c95a73d6102fb25fb86ae98eff30497c09df6249a976f206630727f94124f87c9a73ca33c0051025bbd5e824a4aa8933ca9a6ec04204960bd3c6ef9899d6d4090c0252926df937cdba40906a3f7ed4907617d2560302ad473e95c927ec1499fa4b01795e40b468a89215357922dd8df0b4eceedce4bc2d4b57e5ef063d2e66e5728a99bdf059f4d7b4428d1d7059b044fa96ec4366efab9e03f7bde642989d5ea3d2ef8cb74212d98860e22740b4e3e75179465d82539c8167c775f096a1d42ba8e6ac1eb6ed0bab9a7a6b28816ecfd9d2e2d59fb5ba25970f9d64add567a2ecf910527ccdd324cae68bf4f2cd8bc24e94f426aad7a07168c52751adf6d7f0597eee3db49f2a6979c76051bf294a4e437a97d37dd0a36ace3be2839c8a4df66059f35a698f43a7a3adaabe0cc445eee131545575a156cd709cab3eb4effc4a48255939ab265e55d491a54701d93bfdd9d49424d730a6e545dc614fc5afc3f8b9747d5a8149c90e7153dd826294c1252b037d2c4e09e3d074d26a360bb7429cf15531b2f1105df3ac2c3ff3ce8a6a1e0a287a9e4698282ab4f2725e1efad39b69f60e399ec1e4dce4d926a3dc17f8d929a1def0417df34495317cbefe4049fc23e6fa69c6e824bf2ebdbeaa69ae03599f6b4d9368d6e32c199cc9b360725263821ed5653a9e4251813cd43c99782d0a94a4bf06152544c335809469d74e209b5a95f724809be464b2ebd1d4e82539ae3e532f91dc42309defb577473ec507d72916094bcd020cf0309362db7a5dc3e82132253a889a96b4a7704fb694c67aaa42d69b4115c29dd122a9e6a9930823d95be5e3da4473517c14751e992e65814c1ad5bee4b6227117c4eb5d1d641042326a8698a7988822c7943f0976bad742eb142b0a57a53f0a8158e1d23c78d31cad881d64308af4608ce829262dee5242da7d120f88ec13e9b58e9a02712046b425b97f294dac43a0582abab20a2d54fa5c73420f8bc41fd3fa7fae441e50f6cf2be4dd3d9f526ef07fee4c874b208e58e2e630737c628638799c9c1471f785141e824dfad8a0ce203a3a349052fa57f4d4eee813bfda8fa56a94d0926217c8f327c70e313bbf1a1073e55274f4f42e53df13cf0de252aa8123ae73fc1213c0a8c18fdf78107be7544ff3593c6cdb531e3e30e9c8c294bba9c59bd0104e3c30e8c85d29cc74ae8c50b2a01cef8a8033f324fecf465b94c7cd081bd0b95479b1cdfc5c71cd8912958dde516ad9ac3b1b6bbbbabaaaaaaaa9a9999999989888888887877777777574a29a594528a999999999964350b07c08a0f39f07e6367164b5dda9de2c0694f25b70495f26c5470e04b89bc3e1def923df506ce3e27733f9197b1533730e275c2fcf2e6bf4ddbc0a99cfd723c648ad9e4d9c049f18c5d4a303154ed6be0fb46273749f37592f26a38c2471a18d3ffd3a759b2a6894103e741a6186e7255ca113a0327639ddc9636fac5136306f684df9ad6dca6af82cac008a5b4931ad1e6163764602d3ca791a6ba3130a6e45fec919618b8f5689e4374af73bfa30c32c2c0a64ad9db6a95c4be8620041d3bc0c0af8e965cf7a4f29be81a6c5fe7f6f312adcc24bfc055dae07e6d274b8edd1a1f5e602fd4a41ff56c173861f2d79574a3f3c454173eb8c0f86b4aaa4c94acda295be03d5b2ce8935e2b7c6881cd965bdcb2ece3a51d8d8f2c70a5bb4e0c95972a4a8fc2871a7cf2e09d4525213d49591a8ceea9cecdd99764530ac30716f8affa53a6e92f7c5c811d0df14cd1ad0d3aabc18715d8dcaf110b3ed0602f556e50a1c1f2fa8d632dd9c1471518992633c54ee5d95a7b220c410752227c9cc18e5c4d529eb858ce6211c20715b8cc24c6a4848812b305081f53e0dac744fec93129991b5fc68e73fac6187daaf4f890027e4481b74fabd95194e058d331c68d64c707141875c2e434d154da0ba1311e08bfe309fc2969ed26474fb89663f429627c38c1d7cb78f0d1043e9364d14d3aaf4f821213580d5dd295da30b1949c25f09b7c2b2c84c70c2e83ce266b893985e794c0291953a894629d04eee2b8063791b1118529299950274770a53c4da3498255db084ef01de569bd79ca6304a74908d1dab1b407cb22f8d8f99a4f6e8a604c3a95d39d08d6c6cd4e7f4c8f314304af26093e2a2bd8670ec1be989c9d83bed3ac2138b5ff96ecab52082e6ad44d295508c1979c97828ee7f5aaca20d83049923628a961a22408ce2cc934495220d8649ee9725797142640b09e4187bd8998a8f93f7025dd82f6fee8207c3fb02929490c154c6f507d1fd8a0c40d1af407f3e4e103ab4974ae5f329d92670f7c6df4136fd773785c0f8cfa8d1dc2cf032373ec4b39dfef36c703b74965eae62427a9dd8113bc440fa26a3bd415423de554d78131511baa6f3a7bc7d0814ba1ab2edc4a905133074ed347ef241a5395123930ba9671f39fc481512754ccd368cf4f02076e5bfd4f1cf55f3379031fc4925daa0d6d82d60de532b104d120e62256c9401b3831953d6d5b08215c36304ac7d0a393fa9d6ad7c09b949418c284263948d5c0c91cd32b9b9c3b3b9a06c6dab6d46707915945036392cefc25bac78fea19f84ae57e3a6e8977a71938b54a9681ad136f4d78ddf8956460838e9ff6a397343dda1818d7de24831aa1b44613035ffe1fb395d2c2c05d4c8b5f52478ad21918386149f6a4643e0ff2b3353825bd8eecb2374b39fb02972425c54b6db5778b7981ef52b2e5cd5b6ac3625d60ff54f433b5bf0d997181b3f49f2cfdc413add91638db55d7a444899ebc16f828b237ec6ecf04a12c70bfc1b6f383d4e0466f6dfa0e936ea1343825738e7d2c31a6c9c102d7c94a52d946c852fb1518d754c9ae4ace546a2b701fa23788495194d56830a6efd35def0733992a30fa95ab769aaedf33381dffb1d568d9dc840adc095121afea4c5f9229f4157c54a7929402278d6ed3a4b3e525330a9c6827d6df8750e052bbf692a6b35bef097c1251aef9f62a2715277072847c6dbd348171ebedbe8fbed533811b531963be04ae3f6713649514ec36834f72f4f3efc61f5509bcdd574c7ad7a104d5c4e86341069210810c20e1432418151001068f217c0f2e20f20b5ff0f00104447ad100115ef028a347f7e0e100915d4c4044170a10c945d2a1630719b85880c82d7ca0820388d80244a4162a428b1ecfe306106671230719206080882c2420120b58bc020122ae18438703445a6100115694c82a74a43172dc10438c3e6288d161a8a20222a94045182a720a536840a4142222a4b891830c10584064143b104528de0122a010438c3e0810f90404443c3101914ee42003042200c105443891229bf810d144024432818908885ca28c05885802032295e81e3acaf8c10d1e39c8008104442831890f1149808087183a74b4000322911011814422f20894e3468fe7f1001147f0f81c141069c48d1c6480e002228ce0f121b2881b5fc697e1821deca063c0011145f0488405441011019143dc90808821202052080988104205081019c402440491009140fc0e1d6114400410ec7d98f795d0233365ffc0e9947e3f68eec919227ee0a3658b08a125c5e8561fd83f5dd9adb137227ce0360615913df0eaa5d9269e943356498f317294f1832288e881f39329f697637c900736f7455113558212db8520820736df5996f45b9fa6ad3bf01dc73d5ac64cae3bb2032f1a4da9ecf697ce4d53072e9a9b6dda5237f949e8c0464fe3d164a97360d449428fb6682207eebdf7373fe5c4813f4975666e2f4fd7e1c0a5cb6257bd63edb97b03772157fddc32afaf6ee05ddb749235fb5912b6814df2c6a4154d59595547840d9c9fc8f5b513269a9488ac814f6f7b256c64226ae053733c793905edf9fe34b031b424e15779347099b34c274de29624a25e94fc129ab62666e0a4dd389e7312dc3dba65e0730e199efc36cda4950c8c4c313e062ed58534312f29064ea62cfaac378563cd129130d8d94b1ebdfa70ec8e1e641c0e11309cc81a27f28513f1c28974e144b870225b38112d9c48164e448d1349e344b070225738112b9c081a2752851339e344a87022533811299c48144e040a27f2841371c28934e1449870224b3811334e44092792841341c28504e342807121bfb8105f5c482f2e84171784905d84e8821ba9292378c1472e2e041717728b0bb1c585d4e2426881aa76878e3278d8b0f13bb061035d191f3ef81e26f8f052468f166304366c8cf13d7ab418e94c006e089905bfe2d549bae5f4d6231c9b9c2c2e24166c58a80c3a3fad2e69d10421b0e07e2bf4d76d50a258fe158c5e5eaa98973f9914ba825361a9c1c43531985f21ade0f5537bbc4a924a49920a61052709426f67fa0b268719b20a56a4f7ff855a3d72f0d041068f11249c085145319df75e5039ba584252c1c6f39354994e631f4250c19655d0491aa13a057b1bcc847865dc4c5138849882adbcd9dc2d0695a4da524829b8caff39f34449c19b8a5d9972294949291dc5d7fef77b66ddf68dffa4a2606df74db99fb926c19050b01f4fce56f289c14108284c1b1acf94e8c69c10f2094e067939ef682c4198a9ea094e9dbc9b84997854370b00d008e904db55d953f692c4746f12c209c69298596b9997092d64139c2a49cc270956a74a4e12a209de4c923b6b9398184232c19f9856a695e26a6a0e26d8fd3429fe65c956d9bd041b2c5dcc55cb12fc282ba59b4cb212fcc8ee134ac99c4daa9c126cc6f320ac44336412ac49cb2e0d3275094a5c12bc5bec32a159d53c7e91e03d9ea867c7acf28c438213d36add6a53fdbe097904275bcd4c49552945660e218ee04d122bacdc5f4ff4ee843482eb5842ffd2bbf5d91fc20846ea9569cca371e36771ac9923842c820dfa2fbd59b725136370acddd081ca144214c1a935dd295e8919774489e0346875775bc711c1d78957794d9b86d2f010ac4919b39f9ca43caa1c64b4213849895fd2d5514821f8dd347a295d73de87105c8c99453f73335732e158bb91838c360685904130bab269dbe711c7da0d1d2899102208365e98672e490c96475f061981e06c747fce111db5268400828d96d3c92e2a5208f903274992c9d7d10d1d7ee04b9b6ae7df89712f8663ed4ccd08e903eb5aa206938289d4bd7420326430060b30008f08e1037f55414fa816cf98a13df095d924f9a4248a474fd2037b2a79aeb86af2c0c692625e7db2a8f6080f6cd29cf9c4f3db92ee1db89c47975a6ccda35662073698a01a749964b0600739d218e785903a30f651735252496ff2d37708a103dba77647f68f88a82ff81d8cd138e81032877a44a7a4922466840891036b6f9a9fcce399a5fcde101207d62eaf29f9fc7f4f5edb100207b64ad05e7ea2e528b164c3c6bd81f1dc49924db2f50c216ee0a257dc94a29a98a56e481b18ad9f6b93878c39a26303671f4a54cb63513b946cd858036fe671ed848ca1cbe4d5c0494a8389d1fc4da5a03278f0c89128084983a99210fa9952ca0841033b2a8ee8568af9ae3c38d678ec3803bf9e73974edb256ad0af195851f1b2c754cab2a737870ea5414819387df30f96f2fb572e082103e7fea1fc244992a29ba00d1903a7a4876de8d339e78f3b769471121b8488817d2d29552d42e830c2c0abc9d4372656e9272b080103b756257889b1d2743338d64ac81a5c9f1c26069d6bff198463ed06215fe084ce5b62d9f63ac8af8cad41881718d330bd671ec5b176b20bec690699639ed2e2a13174f88d21ece8813208e102771b7bb3c7923a7f34e1581be3c9d071e3fd868e1e377aa0e34c0c42b6c0678e5def296830313cc4d0a1838cb5b5102d70edb14b869527070db21092053e9a98384a85924184a8c1bbc9bc33fda1d46e3e0d3e6bd5dadd43e751278008c102e7f1a4b54e31c90db343c815f82cca24d1ee55b229b51a42acc0a9abc8e83faaead4db5f84a0c1991c356fe878928b902ab0e39765aa3a8a240839c3d14970cd6baa84721042053e65cd6a952799ce497e45052153e054c537192bfd52602f45ebd726e9fc93941c42a260da1a4d197fefcd43844081d1279812fb5fe3c7bcae608d90277092e41e846f27f93b495ac147181f25208347951027b05d9be99eb34afdd9e57c10d204b68465ce499b4e62fc0e131859522fc91fd525b077fb9a2e7bdc1c6a33d833215b2c3c9f9862651711a2047693b7792e49661dddf808e3c3043d4e19680c13fc8e32788cc12624097cccf9b4e8a68d17df1482044effc4ab60fba627090583b1118fed9da9272d0718acb97b523f2a9eee925f707135f75234e30b46880a4229d1682f38a1f2657526495e70b3e05347884942895184e5b2e0939ad0d962792cd84a494ea73b2c080b4edc36bd825351df354925573026896b2a5bac35df0adea4ca9235e8a6d03e2bd8af987bc45d057b49126d73c492b4bc2ab81c69e3fd76ada25470a2ae7a922f4305a3842ed962da4fc1066582905fd929a98f29d8be36296a4c6939e69482efdf72f75cf2847948c1da9f24a764957bcb330ab6aeee7e647f76eea260b4a411e223bbf4d3a1e0ecda84890d0a4eac14969be927359f6043473fc51c6476497b820f259554c2723d844c2758bf68399b1c53f8ca0976d5549f96923f98c92638595a543da535c18f169944c63513ac9648bdec2607d1292658d392f5f45c4fcef4126c757e49c13627edd312ac29d14ebeb236796725f84abfca19ec547749097e4d6db2ae72126cbd4979f27fa54992042374a9e59f1cd31a09ce3289a6d7249ef221c169ae7e06111fc1a5edc926858ee0b582ae92a3c757af6ec4e9639adc752746f097a4c96d8269116c062b258dce310fbd2238395e6bd0a0edb3f58960f386490d11c1280b1d4a7c1d611674084e379994173a86603b75d36350217837cd27bf643b39c609c16a8be8e07b3997d020384ba164a66c19b22308563dc74c09cb9c258160e45ea709bf6492ac01c19e982429eaa14693fc8153914155a9891fb8b57f31d5fbc0fde853826995e0f7f281133dc7cc9f599398ec81f35d4dcf5eb93a7ae02f44a69990264acb3c70ba3a5ff7a74e5dc2035f415f129de48b6a7207f63cadf607d10edc09d9a17fc33af0c1d275d2dc39797b7460f3dba99dcacd81f5749564bff616ebe4c0c9f9b3a74cd3577e1c3877dd649b299d8f0a1cf8cdd831097a79031be4d9075522ee5b7103ebd76979f465a86d6d60fcfda41b99b18135c9439a9c042bd954660dec995c52033f26c95cc99306b662a5b2bc20e3ed686073d29dc4edef5efc33b061a797a4ada462c60c5cebf589769fbf1b2a03eb1a77ef4acccd9c0c9c5a5b6aad4b828919031b3f6b786609aa248f18780b3aeafba59274260c9c14b324cbed5937eb606063e78aa1c4eb0b32bd06bbdb673b965465e90b7c4e615a974fe9aebdc0094f95b4eb6777922eb031e4e86cfa5316950b7cea943665f5122b66b6c0ad85951cf45ab034369085b2013518edf9df7aa469b0fe79a3dae53325a358604f4e69d208992b704a95daf793a38a9e56e0529749df6a69949768f0ae632969933a5606abc0584a16acc32c28153c83f3d49e4c4a36dafd2554e0bcdb6b3feff59494640a6c8ec9c44605954f6d891438afdab713e2af39954481fb31b5312fae694d2550e03aa66092909a314f2a7902233f28bb98ad36582a7102a7475a3acb6902a74d4a928612967286095c7f6f12ea256ebe04eeabf4e54ecab6ca64067fc23309d5cad1bb12f85079a2728e08ad49022f329ad8614ad34f3680042e9a26b1fde482c17596a815e927880c30d8939a31e5f8a55fd12f1293a399a43fc7176c86f0a05f737ac169302928995517eae1051b2b6f4966b235c877c1a9d790594c5b4ae2ae0b46de7d2a957a2eb820af83ac125775745c704ab2982ea99099d4be05279644f7f4b72db8e47d524cb22fbac8d4826fd3aa5049acd0132d389117dca4f42cf80a3ae496892cb8984eca9d25a93a29492c5813aab67a3c58709b157437449bf8fa0abe242958746f4db193ae604377765d2c5bc1c54a3a9fd011f33cb28293630819f349a1dfe32a380d2a6626dd90297daae0d3862e6d4df3de5c2ab82ab9af26ffe9c8145430969a3da9ef148c0cbe31a594a4f698820faf247dec0a2a67a5149c7bf4cbd977f3049182d5dc189644efa05d1b05ab1f541c253a3f96a428b898e4b42685148582cd62328d8e83824d252d5bdc7d73f5139c1415152a544d096b3dc1fbdd66f3a0f4853c75e2db143dc33ccf094e0a158410d2df041bbd937e2ea9c1ced7049b6eb2a651efb14a28139c5bbd8aae933c5b1026384d292a468d95b2722ec1d8afa94e1b7a92752cc109a2eba2f4c8cf9957823bb5eedebd166dd494e0d2995d1433599ed393e0face4dae2c42e9182309f6eed269d226891b6322c156fedd58396e7a3e8104df764265f29247f0a6e498f43984769e38824b52b0a0d72bff539246b059ede946a95af22c2318353166567117c1a75cb931d99b6a5e15c166b7ba8b4ea2e3c9447029c7944dc955755d2282b7bb3515423c771a0fc15d0637f5dd9a4b0e0dc15e59a6fbe4a3f78285e0823eb1d4765d55f608c16551528c7f2a83e084d06fda84b66db40882cb933ea7ad52322c16084e965c92346a1a475a0a086e54d079d22cfd03975d3a772f46bdacd40f7c745535419918c592fac009ffb41d13f1814b4ad05f65aaea949c3df01635a5796eea981c3db02988f41332074da13cb01dfaa46793e424573c70fe224f948ed237de81bf54d2f7c44bd15cdb812d497d7dae94dca4ba0e8c6cd76fcd2769532774e0376e52c96c3407d63ba59cf2bbad9d560e7c5493fcf53a4853d938f0f1934a42af8bbfb670e0620ca53d5b2c31eafa0646af7f96249709c20781105a0543e85146050db8812d3b4fa21a63d6a4b681d31f4c836d4ecd2436b06b4a7a8d4c3ac67a0d8c0559494932a8063ecc3da9e0b934302629b1c404ad277d870646ecab3f6de50c5cf25c497e332994ccc09beeb49d4c37ed6f65602d5cab527c2d6fc9e0083b95d225c7c0470b2fc5c06dc9ec4ea71406deff32b774090c6c9f6027d7e8daacafc19a6bd226bf674fb2ff02b76a164dafe3057efd46499b67171821479ee74b311f11173859adef3ce88565ce16b8ac24499289eace25470b9c524b0f154a28ad9d2c30a2fb3928715783935dd3823a937485d2e05392b3e5acd6621a2cf0a7e3be9ddf57e0af46847e92f2a7b1adc07db0523ad768301eef63ae13e429a1a9029bb13ac52b515539c9196cd08d9594b6a766091558d5939902175764954aab6b72540a7c9f6a6bf6683e4919854cd5a6b8ee50e0b485d2eb1f747f4a3e81112543e9e0e21ef3884ee02e9d2ef13cf9773ba6095c287d9efa64ce792670596d45d34b492a69096c97eec6f0fe769119acdb8927c6246a56764ae093e4b5b9b449a59624304a8e3165d2184d4e150d20810f3a6df4495b303825698eeef5a994944260f099b39a6ad3f7d1fe829157f94bbc245ff05a3ad5e4f4824db74f952b48b79a179ca443dad788329d5d70ea84d21f425badf8bae08452352a688ea227940bae73b865961c5cf02645db6bebb7e064d478766da649a76dc1588ea75a70f13e98a756bfb40d2d38695d5f54a94c919959f0a77cfcf7960567a2376eac12e29624169c0965556ba19d1d587041287194f59fa0f17d059772941c3c6dacded4158cbec92789ba15fca5f8ad67252b3815352d4de83c9a5e05f74198f613458979e2bf830ca882cb596a5667dec1c354b0d1e47c53415430da46ef8252aff1524ec1c9dd247ce376a6e0ebeb4f32c9cf748c5d29d890596b74b7755776a4605bc55b7454302556370afed447bb0921445475a230c968d27e05a550f0b92d2b94decd577950f0a93f448d6aceb7a34f3096516ccfd553edc813ace5ab513a054f721075224bc97438c19aae98259fee7936c15fd4ea50194d3255135c554c1a54496d93f24c3026a5ea31192abb8d09c63a757916fd16847d093e5436653ad2e4785b825396d5ecd394e69b54825dd3cab4515182cf496b29299a042764776ebd25c128ebfd1a158d0417937c27a64b4830aa942428e149d0dfe323d898c4046960a3a55a292906a55a32468d0ea08153ba753736f61fea0de363c7bf20251ddb860e9c812f79ca24abeb4aea5f0e3330264564f29893a0ee6afd8801093a5006ce64055fdfb3cc1a94628851462aa66174800cec491d470925946eba14111d180397a74c2a9984122afa17031b73f6d589d067232f85e84018d8182d93a8563a4fbaa3078f1be8c9e8c323b11dcfe33cd00130b09fa35ad2a0496bb049e9a6c917477bb3e90b6cc6b42707e17b81913a76e2199a4dfcbac0daf656561471812de1ae963556c88ffd1638b1d5c4b175911638295a5443eb270b7edc9223aa1abc2851cd1b94e82978270d4e09eababdf15dd4c8b1c07b7a3ed97a474f3eb9021f5356c50c2fe51bb5026bb57e992d2d07ada0c149c173e6a06478ec5481f5ff3c194c0caa2deb33f8922342e6c91bd13154e02d594ac2627afb8b53e0539a32cf5816427952e0e4f4ce7f9208556b3151e074084f29a524739f2428f049e4a9c5759fc04951923a3dfa76c49238813dab9c0499208c1d7ce840137853b32f7dd695f46602ebda16b5da257072edf22953ea4ee8bfd88e3d74c00c33a5104de9424ae064ba9ca2e88c7b95d50e24814d3ea221345499386a0790c0a6cd4bf9319ac160fd4776141d30b85172f626215e9205fd829167f7a1349a9649d3176ce51c3af999b6ec9d5eb049a63a2965ed9a9c435e703a7ac8a4547e3779df0563c193e89719e48af274c125d5d49c718427d15472c1ad97fc16939be77d71c128d51dd4f2abaf5fec16acc5cb8b992ed8c9235b70a94dadc6df324929550b6ec5ea3de98aa753cca1059f974bfc93f6528a419f051ff452d03456ad9ed3b260f772ed4951e9e4d8492c182578ecbf689af6dc830523a39fd4b2b0bc828d9a3975499224baab36e20a5ec3f5437b641ed9b1b246186905573a5a0ef14cb382d54a1bf521ff63bacec82ab83139894e62e9bc2638a20a4ed031e6b62463a9e05b3559b6145554f0316f163dea4b497f3a051f73d49e1cfac953923505b7db49ad5f2a75425d0a4e92fbf45a5a4c52754e0a5e8310a272f4935170aa69e4888d44c1e6d89eda3c7f062b43c1a9f0204b9b6eaa7317148cbb9baebc1884cefc3ec16693ca4d10d2a386553cc1650a269394b6914e704a75ad7a12954db46c84135c3e937641fec7cbde4636c107a5bc82ed6ffecf8dc78826381d3ba67cab3927294b99e047ab255152b08c6082bbead11a533baa85914bb0716b545f2769a9a764c4127c27b17cf376d509eb2ac15beda93b59a341a8a4123cd2b1021b366cd8f81c2394602c45959cc40e117298d9e7d8d1c38c4c024724812391c01148e0c82370c41138d2081c61048e2c024714812389c01144e0c82170c4103852081c21048e0c024704812381c01140e0c81f70c40f38d2071ce1038eec0147f4802379c0113ce0c81d70c40e3852071ca1038ecc0147e4802371c01138e0c81b70c40d5cee9c64526d4238d66030d206ded389f28a99c2b136c2061c59038ea80147d2802368c0308c9c0147ccc027b128fa72929132304a8f12e3a606a955eb8b60840c6c995c32fde87a2f6d3f303206f6738b92513bc7de2431f0b12e2d2935377f531818cb9eebb3256bef1218f8adabce5e7abbb65f8391164f326db29dd4d11738b595b2427a3cad212ff0695c43553615f7425d60d386dc785d57d174b8c0be49499ddeb7c09bbceab1e4581b2c5a607f4b4e1f8df93775b2c0fd67d2e655a1e48e1aece756be94771a7cd0abfade3416b812a5769631ad273157e0456e56e0ea548eac548206a75f3d96e454810fa117dae4c954626770a249295bafa502db4999c6249f0227fd6d6d6e1e999a4a815f8bd7f6251905d642c7465a100a7ce952b267d01358ffec5a32e69cc0dae9f18b254d6053b0d8c9466ef7e598c08fd0e65951a4ffa72c816dcd7984fe9646cce0b63208e5a34bbc636944097c456f4f7e39491daf3492043634e6946a3ad5e42a8d208191b1463cc96425792818dcfbb78bed959f0a02065f4a37b7f342a9e8f905272dc8bc0d6edacde30b56fb828d364f2fd8536ba6d3e3df5a0e2ff8bebcfa6d5de1baef824b4abcfc9ec7357fae0b46bd5f8afcca9ff9ce05bf396ab40cdf24268d0bce3df66f4c52ad49fb16ac8923f4968e6f1bb3b6e06e5b949d6e6bc14517a5520c6dc17a5a7052898cd6254de4c92c18cf3726cb4a5970720a91a744180bc637f3983a1f167c5d0ad3fbb5f134f8af60f44e37c520f43683ef0ade734e5ba973b274cbb7825f513fe92959cc933d2bca2a75b3fceb57c14992204ab359c9d9d7ab827b139390395e17b429155ca74ca9e7234d7909159cdc270921ccd6a3964ec17a8ce934c9f132eb6f0a3eda077571e37f28f952f029e71a115a52b02628ff1661f904ef47c15886afe96a8a51170527646d4cca3af5d450b0aa59bfe28f8e8d08148c65ca693de59c5dfc046f253c0725a924878a275813efe486ce71dd4e27b892d57ad717723f9ce04f6e4d7ba6fd5eb309c62fea5f9e8abe37a57ec4800432f888410a3e78f4ef38c6101cd0449bf2e4a0a567821b913d9643c704bff93af52729e9757e093e2dab583e398af56d093ec42b67dd5e0976ed2e8e5ad87889127cb6ff4cd35f95e266125ce9f7586961279846125cbe53ee69349160f4a2b5c8924b734f20c15bc870db24e51cafe411fc7a9a523dad23f8a45a3e4288f43b6d23d8183bd5626a19c197588c17da728668115c294f6a66412c88aa0856b3966ccb25821364df9a922522b89464ffd8bd9ffbca4330269f0a512565999586e0c3cd32f4a7106cd6ec13bf3ec68a1282ebce2c7d5b724a171c041747687752959bbe20b8be1894b07820785d134d610282bf132147dba4a0e4ee0fece69c7e6355a1b6f3037f7a6a4afa4b1f58ed124dc91363975d50aa9e5e7490963df0963a5baeb09ce9eb81310dea9d3f79e0be468b8a9644f36d78e0e424b62539966c3ac6d01df86f53926ef7f18b1ab2039fb29f87e678c94c4375e0e27f88e8c02979aa2da39b4a953407fe2fa8a43beb63902539b01b376d2629dc4cff71e04e8c2338b0161e4c14bbcc96436f604fcebd126b64b9e9b881cf1a63bfeb06a9a6d3062ee653b2f7e8aa0e3a6ce0be369dc8faac815d7fef3f0d266c3b6ae063d42cfaa4f230514f0363e28f52258892a2316860e4c9e4267fec16d59c81f1924cccc0ab7ba9775353e16d1938254b4d0646254b621231c7c0a5ea52295de7a0741403a793d0fdf73c428f18063e37fd08edfc7e213070265df4247a6b25736bb099d762922cc912d3fb026331d967dd5b2cb13a5e6037c58e7fed79a2d5e902ef6d7b2796121ae45ce093b89b9c92aa2448b7c0985cbb9559435f3469818f5d61a562fa4c5bca02179316cd6d492e31e5d5e0d5ce2ea85f7768280dfe3b85bc134a33c60f1638f1d624edcaafc02659cca275fa49635b810f9eebbfc54683d78bd994a79827afabc0d5589f597bfdfb67309a5799a53996b4a102a79d6d41054bf79a29b026a63f9db99da2440a8c8ea2b6cabb545f130546c998f14daf759a060afc874e1fc77254d2cc13d85c52ec587ee2044e4b90953364de92264d604c9a6bbd9fdc6e2f13f8f1a0626d6a97c0df8895d60d93c15433b8cfa1258a3a6195a24ae0fcbf2ef50559dae64012f89c243dbe96bbe40d0790c0c8ac37599294547c83c165517bda1b164a99c0e0f25e9f300b3a6b98bf604fab294178aba7205fb0278f4e4ad6b1177c1293731e9399d7455ef06997e3bbb95db09e5572fed26f93e474c1c724b5a41013deefe582dbd0984345798cf9820b2e67ae4927536ec19e998ca7dd3e6e6f0b467885d46892dc36b15ab099740821ff44e7ce68c1a6730da13be5f3788ba2a804cd854204a25828108943e240000c8a6f0b00531508301848280cc4811c86d24411761480024a1e2036282216241e10102c140e120c8541613028100603026140200c0685c2c140496bcad604ca512105ba8c75b2cb4ba7aa9113c3e5a4ac2e278514a93ee58e7344760988dca5cc6894f2abc16d32d22889de86b08a6d2aa8796f1b72e6383163c3ada86ab5a25dbba25e71bf7c174d31193a2b6048166d5fbcb393055e7cc766d316fe881992a85bf3de4ccff0f7c2655b0a7d47fed1de1b79e4c8a8b20673928180a52f67ef284a277b269972dd7b99d1ab72c79cb0e46c3609fc7a1bb3e35b0aed60c0307e291ca5963fa4d6b0a12463b0b34235505204add079a04a3f6b52ec5a91bbcdb84c1deb9421e6b1186a509401d9126dfe4ef1cdbb8f47bcdca5a887d4eefa789daf62c8a6a689d6afab4dd5599a8c57c62a5c14125419d69e2a6d90320a151869cbe9d0fbc8482ccb0988602af4593cb6cbe2f752bedd1e03a2233e8f259a96796980d505248cc1bb8cb8c3cad8d14d2c25232acd14722af6d1b7acc42719486c70b9816626987acf5d2d372fa695ee3e5d856fe1e3ee5d55ec9c27302b40e335901b859aa78aca8829db8ceaaaa9937a293daf0289624f8dabe5a5b7a98c990e9d6451cc33762766885d7e19e18a00054e3c46b0c62b104637584a10e303d14b42ba4638d052e1bf1f4598648c838a7581f41745dbdd0fafdcc7bcc866d4b1439121969976d9e5e1d5288cb9be600acb709dda641d97310f18e0a03ab893d86aa122bf0c41cb193b6fa4832ca3b12564357532246323df18978d4d8e3da0e0a19c970ac48204c53bd89998c29733b25800dae29d0f5469252cad51dba20825d33a1445a7857b1fe5547563868280d3650bdcef38802ce40b8c54d05e611d1e8fbef3f416d8709de12a225661da8ff6d082d064fcefa37ceb5fbbfacfb2172caa6c24594b3d6c2bc09bb86255c6a306c0e2055c04c8780df11a09c8e3074bc0ed80e5efea4255b36adbd52e9fce5d21de86d4893b0bc6c6427bc9da1edfddb3293cf7d56aa52e280eeb48177e262e502c9bd9acfdbc50f66e69e04359c2e4662b92a16279d7729664901cce025338813e3ea5e781a53b3ada8126c451a895417e83aa7774d241f734d30ee2b1b8cf8baa211382accdf1b066276af9390c00bfa0efc6367b1bdde8a2c3d04bf2a97668cff167f007beca651ee6e8539f02c2448c41fbed0a19d122e8468b04b47e55d5debd6e7dd22101b188f8667c1500a8f1d9dea75e0357963d52aeee02939d38b8a2aaa900d9c415a603be20c5af1eb0aaf02d9d2701b150fe7287972be7cac34b3336f3138bd13d75d0cba5272182219aa1ab1d377e031ae840df88f383f13bcc825d67ee57768a36c1d5753508c7eb7770a7c526e05554ac5935552334480dec9968486d0bebaedbfa6bf7713962cf3fee3e820177bc8307eef88189f08a0def94b6bf45b9155c1a791f90f21a8b45309a86731f262e84d475b641fdd4d1b2ff446a254c3d5faaafa4226227d60686c297111f2e23086d7d2329c8d1595e99b6778ef7d6c453ed2e1c3bafe5bce0f9d9ebda6a83e625b9bc3a2f8c7db48de77cfc55e2e0a2a16ee8938533aea8abeb8ff3272a568be5e6d7d0d5a353da90ace7d1d88443d6ef4d405e025c5901e49547b2435f0d455e0f28dcf34bef52a2f0c8b60c9f2e12dc3b6ab30d4638051006e6ef944502d2f64731aebe35905dd214d907006d26b1f7d0854e02771e35c9104f6a03cd36ddda8e37ad72a724d5a2566eb601bd76c47df2dc7c0f071e9b32ddaeabdafd1590c6fa6755a74693974e2f71ed4837ccf39036b94387daf1e565dad9650b76b97c52097cf1bb1e7e972be8cb4ad7ce61c43fbe71ce731ae936e33cd03e4545f5a787d04b60541f4ddbb8830c776ec39fed66fef7a7f96c5b28e9d8f012d0fd5e4d6e5597dad6fc6eecbdf124b6f9a5399ce181d9932fe03d8232a5f7474576593e6c9f0874ca9c4f1bf1983018f9a4e1fc430a8d223c9e8be02bc8813555b483b872688c34aea39defbaf3bd44f9bd0bc3bbd9ebc7b704176f20ae8806ee6dd27ebf7a4d2a54ffdb68416ff4807b09d89d36188fe0f00706fc0a358e8a53d02720a76d1a25166c15ddc42f88599d0fd9ea30e8a8d6c4a7cdd4ea14fc945d197b9aed877b0721803dd8fd63f6ddc01d3fb0117e451b79759ec8413c54dfc4f90133e64d1f0ed6f0627805cc817615c027c091278ddc8ff21211fbacde753a1b7f62e73ffdb7e669b374c97c723be0261843a1d5520972434fe82520b547aa03c40db9db5fc0c53330c38d4ff0e17b9db19beb7c73af2f0957205342b8f2a0af83b35426e9424515f9c3ec77fe80919921bd96ea5ec6a75f6a97026faf751f67d957bf9aea577e2850d92949cbfaa981b541886884cf7b470ef620e0c1edbc58bb0201e8c4b87e74bb2252166b3fc84b032626d8ee88596f519cd7e6573e8ec6db469cbfd8f531d9133bc22b7b5721225e3fbdc16ce8ce75bd38bf6fdb0cd588ae0d7e873393cc9c46bbddf26e3408f43bd3c31e37f7a70c36ebffa00784ab40ff2cf6a84b74af530ae2dadcdb1baec8334bb4efeaed9efb628ca1efbbd0474b74d08c66b4ac7bbd75e0ee25394b4ee31b6f423fc29e14be7f1ad7f3965bbe1f5d3440bfa0975e1ee435d74847b1bb376ff2ec86606b762b2a970b6dafbab90675c5a08e38fbc94e77d8f6c9911cc5a92b3a3fd7b926c68a804531b090b81bd208ca8acb6816b67cb49d55acdc8656148f91c8c28f8a8ea84c7f4d7ed3738f2d66183c3b0a7b45204d81f4d6a7026cef70d6eaf3525226d73b5faf1f04fce1556ec6219deef10a339e63369f2e69abd2f394601372be461c5c55967e6d73f5f6abeb29bb533ae9bd6aa536aded1fef7c980261af1c7135fc698f2862b5af959720311f00cd0dd45593eafcdb13b49f1c0909b48edbb07cb386e882d47ecd4be5f74e0966677f0213dfc6b732663a1bf14099f92a48235caf913b290e96119640a62e3e6c748db90218ccc259119fe0005f8eee27713e60ca3529269348dc155de2eeb42bed0ec5abb8e9af36345734a4e2ee2baf7af09cc8dbb832ce7fb2b3e9a7bb427876d42a05b4e150a16efa4f775a056c7cfaf42f21addd08dd793e1275d234d71d1dd511da09029d3ce39bebb0e6ba729e44be082ee738cc26851b38c0780663dfc6dd47bbab7d076ceabaaa46e36f71d157c8ec6ada2b5eb94abbf708fb9d68673bc2b78885cffed9a4e58ab1f6876da09764667af69d82c2153786572f3897756ef3aaa2402f4ba74bac3c69612f8e02a3818d6e6cf31ddb750797f3cebba5c427b26ebd42f3143481bd74e1f3080e3bd187fe202f511cb7fce0966ab54fe45995181ccbb4eda496fadb49431bcc5ee2c3a3f27360db16562f6c412b6a6f865458829c62b55581caa0aadad667c3bdfcfa26a2559d92ef5687c66d60d3ddcaf7f77b059f36392f7c97068bf33b034c00d6ff2e223e25cac309c1d3f5bcae355b3502c0dd8057749e9910c47dda0dd46d4a64bfb970675aefaaf9fd8607debb2a07843b0043e13957937276062773a4f33d95dd9d04214e76e86f10078dec06c22bcac446e82d2e36d4f5d3f373a437db3fc2569648e0afe2aa2e3ad21dcadf200f870eaefd6d42f8ec4fc2e3db076f2815033d754477799b4101c7c8e74241b02439f1f9247625a0636e8aaf8e582e8c494f0c5b145639d61556c95ce71ae93aa2af4971f6f6e2f33529e75c7fc201e27093fe51fe9c8cd23875213e4f381d485e0f737295a9a0930be6d62f87c2f36649fee5592553c0ccf7b6ca08cdb30bf8137f629b616db1c25ad97baa0bf809d008cf56534ee32a623d57b907694ec52867ca2bf2d04475a6d6ce838ee8e3b9a664c444a4663a312ccd576949027ed6f46f6f91c247837a011f8d0262a6439cd1ef6616650eeeaf690a90a1840122a90cfe57f52e116bf9452823caa5c8aa4c4c09de1151f7b11768f9942c0706c783036994e191bb0445098ff4fee4ec25bcf909e5a794808c0859609120a98f21206703ed85643c2ebeaf6085295f600abe38c0c5cad2b83383e373677455039e94fe3f7dbf7286cf898f01ef8d7db02024b50b796255db69fb74ac2f1021270edf54c2875c68a3c9b7ce31466d6591c1e267c4650dbebb79c1be4b4102109725f77c1e21e45880b8c566e428018d9c727d84001cd563d1bffbfd26e36fed33014fa8547609566fc5e0d3f640542af9de85938019442f8e4c7c5d15b9b4a4736f2d79f6c7325acaa5ea937d7d80d51a8f2c1693c9c1fb2702e2f06c1956228468f0301611f8fde92d5c049b4d4679af78f9bf1de0f2a42f8e0140fc9b1b347d2afe0cbb482c70cbfc166d21f6d7b6094c251fdbb13f87765ca0651d80497f0df0a6f6e734c1c17e1651cffe9c14c464007c1410c019f0632138a0de32b9e435f20f4fb6f4e26fdbe52ab1ecc8ce389d673f93cafcd10573a72b06dd85e1ce572022501a01767e01607c43d108c50d8a282c8ea451dcbe149f2659f2431942b1c178c3911b7a72a8b6db28cbb4a3c45e7ba356e9315875d12426160c901de98f85bedf4bf1f90b783cec994c17a82cc90d9bc55e8d95e75fcd5c238d88ca26d40abd4c444a747684609a04fd6f038374ea4bb54795601a32db0753ea22bfa9b703923b12098866809200f45cbeafba81cbbeab094b0dd4fd752d6c9fc6b30f2d8593890bcacd869ebde5c58dadd45729fbf5b53b8f63f25d0c2d8a8244e02eb49a7ff60ad76a3c4f5bcbcf1f2519eb2aea4ee4fd57f2eb4cff5813ee37fe5090c84a28cb9594b4eef86785bffdfe6fde2f22409b5a7b6ec3cae677177a493e5cdc6dfdb28a7912f7c4f5f43747485d42ee80e404fa98757a2c31d77bfc252289b0e6cabbd5b00f193669b5b30017393702dcc5c005c493c81a2639824b4a5521b88b610d9209c6c664428186343dde7f585a4211d139405e66f2faec93f2d7387724c886801f547e3a0f831943f2189d062d46458938b391ff99fd52a63ca3dbf59f9838c10b0beafe1af8e3ef2fca631ae52e2c39731ae5d45ec8ae47742d00fd3c06b7e02faa975513e1b48c275fe80c0cdb32bd66e2d40a5938ccf276bc8b7ecf2e4b6d53e740858e94478091922f6e72a5c686b2caaa4c44ee505d43833a3f192f6e8e56e53f735e07fa6cfffc9b92db2b67819446b5a143ba1d435b021fea660336f9bbf06063ce4402e180823f8231de31c17a5936b529d3ed8424ded588aa6781e03aa2993e346f344036429ca5a34bae17b60a599e3d68004e63d18fb118ae17af7558fd4cb66caf73f6d3d53ee93c383846c2c27924a2fd1352560782b9f551b292a86196eb2cb869997fe3c38bd7662a89e44c02ef054d35d51e1a8fa7d8aaac0dc53963ebd6f2efbdcff43734615007821cf6da1dc79c6d7b7bdda9c038a49e9c80a445915e0731c14a853300995d9253750415c751abaa97afbf278a76c89ab2fe6b6ac2160e52e473316e98928a375696d5a5be39a35bbd123152921fc18647fe3c8f295992b887280f955b024884417077e534627fe6e1e231c90dc8bdcf2912325bf5360c23bb07418de1a24e82b2e3aa202cc449aa25a5b28eaedc4a2611e8a610493d53968b5ba9b4432732ec03943f01d043c59ad695396e102953634aac7587b2ff9081a26d1557e9fd069ab2068de9d81bde909ea4f8606217d9e619a2b1371742acfa08fad8dc15880ac38b5c71b4ca917011550ece387341aba053e8d1329e8e0bc8902b7b2e54390652cdce321738de2f560df921b72ef77bb4db7a4f5a089e2e4e945e2bf226be8629120807fbda012ba1ce46190af9e14e7f389848d749d64000d651efa0981d6232ea41036db5d5932e8c1698d6c60876e79cfe8fbfa07104e5ab0f504d02505fc46e704a6bd195a5e24cdbcc87e23b48e0dae3b7048a7eda48b7835fb6ae32d1e2922483ee83d5cb8805d91f2ae7cad77b0849b4430efc45a4e2103e46c21db726893c67c80f100d9c59a4a23adab2d451fc07f52a07e5369821c1e0f9112e50025346565140442bf964b828c73706d8c4c269136c222f736f59270e0587f2d2ea4248c3e4bef423c5f49fef9b4b6461d72bec2ff8461557958fb646f5e1a862573b57b4f1a66d3835fa01820135d01f0ec54cfe86864208509a601dff72a7a7d4096ca09a282b45a1b6ec3e64ffc636ea563c4252481382b352b50c574ed836820212714776191263418515124d91e9bd1a3a06651d5da70586fac369f355c442bc66ed585046a1f2455f7c32060e8adec92dc57f0a913e3756d4aa40940aa994dd8dd8d3d3bf108477053e0b8f5385c85c6a69b68531a6e24b09eb4f8e03851debb5e500958300182d00a3b184e02b5b5047c37111a4c343bbfbbd961293273ce91b233f1c98e263be540bfca945ddc8d90e5d163d0c0532c6bab95da84b2c902260c66c7a1a837e0186b5648e27b4abe0812f8eac31ee475f54da9c7d25bd374139f76219a51ea96ba9c4249e134f049234d9c3cbbf4e7ab23118a9032893a19e9e8abde640f9478faca9dad8743e52791ce1fb0e1b7330cef2305df6c20d9979b72d921b03880ca222c6b07f6b4e7feac675e36d2b3bde81329b047c7f762332bcd5f79a031c6431480492bcc278d21eb7dc9d4c4e2183943b670eaa68010444fc72f73be68a5dc7323ba70324e5314cf430825bc979a5c97faf538193a6c412626ec887db1a2cfb6deb826989a7e9ba79c9198d2844a0a4336f64d5c6bbbd8151ee96c49b4f4737beeda03891c293638c0eb1fc4010665ac41e904160f96acc2e0428e296da019c0611b76321b14082278725984ba8c44678f415d25bd78284aab2744cbef08835470e450f610176a09b64414194010c2d504394eef178079b55d95dc38007d2bf2652b872f09fe95492663227908fbe3cc30ab434ed9605eba7f3287686b443815d8a97e47d90407a0653fcdf2cf1ba3ac2ac124532dbfe2ee1ad8509c306d30f704856ab98176872146478d2d12bb14d3bf700d2076c11c60ee5c75e06f0a36b8019609c263a60f5e4ee431c367845302238eaa5ca4ebbae939e69c8f8977cf3c33235838fc0b0b6e76c4ee06392fc92a37e017cfe0e82c3ad75fc017a00a133fd498cc6f438cd9fe709702005db89fa86be2843596a73c9c34ed7a3a4c109d285dfb3c55fd9dfea2e3217259696c132e0edc38faca30a1c9c96a11ef98d7db8ecf544a195b576c1b458d36a562c1b89825e4db9d7724414f9dcee5a95e93e0e04b6642954fc828ac70f0f12d03ba0098945d157126392b500a30e8664b7c246064ccaf980244d32249b225424a536abc8613b4c59a1ff4c2a2218333a698f2305a28ca4c6d8e282484edad0324da100c8893ba5ea3f651d6e34d26acb4d04360f46e33aa5a33cbf1ee344410eea90e8311e4d5a55b46c41395118b8129e8ab50f67e95b6fb20c3f6b6a9830062b6018e9fa568690825853545c6ed55c0c7b4b711f0935626b6a56f0ed7d6da2503bc48f48ae9cdea96b0bf2ea4dfc1156d12a6748e6d70a9b80bc08c2a964c8837c7ee273aead1e2dc6c944e8c8a26a4e2fa5f66b40c20bdaa284a3698719e48883c2ca9dcd8011f562b18d868fd0542560385013d4602fd35ee9fd034d4c6d7e50864bbeabe6077ca6faca6cf12280dac99857d4e643aa9acd583ef409b1e62c8c7514d8f6d1d6607f972940abf7f240e23be2194c1b1377e293cbccf36031385df8b89c2542494cf5eee004aae8a269d91f39a1f82b5513715bf58a71d78fb88ae04f687dbf5136f06497f9fd5179617fca550188ea863219ad36f501e9a65640b5881b586381631c83df6c516de14351c8e0680fa446105c780f509bc4075d7d419543072c9808cd20052f5c3acfceb9900f16e3f13632e7f3a592820f1d6422be988e6676bad998bfc8f2542587ef2532172f654e8001a96b950c12ab1b8f2c8095829dcc4ba3f59ed6e93d4b6535106225736e1610b85dda3492e6848eb5f9b5c012894be5fb02db47b8442e8174571588f8c481ce8425a5d50c18038595dd6731adeae5c46149db43af3d906b2858a735e2d23d72e7498e23f4e8b4f0578aa4ac38cb85c6f608818c107e5d9f3184c9077a839f260b5f8b7870e237a3621b507e00677f1158e45810a1ae4cb7e0e7c5c2513e9b83bd1ad9bb7f809a3f73e263ba3cc1ebf3cd357319485e2b5972512c9cafb111aa00d5c7e35ea9b535d0da5695b05e80ca0c80a035624e6c20d66ec9c410a8df77af3610405713115895d816d7940828d80604b4cc3c30f5a631ae3a47233873a304b4fe74b5710826806ad72ee514cac81aa881e96266a3c85b92d9c07c35a91f9bad4451e535e2ee1366d8cd2995760e8edfe1d53da7ef60d0b23e73716bc9eaea4134d55319b6a838345503c1237a5099c887051e1b43484bd0e1452bfd724feca8b5d07b16fa02648b19608260396fd6ac965578b6b8f10695346cba9187dd547ef4520925564fe14afd1620d9014482018b9c2c6cd18aff8bc563181da669ad245f14f150d63688c408388b4c1f87c5eb2b6d8404df7779197d41e6d62ea16acc7d810adac7127248042c461416ec8045af2133605afa6d0657735a723e59252a5ad712d38c208b52bc29e67905af246877ce0a98915f7392b5a146ab0cce7a032436e2a6ef8a4eee04e4ec473eb0a03b97cccf18b1ada6fc6c773d43131e807a76a9209721021c955ae9cde1620a2f2ad3aa91308e3417d0be02984c327dcce6b973654b0f2e1c452fa8a35395a1f99f4937463e5f2585e7a2919626d2d806f95e6e13ae05d2cb045919583f01983e4b4164883461f7d4c60c40b982fcf7787918c489fe6482f9308a90b3f288e200e98ea02b893639238ac4bc133366340ba6fdd976d220e52edb7060a51d46fd2c97ddb0b9da9becae3f39a325def4917651129095c88dcba0b6c43e4109e6cb1507ed1330bdcb5a24ae0262e189543629c42648bd91110fbe067995f298111ea6a8c054b1534397eba81a29f6a35ae66c5f250c875d3efe2015dc281b7adfdede88668b5a701c0b8cb44f122e5034fcd6db7c60c5f958d40a033b4d6e30551538db4c413998d395cf99dc28c26fbde8d15b17ffac113b0a295624f5af10098f08cff92d994bb36fc25f392ecd9608895d48d3e4deeeeb0fcf4cf832af6ab59bc45765631966c22a31036ba603af9cf1b46f90517109e85c778c4d4f7091b8ac1236be9c3496fd64fa01e33e77bee1def9a37e5a477b1bd5970a8b19077b11a4c234b51e90e91803abcd8881c98729aceed628950ebaaadd9dc45d5869125bed0d782a0ecb18962aa6a5f99d8a8e4b5834d436e09762f9ca0cfc0d10c27fbc230bbead8936b11031bd7cebad500ec150aca6a669d064cd24f62822c30a49dc9eec20c89c0d7a046e0eed4065eadc856ad89d0099701a4a705d52178968c11ea338a0e6f7792c7da3ab2566520737150f018a220ab610a0611df677638f9232b42154eb6851584a5eaf322b4f6264a57365790c8c4460f2c0c30265c2424985c18a6a37088a1be043f621221d68d5ea867c751e51dca7d433c1b7090d9630f9d2fe4dad6c197b1fbecb793166bfe182aab77082266d209b6e8761f118d245b8caf8e6a0f67d0d2a6d909c395ba4357ce72dee45f916ad5643f42f0e61045cbc2110fa8940712514d0fdd5c9511931df676aa43c633c28134f4fd0561774b91a38d4c1dee028c82abe302fb2135b14ae6f81658ba6e99c805b845134612333fed210573038efea36ff8960853130731f13327e105eb78d8e5c17c6cb0d8755c5e1d448de795d0d7b71e70527d2f6192b76fca2aee41ef09d47f3a1cc7a679efe0f38aa1a37cef561570e025fc415f34b16965dcfb92c36b5d7bed5f5b8315c373f6561f902a610736682d9c530f534043fbeaffcd560fc00a62b736ec239d9677123f1c7dd70c3ee8c5d6e0cf1f97370a7217c4abca93883cac75ff8efc7e60e6e2e0781db9e990783fa1430347666797396c30b132c268b462083846d03d7b79dc73cb22e18d9f5b4372337a3d8cfdaf3b001ef10d904d4dfc44e137562163d7007f78755ca10ce77e606f3177756769a183f09e85a543849ba1d0e1cd8c17f06b6e56acecf3dfb36d8723e3f5b4a193501d836c55cbe3952d9a76be75facbc8f4c12d313ac10c10d8b26554b8fd535ccb00f77a78a322cae3e59b178753a2b98870b44ed3e39457ba742a0ab01cf80c1bf692251d911e3166d3dd8ca70ac29f5519e8230464c34c446071ac16acdf4fd0c63e394c4b647e3105955bede09d996af911fcc17b1692bf0b7933dfc284e119ab6b41d25cffbb83621e7f197e1d29a38431174d6a16e7aa77782bae5bba03f61470a237030b5ffea6e411b8c0b549e9fb292ae157505c04dbbc6b1417459ae1b080e3e55a42eb046fd1973fc23d3b2000f915e656eeb68ba2cc22ab1d30c7b38911c7b3809ec32d1bdc74c65071cf2ba4abbd3b929590953ccaee9ec704a26466192d9e3c92ddb67c599551254cc947a88e03c263b41678967b7f6da4a2099942eb51225c4b844701c458d5e215614f1636cf080f22e8a3c2dd9d9e8f1fe4e05bb17232f33d683bb6bf553e4917e7eb4cba24bca45bc2856680b8bece81c50c9c0b5a00461c79e3e61cc8a46d74851b1eac6c9e2604b3e4a1c87a4e2cf8e3e42fc5149db0170362c72be959dbb40494501772de94f23e430f5410fc3022f69145a4caf567564e917e2dc782d0bec47edea99ce2bf44cbf2458bda0ab87e4a3acc269d4e6ab2f7a597194c1b260d3636ebb9540fb1ef1dc255948dc51aad418b0736529d53853ff32158a82ba200e6d975e6449477b5005249fdfd99940e405439a21f9e6561f01840e0649a19e313474a051409b904c5e77b8cc12a14987662ddb0b8e95b2e7b2747d2e76cc707a6ba11398388ccd30d5117053226db95c212c279d120c2ac650840b631abe4ead437c85dfe6045a6f692d377bca5385b2ba6434461e681451050702d3fc912c626fbd8dc5578d146ed438a1e08ba5538aabda5af70345f237951dd4f7c4dcdde4f7024e03766f7dd7a9bcce017ece8119f7b4a9f8dbed2d60a5d4e5181ddde0c56739bc5ccca3d78f1a4fee09f5b87a33a100dedc66dbe922795e39bd07e8da8762be11b0313e507f43988b3c5ffb8cf16da7f57ad955eb11f080b4ff31f2169f25d1efcdd67e02a91b1508c95e7127a36f245ab1d887e6194a10b2f967e587c874ce8e2fbe6e20bc86bed816e1b9b93bcdc8d7708b92641e8a3b8378c6521fd8fffd58c3cfa551dab73ffc7f04b9b9eb0cb77e5ff4e366de9317f7badcf82d1a7c56021e4244760a2e70b4940e000c30c000030c30c0000aa0a92e526ecccfd2fbb974b673535252921717c34ad6064ad6064ad6066c5d800aa40a610aac4a0c338fea3934c20b361443bc67cc69c57d3f5e434993448c98ce6a1e8e5a78a186425a8739244a565f75d2500c0d1c758ec778818652b769de104a3e74c42fce500671268e60d40b3394f1847bcc31e97c7450172fca50f230bb7ce8a92a7d4186b266d314c7d1b78fc5118c1a4321a6a379e70f53e08518ca042fc2504c123f596140042920dbc00b3014671e670c9f2d3156ff42d941c8cf79ef593eb517ca12a366d37be77c24bb50b84ed2fde94d2e14676bf671e6bef01bb750b2580bed0cd70b2d946ae76e32788e6953ce86175928bcc7d459a25ccc67140b65d049a56f6396861757286cd650e6dec8d3853d8005d4175e58a16c9a7f1983b4de8216380bba1330000c44e05e54a114d22519a5042b871b2a14fc2b436ac9ef148a217ad8cfa9c3536d2a8542838f517782a9e48a0cf0220ac5980e246734c88c3a14cae03a53cda5bc86fe84e2bbe3e0158fe1feed84c2c3f8d518378b66bb09450f53cd21cf6c43870985e020f5a3968701ce820a108000e58216b80848d0c30d6fe1c5120a293f5eccaf4a2863f079a2db41af9a4928e9a39f90d4adbb4a241427ee366a91bbbfee08e59fb1d0fb6c1f9a7a2314ce245a2eae2f42714343bc329678f810a164ed9b46d7338432d01c93533ade501e21942a22e2746d7dfd2608859cea7e9c5b525e0b8442da8dd1e04b434bc60f0a21e45c6515faa0e4936a734cdd23e37a5096c92a19943b9a889c07c5569f4ce3f01d689f41d74171a25bc3681119b426078524ae5932da17382837460f46a3245b7b8bc2e66710d3366c51b448aad3a1518b6206abd08f11af25b4288f770ca1d9fecabd5914662c2e3c87b4bfcba264bef9fe9eea5814e43392a6861a1685ea8f10cb61f0fcf62b4a579a2dd6c4537eed8a32dee8749e752bcaa1fa1c58e6ace9ddc38ab274d6556c74693fce2a4a51361993d551456163fac77c87f3189d8ab2de4a7f5e9667d6a8286c7a208fb3738a6206591b771ab9871853145743bccf38aa36d294a298fa5dd2fb542233a4288d6b5c472d9b5194f1cf67f8dabb8959238a1b230f07bdd15014345bc4cecc874f27280a21744d985744ede4270a31a273637cb5fca027ca2d8fb34bc34e141d7bce1cb363c6f8e344f1e3e3f8e0253cd79b28382aa9cba89eed68a2ae897127ae994c1442988c23958d899264e6497edfac3a5fa2f858ce1e74480d11b544e1e3c36815d61f9a56a21c2aad37f3665d9b9428987b87c5047518c449943c56ddcc71d00ca124ca923bf4c71c924fe422512e4dbf8fdcf7923d86441966776b94e7967df1238a6b71faf851ec88b243cfbf67961f33d38892dabcc4b4d2b1981951f0e85a8b075944394634dd28dd23f52aa2ec73a999e3bf8928874c7b8ded8eaf3582887208b13454fa872866101d86d590f69b1ba234c9d6a1a46cf7cb0b51ccd9d7632dd24b3f4b88c284f107b136a6d4780751869d7f8f23bb6a475610e5d2183fb5330251d6924dc910feed1c802877c8909bb234479e7f283c88d61856d717e2faa1341dc663e3db9890db3e14e29b64f42b9adfdef2a110e34d063656fb75ed1eca1173ece8da75d4b71ecae9d8ed1b8f86433b0fc5bb5bd973f81b8d838792b545a9e7983b946cebcef57625488c1dca69bcf3ad6ac41f4d1d0a41420a4fb96ac7613a147284df878ce7505ad1902cd2cfc46ce55086e96388a9524fafc6a11c312484d0713bae83436926f23b6a655d6b6f2848aedb2751871b4ad78e1a6d28ba7b83ecdfeda0aac186f2a7672cd12e33c3d0584329cd357dbe5089110d35947262ab3a7c2c82270da59ef4e06d5d4bf28c8672d8847ecd3843216446abf5e9f9cd50ee0fe39e717d878dcb509ed4b539a4cf9d2e2143f9adfd524b227ec68ea1547ae9ee1a561ba7622854844c1362668cf285a18ce5e34d77acfa1f0ca5741cc6c5b22f94543cbaab87d40b856c98ef53c52e943573b27e3b49f65c286cc5e7b488caaf780bc5fe20d18f5395b6430be50f2b131dd93aca9985724e1515314a668d392c14a35ab9e757cc392aaf50b8aacde91659a3a4ad50dc4f9d2a14a2fa4f67d84dd3182a94263767f4c5a96b3c8542f88346ebf35712ed097800042c208014fe89deb02fe328943673e286774c99170ae508cde01388909b69726a4e288d94865bf96e861736a1e4b85d3388d5cddc4c28ee9a4da3fe2ca1609aa993c6ac84c24673bd168fc11d2409e57f0c6ac3a4ce3b09128aa983b89dba47283f8e105232f617758d50ce0d1f634db9185d8b50f0fc20d339c3f3341e110ad1ad1e42218e85c95d5e7bbe855072d59ddb48104a9b6972c3395a3d0f100a111311923e8de7fd41c1f3fbc3cd6dc7d907c57998fb61983d288470190fca208e44fad46db877606c6fac521e1d145435e5afb41c143623e676840038287f6b6dc38ee9f6718b82d56e8dfff778670b8247fbf4ae7d2d8a9e22a7fed0d3a228936bb2cfe166edcca2f0f2199b7363183a238b32caf6380d9ada1a2416458da13d68e8f0d2202c4a2d91673d48f58a82838b1c37b62bcab81ce41063482b4ab1de9367ccbef3654531b5beefd345e89c5d4539fef36da7aa28b45da5ba4b7a87a6a28c3a22f7a7cde1930315c5f1dc33f3dc298a41d6f5ef334539d455ecd7d5a74c4b518e97d7f13669e41492a238394dc5476e1465fcf051c986e7bf8844c145280a3f1d9ff1e4b8c5d8a028c388ccb097af4ee3270a95d67d1bd6b13ee878a2b491961ecd2b5f67ee44b9f3d6fa63ec0bc7124e144dcb3d73bacc50b3bb8932ae8ed16198a73d493551c8eb967df4a1c6379928399ceba89b93ee6689897272fc59249b67dd8897288606f50e29ff111e678992494c8c22da05b8a84461dcd51b48d887879a0e5c50a20ce557353fda4ccfbf6ce06212a5b919cd1959756c3e06b08033702189c27ecc79e41f7b0a1240000280a0bec04524ca70d37c4b1c1d12e5f4793447b5e611e5920c69ff2482bb795c38a2dcb35fa1e16123caa82398c62c1b3acd6652e0821185981426d2afdd9a365c2ca218ad6f2a72a7ff7e89042e1451aecf3187ab89110217892883fbc76f9b3bb3f8c705220a1a26353b682879b93844d171b68d6e0da23d14706188c6c374be4da610859ce023212847d5f02eb62b5670318852c464bb7fd654f3c81b702188d2bb453d825149032e02518e321925a5c68e310e40941b47c823f1697bfef943217beb448ffc688e3d3f143bba3d6db22672e90208741718b03e9423ad9c7af8501bb8e043e9537f63d7d4501dee3dd00bb8d04311a0b8c8431987c91f21c6b48e63100fa5fa8679f2dae8838c7e81bf600577288efed9e666c8e083b4062eec507ed5b4c731731cc0451d0a39ac9eac6b6eccf800c172810b3a943d5568fc087f6d4773318792afe7b811f6ff315d2ee450465911f3845cc7a164a32351fec0cf4d8343313c083fb73e9b55e3084675918252010946d08241052ede50bccb3811b2de5d3ddc0d658b6ef71c6248c62fb96843e1ccbda7d6674349634c194387b4b7915f43a91a5ecedffab67ec5822e0840801170a186428cef161e1eeea25dd04517167880bba08b09d435176970354ee370bbb1118cc221708186c2b4d6b55a6896c0c519ca188787d7769ed2d3a6cc40f2060ec4c3b17bada416f7b4ecbfc90eb8284321328a48499f1bc12823437144ddb3764aa7c0c5184aef5ab129e3c68518ca115b3f46785c84a190e35ceca3f934da0c14b80043b135466ecfdc1862fa09109ec3db1499b124ce2a43f93c3a4f12c973310919ca62edb9ce35749a5a6b0ce5edcae811a266652831943c7c830fb1d2ec7f2319a83014f3f5276dff4e3de3058642dd07ef381e624aca2f14a3a5c32357a4b7e7bc509cba95903b2589631d0bd5859248d0fbed4e75aee6148a0b859ad7d5ffd89d7bbc2d9472f75553dc63cf505a286de34a471f54228b67c9505928b4656c1022255828e5e9edb4d548cca9b9c230b75bb48b07cd50562863243b0dcfc155a0c5e23c2b8336c6505428b4a598c4f0f2386b15829a42e1d37c908ca30715d1a4507089397f26f25d74d1c3865051288a5a4dd4ab5f78207011b00a40a002d64141a12caaabf95aca118040052878811939a827946eecf1abcc3882515783724269247dd8e884b2504d286f6cfed169cdf3f25231a10c25a4e6cd187e8e9dada82594a3440b1d7ffdf021798116b8c05b40fa504a2867b7eb7dce2bd391f0a19250de146b7a159d6bf5e5a19050725c951e9b2e02108000297014b880ea088510ef2488d46f84626b4429098e2f42c9b457e42ef2638e3e114aba9da2d3e664fdf02114c2c418c4bfb7546f2194e43ac39ddef58b70104a3732a71f6364690408259bec1f83ad75e6f50705919192f7cd1b77b90f4a2f1a3e4ac6c1d322ef41197acc888cfffa3aa7795018d5a4d1c3eb6ede7a07054d1fb41b9547794707e50821ad9da60da69bca4161c436571fe867bf8583628e9fb24635ae8653a90d0d357a326d517cbce99141f0d4a21032fd310c261b1e1e5af0fa481c3ff0ce2c0aff7e0d3a63676c7464518c1ff7f389481ef34d2cca0d24633fce8ff658038bc277c49a1c6d19f333af286ffc9879fcec8ac27da3dc541611dae55694b4771a7bab45c3342bca923119c9db6415e510ca51a8e6aef218a28a4284da13d51c21824c5251c626629399464541939af5f9b66ffa9ca2b4de1982c6c6ed549aa28c716d4866897a3e96a26cfd9b57d26d16ad9614c5fe48679ae3c4098fa2e8fd1a2ab3ae114529c3858c833c14ce3db4ea9c4f415128bdaa8f777fa25ca2c14cff633c51d66b7598ad31a813ad384e53b38772a20cd35afbacb54313751305990ccff71b84c6966aa2f8e9f756d2401d4c3213c588cc20657d42a7333151d4e87ecf71bf44a9e636eec3db63842d51bcf3f8f5dbc87a8c4a945c2344e4544a1442cea21a4ad7ad229c44197bc6f6e3adb31b3949949369466ddc7b24cae3126673aa7ec7db41a20c345477e6d4b2a57b4441d20707993323b59b23ca1ee62972c333f2a91a5106a31d2b636866071951d60eff58ebd9228aa9e2376d624a11e5f9098e1ac62b1145b7da9ad4d04b631051f8e0abf3308738475335fd185a431422c33f483f294439e3501e23633b712c21ca3063187db60fd237681085d4fdd07fcfa8f52182288609339a32e7b8b9ca4094336e4bccccd9b54a030834bcaa9fa83e78017004fa43c9d4ffefe3a6fd508e09dbd9d7b6c367541fcae91939f8f8784ed7890f85d7d89189fb28d127b40763e364470fe5f4b923ff66dc212db334501e0ad3d9faa1b85e68203c94d57bb3c5ec640a7487e23dda709b8c61875287bb03b19f5c1af37528ac9f48472acd8f99d2a18ccbfd2d250741d00212a81c680ee592dc7c8f8dc2cf6f3914ef636375541c87d2fbe3bce6fd99325d381447b3677674ac213a4f6f2898c4941ad5d8e433864581012c6000160038901b0a99730e0f25d4415ea40da5d78e4725f33f81d85068541aa3ed685a4349547b3734378a0e39524369446334f76e4b6928ddaeeabcba030d6d69c6a78bf75da03394545b73e80c5d7fe23833144de3d27d23392eb5ca508890e1a7aa3e32147b3bd5573634c75018977dab4eff13cf144351ad7c0a43a9573afc7a85aa468ec05096f38d9c1dc8a45195be508edc7caaaef5c126455e283bcaa492dd66d2aa9300d0037521b5fee499eea384a41f880be58cd239cde7acc794b65018c79af399e65a2026c94059284bd664e9e835745772021664e0055d9ce0052a78010b0e61a13466122e6d3a57283eb238d3d28d3e3a9315ca9a43c8f5f7c8ba3a465528b766b598c98a9d58890ac524398720a69f2994d3aac4db1b6d58202914328e28b1ba53e3bc178542ea77c99929de3c3ba050d6756de99cb3359116e809859cdc4462e8f618237642b1763eb765d8a809c5554d7912f24f4c285d454edecc1c5a42a9ab6b630cb255f791120a6b2719bff63667a3049484e2ff4966785ced0904ed5df4c28090500e51730c5d1b9137a477043a4261c2d98a36babcc9202318e52e20010b6270648472f0b2cecee8988a506a1c16ea1be2d9cd6403c080030840802e4e6001200211814cab3e35e571d44bd0100a1d4d36b4e3e6d44c2d1d4808854a2fe9f48f4b248f0305a1e4206fd41a11dd40402847cd20754c7b46ba660df483820789bd90cbb1f4181f1442dedaf48ee06e32f6a0743a19a795473b9a7c1e942764a3b4ce4a3b285fb6466b44e867dd740ba483428bb727918d152807c546b10d6d25a40a84839247de891c0d36a6e5b728d586a49f714caae1852d0adef59b19c4768617b528d8e53e9e36870dd6a645795af32a3b648bcc661685f33035714ccc17b228379aee7fd5ecb425c7a2f867b9513da4f873191605cd69d79fa3323b83af28c70c4c43ec9c889831ae28c64d7a88f96e2bca259bc4a52342a6ceb3a2ec307bc831b1414ffe5514d63f5deee74915e59026d4da8e79862fa6a23c16e72182f858c9898a92e41eb9f5746edef15314aabe7432c619e3a4bf29caf97a1926ca2d45316a4b47d39c56636d4851c822b93ffaec5194f7543534678cfc42154569f5afce35eb50944532160f6eab2ee30145318686928eb2ee736a9f28a9f45b6f48de4e19f444793c8dd587cf3bb1f5c78c992a269c2889640b95c90efd19dc44e9f647d7e5a6b3c71042bcd044d1266f6dde706a5e1ec944315c63f5634f1952c74469626c67f0eccce5fd258a39397c52a9d790e19628a5e35e930e82e14525caafb976b26d676afaf90525ca1f579fb19a2cf2e4002f26414e5b2e2f6115075e48a2145a9521f52d7aea17e145240a11abe53363d03dc183443123e48930a1ef613a20e8a21f51cc5bd399418a8f9b7146302acd1185d9897022190d21bc68444145ccd34fdcbc12230a0dfb2664f1ac35082f1651ec89197c33e99d5f070217780bee85228ab17e32e2a81b034f010866c002179017892864af59d9af57052f10513a93867946c23f47ea2660141ca2f8e0e454e34ff3e3d5107ec89ea531730bd8052da07a5188c244ceac6772d79bfc110c10a4a00b3a2738c10b1a4081148c13c01c5e10a29c1fd8a84ac665fd5de4e0c5204af7ee7a3b0b5470d018f14210455ff706f1675bc516b8c045c002c3a3102f0251ec8bd90cbaef6536ec2ee802062010410ab206f1021065e815a99127267aba6278f187c2fcbf4d4fd506f97904a34e7002128ce024faa16cd38de174fa58bf0fc5e9f0d1c0ec737b6752400210b4b7a00b15c8c041d002120ce40349ef4bc10bd0f0620fc58e0e33738ce68f62167895195ee8a150e7d1e53c234dfd9ce4a1a82149fc67b6da68911778c0e168d2f21ce35baf3dbcb843217ae8c9cb7a8c1a511228a05ed8a1188d1f787e66000b1859785187324e1d4a42e494dfd3d3a10c83f7a4081faae0055db0c0018a851773286ef293c712429ac60fabf0420ee5d510eab3f6e41bb424504039094e172dc029bc8843b976cf651b7ffe6a8c177028a665969df0e20d250dd395d2c97de186427c4d0f22ddcf84176d28b901c97a662878585987fe39fe665c19ca9be7ff22d4afde7c4786426d7630fa1ed9f13c79b83114a3c73209194d871343d9c7835e4c978766abd470612875dc786feb98972c83a16cd79911abbf2f10e306b38e5451e1bc50c8929376a134b7a3f3e9bb45c26709c78572cc132eb7693742354409b785c2792747bd3217e1b4504623adabe3792e628408978562b4b94bae463a91df65e1b05090d7cdb998d0d5783f2bdc15cad03e7786ed70d42bb14251d73364667daa50b4ffecc957f437832c168e0a6554598f77a64d66fc29943dde3be3374f154e0ae5903f64cfb83b4e5cf1031785f2e46cc402078532cc1f9edc4ebb34765d9ce0740a18046bf584324e9169c9ce13590524700108f204e78462928cf6a3b34bde15af09a50d9fdc3fd5c584d247f53d9e901d51da5c4229235fa467980e5001a3e098704ab04b82e2b8b21ba48c0c42558ac69cd363c708461d9541914111410a5ce02820c321a1f8d52d9d71aa3f52734728e7d7709ca275ee41d98433c2931b11538482d5c6d4fb716a2a7722143d5f62780ca68efc1c4259f28c5a4ff2ea54b710ca6873b54e6ff4e42e0885bb8936e2c97340283b0edb0eb3c7a4eb713f28d76f9610971a3531e67c5030f98df461623d2823c9beee911bc73ce14131223b1edb849cccb78362cc9e3ce728d16d3d1d94eaa3373e3df58c8d870d2e07e596cf8895608d3ec68783926475fd4998dca29419ab6959551b36daa230d399336391ec1faf453194398a983ac7fe67b4288b7b08f97149461fdd599443cebf4d723013796551aa083b9941c8f8b7da5894b323eb37f00cb2da8145c161f6eb7d365e519a1af3885122daf97145c9a1fc67e8ce0899d256143725ad449993158588e93c4a88731585716f7c9e3386a9a214a79d7b3be120c6cd5251944cada9a37fece0932e34e02ee80206a85a3054f4a77af3290aea9b24fe5b638aa24eae4bed5413a71fa528a6641c294a6dba6fdd1223368a2d1f7976690755c0022f30511462caa22667869bd3a560a128c3fc1f57eab5cdce1ba03093443651d55816c13e51520feba96352d648e389a2fca48a8656796712eb44a933482bf2ed9fda27271827ca799b1f6434e13a566d9b7046f3872b1b7308a689f23ceaf041cb26ef16402258268afef770f2f78cdcac98287ba8569d3af30c13bc4469c3dbc6edc71d3d78962894a4ba960d1b42d24c258a91f1e863e703ff2452a2389dafb7c1674f0d429328e41fcf7ca95a12a4b7cd9cdcf046a2b07133bd84a83d462b244a99a57f19f67b44a183ca78580587558082f28139a2a0b136a32678360bdf08d688726e448a777f95f820398231a29c1d47b72d890dd5d13fb045fc714223a688b2fba7dcd4597736994494b39b9ff73446bd1d4244411dc3140f3a8a7eff87285362c8a419e40d510e1d6b93761ca3fdbd1065e8377e1267be5b6f4294ac3f22ddfcb38e3d88d2e6860899de9f1d13445162c3583deea43399401422fec76b5db28b0b8842e408d2b82763ccb77f28544984ce5aed3946c30fa59d4c1f3a515599ec43e9936d6ef0b2110f1fca20f8c7381bcb3d14675e3cfb43a8876224b9ec96fef25048bf992a32c69ea2c14331c7d08fcea541dbb3933c880e77a62a3b94fb4745ea3b9f669aea50940913dff7313a9f9d0ea5729c9976de3efce97328845489af2167ccd97239146f42c3e8fbe350b417f5ec267926730d87d2ff7dfa910ffbdef51b0aab17998efdc273dcb8a1fc11cf51c3505999316d283b90d89d3e969e64980d654f11b9d3a7c69f425e43d91cbd745e4ed450080d2ff110f3e67ad35008aea6bd352d1aca11bf1dcc83c6194a99375fc8e498a124293d9b1197a1d8f6991d9222e74d92a11cd656227bd431143a7fd68bac413194cc91886128558c438d6af41b210706454cc673e8f1be504e8f23b5e8a87498ce0b051d6feb7cafd1dcb62e94b351457bc7b850f618c5fdc3e3c698b42d945de34f9c456437cfb450fce88854978c21ed958572c4b74e9225168adfb39d513acedbb0ae508e69d2d664067956638582bcdd494c176dc9a842a1b67d454365a77d5428967ae59d87f4c92a6a814da19c2b9b2649b87e5caa144ad7593242de4408f12814f67dab5d34acc894502887f312797c5e7a353ea19881a65489bd63d0c5020840801874c1021698130a9e8d24e67b79865635a190d17ace5b8d1d67b78d0985baa8c79f69b225141e841cba23f6287325146cec53f49644ca4f05337001088a019684f2a7fbb0d954f2f822286801c760140bba404342fa1a9212e34823187552f0823708942a25010a5ac03138801da11053d59de36fcaf73742a9df265f422709fef92294d1f9758612791e8e4f8442446d586ada8750d6e00f3cc766c28a2e84720eaf0dd79419f7f220942f3e3d7e8703a16c33b2b51a9398487e50fc906e22b9b235783e28474aab7cbc0785488e3287986a1e9495311942c5c77650721c8e63d3a456951cd3413933bdf3867fc4d58de5a010f12d936674f84cc6705090aa7f511f8de71edfa220ff6f6ef1dba22c599ef9333bff36b528dbe398cf7f71572f2dca29eb699d3a830ee52c4a2d9261fc8f9b0dcba28ce14a48ff911ed99158944ed363774cd1ea3a2c8ad5d958e75a7f32fa1525cf29b267ca7cd0705d51ce7e7d749e2bbcee56141e6ec3f27cbde93a831585c75f71b67f6536925514e54e521a9f740379a8a2e020c6244fc7dde0938ab29707eb9e9c32414645f1fba77388e4df68e8294ade386548f89829df14a5fbdc19464ebd14252f4df160ef8e3f9ea4287afe9c3e5755e31093a328fae69a984d8de7648aa2a40f7ad65376b6103314e9da653efd24f1944281c2499fb6633cca4f14567f3f75c6a0278a699fedfd7ef2cfc54e941e4e5d476dc88962b8cc217a7d7538083751a8099f2497b929fb69a214dbb8761c573cfa2e13a59c98d140e481c6779828898cb6cce897283f90101bf74eff6a89628c6d4c0e53d96d5d8962f8ce1fc73c644d124a94547ea443f4b3b66b64bdd14cf3fa4b42bb6d90b73723184558e02d381e54244a1f3ac3f4a0d3a97b6c2151483989be31a71e51948ff89235c611250dde1a1fbdf77c48230aeda9abb3f16864924090a502968021a01851b4c68d2ff4a1df956711c5d278e4e531f2b3271551108d0df66f3c8938acaec4d0a1358588426488d11f7abb4afa5870012a401da21c3b84eb8e8c1b6dc7fea00cc126113d7f87a107aa10459b4d9b53ae7e593a21cac93d84a309b91a4459bafb24496604518e8e4d6f2435fb6ea302510c1ad3e0248608e3284101a2fe50042044f941b5d7368914a1fc1fc12844f5a1e0991affac5dc000f6050db0c000caa8507c28b56a26f990764bd31ec1b0000108c002af62810b54b084da43219d6876f44666ec73e9a1643b495f33e679a8a3f2700a0f25d1640de3f4376cf72004ea0e05cfccf83a84fb6d98ed5098f4fcbccd161d99aa0e6dd0f3c6314a0e1d0add22c9daa36fe2ad3994c3973dde37b3707825224a0e85b0be61443a2544c5a124aa930644c1a17c0f92c4f47f0ead372b887a43396574d2254f086cb9a1e43987dc6033a7fac1016843b5a12cb2f52ea29d3eb2e7856243c993489e183cb6d9cf38875a4321fd9ddf59830fab1ac2a1d4508ef9ba2e26fde7b0511aca92414c584d1f341437d8a5e69ef0a9eacaa1ce50ccbf9a7cbbbf194a05e59118fd57ed34575f4461d224b78f28a2a47ed6a3a92336499f8872248f8dd214229ede102a3db37e88923836eb184e374469fc31ccc9d1c7a4a30b5170b03d16b62f2ee14388d237a8963cc9338862b4dbf840d7cf6386200a61ac2e36f678ed650251ce50dfdfaa0c204aa692c4cde17ea8fc0fe54dd620d7c70f658c4642e3eedafb461f0a6beba92e1df3817ae459e24488f75076cf9de23ac65587e8a1a03f8e7c6a33884e1e0a418344a90edf1925c143593b9987ce17dfeddca19873865d11dd61886b87a279bcc77bd4504ddc3a94dbf33398d20c3a94f3fe9fc6ea750e8560efb15355f36843e5509c7d705d27f925a5c6a174a5fffb333ed6208543d9739ced1cccd6519c6f28fb741049b2e21de274431998a69ba026fe20876d28787fb668128f0d85fa8db05ef5403dbf86a2976eb2b18b1093a38632fc883a1ac9221e676928cd7bd67e779d8c3a6828bd548e830c1e8fb185853c031db777c5af73cc5048752bd511730aff983294f6638e983f21ba1e93a1b8b5e9f56a5121c7508abf7ec9729fab8c1143316f4b9b499e5c8d69180aa90f1e5fb449c6196028fbc6c939e9c48d12bc2f14bc25ae697e4e6a784d21bd509cae8f0dfeef42d96b7ab3a977c8f673a1981bf74444bf88b7b750c6ee6da731a38eff68a11831049b103d27799c2c943c06db6ad160a17c8e3f59249fa82db94221e69c1eed86dc0a75963fdcb057a15c92d327879a0a85b8f629e2fa14ca2211e235d8f7ceaa148ad7f29bdc247bd8d551287c5de847be2f5ba9a1508e99653d116c25429e500ce1ac2eafe184f20791b7c7b3fe8e6b4251a33eb637769850727bad4d8d9d2514b36dd44648cf17be51427137ba6e9e8ef6fc9a24943a3f4c7f888cc6f148287c06d349f5365727f908070fbe9b71974628c6ec0ff765fd3e06b90885e497d937e7904722141c456798bb1f426132d3a4873a1142415b93e67bfed78748108ae932c2d7c38150c8f16db1ee0d83cb3f288e468624af0fca18fc4e671c96ba196142f6a078da12d27f1eff843c28679c365eaadadc413965dafb9f6cd6d49a3a28a47410f1ffd1747e68e6a0e4d932f321638c849a38286c8cb2b11a8e4b2abd4521a9a567cffe19c4326d51889343fbadcbfe64590b1a66a7476e079016459fbacaf2f029217f4cc05994be4cd33dc44c571ecaa21c6552e33caf51372616659bdc77ac22672ac3a2d0d55d11caf5323d5e51f2fd98328bcdc3769c2b8a29d32592d6521a79ad284c7c6c1f3aca698c8e1585f0d00fd27df3f1b38a92c324792aed1373d85451887b1a624a183d4b2d15a5949dcb9adc382a202a4af9206470e73eef393b45d1273508129133e8da14e5ac3df14e34578756a52824dbbba86ac7f2a82245c93787915b4b3ff7979cd26ff8c1e324a0280a353a1342464251f635899edf715a7f415196cf48e7f04fdc1293951d424fe899deb3677c270a3ba99f421fcf89231ea97f364fe56f4299903f26499ec7d7441abc6dc3cf4411352479eee03d267cf55c7b9b21db7e894332eec76ba1d21fb7c4b7fab357d31ef4e395204fe68bc88de2e3943063d5089d499467f626355792b8c61e630cd3636a0c8f045123a663209e3a24d4e0a621e88f28b3c3abe8dc11e6c818ed7abba98da0635a2fcb911156e8ccbf74fce4b80863dac818e458ee372ae2f8cd7fe3f844f0a2da312188c073533d3ffa10ed9b98637095ded036c4283feffae464b20bc164fb6bcd988d4d08d3a33efe60e320e890d7d63787a31a0541de48677520f8aeeaeafd20208831feb3f563bafce01fc8731aacc14465fcc0e7f468d6718879327d2859dc74c4dfcc21321f460ee61a670f7c4c0e3ebf2da91e3d94a333fc344e461ecc9307325ebd7da877f0c0bec3d01f6fe2bc7387d54524a675d4603b589e93a70f4daec3f51372c8b76a31a183fa1923c6d509923998f1ec8617e5c04a46caf509b161e2708ba3fb2beb190d1c0c11b78e1ce989e60d9d8e398e279132e306bd432489ca07396d184bd9ee6d0e3e1b76141b526ecc1acce8769d276a38d94e7c90349434a7ab8a3b190d6e47447744758ff10ce6476b9b3736838d537c1855d96c1997219ba08da23f474f900c4ee62c19a3af04c770d2becd301ecd542206e26548cbcf7be848128632ba83e99220187695c81fa33d44f2053f35ec852b3dc68c60171e6b8fd2987dad29825c306609a33d11dcc252adc937f7c2a75ed4c2601e8c4f748fce62164c963949cc2216be725309f70a9564b3c858a1c6e2308f5b054be6c1cf630c935420577b1f079f700a86c6e50f3dc93aca560a667f701b8f289012ab8166a5640714cebe1d39a3b5738c2778719e71326685c30906c996db878d26901d235fc7e5526f0d260cac5b42e27fbb5157259453c6f0e34926b37134094ee3c99a7d1e9b22618c6fb2f6e147e8b45c1f369698636e041d6a4c9f93755d84dd7d421e6b5d8408668fcfad791c4236492194f4321a679c7e2863820083c0d5ce3bf21208e69aa98911e951fec0601d63fc883e38976a6418b378927b3006f171cd7fc851521e280f3b84ec9e873bd8b1a3741843d4c151a3870d21e6c0fdf22fcfaa8f75c4c139aacf1db7c8ce7348f758df0c5b18bb29bda73a32b4163eaeaa8e272d0cf2e2c85910aecb3344b70967ca028d4bcd0f7aba8b457a211ae4ebb175b0b836d6346d78dbafe06dbddbec7147d8aed8af7388b5e2ca9cbdd2cc0f63c59941e3b3c9b9a11eb60a2464a4d4b80c2166982a481f2277a794685a2a0ae793a6ff34425d68a858ce81a4868c553b85fb7152fa759a182a330519269b4d568ad23546bd435b9990c2983339e8778e8ee2d6cdc024925ff556a258429ab43eeb1bab501c66ea683573961f149dc7f08bce274c21d9d3c31306cb4a07bbb154ea84198ea19877ab038913a50db9c96c42d6dd8c364187fcfba842c2224d904925c7333c8799a8cbb1c6c4ea7730319858ee6cc2918e6cf412c59c322eb3465c3df52d513607d15357dc45dc5d09bf5646e5a64421f875248f31823ea8275198f19798d73276742c89f277d23812a568f598abfb4df348489455d6f3f2e43b69d61e5170902c46be518e20737aab31b86eb311450775dafd38a9d5458c287b35bcccaffa22dcd81d43349ca41e45148249c32a8fd1d7433811a548c9d974e64744d1c1962795f01d42dfb64d91f71a821082b8ae6803ed520b51cc7882cb3edce4283384289d4d249f143912a33b886378784671b0200e9b1b63bc5b2610254f99fc5b73d6db1f10c64eb549b488bc88feb0d569dc0f7b7b8ef41db31da60f9846dda4b268209ee143b94194bf7749f7f0957f7e877a40334c9a4a466b827928858ef687479383d489873623dfd015dea1fcc026c57aec40a8533755d98cd7ea3a0c247d8ec48f666ada70742859e4cc993d5ceea65ab839d4b5e3eebd1a299543592a35af2a73bb2a601480a03d0eb7e7b8f37dcbc98043b935ad8ae75c3753fb0d441137c795b9a1f019c854d78652cee757df7061a73e1bcab13c23a45d323ddc1a0a12970f937a497d9428200106e0706a28a6e6c7703388f7c0e53414424ce2c3eaf6d05096082da96375063932ee0c8553bd92adfded028b9ca864cd86e2016930160b0502a128248892ad1300c31408000030260e060291284d025dd80114800260221636241c16181c181414101612148501612030280e07c240302810080483e9921c2302eb07902535aa93488b48b18fd372c66cf09013f19c79b16b1eefa70cad94adc77f0f3ef378e7cc379f02fee106c2af1f4bca1ae8f6bf8ff30d59b243d815b508796c424eacac8e035b3efed0efc7d6237c4c03a15984fb235c486920d67e9ce42e622e718b8f3f248468aa7c7bece0f1f520e6a1c423750f64fab879115694dd1fec843003a1f8433e90d3dc3ed1a74c07a89a58b7540b460bb45a8c1612b5fb64f5f4e365705a0a2a2a382cf28242c48e8bde9a85293a920519b41e91fb44cf8942265046a20712b04d849e881b0990331f806d600488c7dc69c4270a1063597a4c400445d724d7f4138f24f020a28890be123dd3b7dd693bc1ca09d0a8047042f3088a343950106308e310a522d049040fa14d980fb53549b81504cc5f80bcb925c9e5277a4898c6a42b21ea38a227c37711ff9b98fb09901cbb7a082a099c0dff3bc7f7634c80e8920b0f420f261e547bb07c90059123443a23844a873c235dda2ff385eeac13ce5f2aa48b4004f413344cb0244241940fe1ea086d96257021ae0f849e1c10affb5e003927d4bfd142f8ad083d896441f480103129219d6a816f9ebee9b6d0737b98c0f1a5a609b2960009074b0d6d05e86dd13099e0e80d614b7c3cfa9f5832d54b6651398860cf4389cec560d3a25e07f3bcfbd1b2cd0e267af51e23b0e1568389348b2e9f3634ca942e7a6d79dfbbecd4836e31b88d4dcc0d6ada2d70b61a15ebd0ce7bb151951b89540823fb618244f668480332941c1da9c97aeb2c71ea8b2f827b62d3f02c15e6c1d21232d6857276a1489fde5bd761ff6f73202f625b0647a03cbb0343e90361394b1fba358a6399e26a23d3237f48b15fd9db98dbc01a318e63d675bf55c66f2c77a83feafe2aee86905622132392ee47359f7dde4e87e074633121bbede40f84dcaf52a830356b7417fd35d73390c7e3f50820b3980bbd06874b4cb8ec62f3ae6c3a023e16dcf2a77f3092bb9bb7fbda32740976c9907ab552d212c987bb1e99ed886ed60e002151002828570b6078b2e9f51aaad13a42ef4c1f59d92eb762035d7f85ca5823cd1ed1d4f97be2dd1e0abd4e4d4d596e04fdf16253b1fc2d63558d58508f440fb6bb93e37bbaae20b372af40ed6dfbb8bfb465d7c82c7ad8e00b3c9299ddee9a3d4c5605667b39409b865181b3b5645423d490f63c7044788b109450d84e7fef6aa679cf5523f13040683f7197dcf6bfaab5dd23605eefda2d08aae984d2fabfc7133c84cc808dad6a64628214454eabcd5a26f6cba1e506d197d55b4f994de153aee3352b7fafacd772e6ae1b696fe2bc474784caf6eaf111fcfc55dd6bbfd1fe92ff9ce93ba6ad98fda37bbe40bd069db1dd800ca239d754af1fea1a817f8f9fbb8640a63309fb626930b4d9280d206811e3eff989bf3dbd8339f5d3ae235d71eab249dd681d4d5c9fdae3b52b9be5af0b32bbcab2e4948183aeb9d6eda393a397100cae96b477688c1c775d51ddefe496cd3e84c8a93fc4f06e3d5bd925a04a0d22b5e151b00c2d87d1bac6a4858b7aa8fdd8d8f170e1966496b5a7e14f50b9f75716d2035103fc9b8c6e69f2a7b77c549cf57a0d4f92fbca6cef7759f41c0cb1eeb83a7cf29a76d9f7031cca5ee791049f29337a0926bd4f8bbd970f4fa2b0fd6882d9e977713b99f1dd68e8c44deaf754295210b678cdf561cf1360019fc73d9ce5b59bae177bdc10db86ea8afb1b42a275ca387da0a3df0c765a8e2fa07703bb5fb0a5ce98d96dd0b07168878ba5e4aa0dc1abab455487166d6bf439a0df52d7c8ffe1781284182e30503a56f7e640af039fc5487644d7e541ae79b09ba421bc5fb7067a2f2a69cf9b62420d6a993635c3e7b35c0c0a8f61c3b00e862a317a04623f43f71dcd7583a39df89ae970516fae4391acb347e8a0aeb78682dcdc6e0219f772a663b4a8894dff88960157a686955e06147111b92c63c004479da799cdd1d7631c121146224f64bfd2ce6641d3a722f28aa456ecc8b2342fe62d6bc917c2977cf08b3c37d1cbc162efd2022096b9fcc63f51256e108b68088a91741c710d12cf41a4f4d5a55ec7214208a3b001f588776d0fd3f2efa68b4a7b7d8af1721449e139e29d41fc43e033889c767c5b7ff79fd2197421e9d9d894a0f0861acf8e790c143448bad097448174d2e388485178bbe805c2a445b69911be3e282153ca69851561bf560e94eb981e0a80409183641059e707d82579322d3ab0926944b4f6f6b5d8f2ce3d980ef933dcdec36e00175244c904066bf53046f7b4aac248cd4d55e3c670bbd177f723273d8e1686ef9a760daf690a70360dbe02eb739cfcde14f71bcb9ba8f462faec6bb328442676b4e9321756e8daa020f2d9706ada787ffc232b3d094e0472d24ac2db9746fab34869e688eb3c5a65727d8ba8ab245093400ead67729c3478f9dc333704cd1fd95f27d562c98e009939817d367399cec46f9a8617c07f77ecac196a43fc71fd3372308b7de6e465bad53e688246b7669eca42412f11c87b19ed68ff97ad4b0e1b6e6494224aa0043de17940140cfe927d595602088ff2162952b3c76ec5a1db96cf880fb050fd400bc183f649140d98ad780c568ed68e86855badd4e965c789b5e54e3ebce8d260bb83ae44598c06c95631be5d8ca26a2c9858fb278f3d2ca8bd80289ed3b58973e3664dd41f66b81b52bc07acea25b957d2f866999ff7888e3dd1ac0598078d87bd560c7ba274344a7b3221cb5cb3ab708e8997ed2b6ee91d43b5f7a63971a503ab9429473a3b1d05a8a39c88ed9d2577aded54bd29811f6a7aac9e92e30b0b458344a6cb804ffdab60492aefa51a71242dfae7e43499b2945407ea98d4b41d760805d95669747022c0811b90e971624a1c8fe0bcb528670d5867904cf05e6cb2f6ec9be5045d2c1944095f5049dc390d74231ee79641864adb466d98eebd05e16ddff59b572cb4d6b2cc1619431005a105b5affe3c497ccd483c842691a7d3ebbbb6fd04c7c27ec0aaa42ceab060523773f4bf87931b42a6198b6299dcf73c7516b0b583effd575b321698e15fe8281ea346258009b91555ae2d1b98192ef769091de6e94691127c18c06bf5fbead769da2e9c499eae9d955aebc7f42e175fdbeab2e0dcbe2736845370072416350f38aa8a24e3cbedc27f3f48fa4964f198ef452651356e064217b5eede21084211dc21ce713de8f44980d5b8c63cbf9e2496137d047e7b102db30daec62c0c25192d9f8c4b8b9a60b3394162581f1b940610619e10609bbeeb4d8db525cb9a59cf20c899608300b2341cf7d70c2f8fbe4ab23dd30ad5353faf94da4ad46123eb058a1083ef58c50a73b241d66ff24d9f5c779e61e3cb0e80e862de6d8001706849497ae5005863c10314bad8b6c2aed9fbfa398a7467532703d1f747a105e4a41003efc02922636e0b48a9c17ed54a6dc4364bd48e8504dabf0c8afb9b17210a21fc8ed601ca970fd05122a384c089b72f137bd3d061b78f6ce45542d1d2fc8c83a1ac348f921d46f17eae6aec4a6be71b7e7f609c48f6130064653b08b66340cc94840f2fa48f52226c2429574ae43a00c6d025bc8860bfd5540b4b2dcf932428947cce0b433583e488d0d913ed58dfa3c667a915c83c52490ba567561060fe741ed64c1a31195504f85b4196d096e5734696894c82c2215cb5eb492a96c0432e5b0b6af3372647a2a86d4f30de931a7e9a7b7c87e0b7d9c2f20b2feaa92307cffb86bf360deefb344cf662c90a3eeb180c88c6259804d04c91792842b2d78059ea2a549d507469af4f2d1bc53144aa42eac5d7743549460d2ab56150ea17c2501bcf3e8161d79fab55c497553d67f7cfb125f792576db40c489b100c135201ef48eeb3c8990e9e95d3605462489f8bfce1b87cbe1edc0380bdc5ee5e68617ce55b6c90226ab0fb1d07418fc9f705560f0ba50ac777ca450ba1e5e0eeb6218c2da5fbd2c2a90e765ede45bf96e9dd2b3fa00dc114d5eafa0c4ca192d8f4a15c1f0b206d90c713ff2f73941013184a2110ed24d58a7467f8ff42d824894cf8bf31294f82881bf3d9c705a74447414d4eca55797440f8e9854848eb028f42d2127a1e8ea10e71c4c1859bc26a424f81b5e09e87775d1086437098c445de7078fc59a884fc636dd6c2bb430e8629ef2ce3c4fbb68168804431f48a3ce0257d158e216f4c2e22be32bccb48fb134490000826d06b280b972e0138843b0229376cbbebc001b684d7053c85dc3944e9c7af513924c239545214a6c01e914f95309968b76668ef575cee74f979d921381a8e4b439e2c454aa29b94db55f8eac33cfc72e9921bafbd5de2b20fe1eda4c1e22c19f841704bc4a9e237f42967c598519e92f644e501ae7105cb6d6637e4a3b513a9a356644ed211925f2d00f60650919ccfb5dcfe0101122fce324c420c0acb74ac8e80f64182045d322514e9ddf47f214794d830d48f0f5e09c3e561ca2cbc8629eb7c4d74372e68109c03e30c2fdd3eefdfd97e2f4f8b7d06fd6d2ae769a35a9fcb51150d6ff41fc048a2c684eb19223aa6c68777f033d5e34f0689254624cc1fd505a7cb73cff60d4b26e85ca80c533e004a41d0a14dbe7c3b39921ed3534aa990bf2ed7569258f66bbba3c63087b77c254f9d7687f0ae82c14a13e11bcea2c39a190f1547a33e517c1820532e4b2c0667321be289193b44266d99c4c6dcc41e89d645bb8af4a732307aaaff61c133513ca15b527f2d3608ce0c71a9e6cc0e19d7e2192ce30017efc48d7d889834adfe34dd6e8e08430d17556982dae5ef52fd390269f5085ec4cdf32fd7540088a4f3726385cea2aec8fb12358cfa7b75643c56d829c2031409d85e06d92e5f75d19dd0826908a23f3eea4f81b8fbc921b826f5b7e65ac874f2b01f31d22c7a6f89a1cbf999efd6b2be5e8ad680644f56cd4cac719d11cee0dc5ff9c28d149978a5f0493a728b1be19e791e5a89cf1427661415872fde6ccd09a1d2730cf24ca10b9cacf0910a5e6895ca6adf886159800658af1b07766810dc198996aab8e39478c93fba4b44e2ef338f74553da392c4f35cbb0387cc44226827d7751093d67ad4a74ddf34b0036e966a63b0365648aae41ca9feac0841c918e97cb56dbf3428b9218f39b5edbd972d3861caf7f982d89396c47672a234d4e3eea9d86e70affc349f5cf9bf8bb7490f1fbdde80a949fd413a0a45724394ea45e1be82013991507d35dbb21bb4165ceccae5700ee3f323ba4362a45648dee7e09495893f3006090f57039fe2eb830f4aa96483b08ef8d166e5a76acde04bc1eb08518deb60e863c664525e8447bcee96d73b2a42614f1e10ced287de3f1f305ff99c07c9d0eef053028075a7cc4be0fb303f6e080eeb04ad49f23fcba582ec4d84f225fa0795e2119f8c47633a987cc2e4376797f805dd6e2a1beb4126624ec5e2310862c7c269d0eab25fabb30cf57ea9491571eed860a6da3241c2c3136b3e5b4a975026583f9fe74a8147a80d0200a1aeb2f94f846a011e34d13a9e1ead199130d4bb2fa30e319b42e1e319834ea2f86db9287ebb25fb3062d29655be3b7b381f4948b575466a36a3a1b378ff13a04212725603d897a1fe203569ad1f8000cc0c615762bbb915e1596525ceea6532499cbb9127bca209157d7af72a959d73e621bf728d4cff3088acbd5313a52514485c1d15f3f03d43669933cbaa73824656d2ddcd832e12336134a3d2c43874f417e59221c94cae5be1ab9e9a3dc017e9fab123aaf40b7f418eeb50dfa82a0974d079b58d05ca2e2740079e01475557535587cc0b2a9fd028a4655abde482f1760259de43998a4850846034d3ca73305c6f2d7634f6b82c7bc224fe9a4fc9aa2fdeeef9bca7bdbbbac0ebf5b243d8c9bbd2d0e97d6ad4d28041bf3c480467435681c8bdaf3a3c675e242acc7cffb82cb4a33d2d3ef3a90d492098046d5d173cbe6a0d41f6b9e33c6be4b71113b487dbc3e8ce605b8990cd683de0ea58c9771638c7ef21eb3c7bf46deb9187533672a2ac07a9c5070b50a1dc09c22fe9f2d6594431e9238570cec4753e423eb6ac50bdcbcdb204189ee102b85ed7f8825731dd24042f27f50a884231e86e050920957c40c4af754d253cd10eeb9a23b0e83660235570a64d3e4a91189c71ad4725a4aa0dd442c1abf410d18338b190c46af29a880ac2754f91569542082525fd793a49d13c05d62420b5691a566c1a1814adb582212774e2055074f8032dd9619c14ec5b810c26f545f79093c09ef8982f5d3d8ceba3a5b4fad61842d9b18a70f7c111689ca92a93ba4a0385d42cd920b32bfaafa11dba3d248444fa728554103dd54f04484bf4860855965512a1449f20405c2cae79c5244659a17a31d0a2eb80da9adf51bafa2e32c4e9d5722b40a395722d9b23c6ed95e0cb20aad3eedbc5dc3d9f40d9520b0b8653f6c96a93f9a948e0096b38982bacb4d97a92a61ac00418ff500016629d79470f3f102b4bbaf4d56616d1e9397f873b4a146394b3685db4e3409fea1e5681ab793b6ee16aea4db306daad837ebad4283ff1844bc59e586f4e166b31497a32d350b03152a8a3385431eb06b20360d99d3a3ebeabafd0276bf99f078dc0bccb7cc713201ea404874921bd3425285a7128ddfc2723cd5a2a01df04eb65273fa0dea85159e0e487f7d649627a6637888f882b5e19005824ae991c82c210cdcc1f37b0b18fc5d62e665e83109fc164cfa20a25e538be8afc7af03d6e8d33dbd18be45234cd54e16a14323c0588f1f1b47119e4e9a8ae027374690132b0e440dee6754cc2a03ba6c7ce4c76da2318bf0c5c053e960b853102baa3cf9ea544f8e0102c9ac195e611d787dc6425e1abf2d91a3f7e60107ff07e82215879c45f8998284922146a174ae92c25af3c33c03e7657bf49be00ac716edf4ad2191b5b107f17037887551db8022398ac0c6b188ad96f8580bfe91723140e6fc7e935a7fa6c7810d28074a861f144116d551f0ee857df0d6a814647cf8b361d28bf1f7bbc5364ff397b39bae6f2c814d8196dc8b72bf7def1d46c45c825f0a21b3301889ee1dba286c2eb37cb6ec67d73cf62cd80d25ba18119470f83c24b52a09cecb3dbe45e6287774f8e127f1cc0685508a32e827f0609ff58c313622f0ad23260c3206c33931864359dfd0a56cc5fe5c7c56b6dbd4fe75689e56378aabc39743bb2c2838547760845a2da46a11d8a183694103f89695387cf183af652bd31b98a2ce94c10d9a05486e3ef815cb3859b50bc0ef8cb4fa26065346bed4b9faba950c5a6372fec1b71201569025f944c389e935b61f391f5688785f109e7647e7a834e28b327ff5435321b845060c3480aa0addf7553f9707c19ac7598f2a0a3aa79d970409c34184e6cd40f9feb5c4e4fb93f1300abe0710554631682c62c3d4aaae15de12f17ec29df802dec46f301c50567100d6e8f2bf03c3d3ef406fb19bff67804b43ad670bedd2f370cea5b795750da23bb889e964e7a8080886dd41cc1e8341296cfbb82f743ce0af3627ff5d7907c0e4d4d624480a7ab049302b019de38f821776831614a53933a174c266278ca6943afd511179257c59eedb09d9c00ad8682a000288472af188f236845ca3aa578630ba1fde06f4d4c638f19442f1de512e046c0d7270875ba1eb4b7f114cf98dd540f30bf8905554e7bb5395ed464d90246ffcae63202ff1bbc28af17547517957b43d912d179ddd5c034f97380998542f4c094aab48fd17d744ea337d74665406510118d528ed28fd25cbc28e07069e9e2ad4fd1bbe61f1e5d2e09aefd36b7240e4ef7f69f40af5157d842cb2963dd3a3e7e8c78a7a25dfbb725543d1a217cea9ff38194edda9bdc0072942accc63da0bfc4640074ac0bcbe3ed1b1f52add540bddda71e4485491a2f773954da750e2a8d6e230281ade4fc378748708790124310b681a6ac05cc2a03491a5c1f5c97d3e15979a2bf1e3b5ba16898ab83823b1e41f0f4d2e2a1184f2fac71d7b510ef9a56c00eb9acc8f818dbc376d0ec06cbbb392afd1d0716bb37ec82cd6ee8ab01cf30d9b1b28bd12edd7653b8bd2bfc53f3a7665ea73454c96ef43ee374c4b18be4764315ed17aa033b7676467656dedd740d3ec261b61bb50d013661b29398ddd4c41efc50bad762b2559ef7b58c87c71213b878d77b43dc163e5ceccf65072998a75f5c0be6250e0af7ae5ba070915abdf9e34b25232e38f9be40c69499c1fceae6a0fb11db45db8609f20a6703ed7280ce6d0f4dcc6ba577a0b7d92170e89183781387ace030d0e75dd01f96ad947611d77518410fab19687df9d8eac620da7a2c2fc815f8cde386b0262000542f1f99e3fe9c41d485417fa6c20d08ba6bd311146ca83839c7b20cb02179176c59a2eae4091f3b3b02624f0e9c6a39842f34f70a97c0c6f93af7e51cf06c56d5bba5a814fbbd3cb80cbce32e4e11e09b1a262b8661a862d2a2879d60ad3c5a822c5c129dcda28010601a078e74190ca97295e86764b2f7db5dff2f18b8980a09b8cf9c7b87c668f85952b7d24e69301cac92c74a62354d3774a026e727137ca371a2c222ee05380b1764a3bcc8e0da4eb71d1cbffcbb3aa2d71204d31a3d6b18100fafa9973251218789c8fc03f127d7e3c03da20721e8856b4a301ad820c9a99a7008e7af92925998e7244325e9a0d4df62110384b4fd8aaf7d19162701e89db33d99f10db76f6f92b17b2af01d60e52c5edec255a69f4375e6c814f50e1d59593ddddd246fc63c76029cdf428869e77ad8e6c0a40ba9f7ad1ad241e2102ffc6baef1f2d3da4f514d7d0d41e25ddb190fafaf41c5c5416b9eff75342b46934421c252824b1b5e41b4039be91fefcb6a9d9ac6036c8a057064c11a559a161ce33973900b8580abbf365070c2285f3c3e56a4303afe5652b7ee4b8ade32e7540ce9ce69fae0f905e2a99f48152c0fac715f544c90021013b4b72a5f0fe5c02d4208c190cbb38479ba5544cd564ba121ee6cbf9e37c938752e6584868221f5ee09aa9cd2de2ca130aced9534c10dc63340d2702608726d9653b47b25bc09fe57bbc63b81343c0dbf8665505fb78a32e5a94080330b591b30c99f3c58e8c82bf3844fe4f760d087fce77ee0b508e0cf88901267624477efcd95536e7302c66d3465dbfdcd28c5bfdf1b44197bacd8ac0020342efb8b50b1c804034886f549193badc7779e6c4856c40f277d457a76c4c0e3a8104206299272d19741803d63c37bc6d71d26d88a3982587e97523b2d890deb86ba81f8d03ad5ef1d203e2b7ba56ef127b771c08bedc788c04249d3d5f923733bb949b3dfe2eb4ea625057eeff8489b8a250cb0d21ca0477bce5abe38a006ad63f4ae57778f2ab4d9ea0c6f5ea450dc6f4daf65e4ffa7564812f7c0db8959bbd36c04d9273b063cfb4d2e9811c7b60832fc64b9164e742b955e2afba00a4c900521ffa8ca7f95f0f370b548ee01c13f951667168ccbf967c07e4f82e534be103ffd3ebf12dd12b6b49f5f855957108ef5983a32d3ebeb6f76faba7b358668588c436170d5225c92e750e064a64a1bca42b5347422586ccd435e5d428eb8be21d5ebf6296dc062d2776c6042d9f6fdfb0110b35e55b9ed2bf52c6d387dea2bbeff1d1a06a2489c367c20a41458eb52876c2d87f5b2ef002ddadc2db8d5849903f1d338e3a3ce29ef3969740fee5b9f31ea128eb3cfa96bee96455e40ac64d0e66251612ba45ddadf4d39929a6f38db1c53b09e07d27556bdebbc866c6f47f971097e45444a14581ed9e8943faf9eed86ee188c190b4b1b9c1121951ec3620f32b5a04c7fa5fb588a6c2e509ee3639e3dc81dec1e35a25e6d94984ab2fd3a97ed7540007d467aa8c6d79369001a9f3d59719beeb734e21dfe1a289e8d9bbc23fee7375ef2176652cb013bb2a10a39dccb9acf31db4609cd6e7c30d94a3004646fe4e2a0e7b65a6caf7257936da76ad58da1ca65f5a03c3daa1aaeb2986affb6678028da20917f686d327119f2dda9fa9903c91579b170389d2a76e8cd87eb9e22539d7567be0a4c6d487979d7f36a32f7d88982d89c12acdddae2cc0911c13d5f4bcb57c0bd6b1a5c8d9ed74a77ad633587b2e2167f45491025bca49bed386fdf45c9cebe7d248a4a2776abfe23423a30ad30c6079701e41f83c1416bfe407cd8072b799c8235b16ab0bf497c83cfd61bbf35ea07edeebf58f6229d80bf99d52a8d8f8395d0d96358ff2c45ec5f59de42b883102ea5280d2ac6e688c9ba4e6bf52edcc10aac39e3c22f039e3a629aa63d7394583a7ab1ec85fbba6d7a40501dfb429cd0df76849ed90d4aeeb8cbe51ee8f289817c5ee7a4ed79f0558484a259ffabcb6e63f35cfc2d2776d0e8e2ccb9fb0e8a2db8bb6353d0eae5ccfeb4a04373c0fc606225527360e639223ceac81629bdba6f0c4efde84f2aa8e07f06e56fb197be31ff98ae230d4df686833350c451be996cf088ed07de9e508fe3d87e6b25b70ce2be37ced032c8bc1d965cef86b7d9c473226f0c27e30449914ed814ad87346257280aeb40647d738f819d84599cfa4e21a10f6b807ba4755796596a8b376278b76a726e46d6b21773420ffdbaae2e926db10cdb9029a3a93de02a355aa10d19b0ead3738376573c272401b632d27ac0724dd14a9b07b22f1011f86064c30c945bb4d4cdfd50eb93241c374a7aa46a459a437e4d3c260580c440f22323804122dbbb68a6c6c34fc5776a2e6a49bf92a034b05c89d0d57e24674b76c0d04effd7299e3994a390250ccc6675b046c224366bb0b5e227d84afccd67fe5dabbf0b6fe2d480e22469add649444429af48ed0118bfccbdf500f8a4486e8cc76dc108e4f8e61b055077b54b4f01cc6fb1e73716400f3d35902c6c70ad3713b5613e296c46a7ce6fc110b64a9c9a96531fc1acdeeca135321c452c7b804b8da3b2a5200b8b96b98ba03f4be62119a00bb7e018a0e6f9509425274938136f4e6ef0ecc020afaf5c58d87d2c65fe67d966515507439ceac8382ebc99391a66a09131c2aaca6a189b9877cb3210e9d26fa609016697f37525592d092d37e0bbfed4ad1d1cb21d25b610f220d136f3e964182061d9e469259390ecc2f3c838ba72b1246cbff034fb7ef98d369be118900aae502a16f90d9ac91ace0ec3517cedc80c65ac43f66039c6daba6a74a6005e364e82f4862ed488c6939770cc1f5d5ae14313d8b61d40c1382c62a5633be62c1680597690b6ef637ce47ea23b0024628d07b332ca752d0c0e5d15c0041b023ef72e3b4bf531dccb32c33721784458e0d966b39d527328879d12c0c325cb601faa41995a0b256e2968234d289269863239f9f865891dd66f0180b8c2921d317d9c03e3a23b9c5429bf51a78e5ca5391e46c739d3aaa07623f6cac2e31da04c4eca805b385bb607ecb9c5a215525e2af0b25d468d88ad5f183c6458f70b5876f50d78f31a5b938f0c381bb70ca801c01cc44d9c9771aa3f573759912311db57f1198676b5ba6a7bc63d67d13445c43a8749e74261b15f5d0a3b5cfb9ffdd0433a77d18e9026b43507920e916dde60543bddab472b6078f39685d9c8947400e4c080f38e5182a174afef586433db2cfe702ced6511d2f5ddb5f6f541dbb5aba75cab1eb14e7d3b83837e3cc364dfc9afdb00eebf02a6dad255716542199fa5889add195888506a2e00f10e49e69dd0ec290d9bc3c662d4e239faa874af12fd6a17adb2e6e25e7c5bf91efc91411eca8ea31c00256eede6fef03b43d9c7ac00a23cc5011a17af7b3380b4940ef030c30c33cc30c30c33cc703cfa185be766f66e29e9fa6efdf70414eacccccc4c959f842ab6cb398aed728ee2bd2080078607b007b68eeb86090de9119a7793cdad8ea246201fea56348e4f111a3debad1c424389e07ac8bf7014161d42fb917b83abc89603154233612cc390e1c4d8d6e24083d0ea7bce8db4bd524e1e10da1c9eb2fa5b83ca9034417f70c3d4283639d6a40fea57f9cc8f65db82d58333de149284d99d9f07648f54d0ecd9330c7770f44eccfc7440780c2d87bf4ebec941fee1256276e5e0260e4871374ee706c6ff4bea501b78559a35e32cb935d8ab2bafa65c93140deec665a5d90c5eb3ec4e1519dca1e1623762e0488a79260e832db53a5ff805078d97b363882c31e602ce6148c13f6235de02bfd253aa3594056ab67bbeca4d1aad8206335137a3e43caa704b5eb30771298d5a2a8a9093e1fc848d252af2e4622df213373d05492ba3534cc1496b79060e4c764164295a29ffe4152f5392a2cbfa188864448b943346d1b4066b201ef137c69ea268bd32fcac9453e8095a86a287137422a418287adf580d93296af98936377524e253f34c7b81f444279f1d912b4988a712086427fa7ebf8a5ede99abe1e4449f739cd88b8ca347ca6da2cda90cfbb2e3ab01a989fee7f561f5a570b92d44c880cc44e31de7418392a81f31582815564162a2ff70e0793d1b29c84bf4b83cbea7b2d8628b0f5cb1455114a425fa4d198438651d3364453830ca06598936c730fed0e322659094e8f72d2a68c84e02a385e16212fdab04cbc8302c944c80314849743af91cbec6982c3c127d4f639821c7190ba52bb6280783848422163d61a1248247f4d539435f6278d4f860a1e4881e7f8ac9df75f4410835a299cca854f36a6898bc67c1c516a55c908ce8e27290a4af295e615a44737d1d2547b662fcec7321820f5cb145a116a4227a198929cb5a050ba5c1824c442fe68f634a8e919024254122a2934a0f21a3470b2986469087e8ba4d5c11a421dac8ab51d47a46534661a1948577318c4e9085a8421c27b3f02eb6e0e28a0e3c074230e8074908c5f3630f7b21e57d10aa64781d7ba9d515411c354f6609e1f10dc429a2fbb6c789116203103fc8d413e633ccc03f701d2ae6ccecb6de0fc33c8ef39494c4fa6023ff5c9261a9e513483ef41539e71bc8bc667df7d0acceca6988bc97411584d4439bb356f4ccfde4a18b5d0b31e2af3a0e173c741e312e9546ec481eb9437b9d9b525af767bc6e873e364aaed89eb674781d9a89e8d0b7472f630ca7439f2bff6f889779d5c3736883c4c739a776a98cc2726862cf03192d390ecd8518cd4146c9c8c784439781b4b5e7c9b8a5e01bfaa01fe263495cf36a6ee87306b142ccd2a71db7a139f5e9f8e32042c68a0d5d58d18c4a215d8db3862645372a93bc714a1e6a68824c8a98f23376494e1a3acf3219af7eeebc77d0d049a5907b3e328f85ce19da779851f4d598a10d930e97ee9862ca656875f2ac6f747cc972860cbd85fefebc9e3286b652c8d6ccae88a17d5f0f968137aef87d187a20d1cc3fe6ec65efc1d05883a89357276570fc17da14b7a722c60bcd6fa4a9eeb6ffc55de8a1793e7d57cf6a12e1422729877f7114c57ce25be8e5d33d7386aa165acb3866b38c7316dabfd8dfcd10c30475b1d06589d67929642dc9c02b746272da40b395c9e4acd05a6b74929691cdef55a14d65d629399e0a926375f22e898db33c05fc7d42d0d5580a4d34af28daeed9e25751e8524e512e5ae570ea1850e8b3642031e7cc79429fa94bc4a2729cd094e498fd2445c6e634a1abcc8dc5e1e49c1f84099d3606d61badc38796d0c4c81327e40c253421192e6c044d12faa41a7f7d7d247c7a5943f2303942db9ba42aaf5ffe2e8dd064f5f468c828456835a4fccf6411a1d7cf101b633577985186d06695cbbf6e92561a21f4322926292d85142b1f843e9b5b4a712e40e84c4a47bc75923fe8777d3f7ffca01131491f68217bd067fdb79862d6a873111e34794fbb43d6cc93213b683a84e54bfdb90e1af71ccda2c5fff4c873d0affb6ec36f71d096363c7fffd8de39dfa0cb9225dba0074142ce2838ca78f11ab49da3242eec4b83f6f2c60ed39993e5da19b4216622a6b132e8675ffa41ea652c7a0c7a3cf916e163cad0458541175eadb2483e066bbea08bc9075d69bebe9e0b9a5f89cde71d3a7f942de8b3520a611d849a9f2c68de3b6f65e8afa2c756eab12ae5d70a51155d74ff584fcdc83a928a4e76f53f7e4ede63a8e837e7ec8ca54ed16488775fc7b0921b678a296029dae8d952d1c2e64f8691a27fd06a1555328aa6a3616444149dbecec5d8217e6a3514cd673cbc0ee399cb03451ba941cc78937e468dfa44ef1b32e4b58c277aa029ddea51ea449f5264941d3de244631151aa1e71a6379b682234471320c04cf430be32c68fc7449be462e398b14bf97e895e1f551e4ff2b0449f37cbb4836819c5c855a2ad68295ca63b94683ce33dc50dedb91533891e8489cceddc2946cf48a2cf9f6732cacb47a2cfdb5931d1757f4787449fbbc93c384a7d808f68a2e774cd196a1cd1359c8d145c66f353a6114d6cc9fe58c3c61b328c684f52763ccaa9673c6411edc72c75cd37cb214914d1bc7b8a29e4f2522c49227ad4206a399c0dc7a123a26bd4112b21c30fd1f47e88a4fe5321a96b887e236eaece99c9dd6921da248fcf33ca48521221fac77e9a4134d1aa3153ac25882ea4a4c81854148836cf6554b966cf8aa30708886845aebc610bd1ea6b8e670e3a65c4a5f5000c5c0100312c213a79fc2827c7de17a6c742298bc6e243e0058880031cb0c5be8368e3c6ec1c42b2d3f423887ec6612a0d39849468d406a2cf313f535bde00a28752d19aa9671abeff8776434364c8f80e5abe1ffa6c711e7654c7b143bc0fbd5ec8cd9f71429090e5438fc1c4ce5ae2b181b57b701bcc35cc11a37ae851f030615db37e8a651e7aebd0fdca0ff1d03cfefcb09cae6ee90420000108a00bf301138420157b875a3cb7435156b753747c1dba8c2d1d7443b36c2c1dda933cd2fe32a1913c73e87b5cf4e1c5946275470e4d6e0bb7f889435fb2d7a5b932960287ae4284984b33f386de628a0b3133e386d61a9b05dd1425a6a70d7d1ecb293776776c316ce83724cb1afab4a8f01a33f249a786369c3f96e49d456296865e245387cbdb327a1534349729c3fc41e50ccd49696e104374acc89ba1472a3f9a1ba40ccd86d9a83129379e4b867662335f55b2f5cd3134313148388a1fc1622f863e67f93821668a94611f86ce4d2284d4d1d44e01431352a1249c5fbe10f2855e7c2ccd624b63247aa18be5601cc5f5adf8205d68f42383489ec3fe380817da102de4388de573f65b684d262f6bea60c9f15ae83a83780a9ecd1d8464a16bd01143554a4c51c74227f2f132846ed838bf421353ea4a66ebc870b5420f2bda3fc3c6ab50abd0f43a92ed4b51a1fdc60fd53242d8957c0a5da9a534a90c9742bf193986a69ea37a4e14ba780cb6b2f750e8734ed962fcc725984f682663cc25392d6143764293d52534344c13ba384d1e27ea4c58f2c60cb3b6bb844e7a52caede82aa1af9443c4713cfac8dc24f440b3312ed7c849bf45427ff132b7c884fcc7f6085df60ddd6f7d698e37c229454b51232f426352791a66f554192642a399d124c591572687d06b7c99f0b0bc783121f4d13d69109a0d9728ab9004429b3b6588fd9d25c6983f681ccfc6394ee12fe5d107adac767bce9688e9630ffaa8a739eb45669424e441e720a772bce1b0d5dd4197f242c839cea364e8e9a0c9e2d515ddbc1cf473a171e96c8c59e2e1a0f714d3291a5648f2b9410f62ad572fc46cd049e5835d89eba1afd5a097f814d9b69e089fd120bdd6cc0c33c366d07e48652933b61cd1c8a0cbffd43e2de911bb1874f1f0b14c66771409066d686d8d559197da512f682ec550211f65c2b82ee8adb4a346df8236bff2a2e77459d0860cd22a9a1df90a613aa6078f54d134ea06396652d1744c21bab21ba7c3a0a2c91599749c728a1eec4f50cf19f5cf628a26c476a728393eb1528ae674cc55b5428a36678c58a9ae22b11f45bb219fbb639992e48aa275581921b5d3c3aaa1e8438ef7e44023e5f540d1851cf1ea9361bc0cd3847ea2df141b49a3b821758827da3c295584c610bd93a7135de497e46be6e1449bc24437771f37f9984d349a9377e71c299ae871eaf2cbd2d02ddf67a2e90c7452e898684352ccae14b237f2fc126d46444f39a7c8f91fb6440f2c738c5598781cc34a34579a9ab91a4889be577b2d85a879d9b949f46be69e44bdf2c6d324d124cbd41f5235852857249acfd0632b79e3090a89ce32726bf8483aed3fa2df98b08c2b398ee82c3e3ed8761bd15c6af5c76c4e88b9c38826658d90d8a067b92fa269601663c89e62d9338a683347cb9bdfd42ffb44f4e13d5ea3f382882e669c3a441b52720c642ea7cc540cd1446f0c363d87fa64be105d6a5e4abd97bc632284e83524ea87cc90924507d163982de6f4cd071741f4ef289be48e8b0aa107a2fdf8fe6fd1980c6f296feecbf80f4dd489b13bf979f67cfdd04e83cd1959a27de8bcad3c344e99d562ca87267f9cc8a830f7d0c5c827f2399c4fee510f4dc830a58fc779e8233cc5fcf0bea82d1eda9910711eddb773eed0679fe7b18cb79165a01d3a494fc1f2b754af6b7568cc24e77f90b742fa45872e25ed78d9bc41ca399a43f30e5b324e3a9e140e95439f35070b3baf39a2e3716845e5724e9a2c387421ceaeb6a9e5a8ced037749a1b7483ae340f0fea863337254ed6909611822d2850027740000cb0012d3810822d2880086d439bf72fc75e790bca8646dfc4bcb3816b681cc6a808bae629734a0dbdc791eac78fc382a6a10d1aef2fd1bbf3fba1054543bb122bc27de26594e780073890051141175a182a1ee8195aa9f83a295958a43063a1c4853fe032cdd0662599f0e4f1106cb145e509b40cea396c94246c8e8512d2391c38c0a503940c45fc96ca1be7628b2e88671b0790c023808517d031f4c0552aa25cc6699112439f92a5c7e70c2965c5236818da509e356afe38a69a342328181af34eff8c43ca345783a05fe8637cd7608e4d20a8175af9d4292ba7b8f475bbd038b688d81d16e5429f92446fa5fcf1f398ba854ee3eb86884f6aa1d3ded89f7128c973250bbd86a9b06fc12486075241b1d0480899517abf47b77c852663240eb2486e6e67b5c61b4306321db956612429fea9546835497c5b74e5cbb08c023081049040a7d07f5a7c4e51baa1396a0095c2b03bb7a58abde98087a06859011a855e4230738d9f1d140a4d0c973fe4b49c537bff84be91e48c330a8f92a939077542d716a3351489696fdc16470b0e145d1ab409ed5b4fa75884abc699093d8e793e2417cb129ab308e141e795d0871c914f5dad2434f1730e991dae4868639c3dbdc87b8e49abd7423b6a51e996ada2e193853e64e8bd98aff7644b2c3473d9a93fbe41c86657e8aa7b2de9b6398897add0470fa249a2a5aad09f4903c7bf59536e4f855e9256454e9e53a5e353e81a464df3888751f99242e793e32c74c2e3a378147a14216b64ac17cd370785664a2364d43182a9a53ca14b07f91519a38e1db913da8d5149cf523927cf4de87d2a2a658609cf39cb841ea6e5f595f89699e34b687ad242af645f68cf28a18de7e31b9264d1d05512bab0c161ea939842702412bad8d9f03115e6651a4730f535f75e088f119a78ed1b1a631c0d5614a1c97231a67db6835b6e05117e18229464983a8426b8a53b9e103c523f426866572e56b40e6dd1c2042b82d0588621493f5254510d089d58bec821a4c6592afb83a633af44947c6ee4283e683a69b8f5ac6783e97bd04c237714db330899731e349259e2216b6307ed6f6a27cdde29b7bc3a68a7a593bf7496837627f2c741d795c2e50cd28357e437e891698810515382796b83be32ecb890315207e7d6a02bcf3c113ee5a0b143837ed6b278debcfe56cb0cc699b14c88138f0c7a6b9c9d338a3f593d128346e3ef76ecc0a09393deb08e626458cf0bda963c397a667ea59a2ee8e4cd73722349cd496b41971975074fba5ac1824ed45cba777b4aa366155d54704d0d5215c93d55b4991a544b7fc5fc1a4e459bcf81866688414527c9336c46469da24dd1d0a7296c9ca8de149d7e690e3b9f97a271d354d7d5b7d80693a2cb41f6245c068da2cd1d3a8986d645d1ca657a860b5f28dad91eb1681986395741d185145f590dff446b12474332d23dd16588f110b24b48cdf94e748ec27cd2c69ee31ac389c622fdb389dee1c7b5a0f9635a8a9a68a36bd6d8df21aaa77026da5cbdd9eb184e8695c74457f192ba8777556cf0126d65d093ac33e73cd259a2ad301273a3101353e354a2f309f91673c70e5298127dced5172e7c9d0419752811e97948a2cf08f958125112521489b62a870f3bae797a1990e8e34ab4f4cafc887e73f484508d3c23d138a2d78e949833921f89e14674115ad167ba43c6d818d1764c21787556cd1a6216d17f06da25119672e328a2c9da5e9a42ba1cc42d116dc630e60e175ffad747442bc1e31f446d18ff720ed1ef3e8ad2fc98e79a32441b3298fc62d992e5140bd1e6f1a029bca5235f94106db258b13b5cd296141f44134cf3e6ec76d790344134711be7b9aecacaee02d1477f0c4d7cac634b05883e855884d849b20dd63f742297b1e7dd14f5a3f243d39bffe181c6ca3166fbd0c78c3c94794a54ba7ce8da61ae2c51c2e449630f5dae60c932de49aae6eaa1df3c195e56e8c53c9f3cb415dbbcb23a428639830733f44b21760cfb1ddadc0f9264e7c6153e3e03dba107d12a6bd278cb93b23a74164cd4652fc57c9860a14487a6917ccc19eb5bce5c4370b4e039f46072a8a8e13fe5eb170196c3302bbc7806218c85920c380e7dfe5e44e89421f2c658285db145a96238b49e2b3497fa37a8aa7207fc862e96c6cc30ce7ea89063a1c4859b41db45088e1654037643175af625c7a60821f65a189c40175a6ca1dc0672faab6272885d54d980d9d0e5f41ec9c9185768b185073cb0c527751182a3c51a7a2f4996653d54e4cfe98016ce8546a008ac8636fe573ead0cdc820b0d701a5a6df76baf52cf700ecb00a3a1c7b9de21fc5cc73e0c164a21d8a25cc16768ba3c78a49c99a149f165523cc728cafc6568f263ce304b0c5177dbdd0293a1698cdb93583a6a89ce185a4719597a8789c5d0a70cb6322b7018baf00fde4d53e3c8040ced75a33cdf38525075f017ba101db5c38e29724a8f17ec6e24e340017860045964d1852e825845ea4971a151d7c89134e7d492744c048c08b2700a6c03780bede7fce09aab167a20f32023ef4a98f4b7700067a1dfb83c625a39c6425329e3b3eaf8a4f9295fa1179f7c106d22f99e652b349525e6f087ade6c9147015ba103d95732c1553ea71d3802cb2100102f81e80812b2ec0546853081227e20745c0536836de1fffb86809029642bff157d59671a4d4ae071c70c6516867934954cc48681c6528d821844a278712262e3c404f200138a18b169d0cbb32a3a7b609ad56b45cbd9e1dbe419409fd37aa38ef07f1123aff907365ccbd127a181d34e3cbc9a1cb93844e563af33be325c46524f46fb2418345ee088d24cf17536c673c602334667db21f3bcaa43a06042e421b1ee3d69c5346f9fb418426263f98945b31aec50ca16dd8f959c6fb1eb0105a9590f366c722e3afed8083d083ac6f29721aee6f06e78081d044c3f78c9d9072c607014cc0c5047ed08f47b1ca1462100f215a5cb14508cc0ac03e68629286bb52f91e74d15622e13c6e9610a9ec22045c6cf1811218dd651eb41f0d92bb4ece5758b150eac2036ef45a880001835801bc833e9eb4a5e48a6e197944c0012d5407c83940c601f20d906d805c03641a20cf005906c831408601f20b905d80dc026416e0ae025715b8a9c04505ee29704d815b0a5c52e08e025714b8a1c00505ee27703d81db095c4ee06e025713b899c0c504ee25702d814b82ad44d7b8c167af18165a82a200630e584ae04e025712b891c08504ee23701dd1c48896fbc5a1a7e7cb36a2b90ecd979edf33f0ea0ecb081defe6ace8b08b68665cbe3b38b24e899f1a56116d9658191b36116d903c12dfa5afdd9503c322a2f7aa48cd19349e96710fd187206e39a599bd9269600dd1b503f15c210e5b704001f96211adc7e538c9a02ba21119f7a89beb5de948441f979a42ffeca587f205221ad9528d97518e082f0ed148ee0ba65ebdefe1e70f5e18a2711d2b8ded55d2a1f4c18b423421bc6545f587869513a217cf943f266f8a1acd178368561d9f578c9a49a2e485201ad916898fc920a2795e04a20fc162fecb92636a905f00a28fc1323b7bceb061eec51f1af354eb3cdf50fe653f74396591148ef184177de882c7dc30135ef0a1d99018f443671c25272ff6d007cfed0ca7177ae8bab33f735b8c3fe7a1cb913bf94744dd08150fed7c481e17f244b7d0b9709279875e63638d1ffac7b44397b16b889032ca088c651d1a1f178b8f963c89ba7841872e380ed96196c91cfad98d166f8fb229ae21bc904399c462b0169785f0220e7dbe0ac93a744ae1e51770682a2da39347f686a623a5d25307130b921bdae91472b9686ef3cbb5a14d3d311fecbbc63d0d1bfaeae83e3de717d23f145eaca1699425be2963ac2e991adac8fc33fdceb8029bf0220ded6445fe0ca572c9e744e0051a5e9ca1897c4fed31d30db816ee0115bc30439b428750d70d3bd296a193c6678e3f27c72064e8e16e980c25a76e772c164a6368277f77f4bf440cfdf8ba5978702d2107c3f0220cad47c716df9b8fcb75f4c20b30b49f2957d9b28f4ad2fc42d78d2ba5529e249d42e984175ee87276658c61d9852e788b05d9506d71a1d1c8b3f929e545cd21442bbcd8425f9addbcaa73aa96b4d0e51073bce80d7734bb2ce0bfd12f2ca4f2020b6d89e4f7a9142972dd8b2b342731690c7f214ab9f7c20a3df090961f7ff04515ba3ced6495e1e705159accd91647d11edbcb1753e81ca71c2cc5b8d497ea0b29a057e6d8db27b77258f7b1cc7828342e532905cde48b27f4295bd0974e8f13daa83ba5e2f0a1879db3095d0abd3efb196cdeacbe604297e23846c6d12a1b525e2ca1b9a0b329a6725e28a1871f219fc5ddb610c18b243471e3c7678a21468a267881842633789815938fd09f5f8e13618d827a8b8552b912bc304213d5de71627b5184b662c6134dfbc242a90bc7a25e10a191d20aed88f9118217436835c39883f8e96a0ebe09c80b21f48f3be98f861d89218685121a75c10d7811847e3a2654ca51669613bc00421b2fe6d4f9602db6e040175c98a305bcf8419bc1c6601a2d3784b9f8a0d15cd1111b553d68f29f452f78d05839d2cb783af56a1278b1835edf2f4c574236c7b00e9a1c2d34f0cf991c3429bb4e8e2a91da41060e3a8f4dbee6d538870345cb5fdca0c9d4626ad52a2d13b3012d1c8ba70ac0041230015200b8e0850d0a998adb9b15828552084c174ba6167851832ebfaf59643b481edf185ed0a0ebb3289d537f8ac7194afb000c5c31801733681a997be3ec34d3a4074c08146002e7820b0210a068614250827e43812cb2700f48208b2cdc035d98145ec8a06dcbe21953e4472539066d8a6ea96223b333bc80410fc232cc7052d8afd4d90c2f5ed05c54cf78982c2e687af3ee664f9a2192dc82f6e18f85056bfdc84930bc60418f67c39865b0aca28b89f942de0c6721e52f58a18a7e43a7fcbcda21ec7752d106b330493de5711013158db8c5a82d9de3717e9ca2b58cea2035acfc9e95291a537f29714d6b608db2a2144d86911c68de9415a4e84379be07ff09991128005e60c528fab01b728aea5839fc58218adef7fd42f6f0fb578d5034515234c568884c6a48b002145df52691871af327fa682fad0c4721969927da994671e3ff9de83483e4eb6152526b86159ce8f392680e3ddb17f5b209ab80159ae81cc967d58ce304fd7733d16c9e2499325c44b00213cd8bc766bcd166eee7257ae08ef4620cefbe214bda8115966892b59a876b3f4af18295e852d6141a2d2aba25394a1c2b26d1f7c430d92b24d15b87cc25eac05a3c6b45249a89915dd12cd515a358286d5144a0002b20d1e6ba63c7e07d260b042b1ed14a688897715bf2383ba2cf1796395ecec042891bd1b77a5891486d871fc142c96e600523ba902f326ba59ca88b682b3e8a1247178ae83f2e6f2a0fa9b3859f884e52069de1a59c320af922a289a417f2b487e85752d228cb65d9c08abf62811585e8743ecb356b02ff0021fad2a4317688c1a252258b2c4c175798400464106dacb09bb28f859209c8151f10c1165c6ca04a106d96c5c50a1e2c9488506045207acd323b71e24bcce15a88e08a2d8a01a2ef4bd267b239446349f5872be46148a9edc06f91c559e1871ea8c4a8f3f8c17ed587ceb254360bb3f8d087ea0ebd1bad6106b5e08007f6d0fecba306973a7ae8e1eae65cb9e1e398a5811579e83fe434654ad92db8b8c20495c5165c201eda8d1911737f3fff576c513604268bbd431b36fc638c3fe9bc1dae8e950d164a4732b0a20eed5f849a3ec89291a9155841872ebc854c27f17f3c592c943cc001b70f3809bab8e239e0812d42e04431b0620e5d48922286d119d788b230af855b11ac9043ab95dd23e6e72167e3d04a047f73af2831f55798116cc1450fac8043937b1a26cd78b2b954c8032bded09a658e1eaee9c015563ab0c20d3d968b611fa5ca14dbc442498b2bbae080156de8bfd563634b99728a4ecec00a36b46b91a939639c657f62c51afa2a87922d4d25aa3a56a8a18d8c2221c88bc76f981569e8a5f39264f8c40a34f42df30d45d2ad627c7060c519fa8f965e95dd71f0fc304333c95546b2d1042bcad0b403118f8ccea0274786d67b52d6892a213ac61943931a78a85bcc9ab44f31301fab7218da904a4dc3e56332a360e8bc3ae6d4255ddaf72fb46e3197acfd9386102ff46a31d7bddc524c96bad04494f43f497983cc850bfd56b6368bd8a94367b61088faa8a48e8522c37024188cc30171308a615aef01a3140010002068681c8a44921846334dd81b1480024f2a1c463024161c202810160e0e85036140180c0e0383c140100c0603028170182c160f44e40f32343bb919004fb7340d7ec15f88ede742830afa986e3d94d0af7a8c0ba825a42db4210eb9871ed9f85cc3f27acc7e0a245fa2113bca081a8446a7f2a42de98b0fd8250da9c5ef5f669e9cf7ebf6ee06043556f3edcce2173e3ae7f75e1bef50a25200c128a1463b3d894752fb9bd3669799ceab14640a976973de3ab8bdc9f07cfe7ea3735b2bfb92fdfb0d825bacdc08f757373e375bf9813d34dd9cb8444731ac72894ade758d8e5424539c19e16f47a3f0697521baa55f58ce087aad96a942706939d62e71518d74d3d7ef0295243d64077ec09aa22b491a6552a6462bd3e7c2da256a4383541393802d8ba12f183e40ed1d1244c69ae0bb17f1c37f6679a61cfabe97739a66a9170651688dfa3a4ae8ee60d80be8c82328d926a508edd1c89ac52a7bad3cc6f69ca4ca04cf35199287021a0a5614ad8cfad1ec3020431bebbc95302529b176df0db7e01bbea43d620017419ee76cfa16f80ec56a15a32b6dfe5eea8eb6aa557165be31aab4b168b56208d2701a8c50e4af609686040bf4b39369b1a22836a49e4aa10adef69192c7402eb9350a1a24f101b8a821dadf0a07ed52567e36778d54cc530c77358ba203b4c9ca7d796912c7568c7d1ce220282fddf06be03b8fb7d60baa7c69265ad0f3d7a2b3a270fd2c6b80ca3c2408ed916cf492fd589bc93728e7ad8626b68c85aa5fca2605b45a9b94065c6c3ee9feb119ea9240a67fedd399798298acaba9743bab1ef979c3f064e123675fecb982b291750f2afda16b60389eef56688fe13040a53d347687def84ee81e685726249efe896dca3735db51b96362f393a6b1108c4750fba79e116b2daae92fbd65454a5ae78ca6d156c89a6628414b8ddf2907a12a272620ddbdb81c4541a4821194a08694a18bca1dbc0d99475815ca3e4a6eb15b29d627c1030a421467950419629e02c4ed6e20fdade6a6b9e31a9dc6e9fb8f6616305dda8d0c8653057ceb0ec548a603ec792d123b36a599e4ade19535e201516bcc5328b59d1efd3f81d0fb02a87db13126823ee26a4bad180245d007aff4819548745ddf4b805348cc79fb8dc5c87efc183d17a9904da6820a702297324343b354863da2caeb289b742a0b3942b33a8db0c64552d526b0f7acada464a63972558b99042ca001c32861e736346b5827bc346fd6cdbaa8ff2a4b88f9e525151cc90ebb226dd6266dca6dcd263a92b0f00fc36e61145691eba83cced5ceed73c511f750f4e1f71194eb8865a946289f646443ed0f1e3bdff0b27b0b0bd204669370b1ce39c55e7c2cf3b48ed94878397386c5c72a64136e3644de9a2cdc65a4bb22e9d4e3e971ca283bc2729bfe1784a62f13c592d9c364e26b07542110484a70c8445aa21da758ca7f0fa0ade93002b8e143da32a97957e5f7ce72c127e781068d8f4676b8ea0612c20092c79428d27aa8db074ec6b01a6b59298ca99140d114b16d1e5637970ccd60a8dd30f14dbe2e0fec65106f9f25f417926153acb1b77dcca9046881adee2485afcd9054af2e22e2eebefe94411783a67be8597c4f080f105b65df2fbb9b4477ff98f60cab971063b6a6533ace85607ae1d427718b4cc5f706cf2747c6b32ba99056161900a0ac5c60e39436d408bf2b494e1f8d93c516e310741473a67df1b6e74e51384dcf90c4e387f947c38ac8f832415eca5e10ee1c72042d26cc06e8854d42c90072220347b92ba69df8aa02fa0774ed6bd6689149d20c006456301fab337035dd42221899f8c68ccd671227375ab3c5a7a065bd82fb5b690269789934cddcd525703268f6122ca2f8f531a36128547d69a6888f8d3fc59e92e9d7447825eda9f1215ba193817c8dbd87eab9d53b9698165046c9e0df9e9c9582f2241954e238a794a92c4f0610809aab6c4a2475fcea805c2cc4e2bd0d672278547c4c43edf8d8c0eb3b357a1b1ce9af4412f31969c0e8ee10443a4332574641b16946d9463beb13bd21c4d541999646b90507bc4a3c57bd8bd23df9368b5812e93aa745094f7d923716251220f9240954c7c8f9819108c50b7831aa88408d51b4f29174b2be930e5dbfccd479368d76146426e024553ed9199a8ed1775d7fbc41b6e9f33e4194d68c02b31f6f057f3309f578593800e61855cc71dd7915cd5ea4d70c084662f208181b63b7257843f8a3ccfc041ab6f7c1d9041431ce833be95c2a2a666a52c6c80e726083c3e990840a984e7b7b113bd759e1538894f4df1c540381a3202a057295b50761d3c221df1c69c36763629e4bf5197537852f7a0393e23923835350c4129fdc5423800677750904376e1fe7cd8e94ba56654a39b3ac906bd65b0e6021b6e97b46c3de3a6259c5060088368fd1e31ea6d7aca7dfa820e32504dd950f12dc2bed41e01d14d84427060d68d559e5fa4cf503430e86960163c8bc0d6716094ea2755daade07207eea1307ad3aec888933d243a5606a8f5af8f22c1929bef4bd5d67f0a149a66346ebb8172bf5f173c136c428897ee8c6c08eedb798a30df89083b9d5b4811a39c1a14a59a5a1bc3fc0eb5a1b7faf32efd1007799d7564a3e380dbcbe3d9751516a8d2423d0d5452d30d4f8680730d5bdcdc53c860f449da8072d77064a25a14901521972752e97a150b83aaeabc637b714a07a218023f2a772ac87d6aa55e50bcc73e7ab312345d8e427421b4c6b936800a688f5624fc15363ccbcdb908d7f37dbc664a1991eea25a99018f4263b081cca242517f7be5005d6e6ba055a49149831412f46b6c0c5073aa3691cd53e7e2a3d40a00fc64b34c8673aa95c502609d6a3f3514f87881e4ee01dc4d7f8d481fe67281969ac4d102450aa3da19d8843bfa23ad209e91cd6aa832f1d746f7d8ec8e2e0f9443c2489ca7d5fe2f1339b76e5aa82c23b600b7027a97a361c48e0fbd2e02fca4d1951e20589db1ba3dec5105e14a7ddd2776b640446e74bb222a89eafd3248e92db03c77677de3e060cc224b01ce9ba322092125d719631ca8d4c4c44e6d6513dd0b7f83adea0052a6d6a4d0318208bcb21eb2978c7c9c5637583b6a386f013e72b2fbff5bd5fb8416b810139ac375ba48cbd525107acf47059cb7e01b503118163dd7e0f5b7812f220139b54528cb0cd2e7e600339bc7b4d38942f8af1ec1a74bbaccdf0bee8d3b695726d86a312902d027ca2be351b54c0a5aa37b719a1b841c5116af47f46fed5dcc85c728e61b1217d23e2f8b21d5a9d33c135d8cb8fb1d0e18c92a0e5b152a304ec5fb7eb021a654968d48955e0fd5d53e67b697e652173344a9c2f1e89b2fa1b5e748789ec26d89d44bbc7f4ef249cc5230934b0fa9e9e44401db81a3e4e5239d08119a91e62c256a0d572574315b6e9cbaa3b7ff8b732ad64b972b0b65679abb17735bc43ec56a9587dac7c2b8995eeb71a9a86da07766b35b2c2ac2e564a5633ab88d564a56625b41a596d568a5622abb1d57084eba41bae86211d3b4882a4697d76890cd490c42320dd381f9d4c30cc29760bc72a032818e4f5383977ca3b8a6ab3e7854883a3a250ada8745447ac0ab4546d1fa2a820ad1282d85e2044a4eaa34eea350df2f5c2622a3b550e556f95c24a095560854745a2a70a65aa7f62cfa078ae5514d58e2a642aa1a705ee7b4e05a986a8e24625f43e8b62ac2a30594f8761a8e2a20a041654c51b2a575542bf267ff6e9aa8480b252b1ad0a0cbc9fa993ca302aa184425547cc5540f4eb093989eaa7eaf5aaeedeb417681a19ad5780f1c350aa3e559a4a41854d3550394125147af022d0ad02128afcf9b4a908545a896a3d1663a38d4a05a2725059a85e54e5584d543e2a27d517d547a5a4d252ed5115a9522a199520d596aa61a5a5f2a71a53e556091d50b60744520993db181e2531934d5bca5ad16c3c4932b2c8bf5b537ec670cc98663e87d5d96f633290e08b275eb1b0118d30e9467ce18776590af9fc3b38def79eb08c684208ff66dfa56bcff329667cff410ff651948c4aaa4e7cb875ac1687e6ccf0295ab49c96fd8158573e13840121847e28665ede97132cde3e6fbf1a084f549bb297c034b46c4e24ea5c256ccaec239595419ffc3dcd500ba9757219a6636924a6a2da3a0e1b3aa7cd069b29e90cece2b39be3d5163edaac9b476ed4a53e89762e2da5b732e662815bd122b4422aefbcd9543cb4e547efcc0398919b5c6cfe9fb01eae88d2c126abd4ce9d2b4c29d798f995f6dfd8653c4b7865e3f6d001e251ac46b993951346b41b9334aed07f69a7d7c4adb4a581335d7c0efb9f56450623477e3b278d6863daa7268f6004607b5b6a217f365d291e7e64cbacbb6a7c8d4da8eb353f05061c70a6516c079e67b50cd6e49ab568b4b76f607c1fb7c96ee73205d9fee5815f949687ca3ef135cee6694b0d864f55c11652ea88279b8c89e0ea11b5fc6268e76821bb733d42dc10159035ef1fe8e123a32f7299a90df55949247d6bd736a1aaa5ba5e53a655c71cc81085aa53bce0a936e96ab3cb50e1b60993722740fecccd0a7e7df3af77ca406cac51ff7389cc244b1101fed0d3655cdbc26c5b1174415802f2b10d466e9c76294abcdcb0447ca4ec17ff215029e0e02b5a641f99657805f2d005a0107216d93de996529553f7f729517fb99769ab965063c20b809b36a1d8155ca96c48ea53f0fcdd7ad78ca1d1a55bf674aade6515fbd710bc58a3790184648617a3a97149989ef1238100aa0211c99105bc709b8800694f17614798fc02c49c738fc194d42eead80d072b9433632e849afb0f5559c2ef8cc8cc01a5b90595d45d9570f91f45e82dec0b203c59515e41e03cc400b4874af757c461edcae2b3390c8626f2f3d3b289da18d8ced257e41fc74176f293f7bbb1c2e810c4225a3a205810b20c09270101772806c955ed3104e0a12bed718c568b33fd3956a6eb5e9a3b0eb8e15b0584a4b44503121ffb3190936a91c8869350745f5d364f80a0c41bf1861f504d51ed79b310e2401aae3fc0b97118e209801c20aea529307ef38fb19002cbe65bb8f9879c95e5ac08a655c4f2a8f271904bb8a988343d7caabfad0da5f8cf65838001b44aebf16b56b770e82cdeec8019de64cf3efabe4b800c08003379bb887ff7d35507d9d31613752f43d48024b7c73db63810a5e6ae4f06abe205700c4401e6707dfd5c048eeeb704ff074efe870bc99a5fb0beb63e317f7ebfbdbe4f7d7c7f18f7ca7ee1fadafac4fdf9fc16fbfef5b17d2c28165e03b5f6b78a7b75bbeeb47e6b951230c7075129c46c1351db08d14a567c17ba3e42a88a492bd340941e0b94609bc508dd4262407240cf9d800efcac5c20a341d874ec6be1c0e1e22b029e9a8b47c27a478fb3550b143a2510a6348ef54ba80eb01bea7e11027300891988b43cf8d6a76991e19362f26b617030b001d244b5dd21a2402d23e68349d5dacc1f4e81b83bb457ec098bdcf9a27441e2b38075e0d64cd6d9383da5d8486d02201b89ac610886afee6aeffc58c08713f68b2b2f9450bb086d2b62b2fa8cba86304dd023c2f15f3d61d13c0714a5d7fc7a5a0becc66508911b2cf5977eb303cd29dcfd290dc5cb22d1816d1251216024c52a7bf81238321430b484c2113df3024849afabf848300eca0c1950788a2d3a8a4179d2753ef3df31146c32b6179b8ffdc6f603bb00288e1f62c5c67d6c0209224b2f149b208aa9d0b46f5583d0e649f7b2b85d08bca154e608889d0d262dbaf22eb73e3055d0ee9d790dba26d1eef926d095c48f77bf6f7d8765181165bbd94ed5a8be7776bbbd1dd6bb1cc67055e95963dbae77706f84f7a2bae756684bf7852e85ec5640518cee99f73eed2df33a7471dc1de8f5d8ebe3fdd47def2aed55d3bb716fc5de6cafb05e85f79e97a5ec712c6fa4bbe7de9c7e72febbd2f666ebb5b97548bd68de07efd62bc04f18756fbd699c67bdecad9fb57a47c7dbbabde88c15db35dd86eeb56ea2dde1bccbdb292412aef756e80db2778edeba4375c75351175b73375459466fb7eb1aba1e5db9ee8ebb01de21bbd97a8ec68ed735b6cbd6de6cf3e8b71f4c5740379eddd726d1d156f2bb957a4ff70ebcde774ddf5bcffdbbc3387eeb47ff3803ca75eb12a65b40f3d5e226dd58ed9e436421ad317b0bd29b0db0379f71ec85de2b73bdbd6056d96f75bd127bb1bdc77a4dbeb71e02e6f1622cc117fcaacb920986bb943a2e622945bf2e7b3211174914d669305991146c49d4fccbca9f24e42cf9043c9ca76142c2267190f8bb249f66316a573cc941a221b13f892a816a77d6c43b4cf45796e73f966cc82964721f53b47adc9cb0d12f0664f2470644f507ac414e5e1f0860f9e38f7a175fd85eb98c0b88e361e5a1eb6324484e64e0c7c9ffa6c8cf1fef8673ade841b98fa567650788e981491f4be2765793e3210a3dfe0881ff26dd215b41f422120f93c7c0238fc7c95487da34d88d524df842675fa3d4501826d2070a30c3657ccdc10f6e4c8ba613187bbc4cc29fb260ff71128a118534a8b48cb6a88752146e9779af872dae76c3e20743bb3297a190c96063efc4630b64831e9b59c0be8a9dc98d2de475c2600175a53601632d6a6e34220b14ee6f50ba0da3295214fd4d69b44d29f702caf176602d74f081884722dde8a0c89e4ad81bea5f6b9acb52f5c03de799005d29b92d4ab2fe280a8d41ecc34abab949be8bc725213bb80fd5f32fa49e1ac4a693fa901101a928da7d828f72d23e0245122c2e4ec131a70d205451829900758d40dea7e57b3bb9c9334be8dbf98bb52e0127c8526d6b91e8bd8d81dbe94354af3c9a973957c4521db33405cb243027342abc02f45d0002d5b72e2ae1ad10e0b89a793285f318dd7067093c543df3cd2a98893725d6230777715384cc5b946ab73f4972bb03e7326008042627be6ed2ccb9a4c5770e5c46a362f460d71ac206d0a1198437ed750b2897d7f8906fc23f215f5df73c0aeb6e0636037182baabb711f75737759ac5c0fbcc2675e69286e7c3097362f5c9cdd6840d6cf97d812090e9042372fda4256c60a3c9be6273d16f88ccd9c8e5ca4bdb15a9f64c92b2d4c4cef9bbe54513ac67d4fa1ece46d5b875813dbfbad74c2654d3e5754e00309c5db3319f52be30004c6ed5263a95cd79dff9a2ba1e4fa0f785288998e3f094129a1b9d321577c494388a38194c2a1f1dd96db80b67aff10f4cd10a51da130db680d5274f21041a4099338349abaf908c2d5d1350f9d247932b192116422532002388513280514b5c4ef3395628d904afa3acfe112555d334b8e37626e7a6206e3b29a65aa4f8a478db0b899f39c3767e624a5b107a3730e45ccaea97db56c686b705a2f92ce7d886e40c7e9800c75b3d1d18643ae192e97baa9ab2c371ea5b4407d6b116251c40b1e7af48b2d88743e4cfe978e1e6cf93ed0f529a52d6b3b2278d769cbd6e1a1c111d403f759563bcc86f1ec39c3d81c208a838dae2a663ce5a6c42dd44719bb00a9a11bdeaae4f3516bcb8ea5e6da2d41b6fd53decd171ddb09f4f70bfba9529f60e05b8b29dd0b65a4bedb71e2e8d8db6352b68765d5fceeae30cdcf678b544ad2a1473b15508b69eaa2e15aeba1a3147a3be0e83366c751b527b352554f37dda7a232bbada9b6bc14e6606a441151aa1beba4d96f7595f35f854ea4a9fdddd7cb466385edd622efcf4155b71b939f586fdf4abee09bc37b9df7a910baabae5b8c5aed58fabb57c9f94744dabd916c1eafe6cb00ae3ab554a33556136986ad59542ce2c16d9455cc155f732980eefaeff19ef494429842c3c6dbe4cd85a09d45352ce00ffd04ee5ea8033b81ab48093e1c55ef7a94a282aef955888a7f19bd8344852423318efbef423b103b82592fa5b061f026374abd2a852e92de00cecbe25af66a82d021a3f678db71897b3cd3900273bf32544c8c32003201d3e59e557f0c6111688fcbb418858da3c2d41021b4c090434ce22ad6b7b50c571e36de8984a79095fdabf05a8492f1cf18386fbc3a62164f35ea65d158410f5199bf206c3cf5e41fadccf1720e6941d6d19e0e46788c6e47c3d9dff58ab18f5f4e07d27aa37a9dcc4cef45f7c17a0ab0e438287d165b2d62b0b2c734a8064e35674bced13bf88a4cb4d31067299b3d210ec92886698e8f5541295c7db56964ca951964485c2ea86fcb69e53c02340a77c361d0aa2a70ebb74bee60f17cef07d7618fde9d65dc42f403e4214bc2eba4153d93dd2eac6eb211f261c402f65dc5f7fc0a6a5f66b71d209bd630570a2fee27f7dd0281a7384d0d84b7d0b37005bbf42790a2cc00b9820ea3946e151fc8429797d3214e1b04dcda4e217549f52faed6b9ae5d9bc785690b37a72e62af53a3bc05608c1b279e6a7b5b8fa7d8f909bdc2a3495b3da724e07683c2257f7027d7ac8294bdd24fa6cea72ccb0f445e050fa08316dffa537de61dc58016ba3c1c700642030f0188c0c1606aa64b0422df36dd2655032f0196c3e0842f83af070a30ef4980e359202d23603a4015307cb5c24f7cd23c145003e061b585ce60affc118fa2d61a9de2069c01a7cfcc1184879a657222186b06910dbc1c688a265511b4c1e0eb4721031780ddc0682065b83329882aa4f2d27ccc894d39301c1a0c12638b6661aa537206a899f3c06636e375df292077d091110a45cd8ec220a7a96b0219cc5c4c2834decfdab2807083361cf86894012ac1a6153118dc8d406630839e4160aa1bf83374284838dabe47297541236398e60b12800160cf32e2b123a8189cdca371fda033621cc642d9d37cf208c18cc00c739ae08063a9881034c5f3196bf751dd89730032a4054096160e28315543b98c6110fb208f30ef22644105c18284dd8eca574882608d10791266c43d858e5f60b5f1136900e8cd00444ed6467a446b892acbe0898069b1dd6e489a511c61013fd0a8812162480206c35d898e9aac367206c4e18cdf0110f66b4173807bc07921036e3035749d6c389ad114eb37586ca68411e8246099d481ce214b3047910360ba1902937d5271ad19b989cb072a3d2c91d489e1ecf08800adc2ef0625b51b734018904324bad981b3164932c27550cd0958f1c401e4005e002f00178029c75c095d1a8285b116004301560d9014c361d337dc0b3b8000c648dea82550026f25c4cc305c0c88b734045773e4d998c6302fada8b9f3760b26639ff000000000000000000d06c9488b545d2ac4c524a7a00d4ffb5b7847199524a29a5086f67e6f845daf01769c35fa40daf0017f209df09db095fe89ecb3a866653f68ea57fa2c48b8de81043df5a9e5754d27d420551111d61e84b6fd45cf259595445447480a16dd1d910e2bfe7ef05d5d8c206203abed0040d9ea3670da1e9fbf9a1c30bede41c72d2d4911d3944878e2e74252b4374cd5dbda1830b7dd4f86432c66c72962d5be8e3a9088daf17ad4765bfd0a185d64709956d2926647c6a7ce070191170e1e2f5c4d09185929f590a2ab6040b9d9ce68fd316ad6a3a11a4dd076c2006083a503eb2fd3b53c7a4438715fa4f596df2e4b4868e2aa466f1a9a54217ce9308ca849079a1630a5b4593215fbe5439438714fa597113312c7f98ff3ba2d04bfc0e666262082977a0d08e54dd94e13bfc86d4137abddc9758aae767322774328b6ffc88294de842bc7516f1c9740a29139af8221b29bf7ffe4a5a4217a2c7102a5376a64a5142b3e23932e8670c66f924b4917d2f574e4c27ab48e82b7c663921938ed0f94c1c8f9b9465850e23349aff12d32d450dfd8bd0264d1d7cf3a825157922f46649e3e9a09a344b3ec18d1c1c838e21345af6e3279e39e81042d79a23040f31c7b3781a8fcc061d4168c29e070b1bef22e4a269e800421f4544ac0e4256124149cdd0f1837ef285fa79eaf8a0c9a23b9e7278040da51eb417533c79b93cc7083268e8e041a3fbeea14573954a7607bd99969339a42725552d43870e9a98b1c594cc6e6eaacb41a79d37929e2ff9bab1e342070e1a95de718257899c74665be8b841a3a2645b2496aad061834e0521d7b2a4f835c9e8a841731d52f613334288cf1d34e864765121860ed67f31399e0227b8210211dc193a66d0e90d17492fcf85b28e0cba9e68a69392e25d9977c4a0cfd9989208fba993671e1d30e87592124929378dd8a617b41ba2ac93c8e147fd0e17f4d766593b45eef25bd1ee4ac89d8487e7d141ace873ca3a2a44cd2aba0ca122c908aba27d2def3c69562ada705d3a6ed8d4264cfb0215bdc7e61817b77a718ae694ea051153d222b3f8c2148df897dfbeb2e8192d04bc284597545f89182584b79948d15fb41ce67aba43c4e028faf8cce14936ce688889a28be1e5a49c27a52fa75e84a20bab31582e9d63ccf881e2f82107a5338c6c0d2f3ed155c6342536b525dfdf138d85bf944ef4a63e6a218893137d509a7f7664c6579368135e6ca2f9b3b0d010665fb2af89768466f278b135fdc299e872b27c8b17bc83086962a231313ad6d9f4a8d86f2fd195b9b9852c1327e5b2441b7fa3c8d85163cc49a8129dc5d0413788e4f3174389fea299a775f6e75e3589d6ac941e65f152b6f042126da824a2c731952776b79168dc4aeb98a750dd2f42a2ab48497e441363ce75119d5468695a78e18846581895542e2eae5923fad6f3897df2948b9030231a9dbd7b62deeadebf72aff062119d0c394fe6e63d113be82f14d1566586cb25fc64634c22dae45adad73b49ab5344344ae4d7e829bd3d7a24032f0ed18ceeece6c8f92b82ce105d55852449edbe28441f271e9f520e11a275d19493397b83e8228e76fc98351b395e08a217f1e241639893264181e83735dc649809f9df054417640a952a8c56c6568ecf2206aae1693578f1874e3bf6235fe5fdd056860bf24c57e9f8f4a10da2e389c81a26b4797c68db4dc614e25228e1eb1edad29e2d25c7fca99cd443232fec66718bbde0451e9a247c26575b8f87366a1ecf417347f014748746a950e9b94526b3ec5ed8a1931954a37acc9663aa179081c313c0a6858be06a94c0c60d230387cb280fd8400c05bca8432752c6d4a02f49c696d2e10da6beabebef1783458c101c3734687872e142060e97e10fd8400c15bc98432742580ba3279a63951b36520c1403c7231b356c0b08b87021038727c0858b2d6c9cc01bf0336e54a0010d88c40b39f43ee243a9c9b013448e43f3a5730a5984160efdc75610da92ce99be6f683d7fcc562c31265977439fc47b68cd8c6943977bc12afe677cff081bfa3f99bb53c6ea08a5ada15372545ece39ab863e469a8513a331c5cda5a11fb1ff1b3ec468e8f377de9809797186ae33ab93c9907962432fccd0a9844d539e47c59caa0c5df814eb2394e79482870c5d0e5d9a523c750cadf7c7c8cc7545984dc696a31a9f85c7d0628b1afe340e92e085189a9c333ec47c4abeb446c6d6711a5a9030b422c55742b61864cf0f86362b7cbac5ce3108dd578cdac38b2f74a97164f0aef645e00fb88a517178e185c6729e90940ee29b49ec422bbf41fc25cdbce0425b394e9ccae4961bc9175be83ce77c5da91b2967f985169a4bd9243d250b841759e87392c9538c481a9309110b5dd0a3e44ed24129bcb842ff19bb1245e95f58a13fa1df416232cf1af2a20a6d4c3a678386242ab49e2db9c2c7bcf62f6f0aedea64df3c22c8c93e5f48a1d15c5a9a77de175168c7cab4b2e9ff05145a8de69262ec64fa84a7bc7842ab93cf5284a841e78ee5a8f1316c20b6f1c20966998cc724cfd295813278d1844653a6d6121797b1f58209bd8cd2643163d22576c7e14fe3c68b25749d2644f68f2f132f94d0ae7fca9f3dcde32d4f423b523b3e82845f20a19373ed1b3582acb49c1747689245d1d556d1089d92e9f9822a11218b854a785184f644c81946dc641c3711a1f74eaf98f78464d3d922bc184257e18216e13145841742e8b34547c8be9b972a18843e851825f5e55249730e088d7ff0ee513aa6281afe4117629e903935f2c207cd9a7e28b9bcf4a0cf94983187aaa98ae10b1ef49254e6b088e30e9a718ba67a2ee71036a783ce33765f3cd5acea15165ee4a0c995e35b49aeba92100eba10fec428a557e1c50dda0ea2a16426bcb041a324c98bf96729d97ce0450d1a5d61f7d4fbccf3e768a06e8e61f51733e84c6f9e4839ff5250293268942cd9b9e43ae2e72c062f62d0e6d3484127e60fe7261834b12726b95f41eba5988c2db42f5ed0eca8e0b194bb05b3e0850b5a19ff145d7e3ec7b4b4a21d8da07dd5b40413a109bec6ae6000ac6853964e79724e332bb48aae634cd2b9f247ce9c32b66accc8e20da26000aa68546c9811b11f7312948ac6aa5c27753866282ad8324fd594f2f24f821b5b14e0146d0aeb5e39e9df232ea66882c605d79e5329395b8a4e874794a8db2105314292714a878a0c06308a5edf2d47247f4e217944d156f7bf56f61000bc6000a1e8534ab2bf5c5ce6c4078a4e5b30e939b62ac948ed2906f089565b724a912f9e683cb3b4777bf834e9b9a20057a04e3451840a913ce7b530004eb47a1143b69238e3bc0136d1b84634efb5501a79441e0c4013eda8f40aa152939726135dd00d396f0c1f5512c10da7e131723c8ea28a89765436edae14cabac432b66c90600770897ebe52aa0e570dc012cdbe2979d9216274f22bd125a52987ce12449e6c204a34ba395ffe1fc78d1a58b870712470e1026f046012039844a3e4b46776cc4f8d3936b488e1350049f4e1b784552c1d1b59d4b0110387933a010d1a5e01172e68d0b01101172eaa140388442ff1752ea8e59068c35bc6155d16172e1ed17be71c2cc46e896f4bc6d6b2231a4f21ba5ac997e89247402df0a0439f7f25bfc8f01cdab418b3b2020f393449c71c09db6d1cfaab24734ccd6b5e56c2a10972a54389cd9071c52836f07843d71e2466891ae6ac7337f41d94d04cfae794c428c6c0a30d7d862453d079368a3eb1a1b590ad8862164c95716af80d537545051090802b2ad0802b5cb87081c71a3a9d3395ce8c512166e7918d023cb2f18042ea85871ada59b98ea47d79c3e8a4a1ff8d1d2adac3686863679207622d9e77f86c3e8d2d900d0758dd5033b429797ee8d84a61e6df8840d5dfd0e274860870780912e051865e626fd808228666abb00719fa605a2a3389cd1f1ae52d32e031066490b29e8d009a193cc440058f307422770651cd188f8d1c35667880a1cbfea73766cd3cbed088a9c7301ee48526ac853ca2e4a80b8d5cc97153f2adacec70e18a225f467cca6ca10959e5a2853eaa788a163564cc9eb3d099cb06b1d0a808095ee599f4a56825c393b4609d151a8f7ea247a9089563aad0a518e583c459d111f4a0422796a6346572c8566c0a6ddcdcc91a5382574faa3e8b1bef804c067848a1cb902a7a18d146a117a1836815cfdcf2c1f2e10185ae325eb8cec8794233726283ce937142972fce760a4a57f0246f429373a5707f1113fa52b9c143fca567cd2ea1533173f7e2e6e07ea512fa68a23a0f8f24b4a62f7fccd79e622b8f844ec91c322725848ed09bcc2172f08d5ed61b23b4e55e1a52debd085d26b9507123ee795489d0e8fb964c16372486108f217079399a84d0e498bb64848f07a1fd8d15a38809089dfaf687e749cfe4f10f1acf31674dfac90eb17cd0e5ce962b4cb0cedcf42015b379bd7d1ef4712e3b682e891052baac83368b50c9ccdb1cf4f9d52d1a39e65614079daf871493c774837e2cdbaf847b52e5251b744984a8faa3d6a01317e3a65ef7890e0d1a25af73615d3a85549a41a3f96437fe8b0abf0cfaa48268eeec1aad120343a9a8264b250f1834af218e0515e3530479bca08de6ff1daf372621e3e18246cff2b54b4a2bfaec1f42b5b3ac68836f292d22fe2adad312ce53e768e7ef55d1e87ec668ba6265b64f4573328486123254344afc2f6a129554f0146de54db242acf20d61533431c710628691cf1f45a5e853089641729e148d27a167fe1f459f6f2a7372b1fc151245bfad1ffa4125252e27149d301147071d3da06883cc5fd9609e4f7411c62ca43093bd499ee8334e3776e53bd168a5707965e6449f5404555a4cb389de62e6f45331a3893e42debce5b26365ca442bc1cf345cfe117284894e46d684fea7f6d2b9442f93b4570cad25ba982426aca994a46c95e8d743eaa43ca88c6c94687486c7bb5f3e89365769a7e49d44f4944ba237b7fc31298f449f326439b52463a98144fff1624c92631d9e2d8fe8fc7fc4a2af8c6fae38a25f8d22721e2ddd18521ad1a74c4935b8468b3931a213dedd39fa223acf49dee7153526ad22da34515264c6cfe92b27a28de7abc9628e11d1262f8b125d8452a2e243345aa5b3414f10261e43b4265ddf63ee5b884e5e0abdab41d7525f42b4a6c372727707d1b887c9ae96748a4e5710bd868e9c458aa8c57203d17bc6338d99e24906107d16213b87604985e60f5d56e5f89c41f9a6203f74627386c5389d8288fab087cf3122e243a7847cb170619348da43bb27563d73f4d08bb0b6b69ce7a1ddf73f931f7c63bc78e87368a41483f20eb85f5c6a87deb2623ebdb40e8d5e5cfe2a21ade744874e774bea84b79852670ecde48f984dc4c98f1c39143a88f8ca8a671cba14af278b8c9eae6ac2a10b17999c437e3d35f30d5d9e4a34a5945e6b31ddd077ca792ed694e968d986f4728b06917136349f92f0ac391e47e76b685c4ec8ea1771dac46ae8e274f87f9cb294b469e857af4ff753c771130d9d85e097428767e853ded914636cd378a119dad59331998f65e892af56084f2a23629c0ccd9f4bd2a816b53fbb31749ab26d9934b3c4901343235fc233bca4e9905c187a1119cf2829694a4a60e8bfcb3b84b23c71de2fb4ea99474f4ec6a44b2fb496829253965a24965d6893d2137a41e87e09b980f89082b685be2a2b55d8913bd2332db426dfff4fe8ff5f6559e86556ce449ccc9f891d469590a69695748526c94b119eb96304a1b242677d22245dd913d5a92a749143124957b5cc888b0a5de9b19c2f9e45f1c84ea1cb59dfdef4a4d08bfc48a6438ce9c8a2d07948612175b98e070a5db6e05bd1c24cb9f584aed7d7e28a8a2773524ee8733395e6b013476f42133387146216fd1326263422f56ecc66f153f84be8c5a25a8eefef23374ae864886131041393aa4d421797bbc2e9915d7a22a1cd51848afc1a47778ed0757a4411ada7326246e8dcb23d76500f935345e847e81e21b3a1244608111a1d29ef885a1022bf6808adfb06f949669f2ecb11425f594a0699351e84c674a2b8a977f614c44068a29e8ae19a1ff4a734aa7756c9929bfaa00fbfb9b287912d27c61ef4a242e4066519e3a2e3416b9927fc08d15cb858cd030176d0c8d950c23da92020800eca99e13163413572b5b9c9888a98335e16c7590d1b7b830039684b4fe6d41b8d91e3b360cfe106b0321c7451532d52ee37e8f45998dc682a4ed2bf8c1886451c40001bf43e1b2acc9388399554835edde7434e4e0e973d4f82520720000d9a9f194ff197baf72db4a83123868ce33972f8568e2d20f037227080095ca018800033685474b2cc959f548e2d205043010798c00538dd20c1d1f810dcb861a3868c8383104006ad0791cfcdfc174080187421650b979c434fd2210d1a5e801c100006ad779b101ea344649cbca0fd90945fbe06190f0f015cd0bc966c915fbd4c49d2d18a4e268d494eea181f62a6b0a25149e90a1932dc27269555347a728a9e891f46872afa34b3eab89b343368d0f05463061140472ada903a4b789b52aedbdeb8d1a8e84da7be57bc98e4995754000126785443012e5c98e0518d19363a4ed1670a89a693f498a24bf9c8b9964d58316acc58430a58414729da5cb2831295829f56ec7490a24d62a4ac89753b46d19725ed2639652a914d87281aa5e4cc798ee73f2a0f4552c5f374944e46a00157c8c0e13210147b89fdc9dfb071281081065c71fb095b4f68d1d109ede084766c423b34a11d99d00e4c68c725b4c312da5109eda084764c423b24a11d91d00e4868c723b4c311dad108ed6084762c423b14a11d89d00e4468c721b4c310da5108ed2084760c423b04a11d81d00e4068c71fb4c30fdad107ede08376ec413bf4a01d79503c1036a874cd9202141a1d77d00e3b68471db4830eda31076d42871cb6230e5d9b3e117d3f885a8a81439b5dd14c9ee8cedb56d140c71bda28af117c6345e674dcd08e76aa48d9781b9af0bd23c492880f0d1b9afc7231835956ce5b76aca14d210591932fa4430dad5a48e26355b4230dad5a94d8ad1fea40435fde3e22a2c7ccee2aca71039595a0e30c8eee7a0e2175ca5fc6568e2d6cc4d0c24b80a3941a0f3accd06eca16393b6545d1518646aa08cd2243450fea62a2830c7d2679ecbe0a8dee129d3d0511157a593d0d13c653fe670a8dac98cdf289527a72293492cc3d4327959c338f425f163e04551114fa7cd3414aceca13ba182bedd2ab38a1998f39a90889263ec44de8c74a5c8a103e37b48891c50c10fc8daa1360c18426c83edfb90a2a95c84b68763c9c582e33cfdf2aa1d1174f85cfd426a1fff989296c14a1e3a8486837485395359c47e8734839c597cbb7683242574a7910a73b45e8e369f790a93fde5390084d7c5f932c161c42bbe164728eea906448088d898e98abbf0b426f72f2968a7740682489cba9cc13255bf007bd0711ff5b413ee8d245356911117e44d68366c4080f7e211e3422c9139944d2f5bcdb0e5a11a62eeee62984a9833e6326b1246339682fe9f53c524b45dd8483562e88f1b0233f69ccdca053f1548c9737b1acba10b0b0413be67fa5bdff3cfd5483565f4d648fe14383fee3646ef86592a3971934ff3172531c15d2dc94411b45768ee7a03ccb081f470cfa38b3b926c39752ba04832e67e80df365a1b4ff823e9cca95498b850bbaecb1e1b22b728cd5b7a2dff90b23a6a383a4d221bec344abe844a4e70a561e55f4953c5eb8d6b049bb26156dc990bf59555434a74909cf4e266465e6145d7e694939996ccc1e53f46726f47f672f4597d7c2a4e86747e4c96e2122297d148da7b867fe9b534c998ba20b1953f35e5209328911f2b28c05650245a7595cc3bcf4894ec643484af982d6139d9ed857d92c9db82a65bd1027a416c1e0446f4ac460eda34db47a41290931ac4fd0d144a7836e32d16ccfc65587d029c998783ec42a5530f5129da8a425c994534b746aa11bd994a720645a892ef799899827be3d4f89ce3cc4ebcfee243a95922473cd31e84d4aa2f964212e960e23d166be885e79906842f8a856aa5749f98fe84412c2428a7fe1f2695b68e188460449fa256b8e085b23fac93f1763b94597486244f3f9bfe19abc54d2fd221ad349799e0cf38ab3221c61d2376a485122da10ca37a5f68b8866652e3526390f8fef21da1ca2769e88a5219a9cdab452cc24af2b2c44db62318cf2ff08d19f26f95842c975b0dc204cbae33b4134572d9643ce646c6c81e873320d994ddccc0488ae24ffcee456093aff03dbbf222d7b2c3ff4aae20f60f4a1f3d63719926a52992d4a80c1877e7265ca4eda82beff7b68cd84875c12b4c4a7bc1e7ad316c4ba584f1ecdc94317f405393956994a3e78e84f56c8514e63eed045cbb95bbde69982ecd0588c9c51a552874e9f7c105a937ac558a143b3416559aec96502060024c09843674a9fcc79c4649098954327b206d5574be3d0492d5d8b793b76d2261cdaa45df9435693cf317c439bc5753689085a7eb53c020c37982284ce51d386de3d4dd6b36cd033b3c1d8d9b4a9a66f96a43534db39ef2411496a70440aa97b2b696873dec949a3c5ef57111a9a519122df744578f19ce192b950a995954433b41fab1da4c419f34e656c154b0146199a70c9f44429914d7c4486b6ddbd2c04d3c8dfea189a51d75429272531b4b982ca97356ac2d025799ac154ccd9b2e360e86447b50e2a5b9cf6f60bcdc8d821b887d12532f4422732584c1583ffc6c68800a30b5dcc16d1eb495ce8926ae6f776b352aab385de3ca9e63da921c610d7429bd94d3de4c611d25421c0c842eb1a4e2f88fd9c421661a1393141b2c4c85ea19f0f3a889c5174ca1eb542179f34760ca76e4a885568e7726508e5a1422336c7d331bb20c0984227948918848cafea1262020c2974ae95ca32c958dd258a42a7f36526c99d745670a1d067868a1c92928e18b127f422b7bd7312296fcc14010fd0c24550039700c3098db236f37491a7b5b24de8845ce7fc3d42474ef1b7a0e19600184ce8e49312e91673d0bd95bb323096d027317e9eb39e49114f095d34a1c2e34bae8e658e1b3628b0001849e8925a8c944108f7d421a1f95ef7f00f31870ed923b431b3568e52d3154f82008611da9c4ba15a1942a25a842ebe49f94ed199ac7488d0682a21e227eba6c872085df6a032415a8e99825cc6560c2dfe861604053084d088659223f44e6004a1f9aad822727a20947373c8259466f00d09307ed0cfcba657cf6669366ea48201183e5063ca8a45f08af9d92b2a80001c8603ebb800a307ed24655512e37f4990e3283ce8520c9eb73d437c01183b683bc9b2a4ba93ccfbc91835fc18f1010c1df4da91b2b5e42a630b460eba686262d27f6900060ef0c939d4c347c6de1660dca0f72cdb2be1f349d97d08306cd0448fefdf8e2119316adcd8c2140ac0a8411767b4668d947d96372b011834e8b39724d964116228d10360cce07ce2294616d5cc9b8c2d19b4a3fad37d2b45d6fca01abe1d80110374fe8e912b7f6add701a5b64f1375605306090ce31ca0a305ed0e40931082dd1aae2335a9fc3736ce100e5000c171863d21a734e13f1b1d40a3b5ad0dcbeaea800022ae0c205a26143860b17e6050f56fcbf6dc2f324cbc4a86123860508bfc063157dac2c79cc4c4fe58b39723c0e7580872a7a4d49c6ac9c3f2ef04845271a94f4dc98e15a20033c50d109d56c65217249d8a4960e3c4ed1899d513a33759e04346c307b98a249519358d3314604fe377250e0c63f0d3fe6048f52f45f497af5555f06cd21451b3f264cf018457329e7b4a092e8218afef727c6bc49e74c8aa185088e080a70021a3520f0593c8d192498712302347c8b11f449c123149d88e8ac7a9648eed00314ad58ea89ce8f7ca2bf503a467f984c316f50f0f04457fd39ccea24bdf1abba4a8f4e14adaf533e5c9ee0c189f683889bd07b19cbb42f786ce2903911a937c6081e9a683fb5868f79750b63ca442f4a55d64e4158bce081893eb7e885a78a0e15962e785c02a56267f4ea09494b3441c5e0c15f3b454a522548e1d9a1a6ee924d9bb7bb4ccae7cad89a5186e04189f674d46fff9c4da215aff8dc299e391e070ec3bb838724baca2a133dbaf84c9023d1a727cda2bd3476f8ed40a29da423a41474fe83be8fe83d8593d9ff63381322817a38a2cd31ca72ce8d68535b44e78d2160f06044173274cdd75369c8d06311cd8f06f778e29f1d3445118dc8dfb1540e9a2a8908091e8968c42b24f687909e646ab8c131032d0676071e8868e3c6e09254fe1e992c7a88ce679499f2105350164c3966cc70190570e1c2858b1b7818a2ef3739ea1d495e9010227814a2d370a1740cfb272ff484e83472e86b5834a91f92836884924173468bf35c3a14441b215b92b9b19b7f4942f008446bf293dccd7c098207205a1fcfcf0ae9a2a6321c40f0f8431ba48739f9b1447ee0e1873ee694b993e5d1a1c4028f3eb41dd761b24905a1846367301f1a959a23c42088816cd8c8820b0c1e7b68a3658ffd13523362e070196727989166dcf80b6051060f3d7439747432b90a934d270fed5f0e2622e7a6fe140f9d57d498f09563fcebfe0656033ceed02837a53a9688af496ac62b50029f405909fc46013cecd06fce299ba8e845d6be0e9d6cd5eb8ec193b1e5c2c56771e303288502c4a0cf215aa7ce7ff2bc210cdabc231f23e6f4822608136142c9930a0570411b42b2b00e2ae86ff2b4a28b9d6f1e4d934ea6d6072b7addaa1251b1318818f4b18a36654c5aff2a2b9babaa68f34d478e5031c43e52d1578cdf1f2c76f6f0818a367a8ce9a32c7938df0ef1f0718a2ea43cebda49a62ce1c3145d5b7211627293057d39387c94a2514259c489a32b0ae0860f5274a9a595b26511fde3368ae637833e75dddc5a42a2e8f38ede5c2a55e80fb38d8f50b4b137a8f788e76ad3aa290c3e40d105f91daab447e7a0da8f4fb4e2ebbe1b36278f1fac31633f3cd19f8a7daa7b926250ba8cadcf8f4eb42faa99339208f8e0442b31bce61c3926492d62c83835b6701af7b1895edf3f248ec887263addb97b72dc929efbc844e73b2293bc995c93adc61637f803136dce2046a498dcb3cbe6e312c5c9fd7296d353638b1b96480761429af454a2393d29af7e29a9247f8d2d6ee407255acd219a5f588a374991b11543068e2db420e53928c075de048f1f936857236636f9493e4b1ed928c087243a8f39c78999a387f812fff011892e4bc630d9848cf07fba3b7c40a21d1926a8169da735f747f4a3f47455b85c51800938a2915e2a3dc78812ba3d96c34723baf8d4a632e227ca930a30357c30a2d19c44662cfdcc2616172e709002c3c7223a0daf490509313d998c221ad1d2145db724a2af8a987352954564084144e3b121a65e583d1d9543b449b72a5c62e7301fb980219a0fdee1b45e5e88be67c4aca7cc3f08d1969ef89fc475a694f431884e368f783599f3218852498f61844e32217c04a2f71769a6c4fae66906107d9b84d429083ffed0c6d0a8f329af8e72cd871ffacfa2c368d28d9754d6873ec7982de6f00a1f3a913fd9bdf48450f95ae1630fed09e9b1d7527ad2a0d543eb1ab3af073f350f6dca0bf7030ffd088b9f2596e497e4c0b1058a91458d1934500d971183cdc71d568f21e5040f7a8c0f3b34eba137cc544c1dc9c0471d7a0956e2249e9717f8a0431f7459bec81124f855e6a0c411fd9099e2c00f39b4fa417a4fca39316426638b3c0afe6f24172e74f011874655c59e6849a53862fa8043ff723af4066352d9db4145836a6dd0b00cc1871b5aadae2c156d8f943a3668c440550d30001ce1a30d4d5029b48807cb209b0f36b41526c89c93f4fc319f1f6b6875848e95fb454b7a2b636b86091e003ff85043237272f9628510346b62d8471a3ab1eef0399f27c263a5071f6868dc457f838a27bf9145e619fa1c8fd721a6c8df485636f83043a33b66cc25441e6f2b95a157c9a93f482c19e2e3e1113ec8d086a41da35f15e39f6b46f81843673a98588f1eae5a530cc28718ba70af702129b6694d02c247187a331946ffa834a915048666fef4fe6b8ed9184babf0f105a35b6ff98494a352f8f0421ff2989c8b099ac53b5d68e406f538990f1666e242a357deca255f5649930a1f5b6864083185a5ca21576a01179554ca0eb9925968b37598f8b1f38105ce640acf5d7a841ef8b8421ba364e59194bb337c2cf061853683279d573d5a840caa42bb6f6139c6b9780a95cfe1336ee4702dfe46a9297c50a1d5a0357b538597e825195b27468ef320f81bfa318536895c9663c36c6491c9d8d202c71638f0430a4df4a4da31641585b645851483b6c8d83a5ba01a33a07058091633a8f647646ccdb89103c77d3ca111597fe3b5332387161f021cb7c58713da18214e3cd56416339ad0e79ca363c7d31771e6c2f1c184c6adbc7d434cc614be89413e96d0c789bd561a9459b647c6968d1c7fe843095686654a51ffe7440fa0c0143e92c095e79bca7bee14bba200573ce08a0a34e00a327c206113e29226ed65617d1ca14f2a4b86f07bc26488e4f82c580c1f46e8f3723b68b24c32a445e8b4f2e4645329d1324484bea3a8e610bfe428f50ca1535a3c64543c73e794b11523c76781001a4e8246394cf0349c04efc2c50d2d4cd065f810423fa663d8789e92b657540001577c0e1b17f01c362a70450168d0f0c28f20f49dc4456bcb5920f49d29269d739025137cfca01f21af73649d2816363ee8bf828e619258fe659c2d6ce488610371093e7ad06a875d89b9c43ce824e714afadf7456326821d3c973c6c5212541df431257daa62221f39e83fc45e854b41e7fc390e9a1c13ad4f856ebfe9e3067d8e16475b7c8a0ddacde56b399624cf720d9a6ca13f4a248906ed99e8b2a8a7a2e4a8ad113e66d056122df937e2a4b6a88cad187cc8a0cb35953c890da5eba218b46172335bfc1e0606a55c3f9fa82863ebe3058d88e8a752cce95ffc917db8a00d6b59d994d269452752ca691e4a94b15582af5129c08215968c86f896b28a7b83e5a91c010b55b415e4c54d3148f524b154f49164e2e790723a99858a76a4e506a14d6e7c845811b038459b92d66c0b296c8a4ef49448cc56eb183d45042c4ad1fe29f99c298b85148dcbc6d19bd292897b3ec062145dfa840b211145fb3986090fcd62118a66e454688810c302149da694a3846def138d7f892092beec89c63f47084a05a514b0e8449f42fb9e5217ed93474eb49d84596cc96da2917bda5ce2569ae8e34bf4c77494897e946fe78b22a388ce60a2add2c899bc4b346742e8789a432ca12596684c75d49311479568c3e3ca259aa7c6f828d125179d5b35a41299a249b4979f64574464d06e4aa2ed58d2244ece45a2cd933c95cc49a3a71c21d16b5a9fa99cd743888f68849e982bf526a1f5774497722b3c65ca35a213339dcde4fc8ce8daf45fe90d9b45983cc2acc6b8a7884ec8104fe28a08915192883eb7c455ea0822a2d9f1d3b9c5bb43b49f96313aeacec4d80dd19c52a23b94980bd1486fcb9074f68f372121902539294f4b924134f14f4a54913141f4bb4926ff594d206c4b32c424d15140e42135c6648ece1fda0b13473e4e16ad94f8a191f54c416c88a45242fad0e8dd14a1b5433ef4e1329b848dff9221db43e71f72123991b3a0bb1e3a3d952de278bbe98fe6a18d713ee58e88f1d05abc77d8900f2adea19332922dc431f9b1a61dced21a9a3a5ca6238e859852e8d05a76cdcd3c55ada69c437b41743d4e7f6993961cfa9953aa2ffe34c5f6e2d08e0899ac42cea5c94b38b4e241874dba226f683744fc121f4c88142f6dc0c20d8d8491292ae6601bba20d152fe78180b36b42b41a51446a578cd1d166b6846e51c3534a7540cf1a6644a05b048432f29c5bd1039248c7249fe010b34b495fa42656ec534f11a018b3334224a8a097f2263f7880e5898a14f25e73dca4339605186466c5c89fbe4dc9eddbb376041862ee812a6654d35478ea8018b3174b27af1424a3219266357062cc4d0a5bcaf12e44d46f4fcb88045181a212d09b99944e9e68a8693c0c60d2db4d0021660682eb69a5e8566a7148b2f64aa7fbd8cad1931b0943a00f8000b2ff449d7e297dc32a541d9854ee65691215670d323c2853ea54aa963e66c01165be8b4af65732d9551252d34a6494bfd4bb5e54d163a9966c2e48ad2a4592c74499867859d28b97285be839a98acb000e0042cacd0e4788d9994bb018c93a8e4af45628134128a44227124c33048f01e01b3130800183c2e8f0622a1609e06822a7e140004572e22443a2414201e1e18168ac30261201006030381302814088441c14040200ea3c441221ff369839f24c1e7efeefb444b946a14d67fa5555a94aa8ef54fee8ae5244d40f693a8bc2fa09c28a9eb48e8c7d3538278e7bd1fa1b35870cc244da6665292844094c941223d641d5656ffb8fe06a909038c0f371588b76e81fa0d8e312c7dc984464efa20a726aa747e0bead82dc9e8424fee1819d9645184e80a86bce26a73a18aaab4bbd4342dc0b6339234885a7ba0a5a489a768bf7944809108f01674b3f466890a601c9531e920c4a32d27f68fca9b975cf96e8a3f614975b8fdfc170abf168442256686cac8f12f0df1456fba5ea06d508bd11a56473c24947ad36c5eedbe2fbe60c51c10363f93b334077054fa402c1a7282d94f55fff9c139b4e9ec2a33b73b2407f54bab81665b685069d2364fc598235e00622353aa9e8f292154d2a5d86af40ff90d91830b930ee2ca01d8cfbb1ff5a49821d9973f9f358e6aa627496d97a776bb351d56342f23de87f7ff2b3d95fe66a45d05b1ca1aa94daa1e903059646e831d08c5ba1eebc60f085ce334db123c78337a0a315d164a10c6e2421f6d3606039b9e9def95ffaaa9257b9ccf828411f518ab8fabf7a80b4f96c696546e625071219e152554014acad5095b7924fbac526f46eccaa9392da13d4b7870b28319c4195c14a12cb177d1786fc6a038da84f73ad7acb015a4d8d21b5527cf136a77512c4934ebcfb5965eda3c090b437e2d6aaa4b2e25901984d0450e124e82c4edd8a07e1f7f1ce6ba34a67f8eb7c8edb7968bd9da3de782ad9c77c18d5aaca7abbed1716973b2b63c49cee060aabf4c66fe5a7a19ff6d29bf7d9ff7a23316786b22e4f464f84720dddfa7d0212beb49ebcacfbdba59f7d9a9a1314426037eeef624ce6db040840c6ae0195488ee28275277e3a4a56e5cadaa490ec81854922839adc025780520e74fcf97a78f45a2536e630e2d77091d2ec428b7f13b05f1d1137733f0271eaf059f4b06e64f8149a5a82ed993808a92ed117ac237726b0aee9b062bbe0585b0997c60e70022c780fd74431709e844bb96875bdc6c189e26cb886057664f02dc492c6076f1bacab773d05d5e11682421dce410bbd0a2b05861b15316c950632de2ee708dcbefd05f6cc58a9fa1e2c23ee669bfe93b72d1681865c963e759c9e228547f079f935dcf47bd42f4e70d7d2caf6411a4a1dce2b43079722bee7e3511bbe3b539de68bb2cbe1fc5b7b0e577872357bc768384dcd842494a39c2922693abd871a930eee22ef78e43d2a633b710c7ed29fda8e3181ae365912a47a5f0083605442d493bf3ed2289671429f9c00c3049436c8e60d58220d255ad7e4b3b05eea16d54aca57e97009bbdf14c04e81d37cbadc256605090c3ba5f71301c4e43865f3f9bcea6f3efd432216d7306b14f381ef594b6a727a578ae13e5471e49cd1010bf64c85e73ef134964639c0ccc9dc6535f600d165ef1f720fcbd276993ff062940da2b10e2d43f026a4e021da8a77114e351a3808effee38802981a95d3eb3f41b146f90d1caa5eb79376390c013f369b99636af1265b39c13c97280c00c254113a986f7d28d4a332075426e70f9a32bd5b7218d29b832519329333d4eeb4c6eed781b583448e33bc68cea3e204c941b48945df79a00246eb82c3d852edeabc50d61dbfe013045e13a5d15b8ada09154dd60093df0bd0d550c40fd5884c1e16ae9389e309a08d832109e25f65369a1ddd8366c05bc5ba54d54781f1ce2c8640557323bd06c47f46f20d23153e5a40b5917a5f0374c8f5bd05ed2de537d2652652da22ed2a449b4e8b4a46901b15cba71d753dfe8040ca1df21e3f9ec2e584539bd410799d3a17979e94fabde588edfbba4c65dc4d702d56090c6f3116356b6321d11b2eb694ed223a587f05f1cc551d0507b13e2c8c5105fb8ccc969787db5b638d7077dd533145ceae6cf5a7da4651a803ef73867828b9d0a642137e71307740cc932db6e638426973910d574bce6903878c5f58dbb0a3d7b3b57f15ac9d477d9408720f961deddc8c100fb4597f22a7bdf393b969a0ca0540526244a20eac3f2a6ceb896ae2cb10878b3a45a1ecd0a241eb82c29efba700db49728d5d65867f0defaf11bb441df21bad3616b398a08892600d5b7fd8ceaa1d951f9608b444142640d015345a3aba583b8c0dd64e598fd8074c04abc272d06bb24aae0d3675c74993d2f6917645a55aacbde0aa92b369d486002a9c94779797b122e310c9404206a3aa4bdcd07270857132bb1a049e1186452e983a09981c1451b6ff83cbcac6754abe995f343979a94423c20bc1e4027cfbc286f9b053d7a9c720e36c6e94fa9b5ec01464f7d2cf5b377b39353e96d6e055415de183f9fe7e17770cef191643bc792e32156fadaba5df56d258f67f87733c980f00b95eac026360f813de39670113ef18bb4a993f01ee4acc4b995e9eccd722e3c443b32e30eea9eb91bef75c21b54883c1a1670b94899cea5c2055cd8e16dd2c7e283b47e5e11894d08fe10d294102dd51f1df52a40c700d004136a8c0565686133759ca517aec9310560b5421409d16d9450604847645766abd301445549013d1854c2f960c96a0eb0cca647a680f9cd39771a01060373c80316a4a71ae6efe030ce6ef603f9dcae73c38b7dea07e15e609296bac9612c7b77035b1b8b4051c130788c958ace1f110fe413a413e6a1684d8776bbcb88143ab92e7c14c4a1ebccc4c5600c184cbc8e17128ac1ec7f607681aa636b61e9eddbe368c10628277cdf28a5ca259314c9fc4c391104b1080962d91e40e640dc3e0223581a69ca8af7cf1ffc09a993c5cdb49d274fcc2d1e7832fc63797af3d7c9cd34824d440b0e7d8749df87d50aca4c5ce3c94aab124f9a92535cecfe00377f4e251a97910f76b974405cc6d868f413ca5c89d8dc34a389b84e0657e279a7f2f5b8ca32ae8753aacb6cc755960b002ee4c2f5100f79a0277365d4b59eaf24f43212fa27fa5681cbb84b39254ddf656cadecd3b9a12bf129a8b542c7758e5dc6dd10911851b88c70e3855e9871199dd4b576b8dcb6542a202dc287cba86239c64ad35c460c08debf8c2ee3dcb8b1303797113556da0fb68b092ab99e44e1b2cf85505d0fb1cd9db8ebb914736d715d782e2613dd76d44ab86a00cbdb65a445f11af61cdfaa7c5dd2b30b3c31d45c965c23703de47a472ee357560a6d692e230576c22b6b0b9481a2a872264c7982a57245fb3f99ebb41f20f9a03e264c0c10a498ae7ade1f2460f7a8444d3b13123230af364b42423e86bbbd12223a60f03c94b1423527a1fa579a27443466f9b1843a0601fd9b3edc0774e61e82612a2ff174e8f907b53ed47fcd9fded84c493b7eee22ec32b7882c0b962fd7f30243951aa4c22123ce735f800028258c9aff470b6db6c96392a49e566f61ed0ca95d645f4c97b9d218e792fc7f1146715fc8478d108f860ae8d75e6348b30c393575fb3ede95629b920f209453e9db56af47201b2776ed94c8053c9cb2565ac279afb7f3bd86a340c9e43d5e960f69471d3c52bf8e37b399c764b03f693793629f8b0a1db80ac28c9a701c7f693cb6c6caad89bced2dbb5465b9ba3b72032bd1a766e99ec970cd9a1e894575885ea1168eca48cea1ace5a157b7222517206ff880c065bcb4a75ce6ee722b4407c1b1b591a8c14041c51052e8160b30f913ce9f0085089bfba0f01bc48ccb8cc875832046d69a17ae11eb805a456e068331b82915aac90f1c98708370620c36483f5fea18113637d31435bc8319d993cee09041a718bc4aebcf5ccf8af22952da2bf10971db511ab058ccaf960886b416d190018f1bcca07faf8ecba03d06332323583e9f0f1c366166e84b0ee180e08a0d66262629873b3eb012c2c6b0be80479b83199f7e8bafc3a08f1bcc48e9d8a041048662b08c8dd1f04a4658fec1fd11361170f9ca63af300d3b3d2334f041d5d0366fb0f133a44a65bbe75d698ad681573481d0410068016a00203692697c04008b00e69fc0a92c20c00601981419d5600f7070db7b22c5025a601ae81009c06d00845d6fb28b8f4090029e8300e67fc430193a802be9b4b3b23d3f1d60024201e614f0054e74bda8b62bd092145fe88004eaeb01c60907029b0d00a21780f0487031ce2e2504aec9b1d3b8e67dc09d032d23b6b550241887bb6dc05c010c925c11391e00847363b4b3b1006018808b065ad086663cd6068c21804170821a5809bf76b5055742dd168611a05d609d9c5a1da7c02c00de03a016c044922690ed11a0051d3939ac00688d015a3061f8fd5e00ed0dd002bae28024001d02706565240e9c6c050f4b01740110a500b500262055dc8d4500862e5f7af1f47e4946d4b37a44370f2c13625be56db85f886a085010381ea2e744840e728928970990e9b5bffb2301829010be40cf2463ecb0954bd90f03db90d69af3ff7377f26f17820929939386f361b10ba7a608ed807a76e67388da10908000b1af973f5b22883520de4aa8d91484d29b7e9ae1f53a0a9854581ab2a4f585942a6180c55c931270bae11ac0679c80b04091f990938084e66c170d5231f8412a02262b554e02b60343e107bb4917f08839d271776c22f705712976c8eff58a27171bdaf44670840a1da463eed673de191db5776d5061cdaaf193315e01b4429502d0153a7a28e837e9e201639516821aec30b8d2601309c147199779960019af66913a825e8253a04063cd2ef92e0f34b02c0655627443e527a59c418c9a681dfa9c4d7aa2ab60fc148374c5046fc4e44931e7e84e6e0853ff64407e7edc074f457e4c3504776282fd473fdc6e679a57ab53f054764c2216dfe3f9cc9409255ef2299b3737dc36ec39947e49ce8075744d0b5d14cd0cd6fca3e3cf92c4da00a6a254ff612d8f0908a3ce04d683627f751af37bd1cc930ecfaab2d7aa7b8e48de5f9fabb7ccd7d05b9fc35eccc0c34453b96c7b45332eebdfd4999d725f3b4ed47ede4ee969664dc553fda63b03de8e1e7b9230de6836634a903b5e12f80c6258ede98db4d790fceffa273cc6fd52c29bb00ce808140dce2aaaa618444222857332c625acabbb0d6cda1c2dde85392214aa8c0d29f9b7877cfc7273f394e1868051dca598a3a3bc089e3f317063f5b5c43f4cb264429450ea4e76e330b821666753a079296e907290b6f186c431114301f46a2cef1b3eb0f975a505752a579b5b8e6b7c15545183e2be3c84a2e79e3995f7f04066795ee3d34da1bbe1c0cd9cf22d2c792c4bb740e75d06e3c454656cf36f8d150e3138045fb50acce2b02f4e889539068aba398c00b34890ad4f2044352fc11205e453731e198df9c114077378725b4e67bf1d2ab8aead0c4ec4e2e105ce39937cca4a2c7b4fc9ab3f20d2aae16b33263a3a5b51bc81e03e380e2807cd43de3aded0585d40e610f2658f1bc7250c72f1d400d8f7871c420daf66e2e07fd0415464499335cbec27ec0e7bc78c1facfb8b05627409a5552f81001fee642598fdd0edd501d6394c1c954eb15c5800d4dc4ea44f891aceaca1c8e13f05e588ae8bc53f36398e79d50c6334d2fa5460450f394c42489d4be2ee3f0ce8066ce69eabee84a365ce302dc9c136c2ef0ec451a2bb1baf7c4dc8ea5ee865243b5639de62dc40a91df684dc4b7e5231b00b1dca81dbf4c81d2751d7ebfee5be42eba38c11f8a621e9048167b261fb3d0a942d4ec973191b93eaa392bbc83e1554071e85fc0ce2421840026151832e885f0d7bd2c6dd1aee42ba54492ce6693f8b8548c9a91c9b448970c34b9681f0150f0937bbd77a279a17c2d0a7c3d2b61919001d00debbb0ae934e7405c953cb310bf1714135537f8d01f90ed5f362f32a87c66a615684062ca9e3c5adc9e631da4b098a28463293f5e26323edd6dd93c9f9be48eae36937ff606457fa538088d85e0afe0bed40bf5a65826b047c350e91b80d61d07e801017e421e198568d9abe6a0c0278ccb8312e35723f019f38a36dc6e8b360b677bd9d75e3b15a93cf8db26d062e9eb76c9704451f467c47626f6ec9e647b87991cce3c43e9c98b56d06e79c5bc8f6b065e3335b28323b44f43d01b9d54c207715f30a5f461a37238f80d7c5a12e2f46cc3ae3f9976e353e6fe32721e98aad571646d70f0b9eb75766f3c50a7f465178cba7559bdbc165c6be41d199aea7631207a753c87cd4088e1f5c0456ac2d09e6031020b3ae7a81bcd7084d0410785c80119ce1e496bcf15c798cf50473554b0a8d095b635fbeb58776bb39a27988c6ede5c314fcde1d81e523e32239c7df6cfb6ff141f909dd618581bd6879ad1449cc0cc8fe2463162f627dde107c0162b0e7badafa37365979b2b78d69210a1cb730ebde9bfe04de2a5881572e1d2e281ceddb22a7d22debf84016625054121cb2e0c285a946c5ac6e68d3291f9b2c47cd1da2efc948f0390fef0593dfa4dd60a3321b8834a0d2c44a23650f4f872757c779647dc453df99ad4df447f34d6edec7ad938047aaabb06b7f9f3a76208c196f3320167252040e2343b152425dd08616b2015d2da140d305e423e38105133c1224c0bc9cdf49317158d745330c16122293082fb9e56a764c5d3310dc83fb5e3937c5f224653bb8ae40a2c7e622c71ce78314292a7fb6416684dc225a3bdb431e5eb576a9668594ed52b1fad2f84fcf15511729d6563132211745aeb0c883d05ab95d34887fe8daaa15d5e61bfa107cfeb3ddab84ab6d24c4d300531ec9efb65af476b79834aa17084a3b90b19aaf225d903d93d356543c4542a4b47f605c37cb9ac130995550a0cfaf4ec68df8f73b15e3aa52fd7c0d4dbb4d2aee42d69d737e352615318f001b86c1acc01325c14420cf1b42aab000f0b080a5f0ae1a6e2b1800ec12b49c3cf31106c75327023229edd71214622a18b8b3b97a7c7b48ca5b6b74d235f037806526f84d6bbf2b9c9ac7db088f4dff478e8a3df727bc8ff5c5cfd324d47eba6e860ac0b79b549071a847dcf6feae7b04f0105fbd1b11114b846feb809ded9261acec9364b688df4e2d4f8ff508189fd498fddb557450e922a02ebda8805504a1b048d4ec01b3d0a87e9ac0179bebfef9adbe5de6cef3a0477e5988c4a30642650748d1ad69c5f133b249b7080945dfabe819f18e25f9211910309f4784077b6e86fac2111718b45ffb3b68c090cfefde4ae8eb31fbb99a0b31734188b85800587f5934f63e970a47e8d16c06fd333321a92309a80824da2d8ba35364e23f01c1d06865e6af4fffd534d485801dbf4b12577a4abeca449b12130a5faae5231a83192bb85db5350eab26197b8613bad2acccffe8347a771038e33fb0b2e8ea525a476addbdec3700fd4025d8e40c2d439be4ab987c89c47b5e630e39386e97e3c3ccb9a409f6bdca0a01b1734ff51cc6bd45359aae1e58e870079e8aa9113d5d495f3cb712c77cf8ba842ad4b7c39e2baac30e4dec6eab4af5bd38be937851a45fd84bceeab00aab05a00d21e18fceb5c27a542b80bd941399e2701ba86158d9dab1e200a09fca0030a8b4f9ec746f1eb1dccdb295c9c06d70759a99e5b647686982bc52429912833bec275ae950f6c0255fe3af15b4d4796c6fac59112e4d9b53362945e617f28a11664601160fe51ccac22f8f5e97cee4c43951c6b596d4a0837a5d02157d67a152c41078025f58d6069ae7cea58088cc204fdc6b65a8371f6fc028dd9edac7a9cc2b90999cce0a247c94be999c5619685869470629932c9bbb5a2ab388b44cd9503cf1922ff002274fb1c7dacb5d2f7649877dc15273f35c2bf1ac71beb3e8333077165d9259b0eca2e12339247042fe7a1f82557d1c5f0b34dfd04bbff8fc9a6013f3075bb9796fb7c0a0014c01438933d422ea1a521729cf3c6a3e2f805a395e4a1180c481bf19aa22af0088d74a1012323bd6767d65bea07325e252064bb805b95c94aa4f832784b9ced3ac65c45b9705b3c2d925c74186c1f5f115dfc4a3126e7bae8dc3dc4dda167e51b490dc8aea69859228ac1bd90d60e2596e461fe24b7c8bd3c85becb6f6db1ba41de89e047bacfee7d5c5ac1d45c5c138664a7f4fbb0cc28ed5903a044f32003f48b4ca29eb287db35feaa4302d7a5bcbed056981b6a0571235911753cae040a4852add8a54178a98730f17d035d2743f735da3b042ed2ad005a443479d342cfa1ceffffa24b10a9b3cca80dd3e09d520ed015f066e7c5df8906a68f76e7f3ab174189f2d689bca1fb1c9f66b3299f55977ab0960e2605cafdbb33da146216c82c5684bcbf148ee12f9b4207cb1fb33bd31f0e22ee74983553b59a2a2b2524300fe2575a0dd09d18ad100394ef6d940ca47a2e5d459f1cefe237ec095c2ed033ad77148269fe7082490b686ebeb56e01bd4e9b2b7d87fa8d6d1b5fbd6053673905b07c7586659af7c98fe0dbf609931100cf209c6222c5136d4275db1c4d873d2d6e4920a38b693db23324cc42b7006eea62b96135fc4a08af501ec223dfe694e10c56e02f05bac9fee3118aeb8bfe99f8e8fe33a8d54fd8dd86dd11cb442c44e5f5e1641c13d7cbeaf4990d07c2987db265f58df38c7a42ac7efbd5ccefb950e8a77088ce13fe98423171ad89449f9a94479b9ff7f82ea9dfb56368927404e5b46867a47ce7cc4aa76f03b9f22b1a7894901085e5a0d3bd36db806aee41f4083407e9babba785ae34daf13c028e46ba121e4857197d01a0f14f7b741f229fa6f18591de6c06f8fc63ad2f20e60a3b8e03dae25ead2025ce03daebcac1bb2cb02a2194ce44c2745693cdb89f020a60ff15ad5be3903abaca4be08e2a787d9cfa1a7b54449094062a0018e05267172b63aa8a3e51c84d6c2571308674760b10b2b3151296d97b91b8c5813187c51dd146bf7606238f5081be6b5c99bab85d271096d8646995a00521a181e40df97e98f09010ef3f4088c1c50ea8bb7001a93e796172c8f4dde5d9ebcbca2bc7bf506e6b9e585cb639677972727af30ef5edeb07a1750026632cabccf94975996792773589c0eefdd1aae65e5f23b0f72500a7bc5f033d5ba81ebdb2593ce4e643daa2d3104921064209c40201e92d18c3388d2376df841c98d57af172a17c64b220010ad2c6a1be579315372b535b9d255be4356ddd728a64ea50c16e6b4608fac17134f0c1c2aed00b9215484afbb8c67faaaff1d5cd65adf0db1e4b3a4e0c98b073076e474eb030f1284bc23f327df913da692dcfbdb3fadc676d18b4dc9bc893107f045875bc1130b388a38d2e20a82dac2c4315bd3d326e09fd15e63e2fe237b86d46a3f2cb301983818327febf0adf19a4ef7ba6ebfd19d1be1e0e848565c523bf71ef8f57d3064638967277ef3286470670f4e73fe11a6c8d5581f4fab048c756bc4d18763fbc8d08068420c03310cdd0ca5a64a46b63034b04222eff31c5a4383a72a9a2f35b852d729cffcc82ba5173b4475f0833e186d7cd9c00f27d71304d0665edcb4a892b6813cadd8b2213d5af878addf733b35674fc7bb18b24b7c34746842f33a69032c63f9ec9cda876aa7cd4670e7cf5b1c2e49e993b6f9b21e6b2a2c161ceceda2043a079edb1ea3dc778aa3043e56a46c6fabe58c30c7db1634270727667e9c6ae53b5671e69386c2de59ecb2d5d0fe0cf6b243b786b0658fc3302f69c8e6f4e245698e6c81fc661292a05cb944890f4da2396c4090b91d382fde4229dbb0e141cc97d7414f2a7aab08ba7e754399020fc22c2468a44b749e123bd74cae68e1c59b3dc3d761a196e54abfb7a9e8cfb6c4dec42691cecc75e91c8b83e3793a6d02e40595b49029592308812a1c00d0786e134fdcbb0252634d01f09781a3d5719e45c9bb8dd12c339f83d41e50a6a01c96a0e7291cb5f34723255c5b98088c9eeef8c0f8098b803632c10039c802f048c2e4c33bca46ae120d986f3c6d2c8382bad9b5f84cd52d1f46a2c5e5e90b75f4b027d7b82eebf77a6bd0e1e0dd6879caa6475094cd53095f233238a080d94ed97caeb1770cd4c700a5ace27c13634b3e86ad9e50a3b9d1a5810021622e44726ab15b578b61eb7da43fc7de23b870051a15c2f445ea034656c0c58fae0745f549fca786f27d06390244da7676e66c246623b15eda6ff487ebf6a1a5bc3aadb359a920615de9cf8a0e2a611f302d932fdca80b5297d048f0b911e4e0fe576b798800296dd7fa49f3cb1dd0e6cea12f9489028326f130781bd296d1e862c7e580656d75071621a3f2b347796b547320543dd13aa1569745cf0c8245a80c204c51c7923b83954dcdd7689a392136a39e0502d917f62b7078cc08c7ab2f346e69130724e14cbe4ae2581c07a7642a47792fc8b156aa02461329a8d88794a2dd87f795ffce3640bafe3eac186d80c4117780b869ad5ce080fae8541739c649911214cb03f2f2b01fc38adad316da05d892ca72604e150d9a6fc58a5b96600ecc610505f194cc790c96e830a9a2b5fd4848be4e2b384c19f74d99f24a0624d20c3379a68e4b8682f318ede3f885ed6a0051a344c70e58563ea789f4faafc0f4181e1701ba12a4a64e9df1e9c8a4c780ed5a6601c32200cf02bbead455b064407e7f16dc88f7d9b78c65c0aad2b6ea032b4efd7068389c00032034685e3e26b630e4163be3c1b897251bcaba9dfada82bfb5dd778524617374182a06d5356198042bb9593b957ccc5a17ea9373af378f6d66b06f6f7fb015269f04296618d83158788f59673de0133c574488685e6cc282e74cf92f2744ff1b402d4f4581f60c1b60b61d3c61062e3756fc8340e864c739e60ca998576209d5308e7efb63077580df46814c377ba5c15d56855eb66176e70ea1fbdba1e810a29977405eef6657c108ce0a27588782612ee1ff604c0bd7ee9820e9c91ade07f50aba145e82c8a268c974b8a64bcae3e7681980200344042effeea62b908197dea244b2fcdf02dcfb0fc16defa7bdc31ec1f5a367514d688e6e58f88cd614aa76899e9a5ae4ce1e4dc32504a807baca33b345e75fba356dba7857693baa93e6d369a13b18d13d0b18676e86482e1c311b7c2b94ee46c75a9a885bc529e5ffdb0f3ef0f705a60ae8c66ba6bbef205da40cc59e1d41140ce6700c76a6423e48a57129d4bba1b874a0c2239c8d14c0a6c09686ce818d06afafcd251f68d125f2df1c87a533ca53f3f5c0d541203f8ea6fcf348aa8119540bd20d1751edf1df0ce67528ee6b599337d28eff1e1f6031852b9d911b901d73a2b59adab8d1c826d039b3f2b1a7a5c5d48c0579b144a2e57c558309a0d25a55cce096bd6f377656a514e8c5c2b0793224e91b3180bbe26893f5b0d6f182810711b2da65501bd29c7cba3c8d2fcd3da1f6927fc031e9992c408cc9e0978f0c4bee966c240185c00a454c43bac74279ed4825b6dd09f96c66670e1dd94a67e6f076e334daaa76f3ff8c4fae9b46198ba4c459294fb63eaa356e36faf144057685bc905ee7798f812a6fdf479d02792e3d1258fcda807290caa38929a74688934a1d2c0684c5037145d8abdb9772736140d9f102fcb62fe1e4f3ac185914ff794337cc417abdd967f2447d133b6d7c96852f531f67bbec58c339148a65e456f0d3b7d7d9cd6ed8398a0a00c541b5290aa4e3ef023099a24311071c890a275144d75db3b34d31517d5ae05ff876ef58ae3c8bea6aa7976336464a952b40109af891348bafdf167b049d49c4741954595b5f9c711ab4e46ff0b45e7235bb80b7649462c2995966ea72b725a385ace1cf287277ec104cc389c92d15a40dfa5ca99fc3a7346bd0145355f7add45ceb710c614f1b861c57728aaed8525a20a73b8d6a46b42328bde34a5cf7161dc4602b69ec5d92f9e172e691bf4c46641a72e9d147e4b97431cd456ea80f38f53e7f9ca612c299a4635f0f6290d8b99745aaad3507789686d72585d6a8377231862334d3eedaf73bd52d46a4afd7cd5c6d3ea0f651ea35fa0cf83cf89d14c30ea4fb2a2af28709b73f8add163745bcb369fd00ad074d0dfb93aa2b5de6d31c6137a0a59123166864acb5e3986fb31f1846cbeed556a081efbcf8f8d38d1a44c0e525c8cc9b1fc3b450dbcb0eed8ce53f89be1643d6e05726e6db01ac6179fd6c43a56b7191804705ca52b822f873cbe386c5aae3b60a26da6da196a60f590ea1302e56186c4dcd2651881d0401528a2c8507b41828070b8e1164947093abab807ae7e97bc8c03a0aa584863b32694761dc0d9a4c402a30997f270b666ee80c94b40da6431f552b81f1c10006d9ee1d5be7dac983660a4a6457af1e0af158a81685a4ea3c07ba8310b5ad014d00f4908a7a98461d2502f07bf4fc8f7d220ba6f31b9a48b27f1d321912050a7dd5eae51e1b7a10cba9482df759f2ec4385694608e92e773ba07221115cac03e2996dc5dcb62f6196baf9c2bbc19392ce0bafa2ea7bfee70b8ec26296b5c8ea01ac3bac87e3840a1ca154ff6dd9884870dc0100a85215d6d4829340522fe1136ebe98d000f1a5fd3fa0d887fed0043ff7a365e4e0ec2f1a006c6f3e1806f9deb89835e9f28bbda958964ef2f193962a16d5d940ea92fe2b9a054c64eae9f6bf5c661e27318bbdb5045122c45d5cc510c500c9b893101289c9b5114d92651eca4e19c32a10e907512b50156d42b68f9fc0fdc95503c59df0780f3080acd931088e56e9b95f3f73815d440b2c1441b8b71e8e4babeb4e20cd72a3c5fda7a02bf8d2e9ab9d00b4242b115c92a752649513fb82fc3d2c803ddff3152d0f0addeb0580539a92d4e22276b0d43475f63ac472e50cf5fc9d3c23574cb916ca9dd36b3816b3833137d8016abe1bb08661786d38c655969a2ce5426044dead04d4ce6b85010d8ef08517499db718edb7ce91ba30faf0f2f621a0c5adf6bf6d19f77870947e02fdcd3adddd7588b1bff5c08e4b1280ad5d4efeaf0199e42fe6cc3034d8d25b50209ef45109e15dab3d4d46aa4a12b5f8e6ba0dcf3b502de73f33e3d3c86c6f407f2e803d0628fef394c5a79621f8f76e8de35e048028eebe7b083e160b1ccd6e73dd55d905037aa967d5685ce1958db178025845125d79d2f45d0f008e702cf9807289c191bdb6715d3e8e36804d62afa48db301e4a5027ea204c20b3960eea4900300c3300cc3300cc3300cc330bb138808941251da69cbb352ea0cb3ff7f39001491b22222c949a78d4fa78d4f67263e9d997ae101d70bb50b540bbb76a5862e5984740fab82ba9986e6e37ce13235e242a3a1ffeeb4d2947c36c54d409fa1c917fe62926ba9728f199a241eefa7a75439de7ce16594a15d4dd51cdab2a6c77e802643d7b3e1247b3b2c7cf60b30c8d0caa2c7a0775af4cc5d92a0c5d0bb4b9caf9819864e663c5e7a6e4f664130f49ee5152bb78510365fe8ff93e765965ee8bc3d8cce3e292a067417baea94d9fca58398adc385365b476698182a2ff75be835789290e3cd16fe51b4d07fd4e928fbc7e543390b6de5048f3af8147a3cc642a3d391254bafca1e2357e8c356f659c8f1978b678536451d8f332b4fe7eeaad0b547cb2994c4a8d05b6cddad1c8798fa9f4213737b4cc922d252e84c2b63737c8fa0c1f7425550c6176584d1c76c1e1d056d28683f41db09da4dd06682f612b495a09d046d24681f41db08da45d02682f610b485a01d046d2068ff40db07da3dd0e681f60eb475a09d036d1c68df40db06da35d0a681f60cb465a01d036d182816af502c5ca158b4425180052bfa8fd1d27321c777543b461924c06215fd454aaed4b1fb1df45ee886092230020c4021b05045bba1b5647318bc7b542fb40670012d360660670224fb0416a9d019a810038b532816a6502c4aa15890429f80c5289cf89073e6b631801245cdf80216a1482060018aab2eb0f8c479000b4ff411f92af33fc365988004659860020fc0a213cd44c6d6cae1ba7e30b1e04427f2126773101f4b5e36d1e558d3c7a73d28f10a0b4d346ded93e7f9cf446ffa2f99e46230d19807bead1d532ed174746cec207754d29196e8f279943775d29ceb9325605189564314ed8f98541084f10527000b4ab4ba973ba552a4103e08de046174d1450a7c04fc000b5ca56331893e4e87df1e7c24d15f897c67c6fc13e21a89464e7afc2b9390683259f488ddcfc93aba2e60f1083c3d2365b484799524123487598c374fb9d002168ee8c3bf4abee4a8ab6f4417624f6875f738520a237a8de13bb6f85b797c2ca2971c85fc105d7fb2a388b6b53bcc39c8ced83f119da8b9ac45e6f8b105117db8ec6e8f1353ca7a88c6c39cbffcdd3144d3f19b98e78568567fa7c7a3b52797107d071a938354b578d80fa2ed56f935cf95c717441ba2dc5c321f882e63c6d071783180e853e60f0f9a29572de60f9d65a9f4907311216cfcd058859863f86d9998983e34315bfef5160d1f5a4b21850c8993f972660f7d183fce81768728ab193db4f15af3e25fd2ca92c9436f1e4bf8f832828647c143a795e6d93966128d2977687384fe8f2e3b967bb143dfc17f2ed509993d973a34a255c94f7d37362c7468e2ae9a58468be1b1cfa1d7ab580fc47a938c2e87b6ade348e52d2205cde3d0b4cc761c0f391c5a89e8629ae34bf1a36f683fdd3fc41ca7b44b37f4b9e1e34f1231dd10b7a18fe36d1ecee7f8d0b0a1f9942d9a490e394ab8862ee4104cb3bf3c73b66a3812938c7b1eac6968bedbe3636334f4321de3ae6e8c2965cfd0bec5a09f2c7cf323d50cfdce76f8f0d0a1bca765e862f349749c38cd3819da0e3d9430a12f445fc7d06ce8fc211e490e37440c7d1c8f650acf5c18baec28c6c3ff4ca97209863e7cd4c9346cf9852e6696a40e5264d629bde0ee788762216517dacba251e6efef91830b6db7a64ca56d1d69670bedac448f25ac23cf6aa1cda1e3c0225a4e47260b4d8ee7c50c162cb49d793e9049c9155a378fa23c9c88159a1ccbe7dcef883948b00a4d478c9e1f8e4885a62584c8915994c7219c425b31c584f45890f3a5d0588af93fa70e5192128576c23f46d0984daf02853e935afe38f8af7ef813dacaecbe9e21f72dec845eb5e366fe28865dad096de870dd931813daccd7718fce4c49dd12f420b455f37328a18f536576528e247415e43fdb73fe421c09bd761c72f8916c47e8cb3afc7c7c9b4a6746e85fe743273f8ad07a0e34763ef09c7727425f1dfbdba2a7b7db1ac2a51f3f390e4d2134394959b0ee144ac6203439f0a49fa27bcf4b05842674901ff4e76e1ef7075d4e91e22d7bf0f618f9a00d952cefe566529da807adc74172a4973bce1ea73c682e4492ee38e64a12e60eda54edd061bd92eec6e8a00f3ff4bf728ea3ce9fe4a00df3b0e13a52434faa30c00207fdf95a108b1bf4137228ed000b1bf4f93c42f64c69011635e82b3cd8f1ebce39087eae000b1adc3933e6206f620ab09881f3a1a5390e13942e180b19f4b22157c794606d211a835ebcb37afc59cb1a60018336e7cf95731a13b2c55774def9a45373eae9ddc2408118ae6836dd242ab27f1bad2064fa0792c18ad63b42f6c77157cc29f2426b15fd6fcab4a7c7df8ebf14f4862abaa0bdd9f2a772fcdf918ae6376a9cd81d8e8ae64bdd67b4443cbc72e31407f78bd149fda2eeb4810d537411dba5623a3c8c8d5214b934a64c5aca7e83146d2a09ff5132e2666f14edb7e97e3c8b09c810c5a11e690945abaf9e2ac7c96df9bc774146176801156c80a24c50818d4f3426317718225bb673b4e189cec26fea2859ac94471b9da8c3888e3bfee33638d1aa87d972f286364010460540104605c8dc8b0df762c3bd303ec6171b9b68e65c67b543ede41b5a3c6c68a28d1759316697d86123137dcad12fe614899c2a471a3630d1248b79e37708bf631ebe44177290b25561c3126d2a9554a61f669ccb57a28f2152bcce943fc4a794682bb253f2771c92868d49347d9dd4f23a8e573667860d49f41f8739d2714891e8673e48c8c48f0a5a42a2cf52d758513ba7d8091a361ed1c771a01e6c59f42cab3aa2cfb264ba2d61239ad99db228cb5962b80c1b8c68c437e27a8c1d5fce2ca22f37eb38b55e868c0e29a2f590634ef8dcb17bdad948441fb59f751cd63d7724756003119d8975e4b2aa396374f1c40ed1bea78adf8d9862270d195fa40e360cd1ce25afd6bc51314e4072b0518826c6920bb764395e33c9f8c26cb04188a667afc1c620fa40b542b2e50b195f706e08a2d37ecf98b545420cce98414601e0061b8168644e4326496fe92da5b001882e4795a34cc7418e317fc0b0f187e3284274143c0cfba1fff2cfa972de0da5550406b0b1d1873e9377e4dcfed1c1253e3c63613c4a31f651d8d8431fa1cc22f23c4488d238b0a187be35458fe7cdc233e571d8c843173959ce7bd581872eeb48fecef5971876bb431f6bb6bc317eb543b32a5b2e5e5193ee8c898d3a34923f4f78cca8c694c3111b74684b82948454e4462cc100430c0a0c60830cdfc0416ccca11f4b1d884e47fde7a148860d39b471c38697f03025bff6b0118746c235fa4737934c297068264353e56e8ee4a2586ed87843ef512c0f35462f4f5a1e0c1388e1051926c0256cb8a1e9a9544d91ae0e1b6d68f62b5e4e1de51cc6c9916bd8604323e7b12385d48e9dc81936d6d0b776188f951c952594890d35342e21c60e27dd3b9d4f431b347ec6dc1972c48dd1d047fd71d13c7c5348ee0ccd69383fcde172e6206486a6c377e4165ede284393f37d35a5949b31a36c830ccdc797d4ede06d8ca19309298f7914e425fa5e68bd9f31b80c1390200c2e880336c4d066c9de9ce0df91d74281296c84a10f43d860316fffc6e4f1860d30b41e74fc96db63d7ed950d1b5f68a2e6f7aaa58e171a99fe54e99d25c548e942e39929e538f5cb85ce72e2cae7508247118571898d2de0d3d571a19348c70140061b5ae827532d8bc44a1e5b70230b6dd69c253aefafbb7c1b5868db5bb4ff2b49f8b8dcb842a39db36abde586159a0eafe392f5286e4e6ca30a8d685b0a1e32e707ef0615fa604d3707df39b3996f4ca1ed20f7a25548b9c3906c48a1091111f2e5284f4751dc8842f381e6206f0ec1cbe3bc0185c6e2bac418e7ea51e8369ed05cfe6e497e12a5fcb3e184664e25979ab6fa668f8d26b4dd3926712598c7ebc1847e4255febc5d2da1b3dc7fd51eb3708b12da8d9103f7603a4ec349683fb64ceaae4868bb530c5515e2c6609e239431232b777aec6d56000370d83042a31d65277a87949b2c45e8e32847e9c713a193941d73144f1b42b39e79c32b17429fe3d8e820f407daa706a14d8fbe397990044217e72fe3c48cfca0130feee18c5808a6f141df61f47ccb1cf6a06f0ff257ea8f07bd85e74c612ea587d8d84193e15274d04a6754fc38cc6de4a0d7f550a13dae9041f40d1cf4f2ff21df42cac60dfa6ad70cd736774fa110366cd086cf2edf221b2c8fa5064d07e223e6d55164c378850d1ab41ee60c1f2ca7520deb08024f886626a74e593e3439cd209a9f8fa1a3e74a109da4ea70443e4ba25781e837fbe4486240b472d1fd520e13151e7f68a364e64891b2511d7e68f3e5306a6c4e1ffab2d6e8fd973fd29e0f6ab84eac30993d741db59458b2dc92a3e8a1f99c3984ceee165acf433f12afc43fc74357319a84b21032ffdea1d7f35d71bf0cc92479a145021f030558002decf0a7086144f282c6b7072deaa04a46e4a9480f1de8d41cc4b8acc9c390cf812ca117e283858b1c8c987289ba71305cf3e7e7943c5f0b8742cebb1ba299e4f50d84855b0c96a51e7383632215b72bc7671b709fb0a1c857e6a2ad014db596a8153653433299429c69783ffea0634db2828586dc7552fac87568f50c6674c9142268863cbe62ca51195a94a1d81c9f67b6eec9c960871d7ac7f11b821663f03cea147f69218672abe68e343fe69f6811063dd6cc0819f12ab400c396a3915a564f225f38881ea847b91d3185165e28477437768e444e68d185cb622275f8e17c092db8a09a94856ce11c3d94999c2be6994e125a6881f61859c62a746016f61217f5d852dc082db050f0deaf18c4b305115a5cc1982c22351a841656484235a6d44d425e225c43bbf6c75a1681d0a20a5d0ed537240499efc950a12ff198c9251933eabc012da6d0468e244954caa3462f855ed4bce3092151b0da5d5258446487a499e76027babbab840a141acbd9d4b184888f931201191e017e42ff1e04f7de749dec7138a1dfd48a297fbf4de8247e3bccb3d482094d7cf01e9c996c77cc92e107022b042d96d04f44a890d2cb39318712faff8afeb82147f4f8c83041195e4612fae8384e22fb931d11720186a3e084712ae00024b4d15775a37f4e0fb4c343d0e2084d78cbd8b1223bd0781aa1c916d92dc63ca9a08cda8116456836e7cb79a3a5cc98418446ff33f57c1ce7feec41062d86d0a9f6bc6c588a8ee51042bff9dae25f122d82d085593e8ff9bf7ccdc90fb400425bbea3a2b1311868f1833ed888ed78ba73143fd3c2076d8c1f232e4abf3102139c318e1765b418177032deb40a8e731e306386163de83a9e690f3aa4ccd3e9620c4e3248a9e038a7f0400b1e74317cfc41b5524716f41db4911ba13bd0685963a7835e3f8cc7f143f2f0c972d0a5504962c829a84e0b0207230ba2050eba1c9db2e3c07431c8f053012d6ed054877420ee795367ca63fc30c4cee03f8a31c6185d06195f4060c68c32c8f8020c2d6ad0c7a9cc75354483b6f7a5030f966a31832676888a297f6402410b1934d51e3de5e41e133bc7075ac4a0d91cf762b01ce247086b0183cea35c31ca49d2b278456796357b94424c88fe7045e3bdeb9eb2b15624251fc9cbbac223e5598d56a6b3a2490fd23a948ea44116ab682c696c1dc91e7e3e4b16aa6854f3757aac7bac3bff171b3ac82215fe67e7c57c90052afa0f524549d9e152982010b23845a7b137e4f071a4085998a20f73b57b01734e505994a24b31d9c955cf82147dac6c112cbce6bc3082208c030618ee8521358a765a4384ad6065918528da6819e3e7d2903de4a5a80e9045283ab738fe9147969a73dfb53a458c31cab00067185f8031c619414a80035d6c16a0e8af6389973b66440c922c3ed1c58ec31cb917242b6a0ac8c2135d889de358df25bf8766169d68fc3dc5239ec50bfd8204dec529c3bb380970a08b195970a2cd8f77d5346369ca9a008c83d0c86213cd6ef438c4b7f8a852e9851608c400e3b2d044e791aac8ee0721e6202a06042090452608d51e2123e9f22d551edf96d949523ed30e08402006044820860466cc00811860dc186590200b4cf4ba71937e283dcb41040990c5259ad6b1e496272e464af142eb28638c129041bc28c3478023285f808112e0401706c8c212639c32c830c1185d7421802c2ad1c6ecf3207794e8e2f3587453a96c4da219f13c97949f0c1d49b4297e8e0e35ad23f44874f261b00e793ab8ce42a24921c6c47eec11fdfa460db95287238eabcccb50d2d1882669ec38984d32be3a235af148d1a9938be843644e3cbda388ae83dc6731663e115d8c68e6974924ff4744a79bfa39ce07c9f410bd5c7e950f4214918c217acbd2a1b8c40e2c530ad164092944b7bea54609d195c44ac9ed39deec0da28dbd493d837acab21941b496bb2445bcc8dc712510fdc4d329f32846f0d101d14ad6bd982fb387acf01f9aaf30c142594cd983fdd0c40f37da24db3e7461a62ba3aae54363c9f2afbf6884c7ea1e9a90c3585ceb540fed4e84e02a1a1d79360fad640ff3f1a8aabc8987662e7208d731c4c75cdea1cd1452e3a2e5ca41d20efd4f9f69de0fab439339da726f071d5af19461524ece733973e827d552336b08227139f423e13834fbf1c857cee0d0eef5c7afc6ff67c81b7ab1ecb194b1b059a11bba1cc487afc44dfe13b6a10d935839760e1b9acff31ca29507d13f6be8446545e387d5d04fcc11392db588721aceaf4e296644d0d0b7799877f8c917ef0c7dcc3da61e83e62854678666adb379c66a65e834b6598c114286fe3d5b7210f38f879d8da16fcdd671a46f96e8c5d075055dc91f5361206a86e78e3160e833e44e53cba925972ff479de839cbf63fad3f2429b430fd22cc53a5b47179af6ca593cb34ae51c2e743147364c27e9a083b7d0640bae5bd1d4422f39d210f1255968de32cfc5d6200b2c3441734678b01e3e3657e882c42011e79ba442acd0465ab2d01da44f8ead175a650e092c3063c60db2a84213e6fae2314c947e850a4d5cc4eb28a93205067001080c000c1fc118624880026564318526e51cea29cc7518f948a197949009ab1a33ee47a1f999f4f289cc6715287441dc2466d5cd13ba9842d6095d8abbe961d0b1d46c6942337111aaef1fa75e0b131a0deb28e4b778098da77acef31f7f0a314ae82df7724f4d421fbc65f114292573b948e853dcda72fc087d301fe683185523b4ab9573243959843e34cdf1a97a566b8710a1cb51cbd2517363cee0101a8bb5907b4914426f1ea40e7d32333f82d06528914915734068abca2307a9723f683ef4ad18963e16397cd0e6789523ec7becdff7a00d9f8ed192a578d074acef29e1eea0cff88c4fbe7d66125a1d346dae3a5539ccc2c822074d8af3ce33abf4c8c14133b9d7fa913ae2ed0dfae431a416978e99efb0412ba631b6a3f02956fc6bd07cec39768c070ddaef9061cb2f3e832e44881c2f83c7ead465d0761c98b556c8316826ac058f96439e89d92c60d08ca5ae5c9af38a3e788f1fe669879faaae68772a4e0e93d44b246c459ff3643b684d7db3a2e9ddc81142e458451ff9c146b467fc2c1e55b495afb43cc24f4513437fcafc91ea8e0315ad8768f747ba39459f7c7673d04d3145ef1dc98338192f4513728c994be33b6ccfa468a662cac88c3b8abed473d8281dc50f1ea2e8cf355392e079729b1a8a36e67f9c3151c2f70b8a36739092e01a3bf6f844e79a2bbd34c97590f24427bb1151fbddc39fae134d8a14bf39289389184e742e972e255171724eba892e7b4e8dd28146139d4579cd269a9a59c5ce442721cc3fc27260a251918e83f4b29cfbff25daf0fd71e49a3477d6b7445f31ffc30f292fe4c857a2718fb3ca871743897eced73c28adf4d0d949f4417a641e9a5d2eb22989267a904d327eb8b61f89be323f6e8f3106893ece96d97114e61ec7d406f1403fa2ebe0513e8dec396c4ddb119da6e4cbe2714c21bfd2882e076de9d4bb1a51103423faeec84d9153e94afe5844f31a3e8893afa3883edc5f13d1464bf9348ec6fcc51f11fdb4c51cea21e4cccb215ad5205163653f79a518a2ed950e336f6abc58964274b12e3973c79e105de7114bd69a152c5506d19f967c302d2136538c20faf84b2d457b64a9631e8836b76ab9071603a20d793bab439217e9ec1f9afc4e1a311a24735b3fb4931d1b2eae82e5a0ed435fa1da6e3975b8e1a17ce873ce71f0132b8bb447f7d0584e3172e8937375563df49129669895c790ffcc43339e039d8cc871dc7ee2a1df24f2add3ff71167287463bc7e5be133bf4e7c1974a5cc910535c8736529ae70dfdb5b2081dfae8e1454b1e3ae5708373e8673b6b0ee35289c6510e7c2c16ffb3321787b62d55e538c64aecede0d085a87b91e330875ce61b9a0f4c3dec9c310f25e686be3df2555da3f524d6862e775cab47b779ac6143ab91ff5a2985df4dd61ada543a69e4d0e988a231cb1f63b5e643d169f08e714d2284147f5074b13c55c4289a33fe4f349d32c48ec7e2893e8e39987bec8c28c14ef431b63a4869860b4e34135f43ae23df44279e2ff4994eecbcb226ba1831e6c78fe33e0f93894e62deddf0788d2663a217c94162b997683efce72059e6f0bfb5447f9963e690d24a2f5989be3c3c2f6fd54a91524a9c235cd2ffad4ca2f7cc1eccc75512bd77788a493107216324ba30723197b18444e33eabee697944ef1e6f98605e61724a1cd1bbcc8aea488ba8461ad16fb67c15438611ad7c8c5ff1a23dfc45f4f103b5e823a322da3c1d4c8ca9e312d164a568e5b16988683da49ce2e7cbec26b143f4d7e5313ad6cc10bd47e465d8be9c27558568c2c79ee548c5657310a22bdd0e24fd22677a06d16abc8ee161760f4398b81044d37156fd37735cc22310bd8ce9479dc87d591d80e8fac552c5f4cf1f9ad0d1f26eaedc9bf1e387a633557f5364769ea70f6d4839921ca43cf6e83e1ffad5b10cfdd9e3c81d7b6872495fcaf1d143e725dded61c796439f8736858839c8990a21afc143dbf126cda3a7b943132e44e548430e56663b3431c741fe706ea94393538c56913bc7ab60a143ffe9518cb81dcfa15dd50926397e0ed921873e54066d11cf78b91387e6badbe24b98b6b0c0a18f9813da417d436b1173768aa3bb81102533760c1f6e439792d927847c990fc36c68fb336bf4c8c7392c770d4de5850ac1aa55432b9f3b52225906ed330d6dfcf839eb2741437f56392ea5e8b93a44ced06c4c96dde3383b08399aa17391f86172f0389a2f43d7dd6e1d7e4c227b214397277ff0a99214751e436f39f8581edbd7579e189a9d907711cf79bbb530f4df31c764ed12a53ac0d06977d4ac1cbc5c7ca10f3a0e959e1a7c6285b8f0429b3a7a9544d3f18f232ebad0f745c80ef2422e34a5297dbadfc37afc16dac99572f8778ec2b7e2420b4d0ccb323fee9172fee0220b9dc59c63c9593116da20d7b36715bbc212dc2422b6c4a48b55b96b79f8dd1459a1d3088b931d4ec7dda30acd6b7c0e7fe2a142db261973a6f8d296680a7da821a7641e75889e890b29b41d44c81c0716acfae5283431e7c07205d7183c8a5068f3c7ece9a0544206ff09ed7a08123adee9483c8a042e9cd0bacc54b77967fb894de872d64849b3a5eea05b03174c683f73868c768921f2161863022ee06209edec4888a9628e650771a184ae735bcc26abbc1e950d2e92d064a69e484745d0900be38b08cc9881062e90f07b869564efca36461924e0e2085c18a11377d3eb28fa2c66cc282e8a60443009125b56d32df898c926cba1e538174468527e881ce3e370318456d6fa4a3bf2c997a3846048b4c7b7ba77474811526668900dd3d8513008cd5896d198290c84254f8790422cfb8326c418a5d7c1c86492f8a039cf1851d9f093638f8b1ef463e65125794955708bc0050f9a78fa9df42f5b56292b0b5ceca0b510fd63032e74d06952f9ec9a23447f3f074986d81a27a3848362b632635e23a8acb7c418c5722e339fdc3f1737e82ac59d2fc9221b8378c240c104980b1bf45bda7a9583b8ec129713b8a841bfdee3711c9368840ef7820b1a7461279a570c7e6a96d345190fb89841a7313eaa14547c5b7a2e64d07958d1617967871d87b888417329535c4bd2d18517b88041e3611de3fccce38bf12bba50fdd0436732bbc9ae68c72d5386f8d48ab55c4244258247f83cbd1f937285ac683df677301d3b3de5dc8c19336690010207e3205f90c04dd08513b658451729ce9fc7b971f24b55b41324069db82a1e4a886d918ad637bb589689faae1ea86855323e0eeb2986278f53b41ec68e8ff90abd92638a26c412f96d8dce1df2a5e82a2c24a66c1e11534f8a3677c8fe0c9ef3e78a1945fb5229b24fd688a24f4d16225fa8f09933a1683b3f23cc5ac741e41450f41e247aec749c67ae7fa20df11292c3989e68226ae5b6076e1653ae139dc7241f8f858c137d9c14772eb2ade5a336d1fc07a3bf95d5b1624d74154372fce41e4c4712175b64a2f970619571c1e3a4cf5b60a2b594535293d05ea28bdc1e7ba85d96f1c508be804011b6b044931fc7af973acc1861b821c3aa025b54a277d71c558ea550a25d8b1ede33ab63f0a8056c31893effc6ea47c88f808c2f0e165b48a2cb943c94675ccdc145cd4941cf98b14524ba4826bd993437f59684852d20d1f44771f6b367b56e8e2fcae82d1e516564c99512633213a92e939365ab88394cd90f6ce1883696e7efe4479ba5ef8516292cb66844d7ff95fe51698e929e046cc1885e73e5609d5e79e3c759446bee1def9b47119d68862ad99ed9709e44f41a39c8f164b6e4bc31886822e26b8ece3944e7ff563142c50dd17cde10c345f74234111d84cc1b6ae15198107df410b16ecd6761f1201a5f8b20bd513d52cf0aa20dcf9123e71c88de8394b12c47471e4a40b4e153f01069f5c8b2fd431bc137a65645b585a41ffaefc8ca8b11d287d6a3071f9a6899a3f8e71ffc7eeca197b594838d7061e2e1167a38232c5a82cbac4584ec1ab352f37394f7bb451eba52935c71a73dccb9c143d71f9e4a2a7b873ef72b876e9e07ddd40e877df36024e46c8b3a3493f7fc37594607363e7eb79843a7dedd617cfd0e9dd52de440ac8e70e565b26532413cb4a065f94253e535b688439fe251a69d434747d11670685742ccf994ff0d6dec9d4e5e39e786c6a3858bd937d5852ddad074c624536b990f1eb9051bdacd3826bab93ff5838cb0c51aba548d50a92ffff9e78c600b35f4392ea6fc8da96d918646432fe696cc57d0a0a1edec61a54ee919dacb3a162a74984b4e33f4c15cf4d59094a1f5143d3d98c9d0c67ff195eed2b8dd18da12cfe8ed6187181a09df610ea984a131f349ef1cc6670e0443ef2aa9439969d209cf17baae0e9ea5d2f142d79271ca3ae8380e7e179a385a923de6423b2e7a955956762b5be8aca3f77fdeb4d0c5109e7b739985366f4cfdc974c4a4c4422391c9523fe4afd046ca731a916243eade0a8d07151d87aa7d15fae01f967d7e36f443852e6af40ccfbd9025660a5db6bacc6624ebd4a5d0c4fca15fcc1185e623f6e3e81ff8e40a05552c254fe872f690425be3f3049dd04e48c53f89f6e86113fa1caa634217436e768be17bbf324b68bec2c3aec7a184d6df75e3bca624a1f78ceb91249c24910b127a491e85d35096237496e6ab7f39844ead18a14d613263468addcc4a11bab4cc3166549c601d44e83c72d18991433e9787d0e4d1e411bf91e56421b421d1d783de8e2da94168a39f4c274dd7a44920b46e69d1f5ff4193b96246d6d7e82bfaa08f674d5ddfa273df83d6e3c30ba93992871d0ffa203ab28759f31db41956b93deed001d98347e6ab9d1c349121235b3538e8243d484f19bf4153b9355cfc7c7f8d6dd055de309d0bae31d51a349165e4429f3468fc93ea89ec6a5e67d085e7ffb8cce5838fc8a08f0e36c69847ff25e2181862f428f5b9050c3af9582be4149e4288bfa26bf9690bef9d63905dd16908562986755bb1ee25e9a05d2d2bdaed8eddda320459cf2aba9cd4c3582146e5aaa8a233ef0d1762aca96883ba48f2fc593a0c2a2a7aede061081f876ce1e929da0e3ecc7dbd4953b49393f1f2648b8fdb2c455ffd319676c790725092a28f190fe37488acba194593ca5a62a6228a3e304f5db1ccbbc33c145d4e7e1e7c9ca942b4a068cddfa307dd9692a39fe8a2a323c98957412de2893e4c12c233c7924e349ddb51251f9c771ce5478fef17249be84c53900f5dd1447f6126cc64ce44df1ec648f4ab9c4c31d1c797e3f15bf2124da58cde418e11398c58a22b8b29eae7f78f8855a2cdd4965fcc23c9c194e83cc55bc7f6a958164ec2cce894fade91c41da5b3753a26126d0a6b5176344874de2ee2e24164dee8239af81e269739e7284b4758512ab9ff7cd788e6326818d17ef2689f0c5ff1f24574b13c96b5bc39165545f459c7c7b4744b447f19bf22f64888685db7e7ba43c8ec9c1da28fc3c91d628a9bf93c0cd19c84503e63b911390ad1476221459cd0a85d9cb04dd40c09d4d044bb121fd4a233fce45623134dcc5491c1428889fe62e64dc22b87fc9d4b505111d63d24d2e53492789ca7af9a9a2b4bb496752b475ccce341a322ad44b39d247e0e3b23460c5551a28dd39f4366d49844f31e1629f2516388312fb45270bc18a38624da701e85ff7924a767196474c13522d1a78e544127119c4382ab306a40a22f150dda5a9e23da015c400b3f1538e60b302c3063c6fb19c38b1a8f68e473cab58e880423f862c60c31be9831230c31c8084117c403351cd14ccced8fc9fd734c914634391583fff6c5b3ec1e324e6b30a26b8f42920afb9695c75c44ef92f139be188386f55e689522721177ed88ee08a6153b07965fad2562944186094ca2a04622fa58637f8e8ea310c6224434932d4bf3c76124c0812e3a50e310fde720227d3da61c3ef203350cd1679887612768f430627c6156a31035a38b1a84283288ce427514fb22c1a22441b4212edde3df51cd4c0944dfb2b9b22da91e203ad9cf1cab8669f587262a84d8044e1813f0431fc6ec71181de7d63ef4c944f2f54721e5fc9e5386392448c109030335f8d06b85a62496e13d5c650f5de7e461476d215cd4d043172722776e88a229df3cf439b1ca83abb8f8a8bd400d3cf49ae3368f5a35e5e36bdca1af0cf97d3a9e7668f3a655b67c130c375f8ce10da851872e848ab2da15ae4187a6e273a4882ec95f2c736852aa30e91e1916f372e8f2bc8558fe6b7c1cc7a19d8bb7b48810aaaf630c31bab8e2426b8cb312a801874e3497a708dada1bfaf1ca1bb365e8863e3d4ad69be12ae88f5f1c647cb16de843d5e9fcfdea38581c12a8e00227a8c186b6d5dfb727768c71ae54b02a18a30c32be00c11963b1a8b1862e728cdc815bfa78ca7b0d3574113acc62c307a7a1394bc991db927277fb020d7d1ceb257dc9e9ce397f71863664cf8ed62329f53a33b46b123ce7585a3ee71cb30c7d8e7c18faea29c4ebc8d04cfec8857ea6f4d70b4550630c7dd47164de117693ae19821a62e8e727cf4352f2107d30c410a310306a84a149091f997e1a9bf3370118670c12e8d6004393323df2735170c2c87a408d2f743929f84ac830f1438f17653805d08b329c04a882320c6b7821e9f8d4e8f430bd28c32930638617653809ac46179a92eeb0fc389ea9dce142d37158de32294948c71c831a5b683d6ed54b79f92f1d5f95811a5a204785747a8749ec0e1d3b88bdfb9d118c2146162318438c43c728830435b2d0cfc9acb85b120f9d030b9de59cd692345f08e9d5b842fbe167cc4791eda08615dad02107ab942c556822277ad095e32ed3920ff2955353682fe530c6ea9895821d25662e2b12663f78183db6f0fed588423fe7796e394228f4df7ffa71e0639d73fc099d58d27cfdf93aa14939ec5e74ca3f51bc1a4de8e7a427abafc845e960427b1d37d7e3093d95923596d059ec652bad2c73b9d750427be63e394a981ecba91a4968a2e61c7f90e3188db94442eba1c7b52d68dccc498d23b4a512c334e7e04f623542932de4c0377a90e203ad4611fac0cce320870813d7825da84184a6b53f0e1e650d9183b2c610da301eae64ea901a42e0cb4b364d3626e462d4a4ad7724be5e23087dacbe21a2e7a15103087d4758a69c72c4dc8bd4f841177be5a76a1e749c1417d4f0416f31e7f0711c873ad12b1aa8d18326524a29fb8a575427f8e279d0b59888598839f40b911d3479193d8e3b879831fea8801a3ae8acb5babca3779cb7fe88c01c2f4c1da0460efa97ce103a87189329eec20a013570d0c5987bdba7e3f042ebc518411727f8e235896100498d1bf49e33e4e88670123d27b6c58c196470a0860d5897c932cdacb67c2d6ed651f270dc628c8302312050a3064f5eb42aabd04a0d1a7469d5fbdaf1bee50e6bcca07dcb59ae12353564d067c6a6103289bc6e480d6ac4a0f5958af929c67828af9231860936c83865a8e00141a80183fe554cfd7472102e04f9159869e49462ae1474572021598ac9b424b398f378637fb8fae1d26945cdb00fd06005e617e3356ff6e862154df010931b2e55342d9d931fe4f1ca3e53d17a386b49b2ffa86867b5e28e75d0ca9a9ea20d1db327da79fafa32451fa5b89cca41a4aa2096a28d91eeacf33f0d52f41ef5f587f230ee5f6414edce699c102cacb542a2e873a4e38e7a726028fa30a49c7312cd609283a20dd61ac2c7fa31c7fe137d309b67f27253537e3dd165f99c28c13c59a0d1897e623ca71034ed82137d98a398a2c904ed1c4e3671989f7eb91a249a20a453acace32542965cd1f17bd2426fcae1c633d1e6f8653be69166cc5081930013ad46650fd233e6f5642ed1c5f550b3bf45cf0e9a25fa0dd1bb9a2d6235b7342ad1efc967cb7192b52dbe30d0a04413f9b543aa87b7dc6904480c3426d17998e3419eff3424d14694c76747ba2922a511095b4248e99911d11919e1fcaf54727621d164979cfb51d64b924fe31148c311cde97e141eaf97bb4e341ad1c7f987acec940623faf7bc39548b571d4cc80b2dd23416d15fdc19d5f79d046474f1619cbd2d6828a29ff0881e62be89e8f26e45680ef3a494e28868a2a4d0ea703356b0ce00b2a8c0000ed18a6699a4e13d06cbe186e8d5d5df633d4e44d86814a20f7bd64388463e54f0ce6a10c746ac96f530590db30a8f3e9f7353105dab455089cb1e926e8168336e795b860b99e9bc8006205a4fd93d74d4f148a56e0334fed05c4aedbdb8d471c6a04006fc709ce30939a6e6c873822fca300ee8432f9e5f5d3774f8d087b5aacab1bc44f5e0c3f6d0a6b02c9e83d0d1431f66ff353c59fc60df3cb4279692d139c5cf2978b023424a6db1d2ac70edb2a811aae330436ff40e7d75ec1dbb849a7b920634ecd076c8d376491119abb716d0a843fbc1e9e479ac1e5a6cca021a7468b6e378bc7942630ebdec57a5ae86201e87d390435339b74e87e415621987befd224c0e2347030ecde8cc871c8efe78ec69bca1ebcfeb38639a9ebd83861b7aff9c13abf420c5cccaf82205dd86debca31ccb8f65bea794061bfac941c4f030923f25b9862ee79f3889b21e58af862672acdebc93a7a19dca3ea142a40e3ccf6820c442cce2552ba52245348751a3433fcc9fa18f4f63e67ca41ffe3ad20c4d5a79676e4497790f2fb454e0609c2708a051862e75bea499c3fd9d49bd503e2718c3041b840134c8d0cc4731a7526bc8ebe163e8d5a4474c3f500c8d793cdd153b6278ca85a19f958ca81e8480a14b219faf855416ca6234bed0b55694cc1a294b8aaf1a8186171aab94ff41a33bb38721814617b610c272b8d0a6981ca7ce9763e728660b4aa5b49696ba8be7d496e85042c866a98523648f1fa4948359e8e3883fe529b246961c0bedec5e0ed9b7fa3ce8aea069d04d71d541acd087be9377c2a7860aa92ab41dad8314298f87217b2af419f2e57b5290f880c6143ae9ca294fcb850fd52c1a5220bc749046147a55f954c13333776cd18042ef139729abe70b136b25c0812e4a40e309cde84f188f7288d93fae40c3094d88978c31b62be374b20a349ad078d81caa4a2b6088210605864083094de9f768b05066c1b41933c848028d25b4bbad1fc45eff281da884e3534ea4324224729849a3e473fb49e8bb227c7aee0e21a10bf359653acc8fbedb113a9f95ffb3d41aa18f994943a308fdcf44f74df2d7595f22b43e7eb953e9440af9131a43e86310f176b11ca42184d63b3ecdb09b6373402308bdf8678a399d41559260d0004219e54247d5ae9b0e68fca08fa37b7b902da3684a9e40c3078dc4ed30787c12df3212e0401763d0e8415b39de439c077371f1328e0596060ffa31d11c8ebbb883e63d65fc7520131a3a68639ea89f43a3b9a5470efa9839211f390e3293904ddad224c485c5a9ae786051835845e3068d8e88648787d0b041737e151f3f7f6c1768d4a0cf2db9d271c4e2a9478306fd6ed23897b3874d39a331837ec6a247d8d8ce3c7d18dec509c304639040047e4880c6050d192c1f59450f271a1a313847e6e16701346080879db35264c82b1afd0fbce2e58aed7e990017aee8237fdef2ce5ffff1080317ad68a72f75c8d639aabac0052bda1c4faa77f0e72a72e9904b17d772d592aa88adde41b7aae8a3f2f8e7c3f1308e5952d1947b76d49927756872810adea4ba5266a2c746d66c8f7390a1e2074143f414edc59dff08ebf8ddf31be0c2145df418eb96a38e530d29459363f88b152e9262b7886032d96522d77f23ea6ae5b3f8289a8f538a9fca038cb9a834ee6422a3e15030168705e360140347b707e31308002844240b4502815018869228fc140003642c1c2e383014201c181416188b04c240100c06040301e1200c068442817040182c8dc3b41e0d78bd0b74d210351b537ed4ef738f22d158fe569b435324415db28bca1caf088f9b9e24c61accc9474d01047755d27ff9fecc3daa277354eb7d174e7f6078319f6ceffeb4da352abf7c0abb3104701b7414f3dd049f55230c55c28a22f445bb7f4689ca9cf65adc0f96399a72920f5d42f754044f5f2c3e0590ab9baa5d166e9469d335049a08e35ddb5f042b88660efe72aadb87907e72958749a5f42f22be4b019135f7894b9dba40c0c00134650488a2858d13a04527b3925caac3e3877d0a3c3e85c61c8fecbdce8fd605fae56a70247242e6c441503a98a33e295d45afc6cc0b918c06a633980ee00d7c9f6ad1af100f82d47687d83b5407e3daa6b6ad85c321a7de10e0487aa9b2acca73092f2765b7ba4d13c40d3e36b874dd07a1c771e3c0a4c880734c06bcebce4d8f2a6358fe0537d57c1b0bca051b68a1a10d467f1684e7524e169fbd8210cd81ca5e83049dc41b5b5214dd2dfef16b223a8fade5c54ccafc48847526a7886fafac7f08ad9cbf4f0c4794e934bda01dbe39abe8a455fee381993be0b62cc0900b02758e7e75bc25e56609d45d848e4a24f963b814d96a93d5ff4ad1eec24d455a5f160a71922b5a4017210e809868c4da3473d780f37ebc847cb569fa659ce862bd88df41f29f8acced19c5607ed08cc5a7da259b36176a24afcf8461221c906d25bf62a7f7cc38476b56456db2009aafc5c353a17fbf7119aab3aae73ffd6cec4c7790e1da154aa840dc42bdfaad4224253ac422fb6b0adeae11403bea7cb69905444ce5f6865902f8f4d17d689d5e6d425417bc8f065109d933791b2db186fcc435cd452898abd1cfab06fc5b952e7377b735da569750787c20a06a956563c0f8d9be36ab97841866f278011cdb18b440f280f0e4a7352b32a369e5949d468676e1874a41362d6329f2417c21278b7de68231ebd93606b3decbd1f1f415ae48bd6e67dd177f6b4aaef37d4d111d44bac9bff8a07ace510d82401c218951e5db7de5d58316202809a3bb594ddd9d9081b79ec6848b7638cdf3a96e2989e39d58eb997129eebbd3f4956a90e099504f1ebc8208c7ea2c1139ec5a6fa90490e6d995686b60f25f7b4d1c3d4ae3f9a3998dd98ec36187eb7dd91ed3560039f91241e5aa7f4bba784cda6971a608c54cb79e92c560fde10b1621aac423057c38d49b5557da235e4569d3a88c56802012b2ed923295f800dc9692f114f6ca68aba51316a4fb022283fe3ef3ff628bdc7db9b45754039c971728dedc7c912a2fe9846f61a030e7b157f08884f53fbc2614695006d69295d58732d6e184cb76588016eb5f6320b32645356419a1052730395db6481f5a9f33456a6104ffaf029821bf0ae61591dea04d161d1b46c3f33424816e5de12a0cc8bd498bc84c835b749f1dabe2626007e6285825c3130c9a4a53176fba6691cd95b5d56c9262e7c162af37b40304c00106a0710617f25db78c2ba080d8ca1d23dd7ac1aecf735e76e6b925b7c806f9be8b5aa5d94871331964741c82d730f750722a9a29b264b4d9fa8ff1945aa9874087d6086ae5d7127a8b59824be5a771c5255fb4840d4bafa0883bd854f58f2b1dfc9ee282aab8a0328b1852e5a72027a1231df1b5f84c6bffa2867497cced4fd14967a68da3075bc792acd624a1e2912a5c1bedbd3e1971c37adac889737c4183f9854d09b9c6a2c93ef9dfa7c3428953a25c4e96b35dc1c1ec7f750bd5db36d66dc259e4093848dc6a864fb6d58df6edcc19ff6374981a8b0fbe924fcea1483c9049c335045522c4d8930727a7fae95eae0e09e5057ef99f3614949ac28d1ec8250178f8adcaf38990439c7d95456b70bc44dde93817fc37081c851a5029140daa0929f208b489e944d72d806c3ec09df8b43a7ec5f49a4ce6cc86f746ab8c017fe6d750a59702a0cfda04275b8d98a18ae56c27ed7bcdbd8604d966775e048fae4c95b27c4be12a7cb79292f6549c1bda79c699e97a5eca33848b3fe74d5072c2d20fe0c4418b8fde536d39ba528fec4ac48c6cba61c9c9d2d11e47147ac6b16f968b8f7233033d5ee535dbac927a71fbf13619a7e61f8d3d59e703699e3568e64f67696cd2da06392e7539cb439b0e672bf4ce9c0f85e5de6fb091abe36cd33cf2e6c201d8ba39ac34c3cb618e4abc56b9d76200f67f2c8fa39c3133a77d47e5e8d0e60f0949f68b54aab5dbb52a909c0658001e69275bdbd2a95bcb689d3e639bc0320c9d41cc855d45f8014fd28e64a7a4c2190ef928be7ccceb3344a090fbc30039fc648078d9a582385c9aa21d3be03ecf7fc70530215c7c91b615e0bc384a1486ecf51c136debfd61679a2142e77bc21ec8bac5279a9de178812532bff8ee0118a530a853f907a64ac383e4b822926c982505a6559a31fb4364e8d501b5c713b9a4879b455677231018a4217475f15934f251555298badf3814d6e6e1866f72abadc50db23c717497193a31c80102bd3be4195433557eaf476a87f12ab4daba30411940da53bc1833f53d5f43bcdd77dd0bbef57d4fafdb72d63d65120c2c0fcb1b2cafde8318b0d7171584cb96c9bd5547cac87f705c47c8c672b03cf03a47c9a524b5325c192074a49c99f9fe8746812d6e87452e55faec08213693326edfd70673d55659d2257c1cde397ec49847dde1c74825020054008fdd535cc679fc64cd08b86c868d71320356d09d01bf5a671bd589334782671f2701f7b46c7418a714e5ebe7981d508fb66c1d49c7fa6f6a374a9c1b6854111bffc64b5177357a6eb6d5aa1794c5534345d8fd99eb9124cf362db1cc48ebd86647933289f31cd57f3e26437d32e0dfb3704940a21bd1bd5d181d44fbb676a10281983c2fd345fcd36ad56066152992c42d084fca752927d7f0888f140535382b161d0e1702ed6337457d6c9057611ca022e9a112edfdddee9c48a897739f1bc83af19007a69104595cbb9e1950f6bc5cc31cc057e23ae6b0753d5ef6ec19f3d581bc3c412e68289e338c3b28c88ec65a1eeae85655517dcb5239b2a29d44c4a3add644cac87626e9ad46270f6191bccf48549108b70aa62b92644854a52cc1e707660ecffb1eb635dbe46a9d20d9538257b7a7d38719dbfef551fb70769b1a97fd094d3bccc7a54f051ae0d9ad1853a0f42f68544a66a8219f3bc6343ba42784013da430776bda2b151c697fcd13536350226d874aaff1889e813a973604f455ea890fc3c12abfcda72812d582e3255f27f8d8a3cbd1f1d358c3703bf1921cb21eb5254a19f2f683dbdce0d7a789e163513d94fce3c7fea3588f1bdde306a3dd94c6fd6208766fcc64e44aa21da9d06f4327d8c0bd14191484357a8b46476a2ef8364f0ceb650afd48239f86f2b1f3a5878452ae0446023c117a57c1393828ce39c103ff008b74b34791bf557662d4d5a22947897ce7a0521e354c3479c805ae334b006ee49e75995f70a10812c0048e71c02c3498575948bec41be5a01deeaa7865a749f141151bdde24b63c56b83e5650eacf8124059e99c6b3707e74401c1e425bf02330070bf19b10b6b25079cebd1a640ff0b705b84a154f23e2c5344672136e856e9a13cd6025f21691bd9e679baa987d0db1836f3ac32b3c72347d73b70830c1d598f8f283b0cf38b78ccb62b539d06b1332b7919eaff07b1b38fe682c6a8e7dfad4c270c298443eddf1f3ba1ff8c7c904f5355b24452c186523dd2e6fa88cb522842a12da56eecc459a9a88a4cd959eb75b7ca729c0c59afe0957e41b1a18aaea9d1a401b1bfc4c05e4b03a109c0db2a65369cec2d66e6b47a99f6e615b38065171e8308f13b1c626f130c8254b4d233b167cf94af23fe169c718c4bc8cadd7691af2fca4367d93330b40021a7bd63a4aed16d4da8c0dd55ab9d6ca7f07a11e433245544e649e9c6c81bebe6c6e92537bc206b1e62538dfab68d217224e95fda90f48fcd663d54b2e43bb72d97566f0f13a666d4ccb094ec586cc616cd62bb5680e857accdb425ce46c0a5c0efdc583698be7227e6de8cd3b643b70396e867a1437775eba0c93e23388873b8a6632bf0eefb6fabcd8d34c241d92c75c49921237ed3d7b206085383584182296695d7aa9023480c74160a92114cb5200734b1024ee56f51023358ec806d33be203fe666f6cb36318d00e5050377471dc432bbe1f6215d93878425ad522b6e58a5560846bf33603abf227378cbaa4454826811f3ff2cb823e5dcf5c1d6b82fe2f29643f6b6e929aaf2a92371b92958e999956b0bbb4a9aa7a1d2f2948d2b52f17f4bbfa598bc0489900fdd81ec25412ef6eedf6f9d6d49ebd614c8140375bc770e8161b31cc1ae0cb19421a1f4f6956bd9b66af2ecd322e64cdbd44e9beab804b772e6941232db695b5bd28e48350a327cc02293c412716189a6a103f20787197d17fad4e6e7764711db16de544e71324f92fc2b9971f6e044f3e9ee8259c8e09b3143c723b8ce06e753af8b18473ad65bf02d263564e1be4ce81293027b8456e7990dc75de2ac279250504facd3b63823850462f0609e0dd164cc098ed36fc8b5892dc61160051acb98fde56440303d9036f28fde99f37757286672cf0a32e6b62867178ce2fbde8f3ed1ad57c6eda0d35746a39d2aed6476ecd8912775ee92331636ec2eb93166c32c4c57819cce35cc041d36f3f094682641d9054063b1e3d50cd52092d74a8bc95bdf91453aa54cdccff625281e15e8624edc8bcdf46f6ca4b38ff90876f46d137b09f5c9431fee71c28eaf595adcfca7e3847cb077f7a89cf7a37d28095a11f6b03d105756b7d26c54ae6ffa7b8175405893b4b4da60cb5c3349fcd58d9e8ac8984cd33ddbc488976d232da6b8ee443758e0118a4f6dffa7af9465e42a3aa15f14b35b5d23534e7986fb6073e16fa693661d696cfaafc2281b833e3e5c929cd95c7e22a66b173e10fdd045494f1a3a92dd2ca29f601c8a1f53dbd1bc86d058c17d35d23a24615612128f137ff7572cd2b33c87bc244034264036372ce419f3f50588a363fcc104ab353be2676cb7604e6cb2f93018490b9e1309a1ce0b408aa46ad48b0abe5f68b5cc8d8c66e738d4ae684dabcc5fec4d76a3c2c9cfda840c060b7b1134ef3d13ed78781fad634a627777c9084c5f49422d40a79321a178f6607b21700bcd560ab654ab30d3029f8dd349b2913cb3c6df5801d14faf32e09238a3dc1ded03ef8d2e7fc5212fd1e7f4119d996f9b7ce64d14464275a46ea36ba8dfd89efa54c33c67fa335ed2928aba007e28c223f8ccdfa003c22e963b64838ac894388c3fb04aa000d17d1f4214c7c7605ec72f7323e5e676343d673d6077a7d2556e9e1047e670b4111ab27e30e6cd6b5f593dc1d50b205ef5d8eb515264166cc41b778cf07efda114fc0ecf61e26a40a981a906f9b37510c75803f109f0245ca9a68a1e0768770e2e7bdb9506b6ecad958db5e6d4cea5e2f58dc05cd352b0652beb48f9b9edcc97634d2aa7bdde6cb94971c7769b5224351760734fdb72c3d61562774a5891815f00d5e129d7844b2fca9a0633e476f670a4ecc728344e26500359f07fead39ece8b41d9c15f58e2c101baf8fa21ae5c253dcd98e885b194243a79b33d7f108024aadec27f8c49fa379de36b05186b81fbb929f7c1b86cf4a918e276cf352b443dfde664e891a27eff4a687087fcea3b23654dda029991dc2650f860e02cc0561118b08faebdd24d5755ce96edc3ed98645eb7d9a07ebcef683c022287ed94aa97f2b19624119cbf3d0dea52d1392c193a80f350eeda8cb3a8e52c2f3b0ae22f0a2733f3f586877e0787b6a292363704726886cc8609b4cc7e02bf73c32eeb56debf1552579d75f8392f45159b67d39e9083b11d98ae31574a91b5c5a086e6b154d1e1fba479550609a8a91ec0a89966527baecb406d9a2de6a9c2ee90a769834c58c424a9db7eef88584376f97cbc490d77b27b9166df0d410ac43b3d7cca304ac3a443b915ca2b474833254304cb5a4564f5d50742b23063eace4463bb3acc16b8cda01122dfaf36e20a64bef2b9a6f7e2e17bee945e361a80d440d7399d769c0bac231c6086760e5ce66bbf7602cc74b237fe4eab12d642084f179302708fa9b20a0a8345c1f7795cbb5e3a7d638c7e1aa4aa03064665e32bddaaca5684065692be6c379f3392836c4ae63dca74cbe38f39e7230ce9b2ab3b31e5017a0cfe9be5045ed16d9ac9225e23b5fadb01ec5260783444c2722e0b253a845e61b26fe2390cad437a381cf4452c9844e2af0eadd7312b1ee6cde1db0d8249a727d53a7dd4831833145672d9a998a1eaf3093252d1f2b8bc28fd27a15cd8ab167a30b81b869e9c266846bfa04136d72fcb03d8e93004092fef78223d088777684d5816b7f4649fac8813728340fcf8e009c65182905cdbd28de4551dae7d1ab403d82cfb21596cf18b467ff7f428f43e24bfc3e4ff0da15b1c923923e3b947d86c35f0a2e75f80d0b4d59466bd3bbb0e69cbf11cf0c7468bb26b092a068cef99378a9b62542b8ba9dca24c2416822a2d86ff3f8203055b64c6dd24ced5cc515c7e4c73e8b0da26176ef1bdf0cd2529d5b15fa012869fa5d39338ad3988a33005f8382e1e990e06d9007993f8f45174a60535311f195704060b5d934e4157734bac7c858d575625f1bb2619449dacd095961e035c141cb28fbd26391ba5bfe2728c41ff07768023160cf5306164aed18a6a10b293783ed31772177935e1e03e8597ab219feb0a5d59838f255cda5acfa538015ada9d4cad23d059504297c0ebf3695c87b4620e4318b486cf50094524dd23e24422e1f0bf2b7f10d62163b78d69d978ce35e5ad022c71a57d03746e3f20ab8257ee1348b4087b7c93e347361030f967f8fd51a6974c34624a470037e2c8be8ea5625b122354856e507cff009d304bffa55282cc1cc6e74a8bacf27bc52a50843a0f74263fbe9976a3cac068a68a4b5bbdabf3cc7ef84e677e4bf7ef616ccd3e21b48987c90a853cc5e0b1d34a6f9221c602dd7ded3d99956a4a3395fe0b1dbfc86395a6a9d5767200a9545bf1b35b8bb2d94136e7db4c6912e04bd9d4d81b4148a03dcc4de20b5594845b25e0cbb4c4d4db6728c2911b2ef94c729f87c0833a5cb8e482048a78243955cdd1cd466ef077925288c5783c00a800331338c3498176f5e5ab93062174b7ac5bbb4054eaa934d9152b734158395a260514caf8860c29ea75eef9487fb00b724e0e6387b9b370e710591a854eb25b2bf1bd726b545260c253416365ce2e58a8ea7032ed1113adfd88d2f9dda8a71a2d091a2a4bc11d65ca748ec4119ca59e38ddda1524488a43db78d64efa718b16132fc2da28d3da7ffd62566ef2b4f0b92cde304c2e40fd01671c3c497f2eeb04ce3ab0558da3686728131c9a0499994023376414635d53a014a7798bc6b5434c523d269929f6c08dd80c1de115d57242429945cfb7689c8b7a70167e0c454c11c368c6dc2dc0663ee4349d13052f30454ca0350a9d19951a93163665a1ee242283872cd119d5fccdc5a0259db16fd598534138185c9f821c83855c07485d7ab33a9cae10abc2f0c5ecf3c46f6f90ee2149f4c8a16a0b60e6e336354b3f54ae6dea1e8d33078b0f9a543ae4426e06c465ab828dc620ef590a604e32b5deb39cafa5cc7dd9754bd6292597a455fbc0bc3e02af487cb0e984012c2b58e0a07e348858006c039080a9f5fee35ad3d4ecae8da7ad96deef58356f49605d0aab7bc3be318851990d03c7595f9b3d1370fedd47e80580be449175c47e8989eeb75c39fccdb159245dd25425737d54653421e16891900ad7a773214f8bd21a031155457667a9dc9de421f397b7cf2f072143fd20c9a2bc8ef3bb449011b088d868d826475a96581539f624d2ce8bb351050cce6452695f3abb225428cff6905bc2856ebe288ba93b86c6c5bdafd016765b6566172345f0ce9647beb7eb864b80179594e8e2dd7598b34af6897e79c09b57ab6915cb15b3535339ba708142d28d43e1ab48086974c297f30a9577f5f4231b0435d80b186301fe1bb7de382cfcc89f1e990e40f15bb27ed9d38964120584a15115b621dfcb66bae261af5efdc6db091865f8064affe5360b2011cb74bbbfbcf82bf135f930464dfcf3fa323840c768c31719617cd7c42b43dfa19032acba251871c402a6078dacb5267316b9005238f7bf6f731834ea731e3be98d6f8cf178345df2f9f0b436f4c9a27d5df001f251abfbd881d059cf9f1a10bc87de8c3cb800467581fa551912c57642c3ca093cbdc8c77958260d62d18d8868a1b4c24eb5cdb31abacae295e1ab1f6dc84965e0118e7bfbd10a1fed1b9bbe53fd5e1998bb4644b93258e1b5ad8291be1959cbad804ad555a7683fac475fefae9fd497e8157a049d7c3aefcad09928921aa21541544c4a3c6a31a6b0da4b3d754fdbb6fea9c7a42bbe32f4922cffa0d413adfb86f66dcd6fdded9581c271c8c4c665fdd7d7138a27d5db59cda933d1f1a615a54d98ba115649552b842d8d3919564fad9eef8587a4f78ab7aa6b28c3ea460a410bea193fa5f96554b14d075665cc6615fb69a539ef01c2cfbdda66eaddf4c475de3a4e55062e959ad2a93286e1a00bb8fe9581770cb15d696ef3e3c7c1d0e4dbea3c36e251b62e486683ca62129e4baad5176b5e8776b85d3e1aa63417d978493b4c5716e36b01941c4d5d7928c15e3743207475d5156a18d659ab8ba5207d00c27168ecd65b241d4fa69435457bd8f4660048d33e97b6a17fc7560e672489f778939ab4b161a58ecb83118354f6674874979b7961889ebe414cd3c8d4f332f16dfa69f694079863aba7963902017708c3405cd6e0f96d3d2586389d1ef0b00016b36cb5ccb59a3096a7bb03d04dcba2fbcbf707a6176ecdf4ef687a50deaacf64881ac51cf4c239b6d31cdb169983d7ae022bbf31ff570f939484cecc99dd7c1b99e1442d571b97476913c51d702c5a27760f890af3b2e32f417686fad72d53d761044a647451d1ab1f16ab305dd4d07175c2a121daa4c8a00954fc80a6108c3d0be39054074ac824abb36d007d916068961f34bd14884f93018a195626b8bd25cc42d442000e8c111b5a8e21a61f0660817a907d9ee6f361882c4c282104b3bcd565fcfb54ce4e28e05eea6a6205b09fe3c42b1f7a2b08ff0d307c78957991d3e4ebb59eaa102601b56613a25d82bfc1b5166bca2ae479aad30d4e7ba36414298d038ba4a9ba7725a3541faa65b0021cdc599769743ed6276d222169ff7bb36a8ae260c59b191474ab54a09bb97d52a600e6bd334b6cfcbd191de7e836ababcdb0b93044026c46b429d286696933eeef895a1bb319c5a6e836eadab86a239d8d1d3636b3d1d94659b6999b4786750261d3a4cd7c3697d8ec869b6926049472646da47d7317ce6d363bb8d912cedc763356a36875ca72232de2ccc09cbb23f9401e89a08910a60d0d6e175a84e0a4ea710ed0b9d1d2095e8103b6bcd044cc62d15e883b28a2ad1b567a69abda372e9ebacd89fc43c783ecb6d8305332b8c900ca99fd7b15ee648b58a023bbff1d7a8be6ccfa07336d57a97d5a8d484b204645ee9e90bfd8210de14b7028680330ab1058b886c59e5ed37a0f205ae94c3037e61184df3ad38aad6cd51a7eef86cd9de0ba4e4d5dc70a244d2ca1c1d7d837e4505904f2037e0a8c32e0a8fbc8db9bc01fbfc284670f66f56f56f833d76727b63fcda3ef9dfb3dfaf2bd091f6da7b9fbd983ef9be66f7cccbdcf7e597026fc36ddf38f775fb63fcda3edfa3414d0574485e8b10ae57340b40fa1cbdc230d135871373603d6ef3d79e08cb7d144e56204ac0a562fb41a5dabf83ec6176f7cdb7e56db0b84224a90170275db7a1f4adf8f5cc52c76892ef222b586e2cc6b656f846d57c8ad903cce21ab2a0908e7dadf37e62deaca42925749e7a792fdf7a1cd3dd5c194599c919b39ef8ea8e3f94f6d236118bb711594ae132cd4305655218cfbc2028134127771ceb1690b7b971f82066371269e454643a3725fa4c5d4f5104541b6074ac7511c606c6c1a9f8c81edf212789865493bce959164a29cea9ce02eb1ff131230d11ed15e050d6c14edeb7f835eb6fefccec08676686be7b55f72ff3d001cf470548aadf1673e074622a7f3959fab0560552b26d71a75a81ab7fd4d5d1bc9d96b8e3145d0d2d028fd3518506df4c7da59f3a510718638c4a9ac08920d01ee59283a924244350b233834710c6c7348b0a27ee7d769d87cfb5a4ea2e160ec853905a107872a7d6ee8fc173f15a10dad96edc9fb74c426225f91fa5ea9c8d1c91b1c9a6dc21e331787b6da16f81047a5b3daa1a97e38382cbec5cc7276d6a3e9c14dceacc7a4f528b8dec31d0c97de63ba581969e2d33d218df41a79c17c95711991863447534ca8843254aac327cad89e351e4cd585dc0c8e5f812f7f57c203c2c9843381074dc7eacf8f7d130ea6be209e84b8c097bdeb150f1300cd9e06831312090a9eaf5e086f326fdbbc1997ce5e80220f8cf7defbed11f6eebc2f9e1b2f3d8fa837d51bb3ef3327999a70e6033d7409f4fd191a5a8072ff0e3e24a727f4f63e67561002b787ae40751e01df44c3bde144042ed43ac8d0e981ddf719beb089d0edf57833d09cd3fe940d6380388cb11d1e7a70abe9fef0103bc08ee1ecfc1658a5f984d9c3b6df080895b213dd0be47b2ebc3d3c379c1aee11ce1e7041ee0d8bc25d509def00e03ce225e9700151741c5812261c70817f52f9d0f3f05cef3171ecd20a866d40487d13188de9eacc423910e76f37e08156debd235e2537ee728da39eec8c3f38a460133f7457ad98424b8c38e461c9b5500306f414a5e5468215cf5a2fcc572a462eea569ece3fc0208d2466c674c0bdb866f64ef54dcbf23bb8ee1275709c703605e0a22ffedfb31825cc7ec6cd518621aa0c2636cb0ea3322f03c03f55a895b05c709399ec8b35b19853eadb284db57aa0b8cc1063a803830d0aac13808577cae5002506c205d7083121d342826645a91dd2d54e6048fc7d912c497ea042592fb7e41ed3f04114a3b3308bcfb5d0de7ded44ac786fd885581a0eb1c9589b5038105ccecbd9f31b187333487e2d8341905fc1ff1e8b2ce5332d796a22b4528a001c9e33c43640004cdee1032837be475508592520b190de6b46c53e13029924488285cc1a745bc80c836310f2ed802592792117c540b1ae3608719816999d59ae0c55ea13fc6e0515c3a47d4c245fbab76499e366ef181c31e8ea58a899d19f6ed346770013c97484ffb4cbf0069b613bf1f9078af7078b63bbe9d747c6167dfc7c7b6ba8b9eba3c80887673e1e7c5236ea3e61944d2a5e5b2d6989cdd810ac074387b0a7e91984effd6c9564ba791256ff01c5a8ec9ee75dc55a97c9c3b9191af36ce73c66039c11726c789a78defda2ad8ed75f6b08f6b3b7de49cd7f2f7c823ce15027a34f721523c2b6806a1751bef48b96c0f3519a99c1dfdd262815055f261603915b2392769cc0195672f809a3d7269ab7ab7048011556aa6b2da5120725ac90f407ec89b716deeb8685dcadb4fb13bedbfad0a4036509bf42fbbe9a298fb5d0126aa15943d891450305b1b9dfcf8f6ccec1560c8cdf520a5227bf3bc0cc8dbb1207e851e32bbde46d0e7cf138524f589493229cb2a31e2969bb281d80f7b79e27585200f4de33ceeb43ba1a60a24d5974fa7d9df5186850d509364de24d3269b5910444a8d0c86f4b844cf9143c9c6bc228a3c62fd864cffcb145b23ae3d21d7a30fe83130021b7a0cf62010bc3f5558b0720847ef91158766dc329da63a882c5e4767249cc4735b452af44a6263a28f66fabc813e74709f0be1aeeb5ad04ecf329fa65ae2ba75b6c682483e390addb6040501ee8f6453d06c0e7651c11321ac89db8964b0783431deec718026f91994ff067c12a12a712893dc9e1182262a94d7ec461bf472cac1f4132ea31a5cce04afcb0e0e98228d49ba6dc50d17854f09376ca0d201397179874e4ac76ab8dc40bb6536cbac72f08fdcfe52d716215e84ba1fcdd646e9c24536d5930f37e366f23769f8109bfb141323269608bcc1ada038776fb57a2e7791d64903ddfbaf2f91044c2874dc8250575ebb969ad1d78a2c45b1925464fe8ab163f149acd98583d22c199210b9f57297d9bdcd084048e0695534b9277692d314dc23b1d14acac7c8e002a7d506c994bf04cfce23c4a47a2fdb58adf15c2b655ffbb1c2e29f9a0b607635082c5346b86335314440eca9e73bb88a64707836d045a97be7c2ea59d36b5e219a0eed9c3f828036d4fcf39685f1cc9a68aff5a11ef6517d19056b2d6f3e1f24af8f09e5080dc9994393824e87ec993d2a692330c342b4353ccd8358de05a8b592b8ff92bc5c294431fe5b08f8366601d40a6edb594124f58b8bf6ca8fd83afc84a3c4621c8e7aa620afde143ccfdb21a40d21d7a95495a544eafba27c88a2ebfa961d0dfc4d3027b01850083b83c5153dbe893a33ad1d41cc495e40c744d5b5279aa3e000c30cadce9ccae16ce7b5edcf49c411713cd86b99c225254f4c70ac66bc23b3e6f257a157d9ec21ac73ba4dccff63b2b43a4b98602f22183746651ba977115954d422b9ce6e6402b603f486b22f21cc84e71d6ffb58264f7f0e0d49c92e129b655313cb5ad20bcc9c6fd4c5f08b5b436205555ea2203d9edff42522f0efac8571215321527b1307ba0b4a01d963548040bae9a3ebc092d89b73cc08a0874b7baf5b4d4e654a3d8cba81839ecc1083038241f01796decac2412c570229d8f17b2c2b00d4a36f1000eb073e8d5c244cae1eb040bb061edd3990926d871a0711187589d29c51a8e157bb7ba51e9a9a0a959dd6bf25eac98834e2aaa7075bf72996815978f71a70d1eb7a5fbda9b06fd480980866946978c46fdadf33cf645b2f70cc8ee6313a6fb81c0e9799a9ee3792b4198718632fe0046726c7be89687affbc9b1eda59a5ebeee33c7969758ead98ee03e4a4d4ece75657e938ccd90fd8531d005a7cdebc67c720f2f396d5e57f3d17b7ac969f13a9aefdfd30b4e8bd7d17c7dcf5e72dabccee5d37b3dc839e01d97f43ff01d4e80378faa3daad7905d2cebd3d4238a1b7a3742d4cfd6152b5b3652ea0b5ef96c8d44faa87a8f5e5b8b6e1ba28e5e436f149531809c2e2367569e5f6aa74a46096377402d1fb00134b416705323d6f93454a11eda891c3faad0f53728a5d1eb394c09d16a1cbda89dee8d1ac65c1b9aad3ccf31626df442e7014c04ca98eb4f57aa30ae46287af4765170818d7e462fe6cf11687268f4f2232a9663af5715c2965befcbbfa71d692730289a7b87ca73a3b515514600e7ed62637315175f3c4014160f7364d49f81f76d8b250a7496d3527c945af3c7f42b03072dad8d6f1396acb8ff60da5224eae76c1947ced1a36478cc95bddb7fb0bcc7c1036432850bd8aa04bd8a6c53f134f499224025d4c732d10c0fa81302f49f025eb0c4f70b3970b0160a073ccff33ccff33ccff33ccff3bc0fbdb1fccd22d62cedbd48bb827e7b9807db467f999999999337ce05c9da40c95af4244772acce350c6a0b150cdd57caa979c5f5502534e6e9765f3482aceea39e7b3c961841d2df7cabebe50a5e2c82d8b1294aeb5bbd4fb318bc5004b1eb87dfe3a94b3e89321241defcfea164b6f1c1aa8708e2fb78fbf34bb8c74533787108c2a6ece31f7e6de69c694390fd3f8c9968f2452148962e5d7cd9eb7b7a268082178420e4670f6b2ed78b4110a6366732ce65ed8f7e21089265ca3016b2e28a596ed4702c4e0772e078bbb20e04395cd6b6dbe669198be90520c85f7ef2d1a3c7e0118e7cf107d27877ed77d009bf4ba61fc8fde9efe2a4886ba6601b5ef4819c52d8f4de715b0101ac105c8e1a33b2d081f5820fe4e197f8ef6c4a96079b177b20f565cd3de53af7fad103a13659128fe5e9aeda3c90b2ff73e6f17c361fe75fe081187c7896dbcf6394dd5edc81983d648e96c67b6107f284875952ff96f8cc0b5ed4815479d4b3119fc9d3ae17742055928d9b4a7a1a5b364e088e8d195b38162d81177320868cd3dcf374a003386cc8815896a242681eccfda0fe8015075ec4813cb8187c1c9ac5871f331d7020a5931fc694e9e8c364be811c4fcfd26492a93cb633f0c20dc4fb78e71d2c47391f6d2047ed5968aa6dd7bc94b1811fe69ca2ef176bc836eb26d336c3f2420de43ce831f7b8571d2e9305161018810274e870185554512fd240d0bdeff1020de4918f3f57fa0eeda134586720ab6f4626efd218b23303315b6f282d8fd9e2981b35666c95817c71e2326ce69fb88f0ca43c91bef41d4fe777a0860e9bc08b31106c73eee608b7d1d469311052dfa4871e378f56db301062e3db6b2a87b564d1d89aa103cfbc0003e9fe3b3c7cfc71fb7d686c7d81147dd97c50e1a256bcf002b12dacccb833b0ba401acf838a1b6592161d1a5b5c2059a6dc39e3e7d3b31a3976e016c803eb73dd3cf83cb830cab061a38604aaa8e2851602f0220bdc5797d8895dd765658d8e6d8a31f630477760f197801758205e4afd162d58e81588d3eae3a06ba93f554e8ec7b602c13bdd0f344663a57415489b27b6ae46a4b1c516784105521ebfcaedf9fea40fa5b15553209d8f2dc612adce7051871448e9fdc39cf2836aabfc468198c25d66374df31750206c6bfeb8cb72fd04f2e06437e64b591a6b305e3881d0c3c80bba737e6f311a5ba8dbe798744326105318fde4c334696cb1d58c2d708860c712f48186549d860e5602d1b3ad868f43e7035ecaf9401288e5e31e850e3eecc19a8604528b77fdc8824f638b8ac6be78710472ee185231bec56713d308e4610e2e8d2dfe1d5accd871a30884f26c39437e2f2fae1b4420ded647c59dba947b1a3376dca891238b2e3a6a608143206679fb686a663d9dc377e8d8bae28510c8e351567accdec31e58a62308a4eee10ff3d87766f27d1a5b3b70e0000271ccc7a3dfe09fb2477681173f2069e768f1ef17f798e203f2a0544ddb3d46b3e7ecd8e2dce008bce801717ad83db25befc80b1e1055c7b22dffc7af31dd411e3b56ce66aec00b1d94f2d352e0450e48b963144bed9a87df378dad1c7e6c9474c00b1c10427fbbf43bdba103078d193772e0a831230b1d2f6e40caa39b1f67eb6cbf98870d4839f6984ccfb5e6376b400cefa16f4c9a8cc5d80b1a10ae6ac63e5c9cff790881173320fcb87d30ffd2a3d8835ec8e0ba68933b4b8bf4f59431dea38f7ea32f6240f091c6bab0c091a3014e78010392fdc87ca015a51aff581068400370ecb801013ec57fc6c1a2c68e1b5ae408c28b1790452fe6f94d9ab33bc705d97d746dc5acaaba466c1eb7d799e5f66ef0d102e2c6be1f966a8c41ebf2820504efef2c9d6ece64aa172b205ae4fa65c4788e3ee8850a2813375b91682db1d3aa36f5cff6cfec6b2a0cd79c3964d8be860a42b5c6bc2cf34f51c9b76497986a6a0cfb298fe3e5d39c365390f3c0628890c94b6ab9280531de89a6bcf843062e48412c13118db9e5be51d92888da1f1aad800b51105c2f58694f950fa30a0529e74fe96555d9d3bc800b509052f9ccc9864ea93b85c616b316ece213840b971eae7b68e8e5e109426b4aeef13efec19b8f4e903acddef6e0c772177338617886d46969d96af6acc6b736418e2173d6e0e96357e04213843a8b1e79ccc448889920f47854638294ec2b66fa70f1f08197206edcd35c377d5576e1d4a18309e0c212c494a92af6766cc8a88a2a66f80c4e1d3a04d0002b2a411eaca59ffdcca10431761ea54b1fd749903d74897679dcca3d4c1244eb36fff5bbf0cb722430af6cd112c9c852ed109d6a4f3985cafe40827836de9f9ffe2f7c780d1c16502c5c3c82546a31a654d33cfacc43042e1c41caa3b8ad569a3d7b4553e0a211e4cd3862199f516902178c208baf6944e58ab1f2f8459062d7a2520eeda97f14459075da63cfeba5a4652782ce2599acc7631161cc080b9b7a181e82fc035db9176003178620a7f2ce9643962e0a414e5d4f79ecfd1282ecc31cbdb2c6c53bcb41907bf812d6e1ecdaf3b855a37fcec3e4c3391084decfeca69e0604318fa5329e87f80f042f9773af1ee40772ffb5470f838d03c7075cf48194827ad4885d3c0b177c200f35a7b2b2181e672c5b9c07545185d9e2d070b10762fc5ceae1a7b59a3fac079248a578553ebc8a2a4e0e73f240bef3d1f7069d9e8f79177820b47cb44fb6a98b3b902ff4a37df49843da8300177620cd655dfd8f2905cdde0e1c36645451850b5cd4819cb66134e4c696d88d0ec453cb18f629f479f0612ee6e006b909b7cd41c4800b396452f22632d2911da9d6d9d33b177120f765f5804353296a9be221e736ad1efb46b63c5c6f20f4b8c2cf6694f361c88ae0c20dc4cb1627ef25bba6a605828b36907c3cab610f5cb08174712a64f8564c39ff6b20be54daf794e3758aab06c2a7aa90d16f4d4d22a781946ab5715a616326b840034935f9aac6384d97f73310b5cf47e1b0611c878d1178163b823f87cd404e2d1f6a3c3a3f2d5306d247e91c3d484806f2c847fb921bc363208f72e7613ebf1e0fed478a81b0417f1c63a50a9d7b6c18c8b99af436fbd3f8c80703e93de55196a6b6d0ca17c869cc3f6c5f7fa063b9f002f35653b59da1229699faf72395f2e802492ba3cbfb3458ded02838b2202d70c105525696be30ff5d6c81e0799ca12edeaf2ddaab05626b1ec88d7b6d34709105820f2e7567fec83cea7f01e7e10ac8810b2c9022cd24338f7ce6a2efe20a84b38dfb61d3ef312e2b10ea3d561e8ff2783765ad0ac40f4df971550ab9f107150832f9694bf2534a3e0552d0cbd3d81c1d67ad14c8efa76939c618035c448158b95ed3741e050ae470df39f3603521b87802b922bd7c76ed2eddebc209a49b4d974eed7e828b26903c54ce39edd1376ab80d1823c8e1e6068e726444c10513c8b93a9b8fe2edd6f635821c8e458d4e828b2590dc639a6478cce33fd50d5c28819c1afa87b95575910442e56c793c0e1963e7e58104d249c5fbb0bd1f81b4af612ae6d11f46d98c40caf22c997197a2c44711c8b7fe791cd6651744206ba5d7e0e3417446bd0c8194dfc3f5b87c09811c73253fced4c6cac94510c8de593fae8d69e6ef5d0081e867b753e53d96d3dc0ff2aef0ba99adeaae10b56831f577d43e20591e3f1f498f56d2b32e7ad044779695a7d56689986d887d4ac61f74ca5df080ac41f62ef36d1e0fe7471659f89905c1c50e88b9f5fa43980fcbfd9d3182c78c11d8c8024f032e7440f2f4d13b73f8b20dfb18d06c756c3cb4c0611a6b022e72408c1e6f26ed1e6a8f3647632b0b2cca51a08a2ab2c0a258514515361c07e4c98c9e6feaceeb2b808b1b907de039c3e42635cc4d632b8b1a3976e8b0a13b6ed4a840076a286077dca8a145076a3cf6002e6c4098c8aaf6afeba01af7105cd480dc553ae631e6183d4a260d173420e65a4c7756da95a37ccc80947fb4f53fdaf758a979b89001597e247f96ed621103f2c8fb87f1935a01f4810b1810c75fdf629c8d298fe2f403172f20851ff576ff207501f947f95536e2b4afba16906a4dc3f64573c1027254db53938e1aaf7eac801c7ee5cbda7b537fb00b15102fff28984c6ca920a9ffb6bf8d2b0154904d7e3c216dfa831fa64e51cb6d684d596549c7766fd846f43005a1cac763e9cb152b76c44390402948793ff4094ba71b99d2d812018e2c24400aa2ee7be73cfcb5951e2b300a52d6eec62051a1b1b5c6a2208f7b5445154290402888b9fe545724ce41860a0173b6a8d100b64202a02058fee06ee3afe7a0df7d82f0d74983795ff8981a097882189235f97da9f3309b9d208fe3e54a15733a49b89c2025552fab2099e55291c02688921e62aa4566a253aa93802688a6b147ea5379202e6a2688577933b5ebed277c4b4c907e6aea5c5e6ef3b297b00e351e58e028564a0442691e96f557da14f78c60470d32184320ba5476ca194463cb683084405839cfc9e3887fa5288c20903f4ff7f833ff40200fd7caaf62fe07a4143756ccd6479196e2837cc3fd30a40f46183d20f7286dbedeccf3801cc39975cc59b397ea0e48fdf9a153c685cee7ae004307a4dcaceda37c2e9eec470e082d2bdbf39a52f8bf7140ee4cb56e0f328c1b10543f0fa7c7e965e5291836208ce7dedc8eb5f0f9ae01a9334ac5d2f2a274480352fa705b65fb0c48f17353e6f42a03306440cef9bc7a63bed03dce8901d9f3a6f3c8bf4731e6c13020e58fc3c7e3d0616e1bc27841d1aa66259535532eefe93dcadee563b7340c1790ac47e936c2b2a6bc057fd6fd2c289886b1e83fcc0a483edcf1c10f74db323054401cd7bd8b414df57c9c2ce6d04de2312a485ad1b355365bba4f4178ddf3d8694d41bcca6a2988f2da29ea8ea42005f7cd951dc2c28aa3200ff273688db7ffcd8982143a5c85b5f0f1c55c2848ad7779ec1f7b509007ff9b53666ed6b8fe13c4dcbc19cfacf704a9e5a3aeb6bcaafa4e9063f64b113d1e8c670d2748b17ff071276d3dae6c82e0223e8e8add5ba26b82acb69b926682b0f1e647dbe35c7e3526c8e3e499b91b279dbc04315575fb47d23e634b103a6594ef6ad14e5682f8bf4942b3596e8f12a4d4f519a7512fd94e82e8ee1d965259415449107dd4a5219df3862512a418e2cfda77c36a483c8ef478ad559e479063aa79e9d11c419c12f5143ee9db5b8d20769ed4609bba3d8c11c4df507539329e2e3a8b20a6eed8921e8867e72882d43fb2177c43fb4c04e12da694bec7b9f3a0072288d9bf624c313f0429eee5fd8fb28620650a7d132d72b6d1429052c3fbeaad84205f770e6a69defde32088a649f366854610c4ee6871a5a2c7fa9f0904f1fdc3378f7776d3338020e6fa7894d2e3ff40f07079d0439759bb1c3f903b050b57deeac1377d20e7819c755af48f93860f64774f1f665cf640b63cb21abf7d3deaa107527d6558edd9a6aff340b094953125998a1ae3819c63877e8db550e00e8ed7d7eba56a8747f1f260f4dc2c75c0872a1663b6aed081783b7df9c1c377eecc81a0e77ab59fe31b3b7220e5d1acdaf9f083ac7120edfd9e9e0907a28aa5aa98699d836f208bb5af9f27d928193790423e446eaeb4817017fc3ef46003613dab3d8aa7dfdd6b208f274ac407b71ac89d3a8ba4a84ea62f0d64eb610fbd7b98e37da1819432675ed2628cb51e67206ccc70e1abc79a633dcc40da9c92ffdff72803e96d5be4e577c7260339a63ec6ca34cd78c640fa57eb61ef450ca473fd6c5e973090357dfaa8723ff061050c248dd6a3f44ea173fef802f9877bf5a30e7a3f8e7b81e023b9e0030b35de7517087be52f7d3e16d1b9401efa78e8b1d4c2ef5b20d6e68e1f44a5edc65a2085d8d7adbcca038db340fcccfaf723170be4b9dc9b51c9727305d286688bd6512b9047e153ae46af02b9ea3e5534df0d1fe654208ff3e86f3ea77c0ae41fc7be39fb3ccc17722990f2dfa65bda6fb5c9a340f2ebd03b2266559143813c08f3aa97b71c32ff04a269f4a8adfc03738f13c8c3e8d41dba6902492bc5fdf1783cec916a9840d8cf35fa8353f7bd2c8114b299dc4ee6422a4a205d85f830db7ff7872781d4ef51ade28e04724bc69c97a292962390a793a875c708a48fab8a400c3965713311c8973ceb84541ee59187404cbe1b5f535208ccfd47e5a06710881d539a4cd9f9664e2090fc7f98ab876251dcfb0131e78b952653fce1a77c4048f951e5a8e9012973b6b7bd2c5f15350fc81a956d31fe0e4abd4dd5251e1d10fff2407aea1c90e237f77dccd1c7c9070ec81d2b742a7cdd47b901e952ea2daf3c181feb3620f7555dbc3bcb9fae01e135a654ce360d4895dba3fbecce80b4799c3bb60fd347561990f43e45efc480f0659aae25530006848c3fdbf0812f200f2d252b5dc8bcf85c40b67af952c94dd16e01c1d234fb6d8a1a336301c1ddd7c3dcefc69c159034e7d8de797ad942011590fac73dce988395b4950ae2f679b6b3885141e8f83ecc7339a720a67423729b82b4f1539ccbb4f953530af249d467eccffb91a46873dc655de9310a92f95c4adbc3454194ff787fb7878298e47397b8a53f1f0b0af2bb7b671e78d4abf11344954d2e99e17a8214126749f22bec7fdb09e2e6643bb6163b83b69c2066fdf84716b2dd04d9b634a5ba7d8d5bab09d269b6efcdab0f93b59920c65ea5b6668f87175a4c902dcf85d81c569dff4b90342d5be476c8f4794b90c6b7837ff0902a9d4a90ece2c476faa004b9538e8f6e7d9041f24990265a5abf435de7b1922097a60ae66139a71fab9120fec887ae966f7f2baa902059daf0f0317d04e1576a738f25bf7a903a823ce521dfb3d91a93368298f9e7a2d5725afb19412e8d5145bd2a6e8fb308b2648a41f687510459930f33e7fd9f6a8920bdc7980e9123829c21e43cf7e843902ceb77dc0bd1830a1b82f4b61a5d935c0892df0f37ff72be7c4210d22ff478b8ef204841cb66cdb6c35d2b08426d1e180872aac748a5dbf8090141e834e93132fdded91f4855c177bb528aa1991f4857196f534adc7efa401e7d8a123dec74ffc1074255080fad77ee819407fb6143a7ece15ba9876d3ef34eb6ca3c905c53cc4ad7e51af37820c7fc72cda97b323b7720ac5896f7f1610742f7f033cac7b3123dea40fc8cead9f34e0752f0f8b131ff38fec6e740f461be1f492b07d27eceedcb3c9c303d0e24db3c4a292ba6a01f3890f3a7a45be397f1f51b08579df6c3b698ce47ba817cf1623caed60672f4cc9ba62a64033178cc831f134de283700da45039e506efd540cceff1873f8cb0d44e1aee9c7fa0811445e3a5cecca2f13310f42f63c7c26c6e3310f378fc793cd4efcac0568efbf6579381a4e953748f22c35f1e03f1a7f348cd52df922a06f248e60f3425d662320ce4d018638fc36b23423090326baa62fe601d635f20c6ffd0c53efaa8cef2027950b59bb345f8c6e9ba40900a12b9ef617a3b5c20548c6f114f9e47b30562d5ef4af4285a20a5bc7c1608312b21fd55afd9030bc4a5e8710552ae39e9f0fc61eeb815083ebaaabc6e3fb48c57815ce13e26938fe976a702a9c7527b72d59bf33b0562fce99fcfa81408329fdfc3f42fc6350a84a87861b62b7ef4130a44ad187b02f1cd3325d1ca2932e8049269a55df8a0c73f621388156702d9e2e6dc1aac3de84b20b5c7cce39eade0c15302614c4337eb2410b5b3eaf7483224902a4867dff84720ddeb66cc4ad7501e231063949ececaff63db1481ac9fb42e53f4b89b07114859bd7954793c8640fc61ca703f9a08f9f11002f172cbbe473986cc2308c4caabab503a10085aebae3969ee71d27f40caf0410f57537692dc0704fb916a6cdc0382c6e9717e1f8f2fa69807c4903ecea39b7f8d3e760744cb571e43f6c5ceb77440fedcb5d43ef1756fe58094d2c7ef7ed0251b2a1c90da2e5750e906a44d96d5925d485e6f03529c7a8a3b1f2dc7d4809cbe53e9cb4f03d20597cb7ecf807c5ff6d3e59e33333220fc304b79fbb8ba8e01396965d5e89185980506c41fe9d866fd1e48f902b2766acb03ab5fc9dc05a490ec94b356dde6dd02429ce7e6b0ccf29f05041f65141fa9ab6f8e5740a82c9e59de09a8806c63e6a39e2e1f263715841f255b1f8af728cc8a0af2e85389df6499c57a0a625ef3e84e36ee999a829cb633af7827b19096821463a488d6490ae2ece9be668a317d14a44c1e2b4a7e35ce270af2f53055ec27f3e8eca1f64b7d855f040a72361fefc719f7b185f1c5274852eec34bf53944e75b83179e20ef68cc8ce9033b41981e8bd48e7b5e7082143e97c47de83219e7179b2887dcd015ed2bc60db042137e54fdd496a2e78b4cd40b4c10e7b56ea6e27123266ff93373ecf1787109427dcaa7cc6cee6fedd60b4b9047179be44c53b86df2452508d33f97ab9339361ebe83179420fd28797812e4f1b8d7dfe353baca2989b32a426a6364666ec3dc7bdc5aaac36591c0eee33e66ccbe4d5e6624734fee3284179020cb074d29371f8f207a9c6fec183dae97e9085ea37b56f3b1a588889108040d17597ae1431d0259f5a3c4928a9aa73c84409430db1e75abf7b043d420104385bbb0be1e3e27191508a4f439550fab872df71aea0f48f36a1f11e5d1ea39541f90b2fdf04367364faa41ed01e97d7c6b7b28eee001f96f347dc384ba0362ccd891fee9805cb69be1375cb0de77e0c8814ab0220764fdc16d9ee9718a9a611a5b5ae080f05ef1cc4143c70d083bf131e711d3c9060d1d3620e5cf47ff7e6c8b1a905289d6e4fd6d5acfd1d8ca8163865d0d24584103e24e6b25dfcf197d7cf119907fe8a6ffe3ad0e977d1910b52533e5b1fec8fcc3589c1c3120ce8fc7991b77233dbc686c69010332e7d24a086a98197635ac7801b162ae5a64f4b9fcb70b487f21a75152a22afb16106387ca2cf5300b0837f23dcabfdbd73ffe46c902471633ec6a58b102424f8568d0fd915a4ca1b145821d6586dd25c10a1510cb73d6d01c36d80f561b65865d2a88697c18a47b725410d655c3c96492ce8d4e4194e9389d4baa6d9b8270f71adeaa21fa07652988f661eee1ad91823cea5d97cf16fc51103ca5435ae6c14f794441cebad187394d0f7cf45090d2c36bf4a75bfc70760014a4e8b63c58ebfcb1f10992ba7778cb6fef09d26bdc5cd8ce3dbff23b41cee9a25e397e3841ca8e3ddac1e2e8d784ba09b27abee8b43ae9f49f26c8e1b76e36fd7854f1c299200f7f903f1e55e7696c69810962aef2fe1fdaa89720c7b5f9b1ff7898ae2f6b09e2051ffdbc94cbaa7ad44a103a4a56b592b5e5c18e4a09f2de85c6ec96f2c19320f4ec76ce2b4ff959469504212b4487cca1c35de50e4482dc9b2e6dc798ffd3b91d80042954cad55e59c9bef238361e415ae96d5b8f39f546fdd87004b1c7e16fc5e73659851d680439457cbc1d6225346e3ac00862f6348bcff251ab5a2c82243eb79a7cff4766db0e4534213fea91f193c6d6b99108728fc756b443a794b7d3d84204f9bb77a73dd9749404203833ec6a1c829cf1ffe350e6b1727d438b3704c14b7b287e2eeb63ae8e1a33fee42804212d340f2eff478b1b33fee42004f9b2761ebd64c8ece50f826896492acce5d9fce80b8298f179d0923e0c6a20487776d9a3253c7fd60e1004b74c3a2b1176e00f04bfb31ec57468a5cdfd40f8b4337f99abd8edfa405acb5cc952cadeb4ce0752a778799ce367a7e4e3ec213d1bed1e584a696ca91e48a9367ace15dbc30f298d2dce03c15e3e5c10956d9bf6f1405a89eef1a83ec5182dfb3b907d90d9bed38f47793f07d50e44ff1ff6b0534a9f7dd0dbd5a803c937e6d955b5a0034976e72f9cd6767320c665bb9c93520ee40a1dbae288e696fe11075268adf48f473f363d0b8d2d2de04036cdfb797db73710b3475979709bc28f7f34b6b4700379f5aec7444f237dac561b88361953ab746a6a5ab081d8c31f3583d740b4948bf0cbddc3143faf0652c658981fd525e9d340f218a23a558ee7619250d14034eb1e789ebc686a393476865d8d33103c3e0f7e28efa6b1960e339073a51897f14a65428c3210a57d70d1c3183f1e56ce0e321073a7689bb35af0cc1a1d63205bcca136774a7d315a311053ba3cccf9573df5614e1623d8c14e88110672cc7cfa71dab498af0103b1aa2ba3ca94c37c81ac978729aa079552dcce8c5c420c2f902b8d95e78169c61e7d686c7581a06af2e31ef7603636ab6685185c20b80f56c63d69ecfc285b20868bcb1b753f218616c8e3faead2e328cf1e5920b964bf778c9e7a2d87163b4e0e43420c2c103c9e79fb864a887105929955b8985bcff1b002597ef0e9f32876686ce5785481ace2af49ddf3471f73e350819c76511a73741fd50f3b392e0931a640bc1ffdc033a3f630e5181a3ba44058a98fca1fba871e8db2c34b14c8e3bef9e1a27a48479063471321061408273d1e95995cd3916d9c279037858ab18717cfcbafc14388e10462f68cff94471b1c3608004688d104f28a7d5cad8d174dd7a38e108309a4aaf09b2ed6e798d3e83b6ae8a81182ad2c28a023c7995145155554d184184b20c486f994f3d334b6b4dcd0a20155e586166f31944076fd0bddbf9ca2344fb800182e04d0002b04c0871849e03da3233ddc2cc6c6ca3a742f7bb0151e43a71d030956dbde450bbfc63802c13ab3be77d2603dee11c30804cff2ce4c21d71a218d1b6e03c6313826c0c7e0b88117a308e4b3e0b1c783174b892e061110cd72ab945a95f1e86c0864cbdc21a611d9882104526aa864d3d2ff83eff13568e8681d59e09841318290b5685bab98966de74adb95c70002795c513bfe38ed183f209484a79c4f1b6ea782183e20f43886eaacbbf9f159dc88d1036258facf3f48f9c4e001297b8c25a3f79936e5a1c36d507920c60ec851295526d5f7fdf3d125860ec871963ae7d5ca831e69686c81e058391600001562e4805ca5b9c7e6dd1eee09810e1c9087f1c7316f473862dc80e0e3ae9cf36df9da7b9723860d8829061ff444c66cd56d8e19b523460d483fd49c99b6cb19dcc331812aaaa88a4103e2874f62f16aab62258dad2d703c667ca0b88d47eb043430630031664078cd238d527567e8a8d11743060fdf7c3ccc94d5628b1103bde6bc25bd32432a5a3b6dcea9ba62c080a4a3ab55525bae9f478c179025fa624c0fdd3d06b306315c40f08a9febf2f37820f723460b8c1d2e49a6ec3d9a190331589075f7a694f4d15630c60aba142b0d2f759b62a880746e663f8a58af94b7070374a482d8e3b07831f7072a9a4c3be97431bbaef8b8c8cca9e2c71c44a7720a724e5ee39752baa5784d4112d198ee9e9349fa08a314a44edd8e14648bdbca4e1f390a82a68fe4f328d3304441fa1f6d180a529acafd1ceb4051cd67aa856e58c98df37f82d47960b1f2d0bf2bb805303c410a95ebbea870163a6600c00a303a41de6872c12c2567d80260708228b29f4e43563641cc983d7b5d3255f7a909724a1dfba2a7df5f8bc904b6d56a339559675a6ddd5ac10441dcd2be44e529c4f95bf0acb104d6e6e596a6fdc3ccea8f4bf94a94079ba632a2cb433028d145a8dc46c985bcbc5d3026419acdc31ee5c94e69312b09c2e90597c696568a004624cc3fdcd0d9d5cc29c08004416462d7df37a3758f2ac07804a143345ddeac91854b01862388f3fb29f54d55f6cb3782b03d1e071941aaf4b6f5b1c7b946dc4510ad424ae5c91586228862d923377612411ec65c1f5adc983f6d07118495ca1f0f63901991f610e68b858599d31004bfb8ed29d6ab5daa0a41b2f71f5799a567c0200439eec3da7c5af4dad00c600c8294f53eb28a2a5e00431044bd58215fe1d30a84b11afb31f7bb32fadc38585800062008659ff19f57a36fa5fc81e883bfc83a09fd40b20b97f7e55ff4d6ea03e12627d7a3fba0e32d7c20f68f773c895b9968ce1ec831ce69ee8177f440fe71e56c3af13fd84ec903d97d3c968b217d74a17ee0811c36c5d50765de72e93b10ef87c136478fed40ca513d8bab57f154ad03b9e2feb25ef80c3d1b1d4899ba5c35edc5a22b7320a486bdf06371e5402e8b293de69d712088c677dc1ffc8003f9d3a69cf77bbf81f6166d3991ebb6b834cd948f10dff83977037143e945c47eca95622980d106d24afe7fb04d11cb7936102d43e930d6409e6ffb6198f96a2077cc637f6d0d6a79cb3490d2cab603030d04b96bc9ff3c691f9530ce40ec3cd150a9c55dd3ef000c33dc2e2fed5e6135ab526b251162f5172bd93085510662f0168b397e31c5709a1d3a6664a183c0200331050fa9f941a56f77186320fdfe78fca3435ef8702a83210652aa675d1ff930f9307e8481e8517f7023e9c30003c9b2c6690b9f551ac0f802b1236f7e643f16478ea3812b607881e0797ddc692a93f66b72ec9061851630ba40ec0ee61e7ef82a1b25185ce05b6543aeddfa567da417b70ac0d802f97a64b197697e7ddce6205554e1390e0c2d10aa73c877f5f7183df2c6f9008e2b8e0430b240ba710d753dd5492c7402185820a74baf96acdb93ddaf406897f19186940ec30a4493cb23b3e868ed9a8325805105525ee51f689cb81ff68902185498023953bdb7fc732dce72ecc8a26148816049d4addd07f6f9bbc60dc0880279e03ee2431f0f28b839fced65981e4f28256554a43d355cea56f378906a220c2718b4a2f98f5c930a04184d209d5e5fffc0f330ac33603081a416efd38fe5b66d74c05802f94767f13ab8de896a0516670704aaa8a29540fc894d36a1b1b9077725819096ac879e9fcc731ab100030944f3ce58b3eef1b9657f01c6118879da62eafa0d11e0b8f1811b153002c1c24796da3a945dce6701461188ae1fb33a774e8ffa37025b1cfe2ba840cec1ddbe7cb0e3edea8d1a7cc514082beeb1c53ceb9776d80057488164bf21ce6ababa2d8710b8220ac4649dc3b257a6cc520c0a04a9e9945d3fb168f3ae7802417664248349955a2ced8a2b9c40f4d1e7b18faf6ff6b4a1853b0e1bbd80ab43a378c9095cd10482fc956bdc914a31eec518573021af5802d952f2ffd23c8a3e0cbf120865c92f5ef7baa5529240ceaa5962e5712aff0309a4778f3fcea93f0221cce23a7d78d9b1071b8118165af58731780cf91681d0a1358525bdfc9a2b1148a9753a6768ce94c7da154320a46b1eed85f78540d4fb1875f335a6953e089fef66c8b10081ac99c2d8c8c63cb6bf7f404ae11ab3edff285f5a1f10e3c25cf733ed0139fc54680acd95d7421e90562eab5e34f5683cb703627031b18a771e3ef07440f441f75d882c07a45cb1d36e4564c43820a6e5d26cd9d91537208f2e46f447379703aeb081611b77f1a19df15eae19db24376dfc60bb085c5103e2c59c7207f5e0153420fc38d773f6281bcdf10c08ff25fd5de99401217f3c28159f399d0f5e1103f2c7758c1ee64d3d735d0103f2e0df344e799e7d1e9f37ae78012ed5e73ebcdbb2c0c23e70850b4839622feace23827383b73270450b08763e4eb9ae63c470050bf48df7dda1b4a7edc1152b20c755a8f5c7596f56b70e57a8809c3e141f6cf841c7f52815c4bcf7d9037155fff14a0719a820f7f674a79ca4ac837a0a72ee4d99a65c5310c37fd039532905617da4613fbdd6874ae51c6490823cb69d96642a6f771a0559ed27e63597a220cf8fc236e865a120d68ff3f8c75579509067531efbd8e3860e1f8f4f90efff82f770b366f9da13c4f01b73cca30f3b41dc3c393941ce7934591f237fa3379b50ad4307e5204313e4d167aeebf8f1b374c904b95a62d67e1061823c7ab1ef680f12135b1c645c42bf8a4a5e59526d371cc8b0c4e67bbb5f6d3f4ec971da7e20a312841f754a890c31cf792025886df92e7f593e09b27c98da70ea1e4f6f49105735e7fceadd96a3c7e020231286a91f58dfff288dc63490010972104ddf9ffaed1fdb1b643ca2d5cf0d4bdbd60c643882b41a2b57c7bd37df6fc45639a76df05139bce8a861dc208311a4a8997f6ce17c2c82942cfd38f838df958fc7a3db204311d9de67f168cb1aaa1bc848047173d7e8f45e7ef09fd9200311e44dbdfbf431a50a1f7c088286c6451f554e88680882c56c2722972966632148bddde3a1a74e08c28d76caf4953208e254fa81485d8bf7701504f1ee534d45ef8d5f331004b3b01faa8c8ffd471d2008ff3976e1bf3f10e3c45a540cea23d1c30fe4eb8d3d4a76296b7a5c1f48a672e3a5394ec533f940f4f187961ed67cd64bfe1e4811ef19bc3fe75fe9f540facc9d6b2d9e3ecc03b1e279fc6e9bcbb71e1d7820250bab3affe37187a6b507deb103a937c7af1e9b8fc254e63bdcd481541bead95e957da9a443c9e285ca58132a6a6b31878795362307726cdcc830adc58154f17dfc69d6b963291cee74513d56c24752cd18410ebf51e36103196f20261395d0cb9e4d67bb811895b176e907fbe361d80662b0d41c2fe579a0eb292c74f805d840fcdca6a59e5573cadf6290b106524af6d96fa9a981a41fdccc32753757260db4766d5bbad1b0688e8c6531e6944723649cc11c43fbc6f09e226498a11f3fbf98d6ba73b86b20a30ce4f6a10f7e301732e41d7d18ab39cdbb061963307b324b75a81a6488811cc3a896a5d66120d8c63cb21e7d861fe6748081649fc799f3fffc02a1aed5c424ca3ceee205a2786789daf46e6f17c883f5d18e69a8ab858dc61617c8d63df0f1cc0f274f369906195b20a8b94a5fb6984d63ad059226f70b6eadfde3414c63b340121fe67ae9dfbc544663b1e08a8ff3624e63ab03391c8b83c5154841e7da6b73fa85bf5881ec5917839d0fe762f254816031e673f6999af61ca2410615085ed7b665979b0231a618e9de69bc33c89002b9e2e332f7b06266901185bcb2bb85ccc4f78002b95ca387b14e1be7e136ca03329e40aa245626bdf9e3510f7602d1fe3fe5df3cb86434816439fafea3fff178e681430613889aeec71e936dede674059241c6121e75dc5a05329470c8570b162c6dca468e1d65461638b2e014c848c223938e3a773d8ee90c194860c25be46333463ac6d849635d8ab6ce1574ddca02194720f886bd5e4b61f3038d11c8679fd793989bbb8ec5cb2802c156e7a25bcaff3e74b88e1917061944200f732e887a66ccd9c26dac5d41c61048ffb12cdbab0f194220c65f1fadfdf7c6ce1d194120f59a8f52580df25b1d8dad0fe8702c76d47800811c32f347d1fe4163eb0105193f206ddaa459f9d3b5865c860f489ab647b3c7348dad1d386ef480181f2e47dc64d4a82b2a41060f4897738ad97920e5c3cafd0e88f239666bd9dc4eebd7c1a3c173fa5cdbc901c982897ecaf97f467c1c103bc6acabf763798bfc0604d9d0a145f33aaf859b20c30604f1f138ceab8f875279928004354420a306249f1f9fbce7716840dab1303e96f219103a4c8ff74abd62ec7132204ef778fd1890b35767d7640806040b391fb551346db8d816a82f20a7e63ce841cd0fe673eb029266afa5524f8d2e1d1a5bb8855d0bc89f53a55c95630cd3380b085675d939a794b4dde22db46ac858013163c5b04e313774d0a8204305e41c5ff33045b310f3d98ee239766c7152416e8f61f231fcde67f55f0b1a3a66686dc1a8208f3ee7dbca7ea091d15310b22d5545a5c614c4fa36f9a9cab1d4fe5290efac0729887e66c187fa9d537d8d82684946a3aad4e2f228a8a220c897e641268b5b9bb20b05597be0dd31c6a8050ab27cec8c172a1f1bb7db98c19f20d665398dfe69deb1f60421327d6af270e438249861d709e28fc7913f4e1fe7edb86b718264e134b5e7eafa407d1a5b3bdc46163a666c82a47d73217ca89941bc2d5813c4d0de175f17caf34867ab106482942afd9b5898e7ce1a4c90f5d3bfe6f128a6b1d5011a658b2cb0288c052b2e4168ffb4d5bf5a82e8795c27173d2a022c72548260bfc92cfbc46cae8b12c40eb6d1620c3bb1719f04c95fc3479137a34a82f879b4a3adf9fda7deae462408d5835cd7ad6821e30512c4db14165ac47e04b952d0ecb5eecc69ab1d355c04334a0d2c70ec702b58e108f230d7edc71bdcaced87158d206ace94d57fd03715744610cc828e8f35848b206d47e51efc6d0e1b3716c7c6510431074b31b33f7a2a661241ce2e3e3ff6df3d6a0459e028882076f9c6dfdc108d3edfa87188df33466b4f591a82ec96d96131ba9aa35208b28f73b8d33c4e1382a89ec7e1a5651a043959f5c79c7627a2335608823c8eb2bda9a8d6f840907a28b1fffd4936d5aff18020e6ec26cfece3d772ff40f09863fc9f5b7e7b9b63865d8dac82157e2067ddfca144c6f24d250dd4ef032957b40e9d53cf077285f8f1a788f0b1e6bb07f27e0ed50f9f1e889f49235ecfcb033166ccf651ae643186f4c71014acc00351bc572bf8741e4d5adc815429c8747c8fec40f2816f0cbd3144f6a70ec4f9f6f1d891e384e0c64dc10a3a107a9c6276cee7f1a58c9533977fb8b4cecb813cef771bd2d3f9d91407f2e61f870fccc335cc0407f2a0ddb4071e2dde40cef1d9876f96d2963a504d0a56b881a0f2631f4d19e52f6b0339adc37b3f36a86c207eacf4169129aa8f5b03695fe37da8bd2c0a56a88194c721fab66ce637d41a33b2f01c22986157230d04d73fd9b3aea0a9353410eef2e8aafd7d67d4672056ce527964d32b1f356620e54c41e3ff682f03e9da5384c5ecc940eae1c4ede67c8e8118d7e388c5f0f162b88881e4e3689d529014350c449351df1ece060cc4a42afe66797f327bd42f10539c4e773dda1e7dac50bd401ef9e8e58165b8fb8650bb4030cbbd32a930f5f17081e43eb6b0dcb551b740f0617009f7c94790050e2bb440caa94e6fbb2d3c0be489d29c83df47dbd4c0020b448f4acd61b6de9fe51548f94527da4db57b3cfa958a9767ae0a04b96c9e7d18673cd5a402796cf367ba53d1bbc329903d588abf292ead7cf8e4702ba440de3c59af79187dc762686c4581fc31def93de7e0b0f133ec1e0ae436dbe8e6932edbd7384f2025d9ef71fe1fbcd81d38379c40aa4aeb97c7d6c367d87d13481fabca079d2f2690744abbdda7445d02d12a6de56da8eaed914a20a4c530b9513435e59f0472c6d69cb91c2a12c8b1a24755cd8dfc4e413d0259d376ca9d4aeff118d508e4f19fb6d9599ab1ec178168068c65a854cca66342f24830148bc4e2602808d12d4f00b31308000034348f0563a12cce0441ee1d148003754e2c3a361c1a161687c4216140200603026030200c0400c06040201000034221872cc3e3038252f398164567e3239f9a8407e101e0223967904d257e6c18d827133c4a92df7303ecc3738f10b58124fa438a20a7c79b3f7b4904eed9c60bb04a328895b5743f6f4f7f1177500bccc5fb0775e916d8f6ce03163531d88b2a1eff3eaa3b0f5f5f0236ff0cac80836ca7006ed53d7390bd08d77daf1145a745f799787363dcdd740897fb8b4be2b98f3963823bbf6741c968202728b86b458fee6c4902e895d68fa3139fa3547293041182f2295460d925d53579c84ca935d407da904d82473e9a7c458a03048f6d3ce0e00316c221f6904c23f084dfe367da60da4bb26c6f5ba9b630f26baa0300c62c8cb03f15663f56689ac077a20288f2fc6242165e9d330c97c32158ae0ccdd96773b0706a01181214b2054315da202fc56db598491a3fd940127d97f36c20551b3a44be9d46f08057615af26ba6b001a269074f8b428158b43dce2403b7b348c6a0876071ab382dac07e7f5333e8242178e5763bf02728841edbfc534838b70e4818ff8280cd0edc8aa9cd17395d9c039049b20413d173139ed8dff83f3e8398569bfe83c677a817a62de426481d1731cb6434843f43c3ca93821df64b3a827b20d0c0a0aad88da930a2c464f83aa5366413d213948b98d2863745c2921482b835b16d71ccb798d71357ac6c2612c276681217fab2297c5909e245e1e04c5a24c216a5e07319cf0f5e18a49791052eca4c2f5b93006f5675c72ff90abbb07409f9a36f4bc2733534620564dd725329dad9aabc5c6fce5e40ca06b99897b34b877e473bfe54d160e95062f3b23c2fcf058b293823c2afdc3740feeeca52985c54e2859d52a50649b24e4e07b1ad1f22e145571ba4c0420f2a742bebda418e5858300ccb9719a2da574335fe20dce992c27899b23a88ed903ef690b410cd368c46668e22215e5812b8b65b95c84c4c4dd18a4900b8c5db552c8e1ea392c53777aec8a3740847cf57ca9c846db1a217581942a2242c2bf48a99211f2d24a621dddcb26f1f555138df4802aa194615744c7d399e67ea8e38fe3a13e50c72539503e411d91b9dcb605d4f1ba06664026656a2f61f4b01947d22703339b982411341fa08cf6387e979b4722a7a22af96907dbf797206617244f935cc9db068641895f247e898ca3cdbca50e2a679fbb035fec37b6ec6aea37635108992c0036d707ab20e8487553d16e23ea3191e7c6115171a3d16ace562a54a39c2ae4f07a3343117e61589b2454eb2a82ef308ae2d247253e1db9f1255092ed82e0ede66810090100a423ad91ebbdcccc9a59d59da97bbbb885ccb9f4f9bcdd0fae189f223a141aa7284b21df73b1a66aec2b999008da544d544b986989857637ae528cf6554b0f7712d9839e68351bbc62cc9c7eadec959b8e296f4269a8dcb6c94f452283cfc4e678385ba76b14c9aff576b913e9c47e39af892481cb9f14722726f7bb8b65a5aea032c7188c79eb67625799376c4bbc86874c627b92a8c98159d217d5ecdc883f458961c00b5cae5ca549a22925dad2c828997fd5b14ef9afc8b839c78803232372af14da939049a743288d8aabcc66cc8ca8b876b5e2f7a8a9eefa3289e77e42e7c1f62935085f86daa381904806e13059d14ff9f7b72ac9bd686788519ca204becc3ded46447c1dd59bee1204c98a73e68ed5b754b0666655d9a2d829a0c22ab40d59aa7cae839a1146a8b4acf8113a366758f9e4a4f607ddcdf7521572b29170cd1b4d669336eda75d994928df0b3584b8210ea60b2f6a59c846e445404970212ec924ca15e00f62cf97c0f5d0c17dc927a6daa06c30712af2216efcb7e01914f3b28740c28c2507d7005161559566038781a1f916a6f8f7a26f9589011ae03066ce62db1c6f1270cbce3cf148ad4669a42cfe29953307dc0fb59317aaf5194e280a3c0ed2d2a37b5d8fc04b537e59d33d82c49a1ed21e096c999efabab3cf1609c2f0562d8bdac549c5198a97d85798da685a3f55236f7a26f1421332e5e2d6280f3f15514bacd9344d970742e49f952c68480d6682e6ed0a7461e5280ff033ba6fd4e8642243ed65143dc8469613943cf0d02a2287c6dc0501867032c89132bc13765e9221e0b9a8d609f81c11385f17849f3a2bac2daadd4841873feee50a2aa75f8468d23726bdd0e462b1511f104e84aa0cd8b2ebae632e7c15e08438cb64178782f0be8aaf227628efea8eb404b95f7e432aa10150fc0a0540cbafb05dc129c0c497f3153181e6b04c141e78ba37535608de0e33e80780c30eff616f9c9f55ac59f6688e4e6d9d6d07f0c7d223825c642f1b855b15fe0f7600f67d130b82936869f2c716660ed862d582a903b64a71f79dd42d2c8e488bf5aa50a2aba2ce3a84554ec2c69436400bedc64b5b34c38f6f5e9ca40140467c1a4b02e488e00baf768dc0e5a9845d2ec7d53114256cbc43832bb660ce2ff5e0131e50b6351708bc0cdba8bda10a44786a950b24b70202074a104a2c97166afb984561c42cbbd605697fc33443dcb34a4bae4d548095c79e05df04fbaec5b2840853b11343ab3c155ef76f4b87b30c608505e4b0d085f5d95ec115a988db645f334458aad4e5636c9f6bfc23346832500be0341537cb0cea650a538c8c1a339300dd38430179a045e01642ef53042706b17968017dce144e6113aacb3084bd5204d42765de0408a49106d4a53f0b958b95ef264efe0a3e415ca83617bd213e1831395a5078b0fa7bc1aaf5afe3ee7d4e3bb7295895d6c5d527cd4b5cd60b0871df72f870d723c5af7618c000954d42eb4961bb886b84876f9d20216c03609210dc33310a23c8a4f7f891e8ecadbd5dbc93c8f1bbc017a90402b02716ed02c778aef091b0601b816d06d98756614fa7c0842f2d42bf617f87842d6705ad9a47480c1116f1f1c636ccbbda102ca2c0e87f309855ebb7119878e24f07057698bdcc32ca0be2c908d08f1f20f0629b0186ae7621dd3dca6567e556182a5e5716855c1db03f63af4dc100fcc5253b4a614d5e9823ff3524563d4007f2aec2f727cb0b12973e62976f3f0b081faebd4bd900896b47cdd9c65e2a8a56daa103047e85348ceae61e2390e635db1d48a8701030a9809f1fd30a611a31256486f88198234cf7bb8bd4e547584424cdd8b05d4ec54d51108f1f0b18f17d66f080208153bdc00f62ced4240633e3a980b83015760250401e4a0540f931d708d3746e618616f811b005a711ee5e4bc5a35e0077b85f0c480573f23c1e634812769430c1fe8c547408d3dcfc12c30b61fa50b759aa89f02d2425b8d36e0f210d0ee33ec4f7941affb00f8149456e34a29cb08869a05b4b1b4d69090245b5ca68d65d4dbd25fc51d2b14d99d244c44168cf8ccd5c24c2f44e9f7ba84d89d0718d00d242e18636c6f91414171217a87e0f2cc7bf021b760955414189e3481033cdd41b080f140a1c47a9001083028613b73a4472fdec8b327d0ab497a05e175dfd299cf10f955a419de30ae482a7801a0e0588e1bc001b69ba90b8a813837ea64412a64420dee7711387c10a387323ef0569cb84b1bc38c53e04ed12b672c8be9a810a42d1bd3bd1cc1031ec1f1d441fbbed4086558e30114809b46b32f33902c9d893dd8df4c8847e4b103a87fa211322a19b883384aa0c9454017398ab9b59a50196840309a696261303c244c49c3c738b30f93d51387d21cb8b02828949368183413fb39e40d83327d114448dd89eee9a7afe30443acb19778e10044290514cc74c05f5cf351ba2e4a8d63be119098fc291bfc2ca29d267d43781fd0952efc4913f559e0262e7612ca2a4a333c46d32e228cb85ed7aa185f0536e6535118a03226f677463268573d12b400a8750c07a85f78f38f9f46109e49c225fc175ace1d6b2832485e7399edc15ca405d0172e8555078e23bdfa69c0a1d069582c2039c40004487e0490c828808421ac610085d8212e2341fe6c4d8e2b43a165071162e088e06962142b311255353b120b427ef203d256f0998a1a0f166ca0ae1d45a55da9e20fe5a5ca97b554c9dd20419a1fc54042c6daa5d0494ce50d0deecbf80929c64e5e274be5017021d34a91301936316d5e6224471d368d6c4849e5a4478dc1319012bdc474129c90a7ca5f5f3ea02545124170cc9f9ccb902a180bc9444842cf68e1821e16b624190167d0594b899dad34108b5c3664cc6b8243a903c3d56116d5aaf9e3c32a622cec9a0c27e57011594166a3b08a890bfd61daa824641c956281d1a81c32be80fefb17a450a3f512646207e219a39440ed5672f57ab6d7e2d54b227b026c117014be4980504e8bda40da1627850383d47e8565e84382b7abd480979fb7485cda3e97735d734ee2636200f8844d1b89802d57ab0ef46b20fba09927a0a2b28c3153750445a1a3d06c125a59fb7b0e4365610d85b273fb1138292f5b94fb86ee75213213d076b054325b7a06874536c54c7839b8760219346e2bb4c89d93adb6044d7cfdfa3385253c4b504249d6974935a51ed53f483fe3acce5bf13dd0952777093f20261b0470b84321004c9a18cfc030661045b2a439c812106662a4a646d92d631f679990824335da0610cc2471577f8240ee8dcd12355375d4393084028aca660e0d4d94c3dc28d7208d0a05affa7996f69a41d04f481cf5c81d2c327b1550153ad0dfcfa99a52d56ffc72d897ee2351009b43b73023ae81f57b481aa77538c9156d7a70291b472e0bc29c1f12cb4414e020047b05b1cdd90807102579c60d16eb4d864fc1a024489b64979743f5a3cbf1dcf9d1cf819d384fb100b55faf24723f32b51f3d23ea67c673259d7e040c3d04d1a80d0eda1f10437ccd3e1e5379abe01802a0fe096e774089bb35a8dc21953619ff336082a9526f359369388ee920fbf7acbbf85e694cb3d84ad7b1049856d7a4c8d9b1df007af4e8283a81464d590ebea639cf035efa029a2c0b4e4039916dc1374a80ec9e2cc3c91ee1dc128aefda8e4169f77eb75513f8584605d0e9023d78a45102640ac9dc7cd75a785c54cbaccbe02c8002ee3edfbf26fe58db8de4faa63ff4d07e76f71397ec445b7e4529bc2829b4ba190a967085d94160443f9f75118f78d4440b986e5a1857e8b017acf16b042e202ae62aa0580c3d688fcbb7689972c1599c67b64014284308cffc7cc0395d00ee6889d904e95bcc6cd029eaec25dd956665abf623cb368482b83ccb8483e9e1b83672b68b0d6234db88f88dc7e79baef3b0bff111b189075f1befdb3ba008fecd0495f3e5e706674ba36c705cffcf945dc8e9027f5bcc4b1394e1b40c4d2ee0cade63774d48644d774ac75e49205d11677fbd87295f5051d529f1cb99d2c21c77d2ab0cb20502919e8d1c58a7a846eb6c31eeeb39e5652ea69183d3ac27b0dc48b6b4ed24bf9c3e51d700898d0948957e39ef8417e98716fc22768824350782632bd031f85407c20ac15df5e340ce43d121d8790e9650318dab38921f0d2b64d48e316a3df63cddc7e48ba9b1a81191da597b13c8e9f0cefbec84632a72ce5d2188c3a892b57112613c6e7aa02bc7f8d3b19b854b32fcebf823051045331e6ff7c8f29754fdb6d044d573c668d863e39b840ecd5ba1c6b53bb57c09338593747280893cd2f52b36db46b9003c2d973d98517d842420462a36bd253410dacb57b07e595fbdb7340d4e7007307608f14fc01c850f45436cd507f23d972b8d58442a595554f211d3b44627f5586cc88a13b2e8b5abbbd8357f0da6d835d038a6f49c634edb2561fded2fa17b0234ec81cd4b6cb8a2a30c32be660f2e68293dca631ab943e8931fbe047f83551caaf83b776bb08714598b601dffc51931a8e2ef881ca32c7af54cccc64f4e05ddbda8d76d074caaefc50d96cceca54ae29169fc9cab753f82c94fa01832cde0d8f02356c5f76f385838cf806a99ea698f814361392293f59e4f7819e6167f71600093b2f7d2d6de04875a4136dda8e5cce2df8636029ff550370755a54e230f708d51603abf49bae940aad68b7f55313e191685e42af77cae01081b838cf498a523d2c7e24c633ecaa1801270456dba946a0e0b2f08ab9b19751ac41c623f752cc160d0d57ea91901b4b8560bb5501e8ee7e50640cd21895a1e6a9cc84164ae82ab63c08add142033b33db8bf60a75d2487f69f632a3885285b38ee394cf70b25078e03e2cc0889103dc2a8bac4545a2985900a518d71428e3912e150d1c590062bab303cd29fb67d4292d1c77e1c4eed47849525dfa00db388d6be4484b748414898b8d41083a3629602533cf917a9f61d9ba6b66ef8bec5f7ee0d472186b571dda669a2d2980dd43827a9148aab8dce7e1703e985e87b9d3e2c58e35f0d0530c4ab8518c33b65b98a428565352570aee6f726754e8b359231fc4ed598d3d50e398d35cfeca2332cbca14179c9aa3988f66b776b40e700e572a8759a7cae03abe46029d587a7119f0214f399b37356583b4a687b86d4d8a863740ee61bdd3b5090b656fa1601eaeeae8f9c4899b14974ff78c831975bdf775e226ad3f524a4671e6afbe256abd512f7b3814ab4e108541694585cf49354d8d3b7d443e0cfb767671445d82f97b2b422a18bd8dc8cd7be80ca39d56074ed39d4fd4e30387a87d6bd881487949062cb082d33519978c9220440c35d678b42a728593b11d98cb4968278dc9ac6edccbb5d66a9b6c26553d798c04a026d4a5faaf889ec70a08dde5dd65040c49896914324f59bf1e3ef5dce6722bbec0232e82796d7742665e18fd905180388b38e280d7ae4ce0186d6e191ad08742c1258b22bee7fe8f1069aa3fc8dc1de12ba5ce9c112827d56c8ab6312af27207b67a0f3ff1e9ae60f89ec0d2c278bb77d84a75301564b6403a9628ef8808562db483f8584475aae92ed8414aa31ebcdd72a8e37a04a309890dc0b9c8d046637d1ac6d723556261e6c84830616ae4d221141d988d8b05162313e14e3e89ca0a8b67317789fe5210e6990a57fcde408506c7d85090dc725eaa5d4c0d36507f90554e99842d0586cfd2913bec164d19326a35e4e94678d7ea229fa5e9776109f97254f34a0bdf414fc34a9802f6974ad96f12c63df8cc6e6f1e22b3049e2312fc56504217c7a4addc543072a2dcc1b6791228aba2609c48691dd122fe695683a512766992aafb292f99d29a7c3cff864153a9dff6bb4584e256713c8337aef7457acfb8733d589c7903de7a2fb5d1f6271303af5c28ed609da283b5b6d5b7c9183876140225f196de5500437981eeac4f0ae7b733fa57e210107f7a21cee129a86be5b6a15f6b56e4a0a40541ba90ce8d73001c5a7ac58d4c56c55e5ef60e662a7a7505ff2b998765e6463d59108df57e2d9c450a77a2a359761f0d10009c50fc0e0c16e72c9774a66c32d32148522b68f6ef82a5ca422b95365200a9b0c904e56dbbcfff2f0291572389d65ed9b27b086648c60c772a7d145007795300591c1bd0f47cb18f6aff899777496eec3dc6222ec1495b17d9b0ccd8342567eaeaf12e3886074a976c4236ff9133ffd890dc6bcbe05b1ebe98ed1a2239154dfb10713dd113e89fa8a1ffaeb1375c5543ed4bfeda537a4b8985122d1294702f5dafbd16e93eb8bb7eac6b58a705d28fc6d02cae8fa82272694ff47dbf27b78f49148aa4be12b7f3529529cc56a86581310d7eba91294e0c5a877debe35902a343a08cdc567b0bb13e5558cc0a2aca473de5766528196c91cb7b576b10dc7333b371797b2be706df37bb4c1f256cca5f9ca9a0b04cb3535498df9e2f3641a9c6c5cccaf376d7ddfb8bc006927c96eac3ba45d492c8f65a9e005619e18bdddd2d32b3730e22a8c4d41a89db898cfa688b16abac6fe2cf2c3c8562b1ce9a7bbbc577e717c11b620768edd75139a3adde6a54181d1524a1b0339fb40845f4d45a9935d614d2a7bbe0b90f27641733c333e6801cbe1729cef9ca9fb00648a1537dc6459ff2447b19cca0996142c909651ab37d79df3e032afd3410106691174e025ff0fb5e534e269a1b4fa5c2944101048362c7b31e4947d07e66ae76093219484e49f4a487f12e85d9c77082ae61f3fe590bb277acdd4705f4cc8c5911a7e824e6738436ac05a53cc0abf1a2346c350ca44ee99fc056f4a541904c85aad217712cc88edc01fe9915069c91fd67fd31183a423499f529844a80662eb12d9207eb45a46d027fa81804a432a08090cf2c02051f88d2ef4e72118a66ef6d81090d236da72817d29cddb5d6746bd4c9fa69f43fdb77f9656eeb11873052a74cf5e9548bb0e51852360b4ac89df52228e12da978962c42abc95541fe80f3cce2ee0e562245d9b0dc7e479c29dd3a5413f422e7afd10125b750240b7f0f42f8fd1b96411fec1d27db81a55143ec23153515651e57b2bc48e853f969bc276fe925725b0fcbd8291206482a8e50882ada5a84e3851da333a8da557966f97ee271027600a09c0cf7f04e5e5a0d6be5bec1f447f8023eac40a8806d048de32fbefbfd61bd8b36b67e1808a2f6e4694d7919c4633c2a6ecf717ab0e803e95d535d9fb01b77ff7758e73f47667d46ed17c466445f818af7c89df65a3b1333e43c9cb9cb6fff892261a2b0625a19b459848d532a234a811afa2608aa8353965f3eaa979da14f00c7df284839640ac958403b22e73b7c9befda25f2fb00dddde780ca46e6d7fb644a47e34fbe0291d129872c69342ecfbc8e439a369570e6e7d16a12313d1cf53ddf44249b748e89408eb134573e25584cbe1c83d84e6210efb56eb074104fab18593cd6d2a5965f41551e68f58028e3e894bf2e1f7d446060ffe05e1b0f9b533eebdcdb990ba017c195600eaf5a8fed6e5b9c7224eeca6bb1709e5384d5888e3062474e250a313620aebae3ea994a573545438c654e02fe2f10e45a882d9e102843f3bccb874af2232c4392064c3d7c04f4247f261e46e02a5d06e1d0718032dc66d9731f64be92048ee8036cef2fccc791e74ba5f5f7d947639dac1542ca285a132bfea42703d1443484a29ffc95588b2d5a9d69e06b41c18da14f30a41a3d54b62e721af55d66b8165642118e8a6f3940cfb824d704d780169ef180f09e4e41f2f4ce047e3e43dc5c0ca188a19dd15d8df3cb961257c7cf1ffd0e2e02f1dc900e6be2bb7aa00df383466f6e88aabbe754fe36c6fba0c1d8269638c8ef9d35b3420a4f1c21dea9ead37bd4cabb7047514daa79a8236bcb6a72b5f5eb53f7f3bfbbae2802d9ce42b400218977e5a131143647a98df92d55e2f1e525d2e3f69032e8a8ea5b6b5f10d828cdd714b71cde5dc9d28e057601c6d28e25b8b419dddb0a700f4b0084124e8ddeb5c817d870af94463e3ab1812eba0e9cec28338cb3a9c96656584dba68acfba5491634805a4115d8de0e78209dd030763e79f2e53eb62e015569d4f8ab502481bd1af76710063a393f304efca882523b5aa34320dca0089b4311a71b7f41c6329ab96b43260007c4e039409b98ac0a0cfaa231c40437e8e1eec202bd04a637c980e447e5cbde0aa0560da52bfff0e40e35a7e63267648eb51b46c51ce03e42190b8a7760fd40a9fa87acb89f96c346b3c01897871adee1be6c551213611c97536cd080cbd0290b2449eb0a928488af55671f476217e324ed15e0052c605dcdc2bcd8cbb5606d85e9123cf683a806c26675e8b7dbeceb6b9cf3f6e5d65467ffaacdc5c41cfb26e7194ddc895ab02c444da282de3fcc2111b0980649a141e1592f12004f43df29baaae0da25bdd80d127dc451d4b20fa829095b12980736c2abc356dd5188b514dbe7e6c0bdde52b220eeda023702cc8887d181a5543f2766358aef5f12845ba7cd644ef6c5410c111efbadfd0593fa4c6ec8116600aca7dae239a6518c64695cbc85e9333ceb65943aa10d4fa7d13a2594d19c5e7557ef68198b16774534e4fe4bf9411ba69db71c45d7139a4459dafce10a9a70acb72d97920e6fec00d8307afd91aa372ad53031bc157298505675d39ad33d4bfb6091cf97577b758db261bab3c24c01fc267117afe92c291dd36fb9318cd7b4627578866e446731885bba1714ac3c634f5c4c33d18dc33dbd9d0289767d514c9cc13b06ba59bd5c71bfc3ff825edb519e1c7250749298d876dca8b4811872ae595c32516147259a4e41767a3ab56f456027a523810e1fe2b23027d60efaef1bc2834a11e8b67dc380078506f0fb2559c017f92d05ff3af6b1cdcc6e71b2babf92a9706ebc6c533783aeba39e5067ec9a63b0e977e844749e4ac2042289ba65148ef3676c209735e61f43f98a334d655c45fc0bab60a1d306ce30210dfd530c67bac1684ce4533ea78e009411e5d59889a0dd0b0f000c5c3743ae84a6931ee0c9f3e70420a3fb92247b289815fc72e80b61b85441df801fae105ac0351dfeea1b354a0b0ae11eb8ce0e984fceeca565ea49b1182662436518d470bad36c58c8d4dcccc8983c71b004aa4ca2c60d79a3900ebc0e4e045fe297ae351068c1c6928a86005cbf7fbbacd6c13c28cf83e0fd92470770ab97a8e969bee41213f3ef58ec1af940bb89c747d160d630877ab4eaba281f763767ad41e7984d2c0cd70262f207f38d06a59d94efa14adbbb064acb0a0ef31215c2b48784cc8b14ff56a189353f8b531675399b0fac2bf20cd0116ab39a622c50bfe523d2b7ed9235786859a64b61eccc6ae64b29d3f417482898bf20dd3034a5830fe5b1890d0d3e3e36408aeaf07e3ea8b4d9e3b457f0c8cb02baaf427e052184e56800b0925fd353e85f580214b3c34f7245ab02ad0254d3c5d4419601585059b63ee4ad415a5a67bcd4fa9e359a50cd8684d9a88f7cc8f4e8fb47808cb844c795c30adf47c92e9b673783fece29d786d9463cdeed576540455bbb0273f9d5187d874a967e29f806dc4eafaadb0083f7c953b25fb604111ce09c52ec0b3086c41d2f7869fac45a11c64ab85b793cc6d40ebc2bb1560b1811bd391452b71007b302f51fb91927dce579d5d2b2be9d5a8d48867b2a97383ff1f5497560b69a4c412c4e82a4f41d1c889bb4071253a6e7af7299ad802eae73e13e7c0f07092cc1b5a02e25d87c08be4cde913d29b915e23a2b8b392320fbb3f037a6c1f5ad8f4221e19a558828232d12b64da44a2e9144a04ac101a6b56bc0fbe45ce03019d67ac06b1313042abc41c505c19213ade6399036079f75935443e6679cf48aa014c37bc58e3c20d3124efbbb07e278ff1dda74e394755577d2692acc9cbbc546094a29f2d975576cd5e9878cf66f18b3893e1d0d4e308370155c176849f61648c38cdb138fe85088793350a461ec4159414329b90a730ed2937ffd665135f7a88a293f25435f2f16a2190d2a2b05b5e4f8ae44a0025be18d4c694058fda9c1e9dca458819bc83616bf7fa43f84ab6133a56cfdca3e0016efe09533ed71ec263cfcc639a1340a24f40c2a024148f55eac9b67a6716d0307ee8fbd677f8cba43ca0d6e27d38456f148241bff58eff0d800a56afc128ac5366c8fbc12809413ac43e5953549657a1e8b7d104e692f64c2b63230e55ff21bc2f59294d137792911383710d113bd6a33b211a8fd26485a85a1d49d34442f57ea9228afe1dc6ff1aae3e64f1c791039549ceee4817fce47550dab99924b170145ff92be7539c83fa382f68a4ae08c0143f6f2d1aaf35d989a99b58b83d439c78ae8a486e2d85c3b0af38aca55fc5742a67ecc1d3138e7cf8c7b3507e4b4d91dfce24d21d40e7f52555e889d88659e4b39019eeaf770d19b6a0f690f19da7143f45360269008c05b73c83c1fa8fcf4ef17814e02f31d919a59a0f6d781e9d195bd8f6d41ca3848143989c39b4b512a67cbf1cffbed0c068837a8797f3b86dc00c95c2c8f75df490d1ad7e280685b9e05231445a2e06f2858a51a591644ca1206795de0f341b9ae470ff0be1376434a6d4a6243baedc649a848d86cef6c434471df7c044e3b16318e6bfa757fe5238231e92fe76c2f2fb0596cc477a93e1c948d81c59cb36b4e938aed67c8d0838d030151fe47aa142f1ed1f9036a71346bb5c81865fa5285d4fc02078f8c9aa55ab1cbf55222357e99e207edd4e3cfc948387f834108ce6c994b4bcf60e3fa4ded128651b9029a23c02cd7cadefecade2ab7634611ed54dad3fe37a1c73e505b58cf22a5081939e2bf89dce51095538cb868a83b5261388b4f2c25f561ead4b830489d0974e652b6fab41b1d9626bae23a8b54a9fa75f6765a3668eb2064c987a3f8622f4321b9c32e9b2ba3a779c53e1288cccbd8387f7e99bf35ddd18de7e3bc39a08ada7535c9bcb398acc2afd4772acd768ed65af86362bfc22920f4d1a0b6554587794a4b8c0db639c20ba825f2b64ee3f295cc01a260a3cc7c0b33027c57af104cc28a3347cbd9d88f64f8652eb58cbe313bb47691b36f44b89d949a7dfba146d588866f996ea16839b42fe36540682d296f11860b3fdbfc65968eaa0050f1de2e3643101367ebc81d041981734d8107b4d21fa079e5eab3ff75779fbe79a72ff683a836d67e71178b0e950328e0461190f01d630fdb910a94242b7136e5cac4153a20595dd81dd81536a1c5a3d057ec28c6fea56b1735fe4da6c21afcf6c03dade23d876bacec84cfba59c93d0c1919e265d2fdca42cb859732b2d6ecad94905b122874aef15fcadd7f2533ac9977e8533595c420201255cb48f12401df32fc23eed272091fdc238e13f11e63ef40cb6eafd274ac0e4fafb58334b11a513384f55f319a4da2b72f2357ef4231d32672ca7db26a1779f41058e7b560f395cd3b08e03af44e52420a5bd7e50bb42465b2ca61fba2be8fc41ea9f850615b8334039ba0d9943111b9c8ffc8b0757487ddeba82621fd822e744814b1d284af522d07bc4ecc1b6fc2a81f5b6186faee6b7b26614efa8d50d9abf4b0826870a6c0a0dccd04250ebe4894d0885dd016a14e3813640b224c301ffffffffffffff7ffa34a135f25b6bfd97342b9394c9eb1042c80351899a524a29c9b411deb60b38ed33dae7731e736503f007fd07f0073976e09898250cd6e45f3595942827469283cb2a61fe4b2ed2b47d96cc8f950f4a185427cd30f1499330eea9bf96bb25616ed23b7964d99349dff148183d4d58ca5b964ab18584f1ab3e6985a7cfa3d44718b4fce80e5b31cd74e808f3c81d2765115ad2524a234c4af4ca7f35298c30cd68e905cf13aad76411e67c5f9d1292c621434704629820026de34b383031117c28c24c7eb2dc7ab5854a279e088393443e29ba8fe7d78d0893268ede878ae95fba3c8439da6527c5f925bb101ac254426c096542ff2d90c247218c9f4cdcc7b4788d46c107218cff7b42dc3e5f5ac9fe63100665aa4db75269b9e42447181f823093427f6c2793321b25af0331f01108f305e9e4adf8031046d9ccbf12f19e432c33148b041f7f309ced28277b503a3f97810f3f98f72f8c85061f7d303a29933c57b056f1bd3c3c0a1fcca322162c3da5f7f0f76078d28926adc6fda187908f3c98f32fa9924fef1727938f5aef64ddeb2875d8f81a607c0b70803c3cd0a392de01868747dbf8929651253a7084e1e30ee67c275b7a8e5ef1a5cc31020f0f1d253770d420d1c2871d8cb5277e4159ba0ee67ea2f93d39cfe9d3930ee6f89979512a3707e3c5bf28b38f4d12138d1b386a74498c02830f3998635fefd88b6e1d8b1e1b3b401007a39b4a169fa0a3e8e71e0ee6cfd1267f3a99e49ee26f30c5b59ed72cb55297fb70835d99f064c287bc39b19b14ff7a545cd30cad4929d181e3a30da67a0be99ee7375f84d86052f5d6afc13cbab23399d8aa1acc49e876f4b84eb6cbb934983d47d869db4ccb958206933221fcd52c65f45f1f6730f80571177ba26433d4147c98c160954e567573721c4dce97c1b44df8caf972109b63213298ddb5b27fd410baf79d8483c918cc61a7de3194924f1ee4430c66a27a4e719486b0977747180cca42ff4ec55e8f4d4bda06c602ab52313ec06054ad9d13174f85b2ff0be62a21b7a255929594dc0b469395b23349ba8678b25d30777062856cb298ee8b5c30a7a5b2ecf2799e4c740ba6584aa830fbea430b8653a70976c1c7496eda2c18ce53ce973269fbc082d12d09afb0fdceeb64031f57e0c94d26132dc54aaf604a849ba913e3f549193eac60d2e4fbb48e9fffebe68f2a98ce4f890b0d9f0ac6ce57d9779c6c6117e2008de0630ae6ecd044277dd89c8c15811821c8418344c70e9cf1210533b9744e27e7f87978b48e46f6110573caaa8a159bb06aaaeb07148c5a27579553934e6fabfc7882297f4851719db0b93f7282b1fe936882ee4d3067929893448acc04f3a528d3a53655cdcd8f259882d0ed41acc9d54be58712cce139bdc8137e1b2460d83059818f2498e3b467f2769e90904853e61fc1a4b3274b2ada82b21c8d600a22cfde4b3db4ae2b82f13a077b920aff213b2382d94d5367ffb35b5296cee06308a6a0b29e941d132d27b711c687100c722c7c3a416882e8cf098271646ae51c9df3eb1608a62725eb18c2cc1f183e3c65898fbdcdd43e7c6054ef131572dac337a95e98edd265529e52b1ef9ac4e0854e122d9692aa27382c89b18bcaabdd82663a51ced2d53aa6cfc72b8b67fe6e0d62e8c2d41d1bd2ab64a5d928170653a1f9243d2d9e931c17a6601746e7954f1556be852956968593ce49a7494a5b98b329e5977d2ba5fd945a1874a7e81d7ef6094f9a16e69c4a3bc94961c5988559465a13439309ca529a922c4cf23d747c79e795a5c4c29cf284a66558b0303929ac56b87ad4515f61d8d27092324bc9e10aa3cac7f5ad145779f956983ee4f43f4169e2936fc40ac3a754dd72175f85513d7aeace255561ac389fa272e852617691a24dc7d250610a51ba263244f9a9e8290ce395495f42d5988eab29cc49779ccb3ab914e6b097b3e777fac7635298fb64bf7638f95198c3cb5a26c8b34e37b6288cdb3d4aa87c5ed77b098551fffa3241f5579cac4061aa72e257bc6fddd7ed136692e67f78edbc12be27cc3984260951f5e9c42427558f8e5c9013a6d839c59c8c534d765236516d5e3269c2b4a63f0895e307f95f264ce12c2d634bac56121366529eda269c6e5dd0b984e1469acfa994b584399db23c263c5dc6ab84d15fffe456987b113e250cca9de09e2bd23de74cc2202fc9dbdd4bd1bcaa8d430c4998ab35bdb37365b3120993f6d5760aae215a48984a998fb0a0ba7ea1f208d33de1dc54bc5787e51c61d2509d63c51a617673ad32df50e1c933234c5ba6e67413bd43a89563116627cceff75beed1a6e71b6228c2e8245941c8d22c11a6278c3f296d68275d767220c29cd642d3629d7cc70f61fc4c4ee641dfd907991ba227939ba0bb2146210ce7c426eaa526b667524908f33751c4bee5493aab671026cbd957b71db21c6208c2f4dd39fad91408935dec3365593ccd27e52106204cb5174d54bef6076393af3fcfa9ae4a262f691d326c1431fc60ca7227950c7542cbbf1c36488a2662f4c1e864f213efdfe4d786187c301347769e0acf244d56cf1e4ce617ab2b88a6b68f33b44a5c0f267922439cff563fd1646b889107b37fa8b05349c66788810733b9b2ea771364094bcf1dcce4317731dd29fc4f66886107833e99a4b4882e5d4e6c92861875306efda8345fe252430c3a187493723e39e756c937e98d18733085712ff79e73521f430e8d5f104d4edb61f6371ec488c3e7d7e4ac71bdee2def20061c0aaaf19ea6ae29f7be63a71cc4788371ff9da4fd6458f253224133aa5e10c30da64b5d499eb4e6478c36986bcfc9cb28c60693bacba4cc75cba40bf78d636307088e060b62acc16c9915d6d6538b1c251a396c740c35989af0f1b5279a287fe93418f5743671f19eea25666704d34953b9dd30af2c7a110ce263fe6e857e709313c1f024a593ee9c6af599fc10cc163461dbec444da542308ff4f8826090e5c4135294f67b2605046385fc5d6b27a9f041e907e654f9ed397b93101f98b45dd2a71e1fe572d40b7326fb5589ec6a52fac50b73b0d2a374126b17c67d824a4d1ed3a75312d285f973a5eef3cb240bca85e1e47eef52789727888307c185a976d6defedfb546790b9395d88da56d491142105bf461c3a2c6c70f482d0c62f103420b734aeb848b1aba924e3190591c94ed8599034416c626ff5a760cdbef0e6b2ccc7e16efc9233ae9a8720b6c80c0c26449a91c26df9a589dbdc2a42af5b409d9e4d24e7c869682b8c2a4fdcd3a3fe93497439f020f0f6d85b9f4b9ecec788bc8158415a6daf69b4b3a3b9920016415e6d8a59e684fd6f40a621a376ea840478e0d80a8c2a0d2badffdf44959eb5d01482a4cbe9f9e4c36f984bb2768415061ded2a4ca377f829cc27c227734b1b45a4ae2648aadf72b8f1069e1498d088080051198cc002985599f2c76b1c6c25b6e02420ae36f3859e4e41e85e962dce2c9a4abe0e4a0280c6a9bacf5e4bb84c2a84e1c195dbb1f942636430bc70d192537781b1e1e3c0410501846cc7e4e6521ff1b7b78207fc2dc643f158f1d8f279d38ee880088274c25c4fea710af53d1f7f02001e9c4272a37c2f15f021c374a3ee0e1a1230c07010b223051104e58b13ca77db21f860e1c358c874701d984c1da4767cb24d50c2dbc0088260c4a6bdbb47c0e62d6b5004826cc66f304995d39af0a08260cf2429bca4ece7965f497307c924dada4479630df6582e8d0619e83852a618aebbb998fa5a64e4d0983a786b7febb1345d59330a8f8ecca9d2309537abc2fedd93ca71147c2dc1e6fad73362f1e8584296e8926a9c71357531f614abac9a2ab9d3ac29445aa77cc51f755c946982fe4e2c77f927b52414698eec5c63a8a6e1106952fe81e6da1e9a75284d9e48b4a8f66224cd799d664729576f2208830ab9690f31ad3e4d49970090e1c3cc821cac310ee8e9027c693c92415c294a3e2c513abbf840a2284f962c9b020db33394c833067dd2c131d178449a9b439fd5cb14b3d81a8b28687656b6b93da2d3c3649d5439303020853ca97e1a92d6f932dfe07e39f4e5f1f762e57a709c40f06916ee9828edd07637bdd3551d5e7d3a7207c305a780abde7953d1856f53cda27e9c11ccbd45bf2501ecce46c4dfcbe54513e8e07538a7ca2853ea57348ef60ceba3ea376513ba47d46a57ff6b30ec651e7c43eb399ed9ca48349a7b727d149ee8e8573309fd41c3fcb5962343939184eadbbd3a655d5938a8379a4c685cf1dda46650207532525d79aa103f206738a93b5e4b4d9e5f080b8c14c30ddce7a1f7384655904a40d46d7d0b9beb5e2746e206c305dee797e07f5416d63878c1bdc2801c30a640de670e298699c1a0f440d6652b2d06995d60cad054983b145c87a94dd7c3747190b40d06050314b7a52bdd5a49765e8f81c7c06a3573699eb9719cc9f9df4f29f2f85d2ac0ce6ac5d2d42d52d6430dd298be1a44c0a640cbb134bd74a868e8d1d690222069377888925b5d42031903078af63eb991cc62a0a020653b75baad1dbd6a472240d4eebc8812a00f98249ef6f96fcca965e421b3b40809e0689870718205e30c9d0e426294dd66cad2c8e3ec1a31b1e501c5d633500d20573d22675cc2f2596f9ff8edf41a36d00c20583da8792a23b09a900b28504d18229ed56747a502a77873702902c18943931a47d3a2d730f160c42eacdd78b9630a15fc1204e8d52f7575bc12094bddb557b161173150c9af3c4dc6e725430585acc986765b3b0a66026fb6982b6f448c198ae63714393e2e7730212056345d7ae5239f788930908144c9aec8453d70bc8138c17aafd53d2f63b764f0e88130c5a26d29f9c63a709f197a009c6d972cbd3a74295d85e238c16848030c12446dcb8934d678909812cc1e42f6ef7e4787d273e102518cc4a75b839f33c228224c1e075a1d9bf96dc90a1e3c128751e004182e93d64788abd6ee7e11a39486ac83882418fd2237253540cc40836a9b46856865b65408a60b8f3daab4c6a7fb53c11cc494598fe709d2198ee4923dab34ad54d2118bfb3c3ed5e360866827ccdce410504c3e628391a1ea37226fa0383f44cf8ed9f1df57081f8c074dbe9dec43aa1c0053274f0d10b636cefe9fa25cf91f3c2f0c4ed8fb5ce7d36271b25af034b74e0f8d885c9458ac8588cb85dec4317e654179a19c2c711868e5c98f4652d4f2afaba8b7e86a60a3e7061f2b83619376e996c3921f0f0d0b2c2c72d4c7aeb532eed6d6126bd79fa9c47b530c9316d13f16499770f2d0cd764b3d1667d7e41b330d9d8a5265cce75d26a599893c5aad1f85c2c8c9e1f7294586161f49c3e7fd05e61509f838ab993c3a8982350c3872b8c77b1f494ecf4339f451c3bd07f000dc70ef4084bf0d10a83ad8a13ee73c40a83265f8c4a8bcf49e56bf2b10a83e78efa87c71faa307a48ef981db4497da4c2d8aa21dd7a0e7ca0c24c6ef7b8d697b68ede514306968f5318540e63af152ba63007f9f04f12e59051eca314a63bf124ad9d7639763929a43089d2d36d7175b59ad40cadfa188561feaab65be4661fa230acbbcba894217c5426a13079320b77efe9fb0085c9e2c9b373d77f7cc2fcaa9bee1e3cae92b7616304ef09d3e6e5d19379720925cfd042a897c6ef00c1617d74c26ce294b251ff99e08313a79c77150b3e3661fea4266fa24cfe5b651f9a30cfd6a69ee8642a238e1a3b68fc8e64343e32610c4bf2ce3349e7bca5820993f0949aa2779d60c9cec1dbb81b1f97303769abad3d8a74d2c74b5cc68cfd574e6a3c98b3cdcf88cfa9b9e5b983c954de10aa74697ce77630e93e49494f6983d13a8a0422753069f687fca09efb21a283e9897df37db949ad962c7330ab7cb6243f32ed3f9c72308ff9a730f349170753f6add2e4a0ab2fb3fc1c56703096dc557f2713576523f206d37c689dabbd28e286422cc9b8e75fa40d66a2bbc8afd68a0d0675a9db1b525e83416c9d3c49094f5795974488a8c1b8374ae92c31a72e935384481a4ca59bd8263e56d3bd8406833c29cc4942fb322b7b06834ea9c309e2213398a3bcdd24988b102983d9499e83125533a3c3981e1e8c10218329e685a9269354434b37920d226330d5fa5c133c9b4a58f02568101183c12c8552d154670d4d4cc60d1d32ca4044c2604e6a9f7a7410a6f35b748440040c77f01cd474ab61d010f9822594477372525e5b8978c14c6e53fa592ab63bc55d303ef93cff89b295f425225c308d7fa66578ab9e225b30eb6593a3c92928952d2f02112da4c694f4363d18225930c9b3f3e464b3b7dcde0c2d76810816cc992c5bb9b3a71e9457c042dc2b68134ed3924effc40e6e298e03075f03112b18ada4bec85c9c3e99f0a46a05225530e71125f737945ca96fa31f471831f80422543097b692729a9c9ca1952122533057e567d9273d29139182d99314274527890b3ac777e4909183c4ec718411635231108982b1669d78fda4344fda9645a06054311daaac45cd5e7a6603912718b47a4d7ece5a4c9d818813b4eb64a13b2803a1c67a1dada3051eb8928148134ceb5677ea3c452d8b9860cc6bddcede97603e7da57ea7b3124c41781e9b1162e5c43709261564797aa51ee5e92221f5ea4d70ffff08262da3c995a6f2a4c58d6038bd9b714a4487b754a40866d3fd673ace4304639db470a2323d77dc43306978c976f8931f5b158251d48868a2a717cb490d82d1f275888e2d104c39754eb272c2c64e3f30a94cd2ef3eb788f8c0749a4cd47de2a6da1364bdd894dd67bc30a918e2099f9da4ecff5d18ae820c6922d685c9e4133febad492e8a15b4cb49299b5536374b2542362dd8675d500ac1854144fc93f2a6760bc35d9021dfd90ab185a972ad9afdb5c81cbd16a6164fe1c9ad4f6861fefc1af9d1ad2e932e2d2984ccc2acffa549a2d53d7f9e4a646190a39e09e2723362613c5195b7af950d6061aaa0a6beab5a1b4de315e6ce9b1521cf5cc6b3ef0a73c86b93491d74425a610a0bcfa77295924e9e4358610eb5b467972b8bd8d32a4cf9940edf164b1506add0991c3abe62fa940a93a5080ff3fa0415066d5ad5c132f944a82760d82041fd3426760a3329e9beb0dd49a6602cc558f0b21406534efcf8c4d1fdea9d355298cf4c97127d9e4e2b360ab38e9e4e2a3a9ba34433b44ac911234414061d4c3f9e2a8fd3d29384a23c484061b64cfcd427ccf2d9ff467f46831c5782104f98d73b67a56c36338341e232b23a511e3b423861babb70a3e499df9c3b5010b20983273fcba7a255dab866688926cca42795ccfbcb65c2ef195aa53e4232610a4adbd56552a55a10820953268fe954f1b493c9a5d391a38424a95dc298963ddb2747674b7a53418825fccc7d929a1475a98449737b4d98e84fab9e12a6a0a79aec415c26934627641255e5b5dcaece089184e9635dac736c9343cb21910881048e904714ac64d53c768e48b52a7c9441c082084c6a0c218d40e40963c943d4c21b8430e2547a7a4a3f8e1661d0049fb7b0344a5dabe34388224cb1b477322df1ca75fb21241106a1a35a7e8acad9f9094184c9ce5fdf4a8e420e610ae65afe1ae214628884a7ca6af9e9420a610e69b12bcb95bc2446a5648410c22064986c5265d86e3b091984f9e48a4e79eb2308f3a85ce72935614f350f0984399ef6f9967c324908350410a6278dd68b172a64ff19f207936a7229d395e3ac4927217e289aa76c09e98399244649ef772f870e92103e98d3e9dabc89ef3bf10cd98329a91e214c78bbc77b3c3c42f460b20aadb69ce241b7290fe6273fd9ef2b45557830c8d123f66694d8adf30ec6bdfdb0735247ce9cec60eeff36b91e3d4b74ae0e2627d88c3da993f264692b74302721bf532a4bf99994399853d4f5706a9d98a344fa613a0991834943c9cba4a0d2839038144bf96a9d9389d5e443e090897a8913adad9a4c7815599b1bf5b043de600abfabcf6462763e294e83738346073c3c3c3cdc604ead22e4ff7eb8073fa40d66ed1136571d4ecfea216c30e7d80a95897aa6c4440c598341f698a79927e5a4846a84a8c1957d9f374b3ec70762012142d2600cdb7472ce41ba25b55486a0c1f033a245763a41fea83c3c72849cc1e864723839f89384c793ddfa1a5d02021a37acca0931034fbcb98f4f587f86868494e1784929d91d0a2183ca20640c9d922eaa9cd497c37a319854d4fe7a0eb92c310a83f93b6927ad9ad244d91c0c46370bca7cb352e669bf903759649b2cc23a5eb0642e4527d5a814f477d8893d83902e98730e15dcbd54d87a950b26e57fda54c772cb6a6ec174f2a7db9ff469c128a3ed4be4933b55c9b26078396d728aa3bb52a72158303a999c646e3ffc68db67683d0d121c356e9c0cb98271bef275ce79d2e5396e608558c1a4f45d7253136af1d32155308710cf349dba4593be12428520844cc13866e9ab3c93acf70e91c26e95dd2d13bde472a5b206215130a8b027a726c9d11bc20405739e7975cb333ec16c96a2dde673955525c40946279fdbfc8dcf69f216d2048313fdcbea5326a7723d9960b61fd59567434b30878fc65e3d41436dad04c3a8edb26de2eb133c179204638acc77b75af4ee0c0946d73c274527e98e603c27cc686aca68bd01132845812a0a149b1804f864293fab0420f080a323c78e120200200ca7007a05002047c99f1de846090e04642007098e564000bef00500bef8e28b007c0100057cf1c517097874c30605f6d10d1b0c58407e9123877b0c2000ada391070100d03a1add28f130c017027000024a5e868c057c0180061820a11b351201464a81801152988490f91ff4d5da3dd119ba563bac6a7c890c1b902019e8734042a3b974d82029a33098af25f53a950d1251241c748d4480915018540e9af5261eb2dd241d0e1a14a6cf162bdd767c865a3e619cad78f2fdcf2a5a269e30ba095b4b272e7aca271c742770d035d2004638811a252d279d4f6e86166ec2aca1c64b64132c13e41bd1442670d4389838c0c825920d921a8900239630cd9bd2a4cec1d29ce499a16583a446ba4ae8f81c9430e58faab74e26fa67f208dd403726611a4df65dd166abe51e124918f43a3e49558a87e52092489854d2f8ec71a4070933d1aac9379e620b32f208a30915d5a498d7763b99a165e311c90d64dc28f91c4c44e008638a92abbefa1f94c88d30882d7d32c13f8898a530c2a48267cbd3f9215984d92e93634b3c0729f22bc2284faca4a9602411a64cb2fcdd5e174f71977183c6a41061f4a042a8caa3c28a10676891cc3884398dfa5229cd42ce89867d60071ac2d41eb4c8568e92bc60a410664b425818d7905e4f0e0921cc4dd8ceafa5332ac9c0b041622e181984b954e99eac934593443348c0b841a36a041e1e3a6c9078785cee1819110402460261123b9a9eb37b76d490216369eca8512e30020853503b2154ab49c98c1c34fe6036b9365a65331a3372b40c198c3a6c90143f18455cf2fd269c3ef74e1f4c41bdd6ff99c90793dce668a9783905698eeca100237a307fe9f0bc2fe3a9f135b2c6d72838920774a3461ac0081e1030720773db79bc1c251c748d841b18b183739f732c53ba43376ad4c15ce969cac73359ad3399a1554874d88004ed9021836d4082769c0e1b242503237430098ff3149a183ac4e86668a11b35d2d570121a374347d7b81c36487494d41cde06376ad4f81a061891830d921a6900237170d43649b457d96c83113818f4ea625466da36e91a7f829137183e4ef7895935216438e206731cabe87ae9c996f536184b545bf2f01cb74b618329965fa7bbe0e14d6e32b206f38dae8fb4f4642765bc8211351ce3adf172619e944d83498ace7e2eea1e4183f1ee5326c5ec949133981976a40ce51183113218bce52c6793f289b87c640ce8d0e3229fd4253118f7f53df6e73e0cc696afeff8a9835efe80c1a4355ec109f317cc29c57ac2e587c74dbd60723231dd2b75ceb145ee85912e98f742c713b1917ea9e582419ed2955e196ec19c4fc8ce7527abf7b560d80bd2b342280be6399977ea4713f5f5c382e949d2ae2c6c648a7a57301376bbc4097fb1824954eb3bb1c5c9a3d62a18f7b4f63b399cd73da9112a98b44254905bd92ecb3a3285bdab32a99ce0c4ca66b315f3c9f132e1b45446a460bc7c167e844e14cca1cf6edecad2f775281866b4826523187982a977b54e992537261546890e1b660b47d72838bac68d38c11c4b295596ea6b4bcc4d305ef026675cceed24d5986018d9613ef4258b638e2cc19ce6e7254e332f9b4909067992e94ab9e7932a79128c659f4f3d8e96b45123c1244327ed1e3b93438716e373a49482193a4842ac0b234730b6fe887b8225a52c094b0a2346305ee7b1ef687af17cb5b2e38c14c16841bbd3b509d6e1151154d919a5452d139089134686604a67224d295d91f52a1839c0681dc7871121988957b34dd250212f7e8e04c44810cc4d329de4c6c977102340307a9eda5d751959f9532a88911f9853f4543fb969971c8df8c0bce324dd8a39533a36484a0046c7c824d20b83d22769d2558cbdcc92082f4cb2a4857661f414f37d415fb4ecd3e308238642414417a6b2b8a3acb39334e1d2f904915c98ca429d7cb77bd1c964bf440922b830e65afc97270951297d1d256210b985b9af4aed8465824eb54ea220620b93fa9cdbfbc535412dcce5c1c3892f61211f4f4c841606e59df3442d798d11733c185a61a01b1d0081d5a31be77294bcc82c8cb36d692544eb74d095708044071844646192aed5974e26c75167aa1a374a4090a34462617e82369920df09c2c230a3969f53dedbb77a85f9fabc4baed4a56be80a8326986c15a1e7259fd20ae3c53949c9ef977e78c20ad33a39f8ab3013dbd4d3924915a62608f56517ba54184f05ebfaad0b2acca1d23dbd07f5290ce741d46735495d0e2553983d5774d6c9d1eb33e1195a341eb105444a61f63461eeb1094f343549610ed50a4d7a273d0a739890f92cbbf5bb9ca701860d921c55a23098ef8a683b1df29960284c957fc3d7ff4afa45416110f65953bdcbb2fdfb09933e4fa55eb39f7f164f9834e1c2ef2d77891dbf13a6d12feddc173dc5573961164bcbedf92d62e1a32bb209530711a22c899d1910d184d1bcf7e2c856acdf990963c8a72bd1be79fb1c4c18befff209b54d27aa7d0983699c18a589a7537c690973506fb17d7426a8582b6156cf6fd761dd9ed41d2526a53e1591494c0c0bb2152e57a5f0a45c166e84874806114998ce32d9b4570a8a8461cd46a53521523d2c2290c874e377cf8310451e61f0cb12f92907a9d9d90d8838c2ec77aaa72f9fe104954823cca4dcf1dc246933627182d0f3cb96e261f409b84e49974598d355b827134d13114518c3e4ff8456279208731899baa283cea9ef66b4e0901c41041126d1912fa2a487cf27e7100627da0919c2703a9ef9a517c2206493fe74f4480883b4f439228330874e8bd541dd8dfaac88204cb25354a892539db32d120893b68aef977544fe692280309a14d7dbacf8d7a72b1c10f98369d5538e1674f89349253f18f4c927d70793b03315e59eb6f393f860ce5fd154fe51eec1f0417dcaf478e3646f570f06137621339753ba7e8802913c9889237454b701892fa8146e66c3026130168a04027118c4b0f4f200c3120000000c28134762d17838a467ba1c1f140004774e2e4c302c28220a04029148200885c280301818060302a1500042622408d2a575921f0cb07cb6f03f3f3b27a1afc3f4563941e87c201edc1fb8a20bb45b484349d10bca47c02bd14638252abbe83b3103e6a61cb3746ed0fe92ed943df2c83fe6e5e1f337b1c3eb24964a0a72641ddfa0c444ec52c2d314462e6e2005df7094567bf830c43a00f65263e46c0c5e8062c41c6b883e7c9d84283ec8aa227badb7a40630fa47f489c26e8a2961dcc1c4c6049b00b6bcb894569cad2be8714f449a6098c916373bc6e66c628bfc95370aad701ca613803d43a0ce55be1aacd1b5026c3dbc6bd12a9a689da5be71b15098afac20e84af5f560ad1b66e42c3402ef9304906710a319c8beae7f57c0495a1ea1265c1714939c5b8b32329bf0213cbcaf1834d808c082742effc46a491436439764c1a44d92bb85728aa8942f359c12bcfee33c99ce6eba22752642efc8b56fdcb5020841af12147b68e832c97418bf050ebe89536853ad2d4430025187c3a6f4883da28409151f0100fa8608b8da348419744c2aeec8d5cf1ced0b02a01304c1916f40491e2df2382253b7cf943026cfa99667bdd595523f6e12a1d4832232b9ee2ba82786817ffec4f50a0f935880d4cf890330882e33423fdec52ee4b27a550a7883ed1f5af8172d814f19fb16f2e3afb299b88d9a540ff7293d535270c0a19fe2cb2f910700a1d08f79a5ea3136f1734e1772ca8eff8353d64d46204eb96c688c12a8a79399200f1c82384891aa198eabcd5124a87f1ab517fd83d40c33785225973f16806dfa1b7e9810b260ee2050a3f4cef7efe56d987080d561d106f983465901b731138e27cd6e884564249069984819a2bd4639158c30ef4914994d13e5885e2c84d63585b072d86188e109c20ba65033b25e7cc444825561c5e0e68a72cb19a66f9c8b7fac188fec98ab54890c9403d80a7e5a3abff993fdd98283e9388b5b71dcdebcea6478b8e675d248632da408c6d7e14a6a409db9bb361d3239809c8490ecf4485413e70c174e17004b26f2b94f97b511fc07a74fd2b2a5e4a7a437d52872d0c4714e1ca6b66ecd452dd2b8e680d03b19ed60e370aa48141c3653dbead71265c14b77653163c8328659ff262a9f22aa67e6df4f643d717db979c72be2d3256d477d3259dc53118b3802caae92d892f4a11195f82f15c562cfe4f738246cd86165fdd230a0d78e8b36160d94d762cc7ace334381a63bccda31ace879c9104ea538a930b8fb3b43d48b720665e3501939d6b87ac608ae6d30ecae89c762b31687b3a60319c3b002508c31a8c87047a2171147bbc818c02e84b76ba1ce428a5e6eae10e26aeb1c25f0239ebd8c29874c4c5961d61f2006658f8e7fcad9ebcb316f466a09c609f8eaecfd945866245f26ee68bc75c7d305bdd003e0445f5e2b5fc11ec57198a9f0e643cd704ec415b0c16a02d7aa5e68b299b3eb5c076a5a735751329a9c4df71e63cb40cc59ce9b4e2d171c51fd14c6e255d1b240be08cfef9df8198a6449fe73424cd7a4f1ac1e4af1e8761ce7ad23863efa3674fd084d76b47341969dab1e9e4c7d76b5da64c1ecbfa78c7df9a128341c595aba8d0248dda3ae7562c9f0e46c879076026b64ad5c1b038df1942ee122e6fcc352249e60a04cbe5678328d47ab0222f191b2e09b88234f44bba90f249ed769c7738a227596bf51e59b0e5c22c47b606f1541af5d806f2851a454911aa548920a9e28b688e8f46123dddad6420f82ac6189ec517c299cb837f120477818589f208718f698680721c2afceadc351ca568d7757b87082da49440c274fd4bc3f9c5ce906b201ccc1f119468918a5b72686d853c16760d088737d66f17044bc9e26b45174a968884eb17933d25738cae97b57732eba6fd1930ef6ea0d9d1d406409e0d53a0037a05abb6db869e5ef066f9f52871a9f82ca1c4a08587424613be02b9a8962d0a29ad9a4181f0dad25471993ba6fb5fe1e510a65d468099984abca98ab79cdb052062d24b88af1e75e8d3d7546ef7338997ad40f1138857101c79f21e16a46d1344487ba12873b8bf59c7439f71d38c7fa958a677f581137f0f3853c96ca2f4bd884878f084c7dd1aebeac1379ed8b72dde2b272180e58d55cc6def9dd31c0dea93e13f2365e3eb28229171f1a27a4ebb8943a62415356020b0e8572323127c4e32404e92a49db1a448eaa60d55ea984129611a6739e2f293e21bc6ffaf247aa44ad5d190f4aaf4442f532e25e5a5f3edd47ea3ebdb1e66e3ce41f18a87f8d13c53873573f2a84ef2754605b28d47b665e6c16b663e46a7c270dd1ced9865a8f7c2330083b3de24618f45be6ec00eacab0432163620a6100d83e884931ababd89b527401ea2ab6901b3b89132ca5ac428cdacd3d2d0e07a35a36d39874f89d886231eaac1dc3878002a7a16a969ce089ea89a442efded310f2c72ef8704cc9ab5b5b2f4a46c33a64a4667594a25b931c04c1b145d64029afde488620435823e7a59cb10fb1715a2db6326170fab86e6ac0317e50f5c4410635bc628f4105a550d7345b1a6611a24d8dd660dc60ac270c17b864a66f12379d3b2bd3809bef624f108b2db6b208ae551daa19a64776a18ac9fc5d06f852f7566acbe406caa8cb1a1872781fb097c91307dfd514b46788f085d1a02bc8ed7edda06a195a716495653825a5d878af88526330c6ed2bf21d6e0c3dca3810139c5174bb6d8f6450218928ec102fa6cc52eb2698e49e8445b7b18ed4115f7dd9b88baee7c4565bd1ea3f314fc40a6379e3ae6eaf7849237f49b5187d88048e6741bc237cfa624a76fb521b1f7be409dc962826ba69697cb4bbb16efba367f6b8508076231c0b1a86328fd6912fc62df2c4bf330851d3e1efb8184df3c328d1551023154d805e0887e256cf8663bc841ab9f2117cff5ffd62dcb79b8025329c4dda94b3a6f589fcad295f12919e9a9ee8426315f2dd94b420ed17a58568e3704d9fc7ed73c0b96cf67d872b98796056e4a47475b000f54f11cd1d46fdf977f0ecd9df0052cb335b16d20526c6df7d104951e2507817d6b1ab10cbf99a0381b77bb023a04f648c03fcae26db6413ea6529a7536792b368e659a13d613c5547d4f3e624e53aee097206e62af4df158c1750507a26b5b99c9469f7157c6f4e52625e0dfa1a03e6efc3a0818352f0be7f31f707760df018333fe3a685aa38922182d39dc0d502a521ceb87e8ce633f73dbd75a69203459554f418190de036dd16e81b7fb0e603b8f90861262a1e96fe806328fd3ced328c0a80ece8da701b3815e7409b0ce4d76075b3fa856cf1bf94b21bab9cc0f984348d2f64dddfdc87319f03faa4909ca4415248cc1762ae59761c766235bd01a0c9e42063a804cdffc26f6c41cc62709fde2aeb630b7ce16cf6f685de7e6d182457f03ef8a48a0a5f5e854fc5b8b9c2c9d5acbf9211b08382658c4cd903f5b50bb5338602f43c809bb4c2f9324aa8ae4695bec0c8a6fc4231c795475735835ae747a83873442d6197c339f5d44907bbfed136d8755e8c87e31e9eec1c04c6e3e75389e7ca66dbcb57823e89804294cf0540d34c60eb380b67a13cbd85129722e446081b21319c2d8b8a7768227610b5a534f5fb2f2f2bc9c5cab7809e3a1800f67397cf7cf30a7667fae14d64006dbaa8f116238e60b62cd98aeacf85c2966d3cc9d967f55d3be512b61186d6abf6920474b2b77d4418c18ffe18e247e65c008366e9849d683d193fb99d27a19e15b88e27a2db44289ac9d6cfb5a5ea84a12278cbd9fe55556cb7d88bb2c6ccf5e334cd94e286e464f38c4585a52a5b4cfee914a193b2b97b1a916e625847756af47227a9fc55f2a90bc3c7a4eb07ecd9175034e2047d0a1309e7da7063ae3a9c28a252f0265c4bdaa59786d42abeb616dd4cacfd062cb9813c969c42988a93f33992438ba5d18c3ac7db00707d876be44744cc88a478e2a29222fcceacbc91ea5058de8772b0736783f3afb61670e30206e106ad12d312928dab56d385613295828786bbac0998109e28b8639517fccdc9b485cf701dcc683ec9b1c41646d62b15ea850aede50ad6ab2840e62885bdf5e1176cb564dba5f54c601fa8c22efacb843b47f896430394c74ca9013e04da7c5bac95f95cfff3c6145347961903835741d93f9aa5c147acc419bd416abc0be3a0f2fecd3ab57032ed567dc891d755d3c9e6e8ec25d2af1ce74a60167ddf0e1bea5bfd841d6b32d05483852061da4cff4b9b692f5b69b4d5944146c8e54f4a8f54e27ea87c6e1e02e2ca4294b996442570cb6a9ebe5f619ab223c417f23b34347a04acae1e071680976500cf3f401476e7d4baab01dc0abb5caedd13a8b59bbbdf287917b5e5a92356afa4a67211c378d36ffbe5e4f33dd077d1d1a925ec8441fa760b4247ea417786abd336b17c6659b2a9380c9ba7ab14d81df4410a9327091e52fac67664ddf50dda06da467e53d8dda209f68ad4ca2d8dc177659552430c420af809c90a5a76518b970361ad26f27dad8aa6bb340df1c92b384fcc5a2e5187f2920328528915b68e13dbe2d5e0858bb077847105ace93e405d367e7425c4d2e8ffcdc2738eff2dec288dcf86c1f527351c55e58dc774ea1e3e8452012572965e9428896b17270c6c1608e92f9b4edee7e793bc992a36923caba3c8a35e411bfad89d2a973636a71be7511f2895d3a518658da922d9810663920c1c7a5ccc6d529202a17f88b7740712b87ffdab9151f374fa8018e7e01e9af07b797780b329c3765aad3ed02f1963ef90aaab150286095c6fd31838aa6bbabcce54e89c66dc1d8e97012108a70d73be7dd6a80c27eb2c6daa1b1a780c0943ace62c60661a77de932068306fe5ee2005fc6af3f012812112815705492e61813079398b9944014780bd0d600b145483b166c81047e9b702338e541e3c16b8770594ac5f8d6bfa530c647a84a6caf288b280a72980ba91cc941d360083445a552ab5d25f7edbe004b10e85c66b4bea3733d7258c46d549cd66ba206b806fe421953bc5267af1538dfe3f124643fcde43b726634b04b34500487557870d36a4408d025e5b4abcb22abfdcbe5f86af40a22992ac320f9c23ac18617058cce6e29ecf1cd65c95c56f70eb21511ca6ef4500c2462799ec0e0c9c720b29209495ddb344c47c9476b7924cc4882bbce637050805d690bd2ec0fb7db0c6f58c2c800f92069f955c7b9923f567c00052afa0dce8cbf90f4e39bbc1220c817c33e22791821710511ec300308382e6951d3e33671235a46db735d71e68b592e8f79870e41da2dd0d87b751d5cb17c027a58458eabb68d98d4ff24d64cb99f5f63d36a559a7e81968155eb852c6bda8515b13d4f534ebc00c1158470ecde7358cb5b0b9db262a3f3223c8c32e9dc82c721a489263fd48b1c1894879f5005313681d0e65a41105ef05df94e107fa9dbad576b52f6e28eb32125378371722f0eef7b1dc5c28b9dd757fbc3ba34e294db8117bdf736c4b8864ab8421f334488871d248190e0f6e47681efdf7c066b454b83cd2a2dc2a974d24dcc477e417b54b48a6f3b407409c4098dbb898460db9e6128837a26b68127156952182ca763a8514cb60320756edbe281c7026d1d0e72be68a5a35b3acb72f25f74e03e06fd0f838f40c97aef57eea8e86986d7d04e00470a279c15f89d74bbd485e6af8b4a62013e91323e35df2898b49138850f84e384887775f048d5a03410a66298442514360ed06ad1d26104ecfd85bdc0ac868802f2c08aa5e945c9394607493657e499a8a2e716fed9a1cd800943078385392c8e6949a30a218e03ef7b3d8a1603a6b75dc201b81bbe9d003c48971a38414e65b389f5f6acd76ea938c10a56a2b2cdc2c9b2cddc4b2261c221d32072ad389407eafc43c8e0343874cdb84daa8a8911c4072782fabc6b8001ada9debdd44dc1934a7dd157bff8bb21d85a4112960f482872aba7bbeefcf898d8ae2ba12159e3b298c9ac6d5e3698053f8969701db4b29ee08c2fc4dc0076977d6ce49e48f9fcdaa0e470b8a249af43d1d2f5e61d8bd8d7fb5929c493f18a537e462d9f93f34bea72bea549c751c0884d31080a972c0ffd0c57610ba740194730e0a36a5b715d1ad4765e235128c57cc4a0c04cb43070c346bca829bb151d1e3a6dd70c7b5ac103231d54b23ac1f0d973aeabf23190744f350b62a97224d26b1e9f951edc592a63949b02053a51ed897503dd04b10c7ec8cf2528bbcf80acb2ca2f5f006e5ca0166bb7ae5717b6a7d33c3d15b078bc88b2f7e6fa294410ff516ea6a728340d1b683289a40e82cc2dbdaf329dac31901744d1494604ee9695dadb73d86352fc48c8ae2ef444084824f4e2e68b1091fc052230128528eadb1a9c3bb0a9be92eaf13f0ff10ac43642fdb17bb3ddffa6ff632d9378382a026ac0dc74cda2970536112d6515be2778c081658d61080e3cd6b84f3696c903e6dc32285a7fe3c7c559fb145584d6c403b77c8902f64ded87427281804a14fcf60920e852131107d1a6d05794718d22cea83f0b91ff49d880e6af1966b479785e2c7e4dc2702a75778e01990208d97df62e6e5c5ba8221660698cf6aca9121219ed3a68e97801ad37e44f64c30b080a264a2fe7be5576c689e54a13e18129257de081b1e1885030bf450fb1b11105c3ab860c38672b88376f18abf03440c61bd1e3d83c363c706d761b966ae40845879384b447ab2f5a317fbaa64f14e608027bc6a1786dc784aa58a9f5c59fc9da3463ed45ac6ddcacdbf1f999ed09924fa60bd16dc447f6a73a9b58c6105ba59bef8aa74c90a38b8961ee8c7b55b262b1b841f36e3ec9b95d3d395853a815af2b22c436c676bc3147766bbaa4dbb487cbce8dd348e263bdbafaa86eb6007c23e1c921d9f3ba14c09907bff9f15c24ed4bbbee7f077bc01c1811f067f54905e9cd4787ab4fc92046a15c92c69891dc228ca2e017fe89bdc8db39df19bb3ac73b907b622a31c35676d6cc936559771252cb3f0d866d05271018d7dd8872842699ebfedc39d73685c132847cdc1a1f0298a2d1aa7336d6047e78c72f7699b17ee970988e3699b73640949bd6d739466b6db827137fc6b6a1a1124606cb939c3bfdf1aabba3e61c5dd8fe0af6b695bcf26afafabdc8849f565015908255ae018a28b9830340e8fb5c6261caf8a966785a816c00beac345fa45106dcbde934a9eff6921a5baac46aeb4e789d8b8df27e690e699ea21e89b3ec5c2bad694907a63850628484b4ffeacc7bcb8e49abdf57d8669075370a533b2c9528698ebc5b8809c17313181daa3f9476160a0923dd89e961f44b1eca37e1960b89151d72c5c27ad27e40395438e06d3142969da9885e2db82969044a4fcaf36eb511ad67e769e9efaef4c2f1e73524dfc4f40ca69d45215feaabd3e146f1b1b9490bb82054f45c59d5559a3d5f355a737274ab859e4bd9705daefea69f16aba5b8ff6b784a35248d147a9a73aa6b2d596412f4281e33ea4cfbcb0e1756f8aba2ac0d4e38ef4054ffb2987b4af6c049006d6c56c832f0df83230a40e361e2823831d9bb62afc30fe83da048fabbbcb098d0877e7f7cee9a4e6c58fba7d0ec1207b38247fe32ec405128900790d4b21bd1324b51000fd6ba5b10f3f74977c8d41810aba367ca67126080e9a6ff57d0424694d8d15d31b5d52e071d3b9e7fe13588b68d470d9e41d4eb9e8ca102b2ae04d6713028dcca268575b9dce1a1b5a82b758b5f7b242a6c183ff95889ad3a70729ccd205527d8d6e7dc15a78ba3ffadf328805873b600982de66863fea2c818afee38eb93dc196ba858c722f05f16ee4d5a9f2c3a82c3ade4e0d90f55256c6886a8d4469b39465b290480c9dff84308d33b73462732e1a26a820c3ce4da2174d83390057cbb564bb484a7b3915f083e6228ce0bd68ac002fab150fd537c208cb6c19fc6c8b6655491f189b089d0f384f141c2489fcfd135de47f8f3a22d470b521bb41a224c49646af7be3119e1599528fe218b4c2e8aa2532269338c4ccd2c13b2c5183722169f7ff042aa391cc19469ddc1426673a4fbe0d5fb4085601209094c3590d35220327733ccc7679b98df09595669dd96baae15e76a1829086d0f4d626a8d21ffa1e4e66f9dd5457a9a8acb11c22863957185b725a7c0a0638ab4c8996f4e61d8b8138ea655f44820958845a7181325d58f920e91adfd4c496cc890e4e79a882438824d441218e863014044f4398ca0884eeb430989354cbed44d47cfeba57428440e8ee7187e767e20cd45006599a74034a60fbb7f9bb914382c88621c32de689811b06319402bc6ed910b8553f2b82e0c19e176c0b889cc0be02abe1580021c7cc8f5e06d97d67e19afd27ce9dafc5974108e6823519d477e9e40eb6fe04b1155336b4c58acf385bccae1a3b4bb9316794ead079d9921e409f6a0f03be0fd7556a324d4b5bf32ac3e36ed098c2189dc0c336e4e75b16b9cd24f1ac15e3ac189222c4f33c98929270e8f3a726a5cc90f7a441256dd8144c7cf84e404decd7b34f930bd6f1c75548cc8bc05d70c315c4d7c3010137bbcc5cb575223a5614a53106339a8eaebb3da5af3def7c8650aa1b0733adaac5908953800a177e0d1484f0ac190489f6d18dcaf0b309418f424e5946c99c038d25327b4ee55e9d102fd891759e7b47ee3139692ef744ab47e9311ef7a0173cd3cdf5647d5b9f64f74c37987f9c7bcac4734394784c6ef943357c27931bc3ffb108a2029aa8fa84cd4ead333bcf80000bce644940beccedb1e0790f9a2c9659106e9d0caecd218d85c1dae492c14d5c75f35d86a0e232b8490d5592ee55df3f06f0af4cccdc2646f7c7540e4d93e8b17eca2c9b26e78cfa3a4b353960f5713c8e591665d3e42a97eacc6e4dce9c722987b90ab4d624f7e077ba990314124c1cdc5828b8c32f222350dc2e0e5220424ad1b8df4bfda86996e6895da75e8f72a9b522a2dc78344ecae2086616931b1ba5b69b29b78ba5ec8bdee9deb3592daaf0c93073d0b55e4a8f8e4f0e474bb9d14d6c63bc148f8e048205c67b7330427ebc8729262c6056fea993a3d21e016827e5c48fc7009ef2e8cc18885cb36ba1681aa9f9185d27671f25d6ef67e06a823fa361087c188a8dcf79da164f6ca72d727de49a99dd8162bb5e67de40131e8cd04b8303daf281f2c4868a351e9292ee37c8d39b8ca9973f7393f8973702266a3a454068d1e4ed33fb3e436f7f1aa4463010011882a04c472a33129b5c40b26d81b0cc44cd3dbf771854eb561857c8020ea0fe980e3a08f4265d83305381718c36e51d89dc2471744097f8caaf9ba482f2037b9cd1fc3d0002e1c1e30158c63d010ae3b0e9867b2b519c7df88485199be942ae446ac1ab66e4a198e58f0a35314f3906d392f00296f1bdd37a29bef422b40098e3286cd224c091048960096de275ddfe585714c1d14dc83c58be1fabef1569396e04384c9d22452be49e42f6ddb593b4c7605cb2ac50271054c5ca3bb7bb49e0f85b93efc8c5e182239cf8abbdab9928e7c665eef7e2a04ca593b62039f39310c45ca2669b37a747e3f8d39e1958030010f2080377ae7e01b3b9cc540183d16256d5cd9719f73808bb6a53fc3e4b074df6cdda45d62417760382e1adcd1ce6a8249e6e75ad4687c0246257375201c78cf5b40424677126755caffb5dac0e284f85db010a380ce9334dd0f54b4eb7803029fa1cf087de7f8c67abaaf91d846cc5834bcdc82d2c797e0964", + "0x3a636f6465": "0x52bc537646db8e0528b52ffd00588ced05be0a08441a5410300c6b3af9e49f7199e6f8b793075ab6341c6633cf4110ba4f8f3adecd54c7bf75e94c3444e01bac53bed3524d9ec497b99d77d7ff233249ee104cf03806df0c59b906340d4db88eb6adedbdbbed2db79449a6051fc517ad18949452b23eb32fa4ccf52919a473fd2695da67e798e9d75c149bf4f0a9cbde7fe609e6efab79d66f9f7d5fab9f79da7cdabfd57cbf4925ef6b2e8a4d02b9f8b4f93ef89f797efebe9ae7799ef5db67270af9fbf6d909257fdf3e3b57c8dfb7cfbeafd56b76ae6667d094c2e5fa9f790665fb221dafd9b99a9d9b2c6273fd9ad7dc33a56aae6fcdf619fd26952ab63ea35ff39ad7bce635af7913398e2a730fe93e5a6d10c5ee1c038421e3b3ceedb3fe2695accffa6bde4162bbd8414afafddd42d2c5b220c6192192199074416205890c4876409203121a9060417205890d487440e203922d48b420f9a1002138a24601c4208100921e900081240b1218904c2980080ae006090e0588224a01a0407203921a0a30e6c898231a381245019c3802c51132487838d2e58817232e1c79c091178ee07004cb911c90507922e34818dae5080b475ac81939c3081a46d81849c38814463860c48923578cb471a486a7248c10714486233118b1c248068c2031821a4f5e188961041318f9620406235646aa1879c188048c883102c688172357468c301281270f3c65f1f4c3d3184f679eba78c2e2e98827309eb678b2e2498b27354f5c8c5c3142c3131b47d2788263848727374682786a6364cb93088cfcf0648611083c81c088104f2130a2c3d31a46867852e3298e11209ed818e9e1e90346b83cbd796ac3c80e4f2330e2c313098c74794ac3c8ce489627348c68793ae3e9044f653c95c0081b4f3b3ca179e2e2498c2713209172a4882312387275c488231138f2058997a72f8e28f1348127259ed218d9801138464ef074c5d3124f343c31f1048127209e8278d2f22484112a4f443c85f12481a72e4f608cac39428391324f5b8edc30421a4f669ebc3cf130021a2384e0c98a110d1c096204111cb17a2a63c48c1146300208467833c21a4784188104476030f28123bb27248ecc70c40623719ec21cb1f2d4c3086e8c4879dac0085b8e6ce0c987a7083c1971248911703092c3112e46aa18e101461e600407233718c162648c91228c3c6184ccd31003a86100310cc0cae98d53099cd27072e30402a71038a1e14486d3194e66387dc0290c27319cb87042e3e401272c9ca67032e3748593154e1c701ae394e5448553154e523821e17484131827093845c0e9cac908a7229cbe38bde054c52908a71c9cac9cb238e1e044c58907272e4e3a38ed10421c27179c607062c1e906a7199c7a70028248194e3b27229c7c7092a1e98ba6309ad23481d174a6698aa6324d553449d12481a62f4d463415d144449397a62e4d433409d10443d30b4d564d2e345569a2d234a5494a530b4d2c34ed98e234f5d0a4a58987a61d9a7468cad29443130e4d0f68c2d27443930d4d35345d69a2a10989a6249a7e68f2a129024d574c6c3455a089024d3334c9d064a52986262e4d413431d124a66989a6093429d11486a9044c6930b5611283690d931a4c6530a1c14406d3184c6a9830c0d40593154c1b60ba82298b090aa6314c584c553051c1c40413059892607a82c909262c98cc3019c1440453114c12609281e907262b4c58981ec0740313104c3e309161aa81481144be209286481744bc208286c81344b82002059128886480081544c6102143c402449a2052016a03fd814a808818224c1009434409223a10f942e407223b106181480b4b692ca9594ab344c552d652154b1c58bac052079636b014664909221f58ba61c986a52a4b53965818d2c6903743d6180282212118d28649034c510cd9c0102a867060081643a01822c6102e867831246bc899216486941952c5102986a81972c5102d86843104cd903443a618e281215f0cc9628806868031248a211d18b2c5903143ba1862668815437818a265080d42e20cb11ad2c2902a4376435818f2829036846c21240242d01052812043045122880f41900822449009040122c8972041048940901e821411644b1030412010244c902c418c08a225c811417e082281203c04492208972057417208d225c80e41bc04d1210811419608b20b42850811415800f2012066003903c81a2065004903040c0700f102481740d000e1a2c78e08181b6c91011b40b200190248992512d42ab083034362182203a501068729024a5c08a0cd2c8a2130fc580383180060c612950f7ab0b1616bd3a466821a1b38c6f09cc163c6072d0c69c1a38647043c5b68f0044f183e3ff09c79a5e12183c70b98124618e049c3a3c62b04351a6a0fa85de1598327043c6b78d0e041f3daa209cd073004a9d2e3011a00e1419827199e3a60a40339ce00001b1fb0f04bece062032b3bc87cf0c20e2a704cb1434dd0144a5b2859093a0316e625c506590029116ba1822e7ab8086225080c3a5b766ca002348cc4185df9c0c04b4d0658005520071a46618c26a014830e104143ecf08092073ea0b2a30348320049038714461210ba4a7a801113a5971d6772b009e2b22426e9cad20f38ae40b2521ba302363bbcc880022f0ff818e123899d1b761e80838ca0282c11b608202600c2868e181d0a68a0c5520b493a24d1900389a419869ce0a581212c6c26b0bd79710088960dbed8a08b0dd06cc0c5065e7ce0422d4cd3183bc8d8e0881c6b2cd580b4ab4560071a202cec0003c86e47183bc6d8b146c8881d59ec9842830cecd8c287133e8ef081849033435f9436f820a207cdd00796d0408a01880880b8796da0070b1a1ca101180d92d000891e573010d3c3060c94e871030613e85103064bf4c0d283060c288001133daaf49841832d3d646092a2470c3d606032a38715066420268325622c20ad81040201846007164c10788dc0270ed0121860c1e0060188c0832b1e34d0aba32d475c8e207024c491960ce21c05017481242caf2b3650224986179a57164b1378511164869106945e5872c17682580c39965082216908241a625c5e5854b043cd879a101a40519322880c35ac0f763531ca2ab51e6a45041551f3020715352fb52c1dc050d300d0046a1cc000875a121a68a0c6c4eb4dcd899a96252f6a5bd8e2d43a50c3c090076a1b48daa196051013350b0469a1c645072ed4be30aa80ad042f2b6a50d4a2e8c00a002000401b00a401003600400200606a48d42460b4440d889e2f8c9448baa106819e34466086b860542546c688caac023cac08000442b2845491411b1be050b46b2a03880e3da678f02503131cf9003bf318c8a00433abd9955995d9121fe695f0a008a1311e1821940198053630f3238dd81019a031a3329bc0d2163994c811a6bcf222418eac1c546880810de06cd0c60627d820ce4b0ca30bbcbe303ae235865112af3090607881514353b2506ef180b0912003263ae0a1032d4a5614c0a1c00414bca16004435078194e6b389b9e2e1c0c203d106591019c213586d200da02c8034368f0946088cc109b252fb6110c9d19e262280ba7076436d80c019060490466043ecbfcf2527c99ef80f9c35781c406290d243490da20a901db02e681a31e7ab490c109605c00e1c19c72e485592583e069863ff314030e30f21aa60b46c4f82e06e0c211081899628436478630922580373fdaa826c868f088c18904027093d5f02106ec0438b0c869c0d8d8808d1d52ec488383091c6204b0c6529c4f62f604052334459561e6022c0b18164072a8330079c0061ec8e00d5e83d5fc0580e070a40316e3280bf6828890174f425908a5110243080d4e430403180ca12af017443820d485d016b80c1c061e039321c40511ac0dd40891f940860f62884909820394041006768851c6b0a38b20285e5e0409b1a34c5010351c7420a013840e972031ec30e3f403910d008501f4851304885c40471b40583baa08aaa2ac01a809262580c2fc240164c40f12428c78273e03ffc48ff90908f9f233819e357e24e0c343ac8d1e2b3f10e8f12176829e32312c7aa8f8a9d213821f293d6c7e64e831f363c5c7879f5dcf0d31343d6a7e6ce8e9c0cf0d3d48c44ae0e3c48f0f3d51c440d0b32636464f1ab12b7a221083d3238198153d56c444d04343cc8c9e2b62657a88f8d9e2b3430c8c1e2d7e70e871f313811e1b625df40411aba2a74d8c0b1f2db1333d63fc78e9a1126bd3d3436c4dcf0f3113f454e067089f1e626e7a341043a3c789589c9e303f5f7a62f8d9c1878998163d6ac442d00344cc033d68fcc4d0a3c48f103d527e68e801f393a54786d89b1e0cfcc0d09345ec8b9e2a3f547ab8fc00d1b3448c8a9e297eae7a3210fb404f113f537ac6fcf4d0b38158193d138849d163c4cf959e277e74e821139ba267cb4f0b3d22f8d1d203c58f113d33fce4d0638198173d43c4c8e8f9f2e3420f04626af4502026860f0e31353d64fc10d183f5f343cf193f2ff488f9e1d2e32596468f1431333e4fc4d8e80141ec8c9e2e3f607ab08875c04787d8163d1ff829a2a78a9f1a7a5ef899a1e7ea87859e1a626bf4c01023810f056223e8e1c00f0f3d586261f43411cba227899f07f40811cbea392296a6c78c189b1e267eb0f8e4f01344cf057eac7aaefc74f939e247cccf123c52f094f95142480b212c9cbef809c394812340e83881912b8e6c3112c50e2d624e2c69013341ec2a16448e2984ac88dd50f25053a24644075580c4d4cabcb810c0086a5d9cca3875f139c2078c8f047c22e073e5f3c5d37440a5276b3666e6c40c8a232e18a1c288078e2031d380930878dad8600c9e11f0b8e101014f1b9e3478d8f07c80a70c9e3178c4e00183e70b9e2e78b0e0e182c81b1e2d78b200b2436c0342541cf1d0434a0e016c0c989a7c066c8d529c1f2cc0c4e061c5c3051e5278b4c083051e5378ec7854e1410546060c0dac0ca634d98d6f8181941e545e2788ed62567e6c9123899a0db52e96a6a80df12ab3848125271c861f22d0c902f246280b032ba62f7498d03162c717415ed851466e33cb40f944e9448975b48363f132537b62a70da6239696308a62879557154c61bc3af022539ed1d405066086ccb0e38a2633350fb807828858c2c2c70c51c30716401478b51132021f453865f162b324811d56bcdc1029c1902baf3698b22c49c160089f22969e28b19433d4b804a961489c1c627c3025870e3a425470865004703821e4042f13bcd01062c5920c352b4a1f8478c08986a0ac241e5e718240f02a234719393e90c38ca4176a4d2cf1b07485498b0cccfc38410656349131c48a10102c6df9404a8d8a0d9208e2426925871449566a5f6a57434840048d1a184b6264708543e1034ba70b1d2f74bed04953c2b0b41b02672902b51b9cb470aa61e90b230abcce08795347e019a89129b5bcce78a9a10156f9c26b4dcd880acef8b88010122cc150ea500ba376454c061048900403929ba5196a551039410e3515a851fef062e3050789051f46bca6a8a04d8e351b84297742ae7865d5346a59250ea59418124b59247149ca520ba2364683289cb61021c107555e25f8c04ac81a2f1024c54044881a0562492c615590465396ce159005784850010f1b34214404416b942d1039a3040248093418f34ae325021b1c226c388df1819517194c390041638906a3080c81e1a4c4cb0c232482580d3983e70d8f0780b019daa202336c6d9454766435793124867da1e25069a857ea0df507db42b5c14ea9355420ac948aa56e316bb039581cec0386ce70d2f25a63a88cd285262b86d4345d31d4c59019436986c2f0c1400d4b794339850989d7075e5d94562f2d2c963207224168e004ac0958057c7cf171358466680c21667c80297b28b3d46aa89151bb00d316262ea50c4c4164f005930598c0a8e950ee50d240a40bd30462360cad71ea80d399212f88ec9cae0c913164a6b604131ba6334030015316e5036a679cd8103162e80a1c47c4ba6000270643d02ea88520167cc4086511da4148870c8cc8e02a832f31286251c06a80dd00b3e1adfc0c2fc3777922de4b0e11e420418e11e478408e2c1b7cd920021b5c298d518a42098a1f12f89184121ca536944e00eb022302e625e642cc4a47099d25742690034b8e1c72e000030216040c023109c48e8881a9008b0ab4a8200ba12584981012f323cd8f307e80d1410b1d4ce9400a6c0c2c0a181420fc000210206c51d2a2e483520f18ec80410f18f05081950a66a84006a42ca42b90a840b202a98a243149144862a2832c1decd0810e4a59289d51d2820804446e8842500111151851411141568660099241490da53594daf870c1c70b3eac2a58a202262a1013f444d098a00c049511f481a0354b0f109a225445880a081d00410a10ca74704407497480c40f187e58f9114305515440a6020d6410c3101f32b0e223043e44e0c3cd06576ca0810da2f871c48f303fc0fc50e207123eaaf071850f2b827c580213f443995556b15365c76ac705203000b10224860cdc6450c6ac051f43f8e8e24308a5294a5594a8644005065560604505392c9551010e446988c220028388975a0e352d6a626a666a606a53d4b6d4b0a8f150fba13681da11b51d6a6a6a696a196002d344059394216930d9c014c6dbf035aec6bd7034fe859310de859b416408cf722dbc0ab78208179f6269044428e018702edc097fc269046ee52ef80b5404de02cea9d0367c474fe02cd038f40d75e352e808281b140e35012501fdf284e240b3a05ba8169405fa000a058d826a803a41cd500a500c502c9a030d82d64075a05928167a05958296d1d1239c50a52075020a5025906044014b94244180019014e0081dc3f4415e1a02c4f683dee0438983006c4023502221d2dcf49d687985a25aa28024509640a1902489486b094ea09224098d8c869c28a109131514201bc26aa8db12a8291280100d61a084272440958063e8024dc500a8282a06402d11c01cb2404f41dda8989c003595044a010c58924213404315682aa8129e385981490a49aaa0a6a0f80c51a0a954b82db9515141514139598109536c8889a6a2826a223424a6778696e80998b004aa09cf90123d95420a2930bd86c2503094046d0889be41511dd1544ca81860021494024c8082b2f50c81091a9200d48d8a01541148e1c98d4a85ab86baa9a0002653b7db929ca12f504d9a3c21213664449bd0440e157134444493264b4868d264c9075e9a0aaa6a0a8a0a6a2ac90dea041c435d7a889e7a6242122a2750514f6e496e242c59012a0914094ca6a02481ba3d71f2e403da901028dc4e7002d5844b43419990e4c92dc90d851398402da0682888a66ac264c90daa8424505026e41882403f31c10993240c988252412a091328f9e6042a05062c09e1878068a813b63454094f484852c292274da0a8f04343dd9630b9395972a372c22436e4433769b2840412964cdd9c3cf92067a887a6a2ba41515165a0212d0d458293274e922c21c1c9932612b2d0100f4ca064064c41553d21818a09080cc8e6d00e1a0ce9403494a5758672681c1a05129e4081920d3da0a754388189094e9e90908409940ca58025369e212c7d73a2c2131292409db0044a12aa29a8a82537aa24544ba6a0f0d00dbde4f64405a924544e923081924f70c2246ac98d00414336f4935b921a1a8a04274b9a2c51409227b7245437274c9e100d5d69aa12a6962c006a2ac9094e9894e0040a4a122650325593274f4270c22485274d78888686c20405aa2928270b789284015051398666e812a09c9cc084ca890ab725243ca962a282145492dbd4132850533e8664e8129824b941514da940c2cf9095a68262726332f504859b0a4b929c90840994bc044a094e964c01b93114432f8009943c051535f5c4481173088626c013d1d00b0d05a502940a4e22940075c2094b44b860c8aaa9a24880428104179aeae6046a0a0a05274c7ea88a132626c886a834094ca89c3099baad009584014da0405992640aaa84264c54b04591f0a4892d68684a53010d49e9254982865ae814922cb92d2961c90d8a29678885063069b284c98d8913263c43bb8e22e14913052481baa94002d40a503a384e4f3df9606c0ad544014b6e4e543021c98d04a829262538619224c94f109d35be2d5c2c8125b74e6cacdd2e535dfdb965126512140afd6c90902c28e886cc9305ddf0827272c69c9c1d928cc576485246d66a423221a11bb22099ec8677e3b6b52d7aefad15bcdd16ec7b3faf9e77bd56f7a5af964741f8fa095fafd7abfa6df54fabd50db640f05eef3ad8b260085af0de7b4d93a46dadadeece63edadd75ed0ba75eff6f55b6fadf4da5a31acc17bafffe4b0b5fabd60f7b5d7bbb15f5b5df76ab56e775ff0bac360b475bdeb200c562fa5607b9e37e4597b6fdf1a8660d2bde1f5e8bdd4bb9e77af772f051dbcd4f33cd8855dcff36eebd24befbdb4daeb2dbfd529ed7bbd6afb3aedeeebedf5bdddb7bbdd731104431d10b47d73dc7a6d815e6babd60daab7d32ea20dda9f2abe7fd6bfb0d6fb815e736a756baded9cd1addd421da585bae77ab76f754bfd8a1ea5f75ed1bbb7bbaf837dad0bf45befe501efb5475eafe7b5dadb6efd7677bdddd756776bfb5abfd75af7bed6eedcbe6dbbedbdf7eab8d75a43776ff05eb7d6b6b52058ddf60ddb6fe31c50fddeb6eddedf7597dbea6efdf675aff6d2b20441b0a7a707f4badbab0e8fb50da8dd25a562f56abb6bb7e5e14105813a04431b5ada5d6bd36b79400bda5aadf5a002b95babc30206ac60c36a17606d5568417770c8ea549edab6bb6fadf67a17f47afc561d1d50c75a6b7fc07badbd3eeebdd5e572156e54535e7b6a05c11cefee7afdd60eba03afb5bdabb5b54a79b5f5d6eab6dd7aad396277edd9d194524a6f7bd36e774aa1547797dfead582fea49d74ad35ac16789552b7ded6ab03d5ae6d4bc751ba5cae14a85f5b776aadd6822eb02c0520800a2aa8150828b4b60504c4834713790804e4ee9f53efbeb49d8aee5f57978b628bdd2d8a4d451c3d3d4496c8121121b9cb55b6cb12953d01e000c7e5a0ec298f8e76765c3bdea4bb01d000c0d1ded5a3bc4a2bb5e059efa5b5b6bc95d36a3169b55aad7befb5f55e973b0a6e4f30c1a1bcfb5e58637addc1ee6e4a6983d5dd9bd276ea1eebaef4b6fcfabd5726bbd7ad3b68030026811ad812b4610920185a1074f7bbe3b8ad0eea3eed43775c27e1a500bfedf7ba7bd6ddab16b4b3eaeed6eb755bafe7e383a3766d5bab83b4abbbdc2958bdbba7ab2f7107abe7a0836ead05adb520782f586b05adb5d57774fbb5b66fa5f75a5ae9a595baeb36a5d45dae1200d55d4a68b5aeeaae0abcf47adb4777536aadbbe78160cb738a69777b6def06dd524aa9bb4fadd55dee5e83f673ea14b4f4bb7edb3febd65f4942efee0bbad2b13aa56e6d0882d656ebdda1bb4fadd63d6ccbc3633df40a82b6d65a2d08869e00f75babb5d6f2580f753cafedb6bddde5ba1758eb48d6020b6821ad766d2323b0d66a2b888030d419f2b63c3c43ae7380a1a190a70ad576b03aa5d7dd7535e896adb682f73ad6012b0882b5d65b6bed41698ff0e54e6b18d2eaa187e1cb43770ffde5d56feb7aad4bbd5b43777797ab56eaee0640d2b700d7a3dd7d69f881353c526db77bb75baf3eeed5faa52e1cddeeee46dcfd525b6babb6bc561772afd6bae772ebaaa0d6d01becdb7d414a2fbd5e0529d55173e4c891a37ad7bbeeb9b5b5560a7edabbd7af4769bbbcfba96bbd9edfea9eb7e35e69f53ccff33cf7bc6ecfa35e48abbdafeb6e47704a29a55e2bad5e6ff53ccfabf77a0ddbddd57dbb1bec765b813b8eee06aade53a977f56ac35a2fd8e9dadede9ee75177eaddd6bd94da5abdeb75750d67d4bd7abd2ed60a82edb7de4b9dfaedf6eeaea07ba5ddf5de6bbbbb767753776f77b9bbb7bbb55d6f37f5bef6562b02016ed74a6bf5ebeef7deea5eaf7b37ed6ea7edf7dad0a9e7d4fdba8f7b57afd62badd5dd366d7adbbdddafe7f5ed7b6b75776b6d77777bd74abdba371d402dabbb7b6def6e77afb676df7bddafbb5777afb57af5ca03d65abd9bdeeb79d57b5d0facddf7f6bdb7d676026d0619f0500a6e08a0bd17046b83d7af776f91a6eb5d0a5e4c449628f0aef7fab1dead43ae106badbddef7de7b73dcf6fdaab5a1add6f60d5d6eebe7def77ad5bbaf77eff5ea7e3def76245d9010517dda1930f52405a8146e0cca09540a50b725372a0088cd03aa0aaa49921596a480e384274d929ce084c909273c69f2934193264ca28e82e40032237590397c4a68c204051292dc9aa8b0c404a8128a7cde1700e5046a8a82ba0254094e985080c1d08f1398509933064045252181491305a80065364545c1d8185051414d4149e1090949a6a0aa9e900035c5238aa60106504880a242c26068031e1a6880410914c06e4ba6a09c409d9064095509244025797283c280291286944c78f2640a4a120698c0640aaaca02104a809a822a61ea49129a0618403199ba594053e8e601356502094f9a3459125404258525372aa81498dcde54800a54452214145592149e94e064c914dea19a7d30b395e0644912a8a925505278d223a7c912129e34b1407c725b520293264baa92503149e284c912144830c18427433d6842375678b280db8d252850dd885a4202095051340d30f818063c92600015b5a48902929ce084090a544b5078a81498dc9ca83085df87093715845250c149d0af008542929b13265350929040c52485a92537aa1c3e543fb3c6e0c99329a028129628a04993275316e4255053400c808a4a725b01cac90df30675c24f8cea46c56405a8a0af793879c2e446c2122a274ba66e496e4c5248e1c98c6c0c56606202d41414fc534ba09a9020ab7202557d9a4712274f98504d41552529c1091414284b92409db064eac98d2ac96d05a8a02a2750d5874e16d7d11c55128546d1e972ba9c4b49eb74ba2b8e55372ae9d6bd4a5a27e628e95c4e57e672391dcde54425dd6ae17415b7f3d289395b9574ceea6a2ea7f39ccee6aa921cd5e53ce7602ea7a35f2ecce5723a8bd381ba0aeaa82e97fb74d6e6682bc9515d2ed7ba9692cee97455498eea3c25388ac3592551689428b95c8e2ae95cce75dea7444773395049e774aea475b95c2ea7d35925399acbb9925c2b69dd55a2a33a9da7a45b898eea745649eb74baaaa4753a57a2a33aaaa4755409ddb586a0dd4d53a05ad2014f49c7d2614af6cf0227fbdb31579356eb794e2a59eb594f88f53c6b7de651e1b31c9156293d37569636997ebb6a45b2a695b5d9afa608a5cdd68aa55eb98bed5ae4ee1ee89b33faccfaac1f266601c15729fbe98b6dda4c8eae36b94ae7e5192b575d328f9dd4dd4d16b1bb5deea7fd3d2a4d81ef5e7264ebdd46f7ed53f3fb6b923fe87ff841d912fdefe97f987e98a9d8621d3db1fda9697de6f7bf6ea34b1609737fd84927b5641111876de47497af7982d9bfdbc89d859c235b5c4d9a3fea19c8caf471f6a8489d2432be9bf44733ca81f8d3a7ef42948d95254d0e1f8d981ce6f145b18e9404027eeba3c40f5f74f30c4d9910bbdb65f26daeb94921e52e93ef26dd65f26beea3d86df47aefdd74fdcb3cdd923ffc5db8be933ffccbafd5d2942df9bbdedf854dd95298fdc3ec18a88dea5756a4b6d5f7d7bbc6ffc822611e1fa893ea7b6411591bd51f3190cb65d25d6e1208dd75c9f99a97152907bff009e6fb51fee19ffe4d448781300c43a7e40ffaee42fcc328571bd57fb551dd654b77a5ddb190c9175b22895fdf6dd4225fef1acf9ac577897fbbd9459a53aed7f8357f8def12c9f15b3a44dcfa9ad7bcdfbf9d7edf9c0f973ebb18670fc37254e7f2af079156296d6eac2c1ba0554a2f37569631b98d28f8beeffbbeeffb26fad410a9bb47419f794fbd6f935251daf7bc273b49c9dff37eec24ef9bc85bb3b3b3a3f3395ffeeb7776767676cc78bd5eae277f7cf15fafd7ebf585288ae1f7a2288aa219b1bf17bbbbbb9bb67fe6d846df53934e51deefbf1f3bc9fffbdecd6f03a2f7179f63fb5bf3c70966337cef4f9afda18439c44e4237cf5cb6ad17a39a84d9c34e42cfad3f5b59b8642fb75adf64919b5bb87d76dab1e579ab8e2dcfc37e82d9c177d3e98efba2a5f7adcfaefb37560e6a961a2b3b3e6bd95f6c8dede578df58b9b1725093bb9dc88eadcfeefdccb3c9983d4fc962905a13889e573a0d143d53887dd1f33cd37a6fa9d57d91ba52ebef3ba954abd784514fb455345bcfb45e1845bf7efd9a5b7cdeb27d6a7ae63966ef453559fc9a3d8b7f4d9a65427a8a2b597c2fdbdca4906f4d1671d31da77b2ffa78bd179bd21d5eb56693315b53b654a3320e6ea8d9b9651ee50f4d9a29793d935a95f4613e0bcdef5b26f8d4bc4f492910c48d2df673b4704421dfdb17ad79eab27d6b7ef6bf9a5bb0f535b726cde0df6f9dba7c412b7edf5bb38ae6effb5e74ff362299ec7b5f73d0b4e6dbb3f5f4b65affbd0541f0417cb69ebecd52b8ec9dadbf54cd6ea996d29f7edb9729b34fdfbe9b32fbfedf8bd60c52fb9ebe1d29f9c3ff7b2bc4fffb5e8ac699ba8d59ca834c9b14024588920c3ed8ff9927f851f6bf1741f3b4d97e6de129a96eb3dbe59b4e06bfd6db98c1225042734aca83ec6d64ff7673f8a767fb2d732afcdbcde037b99424b7bee6a0298543ca834cdbc8be48c756ebedb770b70eebe40fefed5352e9626b82a049afcfbc298b411d483f31627b39e3578f92d4fbd1636ce24bc8fdfb777c6ffc70fcd687a1d9324bd3aca2999a5534dffba2376db72e8abf8dfa6b7ecda8fbadd269e2f7a2596c52a96f4ee9b3f08ff2f89454a2e64973d4fdd6677e1b1de57ed12c7dd660fe96eeb7b0f5d92b7cefed8f4f494a05fc10c77cd63fe2be4f5bf8d4e5d68f263547f30cbf15e2d3e6f0c5a766f593e6f1cf213a0ce46e1d233ec3afa229850bcdce456cae5235532d65fd7274b3b378cdd37bfaa029a3588ae60f5f90453a82a651fecc209ff55ff3a4f46f0b623b527b114502bd88fe192bbf93be8de8f707390de645f4fd610510e9539354b23ea3ef33fbf93ee864df1ceb337cde6aa6df7a98d3c44ffcc2109fe1b73efc46a77de1d7173f936631347b7c4a0221cad667adffcccea379ab397c917ad3ea6a9f75a63f739a8ea04c9fe2f38a95d26b766e99a00771e2c4c9a079f3328565bff85c21df6ff30473837d737cf6fdfbecc36df649b3148d13274e9c7ccd5bcdfd74f470e9b39f59b37390d33ed7d7d14935d7932887d4e322d216ca7e184c44c3258761272585b9e98e13cce76da44b8bead7d04ca003504313a677743e6f1633c5672e57793e618a66fa2d58588ae3089255d6753616174164a957a65fffd5497d825cffd20074aea7e7f38edd4974479328e98b94a4589453ec7a8c9294dded3a8d15e3a1b96a9a0680ae4193fb9d22b5ad3fa401b0bbdce48f4693e98bfd8120085e07c14abd998bfe27456caf95490bdde1430f2216359966fa35772a45737d6a83e83d9d5246799f239f5ee7c6c2014df6ce509d347594bbf4eb9a8ca7df8d2f9e52c5c876df6ac74661d93e109232e5d9247b7f944f583e7b0ca7b64db94fa9159fd95fa13ca9956cffec31b27d5c7f598b44a065891f96009366b7b3dda77fcdb65173678d98218816206001db942a4636fa563bb62955dcf6bd550736fad7b4eac086bb12813e2e845a649f66e1ae44a87d187725c27d8a718f8f3e9f603e1b0b8bfed9593d021736d0058d2d8a00c38ad73da08c057cf0c189334884c0d6b67e5284dfed6cf4ad382d4776b73f880d286b110f0e6572506e2c1c22908f74afb64242fb4e5acd5931f5d4648bbd6bffc34e2e8e6a829dfcfdb3e21397edd3bf5f4dfb4d16e929aee48bbb80effd99cba76746356935f97bcf494f71257b7f3620df0f3b6935d9fb13972f3ee95727029882953ddc254a6e87164fecd0e2097cae90eb8366bf45b2438b27ba44c9b51a5beb5baac68993bbec84641002cb96290ab64880ccee06a5d5e42ebb1d5a3cb1ab12c014ac15763dc5155bffd980ecb5d06a6c2dbc6b35b6fe13973d7cd20074ef381b0b0b19f94673975d8f174748f9c06e676b1c2507e25dffe9348b4f28991421070c2f8668630ad34eaeb873aef3fc1a2136d149af74456afd59e6fe0faf77bd5084dbb5c8bbaadffacff6c3075f04f15b7fb108e18356c438f1c11f40db5ade7bd7bb5e68faa845f64573d6b5e8fb9679548bac8f2a43223ef82284df0aff6211c4fb223e322502f821c605c15d8bbc1f40db42b8619fc9165fd56f5bebc14e93ed9b6db27d6ae5b4b3d9ace0b4935a512b506e709ad02b5667fd6b210bb420f83de8b50df43ccf034124ad0731eecafb168ed5223b80b6fdfdbe6d2068b62de733afea1f651d3ec81039eac1818eacea1e0c62139d9d06ac48adea799e27b6e8b82bef73e1b7aa572d083e0128e8bde899f49bfc5a666982b528847c4330dbafa492b7ccb67da61031d7172929a4cc5e86e6557db7766cd2f3fcbabb7be6a913bd9619e5cafb1cf8ad7b6bfdd68ba0e7fdfdeb5defb6ccaf45f64333568b6c2cdbbf4a540408bf85a3b43efc11dad6c257de0fc0050f6c219ed522fb47b5c83ee821a1a26c1bf82e78606b7debbf96d9b69c5cfd6b6e5ed5da58d9fe11a79d1c0471dad9670e5003a1cb70d069720fe5aace3a7884fdee245a9de689f66c52dffb2bda917692e77e51b4a24cc8a9fb21dffffec3a78e887cf1d4e7ef75b9492161feb0d722df7bf8bcffe12ead77f3d465f748209dbb58bdad8573e05f797fc922f52f3e43b0a4927fad7a5761ae4f0a692d95b9e2d3c91f34fb8bde4eabeb1c21771bd11bb2ac7d6bdf5a1bce644bb3b52ffa48293994cf5caef69bc8e2a823cb46ac55cc8d65c3956a8314bf27a8de1beb59d19bc1cc050139867b63fdbca8addc58356051c1b17e6405c74a69d72026d7dc583558d16dd64026f707baba8da478635e4db9281b8b0633b973677fb18e9d1b4ab9dbed58b0d1a526417d4a2af937596496bd9368eebfd226e7c8f5d24ef28ad8aff8acaf422cdf6253521d27fbdfbe7c5face4d24b8875b3dbe8ac0fbe7847db49eebd0552ffab27cd677dfb9f295bf2dedf71947deff3259772640f771bd5af26e833ea64962bb5e4529320d777d3c92c574cdbc8ff924af5295964962bee36720c7ed48211dbc5d7fd263a1b2bfbcc698d35839a06932959a43e7d4a2af55353d64f690be5f93e9ce683031d8e446dfeefb4c6aa814bf627fa1a9f34c77ce6efff99339f3991cfdc33616693b12b537263d1e0269f3eb2d3a026fba84844ae74d25cdf4925229ff9fbcca7ca73ccfeb0d169b9b12a132214b11ba9d656b2df6695cdfdd61452e6fe5abb56b3b36b80c50ba293dd5d73ea3390f11898da931b6b861dec0c56bcd1924a5619e633db6f4925291a275b1208056fa526a5a26c2c19e064ff500dda69c59be3c537525386aca6fdb93c2c6213f977fdf75eb4a669ffb440c0a7fbf8d4e5fa395b25958e7c7f314e67c3d577dbfd9ad7ea67e274366afdbb22dd3f6f355bec61eb33ffb36c1172b62a57521e64efa9cd9a159f34dbf7ccb366fbd7fcbe56add9f933ddd6a408d5463b5fb36dd691409bff58e61ecab9ceba5b80897d2fc869b79a2b983df356b310badbed7699be356fd566fad6529a85d85feb8bd4f3be56cfecb19a75ac267d9d53af72a5a4ff2336dda26c2c19b0b2971bcb4a9adc3a63a8b5b8ae2026a0f4d94ba426944d0ed1656b75948250810f928c09535fdebafe8f6a2c95cbfda73f6ddc3eeb124b6cda81b2b1ac8cc98d65854b3e5fd9fe05b9b1627893ad489b24a2cbedb3d3665da66225953c2789e872cd453a5eef4d0b84e6fbb21f34dfbf18ccf43deb428809a051f4cffa4e4d244550da3fc43661cc368baffb8eeb5bef02f1779aec877ffd7adffba87af31d73cd6baea3949211db84527c59b14474a0d34e9a29067d66dfbef83a80542edba699be02c4f6faaa6e2241a2b4d55628b19dd6583198c9f5fbc736c576d1951b0b86354164b2fd8bd463763b5bff4efc7ef1659d76bf5f4aee17bb935c2f8abaf15d66b7d1884f5149ca3310119f9ec5a73f9a672e8f34bb4eaa5c16df7ef8dd49ad77b5910b9fe2d727bf65761b91f81cbf76a6a6d417274e9c36b2fdd13c75f97e933f68b65f73d1ec1c9a511657d17cffbc423cdfafe4927dc7a72efb77169f9a27cdf42bf9e3beeb455326249ff7eb5312c8f8dd46f46bb5e6a32945e364f05da68c04f27d0b9f34b73e344f9ac317af79d27c9f7c4b16b17fbf49a5f16b2e366da26c2c18ce64fbf7c5167d6c1208f9223e6d16ab5781d9f52e4c492136df17c5265df8d465d78f661598c717cd9366f1bb93467c8edf2429771b892f7ead8aa668d66fd285a56abeaf749f34cffbf6ef985d0b590cbf9f9240689c3ce26ea35314dffb2683741671b78ed6d7d0ecdc322968d25d1b79ff99a73fbd66eb5af44e11bf225179fd7f7f4fa5e7ef1bf953f979d703a03e9517e8c77ec77745a2f283713a5f819e0a8e17bf1fac48548ea8f8fccff7c72a12951e8cebf9d7eb7f72fe657ecfe37a302e87e87f1ed7f3e3bf9e4ac53810fc12e3caffeae32ac681f805fa38f06f7cce93df5f56242a21c685effee20fc6e1ff863ec7fbf73f8ff3ffc138cffb12e3c22f1ff7f3e253b10f847130d8eb605cfd16c6b5de141f67be8871b53e4e7cd9ef94e58f18e7791f625cc538a10fbfac5f3e6efc12e3bc9dc7795ff4143cae7c0a300e067b1e8ce3f9effb1b1807bbf13c1fcf53f0b8ef29c0b81bad7ae3712d22fcc26c07e3769e87e7653b3c3cf887c2f06f0885a118b64c9e9f9e9c5a7ede0a7b2a28f2782fd31b1dfcc97939687e652dc38f47f4c69e9f1ed07ce57861ab55c5f2e3c919cb9ed6f893f339e8e1cbf478aac7f353c11c1694a2bf4cf12fc8a120cc9163e747acada2a2c7f91715b57a7af0cf4af067a305163c2e7c0b2c30bfeff5f88bc6f08bbcd9ec71e6cf72ccc0174ff9f82df8c9790bfe82c7f5fc0545458f13bf8882a2bfe0712d2f470ed17cfc338fe7679e23470e0b1ef7bd05189723474efd0b28a040e871e30bb51e7fd18d171aeab9e08b1ef7f345b359054f01c6cd7e88822f7a5cf8438f2b31d1efecf8cfe3cf2124f443376ebcec85865ee871392f047e8ed7f1b8d7eba047417fc1e35e7f0125faa10b5ec7e37a7ee871e017cd8282f007157dd0e3cc0fa28f133fe82990c97ee806c609619cd00fbdecc6cb1e37be8c3ece7b0a7ef6b8f267b4821c8ffb3e07c65590e331c655f0376efcec71f5f1e35aaf03e32cb0e089304e8671b2dfd9f9208c03027a19c605fdcececb1ec7f3328c03923dd0e3465ceb22fa447fc1d0a8f34218078471402ff4e3f8f871e1638cd3197afc381143e922fa3a7fc1e342bc4217d1bf00e32cc02fd022f129c0b8307c18c6c15ea4e0c5c7b5f01111e342f183302efcb1f5e3e34c1c4217d10f7a1c0f0ed245f467189783e72bc0388c71f829309f08e386fe31c6b519534a50264e0f21b0c1ca6656e102162a4ca0c60e54aab05131bff683c12ea26f62dce3efc1dd45f471e0ae45fd37847e3e08e364b107c2385d05923823ebcc10454c5101db8f8e8716b6a8e1090f94e0cc0fb69fc7e5e05817d1ffc1b818ee5ab4039fb3dc8f7be1b28be8fb60b016f5f73cae6214ba887e0fc6f1e017a88d4acec330eef53bf885231b95fa3a1897e3fa17c6e984e872822e42bc7183c61ab6da5cb44922881a7878f344096c54eabf1e57621f5d44ff85712edcb50800f8f491fb711f3eea22fa248ed5a27e9c63255d447fc43811bf30b351b91f621c074b34918604dc5cd1c6085b0bbff0362a389c18811218d8a28a09ceb051f1ff1e07e25917d1ff30eee2ae4546f83ccafd380f7f17d1b7b8ac45fdfdba9a2b72a3385e6badd4bfe6d5fda9bbd7f74ae9839962d9127dfbb4f149f393699afbc5573badfdad4849252ad2918a3edaaf4fbf924ab48ed4a4d949ff262d6e9fd5bc5292884e49472955436ca26e2adb67f429f96385dd6ec742a62ffae8201d4079c2727d7ffb27583f16e434fa31a7b535ab70642a5d762c5bf2b7ef6ff18d668aad10fa8e4f7ffa1c78014d3ec1dc5659b95f3093fb47a7d1b69db0dcdf448da3be263652d94fbf5b6217f1175b88f98c66496952cae6a036a2b8a9493390ce52344eee6f926c23ffb18dfcabe9c2947cdaec70329da26cac2a6c72bf971bab8a1a70eca4fafea47fa54fe6c6aaa24586f98cbeedf7a76d2a17474ea3b9df3acd7ebfd84da53fcd6287508a756ca7b5cf4e10ccfded48a317d5ef1745f1df73fffba2df22147ba60e9fc5628e64bda87efd9a3b09c4b52a59b451e7d333fdee007cb856c54cefe84cf1e97ff1e826ac66ff25cf51fea5cfead71ce634c727fdfbf581902051d2b77fdef75ebc26cc67f53d73f4597da7927ee77364f22f47a7795f1fe6b4cef5afd9597452c9c34d730c1026cb679dfd810cb0c4ae8d3a5392882efb8b74f44c9a9bf4279574f8ac3e35897c565fa423353b5b93b4f87d56e905caf333e834bfd4a2a932867aa06cac2a6172e7b3cc63cc69e74c87d3686e2c2a61b23fcc694e6d6750f66fd2004bb0d0469d6b3e3aad6911a4520789ed226da1a4df5853dee4fe7689f69be82c737dd1f6960cf35963eb331a277b5f73d133c136aa2f3649f1a9cbf4db3c69eea75965634d5993cf31d71f6bb54925fa35b74ef3af0f7692f7f55b9dd4b9be67b69733faac7d76c6b23fcd8d956525c37ce66f4d9a9ba8e2a8922221d2274afa3d36ad40d95858cc64bacbf5c5577f139d7497fd45243ab649a79451fd9d4fbaf3dc5837a4c934d3777289ee72c527dde57eb1c92265b65fcd2a9b2d96a27172fd364f5deeef4e3aedcb8484d962a957aedf5ae4a37c769c7cf6fbd76ab751bfe8639bd488923ecddd3cfa2929f5b97e935265ae38c867f46bde66fbace92ef790ae52d74204a1a40ffaacbfcb2967fcdddfddb1b2bbbbfb379157894dcf94b57ead5f6b9d7225d75a6baddf44958a8d1433edb47e7feb34fafe4de438ea28f7908ed22ab1e999b2b1a464c92798fddf69fefe33a79d36fbfb974e3b3ffbfb13398d667fd0698dd58295ec3f3aad66ff761acde798cfcffeed486e3bc77c82d9bf9dd6ef6f9d46dfbf891c471de51ed2515a25766ea2b3ccfe22e8b4933ee8b3fe7e20244894f4cf31fb9ff5db67fd6235419ff53b95f4ebf73759847e54c5a0cffaadcffa6b2e52d3f3d84953142b57dd4cdf9feca429bacb521e64fafea28fa0d34e9a419ff5f77727d13febb7cffac56a823eeb274059bfbf4920d667fd15833eebafb9e823356d1e3b698ab6c9525faed2c9f4fdc94e9aa2bb2ce541ae1a337d7f57274dd15d96f22057dd4cdfffd549537497a53cc8f4fdc53a52b366b293a6e82e4b7990ab6ea6ef3f76d2144d93abc64cdfdfd549537497a53cc8f4fd9b2c6277bb4cbfe6941452ee32fdd1699dfd9b144277997ecd6b5ef39a3791e3a832f790cea97b2176069d76fad7ef07428244e94fffacdf3eeb17ab09faacdfa9f4afdfdf6411ffa88a419ff55b9ff5d75c47290862139d65f66fa7b5cf4e30fb9f60ee6f476a2ff2ef17bba9ac4fb3d8219462d30e948dc54299dc58bb32f97c65ff0c7263edb2642795680b25fdc6daedb27f3bed7b7febb4fafea0d33afb8b4e2a7db8698e01c264f9ac737d20032cb16ba3ce9424a2cbf5453a56b3f367d22c52b2be58cd1bcdf50362ec95309f156b0d56ae4fc528bd7c7a9b9ac5c9789b5cdfc9781967e3671c8daf7133aec6b33c8d6ff9de78719ab5a36f727d9a45cd5037340d5543db5034940d3d43d7dc375ebcd02fb40c15439ba06468183a8682a15874771e65ba3b737482b9d2304afff3bec9f5beb9707c7a76b4384deab58371df1a201b8fd5ced7ffac7807b0c749c161f5638b65719a148e2f4d2daa6ff563e399128bfd27068bd3a45e3cff9dd9c57c7af0b7c50b98ef8ad37830ceeac706c3382b20db0efeb0c8d4a2fa5f56a56094fee7b7e56b937b2807ea4ac75c8841b04cff767148bddaec76429d54e5373aa92adcf9e9a429a957aee2c9e1df2c502755595927558d3a3d9d3425f5e52a9f4cff567d62213e73763a694a8ae6aa5816ff463ba9eae3e9a4aa57a6f82cbfea274747fc96f22057ede4f06fb77c919d54e5ae4eaa0a5f9d54a5e36a75d294148e5cc593e9dfbc1c56d51c568939c427f95540b793a6aa7ab2946bb7dbe5f06ff5eba42a2fd32a32537c8e5ff593c3efaf9d34255573552cd3afba39ac72e5109fe25701d14eaa02bd93aaca4cbff1197e939dbcf3e9dc1c2cf5f24afbaaee7227b1d46b740d2838821807825ff5934f1177c14979e12cf85640b6d65701e5732787580a479c3871729716c649c111274e1c1b88733b36ab1fdb87714417e3dec3b8208b71b11f5bc538986b40df0ac8e6b8740de8f7ebc21ce8774a9a30f5838490657d98b15f913ed0fbb3cce7e7efefc76a4e3bc15289d3bee7c06916e4ef8f38adb1bed092bf3f80d36afefa4cfe8a7ce4afcbd43cc8696e7e6a6818f9f31c4b533aadfef730a7d9ffbe6e538b109b7651daaf585e64e5a65e6ee00556d77ed006a93548a8937e88dd0444397601278806807ae062b2a745a62fbea468f62c3e293eb12893ad3d75b2254f8b6cbf2a9d54ba6cdf94ea3871e278653235e3259bd9cc9e16d94d1c999240be8ae7b3bf19e55eb14c08fdfa40e8577c13b31932f9e6d9c3a77f15cdf575d9ccd534b3dfc4dcaff3a897c06badb57aad5957b85cb125c37c569dcb1556b7932cd1fbac5a01c60a2ff7ebeb08b25fff7a9ee79156e956770b889d6f27511859c59a0c1bb3d6e4fa652cd7af6445fabebe8ea019acbfdc5f8972fdcfdeebee5defb6d1511d42acd69ade53fa79defdfa9fe779d60c82c13d6affe2206bddafa89556f0ebfd7abf7e5f1fbcf5ebfd5aab78abd8bef7e97d997d9a3dcbec37561695fbdec5d65a136ca3fec6fa80d8efbdeda4fbfd5e27d1dcc3675ed62e1fd5732c738414bef71c80efbd8f22f089c0533682eff5c8decb3a8966af6506f90cfc7a82efc1af9f1b8b8a34394649f0659fecc38d45c59bdc5854b09161266de1209f81a6d7466dd434570988fef47f84d96b63b0bad322e27df1525229fc917cef45d1fc11e66ea35397cff1c3effbfbfed1ac54b8c9b68dbc36fd49f3f307c1274dd0417c823fbee8587cd1c7d10c73285691fcc6741ca5a874b9f5e702d838419c4cd5595eb0c0905b78c4677ff8b52af60a59345d7c2bde113497487cae90c5ef7f8ffc11e6302afc6e1c7e9342c02ce228f0fd4f70c9bff559b34d9d486d0562d9f3caa31edec7d464a715e5188c6251f199d3ead74ac5995c6b7d703c800659fd444e3b77644a3b8932fd1e99fe48c5974cbfa444b449a402863853b851e379716e71cdd429c688c95360c9fd626eac29aeea145c32accdd1a923fbc7dad4e13414fa8fb27f73604cf6b77847ec0887ee29fa0a0ad069a7fd28fbf5a9f7fef5ad695fb4a6d78a4f17ad77af1d3fb2c91b41b209045b2490ead55a2d0d473b4a51acdc6d2413e2ef7d634d71259f64992bf9be7d4b2d11657665a86a07bee4eab95617abfdd6929dc94af6af1cf892fdebcb86df7a4b12f1debe7d6bda3fca61fd9086d50b6bf875fcb17e187e154dfae1592ff9047e14104701fffe472e8123259f402455a80dfc2855a8edde8f72ff238f801f053c02fe6769d592e1e4fab84b6ec0fbf06fce539cf3d79402e6429bf7dd49dfdf1b8255ebbdbf92f2803251865fe5fb2bf177a1cd7bfbafefbc01d34998c51f4d21a1eb2df983bece8f4f9a514dc41f9ffc4afe309d884fbe8e79ea720efdd7eb4b53aac6894384e257147d972913c90d7021d3c406b064a2dc5864da9049e38da2297391e425bf513465a2cb9489a4477ee412f91b00936fbe140ea06d174b01314e670b7195efa9cd23cd2e56df88c5af650fe3aef75febe29ce7fd7d5c0efc8badde761f5bbdcdc355ac3cb051d1d96e1571d4083aef65a2cd9520ae5cc1c332f13def29c532d1c3ba2dd93d0f772dca5d073f60dd5f9f3b622b9fc8cfc13cf6e347213ff64d8a10fb11e3769ebcdfe411f263e6f8a28fb4f5fd4770391b16c16de5d7bc4911a200fdf851ca07fa264500fa11d79c3c526a404baeaf012bb9be478ab0f3393f9ae4bbcc283bef7a8f44f2f3e45f53849dcfc138d7f37c77d28bdef8381ee7fa7912e3767efcb6e99851c6ff791c66949fdf791e330a6efc9dffcc5397d1e49fdc5851b4c99ee924ccde7fa690307bcff3a2484924aee7f99719c5f5afcf3171aecff9d2c4b9befc2691ecfccfd79cc7c4bd1ec78fa62e7fa3871b91e0729e7cdceb75be491176fe07e3ca277198517038f2cb97bddb74cc2838dcd8b69789bbf138f371ff429f6346313fca7f14a1c7e5a204bdcef33c2ef6b89ec7c1bef448115c9ff31e79a4fc1d8cd3d95e0f64e2a8ed853d530497f739384af9394fe3ffe028e4bbfe232f1661e7a38cfffa988923df8573517c1ec791114bf9f9f15f3817da729e3473a1ad4cf2f07994bb58b97ec4b9d036fefd1cf3f5a5497ead9226b501a14f25c68d4fe22aaebfba38aa8997f33517f17994bf0ff1497fd0afff994eeacb94f2f33918e7368ca3c8300ee87139e08fa6949fc7f13e262ef63e2f5e19b6e49ee2ca95614bbe63c6e4ae225334656375c126ff59daef020d1a325144a1254761050a341a50a3812f64be68c00d1465a00003c516287663da8c3193c571f44c1988975af93ecd61fed6e456f3adc9b7d5e42b802958368cab5dbeffe59b45d7e89932ef4153e66121f97e2b83b949213bb478623792420430052bdf29aeb81e07c6511b897126c6513eee71dcc0b9a0e779a112e782aebe2f9fa440a69f635abd2de765a6d5dbc67f99b9d7f33c10ce8dcf938373af7f3df93f264e67dbc1555cf84aca831c7536dd713616136272a6b69869f5361c8893f2c259bd2d37be6de77d4c5c0fce8de3f33c2ea7f33cd8ea6dae8761abb7ede09c0eb67adb88abe460291ed8727e7c124b799d8dc504984cf1cd761599e214ca29f2e97501939b74567edd96dc1ac777bdfdae486f1f249f5cfffab2224979bd0b5be5e0abfb3a9bfd8f24a2cbd7c3511f1e41672bdde67a9b2b411cddedca151a4be6bdebabbccdf5f74f28f96299874528e99f4a327dfa5d915e380af9e3db07690028fe4b22f91df9e3575284f15d18e7fad1458e3e3ad04b2d4426b4640adca8691119bf858f2800c0af7911e5f82d2aa61cb14c88ef76b97e6eb7cb51f53bb796787295cd4d5a2f0bd2b935be976f59b4d513d1d0eab4ba48917485e54ece4e59963b392f1d1d574ee972bd5c16a0d73f1944b0f5e738be1806cd574c19315ab2182bf7dedb323d8b76fcc21b47d3cdbe68f27dd06935df17ef78cd96697d063e0d537e477407f83a7c06fecc67e0832fce2a520f2f021ffc1e19048998f5f019b844e9817ff6c8e08bae539745997fd597a5e82e874f4753e62f6bbdac8587e87288bbb8e0818dfcc612e3426e2c3156b9492511cb84d4dcfa9a5b38975b8f3ba9f520f86545a236f0631549e7c17f1a80f1c117c397b57e0165f2023a90754c59eba9cd6d2f53d6c24ee0ebab50dbeb5fa4a38e496d2d3384f247f35c801439b459ac4ebb5ad7a9cbb2105c2f13dfe69a654e392f13710839584ac77943becd9e69ae79cda52985da5e581662a9579cdcc5aa878d7c29af366c55a88dfc29e06eb77361295f1c1bb9843e254d0bd0a72453996bfe1ec4517d759e7b2670937116d6125a96b092cddc58135893bd376d9e65ef8982de739336cabffe59fe79dfdfb1571c555a2a9e3bcadf7e2599fced53b3663153f259c2cea0ece1a8fade83638ce24a737d1a00cf95e928771b55302245a27409e4c64ac289ec3fe4c63a020279961b0b8c15426e52dae453d7c4cda70a354491fb5f1489b23e911bebea4aa6637263195126ebc88d55841b4a0209a54893a594846d7cc85239573e6f617811fb219f372f3f8861e4f31643185e3ea93ca0c40514c8ca279598acdc0fee767172ffe77e7f802845f3473110f1bdf7fe33a968fe425c84997cc1d40dcc521d2793ef99ee24c5dd465e76f304d2a1d92f9ae77dcf3e59849a4c7ef8a217ba52b8649ffc2697c8077f7c6a8e1f9ae43bb9d4fad17a7a3aa66d443ffcd13c3dd3b00acc52b58d5dee07cdf346b3eea3958a28f6a8ab402d8ea0b3f947a94fa562173cb0f97bcee98b34039b239f447c113d9d90d0f3feb4f86cb518d9c35d40efdb04df339f7668e1441c5bbff5ba44c9f514576c20ded93f5bb9e6e86f12498e7c44759efb155ed0e4fae1c5ca5e58a68e6138864de4fa74c8875528f36977bb7c0bc3f06b4ec13f698ea21f824e1f5f52494a89be785fa49ee5d19627ba077a9e83b4d56ab5de47d1a4f97f9e94798193eb872f7bd20b9b5c7f1cc71f473204fa11924a2e974be8c60b7909dd7851302ed235925f7359f991b26fbd4c06ee08b91921994c269399423a9ed0f7bcd017a709914a301cb2fa468663247384c8f779f245d2947d719aecbd1775a2e81f658a75c81fe103bd2597ea879414c73188c442a3392564bcf1e3eb85b81efcf1061e5fa34b26fb9a9366e720538a66d98fb277b288e7fb4166e7317ba2ecad8cfcd8932f5efb639e34037d93458a320964fefcc47c4c2f8bcfbcef31ab1b9f79df3273cc139775cc13579a27aebea96fb2f75e16a779969bc9de57374e6bbd17629990fa51f7e9d76f32c8b5ffc569e47b2f9224f94e3e355d4f65b9b176c000115688d0e2e58b172d5eac94566ffb11cc85b6103fc63d0847a4e48be348925f73916cb5def5ad77fd6dc269aef75e74b95c2d971886e36b1cbf0ccd292161283ef861188a233543a95c767de7d0f532a56876b99e2c52945d58b6443e7d12d32f3ef3fedf5ce11fbf89f1eedf344db36d948e26f8e6d5fd700429f548a5c682c02e17658a6f133ef3de49a6560ef1b9801cbed8dec1ee456a9eb973854cffcd2a6f8b9233ff7f57d19c8165677b3ca55d03f0abbced1fc4a7fdfb66db4e4fcb7d104bd538ad0fcdfaa279ae905bdf24d32cb76a3d3d2dd9fbdb8467f9cc7bcfa360b23766ef3d8b82f16898ecc1b2f7e57f67efe997f77ef40efe3d4b8a60fe7f2545f8c7e17f6cfec592f90c0362d326d8845bb27da0ef076900be4793eb0399a767d9bb1ee86b2efba37cd2a37c949b947dcdbb937864e7919b04024252a6bc7f94295904e84fcf24a5f824c91f1be46e2350e73faea9cbd494bdcb3c81de99def53870e0c05171e078b18e38707ccdcbf2c68d1b2fd2b1346fdc7827956eb85ce3388e4394097a3a0abd807263ed609545a0f1077c201783afcbd4743df9aeca66bc9e150a645faf17a9944bb3b3281b29493f886cf2c8268a8378ff02e18441eff341ef131414141406bd905050d0d7fc838282c0202c5bc2f1e3e3185f2fca05e8bf1b3ffe8d31e84fd9fb8be48ffa329a831eac6c843cb24891cf0bbdcf0b9d2e7477c69777e52524340a090999af50e82b59a4280b61d952ec5f1ffbd78b41e694cd41ffb2b0f186195fafd7eb6beecab7f5fa17962dfdbceb7fdef5a2cb1c3fc80433dde2b4f1ed8bce23f49db14f9a34bb4697d959c894a2797c725ca2f97e90d9f962717c9909f4b50a6476fe313f333eb31f332f189fd9f7313df13b73e272e85d599ae511cb967adef53d187ce333fb2ecb53f3f99df9ce64fbe01b98e7f386b961b2fdcf8cd33c2b3b26eda1a4f9f4ae64fb178cd35c6f5fac6b9c96931386e11aa7856fdd9d4cf84e2a85ef639c46df7e5996e53759f352ac27e592cbafa4529963762eb18ff1997db1d5a2adb72df3a9799b3621fe104d64a3dc584358e9122623e5c61a024e173899961babcb183869b210594280c9426c11624a16754471c499a6d5dbcc11b47a1bc6999f0b6ded1a80e08be268dabf2015c7b1d50ae2fd7d19fdceba2c5b02ff3e10b0b2a1f8c465faba4cebcd337d902c5224beebc57761cf8acfc4b72f8a20b994238bf43e259fd2a7f8e6d9e5fad73549734a08f9e00bd179f2db69203ea784809ff342ca079fd4c1ed33f2497cda9c834f299ac907f159ba4e27434ae55c666752a459ec7cc9224559c4b2255cd7f8cc7eeb814e104eb61f6a715a0bd32d40d44bf95ebc782929febeb3fdbee63d9451e0773e2b1b2703447b28e95b10d357a1ccb7325fdcc5ea6d380fb3450a2076b69c5de3c40e4fd8a23000a7b311bd0b47b62a47b62bfa9e15a755364ea3594bee7cd636d9c964fb5e66a8ae197232dec1d049b964fbd40bf6319872f10ef0d32cb9f30966fbb68bd5dbcc6fd9c52294e67bf60ecc18dd41df33815a077d8f641201bff99514e1cd77d2a96d43b8ac45f429e9d4368cc15a444ddcb5887eb845c87798f1ea97e5c60a028bbb726341004deedd87d55816cc03511f20e02597d9bfb7566ffbc6efc3b8ef73dfd7998bd9162abae93581cba5d5dbc011b47adbfd8b4fdb018871e0e7be6fd7c02d9c6cfbc1ea49d538ed1a9c8d05c4997cf3ec5b6a91a25cb1d4972909685320c8bc7263012126c3dcd8a7ef839b0c84977cbf82e311253e98b1965a10c2912d5baa0568aaec9e29ed9f47d9fb109c7612cd9438ed2c5170da19cbde7bde7b4fc469347b7fe4b4c6fa214df6be87d33c1df91cf3d9642ec867a35163413e9b4df6bca3ecbd0ea79df5bdbe47297d4aefd7fbddf46f37bb493391d3a4689ca9fedbcdf729b99424fb5fffa68eebb7127d919a51f5897c933f96ead36a9ef5bf173ff37440be8f8b122507e6fc877f2502e2f3feb85f972e8ef2ef3437ebfb52fd8b97e8fb7b1fe4342d4ddffbc6f2e14bbea6974b98d3e809da68233719a775f45f93c6c94dee5a477fcdafe93b1632f5ba4d2b0262d3214ab102a9f869117f479a12fe94ab17c596d958eea28f9d66e791442c59a4e6faa1d9366fcf75888e860c1639ea364db50c7e2597fc95bf17a9e73a7357f2fd9a93416a197c278138c952b9fc7d9342c61347fe86e87ec8e08b75b4e40fdd962ca524832f3a75b9cedc967cbb759ce05ff203c7106c8da1d9365288ffc562e8b4abebcc652d5ff2fdb265fe6eb7dbed6c1557526a85292db0b0cb53edb3fb179fd5c92256aae6a8fae18b69a52f5b3a1990fd3b37a974dd7b23b66bd192ed875aac64fbad26ec5f0bb0c9f7c526d064fb240f70b27df1ffe4e0f5e4f7c362414f3473dafd6bda566b6c8de37fe3388a2fbeccb6352946c996c0f71e0441d737c92482a10bfcefc556f89d5b21fef17deb5be37f26cdad267f841e18862db288fd1047797fdaa7228b50e9f2f851f7ed83f8bc3fe2d67fbaec99e487a64eb6d47af25b4fbea8cbe35ff3655e738c22dfb6fe654e993265caebab74f3a09eef535b956e1e67cd17535bad4ae15e66db4453aa22c92ac93fc5afb69242c4bff8245fc432f1c1f7de492124968978e9fbfbdfdf0f1ffcc0a88fa97ea010fb2d7cde175f14cd737c59eb5bd6c23fbc175fc47914bf1515be884f9acf5b44c4dd46b88dced6d722f6457c867f4d9ac396493bf7383900471a006721f7bb8e7c38ade6a82ef4d105b1d610a65089e20595ac2b5434e0851a5bd7222ab90a246e28b3a6042470c2d6b5c8bfdd67d967f504f339cbed4567e93b9091ad472dc8fe474e3b411f4e2b399026fbc366d94f0eaaed1cf3598eede55c3cfaccc3636eac1db6c816c3a847dd046257a4a2362378428d9d069e4063bb5680a0053524b8a10358d89a87d2bffe0ee5539fd50bfadd94a2194775d40520d62dd9b6be62244894744bb6df5cd426c217bdd1157afe63e88f0b43300ccdf1aff9dd1743d3c3d7144dd0237f901f7e35c11f4df16b1514ff45b33369bacccfbc7976fae0b75a4f71eba909e2f06bf5484df25badafad17abf9d9afa7f76297f26b5e4defc526477ce2f218d6d2b47a5bf9ed1d9418977b7dbb06e1e3da35a85f7e7d4b169965da4f4df147d3bf34dbf632afc617a94962130ccd16f9e3862f86e679f30c82458ab2f71e923225dd929b6e19fdcea0cbdfcd7e0bf130fd6a9eb83c5505fec537fbf79d2c32cb672e7be70af9ec074d291c45bca7f8ac4fb710ca8db50304f2a9cb677dd7e14d9e65ef456ffcce9b67effb5ba9e22a1047d1ef7c6ffe99de57722947aef8d54fb738cdb35ff32d4048ca9437cfb225eaff994ae1c81497efb7b794239ff59efef53df3c4e5b3ffe6955c9a654cb7f8acab8a84bb4cbfa621d2970aa22fb65a18f459ebb33e6bbdf8725d06dfa40dd6774a29ed7797c265da2a622b109abfa7266de1f3e6598ac211dd3cfdabcadcc4ee58c867eba53e382cc4c955a01765bf7e3fc56799e9b7ccf33ccf969502a7b4c0429eaaba19fcaa2f53e93288a979bf65766ef394fada64ef6febe6d9fe8765422856ae4fb172fd6b82669567fba23b6d1dadbfde5f530a97ed8327a5e65337a3fc03f16933f8d4acdec227f8fdb4e6934a97fb3ffca3df5a1c55bfe2a87ec752b87cd6dc7fe388fef5bdb3b212a5cd39f9ccfef59be804b1b2fd6a5217ca130493edf7d30994369fe02edbaf270806c4cad57a5eb5d6da6a5d830e66327dcdbe1685f88866d71f7d45d2f9fab3fa3a6657241f4794678f01c169e3d70f42c469220836e935393c12bf7e2589e8f2889bf8c8e157724987cb066cc86188c1ef003ea3b6b35efec5207653393ec5caf7759c3024ba8b3952905a74bf89f8508e7fc4670720d24379b69a7c9f480d657f548cf826dfa75cc238cdf1edfc8582e962f3918a44e445f741b03c4b8bdb89f23d43e4aa0c5291a8152fba3fdef730e5d967b2e4fb479c36fefd0328719a979b25fc7b9f72b9569c467fc456f2c5374b3a6e9f11b591bf67c6fc4f0a94d7765f870f476adb7d90c8ab7fbfac48f6ef37d1c55114cb8b62ccdd6494a26badd5bbed799ed83ac4b7d6c34f7bb451dfdd7329e9bb997eaf3dafdfeb8ff2babbad2ddd88069b7ac5b6d6b7f5bda7519ec54ddb109b28c4a7cefeaecd193139476eac35aee435d4ac41268b75f4b8d82d558b67c9df972fc692b15ff1d9e7f7b4f9e6a7e3fb7d85fdc5a74be74ff03be7efef80483b7f1f86cf9b052bd2ce3ff9e5ef98ed45afd731db8b4a2cfefdae4839f8d5428244e9c2379bbff14d24489420bed5fc8d4f622051f46dfe70d4883f9b6f16084911a57fe39382f1720b47f97f421c47d1f7f2e789f8d455b28897a95fc96125f259ad601e63f97bea350ad936c9b66f2c9f2864fb35ffa468bed8492c5b1c45dfe2fa16d7bc0d99fcb9b1d4f0922ffd4b49b20856b619e97e6f29984c4f1a26537c7edfdf772bdf77ff7b4b2a7d58b56a49253ac3b54ef3f049ddcaadd00074febebfb7ef589fd945c4ecb995983f6c72e0b3fa21845fbfc3efacecc3673df8c8f5c13a9be1f2f7d6c4de0c74877dfb999e54cd9e67752e2fbf8856dd6dfa9553e76d6df6facb5fb7eddcf4fbbda7665b69ec563e03dd412975d3afb4e9f63d13b4ede530968e447ebfe82dd3ff33ed874afead1f3e7e3b92ebc5efebbbccef899cf69519ccb5058666097312495679bf05a4f5ed345a0b77fd6e2b24cdf6a2f0dd6c13344ff01ccf32db27725a88cf18ad0f9a9f799630fb4439d7896ed5b8929b9a309fc5de7f28cfa0e7a0064293989d8106a0b3bd923d73b440fda622fbbbcfbc82e5f9d9fd3fcb3acdb3f4bfafd5fabed667afcd72dff3d4b04a634d8f95146271a03bbcafefa6f7f6b458943cec38d01d2ed66aab492a79debb69afac60b3d417459df56c05e9bb79ad8e661fbdb93bc93e6d23cfba98b25a0bd2ecd79ca3aaadb87a3eeb7700221d9a1065fb978ae0a8e499f0ec83b556286796927ebdd96c8944b162f0bb7f7edff781f656bf547ce2bec52798adf7f5cffef6be9f46b53d6f357b6f83603eebf73c7c2ac9de5bd39928a967de3cd067eed1ea84d8499d4ffb2d5a6ac1d3fb3697da94511e064187218d376a64c917e4c6426302d96ff77e19cce5eff42bdfbb27d6b7b8e98efb6ed6bfe6e956dcca67a03bfc6ddb56b82204ccd74dbfe233bf7fa5be7c475b4dabb35034de52d23f7d64db16cca13c61d57ec5407ad656964d2ba6a47fc2b23f0c8360883650afd6731fcab3cf70e0338ae56fade779a0cfbcebd9a04c1f5643d97e43d9f8b4997eae7385ec1528e97b14b04f24762c5b7cd27c5b4fbf5ba667131af827142b4329a3afcb473ebc1013b92aebf7f09953727cef3ff0293efb4ca64fe2b3d380233e7b4d88cf6e535b4f1f045b98ee7ce65747aee60996655966f7bfa5f830a77d2f3ee848652df217c5b74e735249c4b643286da6a4b5b849cc022c8ac022d7fa36572cabafcbefb3f2043391ab7285b3dfbc798bdfe037f9be3f91102a6ee1b3d394203e7b4decc34dc6e2b3df3419eb614c77159f4d6639044a2a551cc467febd82cf9c8792fed96fe8484317663a6ceb3def82e2288ef7e2b30951f63e0c5bf6bf0f9f9ebf07bffb9bc87adf52d4faccb6756b697bae6e23fb413efbd2e2b3898f917a4834073d748c711288a2688ff0f944b9bb6fb1fc3eb33fcbd6f35e1475b657f8be49a51e4f586ea5c6f2e1338bcf269d95ebbbeb2086a0b5d6da9a1f65ebc44716df9aa78fea235ba24c451fb5c89ffaa03e4e1ff4f3e983be7b29c7f73f7d647f1f4158191423ca5647b6effa769a7dd2bef7a266f82e9334cfa3ece1297b06c9de575229145ba5cfb2889b10659c9835c4f0923d9b5ba6f5990f17b567c42a2f47ddfffe5b31d167223e41d13c7d64f17135174f2859f4d979cba2689e4719f459abcc2d7cdebc3cbe37567939ca7bfb48d6461f74a4c6daed76536cf44511c4e767f13ff3fc20a779efb5c8ff7bd06923f9e59fb1fcd5a2965f295bafc369a00b7c6fe223bf1ea485efff324b9f890f9aa0cfc477895f9a312f12c5f74c98cfc4a7a4d288c1afd50fcdd23e78715b3c567be5bdfdee044a7fd1dab3c7642448943d269fd4ca8728c13f4bab1cb69b7c5a4a2a85b856bf6f9953362b7d9ed9997ab8498fc9d1e0c2136fb267b3f8f6fdc7fae6359df49bece1288bc18a6956cb5d0bb7529e30af3689656ab3100bb028228b26b17a466c7c96b947f7febcdfd75c6a53d2bfef5117bb98d21f7b67146878a1b5523bd28a461634ac5852a9d66a3d3670d8a02113e2f964c0d9805cb1d562cff0c0455c43cf1803e6afb1ced8926f35d7f7a6c20c37537c9d44dbc8dba85facad33b6035e13d70c25ccf842cdf0c18c1aa869460b222982b1828004cd7085695e6116a5151f70829a1fb000fdc011b40bcf969e917e40871e1e98cf113886e855dee6336884f970249b7fcd91dee61f844827d5ec1f021bab5cb7d8ce4e93bdd7f80e22a7f9fbefe824fb52e43396cbe473cca235a7ea4f5581b95fea73956852acbccb621dad79238b76b4265016bdd19ab12cded19a3e3d5904476bf264b1355a139677b2288ed6d4c9e2385a934716c9d19a4759748dd61cb3f81aad1966b11cadd9ca62ce68cd9b459dd19a5e1677466bda2cc2466bd62cf28cd6f42cf6c076787a7c5c78ea56e61dfd58d9da20fa94356f80f8e4fee189726cfa012b37744d9b5a9d3ad85a73a629a5d4c95abbd7905933a6da6ad754604d98355eac67bd3559b2afc1b20606ef7a77cd94ec269f34b7196417a5149f0b03e065a2154a2004bb886335cbd0329671857491ae32762608dbb8c6aa26c35ee5ab1ccf9439650e99ec643c01b63aa7cc8d45c6179d1d9d9d16a8253b1957c8d88de12683ad3a861919b63356730c35b0b1a2d9d1c9295f2e7214c316f8c15c3abb31cae4d336d61863c608934f708cab31bc34ed3569c8688204dfc1185bb28f7989006ac022b5257b4d43dddbbda948554c963fb82bad6257b2989b053c53a689ada945e7b7c948f58a17ed2a92aff122ff2713c32ac5d42b6bbcdd1a6fb7c6dbadf176949a5294e62b15a96d6099cf9ac6137305cb8a152e56565ba64cf1d9cceb2e0b1c3858debcb9e2c68d95366d7c367367e3b39953791ef635decedbf99a2cbe26fb7bbb9e62ad402be395120b2c4b4c4bd096f7b8783b2c326fda78963615c99be25969e36169e36969e37169e3edda288db7db52d36c2193464c4d53d56435969a37f9ac62b23fddc2858ea16068188a45bfd026a8172aa6dfacd07a7f9cf8fe74e7b4f3a353a8953fb542af38edf428169ac569a7a55a9c76120509aac17c8c3ac21668bd4bd5cc7400f5fcf4bc3f118f0c908ff7e7a02788d3a470783dbc2cb5c813538bbc9dd5959ab7c5f3e281f176595ed46ace806ad2946ad6c4d4b4f92d3087b549b2fee518830511e57e1b421bf9d75abd82e01622fd26a2f5fb4d6d8a4f53aa29cd748695fde9175bb2d737fd6767597cce2a3e6799a6b12236d159d994a783e95ee3608254a4ef22fa33f028d326e383aa519e4f46e97f7e779fb19ad585d844e7dd657ff0cfce02bfd35eb1692a92b7f1227f704dd92666dfe45df6f7ac9c76d2ec647c76a5227960bcc8ff3f162b4b7ba58c153358d06851e345fea7c7253b1bef4b2673259ff68a977cfa9630fcbd3368cca409d5a059d362a3a68dd36ea09b37efc1715a1967e3671c8daf3173e386ab91c93ceb865090a79101fd64a9d9e5d3db80de06b7c2cdad6d626d09d61ec0da23502c0a9e282ab94fddb8712de3e859281b3658a81ab742d150343e859aa166289cac2cfa661cfdca38bad5ce67eec4462962f15d8b962c59b060b972c58a152bab29537ce73baa71c4140ed53862fac67c9315e2ac16ce02719668da2b6de405688c3582c8477ce6578a31a6e403f8cc6358746181acc4675ebd60992197e033ff764464147ce662195564c94d7ce642bb12542043f199bb9810234bbef9cc7d6040234e5ec1671e6ee12189ec6dc400934f6f73269ff68abd323eed246d96f06967f9394f3b75bef5b473c77a019f76f6bccfd3ced87fef6fc378cc5cc167372820344181831294f438c09179c404439386517a1b7723f413f4f3fe15cb8f6cf73305e8e7e7c6fbd72b32d9fb3b9c1b37aa1599ccdfdc100aaa5632a09fa38a540be38a177596109fe096163e4b2f203e630da61686182f6aac8b4f908c87cf32cb8b3ad7c238e3459defcec77d442036d169d3642b56c25859819932c5eebcc081c3e5cd9b2d6edc6869d3268bcfbcb2a1fa3e5cd7785de364becf86b160887c0101042e1c70a0c541d06201417c64af50eb050c43bba5556d163a46791ed92b758db361a346fc9a467c57a3064d3d33bea34153cdd42cf2dd8c9932aeaf647c56a6cc1827e364b04410014bbdf23d112256aa15f8208050a7b4beee5acf01070ec7df84dfa3879ba3a3363e73aa5ab18e265a8ccf9cca5a4c14c667158cfda0a02f30189771d442e579b866f1fb52f4a92e6e2fe54b511cd599aac4bdc5ac6bbeb057c4b0ca27cdc23aca923d8c34d9c95424fac68bfc41173ec192c467191bf119eb4adf647fd1c99cbe253b7e43776ffca9978a64b17891bf16904bf92566c364a75eb23f4d5336561a37192b4866cf00d9807e62b1b7fab10949e1b059b5c8dfeac7062424f4d64b2d72a99725538b5c284886ed952c5b6a915b30626a91bfc5aa148cd2ed9535fe544df9c2676765ea5fd738edec12f43bef5fd9f8d7364e3bbbc87e7cffea86e7fdeb1ba79d5d802a9c9ef7b73ba79d5d7ebe7c7f3bc5e7fdad95d3ce2eb1d7797f6bc54da62f828f49c404c167fe3c26073d426893e9e7b0c9f4cb3599fe4b4da6ef4a93e99368f2193399fe51450ac2332fa22f0bf10902e1f6a2163ecb1fdc5e84cf583e8f62b8bde8c3e76710f4f059e613c4678c7ec5364d8ff364a04df66f9a676df349699936922204a5ff49cb4c39b1514ad1326de44fa5a0595ee4dfe6d7c4d264a767b23f054149ffa465bc8da5ee0256a66fffec2c8bcfc6e72c373efb4daef48cf2a45bc05893cf7ef30629042ff23f73264d9a35d94fbae5a4fee7eca45b68a7a55eead32f3ce7cc7fc78c9939a6f93241d2ddddddddb1720fe976a86d416ca2d3b7642f4dfdc93fdb4cee6fd7ebcf4693fbbbfcb3d3e4fecef9b3d5e4fed6f9b3d7e4fedef9b3d9e4fe86fdd96d727fd3326e7293a163b0681362681830f48b179f913ffeeb5d7feac8f9f2cfa39dd739791ef6a70f9feff993839f8ffdd958b207fab3c7087dd09f4d26378e8bcfea9f5d26f70b992bf8ac7e9049b7f8acbeccbcf9ac3e9049b5f8acfe8f09c567f56326cde2b3fa3e66139fd5ef3129169fd5e73151f0597d9849aff8acfe8e5982cfeaeb98d48acfeae7984a4c6ae5b3fa2ff3003eabef32e9149fd527cd233eab3f9a74e7b393eeb4384d7493c569611b2c4e6bb1b9e234708d15a77d6aac9c76d34c719a87c6774eb367e038cdcdf8ec8dd36896cfea676565f59bec7ff69b4cffa45ece23b0d594f4cf59a623f9f54bd7d7fbafefcb13fc9cafadd7f91afece8b0ffb3a3ecfac3e8f0933dfd431636669962e131ccb64fa229931993ec841a6fff9c8f46f8f4cdf3bcaf4ad8e4c7d4bee219d8c8211109be8ec36d99f96519e33baa66c2c30b4f8a3f0fe4dbc032b21dbe85f824b7c7f253de1fb1fe07b1cf9556036f0fd8f5809c57c3ecace8bd0028a892d9fd747c18d38e781ec43001a632290cf4771615cce839c178eeffd897489c546510c7d3e0a89713c2ff4b0978bfc3e8af95560b698388e6108b61eb783a3e07e7e47fc5eae8ff24f86e30882412da0c7c970941f8cbbf13c3c5f28ba3ecacf93e00882ad165050ecc716080414147b530c1fd77a1b902ce871b6d87fd87af0713997c216f438f2a3003d0e1ce58610bebaff8960f8b82a305b10b5a10a383cd86418672564c301e1d6e76cb1c7fde0d6839fb3658eb0c216c35268aec6b1b51e97ab575021a3059b0fbe3abdb71fa507e3721ec48963e3c157f56118b7a383afe8e7e01cc5571613391b6d6e88c1f6c257a77d8a3f0c9730c8b0b9f0d549bfe220125f9df56f9411e372148625428086ed7b5c8e5e41850c2936115f79b86c36dadc60c516e272348e08389086ad85af2ab634093561946103f115c56085618910b0b17d18463f50d23f6dcb749e8f67442b34f5fd942b4f95f76f3a79ca3e50fef02d96c1bfdd3cd57a9f3cd5c2b7328b7f8be5f06fad3c3596b03c35e25b995d7f8b65f26f639e7afdf8fdb0a9aa9c3cf5c2b732ebfc2d9673fef6ca5325be81b9fcd7549598a776f00dccb09fbac572cfdfcaccf3379ebcf32d45dfec6eb1fcf353b732c7de67ea56661c6d445fa87798b58de8c74c1fb37b07fd1e53d646f4794ca036a20f337fda88fe8e19d446f4754c9d36a29f63eeb411fdd2e46923fa2f13d646f45da6ab8de893e6ab8de88f66d93be88b66688a6d44bf658ebd833e687e6d44ff33c1de41ff9a3e6d44df337bda88be35636d44bf9ad7f60efaba18ad5888efb4eb7de0b7be3fa8b1763bff306cb540f05d8aefbd294c0085f7570d2d67e070dfda32475891cf2aa14cffa46568d1058d5cc58f7a2b45e3c409c5f0a382825a61ebc116f85130d8077e1f5596dee77dd428453d7caa80235b1c6555c0912b8e8a025bd4eec4da495355b15cffe64d55c932fd9b87e0dfbefc4d55fde4ef6f36dfa9aaa07cff46b33755e593bdbfddec5540d9ff56b3ad958a553bdf0269feaa5af9cbc91f1e7df6ba55399d5405cb17973edb817918d6e3e3df1f731cf39925833aa98a275b1c74c3cbecffd1fa00d1ba6cfe53aeaa8032d057b9b6fa525c3d36f0fb632f9bfd2957553f997e95cfe6bd94a0dd6e67abe263d3f97ef082df4bc1217eff28da5a3fc5cab3895fa5dac297f24ab3dbd9aaecd85e1d4ca9a2631b9f7cf50791b6f2a758559bce57f16c392fe5b5e3b1f17cff8fb69d9f62656d3c5fc5da602f0507d66e67ab02b3fd7430654a95d0e6f353acaeede7abb82df6525e6d763b5b151da0ef87515cf6ccec9ed1ff31839a07fd9829d43ce8fb98379a07fd1e1347f3a0cf63fe340ffa3013a879d0df3165cd83be8ed9d33ce8e7983ecd837e69c69a07fd9739360ffa2e936c1ef449d3d53ce88fe6ab79d017cd56f3a01f9a61f3a0df32c5e6411f346ff3a0ff995ff3a07f4db079d0f74c58f3a06f4d9ee641bf9ab679d077d36b1ef4753417f39ac6af7bee445edd3ffbb57ffcc6effb8382ec773d5b615751657fee523f436ccb9303cbf97ea29cfab6ec87e9e4e4bcd54ff5febed5cfd8f37d4febc37eb047fc91877cd75b01d960f8ea8c7af94c07e3ae4e0af3590ebe3aa34a9f992fd3655a7334413334834cd01c7d46ff33cdf7197dcf7c223377752eaf60884d048265198b810feab28323683ffbf575588c5ba116d5fa419eb56ff5636b49e180725fea1584e8de47a16c811f3eaa45f57dd4a2fab5771ac685508bea1fa945f595d03f8fe88eba9725b6d3fa2d8fb702b2c58e62b81c4fce0e0072843884643fe5d0f7c3740c5df0563fb6a1ef7f1f23fc3782809c2707003be310068fcb5920f3e1217a3396a3020a3e37f445df1f6464f4b89c0f4fce4e056f921fcb5144c1e7849ee8fb410c781c615cee68c76c280602c0021f19002c90f950c073f4fa1c8fcbedf80a883e37fba2c7e576b8664326002c0e0bbe07a6f3399f2f8d74609c1590ed028ccbcd864c1c163c50ac07a6f3391efc8fcbf1e414e1abefcdc7e5763ef6b8dc4cfc1cf86a7c5c6ee82bc057adc7e5849e027ce57d0ec713e1abfab8dc90638cdfc48f6338f0d5eb062e5d03217ce5c265100665240ef2993fd088897c46451cf3997f0c97f321ea69e1201e7c0562d80ebeba3a1eb639f8cae27248473a98837814f42f58a9f339b1261474e371399f2f753e276bf2e7af9aece4ef733ebff3b89cec5ff8aa7e2ef63cdf5f963e3158cf939f1bdff5fd0f54529dc7e55ceffadccf6e84fffa795c4e7cd9e7c8d7f97e1fb99c0f7a5c6e7c20d8e3723aeff33959908a84cb8d2f84afc0c7e5c80fc257f7713919be02c257e1e3723ff8eafb58eb733e0ffb7e50e7773ee7fa9cc7e57cfc5f8fcbf5e02bfbe3e7cae7a1b82ad486cbc1f015c5b19d1007e9e0ab162e73404c54e22b98cfe8bff055939d7cf1e3722e7c45dadc88af6e3457dcf8caf1f83998aee5f64a6ca2f36b8374bd78517dfbe778ff84e53328f7977f1239b1514e79fffaa6127944aa71dcf1a10ac31f2ab20bce0ac806f4e453b95c3dff522f1d9faf94fedb6fa73dd04f18a33ce2b8f30f7e3b8d2ac7898d528ae6fba68dea77a6ca791f8cbb8acae9c1b8ab28578bfccaa75f946fca384d0753e9e8e05b660c554e0e6e9f95ff6195f8bc6472fd3bc6692e4ce572e13ba60912539124be4d84f1e2b411538d23be5eb67c719a88a94411df2f5c6e18a785982a0cf10de3b359fd16a66ab5f027c66715ebc354df4bf9537df803e3b32b26572afa528ea3a4681c2afb9f177c5e3053aff7a76194bef3cebc69ac3465f2ffeedbf271719acb678bd3c8314ea33b44619c36e22e609c2662392dc4523878befed878be38ad151b9b701a8883bc38ed8b813ef62aaa4f9095eb7f629c76f15554ec2a0a46afa2ca3871e2b47162a3b49f1d9f54cabe131be58f6ea3937e51d22fca37f9665d2f7de6dbe2b9227d5bbca83e0896652c963f9fdf96f3beb959f7cdcd6a35f9bcbbebe5ee30c8a707c63be381b1693cab34b07cda2b36a664a884e9542b94a99e2441a7109a291226003400d3146030482c1a0dc80382284aba07140011a2a2525ea189c32847524a19630c0208c88880000c00cc0c401000d251059882096e3f5963e35450a22a35b71063a0ad52496b432ebc70c7551080bfcfa1c9425b1e41417e28bd829d741075944444b7fc17508bee39b74c0c61dd27184360061a42b637a025d4c6d5a5b7a5d01b81052c883c757321c68ac01f1e003e04098102cac207bd3e12820f8f31143eb4040f53b78e9c895a00e30363522b0bc1fd309a1e20d8771bf7b5f7ca4cb437e9feed657bfbc351930f984272327a061b72e8fc17a02c314c815887b13728818604533b7c2ebca2cd6b4d6edc6a2e17c1515d492bdd135eb4bb6a5e8dcd5b5c08e772d4e62e388b2778576664d588e90e214192d03b6b3d6d39c4fb809c7885495473c5213690c56f153964ef29f1e92913eaf393bbd987d7cbabc4b2d71916e79f7c5ae36b3da3143a5fc40d7d36d778055f17bf61d20715f8cc5d7d4022e706faf4746086bc89fd4db5137b8a3c65713b6667d956173e8ad756fa501b2769eadcec2abcadb851d88feac70560c4ad96f8f5347f2a4012234c81c4081bb52b753d11157dde94bf0c5f98f7ef608b65773696161517270368a57aa23d3c3122889ea12f04158e2b5de2d360a72ebd438c303f6e48914b0636d3f4fe15883438d8b5f1261d4ea4cb7013ce619df536fab9723d7308fa5c67bc042a46bdc865a5cba1e2ea15bf37b29c84ea202cbd6e279b8d55d2f2476fc7e4e627a35ea6ca796d9a3c1c7b3868b963298c8c380da80389520d1149510ad1954c4c7b9e002cfc87bbf9f4becb3fb2c2492bed5866ba57a83c4919f3c6212c75f1b1803de7041fa8b42146f21a7e6de71e2b6968a5ec5793888ef082927232d95ae0651ed7e5bbc7eb3b69ba61350c24b17558ee996afec278f01ac040c12dda43ab6bc00e19d6793003257ae3f24ec8263e9351eaa3521e2ec7811a0b489d876097dab0f9ec46c83871116c1cc9462b2eb55e88f82ac2858f804bcc66e3c99e901323d5229d47e16997e9da0d2dc0e614bc10303cfb39dd7828b3ea470fc8b788216225c91f9eafc5cea1b65e8d405ef6bd57db209d41d5ff6743ad2d1222e0f8c9a08eb11918663831b999277b28c934b5d4a189cd4ac403b3743b8a6234a356b918cc961f37433662447508d2223aeb18ca911da4db1bbea8312260b51fca4118c6c0d778abf1a31a23845ac21b59599e483e476d39290169a974df94893482239138788f5e2365acc241b0f805a68d88f6fd0786abb42d5e5ddaa676b2e7601c7b9e6cffb90483b7a7382d2a11b3ab00edb9d0d1a980c9599bc7432e253de376104bf6a9b6b68c9e82611f2f5ceac2e57ba92f3f3aadd9fb7afecd2dd6d65a2c47ac79739079d72079041b33b4d5d52f434dce691de7e6a0a35f7d2d72b210aa58395a8583110f03664a6e478c8feb98c206e796dee42800de7f8b9217bfad8259cd1e199f89f4317534609234ef3ddeaecd1b76d286f8451d3e4333ace3100390711cd12199e87c941494ed1252ba2b52489bd11ddd3bea80a8fdb46677f3a52ccf3eac2698116af02bf2e30417ec637a96d67f4620ce83f8aff9cd39adc07b32f57b1fc699b1659326d6932b9ce270f068a1739aa2458b469081fce9e965cc0b2662db99c35fb5858c969c72f38040abcacdc284d70932ae8fa24c04d0acd99270b42e9af71859a68e017c7bb4140e8dba22b3c7ca6a4f4ad4435c4c8c2a4881ba01bd7668d59e410e705e8df13cbac599cc0df540a1c9972308d9732624d7232811acf8dc809d0572a55e81533062a44a7581033e6ab2809a8dbb4e8bdcf45f1723f0db8385a9ea2ef7a69aa4005c04f35d0a26b320b43389fa1af434c65ea7529ebb76e18d2b0fd3a860961f8bb522a433dd4c01c89b7b826426034f56a197385a4eba074bfb100de7ec1bafeb7c70d0113371c8c6c0ea5448a6d6dcc714243bd800b0193be470ac4d2f011654cd14fbf9423e42bc716c399c8ace3ea1b1755ce9f5249bd68219c6927ee924277262b00e49a52dd7997ab84ab8a883a27dc629400e0a35b291252bf78866300362d68ec366c060551caa6d82fc34fe00484f2c94acc16accba9969dc8a3ceedceaabb0626801d44a9a7643f185fe5b3fdb18bdbb405dfe669f352e13d5e000769e5811cd24595f67c09ad85b62f6948e59303f5dd2419c8a29067cac2f29e95f8f40aba18fbe9f49ed2dda324402624471a100aadc23dce17faeb5327aa81e37e7c8bc6a3a13ef3d66d5e09f61e886d5f3e9dfd0034c7f48d5530a94e1f2528407d04d3ba19aadcc299a976a0f4dbb984d1dcd43bcbafce1a15e31d5fe332660419d0172287aa1beef3b2832d474fdfff8cb73af4473f4d438295ed1109be6d214c5ed62cb8533ed73ca210f72f63f852dbf3a97469cf2ffdb91716eca52a96e89332f36f680c9d458860b0ad1b1612e15b6eaa1631d80d072c5f83f1cc1950dd40277ad70297ab94cf1ea20201df4598baa210474127494187407139416fa67fefeff43fca890117cd2f46d2f3bcb3f292a1ac8eb0370a9c55b5f33066728686e441e0c388af0cdec8f14494861bd2271c8643de3de82b052b689b1291fd5228c7c2b27deb7f183b12471a5ef13441b7e4c03c25b2a5b15408306ec9e843015c23430e54e19b96a4a9be524aa52db663d71da692b0bea0fc67b213222cad8e2d2e23a92792bd926b2526ba65131f33b2975b3655d8be63592c847b5c0fedc0d999809db686ca768247f9e3137f2ceee749b55264c96d71dede0277485257b33eb04e52fe548e3d23e0f729e1ed20277f86924665f002ef426f451445c38d55cb1b7e444084c9ccc345b5a5c6326085e1aa502b3c0dc4834de8414881c97050a57a540705a592f24912c7c07e07e509d1bf6a80cdda4f41429c28858a50f3f24d042036c7f8f3a0450fd4232ef17d296ad817650d37530b194e2cfb3d0fc8e242c76d54bd241f070d08c32fb8ab34e2e041cbb3eeb06672bcdd01182728f44fb303aaa20da0c79b7d348ea8f92b0ff7111a2a47ee048a42c46094e5c7a75106efc5fcda2ca56681bbe88bc10341c08aee64ada3040e024a5b24ae0733b08780a06a434faa9d5028a277fe86e7b0a7726ea5e5fda7cf6c3d15f674142111bfaa7c0b3fb52b4b4dec2d76e0407d2c011eaf3983aca864ef893d03a2371069ec616eafa7905f1bc06bda15dfbd687c038c9e154d63d7368a58d391132d8f7f15b45db10ff45bb6b558701264797cf6590df6e47a34b8807a570d47ffc0280aaacd37e2dd799e81ba37a1f970125cdf09d5cd7311d7c69027a60232afa470029015002e02789edb76bb0cb68a66a296a9485b4269c47748b0ffd1d95771932694dd76acf375e45627c52532e3c68e0eee862a99f110ee75f88be4c44cefde007e963217653993091893e519d784e2760bb2edcdf3d541a70e6a3bac7e828d0f4ead068a916f73fa0e16ab192955d763ffa7a8c298217d71405873264cde267d7e1b287d90655397a12904c3ab3f613548e824beef7dd206f9056fd8e4bedb7de19c5a55ea5fc9b339f2eaf74156600ff1e7105db6f578a04024a930d699b34296ea9732e0bc64b5c2c26d5279b084035a9d6215442f992f6895d367aa172e87c8290dbde8da872bea2f928f57380505b35111ae17faba1cc53a8184210ba8e6e1c1b2a8abbadc0491664b7f1bb39a061ac345e36cda52882c582c5caac71265036d3ccb94dc9db4191d367854b7a915441d80bc81584ac860d263e85b368d1ca03577aac26f57c950ad513190fab87cf6234e14791b226479d9b763e7307e0fbc20ff8c29257e7779173d9588968a6bde3fa76082d380efd1e9ab496d9ad2425fb7b842352e567fe723ad3597545018ff3f8f16d06ed605d7ff770aedf543fafc400ae974626d95027daa3240f027ea89b0a6fbf046cd5873ef874c5fea5d24bbd566016775d3402b61943c93f69a39b9ab29cf37870558f1403a0486ed1453034ab3ba414750bf95d77b182f80d961e1d83977720a78af476a2caf516d339659ec526ec60533c0ce0dd47af20e845fd3496a2c30c8eff92a0a6068fbc2701fb1bc0ba1e79111ec13f2fc2085e996e43be304c4abbadb9c18f5ab246e9da62b684368a75984c566fa0b74a75cfb8241217b3b4d0f9a609936747936fe032faa3a04097ad53118c9fb0c0088fc08072af6e671e58f6dbbbc2edf0f3cd6f39381b99e417b93ad941d1e43c470660f4027f411bf0cf83e722a1f5d968dbedad3128485e6f711ee70a93a5a56421c033311b63084af607261cbdffc7e88a9650781e30183176f1e50bd2a412d0fc26af2570b8da25262bab3042157264968343cc9b2c8e38e43fb0fb78fc8ffd4e794bbd6da92f819131b3254dbe45abda362c2b32c6f6382c9cf23dfa2244237e205c816fbef71444c84072074217c1ceabce97b60b3a83efb0dd9b27ca74923d70a0373c7e8c8748986f3629957230c0e041a311815d85f2dfd86d2c55ebd321f833134b627d9657f5dfe8be59a1eba8bde2ee6f0c2650b4a851e0e88e75e62842b0c6bc95954f058a7dcf334316963e62e93ff1e95ce57bdd14c6da26b4ad9ac84643749fa7e3e5a10854eddec5da719a583dea04211d689ca5a36ec43ac107280eb175ecb8128378a8b3cd87ec36ceb705216f22614745b0cdcc2e03c888c8463fd165b7124fb817d6d7b308dcbe31ca5d3d8a6f38e027ed32e2f01c5238e349a00c9c11c4568b66a935aca477692411450302f449de7036860ca278f2a00aa6d6b6a2c26571628015fe8458189ac43765b3864f03c6d7cd3f681be9a99ee2898416843bd04bca520bebca0c04d68e39d3a2601b7695a9044c42c8177cbc727c521cd901ed8f60a6856e5411df79b8253fb102fb3bd779836fdcd72dd38863889c4f850e2809cc0c5f70deb5843071456ebfc7d516ccb854b4187ccd525807c95cfc600eeb6bc30f25bf48a8ee59585877a9f3e9884c6303e58e5f91de045c1374ce477768eb6cf466107ec9aaf7b86b69d1e070478fc28248bb57e1b2ef93dfaab5b43f03e7c6e46acf2ab64a46e2b040db8cde3bb7183102ff9fd5b701800562ab3dc52586d24bc8008705e67b759cdce5a11478cf3db739eef552a869fb6962a1d92b3bf287fe28e4517e917da318d6a1717864296180f1be33b1efc98a4423a13f14e34a8cc04afcadd1c1186fb2d52df5ddcf6ad55d1f87e21c02fff59c1fa8c17f6831d45fb11350ef0adee91b21ad8588464a19048e2916a97eed278eefbc0f5fc56e5bedc46e98e6eb2d9f5897a649c1d08b5a9e2d43f6b07e5952c71a5c86469c7870327894fb2c5ccb461681215f7b49d7ad0e2bbfae900d8acbec2bad3cda6576688f991b64118105a18b312f6206ce7f7b3092a155b8b7e10fe3cf14e02412be2ed85636e426cb4e0a64e71b450da36277178565eadcd5a79a831e8e6be1f80ac12e328666f9c2771aeebbae6658d5581db2a7f588cc856cd8b604d37d0a57a75f5e55f2f89db4f11a9c56b91ffda940c5eed72c023f87a53c7e7a206d398ee3be14b758d8e8b5d4c4ceeee1a45ba5288f0297ecd109c1bce2b84bee1c830e1d9587f2dd2de94be8420a4dd33fb59f5a94dadf0456b46e321f95000af3d523f4238ddc0737a08fbce276bb07707c6fd11dc43666930cdaac40b9d06f8b75437a5acac9f535e993ad181a7024c8b2f47fd1bca4cf8801f8bf2fbcecab0c322be3f644b4c20929ca41fdabe9814839f7746c6952e6dc7177413991ec199af4a8c29b75d6a3d743855f4e3b811328f7e1ee13c10a1aeba4e3069674fd8d299a1359dbefcd7b9d27e22227e684ce1a511b9cd59c61d53a9d10179c48d88d678652fabcbbda74cb5fe932827a38340a3e3290a05bad987ddad18c0b95dc5a5576a873166e7e4379c041f2b5ffbe13d27652ee42c71518020db8baab31075bf4095c3ca15130f964b86d027d99b5f093cdfed0b2c604002ff2d66f572148b6169dcec7119980573fbdda82422f24773d1664120241911ac01de09592197ff0643a3c6abce8125bb8b09925ab35176394bc83d250d4017278e2e40f1ae5fd58b6dea4ab7ad4f1bc0d592f513ba0e85e969e28daa7bf07dc0f0357978aeeec906fe040a481762b1ce55487075a38145660c5806c63b40443b1034f9cf5b94a508248f71e90c3395de34398715a6d4b9f2be27a5daf0bd861bee18697ef348ce15265e8488e28e2defdb7e68db445b22a551ccf9190c5d3aa49342d7c4a1ceab280cc932d05da0c99ae92382f1a583dfc7d2bdb166a627701584d383e869e051cb103e6068969203aef9f0ad266733e3acb3da424c020f870b73efa4563a40a2a2ecafa53dbc922843065a215ed44d9099023a1990c44b5fa1298a9d452aa4bd21daeb5b128196544cb46f2ea7264054e1e6222988a6d4fcace07de375bf57680bac580fa0d66d60a2f7e4b5e89ee3e4ba7b640b400345d28f49f39afea4f9d9086dc1890f6c227cb5b2257ceaf4e039e40519d6e200467c31be8efd31d1799b71ab85ca946f1ec2a910a8b94d48ac212bf981fb36db853907a010ea6b106b98601bff0db2d48db47b886fa0c89e0f06db0b732ed1ddbc14ea2196185b594da9d7c565a8fc063629d7d74e5c122885c17aa90c3dd4904e38422841174bc17c9408d9fc5dc30b90896e87be9c2a87458b023d14387376daf4c040789f9c634c28640bbc6690468b41bcc580d825809e306283f71a6afa9fa8eb5284520b13b1658a65f6cc7eb56e8a876549cff1390eb386230b3109ad8e01b7a9a10b104932361771e876d493e84c11e4cb6377ee1623b0a8fd48de1b30992174171188657d782e28d6bd8d2db9d3cd95d678bbcc337a6e80c6e30c0608a3ab9603dc1fd8b11e27e79fd32877edb8037bdf7aaaa8e04a7d52a95c3dafb1b0d094787ed5b0c26dedf4c65c55fb68ac5dd38b3811910e6c7090e8c71964dc9442354c025bd646426eba67799c67b1e04eca3f203219040ab7cec2b5b181a820cb8fc31bfd1cb46513d9bde20b9ff30181e76fbf225f6d79eb8bc1efbd139a761824a737d56a86a868e1471c561d83617a47c0a7fcac1e7818c801e7d4b52bb0835e378c323d97dea9cb9dd4cf29863908c11656f3e36a12e1c79a35996ac73b832dd3952afdb3746052b37a982285546adb2bdf662d7744b6853721509e31b338eb604bcbc7688f6e393c4ecca34f218ced2d9513dc19e8c8c95d6021f94db68f0c973bc05c09e519a576916e46513bfbd2e1f046432e2718321ea3b9b45a8beb8e7926ce7b3336480ec19279c3dd998df8026c45656912b53f993e5d33827d0e03709088fdd2b1b00228c8f51c548cffa3d6c75998a3013b569382123f4d30c4c6c6271bcdbfdd4b181a76aa066aa8ff57042bc4745fb2e16dbcfe1ed4f2d36adc3e6adc0042e3dc4f4bb27037447601a8b605260617a9434e5664bf2b79b44b198370b3ff49b736a8c05bf854c07b5f5189a9a6c15f80c7a289dcb4610082156311cb72557d957c73e114bf271158ab0ceca1ea85b8c7e8da072300b5180e14fc2dae641b53151afe510db7bd0ad7ba880ec5e0217d84b0dbaf614b9e0de35a3cc9ed551afa437a10a5706082ff8816da2c3008e51e865716d7ea8914c4d70703ebdd522863704b9ecc65709dd34ed8ce52406569b1773198c4b4a3f2563acbd7ef442134381b8058e55d8411ff9e53455ccd07ef6a09caecfc0aed28810bf7b2ebe74c14118352868bd103f46cf6004523848b52f081b869d0fc53e21db2d7a0fba31247a38a0bcbdee88bd022a38f7dffbf77d7a5672526f1a4ff6a564ed7d90e15a1378971ccb6bcacf06ab0946918e805f9a97823484871c55f979631f8d8e5844e357667aea87efac3515c17d985fc22fc061e87dcc059805075d9967612c8519059d66a8dd44c71aab55a39850238b71a1c73c85f2b4dc2aaeffeea5ca2e31b05f7dd0c4d8b847b2b6bcffb79798c5897a939224e12005fc7b294dd806be34bd4a29ad4e9e30ce7be4d601d075bbc4f410b4abfd5c77097c69e4661ccf163bacca75b2a5779be9d09a61c79e71a651016c00f9db1045b7942284a520c6f96f7e10e1be37c95b18d0c893c7aaa10680cfbb248a4cf301b89d87aa31d4ce7a8773d8494b3b5ed0f5be552473ccead6a8ed41c58af0c341999671bfc404d8e7bf0acae63698237514a4772c3e01e4e818083c1081ddc6df880101c32a46f2f5ee6c37bb99b54388c1801ed287cc1b28f5228b93614e46a0ce7e7985803a3344d49be1ca6ff5809445a0dff190b4c29c6c651848644c9f1329ad25f7cbbc8ae7a14377e38a281fa7edd5347546d88e521c50e1e087c188d3b8b4f29d05c06caff7515f342ec5881243fd6c857f0ad7c8cb9827c9a74a4d6d5ebd179469411bc5d72ac9a99936b76302290aaf31bf667be193e8f178847eb372ec6b90ad72fc1e1f2d74083e9a3a6caa34017b9551ef6c3df0155a9c6116d80a36489ce46890ab9681a04a530a2d218c90263bb0d62b47f553756b7e189c1490a1f4220e20aaf209392b97c22fafccc91933b6534283b2e459b6f78716249aef86d96ff1deaa045d031400b8e99aa37dccb1d428ecb577d6759b10de4d1b74fedbd5e7f05e44d6cc85bc2b7895fa8bad6bd6e3aeaa8b71e2dae7c0d443e4aa0a5dc80a010ff77742c6cf49aa1365eca038878d0183e2164b8e512b05be63981f515255c81893f7ef1d06febd9a28ac844e671fcb724eb0326f0405c92cc588e8b9c51901b0e679c803a0a5cf69c1ff3222d04df2fb91892e768010e4fb01c8f6c063e84803ca22ab502c321b1d5d9661dde49f07320aa5775a6bf25dd6969a39996b071a655e094bd3d90fe3fabaa68bf3141a41b4de0ead87923005886b985630300d4f1694cdf0b9807633f42fb85cc31603fed13001d969080e7be1a6d1286316ff8fcbe3318c46b7ebd5e252dd491536043e4e6f7580b84d9b8ab7a9cffb66c0ee270b24591cb36a64488bd7ee73cfe852d7353138df48b76da0ae89dab413f4acf5b20d55dd356254ff7e914cd0424d9c8af1a388691c071d08fbf0c57080784e262bb4b56d83c94125d1a8a5ef1fb13bbe70215f1f1f93b27110fe748054a413128b66e78462674a2ba7cc2991e15624d185cc774cf354746d867154eb605e8b171f1d2e101b679c8d18323800280111846a9e3bf73fe40ce410039099eb727df77e6bafd19f0624f0e867315c19e929dd43ac810af947f00c0a6f09adc8a2003726641d9c822e1b4b75184595cc0cb432a05bc40d03589f477e135e5c066468de2da057b31f6a4636cc829bc8dbe85a6b70e48bd03e9fecbc2174b30fff3ae24afb341315a7b23ca6b2e0a74c76a1cfc26f745e4da97cf062a95e4c3ab027fbc5d642186fe846dc0e405da327578bcebbbdf72ae44f1be56ed857437a9521e6f1a2e33362c9426a7b5e1625094bca986515f8801a9ce113fa367f6485e6cec0f074c48845530f083e41991bfbf1361290552714b0f6da2be717ff9f898ced9cca9c508669865f9fbe808ed894d36fc3a68bc933c27578a63492854f200146bb589c1595c3aa2128b790aa5025531eb1c0ad03dfcc019d4c95181a917bfd90fac6733b0aa3333da753220d3933a8f59284438e6282862359b35d1ec343bc0896a37cfb38846119a06474ef54d0a4639d602a865258dcfc1391016b813690e76222002591ef8d56b25eb5626b34d0a7d3ef411c82250919b209bc121f63fffc6851fed62cfc054d61fbb1ec16b016771febc497299412423b9b5b507518d0b75a07f4408d6c3e542b8efcbf724e47680981825d0c382e739d8345f0c13b1c799ea2ce1decfcce130a4832feb04a0bbe161fe745581bcdd278c09b1a1f7cfa97060bfedc6e0a71a5c7a44c8fe52f3474fdf2bcd4e811e5da2f4105794a8ef4c4367c08723a3b7c666bc81d4542adfda2d862d30fc22dc16802c29a3143d809e10a01ef83232cf9da66430e24c90a8f795c684c64414d52f8beb81707cfdf5dd9d00ef826cf18b7d723a0dc0800564100ff1410f9655396e7aa2a58dbf9eba235e493fdc23f8e69be841523ce6c7c9c16d14dddb3b1fc1a31fdff94b967e3fc6424de5a85547abd5b1091f98259c9f8ffdab5695f1b12cd3db9f0b9ec5ae174028acbb001ae5309ad05814c563662026f30bcc58caf0cf819c76e9110821393974471fc59fea621004e7b290e0ad8bb850af26162e1d6d6cdab20691fa0600cebeb3b75195f88886f01828b088ac687b9d8d142bc1171815d54a09625ee7de429b7bdb6ff0be374750094b48c63bfd8ef2dffcb33696ca090aeb95861f37a21390ed5b2bad1a1b04f6f049580d5e9a710ab12a4440d252d98e2cddcccae9ddadf2a5c76918919f267d9c42e716d55bb99704d9c933f75c88139ca83c5657211c97083a6f3d8008b74cef83da3dab828fb68d70ecdc511c1a5dae3b7b60d79ebbeb5e260f356097ac9f5faacc18a13dc7714d37b7e920c870bffd53ae762b525daea9d6f98fea80701a38ef92a9b2cc59acf10ad1e9212055d5b378b3144efc31e58e2223ba2c6123ceb623b46b5095e86e6753ae59d3fa99f2a3e263282b8e9a42085b19ed06a5f5228e0490c4bfd4929aef56d2c522835bcb1150d07ec644227363122a3e81c88a0702e40bf9130736385259bb40224c70181214c27b18b1d2f16e7e195a8fa2bdc6077abf79cfb658854992e7d5555cb048070457e0f0ac7cb8c993e90f5fe48fc3b25faa9a385df052347cea9b9fd11a94cdae668ee66dd9a4512d3a0d9cb86b98ed612876ca1893054a448feca4f703f8a42d294714ed7a7362cd4db255b172d0455decf97f3cfd0d6742c16dcc329aeb34454903eab79f342706a8774166f7054f5155c7526eea5584f8b63226759bfb92772a58199ae8eb8c38178864b99a4a2bb28e8656ed09fc31cbd6f1abe99b218479b6e8567962151c48c4c56e7878203a2bbb03e8301efbcc18877dd2240997f2222ed9347544c7286c02963efe93bc4c3ac1ce67a073fc0f65d474e85dca29dfbec79a66c74d9da75fd54466706e9ee6ec830bf31808198b5121659beb0ee75d9296f825b8f2c741f62e600ba6f8cea157efad301a04b019f37f09777ae7068f8462c34d8a327c6f1991c15614460bf56aff32cb582736ab2cd81a37cbd1e474513f4e9dee94ed06513b5b624ccd91e6d0286895163d77759c8b9e9964908236602779fa3d5c890a2800899961cc4fe431e4d91f2aa908ce347a8399f1c3fcd2588552e334cc129ee033342ff8cb19d0273fe3070cf1fd5c927357e8b6e88dbb62bf0a0f6b69d43b76da5b41dbfdda0b61a3a26f9b609a89c68b34268fcd4e381d79215cc1ada0c34ba42eb99aa98eeb2d4664163c76bdf558b11082cabd75fcfe0c9857e52b782090dffd00155987d55ccb5ff0641c9c1281ad354d7571bfee454f5d8db4901446b3e643cb7431c5453e2944b9017ee2c4650090d44c7d4c7966c7a658207fa2c0569249e0b66ac39052a2d997efb6e652169971b19f9b04c095521541fe7f60ec7ea610af4cf7f7e9b10d47f9dc2976649898d814026bad01c264acc3722e8da28809b0935a5464795838dc320ae0dd4c6273ad11c2644ec3728e8db48703b93c702007ce755911e1d954e940ea40035b1b8d1a0c546036e41dbd0ce165e6997b8a29ce04c04129193b930fd084916b195c0339890b8673fb30c520f3a6292f19581dda9208d5719349d32a7d7381ee395059728a4ca868986175cd2aaf1fd8b52dc30ecf90c78b21de37bbb18e480d8717dc29bda2906f69e624dc780707cf37a41910974502df86d9b83b13dbf9b5ed3c14edec5a470614f3c882c0964f61b1035a22412bda730b4aaf736d4cd44ee70bbb3e76f5536886beb02978ba1001aa09ebc84a0e975555270b8b6e0b251d61b5d9b7fd81d878f8fd806d1000e05f27e2e22e6b6004a7e769a332f0ce5bb5d5aaf1d3b264f2662740ffd2d95866753075e424a20907d5968ce244b75a272c6d7c55a7f4c4a6a13300c71eea5b2f1e3123eead61f57ef31c7436b5af1f7764c62910d84da96b3b9b45663bdf8b91ad5ebf11d4b9d102942c655ff834899305febedcc20fb8e7d0bc57ddb61f2aceb232563df9f1fdcd18ecba1a89083d15f56fbbf85501bc11ea2a1377585b9586d2c5a66f56467b6946d94707dd1507411d76e77c2cb020b9db388b099dd1998ebf3b251cb3e189ad977ae4f3ed28884ff34f3ff18559803d0f6a62ac8de2c1d6c01e80eb5f9e4c4527bdcc2f32036e2cbf88d241558c2b1534062800bb9a4d1db8331e456380b18185b3e8f351c1deab40645014cfd25d59c9f094595fc21764e44f46e55047b4981a20a0f0cbab366c89c82c974a5a0170a3a0038b5a1702a23ad04bb82c7ba7e4a450f28c8c6573165a7fd80a17c178eeac40171264882e01b3441d91b744c31474b2ad21008d59da7a35b97bf406e2ce2b1f20233142e5c88eaf74a18c55597602ca6ca31434419c0970b0c694ca8c066e7e433c8c8034d74450c58854ca34cd53ec4164483e61d9f37ac1bfd7318fb4448bcfac96380b094973d3adf876f0bdfae29058e7d2e7491e95a49a14a3f87b94986b4a4a1320fcaaf2ac4b9279b5151b374d5a6843d1a87e1cfbad85cd834ef3f9b8d4f64df0735add822988033b0b27400999faac9788525b9f9bb60818df1178316bb8e20d7a0fe9ff1fb8626c9b26930f5e5c2353275100d0970e6c4b14e6b2eee14dbd9130997c5b64456f9f8112e1b047ee3390643b00ad3ca22fc11862680d44c71ab712500ab45cd53666f0e99eb59c37f9a7c854b86b16a5a9d54713a29caff92cd5d545fc28a62c7daa1ab0e9998afd734ad77940503075f0bf96d5174eadc0ccacd1f4970510e36b62d487723418856e229b68dcf1c5e8fe86e93f8920af8b3453f78c36bcd006a453b8412788945ebc4e90f326b8388e98ed18050df813100b1906e647925d8fa6a2f0e6b11f8c10e7ea76f2d48f803259df541355f0ee2ba5e61284274711cc8210b7fdec1d8c0e15d6de5901de2135832421b4b504040dffaf2471b109d70e8982bdbd585a6ecf3040b37e3811b20bcea2f10825670c69cbc71002eb3142db32edc15f821f2892ec345baad45a2c624e521c2daaf512331b388706e5f781936145229320520c18b39aab99fa8db112f379400898635b0bcc886423c34a5b69e387f9b577fa376bec78319311c647eb60d0b5fe237061ff4faa2b7edc783c499ce0fe9123f3f4c83660b870a2102da6426ae353913d6fa26243eb141ae02609700f2180b80dc588497dde075320464c2a3f7cb0c4abd12e18b68d41e2e90ba241031c25e2492504797596ef6a0534cce648b773d97902601f6f4ccce28bb057f01a913c6a8b3c56b128e14021f8d41eae3ab52f7f7a55a2ec63e3f8f90fc1279843169878a85850444693f2921a0b038cb6a78b0f50d7788818455aa2a8e253b331563634652600a021f0e391610eb5a017d2536b9b2f516a43e56d6d50eace448938747ce93d4c5c4b4d27af7c2b049f52958df73c9f55c48973ad24d94c65660c4b5eb0c57498f46abb59860ccc4da48b1cf746b9b32468dc8b79d65e65f4b3ebabc5814cd537ddd865d626af34723c7e5b51b8429329ecbf4ae2bd819b2528d653939a8b2d672fe4a10b240020ad1fd43116813044ab421c046504afc84aea52b8d99b9fca57e15a595d00e6a6b46e6f7b89c81a7ee916a511fd654149ef59782011081a10c62eb458f37eb0a9b86012394a05bb009335ba9ef224d494409b8a7580a02bd6868e5129f0842859950008bcaa5e83fa95ddc718e8210608b02b16829d16489c71315327d4fa9a7aaf4c75ceea93ff6e967ac98fa0d28e80c1f36dc18a65eba03c1de5c8631f4b56aad6680dd1f618bf29e8a3c172014f4d566eaac712f88f9793911247b8ca003a6e6952649a5223189a0bb9ab4a32a8cca405725403a8578c8ab10a918a925fff63c7d750f63632ac3c64c3c32238bd1ea17a6baac0c6b147129e035c6519080f1e698f8ea21064994541bb6ce9192f0312a9a6c1891c0a6820911b6fea45942a01a5c4b42bfe112709f8bc17c496e46f6567d57772651025a7cf30b84cc9680c4c9b68adfa31ec08a978768fa419ca80fd3a8d91d615c0cec961d97cb32631ae8602cd3f79c310c62b29346b340e63f3c8d2637f1da1ea48b3a27a48884928674ae02985ceaa90466cb893f725fad5fe603678fa8ba3cf0f045da8a1c193224dde11c942f16d3a43214eaf4ac57dfce7b5b3bbac9c03efbeaa13f23413f73d12d857211647f94e4ee6300e80bf2a9841dfc6024e7a409766c02b2017dcc234048847441db20550580c10f10e7db9157dccec9a95b361f60168d597dc1f6a1fa09bc8c36b780506346db05376af49b36ae6047c845c90c1c3eb296413fdf8454c9430d4fa6a0b662e85aa04a0ae921f7a84a1c0037ebb96972cb105812d0f34c9011da3ce733f2c3010b0aefcd42fda64c8018a854ab80fd9f7acb4dd598d1ef6540dd69ed23f291c8eff1ffb009a50f0afe23b962f0991a96970fb140e6859c858c335b5dc342715ea5bde334e8ba8697d5488a3f4d124c4c88820720bd57b25aab1f258958ca37904201a20162744f4c600186f3a742aee72126ed971876debfbd5aef3655dad31ade961b5df68f125d8160f0d0a469eb81c93e648bf4304eb14ac4d24b49784f4c322431d1d66c7073f93772f95a008a13dc140723d6648679d366db116241ea5354a5188c3b4b0f66c10c58942e69d300d8f6dbf730514a56cb19b066d1e540ea891f03db72c0ca29853f003bdca8e400b9f7c61802f982fc3b091a1ea48a57be0b2e068586b1b10658a85d51c1519563f1fdcd67dffbe32448669ba02c7de6c0b3a264e4b509f54dffe0d3f872d263c46cd11ffb52998aa672916acaeb3560b688192408d471126d88843515d27cf620a04a019c96fb9444728c22ab0f5fba3ebac190dbf2bf1429dcdcb3801ac1835e78534de003082cae7df87788efe3b473eac1ab843f7d073d533047f64332c36dc88fbe355834b47e13240156bf5d4e02104fdd663599ed34a7bd9c26f9328446fd5319a20f4a80a274abcf6e7583db243bffacf902dab148eebf756dbe746815199a0a610c5aa245f556f8e61e27613b9e1e00e4e622e43de6e2a0b4a2959884de4d3f8438ce29eb7d7380e8a34d86bc8fd96dae2e0dc0a36c7e9896a87445160f4062d81b4d12248e20268073f2d513a99c610f62e1606451ec5f67360743be58861a8b65c3c7a0b93d76ce51759671abfed789b406862273d247b68f3519f61f1891a713cc980bd32da67baeb0ab8545a5b4c79e46edb18f94bfdb2beec67d24cbb0df3bcdc44e03c054e54a1529ad52297f14946aa85ef70019511608a1de191add029deda3b35e62d8bff74e637ffaca33261c639b62f87f6109e28c0b72557eccdc36756c11a5d72315ef62b20b3c96a41cb8c9b6882898a8f8d3f3d201fb416ddbd6d275ddbd3ffd42955f48191bed4623bf278cc5ed3ed9a5e7e2274fc7b71f4298f38f8a861d092a10a11bd29262c08958d34050484ccfaff482e6d79c517b3af03876fe1d8cf8d33a53983376e32b1091e089b9152451568c0061cc4026158f1d8ce3f3ba3cec468cd088805a6226a0f8e1fa24c0cce0a816950db626bd820e8e1ec19ea2765c99296f3fef724dbec527ff1bdd8ae4308b820027e611fb5bcc83214c28d33e068c1dbaf48f219d2ea441861ac2bea9c4e33f242268fd7941887dea4da7d15808e314a960c83b6adfa2d285952689fb87cc3959c2fbd804140b58297f86e506d4c0e4730dbc4299e73718102500a95e10f10af4dde51d059c2d0a62274ab020c867a5c4ae911362d18ec3ec986c48ce82789d0e48ff28cf4369ba118864425674edc1da45e03997249b92f678780589950cbfbec7c0f6815e04ac436098035c975e75876c07f1a4eeb6d40c4d4a5ca1a50bd6be57a756134246a0c80366e212095c86f48863a2317394e087eee44d56d2f0ee914a210d44e12945461c26225de03ad0e9cf4ec9083e36477b36d4575ace1965ef8438dfb68b85535540b2a419c97d06d8e82ca7838a4397a461d8f60d8c620a96aad36fcc06ee231d16bef89c8efd3a69e8db7a11d0d1083fe1bfba775db0b11e65af3f39921b58945f9d57434b7ac07b3236287ffafafdca7a6b07c3ccf552ad0a97154b2e2d691ab1d2ef88a3d81b1ad75260378f538a616d0e31166903806adc79c9afda6d76c2363b9387fddd73f6f7518df195ec24672f07dcef973deba81b95e5f92e98581cddb9550c1e63130a6b2924927770d3ef8db8e430ff47b9135426a9dbf6045042522403d20e6f5e7114565378b7c1c054aa0ce039a1f6fb6477bcaca12e3f6f54c0e1f1ea298668cc0a7eac65dab20b92ab56c473e94387e4d099b9b220fbec243e82530ab81d3ae663c88a726b1369ad5ad7dc5c19e9f7e4dbe4366b2d768be9285f4698d4786606f2367af883b91e287d16accb6fcff082ffbc16edcb571f6619d8eba3909885cdbb5df3f25052a3d050f3757c0931bbbe4b7dd82f305dcb5b550f13addc8a74d0d9154050026afd81bb4b18022a1d3c21297b597d29443364d06b4459765f3603ee922fc43a749a791f488eb7a9dd542d6a8662a3f64bd37ba7a3859353a9eb52fc97c0ba3bc4d2073d79000fea82b8d8c43fa6e1d88293a865d8d7361c65698b953f05cc823e344408e6ab8cba44eb08864e0bfb1900635a0bc4181d4351708762d724685ea660f2fdfcb2fe7e1f4190d94f5a7e18db86c8c8492a6efd6b4cba58e37622b0c3b4b6956b4370190b5e8a4a091100741624f341e0715ea290426902451b7571d32bae15961d821af23c51f27a141b9411b0282eb9e08f3c73f88029e06ff16d0427b736e84a574ae403c1c3e7f663d29a3af17b020062eae2c17c698a9b97aaaf36536aa0fc0c5b463e8fd78408c9836dea77f23c33ffd309f48f0083c1481f7c80c69485a1161dbeaa1969d33dfccb0d5e2d5bcfb63208abd522f227c150ea171b090b8018820abc1f990d786e0539bd71ced94e9b778009336d5dde1dff31e256ab7942c235c063c9e1732849bd41348b7bc2bb8b373b045e8b33cc2eb74517c85d3f2ebaa1387ec295c66e7609928f19db0c636e611789ee785777094112004c7e8408fb6398ce5d57de3fcc3ec499716be864adb645fb958fdf0ed04a1a70aa7a135aa3aeedbc131a0de89b9e5c44fc58883251e0b3d70801a5a517ce75365275d1f4055a175cc21083cdd3830b24576544b4521b085b5fac794b4eb872f217b60523b3a6ed2cecf0b7acd87af887d894b0727c61d44b59768f0d7e1e71bff499779fc2f3a475fb0f206fa165e6631a5508fdac1826650c4408d225415f61b0266f02b51b0e0d5998d10e251a078f046941c0bf18a96b25ab019f8f6e41a5dfc9870853ad927d705fb0dddc1cc9843ff959dd6bf6602fc49df9b4056e74241213bce8895338f1482ba2b4b972774e05a1b6fff6733bbd6a8eac3d9f4a00479b94cbe2ab21b69d7ce8657c4874118dbe766b7cf7521173fb61cd18be9986d11c104d9bd55e53b1eefcfad5eefed483246a8125b2e5093b32011954041ae67a435c4e60832892ce25b57c26c65d42a4511820dc46b6007e94914454b7a7e49ab6c33f73eec42a5ffd1b1823dac1151fb37b927660b07a58bfd3cbaf73b94da753c3ae5906fa0937a299baa0396c7f5bfe81efac18c4d391a7eeeb42c4a039749b018b286999af1e5b478455f96ae7f93f9da764e12d53a10fe619ae209537692eaae522a30ac232794a4474019b8fca3d13079e7b1ead2c212da04d56118f8185c0fd8140f7343d3328b02ad59eebf09b639a7af1f97e00062ae6fced285a09ac9172a27fa17b91e0102c580243d3074a17c195c372973e095a491c0f994e0d0d0c3455a43568c27ea7585e668996fbe52ee8a7beee97ffce2d2d9293d8b610dfeca0d6d10e3a13f081474a02fef302c2075389a82a9402f9d077206801ed823bad0c9b35a60c9b988b08cf0f644a4609e0651d751808317f143a1a01cb2b80deae813dd9b0719ca39f3e084db116a9e4407f378d1227682584f883f172c2ab9db452312d6d4a389cae89e94d4e9cb84105dc1d64753f2214c8a8b14c8027308607b90f7a52a171b6e337438666ba355304abfd3b7cd191f01b674e24e5a0a79c9f70894e99452868586da9f6aeb1a2d3a9fe825fb77578ea419edcffcf60ad345cc737cd69226f06c3250e594cf671bb17b1fc8dc78fc546090689bbbcf860ae867d3d2ceac4223b894a6b0ea99fbbc2c2858fa8c91b2c21075de570e4f65058d82e744a8f126df0e63328478b705c51ade339d02c9ad7e17790c2fd4cf881138b981f9c8c989635bcc620e58d158d3b306f4ef59e0876638592f3de8e989b23dbbea60c4d420eb15ea420f7ac72d38153381f8c2ed6da5dfe2102c273e1837f87a206a72363f5a95f970a0a5a504c1441a1640d599d90d98171146853a9c084dec132ea1a66cd65cb77ac645b160c8d2c7ad3ee0c9d17571b0ea12263f771f1b85653e6a10a02736abb15651b5456a0df2c2e089818ada95f200c4be1720c39b77d317bd04961a0201dece3bdf9636cc171e4d6e7337c97c1b760b0ca649d0433314c49698fceb2b396728836a63fc85292aae9987f728c99b502088b79a363f9e8a352b883fb9c2941397b479e731aee27c7b9550d00f45427f4c650d1cf1bb59db6d6bd17d0a0aeb0e6493a39861cee12e10e89a2965bd006d0707af9d27c7f9847c4fb65062fa34e2235ab9483a1008ecad4ce580c52ae6e48f87838544bc9a13d2f4403f4f9e5b14b1b59a66dfe25650e15585a415f5852d20be2ee913490099d9379fde7a99581fe3797b4f3c75a2d0d9c4de0d4b2dc68ec17d01b2d2a7b69ef7856b8ee65e486662fe735b8e41b7b1a42d63c29d5933324385d5b597847894ad9e7b73b867e91169597784c9230c33c837ec9910b433661d504ea2fc010f4ee3728e94dfea3a0935eba6f6207c45e414ab8ab77fb8b2d671cd306e0e214782770186ca80684af0166250193d6f01ec0f0718d605c373bca72a5d077704027567a737080a86c952143ae86b5807282df0e0f31d7fda6cc7d615c71a2235e944d26bea3092a8252f2685c7b35df01c0676ab6aa018646cd5943edcc2423515f6d645b5f6f1fb60d616c14c599cd73e7dc1bf7b41b51db64a93beb7b1f6d58d2576e67175be6c37818d807099e0eaa677b6559abd3e0897af327ce56c1f076a04b5e48fdb0f4cbab24d439f0154347b8ca9bda368806c5c37ad84337f60e576a7353998150ce962f2b78085396b3eb58c84798421f646d871e1443326d17a80c5b37e11354f2109713b28dcffb746f7881bbd7ae1a19651d8f5e07f8c29a004b901b179cfd2bfd8b3f7090f00f29b5ec9ce3a251db0fe029e63bdb3c50373497d2d360f7e6b69649de749f93fefaf4f999153fc3dee7f0bfeac4733ad45ca6b5140d8a569974782f6ed684ecd8437c24bc89fc7e23a2c440448ca46cf80255d5951686731ff1baad467b30b10aa93b7a1ec47d4f99e32ee6deb83ca1345210ee721b0cbd7221ec0e7da8247eaeb5db0c1641815465bfe4b4d0f2cdb9a2ca6300aaf091f91dca3bf90914b2ba0b35edb7fe1a4c6989b22f1daca70d869a733e4826e4b974d3aa4657188b639fbaea9007c40daee0f401c7e721b6b26b289ddf6133064f826937964b51cee70381d2d1bbfc8d35680d192b74ac0ad074e2c98ec19b86537311ef4a93bd087554c21699a2e420eef34d8c170ffc7661f44aa6f086b7b402ca4303af3be19bdc51a6aaccd6411c0ec19a20a4bc14235866b8fa05bc24ea5f5369be4abe50b0e74ad13e00296e0b6f25aa5cd5f80a9a4d4fd01d1835ca6b85444ba2f0e114eb4fd53fe4a1f530dd9609cf45cea3910edb88067282246310e4294af4fca657675f40299389ca17bab108e3c01653bed904a16d3169caf5a2878d9155bdb378076c9092187232aa9c06f461c7135722af1b67d75a1a517e8a0c757cc1d6cad7bafc0a0189a865b9b5156a0e6f5f7f03388dfb9d11ec7be568cfc332b547edd254b0364aaa45ee466a9b09143fa0a088d226804030276613c3ff538b374aff6dc014c3ab448c485ebf44b68c5444002b0a133f75cb35b4060c865c156ff95107168cd8bf40ed516471d82973ffb4ef4fd692c3e26d5111f949b962ff0ffefd9f0e3aa8d8a82e20cd67357e057ab949344a97d2979f7789cec908843dfa154c668e9bcc0e25c5c5d0a096f25aa62f2075bf35cbf0fa2a04e1c922aade631e6124784a1c1073a0b39c0edf94c76086ab063572ce0d9cf108e4b2097cf5870e9e657a8e1ddd0fa2a3d38a54b0589213c61339cc30f874ae4679ae1e5275bf154796165ea47676e8f16c6eff4391045320296194788157748d2f8657ffd75ee57a1930f911b3086ac4bc49b66f530ed97e4e8029a7b029e37bc8774d8b0d8cffe17d35ef817fefe858e4fab59d0f82368286fdf8ac4ac0458197484f8896d360d700f6edcbbb36c66a37802277e92ad7bdf82fd89b37b8c668475300600fdf57cebab182b7beb90d0eb531e2982438a8dcb3ae037b5ac0655396b3faf43870915bec9e047259357259598566be46d8913e64917b1eceb37aea4a9dbd29df1a3e2199d0d78f203c6f11756e5e09473ae212dea0b4b2d5106484d176617966cf985c94f915f56a7b8d26d991cf771722e3acc05b3ef9d24994bf10f91be68d0a1bd7f0f88703dbf4e3d0cc65f1bbf49d600759786b8292c76eb0ed9ae40d81f1cb1f1182cb9621762004abf0fc08976db092f44595ae0e3efc949350e03da91c90e7c4d680108c4d66ee2b9e67e187801c5454856a0ce2823733417e3220cd72a080b1eea53c08cd111b78417eb0221c981054c55f6a8611e1bba5516974178f17394b47060f5c35133ff6b012c5e9584cacf17174fc99390c7bff6822c3dc7b638eb1051f58cabbaff2f47f40b728d5d13a696ff2dfd4ba4e4e171fe6697c44fac944db0336e7d826d68ed8200a89ddbb22e05ade62b0dbcb3b681817fa05afafd65086e4669e7f87b90f516a3a040525eb834863eb695bc08c075dcc3b8eaf5ffa331a8fae653003c3bef8e58889df694c4d128267412ce913519882ff094562e0211ac453f3a620f8ff277654aedc1f67bbca03db3c550c6862888882452a0608aae717d06c74503116e693192e6ede687bd1ef086fabe8c7ac927050d6af1a4ea6229e3b9d3677323d2fe6e34ec28c6a99fd9e9a4d04cd35ece3c4446fdbbccf1a147bdc9cfd3b01b1671e64b3568d18a25b0fcc12bb4cb23a3f7c6afe23f7fa4cce3e091689f616893d2c96af2553323fb404e416827ac5cfb877d322de1e27af0e8135626dc6217c5746bc4853e68cdc196225cda3d6858ea4a76b97774bb14bcdf1da4e64030ebb06a4ec4613e25e36e6c9848820e0a66f2fc3ee24a4bcea8f9e289fc0f9c1e0e94cf00884d8474797a71d211123c16c82937d857aa43d6b6ba28c1b8860545419bb218dcf4a1ebf99171f52e0015ddb74c803fb300fdb055805c14b6ca590418d7da1a7f92cb97a06f30c9f6a662edf551f0013a506f05f74f1d3b0cd1e1cd9554377355aede08023a5645123b1a4d2ab26f2df2d56d10b0509ba4fe6e80b57de49d09fb99b2f9fd469c2935f524e895dbfb052929c768024db88cd5499770a8f24eed985c724f33acf8cb6431b7fa834196fe236e78e4a28437a8122859fc3d8a32b5f491aea74d2e199cd1ad9034656146e8d7be8e115f34aa512e3fd66d155aa2aad306bd5962567439bedcf1c4b1faa70dfcb6045af86a55754918bf8fcf29b24653bbf59ee0d4502491fea508a7562c9d7852e5b030137848fe6fb8118a9f570dc9ce97b2d2e2360903d589d9e8f267e75e11a7d9657f780468655f4de547c1c35c47d39d8c204555046bcf34d0222c6f8b6f9201439a8d71ed71aa261bdb30daa932c3ad68aafad11409c55ffdd28a1e9a154580adbc43d92b1c5134d441a8185cce7b4ee2d601d33be2cbaf4fb8bc074befeb7a7394fb65782b8dea2ca07733a3d6b59c2cbd1a3e088fe0944d96932815a299ab79e6cf583b0a2ab0b5483134b45e42073ba7f4074367be9d6766aa4666c9737ab8ef8279afb43d78d00c5d1ef28bc94b991d092502fb9fd2e8ed92419ab563373471014437179f75e8cf519c7924491e6e746b6e7563a474b3cfba6edfcc64513c7b52a2dbcc8161545cc56a4bbe52cae41759939d9d1d471092200d07d5653556acb3ec439f203c270ce659093ce26d505c6738f088e2b7a7a26e6b4650d87e50e2c507997c013584e5172c89ebd41104247a4975fa2416d49da7655a7ad30185cdd3e96c49e54c09108ad14ece95998ac96e48df85c807d44dbc02e5c645cbc60f71723c9dcf90a19c1bb33c61507244e9914bdfbcbbfdc573262221f598524692e9482dbea465150938b1650ff2aac418b269960b74356806f37c8beeef2768cad8213b53097d5b5f527c7fc052d952ae324d9c4b42827b62c96b8a6bf308424b7467b1f7979fe1526c891e6e48726dc19caa5294fb61603c06c91cafc5940f97caa1983fd7dd1ee5aa494741e29897c8e84129d5035d54ddf8a774c89fc65456d8a8c91487a551228e3869f25031b1b51e2e2207994f60ed52f44e5ed4ef8cf4714b3a5e7ff192c713da81bd3f20c735c86d84d92daa09e4099de838c50c3ffba81a9cac92b1a74cfcb44daca01e89d81304b562770fa9ea53a013a37cb19f3fe75c92f8de9567d537f1f2400f9a3252942452ba8a740d169935a4280f21c0c5194966a14afeac41327114ca2bc136777f12f6705a28816702c11e17c8a5c6b4be9cd9946907d0227971d1dc8fd75f9bab2e39e1bc622ca8a54a3b4c7341cac3004f83667ca13654689a24677240362ef6568a6dc427180b993203fba238b8d7e31f435417ec168180df62f95117cb297059567ef3e4a3981d3b5bcb379da8b03c3c489ead000e32a814ae0ee03e920aaeec4e17353ce593153eb4d95867fea200a9c3ccc46cfa4557de5b5b6d4dd61867abcc8fbe3921df1eb994b60e034bbadf80a4108ca228bfbe3eb11ecd4a5cfe56723e48e9a1bc625bc4cb19d95e9be552a9dfc40d4025e6488e4f2128250b68b99232122f6fbc1dcda5e05d0858b729096b78a69a5acdcc6de278ebe013bb78dd33d36b127c08e4da6a2e42b90f7e7f4a80daaeb3c37cc4afc16141dff0c26403fe8d298e897ff256da4c08bc7cfc9ba310efba989bd4b88b7be492240db05179ee3021b81f699830e286030b3b948e5f51568692879772372682f8015c90ee8f446f43315830d88a096bde59ee7d8d32f90b734606682cb253c92358f37189b468af5546383e11a134501ec3c17730cfade04d5125c9bfaa926e28f2381e8b689f466d8dcf2fa32c0510231270b0d03736e6c60f14ac366aeb8623f47c70791eba76d6ebd028cc0473b2e94d46d582cdbea4eb822e02a09bb2e28f205c623f6a360430bb1d4e5f99c6e21ad50cc7e1c3838f7ebe21e58b4b9dcc02bdc762c36e8cd6421890a399fa282fae66d5e7ef543aa010714cc5b67eabc878f55739ca9c04719bc2e6878fee1bfa2003f490dc4af72eab3a11dd4d0fb129cc13f00ccdd9706081c862518c349c7c6b600c715e5da1e90635523fe2e517ce11f7b9d81b7b85ca210b9beec9c3f85436e3238cf236090a37a35e6dd09e54930523ae3be98f24976bbcec45cab3b71b85aac893d2b14d012b75c418231da7a8f08b2fa8d02ee802d867ccceede67bf65734b72b6ac443ba09a82c44f110c81327a9ed74dc71a4f424c362b2e4ae03c4ebe9307a63a1e46a7546ff999a36b1e1d90331fce5d774b2e0ec8dfd47eae4148b27fc45828b8f7775a8bd7c9d7ee4137bf825c147f92cee19a86e19a01e5d259999ac7cd9c707dcf53558073e07dc5c1c3eaa0439d013911a4b54e726ea13d4fb928a933ececba93a0d7d292b16ed9a3bb2ab09cf58b0376d2dd7a3731700e9eae4ae8d834892825dfc66bd166e4f954be72a42ea2baccb957c9db89c08a4242aba40700cebe0efdc2f5250be8747378756c7b071f54674acf42b18980b6c5f6e9dd59381ba985af129121a490318cc51ba4cd6e92a1df75e9b3289b1799f3671e7fd628a40923443c916c823351092690ddfd58ae3e814ea684571c01fc25018d2c399573d299bfdaa7da4f56d910573986e2deb3dd462a2927031b42d5315dfa543b92d77579f4f7d8ba0caa75dcb629745c30e0913988fbdf056a13a844eb40e682bd0a1e0d30ef6a787ee17e99584c8d15c5890529013a411bd4854c3084202f6e66b7202c3558a0eed6042c1e6486871ca1482e604a99b5a3ae57e96ba29e87b9269f576e66ef53abe8ef4e8269a5ff234c8ba08420fe19e726bbd2d1d7eaf6a14a220b096fd6b6008d830d555c53bc4feaec59e856bd31b687643b5de1586fdea136669f489e19e82124b85c2c8b24ba9e4cb809182eead58a1dfabc20a129c501e86c35b242c4c27bc652898c2834cca0dec8e90c8c057234fdfa46500bcbf98de8dac49c30f31eecd807e5d92d72630455ea2914c744987adc8b12cf6697cfb66c0f8952ff0e0f257e828f4124f326a259b701386c483280bed62404e4cdd7c9dc053a1c5a49f984348ca50f94ab9d0cd6c4831604c36447be1e5b16498e09fadf387cc0347761974c728f56e837b0508701f030a28e747c5f2842ffae504c792f1dc31791293f439480b88412a093d092ba5b6b4578487c162192b99f58382b7655431221d7cb38accbbf9328c59eb4e5d54fcc4f92406de7d90a491f783183f17411945764bdd33492e9c31c66f1124128e18878b3c92745eb6e12e31895f5618e8b264e2805740a95b91674911410b64887f2881c4206f491e6f8903ef052d96d2f529d41a34cda714957b51fd8fcf2e935f49a2a9589661fc4a31419e246664e4204369f672c177444e60e5cb523ee73fd015a341762658849007b6db0face4e594ce8ef81a18d4e0158c22cc5b37bf049e9b8468f6c51fc0eb7ecadbee741b2ce3735a72574c4f37fefb6bb03da186d9c0c4e2c05294622db19028f14ea54512472c84523a59dcf91669175e30e844f7dc8ae62c98ea8aa540a36e99f570e89e4f0235671753bed179fc7bc834f3661bd1827e34a581d3a20dd458450b60d56452d1347ccae2d1981b2ee165eea6350c9e66090630e8d6f95a4bbc0ab231bf052305c85368367ee0bdfc5cde74a97b8a7f3df5502c0bdd143abe4075e72d4acc03def3fd2a11af46339a5c8fc7f11ed3e4856d80d276629e3ff2db70f0ca9847ce3b25dfeb45ba09e8d514238662f955dc4ef9d531394fd8af631102288447d0eb07e485d5ee5fbc11902dfc4a23abf2dc9a13fc9af780110a160ccd60e8bbb7d69ad1eccdc69da7071e7a27c2f57c6734bd4b27addbca30c96b8504650262b0bbc63c48f42875b0cf78191e86474de9f2c70c00505940d0bb486a8b30f85567282cc137e5cf71d587f300788d12a91bb9710fa31920d0e14a8ceefa49b9a90f09b5b14ad41e011376c8684de6bd1690b51e38d1820a59b5b36ba52947cd326a4f49e9684461f25dda80129bfb945d115440d373346c2ee6c51b4d551e3262d90903b2d3b2d6994b87173a474634b424788926fce1029dddec2295c068f70233312ecd696a25d1d256ed964182ef19b5a54e8b9daa551b07e3d3e8db2101873e30d95b9feb0319b59a83dbbeebbb6244163146824c9b9a01db5fb1d85ae82d066e8db8116f04ff92db5a0eec30043e9ff2aca436be3fa95435733027098088f9215d008f6ca08d43590e9796d15407091b09838ec9590a7916fde4f6ad07e01869131138c0e6c81d77af948834ca60f557ba0a53b4382fdc89e0ecc11a9e5dec396a87299aa5b9dead306d5606d6596a29bf6285a144894294198349d246e97a56e4227cdd8aeaf401d02c441fa46f7a92e2ca9be9273257a914ba54e61307e8f45f15f8f05cd42dc8b4568cbde0126f2f8d7c4737c440f00fddcbb800d31ec7ca2e08de98ceaba83be547613f74104bde62b653553fb00d2d8639cd419bc2d451d5c26401522f9fe49aea600857e8a7fac64824c8bfe5830d7a19f9ca39817b8cb5a5c12417f45ffcefcde4f7bf5bc7f556ce4ab9a172cec1bead9e56705141d1918b4cd5da7b9cc12d1eccbd9d00e58cb49c3df62f468f1759bb0bcab50fb95da8478633bbf0d5927b3a2c8f065737b6313b3d7d4775e7be76b3850108ed0b7edafd3fde062802e213f67bafbb9ec45faf6628388fbe98e817a9ea4d21129ae9fd7eef63e5be83bec025c3be475a261e6398e37086cd68a234a8f74be560ed70968989182c0e6e0a775056df1ea151da3d4cd4f2a75d6e8d3d5a78f5eb934d57a0181028834a806b540449d194d54a9156fe8f17a6f44cf545d44be3b98ece7f1bafcdf54fc12273fe82a58fdc19f50fd11bf8a42c2e66cc5da119eae0c4ab62b70a9ea089ee457f3c6db170067a8851a59e711df32d1e2d3179f8844a7fe3e6d428be894a59669f9aeefaaa3b95d57793f608aa98f64d7e0864295ee0dc87cf7374cf529deec40110943c137c3e212124058ea86233a8748613b0b28356125ba79d8143530f7512417d8628b61d9f103a848491432c55db9226cf3e1ffd6eb01e03b982b66d68f22573f87f4c8e0ceaaccb0e705e4bb7c0fd5ff947f92ca17b88c92b96988532d4519cf055f677171ad77b84c58c25a1ae7b25876f388addb0557bf67e7556e36a3f7b318b2cb9d9b1a7f3efa1bc86ab07ddefcbaff3a485f5df28c6239f8d008829821b00f55bc369c0550309dfda3e7347fdcf7d9571a89f5d5f8acf7f94177a63ad616b43324497e5440f7c1edd08abbb3f6e07e3cb7f606b159e9cbdc206749c0f38beb9d171a96f113b8cfcd81a1af34a4b6659f79b9d49d12557262447cdc5f0cc782aedf8727c0b3b23454b6474c694b7f6c384168d71c5cd38f85756e48cbfe493496e656e1d2cafc2ec18d46e0d17af26c03d48bd56d9555d1acc2840fbe10071a2906f66eada668dc79463ba21136994174ede81072bc46ef3373f685d15240adca8f3d76c008b4658f36d937a1225826215b152e5c278f8631250f85f5f115de1e8e53d5cbc87e5b8240860ab659656064cb427ab749ebebefc51c15c055f5548cc6c48bfdea7eded58c5c3165b4e16608ce6009b899332f32c1ab562fab19b0cb1026733ec0c2c674bce8884c9f8bcb515431e2efa5eaa33ae77348a5eb8de2ce3b4aad071fe64dd5ef4a7023c5a5e4b97a57f41ec8d331bce33d0f331b6f89f17a7a61352902b524b17632e846dff763929789737ccc70760de895bba814043bb0d8d11fdc7412866d584d2cc54301bd0cc28aa7781fda14a68d565022a483f8c7c251c2e3dd29feedb0385a4be206137411e9b31217e98303cb7dd598efabb3a333b330a151a019feb2374f52e4bc3b5d3183f31d740892bed36b02b49e04c4e98e1e4a165e562c9e1ee98f7138576edb804aff34dc51602f749a888b55801b40ab1b97b250f3db0d4214b5089599592ac674e1ed0bd9191a2dbc61a4d4cdfd71869a6c4db2cc85b94c9458f214b262967d4ed3a3a771d1db30dd988d1f198be3009c13c6fafcc8f377440cc6921dbd7c95d89b5c9691747dd1e7e5739328d282ee074422057ac4292ee3f43be4f119bc01c88e6adf61f06de420cf530389f16287f688612da5731bab287abbdcaba5ae25af04a8028b00595eb8519b0ab101b404ec3269ffa8c23047da4199c2d5abbc407cbbd3b21d8c3c622f7480a38bee38287191633a01651e72bf2a09e8321242aabaf06ab76c75bb29b345fe5c2206585f38813ea4288f83ddd2079939407999e999b3090023e8fcac4cc0760c54e8c194ee53dccbaece0cb256a0d33ec61f46149a7d0a258d583dd44296eb67af2b05f6edc8400a1b2051ac777a25a5deed7a122b71b3e6f45fc0e828e2551070cabab6bb2e0174b983e4c3f9ddf0c365027163d7f7a3d1de5e5c60b6169552f13b95db60036335dd9e98f21e35adc24e3fd61839edb18f28d6bde9e1a607369b348208c1381330ce0e815c30ab9aa3cb30a4de9ee1eeedf216b3e1bcca6b552ab1d50e2368075ad0e6f428f415aa78fd44d6ce52f1c210ffd9b7948de1f08a3273937e1c93da0058e1d249f972e238417909a6d21cd2628a031dabeaa5009760805b813f49dd9115b04a4e5c4b1c7519d3eded14ad2977d6b7afae24726933d6b268d9dea7af1a3d4c9e79c8ce203e5adfdcdbf8eebeff4854b590b0230ec62546a4301bed55b3456d6b2334edbbecace03cb10be8369a377062520dc1c118cc1b27d341bb4b51997a6cca2227bdb74abef5e26e2214e02939bc46810d0949d83a5937911e7f458a04dedf1a03dc8d7989b56eaa35864c4460fdf27ea32cb86f339d749689f5ab3b59022047190b69bcc98497fe72f8a09a4ec881b57543adeff86afc5b44a7ff44af046c1f1687968516440e1e0484dc28f23fec98a301bb3bf877ddf8bdcdeae87636e5348f68342d6a79b31ffce09d2538bba34de79c73ca8484685f632d32e74ab3567042ab1f9eaf9aea2c5df9b3bccdd5653b248ff4b43ecf3b0f454e918f134a0610a4718795539df02e49d36ba6ded9b4e9b2d01cacbe07c2263861bcb260e1160390860c207e9ae703f0598f4045242f82c6473648bce38861c9f9d5cb862abe3e8f76ac094d3fd296658ec2b0aea9a7f9ed6c196fcf066427a73e0b954036d73e80793c229dea1d4d10c9c6b656645a768b12382428d837f49ebf057aeef1c3740ecded3277f25b9315e15b88437755d0d7d8e852425a39a48d7feceed64f3c86eedce2e302a313d586ee9558857b2db57b98ff31ce493d60175b203fa3d8510f6e63246aeccd2147afaab04471c51875293ac857cb719369ef87648714ad1b905c94055d7341ded315463565415c8d4115463085e4aab30bf484abc926b0a06b1439b62aa049d5b7b18d5ffa8e1b9b47c218641953e31012844ab93e92d78ccf332ad6ca0247ef89682eba5d3d2d7014ea82515221ffe5d6f50a066c579c02715a7841b137f575aec474554748f8cd88d96dcd96814d15199a46cc0aa805dc684a1a78bb3a0866efab1196bcf9350968f184939860fa46dc8b6b6805c0335b1aede6e2ae604b27effdbf01e917ef1db5b3f04275bd915895ecae28f2c8a5646e8ba902233835428290601c010d6aa43d1d9a86f5319dd987907e691b10ffb0432a4e09429b1ac648e32e1a0fb3aa916dcd15073c30110af2c39372bc1f9932d9ec5cd05e8d380d38e3e56f34dca0273217adea49b9d68fbd293f0cf08ca44f51f105aeae756a6c0ca6dd2c631ea5b615501112b0fdc343fc73da0239e9c9a7653a402e236477c253f870d44cd90f0c776f6e90570ebee8a1870d61d7d77a60f09d2f261e347227c2e2542e6e3c06b6f6a543459b98b7745e4c1ed7cd720fb48106574b563f8c00e34b598f3c98019286214fb79adafae0832a5b7c116e2c864be7004db0e9b7393a200b7549af1c0507b5d52dc24b51878ea9411c1e9d6000b75d472fe472e2ff12c8d8900c61e9af914a39b2ac3e09843b0b3f073416d68e56b48f89dc909be9c88bf012d9754e2c7c654b68352bd0f8d306e45795a0d634c20d4ada11530ad84f8002edb732928dd756c4e5e1d618d9a186eaa4bbe10bdf9ce7c50881d3ffe446e9fd489dbb6b97b0eebe4b0a311891719c9434878800a3e4c64bca8ee7ba3bcefb611c6ad53b3e70eae1e2abeb294889abc2ab6fb71b7ce6e82d0d4e121fd8e693a5bd39da77b1fb6b6e1b409fe3ed6df3041f06e9097521963206622ce73675cde443a53e654f0ffb930c1aa68db880e470a327c9e5b9dfdbe050c572afc5ebba00fe1980015c4c711827b65df6bb9768284347111fe8824a96daafac25e4f4db88fdbccddbfde9e34fec2097efd17f5d5b8f0f8820afeffcc9e3071257e6cd456febe9ac6341a453de7c95bd4faac41780e17aad2825659fcbc58d1b57f4557de3805685b1a4788592602a9ed24d6d24ea8837166901494af1b83e15f212d5de8de57ee10c734f05bba6077e92cb590a3273ce9e6aeaec225fdfa618531a031be8b29bcf1beabe57465d4ddf734c44faa95888a4a2e624aa00761caeceacdabe70cdcd3829113ddc5e3141ec052f8fbccd9b7ce1b737fb429e1e826a9855748f08be697084513a44239888b6065af61b46619dd9cb88868ec3e823cfb34e9119c834410f4fc0288c9df41fbc1c04de0e04380d59200e3b4e07cd6fb7a585844a098789f046ca936a23f45b8a0ba25f1d2e672e81b78e6e989453935d80e2c25fa816d171b8a1986f0150e03d7b984b99ebe35031c74eec1a39a1724947df17f8848484b4bdbbedbdf79632c914c50cdb0c1a0d4e94692abc64f15426092ed4b8c2820f0b1c5f90e9001b3ebc5053238723ac1c5de142882e5a38a38a2f760822647a82021b1790c1c1cdd4a4760558fb71d89cbeb5f885fdfcb22f3c0ef182dbb18c6d591afb71a6263e600a654629a53f41e8e71f5910346c0a3753132938dbd17df0945e889ba90914bce1666ac202ce6505e2e9e9e9895ba36374795dbb0c5c60f338ce7f657a8564f83726dff85b121410a808a594b394890535983225adf094d28dcc767f2ae9e3d1bff985bd0853831454aea8f2c4061faca84858318286a62bc018f3729e1cdc4c4ccc60fb34764c6cb694e08b5a53521331dc93075bd410055314289cc062d6df166062610c9393343307cfef986d9b8e01396c7e76e1f985b5ad51e88583fc70a4ec0c2d7e6c77459332b6b1b53ce58e153baf286c531d02ec04d8c71e0655f473104ba3d15498e5f6d2d5ed3de448bbbd77b11537131328b82e4d5e9c1395f3b67a27154d78fea383b083e5703331a951315ebbde38ca91366c51309270a20627b478d28589068421854a0b84a0628d2866758cae0b58fb6562057bb8999868f1e1dca9e0218989490e4d32c0cdb4821a2ce2665aa1cc2b77535d3de0882938f4d5038c70f2b231e861f577d5ea1fadf53230b5498530e113d30a4f707ee1c9a442189c7d0080f30f9e73cd964a1da48efd893876d0677bcaaf47616d7033d1c6e0f904d6fa7b9c68269aa9a67fcc5fa309776d8d1acefe05fb83b86b6b1881fd8b37f58ff9fe34e64d1ae6ef503e1fddfe79857bf58022c4d4d650c1448e737b199af88402602a2a80c3b748f3f8bb1bb6719e53727b099a9f8df0bc2da57f2c993f9484ba1733dde3efde7b1a4bef3cd33d55e066726106ec6ae6140af3cf368f25feec23433d6d1fdc77ef3fa7d058110af33aa76c3e3e32d977a7741c49bb9ceffe4568cc6bd804e23f818ef5cc7fb4968d31ccc0ce8389e84fdce2071ba64e691d0d6b6658d3e40c56791ed9f8bbff809c980bf6be7ba308cc7df7200d3dd2a9e8eaa3b85cfffbed5bdda3aecb08f7df73dc4dd2bd8b46baf74800c2763749e865170277bbbf3b23ad02723fba8f7f230caebfbd5105ce0077cd0d2b18a42147361eb71f92ef8e97371489a0560f3822e98e3709f7fedb87f326d9aed300b67716a0d3a4b5970d0a2c307c590104658431db02b78cc6eaac57500212c0b084153060b1c5acbf3300d2ef17d8255d795ebeb003adac97ae2a3075f51de2b8bfaf80610c9e5fc463b4e67f040226102561e751536940e01ce226a1128d46a3cdb0744dcd1338f7931a1b706e33681e804413f2014434211f40048ffbc841b0e719a5b5c88207fbfb0a6c90214713d37f0012495e36de6e156e8772b71db67a801168bc6cec4da535bc23766250e5753da1e2fa2e23730aaede353536785e3e61b7a7dce710d32fdc27d9be7262c5a28a7b4ab9a7dfcd19016be5baca754a3aeebbca6d35355270d7ba6dd9311177022f5008c958549c9041369df0e2ee2f4cdf9dee6831238cd06b92006cee760ddd87f71cc751cc4dee67c7711cc771dc761d0adbb87ed8afba94860448d59bb028dcb53433e0dcb5d84861699eb8906605165e4eb0c1c69397135507ee1a1b5a601bdc3536bae0ecc3825afff8c896f09ea856c8a08861882792a8f8a10d37beb89102188ad0820b1c54208505e216a92b6450781689b056a178b5b79defd264469523c820424b981ec304341aaa9040871634b184f744b54206c511104a656620a3861936d418200d9810945143165c5a90653342ac420605195bb8f18212183065c0cc2c8d5d600b11ec60021ace18b1c5ac7e53c1f56b1b40e04a05ae5f521ff7d158068517e2aeb16105e711e77113a2c97a3feeecf0c4c71f77461a03a2cf460d2e0015e99a90d878d980c1c938fef87822ee1a1b4d70f669aa464cee73902332211ef366fd1b29f3f9e9f984ed5a1b33e015ee5a1a1eb0182bc4eaacfecef78ff92a653f5e4e1f1a0b1d36a70f9a30b149a3d1684c66f5435c7ff458cf6a3b611be790ded9044107db3807770d4d19b8e2aea11903e7d709b88d82d5fb254798ce9b84bef740b4cedf3ea4d43187b9efe69be75011e61e24f3f69d1a5f1c4d15f8d3f082fdc7346ad87fc75fd81fa4a20228cef351e410c5dc4d5287cca0fae046b642ff62bf6f057c5334b26d3f3f097def3b31a886b6d589411dc771db733727a1bf7d12fadb4f91fe4626a95f438fcd99ff14c1c99501761a376001e0ae9d198341d504c1cf1677eec333c127f71d9947bc551a13639ff8ddee3717ea937cef3dea7befbfeb95ddcd26e0edb9db4770ee171ab1bf4539d581a6aa9e849d788630f144c3cc19306794d0e0824170861b08defc474e9c971c650f8b2f7ee3f85127c9ea59e08a4cfd47daf9ab22f0ea432a68cc40cf50c2f48c244c2917b66824f5f6041d187cfb9ca800d6af56ff9179c4dff7a92e028e30b8b26f7ff5dfea53646e7d3f02705eb52257df620226c679205ffdf7951343483deb57643601af9e1343f8deb63e7b78d5fa6c71ebba1070845b6f556f9fb5e408ab2e0774e0d675819f44f5ad0755df7a95ea5bb754dd6c42d9bad904cc7ad6af1e88aec8dc7a6ef59b5864629c679199f5a94bc21096751580f3ab9b04e7553749d8228546bc7a4b66d6151a31cefdc2efd72173c5e353f183f9ab77d14878ab97e2fded5737e3b8ede5f8d5cbd186606f9e38e76dbec51072de2687cc46d8c6feeac11549b1cd835bf891363fc51032eb5725e016a5788a2164fbac5f519c73730ad8e6b7dfc4101cdbfc17827dd66dddbc3d11c5369fedcdcd47d8e6defc76f340fe9137abd55dfd8a2461084b44578f2289265e7d4958d70713b37e62d6db2bbe5f9791f9f6e7db9b51184c02be87c22cefcc9929189c6208e07b1e09b2c8d47c0f8d26d87b70c4aa6f91d904dc6a61fbed3e727e5caddebe6bbcd962fb389f43b69738375bbc7a1b72f5ed31d7e3e0dcece1d5b57917d90eb3b9d9c3f6e6f055ff2d92fb1b320b8d98f5e1a7c81326667d158d3866fd143f30c27aef66f0592c323545041cb148c7ac9b27667dea55a4cd5bb2f52b328f78f554f549ecb75e65bff5f65bb7bd5cbdea6deeea81288b74bc2273f8ddbb38c471ea59451abb589f64f5f659978426eb32b27afbab2bbe155f253e90a76e12f0677885460c5e0fe79f6c42d046c342233e611ab9c1f34757f900e6493a163b95d0efeb32d22dd45c70fd0dd7f69978231d85bf8ec34ee6108f4eebc6854de68ab7e965dc4ba002c2e630e5220d2bb8a1b8af0b5beec37388e96dd91c8ed371a61f529c43ecd87ae915b7dc47c5dd3e2860e97519a15fbfde5c31bdbec5ce3fc2a816f80bb67f44e3df3502bd33cefa5b9de1d603d8eda356ea40dc71ff4ca264e21ffeb92749e4edc33ff7777fbdddd7f3291a99353fa293b2b03da131834df0b2c3f5fd840e27f126c039e7cc3ef88897dbc67173ce39bbbddc847c88d3247ebd1b7ae903e848587f8e86371286b0dd84f354c23fd84e69aac11eeda68eabf23d90f777db61d9c39d4f3364d60b797ea68aa87a990f71a740c0929aad9d996d1e31880a5f9c1e82aeebbaee6532d9ebc7611ec44b4765ef572408582cf89fd7cd6e769fea66f762f7e1a4409e22f3984bec83e755524114991fbfecac3474641540eea5ebbc6e48065a4c6e31d5fbae7bdbc2790c599fbf4ad2cf6e6c3ef3609f1fffecd52a37bfb22141c0623f54cefbfbd018cefb5b1a6baddee65964f5b2eb1e45cabcec3e872c1dd63d0ed90e6b8c2a7d68acb57aff92c66ede7f458e5e766f49202fbb579142bcec3e4522f1b2eb3e2421e065f7205942f7747f437a0eeb9ac68a38aceb1ca3bc2c648778b7bb1ecb3730dbb66d3ba8d0dd94fbe1f1120499cc7b210476ba7bc922f3b2b994af1fdc599a8268aa4480fd4d54f1bcd9fb7c378cfa795d46c09f3f6f763951c5db67ff230c5e9791f041f0c3aba46221190eff08839ee8894db82746a142d20339107c2e77cd2373cbf3bef36e912ac4cbe6b8df38ecde1bae5eb1d3681b8dd6b0df493a3e12674d938be0761eec7c2119eeee06ea9ed656b76db31078e920f4c2dbf65ef6875ead57ecfc2df3e07e9e91d3c25da03f525a4bec5b9a8b95e6d20a8bc86c90e1ea0442ff986451f7ccfcd3351e8f41c0615386668c9933265c01fbd5f218cf04018bf55875226c7e61fab5c61defb7a7ff6027c0a2bee2163fd4150ab1f779a537bd07b01360c5af7822f1d8ac51d8f71511e23ec08fc2beb7017f9f6340a694e6f17dee813bbf70ea73c963f3cff76ddff73d0830b42882a2f77d737edfb77ddebd616ef996b4804e4eec7df5caccd2752b8e04018beddea3d83ca1e00dcff7fffc06bfdf6f6405bf2245802b075f142f512dc1dfb61795cf885142341a9b35877d9fbdefdd88ef9bff7d5fc2f7dff77d441d167ffb4ffcef67cd7d84ffcd1afec239af503761f15b0c122b06c98a51dff771c1df7fdff7fdfa8ebe89e282963807c1fd40fd6303dd33bf553bd807afbeffa998fa7e6fe4599113bbd735196a082b5b918d41eaaf0f76b498f1c5112f03483ac2adc9871b1332dc56b8e1a64206e146b3afb0ae014058dfb0ede58eb0baa14158d5d832ac6dc0c29a260061656383b0a2b1ed254f58d7e809ab1a02086b1a3cc27ac627ac680c20ac67701056333a08ab999fb096e91156323e62a10e0943d8d984f3ef88c0ce5858cb9085750c01c24ac68fb0be004858c7081276ffa0cf618f56690af30ea0b00508ab180fc22a86354058c3b01328ecfe016400200f800a1004c80f02c8623e7afc74c0c1007c7808a087678300c04a0d7600e095c1255f070639765c3a38c61c1c202020a09b1610d0e775404040dc0654a9cf0fe8d34b05ec1758f352eb9c73d6efd9f81446c75e63718dc65cf4fbc5d0988b5ed702e66f2f42fdbe29f4d7df6e0a5890f4d7ed53a0dfb3f93d2b7284c2286c85857d9c674da686cdb3869b3c99201e2981c2fc7bb43167c3fc93a64c295a828ebac71fc873506073afc13ebfdf4c0f4c51bee066c2cd14e509065560d3984e8eedfb37406395c676be7fd668ccc118eafb4da0310dbe7f2ad1988eef9f5a68cc655ff5fd25d0d8fdfe994463e237f937dffd23d098cdf78eef158e7f7d3f0a3496f39dc1f748beee062f80e7791c32838bf4cae001f02c72c74582edf8f253e4bd4802e8799c0f49f22201e03ef91fa9c145eac1799ef7481d17a9d4e003f01de9ba4897fcd773648e8be4e29e923b174983003cec7548a41ccfbd8ef9373a7ee7b9fb846786c15b1249c77db2c10c29f53a76def52089b4739fdccc90bcdfb94f52b3ff1c1749e7ede3209140d7df7c8b4472dd7c8e57914837f7099d218d6f73bcea51aa073fc77dd2b39148aafba40033a4f07580f7c9cebbee93d60c697bd7db90481b08e03ec13143fa7ee77bee136f8644dff59544c2b94f5833249cb73cf7c99c21dd7c8edfe03ee166482aa400dc27ae1912f72ed87df29a21e178fb3b5e2cef13d50c497c1dafc17d229b2175bff33bee13d40cc9e673fc8a44cae099201dcd00709f683043aaeffa7b9fc06648396f2fd2fd2773867a279198201dcd5ef789073324fb3a743cea22dd3c52eb916c1e69f5accfe03e89cd9050bf732f12f748db23d5477af23ef119d2ea73fc9348feae8ba4e322818f847aa4ef91baf7fec99cb91e0312a9f5392ed29339dbb948f691548f947aa4f0c5775d249d47c2f148e323e17cce03511d1207595258ff481ea1b0fe1c12050aebc721e7140aebbf215ba40d390285f5b3c849a3b0fe15399728acdf9296c2fa55a48cc2fa53640914d62f923389c2fa437266a1b07e9044914014d6ff91265058bf474e250aebefc8a985c2fa39f229ac7f232bb9010a934261fd4ece1a85f54f324933bd9005e76682620613519c64fe8847a39ee97551a219539f7f863f8452d1fa414a54aa399378edb924be65674be25ac610f549bc88162a8967b15e12bfa2a4bb39892f29a15f2fbd3927f129aa9b3be7f27234abf7f76cbefb4a57abd6bdacebd1c4cb7dd310b5c4795d5851f443753cb8e9e3b610e575f57b54d7766a42795d5d9a4d4ea7705bc8839796969696266d69d2266dd226ad9d266d042f7b4e3eee85f37c7c7c7c7c7c1efccff338bb8d150d8dd9b7d7bdd84fdd176f1e438bf2ec6d8775f49d0d9b7d8a4ff1293ec5a7f8143329ffd104b6333d999d9b43ba86bb7b38d51112bed866c2edd3b1a9643b369d288cfa8f5eec54928d65ac298cac782ad1d8061a46df8c92192533434ad389c68e348cfe385a4bdfc919a57b282dd3b0793a354dda45ffc4e00c8ff48fa677d6d7f1356ca668bc600227a9cf4ab2bd0d8dfb5693ee6f92c2c781227e8e52eac719548fa3d7d8d749b27ad7fbd3261a732787f9bf99b16beee4e4e422a70e397190a37f0e396f98522614a71549bf78e96f49ea8572a135ba85a45a6811340bbde24ef4b3539a13f6a734a7611e1e1e5f5ae2f1255feaee994ea3f908fe9e67ed38d276aa3c33f3e0397ffed0a4b2cd99493cbfa97bfcbb9b4bec74692639a54dfe74c9dfe94cf2b2742a5efabcc14b1fca5ee93f647e30e79533b67e9e496dd8afdf865d401bb671dd301d9a6f60fa4c50c0e06682f20567bac4048509d325f771a57fd0aa33535d68983e92fe31bf8778fc4af7cc244aeb1f8d296851e3e7f9f812fff9993a65711f49e6a54e5e6c29028c1b5a9eb684a989e132c68b992f6792503449a89a356bd460faae86cd943af995eea194524ae91a9b27982698fe04e3e3258dfd782c88c3e80b71580c048721f192bea3b17926791a4ae9cf2c34d633cfce599679dda97be8d3f734b6fbec597ce8acdb3775a7fed1ddeee97b161af371187df066cf8e4dbd9be583dc49f13384bbf9411885786987dacb0f26923395e6e100f6f6f5b725ef818f7a50fcf0c5d4ab566f7f65f3acb769fd8dfb7ddd90efad96b5a177c49a4e845ba729a76ecc44774a6b92ceccff8d59f84e5033fafd5fe9f55b64c43df72afa5eb737fadefbfe1daf1e7da3efb7d1dfdfc99c19715fbbf7e8f7b7eafb1b79cffdd6bd11eae93b415996aa7aef6fb43db7fabe7b2390658dc007534e5033f132d191ba4c74a0dee87bd6753267e08a3e57df687bd5173999b32223f0bb77829ad9ab4adda2af7bf7de887efd249d99185ef036eafb5a64b4fd86faaef74546f4bd37eabe7a779cb322a38ebbafed5623eaf7bdc76a7627002bf5204967466fd1900ea34e8a19bd454e5233fa49387563a25a93a433a35fc4448713d46f95de2223f1719e892a4967a6d362d914b80a553b2d1c964d8136aad588c36ad91478b3b269e1b42c2b057edb1bdd3c1dd281d362a5de287cfb454e5028afdefcf6465ce8c2f1e3f6e3788b8c3c940bc72d324255afd328cd76705a2c0b163941cd5c97898e356bd6cc74726e9111ea715a2c9b02bf6e7ba3f0e91719798fd362d914f8d1370abffb22a3cad9d41719a91eecde28fc0fe7bebc875bef31bf75df7b788b75775677b47754dd9dd46d89f7f546e17df05ad4edef86deadde637e773defe15f64c4ddd07bccdf8ceaf5bcc77c7aabf7f0ef3772cdcf0bb88036ac92fea1ef87bc1fea7e88fba1ed87ea0f2dc18036b4a46bc2fe4bba86e90729e957d237fff74abe9b77bc57e2dd3c76afa4bbb9c5bd12ee66bbbd92ede6b0be92da4afca9b7fb3d0107cffbf2727601f692fade2fd9fef396d0077ffe12f153bfc4aa7eb5c486f5ad5f8273f3394b708cafb364e787e61dd2b1c4f539964c25434343e60f1972fdd0f843383fc4fa21d50fd10fff83ef3f986bd6cc1f9af3e6a1e9ca71f38eebe61f756ec631debc73937333cecdcd23ab75b30debe6966a75b355dd6cc3d4cd62787348ff041d0cde8ca2379fa083bf9bbb86f3093ad8bbb9930277433a4ed0c1f5e6eea4c0f4331187e93d0107fb7dedccea02e8f343859fcaa3dc900a9f80833725f3be28d7a1ee0e0afcee28a63c4b3bd44d1762ee7a29d7766bfd26bd02767d254475eb38cf437da9ef0fc130257ebf5dbd92d6f7b75298d57a220edb3c110e1e52e19cef1f437cf34a4ea838e7892ac679a2161e32007611b1f0f84a885018c72b3981c3ae2772aca384c8620c5e09918773fcce138d7888621d4a885258c9098e755c9fdd4352b276cffc1d72eb9ef92ef2d321bdee998f83ecb8b07b40942a25da150be7a6d53d3638c6eec9d9e91e974e0e0cba67be9347184c8a86e3ca5cc1f4098832645e65c89cca7895211b52bbe24b143a9489828aa62fa2b8e286973494d278b2c21317c830d8f852c0515106c5e4840c96fe9e595c46dcc7b07e7d0cdb7f848ff0bc4718a4944ea9b54a99d337dfae2739d164abd79b10a0225e4e313c1919cac5d7940243468609b129050699205229a875fcf1f1bae0b400737fa69feb6707398eab71dbb63506678b41477c4a4ae99171db6c456d95a49ee339939c4071950e74ffe11691541a0dc9a4d166dd3b92aecdba5b84c2fa81dc27ae4d4c4eb21ced404589279e38828b2e477052684b6c61011a6f589154034db2e1260c99166e26275060103793935a0bb2607f07c3660f4f2d34c6cddaf4c2714e9ef4d4b3a9a584a7cd2cb31228cca3b17156c92314d67d7753e0ca8d6c0aabd725424dc1fb3aebd9ec88c775bfd5efae11f775fbed3db2088b08938c114fd066ded72f32e2be7bef1a71dfd5af3e85c69668acbef7a04e4fa42f79e957f07c5a539808db73bf3de712a13e77e429cc7dca12f6cf5e16dc19186d47ee1c19d0eb1fd367fda06a098fd0e208403e6b53cbcc329bd0386d7a7132f324a66953189169ff68067eeabaea8b68e652bd47bc6b8666a794243c954428021ff5ab17a148f5e173af646884d5773f02f7e20755f11ea4a412faf637fb2d8e10fef64a86964c3c34c4809ea59e013d63fdd0082e113ed47fdfb3d4082e11526ff336378519eb12712914367f455ad2e5cffdd10ca424037ad624f5df83531401f5dfd311c411c01154d793286c7eeabae88b5fc495b24f6972d17bc4bb2385cdef6ec9912ebf477c286ccaf0fca39991ea887ac706d8fe7a9951eb8b4e202c9701194e423fa4a1f75e3f0bc9b0f7df831e195633b66e1e6e3c45059c30bb9b01d9e6ee0258b3091b16f3699f1c17d81ce259af8fcccbf9d3c50722c430a20c270244603b08ce39ddeb5ac9adb9a63eb94e0a08aa3c48459bb0d953c108b83071c3123687b862af7b985023b0b9d694b0218914d85cb7d8eca1e00426b0d91381086cf6b4d8ec2171841145d85c89b0b90e2144169bbd204a60b387e58acd9e1512d85c81b8c166ef072e1b78c1fd1b8844265eb2b956a9c1871e6cae9852e181eef023060985d89dcc23767777fa1b3964847df64f8f0e7af4e8d1a3470697ecd1a3470fead38379a7970488830d4b31c8dbbc276d003815e01d54bb76d9edd38d789ed83f80e77dcd2be09cee94d6ba6d1cd989441c13754f1fe9bcb049ef0b9b4489441c1fe99e468160188a4da644228e79baa7bf532a95b5ab158b6563d36af24624e2d8eb960d0e0e0e8e881382281c9ccfc3c1c1c1f1a923958f70170504bbbbbb1b053542257491eeeeeea65d80ce71371371787bdfb6a7cf711cc77146558af5ebd19eb4916cb3f98ef3c455e62d329a194df718c089bb824b86503cc471550d4d7c42bf374143c32d2a200754291922c3fd433adcf7c30d72b5721c572bbda95c84a737ada9a33927194a6ba594a43450f7908a43b61f9a6b30b7e1f960a5d5676fa96c846bf74c223a286decb90f5a6fed1e319410a1d89b3ce613a93ee712d8f8f66ade7cc4ad5a5ef6ede9420724b033070b761ecde9c2bd440b4b2cdc4c63b04c711fd561f5bb082f51bf744575c314abe425903749a1a0862564a62b21cc87c44baf48fbfcd8bccad68d97136c51ba854f29a554dc3e14c9c6dc465a5477c385f3e752de5aad56abd40b367b9337b99383b1f1569fedc8fafc9d0c88be77b3ecbb9475537775edb52173106f719b96225ad535259b67ade6e50b971c76fcd227882cc78eb5e3f85f963e329c5d8988cb7265c90669c1e699258b962d4594b21f1fd70fceae14a6cc53102a536e4891bd923d9541e3e9e9e90b319e28ede929c9667f5aba4265c7a5f3e58fcf8e4b679c4d25a64d5e0b53664c1b32293328b1c84efd80c0e6a9a424e586195c5ffaf0943c3f5066d26cc2f28162f3a44d5a6d3671d9f1794a2fa98bea506bc7f11f8d8f1a143a9e2836b7990da05044348e5ff6fd9db1157a2f9c67939772259e336684ba95e80c44b8a7d78bcdae94030f5489c22a087683ab4f5127accbd03e68973574ac6b98e85926902547d8668bc398aa61ac67b17eb26ee8e51489d0356bb0bd4093473d725dc9cb7a44f555f5f6924f6c092608510048e7717cf6c6d7e4411f45be975487e2a03f7e649e66b2cf806b0eb8fe8a6c2ffb0db83e4866b782eb7364162ac58429c1a337bf30154551144551144551144551144551144551144551144551144551144571cc51fac9833e487746da4477707625a117182724edfff4f4f4f4f4f46426bb92983161707cce676f67f452c49123be2f116d4d5f8ad890dd3b76ec50fc30cfa6dec1f4371aa44576ff6b44850d3832f2605b2348638f0acb121576abefc897ff2abf15b9e408af8ee808bb300c571783c9a3fed3d8917e1fa02348bca44a35aad4546936e57cfdd6e4218aef4f349673db61e257afc18cb21f9f1bb25b2d0c30c0c04e1ee2578789d99b82eb7b3e422d9ef27543b6f5c20986a8feb6e1a02606f2b256900ba748c446fc71dc20838945c3eae70ed377d9746ca494b646b0620bbeea592d8600162912e61c4cbb77250aababf1e9f704329b268ffab76ab1b41659fde84a34a66a189d40424a7ff5dfcd8ef36c5a728451df5e86e210fa93477d201a9b4dac9b02b7f19b2ad1d8788f50255c1f6cf2b2567184c6fcc961f5ebc5fe34d3627d8afbc8fe947df2dfe033b80fefebfb93fbe870fd9f401a572f45d29b3cc4ed43524945b697431b320b8514874c80bdd831f737e4c42d72621b72e2664dbc2227b6e4c42a726270e2d86f77741f356f80c5b79f33c0620cdd533fa7b0f8ae8ef91355b58fd48b6fd3b19c173f9c40a8d2e4515f7cf1ab28be15c91f1eac58eb8b77f4271a9b4d1456bf5af0554fb83e8d61f5f5a9d20472e47f02a16bd6609a758cafea188ea74fdb07ebe9771dd3119fbe0ed9354c7c1649bb141f07a96a98f82329be155f258aaf7a57bd8b2188afbaa197f4e2231388eaebcf261a1bdffeea36ad1ecc59e9a03f92aa86d15791dd3ce8e7905dc3e8a748da65f76208f47e0f4443727b90acff915e9e760c697764e3f3090e1c8f4ff57e5221a04f7934cbf668d60fbabd25b6df6f49210ef3f9e1a818d40f82d9372021781b326a33f87b7268e64f7d2e559f7d3c205c7f23c3d51fcd44f1ed2311c35fdda2d5875f645ffca3190a7cfb4850bf7af0eda748d77cd61fcd54a46b5ed702549f7a24aa4ffdfcd42dc2322f92d4b36e916bbea530ee8f66a92f72cdab0409eb6d9e013d6be25118f7f66d6e5191cddb5cd6d14cf547b3efd9ea4988c2f66c757b666f8aec9948f62c3c9aa1c8a3d9f79524e2b0bf8b417e8b903c5ab0f4bd2bc4cb72080a2c7d7f1f1a13e230ee430ce425f750ecf78b431d55f796400ed23ce1eac2f3924386da44073e54158c5d2697960b4c3c0b4bfc14260dd2d49a010840c583a014142048901a405a58bc1fa31302b0849069e0428db546e0f9184dd06347d34f8e147430048cca4101de9803683de17380357804cd20000e74e8d9e1846783589700fc1002e6010c65100b3c0d5e6becd841a50260a705ef152446cd40a68277770c514914fcce93a72307adea08a1028707408c439ce4eca8e1749074232ba3b60800850d6b880f2b991376e7063b5f659d6ac85a030ee98292e1e07142dea85b072ca01c38f90e18e60b0c3b1f880ddb1e142008901f1f06954070924ab8af50e87a324271f600003e9ca1d0d7c1664f8dcd95003ed8ec052511b486cd5eab04367b75c31a40b1b9b66e184f6073dd2185cd35871243c4e0f0c4246e417100368242c0c10e3b92624ed8ecfd20c28318829a5e6cd85c77f460739dd8c32e0ea370d018322644ec6cd9f1a2a5c042aaf0c08a6b08c53778c33b986cf63a78222b637325c00a86549141e132922b5601ee2fb8ff08ff8844261e9a6bb0cdc2e66a43231245964310cde65a1f857f6cf8c78f7a3d0ae3208b1d32d8ece5895f62d8ec152008901f1edcb40c901a9a6bb0cb88013e4c6f4e01fba5fe15d174fa631a4442937d25d2041ac30da3ef84192930ed2c489cbb2606a87b8ef0e2653f79d9f8c57cab071c51f3b2fda953ef9ad3281029240536772d09f76bb083cd5d6bc1faf09ef338d7e30d67cec5809ea1bea86bb30e7cdf01d4af2a8d56bff1f79ccbbb4750b729acf1376e247d62ebcd32dc597067f019e1f511cb559a1241d566bf55c7b269dde0e48c38745c3b3930d0f1e4cde05b0c7a3d908740be858b18e1a348a1e6e2852cac542c30e182229acb16a0ae919101f7ca008335768988cb2224c81832c825317843b54ae2c2c30d41a8149181a143f63a90522c2a4ec8a0249b5240f82193e307831c34d1c689055f60ee67931f28477cc670f9ecb894c21b20acb08282cfa421e131838347074713306787334108f19c19a12c93538e393a5440e1f812461198fb12844a31107889b979e1dc60e0c6c73d12a1179812de0c9b4791445bcb868957c4cb260aec94d13d8ae3ee7be93b3aa2d8fc7ad4a3fee561c83dd88941a1a780971331f480b91a44680773d78431ccf7a8d56ab4b6d5eabed57362d0e7b3fa5632a1d617dba348a116b6d672b5a2beb72d6c5f1d88e08b18d86e966703360cf0512451c52a951786a0eaab18041255ac1a55b362a2f005a947914221164510f5de04e24d1e5cea1b31d76ae510a352db47c5a0945088c5f74205b415405861058b29f1a28051395c38b2d21b295eb472a1f7db83f7e3b287c310a33e87a8f066eeb7c69c11a64313d34b4431a53783799900fba74752166c7faeb88251c3d42faa0be69c75ce39bb67fb5abd9848f5a97651b9a82da860ea16558b9a05a513a93a552cea15d58a5a45a5a24ee14695a236d5282a0bea0aea970a457da23a51bdd42e4da8c072616209a69a123689146c41c1094ca00589238cb0a10822861022cb9cf34b1025c03251504055d3addb3aef364a7debb66eeb368eebaaaaebb6be35109ec9c3b9dfb8f7b8f7e7f1b8cf37dc67ebf17075e3b89fdc771be781faa0e76d9c0e6e166e14eef7f6be1fc7ed418ffb3831687bb0db2ae51c1b7562d0f69d48240875aff33c6fdaa4ba5b8f9c4ce283fa02e21d3d79cc1dd83f7778fe6d1fdedb8ed9397f6b20afc9c37ffeec1fddcff70904f5f36bfff87e48c514cf3add29158904c1dc83aa89dd07092078cbe6e2b3874b540f1f14ad1c5737d4251dbbe73e7e4c211e60ff5900f0368595db27364c487dd7b1e2a636972a1ab9a147725d6ea81338d2db48c51cde3c80a911eebb9372f635819493874f1e9d4b8c22bd796cff91b57bb6727b8f0cbbdcbe088dd9866def5f4e205bf3d8b60e6f9f0380fdaf043cd10889eb83dfec4953dd9dd9a8faf43ccff3da26c525e9a7cfc51a09ecfc0d073bff063bb711d8d9fda300b87f724fa4f17ca28987cca1b906cfb9d9d001d9f1c6776227e8859b08be7093820ab71ac0700b41186e3488e136432adc6450855b0c36ecfec101065763133b7f156e30b0c24dc926dca2b4c2ed859b7003014eb841c9093717461c61f78f00943e387037f90d2b801a1ce1d6824eb83d71855bd24eb8b19023dc9c60106e01563695a4705efe0fa6140acffba030693cb83e57f208d133af51a82c418cbf90503074c7ab4df539b79ed04e102f27f584461f2f679509b5302d22c216bf845a36d7270a73110ebd0c314501d7a7a48e015c607bf2a0d4c3114117a03e40c77c1c36ff88df3ce2a6b9a1a040428a8040bdfaa005932a64e842a58cdcc6123c90b1d4c40f2bf0a25bc3250914ac81038d56c393166898828a1c92567862438b378e5080c31560ac445133840e42340de1c60fb51798a105156e1c91c08d1068b18313172d74d0409426d2388d60875a125f3a35626859d638a28927c678a181062e6da0f1e18516dca082ae8d316a20d142932cbe5042e3a8871fc280018d2d92503045125d9a2d9ca062ca15247cf8218a0a6e3441c3182526ca208144c7066e2223268715b41c11446bd12408305b94d88205308440536b728511566871c60b2088b012060c67a051831a58585923852c48b519aed042ccd30e5ad618228d10633891e9410d9d2d20d80266890820d044a08b1a5ed0b4031561b491431a60b058630551d22ced80035dc10c4fae206308266010c1992035354fa8a0a58a0bbec000085250c604568c00828c0c68f8110b5ace68810833c2940089510c14bc4043931dcaac008233808af8d034323c01f1c314343170e82a7200a34312522ce1000216ccf0f152462990d366824a19353265aa04a1045da10448486831c30568e430a365549899e9b005c2149bc2cd54664b53ab0b1ca42cf15005082c69ba10d18524d38574a30bb94617128c2e2e7421c37421c9e8f2a275e33aef4381a19852ad403862825093a42954b678e935af9c870a5396358a4e62d004d367bc9c68bcc4a0f6d48bc7e699334d3836b9607f9ac563738bc3fc63738ac3fc63b389c74c7098ff162d53aecc2653c4cc80bfd024f741a92cb5dedfafb80f2dcec57d7ca00f51b57aeebd08ecbe05e7b3d7723efb17ec5ec5e84f387c8c8ea3c1eefaec6ab03f76c26657aa02fbfb0d5ce60c4ad3a7cc7ae0c29ec19e89386fe21eec78d29cd284cd338c93992062c28c518d200c9ba7972d55c8be78694aed00c6e679658a969f2c578a10ad6061f3546a82fde70d3e7306f760c72614c11536f79949e34181a8089c95c0e22e2c05dc47162a7195a49f41c03dd879ff114a701f36efbf8312836c482c6c45895dc5e5effac4a015cd869f584547c713835440d89627da2a387074629028c5ee74e25865fc1b158c600ef6c5898f22abe4e46c62d00702cbb38965151c9c2af6a78a3e556e6eb6156c105995d6dfa8a0453a9529355821d9a7dca8c03eb17ce585a9cc15dc0337139933d8254291910a9ea6a8cde8f7acbdd01aa5d749d064c8641f5082ca135e58f9a225a9c798a18692939395197e20f3c446260a0ecab49a283e6801468d1767b2c8c145095eb0b2031647e04006068e4c0d1d9091d5f051c88842c50a5e48437b61881f9450e38a16686c2861338501ca90d58025056bb0e022822b2b40b14245093672f092c61865a8f095d1428f31b21a7e05108841b342981378a1c384152390e18a11a061c697da34003264359cf082323bb860a5073584e896aeb891451056aab8718259f70d03ee3adc79192305773fb87b01ee3a590d5e0c6fa0b20099923e2ac504effd8b74ef5f72ef7d9e3434dee736333e59a7dc4d9e4f96e5aed5f732d6ac963cb330294162d414a3279ab71d4de936a08dfedc5c00bbbb3f7fae95c4f56792eaee9cdfcc7dd71cf7dba4e1aef5bbdfb6ae7194e3e873b5f6385adbdbed075f074e42d700bb7fcc0dd377918426eb3feb7c129aecec1f4e42939dfd63763bdd6adb542ec2fe5fd0ef57b6b866276ea62860707b3944dfa0614aa5b079d29c581bdc4c63a280c0024b83cd5d631ae3848ac0e66722e30b9c3dea3d68b62710a761ef363878c14e5c89542fe90fe454a2d1683acce69c73cea52c5a660dcf396523933c254bab62cca029817af19ada09c8ab572f7d643fc3704abd3f42d8a6f329fd9830e1ea669468341598665d9b5ab22c6d3f9326ad846e316d6674b24db9bd8c32eb53b60542dddcb5ef5b99308dc69c4b0934e654a614252e9e184b85c666989e5c1ae63f3ad9266fe26594599f5c8ed662e76e162f1b670f83fd39226878c20578bb794e09e33eb6ea791834bc98a20c9c9d4b07050c2ff00267a7c2a191022dc6c0d99b6c4d569e2ce1029c6798aa854303298c18384f2ed5db485abd56510bdd2ef7db17d5e7dc8d2d4ab4593d72dfd2805f7ff19658ca8257b897a8b205b73846f7f35fdd052a22c4cb0986052a649ca2051f9feb82bbaeebbaae7ba0225dd7791d13195c70d7755dc77170c3f8e3b0f1c5f3025be495d0601bdc4c6408813fdc4c642ce1ece339e73252afaa7b6690576127ce2a3c5fd53fda48537a5330a295fe0af58b92e6acde37da36270adb9a286c1ad123f74d0cd8afbc3de1d94ea6e0666ae2d44fb8999092c054a97fd05af74c06f88c6af130ec9734b601156b709185363b5262cd6c3e0a3f6c7862a9469bcda3d9fca9946a628a279468b3aecd2d0d9a29342dfed96949f3043960a9cde6bb146f6a4223c689c6fc697ecfa699397f2e65995a4ca031aa85c2e6cf3f4263407e68ca329b3f4209aec5d21855a23420198dcd59762d7eb5606f6e4ff50bfafdfe8de7972025eb7b345652d8fc29abf7296cb672b216a863475594d48cc007163cc180c66c7e918e1d25d1c41a40a8b1d2c30d67cc9a1c0bd813c8d0c44a4e18eaf0c4441ab74f20000087341898a5065e8da14a89667008a2c8c05f17d8eb9e333a0cbca141bba7fd8c3368e00e0ccc7d813732b8d231d8bdc0b37b7a09dcdd63833dec4dc7029cf35db3e9eaeb5a00f7de8bd0fd7653d8be7befa68005c9f69df72974cf5d577fcfb8ef19e759991a366f5d159f790fe464120088c2a27ebb45dba3bee8fbf039d2e50ffed1ac23bbe71ec973b7088b5f24dc83b72805d483cf7d510a5890a0aecb5f7cf0c14fc1b580f0518f44bc2e7f20f0c3ebf2ab0449f86259433deabb3f9a89f34318eaf3839f7d50288fecd91417e033d41d7d8672ff9ef9ec5348010b92edbaea7bcf3df7297cd755af6b01dd6f8fc4bbaefa1ba0b0f9651a3352a4e1050f642c31e3bebbae7a9520e946a030ef8205529412b44002302404617bd66166de2d3a4261f3bb12da4c37cd7ac63d583260ceb61fe974af9dcc199623db027cb6ddefa83ab7c64a0f19c458a6314b6a5888d243053b1f25a6c713377ec6d8f936527ed2b0f32bee259ad490a4c68f992c3d5648fa01cd16619caca00708cee81185898c353d461006192b08c349173d60588205177461976001053d98d8f91e116ffca4b1f35536f4a8c1cef7702f9114c30f1876fe877b092765f470c12e91d4c40dbb040b55e0ee56b73090ab7ed4b0f339dc4c6376c01d02c8011b2e2ebc1c31d41eecfce92dd0cf4183362a017a08dae205a5d1ba323b3fe8de8e29a9410bb56583376aa951e448a20e09a32e11c31326f296130740134403075376b010f3f26308cf03a5a0285e68ea0e1e765c081253652bec10a2ee9c60a78b9e42c8141efc907728d1010b323295005f86f4207b62670476bec5a2b2de18b2848c049e9035b583157080c58e18c2481df13f633daf1627a3bbc783f5af3e8328ad5b6be3ba9dcefb2a9dad93ca47d89b3cfad5e0fe0d8d8f4e769d6784f307be1d0e054e10043f94d8f226ad94760fad3bad71dcf172c76ed55a6b2df5d960ca85449c715f8d661e85795c884c1cda298a626f296ff2089d7c795912f142d1e747e5f3b3e1a4f206c4544ad56e5bceb2a9d46da64d77a93c9452a944222adfb1221195933c413e44b85593d9a771a8e310b142276dbc856f16aa1be947598e8ac03ea712aed3797c28f670c4eaa59361508ee88d36ac71358e5635a646710cc7711cc171447de3e87523b7553afa38ceb13b48e525b89960271c6dbe7a019dbe9144be1561a7d4e70e9ee7733aa9b5560142683dcfdbbc0e53b9885a71779f258f17d66d6b715dcb8a41adeff33a10e436b0520727d8aaed8c5103a07b055a73f4e6f439e79cd3e79cd35be3c4d69b4ed6969721977219e1704e01cf7731add0473add6de82ec68031b47e29e0250d6918b6822cd77525122f7fdab642db0a27994ab59752a93c95b5abd58ac562d9d8b4ea246f6e268e18e4ee4e012f7bdee4e4e4b4726c7272727258393939202ae7f3ba9c9c1c6ecba934c7e70eef8c0da73b6d8d1bc785d6ebbacef3beef080ad524181486612b4ca582ac55ad56abd46ab55aadb64a7d351b070765622696febcd5cb76a2d6cc2ddb3dfd2d83e71bdd36dfa64704fa78f9d3756e35e57a7a836429795e25cfab15769ded3aeb75dc565128eaf38b02824e299d5508c5c1f6edb2e9e6db84c0f42aad1bf5b96d41cc39dd29f5c24aabc771dd14071b5acff3be8ef374f0aafdd78ed3cdb76d9b5b7fa99cc20fe114e265ff76a41b775addd3799ef77d1f0ac5e35356309ca4188a478e02f65c6230787eea09cf4f3975cf7c2d5b8a903295848af0bca6d3babb674f355e7a133caf2a9ca4b575c56255168bc5a23e6fbe235e5e524a7d76ddb07f15029c4e200071f13040a13782102fbdc8bc0cd26064e0d7715bfd9afafc50b3f99fd19c3409b07bb6975e67adcda596e6fb9cd32ba5730c2fac94f616016fbad3eacd9d89478ff336cfab9ee7d1b653805588e3388e9bef5ce5b839a14ca5e66ea6d539cee9b6ede0eebd70fd496b2d79f20bbb7b9d5cedba8e769d775d37bbaeebba9d1a8517564abdb0f2f894ddd3cdd5aeab1c87259c745207804221e5ac3f470e19e14a6bdd809773035e4e6fe15ab97076cd422d20bad1dbb70ea1989bd504ee74cbb309cfc74cac4f32d76df2e8f72040d027e9517ab363ff2db43e7f734af3185a4aceb97921277e28146aa2e8147e03a41fa8044bd86a4341c8184333020c00100013160030381c0e0b85a25996069ab80714000e85aa48624e1c8aa32488619831c62062882100000000034330539b00e635419bb1fa4a23291a964aed6c717ff0195757aa3a71f7718fca348e8081fb687243574827f93eec95d5e45599ca5ce9d9806bd780efdad1f55b1c89ea05d34283273965ad755716141cdc85d32178877baa72cf97731807b6389c217d3eca24c677479cea28df5e0ef5df05ad8b4d74cce49d2cf4d904e810c0efc6f20b41c08c7d55f936a847b25617cac1e6437751c183ff90f3328d3fd99be505258b863e43c5197660489bb57fc80810711d02f765dec9d5d93c7576a5c383660d29e6a3064666168f66d025409c1d2f6ce24007d7188c66cb8140edb4504a8093a3fd92aaa97c35533958d59137382c01e71311bf13c75a34c965820bc9c97da8af84c6e53de05758ad8632a782b5dbe2ec41d3b3c3ba0c74341c1b0688d4c64cabb21802281976c2319c40bea89d8d839661cc85c26c64211d9620d315e977965c7ca04562760f5e94abcec3f020e9d7d69ab0ef3f1e5c6cf4daaf9a933b47abb98fdd0c908b8868515ed7a0c64c283d708a94cec08a14d9714135f1aa39b8f4ed9924324ae2286449ed7eb63f84259dd8bda0414045b475ad63d5228dff1015cef2014ff3a164b1441e9a7165d0c7925bf037b6425374b52a5ddc1620f09072703f3913d5752ce00b8aa8d3eab1033d024e67bc9915b2d291d194d3f440fee9de237e9c362ef6506d84cf7e08239bd40024a95e32753517146d4bef02a83ed5afc4e7cbedca794def2814b8d9839cad111ca9adfae4e0a6667ef1154773e1bba79fa613589e50be64262f13bdb7c275486f886dc41ab186d8462c18eb45775f75f5219ff3619ff3619ff9309ffb5060f7cda77cd6d727379bc108d8c98b7e8fcd44bc70e6888ff8cc172b3689e06db53b191c78c1b2198fc94e211175d2fdf105604c3f2f88d10672b45364444160dedd4d5e6f6cd4da8a612439d2df6a10b30da124078d26bbd25552cddfc72c64360dc03c3c43c424009b1c3785cb0214c78cf8ec5e6b4efa9fc745b73fb94424cc552eaa02b1a50a44f805f46d41cd07205bac9e180bef49a395c0522fbee12aa49e66a9a995f639b5c9c5bb34f130dfe1f00e900bdb961f3b949d89ab2df88118ae910cf05cbd5d1ee835285a5c2bced43fc40a1f02d7c9f48a6c97a745f27ef450c22225c489405d88ebdfe1465aabb5d93e72b5b67d17ccb1017229c0295c1a9ae3f8e2a7394e5992cad00fb5f9c29f54ca40725c955ed53eb45054da9fca112433151238af85fe8a1f2a5c9c136bf0c53e6b9d8396489842fa980ab16070465f0deb6c24c8df34587e96a5cc1be0d020f079074cd4ea80cba50df933f8659ae12bd424821c11edab3e4746b2c995f507d51358788e24cc87956da69f3d30c73a5fee97193b0724e49bd3c1dfa36549c9bd11f652fedc5fdd29e97121bf4fc1ef57f052f961559264391c67cd795425bcf8f146b139c39f31ef6b060eca41b14381fba1e871b06fffc4e4d94c861633d3e7a6f320f282bc2d11271eb6f2e9b897dcf4c9221c8b7acea105fc8005016af3a74614e5234f9b7d4f605e825c09559058ddd08fb90ded75370abe4e38c5254c9630b6525a4cba413ac030e80ff31bfdc2390f6adb1fdcafad3253ef1b72b104d4819785cbe3644c08b508a4b81efba798eae2e1ab64e3830826807de134f338ad176e13ca7cc5b8284f381dddc152d128e513f684e18f1f0f15033d9a5173236dc91288d20929db05768ed379cc2a9452ca08479c1b8a2168c99bae19c75fdc01687c846fc8fa6800a977aa29d51d5d65e963dc1de252f6fea7585af00002397546ec5c7614c34b694aca8079a7e4700c06bdcfd93a3545e769f83aa4d25c83666e7631b3f81919d1911eeffbb9dd7226d28a9775c5e241f85038a116e56eab3e58d008f5a3a5fa2f33a4752053a809788aceab3b930e844cf2180699ad07d68883e40e51da96371376d239bf518e1e7d45c04796be24e34b5f2c0e5a737888543f188d8067c3172913f9cd720b469e5703a9a39355446fc36a3e264174ca9c37892be441b5ac83b47f78266c0acc957b4c5530846cf71f98b64a6a0eaf11604767268c5ec9fb6743c821a7a5ac922abe94dbdeabebbe070ce4851fa0c372004c3544989441c7468198ad228ebdbc1397ec4d6601eda780caa878bc7477555c34641f561fb73e6aea3e3fc5d77ca7abe90a93225f740770dfc01799f6317c4e1ec5195ed760c9eeb3937a6d6a7d91f6fe8467c2451f5bafce400b4c27e928023522b1f0731ac2682e9b615d59d96c9f2130cd3ac206c0aca810067fe90c92a6bddcc529bd260559967f8059ca5955cedc79da48b283e9f67339e384edcdf7d9bd192010dd68dd2341f82dee0bca87a5ea6db8e0a2ffa463b8802b3bf9492827df9bfa8109f5246e3c414eb64f215b86b7b53ffd286662632186ae91fee71e2d12132e6c0e0cd58dbbe8ca492a40a372397bda3fa36a4211eaaa965c63dbadde5dbeac212002dacc6d50e265b4e0ee445b1b8a6f9dada810c36db597748f2250ea494e2cbe2cf66f82ad261e95d27819eb6d5b53ec63ce149c10e756fa2852bbf0da3019b0569a9026532855ad1b92372ea12be39e2596324a23e57e8d5eb10d13f389c7f7fa65d77a6293cdf769d604a54e252fc03d7ff74d64a55e9daace23429f71181349cf6c51cd4e6a6dd05c9f85606de9d6273460addcd6a3251602da220c0b1adfbb1a333a49e8dc3f0b701a23b2fbb26ce60752a8d107faae5a68f539995316a7ab090ee2d7c8c9baafee27a02ea9b14e099caccde9a949248b0bf76e60b39404e9eac6f0dc1b9a6a8739675212278d48dfcec8e2e1031dd4831705fe367616df1f6b6017ca9506bcf7b2ec47c97a0ae20e0efb6859d3f3c7d47e7338505c600b6d7ae81f6694604d7bbd3747881aca81486e682666381f05367204bd1cdeb6055fa245e21630dca073b4071e28c7a29f8bc660b7470c4d13dea4d997cc165b6d81516a5963c69f23b56f00b5bff940f91f480c6ae44bd7de2e19032464c36578e0850c1553a8198fc92591cac9aadf1a5a506944b7cf070f4845500345ec46043642667aeee7a1fbdc72e83e6e39743d7745e7a006ebe047f2d714278774e652d4b8f76df369acb24a67055de3054a354027d121b23104da9265eba950a95a6038bbaae7b04752c2d6d45fcd73c5842062d8745468c37a23830cb2c235ace521a159f985944fa24e3789949bd25d6cb19cba7adc283cbbb5c13f23889c4f5949a3041eb4f9262d10e9d0cbbbabfb555d81f7aaae6d46e96078f349656111fe8cca17c95527797fd2735d1cbe94fb7b55a7b142c687792c69ba78622e41a4303e7595d591f9247d3707a81745b10cdc854c3db08bebefe4fe1e586b4b14c806d314bf2bfd91c4f49c53d3c39832b7a27b46653df7643c4f85b195794e2fcec223522c77167a949144bdfb2a2e72367a27918373b3568c5db161c52471225a0010ab702d8eb6be96d1bb4673aeb5fb9f3c42fb344ebac4725ed838cdbb7042f305b0d9b47fe9ea06db058ea2b79dfa59bcc82cfa9489a6809b09b38d8faf34bb44109fe1041a5d838f55f1e1d3d6f4e87c2c62444d95b53c63924a4a2be169ff82734f1c8825d8ab6e3c0c409189ba8ae2eac56f8025b7ceb44939170dfba567730c15b1ff81d19da212da639724c016e4e2b572dc3b853a27c027e1f15c4bc286853f78ed3a3dce4e865a7b833d70cb54a08559e979ef2d0fbb6ae098d199946a83748a2bdf1a7711f491f3954e2069a0c82a38237581afa87f97ae9bbc15a2719274b5c0acdd32fe3c8500d9816d1e65e8c6e035b639a67eb85982834f5ab220053beae35083c216d0975029ea3dd703483bd437aead163715aa2b60a9159701c5f3d67ac7abe2efe7eb1cb9d9d6959a0fe2f375a5b212d94af3a8ce0e48dc32138abe981c223010667b8a5ef9101054ebf8f9c42308ef946d54501ba804c5dc943ca25761bdb9f5307443518d087fb2becdbc119841059979027a0255e53c434b0ef64778160a311689673c912c4bcf91480c0add29ce887504d49aa6ca8e516f81dce7493903cf01582ce8b0ba765b65183ec2f3d6582ace360b40ef3b685ecf15b0129649b987334995e8d3064f0b9bd6b6a8c7ced25ab4acb20eeb310b6f8614ad600924fde05e0d70d211dd3a760e683afc840ae73f886ec2f3873c52862d5187cec470d5dd85e611edf89612351586e17ecb6619e9617e41428e76b78a7aaced4dd195208b8b98dd5a8b9c64d6e942ef1f86e16588d754163a8bce1bc95d7b2637bdd231996c348aa38b7bbc1a91b23f5c5ab6310b78f62e00ffaa4bc8e6e8b2324558d1e33d29299d3f629986d30c00c6c756cebc728428b0a82e81aead360b2f58ee045176699f16a776b261e02143a24cd4d8614fe2398ff156d294844119a370ab6301c76908940eef12e10b721f5167a0ebaac8f5e28d5c2c515290ea75fce1ee74c3b14fdd01f6c31d62b883b56a20b214467b11706b31035091a279d7032c743b0d616905d2d242a42a6f281d4411b925d47e42a368874b03f41a8bb0cfb6a977bdc2c46d4186ec53c2cf307727b0ed5464450f4910e2667f32004b08492a9943dbec6d80c7e2c883a86d9515907e39848114dc4dd346599e3844d6e643b674600ad2988acf26f7a7d7a4bdb0b53bcd98aa283c50d1808a981de6ecaffcfd9b18a1c05d1aed99862ce4bb6969f2589196739fe957ff4fbfd7a4980c587269d0f4fb5f31dbeb58bcb81e932e787c96a6fdfcbe55ef2d08f354da5fcffac96f6484e9324b86a59bbbbac58e9569c0428c1022359d65cd1205e54687323898214d1c3738233ca014a3a598bd2d1028b68f6e48ebd9b098b4f9bc1a012c3807c856d713f792593734bdf77c49744ad0efe3ddd8ba69e06e2204cc4746b857b2dcb464b5e19fce22583382c30ed8018e744175aff87dd583870f240f195f8ba9333d053231200f74a4d314e8420fbaf1fa5191c0053a92824928e08c1c59af92df4eb2b7cfcfed22f8cb09c21f66ecb16efffda4bac30c23861d017f525121cac7ce5a7fa08fc7b4c9062c09d45b71e9e3ea8db0117b5558401b60fab2d4f693fe29996adf0f1b10bbe4ad10432eb42533a37cf31c7acf31bbafd38e0f8423eb520ec96306ca796e7300edc004e209380ab7e7fc2ac220f9a31fddf28abf64d6a7e2a4729fdab4254e8eb10efa69a1d0c51209389f3523c2884084d0b9c8d18a28036da619fb1814c27fcc05397144b17d5e28c4ec8a2fb51330714061054a216e1443316b7a39e9bace4a0bebb6c749a93528f942c5d42aba7654c10dce3b7aaf54d101c1d0cf451c5da3013b62f5064492c5eceeeb9a0c103699645995b13d4b45d2dfd915707c5e7b81174ad5751428905f56bec8a8bac97a58a2515e007e222e180123d2e98b795c78e36a0e8389d702fde38d99867ceb1d13fa633ac46d9238a6e98617739ba9b0664991f0fa929775e09f3b778ea726c87989c153bca4a0278cc902933d2fcef7efe4155acbbe9859a1b59d44fa5f70ac86e535e708d8a337b2ed9f87ee446a7558f616e2f57d7f40261e840b1852d4c80e1f218f1c0339b1b9a5e31f764705b499907e794ba728245425a2a08a6871152f61297e4f3200a2ac57fd54b4aa5f26fac55f69767ec07b68fdcd97512da9d23fb1df845085e5ecf6efc67f51084ad7a4a41c72dca47dc1817c4b009c1111d3bb779938d55c46ce2f4ba1ecbab8d368c75e8b3a153f7b16cafddf79ed70da1d1277907f7832cc26343086ae2f2253a66f720f66f0d719c37c77767ef4dec1320fe4ab17563246c2e1b3b1fc05283195b0ae5fcb47bad37b4f07f8ab2747889f3a5018da25b20546548889f4bb2eb0f6bd5bbbd899101cd48669f99d85c60d84568b54a1c140933bc659493717c23051cc7daecb38be6a4559a35153b800411e7616be7e905c4f8247a0b4de42ec4c8628b1023cbcc209c962cc5f3886338b150c36ed525d435d4da3a341f3b88c5d434be64c42e42fc148427c8ccbb1206cf5370c6fbeb4a4567689580774dfb99f30cef20a442f6ced6d99a99e2d005aecfdfdf102188b38e8653117ed5304a8ccf96e9281c4cd45c12087b385960f26f96f02350663041c03e9940db8573847863ade07b291b047d8394954d86a1d5563dcd3aa0fb83537b04afa503383d4e135d548eab818b8cc0799f7cfe55208ea51076778406b9752ff8ab4316a7942d26060493674221347810c08894654f7a551167fdc236fe7a2a8bcbfdd2bd129729534ed6661f36443099a514b8e8e758e8708ce1ca466f7f884a55db00fa5a99c86308aafe23e2830bc633760ffd0f21e14463ddf7686d9e271d3501f6eed612e6146228d502ff04b27ba5c90b81903166b5385d2c77f11e7d94dc8b14e32036314ef99837ecc095132d646bcde6c8704b48582cba1574b2b804bd3f10be11e5217f51755b1cb65651423d130eaf73210d35aa1d1f5829f73025725eba7f61601a1e6b25d5dc79e826c34c126cd18b66f30e51ec94792b13f3c2c1f4a90387fbc1c4a885f24665ddbcdb91cca98606c9c4a7975e47915440c6ff4a31cdebc7f1e292d6eb6de0f646a4be9bb182e8007e29da06d1fb48c619f19d8a88c724ad83c27949445d08a07870afcc033f18a40fe4950e060082da0fb585d8fc941ee83bd278bb57fc576ee03ae59b5459f2b4fd9e051ed83b0da078a32b9b4b6ffcee05fe58672e056d80b62b1e823c6e764954247d5f3c0aee1173999b5c1020e8ea556881249916877d40ed78f80688ef077b3497915845464e73ec7dcc169eb2a72d519b5b92566ffa10856c01aeda2c96571a1d48efb25772fa0adf55fc480d4987ab7c19d2641389896449ec31fe7227726681b87203298eb590e984a6c12c7f8750e07368394cf718e34227c830d1cbe7a4c911c329bac9d0fa9d9a0fa5afcc63c50fcf092840e118a9df8c158b6b6528bc824662fb389fe840646e850d67f695f39cbe2c065ae895cf9ced882713ffcf10c2856be731c6cc176dd1169aeb5ed57635d2f8b0b29fc7f2abb91d06266fcf12b388a75afd9bb3b166898c3f11528ca71ba98094594270a9d22790538b9b20dbce6c701939f8624b7e3b0616fdf7d70de08bd48cff24a4e0aeb1f9c4759830ade1f5e7f38a408561ff748c7cdda29b7c162f028325c33144936d8a771bd757c760c351e37d65cc609d627d6f43e05cedd1606077b44fc1e4213dd4ac8714bf03874838636e1bdea26d5398782bded77d83c59a5ca529c798ac286f8acc8b8ff7aedef7768b08a655506d7e9a7ad053adb39d8709243f8b35e74a419e86fb3d5b3554ef8c0ede96e731c3a29dbe81d436d8dc1684301f222b38ef9cda529a57b743fdc6ab8440901c758bf562cbdd82cbb5c6ce7a0f71f0b8656ce5640afed023ed77273532a1e6af96cf911d6004962a65c9e40161a821aa8aa5a15223b1b337e09f0296b12d6624350e000213899a4fa12bf0e89a9f248d44bf5e82afc013f5627734f2bbac3660f543573069056c896ae0c8244f5bb365cd9ad5245f801de62a3b313ba9d7634ca4d886f1e65aa3c79e2d05f005f74436ec04286fc7d52b08a5ebe7d1f1811ca2b3f924b304166df52888e6af4139779f7c88e98694e69bd10f5b388d34b5b0daece16152036c4184e691e9d530ce14ccc9c004b2e7f77812dc87e31047bf7aac7bc83bea76d6dc37dd8a74dd3944caeb2cfd3d7e47571710c62e8300ad7a6549cd725b7e0b5cf1cf66379b95e9aabb2b50a04021af77a1d498678510d8d0957f54412183fa3359735ee0984a9185b9d4390c1fb3dce5355cd894987f5f21b856a832ce443371b94157c89db8b7b9d171f05d5b5fac6c4b2f551d86cb1615930bbf1c944fb51de55fe0caca823684205255e2ed5603cd57bd4f43c86eb9216199a9689cc40922c8f1c66db5b2217a8132d9a74edc188af52e0d8b2eba670b9012c23839407f6e012ff5594a630a6f757b2077794120c8685bac76f75b8ff7bd122bd1c0c57d6577600ad7dc05d15ba52bcf4e776e835a34e0d86f92d69cbccade50122c32e7d2a849eb09b8859ea58c87e2a05324aebb77d4a4e42a77fe6dc3da3ca777004cb72aa0f069975134ada697867542b8278f491a32056ef427688ed57ea78e6061463335431eb0ee4be883d77c9e19196b736422038151d2beba3bef5d759810f20455e31585b7ef17a23cb6ce1dcfce95b8d119aee71acdab4d23d50c4a82cfe00fc6e0ed3b6f67118c245d169e2adee1267d9f93f861cf6a6886df0821561e472ba271191d8b23602ef8304d6373ade7b8ff54f96757bd216c19283a8aa735ca97437071644b3463cabba6f2a42b25bc6bd993b004929b006c0b44aec77b7a2de2e249b0fe583e4a3116f75e1d343e0f95094512678ed197023e14047007408acebbc2163dd46ec4ad74ffdf494d37041831ed0d1a8986c71a398d662ff7b784b9b56070ab05e60b341ecefb9c5eeb9259457c03b0bcc34411e4eaa6e1fa0eb33e8ea3dc5e3987bb2c260e0865f0f5f17513ebbb3149bcf2cc59388acd2a4b71ad6d3e7986cf33e9a5e8f98a52db6ec3377a99d44140af1dc3bf249178b09cb8b56257a880487299da34e6a2ed9150d4874b0883610c0faf8234d667f3517ab92aeee89bbb17e97042a4c08713eb59610901dc7a13724971037cc19c4f511b5ddde6a2c7d221ec705b64b67993e2729765649a03f22c7038a447b153415e6f20af23838aa4b65df4f1fd91fdb9ed18439098db9e2c6e58aac2fecc5c538bd8444bb17de4d17cb88cec5ed5f8950cdc4240eb2a55aa34fd697e1575cb6c7be10b5a3dd6b242381ea27ed9a168c3d4ef02e26dd40702c1c6b704fe7aca49ad7002550b1cce28dd9bbbbdc9f03eb09e22c881e77f80a8abcbbdf8f444aa2b6ceecda9e84af29aa274352192c360b237eac452cdcb72231918cdf3b0ac9cea9d74ed149f733ec08068232d0ff877a6b87b5888a570b9daac580bd47b98cac471a1bdfdfb1d0bf30fdfcee51a4b0f030ad3083c2bf48e8904438e125902deccb589b0ff91cd6c53b1f04c086e4001652ff19fd4c42ac807d9ffb0ca1316de2f822a2659ea39ce0cca624e81f8a78537b919b96fc58025c32dc894e35609e60f2f8077c880577ec1be945c32dbf8404f5d4de96df0237c63bde7e6a5eae3aa1340d0aab5eed8b0410cefda7222ae6825527141dabb44fc420d6bfa0ea69d1a46fb063f911cdc5feb1d583c0fdf9bd21f36742f16baeb67b780bf77459f7233ab6ed061b9fc0cc41938a2235ab9232ab2bd646c730ec2f2073cffe2f41395e15097bfd794a024861d7e6bfd92ec872ed5afee036eec99d7c84f7b9f62212aa84fba7b689b0111e63a6966fb2a2c9a2771c764c5e2206c31a98537a59e7e28ce81e4f2c3d38070842fbfa4a5230fe2c613e3e8b2142b9fe18ca00b9551b837cf759c634a1b87de4902398b186a66c68c2ca9322ea64dc3e4b03ba4be54e2e155073a727a2781bc7b944a5a138498bd44624e910ffc254b8f7f9c585cd09a78314bac8dcfba96768627a1bdb508568a34be86ff8c9c63b7413015206016da4984d22435bcfcaacb625c45a2b676330ebbdf6262da8ff3f55bd6c30fdeab22f1e48ae4eabedbe606fb7b69cbb58498095ece933aee9e26b2f45a197b68af333414bdf1923d0d93a14e8d27bb0e98ad0e513fe486343a0048abf2457920f5ac379150ba7aa41514eafdc2239e851247d0b8f76f90bb4b1916fc4be46902d327287f4a25c65f170e490a29815b97da970950aabd3f9f63344ca15f045b2025dfa5f1432ad93a4826e3b10dc7f47ad1188ae2a45d939200bea5894aa62b90a2201149a1ec5bb05e0c5100e5e0c92fdf9937ca7d2b5501dfc78b331afbd3d829cb1a075fce0e080f8247c0dbf3dc18f19ff635e42549136bda869697390366044ed57922f18368a7627ccd648f382ba279d751e31c73def95032e64bd0d1fad21aa757d6d3844f29d83aa793916f76c1e082ca1772f00c302c10f20448c93b7b184c7386ed073e3ab2d9596927fae88255058e066865f1c26f45b411f1894772fe710c7d93b828b65c5b0bef44e3b99359bb184126348950c07535c92c41c79be0bff8cc3dbea7422605e9a3525f7810a5106743b3064f524c8401530be7946d8fc2e815e081800af05065aa580904afff0abfb3742b9759fdeb27508e591fb7b5adb3ac0680d6cebcb0289dd8f0b658101f4a97ccac727d9f4c37556c67688abb01018b8f2006715b8985dba409ccb1acfe595781abf35a4d3e84711f0c3d9fd4c001fb03a60393846fe7275eec6b6bc5ef6fb0ea08d891d0f221e57a447852b3f70cbe18de9240ec43c741c832d4094fcfb3b43ebb4896f8f9bd76d01b01ac33fa516a16e682a16246ec38f846f185e2427c277ea79b43c6faa30803b0220cf051e58b4820a26d08d67cd1240199c5b46ea3d8a4edb21151a18561664711e27864e2f29cb02521f79e4e4ffa535acb67796d387cad65e415bc7de792576eff91ebf779a9f5bef554abe41a460594b88dd9cd37799ea755dda989835c14a0a9c6dd04e93faa49963d1e30ee02522dadbe0297724c69d823c57802ce9f51b542ac805bc12fdf261f1ef26b4a99dc8c2950bd80cfbb68bef69a83551f2ad69c9eaede0bc576ecd84892f441393a8ae8d5e3b7d5878de0a7820754e386f69579dd0e4f71261147c8ba516767ec11f44af006f2e7b63f4d37bf016b4b4a9009ce28e4c9f4dd61d80405ea39696befcecf509646f6b52f2766e509a3d51f6539882d9664de25dbe879cd973075d0c605570655980190da99781f4d0ab25cf0f23b6437b31e14b964b89cd6a1f14646a3061f03975179a08ddd34339c023ef99a2d80a6d000620c77fdeadb47fca5f38b51fd9715cb2d78268d61031c5be605ac6c6ad24724458a76b8931ea43cc60fc2e055458f62318580ed7ad6d39d135a9e7502e41fcc04c97fc33ddd1e879fbeeabfd254ff5343f9272362708769f5f2b2fae4bf83590538c6e1d4cf23a29c7a2546b6c311d57852c17503b83dc77a598dae1728cb3b0cfb3e6312c725a419eec49ef8c63f65814ac4dafe32a003699af49ee76327968f43504a95d8744497d6143b4d2dd742e5a2b159338d752d6c3b66a0ba3a145f056fec837586f33187c297fe997d6edcc5219fe1e4b57f8ee5a76ca07916cefdf12e199d0ffad91147ea18c7d5326150df0339169f04e9fe4e3a8c07e2ac56d41fab7488d401db198a15a848e8d40ecf869a98c568662516c23bd3ef438609777db32258d595513caef48c719f6922b8d350f533dc44ee7c1308dacad83d5d143ec742284568abafa574a22c9d81a61cafc78522e237c7be1672b4c6ecc39490b2c0dc316540854d641165ac80d3693c446be01a5f3c3598bfd36a80e4d4e2f799415af70e6bca546e53ba4c0393109a64ae66e8c45479b028f5e828fbe8cf50aee34064fb18613e01084afa5f0c412717c90ce51d9086980dd7c66915e6ea34373b4210caf533a1cabafa4b613a553e7630e21af88374541a34fc3bf511d2347fb08ee2891ef62344840d1dc243b54d40c485527b88cba13d50129c67d549c6c6c2083f3899b9c48f7c65aa821ac0bac8dc2729c451972c9360e127876ceff8d6d5b4c518c7e0a563f9981d1efa1fab97b695c0e6b665b8c4e40cb84520942aaa5a89d28f535150d7e55219e65d17411dd8c1da0c732c68b503ce73ef575fdd925cab4e83d7919a13ccb657c042aeed8da89f8882ec311563b41156cf57af2ef6e8a4ea3757a62d025d0506a5817df2860297744fc1c2a3d0078cd0a136e6302593abbc03ca5ce3304f88d4907ab8a62195b962157ed2013d2ada8d6aedc9c7e285bf9841425344740bc0499ff55a84e5ec460d19c51e74ac36a95b0f3fc0f78d67829882a39e49f290208e90a015584a04135fa28e9aa42dd36aafa17cf03a5a04a9251199c77ac355ba5e06d0e9055c81ac3ae39941958dba3a92b2c2bee96d05b2e430cfbba8b131c871f79a84615d8fbc2b2bb39246920f4d370d74e08cd79ae363ea3411ff0318a34ea4eb2c652744abdfc5644567230329b93aea835070029dfaac4b47a8e8e049ab655ded6c34debcde773396501b8738122628a5da4f2b2dd73ae5a8f4a308952a7b6a7dc7f2748c68e747f4dbf63ac87f5b3ce90ee6c6cd7653d3795fe00abf221bef2fe29ef6fb8fad5e8c6f221649f9e0736bf46ece06bb72bf69fb4335482f015781f8b5b0d74c8d959d54caebf19e898a84c9b5ee11785aed01cdaf5a3d135613ee7a0e7787a496e9ef528820e857f7b840120d35c71ae76f640faeba7d51cb437a21bf1aebc9d436bdfcc855ede8651fddf6e43a70b50f6701068588759d4beb7d84e94ef446f0451373ec29be45b6a9180422870851f938a7581e3ebe8ef61ac6d72d808d3a762bef4b9fc0eaf41b5b84fd0070d92588f3f2f0e996f7ce78c266a1797819858dd8dc015c202d2e6e60d9a3373c2f26e82f3dd6c395d2088fd9953a4a81944f921a507ad7ee81cd2922be808aa19b244999932023b449aa10f822e3a3f8da9d0180a434ad3725e5822e63afab64045079f0c7c264782808d2a823c0041e06f50d3720a3d5533c2604f58740144ec3a80f20fe5be4388aaa2268efca6a192484aa88a532b694df8198444c00d7a1e593aff449a8625506391d562c9bd21262aa09b911c1268fc0b960427ceaaae4ff41ea42fe5260134a8147aef20f3f55fe5c271a56db0b7754b3b00ba6cbb37a1fa89a98a435fd174d05cd9eea1c3e40b878df49c4c1933ef2eb64f9cbe1a890a69de74231c850b9d8507231a8750c41d30908eb7d121cf6f58c40399bb789fa105d01921d6df9efe616bf4aa44fbc534099687ccd34c2e806df91f518aa485ae719c5fd66a43bdb2a1aaa674b795ae3b995fc099df1fc0b2cd8b36189f1cc7ac2692b11b2e218f0ef596cce46e10c2a46ddb6bc9edd22339ae271f98f459f94d6fe9d4fe253543e127b271871916611899cde89b5ef3eaa42b0cc97b9e63e3bb686dea8ea4f2e125bf11c647e909138c6b16d9e88a86d352c822cb0ead0bd0fabc1db6a39b2e0b8bee4bc1b591f863346822164dc8a750eb88b8ce22b864edff5e46393dc8c2c1d953911642af1182f22319d7e83bb1b7b62a7a9ee17d274d134c99a715421d1cf43f7c861e32c37a96f20bd8184fb5c6ada1fff5636d622229a53c5d380e3d9d9b0b44559e9cfed9fe32657ae2e04702282b3378ea02dc4feed9a5c23a0b9be19b65f9d6dc0e9bfb65cde6aa99f5c71bf0eaee9cbe01117f1bc98a029cd92fbff7afabb54136733317cd62ba2dccc0d93c38c053bc726ecce9d7bccd59c324c402f24a41254debcfc358f22baf54818b739109c855b489e47e0ffd1b88d7a271fdf5acf73b807fa3be9f1bf191b34fb1e00bc674a7e7e6aa0c5d39eaa7359a5bb8038bda69b7dfbd4e8968b2d9a120114ec1dc0e2f5bdbf5bc520191384c6e207ea5be25de162cb59956d932e0e5a1a2c5c4e5a674e21202657c0aa55d76269185220aea06dd757065c1aaee7ec974836f8ac2f15c95edd94a636fbb448e7b6a645c3f6c3e694edaf8a3aa029b18b8f4b5ff5af4eaab2c00fee4eaf793abcd58fcdf7504923cdfee1b4f3dc7d9f953d679f4461d8ad19facfc586d48dff997c50753cd9bef73ddb6e5b628c91c919076c31c3e1a68a7f543690f9e03f0e3116b1330ca11852f3d869aac22fb1a4fd29d98888655a4a064a6f068233ab2a044035874633a0958422385a19734f39a1c8a42af39c75b13c8e59ace2dc6a915cc00e42083684afc2319b3b62a8d73f998151aa1c4d4da8be3356a62784035c289bde6de2a4a4aae486042ea0ddd08c45afbb771a585b7ab626a85938c3e3e7d5ed7b3afe77aa0aa4d619424e4872857f5b78fc9705aeb81f476c2f092d187ed031525152a90e173996b3021b1747f34b5a24d5c26645b498d21c52c75fb96b92eac4660ceb5a5ac1df6e3b13a422356e137b8f2b635616d7812485f6044cc367a6a7a59090959ea95eaa99171d41d7e91b66b2625872e006f08af3ce7b880c22f2c8a21f71f948500242feb08b095cb636dfe2ed295f8b12dc8ac14073d865574209acba5f5af99dbcaffc93f9a77f7d7679aca4ad1b678772a35c4d87c2d2ea82add952f0291636efdf303d0f9dff7690dea056480068e60775e3b1089950a0d1e5175160fd15685ea0c8d65443593875e0a4c0993acc002fc42928cd5b311929290664dba20b9ce429790d6f257f477069902304e2d95fc6d1879ee7bcf7961f77e93c08d6db8f4993fa9fee4b0e94b2b9b48b6e5453398339909b2a0fe460f1ba5a1b64474045f11c328c32580ea0802f4e21b2574dd9da4edb59d416cdba89ed43faa40c47ba52e53153ab1860ce687c70d2a34afe40e797bbf190169ca7012241efaec2c2688ce9cd0fbea154e4df76fb727bcc21e5ccd9a4cf7c06e3166836358990670c409aef20b42accdc1640d863c560876fb962a14335bc51d218401b2f5e359157455b84100c7ec71ed9737ca763becc9ab695947afac24ffce7b14a380e976ad6f06b11f006a5c99952d2cec91e4de0c43f5bc5008b57596020a2828936e4435ebfe6061c1d588caee493b0503bf544e2733a46748344c043cba721f618532b3182132e2d25106a28072d32a8e2c164c58d85f8e91f0e0590190c4b96ad731d771b6935b99875a4ea165bc3bb330d1fe34c79cb299b0780c1a2047fb46517d42c9c191fd9a8794c5bf7213b436b113901df5bacc1e3a242f898c9cd806225687f5492a82503e04cd1d0d2c1d91d47d90e2b16bb2e1641ffd0184b2efe9ec88ae550cf389513997f1ce9c72e2e01b95d30ce1559c8f3063e8c65fd9c2e2f006f89d46c24d17e5f0d2bf88a5d8755d9fec3a59e615d215c9602d4654f707acff2bbdfa6a689add346abd4e184d22bf5dbf14f8e7e60e7f837f613f07f2ffbb2cc7fb966312f0d36b2c5e7a4ff64c34e90dbc6431666f666af6cb1afb9b679325d86f5e218ec162eb16650e7994d4bddc3558ad30a6ca067160b3f532e82efba8e738fd7a8d58bdb9518cc109e42c76b2fcdcadf4e5a2e6c744a66972fd298369413d17a005bb169036e8366e81e7f88de22ee2e270f600ced1213b48d6f9394515a5bb8c2899ccc80df5f29a5fb0c6c4060403a56772f0b2bc46320c88fe5122ecd9af4160e46417e8fe6e69c56792981841303cd02894ab5881025ad782dcebc96c8c10a48abf69450f30ecd97c99ffb4da946ede0c5f5727846900e4f10ab77c10d6e56f46dcb870744849b47752825f7c594e7457fbacce389d6f511642660bdc05ceb9d8209899628102a370f5f7fc77bb88b45874337a60d76618e67c10527d412b16514526b3b358cc05a9ae8d1c554a97636e992ca4fd31311e967dbcc073a887218450e259355ef05a25120651babfdd8d00becdc6bc71145bc9ba1dbb19a1644c60765f9e221f5cf6b25000f0949d9b44eb716376a24ea7ba1ea4910d5c99ab290b7f39eb60ee574bfb7bcc2817838002a252e608b6b1084510dc2187bf95a406c0deb050819552721b6c96cc3ada4c4bb95606418df9bd4beaf135201cce4560fd2b1b7afdf310a6018901ce353edd8a9ed13062242361c491bdb35cc5aea5e33008ad1bafbb5509a75a951692e0c887aafa81383d99f48e7c2c8991aeaf6c603d359bda7fecc22fed30902d9c870d1fc641590b9c842f53fa40882e034fab998d07dfd8f0583979b9bc17c447addd2f5e00530e8f1a5dc9f29ac861756bdf3b557826acbda512ece68ae807b0f49e8e28124f959208aa83f78d2bf6469af1602a2e99cc3c65e23304fa0a280c7fe2ed0b1c0c61aaf5bd991525d88128a0444a87294d2670a9493ae7d234d0b3c2c4dcdf7f1427b7d084eb8e3141de5d628c48080e7dca6b8a6b1e7a83899c551d0de45a8cfd8e713f7095e4d2059d8d7a09d2373d97b10354049bd8df000c5fa3495d1733d0011d86d81fe5fb1e2238edf129198823a3b749644b402e07d2b08d39a20907a53c1e3fcba8cf0dba65fa85efb3847ca97dc04ec39851d1f44cd5309d5a902b3e2b7eefe6053b5f2cc9c56fb2badc475650f235b0941a0bbd7a16cb95bf1b7464f7c61c104b37e3379d66ce9c1505aad2fd638e9bfabdc1cf7082aeab994606cd29b292fe4c37b9aa1267eb35d6ff3ce73cc0546085e674a043e9e85d22baab248cd0208438cc7e3ef6aaf713b6bb266ebdef05f46a851ed28dd0d4dbe692f33bd0aab2480b1599df33f68f27fc28eba59bf24a752237a6266fffe1d53fa6d81746e1b07f68ad3267cee87fceb50cef7f7511704406ece02d0095b35604d0ffa4b46a5f6321b318aea45738c9469994d9e925420732587ffeea0fbcbb927a7cfe683b5da9080e5130d4b055517d0355d7f680747e0c753a0a4d15d6735a4c2a8eee89ceb611bb8eb8075d804a5fe9ce977a4dfa1967ad948e5f7e54bab9d4b5acbc5eed4713badd1406ab059ad5d218a076cdcc8712586a91f9c0bc98baec9babbbefbe6151c003cc6d9f29fdb1f08243e4a6d11d4c0136cd04733b9437d1e15e2d35e12c68df045c71c643e7c509f1c85d1fc71c83f447c9ad29ff9d67497cfa069dbad7890beec5edf5fe63a362e8b6a5778ae92cb90dd90090051c2e4ac08dcbd0b8b05bac63222d8467bd9e31e5539c6a45fc27dbb0f63b1577b898ce5da0c72583af81c3c53df6f30d1cfa36943ab750cfa19e92eee17c3f5e8cad76ddea19ff39aed125a9c82e2c7f4b9a66d35986187472e17aa95cd47fb55c5abbc15c5a6eb8484d9477c4599b7f4a8864cb98f7b56ac6603d28a7ada11f01dd8420f211a4ee5df2c38fe3ff775a3b5e16b66ad6d95d98e1dc492f0b6c3f7148058f5b94464e37075ea8174e80cbd55815066b955d1bbb8565c58a309736640307cc1ceb95b28291eb3b40e70c8c4abd851997c960c1be8ea3e9220a7cc7342e3a54b90ba8c1b0759ca77a84ccc55267fcedc18f01eb6098a19adb92f29c1bde66427061b94597a08426ed100f6328158f8d1f0cbbf20024ff5b0d1dbd9059d094969f71128ad5a3aacb596f9bd1993f913d2c72ce57f97f6781de61dc68cb268d49cbbdd50918ff16d0aa5280992f522892916dda49944a48957bd1f0d23487a147b5be67c07266a2dd001297dd143382bd8ae7298de55c48107b4a8f4849f463932d896b922dbd46648bae09b2c58363b14fe34c98103383d5502943bd43b21051f0094711f677414042e2ff6606451e457240843055a17ca66ca0b6975277bdb83302983b7fce2066ec35ccba517b23960b21c2f5334cb25a497fe5a1549ca806c3c42c4c9b53b9fa0b3939ef6eba683bfb6418ed4579b8957399adea60b92e17bed69ca70cff3ed8312a051a38bdbae5c3e6ca07eed1797f652b5e3287523819433ab167b40d81dc4869ae005beab83bd03dca6062072ef89612f8788e710b3d869d5930c9b4a0139bc750e79e46415921cc8b721c50d002bd92d79380b967288e6aec2158ed49d178f806468e283346949b90fd00351089cbf8409d368146ac67493fc6c63888e762c3c352f7d22fcff9b807109ea898ff159c37eb8354fea1ffdcc07111d7946629bdb217521344346a31515f6f9dc6248c5a709f7552c43ad10d8225d662119f4175cfa0c2b5f40b3e88073db7b3e7927c16a706788067d9e8ce3b902d8274dcbe5e5c19ba9aa110bdf5b6cd2d02c984790c8f27215fefdca574a2f4f5cdd3b64d485a324ef2b375eb1f815833bd8d6dd0d843acd0b085beee55a45b79f7f3012dff682fc443e57debc6e23b121126277a3432537489b68cb095579f267f965c497b34c9b0b2e449dd34ccd0aed2e94517390b21b98c4c984014857a18e2949be76ec37b1357b1b9fc659df72cc6e4b73bfe412d4312eb2163220a3147ab461bb00a384fc6b164211783d40db45f7e6d2394c5869a8fe833a913b331b87bf31f4cb118268930155e890333ed56164a4ab9cad8dae145c4b161a2b6452130a9a591cc43f8f40248ef781772b57bd413acb6043447b1acd2307571fba605b10b9cd83c01a0542334c370f7c845951e20cf125456b2e9c4d0761649845405fe821308850a2fd7526020005774c11e7257c86ca4238875b0697462dd3d2e79fca55c4e04a91d401e4b4afb4936b9bd18490c64cca2cc22e6d2b22654d2a6a930e4f5ddc478aba95a4e1869c5c3f6dbfb52d3ed54ad1edeba2a805f6a98bce4616e8b7693e3fb39494f554427c54d9ab5d664c86374b240fc65c2382b734996cff223a577c868f041bbd57abc22cc02daea912ca15ab81779b56ee4d270722fe19bb01330c19c5ec87dca51fe86f891ee2de6b5a082685febe835295f8200e1f03c210436e00cb927e0b0888159cb5cf4dd815d23515ef3c00362e4d633dde80d44e6a541e5386d269da0337b22edb1d9f4b9e852a099b4f63e99abf2c5b099e1af1f608d462a10de9e56793f86ff94a58102eea916193360710d62b2e992d4e69268222526c45c65cec07e2e53b007918a9468a122fa8b94eced02ba829d8c3b6a15a24922e0e42eb2cb19a9328c5096a77a8d0d12ab876af9da981feaedfd3ed669e8a0aad110d07c7077da31ec2c0a710c02eb80b20a7ffa3a7f0bea76e6142afd454764e4acb53d737931812d28a500c11295aa1f072637800095e479f5a432be6e4b5aa3caf5b5ea8aabe568335fe0182af75028a08ee1e118717eef0383cdf8e3da108b1290bf4486b5517e78089bc94d7f32c984d5efa89a9a308042fd47008d5d1127df692634ec94f779086474178ee9ab6d0c807f36e9c18ff1dd6f233fa3b9e272297f09e7dd10ade36424a04cc0c74411813874397e87ff82c04d288c8bf0ff34b097da2e7f4d4d8b80169a372bacafa99f75c2bd8407e52d9346a0fb9313bdd85e2fcb27c22f7b071299255c2a2dccee1ae464ff8818441522142d53f0717e5c2ca19efa58edb6d3f84b359d999b95ba2520eb7fe95eb72a0a046712344c52a97c2363a10e430f3c86eb623c8585a8becddc8a8e53de11d9cb460a8d5354d837e33af14dc39c2f0beb874bcee72a8f7bad0fd94662d89402888ef1c7c056b41dcd3194b962edcce5bca43d43678d1112342609ecd594a6c82aacf93496400d22c3bee441ff9bae14eea96f8795e0633afddfcf1cd40fe5d7bf34ebe7e5d372044713d53938bc5f5f0f9cdbc1c29e9ea279fa8fef80bef62e19dffa4857c0eca3109cab078e25ac7c16306431464d302bd07d1a65026346003ec3fca5d3f33eb94f454ac89c6b2d73ba003975bab04f016e304c1fa9c2da067e566eec01e40d37ca594652992eea1129d96fe12f038b9eaabcaa326d67f29b49ea86bf766208394a7a14cb8264725a7e0f0d4812fbfbbf88b92d036209cb22da86366f9aa8c20a22dfca56c4ae0cbcf389122f90f426f8c8c69d4473f8b5c465d4e424907dce6872d0fc203ea4772509b9c2d87a9a6c22909849436e90c33223bed8b0084978df886541d1992b4262bb7ea4e5e1e88ff0ae7625e28da523f7d78fb49a41630a8bc47c906812489aa91f59b115e9e96049ba22029820b47b44abe258ff6adf54900335de0151180907b3cdd30dc552fe9dccf951ab311f90f618d1f27615e1e676cbfe7cb83fa3079bff560f9d87acf480e0fc5dfbad1930456c2d751eb5e764bda731b45da752877a2aacc63361aace0ce6d1766c870096e9c14fe8534b4d1e66330e458b031de8618e99bf0c3051ac603ca87e3f43655533023dae5eec7a7f18c837140e6ace21dfde568f5de279c53554e5b164b5360a34e5b06db8672aa169be8d00c16c3fa4b91396c62f75a1fd6dedf5376bf01b8963743119da074f4f47757f3e95b81254394bd4f6c910e836a1832afb9cc4c930646fd930a075dc079fa7c7b50910ece278b1607b4f6307a906c07dd93e154c5a3ff8478387d3997980f100a9c506ecca4eb1590c899e21da66d9fc500ee34f105ebabff09dd503c9154f7bd6d49c08e97c345415db6a83eeadb06c27c968637f2d41e89fa81d675f1fa5564f720f9c28b9613b5102fa60f27f8f94865e09e739499ef08048df48a87b1ce5a9f56f8eb6caa091cb6a15a8eded7ee0110fa9d6926e54c6eb334db45d0495271c9f536dee2a406e9bec7f1a0dbd03d441b7e0c5db72623bc90038ed42908d6e7c844f108ce74ba49c6130a24f919199b6eac2ce1157ff38fb8b0f75b7818a330c582015e794ee24da779a9bcf3088256d42e88019faa03acfd289f3f55dc15367270e0fe68fae79612c7d577f6dd127280dafb17d4fee932057ef08120d5bfb1135fef3d3061de56d9e09d710680ec723ff98561c49ccb457b474ca2d26b6f097c2b9c62537ce52c1089d2e2f825eee9c2ce7d92c5c311483b17f45d98312466d26fc17ef78e5908cdcdf15cebaa6094ee2d0ab9301112d20ee4cb82dcedbc442e25e675fa388d508d7fd019a921546288ee6c57f6c5d79a98287ba19bc2e0ce8bab7d7a307a6bca003064c1b6cd3f294dda551a1283f0365828db56183f555282a4e16907e96f0c194dcc77d0e8cb5226d39093424e1ee7e2c8224c4248489d5a3f473540b0a62b1e90a417900685469d1d1c625b536842ccd8d694064562e16fdf75acc1a1827dc435dc30c29043104f3641a7bfef074669d5da7293d68d0c6913e759698c0a342e9d06034e14bc389df6b270b8fe099565772c05640f3188e989a9b8d69ca857866a27b71afdf7eb9111c310a293c94be5e672f3339f45cb2ab66ead060813a9a1f43d262fa9f5a4267834c9371d1d068939d17e5e6d7e41ddb147be39a73366292eee464f6e8d7984e32f23f1096723f3d86a579c79466ad8ed4201205b8cd9f9388d4dbc00611a51249205fcffcaa9d60824dcc4618f66bb1c8513128989cde7ed8dabfbe883a21a09f05b5beb1e6dc05e26f37e92e69038621054940dd4ecdbda056acb2aa7020a1df82425c7efd13d9b9052f73c2416f02a202c04064407b074543177afd3865f7128ff28424e6e7c1f0c45b392d6159e796f36f3d6db7a28cdd07e30ef042cce1856d187f0ae46c48cc665875ccd67c218676beecb37a11857e89aa58c982fb678c58d86c098b07b76ce00401b54a3442930f248ca36875647a311c4eb41fbada2433542d0c05743a3d2460f1019502f3162a5d7d209b3c5201ccce847d918407e6d642997783b54c18deb11a48bb180c47c7d1bb650fe4d584bb578ffd52a52f5c5782ba9f522a0cfb280e7a8a7977ad6cc04a9dc3684b0de82110d6923126fe1a1a31f4d6dadcdfe3108d91e5958c5b7a652b2b28089a384ccce18a788c22da38d1ef2c4aa3e31099f2d5fabdcb29102f32bbb9cdfaecbe77289a111092b799cd11099e72e17638d0eff420cd28928728f019029ad2dadae8b5cd19fcba15ab61322bc11f46de402e5c6ea2611e40a22a4cdb2c1180557709a715e6e1859c8abee65e331be52d9107ce32d92082cb6ef6b4deeec046d7aeff0d9ffb681cf00d59e04668768ebe0a8421262c71450732dc0998c342614136d8e7f60b8d2e8c7a724fd6864d85d1c77347a81d86b941d8839f65c38e3fdc6a4ca2b3eff0c7bf0d78db3378fe952b95acb7f0daf96156da495cd9d36ed3bd290a81b2d11caeb172f89efc26787b6e92b745a08a6f252d5152f6910ca1e0ebddf99502be244977f168b8e547b6a5dcadfc68254f2084bcb42bb4c1dd57783e6ff04f15ae020b91d9791dfb846e6ed3da2d2c0bd2958bafa440e33850831ffd2d9718d4a22014b644fefaa569166c307cdd2a0d10d7babbcd3450e192644f9b6064d1bc288c81039f039f2de6f006b7e7ecaa598d5790cef7e5197c73b589802698c530f21541fa242828437b1aa9b0a92efcd4b3edd5602b75f0b041e66f89d6b8198fdb07f34290ebc13d69460e5972fd413a995dfd23a710a0c270c4ed7742e3060a767855f0aa6409058019ac9af432b4b284cd0e688b1700717799d93cf7ac9cf9f987105574a8fedee6b9212a5e9ba8a838da91dcc297e18a4c03570d0a23843f3fdcde0522b5a78fdc6efa25606e2d619081024f68bce731913afabb071d2171abb5315ca6dea719c5e81d7bb54b10b1749b65fb8644fc10bed7042326a31d5d2cadcf91d762bb8ac052354bff0dbad662da0d43f31bc0e431e3574e3a8fc4ca5d339bc8e26bc13d0262c17f63500f3c8e2a24aec6c207714efa17bd9d6b74e39b056345cba0909efe45141e99bf63d03240377d2163a1978cd2a9c3fa2b22427ba8a9fc3b474084e7e34847e5ccb9200cccb161c69d0b331508e3efef72b6814b582f59c25f33d31441734d9b23c8d493038d43339c639c71ac7828accfadf5f1ad57585e5144d2a97864560bf9eca79ddb20c29cdba0c9138d186f6e457e5b59baedb114093d6cb91d3e56bdecbf8a360f82d102b23ba85e8d2f281c15185535df3bec0ca881636756c36d31355a77212f35847b3911683f7c8216156f901b3531b80338c264528cc46b0769b089ad03463eb001e9e7d2b7595e3e9c0320442332dd33c3036bdce39641259d3760efdcd08a9ff58c85fb2e47da85a844c03fc9abcc763de0882596c0b645ea53cf635aa74ccc9d98b517408b4c29cb9a9f6c59d16f1ec200dd848a38272380d03f7a13d4add4b7f58d152b53e9d46d6bde8368db1ea0213fd5cc6d2c3e7035053f1feb8595ccf92bde299d67d6e0076b84e41269b88fa4a2ff121432a230f91ba25cd028f654631fa2553cb2aa0d3f39cd6408ab8c74e18b8f1021e5febc1a230997de4964585fd65ffff8bfd784f63cfa7d8a828dfed3036a89c53cd46c68a56f7f9633390fee788a364462ff04126f128def3804f312835d6ff81fb40842a022bd064bbe092cf70b191d2ab1b88247c8b0a91494a319f2c072f23f646375d9f14711f281e677c5f209eae8b98d5803a6e11249b583ef4da4cef3153e50fa0b66a4da39907b8cf9d6294cef513d505739eec944990a784ee9827f3ed4393139ddeb84f4b5ae8a9efc3e8c3db0a036e10e1255292b22d9ab17c17428ef8d75e3a3902e346eb680efcfdd27e51f776d9ea715deaadad2d5444bcc38f6094f421a224b90c32921cae88ce086ad5a92e9268ae7ebd30e938233193c126d73b2f5dab6c655bf45feec543c89e8fcfeaabb509a485a53ffd108a966fdfec5d63a16d8e11800fa8da9243b28593b2dadcfdaee45c7ee41a39ee41851bdac7591b7628d50ffc834aebce754d8d2dd499f3114f45d067f008fc15244b67d74a5718aa2a53472a1e5493e43623ca7b40786172a900e96e8cb5d9f18c408adef8712b4ab7bd7274c1a3aa99ead4fa0d92a77efc160ebb393d2533abb201c93c4ee6e8a3c98026e2b98b73ee48546e881db1adbe57f58d5102d635c1f65ba3cb622e775a7afaf4cff47cd930d2150a6464c9d5f2171ad3f7d7c06d488a4ba2ca761cdc04cdb44244974e3be8c6ac21211f2885500cc600f397ac348d2a6f1d76d0b579b7213ce5dbdd59cb63927b88bb9ed390ddb3a000b66ed8be9d01f440fef7d1077de054b7071ae27a9d2787f4c024f2596e462648359b8f3d771ff9f171b80eaca5dd2bc86997d358201bb3dff40874d1306b1362df5c37eaa0a50e815d23e4879ac9798a17128f5bb1b62a24f1539d1448d176068142cd0eae5ab27c4f705daab967d217a115fe104eead977a5d00e22871f460e2e4cd2da8bb2e12e3125963cc6e041412ad507c6d6efab61dee4b1b271c8497891366f8980fd22caf08258ec86a5411bd94c96813c96d15ac87f2770210ac9d7b2c9b65153e1346fa43ad43617ca02595438a323c13bbd36b6a079e4a46285f13834935a517f385d169889fc121744163ffe9a69bf02a94ba11ef7b78eb7c7e5824cc9f009d9cb8da74100270b9497eb78d8bc7e07035bc43f805bcedc3b868da0f8d178a0f3972077f9d6ffd7791adc7ff7660dbd22d24fccbc0d3c12fd73d2e7764089bc0cba84f5ba9c2c7159022a669a0d6325ea07dd40eb00109f70413c735e1e9ff84e2ce9f95b2f8672e8d2056511d501f5c469ee19102298ea55a3072c19ee8c89540b558d053bbb9b74fe849e21f8ccd78aebac94ea26632b257c90fb933a6c9ddcce06ea1f62abf328801647870a1bea11f89ebbd7a6faba98661802efc9135c05b0641955e802ceb80a8e831b6a6ddb26f03303a2e81598175841a1f126fbbb602134551e8ad442d5bc335e75adc38e9516c27f12c44923792d52cd063463f882d90cb4ceae463f03a71910d7f69b9762dd77555955bad490ba6526bfbce7f4047c0f235f6680379175cf028de7ccd8ebaab565697a22c285e0bb9bb8c4b7b2697d8104663d6f2b18111fb64ef2ea1be34a459647b643ba4808d5349fd44dd70841841bd72b58d435797cb760553681094af975a66a496fe1ab57621b6b5f7d678f24d32402bd6b43e4746fd5e4b37b60fae513de5e7ce38fbf0232cf58d6c4e614afd23a7bd1392cd324610b181f7877f37265b8e7f85c1d438a4d271dbc93efa206ea99ce8db8046c817a74d176638e52eb39af1ff974bcda4e99aa0e27042a6e25e23478349bc1971f223ec732214191513ac695d6c645ef0b6c6412e1919bfd53b3508a5616c0776353d9cc4038ae105608ed80124983cf8a4caec538d9d7d6fa811322025dd74b2d521db7209355965fc08133036135797008e4297b20bd10f5706ae4eed40a396b28f9668ba590d146deb07596a064f750becd6888854b2f27e560dca98e23d075547f2d8103f6e8ae8edc30dba13d613bbdeb94667e0433ff47a7803dcbc7dd205af5a05b2aeb4a9ffc976a0840bfc39771f1728be960e32da1f16fed913dfc47672771449e7c2bf9fb83d053cf742c01e8d204a5a61e25f0309983922a3f4332086e3539b21386ef9358b44b7897cc16a060658d154965672181342c116aa372948823a085b99b5c0f5ef888e5984c6d690b8ccf4e1483bd10c39615d61c6d5090872b1f1a63db7651787a81cb6afab5b1056f94c8491af4c776db12d04556c51bc11e8577a0ffa17af9c68e4d56d0610e4549b44cf8ea6c08bd481bc21e57671ec79f3eef12d9ef7a203a396b31717773137c8292cb15f3d400b95921d43e2f9cfbb5f45d98882b2fad87dc3fd81b195e30f1a4a8c4ddc2e1b5ea97c2f551bcb722d5d1019ef73919e441c99eed5c9d5fb51bdd06bcfba153ee0d15536d90f8dd507b320fd8333377cfea2ada22a57b3dfeb751ab6f31c952484983f044ddb2cf49c29ce6291fb83f51bc9819ea1c6cc2ab00d446a3069e2345335cc1ae48dc293144c9717de7a07b5d69acbe039e66240eac1bcfa721c76c592b6cab240085d1c78931cdc661f56c93c374cca5472c587bf0b93823f128a4737b9cb0d9300e50359590029ebc44aa58248da2c0993b2c2d1a5058ba20932988f2f2ada7068ba9e6f55bfd9c45abdb75277fb09daea8d61e2e819bcebdc94bde66d40f99d10ca66dd3b25e0336907070f709895cb57ab982e3f5cf366f99b73702c35ab3172a7f996ee558c1e3c996bf268c90ce7bee24f3dd9763f2a04242e265a953988358c8eabc2ab22a152807097464826a2212492cfc1bd0a6e34c727713d1453051d62a4948cb140269b1eed5134aeef9f9ada0e8e157a759f0ae7b2fd76a9f4e9637ffabb3a9d72aa02a864a1e8848a778fe96e63d69d110de1af2c3c62cd9621780e3ffcf373f76424770d89df5ddd1e6a772aed567887004ec55e44ececa55daca6f1c9108d36d29e2bb44bee0c2ec0ebc7b2473c6be03d0244e67e62e8441273668f1622e13d24344fd51be48611c33c3e81ef7bf3350bdcb5e4617af4eda41a8ef5a3cf01ea6e0ecc720eb2b3c79b734d317bcb151b438ed747b5c99e47e69953790fab8d2a371ee1ef1b14d62ae7a5ce4a42c0486fdd78fda144e029ccfc1ae5baf190930128b93476a2f729f36d7c66cfb9557836edf6dd1b0b239ed94c3cb39b7a7498a22c80445e3fbb348d16b1d667e26c423ace6661eb05f26eb9d93f18744da8ad8235c1375a5cb7dd093c373bf32e6c1898ac0dbe760c8414b9d62179c9a64447a0e2ef08e45bc1d211fca254bd17ba1db71e7c041ac3643020210f67a1bb56962550008cdba15f7c80e89b78174ce55c129fa7f4df5d8ae03394bc408cec12fc39fd7db479961e9906681897b82f79399d19933298386d230ec32fc884d4f322a299871b2759bd96c62aa1e04ab80e65f565c0211b17868c0effc968777ce8af55e61009424896c7fdb43c4fa4a98f18f3accef859508fdc08521aeab5ab66d8544918dc724b1963a586ec4f22dd52113f36825f955e4b42a1f45e18826894f94354f6f017338dfaf80d08bdf67d85e0a013adee4fb303610666f41ac280198a3bb673ab0d6114c5241d64d7edb5a009e9a4f9d5cc8aabbe51ee52fbbf9a4891410f3eaf773ae9a054ffd3858c2ac28a9b293830ccc19d82c0dee3b7539529f4393d0010e5612df443053663f9d957d4aa3b836c5280a14dd8a0ea21585b588492073a3a1e360ae228b3c1b5ba59ddbdb771b72231827d84e436d1ebad796a479c7df89eefa9917a13d18e9eaa898715c7a100dafd9d55ba0c2e7773c0656e11e518c2c3ceff9341a8f8fba5eb5d5d282be73bd0e84702da6f509518ea22d24c062891f19955b00275cbae866c5d1c40f75ec217f201acf5989e21129ae3fe2bdbc7f41c3893ed5ea6830541be0c5bd9f90baeed3827640137da59421eec1fb9c7d3526e98e2b533eacc75d388be785bba0525cb0534bd09fd7ebf5bd4cb62b3d697d295966ff02b30210599a90b0d8198260980b59e2477ff9cf81b2331c9361670140b7478611a1615c6de0984217b0527ecc3cb0fcab54066fdfd9d7f1a19869f4ee2041d6f6810607b8170ee577c8b950b93759a95effdc73caf30bf53c60c7d5a1ba3ac5c7ea0fbb90503715d91a51256ab18ded8a9184c9f7c8d4af7af77445b5d152927447ebcba51077755d9afc8fdf340084ce943a9764b32f664384d0b8217d92e9c07bd61e74ca23d3c0bef2fdb3d26f0d9db08445c2b9b20cc5328e773464c10fde10b277b482c33b6b0bd0708b42f30480d9f6c27175d1b695fe204a35f975cb96e23270a7dd22bfd4fc35b4902d43f17ec09c44571d9d2815bc2d4fc155b530557c330f52dea7fa2b95c9fa0993f54d8fa8200f7752b0e5aaf0537db69292f8cdd86e0b5d6f2d04bdde68c0f53d6b149115777b358a92595f71a44090fc4d1186be3c115087009a5bc9bfe629f23f330502b2ed29110188765e8e635b415a7bb88859d7d765e242774d5c05b4301508afadc5f9e4aeea3c09c34cdbdb6eca5cad9f61003f81a4d50e56baf5de3c1f66e1c8f0134ed33caa3b86ebafac79e4a93afa8ab8ea3ff36a5c370518f82744766d3c03ea887af8370299a401021361e42562e3a30a53f42d73224402fb15d2825200d444c00964c00c7365238c4dcff2a369b215a72651fa8945fa2723741a208602782dbd716aa49f39acd8212e919d24354f5cbc1c4bb0086eebbab00d4a3057beba8bd1eee02ead858ad1e25f387c56058c7c253922d78819dd6ea9359c5902f0bd947b1ec0c1214352abd18811b18e314d2ca6891ac0d411ae1e71331c382632c1af0aba387185651798c3697e1776eabdeb780f0865daf47261c11126bcabbc5e92b81def207e8d1ff38d929e1028713346a35dc69b45e800c921454589064acb1ec4e182eb5c3c59c3682b86334014e35194207c2d89e5d94089e2cfad475c16a1e3f6cf15b48e0fc506ea5508d251925ecbb32429d88cd6c009b3f1cf6792d475eca4fea35d054200ac1e8f8477d9e7b2360937b8b53e80cef700150c9f56f2cc5427f302c4bbc4b192ccec4e0ec67d12a3d369de83a802399a9317d3d5b9045705c3c31d9ed2e3e5c94639052c81761927a5b75d14033df0668f85c7ec639a278afedbd8433c64a7d833d9c3346742e4dfc8203fe265b2a530bdbe1ca9701a5b36e25011b642c1785e28bdbc7bc45a484fbc95ae9398db147742e24cff03b84953544d7f5f73a3d4640e8229125ac5bcb7c9010432ffe20b45af135bdc71001f9c32671818993cbc6650e6e2601cbcdf0af180271afa31308c280b1b0339bb80349a09ca3fc3f97fbce03d69ecb3bdd17540b0641649f5ba2753c95049e7b05a1134e1038d2743afd15e23ef27db26f47d79d47ccf1b14baef46cd6d0086513c995bd7f7007254beea0e469a064c95df4d23e50b23680534594720a25b33355657a4b818a7526fbb547b191bdf7965b062e13bf14591338fafe8af8d0bba74cf24c8b2e2b604c5ce8ddc33c01260d8a22635478e8ddd35c93d7e4fc3b3f73facce933e79cdbb0947aa55ee55c224b5efece387ee71bbff36d83b542c594b31d595a7ae7113da288159921a7a24eef9c468c19bf24182e64f6f4ce157e5c899355c26eef85de390427557862718cbc25c3f4ce1b04c9d2c50c13b86716bd73dd75aafb7b1e3b1e3b1e3b1e9e2f3c5dbf79b87ef3d8f8cdc3c3c3638782bfbf346dfec69e28f4e6b1d1a4c85f585594b2337af328876bc4a0b97da95bd1a637cf12eacb1f111f499c5d7ce8cda385c992aa306157de98d19b8789c10b0c2248caa89cf9d09ba799769dd2fe7ec7b9e3dc71eeec8cd9d9d9d9d9d9d911729d84fcfd306c18361ca2497f0fa9b686c3e1d02e45719d52147fedefb6efb1559b5ab5a955dbb66d1b964ab952aeb62dc1b7fe6e6bfc6eb71ed3f8dd3aa996c4795659e19de9dd5addbf25756dc04cd4882345ef56d95663cb0bdf99385feef46e43105ba3c526ae0ec5959dde6ddd75aafb7ba19dd04e6827140a856d580af36d61dc631726855bbf85337e0b65fc163a9357aee0801363469f97de4206c099e9c8e3b2f2068ade42e57d43f7d47197d742af89de42aa2fbe3f1757cd39a6dec2315b34e264145112658cdec22d5f8088fd90e343d3426fe1d8751afb7b9d3eccd4c97bccd4d1d1a1d3b97bec3a6da8b7e9c43d769d126e827eeb5069fdd6d9cafaad13e3b78e93bd818665c913260d327aeb5869c9d0b244099bb13b1a7aebe81ac92372596de2d8d05b078fd985c5cf6c070c287aeb7c7511ab9bc165ca952157f4d661ee60810107a7a7e58d0cbd759a39ae538ebfcff1caf1cac98901f43b2707c6ef9c9c9c9c1cbb9c3cbfb1b11f67be34118345ef1c06a8b1616b6bd185c69fde3918eb3a61acbf0ff629837a58c9f7d88341767e07a95efc0e068341bbc77908c0bb6283c34609d79ddec1e5bb389be2420b1925677a07bfc000fdc0fc3db02f0f9807cc7b02e9ee1e3bb06f03e39ab04d58bf26db649bcfc7cec66d362e848e286f574bbeb49ee80d54001936492a5f7e746c7a0397cadfc03020f13710a8e4d93e964ec89f90d52f6cddeb13840a3e1a53aabedcb5e9cdea5c41c9b26c3ed3b0d19bf55204c699e7d79b6718bdd9e5064e172c4e0ce1c246466ff64b8392655519142fdcbcf4669924c41009d29c2beb4ad39b6dbaf8cd3a5bfc66b17eb35b8f7fb3548f9d4de228ec7bed7bec6b92eaeaf7bac5e2f7bae2f7ea7cecebdbbad2ad777bcd5bf58a7c68e19255826d0b0bbd57abc739aa680913a7440c4eef55890227593a6454ad7182d17b5dbe590d3768926ef6c050e9bd7e3da601e38bcc9a16796cf45e9938926b3eb450e0b0c2a1f7da7cac759d50adbfc7bed53e742b4ddadb6a169ddf2ad55698ea7cecea5baacea552b7a9da85e03a95f94b4990eea57b694a77f75228557a97f33b55f13bdd0a4b9dc91b7bcf3541bc64d5d03bb53a408e3a2d5bc0f4e8b244ef5489c47e697f8f71dede13d33d6ecbf097e13aa1be51bf8dea95517f632aabdf780ba760b976dc3df7ceaee8d01b5b6100ce1c9c91255d9a26f4c654c8c05821b3a7d41aa33766be044e5cb1cb6b01060489deb8f918c3e07e58af13ea2d52947929ababa12388dea8f2c48c331c28c6f05a5cd11bb57a4c95a54e0990227569f446bfecd670bd1152242c0db36083d6c64b0ab1337aa3cd3fd2c492238be3a7c6c4771ba54bbdea37ea44f128d56f74eb81bf512a348ffd05d74330f5004ba9fa62270096728c4f44a126d0122154e1bd08a3c5885fd50a262f2a6650edf55006d13b3f8f8b3b1c693486f8ed698ce5b7630d15365658577a2a950a41055e94334fb0d0dc8668ec37956a1a52a60a0c0e8b2d2cb486a74f9b0ca4220b69f1e17ad485b0e4ed63f5a84f18e37bd42bb4c0ca9bc87cd437e8207a3deac42db688b8f5a88b80c35289236b7ad677864816082d6f62f251ff49a1f7a8ff54e5dd33f7a8fb891eb447dd4de4dd13f6a87b560fd7a3ee30f2eeb17ad491d4e49df7a8f2cece47bdc30db147bd4357de999993e4cdf3e4b97bd437b89137cfdba3ced3e4499352df7cc2b054f087070fd8a3fee39537cfd6a38e5445f7a823a1c87bc7f9a8ffcc107bd47f64e4bdb37cd48182ec5c3dea4040f21e3e1ff5a3b6bb47fd882defe1dba35e612cef21f3dde2da2857557fc2aaaacab9693d3be2591f0e912c9a4c3ed0db21123844aa531b70c97bb87cd443bc195e3dea21dce4dd3e1ff51fb3bb47bd9d6be71ef5112ba2c0214b7bd57532f881f6a867f095771bf6a8235fb45c8f3a5299776bf5a86bd0e27bd435bcc85b68f7a81f9d687bd48f4ce42d640abdb2f2162a1f7529adbe475d2a46de3a798fba8721718fba072179eb341f7511583a608fba88abbc75b61e75249b0ed5a39ef3cc793eea4e6b5424662ebcea394123bd1c233279e72cf3ce613eea432af2ce593eeac8bb9cab471df925efe0f351978a73f7a84bf9e51d7c7bd48f86903dea4742f20e7e2109663dea43637907938ffad01c50ef511fba923770ee51078a9237b0f9a8fbbcc81ba87cd47f94e4cdc6b97bd487fcf266df1e750da0e4cd321f75113d58af475d048fbc59e5a3ce26d9e4537d6a5ffd793934b40be5d5b8a7f355b93416af7a708854818ec8f41ef5232679af738ffa062ab4477dc389bcd7b0477d4a4cdeebd6a3de216da57ad43ba0e5adeed13dea1be0c85b753eea1be450c51ef50d9679abcb477d4a4dbd7ad4a7d2f24e9f8ffad016ea13bef24e9d8f3a4f5ade69d8a39ea7a45c8f7a9692776af5a813e9f81e756296cc4155de2aea1ca0c8c7127d8ffa3199379af7a84f6dc53dea5332b29c8e17bfae68f2d7d58db0144e269349a55e9de969f5602ae502ae2930804c7181e745af70e0bced90733297428cdef957bc67979e75e010c94a49d852e484986452ab1ebc5257abce0e91ea10b94e85a5523e613e6122d4e4ed13f6a86f1fe7a3eee3c451aba3eed3269703ade857577dc27c9813c8f2862879aba86f58cb1adc2edda3ae614a76fbd48d52677a4add76f050fa3578a3ae1c10a48a4ca7de484bdeea1b65b96dc9ff49feb5104206349dc1c285900e211c691b8446a86a6d857c00b1add010602b9443b9b5fc0a63ee055ba11e7a396d909f908daf3066d3f966256c8554b4add08ba9612b3463a70d82c3d30aedc8add08d9e56e80403fa1c0825b6414f9f36e82f03588faf0f535da93f6dd01b678456484b422bb4d49bd00afd406f4e0f502b0483422b74d574becdd9e52d835aa12d66d3f93667b725d406f505875aa12e120e34f776acd00a29895aa114ceb739bbbc3df4abd80a7975602f69a5747a2bc4c2d80a05296a8568bc5968856ab4713f744377467a466d509a0b6d10df76a8bea35688c75718b3f9446a85b24070f96e1f5556dbb1154a26b54226b6965f61cce653a91512f2b6d406b9c941a0ec4047676a83d828975f61ccbda656e80b431bd4c6a915e27a6a85a8824120e76fb52d432b0424cf6eeecd35b4424436b4422da0daa0381f58259f7b79778a432b04b687f113636c85f1d6a71e14d50a6181c02abea38bcba95f8cd6fe6420a9560805099e492be5d6db542b54a283e4732fcfeee938f5d4a1159211b4b27b0fad909513006de3d014f5cbf7a10d5a430077218856280609a01c04ca0e14a2155a316537f77614d106a9c91b7bba97839ea639afe2e5037208af91508591b147c0484eddd5bbd557551548c396ccfe76d44d709b30fad68535de372b64bf1a835fe385e81c1dd80709997b8bf3631214f67606fcf55323904af9d78c8ac50b55bf289f1a531535a34af1d7ec84df0b573f299f1adb9c27c665fd5d8beb7a21eb87e553a3108613461cd0efee53230f8c250cb1a09f9a4f8df9058c1c67db894f8d42a74e13adc5a7469ee7e06c32c9e274bd2e8332db96c7a7c69db9e19117cbb01db24f8d59b967d5f6a951d8637642edafd909b217e630b1bab740256f35ac270edea7c6a192a98c237e81c55113014ede2afae5832ebd50bc85b7bcd517feb42d3e3512954b2558842daee5a7c69dcf608650c2903c25153a41ec53e3cff0d7e09a5d8fbf6b76475e08a4cc72ea314aab36ad97775018d4c27d6a4c5d84b96813b2f2a911e842e96239d4b2c6ba4f8d3acf61095aa1658d2b784198e7c084a86d61d7e2596c5923094040f31d9e7bdeb2c60e80a0eccfcd6b3179c696357e908164090b6779ab766dd5a7c6600b669b85162d962dc08cda540b6bafc5852456136beea8658d1d2479588892b7fa42a4963522001f31f6a4902023c7963502800049b10f22e24c6a59e36dfb4af36bf2f94a2d6b24818f187b8924075796a640507d87317907a7985623fb58620f02fe6053cb1a9fa064bc05b7a71762b8f1a91188c585f5e5d4b2c623138f4f8d3ecfc189f08979a5874595a1ec532351438917cd1773c10d6e94e539407d598d42aa075fe759e36de3d1f6b78d47dc0b3994e0fbd4b85ec55dd9a9512d6b041a2a2343977fe41d648df9a7849b4f8d41af0198bc833fc5f6a93178c5c50c7680fbd408e4bbb27ab508040f6d6acc79d678dfeac4fc6a4cffee851fca7c6a54e9f240b4683e35029f057bd557230bb4578b40c0c2102d6b66e2f916ccf20e8ac8f920d0ec44925f8debabc65b16e7caa746f651bb096a42125839c2dfdb644148c426084c6d0695525f33386d56bad8a579eeef1c1462c00bd01b703e9e5a055a8d420c58551b4af48abe80e117a657a36a4389bec30df007f1115df17cd48c85f2d12210d257f1b1186654226fd5c214b23c8d977730038950256f55bdaa52ea18e8b8e98b39589092b7cae324c29bbc550b6d6a1aa30ec952a7691037bd1a5f70ef88747de9184425f5c51c767e34bd6de2ae9e5a35622638b4902703adbcd50e7979a33908075674180e438e701c909068d1410c0772558e7279ab446d582e33d02b1867d8d016755e5768891236fab430c56c9b171e35b490a7039e953c84e89977f005e8951d8b203a06b80812bdfab8b9e9180cbbe8b5e8620e1cc4750823244497dd692d6f195b0e3b9deeec10beecc8923d2de4b1c02696b73a814c97e4e5d04493c93bc8614c0875fc561766a9318d377b794268d106f8ae854eb2d211caf256799e6890253383a994eaf7fe5df3f2a7d44214455fd8d6754e49e6691557c838b56a1c52a185eabab34378f53639b96024b56a149aa2853c3795ba6d6770765a28a7af67f4037e0e44e2788e5472eb9762373ea6d0937393b0aaaeaabaaa6a9aa6e995ba9829b501948347ec215dd97565d75555551545513495426f12ea393d143ca571efbd7849591011fd809373d848ce17e36b4451740de2e3dceff6d3bb87b38aa64be1fda0a230d5caa80f71ba41ea2a7a316613620f8668aa29aaa66afa955315e3221545fdf2bffac22be439e2a8d4afab2a4655b4e8a669599ff2f35f0fa8ab45c714c5544224f6eba833e17bdcc1205414fbe5c596328f5dbd52d74c92393348543449b3a7db607a8588607d1f970b11aaa45ed1a785a24d82b720cc40bf061219463c89700a810144d307260f4b1d94a692a48e51481c1cbb07f4c31194631741428c6c2c636f996419e837aac136ff000db9d191e9096a0a84860c3b4409414445474a18344479509f44061121407cf0d0614a2a8a0354d41408f4830610d8af302019fb102cec498c30aac136ff000db9d191e9096a2ac3d30e51421051d19112060d513b2344847802e1f4018387a60e4c534b524a51491c8e50481b1cbb06f4c39106c71e35857ec80082cb0b49c6ceb3f41a212284510db6f90768c88d8e4c4f504f4e3b4409414445474a1834ac21403879e8302515c5016a83060c4f50e887a729e59657c69eb3b64280f86054836dfe011a72a323d39313861da28420a2a223250c3d1f3c74c030d524c514b5c441092a69c351035206c7ae847e387a72ec189ed00f4e508f1da5baba91b113adae3e78e86054836dfe011a72a3231386a61da28420a2a22325b6c354531407a80d1a323c39e128230c4f8f7d05f898268364ec3e2f40931da6a48c6ab0cd3f40436e746c62da214a08222a3afa918ae2c004b5b44149435286e3139293632f423f1c6170ec47e8870b4d20c0c714047c4c23900004a9280e4635d8e61fa02137625ada214a08222a02b6d808e400b5a421c39313062237c2fe4107a0ba32760919e80007a80d4635d8e61fa0215f52da214a0822c2c6091b3464507a4a723a62406a72ec41e8872326c74ee4d819e08106ae8c1da8030f3668c86054836dfe011a524ada214a08c2c66086a7240c4d4c128086b003000160193b05022020c39393510db6f90728e9b84394808d414e189a8e4c484b8e9df8230108fd9034f4d84168e023631722a181138626a31a6cf3cf11698798d3c484a4b4937fd00fc7a7291d19fb10d45413d392510db619e968a7c29292630feaa01f8e8e8e7d27a31f9040f0f3d88d986a64ec4447a625a524a31a6c8f74862d36eaf8453f2439768c7e387ab0453f1c013954918cbd38e4494724a31abca8d366df911c3b8b7e3872ec41f4c3851f0d6919bb31ff20192fea84fdc8885127ec178c2aea848b8afce22823c7aea21f2e382ec2505f19e3a20bc6ad9c26893d3b168c4546a3178d44c60ac621a39031c8b829a40e94fa84d425182318f7d5fbd47f8cee63241a374ab5d1ab4f3da7ce63dc28d7a7be63dca8d7a73e346ef4eb536f8d1b1543c9fe0653077a02c0072b50a25f584ad55927a7684f35f77d9b0316ed9b77f7d8a28d26ad36bab5fc542dda6818ca7c94c929bc467a2e0f3165a3a3ea2b9e7a02c14543c55232104f20b05f612c06f169ea05950367607a5fb42fb933b9b3b3dff76cee6cee6ceeecec2c033dbdb30ca4b4bfefd98fdff7ecebf73df3f1fb9e398f5e42aed6bec801e9a1f73db35af1460d8d67d51035bdef99b2ce8815bab718ca12cb2832665e6e4cf1cacad2fb9e416152c5ca102f746584e87dcf06f06657065727a3479fdef74c88991033b3dfd72ccc2ccc2ccccccc4ca3a199693f2cd7acc7ef6bc6e3f735f3fa7dcd9c4f8ab45161468e0a0dbdaf9995932b6349c6529cf9d2fb9a2953e0a06157c2ad4e86ded76ca9840cdd8b1a469c44f4be665f786dd23caf5c8cfde97dcd986a86a065f968e3e54cef6bd683a2ac074559d9ef5bd66355d66355d66375cbe81e977d1b96eae1eae12a7bbfbb5bb6e3f72dd3f1fb96e5f87dcb9c21e0b3ab5156c4c41b1a7adfb2b83fb61447d08cc9d0fb96c139f367844d8c1c4bf4be654b01007922060a5d9d1995deb7ec0b8a191b369a706871f4be65cc132bcce889a1d186a6f72d2b739dcafcdfe3e6efdbdc4b93f6fef9d849f8a9692e7fdf268edfb779e3f76d9220614783cad99d151c27667adfa65599932f644e88d912a2f76d2a873bced0d96893e2c616bd6f73a9f527064bd80c364bf4becd0f6c7ab04929638249a3f76dd6f092a3c1e3079aa7deb79947e411237e8fc823f2883c62c488116d582a67ba11718f7dc489115dbf4770fd1e31c2c9c40d902f6c509c20d37bc41a5b8a30606f6288e93d4229763546c99827d714bd478c697b91a6cb0bb0650abd4788a045b2875d55d2851bbd47f4006305865632cc95de23729788dc2542c46f117929222f45e4a50811224488898910d182e7b7081bbf45d4f82d82c66f11ce2b3704c70c2bbd243dcef4166185012a6b6266e0b1d10ad35b84326b879333346018d1a2b788259f0b1f339ce0b08aa3b788af3f2f755fce6a6cf1a1b708134d207477726b665c7a8b5813624d881de219e219e219224488106d582a5fe5ab1021ba426cfd0e31e3770819bf433895fe98945933664eae4cef105664468644b991c2c518227a87509eb9b1ec0babf15ca377882506295a7d5d604bae04d13bc457933e28525c1cf99246ef10cc263ee2ecba588c39d33b841410524080f80de20dc41b883710204080b8bb0311f7d841c4e101026bfd0681b37e8300e14ce1863985adec899bde209a309d6663ca3841b2a63708e51a990abc16718484e90d62d9d7bc714677a24d1b2a7a83f83aaa1ac3a5ab6c4a09a5de2030f0024cec880d1a49a6de20789a7ce069f2617fe0697ed81f9e8ffd4332c6ef0f307e7f78f1fbc3870f1fecf687bc0f7a0fc7840385c78fac2a1a7a7ff0b2a60b1b171c98aa207a7f50deedd0a373d38776a5f787659a1d5996241c5b95de1fc0d896986833bb8bd3fb03330bdc13b0e68c19637a7fe0d1f2c0a3e5c1c36f0f3c5b1e78b63cf06c79f040e7e1eeb17b68c3523c603809751e300f718fdd039907acfced01bbf8ed01b7f8ed018e19655d103d32247a7bb00a22d705a7eac710337a7b507289d9d17066cd91d1dbc3d09ba6dd169798d79fde1e5e78992176852b99228bde1e980eb8d2e50b5d9897be167a7b68f294e8c053a24387df1d78a83af05075e8d026fcdd01eb7787abdf1dc23a74e8d0212f83156d553edcae94bcd1bbc3190f35b7386ac4cce8dd41e9c117387a7168e060e245ef0e4b3c2e40dea09c215244ef0e5f3b65a676ca4c4dfd9edad99bd2fb9dbd29bec73e15e7ca1466f17b0aaff83d8555fc9e9a9a9ab29bca6353450dd6dc8db22b7a4fe9f81b9306478859959fde53ca0e767b35aee8c5699ba1f754842a3bb29238f8869cd17baa6fcc0690b03f32335ff49e6a268b24a9d24441a2f7d44e9ad44e9a94d46fa91da7d48e536ac729252525d586a576e876e8a4a4e2d44959fd964af15baaeab794b3479b354a92d4ed68a1b7945597134566fce853d3a1b7145b993e2c38716e597a4b2d67d050e6d0e2b5c64a6fa911b0b92dd971030658526f29bc16479cc8f87213466fa99daea89daea8a8df513bcba89d65d4ce322a2a2a4a6c47c53df6a8248ec23b0ac5ef28aadf51277e47397f5cb9802366848d97de51566a6027969c0943b1a57794129b597d01c371e7a7a677d45225b3f504c6902a4ec2e81df545813338755074ac70a2a57714da90322554ec80f30247efa8351cd670e0f09bc393c393c39303070e1cdab0d4ced5ce1587b8c7ce218e1a0ed8c46f0eb8c46f0e38f99bc30d343c156f3f5c08d1a13707ab2b2aaec064a9f891456f0e69765becc45cd438b2436f0e4b0dbc38fb31c6c49b2d37f4e6f0a5644e8d18ab2d593df4e6c04c9b0147aec518962fbd390ca5400da54041fd861abe410ddfa0866f50505050777750718f1d0a05d4df6fa838bfa1fc7e4339c138c9b2d37ba3a44b6f282bb22f374c6c95d5b9e90da50c936695f492058611bda19659ccb1bb1538e4dcf486fac292a6449535ae333df486621e89b34c4185c71838bda1c6368c6dd8f07b037303730373c386161bfa7e6f80f37bc39bdf1b366cd86077dd8444e94282824e8614bd3758154981a55c4187424fef0d437acc19f1b163cb8cde1ba896f4d0abc3228686de1bbebeb0c44132a5ee0653ef0d4c14f850822499a58c932fbd370cbb340cbb3468f8ad61b8d4305c6ad81a9e8f5d4372a9c1cd6f0dcfdf1adafcd6e07cec1ade3468d070e72477050d5ad3c50abd3558f528b1240e9a16d69ede1a946e5b7c756766d8d8e9ad01accc098e157438e0d4e8ade1aaccda942369419e7a6be88283d276422b4b893bbd35b46b32b46b32ec0ced3343fbccd03e3364c890a10d4b0daf865719320cc9c0e6778635bf33f0fdce50013c35783ab06c5519a377062b696fc2ba9cf588d2a57706e51e8a276c6d945ee2f4ceb00c414516b2387e48f0c2f4cef035d6842b29a6ebcd87de19a6fcc830192205469d11bd33b4724faddcd3d3efa776eee9e9e9693fe5e93df6a7362cd5deb5774f4f623fbf9fd4fc7e4af3fb09cdef272701d020d9b1dc13d2654eef27ba174860246730c1fcf47eba624eacf8fba1c24f2d86de4f484edeb08c71c1d13645efa72f37154fd8ecf031e38ade4f139c6f2e6238b1eb0aa2f7532bc4a915e2e4f4dba90d736ac39cda30272727a7362cd5a2b5684e4e4ea7bddf4e677e3b99f9edd476955183060d19bd2d7a3bb520ac07172c7b66296ce8edc4f4a1c5c45e1d102a1c7a3b2dfd52fc8082b5c44b0cbd9dbe2260d685060593b227677a3b31e3743cc160d04053a3b7538b02438b020386df185a2b0cad1586d60a03060c18dab054cbd57261c0d086a1cc6f0c7abf3190f98d612e0d169b2269c42865e88dc1cad90402a34c1c354fbd31285d10f6b5e6438d4d1a3ebd312c85b8a9ea02d7d5c38cde18be24a83851d7d7f7e6624e6f0c4c1d3faa7628c95b91466f0c754d754d4dbf9bec9aec9aec9a9a9a9af8f89a9ae09ac6fc6e12f3bb29ef779393c6f34a1bdf1bae3dbd9bac2c549da9c1d6c682cc8cde4d4a0dbcc0c14a51c6c88c267a372d4160a525ca19213fb860e8ddf415e4c2451c9737135162e8ddc4849387b524cc91bc377a378d318d3131fd6662323199984c4c4c4c6d6d4c4c5698c2fc66c2fbcd04e63793530426dcbeb64a8079cbd29bc94aae4495a48d1f3bd0f46652eaa9adb00352628a18bd99964960704953c1e20d15bd99beb86a34bb58617bc3456f269f31aeaf3ca7952d597a3309b19684584b4bbf9784ca25a17249a85c5a5a5a6ac352422fa1d7d252ddd2ddefa52fbf97969c15e674f4c5b9bd01a1a2f7929500d0a8d892a5a28b1237bd97945bae96a0f0fa32c64cefa5250736a880a0c05b2e65e8bd14829166d60d3279625c00d17b8946953fbe31143ec44ee8bd0446098c92d26fa53ca53ca53c2525a5bbc7aed4d7a7a41486fdade4e5b75297df4a76bf959c1ec44cc8c032f3240811bd95ac12a017c7e3cb1c595a13bd959471fc54bcc9b85281a5b71291322f966dc46630f556faea32a6459424585527f4561aa272cbc122091a3260f4566a92d42429e9775233a999d44c4a4aba7bec496d584a472729eeb12725cb2471f99db4e57752ddef24abba217190acad29e146efa42658733c9e48e054e89d94a24d4bde0c2250ac38f54e4a0227ca5f57958a333bbd9320b004c7973543b29638f44e0a00921b57d4b0a4383bd33b4947eba8a3753cfe3eea6c1d75b68e3a5bc7e3f1eeb11fc1c08e473447badf472dbf8f597e1f35b0d43281238a912052f43e5aa5004c968f2a31635eece97d54662e5e74d48d21e22385dec7e51e0a1b5d2bf6e0fef43e7e3d2ec222459926753d6ce87dfc82e28c94ae246e67f43ee6ac41ca598384f41b29e7898484448774f7d8ef46cad37bec486d584a874a870a29eeb12395fdb941c2f21b69ee37d295df48ce343642947819f322446f242b3049ad3b3626704bbd91bc3889e1864a8b3338f446828135862f099ab8367a237d5df9ad50e345b9eccaa23712d3cc19161b4e2a40faf4466ae64839ca917274f4fb28e7ed28e7ed28e7ede8e8e8a80d4be5dce5dc1d1d254b1c59f97d24f7fb28eef79133066a295884d1aae363ea7db487c5a34d1b1bb2e416bd8f3080c3cf6ee915e4ca4defa3126d2780ac610639fba2f75108306177753280bc08a2f7510538714acc7c25a141a6f7d1d885b10b177e5f605e605e605e783ef60b5517e07e5fa8f2fb0295df172e5cb8603700265967d0b89ac819d1fb829511181c7d73786c9c3cf5bea06c801b171360d45a8451d3fbc29205ca1963aa9c99b2638bde17bea65c9d21696333f2a5f705a69d8db8351c4f50bcd0fb424e97514e9791d16fa39ca551ced2286769f47cec462d8cde7e1bb9fd369af2dbc8c8c8c86ecaf34cebccf28419bd8d584c6123a6491c36cc3cbd8d948fcb80c0f90226c8599ade461e885357e209d61b3c35bd8d9a6bcaee8c7419f3d3db484a8d31777d6632a628f5360aaeb1105c63c1c26f0bc1a785e0d342f069c182050b6d582ae72ae7ca8285a4960529bf2db4fdb6c0f6db8273833934a6991a346e9ee86dc14a2a8813871a2b3a3828f4b6a03c815d9ab414626dbabef4b6b00c4365e944cbeec812bd2d7c6d9d1963e20795ad257a5b6096b9b3d24a5116454b6f0b41294541294545bf8bde8ade8ade8a8a8a8aeeee8a8a6e1445f95db4f6bbc8f9bb2884264ef2783c87d838b142ef22edb7e5091f5dd2af88de45497494fdc59092630c96de454b0bdcb871a2ea0c17dd18bd8bbe2cd40d593e4dc499e3d3bb288397a7950ab6135b6bf42e0af2300679188dbf8d5fc62fe397d16834929119e31ebb918711ca6fa3da6f63da6fa3d3898c307a509224e1a2b7914a055f8a1b7164d8f43612c13a0205eb4c0b85dec665dd1728367c3c9394e96d740386c28b161e468084d1dbc8ecc0c55c0d3f374dd00cd1db08f473a09ffb6f0f263d98f460d2ddbd0d4b05b38259ee49218ef6dbcf7ebbd96f77da91715146468c18227abb95099a28d921a387559b0dbdbd0466e0e8be54e52549a2b7ab2db142832d8e8a18a6de1e42d718194cee6ce49578a3b72fd992248a152b742b9c7a7b13285704ca158bbf8bc0b92270ae089c2b168bc5362c05d403ea158b62c5b2dfc5e6efe293df452710495793246c54e2acd0bb28c4cccb058badae337a7a17951fe0728e211283cb4d9cdec525911468d09811d952a277d1aec69a301d7965c894d1bb8822cd4bc8589b8c353bf42e369b10352122fa4dd4246a1235899e8f9d2849464444444444446407fc5101f8a34285df15806015f41e085681efb15748c655a0daaa50a14205bb0a7940ac2120d6d0d0ef21a07208a81c022a879e8f7d68cb109593df43434343437656c86441f143232244efa1a50ae07091c166cd151f52f41efa5a23b44648e8b7d053e829f4147a3e76a1249e10d55698909090901d2b2588951214f43b887d0b62df82d8b7a0a0a0a0362cc5deb1774141c9675093df4164bf8398fc0e72ee6813b763ef6d8b96de411168da0de10124b9a3a977500f2a296a5a6ad4dcd6f40e5a72191203c79a2e4b9a7a077d3da641d6048a18317b637a0785c083851e9518b31968a4e81d3446618c0285df149814981498149e8f9d4289248525bf2928f94d81f99b02050a14ec2a389f2756fc40b30686de149431f25a6069a356258dde14a8b8f87b72c622ca0b317a53c8c09712225b554fba50e94de14671f244ca182cc92d2ebd295c3269aac67eacd5a5f8d29b028b05c4620101fd06629540ac12885502010101b56129d6cb0b28eeb103510125f90d84e437d0d86f20e7121f950e382c632fa4e80dc465e6b603870f2e5a69f406524200afcbcf081cd88e2ebd81967e46dc1c299b02c44f6fa02c6054dca875a10226a9375095233e66f4d851c664a937d0ea3761f59b30e1f7043639e1f9d82724c57e4f38f27b8291df13264c9860b727e44dd0d309b34c73d73697e5a6f704ab0898503136a5471d103abd27281f4bb9b23c912208992abd272c7780dd51cd21d123a2f784af10ae62e8581bdba2c2e3d27b429013657d4e6e50f182a2f784554ec22a2741c26f09eb9c84754ec23a27418204096d586ad55bf524489021a1c86f0961bf2510f92d61ac8a98365c53e0bc28a3b784b7a499922e5c90a471d35b82d208885c09236fe0c4e0a2b7040ed0e063c16706081c12bd255031c1a7a662ae479b317a4b08c31c53d284aa59c489de128444101221c2ef086111c222ac611122448880861621eeb147b81161c8ef08427e4700fb1dc139d5e7838c97254dd478e81da1c8c5834c953d3178587a47a0e0a566050f2d7d597c7a47d0aa825706a54db942ef082bd8e0edd9c0ea22664def088f35c667638b0c225d7a4758b57e56ad9f9fdf3febd6cfbaf5b36efdfcf0f0f9fd13e4f70f90df3f3f7efffcfcfc30602bce8e6ccb1d1b14bd7f7cc4e119e1f382f3264cef1f202fb4b620653b76d4e9fd53a7d525ccc489253fcee8fdf3d58602edad4fc60b34bd7fd2e0b04ab6709a8129a1f78f5ac6472de3e3f3db47ddf351f77cd43d1f1f3a9fbbc72bd54ae5e3c3f4f9faede3e3b74f8fdf3ece7bc5cb8e46581bb71f547afb581d59b3a2ea489214757afb280380175697f6e247102c7afb2ca1d8c978e3e38c0f86de3e5f63565a7060c06a28d1db87b97190b1a19919f33cd3db474d23aa6944e26fa2ea24aa4ea2ea241289443a3a22b18cc8e337d1eb3791e83480971511236e66aca1d29ba8c1e888bc091326e68adec410966ecc581ca9aa71a64b6f620b2540c250b1998939d19bf835013047f4f4c496cc40a337f12ec91abd2a314eb6c4f426aa5d3d6a574fcfef1e75d9a32e7bd4654f4f4f8f98584fdc63ef81ebd9f1bb47c7ef9e1cbf7b9c5cd4ac10715204cc10bd7bac8ef6b0f0fda949ae25d1bba746d88aa7141e4a353ebd7b7876a0c80bef4e023026de1da53144fa13d846015f666a7761c49c89e1020b0cad25309a80e1e2e4c2e4951cdd1a22959eb6c4f92747670c914f4c5bce9ec951194324d3d316145a594364d1f8188a5c790c8ec61822310431f12ccbe65996c5e02c1b84f9ec0ebb866559279615a2f5ec0ecbc72a39cb3eb16cd889675b560dbbe42ccbc4b245ca9e95c0aa6159c754acb37e591d3cb2c2dea86861b1d12c96365e7694ad39afe89d3b3cf9e3b262ad88160ebd6f73a8c65ddd92bfb72f697a5f6701bad8cca569f262099bdef7c9c1151c44b208c962e3a6379a0cd381c34ca1856d450930ecd48eb8b0204ab6d818617dc410d33b54588c770f837b772018efee47f7277714c610e92c9a358d8aa184b978c1e477ff68f93df44c46cfc4c42484cc330d81f24c44740819f24c8e2a8748a67529cdefa95f32c3e5ccd68ebd1d61b8a455b5d06177828adec75faab2c493a2e5a6ea6b6909cd2f09f9f14b4643fae4986e6b5ab6f492901dbfe4a88b217289ca53967f0243fb27bf63fec9d11643e4d304252525075272877b250f2a05517b2547b1864825a7202bdec9d1ab21d20903102e8fc15116432486154324bbd53486e49b1c553144361979f2444ee4404444444b4e4464e4cd130d89f688889e888988c849404444e45945222247bf8888ce10293911114b44e441a2b1331c4fd8a8969cdde97d9b6352b848e3e4ebc2528588080f4b8ab4a593334fa2a03276345a748d71b224729665599665599665599665599665599675d46a886495ce28292929292929399a6288542a168bc562b1582c168bc562b15874b46a882cf260330b6882f7a6eb070f374a3a2f76586a2adad288187346cb1a156045c2dccbbcbb0753a90c4c944489f3c164cd8b767714c510e94c46da9ec951aa219229585624ce2f397a62885c0a9a182289dcb800a9aeba1113d494dbddeffbb6e4aa7ba0aaaa1bdfab39aafa45a5b6a9ea5bd6ab5925a3165d754c7595f5ea9bd7ab3f2a1955c955c7642adaab6d1f0caa507266ca524bf38dded74984d34489990e1340ecf4becde47d32c3d03d34ef006140a8528891e127436ffcc5014d190e364168e8b0d24aaea4a4a4a4a4e4412507525272b4c410a954c4638ac5a2dbe0b2fac1a50cade82ab4a4cc7dad5863512c168bc562b15874343944168dd494dd03b24e82f50f5896f51088889e888888888888888888c849101111790c8648a2a5a5a5a52587c110b9e4aabbbbbbbb6b7977372aeffe8221d25d3044aa57ae9e482412dd880947b913fde98af38912887744a27b405422128944594b442291482c3a91c844241289442291489cbbf14ccee42d18229982c562b15874160c91c5a52dbfe42b182297824444444444ae02a52b365ec95330442ab12ccbb22ccbb2aca3608864ab5859f2ee20cc3051f5c5460e1d32f05431b78a99af21702ad27089d3aaab7e82215235c11049b46b3fc9933cb8e393a668f9242fc1109994dbea1ec9911c0809c98d90fc490a9947b280448784e41e20159190a6b83d528b84f39090901c09c983f991909096c82073a50d102e669090548151c2a4ae6a6c8cde68724a8b7757dd4930447a9048241289441fc110492c16998ac56251ca932f4a497ed1453044165996655996655996655996655996653d0443249b9c323482edee891ca8cdc813b1f1782207c11049e42cc66385617edfa7da430c569022795c9a535455ed7b83a48410b4257172b008cb92c305d596aae2bdcad6e255b6ac57d96abcbad663851e9b126b5eceb4ca66f5aa7f608854f710892437f73d3d18ccf7f4b811139652758f43e1a8fb3d725ebea7a7e7aea747ef7b9c04726e7a88595cdf737bacc0f81e9f9e1e22ef71b4ad27ee7b1ca5d352e2e584a962cd93bc1836f6b8e8c5cd85d9d23d419e3d7c901993258dded789dc616346d997669c999e9e9e9e1e2b574f444444e41e1822898844072212e5d43cd13b30441259966559966559d6393044b2e9d453da94937bd583aa5c95577d0343a4aa8121b2e748a3c61f3d0343e4514bf9e5b37b76a3ec4c38aae8d99fb21698cfc2ec257b07384af5ec1e60a9bb97ef5d96b1e5b33077c9d9d1ac8c94330d179f85d92e133d3bda9689f25b32994491c1a4dd65596166acc41a9de39a6061941cf9c163c973d957c40f4e55fea1e6c64f59864593bca6aa88162d296b5df90b151596235b65c8c0e52951d8d200c141854a9becc66cc9152eb3ad17ca4c4434f77be8898c9ec8af9a27727a2222cf33743c9103cd58f344ee5b529ec8313044121d53229148241289ee32f69e48f42b43cc13fd0243241109c9c32321c9187b24388fe416182291542d3d3dc21e2e3d3d3d3d57586cc8ecba8ea8e861b1660d8a979513b2b29e9e1ef71e27d1e31fec7d4f4f8f7f3044f6243dc987dedd33d9bbdfe5bb57608874a0b54e8da0d2a9aaba455555d5512daaaadebd217a437424c19217e38d7a0238bc382c35b6e4cda9aaea7c9575d549a8fe41324b75b4c9458121522dfafdf3452f163d9bf9a2df225ff4090c91452095655796bdabfb7d9f117ea354742ceaf5ac96df28f359bfec65ef5e01c8b2a4e1d9902be2c682c97b637b8e19b36451709551f36219168675232364eb0ac90ba6de68588c37ac279f751254cffa072a92309ebd65593e3c1822d9a60486c89cff0867f9a3a3a3a3a3db94318389d8112f317df4c4855553079e5c11aaa33c207f1466eed92acf7a04203044aadec1107934e57fa14af32ff80386c80b4646466e64646474e48d4e3c3deb0e18225955f5ab7a038648950143a4d1549c05a4df436fa1c25bb0b0f67c0b51dade8296b7e00b18222d7811962f2a2a2a2af2602a15803449bc4811d3e1164417c9753d9f8cf5b823d33bbf7dd1da8a57d55e75050c916a0286c8a2290c6f0402e48d8e8021d2d875e6d775eed795e886905f7d56b8d53bf8a0b8ae4e821b687ebd7c56ca2d5f571c72bfeaac57d6d5d1b7d5efeaa8dd8adefd6ae537fafcd5711247655f1d53adf8ea57acfcd5f1d68ab97ec561bf3a66e2a81e5f1d93ad68bf62e7af447a24571cd982a68c9ebec0a7a50693245ad7da75de675a0d166b27dcca5ce91f574abcc56131f3b76e41717282ccaa8a19bdd1bc5f578cfd50bb92d7c34d6f74ef57bcfc157ffdea2ccbb22ccbb22ccbb22ccbb27e8021926df260b9185c5102f92ad1240f2d820b2e273e9ac071b1a5a7cc151b449c4388d0bde8e989fb9e1eb2e7152b25763081e2a57b7adc0043644f7b86a6aaaa990aa5aaeab2c8abaaaaea207b55479c575527e175e2550780d793571d01255ef502ccb5970c528e2f4668a479b10192e13e672599973146fe50bc48a1330e2e9f9d0043646e9f48f4a09327c679a20f60882466bfd17c77010c919ee18b5d7d5ff4000c91c5205157db1339008648220ef05bcf5770a00a15dc88a9823f55f0292f137e83f80a152ab8071572850a15bc82df0ad7b9e22bdcf8ecd9371822331057595737bf5fa9d8f8d59143e4da64d59e750d864836080caa6f4f5ef50c8648550f9115f644fc909c891ff21f2287e09ebc900b399090901b31e1a8ec42fe24e453715b2f0442687521a11e21a138342f242424e4689610514848a8292424e4d7c813894e628824e6a8aaaaaaaa1af7e35555f51143a41ae27bfc6af91e173144f6b068721fff094eeed7156ecaaf1e62885c739acf0e6288cc7f3578e8a0c2048daacab3713bcc74d0d8c371868766ab9c79d63f0c91ac7b1822859e8282863ec8e883983afc86faa0a0200ff2a01ad50779065213fb207735371fe44728641fe44f4eab0ff2a92027e12cfb20bf69681fe41d86c8203427dffa7c4be5dbb66dfd094b5dbbf687dfb74ded5beb1de0a8ecad7ba0b67e5b1e63df0eb56e6d8fb78e66b56b1b964c2659b46948bedd69a7b48e3a53a9a06e1d7d6bdbb02764fe9c68e598f3a2db342055ae94b595886ba1bac441d1064ccc075a1be187dc96934c8517084ab28eb8096b9197a3c582b726e7050d112faddfb64d531e3dd1a786486270c4d0458302f1eb456b23fa7de3709cf9d5d5d58347b07ef5bce4fbd581c67e75cff1fcd58f47da7ef527342abffad48ee6af4e4279cbc4e47e75048c6dfdea5243e43a67f4637e4f7d8f9e9a9f0a17575631f4ddc7efe9e999f23d38be7c8f07532926ba1a306e04f9228687ee3992e27b3c6a88ec1131e2f7cf50da6f23b3df4c50af827815edd51e485eedc1f7aa8f23affae07bf54bc9ab5f705efd41f6aa5f1e695e750e43a4dae4c9527e4f7d4e51068bd60f2146acf4ce9fb38031e1ec7b03878ddec7cf6b35acfaa8e0d072a6f7d367cf6d9fddbf7cf6602ad5a14b8a5a1e1420626a3afbe541e5b3430d91b9b9db677f9ef57bb7d1b34ccfba990579d6336b96e6d9b327cfa2b5f832ba677dc3938621b2a5f0f6143cc310492108e44040406e0404e441a05cf640315cbcaae1557f1a22d5755dd7d59d86c815c3100934c5f413f07e82370d911382c497c0f612dc71d4ea12dc4882047f92e0c154aa044f1461b23ca13ab3a225b081b263c7d617275bf4ce712fc12fd9abaf3ad310a9e64489d0b6e6044690b236bb109870c305230926ca11bd8fbfc6e8e2860c9526969ade4fbfae6bbfba931df9f5a6c981630b97286259e4f4bafa92d21029612a829a8fe049436484e0cfff60e7fffcb8d1cf8f3f612954994c2655e81f0fa65215d821e5081a1736559ae89f335cdc4459f2e24cd78f5f2effe33f43bf167f33fdfaeb6f1049bf2f5a1322414dd67e7520273a7e7577a2e6573faafdea4f4fc0fcea249a487ef5e310b93a55bf7bea5528bfefdca325dcd6d0809385ef84defbf8aa3fbd1a23c59899a753cb15bd83cd97144dafb22530f4be6f6aafbaeff85bd684c7ab2aac38c97e804983448956c984bcea4843a46a773444fed0bd0fd7ddfbf88521d2a7469607f23c30ed81ee464c4f409fb271e2810fc468df412a15d440ff20038136f21ee8033c03b60e04f600818e7e71c93d10057ba019d051278e6ac3520e44e31e38f7400fa6521b4c8cb1ad2922d6a6a5816edae469a9d1a7b544effc40bf40076e8d116b32c5cd921e40333eb29019f355a6a70338c6f6e5461799581abdd1b0073ad5042172e22f2f87de28932bf94457896e3444128d7ef5bba77ef5a732ad2d0b43e4daecb141e37bbc6888ec0152e3069432353084e89dbf6dcbbeb523c3e6c816b1255e72bab5f1e25b370e916dd067bf35c47c761f2273708a8f2af4aa4ac3cdab35a0bc4a63cbab5e1c22d5f7d2c3aa09111a659eb0cd673d984a21df94f09811032e0d9b6669c83deb444324eb158648a05df379ea9a3c8f0f0d913c59d0fc4ef0779efccece0ed07776e89abfe3b3e36487f59d9d75c7ef4e1dd8eff4ec34d97154994a05f58ea35b38eafe8ebaf3944c264fec783095d26ccacc95b931099346eff87da69822234b8b2c7ae7df815b9364891032714276d0608969ddd021636de7871ed78ee515d88e9dba35cc3f2169aa6cd979fafd4307f7aaaa7aa6eb7bd585864815e8f7cfaf75bf87927ef5208e5a3debf8b54ccb975fddfcea4143e4ea2ccbb2ce3a852192b5f0c02c531ee840432470c210b9739d3fcc62e2872e61881cda78a190ec85eea954500b85cef4348585c90b4108bd030fee5dde0b9d0458d2bc90ef854c848e2a7194ea4247b38428d70bfd6e74f9420fa652b7edc51bad216c7d449868e1d995992a2ae666e89d9bc22e524c489172268d8adef7f942ad3b2f31b8c4a270e98d265fe8fcb6f50843649b01386a945629de96e4d03b2f79750410b82569505c317245ab3154bcea3f43a44a018b8e07bacf1009ecc00e265846b0aee039f5cebfae4a7ef5602a6502b3224af2b2f02551e8d5069c5f9d3844ae5146cfceb579d67b8648360f9142f48b67884ced748c3e6d39c6b46803e0d31c47874812698e31e8ab71a7453e6ff888068b7c9cf8883a1257de3ece477dcab0f9946163fb7dd97cf67092deefb1f13df601f8595d3636e6efcb16368001b0d9b1e5edf5a17042832c4a95de976d79c18e4a91bc266fd28ae87dd9bed2a2a44589f2fb46714671467146891245007474510450234a92adb028586284a9599385081b2a7adf287933f0d6e4f0a678d1fb46510a5913b2b6f6fbae85a549798fef5ad8daf3b10760d9526dad21f97dd702108035bba533786ab2d4fec86ae87dd798726c5a9a675f4a9c00d3fbae357d50387d50389dbfafd3c7cae963e5f4b1723a9d0068c3523e5c3e5cceb8c70e003fb0eb1cfb7d9d62bfaff3c8efeb7472a045568f384788e4486315014b6e6f4dceaaac4aefeb5432639429e1b606899eded78955d72508902c6b29f0f4bece2f2a42d49ebc818195d4fb3a79882d19d384860e29727a5f27b10b14621728507e5f287d8fef7092dedff141a1bb5038e0e383c281112a23bf2f943028ce0cdcd8d27b51450b099ede17ca32ccd956d79510ae3dbd2f942fe2981a714c4dedf75563aa31d5986a6a778f7d83b737b50dfc985cb522bfaf5ad8efab46e4f755734e200c499c2026a8f8a9e97dd5ac7ec0f0e2a2c6959d97de574df9c4ac8ad32489df11227a5fb565932357b01c49c242efabf6b5a5373676c54c2143efabc67483a3868811bf1b3af4be6a44ad34a2565adaef9bb69526ed3dbe69697469fba6e5e93d76641b96227a11bdd2907e67376dc8ef9b26e4f74d03fb7dd37a80b1f167e3cd8a8bde378dc8841dd34d0a366ef2f4be696b564e2c81789179b3a6f74d5bce10d2226d0cce180dbd6fda17b0afabc710a673ae89de378df9432f8c19312f7041f4be694d3f343f34b4df178d98442326d18849b4e763d7c02fca450bf2fba201f97dd1c21e6ba0019a1d18d90d361d267ce4d0fba2513162040b0d8c2e647a5fb43c2a3bbec848728123a3f74553d3a54d2f489d5b19f51d3c22ab201999518f8e7ca017865c048d90642c4ca1283a1a438d4e7ce84bb0e80363a88289200dac501021046803ab09476741091bb0d4085368d09f0e6e3e2a71831f6a8f943c94c3c74450c8c10b9d0d6c7236e0058f5441e0540e1669425d69a87524463063dc85c5f0da7a10f00bf9e51d6cfeb858e15e610f027ea100a47f3dfd5bb463f02a3e22bde8f00359b60158deead12defa003b00ea64968d91b1f69f9202811104c93ae277d861f00faea0663725632c437bd065c79079134f20ec649b5e51d2c010c7ec7e0d1d7ca3bf87079ab6f742686f3917a79ab19def8434f86ee7efe1699606d429b6ebaa3c195bc5511438ed04cb03e088eff1ddef20e6e00246f756a4adec1f57d4ee41de40046daf70899fd55fb5b36a563007879ab5ba6a4a2384085080122c40409113efc78d81986e880dedf0901a3396fc2212bb2fcce4219545e54f2942a2108e2062b6a0f8f1415761c442844f1d58380cd62248bee1016b8aaaaaaaaaaaaaa48a0aab2c15555595f57745d57203b84069d72878a2e37563b9878a909a2aa462bebaabababa5a74955634c6a690dd41a1020307151122612ddad8e8c09b4a8631b1b87d5139a9d25bf3f272c2e1b5b0d127e7c2e8cb2d7b1547ad6c3b95f5845e1d512aefbb7a1edce6a724d6207075a0b104317820d04960b504e8036ff3d57bf78107f8883b08535ddc669aa6699a0ad58da8f042c4062f103f56e90a0f796fcf6fa820d9615dd7754dd3a2278c31c6484fb5a94f53345557160864573545519cfe90425dfc4631aadc5276d0a15c46219780e10085e4dbf00324c3ab380af5eb41ecb7282c0f8350327a8d300b104fc3a191c27038cc2bd060eae9e840180da361348c86d1d09e5e03241539fde1e4f43f5b7918d02b7c9d57390f007c0442e27c6b021e4961aac06469832f493fce14a47b471fbf73f05b5ebe6510242c4542716026baf51b5d62e6f23621632cd337151c69b871e10885910594089e43c3f05cd86d9a11a6268b500f44526014e1c2affcced9807d940b1f9152585084fb3d0cfbc0688d5d3249e4c3e170983b80828282823aca01754458e1831e74638a3f68446f528e0a3ecdf9940ad555aed9cb41759d145c15efacb749750d34a27f71d4665ba00e03b0ae6243bfaeebbaae2bc618638c6f13128c12217c94fa43f782dc502faf0e502722737b148694ec01fdfd469fc167f2360dd1eda960c26b00000220e0ecf7705dd7e3f5bb2f955789e41887f7a8e6f8ed5147f069cef0049fae392af8d4ef51f5bbbeea82f553d5c3246840c5cc2e429b3d34b9d76a3429c247c62cf8c1c70d5084f93c9a9240d595050683407655d3a3262993f840248cfc5374030a233bbf1eb6df2bbae51c6ed03e086456909c5b9fe6f27788f236f574749edf393c9fb7b3c10ef46d08255fa9d4715a8480a9a7a303bd29df50e51baa7c4395a812015032ea28c660aedd1e0222914aa9454638097b54aaaeeb63478dc2376a1a19358db29c915d32a973050dbb76611f10d3d825d13df594e19864ccf915a4526a11893409fbd3b3c0604e3018cc195874d3a4277b9bcfe6f33e819a449ac4015646c3304e9708837fc3fcceb97b2498e2ca29003ed3e3755dd7354d8ba0701286b2c3507618ca0e436da86b07a5811f945215b3b7bee7e4e4e46404ac6fea5bfa868f1ae0f6508c5708a71c28abc1d451277ca4cc4618c56815e1354aff318a6229d5b177904aa9454f6912f6d4f751f5edab6f2029d6776683c13567b5e8292dda4f4f467719f5fd9444316e0a2f7a3da4e8f5c0fef500fc1bfc3b44af87fcd7853c15ee32d15f332be65f0f44f47ae8692bfc75ccfeced05f57c37884fefafa2307f51029fcf5d40ac6a39e33441e69d1eb41c25fcf1946e02debfc354b91f733e1afeba01e1c22994488f0d783a80b25b4e8f5e0f3f747cba37ee37e88945246e66f02cf5f1f52cdd800684701d78d92ae21485868ddf1e908c3045c3546e6cae0b12862e6455f0a2d7a3db411784bb11524fceb39858b47dd0775a190ce5f67519f304446e0ad4acaa3d7430e9b475dc21089f7a80b2bb42897a02132026f1975a14f8afaf8b4421f1f9f1cac5e20cfaac796b7eaaccb1bfda2cb5b257bcbfbe6b9e58dce49c95b0dc39237fef292b77a1597779aa7256fac6ccb3ba5b392374ec255c93b45e392b71a8797d5b9bc53a65dde29d8972e79a75953b27a256fdc07266ffc2697b3e48deec9a84a439337befbeb241593371a060526ab55ccb8354ef6e19112992094632407996865620b1d25f9472ce8742abd2a4be512a2ceae2a4ffa77087ce13a44a6420e7ce135dec77fb1df7465551665afd3ceeec0dfdba4aae9458dc01e4221ba013fa54dfb7a7a2ff61463156315fbbec1d5532781555f3960778402b0fef57b6370591da97bfa78c3e055670330800f0805efb74542eb3fcf99862ff90295bcfd8d3c67d93fa9445d32469a9bd6988e13253ed0be8c819107012d2d5618c94b4301a6650a579c9d1a357c6798c50f8af2347310630a37aac5471cc5738ff8470300dc26ec3c37001700f888ff1665709bfe2d6fdff7ec718b3d83eb4147bdb84f155e0fed6d529dc91466f475d1e5ab5b3849f58b726129103849f5b6fdf9d943bf7ab08d5ad42ae50047465d0db6e8966fa00f52a99de1b56b854517af8e8d3929c0bf5ff02060101821533668bc53a9d48fdae2a3eaac51e531cba9636f02f19a246c559542d5571645511445d5958d92f156d0759c4a0d61a30c5a64a0b0b584f01aa1387f9ad3a4f4e936dde57de7fe031cb5db0e3c03a8158e421dbdfa547555757c4cd59e1df9830ef031750f68f26ee7f051899308afd1ee600517f272060281a3b01a805b86661c75fd36a94e02a31ef478e50f8a3ac047d59bd6e4ddbeaa06538c2e5114cf095d840ea15615ba50abaa42a1d08542a15028140a8542a150286c8542a1d0f196304f28140a858e7ea161a85028140a8542170a8542a1b0150a854223a18e8bf0caf7efdfcff1a090d06f9a349726e9b890b00801c13469f5f52d4dd2c1aea3e33a3a3a3a3a3a3a3a3a3a3a3a3a3a421d1d1d1dc75b3a793a3a3a3a3a8e7ea161a88e8e8e8e8e8e8eebe8e8e8e8e8087574747474fc1ae9147d60b543fd1a6ddc7cac92001f2f8aa2288abc2740ffb8246fc756582c63b0760366930de84156aaf50d843681893af58eaf2ef4ebc2246006608747fd4a196f12ea41e0d06f53fecb2e0474ec401fbaaa778c42c0a20dd26f1dd539952252c32cc1c24411136fd29021920348911f776a1af51b041af7f1819e63dcc7cff19b4a0981697e610af44261d1cef1d5778c9e26011d1d6e90e3c1d4758caae708d321725d8d416011088eaf3a3a1c008536bc23c1678df789572d5c8f37bd1c54575b2a5479c1d27537a6cfc4d0184c93d25c24fba35f725cb540335777856e045b70c4e0d818e161a6bd6e4bb3479b297a5c7f544272e4c0ba82e38516627685f04f64ec718fe71edffb83fef5755dd715e3f55eb5e8e223dac14cc65e14474da8012c886e433243c95bcd804b03daf12defe05ff4032ef1d78fd7035e53d48b9b0084e0ab8eba50431034484bdeea912cab8e93a914e6c249aaabaae32f1c95ba4ee6d418012319271f1771c091d3ac96b7fad704c00721f8421ba48f72b0f337031bf92ae0ead53156f55af48218e80bfc8b937c5ca4e12cef20fe9cebc0161de2d6029acc0e3910aaec8a8140200ac48fc3d633c26b547585a2288ab9dfb74d892fbe289a5e174a8b36b0f2424f0a53bd193d3dea00b87bf4e70d87eda3ce1e1e8aa7e27bb4db96e26b94c011ab28d4c49003f4ef5ee740fd1bbc8ede7407dbb16a6b5ba8feaed5f14df8bb5697e58de0640d46ae0bd50f3a50104903c344078e1b45abca8c0a1a285dca749dc871a604c88b246a3ee0f78c23038b4718181a75d5f8858f4ff256c9fe3a07bbacc15cd6a02e6f35ecaf8a9d6379e7cf98f94d24f80b870929c91ca4e4ad5efd750e54f24ef3fe7a5097cc612def94ee3b7823c30d1730bf355e19380173623907e4cda95135b2b5b5b72f393ab312d828c3a34b0dbb3d153879fd2749dee9db5f0fcacb171f77daf6d7533497fbeb754130aa5a06a96aa026effc689c51918c5d0393eb1cb6e49d82fd750e5ef24e977f5d03bbbcd3acbfaec196bc53abbf43bc56d8f52052c68b4f0a2a38b49a3166d800a241f747648bd8903f0c666370b28039b16545bd71c2c6588d591d99d16403216b4accb968a10517c2175f5c9f111845d4a411724eb1b282ca132f4a34ea415ff28e62cb1bbf65b0ebd949be8efaeaa87b2af58116536ca8d9d247f7c4833364bec2f000fbf205dd535577554553a99b85c9938515173db6c234eac7542a841c667c7362657ca031a1513267608c39c1f5f5245331a3cc591589d3a251e7409737defb340d419555a3ebe13eea190804469fba6ac477f878b19e0621d9c844c6455b5df3d7af112a040386c9ed52274a66c17476b4757367829819f16382e6f503ce0aec0e4915af1f572caee45073226eb9666c8c6ec59a1c4c302728749839876a670d8b0593833274bc64e08d9cacecc323672fe73073e832b14c274606c2ed88c93959866532f08bce5b5ef96a08cde42c73902d289781706d91ac96c931a383b7e5f731462b2513adb664168c8d9f11255c4d8e6ced41c12106ce589a21479658297b8035b17b0123481c3842a0a0d0f2462d069ed20fca3307790cc940213a6e392816dcdb32546ba9f00409cec8496be78661d8333c3d866f72c800ada8ca7864a0bf662662089b792748304c262a619f39c8b6d39581706c5c3086d98a31394eb305de096dfb03341e8d7e720be453edcf10f0afd90a36bf8dce08af11f077feeca3ae974d85bfb398203018041aa79a99fd21d30fac841f93287e6757fca20c73e4f66f999f94167e58d63ebfbb200b3f356c8d2c3cd196659e16422d39d8055c9177780465e49c2343133993b55f59d826eccbec959d2139a70e8897877fcbe2e005ede2a869d1720e0a615d26b6109ae59d25b04d6687e8a4e51f317645569dc2ae362c39851ba265a015e090ac53076491d930c2b0ac96618266e744d99f9b219abc96d0c19283553c4b5ab470728ed60e9b1bac091e39269242eec4f0924f1e16594d0697e41c2a205dcec1dac1918332863632f0468b26fbf010b6c839cca1984c2c63d7e0844c724e961c2fb3125f827e79e5e3e191817fcbc8d0b57f39e8af590937c3640eb2ad78190817cc9273ee5814592d33f491817fcd4ca0f97d9b6d5e66ff9a9978fececf84938ee9cfef9c51cf40662bce7e1f8754a654a0a9e073ea1ef1d65c3007fd1ed1241050f383de9cc36f7b73cd27bba6d3ee8353b7f941bb0f3afab5daa9403988fed4076f5bf2833fc9471d45713ff8387da2a4f84bd405ab4414157a3bb0f42d2125d9638815982fede8f21a99a162ebcb9e110d250e6b091b1fcb345d66e34d0cad2b5bc6f446dffef2911193c5079cd8da4d4bfc46edfe26fffe5d0f5ebf978b0b4e9c205f28ca68a054aa084ccbc511ae136750f47dba26b07116a5c60e671a2210c8d28409992d596cb8d0f7855915ac659633560368e38257624c9a0c1cfa3a4a753d24719408a6fe03c117e0281dbfbe0212e0281ce7af7780a3b0df5f2781a3b018dcf7d7734e33994cb65d47f3f8f692c9e40cbdd1e75f8ff2a9d0536f875ee767f4e991e953a8a94f9d44f3d336bd711f94a97d7aef7e7cdfbcab17c1f7e5bbcf64131854127ca3561bcddafad4d1650c319fa25e40bed12f300abe5131e65a3275a26d9f06a57e372ad74485f43e4d936e3e754c55c137b6c21863207329c66046df588c19450d462bf28d9d6d167ce3386c67f7294fba71de05df18a7794b52aa23dfa9d5d5a759a9a74b1a6b9fa65e9fa65f29d8d1772a96323ff5b4c9e3d314edd3d499b67d1af729dda79eda3df99498a6a95e92ef942f7d7eea6a72cba71452d5eaea5335eb5395eb535797cc4f55af4fd5ad827daa8a7d4af6a9abcd312b9faa689faa4eb5adc9b71a37f7a9ab76459e9faa779fa6aa1e06df2a9ffafcd4d72498be4fd3d5ead3f5ead3356beb535f97382a5dbd3e5dbfc032f85ec5525f9b64383e5dd13e5d9d9fae6d9fae719fae739f32d1dbf04b8ef2182297929479252525252567c2514caee44f4a4cec5ea95582a3a4a4a4e4574929027160703181d2e7dc520a7376e4cc1d913f1e4a4b6496c42c2d85f90dc5acfa252dcc2ebfe4404ada7ec97dec97fcf8b4c48dd794ca34b143cfee0c498e24583fb645478e215229038cbbcfe0e87288ccf062ee3dc23b93bb1b31e12825777f721854de7dfc8d3fb9fb92bbbb436519c39361a34c471b8f6043c60f3737cac2c8b9d4ef9f5f7ac1f74b4b4b9e61d4f82547710c914b40f99f9e1ce8c9834f2fcafc93a33786c8276f5fe9e79594989494a05ec955250ff67825cf79afe440aef4c2eb95babc92a35d43a4d2547e26260762f220938bba6772946b8864721b43a43b81f9f14e8ed618229db68c7d71e78b6ebe582c168b5bd07c71587c168b45a662914b902fe6e2b3582c3e158b606c7c71a718a6582c7a712f994cbad01b9d032ac3a236e58596376e74914832c80a255cea98e89d9b69c08e04610347ef47116a8d9b2964b6dc588a29168b2dd086d2f01bc47b1b9bbbdf5df97df528fcbe7c5cdc9eb8fcbd3b909ddcbb7b97af773f3e7569befb941719ef4e02005e9cef8e802f2edebd832f59defd830ee0a85b761724a395a8f4261b0c13a2987210312b4703003318002028188ca459162649e8bc3714001a5aac5c685098c7238294c418328000831000000000000000402007ea5ae3fc4be7787b3b1a254fa516b215bc205b7dedf433f239fe3f29ffa8069e79faa35ac2fd590324ba9fcd7e19e2bc86e91147f11af0acb582d1d223cdfe297419dff8b2333ee45d3fb49be1b9a835d326d7d81ef1be5f6b627c1dc0eca34bb169fc853786ca593c4d1cfed6b052f2bff8c1d08170d53688af4a6201d35bc6ec6f72a0cb8e864555f0a53ef82d3dc6226479e836f51864ae39b9321d72d28d4ed8e374b38be6554f311d5cd5e570c9c8f10422f45ae6ec7c00047c9b693026668970c7110b2a7f9c61abc020920baf894e5e04002571719648d086a96b902f6ff7b81ebfb07795a8d2ef56d35f05e42e0a5a06ba67f7ade995a50c6202e858e35ccf9d14c9804408a2898cc072d7670c256f3b67680035c18f2615c93d62c55d9686eb19382ec5b75a8492991c9444a9a8f82e751c283ad14a794546af982cc1aee25afb6f877aa39b638aa34440217d110ed0ba2921000d41e6a2daa0ba5fff0aa0f16aad9baf5645099d175383ea3ae2f0f84a216f698b4b679616a0ead1b114e9fd5b7148f31fca207a5719f4ca5e77fc77b2ae811e809aab01b5e935889eb972318ba12967bfbd9c580c640f9b08bfe3b26cf206c25a9e6aa5850e93ebff098a971f6dfc9a105e1346aca20115a8334312dd927bd72f2e2faf6fcdba857f26cb69b181cde38a01d5c26fdf62f10a96c83c949208f0f05b22755003ab86e08607db42ff0c66a693b612d52fe667d8f2ed3e1ee83af514d1b37703610f1bbd50bda6f5de6e80ed3da697edde637a65f8eb5f479f33cc418082dd31c73b27e76174f4f62acf5dab9b970757a368acb7193db87bbd32ef86983d153ada9d5ed9790341af8d8e763faf04ab37779b577ea9373becb4dda71566777a2578d9e3ee9de9d7eae18f7db9cdb357d9de63bdc6f4fe8f5dbbaddd63a35f562f423dd07103bd67fbae52afb9414beefb352b8151eb611e5e2c31d6e22e365a971cac3fc1b5d4d9d7289e5a6896c761786c09fde1b2b2d902583d57115728a5ea3913653042f0ffb0a83b6e2fef07cf492c8bed1a51b559c444d60bab89d744869d9941b5aff0ca045a6af86016ae1545156d6e9932e2cc1ccefe3e40491df7c082648343f36821b710be195b75676d226b27b692913fc7fb8c3b00d7164b4062c2796bdc1b752ce8a0756ea72f8e2e94c37fc52d9d200f51de2f9dea4ef9041457f22c9359e06720ee340dcb1a8c660abe0b2d340c1d10d1e7cfec76098d4ee8239f5f8c2c6f9e759c99951358dd897b2294725134cbd2c53bf7cf5a95889c002ed02444daeae04d6a9f613eaea67245bf3713c98f5ffe04e91500c5f84058efe13512505b6789e1032dae575e5f37412a8cbc53431ac2ec6c9225f89149cb2f3c9b5bf0cfe3c8b78ed45327b14f2e6a9e0c4a3c1b58386da3f3eb69361cc01b6e0e0ec7d73879ff447ae151b0fe6643ff3f1b9d29a1bab56452d5d7e6c0681229ed8f7af9c4c4d0c34764162561e6def129f3ad1627e42b5bb7ba4aa336dfc0fbf428ac0b46a7cb31113fbcfb3218a052316fcfedb276a3a8e5994ae4fccc62df4bf2ec5bebdf478c97fe4fc9e4537c46cf0733fb07a3c3fc3dc35e9f0ca4fa45f46cc471e1a2c4c4d22643fcc155a4da10a80879857fca5f88c01348c84eb6439f6bc5e253f777aecbec23a223defd42946573ab283774a79a9d2ffbbb4714150e719d46c712011ff0272fad87bb10edf4533c1bce7857bf121f7c44c9771bb20803a598c71bd9a40febef1848c9478f64385a73f6dcdc4b4a1fb5ef9cad06ce3001ded6ea3efdefde5fc866d0392f07986d92a5458ae17e0697f2c39f8a12cd705f2d3a9fb8cdb2b36b78e42c11d76e320be5ad6d4d95d085ddde562a76f209687b624d4502793da6012a2f9d5239b8a94a64f863d1be4a98c4f49a6c3a8995ca1e74183f335270571971e5cc1005ff798f33fe819c975ba3c12687e958d7e02e2d3c5ef73c56775899c0cac4ac8829e7bf9ff9070987b22bad77bcbfdd2f46cc48e499eb5d37f588889312c14090706f37073a803f0c40a9c8cd60bf6b89b97a564d5c47c9a7f16943f84b639deb87c5843477043c9c8a2ae9e32cdc015a93b991f6e196202a786de96515744bc137ae3e04051e5081bd7818e1bd6f3502b1800ca811ec20bd2358800712bc271adce9f804702ad6986c739b8164c6b9e9829f6425476185e70406aee6308207d324890fe12b39cb60d4c0447295135dee3e66a482d5e9e355ce6ecd202bfa027356be5cef712484d16382652c4efb446ed5514ffc0bf0492a69e61d67cbe559cbcbc156a6cf0410f3c924456d30bdd16f2f5a972a892cd1d09cd182e0aca19ccf4cad4e6cbd268222e0933807c5928a22843e0a3dd60b5fa6a27ee2cd3afe370e8f4583219498d03d74f0555f27afed846f6f4a1982fdf8a288e2e78101b92e73de634b85b95e277aa113a8b67a4ae25e2d6ad61c3cae007e3b73c23a3344870427f4875f759f8e7d41a30d58596c5ea68775bdc4177ee85bfb16b7b4d05e6a4531deed928de26016d34cebaba6e521067ffc1b2d7939ff3415ea169afe24dac6bba03ec89451db6d700695500604983ee73819f70cd4eb0c24024d889551332a1908deb24301593bb3788244f5b0eb26f00503c666c75191ace669443927bf911c622af12ae7fe87859766483efe102fc4d038eef18b1224092631ad9863afc15d1ef275c71cf6006b7336e861fbd77c46b579b34d4cf32d50659aab59ba61650d0d68938738d7b618279f85b2ce4d398fc7dec7776104ec6c220026f4a72603ee6b1e71d34801c4b97517f9196ec89463a7c8c361a586354e031953120e87d4db614df9593a1e63aa604f514fd223d34e4e3e40f3c3f6f2511b98230074170856bb18901c53db4520b9a513aca096d6e128bd82f4fd2d7c47be2844ca4b089872ef91ac8f573e3ffe7d66c324e523849188c1884f1d5538aedca4a42ad55de183931557a2f49837c7f4edb1f7d64a0907a07acd9070e3af0c5f1358b7e07551f5a1043f87eb34a9609826a12bde77c4d87783bbfd4df7ba8d9b254cd0699ede0d11d10c9046412c4e23d4d19cb945f7c9029ccc30c1ec42f611d6a8299b418c937751f0b89b46a5d5738778eb880ae97d03debd472b25aae8f4a6db6e0e3bcaadd1feb6d043891b6eb5cc1f576c7a31629b34f102a3436c28ac62b30f1a3b4673bd85a62486eb8a30648bc8b0330cada6edc4be96f031610c5bf3be9a91eec9e0e778d845ffb0ca8b6cf32d079a4feb25928ecb44bccae5f14316f08a166c288751b1c07f8a42270205b7ce1f600b6bdb60ea016c5d06c1da8493e592d7c14fc62e81bc5993d7984dacad884593d332640a212076796a76372338abfc504e7f085e0184914edc956802260f9701d848bc7d8413f3f5fb78d76b87ea32a5462159db6fc0458dc020574183f6013e33955a6b74b5c8125dae01fefdf970ec27791584f8a5fade961229e6951a7aec744c3233c0b01e93f5e63bd7a1ed7d6e2bec337df3c975aa4fdce0a8735cea4647ce71a91b1d4dce8cad65cacd4f757475c41c8de3a9b741810644ca7e6aaeaf5cf9bd9bf510f0e7b2b61e87abac038b57ce86cbda5f657d9835a4b9dc7ca7c9bf01d1fc5565dd601a63870856f56eebd23bd00fd845ca5ae9f085e92c56d20a08da742366b15a8f948da8ed4490cc57ef7a23cbb699331ee2fd6578d631ca082c1aeec66d3f22e0fede707b9a59f62b4b16325e76d94996bb319befe0a2dbf1299d120e48fe32cbb743d0b36ecfbcc807cbff5b3db730d88b4fd9fe4f4e2a5eb5a5a3d3a53674ab71e65d5fa188ef98653428d246a84f9997e7f23a00069187fc54348534d4fa8bceab36bdb595d02f22dac5afc0e20a79151d88828de35796df94cf93f7c4b3807bcafbf7f446e93b067ddca7cc77c377005f122d2c65de0f4ad9f761a9fbdef37e9fcecf51efdf49e88c87de277955570462a734429df935039f3d19bfe5e24c5df0d55b9f2863c8ef33a519b91db55b32badcbbf4ab98be285a2ec5dedb22a96720c596f3fcf7f13b751840f0c2af8627f0b78414225b0b42cb0ad08ec5010f06710f430caddd603448ce26a71de965d790d687a22ee379ac5aee1136c195109d4277fcfb9c8d5c03bb0f26de50a0d031a35a9b659054667947f084574921a375c15ca49773de2d2aecd40469a587d30d3115faaed9903b4b3f8d13f8c3873adc2c95a457bca0bc32721227f2e92ce9b2cd72469f673118b922671f05cf6092d832c0faf6e5d79e455ff8fb7eb3cac27ba5d95151ca2734f82ba6a8354ec8eb2f423a199dfc3b49c757a878d226ca18779d4ee597fdd42f972c1a00d65be73896533b7d9f009c964127ede93550e2fbe151f14b9ecebe34ec70f6700b8b8178a86607d6fc8ea21013a0e8b7a72f97b3d6e109b219de84abcfff1dae925fc7505575b1f8964ff5beb81173a83f9feeed6e8cddfebc9f9869fc2b8a2693b4f8acc99151d81e916b17eec2d067480988abf14db118dfdda4f99685ab0773984431d5a64969c935d77c6a8eb77842296e23b328e20a67fa31b9b1e52c32e94eed2d2dd405bbebe49392cdd3e93b8813c99eff0bec7f116a463685d2fb96c396b0255d70db7c5101839968aaea8f2cc9653720693a62c2044d6f94a9bd915d00ad66d126172920321b812fe9a653aada303cc70cc1b9c881ef575c310cce0916ef9aa7b522ee3abfcbc35840e17dffccabb305ac35f8d4fcbe6d28681a5f3230417399bbfe2508c2441008cf4005e4973079a116f090bc64d09d1f49f4c2473d32c2f4bcfe1dcea4e22eb14214df29b1d6a6d171d4199217fe80b620014f1396b66bfdbae9cacc319e1a97c744021eb38e60caa3d1cbddf8e269cf0eca89057911ba20d4a67ee411659b4de87f2f9eebfa49ba211eb089265ad61ca3cbf467e6126e5946d16f3069895a401ba92d7d9fd51c1e453f01a462b63469bbaca9a06e0168fff95512bb47ef92f76bf99e98271d12e1dbb77bef81a18072103256877b260819445e2b4e2fef32a6a3dba3064a8cc0673f1b2754e5e0d06ff81a420d792b44b5e2ed42a3a0e5271fc2f57fea738c93f02c97da3d0623e122f6834dade8e9d982d884fd8d2675b51c2b435c30b62f3f48f1aab94b4ca678fee8d4ee8a65ec9cfd994e8d762a8de5aad3c0f31dbd74d57c349644472f3f3e3211ef05d7d78880913bc9ca14b64106c2a0563e2ce7fb72705efc3d993ca8e721996ed03f29a400f09b63273f6a9eff9f12d91d34caa40c87d6a8621cc143375b170a8d064e168287db99941f1c49aaa3970f1f99c87781b5360268889db28e57c137d84898d4da87e13c4fb2ce47fc78f53de7b201753c24f70d7b97460201bf79aee445cdf3ff7f395e4dc411c646c76ea824be5724a3581a9b4e571fe054fb0683ff60a5df2caf577969046e5dd85dc3706fb2030bfef66c5f8a9e2e5cadeec29af8eadcb6b2b3fa4e44dc468e822eb6499771758aea37cdf151285c34d5291869232783fd6654ee423fdab501e620858187630f14f9361121b424540ffa3fafb2e46f47144337389b996ad4e3035144a1292ae2f0361842c31a9930d020dcf84aefa25c5cd097da09a3233573e85294d9353748e5fef1ae33a903d1a1c703683ffb624c3739e0bca7b6ab83a4320d1c475056b0067b9eb808649c38723574c6e5978f8be43113d7a5d01558f0aa693506bdbc20491488b9e942e06a5437959b6c6f3d291fb44ab6828e670e376b8fb8d981213a3e928a30534c4463831d12fb97dddf67a96470c4e31036edd810558f81f0a62cf70383e9c4d8bc0e16ca9f3ab6a781985bbac3e9b5116f9092e3ba85fb87be83e8ce7843c7f48f5d22c4cc5aab10d937cf4effc049b0a7337e72775c73b23465c390dc1b6274f33a79dffc4a0c474298bf973c25c6f9886f85901ee37ba8fbadaaa706215df865496fc3bbe278f7af6242d25dc6927400a792ee097ac5bbec0cc6667af1b57d097f9c559c95dd76d40a8bb31cecea067b9f610c4ccad72854d02e845185958327f14e7ad7f8881a5c6b65d45ab8aa6a9c2b41e726f9879df0b0fbfe3a7242c3a9a8dbd1fc94d2789977329674f15da82e46c09547f0f37150e5e31dd7d492850e5eaa178523e3089bc826e8e84739103aa0d6f5c9e21cf6ffe6d6db3421caeb23ce4b9a519fb3b6f05b6a8e63b754758821d706938dbabd11149a8b35a46a6ca9ae89755a57a0150c86b042693e52b679fc425a48368043576391effa57839dab02f64d1460d7193bafe491ecd60ba41c209e10e86823b99ddec2a8a42036e987ef03a4a09343af7b587490980f5cc320180077d8cb922dbdca552f053f78e434c0347fd00b6da85407d8e8dae1227d80dd7e9759d6b4fae177711c1472881b3e04e7b4649af6a77f2230e72da1f63795398d718b2c99ee9e7073f189d4a029f2a53772377f9b46d34f13cc5aced310d3488a1f27e14765861d3d102ebd74dee0ae5870b4953af4191c7a2414e7c0e53b3400b7c9adecf0e982371a5d3e1ff565cf3ac959dca373021296f80aa23b49a1c1954c5317dd2a23fafa97b5f20ab9e9bfb3eaeb373a08d9b5db23a80920bc24652d9c5eaae1d52cafbfa87bc0e7f3490acf503e742c8c7935f8f8e187646617ec3da9391ce8b842af3b59279d8a5b37408da4d42cfe87e0a1f9e197c8b99f83acac9521cc44c0a07b920d072a22461c100d346fccdf2dc8f5a225315e15886353707db3fae17a40fdf3e21d658e35931d3a772e7f3865836dcb806816febb179ac5380ee6beeb8fbb80461c80a6a23ed159e540f95c1c94a983f2bcd7d8476eec2a235514800b4255aeda354135d11ca101b010aa47edd9688991014dd1e4eebdf0b6f87c6e05c4ba33bb790769ae00e5e270f00f329e7b5955ba54d4f0c294ea38eda72b62cf100fbae8859d138e0f8fba94bcf4a87cc5aa9d3ac080c8a8d83fc642977494d13838662176d102abc19b4eb1824dad345854a8e289a85ddfe537fb53abfbd538e7ac32ce5204764e48644a04a7fb5841d1930d4965302580e617c61057d3537e922a943237e50ae7a13ee986202694491c275358001b890146a2436d264b017420dc92b6d4309379986e12cb5a1f666eb30f316da00d2bb7d9879836d086a6b68bb5e7568ddd10aec72ffa7c790318e80c3cd0cedfdaa143e09540f95ba1c13ca52aabdd2405cac90cb492b015c4c065fb071d906b9a6a99f073a98c79da1594a04e736b8821039f948fdfaa16efc3d7414827cfc38e7175646f29e473242396fc1ada6c9cd09588cd7d0805ade6a908a409569da5f29f2668609e0a9231839b2a8925477287f725b484caa18070a6144dbe906059c90bdac38d36754d7c074adfef65a0fbd81e03cb27f71f286f95e0f11bd47a29f685b920d609d73ef327713d78d1d487470949e76e5cb23e3f01f208d48d92f0155e563f14c8a553b8fb23d3653c7207489a084861e82673e0498b983f9b4fdac27708df39329b4c5b02d525f010f2dddc599d6a039b277440b8bf143e4c15787469fb7d12a48cab92fafb1990f7d968b46a7a8e33cdd4571c5923b278b8b0d52c4f9731bb890f5bfec202f3b59a5d7317044a337f7b070da2426b9fae672101a98185180eb924cd937fc2c7636fb2f6193f89eb015ef66a37b05cbe4c8d37838d6df761065189df23abe5aba1c14e04ad1e965ff0bba9c53ef028ae68fe7c8d4bb479c9f2effff7182acf0b3ac54bd1521f78d86c1b766ea30f216dd82b46555af70b948c83922ab35a7d32b7d9c730b6c81abbf1e8b57987ee90d5e2d69760902f5ff11188641dbb2e25d7817f86b412bcb5240522f98e0c77ced627e72f0c136e40946ac8cc82b3291d4b3f51c7ca813f038f55bae8f2d92cffbc098941b69da339d509387c213403413f88df738591cedefb16272b21a613aa60be992eda98e9d5dd7ac606fdbf11b1044c0ff9d6c919b626dea2aba576436593fa2d93d55fa29229ecb572ad9ed9465febe49362640c5f3783104e3d6535ebf09a916d6d0bcc60606d05412623645ac91f5031a9bb6e6731be27a931d4e070cee67f188a7b302349ec9ae1e60fa254224f4628c906c0b9bed8d9ae62d3880997d2a89e830d4870b85f0f518206ca3c1acb846c7e8f6588107d05bfb744c343330d5ee7f6059c94b58dc0ca384375abf324314b3103d58cbea484bf196bf350f0c56f99e81a8e3004032ad08c0716f0a256c6ddccfb1b71dedc23af0dff97c05dc043fbf79bfe4cd2cdd7cfb9391dd88e6d3adc9303f303aed0d768dd12fd959bedd94998db1e4dea3eb0004cbb213d8614a628178888ed0dd64eb58b291e0dc40e682955bc7f1e4cd348087bc0250c2a3bcaed102422025718e4fec4984190f8aef2398874ea5f1b601581a62147d24b3f16551383e46a50bff9e2825ec1fef8820c641936dc1fb9fa28393b07afa6c036b66e9dd4acbdbe382a9b855ffee1e0faed573b27d64a75854afef0fad4f5a1518900082e917fa9a0e8babc88e9d3af9b1d82d0acd776831ea64f54d5dcc0781a4221387679096790440d06dbd21914fcd42aad675293a89aa98b0169fff9803c9b56ec1242539c62512319e0962b4dc548d9547d8085d94e75879b0710916be332d960a98f964a4c14c060696387a08030b9e8e944f4c4282573ba9d779f1fcce4062a6cce7dd9cacaae3376e223bb38d1cabc6992856e0b09334f8c94764afb78726ecb469f98f477fe1547d7b6cceb005e003fc8ee130acf14f67d4b55189da23b7346098b459d41dc438b1b35994d224c5183f9ffbbbaf1054c78018f7704c3cbb9d37fcc6f09b816425698f7bc2cb5ae2c2480387be55523e1713d0e2fc64841069d2dd37118e2149cfb27c28a7fb27dbd60cd0f5a3b34861d5addc60e755c0cc9db5b12b5b7c673347a36ac420e63e4b67045b397321b2563b50adebc5e75e9c039ec9bd5d8d5dce162eca3b3c844fbf804847adf16153ae31ab713bd222f6642aadaa102757ed091204302a08370986ae2821ec4b441c810e69091845056d16c1c5d87d9fa71aac0286a4d1d7b7b440caa7ec783a38516faf61a2e47c96d6c1d7275334f4886176e27709af1cd09b9e08330c60392181ca27adf31834e6b8851dc9397df70e9a88d3f4e7288dc8e82571460a2679fa52cb2755b0254ca0a85ea59db58fb5283a44ec3246bb024445e22d10a09aae4de1e0552a3a01efe4bb8e6de01bab0ea1a0d7051c2675af92ee6ba84be1ed7593f4bd8c30957e30db8b524963059b1550d405b2695cd458c15f38da3b10555712625511b8344c4fa287a8507bf3e2a0b1d8d4c5564486ef72a6371ab9f28cbfed6c634fafc8e5a64322709a582c935e34589dd2e3c91e95eb08af8dcfc06a739218105fd4df3976e2c184eb8590464252726ec4af1457d608227dd0faaf8bbeb0c60840139ea919285b0d93c35718c8a2a97e071263f5e4993da755b6dc3d74fbf61562702f588cea3024eeb569d184e26052a244e13ad74b51defb2f2db2fc74abbb841717f2c462acbdac62d8d33737a5e60468afc66048bb68db98b966ec8515f3cfbbea72ec9c98d149625632e22ad19cdcffc1ade004a9856c43fadad0cd659f32296b397c758c4722a0ec6af6bc92fa0880a6d42b0a58a9945831864f7cba58cbbdd204bb47a396fc3e169efd337e2c542caa99aa8e08d2411245e122e1808d104982c505a39b492bdda06eec0d501b8a5b7a2290ae976a67be2803b336e021b87487cc86a1b89d9e47d98e35ede2e694b4276c2132efd494a118d88cb5a3a62cc89cae83a50348428a3fbad3d5e9fdf9c441152c55aaa527a8fd5f0100baaf144717857dc6564a6ac797633281c88ec43508806328ddffb42ddf8b5e33e6479419934821148fef6d933d563289dfca88b83f05ed87b96549bd364c420885229547e91f6e683cba98d8dbdf72308dd1ed341888517a402157ed1168c42d16acf0fcd433fbbf8d1377a633e78d8459f22f01f9869a23793ef70688238193692399f2158ca24a8438d925dea67bfbb94c502ebe7aed8cadb25dfdae7e2c0c40c7531a768f79636ddcbb28e5e22e5c86c253c1188d3998fe4eccfd9f14466062374b110ab5a64f265096a41c83c9ef498cf387500e1e3034c5425d7dd43e62c0e561e1b52b75e56e4dcaaa8f9d0a394ed0b565a26104a6373221d94cd476eebc02bf85fc45dc9ecb080aa8a4acfaa28c97338de04f2b6c78efe297426d4ec1996e2d16e11a5761dcc4083f2f113840f0a736baa7440a04b9789c6495e777ee904db7d745497683241e8c54d661f0a30c85827d81be5f4c7ad5a8d7541c42441d492dc097d05e9e1223910bc9268d847dd415b05a401601fbc05f31803e6811a6aa2cd418c662832f78004e8970e5819eeae327580229bc5684a2a7be55eadeb80fc401f1241a8d004388dc4c64ac494a159cc716176041b89f63462bcea8eaa37ce0760f0c85ce3e254d73910dcc36592c6e9fac46fb5a018f1028c52b0e97c3e816080936a52493fbe57624604f8b405b2c244ec8ade28edbab044ae29c7f44b32d1c5b627753f2136428cf76f6ce6bbaab2ee9a4854f51add805694ad950d9e769869d7f0e8bd5f0913f71c7c45fab8601c34de0b6446a0c27f1d03826c22f284ee0f7d769c41dda8e07f8185b205c2ee3867d72fad2633048e93c325e82e8451e3207800e28926852def012a2890b40f88081238d7b35da23cb19a578d96ceea398ffe2d4f0129f7ac268fa24cca910582fee3780a1f066233b47cfacf7352f67c280b7320603e4306739cff7c222d733a53707ba2379f03aa05ffed61df8cdd1c47b24db05ba6cb0af27030cfe303b348556cbc89c4e8c6f6caace8a03f29c6976d9fd781b8ee6d37ba8e652f94c7e15c0fee359b4c32c9112ec446a124624c6e1c6634aecdf6da1b80953fefa705bacc994dff410fc56c6d64c046edae42c14a85bec67838252f6b9d580a8980291b6ae148ef99e103c733a9b1514f5a06edf21d8491ed071a5d87b452495ede2f31331bb49ec3a276f2c67eb75cd4f33bcf075c90d426e3c321d0a5872a3e15861e167b9c08a1672a6ff5c5718c6effbd4365e0cefb6f4b356fcbb21677197ded6da29ca7bea3af1c6de6abb9edcfb37511815d9faac92607959077aa398abe1c8db037635ec2fd011f4ae206d5c95786108dbbcc55860039236bff750357914864d48b0182c5ce34f0731bd868d3f2310e896f696f071295d4a0235c84ac64bb7114e815d52245db7d86194deb3774f987b1a129f5005c768e34a838dc76d5ce793dc6894b878be0954ecc00fb60bfa2d8097512ab79a8cac3bd2785bb3e20b7f60fc61d6a2480102d0e2eff2d34e4e3a7b05e47d8ffd575e1f2cb735a8af77f010b25e8391dbd39971dad8fd3dc1141ba15d633698a135a39ac9f83c70b47c22fe61a7ce5367a5c508bb28823c724a3610c59f2d169467a8b454a212eadb33785efb30299998748621009c9c46bb10608d7750a95d88c9d7f5224c3bb2c7888dc0b316822efd8b3f8c995dd8b360e8866f94c1234e83c098408765bc97fc8306113e1bd507412b88eadeb0082ad2434d333c976330e493635fe1670e895dcb6371915de82975d24862433d669263739c922b0e46f80ea1ca7a30f72c4ddda9fd9e34f0e1b28cac4daa76ea201e4ff05fc0b45d0c4e867b23e7c9b55cf3a0125e0d93fc91a84ce040a42087d502ab636fbe0c9fbdf64e9c262928b9d461c0d76084627664b9af8a105195cca6fafc69093d7438bf2b5c67a78c278809246d8711efa9830b2c4bc4d46c1560b2e1720f9ac77469b9c491a75f730411664881b8560ba4eca885426d73c062aed93699bd51e91f50203bbe8fa7007a96d618038ff0995a1107ab2699e32953ef6d261bd084c841966512d88803822ff1160ee9e6823ac91298c6c2dfbfeb8a3aa0b8f199cceb6e145569cd4c652291cfed79dacd7b6de2f1e06e195088a358002db2dc00b35b05d3aa2898f052674b0eead6b740e7c196aa862a18209afa55f60a83299dffca59d162016f44b98da69bdda9368a83c504d0d19fb59c9b6a99ae7998b87bdf3bb3008acad44cb1631ad44d403b0c6d205c5fdbcb28c91ad506edca16837b28ea0357ac6ea984574afd27a3c1a17a2f0be46c4690dc5eabd1dcd68c2b6c2b9f7a351bd5d94e8de3ef0c354b77cf72e4b3a7b1d04bf8ead17bc26ee2e2112c507147d02642b0f420a5dc93ad9dbf0595835341c8d66fe109732febada1049ba591f01653828e448951b16a51d3c0683fdc53ce336303844442963961d8206afc3c4398fcbe16787f3f01e0b66b808fdf4d726d1aaf13bcfec01eae7cf6960ec5840874e6308ae520bc6bb00c21bb4193cb72b61f419c45afe9db630c19b70adf60fbff8917f70b51bb7b6342b8c42e6a6e795720d0c6001c00df26f1bbe8d46f5a79f1f2e84e1ffbb3aaac99d629de61abde1ccd61a23d26def70836521f2f78e6b283cae4b0914b1c7b93d5ad3f96dae69a8a6eb2618019035219f75ec62f2e2e4ade826d0c8c4aee0d7d6cd74b584b27ceb3d6e153008c1ffeea18617a2c550a80d730c89b178437da9188020c345b7f842eb72b8c112d0d22fa845b8402d4d4f7272d6d0ec6ed1bb0c1bf962a922b786625dd7b0972b0ecdefdaa8d72cb09372c2c223adc97f007172c848366b460de45fc04d07bc7fd46494588456400d7f93551333fa697a13ec2188279369141d217290559c0ea86dd68a35423b997e62481d38ecfeae35c8b597fa500916448fe9c821e89e5a73b57df24f27524f3d374e5213c7f5f853c7cda1235c1b6d55292c9c6ab3a68c549034639b3f36a0fbbc56faa3dd1262741b0a6655383f04fd6b1dfbf773e9ba2f9ec238c827f4680df2781e6d14e4bf11bc309bd6ac424e06716cc8bea5958b2b148b620014e1d99ef8e942ab79cc9c8daf176b1cb580781109808eb2e69e880927b265cea710b034ca762ad61548ca2582dd394593425dbb49cacf916dfa390dd503e561b320e12b9a66311ad7c9ce2dabf0cebebcb21e3b8bca08a20e862b80fbb6c688354d3a7bef79360cda56d42b48652f303fd6368bf090528343ce33c950a33649614c75749c2bb213e218868e2c445b6c9c9345b51a6a10cfb5f5050f28e01775b3252254e09fa3fb7d9957cb5509956743f04dca34de4299cf77eac386ca16ee2043e533d5fe21cf422df1624ccb067381d5e6dba9c656c5751bb0d08cdcc012a9c06cc149a393fecda45da8ac68f183379c48aff1951400a0388c56de749b36c0bb8d98571b777ae5c5f81cf67be5e074c381c8c31431fb8f5fe0f9e5c82801d2286d1b189b4423ef3ab4c91241a9945854ec79f04f5a94a06d479cff0e52f2a3914c8a28f0929e6c58fc26b03cc25da1701188bfff0b952b7bf947808f4e5f008786d17729aee64baa7213f4d8a39e09144128d15a4cc45e0b66d939990fe88311f0ab5c4a478cb14a6a3924107e99c6cf53e8cbf2b4a60ca17fe7068daa53d2bc19767f34f70125b1964e2929c71d496a63f55c15f96b8d18f13f1fe8633af480094a8dca68be798ce32c028aa50539fc0a11d4e847623662753eaeef37de38446311d6053f5d6105ed972448e0e2bef23e8f2bd9397663cf1620d14dd53c82657704de81e243e463c7b984710bd0ecd192e4d60deaaa0aea7803cde14c7255da71752c80feb40310c298c22561b955b56a9095a49d432b9054423d6b82dd9e210cc47db2ca146fab29959507d2a9a8317887d7ab9d49d5b61863de7af8cfd80d90363d37ef99daaa0c774783891ccdbb1cbd6f5a79da2d9f3baeb4801d841b381b2416f6905a74175b8bb9824b51b23008c913006e251b50750c9b46f5e44bf4f8586affffad7c33cc5f589ac5f82d88dd236604a8aefb0dc518acefe0c0d5319dc2a4af572c4c9c7426232639424d6e1dae6b3660fb40ec9b9f8503de2752a2866895f5854870b80e4215f2ddb0621d8c6b782460984220befd9a473c07a14bf477cc5ee1f97735e0e2fee029fd2c4a3d8bef0b44c7ab3468c34a943c028f699ec29f354158b34be5daf55da78800255e3b343d524afff2dfa3e84449b7d76d5fdb0c18e140d8a6dfd84fdd8b1f1836a4301cf3be770edbb844bf2186ab532b773bfaa6dcd435ab67165c098a8a90331f30b00cc5423f7b6fc83d6a68123124c0bc380338e1772fef71b024077c2e9a0a6d3f3872dd7f2c550a7cdf79d74c95731aeeb1ab5cb6dfcf46e02cc3ac20ca55d32f60dac32052d348f7ef14a49dd4f28b81cd9d0ac3d2a63f913301a936755afd85d5c9342da9831f8f0e997f8a95717d169aeec3cc9fe0b38c35024ae2818bf74b44760212208184d8e2c6ad0400543807a38a204b8a011511a733d8f75f285d7cfd6fbe48ae503a860b44d9c7221d9cc0181e4890fd7858a048f8c65ba9fd025ba629c54800638da301e640e45619af432f4b13b350311f345b4a347240c8a17252b2e66c55146dd9182a213007f19fdc4c017125700ee961c26e4a6234f50aaed37be63caa459f7ca4c0f55f7f114e1ef18db8fd6ee9be9f89a1cdbbcb0c8131ce1354cb1109191a5e7142469180c94d8a4308d3b0176c2b21eb0fbd49ea270d14df5b1faa83acab86630ab848e8c1834eff892bb98c1401cf977f5cf41a107fde4e737cf1dde5cc8e38ffb18256b85920f5c9755faa4278bea98e8015757d84ddd0c32817a701cc677f865e739a4c08ed3213a430ba780cc3b1ce7a881db10340c4ea13f6e5c3c24427133bac89b8fd5ae64f2c93e688883e8b8b73f53366a06d8e58673f0f4a20b6aec4122e296d5cc402822690dcc339884045cb82ff5e7baf132f83e402fb039a94d22473349582e2eef3a139249a3558f317013b711319867d59b462b4d7d5d14765ef87ac1a0569487137b1fe5baa0561d0e3cd4c8af49ce63737c82f0a2f53c56d3add347e7482262b73c23aaef878c61999b4f6ca27e6104c383348004eea3792c32c8fc4433a5419b5c0ae0179ac3c81b231520009dce70c7271628a7b97eaf2f3d2f9c30094072c310199d9ccc9dcd7bd91472e1de7dc962ad1af03b8b916bb9ccf56f2f7563932c3218f858424e8e871457699fef2839a9c966c806955057b99e700dd24af870511019322fd28b9a544abec4bd0c91b43466baa3ecb9e939d09f0a0c9236f9896591fc8248ed7072048704716484f6e4f1fe3860dbcfbce0f9a9f8fd737fca90ae967959ab6cb727ced3860803b01fcc6b7cdc8750a175cbd43fa59a19abdf2859193219172e38e11d9549344e84adf887a38f72369610e0424ea63aae8dfa957ec845304ae45b118df8b4db194fb13d47c255c93d33a75d8ca3a54a60a7da4fedb14527365a1b3c453e348e7be1d239e46935fa1cec99fab3aac1d293ae60ed2d081b38b9969c4c63db575f84b086fafd676c84738528279d7edc0a0e525d9834793740590822b33da6db1d985c6d24d901c7077e31ef190a8a07fbb013ef25ffb8dc44b6b32580e0830edad462a50dce68cafbfc6f3ee20dc6e6e73c3e121c707880e119cc1b2d21554a45634220d09dcd239a08eeea36f1607018248c211e60ffdd046a3d59e7d36f1d62314aa97afc412db6e5e21dd37d94fc89e7d1a09d612fee999254cd47912a14aa6bbe566300b17cffd01e54126f4a9e2d76a1f80092e41b919990c0486c14f96303f0bf6f3a5fb2934803bf76dd82eb8839bebfa8051e0161d8565683b4ece88ab6d6e26ca227b3dad1ff052205e14ad1b0a84730f7bb712c01b2f07d895a42c3a21a54626984504e294204b2f1caa938f0bedb8e711943d802847e65864ff1989cd99c3a734327945381bee022fa8d4388d225d9a14c08e10f2bddfca51d608afb185f671970c29913a5ea33d013ff13b27a5b9a6ea6b34d4166689285a4a2c25bc64d0e0243be47c20cbf4240e6bdac8ae61cc7f46075107ccead59182c9923c82a5d99911817e51c1afe6739f21e3b752824ec7889beaaa51fe50512a173b68a37e7865ecf112ec0b9bae84ffcc1d06d06512bd078df64ffa547a3ff53d79ac0cd360eb6fa5d9757a97cbe171d8dfbb035e32f575306a83dfa04db2749ee6f64fb8f1a74fd63a749f2cdc74e22b36a58f0ad33bea8abc91ec07546ece3569f51f545f4d692734b5c75939c7d6a03b54e53390ed344cf9178d42ece187d48633c6fab4ee8c4dce4c8610a29358c3b64453ecc3643f0eda402f92513af5e779fdd7280ba8a6462837b44ccbc4e887da2d3b8080164193a24fe8d094ea12f5df26908a3b0b4f12afd97b13282b230243b9983d91a3fbb399da7461d4ece4850c5c3cc9dc2cd8071bf1e5810a727bf836a5816cf0e4d74f2c3e7a4f5173f295262c01a5e7b43e855a8bb468e3807b7e2a6fb9a8161f943a2acfb40918b77ddd570da94af992e387acd1830b35149311e629f08dabf93ff637d6a7548c29e302e99b09744c2eb0a448411a084546bec75b0b16412ec9caed4398f78c6eef035acf9343403016092978770187148914818921f9c75eb72564ad0b9232e903bc4519ca4f4df588fa68d51327c3d8bd7ce0cf3a24a9e542c63fd32c892846539d135a4206c04eaeac4df0b0ddc807a31f230def0a72352d9192b42ded645af59ecb235adccfc0e06df21a4c458f9bec54b057c660080d4168fcf2d4bcf7bc59ed73092a39e7a61c422837bac805e05ac2f50b77138e501700928f40b2c19c722cad8976045dc0d49e739fdccd4c40bf8b52ea2a6295e8ffddb1347c1a91d6593d14730ef2ab7f88c7ccade17314c7397cb3c2b558a5c513c5e06a7226cd152f964709a212be74add806335b83c9f75b8805e12dc7d39e164a3633eda5ce61856b9f497dac4ce6dfece03d47f389507f6bc81f38aab069174b50a97a1aa55dfe3f3fd96738c982f21eb25ec3411164ef6057b45e3e8ff9acbd60e5a109fab4e6c7d26040a65e92d266674c0bd210e18332254a95d4c3e63c8e7f8846a6edf11d540721aebd07c7980d5b2688346ea825a08fef55260d63b1c1f41350cac52be87c777971f9761e11848d7b5ba135ffbfdac9f84f803efc1d1387a520e1c4ce01db800c10cc9d888111f77a914af5d000bfb66ab232c2c141589fd9f8402f099ba53982dc09508aa5d96a1e71d6fef510ea63358e95696aa28d5798bfeb6a1424ef272305457dc763a2f6f0436a43198a9d48217229534404dc34b09483466b1f4e0dfa9815d48b2ea9b886adf9e6b1b3d70bb9b06ab9e3b3190988ce282b566a834aac1fbe3d3099fb7666983e009393f7a9f9850dac05aec8e0182302d44d442bdb948e674508aeb3f70060e7ebbe648abf1919a400a6073ab95605818c0133db65f4a5488cd83ca1b977400b8ba037c98bf4b95658e51bf4529df4f96540358492672d579888213ff2f62b092d89690ff637a93133b17c34c14b96699d9b36ad9c331d30c94fbb3b9403d9d50fbdb96044c0c94613e70da0bf88f0076e4e4dbfac44f9f69dcc8891d48576ecc92d9269963c79f9b86ca22069e6a4e76e92ea5b39c464f7b14eb4aa021be736cb26351380d919629f4bc41d45d1f62ff4c0ef270f52d03b94dff4c9dac4dbfb656f6157f66e9efb65d9da59f09c721bd60e7fbad4a60c9c3b26cad5ec7eda44b426df6635b635e6af58ba668895a4cd7937774a1065b576f1a73a141a623a091e9488a8e9853b451322ec15c80ba790766f0a40961558fa36ac69d4de359b34f71cc39dbcb452b72c7d0088e40c9e03b419393dcb9a9e57e255aeb893789be758d35dc01aba94db11d6ebad0f219b284a384fce58fcfb725f41f485f4b40af924eb7bb5d2eefd85d8ff68e13fdfc4ce8265079ea6b04a42c209924b9d56487f8da35f2193f7fcef015ee7cf7a18433b0f49903887659642db87ca7ab938ba9faf3d141d9608dd80444cfec9fd6f1cd82de76abec1032bc922fa71e0f4f3513f559bf19409c92a1156d2cfccca3785b345d6674a0b51957476c870d4ea4a02ba319a0a5f355ee24b360d1d91597693340cd8a2ace68c6213b962b72a18776f02738e660be7dd71b3244b853581c4d48db273ba228e8235c0ca5eb07f56605d759761c8b22725b97320197c7b4c70b664bccd54babdb9a31a36066a858bcf83398387614204a771be30dbf2b50d89a04e2a30d4abb3516bfbf2defa2c4c46327e1a8eed61940752f21beca0807cc3c225bc4dfff3044c8556c532fcadc090432a83d6fd94e968d4fc2f1974b8b03813d3921f046a73773e33bb19c08ce29f9efcb61a9978c2f3eb381c1e249fc0c42b07e7c8ad17e17093018e594f3765a0fa12a0b9623da0a25de35bdbccfefff5717b54731c263ab9ef2329805034281a4bc40641890becc1e55857b44c3e449aa4d77d4cf2d4bc7a95370e764c9c028fda44a6b36cc2194378792ce081a423f9404995576b96a104e08c2de75dbf0520a5abd65ddb09de4741becb6a35cae49a6f9879bc77c207e65e7a66f5425175b3613f69156cfef6f917b0fad65cdac278cb36fbd721f3fe6d46acd7c3187495fbb166fbcfa22232a4cd2b5aff502cf5b54cc3270624141bdae4371d72b34ef6a20a33ab52237403c4ed1a1f8493336432be389c4909ba4c2a82427eaaa213f8894b0ee8ae0e8517a668eba7ee9bab2270591ee0fa9883bd33bd1e39892200fa15e86be610188ace3831c112013374822c452115101f8cc0e712d69cde35539e89b14bdae9fdfd781c5c57d1ebda11dbb1304cd13bbd25286e92e28675fa28efa56ecd75fd685c4a1d66afb5d30eebddaeab2a521e735bb9a120646826993746c13169837e3bda4c8ca6dc448d250edbf2596278e83514f6a0e5c90d2849f31e9f0f7a33d47568e3eae857af079fc9d19eaf810c4bbd40c02f005a09f84d11a9a0dff6248de3d1e226cc22ebce81ceb8ca0ce97d24514fec31047570b5d8082f7babdf20f856fe9ba68fbc782b879e222691e55218a4e916d3550fa8ba056f04dfe3df00f7e22577e4175028c5db6022ee6f264ff1aadbb9bec2dcb7dbd0bddff56508edf6bbb2d08b7a0385374c53bdb88f5739433b97919f91c8fb18a20b769ded9b7c1363d3c9855c6e6b57ae55ac8962d1fa2956e26e12cbce2882946b190010039517f031f6c66fb817dec4743a4c20be81bc91de2b4edf56f9e8368dfa8822f3eec6981c2968dc941ffe55afdd20db3398aeb7514bb5d52d8435bf1b5d2df23937942e79218e4438b5d8740a2bf5215c062262129d5edf7c4cfc4b0d878922f9c58f5a64bd4110bf1232b16f147a2d28f7720f8dfd4ce8510eed74872c0e01d562765a255178934bd89c24a0ed5a933871f1d018ef714927ee64efed61525d48c97919c3e8eb81f07a31430c94273690688c3a17c5880b668fc04ae8f560e9517f9f97f72c98061a1c72fdcf3a0f495bc031ee2893a3a370ebc294141162936397d8d6ac840399b55788df894e756499833377149858f9ff6645df35529cc1a1c1af0b538a2c5322b58753c6198c0aedc18dc7dc53f930a7fd44419d1564669ead60ca70ddcb0a7547fdba9ff95935e0bbb52d405cccb1124c945a3fe46e3c58f71744dab5b1784234e9f684b56e0d44a35901699f838359b2ed9cd3a955434aa0387b44e063bfbd3378f813ac62a4e848d46b693deb1098455ee47ad969c9cc54102947468f8c98133b8fad7aa3370daf83f3bd71bb512e59447c717f6cdec43cb238aa3b976debaed53220f61a01d810d795062f64db45fccc056b952278e9123ad64e7f4bb5a76fdef7dadb8501020b731e7f6278aa41b8a807adf58c2fe7d60553641ed6fef0a1342894d32bb7d49435c529de1172f6b99cc27aac0c288e74f67d6a74c9fddfff869c4427ae6442e265d1875e69364ea15d55762e473f5214111515d40adcc5ca551e1919196317c7833c02447b276d6496eeeec8a319dd5182ad2bf53aa9a0a8442ce1826fd11b01c91bd8fbf5d47136066e3ce5954241448c4485ab0108283a53889b4a4870343a50c167aad8de884cbfb6211367bece5892c1e748ac8ce7d7511dcbb02fc61fa0f32626df635218ca133060c5c9f589b7013e8da4789816730fa8a5ffe99ebbebabab7709117d71e78f7029247698dca4c436a97bc9a6bb08bb10c761990e9cf214444646c75d966d634d6b15a52500b71261bfa584d342172698afc620bab8b848effc806a9b38a9dcd78ab8fddb1c8b16adf5a522a7c78d37750a57d92c664f3880f11ce8ef150be5d8a6ab657c3aed52f6c5c5155d4f80a58d544a5dd17bffe71db0a8833d6d7161c12d4b538ef91e410a92a9be572cb7008d0011019282b87c606d190e7ff80a600d422a4a59af282ce645fd370e576ba20b411e8ebd549449c8056ca3c8c436b1259aac7972fe222043c457694b0085b463b2d5b9a3631d3819284f6a200268ccbb32ecf6062c39df882504115d1d1b85fe97e40f9905d1c1062d613a25635b3e40f400893eeb4511893649c66ae7953aaa135cf27d118df913f62b417938264175fb4434fc0dc254c26707ef483542048d9d9c7570e382f33876480836c3b9f138654aea20ddbea1948cc0d6e1322fd576ca40935628c8c9a99f45a9748984438bb8c4bf8ecb28645a8e4d82d633813f53a40a013d4bf4628c2e57572326291b203842a2b2bec785d61682ca5b06d16e9135d5f7e9371bd57cd5240717846ac5407519634ce158256b674cb3671d0381cdd22502413087942d13cebe41f0354580b9bf32dbfae8850613fcbb49392df5d0bf24f250adb1ee5f24246a9e658dddf621d3965a2cf8dbb561bcfedf0760e47ad34ab60fe9b16f2dd888d518b40844efde00e170d52184a61d7ae6e29ceeede959ac7e0b18a02caf42fbd9ed0e6152d2957656e69c974758d0316cfc88c4ec63ccc09218407833dc715a9630fea491f122e2440122f3e1fc339a9d85b36a788fb465ede77b51eb7f5d333f4f2d54e42548c6a44893233f0e132f9e503a4bc3f1dc8cbe17b2139cfea6abe2df34a2197315adf8bd7769d9548aae05c94eb791050deba8a1caa490f5205d806821322be9c1a47f6ea7286c940d181085b2621a537f3d8386fae719f913e92f3684034a8b4522f9e1799e35f8a51429e2fa5fefbe27a8ba883feab529a3467efa1d46e5503c27ed02eae43f1773f4a5302f7f1a8aad1c46b0edfb8fdbcff6a3c541d5c5f3d1d5ca6fa5568ee500251336866b8674b5007adda86b6c8b411fd67f172b3feed0fb9484d04a31445701a34a34910dfa1d4f6d6b022c47f8a71fdc7c66a6a265387832b220d2879f9d17f7037da52a43906ad3280d5f8518afc76b0f1a9794f9e0597276a511a6c575d1907b0cec213534b0932a6b2e08d018163cca41166a58864a839d02b948a299a9015aee4c81dd9afc84f3dbb384cda9ea746e003468a5cce8d110172c83022bc9661861e4ee0b1f305c5d6577f8a83432f347cc5ff8ecc282dd4d2137b39ba80d0a1534c58021f8d8ee6333af62488e39d412fdabad7b83bebce5f42094c6e2101c9ec35b0b32423737e2480d12def77571873876ae769d5fcecef91c1631c533dbdb0918b1e2b5963eba88d55caf1f320b8c23c794a4ea3bc88c163d40749637efd9efc52c053495db559b4e8c7cf547918215dfad4812c94a5fa4553227584bb30b2d9cbc0cabb88d38a0c4b572a3392b1e5db23dc49b7636079e0c293abf9fa46ea9c745f6742b19c796ecc90a7b8173843d299246260c4edf44a3ad2211299a131410d5e99a51829992e8a78e92c332a089ed32ec167696e449b5f522578db72d4db0cad38ffe8609846392c6a415061d555cd0e186287ffbaff5653c47164db7f776dc82e1377c190a6112295e41f4285c266c4dc81e8d7d59bdec8515b04a42a9b388c484b5b30712dd227f961edf7308e0b43d419b632eb5a19109d22f7f908d10b9d19617a53c09285c8e29cd080150bdd16dc5e597675c4faca27602d18169abb92e7bcf25f45382ae2851c5a1f3f761186e7f4bda5b6e17709388e295b27304f6e1d50517299d5f99df6f2f1544921e766c157d66ea45079475a430815452dd9cebd33d1940092bf3c194516d3df4e172e314412c2696a7742993cfeb6f7f17dc2e4df5ed0f11a7a393e45098028553ec0c3a5ce1049ff2f548bc978c6940edc5600e94223565d483befbc52e57661f69c34f58b5a45834743b81e630d5586275527d4b199a232569c30cdfc9bbf1b4d92bf88f1055f1f2b90d4d4172fc1e976bae5380c1a089464e1f5109bb9ce1ef647995416520c1b19b9e100dfd3f2bdb4854f387d0df8dc67eac76d53ba39876772b379b04324287557a372bc1b8748d13955365273fba68de7fa8b2a85241a5afdecaf1758ea5da035fad129c637c065a0f1a335adde857c1d84075c8d9576679d3134256de02de559ab3556bc422a1594d274590d6cd69da6b8c7bcf683232a608d0531107235425aef4d4ac75fb2c519809ce7449b2ed700548b6e872041aee8138cd06f78cc29c7c379e2a6a59ff056f9ac2557043a5144f45b4196fc0c82b795dd180d09e7648347047feeaf6cbea8928e9d512b1287cc876ac503a8ec41acbbd08c278eb9f993a202ff75f72f220f4059a71d0214bed55a035c9587183a5cd1ed838f5e99474a8650c4a9c7292d8a44f860b44981ef2d7090da0304fb1ca75a43a24e043a237bdf186cb857af9df154c6ef911f328fd5a272b09f886a988365e8ab2dc30c07bb480138c4ec911538271b55d2f4986b9dd6e117ce7bf7bc1e93993cbce528ec4ad5568dbabb82161205adacb7647c43774e008d1efa188f5db212a37517808bf2aa33e9a270c47895bb9e4005afd511ddba5c09dd24e2eca0452ba1b89541fda61d4fd03519c1234b285861011e49665be32360bcb89e33ae09ffa148f8a2fe2f3f7abcb34d0e816aa458bc7881f005ba10b2342e8ba9c742eccfe79d92eab191b836e39dd64daf171d9836aa4068d6077b644b4bbb2c4b29edd760f446cf117a46349749449a5495c04ec4479dcf1169d6df0daa7580220d1e98755001d51a9b93b155efbae1eac7aab38f7a6aca5b0bfbe750d30c4423d8306f43f3775f24df3561da357874508779acc8f78dae00369d8d582453513dd20d58fe716da82c11cbcb1bf4402ad5653abd96e6b36db5840ea3d6a5f3b55d8c4544cf701fed676f83bbbe99beb46b4afb2b4cdd872e944b4fb164fb13fe3ba70b7826365bcc56ae6e9590cd86f656edddb0adb9ac7ed55bba67146428851c9c05a7d2b6674ea657ce79ce8959c82dd2409eee47c07afa68d20227612bd69d1679a9bcfa7d3e99e1c5b724f267a5d81a031d2d46401270359e69a12e651037debc00a35ce2d8497601cb437c1bc06d0a26bf2ea3856586fa76ceda980ce5df1ea8ce64e85820d4a8378404c2f4446bef15998577d4f48d7c84eb314a649c0b9c179f66d61c00cbec5b76021ad56a3a5d9443387eae32e8607b75db3026f741bbfe2f7137e330dae19a2e50bf5ee07cb3dd914ec6ebc5b343337fd36f5e1ef0c84fc972dfd6d6a5be0f28b871a01bb1ad450c3b5beee3547ecaf1df75ac24ba294a63f96cf6d953775ad98d443fc41168b355b1e19e46ce65e8e652616b7e3702db8840f07ead965b412e242f00ad8b2ea739209d01c0cbb9febccd6c495dc4be21c3c70eb8526882704641af47852374c24b387f0ce1ae84e28541b0d064958ef90363e899bfc5b828543c809dd7b3a25ae35208f3062156d55cc7d2481ed47b73e8c2df234bdf8fb651178f1e2d3c99197a9bc1d81bdae497db419e9e52be6028db83d56936f546b8919ee65b954b0e18236820a02c197d9bdfc3c334a61727300cfe4fa63405c9e6d654ae547a9074d42b9c9f5043b51577a7870c6351e56f9e23048964689985c7c4678288bb84eb1be86cdf116a086d90a6a5e034be9820c9d2fe13a4d9eb1bcc75e2b8e41ddf9842f3af9ad26faa99abeda4f925b79cd14ca869bae8e55db55216fbad5471e3376fa28722abb248a3541558b6f7b943058eb47acb8887d0d9e673e110a75e67238d39c075d6c4ad505ef1c99ba9c00490b7ee58552861a549e36a4d20eefc829bfc189321e6d1ce253c871672750843ba5fbdf331d209d8b558d78468cf85021c3e51566b0dd4e7e4475c605317b57526efde2aad09bb1e070568f5ee2f5a5666c790808e6b88ebe6d50b906d0183de98560ca4219c8e6af5b6940ec663f7914d8c7868b814e91026b87d82369eb685c20af0d329eca6ba4dd21cfc3aa37ac3966935e7880caa9346d8395086dfd804b7640193efdc05da9e57651d3012951aa6bece6e6f6fb187090f42da662028a80b1129bb1885b4ad496fa3f359fbef8dc159a71326d3d27986356bd27cfe0f019190494b0013a4c2d4c5940ca1cae032f9e0a8c224129d242e85577dab093c48882130db626af868e826249798b4104ad6798c2c03ec1927105dbbaeabdcf00ae7ac6db77c3fa2d734a249bec5169ad7ec889555708904fc96cae1e6c44ca94924c49ca97049a04c2042e8a8629d2f09e985652c8182c8644e1efb3bc37b4635727d15a1d9c50dbd61982499ab291089319bb1261c2664814ee0035e18a3ee756a5b0196824b890360a27138a9f9839e77ce69ccf728f673e0bdbcf39dfe0b22267a7b43feea0617f22fccfa2e92f2bc844eff359768b33dc4fe43e13e1b983ee1788b0f0f359e6c9a8a6d1d4e7bfcf35d8e77cd6c0010ebf5f086a9437f8ce2f8e96c9af809ba1c2590e674a3f5cf6995acf592a565fb5aefa1e783f7117dd0bbbe826bb337117ab7bc32ebebafaf5ecf60b44b8f8be6fbbd27eced46651d8c20e74bb17689401205d50d5314e07c0c30f3b2598ccda7befbd5b9599a66a339b3d9f18eba49c93748f33d171334190c4d25a6bad3b68140ceeac3eb8193030a10602f585e48368550c8084657e001c82d8292e323c0801010ee0c30aec14976c081ca6f207e166c00007eb6ed8f0dfa01e1d08a90ad061a78071f07a90b741bcf7de7bef1decaa6a90b1580c2c75d50cd40a1f844b0f9629000e8a545e0c351a6045c800ce665f84df2db62a1bb6b0220480af3869d8002525e5fb7e078df2418a5d44c9d3225c1a112e0d0d9aa208490cac6ed7db5ebbf8d7c0056dd71000f0e5389635ec796e554c7066e671aab5d65a6bfda15571e961c1cbbb8761dff9bb3988a03a81a94b13ab9cd9046def0a7e3bef930a7edbaef09948419f8916fc4c348167628578264ed09b89c2092133510291992801381383f24c2cf92d91e4bbc192397812944fc064b8e484e464a455d1f3c80949aba267f9a4a455d17a163991d0aae839e444825645cfbf930927bd130aad8a9ee393095a153dc327154e4c4e2c507052412bb72a7a96e576a525d13baa48000b3150530beff7d0aab4d8088169e2e652af9fd862417cb0846556d87bef171259131845fe078d82a139adceafee60c33b25a853f4ec23bfad74ef0bc160b05d69e768f7133ed19df0bd01beae24c04aa01a45a05579411683f234c9a18b64a42426a961039494f94448411e19f91d5a951c2a590ef841a30c8087eba2ec0d7e6e39ec0df1dcce317c22b71b60f8c2879da2e75edcd3106b8035f8937e8295f587bd01c44ed1333c83d81bda21bf4084df0bfb02081744bbd2e6bcfa05d23921393ed1759730f513dbea8b84cfe19813c24f6bad356814971813e1be30eb143d977c227fb57e29f973ab623cab72f588ee8756e582b210b8713c3242818210c9f5f7dc41e318a38ac92ebf21bbb30dd99ddb1a616034a633be80f201b0741086506edb959511925f4b141285442105a2f024e5138544215168000a244d5e5d5c5b1210e0c3ba03d7dd17640b4c79c22ffb89c2df7bb90a7f5c4b76e7561a853e9d594d2ca68cab0bda7605c30807619ba2e77dc4ad7815a74269db950b679f28fc5a88c14976f91497e24b99477128fec49db8923709bfdbaeb81cb032d7f70de0c763f02487d1c18f33c91b7e25ffd51dfcb8bec991bfe04bdc0557e249b23bb71cc991f8116f21ff5f3bfbfeff12fcffffff5fbb0910d917844261bbd28690f009935cae0a76b0740254940746e2d4c0457827602433e9a54bba1de8e4f6bb4a17831c216155188ca526bb33071f1437087a696801cae062140007462a186c34c860035700569e523ed80952543f802041d5ec17656d0b5e5229e947014bac21b523dd0859eb4eb3382248395445272fc198283edd78f49e3f7c5cbc33c69f51126b3a84239aa48f36a8be62207d01b101537ab353e2306124d634c1eeeb845251b3ab4905f446492429d8492d8cd2f584ee8b29448e165a595117c62c27202f02a51f9a65d669b684d44f640855503e42c8e4511539858070e9333981e4458d1a3b2fe431662349c0e2821994a3b1f73f3099b3087a281e79b8c311969c73efbdf77ec883cab9d1d27b8fb4fc8179ef3d70ee524d39ec9112d02c095c5171e74299936424c600231f62363ad19f20472e0c0ed689cf3f9f3c269c8757c16e91410b050ed6b7f8600abd5876f14d48cb33a7f7ee7e50738c823b1e8dca0f425d775e6b34e49cdb28c87befbdbf717d9b3c37781c756755ab71507846a38d4670569351fcc2654857f6defbf9e767140d2e0835cacb82b7e45c081369e90f203597a6f7f7f7de7b77b92bc2ef136fea93a3eb69400f41d8e89c4f2f7aa5f151ba1efd6406a9cd8d76189e6452fba246e4f7def72c067defa35c08c802a34ae27befbddfb9e399d12dd9dee9d179725ee4d46bb29eecc5de1ce6941d0a1d6b4b7338864461560b9ff77b2ffb09b2322a7bfbd9451f54687acac1b1699abb9b6111b74c06e989aa194adf8600b0894cb6aa0d90ba280b927645dbb8a63e271799072521bc7ed89c74a64a163c5a2c1631bfc7e9a291a18e69ef40ce39e71c2b278e9d4cce39e71c686227a35c56dda100e280354a6af3e22a4671d8a3259013fc23af29fbbc3957c2eb289573ce874b343f98016c374c1ed5a3b9aa2151f897aac02537f9f313288ad59f20d7b0e11e6a2ee5903873a81c6ca1f92dd17bef9d85860abf5934d5dffb48d04529ad002a374253cd4dd3fa5c668bbf771bcaaf32a9ac2d9f1541fd456e0a05623ca2f97ce473fe0313799a9e65b7e6b25e3a714436710a7806101b3adca680baeef68a5fcb5df2e7f294ec70bd6bfb313b937ed9bccfa48e28a3d08f555585d3ba81f8536a87f3f935d1875146102aa04c656070ca18bef72b939ac1819abe80ee9fa0a54ffb15599db5a2ae64fbc87c8873ce39cc57358e853feabc89bd3e9f7fb2b6eeb46d5f31284f894a8c4bdbfbdecc837ec3a7e32bfcd2165ede4e25cfe2ea2f82daaed994ec359b37735ff296204808a8a1edc0a211c40a75e6a5789d78767b24acce6ab364f384621b439478c0b1f77defbdf72f36a89c07e5afb011ac77474a5a4343a2f0437daf154621c58768ab868f11423bc31eaaefb59c40efaf5a7cefbd97f9d1f7c2f2fbbeefebc6f07833a1b3a4bab83273c4dd5915c7ee64a8e03c6a22ebfb7cde5017c3530d2cb935b8a3920a861098318784d7df3cb216e2d238b8dfd94a205b2a26f2c8bb43fedfcd62737ddf2a9805998d9113c3f87b6fabb2e631c3319f8342de3fe79c7334a44e6993f0526e4163ea94de63b8b953ed4da3f1e7bdf7becae7bd9fbdf733ec750b7b7e226b94d77b59f8b69b4b6be80c2d8b6324b862c47a7e14a56a3eec2cf87eef7cef7d0bbfb29f5b68b5e87b3fcfde7b5996df191c68419d30b8d9a4092dd0de7befb32c6b6befbd77962929fcbaa85e6d4d7b94a588b64b2ae6eff34f77007ba00d4d59f4e513bee8710246cf99a120a632992f11fdcb4629358b73b393d688db4ed7e588e66d9f4631f66f6381cceaf7b3f7c97bf866746138a3088a215c95498ba9ec771786effefdbdf08f6e4231cb2ce97f2c6657ef63163763a733025d18fef5917cdf1656c219b787a14b59289a19346d0cf812377585b050772981ed16863d729c3746b48cd84a702db2b943ed9620661a119499e40656022b28db1392892d306a0a7242a9870fe4ceda3d172664da0f29193f91a47cee4b0df56da9de17d1de3d011a6b32b0d3143b307c1e8b1d574b35a3928e04a4ddbc29c6d09b9af8e9f703bbb52e64d7fe2c93f9bdf7ded33415d176f9a2f2c8f361f315e4e78498977ebf0065338d87f16a041a62ed1976f1733ae3e4bdf7235566b1891b7bee51bd4ff07befbdb31897f0db7befdd278d0f9955582bc46b07f464cfe8960c66100e141eb8b1540ab9e1a8291bf2178bedddcc79975161499871b58cdd829db68093d2d1c3051a15356bd57cd1426eeec89a7d43c6ceb71812640099b1cded68a256e98ca0466ac70a1b9c1963d2950cb3d090baf0eb32428706155b83e7e8ad2825f176b72455d653c6dbeafdbdf0ef2c29ef17ae1a140bbb77d2fcbcc7ba880b54d16d3942e6781ee2bd8fb62e3368b0c5172b42168190d2d3cb068f9b2e0b2f865ee4a0f3793a3d67ac8d5cd58dec2ace39a7bbc62d7458d95987847f3e68a4aeae887be89a7e298950b577373f52d0c0ca42e219c150900ea3b26276cab3f33b866caa90aa2fabaaa6e487d3becc197bef1d8b0abf1510835ef958752085bcdeb8d36b4e44a3358d8e4a674ccd9efa55a5548461ed0c15a16123d449dd9e6a68c8909a79cc4f681b59f8a2485e5b484fcb4a0501dc9d3eb4bb866d5edcea59c56987f139764f06d751a78078cfcfe797735da4d0a2556d628b36dc8254cce2328eef670f242afad67a72be3dc33e7e2d6953e7170a20775ae5e0b6250679f54625f1c4a20519341b3b65469064404689e45094d59c89254ada540faf2fa21d6d0f985a5d2cc3789a4ec45c7fce9838921df5b290607a6bef38eded9022fcf6de758bf5f8735e81fa6fda3b084b300ff4880b58a9753a6eeee2a0149851fa6aca2eddcc6da8a01686e6b801b5201b54281a22eaae94511ae4efcbb31077c61f408eb6f6d3eb5294c3796fcf5a58d7dfdd2c96a0341c3711591c1f22e0b09232717cb195397997b7237fc2617b324bd4b277ffe2b634416123bae28ce64896019b5394cc0c92d78c93850e87be55e1ad7cf941c7812f704b0f43a34ac5f616e525a733f515257ba3d11c6f1b0407efc7cce8d6e2a769cb379269226dc53c64cf9bca78ef67e16ea5454b1d34cc9d5823b653860c782ed9796c78df7f60deec8531669d22d2aca95ed0cec5001310ab5a528c99b101385b4da94c08249ca8158de98e217beffdda8ee11a1b2c3b612e150193eab837d6e027af1d5da077a8074d824293ab092fba50bba9f4e9f11c0bb2350858383533230a1d5a21a8f1e971ca3599fd24933c0f99c94ece6f0f9988a6f75e1a8a5653cdef2e0ea490171c4ca45653dc69de1da9a7788a7a35d5354bb1483623aa73d45462a906ce9277e2f4c0be848ea6b0ab1355521b8607ae9ee7544f12c975434dea27f57a4e08a2c2a9e8c29bb2693181a035b402ab8392364c0fb3f7debe84608e40c70c48f52834e2e60a1a421a77602d399ff39e3b5471dc3f00d0f9cc4cb51d6dc4688d10221b61cecd4c87daa53f636f591e3b6e3d62966254952dd190623ea34fba2373c7944674d6d576b384b462423641cf8674dc588a3df420fd8ff3fe83c163c6647d3ba62b840408085695d115144c02d2a45b5992ce2d848c128e199360dbf0be6390a5ac80da8ac0ee97a587d97bc90423fcea9efb0aa08598141696d9d54c1d10e815a8e66904e9911807bb8652f7718c39bf40aab9a468a8929e808c1812853fab2d24ab6ec54c5892535775bac39a3fbf2dbd22016af58863ad25101836010c312a67170a15ada4d4699621efcb8b25342aeba14d5539eebd8ce9341e392db1295c99d59405a6d4c68e6cac40e036188b39a98202b7d97befbd7717ec147ee1ea7c36766d57e55eccd07214a88c90626f6e6b751fd0d2523346ad94d0686c9d22df0eb0eed4d4a82551ccf4d6ac7ed284e4d884863c7a477b8aa7b352c8c56e4bddd1f75aacaa7dc2f0ea08735e62e23546f9aeb80485e1b5f8dc929f383ee7b3cc33d03291e377b71d48b71fab1ca58965f2aa78f5169b213db6a28e406577cd190578ca66a08b199ed30aaedbcbb935d640a481fbe6bdf7304c2ae74befedb0405f55d62f3248a84cd6c3216a465e54774afbb6def77650f7bed7a2868cadd7e7cfdb753b60efc4064e5f16e25a171fde0a1393f5defb16bba8028e168548c8b2d46aa45ad4189b98a854238cf26640f39a2251996206fbeb1d99fbd449d2e91912955dc27631085b571eacf0edc0facdbbf740b93fb508314788903fd0e616e79c73971c9a1f6ca2f334d74316b2f7de5fa2d7de7b5fa2307ddb5de4e3de9778effd74a7b4f09d2f8a93e56cd113237c6fc90d6b592807859c0bfbd43754ec8dc004398e6111b1b0bbfaa49190c688108902c91bc1ce092bbb1bc91b2bdaf6eafdc5e618945f1d09481b34778c5d0ae3fa95fd8d17e62eb939ef4023e38bb86d1941e3e6ac0449e5b82af3c4ac5f38bfaf1f3903d9105418d24984cfeef25e793b08d84eb4ed6d6c47d4ff5aa2512327ac6e042cb35eb6b960a4f03f61643bf6f3ad2f2e7525e2f2f0f890025022eef735170d898015d21f3c2b805657092b90385eb1690723be297b7f2e5c58ce39e74138ad07a79d162133a37278bd9ddc30503abad4066305d591ec51a6231298aa1c0c56d3a0dc9ce93e8ec604efb404d06eba98da9a944f04a4e17ca92dd95e78bdcda7880a5bbcc2e79c73cee2338d63262bf0fabe904d5fec76815bfa38f027cb4f5c7fce1371ae58c7120a39439e25dff76da586b80e2c77023b555c052e0e0543aa0c1c65ce720095fd701a12857f2a041af5791309afea0d319cadc53930aad57537eba6a41f4b58151e0bb97a65952c0b8342b62536a31ee2d265de84d7eb9c738e65d329ed67c1eed029edeff256a6fd621ecb77ae18c232c70c32f5b1d81d694258d0aeaef64ae408cb35cbf90c94d9c1be6754334e31a07c543415d3422c087ada49c331a2dadcd29d43444b8e12b0152fb6b6c9d08967cec4b202bb392fe12ac2401395c8004a41eadd48ad593b3f7274189351cd183b793d16d6a4455770434cca9a1db5bae03848ce398fe30254a5d91c185d4e348644e17f757caec10fa84e901d9db19e0de552e44e4f8ac4f4e12d4d2ad70e89b468bda39b963dc1c07aa022589a52a1867cc838dbcf9177a8d42c58061a33306c00024000b3180000000018c581304f24b9ec0114800622d094b490443c160c86e260201000840181b01818060000602010148aa1202003e24ec7035858c43c9b23078c0e841479cc1edb97fabd62d206087340e875b53b8293e2cdde11846daee204cc89f26f84a564e6b9b2cd27933ae1c3614ab88180210282dad91d6ec3a15262ee2913176faa732154ca03bcffcd4d47eb01abe601a7fc86b1a4def25094d2e8c293c5dcece0e4f9319f80b9b8d7f24b21cc9a73dc5cc6534b37ea5c3bf0ec13773144dc484b3523027b8d9b7546b1a212429323a270c47e39b9208a8cd526b204428ccbc9b392b87bd1453ba68753325d9c9e9c3ff9c378bb4c8d5ea764caaaa819a754a411e9831e14b7ab5a8d21d0310eb116372d9281573fd089408a7347a297a75f6fe9970da1462e7f37987d4e4e371ec129c3d29025257f4dd25d19e83a913f2002fdbefeab9f30880dfc58ae948f1e8bad416739461c335f6a37ecb15cb0217402b1145855d7ceed33120dacc63f647659e232f64b53c4805f288f12d573a01f85caec47124963f02dce1dfe7f79492404d7c28364bf1deb5416717f9ba418400ea8ac05844ead3dc329ea09afabada1c18db1d33a04c5da5548d7bd6c99a7498b18cf078fe93eaf14d3aca40f66c0a0d208a35d2c173de4fce52201880717114752ccf4a86e17b6d345c89732c73eb5aea3ea9a12c6a0e1d460d0f146473c39ce2c1db47be6332ffc242512e010a687a635c88976739230543824288f293bf39acdb4983cfb3eac8146219e2242d251e3920306bd64821e694212fcadc7852634a8a3969ebabe063de1e037c748a4a66e6785c01490b77342ebc8e61ce723a49357a70afe854a77f74287e11293a24779a21ca017b9173af0192cf8557ca366b8fb7051622721d21fe19d9ab1002b2f4ae54a48ce24dc88475124d1840dd96753c346a54722b9983131b406d08d3fb7111c32482de26029273dd86a65a95c321abcc7fe449b94537ba348c667cd413e84bb01e316361ead2ad89d061c070f45f7f189737734510d339ad2ebd16b6c7fdcc7d52dbe44e95a78874506245ab5ea5c585a1ea874713a04a7e78d60b75bac9f87a86050a655ccb74f04f594371e991dde81907dbda333de88fe79a2cac4a86de4c93f60abdc4198abae2eaa4c5889ad5e7c4213a8c450138e68698991008ec8a3f2123b004580025148210d61fb7a9f95a589fa238b2579ed65334b98492213106b3e431538a51982eef95b2717815431fc5913f5f0959918f75a9a53bf5262cd4956c1c3889948c1d393c83b93488432e949350f67185fe92e487e81f87c872e542c29d40e3975c5fed682723e5541747683c2ba248a9097028ae96d2f40e101873e96149e8b4ab172ce4c22846a802ae932db75bb425526d071c71f3d3cdf16d694204740468ab2dac1c6fe10367433260bd4e726808947d926762dcf7a512748b1d0ac1e42a463bdd51007995df01c285ac8a21756d483a301d41a34d55186c78555cc7afd03e978274d7737d46133d5685c841da5a87675307848e10701823fa5b2ec5c56a6388578c0e83d414eb82e5f86b44b908a532474e5052d9b06a6d9fc6b5a56c9a5dfda3e8a5438b3b220cf6e4ba3c1bfca38e9481bae1af8ef9fd5ad7f77773918924e12a7a97b354b31fb70116973d6a6a3e5d69247322e8f68dfa1a225ee314fd8b4e839668c037bdf35f7cf1d4cd0bbf4b08597ffc69b8eb4ecfc52e605f34902886a50905f7c37bcb1cdbc20d3afa4173895391c26e7c7e18bc6e849eee6c4c6784cf549474ec7c844452d13440d03141eeecd71ad94e18bd38a93cc67989afbddb0b637c81d0a45b2a21f77e79e81a1f4488ad2fc1ee23f69982ebdc75220ff84d59cf1ef3f333dd314953b5d5aacb5292ce2a32e458e52f7e79151e4d24ed893530b74d8d45537105d35a373a2ab2de9d05f778b8c274291f905f44d0ce1a4802017eaaf195b29031636ec19c0e48761a70618f1504c81808526d58cd71b1a32d2c59533611f5205cce3696067c8f1ef42284625b0d7012d6f0db4961bacb1a7e6cc67ac928269bdcec1461bdd7d5a725233512b97c610b8f6ec1c1b9fe9a69db70be9f5d8e41db85f822dad78600641da7df0983b7aae49cb953e0a788fae5e4040e00483e61c9649c1fa036a2fcf85d0d5ae61584051c212c185575b4772dd8298d1da6cc854acf7be62405525d231c6e38d900cc7f2c317f3650b0a3a0c28f1be91249fe2466bce88eb23311fe628d234fff0f781f5aeea42e1003eefd49428259f4977828785590769f7f34365b497d500a4f86167177d395b980e1e0e141352907b38ed87dec68123b53bad692a957e64bf638b136167a31169c16bcc4c2e44facb80f091355c8e99819e25559c8ff225a11139811db90ae668d26892a761a18211fdcce3909a8d48e17665039ed0c605d7bdf0910a93baf56c796b12159bdbfd10789bb2044ba0f8da338edbf5b0c5e555884dbb8350ca5f406a5b493069c06eb9916ad165d272dc650d6f0c9682eb9dc6c71162d4c52f44a99fae2c7574c8d0518da5cfa11934a509055e4124cebc3d5aa59da3738c457c0df1c917efbc6aea09392fe23bc60fb4ccef82853e1d867c257a0edac2926404428a30d303b2311f80f09108f3c409d0d890c0e9cf03f7d1d42f351eeb3964c7c250fa959e9ad9504aa7bbd6b0cac51ddc4e74bacabc1e0c413d434832771c84ee18880050b440a2873542a9fc6a980e99d2d010bbb09e3d0135a07ce1c21704aee07bdde9bb96908e1afdc7fdb044cd9d0e7c328f898402eb8336afb8a6b8ced0bca35b6acf1ca73a3bdb14f752bbbac56511e4e1033c151101e1352e40a6f0979a5598639f0a3d2adfaf33feae1125042c62a72a746019b4734f7596e86cbec036f30d1cfbec05488462f6beea1011b3701725720d0f99fa8f639a5c3f249117720e999c12d7665c8548daa3c4d23c21dcf2629c42440363e4b90ca5a0b56c34617b65208c233f470b4d83e193763e7e8fcf5d9af35346cc70649dc3e0b16cb4df6053b36a401fb4dc1065a08fd89191ac695601fd6e221a2705a313ad12ab3ccfee0e159bf4baebe3cd2f04442a620dc0a3a86622d451053155bbad8e85b7dc567bd7fc43b02640d6a8c61d9825605fdec165fbd758af772b7f4a2b1acc5cbd9425be623ed865a7c02c301c634d75f22e326031aad4bbafc6c60aaa0c37e9c17659e525624a227be153af2b1ece5db3e3dc34b3118dafd1ebfe41e34ae2d5d30a11230c0b2b2ba677fefe762dace21272c1bb5b6974d1d4286f44303dedc8c38592474941293b927d9ab76874bff14b86295b88e1a1252c2cbc79c95bec694255a0ad7d1b02e1a4a29d3ee759139e428f9ea596688b7e9fbcfecf662fdd0ea39ed944d566e465c855fd14928b722f23c3cc4c9e4c4aff15bc3f25e0c14b50c17eb66f34020845c482657b0f3914b13cb4ff65da43b33904047ea96c8f9414fadd29e47949eb48aa22deec93a8140200b410070ab927b1e31d8936a2b8ca3a9ab7e1facbbad60839fed9f85723a08b75edd85a287cb04938a6331de85568031aafbeea82a1265f64bc13525620f72086757b9757125287c98b1c1b8a6c04b0855cc0205c9ef90cf62c0af959428eac2042d1c0c3f1db7efbdcc7f0480ac57ee390e7a280d08c647c8814de4e27873dc243d1640ce7684193cb70c426cdc37945373efdc2bdeac5a48b8ca38c6ea59c076040359989c09ded8fddc77fd90ffe5ff3ee0d42528a40779b29461f70197d74e93508fef7c3e8f6673728a1021b1122a65111e388e9b803aab50d15c26294aaeeb5278911ad8de43f4e8eaeeec451ecacded34ad172f94e488e6b0cb6719fc96efaa35b152c53b8fcf38452dc1f9d73b30f6a81490ca3c4748b582e4c9fc92dda845e9cde2a14bfb92cc225903293559834469e5c8ae064564f9988e3edb43e3ca7e6628a31adac589e74ea1ed4ba7ba6ec3d4e9acd9a2c4654eb9bd145fbc2824a39774ceac608505bacf821648a64859e8e1661751fd34b34adb472dd63e3085414d5457ca3f33ec46bcc534b65ce6556b258387fe11a4acf6190fb535543625283f11bdf3dd1426cb77c20d44d9c16f94d15f59686d28124f7c6defef2a8b507b2041b6d4ae37575e4ccc08670bcd515acf55f21a441473d1ab98f1c4df6637c4d9679be5b5a3a7a93db416130795e0349d98720093c7476463cbcd84ac943c88e2400e678235f6ff1e29fd385dbbdeb2dc4e797ba28b1f354c0c3a256943408dfd949997854aab8cd5f7f96feda2f300023ff74df51270db139ba7999851126ebe1edfe7651ecf97fbd79f945dd815f891736e400daff990b1456a7034065a286dee216b5a96c27b61b03ed43cc7621299fd0e79cf31d45e78150b2219f037e845ec2045f762a9f25e9f8ca583f9e679743ed1348ec0385676fce91842736302570a360d206cb7a5063611ad2e441809c4e0a39290394e46cb8d41390365d52ef46e1c27f22dbccf92738b8419d134d4796045618a3202aeb24ed4e052412b67629915f916ebb7caeff0c821ace328b8eda47b42e0825d24f72bca45a5742366255e233fdb5444301846a0193a90dcb0ce089819a6d001741438373ebb2aeb20320a1daf5a19c6d126be4dd25e40c410a17b21a1728ca143e0f6372c673f7dc4ded8f81dcfb23d26b67d72fa1fbfdd719251fe12d511f41e8d0bc6287e07f67ba47005118c27ae6788410d8510b4a8834cf17c6d0731159397e0c8db287d6ce9e9c61953063b20e69252f532461583b8f9a27bfe9d009dc1f1dd275db212986c5cb0b4e683bf6e215063912c214bf341ebd1a236af3219e825547e143aa5bf38d3a4aaa37444b48046886497644da04e72e1dc37ad84c6e68f84c7d5930e911c4807f421da1562073cc74bfc9c527bf5730361d74758e21f96ed8a76a2e028815c2d97cdf8037bafbacd9e6a75642b558b8789a86c17b99a9c1028c4afaf95a5dcc457814c2044185f6545c41dd140d6058ccc10707d6861a9b9726aef044c60251d00bb2626925de1eee41d68f88542e2fcb55564f844051c9fefe50372544231c37fa2e6ecbbb63f6baafeb59e312a2dcb507d462d1369596ed022d6f2ab196756114fd08a2242c01210236a25d090083d74805f325a21f1293d402873411a1df7219285c3bbf3eb7b5316650d8de128f2dd318a9e4b8fe8de4448e1d3a34bce19d4294aca221898f96c479ed5224b756744c47da517213c68dc1d9fa2404f38a0cca0d6f420b8c074bd7e8cb850611e7c234aa6f7ce509a49c7cb3a31742a77080b6973a37bb28b0a9f084b88b33a4b25868bb8166bedd72ef2a028672e9e57816db92535d456341701028dc12c8985ca844b9b3984a3e12bb9612065c59e0113f81b90b920c65ad2873e010f8c692ffbaf5ac0f49be668cdd4e7b4a5820add259ec16f9ef2d070b5842e15cd30e44dbd594110773099688c3ebe0e0dbfd6d01a348009121c1757a5e9f38c9414130e5a81d3d27070bbce8976a037799640e8507617eec3942bad16ee63906caa364e3de7d8c87e6b999374483a8f9a48631cebc6d798b292e8b910539321c659c62b565007af03f5c13182f5d0ce010a9a5faf2ece17c05936b4644dccc5a3c5ba06a3381941bbe18be5af3d876ff267027d39779000bc28b454ff3505a31862122f2fd42ca2a508f35a35c13162d20973157e32b32df1bd6050462cb3b77524189ebd82c3257b53cb1610ee46f91f29bd100ef92c5b9876b60f330eb3c1631ae8dcc690ab4f442b8b00cd0f643e5c5d0c5fd253b81e6a762ab53a07e95539803114cd9393f7ab9e4fcd80bc274d6bfe3da1a23780bc7b75f375f8e31ba27ef12f61beb47dc86d86760008a6086b497b7f1c051194799385c3b801051625de35e52115d2fff0dbb840ee1f83d75d19f83417cb0b9cc35b289bba44e5dfd7fb45737c01adbaa3309890b8cf5d1f34ed913f91d6e6c71918930242ec16aa43091e8baf92b1b6d616296a8d32567b3454219874e34eeae70fc4127a19c9223332e3aaad1716601008996c6a3b4aeb9fa21deae2060453b4ac8c0fa769e008058e68c7f8fb7cccb9fe123cf80beea095aec37a3cc34a537478df8530cd775a26f1e99260bb48522ae174e8a002ed86f549b82c16db27c77d94bc7c78ddd00fcd5f91334d52c14d654168b3c4f5091f852c05d63e3bfd49a8441c4095f56aee20782ea8f354294863984055d4c24c6f25344d89bd71d023616649988f3d624c711bba0fce983c64d95b40bbd43c434020d2ae176154d36dce819dca532cc323224fec359d693a8b746ce690bb5c7d680846c02be9e1669196a755965a0b9d7459800b8e10991acbc0909c586e2a73e5e464a5d16f4b86f94d9be566d8d29396dc2ae4e8e08a25eb303d47cc17a09681ee2ff6af48c1f648792534de579928e586b013f881721d70221897b0ca5b045bfa6fc407ad5182136d7e5fc80105874f3e099f741ccd7574511704a4a5bfa28f4bfa82740af1ede4bb60975dc5c74c283f6ce147bc40a6677a59eaf26eb5725bd1fb95e13a3cf139a7cdfd223d1a629a2758712707b37e0f94343dcae0af18f88e39f38fae5ddc880300144ce4d423bdf4512d3f724720cdcf835bf50ad69a67aa072a934661ea05f979e7eea64538c547d29d081ef987bb9f2c6062c5268d6a1651503423dc8459ed103724f012d06249bb0874fd08bcd22fcea9b1b6acc5d3982e935309bc3b8db84b9d338091166ac2cb580984e1c06d69be5c6081e01340a110255c6072072fb5116152dc82375862c304870c228a994f1632fd0f4007cf987370cde31d9fd2c35e14212313a75389eebc91f4b77e91a26d4b4e3219900ffde6f1f9669b06aa7430481249ce5b34e766a8d0e91abf8dff4f24609bdd1e67e6233539967606dba19014a8bcfb902ae68c8504840e9ddb853c630e0a9ac532be93a037f07348fee74fef523f75fe2ea9ea0bd981436e12f061c8b69e9fe83a0ea817ef05cc40e8aee59902b011c89b100e15ec1346316f1dc3824c0895f7479374b3db5c99265b96834b80e216dca367cef81eebe5e33b0e2dda7f8326e1daa62890cdd0dd996e20458b7bc545a5f1383036450152ecf0ff8809638c8a8f97c5aefe2a42253a29646922a5882141dfbaf454a1af4699fda2d25f97f1110d5e7c3225fdea42e8f13cdca61402f964fd9ac899495c75ff716238f2064763c8555d304ec0deb503509c7a215133cb9ae600deb78e2296224d25d60a2ba3be3bb307fa723feac8ff8e24a980c0f10d86372b1821114936178729ee5ed682cec2ab4d18fcf2d9723158f4c100146f75fc1634779cf48efe28479d4810155c175149507900832c7e823856f5dcc4308e81b9aa7d7c363aa2de518591d618c57ecb2f58a3d863b83a48689380792dddb0d64a5cc2c6ae0887e692c17f1dd1580c5611c524663ebe29d517a1d46b013f6d83f4a15dc14573aee45ac0c445b4f9846645e1622788a5402fe4c1f1e278426c57793c0689b1b26e142b88ee8f6b7d5026d2080b612d6101e85e37e5e787b424b5b775d9a7c15c9c90cb8d3f49d73412821076871351fd06c28f55cdd19e2f43da8f4039ea3f43937b7c031ea51a131ea8b76b628e4df439aeb976d485ce79d975fd07a37b428622968e3bf952181fdeb6196a0efc65fad11b123d123c93205f5837fa7277180a0d699c26729874c26ce2e86f16e67a84b4744e3528253c465b0be10eaa72a20b16e7e833a592389ecbc9fa78cf2d6fbc051224f18bdeb759f7ce75c29a1f844967fb3b8749df16b5e9aece5f6a4b539f7c21161cd08785c2b33ca8de7190b3f5169ba9e87a0a95fe44c1101774ea695cb9edd7a73b86e891dacb420d90a3f9917ad116772824c4a751599ce11aa19a6e2023ae2b007acf36f9554923f70223cb656ab151d6d802d2403a40810c1906a38328fe5e0524f1291ad06d6ab3f6fdfb4cbfb231fc6d193db4a467cf54a1f70b5d904c44e66ef5949e9153c92ff6f8bab755f5d7acd7f8e4546a1211f1526c0d1014b70e0a04270e62ec1d6f99b1114ad97be1822ac915dd088d67af35ba63575c2189fd82749a4e0e7c554f1c09cbf4241201c091d1b4ca5204e5f7460451e7e87cebb23852ec5e9d573f35f50e5704b18064e98e0f503ecda2aaea3a532c18d7830f493a25036f0aa8044a2b07e5096b1ab4af28531170f8cb2894907204fc987684d30a4674b258acf7182f0d03b2374b166cafd1a215567d73cad2d50c45a1e43af2a38da3907f933fa49491260ccd7271737ea43f135a4b3538e628c9f0eca1b851eafeeedaec0fa32c6e2afd9bd926b444014442c2b2d139ac793d36a217ca0cfd8cd8361d4e1722c9b62d02ec262ba4f6445846cf5a83646fe4925699b349cc3bad6e029863a4fad316ee51e799f128848712f1241a4b549298401dbde5ba281961ecbb823538e57cc1218e8a77c14baacfcf7d308454396c72e2bb6b306dd9ff862b73e20f10a16eb277aaf2fbb8420b3b4cd0c072425fe3ca6d4437e029e919940f309918314906a7c2460dd4b22a12c90a1da8990c53751d6990c05becf1871215d142d81d562a1ad49ea8f6bf9bb97b7d83cd62c4c374aea242db82b8cfc8b9fc411e3fc129dadfd5c1dce2e9246ca485f5a735d09261e0324592a2df8f50bee76d7b1419df8a4d36ae5b2244d051684624ca1738b76f8d6390a84f18bc78f217733c9b10d1141b240f898a31f5c3a30e5c9424fa3bc180f96afa73124ad7833341623710e6bdc6f6d5c3223a3a8857f92a67dae7782aebfb07b0a311981e8cb62e1e3b9ff3e6721a63289f3209e0ae21a8b4d68515e0c57303fb729d32ba6ed4dd15b85645e97f82b214a508ee650959a9655d95517ba8d7b1cbbd4b3bafb82b06bb0b5686a7f0b0dce12003e8471555e64a69a988807862c8c1356c418868798db09e1046e21bd7320beb9c4180b660655dc29cfefd3a688892fea6e022e83420597289efcdeccb8501151e759bf2158e6994c4c871221b592ea7a0b6890f790fa9d9e699e8eac5883ea8244284fb9b2077c34512e8c653711fcc343a99c3f5213c4d65e718e8ce5e22532403bf13f80d960526cae9a334b6cf56a367ddf5c2ec98942ddcfd1e21670585338498dc4a407a8ee1b8e59c9d96ef0c2881f2eb89a57df0012d7ca3c8c1b211c4c75e29a0599133512bb8216efe8314ff69e3c2abf574af9b30f16f59ff77364d77566d59cf78f5abd91fc395dab6d5eb55d79884a71520dcc37f40717bb6844ff9406355fcb76cbe5da957d5ce75a954a6484a5177c66bdb69255c200af9ea2a591369cff33f00afc3572b09892fbec3aed15503bbc50aa5e22783847f965e7a37350e196b1aabc4207b4f1681fead4859c6422b134d2467a7fb017d17ce7edb26835a278280594b19fcf5e0ab3cc3e4ff941ea7bd0258ad9e38ac553b2d79652afbc787b9ea7c8305ce78273b2f7fd616c543b22b611b4ed8c3d1efb3e814f2ade8345c7a50348a60225216d7384ce1c50ead372d0accc4c3630352bdb3df07cdae3417582c426191783beb35ce4ae8cf3b6e6aa12267d102656e8e8cc88a3492980088f58e196704a2eae0c4906fc368e04a3a0968112dc62d20e5823525d8c1586ec682e11133ec1facf1d8fb51160a2354c4b751b3bf398bacffc46c6b0b51a9a5d6603a9fe2346312bb125f792d3c81d283376c8c46f7b56260147669a7be388ef1d69a10afeeaeed19b4e6c8e916bf0fdd388140485b15b5a87305181fd249150f79fbffd902d7725e1892baf6aea07220c25766c73a9d47b5129e9b2d6ba1a319979a56a3463144b88a0aae9fa78506d83ecbcc7fc4a5fada8f5daa53a77e9e4f61ebd81b5d4615f9093d7898358c5be249258f68972cc50cd7fa651689d740a3b52e59e20185f0a9ba30c6a7f337d1ffd3606ecba888d52f4289473eb2a596b9b65356eda15682c55dd02f6b46e3b5297ac22138a480bfa577cce7c4a24dc56959cf8f26e10f131f1accbd77a0f93097ea6fcd12c92944ef68b271ca3eb6e4057d6c4cfb20122c26303bb6bf2ea86894451154e51f005433afe150cad05b46b642a0509b5fd04f5886a8a12464d828283b22ccf169a2be918c16385e519daf8f28da3ea179b688508b07c08bf9dd3f52ee5403e86205054efa36774f1f62f5f2ea96852aeeab43c8191d1c5576692050355c9bf04293e3ac6cd65cd09adc497f654e44bca0ad03f7fd10842c2a2b6f6e9b79b495deba6adb25d3db8aa8ba20cc712b3ae2648fedbf9b955402ece3cd0beef35a2fb03109f5788560239126d1888b5e6917378b6455ce7dc7d15ef0cfdb455bb808553b4b1b910d94b15c15a08f463e2866e38e0bb5daa6c36a3ea7d2f749dcb2862079e43e097285d6ce6276855fc391d707a645fb8b35cfbe6dfc56bc8b5e78ae81cb70544410d91fb587a17e0bf2173555001f17a86122a065efe9e714e3cf40fb630ac631835b4124da87c2cc215957d55c83d9ce39caf36e805d76ad2dafc32202b068ad16d342bda440725f4af9ae4a9a0c16d263bc3b8a61370ba21a252d5629349f0dc2d4131eb8a2dfcc2da6de908dfeb9f93caae378edbc6c351f3f4e0807f9e90323505b52f1c16d1a85715d604d83ddfb40d0e1bd82af771aaf6d21400c5165de9f65b9c3436fbcad2280ccaa8853fcd5fb39c2c21c2d746a86e004b14f81f55161ab806e6148ecc7f2cd734ca370f787eaa4ba5037cb9e058d5c653b67ffb4e5741b5fb2878ddfa09597d6d500f13e7a7b936f4822f6dfe9d392218eb41e7656fe687a1e2ec43af028e37f776ef3c14760f7318d7f49c5631ddeace65c67094bf93ac5fd3c4668d2104ca1b5ce55e5681af770cd6cc59113891d171297c3c8256348a63638cf062085cf2bb2d1d67b66e55daf1f991242649e4983e2c2191745d56c89bafbb4d03c0333fd170ca1029b1edf922a54f192eb71ae131cbd02e9a22c20d22be82b38184cbc17e209a6992d302a5702525d301b8eb95085c82147ddaef0f9e1944862683781b43bbe8b48dc3c40a1ce58a2f007bcbb8ff9ac63fbf65759a252b5b961405ab85635941fbf5f6f2c2ed5ea60bade4f3e82ea15e172f0d9363c4736ea43878a66ce80ed482c2ed701ecfc33bfea0a7e83c55aab44115925c9a3277e1d94f4cd7b81d6826815c4e5d75df62e54ac283097a25a7ffc3e386efdc6942aa0bfe399768f80b8504c87c39fdecc0c95ce073ee61ddfa423972eda0f8bb8b82ff4860a172b95d6af98deb008f8b4b13608291cdf7e68b83e9d58cb8e28017053e44b47878e00263ba643f5f79f833792ce9d53458fa83195498ffae8debe9406428cb4503ca36764f68c515eccaf4d281bf2ac409134595bba68262dc56b524d64f5d60a1790375c858e00e2a26704843c06907266e7dde430d710856f3d8af1350b84118ecb4fe18a3d8516f126bbca83570a38320c2dab41f6ab276b78e9c39b6cd2e24ad0e1b64b33bab231d1e2715015b0835fd4a0220b13dfcdd6e17252da5689b68e561a1a00714e396f5c0309a4b5314cf56fc1f145f2bde6cf4b185e2c7789036fbfbd44d28d56036b40ade1c00e46de3cffc0788622d8fc1069a0fd0189a1dee32e903af157de30d0d5cc144954fc141557cdf08bf3f8bb8b934c7bc23e47a262264798a209853e0f28f61aef29aeefe053a50d1ee926e4ecb5a0a29b9a6d091c5756ea71e215def746b37a7de40d7a7be383d6520cfee4c1afad4bd728e1d11caa4666892040c955bfb4e396265217d216b64fcab6bd52cafb6c91176a2eac4e08b9a74b2e6e3e4e29039191fbc1cd821118bc0d79307a8d1b9c9b642261cc5cde120f900b48d78928b811d143d1aa9fdf7cbaa6b1182772cfaa84210e78504c83f10f06db235cea0d9c37641795fe923dbdcaca29cbf45c72eb2ede750a0c377586d33cc615b997b010691de433a6cc9874afa1285b9003ac9c29a847b88bddb77882033497cb46cd1152819750064be35e99088991ec8d878cf2274ae63cc38b6d5a4f77773839242ff33b10c0de31c6364965025924a76a59e76ba04367625fa18fa1a7669010675dc085b4304d2b3acf5278a2800b5287fb2581f21eed6cec30f86a53e3019ec79d808681a203467969d635366362e28daf90ce1ce0cec111174762287d9a9191cee155075ba092e4a754082c9a068a1aa1dc18c387880f2a7679958dbbe9ef1dde896af926e8d397b593beca87b84b3d2b01e41aff25a93578f32b8ee3f42946f4447759377c7585b6650cf478c7e1e65025bc6f6204bc4be4c70e7a5b8393726dd9af4664e1726de59b63cee1bb0ae77f1df0126eb86db3236d5fa0367c5904003a85fb4099ff1255cecb225847d99515e018a0b11c686d47501803410c5303ae7eb997e8b1f50327290b0c68b80daf505302dc51f23ccba753584c057d0a2fa438ac6263f81b0f1e58b15e8eee3f801411a4ad3a8d99da96caf2539dbf8a8ae3ca86844841c7e8a7a729cc11b9f134270f822ae0145e5a9b61ba5bed135bb734b3843489c3c01babee02b53704c6d750a891cc14a00ab4d20818b0ef3a678acbfff9b6402bb43925b60a8045a4ebb80728a024c74d41d1dd10f2e590379a1646d38681f0d38537fc1559ee9f5b7d75fff7367cb0cf342aefdbda54c5bdbeeae02b102a602631f03ccf2b047a32e52c4d49891caec3690d679138bc9c2d4206bcea06443683d262f28c197967ef4eef6eee39cf323fc724ec5cbe8a8b22c0c4ca5018c90197cd070b900b92456c2a1bcffb15e1f24cf07df995c602a39e71c4d02688c0639aedd4f2732e39562c6ff3f302bd2c2ec5123d030b85e3c00a7f08a89b7837457270c26cc3caac8b9c7200b203f6164be7f5e4c1d861593f190f0db38ab785ce0a962c14e8c93c0507b90a45362535d59353dc578ce6c0a2daae4270b4a87c516e32f08f1dadfe937c39c731e2223845f8d1326375a6ed52a1c19ea3f65be3c4078d25d2da55529e17657ab7d6fb0adde1a0425208304a1fcfdff23f642b248188e3bfeff89942e879609d3b3b4832a4098021f9de81ac147ef17f43a20250978991d92e83903d846f08c8eff7d4929a9a8db5c4dd309cea23213abd70a0b18096cda6eeea703d8116c4a868269b56a9c96c22264d20e8b0831fb7fcf957befdd8367678497520c51ec8dfea0a8488e489362a5db2c6efeff41422065b8afa9e0adb42509026e18d82417482d37695d2b0238abae488206414df6972b420d03ce7c44d50837f71176abc898abf324e39e4c8ba91877e66737a2534b9518e026551003f4e682006a8375486597462b9505736466cda1807b9ea501a1526470408a653375136335b6bd3442da8a3e33988ea32e90a270603c2da75278d02917df07a63915501332335b2ebbebff39330656de8da4d4b11b9d39f7c12253c92e5b255f9d362406fbcf97301f06610ddb11b0fee771614faa05c5154d43ed8011160057b9ac1139aff96d619aebbac19b1bfedc0d77d81a5a772455e6dbf6b4bcbe2a6bed14305da535e8ada58db9c839cf2c0651296eab16479a27a2e394ee02a1528e6ea884d3b852343b3757caf4056649a0bae28a5b42eb921f64705e48b8c991b9d848f9ac69d8d50e2244dd44013d7eb8c60d1e937d7379cb1b25852775dc1c5ab8cb2e4e5f62ffc9a3e13abd5cd710962dd91e1b172161179677cdc91f4438357768b513a29db597026adbb04bc18b2e0a990253938bb62598504a9bd3585cd0d9f3cea0ad36b7045357022b2d82629ccd0bd49131d984eb356300d332a8639286587bd931f250b5ba0941f4422b1a7492e0396b365aec7601ba89cd63237edd3c0d919ce4eef5ffd4327efdc5ea7f5e3bf254fb3c7bbdcb33bd5d86884df29fb77b513b4b3515da2d2c1c3b800259da9c1253b36a9a8052cf94191c160a94c6e25c38f3b80267b69be9da93fbe64eddb53b22ac81f3be7a7fae6b120437dda4348737276398827c9a50485b505891027405339a618ad2871535e0dae4c67b0b83d4a885b7398c9c736ec3b1e30acd9cd783e569efbcb318122e2a009d604193d9a0a4a322820896f2f5228974addc2921b710422b4968e239136a337351b67b3e3877d654996c30525ce2b6b5c5ebf3d6191d2529ec943a92eab7fd79ed17b147b6a8512f549ed5a96faa984694e716299954c88c2458106d40bace519d9a2460aa2b6fb43ae2c26e31f7aa3b14438ec05802298748ba03c2c398924ceaa6462432db5062df36dae4ab7b8f7bef6d07b324700e6104d45a63557756bdceb5d049cb0f95cd8d2658e6b638fa86303c65e8f144e8624b3215b6db0e5a453956d9a9d5bb779f74de6fd7b9630676cc1d3c85464893b0f7debb70736861e0dc3b67ebbd0c987df9ae6ec8f56057ae91e8bb99e1f206101ae93fc76b55ca9d6eaa20c0b24391d39b29f1f25abf770e0aa24d06dc921db724c9e38e9bd7f8df6761c9f8b6599320103e3374552c410f1d1fcee67e7e740eda708ee8e791453668b35bb02a88ae67170a5aceefcc7a44c3a215e3c5e82806f1d1c96878d0935f508ef946dd90b7b0932116a2ca1549d81237849f71c5064c5a925c68a3abaf123bf49c747bbb17f43ddae7de6282316bf379d326343522a9ee07055275397dfa4260bf004a9da8fbe03fbc3adcdc7a7c180679a18c85bb0e25c737afe2b2e94aa7ac5b8aa3ea78ac82e4445867d0c036dd67d51ebe88258c863669552210c9a49e588848b1761d753981bbf63a5366b0212b88aa1d80e2136292ecd84d856fefbdbbb4f00b4be1af527f07169a41ba6a78c7cb64f5ce65a2df188485d169c3c8390704472202607be06c43da4ca53770fe7a054a169cced0d5d8880f3fc9aa941926124515b4abc89ba233b68bae0e153b92ad63ef59788b8a6f217f1b5b045afc25dfbfecce3d99f6fa6037c4a6588abae8f841d1e90a957d5a417ab17dcfad749131e9ff7fd8e6d0c232fc6d3b5626b26c7d931124b7cd1d26a6e69514509cdcb0a88194cb88da85c00db90052284c6acfdf7018efc97c09d2c4e8e166f595ccff58a6eb24b4dd8c1bb2327c5bf7b982c3d493a7bcc98128230067db8deaee8e0cf09f5ce528c039e7cba3cba145269531c992e984a61216ed52f165c39b4e192ca0943d2352495d50833bce84efbae31acc6813a5d974d471f2a2f2a2b51c0426c828cf80a8506cd586e3efd218ff4814d588f33c0404b3b8a163c05b86a6d18525fcffffc1385a86e5b0be17e96d3bef9d2343fad9ff778f6f7ba2f782a30ac6b193bcaacfd56fbbcd705c064df37ebdf71ec71313387fc811335ba1eca6ed6dec9f560d04e49c4052b65df5e8f832dc86f3fcbc2d1bee37438447b59270d44a6b608758e1de5135aabc2684db39232556d1495501da19508143ca1ab55d5f82bd5f5b36d60d39e276e4339bb38fc0d54fbdc96581e201ceda63fa48acef7f96d900c1126e5803133c2a9ca6404d3e22bcc0c4806a3b4b2295095fa8329479b781945d93c5d7ab17f3dcfeff9fb748ce2990823172e19a6c0cdb3e9ecd030426b9c3f2e009276236c8e158c96601c1b0e2dbeec0fb55ac5539d84664c46b441cdbc4b73615c7dd44ef738fc755d2214a297d5c02c944b1c84c91bf3c7d60b67d2b5e306aa17841daa0b9c0610a7ae8f8a8d2a8e29a4ab56cd450548cc117c4a660c5f0262de9c5c96603949231a74d14943385cf2aec45a94acb38d9654bc2e193a564296e041a463605d6c5e887aa87836ae93db17afa39953111eb96a5170f9e58152157882165558c0dabe285d7042809a47ca3404ddcc54adf9af39e86b016debfaff7de65849e44e66806ce315b57735fa0dafc422fc917f3e4d77b9ac54b0fcd174235fcdf9f3ddeccee316a42089b7120630d10158affcf33808e7bf7ddfc92554a19cfaa27ecb46106a02c2003e07d178c1ebb24e79c2be1d7c739e7f0cb39df00f87a8f7bf7fdff7f07a85486ff7f17503975d692a6305048d0eab28ae500bd4806ffeb2cbc25ef8c31eb1adf1def4224e79c7390a42be7352d880b9273ce39e79cc3af4f8a0feea3c5311cd51ac05855625ed01879a0a0843ce876a0c09630f491ea15c2c0ac3b94e10fc21822d092e5298ae53bbd2237456229595447779d6f652f49dd10c839040abb879c963530a0af0a705558b8c48a315d2d2dbe88924c2f332a199f931da37d41477f88b9a144d81e2d3aba50a4210dcbd3a4fa7fee98b6d8adecbdf71ec35ddef13c03cb79530f3cc3f20c0707c73bb8747368e10c1ad7ffffb2ab0cffffffafd4c40e9cf9de21993c65993d31a97c4ac811632a814269056cafb0f3c980e6a3e98e3b1bce39af456a2c3cf3dcb82739214cda3fe236ab11e0412b1ebb962da2a6f4b561c93f2763ecfbff972e917ce9e19e1001f58cc349a95979765003342581eca1bf76f62696be7dffd4ed9d270067fa27fd14edd691e9516a831584823c60a96684156347abb8611c77304c988dc9a804b097940201c88e00c3180400410441184a134552e4031400030fc078c8843430284028160743812010000a0404a0301800008301e0802018081284e594c46b173f2870a0ebe8d4aa48459fcbdc4c2453f163e33db7746b27c508b3db24c60bebd3a0c067292e776a9daa8aa905c5c3aa4767747005d78c5748dafdf1b42a5bc1f09c4e447cd8a91825ad7db667b3c4b0635a2a3f7450604fd5e091d0ec3974cd414f82ec0cb5b3e6d7a6abe135e9b86cc815b432a16088f84c026648d1a5e3a8c666fe6ffaf868f4acf7073744fa4e5e521c5d2a35282c027291013fae25dcc04602e79e1dfdc5575830a913698a14433c341dfeb74f97465accead1f0b27c327ba5a1159d481ab4c56117a06381df3fde38c961c5cd1356793be885a676c5ca797d1e8698ba8660e73a27ae25e921a23b21512e0b77966e42e48beac2e256bef4aaf0ccea44dec684eea1823749315831f564a5f911079e87d4252dd7d19e9ec1b1153a023cbf4099d0fc43d08280a5603d676943e8701af54f3144f91f83a099513a8688fe700212c66c021470edc9e21a31c71c80699983ca77361a9940445652c12409774b422782c96f7736833a53c874035e487e56c80c44133e36f11f951deb5150696b5856f64c920e4e5be8e70b9188348aa60010466ee4b279aa95e066a5696baf6bbf5e26e1805537fcc126b8583192a0a6bb508c35266075069b33edbf63510d20dbd3b176c8c0b9437fbd34c726424e2712cca6f5cba25174648d928ea2e87ebc28193aa2260df328f9deca8d27f5d4d68d728ccef2d8c258c47259b29776a0f853ca0a93374b3871da223b8568cd7205ef804befb071ee39494eb431a1d583354b4e3056562269af981fdc9fd1ade2bd1773ace3cfde05d1655bbd8d16cf3c082d9b890426acc33a0b79e966d49ec5892081af514f2191646a3caa1d2b18e049b089c27a24cabb93849e10dbfd35c68067d8daf1802be360494f0ba2ccb6df92d6e693b4112c69630c194d5ede448f5b2b33428e648885a12165040239dd20e66f976d1d05bce4e8036b0e9a4fae649ac4013cd42c15c52394dd398133fa22368819844939d0ab9774f48073a65d46e9ff45cdd71d88920be2a125db292aa8648daa01dd52fced148a502be21c21d8d4f3b80fbc9d1dba239ba8588edd81d79179a74e0f9d484e77d255342a524944d0b4975a474985d4da4059d930ccc2cbc6b42233ef9637cb0ed6d41336564d9b36d370d13d0e4504c4283fa339114587dc1d56b6603f104cc118a3885aba1d4429b7bd7c057260f237c06d0c6ca656753f183f5e258944960c527339d9364907318b3a90009c0abd29e26f248b9d7a4bc95e31528c99e1872a87e25e3087319252d3613883e3282f3d81033433e6c5e51b0d3f9d90b822ed31ad6151f790b5d659a2d8b1e9b00e22c8d7778941e4cbe2dde212e54f316b5e5898d42fd5b9e735e14ba4f9bd0019981cebe1ca9349427ebc7d717317210c79d8e1a938e4cb2681175710b10151678a531cce141603cdf9456689030ed4e2cee82280c0791bf627097eab40f52a9c11f38ab8e61b560f873d57b60a9ce050030effe983e2f2c2af1946dc374de64ae68a3b05e628703ab7dd20c987f8280ba8d137c0a03524e1086695c27f42fe163b869882ed6ae888d9cd6060e5347fcc623b4ba9dfa5f93a0c721e6e1895196d707c404b8c42a7d01016ab88b3707dd15084fac8923cf917bc257661a131cc07a7a1f122252a29583c4ed34887ed473fcf6d2b6507cef39c3318f34971dd54eecf0eed4158a556a90bf785531000cfcf4262492c8a7b561b2a8a140c462064a7abc22243836e76f48bc3447031462f5e185218c04e3846d4e3ed0f14cf08b162ca465535fbde9a896f7bb7352df2cc6f0cfeb0c90da386f01f9610cc7efa4961e2247402d2c006d8db8f5cadc2114231f3304f09aba2233272d544a91dc1870e93b2160c068cef002000885a6e55158c4ac58e603b8838f950e83d603dee76d5dda9dec15b75f15a66678d868c719b9c74187816cdc546583b5620ebe4f9a8371bb3d2938384618ad9769bf355edd416f49744616e90f996c44e0165966695c37690cc5a6959cf2f56c559ec468af7a1a1f001c84a655a37866571ae205db5690cc8ad8a7975092200df723171522d20424f0a3ad19beea80f059293f5e9606a5fbbeb1ddb7b787033baaba9b33c0ce87254a76371c1b46dc931a8d0ae0dc324e5536adbaa33476c286a2592f12facc809393a645f08969fed34743fb0c8a3a221109e35040835518535c35b4b4072f2c22e821f05f7e65f915d53b2b84cf62b851506e5c7be48a3c0f16c1691a26a090be284df45f390a1187591d1755abb3108024e9100c42bb1c2c870cc34f0b9afa6d3d2e5912cb6c503a204e0f21f6ad919d6a02647e21472fb92997a551e8a371b1d663b80ee38ceeca188e3f247cc16febed35905d318529d07b1042125bd15d23c1060e5c6bc1356bd3de0e06189af1b1e744873ec8f1a38ead3cc8d16c03f70b23be13dfe18b89ae1c7c839c89fff336027c5e0d1ceeac04b0a70cf77b9a11453f1ae43650da52869fb7ea9a73277bec9917c6b5e75b456aa5868428544ff4953b784f181003c2449d13475d410875b4b30e49f4e44e4699d85f3eb9c6ce50e6b46122322417df25090a3db24f81945b42167a35524a16b2a02589d3a0c89ec3c82ab3f1635711cf364d8a983fe522f87dd4f2164e9850409431e62d868f7b697f316e834ecb7c24fc381a1db93b1c4ec4acaae4b1037b4ff2c1bae84545bd5200b71e39f820804b28c09a834d882bc82fbd421d4eb36b324d943147fead7663e9425f5b9d94b7e4eadaac9e58adf299eb90366b127171951176ce8ff7beadc5ac33da05247c35decd9a3b7df41bbf2d3f9f881d8efdec0e3fb32c47328c870a15a47ba9943c918880786cc6c06d32626a74c8e7c4822e8bd32f3aeae9a9a5075b281d055808e75e3668e90b2b659fce960361e8b8a92e303594421800bf51a9a5b1a9b22c0d4f761f1240923ce009eff3c58c6e18c592fb9f3ee386d99f95be90953ec009cefe0a2190f86ce02175f3cff961d4d288eb0d49423e249b55f233cb1ad1dfccbe020132c33a48665acda12b05c96f1c6c22b62e0a35ed55b3c5353e769c347471a8d6583c4d4a5e46469bd83260198a1c07f0e4f371c5a18cb6a5a79621aa2628acb5a869b25a827e7212e8ab7d29a21e206adc8d6f3e00cea882c7d414161336b29994363889d172235c5dcab0f9248bbb44ba2aae79046684b2882286d64343921a30fabe4b2e41d412ebf057385a905900d41f1291768c2a4e442d998ab503a46eec8e6004915e0f20052fff516541af3f5262ad44126551b5a5d0662dbf07252c28f9419d64ea1463d80c52f8e0dbb09d966e729c9ff697565461f018581a349e9ce1b01a6d2934a08b6b55231770f18edfb0633850734612c168cca46482c2e0b1190e6d836779cbb8aa7c37ae3d730ea4229cf6071b39b4e3a11bbd3182c4b48d1b46a3de9a9d6fd8b2b857459f9a458420bcc6813f26f5ddd69e7b5c59436d4c59552cd8f32cf9de7466a915d83b5bdcfddb0dda527e42209a5253aa688d4da8edde39c19d5cd63ef76123bd095b207f5b5d1bbe6cf4612e3ec2e0e15df880eba411a3da7c60da2d1c43a569d16a54799a51b51a0b5f871b963724c44ad7141cfdf9b4e8dea47dba35b3d33bcd0eed7c99fcfb6a101ee8e5229c24982779f4825200d558281c0d895b6a9abbea1507fc7ff8155f491cdb17b628a11d5e1f5f4c5fc11e49dc7f9b24d3ce5d3bb8449c4985e0eb8edb5e43ab0f17df8c4688c5c26244d4cb46fc72eaaee714c84a1f21a03b82fc29681cd98655e427a3eb77c11853605e8dd4aae3e3bfcae4e244ba8130c84d0d19bc0b0c3f2e127121b240cb0422d9335e01565122dba8bc88c050d74780265932a51ac3a1deb79b9ff6f913f18399b724a3d7f96e244dd552308b9e9a6437b7082b9a7692b48854d22e1ce2206596801ab8c7204546ef0b729b3e41fa61186be82f6313394adbdb1a94a07c15eac1a08551b012c8d0ee91de75aa9d25e91404b50597d5f5f3f04957a69156ca7c980050210a5ac35d10d53ab46f757bbc288f028b80102d6869f28444a464efec060bc0b0432c9cf9353418129467744e72e17406f2e8182d85a4f2e001ff0f905a0fd735c33d8d979f1514138307784fb5053c82aaaf3c958217656220f352628583f2d60d2d39303f0a427c70ac4630aed45c83ee92cd840160214adc7ff80afe7c60e9e88ce49eb925c8a0813e76764d6ecc66adf23642161cd592927677da458c71f27c72eb5848cfcbdc3513d601c7e6259af7b9a4eb6de70d022f5d82ac479d72c73f7cc9e009deb2fee1e2ad2461a43a11224519bea0b338526cd1c931b95c7d7451c576b6a90bee4428b138e2f5bf1f57407e407a694d4f28960e175af2b42ccc0e99bcbd6040b3649d0f1f144051743bea64647c690a8c4e711ad8886df3a288ebd6429d84544d6bb097634ae6e8f6e024d0e692cbdc23c8e17c7bf8d7e434c2dbc01f5e969041c64fa7d99c7a636d75dbf7393dd115dd6b7b741e869cdfd44855a941782954da6cbee4f136c44d9dddaab902bda175aa4653dc48bc96c68bea931316d1c3b9836a196d20052da813fa7286d6632545cf4b15dad823df9af9fc8e1a12d46067153479d4954c73c0c046d62b446358cecb3c9c3ec6de0790588717eb39c4427f13789cf8431f71af0b75c29bc1c18d9f182607b669a036d6cb59d88abbdb0184fc676af77f127b2148e7b5693ed1dedb43bce60a5f1a226123480c9e613661d0631b45047cba33974439fd86f0c6ca70586bf649e00a85542337779875050fd56a407e9e1ce64cc55dd995cc2d08a120b276504a18d1dc4b48db0c3d449c8c4e2dda54ab242584043e0503b5d4645cc963245a17d7b2c7725bcfa8c6a886401e2587c74ec01bf02728a0fb136b4bb2bb4fefe75410672304ed34ec962b6075e12306cdd1ce514266b8c50f91ef0963da2df81365e554e3c172e5b01b9e2d655c7cf665abc328a269263941e057c1a1a64a1984126b0caddfbd8b3f3863f4a5c0f1650108f5e4c58fb8d2ee53ed07b0a72f019297e9edcc79d484c77c79a735067594668477b8e809c825cac7d4de201906c11b1e7e06cab001da9ae4ab62f110f8c63b18a380f9555f15e926a2565f7ddb97061d1b780b5a4bfca389e347b09fe238baff288660973744faae57d02099f86a6af17b44cd44e696d2997cb793cc165c9043c58dda40256f3abf8712d1dcd434c8c0ad141fe8ec72b2c490f429a49d2514dc909c186d3e7f32f98d5be181df19409929f7fab034ae46e19a92c82274861e7e8b3f3e6f6e6eb8d1f528a79cdd5c034dd495df29fd7946da2d36438130e7a4493200325630cd2ed9964bbc90bd2839c58027e50c337112670d702f19fba25053ad5b87fc1c8ef6d49615c96d8ad1903e8598ae8662cb371aea19551c483faf3bf2ab795d32dda391bfbd1f94e6713bdd5d3c3f60eadbe537130ba8340c8434c2f19b1d00e8d8bb90eaa8ffe4990d45e5b64b12c9120c6ece391034d351e1b8fd98d14f066f4b303a4568d263e3077098e75cb55281bfe1e8f80697835c215b89fe526e0667e782b605ab8acb8db4c2b0b5e0424556e048c3ddf41fe90286b64d14c9d050e85accf965c701587277cdc2e9260fe4dc3d70685f10ad7eb2598ac7e605ab409f1ddba0a44649cad31719114e7313ca980f2c10230e60767de14aa512361a9b9b661fa443fd2017a66d1e379179e68961048152d3fbdbe1218d921089a6dbe3914128954e8f6f71371740513659df55c4ad6b972e60e6d55876497a6f89d665490a0281a474e68e47d9ebd164520c5d2dc84de396b4026c8599947cde859f523605b4770570225c721b17e798218a22c84caa07f6a532f6501a82230c6d5778888cd672b74b48790516613016f0c2392b93f95a25954254997dfb908bb13ba69e6e9a579f1c9454274b201220565be09a360dc4db59c88d113e51f350c91dc04f3b6a97a4bd86235424c086cb7a68cf89d73f536454ed8481208574f41152492cf3132ef1b15c51c730d88a8cebc6d1bde8782212cc463c3064bd68cc3f96c23c3fbf172f25394d3caf705a1a3ffba1d87bb1b4f8e763cfaefc9a12e83118d03d0999907349b355ab27d2224de4df0c6b58dd861d3f73365f574e0f3ab4ce1c2c831228b268d2be0928d462c404d37dd28dd9ffd46a534e9b0bd198ec8a7cf28ca0dd099ee375a1373e2cd1d3f3f6823c43e24f4ff0723044395ab3e6412170ee55c69c4f1262482fab6591b70cf6ba9b2edf76c179cfc1e98edd840741e2cf81772b9140158af623b5e0386012f8ea4c87d82413100a03f651f1d55bc312184c0e2a8da580f989f00f3a4c1e0c04f66c3011d3827e586ab6cdc7d07caa57388fc54bb6eb0f64fb43d1293ff22c69193c71534e33939e39afe1d2298fd9e2dd760854c61f216258c418a6cbb61483d5e5cd5e764d91fd7fc61dc242f29ea468c23fe757c7a40c474ddda1904851b67bcf23b89f1e9a320f24c7a6397d7716a5dd4d980008e2bf981c977aa1ecad567e1730a2e490885926b5cc2fcfa24627976c3c7eb5b9441c69ce6de8d43e00995180790cd4fa6181ccb7cb92d0d1d3320a18562b4e14722b86777e9311ae100d7e42028921e77cbfdfc5768440abb41d82b443db90eb985a650c644ea4753eb2519607e8414fbd2216c1e0c83412b49dd0cb349c21e60e26d8017b5647aa424ad3adf01e63652478ea71b692cac5e969335b793373922ebfa5e9078138a8c8bedcf8560ee00dc15634e812c7e32b193a811d11574e0906313d82cde8a0f7048431f99212a6df3e1c06bbf391227165f4f9b9a405f8fc744c167d3879c31c20f766392da0e974e5a3fa87e51ac9844ff4637e2b3fededb431aa90b5a6697c881d8f6d1d69c3dbe7c5015125bbba599153c6ad268c5ea636058d2badc46cdc806aaf0d80ee7c39fc6f5cd181a70368a6763d1d393b45a5f68499e5948eba2ec5d9f512a454c1dfe3ced03a225635a64658d77d6bc3323a39ad663e3237c4419634a84d4b6382c62ce6bdd0b8e258eea40bf4944720f8d6bdc40ce6f3d13856ac4bba586c7576d82e9109bb0e218502989c6189ffa93e6b8494a929f1911a26145e2667c972252edb11a42300f5f8c6ed8845c441f7bc76486a5db38bbe39b7ab100ba66f5101e4f5b3bd9a673d90bf7666c53cb7b06526dab0355907210d5834a94774b2c2faea8c11c620e199c13a91ddfd4b0bf8295a7e90a1f2eb32c5853576c720d4cd1dbb48ee6969eb0bb794548ce17165a347c2b165ce7f0a825f1b3112d1e31949d83b692b8acc6fa8d2fbda961930588a00865b705a4cf0c78af6a098980c5619b77270d0b4678f1bea97350f2c6386ebee23c8b866cc94f33697290f41cfae3a758739a322511f08d3770f778f8b45e9c0b4692efd5d38afc4a82b70a8f7b6936336ed6d7b1d54aad82b18af7cb2c4abcab9a6cd9728c63e34324cbf92c89af895061d664f1e226f1629c5edd2309e3747f03b4e490f572c953f561c465d98634d9e64a4277fc2dff28b6cb484802b54c8b2e27b631ad0de9f846056c9ce00211297106380e3f2ef3f1a041a5e060635efd209fa433a8d11c86e075c22d0d651fef710a2e6592c6b828eec00952649b7a4b4a003029ab5fa1e2577db68ef7eb28e750322801adc114049ae86246f32a8741fc5206a6ee4f445e9a5232056ba213893f4514f438c2a8cf5733f573c8fc0e7ca0bb09517757b9ad556328c4ca28482fc7873671842bfaee64f0139c01276a6402dcd56b38e5dbe0e26cf13747ca8049f81f70575f730b1c3585a04cc765750de29b989d96a9a9c7668541718319fdf953ee18bc95b4bd89c221c11f1484409ac95a86aa08b034ef60de9f83e9cd8afede30b38a3fd256ea9757e0f41e2e5214dbfb90952bdbc2fb83c5a53443730b47da057a6e458e0d2d4ac9306f2d17c5982f4fafd3970143328615e7a8540a8d3bd7fef677a9b801cdecf811c04051e98e840aaa57d0a34df913c05ed0640c071b97fa631405fb730c6bd49fd409c31fb11f0cb1e1272a92e191846974b2fe1d37208d7e0c3512faab115e10dc39982113b4bd3ee23214ded1c0e1c9202405524846811215d1faf8e6be2bc37728f0644cc0b003e6adf223545b8378cb00bc9914457d0a93554c656ee7ca0cbd4564956e82f66c2c4b66aae3d1a9d3872544754425ff48740cc4d8ca62d1ddd2eb45bd15cf3814fb90eabb48c7b1ee3c8ae7c1c68e281c8788e5f21dd23a5ece7f03e99f1fa14c3b476e812c348e1f697e7668877ce4d8d8d05d3f35b681113f82ed1aabacec70e269e69b47583c0a46242fa02cd41ce996e37e16951e86202dd60232a1b247f62c1404f8d12629e9a5c1e27e3493eb8dd54a1092fc472d33ae09a0722b888a0ba09620b0677a12a158de10eaf0eff885cf2e18e01dda9ded666cf943ffee2252a52f85275f1914c8dc3c1223a44ab468665f286f0c53b21a2171e27cf0b4a5dc8c9f003883e7e181bf90b3c9d32ea536e669047eba18a6653da9d493a9104df6186ccca39248ea08c07d3f66a623684362d8844f00a6a6def45e99775ccbe731d84a8b60fa8e811925002dcc1280398afb9618a8dff3bb75581e32c94eeedd3ce5fd9111684e72b1ca1ddbe2fd90c953fd3015306b44588385d4d4ff77acd356c52a6a0f7cbae9af057bc13d75a81564b61db136c9080981aa422f00bf60c23b6d033206b3fc3f5ac044aaa02dbeb2d8acec867c63c1c7934706bb458d2ac98f92336305e2aa55a25b3ba3f38c8534f7c24438eaf1b18f93b84417580da50184be38aef743ae59305946a563231b2fb9549047170b47d6a55232a81218558fce280aabf33a27e03364f239953f10bb96f0c105493a249ff665c8e7e4a016e56cc4a049fcbe139891632986ebe522ff0e97f727ae46ec92a4c52f8624725743136082734a53602cc94e6635aab9c8dfc6319189b5ae54c6b486c4853ac6ea27d829722ab334093a40ec95b2cf8718804a0e8fd4e5fecc6fba663e238eb8b31de896f914050e00b1c6caeb2ea590d34d868d2abe1dcb1906e1326265ddd8156c52516d21d5574192f2a91f0dd1becf620e0f9c01645f906afeab48fd511f618253059ffdfe53e7ad1470c930f56be4444019fc9c061305dfd926a5c539d0a0742163835b5f5bd444cd7aa260afb7904c282da67bbb944a233ee212a2e56a0ee78a2690f4c2b5b43e3788bd66156f0a27a75094eb871c5a9f350642f465e0e6390cc5f0c7df8461b4417c5678e0abae15664b31a92edf4a8f01006ff879b4242e72c8a0061a039035c3c1f860c35c82e89961409b4b1bb6c0a3f22be0c3aa44e73434ca5bcac2db87f5e043af80d86e38db1bb5c56b870f08b58d136d6bcee279023b7aa8ac90173ee275d10aa19390e081d681988cea733c8c4128ec24221d9511ecf170475006962ac30db8339381e9278e0af5e3ee2028ce16220082112d91f63c1e418e3073b9bbd4c946e7e0c5dbda25d22ea051ef576bdf42d8f021f26f1487a564474ad220d5ccf4e873f45864407e0982ebb8a4db72fa4c450fdfaa276fa82f47eeb1b46124bff4281cf5ce6a750365a646f230481a20f2ddc9ec150e8294750f66136405f7b8f340ad324a0a278e9d0b7aaf72e34bdc4931f67fba966f7c68292ce21cffb91775e483114749043ac583b2bd955ac34cd0b2bb3ee2c080aa4f987c3aac7708c678a71ae130f6de901816dd290c455284daa2b0b50c28c5453a79ef8dde405f36d37240687483a3463f3afb45b2af09cdb1ba8d0e80c075076c754b09d353eb06e4324ba5d8c6ac1823f6b23a52fa0c23421a9123433ee368a25e7108e383227d88a7db582b8748634d91e527c26b99b4fd09b459d420866f39b5376bf04d78b91dcb709c8ea9d2791fba6b0d1892dc97c9d9a8cb4308122eded72fcf201795e2344026e0aa778ba268bdb8c9e296e757552ba25b47cbb6c51345841b9ad474f51c85211d21bfe4a78a0295a702672265246cf24d8d71e29deccb89a1e3e3780500c4bc7bd526829218ff6335b3c793296799ad0be4c95d0200bd42ff78cbdcfbbdbc742c414ef3e36a7e317f033c8d113d66104409b61206a553cfec0b9339e152467fac5ed201d2b17a59c6a20afcb476bfebd4877e85031c2a014aa20c2555708c6975d8e7f05f3411bc1312f83789c2b3bdf5fdfd2804334dba832298261c00e613f3a5e6c50b62d135a1ed4ad8074b161653c23e7424c1da0600dc06175c70e2c9936f3aa4ee4be616fb98d9bf779252cabd7735024302360227398260bb0d138628a5b20c29e7f1ff3f5497acee7379a4004173c4b61116c586a2c55f71ab615915249c0a0ee1e06655608ea269d225a87d5ba6c5e93082493699cbeb1d2ac6a98413fe317c4c73e5b949252b97cda2becc272a929648b4b586a4230cac58cb367facdb269b063f966bc32800091474f2efe062b81d8acddf168a50ce9d9ce354cc6f8be30c1666f3e6c641cb0f39dcd17b13db31b9a6a98e4e675ea7b958f7b8f3ff05193e37a830d3a0f673df6bb7792e272b068d3fc6b26b76e752e49c83f49aa04896aede94856b86cf0d557238e6db301f4070315749d174e6f494e63f67b9dcffff990ee28c28d4a3aefe5626244980a052cd20b341d37950ca59b1b135fbcc2b8ebbc7ee8c7e7b951983b1343732fe6fbfad51f083f3a09084f7f5d7bbdb7d5f3a8e6474944f9e3366470a2050916f9e2a9f9e21fb05ea4ae5a9c80eea49224f9046f1f6ae89a743871d79ccf6141e1b9aeb9280493a400bc3061fa723dbd9359cbf9280142e2349b7c31975c3db85f590dd4d51734e2a5e2e976b972d4544a3115a4d3a4c1fe5116a470a1e4e4d728a66c37619cabb1d531ed8044c1c927686376523d621266008cd6e11765f960903eb42f4a2148dbde3b4d66faf482d7495da23d82947e52021a145407129c6657f9b302cba1cd77ba83a99d7e880dbdda3759e2a6688f63e7133c66b5b7d8485058bacf025ddeb851d5c8b2ba0aca8b404839469a5960931720a2f871348dc1affff465db2f26fff71ef23ad2acca7fef8295d9a604d33c737810d3c1d4671a246dff5c915e7c44d429d1ca689cff7ff7fcab906a119a1aa249c289455961b83b7a2f602e8abc6d69ee9fa268801f50ac60ba7590827514611a2010cf36cf8139dd73610e6294752ab8f12392b3af8bc10fd71ceb9ceac2377d8b94341caa40f29284145dcf7ffff3fa0bb6a4e55ce108d9765d5ca8c05ddf40a04d214d4cc8efd6b719a7b0d2e75ced3415ab8357b1931ddb2779c9ca2343bc9bc197a5b58cdea7e4fc67a7f374318559895d5f346ccd7d193729e806ba9470b462a66e9ece53dfb11b043ec3656eee30697656a364d9f735e748df2516449d25460f734f70dca13c6dc092a77cd721c68fc64d76d5235adda92d544fe2c6896f485712bb37aae8eca326a9f28a6d0d87b999d6c20834834caae17ab2237e96397f5fcff8db48331ef5e3c391771818b7408c0e2209923c7f99d7852cd3ea641b0c77ff8a74fd6961f47a3defbcac65b9a3c85b549fce446da3bfc1aa9afe602c9a9c8a1f6d1a283ff711538b7003bb7578f83d74f5e21ae9c803700db70b06b14345d0db54d169a2b7396ba37a65308055a1e22be349b80036051ae66ede3064345900b33e0d4889441257663ab2c6b861137352385011b844ee4c7dd3dc546e18671baaae804fbab853ab926adffc7af7bfb68b04d397bf663fc4fc27f2af08db4227aefbdf7aed2f5747703d119ebc3d90f56555f72419974afae0a1e2cb9001e552c1599ed0f1930816131a9094165217d5e8cc9369b101e9614d83e11e2081276499e2ac1387a49817bfcff034bc005aa198e88232e289c9c30f63e557576403b072760cfde39e79cc32ee7bc458b79084e4eb97c57de871ee7bc48bbfc3010bd3f37e7756f25d4ae7848b4a555d38a2e7e59663b6dc5a1798f609b9cf3ff7fa12e595d9dcc02056a5b10c88ec1a38cac136822b41842535b6b0186eda55997c8d66939d41863b1ffffb3a72e59ddbd8268fe1f33f1940fcf1db24443923f983f1ff6ac478fafcc6efeff07e99683c4cf1f57af7bac30e96d508910ce5f0a2cb032ea3161448634278b57522dc0361344313b67b6c035e7b10cc95427339d6ffcfffec7ac8ad97247540bb49be48fd833b9e2c64578b4b4157936c0e0cdc621d2b81142469090b736424e9486f73424042241fc9e6b68c277b0eded15a7f73f6ef54975db3b57c8f24dc6bca51f05feff737e0583681533509c60f71a4360d632e6a58414c22b04163ccf2aa82a19a99bf6df23cae80addeab37b504dd7e783403bb3177f6824a10ad2cc8b3592588c690d517d340d18936cb0f861f2999dfc5e22456d114b133f10f602349da9130d4bcacb67a533db107d44a16dc303731ee22e7bc789b932efffffd1590f79565b2c3e9e1fb0ab2c47b5b89568bf8f5dd3d3846e5ab0cb38dc6eecf8e276359a22337043cfd9e9f573fe721e57401d696fd80fa478a092da3cd420d560fad108069d891dc130b0697a131087a6a12c35c5a190d923368c6996c7930a5721caf6f935f61e1f958dc4985795ad2003d5085828918c981a379a332ae873032675aaab0692300806100073cc81a9f7382428dded7fc8b395feff94cb2a2396bdeb9e963b9aea022e8632035ccd992ab30c44cdd481b03524d6f0898caa94ea6121b4559c8c08b861bdb01fcc5f9860efbdf772d137053867401a71289280696dc99e596a79c4e4f6022a59f3ee04b0835a956151ffff2f75c98a41c76885060e1b551744143a98e2792b012602c5d40990fee9721e3fbae8eccb2b88c9e6a225c5194236718476769ca4bdfb07285ed988259a1f52bc80a1010d61b08e6ca2d221168f0adb47766f3c50c3a28d7d5b454c35bc0315149975b2cb37f44e22d27bef46358cd88cde881e883e62cd6fc875ce39efd034eddded901424e1cda7950386e415bae4006dca2f6f5386ff4dc888aa37516044613255302ca724509174f7e8aea4d420db03f179be38951ceac3ee7f677f429c73ae39ff2d185d0c2e18873af3ff7f13455db27ecee9b68c7315826bddc779b91cce4ac346f3b6d737a7ffc3e3bda441c1a9e0d74e0e59727ee285b7961f1716b7aa51da1682b4e8aeecc2728fed45693b6690dfd43e18a995e518d35a41fa5cb9059530e3c1a46f122bdc5a129a7310d7087da2f2dd4bf0ffbfc43f510fe79c43f5def7b877879d345c6b2c8e57d8b51b95000becbd7718deab02d393dddd7fd0a0a8d80dde8aa588f943e5e861858f0c172a9dcd5316c0719768b1dd36de29354bdc96dd9f3297ffbfff31c98fc9559f501f955a0baa6b215d6c75a35e53401837e79cef929cbb9c23858851aaa6ff2f4ab448561480048d72d4d3c98fc3c14f3da6cde367dc7d70725ae2932163bfdc189efe57be1d6b53c0f2c5d603e4226c4c478a252ca7d95c81b5a2b977028d48a8e430986c00001a7318040041c44020ca0349ce6b0e1480030cb464d47c402c3440302c0c050241201014060800412010080803c1214130102288cc2a81d900274f314dc2131d5086676ed4461267348a21737faae536ba0c141856d29634c23f32dd6caa60729082f761f46567f05ea51d9f630893a5754d30e29aecfd6dc6120b074725356a46364a531d7125208dd3b55b135eeb2a9917b812be01c76e88618fe877922ae751d8d2d061a490b70ecb25751ff44d203858fb62932e9b4ef99c5f445243c24a6fd8da2ff6229bc83908955d42a017d61d0784cc185e1d4208e8305268a5bc88f9141b51d801700118e46c489c3d2da342c3e73036d691ad7f435fb5d601bc61c707f32660116e546f070eee2705c63ac0be1418b7e306c0dac1086ebb405addca99d51384fa908b088efbd380a80334b8bfadd69e493929814bec244523e7884ddc94a7c7d9cadf3437b4b38a432c3b9e05cec97751fc5cc8bb6b9cc126122e207f34547e9ed77d4a3de3539e7697270097d65a39cd26371d46e59e59ca56668152866f3433bee300892a63e42fa8e75ccd5606ad81ebe45659438c25f8bf6f385f34651c836154c0da536a6bc33de03274e69ff3e447006843628756ed85b7debf0195640bf79fb346b2f3691c6812455567d43e2d1b56afa430040fbb00054f113800d655e401457d7201cc220e51dd17778cb34e012a3736d631d79b3dbdc6a684e7405770c614502888b95f4d02f95fdb34d00258723122916723183984cf647037366b7080c1311b9de9083cdce23109c811c5d5cb816d30197bd2481b4fac4966220488bb89bbfb2e76632c2bab99425bf89f65a492c9a633fc13d3096f30e19d6bac2c6c96b15c634deac0473cf1598cff9315ae4ed77d72a0356a86f296b4dba326e1b72eb2866d437bcd1e98adf2b0a98c77c5cd832c3937820f22c8ce0daa09681bbb3c8cc414a4227642c93ba4bad69945b452f98d6af2d2f68f13abd16c51deffbdba60375264942f20c37b69efbd023ed1998af35e351c85beeae697647352d052b2a9ee2036b3b0e064a5228a7a711c612842556b8c03ccb2e1121230e016c9452d6e163c8af2f963f71b081aa32d52c73cdd105061e88aca8fe336699b4263ff0452b184b11408235cf42aabc8d3f2c6ec4c5952a494796be5190c34d6a6da7ee3f87dc1eee6f392699ffd83930061b7f725cb88b8c3aaadd1df4dbe7c08e94d0d3e5d398789283bdd1d306bcc46814820f2572a524c50d74044a9559768c0fcde7010ee69894c840d4feaf7f109453d00360fd4114631852e21a1d015501c0ed225d2900259091d151634c1734c3da7f8a796f00165cc2c12f5e08a9b206e285e0926e7996bf7545652c31ed725e57f320d590ad59ebb1d15020c9faba9f174b25c48d0eff94582089a5fc17259f29b9fa9f7e031ffd54b25165d251719169ab0d7984783743e362ac0f1abc2cf8c7182c8f5d97935295aabd4e25aea639462b31547f5b7d5abf9a111d506698441ac0f1a89cbaea996313b76842493f9735dde6813696968e9a74c50d7c6aad127f69e3c12ae9873b332d87f815c38f6c102f24c92b387df6cd9ecde5dd6cec27238170b0c0312ace1438c0e6f117ccc485d97baac23966d5e36c61bb417a2accebb260a4f21a859d90a222e2170bc8888e6aa201f348bb7cd4dfbe996a2181d4f3d130843c7f0d033a2b64d4840cc5ac03c7d68941a0e04246672f103adf910b97e3b2f0b63c78f5040e964baea59726d4b2480ec2cf76d7cc72fef8f1a397c90b3c52b4283ae2e0670ce74cfb867e3aeb9d20bf64a5687f4ce3c09a1e480c69bc908a17029f35c41d6b1777d1b4fa69e6221e0197b703025a3e0c5f26c69801eeb4fc072953ada19184712f151116fca04bef3c8161c3bc5af571bdd20c2b16f4b8479267533759230938431b40499f20c0732ee47272de23470110b4a177b15eca89c63239d61f2a8684d8496342b8b95728a8d0d170480ddc9a30c5ff6566081e525ae85dba9249ae9ca6e71053fae812b4bdb8d579455fc069b3d16073db08d81718c6671eb94292969fd72a9511115a58a6f22acb21ba495fac0ca6054a165901fc80e8782f8f130e924447ec51fc0f243f02e7f6209e95aa676db64ab4c96161091a44b23a96f3280cab255acc9e9f36e960df9da8b4a12cc81b6263f74dc6a7a1159be13318d59e11f2384067bd36de286fd8650268d748d67e685e01fc175ee535dc00fdcbdc7c6808f9ab130570d1fff441811a51f319147e3b4a3288f6227c431a20a7647167fd498cbb940df4c07aac00eb586746e0cd41e8377a180509cb9cbbb225b0ede25aefb4942f0074536eeca6dd961fa8184b319f4de3d80d490b0bf12b7d894b9419424e74bc54f3a0f59f04adc40b31e4599b5070c67046516d49682072c12e501eb28cd03cd5d150c9bf50bb96e3825a0ad5462945b5fddc28284bd654669f55bed471f0d80eb793c267322ccc6a2c801ea4f3c12341fc098b34b444f91475accccf34803078f69f67b687ce19300c8fda2761e12e8b3d304a08846938fa04617273a7ce40f6a784f0d77c088c931d2775374f694680baa3a3a2b64715786645b536b929620b785282a1cc7a0dc99f550f93fdcfca96d41bd5145d186db71e7c5421e705e207f329d1a376a882bfc030ab2c8d92b5a3c9fe478d48a00e22b465352715c477751b7fef87d308ceeec89cae712e920611657af214da070b08776f858df0991432cf3e1bbb56c8a99a085182b0a5217ae0e32a4122d71b0a09e127b281ccc52bfe7721d066e625f42d05b3e6152e4d558a2758708022daf6a1c0a6f8975d9fda2b23ac6fbc0edd2c662f561431c0bb71b338ad928d90e071f5ef4a3f1007ae30a0fd72a355b04ee2e9ea62366b80a3ce55d56259f6271a9f8ec852fbd3edb4bd3415ff1c87c90fe8ecec4d444fbc0790a01b978ee87aebcc6473dfa1d18e7e480f204b79ceefc4de2537bee440c8e552f16a3840feaf8a6f23b065d81257dc984a1eceff4464883dea66a9e74453a811290c325410beb0bf44b932aacf2949e6dcf1de1e49aef86435f7f9923c83b458406558740f9a9aaf7f59240ff4abf203f1eb136288567fa8f98839f17481ed1eab06c3c69fa08faa9c0006783522a0bf39167e92381a1b4cc92255e04fba9ccdf7aff4ef31eaf5d44533cca503d994e6dce2874aaa7b2ba1b9005c97c1a119fbfe03b9f6e2e6071f800b5802c14327e268b8fdd0497bb8182b39c140485798312de7b92901f27fb544894b89ff608e9f181f025b7a419cb378e2209f444bd450418bcae20aeaadc4e5ec6b052916b5af864a78eb8525d4cba31dde806cb0e46a944804a69c6331d61a9b02a36e41420d880275b3899a904932a7b607de7c9d8463d5d7edb5163576ebcc913cd213a252112ac7a5d59346c81af9fc33ef66640a1cc12af457bb76f9a0f87f14a1e85abc010914c285d0b26af21a3c06dfe2448ecb525cd747464485cf6cd25bfb2ed4bb0c7d243a0b6872c51c40f00fd89954409ea8e4d2c75c72995e4aea2f696c626801db2de36fa38c11704d718550e8d5fcb67784a47fa467276f8ca23d4264a52873c6db929ce8670f48eca95676fbd67abcf6e95a808616c32bc26cc2120cf6d65aeaee1cf12f3a4dced3eaa61126980af4e6c74edeece7a569c0d5833e4c05c82cc6f1bafcbdf11bd1cf4d08e9917747e73c215cc0bafa72a4212a3380f6aefca73ae005660c1a51175b00c20e6367e76097aa84936c0f122c98ba285615343ac0e53ac070639d5188ef7f191a1a5d2489c43b700008b8bca14f398dd6dbec8d14fa4820f46bf4ee984201290980b906514bbb17151f5c5e29d8a9f576b336ee68acf8c67dffed5faae4c27ab7adbdb6d843b56bfb863656c85cbeb98c4975d6da276e9da06d5d455f451db2e04607c43c061c15746d9629416aa417efee8aa71486f5bcf4ce5a903fc309fb90666e889272b9acc0c2b774518fc07c3c6c40a42c552a2156710523bd0e2be296a02d53a22666e8f583d4abe65bcc55ddc6a21f842a978b0ff3db083c5a32ff9b94701aeb711f4aed526837513868a392a1e9280b79a1fd9168e6461718befb29fc6f64f674ca90884d8c08384407332f46e84de544a1aa075edac334b595e03375d4da4eb48e9165afeec72ea06c0171741ae5f9f843ad67ef3ddf40ccb9df9ad112995e600fd78679bdb79e59b25bdbc8cae4d76c20fd4700955435e78a716393b7b0667944e14d7f33dc937880ae70ad454cb56ac1c995d29c23d4021e25b70b691cf95a11a383bf3ca4038964b2d7da27bcebac7fd62f7083a506e40b6c122d669b364cf8babd671f6fb35ea1f643e17e052ee91d552868e1d01f9e446b3fe068107141787ec85988ebb2576c5a4536deb3b25cf9fe176228d18e588787402a80ebc3620d829c421bb7aefd778d3cc7b737d037d4b811928c8115f8d17f05ccaecfb985430b3a69eaee8b296393d91b8d11cbddd1cfeffd203ecff4e637924e4573cc815cb43c561b57f424449e2fef4f9c349d8c1469357f5988829a5ad0ff9c71092ec1f94ff7275d23a9ff1d5e97e89c0d8b951485f6c60a8d4b671129057f4575c10b7c87e4b83355bcec4a5a88670bbe86a817d898cd86a299790c035ccae6937f69b7b1feef89a2351a3df9b3ca067d31abfcdff602ee3229214a755496d2c645508637ef59fba7b262b17a9f03027cbd4195523970c35ff3a9da7406843642614989ef76f1c6570a29e0ac7c8c5ad08e3435cfa2345797e0929f0128bda1d23084d19c6315196f1e8b1efade88c93450e7429ac248ca06c5924727205c9a1e1b21b61948ce116f5380f535dc51f3e396765c91f9a15c2ff00414f27d1ff6e474c2e658429705045aac2392e561ba3b9a0f4625f30a223bde14175abf0ac4a800086577819e8d317203d2e68b801ac0c29831b3e9eaba221b28187eb32f2e282ad7e8d56df87efb99361a7be5e599a42131cae818158523187a9084f8505f0fce3aa19fc2965d546c5107275d9b3ad7a98dab29457f1a4a39ac565873847975750483f943ca0f72b73528258c963687b81a392fbc176be7007770c5fbc024acbe8adba08d77b07ce8f95e7dc796df00a820b14857f4a4b09e3cb308ebe445fe265549faadc71d605b18d53ac05b57983705ac704aafe8d209c689d9cb1a98947c5041aa25ee4b8ae1cd9a197e14c2d0446528d470ba1324cae6e8934996b40c7c4534c65090c9ce59ed318dc4bd69930649e1b8cf47a915f51421a045c5b8247b111a1dedeb11222bb34121b8e99d8e62bf0e16acdbf520678833715f1e58220b94c0f008d9397847d35b40d3365e235be49cbb5b86091a69912cf6f3fad242a93a2d3380e2bbac45714b1df91283375a5a9d6cd1ff90fc4c22566391e63d45f42bc64255175b311251b54be00ab04244cd0623dcc7912cb21c593028a5e02771c10d6cd3123038f528530754c7857ff3b2d9b7a41a280de3cc146ead317572c2522d402066ae80e23966b7d46a4eb02d2c9c372a97ff2669cc13ca24e37f60e0c3aca4dd06db8cc9c5a940da83df94f6d6c78b4461c69bf1defa47f33e8957b5176a0d685b06c7926ae5f1cf1e907f3866abf55e152d41a1380b93c41e3fe4034ea91b543ae4ab101ab975e2e0b252096c8b4415b83fec1ba2d91e464c07f221e775eabc2c86c95ffcd4e81b04a09682d48d8a725b8d9b86910d92eb2b9c6201cf406a6f1cad8cd7f728f9c8a93ce940b8d15b7eaef28f82087e8678d4423f97842c0d7c9d9b3dfdec42656c1e4a479e3b6e5fde6d8c937e234b052ae0c68a0916f54d2732c41e91d4ba1c741f17be6373d50e3e0b179c72bf7c9442b8de8f904144feb3b4871337754bd07cf940e070c09b90517eb2e430617f80d3f6a0be6431cf06bed784ce39ddbe4ed19a5c223a338bf906536d67c140343992a9c2d1b5b40e9adbea4f226729052b1120db9f862c04ad0a5ac1a8a88db72cc1320ddf8473dcfb750d01fbf93f86abc91e74313ee12f0450a68711d3ef4df4683f0311db209c7d054121c8b09c70e5f19bf07a208384359427953eae748cacf3cbb1a9455c59ef89fca89faa6f1ce38d61ca5de9412926ec0013f7781d0e9f42ec5ab5165af0f9f9ac4b1d95969334caafb022dfeec40c1079477571df27e039ecdfc34dfd580d860415a71ff9f189547c36a7b531c237175a169422de9dd64640c8e9c1247fedf1cf6dbb8a15508a9c203fe1c6e739a1f9ef95da0dca38f371bfae7753b6cc8d34ca8567c8077367d05e4fe0d8e8718bdd7835b9db5749a73e94dcf349df48c45b4c559700e0ad240a0ec48f4e1bdb03e1127b40f4dd2bc162671fc846160e4cdc271cf52501789fdad46773753b8c925d57ed4cf46fc3d68a35afa4296201aad502375af599746aabd5edff2f5ab5083110a56acb9305ce5c3855876694ffff24f66e0c404ce9d0e445aa266cf520e1c680b3107294d8011e750e02f0ad018c8e9d5adf47b7e5cdbcf8510d05ad746a13f33b58d9819ffa906964b0ec2c4f6af4e8758ff1e702ac1e41183e1ac1a7002830e38dcd476ce8b35c964005183fe0a04ac3e0e98a1d5dee94f372ffb19db8b917482c3bfa69dd093beda34f0f6511008cb64442fb7ef46f7bba45123cd61b0d3761537ea1d14cf330903ddad8b479a51828f878e49cb38b582239000e0f6536c01dcd027012b6c17774c9862509ac6ff6fdc305780054028a17425f1b06f118b5e4559c89f605b590ccb81caa9337a73a7e345a809fe7048180760c95d97d5447255bf473023e5572ff3d730b6396aca276c504e375240c6bea8ff78628b5de94062139ca671ad833bfb0cce1e1f714892000a4392bcc63c63b23942ba7c8eb82399039412fa2218199afb9f2fae1d9d0130778a68e9e28436c5159b81225342debf33971ff5d82819c291c7a2dd1e8598b2cf08262999f5dbd3161623e1788c4d3aef36691a69d8796c87e3b5287648288ba22011c051f5a0b655dc80b8bedaa998ebb0607fad07b1f28982c499e3f84ff90602b17f63d6260e46e42f8d5aca7e377365509bd8307eb8d94cf73a430e200dd554fc9b088282857ef80df79b859f43c0136f62f10982d4d725d849045482894b4a69e2262792adda92ab31ef0c16fd492ab85f0ff656d70978c1dd028037d316f925bec5b2b70e0a610912c7694ac78ce1cd32a324b0718c2e6552abd1f777d2f7ef455452455cb872eda5f233d15121b6458192702f2a6dfc9b8ee12c43e18fabbfccec01b7d527713141c70a9e6daab459956f2189f68aee550898effb2cc22f5f893b1b20a76e13f469da6a92be87dd91173677282586d147c55506741b882a3d30e02fc056937e688daccac2501719539867d09875514032cc5ab0735401fb772d3fdbc8633e857c047791da48b220be000e5ed7874b3dd8796d1282d1b0ef660023a51013f650129188d4fecc5755d776622cb8b1609d14e4fa691631e37035b08a27dc9503ee96789627e646c06fe68203fe148b41b9627b8521fd5cf962aa207b704954f301524277d10319475695fb23e1c7357be57289629c4e62947916405d71fd3f80a01c5c98129c6fc6e5f686558bd8b044345ddea2a312412779fbe2b437a719d7f2e73f0d99219ec894ca913692db6577d0b69d20341943d85b34f2bbcac81939792ba40856498c9bb7da5790c6c9fd784436d483b5ad59b9420fbcfd61a63ed8ff781fc371fb6677af7a725afcc949a065c4550f6dbc8082079f7a22bbd57489b5d0f4f71a7bf8c7fc099808e359e28e203826a49e1dbb4958a184998ab4b869d7382aa76d44f1b58bbcf35da2ea2c41c0f6c1b1bdac33c38136e6aba9f85bea845eb1d53071d1264fc04e91c4a033f76619211d0e9442ba4988cea7a05b283969cca9d6cd14d266ddbc5a10d0a4aa0297c8e2e156d9fef415a2e281cc7a1a2454e806974f27e67bea6c3091cddc863af126cf0962c0e47f13ed2dd12912689371debbb5fb0698923e27b262853e7048564219239b776d8f82e90d59ccfe6d4aa2072f25607b23e980c6397b3ce8469b61c112ebd48ee408869cfdb3b71d1d0e494666c5e8dc42dde9eb028a8fdaf88377bf12e7ff31e79bc0867c920903840b5847a62691fc395c9609f81d5ab5f843d677d4c6d5443d49918cc88bd8414542c2adc6d98ea0086e67416306eaa82782b7c99560ce99072c0fc5a10c5ba4decb98ceaa585589a96de76da6d6c383e217c1185b3f9b18b84eea53eb2bc2e7546cf99e0af0a994d6d3a862f34acaed4f4d742a9c27b1dc4ce3fba4e33959bc5bf2a2624e2ee63242cdfccd72a648b76c376f2cc0352d8f52cd8f66c28ea0c5c5f6f96e01cebd133c1667dce335a42d63501be359b315506086e8043c96929bba93da036ac81c827e116720942760e92b0be87d4b22f6491a1bf308e865f864e160ef05216261a8c310121b8f309cb26206b1abe216bd60823757f4b8768a4c57610d89789f60dbd8f1924a4000ae10eb23c3334c8b13164f5c69325c8268536975778f730ee75de86097d4e189623c84941b882690d31e6ee0b6ac2d065a019c0cfea613edc06780ad4e9450ed10cb738c68620190b8099a2e89b4b801a68262f01d416bd5ec1bc536d14dabdd51b8f98b0e128fe61136533c4a59c7edb6ca90a620a7d0bce08572d84cc2623de3f2d43436b2195a09794ecee3275e5e13e4900a223f55c81f131ceda33138a37d4d6bdb903e20b358c75c3e6832e658b5e2b0507e56bc47eb9e744f5e7ea3bb31ff294c9f1226efdf92734fbd041a56686a45577b8675ae62ef3f80a8a7ef2c6ab1b0cf260d70349a9040b3ce204bdc6761b9184b10265c4d7e3330000ec1f1b320e06ed1cb82432f43ccc8f655b3882ae6611335f837759900fc9dec4f14dbe0998c0a9c8f7d5bdf70b625a2ea922f7914c979321e21dea2c60a168314c7db801e0ef1b9aa3482a3ab1c829902ad0fecba87fc8c604fc4d09cefaf663a78b1d5ef6287342684f69bcb878c9ee748710294f2164dceab82d66d819f98b9514a26c6a9a608ad3c7d4674c45ff16adac7688581c7a691a042a7b2257dde8bc4185efd4ef1ed03c8e888463c395ad629344a44b36c407b7a86c416ca5c110359e877122bc85646d84ba83207c264a2839f7d91ac8e6b622de946531eed022f2f8afb9a39104be3a989df06d310a56b1b1ca76ddd409a27038069ae5d2c69fc44593e0e93a111c67293eb31539bebeb60cf897b9a6ec6a46701261bb1a9efa812856aa20e6e286148136d6f4d064910180b83646bbaf735b61c85960872f0d630a4006b04909ce46c57111edb04b286c2c6cc9a9b11c6a0339c419b15d7108bffc666d0670e3daec2cf10ab1a3a157e84686b4f1425b080573f425b8e4dbb08781a682423d45fabb9257d9c076cb5829eeb32cfe6f47127a2329297f19818d9a1cfb1cab1a857b6754869002b4bfc6b36e5a0f88e6e429e9e7c85e8ed2be184f784140c87a2485bc69e7cd2211123c2be51feafaccffb5630bbb213c3f123f9fd89203da456f086a63536a28abfa3266c585fc4191e1d16d687f42e16095d696938e1b45ecc94c899e5f32c530fdf39cfa6da98dade5559aa0fd0be125ab9c134767c0b234b74deb11bad21a784fb9f8f530aac2512c5c48f318a25940e1665a31d1e1f53d17ec4b4f3f7c72dfecacc020cd69b91d0d715e094ab38b964543aac98365fe0bc49e28080ad76456b319e3eb4cb8e2e1524439a49573463b5b306c326757b2a9dc32ea8ac855ce4e0f7abb739847137f4a5306561062be829c7e2e922c5db5b1818e85169e03ee0470d30e425cac5ff5043b42e7e5ab28c5446283332833ab3a1c3f5ce3ae1cacf37ee533fb0e61beb848a1a9b964f36998afdc04f9b4abcc93a928c6dc2f8857a0bf8706106b818c36cc204c1a5c49e29d3555c67413d9eb60f43f968b3feca85c8cfd043928ab16852ad1e914de03b9cede27f5d01121351a30fcfc8204073fa9915b4f12a3d44233556ceed612b90954c371c025c1801ba94dc2156708e65753eaaaa07ec505cc472579c80a7aec71caacd7d109014b1b60b3898c0e3a264a1671e91f222e8d87c4c68bc2e2635ae26b00f949719ed2bc9292c29a8996c2fdbf476bbdcf4aeb6fc7ffaffdf5ba624e5de3b0802090209025d5b2c3eaaac48982842e188074d6ca42536e6a2e59a4095716fdd5d9754c7cacbaec1d7d3bd382dd6dbec9d9737f62a16ccaad3dd5de8d17f120ccf9efcffff7f21579434ea8ac915e6e16b6c6370b0e5cd8b6559967d5dd8de7b6f212a87a868cf2de704c3b5623be2a57b09c8d1b1d5dc76f5ffaf72166435d731880a49332e2efe7964295f223324848eaeb12b18dd222f77564a13f248a1c70c08122d264c6009e588796a20379a5dbfe4821dcc4ce1b8c430248c6dd39196004743427e1ce588f1a3841eb2abee6c1782d36a6a4bea2b26ec38b6b5e3e4738207f3e32980fed930c01867ed7dab110945d631ce76a7c5c6c79102f36681b244db1e88769db1d716809fd99db4a088470111360f39715974bfaf091e21735393730226ed22dba10385cf8d15667cf48d258e87738458e3a247bc24c638a12906c655c3420a1d3d386a70732d35f0c34bf318d3e3c5d79563e8f45a2525e0bc608ab154fa2535eceeeec08c92b26e1bff8b789a7ba2ccd244a4154199c860c22e2509754bdab000cda705a453560aaf1a9ac58a140ae72e0c362d60ab8b1a135be7db9cdacbdb9dddef6fcaff4fe38c92eadebdf3cde6fc7f1c2af4bfaaf936a1e0d0a4e275cf388f968648ab9dadcbff7f9185c0aaa236ac409da9e934ebdf7b93d8a41d462ca958a734881fec3a9577eeeec0e18a920eb51e8048bb777ffda303e3b9bb362dd0557f621f39b5a053be00d469abbd6a67efaf0d4e7f39a9cd898c8838871c09a68a28d110a5cc4c41866ed118b78107b76941158e6d925c4a209aa8e707c9a40d268d0b1f4a4da46cdbd806c0dfac7b93e4bc08c0d9fc485e76efbdbb685694b40b85bf3ae7757ffdc08029a45bbde491b0807598404ccaab532242a7972ac32513f6ea9445575b715b661dfd94e17d766149c405201eace7faf3fae7e7ff107208697d59582655a98a3d086143788cd2c2e239627db286f3033130a124173db0333dd48552844dd4a6bb4f3004b64059c952d4447dd1e3c4ada1bd2ea827a9a30756637ef1fddc93a5fbfe30006036ffad6aef766f3709f7dc51467ddbf1a8f6e1746f2654286b53c1534d535acfbae1b744c6b498e4dc7324cb77f7ea764f67f72689335083a71c786c3df1ffcf5bb2faffff539e0bcf1596f20b48ab580472600121c4ccaf3398a6a31f5ac873f084290ca7c6ac8cc7d1996ee03e88d85174f5c37cdae2e9a2bbbb02afcdeb04624d9e5f161206cdf2eba705201da718d5d5cd691274a2c11ec6528ce2020ffd4fc2a00c1a606d513dd47866ff0c058086a9a528f4b57acdb8349831cfe09cd59bb29a45fbb5f0ee9bb903da6de7153d68149932c5a2a22c15372210d597124b8c48154213bdd4876da4bc0dbcfa5c99a82c06309f2361bf79eeeecb8c92b2369b861ac499384755959f1f0e9ad5bfc1c1c0686585812fb0215b7d6a0b70e7d83afaa8263dad508188cd197878fe3c5d5673a1a58298730661b066995baaebbb7b75bb0c2ba2efae1d539b3f1284c05b354d5868d1a6f25536e30b259acda0a0d40f21289d94c18b0d682e2cffffc308211c501a363c8a5a7042244b38254dad2089acc06377542f5434eff611ebf679e2bfb507b3cb5bebeece2653205f29b69ac8403d56fbb251caaf3ab7b608c8212a650c624112720443c8661025368dc9b03872d1304adc5b25101761ea089f168acb35a5b135f9d7cd8047dcb723d6d3fe80d9dd3d78635fa296847c442d54c8275c118dccb9e243c422450a337de4ee066fb6ceaf26d203bea01cc2d422df506d921763cc95d2d29125fa630b01838123242119241a613882f48bf7b97bf2e6e5aeaba0e051fdd22ba066dbecb777f7ea763a96d6372b6a6475b2af3c6d6b95d0da818c0cd8cb01044496083d271a289f58b00cc74b4d1bffffdf0a49c50af9e69585ad7c776f9c9e02b6c2df6700fefe6f0810c5a052e73f8ecd41c44969af766f7775dfeeb6b9bb23415ba4e8ebeecd51c4b5cc3a5074c218dc7491fd9e843e6b90cf2bc9b27c3516d26a2228a67c5800d9d56e17022c3c29381b1f07c212c984b21a4ab1b0faa209b21325410cd34639a9d1af59c2a5f71b168fbd8fe63880a2d8fa827900f9e8a2b5461abb0efcb7a942605ede9076ddd6f288ad120d2afa935564d86c367fba8bb8dfaadc0d4dd8cba9b3cac1e9d401aa4accabba01a4f6c366746f2cdd99d507e78e381beca86a938d2166c0b221c81119b48c66e0a56771a891d1b316bee5f46c29f7ffaf74b2faffff85feff836debc0312883cbf83263338c4af92353696b65c70b2dcdd45bea5ea2bdfdb6ea059e4a24552c35be8d3cffff717647777873825dabe0ad7b9fff45f42feb69dd23ce9b498bd76a2ddd99357cc53b1cb016ab711e510ad921ecc07bea9490aa0fcc73650da897cbea34592392d90a8860a069a7d10c1562a3193623943e6c66623ae2a7525a138d8c9d3a75efba3590eeaca4dd1bba806edbc003d569cecd36b05adeb62c8533c03a744515e41764274793c5083a3d553276846c1463a843883914263193ac9497b3e546768d94c390a804ffffc2ab15256572858d79109e6d09747a7377cfbef7fe3fd92bbe77bbeeedfeffff582d43b874c3c0b2fec3df8a920287c17708ef86c493a1b181e1920418d8622c64d6823963e848c268f85c518686048124147c27a115ad5e5a0ae059b99e52b72f25b0bbcbeb4581138d258e9c9c22a9e74f3f69f60799dfcfcd4e9407f669a51d442dd4e9ee3f62fc316bab32bbbb6c14a77faefaffff41abd3e61dd288b73de25e76800ce1530031665424d746f95fdb0101cc549817eecf44a0be77ab550f4146ad531520670ba5d67dc435b475b45bad479481e45a034f2e392a93848a1526564e0a32c416aaa7c6460b4d538c9ea80451595540525300e31800040001c03010c6c140d0e3d61e1480030cb474c07c30382c483024080583404000140808c160300004000c040645a140782834a724d606458282fbe8ea336808e4bec169377868bca131089711f5bd95a3d63c05e0b300ae399fb2091ba75c523996a6dc6891c67ad695889981b6db22c4c603c6410d232962824e0cb03e9c5b8a1528b9456696514d8eb5115f9cc30a96822d16850a34f3c8824818546ab429ee42f2a9651153e57a89c6b7fed4d24cd945118793e85d95e8235d7b924498f52a0e4c924346954de2dce7f99992185bbaba88bcaa7476b5bc626179b16a3fea769b2d5b762e6e55cba59ed0a38eab4c88bb2e05ee7d6c4624be5a9e2b116e4f21c90d659434d0779da67adc0d32206c95ad36f6564a1241bfda61c8695a1735f18e14223e19dc08974247b4483edf2d9257b0f92d3b352cd28d26167a002baac8810806f4cf66332df557614b50f1289ab9513c339cfa89c5f902981292a6796ff8c2fddc9c678986fff4334a42d2584631b539b29fdc48d21f32e3b370160fa09c90432d7a3091c3e833456411506bb481ca19e73455a378d1680a6ebbb7c5344cc67c9d4c250ccc8ddc8aac326b5b29bab11c2637852ea5293f262de924858105578b20edabd6d7705464a73d63327c8a94789af8482ce694937bcc3944c7cb9cdcacf0af9809713fc8a4e6b4aaa6d80f64f408671d938db6740c376947d5af4700290fd481b71c14f2c9d1072dafc3108272c82283decef3bb71a7312ab238e34aa7c0a9168958f148408fb6ce5492b74de376bcde20d61f2e2390db33ebe6ba63e6c75ac5fa4c13b9191b0d3abdd41d9941765d38ea9fc7e0c3b5b9ecf8ba2b1e25fd915f250b2ad9123753fc19cf0979b74c017ced4febe917a952258d52c9db7626ab81e70480fa28277f3a3ae47a14f27fc9f960cc0c3139fdd381108651841ff9e08f0b40f9d8de92b0f98e9cc91361376ca42221dc33be9af0ef1bfcbc848f3d31cd3a0ee5877bab912f96e512056dd0b1115125f61a99a5ed7e148953dc4c9a471a0040454061e25f4c0ce94d4cb26707685f1c27d7994b48b352a3ff755b4f57be26b613a9f150449e55b87d742ed9b8010b89d77fb2d821e34323cf0533921743771bdd6838368cc0964a6102ccf2fd7c8e558b98a3558ffdeb5562e56fa95874dafb416c18d0c306dc04f23f65a5e0a3d550779fe9115ac09501044f9db8c9a6d50d2330b5eb4eb5323651898c7441b3922f3391539308332f7c70618cf2b86cda5953260f709e4712a9f6eca5d46c65fa7bbd09f1d358d87b3db744932819b1cdb3ebff233cc2b96891d4d26416c1112795a0e7334683a1460bad29de7852f47f32ffcdc2ab7427bf4843540669a111624b61b5cc225bd189ec8da91fc4ff53468d24621e247941f1930f3d3e03a150b73e244e92ea87153516c2c6aba8f1105e33b8e8ba864a3c521875f526cbf26e9797833e24545219ed67619d06612cba0309bd116f2615d5098c31a592a234aba2581e18c712352921d1fc6ed63f0f747293fa6166dda9a5ac22b03225367a2ee60a5514821a3705141a033c351919c439eb1c6cc28e87726052ce3d3ba8c1c70b8b79f2918c83df8f6da7f455b6368d0d2433f857724e0e3c64f0bccc3c496a45b6c43555f135756870a91f030e4b4573b3c413734010d15802704f6c2939c4a5dc29f1e909acd4c0c435b6d8d6f504ce2515e4298b2999140d52033d419bf38a12275bb3785e7475841fddd72a423f131aa168319d641cf03ab14a837d33980a5ebbadae1f26a05ffa47f3eb2ff6dca3e62eb207b02ba01d1d9ec48ab37ac035743e550ca70d112d99aff493bc9caf7aa5ee8960d5ec1bbdf445fefe52403a7e75e048af8d421a1b89bddebe7250d67283afe9529af20e494fd05d6408f5e330424b21c58b8204cdbf4db8e3287c3c2a5ea03d08e19d6c61e213ce972efdc478f4eaac515bc28486f66486cd77ed51a5a155467b8229c412814af990acc131bf1a7d3639f9f0807b7a611bbfaa904dd19cb7de4227a9ffc78725e709558c31b56a175a24caa86453caeb6dd91fff401a663f7b5b1e48830452117be035524406a0a5c5ddf8e8b24b236ff1b1497bd2006ea5093846304c250380ec79fdfd0f136bc5632167a8ee6474ca823fb93c7fcc912b33dcf19016f1d94087f0c8f6e718a3a3a264c6fabdd3326703f390c40b6acdefe29e88015d3444bea61056f38f3fee44880a68f4021c0253a045f496bcf3c864b2f8a05a0fa560425626490608ba3451e1b220aa63faf9718ee813ff22ce6cf86fc675144e48e16678cb2c6fc007dfd57f8275e69ad4ecc9c3ea9fbe676279809a96812aeb75d59a2a3b8009a458014a5c5ff0d2f5313872363bbcd78cef987231cfedb7dcf09ac0f91f7967853cc077c8832c23c8e3c2402b54d74bef13d4e906e61f80963b99b7c2aa5211bf6736835953c922024a50be06615779c8460903a2796ea2294e382541214238d1bd0dd4d3e16e0353b32fa55ce3f486ece9252fdec51d7273c7308d0049af670571b75c80b6b5715fe2492b423ed36b945811006bba57507c9ecab24eaf100cb6cd8f1594c478d9c2307934f1a4065eb5be6b586b286e5b36ec7a1f529c53bdde040d933aa04a2949feaf0ad840dd4a74126c6100321a2eae0b5812394e2ecbb1d4893465794a57797ebb72f6141e5e51c2098f470359473d224a683c38600dd3be499c44d1c588c9ccbea91b4e8c3657542ca49dfa9a80cc02be6a77e62d9ab993bb855b155f24fbfc4877deb80cdc78501a34a5e3a522d8865eba25d9d31f2a8a2b1048be1406cc59f6931d1204d5936ca8a414293b64e818954364eecd18efee8fbd803ad72eb7ea619b9ef207eff542e7d77312a752b13c60aa62bbc85c20d024ed9b60223aae8ebb23b058683bf431852b58a624ecbacad072515e5d029f7bd32ff4d60de971fcdd68bd5126b07dd27948cde82ee72f09715710d0aeb242cdca4256505419283bee4d3d0110ab3994934e55fb48f33a13c52622405a5d8fe68428cb39e14fc93ed2ecdde6fe3365e03dcce1b85b3d71499d0855e809e7be8754914ef7d11ac94e61fd28e5a388f60a2974d38a5843e60c91678c8cf38ca02dc50d72baf2f7b70eef6882b957272a3abbfc940644ea4baf1106982b4397aaa862908ee67a90e3b2e84dc80f723836db374c1bb717e692d3d9301b6e7a18125fe73ec6da9decf183ffa24534844002c57db3119dead7f6ff63de63e0b8ce07b60c8d439a26f1c4dfa5d155ea73457412a7f6b5908e0ed5c5d48f5f7c7af3a4df11167791ad86d8365c6c1a8c9d098fd3941bb6d348c25186f42dfad522a2813eaac22c02ebe7eb269a7ce2fdb07d26ffff2693c1ab7cce7e63aa9420ae557465837108ef5ef32222003cc1d265c9f2c5f74991c54e958d735c446521dd67243f683a2c27dd261d9bfa62cc8a949356d4a290ad80c9fc5eb8358c055cc3532dba9a45273762f2b7ffd05b7f11f66a0736a99f019f8f0be8569b7294c7e6f80ae7b04390802006651fa2475c1c5ff68d54c3c55b4cd2bcc63fd30813f1ce98229c08467fae4163edaf9c4db4ec6e5c9fa16646c2b004bb51820dc2d22880b821bf6b89901c6219010ae6da262d4d75673123e5460108f6203d60df0443e8e9999d9a27ca02f2c467b839f556bfd8e1c94f378c85137e0c927d2dbf72af7b25a9aea1688b7b2f90b179a700ede46eaa6912e04f5643481cfbe8abe1bb59226363e9b87a711ac60cc11cf597504cda4f9008820984814967df45b6d7f5318855243afae1270812675fa41bc51ce39c4248736c729bc992c484f9b4ce72d1c4cf14974cc847a1ea323d4cf069cb5a6dd28825e0518ec5cc5e1d1b5e215cda0878938b77b2101d6696148f56df6a5ca9d9f1150dbeef52a2dc5b4dcd7e65eefdc2d629e1f31bcacb9ab898075234183c03e85a2f3e83951596939f0bea058072fe5d487e0e34fc134e6c5b97405e79737a44f26cd1249f97ea9ef67bd4139bc5e0955c686e6f0b415b89fb999364f349c6e4b6500499e9f744e0585d483c6b4c84203b2e3dbef30bcb4a2ab05f442dfb53479463a4b9d3e308602f323548aa5baf8b29fe09ed7b72b6caec2c4c4c6958d6737818f04b24eb7a97825c0cfb1073d35afb60e334d1129a87145f2870338146d31a32b093523ca60059f86854b6c0db2309da09e640467da0660309bfca7e8f362d1ce284b0263a5749130ac8421137585ebab0c7012d370ae74b2f8d584d178215697121125478c0995395e078b70b67e121acf2130b624b9e839235a373f079f9882988cd24394cfabf0bf7c3821cd85dd0d4e75615bd406e6a216d395c5a79a309d72ef44c506fe670e7c8d5460b8c9d6742cdaa7026b084ea9a4be12bc2b29305c6b54a09f4a10b29619a8392288b8cc4308482d04a34f8c3d4e4e30d0dfa4dd4b6da6b0fed1045a1ccb1a2813442f4d28bb9babe795e3a318455065243f1885ec68c79dc1080afb62d41296713564f416e02715fa21f074bd1d57168a6a57131906746eccba748f56e7da668263a157994777771e85807d481f27352cc9e202f26f99320d2d4548d87df3d3e36d67e3de3a1ca50dba448744a826c104459d14196fbb4017f36543600d429223b11e30530d71a241f22be6a1be7eeb6da324495590fc0230af771240e9aa5c1b4b4116f85b9a31c2368d4dfc723ef54793c5e5709cd4a5ca9f7286cb9dbaf61265e3fe2f7a06aba265fb983ab405906ae193dc57617c7281d5a64db4707a0ccb688407b4e86cc8cb2cdb28630553f1ac755d8ab2aee1223d76d5a8acba72a2ac5ef5d9d96c253316b05f195f7565220cca92e303c2ef3f9237c6956bf2d0e67e5e1bbd3896a268ce7f2664bbb52beeba6e2409487d5ad3a44c64142e417c8edd81e0abd8759bc9206f33ddb39e0b5a638364548b635f0c92e87a2b6078602d15689d11419b561cf0ef7cf800e4a8959d28dc0a3301bdad721ba085b64425108de978c0f77cf41258d33b4ac0673b1d2c31f3b2f89b089140d5ed3c58af3d69308ccac551af161ff5694b38a3e22ea8c78981166f01aad4b4c47b3b5af9c9ed086e8b221319d5b757ec88af16be2b9278a5e0406b05ce7e8edcaf58697adcf5cfd5aa9ec1035deea2863072df608e8188189b2dfc609b2869a45c2f2710cc75b73f0f4d129bd63909a14046e8748b6122495e911c4534ff078cbb92812295b09ee02134685050656b13cfd000e7607440d682658eb40c956558a8cf7cd950fa60003e4bfe02919ce326597f167ddf275d48a7cc49fd39085e158eae817e34e3d18f8db456c1ad90aa2e9906964e924eec40d5264204e2275b24c2348c505a026cc22cc4f737500621569dd84a5b313691a3f57c11b33185dffc1338293b5125d20efe6955d181fc28de2f777b0e9e1081ff2bdd9685076754a7c2d637d372ea7c4443918a4631f19d0fa9904704aeda4f16ffc65c9c3d5cf03253e68fb9069e97cab0d24c995bac2f409c09110da528463412042943bedfd6ad46bb74608330c4674b8d650425514b0c0ce3103d29c8532c028a6579bf6e3413881d2c8a95e0354d1c33568eecd0e16a8b9fbe48a448789f4cda583f53c8f860f9e1e9539996d47801be7e732eacbfbf21d095fb51e0bea6940659db6019e1c174f37125ac0ce11287a53c40db3f9ef2243f636a0ef018866f428f326c1c02a8a1f0df30d3ea888aecc3299792706a67ef20fd6bc8efe40ddd05063cba31d6e00a5a2851040cf9afd0100e9a255a6b0ef93bda478f021777f4c92ec4fba14378606276d80059fba1129e9957233f6a6572b2265be17c0836a6d0e531791af60ce619994185f5c69330154817c95e8197a2971ee8864c48bf8438033f23a045eadea8a88abd598764ad69e2f9a57edc007117c2e3add58fa18885c661921904e444b8b0a26d0052cedf32d81e922567fd4023fe1885be8e8c3cebfc0a73bcc43697e012510570d7164fe712c67a38930390665b429da09aae7643dd1a9b162211183a09e6ca2f28fd1e269188665f5d506c6dcb55f830c1c1dd57eb6f1b304529746ac8dfbd468d1d3b1e5a56d6439c884c22af959dcf5e9c00045426d0b974e88350486260f8a26d6b47e09c884b69b4590305ca2f48c001685fed2515b6bbdd92b287ff82750742dcb4327ba04b21000cdf225eb718631afb0ddd18107560eac702a740d64492e86810c0fec8e4cee6800c5f24088c9d89857102b9ffd1b58936419e968997463c28e56d9c2b9e7017939fd5a2cd92a4e1f027611c915afddd3b8a66814badd284df70744a26c589940ee438fe0510772f70b88c5a0da3d3be2335c5ba79158a216402a1c9ffc4bd6a263088cfc07e8c6946b414c19034132019dea83edb162dfabdca49e800af0526de0224c909899edfe6372c09091d0121e64d6db24d8894b98afbc2b667b28273517b6e1b864c52b71d711253f329724b33867a4019a3ff4c6a812aae0b30c941795040a1282987fe444bf7c538ce13ed9adf917850d2c5e213794044f2ef53d580faad072c1658d045fc28478d0ec616337603c8d72c239df076cfde26988ba37488671d3b137b5c0b6384211032e013d9f24dbd21e67313a70f623672c3ed8f799a391d1098a4fdc9d8523240010bcba31e77414b36762625f6b06308558950561c7fd1e13df1b197e6341f9ed3626a88328714b5f9322406594501f4e60639084ec440a8916006e7b43c0a29818490af27265182c78e344a9c315153162089f4be21cfc6ff086224a35d328dc6a6b3a54c289524281c58a40b225261ac3caa44e6bc2da0c5cc3bda2762dd25a5376aba26e486ed4cac1d3c9cf70f4c765a2f266ddc0fea4e1a6d4e7c68465c4e630d76ad965133ef5c45a7ecf009214a09a11a01773955f790df7414002dc617b34e22d1aca3366c5a2dd95a70a82b58d251d6f9bcb53373ec42ff56c156bb1fe954efb4cf227fac346e4ccbd528b67cf18470c3bb6f3244cc9a148c688317ff01e1b8b212c6fc4228bfbe688134b0ab0fe22c72154d985013067522d6a3f14268e658f2c0164208182d01c08064e9b45e09337a008405ef424449fd628f05cb3a9917db2fa56d24b5b879180700d8e5d8bf7f4fd239a3f7ad4d9cf445cfa90e6bb9170b879e66e3d859691f48798f597c78167efe12df9486e171f2dcc3949bfcd0119dbcc1ef2780b157db6363ab3903deb19183bc245fce0c98e443c5831b1a098b57bc0cd6ce7b7388898bb96ed9c6250204674261ba5d428f9243717c14cf240446a80b7cc969e3c006fd2ac503b443b13c907ed7c04fdf7c9065d703ffc3b3f49f2950e6c1db533e378771984b91b65afd06c02edbae63e50e7998f0241d296980d4cbdba926796135cc2a6baf12aa22f047ac14c8239a173222cf5db94cf3835a81f4e1a0743d731b1a7004dea0278ef42633a99dfb157824e1f131619f7792020e2f390f2fea7aa314cf339c4d788379facf8f5daa1270d894b04e60ec8c905359f1e354ac15800df9fe2412519834fd550a40bfa3da65b4cf42a97f30f08b47cebb49e711c056ce77f9d18e138d730820b6a602b4881b0d85c9e8a012f92291270953f9d81056d8c6b9e8e98e7bc1b94a1e453aa79feff7a7fa15dac11e856fc7a8da79809dedecb12501b41c2c9e84aa455c527c1200be3113701760fb665aa859b68978ca7b573b8fb9f0a90a60a79f9b1390ecca1743420cbe5bae4872a8c228d4fa831146a0c428c5128a7c1390e667d7c0b607141ce8c5ca6129306ec02e3dc48d58cc9635b4e1f74cf5fa6be5eff559da5c28b0c2183a7c2ed6e2f30b233190cd266a95603685b1fd44590d9b6145251d834a74714ff04e7053a6ede1b04932a0aae199965071a5996f56776844d2d1494af27fd7334f89eeb1b53df2525cef53d57f4d237bb644fb68ee865fc749a751a0c98e7fb87d8f944cd4dc1455b6b50947a340ed5751d5bbe1faf2339a035867cf0b98745d40aaf0d4d1cbcedd82749b151177b051e5cde872a90b3196090967568798f5f831726e65d21ba74ead90d4fc9ff0b7728b1c78513e7b3cf6d9e7da1fa623dd2f3279efafe0f80f98a9ddc1021a2d95f46907c0f81d73701704fcad5c08cebfa65bc8f83e55974370cc14dda85519bc9cc422779b01474efefb4fb0d7bcab40521008d046e4724e736676cec01efe96ebc415d228b6e1b482d4cbcc14b619c46b941cfeaab37f2b47f13047c1de9b3050b62ce88d41235c613c59a3f6425cb685c2c51f961eacbc4ebb7b0992a73edabbed88bc1d6c95685567e5f8c21dd3a0b3343c3263defbeb3a365a80fb4c2eefbbaae8d63bbac4fc7eedd7bf7da85dd34155b1eb82b1a7b05f574fb734bf5903174567afa139e2c1a9b7073244908f1b31beb5425b145ef4c290efdacac9434aea0e03f9659ead85c5d24172b089c3bdaf3102e868ad5cb7d9ee99b4409af3b928be206b687f188e8bca6befa81b1ccd90d93393a7e96ce4967091a8a841126736e8d0eecd3bf7c25fa4d38688bd835a76280933af281811a93476fb4fa25ca4c64e129c9db92f190eb058b1fe95a0ad4115706aca1b15113a1a778e81b1f6aee4430a12688bc129687264c7c4408a686dfdd6a11d82ba8fc973ca74811d14603a05c35ba7250b1ea535eae031064dda35eb75c6dcf32b1bffc5d64c57de2e980aaaac94a892d9a6d7ce554247cbf5931752014933838b2c7760fe657e4abd83e86b3cd4ed559c4f047c9110fe04d1ba3faafaeb551780935a8cda7b8220908d0d4c6113f7f87fdb24c3b3b67f589a4c3aa72ce3abf1560fc622d1b468dd85e55d69eafacea0ad405e99c576e9b988cb02ef61eb5f19e111f219d84849b291df9d9810b3bb89956edc27be097e105fc5d65365a0b16a79ffe16c42ba902536cc61ba468cc3f8eb04b005988f1a2fdf6a2caf98e0c9f07fb5725a14b42c8335b59455d785e4a514f3ab56103b114379b26fbf0212004b93a6adc9a70ac85105b0dca07930a95bad15d8854245a97e99cb5226478c51eba9308258478771ea5128094af9ea6796bd223ecf0e8e1a065b074815931ff6d1aa447698947870c143c13f1799bbdae8092a27a8120e72ef65981289c9db4d6c783ebd7ba56486d994e900d17a19fc5396404dddb9b795b2570cf31d2a9df1a1384225de699252cb5149276108d1a3e8c6399c4607c33f2661ef72f02609e68757aa44cfe1213580c118d4d0d674f082577d1dc62923b672680e02d788ae1aef800edcff36ff0171bda7e590a16fb1622a002a45f1d777a475617c4984815291fae1de3bee323925d67dd1b7c927fae9a0ec90f775cda0615e32a3b3808192fd27553448e326d80e586badb8034a388196e994cc4c8945f3d9dc644b93f3a2294250e331ee2ed125c166951a344655fa7cf92616af6f6684630a76549be195d430ee7b33bce52138825a60806de018460414d2c8df6d28a06dc05669cdd10d278f961c62582418c713902186aebbd3287e6310b1c76016aebd83453508ed2e9fa972436bf33a7a8dc562e3260db440457ca7652891edfefdc8ce0c477a884206c229b38024e5fe34f9b921f4e6c4f7ea3dfac3067fe74e30445eed82e0c914e6c5188eec0d168b7b52da5943249194f0356030403467473a917239ddbcf9bf2476ea887d65a537046859a0aa86d01f203c6971c526b1aa69eb6a690881c295a339511eaa83881bbb3112644451236222c4a6b6c527667469ed61972434e6eedc4f737a9fead8d71ffc1d60119ef80ae844cce39e7bc0376b61cf3d01e54bc25c92c2bab2dec0152995c5d17312d7ed82b45b133303521725b3b8879caa6e19cf322fcc19ad9f602c0fc7c22204bb9e1bc86c8de7bef9dc41fac7963c56eab4acacb6c89fce6aeecc79d0d2925b92b0f9e8cbac4ee745c69e52f2b495d46920875f1f1021194ab282365daa8c8799d4cb4eee538591a21b7ce2c3a1b9bb83ba42574d45a4a8f9263ef19795a2bb92f43d59cb97b1835b5d6bc9cb4afefc6a625cd9c9a4614fe22be73771a8cd8016f12bbb398dbec2a9776c1a22cf1bc4913e51c05ab116abd897b6fae2616bfe469831117211cde2ae258ab0c816b57778388f4a508968c31255368a80de9b224b694bbb4d6da69d369bde94e22efe540310c9573ec85f645a7f7e276f2d853c53c3443c5971831e769451b6b66d3ed2eb13ff38714755fb1264cd4450de64bc2434b1870270c30e963e19c9bc5d01add9c73cef90b7df58e74f131f1e06f3caec7e8e887720d61d60d257eb6f7de9b77139793ae9670eb882173adcd489d86f297130dbe7643a6f642458606ef261cee64dce24731667beebdf7dee7c9f9e9c012a8fe3666945aef192f442125860bb6a625da92adf50255cf889a950c315355528490b6440baa164614ab85d7d6618e351a05cb707ce10892fb23234d33a972633801ab8c33ae9eb8f5f891038b0b5949392b888704c848a9d1e50bd965988f376aee579775c46dc88c09b1e8228f2130473cf35a01c9694ade5ad3623cdf5320a6281502f121e1df26345330a2e1752405e68534cec34d2948d11323b92d449a2d4678d6daa2e47542df4fdd91c64da8b90cf56e7e5c92da8433e270696ec7f33e36d2fa47f386a110118802c607d3911e47d07ac7286d147c6961450829a90a5dce2ae0cc6793ece13cc7f7dedbe83f58a253b1a77885144ba84bdd51a909468b0035bd1a8cde25c9b869cd44ebde0cac354ff945be7b4b9f81dcb432176c7a8e361e46cfae47805100479ae0500d41f2304472ad4cf0821191460b95d65a8311a2a6aee1d9727db637e0339b2386e24189d2bdcc0f70495b45f03062cc5f5aa6e6d607e228594f9dc4c2c569a318f8442b5cd2388a8129047051e36b0d8a404ced8883d71aa4c1ca8a73cc2e24588ad6a01d27274dbc2c5b8ac2f4d007e62063560c4c91d96e8491ad413846dcd599e588886ea1ad2c326bd0ce530f35bb62600a11398a645983ecd970a5b952e4e6433170012bc2638a62e00e19acf5ac4131f016c39473362806da2953c230ecb82352b43e70c76d3d6f30575918b6356866cb1c5d1006e58a510cc443bb3ae2fa400e5eeb9901c5c0147aac0b8ec51ab453c487568a1db7f5c5af38276b40311000b82a71c3f581564c8ef5fca11888b5303913ae0fb45950eb9981679a010c401354a15e314fe092eb030d385a83feeaa7b3ab459750d18a609105a5e19cf3154871498b2f3947d7a6e2894589855081e900432e2ef9434ea7eea297f74b1575d3582d7bbe1234868a6ef1ccc2bd7d963883c90b181994284a57381a970c3f5f4b424f454e6e58652b5a6b3d67cad0fae68e831b4f6b1fafa00999dc9493b9234e8adedeeceab8dc3d91e2d25320c84a3910582e10c036840121086e999f51d995a438c76c77e49cb7046262bc22b5f59405f5a5148525c4fa0262cc64783bd99c2d9d47315c46be9bd4f7c58c8149899d76f894867a31b699c57bef6d75c403b25a4aad0ed03337775f7493ea34134390a2d6bdd347244d07e79c13f1076b0e779bd07e23ece3dc8789a7122acdfba14dfc17860e88b263c3d867a571cc136a5e8d0e2ddc294d76e9fba1b49bb40803df1a0a539e91d3de3f4d4a5407b06269851ab5e69929cdbdf79ec389ea4165883664cc0a4ab6d20a00822464c86a500913065745cb26e2201e65cb6354a443ea6043422608954d102e0ec41b6196c8401a19d73c8639cf77277fece39ad3e9846bc725a25c9b730098bd1a38ce7d5f9ccb76e83cb53e63ec19aa14633888aed07d89d2623f39bbd1a089869638226c713eb2984e14b002cc6cdcb4367d00484066e4dc3c4a5ae2de7bef9df302471c574e318c807b6c7aadb5d63bb4f6e9b825ba8f3db7e5de3e1349c87b3486c48a4062545f453f5a34e1a17c32b7067f2aaf22ac7bb39a1a7225b925872d351e23832fce3568f2a4d225a6dc786911aa8b6467560c1b42e30bf1ae86d21518252b48c215c0f01295002cd49c5822e79cafcdb925df8cbe1cbd1cd32f01bf2516e587f669a5c10d1b2c09bbd5dc33c65dc5dd4cc554dc7fcf63916449512aeeb87fff7d98101feaf712cf43a37e07b2e07b062750581257fd9ce008d64dfd9e5f07bd91fecd417f66826c5681a1e27e6726c023d6d20dfd764b9741fd9b2cb224541be2fbf5708df7fa0065806284bf19ef3c4fd083fa3a0cec785075be83789e08d4ef27861201f7db714e091f1be2ff3b4eee56c5be2b13277c8032f0f73a518c26be9ff8eef31d288fb1bbeb9beffdfb39e7dc7fae9aad8edefa664be27be6d85a6badd5401382825d9b704fa0781d306937817b5448c1ec2fee6a763327c55da144d0fd0446f13c20762c89efb98bb03c23781cb03a19849a7d4ad810b93b601cf13c13d8f3a2f7737c7edd4a833679c24406cf133ce1d5bf4996444fcd7d03ed4db22172cf02c9131f949022f79c7306721035c413bc4923d4dc732f915f6bdd7fb2aa6f922561d53ce2796c328b1881aa7332789d8c810d91451c4971cc35c51f72ffeebb42917b08b99bc8fd44ee1af87be0861f4e7f9ddc739e9284fa4284c60b2e166bee21e01e1545aec0aa86806529c3d6dc4de01e144639d096e8d8c498d6dc4fe01e14da74dc48ae5515ddadf91279c78efbc97d5e07f78db337c61823c5d4a918631d18b9548291cb171863dcf763dc713e53b1005bd2efb7bf6a914b2135f8c0debbff5c75dfd504ea9c26de7d1ef71fee31f9cfae534b173fa08df7ce7d84ba33ee479d64879e73ee3f59cd4026aad411eaf7f35e10aff336f8f7deebf32604a9595b9dd7f99dd7f910df6fb71dc5f72c90b45706168e2f02a2065174ae8b2d8d4d4c0d5ea13b748b8c385832c413b45beaf7b747359ba95fa60651f5fe64f5fe58125afd8e815a057a1e8b1c03c2a3e1f6d40b34e19af03c1be2fb4a9726519826ac552105de5fdc957373fdbe930114ceb95d859a42c5cafb0fa7beabb4ab415b02eee1d08414be215740ad5807d0822683cec71cd3d5fa1d05eef1d5259519b9ba6638addf43c03d3659230c12bab917695556fce1a2c3f37b8a3be4555c83ee91b130267e650dc29143438a251fc5408c256a5925667d60efa4fe0644693c8a968c8ada22c0c283680823869630ebf792a4a46c1d6e52d432f03c77c4036916f5bf9b68585b6ac6ea49cf280f67c6e01f431ab32a9385aff32df388818af9b1215f622c5b06d34c959321278ae1539a896a32141a4284aee5a99388dc70235142c4bbc8741bce7156c94a9b0a7ee2fbe1646dda8d396ce81d7e1d0986ffffe74ffcffff7f6f1eb1b0d47fce77987cc7fc95789e2b1cc302fff51f50b55c63deb85c18feb8dacc32630d7d491aa1219fa2f2847b10a163f292a1cf85d38681973699e1b9814a8633ad64e43579f23521954a4f52ac5aa412094d926ad522953cf894f4558b54ee00a1f3bb49d3bfffbfa364a1fec750bf9b3fd522c9e05454b548b22b6912ebf4d13570653bd8eb40cf856ac130bddd9a1d9c149419c0c802587e376c9abd66d61befeeb3e5f93f03afa3dcffffffe883289332f3420607c6d3a3ac88920529a7a7f5bbfdd25bc41639798d9b7ceb8cb14dfb2ebcace5df0224a30eaea50b46b4ac417b14f1428c4b1b920d261a6bd02a7770a19551bf9bffe80d6aa35a2eb4a45aa35aae2b305023b73a7d6f2484641ca9ed96fbd0e721e1a78ad0d5b4a03dc261e508f57eceed40f7e5da96d6b823052bd960236ba28549ea061800c2a08aec5ed455955906ad71274c0b6a574124f5f4e6a3aaea29c91a1c4182da0e2a5ce6e0aaacadb71fc7f46ac488bbdd9a52eeede6ed3f2d1ce6e8031fe1a39ed4d0bb419cb737ffcd330792cc0a2f674cfdff377b6ad5600a42e777936ef0290164c1f3908921c9a468a2dbedf1ea98b3104037674737742a727401dc969413d493169ab6b093ac66b3946d19d3bc72b451a910e261c3acad6c091d13e6e9cdb3cf96dfe7a037e60b51ff7bff7f1e077600debccee7e020cac088079ea703d65d2a7fdd8afadda74cfd8ec2cc836a916290a835aa458a211af5544eeb72c4648790c7d199141a2421492b2c3169298121afd02c63516f2712b6b4224716a8a8f576b3ca9a1a14e40d25306bdefedbf28df1aa2352eab1e2e98a17911add8aaf36629ced36849cde6e6f376fffdd6eaa76e6da2cac27ac2c1f44bc7c4643a10da90c8e3065dcba56db2d08f7da8b721b4c8326cfc139c1ab76d392b897c5b5f7539defd7aa294f8e51a8f4cff574a6cccc8940001008004317000010000686c20181344cb3248cfa011480042bb468b47c483c40501c8b43a12018100485434140180c0000010040400c0e44e2703666650ff36e01c19cdebf867a302cd0a7cc27b94125d58558bf324a778b985260d98470929262278ab9bba5fd46d09a04584ed6155ba4e92be7fdbca0d7b6b7bc744243a7b9a60ad6954fa719b63a33d7052aa526b2bcafa3bbc822de44e866dfa8a70b2a3e3d3d5c8496035d1f25b5b6b0cc716464a485655934e6c1bb1fcda171e9a4aaec0afbd98a291092162c0d5def94ce10658a400ca123fb1e102b17d1cfbfca172de2e2819b1b8af5d80ac95403ebc11f4b31250f26fa68420a70562935000ee90314b7f080c78d519b5655d5b4f95c511a826275619560eced25997a455d11ec216545c74130e6a32b5d9fa162c401a50aa4317a14a8c9dc52e6fd4a31cec0b4f5119b0e942542323213a5dd22fa089e3cea61151a2b9d2242937cc0631684f38efad642da54a73948273f60c4ac1e9c7bd43728eeb0d591a92fdcf9803c62f24328c2d1b8854808d623c3d021f1f7078bcf20d83efafe613b8e52b1fdc3e31b239e4178c5f1657d1dabe7f787af48af07babbbd5f56f029f70b0b16757bd0ef51da4ed6cf29a494b6583f1bfcc33b62441e28559d7b815ba9b717a9036e663f48575ee0a3b2aa44d442a9d103ca86108781d981015fad87d335d9ad8028a5f1166d092c70acb0fbcd78c9d245f3fdc0674b4978e9838535f7410408dd48f057774b520b9a40d67edbaf532ffdca6616d5fee69dabde0482bf3e878319bd95c044014b5340f2354d85670bc7ef7b32bd04b62a6c4c563efb4a619bb17e2abd2246c3643d5b8d083ec7169c4a177b6f1baee6b54a27c3eb813741896494419d1df828703b2f849355ef1490f347b1490f487fd4e3ac653840425ae68048316bc2735b75fba733bdde4ba028a30b8e0e35196e8fe79b27d3cd17f903216641e070139da0a9a52227886804fd41a9dd53e1168e58268461fc84c47f0f8ce1f49a3a588f986135f5f78d109b41b0f64c9eedce1a77d67de0881c625f0e86bb1627c11e537092b50063c120d63a70ae1d1baa4522c49f2c5dc5be84ecb072f7581ffeaea1972934b52332e125c9729b39b9a421a98d871c1aa658748794514e36b9b9e7c2338ec01acace120ec0388da4d419f012128f4db1a22089a612affad99874da79b5c399043366116ff47f5d9c58df9228afe7adaf29e6c68dbfe21a12d7790510897b88086f28559c2214098763b7c4291456e5071efd9d8d0e8d6f64e37db3e02674be1caf2de818913af35d03dd742c7c6ae87bc38c1cd2ae2b049ec334358138352d73185952b5e87ea4c864c89dee068c3ab04aa61dc6e5c3eef8743ab288e6659a67e819d6b08805699ffa3feea02043afa9f941a8a8b12534800b73352967742f04a04f175e482bac780f9a04f36e8fb239c768b8ecb5a4996e9dbb5410d347bc654e38a12640c151e0ca99d68649d9c8e0638e0bb12832a069bef0403fcd5692637edcae6e32b7dd09ef79d13d6c46c47d3bc01c8e598b1d233e6305e9cf71498456cbf4c62a8e1d7090ff1bd3de1f069fab978f84ce016606f4e3a9450ac1efbc5dd0a0fbff5823318c03aa8b7828cdd28c1122cb40015f7f353b4f2ccd8228d7a71d19778c110989992c7ea1f4b6a88cc7d4eb0f079dd0eb7026cd805fa0ad44de62d0fff5aaf486a758db7960905cbd42719e6664c4d9f4c0929db9546fe20c150fddff1d4f589966a4e61861d2bc4b4342fb4ae05589a78207c811237ffd059d2f904b9319901741a267307b9af41ec14b3d20c85c252cc4c8749373cedaa9acc97790c452d95a5c16bf30e8cc6f1233bc1e7ee2b8417244b6723d2b89a11296f7baf3b3795da9c6c85b24ce8e2692821d22db46579988f539f0a738caac4c5786c61c3f3d09f0ddfa7d96e69ca5182947581166165059d6f2dc26c59a2faf59935b96bc3c3c61549a6985d7e6a16f83797ba92a94aaa92ab18cd824864de2d79058ef23671660ea230f26c396fba4c9d3d8e36752ce82ec24d5d632a74e8e0a094c530a2f41d3d6c221a0b3db585a94e2d2cd856b10e8861a498d191a16a387263804e9464e2b3584716957c67c9f735235541bbc18a1632976cbaa0e34625521432869bd8266157801639847d99bf95c1c3d13df7cf69456080789449db639d35a9131ec09938215f5127c525dc5955d50b730ee09878a5ddd53520ae59732eb536a2724e8118f2e6ed0ee7a7485b43a1b12fca74bd469988334b8fb464866684bf1d23d30cf4ad7520c4afb6fdb8e155315cf1f439e485605f6fc40b1ab7bd93c02cccadfa836fc84198ea527c796258df6942ee0ba51fbeff853d1b7c61cfea4faea9ce187bb513a5f8ac88b45890dde0ca6a1ed2282c04af14324c6d3764b2a8799feda0be876423dbd5ae9b46b8286e0e74a01de4a396a9b52becef00ac2f75010f9d9b9d0ece97429b8471d971b5cae9e142bd0cafba511549f233742e16c2d3fd59a1c0dc9980e6a90b7901cb114d25cbc39cd9f6817724dc83163e92f9552d325b9d8203fd44bf6a27578025dfcc4e11a910b4245b7751212b1304453b58d96f7c5c0cc107f0b19d1857979172319d5edad3e9962de0c028b00f3c447efd314596d27daf9c258b1cb2bf99a4bd7e751b6919c68a0ef18bff81757d8912030543e0bb3010028271fcb9971b223ef565f0bd7bbb55a69613dcf6c88c90b53d44eeac76aed8932c086d9211d3da3679f69dda4312da2e77600aac35552e295cd256009217fb3c0a4603d8933d7f02b0497981edde1b670b2a588f4c274650bd356a6207036482123b0404add0c30ed38cbd2673033a1f1163df89804603ab5c644eb7119a9aa6eae5728f2a8c583ae37752761ddd92edcc563fab849b670631f67922115ecaea6fe8a1d626c6b8c81f5232f54b49c94ef2b9ec6479e92568f64a7b5ee20853aa3b2b5db3beec1edba7b4cd14116d79403a7b0c6353d62ebf20c351b7677b6776abdbbeb27ae4e26104a71abd6b1714e9e2d33afeed97a3bb3880e3444598ecb91028fd11b9c3f45c373decc8bd2109a42f03cfb4b8cedabb2fa7a7a30a7160397ba49e2723adb5be5f3eae79014e3eb1d1b1d6d6829d32454b4154db573386456af9aae5111b351ef18f947a232b057a1f0c98b24240b6f51629760e3bb875d6ea763e48818ed48c1e1d798090c7351a319bf39931a210049ba96294f4ca6945bd65ff92eb7fede226cdd7df08849f86a11640b722b4aa29e15c76d96fe889d240f53e20ca390c8dd0d49a03f36795517c226c73442ba5b300a999dc0a28a79c584040730d4e6a930819b62222a59cb573092e12a6c7188eb2e43318c561cbff8088d36a9945e4fd8b1ab832a9da78033c84d77fe504a81d9ec18d2e0405de73cb890237ccdf0b3222b2fe21c474191e33a11b2c431416283864e689b2874678d5cdadd510a1e530ee056c75dc0e926398ae17ca0bd84cc1f24e0ca0b76414d67769cbc6d087a78819c312ed88dfe6e9d4b3de6b5f8d336432c1a6e6eb537d0f0588c9bdf47af07448f2bd5dc14d7fab882cef549a325891baf3fcde24aaeebd751dbc2cdf1e2b9b8bf8d1051352ee4e32931f14dd19bfc969a894adf5943059f8bab47b4bd93525bbbcc97c24b7eec32608b1dd3b747226ab34ee499a1b17dac950847586af74b2ce4ebd32022a6bf15d2eb5031ac71edf8049a408ec716e2591ef071b5988f1c2fddd80ac4ba20c943ea7a5c7822e559ac0b52141ed9362ee2d483a2386a91f62e6522549f808e2df22104b2b78a0d4cc250c9fd07a267bd06a3f42e6cd4a28884aba7d838a50fc3760da2a0103ace65666c18b033a6994d167a21d4dd0c08c9bb23aa270115f34c35b16700dd279bd941f965159bf2a23c0165636e291e5733692d79bc314074d969571510c98218deec3f41da6e143692afecc42fc1b00409877ffab7b33cc990e020c90ac028ebe0e4e59568a4060d4827561ef785578feef5d0e85a58601ded7c62219ab91aa235832654c5bf0a550c26417a562a36499bdc5175bb0ed2063a399fef0451b0f6478fbb0d135beb2daa1435cf382a0c3735c34fa5ac8ca26911db934b90d6cce2c8e247e09a0c1522675cb5be6070a282eb10e9bdd1471bb3f156d82edd1fd2958aa4c3686041b3b8d85ebe14843341ef412b3aa48b6e0be519804c7e6ce19f5edfdd5ddfdb015c41e80840ac55a7e70412a0b1f4212dfa43732402f24e5ac8e6e224a27d3884c8783aaa6743184257c3b1dd99dd21d5cf4b13d50660eee8cdddb0e2beee8846cd45d7336927917548df8af0ad1ea4232d6e5ef08f165d6591b18b00354a3a9072ff6f8d8e0ea4f365986b2e1ebc9f783fd60bfe528212239d7a525be76bef03d5ee76f083b2fdd13c4aa78f0d07aaad279cab2aab01fa4fd1beca5bf02b0d92c25fff720295b2aead4b1f096b81626a413d86ca26191ebded60876d0412152eb4c2b767d522b20992eaaa40c994046903fb3d13c46494c87c0b2705b9ce435a81fee4d079488aada00f359da3f41c7d4d4d23e93068fe1a9ea8a2238292519d9f8b9d39c3f290ce1414c95c044a128b898afa12d81c958bf8959d87347ae668b5fe9da2e20f3b5a482153afd847a4202df1806705fcd79d4a8c118764ab99afc5398aa04cc3de1464044841cee17284d89d56c794b80e3b146192cf02621fbd09f9215f8c6d5032c3932b25927bd8350b88d526f770f70bc4da2e81f8efbc87f21ee58bbf7b16b6b9a42a43ff5ec7a75354866ded4215f617e2e0ea07994443398669375108dcbae1cbf4cac67ab8b7b378e97dc3c3601175921cef0e5ae424cfe84ef955c97f51ba0695586e179858ab94ff0cdc222d1b62acfe73ed363ae81b457d30da9becf7a720ce25f80f3149878af6acb856f391a82243554fbe466803af82dc0114ea62919bf9554cf4267797551fcc7f6ad6efba623e336c9484cf2ffffcaaf137d47b4d299ee2b22dc0b5704099e2528ee920ade3fb5aecde439b25a068d699bd49c9df9cb376cc38d850cd418b657c18e303057c1866329e3299707d409c1c070693707b30470613c9b6c63a2891b183e5d24fdc89805e3ba8446d548eb042149c81288acf84a9a7dcac1d86183d09e909ba75d87bcffe6da3717ca3580e63a9553d8ba7cb76247db476eb5348d1a9130a5855eaf122e814e2d63b448fa2cac21acf1a15165a004d4b9c2f77d5f3a83938a2cde47096391e59031a7e7c9b739d3b1616af9d95057e893a4bc97322d9e8020a23ece1703e69820d773b48864c3fa403d16b4499152d0b4d91af142a1711b839a953d2f004a0251ae1735e0b0c23a4cc9465263b4aaa2ac2a31560b8507d243d23dec0e3c25a9fa87180b50b3ca6f88177594c489c6bf45d9cebcd2e06b59025e7833b528d81aeab5cecc8519a50743cd687d5195eb165a60216cb58d98798e2bd600f460cdb8bbb101bf6cd2c2f1f62b0701d9ac6cb97326a6655a5c39b7cd1fcd183990d0e93690cc6e711ace17edb5d8c529c00aef2c5194917232691ffef155ef53e272085dc7a3cf84d94985b0a802670b2a833ef829603b6e328ff7f51fb135ca16e729f065e0258abcc980966b3f5afec03a369e4848ead8899815edfb13a233750010a2c7516c034b05c17a077eceb6a8d993b0e80b1607da3da2592c080c84f2dd29df6acf6a92d1a656cdcc493d1223606a5942df29322e786b2336a366926358941dc795a99493bd32a1b0a7383c82c2b9e80548928b2a0392440d8b81034d817a4019c19f45ae8f9ace14026ef04fc574de675ce9a4fa820675ef65d9403170bc004880536d8ee11b7d1faee12fe3e63c65d5b6a028294b51621db879e2f58269f4326b1a52b2130e98a4c0c11cd28b05ca6095166f2eca2dbb60f05632ea9fc50db3b1a94680d5c94bacd4abef76856a8c776327a4a955cc2a488d2e2b922e9e2cdd53c19ed5ca259c8e10691f0afcd32c1e59291201f8aeb594632040d4152cd5ae12445c7d0423011bf41431071503c545a772a4b4afcf79c2c1d9bbac7468f39ce710251ba67c74444477838f66133175e6dbc25973d45173f7d41a9e5b68a024ce39aef5f0fbab8bb49ba900ce97869a70d7fef8717728aeb25001ea6ca7f9870ba93346d97c493f45360047e938074346f44ef0bbb5214bf0498a35d4b7bc1ccae0e5f320c418e6b77458a15809b5fd54e45d5903b444f2ae5dceee9b8e2c10f54cb1da28a58878b2707848b956fa4f32ac0e8f540748a1fb4e072460038ff81dcb8ef391aba966c83183fc1b62ca4eb98612aaa88c543ee65b74a883ccd808a75b18ef7dc063278a1895c4d0300cd3219954df85f54db48e3260163a1d37648f1355294d389e3b45057bbe2a72b1f8dae4db5568d6bacfad391f82fc5a266bcd9d4eb79a48c1c59b7b37814ce1e9fa82243b6a43879baf97fc8a64949e44b3113fd2a7b6cfeb2bb5b8b961109aa3927775994cf149031ce65eaeac804e54b3bd6055ae2658ed30e5fe26d415f949fb34565bcfc29ee6308e5ce701125733d0190289c4f272d92f07af359de58dc90698bf80020bf24275c24a885534df8e714e54dedb59e93fd91ec32b22fb0b19357d9d12c94afd3755204add22ba988f7af180bda0e882b2d789cd65e4df388cd31b1913681157738e27424750f27c8cc8b607439130074bc489a50e7a48959e5c709faa0c3160845850955ff2adf0d448af2b123575db2a85285631dbb8659c0d61212cc69f70b381abe26ff4119c7be9b7043651d5210c866e01b2b1b528d916bb0372a7948aa780583a7d7d9f9f67bb7b38610f63b5814709048e37b8e4e06e544a3d74427d5b657969b288026e712b583ef2eb38bd115c54e85700abddd0e29aaa2c3dea91c85bbfd54492269abd5988e328bb6c110096c76bccb7e3be0d31abcc930bdfd87f3c888aa2bc4d95832f1759bf853c33f19ce118de5e56b6434a7068b54e0e177672a961af04c85631a30c1006ae7efcbac5927c5fea8e77b8ffbe5f8ba36a13f402cc856d267a00297dc44b6f05d78bcbbe4060624543ee8ba9266ee58d68288c201351228c10a4395f3c4d12ac01acd133a0a28411d37f1db6e84f8517d03de9511f6055c5431970b6cb2fb094e56f6523644382bd6075ff2cbd602bc3cc7046a0b23a164afe063aa19114b8f02c441600d60f7aeb70811e7aa1fef8837e9e4d1ecd1af82a87170b2f2f0435fb1787e4b8071a2095319d2bd369df8ad4c87767cdd520ec7efd6351915123dbe6ff4591cd79c247ab14ed18f7c668c351e8de02f99523f124d7821c21086426c1ce89c6c97666fd3f6dd6eb2af0b8871bb6893d4dff5ca6f7769a704cc610baf8e3950251c5392832ea5581bd8dd5b9c0c94ad3c75cc57d00cf2fc7a84112494c6a73c2158c50653e573d20b512f4762a45438d244c9d75df25b15d5f2852fa7a6f10e7d696256ba445658cf2a9ad10d519b4960bf8b3909a46128def2abfe9feb3f7dedabc46cf692ab5f9573e67c3e37b6db83f9c7bcf693a05e0cf9baf9c712902bc6260790018624505c1d249d0ad3ba4d85c89140c08932048f04a6d375249279c0fed0d16a5920994d3e97256f77207fc426a552bf1b92d5e786f6cea21d76dab666180fa57dc2571471467afcca9b42f7d71703477d7cea483dcb353a0ddfdbedc31467cdbb01858991c88a19262d7b0b0880dae94c2a9e2dc392c2632369efd735c65b1e3469d29e2eafc3dd3f6bac2fc048e9ecec31db082204cc88af561b25920053e934855f6f584ceebee4a952b4fc26a9b363107a5bbe3b13a8b83a167e8f90f01de27a7fff583243bd38611194c921c992e8120eb953e991c3a4a4c7126a2d004787a0d58cddfa460788411718cba579a35649f585792d29aa1e1c5a2150330b49d9a013876a06497235f40711c7b34555e81f8ba774130205bb3da9f6364124d25b23064761ba0b383a6f2139a14ec64419a0f1db91d4d17e8ab8a7a63162b8100278539e5ba146685eb92f9dd0bee5f8b8f5b53e4883c6e8df6afa359b7826ac52b46f72be10b44a1ae813e99888d6e0d918ab09f1e5d7f21e3b29fcf526b3e018103d1cfec8d1fa527966e690f0540b928d180582d06975f98e5c0c852ba887d52b3a19498ea5b4af7343aeb516e291a7212896ca9bc7358da03e3d949eb05196d8c4a7c50820c64d84cb00b1c47a650eca5177e5ab335f4ab0b8e06071b1aca36494a888d5b22b01510767bd3576d1f35df520952ecba06142d4a1316802bbba2e56476ebd2efb25cc8386461075608b79f5152d238b654cc50118476d7c283d4453fbbb6dae505fa358e75c4377d6e5a0c035b51c812bcf663f56778a1cdcb98bb2c0473c03d3f84efc75520ed3ef309e7307864f16579bed9e67d16fdd1ef4cfac00a63a981e112c6bf4eee3ab267e8363dfe3b65dd0aae983fc241348aed10b750ae04609cc84e09759ffcd086ae1e44a06342658d780ed4fc6893c607e29d7e960082513172020699a0fb2575af8b57ab29cdf74a7babe88bf3ccda8fb48e904bb66adb80374a7e68fecef761cabdb46b9aafb9ccbd135d15708c072368067a120c3fe7a5be8c4e5e47f1423c0020018000f23a7d03334aab85a4e3d215382b5b48ecd111780ec742f3d1d204c489e497e456467299cb1287b3ec496536553a13790994c6ecc924b0701a21e5fa9be70e901d6d23ce847f9557ae5e91306a3c2b96af8aa78b0d6e82625824e73863bea021a56d24d37c635f2dc316a4c989836f9f66e08217a567d9423188ad38946e9d2207cc2fa8c9e65ca90d225eff2c9279bb884040e1dc1cc932ad7310f559e5a5acbf34ec4458ff12450b4cd3ae1370b518f68f7e494c6b23eb2c8717436c0a8480aa3a741b2fd112e404934818ece31835a3d689d4c6ff6825a477f4f6a4f3410881949f1523a52afb465f71a1f12d15358d700f622e142192def10ea8e8ad63b63ab1688ed19c3f7f94158f8d964caed326ca0aa40c226d61aff2411d948319cee8ccbab5e981056c935e0d18b821d138709d13247488ec8f92288146d3386099c8eca1287c120e741b92eb01353c1061e543d381b9d1a0d8c64f99a8dab9a4051649b61cad6f8e86d40dbf36fecc3d2f25356319df4f8c6a5840d5752839357fd9cf922ea070aa15416010d7c1a8e7e530c79b2aa1bcaa7dadeb3e40c8901e60c0b02cf511c6ec2ab28d5241c1869a76dbeed9a647ee48791f68a3cff4c7642ddb0b95cc56c2b81762b645601ec0eaa787686b17aa36f0908da9aa3e2a4b125ede183a8f1e04af707a1d5f010d5f7fb8faa254294a4fe1ded81ec2851ecd91f8bfe19a8ccb016dc74fa9576b9802763311036554230fcc160e18aa1033f46adad229e38ab8a5063c6d325e08d1d270a13a7afa70ceda4b660993c4de36476aa4e7d0b8581dcc2914a37be85f411f53384983e659f4ae9e6025360a6b546e9539c0ab546db6bd0ffd3f05c443f3d28b5c16b3f6369cbfa103121db4f42306afbda1ef2a88ca9bdc14aebc35f55d607677b3b3a214bc395b678310a260446b2591c399fbae2d806709345019b2a54e5fad8bf5043ca20fa2af95dc8a20f2af83cae10ae70225480adf23e9c5a462b119c4ad6d6c03b8e2f35f6401ac266e5ed86536ce3452e77022e7b5af5f67758d629f6459a766d6dfa2b4093ff3e63cb25819be2c222d5021fc1f9609460493bc91b8b590ff41df05b4186bfc16bdaacdc12aa684a87d3740ab2ee3ecec834ba85b08d07629a18e9b6fbac472cbdb05434e572955749b230781267888a871d82770b814f671d5e407a4299a8a7e33920df93821b2259d4feea2507ef3baca63912463edfdef4c4130c4de2de813f0ce23a5cca87c36ef6462c4a87f3b4b7a2454af4170760a71fdcdf611d454b76cce3133ec69e69e9da58c8cdaef9e5c232cbeebb8e445df7c6fbb905d70bd4f4eef2c2218771a0552c7f6f44ff328e9caacd6f758cc319582e09e4a44c0b6717f709f8ff49b6855a714a5793310a3520aa919731476621315c9ed79a8b957e7a5cf58a1ba4b7c8283d037190275312f52c5d7188fdd7ac22071aedafb33c07123321d2206de5f3aedb1c0c8538ae514a09c6bccb820743a594e982193e5bf4c9b35920036de165753642baa7c136e770249b21dd5399ac7099ae9620c89504c9acc4a9de57cec9af9e001042ca6b2e9a826ae1ecd461711c2e8386862746f1ac8d0c6087516094640ccf59fc344fb47ebd0cd16ecad73745b978c015598f85cdd4781b56222156d8b40b4da554546860138451920700e535326e75a7026058ea152fb8f7e325f70a3ee80163f1cd4abd403ed67150cb75ca3bb4a0abe8aba29b1918ea76db8c1ccd0698d608d89c83c76de26134c8914266e9bb8ce9e614d9144d6544143d1f416e030c762369a4306a71a71ac3d4b062b04a2839f4c90077bcaa27966b9e3f3d95b0c7c059750869556124cce7496a761d905a3b10cd2eada6dc0b2374f24ab4abc7ddcaf1a2806f857388fc8b1e1aa57c6d4ccc649d213e9668359f8de820253c14aa95851019785d48c0dc6299afc6a9f65e76bda4bb900d8e319302addf05d8b890f4d2b961921506ea2d063a736a3197bac0e9086b5723aee15cf1b476534098147d0a3b62c8fb4d636b0111f54f7e09360d38c9b58f83751d04d2a83d287ab5e661da8984c6786fe64cc057e5a54354d496effea3ff272463d717b43500d11fbc851060c1882b8d6d9b122f5c937dcd2578f1355ab9cc3012a7665c14495842f2d61cf67a5592855d0ee0c0c16e18b2ff8df10bb6686badc9c6ce8470c22e3fc8a2c48d008d3ce712402e688f4e3a521f19890048be66904374ec88b1d26cad91d54abfe420189fa6c5b881b2c089b4f0c7daf9aea488724393ff927fe8917227d13d40e930dbbdedf4f8d5119fa8e53530151f5f8714e651c24ce725271af74eeb3fd5613fc113daf85cce9ad8076975d82f47cf5adc4c54436a1171c8af7d955b65e0b81fcbd03e1388825c5ca8df94c376c1b16f340ea623b492b63cb8ec1f4627daba105041c2ce509a84b5c79c8bb28558a99d586acce6800059c025d283c0414434369a4877898c209fd3292110cc647e93221960e0e73499dcf87c890302b98b5537d4fa866c24ebfbc10021612b355cd09a28ef28e0c9af0b1142009a4979a7dd840a1445f4d6995e8b5a3b0fe7fadc9916cb3c6a7fd412fafd3030608b8c4e6ea4b254261cd138d08c4ba5ea8ce7ab3fb409a680c3183b7bdfcdd41aed3905bc2d381f39df197c7c7e431a549124251b9ab71dfff37075e8f3be967903f5ad6a839871da4c5bcb7e758682714967218610ea435566644949a12bdcf20cb5f754b53d194d43783e0b3c2af7dc75723073c2e93da812104f70c917f82133e5b1839d57187b6929660723ce7be5f31e2433fb00431c04c75f485e84342ef749c4488b79403f4ba359f83e28720b408c91c9a5d1505cf36e4ecf019799416638f592fbb138c0eed83d8b4f30c8364ac795c467da299ba6f147b962b23bee1c176011503385a4e4b10782f01709066068d738e4cd2022c375eea0303feaa339540719db0b5e50bbc2c32d62f2bf60bca389a153dec0ad63bfe8010126440a30252d2bcbd6a1ac38a53a2cf423d488f5804ef55a13866b0525664738eccb3f4cab549097868b6ecabcf8d7b6e5c5c20344cd9d4246c54a9f3189abc94222b9c8b5e4ce4f6a30957196cde95a87c99bc5e986db135a7b50dba90ca324d49f25d8223d3e3a40191a8c04d8f9525b18750ffc6bd6e5c0285dd129e043a849a0a77f1424152ee6f2d0c6a20a335e9b2783696f68940a537564b259dd031d4b9a151c065dbe344e3a5c099ffdd3cb93c95d7a2d279c250fe4b722ad8e24287b8c12f56171520738ec750e7897013b44d6b4cdb8d05ded9df5627f23079d2bdbf27358c056064d5198d90900ad336cacc63d2b09575d20a2078bb5bc0f6fce6061287a109d5287124c77ed039499027a09ae675920d23a4a074678ac311819aa495bbd4dafd07c4acde745082263e01228b94d7f03eb81c845720ccd75098d26337310388805d01b0140de15daa4e7b0b7b5dc504c78f55e0e4b03fb1086ab0e8e26ad91bd0991524a99524a01d506440612063434d12d258ee4c5abf2b3162eea9612cc07959f5fcca5596bf4a549e5e7a366d1cacf5d9ab54662207118ef3dd22cee722a3f73b75a5868968eaf38489af5c6547e56d2ac4746e5e726cd7a63547e76d2ac27a632ac1bb8b2dafb14f8571d0f75fcb620cd2d46022da67822480b1a9668b165686902881d82d450010b2696e4a7861fc040288c1d963cc1317a810c76a0c410535a9044143c9822842ec874f185056f901144961fcc48a1b25a2d9668f20ae2880c93323cf0051131a0e2ca983345bcabf66b2e308419675af093831251ec10bc1cf9e00a98208e9a10a1f46b180c22925002892a58a648e102898a1655ec208aee6e096cc1248724729042093548c00611501431718498301e589d7d2828b7252a9e10b3051b44a09185090d293c3cd1050e466092f4a084ca10c2c8128412567cd0831467aaf860040bcdedaec14344ded269e225ca14384c016507177740882caa50238d2a4d8471f1f31063696d4873fb41347d03c6e94b4d9277e1047bf5f0e544812d67a89081c50735ca70d1a860cb196134f1e1891f2214889c08084f60423c4823cbe18ba01bfcc006195856cc0f57ba6cd1240666bc088a6252a2139587048410427f104208218425687afcde7bef41082184f01f7cf0c107217c0edd9f43082184103ee8fe20e40adf7bef618563de7bce3be79c26138d89b939e7c2579a317271c63897c61851592ad5abc751020872fefc3d6666e6f76673fcb60693129d8a78efbdf7efbdc3f8de7befbdf7de7bcffdbdf74a2fc6e71fa3bfe7f7627c2f3e089f3f94cdf94d7cfee8b087fdf91d674e4a7f2725aac29de18b5f84524a975b26e54f089d1f7e4721c3f79fcd925b97e04fb9234bb2f38ffe1d8d5a003ab865737bfea6c6153adc31c91edd8eee7f04c1e6cd8d8ca71e790a9284bb8ea8cacc8f71286a3586725c5de3ca7acdc187ef65af2c08b0a8aaea1a79815213b1f7d152b2f7d1524eefa37bce39e79c26138d89f9b4dd7076eae11ef8fcf065b3e6d625e6cf66697ee9b1ecd4532a4df76ca39e35f73adee8b6801c28fc656d2b96329d7abc04b71b54b7ea9688cb6956073f426c7bad7a1f5337f5c518618c1f9f9f7a1e0e33f3830fb25e8b5d4d54ead30c8cbc34a95a5da33080b26883183f4892eacf1536d14b1d49017a97dc5e77dff3b6e7cfcfb5fcf4e8c13cb8f6e891ea548f54f7783d7a742b0aa520848516be184ad5242ca6f478610145ed960bd2982d432b57fe9b2f8852dddd29f8e8c1ca028a152582ce609205116c30017ae205435418fd48891d2347ee18639c1abb4a1a5cd57b3e0129d5f8582f37cd5b24156e52e69bb01f13d85280e2d457b11a0574a133055bb8e03244c31763d0f8c0151fc2083194858d334662c050f90923040e3c1052028d2a6e2c49c3cb1b2e7eea73660de082faaf76387515ffca5b4bc50c7ad0650a2957b45194c4062eb278a1220824be28c2958489164bba486222ca192f246046084064a14119314bb8785115a77a1527531324d4032b590fa620e3fc334bac9bc58d2ddeeb4566e88a1a222624461432b0a20c157861c00e80f001cb0d3a84d10388a591c4a30a1b10b9a0b6aefe20cca33fc8aaf8e7a4bba5e372d4e582c398ea5b47ab952d75005c023f1deff907e99644f22152a4595ef98f346b8dbcc052f9b7895e2aa85d564d425588c1568c19a19ea9fc9c3580cacfff6560e5cfe1301cbb8e15bcfaabe0d507c03cfac41a78515a7d5c13d21c07f9e1df0989f8bdd79e8713745d25001441bb2f3d7fceaa14b5225a2d49d73a8da67eb7ce1ffe6e9dbf7f6cadf69710a58d326c304345d10a843062b70871831831f0c2e40a177c310365c919319270d021c913345082c4182a5eb090410951e00aa7c7b4394a450e2fbc50c207213040401ab8a2ca96a3206e188215ae124b27b0f5968e0874dd2b67cc58c305990c8104e4d2beb81250c3cb869fd559f26fa95032a6f21643d75d1d047418a531b51b0b237e30c1ecd8e9311f9831dc80e20d355c40831f0404a10a275c9e6cf1fae132bb8850d7e8284ba5a96b74948419ace705d6a56409fcf74be4c7dfc782f830b7e3aa7ea811d16106e9d05d83f7d87b0c7001edfd77d5db59577534e5aaf73e3ae707ca519ad536d06e5f422cb03cfcdd26130e1cb523413bc111026c4149789fd2eaabcf7dc02de8cc0017506e75fa6178b58ba0f0e3f3efc7d05cbf6b4786b8aa17a9097085765ca5f6f31057599eedd8bb9d608b834289f0d8fd7de7ee9ee38a1c57307bc79b3b7c1e25c61c2ee4702999b7211d30b30e628410aec6012dbe2cb0c5e1872a826af797cd1ca96d41b8e13c0ece6b56739d230730ab24d83c91fa1e562c668b450889e092ec0a15374031de030e369cb90143a387c084260b16924c1737cc25c460721a020738c423dccadc02a3e1f190bd7c06118b86a206fc40cc1095b49b56cdc775a2eaab6b944699daa58886f879af59bdae1ffaf37eebf71f6fc546e1bdf727bdf3bcab6dd0d8aff789b77a67b572eeb1cf255693a7bc2af3a772563b3b54ee318405c8fc2f74c141ec8425ff32b344eda0763755e2549953e5af5095ffa47c1a0433aafc541926aafc5752e573695c51e5c7538f5cb50840e49ab08b77021a30f052fbb1e47843ea55df7c65b239c60f6464cc05aa55fb670fb58dc824257951fb61ca0167d02e6bb1103b16dbede8b1bb650c18cba58c25ca7855ff372306d59f33a34cf55f9d2145f5dfd9a1fafb489ae22f246ac648e151fb1d857277f7414975779f02187343ed67d4eb60e6cbcb0b13494646620011268a2ada90e2f21942e4c73ba3fa0f5a54afbe754532947f97a940b91274403b9c16bb960c336a77635ab0c5993aa4c85f5784aed2e1afc37f3914aa91a0cd797723a594524ad90ad22affdd88a87cece787b704f831a4bcc27f48ea03f23228437d40e06905aff2b136e26f9ca9f2df6902fc4635e230c88f61e2f8632f935a09bacac7b69df7d118f12ab7c5f10da75970436d52e6fbc62625f8fda4b70e424284c88700442eec7d743b79fcae350f2728d675d0642dab9162d2146d331d24002fe8980a7f0435288f018014da6d125369216f216957f6f079cad64273f03522cdc187cf3aa21d37a9f08de041090d153e7c6a44e177d0f23c317d940abf9999fbe3f3d6f59bdeb5f97dea3171118d002b487aa2ce47d22d2547c8afe15d47cc87ffc29166c5cc03731bd21c7cf852f3690e32166f611b1276651bf6af71ae821db41a837e6d21f83d057e0741ece10f69161381ffc3dddf094965fcbdf7de8fe6a00e20cb04a6ad5c051f6b2dea88b183bab563a89f4469d650b39a68d61a8d41d4b5960a798c97950a61135518b9194bb360c7499cd42c6ea259cf8c0a99f73481f5527bdb690ebe8f763141fbe12f0edc5c68247a46ef844f00fec72fb78ed64742aabe85a79ef73c4e03aabd4bf25ab421aa59103e076afca7755a7dd09dc28f59bb6297d5b715d16a8a7f88f75973a8e7d585f7744773efe5636fae20ab0befe3bb8ab74eabf0db9f3f7f0e5154abb059f03598357c5c4da84d307facb3e55e1335ab5b0348da6de24243d4aea954ff15d344ed1a8b1827b56b2d34de2f2eb599f955e8ca3c4a306bff9b00e5c7b5cf2d0f9ce2aace6babfa176ed9f284b42c2007f47d11dcc29a10bca2fad3222ad4ac0e0af594e698ce147de71e8b43228745f0b53c5c44f587519a6553fde1146f2571796f5c11f5d1cf1d7ecaf5d3efb93b8428448d213b3b3b3b3b7b7c87ef8c6276767676ee578128640a832d0568ff4421ae8876b33290b75aa8a934cb9f534f2abfeb87762d14000dd880f684424210f20da010ff684e6a3fc4c25876865653a010642028e42d2b28a0f0b0782bb5d34fa8e3beb6417f6ad72874058eba51fc7c7943ef8b287ebef0f2f305c70968a49145881cbab08110d1183a8ca1c18b0a0d42a091af2e324c94b9d4df57757d9a952df768ca5bcf796bb5aaf73e56f57ebf792ef7de6ef7428531c6cd889456eabec7fafddb1f0dc338ebd6b65a47fc5502345df34b2f35a0e992bf5a3743dd1fd7fc9256c38e4b96e055f83a80b050859b6fdd0cd5bf4f3ae22644fe561fea9abfcbd3c5d701c454e366a466b7a8abda25a9feefd4b3ef1affd4a982fd9478b9446afcd5505f1942f872c31e3f6d0e1503acfc6e9a95bdb8c1f06a0cb0f2eb1f60bbfa015d2331acd4ad625059173f56734487ff2659a20a334748548481a58c294498c982861a406798ccacb9cd62c50a228e66d0c3153692f80284219640628c254f361db400585023304775d3a86bf405a92a497aa14b0cafc27f5bb748a71564987ad31ca7682a0baaa023ade29fb4944afd77ab9a3d638ffd6eddaae2f8fd5dff6c77f744d39ad68013740a5071b8554d8bda7c57c2f11d571c9a8db6abaad17c786ba75f2d7b373243c5301acd0857ecb177eac99a4ffda7de8ae054ecf7b4c20d163261542cc36c58239592bfdb5b4e7308a8a24b0de364bb7477ebb72c8f5730672abf32987b4ba139fe1fabc38f002168c743f588b756ae627e467a361c591eae6cda62376bdc721e5b3ea26bf4e55519cb909526aa0e0bd0af791fbad56c3af66b7e5d3e2b57f1ebd84d88cdd35f978f4662a331e5d22605e59fed4873ccc388ee77bb464edbeceb602f6bac469be3a16eed16423f3f3f01dd7cd5d809a9f05f780c9b1dc3987fca7e5fdc0f3f69ab1ccd0c8d3911051e3d5228350002a51851e089c08b71db41c1b4752ad4f7fe23fa8ffa8a68a6cd55c1c7b4d2732da4a6f6e8c3b09d66edec69e4454a29a5945246e906950b607f489e0c556ab0ce50a5d6d56118bdcdfcb3aaf74040414153dcb7056f3196451a12da76b7ee77398cb7586855ef53a96e8bb6c85fb745dd0c4815222d518d713342a4b65c63b9a5d8f2b20d4df74235f2428554ca0563a2e26f6ae9deaccebba93085aa316e14cc96e58ad2af492badea7d49a3b53341853342235f6e96a7e57c8c4f405a3e8edc7038f9ce49c1b620adf23844a38d08a82231870b71c6a8031f4715c1bb599e963348fddcd9d96e5539b9538d1cd9b1aa713382a442232f3c108d3fb1ce620b7bd3ef635a9056797c3ead60aaf1b118e306c3b4110155646a2ed4a8e5a8716a22a851c351dfa947ceb9519b1198b492465fa944634719fc18e1099532280663fc311048cdb997e6fc23c7ad7afcf07975f1a3ea91591d23d58ecfa85cf8c548f1fb3908e6c1537009fe0c44edb81a37ce414f0eb4e3a2ea70bbe12df2198824263436628c31c6189f4d5d8edbafcebf942f8a12bcfbbb9b7fd90d8c6e2b87931db41022075da4e860cb0401a9882cc600a34a0f1eb060a6702264460a285e7089c195970f5192c862090ee8fac0e8568c6e0b0165dc90220c17f0c005071708b620f30518293f3418c3b5bfbb3f777f1f40849473ce39e79c73ce39e79c734a29a594524a29a594324ab99252164000394e5266ab4384539152ca18ddfdb9fb737ffed3dd9fbb3b7408e17377777787efeeeefe1e74871042082184104298c16704e4379d4e77e8d0ddfd3319238c5146f95ddce8ec66941242097dce39e3364b5be9f418218c70be07df9b2fba84504a09a18413ce09e7bf87704a79ea91524a47556eb583ce37df7c4f7e47827cf95da9be67f9efa156e77cab23638c31ba0c34789234afc6dd4dee73629808d87b351bf76c4e3d6fc379ef6f7a6fa3a66dbecfe68f79ea2995a69434db8dac39f5c829dfbff4b649e7cce66335a79e395f8c349e4e3d71cbb65872aea51fa7538f34c920cda5f0ea501dce10161e76ea812839b99cca3fe763d8a9679a664eed503bcddd547ed69c2f4f3d73ce8fa79e0957a8147caedb51fb4b988276390b3b831f5f8324401bf8bc0fb51a35adee4905af11466dae0e4b1957caf84c8d63069be50d2bf287c84b26d4a50bca055ace90510249ca1b5f5cac64ca17324a8e1073066dc284048616a41fb8d1047da309123bf0d0830da6a4202bda68830c1928af62ac03c8d665492a33101866ed77346a6f31bc9aa4ee77dddddd5bc71008a2dc1ddf809fc02cd50547a136cfb970eb22d085f277376f890518b6cdea5e8da946f17cf8e4b7d665153e26775fee369b8390ab08b23ab722592dd34130a3468deeee9bd47bc6a251e306a146766ceb1e7e27ff3d06df7b08a47bdf4529ffc9cd7df8d4ba189e9cdfc52f7d6b1dadb1ee09084fedd59257f846ed92d4cedd5f3cf5c08f5ad7b53b585beb2284f369db5c6b1dac6bda669f6c3384ed2f4ee7483db94cf55d8f52fe0b314854f53e7598e6f8c7d40e55a6939a43d27a4c731c46843790da917c8be51e94013233b3b3e7a0c5eeeeba33bb3333b3b3e7a0852fc1fcf95fcd0dfc3bc652f358a8b65aa87fcf40d8cb5503c7773b36dfadeaa3df71df622cae4279a146e51612e22d1c5bf7299bad4b516a622ca7a7d93a5ab375a9eadbbee8773594beafecc64a262965499aa47cb486e66432a1321356e249bb54f7d977ecc566a9d9b650d4ec7dd71f4adfdd5d5fe8fddb4435db8adc5394ba6ff245d0bac855fc53eb2ecdc9ad8f9ae3d21cf72b023fa0fb5d17555ee171ed241c7d12b3dc43f21eecd784dfbef7dc99dddd7d352333d485fb36a6190474a05c283f163337fd3084cc0cba9fd535526305a8336837d7c8cc1a55859744cdc44c92a318dacdda14d5db6a6747735c387138575a7ae849992221f44e3d73e5930ae3f4ce11aff97eea992b6fcd2e91e1e44977699b55a6b86aebdc966dfa679d34494a9386f3349b93a6605d23334593a82444c4bead1597bacb8d55fe1643dfcc72703835684d5d231e7ca9fc1d187a53d788073ba8ddaa7a4145a86bc4832b352f26bf3c3188901863d06e1162b7cc5fcacd2f5462aa93d935b46d6560553eb721abe37fd305ed9e7b1cb975947b9c5f9e2804d95829a59452ca397f3f93d1a5cc761fc297479bab7a2f21450253612bbf94f752fcbb9bb78d60524ffdced25ff9585284e9c518a3d41876c53a8b2720a5b8ad94414437a86cdfeb52a954daa1c32aa747a9542ae1d460cb73fafdc74e1a579bd5992f021c753e8db6abcabe468b800d109b5a9a5da396c13541a93e68da5e2703ac8f8666b1865e668cd187103d767254cb53fa928d36174079521b45dd47c06243584a0e0c393a3a82f34938a19834f5465ea052ee4be275133b468edc269392ec4ff135ae27edb427bccfb41ade65b327bc8f5ae7428edac5506116b58e0415be49eb4e329befdd342b083a215fbfc78f5b6e37cd9bf3f14097a76b440105134c50696fb32d135cb55a1d9e1e8a484921957e5b9cf8692549fd53d72893d43f4e3cc13cf88b1362b48268c761c28c712208fe589e2572f7e7cab405acea3dc653dfff58202b77b52bd330cd455021bb3068b33a1d8eda356e7475289d13baa0145401d5ff653c72b804ff8d31c618638c1a1a34be62c481cae1421ca18b31461c2284a0146d441051cbc1cf34253550d7ae095d002afcd432007e8e7c7f1c9739d5c4db3473a3ab03e5163193c9d4416ec6eff3f244b9fc989bfbf97befad18353e8debb441286775245b4e54e488929d26479bb4677e184876393e84e8b19323a594d3c4f1aae4cece0edd997b026253e78eb7861ced1ced1ced0c393a3a3299849abcaeefbdf7de7bbc1c34c26fd4b7ed6905196a27438db02b0f34c618638cd10140efca7eff719af352494a56ca01800a3fd502092018a143ad0efc1c2ea0a8c944654b2643425182b414bd8e82849e547112240403bf9d2868c740404da41c32e20685d3ac7f8b444a2986e4d1cf7c6c6a4024c310351824fb9b1b90579f77a91469b0556167f7f5e576773f0179d5b75d9dd4ab685879ef35f18094529ade03cd8a19cda9c687b770fc22b556ad7229190e16fa635512474ed95995fc1a8d2809161a8d5b95fc9336250e1d227f39c9429db2440447cab971190e9765a53645d152f43a8a314656f2dfdc09478fea971131c618638cb3a8e89f015be07040b8b2524ab96395d3434a29717e7e8f94f97b5aa1a6ce257af5cf8f927f6e878f2049cbe577b414ed6b8f581dff1cd1218624fea13495fae7b8ee89de0140d06ec3b450444a770de13bfc4483c9b95cf638d9c36a3a6dbb3a596612d29c69e3823437420fb4a666db56d1deace1192f213eddb2f93d5a771fa5df5f57adbc554363a371935621f901020a8232c5ca51130c244465084b64757b86853dda337363a039a79472ce29e59cd89c3060524ed3c4302993508d95f409eed39cf34f73fe43dc3f95a21408c9eb8c101f213e427c8408f1a9a1f1799db2d4eb7d52294a5d884f960969d6ae56a5c6d6d8e9c1edac74c8e176628c31a739aca39566e35ae5df713b0d80423baeb20e3c44b4db229ff7671d96672717e000153e37845518e8f6cc009d06dc7156077e57009c0dd487ca6e1eb250df5b157c53568ba070fe7182caa0ff668a03b2aadd910abf18b2408edc3052b6f0021220274550c2f00f37e1207e22591d27a44a90224e4a29dfb9d5f2947edf0217d8c9050523b563d4fd9832e2b2cc0e85ba9fa2266c8b732347aac9f43f8a8a3093d67140ab32c61827d625a95372de6ac155fe736253eb9240b159eafb16e6a45486a9ae95360e745a25f2596681e5e93a5402a206ef4709ca7924964c104b251851f01e94419a4cacad5794905242a1a99d74b51c98d83172e48e31c67e4c829a73e7274254b068f92dfc64a809a2a25775ee1602e73b28c618bf3a26640177c98d9fb8ca5fa382faae8ebb388883504e245da1325e8f48cbd01011162bac0c11c1c0b5e3b81411b4e32953a8bc6af0a494524a294d272dd3e673496317a6459a6e84e5a681251474b13e77611a5c20b44a6f97d43a192a7ca5d273c5863d20f2f12f34e7718d23fcd3849f342bca76612abb06073114e729d579a8fa4766a159dd8ef140b33a8682c876d9318fd318a5d1901c7982c6e7d29cef13e37c9f58f2d27c9ff93e83974adbaecef4d97ce4e67fd26636a4394c7b57b99494abfc45bb4dc12d85e64cefefc3b46dab887e45245b0221a594524a790495524a09655f1533b52b56b3e1807944663e55e0fdfcf0725006588117dd8ad39045e256bb4fa30959d5fb939669bb2a6ca7b4752bb9c58db798ffa844ac9a8872122a5424010040007316000020100a060302a1609a675a04f00714800f709246605232140843490ec3288a62180a22c600820020c810a20c23436407a4709febeb74b74909e4ee745f2a7ba9e0382231ff0a073bb1f65a2da3f6ea6dcdcea0614948ff701a838142a9631abb9737a605e93d07d57ee8b7a51230eafff585b3b3f00f578cb6c98fd94445fbe9424b12ef9a54d3d8e3ac30f1177165dfef97e91e33f29b589237a260f820b1da11e6e2b00270c912f120861744b7b195512dd757582a6a8da6e9a0c748aa1e4b251caebe89d40b326b1416f3a2110d5acc1c20c644cf4b1341f27d6b54860b51da0619d0082c1d537d04775c242fe0798ab254dd9ba8a667dd4dc7ee178cd7f432d4f7126bbd0013f6b195e863746494814615776affb67ac4e36909e98407c19a805ea26a35cb811470a5e2dc8463f17bb589deddc5bfd52106484ad4c3c80e54063972bdc2f3a9d7c824ac29243ed6eb40675d1199d66469f60a256b6ecacb30d0ff290efa77bd65b916e3101e819def34df2e3de4266189b5e840372f7b0990d1034a4491879a50021f94afe228f410783a75d091a1634ecc8e560e1a17fee81f23cdd0f292db41d1a698962ed5b300111b12c260873d615d268c5683a128a3d4ca92f6ebdc543587c8659091a796f41e90c6a8354f88f0304075d4812d769a063916e371f51792ddfb6045359984cf428bf8646f28d8eb337deac379974ecfad1d1475448dbb92ffd9e9cb0c274fb0215f79ef44fc66ac2df7fe4331a92410be216ba2b603036b5fe4d46cdc860f0138b5b19cc6fbcea2d4fca873a8e564ea611aabd254b2dfc3a318ba42b4523fcbbe7fa121be4f87bd207d3c6775be21d85eee7fc8eb6b8327f98e076a9e6ec52740663cb73be2a8fb75e34fc56970a25c72626e8de82674fb688b0274109678db4af013cbe104c5f5049ccab5a304ffc39ad14df344162af50179b8d6144c64569651de0a7421c91385a9302ef89d4d2640aaee0a3748ccb1a424253b6701adb4081ea03f923cabaf09fc14de156a5f34a7e68428120781a1bd7d7844e695acc4f2fa0cfa63bb3480a620720aae01d011e9b6a6211314aa9a08b411ed70677bed950d8531d3255a8c305b6d7ebdca1984b7029f05facae746128b45e97172ca191943fe52a0ac30a525166b8de36fe1cbcdf23e5c8142a218751e2766ed006f377f59e4d2d52b3dae2edae313d4bd6ecf9d8407e56b62ad1326bbf97862440a6fa8e3e5b9d163c9e53e4650bb00662400f635a878118f90c560630f9aea8ec0a13f02224cc591e6c0913bb32a723d0b30211607094382acbff6f8a28301ac3be0d5c9dbde1c963536f81cc98c6f269eb9770a55192b00238cf29d1dd23a201c6837d003df87e9dfd881cf694758705813230c08dc2678c8ed0f2731d96634614d6e17ae65e74315b0ddec9748682e31708d8cde8cd98e8732de6f237e09262fe6a5bcd8854076fa8845bb5e488b0f0990e1b3c53dc65985a73d615bb60877ede6ca083bc606ce95ee564e9f6b053c6417ec6a717d482bf08af10371b5ca77ee65f310ddd721413aebed21cc553f34ff705b90eb9eb77928b958bce4f1832f703725150f3e40029931b7b8d8373c34586e20f8dd0a859d82e2ea51679333356a2b5e653f1b8e1062f29b200158d084d2236ea306791b114a357f864eb42563851c0e88c7f1f7c57254f3f9730d048f15d19abac55938f8ecfc068486ecc0b0f31722b930ac995a5663c4053e5b2eb01205b3d5ee547a623d15ff42ea98e188f9f5f5855c46eefe288aec3f2cab41ed2053db01bc4f0795264fe18b9815b4b1ba7b25ae9687c655ee6a23d61dd17ce088298994ce094e9639a880adcd6e6477a3628c5c5c9d42c811bc249c62a035bf05df413dbaa5d10abb63601ccb09577866800734c375dc73e1c1a4f815e8a2d6e2b218a0b45cb306405ca7b27db5d742d4501a112f0752f4999ca0d9d0d44cd1e290ee8268ff42f9c2e33e4679459703b445823a41e8d84c4320a2836fe5b4ce5c7b8c681dc39c7f865a2488cdfdff5847e40576948758a6921eed1393e263b7db72adeac8dcf541ddf45949eb371e24e3561c6b03decda4a441b55e7550fe6692a402d7a63f9046c007a8d5fd88c27f8b90fd2b040fa43d28797fb99f9169b5ac1802dacc15b9f0377c06a18e3d590e2c2f3f26981df215a0ca95ecabfddc7702ee6b5c72d8ba2013e2aad4d02b31569b6ae703b79138a737572ac0e0329e4cec9d689168bad059462fa60181b733bc6ca91fc9995e05b548018b12daa0b54c7b6d4c11a1d3a4bb4c738548e84dda8f287e505a0ff603fb070287761c92abc660d9d4f757efadf00ed3893d57ee5182292580104931628faddda8c963200c77151d56507555668ad62db033d619ce0928712949016bc4826aa650c805b1410fd0b65609ad2b03a1755861572820ad557ca1e185398922ca085a67f245b0bd2b206466af02ee837e570cc72a2750e0812ef2404087c517694ae6c92c2c5a8afa42570e2eb070b2d2366a40a13dc7244f6cc04d5aa96f679a44843de3c4bc17c0714e998ca666df1a34f71da54617cb7874c0d94df139d5bc13a2a521b56f92a4056000829669a655c2cbdf55054fc40c4b38f90fcf702d8d7c51d18f3b2b430f8fdf0569587d94dd4fe72581e3578afdf2fda5e61e9184b4623d83498556a9eb186704488c99b911a158df79c988a88be41712754a219ad6ab96c0cca3a805473640eaab44b11ed6b28fd700cd0fad0a4f52bc2b2cc8151bfdae0797a7392cf45f0b7747722a4762f06000ed65147039d50ff92149d3b3570f35dcac36d174e09b77757ee2d91dcae98c379d69315a9007239247f4bc00a5db0276943e82ae536db21a26ec2310ecac5a816da0818277cc96af5c5ee7ad965842b217dbb2a4166b2e0074d3652f03193db5e420409ae969850e6865231f42f6793ed5a70a44b7591ce17a83adb3b7c154599c07db2ad00ec7364105b222ba49e2caa8b10567b4bcaf8c7d8a8e2a1ada2c0b70eb224bfce21060948a7c2423d3192f22eef6f2e09b6b3414c759f2f260e3e2f677b10fa84fb7f1f7bc28e4080f634794f274e3ae89b62b4dc1d13f7157f38d201f9b5d29e5abcd921694ac93b9c8e80292ac58b3b6e7434548ee23ebe6c6420fec836a2a0b7e7714659c310d3bc03917c771873b2b75bfe85359b581c0ca92aaeb260b5b7bd89a8388825e1976be1ff43e9de9393f5909d389f64e4ea2f26841b88c1e0c93d21165d646db5d50ffa84e136ba5fe25f61ccfb9418aceada1bc6211549e6060537b975cfa25a7cacd9140039b4ce06ffc771659c38e4b7e16f910518551b1f36d4e99ebdb6029266e270e6ce9f1a27a574d5529c9c6ec0b01bfc0cf82bc35189184c71d55b80f9b2315e462ccd596388abccad226a4358d5c7b77f04068d7a0fa42c13ae0626615ac73937a79580183f0c110ee763c4a9b8e33fb7677afc8c41beeb614dcdd201f2a521b0fd471f68040ef87f347f005e2d987e1832dbe9d800a3755955f7fafd3e3cf450858106e5657e0f51eee660bf6883ad09c548347ad26a84135065e5cbf1caae918674550e50b01472dd807202f28cb994850e618aef7d7d4b8d05a9587521596bdc46bd581e1e701ad4de8ede4873725dac3fe1a5031fe1b82bf1b274923fb7497a28d8eb44d853c699521c110c23284b260e84dce92a1631244ab76854ed497162381a481cb73bc464aaa2774e1ef4aaf63eb13bb5705987b7d13661939f31f58e4ac38c1368a10ec34abc2d437c2d723b8e7a5b555b25fd46ac90ae80bfee5a90898020d17c6251bf675428699d36cfbe62c117a0f6efd53c0d899ea89ee042c81b23639780580238137fecc89099bc3ea99df36eb79a892a32b695f635c095c6d701c005d08f539f9a0574bfc8690f3e6322bbd25a2de4d4c0604e667e367d9f3695128b7a254045d779a9d79122cb94f3c8f9800bf46f1c451045f3ab7b96e8a049aba0dbaea2aecdd99bc803b052952acee13dc5fa044b27b0e7001132e9d2d31bb79d184e9b35255e5ef8d5816be93ddd5dbfcd1c339da9650bcc13901124b961562f4e63b5b9791cae6ac12c0b3d05668f2e2298b950676ba8a861bda12be9af1a958e317ac72533ec0bced395e3ceae6f1e338a426ee0e0ddabf871eec3f6b6a43ce176f9d5650d6a3529d0cdd3865519398224f892979c00ac56ba1f4bcb8da13627bfada9d0b76a1f987833aa2fd6e1861399f0b7d5454b7f8b88262e5be962f40552d1e29bacf69b9e7209ed913e0c0a23a0355aae8782e87de2b8c2d42bdc20d2078939039aa5842f3a1132785a8a8539b20038f8a4cb325bcce9f34995385c2a4cbbf74887873eb2dbd233f5bedb9a64b20382aaf8ee4340e69baa9cae0fa019a402426e0ec9f3f459dcdd1596cfaad2c539addac7f5e03c9630634de598dbfdae61cb321c9f57b735dcb866d8926b334536bb930d19a902e961737db4e2b12b684b47d8b3858df1a72b9a6d2e38920d7879ad3ce6001391edd83a68515b587527865064612f530c0c3be8f60acf27e58dd7db79cb0f9de23e427401d1cc17b3a98bcb67f36481cdaad4925e6babce9140407b7e4000a70729d275b065cf2608b910ba6c5a851c7503e2ec528e9f848db6bca8c3697e655ea05fdabdb30e05e50300d8650202fc84202b484e00f325472a6a04f5f06dbe8bd4ed8f3af1fc0dbe46aa8800d1b53e3c839ecef1af3815a1e4a370ab03d01e2834557b77318052afb97c39c7b4ccd8de48eb4128390cbb00862f428e121386824898c5417731536c9987009a7f66283faa9d4afb6bd656867058d71de984c3f5c985872cae141b5c2eb200a4a145cb9199adcdd4d98e3601ddee6e36133b49cae8d9c6fc11d7bb71d5be81d8bb71335591f41d07a0b86b885d48ac3251e7fe50dc2463411ed66092d40351f787a2c51f8b12712fe9daaf142a578b309997b55adada212e950493c0b6e46169820b8cd7494e5053979934fe738a8af62bf9e79db2ba89b0da78f9eb90073a81b23d34f6fd72feab0b5e9c2d9252fb9a756d6ba6d5379ecaded0cbef8a39c6f90c01ad3a31acb812a7f626df953344c0e3caafb34895623c66a69987111749410d45bde549c8dbca1b263c81d47cc5588ec9aee5c24f74e46747532f44198cc32a8fc69f49626fc1c9d53dcb02c80c11a0b5fc853c8ce34161955fab733c93b62366b43c2eb9040cfbab6a2546849f658c974a0a22dd6e121dc9a3bb0d79fbc34258ccb403c1237213fb44b8748b8e3facf0e8ad0ea33ff2f51e878cdcc84a9e96e12d6b403441099fc6ae9303df1abefa8cb9584886db0cadc0696ff511dd9070a06dcb17c5b87ea1137246e621a788abf8971498b9056cbff5048ada49564e8a41554e1b082c1da283a3ee2c842ab317facac0ae3efeb853e6f4ea67f8a5fbdefaa3438048d70dc6fb7254ec61932f12a4e79508543b2306ade79f8c4caea1ab09acada9b77a81a38c80c7a5384f6dfe7bae9a739623ac68f2989ae452fd26009b72aa7f8a5c7a1d3fd8eb6d6bbff92ded6adf31ec5d0eb39720c0f8d97c81799fc99358b9e59dc96c247cd278479bf35147aa177cff5e1933f35ceda31ae7fa1aecb30f2da0b5131f1149b839aeca6c88928cf5f60d612823082bcbbdf29c15c46b51d1ac5da75b962e98a2820034f2649b3af40839d28bf990829b88f79c4ba88867181b3b89d751ca570fc2b6e9559ab67e0c488a89d3f7cc2bbbc8e5a749273b40fe824c96e4624721a6ce08902307f49bfac564556782e493e5a3d97c3d996c954e87acfe99c828d53be8e91c326f1b2b7d7241000ab3daee27724d0e17d47ad2446abd7dd7a337a8d21ea2906ab50b725d2a275a340f4d9c2ef44b66376461fa7c6794204061a691ad3497dd25bbe0b5960f58f305488ffffb58280ac13fef37a6540c0280abbb260e2e8d3b0fb2dfd35afede09b9f207d6084c466ea349f9a46720d5597e89e65ed72a40f68aac3a2f40abc38fa5d41031e1222237607c19e6fd00d02f91ba2ac7aee4ebd03634f0b83309513a51b8e92c55e4c5e7e072edd5e0ea9c68f148392691fb13b519177db7581b8c83ff955db4d0b3f77b39f11d81d0edd3a39d76b6434af8cffd9ea3ebd4fe856845cd56ede601facba07c43e9171686a728a6712122f7079cf31c2c762cfb8e13d49a9e33d17377c78dbcd6a0693dcfd360cde391cb5b8fb85d3c035ed547c8b8469681c2f133fa3cf09f855d1192c3f569bcff49dbd59f2cadf39013dd36aa75ce0ee76bb88655de28dc98eec27bc183b80e073924694bcfe315446f48499be8c69d9c38c25e0a1c06eed50b16fe80ba3c30a5ae8d0756d49ed04221e0f82cb26f0b8973481f0cc0b9598007b2c7a855cd912684a60104bc2a66559cc10cceaca716d92e95a7754dfee6d89afdcac8e68c7173b740a43705ea1569ed2be16bad72eaa2378c3d2c594db89ec592337d47fd7b89d7be4ff8f7f06b8107a6214e406ca5e129baf3dfe09aaab3e830650b3a4ca662ccd5145037bec6901b46be44b7963543b8bd40b6a9c5b6d7791c563373c21901ad68d2a53536606077049ab8a14d0ab5f5005249162e5046fa1ecee07865046d57a3a70e7bdf0e2f44a1632454cee4f49921c2e878fac7913f603e93e70716d745178fac1356cd19de8950675b75e06e23e304b777f106213bec0e5e28177e2a339bab5d8f6038d7aeb280e060e6108b4fc2ea34113549b97da8bba099daae52755561630857d7706eb1134a1cef5d7f089122534e1076e070d7281171164623db7a67e244256438f98b3583a43524f841e09c2112c86dc3ba9820a692f34dd46bb9c446c3cd38555fe878b6b4d65bd4b48022c3438f0c963a66ac5bd9bd11c5d76159afb3fb505e23006bc7f97133c99ee60abb82de8982eeec23d9db8a8ffa9bd8bba0780fc3295ea6424ef59f9d06fd0c0eee12175304292e0348500a36c59659733acea4a9813e306d7b39b94d87f6989122c03337a9460009f1125a6b780c607702023d25f151551988e98c02467508a17c0d1180e786011403e2d2289841823c48ef237aad69ed314573e17de09184cb5cd27b5010dd35c04d743bf043868aeb2aad7773b8f496db6fe04d6d232c2e8aab79cdbee5ba1700a1c5a1033c029110938886f8bcb4177c5dee04fe46076645be4038d0ca998a721c5fc10a3693f4cef88b32026c09b2cd2cdc573ae129b4e03a40c4aff6902d73e94e47d1fd638b471b747498995a9a4153dbcc5df91b59d2b91e564dc7213ce825e7f8c12a2eda3707b4afb514126232e244606989df8ace2c412241730e6fb3211aab9c9c30c32592207133a5a9a30b98e576316a9911068c532652137956822dc42be23cb4b1fe52200ea1262745de36c81c98a09115cd72393a3fd39c2760f17d9e56fd31e5098d9a02b851d266262ba37540d022867b73778cd3a9676a13b0518a0029a4afccb2f07181e0f5f5b2bee9640d80d6ed3ef25a4a0ea6ebc976036222b23612f0ce95372c18f527bde9c157b5c2585052ac3de54e1846121b108680c94a5edabb6b8352287276600b4234e45606e114dc5c8688c35b6eec6184f49168e971c13fb772bb645294a301a22537c6e3716a89ccb7508be1ba5d0de22af81e6cf16f74a368a42ec8ae342d089214043ec98e1d9ee81926858847a2d302db3f8da6751332a263f4ac0df1fb8b2afa69f7405d4799f205e911971c2520350b2df6d70f23e1a2b5cec5f0228019b5e09ece16ab94fe56f220a4afc10b4a8bf2077ac06a8d0d72c4b7125f8132b24a96188923d2a45128c7adfd2738a63ca19bc6e69bab54a6c1c1c0d694f51b2cea4606c8903480a84169623e945481bf419419c11a4517c225c24a2284aee3b653181e0697d6da0522ff26ee21c259324be147d2d2526d744c15c247d43892ee332d046140c601329e4506aabce9a32aae3b805766897449416975d435912cae4fc8c45b4d32a36db4128c9e9f8b8939de8699fc74e1ea3a4bb5b98156b3fd8642f4d8b862bf0f9899b54bfc437bfd5790e9f04f3dc3e9c89d3e15d42d7234d694178a699ecc342654c063c43b9ee19f2ac40253fa24f5cb7fa2bcc8927abf0f5a8b378b6ea0fab01929c9773bb01b308d73d8c8de08c3ee9aa0d4e919cc1794a2635073c2400de26d1656941229abd6a84914e5d2a9e221395855ed318829db8ea12899c2c35c1456546fb114ddbd85fc2a59d4bc6b2de5d7e54143b21eb4d143a8713d43e1eaaf72020de09ab02c74c05399c7548972feea264c969716dd2be43c0ad3d0bc995d2bac654bb011e7719ad838ea897a4394858ff5225b3b56528c94478c8503a452f5ce6cb9ddfec6aa0d2a898b253215e8b221c725f289d5f3ab1c10937d2b5fae90e78d078fe0c070a806f2fb0958043ff2478018770657d816eb3f55c0d3f1da1a9a88cdae70d5a3c3f5422f860d5c4a3bcaf81fa6b0e4c2296f9a820634d9e615274d8d178aba7c5751e6eb2aab2b91431458cf5673bc166afcb2a1289101dca89c85bca1e49c4b10b070bda99600fe93acbfb4b4b0366a3b38684346a4401c242e579e9a3924922e55d65d247d4cac5ac46b40b6180849893856e48f9481f5793a2f3f652307af53ed750c5309c2bcda3169f8f835a61137b8ad3d7324f4b1a050d1f56a849a8782ceb19eeaf7459e877bc25ceb01f7088a35393e7863c24b885a98b1fafd0e2932d7955efb5da4c777733990ed25d35f11ca0c27ad559a872b76de1551f9bf71ae928ee79cc36ebb28cbb891364fc22f45e81ea38d11a4aff596646da6f6684748ef994b704c357f8a12391064771b581e1d1813d545c88b947e16fe6b1423619c6414bd5bce2ff3b274c4d7951373fec40fcaf63e7396da091c19bdf5d78002bc135c4668be530db66f9927ccb089c6593720cdbfbd8bd081310be6c1d346f86689e5f343524b63cd0c5e1e3533226395c3ca9dc1e51f4d18dd75aa3ce0a6b72a766c5661c5e5de5f84653f8878393de4bcc53e40cd7744b7739bca8c9dcfae9fb9779e85af0e6b3455ecd6753d1329d6a22db8b84778a44bbb3a8d00f806e96dfc210e48c94de04b5d965c9993d9854a2d65d5d14711ff9f24d96d52b9a186cc280ed3cc6cefe5576f6a7dd5c390b858323e446804889287e3924daee2d51373cea721eba2bb748547ca2895e9d360206e8e715802775ac7bb2e8f3a91cae9c1a1433e574f5dbd6e5443aaca70054e5a60128175fbcdb8c5edeebf92a1d5436b9fb82fc2c65eaf797ebc36c8bebfb54a0cb09a7029d16073b9db49376294690315958d808b4bf35faccdbee3b9bffa1ccfc1f03a1a3da9dc47f5a231d1278e5c3a203fd3e3cd1ff577a94faa96a57b7751c9cf2ae4fb6c149439fdc845baea7af96cd0657e8b6aa7daa39ec12bb12b6693e5b7ac8ceca7ff592d5887636803fc35be84fb64e16dbd74e448dec2ad035bc5a05ff37f025f5ddad7896cf2662fd49a961f19b6667d51574dc327fdbcd980d6c639081382bb0d7e780b66e83df235d684b08ee6d03dd491ac02bdfd4ee9a417617087fca702f85634fc5e5e84016cd4acfd72f802ccdcae9985d428f8247b36820100b8767e212a004eec1baf3a963d27ae5c2d052ca42db86b7e48fed1514491d5a090eb0e8973bd90775f2010a01775b1a59601b2b54b83197d34ee075292bdbe558edfd22022ba19e80651c811dcd39ff286909c04d81b47cdac82678b16b31739960853d661dbd923e1bd9f694f8f29bec08ed9e2ff01cebed13822cb5a289aab6443b906ca3a8956ab4d7eb50f8f957eabb41b2094af537dc4a3f5618214cf6ea21aa4a7b3762475541307fc467354ce9e936bbab48ec329ab08d314d61fe31e48849edef61937f5e3a091f2ed390dfee00accbef14948bda63b6a12ad1d56da4da89757bbb639b0ee38a676d485efca05dea323b5b017d186bcc38f5eaebf1683d0cb4e985a8c2c97fab61cfc04aa7d144955d1f0128d851149613da19dc8510139fc1355523693e6b9a584d857eff6ebae4596c415f2c53a3375638ade320ba8df11741223e3f37b18643d1bcd6d3f449149fb768faca33394ddac807722a2abd7b04c69a015b1a53ca3d9ceb3fd8fa87e3d1760114d5cf6c495b5cb02afb3d309402801512f0aa40291927254a81feeb1bfd9b4a295816e7148225aa1d337eaa12e0a776418bb35f258603b52886279ba7f6428256e3e57ea346772aaa732954a418f50d5a9aac124f53f7367f91c84a060a517157371923c9dc34082c8a25bc9c89903ce49eab1127b8097012f025e1dabf6b1a61a3e1fec196918ba928c603302c1b136cabd3f2d28083b0853616b680d7d094eae86fc6c215a10c8005ef79f390ea56e4cd6b00e9f8a5046bb53774e533e727fc0eac40fc4e16a2c97311fdce9aae36d3494ea1764f260a9dce4195a8b7f36412917ff0f3abace83e51c388d219ee1b5aae1201b97dc614668e1ac1cff3203bfb2e6f5c0dedb406838b752122896d087e3aa3db65e095529c2c460098d70ecf521876e75323906689438c330b018d987ef3f075eb1e01c91f3642d39ba63801982f5128620017735db9478004db41dbcaf72ea134dcc2cdf10de07de9c5d90135086f5e39a91342cf410abe65dbd1ba23181c628566b4be900d2f5def4e7f520b971678d7bf5a43afb020da8d7d39bbf25274c7f81880a62fc7f70915e3f9829fedc745a8829e87eb9b64e40f67dc43361b2cd4d35f07d4a0b4d691441cdb6bb8ae0d55aa8c4bb5b984bc520c557068b7ff347c9dbb49a8000b1fd10bbf4f2f9f1435c5da613939ef190dbf599904993d4a3928467d432b646e8b7ae609fb5e37e110f4a611ace57dbd0a8775f66ab768857a66fcd2851ac674c054aa1260285a03b72e73735054a6e46cc051f3b2669bd51904e73ac9a1356229ca85c2f46ac1261f20894c1d4647876a8fa1afd27a614c5ce106c0b1a7f78a1f3b8459ba42a774c5a9f95689a35028b3b2acc8e67e67875a0e8e557971cb3260277f6aef574aeb8bea6e32fd0935a273d0207dd46064e0eed8cefb6914b00c02896c614f100c46cb30e8dc593a19d18e98807a9eb56e31772d5e53d7bd8537d51a35b8f80dac4a4ef05ee2c912ea3f945ff49dd7c607723922a188e31d9a99b5a6e74eb618a59ba4623881fe9358954e1eee0b3419d10d28599e13ac19d0f1b9827c4e51d2367030c1960856f10ab7ddf5b8999bede117c3c3524620dce5642599292216edc79c765e1cdd5e6a6a41d81585d825030e08e12b31c7a711841fb86078a840897b4476c89270d2453025d087ba443fc12c93def009d987830bd4b3dd59d47208a32bfb040dee0598b51eb2613d9e4e374ff8595a11738ec2135cd7cfcddbbe4cf1e37980f3168176d2446bdd6a5cad43a791bcaa8d21380d70a60fd413453b4218cc9e308141dea6fcf2a3d14b2f2dbfa979a2c024a88c8be84a3bd7d033e6507b1a85cd7391ddd0d4c4a05f8328dad4f239aa706a7680797d10b66d7ec85b0f2f6a4c1ab4ddf3da4f7c64719421b7a7d2293871553e4db04d3ccd683bea417d9a3d688a6361d21ce62061f9dc744aa92e3cb261cd4266f29a9194da985363793a0052d3954879c7ce2df6c7a646340d2215982a99c49bbea4c731e70b57d1d9a5c31bdd19f58e8021ada07171c380e9826535f483c27e3f9ef093b49f38a6f23454f71bed413bdb9210a70c673de13ca0098200a5babc8a53bb31c441a91d39a11fb72f38a5f11718a63470b07dec637fb57fa8c068f67e5e74ea165dd94f88d576c046c29bf0710acf347152a08bf7a7d885b0f3ca2e5ea4ae04730c16f04d6333ecd5c98251879b0fb163f1079255f48ca826b724ddf908790fa8fcbc42a2ca6b368f3f1135e36ac590c27197b158ec8f8fd333a9a99e23b32cffae9635e328015503c396c990329dac5bef99aae791282b86adff265633053a275e37effb9a10f98e95dcfdce33ea7126dbe37f3d397a4b544cbf416c2fb220b83df4e86d975b9a632537e03f3a586b33274725e40186a6bc69407a120bf7eb1ce47e43f05403f028ef4987cc22d9e213c88dce3fdff17c6683198368a5a7237220be72329adc40644fe8dbf5d8e204ac732d3261a3f8affaa29f19f1148beba430db2e672b08559fe3867d6eb46c2bf1da6a8f48a88b60989b81ff71adb97b43d82e240b6234ebab568798847411744a7ba856a4ac98166fae781a5a6e43edad821ecf8f5c39cbb3af36dbf5ada46ba6c93bddb0beeeb955f0b9def1460ddef318317d8f46df040e9e0a2dbc613e6236bc53fa29496d9980988283dde95d4916f17f058eb634ac9a2106117679ccf14ea1bcadd7e456939e2dab7d1514c44d5091a6be4de3ace1412066d73833dfbf1796edda705569bff4121fb6e902eaac034150c44d911dcc535807b705f1063a1837108ccdc14611177702c7e064d18eb5d7b4f4172730d6254fa263713a3c3b40cc4e11652e583a91c2ec2eb15603f388b558ccd0434791ce64cd7f5e38946dd242b8484db96b41e0999406892b4c1ecd92dbd4990393b303559fd755ad83874ab231e7e16da08c7d52fe63ba113324b59cf06cecec65b2acf9ec2e27e174247ddbf2f81abab366d916bcaaf4ef5f6b30fe4eaeee03d2af95255537f3bfb663784b39597922d24b031de0bf718e4e990cf04a25cff935414a1e7a1c06e9fedde653726ba439f7935d8df709ca7a6cfba7c163a6d62e23d42e25da0adaec62962d857b719f56aaf2e27eb24329cae17e5414e4d26926f1aafc00aadc6afc55556b27c42187ba1d7b003dc55b757ca5c489e55b88556db850dfd476c796868715d879cfaef0911affbbbc8b87f8cadefedc086ef8c41e5abbb0a6dba165621dcd97b969453466b694b1c4ae932dd1f39795dd5abd02d49feb0336fe9d23f24d39b62b6a0af972753b7bf7067ae864914a0ccc6013d94ef683b4d33565d626999a92beb49b4030ed6ecdedfd89b68b5afa1aac318639643ca84f4443ded606a422e06ba2ea4c7d0c96ebb52e9381836f77d671569e3617680ea60a09cbc0fa64e1dceb8374f07839fa5efef4e431f17b2650a1368eb8b4cc7a8a5d34801033b8cd675e8a578c275deebbccfec8b00151f40ec5191f91f62ff440dbf3ac523231b456ceb60d322695a8c17792ce3a65f74255e35c1419d39d9cdaa2ef8b71c71441ec142eed88334a024e222a19d6e1d28022230e1a97c08ebe4234e020f1b8943d170491298e6dccf0dc52fdd4b3a5cc0ab521782d866738ca6f61decd78ef448554d6d94637780e8e3e425cfa75bdb4ef35ebd589afaa13b7a3d9b74435d3846ec3e0ba305144bf95f451d1d4efb8c9cd3d9da2bd76057fb176c0ba6a445a7b4085f723baa044d7102b0c110315178e130841c3762853a499699dcd0f6d668e3c5d4ee062b3ece40a0704a8bf4311a0c9156572da285333ca2ae07459cae19eb574ca8d66d63165b58b7c53aaa5a485714d0154a2431929afc62a496a477e5d01f83a077edbad1a0a53b133b6d1d8d2b741358048bbc24eabc4ad68ef5853a9ec66403ed32602384a745611db6c5e6376457d449855c97bc303399109a0977509357364590db844f1badabd874c310c220dd1e45feead7f15dc41c58cab7417afc907db31703c5d3b4445f1be5d7709b894ee50d54bc5bf734332b8a7814c47b03ef89f1b110de4ddfda0d54e7e0bd01d7bc6fd6934e1d1c181f9465bd4d1c8dbbec2d841075dd80de63b7f976d00ed99da2ee4a7f1e714f3cb5c34ddf99b3e52f854bf146d3a6e3320386cf555cff57e3b4dadd9ebd1eb96e081930a71e6e01cce222777b138a099417c12649c53360d652313973f9cc04d372437589d74aa1fd952ab3f8e00e09a87315e0ef90c2b83a7e0948ec9674dcecb599384d8962f1465bbb35891ce96ecc2cfc863516992fcab5b43fc930841cb31d127cfad9894116dbb53536dc8864dd1c0d031acc462930a58b17938c6eb4deb613d806392d80b21862406431f134b649e7de298c6942c3b397372d6bf8f11715cc43314dd64c0bd9d2d81e6d01cf37580d231acdc3cf5486bdf22359e6d1f5caa7a5bf9a37b94579ab77686565ae2c828d898b70d6a9a78f33f03333fd95897ea9a8976319ea1d11546a437cf4f545647e579ab3c9702fb0d9107a1914d108a71b930db9060916d2099314bcc8ed1790d289459a26c08526c1d1fc6a69f83e6ca8895143802ac8c6f6ca80546a6a6aa1504a0947b2d41f25a1991a78ba249c8ec55d35bfd1d4b618f5fdb94bc809b42ac651f6983c532dfb23fdb5ba72371b06f618704d33e90ca9b2465caa3009bccaeff667a46b342f101ebfa1cd605deef34502d2aa30e2687854c446515a6d5b94013250b935235203e9330d81357fe0514c9254f9dcd3f4780e08a9c9aa87fb96187ad977e5c91d337ebaf428a032ab66e0c409513f5d985ec0a4c140675479baf93944389efdb1ac2170dd92494bf9a0d1a4541df42dce9fe7a2e152cf45f4b5030cd84c52d9cbe9888df48917c90baf1b1db9936f26974ebc5f53c1945ec907fd8f21c3e856cabe3837b5b6495d06f5ddf546ca0d4e823c5c1e51bdc8c1128cd5c46b1ad48f4b6d1f366e251c349b4415307f9026cad44589d045644bce97f5a11dd1b347a52416664caf8bee863f4bcb5922697e3d376a0b46eddf4db4ef48bcffab53e194cf40a6aa057e6bb30157f526a042a9c04050b3224d7e2ad97e345f9523b97da85a3ad8c68cae442e36b2d02d7f0d3dea9029644ac3d3f248983d4280a82e3f83d4135eb0db4eee7915eaacc819865905eea8637852aabc844dafedb5fd88bfda1dcfbde208b30dfbac9dc6ab8808c0e9fd22f253d235c6368fa2c6991e9374275661425ee85f9a3a32fe629ac5531c74746dcb98bbdc1ec4777d8d7bd103c4a01514cfd9fd2d4d5c2314eb5f163485b5df9718958bc8a79c220ef36ca736cb3eaad6a84ea82f4011ddb0c83951a1401316588e603e69d13ed4d0b65afb76b42672265dc993de7ce534a1a2c18d80459a0318ac5aa5aab477a3a1ed630d84a71cacdd45eff42a1ab046e46511a13ed7e2d2127bb4d9c6335180c2c6a9314eac90bf6ab433aae3489fed6c0241e9d595f2c5d2a7b8bf87c77066a4e50253296c2d32dd1f2ea74a4493d7f17c7a5a678d766b4a93b09ada4d5c06be726233b722e96e9247f1c81a7556ff254b3885fb2f86781150c6057f02631ce9ee90519a0a5233218edf656fc2e6fd23174da13f44bd731a203e375ce16839707d754efa77a718d6b194305a1e34c26974b325dfce637535b33b8d1f74bc4a967886a6c1f25fca8a96d4e3a6e8c1ddd425326246fca6e0d11284060241dc1fc29e644e8b927ad808f03d5aea0d6c10c3a3ccb4df90845071d6908dee8de021adb836310feb4144404b535fb03529c6c307392b892cc8fb6cd459fbc52e63235d299e01212570871f12c61053a8d8dcbc816e26cc2659be50890f869c43a609f0efb010df3fc4f97aa338c94a0ad0819df93aea0258b77054ae730ea27682a44fba40e1aa84f5142aad41dc00c07ce6119a20bf267acd75c737b09fe9429050ba6860a0a74633bf590d0504caf2d10f1dc6735cc4875670eae85592b3c146637c2b863fcc6cb261fe7b4b2bbd8038bee6c50f724ce5ebe7cd3297489121e2b0afc13f1d4a8528e3193c7775a5b4e7511d43311936cc2ef256f2d900a5929cbf43f399220985fab4112f81ac8008f041004bd9523015ef7b98d8b6442dc58c4c87b70f5395f18e7609bb64d965fd68486e07269d4509cd83b4186a796229770fffe15369057de4fc601a58cf00a3d7567746f471d0cf19dc31bb3ffa6a2f3399fe070b593f96b67b342e1c2744b65859fa95f9fcef26d32d2b3c45ee903f4f4ae05349351d2685a8adeb50821ddfc0652a66c88af2537d81f76521c8eb6864d0fe1f079c70c41271fc34cee6c75c70ca5f2d29d26ab95f7035fea4a0dbf42973743c721ee510614a274e99e6edff219f0ae869955eddb14873d6efd7a482642195aeaff87712c7a4a6060132558484119bdd54a843c4512f1be620ce51d2dc88708639b6ec11778e05dc53a3da3654777c563bf5d4653c8cf0ac1ca93481a7c413365ecb64511618742ec51ab5cff90f3c689ce5da923e01b5774ee8cda1f78a82b2eafaa45347cf941202021c8f0b042692349ebb4cad238b422e5fd076372649003a4071284362098c4e9c15136f3ccc47faad9a37b407b1086bce7c5f9790783e194dbd46368113f4722495327a39953bedb4c9b29433cf8b803827318865f70092aedf22ec3ae5c2c014ea284499d20f860abb9e310dfa87885ed814f805de7c052fb7dad322aa1278999e319f9cdfc50c1e9e34ca66e4bb07973a7f269c3d208b511d19c708d89ac2189057cee11015d4656c0c38e372d2ea6696d8cb9f87bb131e463979c001f06122b5330d775ffd9f772a09a2fc2e323c663e9a40be23b0edd3d81ef1bae721ef884e27574cdba255c4b8497198e4d8e711a6b08a578af754b529f91818a563251412aa283f733e8e105d6457f2c5889aad18b67535c9221893bd7590578145686d638ccab3ad5587b976ee8ae5a2bbe8def533102c94d91ab8ada25d5c3fd47b3e9de97bc74aaa142923eae8008c46b93d2981eba416120e223591d54283208a128763e3482d32f1af4ea04a926262972059f0dfd0db88198e8319bdccfb0cbf3945149286ddee85a50d6fc536e37a04bbf3f16ca31b74eaaa5dd1fe6ab248c319f084542c8bd3cedcab7920c8692e971573b20e61a7628071abcd9e4223cc41a12b9c72a12f312cdaad931fc3a730edb4eb730219642daa45e75af10500e62d45ffd616e3ae5b1738d3a82a4b25eb8f5a3c553ea5bd71842e82f1f88cd5039b98cf05f4c8143ef9d01f1ccd67c4b80ef6447483d98214524f22b4d43edf9b6d4ffc3105a604f316c4bf5cced2c32e0a981b1b68743cfcb144ff7c406f811aa619793aae2e7f2768c51f88ff37822253011b0415d8a016d8f44da6c441a4f4baeb7dc485cb219366617f6794d2a9a1872dcfa28405b4880697de0f59fa8b0ba723b78ca93c2363e1fa5b232611c2839c8f3fed954625a0ce9847026833f0a4b2259f0638ac9f3aa7363f3a05f2d10ac30a7775dcbe4e2f5f2ed2bcec65eaf561c9a0c513f5e465dc3812196a2610353100cf4ae53d24b51da0dd5448b82a4f437bc74ad0ec0af1411e15fa9ab52b8672dbbae444b9fbd792d79eefc586bb212dc0a8e092a41ad4e3a8b5e7b3c78b310901d18a909adb916c2ffd4e0005747c371a51f846298e5f365768426cfa6d7ff18229355aa205a8c876e2d84350181bd231ebe4d2788119a8ce42264f1cff3097aa01f4b90f2c3cf3d1e84afc123d8162bb213f8d0a896284ed3b205238b7d3f045aa65b55a37fa9c901281a28938986051a1e2502ca5c44993b6cb60a0bf081795a0beb0da21a182a786d35460c26689e250c6b697df014d637feb9120f945a0bbdb8e990c1117f38337fb717267e815d2707a6f97b72fc87fbb23b5c584a6c690e132e6b1427a3c55c98b5bcfdcd946a19387ef0822d6dae1227e5348adbb0f70f9849276d7aeef6a811c6bdfe816d52863c1afcc741643d501e1a067308b8f073c677ed64a1bdcd275b0da952c100cb8514a22658e95f0f9ad71a44be35b3b7ecb2b74fdd443ce5ee3a9febe06f61efaab9f0b82e7f76bba6e28e017c2c1cf157a8f316bec0028c803b829467e31f25992ed169b3abc6550afd0f4b3f818de405245ca4d8c378d9a4d68c213e48e8a5116aa338ca4aac1fc1543049baa52af26e31033aab9a6d4be060183f8272ec7e2415c63346592f131c65fd03ceed04b385683fab8778a8caed707897831ac168eda3a9b8b5888fce62b47226d0269cae6bb716349545ae1ad9a2d841ef6035c2a96976f6e51364c01fde59bc3885b42927cb7afa87669705d2bf8ceb5b898f959573ad1d9c8840158bbcc0c66d83fb0b029593d783b81f548836e506c704930fb2e8446d103ae3a64378400d0855041858b3536a3522d072d828ec0253b142003921b19c9f152aca02488185e713447132781a4e6221c850cf4b4ecfa09bfffac067ac6e1b2a5d151915ba67858d5958cb274a3d7843173270136c80ceab765bac6d5df0e6075f32361268eab92f62b1595c38437b4592103282f08fd68f8b5ac778242361f38bde212ae7c14144fe9a0a93c22a1093c603762b0a578e83a271e2ca47e0605df30e1ddfb39fee4f141986de63f1ac6cdcb3d8e73f6aa6bb7ab925bab9608305ebaf03560948202a7655a8c8b33eb3a2d85816cbe0c60b079e5659e04d5ce1c0a15ee5c3a5e84e28e5ec659eb19ec38d6aa96aa2bdbb86cd5c18c5d08023e29c1ba1ae35922cdd3cbbef09d9a473d08c2c1aa2b70af0b3eee27d61e581b6a5b829193471ab10b14beb4b2b886194cd5b6aeeb36832da7623f7ef5b2025219a9b351523c9605bb9a22beed1773f1dbc46259ce06f20c2499fda3aadb0b13f5a52544853085aa1b90a3a50b44ef4c2fe3274097c85714a6e08449dd25d68dd10af6aa37d00badc9a0db59a59b634b7943b1309d4767fadad8410710880c648a937a25b9f12afb61a80c0140e440795bbc06a6b147593c1ee6edd79bbdade1d1009b3046dbd030bb20256624753c7ef767a37ca786e334d0b701197564404e5dd556da11495139578f34fe8a2f876a8e4d4262f6ec1444cdbc1f1055ef08372468b8509eba5e7681e5de0340a9367b95443d7fe62a5a14e5f8a9d39b95389a433ca38c0080f67eb7ee25411c1fb41bf2f9b4616186e2f0977f895809348fc893ad05ee3afa35d2e58a17d4448bfbea17307660cdc8c03708163d6b5413e6552da913098b47e4cdaa855d35b633ece0b1748a95f02a97ab28bf821750b5f4dada66fac05f3c43acb53671f52466af8627b2ee6758e64e8f2e97d2f4ee3474b4fb01a1e04ef0bcb9f242b150314158bee68adc5ccb5a1fe254aea9d6a7caea88e1864ddfc28c945b07cdc85c20fa80f19e4f49c0125fc6e34a7e9a209c2520c44d5f2fe571aad96b0a620b335d65f9d47f15bda278b475846ff2304e9d18961d49bfd9f00d46a4371191c4e4e32727287ffaf523f15212aacbd9038b052334eecd63d4ab9927fc11a98b4a8ddd43cf785770dc2e803a1041a6acdc364463d28f701d0a1db698f56767480947c7fbbc4f7756f4e151d4091ccf53d1f64eddb86d5d4144732fa106511ad504bf3160a4bc7a2f38a21430fabada28b8eb9c626197344cd35aaa9572732b7ea28ff7b1a218740747f3ff461ab11f4f5b954785b77949e07117e667d23df80df9ade55a67e31b7dd95cae3c6777c4614126458ec71d240f3d6fa644ec319f950a213f69a2372a2b65f2e4bf7c8a64bd7de5770c13f5d818ef69038d2617879c3616b15a35973d0e50801cba5fbcd0305988d776ff3c605b4b2e8a76ef9e1624a9994ceab92747486a360d41eb17af738f1be63565cf835de8a4471e1ad4c5d686f0cbac38abe3722d280a1c716754a5841a1322041309e570507fa32e4f211c9eecbb39d9e027966f2736443504bf6aae69101a407566ddff47ad44d5ba85a6f95be9fa5092b71592b90a62c22803cc749e2fb7162515c5b580c636f4089f70cbc532a00dda7aa8ad7374ea100c6f5ed0cd5517867422962ae7c9ac711f102a87295910a0b6cb4acf1d7d9d426a1a8d04dfec8f6ffe22f8745c6b9b49fc129f1bade5fddc884e6edb6725a556d9b469956804766927c2531f99fac56f8aa67b30b526358445a09a3fe34abdbd5b9c75abd5ed2d07a452179df3601eb2a3c32928cbde2d1e35e51f93c4ac86616dcf9a9605649ce80cf302897bd7231aa7da4893bb9480ed57f49ad32f20aa11689a79d50b567690c97183b3991eb63427ef9aaf726ff0854694c6a4ac51375c653de1a16f5f486d471c321cdf5d0a5d67063dc808bd27c2aba9948b3ffb8f5adfe9ea74fa8ea386dfc6e9727bfd68f993ab3cd7759cd078352733c83bb0a855858213e307b52a07c4fc2717540d2312f7402485f023d858fe60fe7ee218808200977e8cc0abe816222ce5a27c4478f0671941be4b9ee3cf40dd2c4f3204d004148939497839812d2845f29a449a1e689fcf18b10a1879a24324f2ac64f403a952f8c2b860f55a2b81e641c25a6d86e23455c1ca1c730dc24b6da8fe80926890df893152fe5a07abcba1cd401a91ecde594f04f8c9510bc7a74ab368b859cdca014f84d40accc032f8e3e9e3fc5bfc76d828032ff498b95eceba778a7bcb82b5da2e072a5af8ad043207f14c548997dafed488738987d017f126225844a6dc430c868dd7fcd2644eb32ff04c4ba8cf0cbad2081cad27c107a7489f465311fb4c4adf4e0c11ca0471efbf2f3e012c1446c9538a3c55f6758010cf1c71cc17631984591fe0ebe7e74392a24d3ff43d2d9e623d34d45f57be0d50c0fa06a3d201b80da80e0115c10ffe66078869a874452dcb79f79e48ca05bc4ed2f25e5f8709a3274c4024a20966d5b2054b29a0eaa311f8a762b395ee6e24e048dd56af9036e39a9a7803c65fb418409ffcf517e255d3465cf690feb24d55d1d040668c90104392386ccd9c180428d9310144bec53a7cf9bd98a23ba31706823d6daeeb6f79652ca9464d406d406c806d335bf8d7af098b19ddba4c9d48ecd42a1380677dd9aa6ddde4e29a594d22a4eadb5b5da5a29a534c4815a5b394aa9b55cadb6864aba2e2555c054e33c93bed0a0c412a5d4bab56ddbadb556c767ee28086c05d784bd982018135353d36a6529e96a893b651d9a591b72dc11ce7699a344a6cf30aaf7e24add5d553694418872e679decbcb0823f4a47abc6f79616bda9007c601715629ff79a7c6bf746af0b1d64ee9a2187a1cc1638aac02c44752d30d9e1b3c37786edce0b95dd28d1c9ed78cfdebaf9834c99cb55973d83887a690c3c649c40c9ab53994c44d20635e03e99acf8489124a30c144f618c420fb149fe2497c4a0943dcd1dd394f328b8c1001ade148770791e394b0f990b3ee08a9a8e8c8a8892445473e1e2061fd0129cef72b579a7a48e2bcc0823b76b70f39ebb28d06de9692c008d48bc4e91ecf09d98ef8b2bf4285b22e5461578a051d2f8015f072f7755e44c54bcefce626e775d375ab15f74d9fe35e72e65bb820a6abd65a6badb5f66180a1ebeefd9fa2385faf00481b5d44d6a8d9861da48388c871350994b3e9799ee7799ed7c919ea650e4761568ecea8f78c0a250e1d2980ca14e579fe3e50ce6611321d990c857ae1ca0b5cd8ca7543aa14eb7fcbfbd6fcd6b750288984ce604b3a9a725b629a010132d63a48d7fc2baed0420b2c58b2cba59acd1333c899e75bed817a5d6804aa72dd900a648b3d0f5f205b6cf3f48028be6e44fffe0b798e1ef5dc3f6aa2b87f0f85faaed2dabd775dc785df5ab5acb5d65a6b3b4a5747f7727f1b6109bb787894945e2290ab0d2f776f134dbbbd9df6cc2a5c1cd14174a7d833a594524aa90c54725c0ab016b4280447acec10a123bbe9f1a1a4ede74dd675af4ad97025713acf0b6ff8b1e009383b5c58ad2a0bd9cabc644b51a8222a6eadb5d65aebb0eebd4785b3226e873d29d64f552eec0e6043f342295d957a9e5b0ee8c076cae506b12929be4420d3f9a55438640a4a9cfa290964ca85e0c8e946c596a4745bb2dd94ac48b2dd8632878210eee84e9c3ce19c290521941a9a756bdbb65b6b6d8f8ed685b269412e39f31c1f5e373a2baca042c37068f1068913f380e81a817c5172de091d0e0d2ddbaa41701cc7711cc7759c672dc7711c67b98fab6f29c7515a29add57241ddcd5a6b735e373ad65aeba2fa989a2c5bdf8f37602ce58279664c9592c9c0d7eb13454a6f1852243b75e79ca394524ab1ac741ac163bae6f34c578c081848b0d4eeae96694f57cb413190eb501fce14f74a119422f570478580948260174a94d2ae936d84433dc7711cc7711cea3f4fed70c9b6b3288ce29cfb6103e32a77b86916774dc9e44a9b4f749e27a5ebce10cc0f78a65204532fdfdb86aaf35036945204ad8cacf1001a8fc9201e653228c5aee3c22b455aa98b4bdbf01fcca35b9323b3b61d9e1e3e405a328b6dc94a93d3136ccc19e711622bc75a6b9d1cd6df9447699b411ef324e962722b56aa54a192e9286d3e25d351da9adce9e9b387a317653a6d43de2445da946ff879d2ca630698c61c9c721d9a479604368e768454547464d44492a2a3a6cc85e274a180e58e4ee4448e8443c2a58bc6503139f810d6ad6ddb6eadb53467256f2e58d3a2315fc8a123b5da90101141b5b681287166913bf693f854a3c57e14d7ecd49d738eba0cde17a078e6cf67cb4a556e6d929365b272bb312d7541e5c6d44a6ccd0ceed84a4a53acd3156fe44e9ec59992946e4b4c4e4d5bac3039b9933c7ec6f12ebe933bfa922f7995596b11c4d4788c4a1715e20250bd1ceffdf1e5e7c8dac6f7f2676d037cf93a6d2325e3e51d374d064e01a646ee895d145c1090ebabf09842a69fc22d59833e88435983fe875fd6a08fc2352f28b4c21c72b5d7c5c541b74b701735c9de74dccb70d26f062a28cf569f74ab9528c798578e4c87ca72747472b53923909176ddcc4ddce6497ee4470e1bdd36ba0d1cc98fdcd65a320e94ba9802d31dddc88d7c89dfacb576058bdda0e08e37d9893b4a259d968e9cc99a049bd0aae1041ab0c40917401f3300c4f75b7db5ce4db15fc7d92ea41207f55244d1efcef97dee54f33cb9648684e38ea8510c870241dc9e8f4c1d902d1e218fd9e2994cafb450e4bc6e74b88eb3b5880f85425994fd3e14ca7af6fb50a8b0e559cc641341b0b3c2e64748454547464d24293aeac251e0c11d9b880889db90e0b896d8128df8920b8b912215bb10942eea63147280941313295cf08221295db4eb6a23e83a534a29a594768777743f4aa5181c36ab7071a496e7cf9f8e7ed31087ae470cd45cdf53a1a776cc4e4a1c8e765dc761ef77dc1be2388e7bdd88328ee338b0db21e2820eb8986f7deb5bdffa964d7aa22367fe9ab1efe5cb74e48c7bf9dfbd944f2bf9249f86ece81e0eebc21e33d83b5d9d943b4a2a288fca901e33c827f9e4793a72e6b6cf7df71f57bfc38dc4c52a73eeefa2ee3b99bd91c8ee2087d5af5f83db00c4634dab2fab50c9a37c12c396c7e689a13613094d240c1357fee753522a7bced94aec9293b9ba5d256aebba7b57ab7f47d5391b082937a5dfa8aeb4b9477d63d483b8043c762ee19b03650a070c4ff7fb1f4a7290371a93b1b3cdcfa834f00e34fe8647760df9418199955c80c6dfe01f201a0d1e34c290069678c4402d4ffa34663c0dbc0350cd563424144444871aad08104d4ed78ca778ecf28ca419b89db86813f61317ddbb68e8880fd77bdce4da6e14fdc097291c2008f60d365bb68c71cb23d0519e3584c00fd4a35e767777cf3cc3f187da5c4c72d1677c63193360ea152539ebf7af531c36c39bc3aa16f15d287c0af84f98f1ffd2a9ccc764996d8d425b94b3d8244edc55ebc7ce8490d6a6cbe6bf89ad910db64532fb64156cdedf26a1291c363dbbc81aa910b27afa27cd239057a64a2ece6ed9d174f90d8db7c08d8d0d8d9f2c9b90c74d28a72bf790361a8d90164d5767bbe43b4711c304597659c23071e77fdd3ebb9e93aaeacc1d8e3f594a9cf95f833385c3261c69b6f9cfa60737abf08d6954e8999733b444b35dd559e4ac67bdb9e8ef0ac5705ca510a2108ef78410876397eb87a3e7989f118e9e656acccb745895ea94df718c74e98c2fe1fd67e0c7f5e97f9c5fb3b858b5d42c55cb53cd52e4b0d12ec9fede34fb8caf591c3603ff0c1c3e7ef9c6387f0d3ebe0e3e564df071eaa3e0639ad231df5339ac1757dc0008f9b1cb37fe5c533a2c0d3eb0c515396c1320a460916300d68b2256b2c83374828b2d583a31f4b43377dc06fbc8d4e6b019ef4f9394668cc6fbd3da8c3911093faef28a841f6f5e3d093f767945c2affe5be1d8d9bc09612d0cc7d5083f7a1333be5338f0d37dba558b8bfe38ac595cf49f51b96325623deb3f1c3bd6db84e3657d8744495ef335353535352f3d5623abf94903f3b86b46b833ca5b0958e61a3c52161e5b79043cf60a8f9f69f04867f0d892c138f408e6b166c9fe3118879681470ac2e0b1f582c769459e4d8c92498547df92fd53b889ec0fdaff306aec210e8f40e42dcf30acc16d4862f2878d322072d6d9a5106a8ad1f1450e21bb14237b17199b28c98db4e4b18fa28891442693c95b0896e47195ed91cbf193efeb1c26a594aba793526ae9ac73d259e7b43ee574ae6b6d25ac1e4ee3de695cf89303cd8672bae64cc2548426091931b04148be2f48c90d9e183e26e77c8769f52b1ae47175fb8eaeea488b9307839bc5d56285066e4b7645db5d5d549651b4e4208f22961b4b3c71840c980421f102003ca102882a483e0c5d01058825960a1aeac50e4edf0e61a072643a4cee4b51b438810263402d485a4ef04455c4b55946d152a485c84906e84241f0c6acc2c8a207224e60185714414204c6381853238305b4489e0f615469c960a975e3042431673790f70d52ca29a54ccaa774769d6ceae1044177cb11da2559c8ab1593c8f4ea707c1faf3b33e663b3f9303131f9d73a20a59472ca6e522b1050268a7953c3718e609e3da8a4338696d32ebc8ed68e561a745d57bf9150f776dd4d8f4e8af52598ab903c29ad74ce909e200687d9ffa44ef65a63cdfce9f3fe3eaeeef5c2b1b3d9be71a4b8fd630765264943777f9fee395ba9a889c105a9a8107e702942e50e6201bf1b3c31a884904759761ff8c0031050c27082a4042a9660f201142a9a18e208500c8f0651a6d84176c103573e4c9651c0e082cb320a185698ae9765143074c0e408e689178ac50ac785c54152ad4a76c7928f682105134e44ac44411baf9417234486e08395285b204122956514309800e3881d7c52aa724559e99228cfbd69d7a05f63e75cb9e8b94a17bd6bc8ae01a3d2c64c6baf8b12567fa4b46bd281cfa5c661b41b87380dfbe98f05691e90bdc7a5cc8f9c92c18b0192fde90d92bd9ba0108ba977f427fbb7037d4d853e296dc81fab0ba06bc8effae64a6938d6da75fdaa94d2c694de56a76bd8986ebdedac6bc8feea2deb1a33c7c5978bb27e2763dcd7f0a3f666fafd83feaabea5b5febc71513e7d4ba9e8a2fc2c9a0821c60a88540219484abc501d907840724aa590c4b81f920c544854eefd88c8fe1d18205049e19c3b0704cadddddda72481a222e54f6e1322506012cfdddddd85529ffbb7fab8ae8121a402e3a58822d0306612eff535ab6ec539110f0c4257021b4f22bbbbf72006063238b8afaf5975ad992ca37cb1b4e4eefea00e8c0c9a7c037630224b0b40b08410401481a1050f8a6084114592084ac203d7a9da4ae74ba6f3850a724c9651be08024ca22b9d731e49e19135e64b9453a7b4697bcdfbcfc33d2e456babcdd5c3817b1c6a582feca9b9bac4b133db0ce4daed38ea82e025135fabc9f96062629a321eb6a76dce3ec2249f828486886447adb5d60093c6853e0121cbbe17b2bee502e5fd874c7f1f1f14bf3838c4275b23bd657fb187cb7d0dfe4d2f8ea606a8647fe9fee43517cafe74f691bc12c46136749ed4f5ccfd3a66eecfac7e495bbd4b1a901058a43cc1a2090bb08021b3482144171b38c1151ea2f8378669e1f9a77f489a92c509ed2707167c10c4126de6731000941e7c40a3f91f1b2378f8a1097db80bfe33211077c179dca74f7e12f7744fdf7a2919ecdb0062d5fbf0f10223e3c6a592ff859121c7eebabc943798dbcbed86b74ee1b81f0882291cf75b43dcb1b38462e949ee9b9cc164ff5e92335576f0888b134b51278119ca733a31729894b2c3933c84ec2f45034632ad227b966e4fb95c976ba38a3b4a277fa9cf52a5c636caaa308767557daff5cd63728b2a4d4e59b4384c4ae141488569582208d3d04408e62cf7778172bf0ec4aa5f61568fd5cffcea671e88c358f58132101b52ef2b193fde1cf33f63332f7f612e6f345d406439f535a4b00d41dcd48fb28a0e9fd086548fea3d154e7d7da0fcd5effbfa8563e7ef77bcb27a40d60e18583df5539f0a4731d75048cd2e0f948132f840b98d662c488c8cd0082674091b491f69221793b840b9bd14b60d212e8f9990c50388b64ac011778427e1679e66064b1acdf58b1d09f622aff5cd8d8c6e46722633eb5be6c76ee683cc182b9461d7d18433a19435ec9bc4f13721cae57e6c19ba1506a28132b75187a58b423adb2701b3e6b378cc3ccb009236c33a00cd376d04cc9a210f999f7949fb2ab8c240342e8a2a8c64ee11d0513ce51d77a28b5b9e936606bb0f874999bbe03b32a95424c617631831c5d0143407aa9dc0045a2481c4440cacd0fcfb366340457cf8410b6670a454832768febd34633556b0640532b8c1113920a2d9e0b0f9948640643049a2fcd0436bc8923c5cecb20b947bbbc9f09a22aea13bcabaeeded54a26cba89fdfe1f8a21a98d99f2f6b197379ff6a053bd5aa766917550a043bd5aa76e97e17550aecbea29e8ee1b8fb420fd5a86ecffbce1d859a3fc2cca738b217645146f09c43226ab9356abce4acdf1d858281c9638decaaec35248e4b1c5765ff02481e2ea9c82e6f425f0b3f5c8f7510d235bf89e8da255df359e85e70a28b94e42981ceadb22f3428e134dbe2ce7f1a5adcb16b4baad4a000d9793a489cf9b389e4f973d5c3fc618a8be54fef76d3273e8a659ea188ee1a7c6628e2842f7c5cf4af3301b7fb144ffbf2efba7b7d4c1f168cb8fe2b7061bb4af954c0c11dc5ecad39e7a41ab83642576617e279fe069e96e32efcba115d7c09c2ed6662dcfe1f3e563f6e172857febc73f59ac0275b94c65ab8c96ed03cbf86202a2fade84825498546abbd61dd98d66b87e7258389e26e61eda0d9be0e9aedbfbbe60daecc0f13c5f58fb5a3dfbe0d7fe46ff66c9983661bbe0421332c4b29352bb9e6742e50ae6c86c5ad7171e502653ecf4b66b3c801c5dd9111c9660c495192bc04c989bfd08044e4a2ccb12ca388d1941deb60e9a2cecb082e6b47bfbf2ccf87e1e92ae980e27a87f36735b8fda3270db592bbe6dffa4948368443f6e40631b18fb2cfc3d398d8f14721b571f735f4debd26f4e435a7a72627a5db2f894caf51d6fd5dbf31f7930b85d46c3fdb50bc312d33147794f1b4006e28117a1aeafb51b88fb86bbec338713b7b928bb22e9ab11c21504110b62cd9a2c4467300162930820827e8c0105830ff639a323bb0c39ed4241892354f29a52694346f6338f5d077dbd2813cb6d1d8484e6cd4bb9d3c29cf9fac55ae71710e15cd6fa2f99fa7727812ece98eaddc2fc38b86c9ff5e5deb422ee464275e301c5f45d355ff86c73ac95db56d2ed6c7b1dd5136653a3d3d9c5d384eae6b1d2a11fa4e72ef7fad28466960371df57d1c371d0477c0feff525f7351a90b762dbaf7bf56540b12e2f11164e78664925764961b176bce7fcdbde08d1d90e7864cc6b3236d3776787678726ec0989ad6eb73172b9f6c8d2d9f2211943fd94a57de8eb2e40e1c83e41f42e8c51caeceddbcbae7fa861d9ed4ef7838f68f406eb2ff44513ccaa54c7fa4c3b065cb18f9ebb9c9239051a68f0a2170937ff4d31e99869ffc1cbce168ee7ea49c2af55c0a870a089853af4a3d0b08972930f3d895c74510dfd871b1cafc91908029774b8e21e471f10ef75f9ed2f0c70ded948574567281fbf786f729e6c25bcbcddd1bc3c7a570f477cfe14e756108830bba58bf9399417771882ed66f23431cf8990b95083d2a85a3399ac716ca354669b34ba15cd5a9382e85f29edd71b6ab1097a2f73faec7ed2399524a296dfa32d5467ac8c727489022eed854baa7d24b490efbbe7e4f71d85449ef277755eb8f8bf553b86b2e06e191befff7611053173f6c3f88c38082b8583f0e7befe330201f176b70b1bbc8dfc363f7fe1e769222176b1d9b4aae541c466b73b69346c25db9d275351c6d63ee1dcbec59b7ee1cf7adaf8e9a4f6db65c9c1e5c7f560e39b3e28dc499ffe2e4ba52e836176d54c1b9dbdc3663333f65fa08b713d473611b29a179154dd845d305a6dad6f776ebeee1f83df85f73e1087494b99fc1acfa340f4493c1ac1ab20a20f333df43e667befe4cf8c3a4863d669e26fc59fdccffd0bccc03d16c5e70471f725a611f9aaef934b88d641f4dd7fcaedf456de4e2fc16bab83549d846470ef37eca4987a494ed242b7d39c797f4ef5e3accff28464608138eab9770fcbfe1288a2ee1f87a85a32cdc7999afc3a323bd0c96b4c6e0cf60496b23421888bc650f7ba8a85bc8dbce726d9bebb65d0bb9bb63312b822729b9cd760370e53a094ea842e9089a76dd103677cdef68d8472b10ad80e44e0f47201564d4e720a37ab8631ff91cb2fc65a638e7d5ffe335b3642eceefccda913dd491d1ef3c7777f7ae5dc96db4a03b4a2db6fafe43d88f6027ca3f702c6b30c62ddb1c72bfbbbb7bc537f40d3964e994392d6e3489fea44e4733c6f27087f632852d0816824d48baa3db76704d79becb846e739f60c5423c26f3f383c860e9aed189fc089d411107b21c1d39719aa10624308e969c66cc670a87bb60e58e6ea3586a31498b3592a221ae4dce60e40c95e77fd5566d1e934a4c4ad2c812a72c79ba156f72a74a8b1cc6f2b1c1c52bf40bb7f9cd97dce64a7d34633e743423fb90c4999f43cb1d7d28f7571b8cc388f0091dc9f23750cb3214e239a6854fb6bed74b14ffe74ba9d4c373e98af2f8ae285df4bd2e85149ae6584ed774210bca719cc53942e26cbde248fc4aa6b59566ac47bae84771a322537a0513cbeaba6ef2d809b576caf45d4842b164cbb49590644add48a6d48926ade32a7dea575a690a7d52ea2a5be4ac3e0efb7ec561520a915aa6ef4e0eab6153c51dbba9956e4af97b077f14c31fffef7f98f450bdcbffcc4ffd2873097ffc554f5f85874c17fd0ffb984a6e44e93f3d3939353531312975dd6dcae1b98b9698e08725ad533c53dcb19b94de7b0efc30131cdde4ed345d54e6c3d78157ce2a57bd6755a52071e8db2cddd6a29be4acf3422e1c5fc271d5c42368beffacb938f964eb6b0d71c7556ebc923398dcff72f6bdc0828be6872be70b71e58c99c024bbd13ab96d4ad4673fd873cec9c9d9fc6ea1c995bfe3344357d6d8a8e2ca9f431c13355ecd2d41bae6db68bafd83105f65d55ae33113985a2f1d28aad002dee611155bcc0f8a2a8a64b9346166a5fee5f9938a5b9e7f671140777f1d9d5dcefc670b4d6e3fcdd06da736aab8291b1d5c55f6b0660531ae7fcbd6e4907cb235d65ab6f773b0533a5e1ef55f00a0b83d8d82ec3d50762587cd4c7158df9c8ac368de7a5894fee23d8b82ef48370f5f17bdf79ac79a054ed6887d3fe244f6bdc893d87723294587a56c9d78acd2ec53d07bba6172d82836396c6cb5966cdf8e8d822c36154a042b57b2585607ba40e92ccddeeba0d91b81c6cf1e0882dd83e1e87d73bf3327a6790fe3688efb0ef3e0685ed23c4d285d9cc1435cb42f635f4231e18f8bd68ddcd4e40c26db7721399b5974b1ebe6f72b10e1da7f37e23031f5b6e5440e8379fb8e44ceeadbcfe0533cdfc7e53d2ce3271e81c847dd38acc37067da978185d4cc52c1e01ccc527d6755f8b2e2f5899ec2f1bde83d2ab583fe900cbe87c721383c108f5e28646696f732cb58de639617be5cb42f738e8bf6617a9821624342083c78f2610b5985144c6cb1822d3c984115992200fdef77780f3e188e1760cadecb2c53200a5f1728d7855cb48f0abde6a2fd1916d77bfb9a2efb3b7e91787578e5a2fd97a7fbd687ec3b917dafd977a15acbd2042098566df1b178cc07a2d1ef58f2258d3e4b864aea378dc583366d3eeb004d9bdfb419ae26379f7e96d66d04f75090e9ea6e2289d336e89b6c1bc899ec25d94cb9bb497cf1e89fa17fa79fa79d8e3e568f6429418539b4128d097da0dce10ff91d6620a0cceab13f7e704f43967d99ebcb5cf327bddd7b2f7c09e27e1e7fc75f8f5b4a57b6c4f05dec191697355fdedb2feb7fd1468d7034632091e57b5d6a47d781dff7e07bf8e6d5713f4aa6ae8bc92f98a6142124d95fba7c0a129a9dc7e5e8cc30c4c707c7711c4c0b999cf98fb42206134e6839a8906c600c9a8cff61b14046c8847bc9e4e343ce5cb23f909ed4bb7cc5f63d179a922187932e3e426ae6fec6c59c2e2ef7e3cd6bc77d6ee812c28436541f3e32a61efbac1e0e287f1c66f5cc2d5bb66cc9de96ec3dd70343f6583d1528cb5e64d725c747e2f88bea3d993bc904baf87d0a0be98c02f10ad78c71c75576d4fbe774422aea593dded7f7be069964a884ccd8a9825622a2110000008000b3150000280c0a064342b1583c0ed46ca43d14000f71a43c66521a89438128c8711404310c838c218020028831c618840c119903e618b329689bdc7d1f90453ff8a6f099640a5267e3d3d1ba5b3371adf3a0289fd67836f38c230ec2e76e8f0fc7bfe3d3baca39b47fe3451d8c34865b37432c81c06813c70583fc8a0fcacea26fa90052109792e652e0971be66e68141837cc5408446e8ae3225234a5c4790c59cc90be8532e76a5984173806dbf1da27580b376b8dae517974fb2c3d398dc35b41e25e09294c2a9c88ba7764f8061291ce9ea2c00011c35633a54c212cdb70967d259881bb95baa16bcb9e375eab0ea62e8b4cad96fc6d3b861542a0b2846dc31ee26241cc6c799d55928f6a2c1981b48df1ae22b845ef57f63b8af0365aa24c98ce8689f8daef2cb3ffa9bd2dc4156bb0b9039ba3c1a98ef10356661f220833a9d2bb0aa1e835110b9c4eba14a23f3d3e44b7bdbffe7bec358894548c53e775ce867190c7e8b714c387f58229542a652cfbd567401c3ec7d39474e994aeeb1e88a9890a4a6a9973d584244a6865cf99250be5cab9ab10c65a72605a5d74dbdd0abb8d14b602211dfa968e654f037785402519adc48c2309b44f567f9c2abd3c81e4735fbef5c436635ffc4319964fd09945d3d61ea768098232c5932052bbd0d6c59539b4dc44924f6eb898183aedfe8fc048ba2ded415c7a86ae449fdaf6f7d5eccebaddaf84b96bdcefd5e0ea86b945e153e1dc81007ca5e0182689a927ab5f73c1a60fe7c6f57d984b8bb79a186bd06cb2307bb1efbc52a55f21ef8b51019f6a0f4c15cec23c939ff0edfdb52eee25a13305ee317c19e89fceb1c9b4fb4b43e16213e633db54681fad7f212c310a48b0aab32ffd1779f1ca46371e9d30f65d4039896bb62974ee15f0f0ad1545907f3b1c2702b42f2f52716505f6c20f17467786023e3a68ccac68aa95365ffc7662eb12cc1cd262fa8d2664b7e0c62c24a315df3117028c6f2d17c2e4e33f9f11e4de14fa51ca289d4b3b7c1868f10839a665ed09af21344d946e4aa847218cd035ac179c1255774c96d372ef31d9513a4361782674aff401b705c8aaec9f817bf7450026ce26b105cae1c44c10e8d166c27a0942190d424e9b8a1153baf0523a54532d2a29d24a644d18625332578bb6ae19918fc817040a6c3f5a71dadba0886697a296236827e99704b8b2f13ac737590770535f02076842447065565572cc9b002562f810939c787881e85dfddd5789df59a08afe2a1386f881a370ff070a5a7935a68a7634fafaad4a8dc00027c6071a39ca377dfe136146da5d902a80461d4e1f4e15f8d54896871b7b9b6aa10c588a3d56682cdba719cfa5812348022a019ad187742856206b9223b5654b075bafa8544f8580c90e0a1e497001c41b7e074e8eedcc6a313f041cb0485646d4875fb89443db05da759cda8935ecd99e508adedec49bba34fa65bd6e9a2aad9d564a6e52a8f6d90d85d1fa8d7e010865c4ac5458f5dc9601ebef6b33adbb426d37849f8cb86134f75a610710fabf2b1dd68cfdc4bf294a5f39a59bee4a005b9fc357b500e9dbfe3b524aabcf398c467e3706a9d3b6bdef4ccb7d7feddab723d937cba5af186223715bb81e2c44a71917a6afa0098637be74c6296cf34fe44cf5a89598830deb9fcf6c1a97ebd447d6175ba92c2ab0874b965b36992391a01b58adf4a4ab74b46aee5103e1aae8906c927e764686a33836537be94a5e25c63c12980e4faa2ee1ee12298979b256b932ffea43a4aeca9c185c9c8302107dde25d00d78e4b2e4e1e84d6240bd077f15640fe8b8eae99abaf10e0859630151e48b3a0b1b2ee6bdace8ede481ef984b821dca074b0705de48a1ec3e7080e85fef7872fa6e0aae5605ffb723f10502759cc2559c41ebf61b9368656091ce9317a2099e611b9ae9fc4ed292cdd645d86e5a91b214e226446b948b3ab0791752e80d76df25fcbf2e8cf561363d5b810d169b9747edc041bf2f84ed9bbb06757e851c7d50ebfee7c44dab4629ca00c2a451dc4ca3a7c1c5e623fab6425266a2163646c7039188844018e941c7c496c279346c0cd8c2e86b3c1743d62a05609099cc7c45f257d641d57abc9310d4e37d2c5d417ed503474d9d485a9a195c2dfe83f10fedd94049e14b798e1cf4091ba953aa055f70f1af4b242cab082200f853826795430868a1ad0d6cda954b5ac4f2495b4d0b45da0819978b55e501a90167828d18525ede08d9a3d7d92b6634c2d8237919d85f000050bb184c1801e986448471d21d43fed55483fa268e3e8f3a6f32961b025568c983e7ca59a4e7664901e833b50c548af138dc8f2df52f4c0794dc0b931ccba0ba930307ae12f6f2783bd19d725f71697d15141a1cecb7a7aa0245cc4e653fb6020edcaaf350e9c137f8d214f40cfafb2bbf1fe31310233bc49057694519f7e81990ce3b6a53114017001b2c90d6af0f47a6f9f058b0add439643dbbaf35ca80aa473d9754d19d0be2b3d21addbebf451b7e47bfe90cc05cf1cf6c1e969454f303e8085d54c1360f3411dcff208c5f7e9c0ddf571d749e85fd7b4ce04a54fea3b29b5d6ec53fff266f35952b3295c68f4e4bd277b876f9df45fbd3b3e06a38a3838f80531394a5ec583fd09f22c499042d111021d570784a5bd83e873e63e0fa41631c9263e4172ff6fa9444aa867367e26f0564ae4f58ff72102d1cfc06a8c5f17cc5630ea2b707bfdd3f2b464db92ff5d5ec056a3e5397a891eea3a8decd6266af2ae87d612eed537a08ed5b8687fb81a845a64a85ae82793ccb5aa6cf48502a04790e375f3af8d0362eb8b7b9a84ad16bbd8e2d335ec93cfd13cc70ce736db3b188a91a0d332f8ab3c1e8ebc8788a0ee9ee79a541b461f74496fd680fae518fcabca77ef0d3c8ae0b6346c76822c2435fdaaa04b6f3308969ecc33e29ced99440c542d2444a9c7ed6feb803c02b101197d7d443527e78bf48b876889e62c3e1d4edcd9e0de0cdca7461e98a6f648e49fe954c2b781ef43cf910f2866d5d6a9e189c2689b022ac8234dc07761eb393f92caf7dbeb2b4e7839add9c7cf6f629317f360a3451a8702ec6b0928422e479bad9992000dac83c466f0bb7104b91aaeda2e81e966a2ed5f37dd34c2cc2edff44aacbd0adbf153d6113ad28a2670b33d0fd2e085bc2ad4d97a6bcdf9ef0c08c9b1e4e701c6373e90d096340bb620cfc800801e001764c1025dc1b8654af5eae7665aa237213ebaeb57c2ebd091241db9e41b2cd6b0a4ba9fea61c3945525818558df3e66bfd3b1b9d5777dd4d3e3b802b59b5b964f87917498feb8b2bcd144efe1822e234e030caa7a6fcf64ce136239e5994cb77f53353485c05c9d0ef2b6edffbad1f77e069347fb1c8c5070e4854c7bd0bebc729b0f4e7ab2ce6898e6bb099a490fcf9d93a1feacfdc44039681c8037af18492c485cbaa177ccb6ad0ff1f61b914a5acad4c6632c6b617269a4a4536126ee1676d8d198d1d47fb13af81c110542255ab18a0c8e5fbfcd9869db47632153587411c1833538e32316127e76fd899be6deb08a7e54eac20c40a2366f5015ba0e27e2741d9174908e61186013a81a1fca4ec572b694385321807b4fd29ad05e6debb5d8d7ce31f96aa30f059965f18b21bd5cc2e5e56b717b3e0af336be69ad570111466ef8ab7a4fb860eecc1e0393c54e43ebbe4886d98dbc5e754590eafb256bdfdbd728d8759d16f982bab7741fc23720d68cd1f336a3711ad17e91e7a1945dfc60e0b445db1206de6c2ac2c30af2694bd122e99929000c9c454e41b3e23b1fa53fe65b0d433f186194e8f741299c78a7834745904389897aa4e578b9290ec8c9faabdb595de037ef5afa2aedf2816dd328f662db985c1fddb5e101d60cda51e4f5f14ba2f18bc9e924293938b0f441d2e96961ece0a930c9c3911d72dac197a8e25caa5cbf1167227f32d72cb244bdb86ed30ad8061f5e62c4a3f199be809e844e246fcd44c4736a4bf2e8e711f19fbf76952aca21b62f83dcd953043174f731827185cc32eb321c89de1467ef54ca335b859c44336e3a85c240a45bd6053e5f0215e3063bd78e67bb6723747f592c1f6d075f96af86ee13c093be442409c35f0a40abcebe600138de86cce0550f7f01db60c8f3584f79ef8257444f9c4bf051b76378d3ec40f2074d1e88eb8b8d753367a431c3df5ae1de132753333d9fb0b8ea126a3f7401193c1c754089ae0d3605da0f2b68be1aabb31ddb2e235e006b7eba221f6a853d475dde3fbd0160793dba34d771ab4f58be18ceb5d1b5ec239f3cf976dd70f82097b2ddf7bf391a062d80193a91deda17487b0dec42255055a57408c325103398c4329b6eb8e178f43a0079d0aeb8ee197b890c57c4a783aefd3ff0690f17f0c658aadd7679038db462c26cce2ce3dfcc8503f04cb8e62d963f67672968a001e5508840521ed1d395f9645eccda467d30573276bb8ae4db9214af101c33eb9b84d8d35ebf27226e07c50b717b6e4b6d4b6024a42418c30e90c492f25c97b887632c302c70bb5e435b2eebd2d49da7157b3b4b6755528fd235dbf81fc0d6563755a4af6ad31b8f30e87f27225a42a8c705caa1843058d2a460da7229a0727bd3cbe8a36ac512a0e92ca286348dafaf3fca2ef063140949528d9156d71be06cf9817db2778b371eae576549a036a2b5e3dbe0d55cb9a3673bb4f7aef9fee5e1519697ee0169a97eb34236cc6489c1fbfa495ae9029e7dea09f52f0e45434aec4fc232051ecffa22a705bf753b2856bd9932a1e097b859737b604fb615da30a36d3ab94031e1c70b02167914f20849db610d11c9c654ee71e29abc7b137a20e220ff2fa586b86b60b2c878f06e0eff466627f57d34300db8d4dcdb5dfe8d71ac81a1b3edae0c07dafcd74fd126edd2efedcf4c977725bd124052a4c2fc22d5ed8dca190822cb0d1c3bd1cc5a46f712ece2a314d8c1e0358dad03f0168679a0844fffd3990b482d39174273c44296f7a5208831c051305a92283fcd8fd8077b13a5255ce33795d723ea44d4e2cd1137c7fb6afc918a95384d4465c060e1b2fde76f5506f60640d93341018a621fb64289e4ccbdc12af2fe26f831a91a683d3824e371bfd36b437e875fc413c7103a94fb7a883cd119ff571a2d62f9a4ca247ff63a268f075bff2b0d4c1020e5462d19738db17e59199f05cd9500f9cfb3eb641dd7ec0fd05d2bdbbfeceae78badf6a4cd644ca630281daebca12455dd06fe3999d9f9bbdd145d710f55034ac0c58ec9219dcc9799461f7e111b1f75f586ce202e1427ebdb354e88d73b20cbf3c67614f779996700e98175710da5d39cd1c940d7cf1f54817810521db0366077973a6a4bf9797bd7afa6e6ea1d20e2fa786959aced85c231077578fc4c8353fa43b5f33dcb725a03490b269452a432c7b222c2f1800c325260ab9f5a0dc36a9db5bac062805ee2f0d0b1e67a736ef89e1ec90dc2fd956ab36bd5d7a0ead04bf6d3d596d5d1400ebb0fe9a1a33fda2d390bade257d1f54463a55a43a63155256d87c825920d6fae3f45fcc1ea7bfd50d7ac825fefc64f82dff3cd1f543a088151878dfe78ff1638b4dc244b8441ce4eb2a8eae6cf2af22e973092f0ad5a04b6b80fa21a2473230a51726fcd33a64c0c3b1bde6ba7520ffd3f90dcd55add03b8e633886eee0f40b201b0120705048f854bbdf621f34eea3c3331c7dc726266bc35dc43be4a1196e2efb448e07b7d00bff5fe69ff230426c552053c6abef804af511a73c11e4ae818150f18e4f6a1210f3b7fe4961cf22aa870ef823ba9e07a28318e60c807ca3a9270e93d44801179e46cf0ed5a84f3333671fff6f3f4d219aba17e74163651fe56211e21ea29ed41777c1b5a6e7ea612dfd29a6614e89437ee61245c1ecab82f9e40e75e2b5ab682a209aece515e836cc6dfba61a1b6e6176c7310f9c596282dd5c6cbd67783ac9309bd3aa7230cc3a250819e610df6ae2478750c8060f8b27d28a5d19eeb80d916c78638e3983507bb2994074a9c4cda5a686a56b860810b8ecafdae63209d09349d2260182888895817b167b6a9e9aa3c2efb321921a4e4920c1bb376355b2199176101a81ff15729c8190f71c8a5cd444cbb0786002975712697f4d870da58c015a41e467469edbda3c15488c5653d8b52bca04831117b2bbc652e11c594e5ebc44d4edb06277d0a723c65e68e9fc6fbba5f11c110dea3f1716e9beb2765aa9622b3193c98dfbd9defe7b23d751f1d0b33260884f9d41a8d0e989c530c0fc5f8567050a1b0fd117f73cfa49b8bcffc9f55e1e4feecf15202c2d73f13fc17b6e000d5bf88ba4a6cb5abc2e7879dedb3c3aaa883915b889b15020365f60573a9acd6cd4345e655b54e8825f95d7bfb72edf4578f28c8a1454c52cccc00e2b8ce825669370acc18bd185fd5d1d1120d5a6fa30ab81664c1e5b159d2dccbff7c3eba0877a3e72eb21d5f376a107d5940b53e6ad8c041683b421b754ce3d48cf24e0aee8f846b218ede2d04870a317a18b77ca6002b200d014b9093f533b1aba2617e5652f9b93c064959fe7371e38edb9f5bd4f5719e381ea8ea3ca87312423b3358a7d782706201cadb2656d8025bd46aa2f727d6ed8770f972b1b7fe0369d7f208fa63de4fa13917893e4e9081baf2861c1d27f1b24fea93ee359fce25f9be0731365e11b686a8153a7bc7f9a45b37d151f78b68c108fd50c6003bac3556577bd366547f0300393a1d1234f9a4e08509cc112f23fa6c344a3dac5ea1b8919d43c9d7af07f2d11706e6872e069ecb5997bf9d731cb04ea2515a9b5370495741fd333853760b6fd320936b675ffbd123fba8260016fc3fc4d36374c1615e6c32d709abc3388888d1932c9a82d5fc7979a0e1f7e561b790ee080c31b77bcf27b5c07831c90454e220643dc379074a99b865411a417bb65a3b48c051c1ee2844be7bbcc8f21d08033278d4a964cae6a9f57dfb33bae59ba06ee962a7bce8f14caa62262b0b03aecc7744b9ed6d42de18f20061677fd1921a1d384dc6b6df447c7161ae8414d8abcc7822ec71b2ebd7a1e99a3c260d5c059c6bdc55f39c6bdc7c92f30242c45140e54172c5891dc4850748f0bdbe41e5f91a0b08245cf1affe265599c4a47c2974213cd32425cdb20a7ca654010f9cde92abb42c49e13e04ed7704287cb4d103ce3487d82e2b72b07b0f493c4fb0366580668b9492d3a7e5e7eec7bfee80f1154d9964bcc238e6bef1f38cd92dfdce346b688702bcfc330cac28373fa7dd8f4bbc5a645b1a80b4fb01214cc5a10cdfc3edb53afad7b8b213074a6fa43c4c6b22e0ef683f8287746aa15d9d4701b289e7b174537a3bbc68e233bcd94cb0c629cfb410f9610dba2f7a1cec4ca151681784edc10f60c0f5ae219cc4dbe93fbecd6ddc523c0dacbdd4f3b2319ad68116504a69026c2e63e4569c4be81f920d084d9c57ecf94e31ae8bd7ef104e6d61d7ad5290b86355b44b86f2896100b15f66db22334d570f31cc65ccb13fdf37e7772b9a0b133441a04571e31f42f51504df1d65603fcf82d03eb6121e93121c8d8a61c641e022a3943071677b82c5bde43dd67ed6a465febb19e27cb2ddc20487bfdd55b2304299f8e4ccb262e11f8f868799f8a7fe01202ac8df53e8922be363f6c7a3dbea386ef93d4e8050cc1f8b09be90dfd018dacb71b1e9effd9fc98ff194c6b11d8d2dab833b1981f55e0f1e81ea97933f2f9a86ffaf72b6429b2372ad81fe1eac195af3fc6a28c44b11b8b6c9c4623adef21b49e7dc98f2868090447d4cda0149971f4d11b64f7eb18e0557e37703de287a2e928de4e7e2423801f9b396f3d6784e84d0488de1d7f9fef7b1b5068d07fa71f3d2df56b077d52ed470d140b1ff9a59f37aa718f706a78abf6a3ca48ef0122b1f6373fee05b5bbad020bbc5fbcb0498b81e145cfbdc5b16af94f43dd665dde56a1f83b6d503af027c5fa595c2662f0b5403c1383e7c2133ce7b91045b33d576bf87fb0639006e018f758aef821e760c45797ef0955dfc8f5131a49d6a1f370288e3867d482a32f3a143ab3ac1104415967d11c0efaf401066350dad565da46d4ebafc63f2961894a010b842cdd524cf955fcb715ad5b9251798dcab1bdf75faf3ab0db3e56e86777abd3be3e6f5555a52f380c8399d03760c71997a767750597b18e9883958f085dc7ffcf5e9542335342b50ee3393b0b716e2b99a4adfa3135d593d8d00c63b56f7cf3ced063daf8c45c7062de5fabe1a3ba78fd795cf4d37a33ab67116548275e274aff91e68460c026a37c9a91ea2f30f34f5d406bdc744e474ca7728236b54cb23f8f914e5fdd70908599d8f7d1340b847b69829aa6c0989a7057332ca1c75d0036f001f576dcc38bad39d514091c10b37ee48368441b089b12ae40ab362bb04d2cdcc46fb11281a09b0c8f5cbef944dd44f59de75e8c04e77838bb8738418181bf649c0eac2439ebca23f5057ef39c52e864723a5f81be04de1178a6b7e3b87175ad05c7e84f195af21230a8099c022ab837389d75b89c259accfde4269f3adfb3f07fdcc8b9170f3deabb471c732788b80dd3500775f5ef94813ea90962b69f4dfc2f7661d869cb9a4de44de2683575474980478311f4ce1eb6cf0ba4579402b9eaf0c3962dfe19820b5e5aa28b243c5f4912d8bb6210bfcfe919ba3c086cfa82258552ea6b5999226dbe39fa059d8f0121d0b71d3cc08dffc3ff4b0ed43129fe10363e0939fa88ef52184e23ef0b68d641f2d3c5c7e12115da4b152cae0a5b92c0afe29b6d9be0847eaae4e31d52ec2b6946425f9054668a69c48e6ae4de2ef9c38f42884252e796f9f92d40aa6114230c7271878b8572a0173f29117a92742431f1735040dc751d68ced3c0c5b52ae104f9789b6e633a22b8c44d5bf410ab9b6dd7cf329cf7430663118f6106bf8ff76bef5af9d25583af65708c11afe2461e068806d0f48f1c18547e2f3a6b6969c2befe019dfbbc46ff6269925bb61c878ac79a66e98ac9da48c7ea6c68573c710aae1b568c2a03b084408ac673a9f0db30479c307e3b30f5e89c0ad1d8f426f2ef1852d4e5358d519af7597dc9aa2d054fec4aee64c97a8cfa26b9dbdd638f99998ce98d72061f6223aba9199f4525dc0c400049c3d1965483fe989957720998264d08bfa84956647f07c94bbb8c2cdf45c76a6cf580959f66dabdd608133e3c16dc3adf51174c122779a0e3dd2f902d8a1a72971a8a52b5559c6ebd31b7f342d50e09aa4e9324248dd2ba84556969f3dac2e28a7216503842c1e64f47388e8654f87daf353ccce540304b158cf57ce458e407fbaecfb313c77dff861c27eb20c520e8058e740765e9b36d969e61a93c3a5444c4b4128e534da563f69e8e0247e1a223650dcb6b7a9a1639ef3f04a64847b366702a03cc71b6b7f6deca7a13175d2a7cb38e28e0e2d0382190797779b22f75edfb8f632cf6fe03ce3e85958ccbe1f0ead7a1c169d5649f2717fa2ca82b46f7ba73aa880e3753d0f4274f8721058bc92e4cb005d00b342795ec6f00ed818bb738cb836a0557e604b177936b1b4a09100257c58f4d9c8671bfda12f951ba420004d205733da09758d3bb10a0191a329166cee7ec54c58ef300f492c83d00e821d078230a2847ecfc074dcfa36894dea36c60e0115febacf25a8a2c56d80116c15d653ac9b528333ede1927e1cb5d66cb46f1af99a25e1c2d0298a26a1e89760ceff2ae7c88b93f868a8e37e6f9e23a16264d5e3844cf076bb50bf2fbceee0e67d0cf18209d8e7caaa626fc5aa9291ccb67180b1d4a5f169cfd5dde891e59ba6f8d340db954155ab7e920e71c6d7c08681d6b6e1f50450fcd6ae1c4075009c2ecdb2a16bcc93187b1e1cde7b15d8ac783e6e4eabb0e86fcd028f55d4fa3b66b2cf51418804b8058066e05a0ce5e3a7f8fda8903c7e80a38206fb3186e2a9c945e655809f5653fd207fc858430f3421fc9ff6e2e82afb9912d21f614f529d4382a088e3fa55170f6dbb42c6b1448ca5696cfac0ebb8a3c074d013a6ecff8672f104b0b7d33bc1cdedfe60ae1b6be002a3d7293c8841d095a3ddef2f6c51023a2382907a7a54ec8d61be28bd7d75a2506637717044ac6f5eb5de452e5397fdab06d91cf7355e8379ef174e3e1725d5fc769d24044d05951649fc4e25199644fc638e460aa10508f4d66fd20888400007b4a47153f907bbb17b94516b8d261e294efbfe76613b9d87715d0049a0df76cf6c996fcac410a18e428013f706b846fec1ffa42f47bce9a4c7c633f7386d0b8481a05b112f54d4a11ea0d36ad59b67b045c2000f94f4d07de599a6c2fbd8b2ae6b0952a47b2273e5fd687fa79a5824002b4d0ccd2756feb88fc872103c3d1dafde59420e3d4ff27523fd6cede948280f6b229c205b4f83c8a723937d476d746c46235c000e3862c3b69c254b88d66b71973ca0b57e97330ff4a00943756a0e75e9a88010e993b22872bfb1bd0b56bc6d90e45c09697d22a8a850510a67b809a7e0bddb620c4fffb14d8594bb6463688c65b3ca38b7e5341ae8ac33bae0a22de3982627f8b9df18edcac70d25b5b4684467fb40702935094b33e7bace4b6f786ca443099f1cc1ac19e0fb27dabc4be3aa7789a4fc06f9deec2b2e0fed0cb33c6e91d52dec37487b2f1f726c9275467c9004c26b3cc09a951af20ce2e07eebae89f0152ac26ca74857cae7168e125ce784b5713c05cbfcdae6bf35691d68bc4fd4ac69894317a37faad4268dd64f842bad528fb5a1ae9a6e4bb93d1e99b4d34546fc3e0c72117d5b245a1f01db2b4004b6f17e693f418b53df6288d6414ae282b4cac32d05be00d5300592fb9591ec4bfaa473c270e703296188da70de9c5f131a66a42668c936e2370a080038915f414d1b5eff03e6a847ec238477cfedc8ef7b6977348113495edc0be3f3105dc86a8db236213703a59b020c778f5a84566f7aab7420ccbf704c5bf32248c46b0923d9c104e9acf097e6f2d0ffe3896c42b5b79bdda37c17778140f03acfbe7c5ab59f6db00a01241ea7b9f745b7b35885fcfd6aba133633c442735804eafef39552e808ae7cd07785f5db42b6071a77902af87b16470a6f8e5dda92ad353c94116d79d023dc27eb0058ce0fa61f6777e967b3ed0bc217f40afa274f74506cda969ff2a1ec6d913ec8665f570b97c06defb60ec6d4d118baf6a65ea8e850c8becaa12c184ddc4c1ce2dfec8b12b5475628d47320648bd6f249c8fa97a7305b70b9118166e144b9dc49f0cd27daf9eaed60a2acb23ce9600dddcfdb297c1ad05f3d35d4279f31426cedc128093cc8beebae5643a62f4c3b9c80dcc84c68d1abf826e8e2cee9e533591e488cefdef44eccbfa5bb5acaddc0cf402aa358c8276b755b75ef53276d2be006f305e993fd2a3ee0f9225fb5f9ff5461ac6d1259614a89027a1f7eb7f88ef40d509c600b4dabcef57220c3a5bb5d842943521f8c955e7458a770e61d3b7fdbb994c2e7305de544a931ba5445a3d22c6c05c34c795a3a042de5eabaaf009883bc9655f28807a3ec8ca6a0bae7eabc27813ee2e538fb172c88f0f9d5dbae933052070edfe173a1932a982ca64f44bd234fee87fc986dcd9766091da95fbe2de8b4d7453df07cd1e2f3064702942c82db6aa2b317c415771bc8954e03beac012298db8f38bb27c6adb961fe2d0aa08328fc6b7c4c706678a12955e5dd3fc695cc5b65845667ae88330b491fa4d0cc8e50521394161ed6846d9ca84b0b6b039da403a936e83bc9c0042de999c0b58bf5cf7a4c221ce9ea71abaa7069d1b51d4dee915bc51ec2e6141740e7c6ffbf72e7544b988a3b04636134d4fd5ffbd447cb2771f382958481851e7daa31d5422679e92fc169e4ae0a45047d75a427c0a32b85bfb181f4eb52675522748a0a61d3f7da2eaf5f497534d4e0ab086372609301c243328c5d738b5738167467ad1e8ef2e182326477ed8eebdbe5c3af2bb83871c3d18029a73128cc18dae2c233f7a43dda029c5b8e63663f629282baa6dc55941ae6a6f1745c508741d2aa1ff35bd2c823c0729bcdf0f90a016742714629f865e4b3ee55d34b5c32b4fe1dc05842f4e7e2261f44721e84bb9ee2a1fd023b13cce567e9d041be95360335e8660fb236aa2b75c288898e297a66b3873e895c84ae0398a5fc1c1973cd3cc13c9f3f253fde5c6bb0ed3daea6f4f49139a2fed13770f22a67f0f758d5774d381486c9a977716e68750e6ee3ec90492ca422cebfec8fee0246518ee2ef1c6b558593fcad4f4c1d0a0fcb045bb20b2b2558d7546a99152e2dcb8289e9be89746b66ac9c7002b9acaa9a747840663eb561931ee55ab629f1d0644ac016e62b7a0f748964805d08164a075ea76e8fc3acf5750250c433f2e34d9f8e9e644ef54da44051f4e8d945b36f1a5d25e3a1086436379bc883bb565aed9503c86554409e100f980beea9fd13120f074fe29cd9cd4db1ecb0e54eb06a748f434cd82679781235105a2f202034c4285de12ecae65f438210f987274020820e09f505a872419d9ad49d8bb1b933388efabf4fdbf63be3fd67949e60c22e72817df2882eb7b58dcfe404a61b57f66c51fbf48c9258f85da5ad1d424ed9a0b39d16e9dae33862eb1e247068efd24c1386c12961bafff38c62430eccdc42d7f5e161c6df42d7bff6e751054a624822c1f12907a7aff2407582b5c3e6d9625d28bd602331004e6bf5ebbb7cea4253ee1d39d4cb6e0590dd94c3df033eae9d109e82072a49d62ef72b82d6fa5a21ea0aad3bec7b5c7fde1a09abdb2bdf2d0fb35ba36edca03412b6a1950e6f38af1f24c2b6b9f1b9ca4facbc9fd63776accafb5c204ebc534b07198b3c0973ed86b154593d3a31361da0e25090d1bd1bd208c58cbe9aa2923846c67fd530c3a7ba342fbfcd6b8be2779c314dfeb5b3ed68c8d5a226325aa6e8ee7dcb528b2701983bfb45b5a7c54dc9e2bf60a53927783919ffc4f9273fcddf93f71d7b1474dfb3fd63e3570083d4b3140c4f3e8fd540ed0bfadd31df1f3be1d724352b5e1beaa308ecd6ddd88c0e229ba8dcda345e1ad59389e1c553893ba0500d2101d242952f106bc0504647737c488c2db7a1c1e79eb22c27c5da471a10d794fedcece1eb887509874938707349e45cb987f3d5a51b8c8ad7191f1d12ce1969157b97c6e298baecc14f5e0fa415b9d21947a0aab23bde7f017c83e9e2bd20ec51e9f68a4cd50c490ced22903620469adf5d659ad8bb129cdabb4878431d0f11d92a59a7845072ec6236ce7d255600b3eb695af63f023f40e040e4213a3a5a088303211ae7be4599c83c8c37b3906e6b871cdfea49b2ac36bbffb1c0a56e6b3b90898b4e874b77d925d0c41bbf6b6eac8b24fc15485ae88fc125a216fa7c4912fccc4d49cfae8a628c6dda2ffdb1213d0b9500b550d01033bdc8accada7417c535179dcfddd8ba714455c047789a0cd4ef04d63e5054db84bb87f8ab2c4aec1bcf4a077c8efa586fe89986a303d3a081e4314fa5bc81f156427c6858af5a2d4b1c5fafc828b211778de8f1e987f45930146b81973bff6a10fae72067ed80aaebd9df48aaee880a6c07127816473a96a46e154de2d8e819b78afdc98dac00f1b32a771c310ac492ace321a2498eed420881bf3e888911b40107161c2b2786d434cab9339645001addf0393a82ae01b723d1567fd68a82ca63f8cf9bb31cf161732cebf133ebc17dad0f662a151253a06252111f01bdcc990f371a2ba212d3cbb68b1c742c93db737790775230eb70cdaf7261a95537f87bbf4c341e151c11868ff0fb320a59975b94271b5f05218c929d1803f5e59762c9f3ce373714d504d0cf9274048e361ad45409709842127a1cd3fd513cc8391a846e20cafa8682585df76aae6490f3cde58bae4765aad67296d0ef8ee5c72c1d43d53a06184e0ca03da4f39b1580ee425d784d0ef538fbb9b04249c3295d311cb0541c8a82ba36eaefc6e0b5c31ea1e14fc2ec1f2bd241fe45b836efc20f0d127936b3a3af8e91704f3fea69534ac3e57b804d927981fed178359a0f42b197e7c0fed5ec9c7f09a461f57041b6ed4db7cfb0756beea898688cc2c5bf8142f09600f4ca850ac3694aae8ee41867d4b47450d7a14227644afdfd36b5cf36beca73f54fb4ca237ab22be52bcdd61e67c4ce1c2fd45a54fbfcc233605e69f8e6818655212eccd14833599cd5410b01b3da5a8035bce2eb06e7b309711582736481078ec4aa30bdec4070911b7034b37b50af974fb60b2679ab0c92655c3aab89800e30d4b679e9ed3f99a2ec843087e6f6ceef1386f78bea32e1433064ee94dfca9931160c24e8b121a32a4847f878f98c585a8a8b6872138e144a12dfaec76b09103576186ad1f428a125c90634aba50027e102cf67b2aae4d759609b4ba666ce609074f8fce3a00dcdc7de0ca406ad220135821316466d8a8c15e0c8c4b7ae01c096eef8492ad0668e23faa6542ae10a0aa2d44dcf048c68e1d6a1b7e64d60ca49c0c86812fda0242a18138189fb3409bba63e5c533ba3e5ed7c893963870c22d1aa6d29e6be626326e2bb768bef97bd20a74e709a298ccf9a4adf4c0ed47770ed5ff49cb28a5f230399c992d8bceb1f9414269f9299cf3608ddf878b326d5a34902abb259579ce0649a2c4b8f0ee9b0871c9382c701fe865a04b2f9828a0a24f41013fb645ef570dcef55d118fcf727f1f5dfcfe9522faeff83e40e16e36f92ebe895eedc28baf9c8c10adf8b24b7975a1d23ac632c774c42e0c30f69fc5ee1cec3b8aac212a65d82564d885685d4a5b5c389cccc50cfff1527e37291f678bed0a38ac0cfb8a39c7e980ed9c88c062310b5f2083f4fba0b90048897fc610a1a68c162292b6316ad791aca54b1a8200126d8b1b0a92b25b29e7265829204b5a5c5537566db6802c49fd563342431b64e9d89a5e7c8b7fb85da995be347703e9ee9c4b9ea4b38ba44ad31b2d3d022a6c22488115e89802dd3cb10caa2564fa70d22305dee65dba7a8be31b873bf3a2de96f474c86e67292833e808c5de694642d629af2ba39143da8ad6369cc934fc93b969a5c88b689212b1bc7940fe38828a582fc3772d549b894c20260cae4e5a42abc580ac25e9414dad642c5cb5c91e010dd6446bf3c6e16c5e5faeaa7e8a2510e353338b0f6ec824fe9e3e4a6f2db2be6c0990129b9647e1cbf8ccfd8b9fa11f059fe77ca9928df4eb23871b5d719ac78f4cf5c75c235ff519401bdb38127a13e990cc54f31d1e8474d2b937ba018e6ae7dfba6851476be6c3bf70bb997f94d07094d05c972f009e45ffe9522605d09e578d63e08c0f8281a9702f4b01a622450de486bfe171a79f37cf172df40f8fd90c6a54074a04eda778e4a203d52accd8deee3658986d268d8d48213ddabfa940243020f14fa1599963e7a2d7cfc7c2be3f03558fabf0f1f7a98ed58f9c9f8f192a5a61407ebf09d4f6c851cb633d2d575fb6ebc27cd8b8610bc632ec109a5ed8c8eaa9b2d91d0bfd5febabdb508fb7a320825861b60c8fd3e786e26bb08098b5918e66e2d8bf769dfdedb408bfaca09a1a5b3bda810c67eb9205291774a3f11578cb4142dd1bf60c0cfa8df9de14d5cad4e8b5e60acc6d0abd5cc045c452f5ea16bbdad2160dceecacddcd75357880eb03c5b9105b3e2b692ac6fc7ec6d685c0398b13ca33b964cf269910cce7f51ea2da00ac8354627ea11526efbf4a43bddbd0aa6c1d66190060f4a7d4f17ad091013e914df9d04108335d370a9abeec296b57c83f0a92a4f90e6decbdc281e8ec4f05141e7c2ba52743e5d35ee4f1e86b5ccc37f03dd553deb4eba94232124c6c1e91beb35ded23af4c5ac74c372ece515109d663cd212e2b87d6848283a028064004c8a058ea0174c18c8ded46c80312a633366aaccd61ed37e6211469c74e0ed5a0efcfd31623efd2002d023a7ffbae77c66e82975a924e0fadca5512c0f90a3de59bfafb2b39f886e881a0c4a6df4034534694c65418e8f18a4bb2f5cf76361877347648dfcd9ed1238c133862438fc16a3234b0424778ec9f6079eb54268f7a9718b4cfa49bc69a93ffc05ba89681876b593c2a9305ba0569203cdeeb315c0e2dc309e2b9588c5a3b536d3f986f7f0ea36d66699ddcd3b58e9a2a2234c475f7e37890a30810e7198fb09046b4670aa6e88bf9ffd068cca8b007aeedd3a7d19811c1cf6f476f34f2dbf6e58870bdc6e309465a3332725473e0cd6dbf000b98f426c3e7774a4903886b929d7092090505d83b8e8825acb5e03ad688425216c9f823c6e19d125caf7a8932a549bdc424b7d3bcca05d48657e88d11795c86c5a8a0277d18743012f1c56e20d8b0e67a032b693675fd73bb11d3c762b4434be5a2e7476c407aeab4150dbde7fda3cee062a08d8a1641310365a8008449ce9406011eb20946e384c65eae2c6f12be9d34c674e20110da78cb1aaa4dba644d917fa8418a2548ab43589bfb225f144eae4c108323e718b9fadebb769bac87bc7e65928dad24dc136ee6bda12416234458dcdf0b8ef6a432931536207cc369a3d5dd64b1a78fcb4c6f2e64a9ac65b3bbc8a5eaa368f794a6c1d2203e73ca11e2f88b730d67310e0c1203ee997c170ec631eadc41e84da45d1ef9a380647d02ed7d7057d0602f252bf92e6b661588a6c74d008c4a20f798ef7a5a05775375de0b6832d4a1313836a00c1093655a027042c19655701bdf70a191f25c635f43c6ca702806049f6e28d527264be0a7ee6020ebf3e41e190a97476448557e2d495e6c62b9be7796072012569a61403d83b3c5f2e316a9e5e404e2e048be731e4a398ade164a66c3dfc2493f821d15986c5e9f53deaabb3a669f2c549c9b43d91fe52dbc1d9144d1ede9b88f24d8496f733a5ab2cb356f7540a4a00334a6f50a384bc147fc9df7286141f253b85cd8d9ad6cb1c67ceeb0eebca0adc0ee7243393e0b6f0aed4f0b8cdb568b69cbc4b59127abbb1b722b2ea02797b61bbbb4442699d6ad317273a399ba876eb2117a7d6477458b8868be926113e39bd787944cef498e6b209ff2727e36c8e630e6fb8c1e9627841b3c724bedfc836c6a5d262b3685fff41b3cdd43ffe912b925f252918a2b4e8a1bc8ed64b78e30c07ff494bd1a25b037c807ee65b0d51a6e17136e5bd43f969c51721b1933917abc4f088bdd0f54066985fe7799fa89aad665bc626998684952d1ac889a7c1d6448988dfe9146b7632a2248c56d21a6b08dfea94c416026d6edaa06e5eb4d2698a7a15e4a775c1033f01fd31a80170e78b66a9c719c51e8c3432316982ab83c0a422c16230a9c9cea59b9c109c398a2500ea109cf8989cf30ce30a513156afb1298c1945816c68159425f17f270a6ea4c1e31e13f8c733272a66ce57b58772664db4158276520d31800ea81d6aea73513148db32e15040edb0d166b0582cc310e424b574fb038948a33219c73db36dfe506614c0971613d3b06db9abf243f99b2709f66610fae1c620fa1d63571e0b8452e68ff0a8129ae23360f186f441de681a428dbbd92c4bbbf373741f16336184cd2e5c392c861c50f98f78ad42ec2b6ec8e9a9f56546ab2a7907091b25cae0b7925873029ad24ebb4ecc8927b8ee62926057b64e77ad6d8648b97cbeeff2b9150f02e38cf6f33f7c10d65d9b31a6c9dc02bfbdec3663aa071aeac7f40ace032bbc7e13ff19c1f3dd0f3c5d9feab5b190a1ade7c19ce7f3f1aaa35fb99f14bb3e25e31ab9638d7174c637e750b23ea85c0874d7d9970cb6821745a344947fd156886a835d39e89d5923717fc9c1f9ad37e782423f819e5fc3a829f7f5d2009d9c2a703e2f64ae0603764cffdf18597901f16881d51e59ab08bb47085b22cc32a8eed648a0a58aed49367cbb02c4cacfccacf185ef73dfabbeb2cf754fba94c752ef5a8b6bc5aa07d5bb5306e5c8bb6685469b24ea1e7b96d74289c5d9d53bf9c1c658fb9e224344e0164861cec3f6b1ef3584407c7605811888fb99e251c863e0a0b7ff34c58cd52bff74b802a759e8267ef0dbb6823da9595984ba10996a7ddd58f126660aa414d8645419164ffed8852cb98859c683d7e145ec93c123946f5db584f71c8bc0c1fbce4c7e84e6ea35f6e1fe0d04798604bff4f64a4b56d1b08238d0eb57f0352ddac8a89f7b302f9af9ad18917166438c8a4fbc767961dcc74bf0636868d8347ad5ff2db1a1130dba4dc5712b1c60b93ca3d9348fdc93a1792189e7a07a72a389744a6cdb4d2ee5a25ac426f1b67177be81b540faba454ddcf7a3a7f181401d169b9887afc443fffe860b108711f2030e27b4d2e06f393f18d13f2f845ca56b148c183a73afdaa16335da344426ab2b3bf2034da54e02e9b73ce48b80f32982a81f128607d41b1f57fbbd703fd99cf82ad23988240b8206167f7cce76e4331290e27087724c10539c5486dd3a8c6fd1e58c7f669a44df48fb7606aa56bb6dd8a63679f9ef74a301462dbcd7ace1771b9ccca1412e0394befd20696161abd4cce75d068599d6cc5466f0bdd0c6911824834340f8c02a65b40096edeb8112790878d7c4fdc0c46bf09b3edb786b9010ab13abc65633ce5bf3501116fee19e2c50392b4ab0d79f161805042422c571c31faff86944d5248400020cf97b20e42878ad36170977bc0cf1a941f524ce6070c28c8079cb434aaf0e9c290849691d4c19df2cc09e18c98495c7bee40396b29fcb9b1550941ec476461b675cd8f9e87dec9cb911a2bfd22cc4080bc74b9eb0ee8b2f559e07a038f83486a00ede77fa3153bc3531d05a2de27f60f7cb2eb81d611a467fe68d1db4d3d132761ec3306f234f89d04ef838e4364a30fcd56015384614438d624584f6b3f050437f1ee4f1d2f6351fe9c98c63bb448af0269696596096603a03f97c320bb562181116213df86e6a9d28e8bc7f8471ff93b9ffbc1fff82196d7224b2f3ec6638fef72bca8935ae47d4d43ba8b2c823a499a85207eaaa75cbda8e595e48af2bec60dff7e01dfe81a7859e432aaa9c579db0182a25282e8d22f39cb00fe54c234e00080cdd7fce73f90a2aec7528840d3912b42f881bc3980d080f22aecc743ea21c4a20b65a05e0918935bc3c7d90c4b69987b29eb8e0a3c540bee389a296641fd03be0eb19416a919565c8935ffefd5d6a4c2ad78434c941549badd75bd0aaccb9c79270489a852ce191ccfc1d0c9643d798f87058a3c4937fb55368a070962ddcb7eb6b3a8b913b4ace15f40973047b3ad07f227614f7a33999bdfb81aa97e2a5f2af456fc6398089ff39ea52c00ff0b49d38405ea6dc0605b6ae27ac8c1b63407e48826b4473372ee44f295556598f9540a2019247f2e2bc583bd193c24bcdade7898bd3860348274ee55c747e1ffcbe3e207a803dfa40197fc4aa7a8c913788ed175f00427fd8465b1200026f6a05c45dd81b2bdb3e03a68f78129f131ed91fd9126f0b532641a5a2d6e55b1d1c87a8e7e5ba8e77445f770b3c345a04ff73cb78e1d711d1d49c6fe3b8fa2786bd36f5f1ccce5c44c4585abeaaaa2a925d680e27131979597f8e816080a94d5d807f6d5758a703c5cbcf60890c892cda68fc4cc28d257ec94afb67ec502c405d815bf001c8bcc8dac087867a160474ecb7e15a1d1f98baf8bb4016a5132fea6ff0e2abae9258ed7ad35ffe05a63d481af66895b7f1c40290064274f904c501338ccfaa38113d19490f1c0502d5c2a9659810bbb008d096da31d4b6926b3a8f6f1b34ecb46c70acbd2c1339a106def86bd7ef16b92ce96527a25da7982d708d77e465fa4c2d0d99eb80b278f276ff3356f504550119667fbe023767a611a7b4c4610da6cf07b6c1f85a102a9deb7bc0030fd79bbefcd51dab3bcd9e83eae1c7153599f74467d31a9a7560ea835be53dbd6a10dda2b7b3b016d548fb1fd4eeacc0670e65892b3c44a97d311d5a0d81e00bce562153a542a9a0eb342f77de6bf120cc76a499ae9d9b28e0a670e4d019ceb5110ba2800350a33b6b713466ea653ced18ded938bde02a6d6872e081f3ec9786063e3423a87bcd28d01d062813a46d1660d5c72d9346a57e5c0b5c65ba68ec9b1aea25d37069c4bae9da451280c103e44c0490e5c7e332deb5b680a420b0beda011c6cb22fc5338ba6d498ac5bbc4fcb616ae778a67cd835958a6660e45fe5bb8cf933351e0974656e0d2cc1af7f9d1633bcddaa53240b1f4bcbad6d1cec99844a7a67333617b4ac7389b7951d33a5e53900f0f5a8865ccfc43c2028239f967eb9540a9543e09ebe8dd21a0455cafe4351166d9f1a8c5da247f793910c228daced4deefea65812cab583bce41ab227cf70ac652a9349b3b1e39c88379c848a540332041bd8999c1cdad039eb99bd5da5ccc5a3b7182234b2858bd1304f72d378ea8d29d7588c899f7bb8737c97330ef39fa4aed020b455d106d701d6ec18f237649816af345a54fad527a35f3da9acde7cca90c9695dd71d85f2b9291e067c525a48c1875fc9d2a0e1a01d891784a364cec49863d92e95ad64650665b7521100f74f45d8f1d85873b829edea28eb39929aaf51c97edb7ff84f45bac1e5d9877f825282c81708317f24e7fa8ef24410867c9952b00fb42eac58787b2c0d71262758b1955e950e19443d1038682f4c2758917e9ce39355f32178eaa372645b314c74e1c7bfc6b45d4c4bbc5677deeab0249b3754f8d825e5ecd6a2777264744dc5b53c33671c0c04f777eafd93b85b511e8d6eda2eb0d7455436a581989ecbc1a9e6b6fc01c4900b80851dc8acd21974b853616009f33863a8aeade9abc66f8ef426ee06c17d737a0f6bc9d27bae1f8f5677fa5172772e6cf2cec215c65fd030d77eaba1766486c63f05d0e37433970556eea16f956e0636a30a8a18ab0bb83de845491191f82d3d9b0756aa52a7a2c77f0fe668ac8bd2e07b73a8a0fec5f1ecece9cb4de79c43b0e3a284ab49d5649a887b25a159ae8609799f30c07e7f01fe73a26dd9a91428caaf0d18d1a38cfd5ce64eb3b68dd764514577d1ecf91f1a8b1e063d398994c895d0a7ea662ab0f658f01b73844d950e633ac189031c9dfe01fa72dfed84443db2dc996d8675fc614ca02495edb7cacaea90c70afcec5851e407f77bec396de11d0cd7ed7b735365914ee8ea94ec71d243053347cd2faf9140c29b203408c48be789db612fb0f95483d29edc164c3fe4e830bf44c232f3c155c54a52ec85a8a9087758b489fc14099b3048b482403a1dacd412715938f842d68272864175988698bfcdcce9032149b08545e16a6221926757005fa5375874dacc7795c2365fc6a9c4d65bed81db7d452d023a46c3d130adf1f5e446a7ef271fa5425e3f7816fb413e611612b172ff954277aa37637150c1e39226c0c1579a68b01dccd4db71df4670f3ae80e4e1465bcf1c0293472df1040b0fd246beec72fcc229b566dad34a0d21c469d75688e2cb3e36a39a7f7d86d98f292a93d401fb507b51e9c59dc5c8ea12b4a490faab5b20f14ad0a00bd083869a23e7f3d7d2e1207bb0c7df0c7d88caaf2ec6df68125fdb209069f85f83a642635501eb39d8743d5a9b797a15118167c1a9759b4e249a87b5f386515000d920a95dd288fd5948c5dcbafb410e5d3d583f39b3d7aa263aab7f10f8402b2cc18a1a8aba76c5d67807b33cf75c22ebd2b48c1e54de85b4ebcbdbd180e65cb194be7a914db55e6f4a8907dff6abcce5e7f7bf0eeeadc9dcc3144b969e58f3fb30ebf6079e62e1370d36915cc8a80f330a48d05c7a4a90af3e668325c0d68ed2c56d78c990175713ea670cfe386e1ff72df96ac8a97b1d0b0cee0210183a9bc584106a70067b2457a164f7f917ebc23667a1314f4c09fdc8ed19c2a32c59438b1148316ebb912429186c5b2b7bc8a1e976392a57e96aab63c0dca99e0bfae2adcb4dc2a1977238ef1fb14f4ba6f3be5491762421941eb3e3cdb47b3c591ccb5f7a7db82cf211626d88c0fe56236fcbb18f6289311e5241689f73b62aaae047fd99467e90775beef9a6503c4c803fad62e915a30ce3a4e0716a34efed0116baeccf673612c582ba80e8f4e31ed5bbd350a3680922b02aa711418ac59c3ebd54eafaf0f8002484f2aead856dd08c5fe522e6368302d5a3e0ca6c8c9853a695f44929116d2f66e6b724b995292324a092e091c0971474aee475eeffe813cd4c1a21abd8b1116e4b1c97b57bb6cf3ce12258a13f4b179318a8208295eb8fc308b98cb0f02f7c35d4da2050f683081d4021606126228092b50980006436ac4989d2732090a0a9221c62c832ef7a0e5323333730ff7c338576c01b3105109e3440bd79d5062e4c4174f3c01450e509891a58aebcfc3fdf89325ac1d1f5355b04505385cfe02703fdc2160cad6840ed7dffd691365ae7f8fdac40c62084969610732d8887db0eb100b217218c2891158a42106a4de869729ca5089a95f8504e07e3a9e0180cb3f00ca030d133d7cc0fd380c0458ac6061e3fac32a50099a24d1440ac238498209cc32822958ace4e0c50e4d9c0d275c989a07f7e33e001e4b6c59828dcb0f9770e1f27bc0fdf03f91822b3eb8fe3adc8f531fa2d4745043b8df16450a7850e28acb2f80ea039a1a0e7c7500259c5c7e7845cce57f713fec2a98e2854617f7d3115e91e2f20780fb612ac596c41249b471fd3738809638c5fd361434d1e3fa53149c71fd35a8082041d10986a0e2046a5cff1ceec73b1e681cc5cd739000e301c0fdb8143538312483108479e20f9380104ec4507102468b1862fe2ee93360268e8298e1242df7e321985eb8fd1ef389b9039e23da4002cce57f173f2cbafccffd70004430a60005b85f07455c0133a205235870040878c400cc162d38d062002f63ca9c4103d3545963032b51ac2499200b113d1091e5fafbd070fd4900325474fd85a0504494eb9f820a2ce888412e10c5f73002e8f14300d00b1c43021cae7b70dd880444257852823586c0e2fac37a7c8660e3fa9300444815125cff1c64604c08008fdc7f08c1458710634c89624a1295a2eb8fc3fdf801daf8f203882fb2086209214070fd5b29185184461a2e90e00445403ed41006164b4e9064c4c5d3f08054c2a185007646e005104b8c8088cb7f030a13a68efb695ee1dcfc8082cb2358f24394cb7ff350c4b0110116979fc5fd70c74341414120b0595101e607111c733f780642317e95c41c9ca4b9feee4fc15cffdaf550c6f5ff103071fd5d42d0e84995ebdf03e585ebef03858beb4f820f58ae3f10231fd25c378a920211d75f05232946d78d4410c4f58f424d78d0a2823e6a620fb8c549918afbe14e044d86e810d0020f678050b91fef10e064e5e37e383bccd0650731d7bfe3e1caf547bd7f5369b20577e27edadfc765fe2a860e43979feba448516d59ce5c7e8d071c4c39c4a02761aabbbb7b3708c65cfeec0059d4cf7bdc6f858399ebefee20a0d2f99310bfb10471c475eebabbbbab796a6575a9df8f08a56371430e97b530ba418ccb5f7160e2f27bf70311ac864759983a0f4a5c3f5df75f40107777df76e0ed005c366202e532cbb80012402d220535cf11d46f4cbaff4a12f4416f5b0982faed8fd4d78aaed4d7fe04d46fefc35acad3e0494ce51989432f6461410c099f91266685ab0003890bab0003882a2eace20b2d6e2cc33bb4fd7784a90d7dacc199015ffd9fdc54aa4fa9ac157eb71109ea5451f9bfda02c23dbc414eff73fafe12bff4abc7dceeb9cde4b3f85d576bd7d58ad4af6ec0fc0006baeb76087d773dadbc637af76f994cb6e580faaa3f01f5297b24f5a857d92347545f4d36aabcf8959e9a5e73efebee5394d7f24f3d8c554f7bd49fb07dca1ea9bf3dca1eb112a4fef64750af3d8cb9add4a31f3d7a31d05d93fd52b8254ba4bbd17653805ffddd11a9cdc032daa3bced4f9e8fc779b05f3408094669adf5caed4fa1421ff1fb2f506b859149bc8109f411a39328021849e094eb164cc2f4bb3bc718638c31c61823dc6a841042083f070787225dbf79f81fbdacffba53bdb12ee443fdea570fa17aa8f69050bb14e8035261d64038533924910c1f8c902156df4834834c0c498e2662d55ac9feeb3e9852516ff35a6fd3651a7ef9c397fed37d4bc33f41d79dd15c20b0fb4593c9f4276bc48ac906b1799535a27a9b37727ad403c554efa587f0e794aa13ec17adf9d3bbd0c95a3169a6292720414ef6fbc580166abcf5597f7ad57f5dcb01f54f7f42fd933d81f52a0bbb3eeb7d58fbec9b45f4ab728d6ff670fddb23327d165d7fb9460f91a7e907a60cd7e70dd7eb74328d9825b8fe30ce1f5cc89b401d8fa9b8d4d31bb11204f5aa3762c44a90d4a37ef5475478953502eb178eafb14780a4ac4fbf72a05489047da8aebf4c823eb6eb2fd3f00e7fdbaf6713aec2ae95112b4154bf7a23359f527deb6ffc076bddb03108e946100e6b0527865a9ff535bffaee6ffe83443716857e118114070043bdd1fde9743ad9a093941bdfd978f3a81b9683b800fedd9fde83246a1097ce0e492102658d58f9a6a01ef5288be4483cfaee4f3612f5cb5f22f10e77d60affcd9ffe8b445c6eecc94632fd3a3dea6dbc29360f3909541b1b64453e929815965f5d301f722acc2ef43995ef9dfbd91e843395ebeed3e6d8428b803195b39fac725dfe30236ede647912a9caa455ad35b6ebfe551609e947b3930abbfc7760d9c144edff9adba182daeff2efa1e6e1a17ef9535a2b0f85a95beac7439d847786cc37bdbf46330b7927fb2199853c84df14b908df21f3f9330bd935843353bc31b2f7b90990d3b0cb7f7af0b20793dc16eaa1ebdf32401ee7e2e32117e2a1eb3dc4d6c9401d176a9e18f387c1a87893ebcee43a15a6c2d20ccb3356966197bf0f17d44f96b92e852a95eb3f8ba08ebfa4224920a97cb288eb520927aebf14a2d14aa13b85fa25b44934ec7294ffc983fd4aada0ca242b91d8158216f5e32af5bd162761727d0a5d7ffe78bff9e4ba44ea972f51a33fbf4492481fed088043dd2edb8f01fcd2b64c904055a46520d8e55224d2f59f41fe53c85f22f9cb247fae42914e4026d62006f17edfdfc1ea7c86d1f60b899b4c0b3b1bedc71c9158280dc320872930887534834cac23528f88d44144cac1417524d2e22352d3aeedded644fd20d2ab007dc822e8630ac8c353c0573f175c8411861966ac105788f783481109eaf4bbe522a8e3416650850061d7579b674eab01f8eabfd1a52a445221224533be8814919a69193731ccd69cdedddddddddd3d5df677774b29a5fc96ddddd26567e646862a5b52b62562666666666696edfccccceeeefe4c00145415155d535abfaeb9bf88f173a0bc0bfaa837fe0bfad09e59833a91077631e4eae163f442929e1b63ec18bf214e6c41af32e87957ec862f658c0c42171a092565b9d0480889cb44bcc3a88e73ba070d30438546335cb9f01acd40e542a318d2dc0b8d646872e929fbeecd28888627d285883e6612239214daaaabeacccdfde074eca2a72e483d0313186c73b82bc480b191515b171a89d9f20131469486a8a90b8dc488400931395c21a686fbc160493a982075eac551df50e719656a290c8e4ca55cc82eea1403e33055d820af4851711c31cfa89c1013892828172abdd0280c0fda0a6a76a151182659669a55505a2bcdb1a295890c39e0e81284b3840d1a6e7069d25a4206934e0b293860748b1b580fac474f982b61886e540a5bb2e5061b5ae956af40ba22a9ab5898b0bc10dd2c3942865516646c96046143cd9822d61228422a2d92564b62d8217574a5e60c1d6a972b2a3068408969920263c3694c93aa0507ce0bca062b3d6c47412718b521043868b01e588f9e228edab04489c98aa4cd86166a287531a3a941b1a06282d12f9864b01e588f1e3039f00b3ee117050304bfe02d7559dc30c514512d36482cc8644b287111b2109a306a021156204504357c71222402972b463528a9818631c3010a665086d650b72f4d549b27e6125535a425551c174e216607d982aa5d3885181a4a59d49a24ca447534dc08aa490cd3509d654e6bd493164595e54409057565a5648514d396304b6008d3825644e5d298662a8bcc76a676459a13b5e6045c927a9ac2a1a9251f4e69aa74d2e4861945a5174e01468612143575e1145f929aa8f3c229be9c71e3733e54d385537c31b3a9e04b19a2319afcf89d8f1a7960e4c0f6bbbb3b0a85ca61577c54d7d58a32c5d78d5e8966d351b0469e22d489afa16a85577c255d1712792c719c9ba4a7a879dca4da864365bab0d8ce37be89aa70748e94ec87d071228ef34bbbd97074da8d0ddeb061ad6cfaf430a6b56c705839563a6a62e94b1e7d1ddc4fff6fdc02802efd8d3321460f66f4bdad614308bd4b3f65a49e7ff4e0cd3ccdf3f647012047832d6eb06901d85cd6fb1d3a2c079b338c75b0519dcd3d80aff1d8720060bdcf912793a78a016f7035b80c80cb3936479b19dda2e7828dd037c22e9ac954a2d936a5949bd147a85363a3fc0461bbbb3be7ff3b7a8310c2eeee86ad7d104208b3f7628976b4d4652677ef7c42b8b5735b9f5ccaae6314841092e0ee6e63771fb3f7eeeef7e9354c9d6a2b8d16b9b77aa35b21a9ab79749494a739b3528ab723d9de9ed1ad7b484608d54a900c12843e4c5a2c7d20e41fb66c97edda465db6cbdeb8acba6c97cd9d661592eaf82b229c0df2c0fac542d8e5cee92053e3b36c97ed29c803833d7fa9efb2552440efc64ddd0c66210fe5a00ee0f3716185358f102aa11d41ee90a2c6e7fa45884d99b8e409816484b0cb85f00e4c9d8408813e208e20b42fbaaed6be45efef8aefb7add01a215eff960362aca75fa9abcd8c524a4b54d3b46d8bdee97442a150758b5e8a48ce8daabeaa9a2d7a7eb5d56ab5626d2cae052d10b7b7e3fde2b746e8e8fd1d70e6c81688b775f54bbbd14c3737259addcc1b240cc49c15a1c19caf429c1899ca0d47f70d975d8c32decc2ddb705ee8680907068e50a76e5b780fbba0cf1a95af1de38a6d4333165d956a4c5b37003abb3ab56d10faa85ca4b4eb3e8a426d9073dbdf55fb412a1f720cd87187c8d309c56d29083595a9666375f1152bb3e936c8415881a8f19b48ceb3ba40d96d0fa14e971df8eeedecc2c1ad8d469c6d4711cb4bcc01001eb4f8a97c4218980aa9a0e1880a1a88ee47a9a0810a15338cb9fc39946b01313dbc413828a67d65d51dd23f3f0ad198e94b5e12187a62264b5f88c6345bca4c9e504facf49a9704061a2bbd504fccf49ac93d8deb13a3ba72aa55fcf5e69e56da4c251befe6d5c91b905db185e33a56ec422a738bb07ffc2fd7b7dc227cbbedb30be6c89183b5e3a6a276fc06e19b6e299b777a560300c0f77ff73e86d0618e0671830d06c0b541de797110c315016c3a1b057258d7bb72ebefd7da93b0bdbece97e5a9a7a7e9703ff3e3bcf2b6b3cb7f7abb072e18073b740860831c84d0d3c0079b4e433ba475e4a8745acd830d72f333af64f2b22f795403dd9dafc136f73e79fb35d816b906647703280d6477da21d2d2ec3b40bf5ec8b59c6b79f6385ccb2d106a61b71d402907ec86182d39d025a59017e2aa499b192df9863aa5dca547cd46a8c3482e7f347d49bae4eee9f19dfed20397e5e569511ec7505e8ca5bc085f329581d46d88f22d42cfc0e58fec9bb4d14d3c81d0c2aa29424b0ff1d025a9a400cd660ce3a9a1c5738196232d33609c9b66ce18a507e49437ee9c534e9fee7577ce295d06315823c62c8b47493050238d2dda18a39618a3162d6862ec8e5d5cca18b32c1ec59865f1080d13971c9757ee8192eb7663d790d6f5cec131b275374f81ddf8c868bb9cdce3a3953cbe1a2ade660ba18b39fa70a9f4dc00e8c5a596b275764196534a29a594523674b9116fcb791cd3509c1763a8533bc3e66231b67910568630c63c81286736ac1ad56a656758b51bf11faa6c843acb7e143e9e4145316f778c560551448e42681032fd6e28633b4fa12c2e356e6162468d38b7bbbb3715528d38628cedf2c6ec2e84d15565a8c8508d615a01519d51bd4025862a8c137763991863acd1164082b6325de71d11a280d047e9d2322eb77163f8bc0cc0176760471465642a3337e4a5d0470fbb38da1f5067c71510faf056bbfe71f8c2e6914ff9595c726c2a30746839b412f420a3f2a76e7c0514a0871a3f2323723f70857321152d6cb98cead1457cc2458d5f73a1d1972a3e7a85f0a2c287466074808179e1d60b8dbea471cb5417d4af92b9aa2eea07c928a951f400a372579a75a1d19711bc502f34faa2830c380a55234d49081938c99286ba8cb3c3c87272b22530f0b67ab2d515bb6050fb42a32f4a8cbe08e53cf11e3d3f745c7aa1d19720197c7997c2472f6c4c141414948395131a540e593ca22256895be2c3484606379689a6245a6c42c68d4f98af3016cef271114c0a1aba12cddc8874e3438ee338228efb71398e7b68c3e5de39232f5c2e97c50d97e3fea35cee5d596c71b98741b9dcf768c182cbbd8f94cb19ad808bcbfdc6fd707fb7d7b89f4dd370b422ad4853699aa63ddca283ab3dad5d64b8da775db0b8dabfab4b0baef6b0295733baa28cab69587ce06a58ace06a6fe27e340ebaa62f713fa652a9542a7181e2968e60b8252e2edcd253eea7f4542e08562c21a54c37b2e20639afc3f6d14fb413dda56fba6196037cd06542e88ea27ba75b0a2eb7fbe919b7b554b9ad858cdbef2a22e2f6c3a608bafd3d3e3cdc7e12a638bafd408c6cb8fd428c5470fb5370e1f6abc002154d04b920b4c50a2649ae511553dc7e96e205888b29193c4853d99d27fddbce92fad1b6d09fbd224d8208d6875d31484d338201f8e50e811edb0f888a07686acb8446f2e5b6fdd11fe916ba80666f7af2a747c4dd1b6e81e44ad0747b93c03bdf0fb63bad0abd54113c0bf02bbef4e8859cb428a490a86c49f06157084eeaf7a3c7ced7c3022948293b676a7c98068d5e787223d700f8f03b5aa0c349c12d0a9d0338e6d32f20b50815584021850e200a432914310a1a8a31c6c8d1470448a4020b28a4d001ef44224e22ddf82b70215a228aa431bcf80126e9f0830e49e4908505451a70a9053013619c5ffaf8d09365e4192d6a07350fb52d26c3669e6dcb01f44d7f42f69a3d328f5809323ffb23a5a75996d9a0cc223902ebec4db6c6ec9c3fe74f8b24fb2331287e127f61d79b7efe577d9a08faf19b8f01d39d32ed1114da6481f4cbf42af48b08faf33f8894592bf0b537fdf75c341b990411518af13fb8a19a1e3a418699ebc52176c5f831c258f65f243a01a6a1e5053004c5322f7e69411b8fe2a75660f2a2991f6954ff2f9af15a276453c33114a9085222cbf4500b2fb81f9f21a2c20518626428cbc4976678c7d380f0c80c323fb32d20d903c5326be40892cc4c8c7ef6251b93fa1533333118a336283313cb6c8b8562cc242639f145fd98cc3d02c2455c02bec865d815bf093f61573463990c37f9e29d323fd6221eea571c6a7593619e18258877e48ddf4a78074ec106991bbf28871b936eec243736c3a22a377e6cb1147601c15be2331227311936c35578d0a810e94200a4841c48ea21b782ff8f7c1fcee6d3d44993af797cdd8bb70a254ab69c20e84e2549eebcb3034d83a6d4048e30e3a9091c51fac8fea847d90ff56ea1fdbe046e7bce4276710f7439fbb95a259c4e36a784faa73fd9eff4d576c02e7f2020ad201c533dc754d6089258d72f7823ca1b421f05ef10d453d4c98377d328bb500980577bce6b69cffda4bc1c7ecdd7bc04c02bedb36bce69b238251b3f7b39e72481fea4937f7e37e79cf3f97d66d9534a33784497643f3dbae1740f236101d055a9091c41e6c2feffffa316e3e3c644f583d5efe197df6cbd1ef153ca5f742989b0cb4b106f94724474e1858f020198a8ac0b23177ff24f4e8670458dfd85d63ae10812eee3c3d8e6b54ee02348a01431ce5a293d3f8c65be71fc34fbe9956ccb8459faf9f0669e09a59f34cbfeaf4328b99face46d34358123906ef6262b01234a11008a6d59c7afade4cd5fb12bcbb1525dcfae109ea8dee26c109422d63a818d6c2088183f8c6d36e847089c00116b9d108dac00460e4c627104b72d7f785b6e57f0a6c0d487f5f7f47fbfaba71308ff2fdc69f117e10a4aed6c084fd4b62df639219cd0022930f5ef571d080a19463cc4e003166c9c89c535b82851638a175b8090818d2cc4840102242f9240012b010c7a78010d1896882206eb3040b12881ece797b2a7d648f64031936d4ddb7240f6f483644f7f4e1b847ec91a313db5adf9f461cc88112b414a6f32fd03a0c9f4268be488e94b16766b5a2031a018502c2e81418aa0d8f6daf74b80cb662540442d51afa75f8d83a652805d3c2098513f38664ec8cd77799d2119676f620543789941ca104120519d785923053820c1059410b0ae0c412db2051aaec060abb245b199125570cccc5a5809222994d00245041216106f44b972bfee884bc30b16405c015ce8858a2433674ab0483ac3d2a8633a0209f25afc5256ab7b7478263e920924b94190441b2dc5951a4e4f34a9d2372e34da22ca5d5d68b4050d3354941007b1803a21a38613b411031744c112e3200917c2b0c086a018b6c4f85d2c3fd0635c3efa01cb659bcbcccc38b2e2dce882ee3cc689db4607c0424c1997dfd937ef629b73dbe42619885a2ffbd76c7a944780fae18739d1835e8e747d7fcec3efefe073e6c7187f468f083cba449c032dda8293655996659bc6caa8901c3f45878e1c16498ecff15a8e1c14c0a142e90d2af3ccd3b802668a1043c8f04417b13290d842c90e2160e24c18b1d3434a05d2960753d0b14d938d524a29a594729b0ddd6ce446374a6d6c361b1b6a4385b6adab545249b70d9a6184155c76384207a32ec24841932a289001982bd288a1b64a85e8b6d1a774cba6bcc136586ac6d99683c5fa2ccbb22ccb368d95d5785178ed59bff9cd6b0f6fec47efcda79c6e75d565dadf78f0a63c0db07059acf7e19becb2debd968e9fb2e3b54ccb3216eb35df34d6fbf00e4f8745a2e375bca643870db292f9bb25d2976501568e6ddb726c597625fb6c35e594d5f435af69a9ba62f98ddbb86734bbb16165d90d0af5fd59c67296b39c65bfecb777fb657f937dea7ddac6437d7693ba49a95ee3ea0d2af3ccb3afb72b8f8fa1314aa440e38532607051841832bea0228b2ebc889db28a83e3b2d28deec686e5d97b663f2235ac4cd3344db371968ddb21356f7ae746a8c9b2f7e19a2ccbb2c751cafe467763c3ca6ccdfb7c95a700a09baa285682059a3c2f6594d2ec4ab653772ace674f214febb3cc3d8ae3412f27061ddb24e1fdd9f3c76e6f6f6fef2e38bda3e344fdb6d5fc86d07d9535fdf953da2f7fa503b97b8f9c72cae9fa7ebd0c03f510762a29dfe629a594d247726d9e76325e9bef3cf863a3dd787c391c1b4be953aac2a51ff472b9df72a0d424e863c76dfa2cd4cdaa2d155e9bdfdee639effea67b95d3adae3a4ab7ef3c78559e0658b836ff01751ebc379e06b26bf35a53fad0e6a1cd6bbe6d364148bca1258262395ecbe169910b92c30659a1f2a525d2f7b3f90d005dd9001b9c971603a64b6dbdf1a0769b5dbdfac1af7eceeb61570bdda434464680a2c62025d7159360525252cca87e45e4cd796a71d8d5ac6ca5fa78050bbb3a5e083b7a93d438d4cba109f89ca4e6895be0ab9f76f6a3f5c67ef5dad8afbb455baeb0ab190b52cd0c35a239c3ae33b7abbf53bf6f6e9e521b69236dfeeb6cec479f7b693ffadd476e04faaaf7e91baf3ee57e3ad5abfea7e6352ef55adcba9a4439286989fac52d9a4f52fd62d207936af8628d13840923a6210309314abe38020b1a2f62a8d67f94c7f5f10a0b4d71fc576ffcd775fffdcd7f2e9bff603d4eed4764f5cefdd8487a23dfe646da21abd7deb91156aff9acbccfd53c22704f37fd96cb84c37ef586fd3afa9dfd9efe8db5b1d4ae5ef6b03c78575ef6359e0280aeaa7ecaabac044bf69af711e9e998865d2cf0abbfc41363cd42c94b9da91c1493d8d5af1383231e9af4f7fc784a9354fecf6ff08d970cf66c8d29071fbd1fbd6c3f1d08dce9f0457d186e971629d118279d31c6186784979a90ddec21cda2d7347566e1520c4a5e8699cb6029be6023045f703063a60bb8858ad11156684983650c1698b44431a3922ea88eae3606f582470ff27e0f75a66cf0a4875d48748d98ab44b74977b982eb0275991d507445f8ce0f726c363d215007ca771da5cdcdcdcd4564123768d2dc222c668c56577df020db614cdd0f529080243d58625777a7dd038594914190ed914fdf91ec9221c017bbc2768b48a6c2dde3468bba63e4b97219e58a7adffb8c3146292716aa256caec65b0b88fc00dc9bab35643e7d40773e4f6f2156f76cba7774dbb654bab47421e7c35ee976fd9a8fe39aa6bda2d1a75904728e57bcfc6ddbaa9711a37bc32f9c3db59fffb47593eeeed265367b4e29a5b767ee524eb700bbe8959f1a3a1c10d4705d9a6deed94633a7966636e7b62592736168f00e2f60fd9af23b309f8703d7747d00ee8f3280ae8c30062c824541388f26cdba45e46d2e0ee083d488f88c3189ac6294dbcab4956a9c1bd75fbbd98f73254b890be14983882b127189207a4fe946b9f3a6efdd8fe2b08b152046bd918a728479fbc744693f223e63d4fe95474b6485468cf15691b408df9eb283c834820bdc5a51bfeda5bc45fcc6e8420e1fbc04c9bab2e84276adb0ba45e46d3111bbe217311050670cf9dbb6d528dde775ee147401c0f403dda0563fec726116770af78e55f00f62eae79b4713a84fbfbe9e1bbf56f6f14ad9f45597ef4faf933d95c57077a72bee6e2addbd95e8184465ddae0f758c40230d7ec2694aba64f93838add27e410e480f6c00ff5a3dec8a40e4f3dcacbd1d24710da6d45b6bd74003d74083abc1951a6870bd735c6749c8d3c19d1e8fdcceddc0014c8657458cd1efe70f682f3ec063f27db851578b1cf934659e1063d31a396205ce991b382b1f5156b05f91be4da4034567f33b90f9f4e916486667ed1de2163bb6fb97bad17a8ca99bba945d1befa452d779476a716bf5abee002ad46932dd3de79cf32b70ddbbf3b9ebe69c938978d7b72b2d11af52bf72abd4f8905d343eb54c69d741ca945d5c82e66143cd96ba39ed9d5b645e8f3f8e882c84fd5aa6d2d7a2ef5de8c4fd5aadecf9da1befd79af2e32dddafe5adfe9b1b4213377e846204eac4cf3c11a04efce9fd6057e52deeee1edd9d05abe829ed27ddd22534ca3bb4a268e6d1c85e44bbd11a2d11f2f4f42bbedb1610f907b8a71b848c31c68e63b45166724ab9ba6ebbcaae2613999d99995a4abb8eb9f24bcb30ee96cefc0dc59dc6e8823af17794787b59e414c099dbbe33a83d79e4470b9925333fd489118bef927b4efb8583d55e8deaf60d103ab3ba54dea0f39cb4e795ed35153d43cb5061083ec6e8456a3996b229b9851833d489cf84f3e0a17689cb680f779c9b9b282828088818fc9844a3bc132190476e815f377e0d166e75cb3f5eefbea04ea450074d00b6a89fbb6e5b22ab0b04051ba0d9408d0afb0565ca4da2ea8a6777749f93274f7e76459e527ab31af2b7ad6b5b3963cc7a964a51ce2ccb4a93cef9546699cce4fce2751ae591ffb6c58eeed3a57ff2464b398dce86b66c65bb92fe27a594963ef5ba3f52da7532524aa9dcb1621984ddfd4a0fc802e011d0955e26dcaacc7af6ec99c196525a8dfe45e1667fa7f775f0370767b55599b54af81c66b9d212d9ae0f337271e1379a6797db15bbfcfd6b3689442edccc7f84ef8f637eedc7990a10a37ebf51e9de3f6167a2fad1bbf5bbfde2537671dc28f36bb44e4ef22ee76799cff9f27db8446d97e84ffb65efb6b3eca52d5114567f33e8ceae55f6df9679366dab841556d6b5e4c6eb3d19895d70da15fc15f470fc42f81d0e8ffbe1b0ab7b98a0aaeeb7ba90a5f414f882f7a325b04104e4016f096c44812f782154dd5587035737c6b8b2ecea8f085cd55587d3d2e19143e1209451bfed7dbbee1b6cc57356fe20fe5f777b77a594b46bc3b7bec9227ea56d202134ca3b10c27a6a4bfeaea3f4998b8870e573634d95fa6dd7a357641699dec5497a5ebc5b15f5f3dbd486583f9f2ee41cd0b1f935b6604e683f98a9f4528b5b45bd0f9b28edba492d914904f6ad026fd9ffb96f91479492a594d2bdbd5e9616ca156c6e11d946fc2c7df2e3b745bb6217cbd59c3fffdb66c9db31cd529dfd3c29fd4957de66022a324fd9a538b7b8bbbb7777b7749a75dfc02472fecd25806f7f0a9e820a2cc4a0281495d48f4d9c886d3fd865087964768578bf9cab79d1552a651fbba23cd8919b02b9d488c37551544e02ad13626cfb18dbacd0163bbd90c7926c0f038d45f841e9392fc6980be2b19385c105546c7b8e9590fc703f40360be107a5f7611bb5d23fd1c4cd4a804f44e64a804e90d0d353faa21297bec425fab3b3a7efc3a5f9733abba67575c02e6e9b0375ea0f3926a6566810da5ca8634a2999e3eace6e13bdd29a4adfbcf0fb8bc6fc2d3f7a5bca92f20e3333ff0e36d2749ca8f1999999992d05621198c794cdd21351a24a64017e310a57eac62aea5856d429ae7e595163504f9930f2c8feb317f62b9b12caffa8e97eb5c610220fe6fbd51b4380979d8b1d37a8d44e870063da94d477901484667a00b7ba87c3b4d4de771d4e7d21cd83822f8fcfcefe5ff4525e430dbadc5168d4bbfd6250e961d36f6e04d447fb7d5b865fbe08898f13ed730fab59a55e9ab48770e36a3e06417bb294e338c9711cc77de6cdaf9ebf4fa3bc69a7a4de3d1ffe0ec72d072202da686d429aa783c5103a981cedb6cabdf43410db68a30d36ee57e4ba1dc23df7f2511ebc29baa1b6efc7ed01eb203e1f71e43cf9ef96fbda75b5babb7f31e8f45f774ba7ffea2d9d36cd74fa527b15f53edc3edc4e6b334fee07f5ed5576b5ddbcafbb2ea7a4ccb00ba6acf3cb1f85b21fbd2f3ee7cdcd7e54b35f35d9af2bd9ef5d10d2a72ffd67edf83f8b481310c0012f5e14afaed0600e0b3b5fd40f926140a3b1a8a4acf854412a95a11900000010009315002020100c874482c17834cd4339660f14800f6f8e427a54994b646114c32808828c41c618038001001063c04c154d1542a2d2d422b16043144db3485f36e78a12442dd5d9c8f02f39f29f1c02897cbedfe5d64f413bb7b1148d5baf93997139648d242b0671149fc165aa31ec0b921b73927c061b546671bcf81b8b52c38b915d5a6d24077b03189e6de2965caa5a64de59a543edfcf3a0fbc502d42d46e941d3b36be5393caf5b5a794640ce9e6823d4de1e7dda304566e520d03038aebbfd93c9eb7c9d57cdc521881026e800dba9596edf40d821fded2f3345c828d55b1d0295d5a31a8512013a533ce9152e7a3b6ed8915027d589ea13185565c04b344073b496bb02465d710d6326c753f9c525e542070775b9f53ddda10f8e710d5933d7e08731dbeba2537a77179a495d83d75bf2dfdc61015e101a92f15210d58b4bd75d5b28a5e0173763bbb35944c5ed0f70ed12af84568c66ddbfe3911331b5c8134ee8c0af49061063e3ef2547f23f5036d5223c8379b6bc5f6de2a673ca39b68cebf887cbec5e895d8791cd07567c46a4d15732b61ac0e2796321bdf1c79add770e57c9e65a717fd437b3cbb5ef8db9e39968c5cf09646cce677214efcdbfca36e7b28aed08def41697fb398879d67e2ba0c52ccd796c132bc330e3cb8eabf14200c6e3a72024b4ccf16caf080bd780aa84b54e5d7df803f1a85a75fba3727fd67ed1b0be6a5948ae0eaa6ce52f999df93426f76ad656c32c7a8a918e1536998aa994c8f7f5a4f916654a2c02b179f904ab1539617d8b51e4efa082bb0dbacf394c0a56c0f84e6104846788d744f32aedb351eae647c3959317cb5f1a9fb6afbc79e42790af1b28507c213afeda1fd7985073e60ac8e816dc52d78baeecf54311032959d1e4443698e951d580b2865a352d51d6a98dba1845196a6d8089fde2ab89f7d6edc9417b13b9edd384e1d61095f5d76695c2a29e6c39182e501102392f2bef011968bff8f18662e190e00a00947f692da85000ef2413deae56b916dee5f5ea196dabd1d65f57f8e303a390e9116d5ecd8fe4297a7e14cd6837c11f832bcd16a7392e3ab2307538d85d69f63ff505447180a95f9d336567a54192ccbcadad83f212ba20c6b2c1ba0574a951d9b48806ab2618d4871cd194ad51b4c3bb7bc3c7991bcafa9eafe1d15d8fd24fac5507e16fcab498c28f393ca2cdd56905b53ad07c0175a3e9e0121df77e1592e2ab6d2ce0a29aad09ae000d3f5cc2bdfeaa35fed7e9bbad746901446f62d98920e31736d33da6f96a2fc37a694cabecf0e5bdfad281ab5fc3c88a8a93decc3eeb87ea852e0d5f4293e4847f19e49cdada3b3d23bd8a9fc99bf3cd11811d421efbf1dffe96e751bd02952f14b8fbd8ec42ca2bf82537af838f5e8f00d583be7e4d7b5c760fd2b2a0805079537a65ff7d35d8a8e68511b85107912649fd7727757fdd50f33afcd305e3f1ab50561e6a6de926e858ae529dae024395a2abbe821607339ca929339f8b2ae451668ba54b8cbaee67a6a3d9c0b8bb9de385aa4d17506214393c20cf509b01f8ac0c0198c5756b5814ba6d9132b83c0e57767f4eee3a53f87db2bc48e7270677de8d3a83ebb778c3100def9b69059ddb05fe5cb1f0060961aec6117ca885f10ac975b45a19a450c1852634a5957053c401e0d1772d02812b6a235aea4e32f1b25b929042ca3252d129e0cfcaacfa8bf65a8bdb95bcce106d4e6b8aa36700d0e6a62103d01ac6a8924201d9e97d4c3af0e056a01b2b9bcf0140729d37f61c80b37a4d7eacc9e4e7ae092d22f4566bb48e5ea656b859b1ebefc73e4247cd90aa1236358c880e2d9ab8983521e54b0a5a4684653a26a081cb939db7d64350a5b93246758df5c1efb84c9217e423a017fb365d831276f5a4eb8211ec96c4ba8d20b4b3a5cc2e7f15a3a90f25f4d52d95a59bd23c90d3ece29995b15640b565b4567e8409f2bc3ba9c5c2836c5089636c599e1d583637308b173c5f404b9eae9af600d7406816eadc68d0ebb61311471755a76322ad110844fcf566440d242e777a289b78b09a6d85ea8dd7992f8bf1b7f42d94927882b8ea4a621dcda31ac48cc0778184f5f02d9b3355cbd22caa474623c19a24bca2f3805e923477a35dfe6a4a364787306180cd14f4e07f406cef456b33d116bf4041ceb212bba5ae7f5974590150c1b975f77a822f57d291b46ad1a79fce9645afe365845e103062196dba41a3edc7c71a40c90b49eb4428397ed1833b33f81e96d36c6e83c4cb37c3774944b2c103125757a5d6f2fb055cbdbdbb7ecf0b4694481644d44d0193ef9fc3ebd82604427cfb5092928a823d6a47695c9905263b2accbdb66e0eee57cb5ffeb4ade8e207fef4d0c5c5d6f903d2af2431d06ea4076a9567c8618b2bf55522907a02809e92c20624abd945bb6a750245af02b86298ce772ba29e94404f06fb237e5e6be7f70a03c128bfd56e28bd567b69d2702633610cf3254dc4d8e5319278e7b1bb3d32c5e658cd656cb63f5ef9ea26aead82983088c024293d5de29679e05578d981761f30a5ec9c96ac6920453454b6869206babcae8dfdafadd48d883e74ede57e640890ddbdcd454f45ca0b934fc7d84f9e2fec1efa9964406a678adfc3dee572064800bad0611e504be11d443319c49f63fd5023bf127883314d61cca391e1941f32b5328d9102d2c8860aa75d9b0d47d71ea0521c8d4b2929d10206fb01e367e42806acd3564fcc4c089b0cfd823b42dcd46d2afbf3e7971d7400ac9777242a0b6e1124de8a95be84ce6b29c09787c733588e57e6ada5a89c1bcd4f2e0b7a2a054b3371778f19446fc04afae742af492671b8b357eb426fb628a729799f60979a617fe401cf6671fd711a68253fd49a9d3ae0c32c5a7cd2721c2fa78279cd313d441802b213ab43d3ab45646831b5ee4edf0296d583c0c2803b90062a9135571c4e04240692fdd161484fec332a35f0a42a83321398a94b411aaae3c08f3480c394fd3b1e03a75686c05df1ad13e2741c5b9eefdc53f11b0e48097a5a2282390655f2fbb8a41b82a8f24d0f530595790447fa5334f413eb46b32e6438cd6f206c328512202caa37ed6613700dda64a9b22c6afece62cc230ed9a743b287e2e5ab10ae6d4a5481fbe63c6747808bb8042a42aba4c9515aa740f541178c363c59eb360fe89bbdd5113474fc461ecdd808f064bea89b5728c7bb6cdcd71cb59cb8e0007404adb807748b154a938bb60cc20170570f0d6ac6c990bc8982d1cd7072395e4cbe8156b4c9b9614847958a2f9752bc08ae33a186c18eb7224d60d1fe61588df45301e2ee36024ac174f705a6f92fb1c34bd3000cc05770f0bcec1b3173a1df5d97f357698e89cf8558c7e71dedf75e7707d8805f931361c4694ca6f36696dc16b12e9afba0c00becb1ecbb2a1878cdc614e4ec05832164b3f2c939a1e1f0d1f0f166873a4358d5c850111c3ca44d38d33fbff82420a6a1a93183a3f147daed21db06d9f018de03a1468626bf488b5a2401071f98d3cbccf0d349f798fe18a854abe0b2fed62ed66ae1da4109b0b3fc3c6f4ba17aeffafcb47cd7169742659e225f5bf0cfb3a2d8d9d83ffa604a530e1e56c2d5d3ddb6c318054d12f9b354d82895cf30a9fda7976d76d95da3328f266b39ab9d028d7b979bef243652e4fa84d639fc8bef40c533d83c8c68ba81c705468ef301c964c5ff5a42aa5d05061bf94c7802fcb5fd1ae9ab16cb168ac235f5593621a20a52d09196dd43c4637f86d361479272d1f30d5f1121ae573bb1f8ffbf1ee816ebab59d5963b8dd5d16a1a2915de3fc847d565785ddeac7c2ce0079b8dc40ee1caa949dbca9041c96afd41c8adccc07167b3db6c85950f7ccacea8192d058261f3d78e6df16c329e26e782a5f13f9f840971035856a433f2b81159f8f9b4ab4b698989cc7526a316f9c151fd441299f7fa85254a87549c3a02c12f7e9335695a14f1344ea026f396df2a310c4d17140ce8ae720de52b4ced173d2b75d7bf7a334a4f7357f11e72cfd970a8d33153648011855ad25569bcfff427b287e15c172c02f8d2eb86861e32099ac58f9bc6957828af0ebedc498751e5a401156b4b0a00d46860beff6f54342cbafbbd581dc82ba25b9d93927e3c6220b07b8173806d6c268d231b7473a00c24143e0cf86bf5682aec8e28ae38e6b3a003022f97c31e9871f4e2d6a8aa698700464c991caf78fdf5015035679c0a78f0fbe77981a610398bfc912ed8594045881705852bc38d674a28f9d5709f6632e86c5f1a403a593ac10d65f14b4fe17f58e9c364700653a5896a4e4dee90c2bc43fc3584eb05153910ba57636189f024f3542abd8cb2f73ac48bfd4aa89ec5786784754e49d3a10b47576e23fd4ee5864ebc13a25ce02200c05f09680e17b13f9190fd1e2e1440c3e74a17eb520f0be51f610137384f317ace976b1400906e0547b848df84fa927071ccf8eae68e234c195556eb75d80c0a6b066592733537af192cc513ae93c87faf9f3111ff58a561d94851b506ab355ad3afd726fcb3b1d898b6b433b931111122d78580e96845e4346a1a0dfd4d932496e1594d9ec178936f1720f9bf5950e4eaf3b89dad4e31000a6a079117dc0a31dc5ed974572de37f64037f763083899b1bf2a46b215601acb07c22b28cb577abdfb73b2ddd87bab10794c6174e07954104d354eb80213f928559b12ea435ecba49f1b21108c27a625121364cc9bd530b9993ce5a417264519ea68ffc25f2257ff9d3d9006a7cab2854c4d88d4046f5e25e53aea966fcce66399bc96f46944fa150985f6f6056e39a3dcd6d44ad604f6e7eadc663029e3142c1ed20b9216ff82226358c129a093724aff9a59ea709e0536794622413ee37c9bc79fd53843fd68e7989070a5e1bfc50f63a1ea68859d7aa18f1870671046d47269fdaaca59e9bd7ce1a4593959320a99023a4734d07d09438e2ee0a1378e310a80675251b3622c5a2abccfe5ffa8ea647f79669eca6a1a2193831be763d68bd8987b717298deb80afecc8eea25ce910ffbf3921b108f894dfafa802cec1372a25198b65e368792864d012eff43a264284239a87f860efe2825950a8e78dadc5362cc4adbe55ce56c0442dee46e3f70a4da22240d7744cfdb1398904c31c41437eeeb43c004f7d02a6f5e9c387223f0d180a8fb5981d1ab6221fbef41d11b1b75abb52002d4a9d49d20566d40ce54406061f2b953b34107b1015204383b670c7588054cd61e2fc3631a2bf1b4888f89fab14dad478cb60d90da10a5870b480ab682c8b1c3240c26d9ee5f5d8acaa556a9d62743e36fa22a384743e93b45cb5578e74c75e954749208666b4c740a0da18ed8945c0854a15b88368be5a7b9030b9bd197dfcd8d9c30156cae8663181bf2a417418c5a0c360c829d31b1daa67f0a1f5f5b8c2288685620a8af9148cc6224378bb3c244474446bcceb52b9939939588fedb4d9e740f6b070d19d81d8b44eb85d9d48123c60eb5549281c3cb8ade4b13c7212f9c6efd8c1294609df2ecab4e36363ceaf7ccb52d7040ee66c44f19addf58a0e915254a121f256dc8aa68bce7b8b775cd8077e8e94a5da7dc100bec82fcca2d4b18df47dc2c2a1148bc7814c028dbb2d047d7784cdc8cb6b438907a3df849024324b3e7404ae3a0aa7007a698bb4dd5e85cda920aab8c9a891d509d37f76a829965404a2a5c46651e340db91ba4b838f83feb9a6135c390212efd40d079b38fb3357c8269f2eb966b4825c2a61473a1c83d49090e0b7830e1d9a36fb99c63988d3e2ce0a04d8394683a4abda80c07d05ff27760f468858cb7eed17173995afe69c962971618d5401f515a48802299e44b829b05b2cb1e215e0bd240123271402e5df38fb92d702d1cf607369be53d2cf195376422efe53463babb23b1a0b03c49939098c0e8d05c7ad9aff7c033c9681bf561bc2351422316fa00b7cb64b44c5c10f01126f3803b1800f4954a4857a0eb6ff9618b5ee8453e6a020e26dde893e11cb5fa91fd899037243df9d322a7fdc10867b1f9a886f38ff1cea51bf4f495a018002b59c68a15708377fe2190c7d9059dc13c220b788a97ee92164ecc11c8919d6c21c168e28d1579973216efda63d8c1b10b260198cf2d28fb0626d645fe53dcbfc9ec84c59621377b2a18986eb25e85df441d0f6522bdf763c8609849ec5f36ea09c8aced71080f666bebcc5ab1f19a784c36f781c899fb8dde27d03bb0c74fca2aec688dd7f0212853c3e2e743d794402557e323c4e40996392c3854eb4c4e09b3bb7ed57ecda44e143cd9700ba5061586815b24a442de0a8c90b3ae9d82c46398e6b7cabb23319099af113533ff675579d2c260cb94f448d1a02777e1c256479c5bbd272f3631a1f4a13dc5ec02191a93da6f0e54a099171d8fd511c1e2e3932befebea820f555c8b22f83ac437ccc254098ecd1113d464f95e702871ff30209cdafe71f6eff0c64a0c9d75b2d7d617f620ddd5284812327e05abb0ad056cabd3402da351bc4fe5b0c2473d9613629625c69413470fe1be3b7f05ce63c6ed814d8a81efd0f52f5ee92a0640753c9cfefb81dce7cab4b5be8486f91f98a19c2d2e557521eaba8858d152822f060e3c1e0e43172fcbf0fcedf4054c50766892a46629826c8574a32ee522945d9381ccb1ce07057024e33c73dde0f23e8e33c798d360531532f91af40c988e95f66396f24d0ce9f354715ad725059e556d73404824dea2f8e5ba87740aed0562d8e72f333bfc8da1e65a23aecb073a5a333eb372b8ffba1132dec057127267f786e0a01f8b8c65c7f2ba801cb7236c07b506b9169c266d94419369038831f96b3d86bb9630a6308b3486dd819688b588242d705b61424836677a58639735bcfb49895bb186d5e9440422b19038ec2ccd962f5a5265bed0b7f64cbfffdcf1d5a1fb005d97080c3fc10ed43ac4859ff01bc561cad9761be120acd308f250d8010d3df107afb6668b31d8dfed032c2e74720297e952ff580930e785875d8b62d14c548ce48c9fb978db452613a80ba4ac3741a9b5db2e12ddaf34acc3636ba6545234c0d228aca7a976a6e0de9921d4aa78fb6e9902654df48f745d54151da106b48709b6f721bf0c0dd3c6b6d4e31120ca1454090831a9292f2be2f907206dee6c896e59c30f4191178041794ea0290361e33fbbd366a2e19aa066055270fc924a75564006dc4c311d0e479a9dc23a89c4dcbb6164363bd1fc710ba4646b0345ccda687b1c71ed8eaaca31d4aaff9e966dfae0d69e066b72a903aac35ec440542eff34e28c5d63e46fd2f1112d873d0a1e8fa1f339b9041104d346d389c858d296c2d7209a8a5b1d41b75a71c02a6f1c36658a1fb0054db83bbc9b04858b4060b07b5056d399e75c652dbdae6268a40f61bd3a4009930a4719b53762a13e6a8ea4090a2ff92d7d909e364f867efec1437f340cc29d608153b4529462f0eed2272eca8cdc539149dd536426a9be24a7614a5939051c3911d5c32b243db3b1ed6899f9e246169223b943d97fce741b7fc877eb87836ebfc9e859a90668435876b88873051997e3288a094341d6b859bdf7d73d6d14dbbc8714fcfef75d4697058bfa770aa6d0653680b6ba4488b88f002d3145260fd891eccfa4fb715d85c522a053e0fe75a534cd36540e92013272d8efe743f71d2a03125b1af8fc123d40c0a176f787f328a551e2a62d24f42431b0245e782513be4201c8c0aa5a924773dc84ba6900a2a04a9f532e343832dad8fe8212335c738904ce296232b790eb5057b1e2a716daa78060bf219fa2dd346edd808d162ca4e5626ffdf8d76d441a687c83d13e73e2e621e5eb0421245925de7dbd736cafad24041e555365572f53b2b086a5cc409836969d8800fd180806e48aad7ba8a0ed18990a14a659cf51da7a893464a7f48b1dda8001ff79baf49d79ae4a6a5ca535aa57df7a8cd310a1eccfaffe28cc0817ad05cc0e0d9c319eeb677cd3d9c9829348c4344875d47c6f7d992b736ddeaace7ce881c7aae5d21454125ad7a8b58d419fc98927a2c11047da59898172b699e3f3c95a8783cd1b2332adda770c8e3035dd268d854ac4e38342255714a04833666a8482df000797394bf89ab490a8c735b6c4c884bb40cb331fbc6247ad6d1ea490aa20b6c597d146518f2fc4842d690c0dbe8b6a12f691bebd358b8a5790cb44b0d6d376e6f2691a8483a3889c583d13e53a68d2a0ed2da85d53a3d02654bc5e9fb38a8adbebdf15175eca7b2566e3ce89e77f39dee41e9128747c73616466235ad0aff0ab26560d3b0e9488f4454bbb008488114f781e38838a71847008a12f939b6deb20da112c8cd91b2be41e6dd688ec8f0200ec0cb07dfba15ad8842971fa7d59308824b54e95eeffb72f40ac2df56b9a59f39d16fd3a2a01ff326f5428f6292a18f995462922d38e2e44a271137a3c507a5206dbc27d2b7f7a46a4ef3ca0330d4a6e732035633a5578b2ed64822f5d8f1c144ce7d0c246dd5e9ca2e6f5ea8f98daf203b79b1e10532277e072fa09f00cc46b98740f41e80852ca722e019f8709f7aee6d2814fb105a85cf37a41c7c3888647a804bf7a15047e121ca177a5db61588149a3283707b0c73e1619f750c987547d58de8926e098b2c58471d8e21936d98ac7563cc4f823d25567b7e9db217b25a8928f179506640c7901ce287d8bca64765b10e1af39509dc5dd0efb08837fae8345e80d4a66fc79cd4142b90446688ad219e9472e216c571c01ff29511781e33de5fc9ea98246483933fc897b5e45aec65e4d1c51d2a4af9482e5ab7dfa4477610a2f54935b96eea2850f7b930fb9dfae2eecaac1a73bc9567c7901883a66b998d55eacdb3f905b903475f7e91dfbffc7e548b87db0431c681159fc5018876f3773dcb0fd7abe827d1be14f50c0f1833d58b24ab214df060178a2cc127ddb0dd921716576b4b4cf9e711ecfc64275bb240b022b96a681b4d1415bf1b60aff0112f2e14770940c8ccd4c02787e7422e40f47a990605a2b10725398c8051a6d1a6b11ff276dc6ed8f6748b0afa4bf0ec79c6c4e29f17a946b72dfa66d8a4ea40e6d1ddfdfa20bca2d97e4ab0252962088ec9bf165a03a4a2994acca0db2daf4954f4243d08f14aa20995791cf02d5dd4384900ae0947bd894f76fbe5370edab898cf82951fe02d19402b872cee23b0da5dbf5b873b33c361cd95a5621a6bd99b20276831de4008b331a0f49c203cc0a77c7dd830bdf81d7dd84486c14b5ce7d398e75ded51a1121f253de31b3852e69495aac44429af72bed9ae2eaf75cfb78cfc37715afb98e9115a463c82960da324cbc87a92665a2dfc90985ba4346ac70a4b2663940e4428fd8b1273bd3fdf278e6cda7edd991c48122866880c4f6d0abae66da4c48ed982c73ff38629ab800b46cb9f834faf66c931fcc0f447d1ff3c4ce272743ce6ca99e4a433e9e5027a31f1115846bb9fae029a6a02bf46dc77259fcfbea1911ed70a19ef9398d897748543333cd24aaf8b236649b3b00e84d24ab7047696f733c8c4cc4d2590fbf1a532b1bb2104ee5330691007ded94ba223ae8d40fb59e26e3664b0e49d1c6ddaa3b3ced39aba2288b08a9298785f859757d00163553ba9b230115121c2f1063488cfc0b8dfad4d97a3a764a79bc2361186ab068c9e3d5b95b4d4dbbb90c07d0f2323652b51acdcfb0e0af32365a27d321079dc01779b3f0712aa9a5f9258e6f134c81553c05c031bc4bea889b64f07225138a581cb41a8662b40d4a513bd8415f6151b792d9680898d0f969b2341ecbee563989c27c19853f22df69cd1e238d00c167cceaf26ad85a6ee9cbe63c007146ee72d77407da5fd0d9e450e90b28c353885f6468a089b0ba72e08bd19ec2a3ed9c46ea5f939e86dbc18393e992759398d8bf16e58ce84af2287a896b516f20f1f8d9ac5af15571533105108693541d5a2bf067943a9869e29863d6cd825907bf48c2e1de05f0dcf4037df11935de2ba2d2bff6dce8c226a3c08cf6d0f23777c46b1daa2e96837eb0195109ec53c8de8f2f21b5f850efc1f171446a42e90080d2b52e012adb1e46b5a97886ae4fb72be182b88ff75e1a232705728b4fea67c70f8478f769d4c61691564ddfb777f7be83a313b3ca05b41e983b9cb29b869ad88ed99a738f9090949f2273fd58bbd33d71da00f0039de9039420b0240c227aceac2acbe5aee40ebc9b0208c7f21ff48f47544d6a974e00a2d4f86d1197776f82d70400460c97a8c1858d098924579970442b218b5494f440178d113010f05f6b2c817c879f82b10615010574d8e6000f375610d6bb97b24a5874fa28bb0cf0cf8c94e0c775a520cedd1b47f78eb81943d33f50fc180353e8ac003cb8738d6c927777def2ae2129f3274e69a6fab673813433d848c6dfa4ec95162cddca44f06d590daa55913b204afa312686d19a5b4f33c4f476a1ac7bb95d7ca909255ac408f096be355205409697c08d000b0e8a0fac24dd4708f29c82d0613519b2286d07d11f75340b173bc3dc94a2957de6036d91d30b3dabd899486e58a3ba11a5d2d76825756a4f4bbf55da0f573915e11dc2cccf67d5f13556e488131a12ec0f402788a6019a441841a5ba82cd70e572e0efbb7210cc31badd1e1eaa0955019a21c4c70f1f03a330fde20ec1c223dced058609847284e15ae17747578ee7c5d2b1e13b5363d8969deb2f31253a7328d3c141344f3886befa86a354a4094dda9436cad234a020ed42869aaab5dd6d1208ba89cb5e2950f8a1e5463c896e74a07bdae39a2440f32e53b0bf68b784d82003ae3b8bd16d16dd5174feb3a2d7450f7bfe9cc3d13da74884efc0a1a660af0549de64dbabfff932329cd5b31aa0580d22bba8d439f95228db38562e55e51c3d58dc14585111ef2fd63cc0b092690917f7116d875b8afbbce0813596efbdf0106528d635ba14390426f2451e34abc39f36adcda0f90a3719b0ff33392ea62ba66b42988946d52b7fe68db9455479d07386c14d73e7ced9e3849fd9dc506f64203a95e85c7ae7f5e04623575d9604ab73114df1501c2e2b146c7ab295cb247f75e754636ce9189c993ec2f1a997733a706ee299795d07d3339787ea794f9c09d67ac446e237d4866ff434717213e33e034ab24958ea7bc3791b8c486a8fabf31f17169a37640112a3dc0a95d1a90251085e9532d12b463a33d5ce87b1f2ed35cc53fbaeaaa92a38ac462d9e2f536995e661d6a2023b9850f55321bf3c0052cb4bc915505a77c27b254000b1913f48da40adba043766e59d3c06ea03712a4628058cb5b4ec3649e43bf04c302761f6e9e754a5de01002874f6262f094fddf5004807258a4272aa6081b1041a994b6ff645f30d539d61025053b70151655819c11ecbfe772ff59eefd7b9909c11ffc51f30c0713e97c79063546465e4c2b23d3d926bb8372a528d9d87e430c4331b8056d478cc915fad4c07a3d0d29ab9fcd04d144761cf359ef0d4c9fcef6140351945a2c4fca4ac8dae704b987da68caa3d4f55b789eaf428532446adf343c58c20fd2c193f7d30b077cd8e3da4f000f81bf5b65aab6baf8bf6666b8779594ad8204b1cade7e1c379062990eb842bdfecb09ac5369583f1f6c78395ca52d80223cbec5436a7e00f58204831ee931a415e510c797dfeaca3946536d57edf7c8d590214dfc1d3d4d02b468fd25c93e76a033298350e836d7fa88ff08957f9e50363f846cfe278fff88b42823393527ce021b3619e1cc4152649d75fd9969a0bbe42107f7ddb490df4e8bb3e9a8d67a71f7d860a4c93f72f4e40127c0a8ecf20703f7e0f3ef0e232d16b3b45e01f516e6e269c0f2b7962a27c7f60bbda7a607a11467282e1ff623163b011d68dc919d3962dd2e10b61db1038c18a7d5883b1254960b4b8bc378dc1cbb1289c63d16812bb58c2ab2f6c33a0db06b13aa83d422475f453be33ed62ec227deb9ea5df5bccf90e9e299e5fd1839c47094c2b13c173e1411d728ef9f29986c98ce3180af55cdc5aeb07bb7c17a7d2c103b65ecc32d6b7f8474fc3fa922581d3f6d4ac5c210b61868f5bec16bbbfece730f8aac2908c68a7600a9417ddaf984388c578b77b06fe38e1c71b6222e1e24088cf3de4c01eaef125c89fe0d882b98e1968136be1683bf64770af1984e10ea88b873725d8bc5d0b6885971fee0113e911f50de1627f42d05c6c60b0ea987cb96240fc94953f6673f8dda099b9bcc382dcc0470f07703db2820c8f9f5d6f158c0267c70c1982492a2495b3a07b758e68dd38ce3ac53631912ce19bbcff5e88446f0882cbf996b1761d5bfe788c954c90b0c8bf818895f8f671b76f97c97e08e0022b7283705108afc650616ecbf10a1bfb39e6bf661c6f10f216c0d1d2b3553c02aa2a83f9520d4e6eb583d0b3dc874679c032e9aff20280a5f62959ac5de49f61332860de4bbdccbb509b2de2268ba86a464bec1510824bf32343ea4a665301274d32be7fc1ded12956f248b042df1495a0da4ed5043dfdbe7558e38dfbe0b4543689dbb19d7e4d123ee6232a24e4299b16d85ab5163bae52e3c11b7cf328ce032ff1bc7266c220561313f84dd24ceeace21fcb586e752f5c4930de5f99337b8ea3ea93fdd9a01a9c5c10d0e868752eacd692c79e5fc3299e1a603425dec6c825a0fd7c6d7242fe2481a598b75c810a905a1c6d1f71b6fca99b6f79bbc9ae94821dd47451da0fe36f5b4d4e12aabfe63aaf6b9df46ad0a30b595b0dd9125662394938b8de49cc926290549b685502564a21d96f0d26f6fa3a50f464e617b59ffa28ada1aee7b8770161bdcf1bd2988b340d048e1978af9e60a03aba3926741bc2e4bec248f5740e836ae5fc4db126c18740ab36d1792fe5be394dd84015156b8393be8266a5837069e3d33a53f50144a5434d310c02e5e698aa468f342c9c52fc9b24ba41694d469f99d2025e16d4b724d6d0189cdf6b56a5ca8b35d9a1afb1b7b54c53ca863d107371609ac8f5695d9013a1d747f116197accdf80f7606116d8c2b5b266f8e23c9175a24c20eab81b395dd8fdb96de501473bf8c4415e3ba632f5a7f341d4a8ae8968befac3728a7dc675231931d3843fc2dfb525185196261b8ee985340f89c600e1582e5e397ea8423487d6eb5c2b50b1c1e81f65901e8166301790d81488e0e4a897b78ee79a3a9b81c045ad2ba253ca97d5ed36e35d46399ee9830f18c4c136fc4a925d29b251be9aa4bd409f7e7f76f0e72f6d5068fee2133acfab9809ea1bcf63acc7c21923e4bccae293afc6d309c61f6bef72bb09bb81f396d8395a012432b3471154916c886b976f25b78bb191b3c3d8ce342ca29d1259cb595ab922e137a3c6aa83b2756faaa649e2f6d555e43061cb11a453c5ec05a7326acaed5a398fdc0b2ffbbe12f625c1ea3f7e6a099e8ba9e99b7d6d91d0fbdff95d366c7bc83c8ae392b198341899d4612a18d8f74b60d25a6b339c0913626d9c36912bfd5f39608f08a0e04c379930782c03b11b72c070ac310cd66e5454ba54aaa2ed4abbee89cc037f0ec64e9cac40e61471ed3b357fd1d76d3d17a12fb69edc503b75cf93a7b91df61d1a3705b3e444d86ad4c234e22500705fc2c37bba13905839b95368654f4dcf9851b9b1d3846f6017f5bdd7c2752b9e001dca1df5c7589ef57abacd15ab53287b6c3f8ab85b3a839ecd0549f66ff6a7efeed5c07a09beac007f55f2dbbc48c7a9e24da8898211ea5aa96b8ba7e0fa219b8a3d85031d88f7b0cf8624d22bf63539d3e9e90fccce3a649bf2e6dd634f447c3cb14bc712a370e54bf58b027e951af8036f18c6764abcf32ef293a9c87f2c2eea1e05498a2418985c6c6e3425563f028ca7e544941a858acbad804a2175e1d0514adf281fbbe82a84d32b42381b0ecb2e4585307d15489d248aa18e66decc4aac88be9236236c6f18724c62c911eb5596736fafb2397cd4cb76d07ea17d0138da54439d1bb3b6604c1b0377b2a863d40c4c151563e7289e9f02365652f5b46e4f4525049c1feac345bb678142d72929762efd0a7ee2349b421cebab4f166c75069d66c91df185b683a26ec0b6e2722f0c1db0bbdf0b41484d9f86beca8f5242b21e9770aff50061799da1e3ed91acdb29271d4ec7e6e6a884e33ba39e3e8d9770456a77cbc79c9380987b6cff8ea94008bd435d4b19baeeb2268edd40690c081460e8f3e864dfb0aaad00fb3550c8da69d6ae2f32d45595c5e67a00f17650d80d6244f8c40076e177a01d352a0a1e19b31286b484cc83da78d26d0ced0ff4ceedb3a7e8b0321f4b0da3239a104aa1a07cfcec1011bd420b841643e64591fcfca5850258eee9413afcf4e4c381646f4a0cb4e106f88834584580421b5322f87f6367d1e5da9d67dc31168e96dae02eb4783be2df28e408f8036b643c3a91bfc8dc45ddbc08bed27ae69d940466dd49fd776878bc87985a2330f8fc85ffb9c3f440631dd4e74117d605ff0066ec5a711fbed07611facbc095b911d711d29d95d3d689f5717d7e5dee657a8ff8da21b76e5fd236f2e2699e6f7fc3dd879ae3aa63af74893dd74d264cb8f9ec264fbddbe16618f72a89d0ba6d1728e2a7770db7966b7313f2b6e3579f0cc990a76edaf88f486d6f61c0349a9496a09a9dbb7e02007f76870be13358e304462d49ed16f7be36c3581dc07ea805737d17b4f575a775e87dac70400808cd1da231c4e960ba38a8486337bb56d24c679d4d68848af94de505bb2a96e0c0562a9bbb4342bd0e40fc20ee7fa040b4263a3578a8b8d4e78cc14d157d5d43ef6a3040ffe91251e0ab52b81d66810fc47da370cb2ffbd2796924d54600514680746daefabd51a6a1fb2e6a856d4d89849f917437f1f7cd84a0b406b5495000d4c02f44938b1132755a461895d87f2f1d9c7d1d5bf7685f6d4237b049d5b0619adeb37076f8e0636dead3eb15b31b287c62b3a7c327b81b376aafc375c1443a1938d9ee1305dd2c33e34e606e7f348cd88af010483ead31c08dd09a124ffcb47d0dfe36e825c79a52115fa3ff595e1a06b90cf500b2b90169404e59652455cf9fc1b187dc05e172467b6f730dd3fa8f5bbc417adf4526f2bb8065dd24f126cdbf6901d65270ea50664a1ba0cf62f07969504ca75328d977bee75fb924118520c05c578b5d2e7a198bbfad10be8d66c5ec533ed0a70f628a0d0bac40e459a8ca42cef961f5c98408a814db1b99d456f39219bf7f2d524a52fd9891057f18f113ac0ce591c95143ce4e1260e4309e836480c43bd825fbb14509058bf1b20fe52e125cf068534b8ef3810f3ce95ebaedc45c26a09ec988838a21d79d9ece910dca8bc5332c8d05d216bc935db40c56e9f27f874a37527cd96690c31e7bb85da4cf1c92fd495b0d49b88d9fafdcae83b5d6096417a84ebf668e586a9c6daff49f745e9088618b908d24a0b9327e86568dab430cf5efb016963939b1c4662e8fbb9a2e960ee26da84f3d45d991a4ad30e73ebcd7884eb820bc19419040b40d6f20c010adb328d68be09d4fb7c04bfee708e1d18923c84c790c30610d3955498d8e8318cee5d99e13a2c70f1903050156dc9c1211f5af54eb2da0503abe1399dd1dbd9fb6b311fbd4003cfd1e231baba638f65420d60914b12c4ad8a6b62835b3e18dda0c42f5b7fef38583271a5f138e5f3864a1dd87673adb6b2e91ec4d480bbe92e487c8c2075ac440ce3d212ab6326fcf112cf913e00a6d2eb75bf0d337ec7f77ce39d2369a2c2ded7a719becca8a3b762e9ef3a29104acd4dc08dff3ab229e1e16f75b896e1cd4b9b5b82071131e562de590ff2ce59c473ba3e5768db4fb27738a878206763b4f3b975be772376385adde19920fd6e12443b12fc6e8da29d2c9224536e7431363d30d0fdc7bab540774fabfb2e9378ee3028c06378c71667dd82c7abd04e1360991fdcdb24da2000d1c5ff5680ea40d725758e62172d316172b0422c79f89b28e1f7fc1057ae716cbdf8a09058b19347271675b0a0e00181891e30ca566b2663d103a6f2228de28f29515fa5e0c6e246a1ad84774047ac574942459e9762ce1958d663c7967682fe4e7a25c11904a54cd694bb203887a1544acb20e582e45a10ef7157ad769142d3d4e709aef1001d9c37da7bb8ab3905a52251cc5500936f9393f80af2733b49db26bd30b0c2e87f82de44704ed370608f5a57ea14f66dafbe6cb18eeb484287106cc454b71227ec621999b22f9fe36b4b7dc8ecfe83e2208fbd637335e61981331a228675057aef3cee9f9f6ce9c3b6978487b4ac89e3a38d31561c217c0d75a043d78592823b1f02d52cd632b4c8cb190da9bb7adc5a8e7cb1d70dc14dd2834b118fcd909403a62f04b53591d1b8e1b80c409c195fbb53cd9c4c74d4321e131ee8f20531c46c6b0ebb9ea2faca0862caf0ba09bf0470457424ce9380a3c1ee9777f7d5f88a6590b84a0c87fcd247da91ac3f8103378d91722d7c6033ecf8916860e00fc0767ed9ae43a12f1af0c506863158f41b1ee3b242500d1c6b19e527c44c6e8da3a63864c8391f75704a88c08cdb064c6091865b9743c777e9a6629687ca0d0a50776ef0db8266d63d9e148ad8e001719dcc71cf99425eea2aec564d94358582799be9e52dd5180cfa0ebdcfe8f2add6cb8f2dcbf7cb78d615d63a72f485529dca6fc9f34f66b6543b5998883502de29d9b1a4895d19563546d9b0508d2a1c8394582f6b5563900556d554c5714989c5ac558d57166cd6a8caf1a58a65c6aa8c5f166c6babeab8f406b02693328d3c4f7d56d02e4876e2984cb4a6997360590e09d2eca479251d8f74b12cd32ac6260b166b157b96cdb146dbcde0c160c4e32570f0bf920d0cceb9120b5cd69ba209156e1f07c7b18acd5dd231758de5cdaa1ea3d6c5f216d62a8d41f6c5f2ec835d867e76793b96f08e97868c107caf0cd8532a76890b4bb026994c0f1e389947a64c9e900f04e63cf0e0e42c3d78206f6ecbbadabee40929195f8777a0c803b4c23b001617572f662bb1e24e43ac8537875f255d62e3acec8d70be54aef764631fb68f2124b6c1f251c0c27863f845d2053607c6a8a265f2c4ecdce56025898397de5f713fe1c04b7ba4441b4b3786be85130efcd5c3b731bc5c8fecccae5edce8d353cc7d118234ea6f8bd40e13bd89ed9bdb9585a37536dd747ce256ede5f70898717b0bb31eda174cd522a4fb9e2e951568af7091ae6430f8d3c98646decf4c78e0b4d5c473890a7fec42c1f46fc38e059ba13bc45d4f26b7cbf30f5d4b1204510f7eb250edf1ae3b99728f6755f7d9590dc466be7725a60d92e4d107088f963189d947fc52ae4b4c76812d32e04e50f6122660610d4e61bf6d3c9c75a00a1ef84f0afdb438aa765c9d8bd882abe5b18450cd9cbbbc83f01386cc31aab17f934f9670e313d68af21ad0be04817e09eff01801f3e32c68b14e4cea7bf4a2eb57690a390a5c34a7a98eefcc8eeb05944f51703ae5bfe14aeb89a03278970164017d1eef56394257b482cde96747df4ae8d295104677843a268b84b15b33444e5d197783bfd91a30a283abd616680f8880eccd4004d10a800afc06445850e82303288cc432566330a718c6a6ad1687ea90aab6dbd0b268c8555ef689231c2905830d4d48b93416bdbc6ac6ca741cf4962f6e113faa41010c919c84628b0b8e9caaad4e1247281ee03f9d6cc1da32472614c750c38a783b82ec0901c159d3e28da4a74bee9303891f713ba30678fc59f52622f2dddb9263487dacfa8849f1a52ce17be7c467d90c822f3c168735f5966e0c1787e09c1fd83acea0b2c2a76809f6188d67fd4f2db8912624af78dda5fd52c5582509b01d0bcdb58c8a079d7e0729be2cfe389987d52e367f31d212948306c002528ea6bbacb655adaf25b08d5a1644d3560a0a12820f9f0908e147d32081df319bda3edf4cbfa553fb19d2d5beb05818111e094c757754bde2c7eb0e1633271f1c832a044e7bc8b39298301b8e083baa10e2b93d25a0b845e323e8d33bb31d28526cd9d308776a260180d88df0786c3aa80f2144ab53a8dc1df9341b6bf880cfc0815b564e6e47470fc8e2ded4ad76efdb9b6866df37ccf2263e680e4b87d9b3fd4222aab9f31d4c216439d4edc45fb02c20078ab14f995a0636dc75c0834aaf06ba15ceb1077b4e7a37780e062850192020762935853f0eb0b4c2ce927781d86a0628e6f188d113f7fe7b7a982a820dd81841bcef282c15db0e028cec9772b32054f2944fbf65cb3824424cdf8f5a59dbc695d6b7767874acd7e628767a368cfd72f7152c47b6a570d49e88d4c9d10edf4596edab2dbc54b7ed954ab683edc79fcc34beafbfed808118d57c3e347c59290b174cf8d456a80709831bc8bae20258740249684e21eaee810ed8370666714107c28394f489ee891aaea54d170c6a64826781b1c1188d71e1671d7cdfc1331ea04aea58319e4569fa37b3d48bf358aadaa718919b155b7bfb80186c152c02b89afe4f503715c27b2ef0d07ae1f87f1d23d53e02922e410e5b2391fa7df75affdac7e3c5c00a574e17a10bdb42bf077e9425d233fb322c13b2d9928c08b02f1beb513a26d8ac75ef0dde3e6e9c35ae88dd13fd1ed034c501ea6810fae1188045f84912c60396f2933c5266215eb708d2b2b449d8a77c509b29d26c008274b2462b47d592552c05bf82aa41081211d8d32f5d4043460f71c2c0b68e884b9b19c40591111a4dff09a4ebc3b60dd5c7c1e1f5b1866dd0d4032dc0dfbfb15eb0527f11b1b1ba1957743b8943f92c457d421703fe0d92ca36f7c37dad01a3c3bc6a8df14f12c5ce77e1aad707114458e0c175184ae7868b4a8d8a41cac283e5cf21f310655e0fa099e0d9f27537ca0ea1167096103c3f030c0d8953ab02d5799f19344915f617e3355186d0ad48a42c51020dca6a053f8a4ebd11d7ce04ecf73f78e515ef5a644dd23b969c081b45163e099c3018468180dc81b2415cf7d4912f34bfe07f577596819d6b9d8315f1f50f9fef4c2cc988bc838dc40d22d587865808949630cf6c539157d4106aa913905088168b291cabc006b6e3a4733532fa905d6ca6718c121b10c5b0c8e854cfc53619b1a9c236816328c6e013ce6a41c0d21872fc7f0473d01019a0b740cbefb4a2cf447ea81e6e7443b2910130f75627a3070e06ff67d4a014b29e8b92023e39f27e77cc25e0bdb7485ad14cdb8664b7d979065436f00530e1b1d4371f73ae1d3af4811c104144bf4e0695e42252da52f5ea944b1a01370126be7c9e8c6a28adbf59c779dffd30f56a5d41e1aca433d5e9659b82de7504078061013ac22cb7761962b81c35cd7177b7333b9ee027e38297bbf1dd344231bd001eac65801e10f38a886d9efc988c4ac7abce389ae326375c033af050000181ed65794285787522765794b41954e756b0f474f7a48b32312588087d30c8327b9af73cda1b497033ea469850dd074053830edad6410a098a97a0d7179fe24a42829a29b928a84479504beb0fe1a6a24500f7aa7ab6dcd63c11f1b44a71711122d664dfe6d5cf850e26c82e5a96516d1411df40eccecde698750185a24e453c452bc5d32e27e71b1e1afec0353ae8d9e8617bf0fe057d869e72a01b3b11bace05c1210b4425139edacca20c3a3a2ef464ee7f0defe9b7ec0a2a6e70bbf10e85bce869da86290d5d3dd3e75dddfee2d839980160011891796fa3788b1494c8c08760b0a7db9d47c91b4ef8ed24a69d3827f84d9ccaaec7d7dd01c187bac729cdd0a4733591407a6437f63f051855de74e2f75ad690589ce72cdd1dd630c5577a2cc5e96287935b83681dedb0af076bf22491d800142878ab13d2cc6fde8b2c4ec56f29b7be52939364156c7035b5bd20d2816bfccb26d9fa2b2f009f1068e3c00af6608de7c9da272e5f00f1a4e9acee686350b9ba2f5fb4161f6fe9f21665667b83e6e976abee478989715e1a9f3addaafc57acb79b6e44a8587969d94721eab139f7dd817d5671ed7161aadaf768198b016fcd2ced90b616539fa4c3654ed9228f6669d219168c806c1c9268bc0ddece0420d3f89aebb57e15151ea99a064ff70c3f8f5927eda2f687b8add30b3bf5dc24923e18aceee8feb10456724db8489032b54ec92f0d88509d23195d91fe7b1b51970e74c65214874e00493d7700a781b4af9bdc5a38352cc6db57fa1bf92b5d0d566877133b77495248c44681f1f1c9617bf1e834726562b185236d4f0c8e047f4fa8ded30413ce44596f99bc4d697ac2ca8a3492edfbd3b063c40a5b911bf489f7dc28ebd884cb256cf3c0374abca2e32260df52c3f26a259ec6546b3c7e261cbc18564f5a05a2e0e87e9686fe634b318750b2e81315b34cb67b22d0d28d99e70424a08bc2dc76d2a75d1ec61e270661df292ccb2fdbfb095a6615e05257cf5b51264ebaed271cf78af43bbe1e43373878e5780f06138bbf5442cc7ae99d38f48961b90a0bf3f856fdfc0a11f1418282a5dbc1ed3bdd244297897d8c8841f70efeab97b91a718a1a8c652510eee0748407fea03f847d4df23c292535f5cc1d1d24cb46d8a694153efaeb52cb9eeabc20db4112d40906a3c85b3156f1f623439534a7cde4c8d980962432dc0fcc29e48de21c68b245422a1efa89017a47e239665dc2d727cee737ead46dc39b2bab87f0644f65ad940f262d4ca471971c490ead2f164683f9f63d90af0340049a6532e0ce9e85b47e4a30f871042214b5c234518dd3dd30d4462de7898ebb35543183484418978fd82b5af78971fb1f9f0b18a85a65638f98a54124bac720274cd32c6bee5d780b308e5fb94cab7912761c98e4b801ff920746ee6523d4463ee5bf6365788fead15a50bd51f7a08bb54e841e93bff7172d4ce914717d40fcea301f34710216b095684febff2e515caa8239ad1df0a2e7046d097ab739125e84f682396cc8926d3cb32e4a0c117b1337b0a64c19393aedb365f50a07f88a7605ee02d9a356432ca511eddadd4dd3c115aaf7acc41845bc0e45628d4ac0505c7dabf9261cdc54af1fa6c7818ccffd25da3a793d6b5daf6a84b850cfa8135999cf5ed74f2abd072b8bbf0783b1b54f8de8769f229059f6a45ade2d30a3d7821a3dd42169ee6d84f3dae6307d48331115ed24bba9505786a34cb285852b71a66c4bfe4a306e10a2a8f8241941a1e402cf1c41a1d8b9402dfb9a035026ff6d033ec440c23b10ef317987e753bad584663bc40bc82709af0a55ae02d328f54eaa9d66bb4017d970266373551f4a889f8f7215bd7d1dc54e55ede3bc30a7819e8679e29debfb371ce4cc21c37ceff70f597288cd0c734cb9e578231c7fb6b32fad99e15a8405a79a4111890f4438af9b74b6d3233c048ea43a7a062e23150e0ec4e2ccfd77240eea46670c9ee83003de61058d6fe4e09fc936e1e81da0095ee61cc1a3177f42602d860d7c4a757287810bc413afc436991402fc70aa63bec6acdc4fff9c55536d2612041625bf77557c9054bf2e4d734df6f80ac278cc5672c87ba50b2bbb32bc7de1872198a20732809d3efcca894856735e7b85102ad5e2efe3af39e2724bdc92c9dffe5b83f5f26389765e7f27a09bfaaca92cd0656f72f10130d912eb8e8adee4ed79c301b86c4a60d5f2e4a8a2a370d3c063ca76d7b8c2d78328e474dd8aef842c38babe1adf2e3f6ba86b26f95e098b447cedcb0da63f8634442b22849ac953bd06d78e12d1bbe513a183cd5c7ebb7ae725a39b2b77e3dc04b3f3cd59cf61d496a2ce532b7c004fc4eea54f1009aab95ba1e8396463a5f8a6bce26771be63a3fee32432619ca964e904fa5250ee8bb6400f3cd12dcdd970373a94a8577640c529266baa0e8784e2a930c2b97538065d8d2f14e536d88c58b0ebbb229d22acfb150b16126d3b071040f8540a8c4a7c99b890402903f84ee5e66e20f662f3806a60a9ebebca7d394b791d428f1175c03604ffdca19728f030cd66946474ab830024b9295b80d50881de3298127e05243ccf7895518e03f034ef92379ac6ac2dd1f7d53596b12d486bac3c1d3a693d6e6d2b6720e01ef90a4ce86e01ba3e5161957e9a2e15e9d8880b83c431db206ebac036f4528b9a9df28daa0c52cf463a02bec2a8a75d0214822c2bd9e2ab2dc8effe023fbc011e77ca5c2911f7023c729e04b5bdc511ddc32a5cddc738e40752c3a3cd8f6d592311ffbd74634ebe6b2c1fba9aa7b478beb3d0700133f3efbe7228a880e7c281c06cb050dfbe1999b1ffc03d309a06dec85d2523ca37ee9191b3dd748b39b7fa934ad3d69e81f6d69d3e5cf374eaf20ec608020985fc7cedd295716e21ee3cdd924cd8c1f7ebe4b393cb7b3a1b6911ec96a58140117d6b566b7258f75cfd166e98d844ed010afcb5f70b4467398be5425fdd46a987049e563cc1b48215db5848ad305f8b345e13aef69dc47eb24cd8ca209e2f6f85af40a14643501d72376d13514e6f872443b6247148c476c9e470b960302187db20a0a335ae6a7ff3da5c7bea32b5f3ad79ea42b9058c310770de35c533dd45a76ebcbb77d61dd547a8d690e8a5deca9d1e9b2588e5aa7226887dfd2088bc57a16619b40cf3e6dc069b7abc538f059912bec04fc24f4712505d5fab573439afd901fffde0c41ee5f2f93a3dddc1ab60b54aca68e24d201f1edab0811a0eed87b85752c6455fc581f8e4c5af2edbf7463d2cc4a7c3eb7e240486a1cb9fb2a91259edb919c5fa9fc88ef2d940223cf7815304eaf10f45651429926a29b2467691b9136194181321955c36a298d3e9e358c4bea6a7a83d4b949d654e11052895422c44ee0ab983c1dd07aa224bcdc067cd562dd4ef0391c7e03668a108c4e868eddfd01ceae7aa11ad376e277fc10f7e83741706e1faed2865c847df97cb006b6993c077a9d5430b87a491e08bd2f60781110f81cd64b835e36f418b32a59123e32c9feac62697c9002bf3fdacf7b2f55f1a6277c40277604933fa542c0cbec6e401c21ad453875805d46c9c5b14511a3d3e5d74fdcce8c7fc0c7c1981f3737bbd68475071050f0aaab98402bf35cea488e5d56c35b8a64758c897272342c01369d574cf497b66814a974b4b282db8e93380fc8ae0cde0a672355b72587366b455641aef38fb3b7eaa8ba70885c1ef2811f447d89957a3c68001a5eb1d588f2ce7d362a888ff59b8770bd71bbbe94741c99a4d260d0d5e5ba787f0ce86387ab30c0aa3d908efe58bfde6c254e4c0513b47946b342a3a24e4429e301650d33cc6ee16d4d50ce78546e05b027531dd5ccaddec0872e4577cc1ccddb6358c95450d8c9428d7a183b86ffaf762c9fc8e0354ff009828db59ede779a8e623302c5b99c8bbf15aa0cd79a33969028fa63c181000b1b8e4dc066f8850bcb3d79546a9fa3fdcfe51789f225c12d2c14d6290a16006d276450a4dbd2bfe96782050e8d6d06949e611d7314463c3d5c17fcc9b666abbdb98544f099d52e7f08110085c1a463d6bf48da1aaede560ccfd11e29d5b91ce5a3cd4dd1edfa275e4a60dd92abe702d7129c74baf8bce67c448bd236f0b73b3ce67e84a805ec80d9dc2331d6ab50f7c0475996958f28d495db4ceb7c52959a51c1cc1db130406cb8ffb8e05445fd20401011aafe488683a1f7def4452020e689b40b456cee7ec525b7ad044febddde5f5635cc68f002ca2b0486ebae944fe024495e6dea80bb876b187200de0d3af8b911cc67159663d9b81482efc8db29aece7b4ad7b34e13eaea695731aedf9cc99bf7953f3dfd8ce4a7e5533c0d55510b2d0b20343f70c46080f7347f60321689ba7a385c7769930c3326d23ee7017d8702fecdaabf261ef5b2be107bf29898bd650ed16aa5b685b5fc3159a85268b47bb7eb538b46bc469b743f1d886173b544fdaac1f47e933151d6d82b7a1d573681a7a085460361ccf6a05215a86a5a109ee20e98156dc861a02a490864e7c97ca46d3e9cf799ef753d847e94ecfac72d982bda4a612defadad5009928681ebbc0781dd555c421d6f56f5acfdd0aa244b90867cc73ad92231e4ad56e5d1878b4b1df7ab3431506faeb349da5af7b4e74d5f6477c8ab1863495a557d07109f3152bde15270dbc2b44ab05beba3f87c07b28002c055470d87cce73f5a3876a312faeb129980eeff957cc288c106dee190113fce18ac507db26dca065a902f52cca34d01540a9448d8ee9fe797adcbfcdc26a0d581ef24888ca5fe466b5338956febacc87fc3977172b1ecf9b2dba4ef8560db4f50e895d0ff4a515358d20d1997d5046e55b086621836d7cdb19414e2bfd42d20772b7ff655698b04ba43e3a32e9995420f9c71a9b2d2b38d600edecb87ee725666708f6ebc344a5f1c6facf3dd725504a269ae72e9c50bf93f52aee6a81028ea5bd1e6104fa3f1dee1d71f92b336e3d26d585a82ac12393d4a6caa3b0ab51b5ff8b9183c99c6f2e042454ce912e789b53db15432992ee6b725a8d4c16202e2638d93f494028c6c3c07881a66ff397739ea47ce638f2efbbd95ecae8841259b27b325a5265c639e9eb23bd83f91ccd6a8121d604feae2b1a29fc19eef7048133539155e45eab41d7d788a04754639ee944770c6c1d411ae1be91047097d82002733f60ac0b87e5a3d6625eecc3ade88c77c43f003ab8c4a65752215cf433b4871a10214d1cdf92671248ce1f85e5223342dbb28d2a98b7f0ecd4b32fcdfecdd967e65aa0cfaecfd010c5eef3fb269675dc2eead6e0f0f3ca699867ab5d2b1d9f3160c72dd4e67ebcc430106f9ead5a90433e66633425e98d7171a8836688c1a935496db1090490e7b159428a78ba3b9899fefbfaa1dab5ef580b01afdeeba2540aefe9606e9357fa4d54af57fd928f9c44837b784a6f2c334c3457f850028477b551b8ca3f8fa7239ffafc88721f85da682600fe87b0441e32f7aebaec4990c2803e175c15158cbb043d403d89cae456158186eb118e76aeab6f9a51a76c44c867ddd5c2e122f40a5f80ccf79e0348b12477fbfdacfeeb22ed8ae562619665b84f3ee9edc7b33622bc49cb3eb0905d99963aa2afc253348b5b646a980aac9dff26a696fbd30a981e81c64d01f86ced1ad146de4cd1d14c00032efcdc7e99476244d8b1396ca5f20f93fe07e8e98bd6e251817b01b636fbb31e75fde3a19f4e0b895c6d0ce0ebd50a7cd3579a2b2789463b69371ec9494a73fc33f5ae0bdc413c4d8e38df79afb6ae836440694e585926c7a5e8583221b86efda37b5662e247be5802ecb41bb653316a9bc563b6e3c8937c03467be3f2a50b83fcc64ecbcfc9da51091936f99633748a39410f840f89aa6ad8ede964f1f9c02298b03c65ffa25050ab61a3817941f5142f5617bb6a293622c162cd2bbd7ab7a3e70c1ca3f214d517a100232193d46447f8150b47b0d34c5189ac863a105ef1b27bc4fff671377621d576d2cd8e31cb2f94e42cf766b4506611dc20cf85dae681ff7d69ec56adc4ab537e7515c60bd6c8267862cbabe5b91069994b33dd227be3ca25c25a0ff842deff1469e7907b297f1f1564ced7a0fac4f1a8eac88dc47526f7984bd52da205618a867450861a3cf5d5fdb60d85a9bd26cff56bcaf6bce3cfdab23d014654cbf3aa65c3fd3059dec858f83c333d3d44a10549429a8fa09c6a871a55d433668ee9f949d9ea4a703d43cec34d6c7329c8173131cb0523548878616243cbb6ca078ff7dc4668778d772bfc7453ad5ff399755e6e20c79abc3ae3fb9fe8b80f2956f2dee7bc87814531de32dbb0f6773d26799e416d121445f9e68b3f1afd003879ca52a57079c498710bd3e7c4629e7c99224630b12b471864ec6201c778e1c4471ce4b886c46e559a702249b35ace4010a50ebf22213f89a909c332a912e7141e76cda7b238608584cee206fdf5a4de7cd28be20a7ba87655b4b2a5c299dc3c9f23035768b3469cb9f1ca902cc8da6f8f036ec5f70c9f52cae36c3c110e38398b360b4ac23491657122e86ee9b02905b498e75bdb772776389817d3acf329b635303f0d5f7abb1f1f87badc78cc7ff0a5b7e24dcfa141b97e3739049b58f64adaf34d9e650939930371181d601657f38cbec6afe93a5b115c986f451bbdee844d8aa5d44e090a3dd003156291d54092c899ac181252b7ba71da96033cf5a157f86446e63223fed02712225466b73666750fffa38c65ce1278b7104b24d759262a9e3b53ba0438e30412a525419eaa6839305161314237b7c1d7a5c5eb8683e4d5591adc3128bb7674e485ce490420bb61489eb9166b123e9bbdf7bf077b23546107483bb6bedc91d0ba40d139d68444c0d7ba110feb275328d89351db33813471df048d29ee4bdb731740f1af7504c94827620728e4462521a6e72f9f2fdeaca4c2e9709e9f9cbb50bf4d2e3279d2f2395e6dbe9283f83997aa3802ecd0f3db502c44e310dfdc6603655140279fbfeb0b20bb8a2fea6fcb5a8509ab530439f83600e0d0b38b92e564a716707fdf5d275bcc0c7a61f44cdc9680055d3e33922c50e680472fcaa6e472ded0f2c6f542a8700f9d00717eb25ebc725b1c456cc2e84afdc3db28bcc6d2fd258bb47e74473a1bf68defdd073226538e4db0b6da2161fa1eefd89c808da255141083f3c3de0cd8480b2976eef8b6b3a1e6ef3911bc5638a991cac7b5e250e9f8c8ad3bba901cbda778f2e25fad0072605f4e7ab39353ce99dfecc8bc56e8dae7815d54eab4bd707584ea82508bb84b19c22cf55758b522c3949a68e7fedaa5527112cb234a25f44314a0e777ae48b04927748186b942e0c8235eab201816a2f59e98d930eacf98eedf79ada6a5d694219f0610ef24037db131843f06f0fda0466c4c8055ef9cd8a2c7fcb775807091ea848deeefd8a53cc83fe7ff152a60352b1d3b50477ab2e705fe18264994572514ae0f11d7f6174493f597e96f9440ed15dddb21186d26993cf14f2765de462b1b7b8a1dd0df9bc6a04970e5968065125aa62f8a17348243903ee3369a9effc1089bb98a95def79a43d76f9aee6cf39fc305b061f96b8c9747151a233cb8e3df09bad7ccba73a4c789436646ca0b3357bb6274cece2bee247ced9cf5a384fa7d3442b5781af914d4dd2fecb097d6639a6f74a62e88e927637f70f17d607de79768eb99a732e3fcaaf561698723903be66c866b58b6e912f8fdab816cc1ba5e7336ea20aecf15f55f60107eca395f47b8366228e78641ac3be7e76423faa3b19d1e5c58ae40ed0ef0f2ea889e245c68a3765e0854ecfd2813c6b17ca806417079c60fb2c31e6aa6695146cb27fe28647d13c0637920ca6ba95b5d5ae7891e7b84eb0a143d94a2e98d7503baa7984f88c0d3cce46dbaae8da5d793b2d275f9a2e40602765a970e317298775b6acaffaa852f484decb97fb7f9687de052e52de4a3d44ba003b8e61499611341a4ce7ba7ab0af732cc6b806e3e6f383c321ffe6354d2835f24003bf74b84fa4edd5103b168191d1c5c08a5591434c72de88f74b5f18232707b5ca3062d440e4a0e4b735fe8efb52f217e66555106b5acc05baabf1caafa785d3606a3be155b4c33699e77a5176dcbced9735a0f07eda2fbdd49c77cacb304b6d117e896716dae4336d114dc6bed3808eba7bed0fa2fd11e1d94d89c216c1975e94a2b73d635034b3eac913556cd9367f814a6930f355cc416c34105b98910a27e27df3e6c403dd9652beb891daa801abf45d2cd5d0e073452e83e463c05d927a4423c0ab5a27c3a8c39826c00ca0ab9b53ad23b6afb0ef26a7d9c612ad2ecba903ed20df01c0fc985d908f9c8c0df641e8f1082e201a40db9c5ac141bd94746e9cce66f77fc69508e28176185922ff57ecc1d9240285c8537acc2599e009489dc9f56493c85c03f7e63069cc21d14785739d0246bc822d6bcf84b062305607ff827c33fd40147dec4622784331b56f3f8d75be04c6937e985fdbf7daba9a5be6f7759bd997d9dd6c4023fe271ab08033c420505a45f5150811adc18448600fb3d2d5a409281946985199c25f3f85024006bcd3142e4f2241bc16fa9a378bdbf53f9fafa0dc29aafa46239c13bc77af0011400da9b101df6c6491ec5ff812ade1ad7e580bf824be8a5e5e435a70d8e9c4d07e973a41cd4e522226cd344060279e85e746771e088d830155cd42fd2131124bf84988bcd55bb6e382b8c18ca728e0c0c1cc9602b027c96541858235d1779c3bd75966aa09673a818858ff85d7adb1f37b6c7d603e11cec39f00c4018a84da74e82013ddcea8c5b3634bddd9be6437beee01d435a922c61230d5ac4f5173b025ba9667a15b4f3f3340e4407614e52de2dc152b9f462d51b1577516924dd94639721da2b1d37caab0559a0afa59c1e2088ab1c4572fee2ea55064218bf420788fe14509377fd8d43c35eafb41f0fa58b36b48739e7062a05abafe8fdcec2b4d85940e710c963d3ff9952da553d7fb32464ffaa5db858a8f44f2a229bd38d84d0a4a83bd73095c07d0f5d9de98a0dac9c5bf0fe7876fb271f10e8afbf94ae22f36d779935b323d4b61f0810b469204e9161045c69e68b2ebb5e6ccd3fc38b863b310b25101565734fd8d85f592f3723eed2b28571ba277a668f3c1aa885dc70f0f40cb113e41915d3670dd7a73b6a26dc819f71d855bae0143219ce9d9c333e5d10004675174500dffbbebbd222f39ea5c1a4057b6a218f6d731eadae7ade1f57accbb143ea705f985927084931bb1a41caa3aba6ab08e2193c79d8d1b7b0143761f4ed900667db2df9573b895cd10d3735abf25412a085bea6551b5d496dbaa621078edc311ca006c1078e5852ee577a739d39b4970c8a014f374eee7d11009f4dc8526f4454946c6e3a698b081c284a4b249af2e1af5c1cb8872549e4f099511d2effc6d05b9d322ffe2867af1dbeffd0470be9e8c0c4b6d1a18b139ab054ca2ab13900e2328372d11ac6caed4b8d08c8a0a4b0bd940bd79f3463c2b22155559a2e42a5c5a62839930af9bf1a34df3e4a0d0f4503ee4c9c5fd1d35ab8db475a13083db9ba889dad7bb1b01038861bfd39594c6c562db83a26ecae219fac6ee7b0575a4291909070c661272fbf788e7ca160dbdd5c489e370fb653645d78101062b21dcf2a7148dc276e30a6930d33dc48d63938034027f9e45d0d019d946b140edc694271cb1ff43310577d3819cb774501a30705533d85a2cf5c7adb91764ca98bdfe04f53ab9b21133fd2575609dc31162d7fe63a8764d6f0bfb2b1dd2fbeff61423cfaaa8028b87057e7b96cfbe10b23644f4386c725ade61198bb0dcbfa1747a94b00885832a2fbf880fc5bac7707ab82263f9c4cf26ca079609f4068b514e2d34c50f27b248b5d644508e4af9448b78142ceca74bdbed4a6b1b9b1e179049edded8abf1320d1d5cd7f388c0413e8204fc024d2be796f7e61ead7bda00f93b5891961def4294d307be6734749de12a371ba3f4ba0bcc378b524770147c8345296907c8bc2ed6f57008519690e1410a60c44af66596ae44fb27b7ec014ee0ec8e796a7dde2d343991fa7310dfb2d095b061919778dfa9527e99652da234809c56e20d5674c6da530c15f63f22b9c9f0d15091d09ec1bc88c60fb927c08387fb420505867722f3c3d8986f03ec71b55c037927c205b8ce08329871fd81f57ac0fb178586ad62d465c1eaaba9ad44ad2a41bb4be2d01a027dc7f94cef3d5025f023395f53bd1fedc37bc0977c88376946d94e863079839ce169405a5b10b6cb3d093e9af74f2e014dedbb501a93ed8225483ff7a0f79a9a04524073b2fd2d8067114fa703d48b3fbc4001afdbdd77284f1e6f9143e6d9dfe1189736566924a489e22f7eea366f62c09ac5653b9d9a34f131921e5694315d39a292a81c896aa25aee5f639c13f11bdf8dedec4916c87d6137efc74525a6d7be94ed4d46308772d30c3ebe37ae0b5c0085442653f9cdc864cfad74f735c59ee75cd2a9046cd544c6cf899e1aa8c5dfe347ed28d3d9cdab8179c026f12675ff81e678c83b7cd213e233883d3fae9f40ec1a97edfef82a0bc7c3a44d668ddc3e40b5d2d1793c8c8a4ca7293414cc3185bfe9f5cbaae07a3ed743b4c319c93ca956021d6492f3db8d9e4452d4ae78a10d8622420cd1ad4c815fc9271120f18554e513462f73e3ee6e25efab6eec87ac2507b0430ea74ecf73ecec042403eafbfc639ef25edd2c04b3e10cda2d2544c2b28b36f8e22b8589054206b04cf862815f4750493d88ee09878049793a6957324d5e4acf5b0288c541a28a7e9a5212f90ac24621f287a9d65947c3211b25cbb873778ebb2abe8f5f88d722f757771fd0bd9174c184226b999d73f5700774774685864692e9682e54a25481f7a321d8d77b85464278b7c80e31c6f133c0eeb663712c3e560297efe8fa4d2e100d65de6c9db6ba1da4e16700ceaf0b2043039ed88294bd6d9a375a63ef7576d7e47f5c2acb729140963a2353be381c2cf561c18ad782a170dac1ea21a6a6f16d4c923a400efadb7e63d28fc78febcbafaf259a59a1444821a5628d402504db9f5cc95b233145a74bf35d90337495301f4e103cac33a8e56200e434a07b30a041a3ea5982380a05c7172077f339902c6a960dc252f569cd72793aa0cd38adf9e71e8ece7e4700e2d1f408c4c3f81b250d4665eea7f6e4133506ceacfbd5c572dcace98496b646fb2e59652a69452c008f5084c084ada3afc004008b7b708d95b483ef4edac0410420821e6d88cd36bfd6a39463833563df50ca27677cde0dedddd85dbee465fb83076b5f5fd48d53955d5d89de3deca2cf7b97edb2145f820880e1d7a972442cfd8901c218430bafb06777797a70c1562237f70c20f42089d2b730533438c09efddf19dea243edcddb841f9652db4bb1acf3eef6eceeec61877b7857617b5dab67167ca67b194cf12b59cb510420821dc0fd28f8b39db06edcfd4b629f7137436e774a4774e24267fe5ac8d313ab794ce00060c1830300808060c183060c0c008c9c020221830409001c306b7c328b10cab929474c58a950c25e545437b53788a16fd8b8ae9e703fa62632f263c1da5d05ebf1b6d831620c1a984266a9a46688f492a4504f5a99491aef1737c7b22afe57f3a43ac4455a92de22e0ca4e3ef6f5a137fe12525eec245cc8205d26fa689b1d476c106f5a35245628d1d7bd9a07e6a022f1f18857024677598bd78715da1fc5b113c4d403fdd3334e83eb171ea21e68c1e7ac2b079e372363bd48eec5cd094072f7866709139b5c0b4031a59921043240b2e6198c103961bdaacfb8043cf0e26d80c256a1369206f8831c30638f4db803ca2328ea810fe2c438b0a218542684137d5465565c8804da159a15d3f2824066dd5cffcd15e6b453b8fcd5841f90b2e4386329f408b3f65ca0a194ab2c234b41765c753be280bcaf13590827eb3c649c2c74fe243fd31facb0c4c0a45d515b3068c1c26a88eba62d68cc9620d142f4aeb8a59c38589a79a185172e882c68d199660c3c8127148599da973ce9fbf9a73ce8944b3b61f0d130e46b4844123c50b46b6bcd030916424093768b2c4800237688a78c188126ad05c99e10b235cd2346beb37e9ec9d18502e501d5f2be5029ad5a5a24c959fba5480d1822a1ad6d2745a2d6fc8067577472ab8b8d7983f5a1e841052593df5008f15c2ee48059777ddc5ff72eb8707e78410c21eb241fbad49573f995ba2fc0be79c72b5ac7db8393e4adc95159175472ab8506fb81d4689cd6c4369d2f5a3d54270c26c62dab6a9a174155dfb9e3309ceea3a3694dfa8b105e030e174fa39e77411ad5a3e5fce8e04ce05949f04081de6cc3961a360d0f835e6be0c36fbf3a89bdaf114cda99a4e56bbb9089e2c282f6f1032437777f882a62da00ae554561380cdb9801cbca3335c86700d8ddbebeeaea8b3924c67dd90ad07531da81e99b7d94231566fee9cdd20f846782b886568d52c7eae52fb370666261cda262231b567efb76a6aaf19a276ffecadfac03ca806a81f101958cc202af6548d978aa981a3625e90c9cf9305fd82046921ecf989ba6f3ef6338333eb3eaf32570d433d2aa21e43614956729471aaf2a1143346135592314395ab578d500bb805840119695810031858a910be5ed5bdd34c9e7254b10191837e9bf7430c372a54a9ae90d136d54655de8f440309b4a4c004608051c4185390e00d106484785a13830bae7825a5c232541851e1a6823d70e8e779cc6254a91cd4964a4899fd8c8fe4f249021f7647ec828fe4fa6845c9570a4c2b134e881794ad9cd1c4cb6b211f10f8e7cfce93af411acac11e9c7069a005ed4fc187889a259fe883153fec563e4b8e905cb0a3ce92ab1b680a326261977ceee285c94aca2d4afc4d25f92fd60c35046a28ce47eb9e3420497bf2e71be9473d04613f152a7bb7abf9b65c04a3d41491cc09bff693f341327ffbed8bf391aaa79070b7eb65af759f0a357b4f1581d5ab91671c86fda68cda93f287ac90a30d922f3f013bb4c2b2e4cbffe1e149a5ea475453684f521f4ac159f2e7a474b5a2abafb22509edc997524ae94fa82dda027dce011adacc1ca0a1dc292212c807a21562e44398cbff480830cb3a22f83d70a8bbcf926d852cf3b76e7d96a4b64f75d3058d88da03816bd66de0437ad5ecf9f5aa29241c257bd4a33a273e20a05e7bad73021f9575ab0fdaf31fb241fe1b77a43bf097dc1328b4fa276081788c4171e80f0ed050aefdb0a3adf6dc87e6a474e5ee4adaf3203f847841f9bf1f5b8ed016c87fc01d226808edf56fdb5ef77bfdb47fd54c28d61df9a82025427cd91dad9837402cb9166d813ea854a391fd650ce3796ec299d09ed6738b30d8b8913068fcad52a9ae98336e2aaf9a26253821a1d435ae1ac82c04050d2165847f6b2f2251f9a2051fc8d8a18921d27045a42c66a490818b33c01cc1257e02aea03c9f003194a7fb96a9c8911692bfa99d5f24fcd8ef70431880b55a08eb5a3c3b3c3c54927876c2e8d20ad2442de40302cf638f7544ed3d63e1e95849db79c9f92091bff33bddb7f3f2916ae429c184ae09c64a9cc456da3bf21973fc1dce67e77d781ea9f2741fd79dd79ce7793a1f245e79de2bcff60ebf8f0e9e241d5d91ae3a7a8877506a316796e8f2253e8761a676c5d7c1c3f1b94a7cb682a64a8dcf5722ebf85512d5f19a0e8eabb742961ddfd3793e4b7a7ef5abee08c9d5d3bdb3a20697a1e7f0e8e0b67ece6f8f7a1d3a9a382bbe8e263a294de7d797adb4175f47c749f1351e8ea52b3e37b510c53eaa3ef2705c57201f688fd5f730e3433e4b7c7ccff7742bf4bc8f5f577c568acf587c28bae2b313a75921dc4447ebe1c3dfc76f6a094ce2a33b6257cf6f2a498fee885dab37ea1daf43c58dd01e1cfa3d0f0f1e1d2b3dcff7c041bf0dc3c335692fbe8a33a1bd1d9caabdd8d1f6e2afa8d06fc3f4bc773ddd7416ec6800b080a30b13a1dc4f7bf1880f3569567c9dee9ba9eea35bf75154d764e70bca5858a9bda03814fbefa7ee92152b81bfea8e600f4eb860375d4eee4912f849fc37a564f53ddd9102cecc10c6b56a0569efe7a474b5fa3e46f6b2430435a16bd29e102fe8f7a366d563c992558fee68c534b97abaa9a4e757dd11bba134c792aba75b67fdb41043a50c9ad096b5ba62b860fe8c081d661b2ec64c1bb8a38a9872aafc984c3d60d1387103125af440c59931745a84268a4d9f32cede39e764a893f381a0f67b105a3ff6fd738318b67dfce288f8d0b2f83da8ce64be7523b441fc617854fe842a3fed268fca45b6a0f16591c638c61eb6d7469681cc37722cf2cb59fb2a119a2857e1be77fcca61775287f153dab6a9138745fd749d993353ddd6059ebb7bf7b673d7716baf638412078ddb6194d8cc3cae9e422cca88fad5ceee9b581763c6c1e9dd9187d48f8a66f0a3a2dd4d685a77ffb6c71d5da26dc26eefee86a341d71af80f54d114d34e831f950634553d89e8988c282d661343691a2a9b980960cb331ab7c32d4a6c66dbeae7877e7e1c9331dbb20c85a57e007d3b36d56a678b567403faf6bc6675060ba41fd50198ab1fe8ed4b980acacc41a57ead32e2c499c10c16385e331cd9c20d0d5e5881f39474c48c530c4e4a74e144841b4b4069aa48e9fd70843e63c438c648e4ac55cbdb517f623b11ae90ece7778060dde1ed903eb09f534a39e50fa69aaa89c99fef96b783a65044d0b6d2e27efed2432a085b8a19d47f4d43edec9bd338ad51fbb94c97dee26891230739b68831c489920381345f6a80218a0b2d90717dbb748517678829630d2f6880707d5b06191d9ca8218e225a10816b4c96a42c9a1063022dae8f5f7156505115f5a81411d43c40cd3e4b11c9561f874a9d13488e302a860159a29f4ab562ec638a0806e5e0a126a00b1448d18308d28ce19a0880f0671c5dc411a5c2efa11d3467888823e5f5a2562a8a5159680b0437f9f18760a05bfd4808f181bc1f2d7464fb755677c430d05206113cbc5e2e54b7ae2c527e076f68d775f13893840b6b96f03893840b6a3695647ba3cee4114fe22cf92809d49efc222aa8ff0704791081103c398cfb914384d00fe8c73724490b7d94897c29060e21aa7c2f84168a53aadc240cf2917c4384640f224823458d12074de88a7e7f1f6217f3c3ee85a97179e743a4a45d47482e2f0913a323beffad7cbc4b72c4593d0030d40b25b054612b2df4115d494a6a21a23f3a725ac2cccb251fe38e421087052e6cc30c710b9ec4b4b0441cdfd63aba89fa87189df9a23651c5dcdd534b6214285cd86f4a89ff3006cbcbe5adbadbe5ac7676212906492e168aaae0b2e49adfdd5702e6eeee30b68f27355c66dda38f532f31d39730cb543ffed21fa11f09a185a0171af05992fdfcac5321fbf91ec6c37818dee29fbd9019daa42915f463a51502c40ea59e8da8da7f9c44fdd88914dd5653ebfa4d7056bbd6a01e2b29b9d4f03c1f5a61fe0beccabedfa845e403024cc3dfd48e52fb35d0dda9261bd42f840a996b3e9d630065a812ddd245098b73ab7f4269d58595184b0e1893667369c585d6cd94da32f2090999c5eaf3e01851fbe78eba62e08c60884924d4b351d5aa4514c467a8218c12468ce0062e492c1948841183152b4f308579a5c27ca92183f8428b68c8a6dade84a184e672546803f538af0a3b80818a5913477dc1183a3a2070986f5c3055aa07905163882cda28e142103ea6cc1912506133c30e3d4411b000f6c4f1e6cadc54d1867dd46ff79c73426f0ef512e5d2a544394a43711f57d4d4791d2e87931f0935eb3ef8506245bd447d48d55b58e8e7416514e7a86d7b89fd16440aba3d1b3516b70dc37c7bdfb68e48e382b49c686d13b5eacf1ef3971a962202fd3b0589dae3566beb2c8a1e2b602925fb17de957559faf9c5b829e34165375faad629316f68a82b7e23a57275d8fdf4db8f2ff7b16d19bd779ce0f7f829ff8a97620bb405fae0ce3a64233428f8e1852ebab4c084a4440abad8d2c4451156dce0d0bdbde11b659e2084107eec69837e35f2a10d7c80a1cd95366450e207577ce326cd1a295e2478c3c515bf159f286a9147d207494668aaf1374638860c3562ce96316ac88863d438452c0eb16be3bb61468d6b6a6c63552ba0fdfc1b31301c05c512c6658a88f12b7e71410f396d1851635d316d08b1ab86b640df12200d7d9a3df64cb2ce87b167e2c34ae4910fcbce871ff5eb8a9d12edc8875ffebab4ce87bb24db6b59938d9b1c8a421a052da13df850f39ce59f7547482e9f88619fbd12ecb38f9f652fbba3f9d91fb9b49e2b6c9fbafd0c0c1352800dc2fef31fcdc206b040b05f4c04c65e08111715add4a065ac185088a9d82f6351310c48032994ea7cd042df863d56577e7c25f26387e452123ff5db2b49fdd61d65e93ff281bffdba529d0ffc9c5f57774a747c5c3a9d0fec92d0d7316a0d23722367619f837d0aa351d01fed610f3ba0f6b02fa282f273b0866e75fb519c13f89d32c273540df546b247755cb5ee838f0257d4cf47aaa8d9750dcdea6f5cd48fbdce0aa13e141ffb950f49df226dd062e43eae5006ad9b77aad722eaa1ecebf1ffffff9aff3f6c01536d7356ac6aed90551a73aaeaeedf099c46fd762a1458e7066d33cc02397611af43f7a2dddea8bbe7ac7d2a045d777767223928ffc6cc084df2e8545b373f9fae7005fb97f6fb94db72b3dba91f507ffe3de1e7750a0dfeebdb2c9d650d5162ef47516210eb607bb05b1983f07729a1c3658e1246b9454620b0599029248d002e9bdc86d85d2931397fd7c3fe0c2633df0582cd5fee1821338a8b6677852c245998de1d3df3da5cb4a80d9522021fb55ad35ec52d1a8181f8ec10a0856e237051b640fa37a8f78b22b17a3757f0ea4b57b3d522aa3d89e0c0954e9a131a1b6dec80b5692389cba43a53436132878729da2b850695195046b8d95a138d1795ac45d40a42c4b4457333656691846a4d336ac05a44ad2044645ed9ec42ce3655d410c7a42932860d46db78b90116a9428d6ccd2c548e1c6166b6018286225828b5d961ca112c4d6da8c870c4082567ed7c951c3a2570d2217bc249860d0e9575a9709292ad200c383284a1861961b499707b89a80d2a5f970a31beb8e1eede6b5435e14655abec47d3e28caab8c94d46aa5a651ed566fce1082355c595c4bc72accc1847e608b9a8198890ce3ee33c676d10ff605b7351fc7d48557185610ea1670e9d4e38e174aa6a200c76dc2815d222e29a43c5ac72dc39e2e1af51c46423ce0e47e6620d2d15a8c6b8461635b281449033af0ae1a76ad5ef67881a4154ff951a6f544f638ceafe500c7d2f75ad6caa2722ba48e39586172b2a74432388da0f1b8d39e8fc56627b6a03c3106d5e991b67bcc99183c6ba62ce6063c6339caa3c71c6143b40b174069727b0386b2756468e1a2f488a01d51107c34275b0c9a1f2450643192bc828e3022b28d592415d2ace541943f3bc67ea40402a95a6d36b30005842c758625e5962a81411c658b2f4ef07d0a7b38ec5a21f06d2ffa52a7ce83db9aed8165131f236a7a72aff0fa0d6e167b88a5c8a48fc540873b55bddbddd66821618aececececededdb641bc687013eff373133721713fbbe1a7faf5eb01eb6237ce72fda0417797f584c4722e38a1cd16a2aa1d6aecf0626eb17137eb9deec18c0514e2dd3768f3d21a815e8e9e3ca9faf3e8c293eafeba3b691395a1baa8f98c8d4117353703917277623242e8103afdc1a15b81307e002294623561b7cfe384c74a0f3bfdf117841d2c0213f501618713f8aaba9d0f125595afaab2ebc67727f16167642b0d708bb183dcd4cab29d4e2d775bac10a8798c8675dfdc08b4f521578c9115376880e7435ce742822c706f2d94ad07c320c12628bb62d357e11ad068db4273072081183b8ecc5fd81021e4f52243e6106832d26e41132659b051701311b55a9ef73fe5b343ac635ea0865c6a44a1bae6a25eefce5916a30747012e4bb7dbed116fdb7aa769da131e273c3e68db423e24e58577c9edc01985dacf31767183dce5dd413ba7c1a2e9b873e42cf021cb3f72ce1cd871ce417bc98fc9d8bdd65e798b579f225d35e77cfcb7fa14e1769697a1b497f2151a5724c88c45e3df4e27566d19c25891207f60b9c89deb9ac39cc345bbde39a9544a056d8164ece8e21d24c745535c0010b5bc89b1d00280475d9ed87ec04572ce2ef2c4be33785f20b1f3daf3f8710268fdf0bc1f1f7cf93caf3537da24dbe0e78804000019fcf8f8e8b1eae1c1a3daa16387eae4a4360d954d6c837a837a833668838af0376aef18a9bbcf68cd45dc707e57cd6bf5ba5f0675c523a73e1cea71917c8fcbe20054ff8c99bb0ffb9efccd1fbdf67c76adf69cbb275fb1efff3cac621f5f9b7276ccb5f7a3259780415a47cc8c60f4016cb11065afbfb32fa7ea2cab7378a2d023ede57cd044f4579fcd1cd71b03ce50fe7666e69ede0ffb218410b653f17aaaf2fb2917c2147453440e300455b5d7d5cba00cfd5a435af2bf7dffdde7b8deff01ea187006a8dbeefdc92e551466572941f0a0c6ee84759883e6eeec7c250e487ff88206c1d4575a3ec4e88315c21495cd4e192952b96a9a94520629214893f620c729e24b8e3fedad36ae179b1fae17e1dc680b9ce0b0108d53f7fbc5a3a73adde72d8c85ad740858885fec7dfc8a5397e7771786de3e0c8a47b6bb3bbf9eda4bcef29f3bba6feae87668d764c0e04dcd72c7b2a258a094104229259452a23a6772266722a3fa3b161f8249cefa5fad28752c15b5e5f452759e835229331486611986c2b0a63a391b0af53c29140cc3c12fedc1a5f6fc61920fc12e30a9ba3355e7f8d84bc852f253170d76e96017d8853b4cc5c12ece626acf999fda0bf3052e7dfcd4a57a6fe577da691e6268f1578345c45f35cbdf55b03d3837da86b6401b47dd127ae87dfcd2df6c5aa0490bc14ffdb730d834948eadc0160d6120fe6ba4e2f13dbfe37bfcbe0f8e99ba03a746cd61daf37ff71f6202adf4773a56cae99e704d0df127fe9975fc85bdc88ebbb4e75c6583fc89b0d06fd354e9e1d8d56365811e15c7ae68016e2e0fc7a92278c6d06fd3b454dcba3668c00eee97c53189094f4f4f16685242934e673078307b6f624059363108b45e731cc1686909b679b1941ddbaf9bbabb6b66c9bdead1d5efe058a93bf02bcec459feab0cf3cc488fad0041bf65a21cbb74ec300ca1bda5dcba583e4c85a0c4adfb0272a0df3225d920fe14b7ae2bb46c9cd16efc147cb58acfc48cec224cc29f31f63f197bd85e3769d6ca029c16740bb269c0d02f88d16a452977ff907db2c2da0f16dd0dbba593169528ff17a4eef31841f9f78568a0bcc206edeff04299b90c4df5441bab2c0200bad06fc308a19f57cbcc50fbbdfe1f2d340217c5ef9f8017ba635af05251bf5f06cc63fb2f27f59fd41efbafe34f1f4a759eb37aeae7d59efacd1ab9ae9c2a220125be301007c0a147b8683ec78ca7669f07b5833220d947ce1748d67dd90241fd2e902f3e3b898f71457549187086c6eec9d7ecf98d68504fd839e2d4f95f57b3c75ecb600bf99313788efa040559510fa5eb091e5454c71bc49183d503ab0a6555b7f5a33deebc1f45f6cbcb85aaa49641774c94d7b792b4d08e89f2fa81c509d518131af41f2929ef7c80a15e774c0b6aeab6a932870a0503a1a762ddf781a006c08ec988bef1b7830eabcff61c428fd081ea07abd7095481807668f5db7aaa15226a0ffec60eea00aa51772a705882d11950fee6d0a17bdca87cf79dfa6dd53f0eecec54ba427627dcf5e1a9db95a0727fa3c508e516239498ef622bbf4608172edcf64b578980d0dde1730bd70337f4db34f6d546598cb6ad692ec8c7ba25266527bfb90821bf9cf54785cfdeddddd093d0166848f5213db425413798543fdc0487058eda02470cf5db326e7c519b39c2ae3df42eff20442bc4eb37a30c46babbf755677b2f67d298e9fbd5ddaf97bff8054568722cedf96b83fc75e0401d0917a23dffa21f2873b1431180ce2fff8f5f29ac90ee9834413b0a6f0c7bc3ee006f30daa52b4f520524bc12944801ce871797849be85a71654bfdb6ad8456e57742e31768d71533c70e957f73bce8d4352385e9dddd9de757c52171a57eabad9f6785706daad26139b5a90dea653173b099db0a51b51777b6f6aaaabdee21dadd06259c12ce2825dc0a21a44f908835645495aaae983356308e8cc9082144651a4d11c9620e9d7383304783de0f4aa7c7cd35f788798a08f6fe3162314620777777777777e71afd638d3e975256643d84daf16c87d651bdd4fcddefdd3d89fc3abe0dd47e47a163ece80671a0f667c26ae50dd8a0c63fc21c86c3701866989371a0c29f90a7ca9ddda990fb385083d07668fb19ffe3ea7eac0dea2260eb3433af9ded1d3ba36571cac82ed5134830d2aa279860426d8e2b84903e2519a109942db34ecbc64df58fa37f22754b2bb405daaada35e2d51352f852a8fd306e310ee524a9fe075197eabd65855a9ac3cb13afa5fab576303773ed1f5eb5fa796f7b82aa7e1e28cefa68e58005d4eb1358bf6d1241a79b5b6a0a4b00c8a03b4f4f26b490acfe32d5807ee8316584bfbf490b7dcfb56afcf8be587c68eb56d0664a89d6f93c605d48aeadcba67407feebf259b2ada07d4bd0edfbbb15deb530b53b1ffe15a6d4cf0726b9a9dcf9c00e8458e17f3b6a6abf5769afbb0d23c2458ddd96022176304b9a9d638594124208657cf8647b557f4d3ad11f8f3f4898a51f955b44bbb4bdd45fd809ee2dde5d7c0832813f534b62b7ce6aeee32e95e9066d3781d1164848dd5e755fe366869ad294cd8c13c306f2efde283bba41f453d5869dcf22d5d6d643deebf58af2f47ab97ce9f5aa100c6d81340ffed7d90281485c298f28b4e706417fd6d275813aa51cac7cf3fb2cec52e3eb4441bf9210bf49fc244c7ca44cd243dc9209474e35fec6fda2c6f892cdb189f8dbf4f25c317e2b3e51fc8fef454da80c07a01e301f5b01f5d9c7a718e7a3244375d359d8ec922c8acbbac5ba0914bb3136da938702f4496eab1016d47b14d1c50b4754a18317585cfd6ec687168d2f26d88189386858430757bf2f79986d1e51e8be5137f16f85ad9af88475df8f9ff8a48a4fdb17a476f7a37e419847c94a1cdd23448ac912ed39750213a7daefb96112cd38ab3fc947094aa2baf8e4ac4e2de1d492df5412d474968f92f9d9ec56c9f613c9153f4aa5da52a987762cbd5eaf284bb4d0d28ed981093a7d12091c7ca89fec72839afac92f527e52b2c79fddd1fcad9bceda3eeb8eb2df3e99f4c9576df8c5a72a45eb5addca59fc14bbc425b652fb9daa9acf977c94cc75d607936a679c8f92ec084e792497b61ddda0cf979efa6974b3a2dffe54bff8f4e443eb8a6e5e53a495daef4b3b4ef4eb2795641438a4400aa630b4d0620957bf1c8115686e40c306347870e3ea97d28c2fedf5139c43c1407a89c78bf2ef7fbef4b49385b67154fe7df8439aca1d94e6e7caddb7c20e69eb43be440606a79f15138599a245067ad4cae2621ace20e2e53a6261aee1eacea83be0dfeee01be25276fd58a8b0a80a2e48cc42379bc1a26cd82aac6584de8d21411a02d41d73c31b55ab3bc6063196da8ac9c4b2a1e403d39b338e50f2a18c2d8698420b0f60d4d02253d062b0d0d2840c5a9061020251506103831a3d807145b6c407d2c4816304555041061b03cc0005991b74c84189329a123dac597a52e20c192650810abac812031733520cf1e68d73d93625b882ca171738f1104601c200c28c31a260d2c28d4e42c99a256e4803c7951cd6984026098b2d6c00834a1623b02d61ca30c1658b0c3dc440870c336b740942a987376fa4b42059f9020ba62f51e658810a160d3450c439020e37d69cf12607056bb4b0914605693c69d980c98628ae8800872b6ca0b2ec531063a0a04a96297698b2e4498832d06c51f306198884059444d066881896a8e18b098080e1cd1b6ba0b9c10d37f1040be042658e26c880f3031b484bbcb2a8210a982698f0c28dce113923e0028e0b42a0e00d30ad25ca34e9b0650a20cabc9102345f7cf14402373940e1466c459c58810f5c3841840d583680c50239d4f094022daab0c1c6f57d0f1468c06813c6143659b8f85b61dec0401c827ff927ff0a889716328c89411537102163116ac010011a5abe84294302d7fe365941d7fe66201291c6154a6bc081628e18a4884320255d01430d9935719e102206304a63584185046f387d65a238910233b404a1446b663d5d93c8956519a7fde4506fe41a87e24cc8e683207b0ef6b766ddd61664c345ddccbd41e84fba42e95ac47c6d5b5dd01d33c3963a4606a7b95195927eb9e6afc6536611f33f7f0cb697bd91a750a17c4cbe74327fc77ca39e1de4c125d6b110bb5672561f65897fc4823f16336807bcae66275e8781294bfcd57ad37ccb827de49e2081eb45159ec854ec906455d338e6b64e4a243bd599a4362d83ff18375fe3a4681b27657b97bfaedd0db07f23dfb87569dfaab664a1fac3ece3cc3a4d4aced253ce19e315ada97d7b703ec1e637f56afb3820fbf94cb28ec98ae08413286a2a920bc9d51827057b2a65be085fd013d6cdba7e37e887ff13040e52183bd6ffffd8af908d2f68dbd96ecf66fdd8a00d74a050ac68eb4359b22cf2618c48626d25bcac181bceccff840ffb8c9392c5dfdd00a97617418aeb6aee63019b1d0a5d313f8210c3b00ee6a02d5016cfc2efdc932e43a11296dd9c4ca6643981a83a81e215be57915c48e2771f4b91ff429613882a14affe7337e87736f2c87d10841dbcbb1d73608742576780cfe1ce80e95ce45950e8eadea5e6e482c8c6d0df1f765d867a7dc2f59b4438c60d8a31092fecdc6d4ee2c3baf58b980facd8238148209c5d31e9d87bc59e705d21f01785aef13b769281f4af93f8987cc25572b0eb9c7446b66e743834249165f42748a08c48207c2dc2ed27dc0c165896bda06b068b5daf0147f1dba1ac6a4c3560850a7f8210bfbb0f367f3fc120037a7eeecf80d8b5f654378e0bec10aac95910b5c57af0c97c27f2a11ebffa6fbff0d1f33f3fdcba34ee048e5dcc6dcdd9d413fe4944ebc1f5fc8afbf9f8a49fa1cc13788e4a515fda83a8a5f6607328cc4a5f5b120289462db141f02987526a0f3e6a0b9417d4930fa1be340ba252b02c8862aad91bf58e376a4debad534476500ee506154785ac4f9392844a22484adf3a4d1f28367e18b5c606c147a5b140722aed504f1b04dfc719ca1f7d70abdf5497b04e75a74359690f7e0f97fd70599755b6f46554ea0fb7ae1e8e5d9bcaa86c104425b5077f0787aad21efc8ce3ea835b17072da0d963bffda7a5a9f07ddec7c3ffb22d15f5d4a454e16b695a88d5686c5a08f5cc5a155b34951848530be978f85a9916daf1f035333ed4f3f035a615b23383d0c8a09e506ca0e24035398fff260faac9ff5bd50fd554e1675b7ce8e7e1675d322f3d94c1c3cfbef410001efed40ff554bf6c4b850f004e939241732837ed8076fd74a82767fdb4417dba75968f2fa342254bb24295aaaafb565460a9f0630fa7997116fc1d9c564607a73529719156c502810f9f4c109f26a5c29d4e63da2088eac1a1d868541ccd821f001dd83c55f8d9abe14f362d441ffe7ceaa11e0f7fbae9a1d543edbf6c4a859f7a1d5cceef703aaf715ba7125c302a4fa50abf2944853a6fd49faa3297aa91e3ca4b50f894ebc1adb8ad5923a47ab826261c21e23e6043c6d69e7634a5415ba0a10c945eaf5714d7ff2082b0a5833119611bb308575318ed485241e68525170ba82dacb8b2f880c0023392fb06b540f78d687507a349a8f4cd76443d0a15aa8108000000a3140020200c0a0684228148302255a7493c14800b7d94407a5c9849844910c3288a41c61843882184004088010619221b16870fb4ffe529feced52916399bcfda306dfcf2877e0e5e74d3066232ffa8d05950ed614abceda267404d96f1ff31198a71c63fb9c7a9a7241a195f09aca5616ddc7d647ddf330ee7eca9cf59dc87d19afa82797e7390da1190e84dffe2273659add410764805d3d1e68606d750f90270e7519a9a56a0d626b76c210fa69a5dbd5e032179bd3ee2ba1e4650868a871fe89373fa27e681401c1df22a02604e9440fd5ba547c02bca68004960637eeb3512e58da96c7e03c6b8306dd65d4f5c15597f294f3f18fd1a2b5fe3471391dafd5788a719004b7f31bb1794b1a2237136f5a24639b069ddcfff7cdf89b74e75d3941ff55a372df63556b6aaf7be6fbb59839bf6c08c2854cb03b8d8617bc57923757e7cb987fc46c9b7f531c71b0bf00f7c37be9539bec3e1744cc51e32fa66dc4efd91448120223ca6f6049d75042d015585d86b5c9353cadb4951e2b1e6c8c892904e3702a1a46c1df5d5219692990b55b2d7cc6adf96eee52dc568176f39fc698897598882872d42971ebf66297ea77440185b1b02ee3c5049ca1bd15db88da2748520ff86296e5836ee7e6a94c00920d081216fb8e86c25c665830ee5752d030388a1106fa97f8d402ce113e6f6a86af8791276aa0190ea5ee3f14a625eebf5fb5577b495b3d6b304335c6909908436045b1268c704dac71d76571faf42df36a57e1c6278acd584efe52fd9526d8ad5ec6a01ee0ad3f1e2fa06c83a024941784b7804b4a647fb9199e58dba69a7c9b24549e4f319df27fe9e44ac1e79d4a9c898b21e736d1632eaa8d6ef7c904a37ab5e262f619e628a1d9806a477513c87aeb70befe071eafd814156d9c2506386228913c4e34cbf4a0c132e97095c8cccedeab2bbf1ad6eec20e6a159a7f58260e1f681d986671526a971c79e489b93e8c2f0484704d792f90ccf03c7cd9a25946b82c1c6e59a44f66c5f7c962b683ce8b8aee2616ea362fb0215517300fd6fc06ef2abea2eb84816fadc2a84a9492b23b30f3542cab3cb33f92612064cc1c8cb1d9f804655a9da7a17937c2b6e2eaa7c060ff41e8e4e2150c7e8c64a67f0443e0188ec58b94a29cda0a844ff0048f48e05317ccd4f403fa13d5530dba9f3a8e31064e76e3c1c08fbfba85c2fa4e38bfab7bcb11ea68869d2edcdbdb43f87c1a10de06faf9f9b3bec19d4951031a47943abba8fa10df771f3c194b6ed70d45a19be70995adf3688b8622494fecaa24432ea6ff281cccca28ccc3ffbac0d089049cfd2f9aacf1b3a4019b0e06c2773a63f787a69bbd83bd25efbd0bebaca88a2db1ca7b9e297a2763d6df96cef12742864e2f8bc3f2cd843dafd09e9d9ddc5ad8b55ab79289c7bd554881d024e58cd225017f7d1e6a2af24d1b706b35fb9f157ad0af3c2c9babe7386a016b2fdd7d536662cea9767da61b1599a6b75b2fef73f5b3514a4fc766657089dc40a15ec7434840d6b108948bccaf4e00dff07bb88a3c47793f1297e92ae59b3860c9c032175af892fc52b96242cb57faf251804464995398882db1fcfd03a4e57479352c7d6179611296a2261a85fb19a6361c851670b3e1c965897b1fd736c3b292c5ba33f74920f4199e3db01b35414c4825bf7e9623cc683b693a671316a837e279ead9196f97534b9db67e8df2898808dd991f963539131c384c683b90dbbe37c0a881316c31792bddbcc86ba0ab00fe1dfab19eabdc4c1088f7bf380184820a6145505a7c94d1862664f4cbb97e789927e681a4217544f1a0acf3a5aaf0c1d8bf76408891edfa0f0324ffbd067ebee90d6d46e4e5622df4bd17bf0a7fea73af0f10f7e2554afa603d3848baa678c079f64b599127bcb6d473f50a3140cbd3e0798305286188c278e7ef591a9a41d0d26f1e02fc4550de54cfb81df86b5674077144a47ec6ec131110498de7c2092c22309b61d1efcc7a5453c655d98eee54b48b2e991c54be3bbfc984781d743c40747c9ba82486102db7f4c77f99eeada80ffa86071545945541a8fd2baa43279aea53d712b9f81677474ec427ada2a72163bc6921bf2972ac6b3e53eaf14a2abe3030daaca71236de58613f35bb1dac70197bb16fdb8ba904efd889cc5ce8825656e60e3490beb6270ebb044f3b2e61c43ada2c04db518051eb2fde7f8d00d4ecc2d3a32c1da6ed19f56c2c6f9ab8a4568ff39bb15bad52186669a6addceda2b0574f50f5acfdc88ed58a861fad16260d58a3dd4580136a49f5a4c62cb7dcc8ad6aa214a13620c278089046634d4631037e60e161d029935131fe365bdc0a7384111826d6ea86f68e09caa1b1661cd3467e2c93753838912f64f00b928378cf19c1112c8ee18f8163c821373d9c03fa1ce837fc2975ff1af9aeccf3ef78778f7bcdf656df210a9c5f5d71ab823f85945f18a4b9e443d9a5c1f00d07ab1a04af61b113c2477093c870ed79fad91716336c547ddeef6dd54ca063ebc5a354e7b2edf56108f4c912d310c2c4425cc0e22d0c9cc33c98402a893541eeabbbfeb53ff6219c114b85b18d6c039757cbc90127b19023eac261f124d6299230252aa4228e755146e8d37a61e8e945c94f25ac8044571ecf683d7f4fa55ba23259931e34d96a0837d8b334613d703acc335ebd1f7bf1a449c0efc3e387667b81614a501a1d633bbb42b01d21137447563b9f889c25b83fa598e2bd268394c7ff79e5bebfaeedc28881f4a2b1a2520c47f0755aa45ed8919ec6c2eecd49ac822d648bba813ec0e0ca6d2b75e735c4abe2cf8f6043c84cec02d2e95c5303a9ae0b179537514068bc2db75ad70a123570209942d23249097e131b67e6355e19bc5db06644cae7a98dd3ddc9a684886af440db49cbb5f6fbeeaf21f968c1504c89db61cd2c787f2fb5a336e3a0d42fe7895988af6fb2adcc1b3567c484859b2b0e47e03ad5f6590bcf3507864df7fa9042db4c976111a1ac1c3886fd19f369896c6c27368a2a4c25d03a44e085a1dc854cf0ca85ee280ea893ef16299e603da305d1a5e34671847108768d691da278ba6cc835c6b6eb2d6c91bb4b077f016965027322e8523253d7e075b348661fa25df117e10f5c950776eadc2942cb69d2ab9d14a5e3292fcdfc9c022123c5a4e770175fa4bc4cd828da814653cfa9936e654e25724496fc86cecd1a1277ff874245a57365b96067ce5ea0b017f94563267caab6101fb3c3e1fb7dca800906d8a28923b3e20d3858e60772a50fb24053f2130d42195c36d3271dcac568457e4f0584a319d14d970e398d7d61b15c30db16abb015526c45e766fd5449b49e6f8ab88f8639a7b6e9d63bd8a37212b9f765b8ef83c0d8952b8152f5de8d23ed8a3983706e39c7b6c328a7af57942bb8ae738a1410b7621cfe8340dbd97cdf5e767c61c032966865654153baa6b4319744f52bc2da3c42b3017fd3e33e2968b707c1d93fee5c97f55940c4363389d922750831365960c9af70290b5ae531e77ed1cdb93a3417079b07fd662dfa1726a779c6960486210dcc3e69469811983e88c0e453b1b323b2320d059b6061177dd0f8c80cff48c4433dcf97acd138c888554b42ce18db4c883dfe2681c30b56985fafd3f9eb3fd65177f8f1c1113c9670d43024b44ccff23d3bd8eb628b681500ed6ac0930780f92e4bbb33379844051aa3bb07c15bcc3f04149f84cae4ecd3bef8a904e25c31f63fbaecbd1d1046c7c917b181cfa371d28b8e9e199f1f09d3fa4c301025165fc821ca5514bb4af5fa45870118556257558ea2c6d5316fe43fb13038e4b91b7c117b6d0d534105f588a18f516b2b861e6d8b08d3e2867b6c62f32b0e060a14ea54a5b520f9e711fd0102634523dcbfd44259295a5ac9e6437282bfb52b80acec827c2784a349398000a33cec9d5d6a2a38d12a553a35d4f8f7ae6a5daeca90225f3094e2347ee41821d73a86991f40446548db6d2685802deac54aab75832b049c284f9798da180caa2e4e660642dda61ebfad7cbeb9fa9fda268b94d3500a6a163968b4fc31ffa330d6fce8967dd6746bf809beba2cdbf1c948bc35f07879100b18694f2aa93e0709d3afbadb1f2d221e62976a13e02c6433d41a2f6b75a2bd64e3efdab9d932a792e4ad724e6370569537c0f4b04db557dc0485e4aca7f6df320911a7d30152fb995eb02300e74a906af34db763dd82a360fab02ace7102658fb20bd8622db9617b6998d812347dac23230b16a2c072e6b5b742644173988587463752b66ebda5a0f0e287488290b1ffd2c0d4850be493becf3dea504a79ac9c0af6e3111d2178f7e1e01d6651554aefe678ae43a3409311ba0e90685b1017fe515cad4be4f882796de10aa7b290596f4839ada264735d1b83cafe8a2d9da579c32691b11915b07f3cf8a7c819096cf43ab387a4d902ac36dd650bbf755ad9bcee3c5d4c050976989932e05598b4da951934d9b8ab5e065ad4657779b690e35795c5dc44ff5d146c254074081c09ff4d36ced3af820b8b9077507d677aebf4c30d426329864bfd18b4f36a3a7d98a5be59be2c0bb2fd87f5fe8f019495c6cf2096173860fe609713417f0c3af67be3a2767959f429f8ed688d21ef9a4d334978f00b4e3c518ba82aaf227a36e6f8d482239949ff56cffc80b69861bd773cd15972e24e5180ea923e6a88d1e07b5b538abe1e4486fb6dd20aec9596f047f1f46115426e7a9a2725f70426d1917642ca2193d0ffb5cf541ce4f7131bc95a35f47c2169f0b2695a95ee3c481987564ca52a14d6f0135cc534893ba11c8c6e375e9a016cc40ce37fed2d6bd628c87f582bc8ceff811a413475b523b98a5c5a82d61d2ab0cbe9ce245998e6cc26c22af21d54da2d41224525416d7b63d942e68df9ad11f338af6de58e98133ac57144865fe071acde89b85d1816d2845db54a95b8d0250f1127595934d8154bf751affc1875d2e73f44eb2d64bc909702b1d47848778c9bf1f72b77176bea49db697f6faf58c8ff179a0950f21831115884dbdb9ffb937bdf0cf26944d06cfe50df826c2f24dcc7ca3b125e4f06a011a21a91af6507a65296a62e03bbe7492739d68ecb7e438c2b66fed45c34b23823ce2117981db8d45faa9e7fcfe07428507f498e2b16d24c738b1016aa502f2d5a6bfec68db7ace02c9431476a4c1d12dd28e7bf397cc2a5d0597058bcb6955a0846327d6f6cfbf0d426a78d544481458bba09ab91e0b431cee03d23ae77eab2bd1f68d033fb207af1ff7896f75c54f5e5ac2914dffdd3277eb09011f2fe87fa0b4687d069234d89ca6e79a2778d180e2eafe9c7bb5343664bbc67fbc76496a8045c945ea8ec2b7bf0fd054262811f0e0989d0e05e3e92abacac5b62bed090c266420217c25717daa7801fa129e4eee41746a76c568b1fa171b284ec91d29ad484a457451412a5ce7bff4f7845d8183bcd5cb7a05be11ecfd81cc1f3aa1e21d438e45fe2b15ac022afc03b40cb5b223d3772745ad00526d9b87355ab8bc65cd3746a01d3a0b05f5fce0f960e03c2b8fd573035f22d8196e321c16e6867457213afbf7a9af1ee559500beaa8abdfee90bb49d7fd1f40fa24b17949f2387d83c21180621bd00c212e484cf9dc6ba6de39a765b3546afe020d888ce975e816502baf7b788071d759ca2fbc770bbd6ac636b6d846d1fa9ad00dcaa30284ed54332d1d72bf16521fc00b1477fd68de1e5760a552a50e5a1765686dbc0ae61b20567c6c4c8cf88800adb8def80a389dfc9852d309d77d3c0c9fd6b6d666de09876d2dade895e485cbced61a7eb3d9c4e043ed6613913aa3d18895c25f75bb636ac2f8e43448ac5833a3c0e51400c1a611c23459c37746861d7d5c0eef00368d9c618f0883757e87b943c524c6dd01e54731b43afab4e8fb9e82a9d3c3229051ac4bd92da384531a0348e35caf8f9853eac34049ea0758218f231a87a6d71947e01ed5a317c255f94c3dd59263682be185dc4956b2eb6549f325eee8d7ac270407ca3b6d5c7eb0dbc3a5a6ec0ba94dd6a077552030c45cbb7480190013ef8bf82deed6887269fbad03a54091e3754b21cf14c121a18e123f248bbbd65e2113cc535e8290104739b03d6b659370920d488ac5238e0fc87b8cc87a8ee28bdbe877ee3eb28ddb369382b7490468ed9d5e0697698b704bf0327f659e5ae1f282d30055bb1ae4839c96c73b5403fd0b1c1bc63e3a895d7ffa161627cf08ce909bf604fe0d5f077917601803ff6f49ac831070163fb9747300251e7999b4fe764c04cacdea1c90be3b2172b827bb41dc07cbc41864a6e2b39120d7cb2e667932157ee5a064b330a4c0b742b9083c77b1eb51e4f40ad9a6ddd0bfbaf6168e620d25b25a24d915c3f6e382a4c0f15d9dd949d2d4b1b1ca4cdda397ba275f44b45516b21a614ae8052d2ce1adc0e30a97947c236ca5b6732bca12625615bc760177fd49283417285e5f14d12f648e8c89604609e22de3d4cc7dc178b5e0c13153d0bbd5b4e8c9b9a08262e10faa3039d9bd69bd5000b17fc591f574d08ef30f8cd5aacb88eeaa339829c307f0203f6460eda0cb41fa0f11179f1c40fb153a2e3ac6bf052068832d6766879500bfebf2bc64ca0c5c30bdfa4ebd0e9e682a2868386cf5ec39296a6c3883b7cdb51112bc439741f6a5f10e613ea114f0e14f5974f33b463f144365b5e64cc6892dc0672d4da4abb0de8d057082cb644acca95a473e58c2a85f87b89bbd5ec73528c654e72315686308eb8281e7a594bbe6b5f68381a20968920c0ffdbf9694af421764bd82f755e78a254c8deb9f7e34521fd9f2416551810663e9ffb30662700d78b831e2d44d2319ee539d57230a68dcc929e9b9921ad4f46cfef46805ff44fe4604253ec881482a462ad40ddf45d97f8191b3e20f1e01235daba715f7a8015179aa6586563bc6b5b3a2af8de950959be90e1d4ff3c54c6b4dd7ec8f16f73842966e3406f73a5aed03b74cb0810642569c69c77bfa0d753e79bd49b7efebba54b8d2aacafa4d5361bed108163594d4f43758c7a8284bbd98e84955a11f4d288389f423e0706706c957cb33f3dca24c1f85f8eef75faa223310aa0e7f93897fb8c91b2a06dc44c3ede517dba34315fda4596acef95c9f9009a0e9141f3920934a4448600e28f70ca941d36c3b5c4ab724c2d0d052fe0afe33ab0570eeb538376ec87a2cd92561c6a427ce542ee8ecf37833f99d4283a168d965815c4c62b43dc2cd90068e850a7dc0cf5754d9136243ce4b1c731863751f98162d8010895e64271d026208c4ca4858d152b5c083876cd12731dfeef1df28a52ed4158c5be81ea1ff6012e2f7ef44a317b4918940d05c301146c1cb4b60db0099449c94849eac135efe30abfdf441d8a62eaed71493c1846fe5ac0e6d16e6984bd5ffbe5fc1fecd9c9b394f9f0fff96386d3f1cee0cd3c6e2c77c86cba967f86617e5503c2011c2ac58843ee2f03e875026849de3db699f650c45981c9672b62f9c52f4fbb140f450f041d162e14d000bd82786fb3a8f34915365ec212fe1eff1f4d781bf40c75239e435404b505c2e91ed2a34917a2ccbf21bacda60aede75022ab09437c6ca9d2a97b561ab083adcfe8394f306e071279c97e0bf04781881ed13fcd8b2057619c8f49c53fe305a5c3025461278334148bfc9234f0dab0a336274f6aec315adf91bf0e0a3ef77ef5fcf74e6e34383512987d51fa0e178faf5fc7c4d554d53b8e800066c796b3061a4cfc6e3f8b2f76a5d066770f5b5ae819c435452f72b1f6894184fd241133fb1fba788fc03e8767bc9faf42500b44ba02b1a41860c049a9e11660be1b1fdc11f490dbbbb8ce17c04f4b75dda5a25c77c60d1372cf202828d4d00ba8333066f244a155f22f3e6d954eff0c863c921a4c92a56563f0b282021f10e47682551883737a2f341148e54c44eb88831992579af30cf12e78dbbd14c942615d59051d3336ebcbd5a26fa58a48f4dfe1743a5cef32e6b58ee6c723a4ddb6c9db978847e7d491006701186d807e60eb5b0e8d5895fe74be6427d9a85b86eea25a8530755fafa5fa1b7b2d87c103099f05414d01585a2730d584eb7a78aea6b9e2b1e85b1624af1222669040a28ef04945c7734cc4ff8239dcf4ec9dec873e2969abcaf486bba42adaed9764ca80bfbd22bdaf9e56744e735bce12a7db9505e0589eac39b8cd8349b90ceb2e95343dd91e6ea9e98736150dbbe337c15308cc9e4867723172c122600518f2c7975a365215832c2320b88479fc3e4a9d70cb5284553bd6e8027e62ba7514e7d125a370ca932ae40e0f8e011ce0db5e4bf402ec03fe0626804c3a9c0979ed94d096dc203404a990781df2e4ada719ab671a2a9feb6294385c1d470bcc39ac1327ad55a46163cce2652b3c40daed94e6dfcfa34f51b12db03a901f7eecdf3d3571b6fb22a39684ece106592ac6adcaa755a7cc28a20a22656547b84b52b24ffd12bd8771ef5706b36ecff20180dd900a201dba17627f6443c617bd9c3ce2b15d8b2db6c24191064a33ee8cf5080a042c09f167b29f9ed189fcad805236bbfdf01affdd6e441aef6cef2ec69996464959f4964e051fe80b18281e26370b635d015a636190fb9973aa837b2143c0bf0ba2fd389dd7713b5fdd377ec4d05dd623a039b207c8d36677e3cde7a49b4589d7d88c81e9b6cda23c33fdc0d440c6559fb1cd4856f1735b8a5cb83205b0bd10035caeb5fc442a6c4102dbdee3df092b8ff744f7fd32eafd74103236ba219d8111d2207e05b65960c94a3a29628f13fb2244b7c6ac73958ce8be3c0e6a7674462ac2c43dc4624c2f2b3981e9f75dd4551ecb64e2ac24d765fa1208d5dfe3102db5c8c755468b5ce4c0e041439297611073f8a5044d9dc35a17c54ad288e87ec1bc5a1d146190a69e8532c868d7fad6cccc5d21fd074351af014214343b70543d60130ca5bc75ce3d9899038d6ee5bcf2167e9623444fe069875f80189f88923e9861bbb3a03cc6274c3e8e4c03552ba9c7aedcba3a9714ac5ba5536fa239d062b5417687e4419f50cecc6bceec25719e051a49b1ed345ee577740ca322fc8e72addf9ada7737852a920f1ccb5a1e1049679dee3474cdd0a2fc71234c1532e6373baf901224f478db5162a547d2b36eabd60a13070dfdaff50e02c5c099097e6f2e0da707a343fbfc847b96c2d4cf108712ca65c0c29b127504d3f287590d0a433eebffeb618d526483380b49bcb350fbd74dfefb8761d1b78c555e16d89fcb98f7465bce4f1494ab914453edd12df1c1f48e1018de49e7118e97385d89fe7099c04d4339f92e11f929f68fcb33cff58f322ac0a768e74053ba634feb4dafa2701bcbb1231f4c486a5b9be572705daf0cc5e5fb331f2336debb1c0131f774aaa9cdb127592e0fcc7548fd31bfcaa5664eec597ee9ca2501580aff4430de00df635900f43a9d6376166e7fdf8fdbfea0b46127fbbd700a1eb9cd6a550c2c7e4c896379ee88f353deee631042791edee331757f6f2f6e7229acf1884d1342633479b17823980403c9b4847c58acb01e2eb26f85491dc9f20944c11b9049e6e8d4b38309bb2e59b142255dc1142d4cf0cb643e04ef9d9c736e4295482e216ee898d3aec18a9d2db3b05de757f2ad8c80dd68b96fe7f3e831f2d1f508144a26899a7c11c9214e6ae25ed579f1b341c4e8b80f8cdd6b3d4af9614c00b6328f3c70d6625ee8b9ab68ea8fde9a75b7a8e4973a76afa6debdbfd6386f3bb60644e1d212484d7ac5b0dd3a5b497c5001f9e247dd117ed00f2a299ec16131526664c0808607b210170302ac9feb33396d2661eb1fe674677dd891ddd6c6d949631a205e3431236f5942dd3578a935e5baed066d0ed809e64a50ffcaf677e74af5c62d6a3175cf9cd1828f133a5b82c71c5276fe6dcc5c5466b1d29cd418c4dc70f9e62bb644f63e3570154dcfd9dedee622031ffe429b7109cb6224deb83b30d88328065285964f81b454d85e69fbadcd7e914c5cc692c30235a4bd7a6d238c9dfa115a717cb3a65eae700c7a6725e2c7a783623b8bc2bfddb1eeb3113b88c7ae1c20f618581fb3f4427cd29150c8ebe708462e8477c682e44a3fba821d6e0633a74fdcd111a86c6a4e63c118dd105e93f7219a4a77c7aa2235159fe6e90a3c4517b8aa9f971ad316e01964a38c3770b340191525ae1bd9d8629e22ce05334ec89419e0cb6c4d50020a0b2a942bdb63ff945573014f72fc60a5d09af547622070465361206b8c95b098db4093420d603518bb3b43c2fb86a4178c62076013f4420391ed6a2e3819022b254322f0c529bbec6c36300254280783d8e76d90881a3b2a2b738187b9c868af98432210fd8d5674a7c15fa57fa0a5ab259330b9859ddf85484f42100445b04ba3170dc9c6aef7432c5f95b1600bc82313d63cc5632c4ea26acfdb5dfb54f54b4c6fcc91a668b4293b10420b2ced509aa0572c61224a6261a6a57c79128140eed4c06db9ea822dc35a4ea8a266a9c40913d90b2d7466a42d347f04ca8a066cf15d2ec8373f516a45c9ed269a264344b3893d8a048367abaab3d00ed35316e4770c7c3495883879130540ea1a62a71c1f35ba6bc27acfee0071a82126ce5efc3afcea7dd0b7789f19712ff96854c9efa9155a967a20fc44687063f199774d2ecbd67ea4792e6e36efa4d6b9206156507ac20a0131d53f6abdb9585316c02baba664205479fa9159b3ef7b4ad736c38b738638c26a0c8524eed03e1ca4034f338118556374e9b66768f113db55cfb51a3f2208a2e6c441f0799e59d04148a696ce2bd72f094fc289cd01c3eeeb5508379b7d7f93f654ff771bfbebdfe30d5c715e05ef982842701b5ab3c65a2126d9ffeb5cc659f06650edacfe3f75e436a39877e9f13cf942957b4a640c86d05c8bd9cf77e3f3ffd63b4030515bc3d3f9104b4d2a51fd404031d3cdb3a8c85f39c4640a70aca22ee17d62e59c0aaaf0b0211a4a3c38162ca7a05063198a3fc8e3fb08946976051f957859cebf0646fb887d7a6940a355059cf59453a46d55419778216c69642a0e105e39fbb1f3eb1c244ac16e6737c44b92bc594e63a4c1eae2f9ca1aad27fd309a7ae9947a0e6cb10c98dd66996c43c0bfde3c9cc5d2a63896167cf4e9bc3c840c8af3256db67cb8f20ce9470cb9d08a0cc3008c69c44742c36ec836ac0060d8ae3230d41854098718112a7926e4f25e07da4875be25efc9cab0d3272e838708e2dfb79771ddd3aa845f1426679343f44fbc681e2d95e882d39540ad100c110b5b5420cfc0cbaadd5d1f86054b6a28ae6bc5dc6d37935213174839088f97317b6a385dcea20d02402ae74bcf34fed520adfa759161b1f532dd3082fa616f3adfef5c88cec1508cc5b11e83fe44d309ed3a0f93d940e09611bd268f6c3359e3b5befc066a76d9b584b98bac768a4681989cf6c5c78eb0ef116c61f275f71f6689d76d1df5a05e8b65fa9de9ecdcfc28ec2b30141ab5c3d26c948169cfe6f0fd1018da104a2af73cc489e299a0b6c5a3b1371af5b24fbb969ef7d89b4465cd9d30a14d4dc3259deddb233bf38fb980c455dbe37ae62af87baaae5258dc834664fec7e23fd6ac28118ff271eb111252e840b2083f4f5c4052b4a6a1a524196d3e6f6a1c86b575df750a27a17e5db1f70514e70ac72d228ba67ad52abfba8991191679a004581873dade8004c0da18b42d1548e46346b0cc4039ad663bd60a60cc20c216ec47e257f4a48bcdd731d8cc370e5293f47d8d494cf7493bfaa7bedafc8f02fd4047cb43d1e1118d75c4d25510c460c7ef8a2ea85eb5131eb73a9dcc9ba4c4ae8d5156fa1b1e7f2725124a754412378910b68bce6b3677cc6acac8001e5a5aa37f64ee7943bd88befd11f40690fc9c5aa297d50fb988fc11737330b2b8ffb0f8e859b014654c929a97b0257442ee2c68db4de366f06f1d9f1457b98ae233cec93eb7d77a98e79c0873b0ed82f841a4df935d28f7f1fcd1d2d8b66e644d44788db99705104ca0548bd8f99ed17708ca44b8c1dda5a8b750e09ff03a146c8504a186a0b04366ae2d1280bc2273bc395fd48a7facb9578cc62875fbb8988c2950b9cd6842069d7ddfa5699660a7b0ac1edfa9e00b141edfeadaa35551fb1abdada0e6aac8b857a94af67337eabbbdaf57591d3edebd16d8ab07800306217db299434193a111447640647ad578f4641369aa5e8b77f2f504c23f2b2277339e136f623ca6ea01cd553d94956784f0c484468e254689814b7529b8e7122b9fc4053913c572e3a6ea9181764c9d3d4054507130a4ebf78f96c6845cd749f4a586cffdb3979c3a872568a456689db07b75f75293a863107fd44f69018ea96335dd3efb96cd9fdc706d870f875cbc364ea4e56a43198c5cf57489da9b0dd433f04a1586cd0db6642150db567db7fc340b52824e46dcbf7123d4f8a4df5efb7d8ccab7b63fd84083c8cd05c46df6f77dc3d2be2d111806a733c6089dae57cb93559d8703ebcbf65708a05b249956ba8820e8a3ad3fdb53873efb51d09ed4c6dc498320e221c748cf4ea1a8a56c6a68b76fa8187a2fc475d6330b33fddddc05569dc54e3b6663a232aa74600ba267e5d90c0213989e04a8d4b3f662f3f230ef1c0901c4b6d283448e8b3d9659e7c128fc9723b179537c91d5529973262a50b757a4398fe038034b31345dace4dac0e59a29f8682b6c74e2606d06df0b48e0c3b5821a28d69fb217e5e88a0d0cb0f2b8b65810aeb5337e23244c4709b365a0b6b1ae5acef12872579315ad1a423a0ee1d7819e6c9d3ac18eb44aed9263a9b2973de0ea5f9d36e81fcc22c70bddc290114538eb4123c98c29db18cf89f16875dcaf8bee92a7942f30d6c377bbe5d192aa8257485c80f5ce77a97d058f938673bc824ae8525fa4ce396e152d890137d8c0369468b034f4ef18aedddc6dbc84a5a59d600720c8a13c00e97c2a79370793a10406f2102b41285d9ce0356f512dad7a52c9ed9c989d3f280f905739b8faae0d0d3c3758cf9dd2148fad0f50e112eb440492250a554a521008a5e97d7191f89e321b1ab4d662de41ecf3f77ddd5f9afe0e01a744be0e5e37df00ce9ce9324b4b1967c31c8e37b2b9a83b5cbd3bf36942ccbd677513e2545cff779fa156901e680dac9c2ed5491e5f9fde79e88415e363d5b2b14ade0502378b27ad428a9a8b8a15898a3146b886368243eb2639b3c1a0394d60dcc8ca58c641db3b5f272ec472f17d56a322b377414601feb4a0db1802aa2b0d2b691fc9f0816dcaf8f8d05617f38c140aa56d86710b5f2e756545d1a7c9aa69b41a9ba82a73e559ff224938b5255f319b3cc9999e2e12b703bb1e47918ec26c32ae2a2d31e45525615845a310a2e80d216e835c3fd1daedff4ca82b19bdae394559aed8f95777f2a235905af5aef0f37cb9f0bd962ad8a466584032a65e0c0ba17dc8a93ac5ae5615e86cfd59d294856f34b9ff0dab0c89951fd30e0a1d8bf3542ea929f0cf57fe1df417a2d2ac4f1567d53e4266fb6af48f7f71d153d317ef10da7beae53118dbeaa5894f09a99d0e92bf8681ebdb0cdf5e7b601d85e2ee6910f611b497f4a25b0d441ab7811d6c4ed5b5a312ed072667a8ea74cbeca48459c784f67eb1e8fed367b3aebd90b9a51afda21d0815b4f672e4e896700b7c1301d70de9733cb8f5942f9aae7a04da524fbe12f589371f4127e46af320dab2c40ce401d3db5850075e675103640a6395c802e0b9b465d320f73ed30d5695217b3f82915fd4d9cfc651f7458608df652de6dd73ee5c7e5b0a9ebd6446574b89859b545965f2cab0572b64f1dd63a92f13f278861e664b1b25ab355d0a9dada38f685d7c24a3b2fab15c426c1203646bcae29dd6d4668057413a9333a51b606bccde752e4fd22da64112a1e971b9657bff784650dcf2a8344a964547e5090d88236d6452ea0d4d9efa291d2fac8eed0e639ccc26a3fc6074d9001c3fd1dffdbb7d69a1426f738068f17b0a760c3bda0257943aa07adcc15bc6853ca02aa8a0244b728720dfefb095076331e086503ef6e7713d7f79f74f7c53cf52a97bc82dc01d2b3b5e84851bbcd1624def28bbe4d8ce66c0dea2bf0e2a94ca6530b8334ca6b50b24fc66be782dbeb9c92ac66ec2809295eb5f07c551693846aacc6ad5079ac1a997c0d4ecf1797074466d4b85ad5bc69464cea9aaa1d87baef0deaaffa986bb3cf065ad89ac728402dbf2f3ed3f3eb0b3267cf91f5d9b84dd3c9a4d39974f3c618bd99287e1c6f7bd10fb5fa34f6aa9c44738207f92fcd3c1f1b99c6a485af65a90f947925fb09f05bae30f1c1587d20c8445509f04591972c8d240e09b98a8dc5ec5e0a987ae2253e0d7240cc3a9242493316bcad43ceb399d30ab93484ca4d2c9eaeda68d47fbd77874ff34aafd644045f5bc54b5cf697865c8e1c3bc3da082e3467c8d821884d768bc0232f6b19c17c9e80106a5d39748aa8a2d8e0bfd0a0c30f3e5cb92eba9861822960d8dd149b97d2ae71ba8ee19d945d8d31f34efed58f87068afaa1a768b7a2a2739eff0381b781e106d436938bac0cb08a818d4b4fb71c24cc4a741b6c06d4d57ea1943322ca3ab8b52ebebcb94ee50eb4354531af41b0bc3c754e7bc27652fed2a6e92af5295d7604e314ec06cca2791fc114eed3529d65b6fa6ff548c8a5c7b15c4b5ed90df8dadc266f9845aa79498b772ae9ef2d9e0554753559d9e65b76bb7767c54231c83312ed68f199ea2cacb765a7bae9a87a4e97ca4889038dd22e2e5b3f8b52328dbc6c8feb4a0a304c5e4724c6226448d47022483313a6508077a573c72775fe1e5a8f2ae428165cb5b8fda2d0ce0bcc4d21ec5fab42fd692c473228ac0709ee58198e2fc3401bc7b00df778e9d7a01ee11b7fdb62cb9d2df005634d7a9a97f783b0628221eb1702a417932f6853419bfe83e855c71c1f48665e0d0f84394e554a10fcf87856087616ba00456306058f171981cfe52a771e2fa615de05a01cf6951bd7af47ade31d5d7e4ce84137b69aad6d0418b0a5e3afe4bbda6af560eef0f286c1d3d2303c120a4c36e3ec9e14648768abcdd1ea0dc30ec44149b185a1ff2608c38ef3f16774adedded089977d1a88078e05345e47cd144347b06667bce98ef45a80693c8d3489283d1d5dc74f99d0891039bd7cb8283f9f1d0e4ef5100caeac014485cbadc3f1eb97fab715effc31a38c065f376c254fa36960804a466ab7e58c1949f54fa91035347737ca74e4cef80e9d8f346eb140c389552e6265177d4fe6201585f3acc5db8882819368c1344d245145de6615a6e385aa3dc41965ae1f70f212e80550d1e59a5c010772866a602a07261195770e9b2cad7f89ef6fae59bea77a14997a8da580402a5a81506fa70e97adf029e7679835051138da0050f1019c987a6929c801312fc5f0d1d0223e4fb7c91b3f36f34804a6bf33140466b323e0d503a14e640ec2c2c0414508001e88375e84c7c925a972340eeba4c94b8f2e7d4ed777c61d0495b36bc5d70920e3ac8999dbf283a32e415632ea925cb1fe06ca528c1f39b0bd823cd1a86ee7de001d677c6aa70bd32cce9d7eea1abe3cd9cee020e8a2a5ccaad8a3c663b60179296e3c73a0b6b7a985b5d45d3586ff9f0ae2ca8a16cb518c4e9aec80b9e27197a2beaa968597e2640ce308d5481fc9d63b0bfaaf069f588a7df1e770c538370c8b1ab6cfc4e8514c7b5a8d85bf4fee0b510ff6bc115c030a18c5417ade1351b72d87274f02283e20dd140ec777e72673847310886909db39eb96b26c5471d6d4b95bb743c7004307767c250e787740fd0b7600846c166540ff972eddac541caf65c0b5c1240b467b1a736fb84f8e8cc251744a8b480f74c0de04f556fcdef97d9f46272e44d6914c7440da1bbaa0b7cb829bc4d86a0bfa1c3f70f5b5e0b6b3032417295ef0e003ed0f85d253819fc5915a9c460c147e712bbefad63ccbd18081f65796eab73490f01b3896d9f04b8e2e409debb34c0a11a53b541ce6629f2e138688d024653adc58391654ecb409093a0eedf25af47357b69433edcccb79acd9b0416f82e693517328e586a6dd66fc9922beab1b7dae5570af293226216009bbbf9628299da1a077637ed958d4c0fdf45f452bb387b6d935fc3761958335c750b37ba8a77eea54e0ec43544361163b6e18616c922ce1ca31b69728f84f13216545ab570d4db02fb1b61cdd89f1fcc69fe90fa47872e48dc4fe1d603b46df4576861dbf50697368982738291296f80d4c0ad1ee04975662c5b7b19fc31818ad1a96e58a3c933b4134ef48b1444d4b188e50f8f142eb41b24eb9433fedb9dbd8ac7196d5f261c818fcc342f7214379639db9d4ba05f345d2caabf98d1e1fa2821618d283d1cb81d206da899240c9aa11de0ef5e8f37ae778896275a2bab96e5433ebcfd80c46cdc95a31b5aae9ec48c6a50b7d7f6413f6710e718c7c654301908319842af92aed4ab752edf405d6b09afa44283df755a571907f725196fa9bc456dd191394e4df5317f22b046bae399f3584ff372201808d503cb527d00eb45df3c9c1e52f3a1052fd3a896df7c596b0124ab93009f9775289a5100acf3e4e0c7bb0f2b35b0e4686258cf3bbae5d5cb20b05a9e56fee4727783bde794858c5e0b806f260a540a280d9aa3983abac078692accc462119b54e8f032d9e784100271b15a599a011b8efeaa3abe376d299fd3010cc29e164a5e46e7cd313fd23baa43e1c9bfd9c6a95a174848664e623a42f4b6d0bc357c891e645c82ab5f2d30473c78779b42151b90c1769ad1733405a7b375cec49c39f49f52257b7435ac764670874ea57fdeea7f699b14a3f5b919c1c4d60ad7eb4d996fcdb6a5727df522878f63bbb2f220f153f7d2d4ebfcaaaa6f1717173dbc1ba04d88e5a1f179b341ad64c391fe718ceaf108244f4c85c84e25bed2b642405eeae7c0e8e1659dce9eb1a40d6bf828ca6f672f18c3e34df49014911a64be38060638b3ecde383bff3fff3f12ace7ab0cfce3b63599a3b3eb9d58a562644d7042335703fafb157987e39d1bbcb7300aff0c6607484fe3bd524a9311b1354b30fde626924248cafe60437820dfa5d370a560137f20305ca699e4509ff88aa94224f70e890d2b3f8d1dc1a43b5d17d2525e5a917bba179613750a6d7f359145732a752a7b0a1a417af37d335a20536af36b871abedd7d7e13c96be1dd8ce0a052d50d6322eccdb2555990421a8df3da2a60049635880358916369036d147ffe4469b8108394f1314ef169c40201a7802eeb2d47ac3392b828616953870982518a22cbede39bd309a56b0abc6b92c0d0fc6acc29d9313a53bbd3a2a29f64627e342c46a7c9c184a727692e4402163902923d3729f637f6a50b01fc14587d325a94459a725fca9ff39b9a0b16bc97a449def42f5de0ecf188a4233fa6089ee1a46913f0ecd1f26a5755332bdb31cdc9be2e41ba99527a64f630b1c81c8ddc6269e7016a25d22d13227b76ba9b20b9a9ae1927b2e0ffdf1021e402223d6bfdaa4a13f9344150d735e6984698873f12b21ca78ebc343d901c354fe6e8f4d30063ede4c8913e1db2bfdcc4be36ef3aa5365ea6a8e94d675466bfbbb5c22ccd700cfb05bdbbaa46df3514f580d94ed39116f23edab34b3e35d74741fce76a23e43f849d5cb7cc11391371c694321b1dc76d8c0b26d1c34fb79ed5289219be2d8e9e5c4fad774b913117b0a2c22162997baa0b88e74fd72836a02464be5b9b1247e8eea42595264ab0806001aca7b9d020ae8f8d6bf9297bfa2e7189871052a74ff70ae57cdb0e401a7b1885b62c94d6a9358eab19bd3853172bdafb808b352c34154e227ed80093743d2866ad0c551d1aa479e2439e512e684189c096a73fb11a05e78eb697531a48fc8c437a71a3d3e2dc93159686bc511099e3e5223a6a4e5897f9e328d922b81bb5d8a05ca0d587c8c54ae01f0458b37c26016554349668b5105c59031ed1f753956587751edcadd9634d47c6a52c536f2a99fd017923b204304a9594c55acf962342c71b2ac8a18ecc42dee95465105d2d87aa292fdff674620fe97f8072e148976b6da9eaf87d8d3fdeead52cc29896613c8fa26f78522d19e5c118cba3544723033a47e2d5a82658642f7ca519506bf18bdee5ccd57ccaddf639bef35bc5b5b7a9d6d6a37de8081e209f94b9b0e421d8deb225f922c050c360af72e839686361029918f7efa65038ecd5f427d7e64356ed068f547797559619b4f644ed124185dc0ba71f2b910920da2938d35d05bfbd82b8b4bf5d6e39ea8c3b7398e8b1da0d22382f0194bd927638a0d66c1519919e668fc080db26cec7b5f75fdbafec2f13ef65ee31fa92fdc3f517c78e91d8b7821e1fb41249d16439be5c65ec4fcfb8fec6fbdb8ab527cfc8bb683f9d8f1a20d97b076da891c2df7f3a990ad0902ee430d2eb40365b6218777110ce94f0c286c3eb1bf3a688c8d4364f538e5d39df7be4d02d6204bc69bc617be9da8024113cb1beb6d6f7edf620a192d62a476fd1ae6c05b1c59449e6c3a0d4db0fb5200c4ab5a939f93a968fdcae4a6d78c1fa8b19ef526a279a7d434d0a9bd43bbb516b58b241c7aafdd6113c3163523b69438e0bc98fc4482d1b2af8d9a3bd244d9daa85909448527f4045e5d2cd19e9858183e89cfa61006b3539853144abad485594591521c0dc23e330a0a39fee4c64d93f55b2466e8f0304f68ba2236cf883d5819e79376a7224c36b09eb475029eb47526d05a99f463b8a3d06e912cc120e57e06ea3a941edf0749dcd04511f411a258cc9d2f052863d2120c2fea51937637ab5b935444bdc891e652425cdfc0912716cb38a400b50ebe094bc48302a621b356e3960b83ce5da2185e99d6f41b68b5921ba97d6121006b220883296fe42b58434a099634824123ad6c4422a34d01e7a01f9ce6748a0111cdcd218d3c9541526eb38621dc1a1c81e01cf2ce7ffc84c285f92aded1fd96d5220e27941afe92db54c7309a84283b4b2d648c101ffdead1982ab1cd72dea2712bb8961476585f847c215dc6fc6a25bb85355c8d53f56487d3412f5f052fa06ca3faa66542794f1cbe44505f43347f193669faeffe5a06464076a118348a995b692c9e4bceedfa7db4c79303639132f3e427981c6c77cde166867efb42eb1dd82891031549cdc0ee00a18832a35b6223d45b4a8c2058ffa1e3a22d3abe0371b5152a4d16bdde27bbe1150d72f048f687922e26a7e16bc2bb73318881d27405785d3997e1e471c5bc49b35505567b54c504651f71fe8d8874474f528efd7945d54c45cc47871a0648a09230ac6cbc4ba63ff550c07611da874f22f875c2e1e20baf63424a0d6ee2d2a7ed1e4ddb1a16b7d2630a12c03512e4d548500fcd6a6ccdc66b18651b4fee776a9a1b3398d4da6b41e54dc3f358a69fed8c0612c375130e5b6d5ec57d733e161c6ec5ba7dbc1d4a62f73e1fa4248a1060edb78976a0f5c71c984ec0995d9a749c59a8bd418c96de53c8212e17e5117423e3d7d207d94558fe530e533b0f8d446247e18b4afc52306751ab61f8a85e692798c0398303980e9f6f9906ed5652e8d28c078db1b2b18a43d8e12e2b97413a828e449592ff31fade7ae8af1f010bc87b96b6023cc25dea4c47339ef8a7104c78d2c8068c1d74a590d0b47e2a138a004668efdb0a7b5c2608048c61aba3b40bcab0eb827d8ed0b6fc6524774005a3d5d325ec977a214f63d494ae0b93e9e3826a98416a7a0f9214e731e621a5bf585abea16098ab80bb0a89e80097b90c90950f58810f8713b3504a55923425de570428092ebd03ae242b4a3585d6edc9f88974633e3dc7c381559827133f14ba1d29ccf9b3dd48fa79d74e336afb4c790dec0e7d72b2fbd5c464f8173eea39be8c656d457946808c50022c24ff23e3a6286a1bd9b49f7f4f77f71762309e100edcca452b8938692930bc3e89149fc23ff7271b8d27135e14d54de4d60baccf24c8f3cd28f3cd4cc3de3f633eaffe33ac161bc6a374587a8110c3ff04a5209813a11b219b6ee444d0bc42375aceb8357b32f357203a2e56cbd07c6c99ac4f40ace09409e1bfaff1afd4a5bf85852a8a19c048b6d184d1188bff94a15f08554ea0c45f905accc386eaccd7cb3012136834d5fea886ce1baadf1ea4c769b4359e187e285ea4e0a5c45607d05b6e5d4dc0856397ed077faa9dc0b2e58354348b8d79c137d66c46fd2c6b7d5af27ef0cd794d7cc7a71c09f082c654825b686b19b7544d719ca7d18dd848a3c58857ffca239c4136150babdd93af2696ffcf2a5b5f61429978e3f1c8ad659185372bd3c820cdecbf21781ce012c417696120951ea2853d148d9a52982bbe1e267cdf6b4696884f239bee7aa2a774e20fa66870f3b04ce64c6fed3593aba7a205f6e20de3f98fb9c16c1eea9fdf9a95e090c2041b3c459d8f6e1633b155ea310e5d0d7e1c6f6d2fdc1fe0f398142a849ab1f49bcc7519d7205ab79b9e652f93a2b3d39de9815e6e298d73de5dc7b441b440f7cb262bd647cba3224422d2476bf4f8816c7b55420a185a34a46e71ffb713dca8508b3295bfe80ce716ac20a2170dba08683f628ee871953eee5680f9e1e5acdcc53c9b8a5b42f820a614359f9588339d436f6600a32006a64893fbf341ec4bcf1203f3e9389b8f25bdb581486db59533980f558a9e8ed46798bf886c71816a42908cb82f741072d0e9c4fbbb5bfd3406884024fc0d70fda0aca15ed502c24ce8ef80a291c14869a8e8ff1ae2f636d4ba85b1276a786ca844894fe02463565304d75342e85f0ae9e79421c4005ceb489919f20a97eed62f8b531e787fb2964457cbf4855c9dfb2f5982b4c52b6bc8d09e90f4a62b3d886762ab5b0de520a2ec2c4a714c3fb826d12c8bb844cecb86c43f1d12b51462fbf72e7814f062099efb619f0d85d4b8840c4e3ad7eb0a6ae941c72da99e02e297411bdc09cbcd6d4432db417638bd7df51cf2f5d69c76f6f38bedd167a9a90c276d79332486dbd3231d46f6f6ccbd68b9bdad9014ab0acd28f038039e30f603421c2fa93a105eb91aaf4bf085c8acb1c73fa42ab4b11fae20c7f6386c2deb2999d61b7aab06719b352079d7a061649cc41cfe1a4cb7ce0bbd9c8740e184e4b578e34c0850181fadab10e9f17e598715225b96d18003993f9e724a352112453ea614799d5a64cb564c39ff9997507f9456ac1c1bfb8f35ffae2cdc423e608bfb33ed57d2a20e91301c727a5aab6da12f878b2e5150b215a3bcf358f1e74c502ca4cfd26f0300bef5946b395bea97231d0b0f0611246c182d1578e6168b8c5e71820c404e61af03648084bf9e95d9a808e81032b89d9625e64e9ad69c0abe67078c4a92ef5384537fcc0d8bb7ef4d7c2d86183960d03419fc0d87f5c12ca15a859d02283094cb910fc345d361f7f62ed4d1c51b40fd915f1a04fef9f141ce81b706a4535bbff64acd7162b7d348cc6fd85511afa2f77a819232265f57ff40fdea1f0056b76f8135c3431464508b708ed732c61b83ec848ee1a0afe0aa1b780fe9c9afeacc8ad06b9a3e7de051671281fe011a662d800f2515fc59fd9630925844854c04ebc08a3fad90addbbd905a443eeca3455f1525667f721532ba5ac8f976170e8b3e324b9629a274afe56e9a8d60da3d4a4273154c5b88452e045326c4797766337c6505eadb41deaab120175a624b33a12cc1b0028b1617066f801d3004144345418be5769a09b59d14e19e2d9a071a3e10ecb7fbc2baf77f308c8a3a035f6886a888090b06af16fa1d2af1f403ff6c43a58791a0590dbfbd431565e12df48fe146ed4c74a45365c2bd3c68d24ca0e15fd9bf1154d863dfd164af042cf20f01a3468d89e4381f4b8b11b9bf548c29963c578d5c50393958a74b013bf40c94314c53c09fb3af4e6e82859a8ff51c0bba460a070a09ba591c41f12975b8822e6f3c532fb8b801fe1d001497a0209938bee132816f89d7b0ab86fbd9183e7edf7cb6f72645b8a8ac99f5a670139a0db935d11b378652202f8895b7999a1a31be8a5bbc710a5bd2f9cd06422837abf8a2754650257b4043ccb7f6b985390a976e8548c59475e3504fea7b3c810b294ad7b66ea5adc86de6b2824b9f9c5eb62876e9cec35f78b216fe2b14c4a46c6de04dc5aa515ce848a97f154a213d8b67f6421fa6144f43006b694a582b33c9541b6bc50354f4d2f5d20796328bb476ef1f05d52140c02872664d0d37f295870cf62043192c7ecc19bd31be0c5190266d05e67105292892d644d71fbe2bddf55fade78b561b10ea6f06c6df9fb8403383e512541890e3b1c6b75914b82b13312c8e0a157d077c1870486d42373fa474014ef08ff82cc23520d0a0c1cdc8490b0d5e85c8869008c55e40ca2ca22cd9ea5bb032531cd1f060040e3cf0a1d24ee869942892ec88764952401b903f47da9d4ab80f165ee7d4088823b47b52afab1cf97afe232e40381a548a06926e1e7ac00628e23d3504845754bb91cc40566190d7a605d357eec30a46e6b0cbd8da8654b46d00c649036bee536bc1b32c2154d2c9b52de144ae3c22b64c679f62110c15a7387dc20fa3a65740ef04b57748e36bd325ccceddf654918d88882f9facd83d6a4135d5deea5299cba12d4e74b11e07000548ac69fba018eb570b397b7b9203c52833064df6b650701136082601abe17348a2beaebc87f654d0d44fc5c2bc8e8f900d6881e5a17125d7f5ebbaa33e10a36e6a535da342db94d0192239d495be7cdaeea2c73e020dea5950102f4511a05dc31fe42b1b20882bc9cb819f8aba4049673318315a487ec01c95d221bebd0c3e699959b431c5b9742a4939a9652a1466d90653dd6032604f3acee5d036a527622ae7d5018d662e136e57d749ecd4a305b8a2d7467709d7d578aeb0235e415f28e97fb78a5ca12d17227ab78c08a9ce1faeb9849af877e88daee53af6f36f3f2fd25a6f50bfc425efa67562f0526d18ed756c4513d1da31200a590522e9aa4c975cb882a8c247dd9216ee78ffacd265181f72069366c2f923b12ba7631f3334b72e6874630695fda98b1a43231e52eab77803af24cee11448725aa1bc710217a430203fbfd735c2db2c65a3ee6cc3361b58c213984a8e16d5a791556644d815f9c42afa1f1b378f9c1b803e4a7eee15e0fbef9594ab8ca0f3590230a4eb93cac6c198f36bcbf15da2eb2a9f7e423934fddf6618e806eb50c67244c15cb5779a824a5ca31c6d01b6f42c54012b6b504d1b789e62f93ea79164a0be6aa89b3654d38196272e657475577efe9f73af614148b02877684dac8d9055911d5e53cb4b1d686a9829292f359bd190c1df0d9aacbae2de16ba1920fa2e41ec196a30ce19dd28e65746d4005fb1784e014a140e53b9496d8b1528a5c7639171bbbc61c48f6742a86207faec7e0e83757597501b96d4279a7c99b11503f19097f64aff991427f9e31fa7fc72a2012e969bcb936b2395e2dd8a6a45ff4a76a634590b7a0f50a6a8033d49006a8c2216eefe467768dafb041dde072658554379b65c54c29656b9abeaaea69a1b47e8252742ac17417036c72d2a93620dbbff18000050d1c5e945408068ac9d14592f6afd4e3328383408fca64a2d24b91d51952aa2e606a198e8bd241638534239adbcc96254547d434d770725155aba3805d68f212a23653b42e9f0fb5e648a3f3768c99a9fb1bfd72e8415d0f48ce39ec16f7580d4a6c969f318adf92f46810bbc3dfa2fc200e5dd418a179a2463f118a193660f2533bdf92c1cd2644e879482e573e14cc98e6537d803d993f97de1728c1e86732f2fb793d05039015d2ccdca45ae3f4163655ff8f0524acfc4df7be1bad93b12646a7ccca54f2e8c8fa9af82ef642aaab4627b7b65d2ca04ea57a06dd53269428689caea80f7a4a43f938911848e760e7516b8f7b1fff104f100f31ec5131b6900448621096a86ebde0ef7a2c741df606d513d154bd8f16065a63bdc5677631790ef7fdbc1d3d0112b1d6ce3b2629d01eb43cece44bf42029e34d918fe38ca5878102c6b415951a135dc2cb0c43fb0364f0e318d69affd0603d6be0a81994795569c1b9b365315ed581b3e80f2a2f305701472562347ff69a02f9bb28b8c20e8615c3db4c45c216a6fc0ad65282e19eced417afff35ee91acb42569ce4168fcb5a1509425b8190f0106c80f9ad2f14b1ab1b059325d88d58dc901205f2d2272cdd235af3aa2b243d0fa96655ae9f4920bd48690c2d8a046445723c864270849c4f49f238a01002b7af979359c2e97e9a7f6794bbb7f3a1922562c4f2509939c5cf2bedbea10ac592b4f82e466147349217f5ba5422d11ee95b3e054bf819457d8ce5a3a62e3c42116912ce52b0008fd46cd47ea3db88bb0c7e90f803746eb5c502eb1053f31cf1dac23c5ec5e89bde85118e4148db77b60ab5fe48a5185ae436b79ce60eac3c7ec254c5a07896b0f310f69c73491a3de90182cca6aba4b023bf30597db95e77a6d776689ea11e06118c8b122e3d5e0c7a8f23176331b20f6f4407ca0e5d34692f7e935e60201cadd37c585d2ae41600dae324af30ac5bde1eb5167296e03ca98dcd2330c2a17dbc7ee582be1b8752721a0480881c059747ef38ae9bb8af7159e3419cf6c4b455ad28f7c4e228d8aa6204b196286476f60550dbfc85065f2acee855013c900a1c7fd8ee5d2f506ca5d9ba4a2f7f76c090a3e251708e152042e75a68f9eede1707ade9b6ac55af6bd2acc573801648ece99911e8691d68d32a6fab0377720878af4ec77ff505c2d564aaf572c7aa1bd20a1f0e5845e7a26054b0e234e4a93234eddce671567fb1a37a383ab237283abd16be6664559b24f1e8f8b94b38e4e077d988b25e257070e1a3d8f138dbafceb120e3a02909449c2bb5fa734fa49750df2d5c5038318ed5c087ad4119840083c8e615552c397c230c43bd63f51b1fa0e1d0aad88e4b226fc48ae204d3a5483fa35069411f5d6d3926eb092359c467bff1c6d723429d92d8cd8d2e238414515908e3821d138e2a3393cee3847c2e698ebd6e233e40288747810fe711e802a85e4da97d6a9374b3a55bc8be63af5ee14a41d356540bbf476be12e1997da32741ee58970208825fab8616914c5fd735aca50f498ffc0902fd73cba985903665eedd7ce58f41aecae1691d1085fb6a36614409ead1c6518aaf30fb0a623a1bcb51625cc4e1f1b914067f3566a99238ad76550974cdd8f5ccf91d4eb803ac7e54a9bbb3cfffeca55ae541c4607d299301f108534ed01145ddf37996b9cb0508c7f98a2d4c370f13d07bcde18757bf2a6301f264df02766a7aae205da860dddd80392b175e3d4733872b61d6336ac7866eca73842e44b78b725b792352ea0e4f00c33de7adf2387d09f64b0e5e8774ce920375f63231fb475f2916b96cb41a91148480fbc26777c5e145eaf30e7a9994e6c735ebf4d1207280c62a22d031dc0b76518e9c2eafa6d928ddcf7768e56c59164f2adba7100f702b786db0b35dffff0f55cfc747aead3080b7ebda988f1ecf6ecb1fb0914999d9716fd06eeb3450ba9e0e29768c75c10872abcc550753b765f21b79ce2074986829d00bac7f66de5e5facbaac78a96448af1b1aa6fdfe81ecfbaa944386271171611b06bc515b23374a101ca82507d1fef7bf82629121aaf63bf3dae68708b5f6277f8c4ea00c74de957eab1d1d0b838588ba8a5b689c8279fa0f4f5fab852e788a3673b98e2dfbf693ff1bddde40d27bb2abdb9a3a8ea1d38a00edc1658dbbef5819e07dcafe8227733ff94444b9ad17f14a7c260d765ac9d2b44e298238ec2dad8cddfa48df31664ded8da6e453932fc8f7cf0fc93159715fa5f896bd3e7f2d94bb8ea81c8cafee73bbf305038845a202b010e5481a433ec695d85fa37e3c784df4b918de60198e2464b8ac3c69b118299761d6fd8fdf1dcd168f5187a6c88fc5dc8b6fa00ca1a489380fb6680316311449913614a1a395e1bf9253dcb4945f650a12bd58426309ffe37daef46c9ba6413975772d028d2303535711200d447641f090e17ed09eab3d7a8936ba177d0bdeb03c9fca8b143b0bf1843f6976bfa9a9e75e54a27441c228300098dd813f1e235be9002a4fb89919037057e70c0a5d9d9596ae02363e15012898c29f76b8cd0ceda7ddc6351dcbdff9fa5f8f70499410ff977213c127a216cafbc15e65781918432b27240796498049b0fa02856c505682e719bde218e42de1deebed6b4180ba568e853d5c75243b809a5975ffd1a25a13750537b7cad2ca9ec66186249844279d9c7367161e6b60e5c4e9b4d235cee86bb0ee273efbbaab75ecd338e355ee27f0430465ec890f523037897b8c656c9cdc61450752afb36d62d216a0e76141532cbfc804cc08864e48740752fd806f82d047961d819809b65dc3609f175748e42ed4a781bd32c52785630a014088534fcfff73041f07ec9786a677a8a61398abcddde4bca66ef53b5c9f64acc90e09c539d652fc112df51391ab294d595951087e16c2888b226929b6ea2358ee9df521d15ded0fd28fe8cdc4b9cafb30a8ea09d9b054cbd8c293a307f4302b6eddc9605b84f5f55ebf4bc8426eece6eda85272e2df2e0debd82a9568417e171125bd25961080aa926925c494426188b292fb925dea23a7f60e09672e36898ab3095bb511ba3dea9a99c2db7869f12174ca35401c68202c2b4ba3ef1d1408785e4c4af5989ecf18d928da0e735d48444918ee967a0c2def32858ab71457313fd6ba89054601d9b92860673e3bd8f45eaab63c6b2f3c3c47a4213aa20326392f2f7696a231b6d8454b16b4e320eb810c8b91eb03a6d7832151ee14078462d4b5117e58c983c1faa1e4d5c6be28e52ffb4ef21dd6ac3f3b5d007a7855a4e2d350e09d7326aeea2f44f3ad551ee341a30717d62bad0b256aba852004b7ab1f1adc2e6d4cf100d247fc08e25235f87498c6e8a0b88feef2b2b90dfe109d1c1632743ba78c988d06a19be4fc4184b59e88763f14a0872de873742cdc02eeaca74f5f61b6a3db27da4d1684f612e9003dec740cda778a58fbd1bf923a726054d45977723b95649f49c9dc3a6d948a95aae0804a3db861dcb38fa1303814d16bb7ca6e7caa87d44d3adbdec6a8137bec0bf184a25245f1c803480bf604103afbac506b6a778bf840051942a561575483219c4a3b272b870d903754be3b5022190c403214fd4d5ed28340d6128f0d2ee92ca4c449d856cd237e342370dd222bb42edbc0bbcde61713410f1b7cd785d191a1cf41f55e98f8646cc5d1a85726f5908164542fb8fac8da90c442d32714947c525451cf34280cbd984958cd56e7a21728a21a449ab4f0b95ae546356838fb5b943f71ed7b1f5292959086c2a1696a58034e9626c60c00595c1f6f3b159968c582350a633ebf046ee5a6fd213279af396eb119ae0bb8f55a9448ff4ec166d4ef45bd24c6d06a06209a2dc0e94f3b80c06cdfe13883284126689aa977a972a1d549abd8536d9f8ea251b90880fe723f6780b2c23fb697effb88e1a8d507477d1df9afadaad711f1d5d79a933af6a2f0c3732ec195b51506190b4d498d4c8dbf9478a88ce800339ff275f6c5d32fdfd23154fce6f35dc8dbfcd06c2fb625f979436848f541bf638ff950fe3638300b2eaa7bead5011530c950b9bb5a155fcd72ab0eb1598b977c361c22bbfc1d62e94d107999dbcc0a96cce85110ef3a3f4616ae5d76088f4583b833df15e5dcb36e24e1e700770b14a219f88d4c7eeed04e8383af8435784e7c939b480df19c9474c050f3865188e9ab713712193b8d82406aee0ad683f72873254a61699018b5442ffae0e2a1b98b9eee396ffbf03921ed6a0d20b9ce5519e97dd84260ea9d91a87df9bdda7e9eea8d7469dd7a9665bf7bbb0c6f3c4cd82fedc308cd7e727dc81a8301361eefd4f07c65dc724bae473c93176d4412166c8ac7cd24120c9946b194681760b94dd0a936a8a66211075300d55701535014748b39ee16be240d4d0717f69ecb87072fdc998bdab0f85bbc608bf8b51a5abe3db96e19d8f5ffa8f4a4da39040ade342924bea84a2286585b2b2468fabc3ac11504ab3a74a5386148cc6f7819e35b14cf1fe023ceb90f82f6965ea9b273a66d7b0b23ecfe66e1c67ef51ab636574fc79f72b5b21893e4ebb1c02dc3e0bac46e4be9d5cf2788f01c1a5fdfec7868d0d805da5b3173c099a64f929dcece3f19c46e4fa9bcf24a5d0de10aef1a8a8895c24caaecaf5bc08d8ac7bf84c06444d9aa346933b09d0a3a6372a492d7384c848dd619e31d43221546323500df3091232f544d36dd30b1c616e1cc99a9fff54260b76667df36796065db55b9a8180b3c42b89d7a512125d70de6448d9f803a3cdb4cb59946814ab61a68c768b1950341b421d94c2d7342e2310654fa57e2cc2ca0d644bdd1a23391cdb13976ea996a4c3fe92029163523359702293968f5e2f4080b42fe2de55ab89dda0d558bd452e74eb361e75fa3b25f0d39121a4c8811f5dd0d2c162ddd9c06991517f6461e520e480c1a21284b0dc018b9cb6c9d35ec9c616d198bb7160d36d06c413b1849165142d72b72fe4055a7134d668bd57417424c024c8de8749931a46d7667614da81de1dab2f0f66536e31bbc2f9f015e5b1de2107fa8aa125db98febe01a24c7b950be9f5a4a76d49f511ba61fa64c0f31216480a73bf78c356062ef6a70adc0e0da4e44650f634358584d1aa2f458337406e871ea48b095a8ef6c5b5037110a42e285a562983e408b014a256c75bcd66ba9ee1e698f2a18331cd3fab7d8b20ba8a9e2be8e6d24588e31fd728eb3e160d402af69c65b17d7df59e1f2853c75d49c5d8771f645e7c16dea0cbe20733535ba5ceea92056801e9a3bb916917dca02a7e789cb11c1bb1a08217a2c97d1883a8790494e537b947cfdc6cf83c85d59a2dd72046fe27e58f28f946e86c3504b1432d180abafb4fa1d9f8a0d9503bcb39cd010b4cbadfd36d10dc43e751dd116c598c5a202ceb776f29b05e78c25aecb6889d159bdb443ec4e42b2b5e814b933352128014404e43c7410d8a66d0d518a6353983d3ea7fa07c67c1dc7cf0d7c35360ef3825cfd812a82c9b93dc3913922270795b15828c8dbc2e89349623193c21e94ba266cca839165c1c24cf128a8027c9deda6a64ee21410f69563ea449449bc54addd79d1eba7ca9d9fff73b5eea20898d6668fa431597cc3646ab9e836b61460109fb7f1c133f5639a37d0170696873189ddbc2a5e2a8b89ad09247c63e5822c77f9fb7daf1b7324725d8861095ad642074721e935329ce75f52f66b5c52f04c223af3b92834c53f90fe290e38c1715f8b0e4f08ce7c9000412ae882d4f5fbf56fd3e27dd3843cd4e5933ca3474ebe18b4e6b3ab1b05364b5a7bce13591fb22d35ddff69c1e9aa15a28ed866bb34dd62a21e263242468b9e1724d57473c2ce396ebb44446aaca8d9713745916baf33d4e122540ac5d9dec8011c4b9600850127db328e1918c72d13d2bc22add585604fc95d7ecfdbb2f6a646fcb2a9eb380608a5fe05576339a612875676218d1e8bd4c7b041c3920e6358cb80bdb6d30830af039017f2a01434e58d4fb9dafc5e7033c5da67db4e036d1a9a539319cfd25b1123086173921b0c5775a0a38c1a7d2100f6aa2833f20cc3e22f18846b0983f2034ac1301d5530864c0c447bc145176b8b08803493aa42866ad8870c18624536200af7cc48442981aa1fe329d7f62cbf205de24460623676dc5b2df18df1a8176c0e3a68e353fbd0ab74b06aef7b9880ad4bff083cfca458af9e86c7aaa629d6adda17954a6889c6a2f3f74782526a8481c5116d552f9098118fe0067c4a2172795b6328a0398ad38e37a677eaaf84ac25f563c7c35ef6f48d4a9303f05cba7cc5ef52c334a22fd2d748f0688b1b3976bf17fe13df1a54be419e94fbbcf4e9d6bbdd285f8aec360f82e0175f3b0eaab3395de97753cdecde8413c09a43c548b9a41b0a7e5a960a4ec30a55d5c4ad684d33584548835137c9bcabdcf98ec63bece71cdc220657a2119ab4476b0df9acc8ac1fa3487a3fc483306386996c0c251a2be263359b6d6e8ee1facf78eb2b04b049216e7153d02231e9ab9b065b0de6d0e032a72393fafa95636ecb7943a30b443b6eab6224f02bbf665f308d5bf1301a3cedb848a6fbd135f19e4462003a35a1530e31e42d91fecc0bfafe37e9d16a22d0e2dd389f8199c69e75611644dfe0a7bcea5006a4ddf487e5ac4e540afe440dfb882d9b12be94c88a5b92c500363adebc1a53bc87ed50266d34ab8c6a680d99c8c1b6f9c33f94397b68712209db4515b36cb574615d136f3e77a95b5422c02e3d849e6c8a7ac7bf0a207197d9c356cd11bf1e2fb506750ff73f807bbb270e14f7156993717b23e2085178d67e380b50b42b9c8c6c845f1a2e54348c70a978bac4bed31f7008143817b48cd1ba082fb8588caf3c851183215d3e1d153c0356fb24d3d6b6f06b2f91a5fbc80373b0a7c3eec4dc06e3ed407108bf09e40af3a2c37a3a13b925e85cf062d37d778107d003228b18e4ba8fc04630a8a20111b0abe4f61a762244060eda035d06b9d7065e7c160b7cf53f97937a9596ad12385b5e9c08319137068d014e839b0049fa5232b0b25586bbe52741c466f4859bd8ff8806f9b64a9f064c94e804b6260924d15fd5a6f4902a24bf374702dc95244f1169bdbaf4c225e23828847964a16cd6e328fd49bf5e58808a3b249e4a0c1717c7e32af0f0596fa8d601448284f1204c9774d4e212a9b73924bd7809d596bb44674b73a5cb766178c95800b475f294bcf1d8d0e7d024819f971c9ff3a8271898d6c1a992e82545ee95a8c16dbd71e32cdc599f68d1615234da4c469c3bf38bda198427f00598343a9c9c9ab0d9ce861a63ad1e2c01e2bc903111c97fa7adc1e9b067f6d5351081a92ad4574d1d599053dce4fbd1387de8f6438c7e83744732c4c4bb0bd21910863c9cb5ac28e1d2e247f96821c510f3fc0057e58db8bc362735805d9b64f7d4ef9593c75d8719d25c173b7558e8e0ec00d167a756e0115eb233ca0e4b86ee0a66293d7cab84b05471128da3d06f0793224f36f6416b6519f235d2cf2b5fa53f6570f217c6551120123851adedde768d8d755e5370133be68400807e410c7136d3101a5dff1618e6f0db3fb484e48f549b60d17f84b4474cc691669ef07efdb9683a14147992e203320a4f9fdcb3ab37a440896807c453b44be64ecb572c76d7eb812b4a937ef974dab6befa4c770919d34e9250665a7c3df9f86d3f1d2fb7a46215876e06e880c8d5d1c10fac754615593742d2489e5fbe7fd303f6dc23298e346564a393ec9175ca5bc441f750dd58fef392bb81862083ad4ddebca6c4d18ab7d4c01029bc7a560145136a5f1f25fc0cc1dce171c4a71ef82bf2a5625cf2f1702b77438deb19166d8005ee2a792221022d2b27318531c328a8058957cb30d81253d421071686b0dfd128682998585ea5f6488e70bfe6dc6f0ad422a366931650134985446bb258c0179895e7b972f73db41d84d2fb2e4a2821d91663c89998dcac645e8e04d41e814347e1748425a9fbf0529771a2eef3a1c5064e73d73662ce04952972095a1b8991cb597d8d56506e423c4e722848484ebe41a00697092d068f573a62e56b71989b6d8ea18c42815a3a0a73d99032552151273ea33597eeb1bd026eafb3d2f243cc7591de62e6131342445d985fa7bac446c0252e22b542935d109a580fb03bd267a5ddb665d1b78bf128e6d7c7261fc78c0a298c7c8112f8574408802438d6a351bc3e1a0b652a4244298a352cab34bec215c6c82d68f11d13dc7692cc10493639833d20016a036960a031cc30215b77d1806846f9d170a92aea5731fb6daa6bebe720f7e36390548f5826233429346c43e01fade942e51601c15e7d98cc8e6dae9fb638b5919255eee7232fb8dc091481cabf3019f4ec5a1fea57956776c807f7ba83dc0ae5b764e19dba7fa378c4833a11a00f4a9c4ccf9c4c43b5f83a3caefee5ed9d652ca2465d402e602c102ae9abec6eb0f7ea84593847a0a4b2bfb094f979551e0c1f9d5ee58017eff14b6177f0aa7ff6257a9d998f5cafcc2cdd29c98ccfa049166b9d508db6aed2b7da55e02d21fc474376da6edc6965bddd8722b2f67e6cc9c79ce78af1c9a20696aebb17a65f173decfa109a292bdd26615b3ca6c317cfd413cc6cbd58cae26971bc550e37b024088c764ec32bdec57a577fa80995bbd72a6904ed06e183def239142a1502956ab4649b15a284f541955bc313f2ee5ff9cb3b53967acf37103f035c6a812fb9ff7952e9ef7de835f03806dfc2c8b59f7a44b144a75d3c22b55d5551d0f13e70a5dd1735edbb952559dc76a79f60c51f7c4d2a1aacc3e596b883cf2fbab32be2a9c4b1883fe2aa34aef0ffc8ac01dfde0a70341b0dcd139e7cf36c62b81ea7da918854ab15a14a03915602af8cc0184ae74ac51c7104562f82059010c17d2349a28310365c233230c1292d52e1a834ea8a707a11ed40c0fa5e1c8123c3b9c20c7161ff44081e2040d2e6690828631b616636c89c6211635d55b8be6a62b52a288c9f716d5b1741909dba3458b1a81c237dd5358d2dc97fbb75b782d0cc7cdfb2c372dcab34415129282c3aa16b53cf77e28049571627ff7a514b508e331adf3ea5a76023a3a3435e6cfdea2b491104cc2106f1df24987546b5908f3d71e2e1d3bef87d86237f16f226bef49897defed1d23d8e708b60e2b7e98ffe531f6cc652a7e585a54c9f72ea0064b17ad5f7f33374b01c0b60b95727303858fbaa7b0fcff0060fba4f2972bb29cae8a73fd19874e092de2b869516463727eaf4551d0793fe7e6244e97782e7056a11966a7d00c3ce7006715f241e14ccffcb82743a70d12382b88ac1640e8ce4f1400c80edbe5fb7aba78f972f37e8e9bf7c59f7de3e67d1b3705b047b6ab0ad17aceba3bf311e71592428a9f77ca69f38d435c6c6aedcb63b2d00c519cf72b5db5e81b23c8270745f0c47809486d8b41f7b4337af2fdbd764f3be3878ff2185caadcbca7193fd5d9edccf841ee692c555088ec767e45db0294d98e484ce683b323b2d34466d29addce47d6d94de6ee69329c2d72e77d2236667f4ca6ceba74d959d63a37f0525fbe0f594238cdfae386a763b15d3616b3b1f76cacfec8e4f7ed72e9d21f82ef2a4dd0411592a2fb479fc91f3fef5126c79c73ce393b0261ce6f7376071dbb7bfe6f548d79cc6216c79c73ce599740e2e779e68e88761677c7d8ddc3173d7cf1c5d0ddb1632051d4f8fb30f6dcbbcc2a04542dece63e9cbd8c3fb3ca8041ce6a23d1d8f5dc677eefbfd18b9f01f9a358ee28518da58b8df82e175421e2bb64f0fbab10f277c492f4198c4fda24d25721f9fea8b479ec8c462a5521dbe6755fee6e62d30471208a91d730ae3d761063fc16bb6bcfd8dd4395d8b2431c86e1e310ef8818638cb17b0914fefd1edf7dc1e2506ee59e91cf77f440c3341b0b5f04b13007ad842fcc80838b234e9491851458c4b1a486d90d4eeab869d00a68843116788642b22708871a166ab4812482273a2861061562bca0b3cdd0e3d343450b25292a30c0430a55e5ebf500623d4c340eb31bcaf8b254a118884eff96edf7deab52bef3306163377bc0b33271648b980a6ba42ba470640b10822649ce68230723deb84288f5028aa137e6a803069d1335f4d89e14018588211b518df6938446a3d1eaad8686e69e569708c664325519ff1c1d09aa03235405eedf9fa0ca90507fdcbf379a1f217e2c8da846fba1d1d4a8f438c4ceac8f89c80413449426556bd6aacaec52ceabfeb84f801bdb6532d51ff781006dd3bd13a8ec8f76c0ca6482f9be65490bcd07cd54a3fdd824b62752a048f81c7107a246c094ed3dea489831c61863a254aaf3ca9992eabc72524f6b95ef01147e100f4b94fbff2b27a7290f5dab07d9113a8c0960639f59a5d2b15afbfb78a0529f8f3c04618cadc518132181633696b1e9c3966668de532a95c2e5d8a4b814972a919aa5393a26b3b1d4f4981c1f4530a927da78e31095ccc66cac472acd11ea4277447a63e3c562b219f65255c6ca5c268e1d416e9a39afdd34813befafdce650aae7b6ec112065bbdc865b61bb6a4e837af2da7da932f9734b4e578b37a92ff7bd5684e99edc89bfdcf7a1d26d716cfb9fff1e6572cc39bb0d9cc1f867bce63149b00a98739b75aff92db772273e04eac8c04c68380693a6b839e2a0133f8d020d35f1a0b01e1445d1effbfebbd58ca3c964b23dfe6261d6048b848868c56aad886a535aab8c35ce300200d96157d8cfae6ee2d2c2d033763804c80e7b94c931e71c962e125800b47e3c56603fffca63b47efb2b0dc258ef5b662da8b6ba74b1399be210ce8e088df403110d456f34f7342a4d3793b774ba1b8fae85c27a6e3cba160e0a4375341e83cb56cd4ea5a3a9c11e761b1a1f2e130e0a6375313befb750d9b5a1f970b63c9fa9ca6c9a2a834fd604f486de2cfa852df75957b7af2dfdc9397e188a3455663cefe3d278dadde95a39e15c81d51ff8ed983fb42ef9ebb9c3738a1f56b797742bea8fb174c96fc5d215962e36972e768584f70863ec342613ccb7b4983e48136d870a4ae86c102209a2f1f38fa53224c9c0858f1123fe355ef3b7bffdad268573ab61b574b78fe5eed841b07cf7ff54108c6752b7548b8dae45b383cf79bf4657a5cca430763d764f61073f9dd61a6ce1f1f556e33e3c090a4551aba8e05015150698ec7dba4c20d114df5976046fec7a92a3b873188662aa1fd40f6a0d826eb2a8a81001bb398c31f8186310638c31c61e04630f677cb50ad43be06bad35f8807e407b942b92006237429abec42994f4ecd1efd168efbf4509c171c80869fa22df8a64a9f3691dc510e3974e09480e7bc7af907eef5821ed3cdaa3d1efdfe5cefed16834daa3514cf4151346e48f487234fa994f8a259f7eaebdab2fa3389613e4d3befdb07463a52b2bad3c6985b4471f3922c91ffda8dc193d4992e48824432739f99aa4dffd4821284323a4e92b8d6d28704b3c28676b897644dcc7b7b1d15d7f067306c10773d60155dc743d405aced85af0751924a1e87ed21643b17409c30f37064b54cd501d42b9eea47f583a1694bea19e48a585c96e3d36d8d05088c2504d43798cfed1b553d35a1a86c342354d87f2c466b5d9795fff34c16181206841ab6d425114c721f85155c69e740d9a86b2a9c1b6d434d0a54be0488e409f129461722c5d2df7f16b5006faa0f7a469b60463bb6c2e8c1d0883c1b02d0f283b4199c7b0ee89f4774769a5442ab9f48ba1d6cff23b5876ac904211c458c76ad95dee907e5491f6de21fdde7b93401fa4bf6fda7f1f26e7ac699af6038e1e400b3540d922e4eace80952f66454562329f20d1f37036f73496a8224545b859519198cc27869b3189c96245458a8a6c4c162b8acd68b5984cc78724e7fd22b19f24455a6bab6df61aa82710eaf7e4796b4aa49eacccfa9cd7825a5f8cb4505feec73cbc47e4a875cc86e0181345711c453b8a3ab3a22231994f100b43497605ec8890e393e38823dfe69ec812e58ec3a550281cce4695ae763b7d63b3c3f930c12ce9c9321f1b0cb27e0baa032dabc08dd91ecbe326cc9a80c43e58d2c979b9691d00a12a70ff8650c738ef87a17847184fc6210ae7bb9e10623d63db90b4f188d41a636ccbb0a4330a957d24bf659c8d3be48fe338925afb2881c6bf0f438ea8bb0389b516636b2d1862d0d35af4ac054ba071cc595533c4d2c28395e6dc6821c4797f955a580f0641d07aa08d0282e05b30fc1e2a5fe501c19c4771147572ab57ce1412091886a258febd2c2f1d2cd05ca54cc1298cffffd5a83af0abba108722c62c2d3cf67dc11fcead86d58a725132880ba227a2ac3145126c2431fb481bcc88912ca0b4ec9d8661288661aa03141e6a55a044496e6b045173cfcb9668e5eebecae5723743b9d5cd907fd95129f1ef49cc5f56d50cb5f0f85c9185a96a72d6ffbd3d6bac673187612886319fe7fdcab75082ab15d4795e2672b7b92d679ddd04639a71e22449cd6b3760cee4312b185d2a97f39a27b96e73271e8d40a8e48b9ed898b1990100000318082000100605c26098c6a9a6621d140010578246624430920884b150308ec3308ca2288641188618620801c01888144289ee2c7c352cada311e4d1900ddbc7da9ab01a9e3a58eeb7f92216630a0884e8181eb2f3c59db4ab0e059796629f43ac302273c61ecdb18a33ef6045bbe00dc8e950c151b11f2e6d1429f65b43ac0c0e8dcb2f54cf5602ee8c24715681c151ec0e569de708db8d8b4382820d818eb1d7f5ba229dce13b033364ef7f4cfb6968fbc590a047279fb4e02b66bde777e956a592c4d2720f9790ea35209866337bc9985a7d2c7f1ead19a97fe74b99013aefb1bc79f93e7d09572f65a56e491b004d1338194c5678249b02679b126dc51def0f500ca8cc3f85242e50711062d7a5452fb6d5e7a960b0a09f90e5ddc604a26f841cebada8de32cb171aa8ee3451995c080dfbd02aeb8497342023a4b21497968204d788fd46e9737ff79909b0a39cf5f4d674c8f24230d7050b10833a4c5572b347cf85401a8c8ac6c52c427ec36854e678e86b09a21822922b1cdd0e45986266a887c328ecf580955018afa47db37b0361941e19efc545db6a40ab69943012f106a0f437d2ad6bd26c2368ab60816b3002d515cf8816661dda088afb31f22ab852fe7886c25317ddadfbb37ce5213e94c862f5bc31e9ef9a066713a8aa20b674adc608d10d1cb549219466a4d32534ec95c3f28d376d3dd71539798cb84f9c188ee34c6820b0de56a92334acd9e60cc8c2bf3a04c7fc39160b3c242245a46308c93a1b176635082f9f990c2e03528a7f7e2f7de788742e416a60cec32140716932479662fd16cd9356d625eb8b8c57bb085eba3718e9b81b2f14c99b01749d8d42978df123eb3c6738af2c2edb9f22d35ce652fbf62b7ec6e7509eb5692c3ed45c20fb5906025ab7867cbd1bdf472b34aeed4113f146188e96ad48920aa8438ec3a25a54e6ff5ca74bddba4390685bcb133e48fef0f24c84bbd8ff012ad46176d4cc2a961ecdfeb82d25ad81ff2e023648d766cfe5c7122a894c387dbddf716da7beb35c79571ab438169636f17323d0fc99e1fe2d907f66ce7b61c0459008021d110831b8ed9535157fede8da7c89c2149f060b556dae095b5a1293dee0b90d1c0036638b765628298a3c98d2b6a370ce81cc6f46afef82ae2b6c92d3741953e56cb2b4004bc14882a1a7b952df8c61bfc2222aea71708830cfcd2caee60e3511b007499fa8689fea690ee6c30786d7f252f3605196b171ae7512b8313f517a9590aa04ec9ad83de82c1c9c8b8d4e3247257aa0ab8437dc9dc6f3a456b5b0a0e757afdf7e9455f40d310b50e50822086474a38fce7113243d34aa45a50b13b29b20fee720908c7b3ddaa271161ba06f85089a9a9ba058524a79c405678bca3efbb3c0022d479fd7805ff22b97da774bdd4703413537f64fa0d5c4966a359271e2fb7562ef51a14b5101f755a3ab866f2075ea97ce38182ebdf93b4e779528ecb2c976f10b3a26c7b783ee92aa4e540b32feca613e30382e1c3d5b9590880ff19ef0754a5368066465c5b54d50286a91c3627aec5167d447247fb0f8bf43e97c26e381a8117c32c42dfdb3af93f4ba323ee9eca0405fd808f85ba6d1024faa838b143f985d6a0fe5d3f2d0eb7997abfbe87c736c8f8241e0ac0d4f02a302261089de09c9b894cfa0f7ed6b16653633ea7cef404830991cfd8f48c9bb2808659f09bb4998321fb0647b116a0b6440d95ebb6889e7debf5d1d28e23d5c3c8644652ed3d9da1df3343a3a7a1e3a9e924e2525765ce5298e53e4dd152c8c9138624a1c82bc9acc6a2ef95c8131ae5f0ccea248ee3e35766c6334b8d59a3112a555f3d17934e9051211b71d178381b503d301ac822f16cab18d7975fd919502b51fb4278a4b41a7d999bd3fb37d26f7c3daae3167d137762f5d0b6da820424b8202d6467db55f21bfda0048d8539aefea8319362eac0670171a187cf7221ce1a6b74e041d152a16741b0336a7a40b680e27a49cdb55c0af162b117ed800108e668536d3fbde95624240871ce293d1aa62d874e5a2bbb1985beb532a7aef34726eb9006d2bf7de110181ada618ea172af3ef842327c42c3f504b10b0137e503f4843d48d812011da2c5236c50f00238291c2fd73b297496862b49a1e401bedd86c1973ea59461de17c548a6a6c8c42c23db6c6808144ead2e8b4b65808c7ddfe3a12a161486a584d0bdf12a21f950f3e3b72df81ee8d5fdaf2b38d0f856b9ee8b5da28c0608f00b0e482f4f7cbcf51e77e021864cbc00017ccc413d386dabc4f11b5685fd3ef0344b7babdc8a64906dc539a21c21292b264dae5851ff80b291e70e02aaafbce8bf7531b8c5418939e321411ff6a071ec65e966a1c47045a5a0db7db4aba1d160791739a0b12a78019cf34439afcdc84b398702ee578dbccf0eec70c7cbf2b8dcec404dceb1e1d68ae52006306da178716c83b41e5e01ac1790c4df406f10e5cd414710da5a2f0306e6826b52c690688e2991a58262fb8086172c547d8fbdc5ec39689704d7a8374759e86c750928aa0025d5d699311c9944928ddb75bb4a8553308939b805fcc253a5b6a2ced2f9638eba0b4713891570598b6108368a95064738558d0cb25c4c5c4dfe8c70c751d7a8c25caf11fe2c9d5caf1b91395a66e19b2498d40c8ea47dcd3d42c633e742e5d0eef5d872e89003b17058ad2067dd581fea039526bcfe3cdba47702d1d27fefcc23f83c78b8605e202c55db28c04cb4d72648b7402ca7b52fe584b8d6368a3e7ba0a4a2230a3d1c13135fa70be9e448ee18401c27e7bf9c32ebcd6bcdcd07ca6935f0e9fbfa90e7f5954f26a000d290b21d576c5c53eb776d5fafa48918b4d2a0b42107c6fdfc8672968da2a1621939fda84363eb8c2285c31da032a3e0b7a7761ca5dff8af0cd5ff043b2761192a170ffa53836708df20018197b8bf7444c238ecbf2b3701399f35a827af6dffa76c6ae05a4d4769a979017f2802920b11483ffbf14b40b8137e1c97114a55ab613b3fc197e6d3356648b2116680fbff49b943f760948f998b2e2a6906db4525501430349ffdef0cfdc4b9282bcfddacd14a98d12d2717c81b55a610cd45b074d75406dd56b1eb4a7391f9864b0a6ae49f0ae92b45522862539d0783a584e76a69f1897cdcf90b303511cc4c37e1986e76f5461325e3ae5c6839193f67f6bc940ed9359804356426b65515f331f98a1b11e47a7cc171ac21284b78c0a81e0ed098f4c7c28059023f5c9514d2f529b81953f15c3aa645986279cb3ae4724321a101df17c1c488f0222f12fd1c341d0e4b4226c4ca80e13918fdd4f95cc08cd55dbe9a21869d4f4c845c892c2ec327d06ae95ab476ae7191d5825893f36ba21f6b24610c3150127d2f63be6ad573dfb2a46bd85a36058cf48b17970c4aaf9a6579d551bcaa12e0fa814e8eb35c309673664009010e41120691016c6de648c0a09ec9c84f11261449f46ce09aa8e4eb4b4327c35a03505946138e30043c8f5e50781f35c8ca369b942edfabcb103204ac70935af73856dfd9e4188cdea455ad3a570d5902ffba9c628ae81535bcfc8c938e3729845caddc916ef5b7a8e1ccf539eef5bd7571b8309adf14327198956beae299cc6042c6f52b4c428ea7f85f2435b44c1cc2f3ca14a54592d7451c98f55f52ba274db94c1cbf38cff8d02a6e7328b1c86f9c38ba8ee9901f1e56c4277124ba72c90b666a897309666d260b5392f74e0cc448ea1e1c62e45db691b9c7f05d1c2f4b82e801c02a6c3b339120326e0fc111934363d4d090e9cb00ee0261b58a30dfd7194fb9d5945c5dd3271e516270a4fc83400ef4402df3af26096ce76f1f3ef6a9089d1482063b38aa38117e28789060e97e5f7dcf6e6e09f04b0461d40661317ed2f333549c9910b75d6f084f64ffdb02f77133e5550bf5f791fde40e4775176fc542cc9c30c57b747fe3d4071d47764fb86a6d5f186907b7fa9c2039fa42e59087eb7c874c80a25d4255c4827fff4b7915b94054749936ed780eb21a9e39e7b4e6f5d98c624af74043d3bfeffcb44525a3aff2bff8f6cc8abb7a93c48e15eadc9084a729f145e29bb9b56f0b1121d9df07062e57b32389232cccfc7acc0b806b2a9eb06d4c7e34aa211ed7ee04d8e2673177ded9e5388a6d399029a10c0814e494e220e857205adecec1ebe1f1893de540df1ec9d2ce710fbbbd2ec49ed3b468de979efcd883a32917a3ec3123c405ae18d06bc1550ec4c269a63aaea4cb56d5b54ae8bc2418293dffa9ba3eebd8cfce962648fa8ac25b4098f65a54972daedca77ad225a3119dbd0344050d499d2aaaac84c3a9a488320ec60f0202f1000f95c96238a3b52b024d918e859540b01ea8ae704dfbd44e001e54a3ad4d805d2c71363b2577498cef94ff7d9f2775cf071d91e1b84d39f7d4672dd9e7bf8d929a18ba229f5f59c30c7aec12824a8db091313c76e5963fe9ef2e9a06bc7d8862e3fe29f17dcef3ecfd1ce65f178cfe4883bfdea0dbd4962727ead4604f3149c0b7c1748b5497575ad581728e848807a6b185bdfda8d50f24987fdaebfce092ea6d0f29ed66512965279d37eb7b8a7123641b92825c2dd9c4aa9cfe524e787622af497aab0f3b40bfdcf0e24ab4bff1e7503b03dd200b73f1af003912c3eebcfad77762263f321a9a1f1fdd9c0a16a648cdb86090774350cf2b8cc08648ed9d786708ecc2bd613631627c652f6f8089e486fb1a0f9362b0a678b59e8610e2f6d77e5f6c1d260e9000c5181ef2327946c6e3055e437a7381828e21291e798b314bdfbbaf1336e625099f391ecc842743b167dd396393b4f89b8eca0d444507aaa6039fb520bfbb875e901fd8de9f780cf771507fad984f2426bfe3d065710bc9408197ad2be03f0af90fb109345d700ce2e2c0f77c63103708ae2ba72bc6c398d83857c6b48bb75134f856b22b166b15062e8d22de4c62ad636a2e8577a1d8991fb68291c7ed98c312f7068b8fa037423cb19e5db35a0e7a933f3eb867d5385ff41d564f18a6ca7912504847fdf9cc4ebbcf069ffad90cb937898f8644b0c13062e69de22b534f57e7a8b08139b32fecca0e2463aabe0c19492bf09a699a4cee05aa7fe5349283159220a01c262391bd358dc8629ac5db28d040a7b4dd677bfcd31062334e84682c19eaf22f42e7da096707e7cd8ce5fd2bb46285a9160db89d09d3163a0d1fbf6842b8d070756745ead1fa20bebfc369c7611250916bee8910adacc0846beb9720226d065e334d93c9bd68539d1ce6e7b7b986442614440e39e2a24e14fd23d92b1adaef4412ba6042f438487b45bc48c40c480bfe7d8387374db60a337dad5427495e301ba71cc0adb1e621e689bf13d3b3276981116d64ff101b36267ebc4f5daef8fbd927876a3053e44ec282c0fa3adf71c93b92d27d7960f14676124310cd18c0d2b5bbd5574c94e06f42ff3f83d09d3d5a9da49675bf7009b8a3379d6cd9b35b281fe40cc60da348af222b44411019fa5089263b0468514b87489274ff427886122a1d579c005635a76e93118f894e253931f076b2e57bf64d18b5accdcb769834f5388825ff6e6ad20847b8b68c956ff994534fb335b36cafdc18f03e9d058db58c9bcd08ca85e5ebca96b208c53f0d4a59328730ac7c5054a5f88418f1379470249c0ae0f87d22658e165b44aafdd3e48dc5ea6ada04d6e76e191cd2b70bad577264483db27e9f7066e3eabaeb6006472ddb9aff337a7c66c71966107a069a5548beccb0c5e5a681937df1de8b3e5d7884859e00a7344437bbbbde8a02c04dc530f62726883cc938ce79a327bd6169d7db79f84d51d92e57f1a0aee5cf0c4baf4d236265010475863cf150bb6b554220b8e160b203a12d6f9014c3c06c2ddbf41297568fb8d2f54b10d5b2c193c2cb4385e98dd4b0d929412ecf030c247d4faa9e6d12038d487c4eba602893736db3febf4d1a0023bce47d5ecd5c1f17cc9656abd9bc6e7a27d0070261dd94ad6f74f4a0fdf16047709f2408eb4ccd930171fa4a7f66963f08e2d96b74c0ecaa8085e47d1a43815e55c9871878de8b78713fde9dfdafaa7ee3a7fc12571aa249580edba68e218177eef729148a0e3fbe979472d7bf77f9e1ad3e8b818eacb08835c7a0f7f53527ae33f5cee2c86bef164b557f1f8f8924246efa9e7dec8c831b78fe7480e1795c16e12eda9414e67b807b98dd2b0f94bcd859c89a04dd2ca733c179307a53c65fa42c82b3be8b43035c63280f66ac7efc77a3f2d75d58fe7fec8b6bd03f2f1f34508f0afae5ae8473e19460d02cdc72e6d73d5fbb1e03beac3b9954aeba370b675f198a34793a893abb1820487fb2aafc9dcef1fcf15d38e312bb9e4bf4e564beea52305f29d9c8417a72df0b2ed44d9d0b1b2e4199736d1d9f01370edc5ba196287687a3372eb79e5225a1a1b26a7a36d460c84b1b5706a6543287db2a4d411b2133f097b81a77e7f79bce9a4b5b5394fcfee4e7972ed97752128c436bbafc341b4ada3cf6192080b55eb04537092ddaec3334987b276f3512b285a5528ec02c4fee46d3ea592d4585f65255018fdda77b9f8a96edf7fcfb57e6d89984608e64cc7fe140ab328872004491c043efc19829a855f59a15ca0154cd2eefbdba4e85c743385a670e44020f3b30c3d117571d0d00b22b1a71516e6fc5ab3219c59b0d8a64ad6e14fea05672050af1bb401f5b130d74be1f485c141022ffc77a480c02999db4b691f8c30a8ea7c98cf6848ae86f2223ed4460cfdd4a5947435270ea6b2dd2c680b3c94a599af284ad31a8418b4b01595aca7280613e3bcc7f2a9387f61b427686b234774b419ffb140597b24b6d64b1a77200aea2ca8532be353132c5b878b78532f0a880981391a347f3f14488b6da01a1051f0f45e409779b24327c12ffc7916964f8eee9cbd463cf6c3e9124358f12b9b5bb98b8ff42c3a5e7a4c03067f78ee6dd784d88dac2537c412921b9bd3829cd643e0cd07fcf49c31d1c40a8d8f6be4ef83ea8864f52eebea490894901fdec745d2da48da1c9a6a0d332e03d0dfd4c7d7d850fbef9215161e37acaac20e21d304df2834b4b52dd905f86feac24873ca46306291306096647238d3abeec3df6e8da9b9298177f12d4d7ff23f8d7ec66e97cf0de238036ecf2b0b53066e175ba8deeee88a98b403aa1194c59e75268fb8e6acc329fe1a2ed622f7b14ef24e03571bb126bc113e61ebcc94ba4af58946e21e2f991f9013c45521ece4eae574b0e94d8232dccda3cd77b40913338964c71abf7b3bc70baed2460892b9ff16474b53903b1387327c08262a28ab9626b23067c71a45ec0168af559c844df89c1b7de84e1842795391f51b1abed3bf10f2b74cf1952ecbedd5b89f0508dfb33eef129b781cf93de473840448a26f6d7fa32cabfeeda8a7a121806ffd823cc7b6b65f196175966f2e5a31686e5220689fadb3392a09b4771c882925f60210c89067e923e18dce22c521004061f1bfc4e8c8136f778288e25a9db54a9136c465f385e5beaeeaad0be762a96346abdae1591301969eebc4f19aca4368d63bffa3e612ba1588bf6767f4029504b9c05d38e96837ed445f7a109176fad096c77674bac8c36bf87844f886ef29786a736f75c8db39a42329cb395e22c0e8eb8898eb22758418818ac2edc8578f8a356e22419231b6fa371e5da48190417a34a59e34a671799e92388bcb99651f8f3690bb98c117f1653fcf07db05729cf626b5e29fc9d64e027d8b36c27adcd17bdec24d35ec2a55e3d9c199b8d16a16bc0b13c10ec471fd865d1a92300eed435d529d3d367071dc65788d272330790d0cab1fa1f2339105053d53a48cc8af0ec83acae1cd1acb1df110291f1ca97bbf0a0e05e907ca0e4826ca9adc4550cea8035834be273885edf10de0a51f968e143d1a1bf8a3877cdee6eef54eb16885fba4438465a64bf9df3b0cb8e0eaedb9d20443fca5ddfeca000eb890929f807105c19ae5d94be05a670434e8e9ee181916fac726717d87e4c8ec3cfb0fdbf58f55810d7f2d5d9579123b6335cbda23cc00050d432def1f188fee938d26ec7576c2a3c4b0308b4147f28817c94b3fc36ff3ac257d4d06604d7f08e34c312117250074aa7214b55118546a4f90c1dd708fcacf46241df111eaca3ba7af08d532a87a5d31ec8c96739e9e4d5a053ac571d3c9b841380a5f9d8376468abd20d73fef4ac26e6538044080e36397552a4a69a765b265b5826b530e238885545b3e7236049894fd6503ddf942e0924fa32cda0ffd63abd6fc2654b31e076a6eea1f0d05c90ad12f6c271e602e956865f8b104ace104f6158538a36be176187ad0dab49a9546689ca3fbc7e1ba92415aec77254bbf321393ac044352bc4d99d88e0c1dfde5fdec1ac47554abe4afddcaef39dcff20cd44e51e496f3ca43c4f776252a8573abfddc7e3629b90328e479db5905db1aa0dba1eb0c20dad586e07de01b9c5b8e2e51fb08b88b64775ac1d82ddcdcdf0694896cddcf4051ce741098585bd023cfc0dca03437cbc1ebd6b94723de12c71b13c02cb7d0adbf790f7fe7bc99438a87fa6d82a36481e87e2c8ba4baaa17488e7e57bc5e270ae91e3372e412f47ed1aa10ac25830ff556b901105282e93c5636b779e8b09890b68e163803f6214797b55d7a7e60f56ebe4fb2b0b7ee77de069207e50ebd02f7916808441340a97207c417cc9bc783c2196ca783d162a59bd66191abf93977eda125da29fe9995c77da0d4e09d19e7051c64524c52bbf6792a3cb8836e8f773e7aad0aa87df2a70368d6ce9e6246448d732e2b98f9937a3c1f6d3a1ada263c26db26d6a54ebd3c303ffdfe591b300d0a4f5ca3cac37b2899d5bbfdf9baaf51a28a02350d3cd5ba97b8c1ffc44a938ff9f678732290011a7b72ceda3e236762a7b91b97e78dc403b976fc1535cdf731be41688b8f98e6e1283420f93ccbcd4e33287df7e75874eddd7acda999660d7a09389136cbc689f650367456db57851c38c9c40285912bed70e7da47a6c29349f6c4ce7df04046c6a6cda84d3996a13c2bef3a6bac17716cc0aab039bc85bca5e5c004f8bbfed18f29b1445642e26def5bcadc8d79ef48b8284c9cfb221df1f973d90a7df8de39ad8bd1fbcf6f29c38d64fadb15d5a6619a9fcab30ee5d9fbd6767ee5128fc6f89c1fa5f336559298c71d3d022c22575922a2e72579fb613a5bf90fa16d4f963cfeeb59669c6674a5e15f2e06a1cf3f7dc8fbffc03eeaf6975a667eb21fd5e7cb30df219a9ed5efb844862f1237e917da7c0440c8c1523f23807e17882d52fef22ffb41e1ea41089a335179f683538f5dfa72abfd683e12801b4a438379bf84b8ba41ccf3764a5a2bbc71051d1b029b6b3dc86390bf38557063bffd5c5fda2be59716dda21b9eb0a7338fe46763a47759f2985181641b23fc3f223d785cb20c14d093879a6923fd170235b6edf8675f9c1a77f36e37ddd0b5e7e9e00dc80cb912985f64a2b26bee774ae468d57ff1c38fe71ca5439b25e58e3102f8e1d6aa066acdd93c516606f7fab594c9e0a2eaf2d4dcb3c3da6b483ef9cb88cb453d6afa2f50c3a8e31cb97e289701fa43f931de78d49c985d93b5579b0441239bd28658ae34f7e034c78e932e49cda8df48a05c9c25e0de0b8d4788cf8daee4b0432e27c55dcdec3732be526586d906ece4909f7481dc0627b69b206004292742f1e14dab41eed1652a38ab24411d888228b80596d180fd1f2d009f5584d076d6686a5e0f6db725fe1c41faa7509ce0f3fde998bea8500a3a25f307a4fb4a42bcce5ee1b2478066c42d0cec0b90269dba2516cc2481cc294be93793403af27504a55e9742e0e8828a3ec5afc27b18af6aef7829044d75b3b1c5ab9d0d680438a52ffa12fb0016e69ca40155b866541d872bcfa9bdeb3dd7c5ed06b0655cdbd4ef06a5762e7ccd4084e0809c9346628cf57024bd7494e48862498258304bb25359d6a66ff7c310ff91a17fdb0feb1ebd05cf1cb4bf03fdfdf5745de1b71e1172dd7691e644f6cda2fb8656f043a579205e05e106db32db08b6b3a05eebad849a3be4906fa7252e450d9f106e33526e03cf6e82bb2a40255cfa4f12a595a3ee6cfcf3ca97cb5bda8e31e242094c77e0acce014a2efd415f408a59451d824a1b72e359abe1ecf79e76ac9dccd3c55217286928c452392c941525cf4f4627a7036d830704c23ba1e6bf4fad690e81c26b771ab1dac097877a0754c2ce3396097143282a296a3b7b4befb01a298decbdf7de7b4b29a59401070409042704df81a5d233955a96ed147673381aa2192408094284c8ee4c92019c70e8f05265496a468da84837c3061b49bd1790d4f299272133a0188d6962a536f69826aa5ebd812c4fd621907057af67925540208942eb20a0de128e1704440af5581f2e84651bc8fa90e406e79b9f81156ebbaa0462f449be5177558d9c85d3f39fa6b959a84659f76add62a12d162aa5de8cf48d0ce669a266bac462f1229c0fabd0e8689ba6695ed334cd93856e94b577992eb59e1c3fc0465e62960fadb739a54d55659d278bdcf85ed316c940f458b10a6f28ed15e636cd4b9a7717a99bc5147088c5147008782b3281accf1ec23bf92bc081b92b00ec01510c4cbb7f88c5b97b440400c86fbef51e6a432c2c4ffe0428f1fb2b2e09d8079b34d325fe9ba7f7b6c92f1ffd3304127eaabaedda56771fd76feaa1e7474fd334cd73efcddaac9669ee5deab43ec36c66c5b8548f7a33d21d56c851326f2dc18bb9d68811255f30458d6fa94b992bdf025c58918145cc0c2b3eb40e1fcbacc6fac3545b1e8b41c83b0cc330ebd7fa6afc18671cc11da66422c30632af2369937169751b95e4c2981f0d1ae6d40d58b4ce3f4db3503e9bcc62bb2611217195245ec7ff03d5f18fbf241f492794b1f6626bff07df5486652369531bbe36e39db3bd5f30c6698c745efcb4e70bd66d54528c10ec0855287345c2be42ba590d80943120b0d1422586259dd10c2431f4d0e224ca468e0d75a39260dc3caac9c1db691acccd048d39fe52f12a04355a48355ec62bf5ea45c77f9a9b49b7d17a13303210813245e656b3c93a4e42e6080a1b1bacaea0d46c3d36c6ecaa8ecf6ea36c50d9b802b3eb0ca116354992a3b579ab58667fefe0f76d39e79c47e4ac73d651d8dc40e268f84e1c0d356c6e187224448b519a118cc4a4c05204cd1317342469b929d2bb231e6b3dfa527443146415219785868fa72224cca872439a244765741859ab52a92aa8a39f0e11d588992826179e8c98d1290105f0339be5aab8cad4aee969dddddd55cf9405c62a70766fb000ee9a9e72bba65d7a91c671d774771769b797f8765052bb5dd3dd7a64a15a9f0fececda4042e24f545b623d510d7d566c8c655bcbbdcfd16f6be8e7e867bd6decac982c7633630055b8edee7e68e8aea531be2a8b21140d02227b36dbbb3bd33451157926b4c16922f55dd3d36aa5ca14af0764ad9240c8aeaa2c4badcbb2dcf5a4744c4d3a5df9fa6f2e7557479a26bacb728985424a8a94c23bf9a5ebfd763d291d5393aef7dbf5a4561d93aea7deaeee32dd2255d7bbaa6ee7c45b754cbd1d4752ba27a89e4ec7b4db26945ecfdebcf3ce7b9ba2485229d2d2bbf4fc64efea7aa2503edf063b610ad99ee5217b343ce2a6a4d4da79afe7de09f36d173d4194a493babdb76eeb08b0f7de4297a7435194b5f7de9b1cc9deae27a5636aaa92c0852d4bc630316255c36bb2a091f1c24a1b1b98780cc9f9e2a7d1f0881cabf3cbf2735816928da8c06dff5281c3b88fdb8fe1f4884265ca18293a165a61baf018d26bc1c9091357a1c49a12254294a13aa203872d4c673ad5192a364a52637c2db0c0df3e164102859c73ce3947ffed39fb89f2e797e5e7f961257ab858c00d6ed3e9d7d20ab0c44ba42248fce0363e8e2244dcaedfcb0a307420fd3883c3d18d983365d6045bf0e550ab210c4fc80f335db68ca086a35e580932599a4a53c36fd1124edc3e16b3ad95cac9d7f61bd37936011c371a3fa2e0c052a386c3fccc6c19e2e44c1555cde6706333c317ab2d50d0d4f0cbf2cc36c1613744060e1382b8a82d89ff83459c53190914f87ddb632f61a877ce59e79c73ce3aef1ce61ce69d69e1dee1ced65a9bb5ce318cb32c763b76d92c06728ad3ab4bf88938c0799e277a5a9efb79009d0dcfb4304cc791f3bd9f90b888590493e2de7844be337c530f1e6c377766afadec4435a29ab5d962199659cbd3f315581ffd34fbd7becd00fd125d1c7bebbdf596a5f856602be8b115589f1daef9c8bd79840641803b4bef7d9b01ba4d6badb7c596076b3bebc11d3a0640efd13a6b9d3326c1f2b4cc60a4a6cb8b2d2c40806a2aea0526543d76c0b88140c40a87d20b4d5624b941636da3bb0ae18728480d3355296c99b233b24c76f83803758ba1f7647fb4fbb59eda2f3c03c1655cc665496c2399fe42d1e340bd1048384eb7c9708f4cc6e168c75fef7219082014f6ca1eab4836537ee34896e5ba8a434060188aea4d05ea14c989379498c2a09036a6a85a01049eb6bc5aab41b412244996264e136669827c9e61b49d6b9981b25342668b7ae44a0f9f12251e4d4ac8f46ed090822d70473776385c59e2702d82c1e08da3192404e111261902090f4aa1755096d3ed44d0142a3135a9082a75707ce0f56c77f273c0daae8b2a147abef9e69be69c36ee11beb7ea1ee172e0e393b8104838abdbecaaefbbaaf6d6bd32509665492ba1c3a11a6595a5d6e26db15029dcd18ddd6b061ef9cb2931e572642e3796e5b8c97b13527fea4fa5599f3dbb3abc93495c1448589fbb2397957250f7a6536f392526299d7a2b734a3935ff756167688f27b4414e09e764207a44486da72ab85cd313945049e64832a774b7127973ac1048f8ceac477fbcf78ef7a667d08d95a2a9b53ba678e2025d4459addd8ab1cabd751be7f4fca5b9374992977482e5cef34449726f132658e8995362e259c12245bb71fd8dab2c5d6b90e5c9417946a3d18256a4d0e0017a5dd7f20c4ab1a20c2a510c52a8085a65207a44d08a0455049525cdfaf08b0669b066c0ffea588a92d5e2a98a20db4a6d638945343676f8578717cecdbdf76e578a9b87b95c7ff33769076ede0573b95c375acb703edf88c0b971d158f8e5e33e1e917302fffe8ddf8e99c7c731c4ac1024024b7621a0691a41960f8481c960839daff32766a5f1f4f4420c1e547a4d8c3c35cdd0e44811946ae67412a347baa300e176ac7082151419633c0095420e19bf9b122b2fa648272fc27c80625f60e3536b009282122f60ac5cac3a44e0d404860d219a04ec1e9113f08329b9191fc812460062724c3298a48e84a086750e0bf61305ac71e2f26434a5071621848c13522fc7549a1a163f00c076f2e5c90e75042c3b629461aa01bc410a902ae984dbaf7402630dc06e7201108a5f1693a907a712f593c2711b3efe90f4b0dba81f918e74b5b63eb8b73856d18c224dcb8b2a49c7f847fea5630c83218aaa04d9c871b41ee7041ed2f0cc43ee07858a0db8fc3ac62a158c6e3b572ec10edc57e7eaa0a2f861cc16fef992bdfa4f16632326ea61acdfcd80367cccbf637ad45de747f50280aa4acdf86f51c6df41c6bf817c7f8225dec50cc3300caf388a3a0caf9886699ab19550dc2fcd752fcc3be39dc2a3e81383e11d9c2d54cfe989654f467d43b26b9b06c89dfe0deebdf7b6ed71bcd96aad55ad63589ac02818c9b75a848b77b7cd48816b13a921471e17bb8de2922482ec362a8908d7e9e15283c33897a2cebb8d8a21d8d7db13a5ddbdf7de8b4e055bdcfcc3e39121c30aeed6eb5bafd6bffe4592229a2ebd54e4d92be51d7830446647d02c611f5eb673e2f5565fd31394d495218b6a1445f5d851b4d56a71143d4dc86e5cbcf5f3b21e1a79629e454a15d46f0a29d80277746387c3e1703fa0deaff7fbe18e70c116c1a0d006220ba1df922b648f085a091e54cf89c74208873b420212da602818e46329240484e2613a18aec5424f13a609d2048dc35e3fa97b21e6553b740a77740387435f38dc8bf5fa174bfb56a0a90a1579f6c3bbe087c72343a6151cea80e5c1d00abbb2e71a0e29d75b974049e5f76008c5a128ee8895a2e8f3cc27eaf9f53a960ffd1f3cc462fdfd211eabf573814b87e39cbb582cadd1744982cfffa1c3bf3e3f089c5204ad044d820e2f9c18ec653ca4600bdcd18d718762ceb34bd4a75c984b12c332c14697caf7de60ead3fdb1890f77ef39a5de8c54759f8f635755d116aacf9e9e1e1630d4a81e3b520a3725a626313cd5f3546fe87975a8868b3fdaaedaf3faa26f8e6708241cf7ffc15aa328caba211fc756abc551ad35aaf5992ee198e9d2cd67970c842cefec982bc663b0bcb3bf15fbbcb37bc25ceb0917ebc30186119c5cd06df1b55085fc6200da1003042a3015b92cf4f8717f309970efbd408090f05da61e24b6dc7befbd42cadc7b978080b9447adceb6375efbdd83e514cdf7befc576ed38eb9ea5d1acfdb1b39f1e3bebc9d6ceec0fce31ee0306032928a4790283941b442a58a274758657434e062260967ee41f3e0a90828f950bc6191bb7164018f213cac184183ea0e58718a8201885574dc02fc31888081660446404ca0a43471a1b5b4610250726aa2b52aebc9050c34760b00af7cd302c430ec2744c75b6ba2f2c92a98ece167e623414538d653b8df9f88b6319eed004b77079992386d0ea538fa7cfa540869b3eb1d41d6326c618633bf4eae3efffc9e3bee3f89fdac6514c6d9cffc838eccb9f7c6f6af360db60a89962a001e297b10b72c6bf7d4c7fa8729ab88d770b9670dbd0ab872990ee2e2c4f6870fad2468c0b366a3c3c9e80502358630456b5fb1cc6672ecbdbf0fb3f40f96742938ee75a734a4cb7e81615155d15195ddde49472b7c895f338b95ccee3e4e07ccee7e000875ce9524e4e1ab40257608b9cd2ad45ee165d9da084f65cb39d1ffefe825257a6c090b1bab22e974bc95503e78f3eeb89baade57ceb5bb85c7fbf852b1694e2e2bcf888e384f37a9c1c0e0ececbe5e2e9124e2b5dfa90c34a973c50009ba0242f787d7e20a00f391e2880fd043109623db49fa0bcb38b724a4c6649c4b14bc619023fbb8d0a13d43911a60adb51845b549826aac6e6bdb23e3892581ff1c5986e1ff3eef77aebda2df6f9ba7d7b3e5687601588caa3dbc739ec0cab778d9dddf10517e147a3db1f7161b032fcb673c40d7d185f43d31fdacc280626364b9c44e5d12f108c1bd2efff5e0045e8f76974ac62190c7604766165f8f1197bbcd24619b7204abf5fa5dfb7f96c5962bd601aaa6418ec6617f6ec2a265df811803fa664070a02a85c8cf5779d8e9607e74e275b7c0ef66bd0e3b6dbb7e98e45510c310f2fd19cbf40afca64fcb286c90b4c9b21ad3020e8a86a8e516066941674316aeca1fe32021f80975fcf9897474cfd660b0309ac18cb6cd6310c3090d35b95deaaab5e9b2489e5b18f32406319ce8173601c18074625b0ae59736579ecdf2bcbe3009bafcd46b18f9564d2f23aca00fcf971da736a756c63ee56e1ecc0e49c28bbfe92e79c18d557bbfe57bb4e9772826cdec949f1643a5a6cc5048655ad915f7e7e0904e1b696a34bf3cbf00a96e532c622efe41d263cf4852b969180c26d1f3ebe24ee0d75186ed7efe822adbe706fadc52d8a61079c97a67b24867befbd3fcf422a7627bf16599770868c66902f89dbed872b9ebdd4104c58155e5d85532130b40a83a22adec4a29e3fdce254cfe2149edd548960aac4abb1a8270245ab511d6f3d8f463d8fb8f1a8e71f4552ebf2fc3cfbc9305ee64dd0c4b14f7472ca331129efe4cf894eba5e17773dbf4d5c7bfe12cd0077bd7d6bfeed2b4f78af679fe5b13e3a987d3d4775219d2afc27876b9e51c0eee49fc167e697f3db4260e8eb39fcf50c14e26dc235fce5990580b000a68513a4bc08a1963f04e6190a17d244054b405374a4963f5c435fb85a9efc1a40e1f8f576e5749770edf9bbe8084675c175dbbddda28b0bf71a5ec123b654cf3a37419829257614074b2ec0f81191e5a804cd9be994a1912280822200c316000018000a8483a1704090047232fa0e14000e5c7e40684a3a9787a4c15010c428088228088218a38c318018628c614c11997676602acf413e8856a621e6243a26b534c423f4b368a0e7dfc804180b3a11941155c19bc3ce34b384687627053b304c13e789b0a528a85e39e1e61203a02138d391b7443a051efec5559b68935640f31aab70f424abb5e619efbb2e44369394f07b325abc505ac0d4f33adcfa29a1c562bfdf1f159830792e51a4b7bbfbe4505cffe31a2a203f5c9f20a80869d225ba185025d0936aec19b6e5204f62ff3d0454cf539d4fd3ddd0ab98e56d4b12f105a87e379d786fc6303166a3a19081c8a092422ca91b77c4c4d580b86f2f5ab7b9e79bfb61725aaa75356c60cf7a505655ba8314a627a7afe424caa403ddc91005e831533a4689fd3f4864380c40b0629437fe25c24603e0474e0ac1d24a88d8403547d60651a73c6b53894c7d1d81a35f1fde04f539aecf676280fd4156d35c38256c5e9910a38b79df27028f58adaea7645ee7dcdf3adf4ec117b509291b7a1ed2f59b5447da06acdf98eaad52ee523fb661eeaed9ccecf211a80a216142e8a08523228c815e6145c9cb299a96c80e72b51190c6188e37da72857980166a7e8d537437fdc83e7a602c638f9fbbb5efc5a972afca106eaee4585729c0a728ecd9c60d4620192d90195d67b2aa8b3c4e2ae2ab938258e2121615e980de2005522b4cc0dee077019ed5e938b3a8a44fb13571c417e015198c34f01a559737d2a88b84abfa9d42fd374e806e2abebf5e70cbb8f5e297017453ee674518ab988bc36b9b5c72f4a619850c68bca6f4853445425477a6a74250ca4c8aa4d1e9c8e39ca29074e7fadfe17cbe9b22791e8c640525b643e84ac8492a7226466767c9d36dce0dfba898ba6ca6e175b4a06a3cd8230bd57e24ba630e38200a2969f808708fa0d2edbcafe9933127dc28e53566599ce39e6640463f91140b5b408b95f23e5a38088607994caaaaf66ce7be1accc270abfd51f82e1e9cfb4893a95937f6879feb0d881b1d678a984d7af3abf35b0775b4ec63b640027830d8780d0f29b9313a4701df62a5df05032238a3238d967dee53cb31d936a5abda067830439ccfedee4d7613bc99a00a6f7e83fdcd8576ce31871f879dd67cd22eec499631f5bc7021b48546bcb4aa39ca0de18007034f45e554b6d878808fbc0bae0087df3f8ab47d6de56591ab2e65a7106066eae2e6310f8e0d4e97547c42fd9515ce9b846ca6846da11cf4490b6dcb8c7392cb8e524f1b2b594397c1252ce18139ad719f203a88af09e6828a05d2a8e146ea53357168231a45823b8a501fba50612e2b1631177faa82216ac9fa4ee02939bfae464e21182c3302da48b54462f9271da05920779e1b1b42a8561e8a418944d8c8a4fadae9a3d1967cc28a8d69d72763b482c6086314022d28f3e9dd208bd41b9221614c0717e27d4ec6100c46700a030a4a7e4799a75ec4a62fded40818267ebbf79f54b69b08d5374c189f362bf4a0343fab06e47831880a6bdcbf2006ae562d38fad83645b0042ed67d409fb9330ca78cb44c434aa2daed990978ce4060de3d32fd6394c1310247618c3dffb934b58d107d8c4531e83ac5f8f722a55f40ce1904314877d8a811b76c10b98a90db9b54b0579c38903ac814263650210889287402a9eb1e37718e6c95d33c8ae146b57c96ac985118fa8f27b396594283b528837538488170a443fb9326d5547f6894e0f404908617cbbd2b2cc0076688a371265e0ed554fd18bf7690caaa16c85cb0bb0844fe19ec88dbc5074c7d25788a7c7e752b47f0162ca9e80c32513f049f338140b2e05f6ec3f6fb432ca4499c4044b004bb74a0533f7b3152893b8b22c32804960b30dc9d12185c5071eb102af228ec347610204134caaa964094010ffb0b15a8accde5a4615474f6fb0835d93a181594321faae838993f91296578298a9742e6c9cc89e280c306d1bc5cf028da0e8f0113d6fdd65b07395134d988ba8fa1eccff33bf69ff360e0619e0a9f17bbdfb7b4b8daba6bf7fb0651fb399a60b471f77bf0068a2d2c9a1c453cb7bdd461b88d512ab1d240d3eef7fa856d0e6aeadfb9da394ef56fc5d4bf8550596ff8c951e0016ec518b58d3cc0d50487342ee0da60835e169e898d22cdc1333cd014d75ee5a2459221cd95eba6fe8ef229e256093a19d48f81e27e31aa3bf863e57612d63f3cd8c35b78e233088c9fa23d6bb5b5113c2871575c6506d0c4fc5b18dec1eeaa9066181a373aafbdd624d741be43ec7c67641442892946a40c128b541e1f08fef781e8611e2ff2cedf9eadb767b070ca00e44c9b5e1197566a3f26cafa3ffed42df0b676998a816f0c9667e2fe8a49c0502c0d01141c15d0d52c38de02644f4a6a2575e408fba34c1194c0d0e2663d5e57f55f77400c7cd0d296c13aa37411d47d7de07e0583c2d506e5534dcf54e066b732c4b22b7ab54809f564b76b52e6d10ea08d54ab0085e18c80534c719b27f9b006486a0090dcf982a7c272aed79be5a85920638eb324112550b2d1d93c696b39c0b5a144455a6132bc703b4bb7141fbeef8a6058ff40f07c8168289d25e767178796dca97864c18f6a305094b3f410de510495f5b9a509e46d23523a1218563414175cb3635399871f6fffad3fa0981a8094ed76bb161e7472babe14658002f73a29d3af3522559e73358bf5f9b915962c7ca3b42b0a8662106d0ac2b054c088d78941ea7441f3e71f92e553e424afece6dc30a451f45276d6591e22bd571a1091998bfd45b3147c0ca225d30a899953a8d2e743d13ba469e78ea715d407bcc9db0a0199da523203bba64556604f777762d9ef799c388ec82c97be955aeac2f7047439149a800b940e98343cefe126f524f4c15ce389b398d1c0648143881c968d30f05cdd51e5201ed22a4b65704fbb80ed0b8bef03d90bd5efd143d931cf2b4bf98af32341d4a92224004744e9775b363fe235bcb79b07992d451c6fb2add3048832d53b034d193fac883569b9dd728c675dd6176d19a3e3ab3d2dc2535747f311a90087c75f2deeaa035594c9d2613f8fd14017cea5817a771895604c6107f7b3db1cfe4462a3912b231c437d5746b380b4bf1dda702120afae8b420eb0379d131b80464db56b5bafc52e8c478bb49759d202bbc8da8c40bfc3bbb52532201d652010a86ef0eba4db74b8044f2c0881beaaf4ffb1d55edaa2fbede5025cf4ac875170b515d6f219125d9571eec5838bbbe34a055097bd0fa785ed7e9f8c9a1c289479f3167688083315b6a12f4a6e1128aee2baa3f1884d2612d88b4f7f00d88ba71b37b9759edb5612e31f67d523373666eecac95a012fb9901bf0bb3b79d2efa69a6c2a3ebf5e043ac08865d6346e71a69f9fcbe4c3face88a93862862fefee6bc0fa0360d06e0fbb3e0143fb436feccc0d82e075ee7a15e717def275384b31f969caa528f7de91c704492585504097e606223660f7bb4ab7ae8b19c70354c0a36f55bb804ea2312af48def5b26e388fbf6c22efd1ae5483ffac7520245fc33f6947de14d326be83d40a7466a7f766e8ed117b910076fb6a60a7a8956bf0c24ac304fd2e91d3c9904320090cb245388e49b095caba76a3efd9cc190410f5ca943765fc86c1feaf17b98b7e4fc3073e24073e76f09d8e8ffedf85376ca3f48bf11e711497bddb823753c95edea9b31080f21875edadf4175d39f15caf3edac49615647409688d01a59f2bc8147101a079db78e3ee31fe85a9f12a47dbd6d7a5fdd11a114bbd309878edd9a57d2a6a3134cdd3b74772822ef4d4abbddd1936ed9fa6b0392ec09dbae230f893598f20842060b9e13a8b1e695cffe1209d955992cc7b85e158a569109fff42aaf93d6cf1463c8b1e8c0c62f17c311e6c87412794cec08af54ab8d9c53e644422afc9ecdebef868a4ce4cfd330125452d00876e6a5823e8734a7a1e2ac08d58880ef7e113dc88643facec380a7ce5f426cdd99f2f2d9c749123068b7bd34e60ebe01fe73920be59eb3c2533a50611dd14eab1f2125b244fc2dcd51a719a13fa989f2b8739b1ccda08292c4d24d9a59b8b56dbc9e0068eb2a719793048816c5091305195acfb89c01e0b59500851b306c753f9a9bb378b5fb571180b12431b264dc2e3310d7bf353894a3c53df375a29381b5017d53bb1026d317783153181ae247b0b171e60f7b882b0ae9a965e54cf1d96b47e43c44639d22a0897c39e523a78707a9753a322d8fece0bffe43a54b7014f63549be172867eeb84f91cddc099da7e276665c882b070673889f51652202fff158d3fb68fbe34549f99bf2cd12427db221248f00a049606862e3dbfdf22ed177136f4297099c96801fe00b5bf4d871322729249cc965fd8882a0125ce625620b600e2233d7f026e83818f4e2afee937f007ad38f0f5202e888bf8d127f81566dbd0ef33f223de621e6aca2a04a6cd01ca26b94738fe674deffd5ffb08e178b3668c590830e718228ab1672043f9cebfa19fa9b7b25d8275226ff123afd280a428a4c46671ff9cd0ec371c2777f888ddbf5f81a54d2ea0b5e4cd9d4762216d2da6f540ccd132a81ddc4e266790f9a90a2f4f6b5c7aac9189e473fe0f978d7e41af6b18abf041b2224f61b3262c608940a0c2ba1c8b74d9ed7cefb0e32e5ce7eb8431ff81eead48fd819e1e8f470c4453651f58c2aae025191812006befa17a0a051f17027aa067342002c2b6fcd1830a2c62020e0be0882fb40c9209c74de18b07d3b9884c2545e86cc95f1d3625133da93b08f85052f2e9f25324998ca9d4d2d678ac3cf8f7c8187deb8377879469e21650412088f05505756ba3162fd336ed252e6e76495884dfd7801ef06895dddb2134ca21d9acb85ee07e588c6bb08d770788ad518e1bed0d707012e4b82b78f54e83007148fd180978b64eed5ae9371429995c77bfc73d283a641af36f942537e44ca74dd85602092cd15d61fe5f9804b130fc8fcc90097ce9a17f394cf3a20cd39e9850b2a0eb32c2d514078269024b8cf7eb837986f3c8cd50d2eb8817b583f0874b5af454ad6dd1449d85364db6027b89848bdc02b7eaa3cce0b8c55e52e2b714352e79f002dbbaf5e3a6fbe55d202ea55b9812161b5c8b3f7497c7cc7bbc0d27a108ff41ccc51d2fdd5101bb7a6f0805f19174844ff7a37670e10fcd8821c5b13731f0220a949c970667b904189427e1324ea91a70ab8baaa796493d06fd7d08a338a405de9132ef0243f760f9e9105d6ed75128399cce059f7b929f9a2e5bd98e93261c1aeb33d6d3038c0fdbda70683e3a79790afa0ff97b6e1841728ccf70294203a51d416d3015d700871ea78ae026aabb630210cf45faf33b81f7a2f5292de1a4f63935207effe9f8fabf60214b6080d22ec3eaba9c645c036e709a2e2223f17212d57964b7d5981cb86aea2fdab79c2aead91a77e5f1adf1a8c1fd5e66a124c3cac009e8bf8c8564be9a0809bec6a1c16602f45e42abd37f68748484411bcaa2739bb4661f718f143df7eabb588888d5d312cff521c8a9acaf1a0c3a639b59569433a4e5d55f38cd1b055f32143b185678475f558fd51429bb189dd8e88ed3fe39a39626c64ec9028c28a5c4eb59834982b3706cb3f3a364e1b0c967f7b8e478820422d6b82475824a90554f2734728521fd3ff11f7d598e3a84df380d820a52d5b77bf7ae4ac8531d381ab415d8423d546089c219c4b3642008e9006fe109531ff14d057ef76ef944d6390c4281e2c675a43214dc118e7b6c9dc9b8df01c12298783f7346b3bb6aab840b715d6d28163c48127af9c680ad2ff6731d7abe3d4ef01b0d03fdda906f3f4a585d70793640799e1886063e6291a037f1433864af7cd38463bbbaea5d10e901d4b44b50c0cb72d57fb2811c426db07e7169cf4d37d22f336702b3964d75480c456749d3cbc158dd6b0c75fdcf94439c3a24112c404e584fc423ad0b826dbdb3b9f6112384876784e85772ad644772bad4455e9b2502a732e2e2cd956a38d06176ae3e7123449a71cde23dc313dc9d3b893d69cae408fba1d42aa1ebefaffd115b1f5a47c717849ffca567be55a89125011caaf5ea24abe749d2cc25e9b79ac44d938c11f5d39ea18b61b90991ffa90200c417ea1324d50a837b760454e7d37e308f049b2ef52a64fef5d642a404bbabcd543a6823ce83f53b20f717114e42608e7d9d4de48cd050a440d4c9cd79f0fdb8a7f5c814890911b90698d9812d75a2b4fc7408fdaca1e05b76e56912af0378d29e6b402589c8effef702f6bb14c20f5cff1f7e21731f8c19f2959ec4e9d1299484b77089312c20542b5b5a3654d401b0704814620b49c87a96b1bd0818c4406f604789c42744c140f8b1d4bc1646bf34fcd0d2d03a885feaffdd99bc5a8b685914af17a200e6e8683e7ae7fe26d3db148f4292024907cb2f18a5e329c6e8b89375db2de638e80e39d9f8f0ead32663dfde53123a690dd5a38970b01d02813ec9513a242b1b0e005f5a14172c08433009080da324974df1123ee6f4a9d5bee2c999bdda663b2211e4a86255ff8da0a9093ab98dee0f89aa4cf00eb84913f6f98f769c8805781bdd6507669323e99791bf75436412be68ced6deff6195054310a91781266c4da38852b86d779ea37e6a28472647e43b34f438eb80bfc15ca6de1c5db395fde7baa09d4b3812ee4ee0ef0e91d61b091b3b094b3cc781426aa7df35642ede71fe4f523850c5ccd5c071846db515d0e69cd24b62054e24224c556cf779e236fff8d4232fda65cf60a2b3f60a411ec6d53fbbd19ba5f0ba2f3de6c6c54cbdcf7ba6fa10d5b942d54172f629dda57282d4986c817156f4c2f3cc634ea2b79d5297e61ca5f5e2af6b80d83211fc11ae797d91d08685ec424cb684b96c7c404c9c6e2a808b4a497a6ea0042e8462dd1822c890cecee29b0c7ad6dda0376fab6d5b4eb6c89a6af3472673d69ddea6eb19680b75894e379c7ad1d01215145bbdcfb4e9f46b523d88dd7bbfe078cb1de3ced0662c7b3abd57c3c284cbd67d1910e52c12b2d6ec58afddf5a24a5d00bb291ac8023dd47926df46438bddeb836db529d8d5c7a8bd51447caa0261c56e15d819c7c287a8d8b15dcbc330fedd5a599a112859d83e763ffac8c42f9ec1343cc120df4f4d494162b0c596469ec95f051d59ccc8db4b91780358bcb77054e1018f6e1bdefd4bc828292081e8696f0ee0abe3bc9f3e1817b363d42bcc86e09ab8564f63cc11b438a9309706a6824239fd0f4c0cd0b3a6e144d902d75f9aeaca46f1cbda84bb8af114bf2f53f5687fe53dd1ce75728a9a3b521fb3897e94b8bee07707cef8cb83acd0a32d0847abba1fac0b8074713fe70c9c177a11a7667bc5653eda588e7647c18412c2e09b237bc51de897296ce2301834b4d265c20b981e7b5c67ac2e5ceb255b0a675d1f504a197287aabec68fe0b57db77686440fea7c63cb47c1e831b5d2f2088579392831618eeeba97e6efcb9a4cac081ad93c9e65a4ff0d163ce93d8eca2df4cf1ca7e4bc8e3c6f3d7e34c4f1fd03a9f4a47b01e92625a8ecc3ba373cee9b269ad495ffc0215a0d325f2c1af0c7547e1d79ef8598f71b2f913c1c333dd4cdeeca79fb8b3f16fb92be9a9cd4c19ad6bbf1142011bcf60685504f51f55e5b5732ec209a94f9baeff0461e4971dd7f139d493e03bb5f1534d17cb0078b7c3b778290b0445e40cf020c8c6f59f264784f3254abc100fd1b7dabe93db17a5a3b3509979f8c9ab111bafce3a201fc1053557bd8924098753f73f8d4271c92e7ddb042843146a5d70cbacbd4d2053a89cac1c5b348cd0a79179026a80740a63b1fcd6c922341d94c6a414cc3a65643a6de4236c8ddb6d589c8f4760da1ae28599e4c606be650ce4129991b3b2a23dedebae6192bb922c8a6a1d491a6ef915698451b6ffbf52fbae7b63749acf25e474914d8edd92fb8019de9862baec17945155f8162ec5c7216a48041b47a0093bf9949116b100ad17217d24aa8dcf4316e9503ca3b2021c93612f1fc7bee9caba00faf7a1705c800df745c1bc026b84399de094a5973c21d17f217f4e0404acaa06db07cc3cf8bdaa24a9d2c475354d50847577cd7e5cca127935ef13bb123f6e29d3e3c361e2c8bad40b645f676de9853ffa392db2fe6f0fed61889b218bbed878870471dfd7cb3070606f13bd455dbf632069cb5e5801c36cc3c74cd9270e4a750f0b6f69443d528cf4b5e394fbe53c7464016f6c7dfc0bdd8b13c41a6045d7f433b0042e58596122126a286d17981cd257e471946b3df629574c020d7548a19e1368a887e511b7c3ba293238e0684e5fd1e2a6a763f7c37d7f2ff461056915cef52f6fa932c7777f08f6e6d81b63b14439ae4784f52c613026e603ea7db26e1c04ddfdd2afeb7ca7559afbb7b8427c1a3937f3c70810a0db53f5268b890edcb7519f384fc8f5141a5c821287e8df5379c9794f6f807effda80197c191ac043ce905718b52926dba8e857afb00c9f12921b59aadb92aa0bb8fbac691f665e0b31ff6872a7311fa643727400a1c36ccc24e42fb71b73005d267b2b5e3664dc409548f80d477737459d06d5d08791001886af27141b38db3f24c20e039b04c708a5a7c2c0a0d1e3e57cc546a4176b6d90f55b62a9231fbe2e4784e20e305f873d7e35e8b3243c66573dfc1d3cfdf26fdbf76dbf246beed92dc14be02ab828050d2e4d6591aac7e0bf37804402caab57f6e53aa2c7f5fe9934845ae5449d78a0169d6731cc727af0969357cc80f8ac94e946b3eaca1584f816bd80bf8b9d6acb10d68b81271137502b7e76ac404cc551a1a741ad08695e12cd045f01c452c378dcac7a508eb85b06e54fae439aa070dda8c177dae3212009fa4639113ea2181f31310ecce7eb4646e0d00d3fd6074d98c0dbab78fbd3cba16713b1d220b160130156280b59b83f898bcc6146d2028b931ea981aee703bc694084ea88bae3b7a36911be2852347b77b1e857d189b4343c416b09a12152e1dde9a1719418a160910471016b94df9294b5649049e20780c49e722191c6c25f5631e999f71e317d0bb365e92705969f6834e6d25db9b215bd73b32e5247c4dabaf312c9099b1112a9f7c512595461a95842a60e4d354ce65d0a2212eb904587b219b6070fc45a8be565ed88b547f2673a3b13994376ba0ab93a29c9b277726640fcad2b81803d62063162af945863119174bb1d8eb6e774003dec3c5f6fc587ef494d4aa02733c55b8d46cdbd21809eb2427c9025db23fba6017d98c2dff7c529671f7335acd4daa8c88ac7fa7483407dbb4031de21e28bd2c30d7ec9a002248baefe86a97bc4dc32f146ac580f7f40c683de03eaa07b212319ee62e51af5ef5d4c0518eae2eb79b1db064c6e430bf3b3b8a4c25a8aff9a74d8430eb9648729d0cb2f6a6c21ddc8cb61a8865bb88f87a6fc079bdebe557aee5d5018f8919201acd1794bf50b6e9a8ace49ddc6da6cf8c90ae05ee5eee1087482bd8898c70a17154c4ba8d8fd9b282d218eee0f79a425d4e75866cd7122c24b7a5f132577b3f6e4cd45d84a7e60842cdcd4abedfdf68322bd6a91970f28203e27cab9bbbe6708bbe8c9f005b0cbcc21c70b3a7094c7d75905a1b5aee0b18070051a260ffaec88cccc650348a5744de53768b04ad1016871407751c1ed763dbcc60f8fd378fd9e1dbc9aaecf19837fe605c9b30d783702bb93e1d9509ddff1bf5849e0d064856a35e5092b252d6f4ddb52adf0581921f386b9240d6e8ea141b92e77aa5c172a2cc10d697ca663f9e9f917f743cadac6facb1a90e1b3b857b3f501e67f33c6a4dfcb20077bb5fced118901553cb8fa76195148b9bb257f1cdf3ac50daeb1c7fc54cb7ac761b1c9e489ca6dc1938eb5eba3019832929292a2a4a26510ce846c7cd49d0bac617fa5cd8d5d30923bb173af467625dd4baccb79979d1c640d1279f9c31bad5ca965485cc878621d847f831ebc534e26d1c7c89a433f6f18eaa0d429665d40f91d27cba2a1accb0e2395faef2e36038319f1157f749b680656d32556e30529ec29615179a2fd04466355904253f833d829da50b4876159b979b93053eab4df7373eb6d5433644f99a92dd91d996469db01c5a3aac5432ba307410bd03e2be9462df1c0d13a63b485b2d26ad1bf4dc60ef31cfbc53ebb5876c5ce7989e648d6d28bca5984aed788d4b746d65e9b4aaf3d34d019953dfe0e8f0dd00943abca1227fe348a4a2f3653847bd095110fca6968d4c3cd509a64b2898b4802f5e7202a84331bf768480b7f88df9062011e01a38511c7a701b51403e34aef11c52e7db0d993aaef08ff0dd2d191401674dbc128efa1e02e3d56a84dd401f410cef257a660f9b2aeefa838f346152ea4227bd74f76b9430d605d6c3b1fa846c0d42b642ba70fb134fd06e4f8c6d5b7d46e0b4d51e771ce503048f9a21bff33dcf2e4f981160d14b0af350c3e3e89a4d0e82462f16710ee4d21efe9345516c910bd185b0b7a9e92573304dfdff0184f9f6c1a5688e99db08edc1e42e1972176deb8ef86191c3ac49a626e46b4419d0a6b1e851f80c471878e1553ac7951500a31ebb0a4f15908ff89792ae7ef6737737a8cc40ca97f85c908f71dcdebdf5cb10ed735c9aa5923b338a91cdfcc036b664a090380b53dc7afcf711a6af4d31ca2aab117658680b9ee21797a1c0035c3f93b565379824deecf5c1c56109f54553b38c13e3951385f9e385e2ccd98e739bfcca4aad501e975e6a5d0dd34b398e9ca08a5ef15923a5bba2f5d477816e3bc7b7ae36d5ae22be3db8474b116b8303322439b960d3609560e930d9c09d7d7573c9fbcf631d64f5cc9b15ad8ea64b0cea5ab5f59c3ad8cc2c8f97a21071a380f2c6d36b059bf340468d58b13a8a9e87e41d16921fe3d53c0000c2ae62557926e5cebb5bc2a4e7f6d1ab93979830abae80afb2b91916814d400fab6ba7bfd15cab7aec3612839604b676ee6aa774a0d6eaffb35ef5bed13c1df0861fc17eb4819dab54effa64a4d426d0bd3826b552f59b1ff29cfc416b69e0fde0825a164525a645da65b47850aa8a4da3c5b58001a6499d85bc054051495c79cf1d99dbb77db0f425925ec5959b587f045915d2245a45ef76cb827b74569f6610b9ef210db2fbcf370efe7717f3887ff5278b1905743ab01f6c22d2fc1d88d85b50c4f47d87df31e710782513af173fd0ec3cccd971c5bd6d1ded010f35855657e82b97c3111cd23b36aeadce81e44dfeeacd17873f1893b92e861ba0f96d7030b56cd3357a9761e66bafb0974d1220ec941dff36e144ddc00e5d671b31c4226144004e1430868249eea2e56c36dfe3399b6499bdb9041f4900f498763b45949f138f9ff982344049074ef577d9aa9c4ac8f02095905471e6b3e4c9b8acd821731e17b4bd883edff936ac6dc68fbe0bf293edce08522da5ebdcc7e8ba114b6a3d61502eb576e33ad190cb4ad8c035ad172c48dfeef329d1f221691e7ab1dae9b9140e9c98b9b425facdcba7d261efeb9507b109977a0768da39e8d10764bd21a16488aa2664c9658095eeb20ba80f06f0b63775c4f313cca135e000ee3a9c45082f5ad49c0e1d5eade35e5bdafb9338522928abf80d0aaf849c91eedb012a6fdd7e87d24349207cf23f0dc704077e77e083cf17ca75b47a3a61500311a9f1a9b40873a732df9e8d919537191cc0cfe11ae379be26a6b70ca7994d9b0449e0212a375cd39c0e2f5a9915262985bb5354e64a6eacb7898329dd2392e2a2168c39748a497959955e437f554c5d5cc5b09a335ef551c9c63a0da509ab9178da4e3e1326aa9397bb4396179f1b64b4673c665a2e5b72a75f839d8a4fb5bac192d83e0082334eccb80b6a1372a74f50a8bf501bad4546b5a39e5d2ac0ac0533bb8454faaa0dfa469674b9ef2735133184ac2f4b0f7cef5b9521db8feaa86265e029ecd2ffa033606af2328b656741bdd48586099d065a20ae44f3d38f8effe024921674ea490e857e71c30e95deba821c4e6b8126dee1787e7f660c834f2952d28c0b07e5dbf7739407f270ccf014da336fd9b412705ec17ff912cc3d3b7b256336020c0917c60b8433965067d9d19263e8b3c98fcbd31c3e30bc15e1af52db39017f50992775385635441c5246219c4dfee88d15d832f0e9206829b21887ad5337f443f7f67739d4ba27e656fea7b5367541fde527e390a1bf2e8d39481eab09ca4100cb659834551f8c338aa83513c4cfa57021be180253ec67db7943124603d28e94dc39c5b81801eabfdb513a671024b1e579a4e89a932a77a1eaaef58e66c9210d4229f35b6ae1308e69920fd04e51f2c8be08830b5bdbb9d08f211a17cf96e26b97f94d8c1c905088e91e12703929a4ffc18d0317226d114cdac70861757aa556c370ea02f49b59cf99d5ae7b00a2c2739b202648946e87f03ce72cfd22a4722e6e3eb7f23e2d19b2f996813c39ba3832057a9b967497519f8a34c632a4f85f1f9418e6f27631c2990a6857ef2a31365a9911f17af631c8685a163b01556443f879091f1657c54ccc57a70ea2788e20602c914110702bf6a7f59d04c04c0ef1464790ae9c4127009c553f877a16e6620bc99b0acd3d00fb46d9903e9f8df93169ba1373c5bb3e379039d367e2f42b26bb31c5d76c946006a11546a6617a7bbe98fae7512ad66bd6c7fcdb55630e39e9c45c530aee4fd85545f88b5753f959e0070b921c2964e93938f7c7972b266c02a7eabe8425f8d97f77c58dd87b3caad166e2a0b588764782ab40aac0977a5d2fb51c76e31d6596350e87c568cd00d2e352aeef675b3a9e8e98277673bc7d0f2f6ed77403e02fe24560af127a928568e06be4e4ced501137cf1640e8ae03b1fb055ced83281363396d19cc4c9b52be224757c1857bede0cd4b2d73c8c9a94a476c19d2377502fcdc14722f906252fca8e7935a78541589486e7583216cc6255a82487e31be1a8f257197318ac43c83316bf292a0e93f7f7456fd258adb8d24886838af99045ed034644e4139f084ff39567340308e6062a8b889a0e0d48ca973ef8ad5afb6971e1eab2f4a8589678d5abd1319435b9948a9199935df582d55422e163bd59f4a74ff2c084ea60002820bc326d64f02f8014bdd6e63750f93f838938218e2aaa10b75689d2cacb278dea1a49c69234a128a16032717410afdafa74d516728a7283314da6a09fdf379b7b56c854ebc8cb4e44e0f45fc25c4d022adf3de26792a70d9453ec93be8e81fe47b92203af402bbcab06fa1b30f5e8a790e2be9bdde806bed3c440cb291cef5dc2c748e4b36db498416422f253602725a5542a051bdef09a563a3aa3410f7478510ced070ee115849c99c975966068e4c96a98c6e4c851cf65be6b90ba76b4257910034de3489f76634db6158c60b6e68987e4d3e0ed22de8a5c2eb99cf487dfb0bf5a621fd9a7d0c520fd27bfee84901611f1a8196e97a21e9c95221facde4470f4a88fb50044d4c1718e8d130d69aad0c52386862424092aa69e3a2d5bd9740be6bf9094d87331b9ecbca94e3b26b4c8ecbeb5227481d0070355e608e5acf060f95e4eb7eed62459dd4d3bfef459375eae948bf22b5303b5d648cc4aeb4e68ca959d845e18b129a80dfcc9bc54aae53c8b194b0a86ecf758b21217a57ab79219672fb87042da7db277584bc8a166de6b991d68da38644901d1e5214ba21596bf2631ea0450bf25d979a6edbe3b021acfb5cf1d7bb2c89a0f58471886d1370988ec24e5fe04759a7882e31a52182d235e004edfdd6b96b235f9961692d1bdcb7768c330627f8ba239181e2329354b559077b47b25182e4c06ed3523763b991f7ca3a2a2ed1e6bf46182205e06ca0e23a091642a067ba823c040ee0a668c621db19e97974244450b4a0dc1328c14095424cd715026d789fc397ecae10d0593a86f1ac10c97aa7e352ce0a8d3856d6de73a65ee390ce9ff1ac5e6a2a159e2853093aaf4d8be48b279fcc3513f82f11d24aaaa6430499b153689a0fea7aa96205e41c69b74ed3b56df65960b6845766e54436110711417ced356657db44c0877c151c219d2e80a5e5a2dd665fb4d53cc2187a9479159b63ee3486c921871ece7f73b65cc0dc77537c79f5f88332928dd7a4e4c4217348496f1e4171c34f06df7654693dacbb43bdd1b72aff4efff9017d82bb617ab6e2f55871c3dcce965d947fa326e8ebccc36d586336313aab1aaba21579a8f061b968ae04dc89d4a5a0f26e194974faeb71752ac5e4b6b545ba03d97a6ab043e8c26fdc328ed1a7db0aa99746b31d9bea6606f607e1d48b60e60e99f8518aa273d86e827c414de590752873d42e13d49115de1c1d1b866ebc452eaf9d8331c879321dcaaa10e0c3810da362c94427b92ae0c890089d44b5c00ae2d565c5cb0d11ecd457ebd8047652eb80f46925232b61d8900ece4d4344ac3628050b0752151c6cd638e0c2140f88dd5ca4ec118e3f0a3274f98ca43adf88415d521064e862aa2a0069e4b2edced8df07c882b9efc6a142217d3a1d04f20497c1d8b5491a8ad884df4778d62bac9291189e7ffb14cc8bfd6200afb45c67c187632f6f36c06ee4a64f6c8d86367fb28e8dfc210d091f1f75eee8aa981324f139a9dac883ce4adece27cc771a4d562ac0ca021d8c52f7a3b978067a39e2e0cbb88e896a720a3106c7898b21fcadb944b34a79856286620c31a44b7d23f2ebad639c64567dadaeb79415d89fd961c99763bd7e85975dfcfb72c465a358d43473f291f7762791d4f6899d14fe5ebf1b80e3d721e1e2bea87966f6c36409a04f852df8d61d69c6d735e3ad1a786676737deebff22278e792896429352a0b9b44664a428c6bfedddc040b948d022abb055a5c40104a4a07bf5daada4444d9dd46eef6a6a8731364403485aab383385f2f6c94ce4617a7d67e9c59d2996a79b013e8641ce80fd01e87161e4c2513c06f824452ffe686417a824b10299b7ed0c2ab9f9e2f09217b6f22a594292529031c05e4055505f17ef2eab85b65e6b85afbf32e9c524a39e7ac3d99bbbbdda7e4a48cd0bba5069cba73b84f3aa54b04a8211fa8606319ad278c91618c5d04d445ccc3fe92724eafa76e5272d19cf467706dc9b011ef57821e9a6599b6792f21f6fb0b4ba9543dec317dbf4a686782098658cb5e97998b08e087c11ba75e2a255ea182f6b562b5b29b7d5de67070705233e6e57056b83e88247439272725436371104e1921841046e82c9d4d864e6a465f8e052783458ab5b3b56470d005f35cd87d20b8b14b75110f9b64e17f5526b1f06f1739ecc85d045d74d1e5875d045f40a21c21ad25cfccebc1c01a058e89081a22e46d548ff4f0d3778121e4d3396cf5c8a7e7d5e258b0fec1aa0e5f47cb14bbed54b1f15940dd7d4ef7a97215a574ba3b9d33e574db362c4f5aad5665b5ae4c1ab84beaee52ba532985acd420b2cc679665ee5936ddbd1e9f3059e633cb32f72c9beeffea59a2e22ea9bb4be94ea584f90839d51fdcf6ac2cf39965997b964d77cff338ef8a18eaee73ba4fdf28a58e85852da29e470f9b3d8f1e3fb4a3dfbc1962a27d0fd81093b9d56dce39b32c43b5d0aad672ad56b5acd60ce32ea9bb4be94ea5b410c983213951269c842cc7fd7b1e0c1694653eb32c73cfb2e92e2424242454853cd8fd84aa8fd015a7ea4296f9ccb2cc3dcba67b50d21515b2cc679665ee5936ddb987d116905acf6dcff23ceb59ce439a4e7cf1b11cf7ef79301f9fea537daacf7bf7f3f17a7ce80cb2cc679665ee5936dd5baf2b4258a84cdb529252ea4ea9abaa6ace39b32cbb928a5b9439e7a43e7dce497d4eeaee94ba3ba5d49d5277ea4e9dba3ba5ee4e2975a7d49dba53a7ee4ea9bb535aa9bb36b32c1b93653eb32c73cfb2e9fe5ed017275764125f60afa0201b648382de0ba23c2cf5588efbf77a7a6a4fede1bebe7a1c4a11ba485e0bf60aeaf1a19164936c924db249f6b34130a9f6587a79dcf62cafe52ea9bb4be94ea584c12c0c661fb6d54a59700ada58f1d5031479f86be56861484e5f3468a55acb71ff791e0c161474bf7ab3cc679665ee51468cc8c35fabb51cf7efc1ac04095d29e707add45ab3ead36badb566d5e7ac91d2e993524aa73bad34f675d710af586394546e93c2e6d940afc8c31fe38cd69d1ea0be57ad99ac555619dddd65dc5c4a1919e5d26910fe21c1035d82bd33524add29f52c9b73529f73ce497dfaa43ea73ba574ba533a279d520b8c1e64ff4dedbfbafd97dd6f5379b0facfde15f1a307a8fad1dde78c3156f76963ad965a6aa9b5abd56ab55aad542a954aa552a552a9542a95dab68dd2ad7a9d746edb535aabd749e9a6699afbd4b49fdfeedeacb967d9535aabd74969466956bd4e3ab32cab5e677c12503fdfbcb99f09444477767e2713ddd9918002015fd4a43a5856712546831042086144000bd120f48039c6fb2296c052428e08801eb8bbc317ee5e025f6677e70f738529ce49e99cb4ce973f5333e2f5afcfaef9af53735e2747e7733e4793291935cea9242727d6d804c84ac5b5de434a5a6afa22c6e9898b86b0a2c4e4050c99346c9807ffa091d259e98c53f5a9d7721e1563fc0d84ece39b906d33b6cfb62c6651a72b014bea441d9d6aa4f35127eab0e00dfe99f43fe7fbbd4ea97e85d3452b2a579c12a1b8a2938e4b8ed8535a628fa9893d05a060f92ddb24af73a0c72ef863d96320ae79f8fbd9a1e72e879e7f8f7ce6fbf5d8f8db0e7338805e7c863cf15bacfbbadc1655b373e1a5110a87ac07146771f9c0b4864c0b48f86883822720b63831b146e9ca940dcb9124953482c60d24c7b93016c686303450187c9c45cd597bd2d685595d8a1cad1caa412dc5d883944423c10f32412f0fdf47014131891a2c2ed4a4b9fddc1aa3dbff6bbedc7e6f8a27b71f16f4e4e3f6c37852e2f6d3c041850cb73f071532b8fd22f470fb355083236ebf08f807c66a2045154a6e155cd80489b1b9e1761f79904c41e4b8ffd890250eba8b20352848d3c4ed1d7a642fc466dd5ec0ed7e9b86c9ed87523cddee2758975b5134b1a2201393a2ca74a27d073f40cb5d9e012f842e7887ca031a58ad002e8c09412272940868e458bd13c736882b8cbd678fab308be7c18d8800fe00f4e4d7faf5a9f001d5b01091889183a02774237ac074addc0f892b75b8fdf12f45753ed0855cc0953656ae17e491afeab912ca1bb73fb6aeb42c0e4c17b8162e2b9c2d800bf48042c90d5876a8a10332f01862091f6282b85932b10071864772b161d5341261098248ea8a92281a456d4193e5f2c3f882a68ab6438682c1a62e8ca179723f8814c4ce0b63689aa888b0ab0b63686ab031344652d02c67752e8ca1f1e1b4e67edeec31c3143a2f309ac2da82e4c98a0a2250e87c5026c98e1c2a47622b84f0bb0d44eef0dddddddd1942170148114e5ac8ec88b130f4c1ae3f049a989052c86820d3c4091a9c9022882177f79c22ec676d73920d5370f0411345a200a00147359ab9f063f00febc2a77103c2cfc1405604f8225ef80ebbfa03af1bc029f6c1123a383210cd1fbeb418a30738196c854d5bba38196ced3cc814d93cd1ee631e3f6e642137b2911b5fe394033aee3e98136423998236b9057ccf951fe38c94dfebcaadc919312bb04993a1552276920324567ebf7caf81fc7e71418b2d271bdfe1576f05e24ae353f3c0d7c126881c95a0c2484c1297fcc4a08ac4df46da0942c830b6ccd8c8cc6cc6f6cfda33cc149c51c1fd209216e60c120e5a183168dcb09c3d03c3fd3c99028c82a985a3a223499a9476901c3982810f234f3c39daa8ac90495021625251924248f14c90332f6caccd4c1b3364d46830b6c0c29819fee9e5ce8f2bcdf28ffc18dbf94770e3cff6ee8b3d42acc182a671fcd35d8b1afdfc0c9fa58335856366a65cfafebdd911e67367b7fb42b28d115cf7c8dde7508ee05d8b1afc9d0b34d9527a0188906263988c626484ac60a3d8dd9a32c889993946c6e932b3120d643424a5233ecc1c4de93056e6e9f25b251ac0b01311dd98aae14427dcbe1f0962f7b503bc3ff580161ad89aee73bebb6c26c0104de14c9ca46041421b6bcb2e8c915961056b5a68c90e530851b426861f24709ae285214304d18608263b2c13185c12892b5caa9065505d0655854b932c83bad10675616c4c1a6e492b6201493630690114222286a0e0850930464b48908031f2240420229bd062aa255c504b8c780c1a37ea183163c8b02e8c8d611ab3f4c498a4a22540c620b52e8cb920833142aad1f68115cee975bd71b0c18a8c45d5d6cd766541e1a5da2539db0a159b06af570c8a5810c8626f860e5f18657963b5d86c4b2cce853128a44c2136bb300645131814472dae5f18a34117f8302e05d120ffc8d76cf474861c87c880871ec0108124a54c91160b460c496105344c8248a6314ca8bc51c2ca0c4b5020a3e3871ddc105569b344192c1b5842881f98c24c215a238fe861222296c6081e9c80c82d4e5238ba41c89119323a14612d4147d6e480250a144451925a2098274e7c60e18833422429c25c60990d491a894b4821d2230999273fb0e161872b546a9812533234e5128b3d19281368d4e8101b927465e8b351be408c0c976bc002344fd2f0907282a1015cd585b127c02015f10b9f48baf0a1db2cb7bf055f40660844002166c0c10547aa885234149d3c4939f384981698198a0f6185b123eb10e545dd78658c51b2b7a720efc6da2cca551b75593c996eb67ac7ee3eef76b252948b25654b5425c1ab6784c7d81d638cdddddd313aacf25b7fdc58db0f8bbab7d8a31de7cecda22e7be76ffe2f545ae3ebe060a5b37fad1bdd5daccd7270077061708bbd1e32a7f4875d6d8d003bcbc2e18665238d654986814579fccdebdfec7bd29a759b7bede8ec627466e3c31e6df796ecd1ffdabb65f7b007bba35b59637777cf247cdb99c27eded6bb160e084837fe6c6aa0269a4f0dd446cd5304fe741548847f1a49a7fb3856f7d99ca61b57741f87d37db683f974f902e045d001e8beca41f7d96e751f1733ed5bb0980dba2f3e005cbdc45efc7735e7ea1d573755813ff19ba8dba83f7e23a99e05910e118b28a7fbb815dd67b7c7e98c926a8c2e465f55f735971b3fd549495ef4f9d1e748df04f2b5961bbfba3eee127d6e741dca8d095081752b3438c8e9c5705f3ed894801c6c27b5527c277a10c206279caac081088c97218a74e8a1c214083b49b5d44bed454c1aa71b9f48b369a61b9b4c3bdd7e72865b3412bf76c09688061f057821d2d28edbc119506b7a81c76a959593243715c367959000b9318b854a48882efcbe50e9089bfb5527b428a5845ff8041ed04b94107a64b6015d7480144f9812192ac56e74b131da802f52323808cbafb1c7de1cb938202c3f4c492925fca513c0304b78a33a7374f9c70ed6f9d4e87a983d107a6ac497ddebb8dd0ba664c4e8f2d8eb6f012150008c3a6082d26d1eb79f6e47a2c8b02018377c98b8df76bddc1641033872c0ef8f462b242c67ddbd0d00e40d19eff97ad1d9053dccbf5d315e1603c1a1f8fc03ddbd7980782b1111912907a0502e25a887295682f2611e58c5a9400f30e796d879bf0dececc0a617c0e0c2548d9dcbd152d1e0c30b048b17d6409679e25bbe30e9e68983afe7157fa0c82560d0800579fcf3dd79df29992f3b1ff622ac8162eb6b3d8b81e6f3d67d8026317084d002038b2b628cdfada8e6c6d81ba31b5b0c141bba94cce714bf3695cc872e3ee106c17c982705bb116514b9566e468e337e735ac79a5f2bcf4a3b5fb528c002abcd948cc93c5d6ef9c7b277fdae3ebec73cd1522d08464dc9d0a686eaacb601055860ebcfa7afd1940cfa330806949e45ea82a6e346e882bb7b76a55cbf03e8eeeeee3fdeb2593e45f8e28b3772fc0fad0783f9c3de6387822e38014ddc61fc036130783d08d67becfc7260e35ad4f8fc56ad5bd488ac4197cd11f2f3d5c19197d81657fe81714216bb6559dda573edb2b4a946256de79d29fc6107b1d7510718573a68b0fbb80b5fbabeeeff24338c6ef666eebe12eeec38b05df8abf82b08e99dde9b8cd2a7fcbabbddb5d5940ce9fae495ae548d0879155b2e957fce5d6157f7535deee7aec545dd9e312b62c698224146ea513efc53b768599c75e8ad1eae20f456aa95cadd51a9cddb3b9865a85682433b1b4e74bbdbea8a3d89a6b4ca5979094767381a88e3a2f416c785935de42b1d8592924a975e6945797d9f13356786fae8a849378aa55958bc61c33bb5cdca27d621d76a2dc73d841fc731c71ef70327e574e9d2a56f558b35c6791b75b594ca07b7a3e69c4fbd390dc535d04b7b4d7b8d2f6ceaf53a45551abde9ac5aa554a3b4a5b9ec3aa946e7f47a58b4db1fbeed96b4e7b5e3057d787bf67a60484db57a681f7e7541e8ad784d93fd950419fea9be5b5cb1e2b7c7c159b1e1741bce6f389db3b775d0c5f1ba5da9b6942bde6dcbbcce45169b7557074a5259e3a51d02da51be8c8dbadad68e137166a0f16becb211fbbba8ad6440f63070a5280a20dcfce0e365c485501bab552f8cb959814c62062d0920a8f625ad62664e750b2a1783c60deebdd485313736f0e8306e8cc4dcf860af34906812c50d91ca8cad17c6dac0da509a4d242d4155e9873c6289f630831fd164c22a0e2b1c1569614b530db282538db7d65aab9625e6814df58b15c339bd9627e6815b88980772501428b890a5a95a0e697b222948943a83d5b9301624097d625917c68200a931d81517c680b8a12d587b610c88992296c58531204d313435697d1fc6cd4c8028191dfd344e96169e3091830c3b780cc50f6a201d462aa8620a362d2061e5ca50fcf734c8638044a3589b261c304309450646821871b25b5eb09226062f6dec1618a6a491c10915454a3ea63c59789954102244898dddb2a4c7122a2cbcf07e1e930b5e988238d9b2c28f1f437eacb1d00378f933f8e27e396b8a7894b1f032f5f0d2850811d7450622d707cee0de55212129e56f52be8f107bf123d0c3caff7ce2117bf25d7a4747d67f467cef22541a92c4e31f0f98702330c67e1c2bd5a2f360b4bb38581aeb5bb4faf095f10633a0558ee6a1df1158c1f6f7300fb4ec51f6e867ae1ca8a7a8ffea044eb090cb0f6460d3cdb6e6940c385d5fb52db2875749d10fadb81b48f207abdac1956b0611ffd4f936b2ad5d42ecd1d76016244666900589902c47bcb069220b0d4ef533a522626ef6a927a72e3d92ae002eecd223c95dca11239b482442e441b7a79f837e0894123d81f2a4890f4d2b28ba948b0f4b977e08fc132f5d6dd5d5a2351a027b3970b0f571b616ff7c1dcc60fb5b3155a3df5fe2b0d8cbe87fb0e93d2082fbe9b85b06f8273e2da16fea554fe9e6aaec650f011c367543c7ddbe662e67af76d10884eceb9bc03f99eb68060df6284c52b952291bf5b3df5235b4cf3ee51a41fbecb5d6679f6da91adc8d907dfd2d55237b40bf9671f5f9e96f4001255b425fcb1e7dad4600c86741e01fa13e8b3dfa80da71369e3dfad973f7695d0b1b23f4d7efcf3e4bd5e8ae7af05129106a7731aa0bb2575333da99a79f36fdcfe6608ffe064a684ccdd026c064b5fffc767f0a041dcd4fbf5b5a07ae7fbb3efbb9341eabeff1434c5ae0587557e3f66de582edb785f88706bd2ecc5c4a56973ea56f1b68d5e5601efa3d97c2ee572510c4c2a1fa3918884680c8c25b3557ca46d6b1b2dfb62cb39772e0e5c1faf5bf7ee56e7dda8d1081ec3cd1a5078f9b7d44c32403344a6884c49f4e49e69c73b2bccedfe69d2bede7bbe49d001ad48fd09fbda6b9a203b64f3dbbf83a70ebc77eeafaeaad2ebe9eb29175ce1eea512180403f3a7bae194648b1727b2e3422ca94ebf10f7c40f799703df6fac6faf4cd9b376c6ef42eeca80b84faf36b84cd13b4209b1757c5d3975b85537cc5e0722d6e0254ac0f0851c22e8c93c039299d74ba841242d8a181615e52f8bedd66c1cea22010840f5d4077265a43eeeee6d7a0c65b0262b0b1a30f5afc04c460e17f550674a13100f2689095a04993c5c9151a847102480b7c60016547861f49706081b42384153545b03044931694e8214a0c8c161d76a84086a94c10638058f2821e394861c482c9ce111642ec1439c262879d2190b0e0042c56d891c262cb0e0d67880892820d4758a088c2852a34b840052cc4ec0c91c242c80e0a784882ca0b30b070da9981450d4676a24c5132c2cc0a6e48c10f494f8e608184fd6c77f3e7e0a6703fa011a30315419c41d27102247a3061f38297334dc0e006352a0400d1c45aa136715929052997bb88120d4ee0065d9034753122ba2cf6d6441d31da60251e27a8f0329244cb58bf5069479b2c8dd20e29863451443fd180231fb800f6c37edbcb3f00b323cbedae4ce470bb862dcc38aad8807482163132483244c58c1447b4f1622687a126922453da71c49b861b846c4fa8e81c22342f71fb0886db1db5d8eff5f2c2c1e5e7245166774756770db73f068d1b10c8c1badfc65c554a34354e4843d405874c686531e103a32f4443558c0826d447358e9d35f6efd74bfda5c5f4523759b696e3fe3dbb64822ac510fdead2a20721708e251cf0c5cfe5cfc1a45f9b3e61182266eecb2838b9bc7499995f374ee9bdc4c4df4dfcf3fd17fef95e2d867f3e8f7b09cc65164103387274d376c1346e89edef3824dbef6f1b0807f3122ff1122ff1122fe11862ff7e56892a4698240121a589058c52d0a50922264c0019e2b7dc0a1ff6af08fc1ae0c7c19f835ffbf295e8c62fef4118712af0e4a99324523735d03f007eb88fdf4bf0c50e855dedad5fbd45faa29a9a273e7d22f2dabb98d8a7467583f82c9e16f928971bff5228940ba7c3ca69fd0a0e1e2700dfc16b144ad79a7a280d0487aafd28944e822e22fd72e353a7f8f4293efd42c5c489d4402ca679e2b7f80dbaafb29801996da804cd5a4952e7d0900400080293160020180c0a8503027120c8b23c489a0f140010618a486e583e134763410ec3280a6218884108418600000c30c6188318365a00749a6b1e055f5a45ac079c94497fd612371fa39e2c9ec2bd5415b118385125fc2d256e3e37761eae34369007cadb739eea39e167162db592fb3a27c4249ef5b9514ff69fe22d5d29f63ec85262fa3fb7984aafe4daecc4be27b8a7765379410fc889facf30cfee9d9a871ed013f59e619eed652f395d3e5a54da13dea98e7e55a97815ea88b5530374db443296474eec3b41fcb34ba556d00df4e4fd27a87f76bd2b805a6ec3fa45ef8ae259cd5ac39f400fba56bb4e149d02649d88c41ae20df7f70d0a1c7797d61fed397aa5f42a05a5b99a67637912784708487d8c22cf1949dac6a95bb65f1f867e732245fb66cd8aae357342298062e58187046ab1f84a292c26dcd16179ef24c5f14fffec205c61472d07cbb3b5f51d0cbf1cb2d87719cc305fec10d523f5a7914cae5782f2e81f8bdb08c4201bfdf5b0215b22c32239d1ceb1d6c83f3f9d2eb8cc05861da95d422a9e0361289f660a644cfd90baf8fd1ae6160c15177d5a1dd08146650c9f6cf4a46fdc2c8dbd48d4d35a4d01fdaa4173831b9c18b2b89183bf51fabb85bb04082421c5e48b1855e6272c78b497bf148a5d0bc1a87f859e03df371de0df3b99cd58984c9bf535286d308058d7603da79a7a9a318d05db22ce5a97a9a870f356f1fc750aa77320e19d16fb9d4e27731f3f4cc5d8a9c822a54d5569b3e860d8513f43cc8b8272585c0a6a8b9a0821984fe884ef5943460aad3e0b1e8e1beb1b7c09f6c44cfcdd3db56a36e9ef9b449a70013db45fae9fbec6a15877a3e1e730ed29086cf26579ef7ef836efb1b84974b317940e82e3c4064275e375128b7a99361777d0f5bdd6a8d2d1a3545c3094a318b1b30ea43b9111b78740d5986edf269b13b475c8f5a5b971023d7c09f85ce7b8ea83cee555d8a4ba0cec6f3339e2b640354f58405e21655f8f2a8258e3f61338523113274790b5ab1e9fd1ea066aecf1b1c0d791981dec899c33c6b017f0e5ff852ab043799bf0f414184e26ce87f55e1a1b73d5f7c4399c774e9cd0037bac4978bf57f4a682e0e186c467fe11378138a093a8375ff4f1a45f6f8f4e72d8d7557efbe54318fc64984eed3ac6d214c712895525a8282846abf9a7b7eccced73c2e45ca6f126901974987d765ce7506f3cfa912fa1df55317fbe0c07713e064b6ee20c3a88f906a5ec913e9cab630bcc3c4ff43dbfdfabf972713353eb002941021e821a4cda10001c6b2e72c60a5081f899866f564dffe841997f4e7fbd363dee02929386420febda0b50e1feb9463ab2394dbb0d39b91dae78dd49f76d0a110b3eed5e4138a66fda28347488c7e48f521609aad6d8e53b7a955608fcba68baeea59408075e4879d2d430a05765962cf9db1f91a73030fad42f5c5eecb866dcbf30b31c608f324c90e1066dafe3d637d0ee6da4ae578d37f52e4fffb1a34ef3d17971c5414a862c608ceb4ad6035e90c7afef7ee3b788fceefc8b3c5937cccb6bd0b82cbcfba60688f70e381ece1867d2f8cf426942db2c2410a65e237982f66fa5585fc2f65eee40909c20da2b219de9a1d636f6fad4e7e870841f91f2c8ef19e6fe09f1568f14743d0f427df2da7ce1095550d1bb0a23d71926a3d314d8ff0ad5773c983c0a5460e185308f8379a57796795c9500d575bd81c0ba2f169b83e24dbf6cc5091bf4d538c887827785b675409706f060af6ec87c3ee543152226065b85412f98c9530df1e984102c014cdac7a5b23a5070feb7f62f64d1f1322963bf9737683c843830112973122895d0c85ba60f3214386440ba106a35c8936888350b731f19f49ff3b17bb34471a79ae363dc725ca588e5295da040c9252c5daac239051fe2a15f0133dd461b4832e4c57804f35d025dd2805dd3139a2b9098f112b1c3c47c5aad24279b4143346ef00e39f47531e285c1b10cc8e49f4f8d623dae74aba84cf6b564a66e20d7f10b045593b3d6ce84c9d9fb578aef23160b81537ab8f82be92546f5b9c768b4a63e5f35f0a5218a3b581c56b327b3e27b5e97dfd7c8795463704fd809f39eefea5250f397f9a0880cc160fc523cf44e22a774d3a94624b42d8236e5ef439d79bc37fd2243d8b6d4a946ab84aaf2efee9a3da6b4e70fb4837870373c9369b0790385823a71cebd52a14b2abd635f767b8611a491a095b8c2feeef37ae74def6e839d34a6f43f7803aa38c1a7043a0111620371f6d1a2d6f89aaec57f788862bface7ee6dde23b062ce36d0e66cce6287cc9415f0d48339733afdf3875ed38bdb2201f8d7f0d118538c82f6fb305150cb9e1e54720ec695e3b524421d459306ff78d16a5ed612f6b4cc34ff4c3e9da0cad75902d8ff123ea8dda3b3ba57b3d20878c81f2db07d03e93c69d0e32ce580f4f9f1b1d83f8c60a8c02cc901325ffc8e33c22abd05a458efc07d7f0716b3e17fef162d21eed55b040005aa00be182886fa06e23c6affd428cec3e20dbe45ab2b6326acbf2848eb5775e1f077976e32491e4c7df8232fb0bf688532219dffa25894d7013f5f16b032208ee40f3326694323b05294adbe290208fdb0f1a5178698c48b752ae31c11fba9ed77aea8860ceb00a525194d6da013bb1de2908ae10714dd9060be5e7710eb0336b8fccca8e1b50fb9eab1fffc6c2c40005a53971c15995d1c25ff92b593905a26aa5f4cab57a72aaf4c8b5fa74abf4c4b3c5193e2d749f14d4f41fc32adbe7252bc3255f9655afd32557b6552bc3a51fa6552bc6aaaf8755abc7aaa78655afd72aaf8655a792253523f6422ed2d13105f3a5dfa655abc505310bf7422f1d6d3e29749f597d3e29569e52b93ea9549ed2993e2814e437a651ae2879a16bf4e8ba79e16ef6422f54e4e142f325df96552bd3255fb655abc3a557a655aa01f39e49c7586aa90248809a5edf7a52721d21a632a7177d6a0a1c29bf00498562cefd616846be5a7d9e4e976e2db933127ed4690d7a7f33a4d72159bc84a396b2280dac99e1fd53376c4d74837f28f6ccdb0cd0a4879bffda620904a72b791edfca38dc4396df582d2e95c38e72983464460a33b6f55c962db955ba6e2cc425e00d01a0a29c5fb3c11430101a2e987e757f19ca783a0286427a46e28d69943bcf79af884581b696d5d71d1163354a5f1b1e2956db0b0db3665dccfd99ba941b1f61773b066bf9b3afaf525b02c06ea4502a1dbc6be1e859c89375c6ff518780f064a1e5b6c158daf60f583694a9b8c6c3efcc57c7774ac600a836caa563bf90f01efb6e875b33200f9a5935fd50e7762990d01e9a4392f8615c380d3de7f9011fa8287ec80d36ea902cb627beb7abef8a7809413bbdd95e06c2b342f01af6d3730a01eab524530790b9edd467278d6020401361c43e3852087ef6b162c6ce0d49e309fadf248191addcf762361ba193525afb132e7cd999b0a57f81a24e103543f89b1fbc7a614448355d21951a28bcf40f8c59303af09c4a368ca3697ffd58060e4a64a443c1e2df9d851bcfc6613e644f5b1411eb725eed5685689f9d9126a554b9b055324de690624fda9be3437dda64db5257632aef53e88c942338b3d8f81838f757ab7b001f0c9fa1f419b0d3a59172358bdd1e5844a2d5000338d08e170fda5841d54b1e7531a57e3df6a0a93c48e2c3f0b975c0f3f23199dd946323e779da0b0905a3b21ac80f4c889e2aa8455dcace608ab9698bf881b42dd759d1488526afb1ba7d744c01e8a156462eeae2727c170505b5d27f8abda89d8136f028773f962b1eba2fe3f38ffeb8ebac681c2f2c0990e63cdabaae3aa37679003170084338749e23579b612660dc60d5d915392d92816f5beb79dc9a6a8f503367112673851374a83887312d49993f79a55415dca9bedea9479c469917afd32e58d556c3d9a7024987bef971a287634668482b21f921333366c9bd40e590fe6212bcc1fb266448938ecffec15e6c1336deb4e8ce7cc34a73034ada2cd40e2de5155e7fe624770b35b8692e2d7dfa1a90f6a264b9cab902aacf66def8f254dd8c3cdcba6cfbf061633430ecf1f7522f70071630bc42106d0a52158b34c9918dacec83c8adf4b7265499308ca37007eb586595bfacd4c080ae15668939307a2468c773f9fc2f282578ff2f2f6a60e13f2f61a0544e2332e78a56a72b1449e1ff1759952a76742e7d1b9182ba83abab0640c05d0c3454726f949ea96d2cfdd353c06d39ad06f899d14116f752a9c2b8f07b2a0e0135597666a32f12448176f308fb07070780c82d07cf8344c1214b3713c16aaea1b2f371c01465e15be268b16aa4a5b7a2d124d163e640cd0d970ee32a52157abdb26b2535c6400dc7cf2130a8deedb810fca88e21198f88c64b95687f9f9cfa1b49c8f80083eccf146b0c684b027fc673964784435673df0ed4c1f3bbb519d894837be3bbb8425390bf24a583e0af477acb0780dd66bd07c7e2242f1a3edf71ee51e3dc1316fdd30fc4111417c4fde3c2cdcd6638b7396e634706471684d5ab9989698d7bc8c51deb2cacca282d17c65170da9667613bd20a74d7ea82d5c307fc58d13e8df6fda0fa07b9951992f98ae6c17ca09079f52dacb3515c4d699d9f9616c54ff5a5ba63209c98f26ccc5df80ce7c25bfd4085f6f5fa20ffa5a30b3e71ba69c9c0f5e0c9631ca1a5538ed638dc5d2b18a76a129dd9667d276dd3072eedd3a662fcea772566ad3b1a69eca9a9284610f82b0f9ad43061ecb1737b3b6a0593fa0f5bfb5d86bd62f54bc0b9c8ee1d69d48e7c0702088fbfeb87594606435d72c6f27e5e37adae2ddb68171ef81c65faee1775b0a2beab91d8872a7ab7cb0f70a4aaafce89ec0980137475927db83114b6538684c3aa7442a31182b0c0bb949e1aaf416aa920c5300cdcd13994dc70c9015a1a9794f25cd05da522be0afdff4b1ed77b7dcad49fe8199a08da00b26d81f6757fb18111551be9824d0d24d5a1a4e77c8afe2c75027320d359a977e7f08f2391681d096cbd4f29ff527f8351c1a7d6719da9d7005cb49a80ba0bc5c2fc80a0f1b7e34aa8dbe2ebb01d23438dbf325f01cdaa4bce1e220aad2cd03b31db37fde38054d089e97ad628362bd65a9fb3d6effe220286e5876b41934183a4e4526715b7ea984324afa967176e91973e03086ce402cf79e81acfb841346847f7a37cf3b70262187017c42f1849eff311ca29aec5200fa819b9a8108f89ff8c8fe32239a74552bd53915c08ea40866dfc9edf3b179668315cc91b808943c86831134bdd15e3766ad2a65f3f6abc85a85ea98099a7db7dd5eda25f84aa01bbb93c3ad62a49ea4179384cb3761b3a655a45d97481d151cfedc6b49c573f936557e08e34794af522f5dce0997c12657141cb2d4d960765faec82c6ca17ea95f3fc67535947d3ac2e8555517e055fe06784b4276e030a82757d695e819bb92f3be5bb7a4f395831ff290a8161cd31c073f2dd109365f215ccf455b5b8ad916de33991a039b4da4ca0077bcd6ada7c69d09c9d0cadb990220c96a0d73f22af4bdbb8aa7b748fb1777e0f3a7f4fd5010958ac2cae8c2048645f566869173ce09973e088da0a0c1ebdf3f0207cb0c72d4df0a8584f26e378a591da6178a23cf017d13ffdd98ad12c05e1d21cd513826d8553846069dd6ecdc69c5b0a81390e6f7fb49ad97b708bf14190be1973d4dc10810bbf642a87792884f51f00445e4f82740a39f5e489ea943456dda757f4d4226fb0900e7297d3f67dc7fb44841300f403e447cea5c64e27af7bf6d6b5241892553b166faa5a5157f0f5b066227c68c3e1cf4cc87ac8a04e7a1e48b3d0ce208443aab5f3a2006be79d4b4de2d5b3dacd1fc0c04e8e0298e7a32383d55b44a0f55eb7659f338b40d2c8fceae9dceb270e31095f934fb6fdb426e43ab65685708378d054ccf05570f873740f683f791c2b6f17a4e746533588ad4e0c3eed27666ee490d1942e5d1999df0ff01d6179378234f1f017f3aad857961271030e8b23ef40af39a27aa3f801f8062d0934ba01631522f45de8bb86708856fbab20233f30e120e8a53428f86a276619929a4c4d9328e1410de41ed500305caf37c4cb2ef1728dc42eb6d16c8c9fa86a5776c837cf6e4d01d12401132039e1612a9603d2c0313faed84483528e6ad1b48b978fc39a19198b9d6caef15e2db38fb4af39357dd7199b070c6b17daccfed39fd63dbf9171b67101c8dc66417a6c1c9651586ab5b4ed31aa0ea3a09b6a4bb004db7a3583c682423b93e99ecc2950819e1b57dc5bf54bbdc4783293a49273771b4a261644ca12e7175d2fc06e21bd772e41b10c8a59becaf7cda7a8ddba2263f999bdab713bcdf86196bb47b49e14f1693d7b7a55cfa55b011b046d3b2ee5ebdc1acb934ec61bf99aac8bbda60dca336475705a8403be310243e9456d4d36b1a69587f2f320abeea667c262a01522f9a0b8e106b7fd9ee235eb5e67f7c395187927380fd2ddcee0e04272161a1c8ce86ee4a5b85dc62b19475d2e91cb797c048d8426eef83a42ba153c01d893def63d6bafd978d008371c54e3d0403adb9f1b6f4feb36d196eec582539257477e2052a91c1065726c9f4938497f82683a921ec9a4368f07479b2681a9b56df4394a36407861f47043021c70652d5469b0e8d91722be2e7ce802bf8b42548f448946b466cce0c470a0489334ee0ea91e3ef7a0443fa59eb5b723be453c3ee3f47033079cd19baaa460ad0b48cdd22aaf3c8d22e3c79382e3a936f86c5bae857f4601c668d8eb090c13f789ddecaef1d8d3a0de25cd598c1fa1bfbdbd0073f340327a226fea1a2c29b1822863cf33e60f7ec6051068554bcf007d585b0e973b1525671c1407a530b6ba24c10d06224d11639b04203381066287158f44069b73b00a4b3d4d4f156d43eac19aa7a02f061d57891080ff71dd5666cb989164da3bd98291d38573583286f6ff57e2bedc2ffac019e1d4b4961b351ae6bdda920cb8c06d654a1385a98e7e81b22267ad46a2de83cc0182cba207cb641ada65b886cea6f2ac114285df5ad295e8437a4004a5fae1e005a18eca2278f83ea3a11d6faff230d8b50135b2109ace8913a0143224d2f9e16a4940149c66739cc618d271ce00c6321dbb77c32a62972ee48317505a7b4fccd76000c928a43dd243e9c0dfbb65fc818cbd64b1ecc505f5fb65183eafd1002dcd4c67564170977e23691e2b672362ed98fdbc8e2e7aca770e303ff07c18ab492a2bc5d956aac3f5d588716b4ad00af239a50de050a70eeec14dff7f6304da27c112cef17c1eee57314c05310dfe69eafad94a3d9a9f6d24ebc9d5a795148e71647c797d26efaa3eb7301c90ce0bad256ba8c988025c00536d264d33bfc7ed224be7f0ee1bff95e653b5484662f130b7d9ce32b53774aebc9cc1b4df3db4ba6e091c2f92f51d3ecb8e9d8c901429270252f6c9196a18e5c45c67c11a137adf7d2caab7dfb68b74957369495e92a7e0e3efa382790d6c18f044b88cd3a271071e571e9a2f3463c69abe9661e208837b0052c1ad3f263f691419662df181cb27cba3dc48fefc7858595027c835e293b532e8f7ca06af98162500eb4c195e00dfc9bfa9a3ed0ab3bd259cb0f9106401373045259d59f06e42cddfae1c12c216f996fc8c470c64f529a35db8ea3cb3870f6bac722cf39d3eedb5b1df05bbf437f4fc13fc1680b4ef47150fd0c5f8459d19bba5b505d495199cba54aebe93f43d8884ca51cff27ec342832bd45ded0beed98777fe06b8b555ab8736f3213c5f06dd496dabe854ae6f51835cb685bb927857962475a7ffaa97990f4b17756838822404068bb5cd65a8faae39e7d2c8d0cc354c6c56049cb1e7d66057f7ab637aa18e012afb8ac5897040576579df182f271ff4e1cce3e272cb808c858edae86248c36368b27317a2a6fac8cdd8fe55053aabc25c2072053c38b533083891233fe54a8396cb5cc638f5f03408c0537eb63e6f15f0f80777858bd09579d45e45887ab9db25ec17b54ddc2977c8bb40b844f5b499fa8f389979753a8f58490dbac089f9b2657b5cab13fc0f80dfc07d65bd61933f6cdd47c8e01e5540b5e2bcbaa397eb57b8095de0bfff8b857b8309c923c61bcbe9811f33557719bcb091096362ff8adf0b03817825af0e6f02d04bd6aeec545bf0c9e8df765d5f54e10373499bf41a08dadac25b4f623f7df945d5d7d448dd3ac3ff5d7dd5a51c300e43f70a7f0b12272b1b73fee1a7134fddf58c6d8315c9cc075044e18119eac60a87eb5edbf5681c5e2cd6ac11b8f1bac0bbd0d1e8b7878228d524654fa9189d1773818992dbd0c5cb3c13ec758baabfddd2bfa8cd4e6a0a18e4cefc97e5397e779acf24787d8145cef499de37723f3326bd2e1589cf08e62caab8d597bf1b5b12032d380894250e9c024c7c9e1f3ce178e485ef8f58f6b51a8d1991ff7bae0cc3b97844bda1fe421225bc5a52bf83cb944f61eeb60838c0126bf702c7d4efe4d672a481c6c301c9e43370041d1c16e0ce390f5268b099b0be1b695f4f4be6927d0a1d7b2c0a9018e421fd8eeb5de18625e334218c3eb70c07886da656863b47c9ac7a7c94909aaa1d30f0cc15255260aae6665dda85a417749f2ea1599d5a488bc2bdc94ac81383fbc1c058a083b0001f39ba096f0266b6b8332fc404ddc7dd274146648054f6379789ac5bb1bd197f032efbf65648a4882d9a026995774673d616e6daeedc594f82d984b3dbd667aadec218d7142d978eb2ffdc1f2a974f89b5129ecb57352621bc92910dc68e2d1d039f5d21074ced09963be969a06cf6a3cf9144639facc303909a28262629311299224c3f6e1c9ac99d57175824ef4f089627693e5eac38c33e73c085276baecede738d407b40ff2c08c33a49967b3acce5dec87c094f68232dc4b2039ed3f045408f835b4ed9ad026107efc38c95c2be9a03bcb9b1483c34edbf01e45f9e9eeabcb0a6c12c5ba475cc299f53a7ceaf40b8d7e517a9b6d3edd16d54c55a05af4fc25b22f34e63506457de230024d7fbe813cf629167d1baffa8a1ba61e052b88eb117bb295d3b518be3aa6328aaa3151a7cc4cdf7869fb9f781188e495aa983de9024c9b1089df6ace3e45c1f6152675d6a608d984b9299353e7adec55e0ad74e239460364116a43a548214dc3f7ad7a420e404d7a0ed4de4e6e7f7cc65c4d131bd0cde81a51793a8c40e8fa70ff8f792488ca33bf4056cc0f4ee83884e951d4d534ce213bf9f2da47304d826a175503d82a22a267912277da274f4cb149e994335b8170433abc027f099f2e46c90aa0d3dc129d5490f9e40d92c5735db9eb5054b7741089e2519533b84d630f69ee84e9ba9a6bf41c8dce382af4f587df2fb2a8ce6d25f6ad24e9af856fcf098c5791c570da82b2c7dde0a5e99f37dacb70949bd0eb5513ba66f4744f7901380b5ee284038ed98437991049951564817eff6881e3dcfa7c6867275e446eef5c687b229e1ed102b13d371797ac56d16e77a57212743e09eb1372db932720a749f66762069703080f7a444e9760094413f23d028b52ed215c94abe40d98144e52a765703321dded0c541f6da5630da8c777b51af332b81e9051b45a87ff1072a0582267b16400c5c43ec856edcaa096cd09dd1d98767425c288761dc35f39cf67ef7b43aaf06697612aa4c673038c840e008bd24913720f30b1d6cf60222ca76ed87ee0ec2c85b6ffbe36772029340bc1ab4dab406d150924f9be6410126c0c6c43c65917b2805f376cd7381ae3c1c25414ea07f8ee1ac704e9085cda624316fe0789ea3b797503483c21774715c2362f59717c05560c0e1756539cf3445ade29264e2c071c4b278a9034e512051b1a1040429954f409edc0135b6ef03763aea8da04780e7358cec638c921b2501baeca6d583937e6d3783fb807ac1091f1c6b8bd870c725a249d5ed27650e2d5452755d3fb326a02329ba679cfeb6dacf5735ccc660a0135c2c1bf83cd8e5351ccc17521446e6ba8d84320b7a35ae6141771f5c6364686865f7985c0c008886a4efe52daab609a0672a81339366101c6ad7a74380f21671f922805ef2069c39f90d322d91830d17250e46167ebe9f5212f86a8e8bd2f7be9dad7092bb48b61666a461c8373e503250b3121bb04ca884bd33b22b3c602ea70641e26c8b41f6af91102d2bb8c25ead0648b8994b231906b6374ff8d4f4c4e3c913f40ea7c21569bb6059f5465fe9dd2a2d25a2dd592bf4c2004333bb4011d012b62fd6d860c8f92885e8f9ae5aa5c6e852eb1b59b8f5273c24e6f2ef1c4c46820a3259211349b0b6738341e888b881ad400749529f189a6329d27d260a92cbe8a08c602633169eb885381c12ed725b84dfa39f0f7e05eec96256b69b515d58b368a351b3c41a3a4e7acd8078d7386513437a80818fb69718a98d3a79a52a960423c66bdfee863961d9c9a6e51d021e2b6e33da9eed53e8494f05305e05f81ff2e3f8512f4919604a2ccd081c68da406280d4470884557d4a6cf14fccf5c0d42474f76ac40d77101ed3a66cacad578c9b2ff38cad970ed76a5fe8a2957a3f1bc6a6fc50cea787c6948ec0f5ca44143660156d5935594756660c1e99fce71e8d3c26764680a16c324a871d6f909276545599afb5f5c005f16a866d167297d57e4c5b707de9ef69fd398806480a8aab6f846e85b2f8c1b3c1f1c1e95ac9ef207d3426af90ad858cba5364a9035ff9e2705777dc561a865a8138d19ea9f6a561d7f9a21368dc509b93e9087386aa1b149ff5deec43d4d68bc0c04da3d57041f64b1007a049a65b34b473dad20b944ff5bcb6be48ec4460e4ff4210aee920675b5f52280c0c3ad6a6d7d4601c075061c7600215803112a41c2ce81da83de679d52f80efeac5b0e60e2495c595798aea9966666dc8a1983d045f0e2963625a6a5b7cb21e4a32cf237948b48979ed05f11c3d2ec25494d19d36ce93c8aa7d9fbc51d1b7e6a2667c74563a6676bf07e1ce66a9031d6791ed5f88a98a0825d202d4033434d06f254db03cd1165308efe3d45f2970ce2805837191c7f56031b30273c84e636d868ffba4bce5610e592adf7518aa6d892118e7e3c62992b1229049974250fbc898e2cf62d634da893d27c25945c40bbbd101ae4d3e9f596888e8ad453229f456d2b54f6331a874515157e57949e0fa8b8379c5c943be55a7612aee353acd5dd05288d506a9527ffb8353d9a128967527094845e118e40d62e2b02a146e5ddddc0538ef7a621a94bb69d4828305369228ecbed81478204ebd00982b6ecc77665f923fd58b96a062fb073dce7bcc20b9f269d91369e43ef5047b9d6e44c5c622a1a1d194a5945b6405703a2aef2db0b9dc913ab958d30a771f56f35990d2409914498133e8749aaf9c584080dcc9a381df54f1c5e5863794e4094b386cdced5a1a39e2ff68dcab56688b409f3a5aecd9d788a8ea22353ca14c3b859cc9751578bf501f9ab9a23432cea299a0a6f0064ca2c7f10fe272f8a78d3df1a101ecc1053717c4364fdcaf5522dae4053252e47eb944a90108b9320a79551a35eaf7536fb2352e50037b6dc8ae0f0968f36316bccb49c2ca3643eea53d8060b1c4c6a7c4a741ff13054d718dd7f59ea3b74051c4492694c11d41e51d8dce0a045f1d6a5b974a1024d39fded28cadd8463e1983a5c1f97a14c307a5ecca9c49fb6194b2688b62b6349c1a6345c73b256fd131d143da7adfbfc4adb501087c0efd1f001edb42c4f68152926861c210c0796844515963b7dc8c5ec2b6158ea3104b019861816418c1b9da3e02068e3972f893b32f4d115c682693328363610434a6b65c5c0181b6f959325782b9d089758d61f732a79e74bb29f7abc520ec53cdb0104871f1c9df0ac3b1143b664a2e3a4d6757ea4aa0d7185800698dbd611cb0b530c9da11248814ca93aebe8d806f9d410030df1d7e6e38102e5eccf9818f2e494a3a17517e7eeba6bf8b811e029affa20180d999b9841c5b0a1f9414a0677dbfa7929335b6c856a19716e5c2fa4b03dbb7e24a99fc942e7d3e8990cc57f8a82ffa3cce93b59505ab1134fae5a694ee70e7794682e36cd49622544f00b89c8208148362bd427e71f3c83485bf209afd418ac66e764ce504f2c18248edf848845333ad94b9537c7263be46cffa44a12264b3f3e0262e443f3248f64417ef0b03846e6a0ebf4d056fc915f9aed51ccd12d34ec94e83fc9ddf62ed8a4998a8492e06c9ab3faccadc4ce6f7f9fc72a51c8f3528c3adee7b0409fd1599826e89bb6a9088ca428ff6e97abb7aecaeb5cdae9c62c0a8b55462b39d4d595690daaa106fefb504aa6aeac3db5021f513dac70795606cdfc9c572f768fae77ceeb042b21db8b1650b20e43a7a0d226b1d0f6eb254d1a4274afe78114b2347a5504d2341cc6d66e1ee92441b11cbb24038e1933836f8c160437f6dc56cdc1ccdc6b8ea0a3bb48ce0d071b05ac6c96e0d7d54f650e204613b558351275a2dddacb90314bcbf1abbbd55668fd02aca0ada58e1ba79dc6daed99382b93d74e7d6b72e0f85335daed2689be513d6158c5db2296e2c59b3007ff0e200b6733c570439cba196a743b250d7a9e77066028e6765ca7b557ac07c3318358018ab58dec0eddaa7b7ce3c78524aa98c287cbc4f14e7209cd1a32a8a67161e5fdb82ecb75f871e12aa0d379872093aa685a7c49ab81671b61c629fe2eedd983cebec954a10333aba3a23da5a77689385a384233a252563ebc6e67a61cf07c5372d3224586a980ab45427acad272464a0dcd998a21445f4fd5e61d9c4aad7973a314e3d79f09cbe1927e42ee75b5ab268c818a7ebc41eda59db484aecc183c53a2dc91b9919620f63ff75880e978c7453046c13340c45c3ed98f6942c9f6a1d6bb879255c90cd8591e84bcc1369b2f942c339cdcfba88370536ef918d2741420a580310b0996c3ac2fa311b614be3f01f813a623218992534b581a9b18528caaebf26db06684bc4dd043f223caf743949ed2116b19d800fd6328d693d02805be798d7c753e3257f3da880766f46c7c81a0157da1a35169aefea392beded843aad2e036a91cd3885697bd46025b188d7b5aa1a7fc672ec3b92abda29c15f2ee97bfe5aea2c96a7c323003f1444eaa53fb797dd3d847a4aeb742cae6ca315c903acbb7295c30b266fade9dc310159748370829497775d6b7e4d10fb406cd308a5b149799270a7da1f91012dfbe3aa2f4c6b044fc2d2a41d2178f02f5524a4eae6038f63642911e758406fc331a2d22257e9bfb98481c79ac85873a01f58f8a94190ea9e7ecc45ae43fcb44bdc29bdab7cb588c3c2f723da5abbd9751ed0eeb4a880dfd494643ed38a4073ead303ccafab85a6f0a8e0091997067d72157d737415d0486bc45bee3930aef8b715e320ce29372864d124fce275058d91a763e0c7449bcc1384248be7c4c26ac1afeaa25c83d899320d8185d9ce2c09589815db51c1e3bc761022771bf3257938855cdca3bbc5b0e4906a78809a3dd05905a35ce3f97e215abe99b59c17d420b5dba52cbbeccba630181adbc177409c5f8f18004afff392c01ee7a9c8a447d24f809cbe712e879059b10ab88dc17511fece9e47620c81274a0c4b66f806103553e57897e1a7df6a397d902db08eea6b9f5f5a29dc4a3b39364c43126e3ecc200c07a730e63ef1e96f7c9c7ce93f61d466c91e8cb6b6edb92261e1faf5d01fa1d86e3a4f5618bdc9dafc77a671c1ac6d4b935230b15b50076c0a607e361103dd4627af3e8c98d8f89a64e7d7b44d95d64a21d85c2713e82132e9af2a03fcf5ec03a8741e5584619841e468a234e55b91a1ec9903b61418996cf6254bdd267b38021e865fade31a2b4b131d6682d0c0ffa22f78c4d42bbd5b9836a7a41a1f7f96d9b9c566c2c079d4ce9f94dc344aaa0723271c52a3305977c5c433e53d98899d3decc922916d1a2f05144d9572dce18e8e6e234cb370dde52457878faa592cd2d34160e41ba2f1854a834d1a36dec14cec319ad66d35a4d534bf2a38836afc81ca13e87ee7c0ff2d0d204def8350f4d35c092db27cbb62010194017c42e803b1af40299ff104401b6efd26243bff45e3f6c5c0fe544b17c1b1496cbabc6beb1b0242f75f894c3433bc04385947b9621385c84d0f78ed1a136432248dd125b7a1efc6f514f78d7fb120cec65bf460684107fcdaa3060a4f43c549c46ef62062506871116de61d45350110c6c85da6b3c647f6af8b5ffc462162de1a22249e5d84d4034788273d99ee86fe9631755309a4b5bcb1e10c088447a63a3648f49fa38378319566cf575c8f2d1b7664fa721e981024a4a675e95dda93bd6dd9fa551c71b7acc43bc14724d8a92aec0b667adf7c9c3f7eccd03b5d40d7957ec72d401d552feccbaa593bf6258cf229e4f4ac510d076748fa30e15e94ce1a7c5abb46a2ae1e7aa191b2e944625f5a37f5408694dfab15f050a960fded0fd4d8c01ed1e6aff6ba1b75d11b74348fe7b92e7dcf3d06a1917221f2d66b550d806acd8a880a6262043cd44a25cd573f5d4ec486cad7ba27c8c324351e075f6c65f0b941c022facf4ae426a8179546790dc6405057166ce0b34c507720bdf562645b46d785e9139953aad168ab4ecd8f46769f23d6cc96a3e2096c0cf3e1dcb4331eaf204ce8176994e400695d77f9b16aeeeff2573ab4e576df9b3770f57bfe0794c7242d28caa55ac83369a537ca66e5278e3d882922ece1d1016144ba07f912798ea66fb0b6395c02e4f151aa479c26c7711a7c12f05d79ef76843a150f5b67b5445362ee39fa61f741a4d9569f6c62e41ba29c690ed9ff8ca2d556c7389f7bfc11e76a1ac202c467a700a12b1e78764c30535465bb9a4ed5772985ab49843ae7d9ab096cb5b2e215b07d4f67e08befb9d8d4e9e46bb7db3cdaf354fa3401445ca8cdc5e65eeff31d6c1f207f76ff3806fb8d9c6e243d2dbce6fc1a232ae80dfffc1fa5e649e84bf7def04180e3fc7325a194e25c85f8f7ee1759c08c5d590c24b2f82c80463c05f748458c55ac82d236e2afbdd2a7830799bc5cc006006b345477d425e98c9abafdad2520f851bc9183763a69b5047337d7c071ae49aba7d8cdc545fe8a81452c9ff224b6dbe28b42648a74311ac8114c3fc4aaacb8d55d7b160cbc7a9ab7b84fec065810ec1c8add1de15787328030f1d9630a9069d1b8e8ce4e5e51d2290a3795787339c0a4745ba33ae4a7bdc5d42d5d1ce3b39506a2da8ea8291bee987c5f704741dc99fce757bb3884155c77eb26ff3e7d05bfb6ffe60ed4d27b98b252bd29173bc022654046d1bd85fbbde0c949ab73c60f5d65e7989a75734814714328a75eeb7204c43c3378849cfce0ef2d9d5a367ef150e6ef4ec2dbfd56dea42da17ffce124fd4e07cedacec504730cb8535380b0153160db3c29b160012c3275542993bb4052fcb7d5d90f0ae3daa7ae762b9bd45fbc6e4f925229ebb12cb7861667fac886772a81e9eec59ef52eab54174e3715245df53fd4a934c729da93bdfd05cdd80e4a59a0d41b6eaf27f4dcc37e3aa1b0627960fb26cf33726acc7682c5a33cd83b091b000db2cc04a65cd8e7f539dbeb96b7145cfede4d65757bf71665f7e098ad7fced6e28802ff9ef1ec3876d75d2190f7508c4467a4520e6d72da180284ee078541523c40998249e1a55785b4e05fd157202c6782d4d6e1f06fcc1b51a3c2a99a77856d3740e0e62296eaee888790818c74fc4154c44c04fc75922144e91ccc8492169a1592bc1341b3aa5b47f60dcd4d036585964710c6a562251730157cfd738994b42feb4a5c802de233bb8e970b14c8f8349811b18de43b0003280ac0b2338d2af5b871c68e177966daa2846c37e27086243a9c08f0f1a5281748601e350a54022ddfa5062e2f1c091d00b147c4ea55440eb6238a3d23b41d87f1fc340bdfe5ead5227ec686d4382042aae4ac10ce474404c5e665a4406b73f4ff6ea451d66005859eec30c6a48ae91da4f20c613e9ff3cc6ca3d516b087e806b40c3308f9774c5ccbce80c32b2b02dcb735da8b66d7a9aa5b1af4b62db9bbc9ecb8c290d6274daa5a0f5012f7383f34714ab5e1c248e380d624e74b21712ef66b758ba67f01e5c3a64878f25d86bce3b0faccbc9635c29225eb2fb50344d441851138176c8c8949ed4334fb9886747f2505230839b39f18d3dd68e97e94dc71a7376576e66a3b8ab075c3cadf2c46f05817074a36db6b9729e786c8e2f52387da062d32f927f1d7b087d049b9380050a4417c3d27fb05bd0b46f9c8df96d9b124958505d728b4d03ddfac52cb233607f48df543f0a56c5459c2b61b8c420d363524a162267d16a6b6b9fb8d6b87673a1059fff01bcf09208877cfd156c9400e0c04682fe5be0194845905cab024fd531c38cca20fcbacc0b1936069e5d1127186adcbd45547d18f1df68e6caf97553c1163998982ab10c5740142b88b434741730f74cb12f08a2bd8fa6cc9ab70d0e8ade4556b7b53867880ef74bbaaa6619cb364107c020586b3cf6008d470186237ae7e91647e86747c0f14bb8f3690bdf2fe935cc73c448da128a44f88f3f9e976519b030b954f8828df32e441d6d619289964cf8bf5e1fd016a8d82459b15e98053074255d3d1bff60b8e9ca54af56766cc16888b2f5b9ce7cfc616918a94b453d8ffb976498d4d7b12f3ca8c0f31595dc1f15094b0400af9ce734e6d54e7f44111b6b01cdfb0c5eb5850244e967c93992d44f0d9b50cec868815a6db1dbfbfab783ebf578f4a3aef9fd28d482b956cec83e7c12cc23d4318016ab1996ec17ce48ddb858c7d2e41c0359d2ee32a6510617e8cb9d8267a67de19a772cee9d272970d925b0e2c876fbc8711a3392ae624b16d2c80651690c90b3b16d93d5ea68ca9ffad2fd1b18cea65b1892494cec4e10581a2604380cca1a9565e4dd06382787d004d191a546ddc9b85fc53205ace392aa8cb43801c2f38438fd7961bda18fc2f0af99813a2a5ecac8fb466413b8cc809c000de2f905b51ac5da94a5931d6db1b7ee4dd222a055f16cbe2103a83aa8d4e187fe9db688e082b66d1759134a12660d38c14075b037d659d53b5c9597db85030a9ea4db234e2a264cd23bfc31c54998717cde27eab27be49f9a47188963be37ca38f86821929166d2f82eb4cd94d675757f5f2a047966a442b9b81a1ee72cd2f4e638c1e1f05b9dccf63ac1679988a2205eabd2b16130dcf795da154ca22d6ee0dbea6a998d84c19f87001722006c7f361bfa3accd7799ec1a4ff55b5c642de641e00ca29c5742873badf85aea1f77444db459024681ce79ea4ab6baae9fbb93ced9725c7cf59e95a377ff77ef4cb2ddaac32fdd4d2d5ed3519d785233e9d06886cb54a8ec49826783d91ad4c96b67ee43b922dc366faa17d1f442ade7102b662490014983cfdfc858003af7142d257aa936d0ed8d8f6aa981af127d5d7b1621d5bc24e558e38987e484b96cc394dabfe591fb673f8498497dca5707c196436216968a5237ec1ae37d30f3d482fd61a373f08f8a3b53736d283e4fa0502175f6e92e17dbc6f147d7e267008fe1042183b0093d0b7197e0c38f427653d3151e16f7fe71867cc7fea80d330105d84581a1eb7dfd6b24759fb8304b2eb6fd961df520987d2ebe3eca1a2b19aebd7a08758d1df2469bb5037b54cf4ddaa65b8cdee41c5141ff287ccc187679b71477a9045a77dd623824e457d2ba86d2a24a542ebca74538208421d5a38bd77209f382d07d2da29d5464205015a55a9b08f72845f0b177493e6c930469e22c854eeb482d496047289b481ef23ade7d2adcdf3575c0fc1fa5e482d4023a031eeca9175562ab61120492af3de455af31f6f145cd73df2669c5def2774d662ed114022ff7254e08764f222d472795cf33039b37f1e97f31c27a975d184c9d5f02e6d4dddac5a737906943ed58046af136ce1fca4b876355f1da7992074472cab34c3a63f8e52b442f376e07cb345c8bad417167c13f3c3530ccdb642ac4692180b05056acdd93675a6383b4382a746e1c01a33d0db0854aa40932a9e35420390cbad5a5fcb3e6caf1cd8a9dfe20ac0111e800760141dbfc8cbc0122bcb56c9f46cdd5539c507741834f070dbaad2640113d5b90298ae80a1e6ba00bd5986276ca452034bac6c5b2ddbb334972a1ea50e876562e932e38ae77a65bf91102518c981bbaca4db29804808ad17752de815a13e3dcc5c291cc5aba694367f9ad3c735e2dd7d3e028bea0df40462ead80487194dbff35f0cc7a8111823751ca6fee8a4fcde65279ec332fc85e6969b696df6fddcefea67b601851ac991baada4dbab804c08adcb7bb948eb1d50cd95f3a007dbd9bde5842b134a62e18b0c3e4ad0d13153f003d70363fee5027f978443be27909a5a8e21d0a4c16fef3fa17ebf6adac3cff6e6405fc0aad977e6117b6812205dc981fdd8dbbbcc589b14ab6448e94600c4591d48db0b7be3732ee7fe5a63b2fea23e49a93dbd1692f8287863e57e8165d031045ef8b1576635626a89eea10f88faac01f401d8abe08075a98d76a901100978793d67b23a54c3afb803739fe18efb4f98fc598f63d37bca9bc4997f42fd7e988a793d0b0c80b25469b2c4b58ddd66f9bae66ba522ad5f4653e0e22dd3c1b59ef65d9830bb6dc1d25d8d9679a3af141a3c71da10e570501c5c0314d366cfbe19985b3025bc94432bcbf4f5127eb75feef4287ae040a61af9f09c7160dc0de063d01b1ec2a3cdcd2f03437404c0287c3610ad3a3266acf7f4badeee7951433c64ab85970826535d1611c92b87bb36f5b60d00e689dfcd4b5c011f00f8b87c9abb2b1bb25498cf9bfd4a55acdaa20e38ec85aa7d6e08ccbfc152974db7757417f6c00332e024c825130d4c8c216567d8c98136ac48b4ab7041516f1e76bb8b9497573670c2c91d440835b21527fdced58806da8bbbc0147c4b96c05d20834c7c7724a0470403ccdb3cc07fdb68ffb9caf9387ab46c04dfcfdb5a677cffe40087f3752eda1d56df7ac8748f45c076afd00c905996827a2a2156187606ccb79f6af510e4ccab1246fd8756291c9d87ed9946bb2e9cb47fe530674b72c4fd78048f80719a9735aff0c63b85cbd57f55464dd6fbd3ee1cb963e61a54fe91f99c5ad0873ef83b1cfe5ec796c979f75fbfe2d234a5de79820d978e3d1cbb6198a622840655e1e65724cb30140cb33503a00a1a5e2f3925331e2a24371daae75d789e100ba01896f19f8cb7385d9311d653de539fcd5bcb45525e29fe37fe3a935c266bd5661e6d3df31397801b25dd4fae85dd4705837f54601d393652de64291bd8fd6aed0ab9513bc4a4d846fd45653349252fcf498483cec0cdbf03bbbdd8625bc8b82c95f9921984a0b65b6c518d33f08d9f145b7dc775008cbf986fd38a089743c979ece497d8d8acf51162d9543f8429065ad9cd65da4acc5c1ad00b069c20e11145fa651e09be3d823102508b4db31ee601a85d5ff875e4905ab3f3b1c2dcf247f416cbb8931e13bc4514281f862ea769a23651b2d1e23461a23850f1e1688210073bf3e1c8cae131116e66790282a486fc424b1a53552aa6b0bcc149800466b180565c9409471280a57c5d08ddc7c102e07c2166094e06e27a85d736773d30f1fdae59d1fafcec86ca1ad98864c1ffd5760188668f0aa5c034628084bdd53ebf119b999afe49d4744666a6e2a02ad2128f4afb6cfa7f3550c4280e9fbe0700c43545d61a9ed13a3c38d1d4b83efef2c58eaf556e37ff39d97e9779d4e90adb35aa88111824ca772f3eda90532445a22a65d13c8a83c46bb8f65efc96e8444bc189e5384194d6580cd05b711b368aa380aff31f364798510d931d795224dbc0ce30e31424e9e7194d87f62e33471e9034189a4d869c1940d3e468b74c796400a281a7592ca3d0ae3938dc14b669d5768146ba59a5a00a0cb894a2ebaf50a1f0ffe05634774676601656506e5aa9a85f23d697cbd6d085c64f00212d171094508111801fc84d2ff402c4e3f0893e09316565f19899ac3b25dfb102a7348578e9c53466fc54519b95ab85a5ddc20267211e80391c8d1edfd8fdec51689cb2aa398da211eec2226adaf00402614632c393b4bac1e2fea04ba2b42a1b0fccf8a35d2247572cad9c710ab9a4fd8d57272b7a929b91e0d14ff9bb6c258238b28c42f6cd498f690f3073c209ff6284d94db84beb9d0b104e12274aed1e7c17881b6a14090ad05e50b2e73e787794a3e24743dfb380d3e2524b7ea2fecf144573399018a3917b42d708fa957a1b4da47d9f50f45df63c9f01758c01e14141c066638265ba8cee7ca734501f4bc386a481bdbabfa57213268e17a0a65ea9aab54a147b9d3689d469bb19899896f0c1b16ed9f6b2bf339ae0e9dfde20a2717bfec33b61a0fd9c01b0f239a3bf147e3bbf5169738f33fc56e8e4efe582fc34c090ffbb0496fee6bda92a877c8ce8d16412196403f89473aefba68556499c8122a9bff466dbbdfb4febca505499520e03ff04ebdd919b6b1f7fed36909dc32415fbb055e0a6e9439fac288a9a9bb7552538de1c9b7353bd4f5b5ab4ad2b66c8af47613c7a47f4fdebf726b73a4d97b70aeaffebab6dfaa6626581fff56c4ce91c439c8d892aa0d99a1efb0ee3e0e62d42dfb2292bcf7e8ffb46a422c549dc262cc952c8980f01273404d59110527b1a23bd064ea28d06837e75d6d4335fba5c9866daf8d9605a38598beb8fa6457fa2b61cad162ccdac250b300f0c54ba51573a8c945b76893e469b923dd2c1a63855505edc26f2784d813c377ac059ff0a0c5ec1a31121094bc534f65c3cba7ecd4ea232b5c63325ce1f6b2e1012df0f9249c3a3004991f76ec18fb2516827f1ff22f0100a2864f8363f9f883fbd800bd9169ea55c60abfcdb90fbb502a890a36aa3219c4b2148a7d28a9a661e216d41a4434534f25d2f3c36fdbd18b8183ebeaaa35ef65a5840f58036dc798b22ca1b68f778302e13e73c8fb4e0f4a17bd3ffd7b7fa6b6bef1b45be8d16b418a0ac82874040c23661ffb0c784a0efc3616d59202fad312e74fd393debc0418527ff609de6f46cf6236dfc7dc9e36367b01395436153534b53bec1858ce98d2e9a63bb90734c09d2a20e07cc02d3c3804e2120831e9f693e91e1faca3f5b24478f181d01bc8c661bb5aa3b00c52f3b5a1a36044d87c2e794baea7001b5a50288d069e80349459b0a42b10220e1518a5e22e9d058898619c53cc915fb75c56bf9de6a5a4e193c7b07e061e1cb45152488f24c76a1875e688facdc74f602ea9cf28a561048cb4ada001d95342a75545840605101e36248cb928a5d966ccee816ac0532cfc06d7878c21d4f16d6816904dbac57e6950936a6b55cbedaa0d65c5b3088fff54f5b6393a5b368bc5a61a3ed26290911214b2bbb77c7087d089d084a7aa793f05149c7ff79d9729ce56ebd493ace5b66ee725cbf4e8bece9d80eb3657fcd719fa1709ce578ba9d7ca42e2f24e2b93ace45b9d984a7db6bb97964fb8fbbe843f9aa26226f4044ba80888fcebdd5463cee3e778b00991e1a5f8d161b5fee862a8c9fab032ad8bfbf82ec80130ff0e837b4e17bfbdfaa868bbdbd92e763f74c3c7d84eb9d185e88a02191627821428bfe795eefbcaa93e0d7d5fb7beff5e6178e3cfdfbcbbbd1e32e1b12f15c3824e2b9b8eb7dbc094fe73c6e727ff511fc5ceddc7b5fc32e097eeeb939ba303b3739243e89530017fd22f2e7977f2bf7f72d1fa78bb3937293bbbe9088e7f25c1db697da796d6843ac2700458a881ca240bf7d6b3f6f5cec7973e647e8cf3ff50a50ba1dc028bda802e8082d2a3a024a0d6868442123692885fc54af00450252ca14b2110a45bfa10df73b70430ff0e8f6ed7fa92f71361e0a85a3560739e7bc81dc7533c833da9e7fe3a37e97ceeffaf2bbbcfcae2e83b26f4d78fa05ef37a9fd7ee617cb1adab621bfb5014b3de6709c3df3f030db8071d9fe89073bb275f0a9668188253a68627821822686172158add1a2268b9dbfbeb62183f9c1edc1b73a068ef3f3c65db3db40301c793af85de6e3f7a3f7e3fd8dbb3e97e7baddbb66b781bc094fd7df37dda476ad439791fcf87338d29edfeba0ee637e4fda80ff7e174afac26187e2cdeb03fbb5d65aa5905a6bdd9ad8194a4980b1be9c13ca46279dbcce3927adb4d63a643f6f28f8a70bd389c39167e463375a57e7e2e8bb2c9d78d223b4c8dcb66d9b7372496e68439cc4eb74d2a62f1f5371ce39a795151c5de8db96c452717e094d6cfc540ab98fc31163fc38bc61a77fe0de0045d69b1ca0cf10d78b44538385acc1e206fd86d7d2ee3a39462266cb6d568bff8f74a3928ef1df973ac9f6f8b990e34a6862731c9e3e5cd0b91be8245b688d3eef3fef3715ef7b9f176368dd76f9fb9ad4fefd77b3f755c7bc1c7e7cd4ff7de5e374e9be53f53782fffde52e5adf05d6db84a7e3dba476fc6123f6b9ff7ed347b8ffc271f59688943df44bd903fc8faf42908fdf6f7fbfb7e3f7e3f7dd7799dfdfa9b27b36e0d075847bfb5c68c7398652cf4d8c4f94dbd3afdcb54ddbfd887fe47ebcdfb9b08b0b8978dd7543225eef7da76ebc094fdf6a12bb19d9defe16da8e27b54288164a87dc9ffd502d4c406e6cb0472cb7e855e98b54af9f95fa98719df6eb935214eed758b125cd892acb91286db94513417de45180ede96329a4f63a80f93c134aad348c6e0a5aad8a89155059638725d67842280925c4900186115710f5f9723ec6c2499211244814db43e6b298710f934186a05f1a5798e0a70b164891a068066884c14618a928789861f166263800a74575d2398b3e4a2659e3a6964e7fe709da1942568429128328185469d105d40f92b498f1d002173475c102d8dcd2a5092806504f3cc1e693510b50504518652c6d9963e0e0f8e04a51d92a0e2c4e162e8c1e2a4e16ba4469eb6947c5e6baa49da174c6155370b25824341974e170744933038a76c6149d1af605576c2173d0271b5f38c144126c7c81cdc75848271af4f9723e9edfba820424e8f325c6a204b5cbc476bbf56e9a169020251069a41fa62614df153a1c4d2ca450aa02860685acef2e95aa30d1b92e95aa6899e2b0b8646c71458d1f356a5fb82ba044113366aaca065cc200926098a00b1441dc604a0e9a0000106218d5744083591316b52c2fa0f18047554c4105e3e1e1e179f2c30b2b64b0ed9f481a38d12383d97fc2c3f3c4c6081bc0ee3fe11186106cfb272ba6358a80591e1b29603c4f700c01bb3443c0b6900bfd273448c06cc8a5ce0fbc60cb0b7eb628526aba5152fa51a2813152d2828ae6c988a94e3fe73e6223c650187c1267f464ddfed71981a12fdbd1640f0bc4e96bdd94cb06676afeb02d6cb48f5a494c54a73352b23d2e3be5b8f7609a774d34c77ee6dd12cdb1df4dcd133a2eba18bb347a8dd2ae4641be7a8fcffe5273dd6ffc062f9c402f20416ad65cc2b29c3ef3874b180956ecb19beab666d4ed7753545d157f4017cad15ac785d49932c77ed7b1583ac6ae56a56de920457b0abda690ced6069139f46b98094aca1ed393e52b9c139ed8678ba2391b54ad7393a2ea7583aa39759c1b54af743e9da1ada222759a7d72e756def5696c9040a1b2856ca70d77aafd2b9fc4c95cd288a0eabc4b9ad09494f96dfb19aafa4e9638309df0d4514a65d968a0c5094ffdc06ca928f3f2bf9d2dd55122f3e99ca938f22062d39f349fe96b95c1975a46e6bf0d87132acefd379ef5137cfa92791c3880e3250e196ee94b2799445bc884be74911ae8cbd347648cb07efb196e03ebb7ff32cdd3bcec34bf43b1364263c3f6338fb591ed671efc1d4ac365ff66c271e665decaccbc9ce12e006d999f792bf336ccbca52f3b13e24d5fd6082b741db1613ef8f3b7305b6d6486384c32c30ad0579da10af4753f891c3f43d5c9115a9a33bdff56d9527189123b04b2477df9b42298fa28a9b6d08aa8f53a7b247dcdf9252419425f45b6079f03b516365f22bb122ace503b913deabb9065b7e8ebfefdee2dfe5152f5f9b266a1e04fcd25d52897c62969c6bfbf5d1cfac824dbd0ce6828c8c6961fb65459a99afa01fa115364a5880a090bd2d29395a72d3d6c09921224268b952c53415882a6a6a44c9d81d403921a5a82d09225284bd3d3104f53ccd4d492161fb43c5d79aaaaaaa255a14d2d05b1b45475a52a0dda10b4317e7cf841fa0169694988a5a59f293f4d40349911e5439416202d4b597cb24c2df9b034858444c6540f5354413f0499b16794105162b20c9185aaa74a0f19342bb42a30406096840063a5a7aaa84a514f504f5514952836b450d122260a288a8da69fa6a7284f6280006289cad219413f4152514144a1b1c708e2278d2d58b65405552d3d3d5555a91253258b1820a6968096c454f954f96095c6103d6588b2afd208120a5af2018c98a2a0a2339e829ea4c4f45ce991a25da19db1655faa8a52d5837902195aa66859da22b465090c1530628490d6d84d4f3e4f4b3d34a5b13465690754a6236132525b7eb688116a6203cb54d5cf140fc8889a122555e45324852405494c14da5250d0187b89c44e2fb4c0474a6a0a264c364b71816292586a099212434a78e72d7bb471ca3459f6b8253e5a02c4d015a1a1dcc31e6d328d1599893ddab46c72a691c570544506303f5351d4c00414c5474ac980022750427b6c4da33984f73c92a148053cf3f18e418a7e0824d8e396f8851a96b2c716cda4934e3a29a531da91b243f0b2479a2e505d3e0c541c69fa9c31b461e51ba27d4142c645066d5891319aa2cad21955a4612500b531c8f0a141214185b7c4c9ecd00ab47c522bb862c97be18b23a4fce0872ba838012b8a810e5f7e10c50323590a2ee66c3a4ff739ec80bf0b5d0de0603cf83b0c05c6e5efbf768bfa3079a9ea3aba64f2e224bb0e499f2573e8e3bd771b7b4809f4453d59976fc3138cd8354c62e3b99fc30edbdf30e4226137dc5ac916e29ab3ed7fed560e28172143b3288eb468e1c27d49c24a36b78df85dab3ee99c95fb49b797db481fff7f78042bdb4675d72b90fe26936d59a779a4ddd7eeefbd4f6fb88fc3ed1de5d10fd0a7ec818493371ce9e3708fb0147a6605ed0445b02105a6e231b484d31012d57cec03982e957cd8d27b74a9f4d346a751f2618a52251fa23aa5b4ae7e18216712b9c5953e3fe3506a7fa794d2dfc1dc40525c82a8211186ac08a3e0290626c0011568c86089100ced3084097a08c3073559125287313d6a404e3426aed0b450e93086a3ad60484624b3729d92385a620a2b1c0e0940bb766a451fc15ea7f53ccff33a29657f062b77a48e7c1b04e3bdedaca2efd07963ac70b49d75ad7d99bf6fede5b3c665eed33085b3465f56bc4173ffc6cb7c37f8ea6938efe0d3dce0f9696ef0ef696ef0fd3437b87e9a1b345cf6fadcfb2bc3bbbf329cfb2bc3b7bf329cfeb516ffb533a1657d1540547da7ee5016afa16f3eaec6e944aff307b98317fcf082250b1b0c71346a20460753269da690c11847f76e3fdf5a5bc7c9454f1b9bfac8e8ab9e20658f738acaa8be2f6daa3d9946b0d717b2b4279d99335ea82049054755d6c8cea098eaf36d9105833363c496fd9be922ad50e34b931842b480044edd11538c683ee832032cde0edd2cd86f8faa4daa7636df1a9130db5c4813c2c2d8230e5bf7df27398ee3c2517ef795cf9e6b27a7962f3512286d74a19d4d5b64445f9316855097b4287cfa6885fafc1f5dd254c0d4ad50d5b14516cc509f1689a8cfcb7178b79e09d5a1e397dcebe99c4c0a2a2f524c40dd239c5070b4445297ce7d39c12bf17aa2d31574eec7209de338fa927b8fb9ec1d7fa9832e695110f5a9bdd0cee86bbeccd19e5de6d006d5a1cbff6a0c40dbb32157f64881ec4cf6985ff3b447eac5ac0a2ffa7c3aab18ef0d84f1de3af4d1ceb2cc393b75f99c94549c8c63c2359c74d4e5e3593789ba9752cab7b3fa7ddf4b29ff931288d62feb6c26c73f924eb239348f9cfa6867dfc79c99501de43d6241c9fafc105495510519569cf10316285cc61401832a5e78404548564485657d16d5687d72518434a198f511fb50713e9611f5f9b8e7a7cfb7184b2425b870913243c9873092d604154598f1e4c50ea26c0bcf4208434e24c9e67f1f3106aa3a39a0803801114a440d9102d87c2c547576808841972a3282b0e207d87c2cab3a52e98a940f9a8c38020656c0e6639faa2391aa08f3451518545a70049bfff570bf71b27e3996d1970f7d59daae3f3ea0cbc6b23e3186026359976b8cd16928dba4685ea8684b00e1cd682890d194a86263cbcdc1051839c092450b8450f2408d099f138889029406149fc419eb34418d2dbb0969d413a0f6d3d7f652c738fcfd3889721da70fa7afbe391c31fec21bde6e4e33b6ecb4cb0ececfdbbc4c5d94ce2c6633f4108df3c73e61832eebb2c3f6446df3b1303a379b6d6823a3d7beaf564fc75c0b009ff52dac7e9760d35e7f891462d3b79f410ae95ab3ba8536f4b56d7f5ffeb644e66c21a5f4d25b59dbef7006bdc4843266077ff5f3b7ed83482155490ff8abc7a04dad59281d5d61a9f35f79f329b6a4cd94fafc314f29e695755965cbe6c87aeffd1286dc1f4b0872c396ad7fb3c41ee5520b35c88e14327b554a9a7558857d96fb1728eb1e7dca65c782800ab695e2f6dd6329daef3e4bf17ef7528a5db7b1acdfb7aefbaefbae1bb6d0976ca9afffaa5d98e0818829c0fc3001ab414a3d78020c2ecc408201ac86f55ff577fd96cd1adb86b4ef06f9584a1936996d587bed77f4c37fbb97fcbec4ad97ec51d3b4e5032943e6007449fb92c58c89161c5154461a5854092db103a036aaf0f2031558be8802b6460c2af7822043e08ea37d3123a74bda97333ad8256d56021a1cdbdc362937eeea3077a5b456da6aaddc92e322128cce7dcdf5feec551fc9d16f3882a073f6eb5671d45a31776ded3aafebc0e81b15a9d5315aab75d9ad5abb61eed26db376b3f6bf5a372a7717c50d8aa312916c746bebc5014710741b726ac4a43d5229143ca9983ba7a598d2b17277ab14e30ee38eabac2faba5b54accdd6d5a5babadf53f59adb456ca11c01104b39b9b185cf978bfbaaeddeef5dee575734e3b29ad25b05fc296d3768ee3e37dee2d775d7a2f47b9cbebf0b41cbdf78d78afedfbed4573709074b17fc4e9b58a4d7f02b11d88982dbbbcf688abcf4d81b95e1f6b4b6be24b975faf354b5b3e12a50dc4dbb89bc151068a2daedbe4e0080589bb592fb5d60f584c3db0bdfe16d73d3f636eebfdb81ff1d3e0222d9bc9dd8fcb93d75c616dc8658ffa2f7bd4af49daf3c7efa1b3edaedb0b64f2e94f17dd289d1373d7d64aeb6631d549bced9b1669b5fdb77dde36593177eddc649d75ce235daf54dacece19622878d6316eb573d6d4b6f4e8ac9a88fd3ad26ea74e529f16f1d1297d49eb534bc7fad6556fad767bfb74933bdb398f74f5ea24f5377da4fe4f9d005c3b9da43e904ec3df427b91be9a30f8bf518b7aab26e2c3bbdb78df86fbdb7377167d1c17658a2f9f03242c87397cb45573ea770568d501d45db3c5fefee3f2d445ee6fff711efb4f3cd83737165af8fe6ac17dcfe5d9fdecbadfa1386c32065f444e1db3c0d3d0751cc7ca1cc759d66716662269dd7b1a8f86dfa153c768fe1381cfaee9c747efbfe9f238dc7ddf63eef2a1330be3eea3b98ab1792cad7ff2c0679f3bf0d9456871a9e3fb727671a9c5f8c06cb3ca373bef60651e32f9b99c11e3a3c99ccb2e4288e3cb9141687d3abe9a8ce3ca376c32cd4d96e1f6e3919df0d941f093873c79e0b23b71f23b74eec063ad98f81fe0311dafe3bfa89f3a96c3e3c095d017178e4c78baef39eeb919c76484e7bf274f7e87e2274f42f052c744f03b5407d97780c75cffb9fefb687eaa6328fc0d5cf6263c7673f352c7769e033cb603f61be0311ecfe335c063ffdfbfd43122ff7d34531d5be133c06567c263e17fe14b1d43f21f1706d53105bc0d5cf60f037cf69b2f3606780cc77f375fecefcb228d2e027faa63307c0d5cf60bf058081178a9633284f052c724f03bf41b2183502014080542815020d447429e3af0ae2683c23ba612f20ec007e09f702f0b7dddcf817b42f4759f877b41f4757f04dc03a2affb22e0de0f7ddd0fc17dec83f1deadd6ffebf59990a70fbc73c2bb2710b0a6bcfe3eabe7f5f757525547d29c9ccf792259f3027c07547540a89a731fe3bd5badffd70b84eab703eaf73154d56101d59cfb18ef0d85a1fafd4d5475ae53cdf1a93adc4ce6ac6a55673b111161bcc7964fbf3efdfe7d7006ac297d27551dec5341262ab27ae4ebfe7d8ea9eaaca468ce7d20405eafff566b27f924f5bb92eaf7ef7f1d057e87c27ef678673763be39866a9a9f51f1c65f0afcfd6b44c5fdf7bf6e4c1681c76ebce63763a6bef16342f81dfae531389fc49cf25d121571fcfd8e46c507fcfdae464507fcfd6e898a4bfe7ec744c517fe7ed744c5d5dfef9ca8d880bfdf3d51d185bfdf4151b185bfff817987b28c5860a8c880bfcf3aa222097f9f85444516fe3e2b898a0bf8fb2c1a15c1bfcfaa5151c9df672d5131c9df6731517184bf0fea588e1f792cc77f3b67718324a6943120fc0edd3a96c48cf21f4d0e7f877e38c648cd7f87d27cad9cb330ea33d7641e7ff33bd4a56336fff1c83bc684f1419f9f8bbcf64008420e23832e4212b3e7f307f8ec1ee0b3e3c067ef009ffd063e7b133e3b07f8ec1be0b36b80cf9e013e3b133ebb0d7cf691cf8e013e7b0d7cf60bdc8c69fd0ec5f9103066a9cb1d7a42b600d74f0300748c461b018014c204a1790586e822b403a9400fbbc7701190dfa19f013205b8fe9da36337509043440b2e377e877e4426f06302410828b2ea52490b237e14c921ec640970fd33f0ae1601de2dc9c03ba61878d714c20e2054d042881076320c5c3f047ae8188e103d8c805d2a69e183630496e7143e612c208cf76eb504c002baa122f263caaf907120203f80eb77c09217560d70a1051c37691cf1a2be233907973d85cc00ae9f041678b7445ff717c03b26faba0ff2ae89beee2be19d137ddd4fc2bb27faba3f02efa0e8ebea29486e974a4a1ce54032a5f009bb4e02f8eb749d760c1921414a2c2b80eb4f80093a0602142628c00b080a289267949f2a37511b4990282a64245cff11213a163e216401b4d0485e81eb373244c7b8973d84058cc47f877e2c7c47b20fde85913deeabc0bb2ce68ffb4578479b09e06fabf5e316c0ac5f2aa1007edcfdc607491890c5918fdfa1df0a59f39baa1e7c76061c403799bdc723c944b8fe58d7b1d7a1bb9014f509c82970fd0840808ef16802010d9841828702328cebef311ddbf1137ba1cbb22349dee1fa0f5044c76e8a28b24486ca0d0a5cbf018ce8988d90110764c1838d92acf9cd1401f8ec0e38a29bcc4e0016f210aeff8404e8986bcb4e0004d0704120d708a911b2040c1b113530e4194e0bf0af8bd03e13168077b43362081335f33bf47321cf1e3e61b307ded56acefde9c399fa7d507749663c60019ac8ec49cc9e6f400ec2f5eb3040c77448312002788c8edfa1df0b59e4fa4de02ee8582bdc810bdf0c5c974a4a6ce922c45abf43bf19b20cb75df3121e045dc47699b063923dee97c07794b1b99712c89adf88b16d974a49687411f8ec32bf43bf2559f31d3ad8dc73cf0d80cf2e01adc31a18ecf931e826b30fe045e0b37f72c7cd0e90b502d9e37e0a37b659d1fd2f96456081a12f9691ec71df6ed95ded479651bf0fd34468ef92e8ebbee61d8dbeee23e96203e0e747847589b6b04124ecdf7f1ed78fbbfff11d093e9ee54367d68f11befb11befb1f248cf0852e23dffff82ffc11da8fc562fdfc9a7ff69a3fd6b35846b20822f75aebfb770e35e1beff56c81db7dd7fdddb2a6bfd42aeb2b8ec4038ed3f38ed730a97b029854bd88cc225cc07a7bd07979d005cf60170d9670f973001f0b1abf5fb39fcbe0cb7fdc5c7ee8b7e3f007cf486fa7d00f010b8ec385c7610b8ec21979dcbce83cbbe83cb2ebb8bcb5ec369d7c165971d87ecb4cb18e9dec3e07b2d29040475a6227efd9b8adfeb9f3aa647efb1cbfb5c463c0ff391f52ed65e815f139eee3a92bffbfcdd779fa77993ea7d87bdd54aea24dde7fc601215593ad692425adf0dfa55fc4ddc75e3fe71f523f8a3f7df4feeda2bd0e36697236b5ed3c5964a2e98f59145837e89c835ba3783ee7de6e3a4b886e3e4dd773fbf2f1c41d03d2e49175ac99281f2844e2696b034b28fc35c3853e5fdd8aa639cf580e84bc81e67aa563e541cbba84e39313429669dfeaa878a73f6d54fa73f53b5eaa12f57978de372cc5ddbc5d65a2e6f2e9dbfed628bed6fdf4d51d1665717a14d46455f14aa8f9e90ccf3f17e3c20ee0575539346d117eda4ba29aa3eae643e9dae64f4e57a62d3a74fa3649d7e17d5494d793d52c89475559dbec5a179e22022bc65f011e2a76a0905a293fa208314ad0626895ff821d3c4d084c44e2faca006bc4f80f712122f0122c20768f645f6c25117a321bc8f649022d3c4400593255983628f3befbdf7a612bbc04a0c4ed8ec544b41d23492b8b6040b934c130350d28fac92788953124c334962a725434ea06625209a40332716c09064730c76ca1e69a86c1e628f2d59c31ba88a3d6e2a899760214311524b9c7a9a90f09e32507942ca08aa2615c647ca09893d06522e594245f91348953dcaa608d410030dc76e860ac02085d04fc2a476fb4cb65ea59412cb1e04904226006a6a64643c4fda295b042061aa28409ff6e79d17890f501183304ca021a64806ef0409a46c8922b443152906092a5d0c21841557d6e081051840445099aab285fc968442d43406181d52b0031042d8d820e8076cb04105962cce18527262e88a2a35886a3244195fa648011949488933babaec5937d9cf0ec6a94b9a14507db4545218f51a5aaa2afaa2a22f5b455f4cec71cbd2e7cf2c541c2d55a7a222fd29834d3054c7c290faa4a2393db23ee7e663a9fadc84fafc1aaa0e956292753acd4954753ca80a549ba8acde208e3a146ca44647f2a84a552a2bf301b2b0d10a556b89e890507daa4876490ad95283aa28ad55255547c296360d4c91969aa5cff972ac3d7d8e94893af5c964aba8ce9c4f3d3f5b509ffff30836cea43e6b348ad2a9d6a4ea73ce6d0897f125d1babc1677788698da24fa92350bc61eb52c9810e9a937cd8ab41059219bc50a0dd91f0b24ebb6678abe2ad54f3ed56515545493536d0929c908cc96d99096a02a547dea0f65eab4694e3ae79c73ce39914824a9a927faa250495dd2a07433b39cfae5385eb3b4e7ebff664bce39762bd0eb388ce7c69bb5f10ee98ce16fe703a790275c2ef2c7bd5cc023a4ce9dd59cab736b35e70ed19940ece071f3446706bd145ee4ecd67e7ad5e1a65a51fba9091beda3eea3937c746d8aea70b39af3356d1a1f9905569dd9c34a67fad0507566cf8cce8c72a3ea4c292d9d394547d599545c3ad3ca579df9838dce040aabce0c828a388fbfaa7e7bf24f5014274555736e952b4c540401470835324e72705ec7a141f58365ca380a62903fea8c76f8c7f469d93fb08795cf7f374cdb070d3d33516e48694dd141c565e57fb001fa0f73fe2531836afee33baf39ec51e0fa6fadeab07a68cefd9efbd789524aafd37740dc6c27eda49db493584040336eb6f7aac632a239b7b5f79d61cc323242e13934a4087621a5a808d638aaaa03824c5440f470c12f656201e2ca7fb36e9c7b99631c5e4ee1b13cec678fac9e7eff1bf2df107ed33f3de43f9a391f32a404e3933e6543b84de73eac1e960fd59958c2ef7375a953f81d9a420abca39d20c897798de8c9800079bdfe6b52c59a48ed621884939aa4af10b8a42f1cdc29ebe892ae04f124ddea523fe1fcc913ded1b0e0e81c2ca0a9598f62117549aca17bd303281c457536119ec250180ac4414444b4ddf080ffc842c2f99145ebf7c98faca57ea34b9d23ec68f4e5f3c407c787875d921410be55e6345dea989219f43b74255575baa52719cd8aaadfaf4161b7c30441cc74a943ccc39077b4a22dd33fc99ab28249cc207e87ce20c22e0903c1bba52b5c5213c6aea9dfbf210388c5ea52dbb032e63636b31fb8a439e17f32bb4bfdff5d5678dc363fb678ece0b4d54db893c2b083eaf7c37187f4460d1950660d2b331a73974b46852677a975d064cc75e8e032e5c6d7a56eddc898b75a55a4e0f0bad43730bf718388285d977a66668677b42172e02e7518d923071ab3874b9a33762dae4b4d03e634bcd4311a78476382c64766e9b87d13a97d875d92127b0493fa7d100a4481c3f04e7846cd121898b6fe5daeeea4709495b4206b3b671fac4d37159024edcc6255e13d5d8d9a30abfcfce13d3e0f9b55c26e89e6dc97f230494dd83766c6ad8109948fb7404a009267a880d3ced9076befcd830c09b2338bb57d565237a6131eaa5cfb77b9fa38f7c3dbe5000e2b162befd56ac55f0478ad587baf660f9c773430dc01377d7e7c58bf654cfb77b9ba69f6dcffe1ed4ed9ec9175fb67ef366bb5a9d83d7e0c3efe4dc730c85b1db7f9f66ae5815dd0f4b14b026b54ecbe90af7abb25a77e9fd3446cef92cab83185b20815b9b9c1964a2960ea52290cadcf9bf5edfec379b340411fee7e76dc7918ecb4f75a777c04bff3b80bf440b0e399b5571c08822e23f8c1c71cc40f625c37b96d1d0575b84307204d0a91fd82b1696eceae6b52e7dc2bd0e34d78bacbc864cd89b3e6d8d565cb1863ccf19997ea23be53c813382af9033c42ea7047542ce81733d1eff6d22f2845bf9f85a858f3f773162a0af9fb79888a5387bf9fb55071cafe7e26a22294bf9fb750b1f5f7f38c8ae2dfcf455434e1ef67232aeaf8fb190c1583fcfd7c44459dbf9f91a8e8fafb39898a43fe7ea651f184bf9f6b54b4f9fb79898a28fcfdcc444503fcfddc44c59bbf9f9da8b8f3f7f313150ff0f733141577fcfd1c4545d8dfcf5254ec7f3f4f652a2aa6f0f773151511f0f7b58c8afff7750f1589fc7ded43c5d8dfd73f54e47f5f03517185bfaf83a868e4ef6b212a867f5f67a12292bfaf87a878e4ef6b2d5404e1ef6b222a2ae0efeb2d544cc0dfd7335da48d34187da4917492a6e99a5ed24cba493be9270da5a3b4949ed25454c4f9fbba8a8a30fc7d50464508fc7db007f4017f40202ad2fc7d30888a16f8fba0101569f8fb601629c4c7df074b204f50e1ef8326906291bfff49551d8c3faa2deb172afb4001f5bb896ace7d2227a21ea40832d15715d5e1983e202a82e0ef7f415474f2f73fa1aa337df8fbdf101543f8fb9f162a4ae0ef7f44549ce1ef7f5ba81881bfffcda828c3dfff8aa818c3dfff8caaceece1ef7f495567fefcfdcf470a91f9fb9e141581fc7d6f8a8a15f8fb1e15154b0067205ff7c7efa7dff1ebf1f9f13baaf2e357ebf73da3aad3010d559d55ad888a13f8fbde8c8a3f1e08d4cbe9995ab59dd4011df54bd4efccdfef923c1f2a86e0ef7b3f5414c1dff780a83882bf3c7fdf13a2620e7fdfcb42c527fa8178b217907fb57eb76abcd8e39ce1543be1e15be2dce13ff052c772a07de63d80c313a1bdc635a4031f73d9a070c34b7d4307666ff2b19b1d300eece091c206783c110d3c5f21033c44c2240441013680a024090b0b004116c01c0c18bf886cc04b1d73e15ff81dba5afd92973ab6fa1d8ae30118f822b24b1d83a1490d5f44769cdfa112b8c017913d84dfa13b1ca1f4bd45089924a8a4eb17ac9a18744ad1000000000000f315002028100e88c442a1240d824091c30f140010768e4e6446174904f21848721044318618000001800060083084183248d2015472a7ba6832e982dd940b7317d2a0d8734950da9485e45c76cf1d593be4f27f7d4ff16d0bcf1f767d6790c5050e80dab5087e44bcd9b2a0c193411ac9afbc29848796cc7344ce20cd5cfcdda2c8d0a2dc727d039e757e61d8f18e6c6fcc59c9379f4ff27caf1d37542376feef3a7f313df947dfb236056ee560063ca778d57ada004b84a1b93f12e392f9379743245b1b08c9a835da344c423be65cc36b701042302459c351277cf056ec5ed2d104aa36d9424e06f9964d2f80cc9088894ec62848af8d811718db4de4d040f7117fc30608b94b910a55c9288308ed83e362e9848f7f9007c1fa45eea83bf0833cece63920ad68b4313e12a152297127321d71c75abf30d9723b0cffdea0f2b42af1db4e47468e5472e9e2d4bb4e7842a4d58c6c57741b44dadf374065a34422c7bf9197586326dae95bd99652be499b0e317b0d7a097194b51ad925502a66eb47e60c16657f3babec740c1e659c56c711b515dff6838a0bd20869accd35cc30362edf870972edf94a26105787fe25eb3a086939c22c6d611598fbe201274350b356317eb190815588e6c0d62affa97c913958709859bba9466f518c15f20d9701e6d3e02631be638bb8999ef65a671b55d2c010948a694fea7c33d5736c248dd219d5d5a7c593a26c65354f83937d442a0edbc3c150eac36c9cb51f65a5c92ac281d98030f4555a321212b50b7c171f13eafc021f9e520de6f904b7a944e484f8cb02c4f78582a9c60d88db19140e99115b3ba9660875eb26468216e149bdacaaafc83c9a46a29aa0b1fdcd6ba12fff003e02a0ab3102098201ac56e9de9920ff9c0afcec8a0a829703984a23a0ef1d0c0fba348ca44d6b986384415564d2ff9f031b203ac08dca8eb5440f81581e5547557a86e94a6a1914d42c5411ba93de8bec8f5f9df1277f59b31973fd021b592551339212db0226b73c260a5c05a2dfced3cb113f2746a17a262a760dfa7055159e058b7f2c0c4fedc37ff28050db97c0455be6a2025402a80a5005bc1a64154875b0ae16812fbd9b1ccf97ea402f9048a24a8ee1e7eff4b553a97c1e274d5cf6e7bdca5649586da3a3a57b7d51b8901c3a8f09f0bd16eb3293070c654c881a6afac28623f097c135ee998eab41a0d454e23b9b50c501b6221ea960b38c43cb74fe7f4fcd8945674165e159075fd129909985f5f6529d88223238b03d9d0d06324d6f83d9feaffa3911b18609acecea86ef4c9ce01bf3572000a372ce7960f1ca81903688adb496826977e88e6e441d2b2d2ebaa7821f8dea048852dc6aa2a391b44ea36f8bda9c6623b38847add158cfca188a73a556c5928c5e6940adac48a9516a9619bd463c20ba3924b4790bd3b0ae33998dae8df4e0defdc9204f727ea43d5df6f3411eedcf3f5c67e13599726cdde1cef9c720b56adc8383f93a1970116e08201c82e1d9488740990e89a028bd2258772b237e5ae50808fb8184711b8f04c6f09d84879c55c2383e2e71d0624c8082d69051b5d80de4cc20e625a15513d57219f24733badc50f387fc4c3d086cd64812b532aa586d904ccf0e8968891c9602c75071e359d8a81b35521c347ac28c7d3fc6b787519fd82893c33c00377a032034061869c6305e37c67dd9784281801b43d3b1bea07363d71721c208a176c871e3afd61142281dd2c15e447d870c13b8dae42a15b5ff1ea157f3efa507f097838416fc19df59f03ccad16c5a7d07cd6118f253edfc324cbbcb2b9d79298bb2c71fb0bfdab0aedaee1a272d8ce796f7f5806a67172f965c11787d0dd00beef77ecc2214ef895b64599e753fd6c68b9f917ec3e51164df045f9db80775f24defd245d8fca65ff73b7f25a111bd1ffdb62a3905d0dddc82cd24f7846f4156218f67e5fec81dd5fe57851b34d63fdf385a676de7f8c706ebb3ad913787334a3bde30c42040d8c018f267c86de3aae7b8a212c2e17a70ae344bc35eb63579981140a229f972a7af06b3e6aa5539f788206c00209697a813569e342f901c6506512ca3108754292ecde8dd602cb11effcfd8b9858c95f6ad3d579542cf3fbf3bf240dd1f658e417acf8f0305d6f983b2e73a0d7e772181bb584f5c0fd7f88276f8b70015a5d183e0c718abe5dcd93801d243ba8bdbd6318e2bf8a5ce0f673d4b3d2412a23c8cd84ff9742625d7180d924f3013611d3a80dff041c663fdfeae235b4e7610b5fc2140d1ed6492fe32dd531ee5e9bc4f97f46879c01266dfad2e238258c8e845905a3d6edb601f82b6b1a0a6251417724db01a580a8e30521248b5fda4cd8e71f59a90a080b254b70425f163ed942e62718daa88fcd221978ad9b0aa1f6b8fc67302c76bdc8c82c5271fe49fefbea3322ada84ad8b70c28d30a44a7e59f536fb0086c3ce591efed19289a6e02691fa36be35f863160e3d4d6048dd341e6b59fa902223b4bee90cb15d4e5d7fa93a5809c5cf51651a47ebeef35fbe05cd7e40b6a7c54539c9c43cf9faddbd56529fcf6de4d0013fc9346c5add969df44e6046bf88ad4c7303bdd5579c7d85a7bf41c2f4ddebf7ae95469540bcce22aae57a500f6ebd6cdb75d2beb25945fbe4b21fbc5dac91800889b6223f2cb09a924473262f4b75ad685712645a2530c274eab70c1d2f7923b5d9423c4402eb75fdbbf5ee544a763591aabe17c5ddc95c40193a0b627f4f8ddcf64454a3ae43943dd19b070929ebe0c06a94d7eb8190d76740bbef80faac22ebe4aa0f0e70594b30dde255e86fc935cf23864c6252d70814f6bb70f959de1dd4802f96816b6d2b79b7feee03193144d70ce0ae0ba68d081eb716d98ac8bdfd654075b4a50f9426ee5b025ce877d74f63a1c6ab54f2abd467a5488f6b80db35253eb25245fda9928fb05fdb6de6b5119047df4331c6eb85da4d8413fcb79b6b861f8f781b14b64902183b0699340a7e08bf29d30162bc4f55bb37a1a873c982b6e180327e03d301924166f4db37b6143f77925d439d8e7fd399541cb363b33e3e3d113fc5722a458af0883ca2c8367cac6457a2a029cff43a060ede65bcf60fc50ead3d967eb0e9405a1a2b5f96c8b8fecc2a06c17d744ee3843c32c46847de3fd935ab7b61991fc3a7209f8ed1a80138af14ac72025a7143281d7d89a436b93cd23b4e0616f7b8f4b20f7bcf521c6b168fe5854604876b93bf9483ca0628a401e3b8307a337452495843d87076d3445ce741742f9a7a52c184887fb7c3d0b4cb938820f6fefdb105821462088a68c28060c63e3d064dcb071eaa7bcb5b666cf5ce3ab2604e913360f56ac1eeef0a1a52ce47591ecda0c639b09692f3bee366b5a070e2ceca2325a0e0b664b520f92ac9a3a0e81710997976f32f715182a2726712ea86548c5a3490d6f1813b7364071e58dac7d232d59270fa31342e643414748fd5b427e1db4e454bc9dc614c15f3daca545803c196503fa5599160e0eb361ead01abb5f99283be1ee0b610ab5f58aa6f916e444bf74fac95f9a5a0c424bc3a1873b4c4bb909f5e7c2c9a143aa7f7c948a27d05cb2a6c30b370471192f6c9f77dd9aafae9a1e05bf61231d2110608648d861c898137d03c349808ab154d6830af28e3cb4caa0a41116b49f3e27b6f7266d06dd05f8ce7c9ac3c21da169e27db723d13fa9200ba221fc010e8ae4a9044907943708860c1312a804a0d588fb518d1679bb32f567493e2e6a14d3a7d1d4fe49457f6a198539d33772961e35ae35a1c99fb6b374e27d4b01046705fad3ccd9008b1efdf05bbd8c88070977f33a896a0e31f545dff9595e57ae22b11abec1a190cef5f60ca6db225bc0df136ac5026b04b7ca34fe6e08a1d4034db9b03f12127561620e1d0154e8fef4d207dde10a7310f24009fcc1108678f446a9d25b0c55984b36968ba40cd718c90223136fbd0dec9bb8182e893b08f1f55c71a526c54e06d0708acb03340b58c10031c05c60933e88993849b88a3e82067aa6148519f4f22147c8c7998af80fdb92bd06895bea4d03aa4618c7a9820bfe0f377379a198edcad1c32acc23bbebebd1d21e0ac92bbe9e094ea1c61769ebb78f47189572d62e7d6d4891649e2040623962f1da8d44b60410048a97367d4c754853d9339ffdc39f7ba0aa1b8a48a702b1f49ad7584d438eb4a5fe841f500952c3e44f541edf00242a7844a61d106e145633b0ec6367394e3188035213dc73bc2f8506bae171fc25f268016a3421f0ad7876648e6db10e9601c3ad71a6bfd42de8515a08d9b005dcb15afccd60e02c87283d3ee0a43a91ba2ae0d2cdd76dab08525838514a66b6d69740ff7ff96a5545e98af6e8fddd8745f76d2816e3477635e260dcea5b2b5006f57a8872c74d38620c7ee3f70c35fe3511bce64ada616992d02cf243cf38e89bf93ca4ba373c1f5a2a40a58314469c7a650d0b79d42e9f35b4579e82313f6d8dd614c93939310be84f7de52b5f8e216ad2a722cf54a6cbbc2068c472fcccbd84045416792fa3ace8465b639086a98bf15e25731503b922975434da3ec04975668ab89fa1109f59336647cee42993529831d1a2a5b4c054796a81a74894334f07ba66af4fc40421bc2423560eea720f791e1c6a6f44fb361508a4e2547942c464bb3a8ec938bdac051d4af117ca4729886888c91e2619fa94fd50f009a283d6e526a4cd149491b71ba142d21374049bc84812d15662c603b14e57e7c73c0f09c926feab2391ffdf13507e7eee3979b870307c4d0e1bdfac795968e11ff3038a06b82aad919972709d7761ceb56360be74c06aa00f85a306569a40d68f6e5615826c8b1c2f14bbb4d994b19961eebae0fcf24ab1439302d9ceb785edbe86bd333127c501c133d8bd411aa44c62d4aaff40ad6578f58e1e029c75faed9bf558f8584943108a3f46b3cdbf59b2002c5d5d62f4663ec5d00d08329d27474e95c6f4eb68a4d6d224518c99468809b3afac583a5e1af369a6d37e7d881e4fdbaf367e8ee2db2b7f813ba95f3a0d48dd96cbbd1381c741533670378bd566834f686ee40df629f54254920231016107e11e991401873db6078fa5da5d1d1aa0c1889ec9ddd2c0d6ef3c95d487a3ef889b8cf4ce0743803cf675d808fdc76c4369d45dbc02350720719a23eed24447629339688a39b1adbe8e751494c01d993c867a97920c91a32781089c1b5dcaefc5ee17d0bcd2c88b9bfd4796a8e904ac89afb1fc34ed62e50313b69886d3bc155be0ec8a6cfd487c0c8048bb6673060060262402919224e08aed9ffc6c449c91f715d24185296ab5daa09ab4669906be3c0a8fde4adcc2a40f1657c71acaf2d6fdc98ecbf496375639ca3aa7cc5ac831f6a05b5b22f55c49ec91a744060aa9a528c9b0589be51bd9e18df115acdac0a2247380eff53c01ce8de925134dd52350e01218d0e2e23c354209a8bec1ab9b1c6c5e6b21ec8dee2070e751ac3002a17bf51f19d019be20d43804e2b294ca646b811f287c744c28d00021b3dd4ec5d89ec3654af26373e9f67511be6447dcf54f92e5734e5cc5e1778e86aec44c21227089045e364a8db301bbf2a0c934c0748ba6dec39ed2067aa1d1e09111ecd459b8966aaf2f2d92662f7cadcc47e0485d4cbb0b01da9ba12403135e5277f42782dcae575371d6854289fe0ebd7f189b68fdd3f055631bd713b2cb1c83d3f76b672f94da1e57d35ff5f4b5fc117084ed79a44d66486debe32217e51edd7e0cc5c389fd4a7c294309d28be0126b025a7ea1010d8f8e20308c0287abcab7f867d63b839322b9f1c3a70508cce797c93f461b9c70d3ba67b2f740ad63f205244fe2f28e8552fd02b6484a432ea40e85ff8b7f97ea81d9cfa4e8b9deb88b568afcc4028aa3ffd5121cbe39884c56ca9315be1c1294f566f62cc7a6140a49cc5a3097119fdc642f8a7b68e78774fc1724355bd332e456efc245824ceb741c6569bb7888033028c242d823c3af9e97caee064b87c5c0412583b096df2bd47ce1b47b7b2c06c8e0980e80d0d383f03fa025ad91c41bb1dbd9d251559ebb0446c016b82110616030ffa2530d86882dcc5b2e7632104216d073c90cab8716f470617a2b043e5542ad2bca3fccf47828832b0de666618fe2cc50cf343f285626e13f4fd3aadcce10f1b79e9a8305345c1b40330fc59cc0ce8fee5c78ddcef25f5fb06aa07a1dd3653717e464abe80922a10a1b4db558ac47e46236396b7b4619f495327d8edf437c041f349e234bf0dd707803aacdd1d66aabe31be8e996d21526b215c95ea5169a45f9623f94c755ff363154cd80322e03a9ed5af2b9a1f0945f85edb7f3cda43891677124430ac95a3b7f9a8ce49e84e2a5642143d97d8da0257e5cf67683854cedeba35a2dcf799d8729c6da412eee86ab0525bd64913bca18701c0418b639b89c65b02f8847d34d386a66fda22dc912db662b97f4a739f8ae163d4c58110fa93d7e21f56d46c6fc0498609af5d114258f216ad08ef11adb318cb2435e50958669e7c30875b1224c274c08c68cf4d6923794ff276ac12a8499d3b44452a1719466ec435aa3d7cf38df0ed8fe58b480d46e7d013930bc42c4db0a39025475800ae4ca831ddc4471e702d68f19a4dc6c1c2548e551ba17ab7838a57e0ea9b366bad757dd63da32dc4de347e79f2e97d271433ac0aeffb6c4cda858f167a222b88c478b54f8a8604ccdef21de294bcea36641cef6129d0751410b4e91614c6c3f87108b1268454b476cce8b76f1e06a8210573e10342b54fd6a24d5b936c9c1786533e87fc69f0d12195012d42e865d9c0cfab1264d74074a0157cee8de6f83f38cb79afdba066f18665b65e082e2978684148a9868a7bf561e82f0bc6f0de6ec62b081e1135c05bac0ba0349b30e9527f1c6be104be1f56a9a1b253a0e78da50430946c4d8eb64743ae2032d60f3606ee4cedddb323d26c27e447043c69068ff021c9ca316368e7dd44866c4de1f383927fa0e4d0a56c88cb44104ffe6e6791c042a09aa484df5608bae34d557a03485f11557baea06d166eeb11c53097e91ce08f150eaef4988f8fae8bbf1a9d7f4eb5ae9c6f0403c07f9a6a99a7668c86960891df45713d36311cc427a4f3f8fdb9537d8a37f86b2efe9899baf746478b067a493a5aae3045318ec211d8368f4fdeae9c798fbe6ad34dfcef77434f9d980202f84f190c3365fe889986a42ee285048a611658ff76b1aa64cf10b6daee439f0436e7da1b1af90fc335a3991ae8f9d7afdffa50f9d33958c8c043add49f12b28559faedd000c00b6901c879f28e9a8ba0e94a28f0b978b091c0fe17c320c515af2576e60784a4014efd1209d94f020346c13080af02c02cfecf104318b621910f80bf1a9a9a637471a0ccb575a60608828c21b53b3d24a15a523bd0c72f79858a15e4177b006eeed2fc7900e68683c9a9736a5c41630093b45e2fa4e3e7b6176862d339aa5d70da410eaceb191d4dd65351aaa1389da1658a05e8e8865f33022e63cf48ce6a8239718a4d17ffb952b0ee94a1cc301c5d98a4c44185a1f357d7d881021ecf5c8c8644d0544f22e2be534eb2f9f8b165076f91a0b9a0da8198a736b2c822aef7ca237b15407ac2c62afca6de87bad3aa8a38983d66033a85d9894e16a6a9674d94f6042003191c94fa9a053ac076318319aa48e9fe9c4d90b132a6e87f189b502fff92283084da88e949051c4d4496a00a4177111be8b0d1d12e1421f84a7a224b6b0543848628e2dd3bfe0cbcf1c911ec3f259634f78ac0e84e9337395baef44a2d142eb78580faf9f3364f650695cdbf278a7f018ead218c8f6279041158da38c35f9f0d8445d2f8a2566dd99edaf4963363b4b058010b08dd217427a41bbcbeb4e4388614ba8db4440128e8c9b9393c91349816f8f733842bec7f020cc98e11332175fdde916a5f598841832384304f687e1282f629a8b1c32d3c1eb01da03e6656d5e0a37c50f1a7a06d1c719e4f8470927eccd4044f4e8dc36fd737b1a6c6dfcbd6551749132a8d60a1e54a5bcbe9ecbf81570404220bbe229d793eaf087ab1c3354dc92f6a6b600e67c7a1b720fb8de2c6faa2ce4fe3985b5bfc9e44c2f777d309c81490c756407efd943a3c0a9d33d845404f6ac617cd2bc29caeff87cec10ca273a146744ed030d6d6f724c172f2087d8fdab48b92b61b9eafd010b676f4f4ff1d6184a1880b7aa190ad765e1f6eb5f2e4e5de0afcbc86ad663462dd3fa29ec674de79b46cc94519de77bfc354252a52e1b2737ae3c224144fb76725d9d3e852da295bdd2f6ab23db1d06c37f747003410f9cfe7600dfc5ce859b7a143a4e1803da728eb75a6cb3d8a340989b213053fefe19fc593f07356e2d907bfc1b89752901f799d978688c0aa1393a77b4238d6128e1537da75c2c80040347e3616f168ba554d91dd39ed10cbcec5dee6bcb67ebc1b28c9949bc236f68ef7b5bd84241d90fd3fca97ce47d50a8f682013a79e399a985f305e2538063cd3a2a498fa91148ac03b69164e2745509070295965e6477d50476b15cd1f115925eda435f9a44df924b9e926cdd1f6ff1067b849bad073e32dcf6297e6e84c1ff7ed63a6c7996ff4539dc6300565a9befc9449a1b1b7a0d4231856a4027c0ef076b266005c3f01193d4bb7c177c62dad830fcb6374aa20dd77b16cae2ada8eb65096a48d6b18f0da98adb8d9f70164d849da7363746a522297d8936ceaf08a018728236f0897c332d0c2fd5db5cb7c0bf22daa63be85f1ddda1a2e9987a13d0456964de90ff4679b8ba769e5a7e3c29eeeda5ef4359142a16538dca3181a3fbcdf79d623f36642211d52fd80fb80ccf98f7ffb24ee91d881286455672d2e694d60e012e6f9e9b1116774b7d4f1fbc4b942aa036950fe534c88f155dd6495a1e04ebb98e85b9d10a68f57bc0adc19baa3c7ac01683fac5038110b201001aba76ae460304420dab3e95cc7caf0078be6db9be438f83825b45c01e8a2584ddb1581bc59087031b7b603a0dd5cefba79acba7c4c2c89c399bf6e4a1fe1e25d89ec05e4c219152ac873affd30b7cbb4d5e47b5560c3d24a25d68fb1abfd489b3a58dd45c3db4be085d88eb3793d21e926893387a00303cf51ac3f1ccac964b9cbeda9f4adb834b70e8da9022043c2d8229668cbd3cf3a8cc205e7ef6ce3e54692f16149ceaf083af0018b0a3aca308d704436351e8d3e2affa075b968993cd736f6bf843477278d190f4f504d2ce40be468cd3a145110556f9e75806b141732bdebb381b3ba12b86b77d02a7d73625b5bc28407530f3e53873c86756f8eb2ee45e25146f46702327eb5f539c56e7d22f425ca7061daaa84e9ba044d295c1bcfc0a3f459f62925840d618dee8dba678c1a6209800fa7deaf15d5c05c6263e5722ae5a7f9fe5eaec13c75c9d40e1b37a0558a771cdd13998978b375d454715564cf7246f6a0ed1ca2afc81e09655be66245f6a0e61d90c522b24731bd3254f890bdf3bd2f293f4ec1dcb317e133f6e549f7b23b8f2e55020f9e4e87f694ee6549797e629d31dcb80266ca1acc4415e1a0662e4331c71941c08c287c02b01fda1e76ce4f3dbc89d38a7b211945928fa352ced1fcf2a950d92465307182f20dde45533641affae5fc405d04dcb8f76b7e0588d5c45fabf7530dbfdd9519c05a3e3da84c33321f01247d292b10512aba7f4b6caea853c6ccced8dfb4e33e3e83148484b758067aafc6da220204d42d532f867459e8e6d442e2eddd4a881071645d663aad8839e072e343beb2ee06cfebcd811fddadf6990a0e9a379b83bc84e6a0cf49a0958a58aa3807c506348439db88694255056aa663049cd5be13c8f78ab0ba2921ff1fc766b9381f202fdc6af695ff07e2c28f92955310014f9b810230023443214813ba07213f1a03e9d73a8898146f28566030576dc44e598ae72d3ef24c01bcc4ca6fb5209464ac4bdf6f8c81ebbdccc4c3cfdb9fb85863d67293186aad091b06be4426b6ff928df908da2abe70bfff0958287951dbf08a27e0fced74e8de376429da990fb1318c9b538c8a571d7d0173d6db1504a06bd37e00c451a28346569b3020a613f896295931253ac02c57bdb71d948418b6090c546fd315301ca0760403b5799c2dfbe601c652641941cdb5105dbc3704564ed40c28b84f6b865dfc30ba9dba98841e0d2c955c589c3247cb2e05cc0c87c6f584ffd17421609e937114ae50aa4dce2828146e02e8202c2b00a7a9bc44422955f1132da76aadd6b17940e95975348dbcd60a24fcc5b913d001912c47565180625499a874ca1361be0176e4a6c4d5ecaa0137f43a3ab271fdd87e4c87f02b4ee8bda7ecfdd1eeff4408c440d7473a1a9948db4004d19ffc799a8c40dc6e85464983fbf0197620116fe8e3a382808a02c0e1131584d8c96f54c2f901bb838f9ede725ec07882749513f822227c3c67234dca16df468995b23512f66a203d6f3582e23449cde5392912609ad47f3ac1ea3526497ff49fa22d4819fb00c98bfd00eeff3d64dea3ab6f7a88754021ed1df2555c8fdbeb669743be4228683bb65d912c93ea04b582039baeef7336707bb2d9c84ef2d7904db8542fc02151c0b9ccca5ad212562977e30b0a620508687e5d2ddc05999bb26c6931428f81dae7f19a1e70d6ceb70fbfade96612c97df8a374bdc0a1c2e87e30ac39feec5a1a89e0801f0d75e656034066a43f549a3aa0d33c889666523b43df7b5b85f0980cf911b1086890387016ad7e044419be22ddfc33e9cdfb55b907c2a10658af3c3236186f9718a2f94cdeaa1a665e223f077dcdcd45b2516feef1c17867c4e920ced94ff8a30524f430a35055da28bfe87813db3694d387da2b03c6407631c0d51b3620e3764bf62e6036da4197e2c50fe3a69dd5b7a18decc9d04eb320aa6c91eeaca33c8bc7f3f3c8d0fbf3947e19be246266343dc79cb73de2a1b109b9b17edaaf3c6bbdd58490d107e0ce4908a17dc80598c23e279e7767e0bb4541538067cc0ffbde37a3f5f9de19f1bb28b863e2a89221ad7589f29623fa751f6e27708edb6cb4b355cc1da6a1385e45e15f1aa6a66952960286faeebe9685ff3e8efdc92ff3e13b1228d151305091cd7df832584072ff72032cd96d67fb9b29df78c6ea4bbd1e27d6488a0828c910c44450631a7fed3ed850598199d032c7b986ea77420b067809cb5f6e6169fc31643b4a1a78d1e309e11ba8d633eecc7fc2bb20187e017a137460dcc2b493324e10dd830c7ac0b6a3d8cc2e6d03a551cf1811525636dc59dcddd37ead2f99277d6be9f00c5c0c41d2425910078355a82b213f16d570486aa06269e0763324c1326b0e62cadb215560c0d935183a88582bed6878895b8655850b59485410bd1473dc24ffe4d5b23c3effe77d7a84c4220cb7f7b84bf487d86b68646b40b59807484f6e1fc406d2f2655e1aea0520c86149c227d2e3a1c10a98b417f39cdc9ecdfc1132b4e6c69ded2be60959fc3a56008606ad6a28600c6669fc9df3f1c47a73749000b5ad0cfa3f055dc2c51e4401ee024b8b20413ad93982ed512617d6f2c24cd81e50d977451066cfd75b6348f2eadcba358199cc2edd963918cf47a58ff2317e1c3f98eccd7cbd2d54b73f269838cfa90feb547369bc31d78efdf751525cbc4f4bae85b9e56218b273743480e2c916236b2b0c9185b0a3081281c228c29de1e0fc705e9621600c12623f10956c51b04e1094043250b4c5a42857937206538607ec7488680396d4d1fd977b6fb8af142c4c6f7d83115f5f812e985bb29bb78cbc9d9e296d0867c4cde91d12212440ca6a6a06bd75684a3a359c8f2d9cebecbd3000e66547428bfc6166bc0295c11b309c9c68af04cdd1601e05b7ab621eda06dda7612d466b9d5ec40a54a14f0b343b50305a6181ac772ee9a910a3a6e35eb449c41721fb2f1ca692055c9092cd0b5aa3a63e32bd0f16bb8b0bb2a79ff5dcf5c6b13e6c1bb4ca33e81a6a6979f245fbaad3155e81508f4afe7a821fbf3bf341e281e60cd0b1e024bab7672885ed94baf361b9dabb9b815147d5da32b111ec66373b57de327a4b19458eda61db2405eacceb78a8a28381e8b08bd8d30cf270e8a9be86cfa7022758ba8d134d7844dd7357034ce866c168343a476c4d9a0536748f4c4eb03f8f73244bf761d1e490d883cd37e87fad5ead95e4c645ed3e6b23043378eb6fbcf6a117bbed431767ee433bd27d687cb1b0f1135f497c58e620f28381f9c302970739cb5e67762c76ff6ff60473a7a27982ea52369d938def8142dd681401c88fd66d1656f3438c64a39bc875b3679949dd0fdfa953582165ec8386b38fcd375a8ee33593404497caa0cb35c4cd853e3836e70ffe12ab4257f32c07e23b14f08e0fe90811c151ec2305672a7c6c0a60272dbba34fa5988fbb9f9da2c1e820a6abcd9617074114bac8a5a18c1ea1a05feeee001b023c00eb7345991b9568e3f2dd5a76ee3010e61a0e77a42e65454257b6e7faee127f62c5ea52ff1c7d4fc37251c6491c09fb3bddc729b5327196562ef6ac17e1c31875548bb4dc3fed13da1e76a50187c2296dfd0c1c0c6bd1e9c167a3557c89924bc65040b97407f44a5cf9c31aee770efa2359db3c54fc92e0b7e9157ee68012268fcec89433ff28b358dc37d42b0d9f705a1a8e39d2d56e5a8477e14440e129ca9ce5abcc886947754288c887949feadd5e38e818648971c057bc0eaf5246311a3ecd10f156dcb323d84e0c2fb3ead7ea49b395fcd1ffe0378bafa5ab8809dc3395a379b4ab032d776831bf492af89ddf6d22b32d637c3f4bfe1ef98f1f78aea537750f6c87849f0dd9eced7ada7f15dda3dfcd887008a9e6b1780e1a948aa2f7837c1076153b9a71fc159420cf0254778f533033f86bc5f0aebf026e81851531f20d20da0803cda925db6f78992208929625c1e2d669b67e1efed937f590e9eac6839ca6a916ac1259deec69e6302c26a5d54fb1a867d2633f61a0a3264b9a36a5b7960e75a0f7112ffe0efb57469c1539e89c7be9f691cd98a4f23989caf62d07179fdb6e902005ac8a98811802b537f12b41cb64a2a94d7ad42fd87435bef03536e5f7ee011ccfb3e90c3110b2cd1fdb8386f3711171c1d547a6157ef62b7cbcff00029fbac0c932c4cd27012102e4b9842dc5d3f4f093f67812cb0985a8810a85bfb4e74b89e3e8bed3d3dc6e7aadabb9c90f8096c7d1ed0edad126697e73db207a52d46b311bce7eac5bee828697b3ac03893dc4300cf4ff7feb457e633bd20850f2071eb0dfa2a3a49447d5f2e813be4843b3dff92877ebc3bd46d2ceb9b96c717421e14d26b22badeca22687f92caf57a4d9672a882c5648dcbbc4285ee83b258800e64b9723f7b297754bd3cb58433cddaafdc02dfab31b27fa3f87ea2eac8eac2500ff04d06ff6d7910f70c37d8f24f741c543630a76c695a1e1da1ec370216080fbf83ea216f1d9722c5c511db4514b4c871bc3b45cc9ce73c82cf3b0b43c0fabe6223e15b93f0085fd11944860dca476d54c5ad5f89417e78a0da1f257561049050af5a6eb9467f2f5e265c432233fec3b8a68b4b5a1d4527e06c497d3b7f603aca43f791fe31f76e1bd078013bb653b70d61dedac9f39632987e0269f51e7edd1d8eb1d371ab49c5a334fc7edaa82327f37e1f4a9a8d2836aeb42c0c4a045675381d4f325fae67aebe36e33528966e8cb5bad593f764dc56b874e73dc5e7b84f06dd19cc4c8222eca4cf201e292ef909368b21975eded22cf47d082c26425d8e8578453807f8b1bc50621d254b87e6b6c5b6d41747466064946df69150bb70853e0c458f90f0dd1c9ba7b107786af8949b8fc2cfa33396a8f3e00949982cd77184de67a689874695f9e257b59b38a969f423e30615061e1c14c6844d7cdef3b049f891643e50b7341f325170904e980e0a988bdd418ab41e4210e25af423c484147154851ab4b432ac22a78ccbbedb8f424da90df6f0a04d1c9308e13a8a6e81ebc3c7a4c92e5b1c740e9d00e5b97dc472bd6505cfeb8e91e0f92af022791ed6f7b79f20656387ded685d73463df436f80441e5a29fc603898c21206f6f0e8cc1bf12457174250d5455fd435690c73ecafedfb86171ba2f707ec8326535575e6635e16060a4c34728845d5011f6b6e3911fb970eaedc6bd2d15ccf9a5b157224df5c183848255fc16c8c3449fb8d1593210c34bef1090aa42c698d9298354c6db09e7cf71deb294bbd9850072b1a4a5e815800b7a5deb9e724aecd2cc93f0ef1637982a916364124a46ea329266ce0d2fde117e6a2313c03d8a6e960f9c50c21d0f65f16ef2011b9bf43c10435dfd09293dda1f4a526f5afcf17b1a96e0f79409e85b286889210695d648c142bf48653b00575a77cee3e590b995f80a0b132d4340f7aca3933e03e2e0d060f5ef42e07dc17cd6e20df37827be5fb2010312bfe420ca0576273158e3fbfde7254efab710f82e439c8a98c654dfce777ea4bb021378212233eb9342d97df83a59d76bda105314a17accdd785fe1f5acc52ef4f7b3f21f5834621d1a4a632ed9188deb2f78a27ee4b6345289a8a698b9483aad85061f610afc604382f3ce69cb5e0e58e5b16e10dd2d71254e71cfadb70d9e6ad63fa705c986a4a3c65098096efad516395580b9e4b31549621f9446458d280a30c10bbaee1fc7c9d5f37a96456b8f95f45c2f932dfee20dce217d0d458780b200c37711e529d314fc908bd3cddc1bc9b7c00a61549bd2460514e006f5daad45cf371669f0fa318d5f7d4c06b91aef32468ca23e5ec49acd0222398f5c7d45ad44747ddef40f3644ea3dad42a0f0929f9e3546ea5debad101d196be6d12460b2bf1c59cc0c0dba892a48eefd63756404170298f0534e623cc6bee4801bf45d59c4e0a781ddb2fe6c1263a744b216df3dc848f21bc756513143f3111f570c21d7d509e0aee1d639180c257c939d8b4d8e5143f03a796f857317f1abb467ecc3b69639093162c15f32e34d2254caef89711b9f1ae63c9f220c98eb69fa3a0af6bd0040d271d40a96521350264efcf143359e31fd77f08a97a84d2a42990dbcf09bac259157fef71d9d15d7b7412c66c25bf5a708fe1f09511caf609d10549f7412857cb5896d381e889837ebed1377e4d9056edc6a07f1c36df72c7048371a2372781ea53061a1fe77a53d774be91e6c37c6a5876fa612c25308fc184b771d434f82c6c2ae4877802ad079c8ca76ef46ce0dc38512fa12b71df7a18278b9b56df6d80f8ebe474bb4e971ffbf4cc7499841cd1ea1b7a15a269166c4d7deaba3b149efa8f0c2a668fe17ed8fba1946d5e49926b7770c690052d35b621e749575d7eda4c5c8bf34586c2664715ba69392165a7304963dc1d88bcb2f270fc18306653fbdca3b7868cefac738a11730e05c809d76032c2c59129eadae2032570ae8c2c36476700223448e6a42ce69a27a33e1e6e72dd7856df090a05c5b59e6258c7528be6340007bcabbb4959fa9c045682d275c836ce0e1aaeeb8de5773c14c3e9a942748023f8fce64298d90c7504a2644ba17cadc0c8d8f842527ff570b3687e818aa7247c4ed4a1dd3ad00318a394a24bf164d2cf7613b885e595a4fdbee63209144ad5d1c54a35324ebda5510d6d0e0438be3f44ebf157e1417bd6619922fca146ed90b92071fa52bc9276de303642ac289bbe799a2cd4b80bccee676c1350583623f9c7495b3da18a80ee6f5f028335125481a03322c3ffc5b0a96a2cda436601fc23cfb011c9232ca77e73e0ff48fee4ef91e1361ed33970ad9b973f925e6239299c4994515a94101a9bec9ea5fc0c5c13cd9121d8f57cd7785af9c53d4ce4226d661ae26262076e7638e6a2e9ba111be43ec1d3c55def2fa69255aa2bc0078b9ba6dc6e6eb803c31ce46e356a86534a1b5e031543c2ade4730df71e3c6b1ac874fe5883ee4767f41323baf6c197cd86664011035b0663786abb50035390e0810f2aedfcdde6ace2b345d985e9e9e02e9bc4f13bdbdd37196d74da75fca9077e08c363184fc400a4dd1233d247016f95afe373c665a8d6880e8190590afeee1c91073c3267337b966be486d123798f43798d07c4e3749354024a7b38042dd099984faa5cc237eda7fbc8a1b5d363f9e7e16e434dfa3c0097d81721bcd9c93255866ae1b219872fdfe620aa4970c01c1b725a8aeacd1e13802577d23a19900b8203effa509851f38bccaf88e3dd90ff2cf13c7d19746de2c63af52d2a93b82b94549047b18cff08c60ec30f5198a52aaeae64d4279890bb9c42c67c5d45ca7e439976edebae8ba99906eec59d48163c6edd5fa2a8c1efd96aa36deccde2b7dd1572b780ce06a9f9643e790708fcb9804af102701a49956776083e99b52a5e6843de1088f2c27651f5b458afdcdd31462e4a1806be8c7918b690837d389f0794e559d2f21b1b90f9ae4eaae6c6810eaf34d246ee21301b31c48e74102d4b21a97f7a1c3017cc45df99b9634c4903442833231009685976230cf96e9f7645031f1c5d69b947e6098794554752e713268ad55f560eec3f61d238d382ee6a86b4e913100848e7b3d6ac60c46178c8908e75c2c9bdcba7581e50252b6354072202040dcb02e61f85d8419349a5cfe806c04e700576b52ac7b245a64db6986d40815351ba8a7204073477d54539ec6e621deb1b9234061867df7b58bb007761bd5692199d93edba1d8643a530fdf44f8f32501f4cd35444b80259ba39d506e04e5939b573f7e4c284d9e984426798c622c74016e08bf7b5f3003bdcd0607fcb5b767c6bf5da65b095d1d9d42d39445b455f2a547e5bfbde864dc6d2bb02493d2ca6424ad707cad117ccdf047176ca2eee8d23494b02706f2a455fcc3e1ddec5b1b2ca34862f145d6299b9e94fbb234ebcb06c2d875fcb502b85c9b183aca0ce53ba4639ce96c672abb753748582530608562896aac434c98320aeb0022e086c94d11271648bbec7d7a6e031de756cb4ba1949451fba007ce8ab8231713d105edfd64845a3edf68a2a3cf666cfd98f3a6041c9f3baaf773bcfe68f922f23d03a4de8e4fdff0d4c8a3b2f9ecfecaf4972740d92fe85b452e5809e4109a7f800f4804be758738bd06a29da2265a2e497b790dec87f762d297dc7f9a5fa3720a5e2a6158d00ab4093ffa853f9c394406c4217af3d8be040391bfeaf02ba2d4055836ea9f84205dd44b56f1c937003b8d943813c1ead3c344a569c4523c7e2e83156cce6e4f58dfe83ebf1eb519166dac5277837bbdecb49367693f7b102900c430e8d6cd1707aa766df89d9cfb076dfc96f47d9aef1978f90bcd24109bac0a9c7e4988739919717b47f73cb768d516314987ad1351ca24f9641ba341449a127f8490c7743b3fa1734068602befaca783423bd8e9dc3e40d8c9d3ef365e7272cb9c512614e3e827e1bcca8645f981e04a3d471f0c2aececd98335c4eb5ecaf46e4611d0c5fe78c44203d579e4397414be06ebb4ce57abf8051c2bb25f4be0eacbd6c1c6ad58c1313b5deb77f4150994885c5447c1acd63cb59063800ede24228fb753713c7e6cdf74b61518ec621cbe50a35ec578fcadaa9788983fc135f51d02eb78ae0f827ab22a3571c84011e4b1794379e1939509f692229ac8103403ccff8628c6a66fa516e70df384a24a3272627b906a9304295a1a24a7572141c76fbf3fd0a109ee75f810b126f555e9ecbad1cbba2ada7e207001bacd3def7263cbbcc941fd1234d33bf8a219fcffd418a96eae7fb1079bffafe49e39966d29c3b9062dd70050280a280aa375ba3441ce0d05c30e0ca69b872c4468c82eef5cc7c26df222adab5e1914a56acbe15d2347763c4dc729e2866473c1b2608f8f802ae5f4412d18b91d066cd17334efd51fbd712e50e7e319743d92e5506be3410315b6cf287e9d27c41edf49c9fc2f49d39f560c4288b281e6d2a971c4805a2f10729f1ae73c1af88e9d68aaac340f3ee4b33c5a291a95da0ac87c65073e85ad02e635953e76b22254c3989563daa4dbb49fc05b128fa927cd0e938b96f6b0f846fb5400c76425d44df6b0924183a6dccce6d55495f654eec740d2ce2fcf79cd05d6e9e7ae6fffd5167a7b3d5ce07c81a28ee204f14c1b66c3fd97ad2591eabc267ae14900f58b67071f1a8ce30f87c194741ab884d4b8fa6e7385faf6fdaf542e14d061b6abe669b754e02ad83cd304e79e952e9f90a547d9824663d2f99b831150456b164ffd04b4bb933601dd92490468dc46cfa87b50e5c52170957cb5b74fd84d4c14533437dbd2937c8f3d1b90b9249f5eda33b2a84b9a410cf0729bcfc8046dd9ba00b7b2f5025f9f9abea0e78cd6c4036752005ed789c617be397c0d43ac61696183a1b17b0344d8ac4efeefd83641ff9b1132921f2a22a6eca42939c574e220be9fe7a31b617aade7be415c4b6fe73417cef5dcbb8a448e3361b58faafd465c82e818370c7dbedaaadb397ce34ce7f63234acda727d8c041139ef5d9ab889c06e56fe68da851f83e7966680373ee16bf30d1ca1c9d237573f70efc51b56f2201fe3721a80f0777380a9095ae7d47cbe3e5e46a4b0119d1d4630d296086a74bd42980c3b37d3a15b9e41d3c3f2036402a94950b8d8c010c067011d523a13fd0b8c33244b20793197830f97e8ed4df588e64130edaf9e64f28417a89a769518e3f5467d8fde8585367a486d300bff5d98f45b909d968af2ae70ebe362cd4adf8acc3f80d29c2f057092c04afce01c4323721799ecc719f2cc5426e0ed562d24ed8768006308d65a4e6ef6e7f2507d711a26f166ad1e19be5d2a7330bb748078e6543772cde52075a08c5d522aebd6fa553f6700015ae96af3ab602ab3a8fb8090691d71bb503e0cd560d529380a2f8f36f46ec8c71826113b8056b3303bb09509229ce2eb2355e7bbc05cd55c01ba5b167f343d4e6df1f719437034376e76c13ec628978802f914460821530dbc150a8006ff0416416d1eeb9fe2407a851061a3cb4a164f2f812ef96e2e9635a4c5dd909078f48b05d789814792350a5076a964a8aad835ab94bcfb2ee2b1d67ee2547a36b2531f9d837a2ee23da5ffa88da420d3bab23ab28cee7d08eb8fee2c21fe8d15fce03b559fdaa95adc4704f75376e27d1af6f6caec6e10c1724560e87b65d8fc318a087b886caa8c6ce0a36ce12e7245a1802b9db0f130a3ccb6461b91b66e1d23c19f19e2be1a1fa69cc833e3d5b8712198bdb07c7a7726d639f2f291690aab42ccea3dd3bc14ccc3702c3781f473adcab146a80ba7e880e9231270e9c22981bb1abfecf490f2873732e4dcfec39f89f73edeefcbb9bd36a806fa7a9ce3d8122e0dfcdd5585ffc6bb9fd37d99612467180017678b27c994e7838131332433aab0b544eb17333f9880e58c857ebdf035048e4f0c1c866fcd8cd98dfd3abc1afefd1eabfa7363aa102c8285c4860e1347db4b254c6dda7929d8c035d87e38f8128957d9e2668373803834195bb59c0f3f111cc0b3003509897611816f4467d4a12510257368674b0ac6d2d1f87c309e641e11dc05869902e760632948354c0564a1775c8034ecd8fe4d5c13c89d92f4a5a95ccc43c32334689d83156642149fddd6732faa18a20769c183deb9ff743766a0fed3bef06e9d8c3c339c7b7195d329b80f8e09dcdadc3b0c00cd1ec2e372024acdfd074747c69243938598997b72a596738f3c5833d10a14c409ac4da403b6de6379eadae65e1c8fe02400f0ec8e62cd2af73f53e34007908bfe67e6876bee853bed0c2d7fbac9db5de11e10e8f5f1fbfabe520ddc38292cea158bfa71c296f157d10b7c11fbdb9a7dd13964c592ec457bf6c1b71293c618e173d605c2edf48b805075b7949fd7104cecaafe7f23a2421a163c000e6b75ac669b6a7060eddfacad4596f67e9a89e8166e404b690a685942a257abc3908041c840f5dc1ef609c09dc9226951b1b7246e5bda82ee8015c4e3c7ade701c4cfce621381fc92aae7627463647bf551017b862d80b2079e4c286acc50752d7c64d83b144b28c887df61f83f7b9d7b34fb6a11af36a7a3616db352e16dc4e69b263e0180605a6f61713d164e7dffa2ae00916e93aeeb35ea5a489d72217149d1ffc51db1af3e65f9b267827b6acf540703864f204765b83a383b0247fdf3a1cc126dd5f0935525d4fce13b9af16fcdf00bba19d0e749d1ee2adbef484d726ae7dbb8151e32f3509e5a8be52fe6a67e5f5ceac8ce3b218578f989b4cc5c247a5497cc80f134cc98dad4847feffef2b750865f4a44a79af3defa06358bc81c5a0f665ccf379a597bd8834063b34f049c051f0a48f9c75f81c3fa8be6f83f7b381f0c9753c53f430a94ce3f5dc89095e94a09210159d2940cb81a501f18282d3c00c2b1acbce61317357035a76db0fd37b0e8e0d73f2aa05e411505ad3296efa1a49f433a9f8b679ba77d45a992637985ce5fa024d3b964599d35bf14523e913882650998581f8fdd53b7bbbf0df67fd1f36dbf4200e594311634e33a8fb2542c1764a94cd3f1024b3b632877d5adcf5ff2e33bb2a4ce5dbcc69252d689255670f39a265a3e846648fbe59e4da1812bbf589a85185e1e4eadf8988ae5cac187a4740a4a00a4b3384257be35515794303996aba8eb0b94640c79035050ee4deadb9fbf14be8608965d7e6fa660eba55c8ea58455e797816716388bdd58aa81581e1d9c6c8c3ee4b38d595ae75d2ffcee6cc7d59306d5ea9686d32c6ac7fd17df5435f8c1061a96ba7377df0dec7713ad67b794b843015ffd46817df08afdfb510afef9e9e658541169bc5d096e4f8185b3d9f34b2ce518ba12b0a0a98a18d0d7ecf858232cc2a29bdfb7947d8b66235cfe0d2f9572509725ad8f76ab6d244e8bb33c74d7fa8a926261898578afffab486c5a8a1920cbc0c7f48fa5f9353405ba796c4c59bba5e69ed0c77b8a7490a71abe40a9671e7219eebdf3618761ddbf6629940f5d49efd92d1567e874aff6577192e1e20d96851b8ce91d95fa608b59aab2e727f630170b65bcf28fe24af112075c313600e273b42c05d4fbdfafe447706009edddbecd92d26691c58ddedf1029914f707b49d0c7e8847a6761cf7d9fcbf2b3d2b38440dc7e6960cfbc747edda53e2e5ce759d20b3028f62bdcffe573da041fce9f403a73fd8fc06a45ae9f1332cfda3d07528483ccec4efc7316fadc9fb52efeed2b166dd7f323943237f6240af2ec002730cfb4ff8192cce3065ca74ed259c4a5ebdf1aa9e42979fe04c9f9186f8a53395b2cc259b21cab7f28f97839b17407dcffc6520e8e13c3384b9d57fe514892153101b2cc29627d73dc92f17c9e7996b981c6bb5fcad54f14544ce8585e1ccd8fbb5496b95f8ea51575fe1b48c1facc6697859fbff5e4b7622d7cd09cec76cefbdce75268e67d02614531a1cc5c2c00c3cd53434a29522277b2cbf3e867c5271246cc8059bc27c6ff50d24fa02b1f9f2be022b59d2220cbbfc5f47274b23d3f9c3941bb7d04251c9f570fff5e29c707ef536f6f5fea3c31661ee7b789eb80791d2b894096d13466ef50fae116b064a8bd7ea292e60ce5af959f14a7528038d8933dcfda3c0fa6f677c6ed59dc0880ee4593d14bd20d44c8034abe428e58200e3b4e07e365125c3a4c1c2ed4d64abd39fe2271f191b11269e1586a0c142f3e068fbfa90ad4fa729ecae9830c4e2a0640c901119b1dd3f569d51334f0473f07fbeaf088dcfe44aa8ffeed4f42dade6d6defbd654a2905a408950820092412ef59bf95e36e2a6ae42676ea987fcd0a6d9104ef59add7f1455ebfe35f231da9b01ec6fdeb856c308e548148eb5f0d58db9774c7974fc5fbb5e9785fdb8b45f6ad9f8c3a4617835a2d929b78a863b79a15ca623d8b0c9acfffe336d7b8b6d458d25a72538902f7250ade97287c8ffa1285d49728805fa2107e8982f8250aab4741f560dbd808a911d2393dd034cdd34d4e5ca3d529d9a4d261540af4b8190498d622f9888fca7fbd28755a8b5c97952957ead891d3184dcbfcd31cb11c7ce549c9dcc4428272248ff1298396bcb44b9576eb0858f51f00d7386ec5a32e573301e56fff6977773061e5ba7acd1d4fbf7b9cd0d5832dd6fe9fd8fa7cb55724eac15164914f867a6cab8ff2d99e3c89f2b6f0a3cc6ce2ab9e924fa27cb6d5f7ff579bf4eeee2de3892fd620a20629da70b2850d601bf8363aae8d63abd3bf1a652b6b0f4a1f3e4ada6e07a507b523f0c49283e4bb2c0d25d70ae5e59deeefe9ff9811aa3b2d6a2673dcab9607864a2d0f6c48f7fe5ef3e7beb7b9ca151812f52fdfc8e8886bab3a9f8fe09a3fff9c0d4d92035c6142bae74898f75bbbf99f8b7ae37ca357952b4647391d9bff5ce37e3eb93e36002c2d8495cd7fbd5aad5a7e9d2058cbe7c81fde994fc6a88b162b60bc6401079628b6a91347141bc4a8e2044818617464e48980ebaa47f3c0869048fce7ec635c73d50663b52c1ca4a13bea16e9079b76ac6b597ed6dfd3ffb17ea260ed9fb5c3236892b0961a10aaa177cef9731cf7dcbc89d117c79e05c8411a3a7fffbf88d5bfc78ca70b2dbffaf7e38872ee1c495b15b61c70585d4dd1f33177d7cf7a3ee64bce3fcef53ead70e35a089866e4c765d38617ea7c0a90537629893a2793db0a4cfd464ee823463ab66405aed23cdcbf9e7e7887a70a8c3a7f99d6b18cbf5c2eea74d24e7a3a26a4c15ee136f47473f2f4f4f4f4f4c45ac165f34508f2d3b19cd9ec8971d26bc4db8b8a8cb8c6d5f91c04d3f8095ba14dd4f9957c04ec4bc6c2e34bee52e76fd370bee4a43a9fa3306dd9c84fcb26374932689994829ae7f5f38970ede6e79bb03e1ad0f13b7ebbe05ef5e5d7fdeacbf5c27bfa65ea7bd697fb05ea6bbe0c53dffa725100beeb4b55f5d140f8365f6e18ce464e72d19372919e208069bb2270ed867c91fb551e5e2417a99cd44dd5b2abcc9ee2620a96fad3ac43bf4802ee553b74bfe2c17bdac3f72c1f505ff343ea5b46e0bb8008dfe6e773d1faa4a001a1ba83ec56875fc77c9bd135b6466f75fc6bc66e75fc59231d57a3af8ebf6aecd5e14f8dace38d6cc4475cc4838d188895cdefe9f1e143261bc79b9b221e2417710c3a1ad4c2411a8ac33c5f68a700b2e7f4408f28e19a57ff25483c7ff6596c855d1f7bdc85862a397342f3f8fbbfbe738e9c8bf44acd288a2cfb88d3983d05777716abfa1197792d0bdd77a64e067073c045d5a55cc3ca66c8411a8aaa1ca4a1ab5a863c2c92137111d7b64e25cd55bccc258f2cbffa71302e4cf47d2992fc98e804231d9bcfe3040567e191e73812035c2bb9760950558f64a22968bff89c8295e0df24cc7b215b917e9184794236365afdcb65f3a9102199a8c429924dc4202e9b2f7ade7fef9112e8d8fcef3f12c9f7de6fa51f598484c56a8fd514b1b096bc33bf2331c03bf37f1a9c2107692858393209efcc4fc1e7986316196069acc38c89ca19139533262a674c54ceea64a259483291cbe6b3c0081511010515496b506185c8369faef8418da32d2738c204b6f94a56e0b6cb8c888f98888b26516a8959c195e7a13e8522c3172af5e1c7411a5a5397fbe9e15aaaf278a1de74364d7ccffb8f7240c517ceeab9aaf7a8d023c511a4757e6aec5c401ce71ad2810e4966d46fd6e93457cbda695374b1c0a0ffd31fa47fd6df0376c785ae92049a07368443d2cf19099a5f846bae3a9bb8571cebf9d92b467fbad0501719c0913dbf5968d955fec93b4c02f74d6e1329420675cc6dfbfbaa414ee3667a39cd2bb23af3e7a396f68095cdefe9f1e143261bc79b9b3a4b689b47066195414710a163b396856a41bfce8185898d39c81449a941e807339c9ca63032810bd8b0cd0f9a5f44c953c27f437742fbbf3a63ee23d6f92fa7b9d3f5f9ea9c4d4e97cde9411b74fd9606dc1c6fbf880b0d9540c7bcaf65a1de07c53c9bf7419ac7396f728ddffb8e6942364f55bddf1c8f53006e0e8c5fc8c6c1980c7af23d339751ee3b26eb5f7f6d1cd98463aefbe737d9a36343fae74f1249ecb72aa900dc9c72fa8d9d9c064bbd90ad667df64bf5e725ae95e15ac835b0136d602932e809eb5d2f646b7dc94ff56d46232ef3478d4b948cac3432d3f8fa5e5ff9914d5aef45c1c5d1cdb6363e722ae2af8d0a4c88f8a81749f14512095ff9ad3c4e50f6c2b5902c8b687dabf52d92052ae0b7de9fc1704d7c90840d09c10fc9147c8e2a92b0f085aaf8ee9130212821be826b5b9574699e251d4be21af8fe8ce5c86946c60ff08e3feff08b63f30e7bc0cf4385967c43227ef81ed83d92ee4baee2af5822e910e07d177e378adc8de557ab165ab2ff740d5fc9970569cc344fb94c4c1486e2b4f9975d011c2f782187961578616683358688038b13ccc005980fc8a8fe032fa9478d5cd7811f82e08bdf755dd77560f8a2289218086b4722093f64d23ca8f7efc307c7f051230cfceec5073fc0358f8409f139e6a89e0656b8dd6e370d880ffea2c60d6850bb17c720a8efc8527c5415f7e62909b95829f01c552586dd97291476754a147675ca55ed5e04c92286ded6fa9f16c7adb416395b063ef8e15886155c7940dd87e3eae9c85246928b5860d05610c696123c31250d2b3b4698294c34f1a487276efe4c3ec0b5ad2ab24cbd92234e6b81acf1e5b2fdd6b80eeb5ec8c64c23ac23839ec8fc497052f33d2ef3a742a4f5ac67914ca810617d0dc924e6ad5f5b4d6bec7e6d54402623a441bd22e948781004c1a0158574640f8a4c8afcd1b1fd0fbcd072cd8012689eeec5f7c220dd8bddcfd0086b37fa252b7da91108efecfb9007e09d2d1244846b42f56b9a906d8420eb85a94969692ad9bcb0a43986f9fd030cf397300721c39025ecfe01d3635fc8a20ed6b05235a839fdf36c3cec7470ad2974cee56577f79ecf79dc8840bbe1e4f96acdbcf3e385c3a913c64304daf7c930a7ab39e79cbb38aae59d7d9a0f30954ac535253ca6112e76b95c2eae81b9f1c675d976d3915e3b7454ffbe39690059046aae2d537131b5eafe4777bdbc3e36fbf1989cfcf383f4838484c48482665a734fcdf7fd8acd7a9cf691412d6b1efeb2a696fdb5cd0d4141412eebef20252525273783b5bb50e88aa3ddec824aace1f725e162dea6461b47b7eb3e03a65eaee99a2e97cb076eaef9721a1e5f0d879439dee61182439ad55338fda2e1bc5a46afd7ebf57abd5eaf57f3ec14affb9a7debf33f24eaa5e7d7e3f83f8feb7ac6cdc904e893eb3cae75b40f67737afc78d57f9d2c3a6e4ef7aefdcf4ddfffff3a7bf84fd6b405d40b65ea946bfd03cebe9ef6bcc7f85333de69ae4dffd96c463984b580f2c35840f96171507ed813e55f3828c3564019f6062c0d65981b941fd606e55f980a604e3036283f6c0d580a283f0c0de55f981a941f96460ba572a9b8b621efb44ddb843034283fac6947083b036606ac0c1e21ec0c2c8491417142d818947fb98653f7411c1508ce19ba76156c9f5cc8a3cb870d0fd78c56300c79aca9a018f2f8555015f2382bb8aa495c8f41d5a0822c4a572a917219b0c55bd35d6355a7aba9eae69c734eef638e03dddd7dfa4ca552a810057e5ff85b1ee155d13b1557eb665ad74dba3ceb602b5c714e7e4f7dbb3522d06e8d1137519cbd3de7268b63753e3c9b8f03948e140c0c7b2c6dea76acf4517b2c4b56d863d9aa2cd095040de5ef242e116877bd15f658a26a099bbcb36f5377549b96cbc3707913ef5ad5a7e701de1d67556ea6288373644d76a7a26a4557a34aec9e950156f50743519c28fe827c7050b9055457427da9548a519d8d8eb23bd497025128980550f3fb52078ab5318efb262a0cc32f258221c87d29143972bbc3cd5fcf035e7bdd558eeb58bbc3fdb62af77c81eacf20efc8352b03d539540738e66637b64139ce0a6606413014c5102c827b0ed5302b9c5c5d8b85fec29efdb1ea643251299a021dc5b5eef751efe3e4b93bb3fbedeafcc0ec66c70c86a1ea5714c7109c4f43514ca552ebb33ee1d7635d1bf4cd39e7fca0542aa50ac31ad0b7320b6d6cae68486b98f6d150bf290ea4282b54713899390c439ff5f93c8e27bb9606fe82636a6466febedde99efbed6af7813a7f63dd73a4330bdd5a25d415b250f97dff6baa84dae898bc23ecf02349f0cd7d852b80dadfcdf7a156d634d4a3c859cb1a00b0566d727b567344f96f421b57cba5dad599d39dbccee0ccc70404e702991514951394ffe3242b6ea8a8cf3bc3d5d9a30a23bace89a63aa3b87b8116ecd49574ba144034a95a3e92a83841edaf7142055c9080e3894c9aa2254a6c51a4a589247e286289cb13ba064b047266aafd45eda722508320822e45ab03a031c598f92a1e5c50e77c51049a2010c185893ae7873039a6a001882f487411c2e681a21dbce8a104667070c236b788d7c5182b5ef05a633a890b0db5fb532038d9d2469df3514239989101092f2d688287343c2b185aa38b2b57cab4e171d183159f08e45cc596246abfb702038313656471440b370c31811821b87829c28a9b4786045bba0e04a414d47eee33439192eafcf9f3030105639820cd982222885a8b272e5756c0822aaad86617f1c60ccd3967915765de269c59dde809c5142d62e80aa96b00b5b57ca9dda16bb22b8ee93ebdaedfbd39a77b63db36842951ff393b6ebe81052ff3720d55f77b69d763ed175010d56e5cdbcb7d5c9ab85f3cd154bbb16d1bc2c4508f1501288e3ab67508bfa04eb2b1a06e80dcbc71df55ae5f0fde6e435c7b816b31ac9ef5abf188cbe677e35c9df91f1c4181f8743f7f024b0b52e234d6cf729f12b0d51db0b419cf0c721a025636aba8e556715b56615f85ee777584ac8f0adea880f551e1fbf235647d5440016084f551219543c2faa8006eb080f55121fc5d9df90c581f15c45f1f15549fc1eab093d599bf2387607544b03a4f5667fe373294d5998f1a39cac82dacce7c3074e18506aced0914fa505e356e5dcf9de49b1fe958cd04d49f9dc4e19dd5ff346c08bf3a3667681829298d6fbf93e3388eac586699419d6f84e9090f715e9a8b56ec6475e39b928e4dde99ab7a63222aba0ddd4226380ed250555db98eba0f72210fad0faab358d912d7ca708d7be73fd334f1fddbc969e0f753f517d338ad8e131f68a1253b7d7006edf74012361f7cd5fbb30a96d64a2b730e5f7c22e0ab3e0c1f0441f0419285d537013f7c262413f029c9247cb195b6581a3fe9fe421c615b288f112d1769455299af7a5125860f7e707b16fc5b298c25af96ecc4351bb826856b1ce9c186b0f7fc1b3e2bd95ea0253f59d2b1662b8b0545366c0a1a3ef8fc652bf9b30bcbc34d3cacc63e01c7661abdc774cc598d6d33edc5c61c015d3fb29556c7398d11e527929d3ad6ef914a3a46b2c03bce31e11dff09b23ebdb43ab4f66265fe3d3d3e7cc864e37873d34acd0243bfb67f3b3d793fa9eea4450f39f18e373bf977937f2bf592e8c491ea9c5e820471cdab4e7bb56cfe7c9eeecf95381bbef31824a863f3055abe3ee88296403ea0829640620208c00675962f0090250a19acce7c0d6668cc7a9aa7e4dad3b1c9415a367dece9d8fc1f24a0fee5acfec0a2fa0319c27584a665c0b2f901a87336bf6702f1118aa04125903abfd6022d637592af1e5cc3e19de93fff66699fcb98a8fb9f5e2d6d57c892455c16a40b45f29eb0e155bb4ded1f407350bbbfe7f7eb3021dcce6fee05ca53726af8e6b221a7cd5ce6fa977bd1cbf9c680727ecdff7407ebba19537297e2ee4dd445dd4c6cc6dba29621c8cc4736effa72d67abf3579531a7fe26a7ed2399d179cb9b499cb9c87f5dd8d7c1b6aba358d25df54d61804b2aaffebe9af18f4a4f5af77b97e07c9e465f34236a7a68e319a8e39f7200dc6fa1dbfb66f2ecff7dca396066391b01274fc8e3741c7ef209b5021f2fa1ddfa4f53ade841d7ff3376493d7eff8e5810d617df861de884ab54d35fa8b633f38864a6d6b7108aa7a42c004a46a2a5553ffd3e12cf62fca2db7dc3e8dde1755d4a79aeaf72cc24af007df047f9034a15349b6a9dca5da71449f0bde8229af322c0fe2e66aa48a92e8c9e103eb2695718202ce1d89ac4ed749eed383746ce74eaec7ebc97d1ec771eeeddd3ea7072dcd39df8b6cffb74d5724e8dcfa7492e3ee6eee35287beafebcf2c5534a795fcc1c170d37048294f2bea8650f85830925acf8610b2ab6320626081e5a90458b3392b095b33266d4fe2f748565e2407297e2846a2dc22b3e21905e389ff37a9c13a87a72b081cb819b64dcdc660a33c4e07094a6851b8090226689335e7448da828769042bd39343032102ae0b104329a617aa6e52192a3ea72dae5b6fc24227ca20854bd028e8ac8c119faa6e52991daa5737a98c14274f68992132e0741f5da02057cf8c0b4f5c4451fa2283d153133988f0c3d118226210c1a88896b9e53c0dbfefa3af2fc5450f438ca9e50c15658824246ae8ffba70401cbf6ef808081e7252f97b8b97289098b862441517b88622d6a1f28b11c463ad8227349cbc60caa2bfc8663e0cc005b8bbebf34b77e72e69dc4ba17a03086ee90fb3a27215dca5f214b547fe00581372930e989936d3b136539761b5bf9b3e27772f7dd4432f26bad44a2f247aa5ab345173930fbd5e942e7754ddc88b9c884b9d5940205808c3090b73ac183f74b7a54e212ddd58677b377073ca89b493b930ed635ef2ada93b6a4f23a32d3b6a7f2f396d1ab9acbf9b2ad83767722497f5bf94a817a457157ad443fde4465ff422f221bfbd5e941a2d4d2d63fd7e1a4da3398dd88805a6799bb7799bb7dab71b53d731754c1d931b21bd5e943a52fde95e2f4adde8fddb9b7b22a58888519edffc664ec8f8a60c5ef850fda73f2802b9185ace2538aa00aa7feafbe607e957ff0047ed9adadddd8d12817aba4a9c9b5ae6781748d59768a8be04461746b130548105b728b2a81102309e1c81258d21b4acd1020f66785e1835c1850e58d4fe8f8ba6dadff5194104214e967d4e41d41da8b8bb67509bcc93ea3edd9d6219aafe22b8bb4f9f63cad080552e003707ec8088ce110b5ec2dd4ba661ce7e4ed3ef48e577712c5168e706943367f053752b1d6ba48ac5c9a5589d762cabd31ce957bc8a6359c1bc963bbb3b56cb2277caaee54eed55edd7a00bea58d6470ac7e264b89b2706a5a1c88f24e57022203450663456c7b9e90c2d3d892d497440443bafd2b12b41dce4b2b6e2563c096f7d9ccaa744f5f7245e59580e85573d094fa2fa331a4bdbe50fd5e404c3f30f266762a62c74fcbd756f8c7b4ebe61a12533851d59b7a04bb83afb6eeeb7f6209f15c6ec6722efe722efe75b3f0f2d8d237f2b187676b39b3c5f8420efaa58f9aae1aa272477dd53a4338ff14856ea182b8c2eeaf0478310d09295627da444c9a0e52acd56e6dfc34bcb4c4db4630dc213add142bf7215a796f9bfaa7c4efefa8fc59af3e1846e71c1a9323b350fe7911cf7d33cbbb33afe44769c56a9fc264f3797eb7e39056e8e76ac9fabf89ad9338b2608c819b40c8f0415992be3d7d8485cab9e407fd0a73b143a85931e60a9e5575d36d07daf6ed2164fb80136adfb98e3bad7bdc9a3fd9cf635096326bfd5e96e90b796791d01030d4c495b14d9408394962d0f22d030a5655b4bfa4a852e1c1d45845af020c3ea892d42a04ad242053a8a08026c1eae1c0960cf2fbbbb5dd6fa82f6ec6e97f2bdf7fdd082aa1381bc005a14d57eae87d08593d3e3479d40ea8c633e0da2ce7f5d21479dff587851e7c7949ca8f367346c521668ec7073306296a0d497289ac2fb02c74b521362640893c64751481c5a00e49e2bc29dfc91cd27c109f5efdff79e0a918e09155809fcfb44f8775dc644f83d9209f9cefbe5d7e9cf6f42ff32f508c05d1f11c05d9e4e000f8f3174ba8b8718ca5b684911302b154397c7163ab5ebd8dd9d53dfc152a8af73668e636e721ccf919bfc33805bf9cb6512c9fc5445b2e4e753ce762759b240469dbfe37c6e1cb2d3c596394a26959124d933250b955b312548539770f5480cec994a2249b25710d5496260af20625239b24ced1544756bc7b03282dad44d0a43268514e64b7846982c4c54e9c8a0aaba49618208a10843a47aa22d178064a8e81472a12b31be339466f185d22d4760aa804f8099d20901460714153037746f80791252a12ea71414ba12e37381d22c3a255aa325e503eda240dd403f265035d0541121140af2d045a1600d68bebc809ae18b13518a9727272fde15df47e947bf0cb4608159f184811233f0a802c768869b2d55605a66b0e195e588c7ecd302c5851db39ed98f9e2e4337595aa0e3cbd06bf66539438acdac67f6a3478a18a490b2838eb9c1e5c58b8ed997a58a195ab39ed98f9e3046618e6cb2442143cd969b2b0b1137b0a8b8b5b2ec0003e5325493e586a1d5144cac2c51545310d1d927c70be2ac67f6a387cbd2ea9bb9117ef40b29154d2150e1a4a2685a00b98862c090d25225ece20594155540a516be2e57525b68f0a4704259e9acf8661f122e848084e4830c43b3af061942f892240594184200e382a110b4342561719221842d4c142935e63c0dbf242f450440012acc941bb0a0357593a63811c7d0f08d0e091aa2819282b296b8341414d359415759d0509189550e745249a141bb22442328ca07900a8ac2e1332343088672759384184a6da15fdd24216ea214147c43750545a199810c0e8ca420cc844f14553729882d46f042d475a8b6a99b74840d75d64db2628aae0ad0037f56cf7bb1b87608f3c632ac5e2a851a3fdef13eee39ac5c074e6ffc36ac1c9923c81c31c5f0ffe6b59a61c774b0c2d0c6d562fde732e71e519c2cd086a583ee58bd789a6331a7c56020a53829188b8501ca0bbb102401c0ce9e136ef7f8e1c2c1a9bc5289e10f08b23af0bf6775606ae4fc03c1a7a0ffcd37ce0ec7ef875b753f290ae579ac07532048b252de7fffe3a8917b8f14813aefbd9187388250f5481e1c37e92a00e1bf0662bfbef8cf564d65555a67af547536fbf7421fc5b08e6075f998aaa8aff6e851862e1fbddaad421fb9fa35cd47af35428efa50a8d4f88dec496c9c457f1e67c7d8e7e466cbb503a7c21c57485dab04f351774bcdf7a38222557d2bd7ab8235632ae85a24d066f2a84c2671e9005b352cafe3a6e3307926ac97fcbc41f99d270fe61bf7d7dcc1adeb98369eebf39e395b4ab8f720cd9a140ba4a1af445689ddcc3b5d9b1e2fa7bd5cc652b1c01d9e99b9fe5b5d336f561ba2c0540a045237fc81d3c385c3cdcf552290c7227b3c3ffae3186ca083c1063a1efc63b0818e07de6a75b8d93c39e19ceca1cd092d3f16b96a53fb7731283768961be006155cb130582e640557255798101526934b84569b4505573e2ab81a2bd875dc74671c3ecabe6a56f9e3b838c790ababe3e304bb9487fae6b83a734e9e1e18aec871bb24685091cc548f9c8eedcf39670772e114d9553db3dd573e99babbcf39e7f4b91a9cc162b15894be3e67d125ae53752cef85f341dc0c0aead86c9ef5beb0ae0fbf013e14f59d947aa8542a05a2c0f0f341b1667465fdada579b35910cc46c46c3603552b6e4527653daba6678bf434c839a52057e294946a5afc795e829482823e888562dd0405cd205e9fc501e2cb997477bfc99142b1ee7e1ccafc423cd26fa6c014ea03bf0f04bd0ee426e80d32c85569f1e4388e9b35cd72ba3b39d5eeee7ae1475f206aa652e0a4ab9f391de70bbddddd55ad787526f55d66baa2537ab7e5ae571aa8ba413976ec7d18a0c050fc5473ac9f010675ce396373cec72975d47e90d5b4f5b9e8375767bf8685026282dd386e8cdb20021dca1b6b2aad738a6018761c0615a82ece8d71a80eccae6bb55a2ed085f84270da7808d7c339a1725fb8a47293e5ad50b9e75f4d213e56d731c91c0b9cb373dee4ce85f0388f0b4195c8a9462a86e0d79193f384609a814bc7121db7cfcefb4017cf162db61ef362dd1bf99a39e75cde9bba6ce4698dd355c2ddecbcd57281aed44f4fec17039cf5f18fc562540958230aa129d6f49e8a4266fde664b29a2a1d5ee7f2fa3033fb8d08c47f33b9f599e17bdcf1ab2b6bc6264c04ea1e2626a0c59fd545fa8fdb5a4e00562a710cc7f5c8f93bebd1b1cee19a6c77fab74b6d2004e85a13c3c1805709cde046cb8f31e8bed74d62630ca5fe94c619a11a5940bea15123e4027ca195c4541ed34dcda37afe4ed372dc867ea81e83d151f3d024ac389298ca1efb52e59ae7f733ad2f1d8d3b31dfb8ca952627a3a35e6a26a2a2cabfae54d930a2b65a5f2302b56a9e2502d54cd61a662aeba908c4a2bf1281e88fba5a4387ba7a9508b4fac2226e55f5a208a4127fc5f854695c9921b845055300060ed44f149aa28a52e30b5de336c3a4e1c65253175c5620e576b37536ca258d21523cd280e1a9b678b5c6ebfb287f14e9466566031a5ee06c1857c48ce08d28c610e3060bb06823862fe238228b9287821ce240ad0f8cd11041ede72102f59411b46e26174d546aff4b0067987c5862630e256860a19902850c495fe8f0c433f3031bdf0ef662472d5d674851bb69046630d57e1daf1acc10e2833adf46049a1f14365c1f1148ebd3629b32cad4fe1a11a8afc8e911a30c239f3a9ff5eda0458a8a407ee6a9f6af4080e1cc151519642871060a25410fe00ce7178622908f61a676d31c63883a7f1e20e9c540c137972a51e79c734e9c324cf389e1a5f67fb4c8687acc34a5f677df3c8ac29be1fc428e6b92986ca8fdb387339cae1297dadf73cc0f5ca49816060c1828c1bfffd3b4eebb24696a772b5b1b4fb9aae532ed74f716fd5ec8d61fa47bef89741ec9848aef7bde33e1ef48980bd994f4afc0c9b1028285f648a15bb9e7a6bbf3bbc0bd0fb3b6e6bff2f9ef56e4b83ba4aab656a79fb5281c591f54ed71dc383c113811fc72043a619938ee48eacb2f35a2fe5319691ee7783812a642a57ec6204250577f747d54755502a076833c4cd483ee848e34d2b1ffc00c2d81fca0b8ef511ee7711c6afc09d2b19e2204a90541bb4740f7f391bcf78e3453ff0afd468e90b38e8d319739f9e38423466260912b9a281a23062e9cc0210639bce850c60e715c01438a7b0ea6108e70604ab2218c1c5078c0210c182930a38921bad8fa7f82e4340f3f93d8220da0d8410d3dbfb95a10b45d1df339dfdbba3c4d96429376e4dc0e6a807da17fcc9fbe62416182fc8bfcf807790128267d81a5ded44dfa42e947e5ea283aae6c7ecf9a114d3df8e2af2d35c29a8495904a81e083df242c6ad1fb462d4ff789951b59ca68a46338495058c39a045f7cef269374110f2ce5fde70c6787238c4b52f382db903df3eb83a42331d0bd4751aae3fa344d534b4f535d699831c79532367c61850ddb949274f4844b1766bc0004e7b39e8f4dff8ff17034f19d94b8ec47cfc7406eec5e89bb975feac5119c739d6025a43e7c22e08bff41efb21e569413b20ca186136d40d1818c6d522a5240650a1ce028020ddb7c252bf0c051c2c9c761024c023ba881e2745003e5ba2a9c26688b41ac30f4690c5022044548e1220d1c55d8845e08c30c1551e240a30b195bffac07fcc0065a7eae55c3fce9afadfbad79d69b60f3946c42dfe65964132a44e8dbfcdae69c479ad83c7dd6d8848aea9bd43ccb3ffcaee6594fa48664bd8a2462438263498fd4d05be3e73277d5d5b8b5d591afd538c436d6d3f14914106cac1f621bfdd79c73fa8ffb98e45567f83ed29135fa114ac2545f1354fd59244c45c24a603d7d22aca74ca8a84822f46b544f55feac17b2fd7838a6c0849b6b9b13b6faafaede3dd88a7cbd0a56807ab0fbae1ba75724ddab7e357f35a26a37a6eab73e2caa545842fd57e357e7f2a04818ea852a8a745791305155c53aeb5808a276a7bf1bb9914ed2b53a3d339f37a8aac138c0fdcd2999c8fa705d8296cf1d6c0857720957870da9935cc2d5c9201d0b0bc08596df5fc6e81c483b06110b6e40504184021ac0b82207379eac4041c593ad5fc90aab8314d45fa4ffa73f483f8b0185706bdcaa12d0ccad026dc7e8c7280896b020c24a184cfc802484030d2c90818b193560e1828d9fbec0007701b455b986ec411c748d38cd6362ba61579c991d36b6b523c3e519c14cd1c6b672b77e5e314c2975b295a514c0a183146d38d938f56b9b7f045682f7a837e1fb14d9a4ff7b14d9840a91fe8f8471137f8ff47e6d3cae37b2ba98cf45f3f936ff03317402599df93c0765267ddea0fbefb4fef931a7e54cef8e23aa5c1755ae8dd6c72bf70dc4d2b8c965dc3b1951397e62a28bd667acdcfbad720f0231012dd90b8f0d745d7685c11f729af81cf75c65bbe8fdfb1edca68a2405ee01584440ea3d2fc936d5d4770ffe0843b97aefdd94bac83b7219aaee07a2b3a834cd17553d0bd1d00c000000053315000020100c878442b1482cca43416f1f14000d71904278582e1748e3248751140321630c210000038831c6803255260e0f1bb0e8f5a57a22e1323b2ebea90d5f0e296cf79beaf1b36680fb70d52bc6250d1ab88fd0adb8eb103351436be676ab688e1c0db5c11de81d2c2d5b9b2e5e868ece20edd988804ad014013c9418f13492ab997afb931f5f976422d188813f321606d93014a8da3f6841ef4bb237d7f528a0a7da60d30b5205e800197061d6498f12c41c03eecbfa538bdb38c7ae9f3967fc49ebe84519d3b176bbfd97bf05696b176e777b0697fc7d8634f88ecc847054aa83f53729854184f019ccca85e967fc4df3080f4b2d64967e2295e56aaab1356b0b3e5a61fbbeaa6941be600e5c0165e7de4438b40552202ad51acc6ca02e39210d315034174f5a1411dc8fea627939736f4b686d1945ad8d50d82ac8019d44a1cc854767cb3546f2cf99df67a625eff5ea0540020dc74ca18202fa68ac22aa9ca6f04d3200d2aab547d94bb762a985952918771cf716e3eb2644f9fd116b4c033423a5a17e22edfa7a333a185361ff80d6b50a43da6900d2d9f58325e995c72ffce6d399a5bfc9c6020f474de46a92c19b60b0084313e5c52c9160e00f7fa7ddaf24f4efac91c12067a52ff0894dac54b36092f5f1d04a6d4cd1077f432ce9490bd55976d07eccb8e132944f3a2259acda33872ff561c7152b4add5e302ff589158e1f2d823dbc0c48a035e8890b505fec03e895ad611f2e7a71a7755c566a339b2bab9392057198cc0d9fb949dd38c55728abf7ec9e7021432aae2c126c66c20f9fbd3b6f480e4edfca5efaaaccb01d5151cd0d8373f3e56be4d6677c02d8db7503f416d591065da527bda81720c216c1da5fbaef622305d8665a5554d18152b153bb5f0fda30157b3923e9ab3dc384b71e552dab6df64ff14338c49a49c9506abd2f2c80c12eba3d32516bee9ed9705d96df226feaa640a41d414f39ba51524f2494e25a6e29be0164f7167f51f742596466466c29608fbda6ce3e58791a094225abfbce60ed87981516a37bac56973a2168151bd85dd599ce3a81c516549b62410c2cdf5968f65cdf246b130bc226820c7fa03fe6650560bd2a09e78082aaa41c94de854352f6a9bcfbb3cf2d2cecf343aea2031eceb280655c1f4205d4cc7ae083bce4ba6f983bcc2ceacfff036b7a6651678f29aa8b4840284277172b0f5ce94fa507b30e5c230fcb5693bbe2d77130d174d5b1f702538cf0d626605b4d33ee74bbe459a66c87fa232de503cdf56567d2b9f0a82a868b7984769d547b1ddfd82c330d07e7895655312092f8592b80c0535db74ff8b6860dc658042771cc232a8f6a8f16eb3792b37267c8a25fc6be5706e63e5d6471a9b47f598669ab748f03062d9f20c52cef7c96e728c5ef36ed20de17ef288d86589b86ca0cdf1b75209364d2a49c76b0a0252b23ffe6a78d5b743a8f3a71d825898435c05766bad38572ce19fe878f021121683283ab1725ff14daca968bdb6549cdf1da584822256ce1870c2d1e2af7a933895bc6441ae8bd6ca6a0d9f0bd6c00d436574cc6f926f0181e3a16f1a1605e67a48cf50ee8696773ca65b0089e1cff28cca338f5e84f22c02526dcf4b8692b8472ed240963d0e8f8f1a8c3b4d6d37f82180311e181a573c974ba65528d32e128922e503e8ee04127e3dffa011149027d20b9414c9d728405985f7678823977df9ee52e11d1de71aa05901b20360edf09560ec877722af994ca9682059a0edf0c48c2a2d15b187692ffd2d48001cc6b18406b434bcb26fc71deed605ba8719a04f9e8fbe740fc2bc059943ba638a1b2e2abdd07aca164a3f0197d127389d60e7a897b82c0ac8db790d3ea295b864ce6ce55c1aa7a5f809eaa24c950ad8ec7fd7234bbe97ff069bd170c6b1144dc4353bb887ad567c53b6bc1e8e780c7b338c2f81f5552fbb971841083c7dfbd1fa387fec16d0e6a9e4ead3e9fb778731408c6515229bfbaf6d07f35e080437750cf7b0033e91ed93421d989725074a0263cfd25ca474ca0a3b11f56fdcab084d0ef489b313f11e721dfc1352be23c94cf5cbf095815cdd4012608c27b149a8ae65cda2a950908894668e1857bd10885f39ba09abaef30781112d7b12a27042af4ccfd9fa8f77e84f6e56c76935d0c584a0a5a1f409018f4fbdb80688e19787810ef4052f6f0f1b300c3028c6d7e27572c5e897eaaf7805087062a840718891e59397dbf59d02f3d396f00a74a07db32e2875c8024105708a033fd7385ed12af2dc14ffce3650e27385f1b318a0d154e4df9337762f7571b21f7d9afd751cd76db530764b2cc83193cb87de0188ddf4dd4c5dbfdbd3fb8022ba9487f88b1bff80cc82de1f04613680118ae14a8b18a2d42df9a892b7de2686d1016195a4d68840cf38c9df7d6e7b3ce9ba45b0c249be9ed63919ca87bcf664a57b67179f6b13aed13f3fbe988235b3483261cbbd2466da07723516b1c4b8b8cbc01c5a1f63cad8cb1029948dfe36a8e02c71ddc05c9f8317752691f41e4fa8ee9d1085ca4c7413865adabfc265fab25ad6b20b36ca425b6e99a4e0d1ccabf663e80d7deacd4a531c8dd7b897d0b1337272d90e6b250dc853b5d581be9e9cee3071ce695e1a8ffc9b35348c9ccc5eaac94b7caafeb24d09d014466fc739e1ba1d77e2c23acd33852f4980f62e1ee8538ed2b1007bd0da9d66b60780b23374932e6b5682c81fa519ad2f9774b2ad1fe6c2c31abcc20bf27d8f669762d81f7d2c8b149840d40017447769e13ca72c05e478422f438cf0ab9c1294a684a9d26449dabb2681d897a2ee151d85601fb69f2b1b3d021c30d9fb28f1e35e369b5a2dba11a1fb49de0ed2f1a54f511c91b472f8df8af7e9e78fa02c71746ac64c30670f7e96fd127fc643ec049bb7a65a64f5e9c4585abb63370f2d239323551f6c1afdf6858098e3e01d1b5ffd2bb5ed814493674aa5e21ac8c695116ab70e989390e4de2d447f1fe262bb35fe8062d21a63fd7e6dd84371be0ed00c195fb9b5a06c3696475bd7f12a1d40af6a9317a67c9ccd7ed4add79b6d1d477a84f51e49f7585b04854cf09333dc3e35485f0edec69ceaa48ffd889ef6e32db064a28f94dd5f901c485e3b460c66c4f20198752beb32e543b955ff1214881739afd34c4aa35a76bbcff1a3ef0fda890ab3b2af614e5422f707ff153090889376cc9186d9b0b617ea2448c5706100e20b0d684b09c607f658f9c2bfac88deed9afcf97105fa7c58376c2747147e1fc74ed9549ac0aea7d20c57d0c9af4c49c5b8d93d0bb2c362573c784a3a1c4f60af700f7647bd07011141f353696135dfaa022ac48f40e4e8bb63b3197a8f8731062aab3ef168bb16cbed20573465550187c793a605babfe9fc510f132c63099de9a048790820a0cf3708ec10903b6dd1295ab983c3b5b87c80b14c24867257a4c925e8f9d3fc16460f3fec198169bb6c070174e6245a56dab98cbe061889aae795253563a24c2346fd6582311b8f473f32a37243afc0052088af108ba191e0906e5859c28fa0a4b3887da17b244d73e2868c7c0a2d70f873a1462f0fef6a5ae48cbaf710ac23af47e8afc50e4295d49b1eb3a6e72b8de94eaf3c4333aefb67f2852a3f14c5378603ea17148bb6b429e59fa471369a834be97d9f0d3fab5f4361a49b26ffe1112a445b9fb36b236603ea85e5454d8de7e9d814f2c7f5892be3a50af8dfa9072e9def4614af3d8425155512e96422fc27c04e90c90441eb182440807bc1d351053974861af825ebefcb47115f6582db706a1988de01b856d1d5d1a8c574845be81d084a0b32239cfc46481b33f782600e4434796a35bb933e504dcf74b5a61c4d32b026f11e404a9f4ec07084794715d6b31ac681cdd2755e1f6da19d372567d3310251f2e468f60a11e7d18e4ad529bc1be45b4051ea911a14a402a72d03fe2b6e85aec94f00ebae699eb235d06401011250270bd46509c5d187de0c2c6f6357c4c4e5f41a964fd3a5e8815ac4adafc4913e6a58005f02f27862952e744aa834c5139e9302d791ab07cb514e53292b9b2553a8cf915369a6625d7635d0565e25da248b6c4aa82a758aa40d132eb31069c7800d09af6f8c2d4da11836f4a34f5ecd0b1c7f743ec94cc34d5e063b37891f871a03aa424b8442f84e7425697c2d48a4485039e8d5d7102a965568d53c5ca541e48744798397d6d3baa951e2cf8af556f62b63f503ab11c7ca7017fa9059d3662042c877b6c4ea0298a36627db1d0993b6ce82e2907bb222e4992946bbb5c8791ce8fb4d4046c6bd128c7775d92cd2857b8db6a844e5ea6e773c5a6d23bfd1570000ea4ea60da10b6b4097da2aebca64a1b80bb751a13d524dfd046df4a32065288eb6eef907970d1f514dabc4107932d8c9e8c8cb339a27c2fe82c2aeb1bb9e6fb080e5e0e5d5321dc39b9d12c88853de2e4d05eccf386d4c04c3819df41f309940273a62c4b3a301cfdd1af39d3158783b13f77c0ea9995e04282931d3670b71d2fd8eec8108abf08e51021a27fba5ae4589cb8656e0cc9c278cfabe13c00d4df9ab177300ea5ddfa6fc7843f1d6ec42ece3c05b7be7a5349c1a924b90a8a2d9b8b568512cded654bf18116a90003259ef4484b10902a58ad68799ced95976c3f9b2586f3a7973ae803e94f86c421b1154b78ee9b51823362852e30083f25f246be29224f38138d699354b57ceff42b417d06fea4100fe033f4d2ee20f8d768f6a59e6002cbc8c18d0c76bb7b94ddfdc89d25e373b61c241e63166c49a303265221d223e0732aa32e044b8d46718ca31e9a47963d16117fb12d72ad6d5e46afb5aed77d977093d0d4f3e1c31717e898959c11cc1d831fa69026e4147ccb416f021f8c5e01ebfbcf0f0e497a8f4b7135bbb48077e9e93c4f33848de10339434175064d295faa40ec0a48f52860282d2022d3cdf923f3ca36fdb58e0641fc36877858897a27bab327bb1c9f62dde43519d569daa974cba12052c253e19bf07047b9c08c13761d9db78001609bcb8b3ddd075d1d2f42cedcf8066cab810f18068f46051325e57d3167090ded2456877f3849425d4bd74628b2ad191330e2ae6b695ab4699ec716554538b666e112b6612023a3c1d1b2019e4818f75e73543cd084e2dcf3fd9cebf5dc2071cdb401edc746addf87d312a4ef77edde6266854358caae27448682125fcb58881ac4dc26636273602adcb4a7aa0346236be842b301d862429477ab7f3e1266e10c8577a488aefa1e8120758956b282252b6a1dee66c7cb6e8be4f2ef16e50852bc036ff1c0bbeafb964f0830835ed8d3d323300f59890c7af44ce3e6525424e7e611c0389c2a1d0b4eb3221f6c9d41c0bd79e259799cca7c4a81464ef95befa0893b0e1f4a8326d008ff49ca52a9202d25ce67a14032288fe75b2eb42070b0dbcee415f1cbeca4a472a45c4f11ad99fd65376b0a02f4feef473f38396573228dbbb6a5b94e837840eed471064d2a0b60a3cbd214df550aae648645b020e754086f28b07e69868928c409147154dfc4af628b89fd1bea932564d24a8c390672b88e5c10844d05481614bc67cfc1784b2ac83253355743e1313e1aa8c4335a641711a1e412d43f44a29af38dcd55f14f5b2c7c6d11471d54dd906a515c626540ad6813fea7fa44f44d321eac43cec03b8e971b1e7d29668c19219a7c3dd49da509669101af7abf9fe0441e1d7f41cd70ae9595063717f573d35bd45e6add56c708f1fd90e0225f258b388a4fb3e367598fa8d68deb4b8e3e316a69975455d82230419b77d2228fa0cd38feadb0a1769e3de7227649345439519df16b3049f8ce380964b2ed23b8fb8e6f07055115520ee427aa82b0eac8432250f8e82e68a1ee14f2f63d06e482c5266307292ef17e7058be531c800b7535d5314b2e69994a84f23e5ad44bff7d83c295bf397abd20339b7601860e97468faf5025b00f8a09f8fab158b71ddfffc8c40250f4a5e2226f4a2636e9cdfde29638691705750d8ed430c04e6eebc1b13b81ef873162a4350021075effd3ffeb5e6391b1011ea21c104cb46830f137f27edb6ef240793b013e10ef21648b7d4610b193caa2d058d728ca5516b6d1e6e975ce16587d9f93ddcb18fdc6270059eccb8239ce2cca2ac6e37e0e2cda19abeff8dfb29e1c0b0247df31c6e38b0810ee2d3546bac7c331b18974b8b1414e014ad403008353d3d295622dcf65ce38ab32fb506e4c5356bf7db36da9f94faa584fb46150928a069050bb2223fa301a8f2a59a80fd4bb5e81578efc7886b989f76f664af09c391f0d3325e7a3e482f2e64e3ca92a003b83d06d1439e06151ffd737a59dbbbd84993afe18cd79dedcb96c48e46878718d6a408c3805f1c20aefe2dacc0cbea228034b0feed6fc883150197de9ca45d7012b61468a9f42a79469b53e530d69adf859012bd133287c331ad680bf12692afdcb9619bf97968cfc8953b3fedbee4e253f56b2260799f00df40e50299d81903498d145924f8ccf7f2eae4f00990c1010a87dec66fc5f146853772b8117c6cfcb5259bbcfe32e874987f8e10d7680bd26b2dd1397421335738532958826746cd1541ab44da5ca722a59ae53097d5219af50a998c91e1b2062a2a966bd1e836dcb60447336d0a00b888002faad19f85364d41bd1f6b99258d76d88e4dbf437581989c2115873597fb7b9da85e4a39705d215810039cba18dd4f960bbd49e933a283bb339dc29f07967de88d79a5114213f346521015e57e6487920be6bb3fcfd29579ee11a7136028ccd58a0922e0366bc1058d55f384c4a4c062c0c12bf58bc74e67b698c63107acae3dada5960f601c97a0614b39801a40dcabdd731ad0441ae8a0b90ba5149151d15df0841be2666f3ce626b77aade49449fd3bf12c96513ce7e0fb967b7af78af57f36549cd1855c981df0a78b0ba0fe4a4e4ae1ab6063d613e122bb872abd3e92a3c317cd7751db30d35a83934e8aa5076fc68125746d1ba8f3f7e37757ecd44bf3f2ef01164661b7c68b9bd356e94112e9e8a6d59a8cf41efa0e047d7148d8277f72212174a4ed8294773a09e3d819b41dad63dd9bf93f7220801c0b4a0c1253b3d82aab27f9371133ecc0cafbb7c7556265cd17f54efa648a821164f3efa95fc3a230774619dbe459388154b3b47e8eb1fffac11778e7115f4025aa5cb55efef68f8121aed2f4c4a8e660e61e66e061947034422ce299059b511ae398bc58c54585653554383a019faece6b143effb3ac6a4c124b33bc7850f2ea1dfdfe41b7638bf371dc43657c70bfee8fc1481611b245f0b77ff231d4864e1565a3d1a2271d852ac9aa001533f3a3fb2103091e88bff1a0b1d1e276e21be0d5bd63a986b9ebdabb99501747b03f11f25a2172d3a036f910ed98f18964add16129a0be7909259a96efb2129a82ec351a1a912051467733828898c22eab21deadc08952cc47e9128c4a4c604cf0652b6930115b81516f58637d1c63d7042217027726433a68b07c3ab918a12fe88584d275c04574ff7bcb784b085683b3d3884c8721ca18e532c460b489ea8cfaf9218970a012776ec501c8f5c1bbfdcb30f8deaf366f97904bdb3e41084f91c7fcf40326f8b29e5903eded6d44a716277ede2b4d53dbe0ddcf1f0687d717155362892a8511d1df4d9e812d7a775f53a154a922b8983567186f257868ae2ffad9400f864c06dae39c0c1660499f0501056861e71769b061a4fc97466481df5fff08431f89aa716ff89c76f5b73c18aa81a50fe2910ab420ca732ec2875bb1469d368d1b35437f8b2bc0d4345d9b5058a911c665e5814427a4f5972aba2bea0b4bd46e6ffa48a04a178ccb259b54bc24c268ae0313ed0bc581e1345b1f645a5e171f5fc925d7611140427b6ae22605adb9d15fe5d0293c8e8b9259a358aaa10019561cea78409582860649bce685621bae675c26df93b24173bad9761668373cf6c6a4a0dd72e2700a9d7114f224429b17ca1b0e6c392486451423ac2dd7c8d8e70a7888e7027e70325493a402db65292a6556a0bc082cc247882b53b9e4c0e07a8792c5283437a6c68fb54874b1e96d31a39b194aa0ce78e5f009642304f3225384d80d83e8664062c46b1a862cb4874fa6e10a48df4edb62a6e2622979e3dc6bb6b04726b1c48ed88c38badea22303b017770a2a0f035f214cca6017781c5d0d98d3134bcdc6087d0716e4ecc23e32bcbb155be8c4b0febbea14140c4d812ff60f53d89da489966d2618ffd44ad8f3b0626d3c5109f49d5dd52d128c64de8124e6a98e094acdad3ad54c3506455c47183dd8756b552aa3b9e84b659e481ab845a639e4ba05220f2aeaa903352d04e91357a8d52ff49b90f3849efdaf85ce8ead80d2b184dcee07a3b36b6f5357ef70bbbde7530e2f21cdbb4aa80379cfe0c46e89f4ee37daf636b49ee14210346b2a4880da10bdc8bbf8d9e230b145559eb2e2fdeb37d2b4329146faca81018daec2f035af43a866804a2a5e80589dbf9a0e0451ba101b15e6e43619d71b2553b7a9176c2ebb13d50b8b160edf9eb13ba2c2a07b4a95aa8170c2bc98877c77a55c66e776aa1dba8cf81da819ba101874432f6da889b29cf0e0596d43b96ebfe3d72825e564ede2087722d6b305aa6ac5437ceca6c923e77cf9d881c978b20e2bf8f189a05b9340b821472d3f9bbe5eb2cf05c16a6e0d591e175665d8d83ff740075c32b26c348ffddf6ee35f02634b70a88297efe5219414d5044573938c48b4e01d485b7000eb3440037e257eaeab57854a501250400a78a82b0bebf0e44a3e40b41b64495e0f8cd5f9c06c147407cd2b96b7d18ee7a144909f96be74acf392230563e0edd8a839636c32d016b8852814faa1aa49394345d8bbd1fcdee3b2560b705a50230dd5484bb96653586342e9b1416ca65b3daf3bfd9f0004d5c6915d3dca440abba4eccd53c5c4331dc560d52ae4926d4f7d464441063983720228fb873a8805c9c222ec90e3c92e670ee1ba4a1fadd7ec92fabab1a54979d948236ff2d24421c9d6d18073070d356d662c7ad0885413c64b5468263c241e20821e00218cff499724c86b0347b2871257c925b3774837cac3e7a4ed5f33d0675ea185914c4c29271df10455ab34f7bf986e91dad967cfaf035b66fee386f8aa0e66e037c5450cd966fc656909effd0ad8a4bce8fdc9ad19a3f541dec4a569a88bea919f6ebcdc655ba5ebf0932c56908ea9ba7793754ac56d32416de90d0c237557652ee9cc4209af4a3248ec8d153c36a6e19d48876e6ee4631c17eef4329b7707998a82f03da11e3ddb8b716754179d3ae051cbe03286259eea03f3d3127cad38a541b0ef8e77c5da3594c7121efc2e59f7d887a20ddadc5948c35810569e7806a44763dd0cec18a8c0ffb8382471965672702414b11b712f11811469577d42dcf1cde94a2de980e658f9e914ff298aa09d6e83656a70242513961d801e5332bbae23de9fc177bf26d4c753eaa1d9b1be7fcf852b847c819cad5a5a030a03d1c94be02b205a0dc867573f1952406d036059bdf341c75154707cdeb18392eba87792743d9964d1ff4a505f5d7802c24c281004c99578b2192f2e51049feb2338c67d14b681e9f320aa8456e8889f0c9765bd7f0b395578c6648d4503af9da8bfa7265fbbdb433ac760c70184c6d5ae5946ead2abb260927239eca9cee4c58439a28b23c5d5465fff7bf4d9bcfbea467a40366096c65c8ed971d0cb8b4797502d4cbb7d97f13643b8905a5be34ce36526acef6a272e6c08e16f96af4dbf8044000cd2b921a5e960151fcc911cb6f166c089b59a9b0269876c0caa2049f35f85a2034c535fddf2c4c6d452b1e6455693e5c5642f15e13ec9d0c18974e2032977d5662865c53619f148c3d7693f384e0385f1880c826290c40e2c2937577a68df645f88f00756fb62e2e670809383ecc121c2779489b099bc7a65a1354252f816644ccafabfef7a5876a52b048de21d044aef5dff81d471f991f6eae0b4e7549f4a6fab25bf21bf3c8a359f845c84188f54b28be8baed6809674a95a113910164e71a86f6555ecc7baa70a1e829cd776490ae014add5115420ba88cc73f6eac4ffbac2d0390573ff98f972c2dfe760accfa47b391b85ef9fffbcac56725641d234881364f40f50829d3917abc79a242a73c092ab4ad7705d28afbc8a66e4e9cd80c0f927bf0c438a1419365933e7a6424085c7208fee10b16c0e768d23cd4b4deb70b14a47f90944fdbb480b41cadc8be3762de7734427d2c68e022856d534c40c5deeaf741913a24779790a8a09f05c483389e0d7e19adaa99c28d53fe8ef4a943c934ba86ebe2c224920bfca23f93b0ed1ae845837902105df92253a6b2b95803aaf8be51f0bd2c7a447c93b53727bf71e52e84dff5748a5fe6a87d17700ba79128bb0276e14b16300637c0243764b5f4dc592628f1e788defd1616aecb94c93bdd4adde570fc988165f963cacccd466b757bf9911c80ae3e7cd6607f457af83eb26a71845ea4448701777df9c068fa02d6e4a627e4d4a67ee98c32c4b58946d5562931645e6a25b7a51b8a26b553c39b9a0318383472201aeee0d02ab1d685f4796c10e9a270ef8297000d342ce8d2ef159e981cabbbce5d5d6baa8839c64e8b2c87d4c6f197885c6e3d58e27cd23f81313f363417221a318a1b2a7d6b923076cbea21ee7882983ac90de9fa9b693cd1bbc0ab3975d8ddefeba3506a5d3e50c6df9defc086d3d18b0ca31ca70e3525471171e682cf047e8289720ce6dc3dfccc8f6c0680f184c0826743015bdd96400f1270ebb30af66a9dee0bfec9b9460c24547984518abe2b902ce4be183d2f6bab3621ceef0e8b80bd31ce21a2c4abb925de4062900e1ac17744f6d6bd3fd0d98f624a87a0c46be7a832bb3aa9e00137b72f5945f6becd9cecf7381a5704f9a622f82abb66663c38ff44ff6d47ab6df6dd96d8663cd4a61732944904558a6519451ce48771b579c8082e6c24144dfc44f9755c3f58a61caeae9d81fce2072c2b7f1a5f356bd54f033adc6338aaf4a3e4c1bef3a980e997180576bc9163c0568f5f8bf50b72d9f55c9cf138282d4053cad2509297417164af1435548bb075c36557227277a82cf5fbf6ebfd5561098655f9f309da5f77f46af4e6322be243df086d27bc921965dfb1b064995aff1000af6698c01511ccdf9298544d0f49202d17354151053952ff4a0cbb7b48822cafefce96d6d40b2e2d5345ac14611b51accef3465739976b706ed5db50664a4bcec29e29112a3ae2accc7dcb779f8b07831af8adb8478e2102d775c9ea4f3a3f74fe444b737b80e15516f26cc85111430fa7d09bab23d8236bf6add1080c72d75998db8606c0b9bba13cf545cb47a2563bc5b46caafda17115b242a75eaed7cd28b3dfb87f2d38615deff6b841e0f5b1861208a82f65d556e9e4840555398936ef963c7eb2e3fd79d5d06b409f846d93227e21934d1b3d04852f6d0d67df4d016e12a09e59eadb25249b1d646d02f12c6d167bfb2f79a21f865a737f848b1bfb2cfd9720bd4ed04cfa04db6ce876cc202e5560b1411c7ce74522ef98dd0911f7cb4a378bd4a5f8ae24dbfe0ed945f755d8fb5fd75b228b005d1925c5c02bfc112155b411b54e25615e04e5e391d5089d557c632f0f33d136a19a40d2ad3037d48dcfaaf59838402c6fa65521cf0eee07b2d5295f34cb62acdfeb6b1ac08ca553fa0e3167adc65c23b856ead87c5af8f172f6df4efa2f6faf8cb7224d02b09c829270e6bde7bd7f4e9bc1ae341b702d5bb2eef18f8eb3bb0f2855586a13d4c4d2db902ef61d2b185c268fe4fa22bbd75217d1a6eaee3b398ccb200f843efa8bbc3e246a5eb1acda9a1871130413142c064a46aa3b3e206c74208a8e630d5a6d3af8c4a03545227000636a46100a2d98351aad9bcb9b281134bd2c32753f1804003c82e750015047638df24ac14ed25bf2c6004e27fcf1c1e49253b9f6b863be7f4830d382665081f95694bba68059cb5ea5a01da106c77cb9b03cf24bfd4f55a561aa97563b0f8721f0cd50d5f0bca468ae7f62b04973aa9b514bb1db8bcfbe70316e03d597147dd00b7a56edfb6981863aa31de6b33e39fe633bf051a2df903b0fcb543ce156df4197c3c0487d72cf5ad2d69cc45fd5fd132126188d1b16b01e62dc7e5cb95f4920424e9cdb6da01507d5072ff76b15a19bf4cbf88841282dc41a8dff3b48a4ef69b1e16824a87b578a88d600d3b67a69f2dd0fc9fb9592b7fd4d865b1aa20de6586a26b1064fe044c6a1ab57f0df20f54546ad0cdf122cf535319b4507678f41a70b28a9b5c32cb019f85e730cd968bbad345d834ee60d138f4ee65297cde8d5952fd95398c2224f92c25b27cf1fc6ee043067f2a5d8ac873a5684b176b18bd5978a6d43afe6f7bfb9dab232965fdfacb53bcc457a4c04496c5ea362e2acd733e617ae61edeec3823c7f5c1f8163e5ac4df2fa0cf6e9cdbe2dba6fa8763a0c4381a549ef3385327ae244591077dd71ff5853d073489d853932ae44d99cdbc3d285ffefa8757401323b64ef8ac35b46d597c9c75e3a829fcad8293012e05c116a0aa1dd7ec5cb8aec871c6c99b999bd45aa2591969d9cf06cdc1b3efc911b8182e446c1eb9558e01fdcad54290b404609a81c68cc1c5bcc4355576a039345298d665441d0093a67a5994272aa9812dd8c196b7ac87b2062193bf39eb3980ab822021576670995959210fb5208bd041c36165d36bd31f1c00f64cb7c9193db9c4189990258420d0a985532d0545cca74fcd8fa7cb07ddf435679aa1b7fa19c8aebee6f0c891cc5eb1a65c37fe822800c820f4810c484796d8fef8cc174e54a436754efc88b34e3b10c8dda869e37b84a19a5bec99dfcabc2f323d8a41ada9e774d4c55eb4d7000ca547828ef1699d23e1e98ac8901d16c0509006e2561e57d1b699388fbd10100b9f80ce5b029d890e59278fc9f40cd771a42352d598cf3958d47a9647050aeac9f29f8052d7fed8961ba29a929e51f8108783363728f5e6c377608dca2b00bef38969cc6c80e1ff1b6206d54403f2c781b6b14442abfa4c1fc5f5fd140952827a01a60a9d9fff073aadbdc5951a51922c39f84d782b24746b4cdb1443c3cee429c18d2bc11e2ec11ea9c0c50f99560c24ac17f78eaf68f3aee4bd426f5fcb3fd868cac36794dcac2cb94686d8c58f7b4bb5cf12abcbc76875a0be7671c895f8c50f987e0d3903c397224f7cd43540c359a508d6108ce7bf19eb33ef1e4526e6bbdbc58f0051c91fb75c8369728237bcbf0b1bc5884ec08ae5ee857e3175450f1b3b0a8899b2d2101417767c9994a00b55d085d79bb3a52f80e8f8d2d6104dc28aa080b96fa2a058a6c639ddd883a91b2c26440b849976c73776fa518be4ea823461af823c105cfd3801af919b3e662d4d84cfad18526222e511599dc0af3ccd3d83d0dcb8b2f53e8967b9964458a7ad8b6893c66cd7f51f9b33e36cca0c0a8b9e300034920910a92d01e6169668a9bd092ea8d8cd9db8fc27d24d35191351f0b27efd77b9e4a660be9d7063ff35ac29211a52ded52159d6af8f2b21d9bf15cec4a2791c63263429bce0a8d9bcf89e07e9b529aa8c8d98a96da40966634b8e190098de5c35e51f1b609a45c604488f7f1a87e2cf932fa5e25e4ab8aefd0c2b2a883cf00564a2009a542298305452e45d4d05da060b0ed5e87a918fe53da7d97b84a98f29b4008bd694df1217fb994ce16cbd298d02f2b59fef9b4f952945deed5b772d9e1bd7c8eeb0c0441b364b8c1f7532be558f3a489d1d3633d42eb03a2c20c1302c2f6d3f70f47e98271525f774fc16d9896cbb3db9d0851b9ce6e78ab8d5620248cd1ef15997a7f0289c02b543a75034f90b7ca94b3a0a81540a58a4336b8d245301d93e3712ddb17a13ce5970d826427d7c14cd0b2e89ae088009c7a7768044d2e53f2883ad90c8db324d34f456696cc0e4152001407212ab56a301f3149fb849d3fb9fd50ee45450dc2bf9ae8c203890e811ede649341a8e3d0442a85d2c26f31a3194b7ebe294342db47f3572b8e93ba4c9dc5cde3661c4dfe04463303400011ef81318c4f536d98ffade19a0032a8c05869608c3474c98443200adb9a104a25c5c976e90b7d2274a1ddeb88be2ef76c89ee26df127dde385414f0113478e16c3efa0737a424e51d2e47c3386dce8b1b5e8380a84c71fca30d79bfe9a23ef129ed85e2802868c3cef331cebce2c81682d308956c4367020ac0c65d674161f1be22e26273a5773722409f601c60ebd10af1cd54f59f89d52eb41f118fa92438d3ad630f49fb2577dd771acaf66774c66a16d6bce38945b9b36506f44155bfa946338cdc3a39c564fbdb2e911be2018a1793ea50c4071c2b85fcf0010128d0251d3d83b5a4560f4a85839846ce9594bde31a677d000c44a447d2c6e58efbf15a24e2014134307ac5bfbf2e79d147e4d144fdcd28ea83ca9e7776dc4a8e4b695c88e46a91cbf2db02478f72a70d392423f2c12af700e5629aa1d963771edaa0089fbcca728245dacba894bd711b072d9fa0f9f32867b691491e39e4e6cca866d97c3a2842a8925357fb9d0f0bb87c4126df61582f15b241e812391088564472c34f8678f5ab6fb2814a9efdc45e61affcb14f4090a641dfbb2e2eaba12974f4dc580c2b2c66ad9b87485c4cb5f93682f52160bb9fc9b43c994181f2366bce7295b32e500de719f94e1bfe18531362d9a8c810b9ce69710dc390412a4a49bc08e23410ae90ecb195c78558de4dc544c29a61b366771e1751a907393b127fb11e8967fdd9dbcb093e0911b067f19058cf11d00832c6b3f7648dd9757cf8e5ca148ad71746be5a9310051e03e6de2a6914b594de0ec5c53314eef019713df177ea1dbf3d40e156456f60957c3f0b3f3f39971e8f47d871a02ae2eae5d8b8ae59df4faa062a5cc10dc0d2d53012c15dab04e212bff01a22126a1a5f7db0a39f102509d0c4b0d92d2fb01acf5fcd51aca5b3312acb7ce2f6c871422a07db08a8f5ce501bbb3b1a4609da075d8ca46e05179946efed58c3654458eeb34f3463a14ebf511570899af8f10c7c019acf6d0fc165c3ec7971cdd76315754803a191ea22b0e8357d9066087c51fe03bb3a028c00a79f1f9d977c9acef8e6683db20c614995646660521ad683dd39fede517380ca311d8784087823c135f258fac48133264006336f7429b593aa97e98cd25b86dcbf91b9fbba1462b80351e2a964c0a4e75160c3c2c7cb1566a20f5057f31937f2267911327aae025cbd4a7c177b11e1b2e895f1deffd90fe72355b324dc22c1617ca8451cf33a3e79bf860a84630930928d950cb4fcefde4395dd17490f481b20c221c07f1820b361611dd4559424c7d62b27af01bda9a0fe3abac74eab17802108faf3e2dae2b9c5b497eaa8aaf150be7715c120f397a8c1a5553b92b81000fc63986c0f418d3b9e888868b8f376f6674848603f6a6db77aaa77efcbef1d0e668855c3e46035b356de7180f4d241ea03e4b96d255e38d23b96149d962932c44189d608daf06d3df87ec96a8aab7e445dce3e76e8b9fb5a71dffe13ece855dca99b484a22780058bf6275c4845e5e33dd2f8c69f6e17d66bb484bb7ae27ded43a59f866a59e780c38bbbe9b9f602c50d56f656f66fb02b5f8fca7e2cf0edb14bd7a68682ad8d5b8eeaf28b1a11b7065b86fd897e95fdb3bae1bc9291a8887e8f5e863387290da0b76c3709e91526361cf565e2e2a54ed0af09c961370592a2e2a93f75904816618b45d91bd53b989214325141b211d70783c4004bec57a284b5cd87ee9eb5fac892ffa4f740edbea81fd76411da93f467adcba252297ccfd672d0a9bb7e6e4cbd778aa40f433c570304a65814b59346cdd1aae0b6f3e629ad01317991a92911a786d4d30716f1f10391aaeaf54c045800741b50a80e7528f3d2f23545af33eea1bde378129c7dcc20b3a52888b99e093a1bf1dfb67c5bd976a79219c57f0344297cc499773e77047f63fd2318df67d2f1ae660acd24fcaa7e84b8c55af7386f8cd0a644121f86fc9f2eb81cd83390f86e6aa80df9ea8015e06f31636cc86bd3f8dbdfe15176de65d8e9785d71944433585917833538bd0b48deb2424ce31347d9bf640affb34d98f9232dfaa199b381490c05e9a9405a04be90460ff068896306585f2b8eb9a0f16d94ba08eabdd8e9b39c1e8bf8add142974c3eaebb028da0ce7656f1d79262b8a350d1731a4512143658204dcdf0c63e9219bf308f23945e96340a9fab6936ef7defd8e5e1fb60038b7777c305f5f5e3c2ac8e41414a06509534f8a8a7cd8ec2e1fd38dfbedee1bd44b86305e4cc4ec7661ca78f53c4675672394e776ef91601b3d636e5a840752a1a84db9c5dcf18a05cee8a02e7eb415d4fa947a97e5fa719e8c06796993341b3af33963c1eec95a82dfdb2e87d997fbd0902e468d3e566a444e54a321b1bf7e94456ca03181f6138379eb8599fba23d40851be8bc5db106eab48c41a5eb72a1679ea89c12fcae958209c8ea597dc40af6f7bbc715ef2955d73a34c7427c4ddec966a1f19bc2a0b607a76a742692f8b169405bc6ff7c117debc34996968e3b8bdec2eab760336297f10e11f64d105e20148f78faeab6e433ac889d9f9ba244eacff93d08dd479f8397ed0d88c5c6d0aceae803791900a6168462048775262fcc1122b2fea12690a77121f93e8659b0ca4db9d0e4f6846804730c11e34fd65d98a52acb7f9aff506f769c399929b95b817e062b0eb3cd0df5002358dd4eed2af9b91d20e06eaf54f168e8c7e5cef6022a583dc3295b1c636cc5180b2ab1270273af862c524580d6c42da19914bab634f8b534db17b1bfbc7c49d121a18549d74166829db036dd455cc6b0750e640cd7b7093e0e690a457e8eb4b0e7aae601037c5564570be4ea52efe51d47dc9ec3a193ad00fd5b1c0bdc1b4f144fe2e2bd8bae26b23336d712019f286e1d034dbba08561d40a87ed0c2e9d6bfd0d300a8bc97d5efe002ebe032762d088297dbf1203a40585e334056fcf3abb0a1b351a01311c4aa644a1f715acd719884285116dc5885815db4273f4b422bebee2ffda6c841b64c295bbd918a49bb523f5b09921bff1996ae1b33455c71630b0d6acd805c69879318a93fe0dac904fae44b99e38a9ff2424f67de125af24c6f6349de75201423dc2acd32777983fb368672c6cd599f721a52997881bfe302110faad6b68ff87ffda8d487ffb3c9b15205147f6dc800b49838e1bf060b73b702122e59edb96434036afc431d1b26c6fcefafcd3865a6940230ada2bae66c077642d1fac8a8fc364958332046f11c6f424d2f9dfc2107d895f1c33385fe508f47635b0a16c1ea00328d7b534488b6b60e72b5d5bbc7aab8b881e3d2d3d63d2bb0ee7ac49c57e78dc22d63a6298c8dccb443632cf66dfed80e92851b5efad60974e5c9c6b15904000533aa5218fd2583aa029e14f1a0cc4d5bc0dadf7264d2c43891b66ed370349557dda9357717276a73aa5802a7a2d689828b99b9c08547e52fff9e248b7400f9d7a52a099c20bf16d23582a463dbb839dfaab7af12590710512a2a2ed631b8b175872dac555bf93499ee54d046a26a0b6fd85fec4129a2066cff74947dfd0fff196e33493358cfc424acf584f16b957692fd051a6ec3fffd360ae508dcbf7ffe3b8cbe7d7d84cc882242ef116d197940508ec661e55ae1b4d9cf690b3a920a46f5227738b84136d970b95ce90b9e4bd94f4f27ff6cce197926dd507ad77e4930eaed87c9890fe82003df296d2f44bef651ed281472699834a2c99cd3e41b43d47a120c85d428e764c88071199b7720b9a0d4b971584152c948188d64fab0a7ec0fadadabc7012003bdc2fd652a718bc0792c2265513077f46ed0812c67868a04312141b1c77e98f22046255a83d36b1821ddd4f249474ec6633cb9e0cf28a4ddf9605adf469d61822922315a2f337ae465e2c19547752eb0ed7c1962bd992547485e634875371568995149598955c214518b6e50e08a262dd8d0c4e17d5160b63b388b54c1a419ca53163f87d1b40a394abb1bbbc863390d1744f42bb32404a1e7020ba404c203df32da97b091cc414ddb87f625d2484db921c9a1ebc209b40cf01318d51bc7f2560cd64fd9a9764a5b52692b6306b02b73c72a8d48912c68b42d9b9217a3a1a75b1ac36f790474730a0a0a1777a0ef81d639fcb2f0a9c736036642c1bf317e5fc689d2a682aace8328f602387800d20ee317fe673737a7db583053ffac3f6bee003e04bc40019bc60d529efeeb257d89bcc71743816c71947ddd50e3e18a7ded2abe5f4ca3232ac1ae9bf0fa4e312a9c1d3f80d76854337be2befa61a36590750a072dba33dbe590072a7e8eb79ec3e0c79eed40d656ae66f13a534f5f8709dd4c95780821b05c089c3e4ef3c4991b993dbbd397af80a9a7bf2f47a3671044c7566763ab68e7c6eb8a2f82b62d5731c404c67a503c2a8e9ebb9528f5dc8bb53351e6c0756b89f9eb86e6a5251b434f5991449f4fd329cb96122a046d1c23d9403126a2b6264d96070e05f04c33dd015182409c48c85b412e18ae9115cafaa82ca019925bb02e4e9e4ea68472cd6d64cff5b393050ad4cccc12fc217980d1a758330c128e8eff14494f3eb91901c811013a5ef5fb9ed0b0e57b74a4a70103bf1250aabde66bf5f08346512de7b8f6a30b10f473d0bac683ca0761c1f1548a6990039477ff26bc88cff345c8e7a30b52e55f53ec96259728f41cb83fdb23cc7fbab348d18a20375cf2d6e8e1c3173397e7d09178dbd77f33df9d293391b27a77338f1401b77c16ca32be23ded6b84349d5b960660a8e6428e10169cb152f6150f5d796890d3edef1153db50b5d442c54c7790e327dd3ef9377dd390a100a94da9a52b2737decf4ee94f6eabb3955a681e13cfe6675533463b3516f100fdd16439024ba4066bd1cec07aedc847636b95238f1b2be23eb3731850c41fde3d55c7cf1b140709f7355376ff26fb86a03eb4c8df401cb0f88121adc45b37e082248aebaa44363954969d052b79f46f3a6f94ecb497fcf38b2583c9530562d4f5ba4bdfca5bd9433d17a879ad6a324c7d5e4071d4e71db0e0e807346ce4bbd85eaa5fe3a57912f710d508c9a79096abacb0e8ee6b3c0b3f998beb25934f44957004a524ca9c2e6f9352eac5c4eb7107a2becda65f3283611f56d80f5a8cf723760e12ad79a10a9be89c9310f3ae2ab826606fc32c1bb707def882a33c97917c9223f5c0f88eb0371ce40d592e3ab1f1b699109b16bf173f9d55390f4204c312725d6dd53487eec4ca283d9c366a8bc1c185e9ade27f01c24ab2469241e5149cbbe316a3028fedbd3c6c8724ee82400ae29a5efba4a9f86b5a41f641d805b8e5c37758e9d7be2caeae44c36103e38bf6af66f1ce34296b52ebcd9fa7d26d3e5858e163b5e34e02193a03e71c043c4a1d7f6a3fe9ac43a98731da21a6aef639ecd3021923692731ab6070960147470677d45fa34cf789e27044f09befb0f210262327ad8cbc3facee8fec76102e97270f6038c555ef4004f2b6c75b052891d2cf260cb807c30ccd196b41f50a01f7a2df3e466aa1eab60b7e5d97485ae2b9177b2bd29e5b95aeccb1ca467a6b242135efa3124da97fea910b3566ccabcf6bdb8f9c724d48ebadf8cb0246f1696445c15f9a0398bd7d69e3f6e35c1622214ac150e793c1efb50e9226773689b5866ba90b542c7e4ee4d5917977f8526ccc92a9751206081b39781c61c5e1f56e69be85c4b71567f6a7feabf9f7a90b3df4e858ee3a95f59079017bcc34ed4b083c418044b5601af3102466742570d598bb6e7f242d610481f32a52686f45ba546119076b45eec1bf6d9f2586a5f0dd85d4c87c257885c6d1b83b40be4a02df60566f2f1aafb954c95010142f3978e41d3b38a178be891ecefc83433d1fc401645ad8b03da1ddc9ffb86a147a504cc7d9e84ae522754cb02bf4fafa09178fb33d21557af82d429619098067bef749670a28cb27944587baa067ef32beda9e8d24e66e2ab2a70e25518fc378628ae7bed9dc46c881568f2305dd83161562c20ab7808809dae08f892bf1c6be0d17654e39fb1a459a1a8fe1d794d0d889f21c23d4e9d087820f30f46f81dff44673dd63132fd21b84325d888121de6ece88f742dc8ecbbb465b9f032d76bf3de8f70b3febc2a39054467b050a0ff6b632d4efce823777b4c1c1aaa097a13ba59696db25a6fe8a0237f11325a9bd0666a609392d5ab9b922aacb3f415122e9ecb1df2e278de561d78b2f3a49f9e94eb33a54dfefb402ae331b5be8b6f5553387ccb1304561008f34aaa08d0ed3c9be1a0b4fe203be7d6827f7e63efe1eed6e6d4ba7146b66a017a83541b6015f8924124b03427abcf7d8f78d2957bd0a656055f246322e2932948f87139cd72eff8ed45d8c824d09ae90b3a8e4a260dfbcdc1810f19eaa73b1d07fdb5103f1d6e12cfd9a8fe62177029ed5292fb7874a66fe885b842b3fd51e27b5b716741bfa02f88830570b6eb42213fce28f0fdc46aed2779be2ec4ef3ca65f642e142e136cdae4ee3c1fbbe7829345a0647c55412de742666d34ff5efd67d3989c953aa15fdebc7854931a82ae81e1a5025f244a3a7ee319baed8cf38a2ad29a4ab3e731e940276f6c4aad1ea55db9b53cbb236c3c0d83971205a652303780815043b88f271215a558205d9d0ccf51175c4c658509261164c204ec7a47731ef0573c68e88e5c29739db8ee995e06d221806f01bfc3d05e3efe936b2bce0edb56ef879f31c2c5e8f339b222a46572aa6b128f2f07b6e4183e22a977c26a69854880a96886a395ad37da4e5649cd1f15789823140f91b7298e3335b48ebf67bc4b30a84bd36625343788bc9163446923f1f2b97f6f8807d1429db9975ea9d3c634521500f290b63e297aa77e39521adf7dc2111d2142da98fb5338d73ace05666d656c11aec101c71003abe55301b07adc2a1c2d5135cc825227e68d21b5c3bc4d09604eb7c9d50310a13fd26e9a361c45377f120d6ae5811ee86cf8761e029492259ded57591b31ad857e9581b8ae30be163fa1fb8204b38de20a4123c4116320fda031c55e794cd3f5b152f8bf3a7f5c5f86f780ee7831297e12784a5d4eef51526f7abf914cfd49a7ec979980bb091a0255cb85d2effd481a44c528aaaa52bd23ebb5d6ac39a1d4c71b250a80fac27b8064f58329b96e659bf061cd051c4e1a6b45b2caaafda172f11147212c327cde9edfa50e3c374dbb38a24b7f9d45b6411a5a6f0b7285b3771866d4980d94ca9f4a7707396be78c5769a21bb13aa9e006cc1ac61a9d5c350acd266db0d7a831e77b0619dfc462c1a206806ac157a3a7b40a1a0fadaef1a3ad33a0453987d4feec6e984c1fd3dca283223c302df86604930b1fb064fae69c1a55284bcc27190c91ec17862843bc76ee489de17b2b702000646b04265bf20f52303ac987b863615852a891e84d9f8e5e482d949868a33a0285b2c6f58815db698198fe3cfa757dc9e57c0d08df8b1b9f24291766e744fc793a71018cbf4a54d804553bce8f0682bc16559c2c46a98fcbbc8f85300cb3bc956f38a8a0d2171b2913253ccab4609b608f7a24ccbd27a7f40dd529c8affe605f400a647acd79a058602a4a49cdd3366010f699fd121932334d15e6b425321423258377df838ff68b5e09295a4580047fec1554d7f181d8ea6b8136a5b2945f178d2d0cd8e090d6ae3267ea7a1690a1a8d8da765af9a80b950172d6bed6ec1024116782998f3d18e3710fc6bb24640427a8cb1f0c57c4493e931b97868d5491e074758d7bc44910136e5c2c63f222020e11875d70494a9fd250fe6b402b28262cbc6c0bf5fe21c3f739bd592696146958cf14e4f78c9e7a4b8646985617ef7b800128884e18fd56ad3a115d5678b8613c20969965c5a737644450d24c43edf4d147c09364b4ede1f3fcc7fd5c00995692ff34e18a5313a362e19009dee0d02b72d124ea69a935da2c4958e4cb4b8807621f6e7284de00d40caba31d092ed3c922a3b3c95424d81644a1d991188914aa072e353f88cb16e246999fe34b21747d06567d85db502597422852d88d24b784239c567b73762311f491107ac644c18284a5233e589dd9dae7cc8050c279379a2c848272b59ec697a7701163c3fea96962af5ec6945b8ccae670be43f2196e6f37ac697456cc11d74434d45be88e27bf0e3823540065b12422961c6ede161b21a11bc9608278cf1aef95e2b727ba03536d725de881e4d6add0c644b3c1581f1c73e086f94010df42f09db42d54de6754a2685d3942e1b8724512dace863442b4e9012ea04d079d130edf63f864612cb47f38bc4c6621d28f18e59285920d61db4959df9e7863dd98cc74754526521caff84f64e64054aadc23fb58829b915ad154a3595f0c5a6c76aaa9c2a1c0cbbba8ee0627b92243c61ee86d89b83f9472b141cd48b4bdb1162e2eb667c412f58661b3828e2352cf63b9d64bef3c7808383d1c4d93bf0319ef5c3c1bace284d16ff1e22639a4a2450e216a0062df32eaced32345fced1c023f556852c741baacf88af3b963e2f6abeb898a2bcda654a85ccc1e2bde57de586f3d42ad7f056e08710f4a48cccd4294c13c2232b1e9b196c1ab0983a66aea8266f0dac0a72965221385c9d5ffe8dff284b0a76203ecdd6a7c60bfc98ad7843f28ad8e0fd6ea849978d08fe51173933c8b55a28c439d2ef14477f07f522899019ef0d514d3544fbba802a92c958ad069bf25524b006056c3fb6afcd4cf3fa1a62b4aea7521fae7b15cc6ff9ceea9f3e9d7b9c346b046ff6b822294b99eca05a4fadf9e6c5e4b1ca7743c0825e7596d68790e13fe0e1e0f6deb26ceeaaa8f78829f69c301dfe0091d2aa0cf4b7e1dc2b180e2a362f0632c4225ce757ed128b611e86456609a0ce8e62fbff61dc432da03658719a6f8b1737c875cbc5cb6ffb18a09cd4b09debe943667077437467e790f6abe3001c08d230dc88abd1a7b44ae3018ad361543630c3afe1659800bb298a43cb3aeb0782673f11db6308be4c196ae5eee5b8ca644ddc0002195aa684e9ef72444578c1c52ab6f6068e82ade1e163f9e5383c331bfa64e0fe1631fe86932fa143e766609f1529dcf0aa131a5d5515fbf28e9575e2fa5615de98c073a5262a79640333727ba1a12fb1108b1889a87562685562c6b723af8666173057a6f185d232895f2bb10f2f4b01553f9e9e1eae9fa186ef0f7709f0fc10d79703ec34a756b52a9beaa115b0aa35053b1006e7f5e5c4d81cb6e1cf36285193f53b3b7718f13d05745b64ffb4df309d996202a21640192bc2b77ab7070003154e7c4615561614a20274413942dce59eb98402f0e059c095531be83b5b79e003f32c77c50151ff221614cfd2680e04c0f165ecc78ccdf94b009878281cd87812e2bb4fda6f01206d2cb322829d3ad0e0bede4fd65ee7d8ced2f2d8d61f53d9a8f5b76289dd35fae96b0dedb94994dcecdae14664d01f35a2be6eb756306a20ebf664470de030aa5fbc8f3a418578a834d042152ba92a989804ddf4f39374d7e49f155be42de76c58df45fba56a08702cbafed3bda1e8d3c74df3b4e670f5b59f6b7595532f853dc49e1acc68e3e1ce0838f7e9d2ad636522e4e20e25738cf22433ecb0ac66052161538a40619ca2e308f1226eef1579db14435b529bb094a2f4035984930f58a8deb4630417d0bdb8da65bfa16f285d20d170b28bbbb02d575c2f935661489c776f7df4eaa692506d905090e6124228742c67d84feca3bd91901a0218b0fc25bfc80e903f65a8c41f535bcb1818b6c84cd809e41b65a93310249541961e904610158d3d476707de15379312918b66d0cbe52ee991a07545230536c9a63b414b590322a0b008920a95743f4948b1b3ca93196b45e4851c28582c26dc629f2e06f93113d915b8a8d1e453d9e62f8dd246693de7343552805178c49cf95a441f414c3e697e57bf7e50b223a26c26890de50cbca3110c621db336353fc1aa912af98c2d43cdfefa0cb4c92f17cf2596b3c91033571858a912634d9c098df10da303cd544985ebfab9b2e5e37e50d3dc3bb75587263f8d2de1241ce7176780c031a7e33ca136a3af35864a27325abce94d9c6d0cf36b9144d5e4c3253e7084e71820580270d387861f0fed0fc68bd40c5414721944a0eea85705c7a61724ac556aa74a4b2d829531989789b0f9e490ea78f57186b4ff963647d1dcc20e99ca69ea1682ece0e7bc81c891f8721700f9c939b2c97a3d97eceea92a2108002dfe8193d3005411f3a456601ad5c131fc57242bc5ce202bccb722541d1176187eb4ffb066760fcc44a65f4da3f4a4ca6b827479cae9ce2a99711692c9f24e057ce58c205e214583d2b77a06d3d0ebc87776a5766b2a5984604dcda681df700d1dd9cfb3652c57492b5c995a5e64708a83b144c2b1fad5f1e6302e78411a081fc4886b2391630622c28d7989dfc25b39bd5e4f31205959060d87f713389d91df394580dbd7f8ff88200f9b04fa57ec9a0c093b4cf780a3c9333355946c06167bc0baf12383133022f5542fd607c12777106d25248c71fd98f86853c45ed41a129ff3cf849d6dc2d6c9c09230e7e8d4a65aa992e1ede6167c16223c679268c70b1a29133e69b64c865eacf8d89b91472f5c773df3cf4366f8ddb19de1a1796e228512623db28c67a1933d00eb2c9d766156181a9be015936d71596803bd1d6a23238c10782e82fe926f0e1b18bf57f0053240db26954d0dcb53c3d97a0e1478a8978cf878e23dc4bc7565285f857e810d1d0430bc12d8a8b450feb92d4a4171261de3c4d9beaaf06e91ea5f4effb6a4d6c48fb6d04bd9cac12ce45489d780a42f84fcc82f5e18acc786039556ba10b6b4559fa3636b8a8b08b1e48a849e304eb5189c14dc54d79e2e399a96254a5ee4f1a74c6245290180a2795ed9b178752f44fd41b686f7fe1d1d7e51e455e29ef00778d3d18126b405f8f826f02acbe87b6b3029c71f43407fb59c25c1c50c5ea0b02538fc0bfacc56438f9060809c64bc5bebde1d478a2fea8af7436d1e0ba0940387814516700d54408ec0dbc348f701e990b4ebc8362a0a802287a0f3e750932b831d1d72b6437a54907d1124920c7f0ac1822faf1d1e5c3d836ddbec86f4cd04dce3affa32fa6ff9f48e0f58e021f606870c248f80a0d5dbedf10395fddb5cbd43d94d126ff52fa5eeb0641de4a34dad9ae85224021b8f3f7a3b3fcac9d5e3a4f7472a01c888f006a949b3ad1165cafe1906ac8bc720e6511b2aac651a14b1e54de8fbf623b9a3a4e24dc22fb20fa8b89c21bcbe1d2dfec81bd174b382e0ceb6d4537ba1d199710bc31962d0c50ea4bc55c56cefa622ed60f0d498762ab55620c730cb5020522ed75e9524dbe068fec051997d8811619b051c7697302e7bca555c263108c22af6e467687e552c73406a6036ad1cce7f1b4b688998b2a8e38569ed58a5f9062942110804c994e0c380b5a67e30081a046fe869fe797497188357f803c58e106b728758740fa4b470951245495607500bf35370cb731efbcf9a400f78839627133660ff268a83ae5e4c8f428d3017d0b774f8dcba9c7d5c66df6186bc74807094141181001d3a20d8c1419fb2c15eb0c423432593f71400c7bae51b0bb1ec653ac7eb46400894c7b82102416024d1915603a210b20a0b40118f66518ea0d36f81fac7aed1388dbe323660bfa3e4f3f14908ba03b1777af54db3d6b3d84bea0f1bc8be258ac74f6a01f1a4667ec5a559c1eb14755cb1e29a88d5bb47949661a6d65ef53c9e5d5d08874a20fa3b7e3bf5896f345eb07407edb897042097defc2238df9b69702a681890b230f3d7478f646dc469253e3ca68ec8bcf3a3b2c48bb111263899bbaad70f1fb43cdc36abd8d47d4fc60f60d8d73a1eb3dd5e6a3444fbe478bf7bda6851277859df7156953d307950c689815a94afa81e4ce80aeb7d087e528def825cb6bdd161c449e363469e463f594c0f4e9532d8fe1cfa2be95f5437585f2389571e3eace91b4bc54510f219a62dcef7ab1c80cbc37481c65dc5567b0167fb845907b6ce2d2b568dbc6d65a0ae423dfefb5c6cb8203aafc8b24c0118a5f5f3422ca56edd401c80b5dd5f52cb5c2db934553bbc030487e505591ebbbba09e63ef44cc30e1a1c00a7d2413944d6757e65a9f80e7ab35a0f318aeca4422fa94c693178c699fd6dcb780f2a0e1ae748e5603818f8e4aa51a035bfef2b40c7b879438b4898f8ee4e5c983f03bef38d4cbfba0023a0f81bd97a1563ffccd6b4d789d2bd3455a2b5070e3b3fb82d7a422592a49ebbe797e89cf48530dadc042728fb526e4d0789b63a46e24baefd21f4ec05352d344294670db95e4d3579fad6ae2029cba7d623e98a1568e038c408d3ad7ac35f71c8ff1951ed5bcd6f440b91d22a60d2ab6d61ea6d2741d303aba522177634d55845d1040bbf4a045c202c524f4b82d7dca4435be227e3522f0c3de3036daf8a0c7b3c10098e4ce72813b694ac1d82c999766661b0705b7620888f50bc04585ec7c788ed84745465b49c24d0868a92f7877d230aaa3e86080a83fe327625e44c91c86971e4c06392331f582af781f3a6ed60e9aaee3c5b2c598b10141376abe443f0b98840289b83bfac632bd1269638f04ee9c18be271cc101c904b748735ef01685c64febd4dd6c424d908571ff7ec632ce067adff03b2e6bc85abb563ef3f88948ed29f49878dd2065db337fc427fe82648cceae43006c20cfe501fb2ecbe0265b4a27050c28758da09303eb31c7775e03b3c917f386f2ee5fd1a8e4e523c7575efd57562f7fc91bb42e6de90525b25ae10d4f66434aa35016ace5d1e3d4bfea297ac712c137d58df24c064f4f4fd0fb89006b2bca0382595f00d3177348ca96063279f2f96323e476d462d8f6d6245fa4adb526573f15302a06f73cd06edde012a8343dd60bd8ed0b18215b01514fc6162649526bf210e5c0c07274ccaa09c409947c4e6ad5b21a58ba2d82b219141d6956d2d0998f7589110b7095a1ee98a661976308c698549ed0391ed5864504113b7d03e4af039c37dd9b345d44c0f8f55bc5ce30490cc99b6f348d60c2096c7bc41978424ed9eec6e04a552e6432fb9fc5d1f6a2a723d065a07d8f3a22b2b87902394f0e72856f121973862b84e09e5ffc8d144f06dda8d6800272872bc40fa52b7f45d8332c036c210ac90e0ddab8fd69d276854f1e08e5b2440638cf1f319343e94460c8a0d3f066cc5a5f616a8f29403d65628496fd5aa7d4b6aeacce5638805575d2c1ab3188dd025171ae724783c4a67acdeb5a512573d16cbcb8e71be2547a88b9c908bb56e1eee49b0776e7c83871a230b678a0566c8879a3b8e2f0d54d6ee975102b5a233fca0416cf2203f57fd39b155490d5da08136e2904a48a17e5d7bbaeb920693c8951dae8243e247838a02ceea030fd5c342aa3081199daf0ca7c66bd19bf988e8125a5febbe1667a541e636c3cca98e4f0419b6305cd33c1a0fdf57a3163288eb5a268df812699f307df7dc34f4d6bb19af15f12441f072ab787556125437f8f54a8a1593e3171918f118c282aac0544c14b8644077761b2c1803fad4cf55921af2bfc09b64aa68564a697bbc451157d8ff9945ddd3961ba33fdcbf8730d593d3bf12b5ff2482b2a6356a3e66837566513f94620df6df83b8e6a3cde5868e4ecd0907119d94c758bc31b5555c52febbfe52446cb5d81abefee5be768fdf06ebd29aa08f7a83e888609d5da6d68058ccf134002707ba55880a39d997bab2ae4fffdbf19af93a1e9bb0ed94894afcd82026c3a90ab585d1a42f2a83b4475e10b9c71bf95d25d6ffc3b45ed67d4cc06d98c46fb851c99edb1f9e8499cfff5f0a099128d5670d1401e09a1261cc4909c1a41e42058d932575d919cc4824f514346161c539bd2a4713ec4271dfb8d6c91c2d5aa68ee196c48c35f6f00f30a242a876a63788f34f0d1899ba153dbb008a6606476e5c5361e04af82b72fc9c7a91ab176e41297df74c430008ca31b9771b71f57c55f5488c98100dde41f331c9ae96d65915661b3d0ec66f64d37153079feae26e338aca23a8364307160b4995276424513d54152457f304a7153afa5166b905c5372c31570deb93258066f3ca6e19030bb0595f5e9efb9cec5b7492ea35e466a0cf6932e3773fbd6fbb726d41e03b5abdd4d316dde0d957526c25076ed3dcf4d4bbe46a5f4f51cd69f7f611bd55282f28ab686a00558dd1547a9572815f43fbea4069372d7c81a827b6addb58950a3a9f5b0910a3013f12059ace286e2f748277e210a7e5c263d9550eac8142bdd2236532ee98c9fd906f645ad702904304fd098f2e946e5635168288433b67c4146036ff8799b6e77cc976f450cb25fce5d222ff43fc4b8352adf5a556e55b2cc4d7edf70e2eb5b1344261bb0c9f0349ef4c95a65a9d07ce78695a7f743b4c3bd3c5693065a06a328d024b7a576f25a472b466a03b6f70bc752ed3084e1b4888ea1809490389195c4409491959e28c2530ec03faf9351ced90a274794ebced79d5ab3cdbe05bd0d558d9b2f0d8157218b255fcf2536ded0d23ade7095032125284299f0ed457b3b24d85eb4b74b7d1c05a2d2f437e0091b74139ec9aa70cc95f2c174fa7045bc0dd23e2f01067ea5a3bb0ea9f06ff54fe3b16c6ad7460edd2dc036ff4979e70131026888a21e8487fbd71c941829e9c946f11f36b297e45553143f906819873ed87c688cc15063c5998362acf6e4e571273de94324e6ad377f6ae8f78c51e52737d747c6ec939db9add10994895675f551b98617cc3ca03e32515c6c41d9be2d70a8a136940e1304e453a667a195626bafa44c4f72fbae630b7a9e104b02b494c80fd13c77a9c645ccbc32074a0c17a2cec00e036895e695f0df4b4a143a4e333ddcf2df2e1ba6eea42686ecbd59c9692cafac90d8dc87a0833704869067eb718fe5f8ba337d73391b6e89f9ea4d7ee4394761832933d0b10078a10e789c26fa0653048aacb0d13d19364f05e48f08997991561ced540f5fb9b0b5a7b442f7baf0905256bd6f402a08af36b5ff1f3cf6f33017541ed31e65566e3cfdfd18cb4f771fdb87b01b3caece268a540790a8f91fba7e6483a0f62f77f827efd4c32b45aa07db5df7102247861c3b6beda37b4a429329edd1b5a4d238604f81f1ade40c146b71a48e1b69ad1c2be781548949a7ecbb3d046e3d9edb9a08af5b07cb26613a01ac983e565e4f50d354687fa57d713ffe4f52b78b31131c503acce0401fa467e566b57fad81347a7bfd0d704898764846781064416c4c02aee04f246af232f92e4d1647025aa5b1f9a4f2c9eed8e942bb6d2b3fd0f03833f088f0c95d37a6a92c4d59362db3b89e73d13d149e51f5ee3bed5a3906695ff821abb4a44c2164759187652e88e3eaa0915a18a6f65b05ab92ad6ae6f9738d467bd8546eae7780a3f66a5a0dc4e2d078bb330309b44dbe7640967b7f8a5ca6b90955bbf1bf07a1208ba7276e7c0a332e82041b1c20d631398dd2944f1dbe9e6cd53ed0522e0666c81a3e71cca1455a7b016d80773403d8cb73fdfc92fe54eed4374f4e67717587e204640078a5f30672760ac74c22c52dd150523ccd919dde6c1ebddec889cf8da2d0290029a3f8999d805ace4910ca52eeccf83338c4a56d2d108d74a680510ae84cd7efe5c7c6cfaa3e3a696fc4ca54149bac4984081aa4a04515f97d989db8f19ef84cab43f534eb26ba378f6fcedf093295a78f36aa8d2e3eb479512210691653ab6cd65a96e6d0b1258f74960981b6ed8c18628743d908ad913c4a3bc039cd730257f9b815688c4b81ab705e73a7d500ee994aa26e13430ebb0a118a62c61374553c0c9298b1142b3606fefe772a2c11e248de299e5ea69063cc2f55c704b81f6e49be0a6fd9940a4e0eea40fe3f4e1564296d2a95053a8b2f636795f5588eacd6f56c1f8631c63155bd0291e87503167b01d621e04e74f3040e6b00dc598f649a81ba4e72c222b135898320e4289d2e455e6bb3697a6de5a70376a0137a89646eb535aff3005c860f57e3256796ef41ee5f8ebfdca892c9fb3d79659e15a3529874a84ec4dba6906dd4291db8bf0554cd2bda4a65947601799abd6cb86b49ca12d21a4d721800893ee33ebc219b8ebd72554a8c60927046b196146a08463e7aa092c22573c508861d04241ab99cd645563ac4594e54f8e7c47acc52a08dc0c9f88e63a68740ea842d1bd0a9226c5d58deb42523e0924e61c295f2113028b6038a5d23ca9736a430fb1a787da5d41b27a652a37d7ef21d91a81f483fedee375e0c6197c80abbe368bb932ece9560633fca7655b200189a2db0c579993c3e218dd9eb58d6666f5f011c178b895dcf90a110604599fab3fd37479d4f653464540f0ab94bccc3d8cef708aafa10244251880f415d8f4fa8f967a8fbd12036bfb70731cbf5b001564e579fdebe17cf380c7a44523205f3544f3b57cd96909487826f55568b1e36aab0b34e7820095b70178eba1a20e56cad599a200e7d65a841afd0f3c24f858fd41b975d6c4d43659ea3988adead39cc6b5295091c5fdefee727fe27380285eae24d9eecfb278fd1dff53771f38f36a0b41310cd540d032bc53b4263436d791112d7f8c0f11c66cb0e4fa1fe97501f2e5bde51b1c7bf5535f65e899efe41b8f7af143df0a3de0be547fec45967e475501544a03ba65b27e5d300e429b0efa036e77df824a9d1539bbd03bd9e1833f4cebefa7efa09d5d9aee366ec6ed62fa1e606b08073b02c1cc181de703aaa0e3993e3c5ea31b9ac002d04b0383204aa1104c92b6ece51d45180c4544428dec6e5bee2da54c32051208ca07b807427411f3847f32fd2e9373a45418d38312eee6f829c7e62b079fc741b9b8b9e58819cf8b2d802811b545191fb2bf6824fbbf14cec97d1ae003091d9e3154284106082d9064ffd7428becdfd158f0313664bf214c5da10ad2c38b122f7890284d4c21a68a224e4cf09870c149cb09407532a57f79c8f4b19885959829f263812597321d9eac2bb2ffc56296b2bff834291e62010455560cf80b905f914be28a26b23f16b178a19543dbafeff4d659bfdab0ce2abadba1e880675fd54b43a0fe4e3a46605a471c0d952bb9838cd3ba93026c0c685f9d09c3ad0d617e69a7fd7b9f9cd1e8febda7760cc12c33e4b616a007d000681a8caef9370c7f9b3fddf1763e3739fbdcbd15c0ebfbeffc8c289b2777cfd7eaae07c270f872c568f2cc835ebbdb0abdf0ba64e4fc753960e69af75c07b91b69a19aae81217f3c1d047e3fedc58c0e0a61f8fb717450ecfb4120c2ccf74f21fe43e33fb2ef9f503aa8e6fba793ffe07cff94e23f39df75c79ca2b50935a772ff8cd242d3cae6cba982dcefb9b64d275af3be92446bfe77c9bd7f0669a10905ca0ab61cb4e6ef81169a42260c2a727f91db6cd09affdd42a385449830fcc3b0a01c40ee0f400b154d181e63c2f08f917b5acdab1c9c29ab39a76437a40d597a0d39afa613b5cdabaef9bdd38903cf3548643433098ae392fced8ceb95630af1ac2924fbd71886d910e145969e731c0dbd0b540404e4606b9c619ce6ff7996d77cbaa061f85fb2f45c762a6274b923e79592d9d35149ee6fb3d7c9822796d77c925430bdcaee2553d2078ce3f80520ad75773bf5143441e13d514a001116580509020731591039019515989a3c91830d62604f72d8ab6aea629baca846e89324fb824a8900b9d0440b4348253d81a4015f8058811432300879c20a0b7c685d799284c75b220acc0bad9bdc51604a78024baacaeab6f020a80a3c3186cfeb8897a7045a1224fbdf2a57eea82a765c81607750672bedee76ef75c44beb05adee8a932e1d3502e4c2d5c0c9103d8ca8410726c6dc4abc456b91e2f104114134f143099adc515fb480507ee6b9ee9913e9aaa14a9efb0029707f8e82e797934c6eca4327e05d32e8acd3dac9801c90a8010b10b92e526ea5fd49da5bbd7abf5efbd7cbf7eb104dfbbe04d1b4ce1f59deff1ebc63f8bdd7419767ad1fd659dd364b58b66f355db3d60fa6701d0f506bf5a1f2e99efa78b6cf4f079c210db078001f73e779df3f959cd10f95e0f28c462d4325b85c5f47f63c8c2fe97943de8df8083c1f893ef164614d0eb80c75b4fc802dcf6b7fcaed913a42e03294d90fb3950dd1eb55afce993ff5cf68941f59ce96725f8f14812c776445a187689bd8358765a7cafeb3eecfd2eb96c9327550530765f11f8f6a8b7de23687ecb607fb43aea2f5ace7799e1d2d936dfa814bb1ceeb5d919ed50272b81f74729a4b719a5b2bd91fd4d10102bfe834cf8bffc4dedfb3e2b63bf3a51795fdad9395e23fb0f7b74ffe83dfdf5ae920ab0efadebff3d141adf7ef9a3a087cff2e4b07657590ebfdbd221df47a7fefc932d9266a93bdbf67e53f5ee95d7958526d732b2b2d586cc914473d236da3485e1224af09921705c99322a66dd4494bdb689593478293c7c3c90be2e4257169810b685598ecdf3d695bcd753fda3625fe807bc8e57059c04692641b45db2a15b557da6673221653a9be5c29ac253b97ecde3f33e9ccd84ef38f8d9ec569ee53fc4a1416d91d8ad7fca5e0bc0989dafc07921b414a82c404c97d3851db8ca26bfef30b759a62a89393409d3c479db2bf6b9c56dde31f8ed38a52f7cc2b39eaef65878ba825bb54f6f9947b5273fefeadd1a87bfca86b54d45681aef9cf223b2c883ff034a189891b0516b32a950da7a2bd88d13da2c5515b069d65472abbc55db1b80564c78d9d615e5f1ccdd8b7eea09a5d8a65e2b41fd8369196c969fe4242705999b25fa598df500182d77f6ce77963ff0e2d7b5d676dad955a6b2d796d15458cad25dd29f53abdbaad5dcf24a5ef564772ebee39ee74274bfbdd83b6bb416bdd5dade016b0ebbaeedec83171f87b46db6e03f9886f837a016d068e7964869744897964899f24349409637c84321b689afd19d47603c7c4556551e5b2a7bcab49c208653a4abbd72541f02c51d76c95d26b1cea9aad533e20d050a6ffd17c881acbf3cf8a1b5158442dd18454172b82001384140c497278a2a44372058fd7054aa5fee2bb20ea88f6853b355425be08156e99baf9aaede8ed3ca013beec709df8122597f816f1057f51c262112cc3b9c953047f49ca791e491365f8cb8f2d7215b9a44d7965c02a58527c69c2c46b0c16d50d585162b0a06cc0e2a13382e5e4e6b08cb482c062ee282c135a62f0d5e22505f6aeb861a8f8e24485151228c02da08209ac1ac87b432c5b62c7093b509a46304130b061eabd0071d14469470b109d199c3090cacd98aa5c74a9d223a7062a1d1d78e0cc4035bbe104d189524e0d26dcd8908593b359e2247659ea51d304eba64b919cecc9934d1721391a2758355d78a0307303966c0b14623624d170c1e204bca46a868b0b7ac068887171a2c78b4915e672840f570d48b0ebc3050b5278f10d3115ad3597293db0b8e0700214171b766cd0a4c405861536a8a1890bd2064c9cb8900084690b9814368092b5658adc0637246d59c2c70cb82d46f0d88006ac2d3ffc88a2b4e589c70633645d2cfe0190c0626872822dbe8045e097133314e1215d09956002e507264b2f2a98b4e05a8249aea505b6a9c2e5035f293a1db08b4b2b08068988c25d54280476adc09b01d71da0c01e94242732d030030c08a6b9a36850726b03515195bd49055e602fd787b9f5dda0b17be6c378fca75a6be7acf63b6b2b75f7ff0f54406c56502562095233e5460548b22a483634f8a07952aab1c20521333c30c9ace8f123b683134d9816f014ab99238cc0ac28c584c8bdaa3ce11f50e0a29283ed9042c8c314ad75981982288531f2434695aa30417c842101a9872a3060529802e305880c2a5449c890320566aa8715181f7a5081e121276307243038c8787a02b3a4828c1e9e68566e8b09a624ec1558963b8ac9874b05dfe48e6272420593521026a4561218078b9614d886894e0a5f24421a704b085b056e5d7181872f0a254f5e5d702c779412a51f4a5ab84694e4a02821a105059826199af8a2c89085870c514464783241861b2290cb3559c16ae209b3fec2a7ab3e3cb4179d7d01ba5fcfddfebbcf08d3615240ffbf3edef6af3b095a24ccf0c809420e21c011042c097a62e3bd6a2e4cf6e1b03ee872c9a8ad5a3b5be9abfbebe280e68e9cdd33ad0bdca04eda419e25f49ffb75c77a248acdda35c60b1e6c2dad352e0250e322003da258d32e64b29a49efed6ae3125dd4b8ae0fd0930fcd341f6a33f5a14094d22b74eba42f5ed4fa003411c40100d9130023d1d8b4a6c18bf9b4cfc275d230ecd89735667918efd4cf5b8c42948a6a96d3faf9534cdb2612fed36a3231a3985fa83a08d4d242348b661d11a56d9e9bd2575a2acfef490bd5a4a41bf2fc19a46dce34e4482fc9f3470b55a7ea04c4e650b22fdb8ab2b5b0998fa383eecfef400bdd3bad7a883c633fa383eccf97d1423e0d034b9ef8cb05e499419e3d369a03409e3fb6508e868133e7ccf144ef933b642952cf798e2cefad354914999c49146ba853f6979150d96b9215ad49d96916a5a25bda4673b9acecffca512a264a4599a8982894976c2bcd3990c8f499c0459129fd994dd036ca444bd84299a8bed156fa8d9e7da24c01824a809013944ac523d320554332f59cadf4823453c844ea1e7a475be9d4757281154f5a404ddd1daa60e1e81efa9ead3589fe104a4830d52622154947cd186da59e6916eda9b80c6a6e0115a91b534ba0f174a534a4a2ff55c5ac70b094689c13b71c2e2719a8ecb830279b483d936c39bc5627cdd1648c729020c72461f298416ad7c86cea3b51143c2f26cda7f2e449daee6bd95a2b75f7390588e78439e5b1fdb5d63a5db5d65a2bada10529ed68cbfb6e15ef576907dab0d6faeaeea69452da14003d9d56db79f76be1af05c2c0f055df35672db2e1344a7a4dbfd8104824c4ffbf60200cb770ec8bcddcb753756a8a86a8a78888bab75f9fa8f5b652598dadb1a9b4ffffffb7b9a1b4ffb795da4a6f44a76fbf3eb555c411ffff1f2787870b38c34ace684c1dd9dd893a1df9dd5d9479f8d61be3052dc60b1a4834494a69e8ca610e5b3974d1e8a7397e1974c9ba3bbc2f180e6777e33bdb4a264550c95a4e990c63a99932a7a194866138838019f0dc2056715b0a7b7557d7f7d1c256d36fdab5d240b0756d77475ad2a52304fe6e5fbc843d588729a535596e2d6b372985db431d2d78fec44bb5b175b108d8ddedb6f3c2af05ba4afb330ea8e7266795dc54f2ccf37d4b16a2170cc76668cad23da463d7bdb55df7b613ad95e1d80c8dacc66666c6bea89526ea38adacd9ad8d51ab7d512b4d56637323e2c4c8ddfda26bfd585904a72491cc5a1bd6ae76b728cb09bbd6b0ce469d5b83738313e2cc6633317c69ad6bb5d6ce421d52449df271b415978c7e9f3a5278fec420a48fc726c94c6b64363e8f84d7d1d0a54b922e5dba74e91203966aadb5f6c3d284e5de4ec8ed8a209913c9f5baaebb4590cc89a4bb5dba8ba4bb5dba8b644e24b36bad778dadef586e7d60c74523966fab3591542c3453b2624182650a4b97ad9dc232e7a8050b00b8d4cc39e7443280acd677afbd4fe37eadf75b2dcf2df5c65a6b6bac4d1bc34b6d5867ba4eeec04e002ffb9e14b0bf9c59e5c42aa7150613d7fc7cdf4166ce39e79c73ce39e79c363f737ece7e624d71e24ccfdd7c395590e73b8fa6a21a92a7d3749a4e33cbcc323fc79cef8139bf68cef692e7d3982cc8f3dbc76d360690e707a0854498610b15cd2cd3870fec3eb0fb68b2fceeeeeeee86e1f0e58ad1c866726636efb91cd0651792333a5292e7a690ffc0c1721f37a4e76c26951ba9a901e2421cc9699e9465fa3361a72c332e244ff21f3117e234f724ffc194150a71244ff21fed3e5c88237992ff6002027220dde3df4a76765e4709dcbf333a92fb3801d3ef2fdd4737b9704ce54d9dd722b2e18292795fdb621f037fa9415be986d5e90ea014b45429d70cbac2970dacc6284716968900022cac79f5b992386ebc5e2e19dd77541728b2d145e47e0f883a883e955c6b8a4cac30208d2c1673c9e86aa6d77d503e73eaddcad05fd342734976ef9c5747aa9d3264ffb006b4b1373737a24b145d32ea8b132cf33910b712c36dd37e0184a6d284b1d4e928c1c4694c4ef399a461f83f61a7a9a47bfc5f389d33affa35763730277c8df606cec2d7586fa04ef81ae90d7411be46bf8118842fd7bd3b2e1ad8ee78afee9efbaf9be39271bd0e6a896acac266e1a53f5ec0692e1b3aede20a5f5d5d51ec02030fc8c76706069d51ddf95054828578e134da8f2498fb43a1e61239058773e992fead9304a6362e195429d34621fbd5d5bc6a2ada16beff84a2b6909c4b404ec8ee138becbee473096a090a6ac91fe4b9b1b1f1a696d39a1031c6f4a9a38413e748390d54883df182c295034e1548c4ee93d40924e4d8bf140a88f0ae84d9014d80ca60182cfb7620a9b97a7fafb257c215a913ac20f64869e20422301629127a9835048e24774e43ee6ed00b4ca1a905063a6896e99eee630f23cb9e1759d242b27c19598aded190e5edbe66bc31439661990ecaa5e3a6162de424348ceebbee6364d983bb8791258d49eefe4596df4bb9fbb0c3568eeb9e1bb3000e55defbd71bf68f7deff3c69971bcbbee7b63cd8d13bb7fb3f737701688a2d43ff53defed2d69be646d9ad74df32e089cd6dd705af75198662edb2a77ef3b9c565ed273a4e39cd6cd72e9b8dc79dfd1261c0e47e4d609e95a17e95a045258ea5a0452a0a1699dcb9beccdf21c83a77fc58271e907879cf6310b4041725ae71266995b93f9363715540d39e63d2c3715140cb9fb21f7468f59004a1215d40a798e9f8b03cf1d49c3039713f774ebcead81fba83db46d2675ad3b08832711093c44d20fb97f1269db05bcd67f91601a6ed8b243eebfc06d072e35c86d8024a20e160d8004f7779ed19cd60dab42cb50b80802d923c9d812769c498db16652bf8f3e319cd6fdfd93aa7f3ed109552f18b0793aefbad94d97f251245b27b2fd17d6dd3d0afbcf59f7ed257bae08ac282180a8d2e376f3a48520767cc1e91075b3ef631fc8bef7b02af667d8f701e2b1364a87c0ebbeda5a3ef466eb2cbaef7d258b6648d4a2e137f835ba0fc9a3efbb07c9a32645df77df7d7fef7d7fe4fdbdef7d8defbb3aab0fbe8e9b377adf7dd177dd83a4d1f7dd1bddf75e47eb877cceee6f6d8d776c8ba37be65b1574d57feaa51d049a7653304eeda0aeb3d1e85a77e38698813aa8f3f775ecfc7ddf8baeef234b1c2038edc6115cdf01d548c70d6cfd9cd13d4030fdb2fde74fd7cc83f0c1af1192e0d7206abd519322f0c33732ea8c7254c87a925485bb8522ad91462e1288d6baafe515022469b4d6fd074e5ae4d37237c333e85e015f7037a3f4fe7ef7dff77d9f77ef7b97a7abee5509bd044cc1621641cde553bd97afd3bccf200bfcbdebefcf668def5de48ca845cee6f77d8d5651eb33eac09120c8b880c3ddbecf7eeb8fbaafd17ad7bbc823fbaf57eb5d7ff4fdeb6bb85ae48ce8fbc8d96cb55ae46c92b31aadffc0ff6a7ce07fdf3757dfe80ff9f4c096d5ab6fdfd840b4e655c1b388d3bc9fe41472c972e6e9f5115556c002882d5a897fdfaa08c28d57ea64009b07f6025d2e1036ba4823fcb0377abdebc1f97ab917e97cf84ebe5e2f231df875bcbe88e635f398348afdcc1b854f43ab1dc662b13fd2f9f0fbf61afb06d2d7b7cec3bec6cdbf6e1e76f347e1ebe87cf8356e3ef643fe7a1d380ffb39c922f15fa4d1cd8b6fa4f338afe35602b974dc60e1c3be287cd8fbc348a3264e16c5de451add7cec8d743e7c1d371f17cec3be86f82ef161e21fe93cce7beb8b6cdef545390f9bcd973dcde3af31f33212cffc5158d266df17c9fef5453544f62739a351dffb5ad4fd9daf23bb5cb09c87e53cec8f6cdef57d9b813ffbbee98c3330e767e411ec73fe86ccf923d7dbb4480f6cdef51fd890b396eb3fc821672d58cecdcde7dcd89038a40d3923bab1f9be89a40fadd98cb3d6cd386bcda77db39964d16c7ef79dc1d70b7f8c3caa795cf3f88f64ff0a651f7e0dd987b1f0f5b28ff440f6afff40f6fa0f6a482cfba150461af9903464d3909c11c57e56147edf663a98df3d188eb3effb3691661f49b403479bd49faaddca898b7907b6fe1842f7730401add1878d205028589a38a9bae4ac838e7ae4ac8310ec6dc6747c8e4b006fdc00c3db5601f4ed8bd692201cc1f6bbbe21482b1496fd90dff01ffb3de8b2b67bb0bd02b2b5d4521b234bf05bff170cc799877ab8e1cc089638fade90c2b75d12b8f34300c169b30ab419e70db4b1b9b1a1f91990dac828a2f999b7a47873f335622f9247b28ffd8dec637f44631393c55ef647334ff37d6bd7cc039a9ff91ab28fd98c7d937dec8d687ea6e6871c9c376f03d29bef9bb7b17f14fb99a218594434f343de376f431ed9fccdcf90474d8a6cfee6a76be641ec67be468cac7143da9097d662e3ccbecdebb8cd8c334bc6626f431a5da31952c7ad5d32886640d9789b4ca06fb1a719c1d8f8795e5aab2f1bb14e182578c4a4486b629e5d153a4c0a55378689ac2552f8c144cb94279084a89262880f4e619cf0a105aa6e045472480207323f28d9e2a8081cc26c3182a40a2b529688ce6b42071dae951d2cf096a2872ab825e8f4a2261622bca5c8828296ec7fc3dc5228f810e4698a73d27203dd0678b6ebbcc984d2b9347d74adbfa3fd1442f75e4775d5233bdbd9aed6279166bbeb7ee75e4f871d61fa17046c6abb4111728b2c815f4e2634cbdd82bd88571f86d6647c76f83cdd2f1baaadb5d65a6bbb3a99844d21598e30354216b0b3b5fb3a5bed7c5aee6ce46abdced63a6f3abe11dcbb17c0e62967cf22ddfd654f01f9f0a191797aea2cae84c5ec40583e56b4aaa712a7fa36161293d934c2d465926d16f00e0101f9f8d068ffa288f1d3f4916d9819227dba509ea82862fca4c3e9bbffa6d998b7e5614ea87e69adb5f6278c0641042ae2eb5d4f8742f1c6de15553bfe55f96104a553a4421c5a484cacc063c207efc812ef0a134e1ee8d1233d8a71226247151396965bd950210491022557500069b2c4adeca91f523d9c64ff5b25be28d54329bf724bf5502197e2d47d020cbec92dc5634cb84214511c31c50f1e0a78f0002ee151832b090f25251e29785df00c99100ae32bb0842e2115605e4bb02cb7540e885cce09a6027ee596cacd402447e4da80c1dc523924249d2d7ae0ac806916a68748c529078a1f37529070028e65edf791904c2340737deb44ad9375b24ed629bb5b255924fa6f912c9245cafe56a4f064afe28eaa6ae958488d95e93725bbca3af16ff5f530ad812da7b569fbeb56ab7eeeb556d269999a1cf0fc52273786795447083c6ba5d487804bd32523e727ce8b373635329a991886bdc0d60ff9e7e2875c4707836fd7926779863a688319fe137eff066ee098b90ec233934907d17cd7f88fecdbe6fb6716ff11ffe6fb67980ec2f99ee57c63f0fd5ec47f5c7cbf2bf98fcef7fb52073df9cf7fbf5bf1f1fb3d49dbbc496ec7517a3d471dc98a16dac00a16b619b4e6efa57f0ed1421b682f45e4fee9446d379ab4d0dcb1c3095e9a42260ab97ff2609ab87e1050db64e2400b4d2b1386bf1528f0162f5520905b687a99307c5a51172de43b260c1f9d89d79e74a61da60e3eef90e174dd9d1f3befecfc8ee77660b9c4b94a75cd5f4bae72c9fed58b3f06637531569db14239cd9f466db52ad525a7f96f3085aa910a03ce588b744fdde1357f1fd9ab104a66ac38a7f96f600a5131636c469ad53dfe37acacac28956ca45b764c21aaa561f81fb18366e91eff99914219a9136da2485488d3a814fa8426d19abf955cd40d4b4a9732511f8ee5576e65650ad11f1ec6a79729e451502074071419a829b2bf178f82729a934b71da9393e33836adf914dd3185fc4ac3f0f7c792fd7764af513088e0b25ed5ab1d9f1103e29fe1141ac10da2dfb0b75fe3f5953c6afdebedeb8f3e3cf60de38cf1dba0b6ef31fe0fe31ff29a0e18e3c7f8317e6c1f5b8cb1c5158738c4155b4ccefcebf70d933327671e846fbf06f8953caa0fbe258f9a14d507ffc862fcadb16f303aa8330ef1cc03fbe1d7a80ffe907fe40156c0ef554c86409fb07cfe1d78eba86638edfb0ca4c09d67443bee7b1fcb33777debbe951d977b47487e1f0190601836fce7fb22fff9fe73fdf720509bebbf9fe13fadff1e021fd2d7dfe7fa60a4116964df45ce4430f3c0f5e017bd5ec70dfca25925671fd8777d5157bffb4a1659fb3a6ee113b9fefb1e4607cdfcb5bef5add63783d6be0f47225afb1ec4553090d3be6f913e4efbbee6f9c810a692d5e129fca0f07c807c62008d71f25a3f7130068a8a6192247e74a12cc4322daabcd656583fe05754902453c228d8d5f48a0177b90cb7e09b5b2a0953765981bd5c86a10c8bc623c36118ca74a8844fde98ef85239d18acfb4210242b26c97b8104a4a62c1e1c88799a82832c9e5a80020eb2ac86743981032ca6b048c545e585c335b9a396fc60c5121d949628f170b8953b6a8991ebc392202e2c41217c6209ce076c7347318da19245db4a3baf3301cc6509b293ad01b03bc8ebba6dc51866c729664adddfddddddbba502e8d5565bedede8fda67f9fdada5defbdfbfed33fef349fffdf41170a087abfd3514aedefd84a7d7677df57a9e36e019d56b6d410b92c423706d7a3d6bd520b64a7d69d56fa7507b0afd7e5b169b5d2afdadc1584dd2ba92442fac98ab19858ab112c170c48f254a23273040a1adfe248381c2e8854925c383b6b032245724b96e8c18a162240238272c993c16fff0163645083235964f0c1bf314465f0b198820c3e92301904df67a9860c3ed05299fea15470b9d5b243e4ef3bd28252167b2bbf7c7fb6edc6a63c18aa80e189686bdd66db62b26cad4dc194112dc4992a19d50853009eb27b9de0045f785a0f5aec70ef4da1b97c44acf02254b21b8121bbc3c042d817df1007cdaef1bc90f5448e64ff7ea1065a1e722960cfd9e32467345cf4c0f6d6533871c41523929edac180f4c359d541bae8815b370a607182029327381cee86bbfbfd69fef80ae8fd673af479fe8512f353dbf4b7a30e170c7e7ba397330083fd65b20eea32757d68f30dc71bb9ecde3ef6c2ef1b7188f9fbdb51d1693406d50581c1ef03f434aa54a1c0eeb1b30d3ad44136772f4e20b7b50f482f352488a9215272d95b68a54958d9ad18921b02257b1293688709f64de87e88d61c28032bbe7c4f03904e60de3cb2843b04d4c305035916a88f5ef6c9d4a7831a4baef62905f20983e7fc1246a60fa383ba08cc6834a582cb4dd242a7ddb1cbb02af88766f8004dd710fd19f47de80351c706a882273502f49995e4fa451c0e877375a0410ec12cd3801c8259862c8fb2cbc0625f9f40d66287ae75eeae5da7cd1009f74f2a1008178a883a6122dd2b702cb7940b3b4441413d31adc0654aca8514f4e0804b13adf585f27282a90a1e71069ce7db0e1f41134d0cb3bbbb298d01a4f47602dad6bd9332a13c59a01488facc30a04f9eedee4059f01c53e496c11ec4bdd2934b1d168668e147a62fb640c4eb00cab85265e58671052d1492c415166090e11805b80c796852427e64ffea7e65321d394cc1c20229583061c8111832407db1c10a223e30b915895e0bb20f9992dddddd91c831aa4c260399d984c3e150989fffe031da4a2ebbec2c4066c0f20548165248558220657f9f2046647f201570d9a5540822bbd40a43b2df13a45c00429f8e0ee86c8028b8f4ee69cf17dc6f495895db41bf8eec7d809e66f5519ae683b57f3acff9de6833cf096016a7755453ddd355275aeb7ec62c1045860cb83a519bdfba9b224430f35487679e87735b0bd1b592ff50a914ac72d72e05e4853c134a01c9e599fc02f26af7ddcd3171fed30d119632cf4b2e75f09ce5e9e2a0861802444536ee08c2059ce638f7134ca10dcc0cb4ade6bb1288e6430bc952ec705e42dbe693a3903b5f21774e2477019e7fa8c4cc784539e910d50800000000b315002028100e08c4e160302c120abbdc3e14000e6c8a3c725a361a09a320876110c3300cc3004200400600620840c6394765006422a625a7c6457c6f019736a1372b464c01cd38efac9b1d689ddd406f6ce051923acd6ab96593ff91b998f9dd4cbac4d18fd5dc1839025370ee5597327b21955b0aea080e22e334fd5467f863fd6e942663a7bbba85fe8b3f6fcc922d9ddddf6cccc60951834aac8e8868a5237a19dae068e50a1cca9bce18538bb2b9f6c6d8af8d3c432654147b6106d4005261f011e13b1fc82c7aee6b164da386dedc6077a695f8938dcaca46b359281988d992a849098c74d131c38c678f5d612eedbec3a596161eac6fc301f2c556d1e66800f4a9107ad6471cb1ec3b8cb9a4fbaa867e7c47e0172a6787c54b655e099b0572d1dc9c669bc2e45be104c59b8a60cc22985d966da736f38ba6edccbf14486629ddbef33ed49d4dee626054a30ca4d112e37813221ba163e283a54e5243dcdd0ca822b88feab193fc18bc6115d1347962711c2ca4e9440b94067a09f3072553052d13b213a3040ce700abc1cc0aeabd1e353cb60102b47b1e25cdccf08ba16d8b65a0acc1ca14faab168280b004d1c3c204586e67360c7f4823f51611273832973228762b5badf539e2c5adb05ad53a3689be698d7cbb3e2144d11f53dcfed1b8914f18e5137f2ebddab97c3cf0db1f33f1a178ff8d1f36dc0cc3a24df56344756085c075bfa5cd822957c30bca6d0da2ea39284b1d4a5c76a6e6c2533010b1a920ab3d31266fa14e5842b8b376ba613aa69a8d0ee5f92645a4996562962e86e2810221ae2fb3b91d3ff26f92e28db534e47d6d5aa1cb2b893f86b435841e2fa78147685adb15c1af3aa42e919e9817472605c30a36b05c00ecf52293225ac26e411c29e1380cbae5819e96a337b8e3fb2c180a1b7ad08b874a5ef7b729f6e27496941b57024496b1bab019e23e22cc914bd8f2534a444aa5fb80867c46a3a7dd659c60fff189ba019f5cb205d01f26636f152db066fac79c9d8792140a8ddfeae56ce0edac4fb6a6ae0769db8758ccfdaeb1101a6edbe649ae4223d88374866f0a083675b1488ea48f5cbba249ff7851c1fd5606b738d7f05b90cd4d0f85e83b854a4a9c8d4305b3990b0d93cbfe406e72019d0eba204aa4c0e7d5e3d76e7f4cd83159e16b6028eea9d3ea1188422f18b61b6de09175146aabbe45698e910eceaddd76dd052e12d8b66f9cd2f124661eef3a680342ba6e2fcba78197856a86118aa8f34a35c99d06b5be5ca4035f96d3b385de0eb7360abbaaae73bac337aa08447f6318294daaf05a1cddbf6dc1bfda0cfac8c49c9fb51ec1025afda4e8d46b2b67bab76e215432a40f7482a115cbb57d06502b39acac9a7cb2f5845f9d935656b3bd45af70565a01ab4f26191009c22af61a59011fcbb2e125664db97d1ad43558f2b688409235b3acee977e7c680b31a7cf4706cdfe0ac75850fbcaad105e25c39b0b198581a6d8a2f7d906471eae24423582473d9902d17286a66eeeffdcc42848554deca0807e8de78d1809be1381517bbb2242f42ec8cf14f66e1ff22362ea030236d2d81214092fe5e858ef36b85909eebd3a2a47af1cff3812ad638b9ed028bc480b3b686f98ac3808ee5725e98bb086a4834fe05800dfbc7da623d40ceba2529d722022f19b2a4c7c9cb0e889995b6e5d44f504316ed520299a0a43244cdca0248bec280087cf124844c4149aae9f54cf4ae20b826a9945d0b959223cbf8e3b0db6c469f2d485df5071276fd963a253b3407f823d5e6a84f32fb3b58517d7124785649d641c8f2ea641b15226ce762f4a895c11fb938a3cd64c81d8c3770543bd669a34741962b3cb052e6661571510daec8608f6e0e015fe6bd76e8a3c63f0075eb65cdf90f9f99fc2d84dd3f9bd433504698b29a65358bcbba00be7aaff44247d5c62ab28937263260065f2c059b207d39574456a08c2686f2e9f6fd7dc090fe0b98806e8a5011891b9571775cb5a7add60eec9894d87a185473a41354798ee49689e24f8a36509b5595c1b1d13eb1cc859e07d7bc0dafb8614eee7e3fdaa7309fb7e857585fa6abc7ba61944274cebc497e5dc357bc4b243e0daf435b0d2696b5f954b8c5f0d114239d5310b1a96b2c970afd929cc6ebb5799d1be5c3e1ca3d3e2fc06c512709d731ddf9d907b606c493eead1bdd47d142c7a02146f12306bf9a06f7960826bd30a53220ee5407156eae5fd59418ce95faf7917a7f453d6ab3e7e882c136ea8ffe893cc6e95a64479ececb71a888d492cfb980ac90468b4a99f530d7ad608f8dec87a86bedb81f87e9746725ac7b882c56dfb294df66791358a1236e807597b9fa0d2ba446b115e0bbd6166ae81a00383e953bb06a83a7b99b24049de36c01b990156e9a7f012ad8324c9e094538f78a8a65e2309a3dfd3941d959377a6c11ad644a9a2802a57ee6c0bd9b38e9ae197689fd22e14f6741956ef7f7a34b02b0b97e6b79d60858744a0b0bd7921cdb014a90757aeac4b3dd7a0faa7c67b99e1d2dbc7126dce63c501d8500d160259f29f67003908bbe10035beadce29d998c6d6dad1cde2b5046edf816f45bab89128d7320d491ff472158abd0e53831212a8de8e91700f8afa6eba917d2984658d3dab3b21c4a9f07fc6c5114c327ea04ba92546d636d9769467a3fee8706ba436e14145958a51151f425c29a55a39140c2c021d4112294cf375d77efc1a0de4570ac8b5c613c779cd1767140aac908a2631cc164b479fc1e790bd4bd1d4e981bab14393cc058795a1e22741bbb432a6bbbeef977083b1fef0e78d63defd7c9d98e463eb8c2960a4a4b909ee4c1711122e97ceba558467639507d3fbfd3f54abb9262648d656799b8b2ec9e071fb3eaf3259293a4d71c13d09f959bb965ce4a7b80a3295f431b63564654ddc2d6d962ada01457d6ce127cd9b0eacffeee17a16dfa24c7da1968ee0431b875a4110745f6957cb18bbe6bad752a0fef36f5c20a00e4b19f94e8eb850c25437361150182820cf2c2b0459e7b3830d85163f2d20b3547215e002e88b71d7b3faa6a41470f7378bc1785239970175b722db4f1e5dfb80ab1983d921e9ad29e39a0d159d2b217d16d008d29eab87fc2ee108e06422a81ed0e82a2170f91ae229a005c8dc98001def4a4ec8c5d4d9f5e15cef4e1f7004a8169892975a515f8a2e9b1f8414fbf38fa2bf175e912ff28949f0a7cfce43783e4069b3194435a70007fb30897a73fec661091d025d8039de9505305a10c61176155d0b15375f476306421f49b514f9c28ceb8a7c02d64762fe2aaaeb06082103844b923c93be3ec48d9874a94aa6f4910c545806d8f85424d6d5538c4b8b502a8317cd23b30763c0a33fcd1dc90e33f0d5215a238200412fc05802f27c83aceeec60631301e250bd330c61081054315d71609838126682d71e22e83b55d2cb4cffd6602b96f0fac3e2aae21dfa40eae844c74f97f0ac5baa188e9598caca0b23005de01d51b42414c8e8f18baad9d769b47e0824d178847fa2549ad72e91ad0545d7a73edd538a7910934b03f9942c7e69e70a7987f2944fe9b4aec5482cd94f1b13f38ae22f3783536a4adc2f51a330a8595c400c413a99c3c7c87b92841c474a6266f4f990a7c76f6e90406a1b922d20b98b758c0d12c52606520137ab75b92fe1204ce168979ea09fdb5f6543c0349299ea99f47623b799ed2f6abf81c58d2a9f6054ffc7ca56363ea4c58571485d086ed13b43f3b6710297c010097bb6339ef398b0f44ca376b22579a6b200e3278b1a61062d6d5bef279f34bab3810a78a0f31c7fdb48219e594c19eb2419d97aa80234df22cdbaf84b1ba431f1125f64dcb3b6b614aa6768bb5e9878fae686c4af32e5161482d47209bedd363931efa113474b8184e0f338e2f26dd3bbd321488f36698711d9093bd8d11144922613b9d6955cdaf4407256020474b412751818d04f22d2b8cf85c3696bac39ce90738d05ac2b39bcc6ca85063b0fff594fb201f7d706dc8618e1bb3cd1e3c76473f65c2b68d749b71aa1637e6d2f87ca168d71b0f40e009946174eb93ed7206af3236137aee1f225caae99d14508db944feae1260d9976664c4b5ce8b52a82547200a36538270a077b009773bdae3b67b7f7f7b83195f6091ef273d19669e4439fa520cbf8543781accd68e0c29173b9c49a62effecbf4381e22c7413cb2e5d2d09340a94d1ad358fc9b6c163c8889a2125c079bf91cc1eac9a7d31807fc00c8376e3ce1cbc4eb6c9672bd81e35482e4dd99e74935e5b2640dd39fc62ccea1142ca5bcd39246d02c79e7efe40e4d514f05f0b07fa1605b9890723f24a196444a31db214ab0456b614cec8a7661ddc96b69f429e8442021e8d4fe7e7bed973ab3aafb30a45f090f0d48d83b4221e05c567062d027c4f69744f72bd6bd6e916a119bb852f992c26c58f44f0f7b605841b820f28eff0a4a53b28be6eb6454f2884a981d044425bac3ca68e92b1a14495d62ed3349f65c4002e6e65f493927ae56cfaa25a3d67effa6b2d05d13c1b819f1ce983f3df73c32116cb4be77272f1c7238fa58fefd3cfc70251600d9ae36a8c0066fa7ff55da9de1a6c0b425c2dbf31a77209a25d3d44ee3c809fba2d668e923eb9b91830e3305a40e3265ca7cecf33cfc000ea2fd142ebba31b7785537873fe152f8d894b6aac1bb9f9ccdf71782331e7f9c30d558449629a905a4f41e160c6af44decedff9f9552fc0ad0477a4d54a3bf0920bd053cc64b6c55e44952e4a1586faa87c56735c68ef444699f856d9390cf16eee6cf321f674d00fa9658e374afc7d5b63e3aea5688af01d667d48a2811c44a6b20c08c83c6f1a340f4abc8490d4d1537c578e6900b607db21cfadb185147d602632220e27677a1eb3e842bb84290e920ac0ed8bdd4fab9b8c87d17c29907211f68410cdda6335fe23d411f9a1d9cce13c7fe469889fb5d48f187e0b7547f1b1630d5a2848d0a92171b9eae1ac5a30e97683c01370ef1410502bca388844b43e1649524c91fc4c9416902a9f19bf112b0893d7da02f23d458a7d0be4c6fd2092f4fce906ca7d350fb508646af3d3d6c30b3378248abe5460dbaad59ff8394a3b3f094cc575dcda5090a534fc935427e88e3d74d42aaa56a2e2cc1d139b8a6edbd44352fe693ed44e303c20fc169eb9262703a55c72aaa7a7e3468e097de36ca1d73df98df0ca5f0fb2f49c8e98bf410fcf1a3fdf3843af4ae88602ba8e5d01dab132d9e1b76c360380fa7e729dbeb0d036d8ccfd1a328c740414279305f88c25dec776d15f178c2e5f15e5590cb3bb4d50a92ed73bb273b5bf7139eaeab515b51025f5f7f7b1b29e4074d24557fde0e9e44b87ee448aed6334669db715c00b85fef1e493428a919e26943921c1fcc5fae234e7fa261a3b794b29c40265fcdbc59a4611adb269bf2a7e6c03e96097a82e266db73d5e6d7e63180f4e976943db5b482547015102dfb5f98b21e008afe05e5833eb8faa124b6a77bb384baa643277cbd3888821631fe5979d8b19c6ca1e659802e7e9cd77fbcdd42d0cb5d3a34d822f8c25c3c1cff9e55988e847ed48d25716e10def86f905ddf87fb849cb3e8b2e4eb54ebbe92917584df72b9d043a6870360ddddb733505809e9cfd704711517450e27f058eaee313c62ae27989ff4dce8040d2a881feb97fa9139d8d611abca88ac7a2b871b7e2a58b5e21d80ca7da4821019b41fbb312a1a4bd74e960428c5fa7472d01096768e9e3fcec24583f5b55787f58a2451bc292b3fce7bfabba4b541feb08a5034b81940e75461de2bfd0c1bc1b58f37b3f760c5c826b93c8cee6bf93c46f6561bca70435ce39cfa982641a59b14c70a19ebfabe428c6fea55a1dc2d846c5c1b6316b1e21bb8e781ee16499e3b3ea9d8165cdea251109594a844d02e2d62c6c462fbdd478c51a4a272a55e9c4ca593a81ab78527739d80caa85e883227eba69f762c02d4ce343ebff7014003fd2fd9eb7a87dd490374f41dea37e4a4f5ac8d8c075df6a865f18df8a03953b99cb646aad7242ee1b1744a0a6bf05eb880f37065728b7dcfe3a846e1641e70841c69a8472639d91ded5028a8286d986b27adb5e2e211a5ff521a325bb40c26ce5b15e3c1b3fd8648ebdf149d5df767a3d8fbe924b50cf5b1b3049c8ad5748fa6e0bc059f8fae1191d3fc98f0b75846ffc5c406a180941435dd207d6be1e8ab6800658c15aae486397986a5faf65f78f97437de477a50ed83fcfb5892341e9c8919d8221117c511a829c4e268ecfb93a4043e7ed5817871dde7f2c9d29243fbe82c260d5d737f627ba76061bb31becec0c04ca37a4e7765224a3c98a6f422d1b05f8663af504a52936c193d699e443ea896c43e64168b74eeb451075f0defcb4d7ccd671798223f0fda4958820ad07ac214704f17748574766d8bc4b36ef6c184abc4c4b5b0e42a68f4b56c96831211de670c984df32406ba9c44b8371bb413b38407ba57765a27ae49b8ca9244955c7d0250865293fe77258c82b0b8a2b27ff0d7b2b8ea59dff1ae5d038cc822c3a76e486ea449321c18b083806c70e696ca25946782d690c9aec7e02c6b04fe3010026ba0eeab801313e0f65b22be233e3a5eaa5c09355316c57a0cee9a660459ec61dfb9eb678806e413252d441fe68d711ec88680dee7c95427467aedbe5e198824a66150aa5cdd8f06162717dd1e8a12a9e7d90bb76e25f1cbcb0b9fb50bda71edf12d5a3388476580d2f1c25b8a6ebfb655be5f6ee748dfad460c6e002bd83164a7930acc56142362b2a575c61e0b531c0bf02ed3bfb957e52b68acf2a228ac6af5a4272e86cc66ad7ae0df8ecdaf03d820540fad9449aa9062cf0484fbe2a1c743999573f55b9e14f655accd53cda4384a8387ab607c59c7ef4fb02cf1aec4bfc91af44f4a6a900dd3826614344bbd8953954ba2d45aae90d077533619c18d780f07c0e420c142193e4a61f924b704dcb001938884c7cbe54aeff2ac1ca8715a1e49d8178351668984531ce1fc625af9b7f832c014987e0024502eedc5f2f62d44caa1b02524939fe77f302cbfcc505acf7be301bb90486194ec450a6f527128b6b9bc3cdb822eef056301bc925ba99c3192b02583d7d07e91ddba8cab738104497da40970fbb222c1cf4e71270fac5b6933f3e611647f77c2fa5c136934ee38c6a59227a719fd079a863e66872ec60d0764c6301ac22d304f3c6d735c27c417e8d83d16692cc78396b8d34f8af55b42158963783947487e4b0fc4dba6a653e4c15bd62fe3da1a93d523e811517f0a227258559f0875f4015424da8280e75dfce6cfbe28677433636b7dc35d6da3aa1e9c8800449c56fd216254fd32f65816675e537d0315ad6eb3296f54766ee15346e9564b065130455abc095521260c3084eed0c741d43424266f69a3406a3ee905b84935fe1906e52aac86e036a50a975476ad69700c05a9e0bf1ca4426efe78fed37a895a4aee2319002d3064eea102b69d52647aa45d47e589ed1e17194cce7a2ea2403d0c894aaa6a663ff774c601831c4808b32063aa8c37168939eebb53d44b6236a0285471866520051f5a30dd8fa8646978840b850a0e3944a2a779bf4b1f928dc9b5c763a3e609b472665ce1e994ab5399cae9e054086f78f5cae1f9bcfcbc55195215acdcd404f883ca8349da1ba47c8d63bcd3aa2cae2d3737a21378bc7dd45d92e19d13a700541a2c4a53200403baa4a11ae991d7158f573c46af0c5eeba3a38ffea6e5df3c5bef5d6aa1ccb04633b432ee997ec766fdd67236700b504eabdf6db6c13cd7871ad2e1a5e672ddcf4565356c951467413e28a9b7e4822e738c60a34aed40a31a0d4bfdea5a884f2cd22071c1e6fa1225295cc13606d68abafe6c996c15e54961e4c877af260731a7d79e657e48e9a878b7cead60f2a3a1f11da44bba353501ec10dc766fbe5e2094f3f50f477e7aab8cda97732739d21a2417107d2c284271741ee409d3bd19dc075be9ef8ff143282f8e312ac36fb2bf3f38c642c0980f2d6d799f22aa28b8d6cf1ea23518adf9b97bd9364c274dd626d9387fa9f0417285b585d3a430f2b33d93e51a59c727733e0d69abf401c322d48170daac3e6261df61d541f68360b6f88aacb520b8c77d81581dbec6703905584f69c9dc65a94a0aae14f96451bd2f3de3f3ef133f89bdeed3314a0675f4df7de5e6ec2e6e33748de522a9fe7ba3e88d0e2769390a797ed59f0b0b823736baccc07b11b465963c65e047123391f9862cbee9c43c00766b728982bcb4cb602f13b1f6c157e3ef071a02a4010854a3fd7a4a8695265fb3e4b2edb1c2b077f33df36100c20e53a5e144edfa489d705c3fe12d46c7af9fa45fa435758ef225f14bafc91ee5ea4e1fd934542897688fc0c7c5856b45d4fc12ae6611bb894f7d49c5a6014cf4a765744f43636dea2d97aafc1c4a0e6a8c60b5275d410d12d18354c501c9dee5efb8b68ca19a5dcbd4e36c9e6df20d72eb991f91f85a7a898f4f841641cbc40cefe08d76a13406ba75d8c6da09763a190dbce84ebf09a17860869024474094198c5801940aff63962d5f6ed6061a345522d2618e0e380c82c1a9052a908ad146fc8fb35905bad3f200adbda7f6208b6a7e014a420701c4c589ea45af5255e4b365bccf454f51751146f6c64fa793369e30c107f908fab1a924b48a74cdc896746b8b9d3abb0b979d0b0363c28d17b5d7d2865fec11479dad6616ebb32e22e8506c2dc1ef3b21cbc6104580a4330318cc2a1d03b247c19e31e7e6648254f1fe7d6366e576fa80d8c84f4cb3c786e85740d52e89a7c0983d42549ff746439ea5966b2be3a3d2845e0eb29e4111a023b12c24c312c3202451090309b7abd98439e93e598ba9f7c998bfdd42e79c38dead0976a54c3c7a146df1f65d761be0bdcc9f4b3a71b0d004f5a4bd43c5e5b9e690ad14cb194d3a6a7c1bc9e5d0b7a0315dfef5bdeb2e4d7c5c82030c6e97324a4026bcab3c503a4faea5ee7720112e1d702efff5bd5ca0e220304711a58474892fb0f7fb5f4ba6ef5ef203adde825c693def874d17ab241f7a7fc7f10a8889b6cd73fcf5e1437fef7dc21028975f499f9aa0fbad4c3d99b76f08ca849cc2dce6e170bd916a7814961094b9d0071880692a3cff6dbe6ec1657260e8e9c4b543cd5d37a8f139f2c2f825695349d0aa710e29c75d7f7380bce0b0314b99b94eee98e33300a1cd5edafd5e5df222e5112fcf85f3aa165b2c6d6db47b3c3ed0b1b2907e336fa37b146ac9d31ecdb9d2e48f26a9f5f4a07954e384b8f5f307211580a0ff456746a7bb6933f240227da2516bb51c1b5119f6610a9007a304e001bd6f4ccde03b8ae02e843cfa4cb607f715f782f05311873cc9412b385c170dff1a51cf18cba9e2b49a8decfcfd256934c306948e37257f64d533579bb051d5ed502857b6b60e9cffa7abbc11bef011001d621a022234c49e467b0226461ab803d553abeef4ea9b0cd8c00974eecb42028b335115977ea954184dbb0b3ea6c32e2f69d6abb4f39f955ebfd37b56ea77c345d1e26117422f13c9f5df1a3f8196d14cbbeac9d39a0c8293ea452c1d381caddf7c2f423f0ef7cb81b0a5f85226a76bd01a0ecace6801f8ea5c2a621a2fc5a2aabb92b44f2b9f9dbb1a772cba5d4f1ff098cc1b770f73703f3c33fe6cca92502f2d7232a311997006fde6eca04c0999a3255bfe42f20b96f7f316ba9aab331504a711fe1621b762fc6e6b5f59218da0d16773b8701caee465715902001a12ff614541a64014297ab0b2795ec00e2d70aa767c5f322dd8f20c4ff49d667ddedba3fd190aac509c1a3f9d791b5906354be5c4dd8b06dc4379a0ede45ea22e02ac5e21f1a8027f43da5bb41ff0250fc5f341d054c5c053ec0440ba81675ccf883117aa5122cd6c177238219710b5309130c710fd0ba8e490e1b81f3d314dba639974b18b56435464da3e63d16c2609ae207c13290e54422d15fff00cbb86c727f450b6f2fd3b4f98a8470e5f831324126f307cae82f7f9c59b0fca1e523d70fe8e051ec7e1949ffb14c914abe88ea09f1c518c953217f61ce1c7b49206b17c2ee83b507c982850f27894508beb24ffbc2c4bb546da614f80d847a1a4c0efcd567d9406038cc9d5fe4cf6c682a73d85eb5660dab6f828cd8890a955ad2e0dc57932390661fbbffb5494cb27159cecc2f32aa745be30e477ea2f769c1f36ed0a336de4ec608740d9ce037e1afc00fa891dc2402fcb87d3a2646c4e5edf37bd637abd2719a0599ec0456bd172bd860b34b5d3d4ada9503c2ee7ea09f8941d2d30ca6e637819479702bd94efa704974dea453ef05bf1e5942d506049f41a1f9591451c6a54f0b3194db07ec01d48d26fd9b9f4283981a9d049a7ec8787cb724cc4b4d29e94ee36b5dbfa4c3954698e5d66e9186e08b61c30d36a69938902ce26ec659a4bae12fa1915e8a11866a5fb4a1fb4aa5888f888e9e0bd63b4e74059ad85b01a65b22660f7643d25a005da55f37c8e07442747f6ecb25aa8f06ae2fc100b2eefddc286c75f30d78340cc04dcb06064ca683967d8b9670a456ea526ed9ca13659180aaf16f2ffa5920b2a93113a0c1b160081e00cd9a2b25ecc14837498a924722c6261750e536ead12a12bf764e387ac2841b10d804b3ceef5aacf65d64bd7f8a21bf2fa5e4c4bd76ad3ec73a3cf4f53e5c60aef7a93a0154b20018975953cc188b9b034f4961708ecc3b1e0ee7d86985a968fd31378339195dfe8d2a777c97f5ece2e291b5c6a5ad6f3adf65ce46d76da86b57e5037398ec67ab07fcc4bab4ec19a12695e60636ea66bc50e9aba077935bffadbb2add9d7d66f2b2a3a072392d10f3d28a5eef648561a3c81f5c5f69eb599848e0248e1a3cb7082bb37c981f605dbd8f4a54e988166a4c1a2d9d14d5af5c5a60483bc387373b3e207848c3d7ba14a96afe21ee556a25873030cfbfb94a0ba2e786017488f7af6e9436f7ac8591c317037d899112aef4c4471d8bc6fbb61033b435d60f52250223aeb900269448d9ff1ac4ef78045c84b81e0017b4546db9f1a762045087a984ab35384d8d0acab82159525cac408458a1999ebe06cf18741e563a747160f5eb5eb5ecddb958a9e3cd4c7429d44450f16c2eb69dd4517c2564995cf2078fea67984482ea59cfec464e63649f846dbcb41742569b023a7a679bacb9d0d50aa8ba4398ac3cd63b345c0c404af02a13f830b4a2ce6d2f4d93849ebc4eacbc8fdec400ed354708eb0b3c40de969b25e9ae1b65264d3993aa6109d4072163d0b800cd792c6a1fc477a1e9085d5b7b52fa3199c5b0ffa4ae5f1e0bcb3733ad097065665d5e2fb7adee650bd594f64df5df43290bac7468c13dfc6b353bc449981ff66cce55974e51e87a576f540c1acf8789c3ce8904d74c1b7eb13597755c286ddb92456188cabc6f9fb3ff6714ebbaa64984790c40809ee3e8d7ec6ca8f29a2560e6cdd924850e7f629494a7cf548c84b2cf73fa870a49a4e44fd8942a60f08cd08b7926a1b0dd187cf6f7ef56f6b4c67c887a3b00207b41f1788c96428d7e781f9997451ab0a3fe8f4f89e37180dddb3cac7c064ddc13fb256c248b61d502db3982ef9e451318286af4fae4faa6bd0283e521fd6395718a646f598000aaffc3da826b6276edfc1d024be0b3c4211f10ed443301567dfa61ca465b401505571eb58ae63e8cb2de12c440a40c9a50c32a6cba805aa4683c29d6ffe8d3f9227630a68bc9a425a10a4d148e7a5e3ff13e7bfe7d36c725cdcf0dfd97e9bf54befb30733ea963c4247b66af0e4d224c6e718e0a9c4dcb9bfc19e885a49852de67bf8aca699661e02392bee1a021b8b01286621c7e22e8191e7402c29032db30f01749cf70d0134c18890a89117c89d27b61a0138c30498662047e22e81b063a020a2f692846e02d92be61a021a8b01286c288e54d6d150b47109baf20d40fec056d1a9cf0093d8963116e963aa57a8c56acb69091980de3b107340c351b98f089f43dd809e25226830d615bd44394633a856d2953623510e1233571db278e6288e9461450d15caeb8e7ea237f4b11afb85dcc8d2cb0e2d23f0005376c0a7971eeaee6baa219da763f11f33247332ce2d1a0d41de3a5a5e36c648568bd66cdf92a537b431198061085622f7d80217dd5962d1e5d5232c8627e547ecc802c8bb11286d2a51ce32dc4088de6d7aa46bb2e0c9b3f0c752031ac7f18faada1502a9ce1cd2d0ee12360f8ae8396c1fb64d23e490179c22a22d4a8f537f540b9a2f192dd3b9a32d05cde84b662b66300b13acd4c54b8a790ca3bbd791d81c6bd78f02841958b1ad5f7cad9c8864bf700ef68322ef1336a958a09fb4ce1b82b62c32617258adb7718841166127f94a7ccdd83411ed7ccb0edf922a847b88038e069543d94e0fc4c990562033f12a4ac73237dc68013bc6c512b8dfb302773410b180448e3c5272c996dd5975c9d27711aa7c1f24668aaf781dddbef302c26aa355d1f49d778af383022c30f5148c8db1a657f309503beb8f39926dbfddf90b666db89441e3d934c8256524600cc37184f2461e1567ab8201792424c676c5b9d807176cf9ea7aac8af5e2f4359f43fef588104e8c10307c13916e04057d2a2240cfd527a724b5623d2944a5a7a13aa90c390953a0f582922e1e01b27b3f1b3459cd0cc6a3b7d078dd920ece7a01c9a2565c331d12c0494be6d9a974b4a25552591b609bcad65d62b715d755057e186496460f9261423f8814bc74e50b2ded8635827a1b6738a5dcce9475b3718ec4b97a7f3e5b4400dccaa0291bcd63941ce0d462b36baaea277dd366d448761008b1c94a11a079f754bfc2514f6b770fd0930cf946a760e2fc367aad2c04558cb0eac08d8bd21b90997d777c54e6a231b3e8479aba96cbd39dd8a44f022ab2598052569a309e7943066df7144a625f338a8d92367fd05f8f14c084c7441b714e2b19c6da6e81d00e5ac6256c2f413847c1e9c53f196597658631c3950c8eb02f99fd4b2231c13a6b86c1a473d195ce8a220432dbe5cc0fb8329131f15f4ab80e62b7157266fc1fdf7f280a60433e4040ea4f00c832c0d0254960429e2e6626906233e06fbb8483fa06423f9a45d174f5cc484dd1d4c3ec1b6a8639809dd803f2c3d29bedb580657de571e3a71632b8f8197bcc2edf00a7f64127a50e0534c540c7d0e4e9e6f4528f6484f9b720c89e2beaac8cb16caca4c09c5f56596cf0b3de4b72d425ee8a4e8fecd4a594a4590189697b53466afcc5e2e5cdbf645de7ca2e2b91fb73154f9027a5807303379e2cd45cad0f843d520aac4a33b774a36b8131fc236f95eb4e5d71ddf62f62cab56685c33c2fc7267fdecfb88a8155abb19e990fea4ba9be72162d4f8daf55e75de558c6627fb99106f968813ad68c0d850bf9b590305c9f6268972137127db125d93c8550af64f2313d7a41eac801d9594d1b51ee92a1b48f8ccbe6173cc4e38756471dc6896d4379578c4c885143e0f8ffbcb4f188739d1911f454c1f46d2048cd776253905a4ed2f28c7dbd71658f71e18d9b3c163376b09d80ddeec671310f5d9bef1711705b0d28d2cbd54800973e35f0caf66e66ccda5378450c2b77d233ac678daac5cf70904316332a54d5138a8e24a487c3aee1b981cfbfc166ed5af0266a5bd488aec137494ee84083390d18e98eccf7fa8285b5aa27a7db8de5643f23fa782951846592d9d6d8f06e707b27bcb593328d06421af7d0a8b19193ae98f275eb71376e3628f229d23934b40d6695bc606dbf4e24f1a2d7ad23f0d594f477aa7dfcc9479bd7f3bcd7a39fa545f54507465b985e188e1705c41411b751b03d41ecc92adc1d0ca63ff0c79da27a0e0b3bc356f9f17eb6f7f56ebe9799693498c82bae88147c4cc649bc394f22995def553316e8f683277d77fbf5915195053af2281a9f6392d76d77f26f3d471cfa23f8bebdd2ef55068854196d6aa2c34316e72196710b0d1ac86b3cc3c09d9be953f5d2ecbcfc4b70ce7ebb3c9d11eb7aa295565c10dc6fff3b658e09dd1f17c1126a2ad95153e0105c44e0995525fd6b31a489eaef57bf031bc32f60480d80d646cfc39acac6d1ef8924a4c2ca280d2b96e6a95102da6e50d5eb8ca2506f1996144d7a1311b2345f3f882ce54ebeea884b5e1c947044d42e191567a2f7c8523b35da46ecf318b558cd21459c7a9307666d2a6e86939b55e5c092a06c9c82e7d0558d875bd2ce07d8f57a091793f9bd07340f649bb573728d15fb1fd760decb11a0c1d2919b0caa8f0815e7bb445fbb932f7975ce88d2906bb2f71d5c6f125ac4fea668be14b0248ef4bfc73101b12bd2e875681a7c38b55325cc4609d1242a959fe2cb8959dfe437429c7c70d90871ceceaf21c8f936b12a7c8a9561b5b7d9f1f4bfd494cfbc35f693e402b0975c781c0f49e6c2ddd6511e8a927541c6f90642b3b9c0eb4ba4f6311c458881d42bdbeaff91dc9a6665100a33e90217c03462f47094f6ab7f8a5a2c7330ba366661f2af563a880e782fc777dc5bd582b34aa298ec17a0f2bce58565038480b6cfecb644be9a5be7c071901fa44cd054ae43073dc6ee87968b6acc625d8e8b28010ac4858b723a9893ffe3ca58ad87b6839e7eae1abfa4b12e5055e015f3c19944fb97daccd31c5c4db02959775e2394a5c00ce56d1b1abf603cd6d6dc52c285d3222eed4902ef75e4d575fb7e2c8a11272043b0f638fa4e99eab4bac58c7cb3f93d71b0a351ad321b185b32a67f57d5ffaa8794f9271f01d898849010926d05c5270a0323d74e94227bb2c29d224108a29b6472982f852c014b483eb1f9ca4b5ef5a3451d35fd39d91648c99d225758af120611a186514633b00341ae6bfed38632b73f54dc3052e51a2df60244b14cd092b6eb66dd8975108a174c04d53530c25bd70bc3bb7eb4c4ea5aaa563cc62bf53c5c759e57c23aa161b1157239a41a2c16d8feb46905c8a81c785503a8872e975b93bf1d1562aede24a19715b612f846f890f77395adc680f738c12c89cc56f39d719b3bd76eff548e617ed0af98e3a55f7c6e4bb9769814e32c6ef5ed9e83e2a74a3b6168ca45ac24510bbf3e1d4d5a8cd30302b5aabcaa137c82ea0d8b15d175d5e5ed26330d7e45a36b06174474da6adc3b84b81e1cd8b78baf623f35005e94780adc48864ed01b560d6aa33284723acebd4f3037042faa90166aaa97cd35f861909491734fd19ec9b8d4b12b6fd2de0690121a5c044a496717257638ba99ce7c76aa2927cd324878916f6bb3f2753bf083b607c5549fbc06e0a26a9a9d3e354018c313a309344b378d35d310d90694cdd153fcde62c3da184d48cd573202aa4df15cfec4387e84b2f3608ca3136ae2ed954709108c356cbabbc8fa1f96821429a182a5909ce3869ec20339a49b5127e904478a65314de1a8c576ea16a6e3af872de6cdfd85fb3a11b18d825ba0c3efc74fce4c0963f6fffc82f9877abaf4d346e99e4431281e7ee89512b105ba529fa72089dbc89b9a189814e82eca59642e7be158ab42b60747463595b82869cad05fb7c98f10e34b4a75982fb888172c4919a103d60831138d029d3d8a0542280786a53a3205b503894431a586369a8b1af536f9a28f018ec9738a8b18066026d57c6d89a13271384f4b2a103738100cadbb7e9f51cdc5d1658fbe7be783d0d49ec3409593a001e61a0deea2f322f015cc906a119f6300d2179a9f69b0be3db2e4cc3cbfc4577169fe270f85eb69c87de8f5f7e310694d981ddb59bc144729c166b88017aa7300618b0f6018a9c8e69304cc0dae0963cfe64f9342c816ed70a7a5fc12868f06271b3d9a33abc4f60b410efb028efcb0908df129c9b80c72b32675d11343b194a7ae40a8cc090750b8c39590dea6ef185ec9470059f7f33f906bcb13e8f7d190b26ba891d92c25adcf8f3f67409d05b8c85ab1f1e0d0e079d1da5bb6e66adc4578b11c2ba1c5cbe1b9c3b4fe0cd88058db5ecff7d90470453ac6ea0968a0ae2be9ad1153b5d5e3a4c53663534b05c9eee87bc06ce04ccdafa49a3145fc3407d1007fb15073247243910c9a19883a7458fa01e2dcd97b31f688cf892002b315b16b564579c9bff274f88b14d3f3eb2230bac99be38da66e7d4b3d13c9f4e1c6e2624bc77417082ce73e2c5f86d85fcc7558105cc931e7596074d10f21314d4306a224597cdb33170a2ae46799939c54997b457867fb650f1209b2ee488e08da67ba1f2f80f92bba9a483e854478004d7bd6893837e041bae33b045472d37d3d7bd82db85ad4101c04c95b03be2340d15af2f75ce569b5be0a8c1af7d0b1673417482237ced7597737e197e7181f4e7dae0241f9551589fe8b5cca120111170e6d6d913e69f0544312c7de3a0ca81b1cb0a3baefd7fbd3324a8bff62f04a842faa930a312719a14094f6645460dc8b1a724340c9aba78552cc169a053a8ecb0e1cf05fc1375e6839744c300844bb366e92ab2e835d45c1a12de0fe416278c5204d102284a9e34620501519982d910be774e1020ca0b42ad3b4e67c01c7a410c651cf92586babffda72b8763ed4a0126b46e7a7270f4ce32efc09f49f15a6f28bd235b44a42f02199039d7c60b22d8ba073302827b2e8441d6cf35e4c7e386a8e37e02c2342fc8964974e240f5295434f1bf94205f0fcf401ffdd99a0a339d1378fcfc6dc0a26c197678b8069505cff86500e5a1f6170e8a3573d71d0cbb7d5b5e690d4408af2f33a43c4c23db0493befef59868eb194589285a743883ed4b925cc1f9618684588fcf30706679ac840a4391161a4fa04727ade13ada74e182d1dbb5cd7a3166b8c93a6f6571054eadf3f481eeed5f440c628b7031b58272b278cf02e1d8e35270374683c16c26d0912cf4800434c2eae436c8b2f606b6e748a343950563446772c7a2a2b6db86734ddd3bc483ab98435d6bd248a29e6814f4ca371e4dddcbc570f19396e6d32f55a9c62e6a0ad772c3cefa3622b1d1414059a48b11c1ef1a5199aba58df0d4bcbd588c6e10f47ad7c69905483fd6983f565845b1e257753b2b9e90067dc2b25a58e700daee8e81c41a3dbe42155bba2db72d40726dcec7dddb5a30cfbafbaffcfb63df7b5f8ca50081931e864671738bb42465c90623df582acbeeb626158f2993e51e5559dc83463b3b2a9e65e7f9bb6c92763e269066bd9f3dd4eb3cffbab2c079112d4d0b3835df69c48ba7c1fd25c6cb787d028f3323a1617bc46dca11b23b9863ffaa3b1cb05459a9aaecb7ef2f32ae632f84ef80e16a418fab5d1f8d45e2fa0cb29d9ff50976794011f3916ac757aa3844081aa14b5cf232d9662f7f40a5d52e107372f41280899d005a8b601000c66170c8c23f2bdd25a431283d3a09bd830ea13f400fff89ceac21621aeb0a1034e59e873909038b91d023429cec7f9051247ebcd853c188147554941eb1e040fb1809066cb0b2273e56177bd84a6d99d9435f06acd4c71009e30d8b5a7b248063287d8ad4e317bd321dabd42c51ddb8e8e989c0788f2e553c913db782b890d1bd109b41bf5f8099028acf0429818e9a64261d2a20910624841e430e45b08dd0cd81017d3eb6c61d1d6e9ee1e8b1e05b17da1a30ad6d95a146317d5bef0482e9003340640c53c63e7e3e24359cb69215a7ccc38d3f762da0a924407116ac711afaa7b6c0f94790ecb4de45ee16377a07f540f5107372e617abfd2842fc07a81899198dbd4e5691a5d92330b524f2c501da97b6108f886da707271161d1eec0be1b39cd47668022feb5905c59ccd1dc68210647d51d9f0e9d43101fdb8916d81647142a84ac75715067ccc706c6d670d0c0a0a20009c2c2a3b21b0edac7edcb052d93cf7bf40905562d1e59511d572d5e1f0478f30d2ad290ad3f9d0c58c58c5e20803aedfeebdaf8ed8b63d66ee7b769579e2aa0b206757f6c255a70b67e097d48efd6852c81ae96388f260df52bb7615cd52fd1d982e99129f17223201907d9ee14f9d98864d52992b9492d440e7065db3c0b12cef9ca06665988967d8e515303d4ade71dc02d60c884c1819b03ee2dd3b9d08c6baa99f29dd912844c976bda9ca5b5e578f7dffa276e23f66458d98d3c932303bca598124707cada9dc790b6074ea12a9bed487742301198eedc5c434a774618205a0c6613464ca964bbc23bb79022c597befc802bf3a836f7b8c943ef25da242d14455eb7be314c9b5299262d8290318986d5c79a4757fb77d4995723993dd1108c1f56594f94a8e887d0e989da89b80df687602e89d385a31ba9cbbc3930865f125599d044a17768ac294b82cf71d809d7800a3bfe16783d7f70b7a271c96f5af5ae623dabef92a14f4e8fc90aa25e414ad7d46d1c63c8ebc8261dd224e9ab74421562cc7b257d2f21e4f47b1cf50225f33ea4f5089419bbb270fe2949a4329ba6ffc93f25c3919b3567df01684042e49e9c2df19ae443892f1164820df0be2d4f122e0fdaea8934908b17c4e1c91ab32a97af533ff209d50917c853d74a3daa5595871f4fdb4eaa4ccb3aae4eeeaa0b2088405a399dcc5ca3f2ae17c8909305372f20c7cfaa584ecefdaa44123d9aa6a2a38e933f0330141bdaf1286f92f70f9e42945b406f328f9583b6225ba184ddb6ec8ae4fabd3e34398fd7c5a7ebb9f6a6e04e71cb66d93ab66c8d70ed44af6dc9ed888bb1e948fbec7a0d0096dd569bd6b23df404405765302f3f2058a5a91ed1e95591015ac33c2a6dd91841c0c023c19a6e25d7f2277b65fc6d034e140550e998513b11f484ed46d6909480125d4d9ac300032086edf59468e0dfdaaa06c9d2f31093076d1fb78b9626d82b7069ff00ddd2cee50150c6a6298f77d910087da20e8155e223df9da27c4913f63fbdcabe727ebeb8aa10586f7116d33a1c0ac3500bffd27a87a50808259a9c2ac0c9199ac8ddfaeda3349b35f04950b0c089a1ba875445de57c786f63020d643d23550f7732a3f99b3e044b35264d85c68d7ed8f0ab9f1bc663c57da6a5573f28e449b33792b5eaa0bf5c8e4d12626ce752f4438805a52ad100aff8a24b86c4d17a4dcb333d3aeabd957d1d7b5fea1e0b7d275d5628b2dd55d401a463400146aa8b138fad6b2a6f3555e49999dcd079a2c569692e7832a5cce30e7694551b7429f94b2b029fc49af9e72f36f547ac7e3558794d940a9b8e77a25d40954199a79098e06a0b1f3d886d1541293e2c7e47447e210c6edeaae1029ceb5a919a9af0870d4be21f8f5438ec0e0a9537090845abe48be918cf149c13572124716f04e115fda1a6ae6615b180bdfbb0d4a24dbfa50ba54bb2eabf94269c956255b5ab2eedc3963f123a7efea7f2ef2e119dce255867dd1bc3f230e2342e62b4d9ee1db4666026120d029057be218cfe6f47aee22636c398775a4429929bb8907f52732a72f555c985565c114d8b491dd097d09bef502ed504fea5cf5aa1ddd2794d35c842604eef18d41a97bf5da8ec39282d395f0c27269d9e305bd2acf009d6de0fcf9389d2d9cc8c8b223d11c9bd42953d5fdc646fd206ba2f9910d2b94795a50315d6f3707b9face28d54388d71d4d72e9388a5d0e0a0f09688dd91b8899ac57cbbb2f0c7ec39d93e7c15d2717b6e151c2feac0a96a8718e9c6102a078ce3541d5ca3eb59d21a363e06d63694ca72c93a7a3fccaae38725b4d9d3fb6d0ff189a56fe4357f923a89d68985d2a4bc02fe0c037e99e7ca90abf9208078bbeb34563a8958d1219659972ddcd473e621da0224118f47d733b043b466b7af12ffb420d32939bdaa930919e569c47d1237e6743b7cf65fbde4d95f81afd494dc05e4bec86c56641d80455034b767f277ffa5711c605f38b7b6b8be5b220137e2b7c253b042ca7b7760f33d758cab9995df5665142777fe66d1905cfdd4f6719b6b2f1309a97d145b40c2ba38c0b4ae00a704be9a2bb529230d2e334239d9a210a104cd971e27e3812e5e6777285dec05913abf4a9bd02940f8ceb07dd85536600b980235a5ded837254c550716310b06227a300b79eff7641228e41c071a857112bd18815d65f89b5de43511080bc2000e3460e9fa6d6e69dd5053622a13f06526eb460478229ca08e474f3ea2a707619fbc89083def798accd459758cb1ab1eae0e52fb96ba5d553ea94beb4d616af1098da0f4b2b40a164f5bfe1a5f512b93849d0a9eb587869fd47ca8991694dbea9aa835f4a32d40011900a38e8f76a2d7bbb733d63d7ad551d915e8fa342178eb60889915576d120fc39b8c5e3d01a6f97213525a9121ad0a88066ed46501f6610172a3c0ce101d3a6995a57c3d855ed4e7776569851e859bd3730da44d1d9db3d45ef105575e62ebb7e6400cfe55fa3a3974d2bc55dce589c043a1dd351933ee474d85dae0c6964abd67ddc150b1e11d7aa6c071a002fa1a189fbc33ad9aaa586eea5964bf78aac5a8c666d9760855f70225918ee97ce10d7000191230f634d3eb0dd6dda9e87defb3aac5e38dd3c55f47e7f2168f73f0a97ff44db5547b4af238e921e76c2c14e9c7f44717f59bc8ba366c0ec1ef192a7e418becf2af6879b28695a2c714fdd98c964f3acacf8c06ea04bd8b65884d46d496c22db1923694181b3a24a155cebd288fc9ab197d69042fd4e4a829a78020c751d9e87502897f804ed19964c690972af1acdecfe06c56fbef42915a52413491d32b6726faec254e4dc4ba08556c7a6361eea88db8cedb848ff7d1a06c4b01c3f7662c498e6fa4af6b1c57dd7e7b4430b3401ff4269965d40e87a88e21793f5676e2a344d60d580cde611a46ebc753d10dc50652e605902ddb6043d7357932f2e22e9c523ceda28fb9a1638323ad96be9602fa54f144ed734d6a81ad9d0f6bad4ffdc8d81b016d2c50a10d5eea62ccb6b5834e96837416e623920cd19682c966ffd0cfe46a132b46065ac0b1666e424ec422147016b8369d9f48dafe62992594f2b779e755d1cbfd1ea6e4e8b1fe770ea92686f40c275e8ecb8782ab43e7fe9903f0a91128685ca4bc7c2e8ad9c9913f9fec3227159b38a6a37f2eef7161d160fb49bdbc27849a54b45e07efc62f87449645c554500ca0f36b0e151d35d14db9dbf20a30515fe67cb2264a0057603eaa71ce66d135e07a28b1ca8430aaee10d19355cbd59594c0aaee8cc7fac41a9a98d63f5aa539b2c7d8be068c874ace40690e9470323e1dab60b04177a74488166d8fab6d3a0a0b3bfbab57e72d66cf61a1c15877a7a9731a17b1b8d8f7a3ad96f806c191ca954cfb5f5ce73383df08a5dc99ab94c3343a820528bc58a3a824a01c967ac4196ad0793f63043953d52f6414faa94224bd40cdaf2e2d88966ecfb8aa85ca040d8bdf34bb37c2d23c0b5f4e52d7af13447df5a5cabfea8c188aa09eb78178b7504d5b3ec501c175706ab31cde9254dad935d8206f562696f7d4f7868cb9d8120b5a2f4ffdc06da6a81bd6a4f5b0c4e56c3e2447fd164b42a7cd03231c9f6c8347466f119b98067d980432f3904b294b7d900b5d353c0af6b263c78d1d517660c20ce398d35b6caeedff8780d911a0a222862c89493214c242f7794b9bd0707c38a05578376c2e7a3205a7674adc263f456b8dadae05cdb63f510798bf8eaeca261f042b504a1001c7723a127a3e4a64d840badbf8b81e8cf90be432a82b7eb5e22cc6326d4c1a4c8336cecca466548c9a23aa92bf882601be265f15ef055171be77ef3e16e35628b01e8d64d895c8f38504a87af34c580b4576f254311e0e02c2f96a35146afb27649c4001b96080e7693784f1e0cdd50dad96dcf58b1eb8e711378429240d64e72b16d90cba21b78facd888cd3ac3f8f1eb1a016162b700afac502b27925648b2caeb80b302e2a4f08e82e4c4968cf6f534dccc56784639e2be6ffa11b1a62f0e5a32eb4253f200fa4b11aaa50c97fa5609af2358f0ea88fe5bd26e48a90932d83424a6bcba79f7c1a399f0736a0c2e3b81d83270c0a62161857477e58bc6c40adb1bfade7ee7330088545b002ab16412f5929455152d3fe881f27080b5c5643483053dde767393ab12384a486d3ea426a7de3742543a08b59a8d7737a495c1b67bd4adfc2b7e279a344c8802f6045e9a6e87d26db7eccffcc2209766ce1cec201fb2faf180f93b69f30f3c031b38a77d86b3e5ee2935b0f9c310e2afcfdf4b1466b652cb7b8ffd82e6ed1734f9f6719cbb18dd430bfe0884a6bd1b8fd4c9312a9ef502f48baf5e64a161dd18dc4c2294a05b43f4a0bc2143093268bd2e202012f8359d7db5dba142d9262aa22c4c4de8bf0be6ce48eed2f0e1bbf4317322ea1d49265aa5747d48fbc053f7da1c16dd8be078fbb78a988d5234633331437deb9e0d7bb86715aa7b4ae57c3e4aa5f6c45d24ad8e8e79f7687d93d58f983ece17f8fa8d2814a462598eab81111efac6133b48bbc8395060917cff33be81dd872625d76e3436cfdd1416c428951807d4abf44ab0105bff7b5e642ea7af4b3698fc254c5dd0ca2f50107abde82b6b06f36b3685dcfd0c1b1d0c54e22406b0e157fa3c935548b3e552de99c70c868f7e5513db20ab836fdb6a83b38dcc8660524fbc6b7e03760f8e3481f385c2dcf5e55b9af247fdcd21c8cec726169ca6b4b2839338d61edd78892711b345bbae19994187a8572661741e143e49d5158896a38fbf9b3f70a1ca0861e7dba6c236035e2014d401de6cdac3c56f0a3d5c27c388d564913b915c0ddb1b840dd9d983c06a3d562d5b0c95df0ca0cfc2176861f484954f00d3571b2fd423fb2b2ee1c3959e289f3d0b3747d559f8e672957496b1dd775d477c320ef0dcff2b67846ac61b9935be32b6742efc25fa461cd233a06ba53640a69b25cd08fc579ce8468f6c21d6eb9467979410d220dcbabd66c9db70cee967a2922fb6cfb3bf2e7ec7a8e1ccc04eb69b1b7bc405b68c3533a437343313e76772d74b2afe28de0594900d257c4555a5ca71be064ad98f53fb7a959d01188b0499141c33512831688900294d8a455bc7002a22175cb445d8c3f4f3097c8bc938e63d30abb2b7a41df08b4d4ffffbd4c587833213a4468e72f30ccbf99a702b51bf7280bf6e7182625f8027b984124b9e24cd79e62300c037cdf4524884200b30022ff97922a8b78a81e2603f84408e3bf22b9b36f79aca827d4bf83e7d7d095af25e17d46374b1d116750006d1aa29ad3f6724e0ac2c4d35941caac96d2de08047da314604eff0e00eba6cac3ded427a746b2482c98337b90da84ff3d38240ba6799505518a921d462036c39e569d2d05f230257cbdc8a116a8ea1d5e73d091937409496a04e393d4e72973aa60efd075836141fc08667e924b2f238462d69e2a34fe113e82dd885934a15001f7a3bef6010f8847f0f0070ec511a05db68abe46b03c878a8feeb4791cef2971502f75e0cc208460f2cef199720e1e98f0722d580202e6ef66edbce99b4da37969bfc186c3e9a26f325020f83cc3c8b01c5cf14d1be07bb7825ec9be5c7681c38f6b55bdc3355f6110d09dc4956a2094d3b1ddb6a9919888b9fed15dbcdf241bb8212dbabdc9d40ae624c900b4728f73659af855a8b9c387c9a46e25cfe4eaadd40daee0514fa266d94d7849714acd452370c9f9f8554f87af96e4374d1074690f6634762863e6dc1a8a537b51ce287bc2dcfcb88a21d17bf8379478901dea143856c425081a899b0f6bbc795e86a48bf0ca2e9a0dc3f8174f9760967a693082ea28677d124697d865422fb9314626b00575601bc4fbd6418a8bca1df1af4a7aadce92fccbe50b727fbbc3fc8607d109c1835b8fa3b18054af9a25776b165ae7f279c5cf60512295020cd69fb05bc5fbc40b574516e851b794769be06f596371abf2e5e1128c917924e605543dc65eea401fc063e9b9fba6b902b8dd37157f8771ffba767b0b78cba337251f8ad5f811fb9a09460a0e01f61b6380c7f5945b82fadddfa80591b87ffa83b82ab08dc9e2f9c610152f655ac54808875a211d5f2643a73d9a63d1b060af00afae40373d02e225e95c0664414827acc014fb122024fe24df04fcb49a77115c745fe03198e3c785cd0e9a26fda68ac22549a12a03e5485e6d034266bf21ce6a19892e973fc8eaeb236a63413a7b092dc730ec931a016f3482daefeb387cf3aa95314a9ee52f61ea971fe3c0f210e3caed6f348500b8fd70961ffc9136af7e2a6a54b3cc3f36ff5bdb63d81563437ce99cab35b4880632b319e12176caf38a31106ce6900b2142b389e612e0f52cc08023f04ceaade0b63e55d2e443dad5f01ec61b31142582e6a869816598489b59a24090246ee327d32b4496326c71c4e78154d03bcb381ade59185710dd58d4e221967feed37a5d57a6205987bc06895bab7ed28a4311478c2881643b75352cee10620f60fdff36811fe64552da9559d233dca571f50c9f06777a51de6e95d968603ef726aa4d4c0df573d915a8def2529ed64e12b7c08a5fda9453240d043a54c8621010ab32eb1b62465ebe86dba276e9c0ff3f277f43f9194c359dc5716170d835f03e6639d9360d17ea7420884caff1b43d2c92312c9c4b34977e2a2f59b25c6f95ea8f0f3b4fce80d89d6e104287e38bb428913068bd664399ff9d78582424004ce9c4274250c24aacc20d00de1b806eec299dfd3649098e13b1066daa227b7a5cb02a8788bf0c4028c34c258776daa49fdd4b1c1b6b5c6115d9c2b99f3832f4cdbe08fe00b208f31248436e3f5d89bd4cc758a8c4ee0ca6187b16be87ab5c95b1f255c8cd3d52447c4347dee9bd7ab77c44fcb40165ea01d4b8b5051ad1dd45610c91c02acf2c2c3ee1b49dc35b089bbc7e3be5a45821df3bc99470a0748e08591ce2e2783b23c7963573546d1b8842383f2e292b27d70585e9718917870e96a2e74aa64ac03e00b084a1a1463eae9bc2359e383e359970082f0dd7b3120e9d0df2b31e4940251fa517bfbb6cf87b3e64f0c4b2045264ac1b02b8e8a1528adbd92a09b898a5800b9305dcd4046803e1e7ac581eee1098a26bcf4208c381081d59880f1d9f599e6d76f69cc2dedd07de5be58395e37140b2d34c8decd25971e0732f02b77b91cd333b94bd0be9cb907dcf7c342a4514bcd3fc8bbcafa55011c319373488d679104236356d5a354a9f80b66c4fc7a6220d5261cc030c3e86a9dc262898a8b7ba945ff99ec3bfb72871a7861f5d23c4ea1c1baa00a7638a08384adebf848d0d7da552a6d7870be16153fed2b2fef46264653237f9d98688a12ce8b3aab7bd1a66424f0d55f310506863ccdcd65aa5d6d45020e9939fe907210b5028d30723450d5bc37532ca502160fd385cc4c64a8c19987f62e9a4c9b8bc430fab8952780d4b56a13a509ef1d2ac2f9421be1179e6f27fbeea7a5f7925502a82b6a4557554d64793c2150e0041c27b01e1d1f25afe6b94e0b238b9bb44c1705305bb066e76a410f81b643d4c0d2c9c80ca95a5013115649242b3ca8a6e8e91d84a517a5c628267a715871f6d2f0c0c91d5fa60dc4132ec880fd8e469c7eec6dd12c0678bb32b5227cca3ea106a410f6854e02da4907016237eaaf0451c92500f08799929c25688dd2aa12ea4d11b3e64109711294a348f9caaaa1c92743391f80c1434930ebbef16452f089c909d50525388b1265a59f020fd2a82a08bba3553c898a1e3980e58600f9d41debc57042985a18144a5fc32b554db68865cd184a8b36e6e19b20d7cb05988cda9e3f6f66df6eca25b21d16707f6bc501153b43e777a6b6a897a7b3003062b7e064658b731a520775ef28268276928c6e1218a9e61402300e19286c618fe44e9190e7402132e8942308647517a0c078dc08549361423f011a1df70d0114018c932e71ac928a380a54db6528ce54f95fe1b0f1d819497a81118c7ab483d0b131a012997e40846f122daf47ad687e5567eaf9b336519069f48f853970fbf16cdf1b20d0f7f11dc2f40d19c391371ab7100a5f71a40b73c923c8a81a0b0a92f62a14371f8db6b0f29d3e0441fc998380c5fa909d4be5103710da2cd5a8b568c7de09086004a201e6231446ffc5a8c8005d8405c6260886e66d729ca63d138af9c6f3db46f1c0c8f937a013def312839595769c5e1eb212d284ff5916e65219f4794b9ba84d2832dcb13dfc30c3b6c9f8ad974ed78eb322e56c328208b7c49184aa076e469d5297ba0149df29e6c20ea07d88eadd233d1cb2040d08dd1d4ac89d223da7d777a947385ada5f0ccb36e6127296e1a4cb9765c59cfcf4b0697e1298c3c85b9be6e7212cf9dc7f7d1d4e57c7d2129e808a61564825e9d0efa8157b8b4356236b4931dc95f003aefa632fd089b9629e7021e4aaf1859ffdd57e38d4d8ea6a5279da3904c1f247bf733a33c93f08d3c8567c3a8ff0ea10d282bdc48b0145a8751988e3c24a4501dbc36b3a6801b7fceb171082abd59129d13d9db1992ebf4e80a3ea51a5e6d06256afa467f93fcee106b7ced65899a249d8a12a656c86197d40ed11dfc781626a584e4a2d67b488097470c33034a993286592054b29236959c9434184c797fd8affb2811f96fa8d4e724919982f00de7d35ccb81dd98e20514702941ccac339b05121760bcb4a32bfb65edcaa84bc905b3a33dbaec0a62cc561cebdad4c6d6166db746441249492425b70c980872082008f26b6189eef20c52e6b834f58e15774f2268ffb814a378cc97a42c715806f9b2a22529459196393ea1adb84fe8f8145de608253e117140b913867c820203f2a4658e481e8b4fa4cc0537f6a0fd7d86967ebdccbbeb1de6fde5fd91d0e03c31ef6f83f3c8bc7fec01fe70368620fe1081884ee08feafd6310f0e7be7f1401fc81bd7f1402fecc3c4dde4b34cd4bbc5b4ab8aac4724aba57e2bd92ef95a41e421d1556a27a25f7e5c3b012d843a88395ccbc7c2049835f5e62d7dbe841edbdc0e44f2d3f06c3e40bc3e443cd7559a8e068c5e353d2ed7030dd960be685737145b7f5dbbb601aa2cef56d30115c6241104d302464355b5eb4bbf69de4ba9f9047d39eb3cf7179dbecbdf632dbff0175eaadcd3b95610fe4dd26b37876a5836bb38472b7dfd106136d430cc18a1532229bbf41db025bbaf5372482523421ab79f80171248ff9aa064f51fe11cb9395edb9cd65d51437c60613452c4d9a5024b3f91a4c947f90d5bc7d45987f261c1793ff69fc76265e8cf710f6e0df2b6d79b8b7cfc19e7ffb10f2746fad873fdcfd3f90dbaff15086f1dfbc91ff1a7903f9ff6ff2ff6f80c6631c6e8dbff9b4bf1fc99ba727f0a7d6c837386aa1f1f9e67dd79ba35efabbc110e2d88f5bbc07cabc68647fdacf382669e0234b5c98f7347e890ce6652545f2d3c844391381321f89e30f65ffdb27e719f750867fbf340d0c65d976cec4634d3ce6f9adf460b47fdce2451c1197e5cc65b9d18a7c9c9d89c382c8e79ecb35441db578cc3f464921dc1d6b708e25643698c89998c0033ec86ed8a91fa51dfe442d11871911477dff2816a28d1fd1868340060a2d462044193f84600a1934821250200882096c0045962111877c7f22b10789c4f1e742fb0e118836fc298e8101363836f1c007566435f89964367e42ae658e4fd18623913d110711cb0e3f885c68ff5595b8c2418cf2226712a3a29619bfd9c19287a4e7c387d6a7439238f3b57761a21c5246202372fd0ddb134c6448b2c7227179fb7c2bef9d985fe51d7bbd4bde0ff337efd7dd3aa49d981c7b6528716e0705937707b57548b2c78795b7cfce2aef9d984bde31bd2d520c79ffeb6a1649cf2f72a16c896c7b67128b3e166d44332d33a94fdabae41db5cb774fe00f65fd5da201498a61f459786f9906aa5b5986209a93c033f4f63550bd7d05d25b910b6550769f2816c9b82319b68f45bafedefec63a9f2049e219d205434d5739e949f640211829c1e98c2092f043936c7eb5227b96c4a009319eaca4600558c44036bf42c99e1c2f9042c61259b48862816c7ec5227b962091c4842424b46419421164f36b94ec815974c0c90dcc20020974c84236bf6a913d4b86e00017219042074ab052846c3e57247b6ca228c30534e0620733c490cde798c81eb883a8268c08c1105aa450826c3e7774f111a71b71d05095774de57debc7767ce057647b8289cc5fe2a2ed0926442b4c1104996798910db8dee956a97871ab95fae4b11fa7273d3f49be0b13d978c1831cc86e70fd0b4c93cc75a428b5031cb6c03c4c268a0105275881cc336c8811106cc812d91019d11299ccb02146301f031bf2fa8e8c2d9c9828020947b222982619cc8824b2010532e9821228c19428997f4ce2cc1f22710c7e61182138e04cb84444030b64f2a10cb6e32371e6c760c87c18e603cdff51a5c80bb655642e2cf303268e641ed2ca6f9cfe9a9c73fa9c3eeb8cd1c580509b3246f7424699297d125f557b8411b0163a8f4f29b539a5f6dbada6cd29f3a6416f79060d4ebf5293526a187accf3388b2880158f304ae9133ee540051530ce39a5947206b1fddce4776345cc79e69c1ad09ce7e646ca2c4e4a4468e8b129b322aa865366424c991d4d215be08226eeb5bcdbfa51832854b81edc4dc3292d58e2a6753d6fe9895a6bf56ecbc8f6e0c05704203a261e0f80e08aec0d7ca8513a26ca29e1c4d18f2aac2801a5c90f2bac34295262043efca0224a090f1c35459999e1c38f2ba088c1c38f262b5eefabb6b4008289205823be2898f841d6d0090648dc8c71a38600c4d909e26e438cb64c018923c5b831a87084bb69da6f5f44fb8d48cb30cf4a8adcfa4b64f101f047db2f4eb69314933872c33fe46a0b2452be0d3206299f02b268de5a5daa1139f0b838a5051fd8a2d5336543207d5fd09c2ef915094a24d0f2b79b82a3aad13041d71fb47f0fe9eeeef16589209021450ded1f77d060891eb4774fc4c4f8ebcdd7576eda748f13a9e618a3bd52c664596e943b5958187c0d6fac0aeac4871fcc2a1d1faae00fd445ec861d8bc7a07bdd6ea6fbcfec4c1a7e7477a9dd688d86964173244dca23987dd032c82d1ea95351a234c6faa4ce58e3a471c618a3a0b01e25e357b47b171e8535a8a94141695050371ad426b5ede84683aa5b8392797f9439c244940675c4e9c623a82d6aa3729368fd24c560872464c002263e78ad80032db8428922aea480e98a8a69a91504a623a49ca4c86006599ecee0624b4c420e4b20c1881cc620838a107c565081c3a5400012c2dd7009a8c78f166ced349c328bc2e2a4b32648592b9840c0bda6ccb89861313b7037a4a211007bee105e1f930c2872d4fde662ba4c85f3813818f66000e22000f6445843a4124365458583c537126db850d44a7ca47411a8e32f0475cc49640a42b8fed186bfc45db4e1ef3282cb80225edc7d110071fc871003c3bd28a2fd86541000bd8060c02168d79c3a8184c4ea8917b7c2c9135242b915484e2e1f216a0b3e25e9a94e498242af349c9204e5f5c4851623d4b418e79cd3e7a66931ad84d693c3f58f484ffc5d5a5cdfce446bd1c5b8d1e784316f77fa33c43e30e18dfcb7a9d2dd3d4a29a59c5a8e14c27c0f7a2dbf3b122766bfa1b7cc6d7b8f1f6d50aa697366295fda481a347d67645e5209736a9ab66d5556417dfb1a543d26a79694fbfa56c3f3b95af586393d25fc5a69866dd8833a1e026dd3360d420865529ba269dbb66d9a94b8e531cddb44fa7a4c42ad21e4d9b292979e5868503b16e7817f8489eb587ab42812c75f3b1ae375e576e151a854a51b45fb9276d4b4abf61d190079a350236f97af79a8eaa403ecf049216f3f008e9fe94021ef14be1ee0672e79d7df7100979fa18083480ab55614089023ef1d8f83488e9fe148216f003c0a447e56f3aef11a91ac83d14c7b02e48dc2e7f8d98ebc09f0386279dff813f2506dd5147c7e471ef2fc75e4216fc7cf74dcc83bf629e4a1dbcafb8477c943b7f53397f7c9fbc6eff899e79dc2eb78890d906b9e258425f390b702ab266fd6cff9b31a21f2070f519f9ff90fc9337907a12fd0157ede5ff02079cb3ccd4357cf66f2a6bf7a61f5b3a0cfdb075d41a6d21ad4e357c8439ecc7b85f73ce4c99ff9cbe43df34179e8ea19cd5be6a70b5907fab3f93df296dfe3672be4edbfc2cffbe4211a5459b5c6c707e521ef27efa0f7c943decfcf7cfef3feafc94357cf5879d7fc2a0f5d9d2424ebc0fad96ae623ef9ff7f1b3a0bc7d3ee881240bb8000f04f7fc0fccf3425885f711d46305192ec06bdcf34098e77960157e072ec0ebc03d9f03f33c0eacc2ffe00238d1f07d70cf114f1315b23349010502ec609bb781697e0018f63a38e673b0cd0b00d37c0030ec7170ccc7b0cd9f80691e0018f63570ccdfd0c8f8b14d861eabc1347906c388d0f06570cc130dff85590f8357ff8259efc2ab6f6156861e73c12b57d2f02feeb40a6f2088220a0c9dc27204383491a13f4c6dc0840b26b487371de050832cda6288a190af2f3c75e1379c242413459990d770d20b99c865427ee2241732919409c946d05590f05bc89eb727a1e1bb2f05f11a30b0d0850b9b94ba250f13794f547faee2f7803c10be7ce0dd811508f2402db548919a345da24df0a7d3fef40ad84391245e823f18691553e41edb947a36a5a02b58a0628c42fbc32b58a0b4cc3038979ab616401c7f28a044a1a4fd8a28dadf6e2d803d9a1528a0342c48fe6d4a72898e4b10c71f6a3fb3e6e4c9d18e1ac98e7f83dea09e80481d73d53ed7afd7dca2b427d9b3d5fab41d3d7d3e80823a2dd0fe4a4854290a12947bc612776f472f48ddf2d80dd23e62a8b5979f90ede9c778e5a60477c3b241e964b97bfbad4541cd1c843231da8eae68ff31b26c475bb428d9439d2a9528da45fc1f4045c99e2540fc400429989501861311325ff2012b4950b20022081c8890f96f501b9658ce1211e820c40cc0e0e14a174d4614510693144c4b1c0105122fa94877c144cf68e8b48330dec3452d1993a2964c165124e7d17e2a69340a88e37f451654077409eaf8dbcd892dcaa684443e8d0dee9647373cb6b3639dec60d1a2a28e340cee91de9b12d35393f36ccdc9c9793645a24fceb3b526ed0f9f9c9c677b22b74dcb0c3d76e43177e2311b6c47b26753da8e8e644f95f96f4f362525ee2bc1294eb0b414450d6cf00593cc1320c510453f2441054144a135398f96619222490a45f678397c7cea122fc364861df19efb22b5cb4433998b78cf6522d8102651c6fd1bedc043c665986412655de73df71ba8d27b2ec3641e629ff3e81174094e7129148ae4311c575c24edbf2929bdf2be4eb40b4ac5e3be6298f650e6e11f1868c93e5d829b94ffb4a46528d9439b362caffbafd8d3a59896bd4169a74b12c7573b282df96f4dfe9bd21685011e732b30201a19641469a8a58d5e15a20de10c2d332c860878cc9f3e512b7489366947cea33d913d9c164543d2ae29e925ed32479cae1769a8b73ca24df409d3256a45fbbf04810921e84d97b0e86e69f30128450b3de8ab78840a4f444ca293e8b2a5c765f17d93436818f285a696db4ba85df0eae517b4b2fe09d11933aeeae1a7befb9dba73dfc22f089641fef6f083fd80daf391a79af396fede86bf77fcbd44227b623eba622b470d913d3139462e6620e9e33e17e4d261a857587b7bb5fcb47b1586d58730df817277a4818eff651b3c16dfcb4868f0587c0246159178080c51f79f787ab8fb6a3cf3426283c3dc91780f8f0d46f1281231868e0f8fd8708b8e3b3a41f24d0e29125f5ae951211b121d464b5afe8d2dc380cc1398e8f918095c2dc005513c0675905843d4db3b8619a1e10109274845b2977fc937bcfccbeb305ad276ea305aa2c1797418398fcc49453a8c966437bce499ff6c7efc0def255aca7fc133ff89e30764e30149bb10f8371e7b8f45c5a2f891497c2436c44fc84e186768cf45865c71a15d2dc005392e4f4d61a1b6f23c0645c367ca42b6d4448727b2db53a3e8a5a3865858597a72c367694a9e2d85d0febe6513f98408e79948d08e453ef178864e12631402feb8f6974d9c074e61a2090fe481b6c2464fe885fa3921c1914c73c27ac13c7cfbc2528c5b6f0a4bdcd5dfef9efec74abddf803faa7759adde654e1fcc778138f15dae773d84ae08a5a38c32ca2865b4d1461bdf7a31c621b207c618b556aba9f510b66af5319ff54032e2fb2f78f52ebc375cdaf069c722bc2392def069c9853559abf72fc8ac828a26f4ea6df45cf24d0a50c75fd7e0dea47063c3a7f8ee7d7cfa9e02fc118a1f757c0f0816738e1e3d90efe1997fb92c5da8b7b34c70539fc37952ef1f434b7ae0cb49a2d6fed22086e803ddbd7d1fe858ab8c346811ef19a20fb47d6a2d358a4531d0d244140bb068464049b15483261c68f95cc46a7dbde847cc79dd773d3ce640398a626095e0b6947035ec02c492a422b8d882044830e1044e20308225b24011418b101831e39c128b238d4a91f61c118aca13bd6117dadd890a13bfee3980fc29060a0c8101852a5e18ca6030943db9dc15458d0d86716ff3b6044b527e0af26c2e270942bf86a8b9a72f7f831de4d9bebe7c87401ea5c5e2eab1cafdd4f685d5b7de06c38ad8c4a22d599e6436bf44568361456afeff33d1cd15b29a5f22b332ad7797f7da13991cc79fc56159bdbce5a7bec335dae0bea0d497c253c7ef7b0e47a6cf3eb4dd4fa1fb326fcfc9c963cf7d8d38bce7be8b3852cf65ebe43126ee77646aaa11c7f6be461baa577d3f3da6821e5339314d8f451bf253b88b36e4fbe743ea2e4b0cfbcb3df733384af1581426e7b1ef4ece03715cea382c3fde37c31813b01a7e12803a32022bec804ec3af01ddc7808b8d701a7e08e0be22545ca81a7e42ead782930faae11744bf1e9069c7a6e1a703eac81c3978e0a702d491376e0c606af8e9401d9993a3e54f0c00a9e157437e373735345047ce401df9332f5047fe7f41ae16d491df4a411df9367b155f1a5ec534605ce8748228bddd072d1feaf87d50474aa63babadf18a716e337a316a18d67153ab56b356e32a475fab736f5fb74abf761c8d316a9a566bdeb4a31a716689c60877be0a6c6cc1e95e1738d1708a134eb47f8f86539ae862873b33e3939303fec87d43bf665086ca8d513ce96d731dc7a7944152c68a8d1c6ed4d14ab8511bbc3c569d26ea7e1a3e019145c30f88e3a0a5d6a221c295923acf6c62e73a745791b79364eb0bd24e93f86e2f654ca2cd39a7f6c538314c93b3b373621857374d769dedba099dbe10d4f2350d2ae19ee2f9156b5bac229c5f406ab549259dda3ecc765c9594d2ac3df5668dd58b9da7e11ceb713457886045d3979f4b9be99ee56998fea6611a204c1cede763be4f0a8562f4f696a53df4b42f488b1af5ba7594520e76b1ebaebb5673f469f23bf274e55b6bbdb86979476afaf970dd8216b77efc1d6bddf9707ed45f90183df31eaab8fb5ed0585bdd30fce857192b171bcde6eff0b2ef55dfeff0320fca934ea5766eb8ab50e3c3853f312ff8b33515e91dd3dbf65446d8f98b1934635ce914cecef3c2ed0ed125a386559c90b4f654c32a4e42e8a9b94bf805c1d25cb952431ce4a048bba276e4e96e1ae2a04a187abef61980489524681a912a44d8e016656a6740cbfc6a596de53eb2a673eeb94d8a93484da9a6bd9c9206b1bfbdfdaa4d89ab943389d43020f4b7a779d3a8d6c58fbafb82c0e898f7907d6b2dfda6f5a6f42f68429dc8046f4a2925a59252a825de7eb3315584f5f7397fea4d4208edc4da731e749e9576afd2df6fcbdfe16b092194b3fb62eac7e89af79086425dc4cf87530d9770d2310d9d9460d2b6f3dc5b1b7e7d77e8737bbfb7dfdc4b0cf3364e7358b1e70de452eaf809c125c01d68cf1ddeb17bfbad25daf3f909c11dd8cd4b322dfc7cc025e824f10c21c8045dbd905ce4b8186fb6fa1e6e612dcf0ca10ee4ece759e60617beed5e40baf73c06276ed12c83e796c7e0dce26a73699301fd821c6a7fb5cdb7b8c94dab6f61a51a8d34521a638dd41ef2dfb43c65aa5cf8efc5d61052b248b922058aff4b4befde784931d2f2673ce76931f1f1b9e2692a043de79cb349cf397fcea5e8858d34bbe638cf44420c8eb4572f4609c0169c3cbebf955f9074397f2e7c0ce3373d76a5aece03a37b90851a851e6abca1c495a94d952af2e256c8656f7abace3b7f4e1e09e459f440b72ff852626fc125ebeed1dd9d8a6ec163f03d69064d9103373e9cd20493860f5316ea1ddf003cb8537b513a09d535b87c5e4a15b5077fe2478fefb328de175cd170ca0ba8e8cdc3aaa00c9c68384506465a001a3ae1a00abd73c3e36780cfc126aae61cc789d1fcaf992a13e26a5f43d472572df3872de7e1c242e7e93a2327fa47dbb736ef7d8125df4f6c93b8ae78dfa0bf7d811bb4fdf8dccfbcedcbf79ec310ea78797f2f3f093de38c339ab097e82a43cc35c4f99d5097b77dedbf8fdf0b3f5fdeddcb7984f5fab27b20f7d84d798113535ec0a4e77bff7d87ed7f18c88feebe5a1ff57dd49fb020b37a6ff3f6a8edb66f1f487a78d7b798cef0a3bb6c811fdd7d979574f2a5fcdac5af9bd6042b3a38810463d0f22d6cc51b2c41b7600c9a064dcb398bf47643c31c6829d25bdec9e16e988679505b691f8853cf409df840be3dfca0b6d272133d730b472da9b02d98d1c2961bdf9b02658c9b98832bc2288ab109f2757570e3c3aabdf8d73fe67ffd5fce838537493dbea01f1e731b28f8d1c185bfdf7ffbf83d9ce73d16e14f22bdfd67804d494c5eb6e51f8e131fc87b9411a3022949140104077a48824187a22db0787203233435e1448c4d24a1638e9ed2a76cc285057119f47e21d2afcfc73e7717209810b582262598f285173a9cf0431940fce08a173578228bfff1631b0aacbf6f9edd7421cf5681a7d5f32a00cf8e8131ddd0c4b48dffced292f679a61b3fbf7ff2f6c9dbe14b0cf48237719ebb5b47be4348268abf6f907c071117f2ef1baee43b3ebe43f11d2eec60f2321732d19409c94642be8597f9999a991cbdbde8fecea1edc7ee61785ebfbdf691fbdd72fd7ebdfc9eb989b57ee7dcf0c9a119f0f1c8c78f47b207868f453e0e7905fc7e21e0774cc722a11f0f84051e383e3ed0ef96fefd92fd9ec9f1fb46c7efd88edf39377c7efbfcfccea1375cfadec33c0458e1f3ef168ddfaf9bdf3328fcbe49e177ecc6ef9c1ebf6f04fdf6f121043b145701fe0bb026cf64213c4481601e78886a8c030f511dd8f110f5c143f487912379c7da78f1105219f9c1838750de2a233f585880d033200f206ffb3079a8eae4cdc2770be8bc4f6801423f0362f3f6be5b40b7002b7444c8e6a1dae56dff75e4fb59a7ca43de8fbc5978a1233f7e2694ca7b00ff1df999cd5be7bb23ddcfac9777ea7ffc8c85bc552f044457233c583002c4080b3f03a2f3de791e466c1879fd0cc67b16be07f240441490737e13c08bfe19108ff7c14472741eba4044b69f098047de3944806409e0f130e400e48d71f2963d97001c3734f2f6e791001e3fd3f8b904708f23012e1e4670def95d79a872bf19c13fdb72f27601e52d7b1e46807ec623e71d80c7467ec6e58df39b11ee67dbe79d1fe867b2bcf1f3787901e4a1aae3711071fd0c872c0f793a0f79b29fe997bc73de9587ae8ebc05f03888bcfccc75f3321aaf3f870b08c8b1d74ec85bfb562bc7fb10206f9f778fb5b4bc5baf43fbd909efc2cf7cf2ceb1030f519d74001c5f24dbca0130c5cebd4eae94523e7938dc7b57f761f5fca66e2a359d8752fbabafb4ba54aab7f15e9a2bd735acd20492b64ffd0bd757ecf256a5fa825c5f69be70593dfc54abefa35e68f805a95c98c65c720e2e325572a0819c7e4d1c69fad673d95aa50921347ddb39f4d4ce80b6f9c697b3c3caa12bae752febb967b558a9d4caabdedbca8211a652f7154e82f90bf3f1b39662d55b55b4ffbd3c0c868ea3caf1d896f4f2aa971b509034d4d5e6540e4c5a05d2f598227cf45ead5a7f88311231678c33c6386710ed5f1efeef35743b4ddffbe2fcb66dce6dce39a7f613ceed9dfeadf4052f7e42b81dbd5b50d30cbd562a6edb9c53e32ad566d7d9ae8b316e94ea38e7ac91da4379cfce533329a0b4b7529b53d328534da2a607164bb2589ab6c94ff55163b156defde8dfc8d93922470c2d5410450b1528696af38d9c9d1c17166bf5dcaf5c569ed74a5d0cb5ddeef63b1edb623546dc7d93a3b7bf89b5bc96154f7af3804b302068e29e3763e4eed08f6061f4208d7e325b48d9c52fe826b6f91724b789613e9c4a39b72ca9c43440b89c6bbb2d95c4539040d253ea7963b7bba2b54a296b6549585bdbd3537e41d2ca1b8f390d13ee9ed9eaf4e40d0c09aef466aef180cb4ecb534d075a50762ae90d7b30eb0ca2af19e7d17edfd052474b5903cabf813ff37db4fc96c75c88ebefb17d839eb9474dd3dd9e56699a37a4a2ca3cc6ae071d6e07a42892a226870eeca81e4a4fa5a258c68a87631ebbf8e6e6f75435954a71412a4cdf3f950ad3bff7ca55eaf3be8ba1f55498e60befbb9c8763f40bbaf955f8e6caa59fcab31a4e490282f7dd77d99af2beef7e165634d1d66a98450978a0adb639e6b19bd477a9ef7ebdad6badf736d57d419495fa3c97e7de85e5e279def759cff35cbcd577bf729f8bfd30d4777b1a4395e7a27a954a75539fa77aee55cf3d773b16cbaa54aaafcea3faf8af2f48d5a998a0f4b641535186871a1c7c98420937fd6ba6d53aa3153b60a737658c59a311febc4868dab2a9529f4aa552c1976b385f1267fb5dedc314e69ee3384ef5150b414d3f858328078315fa32562a07b52a6be9b82d6ea17403287ab302497e1c273d774e86fa9c90fadcc3ef37552ac698fa202e85a3563d8783eaa7b010dcdee755ebc7cf7ec5325bd05aad55a53e8e6e336a185e4fec0a47fde108058e3178225ff7aa3eb6c8b8f13fbac21492a1bb4f79147b3eb227fac418c547af608038db6fdb06ad68bb6d1cfc5eb039f5519547310d10a040d170e5d26e8be221a4e8fa546a5865882734fd1c976e9428e57efc6eb5da2ab66f5bf50ba2d476d7e39ee3feb997a98f5aa6aa7dfb2dafd22f885a0ce7463f1fd6e5556a5dabf08e34d0db5fee3beefbb8e738eeaa52dfedbeefcb10ea74f97eaad457a4779411ca8b343c8075346316356d31d67ee9fdad596baddd73736edc6f564e9925a1e76bb4723933461bf5349ca3c251f6e282b5fb8aa09f578550bde53aefbaae4bd123ced571558824d503f9b49f777194b558d87e2ccea5bd663aebb13e22100c26b2b881104064d10518320871b4b7add86ab55a704b6d1bf484e984a24ebacffa8e3c5d2ddb8f1b8cc7adb6cee3e723ebf936a6ca4d4aba694f3f8f6adadb28e594f138da592ab36d93937978fbc8acece6b6e1fa828d66d3e55d2ebfc3cb56dfc24633a97a96ea7778592a56f3018ae39c2eabaff1a15ef977e786e3b80a335f96b7cd54d1ba57be5ef2639046cb95bf2f65b21b4ca5523095d47a208f9a37e33d4633d6c387b3ae5838a9f52efe59bba5bc8ea335954aa5b4cdb3d6da20fb96c68f556b9095d902db879f12d50771dd6af540fe7dd56359158ef65738c9f515b76e4b65e1f63461749eca4ba51ec855415d2713c1b598e60bfb793f7ffbc2bf885fc7c2f65de217e41111b1d0aa206fe505753dc85a45a7dde9b1ed75b8b47e36cb54b934b72ca60102c511c8394f833a1cd46150cf4b61ef2d9027b9febbea7a20b7aee5e73dfcbc215c5e0a27b5bee301a7547084869ab35e0adbeab1ed6b8cee6ee9ed5bdba73c2f75a4b74d84303ea534568e4ba53e8fc608abbbe552fed2849657c695625f14424a2f8414c33ccbd58d2691fa7b1890adbe7d20879a477fab0fe4146e5f29de34cd4aafd6bfced3558a37f794ab3889d42a8ebb0fbb9f67bb2ef55f3b15f7917234572ed410074934b53ca65d8f694f817c7e4162284e7dea535f9d27f5a9f8d52c63e5c2dfe08ff7f0e717c4d9fc823ab08a23bd6db4f690e3befbedb76dd7ef7ec310c3ea0669ad1df7dd436e83498868ad5077f52bec3a6eab39a5824c93e5ce8ff0a7ebc2bf59b9cebafcf658bfbfd6ef94ebb7ea65af5ebf5d627eb3647eb760bf5d33bf5f687ec3d4fc7ed9fc8ef9df32f8372cff9ea1f19be6e6774d8ddf361a00bf3f2849f742b0d65a4ff88efb8dc3f3bbfaf0d3befedca23e01436db117492d334ac3b241512bf5896bea966c144fe9839242523db9472bafe258c4f22ab6a1e5558cc4e5554c018f491c030c2fafe221315ec53f64bc8a813c567768bc8a63355ec5d9a358460b0d437d028e1a00d877a858090d2fbdbd121aaeaeaf643e0d556b361a7eae83cde74635706c420d136abeb8e506c732689040f3c52cf269e048c6cc1066be3846c611083030605fbc8271e4818c17325fece271cc414c95982f52916f832316af29af2f3ad5e058050c15305f64a2c171062f3278f9a21429f10997865f7401d491d10927a212ad59eb8b49c8e098021612ac2f1e714434814b095cbe48c40b4711ac82587dd18913ddc3e5e17eb189fc171c775069f8451da08e8c46d1e8869486df06521f510bd7f069f861e0fb68c862014fc3af02019ba2a804ed95845d8e3254232200000020000315002020100c87442271403428d343697c14800d82984a6e4a9acbd328895114638c518400420000841043008c10d40c150015ed88276d41117a7a0460d61701e9410ce18d295c586a92de1adc5e9a7898ed67999f504756c24aa9fca7964b0f804e00f8aa854ed18d29f1fb91a6bb512f85bbc30a117b6511cdaebbcbe570612590f4d697447c6cb0cfbbb780428fefbc156f201c8a6370053b81b3855bf4b42f913355994b8c1545f5c47e1e6e8aa8d1e1d9ca06aa90a16e94229c689ebf3c23f0ece82c6672a6791923e415fc294ae793f1b391e87b3aec3fc9f463d95a3e9e9a67a1f683e6f204492a22ff6c6dcbd10f358a6f13490a942988221c91d745855aa782099553d266fc24310565d4a04cce37443197ccec3afa5df05d1b968a680d3793bc8a29f1ecc190843a84b073090d582a8793ad1044d7132df4e0716b4cb654abf8a05622a68a4459114d9364a8f886bd845d5c1724a6e9e468b69272185fc4f18fd180922576233be2471f936bbe8f12301db32889cd35b8a847f9b78e900607e68245f85298aefd33eea1274adc4fdf22877f50fb9c8e1ac74130705898744f2a5fa58fbf2a0af624f4388a921f2cd51f7090e42be027b5ffe6d9c7bd29cd9234edd118f039819a1d0db84b8185e7e833103c88c0826e0daeb6386fedb96feaec26cd448ea612dc677d0fb4dfa2afdefa9d3a56e979a4ebe505f4f9f5b4b40a86e2aadabb01e01a4b9e8cbcc65208100d1fbdbf7783f4c3a600278a136703adc7d467a4f778687222f0706ef352d7dc41e105df82db088d538436a5d1260689d16dfd989fee6a3d4ef525503a4cadbab382bb409bae5d60e36bc118a66757e0317f2e7a132148a7bdcb0c6cb11ed9e69a8d6863f8b8e0bef00827288a6b61621cb41434acad080eb07e3c6740a243b84f87b40d68079e35dd743023803ac32b61e8b5870212dad81e72a50d2dfdaa080e6a89db7a34ea6773360bff03a7e909fe4fd362b155e6e4a6293555de64450cc947130a0d6d1a37c5fe82c5ee0760e0b4c74a41f7fd296f3dd882cb0af5ba0a59b8a817c54dcd8aa543094ca034b1e61c7a202f591f331a245a731a8b0d1dd206f4e0d784ea962088fc606d18cf63833183bd39af55dc465252386a563906478e0265e0c05b877c29f00c89864acec8fb596736fa798c575cd960f4db594a2833d369abfdd29293928ee6991a13981d4b4999c75c433597fba94398f605be2f715036f0d2c79759fc84b1623a5b7ad9bfa1ad8dea6316b304d61f931041db61be0912d2e0057c9198173e3d99d1f48cc2eb419fd7458fe0fa9e54018ccd0c2e463b0430775c088d5db0695afac57260b50a0f5eeed26b45fd438c23d2402f6a0d959b6b935c113b9e9ed0ba7539d586572c88655718bf6da7404a189aa3d36fe3225a0b4a41575a1f18c3deb7d6d03b66927780d9df3a168f654574168baa424f283d23ce7291597570b98c4bc172d8460bdb8f5f7988830e1192a06fba80cb7d4f8128896a5c32d49a5011e6540e3b2ce5727c7b53408e21fe56ecb4e57c7f887a41cd7877f4cbd490a5708f3c7d45927e63afefb1277fd3660428c4be5d8b206362c5d1b94f5927d8a8e5ed258d88ae66f4a23ac58d014857da927670225fabc29411556534fdea701013d67698737a85866a2d10937d77fe07e0964e0fbd2878d6062cab43bf17cc72b4390e8a9b8192b43053d2f000ca2a40366e5134a73c0c71790037e3099d1206c5c5b922f1d4fdb1aa8da23cd35be2a9f6f762a55cd2c93b5d69a79adb37205177f7295f74942842b61bb87898e666b071764693bec390fd80f516927abec71613693a4b20e203568520bc32aceba5586ba80a6fb80d4a38b678786ed21087b7adc330c8831111e33d0abfa7d1fbe4f8ab4d5e7e38fd77cfbec4517469779b86edc27313389a1ece64a1e85fae548a7487d19bf760c5eebdbe52dc657809d5350c8597482adffbacc8e97ed92e3d3c65e0fe7a843c93bd3c031bbdc8a2e49c5c4db26c9177b74f2be38c9dab7d0b10b13c3e6493988b44acb723af68002014dfc6d666e0d4475eea17232fdb96a4d5a6eb5b1761d4f5aaba36b5b85c0464fc6dae9b5280eb9fff86649bd13c8b4af9382b80bece7b9de2e3807f62d50753d86b1d87e36bad867d7cc2f8e394f07bbddb47ff89cb7832b1786fea060ba8e9f6538cacfa806f9e0f4103c8c9359b2afed3b64614549f00c70fe4b9389f59848d304e4443e6e23304b29a6a5573a5f95e1a017d5ebd9fb9ddb5029b8a4ae33896218f9c3e02481b7143299431c1f4c1a696bee1cffdfdc2ad47e17c0a124783ec8a12534aec1476d11e4d0dd05b5866731b3b7701d786c606a38f9c867814680690e52028ae90952747520a290d0854ffd34733d49f2cadac57ec9ed548b30dcace7396d58beefff97290bfa1c1e0f05961654cdf273be8b1328db2f8e793bfbccfe89d5b06081f7dc1c5885c2c5ddc59ca9c093b8992dcccd4e6f6135b6d9375ef66708d2c30c04a4e5fcde140f88ac63be764e542cff2029e79babe5a62456b27c6048549c646843ea1f9c52aca75217b21627853c6162a0a05b8fa7b8830e917b05be73d6331b8b47845dd369f5706fcc25a425f5dce318bf484b13aa7eb22a4fae0a5d1a83894c1d00077efe3e4300a07c5ddc11108cc9587d6862242526ad73daf9000fc21c4b23a00470942adae15ca49bd1b321bacb54bc3945a403e32cf015da128ba722740d928654d93a6f4c2d41a93e09d375e7bd5ee2d344c3d7198befba815d8a437d2389222c4f12464ccded3f3e08529aaa92952b745aafd0ec86bd6c21c50c06e94fa8069138d2b33b73025a13144937e6e3c84da3cd1ce82a82c825977008a29d11a66fb406af02e6ea7108b0f1bb403e07496b5f57a71ee808b1cb1d97b4b032c8496ac3d7fdceec3df85d85a382c97491a432bb896fb6910111367621fad882b2c562d2be70beb59d6170f2d61f1a641960efd38bcba0c9bb48685f12761661b2ba6ac747f7de80ead54ef3307d714240c3e37c2bb538423c417a0276b40faec13ac418c45c64741dcaa917850de63a20ec9831b86758f3ff5c6cbb941db2c951fbc0ef148cbe819da1d59c329a7b1f8d120de7439247ea40e1fc9aeebe704e503bfcccb42720c6fe365e466dff95e599bbcf92c4b7a0e2386d1e4051a55e35bb6ea69fc1715563f03f69b9cd6b0228e50e822884efba7301f45fb552d3ba99d869d1d7ac77eeb15eec6ffb14f3ca625aebbf1df28524b722fee75580071fa81955685a8c23ee5b79dd721f4d08864558893c4daecad5538d33d64981a5c1804a70c03299a7367e09830e17240b80b2453141d40c3d0fcf037397e46611ed461d6584da787a6a65a0e37bb563cd6b002693dfb88e3dda6db792cbbb759b6e531ddfeb1fa14d647e6be8869fe5f880e0ca5ad36bcc2c11cdc79ec1dee05a5c6f91c0ee23845af7c1653c76f327ae9ca12c900c7502b50603a0aeb0b5be4c3c9b8a24880eea602c0e2891cf30e11a98f908d8e5b9e018e45992f0ddf4586a013ec65a6111413872c46b6c7688733da6f93696c31562d2f4a4bda5238f3e1c1d8e5bbc1732055b31c6c195d7950a0548c6e506dbfd65d3f93047372508db8211eeaf16598549a85cd727ced37da13016a5ab082c2930b09d8442d3411e674c73547da4bf2a4bfd3b85e53b1ed0b21521a154a85a8e4be3ba629031e538e6eeefb22db63cd066c75021e4ba05f1776c9fd8e219529924448dec28cd0c3514bc2632c2b113dc467a9d39af50e64e7b756c5ccbaa37239dd7714edac26a03e6bb675e59ed40bf0fbd9d41b7619f14c0d40bae750b66360ea7a21b5ad62f40a74ccc57ab0aced126b12ec09004148601868367556fa19d0520dad364319911f7f5356868b257ab0524d294e7302bb24cad94d55dd09b0be39958baaf15845a7bb95ded5f3c057d6ab8881220bc608945be716507dd20ad4db3c8baca9084835b2261483aace2865267b237ec20815b21fc40c39842f23a9c43cfeab69605aeed05a001d39cdc94edb8372813cd11962d26e21175e6b6a57194e6ba26cc52db207ca4dc840500d61f068f49f07b369e72094f50bd7d814a757ae8d5a17045876f7eb9677d3ec5736ee443738986a459f5aa2135bcbaaf5f0aecf5c9c362c977a1ca795c09d58b2dc596b02d0ea8a61c5bf9229fba76689889c7af33d6944a80841ab07a7c520da1e6a3fccbe947b6db65b4922640fef56071d185402e696d3744588a6c562a1fc72b6f2ffcd50e67e03ae18159b21ce4e6e88f39f0b427f1ed3608a7069fdc3cd206a65c276cd1880541368206a96999d05d6a2600fcc881a07aee653eaafb227ae711251fb7863c242bfc6b0048423fbe10d5a258cc73070a59d0519c135c72db7142c56cd36fc504b89afb312027341e13dde95c10a5a8d5fbadeea3ff359a9e2ad641985a51728b8c73ffa05e1263b71e0aec00a4c7c9e102f5c24c00656008e4c2a9ae4ebabbe3297e5528d68399ac7648dcd2c5620d8a87dc284271a95346dc3931e8509129b3c400b3f9e37fcc5666267f41314832470a3181c84dc6510d2622d4a90dc8124b06c7a9fc4fae3f8b5515a755f93bdd19b792709653d3ba506805b1736d3709373bf75949787afd03878d8faa307669a6e6da4ad5bdde10b3068b1e837f5439557e497efce84960fe5e741c5c45bbf8265d89218a504e26dd707e3c5788faf72096c50d15175da23f16e9f5e6283eb7896355b7821261a603291f692acfe60aa549f22de862c680616520d75c44653f7716835fd2b50628313e86344b2896f65a47d64865e47b874619c49527499f93b6ef11730fa7e4f370efea6295db7ed4b361405c703b6c51924daef16d8eb45ac2873d269aae899168799cb696224d3e45e7027e9719e2f89906afa84af89a06324586c1bfff3a6b4539dc3643a4ec08bd51e4b5947625cc2de7f68c540e63e8579cabc9554ca2a6a5e0627d1787680dfdb74f9a3604b75bb5e4d1aee9f538b812fe4b446e7e03cba9ca5242eae30cc9b95953a049fcab320b48fc34e0b121c4b09a714fc722c6906d00b2e7d01c452812a52717f1d6e82a57ecf69c91bcaf4f714ff3efae57861196decfa846d096d642a2de168d9ab1b9c74be887c747b94183953ca31cbf5cea41f1b016755e109c441ec451e074551807a90b62e8f8285ee63295977f72dcded186677c99d7ab1dc4fb0368b098ad74cd128d6dfe134c949c7050bc5e486e6a2812657154d520d5d7e536ba291aaf9a9d7d213527bb5692ad9d16baf25c5a728ca8ed9d2b7eb951b4b8c3841339ff63c288d50c838f4df931eeac094e84439e4b14d14d6c62a869735f8b9cccf16a8b4677c54f3e6f01dad8638c86dd2d423f5e0f38f9be63846a2047b03fc91e78eda3926cd7929d481373cf6873bf85f8c7518398f2c62c19a842b021eeeb69144c23585a9b811cbd0db6d37e269e5382f81e2d6abea6046d2cead21b6232c5d643f5c769cf078aca9e766c60bff56e7f0e16dde646c64de9c122f422004b642c14a2e3d12ab33e902a96a7caac100eb73cb48bc8e0806875de8a3c15c0cc118cd22d2f4429b3623fbe6af16e556eb75571534d0f81631319c10e6af101c640452a73a55b7a0a852c4b3dee20a590f0bd56a21924cb591f6b78c5b850710b72d52f9f49953b4988de638f475021f5c31ddaa446c2f5cbcae80e3ce8197dc83a93cd28e1f24b7b63e10ddf724eaa23b8a41482406b31e64049c558772be06d1421b58c66672ec64eef9358b1306e01eacd8e552d97eb2bf218fa7340f6dc1c752bbac2bac098876b3184868f03b158d8eb2b5b733a95771d11e4c22490a6fb5c382b5936f15160cdba90536d91cc5d41e790a53577ba6024305488845f3ae8f9140cc72811df782b0fcbb8d4198393afd2f31d1aecdc43b2f99ee7d9bd200174c1f552f3b3f8f76472f29e5f9f200174c081b04b3523d7b83548aa27822bb2b1559689498c91006bb598d3e38ecaf498139ad3acca74e5066d488368305da4407571ef8ae1b391a4c21d783a0e44a261171c910c98f98e4b0bd68ad5232124abf00ff0132a4fc4c4e3b92f84eaedf092ebb78a743874df7e45c716c372fca3c6af340f4b5fe6b0c0155071dc3a304ef8992a30a17ce603f2c898a000ac525691624b70ca717de1e82fb91cf1b3e4b347d0f1b83c6c7942432ee7bea3ce7809087c292f02e6acd2c60e630a6ffddc73944f3416ad66eafaacfee58a67ab6179671a963ff942680208d68d0e874447251f9fb7138ece76c8d76b8790b0bcfe220fd2eb135b94691903f7577d4abb2121be2581b4f23edca215e181730e27598921ca8b9525b8fe469833b6ef752d2eee52b77d09c58dfb2c7e38e247fafe94f627834b98778d52a8aaab9a245f71aecd7577a7f4dc2964865168951f9b729eecb4bc620ffc00cd13aa841d7967ca72a520cb81d3c2d100ca640cfe3812cf83fe22e5a0f9d64c23bdd220aec3bef1a6e08db4e6d50223ef46441a7784cbbae4499c44605c40b19851bd3a6edd468abda9c5de7572020909a506c8b8e49af17530bbc6e35b3dededf30f1c066dc17072b4379a91a0b1c18ac0ba8ca24e915c35941c9b1def400cdb0a22a5aa799f44af183ff8b88cef1627a3f585bb5a2c7ac9fc19c927a3cc3e9e7019d96955de9db1c0fbd8d9e1de1e25e3f63125d9a3c115e6688835ed802e16b44afa840890c0aa04056562544d12b9d3c2a0cdb9694b24d6b3bc6bce68890f24629278bb7d08f84771f20b2340e83f6734965cd1b80c450f98e50ac71a740baf1ef789f3243b50d85f24e4f52ae10db214d9510122c7cb80092fc86afa7f82c75cba9cf429cc8679af4afaf21d533e7e9769b7170f46e9bb3023053583f3627dd9e23234008bba4e288489ecdb094a04602d6b4b489ccc56922aec8c9728e9a4a79f7de760fe00a4368527a963c6e959e6eb377c8d2ff9bd80755cfe3dee20c993bb054966c94ae3e5dffeaade17e4a26047dd42fa8bb40c2068d8c427abd65a0873f57a8618ae2e8ac9dbd007240ab169d3516604326403281a7e0e01f0bdaaf23514c758f61005085d9a52a468ac120825cf894db2983e63260c03fced04123e390120e232bc0de5221a002e7002231878a2448bfe8a7004e7185b2d6dd930e00c48ceed0697be902425c60b0a2e35d00cafad664648ee17dfb282e29e44aa67982ed9c21d4d34cbdf5dcc49ab03eaefe0a6a47332a024e6377f141077e2db10ede551025ffa045858f7ce80580128e92da77d23f374f609c7a2deaec134f9fe7a0e46b3fb224f0c08d7f5dbd8daec2b35201391a1794246b2f369b36abc65c414a590bd829f4751d522805dbd2c3c1d9f839d51388dd5e05b9b157dcabc3fa7c1a5b4ebeac6f9725ed92411c536c9ce386e2fe972a678408dba07b614126ca3e63311601618517633062c30c6c8e4f72cf28ff6882f815d2cba1ab3c53cb6a3d29a98288205c4f07b3ec0c791d522f0ce536d1ee4c8a459458d7bb1e7b0a5ae7c8593410b3f2d0b430c8c344cd253f9a74d4f2a089982eec1a78ec5cc0fb7ce2fd59cb1b98bf1ecab2c70cfa3603c984d73e9fd3c6074e0a9411d96694e52165f4108121afc66329c3cc60869f5852e2d1c0476d45a758f08edb289e38f7d38edfa74b6997baafd7a4b157bb9b1166cabb18b3e1b3842309178bb9c1d6c73208563927b8c058d0f5c27c9b90a3bf058317fe12e1ca17c8943cf089d00474e985065034f654559301354e7ef5be0df7660c89c9ff9d1f380f77c9b1b6e806e87df7890f96ebc308bbe7a669bb10046d231537b344d9140397a862461f293dac617e58989c05ade1f23166c966d2d6609b99d5a98313353f80f9d08c10fc046d402d40f1c0985e6e6911760ee4447afd8e65dc96870eb3850b589595702bfcf563f4a2a11c16f7608ca11c4ee01e226cff0dd49049647db5158c920d28fa426b20d2cdb80bd6c12cf9fb013aece10ea68be900a4161dd1f644ca4b5458d9afe6b4a23b4fd6d86dc35a85b9b5de4f8f12df6fc3e3f4f300879904a39417110a2c781c5f1d53f423812e749382836c01c7c7184fa8053126321e052182785fcd799108211b29b7045061cb4118259f3b8dcb77d554440fc4a3b306f92e05c9b7330ec86c232364da7ae906ade102bda3a20642e11bdcc295e7d48be5ec4a8152678ea6bc1a779ff2181976c5fa6011696681fce952f32ed92a504fddec40e6f5b4bcec799a797ff1c37bde79a98cb007b4cfe03471de699a7a2f530b8c167b33a291aafb7c79e587a1e6b835ee5c5dcace5bcde4b4fef04a44edd7e6aa9601fb67e3a74ab0c49e935799fb46465c404972c8952ad3dea61015e5f16911be94549a3956b1d631c396cf440cf22a5bda3c5fb80d71cfee6bf1efb7c2d3c6d22dd8c94820ee831e4aa0c8173dc4bd3e68625aa70c31d79450c105a8a86e6be6c8d1547406543467e9c920ad209455847af08c300d05aa6b30c7d0f8be01b150c24ded7b033c64977cc2e43547bd2f6d52709a1e8fb28f87fa5d78c4084ce51e63607280807290c66dcee83c63c4a1e8a6b62a2a3942a422c7c5ccc7e76acc593283729d1cfe8128541f446ede0c59deeec242d1a5459d4fbc6dce267b02c94975cfe5c32660874f47481394640e6688c6b538ca6ce4c03df2e7018af8cc31c40365a683ac5947ec8c506f42c0516f91f5ce7a96c722ab922ca6c19883268fd7108a39980bbd62739da182025da1d828bdcc67b25527666338aa93eb450843c166eb194e9d17d5cd8d3f70e4539f8b1414660a32c88a672ebec12a9423b6d02712aea0571e10f5456e92ab0e08426246d5076855363522a4931ce48c7b6834650ff108072f158fa50fbd00d5dc7f5c027b965b1f4017eda6aa36ab76d76d101bfb651d631e9dfb2ab284a5acf9ffb4e49dcec1313d3e7883ea905fa9d8a342cd2a4378bc64562abf23437c3e49d18d72fb0d4b897adf635dc4500d00bd17c840b7cd8e756c424d3754c839849a714c862167e45cf0f4c1851506311555e02cb4e051622858475f2b7882e52c0d1e896e9e55abdad870749137424161d70950749391dd1abcd46d49575dc61c791085f7d0958616455b83d1bf0f627746770233148427b17cbf37e9c6900603e0547d84ea5054c82c364116273d83061ca4909c837c742b987fe67f40b2d5fb82cac6ba6bad6f1a4189cba2ca791d3cd05a2559f0cb39da9db7679d4f6f4b6b66eefd4c2195be454f9358f7834190f2ace7a333b3b639d2ad6634b085535177fa4faa29d649f7a3b29e4cd9822956d35f028cc459238a61c143a30988c4bac9b07929affca5050fb7bd49c7622fa6585050b3e4601e5295e37a4f119fc841384fbc0f9681d37547da121a8b95cc82e8377201fc7edc928221ee5a095516b22572801515f5538e2798e4a9d59803d9938ac6ff1cdfb7bcadcecce95b6f94159e83b3b9de4f359cb6030c58d2eacce5a5cb16fc889f6f80840d7e7c3737fd969658c32208c596d879438653044568d57c847745c466f76b56db56e1e724ef46f2f48100c1c2d9d86ad769b60ab690fe96d9834ae8369be09d3faa911a5e99542fb29d9898f9f53783f936008bb09889ecb2edf96933072ef47b9c596b50d3222123d0940582b3a00953ab804728991a763320fc480058b8a7f952a343b470e410beafa52edb9fc9c04d2cd8c7e96c0bfc964dff83d6c01be0319c33bc8685d9da4026789c55566a6b3f8da0d9e85179124aa4582a652db868c1cedcdbdf2fa6f56f1d6a8f1b06172fa843d56c5c544de36b4d76d41c86497675d51aa3327f297ec3113dcb58087eec35deaca32d76317a6092720b19fb3388c3c5e5f7164887a0367d3c2148a2e8fa2c40868a5cabc673ca202757f84cf6fefd80c5f70e91ff482d5e82b2453d372361ebf12b8a3bf95398d5804fb8862513560ee43269f5620d2b1e20981c9eef50e10797089205ae4911b8554f86da8db132a70df9a83454543bff7d64d501dc1020a51448661b0a28a64138859113fb692a947bce978ca42af70e045d524954ab9b627ab77e1a0229df0acf41b74b042d2e33c960d99d2a29586c314deb72852f82eabad03fcb04221a0ec8b553ca41b7924b76072912949d10a868b537084cc252a305990d5ec627d958962292e41f72b28cfc3736b39e10e7224a89a3e639df79e8fe7e55383d20dd1a23b107156baf19193b86184a1d83578ec0aeeabb011b4b93e30522b6b6791f3a1103007378529dcb9ca9c433163ba47c00ae07c56293c833cfd5361e63e31a3a798f48dc20c2a51f8cce4f35e0238888cf020cb170f7ad10ae4ace694331e87d0d339e13c90cf3d6dc621baa3e1558062ec33d537ef8d958e1dbfc312009dc0e919b1448e01b2cb75163de1def67c8047221fc85dd6b4433ed2b971f621990561eda06d748bc0752ffed0cb04836e6cf0d66e2426133118ac562e82369b92754c73fc531c59077f199938ade7870636183fc4ab2f4e914a77ae2b3e91ee74d26fe52facdfc4c71ad13d3a714c04cedbcad863b8f701f18b32e973f9d39c15ea2314438761abae3721c68d56398ba05be605ea9ff5214284d9faf52f8b95b1eb4b7d68a824d503aaae250420f7e162b0ddc1b3a5ca4da9e5ca8e83bcaddc99fa2c731dc7774c41a2ab277b44c222540dd01adeb20e9e896197101f413dec97866e6e176de25aab237f24fce1e9377ccfee7963fde0931f4dad1699ad4aef3b8cee55d016ce0f7d642cc788be1426d502dcccfef673f16b9d1bc854ce0d4835ebaccc3739a94a38aaa6ada30717d726f4fe0f002e2634d9f157dfd50cb90a730d1f8a3d2f02ab3846dcd583c2dd037a8a6bb9398eb10f70bce203a4d286ce15b122d2a4810ab67b35e3e72a3c768222fde0c2f75db50dec899f66953c1a8c834f45e698a19886fe7109c0e87eb9f1146479109850d3938ae8719f3c20a3b1a5de7ad62d47e424f98887a5c87a340def062a340dbeabe55b3532601e659b9a81b6878efcd87b0d2e3439cf77edec06e665ce3c1adad990f6a2bd8ec0b604d199a9fdf3a04ad590ac7385d632c1b7a951e596a2e5dab6794a2847b7aad704febe5a5c0d6926bff5e0f75b83754782148310b079b823a6ea373b3de3839eae0830c0e65d2185b7b0f89a78c12a341492758e594fcace89591a7beeb876987ea0c5642e3cfa38086148e12835bf2ea2d1e3c80f663cb3bfc014b55e677e08bfa548de01a23023361da6a836bc27362daae8a1b13aa6eaf7d17db66cb41fc981923411bba2d389aefeda25e7b28a8877d0cdf941524b9f99f9a54fc24dad6e33982a8fd662e1595eae2394114f9a876a08eb20e88ea8249c5b67c85ce663802e08a919d402cdcba6f4f10f07a6a0b954748888beb0a4dcb22a94907c540cb6b2253858323cd1f948a13738809224b200e47a673423dde2cd0b086824614418d5e71aa36925525e5d227d7ade0f3ab08410e2175baa97be02423b030e1762748e6ae6bbde4ce417d6c11cb1b7153d816ef16687820be6e7c7860c702293802540769b27d09a154e92d2a18b1a38244b32f1dcc2609fa138ff681429c5e540ba3653dc9da50e9f1fb76fb3efc49a0fcdee830ad4c522783b611c572562ab0a4e050f41f360c90c25ddd730148bf8810e5b3fe138fe765cd2b0c103f2ee0113bfcf071e92c3b7bbee8ac1bb76883ea1db1002aa41dd61f26f6c9f15132652ecddf46b7d6ee5d8478e7e8672cf6f148ee92c8e3a3035685fc08c4d52ec53da3ecf398ebe7033c03b299fd161ed3f10e92807c5df3a094fdb6360bc7b5cab844f2054be5526c87a2351534f93fb4b458a187abd11592b82b1447ad25d71c6fe32dd06e036a4f1998fd2086318daf57a082166e3f484d3e9112e934a6c04b1313184041083163ff6ee33052e02fb6158a8f09b2c00acb8fc4ec4e819158df64e435b8bd1a606a9011a610bc3e94e90e9a5716ebf4ca6619a5cbcef09764e2873a8c09d931e36ee892c6e5dbcd43937c0509ef518abb819d9fd5ad0935286799d56c57d1e5baaa3eb232865d1f8d4dff3f6d78526966002fdee583c98c8058a362c203cf2d52a8bc9848d86836e8b30450d3315698d8ce9d9142d4440b6cf614c21085d61d85098326ea6bcb26d1634e0c32850bcde542b5857f969268a3de77a69efe85c78093d8980c53d2dd0e77f8d6a4e781640eb5a18343009069f252a62a8b74510fb01708d1978a9b1928f3e32ab454501a078a6468ae39debc7e206a845018539ef659d774a23d77dd89a2fbbacebb4a3178e08a5db867198f5c0f11b32c9d7dda038cee81a2be0ec5dfc8065d2e45365cd0281ec9e304eea0cf81fea3cc559c0c0a9d20695778eafc277af81d19856c285f32124a6146bc089463247f8306ef5159917d75adbe38175b1fbc72b400df8102ddd83e314ce574cdf671f898e635483e12ba3979c543186c7391b230728fafeceaeb75b70541df027b876414b8f66f05602d9019f3aef9041f1b997e481862f5577eaf17a19ecc96b88f61a499aba30607ad05a674bb72a0958b87f9a620ae639cf1fce2c6c3c5ce9b1f476b5954c6d0ae4f2ad84347a70497a3b7beda2ef84d54247a70708b6946e737437cc9e65564a830c89ee03d0015e48f7a586da74cfea25321a378b2e089831989d35e98d2378ea2cc7860894577613f1b1084ea9521c8143306b9769bc819e948d851fe216234bc50491c84da1be3f55f9bd8fe260e6dff00c8208ac6d32932c1ae292cf7802fdbaf023ca0d5fa7e15a486303fc89a122153dc61508203c500f6d002e2e155a6f5345f0d146f9db4c043e42708abd793294316c91d4779169eac0270a2c5b3e7f40f8b90985c77e4337d0af84b8828fba5b0dc0aec36cde530297555bab2380cd406230555e13c65593b76a9c97c4a391f83b9dfa1cbfd34ce46c47cb4dd613016e8a6d3cf81f1cfd315fa9a2f7a2de418ccb2f13786c4601380036972c6c43826b29d40d9aef96c2ac384cc53fe11c360162d1b6c0a941131bc70fa477e97249334670bfaa4254223b3b530838dd400bd450e191371bf9dc1da1ab792a20d4e29ee5410571aa5eb0e8dd3e5f27c08a955a7ccef7b1559469c4d7dbf2fe364b7b442f301137845be56a3a93cfaf4bcd9d55030c138656bc8a6d286897fc8d231b80c676b011a3f3c6332313945077caa677cb65da70f0b641b51e29ffd936131a4ec692b8e21471116d1075570a6bb5ca8c575bad111190f1f3ade2d26861aca18b2112837e4653ca10801c24b1d86e068d81c90df88a422ea5c25b4778b2c3d950db84d3443c34c4740b66c90be302fec260caabcd43d6718f3d36000c9019189a3b869639f96f9af72201f08231708b33fd3f09b9ff99c7b5a31b1176ec20ca20c7585506496dda7236aa669b1909b7982f9a92b37fbbb977ccb9e12b8d5382b3eef9bc402999425e73eb9ca57a53f7436a6a9b46867ee393cdf46d49809a2ce81602a1fd3049b37f0258001fea0eecf71dd936276eb15d746b21a7575a5fafe5641bff0c89862245bce00f9bc506cc46c744c6e6d88fddf1788da2f912feae462858826eb06de16a582c62f96f9e316b2771713947db0378112bfa20e2ff6ae59be8dba8985a0d84f08c4e1e8b86b1a865ae9266241592f316e167286cc7ad798cad789a3c615bd40475b6c792841671fca2a76b072bb99d393ab8b8dd7eca538791e9f801ab48e460302ccf7f21f517bfc1270c47668d142f3e5cdc4041985826175b6696813f06c9ab5d01d18c3eed8ae05b6456efdc2e65594dedb5f3bfb9dd083d9c6571d7ac924daba2471cbb36e959a45773c88078dd9bc6d23badb5216145fe5d478f3bb85c02b53f3ec1fb116b56e043ce871ae05f0ee4a3f4f487c4f4973a9adef8c74c66b82ee1c6caf3ec719aa798cb030cf198214ec049c3b7b7ab8de0010ba4239add21036ea2c0caa13aaa4ac45658137452b5ae02a694c6cbcba44b9ac613802d1da76444fbd065d32ec83d2a0451c9604cb14c5f7c8bcc9f4a2e6480986f3c6c0b7f6e9492f618116905203136fe7ed28f54963b468362edf7e9a4fab6e904050eea0068acdd8961100c038d8b77d7e136291d3187c9f3e775b5bba5ee3526bc1d79495c78f2afc24fdaac735086b4e0fc3ddcde9782f7bc3fe08d587addf4d3ea462512781f9e465644a2fe5860f70c7798a9e30abe35ccb090a97c111609c24e49f772c5e4178266737546a7591430c674acc4252815b9e36aa0942c25561d6aebe248ab02661c52b759e7c5db16198e9f98b771ee904a13ac06f2d9466b308f58db64af54a5bfb5fba6a8daf5627522c51a26a8b374605f271f7e17738c527c6e9548841ae50d74753e5f23383743d06b3ad4dea2e6837941f8da74d27cf38dc3788540cbc92a31828d9e350d4462836e07eee72b76307e75d2220803d774c8fb99ac1694e008c467fdb4e4644bfbbb6d9862ef3f5156a62c0faaedb96f39b25ee3f311f44b39623c5356d55eac2e69af06fa9ecb0db8ae41c7f10521e03be61b151ecc89825cda7ef94bf1ebc5e47e49f26e344592809e7ece2137bb2741b480c92d535b2c0b8044ef4c61a8d3775f8872118e41c10ad257c4b5977fa25407c738a511e68545d2704cd209ce316b7c3202d6dcbc7b2a582b438a016e21e7edde494029ced3b35c83a81f02e091d130a24ffe384d4a5da8722d547617df6a3297c26cf95d54eca99a88348e9e5039a1cc890e826b83c02dbfc70eeabe40f1cee137a0602fa355b8df02b74a62adc4154a71f4bda164f16d11a80be3b3f48fa11c4fa4e7f90998cd121714ddabc45923b497c57bf7d20124050f015c6b5998d210fd92eb80ccc9d7c275604e1805e49302630bc110baf6491109e006822d436e401e3caff06fd1f9788239dffab9d432c51619cf02158ad9749d73b4754850271f6d66ad0361b0d07ece1e207e3eba93e5154563200bbe6445485645df9a4d427ab7d92a3c3559cfa89368ba1f5a95660317cb52e1826322fc0c597af60d64ff0f0398c850cee5541568aa91f5f1579e38870b3d69bc727fa5d2caf71ed60e50b2ef0f1110351f9c94f4905cadb1bf494fc3bb9ae48e81cd53e4dc3a509990956e6b2ef67b964682c19bc8fb6eba6cd61b511d2c760aa5acab69de2d0b191a2e5c9553232980708fa411a61cc6c85e7d4ea0d78128d61cb5743e39da59a4db9d61c0d0b41a15f69c4e5d1492130b3130fe3859269368ce7557906b7a429ff79e028ea888a10fa248cbe4ed63aebae9f81976cd553cdb9d9f0f192d6f0152d7ad8b6dbe5a37c55237a2ce77b1ae02d11f47c7d61c2a8f1750166bdeb6d80d036c92782ff00d63a8369b3e5644e7b909de0436b8102b4412e8b1c08add8ba5f8649472b5a508dfc104d5747b6a45afb272f9c37d951ef411d849fbceafcd52a73a8a450ef3249a85702e520ac7cd293be47b913cc9a1c4219a5499d6745954d42b60d992e6e30a666a110a7e0a09ebf1af428fab2005a370c78c4449a2cd8e3c4e5b1b430ba2bec74e89b09360f41a4a46f39a8ffd60947fe60ba3a95931495b8a37891b1aa1410322d41094580b871dc74074057a7fadbc85c9264e297796867bf0f37727cece2dfc023dcf970ef6c54e3af50f2872b1e4fab5b3504ba8707d27e457452157687617ee5f7079db7d3e6c2d2ed15b54345a44dfab9087c93275c78b2a4d0dd6ad71b8a9de63252ec227ec455d2b3d565acaa213f38b4086c9f5adcd0c0b293cec643dbcda13c0f1c8e4ede791f39083c0ed450023e00450ee94725126f6377fdf033173b001d268f86422f5b17aa3ef387d3036ce33864fd9de6486d953419eeb2b91997bf99b10a30518c4067dcbcd340f479ece792cb9c5e81ceb625516d71a6edbdc193a1fd36778c17d1999b6a201648052f953d40d1415419b9e1570fb9a36bebd316f0e092c569e2e76debf4b9edb3c0934130ce76496871610e52d1cd32d17c4efcb3fd62103d1e04afb1af88111de235f7a0e06a6a995fc56be61d09457125c0ee62b2207f2dc8c57972f4539b0a028c8ea012e39c978694dd8fe38c88ea49aea35d4b5ee7671822db790bc9325a169a718ff6914baf417d4ad34d76213c1e6e3d9754a7cc90d6627b9db7480bce581b78a3a332f605dd5ed0c08b950e1807d0ed8de0f8153b29150eb610b1167b7f6a27a4c2d537132fff8e5ecbbeeb2d17e2434a261668360706ce5dcbee1d7e43a5c83ff3d0106ea2c355d966e2a68d53f3dc69fdee036813f6e44bb3c512d2a47ddb43fb0567cafabd5b20e147857b5f94206751efc7fec87e8c7a7b87e27b132ee0b75f39b796ba0f7c2be56c801c1dad6b29e9006ce2236e79a318929e7c9a556c6eb3fe74ba916784de2da24afa0e1f32044a55195ba66bdee95cef2e5b08906e77625295be0dbeb2b0144ea386c84ea41c87198db7fb118e88017cbff723dc0a027c5e5da079ea1f5bf277070b428f61e956050692842c6e73c653b0d32bfc117abda892a839bae0f1261adcdd6dabe8ae3cba0eeee84bda80bd587b4b79f33bda51a8c411cd1faaf68d136b80d4aec49af475bcb3994a6d8323441cb5afa92b9a244fa6273466a71b39e7056f03e5553a976d5586c9d23061ed548e92dc460c9f82e43717ce78aa7879bb0c9c20e4f85b2f8f5b0090f1f5aeef4533e4cd031b4a376f97252a3fb49536e9cb0dc0069a961c525194678ea847dd653870fb518a0169aa3daa966554507f0bff1e077e3575019954d8231e4b936a3c0059ae32e7704036699df9a241bfa3aa6593f702627118d826b6254201e540ac2794d43db930f49eb5adf568904494d520c9f4207147be60a491f0ade9064928d503bb86829ca3aaf1bf820c7709f89cb35097a922e17cb53914e938231072296c75429e1b71bd11866e3e18a3e66615507d9fbca4aa8c0a5b8ad417b45f4298481f8ea5dbac523935a17a1d9ed51a74319708f6b86c12e8ce6d8f41ecabed5f58326e0fa73bdbcdbb76f0cec837c58b8deb281f4279f0127ef7027c0b3540fe9bac3f9d5e7c4ae845377b45082b4fb870c76d961e762537efb7507e6b6e9165a50347e71198a02734561db70ea26569f10011d690141143cbe84671dee5ffd2aa28ae2995f1ba4ded2ae1718dac1c3a9e6d74cbba5b0bde24c526d83e3ca428c76a5813f5d5f8f8627eb073e46f9428784924d72ae41a509e153a9efadc7d24b79d41c647e4bfd61dc93418a89dd2b6db7c97112aa48b23f2ec4754be1394ba80cc4bbe26cb742dbdd99a6cbf9a8d1897be8927dd22c9861154d256f835842f4c5be57c95efa8ad52422ee0dcfb81cf6d90cd57787e7d4e19c2841391551e272160c53911ca57aea87e0967ab657e82c3e71af2c32554bf3f38a2d46d10676b2ded2383260b0558aabf612efdf3881ccf6b5dc43d71eb22851cc9d6f5e05ee8ca2085cbe99af5ad8530c8f7d59798b5b96e4b42e373c68127aaa8d4798307c9f11bcf998d7db2a36f4c007ba374ce6a43691b147401f71a2fde7a4067f9e6e777ec583ad058a9031dcd3a5062f58d738fca850720972e06eea9f097d7d7b83f82195f3cd0a364abeaf9d585c6a9baa0898ca6f32f3ace28ada873bfa119a81884716155de8e795017c81085c22e0bf867ea209ea2fbb79de31e196e894708f9f684eefd0c6b21c0a9cd5a66782daa93419f04fb6e865e3e9d8dbdfd59b33d643cdb1e1fc1987ec3541686533e5c8c0738da492690423a85fc92abee68a09e2542aa22f52e63774710fa2421267a2eda5ad8b46c368fc9691d8d66ab00a76ea04669d428e9f4b998e5a1b8de89602d30d292105404ef2076493c88fc94ecac7fae0b756888fab21a148ee9b121554285540cd10146a1dfb8faa13f45f8c37479acd57457d25d65bb86c80d80c924cd8e29c91436d8177ab8cdd7db87853522a606138e8992558301133600612ef59d482a45e75640a17f8f2b6e732150e609912bd67b20c52975bec7f5656d44ff9f048a96d5863ba855a4bae2e8f377c8a25b23bdf0eedef2d4cb4d00b183e5364dd7878a16325d49ddb2be7a8db129362112f9629dc4af733174b94ad710d301af2bb89bfff226f4bb3da30ad68a6fcafe54f528f83b7e185c1fdec01571e8775645a0ca1fcafcef32ac71086caa542714112294f7cb61992122c03feb93bbcd08d8c29cbf4f50bac404507abb1061ba84ae760a11a2dd0997eea6c0ccc80796a3be1149310e45398fa3d0b8e2b0d22594c29d30459510b2e44a14731b42f17f4259dc3c028fdf75a5ac2f81f4474bdb8dfac62ba8008c7d4052cebec59877d84bba580b18853e0484e81da0fa2089a9a9050ba8a959b598d169f548d836aead5f9ac03cb9c55d3ec3ffd311b27ab99c8296ddc0fbc88246fb21238e3dc9b92d839ad2bcef734426487ccc90366940683b573295dceb45d011b2ad0ea2e4cd3b51c32bb89be92308d5107b8b168f576d7a8c1d72c6dfde63050021e2a385aeb73f4d8baf57f8d90a8e788b7049140a64e0b1ccd67cda25e11e282fbe09963ef02d755b5dc2a00eeb66c6dc3b57fe2fce20721e9e214b70e12e33bd6e9701ba50f30294a923173d49d63cce95c27af4458cdf94291b81682f120ab28397e137fdf6dac6240aa246860513213c74827cf9db3c05e30061ac7b30f487a9458601af49a2682f98a6ffab4fe06002c79ec1678bb587492ccec027d5a731b28c406d8ceac72d4bea76f471259439227ff213c221861275af3cfaa83d6b9ff42cac6935bc43dbc2d7fb56247395c48a13aff970af7e08be05bff16e5a577ec7107dfc7b10b5b5931a87773cb1cff59e1ac7f1e16d1722daed0c1e2562154083df638d7d98a9675bf6c169eeb51e2efb6e3dc79117dec1ebad65308cbf654ce924ef6ba413bc991219572839195e77b41c5636017bfe74bf242318d71ac3df692a3660acd07d0c98d51fb56aa10c518d12e46d232258bb114902a908e9aca83b0cda49390b74ac513621bc8a2fa70491e70660993adffca1053b7e5d1e3e988e1ab5dffa178a8a40a80c3b4555b30cd131ab48ec445da0b792f1a0c70b6255f10eb1fd1ce01b815692e8506dddf281cfd1865e035e4239cb31d53fcd8124ead5c64b946056cc219a0e7fe3e0a752933863e42819bc565da287e2ccc6ae34bdb0fe5a46fd9f5778a73f22231c3d33ac59f6943be30fa63d683f2eab06b55cb2bd91331944974f319dcdeb34c9b033925dbacf0586ef2f5854479640f8868fa5a75f02d665b71bba69f221a0360f0b6d62f45f191c44e0160a96eb949f42562ce06fe049de6fc044ec37481c7c809b263358ab8d9bc73e98afdb1cd47e92448a9febe7a04b87096769577d00d55f1653a29bae3c550d8c67a90fe3a19f7370fe7b43806abe8e5a59f537a9b4311aba149150c14eaec6aaa4d66c3bc3b476e6c93e9809613ef99b011a9caea863ef150545793b06af99e6de676e3f66cbd8062582ae8967be5b3b3dc491c35e505061d6f0a7deee690edee5502a1b44aa540afb67b6a883e8698206b0b025271be3943496e58bb2b9273fe9d441584fcee0cf9af44d2b3866d883935ffd726838b308bc1de5b4c0a9569ae130eeec30b040b4a0ca1b362aa1af6cae72d3324483e14449a4f0d657fa596115349f78fc04a5faf11f55dbbde282ffc87d963bcab14a6bee84a2a4e6b071f4c4c4e73e02e1b33b28d99ad6ca6c15519d0e13e13aa82b992662c8a408b2a195a3ed2a52d051d1982d524d216969e840a7a30ed125e825c515273be5c0675343079043d2b06954eb146defcf079b7a696c3c7a38ef9abd79473c2908cd0431c4ce2f06c29e5a6370b405261ce193cd46a84ad9b94941fe863893671373e141ec7e427d7a760d9f1e9feb134eada05ffc2f1ac5ededf09c818fc21a175049e0ba65fda3cdd00b8c5d7acd1ceb09ac48a61cfaa0e847f73925b86c8d7ed714523439451f0eba3b04e2201d3982fac2d577a6106d393d3eb34201e5d515199f9dc325fc6d6cde6ed33749d7e423d76706571a654d3d34b5a9408cf1377b81c3f5098a0eec13740f07e0e05987ec906858af37071f6a5213d1c1eaf32dba862d3ae5ec38e202112e825df58ec646914b0d1395304fc0be159f0f4de8852b6d6cfa23529bd93499d6c43c61926feb37739ff09d4fa8492ecf080415d3dee9b7032941c9e188502708856b1c958c07756d0d1f2d0526e69d097aa3e9800238a827d9cfcc39d060dd504f259b879783ccc49c6eef72e6ce57e4984994a8414266f0ba9fa5b92aa0c4bd1faad036f0f4647336ead6bbf2025427502c2e09effcbb12cc3369529986cb12fc2d59699ac26501c9af5e2543e4889db75e5822246f8b91924cf2d10779c79e5428e0c120ea91663e3c33cc95b1c2bb200dd51f33c49448395cdddd14d3bbd4ec7da62c829819c0c2ffa3b6aa0db2d446f2224ca02a01bc32f0c8632446f88b1553eddca398e95d8148781b31e9af34c0a3c48502d3bb4b23e44ac8242afbc382468de10358ac484847b41185db621a712f1bddf09624c46055fb705f40c4ecff2bb85038022edf55166e4bd1ed4ef42b73190b100942b68212707b78733fb5f9133b9b79df6459e558716d22935c29a1fd76d45a1fb579b41e5d9ea85f9feaafbfd3531e66ae82fe129166d519b369c777336cbb6c8236e4e62efd7bef2b75efaa4194ca42de2abc763982440df91b822285c5bc47e47ae4ec237c6813aefef8201fa15e735e58ad3831f5a947705df2cd63ef030fbffe1ecb488af521a80d3d86d99b48f86a38023e31999175f7eee205e020b400f3b84828ba79b8425b9cf2d235df0b600c692df84b9cddfe62608c238c62ca6b367aa0a7300dd10bdffee79f7e01cdaa28a013e4d8f241109616230cdd8732cd9743824704587d20d9037ffd892ee49bf5edc0e2e838645c53bf3cd1b770a2c6476dfa1759a464ba0a5eff12e334a029a516737cc25777687fcf45d84f0b61bf49d0290f935ba3c7d22e494839877aa9f6a0533edb05c04b9e866f4a7bdf79dce563e0af69e40eaca66a7de01fd9422c496c0cdb7df14bad9408105f97fdf9af52c57217ca6e0a72d3a515d2dc36fa62c9ff74178b408e5d09dc4d9a217a0d8a8a5640e64bdbd4e884955a4e2690088994dacfcfd91fa2cb3e63f0df58f55f9bd5572409cb0f26f082e6acd5af084a881f2c7c60486e9f7a412e1243105e2d78f26c099d4f387d141f394f25e2875d99003b761e08b203608ee65ce0f013945d0dfdd917f1c88c981a3ef4b23e67c21d689f20765706e60c6cae5f90b0ea04ff9a5301686ba142918e2a9c75a7c81799a8dd7b347e383015de7e8712cd0c58232461f654dcb8b9bd8210c7db0cb0e88a10ac7850f11275d7cf04bfac443260b1abbeacb00e7f9ab0c10f16341e16eabc213a5cffa13b78adffb178113daa823cc9f4744173187af877bf022856a129da01e635e15488d9072c237e873112a1b1d6946275f7755a2bbbf42a0b08dee92e1475e01b015516d5b5293c011cea0efb36a8bc2ee79fcbd5ca7395405d2e47c49948b0d1869bf1d7de6ff31a1e01481cb8d029a463a50b62e161b9e5d94e1e117d1c8f07560d330ab8260626c80689cc22ecf98c737f196991134bf9265ac624792d4b912ee3120f4d059561b6d2149f1c2504e1b1562904cbc9bd5922789f21d943c410fad46e4e3b2dcc0a454b7dd3b395ac980339bb4015274111658682d464992ce59eb7ce759e22e4ca998e9f1afe453c31285c819b7bb393db36f3374298785b4bc9ebd0205019910d7bb5d832af3d62c21de9087ab8d4946b576686ef4f3a43e3f54106496b1102d8e877f1a8a6a8ce6f6b556bab066588d12151f05c4a9fc56065b0ddbe62474a3f55b494e7873600820040a70b6014060c5b3168b3aee8e6a2b70986d5cd0621260e18888380c9b585c1402f6a945ad96bacc2bf155f6d12d3b011c7b123452d9eadcf333789b5f1ffcb31cf429d3d5e6692303d8a5411e3d553b60e102bbd8b9de5589b661035a59622d9f2697e2759bf9a8c92c9d76998e9b25baad794efdf877eff89383920be9ad218c28944154a70000e845b41c1002518c2e992ad788df6334ed6c88ebba5302087989ff12e9b3529fc093dbbad68108c2fbc4ae5ca393543c75a97c379d208d611dcf6be88b7923cb8972fa28e4f876f15982e1b8b15518fe6600a5f7698edc332bcde07d93fcbceb76ebf3d0cc3eec143a85bf49e8ebbde6e403db8f134bac0ed4a953eded2f7d04c5d22315d49f11b5133ef299e4e15bfcc3a9943191d4a5522773cabe68aa64615d7445dd44f65139454a4080f2038c2448035fe79d0cf30497a7fe08c8eef4b1c2f22658a9d6838a62baa8e67d9531c0a923141085af90290c29d8b8be61c651dc6a5f1db1e15b5f403b1ab6daebd29c58747d3f1585770e127f7c0997ed8ede6941e4ccb7c4f3917d06c648ef0d320ef932e2a23b7efbc410bdc872699e8570afb45cc5f997f4714e10a46337724168f9719e6e04ef2fc369a567a6f14c58b61e171bcbb6aa17c3f4d09a851df558ac6a5791df3add008dab77a49a332a9e8ece5457c3d7f7747f7f21a07b5edfc12734c3339b7af99a8f60ad3908df231bd18ce7b78e597626ae794357d6be344371d3a5973db33ce07aa5816f0800f43d91bb9c1bbe41d3733a4f12b8813bc155335e344c7ed96269b1b558299445c49f6e08994b1db879938c1d0251f7030e10241f491b39053a6cf4c88fa80f3348eeaa50cbd8342f7ac5966f46fde3cac506560127719f6917146164122d755e35a3b1a5a920e53d982c598c152b060ab983e8e702b76acae61da64e608e717b056c80aeccdd022b9b1c9c78a6d6857536422c05fe2d70494d0127c89734093b4e8bd8c5fec0a41736ee5a86877e21e665d347e712b44c331f7df7f29fcf06209e6e9e842da6dad5771c7dcf8ce0fa489262b716c7b8575069d285b779e0235195ccbbf5c2b0d9352b11b12b686467039f4fb655d41fc12134f866f61e5778b2ebdbac3316ff0e03e10fee70ba5119553e4d49f2c09920e9fce62710b48221e073d830c7b605bdd80e65e2fbfc1807fdd52ee651706b5e98ca8344896540441108711d740364fa64ab21f715ec26cf09bda50111d9e598b56d792ea3f2f95bb6ec2fbb6bf4a845fc67e41973b914db4a231919fc9092fb3da0187587b9b40e1c34db42c1f7b7157a2c048fd190d5470bab1a6ed6bb1db68818de524cc4b3a0d4d4411c3e36a75f048a51278c020fe11a46d70ccf3c6f980435c32ad9c178ef70c9d9403209d2efc0c5cce7bea73394fc6254240839614ef7b7ae5d8065186244d50fbb52e29e2e35a3a8f82f5f8c067944543709199536c8c95c26c3c4282aa761c42b531614e94962d37d01fbd30bc52bb7516a5e245c3fcde80592195c5a8f5b45f2e0ae98ef91f52cd23116e7adb64106d2092f2a31f3213363672c988e4a960b43aa6c5c22741532da524e9278fac00538ea68c5cbc52c96e20054e58016477080ee7992375d0e32fc8546c74d06340ad3fbbaa1eac74a1cf8fda9d50340dc3a794448a361220a15049cf0c6f25254196ec4da6fcab2026a9238b2e4023e609ad4bdad47416190fecd21ec9abd1e9c76580543802dac4cbaf3c23a1e9769f2e533f9c172a0af57e48078384f0545471d5871ef2e4b6141cc6ac9a371d029a378f73902a6814a3117e349cca477be39e3a868d99103d9a7a0afddc315f9506c4550383814abb87a2c6e7372415684f28e88c4d41eb96bb7353b30ba6f1a03996ecae1e59b03a7849a3e8bdfaa9f5573a61832ea3974fd49f7939ae99c6cfc96a40c3b38b8d7a00fddcf750e88cee0441c0c2c86f737b5bb66957cc21519e6b4041b2f56ff20d0f8adcb27ae1ad7ee6d18c6acccc19cc0c5d9af20e4fcb5328d0145e52d3ac0e9e7b7e81901b317baa95ccffd7f6912aca8870989b2a3622218e0dcd94d4ae2a79f3894c3a922912de690fd979f6c20a9d3171c434e2224b872b3834089f87cba9a918bd4f07e6af1f67f1456b96b31665759d45801a2737d38f8ef1733d92ce035dfc1bb87164ba47cdf93c9846e7a3c1306299acae46149a8a87fafd217a956f5fb07b576ba57b4b2caf0449f38c370ae2f47189cd4cd9fdba2fdd024ad1e7fbc238087767e0cc06695e1a990d10131298a481a804409fec06521bb572d5227af6934bf07cc6a057bb2388199115ef551cd8b846fbb95f1248afde623afbb9b4c480f843cb30eb445dccac63c0890400fa0bc1b481e9773ef95c216aac5b373f2ebf3ce5ed5434c7619464db26dc86e80198eeb09b0c24a84b0c4888f34146e6a6f9dd05a39ec31e4c1e6815efbeccc53478979062b427f8c0ef95af879fe1702d46ca74938690cefaac742cafe1206cd3d4f1ead1479c4ef50f24007bc3c554ffc5fbffb8b0339e742d4eb5db2103848d475a8679b5d51daef49653d411ada87f70fd08fac33b487296cfb7e4d3c53458f8dc53f940fcbde1e5e8b23b155ae837eab06d885354be626881b541b53c2514b1084584d7d921147243ed3f6472ddb14d8bf5ba3d6e6210c9de6d14d707e13afd86ea00ad30174a6f619cd24ffd04bd056981622db5d49944cc6cab14d6b61b2601bd0cdfd4d21a6cd06a2600b2703210bd7fd39af17996f66cc024d13f46c3b0c13918c46101baecdc2e5060de4ddab38d893be9f4c7f60062005e8b4b273a831750be436e86f357180e28a7825a0685c22cdca08e9518f391af96b2ee1cfb6677a8d7e499ecc3468af6466ba9d9d61a114924727b65f7d2cade01bf02cd02e3020ac41d33494cb6dc6eda6a8d6ffbf9d6344debd2be9e76d86f5dfcc914070d1fa0432dd280e939ea873bd2034eeade66b7cfa553e526ad337dfda4939d19dbf4af0d4405f74a9ff3d65e7d519a524ab5a69f33c69cb6f7c28bd33f9bc4f973de939e7cd513cea5b25a7f524ab74c9de19ce3f8109fac26dbc639e75c6fae397fbeb55efdb671cd39e79cbfdc7703f1e7fc75077bb6b10ddb30fd41a4e69c73be615a6bbdf54e144e0446f36bf5f32956ba7dfe596e08209832855baef16b31ce3937f1ffb6ff30be61a6128661db866118a639e7fc5a2c639ad6b68d3f7eae71ce39c73294451d58dc608a317e0b4da031716d923d92c5f2bc7ffb9fe67665d23c02f9a31f6e08e28f5e7153678b365d17a769c24f70a288062c5f84b2ec628c7196d57c51b92fc6b66e8c31997a5d8b23853b646a265dfcd85e7ba1f4544848a423fdd361eb0623060e4a9b52fdd7ea1ce352b2473fceebc8ba6c6f3bed77671f485eb5a4673ac3f57fad13bdfa729e65590694656fbbec7967ffde681139b635be62a0aedaa68b3f38a94a6d3e93c4e4cc75f147471764ead4577570b7a4572de4342079db38a3e6378a66f5d6c58e75405adbd6b421b61290dd2a6151b0f4dbc9ed76b2e30dd44a25e1599631426ba7b05160e837ca796152c524803bd546dbaee649db6f0f3bee72941ef69c7df6b05f2ddf44c1a1df27dc139bcf28cd4ff9e6b075030d813bf50f58c2833cd702626aa5a8b7c3b31ac7b6d632ce75dccfa97f652f75b26f9de43af873ea6c3af863aa78d39e310baffa39b33f71c7a5b8acf4b167a58c6f6c13813b75031199d9e74ddbbfb63349afeadf936659bf8e2e890f598e57e57813fee7e671ba243e70ee53dc9bf03fa887fb81bdbaa4a73fafaef4f46a88f4ea5f789230d92fdf562de9556d05447af571de885996e3c607259ddbd8ac5a53a7cacebb201d0252a71a90a95aa83f84c866adf40f822177025dc41f37f2c409b8e0dfd52312733ab0855fb382202e1977e0b284122e55b654d9d2ad0cf10274497f081079a45551815f82323832c245092b5d4af942620f2b7af265f4be02ba8c3c04883f78208f7c1e5d5e1e0474f9df8ece630acfe03f1e1760b0cb8c11628c10567c5164c5174ebabd82660522bc7811c28c196ba12073a4e7b70c8c71037ad0e68b91f08675a9c4714f305901882b7b2e4ae94513b8e6df5c11f775edcf374c70b8458a19d9e50422fc6c9ba47f3cfb65bce085d1d5a535009616069c9667d6669267b4567b691aff5c35efa0d65967add52b4a46ef8c67aaedfd1cecabbe254d2b6d7bef7cb7c6a3a6d492322afac783c60f90b350e69c73eadd3b779324779eb99bd65ed7de247c6badb4563bb5a63547b585dd795a4eca396d0d61a028d321f4ae6e4955bbdcc4adbd9fb139e7def4b10cbbf7da7b6fc5175fbdd989490bd0ab5e7b73ce7a6f5d4ba5abcb9ff35f2ed75c2bbd54882235b7164699d927a6df77f539dce7489dfa39aac648411f50d69c6fdc403ccb76f65ad4607295ba1c0c2bd559c3396bd20799249cb39dbd25eaa26dfe63f06df9ae800a6e3f3b55a9450d12bafd8c4129b1af03ac6e95b4edecafbe5b49d34a5b8d3eedecef85574dd61bc95a8b619c467aa2a87f3c1287859f506b287ace396dc85008af9f639dd7812b62a455d65aabadb5c223fdcbbadc09d8c079a5c9d7dcdd003f9c5d71ee3f4ef9cc57d0cf74894a29a594d63967bd73ce39e7bceadb22b1cf492bedb0cc39e9352586e2849fc024c59952ac6edf94ea21c5c4a54c9cf755f8a7df94d23c8c1d4cf24fd0b49c73cedbcd5b8e77db56af6979cb39e79c5fee8c7feb60e7b60db4bdbe3610d65a6b0ddb3967bd6ddb763755196cc486f3f6380b33bd8a2cc4745cf18671d67a63bc81b0feac495a67cd6a922ee995ce5aefbd314cefbd378c31d67adb72a6699913565239e8c0aa5a7f5ca635b6b8b3165badb17c9d43eb962bb0e8574c500b1b5d74fc99d31b085f9bcd2c6652db08c92642dbdbe1e58c936d208cb23ac3364adb7b6bbdf7c6b9d806c2af55a6ae6435d75b76cdc2ab7edee8e452dcb6496d1bd18c9c34c6bcbbfb8348e9ddd55d05096d299469ad8bf168ead4ef2269883cf5491d868244879dcb19e0ced1c4f1a8fe5d1df5d0ebdb782485d2f00f1ef55a3fc84809561b8d9f18ea9fac32a5959324000adcd23f539f22662538675280e15e27d28a93a0254e9248d9599d8e98e243fe0740cfb0cbb2d61af7ad553ec11e772aecf3bc825938e884e3e9d14c719774d43f1e19ac44b9679c31c33e1168e875ca108fb662ca92da813c521e911fc420b8a3051ec52192da9c87e021f30a894630a5aba0ae5a32c48951ff220e39d087cc813e66bfa921c31c6eea713fd917cd97bde84b2fee979e4c3dd9bb4b95c14d5cbd9a62d13f9e785da52198608224aa9c1002ee40d384f1a609fe715c2d5221c697525e9899fd5b4a114bc09cb0d037c994cce9f04b965e37add666ea4d9fedff3d8fd5f2faedfc7d22936d759978914c56457cc58b86909ed4894558b8fd2f169d2a374d3bafbe947ece63bc01dc91401bdc9d00f4a25fd9a3b994ad36938f75f6e50309d97b158b5a8841441df9460831c1048a481483889e7c0ea2144a9ce85289301108b8236391fc0c36d8d65a4ae79c965ed7d4f48950ffa21931e619ff77a45df4f8f1ba6ccc5688ec9957cf12a7841dac568c11478c59f3ca2323d2934148be183d515253c65486fc4c2f52fe2abeb14eeaf1c9cd48a38e4f3ba07bb96bc61e8d484ffe91b83b222c1a9fec0f22f72a48d50291e903825cf242978f13e603b82383e08e7c9515fe412a840ca11cf46169976d0a49fa1771e8f2a79cd6461c87b23c79c1a50a125a4a10f67c599f3ff3cbfaf51af65ca5d21619e64018af873b671e512384f9c6d577595c7fd82f7bc98f2b0da45c7dac1ed293cf925d4bca49bfd63bbffa2c56fd1e2dd95357b3253de94d568f5b6d6d495397ab1790f87ff8364970f9d70546ce6e5c4d10b545b748af4e343845c319513337d4c8b27ab0708dceb07d7afca79a93a6a5f4f5767816e7dee4bd2fae833d9734ef66cf277b75aed19fc37d2ed97cec251b544de65b5e9157e00eeab38de6521c97513535591251224a44897afd93a994a9a8303232aaaf372df6dac91eb7ca8a2c59b29030ce998b68fad02c17d145942f224a665333bd3ea7463207d8c35759c074d8ebd331340b4d5351e8f533cd5247a059e81a9b1ac19dfaaa22f8478d7abd027dc4cee5a0373aa3e95fad9d6c808c5b547fe0ff2013ffc125480474a8d335564f8567be168bb4fa589ef7962589c49062441e6b697c4b65986b488a117f5c5e228ffc168be579ff1c37af21222f62c45ddf0e4d9f7a27f743d5e81aea5f35b223401faae4329a5ee20fcacdd095b8a0e4e338bf8cbaa449fa7779a151c21cd1bf6a46943a06f2c8bf5d2d036b35526161142797e2aa19e9c9a7dcc4adb7c323912e301798cff9eb8b92e953c9441df96730a96c50218b64287ef54c977f19a5e949e28f4a26f2c8b728d0237684eb680d345d5633d4045cc754a3ebcb17d90306e3baf29046ffae146dbb451d972aa58cb0cf0aa28e7c31c8c0332005b113b1c00249a44b5d72a57f300e294d6bd4cf106b1dc5079bf8d1e1001c801cbd3575e20f1eb18012f4213275ea863d7c2c6e138542a1220ac5edcda13e4fdd9a3e51884a149a1c0ad5edfa52884ba14b657237b63c12dd8847aa30fcfe178f4ef3eacb9fc718f7defb31d42492fe6cb5eee2516bfa0471479b771e701df57206d883f280ebdac735608ff6d5e62b77a345bc794eb2d65afe79db3e88bc4562df38c618eb0cdb75e3158e118f9fb19bc7ddcd074d9fd805ead48f54a04e7d8e73212131f9a439ce1871f3b76dd4e00e874b0f67d49c36d0cd079121f0c7b92b128b84d0b7c77b01ad6f2b3924853ad9240c3f956abad8331bad4b972e5d4a1baf6eb2e0b8934d4e7206c8539feb640d70a73eaa934da898be72dd94e3e3d09a362e12fbe9334a632848badc40fcb70eb5b051a6e3cf351ab7d165cdebad850d301de31e8dd6a8e4ec1b2835642401008204b3164000180c0a0643815040248c8569ef0e14800d63883866403c18080591388884200a8320888110844110043186008510824c414a03e0a2d2fc7bc699189a65f3f6d8e8b9ece138aab28a2052ecfd75489a0bfb043312e67b49f8a0e0c4ad5381bb4b28c6b2f7ddef1699085a12f9bf3795171fb4e54f857eb34b2439c88adbde33737f4034e275ef63630383424f95136aad659ed6ef42799d0066720cefbd2f1a8f0eec6bd8324fd75d2c0c56f788e70f7669872c2c3c2d427bed56da0a6a5b955b7d8110797122b664ed9aa061385030ca08d1899ad015d7c202092117d6b53479434839ead73a6bd3042208d67deef9b31faa8d6b928c9c429e55c5f19928a9047b370571b42299acc492bf665e88368264f3e41979948268207ac9a6b7f41c7edebded3b3c4b3db79ba0c7a6784ba4a14d005f6958dc12bb04d219976483723146a4a6c8047a213ef1625502a8ff0865e9da7f20a429858844f767c16db39cd7b95203237d5bfbf6ce25d0a3a399d1d423e0ebbee0b52bcc3d9261e0ffdf8b41780d249ad83d79fc65a023b39f096cf2d1ddb7994709fc569f4908b563d57f46576966550b49b4b83d5fb5768a1affdbcc34c646c247cc9bafed60a7adda459ab457b13a159b14907433bbac85250eaab8caf12df727cff5a4606fd5b8dc331a1dfc43c1b08d96ff1744817060d0fe329d75f294d40485642082c91d9aba1c8046f4baabd0ff72e0475339210104c9ce9e04fce170699798d09ff52825401e650a8053f53896862d81e1225621eca3d4fda7d09f6669c27fa907f892f188ddf7421cebfc63078a65bd6d2ad1a0aa161afc088a61874e9a8b4cc4860edc09f7b53b724f733e1c756f9bdd913b0f6e556e196073008e1c7fe5f3e866b502fe53dc445819c6b1cdb9f147768a71bfedbedce7e9dfe549585bcb7f77902475117b144b02f0b4a5c36cd20c436a4b0ee6034ca6e8956b124916a3d5873c524e99238c757cd396752433a7577bd53041baae8afd576e1f0b41dc1900971dd7b1655464735fcea82b7f0187cb1b62b8c0736db299a117ef69f1d3fa632713b3ea104619f5b7664d516b26465d6d29f83b9f91a61e6a5e3ec8ee1dc3d9da9c8a97a00cb01568007dec549a623a6fc9d484562facc9bd7473b290ddf8118e245bb16ec70e739d0814a6e3195c9f7113ffad944914ba3c3bb419d7fd8f155c101387de207d8139e68741938948a6a8ae0ba8274b3b4f6b6137ce6c2478935a5d1123342271b8794b2015b788abd771903259d49325a433500b77f51e172e8040446a47c3e4ac0cc860715b4e0d5436e34e40ea76a3d43b763fca61d33b927c5e77f41f65554722169bad01b2fbe648742e84f557928c55490c6018e1fe9535bed8903f03e8dfcc7770677e434093e490263e04d9996144ee3cda79ddc4cecedaef2b46aaa5a5be1b732adbe134f664481e276ff8433d90efd2a563f806ebe98e817a4f5b27b75eae911a6f96bbd017314f5635841b037e2799d2bc494d429a5e58549f2e44bdf2abda54d95828eef8f05f472b5fba470a94fecec7fd4188740769e91c0e1a16d8dd618eb02c22d84cf2093358c647c0603524a9fc570ae3607576b428bc2a9069a8b36a52504b09655e639fbe00bc94f23a28e4236ca98083b017b38e11d23da920c7aa1b8da0c7b82edf86a9fa11523c4866e92b897235ee8f81098a49013cea55a82032e464697aa8aa5d1e896a181cb752df4e07cf7b4fe70a3b9b257c4ecc016bdea33594db0cae396113c2fcf77bf40b7ada1aeacc02af1eb7b1f858f3999dfbfa50234b3c1f88d06a923a937f7212e3a26b75e6172bd476949ef6fb15ac587a5a112c6b16e549a887f739f33982d8d4bc198824a48dd12fdcca191e620230a7cbf6fc9b7ce5e291403e4ea1453c0277046ecf37413439b3790aa7ce172014efbfdddca9ef986d6fed647d8f118105cb1f9d0d897441a40ab32f44338069e6731c5ff8b0e7fde30f6022ec421875e248f0971fdd321789c84f7340519af88fde775434a3480f2c04a2dad9681a17f341197a5472008bf63a476d3f1477332f0abfedfc563a20dcebd18a996e58f134e0db03dd5de2d7d311910e3fe61b443ad96a944e01449d0d6775003e76b8648ec07a7e7e79be46118065a939661b5af107e67e1b2de0a7bba6f8082de4a7019c4f2830457084016b8af82ea3b7c59d9a3cb44183e8255c07b69b467f61a26554a786a2941e79cb678f45ca540cbfc893b24888dd069eefa6a1d3533161a6b1344763be6d96cc597310fbc98569ef4d39bb2140bef9806921990850bc8269a9ddfaa825dea47aa95b00d1bb4981cd5959f70fa7485547b45e8d8629b238e3152bde02a092d406ad8e2f68dce8ff990301cf890cb514b9b629a3f78da3101c8594ab13d727f467481fa99c277f295a16365e422b4d69918c901e10bc905090c2cae78d894db27484a67495471ec42f49e85f4f061533bf39b7dbbc0855df84e9a3015bbb471926f9f32884c632d01a404c08ba8182ecccf8fa275c93d2a298cb4fcc211d40c4427fce479f278dc551476ed30659bbf1e69e39973b72fea18a8deecc4cd6ae88dfefd131049ce3ad4b2dd82fce9f6f2d14a18f230115068cdaa30c4dc1cfa57627c8e13db83765d0d1996e683d3f3870710877e0033d919baec807e2a746227321d752b83c3e7783975a31a61b51e7ae31c88039af70cc3adee26c9df3db223a1372bb33bd296e43d102e566f1e5f90d967927953686b40cfa08c49b5402dff7070e32facf90f74e6a3d507bae2136c6c560910c46f0e018f2020cb2af676e0a32ac044432088995dda1030c90e405597f736dd60437ee6a15c75842ea831cf30e4931dfa77cd2791c8e36040e1fce76c2388363c1942743b80e87c789cdd239fc19d191f54f10dd585a5021a2009400f482491e6fd7a223dd6020d1bc5a4c5071537194687d09b4c306d7e70a20ea6b564d82e88e82f646c3fe61bff622a2e355710886ff22d899bd559dc16aa57ed9ec16de477f7bdfd4cbea2e52a88738aa7f41bab0d30ddeb62c0ea1f9f898fad29a20465595e1c31b50ac5a13690f3e61907a89df1b7ac8e739c59a53e6497793b1ad56444022f10a90a0518312733b8749950f033fa6bd1507b70769701240b7ed036cc7810a477d0b7bbc9b94f08099e7c9cea41f2841c19de512c06e6ef2910aa889a7b53cdfae6a3e7d08c9dd3c62e7a90bcdfd70174cebdd32230508223e45cd5f5e94197ac63c6085510248e371cc80e5e9e30b0a2b087c9593ae42f0cef46512ff1a95a7a871c6c6bac20fb20803372ac9ef57ba11cc7c3d04cc5f3cee3a91019a24d7e8d3e63c722bc3a0433de7913ea4d7421fdfeae25390d9225459580cec838e95e4dde4edda55a1156f2535a7d904197412dbcd6f9452a37c7d7504fff8b18648d856a909a168c6dbb0e6976e8c504f87b20a285be9c3065a364a6935f0e2149bb490a5c54175d681d681fef02ddb53ce04bac023285ff9a6925d39f6619b312b967f2d21a77bd6f7f4795a55838a687bae707d4ff6cc0562ecc9562a3ea5ce5c40c8bfa6e2891d4515f6ca839b3975629ce1abdc04844a00ee05af6bc098e65a4b58765280c3bd546f82368ec001ab42119a3f6af319b0c2087ccdd6ac9b0d1133f781fa696e1be8978122aa8f45054f804815676a6785c17898cab85c12559a4b730da073ac272251cf3dd013cccd726badd2ad228423de8a80b3579f8ffd7e72696225fbbcb964425afe1942d54da3242615df4223cd21415552c419edd8090463c3f19298994bcca24169f8d8e3bef00f964739acea42a9307819c354dc2567ffd15c4466237dfc9f7b306b6a57df8f2df88b938ab8e80a0c2e89b58f1e11082f4656c8a12fd34ad8b7ce326b83d3f4e2905ac86b9d931094040937b9bca5e30d619659a3e3efc94a95aba1b82f04560f7043091353d49015114ca7df3c04a0483d1ccf7cfab80b23eeb1645e96ee9ea0721e0239cbcdf4d1591a3cc99557cb7ff06a425ff782a9bcb2af1b4a39b8108736f8c8493ad2e0757634585cab3feae0714fa7c03f95f5b05eeee6507107712f2029347f776c09a1087c39b01510d125566122668588add69f937323a48ac7c152613fc77230956221311c6d65d39039ec2b15ea4c69c97b17a71c2dc712dff2024a748bf3f0283508f54ff1b3ae47e074628b1e446ec3fc5975717e5e73a69afbb8c3045db95e130bd4e856a960711eb28200366462e429bec6dce96591e61f21916af17a1973456ca635db7eeeb47405b24ec749c888eea1dffa7d253903b737d874177a639903b27f588d6b4b90a04839c8d07b0a721b44730943b957cada679fe7f4b3db4a08bb770dc71c2a634cddf72a61e5951825fdda75f31e11ef54d7674007e2aae1e73dcb5a91f855e2401f6a57b3cdd517522f9294c30c1e7aa908e7a2515dc19bd55f17279842ebfc6dc21ae876ec9adbdf08a64305ee39e617bfe29156cbf8d48d40e85ba04a6c90885f32484de15dd1c6a20fed8add6f88ddbe39eacebdb0374e071a77ebb73701f4d05fd0128b6577023660809a88e1c69b3f4ad8227f97089a3d86f8c54f6a0139e324db622ccd6b3a050c70f0ec3d755f3736ea0f5966ad25499007610846ff68541be5d292881a4d148e333bcd18db0464a3031005e3da435688da12565a74ec69d5d2d500a7449af04592162fb2ddcf31f0621da8287cf5832c047db48a8909a3472138ba37c45438846dcf6986e96d650ce715f39492b99fb1d87d2ff4cdffc5d0d3c3340d927d742eed7ad98c21cefbd23d5d9aa0446de741bcc5c6caa472c1a9150eb444b476fb72e1c06bd4c35165e6c103273db0e1c53e56183f200ed636a6dfbbf13b3d3835abf9bd3728fa199cd3b4a34c20584462cb018e60008fc48f79f9e87800a75f1ca588f7dd8d6d03d45d57b93f3d917577bd5b57497725c208e24d041019f5d0aae31e26d6c0843ed72880d3c665629a5303ba71ca0894dd471b2b022584790ddcf9c547ef9918b30cc8309aab80b410c7400988ed865ac04ba08850f8de0da8481006215362c83d548fb1ed21231e580366c8cda4df2b962c875f0e42175545ba26ad15c2c78f0fd09517710502c9e09c8c0d0111660320ac2ed09a2873a92ec2378faf0bd30293f45221da5a1515f98feae0783934aef82e407052bb68e665e48ca2ea7671d2e0fd8126c871ce74ee43e344090a60185d82098d8708ec16ed497f62f73578cc41307f260868c886a069910edb6ea08aa7b2cf5fe584675d3fd1dc07b50fac0978ed6503f33064cc2ba33e0ef9131396fa149f6698e1811c125b52a70f323639977211d935fc190425a8fdd542ad60368151158e9f424b83a16c7fb40f896eaa70490b12f31da5105a826d777834255ad020e759b0354dc7aeca9a5fcb49d14022cffffc3b1b63126d5b4c08331ac244dae70da57fa73c52e2d2ad86f2ddee8fc6b58941e2e4a8383920826bef846a4c1180a0c45a379bf0d61443677aad4599669602f7f4065d660e3beffe010a83a9040aec527310025df455395d4aa11075822c958ec29279c230cc708fa83bc10af10e50291431e544c070a870034f1b72a77741b289f680f9a8fa6ebe39cea3e7f07e182f16867a09fea69f1b1a72ce479a49f99906bc7f6a2fca46da534d367522f9128d292c86016f6ddeb5bcec26219c134edfd1d53d95dfd1c6c801fc765436688cc45a18099f31ba9df9db4cd966d6975d915f9de4675250ffa3d147cfd0e019ab81b3b72b9cd6ea9e192d071371fc6236a378dd06d946f66af1b835f98536ed9871b1da881a5cf6667f1750cfb0fbbb2f24a80350e2df17e8ce53864dd09b24d0322efe72f1f76496a7780aba46bf92048fa04f2c03419e147950228d1c720fddf318241f2eb894e75eef3ab58ff700a3ce2f2168d08daf448f45ddc100368d9a460c936fbced3600f7ad6990815e089a9ea50f2440d5ab65ca101b318554e31ac83ba47d3067b58ea16a500d400e172e7a87c26283b199b5db0296451c030b630d87fb3fbc52eebc19dad35d2a482dd7012a64b0a8ecb814c67fcae3eb58aaa265f771074c010d8dd89bdf0cd373383199f06a9b8f2ed729155e9f17ee424752920a97541dceffc1ec64b340f22bdab4aa72010913f2ac7b4f476bc901bc6560c8406ac02645d51450cfb5ed980a2119a38020bbe4e078979506ecff72649591aeb48d4b805f664dbaf942acaf5a5ff68e9b871073531020aae7b4981e0fd08511ad5e895429ee0f8cfcae69f93727a32a6ee2d21ee575dd1a72532c5cc56444b772070acb864162c862569fb55dd4cd5b67d53628358f0711d1689f27099645396b9956b6ce5d9b105bbfd1dd048637c984a2148549eaf85ae14726d874af828be7e2a0efc6d24e062f5d2b88b7ec5437f3d91dda1303d17e231e568bbf351434e24d9f89b26f41a7c4930e9333e3393fe6e09c37bac28250c6db62afe2fcefb79708cb767a48c30db40d1dffb9411f0f1f95d47083b3c0d5deea067187e5dc2b00d1055a32c5bb0bb15b0eaed0de1db440ad24d61e1f9cb0f9daf83f4f2485b017118a1571ee003dc3622fba1d9b608229f7e89486f252979ef139dabc176b8d3dfb48e0ee75bbac7722b187b0f416a3cb5eca8da9501ef7c513c5d797e3cde806bc171d1e267236b86c3a3d66ac094f73b9bf1e17bffba600abfc8b9df03005feb8d99150c132fb54750c9fd50e1c284aaad233de38da897dd7df4aaae8537418c0c2281d799304c5fa802d5a97b48ad320b9988ec2e5cc4f702ada5da39af844b73ab8ce76a796b2bbc2ccbd6110c4b8f04ec9e534aa333be17ecee61874bd0487da41f7a9c2a3a442853495bc88cf5038e1741ac9dd5017aa9ef91c2180871a47dcaa02d24c5acb86d5db459bf982414aac34f7bd53cd9bbaf926182f5d7b07b08399319b722cfd3e12ccaf4d87e7dd5796377a2480816847113ae0f78a85d007221691a508a9f437a53ee7cbce60cc85c0868e14a0a516238e67841d80abb7525e939e8f4fae05eaae01d5a4a596c72d1518f1ee0c0348616500d4dc00f497818025659fb46437f2a90e5c0b39494f546ce9df058ec602c5d138651323a5744d7469b62578b801d40e44e07d81d02617af745fa1a6e60e4a05c16c98482f350fa75eed0eddc99473446b525985b2c29ac6218702ae25fd0845fda26bdaec7f824ff14ceae1667d933c3b662090e27660445180da8a60ac217902c0378cd085cec2e35016ca75b2d93a9f6e3b899a703c36204d309e25557894fb73ca4d3e163993e304638d761c291800005665a0702435565e6a6e0ebee19109346e0a7bdf1488a8747fece6491be0b6523aafdfb47817c8e7598cc252bed3593ca0408a65bc363e10a6aea9d866175936c7971b0f45523ef3b4bd7fad4c4ce689b288938edc44e2198e59274e6841c1d8f2f555d387f068b1262b4bcc07b947100f8d5d5b1269b123c72a4fb53dcd07711bc98eecbcc89744a7223e98b437c87c2fdbd42ae73941a65c2a8b31e42423e01380380f15e96d60c8b62f4ad9709f5798688cb389b2ef8def7fbbd70768f28fd2ac69202fe6c28dbe0a35eab82bba29f831194278e50c2713dd520b3dac4f66f85b40c72d45d7ae7ded2f54b090b161dd5c00eb334838d3d031312b76b720d8414108296735ca52816f7a5f3d729e699c0e81bf623ba5e79504faab1e733236f28bd1262542cc3bae571ba228790c188bba61324e708d00fb211650371c3d1538eeb8940a1b0edd749d73d37d546aebdabe8fefa2fc836ba6a6a42c60bda6cfc399a547b2abe7b73cb21a7191fc4dd8b05683bb6ec89c989da50890b031be3098f28f241c04a367482cc159ab49f8ce47abfc03c477fcc9bd14322d647bddead0763ba6bbb1b5b5e0098bd8d203b996d52f6d8555d544dc58d038e0acfa3b1342f0d87686b59838e1ebcf1b99cbc1ed5324c6ec9375bf4211fb5fed0eaef046847c4829a2dd86626c89172a65207f50a034bd97059199893716d81155241262911ed12c4164ffce598347d87f456b470f1ab4bb35990e7b991183978590b57dbf3c5cb65bfe1df99cb2b558c76bd5f7a0c3c53955422b8fb14560e34114b67101c162cf2bbe7658961f7c5bba2f241ff25dc43c721b8d2f52edd4ab70791e1a56f00eaa3f57c407650cc55b188549ad49cefb82744576eebbf2cf536b100501785da1bbf6fca60463216135d65b3da08ea63b78a5e7a2a46f96025cde3efd0d77d082faa452e4c57d6a08f8ccacd0ba0ff938f66b1df6eaccfb530f23f46b68e215e39143238bbd2ed55318fdbc1a8113c94bf269e3a007ec439e75073fcdf529ebcac5af68212b5d51058bae2c0183d000422aa18c5eb5c10344c98c82974ec0fe203587edd235456f121ec4497a544633b5800e4976c32a1e64a765f440000edadf1ac64947e2ec34f045f8c16e39e241be5d792118ae20cfe813f11bdad4a3545002e12bfcc6c209d94ce577b75277dc1b838fd293e3da3e01b7d0cf663708aba426e04b5e7f7855e80954fb06ea065923fdde9903c81c8c57ad101154f6d43ad74dc7aaa8dcc8ec6ae30d5cc486fa97f274bfd4b1ddc46a518213023747c1109ee894db86c97be6e18057cc387bce36fa85a5d092094da3f3bb06710274398aa8fd7989825e61143aeb1495d95507a454a632b19854e3be5f7b2ca73bc7f5999029e9c6c6ce7561538730bbcc48ffdd12e7a2bb66a6729527f14d8863d1eb5ce1eb759cfb254ebbb6a354119c8b13e62d8d83cdd102f5c36f2d0ccedcbb18adb809dcd361222989b5bad0d83d77f40bbb351e3f21bd1ed3db28dc943481c8e5514b7552a08733cd965038bc91101b87bc1217a99c777a74571ce9488718ecc945503011df29421dd8e586262d940221eaba221010d1612d5d9a3470bc9e958ff8f0bfb142bee4104cdcb41e7915a59cf86f15b2bb0b36733b44a57a786f98346360aad0843c1b99dd57810db760f4d59aa3b7c9f92f69a8bb876336eb11f4f66c9437d4ce38de338cb496c253c261395d20ba15aa27ffaa732bc3f68f6a03e3a90862b0472309faeed28b788205393273cd2c88b7615cbf4bd6e67374ae400519dbb589321034f940ae39e86177295f7c4039b5b560866be34aa9febe40b127eee65de2479c2b9a15af05de836ac5948223a1a86285ebb01480a85cc0067b60556aefd2d7b9bccb705c0cb8ed7fe9363906be5454a562929e719cd298fd2e6d9dfd1fe230647a0a19ecab00fe94c4a6875bb58f7423de7769cb2fe54fd70cbde1e06b0837e23cc82235d57242dde59bca6aaf143f041f1490d5ac36813fc595d77b30727968367c0898592eb480216820812ac84957b9b828f6960d168e3c452cc8dc42dd42fc5b4f42ad43eb0212bf35cc05f83a54301800108bd46c27662e3dce85ba500d7921f9a73eb68b551d0dca2ad896a65a3a359d3527892070d9d02db1b0a8e08904a404ee238f8dfb16744ce777e5b8e046a25b121d41a6f5053638a495c19b4b61d2021343cdb7124a1907b41a6d4273877c31de926a34e3674ca449395afcab201b504ab14424a01f9c30a2254529e6ea3aabb78c96a585c4e3dd9b1db6c5fbc5b2d88c1b510cc6508807574b7abe2a125768ea57b95bf9e5dc526515d27de89735b0b6a538defc6c2aa8bc81b7e5b5a3045ee18e006c656f796984acd7fc686d6963a876dfe225d0b7e8fdd2c6d8d8b23bdf69b36444ec520c48284b81534eb079ec3584ce06d46f85732de2aaaabe51d50f299165dd752999505735d67617e2e9087a00742d544b861a6def00e58dae7d43c2828b0f1571d2e4c3908f71e9b828124304069f6805a92db24b11ed8374dc877a8555fea19a6d0a1c103c680037fe5bb49a331e1908c8a26ef8ebf073e7f26a7506110a5fd49e25d9a679ce6932278f18780fefa6b96ec4639be6c8379b05d7f165b1ef9f9432f253b0485da926a6e1132c5da439a105c24d010752dc58ee636a2f78026040d3d15dd5fe7a95c1821f00e8ee414b4603aef7b0feb9d6743337708679600e24a379e70166a72e11dfbece991d4c62b431e85843d899aab0d66ea4dee8bb2e26381da97c36109da4d07f3d112a67becb9251677425a5a5417c2db00c9d6bd240322a10ac5b1aaddfd640953c651f1c0570a4db97324cb3a6de03d5d79e4d9dede12e2b4a46114e441092e9c6738923218a345c63dc6ed304420cacd2dbc12d66d073db1a31e5c1832feb7c7496b7376dc3917783e85e0a0d35bba677ac6e25660159b125e5b40e54fd769f26d8adcc173416c46ebbdf579724d489ac42a47ab7b67dd013654cf4a222b716a0d753e2cf02e366a73a2a0f7dafe871221e801051776164230428ddeb0c03e2886f5a942663dbdfa79123cf925f837ac2188693a94277644df55e09e8ba6860694a6e5355ab2920f5f4db182cceaaaa132e67cebd1b4cdb8b3c5c6d80ab906f260a660fb03cc08ff7f6d4ce70d235c6b8f81b359e5ff2a73421465016894df5ea59a22e6004b2099f4881ec1ea5c9e7b1116b4510fba159de411c87b381b785cd3035518ea8c0e1072ace1f494b594805bd72907e9655aaa93cf4092930bc48cc1a524d981706693828b0c6780222cf26b5f6d46305f9ec9a9dd0a67e39a08f7053d580006f283b6e2544dd4e43795a1a6a170f2f5d7320132489bf832465cdee2e4ee8f4fba21e32ca2f2e302d73d08896bffa2e520efedff3cf274f1824448ef0df2c28bc9c8772d8ca817269b6f93ab1eb57d200c1e592e97d6f5f52d9d49a368845f874b5ab08733812f8b509e23b03d377748e222cb13afd598819dfb5baf23be68ccf1000430208087621ec33c0016d5a02a010cf41290597e02135425722b8f33a7affdf6f85c431d1ccecbff3eec5d7328debca3da15d381080ba1e3448cee69b4f094f77589b7eb55141701a6b7461da5ccfab755604382465baa67ee45306b11e938a702263b6d6e57f1063c91e3c058983c140c922658e9bc30c9dd11e545f39a1ca2a8daab0a34122dc47f830bb7e9c5b37618989545f83d19952392cc64bbfe3c8f4425bf824727ae8fba2b273dd902fc28fc8b13e6b7b398207d8e9db81a2dfafdef47dcd0a5eca42045a5d98e035637e77ad42dcc60663211f186e162ebd85f2dc7f75c1e8fdabf7edd122ee3f429e3688212e048cbc1c17ca0e08ca6bb9d563eb92127a84d2b7631296ac6ba8639ccd654d4385fa5d566118bca81682f90b2a0c6528f72c688e177cfffa057c109036827a5639155c02b1f826adec0e196a74ed270904b73ff0ed2fe725be6f8b508e369686e403cf3a80ef2a74ab294c7d9e7a460a9f056366f4c87b3297740e6771f744901bd700b60c28a48875da3db1602d5caa1363e1351276e29d0db9ff83b3e2b20d0a83777b861c740500a64b8fb986876f36326302e0a0a55b54267ae34175c73de36dd5eb75c0945210c43b7261f75b270ee4aaf936caf84a9402469e125ab665ffbff383e60055214700131d0df2800461aa296316639b8f3a0c71ad02a907b15849ce09c01bdbe933ceda8a6d07f6fb857fc67afaa77d360cab2cfdf3bd1ecf56c6a2e6d6af8aa08d2fbd481e3d8c507fcab7d0f7db46749f70fdad983b5590b2c2b010d44203bac542925b2010c2da1cbacae095c85950a4357bd77767abdc46fc81d6b60a33269460bfee52a7ca7c227cfd23e62fab42558692e340785ce79211e67fc1f5918d7ef45cd37442734371e9b931e31006107b5bfa66d6c47677f7ca95bda59432d50814092709293153e4d8383de5790b581cd9ab5f994a460caf3ec295ad70bcfa1013ae6c3bccab1349790de7c0635e1d83d65e0c50c1e449293d4465d8698d02593e96370e2b4797514a293d46e9b132a80ad9819f1df8134701e01c9441553ed36d98fec4511a3e23e635caa02adee939a73f719483102c4196e9e58d6983be970106e960a9df06d90100a4d870f7de064e2925e69f49a3ac7700a1398b79f6243796bf8eab9509ba58ccb4341c3b4b0be5c6b27360896cf87d6178ad187a6a45cfc3ae182edde5f3c6f97da4f8759ee31cf67092d861a6b1bbb5ff48eda99fbd19a99104ed0c6bc115ce25bf8fec7141100441ed16b03a8c541cd93fad6240d7e0fd5c554710c749b2f4b13356971453242693381a26ba4c82c0f3c18a288241a3abb43f5a3bfaf85c168bafd2be9736c8d25e65ad599a920496f66594f643972843c61433ef95d6c5b084bd5c5e3fcc621e7de0ac3ccff33c6f3563c60c2b6f472934967c88f27594627a9895f7b83e80e0bdd2878d87390c3883e6ebd214266a683cac21f87ddfc669e2458a2239aa5c95e4a2515a3476ee950d0d0fb7689616e5c0868af5323d6c892b9cf2f319250f35449086f8f98043595ab4466973ca8a632d678d963663882646e9214bb429ed8b3533c61ff66d3c6c89a9d2b25075b2d38c965675b2e3246163634ad47b2919e5e7314a2b6406851c781c88df9429605e5353da87bdccf187fd9aed36a30f1a1bf4e58c3fecd37858c14f87a406aa4ef619349d095fb924090bdb0a655fb168aeca4286d4c41045987f0e8b01bbb9a1216a2f8411ee99bd1cb2acffba6fc39565454515497af8c31a4f8bbac33d40a83657caedbb522448331ea939427a787335cfdd117acaf3852408865f189a46ee99bd2cc7524553b5606da840f9fad5652b26b569cf3ce6b31b39f29271bb91c41147a5daa736079c4320d8dd01257bdeaa86f6824cdb7a5015b1e5abd6077a5f455b6545434e94c2f255d92a839e38ba32851c6599160c55a48a243f518ff59edf58efe923faf77ddfe861e839183a587eee89368f61aef8e18f14bf51a4f95c3142d192e0f8e3ab92f4ddf8991c5cd9e30fcd85aa8ef3c620af0749edba82a3023ef02b41ef03596507e8aaace88963d957a5e9a77f6359ff5b420aa225a4f08076d1eba74620af108be04a0c4bfb7ddf575333a3144118d83ee5f165d80f396eec44b9c1445413090b887242d3c4501143a5891d929ad82188232cd2488a5f25e51fd4338f9eb8653bf7cc57bbb5b7034b527862aaf1b09452e3a90e541903ea998530208ad5a19e96e8fec01f8e257e9ad123491204c70e6b526b10f4eda0a7bdd0434cc381a06b10fc4813f4bdf7f8f9e8dee863d4fafbf43792df57d6ff3408826008d6949668c6147be43ad548aaf40e73f63ea8b22075e7ca42b8677621f8c67d588663e9b9558d240e2950651da8e7952db929841d6079f625ac96578e5e4720f8694c5bab3a636987b618a229f16bd28354996d5243b8324b1b1a2a69dc36a96188d473a8c422f9a5b2f84ae32931134db1ad87acb11c374dde824314a6e23db745e38ffb9ed3b048558a64d19024a95291244923869a0cb9178752abc3675f89241996dca7c8d438a6ea9579dce3d153722469c4f188a64f2d0af605001530686a2a8b28e2e68a4111351c2cd0b2881e8a50a0288aa2288219638c31f630aee0e823144131e87b0111b7259bed531e5bd4fbca72de73bd3d30d262285ecedcb2afa72d945322a28631c618e32e77389c6c71cb02f5695da2b5c5d699a356448bd3b72d484720296184aae22508170c59c75eadd6f63aa00041b605542f833c36c57b8a1788f69d030df19c23e9f19d037d1d7d749c1be039e76aadf55e8b67f88cbf3e830747fe75249bfceb244ead3d9d7767fe96291316fed26ec5ce61ae48f52006f8eb48aacd007fdd00f5cca7175fcbd58eac55c7bb0296bde3f4277257669b483506717070403bfed8ef63a15edba6d75687fd42d1d3317764c7a5c410745c7e0e961c3872ae4b1e5fc72018088fd7a60f8fd71e6e0b5ecc9119b8af24bff66c06c93408efedd3d4dbdab9b86fceb5e62edfdb259105091ec2cf473b908a243be7dc0d177c47ec5f89bfd273bcc7f0be10f555f41eb76a1cbb28d85cbe185ff07e453618e0cc00c9c7aa735dac3ad77f34d9ae7bb66a99f37c8910cb9862e3af3722a8cf8e7d68042284e84b3d2b67b93bfa1073239ac163dbe1effbbe2e93e9cf67eec7fd9c330dd96141c214fe1290fdc3f60c107be63f9b6dea835c53a79e337d526f1fc8b336886cd3417a2aa5c181e869cdb2f2b416516140e3698da2e5690d53a7b0f1d4b250c353dbc47aa0c653ab030d4f6d09ac941e4748576c36223826a4879a8a9ea068656896d6c4d3e4b2351ccb361b36f6de7bbb6c6c2122b8a9a94967b7b5271ccb9c108e657f7a7a12d2dd98bbaf0ef5ccb7766523ed88467baa3dd59e9ef08cc3dcd1f6ec9d109e75429c1056125212aaa16196b5ea78aed2be5212bb46d95951cfecaf128bcf7e6942ae2719ec3bfad8bbe5da3649220d0d38dad837be6d80256eba67f6558999ee99bd55e21a2556ba67761a25364b25aeafe1af5289eb5b2b67954a5cfff2af54e27a162d3bce5265353c3bb6d51e1b9e9d089edd5aada98691a8b29667c74ab527c7b3e32d55f6f2ecf84b95ad3c5fdb6da2e1d93153ed71d96834d7de4db5cf8ea3a8329667b7363cc3348c9b6a8fe919d7702c3bcd46b3d59a30aed9265cf3dc46695f7b1dc31b27ec87e187574c912328260cc584a2987014137622ced3d3d3938cd23e77d412c3d18757de94f66f0dcfb8a76bc3334ea909cfb8a31acbfe5453b269bd8f3227849f3aa11acbeea2b9f6ae55a1ee06cf21c0418236e3f342460c0fe6a5fd1a1b353aa14e48c80535da3db411bdb2e5ba6593d3b2b101713c74cd28edd3d07829292929b9c4d1c7fe0c5ff94a74ad5e2f72f4b12fc3bb312b3146693f65b2ca6e8c109ed5ebba1c98d6f7e8633f86872b1156dac74f78d61db9f0d39367d6aa1343f4cad22b675cd93d3b7bb60225ca95a5d9cae7ecf9e866a3ecb996a1585957853db3e78e8ada595175b2976537c69ed9bba3edd9b5f70ecd1cc5d3eec98736b351ae65a3cf0e738d3ef6611e7a1d125527dfd086c60366c5b16da6fe91a013496d9a84e3f9340957e433d32495c8ad9eee74645430214068ddb971eeaf9e1ae1390105dbc669bce5777b3581fe639929d0b3bc5a33adbe726ba6d5536ec71fd555de03b3caed951b7da4542995afca9d7baaf6aef6695aa5e318698e66e89d8b4af2a73d2e0cbdc3cda3f2550823d39a4492230c3181080a468e2459f2736541240821b056290feb48ba2d536679c26dbb57ba978e639e6f0f8baef73c34c14fd70e8cd68e51207265d684c1481849b304d279708ca70ac121e8692d23866ea98c014511f425777683440b823284dd1619d5a21c21892168e4084649100461a0a71c081d4b186822118150bc878c4e9a3fa36985700c5bda1d00f68a2e3972cf303bc935a26369d77ba6e7737e79705a9954a85a1c6b5be662098aa64f3517a1c74b342893facee70fac0e969fc915a005d8cf1ba163778d1534b97ba2554666674fb93fe133eb09a109aba6903005bd753551d081c4aed54c897c769cee4fb50a3bb774cd417159420eac2997e358e8e48e9926c9abd07719fa55d56c6bce35062d5bafb592a3991e79d145b30c5d888fea3db0911d330455d8f9225dee38ee89d03a90f769effbbc4f7be5e8799e977a2d6141aa7618d8e3ca520e04673748341a8d05d7759f85beb3faeb3c3b40003f7db9d0bac72de279d95472bf48d9995c4794a46da97ba326d5a4ab83abe2f47c55d899e9ce77ad96b37c48cb599e9dc5f21af3c7c659fe5313aa4a587657a6a1f1ec34e64f95ec327f6c6aac38027679baff75be8de318e8ae92a6ac38360ac9dab1e740c1d6401c96dd6b4a5836910ca9711b47b2808a22f149f9022a4ae336e6cf4f3581d02378a6d38a5d9ebacb741b58ca5c40456dcc8ad19a1ab7688db983d2985dc515c752a6108cbb5bc7f957a69c6e95156595155d817065faede83dee1c5f29dbbce3f5c6f0e4c8c1c3d35d1b7523e73c6fdcc8d736853567adf776b9ba6e8a0d806d630dc2e5f20857e699a9911d73847b620721872dad49d69452c4f31052260a3786555e97183421b2b67a9c040dca632b9f9704fb12fcbaac446a84d96935f3831d842bebbcb3a6919d2034539a98f2563f578ea52b2cc1eba968adadd3e2ccc97157e134725a2d396eececa890c3480e1be559bd5d7eeeecd8b173ba6bc794e424d903eaee7561c77b1ce8a1a7adb733d2d31b6f73bce5b9f1d7473146ddb1834906caf70a8535e7ab5f334db3a942ce17a96e8de43c767dcf5b813a6b83083510d26b537b7dee063e24e11e7f6187c354aaf6a45224597b48721c6bcf388a62ed11c530ac3d615875b283b547f780e0f7d59eefab3a596bcfab3d9e577b744fce5d577bbaaef6e81e4e97b8f68c3da463edd871edc15507e3da73ab0ef6da931d2c6dd5c17ec71ff64c9a84fbc8cf7d38526b3305bdf322e0a73fd38773ec1a54817befbdf7de3f681b8bd893709f8b659124dc771e7ee991ffbeeffb54aa0f54a954aa0ffcb09926e1542a956aefbdf7de7bab542a954aa5523913d5de7befbdf70fdace5eefe98489ce1035e881082cb6ecc0846e0f021242552a95aabba2ea82683454e535d05095c904488a132ddcc087114c6181093448177114461474efed4f78d06d3aa9924d7d4f0cfae8479270df8d412a3653b7c606e1121a8dc6c2db22523a17afacc81d47c71d5e85a1c69ff1bda08be2e7593be9189ba9f631350284f41808e9ebf8c39e79fd85eec3994a5eff79f6ecc379068a68efbc88761c72a176eda1367d3ed5aa54959d572096f6b5ea6c33ed4cece1980221e91108d094dd7927827e5c71503d3304145878f10518619c4159dec4a2421eea0408659915c7b087ee83cf9c3913c6e714487d1fef3bf7c17da30f5cfe103300f4d8f587494fb16b0fb1c6a6cfe76966b9fe3cbb765ca61ab3b2e9439a525c60b913264e80d0168bc562b1582c7fc283b29c09cbdc38663d28284888076db9d089b63c48c885b65c48a32d0f0a7aa2d126a932349a0b6de299097a72a24d701834b4e54f78d0960964695b4f8dd4db1701bdfee81bcf727278628b5015283270415950a430a2690459c424a14051829408da418b9930376d83105c3e20450bbeb8805aaf6308f56bbd91822ea640482f3a37fe007acec522d761227c8ff1095af6e7f6cca7dac1ac00efcc99333610e1334d292cbfa3149808cf7d161882debaaebd50f4d639251748815e05efb303fd1d45203f9b58015704fdd9cc095062df336122e8e7dc88f7d95482bf33536ba6769582507be991d76691245c11cfb3fb749e2ef96c2a797d0e75f97ddff77da64fbe99f1c5aed5c7be6772cedd48b5e9d379eab912fc5238603b2f53adbf9a4d8068b6da9050500b2cd050d3279b52ac7726c7991503519708011725abc30bae6cf102044ae82d615ed010b700062325eb440b2ef082438e28c0c878a83d59222396b8a0b7cc51046a6fb88285857ac301cb086c51540866e000c98c992f22172d98904624aaa0010d492782b6a0614ac465b571c9f2041aee246a4accf045871a6e60c38a2baaa882c5010c2f94f9026552001a6280c5fad005caa485038acd7a07908a8fcbaa4588185e406f599bf8020d695a3435448041460af4962d2270131f681123848656bc65b805c525367f0cb083172294c90e098c208362bfe64f9d220c223228931c39404105c5661598bd1f789101c93609752ca9c0868636053bc4007dd2e5043ed870173530b42720a4dcd05bc296d0b0f312e603652a1322904208bd650c17d0d01371f9738108820430a04c442094c2ec584199b098707985681204137acb008c416dad8726aea0b7cc41020d41a8298a422e94985012834ec084de124603341c455cde1e5440a508bd65ce13a83d6ac28484de723b41c39478cb4ac40f282e7f3214482831a14c307aed07d6c34d840e2da0a1b70cbb4043951149596e2b1197f58819a0a0d05bf628a1214b0025588286deb2a24caec5951ceb8eff3401ea9941100441261b62fbbac49ed522a73b4e6bf003ddd3a0a7b50a2c612af307084bc148edb0518320e88ddfe7a3fd5c875f8f2778b86172043decc43c82ee95a07f25885f952247cc71a31663897449ba17a6c2d41108fe54fe1e5527fb0f16ec550838969d550ae9f104c9030daf4bfce309b73d7e6d424b0ddef31f35ccab74a8c73bda914c813e847bf60021e535e079e314c7f1157a8e87371affaaac688af3c6117b9ee79163188e1b3f264723a03ead5034954e29711c53293115dfed9e56eca8cf088bed995fcdfc8cb868f2f8eb1217b437d2ff1ddd533b8f2df667f432ebda3f266e0cc2d168b60b26de96351e278afdd5ae2cdb31011c8df69edff1bb955f17ed384d5bd37292bd98ebb2a73f30fc21ea171535686d279a740c9711af187839befae1c606edf9c6f9128117ed5d8e9d2d9ebc94b4733b78b4b879413b06a1478b065f460861a5e50ba521f7d42e440b17d8ea0d0226ac7aa00193bd98ebf20f14eea99d88163538bdc4d42623294435d18e931cb139e354d37e7feea97d490a2a6a4807d1525033a04111aa79c20ba18b3db796c80e6571c42b8b1d322ad24238bdaa28b2f747945a94086c8dca51f8c34b89a38bb92e7bfa03437124535bb562b5686a6c5caf1b580c193370bc3469e4d4b0c1c1190340071d8800183d8f5941aaf9ba94050e42da4f2c57b2906109ed1c246511f41a637bed36b428695164955e7b0ddbc5dea0c438bdccd81c6ba1b6dcc0a09d8675b24d504338dd98c0b463ec13540a40a0bdb451160a4a0728dc9ab165a06a70b281769c1b746950505e49da67401122c3d842bb0ca221328c1b12688f6154b4c944bdc2688745a96d324e4568bfa172b402c3c2d16b7f5941fab844bda8407aed2e2c573e2e3268b749b28d4738eda0bd468b926a053128bd769a2e37176eafbd058689a63603d36b6739358de08eb94f580c3939797aedaa28a8a81b1db4ef6be6965985e1d4c42df3da5341341b80d14e42118a7a6121f4da47a2a14da686a1d72e1a15b1647013a43d8c526bc1600aed2095a32088387aed9f152432556e88905ebbc672858c0e3746575ebb976423432485edb5672d4af7d464684f945e7bd7e596c50d0db7d7ce8161920209a6d78e9d9a525c92d07ec73c8d47bcc088821283b8f100143683cb8c559c9870197b31d7654f7f60288e646aab56ac164d8d8deb75038b2163068e97353ccfd1c739faa8e6beb330cca95163fc1144237370ba82a341118a7addb4d3201a5ac5e074938376d3a828eaa545d16b2fa3d4c0af4b5734b9b941bb5339526961c4910d0ececfa8f6d8af4b943bfb986e0c87aae3db527168d7fee5a05def9ca7bbcbf519bdf6302672a3e7d80a522a8c1394762c577093531757926cf989a81b68b75a94f213af32dabbdc5448dc84e0f6da678061f288e082e9b5cb706ad241bcb834bdf618639ec62a373c68874541793cbcc840bdf61bce0c5766d7701345fb2b8836bab0447bed2e284263686108bd761ba2a1908b1713da6b8c8a3216373814bd769a28b5d0e9e584f61695a30e0aa71b28da595690a29cb4afb05cf9bc386db9f2da5549b6a8276caf7d6b510a939081d26b4f75b98d423845717bed2418a6a82c985efbe8d4c405f1d4f4dac5314f5a053088821279707a69817aed6067a62b1375f381aecc6bff8268bb06a72368af5d43118a7a9d117aed1e0f2d76261afaba64050c7f5302ed790c23aa284a7b3786e154eb527bed9c0d8e5e561cbd76acf4da3f1bf518a985adadf9dd865e3b0fa81df5da77b4f65b96f042155494f042154e8fcd5497c957704cfb0d6da79eedca6bd75157865d73e8478bfa8a4c0f8b0dbb76cd7465f57a5837e119876a7f00104357f60f0062c883f2a23c3341505e131945a162e5b5c6a2935e6b79ad3dd54faf3bafe9b567d3c3724fed39292bdd59e85afc9ce425dd98cea667bba7762876e79eedb57f5db26bff6e57665fa7dfedb5d71c6d16016fd6cb93b0e6a42ca4ef3cb438463b0da142a8da437ee76998c5172fa056355069e5b47aba322dc395d52f5e04755a869593d14e2dd2237d0885672ba71beb7c4c5886b632231434f41d0b4ad1772ca2ef3c156b0f04aaf6a4be034ac3a8efa06acffece439c11ec9445e53b20f33504abf62c2af7b372cfcef108a47bf325c4aeac1a2bca95e97be69c7144b0d3efc6d55f397db7aa81fdca25ea717c5d6282e9415beda90f72fe61f9ae9adf957b766ee53b53237d49fa865dffb3ddb3fb94be68730eda3268bb330fa040a52e601338e6caea521347a016900974029f40a8efbca660d4776099ef3ce31bdab01bb1c961b382f9d48808260d0963c3aee7e71e76bd7ad942fbea65cb93aff7cc5e471f6603a2d829abe83b1babe8ce564f37d601d93f001c76aa6b215e39559dce7544b1411bd67aefaa6d78f6a35ddbb056c23370c8e7a059b1d277ceaae19936695538d7fe59f98e33574cf7ec9cc7ca86659c4d18c68e35957b76ae6b51ee4c7b1796f9100ac73a1f1e49f748ba6fd59e185f6b77a673eb5c1f5d59b562bb32ee3bd75aa87c77eb729bba1cf1a9a6f21d97a25fea62e5539df49d92be7da799be737cb9ef7665e9cae9ebc2ad9cee0c4cbab1ce3bd076cfce6dd8b873aef69d67f73aff6e776659a0a19d7f4c57a669b5ea68242cbaa6a95cd9f5545ff9ce79aceccebd9248c962c910d69c1002e1ec9b81f0c10b367e241fbc607fefb52777b587bb9e6b9d1f578f40d5c19575a6635b00bacebcd21e551decb87a05aaccf6504f7c6fd00ddb0ae91862a7d5d603bb420773d9a3ea60b7e390cf43f332b9405c817e6695ce5cc2591d2b541cd8ffcce3c7b33fbfb8b66cfd5375b0dba3156c4b25ca3db1a7f5cc4e2d4d6ba41a5e3636af95adc657ce62b15c2e97cb81dec6a655d6d4b8cba6a6a459790d8d8985b03856de2ad3cbf42bee9eaf9dd6ed9cf470e331c69dd6ffb4d33ae6e7ca3a23e66f5779e726e0d98d774ec4c895a97ce59d27e97c97396e4ac7b1d408cf3d5b5e4705e87bb6bc8685893e4d72dfe52ca72953a0a7f13bfaa07999b010eabf1c48fd9703fdaa4cfd57becb94c86faf2953ee6bdc55a6f65dfe5af9e7e1155da5cdaa64b9ab04fa5d26e9dec6c433581c2caf29d3dbf42cee9e2b6f95dbacf75c99f59e3dee4d59d1eda9ede4f671bbe8f5ceb81bdbfbc66f33559265ba3ff40fcd9403d31bdf79a6d899452cada3125aed05c90e1381f3cf3f33d5ce05c95f087e61f885e0c7e9cfbfef4bc57b06f1b47b1ce630c658748c31c61873185b5b16d1ee99556720d869e7c68df3dcd9e9ae6d8ae1522186911848a9759ceefbb5074682ca493f617bcaab5b956aab368c0496935e028da74a18d0e37134613012564efa901a4ff9ca497752e329077a18092b6779092b1336b24c9858428d091bcd956f5f81e52a2f617b8dd7982bac7cc344134682ca5b3e44e52df3a78ae83f2c57b9680ed9def296f9b3327faa0c61f9ca7faaa45256be808aaec0c4a4ad4c262b6c6f39cbacf50ec07396affcfa094bb0cc74ab02a109b5c7bead59bcad54bc75409d69b3569c56259799da29feba2dad09352d2a30b6bd2955b195defaf5eff682e2af094af80505be8950756a8d028a279808c1da32d68c8dba674f987d6a9dda7b3b1d6c1518028060229849ec5f07faeafa9631ee693918c7cd584d164aedad256adad2e4c5a7b54cd3954f6d90c517175dd99559eb9cd195c1b4888dae4cdbf0d6ea1aac1f594224855b53520a138529891f6028814b044b5f66a064c536e596b13e82b5a18ffe035674ccf81bc56bbdcfafd70fdb74878b5c8fcb94c3a1da661e7e30c3c64555c73a12ee8540fabaf481a04fb921de7a00be2ebd20ca67112c2b1a9615bdb163471f97090c76c24ff80a8e59074bdb5befa0aa8e751c2076ca19bd75ce88c3a1ce70116782b75c95b7dc0a48e0a1e8ad755c846b6ff1d15b8c7465aab75bb0c028862eb2106b8f0cab88a42000a29dbae7681adefa0e8c31c6256831830b8c08a205657240afbbeacc03295258d9c209180fdcd0ebb5ea7a65b09d2ae2c812eb4452e06cdfdd60c25d77ad5ebf6601c349ac59c1504b4f9020bc2d3581e494fa81062b4331dc8a9656e053022c5dbc688921286a288b0dbf6601e3cbea8691a62c7d3162e90bd19770094c1319294f5851c55196313b34155561e5054ad820081e5a00a19045f05c6c7b1041eea1966f524e6b8bd5b5c3766d9ff2a0f0c51643421eb805a1838f5b0b4c604308b8689104fa52f020f40214dc70c51068bac3e4819bf4972986e731854b105a387142054edc7c5d72e20a279ea28a50328108b470c28bed89176c28934b04062d0ac57e4f29be218250c286455c863e0cd1020dbd65fdb2031a721d8885952468e82d05c0f44358f1ece776d1451726f4e787f3ce7f7e98784d330842396792f3a403da3913d186273fa0f9a736c500fd61c2b202fdc96615eb3ee00974a172541a25510953409c16a5a32841b4263058ae14114541ddb45039120a726ab261312a2a13d5e5b67363cc3d6b47f4b6deb45039e284b820a7261b166c848bca4475b92151b9509e9c926cb6668dcc94c199b2cd9daa5371a6ec6ade135f33c73d6bec71c2ec94fbca913011b29932f9d40d383d8c507fdde8b9b746449f6a0d0627ddf0aca6d896621bb65d9c74cfcb99d895d8a975c236309f6a6d92d9fa7497754e5bd4da3cc6b8c6703df1ce5bcbfdf0e7ec5847a86c04a6eef270cc4b391d29581cd66b0fce94bdcd108bce7988d3c3f63ccff37e7a5c4f091dbafcc63704ab23c7e2b0d77c2a53aead0e102c0eeba9cba64c2355a73cad83f0f968a62eadfd9aa9fe92eee31cedeb15349158eb5ee762090bb2bff3fd5db5db66222ad46de11c9a6de3afe3a81dd4f3837a621d7f7b0050756c0a46ac898267ddcb393b5b7c1bca5c87b5dfe88163d7776e581d3b64366de37c47d803cf92dcd8755c829042087787d5f1b533ef3d40d5b9dc9da500c23def0d6ff5b167708faa731d2787adfdeb2c051cbb0e85c496fae5af7ba029855ba4ceb81ab32e6e51eb177fedcd79eba9852167fb43375ce1599be2c7beefac5e5bb1e7186324f6d356ba3f3ff73e4c80ecefccd68d5de74166a755e9b47ee39ef547fe7a4f1372d8d6afe3eb8517a3eba92e7be21c16c7f53a33c7e5aa0b3e89f5de9a15851bbbd84f3cd3336df2e4b03a5c168701b4d6ae1cd7791c50715c2fe392c175bba38aadddc5c313726ffd66132af6046053ca0a9f6b13b4ff5419f29929bc75edd688ebef69b1ae4284e00db3668f7bde7b6dd8fb9e4384a4315a9c5f8ee3729eabf7bce1c23884e0e7803a134d1e1bbb1eda3e504965561b63eae02f8dbf305714336c9a4f2b18eb45e2956d8d2cd13d791e02593b8f2d53226f93746feeb03a94681e3c5607e7d70f5067ae1e25aed79e1ae0afeba83dda79aeeb6b8fd3541d9c69892c0eaf94407d403dafbbf08c02d5048ba342d5b0e27b4ea83ad7af50d5b9cead9a6cced471c4d69ef2882e3c132d11e7b7c6df8b6b20b3735c8ee8ddfc05f6b0d6eee8e8ca388f82af3532828235ea3aed85b6a7dc719cf6646975d2449fdaa0faa3899d5aa4181ee3ff981cc7b073497a28d51b9e5554a93259a4253a48b0a5c086c084882e05362475e6cc993368e8f5393355843e718c03810bbd2c0d1fc1339b822c8f1d89c78eb145b2edd41a3de61c8770cf1d162967a43bfb9a6ad2edcab8aac40d581e5728311669ac2d7909e353abb4e4e5f6a9ed52f3a9656aca1d77e4a425c121f854fcee854f6d50eaed731cc7e5e0b9336bc36eab8e047889a1e2a809f00282aa539fabb3ebdc73a93fc3af14b2e867e5c75eb903c0fe7991fd992b804e02683ae18182beef00b0874e80d0cf7f9eacb081cf79a040e8e73d7068c71f5236f0b914d0ecc00ad799a07514f2993f16bda92cd6a684dd22e14b53c510d69cb4f658e7a0fcf520dde34bb3a5f5a1ea5cc71fdc6cd20dcc13d40e58c4a4168b982e9fdaa6bf517fbdb3d687b742e364f077064be5ab353fd5a9fe0a7eaaed0cb4b1eb818d5d9ff1a907333c7079e0410e3b83c03563dcb43cb022f8c35a1f6a4fce6f697866c28d5dbff77a0edbd23c1ac23015a6ec1d81e0b0daee92b7756b2a7ee56cbd640af45cd5a93851ec5aebbdb6d6aec3d7765da7bf0d3cd65036ec46fd3eb9eb7287c1ec9f6bf1865d3f9b5fb9d4c5cccbf8bad405cc879f088e3eb4698b6c8883c3be5eabce9d853b2a8e75a5cd666772d5628c393c8a70df9aadda9373c98d3ec02a8ad87bdc71fcf1bdad3a9d87177317933011eea748809a043999a1c8882b51c40075f241b105182cd83003299850ab12ef99b355a9d77b2d67c71fa9e7bce3c0f7f8b3996e20c687a058d1fbfb39b3569d6b8b380edbce1ebdf56f1de1d90aa1dd3939fd74de4e10cd15c29c35944883b09adc3d6dced7da247ead3d58d83c6e60ddda1b15d7421e61ec1c3c67f5ea64a7fa2b90b6d686097d8a789f7241b0735c55f92cf914e8ad09846d06c2106704bbeb92dcb38ee938cf1eb6f69ab62bb3e3d287c9771d54750834894e030838ddeb5d676d27e49e9549098561f3ecd8d9ad1b396ed4aec35dd7a1f05d0adf714cd2f3399fd3faf0ac26c110e71f982beb5e835c34dd8cf8bac4850b5aefed72b99fa75117b4af4b5c4085f17529aa85ff6e78f619ddb0d1edd6aaaaf7ac2698d78e3593d7e5b57bb726a71b9af4d33d758773a685b5b7a5078f83c34ebf2eafa5e811b4af97b9a719746863efe1c2ceb59a3aea9eda7adc2cf46aa61f98a4af1e965f971bd3019bcfa8d44b180a8320758a6844800000c315002020100a860322a1482008c44c1e7e1400128294386e4e9b4883519085308631830801c4000000000200644646662732d159d907344a74d5da5660f6168a4a422a76dea6ec08e286c895d2d9c8c446b5cd5edcdfba7ec260b1af71d92d1578f6c8f4ec56a21d8862ce38f3d61835054aeb00c35426d5a9e88b3c858ad025a306199d16074ebe5afa3136eb761b77998e0e37459f8f6c2eae4f5bdab245b36c03444d208b15f2d4619888e4255a6e9f76385950237bb5673d714a6e6e1f83920cc121600cb712fa221f51e9500beff54de9766a1f93ec95e2426af1814eb02a56212233ddfe95e8f39b74bbd076a37ed3c7b6400507a9577c81859392919db93b7d1e4043fce0d597ffda14d8a71c23ab80b2c7238cbcd4b83aea6607ddf30c484e6f996828d9cf7c40ed376672918550a27309f95a92c63ba360e0eed402ca1a4ddd855052e8f5ced4c7d56f61f2aaf7006060f3c351fe3e6fdd8b6f8a1931d3b885daeb934cfa047354aee4e087a25eed2bb5dd25ed047befd0ee5ece83e2ee9829780a02dcbe33fdd28ea2c165a772d5d34c36803ab07cb4c1823831850356fd73f9167d9d3334e780a3686e24ac966e914f16b50ab5dbb39743dcf2ca1d11c3f9a67375ead527d879a6a26df4a288c436647d92c6b62c0db3d9ef74a1cc6db53f52a2afc2290d7a2e266ad4357e99e3d63807c2317641ca2fddc807a1143f5d4564fdf8342369e15c7a6c31c9a850ef584e5f232f2991c34928b3da43ba03762810d52d599891a8dd269a17abc6982a4b1f1c9737fb8d1aad4a4a0923d6af820dca11db8fb1f7f9e5620a7c656a0b1803bb19db76c115bbd59ca3fd533c41ab07d1844d01543dc8b51b65785ba62fb86a42fd221e22465e01bca2662537d4eecf974c9c96f71b1fb2e76b46be10d57302e5dfccd8da0c0020350364ab5c80388f290c3b20a3acf7232905fe003ec53fec0aea6175a305d82e062d2148066ca035f564b7e2be204074f9ab07bf6f3c1447a28cc6c11b854e0cbb61d742f966ab8072bf2699dbcd6c52f82ea56d03d67de2e8532987f4d29c40359a4df4dc2fc106f7260e904281edba31c2f6076c5780abe094851e2b699a26077afa55bade923e39948a90846092d3b0e21da861a961b688c93644969aa248c7eb73a80d0b079c270af53e920f300e15bf960b3e24dd2b31b8ac5ef0ae40e9e42bc94d1c4d3e22b8a614da58329b7dcfe25cf39d925c5335dd16bd0b917fbb5ca43893af15575fecfe1950a39368a2928f7d8d8886848935c93941c42069138704b2eb16b4fe33a31f3b6278ceb259930d7d000cbdf1b3c3eb0983356d259603b49a5524a6f51d231886d2955f236269da38eab6a8e441696d44447918a692e7770591571c9704250d447f7c042f93c7964e2aa401bf28e25454e10d290c5bd4ea38df4ee6ee169edc8898acf50aa0337c6859a71f29c006b0b5c0bdc832273d148cbc8e3e9b2ec91ab1878240057f0c0d37c50a00fc8745618df925e232f9eaa2b0c1f8a4870ee90e47a597addc3f94d94d10bbe199dee8c42522d512948ee6f4fae5ba5d8af34076743a3d682d2dbed6fb8d4cbeaefd25197cd7f5bb4cf9a8f36b99f95eef3719f954f7b7b2f8a6f6b765f3d91bc4b959eae07fe065265b2d959b37552a543bd18098d949209bfa13d4c4019d0a982046263efebee45856be6af88def7b8e65e3abe6af64e513dffcadff82deb2f95eef377c2739223bf36b3fbb67c6a0b0e3a962b6473a78776a2780e9775f9dc1542780d4ca93d9b01aa0789d8a142c729f6dcc020173eb98af3920fa9b98d62da6c802a3aa296b87d92766e125b2daeb0e6d76ced01fbe4876eb376753e9d8dd80b0d87c4892499d9b70854b0219917d5a1d1cc33c7fa53e0e2530c87e70fa800cc2cd70a490039df8e307b16fe1b4e2417cb26b8de847e10d2cd220af3d8b29d7050c86e441a23b90b778318452d3f9215a4ada8024415656d6309886894c49ada823a8f6d4584186fc24a0d73b1e02c5b1a7878e7996dde9bae7e876f0ea98e7c4a1ea248cc46b5bf806b89174e62cbca4f611078a5a67257be2d0e93f4aa994ae3424896fbb51a159971ead44cad9f216b34d631a3f51b9dc4290f5ef5cafde4c9146b2ef4468c046d070c77630db7f527c4e0e7dda69dfe878059dbf8981df3cdddb84604f86bd63b772069af67cc1c28e0cb99aed67731c024ce810c6d61460299f59f62a889842e47ce675380f0f5a74db4be87f99180c071cffbd2df34a61b7ec284aaf736b3b027c8b3281c2dbb724400c1c5773fb6aefb5c07f9a33da25f9323e60ac7c22c932b0e6daa5e1d380550098004ed20e722540632886a24fb91165afcdb2a4852de96064df9e1cf93dcb45cdf9bf34408e9d18f4c39ea3d4253620b8312694453668ef5888a93981ad2507e83e191097fa98b88c927c1f5549517a0618c0bc5509f6c43eafbac18fc6a7a9da63f940a82a9b5621a66ad16fd7bf1f2030f41c12ca616e0d9fb8e58e62c83a6db1cb5c18f7be251b2597c770cb53545e46b3b968d1bbcdf8b1e17ab8bfc57b30de20bc8e256a06257de50ddb222dac85990854d0d534bb04a21e76f2d060cf467a744c6f987b6fb38e05c8fe261ca2b680d435485bc819a95411ab38453219b12695fb346b6a4471414c827137fcf9b42596b4df8117a78fbaa5a09359e1cbf2f8be47ea03260488ae8ce4e42f1b008b426e468a6dae233a9202c6910c8ef8289c935f579c163b2135d63297bc57f482b5101f588640d78f97db70520b51a1a3006351ce0c8b4d890a713d0845dd23c19bd5ee45df9220f4f164dfabc13c19ea2540111dd0cc0d778d827e505a42b03301520a8fd0e4421c29a19da4c2cd5474768a83f7fe468a1fda936b73e502fb5c7d5ba8b643118e2704f762b7cbd2ba8c2efab698b04383e2969b333520a8011d43a0f07cdfb3dc59a3e45add630d6dea23074b9f201d693c7e136e8ba4138082d0d0647cfe14e43cd55e43b7df36359b256308b153750d4b94f116de2e3fd31423bf81794981307e12956ca54aeb5780feb124a6831311b4fa5952677027b89837640a875b60ac0a841681e47c13c53ee828627bc03e9b78177ac6839f1f58713b8364f700576176530b9911dbf326f63c943b4ce78a78453d4dff44415b83c5463a6b90fd40a253ecaaf4c92de66b46245384a17066c4360485b7bbdd88bf3391751ad121790090fc3a117cc1472e0a242f5723d959dd4f4c5ce170bbaafe5fc92c7dd3657b352b2c5ff34b66da2f9503d899b5fa8153de8d70258185aacec0994a760b674a0cab5c43b92e6f882db2eff8ed96cbb3731655050fd762d7c56fb903799b31f1255f5a8cb8f37f041cd5aa0546982c8798e80468c49d24ea51ec12e5993341e333b51fae8f0a3572c273837eb7f25d99e4e722e2f5b09dec04a10d80b58c0e13633c8e1f1d7175cdaab03bfbb1a402b6af60e97d630a4358003a4ac2a73935b04a6316b85c5c3adf4714344254a19a58493cb52e2f6f8541993f120934d705327f74d9d3859f20b5b2768ca355756d1428696fe7419f77661fcb2897a425f29ee0d4ee9939f96a97ebeb802fad0e1955cb89571786b8315d1295ef23d53ad088e10c3cbd8eb217404514de29bbb0722842612b07b890191f1122848c78219c381b79c118ff239cce125798189d031e8f5a2acb899a00b81ecda72a7e17781a0954ff453a75e12dfcfb39aabee18d6d2f4ec1991175e182a5d1288ee492e1feb93cb378e71ffcf87e19213062302cd914916cdd74a85b557e0d5491d2a899f63b97d09d92422cecab004d58576e318b48535494732785bdfbb555950cd604be00f4942d71f474139099797828c0239bf743ca108d30212f6386b82cee65883eb9df488404a0e594bc55756c4599be20854daa4d0ff7aeacb404525c904ea692a55277c87d0e81e1f2818169da80a076a1d3ac63140a5e01c79c2658069c698034d469e0c7564b67cc7fa2a0db651a0e61ebfe86e607991f51526307069cd0a3724ab762277829f980b3eb5273c8e73bc18782238640341b77c3241f41f45b90714563f0c0b63ccc00e064eed5b5cf8a225ddd08c2c09354b2432acbcc7469a8573abf6be628cb7e42aa59174a4a242f09d30c568b699443b24d623611a5a265bc155b94227fd69181f5df94fe003e77bc9e9c950f35bb1076c00e628e1fd0aede554e1d4a5e0a0c914d260a1250fc12374e696a635071430289a72b2259e4cf9b57e08c7e170c064a379881ac7903ac4a19da82678370b334210789a21215dad5bd1a7462d31a0d6e0767f9ef07915bfdd4c50d786e4d62c447cc153ccb42f831e5a8dc4c74a58564e6721dd9d0ac934e4abb96bc7c49c329b5710e259421901900d5b8931a73ff07e3864e0ae431fa5994251f9f25c111abb890c53834f2468b124ee4eaf5b6a4d0c6b8a5f43bccb54fb6d90e13afe8470558076a7c432b714c36319addcd7616b51c0d603f9919a01d9f24b81707246b41a5c3adc1ad325ac7962ba20c1d289f53d852c7992cb178d05658f715b01aedde63fb18b7f6f39a53588ffce1a2ac007fbdd195e7880dbbfe01ce1daebbfa6f2747bc4a6a5ceec5f168442a89406ded080dcd869884558116ed7913933097b17bcf126b1c5bed51fb8d414e508cfa73a46e174c0869385d6ce2d324d01b02b99464631d41ad5f161cdf806a2ca68d75c940232301c14a893002b503e344d6cb1cbd0d2440817df416b27ab56ec7221254c3a670cfb95bac23f0fa752830da7285e80716d1cf16f803e4bce58b19c9bae799d05e3c17fb38605569346cddb610c185dd9e0f9e16616490249460f1845a4187cf412d8f5883029d670ea288fba2d25a629b8230582d064d63766b29781a259c77cbb719f501a70e360e2fef1a43617886b47988bcf9616acd1100a67ae70af55ea036aca77005839cda5f43ee2a95de1c134c2f1cce7f94424c51bfdda165490a410ad80696b9a09e299de935b7118534b89660b59c18ce4a6b494eacd4d46e6c551e4f704d40e2700f1b086dce164cd368844bb425f5f2a0a72d5101d4984a6ba15092c9f4c6419b9b96e7d8c1ab504399cfb5ae2e1d4e1807f2fbb3a53726c804ef04b294f24b3d8a253c419ef442fc1e9b96cf12070dbe804c07ed42d6bfd4a05bfe18e1d40af0215406c00154ef24c225e9fbf02954e077309a999da6ada53b300029fd1d622d2ff6212ade7790586b1a48b37e011ae55e237f67b392c7f2593071bfdc9c2113c2b057b9149915625c50d6bada6402e4127b9026bb622351e170136ab1ff414e426c49e1ee1e60491c22791e75a129b9f8165238d63f64d35b5de6d07c156cd83eafcaf0459320f9b9fc9dc8c63cae45be3d902aaa4f244b299d8037950223e9efcfe5ee24d33e6b3b12b3c62b171b6db169128dff70c62257f67f566563540bf2b263e3aeb8aa3a709b37f192527319002a9792b2093b7dbd6af1b8444369e70370342f6a910ebf81fa91ca88c64fce8c886658d0076360a236ca224714b38d0e353a85111cc54236190e99d70f566cf2724632910bc87cd8845f0f1761518f3f830d44e8f998a22e12c8034e8f695cd2bf3c7a053a9c50b3103ad083c40e306f15e87d3c6a6e83c116689faf0dc65600794538f728d22f98e58bf08bfec4466816ccf1ecef91b0677dedd43cccb5b9930f16cc3e1d8c958184788aeadf6aba6610830df3976f8c6d7796e7927c133eb410196c259de7ac3f928e6d0d3e72fa6d15789919bb473d5cbe9ea20ad6c2df2ee19732f834e568e094e0e80f197fa695ca0d96de4b3ed1c5927dd1932aa7394fe7b9cb930a4bcab9cef64c4bfb9cfb02d97f327cd483cedc5cb888f443d61fbea0ccabb1659369724ee06936aa37b9fe425fae6a045be564e73eec44fdf5cff4f80879c84abfe5a632e3822d8bbd75d2b836b3ca98307e2b64ecbb0ce2fb12d89826d8c170b9bb9b395b707d93182d9ee54acc4a678ce7b4cf971f635de06ca52cce0b5b74d7890a63f0ff9bd09a892198423582195cc717f274c5838c348c8ec5b4c244445b29b0c1901f696ab6c2311dd520b43c7133ea6fbddf43720f3ab7a6f6a97f1723f5193d88b3d3db0caed748450e7a4a2413a88e7da7f3136a2a49230d20f78fd386ac46c70b3b48e114f4572bb8257235fad7701579aea0cb29a4638331659718a627242633ddeadd190580830edf89e2f21986e79c51c25a9a52d8491a8f12ca8bc865d153dddb41d23e6d0a097c5aace8ed0d9f7d35f92e76814d5ba62aba779d247530a39fe59e98b971d242f4dc6ef8a1791a2a25168545f0eca1579b7441e59158d430f8205992e22c6b3f439536e241a8e410d4b2233f2b15cf8e7c6d026711e162104a56be23400a92751a2b432f6e46b78ce871e9aea0b64e2714e8428bfae28d20057bf786c64600f342b1f775188a7f2fb29435bf9e5f16f0d34426c085f79d9962ae7e4751dfd1b260051235d7dbc29ffef1369253a7dd152c10135fb5c4883c46e4ced4d019ed36a9024401623ff93e2f0ad10d96ecd56c5b5f2503f2f9eeabc488f874a7fac3a687cf82b77f433b171dc7185d6d56baf1a1f6024da63ba80b1d455dc3d78e3a9a211bf62f63ee9c16493d69fbada959fac1c61688ff7d527401a10a1c32a111ea9e22448e62b57b6cd854342161aff8e02f6c9ea5892c7c44cef0f92aa82762b5b264348be99187da687a5730a4927260b4744680ce19178569bd8537e42b753d728b9f28b5755ab37051ded95ede654507cf6e530a74c2e60f23cc6d0bf393f56638427cbe91625c56e2e4439c22867dc40ab3c210a30fd757068cc18f173e591358a2791c7b33f108fc842d646e73eb6c74fa4c85943a3c5b27e0c8b46c0b0da378ad2b7abb11a1c657a38e103eb4e7870358c33be8a48da91688eb34a9a68772f64cd432bc3f92bc5690766c7dfa33ac841a44d8676773c3bf4b7183336cd0b153117731da53180ac53c149371de1b93d191ce20f65e45745d7e0c4c5dc70ecde50c2913ed6d55d32704ad9b174b240d080e2915e3d23748a8eb29e35b1f0ce206f051f827a0c11304429dde9980a7b6e814a275d12a8d8df35eb9f002f05cec78d94bd9ae1f284f235e7257fb6b3657b27877aa0002bee758377a120f180610344764cf52c9daa70e856f62047dad628e9dfc22964823f0bf0655fdc401ab956b7546ae10c0bca8a47417166e47ce46dcf43c814e5375189baa58178acde6510a5fc8139e06f3fea36abb357b5dc700e5a3ebd3a7a91f47a90037ac867aa646f9247072d7fab54d2a564ba6eed1a425c0d47068e4446c8d39b00fd582afc47c5c6da009ea72587c9f5ddbbe819fa6d35618f46d70cc51ebd51506a7fcb96a6cd166c8bb1940bd35f1539e207760538b6b3581424f48b744e22d3d7f6c747ad99bda717b38c05a936debcda13954b9cdf84b0a287c1ca1372be8574a2bdd56fed5d8aa5d39fdc2315a71adf85624e6f4da9a6904fa8e9c872310aa6270c40a1eaead1345f42fa19056096f624a078e475491c4d70ef98d540c088fb49d8410edad3903d1fc72203102e3154eb8eca24a4efb67a558a6aa70d3e9594f8a35a10ab006d3df687b3f179a85c196bbc026f00b4f7d68371cdf074e4630aaff577dab71ab737d0ac3325e09f72960befa35edeec4400af53bfa1e8ce893ad4a529f824bdcd632888e2a6414080924623286ae57942c5e2870cc4bc2e64938eb156710041854feaca43fa51f813bddeec47d0ca40ee716c540a066716d034ac952d7967c0698e9f5f60acb4e21d2549c39b0a2fdb94abb28d0ae3cb6c20c56d030ea95b5d5dc95d20a97d56f75ccea7a1567a564d5b5eab31a5f49ab93d6cc6658715df1afc456d7567056cb57ba57fe15f1abebd55cabe555ae95cf6a6cd5ca2a776569c565c5b71ab37abdca5955b2e25afdac5abcaeb0ddd56bcbb0a3b36d506c02131ad5d13381f4d5219ce26f215203ec48c3760681958f7deae92d87a22a9bc853e8e271b01ac0e04524e1706e13025bbc995e55bbb555962805c0db77312a2ea898ab7119ebf01676c9a9c7a83cd1f3e92ee287315d506c1a20cc9765a8d5bc589a5e1ab42791df5304901eb475f15b0290efa40b1ea77ac0daf80222442140807b3f1e608358006c635d4c0220a3d2f29220bc1d8b3e59ba8c006777944f45a1a5283c94290179e39e8427d06edf318982cbb64190f8a1b1b5bd827764b5cf15f6a421186fa8098372de131a55bf10b61ba87776daa4a442d020d80a1b6bc3d90541bea70e5711df8542a98c52e4c08e8a926e4f1ba0e1c00ee83ad277c3544d4daa6010397ac91c7008e94c539ebfddcc73d9aacd276f1e0b07f6f8721b64d06de476b2b97aae5f020084c5bb50de0256a1b00bf528fb4102692701fb9cf381fc061982082f1b883a3de16eba560038cef2de62c5ea0a776569c56df55b15bfba5ec95d295fe15efdad8eafae5671ac94565d56fdabb1952b2b9c1525abeed5df6accaad50ac7aa94576e73ade8e7a4fa806295be62a55be5471d399c7b06719073d1bfeb791254772774ac5ee9e49076e94bcaff91c74089e52c56e42e1b70a7630196b533da34f2e482e507f1fa709e1185bcfc389307891d9aa6ed1950df32ca08b8e6381fedb9d0c4b452b6e25dd292e1b7885b0b69a1adf4811e3b93bf497ede5f902567924dac3e51f0642eafb0bca622770fe8e7d8f9cfc5e24966d183a59570524883c5ea3b1d616f0ca64592fe060268039416fd2c921759dd87681288c27a19fd234ba7e7c9d173ff0a0030ced5d24520ac7aac4f8a775544ba0d8c23dac63458087a502229bb0b22bad07f5421a54168daed5075c2635a10649da12cbf0b188811af0dd694f08544d1a074de04717e3b7a08c6771951be92404ddda5d3b707204fd97b8e3efa134f6d0ef7a94be7ce0ac8f3a6cc6b7be9dd35a5f0dd0f4f37337730a0c1cd593cfc9597b62f9062f4aa97a58da7b245523b309bd34e5fc31671d7f599802811b4f2d04de831669b6020a0b94d6d88d612bf6ab05b8da2f5a930d16158beafd6345f0e948d02588af53024d3c08fa8a8edd0905636c8c2ebd0113c87031829482c2ee1497a35492b4fe8ea777fc4a32268f3b2a6cb9b9948c6750583e8369a0b8f4df6758238ffd5b8989f97026ee9f2c62d9c05112a46679962ab1cbb8e3297900ab24005360668b9586834fcd1d9679995aeeb542e5293ca4e6ec5854eabaa3e0841e5d06404a018365d6ce3a3c5783667e82726b1b9678c551c599deaac9a0c647ee34aef4477c1d2c339c09b8ba1bceb559dd548b0d01c47a26187496c0168416f5bd9e7e8760f267dd8a52d0c6ca8e4b414e8e4cfd47847f643f5dca86b68ebe8de0e88782ee01970df0141328c5e0b5f6a4b12db32f6b08db9b95f03cf6a79985c8f6103de040c39639358ca8c05f038b3032f149dea056e9946a7a6b4985411b451d0931d416e291c4a64145128567a0e420955fd4fcd3353a4e6084add8f4f77dd70844519d6ada55cd073034714040c9c8d0f9c81a26b01ece10c6411c825230d6528f0751e27567caf771ec87aca38628aa184bef316398a270e0a7073da30cad0fcc029f21e5c52cc5fc122fec72360cc008aec1c70829063f3f354298de4b2b12ee6b1073577ac830e1951e32760791bfa68038cec704882547da100d4e53ea294ecc24f7de06ba4aaaf7c36e62138a10e98d5793227980e2c2dd776f40e4e087d13bf230e872442e9622770cd32931132d140b61fe0a67e7f13964e4ecf14545580797ed520bd1a77b40fb4a95403c64c06457f19d48b5b26db66ceb39870293cd74339774e14c748dfa299990b98665c16648c893719af68bd3b5390a9a4f8a893ab75e14e1ee41b146481622006c49ced9991e453d71540d8d148eb4a7086f549f69caf29bff98783d880bc3a35600a6a75c6b71cdc9bbc283a40989892333c966ebb2f30007a88ebbc051486c59d70a3db674eba0949db116dfd506241e51da47668c581ea0b0d46f77e5ecb8ae00d4a095f807bd6a7f81281fbb86fc8ba7942722a29a9975693b93029921d11978ef79fa47c746c1a9944662758f35ca2a7e73c8f9a1b6f4b525d410be53d30279ea03c55d7d6ab1fa2427f816f1d0402405db2adaab72c08639f560ea498cc50ac0404b54b59991c33f7466ab3af7a0a933aa3d0825c08aa1455c652488c6e28e18c6c0712377840390b9cea3db61aa128a0a350a911522303c9c8d316bf846e781f329e4a335fd27d1b0acf4ce0dee67bfd968c2d2ea58bd9fb4bd94f782b7c843737f5c86fbc870e4ae3fac51674beabb46ba573a7df79557f32613d1ced5f10497f186ef73c186a9ec946164b4d32670e137bec71e0c2da712134b73ad263b3dd75da2844728e0b8984e7b977651fa0fbce69c69f560707aa78d2245e7824af9454d702f7dc23aa02294411094a264f2020c45a543d664d2324b20f47bee901f40df37a15caf550378e84ba55ac36dc5a08aae9d9ee2e7b37acbf1530a8e5800334de300fa6fe32a3104c025a912d4aa238c63963a64501aa04f0f63aab8c1a03308c598835393867742a2476da1c83b691625321eb53c898a35247be0e2f7a39ac8d37a49cc821cc818806af2f45b2437dda769a2211df207a820492520494da89b83522646f2594f05453a75858ae6c9ef0b226cc6fc7d494a77bab828e0875ca9fe04f54537d2f6f0c823064e04a5acfd4acb412f19594bbca7abf58cf7203f028a63ea10dd03ef7d9cb903d084af3b3ed607933a3652b0075b94959d9b661551c2db13dfa549189085ce0a3f1b3fbcb8bda2a1e969ce862784f1849266d97660e7707c17bb721b83640edbb3e57c6fa4638f4f3aaee0daa554c58c05af11df4975219d27d3c1fe1097e24954db355aa7b65be1c4c41525ebce8cd4f88d0f957f6e4ebab1e9425de262d121311205c5c5377b6ef4064aabf082b65658023dc5862fad603d24020d420a683e93b072b645deff4ebe3269d01b61cdcb8487b525d3c3df9407da7e587424c4d8472fc46f6450c4e72057c07e74f8803928e4010a0ae6afee492e81dbf334bccded96676e04447565648da53d8e4d869b964951401eceb125805e37ae15a8a2a02c7d4dcdce5df1a1bd3ded006a895cb8a54c2ef65b00368a949bd8335f440a162ef70d5cf7cd9b448f2c97e141e6e41a81775ebd12a2f191fe1370c0e0e7454fc4adc03616c206024d5da2562d5d12f2e52db81335b17b201e7fbeaf66b9a0de3c3e6fdce44e164fff3abb1b08d2e1644ae3f09dc89e434c1c86ac04252d5db82b760be3c96f4a666cfd8d63e03de627e881e4732cb5ccb214a1421781ca823f273829c40ec73accf6c5c7d4f5bd6848d20b3d46b0241c65e8f6c402c8871d9441915674919c7391522c20f8e5ff8d24b7a9e1e6cb608c387c1cd99f459c66630fe422b89de6359c678d98d985f77f954c1c8bf48885f283f6abbbb0b6010fbd44dcf80a236b9fc371d22d8731799297480a274841c514deade24b130086ac3b8c064cbdb983d46c529b2ec773e885d1914f72b02210ec0784b512480a374c4464fdda89ef15c8f532e3303d12d202699801a8ccce7271691a388178cc30a2f7aa7641ddc7c5964100daf1894cccf37839611e5647d70969787175f31bb4eec94882988c1a7eb4efb131ecdc486388359594b7fca447fb91496cb533a328fe1f83220486c5292d084e1ef092fc6890bd3746db6598b21deb47408b49ec2c5367886e6b824156b1e5795c363f827401d828aca2cb1017f9cf2274ef809e5afd712bd4f8c502b48a3a9c59462981a1c5c37ff080da0e59996396e3d72655d4cf9f14d8410de19ba18516576ef9d41ccc047cd171849fb8ac7183b51edcaca164be0c0e47776e8f3c5faeca47061b8bf0f9b044de6309a4482c936860523804074885c6355ae8e6d91d13046c82d0988003075567b81fdea19068a267c809a89c090ff41cf5eb9422c9a5ba209936b455eaea1114702e255203080f3186797f0769dea2f717409c8425c9659152845adce46c7f4f81492bde25a43611ed2d829deebeb6759a4e8e745ddac9cf0e0e552c9b33ac5262c816e81a4c5fc86efe9a331dcc9f1bfad087bea87daacd1fcdaca268332db2a6767562e1d6798634ff58e025a9f81a79c45ff188224f60491c4877eb55ead0bdf6d902b6b57a34407c5dc162fa3c359bb31a523a5750ef588926ba6e8338990abf7e81cc01f1d53820a885175727d4d58af0223b6251221b472a91249725554c17199bfb47f81edf7d82d4186618dec3143c86df13287d62e4fc114010007e48aa445f6647507cdb4ab0709592eef8174812de4889788cc3f6ae657a0a5958c1b218e9a0ef485bb5def2c791d5ef84d8a45e775b43ae8981012d7cc961300a6e15a174d4f48a302f50d5ea0d4cd94a04fe9026cf110d4fb1789504c43cb6994594ba992cb54dc4228ef5494543e03051e4e678249bf7e362b40e2509fae00bb5d4294bf107d67c9a193a38c139e8c18122616f30dd117c49038e106e5cfc9a272f2e28e5f50cf037d3c859b5c2e09425895038573228c5c8fb8200342023e640ad2a3a1a9e259d9870af4be4233cbfc8c0da4a80ed02f8802c5598b8d2e252c980895be3728fe89df584374714464deb48dd6c2d8f00dab2882f388a30dadf759275dbf749000da7df025f648ca1c24fc64b4c9fac654380c35855d9ae0f734c0fa02248ccba60a861c72003ee788994356e448967623bc6e3a35494abe3bf4dfbbca9e33d4523f540db3e9a8e4bd5fb8a150a98f47d6b68c467d6fb36d84722f248f7eb57f8c28d6922c14e1b173ee5700c088c2840537c2ae03c45833ba1935490472ee0bc3171747342889170e4567b136cab8fac16dbfd117f09b482394a7ebd02c34796203c6c107305b4843a9a0c013bbd25fd1cd581a951daea08a2e69478aacc65f6aeaa224130b4e881221510c2204a7a0b5679e64ee35e4f3d28c077f435660b567a6a7c10597f082e8d251a247d3b55e812f314f1de253c116ff247a085219ee54ec9110ba662f59372a31f886e343a68758db602c97f449885ed3aaf46aef101aed81e07fedb8168bb3b9e8acc6bd3c815e30d40ca3d085a720561e783ff84644df7ff57c5996d913c0264ead648f4b74db3d27c19f643264d691181e9d2c694192828e65c1540704ef96d897741cd135d60d224b2235d91779457bf924e8b721811c58e549e2583c4a3f4cc81d21f4803ced9c7e6007be748664fd200002056b9ecb989877d7704d138398b2370df066559f0d8a69dc6895d48ae39c520b3160f62129be51969f989ebe1112f15ffca07886834d96d3fb90239e8f2353d88d100202ac5620242f676ffa8a35dd83c36856c99a09c8c42102658ec547434e362df879c84bbf7e798b2d3f6f39ab317b11ff4418d764ca52a71d426de74c1c74106f91c106d0c76c703de463893d19f637b6a1e5dc2129f194fd576a2fc326b2b049f32df2e8c9ed2db06e33b0a4871f914b69e08c4e2dce3b2fd9f222c8eef7ac2265e6c1313a62ca15f198de431f7475d6159891329106e254a776383239d11819a2e90f8a9a20ae6f7fb17780c1f1d7fc02db604e61697a653a238a197f36ef04b5fcee535a2b4bb157f665cd3434bd9cb297a77dc4be9877c67b8e69bc5434c877dbbe49244877859fb156da5a6d5b77ca526b82f72409c4c983299a892702da58056af566abae0d77016d23dc13dc0464437e09e59bc59fc1ec89b7b5293841f6836eea24a6f82b7b10edf6dbb9cbc1d27b984faf4f1e24f9e85a7d4fa02b8c4fabd336329e8325b6a204b8c8aa5b18007643a3196d21b64f9706da1d367c56443cc68bee6413e38c85b717cc47354eb5aed51265a7f049d9951b97b3dcf7ec0a5371dce431fb0766e6dee7dcdcf7f7c163bc23bebbc273ccf84022ae238bf1701828dda75e3efc470e639657ec73de1fd8a0e7c70dfdbe3d346756ea9b839836056d781f8346051e152b745c450d7fcda3bc61c52bf005ca89327c66c70200fbbebf6d776144ed24d6315f246c0ca81be92e77520d2892afddfdc706d9903e4c26953407578df6fd442f5b3c3ce98f43e720769ddda08e00231c55c4ee66d8536f28507eaa402309fc0dbcb485ff16d1aba9a6a382d0d19a4f8287d5ee230f6d880a252d5ca30ad73e880d9d24e0dee070154a01bf217782feb04ef1046b5ff8f22f1c15f6f95d8fa94258b2f92596adf57408de9a0892496239cfe4a7429c8ab34ca490d3ef71d18761ab29855367688c1474cd3e905c2474ddb6a85e6c94c6cd1e6caa7052fca9c8c106b2135b777585c621eed3dd9b03a8d3e178ec57f98340a33f003e7b11cab763a531c830d094373ff3b19cc7aa2008c239d7cf1a275054323c4f0eb24961f84830dbc22cd01e74cd018a8b424e1b86fc212ea848cca0b94506025e80761528054f62b7a4680011814108d243499be7ecfbd5005da121b9a651d2dba82ab43b44fa19f004ac52a1461506a9465baf2721d887f50fd6b5418e61bbae229917538296d50db4366108ca834d69fb404e699f876a390574b4d3eda019910e2203146b5943d1af06f9d7379cd26e3520f53413c109c8c76253e4f70054412253b08b91fb2480fd4d410832dc81582de018c445458dc5e9b34c9e764721ff5603a7cea540417e1adcd200a25cb7f168eba3a0ba109aca7d650a1ee150a2e2caa9597f20bf99ff060eb3c4a5afb6f0d0b793fb784c674a440a9eba92dd10937e25bb721257e236c6d8762e83c195b96b5d11043b80893a87a930c42473edb248cf759455f140a8c8730a15d72aa62b2a27d9caa66cd89e61e830442972a528b423cb53a24a983c620b8eeb994b9583cf698d3eeaf047225b1807f7b14bf34cd6f7e8d7886e37d662ed297efa205d39caa9f4a87de84fa9f548c6b26680681cb95dc3f526718a0dd29c2a69efe4e8f27cfea7c11aba73ca9c5665f368a8ba93d0afa79c74b14b217bca5b65f0796d5fe14d8a22c4798937a8df3d112775f3abeadfefc9b4a43ed09b73fce325627d47cf73b4114c9566300c89715a1b35db126db753afcfdad92c4f44b6a526d8edef4f14b602794cad2c629937103b6a79c2e4241bf076050f1dafa48e1ba73363c8a428fc5198115c35c18dcd6c92ac862239f44b74573c6abae75d0e3123139b881e954cc9d8c93e1a2429f71c45f1bddb3da3d7f72d25f5b492e949631696c0d85b096724d1c2253af7ee1a15f8c18b93e69d0a9a2bd01f72262dfab729ccee59012e8ff7486a708c1e2aaecb3968d56f0c37c00514fe91f406493d84474c2c020f6852e4e52f827911942942217d969c8caec42b1e4f95ca9385cda4ae0ee1e16bcbc118f7073f97e15337861bbadd065bec10c39a22a2fc8e857382df1e519c52f4e284b0608a7d5b4507dc5d5a925e40b4a711a18267f90f713ec80a9f5e20b66fb8f08de239a9eef817758f79822465c94317bafd8a0794797f7c72a26c400c4cdafd149b1b1cdd74f9e2016980406e7a61b52efc1a2b66c00823164bd43127a38ee6e99d52a6984342eba50167ecd6a248acbd18245997e77fc19970c6d07c067883a13ef5c19e5cf831a4e7bd75c46a50922c5ae74128ed7742169e7b3bf7cda821ad5370792ff3ecddc1cda198e6e3799dd7b567b20b0fd21a0268baf7933aa0f055d35e7172698b1e5dc90f7baaba997a20567232d5c8ec5bcb124850f76f0d014ed04b35e81f72d76476004380a7c2815f91d203960a0ef5ad59a9bdf9225af0997d5745a6723dbe838083e2ca0d70d530b40e4b3b971b388cc2a6fced7e2bbb6fc60e64b6b3aa50821e8db25ba6e0031242cac8354eb435aabcc48070c9333e515c3f928b50cf6d24d0ea27a871bd2d4596164f43731ac0be70920fc232bd7c515a9d50b6a5a65f0a6345383673ff0855dbcaad2013b92599ddf559adeffcee830e4a0af2be4a9eda23fd5f16cd72dc17d481f29b84eb9115081e7304f5fd9261f32ea2acd161eb4ed9ad802da8cc1a4a2cf9b391eb84aea74b275dfb40c4b7df40ed960da35a55340434b296fb1285e81e9ff289ac8b0616619a6fd969b5d89b35754b2d8db374de708499cc2cc04502ddcc93f24e856afcd8fb4e3a98e421242ad1e9202ee94aff24b651a5d70631614b6e841b41fb18f27acb7553558100fd0f7e111dda9a9dcb82cc0754478c59ebdd96715c542d4ba314cda04f62feba8dba2d7b0bb41585b2c444469fc96c3fb74c98758f43938e8809c09633b1a55bd66cd993e2d2412fc200a8c7aa9d267363a42ed5ffdf0130fee70ec3c450ee9e447a629ecc2c945b21befe0e32b1381a7d03bdb2ff3c20bc1c889cc15352517049ac3ae739bc8c0a033b5876eb9a5068f0e605f7861f455e95be468527b85dbed02631af2a7160859821562ef68aeabf88e2ce6ec4a1a2b638b90b9be245f11b1bd41f9ee18eff1ef79b22365d201c171668e5e6072ff60465e8a2492881b3d41429f9aabb3920edd4535efcd5f4d5a089e69b826f539ebc23f966acdff25b0484de151ad0a90749139ceacd537c9fb6bd068eb331a8becd83dfd9609772133062e15bbea7e292598f61e18bd0c5402ad18cc082501e41d4f94cb7adfdb40dd6e133e3c98691452e108c0a4ec1c2d063b91513a1b66dbf89156b15eb177cc8cadeec7428c6240634c25b37dce91a24b993ac1faf2fe4a9a907c44ae26f3fb0453b009dd4f3fad25633566121c3cd56c9fd3047b84745818cc9c3417920c1062e4efcce671d326f3262b3c25abd4e9d85d15535622bb1a932d94684df4a4d459fc478f13e0866be42c106467aeb71122d0dcd1cfd51554bb8ad7393234b2c7eb1856dcbbc2d3bf4e9cb6f1ba23cb66674adc7e07e2425831a774f6237b0016fd03b0b7dcbc064ae995df63a4ff5287e6535aa46169da5b385106709bf8f64df037f8cb8b902c4a8939f64f265a0ce61024286c689d76f782f0ff38ad3e783af0b7bc092e915156235589c030ed260458244f2061b17a71f1bb619253979ca6053ecb0425e38072023436a57f2510dbe896fc7590414602cf1e1aecf6e9771be71b49a9cde4b36bd54c289440997c0b9ef636e6ffc2068bcf2570429924c79a643bcdc10e76e58c6d71afb421c24b3b546b0d407f4c175294b265e758bb45647e44c935983ad0e98a2c20eafba0c7162cad159821937e21e051001971900fb14cd140f9b3d938e10b1462815d6263db712c268efd9df988cfe08745ccafd02bc9a6a1b41254c32812f43326c64fafa9d05c2a0c52f1b327a935521be4716be62647b046814e71885f18056b91b0a2f82c08506b8cf1e6194989042ec8ce0943cb21c5d2135230e1f27e1d0253d06010c5bba4de02a77b200a07201e944eb066a91dc65647aa68d3ebfaf0b272df1706f559c355d2195118f38407ecda86147149642f11eea5f57bb6b0f3d1704b97031a80c61748826c2ce00c26b4b375d7e9ec30c17806d6d9e60db8a61fa0be46d509d8ef621362c93388a40ac5237bbb1a1b98a2841ec145f803b522845ef6e091cc091d220c3a9edf45b4a32669523db6e4a9e681c0fdf9c55bc6c385c9d54c2c94c187a487712696851c65eae7049c8eb52a121bc332c405cc9e7457366865ee4eb22d3ca86706305d83eb33593621d9a396040e07b29bff9b9a87167a655a57dcb30e15c2b71b80d1dc507599573dd3ab6905225b2f0808db129788e78b2e61495da608148c8efb23dedc9bb4c561098f53a3033a6d5e3e4edb924ef6bc99c71aee1e57321c0c621470ffd178eeaa9563599db4c5906c5dc3db1c21530789012db6bcafe58a404cbd21224f402bb9e510d0090b5d52854db412f1dfd57a98cd380e42039c897c6afa1c8657ef059b7b54ec811829c578422cfea34d2e8e290c8003ccc65ada23ab8dd5d598d2e9702975561a8545188a49e22646e42c9538c2ec024a2276de21b26db6e71f38dd75b16878c486074157b6ea5559c39c4839b149b62fbf07e98f3dda81c3bbb63a9d88f60e0f49dd0cdcff809424c1c987e74d78ed024d39a89e52fedf2b0cacc6ca5252abac15c06326d20383f1bf0d58ecdea6923536ef3241046d53b40f95dc1d2c8830b484680fcdd5a02327584eca86ecf767bc04ad1df344e61e40a76bdf99e68056f71b6c8799f761400a2393676f508646d17495553e3e439a17a410e59361415988f4cc31493edc8046cd4fd8155e936be762c61e40be410b89351b2fa5348c977e200871d98e35c99de643a1ae5e452d0f73e7220331226fc2e3fd80009e5986e8ce73000d4cc2fa353e399e281b9435508f2f6e212d82eb851bd4e57981ca2f2411cc43eb4f293b5f5cc30faf56df85aabe98f92a1bad689d98079370ef3e51d948d9ca19f36f984899250a6fbac8a489257eccd54605b80f0f23dec586478ace37941a985eb3f320370b87a524ee9455448c242f450d21136a09e497a813f3911f858381e07229d4311ab4675184f9b895f6495235dce247d50e096c79a25044d25b0135b23b44397ffa30bd9af893c5ffc8ea5324449e13c77e22c015d9600709e4fb54c27d8e4cb32fd85e4dbf3cd97faa40e9b357ecdcfaa32a79e31e8a041860176a6b1094f0c3c88fe48d0fb017a75357f361bcd25556e3e92f3a1dacf8df97a802ee2eb07535985b1e9daebd0584504ce60ee5913d8e14ca7b20c1d7626e26a0660de4deda6032d43fe8be7efa84e3795c28a52ce3fca3f0655e6dc009882a730811a741e2a9cc68739c3f17fd0a41144fe710286373db80dea9734d4be29a7c1afd444ed6b74fd7ed8d90098f671fddb042f40642e233cbc96895897fee7e2865ded527c82ef9342220927538d17a9f54b0df107acaee1103fee297c3e93c54ef94ac264e5687fb82d8cabc8c13f33050762f08fcfc61fd5ea47f70590c174811fbeadaab1353105f9508b8278a14873da22531ca13b623da450903e0ae90b8634b9c4323624cb64cd07a1663d5ad7adafd128e6aad565e0e8370858fcc9f943aa37940972525bb49720ab8ed42df1834780211fcd7c3cde8cedd395bf0cdcd162b52c3024da562d95c10101be41ef795def52084fd96eeb1d6b3b6f7f6322502f4a12e8eb3a674510958bffdfb2568a684c92dc93d6aad5971da574133ba9844b12b4ac1c6aa17e477744daa56631c8f1efbb4b15b16f4f03f7f361b81e469492834e7b31fcc7620d618db513ec1f2ca7956d6712eaf5030bec523eae69bda660a784960ab64cb62b4ef7922eed616c67122d0d96da64356b571c2fa22326c45b81d1d7cbb93ca11bf8e287bbe03291b871c2e6a0347aa0806e3531575277a2d8c0be07f79655733a99287a1bd601377eed81b791793201c1943730733b7c0b9e5bf0a38e5aabec00d8da551721d8c95479a8fefa7ee27ac70f5b1018a30ca82a1308a155292d30bec0720e15a69621f85e863b19cf8bf9f7d3c3fe3183e3e5968cb0e44ecb62f1721880cf3f4cce7feb096bfbc55e5703d09586ac7db756dc7e360e5855035c1157d1f0b6521576fe3b2eb6436af130183f5d5eea7d21e4f6191b294e69fa12e4fe2bec63aca12cd607969270e37700d9070bf872d1025ce206e60a161b741cdc3c889659bd5c6b0e311a3225c9614cbc7884aae19b76a97ea979e3521909ac9f4db4ac9ef8ebcd512f8052fa2bcc3468b8a9eb093fc853af17eee1dce99724a0da36d70fe8ab077e697c49bbe57679bbcfcf25d3428ffc1d0d0b279cce684131afdd0160889b650d4e32ad0f469371cfd4c736a203f90c8771be8040efa78d38c773b7cd7d3f6512f8e2e3cd709120966683356e206309e18091400f64b41419b49a09b906c333a38bae53ad2b223218325de28943db5d489df1568606183865d4151d08ffe68058cf6562fcb3eabeb69b651abe8d6101f2aba59d7e0248ea0e765c9a42c05d21347e988ef90810683e73dc4436bf78109e366070188a2eb2b18f6bbe4213a73eaf650c04071e0e7e7b9b3123213e52845b76369cddbd6637b3baf50300d2881883fe20014f0a2a694fd269404e3120d08f5ac876939d7d96e1030d6607cd0cae9b2afcc288ed6a0010c69860f19cf920f3c75d1fc1ae35ccac941428f617053efc1f4f13778f3602e16d6d38a26b1f5a5c51a47858c0eb6d9ba2178b5133dbf02366b7a8acd3621e48482d6344671189c424f3e5815f4c200ee1404d5eb683fe50457e09d2e98059f24eedb7a9fa45aab1bbb491e4adb0d35c905e913b741ead37547c8d7e11ac9e22423acc9aae460b796ed39bb0e72507b841744cd30e8edbe93e692448ecf125de42c9272bd34cceb929ee296846706d7007dd1732179ba83ee10c4e61bc78a7560b248ed1e6fe83b1e321e0ec5f405a4459fe4783c3f929524602d5114c9e7af9caabbd0454811f6851a5f426ab460fe05579d592618c1b043d61a2e61e9867938ee26fb3355edd83bce80affe5d5f7f6a721db2bdeda53a207a7a6d0d5ba87776c44b97c5a247d2807569ee1c4e432edf8aa2a671f39e83d8024186343db6170319385d9e08ecb432865c837781291e09376c1f99900421550f3ef112f91548cd7b78c7395d40cf610cfa99b6ed06338f37fda0505ba479f1e73afdba701fa04b21493c12d435996a2f10ad2ab128c10a64a124f6efe3f75444b10e7a8ec5acb195f4fc593e8d744044e217ffe8444ced38adde967fffe910d14d76051721327ad0532f428638c26851388d2f4d3eb1b4241b1906ed9cea12082b4c1d492b2c4f92fc48d83fbc6538be3cebcc49cb640b88d313b37c25079999e289c5165263d270ca29e521a28c54c6043b8e7cd59a8dc01591427f395f84468e82d7e8edbd0fa51040347cd80238aebcae39313754d4493121602c0b0fae213a3aa5275bd1e7847ad54cf7f7a431e41742e6756cf11d15e75af0e465fbd33a0373e78326e2c1983412faddb2d1e80592f826ce9f89781ea42715ecf84741c93f63dcc7ebd711392a72443e276ceee8278a1332135f6ab483bc1cd14d06f0fa8946542504a72af2bab0824ae7bbaafeeed1b78eee8a56485f7608aca4a6b9c8b699bb835418df3b9de7b7e3f0a16d5d0a8613f7788f2cae981ca92226c0f412819e0f99212de9dc361c47dbaea054dab297338c138bbd3a0137477310479100403cce83d31839ab7a7c67d6fe5f29651a418b09e368e48a5d0eabcb63ab6f845ff2bbeb522a70f356396f590e5246599c5003f496291b3e04d05359b25451a9780cc925e3f1bfaa61cc45dee4c56321b5719a5b915924cd808a0dc2321a69b361dd71ff77910faf5dc8b4e30f4b2fb892ac5a6f2875901a13663e91dd0d442651a5ba6099ec52eb856f28f257afa3ff0359dc2f1472c4401741a45cca5952f0b6319c6fe3fff806e097b3cfaa0c8314200ef143291a1b6c095b166ce06f76a3df444aee45a3620f01685cb852bddae5a5c9b601676eb7e88ea1a4f77a05a7c1c50170348504f4d267b27acca3cff295944e33c9dd7040e3b2c198f719007f74e7e01fedc58ba85003312d18f7284fe33dd0999fd8134f560afdf7788e158a5d6ac591f2d1f53c5fd6ebc8309d340aec8052ac35b9caf959e7721887b969de7c172b99dfb1b25381f10b4b29d3adfea2d6e40182ee1c56dc8ec73beb3c1e09181fccacd5c43aa315b584494a8dc71f3e66789811bc54de33529e0766fcbd99e978bc0b775730870c60afeea5714a872e092bf8bf0e733e3e4b82b6167c3ad08899b2e9ba2ad76670162c23b5f78477dfc75c8e810ced75a9bc486e2f7d21572f70a5eda1bea9db9e5f734cce9036e41865bef5e564f378feeadcbcca6f176af5d8f9c5ac39c9dd472ef4b88140886db4752f0c6de9e902436d49b011db7ff0b9fbfa054764987992f8b361dbbafda7bbd419b39c69df20ef8f2cbaa92ed77ada1146f8f7d6c2c216425ec02e17c1597b5b7c7e557932a38858cc813406ce16fb570b1bb40ea1d8c5533c433f37e18faf524b3b7047ddb41026d5a830764cd89612896c1e9692f1e397fcf3bdebdf92354d14086e6378b4610f82d549af83b2de2299449c855ec683fd5b972a0e178ba91b4234b4c4d7648904c0780a0d08a660a3581a5121adcaddbe7b512d4d49316c59f3a15163e6157c71498f2413e891e6c840835f58876eeaf58e0533d6110f7c996c6f90e10be17e225430a3db13cfa54e1be337b9593d51121b82c071fd36d23098b1c7eb0b0419734e1c08115c7020de1e81ff4dccaebbdd6da8bfb0909fa28d70b95f2ca104fcbc344ec88b9cbafc4e8444b66812951b377b00068ae8a0c202ca65862c2de7b1dc573dd7a2283b3255aa58e2311b32209f328a57522d20b3a988ee93fc7be30feac4cdcb3b28b55d9a38b4f256767e7af8536c89458911d92991c0cac096888bf0582cf35d198cf16d125e66f07a9db792bf61d3f78b12f35af3e1a0871233c949cdc2d553f075c9e788b5cf1e4f90044217bf207107d366a854608bd130622f69e2a3deffe2b25d16697b507a9c53b8337b0c72834a82f805214a99ab6b889766e7879ca6ecbb4b2d1f1d3e449f03a96078d7993db4b7a19cdea8badf587e7342ebf6394fd8889c902e7a338b209ef7cea64498c47b2385c2cd13262deeca53c904c9fdd1039ac81355227ffc5fc3b58371d620364259a8ce570439bb60cd252db8614b15e044ea21b46642e856e17b65570a8ca410b9532b7e935e6d58e7b84311d28987078bca8058e39ae82f4d734b2a5e67c3c16e410d696ed9060417f90de440c57cbc41758a681d68c4cd0e53974bcc6a5870af68dfdd4a18991d53776b22930cb8bddc481300b91d5fca5ae88f965bf05703a838b779a9f2fb4a65932851edbf687e10654080beeb356edc1c418f2177397073e27456335d2e5700efb0971218bbb8cbac09b28e6f7a2362d513f353724d2fc1897775c0b1337ccbf0f2fcc83518e3407262e48775ba8b2fa2b724a4282ca6144550fb83010588581abac2430ad80f7ec3775cc7a7b3a7a704a71a2ae80d964f066f5c1ac3efbb8030f82b9b0925fd40bdc600db22b8108133f9a1d67253c08a72c5c6f3df66ef07da5e90d6467771bfeaa085ab634dace5c97e200d15516d8b4d84368f41b20fb125dac0042972b321894626614761415316ec2776cecd667f848ca278336290c60a58e5017e671913c37edbc6d3c50b5c547c0bae8dcd72a5a0212882cbaad2848b75692ba05911ec72bb2f727ddd2aa8f2e6457ae588225a09a34f89f345c4769645c04768c0ebf0e904f513633fc07174d551eaa5eec2893d822278e8cee0dca9a340d031f8946cd76565f8c2e8706b8b78df3b3f513813dc7a8ae5ad6a25b56fd4a5c3d0d626e43f069b34c2172eb445d96a0bf707fe1994c5341385b41eb6c181bfc8be81762412e76fa40ea55534ec9f2a8317211b218850cbc540e9f2e114c140e624ae57bf317f2fd17b70768e34b83e72ce8c4f68b1a72a37303b3036eb56968997d23a5ce02e9e37b9d5d6859995b0625ba98c4db26e02476575795afb9e29b5b521ea99c73e93b57031273e1ed076f0d88a674e0ef6d2758d82526c07db9d96ba31a0a3d7d8720341b345063995ba6e65688c65462dce77aad35a9034d9a06db965b208ed60e1eeebae0fe0e2369948e66f5129ec980d1fa75a2bb82bb516210b39bd2d65a7fe172b3b409e727451e38a25a4f9e0dddabd51c77c20bcc041887cbd640eebbf3e4234dddde0103b86bc363d4f06e7f8b86619ef787877b35994c78b3d67cb0fe560d5140c66551e3d19c6b18812ded86d22eec5c87ecdf556a9d40faa76620007229b94bb0f1c882fed1a1837ad10bf8932da5a4ee40eee213ec4589e415a7dd064d7a09b0df6b12d30798ce7e80d4cdff8b1a8095204e98f2afa728ea02f7a0f7df0c6a69799f630b3269fd393129347d95864fc260e9c650511b154cce0f8364bb65021489cff91ef859eac261d58d426a4fc01aea40bb43c10a604f3f51339f4739deaace0764845720cceca49cad1d96d39c495d1fe68548f8940156f2a96a337f44789092107c7e53681a725fb8c43343bf87aa443b152850dc8a237c7814820e6efd4bf2c4605aa0fb345979adf6b494541c2263f4920b0d2389a7ba7c0080561b88f0f081b5a8cc3fc3d5970e0fc724be670e60fb85222088315048d5825500e519166edc83cbe6e8edb6a6ee077335c1f7d202c3bd26e4e154f9c87d7b471a1511b90eb822b391ea30ea7c9c2c003c7b144364e9e2e90e3ce1b663aac524bf5f611b0c40b093072270c6e9f12deebbd5eccba4a818cd6e0f94c5c64204840c054af753c858209c55493a4df570c29087c44f14a42928b37022190dac7d9399554633894dd05cbca362482378c150f218e3012ac0504879c876a8026e84a18b942aef7993bdf0149d0ff772c2b4a68eae8d6db74608216413b2f7967b079a0c720c970cb63dac497b949e661823ca8a643d4da39d3e33d234dab3ab7debe09609654bdaa3d786f2d5440addaf6e91e9bbfbbd04a1c4c20c2b947ad4acd942aa150accb3053347f4923f8c2886d22246ea112499d2259932e1f0618631697215615713ac49af2846d41e7d269409d16f466c33924587681057079429e58d0e49168e8687a41194f6e8231e7ad1628e66d98043c40f276930ca340d47f9835424a1410af98347946a59c4889a86669621536924a1344d76182dd80f23a23047b6ca688f7a4150c17e5ea6f1f4589366a52411a5dc1dbda2f4d2a81ebb34da22ce0165e8ebe581d31ea5c78824ab47d3a1682308d8033d46a403cad0677828532222fe0630045b69d58119f1642de831d8be2d77031165487bf014f871982b2880e4a33de8e51883e4501dfda53211473c6c8cc04f89236c6fe21d45f0c6d08c19d875b7c4a814e7021aeb12db0623fc50194a2fa63dd80de3e797c24133ea065e1b4db245da439e77932a57cc20d3bb92372994e945652932fdac0209934c6f862f323440fe6a86b10b3364f80d4a2925bdaa79e8a48b1364e8e40c4d32bdaa8985a0b4870c93b50ec7b6e5ba8372d8b78e57e9cbc93d3a1c72e364093b86553163f83b22fb6cd5723c831732bd900a197608e85fdcbcd0499423647a61515669ef6758a5a3b56e013172508334f4608a2fb48a88e02d0807f04d1a17a65d078122abdd1ded61b7eb7048dca33d275d1821d38bf3b6416d93df111c9e31234b39e557e55f62b25931c437dacb417d953efe8092412fbc29c193e9291aa4c810a609fb412f6623b1b82da264ca5d9d5e51fac5a4284374600d2e532e7a454fbd22d0cb1ec99a2d9f1fa04c879234122cb24344b28846a1ff2452a694be9188b4e86591aba34c9e2b28d37f5712a817990e15c9f402caf44a22ff5d525cffae1e647af9a0febb7eb024d36b08995e44c8f49711b67f97500c4211ae23401b307f17128e646a24d34f2a4421cf6b46793e9b429eaf52c8f3d813f2fc05853c2f6f11fd1042b0dfd524d30b691a0700c1d26f1312f990ace669d1ffb800b4d14864fa6a53f7e44c8d64d5161c6ad1e790acdaa2c7913c3c3d3cad0f16e5af665a796a0a54f1e2c815f6ec4a78d45ff13a57c43cae675807e2c3d6f50b43b972c28e2d6cbc6a1eb67494f0b8561297e08b2f5a18d6b9308e5cf521162dd822a2c4154447444e00e2e169f518361bb6900517b96f823524048ab2d02247275934216771851c618d6e01f00c3c88429329b880095850426ba3df90ace4524a2931aabd9e71ce18bba5c4aa20e4cc5f4e2a4f4cb190ce17ae35abb56695071b7c6798bd689e1c6301ae28c0916d29da8bdd41333528b05f0c0a8aaf3106c11afdf824e02ade0a2bb8c0053188c18898bf7867a04cec8132f1512806b5177770628277841bffb9e4180465228c3578a6bd214a83ad0f63b6e903f768ef30502c8c73c21a38e490e30bf04293e3bf1500e4f8afcbf11b0e103ec27f3239c27f34be02e4985786ba00a53b860af6013d2034ead12c151e480373c46249f42247d939e277c4e320799163ecee0165208d292c4c7e145670a2022b8400890cadf88bf6ed4c045066822d3e66982aec9ca708f80028c6382f2c400f6c47f87ed01633a759a7a022f9e37212175a90db89dc9f3d349f8907115d7022f70ba4e4c27e33337d63a282c5008465c8ad8618029b82f141130bf1c61c8d441f48d4276ac264e8a71f72d8d4b8c242999278e3ce439ec33a4a78d86fd7e1b66fa7ef945eed4f2aec1d863b6cb1e47248d3754a50ce489609eb580c6762778361d84ee9ee946eb9cb43607bdbbbc35d0a216f3f44bff4abc2ec5561f8d8376c62582a66ce39e76ffcd05a864d4c2504777b1edc2dd65182dd84758e611edb4b58a7c33ff29793ca578ed656538435e6052d8e64d40bb6150089250013d68455d74dd8def421ece93bdded873895f0e5aaeb3e2357ddbbe7681a20dc89c42be747e67e5dd72e90ebdbb76fd7e56e8479bbae6eeb30ec6eaecbd2533e84e912efc89b9e226b2cb1ed5ddf9e92f221fa6f3c44ca8e7ccaf64e91df2eb18e92adb18e4ca9574a4a0a2e7d054abc721ea5af60d5f6bec47d791e2b4f297de59a9e725bcaefa4640e2248e4048f05bbc4359e7cca777624eef1af06e987910e1aa760d841d7769bf6222699a4c4a85d1289bcaeebdaf085fb4877ee0a6995f61495865542c89b3e44f777562e0f5b580f65b799b487bd913ae9bae99265fa10297fc54398764a37e1b754d7cafdf5520ad6295de53a2bda67e84d87c0bcca6d5a7ee529d7f057a382774af22be721df2b5875e11593fccaed9b6eca5dc13a3a4a16005b454adfc1cef29d153ce42d57c131895c614f7295affc8b495a70ec912b5cc2b0f78e121ea59bbe93f29d128e427285ddf42ffe384105afe0482457d853f08c5ce1946ed37da43deca5dbb04fb63d55bd2a7482cf2c9231242a32268590a4c85f8ccd9f24ca18268d32f6aa5d9ffce9a49f8e02054fd37c7d2463c7b0af833276ecf2a76954d1a83dec304728bd05d6485f7bd144fe641124f98bc92ec89f3c9231ec3208bb14c22e81b01e922c09d42bec18563af616922cd3b16fa50b5b12a86932276412ed7e336bda27a4affb691708f771c7c1e14f2773ef7e693f226b50fba79335fc71cfde5d2099bb305f2b42e6fa5613ecd745454d43451b3594d28d2dd834dcbfbe5bec704a2f611d2538a6c796e9b0c329422457980c922bec25a18c4920b9c28e00246ce926ec291843619d782457d85370f3c81576150c742431f9d279c897b08a47df2484e9a5f330bd8475945cd729dd842fcc23e5a69bb08ee9297846aee289b46cdaa6af6a2b9536ccc3f414ac63ba4e09f669c3ba4b2a322af27609d42c1b80b0cb24506097525c0a0d31c12e899a262563974d9a063681a7a8698c9a155bd8b36e6b24ecbd05f6adb76ddbeae55e82ad99bbcbaeecce1caffa58ff236b5f44009793b25105719d02c1aede76370d45d35cc7de47fad81b48b26412d631bc80674882166400042fa0e88115b08a2e7ca85801134e34c141129a1150f0da821c18218a6da6e686164b903718266149e79bda34f326de4035e356bf421475d0812e6a40822133c0c0073830820864952cb001c566ccd4dc60b26407429e78420b4e000214d82006500c45404a4ab283263f204211d2c062021c2a0b96107a7286324ce1822029dc9401046018c3088ca8b082108698dca83f4c8cc073055181127200050a63886207396032e4037a042782c041a1cbd089163a40e2e531a9bfd8200aae08151ef5129ec864275ae4206e193ad162069814d9277d955072015a21e1b9a9d1970ea54d4508f0c06635c33d3376775cf74ba532d5340d9b2ea539a94969cdd7b5c139a92cdf9d8e1da47003296429f1e50c0d4ae59ec2e1e7ac539059ac57e6963d25ed248e71051bb15328d32958038334d2382f26364eeca2739668378d6c7cc530ac524a29a5337266286c9c734ecc9b1042389118dad13450eed8b10387c767b8548adaecde68afeb8c19338e2cf7d62cb574e2da73689b501e46422893b003486d372d49689214f6a5b931a499c88cd107d00b353557e682d2929a15608cc810ba60e468095688c2159ad8e1075e70618926149dc1080c1719bce022b9a859c1116e1085d4028b3c4538417624296b28f4d04c06852c98e47ecdc207da1784749e0722a99078e5095f4ecaa63d384305073f9be10fd392891ef33d76e0f4803560ae3525e7fd81776029a422533ce1139a767ff4aa4f812758791d974be8a2ab7bc2b391a994b5322907910b31313c28322b0d9c6481832c62a044eaa997149210c4205181086290cc1d360b2672a79e2ae553864eb0f082678331f3fa4400ccb4628b9ff1e28887a7116387b79171e60a5397c55e204655f80f95279058a92a08787a1cf0940331539ba68f3be6920dc6f4b5e64a8faf5727cbedf2768f1796ae7757486755f65df4aaec3367dfb45b7363467bf39484ad3258b0fdf8f95d123fceae929b96a2ae2ce595d122b04cb9b8d5631708760c3b8e780c67f893e740bdd877b4276577524867fac5175f7c91294e113c67cc000090edcf78fd6093d8cb4bb3e2097896702f48f99b41459d9c758205175560c74fb0f342219de9adb006965eca1837d8e1a8f3d814d2995e4a59b9531256060b361e1e016d30667b4c56ef942c1f120051d83e0787e4636a6e344d1fde46f3248bbb3cda9bbfe63c776dba9a7b727155adecaae433d8d2113264d25b73e3a6e46a3ebb354d03bb1b23e427cf6c490669e9f491bb8b38622653788b88797efb220e5fb01f1cf2410369e2250098603f2e6331053e4eac8092e5611559737205d2154452c6d6c21659fe872b80b2bca2bb1b080e549e1e15b39794f33244b679f267ad4dddcbf48211648db064f4c9d2a224910c3b05d02f32c59f973b66305871d24518825a3a47f40f96446929913fc204852ab46837454b4704b4356dd0a231d6f002ad99fc713d45597eca2749d8c0da16a486aab0fd4ca1c2a1388b7212538519a8fcddb841042e782202a42c7fcf48964f4690457ed2b324045180ecc77932e41389862ca50cc10db24ca150533851b4051420ed00094dd848a004084980e08a316051610034e509ac4445cf0afb798d2ac233f3a44850ee549e09b0908b1cb3a5f3d60931576f2701e20bfbcd2c676603793ea91ef818858bcc851022a5525a2803a594534aae3d4aaf8b524aafebba2e9a490985797a3f08217c020da59d618c4443921c0fe161a6b0d028c7f8998585135639a594724a29a594f23595aa55d20b8403323fd181eb59861d8fc9c3c323f2f0b4ae539a950ecf214f9eacda80ac0c138121165b644aa1e47a6fd007c0157d0f1a4aec974a5d3376d0b5612b5734884786eb8555d88545a31e13051a97d39ec669da61d370dc4c8689626bdad34ef14c7bdab3d73064ed0704025933bdd2b86b9a767f8032dab778f384296adf116dd2866435c93ad9a803b24eda35abfddb72d434eddbc5d1a081e558a6479f2ffa683a6811354f1a38b01c90b9889aa7fde99af61dfd43d3b4ee7daecbd19e76182ed8f818595bc1285c2a95bea95c08572997be2f756820d3141c4432c55c7bb4b6477fb217cad83d763a2490bb2db6ec2e6e0043b01867ba3b344d3b3c8d77487b9aa671da4d17b6c669d82fedaa17d4aefdc70d17f334dd2226aca4eb36dadd701d4d51cb69394d0393b577739cc76937715cc7715df78ee3ce69ffd134aa0dbf641bb27618a361203188764a09e8c55f4bbeaec398cfd744b1321cc37d2a997b13f68b49373109d6a0bf3eaf1131cb21f901fbd123f9ba4e8fd01f38295012c8aa157bbda2a1f853e5eb9b27235fdb0557d75b2eb8badedd0db7baaedf2aec57f341263fb0ce735dad85ac6659966533cbb2a9cd39b32ccbb2acd65ab35ab16adbb22cbb0ccfcb64d31e5be567a28440c8441c32550693416548d95106fc4bc440b8cc0e870bed70b85ca92b45b5927c6abeb6576596a5ec70d42c8f2342192ccf0e4787034299dc1687ccf2db253b5ed705af6b6a25799bc631a14c1fcb9f8c2c7ff362628ba60b82fb01fb4d2a5c24ec572f8ffd6a15beb01f17c4cc15caac41eb6ea8a006fb552fa660bf9906fb4d34d86f7611e50c66908214ca60bfca85fd2a19ec57c760bf298624fbcd3080c17e33c32fd8af6ee105fbd52e70c17e15a90afbcd2d54410b26edc1f3d0dd1065781e3a1c316761bf894514aed082fde6ad387a16ec57677437b3bb5b9ede228ec8dd33680c80060d1a0208000d1a37e04be330316c7851c170a1916a615941d1a0213b1ac0879ce5c6df4e8e98081b8cd9ca606537dfcd49e3065b44d924922cff04074cb2c4fd6dda0c8d94744151595c9d11a692847abd874c9355d7a1910d906468648326645170191a2979c248490a5019bb8a1e1a294122d3f7b74ecbd0088a33e4fe56e260d0b881c54edfdcd6c15249becbf5422328ba9061d0b8814dc9d089173ba071831c50663e5e2d5f1742195827bb6b9a6987d34ea445e33baceaba928ddab76bdb10a525ee93c739ac922f9dbb76553cb4e3158e4a6221bac59dc3253c334d60bf3e6a297a353fab4dfdf3e6278ffd5a8adc52e4f9156445a4186526e58855f298fc02906751961cf5c9ddb4bb7f48d686a18fa659e5598fa416253b911cb5ebbab40b565576ed45d9c0dad4c505d6956a87734a1856b17ff08a5a92816ddd5d7a09c3b04bec9ab45e4472e95d67774eb7445a59ffa84a58473544a9a4a968f86bac65d884b38a55dab9947bba56aeb05ab379b7ec5e3807097291b1530c16e1c463dd311cc9eaf005324cc3300ccb30ec5896613c4a3895619556b36fb8d62c7b56ebb3e7641573ff51a140963d3100b22c3e65997645ce5e6a4e3bccb23b005e00aeb29fbc53967950263b09e95576f8d3cde9559665d9afabbbf1a04c766dd36e47245babb283ba0a91564d3961158f949f7ec23aaa214e5ff90ade5949399116977296a7702c98b34fb9ad2998bba9c4ada0ead677dbaeec6ed338a7bdecddcd4ec3090b3f2fa757d9b92cbb176c3de6c11adcb3af20cbb2224faf328b2fe0751e92d7e122a42ce4ec13ff8032d99182a8e73615fc9494ed6e2a75483f9a862567cf691aeed9835c2d890dc60c363e364d119d85c4d830b62ca1a00c8cd164b457eb4cafea0af6506bad318b315e94ab322a86c5ee9ca9bed4616edb6e51da95e14199eae5aa6515038143d38b538c308032a7e844af4e8f4dc01e4e87f546da3bd548a929a7774492643f2f9f4edfbc1bb046e7d365342b1af966e4d3630af6c2607df2e9f6a577294fb5a4f00059299cd32bc86ac1b057df0669524eff6c7c708b9a695cce391931b78d53f9d6dd682d39dd7285f4ea74fa276d5c00f6a0a9ace0ea5455b007654e313f9ffe79f954abb5daafee46bb27593f7a75fa69cbb878e4c6e2d8d3de6906d63e1ec65d9e7acbafd37b4da3f2d3659c1eedeb85d1dea47273da3b5dbb2714fe2017f9f4f903ca9c0ee305ab3dcba1f293ca49e5a482bff9d365a74302797e8b711baef272d563606b83ec78bce0aaaa379f6060175ceb8570d572215ca9e00fbbfc6775682063dfba16f8942ba3bdd35b4ea76fcde12092311877b94aea2d5781812f57a7bba8a4704aae4e6f51c12ad459f067738aca57704a0a0aab5454ae9292f294d37f34cdf3e9394da3fdf4204d637f3a8c39612031e8ea1216d9cc4c502643f52aeb600fd9b92ccbae6d715eafd8a6e7c4b6ec5db38c6ad8081df23a3c90bb4cd260e3ae5d9bc51865dcb6ed5b8c5bdcaa1d22592ead8c653a9c006499b04eafb267b8881768349c65df26977dd64099ec1bf759c36a305fb0306f8fb7379952765aa613695d27ed16ab2cd6510d614fa7affca47d4533fd745307654dc32afad2f54ebbb00e9aaf5ff884d41eeaa6e42abbcabd5c655a6af3b2739702ed653e6460b5ecd9090059a667c76956f4691f9265c21d80ab2cfb322e3b8451320c43ce864019982ed8eb74dbb29f368b3db9ca6edab08ad33aac699ab6653a1b3e25b5a761ee439ac64523c2672f0eca5cffb063f0426c86ed5d8d7dfb8ecdcf1b3f10c0c675f18d5e613c3962ec93fe8a1c12997a3dd32b1c600fd83f8a65f80d07c822005c61c7b2ecf4d6c863c71a7a7383de7c8d6499625a729df98be9709c7aed61bf2ef69898d8355066bbcff89357b5ad79daddccd8c35779225cc2008660650749d64e3df6789dbe6217c5aa193bc68955ddef7879c44629ccec15ab78643aaa21faf515ef5c6f222d195f1f71ffc8157cc52a1e3aaa216224d2a2f5daab86a15cb550e65131942b39942156510821859747e6a16d207984148b8c7a8848060961405892a428724862344a12c6837484f5603f47988f5c5d47179251d110d11091d15051112714049404288910505050377fa6cfc5337b26cfd573fd4c9ecb67fadc284912491e45394a4a32056d5612c92169248b2890149241328904a2498c68915cc913010dc955d31e1ef9e3235792fe481eea237d280fed51498a823a5ae1e69d45d328f73796284941484742444743492d4645d3876868fe2419022a4a09052525019a3d0d3479e4cae5c74716754ff318e596ed0303e9284a92f4312a221a923f423248ae5a5e2689431248ae5a25149404284aeecf797b78a2cfd090203f7c10e5464aaa4772655424573670f376500bc5e0e66da00d869bd7af1e38cd43af8a874e0e1bdc931b161d21dd22233c44744390500c50121c7cfa461e1db8798344f1b8797d5c1ca31db8796d78e0e69da991c1cdfb4d869bd70280ebc17bcd4c4c92abde66385ae1bc87ad9f095bed33d303006464f0b0c3cad321071c626ec0f730310250a23c3050d0a44a6805234c9861c951135124d185ad0c5b67e1025c68420a463e784211340859010235fc90e10c359862045454d9839a1560dc11523005aa8411402941a1660595254327542821d70c9d98e10c4ad45cca599564da468332c588b0c18108677a1061a38283aac98824cd217d50e00724d2f0776fa6a65ab9a24fb92f5c5898a31620d713c9f43b9a757a1edb8c647551df2e92ac94d34b23c94ac15811d645507a326d8c35d68d1135eb43581194a641c2b8f082e76a8261188661b5af264db36d31cb305113161015b547b9acc68a9465d93321c9ca8a549bba5744285bd234431913a2ce9a648a43de60acb05813ecc28aa06d16462457940ec51ee8e10590b725302db0f1109eb4a34c4f4402981f1b9f6347d36ca5d3472c2c9d475b64182df87006db9d52d36d92b0f11c87395ca1b4177b328735619229fde9664b86be7a944b3813f2610bfb5d4d302228b40894a1f7410c367b43e970d4ac357614258af636a5bcf19793d4b70121b0d93f2c29532edaa3cf328c45b1a65bba1913a2ac898633a11e45eca725c9f45f56444ba241d134d97d8c3c0546c48bca1f1c32228b3e3e28f9a752d775e1194d58983f0e366bb6e4118c4eadc10918a7b0f0c9cf912c337cf2e393b756397c04204b050b4981577477bf04b9bb6e5f4c9e761e05616dc2ce1f79c2167f159b32f612fe4c41a2b0dfcc4cadb5d64f4f9b6f1899659710cacc07913db9f98dbe84e107933f9874b59bd51923e6c4b506adc1a664f8440552e0b2a002269452f04405402861614b193e51010e2ad2131500556b5d9c188902842338aa10828209a012c46009a135e0b842c80a33387a82123c4c98c001e5c7062e784202269044a9335de0aaad9c2dcd54269630836da66666464d57679ed0aaad9ce5300e2bf870339589110065333533336a368cc30a48db173d1587167e343218c1705c6128bbc2e7b262a8ce5426b480ced4cccca8c10214589002abb2ee60565b397b59232cf89154f40a66014ab54f8c8ce004388e8ed4a0048e2c44f9820f0e2ba2c430214a1542f62543274644d8c228079d17b6cbd089510c4a423052810a7e60327452c50b9868354fcf7e76db4f2efb2895be54d64cd0843f0dca95c65dcb49c53b35c9d5eca3a6c6f3240b9b3e64e491ac2c8bafd7074e10b98a48335e5e6262688f2192555fef10d9e3e6f821571d6b6a7e682ff6fbe690abf8eb88da1b14684e8385d2c8a8a88888c806bb90908e8e5229cf8b9fb78f337215a78c32d66eec0c46e4a47a224f1719aa216f32f20c2943865de4680f32213701ce1f355ea4a0f4316365d720517c20e118c9e07ef438ca5134eb0fed492aa59494525a93061be79c138582d872d20bab99b6715dc9644f292aa81596164e7b6357f6aae1202b2818a525c5f990abbe2a3791f5513b480b0ad4556cca214d9a493289fa08128589bd817a893c32b8b6423b4d6b2a75dce6825d59854943dad6e43ac3b2a91b64dab905c16e90ccd68afd82c1a9b8a70860035057393bb16c580f32252bc883242505e9555f5e5d04490a929494a40a721f971e6c1fa70ae28349e822c9c56b043ccadfac710a734a29a59c999bcebc423a4fd943b3252c9aa9b1266bb2918617369e8617368a6d83cdc1ef9bd7fd32fd26b491f0f6f11779cb52ce9b7979378c9372061127ae50c8700a79cb3878bf0f6a21432d72fd54b0bd9839ba45f705e1a453661a2f9a6dd594b2c2a5b4d093359996804acd8b6e5ac7d94019cc08192b42adb5da219b2cb9d4339649ed9a2a16244b9b259ef4ba5f742c2eb228a8e4d592a9dbba12a7a538181886615ca96577c83a1de8746d4d9e36a6fb923783d35dcba5a60f0d8b1b376f289eda96613054179cd88d91d67923eb761b7a57cda82ad676790272f1bba0e524c44a9da5dca671da66e24e175782d0ca18a38c16eb24c661dfb48a056133bd3607762509a79516a3221b194b1cc7924a1de14058c3d9a79ca235953aec72c3681036d3eee6822adcb672d139a59c525e9fb57e629f144e6cd6eee66a1a895194ce646d431258b4614720d760b1533a3179ccc21ab52663d27635feea5442d067e731af7db37285616f55bd563f44770def68ef5ebfed645855b36f1c6c950e5b37b2a73dac7431aea6ca15268dc822ed61b248fca54ff7d583f92d36a573ce13d15fcf2159da67b55e6469f3b3e2f9cde43931c476ce9f39afcf0f998f3c3329b624820ff78ddbb44c065b5512bfdd5cb77b6e02bb9d7b46e9ed9e8b53a47f7cbab01f2c6aa9fdaa43224bc319c6691eb9aa3fc2912cedb5de47addceb9644541f87ea63511dc26291ecdae336bf55557cf7c8558db8a1acb6ce341270559f44ad9505d5f3643ca61ec6540ca4872ea0c913bb1819f70693097e925059893d43403efdd3341c92a6e956ae49a322a2aa096937e1d8137b7a60a7ef717de536bd4265c4789f51a3f2ef39e698c4cabd8f4ddd65e55445454545e53354ee0d957f336a54f00d96b75ce5d6bcb9a4ecbfd803b59496ab5279f461b92a151c7b62cfc9b25824fb03d68849984c2653ece94144d39caedd47cab553a069ecb59fb89866cdd0fec9c8da3995144e057f95a5a66093a97fe44f7b773910bb696eaca4d8193766d4dcc0612377bba244d7ccb8117b5093a764860dc67c33c8889628d951364be51fb782fa769f504141a142eb98ccc8d5f5eb52b944f4eafab58511738b1d02e429fe8290ef144044d318216f0496fb5a9eac711b07cff28215da7ea18eba71280ac9d5751a11d8ed30a36e95abeba29106abf2954f2d4259ea7efd099614cb0b7646b27a74d726875ce12754de430507314a6a09428024ec972aa25e4fa20b0265ae6f18114d138568a8814617b661522a08c771dc378c53b9451cc193e9e52d42878727531c97b4a7dd2758dedd2750d78c644523169c1a00161655a480cef23692d543f620a269e85194fec0d575889a9d79a89c07ea2d2d2e87f11d184f3d85775c70747171c12c2cdf51dde543b0fce52f38c26849a9585c605cd8525dd84ab144d455b903c0c2c66cc4bcc949e594f74b29f8eb4c7f608d0804fcb5e4faaf2567f8b3d6846b7658c25f2ae7a4a29002e44ea64fa8d4fb75fea2d0133d6fa93c759595b8068bdd4808d6e8f2f54824592abfe210ac51b1501ceaa2d0182c5439ea51a39db7c8b5e5c9f46259e52be7813acbea8a2c5795ad5c185ff9102e67c13b2c77f90a56e1ac5c7516accade72d872c9b04a0896a73ec4ca5b569e5af94e0ac6612bbb0ee37aea62b92e6cb9ac44218b043bc406132cac33c8a50cdab9f8cdd8d5d997d12bed5f9dd12bed50fb473558c31e6ada3f54861da003c0c2a6044996a67d08ac018f90b5471e584366edb148ec89469aa6bbf6582459f25acbb543a945214dd3a25d81cdfe889d1e02d75b0e65cb857265f117247ffd9c54ee4ebb9b4ed3ce5d0fca68b7190016f6f4cfbbb1035046a3b7e5de0416c6554fdde52da75ff9e97e756505ffd09e5604c655ef0ea748ea2e3fdd9a37150c15d5ad306ae55caeeaf4c82357da612b7555273c446a2929b9d29e4a650d1aa16ed31d8032da35fbaf2577d6126009fbc122a2283860465dd38ec3a36954b076ae7419cdbad1aba6d1fecdc8dab71f5abafb46df1fdad33e8307b6ffddc836ed696ffc030ed3fb1beac2f64e4fb9b3bdd3e9b103c2f4d3b9a75c95f73d65ee2d779eca7cfa201ab2f6ee1a099199fb761bed3f340dec6eba6fcd1dc7d55cba1d1e0265b41f0596c39b86fd62a13fe56fce4bed22c27557458c31ea1041d2aab7452497655396dd0d0e467588b4602beb01af68551c8774a0c17eb50a20b2288e4314c35f349a224b1859147f3570a2d0cf1785a894bf8648d675568f8c4765a8d3d65963b5b2c7887e518593164bb04c252459199c922a4da2d6800b4ce060074859187ad2faa25044caf06ba3dc473946914d9f4d53806c7aa9bb3181e1074660f0411243184352ab7629e0c9ddb9eea69bdb9118b020162dcd665dc870622858226311677a050ba93841912a73ecc9a6c8b1601b0016b6ef4ade6077e34316f6b3d753da4bd3a8e2b715688303b64f2f31578fdde6ba73b73bac807e3d773bc74e475fbb38608ecfb2ce1047bfbe02c10e6d4260bf994b2d7972585854eee963ad1ab030c900c90423134cd0842726f840968fd60719a4b82725a8c2139f287277b5448f59c6207923d1908e2e70a6dce89348d6f50beb74ed6eae4facc3fd7a5f1d25f54a78c8cfdae7312fb14edcfaea28d1ae0487629dd852a21d763ce437acb35dc6221ef214ebf4a5943347bd3e0004f9d0030591acedd887441e2e16c578838270621024c2b0e7c0b1d8bd19f9a44b0c1bf62d768a4c99f448a420916b64433e6f10b9c26ed33ad210338d5ef4d2b26b0d56225989fd4b512c8b16f6082459b095b239246b279eca63ef718333432044ffba121e77a7e3e97388ac89251d2708f688843d2661d9e3906471c7befad9f882c8e2704c92d107321573304bf98b3fd875a8c17e1de483147ba87d244bcef6c9d8e3a61a229e7e01f1f4445443f4af2fa07f7dbe8b98885d718ad4bc6575d66a37ecaae27d5c5715718b86c75e87351e70025491e9c55044a9163225c012f69b9999e1c5964278b2c4111313c7133d35977c6c17858c0acb65f8648925e48f33b2c450a64f96105a22e8c9123d58a8a9199080063c3f4bd0a0a80449d460c8c9174890a0063d5c30e144d01ab6b045af201733f0a257307f369580257866d4dc78a2c414b81b644d2c96e113259c8021592dc3274a24010b835dc9f0891241095022892a432755b8c193248e66cc934ba411c638e5afee66d22cef8412c6da5f6c346fa68f66211d80bc99a02892850051ca10c78bf3362100e19440a06c29a5bd6e2adac0c6181333a56c127b4a9b49976073800a9b40020b69bc376373ada4f3924e2c265e06070b8b241640126b03653ada487a1b5803e6c6986cdd47667709364ae7ec20686e18a7125b3712666e6b63f4c00a1a14d1800a5944d1ead74816ccc20782100417ec200d2de86fb169ece826824512566b63ac1cd014d656018b3cedf381925bb99d27f420072df4e24f1711b520cf4b6dbb2d61fb22653e0dea2c8fb79026f5586de52c0b0ae6f34328cc5f602e91b6e689220e655996659fd88f66b5aa611a8f76c963b2b5f40dd75b1b696a9e2f95af4661eed74788e4adf39c987c0c0c64943c72e5653c32eb691f971f104016b7c474419e33f0daabed4999536ed38d5d99551ee31bc6755b96f1ecd0f0ecb61f30efbc61b78b744f1bf1c138989bd36517d23442da9b302f397a92b57a8c48c737063b92fdc8ae901c1e9b6121edcd98db3e467aba487b98f715d6d9611591585a3e590e339b0529b7dce2d93c3f433c5cd82f0efdf00cc11a187763de5d1cbedd1c8e438188e7c792390f3274a0b1ff6ea3f42f26bf64b7e13237c255f6120e39bbbd39bb0e37bb8c9b9d879be5d404699a2cc3f342b26b976615be1c42d64b67ecca2cbb9bfbad5d5c54da61687739bd9f07c4756d9b9d109e5c7d3935d91ee630dbdf709d1d56df593db656b5ae56abd5ce0edf69756b0721bcef8024e61387cf52ea9fcd28fcaf66d4ff755e41f9c41ee657bec3f56672c021e6d68a81a882803976189c3344b250ed73f1472467a94389310e827fdc47bbc9fe232788907aff0fc3df4cbef7abc9f1cb643c5e060fa712367d95b5dbc8f89a61876336d3de108fc5b2521dd2fef6bc26acf6ef315e7b3304905580a168634793976a0a60336c478d5c7515cad4976eaabdfaeca2ea6d7d4dfdfc8cbc95666c4ae795f410df9ab12ebe84736a32cc4b9d8e14279870820cf39a7cef0cccebbb13c23b0cf6c98ac85a33ef09b68b340df68919699aacc727cb302f468cdbc818f774d3b5e17e39e4176c4454dd2f955d0ee37ecf2e4346449615d429e5a6fe0c9b9e0e97265a44f1d2de7ca6838c31c698d592b5d8a4ad322fdb21e32193916597c1c30edeeaabda2a9579b88c7f5ec6b0cbe06187ecde2ac3f05771722ce2888cd5c804fb354f6e1de4f979afbb313f73dc2973ffb2cc3d42d60ee776b8195c61f72ef6d5ad180679562883491db0d56ab55aadbc95a783177443074008c9c834df50a6a7e6235928a0f632fd7c7738a00ba098b359006dc425b107567c0c26b38a3dabd83da6b773f4815e44c1557c854ba28d0863e7e82359fd83bd0d7b9e1df278bd383d95cafc90943545a0546f364861bf78b4241e514a297d3d226ff11f0c0633a8d563f0474a2c8bf873c1bfd73471c26077494ae57e0dc5250bf5552c6bb562b0ce2dfb3ac6286b166b949af672bde2344d7c2a65fba75719ae1b0bb2ec747271692161bf9951cdcad1aba6991427477bb33dd91dd534377c3ed534f8f32f4d732ff346b99698b77639ecb41be212d8c33c4d5595a66938ed4deca99b5d157321f47c4854052697a910fa495517e6d4addf689dad14d80f529169cd1e7f83651ce772bf987cc5dc547ba9d77f4472c48f79ebbaeee68677dd769ca6e926e06ade05c73c1e1ec51e664caecf8183c4eec071b9373ce6de3701591580abf9e9e328da10127b98ff1a1fbbf8dab30ca7743b88648c7dcc68e4749f23edd55aaf4a47e6f24c01d95d628c55f5d4eb05521f2356e970c140fe65af18880ac3f107fbd00b23de6dbb37e07b6f27d958b8d8b9e021264b2652c7a388a469625cfe6d39c6bf34ab7be46a3e9e53d1d8f0f80cda8842b187f9185f81a88288d71e356fc62348c4233822b1e17692db4e484e76f55a8f1cae03d601bb0dd448da9bef9e2894f27998ea9e3c53ee82e761ff4099254731ca60e311ac513fffe48727f390e1931544216f1777c38d717c617eef81a2915855f331f3f0d50e38d8c0cec243d6be721e6e0657dab155d68ec3cdda77b8da57577be39a33a369f88b19fb8ec82e9f3054283dea905ee5118b88b445d55e35d565beba9bd437b89d839da6bd5cbb2a1d2920f4a9c30cd32920751a638c1f909c99fc65dffef27a8160950e8a81c4d7a7fea51e31900dd79b14d566d77537f4306ed701719d5ebb326f58ce0c86fde53ade55f13a445a3a7c4787c7960e377bb7e2d5917d033ee4e87da75b9e1039dc7b1c8a4c9a26c6e72351d3c07c3e36699a7f3e2e8135b6db00e7edb35f9818d75eeec20d03998739c3f3a5a314d14696c21f91ec62038e18c71f951479de46da0e88d4b7c3b8d4056760260349451f97cfc76f50d39e811920b6571cdbeb63f60a6b608f9781e10a6562bca9bb3cf5ec7e3839e29c999a9cfa96ba3cda73b9f4b2db708532a9a7524fdd8764bdf42af57921d146067b487da652908b05e4701e11d22ec52f6ad8e3ab86736849c17efdd3489ae6a79d68a04ef2e1e42c87db72bf9a236eb98d6cb9dc59eef78cb3ca51f74b65156c44cc5f3ccaf329fdf3a1b2e92ec9f3a5fb719fd786cb316bcce2a3867fe80cc4e2f0ef469edfeacc37a466cd7a5ffdbba67d87bbba5e0e3ae0640d7fdb73667276285731e6ba61d81e91383384f9da345f1721cfe726f69391677b72621587cf644d071d74d04187c71c74c03ab195038672a5019161cf2aae385c285739317562446ed768b1d56a6d2ad50da308e44bafa4cb89f229c3273f52e42dc2505901b260e02885ea8a2cbf419b4d16e9c07e353b9a00b07e355f0d96491f921599f4ca4e69f117b790e56b942c6576f90d0604786073bc9cfdcbf13276ecd94bb3e08c1f0b73c57f0d22cb5e710c02bad251df2477d35db2d48be5ad25fac43cc4c7480b8e127d36d55f5e7d3a1c2f43bca8542f36d2c4f28dd2ee666aaf77e623aa53c51792a6b990545c7fbd1ee6007c6171541c8f40e0e52afc188f2d9bdeae1b91acfc8b79c9b5bd57c88a409f9026f5ba45ec41be1e1ac995f4bc98faefe531a91ba5884629a72d542e9ff215fcd94eb9b661954b181858d5eb4fd30051053163def2f5209854ca5a08593535f559ad359cb5d61e4296ad3108d6d031f1133b30ae7aeda1ba8e920a037bc5df8f5cafda6227c4ccdbe761debe72d5af8e0d57b5601df11bf021d7eb1069c5f84e0c2c0225add8b2e13bddb2e136dd09f1721b3094ab5abf8281a882988fda4fcbe5e311d8e1d03eb1ea42b96a696979a5020b5264ed1f915c2be55a6ecdb3abd788e48a85ccecc3175f7c61b3c67542bc5c7e8b90eb52bc2afe8bb56958f01733907aed0da4e52ca9c7ebfa5abea5301031d718c40afe88e4da41e0e5d76dc15fbd1e57aef62ddef95af3b57ddeafe5b165e5f57ecf35959af3f4db6d6411725ef431b71411355ce2586a761b3924471446dd46a22ea7728d881fea14743f69e2502f3140ac8bf67ead4264aedfeafd62d67ee18f5e88ccda87e4fa98313be3cc930a168805e6e910f421574ca552a954aff8090fecc050619dd88281e1affb590857d4e5b0c3115d2e2cea58fa4ed12c1cb0ae7317cea12a3ed1e7515e00c6e0cff60f7e03dbab7a510a8514499c603f88a4936448102149727e04997d31fc80adfe07912e593a5d8bf4127015034cd245922451280ee1208a28848884d80428314a8b3626e4ec158801d6fe0923119360cb8923170769be98978cea4e390d00b252b00e0ce1eadb666610c98a00845eb822f73348f4cde422e2177d65d60159918be8451472d4244874e14bd052debbb0d7de17f3923b54b3fa471a79339ab012478cd73f58b5b84bb1be8b49312868ce396927214c8e3649aeb84deb7096dd6bc4253b5fb2624f0feb74c23964cf4d9462496e2c4b1c83b215f68b4931a8799a46de8ba6f984c81c2f312e9222107b6ac98a4880ab8e494d8851c87d532a2906c59824df64906900c11228686f9bf8fb9193cadbd5a5274edd10b1750a52e9c1116759310e2f04c88a81e31118dc48c832c67dcc4bce7214ea224f360e8b8a45523e36a4b12855944f6f410951acbdf167ca5f0bc5e0c2aa806815103f340deaf236b0c6b571d108eb875cb5b4118dc41ee4bb6fa8ab7adf1494910d148d441b2d058a474209943ac5a83756dd9722282d5404e5a58770c5f8177da24f914baae5db756356a95aa85554f0133b308ff1fed523c67594340c4c8cf744c1b80a8c188fd1f42ef8b329fcd5120ab7605b4242127b90b7dfe85db9cae5da470849b4d150906214d49164f908d44550a28d96a2057f168585a81450b2fcb67259de409265f323f2702c371e819ebc4991ff21ab8c3c3e37ba6061de4092157d8a5a8a68e347ec415eda4b24f915f9a32f7d62b846c50e0128fcc40e3eccaf770f98eb28b930fe7ee43ecc6da44de7a47230d75ee32776ee612e0cd6f945a0a4081ff2fc11adc7576b6d78bfca1930fa6cc087dc3ab1150306060606e68d9ff0c04e8cefb46087038375ba15e3363ce57e349ff087ca5ff489a5fba1727703ac6ea854ad35a5512c99a2910000002314003028140c08c582a16830206962aafb14000d8fb04a765299a8418ec39442c618030408000000000080cc2606a3c70e6eee85c959f4ae84316b26b2d2381178d334ec8c8e95a1d4a38f71c5113508b71871e0af8e72d1eac747d96f6a152f46b136c9b1664315283935817b0d90d5729853c807a48ee300c60a6e5a25c62f87f284e7c1a8aadbb5f08b5579d9f58a6a6255987f5150dbcdcf2063d62f0a2d6a0d901c550bc26ace8e9d7b564852edebdcf0c7267e41d520ba21cab833a62cbefdb568c598af47b768db423f7a01bd62c34a7cf14c4098f848938b926a85c03d5f63f727f6e1621ab5d048a8ddb826b24e272655b64613792a2844e559f2d2f0d1afb2b251515481ff296d3f8a4f76746c8589ea7c4829b0e48350bd0b9b99392aef6d105724c6bac1787d64b00a2564be361e228cb8824140203a34f980fef9016c61d9f84b1f0368d75c58ba9d486f12c9f9ce307f2f3cd98b20a644183f97ea1d662ac36378846d43d6e80ba94171c907419d26467c3cf4c422561003fcea2fd2f417190d4b971cd8a4c69fecd953b8addadcdcfd3e39d81d0b9d5da72f97d8964c5d6263308763763819dd9c46d10d98c03d74ef5c3fb04f60aad53026846751a62ab524403a732b79a57299827caa730cbc582835376d11d6ef19e929d0ee0f32812882b40a8082b8bf8cfe597a72ed85d53a5a13549d565d4457e1673ac71cc7cc9881b05b1ca9cf93a16c0ddb08709227cab53b69b5914e5aabccc252a566e7da9062e3bffc95afa20027dead4c58a3fa824ec6ab0335107edf3006e105f0b8a2ee40fd14d2ab6283825ef798c7bc5ea07d8bc46b4a3970d4619c96ff7bacf53c1dd5677110470652fc48f8e4bf52129c9337c7b4dd6128329a4b18f371039d6fc7f26525b31d461571e717a3886f54be9b7f6a9c4841bbd63f39c24c46fe62a7f54de39a5a4f6e8ee957c0f2f6e4160f7886f4f4a33c96705ebfb081f6270e6b3bb866b3271000dde304dab902536354c53f0e8140ba8c1082756ac73665df8b51ed3261d3fa30ac054e68bd5558eb5f1580753471763fdbe54a585bc887763c100a157b040a15a362549cd69b53ba77145a6c2bc68fa3c085a06d8bfe003a40d19a3e1abb6eb93c254ce03ed57c5a6e4ed57fc095616f56e47bdc8985bcba8b66eb47a5138711d048f716d12f5b829b72f9a55a214d181442173d296984def5a085ee485091639588e32cb488327d39ec96254cbb29c4a548cc48a4cb827d92e194196741936d38657dd3623e81703c1a6423f86a092b0320b6b8633c3053e31a6a3aada3828a8c1f97038ee1df20e0d84c81934f06bec2ab41ec3c7f8da99657067f003629597c5590273238d94b19fcbb4a9169d8b20485d8fc505ec0feae560680fe42b29eed54f2b52762087da10215974ac6693ca0b4f20d0db43ac6482d13b3e29d14484f79aa9a5d8c832077550f03187c674b648f93e10013ef86d055dd46564f4dc7a053187041d993d1dd83ba9f6eb2943e8c3a1da16aca04ec251caac648756ea26ddcffe44decf0a398ffc12b2f09c4baa46c919e3cc79e05b464c302393ba269a5ed9d5759c266b15a3476c23d87c064a1c7df1a005bf5de2f4d392fdf25a10d03f3d6c23c39a831a5000715e5a4cf9ad76e1383567c200259b63e8fa3c5647a056c114a9c1f2801201995048044ec0a071b431540670be91cf3631c1c3d61bd43d2b15e027a5d61120f2f428eedea39b7234e24dbe4e12509d4dcc839108f307a9840d6810418e4fac386c2a5821f13dae0229fd78f2e829c09d1b46670ea03ccfb7f5371e60b4ec8b583fa46a8378181a95ca77f9739b67eee05fdaf6cc81f4b7312e7b7d18fc5ca75a3e6636d73d678138ebfc5564eefdffbd4ce26bf7243ef8fd0a6a4c6ac843cf549598298b1274d86c1707c72101ec7257b66aa2f7414bd887882396463da547c096b4a73650a4a691af1d4a0448daf207a8dbd72a02bb2112d4a9f96fa97eee3b18f90bec8ff9656d3eda576bb3ba3980c4dcf5b6800f2e9047c6116b5e65c73fc69c14d608872fbf8081151a4bc83ec98aaf42cd9e0bd7ddcc2ced5cfc0e1b71b77489b0a4e216863e82196ddad999b0b422ba1d9e17d225ebc5bb607f8c1816877d273b1e957ef4b65f3109f4224781f2acb87f401b2a7031019ff9ecacb5d9aa837cac5830a00c83430e9839b668e83e2688fa61cc54427a005936f8ab8d304745dc55a47f4b427b414b08cdbc78b9180e11a0be8f7a148d3b9512372ad6332df146a5947b927a8523dce36db85d15e0a7f46c7b4234c91c93685ba84c77eb78dd23b58c0bb369ca7453c1474d3997740f99c7a01ca46ec85c3c852ad90e965b9c0af9810a27bfcb3fae4cc10a7189fb64a80480a13dd61c571c4e150fb609451e24066de00b25af4c1aed0476c2f95660cc5392ef726d22d21807d9aad6e65a4fd8269fde30219805c68f6940727fbb39b401d2f79281d2f1604c4dbf853d54fa53da2c3a3eb5438974dd89dd33a9ca7cc56d7acc9db9ab3d15dbaf0becd0d2718eaab8ef10e0de50ff2d824b16bc1d3979e943f2d28ce3ec4f97065caded9e2820dbc1687ce6479076d6f7db755eabbf1e36634f3b62c26ea5a621b06263790a9e9283f1576d6a5e363f9783023de29ae92d71a44ed1c5de899e9645521acf9fbb7bbe510922f833c0ddd38ba2ed4f2ebd09eaffc825185fd2b4e83ce03013b4132ae77d9cd58c32652fc5b4beaad860ce87b7a69e1d427e532a804607bd9b8678012cc306d68411ecb742d734ecc4bfbb11dce1ee4a83711bf96c6d4958c04467238e5c1f5e10ece36868f2af40d39739fe9b1cf0c3899ff221c8dca98f364959c36b270490d2fed83183dd988e0c0a71929d944cb9f9458870168f0b02e11667dbf796be8a20ea36d0405c25f3796982ff3036189384a500e2da63b4aa5f9d155ecfe1abe7a5b988bd36a464495a55178116c8c625d8410e84e4eeb7249b3c5fdf543e25e97df3f53bbb6a39d8e7a236e18435191a0221a460048a57a4fc344afc9a1b517d251541a57ed74e47afcbea1bec07ab06c4c48bf1d447c71740cb048285a03e42201a9cff3449097c71f990c17e8830b35961b9787e94d87148115a4d375523b87e3d38a6aa547be48d95f3b6c89e6bf6375db40ec9d04210f188f0b59386e0bf8d9d5471f1670d1a5e00d41500d9173c8834033a25a34cecff81dfa5168160e9dbe6d79a24a22b3d753e2b58bc68562529f53cacd06ca144cfc2507ee7a5bae386bf022cf83c200fd60d66713d6a9ab2960beae695752acfb2b727a571d68012de11c8fd83f85013f0fe7639f0da7ac5389599d3bbdbc6dc73940e640f7a0d0016d1f6af5bc3cd78514326a3fedd9efb38aecec2eb1e449f051806d7693a54536f52e7538ced85699ecb26d051b02557c27b120a2a215aff7858b8e8d2170ce9e90ee438599a5c580d70eb37ae266b64ee8755e621ce8410de2d2100e6de5cef25233000c5060544dd361133591e98c8c4fcd36a79ca5a671b412b8380616866d242a1bc2697cb7f3405c2d2b77d5c5ec71694a60b928710410d08a055718d2165a0b73bd1c04d095441ab0543075048b1599aeb3486dc04587b200cde5190d386e1f14f3fffebadc1e17e4c8cf52fe5bdc871d09238b51a477e19f4074a85e21dd1c92fabad973ca6ac0370f75a1996839cc43bac734577c86b2c6e54e4abdb619b4f195f5da45fa6aa2f1e7a757915cb01c200b7a01187d3681d9a71fb802f9d6e997f6c4cec9d0195f571d12c839bd11f4cebec9340fead7125e53830d932dc2936529b8393fd62d56d19b02bf0fb638673dcc6cee79e522b1e1c477b6b89977a12230c0a4206b277bd8460c44f6c5c0e7d36453cc54fd0fbb4eeccc49742755201d848425d434893c969103d65faee57d095bfdef4f44f23aadd7021e33eef38dbf007b0bece5b25566fb04df0e2603331bec9d7bd98eb740d77313d6d9a349bd6056416c1b4f8a59a740fb7f9e9a6f5300b82ec209eb21e94af33668a7848ec069d7d0a8f304a683605fb19992012e7c06a541193b9aec070a9529b05f2c900ab9bf7808944b5b2c71d484cbbb06dd267e649ce49f049521e93b0b1c01c50c256d9556fbca5bb69f51d0f05fa0a74b40a6702f66e5d52056ea53da70ccf255b36b0f810b67628846ebc27a46aeba251ffc88f74abb46f93488328c899ab525c3ed2242b9f302cc4a8c2ca70e24476b60a7e6c1f73f3c4922b172c13af0c18bc3b620f4aed42ef4bfa4901afd3dce971351641eb8b95bb18d516d536bda339f5a3ad7eca5da1e36b7504bc6dc6c75e580cb3cc1eb0e5cab471580b8444a6ec6ca82fd59f2e1d56f75ee6d586421167c381789ad2fdf7b166be726143995344515df0247943d530002e29e01d9698549421bf2c937d32c85eb64a36f83ee0040901edd08df225e66e8644dd19b9daaea4d217589100420563280b815665a45c622c4000f521fcb7115e51e7503c92eccf44d1472c32e64af52d0e252b6d397be1eee8d1f6e30d5d1d977574884309e30079d675df00b67653e0c822a6a6dc144ad876d1b9d11a3caf3d37005215973b644eba612f2acb93dc1b6a25ce951d907d1658fea5d13ede5f50017bfc586e1ac0da005f9afeaee130605d713b7acc69b554f623feed875c94e5af1d8384ced55454ef3baa2ffcdd5a504bb122571e277d85173a8fe70af0efa00888fcf3bdc6dd1eb2e10f728ac760da47a79047d55fe3b1ab932e8ecec1a175b8d56142864f5a6d2fd5e23d24a81ea72fed3427b857c422f1fa728d46792e778037c8f080801b9d516ed80e8b41c5b1298960ec8514b22dc2f1de2bd65246e090bac6008a1475fff8e19d3c544532b3fc5e4f43f5c88ca790a161c76770615f590e8bf6bdbd63b7b7b7e9164874b82a5bc39892c4b69746ce7b77494a18867422c999638975fd22a2b9c0b110cd307cae3d1d9d5a151c8040a4b9c2986a6d2039b90a031985b91d0d7a2b2f0e272e84de66e2c863716aa05d90ef1f2dc084d7dc9e41f1c3340dff460c0dcf9c218183c4d01d1458c18ae2c917b82e3f0d38ac36ba8fcd839855303115b734edf84b3777315f1da3b81e910fc2136d7eac06761fb17e930fccb3820164b0afc1383e64bee4f83610163c67b7ac801529641e78acc782020a41236565519be41b6204e9fa0b3753cd9a657d80ef64e61e821506c78c39b525e3855b196c0251e99fa0fd8a784aae2e6add51da2a508aee66c0572e3e1408f3baa5ade786075d3dfda256ec26619eed2467d4ef850bb4558be38937ac40ef5b2d7a4e3d8edd07de538e324614b1f3c4389d1a6e59b3d84a895400d863c01677e1ce1dee7f18f8582bd65e08c8e2761e7f7baf706fd6d8b8d2b5f4648513291e89caf0ab485231657554c099e0fed5fd103d4293eaa6223cd719d6ad50eccf4f0ce02e2d13231190313b93f88787544c94b8f8b800afcb13ba0358bffb963d705210a6d80e192a2b4d4ff6f825e020bbd98fa015421529810f81484fa6ba491006a102cb2621c9323488aaec9f5ec40d12b375c3eddf53eb4c5935b3413b8b676035638e5ca5ac13da5c1c57c261e579f66c740df3121c24b6553319c61285e256173d05f0e509a1894700068823b1ab5c6cb5727afa5621da5e7571336afc46995b2829745a44e4a76dc695537fc5b2fe175f47bbaa1050a14ad3d690143a8531f5659b455fdd2dec44756400dd5010eee14cecc4be233e5822d4d690a60d4870a92c46504850793b91498dc028d29f830732d50cf5579608a2e12265e48e4a9c474c7492b53092755d7a97337e76f23e6d116cc42977ec51880171dfa5f4ae855d82cd508ec7e408995fe1d56b33d19a2481cde781d7bbe86563378e05f3088c16b034c17b4329fd5a71220dd2e78d1f183c2b1867d61dc7409320b9820d1b31b4994074cd4daf2dd5e4dc18fb493313f121f6b64ba4686c811f32808068d2b68530471ef0f5b9bbec09e8a76f5d524b69bd2be267637024b225ca7ed953a7d69e4499155768e3faecdb58f00489fae583f4ce60d38a0ab9723109b0fd5d05e9288d613266de33efced8d56aa4207df204cdd08228a5a08b27a1529414b270c69a1e24b49edad2440754d002af9d5f2a1b03e0bb0b61806c13a546b628e9181c37b2668b3e08d18d6d303fc49d0d55082c03e8c268d8fedb484371dbae963b719f69b32428f6aabb0b9a40fc34a07cf372eaf127032c2496ccd72aff758d2391fe492f077bfda8a8ac1d473189b69d89620f7a50c08325bb0661e7349f9af8dd460580ee17426d1090ed377c6b70107aa07e8e4c9ddfe3f28c86da556b7a68f9f1406aa95740ba96debb0d9de0cd0b43ce8595574fe41453960433073088fb415085b57aee137b992c2963711f38bc3d321f9ebfe8a8a9eebcb35f6fa9dff770c29bc7bc599f00b17e7c2186ea45599b3afda52d259e0f952f8da7c4b0b3c58d1d70768d6f4cf70bc4a5ea222c346226a47dc872a916fbd695f20f7a10bdf4378a7770482d8821de84e33b32d37f7bbf80680bc340743f720e9c5612ee6d6428e500d6c741d8676908f2df709841bb4138034f007dea922eb25d35a6b53f6df4d1238c8a2da8b7649dde35e2a3d76d06fc39248693ea16b9480efbe8fb6a664786c6db36ea657bb3180ece76e35a88a4e59c467fcd5e82739a84aa2b40fa430c85f2d99db83f9fff7730a6d9fb6527dfc03655fd160b2dae1044a1b03c6fd8e45c3bf4fd979c0aa3b9d1e8d918b8493da81697750b11724ebb980b83bc18df3b2f682ec440465ff12eeaa70d56f365c6ace90c8280d8a5015b4a7958acc091b00a5738e36a60c5411611461347959b592ca2d6c01abc45e84c2b5695926191ce8a036d9e0dcc2dbc26743617bffdf1b1a2d9746b95f3085c580d5f09ca2f7b3a8f3d8bbc744b65bf4e30726ed53c08c3f0a12ab4269e5d7753a18d87672fbf7de72d918f71de3306dbef9bf0ba3b86478553ffc2529cdc69c2846279df0d724e3c722b715cc7a9663dc020c4113cb0e84e588733c3a37bf2190288797d5916dbf99fd2b1c7856bd145b28bffd3be18a18b0acc7a909eee529edd521e4fe9e248a4ab44b345b9eda445e079274b5bd79b0e3d6eb743900b414d523061639df8a22b1482fc61aa59bf07eff219e3fc34884e02c5c46b467e48c8b5a5a70729359875d0dd2f90b7a70988c08266132d400541cc354204ce3858c7ca8de17b613b774e3bcad3f97e0b7c492ce0029c6585a5d24cf30c10bf4fd3abb4c8a5e14c9ab4b8a06381e8b2a1888f6552fce6cef24e016e2958b434023b00eca72c84f179fda6471de25fd22a0f34dbbdb0ddd138d9bb2e10d32d24df85449fcfcda2ef14756610e0b4a7eb968e388779ea50c3966a5b39a1e1523182e96200c727cdc56670583e0b87aff2672d944ae86cdb6662ba5e383c7ed6cceef1b597c0e6496a9925071a3f5bf7a04cf4148adaf8561b7c4a3f9c45628a64c29ee17a2be6734be08fcdb1ba2c5c93a01d65df25c2224bfcd29107e306ba92366ab00923664ff4c69fef67f7b08905fcab6e02526a4b7f061bc8c2fa7d29680caa9740badaebb2eca0df1a504f406568935e014816f92290423b8be74599f2e31a2405c27aa724fdc5cb5574ab9de2a9b38662da3c7c00b3ffae9f31f9c7d6646c90d61a541044cc380bd55b3bbe121d833e9c23a23fb799187e42075b2acb465f94755d5c6cf9443672849870bd201eaadd83dac34b4aee2b61d6449d8d566cddc8f11f7c24b2153474d3273419a366c02450ae253fd75c3b34439c3d7c86fcc59a72e64bcae78110e7368794b2733c6c04c126ed10d8c3827f7999867516882af203b56ec6117d5adafa75ea3b2444bd79799e84614bdb8feca51ca2834786997e5fdab462be62cef03883093d4376ff11e20c84b75f9ebe2cc0a04d47f462b8f796ec2d44e62b214632e01404d9e1b267d497aa762bad0dd6f3b60b13360fe242821e1f92ac86b8f2c0692e9c0e57ac8dab59aa28aa03d5425878735a558df22ec77e4e6e1ecaece7b77881008b96042cab3173c2fdf78178a692ebcce53f2213745af162d39a96d68ff93ef78063fcd30e706a0f1c45ed6955d7834bef19e2f4df0c606237976e0e987f8076b80990a061205d6b7b2be44dffbc002dd3b15c4f74e74f6f5d39bfb7e011a49ca5a732d689b1cd319a5a4638c08da323b8fc9d005985d46a0b4f31f6b1c72219593380722e12dfa895713ada1b5f6db1b4622feb2296fd1e899d95bb6a9a27e8bfcdb46e094d241f3bc1022171cbbf0e016ed7755380b5ed5c77b8283e2ee0946b3913d14e5e2764557653c06c05a7abf9e9ed929a7f0c3187f355e61d3f1d387827e6f5003b86ef90c6c0da5fe26570f12df656edb5234d2933951794de0e0c9d41a6a82abfaf4000a4df704467010750baa123e30651e3c6e4a8f314656ecc4686ef925d935de4ce3c94626c89bdb097063472fcada9bab004612ca52b1bcb5b98015e914ee22b126b776445720321121c7acc652118312a1d97335178dccba2dde4ccb128682d6ba4e0645cdeaf3375eb8f707e95597407b8ef6aa240a31a596f89a430407850367c20761a9d37d8d815d0c39bd87b6de4d11572d57f27974b5a9521b2b09e0a876de28694a118440e4ed89e4c0408c8d0e10db43746eece03b0eb7b62d69c9186614b62393d487c6177dece52258601558fc7309d78e8106c28736950d8e645e4385e110d778a713f727c601ba70deaeb831e59435b327e4ff113c3778f38650dec79cb71e6709ffbd6948edaaa245d57bbf1d041ce66cd3fdab86456d0c25a531a3b09845d86948bd48332d048542d23ff1db9ae1198c68f1e07bc1cfc3d19c280deac7ec5f5b80ca04aa08f3721d683b03c680fce350350d080a3cc88b37e4c067b4ccec3e82c1a7bc8d10d03f6930c8c17e01fb7ebae9cbd069aeea169a4e864cb76091c3b9a0ea5942e8f8b57536b50e43b5e14f307c8c0246fc2a19bf5187033d31d703ede672f690772f9e9f23cd0b8593fdce105c552053a09b5e2236bb06c359b92ab672300f905b00555eab15028ee60d97646455d9101ad4ae7e6faa72c3a1a6a5c9ae1058cc199adde84556bf95c108f7105ced8cf1b46bd958a1ee22117638c01c5ca348ea69f7497690bea9013b5d8989ff42baa2ede695fb7fa896bac5ef509b8e649fe4ae9fa06ad66b27e8ffa47304635f272dc9ba465a1f63159e2ed259eb8edefbbe24607a4d51c1a60811a3433d7c3b617f1a1c99c3d34446092af64b8b9535898e73665b23afeee8d61b871d9d6673c3adf2b91c7171c06737dc7823255f9d768823876e94f100a43ed75f5af499951c12f406cd7886dbe7510aee53e211587980f0717b858a8825ee99adccf5f6bf07723a84ac5ab190c4793f95e3a125126f7e2e78f8afa857086aee92282c2a2ceb942cee77c50c591fb58afed4b4970c5d4b88f23074c7011c0df063c8038964fb27ef8fac1d64ff5a02e5a4c67954cb62e144f9aa547d432088e6f6bad06259117c68ae69cbbd1b4c915d4c4b3bfd52763289e14d568bb7b3564558b4a36624e4747f79a3b0c65c8cdba5c133011b9ab8eb6b69eb13e2bc01d911663bf944f407340a9e36e91040cd8143fa2a5471bc03ae519d83f3d597a0bd7538eeb735581045c2338d934972b8e393feeed2cb073accd4570377d6d5bd2687cb3ff476a9caf13c8f4b5ea973dc474e1c496e49a59fab2844c906aa636545a615a5a0f8efc43a381316bd8e82ce5e2ad3d92c03a1446665e541475653c341c5893a3309ed468d83a0e3982817f9b146a51552d15cc1454af58f4a8e65f1de5c49bd05a5e6ab020f4c0a8f96f113d5be2df0975c6febe7c5244cd2df649accf5d5a1bce61a291b2c8fa822da34e014c7a575500052f0344d646a1b3df3744e851763da2074b8ab0eb5287ea508b6d4afd09c6abf8829da3e126b5b91fafc1512c8835122df13d5d2326d10fd52b04fce11e988a958ee2e0944e3d4e04e7d361a0a65117bb4b30ae3b742505e46dbe3047d4e26df73ef9d4897f8a3ba87996674dac49e09d0a1a9b634f29dad8e2269c523cc34b6023994c2832e606d364dd2fe40b8fb1d56641ca15a2da8c1cfd4f808851631ed68b0f8b1242a093b2a58d5804ac9ff37697472d75e67af5f919288fb707adea90e406c78dbe86c382478a2dee1308694d499246a692078e85b2b3ca1bd5e1030928d2fdf1344a6a68dec54ed6b85e614dd44602f5537438ee602cb54f7af23be62c52d9765b2017e37821bc9ec95cae67f7edb0a1ded7e095a9193cf6a0d3de1f60254d1086f70f96b25cd51475f5a061d6d29c6382b5aaf47683047d1bfa9bf6110760b35a2994a58dd01e4b1ee67a397530ea5e817a885b981814d07122d78c086c359808290475617c05c6c4719d6badffe560738a8ca57def1f39b605386fefa221f81eaaf80439cdf8fb6c8afd7a70980f69b89faeaeaa7c0090e0db947d57f57a311c4e99c0565cfa9048c072177e0cc729220e192547e71e7fb6ffcf99eb64811fc0df41080e2fe9d9a65f631123dab834be06b886e10784ad5cd2bb8f958c58949b2739c5e108f90627c82205ceff8c1fd283a26e33f20b6177d39f0e898b5e311424189b8ac286b92c44026a3cc8e620c15245ca85982bfe84f25432ffd0fb8f89b510d1c1cc7e9db92b33f01316863ee8d4fc59fb9e569849ff8169acbd1a893fa42b4566425306ba124fcd1418f3cad548461a596123b71dd796bb6340e97a88a05fbe04a42e65a552cdad02955ae3cecd187b05b78a552cfd198345e8d4d7760baa3b88dc1a6b93b086ccdda71acda737c994769bdd1e580436c8b82605f41bbf203714ea4b99aa18e9417e9212028c52b0f170d59edf1456c813bb594b6db728139b78e4cb9324e677780ab2a6230d94e245032ca565c80a7a23370ac2efdcde1f2ba4c619961ea0b12d155e6908c1186274e3595390cf262e40b064a7faa4c5a9b502a5342f46d8690d0a45aa4e9f639e93e3abc14b162b1bddfcd277f813578fd05a31eb87fd6c42eebf5eded1569bbb563087e2ef34b5c7599e933c60416692e6de83843e18330dc4986559a0d53044953d174f07cedc14da69fc43ea0e88a5a44ee88808bfaaff853aafb674d9894c739a178fc50e12ae4b9f0eaa3a26c6d1c81ec5a424540f0d748e3939ceec2f422d18a36125a7cd557ecdb44ccc54fc54504beb343f44a0c627e0c278002665ce7523af77da2ca598a7c4187c8ed0ff601ea7d4a432f107b5b3f9522b218e004e29265bae0313e1e0d35e43b650bf2b2d510feee566838d092c095c6f0f97d931b6a2021be569470a2e7a970b7ffc944cb14f53072ddd06c8769ddb65cc05d06c9fedc7793072d5706ce8238915c7046611bc1386ff0d183b1d0984af7d2a5d36177de7e3840442050ecc3e9ef2792f43a6e8e29357a1325b7a38910bde5f4367f986cf2c6f96913c54608dfb174832bf7d3cc075a05a422ecfe574b4ffe2df93e216e302a7b57ece0a48fe087930472bcd8b6e80966aeacaafeb3a647ecd43f1a3fee03f23f1244ff83d9b7a57284f57ccda37bc850ab553ce217579813170864d00d2fe1deb2d1f2a2a9ca686ca5e5cbfb1905fa90983b45af7cba7b2ddb03f656d3054418556f450c605484e0485874bdf284af13ba2d3d37757b980f16df8f0bf2d3e0f8d34cbed6d5f9b2e8d7e76a9be2ecf92affae90f18112f40a2f60f1755ca65b28359803d70fe21e80ae83d37b80e53e80b6072acbae06d06f2a141f7056c7cbb54149e4bfdc9b095af0334061f4b7462114c5aae6399e3b21d1243854863540c6ff87873628f304bd0671797dfe004ce5e28880ea1571992c902e2d405ba1821cd36816b8f4fea0ab8e510eb718b9c5f85f54b48aad2f21b396837bf174458541f32e5e543eeb3227fbcf0a3aff2c93391ba494e78ede5f4d8379a928836995e716849e11bc174eca4296263c0b6134acd05edaa113440ea31f13a14ef83c15e8ce3a55e3822045d4777bcb41df289cdf0bba6686434106204927d99a50c588c6d6006e39ae580d398571814e7872426ab1d2e9f15858ac3ffec3cf152e27d3d74430a9ec0b3127faa5f805117fb241201024f9db08b88189ee68e68ce7412eaaaa95e8bfc1dceb1f66db95df1b001678841959df3bb8978b4934b112d5baec91755f62772b41140e21d6f1683a2d3fe2a6a17147287de783f91cb2596d8347e194b4d44b0cddcecf359dfd5f5ca7386ae4249b5ac18806db952408df20717890f2c94aac01a3688c323be05ba6b09310df05327678c05ffc158c858fa6ba77ead6da9b137ec2faeacdeedcf484c2c3c1b810142fca563716aceefacf062f2c65167713f980a819e72d34a55d5b4fdb41a452e9fdb4fd2ec71df4c97e93ec0da45ebf6374f16893a3040a91770fb472feb631f62ea8c3e66801fff96a3f03fb51d43fea228fe5d8a878750dc1b819c27cc50b9de77a2e20dc9707e2ea2ba96671e8483fa7d3afccf4efcc1838f657fc5f156c1148bb3bbd53f03785123dceceff28abb5d21f14f898bb8de0c460098641d41dacf8bb7496aa273d78c08981225dab67ecffd12c7fc583b01c1e0d2ca3859bb7357d7f6cd4b5fd5a520757922caac06e21f3fe8485c4a223ca2758448da6c74a75c505af7150701902add48b50b99c40db8e1468d82c67587021708d49221845759aeaecb3b6a3b5aa4c4d42e1c32b49aa3c023fd632809b70b3521a9676996d59f28469cdb2d5a42606cf6a52e11d88c225321ac0fa4abf5d6fc55d45a25dd1d4810207e82399e77140a8900f8284de2f46b31b8e973a75801bf6ee0bee1d5a432b6ae470a0b612e54d258765479291e0de1ad6125c981bfafe21156d99bd5d4999bbac727af019f0ecd09189585fc41786d3c9e262199144fcb9541ec3a311dea58cc34bfd3d8cc547f01c64b8d2d0a5ddca808c93ac10b48cb589003c405ed7e444e26352024f709d9d78c04156070e0556ece1a16ec1dcf22c2bebcf5fd5507a8b5c713af7b4beb72f11eb95cc91d7bf24ba0994f1a20c0645fe0376e48d4e4d6d920f31b00775d9922a210275d6a8fbf72e0ef602239c092ffe5d497988d6cfd4e4d42d264362c86a722761340e1874935d02503c0701dff0038eaf0191137852207155e43bc57238ce311bdf9f8ce2eda408a0504cec8c091c5306cb3a8336fe3074c5b601e69f01950b4156873f0e30f75d6039222689f86b365c703c505c6bf1e7cd9129b5c9010606cc6aee17e661edb4bc0f9edfee73bb0d054baeb165cb3831899310c1182186c23fa25ad81ccdc3148e346cfb8f447a3ca974de8998d2cebafa5aa9e64ec2863091440ff914750e50c348a392eee2a8d0082096ff4d9b86250968183284774c718662375b59fddf3b1ef950961719c1eaa02c9b49967b2b44d0d5196bff8525584fb23432449764668c111f36fd65ef6efc5444147daf97e1df4dea364a8a34a0025e1dfa0f0455d93a7fcae9dc691c07bddc0a261bb1265f79ffefe72f8e6c622bf46b08ce632cb7d0cb3e059d23d7fd7fc6c22f20bc4ac8379b5e48d3cf23f57c7d7a313ca945143ff724857ee999d6ef419d45259ecdc3f91e6dec0ccd6700cb2daaf8fa67a62b11a202991e52a026c5c7432ff0bd5a6dbf45d4d15e6cd63097a4c59eb30f5fd52ecc1a84838131da2921c1acbc212e311f2e47ff57f4bff27175852d691c1e342921770161e88727db0c1963c25b62f6881c8b021ac1189eb5ba3561ec1c1a0bc1bdb6ea6f10e01cd8c3afa8eff771d0c2c5da41527c64aea2927bcb5482e15d73f209831ff36f0f7a072c11fa558eaf61939254774ad5b25142cb0b5ed3bcda2ccc3ad2066408a8118fa9d43290df9cb1af6516d964de669c09ec2ef894e17e92dc472122adab9291c9c0f79e9db2e4c4b497e36085bf20a8f134e2269b531f27f9842e956e81ca6db690cb95cfc3d66b8c6acf1365f52ec914e9089444e4aaa1a4d4f074472d4d9910e9c98efe013869221b84d952cfe10dc614954afb90d5dbb28278840b7fd2a660d59b4307e879b8c67273bc96a0e6afe561f6ff56653137436308cf52f58e0ae7013b0624eb305bc511181ca284bf5d1ae9e40924161524181455b31bf25005610ef44682f366fdf08af87c68a9238d7de23ac0382900eab3dc52039ce284723016a3c02a139b9eae506946ebf3bfebab396f68126f306ae987af86e09e0bb8d5134c33efe3d065a8d13458d3fb536f16dccecf110f22da7ac8a9704c09c255946ecd7a6a3f87a55abf3ccba323ed753686dafea37b8825cb4bb9d756860708c18c5a382fb4c6c4cfe6a83da3fbc59a4983b091dd61d02eb8c2c552ae5582520bf8af4e47d250ca5a00a895a7b547095b136cc8952af80f9ab3d65df80930a555773c2e9c22ad00f8444f7bc785b5438389e393a6eab57a5882388ffafdd6128b5261b224bb9bc090124b4007389756755f324c219d4624fa647bde248a4c0215638fbdb34274d66a9a924b23fd10ffc5c286242570e84fd5b50840a0392ac4061907e0212bed89f6fc7f7086b8cb6bf44fb228489cf0b5f6cdea3b84ace4c20a664dec814a7c0283c3b2ac67d7e9c464d15052b5e841ee32ed49e6878d2b3072b4eed1439b1c7f987985799c930816298924e2dc82be3b59ebe5015a7f496b3d9b27b8d697e13e80c30d964d2bd7ba031056ebe85437e4e6b3e667e28e2e022ff694007893d0c8e869a2175ac618b8d607908f6b9dae599c92bf1eafb9341905204577a802be031af384115d1539ece742cfbed4a70a4c94d81b81e1b0ecf9ee5efab3b7ce6b05b163b56a201e4da60a86c9f10cc6f9f62d750475cf590d52b260a58630293c397f638842271bf2bee12b67575dedbb8ed66ec4b96f3bb20b5b21f37e1d59385a69a45d25420aa4ac68d430ec48a306c3ccb5251f673c490d4292e2e075b4a4a90712dc779acdd1581c0aa5c3fc6c70ffb282de4fb26f7f7e2e4f6d4c47554037f0f7479ad862561230bf15e68389dfc95ad29e5c1b1d34a8329f9753db1c6e3c28d14443fb2414af21c62ee781ae6a70ed4e878c5231abd91f17f291efcd3248414730579059f0508d1019c75745fe42aa63cd47db14557fbf8ef63fd3079251c18ffe589db63254001f373c6a1dbb0cf243629dd206ba93ebee959d1657d67237fe6c4b86a44261bf95d732b92736d71f3301ea2a1cd441b79c07aa3f66eec938065679221104935ce9a46ac611548ae1d999a4e44075b259280380f05586a1aa24938a3c2e13a5755e7fd1b7c690772ed9dff867c231b6f8743ab673a82d255a97a1fc0654a0dbb595d2bb5d1474405af22f2202bb0f216ac962d194cfba2c33322453362c070bedeec3991e0092a329e278e64ff3d675046d171498e889a33ad38e8839b89f0790c2911224e0201255f4467245c5a8c8d63de78e924137fb681dbaf646e8dc441246b57a8a4b78601b3dc2948c289b8f45ed9d9e27b01137c211a549276bffa879ba437d9ba39dcd2979c4d05f99c106e131f4841b98c21d31b1401f1882de3e6db7b4ca50753202116656c3eddfb39f0be953230c69c1f223880e0dda349459e9b1e704d41823f5fb29bd980c929d2f04e99d6faf451c7aab4389dd04020c8af3c5bf29471b48938004142a45d9eb54e6858db32630f4728425e6499c2b871d29b8c2a1389206bac6a760a05486f798b530c520b2b61098fb1bd68712a2aa7e4b0075c51ab38403eac97fba55402194839a4ed62e043e39198fe6300bb3e40309e15c0940b5494fbdead82b786b9870b00ef8432e5724bc0bb18e26106ef53ca0a5094eb8e9c12a8bd794ea3c7abb36d200753ddcb80b6f77d58eefd693f58b1c62496c29d6240edf4d8915301fbd49a16123e22ed8e76bd04186ee64a481d65e6e100f01f391d2a109300f12b76b1bbee509061107c21714ca1d4ea069a9b0e7ec1e9f4b01ea1dac307fcbb885c2dc14cd7bad597bcde5e1b0656052ffa8b9281ad78e6b691aa46e7b8ca2cba0df332810cabb0053c99e56fafe8a487ef55de6082bbcc076ce4176cc6c3f11b05992c9e99875bff1eaf06f008be28af7b7533713d1895d7a04b317babbca7951e5a05a8c75bfdced2d9aa9e70145109bc8134bad5e72daaecf13cbe17765b930e86e62b53e912eb679374773f56524cc22c19190ec3e64b01ef2491daff905530ab1beb268eb3b6ac01703c2f1629d30af91b9a6470523bbd33a0fc23ce72b94342f20590e6276f176b4b088af251ea71a3fcb80c38d2d15c0845dcf5937dd451b2832112e07511914edf6858fed54217f612112c6d6f07e644906fad5268f4157f88489c66e6877c041c5fc1478d66dbb7b5e0f1ec84aa7c0d2a40c32e9670f4c91ae99b8a9434ce5ecd99c2abfcf72114c70572580ec169ee1d4bf4699da0df6f721b694d6c8258844405407830855e1245a21f1d5cd1ffe3d9043311f5bb5ecd4117f779a42502849519d679e39eeaa40d07394b3ce940074cd6027aac09d0e62566def9f96079540b7cabc915536c8a89ba5b3b45a883d0644bddd1e2cae167707fec27a5087f11aa10be95dd10723af2626110ccef77d9f730baadd88f55f8375ac31cd69e989dd7bb1b9836aa30495ab1e6889f96de46f46016e81e89331a60253e2fee10d5288cdd9af3e8f9223bc99e1d5a1dde7fde824cb330960bac3f7d42f562a0cd3f0973b286f0dc0df07278abb7cfc9aab005b5c8301ee404818d91c2b0d546985969ad14c1f4c078070d9fcf391be7c88b9df191732ca5c1bc0330be17713be52794011957d87f1993a4c8c58ad3a1dc4d06288bbe208b41e8efbe5fd0abfbeda346fcc65342fb80958572d9e16ab2c6eebd3bb6f876d2de329f684accfe54dba1b75469c8dad234ecf6a710da116cbc8eb510022f9895354efbd8bad1a29312b626cda109a2773cb8cac0b066fd9d683a078d239a509ec1cb7ee777d80566bc1f1bedc9e8e1d1d35484df7a0f3596eb659e2a9aca9ea2e05bf31555f30fb52c8796c32d4ec0795334c8e3a655d3cfcd6a7e13f0cd03e6628274d0bba71477a312bf226f05db0a6fd0847e642055b0309fd1cf9c9c070d2ada0f66804eaf19c79506c599b5cee2b01b06c6a4639c9aa9150ff36bdb1ad502517c8f43de4797010d76c460165f8e4ac4334d5b958fef6c97de414c0b1e4e8407e0665394161eec9f85cc4a69830cd18a18426ec84123f45b29e05cea248040d7398002a476292b584d6017996c6e4e0e21222e476f27049678132a4deb498263fe436664a1e6207a09e171df10ed1e0e85e99aa0162777d153956aa20774205d16acfcd17c195619a53507d24d64bad8b445f7eddf446055160bdbeceb5429f03d6b063c37c2b5e170ad1cab69666573aede64117ab5e55c279c012e8ec7a00b778bd832006e2d31adc0166b50026e730af836310e4803cf2916ddd719755145d163613bd9c1139cd5d5fae3450a71c149e4b61eb93d824ef977cdf64bd3b14ee36cbbf7586c285d118a161980d8a0cca177700a48c41330971a9ea056026b6e5328ea36bae1b36425ed0de9e263ce1e96f3d9bee033ca95e8122b214ad10105f570ce13b0cbd25daaca9102df2ad4cdbff37aa970ca9c2a81a1c10c92ba2f1b63c2df37764cb8be90450b62f85c67ba3b44a20747b2b64f63f73319bdf5c45b861aabc9dda817bf72eb892878d880cfc149c3dc9ac63d531f7788620da7dbb0f8dfe0790c03e90bfb56ed809db3a4edabc0125f7a92080b5024e7fe7d33600b4bec86e89c5b4a04d041ec40bfec9572650dc0bfa962abe7327461b63aa578e133a308548c623f4308ee06391ca5d5e85baea747bbbd643537f9b46aee7ebf534b206e0b1fee8dfd55c9c1a7650ec90ee9ddd07ab2a3c2e835975d61d6f875fdcfa5e9e0dd52af69200a6d0567feecefa47b9635e588e15cacc1cb44d8a29872aac69af2f6241b810604ac4650e04933bfd806807b9d00925d33a36b86f3ea05832818f44468f3809429f74609c3396a23aebcc780d30dda4b36b3379893eb34c10779cd255ef154e1ae021efc62ce0595d91b991facfc12612494e163e6e50aa395006feef917beb4102c469d217a5ea10f4b4501b0fd0599e269a497fc341f581c6850deb2fc2766d8903cd28d98eb41f73f460607b165ce43ca6435fc1f091f0c5bc7179ceed48c7a6ee1c70cafb11a73336aa6a522a5ab6d743a2a2675d1662c81006655f24607a950afa4a21c22eb7b76711fe4662eb1533c78d2470e8bc350b2d64c413935b689dee9d0abc70f3802fffd0cd0771da4b299d9b6f29c191a8517acadf5aa165fe178f966848cb0c37502d33c69da5f0b2ee38ef0f19bda4a529136b9a3b1d0ff48f4c5afa43f54ccba983eedd8f7e222ad08fb70b7f345db65803aa9ce574f675216982ffd120fddfff9d3e7ee52d0d15a1d86b430043407c1db2435ab32c430bd48db0b1d82f2157c06580cb9a6b816ae6cb90901e0c50923e2c29ef90944a970172b7a29744a648cd0747e6655fa5dea800a6c1b0bee2f6e76dacb8748342ef43b194f47ad1af801a1b36903fd32944804017068597b04f987f3e701df881ec3abf2c6313eec195e12c823eebdb9637e9bfdf8f6f5cf9885957747ba1b65e0f43d24af7fe664ab6d10b66cb255bb1a31114be0f869a873ab4bc0c221ebc377ed36fc51a61ce7b766fb944deead50c2c20e97fe04e759c7c372396d81d689c508ed714d93f6a877108f0b7ff520a7509762d2a15cb3265dc1960047be0150a70fa4efa708a7496ac6d43ba8ece64bb4bdb3e2ec7d6b235fdced33689bc0965e9698b7054eaf76eee59478390e739dc10640c5955b4afb21d3edb841d27da1c3aab857f1d524845766fcc3609f0a1cbadcdfcfd36adade12fdb1d1ff4c7e34ca23ae3eb4d3a8a30db1574459ff1144040decbc4a49ee7795ad3f9280d7068194d989e3b992cc6ec8d79e6e064a895c2340c66be9892bb85235a895779b85577b85e09acbd8672b0338e547a639e257df09f0a7749d4e97fd5e1293e3c6247b8f7c5ece5cc062be9f31b9540b94eb307fbcf2b3618255ec8c17416dfa31fa9f5e33149d03a9e41908dd7f98a321f2350e93e63111e42391a6a41e1c4d2ae8b9a629279be6327c2425217267be2c581f9ecf280d80859024e581995b01bdf5e19ba834932ba5cc463b4269d9983d6a806178682a4256dd8a301dd90d03890ebd216460220b98546f6eeda6fbb232b8451e542e9f27cc5046d1c5b98e90a5310728549c9651293dac22d64683e16b48455b8efba1c3496d7462f40847410178e651e6c3ba80d5d47b0ee727e74fff2480c63a8d3ffc67fcbff2479f301d8558c97fc8e3db46c6ec8a959790128841aa9decf4516693aaa468867a2c53529925ac3150396d7ceaa30a1dc6af12af46a85b187e41e5d6ad3eb7667b8cd0fe2a6d15dea335bb171a64b3615bdadc7d87b1587288e68c0865ded419fa5fe4065ee94ea8b9341302228da5701725c558684b3052aad1458990117f30f63938961d506bf5ac2d26efe7349757c623471d0feae9e4e625a70f318375930b5c4fd6d414d5442893f38178d2681f8a9cc2442e38d9c002d74479ee0e9f2cd3fa08348c06d8c00e40700136840c253b1bdfd260a5bc5ff57410053a427a3fc645c4260d0eb9a088b66b4d34a629428359afe0d4473d3c7af57d35f0d5359e89ef4f165e32f26c197c6a5ce2d8000c0ab9e57723880594bcea21a97ab739bf3b51cb6e12b694cbb2b4152b183de251191edcc9a7f29eb9df863622d1ce7b4cb1527f5ed23cfcce63c84d1ebb3ea5d5378814b508d48878a6b94d379991510b8218dbd783086f0b64b966fdf94168b5017f67da84e317d910dad6ad0d0e2f0165e1eceb66b62194c28bd178c291c1c1c32df3e51d1cf34bac3eb119f20bbe0dfcabaca83a2509ba1b0a2ae56b789fd4ec1b6a0164d7ac60262888af5e24e5e8d095ee7aeab6ee9f403f77a8311af9fbc9a44d9f20d22ff4259f38b3709f8d70a9a5fba69832a5bc83708b8d40acd55ba01e576cebc19fef5b3caa5c5e0c727c235fd998e1113c62fd681f64983620ef4527330476514b864d69020d8125531a854458147c2fe6bd5cbcdad6cc1e7f6e3864e49fc03c6bc0332d5e0890758361c6ed0d697cd9616e506a14dda81e1db672ab3b559ed7ab3387de56605859fa0cc032cb7569bd776f75c099e820c916fcdc718bf5864e669d521fa36f919124d74c7e3d696016b8a43590767370520b66e9dcaeff41efc1d5d65e9b78cdc9b109758f847e70e20bfc42d1e99bdbe66db17c5511cb0d84976002852828ed8590fc6339a6e0c4500dc575c6c583de821dd780fe05f2fd3fc8437be1dc3f6d85eee5983aa45e2e3f5cb845349988612f8621c44f78da5b9771f0a15dd5023943fe94751f3f56b912ed11647c66f53ce4b89a9362cef4bfde2a37ba189fe4232500e247982970d7daa0da68c15908ced073c182ac3ad95444710058ea31f31747ca2066814b691c2dc217652f483d63770c7f104944ceb5366e763472a58dbf968dcf997867d9228eee52841e860ffbda8553a226353b3d0fd8dad06804818440d97676bc2862cefa46b7e91967383da4124679263524991a01aed18ce606a9fc6b6de9c3634fd8a31e6c1b4546a748e8342759319777e32b29ebf9ae006b4e4899c6dea6eec3a51fed851f8665fe169988785093b42414800236f315acc1b97584b5f2da25c46d0e3e2fdea15e2f4f0054a5f649d328d24707b0552c19579442b4ee294f027ad77d87716b8bed9983ad7448cd903b50178a9a49a597ff65f650ab21b707c227c18fa28aa171da41f2e0c31e7d0c24560ff90400e470d0520f6caa63c67c4073c8c7c5f3d3442c8048b1589a16ad5d100288240a2498c5d424006b1696d0c954e5a70a4707191bc176475b902901cbe6ca211867f1f3483dbec36118e3ee5c56a76d3652ff0161d7563634d7637cec11c33a2519ac6a4bc8a639ea27c187e9366f64009078c5df090e91a15ba5c19a4a627b981972e9db1ae1a2fbd6cf7a70ba18c9a8b83863730e67fbd1de86e82d976bca9ccc172df561757999e8d94954eb49855c4a652a568735b91d36d85abf7f7a678abd7466de75319dd3a4c6bad2accb791dd4f5888436bfb8ef464997bfee42f2124759218f09172ca463406e330ca173995e47e7511ca8c7165657505b2365ce815512953365ecc79ff6439a54c22712b4f25f29b6c88e10c83d6d7a85546fe56c23f250ac3d80e8ed0bc62b377f8e139cefca57e6bcf30d77c9acc078178e69f35f6f9d2391e1f80fbe2c2f347dcdbe2f9495a00bc195db9d950f78572dee7497d0cc8d0acd23a4b4f735c635cd505922aada8a83788996751f08a9a3a1fb8ba691bd84e0d6acaca5799881068220a28d9a6f31577a3c2005cdda0a0595619cb5872a2b7947c54ffd9b2f96e89d2feff5690cedaade5fe29a88b6a541e2f50e2151a40543bd4ff432d1e4dc56f845523575ee96ba00a99eb3cf2f618f8576db5e68ff714078f33f93f37479100b8fedb9e268c37980ec616f51ec71220ac81702f3c236291ae9c7240d71dcc4942c80b0a13f594e7faf1411dfff5b3213845adc0a16bba44be02344f2615f217c6a044b14a8d5f4548c9a1199958577ee15acd6033f3b279eb8a4787d13a56b2d04ef11274115ca4012889a17ee1009ec9c1193a2ca8510a6c4a22a39b5255921992ba4b6d0778c612e8deae650a986f8e0fadbb8e5628dd0003135e0b8ac15360c448dc6006018cb1d4656a4ff1f95743ddc1102d9f4807f902e3e5dabf588f42d568ab48fbbbf28b9a1833ded1d05156d309011a3e5286fdd9663ba39be0125d0a35343216bc288d4126f049835816309b68cb907889c79712ca231bb795fee2551695d482b79daea0d1d46a83e8abe88e50a6f6e807ccf556a2b92b0c9433e1bcfe857db72e3a2b021fabd19cd49571b8e1f57f92a3fb3f27c7c13b24aacb008efd519ac897f8db6a87cab8d463495919e36e7a114c6fef57a727732256f02687d80dea31722e620f267089c4d09f312a1e0affff8f3700afe671bfa2ca9fddddd12d2643f1fab15cc868d6211feb79f60412616693b6e624f8bcdce65f7c7260f8049c34cc097170d14d4f3efc920d38832af796fbf84a0776b971ec0657c7fec7f834390841f302fcf548382f6d9705391a54f0acc5e0837a89e756334a2418586573940739806c3c10b38238475cac8f9ad971a073c8a11409eec3c42168df19b9a2002d4b1644000e17773b22a1c8aad871157b16a2de4f12c1d5aa04f59ddcffcebe21d5800a120534a60db143550cc0546ce59e93602c6f9aa3e001c51b32f3e4834f344ce3a5322dd29e7b844a18abb6cda188669aa09549abdddec78374c0d6dee8602543ca7bcb2ae28b241ff821fedb06275f1e65838711870fd1d8b7425e851bf351a4a72fbe7166d0a1f837d3feb2ebbac25a06d0fd1fd91bf5d31451195d58273883d9335581e8cf519fad035d8f6663d2dae4f8e5846c8c627f9fc65d33b8371f68000cebd456771d7cc4ad4b2117867aeb11ab07c6b59b02234cd6434c79457e35b94fe68d22756f75b18c93a8d5da918266601708cccd4170443242b97992865dfdd5f16ab232f21d3fe9b4670711f1b49b7804c3a6b18916256bbc2fb0e2e6ee594a5961b470e2f20b6e060ac164ded6153ced4a35a690c92fbecaeb41e5a9372f8d57f7d435775adbf3ba15775da30903a300b10599918933dc1ed8ec022e32a1601571ce255ef3cf6725cfa3d24a73785eb6037a6d5f9df44ce94da578f07ce03eac1f85ac125db8babe10c79aa827c70a8a16ce5e3e5977fa8581e109107c98f349bb2bebd66a086f629305f406deb24025f875281c7e44ac6d63f31f21e6a8c389bf3b0c5b20d1a4225de40e09f0631537bbca7f2ec280a41573523f54c3a0f7fe570791aee29b0be6d1b01389f4ddf78b8159197adcb59bc7f8ff24bd6aedb19883b8b84d14ee62e8a9d59eb9fa5a6043456bee74b7487940587b0a69ca09e4c2f2d8768c8439542b33e2920d85a794f6d7937e12c4b9f88d52b49b1a1185306b1e4099a576c840ddd0ab977e63afa91c1fb251d6001e12462e28aeac3f620018f6c3887c01380376589ee955f06185a1eb63219b10baf95c8c683e599766479c0cca6a7f657e9f76986529428903c4a00b8a2e93c12fa0529c919e9e51d4101d147d53f5836d5d65a7ec5fdf628a153089fcf4a929f1cd707738ea239c19259c211036be99b9a87acf9ea0c3cd39dadefcaae6dcfedfa42dfa60e15940a48ba8f23f363b3360b84ded014cacf3aea02c0f084434ca0ab7338f6615d308cbaf0e1816dd51494c33f669d1f491ca5b54958b1516aa8103accec3d2b8e6dceed91c52f93e34acb28e9ad8423c8ef44c1c403649d12c93c5bde8073c6f6cd799b4ed480cfa713e8b62e862ad70bfa01065164a45af4f5768951da84e4db9289033cbfc1926a264aca01a1911e72c94470a0664cc21900bdd132808ac681ca3f38a7b30fe179e5cefdce5385b1db822ea024749b52386f2c74782765efb4c33032c34e8756b72695c5b10b44fe371061992e0bbda8c94bfa300b846312d2a6bce67c998904a4e4627a160613ccbc59571e4576747dbc60ebeac63cc02d04392d291054b310b096dd1e8d01a948a46f2236de118489caa692aaef85d918d401596521678cbcceb27bcc6817bc8c574d58c6c408c09c3a9ed02f0d8930f0d96ac05de1f6f8b9fa0610ef1d21c24b82707c2bef3b24ffa19914e9884171d752a471d53662a5e9b98c4fb5b6ae24f52eb8a67a360ac82e6853a6c803309fa447f3e08f21d561d5de776e325fa986c6a7ca6c4f8c9f29c8099f04e7ed6c8d799099faf8276ff2f05f25076e86e66ce23470a562971d6151dc7c5aab009a9bb06b98ba83875abce5449488048564342f7891dc0141eb0fd34dac37c8e3cd1cf92e35dc7a6bb6eed01f6c57b4ceb29588647e14e2c6ed2a88d241041fdc22e7c8a0137b02048ec15c59bb5c06d28c40d76d52d25a2dea0e248bda00e67c4893ae271312d4746adaf615125dc865dd57e0a9d9a639dd4bb15651364f5ce26bc2bcab8f3af351527a90b58df60e2d563345dad452c8bdab43f27cac08444a62eaba8a89721d2e9bd973e981ed1c18fafb4fc3c1aa98afddcf537b7fb2eccfaad2bf80fd2b00eb60b131b6a9bc14f252b7426c0ae5f82e3a97b28a245f08965329ded6566763665c7a9a9b4a14e69c291df92309474e3bb88ecc2b677b53188d8b34785de6d83d7b112aba9178c7dd2223b11fcddd0bdff486b1303fd8d9a7a36fb1ab9c86a808d16eeffaae9f32d03c4ac391445733a42b31aa9197d5c6f8dce0363a586302d1c1b4c77ba6adb49e6d8497949563478b493d8c929180cdb3c691271937e225a87a422bb164efb4de842977d5d6318a7d5b828d51db40543be1eff6c64032adb2c8879c2666129d1c6260e528cb980a8f911009a0321f7128cf728090755c53bc7d059b62a7dcba842cd3810f8bb46b71d6721a9687088104d2494f437855b4e4a9b687bb8672253de8e1f75c929673d9f57de89fdcc2549f661c5e1a0003a66dbb3a54fa8898d76894f9e4bb54a4bf654037739bf835fc029575478c23e2d6c2688e221bc49a3da096bd923d50f35a8ad603ed4f944259f84629e5b4572f8c7a94966ed84a71a2d7a9c80575dde1ce9e52c193fe9a93363cfcbafe620cab58b79ea0beed7fbcd5eb1b738762c68fa74f0a64cde2cf0c98deb7a212b9824a0c280d38a04e6fe8091552d03ab5b598b2ba685f48b8b74de5d614017b5b9a50dfbeb0b8de7884159f9b8082f4bb18661b2219b306971340c8d5f5dac5786e1b4b3da1b9c72dd1095fff4e796425c89d9e6d29f224ba480646b1e17977239fee18c44be840eca92b38d865abd62e27a93eb09aead6ed92308565f74cbb6cfb71befbe181ba43b6cf5314d997f8af55d7d5536be98fe6638e35fa85b3670628042dd5bca031e3a321a6634c2b165d7e432420725447a6a16a3f5e44c9da02ea87eecaf4f6a3e716034a4e4b206ed26449241622200b99883f73b92cf7d01725dafca41b405fa07c506df97443b73ba054e572ff6e4128dcd00f081aade9aa64eebd71a367150c3c79fa5efd3a1c855ec5620abdb4377434b48804c4086c148c486abf0905358ae670b653b7f17f6ec53e1411fb73067c5bc2c5d49d7f4e9b413de0f4166fd90b1a2033f7f407d0c0b3a832ab1bf111de5c42a1f9b98fe40b95fe2935a1b5b1b6e0cfeda4abfc93c46b06802a66decaf47d1bae0de003ee39cbc04672e11f04c255616b6bc8e9572a1c7388ec9c165346e223209d49e0964437a0c34c094150c4a567f821c9729c6be15fb36d0df9608f204cb262a1e42324013169bedcd00d8fe697a6f1c25b46bb31edc5dacd03658ed5720ca7090e8e005a2de6e196a01f6e28f49116e740c3a509963a895a323b311360198e9181d48fe208406c4db8092cf283514df915d49dd8b02aa1a080cc05c59fe33da2ede5a899f6e2199f30587ab6b056b5fdf2497f294025d299d1723eb1f7d2c282c5a7118b0cbcda8726811dc18bdfe993666ea5bf6ae583cd5a337d9de54a514986a3409c5ca64f828f288d000af690a40be6d6dc0eac20724c229e17dfcdb838a69ea601885a48e24c0f70bd6affbc4560ce22f2700efcca904ef991079aa43214f8acb9882ab8bcb29db4780ba81728087c6fcd0ecb07ffbf18e7dc124a839f6c689eddbcb06e1fe81bac97d6b1ee2485b0a8a816a27804dc9ba220e611e7285ec66b340f5b3471d28e5929b366988d786ebf059a7d99cda276a3d392c61907c9d44ea8d64fe422209bee222a1c2006fb2a2964891548f465a61ab0c4de1dd9470651fcc10848dc1d8dd128d204ec3fafaa4d30cd91a008aa502de39c74a1e838b0e89e86a87de4d042c5fcadf1b6056cd5b6f9f251abd0e88b036eb0ced36d2064ba86123c7d416ce2255b12385d6c3935048df0637c49566422223dfef49b3fd163217c55f99fa0a108289997ef04246748bcdbd3fd1674fd5e1b7e9c4b5c61aa0861efa95071d8de91f6a0802138f36b4a0ee2463876413fe4f4d491d4be14379fe231045e97e7b4f27620f62f2657be503f08c0cccefae3467d9605a46fa1d8e2af0544968b5c1e4449724de76ae31a8ab890cb9a80194ae150e8dc3c55980c0f40a4571e78288acf364a05354f6ee480b80cfa4cd428785121694113174a80c681c5229d47818c4d218482c3dfe5f89652734b407b82d23f7a7cebd5b6267f9ee22341c74a693f092e12418641fc028ce1217727f71ef6e31adb14155045ed1214602687458c55210adb0f4934481fb811b102948375c2ba8783d176aa9a11d161e245e6644d092bb46ac894a675107ead055fb9096617c13991573271fdfa355552e1ec95550ba45d817efe8511957713ed70ae034a1078737f009c3218ee7959871bb372e4760ee97ec3c83286b468d11e805b6af078bcc35cdb4ee4e07e895334cdfa3fbcf0d78a27db3200dbe145f7e253f6d0c32cb6e413f018c12c0da98e545ca849ca84fafa382cc0c436fa2423de2c3eab11a50e23b152b0fb0197008b3fac238638758528ae083ff5afff36682c5d9970e05a7a83cdbf5a83349e7d3aeaf859661cda3c999c69e002b3534ad59c4992754ca4824ca7cd36ee182a25a5537c3f6e5f2cc9ed8c3c9206fea7092871e2b52e45ddcb2d86de6f874f6eed2bdab014fdf677ab4ab37e9e22d8fb4f9a0a052a5382e2ced1edfab887dec0728a0f2d9d7c5a4216990f92cbfbe37a4f0816f6fa75b7df062ecdaf585f3f9488f7d3fa97bdd89fbc3b65d8a617060828ad80f893c9b2a96e0da29954870d8e3f6fbf4c6904a0ba3d00cb7996c4e8356bf29d16e3334cadec72cf53608f3d6bb4a0d688530494e77acc26933d41f78d8a61052ca0b120b58b4ae1d3faed5b0322d4401ed0fa3f124493f4f242bc4ff0abac6b81821f07f11ff4704b9fbfa7e74c00b111ebd842663571700417e88ae6daf24b8e8bf3b4d65230211116aff60c1b5706aec2994f933ec50a3a14872bcfa74cbab8f2a3eb18144c33aaa0f296c77b8e9b8e045e854d3ce0bb6e568de5c76d895f900c939deccfae01b2930cc07ff5a40790f84fc9a181886a1b8e3bfee4a930fc85edd6d359ffccf72b0ca12397796b5111b8dd8835960a37616ae495f81641c0c439324267efd91b24292a9fcfc51bbd6e79bb8f8e9d7b6a4f559400b9dd7f79abdace272be4df894f94e8cdae5ccf580b6e8678005488592ac3ccb98d365d8ae4bd501e65bbc112d7e43638976e74ecef6f3b88ae6027fd1ab50f020bbc7fa84e51419dba62e3968e0198f3a4753f78f2177515205a84280df3ef8882582492b1b0f11fc8091797dbba92870311d38f1b2d34fb86d4a9f0075ad8483a17cc4a72285032ece3b237427b0da056a2da0d917a8a16a702050c1c996777542fe78bf374da0abd4c18ff82b6e479faf812251e5d436187cf44e9b833035a539804859e7706e608265039f380b72afa58fe5ad0b6bc9fdb592c7d2c63f5913b98e9a0d8bcb0c3949553b5f1e96f6a474bfcf0b43a91fa4bb6d5822b9045081cb19d20927dbeeedd19a55df15c8b3327c98b51ce0905348093dfa8bf1f38d8413ea85e9b746decce7864318d258b0d118fbf398155e83408d8c19d8b2b2983288a85b56e9641362ebf765089892cd577aac8d51e09093a98e2e2b00561267dfc2dec2e450eccd7001577dcae3bc3fe5e375aafaa480317810d9e8f75e9e78f90232dd448ff067c41952c89d486760924734326e34679d9c74e0d6d51bbe11f17289f7dcf8f40fee4e5fc5ae9246a599d1187894b43601603c5ab159f49f4a429b41e88ee358b9418fc14607dd410823bc5633ff7d460126cb4b0cacc06e552b6d35fdeb09b4691500e09d8530edc5422e85c07911cc3b740bd4b57379b8833f07fba401d4499138c41d739ed82b5447d18ba23cf877f086576c071f61c68f02dccd4ca9d2e11aeb554c106f34be6b0add37fc3f3efa0ae63e2e35eaa6603a08613e8127204c0f0207842e8c026a3e22f9a8708941b722033bffbb6d5037191c5fc29bb5818a5a24e1bc01f832dea20c89d491e1c6df9c5723fca45d8592b6bac4ac44e1bd572fc99ba521e2408241886a04e0f2bf8cc0538187e711d98a92212901d14e41a406dd156ca2a0573f4e14e33841c26dd815be56fc09fcffd2db56478104de981b046291f57b314a3e09b3a111a060b85787f9e0acbe9072bb40de03c4eac9250b48dfa3296c11b6c3e0008b25d7f0463d1260144836c05d471bbe2941264d1a986899e003b25bd894eba43605d637ca06c1bfb2f72af75fc81d19fa035084c4590ec866ca067a22d19082a7e6d23618ec1f95b551fd774ed73da15d0b57d2dd5b31d50d81849930f790619c96ee403f5552d8661d4177cad158ed2d75ee38c928ff8b3f585df0104cbc9ceaec6146a51cf286b0994f21c04509e2296334403602f4081008a8dacee6a01f2fcba638c40c42d3edd70a3c247536a7ad649159454c0f3175ec319aeffd8438102b58d825ab1d8676117951a653d537be717a1c04d458f72244a90eb7baaa2c686baf3aaec014d63c2840462ade00f4e6c9994dbd50df0372ab546455ed2bb1e6e113d46d2f6ff449921e49652856eec9ebcbc3c7515f82838e539981740a015c57397f59f94caec6070c3612fbd789d05aba5184762179f4bfc813e148799753ef189b1ae8ebdea0b9c88b19384c48acd00d71288c0a0a1a6b3da2334a5580f1b8cb8afe8dad0bed2223b6cc8276ce95673c58d33bea2ddc46283a7d596d86ca2630255cf7e532b977ae6be94684f1206141c676f1b11b694eda6cdc54505d45993b08ca9b600235b1de45352e95a59d4c2a8e735d16a8c8894ec632c9a6584a13b3812afaebab1ddb590ad218830b1baf5e725ed9609ee60930170b8fd27ab7a59e4696db7829479440869edff56ce90b676a31471709f44096261295a3d63607168d578897efe3fe5efdfb02fc796667734cca7285f78bb8956de38cc686556fd34b4ac3c8bd9606661b082d41452e69dd7c6f77fccc7c0021906cd99be4dd500f37cd6c9f9d86c6479f45f65c7398b76207f1b784df3c008db811b93a9047272c8db42a701c4d8815483b6fb1ccea2ef4dd2207598efa62aad660f269b4063c2b97508a81b3d4919e1c9f8917bdadd84b11eb15cbb2d3984c36adb0ef06124dd705b7e5d27c33d596cdab833903f0c3b0fc3c4dd7ad717886be0d46c4535d972654e03aa8d23b82d7f2a66f48d02a8af2aa3593a2d6ef3c12039a732a8972ba246e28281353f04d4dfd7e9561260c5a19ba82bc49969bbe783ab741a88c9b16862c188f7dd57b8aac99dfab50421078c0aa5d167c08c6ff4ab55a6373ba67ff896d791511ec76f98ea501270f397ca81e0a6753c57e7f327d70ecf880c0fb9c7d51ef2773cd410dc903828f49f32739ce6f0e8a7a77eb0d67458b31e0ba12f5fa63148238e139b711fb7c8fdb650995a8f0985ca09d2e6f14c3a02223fe938dae7a7c855111189bfc52a4daa8b0741d5b4016bf3ccebc19423f62c8bec7aa149fac6aa15ea8607eab9cdfb259da3c0eae6d53ded9b8e13dd6b62288a829ad287f20525c8614263efb3e3ff982941ab2914c47b7482e766ca08ecd5415947fa27a44a2aa30462c65829080f9ed690c70e1a5b4afa5f6329c4c4452aa7fd24fe17cb945d7e5feb95e280c904876bf5d8f9c7d28f65d8fb97d16c48020b3c045207b6dac6fa7777f0b917c64052e0cd4b27f44244f9bc64e626f0eedc74a7f1ec62889efb6bc1ff3242f84b4d9c365e89b80aa08628abd408377227138e4871397eb8a028f8396d17e38c6f1ffe2deb6f0f73846ccb5ed0a5493648662666d53874571e5c12d83efdb5b3d3127e5c83d9b19516e415391e3d0a275396c5118e14680e9c9c15ffa07c61ec6d3ee777daaa27157fb025ea3b3e072ae26eeb687835088f6a373dfa06758d4219dd12ae59b7be3cd6ab64c21505c0db97f6e1a6c557ebb0772bbb3d5a47400f097de9706c9418a5c99d05a2edbcda02f7478fdd2c3aa49a41bb5791754f1f982a09241f49b4a56a18d4cccabea2e88da1f965436c246b4cc1654a46ee234fee30df17b2e91348acb88503df1c523c50b563080c74052980144f4ca21d2214b46c79e84a6e7deae04d79ce2fadacad5e624920f4bc5e1e766624626665222ce27a9d0c3ab8706a9fc73ca8aa0156f81e9e62a5a95b90c2df653a1d71f50a77982eeeac19c798018d889a3104a8cc8ecb390c804fe458ec040463671e7c6464fbda8501ae5eb0749c2f64c802cefb1f9d0d761041f107614df4321499db6278cdfc08a03a723e9b56e8f4f188801bba71e00dc8379c507011b3f9bb1be46f0e3448dedfbea6c8fd7e2c6062a5e3dfc4c28c6aaca8186496661ef9d6b3dbb384594f2b05ea296a3db956ce2f0c59890d0a29ba5b4746155f3f3f2968868678ad8513c40062845eccac8a71da67e9e09afccb7e47ee6fe59ee32eb41c1a61d9988f5d788225b34e07d6a13de3cbeb34d7044a37d5de9d9b8bf075c9607076b25054bc85a46286f6b8861028ba629a696a9288d4157c46530b32ae2d97abd417a85f4c5049b541ae6ca84d63264e0af5bd59f09c2f8a1effbaeb5ed79e2e82f2117378459bccec6db9d653857eee7b6682abc37cc8eb3c8b1026218636de6b33d27fa7c0a8e956d119374a08468326d40ef21b1329933b8e6758f8382cb21a4a057c7338693aa77a76b84aa141747012bbcb3a0e69daf7921633ae350df6103c51c6e992c9da1edd8adc5dcbc0d50b5d3c6df981eed3461c36dc351c796586255ccc911031064f8c63b9114229ef409f8a883583375dd56a941669ac001aa00d692993a2195d883f85fe5ac465fe0295ace15fa4184ce2b38017b838a6083e02d0966869e24303d4776e6fd3dba85f1323835a17ffe31af18b763929f967c5ca44864a13c430ba5f215d8fe3d861c29d56ff0b4a9b4d92dfead1f7461198295d72b27c52e9ce2f03e169632027d63d578ce51fd23e4857b4f9726cee571919542d2bde8992bd6ffb9421288bd2d1cfc7f35fc72ab0348f1f07ce36a72440ac32691188dc7d954e440208b77c9a9628bd48b2d3705b1f9b4fb0c3edfc1e2a99650afbf974bd7832a36320a95147e434e3a56cbe361bb07f08d4ca80ce9e80553f0b86bdf2cedfe578cc30f1158d4d9ac444afab1a3790b8de80f9f017a14227d3748061e3fc78be049765a949079625dbd91e73a78e5aa386590e9b0170b9c9b171bc70a90f14f416d508b25428ac1fb21740e58ececb8616324dd0ef2085f7712240d106a48b3b21c33e25bc97fc4b0ff334b6df32638f32f9def052e0b9be0062bb5917ced73eada32f8af2676527f68a5dc51ea0052bc258ffd2c93a86d99f34ff6e4711d08b6259cf909d58a9034de4f0bc588f0ca040f58714d4423adf572885b2cc98b6ec69ee9e90c64e50e306ed25fce71a830ba40d2ba2701877e6964568e05a3a83359cfd30209ad433f1b668f89e0810e45d71942ab1a4aec8c91090e6768d46237f48ab89f21ad8607c5c1e6cdbae9a1070173065a717221732e27b957954cfbd6652a13fd312688829b8ab1dd7decd5384941100c2bad37712341ee3ee1dc1b6c89d523c75b062338af76e672948d854d168a5c3d8622cbd3181899cc9b59a840ca40517ff9450d7c5029af5a46d73c41a869e81eb8520a63faaff5360adc79bb4db1138c4a4b306a062cc896a825531df9eed4369be73f23aaf06585520060e528ae2eae3425d9c115714b4d87fcb3011d1b1d7cea0c230c24af960e4668a128bea5d0cbdacaeeaf34d0f1c48c460adaaaa90fa8e881f006b5638c220321691a9e561813ff763993da29485e2493cf94b05422e5daa669a86c6ae25edba6fd5f98326616201249a49ec293b4fe8cd3901962a82310358f7e0a17e48bbd8053b60933a8934b857a84cb10918848efb4560797636dc735d0c1e879f071e76ca2d769ffdb884105718621313a2a0e042b7270472a6efb6ff595b3cb3554516cb4f894268e994dadc94d66a6052a7932a8dc5f0e4d092c322f49121a53ae233d43fdbfc04b091a98352168e8d4f3c85bccd57186bc3ece607365edf7b591b63d6000b4174f989298a876e1ee12504a15b24befc2ba88f49fb1e8f6ab00e5ec32e8e47418f8a4a4b8ed76352fe30132f3945694e5a2a74c5405fdbed1ebced692b3bde3f0603cdc8760498db45b338dd4649a27b04b1f1a174f168288f668635328895975c95b4ab6560610d8dfb1bcb1184ac8787fadeb1a4ba5e643042ddf39f6832cf6b2b0c53bacea3bcf19bf59ba58d1012f6a97b2374c0874179771ebc39c272b1a4b509127c55c6ca1920ef8de482f82b89fd4e788539ab47324040f21e21cdb1d03a42c979b684b7d8e5e519165e758e190ca6ea632d118d2742e6adc0c53c12839523412328a86f76ff9290c200c69a2bf17826c0f49b32e9e442364c434cc95a42bf90b8e1d95f451f4b1492638f4fa8846d4a5b3e487b6f8d1d0be3c277cf029d74890610648f861cefbaab7909b7d4283bb40997d36923d0d2be455dbec5a3a9f2a611708a4f0f7ce0d286d4cd060dbf4656af3d5438493a0cfa3e89ec56c38e8789928bcd2bfbb07d10293a7ff9ec71e198996b680f9b1713cbf1b68dc5a293266b2c50b753a4f61b414f937087e337b0e45e5c68b7219b8a3cf8999ecc60b8bae18bedc53db096562d279e655c08b9e6e3bd1cf1c868a1f13918ece471b9d6aafeb1838d28388b726177558173d67bd1579099a6e09025cda3c41c57e26da920b9e8d28e42989c0ab4c1453f5683ec9337a1848694f5ee0bdf4deed4d8c868513b2595ec276216ed75027f4ba236018534477a43f303777beeb7ce22a4465e3b4edf7aeb7393a357801f33c144baf45e1e9a3e0fcabd319a75051c8311b9918394fe371f1989121009c89e6e8d00c1168655ff41523b22ad350ce7c77cf27b6849245e80477dcb293fa7bf9fca402352bce72cefbc1711d160174e39a24a3b619d42587cc0199576456a6201d2c9f13dc20b248c9929dcdc4c655cabbf6494cd660488a6e2acd18788c881bd09c160cd345cfab9005115993ab94bfda21dbfad9fe981be4116bb96314048dbfef30b43c9eb3a80f12a0cbcfc0556633d5936795dabac2a4dabf92f53293a87821c930d75697acb3e13e579d254f053f7854ce670954980e2ca4e4dbd512e3805a1653381370a84afbe4e42457521bbc95f268b0aebb093f397aa989b047294cdc16520a138bdbc9c25a7d41dc6300500d53f8f6c41472e7dd15540e6cf6cc0afee7dea0f18228aa3f1894fb58e776c6163c0e334b72fcf20a7bf6c96f76b3a84c2f6796f453139b4acec76e6c2fa6a74c83db8b173c4123d9732b64261cd777dfb9a01e341cf149846ad84aba7a226b8601e1a3606265f8a72b19b4eabcfcce9159b5532db9b90f42357d22e42965d91aaa93cb7c8a18baeb419cad27cced8fbaca93edfe74f515d3466fd6701170e1e5ec26ab35d8b0f21a7e32902ee78f9f5bd4554ea32da046e52aad1f7bfa70c86aa21bc925237b64020dd09ecc7c66efb1de5cd0d1d66094ec0c6fb892d408f9d820c6bc1f3150e27e136cdf7c1470feaad0e6c5fe7ce6779093524bf0c17650e0578b62f33cee2383180768a26be81ec1676caf6f33681875bd94446f2abde576bb5b1875d229e9449138020aa610c3f56331dbc9e218483f9198a7e4c1422268dc13df2fe8b7ed6ff5f4cad57305388643d7c0816d9c00245088a8e967bfbf2e27a38e8d4f598b4b7db37f18d9a83410822e1ac1ae0422171794bb77498ca6d2c9f41ca6cd1fbc2c49a01e413c79fa9a582fa61d22c83eb9afa81d9b94c907b8e904d9bf001b4851f0d8ee950fb607a64300dbe4e3ccdacec5ae0280b7cb2a614dfafcb323ce3eee0006697c8fbec3454624a70985652204062e2a9e035ef39b4545a77657b1468cfe12690d45118d7fa2e613ed034665c76268e90994ea904bd0565446c9db06f47c8c2ad9901a2509444f17371a0bdc677256fc5b20c744ca56f5d08e894cb084707d53dd864bd73da2f6250590c50836a6a83c862f365d3f0b94988e8910fc1584e2ac16bb330043a9ec8a21a0a16384b39ccf38ee3c80be6d1ac16cda21a53a0594e5d32063339a4ac5b9067712b1050f6ac2621fcf06e2c1d7c74a9c984f48f5136e06a87526ca81a6c6c69cdfd0f66ee4ea133e92f7dbc0b4537f0c41a8c311da2e5a8d0a8b9989e43f17e276894d3b25d8710a36112278b813d7edd879ff02cc23a63f4a85d1238970b1f7ed1ed0e4433c3216b5009c61084623d305f702280f29f00500b0a5ab920e26f79bf8a712da28e0344fa3a2e760e64d2e0e8cc17fb162dd845aa6abca8f273c5c80934a83c5ba36806dfab1277280e8069976e9e52a4180cfc61e9e7d18dcbcd7cbdcbb19da80afa903c31219981d096e2976b3ee8170c38ff297ae66be94e84c5fec01c15544bc32a807c2640d0b4e1b080627fb5707fc3797e829279c1da0efa0db3cfd30794269287cb7c3450a10cbe4000d3a161c71b022c145ca8d139350386862ff460a3bc7a64e3bbbc9e679bd3a0531de7f1bf86a1b203ccb76cada4d78ae5436fbac98f739d0a1211acfe860cb406388f8fdc1005272d3060c7c2d28b87cee0be18c3a7e3a05b464d618f8de90a2399d2a895ec2a4ab81f6cfdc0926779699bdff334237929a477e37d66d5eb90ce1b44e2770fd2316396c92d21e4f03f65c58f0cafcd554850610fcc32fca7c7e24a80a5fc07598188ee50018d6c6b856be66226b1501d1a131c825dd34f34aa141ec71d6130852ec88b87d07946eaf2bcda8c56a5983391b1bf71ab5afb600e7c30ed99ca38950a25e8d363a94f244fee60a5641251fba44162dc10735515567d05254a3e2b865a84c566ec92aad4a384bbee15ac7239187169937d48492658755cb719b03860d7251911dd3a41f9ff7646b4a844f75970367351c15d7b43592202a7c742c1659c77703aab0f09dbfa0486b82b6d2cced1a18c95d78f09c616c954c0cf5f51223edfe6a361163dbe36e218b06052dc42cd0887f708417d2ac3f5367c72745851da23ac1abcd86ee1240a6a06a0b0b2394e70158c65ec541ee318c8278a22e9d20b0809540a7c76caa89854937233803b621972a3c6a27081bc23716fa3e2cca5ffd540f06285135db3c523d08ab6b2452b10eb52968a5091b71486f5863a72a56110e6d76b9408055792a726e57ecf05913fb30b62052ca22e3c41e72726fa84eaa8f375f856274e415fe13c2324e93b020843f90a754e7ea483a6699a0833811771d58874cf08f8fd5c941fedf6ffce9747f70960078c65863110f08742f01ec440d3c78e6ce5fa772c6d66f851583b392f5c29ce4af8b53b13f53dc187e93d538e34c43512df534aaf1d0f36b89d7a081e60276e4dffdce937671bddf3d1f047c0d6cb75e36ad8bf311c1dfe3a7995116e47e4782922174889c8032c9a17a58a75eeb802cb3a8b8daf1c41c52363ee5053cfb1c0e69367d83b8cf93a9e4071cffe060490ef39b8f0a578c95fdb488eccee4a82aa872325828b820c48089f60ecd950b360a3329e1cd61c5087dd83361382f85d1193902f0a96e7ad58238a3039aea066a7e15b3c561ff5b865456ad5f0d16a3b1e3818db57b15aa8fef2aaab0824a1355c53d038ed08f7e41213cd48187a82d5eff12abcb9a0cd2ba8c68dd9bc67cf4056f6a767bd270acd68363123680d3761b8a53ed8788311d055d4cf9d238deb6019ace22829c6943328624f1ee9b7246ab473925f0693ec24750d2dd694afcc8aa8302cce6ae3b39f62a12482a0be5e255a918df2f0277cefb68f73b9f88b93a09d65b4b138cfb65bad430078489ae6b36175aa78d53aec65eb11ec964bea94336f289b9f3c829dc088afd3856deddf1504696531a7f5cd8094d9c7697d468910f6d680d838385592e8681b7340a5ed927766daa9f77631ff3f979f1dc98553437836262f08b1451ab6e20ff1b878f658f1b51f61ab54234abd06ac1ee25ace5052ed842b3a392cdf5135d9c8ed77a929beacc5e833b062b9eea82c9ee79fbd1d36d55f66d86d519744c06d145f697f63144caf03c3ff56ae31f72af8719b166edb9ebd6d3e7d5b597a65ea561e33af9a1ed954bd087c58e3f9d3c072681e884c38d0b93908694e609a1d66c2285accc0a1a6f175f54ada162888118d5c3a490ce88424d5357dab75b0972306b50b7f1fca8deaf07bda5b639d0fdf2a7bc166603adfe88e5d1716c85cc678bcd882746cb2e3d92a31b8b5b4501692109b614e321db2d28591954a8d19a06a020eb3c400992028c057b920c1bd9175b251be792d16a004df04b91ac798c51f2468349d6acaa8d4376cc6e0c8e8e360a0e2397bb49eb0cb8324ddbe50606da469056a077f61aeb771406dbee7e25a63e57de311ef08aa72f7df996e30198a21839cafa59a5b0c90ef774e30b25828e67dfa0ccd1807ad71b41c72cc2c2683d01d896f3ce35dae3e845f8424e57d8df9d9067c1370f84ce0595bdf190da741048b440e063acab210c44efd4a213afd07f45c5a5005d64352fad5556b65b496b103d83b15fab765b10ab8946ad44285056a26452c5b9d171a55574a6c2d0c2e2ba9a6e731a803ba88f3bc59dbd0e974ef1f2eaf133eb574c86c87bc893cce87fc308cdf33fa7ef2a3801fb7033049a920847849eb414d3b87e2bdcf5d75972941461927d61dc90dc40abab1a4c9b55aedb3edc27e3eeadc6421f220d3860d833304c45609a02e9d2573531ea15b46178c224b81892cb5ae85a27ed1107874dbdb3f9f9aaf0d7db85055abffa2205c4c58404810f47cc1f0e24d2e74e7359a47d51c4c054b102d46e0826f7cb246cb98255dcc27da2849f4961efbd45e7d233aad43678282cf5c070d24de302930431d89a34395e831b481259fb52e41f122a30a0d8d560cf493d6da9a5d2169f37c8617b9ddc431ab5efc4e9063b68fea08ae24dbac37ff93e156d8fd0a4087ceb7bc80e6948d9b146e136535e2998406032acc874e8116ceddefe1278c1412897a028ebfcc9e5a2a318c56eac8ed8c5cf20b8a0bbd6dfd45ed2f83964995022adbb9fee666807ff945cb119014ae8da9d4f914b49f1438acf5b8d88d788197fd067fc32fe766539347edd1be7a11a1ee07606de1e8357084bc452b5015c617ea3116246c5ff8d9a97f842d116a19e7416fd49bf70c88f106742f5e715e1bf4bf4206ed28be68202c778f1a499a58bbb3428c59d1fa01d287a527b41a1779a058d123f1f4879ea2333efb6f155db86c29b2b11778a8d005bcb8ff620a22e2718962da70a1f3389e134c09b981245027aa6e7af5331f6a91fb96df889ee163bf2821845dd993ef6ef4c2ad3bdc6c575a81c21d93c2d8812474a7cf768c4b7cd261829134ed6a25ca502d4f29adf84f5b04c4a372c8d1f5e03065624b67e03921ff58ab4a49cf95d17b0ea980cbdb9fdec7e825e14ebd9f4508fe32a6d31f6685726dca5e0067bfa035d8b4e9dd1b70fb9d5c49a9f7eea8393d069570592a31b1e2ae1cbdae462ef69b37b95b14b3d85ec7eef76862f8ad51b72e1b7d875643ca1f16626fde2602d58b6e4bfaf0f0c56fff2d4dbe2fa9e15eb0a78049a80af78affbfd03223e026cb0f5c21ffffb2fa1ef2eee059b4ee15e438558812643630cad852462b605ee07e2d667951af658107ab799d6dbf0ca5183bf92b60e8e13b2793ff1477f3e0e2b4f4574436deb80ecd30f0599844b494f92d57a2b2d1dbbe3d8e046c317e977d9bcab17cd50f613b2ebb886c9aac92b0294d85ccd5932119cb7552a31245d2e9a09343d7a5c1b882a859be9790c704e650599dc46fc934a7d823a1d2850486dd6abcf9f3d097ee4ec5caa92322819a9fe7f7ee54f87f2b50bc9bd94fece4a4bb46a0c1e2520bfd112b86f9fa114df54ea8451dc6721bba9845d0cba868661a6bdbd0394269368a79d16f49617f1e41d526801838cf70983037e2ebe5c245fc87babd2b09a6a359561e15e403eae20daf0bf1c9c157ce587310102bbaab2cd8adb5d0b0fd9cd7cafb0c7c8c8af59f4d77720bd64016c289faa6febb04117314571e2a6609dcfce17086a5306f431808f4ad1dc27b6d0f7c1783d13e5138822a748b3e5e8ba563ec19e65ea2c5e630e8b1cb18ffc1c8ec9c2a550efb91e0728ded8d0a690820a7d0861226e1e068138bae14512e0552fa49aabfccf29474c12a80137995851f8c613d65dabe4a709ebfe0dde86cb68af3bc89be760a33aff966216534be202584683b8d2cf87df4cb3dfb96a989ce00d9d3c18b3d5283ac87b20c17db03cd6968b46ab3d8556fe8ca6c66743369fd8918292c6f6c216ea5b2b3d9490c0a17feaeac127082e4cfec6e9c04964bacc8833381f65e0a80c16d93acf91fe4f3ca3576f1ce5afb691fb9f5828cfce94124c274e88759e7ba9c96e16c38c412619c929f82c840420d856f78e8f809312bee26ae6bc6a3b3c1f493bc4b06318233473d2cb38911580e7b511952f0abc7582f8d233d42b66c4bf740e6008ae29891e41801bbed43a2269501136669670f3087890973f96aeb3a38e573c0d002be90791c07f21f06a0b7115a251898a3d03f82e8de17cc91fd10fc75978d6b531082079354edb2ffc1a1b543f388c549a49f998c606f5796de1913207c39f5048ec75df124fa9b58d67778a5d87c23daeb65a38e600cfc47ed8e67635f27a724aedda207c59f52b94030f8bfbb6c60d46524de44ac3867978447e4cea9143ea7892e04cd84ce2ac459e3e7e156955528601405117cab3f70445ee9cd58ce64a2c21e9fe36070742b3e763fdf0b3571ac54d29edda85d6b41ab4693d2532ba1d9c8890ac4c63faf026dd10eb229fdd8355801f971d8b3934718fbda6dd544a0cad7dd1d20962048f0647e192b51fa0ad410aafef3039a864bd1cad6dd9bf48269b16871d8b51dc248bc477a7b93413877970d93c54487d2de781a5dcebbc74a7623aaa4d40c6dadc0a4343a587e2800900de09cd4c09994da9d787baf3662bc315fa4b493fa148986542c20f94255fd97180f1d2413ce00da18b7ab14509c485413fb0de121a2d9034a319fa85e9d391955c197af1bc1db9626b511f3c5a6084ed3d25070829efc280133f06cbc8169a172b2665a1e72ea5a769627b8fc4c4d42bb73f0058e0481cb625f612db1ed7bd0f44b3426b2a12a123dcb02bad35e982015a10787c39cce95714c3fdd7adcda3567b76395cbe59350472d2eb41cbe53b5c7cc65a41266c2ab84d4493649f7544ac660b8b3c923a9911738b4798417bd89e0b1088cf6781723fbd519b4939772358eafe7e79d2c626a6f482e255e259d6054f14fbe35d9be50eb9036ae00cf7518c4009dd369a5c68ba0c8008517721fca7a33e328f87d7754f85ad409c43d29d4feae41c1ad7b86eea9b17ae50e9dfb3b279baff55ab5fcc8ce108498e6efe959cbb4d985b6cd6df51c5cd9c48fa241daa9f385559a375b5839f4a84fa3acaa1257988097b3a7547a8c8c21d00c143526b519c39fd417ffc139b58b546b463102d0358670cb76176e33af7c21bb5709de54a84e6eca6b319f3f818d831374eee3f7a194722485fe611b58c8984e0821a78fb1e4b43522532e73649a89ba8ef556cb0cff9ce793eadc9b2886e99f56390b0e15f6aa50307a17eccae2aa425bba12dea1743179fe1d53b5f7cce02010ae7df64b8324d02d93c7f8badced36a885b0f1231e3bc4ecb36f9672e362eb5c9f3f8d34c13ce9cfac16ae71154f9d51c15968e7d188b278da74522ab81182740891a58421feb13489ee014b222aad62e8c7636cc0e694f64cc9d238e3c798074e611d58c0c6d2ebd66d2044cc404dae313c55120e0584d07a517fa898db564ae1a27a9a2bb282b62f8e5a402eed63813377b06d3bc1e1d9746aeac6f81c05259afdc862ed8d9dd12584eceeec9f86ca8ad954bc7d85d876bb125d97b77db726f29654a325c0c270c6c0c924673a2eb292738129940e7515adf67a594527f8d4e4a81f4a98e74b47d9a41a1709f35a3e0b6bbf42274dd9c78fc41e79c73ce39e7744775b59ef691481ba949522691a5ecbec10a34dcfe4027256dd19e2747b221a09fb9338b14cd62413ede72d61326b21750ef18fdb0b14208b72b13baee762b29ad554e6f6d739eae0e578adf0cebb2a7043ae99db472069554ba949ec72e416e1c2369e43792aeeb769f93d25ab5209246fe0e19cad0d6f0bc43d2c816a4aef3bc2f045b80a5d2bd26130a4a4aca295491a79495951514d32d812bdf8ad7915656e6cacaca8af78a0d065dfb6c071df7d0146b3b4857a0e1ca1a23b576b09fc6ccfd52520abadca0e390dc580c5d8d4dd6b0cfd7344dd3b427e2a2633b654f49c15189ec224495d1ef8d87109141a4dd6590052ec4f2fc2f75ee12ad2ee9f42698c1284b59198cca1094e79c937ea5470cc93994e8af86527ba9bc4327f3b70025e80c9598dd4cac68a2db7d4e5a8790604749d0b5f1161f933ad1eee4aaf9f3e9f7a0094c0796254c0530980a8ce44ef338d89cf1f76027580a16d3c23ab9f4092ae76b912c8f8c64f9b4c86173c5cdb899abfaff51a87b6730ae8894c33d19e29cc8b822cec8b3b2a1dc422e3615da8e5ca1cd5b71b339e39c1137736e5659dc6caea890cff8f7ffa350f752a1ecb32c331da245b4c948990c5159e6c1824b6179bcac1fc31d6f9e422e3a716b11578d77c75523156205551d5709f9b51962482ba867457e86fca807369be8c81bcffe1489bc71d677632657978bde71b42bcb67fc757265796555d78c915baed775c7cb9ddc5bd4f83cb10c0d4059cad0e093c72b3bc351267dfd9dd7213d62481ebb1c6a75b021f3c497470aee485974baec0a92765270c0cafe9227cf269e6419852c9734f1cadd6be1f6ec974c3c52ea8dbbc9c6ea25f4189828c9dc533124293967ab56bb89f6929bb01cf6dc266a220c87ebb9e8723ecd7e7dd2ea4f6763b32153a299bc9138b8a7a190ce168fd2459ba47b2597eb7e763fbb9fbf7d5784db3f37afe3b4eff9f65d3e8ce3e766ed367dfb9fbf6d24ec82439cc9dbd78f01f3bb6e17d277cfefb00b89f4a46e1209b7d831ebe4c144cc4675c0faf194adcbef5ef82ac54f8c1c947e112d32a59249a64472b669b5458ded76a94f7a2564d8d0a53ef74ac8d060a0e68c10f6393cc4621e520605b47065d8c031dc00f45fd8e0162ee26441c650aa83aef11dee8c7691c31d5159863328fde9429bd2396bb7c85d310f2dcafd31aea2d8c91d5134d4c1a5f8e88e3fa25c7a467f639b4cfd5129cf92ceea2d35fa34533c12a92ee8648f814848c60496bdef225c29a529cb962c799ce0d60f9db8e367cd057401310e317ff76f2dc61d8a36b4a6948bdcd39f4f7aedbbd7fee6883612f33893b5f73a97eefde577a3df13c5dc09e9dce170870d9d07131b8675b201dd65b872890f8632f79fbb928ce9a8b5d688dcdfb5e7df5b3ff7dbd6edd3da90a3f36bed8d90379eadfde6e9807ddb46b2ed81c96194785842f3b047112e5a4c848bf6253579a76aff851d2dc93aaef199dbb8ef8c903733db23de7bb6befd1a3b571ee6b08d69d12d6d0f46a076f2e879f803e555ca6af2938b50c8253d3b59be4c21cafe5256d985d39b1165128984c7d1c70f499451fe0333f7937eb41fe03ca26cc2328e70671e49ffa4f0d399ab957795154cc218c854b1f6742f9672e6d3c9fe34b470c74f28fbdfff641f934fe81bf2de9f24c19f1fe94961e949d84763971ba4c7426a26816f43f0b9f0fbfe6a90ee57042135fb00b117a61ce5627b276fe6cdbc9992eb117d4426af76f802138450b204030d84b019e529af8b73ecec1d0111c5ad3fd985d112ee58f3abfecc55cbb0f7a2505f7ff2ac44b3a2fc505cff5cb4e04a8f89e23f0a35a7ad719b8dcb1bb60dabb5d6fada8cea1b7e32130840726df561c21180e48eeefa256e45527d5cf4c7b1c195feef3307ca23cd298af218c47ff82b4b5c91b8d87596bbfa307147af3ed9a5cbd3747c3bf9598c63835b7d1e8a5b7d72bf8fab6e58b75f88c855f3db83624a7cc855324fb55ed58f82b9d84142b89fbbfff6a3fa65bfed779884d59fed085fb35897b5a3c787444c99a5f431888bc05504a60623b8a1c7888c33b49610853cb8828cec00094f178c80842f2c39430b82b0c114f8d00235fc98a14886ff8ee93fc4f4aff9d1c1cd8ae26ef6fd5bb84afb9aec36d9ed913cca5877c227eefdaf8ba9001401093c393bc8c10f8e20633e4aae9468a9a10a4e28099a65010a19f30b629803cf13e230832dbc41c6dcc012acf0842a40f1041d18c99853ab02fd1e56964b72c0b2c972090e94643be7f6d6de8b42fd8f36a7a0c013d75f9e49c97525d8831cc78332fd1440a0e16e3fa632c77115c7f6f56b6c330cc721d92b4989ec6110cf244c8076617f76cac506627647daf9f4a969d2521ca4395d08f7c78b3c86e0c7179b503d4307f47221e969ed18913a493cf961d4a38910321b4a6a62a619bc87e27af7bbab1b53e089eb3c99024fdc3eb221c1c83fa3eb24a1ae793457ddfb531dca3357a577ba033a12d4df5f1ffd2479a414a81ab928c569936352f768c0ee588df2cc74d239e9a473d249abffcced27fb7376479e6f8db41810b9c1c90b1bcc3768e10926327822094970620b6d887d410e3f5b3841ac0c3e5ecc0d4f546c10b6692d10f22865ae862e04f9000f2788e20a324619fb0196063324294204237b90314a21955c8283a016592ec1014fbe592ec181ce5cbd0c3b79a94c62488e4e4a3824e5fd59fe140e5979220390e1d87bdc00f4732ece72c91245b96baf09b96a18fd96825c750e7dd51377f4d62a0977a0fa2c578d35059744156e7dfba33c1a2233fd70d41e64effb6340ed4176b951bf844d56d3de865a1739414b95e5129611f89bb5f60a4b28a1d4e6b4ec637c98bcd75aab910e0985bc617781390c77ec96aba8e7e31a92f2fea7d0b113de3b9299495dc5638d9442c9f4d2734c39b654ba3e43ff7aeb03df87b8efe3a8f083e4050b8ab94a05053321d90772de932935cad606d449a6f40d16c7ccdcd79899fb9cbb22cb25284092e5b723472583eb7f7a1429dcd15b6df4d4e2d1de0d8f62b6f314fe9ca9ef1f06b916d6700d494db815327d14ef49f2ab8f033b419123f16eb950af35258489620b30194b50d093e59213eca8c872c9099ee4ce934144320f9ab39523b6f0c9630f8955d3b42ee2aa6a7af0755c754bcf810f7e273bf786e45a937091fb1a06716a7a2e347dc9e42e130ee22235616fddd07dc870b54f661ff63922a3f511c4b3c50162e92af07d80780b7dd4b7b664bf3e58025f03c324b4d7baf6b8ce78ec70a4da27e122fd9e0444f97bee0b5d6a6c5ca467b8401801b94ac294e40c65ea2f16923cc68c1ecb7474a14a7fd32acc55a3e7b4849cc83c6b0317fa5e0ffd208fcdc407798cc92fbcd65a9318525f669a5342223859780226c309cf0b3bd64a5c14ea2117e9b7ec37a3fbfebc9f1d731126038adbd29e563b3a50a63dc8a327c9f4e93743937888430e5ae024094974f220a35e01468625a420843c30510719f5a5ac6f65fdfacda824d7438e2169e8a7842ec0100596490b41cce18ede8a80ff1097fa2e1150f9f92a7848b7e047c80532883819c670f4848c949f7808114d07748043924d08583883908c2144549e485f810dad1e192a2e11403dcba35e9c2023e559f090153ce4851764109151442143053ba13d9101c848c14e6c36a6246c2117e9bbd870b9216179c3395cc431d313b47087102ede34dcd15b296157072358105755ec320411f4fd45df5bf4dd457f0ac1e2862858b555f216b39ee195646b2f352bb51ee2d663ae9a48ced057c196d62c87a4a0833c67965158420e39c63cf22b423967b8e764fcdbd49b52505ec3a398b54f85439c48bd87435a86bb2481a5f8fa1d94c445134b0beadd88abc68eb184d74597164cc3730b0b4b511fd11ca1bc92852fbc329d793565d06f41b184153882ce8f90cc553606997e0fd16f26aeaa2c60616161a1df4d5c35339d364f5413a5087be6220577f36ab4aecca727f255bb6dc1a3bd28cc827b481a190838c1f5ef9a68aa9c5ec2f0e5e780f0c396d1756118925e452865f811151fc3c3f0e5bbf6c2f0e5e53784cb50216faa5c913714cbf662ae7a457b15ed59b4b7dab842259c21357514943e8a5220f493a0dfc3880f9b28ecd96c2317e997c276d247f455845f285d24d15f80933bc4df89facec3df0425487d0a5a460abbd83b67681b1dd16f22fa3dbe1945b84839178e23f255a9d533996ba6ef4558e30b23991edd40278f9e9369f69d4cb94db3ad4cbf4711464849c459d3dd88acb66955c6f02dcbaf628a72152e7432c6ebbabb5d45e563781bf155c3e60cddbccf979038cd23e4d3a362bd0e1489affeeb53188d01d120aa84be6812152fcf85d6c597b7e1aada71d4455d14c98b8b109aed1f51caf663b858df3e878574b63888fb435cc5ea1c20365c356a6fc3c5ea43baa8020976001f6e0ca7ae17ee2757eaf299fa4f85bbcdf7d769f9fa2aa83a36ab73586890de017cb8a384f1f8b011a47310d807e98374a63d9467aee6d19ca93cb976cdf58354cdfd437ff94c45f9d1855aa7739a75447a394a118e9d530071b17ebfcbaf3ccb0309e2f23525251552242ed6ef90feb85881d4b7243c5aceba60ea72b1be346aa9df8d2089fae9387dbff6e138017195cad7af9f84bcf9709cbe2d285b50214bb812aa8492ba78514253387aa510892d8f5268c7ac5fedf088ca31a6addeb87a5bed45eae23f1cc16548dd0332572cafbdf772ae565a58c295909a2e51cad34d7606992c6b4e645914443d3e594bf9254178923fcf3c8adc6e20413af97dbf85fd5f5863fba6b175ed8f31b7900209d2519cb496031eb2f6293573467b7bc2a3bd1f8afbb6efa6a679fb91f562f2ac96ba28b9dfbedbda16a7949494142ca4f3098f9b8fedc18d166ddbf4fb8d367d6f13e18b71271279529c57d3724d4d1e7fc46497233a6f7f442937fefb9f8eef1b0be9bc813fe7ce6b6f042ea2e338d61d45506bf98cf6efcd33c31ddc9a6f8e28a79f68df45edc491f48e0fd311a55d4db3e1605e246b529c3f2483cd55504cc9f67d58621b17493c96b84b82a033d35e5b02042559fbeed182c0cada7713adc89b5bcdda6bdf8c0dd7b83831115de974d94f73e391489e299a2c791da9311128e1d819e5fb9ba1674da6974b7ee0248fcd335a263d3eda1bc940340de5b53f1d51f95218a4f3878b7051d31ec87cede5fc1e73a582b7f9da0eeda7e42b7cd07d27bbf6ee881adf4acf5dee3e891b72859a33dd6f410cc3aaebac9193dc3d91dbd6e10f9a645994e5121f1ce5ae3f3bd2d166467b957824d27d0cef5e5ad369890f9a8c3206a3fbee6d3c6a769ec5e3495abc020d7744e5ee5ddab6216f66ee3e87abe6775dca551ba68fdabefbee654c877d34cb5bcb430f80728a2c97f4802777ed59d97f757cee8bfad8a5b425d7b88b08434092b38ca9d19266f45c9a4101211725150212c455a4979f84abb897364f8dc4719cb5d6da1447a4f92d37dc444445dda4674d248b7e0009e242158a99e20070b8fef2e42afa5ae770ae39330aaebf3ba92391482412a9e5aa518903c0e18edeea83a4997f8037dc71ea4c23ae1a671f745c358bcc9dd9071f17e777cb45eaa2f45691b9e362b7b5d65aeb27fa1b9e3a2ece0fd770adca14e6388db46691b983a70e0c1da6bfa42c4e494d8f216a3e8924802461e4e4a8c64816d5d43ca9f99a27df32aa19d239ac9a1e3d86e841448f1613598d0d1b316cb008c2466d1e098bd50821440e21f00e21baa7368f546203a37ef3d4c0806103e3050c9bfff1a3881f4d664545cdd3861538b89dff6865ea63c417c70429d21fbd5ceab2247de7bd6691d821681863ac751ed6ec2f572111c4669847a27e1054c6a18f8cebc5c7e522adaf61f061b00341d2f8481afa35b49206c4a0f62e9341b9e832366204b96ab2780f678e091d49fd1d97185a10240618c0a4e679487395c1ee9a33d3eb0f4f5ffef03f7ca78532dfa17831277a333318f3e32915854c7fec1cc685e10943399565189c20cb4ccc603dc75931a22cc3a007a35c44024b5c29869ea13cf690cc3dd472925b9a09578aa1a7495ef93907a39610e6c092464ea84d70c9b47c5ab0964f0ff6a8bcb159ca9a25642a67a847f378f2578c5784abb8ed31059eb8b2491e65510c1e7be4986f20200d06c903f50fd0f7e82103be8ccc0f2113f640c18579991046ae7c3994c8302f613e1a54e6141478e2822ff31e8e5a9fc5c33cfd6e800f8347197c447cf0eda703e6eb3b4ce6598432bf7d35583ccc7b8c850c36c245988aa9d803bb73e6886db58c7091d22c5dc4784ce53963c220b5082386c832a026e6096391240f447910923591879875654a07591e7b8809ab6518e82094bba524bf64b98407b0dcfde051b78919b798cf506ff98c4a8391d98274417f94093d08a6e51976b9b39e0494003e88b5eadba743fb0a6a433471ebcfb094e547a3cb18089953280990e1e2c00f03834710bb8038e6357c447c1d300f82d893b8f8d5d01e7c65fa2f17294c888d90c018eee83023605fc5e701125aa5bf5c05e2243f7ec03c0c0ccc170113fec8b95a7d4dabdf99509e028df8c92294097f8844b8d83f80fc7091f6dc964909c1b05d2e18ade57af171d9b041f3d8609e4f6a550fb5487fc6d838c1d53e0817eb871a8e09a5a449f94e0c73c477d921621400115f0c4539a506c2bc18be9833476ae60c7d09c4e0ca253dc8c960d1d38709730a18e690c12e372616d2d947ca8f413a7b8ff2319cc5ebe9014110c45f0d9b651e268c791408be05df73953f28f3a0f820f82218d6a45ac0608cb5269209bbc9cc67e80f9173476fb1b41841b078ed3fcd7358da9caff22c52e128aeacc8845b96312ee658a9913652fcc41acc6b9aa6691d4c18f3dc57c3660d060c175ffb995465e2c23c8bfa30301846cb9a49d8443e435f0b67c22ef219fa11a0c21d3dc6023b30dcf1300fa3b90eb812e58df625999732342d138edf0c518f4316e168d3f2b3e527be1e8b0af330df3b3b3a3b5f640716f4dd007f54424a9af975ac0f13037e8c09133a8bfb6a80ef395f0d0dcb60ff21741f97ebd64ffde82c1d31ae44967997b94a46e6e957637e0d8275264f33d2b382a727a604fc6ad80c43c36698efef0806b8eb6bcc8079f9dd702430a54f07652d91b5efaed720a61f0e2ab104cc70478fc594a0789d93a30d7191e6d457c1c2ce9aa60f87cc836ffa66d4672113ba8f8ef91a1249431fc67e38c0d73c49531f0c69c51218c3fd6472ba156f0927c84c90fe6a1c67491730a123a9b9043e8863429ae747c3bd9890c583a1fbb80b89fbb40bfa31a1e715dcad40c34582ceefbcd2e91474b99159e02333efadb99ac1301f03be4c7844fc191ed1791962257d0c906d7a178970f186f6e083786c790dd7572293be19130f51eb4fd237033cf5ce8e48775070e77f11dc3b3021cac51af313e6e7f6329f82400aee7c3cc3633e462694a78f317138a672057f3e8885ccece3f435c09f20a65f43238470b1459aebc447665eac33d85b3e433f068f16068f16c4d467e6e370f468a47ea686e0c11d7be87e188ef4c3b175441561512a1c7f7819fcfb2e433395a728295a300adba05856b00a86e162d3594f780cf2e3357d0a46c14188a6b0c50d2518dad166f76e74b846025e28124208ef948a6951dfc6575246ad1f84bc91b9e2f1470e7f082c71b7af51c30d6b9a6c53ca452532a5458c70953b518cc750438dcbd572b57c5c3a3a5f5936ae4b91e8ba1b03d1873ba6b2c44500d1872b6306b76968e4f6924ec6f8101759f3abe632a43bb214224b1a76e700f1e48ead53448c2c62c11da5d117d349dcf9849231512264f3c23d9cc19d926229db48aed1f6d0c9d6a6553add7b84dce97b778109f7a6f2d01dc5ec304451de80b028a47cdd11c5049bc72e07993766fb9ce16110a7d77397a3123eb03d5a9a02eb51eb514a6b8e6dd3a407ce217c620b9fe14e27a5543b5d8eb35bd769b5a3d3bbee64690e284ba9cf0a8276dab272a0bbdbbbbbbbbbdbe77531653d3a9a20f77b1e89cc4eeeeeeeee281c6ce04864c50395427917858bf0e6b49ea76977dbac7ccea6eb3acff36e8720282d582a95ee35994c28282829295ecae974f25454e4af7c3366eeee45a8b0b0b09c585258585858505858583a120b6737161616adb2d0c9e2cdc23ab927cfbbf484aa9ae65dbb6d9bb51ce75d4b22759ee781e08c7b4b26930934994c2653a5d34d2d5bb4229d5170e77707e964cb764933033a6bf5da36486793ba2e9ee437a38e4472ffcc305c94df3f586c1113d322e6e469dba6cdd86a666cd76e5aa524d2f4e660d07573cea641d4e176f5da9588ae45e86ef7393b8f525aaba6ada8c3f5ae95dca6d9d9034befc7a466f55a6b57c981a3099aa83b5ad350a993a4d9acb51c27659344da795ef87da0e7b97b388afd2051ee076592a6ff9504a8797ae787a491365ac4b87b4e6e4cfb5e6a4241a128282828d35b854b428c8b73a25c94941a41c69031ac6c92e5105d7e2169e4b6699572727a732419fd1c91eee9844e62eb627bd2c539a9d3a6546aae397dce3967fbd73967b3c17a744e592d60dbbdbb76aa33ca6ab65a4badb5d3db5a2bafa6d1d734ad9b524dd3344daba73cabad3eb031997e4f4aa58f31fdd55dfb66d06ddbe6b6798a6aa1dd7d4eebd116b9866751d2c89752a31b0d43b48bf9c2bf81e40df8fecd235774b6fab15baa1fdb6500f7dec6896817725577e6ccfc01fc289f10a000353fca38e0f470928b1fe54c003f4a229adf21678b1b333fca2000fc0823003fda64ff16725589660e1bf2a67bfae28f3f4894cc6644bb88b192cef76f86f7cf5c75ad0d600df44f0690f4c0a36300cb2e60013ca26c1aa75d44e0d1493b156051803581178dd33e4360d75c713309b822e082802bcf961030f2e4600f10e2811d8047548cc6e99e1d78f4a3b9e27874e0d136008f37cf6740108dd33c39f0e8d91ae1682da075a395e7db689c366223169b2b1bab11a3119bd138bd13041ea7d15cd99602a6918c699471e374911878f4bc1dcd19207812c083003ca2e60bd138add32ee6c3c0a3e74d68ce344ee7b48bd95c6d2e221aa759ed623eec067600d80b995de1d1aaf0780d806df0c6ead13843dac57c4d5644e324d12ee6176087003b03d8a9c12ef088ba02c0e3a579b5c0a3e74a3457dacf9c994148afc601d22ee607000300cf602211b3c032b8eb5a481aa71275ad4a84240cc3300c430f5d3e1d380c631e7f0c0ec30fc35008879d432a44872a11cd022da24d2813aa857a869818e972c1fcffff7f18861f869fe2d311fec37cf830e1ffff3f1298b0f323f96922067b0d210cdb3326edf89076483ba41d1f152f2f2f2f2f2f2fffffff2f2d9f8e7f7909ff3f7c3c767ec12f2f2f2f212d4299c8fd3eb487aae07fd69acd66ad15a9542a954aa55e5e5efee52585fa74bca452ff2fff2fa9d4a752a926a926b3288e8cd0f0f242b422f4ac22f4dc71b01e180cd693a2a5a5a5a5a5a525954a7d2ad5c2f2e948b5b4bc7cea5f5278ecdc825b5a5a6029c2ce2de10c9a4d6032a4643e2195c24972f3f0f0b8a05028140a856a69696941ad7c3a5a50a8d4b77caa058f9d511885427546cd9ed99a3798aff9335d33072d2d9327774e6164c41a59236b6464454545454545450585423d0aa5a2f2e940a9a8b43cea5b5078ecac825554548e56bc0e46669199e37740a1b093dcb19d582cb6c3723a9d4ea7d3494545e555544ea74f87cae9847a9547a99c4e7f3a9d8658c2cea721d9168c66445d50511162093dafb48ad8966dd956111493c96432994ca7d3e94f27d34b1d279349e54faf62c22693e9c7143a903ba1c4833c8917e1747224473a4747473a29f7de7bef35994c6f325d944f87e9ded39bfe64c263e78befbdf97a11dff115b8abe53cde02932925f48c2294232424d439e0f77ddff77df7debff7337d3aeef799febee9e2effb669dbfb08b3a0d9ed34e7a0df76eae66b95cae92e7799ee779dff7792f757c9e77fffbfb79de7b9e17e47550aca14024136a297cb052e819640dd9581b6b633d21711cc7711ce7799ec7953e1d1ec77deffde7e1b1398ef3691de4fe240dd4489a079e274b4226931d75d65a6bade5388eb3e0a783b396b3f64967fb040f3cbdd33a7ae03cff04f9f9f9e9344a29a5945a6bdf5afa5287a5947bfb1ca59da96422bde0a4a809185a67364ed742dd3be7566badb5564ae9535abd4f07add576ad36d5e6c50072ff147227c10af03592a63f6ba1e7cec58b913ed86a603189d3b544b7edee160dfefee9a8d87aaeee442426e4f96110ae7f2b3be9d5ea9afb638448b1bcf9204f1e32b8a398fb51e26de5d9b5e6ccac75b32f2e0c157bd26bfe585f3e3371a4d85f4320a4d8dfb5e64a0172a67fbe9cdf393176ae3cbdfe16a044a6decf4306a4579edfe58a47225e06ba7390a4c8919e5ceaae8bd3ce295d1c6b728ddbe9ef50e8648c0a495d084f72bfb59d83db65e8af12a799b40b2a6feaf7ffd075a161b31c836cd95f7e3a1a5bd1dfb6166e217d263657fca10feefcfa9452ea57ba47512c1af51af74a6bad4f9b682b8347942be93fb0f4f245d9ad02f028a98487e7859af5e76bced439d42e2ace94b58bb0e6f99aabebc158f34e0bcbef79b46a9be5489df781a56b42a130951516544b0a97d48b8a151f62af321e654dd73cd69c91f1e64bd638de8fb5f7ca2ce5f15c4574483b4c4817de4fcb5341aeeffd6cb24de62aef572d44ef03107a3e5ecb63f94c7dc730974522a34025165f2ac97ca993c964b252cc97baa3a312cc97bad7ebf52ae12f754343a5f04b1d4fa9542afd973a20a0d28a2f918e8e8e8e4a2abed41929bd7c892493c964a5d497484e9c945cbe447abd5eaf528a2f9186864a2d5f22f1944aa512ea4b2420a012cb97b8a3a3a3a3d2ca9748464a25952f7132994c563a7d8973e2a494f225eef57abd4a285fe286da451d2a99bec4f1f094784aa55289032a59994c267352b24e4af74b0fc455dc97fe87bce95eaf57e93567ea50c90e95784a2f9da764794adf97e697804a47a5a3d251a9f4240b542a6d47a59235522a3d28f3cd28b1d8643240b8a518d9914c260b6140dcbd86ba57f7ea5e43b9fe87df773c1d50c7d3f1743c1d50aebf6285a7e2a833727474d419c9f555bc74299913994cf6e2424a417a91864aafd76b28d74fb57028120f09a844e221917840120f50aeefc26257b8239291127744e28e8e484672fd142adb8993714e4a9c8cc4c9644e72fd96140d857b95b817f7e25edc50ae8f3201e1d63c6e4a381e0e88e3e178381e0e282c7da34a25098b21732293c99ce4fab70bbbe758baaec3a38dcd6be8f57a0d79fe56aae5b14096c7f2581e0b94eb4f15fa83470ab73c5f9bac5dd40f3d97e7e3e9b8f8851e6caebc229bac47285723b14d0cb9fe73e18ef6c81ed927be02c03ff5f1d5269b33f5657ea448328b1f29906aa44932f8b4e52af1c1a73a90389b93981f290f32f8b447dec03cf894e5abcde5a23a2ebae37ae2aac783c4d962313d1cc91bccc4579b4e9322273257855e90389b8f0f1886e4cd8a077fbe7ca5cd6613368bcd8432f813c855a9077f1a41e26c395bce3c42067ffec81b150ffe34e22b2d169b3db1e9134392c197077fba40e2684d9a4c1864f0671179e362e42bcde53a724d966bea14b90ac50689a30505b961266f5228f195a633c4a449065ba62071341f9f2a04c91b1697afea6cf6337b81a707df7b2071b49c7651c1f796bc59f9558dc5bc48cc8d802a7b9038b549933e64f0fb89bc4979b0ba5c33971188120689538382c690c16f99bc313d587582749480dfaf4682c4a93eeda2fa282183df40f2e63e4867b36ecd5c20e96790c1ef18489c9a13c457f40908be07240e6d527a10fc1ff266ce2e11f83b82b090c1bf21716850bba82f83608c3619fc165e1f04df86bcb10fbee8aaedc71f32f81795c1ffc29965240ef5899137b4b6c4a139eda23e083ecb370384e54db639f9018f281658268363f0e81926f4b9a5df5cb1cdf59b6b73a56030dc74369f4de7379d4d67f3c9f551567ca9d996334bcd66f54d2abc975893582a166b92eb5f970ea5b98234174a7369aea05cbf9482d4a2e9683e9a0e4ad3d174349f5c1f64e14e332d67769a7db36fc5aac49a80b153ec8b35c9f5bd940da5ba6a90d7cad5e57205e5fa9d49f3aa8e0feac35507c43eb93ee956129dd51c3c9bd59c994b3e97e6715342634d62b158933cbfb9396d72b57105b95cae20ffcece39451d1f1d9f5cdf86f4378eb58d29007c376672f7f604008f146ad943d469e627cf5c79b0f99aabd41c6a1c13eaf2b4b8b5fed087afa4f9c1f526935c9fc56275e18b7b72d1f1c4b0c984683671954f6b643bda8eac9196ad8362be02c03da1bcb0895cacdf22ec263e536bcce6ca1e4d9ad338dd9346d9d93dc995e6741ed2dfc29497e362f5747ce649e3784bb45047f6285714489afa63c7875c9f843d96a4a91ffee0d21fbd1f98079b2b29a507931eccfbf97925ae1aef36b409b9ead64f7d4c17006f4a517b0f37296ad283757dc935256bde57e3b3d7169fd7349ed71e80d0c66b5cbc3c5e70c723336fdf3e8df79434159c4f3317f61000c2968d2dec4c88f299fa5bf8614c28ba5877e64a4a8f3557279fa9d363b172c557453da2183f620794c8bb0f897c7fe80455a29b524a7f760841d4146896a98bbaea03a9b5ba0a08e945b3df9487a7c7c54a0a6bf47374a393f2d09e23e4caaaa0dd34a448e68afef84cfdfa2a70b883eb432ed6f797dfe1ab96332aa48a1fe513152ae8a3fc112e5f1f88bcf15ca54b75a92e3ff60a72ad36990b478bc48d30532cbaa8e253beeb9023611a3d76bb846367152abe9b9ed7ee4d504a1a15dfe1072448ebbebcf62af0cbcf2ea59aae8b39b9a27c0c3ff29f1276a63a45de85aa90900be197b04fdfa7efa76d39520a209ad696d32875cd99fa5de3a2af39529790cb72d465311c2ef75d83126d4b176d6ee0f2f49b91fa1d8da37d7d1ef2c67efd0748d5cbdf5cdae44c7fe95fc229c576d1cf85fd61d8ff61ee6cb54edbec8a70c5c4dcd7efec8ba661219d5ff0d8cff9e0b422ade33eee32511d0debe4fa2b420f430ff299faddd6c3b57878a88bba5ca5e2eb073fb175717b151f0e7f100be95cc263e9b57ff974f893b01095b7bdeabb319329d033b9fea16663b674f18560a55d577c3828ee22dc469da781b229346313f6337fb4d0f394cc9ff9337fe68fe69140151f0ecd7a0f86f5bb50c98b9a21eb803ddceebf1a1a26bd109ae71f51eab4fffc2d8bc5aad1fe3f1d1fd6fc63b8d8da7fed6e2b16e456bbe0150dee9ee7799ee7799ee7799ee73df8f2cdf07a667117b5118bd52caf599fe7f2e1f8de6221250c7eb7796058dfd658e9ef77e1112dc466fa5f28e466fa5d15da4276f974746f5d65537c38bab79fa43eba681a41bad8be14ce23489aed5176a2ec8fdd5b9265e97c02cd9ff972557d073cb99476504f2148de78dfd26232751f94b7f7975e28254df7d931f5e9207d37bcefbeeb8f860fcfc33ec00e778f04a545281047756a288fabb3f1ba060a7d0eb9b84989a98d67c32d77387fa611e6131368bea6d01c9a32176dccd54c329564b9fdbb9d73fe37895cb256de9e2796e78b39f37c2b71649eefc92b6d523e1dd34efbde9c9ec6fdd4a487adcadbc227b697fe7362d3a7837bd771d58ebc9179fbfbe1e030e56c18e6e0ce1f49b37d0cafb1c69179ab4a5c25e4dd8b4dd5c5a1c5cba05e62f2ab5cd598ac58909b488777030a0d770cb50b2d67cfd0081690ab9644c89b6f693199b6e75c84d0ccfd11a5cc7df7d6c5ed3d2ca4b353ea9da6aca6ab9092581daa4e5e14e5edc71a9149de9e524ae94869535adf564a1db0876b9f49fed94cde68797b5ae44774fe9edbb88ddba8930dd3d9f54155243ed2594de275d5c8fb0e0be9fce1d17ef71d8cd785f5493daa4ec26a548524cdf6a4b06e41d26cff85950bed62a8ca4221365b8c9a2bad32f199ed75eccee5d15a9a2ba636093f1a9e7fee96b7a72f5a44decc3c738d519d76b1bdbfc4e38f98ee85d0ecfd11a5ecbdcd1d0c57f5dbb8d8305c6c2154acc6575487b262502f5725fb8c226f3f7ed9bfcad58c42de68a48fd4e0931efc72b487a34dee9f4d369a837a92376ee3b6a73aaff3914a3dfb707c4fc2423a8378ec5c8acd95a43a9bd7cd4709b7d11763e3c70e90ac9fb4827c56e467681ed11e1bf64c87f7160be9dcbdf6d190f16ca8652f9ce1cf8535569570423efea3eeb53f3b3c56a3bcfdf6de87c3e22ec2423a7318a62a9134dbd3b0c68c607d74ffbddd3cdc452e6e6f4307f0e176d16492b73f62faeddbc81380f2db83219534ee2858ac81c16242422c3c998f86631fdef6413a77d879dc08cdee62ffc348d03cce1f178b7188d9bec5f3c7c5eda9cff87bf67acf6a6037867a55cd5d889aab1af399edadbd1795371e2fb8d255e2f624fbe1d82cbe2e6e6fe74ac66c2407c112dff7fd7c24d9bf8750c4dd876ec7e27432dd49c267a8d7d6656e69ca550897e52a12dd9e764ffd08f5474773c7a2f28f1ffd8ebdc745cfa7bca9b37a181830ffabf5fdc6fc3aebe9ba68e5ca8564f7a2a88ffe7fcf8ddda793e34c3299603b5cff209db9b9ba4f7ff6b86aa4b05c7566eb8873e22aef0965c99befe9d325e40d587a107c2f1c4b78ec397391923e1d1c37679cbbd12c9a3b467c66b63387977c7ae76b26f11917eaa6cf6691ab38cc4d2357f9f45a4c1289ce63f3705f631eb9ef4e8e5c552f1612c274b83e8274d6c974a439993aa00f77a4392b3b676a70e1ca2547906426de90cc9f38b976e8bb3193bb0e91a09dc4c598c9c445faf32569e8e3e1fa981fa4777cf0b8aa47dee840de78ffbdf7e1b1698e8bf4caccf5535ac445faa1eb8e5387e6bc725ce532ba900e0e31cb6811573199443e043943ff089609570a282c0cf53fc9d48ba833f11e57b568897b9ab9f934066b1e4943fb067286fe0a53f3b88e5cc8453ae44ebe08d5e43239ca4f5ca4cf23e7ce24ae1ae7bf2614f2867b3adf8f28d5cef6d3e1df3231f464ffeee770f8b7cc73fe483d7499dd28e696b43e711509b770a1b99a2f9fa16fedbd2894a5dcfb57ae7ffe38e74b0c293eb948b79b47148ab218e03f718e1c3e5c6eccaf3fbf7e8e203aa89bee78fe5074ed54a600f5e39eb4b759b3bffd95379eb5b731c9550ced85d6a38645d4a84f2bcdb4471131b4e642899d524a299db9524cbf19dc689329b6a13d35a971586a94be5c228422799433ed8da8af594b7f72dc6bfe719ca5f43723bbd33ab9c8fc1df3859892499e285d7b42bfa3e553a0564e261759caa46a6c6824ce0ee9a266ce4c15282852b2725c9ce0cbb03e58ebd7effbedfb18b359aefa7228a5c01317e5bf074114ec22318e2fac99ab173cda141eaf0bb65d7b7486f7d5fbe9c970f4aaf459bb863c50706551f6bcef286d2a9dd6182e63d2ca3759cac6d0a4450b24e44b49534797faf3a57f333eec52a91cbfe75e8692c7ce9d2ef2e74b17f92417f962aeffb9488c43cc62a67906a15986426c2ebd7f332a6ee133f353e0d1b6dcbb8247940afe3c49285f3fec82827188b98e5248aca188efcf7b44e87de7525ffbfba5d0a562f9487896d8bd528884e72388b072a9f3f79d7c19825f383a2b7f5fc3318686f61e11560e62737d8b7fc478da5ffa319c0b474a440b2d1c29f59694a6fab342a5dfc9b00628bb714df64c3f1a1f78917d780fbeb091fde5937e7e7d29bf4b4131ddd2cf505aecbd87dea78428e17873f7a67044e5ff217718897e10a7fec78b3c9377b838843b4a598eab841862d6b7f65e14aa75c420d6704717d2ff94550c77b4a82d6b260deba0aaa4ce5eb254b1f9e46a0892273fe562b5f1b912c7f02872fb35c34ed22f6bc89ff2e7cf2f871234947825f1d9b9f88f2249dc11763e7d1def8f289db93a3d0b0ab572afec6064fb331c6db27db796ba686fd5bca536b5e9d9d34da1a8286352d65a6bedccd27ad6245f2e69c2278f52a68da78ca504e2a2cf262ad5a0d25a6bad94d25abfd65a6badb4d64a6bfd2bdc5a6badb5d6357432c65db0215caf4c9f88f9b93f7b38f6f4b009237914f392268a64fa54a4dfc2a6254d8fa4dc28b953887ed322a5f3fb2a5c3a8af95bc4d4b88abe98c355fef477f40425d14cc347a934a24653069df458793efe30fcff7f79f954ea5b5a1e857a15953f9dde64fa7bfffbdef39ee3dedaa7f46bad5c1b268928e370b37631bf5dce59e39076dac544ed70b3ee4a2972a65d72ffce97c3da2c2549069b24ed64df5e92761a47762599224596499ac28a96cd8e9e2b279360ae1abb56d772955c72c487f49a4f4a32494179ce4c3ffa3c6470475a44752057fd23c48f1408993a4191e0801f6992100f72d5b21d3fd225325d018d0103362fc895b372fc38c990671ae61b6efc389dbc1841aedc65e3c709459e50985698f1e314fa950b05f1e3a4419e3a9840c83f4e242d6c902b3f8af1a3cb213b1ee61208484d41ae660bc68f9e85ec5e70321ce0476fa2f23e632f7ef426b21bc1a130006a0f72358d6c7e742672017e7417380d06f0a3f79856b4e6c78e22bb0b1700cd49f65067a1a7d0e2c76e42f66f24c8fcd83fddc4d83d107fec1b7cef313f76916662947bc8ee81951fe5cc2585fbdfe0bc67790418203b8dd692dd94dd5fc60af1001e5d6b878e063000cb72b0483b366ad070cd70d97b51a82c14c38f389e23183837ad03b45eac543103c46c0a4080014ca31a1702e0a1e1b1f6a25033306bef45b966313b1846c58a1478bc28173ca2565e2b50287844a580241d4d67451e49afaed53da17b753f9d2bb6c915a8ab519f1c869ebb17d24e115ca4168987b27e4652018975641486789c4c727b7e093d772d3033c88462af14c7c32981fbe15c5cebe5058fd3486ecf2da1e74ec5888301a7c3b18e8c503666d76089accc0ab5b4e0d195e4ce2aa1e7ce645b4f78fdb85ca7236b03bb63752c4b45058f9e730a3d9b42cfdd27148719918ce86eaead0a1b6c7b6d3f26131e3bc90d3d7f1b6be3c1c6b3ed6c3acd935b7607a319d1177ae642cf5dfdd1420cf6e2a4506ed24bd2ccd774e68a04859c994f921dd942cb0a3c794221cff9e191eb3fb6a0d1d447aefa67033f52241af8910265c0c3f79a1e8edf9fb2e4aa6518f891ea5ce047ba6301771b229c895c39ab023fce2614f871164dc05fde5f0ce12a5e72e52e09fc386111f871c620e00e4308f79f46e4ca851ef0e3ece1f1e3f47180b7bcc7d8e1298ce4ca8f74fce8470df871b218e01e440e572257b385e3471f5ac08fcee486abbcdbb0f1a3572148deacb8e46ac66afce83f347ef4d70c3fbde708c2e56a1a29e0472f22e3473792ddf4be2386a310c915e501e2c79e25e0c73642c08f7d24040c4f22571486f36307ddfcd84a0ee0df7bab75a8540cf7a5490f15cd8c0400000003150000281410078482e178288e744ddc0314000d84a44e6c5a9cca93240782c8188290223002020000000001080026c8b0812082c1b9d3c4c3da5e58a3b9d3e213a6694d137a7d266b06b9a62b29e612326a2af429b68b6ac037f100ea066a2387132916a38293dace71f340579d3824464629064dbc9b1de10b74d1336bcb3c619ec84493015589e0b52678d73c049d168ecedb44ad6afa8b1316e993c627f58f25c22435ec45a3f78627ee513f942af5e52cb542424b59686ffce31c2e726a8d9c256d6e75bb2d3471b9fe04fe097bc4ce86d20ddda4857e8ccae0b563e1bde61c7356fa2fde2d9407cf85992c8369d897d1f7e886770c9cc98b483222221b987b58ea5148217188aa83d53a07c9459fa3d5498064032a9d12ab11816b6c7840f0f9a5678f2db9c334afe08ac4452fed064d60cdf1e18f0a0de918fa6133625c5f7f078cd68c127212a42a12404092a111112f5a69a636bb101d4f4f41aaeb659ee66abd1bbf19181ec47fd47a6904d124ddef2cca5343b950167bdfb2672785d7b39b22e7196e022e7eb359870a1f8d78246a87d87eb9577a94e8b4b91143683839e0f10426db8c4049cce90dbc8c6d54d433d6a544a33a94ec096038c37830291a6c4293560a322991520a6e4be74e23d8020b9621a4dc524b77a0cce7161f09d516abecfe10e01d7682564b910800c623bf5948bc58b3a09aaca517fbd51704facc5960c1ab2d552e8e84961aae8341509f21e205752595e6c82eb1bb57ceb30160ba4a950bfbf2b0bdcbaf6f06c110b2a1c275c03d499009fc2fb1c44fe0a7ec5e5b949d36d53f6894c7222f6447fcfdb27482a448d8596f86b036b74be0610628d7ebc51ceed928e812eda6190ef9d5e618aa05999b23addbdde564941933a77ba960ed6d60424f4427ced143d817739f99fc5d910f97c374433f963e7b97a0eae606b5abed56ec6b4060a0c37b7310013997ce417abc3778a476a35b57aba83a897fed5ae4612d69871b81818270961bea15daa90fdc200a8a35e95050a2037aa78276953677770c143611a54e6ec65df31b2a5c0c42767154789381696129198df436e6f39a12134b29aaab980747824a29e8eaed74d251fa22564eecc698bfa590ca2f6bd53fa701e513c3a4607093f4342cc8019541b1285551769d38b5520fac564f8d39cdbe2ef8a1d7cd90e4498d8a71802a335959a0aa8aefe1321694c784c1749c961aaffd6e38384f1420aa944c2337d6c61977752407792cb1210230636bfb17d6942111e0d6297e1b0cd3dd2222056b6535661c974a5164ca92e375419ee12e4ea82b7202717a7aff5632cef63b1c0d02d07d63923982f8232a01d08e7148137888fa9ee309c49068e4b9fe86026d669050e1102f0c6cb2da6e35c0005109352d1ca60076bf64484142888d71de14b12c180d60d3cc63b1edec7212deb3716ab6768640d46a30e7e46451fc3d3e67e9fd4097c06707a724c70495c2e55adec822f8276a76b7406a4bc14f4adf84b47c210f4faa899d867dae82118226ce6a41942865001571ccb62d2f6ca36cf539c835b13b8cf2e1aa252aa4815f9a684f57e1bf2642a43aa1fdcc04dd107983275421628926f12a3499cd04227d5e18788d350707c4bf68b2a31acc3b5864220e466ccce3ed2e1337976c35d6668ebe098b9974f8c71154eff15beafc9c78c6a7fa88884bae38f93148635c22add8a27171d6d1db71932a3c02705b048958edf2323cf4599476c4aec82565033c5b1cc62d42cbd8aeb917eff93c40a78470e1e58844b3d342d06f83da5d641a5e5f6fa6e55de06d91f6439a6f48bff289581dfb76fd1627f826409b995901fa6f9253e3e6296e68ae260b3512b25808f807c3d2b598a8d026afc9c866094442d316694a3ea17914a912a84166cfaa06cb6e2c1227631bd60d28b819d5b0431641840ef8ca4fd8041d89e424f5a808c37d95b80e5b82fbd5b7c89bc3bc7ad39151dd1a632fe93cdfd5cf4aa62ac7d49c9ae4ae33ddb8861cb9e8606802bbeeb4c18360fd6d180465754675ecbd7ed13b686dcd1b11dcf50811aecc772227721f67aedb9c9cd0489941914bb3fa83cbe06751cde432bd347d8d9a689088a40528481b402d0687700d2e8530dd5e1d2f0589f6619a4d0f292dba963fb1dcd4d411c42799200e2607760a9e2a027b4e20a8bc1537969d4939f03530efbd2f374ddd8094dc7a223199ab0a12e67db41aad3b0068f68d123d64fe2835efa4d9f09864113993745e2d2190312dd4277c7edf9c0e50f08d577a15f3a3ee6464ee2030f74c732711d7457ef1d84d323ae066eeb3ef0218d4721bf5470fd0a9511f313c5ba6497123ccdc8800c681439c3aef08fee358978a2bdd1645b65afa2caeee87a3cc26b52537d227c3a2450cb24ca6c1863cc3fe2f2788781e529cc3462f4b3d1db70a9c9fb917caee415318f951c890c7e739767b6305874367d18904baa31a22812cd714f616678370c0e27a58d07644dc047a1d3c4867b3afc361936843b22a1c147132318360369a73381e28140e74ee5b9d29809c1cbdd1d99dbe2845bf23c8bd6c47523a37909eda487d6d8a34572512707a6256e6f70035d93e858ac446152913ff885823449a1ea6603156f35209552b389b056eba9b6f5cb49c22ea7e2fe990c24d14c87fd48e86225221daf692cbedc6218014aa2f269d9e0d12327064a338f88785ec17b9623a64ef9225331a1eb6c28c9f394562f8208298b02c4892739b956c8a8731d01353c8cb5c9186084bedbde41076f6928cb928741228fb0a0aa3245ed8e594bffb95fcff263e441bc511256627afcfbe100a62d97268c06adbc4068bbf8fffb555fbbafbdb600931e7db7e7ecea961aa6c3cd6adb073a67317490bbb484392817453b759d43d72f084b1613536ebc141a383a8883479c67d6a87564db77e8012526bf2e4457f80cd0b163c8621a794b8ac80fde8a3d2bedcc2b5b6e9d34c961328e6b31592cfaa12a9e6084e307e250f6757da2dd6637154fafed9d7e2fe164093bcfc097c434b06efbdd4044c86340af9ed11cc7a506b9b06405583e5f7bb55bcce6f77cd3a6e4dd6be7f902325e96b4d5c0f7a7baff68c0d599710d4d8991b1d0520ce2f50ef1713b68cce24c7e6c8b30845802004396ea656a2b684fa9957772f44902e1131aa84f5eb29f8461f3931e822243bc830e929bf5179c4ed8eb9eae9efd8e5fc128fa17d1d538b510aa06671d521d256ddc25c1ee19c28d840b727d6e77c89399f0163b2e43123f76a875c9ef540eb8ecd48db93182c6bebbe09eb6fb31d1c0319fc2b2b9e8a63929c268cc473a839c56ad0c3576248ba8716fd3ec681e17aaf448a932b572933788999de2b7fedb060df2b715ad0c286548eacd0ed1030803339cbf01810e48b9cd0110fe56f90ebb8e7e9940e6d7aeec34dabf22ad6b6f6df59b99eab4991c3b0b69e920a19960afe5eca8da1db1e8184207cebd54fb28f5a4c3c014a3ea70d9e43823677a05f70cbc5acab83fff77bf6b4bb6c7ed12342abaece0e39ab9f6b2e24f1e8d9b4d37260318e1b784374686a016be18df9d34a6688b81302d31529cc0bfee68500c7acef185d8180679b6364f2f762e70df2617843d47c9c96613a3319a3a8a4fb083efd6311631d5d82137bbcbc6a661f2badb78c8c1434593a214157fbc5f996b0a9f4f2fe1d8931874fdc28f022d2b0eb646db6b93c17b2d72dd14f00a86f31773f4bb8692e8e36cae70e93dd82209d2b1712a1af17111682e6b680a260cd6d584f204cbdad39f6fc182414b9d8afe8af3b52e9e1c7691ed664e8aa13bdd50eec15a18b368bcd09b3b53b965ec156c89a47fd1e50afca9bc3b33d84e4daded5e4d5decd37d58380193a2810cb55643518422fbf48cbefcc475fc6deaa644a732fbbef2758a8a3cb84d32aaeabc023cb9c21018ade1c287bab0dcd162451527a9df86f21f86b50637525fbb67d0c40ddfaaaa3e38d460f9441dfd129aab01e13f446fa45a2eadd7f1b9c35d9f439565a40a153d95133c3b7f44575c28ca90acb38079620b1953f5ed9bb7d6c3c7cd0c978e10f39439c8f42a3b3338fdf333c0d529949e8ad1465ad000a4c279a44099e0412d2ec9b1094221ba4adbd7e7d0d5ae45e7a5b373a18536ec665c5fa176984b51b5ab70e39a4ce58bf59c140843d1266e8ab08ae1af8eab6c6c13adefad8f87128ee6e73705c3612c4942f0595ad8994e76504ea75b47d25610f3af13b2092bc5c9fddbdbcbba3900b996e491000737aae62283479b0688ba11e2bb6eded75919f85215450ef5bc69787653981589f9debabaa74ce43e1b34b5becfae029b45b19f591c2ea29d7de18a6cb5ba10d3bc051daf9682aa4669f6dbb383ce4c51e497c679c83e983da7dc60ab1ec08912692b7616f4d46754c33170b558123b9baaa0bebc87aedc57ee6005fffaa4b0b9d0fe23da695a0580ea8b329c9a6dbeb528c367eb93a387f8150a1f5085c1b6b25dc492b7e18516da915efceaf786e0a31f9f597353d2f3e4f505d150809c1a892e1c308c071b721da237045a6ea442c119fd250004f6b24eb15c228a5ee1d5b1b868a0945bb5a00b8a43c8149fbe24d489aea127a58eb14a139fd9e5fdb648d3da33f2a39020a462d9100fc1a4dba04df384ee2796feff1e0b8153a12ace269a0b4fb0099c571b2334c1fd404d4218eaca8022d9da3399d6b9c3a57202fbaa4d443bca270c6a0834b51e9b3c8061a6980424d61d3e3a89ed1829a02e1d5d1a5f94d19d80e1ff2307998b9446f0abf0496240f5fd5e510369fc82a1f9847b9b29442d7e58c21e90d1c5c9cbdae9d14a05f1365192f1d2bd7cc7a648abd9226d3cc229604e082bfda8871a21e10998bed29dc13a047f432e3ae57e26babb4b3232577c93886ee14aa4d41fd188b3e18443119bb5869e1bdd4d87152c6b3352ad6d080f255c0f6caa125d29a2a0603a09d3ba8b8d0b78a5217ed0625c41399b6662e8c286250d97f2d46e08319d11592a60f06e691f8d175da8e60b8884983be692410a7354054eec055d3069fd9f3863bf028ff343b7bf4e7868a49c33a2c0b4babb32d89d46be16a5458fc7837056f9c62d43dd24c890d1fbe10b902805708fc3431765d882f716d5f82e5ca29df09480ee66dd9165882bc9163f33b732dac52e8719693965e99c7ccf1c388c1fbef500d7feeab082c60bfe6f1dd52aca7ecf4cc6e5100d933830bfe6b4cc9fbfb0a05268adc45e7657e586564490045cf1e2a45f8f5857a7cb9b7a09cb69418e669ff727ba202c8c55f925761b902421b77de31c9a57b1d61efac920b3bbca71ef708694137b4f2c6728dfe760fa3b902528b018534148e4ed35242de3139e91061d5ce526b5d29f35dfdb16a3ef995ace34108adab595d20a40430be6d070fe99c9a60e0ea81c2ac1d8bcc433f04026f1d8812e0217f969b928fff94619227f0b20c6988766421573d0c573214941ea9b45d8bf2bb579066a96b7cc2b2010888c031e801027f0d16101ad0d0aadc147498684c62280fb17a34586d05522fe4deba0aa1593f76b16a9eff16ed498d45898f2c0f0f20a40f9fe50e7f7f9051f4c76cf0d729d9e2d42f0fb625ab53a694ba0d320cd74d5e0cdc461ad1a7b24c88f72287d9ce2fd96fa8892da6c282be3aca5ae0850090e6c59d0aa8d85bf4bc539028308e3bfe0fa374a13dc4b193f3e62735c17b3422eac3632e9c8098a54a24e3f15085a784c85ab36b2fb7cdf19a86367320abf6094d0f8b9ef2c4b05ad0ee4eaa16e8ad300db569b04970d65d6fe450592223bdd36e9b7795208146d5c36aa6ae23ed5e6844bfaa270384f6928a697228044776b6b4b5f56a0521f79fd4b145f1db61c4ca67be958578c6d329a3b58e9c3d568b1a4f2c43520f5d841c5579d52151c713cb15fb1ec3d90df5b1b6431c649d96ef214d630a229c769cb402cfeb52f171d3542f55e57f1f07c3fe14b47202ae0f809c6abada25a90bee956155011e40e4df8a63fa3f7105cd1f86f4babdf2b8c34a8beba8689d8d262f5aba34ee9d9c1d8ef35b414cad3668cc0cb02c34e46186aeb2f28f43c8314e0d518c7c8c6480fd96a75b5f0243f367b2409899e827eb850a8fbdbefdb412f687510b19af4deec99f2bbf5710e58a0d234176341bcd7f44124bb05e60648a3438fa08d36fd74a152784db4aa8e8baad8ec897ca1e43cecfe2453578420c178bccc1b6b7c99dd4b9d29436041a474a999162d0b9f0c20f192a199a6a255e7444786166d4e085fec3ce0a8cbcdb196eae8d178a364507cf98f474e3913155f42c8a80089e6fe48c60f1948fcacb596ae3c7104a4d52060143f90613fc40baff0c317bcd5f0f487cc6a52c2872d585be8b1904ba6003ea9ad7237b21a634a2df642f254e4203dd2ad237d3927d971fa267ca942f3fdefc40bd9a20739ead3944478dd2e796e8b4ccdb2943f9a4b96548978d9e08bb07700f96dfe2494029641ec90108e4cf1c1a384168f40734dbadc909217e3137c87289e2d30099b37931d8c607184c329ea63ddd901751d36381a103bc5e3054977ee0153f24e2dc28028aa3a2c498f94bae4d60a0ced3e1c7fef0e0060613a822cc91a1c3bcd8ce521ffd066888d3cd43b779d20dd02f60c501e29b4ccac8ce5c57cf19df2b047c26fcd0c19d62de781e66cfba0286883b2942c5c7c2e877b20701c018754c85e157c00098a26ff33b6443b4a3bc9cba41598108989ef442f58c062e3fde709402385e6ddd8d03ff70f6ff0f50aff276af010316c96f1ccfc2bb19dac5cefe44420830e1318bf21b558d7c9497e77f94c553e8b77f9d56b2e75de3ef0e6e8ff1b3fdae7419cf5efcf147f625825f965022b14d113462503fa0464998391b89bd16d28e12890428f2ad90915cc19d8e208765b25acc0bd461b4aa9187e996cc91589181f3673cd490fd4673eb57b879d3fd9e658fc33d931ce78dd7ad9e691b413d5f5b1e33dcea328bc98c048d4e5959eb4f8db94628c90c74d55e1d5b1d0a646606b1ef8d63b44862c71147647fc30e14fc6954c872456b011ad3489eda77c54c58b04c8dcc292d8d992b11e0cedaef19aa3f136ad8a12cf25beb540b26580d3271d90fe628b8e01262091e2a834bf2e32c3cf3397979740dca8a46844b708e9013a1f90bdb0a415c9cb7e5b5a1366c1b55ef6f2caea5196e27fdc55d76e05fc047a83fc046a83fc046a83fc046a83fc0f44858bdfb2178a313c12ebd760f6a0a2abd5d819fa52f4d6c5e592c826d86d238681d3f817f00b1a2a29d1f97778c2d46d675aed0a4865258490f504ea89c4916591befb5a376171a190a86efbcbb34e406938138f1445fc7a97f5b298a453098baaaa73ab75218c9a6ac28b2f9be58465bfaf1576a155cbf6554d41d40196d2cad79f05cdd24d008f3222f344cf5f41d46eec655441d2f7215c96b66b55f3414a66d2f18aae65948061c6abc63d559be6bd4d0596fb1c988533256b3284169cfdd302a406959e4ea8d4502b44e3499dac816800e2f5ae5dc4e4c62cec6629aaa80108b30669b7cec60f0ec4e208a0654d5c09fca2df1602a0acc644a51cb9b0d73a1847adaafbc9d57d511a814b534776f440af70804520f1fe8a14fe82ed156476e0fa2043d8582d787b80d00d6a71f54022a8562dbc4a5f1c9da8e268bb87ffcc1a1f76cbb3f913629d322e91f074bb4bf44ca077846b032b9b5b27e08bc88c3094c1f04d808732df59042117288f6d24a621f4c3bf45d9fa7075f09a92e671b461b7e2cad21f9faf8416e4725b8b6b69c5d9f775a2f7f9199c77755da0c9df2183e4aef5b9a88c7ec343c779badfc00e876bf908c8c58b92d6213b532b742823a579c70c6903607e53b972744764209947ac44805acacf532288ec9ef6c55591aeb677f3669801411ebe2519a02544944333cf5f990d4c2290b651a65ee680a523b718e254d38958d6399fb0a1e10a4628d29965f7a503fb93579e217baa83d07271911e602a8dfbe60c5969e62be755069d4d615bbde5b5539cc4a653c6833fc56ffeed7d257a2fa78535f35752cb49824b01332f94ee21b93b19b3454ec281bbaf723f768643557deb0ad8cd4549de1ee3fc17cc7b82a4239267c6cb96f23c1403be7cedddf72ce789b464f29bff995b7c60462f5c9382b6d21a9fbbd25bae7716aebbf415b1db9ad3ac39d8f82e92e046f64212de0d5fe9047a578ba0dc18d584a61ec60cda6af29985fae6c37bc2729391666960354480e20caac31919650a048d8c114b7928c1aefdbdb403f34de6b98dc5e7d6175853a1aeffafda7f1fc1f972e9636deba6ec62ab3f160138f8df96b8929b786cc0e57f672e9d67ab7b6325aa9a5e4a2f7c5d11128b975c7b87536b56cac590d57776aae6211b1353194f94fb9f11e4b416fe501069850c526563138635950409c6abc2e88a14d845d67026561bafd1336ebfafb7d9fa8015d74cb28e704253da6513d72b23f551f186b82b608c0118180531faa75336fd9e3642e72a4ffeab86522ea3fd916375b69a1ec2c59e881dadaa1d3882e066466da855f12a45a5a7ed9117687771d78b9cc89adb869dd454436d0fef9e9eadb620b46fb4dde6b4094d1faec793bb49aebccacfe970f144fd7cc3a38b5f46b1ce93a2cd7583eb22ca5ed8f84ae5e165e66f4eeecb581d5246bd80ff5e624f2ae130ef8272b91e3b42e614c86dc18879ce081bfafc33111bf041344d34457a37f9d0a62d44e7a6d813535ea3c68b9945cc2bc3a01a8e705877f18bbd9a819f9f282585c3be50a5cd30e46b43c66bfb860434b20cefdb363a1f9a2b21c81ede367c412430b269803b94006f1dbb00b27f603c98c24160e24010349c46bb9843dee0544339a58b88061413c061f881639d6642816a70b10b37ec2ce40aae2de2bc46e735c6d8c4d0c1e6b620158831f071b34d840325e5d8365e2f937aa1b4a4fa444f6e0d30c10130102c9812ce2b4af396cbf364daa93f448c4ea9f148f91a47897f2b167be541ca39318fd5ede0dd91100f3f054f1b7500fa6e425f5d62c5a56624e1f5e5e776f3319448f7d6d9936ca8078248a467cca3c4db3bb510978dc500ea2ba9f7384509a4cbc83434b9a88dab2e21542a208c9932c84fc0abb7dcc8170932150666de39ad9ec083f1e0f3519c3dd508bab5e7f2e14112cb7a7f8a2ce150ca08e25975d77f359a593677759549950616965dcae57e1acc3605dfa971462313d51c07412b6d35d9f61ac84383bf066d7d6c9f598041b51ebf0c94c995d65391078ccb7cfbd544716d4161d6b8e8f9a17ec769fdbe7fe40cf8c0ba68ae10d819684421ddb7d86ba91dd359cb44950f2d10f243d62242059f28032c72a683743da271aeb274162f6862d647f6c0178d50cb8e97a3996e0da683e584d67e97db825e80758748e1efb4c9bcf03c8c729517f5164d7d9049adad2c3a5b88d01ac009999a6ac7e3c82f47b68f990055422454be65160aad465ae15b964f3d7d9e9d38a0f05206d0566d1b27da9f16b8f2b862cfc96e6f1738fb4a10e8610b80eafb0bf2179a7d895509c0cbb096b704f66eaabde110ceebd29ab62c30196a0155089d8a6e80014d84f5039332e458a3556470bc6c5936ae22ec84f910df06338d217d0360a01925e876a7d14325e2933745ab6f6cfa095dc395ea886552e94971ccaaed51d4c54790a12ce90a13cd29141252b8705182efad771bd4819174a521a46466cdab3b6396afea2e51bdaf8b877bb696f2db9f13996dc29a5365dc373bb7af8b5769d19c1ec2a375c0f1bbb4a14a2d3cba08a7711b37e54b7b59291aa2e99b7d6d5fd1ceb746275afda048a14e46527e09d413ae9e6defc92d5b4b8b37aa0e017ada6c5b5f727d3ce12fc9059771af0efeda767820bc49a9a749eda9aff02ff5901821344d25e30301550d3bbda2ea025938464caa92f14cd1523b764e962660949d2f0d50709413b86eaf2bf47a8cd6011cd6d657e382a020be34b362025829d67adf1797d199751ba72971a9e6bc4ecece4bc3b532661dcbec41cd804073325481894a791028f202244600e24680825433c9013bcd9019157e2817126ba30da5dc0ca96d81f7d37ef93a565f5570d0f5db3ba90908e4e82c1b5c845544ca1117589d2519c03b000a440606121c74473f681dd77bea60504c0442ee58e3a85438a0cc4c531644df31a9728bc2bb21bdcc89ca5501024869688e039f260092b584623c8243200bbe0c56e7ca5176f94be255a9ffa7b5647e5c80e3dcd05bbdfbcc9ed4c19cb05a17e6e8a0e96263092d30d8bd40e2433715e9b0d3801c4b4511383b3ab952d45c3868e95272a84a35812e9af07bdf729652c1ffef4a4bdb0c1f23cb0e4cb49e2189f20034e427135386f15249fd2f2b07b1789eac4cc115304b870bff39f493dc42e6b5de562457a17855a14ab486d1e45a13401e90f8d0dbaf662a1a0395a4583cd49112759e222f53c32d12961e6062c1d48e93cdb278a2cdb90c9a7d5f565c5782473c7bf4f9aaebc132844c209559b61852e16eabc5b72cf6c53597048ce57e2e07704446b0ce1140dd1e58807fd82b71d66f2a53d326e7237c67948b38bf865921f38e37f36145a4df542713a1c8983d711147b359dcacabe0a40a08ca17422d214229e066e81c1237bcbc46148dc8efb1e4df85a3ff308e7a098468134210ae3ce7a834b9935560b04cdd1281a4c4e5634651395e9f508e7e20cc2187800081958bc997f122a682aec50310ba516398b02d07b61e8a2fd51dccd043bbc099799b0cdc61baca6b3a8606d52a13671304c53a28182cbe73de09f264343f1b4501c67015854ffb94727c0584db4f04c1383f651dbe5307e6e880e27dafe37944b0b99af8bd0495f9f6f26f770aa4d50da630da32dfb3c1ffc4e600e116ae4bc7e8938e4de625bf364177c9b0184153b884ca74fa9c9b3d9cc4fdc46108b2e69f3bf1a12dac6bac258350ec5826f89802d69060776292ae3a84e2574a933517eb550601b29119f5b0bd1d996943e374b84659ea7e58cf6225aeed1cd51f54270236e99602b1402b29949101c8ea63ad0db92f09e3493b3324c883dc1b3e29ac22371658a724db07a24f807c43f481cf3f836c5a4e5dac0d1c2364aa8f46b54af7be76eb2fdf53f69e9032bdc0ad36d2e3eb31247cdf44636c3ea379f4b295e815d361a295c2a943d9c43715055cc145a22a16d6a67ea4144e3c8e5951f6db32b0cfa5f9c42e8078356384b22346a9c69b410a75d6759156503509a8d95de3f8604149ac537c3043669d3b182e3946472dbb131b333ed004c90cc28b0e576e4d65447c2e80d49a4e5e53f6fb50d0b378f89d9ee1d4c9e2c671ae965c758486d0701ef6d9bc4408371a3b5b78dba1952a3c6882c085c74a5e2435f22f246414c5c9ecacc691093d997d6774184083b4110652179aaa679ceca9e3425e6a238e02505276f7e663c4f38e8b18b2045a3fac2218c17d25b6a67d49418e62930d1485328024e35995922e1518125587a5d15ed0ce620c5c51a803379037f785137a05aca1886e6478b7f4fe5a5fc23e6a765e7908cf854b9d9d27ae648a4fab64c51097437574074872d6fc3968be5ff6276177899064d407f63867745f6cc3625d75ed81e56bbf1f119f76401044b0c74de4e121b3e502cb3e4080ca27b5c1a258105ea784d138bae6d86c53373366712ba3683512908e51c5d5e91772669030766477fcda0955daf4b2255572370d869ae24992e2b7585018cc066a17865f3a3e0cfb11f991601fa4ef8ac4ad833247ff4404b871c2f553b958580ed9122a72751f8ab539b3a525f5055eb6ef763960a2813ed70c117c1c49f4378c81fd3b7fcc21ef3146dd3e537e882a7daeb2b46d20de4eb186ee78dd17b935d9b1120e75b0de9c72e769823da614fbf941d98294c30cf52502caf310151ee4abe82281546a27c1604af176207fa82fede61f55be112255e0be199423dd56c8c04616d86d40dc9ac719f215d431886484bcae59da478590895d668b26f7d858086bacf67463794804aa5822e8d4c87d827a3fa00c7039b07187f3aabefa42853f12fff645c1af0dd281c84defa6c103c27079451745493d724dd8e91000ab3ced6c3c5e8d5dc028d4b87c7fa0461991821fd18860ec6a86189a6fb5fb88da9d168f2906b9d388364b0645d39bbe5b0bf1afbbfb0c0c7d0c6d35124400e9cf5277d86677883e5e28573d5584d4d3328bcc2aa8ed441f697d5c20ba79c1026d025c749eb0727fcd81d4c4ff5600c3bea62cab7b2bc2fc83e6409dd2d5b670037190c86523dacb07068c5b0ab7ffdce1298d63551f4f2f004341401705e7c7a9ff6399c87a3bd9c0c7bcfe16fd5cd000d3bdc676828c4894170f1265d29edaf318cf1f3a115f76f45d6ad4102053738cb8b40b06abf38165cec00323700c18806c008dcbd36a56603d6dc5c7013ea57118f20f631bd0381b06c2fc1f7b83aa5a7c9e6ef0e97b726e88a173f94d7c08e560c2a0ce3caa6c83128305395ba9508ec1ac035bebaaf8b1124c8b79e7e5b620dc6176c01520d9fc3d7beb0ff0f4a4585f5f558191704a007011d439c1b01819886b71e053a7c462b15d16e263749ed775cfda1c061cc59c1fca9ccdedbd7e5dd6e546431189b450d811d0e8ff34651ad24083b51308c6bfb7afdb1bb182141018f25c2f0552375d5a4fc3e5bd1771401a02038d47bec48ac4c11b5c62302a8c7189bbeccf6e5e2c52d9eb8628b25b6d862122f6ef1247eb0c42e268a9332ce20a5faf2c73efdfcf34f7dfefc671f7efea18fe113dbc702ea6c95af96565c0798636351b9cad0f67f6d41c273a363ff63103ffe664a36ba80c0312b5ab1d23acfc2ab9cd83e0d373aab5736f4c78497cd7aae00c4a8b2f46f4ff9af2b961e0fa7f9fb96f6370a9b187de365b057ad8b7154ea01306012666d8f8b81662222079152a425b14da5074df599179de06bb8afd8e2bae06c5ebc757dcec29202ffcd9d4f5abe14413689ccf7a089a382d6291d041486ae0eefba76b8afa1af2f5ae1fb7cc01456966208513386b81977ef2e3a531f98caa6c63766f4d7fba9a826db1fe8ebbfb60a3fe253bca8d6ee8f5797a0a88ae01791eb5f5a851f355558546bf78f29a91642f3561039a44f80416ee38f497bbda866fc8f873f5054b6e75786fd77eee25f2f1d155589793fd0531197b8a242f07e61dcffc641fff7c6e445552ebf2086c4a2fa1c3f35017feb20fe7bc9c4a22a17bf0089a6bb0e1405815f9803c02c9f08de38e145f5797ed546c1a25a233f36167fa86bfebb49538369b8413be987a29a97bfa58f7fb43abf2b5465512de71fa124575195c2ef22c73fb5badf29a0eaa25a8e335a47f4a22ab57d1aa07f5154ca8be92bd1e29de05254a5883c37bb7f64308cef6e8f0923ba850f273412a7a1c90716478348735165c0765d4a6dd0faecdda25294fa0e3953408ab88c44908681a23af6602657706745d5680668065725e200624d1362511585da00457598930fb76bcfdfa1de83b7c15a36d406cedf7fe30f5854e52544b098d0eba9afa9b4a3df5fce50779a505021f758d3522a76a43ea64abd049ebaccaefc750aa022281e53608643cba2cd4ff027de623313641855c3944479a40849887063537e38a09014210911163b718bae0831f8abebc3830b6618bccda9e414e2bc4d1432ac993daa83ac3d0c460f89f59daf46414d2481e32d0b0bc30d863131c4e165c64b1226924e4c142ce2c14863eb4ec134b2c1d84563abade071f101cbb87fb91a0af5f6d2f0ea5ae395878d69fadfc6063456caed9657f7dc683857a68fb084cb8c61f10e50075ee6166e654e562978ab998bb15d60425952e8256ec74d33d974f581c0aaa20ded7be17fe8f4fd3188c55d45f8578d08cdc8be21566f3a994b4b04ea493cd4efa3e2804853ddced05a634b994310956835284bd5f070d205cf552a80395f1203d9d9d092baf582ca301c1368359d57ab853d7ddada21732149a83c3ecda0c1a42634a850351dc03f3a090a412633cfbaa3cd4707708929ebdb65dd0fec1699b6699587fe8b7e4add661866775dc7ea834400f85d05e095b0f917dfa2626dffda9e0edf34db3dd9784d780db630addbb41a437b93620c166d3fe326c9c0595d5b0a127067164f327ce9ec9ea90e20217b646180e8a50c70e25f5287947518db351d534d5c16ea7faf28609926681d84f5a6cf197381e1641c3aca72a13f09806d65ff9fc44228b0a54cb9a5eadbffa285457e8e86ceda4a02f463ba83ace233ddfd4bc1f9ff9b80e5dd927171015627158f756aa528697f1d13b6ad334c23ced898d7cce5b88ceff6e1150ea61b2143f6a966847c76991ee03c6e591886f5046a6c6f1c825583b6148922e24e9f03070807259ca2ba3003cb36927630e20f50891a6497fb43c229f920ccb6cbf9719cc1ae36105b34f44a1e16cca18931c6ffe95bcb22202f4e7a31f5e1752d93671e93944ce680453c11dc88d5e3000bedce57ee5449a005483a9595f5d3cf1828cf0f4f24aa3e5976031acb920ed6c906ebae297cb28f348a00311df8985115b2d4da683b06d7497dd8ff8db65de85481b4f99986865502852b9c696a23327b219bb5999c47d5f9c4145da0cc3cde90a942c54a4e1d3ae7b1fa9100b5400e5f0e35bb759e85193edfa7d32c2d6e8b704d2542319b2435fba850ca9af7a122d5a22e2dfc10af5afafd92cd14da9ac2aa9b4f5688c45d69e1f87c9e2e13ae0e8891389ec3b5e8768806688aa3b5b6b95084e5051d0c1e8c1e2264b45753f008d22c4c72b8b28b9b7a32869316133f50fb3cfae0134185a9792279e66c52c489e4ad3c216db83fed064e69b71b1b7672f6970f6c5fd73007b475c1f4166e3453942e22e912b9d1cc8dfd427902409a712515c5827953ee90f924736e7c224a6136b4db73b3b43389281a2e85368b04b3cb7074fc464bd6d54be8b373a9ea47dfec36f52adeaafafa998d6d51f5d2223058709ded34172478e9e2bee1a2014a6b99eb2e89a0a11239cfcb75ffd3bf6f03b48acbfe424d342dccd3b50a6c64189e929cd68599acf888b79d85cf87ed8290b475fc02e786e04228a5ffc83ecdda5c8052347c28065b41011294a3bb76086809d5504b8fed20095dcc21ab16acdcdbcb3c441bf65f13a2a622ae4949a358e8e9fb14000f50bbf1d894e57f3feb8b85a17f6f64e83da8b33fa103f02def35a2e02b0771397926d2bff2137a6409f0206b51998a22d84ca3ec7d92500e2850f24e3f93966311a9c5a3dca2407b3715fb1e4e19936d5cc9e196d0e5604b3b5b83515ec838e9dee24d2133b103b7b595c8879b452b4527baf2179f031429875eeb36511925dbc2f2be166878120a9230573366577ed99f0430dbf05d4390cc0992e0fe72bab36a9f8ef9004d301e4ab0622f70a0de2c0b2589b460fa854e8ffaece9dc46c4a721d02a07ceb0b53545656649d61de84838c3d958a05591c83326ca3f937162947f513802bb1b54ef6b594b60ef3c7dad39edaf2e0f20014ce016cc2548fff3cbdb11f034b1bbc1e267aeb58e67dbddefc9d5c82cdd8737646f52b9994fd3d33246ec64eb3d162f178c4b861590b1e31e44dfa211657731a766024891b874ece9e7b0bb09b493956fd3a13e698664453d79792f781f659ac1af4092506fa4b121d2bb3178b37d29530dd7cb9dab90362eb7cf5a3b63f5e64621db0c0c48822c2343577d980e9389c7260caf34fa777a89173696917152bc59f78f66d8ad47331195d8c1b7b747a322b6c219e63e92c16ce7108ae1070c903b84d29c030573c8a1a850e218b5673eda9452962ce7dad89c0120229761db9464cdbdae629bce6d13288b27523ac42025847088231d3f7493363e01933eebaf9c8579102e367f7a0620530da511ff5b5c75230015ed414ec47467b953a55aa6b5f74e7ca2181f064e262639a04b61022a11e9cca6dc9ab0188f448d973bbe43beabe01d8a5eed3b4029f721d9093a3a00f628da2bc5213d09de951e8eaf1092b888e09b2fd05e715a2d045c97c53c86037c02e4099afd5a0a2891d0a766de59284a11f12ef3a3c6cbc858c8546601c24d733b0a08c755d011e183aa96d2438d233802b454aa1a1c8b83092cf4397bc5bd45d75860fa8f68edf0d1bb10c1406518b0c40273cbf0ee28c738f158eb724a39271cb874af21a9a0d6044639c5e1c94c663a8c3f12983732b845bc0340f2c38f49e0e850f4b802a20f0fc3bf6d888a051b94abab5a584d9cb6d6535eb85df5c6c6771ea170642f33a55afd230b5f30108bdd4a5211b94de5a61a4cb4bffb68116a7713a73173d9a18536b632fae2c76aedc2c58ebfaf29632100f0cbbb4e0671846e461ccb2012ba22f658c62059389005ac2f1532f4371f28b2f9802e5dea9de4c2a2fe6c51d4a494285c76381edd2db1259fd2fc01e0c2785b36ab51b772c005b4bd2f9aeac05d67f65f9b2206e3ce0025a484cb277ba3ad0ea496be77bc9f1fdd8a43010ac1c3d14bc5931119248d7a6fcac114d98f4caa325fc700b04998336ac29c4df4c15471779e6a58b85fd74cac45f1ca3e8cf24916ebb4a53641a9a0a02547a0123fe229ab79fbdc348b8beb1f43236a84d2af52b28e51c9cae2afbd5fa80f0815e1bf8864fac5864324d11ff23fee168acb6894a6b95a80cd0ffdd3ef504dacbddc1d5fb2a93e0a03497369343b1eae84369c85e5995811847418cb7fa8e98d9ba0a79d19f13f9f0ba8e3df1e087c603a75e0a91e5e0c58213a54c512eff3434830546d0008028183c8aa21147bcb194fab8d7dddcacd0508599e790233d94c83451727ebcbccd5154592ceb3a2c9fb353217d8ba443bc1dafa47609a106653450a2b6e5a56937f9bc3b8fa4036a96de62ae0a9dde4147e63c3c4aa19bddb7a914dbc672b0cd90720474989611d86ac38f64dab56da92d9c65fd081652596f7f219245051dc8ae2b56715efdcf6e47de7493ad8c34632893bb40eef0f2f5923aadb8ae669d805c7e9dde22d2a71edd9ddce4bfca62bf76cb7f7579bbab2f893f1c23c8dd1892967917372f2801051873a8a1270dca78eb7490ab35454561bfe0260561b2d9a018d9cf5c6f875608103c757653512d1e2d310fa1eb8c758aa5d5f1534f05268038f59c2a9adb4cdd7aa4bcd9c1b89a2f45ba26eff4daf3e8f7f0346bb7f9d1900271f9de30ed68a6689ed8ad1d1f0284d414dc049445d499d02b2c8cd814e6485b4978c4620eb10155f03844d3f614a17eb721609a0dab523dea10002b9c2f30b282c3e194b0a080241ffcb6aa5a7906e56c106247b345c79ad99cd0d77bcdba62b6517881fc2d3e68a38759046303e9f13e60bf2839dc2ac80a3af720f8decf00be2ac2f24edba775e7f7f55a28e4f47efac3211bdbec861f382c9536f400b1152b21448fc8449596568ca9db27da58a95800cdc81c34f9996b3bee178bb543fc9f15b0cb93d71e50cbbfee921c0539ccb8fb604bb458e137f446994a19e6daff1bb95e2ac1000a68c0c4ffb3c35a3f7d3dcb64f92d27da4530d0af896a2dcb284f0c268358b278cad71a22a91893f279316325558ae6e381273718715cc57922ca8ba14913232cde99fe4cdcef6a1c6d84461466e884f5e1595bd5dcc5a0e589805c21ecc01b403042f2413b00bd91d21ae629306a842bc03df828c3536290b2eae9204f9347d1552fa0bfce5730976e6cd3c071f75f9ea3a5dd5ce0cca7194f88f321e28c180590c1e5058ecbf869f1dd448c2b6b64ee6081da68077d7696e51235eba5fa3d7ffaeb4b93c9eac023bcdbc093d90523404d6513a69afe5996e2b77770809cec1a888d841f830329d8251fe3f4d42c004ab5f1299157a78851c95b926c4454dbceda937eb60b67c047919299659d40403ffc615624060ea298285f89ba4db6f0d53be7f3870013c4afb2b94964d6fec76ac59d87e7c5c105c4659d1a86e48fbd4f0e12d3d473e1890df86deeecf351b96f99dbaf00c3e8df1e3e745757bbca6f70110598040efe891569176fcdb7fbba10e7a185bebc5dfda4a3fcb3fa261629702d04a3e0b6f8e8223f8b77529b7ef31029c17fd83db72dcb1358fefd26c912aca196e02de55b07888bc7df636a36090cf1d65a8c6d6491ef340691764ee9f558020b4a8ab75ba7844759f12617b68dbefe2c9f340f1751df32b8b95fb3963e2bb14327b515d84926c77dc829bef6b56da5559806c639968acfae006d21f045b5b87ddbd05c188e2e4341f4074ea65e797bfd0c1e5e3186fae4d5700a32a6d1fb7e8cad5135823f601e64a808563708f347433a0106947f8ee8729be53b941806a53c2a2c143a5b9c1b1ebb69db95dc41e898b49c726c31a6aafa66875b9ee49cf881cb45f0289b578712acd14b449f29abcf505ba5db3982b6de9d8eca6eb0492db485f3bd1c13450d81997c75a9e0da23f35d9ed2ee47c01b98d4d667dac47b09c369c3c9e8149b780b65cd5341e091b9453bded50e2c02697aded79b2dadf5c4475b77dbaaa3d35e95395ebf43f33554212f56e79f85558868b53a7ed1d4d650ffa87854c0374292e0e1a0dba19a1528d49c58386cfd0935e51d1bf31e71f0c0bdee80a88096a39989c2a22f043f9a407b7358d71028d15867f70501bbe5f651af4e713115cd8cdb2796026fbb8f30d481092dda77254e7a06c066bcf7962abbe3daa2ad19135f444389bd8414d3904ee0ccb0420d0ef7bacc7b6a3037609ee81e1431b3a853301722f428108a947cc3b1728eeff223045941ede4ac2c204ed00e4ab907e0f60e6775b120d7511f51053f0a248809386ffab9ea9e6a558c0ae183cd83e4f02d9a658b81ccb3b150aed7bc891de535d35683ff0d641f7bcbdbb8ad135359611e115dc98d0af3f3dc0d4e47410092b97e8802d0364ed9d8ac1da8ebbb29734d5bba66e7e61bbcefbdba43382e637da55242d223674454e06e7a790e4af4c3006432a04556ef44e477f89839099d37c55dfb137a294cc04dc57fba1bde3246a6c09b730c05e4bc14e0888e03e8e98031669c22efdaefc7657808f26bb67c8d7e0e60d9626f757ead7abc4b3f390a28412f483b2b144a62a13ed45a0cc1776dd2f12af64c308317d84d44b0b2cf35c0ce5c451b853990273f868e61e45bd8ffa1c36bc0b32e5f649df4302961373f41078982f31898031c874e8941bf260d6770cee26a8a63332028d8f227aebf9d88a663c7282c13c4efc3d771b207de7e4dcb13edfd4cdcdd10910aec3e32c32642ce0a001525eb84c9445ae298887028858e0b596c87b6b70732c4dcdda952074fb0ecbad4d6daedf54558129e4be0dc401ea0c8133d78c2e9b38a8f5606a1ecf09f21735b005b35cc96532416df9c59b119ab5d5a179754a58541e559a38011e804fd38eb961d35ba8e4356d4b95f398948ba3a089928dbbf4a6a4a019c1b6cb58117ef0735bddd7db606195c86a0a12313f79733fd5ee5be7f77fdc45ee577395fcf5c1685a8cd0e6f745b93e6310faf74edb53ebed3cb58804bcc05c9492551c8af736df47dd149622392475a35d911c319c672d4790aa150ee22c4e0ee831540d778f239da23094a133a6a6b4b273fce3e2085378c17dadec1ba23ff67805bfb56e4149587c3034e2572b91199ac03a192453ff58a5e59603e41a2e44b48de75769905ae4f4abbe8abde360b0cc154043f303f56c0b0223a5195631f81b1470d8ae73ec91edd088f5385770e63711f49cc581d6908e39773478d27d852b2e8472d231dfb5bbbd4c11b95044b215ed45391d05f1a19b099732389249288fb28da1f177791da521411ac0fde1dfd6ee708970116e830b4f12eded649cf3df2200ec9d6be3056f8645a0882a4d373f5e160b17ba6b0c4ce58b9698bb30976d1ba35ce081337e216fada5455fa0f86b11443ff6585c513d5229597f6112e087a13617fed675940fe82db72d0be8f2d20e19cefee9d423105c3898b391766b7bdaee6b50a82dbe8ef67f3e51042200843fec507d3d36591968bb6cc5706b8d3890a29a4adc608e091a5a81216141b5928477969a24d198d15cc42504a8c8ca6654254f592413f6c9e68ad93977e333f1cda351419877769ea492484d80a6e8ee9e79470e7786360b8feaaedcaf7537e293fe2823c464108e82e0ccbe544518d9cc7d481ce3a7a26fafb427af7dfbc83ee57ed119f74c82e5ee1ee378c44c7f451f1a25424a09e20d38664cb61b3022c761297a68e315e024b636c0fe86e1f41ef0de2dfc4ff9a766a360f3f34fe5a7eadd27915ff6ff467c00eba581b8b369cdc5dd19706c06c060cce04b1d0f22faa056c80ffab6d9c79061975faf17573ece50bb8dad1467fb29deca0c98de02f40158191807606480eab53560c37e6a7136f7901ab8492f2fb6ed0b2aa422dd057fd74a03d30d287d0e8f06ba77469c01f0b1f46ef1b9d80d98bf604ae5cdc6a34d6e036641753f54b72ea4daa5527e7abaaf866eddd87467c7d41350d4463e16b7493c880d8c9cac01e23806263aed6f3100cf1f9774a6f98cc56c561bc793a024e183d9953ef5a99cd3568eb9ad8be7802204e865ea70e7d0ead14ca4f82430b6d4dc880146bad27a215f2f189224f2834da0ef3bd05dd5bf2709d9c4384968d373a278d91f1a4c8bbd05f0878741581689ed1182a008b164710ff514ca154f29df08c3593a8d0d975435dc2a72d81843e6c3aa5839a7ccc0f9fe44351ff3f1b45acccdad44622860c9f04fc9905c60fe0b568fe411650a50926f5e81e37aab5d09e791210fe57b9d5537dc429ef304fa6863924cd82e01929306d0996bf5913ee980e7439331b2fa711a287e7af4cc158f7064e8fb3f0d63d6c1fb2ea416fb4473024f3083837c016f866905d4f576d3c058b782c5b842e9fd54f869cb4fe585d4d524e039e97bd40ae99d325461e772fcc24dfa8811f2f47b108bcf62984e85c0be23103f90ee32b692b5779e1fdd3c0a7fa9197dbc34ff89756de55926c7020ed0965b6b68d65191a87ca9fc6afbe29db5b5090a10c2a7042569148beaf3e21bad8d5019ce60db17953ab110c34a310fd614fdd4d65ef800d8c1ca7ba9d1aac503d2c75403fc8623f81326d9244657efcd53d7097ec90c5714fc9f128684334d2cdd53fccdcb1e43e7a4f8bb2ba4fd8cf0e5771d8cfa6fa2b2bce3a49028b1202fda03f63c7f41363e9dd6ee836654502f38c11d305b313f9950674fad181e13bb903a396fc8bc963266ffa4179d099ab553a25b1d765148a8556814f494d63e8bb5c432fb7c038a5db5a4228a1b8ef697099b3e64b291620d545b9155e332320b983563f17d7b594f56de61533865c1c7e1b188f2c6d93dae0bebf9b8058f4f28929fb9d4d4c1712f75837b05f5f746a60b09842a3021946ebac736e27be12122b8d76f9d7706ad182d98a640006b188ced9409904946e6f0327d05cdf4c46db7764d81e2f2c2ee811f52fa3e55f7a008196c6bd16ca3d91f03d20eda252bc92f02f31b1916aa97d4803035f3dbe87e2f65247df38eda4ba68b54344c38435b0ddea32de83f7ce3e36c32172cf8817f114ded0037e369f9527594b4d9141280bbffdba70d15b8a65b26fe1106b03f49d918fea22613184a74b4a0483f354041dfccaf8519acc857cee0259ac079a63de4ca76294f9f360e558a48f4f1f289f169ab8a50f8ee0421710f51547781513a7efe0ad31b0b6222dfdb42511968ff20b2513f72282634514c4f343feecc253ec2c00ac224a69a89d60176656168f50053f2a0b5edb4c928459d896e789a00f992564bcfbdcabc722a9df2f8800b0f6aae2e2357a49f09856a78f308b260e84567115e6ffdaf4aa915fab94ea32526e7705bcfcd43e3c1622c1a9fbf8a79f377f09dcdf8f60d08f7c381fb2ea27b1f31d7155492251fb027a14fb8b4bf5ace2e65e0ba94450a5c06a27fbb2de25dc1a334316e147d914e357667dd182eef5e6ff13ed733ac0eb9fa14d1320ede300e06a12fcf2a6ff1ab86303d46a76bafc7e650b36432d266ff94fe8e44264aca9db897e398ec075f5ac9db5f2869b895e886449e660b6f8cd50482edd523e671d709b0aa836c55d70331ec7b78c11670fb286abd653e29fbad2d43b4d474b15a6a54c024e01ae29ae77d3f25fe8b93852086945f418867cb145083b0bc27cc5b4595ae2a910d68a732a4317255fe8878519f7d9e41368e7686edb9cb8b67590a6a3980953df2d6742137003ddbac41932f1253117767a46e4354974495960cef3d69f729e183238b5cb87d3b1d13c5b7418bc6d9dee10a0153364568681f8ef28a67b340debf17e0060a1a349a2a1a947c8506805851b5311c179ecc15c5fa26dc87fa1bf2c2905889ca6d1741851cd813478c565369f7af039f3aa87a0aeb919af2b1c8fbf7848478f3721557312dee8bbb2c19aa4ba0ddc984639e872d4ec1c17a9c94f2135c7c37d2eb501f6f80155e7d314e74bc905eb8f7d8f839f8840e61dbebaaf2bbe1600b488bb2ab080187007f7e6803977d8d42f3a80d9d6a081f8920bc2a791606ab9d44393ec59dab7c5debbe80229b574f3e1c2b8b57ea13b3dca0755bb3e91ce49c4d42e25441a2a08a21012e61d76c99eb8a7d208b8e6f3e7998df6e840a85e7033a70a987b8cbb773e0d14a019323a5bb6035e8a4f760812ab0b749880a25c4a26cd816fc149ccc81325c48a3e6e0771a8761ee391e5eb764acd4a4a3e11698e0ae8ad5bd3bc7ed722b00f2ade0e872fd4e660fe580a2516db26b396896cde042138c248e9128f58af825340be51416967ec3356f7f7290b4b706394e72ed3a0d0e657662429ba42e7b65af064a8ddab9c0f31eb362cfb338052930915ed93eeb18d20c69e68cbc891364b1a9a8727fea6a813756fb1f0b68555a6099b1135103bc5f19e30c3b55ced0a67e5ba849001edc356c0fece3a70a2e4bfe8a6b0707f5083ee81d892195e35a8fde439558afb1c2660a3ccf9815741bdbe408f52843ccff216e1119982b0d4c9c3a124dc8fd8c2d7e6008dded0ddf885b141c7823688b27280f36f997ab3bd355be862970ba74f520a879a34f2ceb0d3b8cd5e9f6d2f598430cdf1a87ec746b91afa408a386361942f8db3043cb27d303925e9f84798dab47a040ce5840a1f30b8889159bbf8d5455abebea24dbf62a2c260ca26d0bb8f279c5426ecf2d777d781a5bfa5d4f6f19081b816ca5fd778352d1eb38d2ef8f79e275d606b5100912bf602809a8f6731fb0f8e955a566aeda5e742a3511821941925211cea762518f7db9f5d9655c9311f5ed45221a73a5bb2f4668be25c25bbbb40d1ff8ab1efc4e47bad4eadaec2c1299931c8da938b7575565110071a45f5216c1a1091c66cd8bd05cf839f73b840ddf6730571017d0632cb26f07db10178690158fd312c04329648e3b4c055ac2d7ccb5aa453e5b111d7f4acdaa59edf74b601aaae33f819f4faebb8dfdc212ac43e14e7d3dcbd949d0bdb455a44fcc24a4914c119fc2545900e7e02a16a5591038a54183962919e9581f44591f3584bd640204a90e1d5dbf0b46f2d0bb3180aa316e0ce0bb0a9e5ad0029c85f83a3fa2ffca793214c0bb86cee1f26e2c7f79ae6678fb9a52eafada9007814961c8002eec07903c3cabab145ab43b8a0c67324ae745bd0c5a7b8ba743368e8f1fea7160294749867e9eca380da9bd051f99cad63f7fd9860b4267cca27e6eb65aaaf7ae024d9ec7350ac7fa129beb4b1f0407538d5de69b20f67f35300c4c19fd0474780a073e7581ff054e8b87d289aef56f066378848a5a9fa24675805d163d5d14c3e19c53bd49cd3078e8010d478134560b365bbb00cf1b0e6191029697c62bfd2a83e85962128b39bc2a3b16146d20ba4bc56bbbc7e3e35e906d9236f7d82ff759ec763a201d0fcc7150a597007ff8f52b79b3ceb5637a2ea1caa72d93b78ac7a2cdf37ee2e5bd272178febfc887dfd864c5e9b77bfa0b9caf44734921719fd4f309f55ba63f0e0bc1d99e2245a6b85cbf743ef75444e69419420a790fd71a6726fb3a1ba809026655cb9e424d3a9c8dc99106d2de077c49f693774a77b83ed8407eaf51ec30619785b45892e594fee7acc4e8682056240ffad88b4d6c62b3b17f383b31ce0db1ac814c148c186dd1500e9004f43ac8e417109d0e2441a484b0b8849f37dd81b137ecc2a5fdf788fcb1d303477510237007794127a87a3754345b1f24646877f607ee05494074626cf70b91b7cece4cb3bc761babee6d3d835e4e66aba322279a57a9a2f1913b49bc03f6cb2e9ab371b1e3f95b86ae9620cd0dc2d63bf8f80e447a689093fb6524e280cb7eef84f210cb0d237dea08b1134c7130bda36b7d2796f373c9c41bc82be001610c70d338e94412add836dfa09cc24cf03805a6efef6bb33d17b403a811f08e86524c935f3c8f7c70b5620d1375ba9261ae8dc0dc6525fceb4491c920671ff686a2fc9210b82299833592d2676837543609917911646edcc6342f44e75ba7a4c8b87f51b441de3c5b3f54bc9a33a0ac77776232017019718dd5242f64afe1cc0b152d8adf7638a31889d753db23cd308cdd0ca9f57f59895f1b59bb2b0b7b25065c65bbabb7676c9ec2ee01d5c7dec7be5d7287a4271b2a15f9a6cb7a3ab8c396ef1c5184ef3222400bfc5c1d14bbc1b824649cca122d1dbba1a7b0a0aae9d693f432155e3004162905d60bc9f1949d86df8a033fd2bd280cb4b53577372a24b7c43ea251b2019684cad5c1ea3b3d45ff081665f1f9a0bcb3bd33521c6ab594ae335bea1820d1bc182805e78a362e8c13925ec2bf3b3b6b0762a2b9dc082e51712a0ce01bda26d3210b3a81e671b76a21adaf17cb8e7a89ba49b981fabf1988a7c2aa5319338232647be8fd91b0c522c0ffb74787bfe6b9919319baa93f94addb407913a51213f12a0da70a0e32e89cccf6ba8ed6ea29c7a2874b1858b9f081f796522410143bb1da1c11c4708cbb0ef0563b8182e4aa64723a88c43333852969ca1d8fffb291de16a3464973cf68854dd4917add6031e56b82d85e13067229827a99c43ec15360683d1b821e0081d784bc8d7f190b25191131c894ea429e5ef865e0e59cfb2c1d62755960893ebef62b7b88671c432182b475514cbf0c893de294258a31b958b707c25b18305c037de9052deaba4f413df1b632e99c288bfcf1d58e756b3ab46805debb343882722067d5a442b9122cb4472acbeeca335651ea6923cd6507ae292e6a80b58a2b77b00132e1f6b5d94c20b0eba7320c9752c95db55217451b7e15a416113340285785270217207d3d7f0d643487668d958629a19f5a3e409bf68659735e4fc760706c1b7618b068aebd4cbb76fda3a5787d7e4528059d7e4cbba0992030cde3d384a4fb2f4e2b06dcc72b8fdc5b7e037e471b39acbc69621f8afb1df46840bddbd8957b3d16a0ba6c541f3e13a4f14c5e138776b93de52ed995391f3a47a1f52c2d7def6c19a31cdd555a731aa281159a696428b47ed0daba0c347ff955e5f80c60cd161167be78b1090ed13314f4a0e35d9d80c4f47f33a876b74591a51536196caeb01853216d8d128fef787ad56f6620774930662d04ccfeed260c2441bfd4120933324fc5415788a708560a054e326037dbe1af2c4e658be21fe1fc273c1c35af6703c17c9e4c3b1759ed0b9b6c7c50040be18f357e8e1b8b077500c3a8b2cfb6a598b764a93c37b3ed5c8ae94b32131a389bebc00252d34ab9931f3fbdf87b47f2cdd763f4410997e0a262ca93ff9911ec38252482db200d2d168c19d2fa718233941c73138c68220232b01dd7d38a464e65cf5f94e87060945a0299afd109fe87bb3075f90874c18626fb27195d61f9c5cf21046f5f1caada09f9981454310dfa7c498e779eee870b203a47a05672855794780b308af8a11518d786e31025be7385bb6a78f538148d5c148de48ba74bfcb0d9c2b77d2c9c376117a58b9c71bed6f07a0fdf9214562c2ef2977a78f86d5a30e3f029bd0ffe53a34ac25ae9246d8cc06fa028921adff76cce4f779b8fefcfc6b2b8bc29d404ac312b95f6450047f813aac71e2d326910686213b339707fd41b53cf90fa6b879a8fce3ba7016264fb329bb783ff3356e05a28035ad7cc990c41abeab940a914c0f66411fcdcb028f945e98ff7d44b60074592b85d5800cc6c0127f8792dc007e498ba471cbe8f8051a9e32ef018fa71d20b0bb805f5faaeadfb2c43913bff80d0f42c220871290013de5d67b7510e101076db21035d6cdf83b77845a12bcc0f6bf77a98eadac8d529c706ddeb7bee82bcf963df5ed0dc32e37fd78a744a6c773505b9f3091ea8c6acda371b5e82125e581a157e134f3cbe0981c69e0404b4614806ed811089753f7ae8fe3bbd7b5442cee132bf48e11a24aae7e7b2f9425c965344a4bba13b02e7bb901568ecc213823c99ca229e27e5a142d4b7ec31db7a32bff11a7f46858813eed987495043d6546af8dac515ae2be60f9bf7bdda1204dd04ef721376e1aca023310b58ab2186401fa98de5929e8544c5f189ea38c5f00da40f14059243914d8bf8918d751270d4797a84c99f68152313bc7a13a4ac220d9a71948c56edef57d10bc43c357e8a62a884b4f4e8eb24b470cbc760ca2c5a91e0f12012e4314d41e0f4c46c1eaa906dbb0d8a57a39aa2ac9ca3bc2a01fef344df817673ca6b89d54048450d844291b7173ef96bf8aa760b33457454b19165edd0ae21cf6a6e171bdfbc356da153cf5629dbc40fea18d8148b69c0277230e92d0c357858632438ec00a8e31166400d171a16275b214d8d7781d5630277c39b7a2aa2edd71f7406b1c62d13b404ba496ea3d612620eac5260806fa3d5b15ef0586e0cf2b18c35bc5031b99ea1510b0996c2a0a12ca2c319cca52b203f94140a484d915290d7539b4d34718110baac4974094f1ab486a1883d69e70db5ca49060f3fdd572937ffee6b3c5c90b561f2264fdda33905e38a689ace61d391bea8814ec2b6ea069473dd3df84a13214acc92372c6cd81113d6d20c1cc38b8bf2d30208c5ca110a099b170d5881b344f64604d9573396829859f491a50c75239c635b9e63a4aaa5657e9025c5ae835d19bbf4aacedd1478128763dd86c82d82b0e77318a7e24e0678a7993b7c94e3e79862808e45cd38da0635f14dd123da412fcd418d0ed41efad6189b8c796a04c81c449c27b6eb7845b75c3a314133c46ea17d2d73cd01e07414208379f8183f82579a54329ded504acaea21e5df55b3179660fffb93198fc3e69868d28c2ac77fe267fca5b626fe510367bea0b058928be978179c06fee4bc155ef4de2c2886b5c6c494e5b8232969a9b9f3b8bdadccc4d000eae4dccd1db35f0eb65560c185421430bc5f4deead7a925beef0c69f340e2658a4b21564db88ba78c97feb7c0428c695bd11c33c56e2818f4209dd83cb8514208f5305ba348e9b5495824a2ee5c2fe7a99171d6a78e4511d2982f0eb503dd0d386a5d3d8894525f1b8720ad15215b3e33a5a3e20a7b63fad19f74b516957bd871a4de1ab4888440a407c48da2401476968fcbe53a006713a1a6605308701a11ce918460f7fe9ffc8648a7eb40fbec15e300a331464577cf8528b889f75e09c4a7feb0f8d5943b31c84bfc2e6bd83950826f9aed12824f7b1db0cfe9380c194bc28d05e89a152bfd186947d721223a27c00d22aedf8eb9a6e37816b93e436ca7cbfe49dec035d643744eb42e43e88f034a6eb42ec2e88ec3f0976fb7d2f8887fefb1069f76c66c722c878fd9f84132f3fcb0fc634fe02c3c5158738dcff97e3e8d41c371738a7e67294f6c42a07e8988bda5120cc21d4f0b09b66034aa91b6fed2566f52a2f334dc4274fa7522426fc76d9ea08340b6a8541e82dbe7785f5a73c2e2452c870e4428611a60a1a2a1d5cb3d3f565b929390e216868472a9274240052c1743033550ca238caf5dbbd5d84cff24d1e0b7ee0df008b268e0c5fe0d12218a3968f4db5e8d27aa4877f58b7840b1fd4932f95bdf7ff67b1ede4497125405afcebbada70eeaef027cd8b78bd9a424688572e63eb273cf153ba8dbe9ae992530ee8ac1e7e8638a0ecdda0a0165e58947af7bc0c393b81c2d06ab0de6dbc412bae67ef539902e2e8b59d29aaf62bbc2fe815726ffa4e3e37e888b7fe25fda54e2e38bbec3c08c0dc83ccd77d607acb0de89c3a3ad9a3b76afe253ddc84ce965f0e14533e81ffd0be2e9dc36cc2af3f6772adf538ac754a13dc8e6ac6ae607000ec93576f5f6068e2e80c7a0d0d0fb2f9745d2b6b133af4b6dbe70cd6e4826f8029b5d406afde6194b430e90ee2402c226ea078d175d3259af99900c0d62ae30f34d44f3c2c2a273b59b0d2f0af7f8ba630c0faa4aa6633cb020d1a1ac9a002340cdec88b843798b6e185fa3e682d9f1f5584d7fc6cd80545a482dfdf044705b092507d5a9b12090382ec08e3b50dc9c3a3461a8de7c8bce721b1b312a9819437f80664934936561bc380312c05069f882f3cacfd51f6cf156ed5b7556955134b13df0a1f9bb4374a4b23fbe7282af6284aa156398e35508a9a4848c15037df7206c9c4936b8707034d2b040185734dd42c3c8e3e1df86321f0204565425952bc188e31ca599ab64ebcca404f45f37b335b67aeac5c8a3ee172f18e78a73053d05ffec796b64114670edc866e54ae8dc6adaa9780946ee94846a845ab6229e89cf333962fe64b7c9feeef0d83aa9937b3437a516819bc11a1824df83aa797c61d4db7a2ebe0384b11778e6a43f85191362dfa62434fbfcc268718b0b459e3580ae685f71d2220829cc40bda90c53527bf314e59cd6295fff4953d9a929065bc7b9dd72a55f1eef915abbcafaf99a9def6b8f82217bcc30dad68a22329edd8a6fb3ff3cf515b437eac8db0fdf5cd6fb63d0a06f68810a4f026d32127b30a5ab3b0d2d31f745f99f746b7630520f9a80f8247ae208f2486e4b290a3539f231e31e8b109657e3fa40d82749538f08860226cc03469318291642c706217553b5689517b05bb1368354d710b2337e1f19dadd889cd59acb180b9be5cf5e14a5964eed55eb1fb52e74b7261736bdfb9ffa5e3fa22aad275171cc10fac937c25f54e28e04c6429878232735360518f5961b9d40efdf21e0d112a8f3e924622d42e99c6e0a851f4f31247c2e149c95fe93624f6ec49bef679a591f793d50bb6552852265e5498959e50838fd8d7b47edfbd0915ec3f1a5e16230f287ee9d462fffea2f7a9e366f5d28f04276136324e0c017e08dba938078696f5cf764bc2dc657c29367ce5ae6fc12bb522904c1e63e7f82970df2fcfe8371510e31990b754dd3ffbc1e17849370ece8cb5b4126a96f8699cab03e168ac30738df688494c8b498e83c257282e892f6e8cb6618ba0776c16720bb1146c28942c2d2c0db2d0d420f5fa24644962c97db6562a1c9223cff7fe950d3fef072ad2d802de3e621dca5f7d41f5af13be3766683f80ae630756e49f2fdd647160b9d767ed25bfdf47c3288056a80ff5a35129ec68bbe878df2153c40a41ce3fa0c61174582f815a77687abc5705e56677993238dfab621ad139817de384aaabe7f8698b2da3b443323710b2976222db96ce7bc52651da4890a080842691cd6c2d715190c2fd73a5898ad84800d2b493c6fa8c0d4b1fbf85386901fa89fb42f13345f646176ba5e055cce527b150bac3bcf3e15316333973c4b84a468a4f3f1085d33a8660c78fa4d3e6688674beaae6fc7382368e1ee807272ac31d980176c5c2ec79c840222201c487a268e3e0e5f3a03e7493cb47984bf9043fb132321fc7e911354f1315d2968d9ae32a2f1f53b22449ee4403ddc35f93a97395cfca08d578240a8197cfdaac3097974fa908193084b4e83d7eaf7af28d21390565f9d020f5b02a0ebdb67b80a8ad514480993583805f638595e295878382518ed4b0f0175d7ad6787636eaedafab71454c5ad25e6940c4c5dc47da4a85d671d25310183b19c2ff1e6121058c0bbdfc7a1c493e32da6edd96f535ab030ed9a069c23ec7760916bc49e1c37dd5384b21445f67d6642124ee81e2bc45e80f1ab63b2e03c00be27e4e2283b005189b1e44b25cbc0e160ec72dd38c7c1bd86eaa58c77b88e710544d425b98579a00ee14dd7efcebadb2a431dbcbdc4a4980d08fce76b51403cbf016ce3cfe2ef1e64d983992927baf62401f3b35473a9d7094fa2a4639461af1c0ca82252d0be13e303bd4d08a539d315e8d6b764db18331dc25c0880163cf6ed426fcfbed7d1c871d214fd106a1a414213d052ddc820ab457424f8565142d406973f5c62065ea6b0611d67d79351d772724a4ac89e7c90c3db0a42c1691304da36762813fba7bac601ab97b0b6e7364d98f1813fb812b2d943f7376e1a3528f06f11d16bbf20f40b389d9fac6fd0db3d0b70e05a9ce45802b8218ecd3e0451d31628a4f3c47f17f25c44436d86b4ef5e23c5c06b2175769bb9f4ad5b573077ecd62be14cbb227ecc1aa16e6885474a20488004b431593eb6e000f8df2e260e7fd8706c8e070942ad6858cb36429438f13a7de888a109298ec03e0ad9508274c94a0dd8fcdd27ebb47978f194a6ad1e6b9ca0921ed9fc18dab8c29d4262910493178a0aee063313b754bf2601a0afcf0562b9de493977a5fecde2bab3c8499a7039f9e944b03e46a2212dd89f86b9d1921d24457a01fe948c157d03e2a9b61b81ae3232252a8f65e53ad6ca2dd0caa6685513a3bc695bb3c4bf8f8738b39b066d97fbdb51ca1dd62514218c536a97aedcb36f75e30008a7afb98e348995b0bd6720e136f554049712ebc931ec0dd718dc2206703f653ba67f4ac546ecf14b93fd82748325df1d4af10615c8d890c6ffd073bceb88b7cb178e877182d4a812e7f9cff461828a704e460d8f2cd43f4c81513164593ed9a35867fb9a130d3d511f56eadc0e9594a7c49829f6c89cfbf69f4b7d90ec8565bdb217480a8e4d5824a610a432f9cb169ab4ae569e551270ad55639432e93b30ad70b5a6068b979690a5818385b6d4e671e63bd7924963e158e611671d3f9452ea8017e739aa42beb658898b793a03c474181963d75566972acabe56f22c69da7021ac31aa1f14c8e9ea004707bad09b6a3587d4e8075af45de358ab83c500ee8e30b00966297e4673b5e4fc22e294bab002a25dfae7ea8bf2331788746bd53e1778fb3114f5ca3f9ccd34a9d27714f0f2e284c2a6a7d6e2884e66303ee0e561d8910a6c8795e138ab864e9bbe32455801029bd694ab63c7de6697c87a06d44084e0cb6e6b5e1bbd101d382b8da477a7e7cb38c900dbbd59b61e82b268bdcf26bc0852a4492c2b56bcbc793cbe98c373502c4c6b407b8a0bc060242bf5376bb81e7e9360d976a6a84f384adc08fbdfc57cc39dbf38c32823f5435e0c8a0102cb84684e4adc35b63449ad5b452f7638c77bd216f2430d1d3b633d7df08a502e883f7ff60114aea5ff390e20412a0c76e0e7643c1f2a7576914819c200ac67877d86422a506deb3c50b58e546b13312d8f3bf430403d1d99558e179a617a6c01d7fbe178a571c35a24e23321e20616ae6da444af3b8af12d6f1a4bc899312ee6b8737471772703484bc79c28416771d6cfd3572fd5c83c8864d22381ad807d0829a12a21f844ce8db77dd991aeb97c2aadf7c4f97915d6042bb14353dd5a7ac435b56169879ad4b28ba23e98c674b7c6e40d3dec2d20bd20bae3d4169b12b653a42a900d5ce6f959e494aa1c82aaa7449e23f90d4b591bbb11c83f23f2399016f594dd9043d418718e63f876d58a13ea4531bf66ca01f632a94a7d33f99b0dea396396e3472777f7be525edc096b24070ca7b20661fe1bfffbf6c7c1252c436ca503b2f62c96321c67fb5aeb0cba45eb9fe09e597ebae8183927e3529b6fa104fecb2c237d91c1d790f489fcbcf9af59feff0a3e0930157c657ebcd775d67c00ccce9396badd30d87adbd82adfdc977a1017281cfee1d43b5c15ae1d0e7925c5af636223ecd9f176473cc338503929d4dacd0f3068d9e8b4db57bf2cdaea89b40685adb01744d726143fa115cdf2fc2da0fec667437b09e8d2b5b67df0cf71cd381acc031fbd3c9675b950e77cc111d3a11c889158d824e65972d91402f1036b81f081ee0ac0392be5886efa19d49333a3020705a2e65cf8100db944e6e568e6ecacc7c969c1b0255188372372a9dbb6b2d0b2ac089e54efe1c2c47945a19872508a453371aa62dc9c446b97487a7d648c9fea72d88588c6291a224175485cc721aca50b8e1ce4542ca0f982153acb098026923e64e02d50c3d5eb8918310875df2170c62f58fa9d338f95992fd4d80bfb3b95ea747caaf9712bc4ef2e80809bdb00c581c8f64dbdd33300965d7f3f3239d44eee53f38511004a46c648235287fd5a801eb487525f018263f28e4d8673fb055468fe0f5c36bf1d4a5c8b55adb1c3cb4a232fc7cd2e82571dd518fdbd320fea73e24f25315642847630e01ade9a09e39220c8679571b0316f20ca70386348680b60f7a586242ab7e27f8b7b843caf1cf18ecddeff1300e6dff98c9d9b1e20916c4b5be775ab87719664e6a1388676b7a364c1eadec2051d6aba8e24dceaa7055b73dc69ef18454119fc35acaea1a330e569a660cead5c79972beb7602a5ba0d48ac420214f9b1fa813b09cc9896e4082cbc59a9efadefc29f95e306bcd2a8fe7c03618c0a3be5bcf72eed30412b88149c5f877972896934f6b07b005cb6387e9e39be17f6c08ce98708731b27f1458921a0599b9e2d668570a7276c527d6262cb65f4d998609b7b303c22656e3dbd15b0e7ffd071dc247ec0ab871698715b500757834656dc35d2841ad8085064520f30780af085265590e613cc3fcd7a3158f45209bf31d58acdb4f9ccbe3f5792679855b5563ce9981a8139a9f8e44bebc49de30aa29e09d084058538e17755be2554577d871c008eeaeb400a6dc07c1e42ff45e6642f3115320680b73a2fd73013d7b2bced707229e7031d6cc32dd519a23eef591412289a13386adc15427e29f3de0e70871c605439cf7998011c1e3419d30cee990cc351e7da241c5f7f4a1146eb1279f4eba929030139e283df3b80d44850a5ab25588c8cd61d73a8cbc03cdfb371df0adfcfde602610b4df25577eb51ee58a0f3b3dc2e199fdf4fa08fde5890f53204537736fafcdd0e0eeed49cd2726abcffaae29dbbca545c9a9ac65878db4842d7db90ef459803df15c1666d4b0fdf6593f6bc017345f516ec4899445af196df8036c7db5082c4c0176ab04ce7b8c32400765c633c7f363275367849d531bc9d5a401b629e11b337ccc424cd0c5312a2e525d1edea3ef63d80c5a7b945e963235a16f18ed62e02bf889e7eaca8db4f267036351eed3a9025d5087cd9c11160bb5ac15114925cdde19707b0f72d60c5a75df73ecb449c78637b5179f80c4ee19ebd4a14d681635334ca502a1288c83660474da7900f2d481c0d91b16d9033391648e59753d74cb548e34febd440791827cef70fe77d7486880eebac986fe1db3c0927e1e6c4589d53fb62b2e00d2bb01979db1fee1a106656905f33dfc70edac2fce24895de7ac0f9c941c4500edd496066fbc4c2e8dc561faf19a3fe8b17ddda2f0200a0bd12417ebf0a19e2848ec999fd76c3d2383c8555d7a814ca7291c55e45bafd16de56da870b7f3b6c203a0502cffed07ccaf8731c177601019ee07153050425d8c46d375735671e4756040464c3d0b4160c03ab1aed17e8521a2b9361e1577a7cd79c1460bf60eb38a247e4b4e52eb080a43e54483a3d2f22a58da1ee1a0589d933f5bc7786ea02ce0e23b2c42af2087f460f4a06d009547316288cd2a0b5f8def0c9caecee9ebd0ea12b06df024298a9a6751d5c66d10a30c6780d5d51d4029fad2ad60d97ef190e774bd0ddaa46211f0274b5acf05d769b8f9316c414f4ab524cfd9d3ae8edb6422365969d8b3f247f967fa51d768e0d1729fc2a031ac8eb5a2cc1611c68cc6b8b9b5c83443f6e13d0ca6a8cee32ea4b97a9203107cc48c0cf86db23509010c470a20c13fa61b8bdf055f062e5365af9c58989645259f9efdd047c8d02cde11c91bf291af1260eabb38410510f97b46e21fc85718c4ae7b7f90189bcc7a1a8880da10d44d76e8766d881c90e0c86ad13258764663c99704a2de00eda3ba4b52271bba0beb50b2993cdc5b081603e3c5b3f658c5ccdf9f547196232173fbf4cf69334beadf1151b8530994431c743cdf8cd407cdd0c87b2354d409983ff7614ac2c2b6158c83253a448620b314474fd7fa4e9bb1ce6a72a4584dc4a0b87b19dbf5563c01a961784eaa5acdfe35e1670879d12f7ee014bfbd65a47c45b478c726a104856ab24a4959054395938fd2438c65e8bb315657395283fd1ade5c2d9b16baa26c2e2129f30617ed4f1d0dc38a08766696cfa4c6e54b7e169928125c60210ce81c15a6e53fffd8f1509958733ac8680847e814e3c08e535085f60c9255e9f96d98949d4afd08660b095ce456a8448b81439a144ed2c4d78f4190f53351fcdaa8663105fe9aeb307b893cde70139e4932089aede8d17b55f21ccd5cae8e4d1fc60f9f665cb5744dcca3aeca0ce46e4b438a284f5cf4cc132cd4020399d271934ef0a0dda742cd3239ec070309216a3268820cd39fd52a54d79f9c644fe959204c67c463042d777aa99172fe372ae2a57811141271990c7a751ef7607ed1700071468f275c5b4274c69c751f8cd45e9c14b25330a149b190fd908969691dafe58fcdfe2ca3febf1d8249233cabce78e27fd0882446a58d24b0a91292c4f2aeaf350218382cc53f80d1e3fac47d3e7acb4f002a75fe1fa0d89442090c78bec3ff07376517e43230106eebded70b0f0104ab7af3fd345c719a383b30ef4204a18f3414816fd5d9dfc8a496074e2f7ed20e98e0495f521973d7dd179015cd7fd1fbd01c2dfba36c49c80a501ae1e2628872ac1adf18e2764fb47b9f7d334400f8204ca6a0794b358c98abde606a540d6e0ab38c7ae71c2dc57071e0688c934f67615f20e9ff06c04f6c00f31caf4a1c20483386fbfee2eb3c742233622b68aa5b0e8e93c4774001263e7e80d1c209c10e890236c85dc3340b913f71682eadc941a6f39fb4b76f3cf70be21400cf5fea3f9802242f859add183c7a65cab1eb637bf1157e0b52ce749d2831ada1aeb41278b764704f6bba78a092afe206112d6cf6f4fe061f3f7d4accb5b4ac4a9f0767d9f956859691d4a85a4c3ba950f121059cd28e47a3c3f9c87d9f300c4b0da0df2e1ce1b47c164b348b4fe02d82c6ff80a8872b18c4f555921fbd4c00a42b91034dd09deab9014ab2ce485ee1169f85606e6258429173fa52240022165546820c600fdd5d208c57044f404a0fb296f31d878e2f6246a8a6e55f6d6340e62d751cc3ca2b94c830f742dd7d3090f85cccad4c0af6523a2209310da1e0f2a12e1d63cb139afc05ccb753f60d85069859e6de88ea46bcdc84156a99c7660cc06262ac7b773d6aefdc024836cd868bffb19a19137e832e804256ac3b4410a0b9f3caf4e81f9b2050e2da16c870bc57db91a44f457517cb647f2d26e567a076dbd97d9d0e33718d6c9d059e3c495c9c3b818bda8b8144af8a35f638119941149fd59a293ef8f5871c326abb90af5ed68302fc77d15fcc8c473e715d8252b8b3d0632db2d6039f671628616dd08700682d3ab1e75493aa077a14e8e72e0cda0a0049074c950aab10c5598cb09aaea396401d37390ece3028d28dfd8f28b43af138c5e1c6830cc64c032a8730b0f8caa96879e2b8ce549d97103b06ceaf15d5235312b7e958d61831650e3053c321185462626e622130d1299ccf2ff638e4c096c2cfad6dfd294b2d0b9042bec26f4c88a0efdfe4332998262916c6a92280128e15ac06a315390c0f6698801215b9ceadbe2987443c840be6d5d9172de87d1c9614741deac8048458f30d43e5f9d875687b699c447e7caddc625d6098422e83e6f81f445f2d67582a1354e6d8690f4777be50c95280498bb9694772710e0201175f753d45405daafd97644c884bc9335d5cdc24736436d69b3d4077bd0ce330ac42e93e3983d75e451e5fdf6a34f9c14d2a7a639ede3f53847e69be95b5e4eb167e03a1ffef358b66d1c816f107c80309e3675bf6b6da72e663210a41e8db04b11b6f2d44dddfe9edbe15529bb552c0bad521cbb1dfb6715c99d969f920d4f15c9a22cf24612b09b92645559c917156f1c85a47b2cbddfcad177f4853852da133d5106df008285be9634aabc46514ad9928bbc2410c6284a66923114305667e0c60ab0432845f79c582a5d5b9f2c9f34dbb01be59f5ffa90b2420506fbe9a92b3905659195cc94dec512870c031bf309f2dda3e9f5abe747239036d8982b7c789f1a780f8ca40bc9600be3ee6a1d0a9a0b9eb5db412888d855cb8cf7b8641e3cb135851887105e91394e8c1e69e0d6e92aeaa3020c1e7992b2b49685a9bb185af1cec922ad26d5c19dd0dcd80d7238cc761b92b7c373762a5572baf0a4c8ff3d96fb84fdfe4239c622d49f5ac71807d4fe9cdba1befe9106cf3ec274a79fa07ae2d2c24e7c46c68350d910a20c953c005489f6593fd4ff2be78a924ddd61ef09979cba63c72fe0de7bf91eda52d4bae211e763431a3b8f520ee4fd9619b8e9292efa827b8f6e289099cf8572339f89fb06d901c54ff31107377213048789fe9665925066d5a8423c65465c073fbfd6cf111fd4d40bc09317a32a13ad7ab9a87d54d9c969b8cb693a47534d8608537860fd8e3d29abe0d0d481a092e891b33aba0bd834d5d3da005ab26a6d784767fe2479d63e7dab630cb2844b32e3f2211179d1fac439bcabf1a95d007d5f939cf2469875327825c5fe3051b3517c0763f449718b6df265c241f9af4293a0bdc43c0683d897b29d38884b76eb8be20fee615a640f41efac3474dd54bcb5021d6203a6c1de137f1d2d7f43c3fed84161afa7de3b9c98699c515304b8b46ac6e6fe46b3467f9996334fea90d8e16176de18d5c3c958c437a0abc60210fb15eb1250e2f2c9f4ab3e5199e0c144c2500893fd1a95d5830414274f9b62b712ff69f84314653e4834c84b6c4af7e357c22ac7ae59fffaed444c0e86a5e975784d7eaf45d81c1a20467254e9036edfbbd70a309b60c3737d6ce40bdcec038aaec2835630d81da5037e1fcdbbdcf7d17cac959d1a1270311574a6a15f02967431a3f97e6eaf45c9264770918220680705ecdcc71b0110265d0c33dcab8dff6a3076d0b39db5d6ef5baddc7e0a67f1a535223721524a995292290508ef071308598cdb1bf70ad4589d3bcb9b9bfb1e7513a28c1115e78c538928e7e984aa62f6c7b92e258b2c66a4947306b538fda7530d280d3f33ac09254f1e1f041c458b660dd4f6d911d64065d6916232372d380a94201ca13a5004c1e874e29bfe191df8b7a8b63f313693c46ca84631d6bb7b6547dceeeeeeb2fbb6ef86a87c21a9c18399c9f5127dfa67e474a06dede7856aa81966d6a1329951b30610bc074545353f27dfb47cc64c3f338bd38f424dc650365c61fa67f3c458bf379ac5e907826b36536788661627aa9fb35c51c54afcd64a915f0ace3068f8ecf7f5505d6a6f1ee977fd9af1b7b2648c8952acba767cb0eac5f7b19e408616b37d26a70c2dbaeeeeeeee02f9b88f4fec95b3141956389ba4a09c8f0c2b66fb0ce56339d9d4f958ce9b5f7330393e6be22db3d52ca7f2e7346e52fcbaf75f40fbbd86d821aae8b0df2eff21dabb8b46bffba6cfd8f378c2e4d2b3bbfbc58f193998d98f1ed6677ff6cdee7061663f2aff3e739360b57bb359ac3732bb32dd30c3aa66ad749a75a954fa205b4bcfa492681685a8b2be0614cd5849cf4c6aa34abac2ab35c19fb5d0aa86b0c26a7de62a94117e5b9e9887f0ca8e484cc2df2593c6d0c68be3de44dd55f725eade632402ab3bfaa02402134460a23a77d118f2ee9a80ac7ef97427fe5a3eebb3294ba6cf6ae667a9ba99cecef6ef624bbcf290560013160869400b28f84115222cc18729e9ca64652530dff488ac934a89f133c685f14d65d30fcc557365cacf6a625c8c24332535c25624b621deae6c49350d715ffa76fde03e96ae7d520e4c4843dc7572d364cce37bf7ede1b50f9a7ee07b6fc8bb66508cf9431c58db5a6b8d496bad88d61fe8d6da88d9d73ad168ab3dc30cdc64f8696dcfade9c0fa353193d696748c8c4498994bef8b063b599cd64cea0e2c66fe3601d432e9d68eb0defb547d6f9f63ff28d4e4f67e7ff2b0383b38313359e3fbf64eda111178ef0304b6870e2d6779e06a874bdb691d5e0af5b608ee3dc6e5b25c6084113a2797a75b9017bc1b2fc15a186b6cb432d1da33d4aedd1f4361683b32dad2a3e6f4ab8d48f1e28bb730d6d58823bea9467c117b8f702aeee4dac2cc7c0b16de42527916fff68e454b9163b13ccffa975957d67c6869abd054c4fd9586186b10be05a913f995166a2b7c332424c4aafe95e9dd09fb117cd346241fbac22abfb046c42ae84694dec6a366e820d2b7e91b0c2056c55e99ae366aa31f8cb03c1066ffd62d8d8b526c0286972e5c34610c086f473015c69a3b599cf6436bdf5658f543f710abae2c8f4ff1259a24e623cdf6ca9a6f31b567fdbe85b106dd88b1f6f0722e186b4f673033c94b6ca9eddbfb1656d1e836326215d65c9c8bd2b7772177d22b76c2deb4a742d4c20403aa8ba8ad2d7c6fd2bab52d6cd41a4b5da25269448c5d69435c7ad548b037ed4951864b66a3b2160574603a89f4a46e4344fd33c61849afc358fb60ac630fdbcb632ad231ee977e6b693bdb2be8d4ee426d5f28b037ede1b503637d49e7153ad30f12c664d0e234927fa959abdda4abe1931ee6c0d83e4947189374411fdcf3d08304da97cadf5aa68631d9defa3662158d7dc2181396a74dd15c24d5811a614c7ec63d78899613d4ae2c4fe9638cad91ae0c6b471de3516bd64b5ea236120c89742d61e26362d38f978a30fd12263ea6779a31592154d2b72154d25b97964afac1f45bfb4d97e949145e264ab30c00d57e137fa4d9d76c7280db1475dd0a21cb100f9201d0845a6bcdb39a20d7c7ea2da7df7f875ec56bc78ab134270985baa07b93477ddd51d5b966ad725b1c7ecbb7314cc6c435a12b743794eeeeeeeeeeeeeeeeeeeeeeee920f1f78d582baace0c3e7191a34ccf0a81932c8f8f618ab4e1fc3c790f919a382f9f6405a6bafc30ebcbaded4da54a409a9f1345f2307c680a0f966a10e126a4142a66fd37794cdc69b28e99dd67847fde3c3c0fca4312f43e7c7a0321f038df1271ac3cba0a79781caf819548647d1193f0345d1d024440025695f3ac6295467a88da741679e064ae367a034bca4ad5eb449951a3404319aed9b1586282d130b6c6054d8c2506117be813f270ac55d648615c9cfb80b5669e856d3f5d6274152e53b53111311d3b7e94d343436287bf9028c1ab4b164f1616f8496272e7b8140b42a6968e8563ea2ec8506651a28cf401b887613da4e5a06fc13ed27b463d096a11d6509c6a634152b571823620cfe451b0bdf6809d245e8087e6243ec81b1ca974e8d4f22c548b2e184d9beb26466965c84c45c7ad29748415098a3304fa9f0b90b77599ea32ecd4a15b647736273aeb03c0d7ebc1a55225553bd9a30d5a894f5a56f42cd4a23e2cfa4101759540613bee54da80939b1abd93b71f05454f85654189fe3b3dc9d5daab72c73af60828b0a4d3f3bc41864be9a1063f0c49811c6daef934131c648186b6f142fe622deb244e2ec555b54cb221a4cf3767885ea1bf891080631b115d291546a3d4cbfbf306f59d697dcdf63a765dd0aabf849ef43d5fa1884d7d227b1e28e65591f2d2e31c6c8592227113989c849444e22bedb1527b137f0e3ebb0caf4315aa6223096655d9665997809d6c258f80a5b612a26d32c992e7e62b522cbd693a4905e6d9c5292ba08711183d1547a0913ec65ec3f32333333333333f30fc7384d9775912eebd9643de9a169084b52a4f12e228dd45cf4505b619af9930aff3111d2b39591be79b11e34a78cc134e4a636178c41a7fc30cf5ff26ff2bdec587a89042eaaf5d1fa687d34f547667ed2cbf8cee55b25d39798d05271d4bd828928557e3402951dd229cc37ea6fadfcaed06ad27bcd428d35a1d5e1edb156535311eeee1c182bc5304ce9d10f84573d58d2bde84a0f48604c4713f58fa5523b47466248c2a32c925080420545ce85a00762cc8e9098dd77a8ce43754ed547ea51a3da61ccbdf7b8bb7b8f55f5ef709c3360302bbc321d1e65c49ef0e82e4f2b0ca544cf9147e91d863883262598b72c8b3e1fe7e33eedc33ed693166d3e263a89c43440cba44124a6ba9fd55d34668d5609ba9f55d52211cfe64ee6d16fb9ef61bf680c718ff2213b14ec73ec9a8bb135e08969fd38c7dcc5b99273d039e79e2b4d12f4947329977229e7ff1c8c3b05eb747aeedbf8f50079ecd746f856304a9e4e1518f857d0948cb5495a252287eedaeaed849a89b08ac55baaf7773bf5da5a0b445878947ee2c1512495ac9e1c3088722a619e3cca1c3394f052831c55debb131209d2d723b796726fce3d998d7c8b380723bd82efd71ead911509f48d96231f18ebb761c56c6f646121450aa25125dae2511ac9b91e7de789d5daf4e34327c78c81a959527c59a280bf846ffa670c4cb4160cf94c3ff12d599ce6a1878704f8d6f3283d0b6cc191101a0b3b29cc9226233e746e10e5dc629e3cca233e649c605162023eb4c0ed35662cef0ad7ad4474774f3ea81365c2478a42d4f7624c01b9bf482ab9286716f3e451d674c03d7a366573095d06d3dd65c099f8bfe7da1767117807b593942cc8507c6305136617e7fd6b6ff9dc2f25b03ae89e83edd125293523a546398d304f1ee591991a2b4ab0c404666ad0dae36fadb5d65ce3d38c974e33ae8a7ba740c04fb2040888f448ef3de7dc251d57e78ed9d520ba47ab399a72f7aed4e2b4e5d99aea1b58f2285c80b01e1d6b200049d9b640e97ce9a8b29a19ff1c2d57555291dedfbf694102b5a34393b9262ae6ca22ca244b36aa5fce0363fdbd830a04b37df425cfc8e53c412da62b4554d0528162115172d18268fd3d4a1fc8b91e1dd581d309cebceec772f04aeea4e049f3bd04f8a6dfff716b426acba136a6eff2c1bf4d8bfede603b54f7bec751f3b9b84f0730a2ac12c9b5201c0f3c4a18f7f37b15f3ee533aac8a3b52106374ee0e46c6e7d8cde776203b1174e70edf3de7d5ecf75e47ab642de63e2689abb1614a5769719c559d05aa7fa9ba20aa7fdb5aaafedc83d0b9e72e10f8babb3bbb6f33c6391d943e80340bd39ffd8a72c2482a593d34e821222222221a824b718e04a7c025cfe17b1e448bc0d71f29b5d1b9142915535bd663116c3d25084652c99226234a1e13f3bd4723d7635b94da292ac2aec7f7e5cb97209ed5bc0ad195e23ae7dcf7f07bf0c125b1216ce8dc7bf0a166c3c05a23f3843a9d5a0ff77ef994e9eefa3d0e13d14a50d5dd07c18db725577172dc44f68b773c6ae9efbde733e53c6564e1ac1e2790e22630315326064beec9124594323306c644812ce6de8855b4ae28db2c1e63cf62eed945ce9628c6df98050689212c64a97e6dd18a56894b91be66a9543f6f4138e7be81e88eaabbbbbb94197b513d632eee4cd4ab76d243bdb2deaf3ec247d5fd05d3bd9db49376d2ae9dbc76521b55fb2706283672273ee22e509044e4a3232d7c05443e5fdf1c39e9ac0073106b827bfeed54bd8f78925dfaf70f9c7397079d6bfc3dc36e31427727d557b303091ba7c5e99f3038d576ef794d75b79154b2a4909d25e67b8fd20a39d7e3ce0e103c1580ea24b4e0d72c0f096b417cef3df7dc73ce31262ce86284104208638c50c21ee037081dc946f635266191e234bd0c9d34866e3f28a78319828414134beca713bfe61ef7cfcc8c0aae88f02b3bcd9c503355fc37bef37ffefb03fddf0554fd92b14fa819973ef0e57fce39e75c1222eaa9bee6fece3927a6638c6ffa4f3d5970e74178751fc4989fbb8279f8bfab29b33ccbf3524dc8d02652e62d47df4f2a2386a606c00130d49986cc2ae387eacf7a18faf6c6c154f79106016be95786eab247690c81f53dacefdd4d445e7d5792fd524b975b9c16df726d198674f9e2389781eadf78b867d38f431753d52f7f4c48ec9280414d36c6326c71cf74104223252bc6cca294e9ca76a491beb21ee75c4f47fadce541cf89f7d8f42361a6c4bdf74aaf879e6ea6215fa184d1df7bfe7705e16aab5bd3598812658c33ce2827638da5ba67d3694696d9325494d3082bc6bde6e8b677c7cdd47e7948bb9474e5e729ec7adc0823a9b4f33ebef7b833e30edc914490733d420cabce9803f1b76ff6a734b83729647377c75e917fa51baaeba87e03e9ae66ff62a9ee3698ee73075e19ea5d0db3639566255d4b669430db0edd286f209af3c512e3811e3061b1b48703a01409c5ee884e7dcf05f33d21eed6e5594857f6d5fdd9346309b365279d188cae6882eb949a17b5502d62b6439a31c91a135ad114af7f2e4e7f6f6002d1ac663a402b722e98c0a815b55091e5bc22a20aff72c7f0fbd5002d937f9fff07ef96e5a7a6866ffa674d8e1a2c872f633d4d526414bd1a2c47ea28febb4b9d273c4a129d7d337bad3779ce9e76f79e7f73e7178d21fcfefc7e4d00556910f11f681071ffc35f286f2758cb9807998bb3ddbd72efdb37cdb9739055839ae9956ff595c58731c62bc608af756f8fad02a2ef951577df7bddb7bbfb8a2dc6e73695aa6e67a73a7765fd631fdbed27c2b0777676efe155142fd797f5cfbf3de75ebb269a50e0d50e54ac91155e606184e82302a007d672f833fa54a9991d67a4e5f02b6071d864f4aecc777a07bedb51c0f280d1729e7fe2581e7eace7f4cfda1737b2ae6c864b3bfe06063ff3095e594ccd1a1753cdaeac6bd6bed41646e52f8bc39f431473680ad13b3ba914f67d6528d49cedfadbefc04651648b4268cc1c7be55a02bd7abf8f844bcce2f0532db37d4e530f840a7913a541a4559a6f9506f51250f27c68ce579afa1ca8909f81b6da83aa41d5fca0394f009a7a2254c8d3405b1d00c574f86d78a63ade07ddf13d68ea0d4085bc10ac6a463a9f352e26d30fcf9b4c3f34decaf935fd0091a47da93a5e49ac3b70b0d54c82c1f134a60324695f6a8ec7f16bfaa9a119b18a8718d3b99a513f6939fc365cfc9610da4dec0d7f8a360d16e3d7415bcae2f0e7d086c1623ba81427d167c8eba052865ca994dbda6afb1c9af7d4d35c0dd03253bf35e75b4e2af5a94b12c9799aa7b97ea04184e6539fbab21f4e8cd1e4c42cae3d861d9de4726847f11d14082537df5388aee7282d8763bd5a89c581df51eea0aa4f511edf4f5a8f86c243ac6a166c436141e51fd2823f9a70f0aae32d1d54076d07a483ce4a63cd49d117427d28b20d3b745c19ca01a51c10cdb56fb1e441755e07e5da516cf82c85d1dfe6587fd6ff1b3efbfabffbbff32b7ac3ce4ae78b54adf1365c59aac6efb832acc6ebb8b2aff1a92b43d15c5fe45c596c5468994b45dd9a794b1db431bbd441b7aa56affa5d7e1bb1da98d506aadaf86a03ab3652d5c64eb5f12bea522c0ebf8afa50cbe1e7413d078bf10ba1be832835b2596b7c366b7c94f7a1bee1d7b9b268c3954d9b1d57f63aae0c4b5d598ae6ca769688b11b3639d750007e6b00f0168c0f2d0e7ff4211fb2483038ae8eb238fc513a8a0068cee3509acf41717c4fd740b7e2a05b81d0f5b9a1593351f9319ac51b349b363443058066580dcd5200a0d9ce45b38ea2f2539a7d7d9a751695df06cdda89ccaba8be41e8fa9ce8d61870a0eb23f343d767475e40b80ae9920e3bf8d07a6cf5e10742d74749ebb1a408af779926639cc545f1e11b2dd6b62bfca6b7b64d31f78a26bea8a6b71e88a502421081f04fd2be7c0dab4af23bd36952c5f4fd569412f3a4986fa21a9d5a1de4abe9fd992eef2b1b4492981adfbdd326d262d4c55183e1e449142a43588ab8f082555e58c54daa54f1ef2bd701648c4004d94afa20adfe24e92f5f72328b8889c810d5327d137949880022e2923613911e62ec74f5958965085f619545c4af1e622c8856ab9093b63d0cbb092f2a5758ba20ed2b4dc5e2f45bddb66d3b18f77fb4b164435457c2ccda8a952b0e284a8999abbcb9710f7ecf25256c59aff49655a2313a1050738e73bc8dab31331f592d577862964788b56c71c1c56877b7051d7939522464bbbbbb178cdec2dae20a96dd82080c1975afa072850a0d90b2c4ba5b5cc1a2eb6e4114c6128e64b094ea5e518508bb6afe76cd19c344706b804ba7c1b933f33314a8b98aef8e3d9edce99428145fc139e75c7733c1bdcee2a4186bb23a97598c11bacbc9c0e2c45d435ffacbf7e832e7de35e33e9e8c842139bef7cc8b301b096346cebcba8cea174330387f6666ee6ee76f2c7ca2dab93be7e6a2f9862df09816a771f6ea1159fb9acf44132533be327ee73e32d6ee9a32a2ba9dbb736ea6d27832d9c5b575f051796295bbe2a5a495f415deb66dee3df94e0efdcbcbdabb7fce9d9c277fee91d4b9349beddbfbba7f9613a0668df9fda24abc6e40c5eddb11e25bf1499fbd87902f034c61c62bfbdd85576bcfedddc53188ff5efbf74f0616935f5eefe87e16bb883bf1a63ab5246957f355d9b92ee6e4b090c5e9dff9c26ccfa3c49e84072d9209269620f4489a484843bcfa92f8dca3f42ebe789453cb3c799439bad0da15658c3a3e7072a728e7c90959981edda55c1ef73e71803e65b6ef698f727ee1fd7c1797480b4627412413c2e7a073efc1d7596cd9e251fa4ee5dfa9fc524c294f8fa22728e444a15028fa00ea1aad7e1141a16139dc54c28b55e32fc2472ab9265e2c91a4448a1575115683e588de03cbddddb977ce3de7de7bcf21c1f573e83c4a0814a30bdd4421e08f079fcf1e410e13d1e23bfaa03796d2a9927a8b361f18aa636fdc0d414c32ea28121f405f84911d0f38e0fc0435584d4d0e57b2a4092685e5709fd5542c87110943e715452824efa806cb11536e0330f5964826460c1042083f86183231c618839a0e63223908218cafba18f7dc2bb16fc1cef173dc98a9e0de535a6312bd3910e5ac627a943545b2342d8ac5a4e42cc11d21f57d4c2d7d0ac684ed509f2fe64aefa12f71c98e07eef573ce565a7f83e2dcfbd82bd23f2a854aa4387771dc631002c417fd87109ceecf99f9755bef4a58062e4defde926d31f8d09f844c4c3f8e4dd645e47de95db18749eea6d01c518c694cd089418ba91d3b8c2dccf66dd41d3b8cc684ea48b4c6318928e75aa1b9ab2ee6ddb7e58179f7bc3ca6778f5a1e3803ae103ee8f0d1b638ef4d9417e7bda4febef49ef43ebee727447ccf99d8a928dae79c73efbdf728b990733d2ac13746d2d5a449fc227a808048df81f7a9e20fa96c36f4333b95524a299d1b092edd8b4739f49c3bc27a4c4114b264c7cc18325e94609652a454aadf48af9098e429062ba8bbf9c8d0ba5654f72da851a839b7dd376f4c7640eb5b1f194a6faad3515d117ffa80eadfdef382d4458a13d18b78e57422454b9a4c31f6003962ca45fa5b292333467e5644099de31951a29c5e03459b1e79e27babefe160bec571e838d0714387de2afc02a14ffe827b3bb7db94b0334a7847f028edddfbf1c64f9e9a94a7d3932618d76392366c58df0f3f8b31970f3842980de84bbf24773520208b66cd0359ac40ad08394f5e03bf20daa2f5b857823cca20c8b91ea3883209cea780ef7a9673ce95fe5548adc56292d4f74eb2acab6459e04ba520ea1b52f2299c452ac9e99c73ed62bb67a44bd173cecd486182cf7471f2c8f0bdc3f76fef07df72b091ded57cd0c36e227242cd1459ceb9c32bce88c5603a8c603e4d1172d8a23011aacec44a0b821ece8ea8cdd945e53fcdccf65b9339516dbacdd4b4d156311dcc8ca7b0aa7fb25bb1980a4f29800866c6517809f629542af3141a66c01fa54b31e363468aa0caff5803aad2bf35521c8d333ba230b399257a410d0e9678bf3559ca35cd9449a39f63edabc6b530bfee78c2cc3cc534a8326405d2e7614050e36fdbfaa2b14faa5c7b98ce806272111656f9676bb443b6463c0c013117953d4b7522c6b030c65d8a8e66b64c1a16cee22e68093da5666f07959fb307e52131258a2c54ac40a2ca9f43876bf6b7ed2c4e4f614c88cacce64f13337b501e945eb506f686df88282498d22a807254b339a5811687b3f40dd124ca423e611e481061ce8c839a93a0274f825e8044d09327511c01258a0aa27c6135a9e2bf35adb5d612d098073f0e58ccbe76b88c30c67f8315ae30cc941156f116e98032aafc3335569859eae7c49891bee15f2b14b9a10a334355de216c91e5d92a84b176f500992713ac971b4489bf35ec5c6b1042086137ec76b954b28479f003200b33f31f1acccc8360f6801a8879f043da379a98d9fc99c174438ec8f1b7f3d2f3d436b052f9bb81144d662e8b03e1f3bb32ce92858b8ad8c868af8cb964b3af8cbda001a826a07de0e586fae6270633735ebcb82fe403724fd800c8bd4b37c2e4a35ec18c9527ad4dd962b8c1cc249f6066281402aa98edb1360268af80828bcadf9a704c932afddc809c300ffe03e8609e18633e0102b2ccac99a081aa2869d6eeee36b7e467ca542284af972e969c947c51f98500aadcda7befbdeec67e650d6869a34b1863258cf1b72e560f040424db919381d57cb6e647cacc9a93ca32e326959fafa87cc51347f01349573019a86672298df67b450d9ad47d0e4ac26ad281f7f177cf8307ff6534978a291cd5279a303b014665660744e18455968c03ac08599603a268c25893dc0489bad501503861d51afda08903a268c2aadab8585bd34502f8c8df62539220dda62039aa7b0b4a57c1d461b61ecc3a72307308e9158a77fa57d379e0550ebe5135a1f56895ab7f8e149f5243506a50050b6c9085179ffee7d5fa9c6ab7c99f4d38e4d861c4bb82bcea8608aa47f84801dc6abfaf23010ae5bae5a80df533bf82c08c19d35dedc3ae50604c2f342461b67f56653e7ef5857ac1dc2a25f60d7f0feff8c02afab415bd34c8565700fb14f17cb66f1ccd7aa8cedfd3cf5489ab529cbccfbba43099cb4dc65d545e825f60ed6f4de682a430f99726c0f9f433972e6a6b5a84f3e9b7e23e7dd108aaedfb9bb04f5f55826ce52e8bd3886aa34cc4587889c561a3221e2614056dc0f256b9f76271831b642298d1bdb33f17bbddd7fd7445c6a8f3e56365b6d309b5cf7d18f1bbdf8a79efcaac8f4c845aecbe0608a7a455fe1931b5f5aa4c3e5acefbf670638c5fdffbf88741edb42b6bb51bcf77b58f31c66cbba8ed637c7c1fadc7cee6bc7fef51bd8a71f5cc0be625c018ccac2f2f1f18fbdaae238cbd47d2abf5215d59849f656ebdb6ad15638cd70ff1f1bbb743044f32f6f648a56207e37befbdf7ac67bd1863cff2745d478a11898f951a4b98f53d10244a483142f7480c43a50a2af8b3d014a1a1fa6e794a1f890c514b5f7aab998258cf5756a3a45508df9afd45ddef7f68476b8c8bf9ccc68cda31dfab7adff3339edf0ffbca482412e9fb672e947fabd962e957e284c0c0f2f8bb37b23cfd0e858ab10161158d180f238455313ec6958331d3cbbcfb1cdccbd0c898e94d5d8388b16b43c918adcb27b33f3bcdf8ddb973e79cbb7c1be631ab38529d1accd267519660d775ac81e67383d9bec61226aaf5682a7ef746581561e4cc6b102d6352df0564fa821094eeee268c6ae6d59b28aafeb167ce1b563b059899f957e9f0f0c99123e543078f9b607af4e460c487cc8c8911c369003cf4700489171932cc20c07e6183cd8e6a0386c375d5bc0d0d80cdeba034cf43311d376e7ad01f0f43b1776a634af99016fdf13214fb186af3b3278701d01f7fa2d8c7a0361f8311a662848300f4c7cfa0d8cba0362fc38d9b6674a4f5602a46386ea036bf43b12f00fdb1329a693d988ad1c431a3a236cf8362ef437fe8d0ef5533622a468f23c78db781defc0e8a7da53f1e09ab5a510d473131a61f1d1f6373e38652003cbd8a58c54235140d1951693dfa081c547afe0695d2833df6374f83fd8da7791a1af0c4c4fec6e69ba908f637deba81fd569b9731fdd8603f311b0cbb6e6c3767d7cf86063a1bba8bd1f892671ae295c6e606858b63f318b5626e4ad5e6e3e6d8cce8236ca069c8dfd09cc768eafb88d6a3838458d526083ac2044250866ebc758376fd415d28d62844a5799ba7b1c1c951838d0bd13ccde3b8685c88e67bb09aa4b1b941b936945ef5d1a35073dac81a4a43e9ffed1b2a80a77901f4d18f55ce0d1b3398eca099862c153fe8fadca03768e36e79836e4dd15ecce67f50b837369f63f3bb3936df507a15336d7ea7d648d51a58adf1b5068e1a3735b01a5dc3e669fac8e66d5e0047368f7364f3398e6cbe86239bc77164f33747368f5d59649b7756653dd5e6694c4596a8dad0dca05e2d138dcd47d30f0dbd6cdee6ddc619b3b902406dbe86d23c0028ed41d7e7291420f40c7c0940d767003e523e7a7230c2430f3de8fa1cd152c405972e32fa207ad10d7c93840e9607f5fb6c835da15053d47d4e62553eaa9edfe719acaafe3e57d9550e2e683d6a5ace3eb7607966f87d7eb2fbe37700bf04f87d3e82574456a75d210abbda29da1e405a167597e7b700602c0f0d5aec16ab92e155327ebf2d6157414a9fb521d4fd56c5b627ea7e13e26f4dd4fd2665db0e7685c3efb71cac2a4614ab8a018a559d4cb02958d5fcf6825dfd7c09ea7e0be2df6f1ed89504360b751fc90fab12028c0aac0ae6f72fb0195826bb02f20be4e333ab2ecde7fc7e5c9e99df97acea6180df276d0f1f38d47065add6f0fd160dc5f91c2a80b768d09ce7a1345f009ae2799a9c9741531f840a7914f52ac30e1079a2391f83a61e072ae463e84af32d448712e9ad963234e76368ea7fa8909f5c699e77f021c2cff9a64aa8d46d3854bd646644040000000023150000200c0a850322c178482868b2d81e14000e7a9c487256994a64598e0329650c32061942000000800888d094360000fcf1f728d36f6704d05fc7affeda142c0f6bb6297c6554b09882b475fa3f05de48a3abf7020eae212b54b37d41ae98cfa864941ab00e308e62fc5678738bee924a980bfda2ab4de1e4832005b2b9d1cc80520a845aa86b1222da67e10cfe6f0ef55a5033655c060b65e01c2f708187b3b90901b3bcbcf01a7d06c576ae4862d6056bab444976a109937bd74b60ff3a826eaea27d7cc1df06b3b294858362d3d611013510530f449e0cadc75ba124b3894e4c00ec6dbfbb7fb148f940c1897aba91af4b754b236031c59687836dda6e5a518f69a78a711f9714b5ca64bdd02498264b9a3ae7a529db4797cdc46c272b3f105a834517b821742b928cb51004da392990752f4d8dfd7291ded1e8ca12b64b86ab80b0d1c9163cdb67522da41534e8af7b63073e7cb13cd580565bbc1a39b9983cbc44677d336fac0861209c5c43230e42d38b114d80baf31771c0c75743c773beb59e43a344490414fe788aa43ccb92af73508fa553dad998f97143dbff3d984037d155ac182a6e3225907af714c2057415e52358bf9a2f37135f29b4b270f0a04cc83287f5beb9b3f27b3d7003297529f204315c61117965958e3c09fc62a82d368a067440cc5993cec637f9b6cd03871f671c54d3f7397846f04cc7e214860a09754c0c62ac91ba1703ba26533027013e17e640e7bd0485cbdc2582e374a02f1afb8d38b6f46f294bd6e354343d4e47a36d7c6c5766a1601bf7007a5d3a33ec840891964ef01bba2f130a17c9af8702951eb36cb125c060bdd40657b1595595b78d322433f83273f4c0cfbd7d23022c1389afaf2db0e05a7cd216cabfd0c34a89a86c70d152189376574b8872a0cca9080830f7d5591b548969063df61d6d225539264e3a37761dcf54b01a0bc5535e021d1bd41f221843820ab9550cbdadaf197b8a5e3d2cdb5d8de0012bb3164f69c23d01abdb52e56f3671b11cc8e9bcbe94484957ccdfc129c88cd56c208c33207989d643b1c81c67d691524314d19851d5af0dd578f938fb663a8bc32e0053a907c96de14da53e3a9fc1441e913ed76e4d016b891fa0e9e49e8eed0ad16bca166ee32cd412a2777252d3c2cdca036a912d9b0a93eff05f081cd446dadafa3557c1d1ed42579384a2afd23485826abef38688574122e61828740e0d88c56c070fb679282e03674dc94b71951c1964b29aedc1c91384df18a181c6ef0850f0de0adae135a47645cdc8511aeb3874c1a3ad6187ad9d25f18211415823144ba830eaa5467c2585fa1d84b5cb4e3c57cdd0efcafcc037b382a4b1117ec946637308e3c017e4a3bb3ee843778d906d4c2644b6b8af11f94a583e46224baa975471626c4a7c1525240bc358510a18685d5c8e81ff92466cc78e4dcd2f82068ddc0acfaf295380e98c451999dc42b3cf92f3446aa65cf519bc76e618a63c5646a69acad01876f77ccfc270015859c58c225283feff8831bddd6476314587320730d7f1f53ffef41442959f0da3aa7a0e0a2c7feb9bed4750d9be3eefc06654bd2dc3037a1b2c95caa8b6fe2bb8a3a523a8e257c19d8402f3f22a39acb9f17540053342a1503b4d6ec899707bc1cde29882052d26c2a11046c1e86fa8339de6f544bcf912d4524649cd52ce4155f676ed44e232830a00c12190641d6671a823fd445b382234891bdb800977e07ca8f23e626d73496ca72935676085021f0d34df5b97527bfc093e1411f65024030d2a1167b1dd4a869921af6297bf811297ac80b618ac671c05b14c3e7f0031a4e60e0b6445280e3536dcf5f6c52ccb62151fe375f6148b4442927ec0a867ecd9fa1114fadd81854186e6f079bc8867f9c879ffc650f520333979f69336bfa9d6afaded2709867c070ab27e1706be5f5a8ccfda56727440ffe129896daef72e9b0021f46f91622d958a3f3bba1e6d3945df6f00ceb493408101b2ffb0318e0013553659a97573c52d5698a1c2b185b0bf92f06b61f6ecf8cabd5cbff2c1cceccbf0789abe3a4cdeec918be99c28a965e294352b2ccb8b604eb1c686fb6ad54aafcb267be80292d445923b97da6a8a09f3162783ee81ebb611c8378a530f4b052dec136f3053a34989f739332169c995c41e1b756f456594f9882d3f910a72f0bc8fa6efabde847642a2600079e6eb690dbbc48265c0bbe3bf731634c05bb612bc628f11b024468ce7d9bf2f096950b00b89dc4525c7ce17c6c60ab0e78187752b31c2f52ce46ba4595104dcd0a0a6534c86c7360c082271216566cc1c83f7b6fb205357bd74e79c0e520c665c6e67d8ab0636846ea502dc694e9a39b25630a9981f625abd542be82428e168f987be972eda9ac31e575a1b88812454330721bd72f2dae8bf7ca2fe9a9959041d6267d14b3aed1cc2e146ed8b530d9b384252e5bff2d47add39b308cc68c6603c33031c2888165c3fc1c8dbc81a17f27127677cb25009ebdde7b6c690c405612769c65ebb97192ff6bad01b9650a8d0cbebd98b21482ba6283f0b9fca4732d516c6c2323762866e948a1751bdc1b6110889557e67f438e304c270c5ae2007dc0284fbe0a21e13e507f5e7fe62d31828f1587c197336522472908b1b941b0c39b2b695465661d63ef1ea26b95c09bef5f22665d63d008b036fdb4de710f87d912de54f567fb410786bb3fb97cc977473a7f53892d3bd5c982f524249ef024a8123d18938ab8c19524a86dc2e6ac013a22e4a07b1c97064d625aa6e726f4ad116bfdec18d3a8360cbccc1d03f2185cb8a1ee6afa55e3e1de463685e45af4273b06de942c0e08f912bbc2d7fa4a3cb562e9bb667d92d330d56bcabc8992cf168d036744667ae18d16bb1a81daea9a19b9ae35d6819d600767b90bc2d5154be264f8f66f7b9fd02efad6917ab197288a08c86eae18ab4874d604b1e82a0c9c21e45ae39c9d163c75051cfeed13318f0da13a1f669085f4a969a3ff55ffc4918f02224271892b7ed0722fa8b764e2dc23b5113a8819f7352a96fd5d0d29abe524baa14f9917722498cd5438584c572c43f35e2e2c9d6e741cda96adab55f83e4a56c6a51916245c3c2cd0383af798cb1617f59d443e57bd01ae8afdd5421f42f46369ea0664b1508384845281f6aa7d4573a4ad96b25a4cd268e1442b676545e6cf22072cef0f146382b7884a9512c849c7bf8c319665bdfe8d42394b0613641ba682bbf882f8f38cb0ebea0c3c001657091a561b0e5b778f7e3b6f625ab35e4061aa3d8e90b703aad6c00549b1d72c40b1adbffbee23d75d61b1e0b2f2871557419de42ef212cbd3346dc523fda8ff586ed0d81f65218a144b5a837bd4559febff7a0df92623ec66ac44c0df1bd03f106a8a343b183b2319587d147abb32b99c6fb79ce3141000788e71b656488a86d273c9e16a34269314dc4637b3eb1f68877167162a3de71b44a5c31f6c5f7948e4b75aae7193fb78e7a5a29423cc4b7f82aac0c3145b364cb131438b3cb472d76b18430021620cba25af99f39c57372f80db689c3142a5d06749baed0297e76bca3390aaafb63c6b012044b6f50336c049a1036dee5498136a62c80c95e45aa1f98759bbef1685b2790fd84475837b0379811f6af09625a530ef21593a6303d6ac63c78f6a33ad2850d5abe95e0e9edf123d231d3f733da12eee694d657b7a0a4fa6adc1e0ea2efc946ea447d465a03ed59367d5f695e9ded7893a49f08f342275abc35be39b735fafc4394749c9cb13d5ad5168eba9b612ff7de5c0c991131f49a690ae2ea11a3a5a5f52732704e511f193622d4ee0803e3bd0a8b0374ed2fb35669a7eb94d5c3bdcbe6c7d1be1a28ca1ede56f5b616b5e56e8e7fab157024165d0ca38094c9e2074fa6580df2318e228ebbab9a144414f7c356c564caf8339278caf02f5ee6081e6712e29c64da14c259eb3cb3ca605234dfa91a973cd6a77c500e1455559c0636b69b11d44055a938e185d9e0545ec18cc413d9b64f848e129ed6acafd14a1dcc0f4dd86d6954239d694f96055aeff2c2303906a43a18c8719acb3a0c29590a987f196a077be2ae4bb850b6f771f58f0a7997fd857ddb9a3c23f33decc6e56821b449e43c54b80f511a207d665c61963d3388a84c4ad94088da078b568043011abfc2c4724ae71218fc9b80990a35ac7feec1e480168c7aaaf16b3aac59a55a59fde30fae2b11d8f737ee258f2f5006d088b078f320f197dc25f03f7aab9e77326561cdbd560bf077a739b7c2167d4a7f66652a8f089163e13ca53539965a3bcac0cddd5e0b81c99e31685203b1699fdc35aa3273dea71860786d22cfb3ca8f79e2595167a1fb764ebb31664f9dd441928115f00ca82e257136ee5340a18649ac6087c415609bf084c0a9bee5ab565b5143bce3c6ab648a37f1e0fb893fc70e7e4c325701a601ed17ef0c826ce70b16955693f59d575a9ebad28945772e5e320eb01fc5e8f343536511a338ae6c3c74b462f5db88900758420f4006427326ec70542844f880f487b2362a12ef0b124c2c2b73a7248a263b72b0e74e655e3dc2a4364ade1112703fd59be0a5988027faa7ae34537a0b2f085d023c3d875e0eef46e42501bb9e2300c7102db703c42d5db03d98be04c82eb7cf06ebf1da8e56a71e36de6e524a1f105e2c69580dc905d42c064336c3198d4d54536234f8fe97af65a26d6ef14c74990c690e29231f206ef15d5df0a233a5a049e34d2e93ee8e337c1f882f1c560734d5a4e43eeda841ae47488b85f4fe34282e0040180ed6a4843935a961791432cb1e2927557b9137429554b06f8914ba22dd6b52ad0f050aa861b74b3d001f2f5a935ea3df68f58c7c8be5609bbcc71584b37dd8653fc0969771204a5a35322d68042402160eeeaa2c6a44d724b12a4cc7e1b0974e8d02bd96786bcae0630d711e330f1b875d0e0a3f39d3f2952388afd7277256bd72e7881de842b85f1dc19eea09f4d7ea061d2f4718279e2d04ac1fbdd239dd2b0d25dea6231f1132873b7b334813847a6046380f0fc0cf08356d3907c543a8181dc01b79622a8a4c4132ca115ba941d6bd517fc2146502246c76226977a47eef5011756833539b0df6860540876ffae408304b58a7f9bc21ad571be7ff26757f1ad37e5420790cf3a7713a754a5035014986115d33a07256e2d12a8834e80a494624d16e3a819ab7b19a973b2fb3e3720faf5a52403bb504634b9910f2939a054026145c9eefe5da0836c637102cd0f630307385c9865f52bce4cf359e2b13d6c08c347d1b968b5595ccb6834b20dd64a481501bd1420948ddb6cb5deb5217d81a6f4c9790ea227bc913c780397639a22146c9a8bd3541ef95c8667c8171c26f511bcfa0505ab8beb4e18412621d65b41e0afcfb151b34d550813d1d6d70e7497102e5308ff2ffc1e8d479df6986ac7eb56ebf1e8ad8eaf1f8d4954fcde8e393e8edf4c40d552a7d847e13f610a24ec0cb5bb5103b4f28263dfb004bab5be24bd2069fc2d8d6779580e2cbd1ae44485eae127159ff987670ba6e841a0df546b48012648a7e71cca1b1d55e12823dc025ba725c981de9465724ffc7a109bc52d4740ee035ad003113162ebac150784153c0b1e3fdca736bb204f3825029041c332039f15e62a9c4687a2fd20db59eb05aedeadde3841c147037fccc2ed38f15f5d1177279e8e4488f2ce4f0f264c88ecabacd995548e52809329b9c72b91851f227312f05cd27ff1999a593a75806b134f11aea7eac7bf6f7691bd5bf225c18b3e463c7672e003f955ee0dbf77ec993d397a45d5c3384c06c828f3d2bd48e0ffc5fd2eb4dec0ce810c465c94bb0f04d0fe834963b0656b0f5d7749af161a08f404966dfe1956ce92a5d42cd9594ddc842f87ccb80508b8b21d76821df5f03ba14bdd02d9f96fcdf0a3c5e75fc065cd0617729e1eec7b32e9e6f5618340e921980fecbccedf9b6d00fd3d36fc252274e55529fe4bf84ba82325d911c03db1d050e05a034deeb2c35a25ffd05348b712e92d56049e9d9cf22ffc3b27cdcb1d71b8d812570e3f85f4187e5304170905d71136f1314eeab82e0573a658f63d804ea0e6183cb2c774a292558620e81d40b467e3078c0dc94acad9348ecda40fb75bc0be23c72d1cc586548a144d2ced24873ec8fb21a4b56c202be3808d0d5f7097e72e8f268359921bebe0d9d1839327e615c2edfc422013a27266f45cc556aebc9d26821134a831dd526251d7ecd855f5f6d5bcc4a2b96adb0e2f84a23cef58aaa280064c86ddd28b3c247d75b055bebcbb7f8f661240d17a3111805247dd53340cd32b54238580d808c0bfff70902e007f3e4577c3139cc36b10914827ea6ca01cbff62748e50f4197fb4e0c74fd7d6edfbbac065ceb0e83aae6f789080aee92d46fcfee5528c01aab7b8c5a0d4648d20aa40bb70542b0c11b4792b08138bcaf9bea0b72a9a368d9a230fce74496eb5154159fa3286da0a391d278680548ee6d1b90bbaa9843824dbf32af44c6427e01e5b83b9f3fb047c7ee3b6cc38325af23cecd7b987b5f917ef567acf25490feca982353f7700f7938f41f7fce0564042ce549f1b260ee8e0427e334cdc339e78af3e0b32b3a2884c8a2fc93472e1939a64b627e9d84eace0c7285d25f93676ff305465303db9a4ff7bee79f5c5d994ae42927b0d5e13b2c1cbcc5578920683af873e06724d3b78c01600aed6928e926e9eda19bfcfd8823046ae93d70c4802bccf12bc11dfb73d08fb8367e891177cf33693ac41385e98bea365a532f019b560b977cd06fe719d708010af41ff3ebd77ff9af671f20fc620cc164bc04e1f42b43128f99701113b26a3a084b138e8915fe5682397f6a767d745c7af16bfd507d514d25d465387169dd23a31ab06ecc5b3d50d034af6fd5ef98ff9fef56121fb0838f3915449d224a7e8df776951dd20f73a6ad639ea34e355f6b9ab32960402bcddfe7efb68bbd15b8be8b9bf084130baf1a0be5103c29f484eb68c633457ce92492d62e2118de5e473193736ab3b87a3d62e93fb4b3dcccd93d563d470e634644e8b25892912d019f444a6dfa7c96d8194615131ffe5a18d7ac810cb2e6eb9bf494d15d8a8223267e52f584f95fe631388f4be0c6f95fd5ec881c1b1945e575808a899bb62e6b7f251e6bf557f7865a30a0f8dd4bbb4f3acb080161ad0cb37f7a7a6422329e9df853184bb7e57d2e89570d6422d314379e6721780b5fcee83e24a6e7e9c09726c637aa2d82af3c71d2064c40cb16479dbca08599a23188eb56cdc0e12162d25ca15e8d2d3d9d0bba8bbfec63d01bf7dfb0c2d411be5d0dae24adb3dd8e1ee07fb08d5efb4947d3c1c51b70be5cfc2df3246c63e8196b6ddb3896e5554f74e2acf199cde4cb5aa23786deb14731f5800e8b6244da1ed12f7d5ae903c481e9f863c8efbe9a5332fe8085099bce9f5d755f57ab8003675e951a18c51120701ef18018d2ba7da872735c30f44705c9f24a28f11c6fb38730ab79fded9df25dd31d963c732b8eb52f6688b64542ed615d6355b8e55bff464ed9e844864176f75f71436c7abef6a92cab955f582d7d7686dc4c5ac89673d568a19eb9fbe1b3a0c2a9b301ae21ad582e9737ff94bc4c658310344c9eda6832ce7b9af30d5712f9ebcccf67152ec24d038c1cacb40cb8ef87a193d3d8e7976a2bca9f0cf738f017dcf808bd702c444ef4d6e9716bbfb0e8ae820f0f5069b7a9102fb9ea42b08b159431134d327ba2669c7e00f6df9ba3305591b1e611647634e78259f6e498c881eb3111afef8c7e8bcde44b485ebb95bf4025b61d85f4c2204085558cba8324256c088e8b8c85a3c2e159fa4d755827767438bbbd5122c50b0824fa0e61894a378bf6aec5cce3651487928aba92411b44326919aacf9a7ddc023661fc75f3c28e3d1de65da03c92727033f86c492a293fc12cef40ec0d64f5a69725c748c9e1147257ec82342387dac841829c980e9fda24b7057ce582f522bf488730668574feea9578a6265987a139af99d1b3058b11631ec0c6f69686971a00760eb0ce271275151f3886e71d0ee897bfac77d29b526d98c8e46987732094700efcc61fcf4bdfe37c7897dfe77b23438f4295ec55852109b66a9cf7b427451428b63d0091a20cc959d4d59d010bd967893e6f86657f92a9479b82d5bbf47226317634de8a527b19f17a4a72d43fd9078af91c45ae16d8ee7ce69594207cff7780d0a8e646528b299389be5ee24ccc170e45b89c10d7e7d05e2372b931dd5bd59c701136e8e8094e57b4c1a17f434520444c506b40b063400103aac9c121ccd78226dee5e78e49a46eb19edd5881ce6e4ea927e8e2c69f0cff4e80abc2e2199823a3572342c04c5a7027db3982d32dd0d2940b7193eaa0fdb862e75c32071de4374687168a3b0c50af54b292064c397ba50c2bb4065b1fa61117a61018cd77cae8182fca49db4713ec5af7a7360000aed7c53f614ec0740bfe160d1f3454b07310fecf6722a152ed0c068931fec936dcf0c407ec10d092ee4ecd373b0ef51ad903f883f816ce86d26f8ce2c8ee459fc7abf377bcb6c45f38bd3ed87288c03365d9c7b1c2ae8ed6f1751f2b047eb1b4e575f4ec4dc750494359cac8f239b3b4688255ed5f1cb31238d7a93714a467db2b7b5fe9596e40c8855a1a753a5782c9cb8d9c9b279a44a22c76758772775b3154226369a223b8af1e5b7639d2aba676f9ef4bdf16d01b72d84b855a9a644018a2b33002eeabc359cfe7e84baee330623a87482a6d306348b9b8a3fac1874106068b1d3ecaa66e7f2b6ee8db02993db038e6f5ce1357beb05a517123a7cd157e325ceb98a0c97353a9fa39005912f5515b7beb7221affa5ce3e5cfa1101ef4aff8e0d21e439ed0da149c43bdf65ac60e3824e42a11f4d542fc162c07364db0c91f19d4f1efd08101809b41b51c3a98f22dd16e6baffa67cea22158aebc0d529ba1d9e8a5f61f1d470a4dd09ae838084ce90ce50d358ee169bb33f5f352cf524d9ce05e7350b813c073c7b317a78c367c0821d8ccee0f36f501489c84adc10d344d935381beb1023abed24a5122f5d4e3987327d44f1d64535e74ee92746f620a070bfed3520f9de24a0ffd81503fa8e7ec937533da308e25a1cac25c38edcf7e8af4206b4bfb715fa74f71d018552ab41a1282116b842010885db2887eb6da9eb956056fc907f646be2e804090ba65bbf366503a6867314de36330b0e611f85f93fd5a25e9d4c7c95fc647d52636740e6b49107d5a5a4489ddbbd3b3808dc6d5f9bbbc75fde03bba86df74edd572061be657ba3ec8c3db3afe0b7b7f6e0deb286bf31f02e4f20b7c70b44881003da4327bc192c5dd6bfaa8b88ea20d213a0793d466ce62844ba8a40c4f80af164e6f895fb729a6bd4aa9e2205a1dacfd8bfe0104fc021c36d562a9b0cd3e876b17c43ac3af27b5d88064cc359dc4a79ef71ce732758312a1a7ea9cece1baa338b5700f8584608894c1ca81164fb2b5670abd054c0be5ec90939bd60634e31be8ede42c03e2a1d81e8c602e336370fd0b9a16af939c49c3ab0307506f097ecb77b87258f228bd60caa20e994cf8e16c6e15998cc07d958dfb8e50804c69b191cadfb6564e871c82427f3c878ac6933a860844aafbe0ccb894b696a70c3ae6298e36c03c14070ca88df818df30872a7c8a204d2bde54b68ce064b3b804e2d033abd89bdc69770879ca88c43912e75901961bf414c28ef84d883090f24d1fdd836fe94770e3404de7834cd89df2c6e374ed9e40e7ddb98bd8e2b29441250c1d53082d0368a0e4931efc3caee1deecdefaa3e930808fd150e5969163fafc707910dcbc636be7a25540c2707729bee80c59e531dd5f62340e0879f2c801886be829e7f863ee0db7a6c0b0a2a94ec036e2f1c17eff594060f09cb215a94bf0b8218e454fb71bdc418e0db2a2e8028b00c4ae7331f1d5d5ffd217d6d35432502cea0e47355d8fc4e7f2ef8f2721720c5c2a4a9e402e6912c829b4d7be4a236e4f2e4edb63c76bb39347b586d10d93d3145adbfdaa21bc5701c944a7ba93a543926224944d5f584f13118c4fb885fac817824ac3441696d2ecff938f740c27b72e5822dbd51e33e1b5d5642938317442cd63803d5024b7cf7e24e2608add69109718099198abbd46e7bf25d2bda68ef0a44e4e4c9fe399c22a98c81771e27b5f43ead1858a4370ae3f8f9193ce24db8440d3a5656fff3557d98607cbd2deed933d9f390c55a86414a624bdaa394002484a102788980627f227ccb7e81b10f16c5d9df79e72e8f4adba9d20128d2f5443f7b2ba24a0c6671c54d5482c5d21814fe28d5e74ede082d36ff7cb7bc649dccd21ac01b5238c2685316d6ea024ebb0203e23a00ba562260886dcad6015fd7ffb3372d00555d146038ab903cea6df44430ed909d13b83a5cb6261176d140ed171ad16b9063d0276503fa83349d0e7242dcceb187966d4889e0b8a7e36aa6953a21dadb06d448e2944ebe362c46c3a6ffab752a9c4a2c17837da392aa5ba605049b1f0c4b9a50d48411814df876e58ff18bf6ea1303a706a726330aab0c4aeb7175127ad05d823804de5fbde941f86cb372fb94fd3345eb6d3bb6daf27478c421c705ea10b1bc523ebd9cb0d1019d4ea64742d442ea4b7f508ad9d014b234f92acefca76ffb52a6b9122b846362840fba3a9f15978a27f1dd7b628daf39b83bb15d8a4ca06ef59e0a6da1752f4a40f3200ead6aa873e43dea07312c7898637b4f3809131ba9f5eda610f1699e456106ce92dad444661546f5931d85588c928f8ed1f421fc0b9c733c76ae72f71c538f01f3de4843b180f4a4e1a3d773adeb5d43a1c6b322e1aa23ef56348bda99e3edfcfd58a235c8e38664d123e2905b970dcc7dccc67539fc12fb5cd736293d933365692f3197e208b12eb20220ef958b16ddc9b5dd76f3fdfbd49e2c53a913b135b5730196c596eb1c7ffb34ed89b4ac6ec55b0d49993d081ff0b9ee861d3a071c564b080807f109da1d5b655370d7115532a5f8f3068644235356fd53593754c8398a49ddf72b17b61a38f31b8228c6bfaab06e432da99dc8a82abe062eda475ebcc4914ad38d086782af9452271be0a242e5fcdc1540dd0cbeb499fab6b982f3e860baa67cf19c95764f42112ccf187dbfd30fea986696b83acfc6566f9bbf3bc988db1896b4ff127afe57e085bb73c82d2dee524624183be1825622733e412b94491070c8f1c53568a5e9a0b746409efa87bc574d28de84f46e6590e9d448a98e0d603cb66adaa2ce7106c696236b03b104d113349002fab1d9d3b40196e7a39e110799d38df3e7d923520adbe418f9aa4b4c108f7c5a42c316d2d0ea741e43c25c83e5dd3998fcb65fb847726fdc09fc30708518ffc25bd57a65abf6ca2e63938706b8487e4d000f4aa2f697026a4427b329cc37370eaa0b43d5d0e6a7dd6996ecefc635c5ae3646174353071816404bebc2d01ceee689aec740f8e669aa34c3a3d027072d72e2a3a514be49e4ecab5ffd1fa15c74d5c4a17730eae7546fc2eda8188f3cb8096585dc9816749a1346c7d5d76b4c945875828a113ae77d4254f6abd3ac2f9385eb306a7092e2bd52734787ad582a8186a5f4795ed1a959279c62432771b2463bd71891a9fb78a088905f079da29293b565be96d903a5bc6606b6260ad40197c0ddeee76076bf9db78e66e8c7e4a6a131c42d26061a8ea84cb577bbc75427a176adf7d45c30d9ca1454afe030b024f636ebe41a356c0d8aa71a058a6e2cfeb8531d9fa46ff0518bd738cd3386f5917e14fe2f0ffdff9a9f64c4ff904d480692be9c4423514646ca372dfa66fcfbd6a114481ebe3996a4e99116a23262c3cabf6143748bb03b6d7a7310b08ca7ef8c878fce9ae8872222d9a67d7fd7243d7f3146138344fd29a6c5a5da7c909c51439a042e89284ec84bce067570360236013e739d7ca65ddf40553657a443179a88d145aeb55a0bdb8d92a899207cff9fd963894eac729e009bf241b59fbc7075a5ce12e6369be79c33818f48f38e28ef68e174081848c366554a1d42d6fd8dd6df313bb8b27bcf913b75cb809d21461cd26dc5ff3c718841f9115e6766223f2da811d40ff114a1615f3ecc6f14bdb303edda607f76587b90f157474659bfbf9c11d9003e494f65a3ec20160fcea18a3eb6b66c544d56dbc832525f6b4419218463abce3a91443bbed10474623fa577f8ce33c8ade04c756513d5cf46e871c54efbd7d156c5eed8007d03e196033a6c1da0a212b376e5974fa60f75fbc98e0f3c66c8a54467392c9f9b135e5804a4032789e57cd6e9b07eb83cb2dd79c90744c7f709cc59f4caa9494aa270c1505c93e825be161c2876525cb4b81a469b06405c3d0005446019dc5080e6d329f5ead5539fdd8eaaa4c27046c018fbff166e07261620fb9f47f28c7f0f710ebbb4cd8a2d3c91c66c4f9be4fe0f1292f82dee8f902ccbd2f89d7cf581e831b1073333dc479aa026793e0ab729683d6fc318a0a0f4c73433fb6d46a8d4b31d2e7f2a6d5942297d063a62f8cc5964f3ba006bfce130ebb695a56dfadecea818a9da8988e04b03c760f9e57da4698e944eae95270a9f2145609e4ae30d755ee6bf30a0e131fc198f94c3732a09827a9b1711bb88aed5a12200706b3c4211f1a3d7963d83ac807234e88985d767a4e0f874c6037557f76141204385afb123a4a53139100f4d7cef7477fc5948186a71d026957010372cd605b0f11facb8cb42941909aff601507a03ce64a5a900a0689721be1955d7ac7df9cad76322e3b88e0a1118adba8e8956d5b4af32765cf9acadf8394baf35d1069aa37f02534fbcf52837e01a8535f2351250cb4f8c7ddcf8d371f24ce26af82815823b992cd78fcfa6b55a8ab49f3c3a7b70f9025cb06386f61620713630843acf549cb542f38deab09df5e4be1e53c38a6b68fa94ebdae25cb30a0728d07e715e3615f1b5004266b619cc903d580054a5e40154667ca573614868f37f6730e4569612331da63d00680b91f5447776df03348051b789274204f599fac0b84f3ff230e4423ce52918d4e8895edcdc004065b3f4bf72d3722ae4ca2dcaba58de06358d8adbb6ac7128c8fbd90ca43ae97ed65dac56660550324a498d54285e6a1a2c11176a9d59c462e33af40225cedce510700f6c0974845927605567e6e810a752c19ba9b07c4a015dfd1037431c8ecb08fc5ada979cb0a8537d08f72397fd9b1febb08edac29803157c32834b6f0906529fdcd741d8c91c04ead200dc991254f1f3e1548a3d400c3d12019a0cccbfa463c27a511a5a62678baa617c6f2306a8e7a34f0e8e2051d63966152a914fd642d999d3c545b011d2afe36c891ec720166c69c05707fbb01795d8ebf52a4ef1b8c6575326e50688ad576675147e2427a0685b69bb8a97fbee1f99fef9919d20030c41aedc1c0be913b768987e3c47c52c842972a88f557879d5c43afefd953951bf749fda2aeb5abf18908a65146b8c69dc6f4c3b0b4806996a123f1f36c03001a72eaf37d2eadebaef6e2f4304c3351b56ce5d14c532dedc6580fb315581d715477c14712322e3e523185d1a20a391923c21319d0acd8e5bdd3f7bbb78162218e4b8fe5849117b782a10bd26ca66f4f23f725ee165bfbcca4ceb76d9e588322ba7fcfdbf9f37a71824ecf43a27b27511acd22e1eb02f2d2bb32284d84485b3cc9a3064c61db24fe8e288bcebcc31aee283a3ea471fc4d2050e2c10364c14e57d0c4608cd75a668d64872dea4c17b1ae37c5eb71c125618a71884399465b624eb3a19aeff5d2ec2755c9b90555fa7c085c20c6cb5544911b45f3f6ecb656836bca5a0a62fe761af281e308abb4f12dd139b9b914710c726fa425362d77883402c9c8010c300e89f6d755cb0dd70272f56d2974ec55fa335f4e65b6b0e454326e25844f8c183a6631d02dd6d2845402b45f71f8035950638f8cc792c03f1a4174eb06fdfe36f087580c930aa16e6d564e2807e0a43377988036aaf897c5c75c3b8f9c8a2d57dfde0d0566dba1987f4cb37a25d65c090cf2b6e6077d248ce19413b2058bfe2fbfe23f1b91b8b1c1102097491bcc81d0838aaafae262374dc8c3f78275de38f666a38cb08e8336341c5af06416a15ca327cecf012ac90735eccae7e6c377d0161e2e263e5aa5a749142c1540c1b48eb9fe1d475ae8f453d900573d8c5b7eb3f2aa950a580564af81ec1f6a78cd128c440128d1f1f4adcf1c3b01ce5a8983336da407b19bd07a1e8745f7ca6518849f7685a5c449c443cbc9ee9f6b8eaa5777cc5736d426398cbf9facca2b0645d6497d4b6348b0de38466b550e6ebf6cf1fd3817c4aab1497e5df113cd174f4019fcc14ce5cae7ad4f9cd6e552c9b52b77e011ea725f5ae7389a46f27b869f5d6ff0f2edf4367add4bf24bec5585e03c62e54cf26b0c37035548041061de698600b7faa59b57f82f6cf7b041dc9b6015ae8b8d4746377a9fdaba679385d9bce40d606f1e770affdf3f4ed7b670b7be86345f16edb1f467a802720da1331df07d1bf34c77fa96344a8511a511e99daf37776441c42bffb278e826f112be87d2cbfeb9826d0b5c810a7431a62c0a7b1710c0801c01c099e23987629f89c9c5c1d2b3472bd897a7d829f747fb9c78a003be289618a07bbabd845ba35ee8c4cdc89a0259fe948f2f34806d63a0a892d434f550910c3426927083b83c3ad894b1d453096c82c48cbbdcaf6af3fbf272e6253e59d08f8286f87eb522d1bf6f959de19f9704860ae50eaed21928b2db4e1a24673615fcc9c2914fda0dabc9b3f9d7251d05977dbb3b5cecc21440581d312aa2c238fa0c06089569f153305338e4cf44d305f1b243471dba47d3e502eb4b38217dcfb2b11786ec2950f9c05eb5643e6dc7ddab27f6f8285ec4c1f3202d725b7ae21cd008d654f15e092b82523685709a0094b649147fa4186235331f8a3bab8d53233e11a3a859c0511368076cc4fb1c5000c56ea72ec32e3e634c69f7efc42607d9384b988dcc44b5ebcd2ce740e07486e610145552c32f202993a1885698b8979f45408698d93a316cb4347073675c31638ea1802b5fa30e579b09643d4689c71022e0db457089380e33b338815d6a7e1208671be3d14fa4694e7490db24f7c356ffa5cf645192c9c35fdf3840db414b6f84ddb84088530529737be8fcfc0ac55a0c7e626c52ae3b65a78f636b1242e0c1433c5d034e79f6818366fb6fa3bb2cb1abd1f84671a87addd063ecfa88f3878b4198e4d0c1521ec68d727c5d330c3f19d1eaad0c778837a6876aa6af4bf79b84b92010b006260aaeea38f5ca450d9e0b1cd8ec95777856aa79373f214f1d727b7c3fb1bca58ff61f1f3d46845ff80589864a4dee2c219c300e33571fccca09bc0422c0711dce865193bd4df90ba5ea060eb0bebd9dc65744af60d7e578f61e715f1cd8faf732affaeb021b6c8b42ba4fcd0c3720d2b2575276175da89167234db22a2702f6bd213b114ee83b06b69ab7ffd6fe59750b5c9590a9b58d4c7b8a832c8fcd96435ca160136da78a60e53dcc109bf751e8643024f7b10341aad651448ae496e93abdbe105b135de3eaeea8569d0c207585301d2a1bc40fd842b4dcdd00efa2f6fdad59956bcea04295f82213dabe7af4b909118d0a40c69e243c6f3f1119a936e0c1977f9c7ea48d9a062711ddeb04f9d0dc6c496516cea532a6128326cb37e0f446293b4ac77b8859609b97cf4ed7c99d94fb8a92456d51238ac07675621d09e34841c22450c6b102132b87d53380a80a62518852af3176de03b0a41734065f390db4d538b0de8fef5ea61981d8626df64d3188e3f7122e262a5af54682c477b250b3ff7e55b46fe6ba9bca0790ab5d64d58576923503f54080622bfd8628e4889a6ad1a8fabf3e96c582a08e578594e7df12d4f1f870969f02eae4bb12da1c0cb8c11e52a45f86444ba6668e4d78c09ef47dfb8a1c35e575eb1d3ee4823cd49930f8a195d1e96d5b0c17dc4435fb8061cd58abfb2a77f068010469ba0603ec2a59ac9b56f78cb4c13f176ad640fd0a1198223f90eed30fa12da3e8d4d3fad73b58f3fde04bccee01eb557a922a26a520a4ecd6aca8465174ae0f5ae429a86719ff3ecb5ce89bf4bd00edf5b349223d7bd3b9bb104549ae1a7c941382d32b804850da68c98667c7e997df137f53f8cfc6612bb28a40ba779f6ae57e6a4423cda3f76195da131d150069160d7adafe8412a4caa013a6422cfccad09cf96a037534566177fb4f580301c2e3055929576a3d03bed9ff640b87f788ec26c7083691a2ac5e009835ccd37db4784fbb1b1cabbe2af3190bcb4322de90048a7742b86b9e03557a76d7d8a49ec019be1e82cc8b41449daa6356b213bd94e2d8a5233a828c5edc404bca7da4a00775ada388ad2804fadcd5639b5bd5ddabedc5ffc9683253ec8f7954718e161394fb3030b6eba7d23500a225c372963a8f940e32c13aae9cc9e8101ad6343d71f498e28d7ff0347fe227037d9afbf23b769b96028787fdb542392c505fae7bea4325e04a7484267b0a40c184acbe624d807b25fe19a7d38b0aac2499862a39ec3ad7d07060f5f30c138344b3829baca8bd7577812f52b19cd233233bfbb4f7694e4438bde5402d403e3ac8afec91c10809a8aad582032c047df4fbc1635396dd4fd2c1836f76f9c5c51d23efe133043bd09b1f93643ed63fe02a45f553ee15e9694eef2fd87f250604bbf020da76c82784689498c2e42d8198c1c3938c1ca32fd1dd3f0294452d7c24844d2dff8f86596e96b7e7f01e879f6cd22c1b9054872fe1d37606d113c912e1ec8ef72f836f818ec665dd0d0e94b7e96eaa6ac20e2618b8882d67ab825470cf4822cc5dc72bc294cf5c7aea200ca70947c0327662065f6d9e6678ac0afc6899ddce1e24db181ec11e81303846d5d99a9796d5d3283c83958d86bd3dcec6c7ed1d31c25e9d722b82c8c5d69a503ead7737e846190732b34efca19d24c02267bbe6511ebc32625a3d4863eb768f7c776890d82601954453de75b895e54c25b3251dd36cfc1980752e4273b32f7324b1f99654801578a9b3e0640cebc2cd670d0266cf383beead4c9de4b0a20179c2a9e9289f2683ce32e31d0984390dccd132e791ed2ad284007cf551ea586ea2765ee3e8a11ee24b7767a5e5e9a1356dce21c20f51e5a92527fd844fe2cc6e3f54d4cd87fa127c880f5acf01a16ba6933c61e8216c45f7fc906e478153ad3e21603e8166b3482b4a01681b35aca38818b44d0a8f3f9382e71d6aba12155e26647c41402aa0ac1d5c62b1d1f013dca938519705309e1635320cee6a6e952752644b3621847c1935c0e13908dbe80d71954ddbb242e28b06eb57638a2366714aa8fe7824d9a02abca4096e987400193bf8688f2dca88b2d92a8a4f03c048bd413628cc353725ff9066f3cf409e45d0cec49c434d225c8e72fef59008d3d7a1b0fc056ee9b957e14fbf2b8728c1ed377358362173dcb638d83551ab35148f7509f00004396bd1391cf8322e3ee60f09806e0fae0d18a7c0a424abc74402da71780221deb5c20bb748135c8144d0b0b32819d2127782c2f655467f0b0038d2d9929009d6a8437819059a422ea11cd936a0b675332f3df57aee780622c41448c7f1d413c89088836225f2c76283d33ed1f1948c63133f5c6e88ac158da652234a65eb321829ea74c3fb65f90ca38e37598f520b8cd35416045123d358fca0f8b0f6a423b16977d34040f80ba108d0b4a2d172cac57d2d726d4dd218e3a7fd326f16107edab383e9ce6e193ba4bc9e8ae8f5655feed27f6ecb4c24206bd1b71276b584745c81cc8eaa152c668ee18d0237f429019827d1fbefe2f7bc138da9d4ecf4abdf7b002cf32dedaf4598b8a927e160c7db6ecf8cacecc13007d034ac9b881fad1158a36e5fb58c560769b62976fc82ff8aa93502dd7d8673112a2738b6fe9995ea4d7f9e8e81a55f84bf1745cb78e2cc3a5d16faee48753ca99b10d8960d65223fd48bddb1719fafcd56a7465a17518cfc1e1a12b1e1e5a5637a69eede9cf1abadd28a37c3d629174eefa05724e18b62e1e034e160274af216761ee3006e211b384304d1fd68071a8fb329f2af468f4c1defcacde98f0dc4b3603a11f1ef886524f4c01543b378f201a2dae58ebf65e5d33e267eee6c9fffaa2484164f317e187c373ce601f3c2a8124c834b2c89f45950922224b022b2f2016f50b14bc2a3324e48719bbd8a7db61a1efd61908166684313ba2ce6d15c4a58ef236303764232feb659871a9305fc0d1e0d4e523a17e4d85e1e3a271b0e4ba03513457a7c9f99098fd48d0a1075a5336d33cac561a0dfc70c4a1bc65812827c2b8a93eba9d51b123c79b1ffa3e85eba4d506f5344a51a386422dcd88c8354ea1c665ed6372c401c107d9ed8e617198accb69cda66b9972785b63458105a43ef875b55f3429cdf7868b46153f61f465b728931eef8eb63bf1eba90a2950b44bcab4710bff3275b9e9e6489c382fb0591de9f50d3dcf68256a2e3ac06e1e206c4188dc5958fdb6368860dbeb6e50ae8fefe05a3a996e20488be786ef5ae1580fe2fb8b6b98edcafd8f62a36ac3ddf4ebb0b2b4d99074e7ef02254891611810e7d1db9a36bd0720efab49d88eaa372a13b1a8971e6d4733b18db3101748f216a1e60a0de41a3741a04ba8b958a283ca429fccfc103c86149015d90c96efc7ea67ec3db8e348666cec3315ac47b30fc053b63e488928f0d9f0f180b93394a02d9b342fdededc7f44c17d42aad0a8b024e12fc230a20fcec622c77859bf146a2c8c3390ccc80c02673e45c5a734354b346ede9da49768172f04dc303d9a9c538b72004dcfa8a98d958a371563a92e1e23cd5a248222b78e0241820fb6a1b2f765ab180b67e18bad2d95b2b273c46b4947923bdabec92ab9e40161ab403c9242e925cdba992c0126f322f0d7c8abea379f0d1a498eef3b01ed89cbf4d31f461223e3602f3c715cdb9743144faf6a81d5e664f98a6f0983458c4d69a48062d2fc4701f8f4d7b6c0b6d4cf48db098fa39e9685931c328b6537e3febb1af579d9327304ca4bc5689833efc721c886969b38d612cc0ba8890e5282439586cd16bd55d2af25610bfd5a589d48f4ac63fa78da5d8092faa2e3a4f5d0967087695782a622f9728ec3f00b69ed9ea6c780e23a636aec42daa6d7dd4f57aaf37ad2426c2f4e1697f2691ca73b0ce6b52c61f77956a95db4eda51b1729b89910fb5d5cbc68cc828e924e48547ae114a6045f3935a572234ec883a39c9407b0cc002c7d0cb5d441d9e59d48d6222ce82e17619f6070f6eb19b0a742d390c332d3934b7185c33a144adb36c5ef54da1ece811d3a35549c47c011acadb4d8b10fcd4260f29b725b2592b1dd974e3a96b0b52972567d5f0950dc07652196d0f5c515b6e1eee4f553024da43fd180d3f6da196dc7d4394899e10491e6f79f4e4a6128a8ab78563915b9efbdcbe95c02161725bee8d739922fc68bbbfbabd309ac331683919aafd66680c2a870edf42694f030f94f4d389061d2bd342df9c2eee8cf8795ee90f8980803035ab13671abecfec48181446301cf0574728bbc4f5463f70587a388e90956775f17520faa81a8454f5e9ce85951fbeefa51b481b3d5db6d8ed83d3aa7a20defd1d8ec0c6490e3de3ee3ac3506fc4eba3dacc01a6b9251fa6fb3718b51a92231d6b9fdfe20581b30ccbe17c3bab8ed0323eb01f03806da52892a38dd9bc57faecf2d985fab3629c5bb43293ee9b25cbb6d92b294a01d590d78e2cf4e64259aef840ed36214e2bca8d43227a787c2232a260b2573eed98ec8dd9a5e95b33b5dfe54715ad426cd90783a3cb221bfbb5fbe47bc2fa91c4d50882d4ce1121667415946eb021c098a6f4612773bd01094c2a5e3e2949c51e2fc9863ac2589978c68cd0b312b84fba2c0b077600fe39de60064e81d08eb6b17d06d1fddf05497f76eb6dece9d5b26148492879d54379f4b8e527ef43b39c30020ca519e78de3a29372a93580995fc6fa1671b1132ab81b8bf8e63699af57084b7e527195f3247d57db91ae3d0e8908280773305819e488320d6bc9fc9ac026ca807f2b2b924f91924c98d0a7e61090a73f0030e8185d82b91221273cc796e92fd0a9071073e0c9a08e802174fd5b8654f270c4a7399dfefcfbb03492ebbbabfb62a56d2ed9be179ae1a21a25fdbc44a4cd15d8dd9c0a25beceeddca08b123426eb8b480184d85e7888963681ff1be4b5a829b72c5f3ca2fdbc65400a1f484d44c31faee696795a314d45301fc24c703b3d5f83f3370b1624217cdcb91340ed3273299a9a06c1382b901a8c3de4423d6b0ed1d3e9cfa521b3ed181e2f7bb8e66301a6bf8c5fe83590d93cba33edfc9400f674c311091e8dcc831c83f5484e3005c3b7e800fa9f3b4581b65fee1f36d604d04ba20621c5a952c256ea10e075695671322191d2e6a28d60461e9fa906eede98e50dfa221fd05a1d0a24507f34413273f8ec1360c03fb6fa959139248e195a36318c85605efa639372cf18ee16818e38ccda324d884b6938877e12c968b2365f004e85d3824d971059a27205a318374e4f6ed100d88770190a67ae49b4b484949355b6846f6addbdf19a69f2c8e22dc10b9cf51ea3133b4ea7184b63453b6c96cdeccf2709f0e2c82a7796658af1ce1c3bb29a25e5eb37e862247e91d18b8c20019f0dbe9b72175fe4dac6f5be7f10d58eac52bbac4b9c213b9cbdd104363e224bdb74dfeb299b9ff457a2db5b8092e8c0ac5fdc1011f1abf7209d716c56e39fb6f22025e83d84ef18c89024b508f86d7549991c30fe6ccaf616de57cf14f6fa3904cbf7a0b7473da232797c2ddc5c86342cfd7d6f13be50a1c8b05b03928c65e547e8bdcb09ae38e863d29c8bcedeb6ae8d00c14c33aa2e506e25e19d4c1db6beb3c669f913cad8b665edcab0693551a8d0768f34314a41baa580c339a431b2eaae4518d805bc07af8515f43e0bba813fa458698a9c2cb472bb5fa0f1ad2f2f0da69e9001551872e9f9d61f2f35fcc69b6d4f97aa25f3e61a8f4bcdffd8638dcbb9f2c426d7021938b69b0d61974a09a2eb0126772c33a0a8afb03bc5332029a9427124ec4263b04ceeaa9af2f144ea3fbc188fe391ef010820629bc46643a67b83c9eaa5ddc1cf882a163b8b795ff43f1986edcca277fe11dd844174b047fbb9658d46d0b190d2d3b77c9e3d8126db8a9a434297ff8bd2b70e28ed68cb6874c44283f60259a8ee3881d1b8d56e2c3e014e6f0bbf713796f844820cb74e19005300ff8e15c1ccefd60fbdbdb45426718fdeaf916254ae4cc62c42ffd71282a64ffc9a91979584b5aced3197cf0d0d79a28297db934017866dcd376282e11a0abe6a766406da6097890948ec1426a97948ac221985671f6d8ab6b396a25ec93f2c0e8a109302c46e68d88143d70094a8f18b8fa8e009aa81f5ab2feebf5114d5aeec1e4988d90d1461f6ad7e490590f35cbd664fa23ebba722d29082b92154506f36e4f3a4bdc1f4cacac94fe79a78a9d046d12769ca3420a74b6436c028ac63240f87f56dcd6bb9d8a7b85e38a86a05ee0cdf1f987a27a38708744acc0abdbfa01f1e3d2e56d2052d5fbc38f6631d130ade5f4822dbe4128e416305a2837464064102dac64576b0014985ac323e2743000e209a2633fee1d7d2bc3fa380cec364f1715880722010d7997736364a56bd675b8a9437a5feb21b515c2214d02da0341abeb52a8812f949e18df1aea9812b08e8d4b7821062f7ad2a8e8e2b6f780581eda715af9f7196116af5f0090b6e96a75960e802d20561928c11153574c0aa24709d29eacfbe849cba0042147afd639cc9ecf9d1103ea01d8a611f33b1c4909489b3c084260e44e677ac5c6e80299495f61513e7580fc25d0cc973098872c423ed8b75037e8b507ef170c507c550bd81541459421a7ddcf6151fe44f39368e4d339ae9b3e5258dd6a7f711129702af4d9eb38660713c760b3fbe3050e008eb6a2d50b883b15c4f012e4a58929ef14c9a9a8e0a9ca6ff9be4059b009428a66b779424794194c561719b529f6da15cb157dff1dac6909db8469d58f11c5152d79f7f7658cea8be8fed7ac7eda24c28c9d977caa63b4ad9c9e7a227c4540f98b5d2181ddfceb7539eed8a407d875f3e30ade2141007c5309a303f7ec21e8129b98746d585cc8e21bf0070958a0c626ae6a6a033557945a3df8c3233297ac84d6a020d84ae36553e2da8fe66a222d4d1ecd26c1a28d1952b900f6a1ce3da235767c663a945af475a5a5d3e83b8796e9c86c6298aeeb44088adb8b2c67a4a6e57209c0249ede11963cd211eba3c73ff48fd61e93189078ca4ebae1047ae4b12ce492cd426bcee744dccff9a2eed4d29fbaf1a4c1a9da2955021bee4b98a0dc91581f6ab14624e846b972daaf41d168a5b90d9d7e4be6896077731c4d2c9a89cd72addde17d7d13d20d2d7d55c84ec4c3060b4f65435e4e41b26864a6051943b846077a9692bb06f39aba0ab6c92214bdd8695ab9825fdd3c030f541c04f7aa27bbeb48f0684d9faa714e523535c18507348dd056f87d69886254889fb22fe570bf92c7934162078afa247c9448b8bb2a4f2a558242c35968f12734c7fde7b941a75946df2493980babbe127429ffd5e54f6742e38989c75e0202d306f3320d1365e50c0ca6862189ad9991753ee0f418248c34c49e5c1e5a18a2f643c755412297cf04d31c8a1c51912087c7fe8701ec9de61ed03d4b928ba02c60912995124034975e156cded3d047c1acb62e0547d03d8b614b58180213229128545a4bc8d7054bad6178c890e7be9a7aa311c940ec2c2a5a74715ca5169fe05a46c19304346b08cd4f98af92377fd55dd7f02fa4bce4afb1c368828914e18f0e1d6b552ffab6e7f0d7a9f8874dba0173c16914b28ffa8f65ce78f748659874ec8e1bb62b2c4518590baf7b7128e0e7e80bea63b92449f9b75bae87b31ad32efc709cc7d0b361927128133850836d91262d60ff9a1088e82313fcb75ac6ebea0372052fc4770de87902e1045f0913636ccbca4c7f08afd43f0e0c6c438af1225c30e6d47232c556d481c1cffc15b0700703ae7beab17575a6db26c001fa6362db8559f04c19c01b3add089c1351a86ec38a1a706921b911de90fad3c0fe331e6761016db3f22f64518954258d548847f51f2ae111cb2091cf1dc03a0928f72e6a778ad5a4ed9e95246a862c1fa7fcf588a2a74962105519245f132c2a7cc8c608b7a0a43d53948dfa7fdfb8914e5f3528ebfaae14c5e9f3800c244834df823e1a92c5dc76afe0981a1594ee5f84fcdd80d78e12c34bbacaf54311d0a9a198e1febf7a3a00628006041fe9441a7cce9028b176ced3910650b1c728eaf471ba2771d5694740ceb9a7cb2c21cb400ea59c147e892e581884a920a698784a2d316dbedb5682f570eef94af5590b4a5d5b68c96558080615954539f6549e49f3e19af539718614808eabb7cf2faf5f25853df2a5d250006378ed18b78412b61a11254a1eba07e44aff7195a9b191b9c76dd48e5f4aa0d49909a6c656faba25f69a81302c5aa2be74d6bb569ab5837126cde7e128326571a341f7846e8fe931a02c579e686325a79d0cf9006a53a9d6b4699f6de5d36b010220cc043054c08d2d84abcccf57cb6606081fa1a0b3964b1fa86a9f7defd40b86d767695d815ea94176b4bf2ce0647fb1f8dce74121fca80c35697b23973de68bef8d6772ab48a91be564e018b74b6bea7d0da239656cff618289857cdaf5d4edc3c0e57efaabd24a32e8b259aadf8dcd556f14fa81b521dac2210c524c559c0bee7e2996e8228e4392300e867378fbe1aa47d7f4ae87bcdde886168ca77b40a6dc43758908d14a250d724cb789965f2b369f02de9dae290a9287b58a3a169d5c8103042dcd93ae41f04f5b613303854faa23b772932e4d35c91947bbbae3c1319850c183a13f8a18feb2bbc60919e2b336eb548cd34c9a45230a80a753d8437e667bc34c58e700ad0349984a034371ad82222a71a47eac222580adadb05907b4fea8fb1f53f5c80445a5c56244120ecbce1a07ebe0a1cc28aaa01d993d7c8561dadec743e60557c39a8a6418c81b60f2ec13b0deddff568af1e4393f3464156595576409f9a967f115fe80734a188855ef1eb9a91bac3a1fd6e834290ffd743952da02e8f1ae78b5ae2226b7019b6a8a08171a70c3c8de0c51f8a4eef1b889a44b454ee3cb78ea6588f22b3d35c644def13566437268fd309b02aebb2fd1823c483346352d5e8b915cc04513986c3458194946b863696719afa6d424d7a64f331bf16cd1d010330ba613c641a22565c855cb73ce187431b2c877862b6a6c6bc4a3581c7bac195f2d12f198416c181b821f5484ace349c19de3cd3daf689e04362cb2775c2c57d7440586b05091c2851f77058ef4cf1384046ccdd6d3c38fa1696e132043ca53ad42bd84b315a4da196871ec06568d3dd40142e7044e86d019ad834cad63453af308f83d2966b346cd88ac2a423dbcbe3eae8205c1e3b0efc4cfcf91644bc792301cd35e30df1d95ba08b2c8d8b3aeb057561107dafcc8be63ace18f8fe865e18e90452c19c00d584a24c3d449da5ac5da697504f996b633bb01580a5a39419f9c75ea1bccd74430da0744c262f67d66b66d71d99bf7e6b89085cf371fa83e790f2b27753c6f0eabb2417539f1be2c64243c7bc77bdd4bddc2ecd9559c4b5c918b1112bd63564483d75872dcc9b29261e3b2878953ade2f8f28c318f70b568c194602f08e2c21ce9e9917307f88c1ec3e2d159bee7c8f23bb83c66a3755d76a7712b0f345633cd8480be2eb7627e904443a103909769d8af9435e9a7c52b076782c01485864a02060ea36dce92ff6e46409478b50cc69ecfba6ad30908484ff5e19e0bec1e2114e7e116928a7cf522fe153b7180572efc00ceee29d70d247d82b084aadf1f0ea853949cc04bd95df4b0ebabe2659786ab067c9158c9b69b20db9c89ffa4e517aef8a048091aa278a3d7db8f44869a286686887fcfa28a0d446e0fa0fb50eae1fc2b3bf139c1b4b615ec9cc24c363e7c1b0a9407b9571ef28ad29607662afc3a0f08832d9e982cf3b60233dee434bf4769a779dc2dc6ccc6914a141c14c28e45b9559b81288666d9337e64408c10a70d11951da1030fc05762a475c414ca8e0b7a9ae81e7f64f019e32fa4a3e07856ab3b0d8386abf8dd46c1324791916011199f31aa8e1d4b548de4281b40532f844fb1f13926a4c648f9d7424421c00f963f80022505985ea3c9728b97063081ee316041fe8ad80e55ed205e19d8936092b9e562ed6691b8de00e4a94d0b12877dbcc2a5ea0c6970630c3f6f2750a60e0e0c23a33099e5a9f62ca77e2cd6a74f4babb30687d6d5a7a5160bf67815c52f6364084532345d1173feb8c785f5b6eaff3690093ea79f2d2daa3d1ad62dda1f9450c57fe16bf710d1a68ddb0a79a23de2ffc41249df25c516711d21628564880922854d0a29299cb535b6b5f0d897563488fedb395653c338e9e7e9ca3e4c183c095a21158831cf26d2a39dbdf470876c439a621c8d7340b64ce9e2e9fa3f173a762a0e50044028152f2311e419510199744a622e2bcef785e2cdcdcfeb5d25248e6f5194f161ac042a4196585c2b1aad29a1dfd493ad74e2a4ea560a4b72ea184b6ba612fb1348bd602b1af0b6433cdad6116149e7d0220ea381ccb32ffdd70b5594a74963e4f543df88d5cc8d9b60c322678ef69ea5f8a978f3535e06884ebac0a3a27344496b35ff26975cd9abf48f6eb84904b2e10d0599e125e11819886da3c27f626bec8d4049b920f1efef2906932d26abcd36cb2708d37b2f5e7eb08ddc5e5592a317852da3d74c4f66459b3486cdb8539ac805e0064c12e48d6a042ecdb0c35017efba3f7ca28b9a65adb8f315298f5fc72f973612ea4e3f63a3ab6fff65250ab5d128b7188345b9227809f4c3c77f98dc2f003e0a2918f6ba2298b2afcbaabbd6e65b5cbd78cf15becd0add5664cf7ea039b281cd1afcb31068122b16a50dc1185ef3b7f22360c15b1d3447236b9d3a2bebd18a78857e3a98e68344797abb3b8234758d231b3f93d0ed9b9fd3ab4d16d430659396d408a04933d22f629e8db49820dbe442cf0de67239c87b25fd52e7d35897c99b2fd0017edbbc2f8981a3877c549851658f5823525523c7f6d5df3faeda75f509c6fd46415d5e639d7291f27e65f54c298b250031ed5a0a9991941357111d9968b42cdd9c7933bd6f2cd7492896d36e05f192b30efa9a908bf96fb17559e423cbe6f22bf7de658b874d0d5e8e2329d602d2fae4f76d84984537728b1f8fff02980ee05f8f121a02da0925b19fdf719b04cca81ab12113d8ba7450cb2c3360d6b3e5280e4b477618f8cfb7f5c469e490808785d4e6dd26ed3595ccb5ff52d724d2025c9bc70dd48e7d42d974561a8bbddc7f02f1c1e1a3a4552824d58ca9d3c54521a06a5510dc4da7c5c4b92e888423c961a1ca26dc83cb2619b5e5006db9a4757ccd1de468a2c1ad660ed898c1d438dcbb4995aa7dd6f74f6e95053e8e8f42e79bc2b76aad357d4c15455cb7259fb3214148a9b1110141f16a2454af0dbd4796aa33bc316e373f8c804e070ab06b5fc29f05979941220d0501dee461580ed97a6a3156a9cf22495739d7478f73f2c390276d9c5ae590313e429ad649fd38c4a05b901a6bd4db4fb4c48d9f58660c17396b27d08c346111163816de83df4b5228a19b2a5d361773f3d48105b281639431d4c4b0b2c0f4ae2c5194f21b6e4c4218bfd130483d2778e2a9bb734dde7793f6aaadd860314d2878649f334dc3ae360ebe726f14b5cc5151622e7ce5f36d16f652fc73476b595a827179f21b0b8a6720a038f63a4746ff0c6dd7d72f13e0c9467e9f12ada058cf1b5ff601b9faab9699621e1a067fae3b6fff37d171dc140ac08e4070c63121b0fa3f40e418aefbb33a6bc641bc38942d25bb6ab6b0af5943b4c97df93e49716b40634d469c6f4c99efe0a3c4357ff80e49b4a74461cac0963421bc6ff5321fd27416da8831d48a2d8d288ef9707df3aa5424c7f3e1235c7de7010366552d34a3f283ad95fd49f24c748c0440b40c4ced1a81e2f03b97cc1e7a474055b9976e8d41363bb59ecf87534b5603781507f0d36d9ac11f938cc61ca97334eb093ea83228ca38c9a963d47cca465c85fd2bc2931302a1685c12bb6a0c1c5ceca8a8b6355ffd9dd3f4c83cdeff8feaf892e4b1170b15d2e467c112ada2daf3c97ccbbb25497c6f2575c190112768af6300e3fe61e569c8aacb64e7a1b66fc05e9429f6ac4d2bec27c16afc2832a94c45b6c666c1374f63699579334e438180f501fce3704bced8dac73309a4f03772e16535a0d5078723ff16ff4db32700de2e1c74e3f0c8a912a9ea9fddf55e11fe11ed602c5e2126a0832ceafea72faa1e18c20f9beb7208c631207cb8995cac765f90cfa4e0fafc2890fdc9be35ea80e940c5cccd7006618d126c47ed438db4d1590a0e5ffd0b1b5b1e8a3be814058980a0ff4036bf521024163e77075848bf6024a2d0dff9031e076749a9f0c2526444a214ae435c8dada778ed459195ad92d497125138f895fa09647dc1b6b948431fd941e6b77fcdaf974bb51e2fcba1d3258d3917a8a033c665809acfac852ee792d3b049c376007cf12ec281c08c188770b3adee9728f169a46d0d8c869de23788fd52fc0e125ccdd7a8fa5d70c2390655b64eac8a832046ef026b4997073be7713b1a87b935ce4aab2b7cd4c42c8b434e27909858cf8de36adb7ffafabc0bb0be24b981c472b7b3b80363de9cd4b3a05ced36fa8b2664942042896635b78f6127ccc1688b381290ef02f39696b15a236f900c8b60919959809b174e804018322ff18eabf27c145e812e600840fc3560b703ce2c35de73fce8a73d6360fd713d6fe89db436519689be67e4a4df92db1709ad0178c0e939515e39677c93d7a182b6a456bdc94cf3beb0d33b7653ef9a7603620d28606c59c723d0922eed6433e2ada1d4f0077b3b175571dcce49a6b7fcde3ed74889444e0cfdda773ac3efd8003357b6cc3450bc0eb90e20dcf8d981c383697510b8fdfd36f87e5bb76f20ae5037773950a5e4488c5ddd149b90a6d8518e1883f987a34d8752e6656ada86a6f7e23a2ee4fa975bf867e6f27a4185fe7d15360f0dbf8efbf300ca601afbb84ab62158ad62c2afb6e56a69ad50aaf4afacdf0d9fdafdecaafa694131c95ef2e5513869c161068098abb44370c2b676b17ea0274824f7e46e9de6fdd6752a75529ebda66c9b41c407dce420c15574094eb382ff8f6b0909dd54de581d09ac5b442adc1b7c0645c69a18e9af8d46d50f90b2ab74bb7680d356aadb8727f124580dc205423db9fc01f7e650a4dd9837706be68488003b57f60bb629670181f98503c9f3a6da794979b90e6f23498e4a37b0755ead67bed2517ce6b8b8a2e29cc844454d21a6c6566b9cf6e602e6377e05c1a8bdc9c777592b6d31fe4690abe5838db3efaf456f0bdd96cadbc911cf8603fa460e9f4306dec7bc31733b64b3a94748da7861fd0433b1beac6c0b846b775f3a8b7fa569de20a47424ecaa1418df9ce9ce83c5923918de61a666889b2b8cbd8d64f9cc5a17960a2aa6bd1cea3ebadca72e7c3bf0a81e7f58bac001111481703b6d53c0ec483811a57722442d012258f02b8d038ea59c4c5c8a89f3590d6865278628950f111b44c1617ac2faa1e660edabfdc30e617bb8d77972276636d0926c010e629f56d98b8bdc1b44fe34cf623925212c7e39565c39427b39676e49784ec828f3ac2444e0db8cd3863a49a3904ea4b2d590d3c65897d19735f6e807168e1a9801aa4733231069fbbbb04420e746614578b361a3a5a8d11a29d7524d3dd4e2b601d7686d2e5f48a8cd533bbe2916bd401ca0659de73e815ca484c10c928cf2fc06e9c783d220870804721d7c5e5f25137e65af8c15120e7b8e7737d6230339b9e9536afa077266a317f2afde4666c4ea7564d002e2e5bd06cb075b1cd7271f671cff9ef1ad495d88cbc7c9a69eac3f64b41d846400a58320040ff5067d10f15f5dc925896e0f7a5aed9a70e12fddb6be357eaf2ba94ee386bcd64718d699ac1e89fbe35ae675e71d5cd4e032a37581ff7440b302b00f3fb60865f84e9ea7f64116794e7e8cefffc4a6d037f56afb055ef4bdda9a3861a45e4a7a0bd61fd3afd8b318bb52e5fd29a2cb4c0a86f438c21e0a07a7b51031a35d6b14c8c13306a7b24550a35faca6a5ea93c6d0e30cd7c0e1e48eee7815c5ce95689c775abb2c7a863015c1e5c98a6be79016b3a411c4247d027d23b1a54fb87d1ed6fc4fc67adc3478f7930cbfa7375b19eb718dc93d6fe2a23870afe36f7b9273cdd0389998ba0861fb2f628bdcd5b93a1c22f0e04967c70376302a74ac6a930a146cdbae0dce99637a064788364790d62d8828802a82a8117d4158a282dcbde339b29dbd9d4c0c0ba73c75a772159bd99c878d36e43d373a11198e29ed1be7e097800ad4521419d2640ad1fc7188e3959a54d7a97fde3dd8561f89018cc326c8a2db7148633bc50f0b84874dc33960f13f7fe101b703a5fd5b4e869cfb2d8c36af144517e7d6e853d79a7174f4d8e8a209e2e04118230d6568c04ad286559e9a45e60b2a3bb3ec8cbf945de93aa9a235a25d27212eb467208a29af2f925f54c26c268fb188b161ce9d40ac46d81915b0d0a95496823f7a50b2377055ddee80c48b8e2b53a41d4960d9f96879870543ab610ce08cea76abaee01eb1dc8eac3d82fdaab865372096f0eb59ffffbe84bfbfddc0e30cce92b4a036f52500ac161ba95423fa5a073e3df79886663bb8cf47a83899f0c8cc5ab0a92f23d148fd34f905ce53aba678ae24c0f05b9ca943279e6ed3792e6b84621ed4d70ea9f8d0c1c1a4fae934a21ba372a95a3aa971e1a3c01393eceec0ae382617f7b4cde764ce9f88947833615f35c4851097d02665510b5aeac1830ea939a56e4f70d9b907607807300dacdc4ea99954a0832a91decf0ccb9384123805d2d04d1c1e3eff7e585c4a663804e218628e4c30a73ceddaf31a10cd732ccb27a0a439b06fea25971d8a265b5a9b9ebab7e8c895b6c07f47bc533daa1d6fb4ecad54939a7141bf16e76dc2e24e4b6b7d4a52c795a0b6bcd9d49cd0e7d2321e27dd28e04b4c8d1deb5ddd630bc3ba54292aaa8af8b8e505007b8df5a1ef9d47f52022662bcae5a43312f34b0e30f41258c97ba2b8c1a4f23a2bec88ea9bcfbba8b67632fb608e8a55388a3432430156888d800a3586fc621a20a105230336eb54a3c5c8642454f0d7d9d017e22ae180aa97252be88c451a9f0619f36b23dd4865749c653b2a9dc57afeb2dc317387a16ea83d1a245c09296288fc01ac1b3d3f246bf461872d881d3f669be2243e798091d6fc3e9f81bdd182d3e3b696dd9f691f7ffed2f99c72de8fac7e59e1be504bf4f29f1b4e94f2af7acb8a4e13ae22e6e8b66e5baffbc4bc0619e4091ba4df58d189def3e8abfe3d6f54cc19c3231e2660dab7632573025099480d5a1c46b3ceffbf9b847c1be35b22fc778e1ec9ba75195c6e2475353daeee485a468fe2d944e017974cdbc2720316b53284be6000c18bb1dbf4a720d281843bb19bc48281da2d0fab33162fe74fe5d587c0e721e2daef9e5495939dfd621aeb718228b6478de75e816018805604d4e347b2ec5a5e6e4a61864d2ce4481c39394e4878b1626cde2b86cfeaf69bc9390fdfb77a55c7855011f89873a898c60b380c1c5d3ab0bb0dff9352f2ce3c70985456434d1faee8221d563ab8734652e6889585e4f9f5af9eb285c7f44ffa13d9d006861dbcc741a55293fffb0eb10ed16f924eb1233038a934f359507ec0e4980f2dc192552ab7dbb9b3360c11fd94166daf4485a1e06fd1adc86a97577d37e4f88aca80d49cbdf557fd1584a21515a58405c3b9c280e0371127a96f22e62d062393c78bbe3330b0989b8d1c506dce37cc5011b213a52a6823c7e98466b1b85cba1b9f3983aa80d2d113f3c2486dd390b6123fc5c54c5f083b7ce570062d5e6f0ebde9ed53a81f625c8dad91e546a707f600c8d9095335638e597acf3cd3f8135cc4cc3aec52f1f208ae2f145b91455cf3da86313f1b4160acaebc9f3d83b381c90620d341f9989f95ce198f3da9408d74444ac9ed9c55344e23484f74911ae0a8831bd79a66dd97869baa2f431c9514f38cad5b548d4b96e07f96dd4eb4df23e4bb89f5be9ac893c97c37d9f07c25ea180a712e295da1a008b480e60b7fb3547cb3e44dabeb2f394911429f4c4c4e6beecfd93a618e024899e6841937af29e916e74369df6aee25f86f5fa7aca3bea0a153d38c7cc4a0952f4c9513c1a9615a4853683045f81b0c8956eb15a0e39059f357aa52a7004c39f03e446030d97657c547f9ba449ed312cc7a4ae8275fdcbc359b6064f912c4e51531c697960a1ba83c4ad1e34d1d5c2a9013b386a6df37d028bfa32e23bd642c9f888dce522cfcb9ae920a10c4939ea3929546f700bb74ad596931dbbb9c4a7bc7d2a87a512020b1faaa8ff026fad3309b56c91c8e005bd49c07c63cd4543a713229672f1f125b105e5d64ce86b140cb246ace69f72850aa92ce58b0d428c2144ebd42d7c12eac34bb992028c0170216d73ed9a4458b32527dcd93f36573cd93b7a8744356a68b7f2e5327eac616aa24ca59485a3a529a63e5c402226756452e2818e41f94994a74d31fa9620e065808e601f3caa11ce0a11ea8569bf629ee2fd815f79ad9e276793e1764d37095d6f51feaf9fcc203448ea46c0039739239e380d4ed3559071580967dc47cbac2f2b270c13d404e7e0bb0e7e126fb49b4767bd9c024897680724dc81cb5a283f4cd76db9ea6fc2a7cda27e154dce045b569deaa6fb2d6ee00ec687a425e68b349851c14a17fe20609cf1fd10d974213224dae60a88b0a5a4ac407c5da1bc641ed719c17a1f76d84d750936e334ff0b1b318e1cc622365dae7ecfd90bbf080d20fb18901db7c82c0d01b0d89682d34320075189797ba87786fb5c32c407a8199f58c6bde793d81a3ce332c27189c694fb9048c49a35892c98c2ab3515753eb6d99f8cb162d34df62e0514b86043d8d5927605f467fa6b9c163ad2369db0bc70e115271967152dc574063bd86a697ef437dea8537aa181dacd4d698a524a8a03241b1295c71d02a96ac9b411c390aa05229eb88490e04ca80264d4f95684c5b4493a4f097511032f2f8831d61461aa8533d1dec0e36f54db01b914154661fe6f27d904386cd968148ba17471a630419b2f4fca3341401a3dfab436155331e2aabfa7ea5ebfac28f35ae669455fd2deb75ad4ecc16d3ad40ca50030931643c6e711c6227ca221872a0724db5774fb5175533f896217d2a589f68484eb43efe83b944733dc9f9bb59c650b41af716895b313dbdcb3dfcf5b70b06fb7077ddda9028e6ac8f43612afa811416c328bfb347721c70ccb2d8772708a779455d463237a3abf217e90c22c209a467a048f51913d0b00c5598986cd3812bde64ac3d3f8c5ec962e5544689ac9fc0075bd5f5158fd12ac21220ff00a13f6d2b3c874351da4423b696b69eb3be66a77f2d0de8ba544d9c958559e59b3d86377dcecdc63099ae71453deb01a99f4c2417ea711791e58c627abf905155a87125d135dd01d5a15cb0dae86d6dc25399af3051dab2564d054295ea402dd804d84c9c296c3ee5171d16dad757436737c98cf8fba8cb2f314867db58efe42ad9a7555da9a99726e2437e438aa80fef2efa163486dbd40383066eb38ad83be06ac7fe1ec0a8cef208400a62e1d01ade07d4ef90e4bd453fc8440ceacf6b8759de100919076b7c53dfe103a432f16df220c4afa55118c3479aa2e12ef1247682f5e337c92948b7fe83c2b68f7bd34b88842b504bdeff29184f14008feb46cf5c195a6ca075b071ccf5a83a8c8de74f4692c5c93fc3d0db80c357423035c4d96b0398e252f8b3d24da457eb6d91911e90e6a745bec1aa5991c0149cc589574f28df38b91b7e828d0f6538cba5aa61ee655090e7f4823bf98484e137ad4486340a062698a472e8032dac4e808876b09a476fb434168e2f05e0047a4c8236170011e8b9b2466962125c1ebcfd944e2d4c7c02f88add49040d6fa343504072e64d4c21f960e54f2dbfd8d70c4a0f73dbdb87cd80a6037e9bb305abf718d02c2d63c51605bac726ae28cf8c89235cb13406d284a5a959ec88692d098e5122ed18f1150e184fb8efcef317c4c807421cbb021abae95e5b308c61a40e128fad2d21af3cd6f81ad1c710069ecac5169da30b57394f065f249d0abd36f9a3945d0fdc77e790cc7ed02d73d47500b3ed0030eb996194ca29d5354fc49a9dd3ec11a3ff2155eac3b55967d0a025aab47bcb94920c8d054006bb054f50c00de45c1f9a0b5251171559ac9e9e7ed6586979ee49d6e8cdf3f9ca72ee49e610583638a3447c3d5965c725a6c116ab917b5a1c453a271ce12977dbe19e8dcb67ee798be43f492073898b547cedc771c212c2fc44d6349d3b036d44464e4dd9310852b51bf78706f4e40f749eeac2b551a0b5d97c55abaaca58a75d765c4916754ae4010cb716b94de44441a33af72c4144d5b4bea4d1756efd5835f7fcf91999653b6bbaca8e69361325483064227b6d049539feff30a32366c339b55a5b6b596d2d7fcab2d6b29675c73dcbd22c3103920579bc17947845784596f45ab867e5f1785f73dd4e09c72b5f747a40b629293b265f2fa0d9977bdadb744feb36c419e96549767c4b516c1a3c5171635104f95db838b3b927395596b07561fa91d612b927599274ac1c17092b8698d615aff2a74b6ec5d7301eae281afa0f0b3a4471efbe4970d359b470d3efac785ddd93bc4a2e2426dd7be18266fbabd3922e82d9f10b24175fa35d6517190cef69cee8900f0b7ff6ecb88b748deced237b9b906119dc70cd999b17a0d16c4de1a615cd8b493332b9ecb2e359895abea0eef9aa436ee9a6f93f794e30068c661bf685732f8adc3d6733af2d0496c706ec898e13bbc5a73d14c4d640acdce6f5ce4dc72372b8e7cca9d96dab1a605163b3bc8fa9952c2217f92f3b065ae13ace4de81cf7677f55f7c7648148d931f9b2d54efd6c55a7f955fde8888f416b940b49c46ec2b185953d04a231e21c1d7a6c845fc0b89d8e83f9346ee11686717be133018b451c821545dc8abd786163ae26edfd98b8137db062a2eec5dccb725c314787fee9ece1fb9680970e3df6a6311074a614370b37d3989873d383f97cdffb72beec58cc893744defbe802ec76506ef9b1b6f6e0b365f169810b3f16416b2d9863142ea53588f087082dbbd6edac6be56f5aeb792c22f7c02c0cfbb82ca7234e0f7c50713fa6d5db253635a998698b317fd8092337259325d819f05e00e26ef4c6e4cd7ae57a197346cbb2cb8e4b1039ce431071c5ddd7816dee490382957fe47ab9278d86815c3863c49da3903197bb31e290c61b4cce9b9f67143b1fb70619466b8d45d09a05b5b188ecea0f14a0372bb9c28e445c6b158156b8a38e8e703ca670a3b731f732c723ee650e44c3c873dcf37523cecd0f82e4c863327eee7557ee69b301f25cbffadce7d13dd23329f9ef836005a36287930a4728c272951d7bd05455be8adc346272cf575680907b52a18aa2afbdfc5fffca5ebee0dc93cce4157394a2774fab80162e087484e38b832cb03b8b1447c0eceeb8c6ea3c19f68255bd27432c3b3756de378cdc7471675865c23d6fe5ddd3798e939c85bbebe895c55df365b60efadf60f0bee490ee6393af77be6176dc4bcd448bf0a8f09f9b70cc418c2ae4ca64d5b7eb9cfd2a3b35e522c5cbfcabcae115faecfdf215e752c78d323051f943b4941d1739b03e9107b13137e03d8988e8533ee9140d52aadc44444454e6f844ee9665599a7968e615a4ec7856a2ae70d331919a7b5a6badad224b2bc1ecf8078856620aeabc7cf724338d5a25d7274a4b9e30a006b967edd55ece4490242535ae9c117fc32e697eb8aa23a9114888babe81972a3b650252a63c643a85cb650fa888aaecb2e3220afc1c423d72c3b1fee00dbcd19b88291bb0b92751a6119969ee4924c3a990ee215c8086ebf8a452f7b424ed971d9720f269a4ce1dfbc08023da01a6547ade2fad0914a59299c4096492332065c7b7a4bfdcedf380109945f6a4db41765cc2f6b3d4941d63f3d79783dda5d4ecd8abe99e35c97740ee525276fcfaa93c11773500955bfb5661f45677776e8bc8722b90a421ab4b63942665efd82b9f2f787fa7b307a61155fb7c7fecc888e94dec11665fc641d23d316efc6599dbfd57c04ce6c55394b263a019365d5e337299e30f1df3c04dc755ac6285e1064c51e7714f5cb354d6714e48b3061395889db3ec8d83012fd029c1ad712b7d0dc6931ebc1d369a6a48ea71ebdf78c7d609e2464b0f3550b891dbe1148725030c1e72b88409c2a19a41ca4765400a1b31466caca103074e6b05104b7fc74a072f489c254c374a70042449940e2523403234b0305909a90104079397189e729841b24311a92271c816281a2bd70d3734c0c410430509878d4f41694d12304f6768783962451ae921f382047a499068b051a107154220854dd25494326fac6e304343872830335088c1db98786345c81c253e88e4de84502293c27c953c2eb05121871d267c19e28409c7f485c8cf68cacf86275b926461c264860d1450a0c1c999148670e28c627c4a1e335f627cf9b2431628ab0f6486d58a9d1a7a6090e488c3bba3620892a82b449c8469220515471787c8193247a250186245ce103141703be2b48e40895145ea862a3f2f47be871643cc4ce121250a8e3220c208f1428226483bac90a736c1a871c58a1312e05903a50339a3d5a326f9208a1764e1490992d20d72d4a0019244cc981d348b12928e1f3c82ac90e3ed6440c58d93273c4568d0c111c980f8a143cc9089481b1ee004c901060f0f94df0c3228c130240e9bfb993aa9d1c2fa723d5327354cb73f4b3e6d19d4f17182941c782530a18425c1a91884e850c54c0f75825459a2a27a68b99db4fe293558b2739911a4061be6ec404607913b66eaa466299f66104e09585be6f4c63352b927d3a734553a9eae98e913540f20a6aecdf4094a4ef9b10bc22d2f00327d822a935d993e4149e5e095ef419dc0d8b0a6072349b80891f920d2454a87194192b4bc71c560ca014c93314c609ed82a3bc8d8b0e18a6f4948ba116d18145e50a0426001d1c2d85acac4b9acc60965904f85748b11276ba0e4c085cb0e608062843b50b161ce125dd522446269184f93f654040eab714f51619ea2a2e456a64f514e784a00e48910344a51422433b713678a8f6c5fab378a6f638a67aa491b281a9c28990168a5a2ccf86115c75795650d155a99e2c1a60b0b5558a0fc04a5c38408d2931c6e96086fe7cd144c05904459d3e54a0a355cb8514c3540c3549131823a538e282969555d39f2a6a98a9419bc8c50a38d5a0a416e89b18cf49c19910cc7f7e15f83d1c21c34347e45ac48d111c685a4b785867f4a5bfaafd235beec6ba864fff964eab486853c66eab4a64719ecc9e2c240ea524c59e6996622a4e483aee0af42533228e4bd7545f1f8d4000199e20a2b41477ccc0425e178c8b1df1a7662a0a02ef7043a51dafeff45a07151a0ef59d0234fa0e6847ce5e4fa26bb44b24d768d648505402abb58648501804afea95269b2637b1bf7981f469d6ef0650ae479ec0873c75a380a3b76dc1431c52e11e663832b98f1dd28140c59946eaee66106e1971e11dfcdea705d4d1232b966e2a28370244518ed32478aee566117d0b9b958a408f31b3034e9dd2aec430cc1db991b544db4457b40f838c0e6b384fcb8a55469c177abb0b14c8fdb0b7670b9c5671f077803898173a31c3cd5997ae281973bd6025f1e76c81da358041d5a401d5f9da426816be5e8ebfceaca74b99a14e1ffff4911aa87764f8f8bfc2e2d731c851bf3677ea802197babb3a3acfaeaadbd50ffa1c7344dd3ec111de78af5550fe68967e35cc41dd5133b3b6acc98336770c021bba072631715c50ff8f67811ba25dbc721b9aee43c1423b817173d09ab6ee252043af45026940874c85f469b76adaf5e043a1402f75f5d8dd8da7bbf2c477c0e209f7d95fdf4abe74247d8b87fe7addc743c94c36de1f3adb20874c87337141d121fdb0fb1f35e32d672c5ce01e4c7e700720baa0717798f78d2a856543efd4a8c3de9988a0bb18405069ddd22278d00706052fa3dd0eb929476966aaee458a64f6f68e457a64e6ade64fa1b73b8dc454734f6f9770c84dddddddddddd4ebb2b9d7c92de793215aea16d7f8681b0441108297e8433ca2445551fe807b3c0fcfc1757cfb89ee9d31b102e0ad4dddddd1f2881da5aece7eeee34e64e762fe1ee27dc4291dd5fabdd987a15baa81b263ae2e96af744c74d07b41252493f9b927b963ebd7bd268d6de0123f47142230d79715455760c346b51f17dbd2aabcc9b7bb69b13e6460e6e2b37ddc8b967f9f33d3651be273b46c3bdf6abaebf5e73d2b8906e776f30e7fe780b3b6df23aa338a83b475a98d2a69452dab8525ae42d584fb9ec96b7bcb7a564dceae6b54bb9b15f207759defb1453b2bd8b28b5d006392e00732b810237b78f5937d1d8753ac8e0dddc1b8f8d28346e25b40c53bed0f0a9722b810233b78f7923a071f70047069a9bc37caa087718c3bb75195d0fddcd613e4e7c29b45097d259a3c81ac5a9fbb8babbfb8f621dc51ae6bebbbbd73162fd9d0f0dd75df4eaefa3902f58eeca67c9e2d86bab385671147a43877e0a8bdde4de54de695a4f591cb146d1e8653320dde4274ebae5033af4958ee84af6c894fcacad45be5c6618a005ded2845932c54e84fe91ddc81acd7077bbe04ee9e5b2c63fc1de7d10aae15d20fe854c10eb8718c53a8a7596068f626d3dcc9b44630b735dd628b2465166c4056b14ab15618d76bbddeed7bcb1eedadc13b6973516564db0dbedec6ed7f5a90cf7ec5d2671ac853b864f9346c66cae9fed89dd56ac9c0252b0b3bbdd6e77ed8e26b90200ae10026946ff144ce07add90848c2ce959f95555d50f85c2a99e5171d90bff7301014892ecddb37db9d24402b2e4160eabeacccbd20d194e97925d063a24a5512cc1e80f88d4376475c846e1a649b84616eb6802144c51510c97650aad10906fb158340d1080310b37ddb37d8f2bfd15fddc7fb026c1894a30f5803861e4191dd1d87f18c0a02be9884abbb078b4a84cb54d1d8040a091d1d7aeb5d6d28cbe76adb5b2a97b52a08bff69d1b90702abb8b8beeb3fa642576c0b25595bfa1ac5c72cf09162adb5b322378dcfe733bbf52c5ac858a8625155558c10e4e485e228d6b1fba88566d01d0547584f65f7a08b664b9a57f42ca117accfe7f3599aef6bf7ab35d95831d6319a593a8d7cd2c2e17016e713abf0e7f3f96cac7d33a47b36ae9734ccbeac6199be08bff9d4a52c111680327493e686d1dc3e3f71b632041a4f6ed15515d4c3e512eb8bf5856a5cb17e531dffffffd4de12e7729d333bf7b56bcbfbd4e906b3cb1afbaf567f904a9bcd96eb9eedef58e63ab7943369361bade2d9f985227e2c96587fe808c72b1a458d5d40001c489245b6b9271d621bb661fbb2aa1eae70d18c56b0623868c64db26160afe7868b46e092b9738579a5d861f466bff641b44084c5646e5cf313dfa4b5fd21450b5399080b4001562aa366ec27c68a8de78bfe965c6d5c14e86cdc8d320941e7c6ffacb73540cb3d2910841e2ce216edc885419d3b62f7161e6dcbdddd7109ad0f746635f5eee989bd28e1d6c382a5781a400ab06e3d31a3973dfe00c73d6f7ed2cdafb8392e5ada5b538075abb18be3360963dde8878e05839090298928b7f153e1918dd63d6b4aad6561166b14eb2823040dcf6d6cdda4b885c323b701698e33c840318fcddc84e577fc3fac55e1e89dd611d3fe694feb2dffff8fb3e11a311e0a69f4d248eac265de22a6e57659de1ba4d168b4ff20b89288724ff21f46c22b8b301aac2c6b475a05502f3fe1b7f5ca96f6c4cedbfa3e31524cc22bcf3217572d7f07f99f04953ddec086cbca6715935f38012afb0f0d00913d0614bc1bd8706988221786a043343ae26b1a50d9630b2c20914f103df924914f10f96b8c041df1f8ba51f135bbc483a9863c5aa25eb83d5ef135083c3591117cba13039ddbe3a314553eeffeee1e6fbdfd2116a5157bac8ea3c8aaf65bded3e4e3ffa623287e3bc4c9175925468d192c552f6410993aa90163c7c9b6581964ea5465c3490d97303f0a8047d46bb7b92749be1c06f4ba64492253a73727e40932755a73c2af493fd1813273a0b3afa7c46b9dc35c9415239d906b3cb1626406133232dcc4d8093046a0a589151a9c0c5478b71a53f1b2c62715ba9aec5c269fa60df9a43f32f9a45354f9a45535e4b373635a4c73398207ce133c777648b9c1c50521097c2cdd4edb092134c43819167942e6f6311e54973247e6f4a2dc7c8a942c403935a0d8980387ea089c2d5a92e0b99dbd9bf5d8f0b002c660c2ee76762fdba9dc5d7868610b99137e46d6dc9a880d314daa6a08d1308101875b60f87124e9c7add920c918e226ce93995b63a3af15a04e0f545ba85891a103438a162248bca0e901a5865b63175fa338a8d0e586276cccfc08de6038213284927315484c40e1502cb149fbf2c7bc3a4b9b85d9ca12266a404040574cbb2a2320502c61a2060424d4c33587b89c6a7167a4008dcb15d44152945c16fca039954a14a212ace4eb0768a46980008c31132cc5e4d83ad9d3282a082e6b6cad58b2185620e8728f235f3f4056147f84aadcb3778f31085652205029c7ad26a1f331e33a3af29c508f7bd2e08ba30ec2e3b2abb7b6736dc3ce527892cbe572b7e672b95c2e87e69e7d94cbe5729425d69f08232e0ae492ed18fa89b38d0cdd9c8f3b1fd76d24fb082e6bec068855117a670952dff0a54eca0da489094db3c4cb1218a61a9a4670d30ad8143c5a52479825efcbacd420384cc0224d4a41a91468ad87544687ec4f837c3eae44927d48f6919d47658d95e8f43a8fd38851daa38a236ee13bc2c8f265d8250a7971d956c91ac69ad7a3346cf586d63764fd86c0e12c6949ef8985b1582c2116eef9386b4d5fd9b230581016254b6b4de999c9a8ae3c4a969ce130cb8180225dd62164329688b7c426edae119ab1f4c00ffe947082610eb416a3b2c62fe77ba82764bf921b9f154776fc3c77d37dfe3b20b0c7d95a082e6b4c75c7c68c7ef8380f5450300b967037fd7c5c8d65fa4adbe42d291154fe69606e808a5e424f7c74a88a63d31115dc00003501985df19245c62a59d3e22c087a2280a05fddf5cea93c8dbb69ea21530f897a381c0e873eb223c0e16fe81bf686f696d8fc31f1b09e05735d20e434001e0870c7e2b010977b3eee83524b602cd6551d3bc3216b18c33d1f77f438dceb1ef7b8182be8c63d1f477b5963207b5395f25997e4a9c755c996e4eb076806341c0e59c3c7bdd2f06b9f1b1ff7b82f37e8bbef0c64390ac0623dee63b08494eef9383b6c0c347fbe614f69687a9203f1224f0cd032e6b45abc46f14da42584c230586bd9d79d9568128d5b30578f621dc52a2b43254ca3253bf697750f6e615b0346b1e2377222a091b318b68ec57028ae8052fbf1d1144fc8e3599735b6b0d9f378bc168f47e389632b6687dcb3792b5e76316d851d0eabc5a1ca8b2cc9fe3f01d20bfd5aa8e73a9d4e67044294fdff0f6a22632e4a1babc3e6f995ec811fb9ac71d314535355ebc4a036a359c30daaff7ffb3f403396b5cdeb21dd42eb5a4747c8cef4de7f3b3b0bd29a9d40d563ed0aef6da08d37994a6153d011b215ac78d5ff6a98693657500c7226754fd292332a6b5c82e808d64b5eb32ebbad6b5deba83e509d6e27561dd5f53416c4071d3175ffff4c4d525421824a30d32122cb3dcd147802b1be583f488b58bfb68c4eeb58de6b9db7ee63ae17d93aeff9946f14dd7b23b88f75ba0ac89ef5de14ce7b5f53e1ef29c4dcd37bad6b5feb74ae63aae005800f52c0d7dd0da445c0afe11228c6ca9709ad50da5b62b38f8ea2dcb3816dd5572eeb2d59993b9cbb7658f502180c4efdab8200d45a67536a30587e594d9950598a25977b36d085cb1a073d277c910444144515400ca0e9123c128fd6dcb3810d9cd2953bdc3c600548385e06c45a23ea80d36d366bc3721dcf6ef9564683b459d6286eb9a78dc50a5bdbbe459b699bb96161dd7f36929e3070af195c943635a1dcd33eb967c5e1e49eb6890983d9c371cffac23d2d096e305972cfaa240912257304e611d388e98259c46cc124620e3179a6103388c9820964857bda1f28dcb3fa3073983bb387a98259c3e46126993b4c1d660ae3485494800eaecc66e30c86d96c9cc9c1279090101df213b747180d62c1cd71242a4a40075766b3710644e3766c86e39ef44742d1afba8b67a79d600318800e3dae2e44e77f2e200049925b48d32ccb104cd334ab28da5c348a8f71808207d314cd1bee49af5c5c5dd1ab2b3108e2cacc8e08b4325e509433b2343d7b1245b17e351bc5079122f9e59e24b6d6344dd33445e13b4baa567c33751aaec9e6971f554db038b17384031e64c4d061a4c898a82a6e763c69c223468e865b03950d492e5091432400752ecee7c55f8301c31728a81b5b8ef8a8e3a2878f1b7ea0a044069edfc819071c70351bdf7ee1b7370b112825a9243c6c64b955375104b9349f776c0163d9e1742b816837279aa0a8d42e97b512322335001040000063150000200c08048583e18048d0d3bc7a0714800d5f7a3874643a9a4943a1340782148331c6184200200400028831c61884cc0711c77ef7ba35a75b486098e533d56df1f502add875bf081318d9519508880dd4878f6e97b00c724e36b06a8407d002d2ceba6d292ca209c5970f394ebda5e1243d1d7f0ba96f6e1721640d8d6536f35a4e058609d44080ed13f01c187b0377dc7381c4a881b3241488f26ff764708e3e725906ebc8bb9bec986ec8a8bce15e916e389a8afbdd31b89ec0cc6149082f7f7fdde0580fe4fb15c9c60831c43c30b3dd0e47e409b06469f560df534f94f7c412c8b6fa4789ec552d1d47e285120334fdfd3965c982e9020e667d2b02aca1a45b080f6f1a060fa5d9f7571d11e60ae8989b40fec129647072ade9775606364200f44578d986414f1247971bb4337f875f6e445a07a00949c300e95a91b3780fddde5d4069f28bb7e35d654f781f7eabefe384d58c1f8879287a507936bd75c5fe245f065f9b23a6c16207a06710c8497b87d99c68e7b47b520cda24bde925bfa852dedd4989f96aa01137f35bca933a863a53a244b4b64ddea5988d5c7f7f7540c55d756ef0511e8b29e947c949d3f3283fbe17979263a8fb6e0940aa85b8485e17802844ac0062bd189c447a2c96df32367114087f96e45421945ef2776cf01aff0f0c191be8b7ff83f45374fba17fbcb8c20a9cb7af9ed053184f3542005cc1f6e0183117cc5c31b3e52e8c7b0b1770e00eb3c4b4325f5c10a91d869c0dae8e454e073b64f09d2dc7a804e3c548f595b4785e21c85350d705a67f82d2ce16986ef0424b4ee0d49209d5c9118e696b52fe0a5ef5d3719938ba4972e1a502c08e88e26f0ee235b1ebab7406120f7c28076cbee4ab7f84e271c8c8d8eab43ea1dd61960d8f39e352bd0ba76b95c590008ad8471d94b201289b7e87bd6786c9eb38ee4319b79284b5fb1ce698d800cb8835fcc045510c7147dea2de5a90dca2528a7e06e6a475c403a0fa74bfdde047a011f1240326dd92c24bae5e5d4cdf1bdca0fdecb1bf1005e100f77773bdf7ee2315cf21c4c547e8842f20e27aac6bc5607af0ca343fc754f519c8da33622c0fdab5fe5396678dacf08e8cfaf3447359e11890f00b3fbe14474e9ba8c9f4fc7e3794641ead1c47da602a8bf2b2dcc66b255118c3ede6b849644498c33f41105f441ffce260f7b3c0a3b2299808adc5aa0ea6e3c318367c1274a3f4e983beafbb357cc52f498e936f43583aa19610937bfa7ad06887c4df7a318c908752935f490ad24b0a32d13e49dfc183b2f68eadf63ffa840e4e221bea3c53381b944ea78d40a0337d69cf163b9ee0a537f6e7cdbad59189c074d557671d50ae5828c9fb411d51c9fdfa673844b7ebc02d4189b2bd9545bc9f268fbb68c2176e07372d4c18707d9d618e9559a330047a6c9db05e853019390fb20eede91c444dacf655c920dbafea0b7c90c598d5ebbc7de1395e3a18b9e438f49240360272ecf4bdc9b1a61fa28d781563533d9d7741efa57a9b82063619f419d9800e9eb24bfaba202b5a93eb8b665e74d3c3ad585aaf7c81f31030ba09abbc05f3006af5a5763e9fecead1203cc238bee2d1c3d4200e086fe5f9d115f80b7514559b49cf941b2e06f3e5139025814244f5b1a9ea9b1103e45f72293077e03e34c28efcc4554b47c129371f0306106fe95400458d8110b179958ec002a82e93e3dc96d22e0c968849bd2137c594ca9883cb684d47a5336e06e822752b8c044ad2b8d87d484b97bdf8276b48fca4c76ba72491e6f8b7cbb56a470f4855d777969ae3334bbd1ee21448a8b2f8a4c13db24c1a186f7993e00360468e3f263b1294d68cd0d3f6fac0435199a4a9c14a13de58e224a5090fd561d2d10896ef5527d68637390657caa3fa2cb38f4a88652f9e261a23fe3d09e68648b28b9f0d6d96c56e9300703f4f55b2699d2b21747852676c4c6fe4449dbe3a91441a7d5cd1b7050f04016d5edde478d04d40b2a4575a2a7224190e05a522b6990a8f71e04726db28acb3b0e78acdcf4b166eb1f01cd7627492bb3d1cc12d92dea5a5cca078c40a48b6b1d4bde6974be762f005a86ca323a508e1eab68c89dbfb227414036487714270d973ce21b19e68fcd8080b86c6a3eb87c768397bdc7676480df9d7b34fedeb7515b1f1f23d98122fa920da6efc8868a559fd08f8cb75d18f53d4ec35eb7a001d173b0abd5374edc1ac401cfebc9470a3182bf3e4c0fe36b45f8c7d96cbd51c7f07bd3c29014813f25e99f37952e87ff0503fdde1f184be8f5b836ca71fd51bfa3aa5305436c06779a7ad3adffb9ead9a645b023cc3dfc1f43beb198ed8253367245f7a8eca2bc8bccb53621a01884fbd2ed3f54e378192022c0a5d857156395acd417a47fb061d8ce4fca2f5e4ea7a60682b55590f938ab103b233c489771a23ab8ba4f36c6e7151e53c71c76ff80117a374783594153a33496cb68cd171a67f64061905f888670e3bf0f0c0ad10e6d942690f082c342bbf6e74957b8163653e897b8999003bff337e2fa6b83c709e32818a2acf246fe8602ce36e73238d20ce45069221c93d5ce51f02bed81371384be5ebf1b2e28d8a25c5b8402fdbb16b9ac84640cd300946abf07c59e34aaadbcfa3ece35a2c101240db319847ffcb65f5d8d8ae0285fccf77ce52e46b9881faf8263446e4344200b14e31eef3c0242ba4e88382a47ec04a961f1a0fb5355f4b63c6883a00ed45194a1d9ce16a9620df6e75a00b66fdd4e75926a55501970a8f3619f10f6ca9c2d806d5962d6f81650d35952a224b813e350c5f476d0ade5b5f189aeb7aa40396a166c898b4f36c00b2b3bf4d8ba14afa5f9ccb3d4b9827dee4097a7ca03c0e2b408d6890d666730fdfc2230881da76498da082e4c902775a8901700a6538a3a671d1425204146f88c58feb4f2425fedc6effa13cffd2e5dfb1bd0f3c70172c0c6a6e9b73cf77e64f7a0f94906c991e96008826fdbde144022911582af88184a43ef7239da9fe1d4089e5eda4982adae2c33a796f88c46534f1489d2ce9a13be374f030d4bb401ddce0de91e243497359f29819849291bc991ca41e3f3d1426fcf07d37b53a04f07c8c533ed481204c6aef6aa420ed0e970d716a47c80641d42364cbbbd74406b48a0d05164a995f9ffc5c3f5e37efe07ef4aea2caf12bc0f54eb6da909b592d4edeb41df30ab50b1dc63a31934b3b622214d2ea4b3a0434ed1644221c5fe5317961aafcb3cc4fd0129274f87731c6f2d619b2c53b501f8d124585c6f2af5a3ca72f725419c7fd15ef3c34c67ce7e10aa8002c22c57b6af57d7ac1b9490c182f724bf0370a7a907681847b99cb1a55485749016d5e11348dd97d3ccb49598e6ce100e30e754b61691762eec7cf0f68aa6b18ee0b117b5d72f9ed0d0ba9e99f5067936bdc693ee7a909d03b131e6abdbcaaf48a47a1e35edb867a7728c34e84bf725936e193f5c4933461e9fe22117a34d7c3eaaa109c93f9700c358bdbeeab77fc09682f9035ca36f7f1b4565057a03528d2fc8e43a7b3c41ebe3ab8711b686d00249284852b336577f5b9aa3912b42da6853a9f61bf6e59348101bbbc1f456a6ed530e6c938d1ddb956ce5224d2e52fe7660cb195242a209700012d810cfd2f6e851fd0d6cc0a581200b7f4a035521e66917f5f25599050970c84a9b1e7b67f683f8c65ec40e208ddb209fa130a67e895e117c5ad7af744b3eb12ef2e6455e9636f17f1e681270bf487082fc3034e16e045b5ccc39d999b0dfbb8d434719813641bb0ea22476928276063f119975775002acbdcdafb4f124a19a69c992ee609d2923f8b7f9d52f330ce97123d9bbd4b7c2fd425066c3d1be44779feb672e5001cc3e763ddd5539989c85075c7409c03149fda10d2d2a7da102f2578a0a2905f0f2056801b91355db85320202ea9374fe84ef89ed504fb0bf17222d598f35f4084086fb3e1db6a7b552e4d32ccd3de72c143fd89a1600bead47d8c0517b8e80c5755c598ffd89008356c5e35f01c1fd30c517d50d2d8074b261e0c467e2032877833dd41a8d3f7f3a3a40702ea13929dd209a71cb3f498b402eef790421ce9f92c7a47db094a2c793565d5a8fe98da5a286acacb23fd116ee158110f60bd46ccc7b5e307b9da9c0e626103bf6e33cc47d0f6a7a5048c5a0f4dd55479780038815e0e9af48ba859477caaad3305810dea27b9ac1c7d1c505bf5800cbbed58e7ae30ea8b6d79634a6b136da2810539532edb24fe6e8b9b2c63240a198636f1382b03fd00b1f2c19ba9a711f1732e027099814c3a04de4b0d014d9b246c32ab4804c1b115c2587ab05bd8e5859897849091a1122a2d6eee9de82e4de5977d6533e4dc0a6d8055a52027bd56a105c4790add87bb2dd1166823f5aabecd57b14264e29ececd9e034eab1c774d684334e1ec7a7e6ec14cdf3e41b797f232a6dca41ce626cdbf04b6beea16c949a57bd7dc4ac37fd48002e6c5f3c24483b1bf1c3d34646f598514681d95edbd7ac38aa8801e135026db3503430983577591c272f42859e498de7616fb609d7b8691afbb8856af21f05b9f0abb9e8a26587a94e2502b88d2ea52ff92a579083afdf9edd04d0a4fa6e2ccb207ece7676b9197af34ebdaa481999a75a3d180a359d7f33f7a7189815a6ac4e157999215e3f638f6a58fbc601a906d3d7cf4f739b3230a20327e8f11bd922e9f10f32ef77a944043c2df92ba32038f326f83952aef5eee1d3863b53d299bd52c6252aaa67c9b09f448325e16f9ed32e4336ca29fa999b049d6f9b67d1d7a0e76f442d46a700887c86a2fd5495b966ac58abcae79c1404a9a2748d8845fee3a14a242d29f15143250ba5cdffd7fae783780755731b04d19f1b0a12d47b3878c8e1487cad9ceb79916dcd64b6cedb86dc9d3d9627f54fff3e5d43f4bb65afaa30c543c0903d1b34e656a13f6d01adfaa77161a376ffc9278550d6cce6d84c74dc55b4ac79e9202866fffc5dcb07ba3c1ff7834ee43af33d5da4dac7ee95b91acd53700b5ef3ada202a735508459b6f7cac240d3f41e0e812236144c2eda9af8e82e7ebcbad9a9aa8059cd8898ddfdf68976c6ea3bb84d03ef09224cb1cb43248c65cf864310124dd212def8054d39e801a35deb7f730c3da10742e15f223c689feb4e18f76cf4fc91c9c5c6dc862e4cf5e5b5d08b13052b1dd6b723a1e06354eea90781585c838cec17d7d57a26eb2fcd42fd7eee4f32106dc7be6138b7bb827453a38401dc9752a0034692714308e27121e7cb6a6a82d073ce4c745e19e40e05fe638e85e3c4459611916d901af75bfd571bd9319f30549d8516f55db788a683e57668a0d557c7023986fc0f5b671444e10d6207dee10678f095c946f9ccc3c38c8b8daa092427ba4de81da39424c5058d70bb0188051c9a4e354ab03ae26552a24872ee261066c220a92e1f2c7995d41554ca4c6690cd4563b50c831cddeb41bb5ef7c6039fbb19c462d1989a3abf7d4c2c0bf11275fc9a39325611167e3f4c169095ccd7573d96fe776a8b0e5ddc959ed3fafa13286074a2ef7d3cb1732d76449fdbc536e171893bcfa9f06160bb8247adb2282e50195ede949eb27aff89cac1f9581a32250bb67d1729182063002373efda582decd23f9eac68786917e931c7f27b798bbb4a2ce7bf57e9cfae76b588bf9c51ce6e13c530fb3bb55e1633dbf6ec5998452fe58988dd1d85e16a7344f26f0f88750521742eb5f79c4aadd5d58513d9bc9be27fd22f93a487660cc4cd2b1fe4b4b50bac92d02ddcfeef7188fe4d4c3f705c76d810fea9b44362b270b65737091068ecc657176b56b80300cfd3be4cb8083373c7457b1bef202380ecaa7b6c94b8d6b094d6774d4a35d3d001b92a1d8402e5885dc7bdf5748b41d932b75b56aa16d0641d7706e25e6de649c01208c435bf37af4a067700bdb268990f709f7692b34465e4b7ccb0742d849f758aa5d07d7823327fcd4c89a9364b3405f7590e93d68c9e2ef2c442b11a80f63f94a8edf0f3ed0959ef468d01c2c337f4dfe0d8de8f7e5c93d622527810b4d08c6d4df6f141b8c4988ef399babc7ccbf7d427e94a75cd4f285626a8a54b85cf7e01c0037d15f1a6e3a60e68f335f7a46cb055341c2d91603a2e214baec9cb38d68737ff6a215d4c8a9cdc3b3a9b94518db4918eb3dedffadf7f1bf4131605bdeb3091b83e54ec07c2ffbb9234eb350ec0ad04fd422af5cdac57270fe0f455a1edbc3c9f11b01fa9ab8acf93a3d9c8092f868a66fa19d322b7e3c6600e3ec971aa11952e5f7af99f6e56815cb5d066f567d1753706437773c67dba632a707c0ae0b48dcf9ef00032517638b03844477629c5bba0c12d59971cea77ca8c4252f5f7b818b4e60904a54013fd6d15650d94ab37f0bde49c31c8a31afd37ccbb0c9f544a03f08b943e1587a0a794088c4bb55dc355f420a121216fd820555506365527f93041265794690ee10eb5ee070f9ddaf8301e0050272bdf692a9744ab17489f1dc834d89de57a3098574d80b58113f3adc54836666d845db0c23de3296d3c44d0bb5b64b616ae74aa8619c7e7117c25a126b9cdc394023a48623c3ed2bf9fce257c1b89399e7fcfcc1e318df9f380cffa72f20a3c6c9924dd56e96be02d0cb2edd4dfe0ce509d54bc3288e1e4663e1f3b1d4e915be0f4a4a9dd72def03f04d89c5429a5ffddd725c52a23acbf0db52730929142fac2592bcf8dba8bb131a94dddc57f80138e54201a734a4e2830305d121e7745c2f642209733920c4ea119cad1697400fd2e4efccceb953d5514f5614ad05928d7af68012e603e6be0fd8c42dd144e0a3027223ddc0a37392f0cbdbfce3306eb64fb1050ac6161058660a5e68532189d345e007d08a0b9d7fb924846fad85849fe49e989845fb967ec788b62bf42209a51655ff32540c20753555fa96b75f8e140cfd39863e4b3e4f74775ffbbd897e6d1d97e78397c5db4f034f51dc667d6378ceda932d8d90dda838f99343c00f5d9a148598beef6a78a6616ca7d145d314a3a20ea7dc95e0230ca2a9bf8f423f2caadd3c342ee2e296025e893df600da34363e2e4893de84010b53c2e4283882b6f0ffb53e390eb72c20c20345ac86abab3c8d7c033188bcd5d38e2a73d263fe3d94cbcae3dcc98570206877b065eeace2660aead7307a62ebe9033d2a374066a05ea9e894309c84575e7a9d5c116e2d7bb7797a13cd2a1690f5b3a47089c913593b2740649c26d7776d57543ab00a9540b7c66cf49081959eaf3eb56ba51a13671f54df4aedbdc87caa45dacb098934a3c1449c352201d0b3026dafea8e43cca77e5eaf5ef003d63342ee7869f1fc6b4ffdc08f681746cfe6422cf0ac5365075d0f347c6acc0fef894fbc253d8b7d7a351919fe06f2ffd83c50cebf3cd5be3f40cb837040bfd0a7fcf0754a7ceaa7313b1df66c9b27a5f72eaedc555c5abef891d5961b5a13df43c93650e226fc9f08219b8e9c9404dc4e2089f33796fe0ab685bf7e3a273d6fe63e69336e2f2a84b728c42847ca22fe896ca900dd22937314b89f293168d1580f64fce397bb0381c8a1f830211e6f47ad7e050a9ff80edac70d7a8309d88f27572180e935d52db79661543f43b50a837dda035c63b29fa88d4406ea23037c1eedfc3efd9c27da08db03648cfe34280fa5949e0a10083c92e51bfae3db081444656cab54811765ac9646d0c7e2af563de6b43517f37c4cbab670241cce0a9f0774e154fc0af3b62fcffb0f197a4e5504ad658c31a3e4ce88dd3877c5874a820bb2f0a3ed94d79e5de751a2867174e57e11938ae97ed28a385003528e0c9c652af27288efe54f2b7cbade899bf31b87ab699f2db60c070c71777caa794d28342c978253a33637e56d3284517f42d803817fbc54244c014c002ca0fe001a5fd044fad99c1e571b92cce739315e5d28d0e0b249c043843442751835ba1b4d33d79d87fdb8fc166f85122f3b7e828a83105e00e4146ad7a2d2390417d8a29af51e230955ade4994544ea1120fa52217c86832e57b54d1c170b96a1dbd89765e2e80f41ba9e0d7145d97cc88c58d3f9cf21542dae4df54f4acb23ce9523fe049d320691d0e4a8dcb96d2cb224e6b990a3ea580075fe46737640c76c87b2d6353d89fa15f6d9ab057518fb43e7265365580a75952952c48800551a6cfc7274b369349c5832ac2bf4941819bc049ce808684b4bdf28dbcb7569cf859fa11f2eb890bd0e0d53477f745e5eea44f1662f2c155ef2021a2a67bb9e5b61edefc70106bed4766a6ae00afef98ddd530aefbc4dde222836b646d47219c1e72297d91f6b842889002c104b00cd0187349e14857d3f3c75ca2d994f9062bf93530cbfdb1c22b323762488773eefed55602c382e98694470d365dea0214d5c623154e97c067f5e262f7e8f21c6095d3da6d91d9e021bae7d15c92463efa19b7a5e5c2029db573711916c9aed87dcb1342e1cb39dc90690fc958c40db961fc394a1cc0c8d9cbe3d346e801e69c4ee19438df4f85320e3a838ac9f3e9b8d997876719d6a8893fa2124582cd6d5f3fa71e139def18075522f97cfb749395afdc5bc15bb470cf168efa01ed68708995a0cf961167686b627ae3eaf3b56611e203a8bd3aac3ca33f477f870a65ec032106d507932817b9cc09020122bf3031fdb710a43066e297eb6218772a0c95b0241c82307ab118815d373d541e3acd42b100337249ac2a1a9f13f3c624dfd7ea0c51b48be02765875783cca964b3b0ce3f9f2b70ccc9c42f747cc6a4cfb3003fd4267717b8e75083257f099a15e54492c65ee581d3d7ee655e8bd2448073ca299536b753cf7fab00d2913483d163beff69381f5cbf880d54b3a4f59a97ea2f4964002fe4f00ca63cc3aa9b4c0641240b50d15cc8483ff0c19b97769ff382ffc09fe0b84c1ca1f6563dc3a4d0cf064f2da35aabaae661ac22b9e0421afe4b60fb9d359b3058059843c5f96f1c4a6ec6541a5d8fffd628c303605edf036b9c99e77e4b641ff0ead8907ec9f283928f81fa389a1c712f60a0ac3b9b886d7bda7386e1f254f0dfa9d875c7a21ae652db0c3bdac33e0f260b5ffadc073624824dc3bdbe888bf7004134d55b198a476d73a3d7c25a623b57496422d9593d97129c51bb25aca70678eecfed01046c13d4299bc54496c26ced04bb7e504eb1aecd261de8589705535aafed80a28a76d0fba282b59aad0c09a9c7c524888c30e485f26ca99da255c017e8867239655f10039d969d64d85f3b10d1b6efdeb7540cc78436f53ffa8d52d2bcc8c0b6401d1debf66a529d031df20a9dfe28952905fd64a6eae14eb8724ad6dc3afd52f5cf0213ae4a463d21987443e1144675e25c22c039d99597fbeaa1995b6ea4ee9c2ae7bec21f85b375e648d5d00618fcf955098728ed83a00cf8b2f4e3f860481ce12e5f2931d59d714d96205b392fb3988519c21723e2a2e75346afbafc76b2c989d6eba335c6fa704ae86a574f67cc3c318c15857f02fba6b0de6868744e540b8de474d58bb2613dd27e5fd64812329ac2cc9a42d9090d39b3d155e6d2bcbd511c857064229e71c82aed3be7e01eed54d2381f605e63ab0b0701ee38ee6f0f18690b15501500370284423781831bc7327122b25cc2bf035855af86d21b820f7557122de4c9953a73ca0e50e6c079f4648449763045501b496211851dfdbc2b364e67850553129f8b56ee2c99f2d7c30a974121566c42b6cbf6e55285064d3ab23b38194a43310645a9a07aa3ba6894a17e40ac7507b5a3952644fe37f2af01eae04495d1bedb18cf05d890802ac2547908e0970b691a5997a27746e390200896c3eda24707417ef81af0223f004d7be088f8ac25c8771916926f6c594261de44f82fa27defeed63000114233d92f4229b0becd86913490caa2d30f8a585dc83424fac02254ef3e231c1b85c30f15a0001d962446fd319623615a971d2ef824e9b6be93d167fa13e0cf8b5989256b3eccc5da44096d5d62c2677037a1aca0df6e9a2ac173f0dc5062ab978de52595ffb4f007303960aa1e77cf4789de7e6c8d2b6715f06182add31f712b0909f63aa52162f406899f8886b3306936152e1eafd6f317ddcd7740192152b608d2e69f38c2e958e06229b7605bdeb5433ca65220848e19fa53d2a19db0a14b1b0c65c306a960950b897c0ce05683447cefc8c37c2ccb6cf2f07892b5cfcc219b46b31f908b455ca1edd2854cbc3b30a72c3cc167f99314ae97ccd964e9538baaa884da664a0a1a15f6b3a0a8aa5df4f94b40cb7e9a442d391cd9c55cd834e2b054c0299e2eaa2828bca3cd95beda8d3b5d02a3d42b3d7f5f492402393e53572c2aa1d64d922ed518cef494b5d16c1fe66ba34105a59a09710b09f0dd6868bb474eec69dedbd7c555784c154abf5dee6d55484a8d1b5f4fc9762281a4be2af21649172c8383127c2df1b217cbc716119d9e492c37522d43de2c8880effeafd82991c7415db300b5d3f76c60904f1e2f5af98a7afcc08aef707cfd76690d8e4debfd4aea936795663b4f02a5b0628d7b8923547264e95ecf82e0e1f7cebb1bab9ec90c1d41b352c2e509e08ffc519db7384f22c27b8bce782a4cc6931eaefdba302961adedd82f602f106f5a1676adbfd8b64021fa5e8fa569360a5361f1159f5aecfb2a58252719f0b1e9db2f19a1be643ef9fc7077bba4b3db1ab2cd308eabd4940f6478c057728331e712ffd86adace82fca6ef50bcac892bafe2f16794d12e15bce2438447740c6ca8e872e342d849a4fd6221db52ae14db0b19dabca17af53ce4a20f3a8c723d27478d47346b447453eab76a61990cce8555f639f740f023673816a09ece9e3126de32c2fb63977a2fdd97adf8dbe058a095c41160c4441f5380f7c33aa86df7b9aba367814a2744329af866190106babb3cd2396196ba8f51b1b77d959a94603d7b922c094bbb18c5c61b66a110bdff280fe178eb0c03a6ad7442328848c7d156c03c1c2f8979796fe9f0640e6f729edab333d16b973021a4e6a858dc68455de1a9647eae9a44ee021512a4f90cb1d0abbe05ab0aa7d45d58b35530a7856ac45f36d48af37dfab1145ea4bd4401c5898f1023fc042426f30ca21abe2974de0d6a0cbe12dc9b8111f4401682580285f897225ccf36d0b13c0fdd757f1564d589bd396d851de51f75e28c4c1eaf3566854ae09ac0ebe0637d37813e731697508f0ebf0f297f34f2d2720ea72d43ad64261e006b96223213ac2ddc88cab6cc2e54850e43a325e5588a9f9dd8669c788e9de938878f14f33b40de9798f972a0a31b8e9ebe720527616af2ba02b8cdaa58887ea9c036ed7f2e368e9dca2b140ddd537f4ca02d5d695bbe5d59f35492172275c948649f713ee5e69f6e5f5eef97e7f65bad3d2bbccf1f359ad93f172d2e113cf58f6b3b54fd97f588fc059d0836a4fd835feaa5d716eda3025a5dd3dd96011c564505f049e08abb9369527a07bd23464381a312a069d8b3e5af6ea4e72d69c07aa0c054b4df3460ed7d12b2ffa10d921895bf231183bf29c90dee9eda2066de2e6f6c99bd4ae7740b88472835bb36611b6c66357ee6a0eef43661bc730cc227f222d3d536a9418a4dd4ea3c38132ccdca317bb6629d0f2ac1e6b9fc12dd24bc78824ad2c50b7b47769b9824eb2b5ddafa48d16eed42c704b0432cb6486e6325817721f1c43507ace58ec4a4207621602d6d8b1f9e186000ceca3ae89cc15ed3c700731f6c9483f0f4949f614cd2b069bb11fa1b1e90ee9edc3f115427f81c052fc5c5851cdb85a67144ba0f51b9e31e6d8ccb9c8d2d6de0ca3054bb515d3837cd6b6c233931b2e0c9fb94f7b7ccadda0c7476e3cd8a81d24a39e7a03a56a407c091029fb5f3cf88dede27efab536c607c5652866c77cb8debe63df5e38490c7f7464f6bf29d57ee9607da384c87aa84c1506926451b16c7029db9aab55ebf2961baf09721e439681561c855fcf0e294f0c98aff5d778e770e4f8219f93112ecb87bcc0397aaf13fe01b32650c14d8d22f240efa7c6ae82fc06e9552febcaa41a2bb4bb32a5409c230b70d3e7f0362b0a6ea39e70ba86b781e81e149ca611f8e0101f764b423cba98b3c166d16cfaf069528c565312daf3ac0e5f4a654e67185272d21c26993aa96be3e2eefc44b62080617a022aefbf08f1bfb61a8a65fc648a66e0b73564a15c17274fbdf55cb2acd91c7a2294d62d99453bda71ce99c6636b002ec607a239db22ef0abc072c0ed88c10b1bd894218854736ae0d17d718f0894945b6748a33e056dc0c4c6f7bc00c22120284caa19a3122e5aeddaf047d859c096a25def1908447000c7756c384b3f2918d5b03855512c7960dde0560211e58ac3d99e6ab20c02b90efed6c05768477ae0a5396c401716fc812c3758b8123fdb2c4ccc7d1d46d0f1c36230ba86db36257457a6c85a088b8e72b442ed73346b99705c842149e45735309439ce756b70b3ea948067dedb0d060ca421bd770a1a201d8349cddd4f3d7dde07105a3899e65775a19367c1ab7dd409017cc4e531e96698497223004747dfb9ef08d9105173a23144d63fa3a1da680f5976e0605bf97e67e4cd20282d782541dc6ba41f7fc3482d006dc985048e449e19d46cb88141c0c8b87625c7afd3678515d892710654bed19c483aef045e2e605a6bdb9d3f3ebb229179082dc52d39bc642e771e350f48dd81fcc5316d64c771de715fbba246580961f302dc08443d36bd528d337d62089d81988dc8edf8696b082a39c6bde0e4e17610dfd8ef87064afcec1f722ba6d9c636f5e2e767ef1904a8cbfd0201759cfbc0ae10d142879a13df63edb012c96b054d90cfcdda083065ed43aa33527f7ed6e40fd2f042310f41961ef94aa9d7aebc9012e57db3c7a49dac4ef40149b17acc4bb0dd44d7e0acdb8311c182bd2adb403a01a46e589981c5b2e0a1181889b63782fa2954c27097f7592c87dfe73bf11b7478ae00a161ab776c3b29b5d7514fd101a3671b25896c5907bc7be1e99020a88edc50a2974dbc726edb60edf7a15bc4fa0f8bd0bb85c23f5003ae4e364d7fe02d3e75b402aef66bfe10d671e6c73b854f2ce30138b0c9bc049b5f3612e50936135795092436df250fbe429f286bff075f842d77777fa069fd690202fecba802920aaf713a0039dfcd1ab4ebdb8360810ae2cec8c2f31885beac079f8086dfd6d784b94e3a5379221609a4dde2a45e22e3f2c24c7e9bb0b720f14280e78735e3e913e7d2d170f1c8f8be29da6a3cf59e1e72f78f90fa2df64241e832ed407dc880076443a1598d58783066ac662c6dea0fe81ecd393612f4df8466f80a46689bd9467ef9e29e0ac03b1587bda250416cf3843b983938ffa4aa11a66899b545ba64c09ebf5513c557a29f1e241739aeb87916911d918619894872703a05e8206fcd22bca8ee810c48442cc4f5a646a527fd9dd13051703da4542eb4b2c93872812fb31421a91e5cc46f7f2a2a4d0e129c61a5aa96c52c041952250388823cb715b43b634a1eaa5a26935c992ee6cad8e44f94740545d995ea871eb4e6e293fd825c507e61c582ec1fa260ee58066fcfb1253b9e253ede720b4ecfd569ca325da5e2889fdc78797e393c28fde750f8dcd13b70f2b7958b3f62fa63f5e6313fbde86e95f9046b1b196fcff9504839aff596115e3efb282cea1cabf53da37055f8554862fff2622656ca657fe170df4a1a86cf6fe320814dfe0d7effbfeba3bcab5cd6a3244af43cd6a6e3c6b6e0aeb8f0b22a634fb6a59cae4dd3a333292f505c8f7f07dd6e6aa535abdf71f8b8fead46a1bae856eead887fd09d4a9a00faeee4ea3878cc88ed21db7819f1f086c72fa7db54c4e7ba822b1ebe836f1c12d764e9f20323653face2613eca77cf0e820b0b3fb96e7b49bd7bf4244af2866fa089489f6017fa15f53d00657bf256b470e51faedee251144da31a5dbff9f25526ea8335abf83119d286c3de07fca96c0be8fef1f6c07b95eda9347e9b0b32ce60de8466fc6353f817cbb436d8642f7e081be9f56ba6d2f77feb06ec680298d39fa6a4731a5f924bd03b5cf535d494adb628e52f963ad80953536d08bfb367b950117abe8ffa7420031aa89dac2cd78baaa289fac7063aa9a04332b857ee128b89fe637662ac50f04545a11bd68b16d58a9730ea0c207dc04158e090bc1ffddc6c31ce29f4afbb763607a85562a5dbd1ac72d9eb5500b0d4397a923cca53233737ec4cde182cc619754b9d80b2a528fd34d6a4392df07bb44c20eba205e1c0f7d86a4da843059faa90ce38374d238cafe914da5838eb1d4f61397ce1ae2a7733ea55d19d4e4de5b18cb6f2f616b43b628b0e4c3c44fb147db7bb5639d9924a4e7ed444ce317d78eb064f518ce0c4a183ee90f81a0642540831cfddac85cb394c40183fcf5856bb6597d5130b77c7f4d6322c96b475c16db838d515e151957f32d5e88d1e4aa44a958ae9c9b87e22b9a8a280cdf5bbcfd74caa9d967b405d0dba9be2135bf9ff381969f752ea50514e98046507cb778f59d1919ae7997efe4395c4a0ce09add5d4a5b87f2922ce34acf5b9dcdbf08b35ba7a58258637211438ac0dfd07749debcaf30bfa559ec09e49231f27a05a8e4e7eba9a7144fb7906671e606ecf8259165fd036602b382894de34d3d9a10c0e65b39a827857fd077d871b8fedef2a52514a17de645b9bd401a73e9d0b0a54db623d5fb48dd6c436764b61040696c7da4602c5035d5d4c138267b24b30036143fbaab8ae744960d1de33b74165d74d5775cf4347a676a1491502bec3d1825c1b94bc6edf41cb9c48527de69ce05d724b4240645a34bd4474866ee1a338a778e2c8d2952bb33618a93259b5cd61358e4de8b59d29f7eb58c6e9a5b38573aa723336409c598c8915c03dfb0c20d3e9cdb2d99684757900d5191d84eb4f0d6365f2e13a12a4891d05c77808a47c2161d5a3831e380d16ff71ac4ccd5bc07641e62e6a5374ecd21610c69af064e8ffce6a8c6f593a753ede9d64833b0e3c557363ba8b5607131dbd4e8ec80d58860d03689a5759abb6bc152e4f0dedad0ab9466c95ba53e811ca0ddfa280658c92a23ebfc1245ed6157f2679beed1f3e4b9f08261245de30cf47045d590d677fca4451816c6561f98ce81e71a00e01d8db7fdf39ca35290910c843b45bc15e321035c3c68e25da35357c687b58930cc100386f2f28c7eec365be2431f416e1fe455a49b30c63e25440f53bae06e40a6c60caa0e0f9d2e34d8b1cc454cd695f3d353f9c1f6bd6caf702b9a632ea47edac92e2bdbcbb55aee8471018deaa2a5a2303110cd0a09af9c8319e6f4513b28511e2b789f5709eae405205ea87482fc8ef035c3c9cb8fc836bf411085e065cb7fe2972e8fcba0569b028d37bd8983cb2bf8ce2591164a6a4303a9d850227cb8a4d03165f49f7968f6b34d436e5e02910819c0724b94650d7785cfc1120a1cd16dd7a1711220ea8c659e9bb22be92b5530b6e1362a153f46feb3b8f725aa31a70668bf7448a2da7013521435508e42936d614f440d34c5eba6bab04e037094a67ada30a235fd7090ca7a5250fb7aa84ce583035c3139f2ffa1dac31e0dd0a51a534eae7821d7914c3f113f22598fd1113c89de7b4bb132df9c63db4724c7a39f2feed26a5b9ac18227d124f335036dd35ddf9c83ef39a8947e05c22ce24c02f1a34d4d21b39840e1a3024e0cdc9b99e800ce409ab4c00ddf62c28f8360b2ea00df5b9d91eb8f66619efb14a3859350f5e89dc84431abc22125cd1049f3262f14d0c5faf0a11777301e8253a54cf64c467d3ab8529e73894290c23b1bb3f6ff9fdc1f313aa821c36013f8d92b537255d8696370f4a2bb5c6c50a9df313403f1a883dbe64c07acfcd0ec13ba8ed6806211950752f9b32c007285eee6836e30f9888f2f1c225de36f48ed35701344122192cd1033e4eb2fdb6a49a8e2c01dea7955ebf8a5faa792b0bbef9de09691ce08c5acb60b2739d1156888cc13e30287d62917925eacbffdc4ac16928a03b0ffae646c11dc5abd025ff1b27aafb3f5a09ac8491bf0024ac49224c8edf549469dc085adcc63629398e0d18baf377c95a3d854add7bd0b52ebbf5052eb45494f9a9721ddbc5ed7a8a068cfbba2173ef11dd7a6ca97d00ce69041b826f5109955234ed40f6f57db0e75e6730a78bd56302b0f62ac0fbcf13fc1b71ac24d2b17a465a9b14f55cd3fc92d39ca88d60aa9c236caa30936a49555377c7c8f549c4f5edbfbe69ffe8ecae194d4b3bc96d219536a34a370ebc5eb17036256acf35c4a8d54016deff124c9c3e426b1805310db63634b15fc6d1121780a1aa47d91c957815f2364123283403b10d4576672a11759a060cf78d38f3d2e4a98c5dacf38e726d4e81dc073b00866401c3603fd612b2362eba7a8d7b62308d3f5b8c4f3cac6ab179a2ab1aeafa0a23d22014370d001c98b1d4e60689b50809f89937734ed33783864251707a886b752d535e73b8b8f763b0a467fd2f4e9898c16c5a11b52b0885566ebf7fdab14d785222db6b297887b52db811f8b4f20a297383852fbe0625ae9cc02a6a3a00d078c0a90b2f4fdd3efa250c8aa19a97e26341c53b2068137cee3847c531bc068023d0f5fd22342a5929c0a292e903ec71e7176a68a8236175b9bccec4964abc49fbcfa097218a5e62b0120c0f2de24bd4ee4258d28b16ef6c15566a9472d6bcd6df62d9a063638ffd2edec136f9c909edfaae154dae6dbf43efbfc33eb8f0d38e122a02e84bc69b20d410155680132516bf81dd99b28dab0f80b6ba05f679dde8f4c72e092b69985a1ce0958d7a6b0b47ef49dca9621e7098073535763ebeeb49253ed06bd51c430a714babe1b723b890c3528b8f1e2cbc2c4ee882bbbca89f0bb081074239ea136caffbccefd328aaa38843717f351a7e1ac1368bb4e18f85e7e434cd7101c8250f1534421e1cfc5dd963382dc1f27890099d9363c5e0e6d991d914a03e717859f289792ebce0bd6f861a8ea2e55598699be2ae44da733a6991fe03f51c56270d89f7fdf5e0a007ac0b136ab71d72c375cfc54c549b61030a11b4e02ddd8a3a27445c78bba022166634d6b4be5fb3606157aa0604cef3a7497b848e14e146b3e4908ca7a9c3061768c8846b916296a3e77fbee1c3b11b37a594e2ba41f6b388f4dfd59af70b0907d3b4f7860be712cdc168187f7b8e5cb8d0e25f352aa8f3287b7dde4e93643aaa53cc117f9a6682732e2783c11a9a7ed84fc7e9eca9e711604fd2cb86b63e54253c424467918e75e73a82a196baed4c9df6cc6b7ba97002162e19bef6b5b732e73b5c3aff057b130b34bcf6004ff756d714bbff456073c91fefcfa8fd9c65aee617a4f4c3f335fa00968d562a2730d893726e3859aaa260f320f43a84742006c264be9f2a984da79f744de32c4fff9627e881a0fb7622f9df83e3aabd0e007d11d5adb10cb0c2250e373039e3187302333f31441e65e13da4cea2b70ae8367bd4602ed8091ff3583c95d01fb333c0d6a88cd4f35fca294c0981f5564fba7975583eb57f3c8c07580bc8611dda4788fa0daa6a2ac49de490084a23fd406a7d79c8123912243404be9833a0dcbbf4700034adc53aecc7f283d94bb3bdcf4bb30895247d9ab2739e921f78bbc04d63513c20cf8c691dc79bf947dc4a11062064ce948614dcb097440c074d4f9881d5c1c965d983c4cd5861b8ae13f6022450537d998c14239330e1b461253f2bc33401d7de4476e1bcd4d2aaa34974a486ba8f23ac985bba26644f66d40b5193d209df229bf89a4e628a3dcd50d3445e7c1bc3c3e9816fb383d4a8a7d110eb7e267d76e701f4774701c35971ac5a2a6e2afd32dd38c8ad95fa5a7ee0bd3f8d236f533fd8738c39b5f3fe62a84b20c030540443795a06250948ce5399ca3b4c88fbd10d835b235242eb348b06f66f3fba0de12214a65623c385872c7c83d13bc59bc58f7e0a301c284ad0463294670a2d13db061b70ca266c7cc3f115218dccf693cb238d41b38bf66488ca214fa8914014b1def1ee21b0918cf2e90527aaa27ab5da5b19d92dca028b8dc0f115c648d9033042018ccb91dfed383ca57cb735d44288e08233d2e9818c4fc75cfa17f439dcc3d6453ec6f755eca43e5c2edeaf8982bbeb2959da66684a22baabc22c2a8871e1a8982a468b48b6e38ac14caea4572d62f58dc1e07233d7f286e6ee3b0b8d6b1441fb3d1c2bda4aa0238ada63898a6c1b08131a7861af1f8fe53851cb6e80a6800be8f7c9453dbf8b3840707c1ca44c91d5c8a0118ca57902a2207a66c5164528352331ceef972ee1afaabbb2bc844fa0b4a269d7a1f943dcd6f6cc59df28e9eb82926744ade39742dd89f82ec1665b72137e6a47c4b07b3f265258c5b3b2240974fe35358c4052bccca9f861047a96fa75720bcddc1d64ff40ff1d99268900e6c8e92d1a56634842f2e25d38916304804dcfd02d1bc5cfee318dfad0d293dbfebe0df58d8c149e19078f8e0d3c6ae5bfda76047a8635f9c6cb43de0eb6e3b92e1dcec690e351f7b929e942917f8de30e1f28380f9bde9af1f3df38f8515437d3dbfe718ab17c7a0e603f66eb8128c226fd3efb146bca7eb35d2111599424d4700e1505dc0f513feb6fbcc4bf6690ddb84321781ef609a43085894d39b6266ded350c3519f504a64b4b9da5a789e93a0863a373d49040e374ed5e209539cc5dfd6a9b84152e9aa387bf5de3b885c18ca72ee7981e611ff94e8dac324e12fd58a152c1e9b9ce56da082cd2566d0073f6d1e161ed09b5cc264093ef3bb134817accb5fbdac7b2713bfd1d80d6d2bf911e694206aa9d0c6143df2c805b48de963d51fd714cf841c32123b586d1ef327a3eeaa0d266ea05e21b34488d696d903c04834892102b7dec07d7ec0935ca82160a754be3c7d83b62a65da7fd12d496003d9af6591d9953081b1a761dde4903ca8f90b5dec9d820fb232ce221ab7e5c4e37c8ed462191ddcaa638eb84b1307a02b8dc5cadc0f8e245e15ec1c623c1d810656efe698852f36df5eb8d25c9e22f7dbc2206ce666956309ee2cef35114cd7ba3f587e67386be6d0eb748e7476869177f6ac15caea165ab9408fe3cbfc06776f9a8c72e95b390fef498efdc3ca3a467a280cb2f9c5bce1e4e3a989d7e6940fcf5419ca226d77d91142a54930aa1ab692e1b8a16e668c211c4ee40d305ec033b6c648023f1e4fa55fa1259825acd5d13a6bb7482ea431e4b559b3c90c7de6ef9b1a39a318c9de28e7fddfd207d9c36ea638457c01fa88e1279e564cf5f46cd1ead8e07bb63505e6450176834edec2395d273644660837e560a5e035a977df9e1e04ea1739be83584643fd221f78742870aab78656ab2cf1a888f9c6529ae971b06a998e159e989cbcdcd0a0707343d5dd27f3389ac4be6cdfd64945bd89b0d307c886fd35c51ab76b049edea63401ef4fdeb10f5aa0128a26cf3dfe8f441d80ba3ad5f90d2f2c8cd5ac9fb367f9bfd4af4255ff521c7cdc4ea1cb68b20adba17217aadb9a82d6978ba11b947feff15291ea16158f351e6549fde43e6e3d3e12c3ed1d28362b854ad3cbd63e41730d3ff8aab2110008879b5fdb73b5f021d79f4f9bbab222383d7468615107a32a1419265d62a172d988f6ef826d594b1ba8808fd1b01f4e3d6800beba96dc980b9d66015931f46112b15fdd70aca54a57923eb2897fc2b97bcc03fc1fcc49d35d693e2134ca3e18ddac59b6e878d04a4250dbfbcd62e7bebbdf56b04c1896f2dbb7a6a9f2ecd06c85ca648c6ad39a6b1b6b20678d8014b94d18de6f28fb920d939f77bf1f1bf62163a31b75bba56ff1d52d36fbc0b0e595c19a6482f3fb77a6a979ef72ce48c458d65b4551a66637ad899d62c941528d209a604fb23c6539bcae4d30049b93825c5ee4150aecd7134a0a9eead0fac137d4c71ab49241a447a85c1e00a9b1b37ab59027bdbe0df0559e68bc3875fe0e9d33b4cc0603e866019fe80211ccf381523d86e5e40a7a624e5b70ee9380cde483a36ba8277d0c73e67256ac884acda3b9e8f851d6015a6f7ff83beafa4de9b0fe550e79e691aaaa798367b17f6a42e1bfb2eef9e425202fd51ae4e36a4ce8054cbe051de346c31283d0b1f72e3ea5bb2f44c37b6d01eb8be5bf1f3088c6c78990e410eb94b554c3920a7621198d77df68ea3912db53e939102ecf8cecca3a769a891d0184c5b494a6ab37ab3410ae735fc3e93f6203d24a269fc2788d7adfc48d614bd785f87073d0c106d7f119cff0fc6acad8641903cf48e8991fc5e13ab87dbd2603743892d7c1ad562189e8657ee0081f52253ad881c008aa122a7df4100a6502a9e1c740ec05463cf1f931c0e8ffe3d93f42eb5010d9bdca1811f1e74efd57fe7ff73b808263aeebd9ee1272a70948a982fe95f0efcf954f5cc663bdc15538564990c5a5e4e5defecfcb8f8c1e061e01abfde39f448534f31e98d7af5624139baddcdd8218f107636c79ef7a5283e188e1fb4cb6a6a034bdf6bd42efe509db8f5d58babc6a468bef0fa272ffa7a4949497d014c2da2ab9247fab1a7613aa96c8919973956c7f9bb7125c98b64345689baec4ba29049557edd80d4e2e004fb3d4f3f633432fd3b151fea8499e109dec9274932f04c93ca7bc03f87aee848202506cf7c3a6a5b5845d227dd0623b0b8bef10d12b26fc4cad637a1e7c7002d27b61819961fafbc509ba6cf8a8c072a09ef4a14f80b9c96e44862c28d85273d111230667a0468174a450ba30376cfa6c76e182fd1899d15295038b897a72f05fc877bfa55792985a00990e869113ec6d90a581332736431d3d056a6a696b725329c571c1611cb51e6a5f144a75ea6b5ae6c108d32ebea945390b3eb07d18d6bd64ce855ff0da5f873de3d15811296d487185c84fa536c2af85ebcabe8dd8429cf1501301244a6d7dc828376a0bdfae0960a103a1294db2b8d81c48442a5bb9d09b693b6bae78f2121e730b20fe4d6fd4e3ceb137d3eff09ff8bc831aafd51c0550b68d54de6855b90f6d78a783d5d3df2828443ea595ae2121204fbd533cebf56700c86ddfb613ca7984c8b65524fb611fac1f9b1cf2f3129c47fde6ce8309b8ce4b24084b70e2642e4b1ff753a7af5c9f902094c3dbb1b325e85980cef06164380513c4e4515d2424f106bf206ff3fe5df646b3944a63f905f9e1e6fd24412634fecb820245f4c60187bbfe0f1c9a5a2880f0dca6b6bb9f6d122ed254a817677123c55abed1d6b44b554524bf6c1e221486873248d3c45a46ace957178e9549b1b29e9e4ae301e19fb1e912c5cc9a6afee427b7fd0d5ac604a819fb899ff669cef6dace29f77d18114d81aeffe2093786066211a18f38ff85b516bcad753c7e8127f7e0d72e4f4b8356c9bcda396980f22061eb6c4c9f0ca12429ef013f18215fdde603dfc7da013ea688464662b80764c0e137647e10c295deb4a3f04ec00d31a82d55a1f461dc73da6136161f2504f49017beb82057196d261e6617483994d58a92f4a3aa0d8e5709cdc4942d74fb2583cd8e2670dee4f4c4447da71c6553b2c5c0b75653498210e8adbd37ea4bf05767396db75df14de4c84dd9046c187ca10a02c3b56e7bea5676cbcadab97154acccb96fec457cd13742ca234321169c93b044ac62687c848c5628f876b65c0b6eab5e7eec1ba2f92b7eefbccd3168b68db1672bc197570a286397584da4e736240288894b6d30bf94cf61f1603a726173d0b61c2535b739c668d53ce80e65e2c12e9f1764437525bfa963990fef0e2de38132a345bab559965fcc60eb0f140784b1d38b61d8cb23cf23f18cff9840f241390a5f3d9dc57fbb50a98e2b3e09486b51d46632185abb120c6dd6c4d9ec38db74f7fcb3564c801b8ebf4ee4af757e6346999a3d512a38acf0a5d6e79d3090f465ef2d38073afcd42513078c3956e47ffedee04029962240578eb69c388cce4dc86286a133425e611920b842ddc034a5c8024cc7d7d25dbed554148c4d0ac25d30b8cfdfae27d5f7971718a260e05a251f66e5a01d3f47bccf2c50e092ff1122905ad7e7b034942b049134e01e7bf2208bc8003d3c92004d252e5ca50483742c222bad0da34b92361399132d86a35d377d2861bf1ff4cba98567b04b8ecc37f7995b975f872bbcec4f3444a2c9e771cbc8d175792b2f4823b2a6a0fec8ee332654a2cd04edc869b805aa15f0ac67f3436780b2e042f0cbbbedb4742edd801e61f4759d197d242a3bf3f0b7b1fa0a31ee892724f781145a2c5c4a7c7843164523c608e8fd5b85c8fe252cf61063a79124f5976386f56cdecfe87b8c798b851ad049e07ed5d13e461cbef3efc32996e032eaaca68c36a41b74b87aa432825f6d153c8333230565252afc2a8065cf334e2d7119af73b06c28d46ca9ff5149be7face454599b6a4f80e6e8f7467fa460cadbd90905b698da90db5e87217710f1bf0cf6218a3138c3999f211c3eaeca78e6d1a810385aae49b17588d3b9e83def1d147b1c0e22ef31165b50d2cc782b74613974b92075b8211ce27936bdc1fee5b07b9977ca10e62984d7728a5acd19e4259385240371afa71fc51d1314833b62baa1bf531f41456188a8b28f0d198d89178666343a70557a99e929a721227191caef63bf415a545ee7a77b33a5c6e9f128fadcb8008268876df996c663ca1a15276a79542ac70448ea0326ead5c6266494111d893fd7118d8eabdde7ca2c8b2589ffea83e9dd71690070227b460ff8a045f241b77f543f1c92db1303651f499ef5bd3c8e7a4174267b6cd4e1d065ee97387e72df597c3fe5a8feb7516146086c109bedee17bb80eba472b37c67812d5e8d2d26a16815899024eaa2dd114eaa641271a8597b494e72440259419365b54856e89665a105a5f95fa26c118c60538306e0137101dcbb013af43c3351505c15e738075f96375467c932b204b149040498c40348f4ce94cad78040b88045aec184ddc58c0e00d592ba0208c5018131e908084676ffcecf68b121c13657ec6de6b85a4bf410f4bf1b4922a59452ca2f0319031c034732166660a3092b826c5a4c21b30fe27b9db890109588442217d108c9b582c8040fa1931718a21cafa4700b1c2f2f5e42805bca700d21a6af2442229718e21019ae2e684084483c1142c16ad890cae582def0ab09508d77bccba1965bcb3a7c638b3f742f2a474adc75e48931745deefb3e253d5ffc24566df4f3a10e5a9a9db995e6841bdabfa11c7fca31b6548ee3588ee578721d811ac7f1c938f44446886320ab73aa4805ba311473856eaddae49c7565c13e499a083d19c7b15701336547183c442b31e1179c0390e40849096736e4d6c6711cc71e621a015cf940241fb6a51fe26ce5321aed98cb5dda886b6cba752eb7d4878ce3881300168b328e6310bdb4b90b74e666e8f7b9015e5ab00d579b9c09e83a9bb36f7472f4d2e62e7a892e9092db13b4fd388e438e9294961ea323c4206a01c99086ad5b051c1013a36370e82518bb17ff874170eb4e0dce39b7b334dd79e7081e6d9aa63b3b3b210bbdac6912fe5dca3b188ade970db8eb7044277a59d39d2fa79ed8262c024022a8c28a635c363a0c8fbaeb129d67e68381fd098273bbdd6e19863f0c24822a3e1672de1ba77ab1d7e865bdf1ccca20d5266b9df5e6e18588b3ae1d6e18840c7e1007dbf0eb8d2ce6b4cb86fd4ab57e964eba9fedd66d1ef373dafb64b25f48f4d29e4541fb043f1b56b92e1a70353bb41f0ee28631efdf835974418755dc70eecda81899d6defb648283c3a4e39ce779daa0f33c37cb9e49faede9799efb3c4f9793f496b6bcb00d5378c5ed3bbd885018aad65e3fd42ce53243b5f777fa5831e17cf3d717bdb427a772de6e376c24f32fae143aa80576ee7d32d9221abdb427157b9e43a7d18974ee7d32d9ae387a69cf252ab10bc34837b3db383cee03e291ddd99c5db95e5a9aedd3b9bb43bd878670933ed0e3e3cd59fcd1b9a1fd4c628c5f304df8847a1a8ac36e68df76c32de50ec3a3561c7a6969e009d5566dbad35863d71c4534df5d8733ce9d0806127f9c586968345a47c345b01625bb74942dfe2ad7216b681fbdfdc8c5274546e3e9976ac89e58d2f8341aada3592138f4f1bad3f32238b47f1bc174c421af197243fb47a5a51d25dda32db0dc0b44035ae59864dd7bb1d26e56be08d4442dac0ef703381c0e779ee779c3e19a1b749ee7f945c7e17027bfe788739ee009e2f0a5a4da605c7f7581e11c043908d6d1cb7b82e9d205525a1bcedaf8e971381c12797b7e6e004ab2c335c310e748f7b482e532c1e1388e8b5eded3c339cf7bded3e331a62c778be16f4de9f74ff594513565592591204bbdc459e8041db340c4e826c6bf6b17c49f5313e024537af71285571c1a734cc9428e2d4130d41b5011e996159c1cc1049015053816c3358cebdffb333676ed8c8d811de60cdcc30bdc1416ba68a3882e3f925802c91340303c6103c638080fed9bae7232a104db25b6df838a454c7f6ec4b4be1fd804f45b0f2a0d10397ac963299c560f9dc887e0a35f045c63d2a9363da6b59d11c1a1fed34c4aa7d2e81700a8571c0ac1a17efea17ed3a33ef5abfa3cd59a38d4b7ced47a7a55ad2a16111ca61587271d1c6afb15d498095fa5b18ffac7a7d32a47f5a757b12a0ef53fa86bfdab400d5d07ebd7bf836b52af5f9e73eca930562d59e55cd9e9afec543fc7cbce6b7d215133d85ed592d39f583c3c3213eb6fccdbe1545ba526651cd7ac72ee7fa097c6786a660663e9a8fd4664d834b3da2c9c9e90bf1119e7a67f1cf237e2b2788cc8b96f62f174d6cd7d95dd97ad366bbc207f1287fc77d0901be1c8163cc051c6521114197fec836b8668c172b2a1a4491a69c8f8df1caef981454b0d5756003aa1c8f8df14d7f49e212c703e4ea88c21e3efcd681f1cf29bdbb2dae2f666daa9b64eb259ec745122d41a14abd6138ba57a01ed8d7d1e0cac62fbcb9b585dd25f358333d3615f6bcdb26a651bbcd26b6c0593fafbf62e10db3fda04f6df940657966209c04347fda903796ae6f6a8582b5b82ffc2e221f246642bfb2f6f44969a51bda452affa9cd4abdebe4af52f2c9e1187fb793688c3dd2b4d7e984a931fc562711cda108cedae7bcff3b8c9f35846623833f4126ca1df2fc1ba8de8cb7958624dd3344dd3344dd334d1e8524cf0bf77ee0004545c32f04b8a2cdaa05fb68da228cc344d7308866b2ccd344d93886e5a1445b7ee8c7a189d7e551f7f5d55d62a83fcfa3bb8f7f565ad2a0af7336b55bfcaf25759d5d9be91d9104aac20210405150164f4d6d554d462b9cb393370a57bb1faf6da9bfd35879526ff09e3fddd8d95bdfb6e6f363882b10c569b2a452cc732efb9acb73d8217bc5d101cfa7e03eccdfe7c01fe7dc14a937fcfb86c02f93bae11bf1270972e0c5ce95773934d20ff8e1dfaa86dc8a8b9b18652fea39c710ea7d8ceac88c4ddfbe7c80e69bdb43f5f4c028cbfb4316d72e1150308822008a6d17350d00682b70bbed1755d94f373f75d76e1a0c3533cbbae7b8561f3e9ba1d2eb5ab45f4b2a61f6844e6141d252975a3be3e74b83d21f3ffffcfc2d530f4f2ebed87a6c32bb01bd6bc128165928afe0ddd900ece6d5a2dde5aa39764377b165bd0e2d23ea29764cb0705b3e9e92519428bb471ce45284548922461d8e3957b463fb600cdb07a1cef38da1387af383a12bf2114d80506ce57e836809470b26d9f4c445b2fed59fed6447c6618d5438e929496ba0f8a18871582a2282a82904ec370e882a11504b760b61bce173c0387593a7abf9ba9d0ae1b7678449783f8c26da9e7c713d93085449c5ee6a344185074064ba1280a83c16a9d0498aaf28aeba5a5a134f092a0f4c279c619575eabe8a5a511d9a46098ed466b5dd38e1f9cd390c038ac8c5e5ab06a1aed344255180666709d719af2c9643f1f2bcef98b0b2ee5f6e0499c01875c6a2ced86f66b4c3f0e81417f7eb59cc525fa55f4f58fcc1b09ef489284420a0da16ebe419a836ae08fb961f64892749158e8d6c43cc9a7294d4d601c321c6b7e767b6b429225499224499e5e4f502e263ca7b6c028394406912759239b083d2192e213024992244992a42aace1854b07ab601817951d269390d4822c4c42bdb469f938bd3e699af23099c6540106b8fc9b5e64d24b9bfea7694a7256d0578b81030057528f708c0f1523d312032049d244a6699ad6eecc5a6b62d9d4ec21e03f3f179114941c2283c893ac912653cac5a4442f6d6a4b2dcdd6bad25d8af5fcd88008775b775baf61cbddd676ebbc758663ebcc7bedab7ded8a4ab31976d591dbe83d448c8c5c31dc7befbd3d3e80b628d4e98c75c62d749d317fcd718b8cb27e94c7bd1f5328c3690439f8c9304134ebc1f8bd14a633fe6c8d4c0b27e21a08829a920a7b5401341f1d93e57487d0ab067ac341b51d1cbeac90825ebd3bbdbb308908e912dd5bf48243ac49714107731f3b87831a06910412807210dda39b74b79437a5fa9b74b7d41bfc35307f3bcc4ccced332f33aa99146ae664f23a71089edb3affbf175ad1199bcc6ba228926da33814751832cd8b9e44a4ac77c781e0c71c7778638d33efaf3652ae29b7aac42c2fe2195d9c034614a2daec70a5f11243c402001792abb4747b7e7a804bdf29009f17624877bc1db3a3a6455334875ef4f46981561bfc38ee63ebbc757e59c15b671445d10bd67bf5cd175f73875e5ad444512474f552324dd3343d19cfbb995d4ca901453df4875ed314ccfd35efbdd7ab02ccba0b021828fd753fff0ebad72c14f477cf5928189183427df07f655797c563c465e574dfb15697a7fbcd5addafb2fd466445762edfbcc80e89430bc32179a45b1cfd1a5499fe0e7a94e16405a42e5d70ba875d4be582b6c84e8fd22deee68aaedfde786eae678e2680b22c01e25a2538d79a8624a459d795db0d873078f43aff3fa7925f58fedf9ad8fa60ac5f3e70ae357771f1ff548a3a1300315e68f2320a855ce74b853007970f6295571630276e718d8112d960428298a689c41f1c49ab33d6198758aeced87a303e6eb775b77538c5c5b9dbba5543fb1cf36ef3ed8145bdb426914579b771389ca7a333a4836b2caddb6fcd2abdacb8dc6ddccc032b0e43a35e5ad36662d3d4663671a6ce679c955203eedcd74318857d1171c52044ce452c22c99e372ee08560f4721c4264b4a1b8517fde77442f4791d74c1e2a46a6256ecf1b17f8bc2f8b5e8e1f2fc5318f7adc6337f2718c9944dc87f1e77d074097508ae8450eaea130895008918825971591071085badf7d4bc7ab8abd11a5c8af23ed7263ef171abdb4b326e60c04c10dda13ccb32dbd0473a4dcf8dead99552166c7d47a6967f941dd409aab48e007665b34ebf95929318102550c7f0535965799955f6513c0a86c8f78f8cbbafbbaff3add755dd7e9fc9a868e6ec1f182faabc85fa2dc1b257d7f09ee679536f67ddfd1bb1beccdf541f51bbb63ce3f575f4d93a5e79c9f868e9ffead30ece228fdeb374a623e9b9231a8d4ae59456525000004f40063160000100008038582c1589486aa64f314800d485e325e563a50280e0643924094624086612004000084010006000c830c53cac90e84e9a423440d5eb4430ddb81c16fe30d445279e5490b34f7569be995c13d6bbbb1edbce028295594dc46cdec858a582048cd9b75cf51ee822c8a7f2ac8ec17a138311bc7879d162269541453c53566d696f579272a0993eea71dcd7ad101a36fb9cd2fd6aae0d0c8d7c1ab6a41ff3eb0482e6c4c4896ae1192bdae954981436cef8e9ec0b5a5f40f5ff83414fd40ecf3aae057a53f97f7b73b77154e207422bb4a502f945d5d554dcd826e341425e6e8b057b68bf0df8c9d48023999889777005e438f5eabee3fb77f1d664755b73abe3c14f653564c8db7ed0fcf63e9789027aaf79b0c8551ed6c0429a4c31b729fe028d64d061e6bcb5cf6cef5e9a3635ce404972f9cbe46784b1dc3df4270ea6253d0bc386824893ac596fa6ad15fce09b2796c8912921474ee9637435b45ad11923ec138977d9c092b19e9d3c819e4a49132982512047fe1d10437050edc2c1f6dd02eb141bb14e5d4899955ec42e9ac693ef26dc41fc2a5bb70c1454420ad4cd0f1a856d694020692f25fd123a1b95b0700e4a547b120322ae1fd714147bc228f532dc2a222e8e0e09012fa531ea8474fc0e2f1e8ff56f247a6fb8b630cb45bdefea0a83bb39cd675b5b5750e31c7c05fc928d2079d0929fabce58afa49daab806a8ee55d0068f2783f0a8f541bc9b8fc9b6eab10b218be0dfbeb2147a6b5081fa6dcc0f2fc2baf8694c5cb9a591517dda32d7d2f9c0d7be3ef211e7e84121b50bba5f1d0778048543c0e36c207e5e77e159e03fd71a632e17d4321d16c7316abfc348763e8d1373deeb33eb0100701c1e067dcb9a1452cb6a086023f901bf9d66e46a92140dd2d2681e08f0695bae598f87c3c60036a76049934d17aded2c093f66c774f94dd9cc7cd00172a3645ee02b184ee7df4753236ada10e421a8d1d0fdd95d1c6781755475ed31b55bb28d2244e97df08c5e70ca8230811bfed435ca057b18e4771f92ba1d36689720ba4d0319b71ed873a356680210c888d7ca3e2b99829378cf6bb86898549fd4585ed83feb18792f21f259a471544d45906466e662b02a4e348872d4441808cdbb006d0377f05e86c8f5c3e2268bdafe2e3d003a6deeba88b6750b49c95a464d07cd7e94cb449bac95479282770af1a24302d4106be66e766608ffd30c02189e19a206bc9ce45fc13df63505e3592532458059a0ea29c7eb51dbe97506c8b3a760e791188c8cbd7b5a8167870fdc0444c9893e0c2e7f1ea192ed8cd0709440cf45a7ed6f068774abdc7d9b3fb8f2c93a206beaeacba06aaa3334400f559867270a00bf4abf11cbde41e1ca6e38fc6eddd17eeab33686d7d9f60d3c861ca2d1c7d8c468eda84e8c437afe517579b418823c86a5a69cec4115cd0a01e813df27fdf56ca2723c465716052991529ee2f9cd7b80c3cc9cbb448badc450eb1d8250337a4101103fcad4948d11facb9404c60f88a70c2768b59c4f610b24b04db556ea83833a3b6986c0066650a0db67b18550bf0a905824cf06b7fb1553b1d45ae841f02f15ad8d9d182304ade8278c0c25bff3890af402ff18a3326b372c19e1dd3b43912658f66dcb9d4ce4acac89b5ac318ddec8f3a4ce8629d5fe6a64727ee556f0768ba087ea7e9d0c489d9231ac2980ef33a54afed22918bc33e1655b1ca07a2cd2f5a7e3bb0cf4b74c56f175a1b6a1868120dbc4bc92dae7ab3ad41203653a965514651ef6f3444d75f3bbefc3a47728152aa62a552c71d5aa8fc5d500d3180945cee672cab25f5289309ebb07fbc2e518aae1de1aa5f849a681561d54f8daa0692dad4a37fe7bb38285633804059dac9b4982f8b93c7d9d0370d1e2e0e08b41c53671e0bd143b0bb03692e611d3095452b5abc2b2a69a21817539e5abe1749ae32c281165d730c3d5d4cd1af8944300e6d909de3fb4f555a48197030b188219b24f9dd514cab76a6c5e79cb41e48ed78ccf372392ef1297a3d95c3392a556315d6ea21eb6a03923ae307cd78aa1ca0e97508bd76fd3c7874fcdbf5a129b05273358a9d7dd0945d5aef66c2c2994e2bb80369a69aa181450576de59f235cba43e02624ddf99727e70c17a6d7b5f7b8442cfa73dac07991e8ac32dd2ac9ec95279c7f203029758049f14be83666dbfff2b6656f41d7843052bab081fc76ef277bf783f8dd1f3b0f823453c1d7f9b9f1bc5fb3676da5b11ee9258bdfe9fb53f1174897df915e40f44b98a50dba6fa5afe697e86c5b520b29e297cdc648494536aaa161e77d48ca84a15f30afad42fee7b4e129c703c6ac60da02b8e3d5d6ac2c4ef34900da89a56c1326c683d47e0e785a8f3470327ad299a845f246e365f8e0330dec1853c9e2de1d5de4bcd9d729ed54ae74bdbf839a2882f07ad6e3140d6c6031a18032d894470a7b434a80773b93ab1f3cca8b1d59914e4f3efb754e57d9370fc9609d542be4cff38224945fcfbbc24cc80f0c7bec3460de034450fbb6d7ab9ad448c1d41ac818e78104bdb4bf66101bc4680a4fb897542c65f5e72dd8a0524ecf97a81672872fc52b69ddae2bdf32dad78a1acfa4a0662fa1050f904199f6fd54cf421e30a03419c0b4481277a9b4cbcaf421a2ec6373c23a4fa313de35a39f04b56ada1f2c564fe0db811117ad2d85c43fb014c0b1014fa6ec9944f7240b81d1310d12732d57319bc0f02585bb1a49d78b917db3a01adb83e98665927e673af436676ef6cbbb2c8637aaaf1de43844cb0cdab3833c830411cb29804d8b0b9a242376e4338c88a3754671bd2a57ec42318e229652afb2e7760df63bcab8bf435636d138984cb37aa59d4122f1336b4174ca0e48bbf7fe50def9ad2ef6ba80b835842d8a5f1a6795f1caae147d104403ece1ce2e65405c588e2bca5712ec7180e88ab4f1f8d1b4f73f9eea27059845883e7154294dda957f5ec9134b0199f7760f3ce81d75008031f7393d778f7e6c024376637da2faace1eb0545a84b258038ae51eed89f69aa6d188cab9f0068592d4d47a67bffd128fd96c9fe4b1d79e91c144d401502d5170b7c7f6622144cd4a3a3677ac1e02b59e6d7aa663f0276ea4964a3dd5683eb5f6858e31c428c64d952b2fbc67a8da4d74d9970cfbbcb93b3974c9221133336644d86ec4dde2c8817cec0abdcbacb4f22eb167b7b354e9d1b3b26cf7df0d5688e3baeac88b4bb482f9d55eaf25a4f38997a86688ca4c4cf39950a7c10091b33f9ccf98aa83ca85c2a06c8a80b38201b842d84ceb17bd52025c015c5a80af6685d8cb1e539e95272e329c6c9bb7f3252726afe8809600378f3d812b41c6577fd69af3cc788fec2d0aab6f60d81412f220eb0cbd7e129b7c3f44660b711d4c55e6c881e4e1a51fd83e4a758cf7cc9529743dfa7de252919036fa64b515a2b8453efab631887f2483a190b3229d88b31358149c6b14c079ff8855b413895bf0d2fcd63c9fcaad8935a932218d281cd9e47d24f5b92d7642f589030e4bbcf4d8b793f8ccbe2ae4f4cd26b12589868c221339ad134b5414dd26720954b7aeabfabfb9c023171f480ec19c2b865c4a2a96aa6bbdf426cc1b9bf50cc1c04b54bbb131661a76c3104d4753197e94429fe68b032cea8a47e59a9c248d54a8efb73ebe88fd60012c7d8147db38ed7ee7b17280c6c02c022fb39ea7a3aed0eeb0ba484f0da93dd56ae8d45a91f9704e76bddd23c06cbc96643947279f9ec7fac8c04df8c9784a48864a251f6112382da499812a2035135a80b8a17b277b02daa80c4d2356887709cb601759ba0140305e703981ea9ecd3993cb99dc69ddc493ba80cef35d5d21d4e5bc7812d8d97ba5444c804314b8d17b0cb23a56a3b6ca5fbfabd2b6ca839fb7df865a55bc07a537bed57747a626adf489b6a123e156983786eeb19e89148b00037342c90e6d1ac1fd238d0f492f3b9c888342d4b152c78a6cb396a4e6582df132c37101823a5d2e7be9a1ca840dd043435548662657106c9e68edb75421631fcb13e2be8d68f281979b5e177adb4c5691453fed593aa2520e97e3c5aa7d1df8c3c1006a9427d37eda92732d9b712e8446846e900aa0aa980d348afb4b7a490db4f5fc1b3c725373492665842046f0421a3381ca643ad4780d5d6b8412c74ea8a0bfec49557f64c0a015e19484e101d4544c675a963670c04c14bd2fdc308c184ba7adce4b24a37fd1d005ccaccce003a641a1ba91f89bcd55d1adc5cef6d74d2ba6ee4009c66aa59c63b02a6a1827bd7d2ab8a7b9110a835bddf64c694e072b59257cd92d604968b59faec513f763c40f8704ceac21b754590a1a9450315dd5011f3d137708e50f8de4effb8c11d939018e82a9a56132ae1142d4f2a1cd2920530dd3a1d7b697314d22334075c11337ea137d469c75f9f50484d54aa821b9fb167bd053574275178a16eb4e3b8e137793ec98405b3cb46a6051d89cbf2c7bb725296c36947ea3ff09972522eeeb86f41517d66c59ee179423a6af6d89ece8f6e42b02e3301a721a60921c682a4093ffae8d7260752d51c6e1c76fa6d9a7075d3015043093126447484474030be025352101a9574156509ef05e9a941146d7a7502a8edf5de42de24ddc298a4f163c50178286a5ba3cec51d87454156cf43c7545956b423d212be5c9847086ac9b380bce107debfdaa4772ed5c8c5d2493168df3303bf9c9113ac6fd5d3eea218185441250ea0863c611a188db60b08e763d727edd5e354a0bd3ee09028380ab4634606eb8bfabf54ab28e6eb51a26e0d66d7fdb8dbe0c42e99a0a97a38f231f47663b796f254700c29ef1337e017d5a946338b7167052d5846b9d63793d113061812079c324d99a084fa9e2c7a35b1784df3ac1838f814296626c3a3d034505ae07fd2857a85a47290825635819931a5456500928423b77eb0201fb267674d2b74d2fdf2d09725057e08ef4e674820f50ffdcebc2a172571b8527441e089ac51b35ad1e67491fe88ed45aa26ae006c2f1259311a04dbc11b1dc65dabcb62490767e5ea5e751e4479cdd8c6ee8c3be75db7ad845ba8f03dbd4c3d8466434cb43484888ad316766406381510a153fc4daf067c57ec22c90eda2707e62729eb6874d4052c0bd3aec742e2cc7bdd333c32103948a0fc2c68f658f4735ef231ca8a5b0ceb4eb0a4a3f684110a36db79b62ae81f0232d224e5a31ec01ae6defde9c435939691344c4062c9e6d99c9aa7b4962323941157e1ad28448c7d64ae558be3d97af45fd14a2b1e681ca9c9c1e02e6c05a4cd0ce9e2dc350b79df7145a5dff139a03182613502c0a433258499dbb01b4278caabb218f0f70503e84e40e19801c808d62e6d081ec2d0b3275ff448cc15f46755d4e1f9eae9418fec7711d60ced517719b8aa8f8af5abcc5eb0581917d0f1a72d663c4a7d99efeecc79a85c3ce12dbbeae066ad012a7ce6a89a757df0f634bfc72250a45043f03456a54f0a598efc9b6f0d21644cfc57f7a30e50918e0d8d93f9c537409000828351580b1b95ed23713b229849e5e5736396f36dcc5bb27e30721e6442fa105b08f4bf8eb6878185c815a7385e9c0e8f10f06a61ffccebb04f550183cdb1ba98b8788304fe14dde57177dd931441c95e4027fdfd48bf2addc2662f9827ca9961743a6039bb15359f8123dd2c1410a911f11efe434b6794e78411d2ff4512eb250307881d62af1efdf168315726f47bfbf42d35503100c1418f9f2048c9241856095a2519c0316beeda2b37f5854be420d1831957436f42a57374c5a4440671cf027ad90681287955152604ec5ec3ef3712408a93352d6b3d59ceaa624f3501f7ebae0840a7626e08ce4c8722c195facd31ee351bc515102709eed489de5296854532a413be3de834bca52aadba658de9c2e8777d7e8db1653a7eb6c8038d130f7aad3f094342752884c02e7ea6eb8f76fbf0e877826cd1be87a32dea5b003bc4601e6992040b853accb23c7236c1c842091ada3700361e7c31b02e3d08c685241b0f8f39e304e1121485dbfca88ab5c89ad7e90fd5dc7cd36edaa67ff787d84aa3286d05a3c768d881edca5992e8c9528587d6c96598522d907ff7b6c39cc8c39b71d24692fd0d8b0d442b3d044d144af4811c5946e40ab6fa874868eee26bc3f5dbd5d5ee7c60557e9136753567910caa3412d163c80f016da3591ecbad98f6fe819cd5d005bb4f91b2f76d0a90361510efe7d698fb34b12c5863683538d0f02f9fc189f7c7fffec3deec0f56fc646f5bbbf2b22d5b46462378dee14d13511eed877be233a544634dffcf8d4ee52e8d75014ca72301cd330c6f034005913e995b5782105253ad674ae6214db2210862e4b9c8f78c1ccfb4c601a1162c5910bcda8434cec0bd1a1e76a3512d35be34b6b052f6d2f6d4e8961a302d264e34f181de6fcfe90891523977200a0232efc1df455041bf5ff5c1b0cee2ac116f0587d9ec0166743aec3b58232dacb708a44143384db3a7d3e06d2cb592c5a06d801edf73ca49d5ff97908ce0f99161f123816502ac2697d8e303950dd6fb613e185ff8bea3aaa4e9e8ee8512548fe1728a4e5840fa37db57b8c5d7c012c7e05d060432c381ca3111574a89a3183a18c6b17ce4e5b4a7033d207f069b035cf533a67c1b31c280ea8c1794272fa0a068256c785b62bc6cb38e19b7a53f2ea506413fb4ad4bdf4231beb7f95c2bf041407a7f35ce311b56fb5101cc4d5db745feb9b1c5adc63ccb9c4858d980e3cc898fd51a8db4f24cfd2da201219c6be64c516603669b30825b601dca17f02ab864a0414035eb6388a6c45b7d35cf345a2709c85a08f9d268a66087b7d2379ec9fe8aa2733be3c9d91394f7950820300f61fad8c2ba9591df5a1505b8c7b549251deddf322cb99d709b9322846db1bc23eda8d366c90672e889b5ce217cda4fbf3450743a39f7fabf579860f0eb4fc0f95898e0e717901a8f32974338d9f137b76acab8d22f7bb4161b855353a55439dab22c4e9e7485c61c7362e5c56b48095decc6c20887309298d7b34ccc8f4a975e74432293a2e4767c67017c199ad65eb078ac236fde809eca624009f13aa7ee325bda253edbad50a362122f8e65b04781ac5f4a1af50ad4b29141e13f47c427fc453d39d02bd4592e9a9accd36d0059b3c3897a8b125ba8d4ae6a433910aba6e95024df4514dbc8abb4efe215806ad8cbcbe8055728e2d12c27a5d3aa490d2dd14c805f7a39c7d79c0ec21f02e2a030aaa7aebf63b5164542842ca991e29878e935322b4e30279cb02edbddc304f3b8c804a8bbe507cdf84442ea78324dade893953a88fcb2d48f060111ccca1915619fcbe23f4d7d2d9629bf1fd5c4a8f896978c6a413e9cc0797ebc2ac3f31e5060e88012a18e6a3800f1e30145aec3a9fd9765caae9711335afad937f7eb7457501e21c4ecbd741c8acf8ecfcb8d0509321f0200a48e09ad6d3e187e3c8f8371bfbe0a9277122929089fa9e78ecf39060bb3e6f42376532922a122f6e0c662ea0761696eece545c98d686686b91b1c72688cd126c79a6afb73d1501655ed4954973080389fbe991df8dd93b5b9530252be7e4c8980e5776b55ecccd5639ea50a507519c72b451604e7bba6da49141dde44778a9809369914cd946d14e30433e10a6ac08aef39ec9828288cb50a8beeac1b46bcffdf7bac3ab1d7518bf2313609aaa6409d811c9416a7a7cbc80f8ab622beca38cda74695184d1840cd182f05ac11f1d14382cbde794e6658994b141ab73e7170788e5c1c2070432af9db86fb84043ee189b6ecbc01b01b9754072f0d2b4e7edc60b88e9fcc7f51f32e7b154ccadd1226238cadf294395b4ee58a7cf6c15b91415b3c0c0422350095332e0db3315d38c843ca8b3abb38db7348b89c3849a6f997d3822e8faae62e8d7be8327a00fb69603fd951653103d154522d4d8a1a9e4820961352c36d0d1a6db750d0c6e650384b10e570ed844cdd8d44ab9c090b1923659f55ffb267217a306f86d19edb1ee1dcc53170f9bb5aaec4ef3e46069ac7c7da802eb122a2d870903a3fee8bc17dbd29833fbb55c2b68b0ae717cea25c10d3fc38bb38daab7421e857cb5d0012ff5cffd8e5cb95d1e1192fde8953eab40dccd6018b0c8404dd09d3d5a1c3c12d65df412d0c70abff759d639527a5087ecf72c3c280a439375c826fbebd2742fee411c655023de95c962b1c6f72a5f33d411140479503326de3339e643c4643e381efa0ea1ccf080d5f3913625109aa1caef55f739db57a149443d8fc8654e9f6269ed3bd2eccde865a051be4ed6bbc2b4d0f57e26ba7d819bdf36bbd798b94ae85e5a021cca7b6dea2c35e497b8ed16c8473a7c12473e7c68686ceec8750c7f15dec84d77d42ac45b274666ca2e0b292205a300a8fdd57e17bc84d95b5b1cf5f92fc67c14180158e8ed16783a48152e53b45e07125d4e5ea3b80dd64e3a7440b964a6a7f8a6317fa9fd88f652521057547baf831b287a763af36cca70401aa555a75d348f2cd430a3b4d76b143eb81ecaa259f0e9a419c8367ea601d2226648a0800c464e4de98d065c840a3ca36057e14ffe23af61746a5132e84165b3e144f824b807c63dbc50d4ad0c2f9696cb3e17f319675cc5d6b24f59000a6154e9afc87d857f94721933b14442e244b1922d764f7691c32d21df77ac22590c60511340d5edc7ec5ad5ed42ee59356ab71655a733770be8338cb81236b85929d78ee84aa983241ebad2f384147499021d0c406e4dabec51b01b828830434fa816b725de702c86d8d02c383bab32bde174fb518a4c77133f84cc95909cf855359127803d142975b4ebc19168844f550a89b24ab01c4c61d4dc1dd84e1eb5b051652bb6c64400db05c1d29352cfa35e07b4c2fb5916f6c21afd67f828f58851d229535f9b902621e4f0c485311d956b27f885f80f429088ec5175ee5f1de7bde28332aca827e7981d2874b83c9ff412bf9c432a4c6c6085f6246825afd71c8310a5df624b90be6731f5574233bfa607aa794410569bd35dc0b14be72ce1b5b07a5e3d20b34cfbba982953da6b06a36a325c2ee2b94a0eda71c7e65fd1d88c17a90b99e9a17e66c579c2e7c861151825a0a19a43d96d8ea400ddfd01882ffd9729354f9548bed82c33e0829271a05e607c435b42986c9f5107bd290e4d8fb9616c0bc0c299da465ddf9936eb51304df17f456c784e4963a166be67afd60ae33b3247065a45a32dc0b18080cce8d9ee6971603bc90b987ec286fe5d3cd5b7cef84c6ce108a02ca9816eb05fc40c42e489d68c60bdba5a276d40eda7c50d2a0871032a3e055429abf1645bf1808682e83b63bbeb6d1aa4b6be95041607c40d000322d53003ab306dcb4529e9a1e04637b30902b8f08c73d51276e2c606a6d0be510ec4e78b3ba24d559117c5ccd1ebe38796474281ce0fc43eab9c56ed670251b4f0de4e0957debe792e1c55ed4f7ac83efd6b36759dc49291892ae67a1f71e1da8790adab21f011f1e25613ca2fe60cc20682eb9cc5f4ccb2beaf840fcb958868652fca0e52f530e209b7708b34acdd6faf48c0fe038a9b4a69c0c7ba8c6c4a461115c310e6952704dcade60f86b3f63833b29193cf3825cedd6227245d8f3967bafeaf5495f237549c29853578fbf336a6890035814db40a27e2d52764ec226fdff547740264391dae316738939f0c9ba48f9401ccd32d28aefdb55568d4fd2b5ffdb14224c85434dd8fe8ba4bc37b1e4f371b94fd97d9e2693d68008de7df99913224b0d924b702a5e4c637d40e07fadd40de140cb9d68ea7476e53c828c33a4ea2ad06dd9cdb9550e04b5c1bd54a8c32f51ce94d88c8c2e4e4f8df3540cf004a282517d9ef8580b2edd25a8e42d070ab85604e67cc7204b85d0efa60627f20b88c7829bebd086b035a6e12dccdc4f887a29c02a7f5ae17d888ac9993ae355e38ed519fb875ee134684df9835443b425ab9762f8f3db6e9e687cbdbad5c96e8354a983a70d9dca9c38abbc56a7faefa1d3c4efad972bb27fab26074aa61f734fd5eca382c7a8c60cbff1dcee2e782e75edc3f56a096b726d2e3a35b54e8b7b5ba63d975af4287a85becf657efc0a58ebd1d45fc157170ede28042adef66c913948fe9e09897188d2a9cb17f47ec852b99a742cddfad97f4d4633523485b1f91db78cb45b27f2f8d8738340c9ba0bea3561d2e23b94b7d0f5fb982bcfbfde332b2c94cd08d16ebe20ef9813a58dda68d0b1423d943984a69e78d7e072192e0ea188ee08ad52435ab56f7c2e080013f7ed5ed386c8c48a4f2a4ebb8930cd298a71f05b0deeeabfa7982e5114f3370fc54891a979b6d68a61b2d4beb301d9af2e5e3b695f725ec93aedc3e15a418fb8504632d799a4a32bd49c346614ae294853622f82290b17ced0300e944cc15717fc674aed6cbaf669e631939393af2b1d1cfb9dd211a63110f319b674375d828cfb14c444f5366a07af873a2b0dc77ffb873dc10bb434e378ff415ddd9714759c64579a29ab5b9a8ecfd8b0ff45223f01da8fd10ee5338093eef31d10ac4d5b0f733bef8d622d5a5080927faadbd19f65e2b209c70f627c939a1cc8ae1416870a1a44fb7485411e8ffa22135dbca0776a53f49b53ec43f56c62188a68c0228b38fa231b7af90a0d941d5e746c9af6c4131173fa818d13fd4122cac68f04e02c0345b03dc7fac1d4c5fd3d346062836f9c7c913022ae7f80fe28375186b0269d535ce61d4e680b0dcb6ccfad96527b29d505a4b597a0d0fa624ab4b2888501d01ac7edd03ecff2001e8fe6b01b0f5ce62d64c27bf1aee7f91278d8c18dca8f6ecfe8a5748a5782d77002d25bf57828d9c70815c7103637445d857095f8164d0d2458724bc4bc417b7cdadfae2b07993012dc277b8336a670fbb92114f25d2fbee18032b10c3d76da1ed7788646eed753b665671885bf31359e2a3d792f28a08a7ad75f9aa24d2f007142cc3eeb4b517505bd4004f0526ca843caec9d449759c1423cab7c97247e9cb063de100febb5b26b9eca5d753849f1bb75171c3d1cf113d69029e94ee71b8b5a1c749f44c5a590ee0b1d73dbd5cbef4e08b766975899e37626edc67cd5d9a9075cf49ff04753c72959d199e37b987472b6be2bdeda3996b233bf708d20b5558f93fd2bdebd233b1b34ed72d4e66296c9468e6f8dde38c008a35a87d274d7c4c2dde1000ee499fba5ff8e57155513c1a79e7678a50a71bc3a1933d32a1de1e4695f739a9277969220676ebfc2be8f80385a8a5cf58d6bb108d74d741584f9b58d73f3779fa92726fe9beb6557b1ba278f4e16c4e1c77256a968d8a19f5f6d4bd3b22145957961544cb88ee0f14e053ed337896cfce85a40f8ceb343eaf873fbdd06cc730c18bf754498152cc6f556e3a41630d9b0463a2ee19a23a382126669c713608abcae2092f48216cfbe038b6207cf752b2ab00c57b11dc37ecd0587ee82380af6e1e20320760e8b49279dc53b0434053b56e77a502268804efb01761b85ffd443967c152a01841773b0e463beddf27306d084274b4fd9b634f9b2b5a05851ea06ce747718a5e039279f227c6e82467480d9436eed512651465f9c66cccdbe8729d6814a88131fd9c1843b143e672eeaf2aca0136876f8b8b3a470198f09deeb3e0b21d03e255244696a85f2522e0148fdca52ee4a667db16d0b46d57b46e3bdbdf76c9fe6401bb3d886c26e8a549edc2e44382e20787fe84a2c06c95a433b2cd662bdabd83ac268910f57ac7bb10355e8682568f5b5276fbe1500bc1a6cec52f20b3aba12c3404f738909d1fa40d2dc804012f75fe204b07844c171132aae57bdd38fc3811ebfed9d9e04078f84b2b5e2e83e8609d10c376f528a805c0f36b004ed9ddcc359a2c0f19451d58ebfd97159ef35ba7b03147aef84e35222594a83655ccd8c7bfc17fda5a07621d1ba06bf9e5e66f663737542304fad035904a41a48ae478a7544a922ae249d5b470597754e2019803e0abb127d1273d2a968e69291f40d3e04fbcec16e3ff8324c86e62407c6bff44ac0502e27647ee1b17a5c187e40956be73231d029df7f7876da68fc432e79b74cf5e8bc99e4076f03dc93f1da25c91c0f7667fa2fe1d3333b9944b4a7db5c7e1f72720873dbb1fcb777693b011b4d207c6449aaf0e382ff41d81a1d1e0641300a1c50a5af5b8ec79091acd2bca9daa40a2aab1e318e0e44eb329c6edac035c0d81dbe44688aafb0c12843532c171c4a0c7b107750a85749e9ee8bc474f2b6cdce8b37092c9d7ddd86caa85f17ec44bc5c9ae2e2db44db2c37021ee88eab06804657771d1cd233c96728acb47ae741c466a1e37f9c0af62013b5f300436d11f4201b70b35da32d98fc8a024a673ce1a26bf86681883818786876db8dba0a6f6633fe7532d20966663d82930b2622c6159a39933addb8f5f6d575d521048757dbaf89e631e122d4c76cb5a4d9906fe036e8ff7e06e82a6f506e44da86a30877b1364758e34982a7149e844705e2964e24e8c1da13d2955bf89231dc2e1564805c6c1ab32767f15daf9658e142aa43d83110a832fa752b80ef5bf6c8e7f2bba70043750d1ce4dac3b36938fb3d3fcd5c74352a0dd597b695d2c25bb5f57a00b6cae80fd3f94e176f2f867b15b01154a1d3efd49c77b05866e0fb779057ce0a1bc5d01eed9be745d019115a8730520c0630192411fdd668096f248375196ccd939da3af20a814b4cc3f518309124ea48cebccc989b710d70bb2c00600916b8c42abef6397ab42e1e1b805fd1a466ed841f69c7f3976b165e4263054c28291c135634f826808565b40e34e6446c8d8a98a73864ffb68f1370718f2d52417b2e49c9bf4f8223d8693e3b8feffa5e33645f2782cf7c451f1f9b68aeca0cfd9d1824146cacbbb7877343be4d797d8bdb5ea08f497b9e2e7951106ed9e690a9c7d3114aabccf12282d5d6a1dddd0efc75e724c47ada243414192e9b690d4cbdd919ee658c87673782044713a855eff112f761a1cfa38228dc0a4647fd45be191dc579a0ba0202338b15cbe2c54f8ddee6ee0a6a661e7b5bc800ed09388b462e1d6c73cc32efec6ce3697482ea5dfe475d7b19b8e9058f0dc37840bcdb2e3685aac6b84b3105c7e36a936f4f6c16682a1c76351834d1cbb902e22c13991336d44a719be6b2fea603596fb30f2e23f59e5ded509dabec1d8b2b2ae151da5841c34c104abd27450df0a07c56590291a0706506542d3a575b96f618440381a6d96df26bf5572f27cc3784c0c377f35d4828042fd042d2deca089ddd8208dd27ea6f7e16918fab1b56b4a326a7744a46493951c62885ea581740da1a7dea72c3d9a2a8d41553f2935786d59166a31e41a2b4d0ae58bb644367e6ab64e808055697012ec54045b6e4da73d4c1c672c116428303365cb6a2863aa0c2521a1f5910c8c29cf8905290907e70aae4fe71073bdc07f5b64de5b06101477a3e700238f840504b6f830ebdeaba75be0b861a329bb26e212cd4212cac1b74b4b292946d0d7d24147995bc0781dcd862c773a31ae7fb2bf6a5759a5b1b3ec91eadce702e758a98d639fb0e82d6e82f2344d8b963d9a6fdd426016ae629e188ed165dfa4644333465a62ffd96e229c277edb1bf2263dd0212704c29621b626b0c45e859a40b7a48380da3d744ae057666720cbee01fa39e25042f6daeac3529dd5fdd2fdb7ea155d502bd961c884e57b0edda9d3008c6114f6f4674cf9fa2066dec36d393883121eeb48d22dc3ea3f16e6f0a58278ca25cbdc388bc5050debed58688c2b941dcb88e098eb4b0a368c2ef55f990167e655111b20fd3b90e929b494c48b0eb1e2463e2142fea6d648b81c34c91271f03a5f3ddca38851941f889871c2f99a7a0546368a0b4016e766ffc0d7e8fa97a306ec9f2c19c6042948279f5e79a37ad816ad60f992303d397a54ded9a683391eebc6ef48ab72e1cd0997de295851daec83d412080d2d1eca0a7e3d6c54ceda8333f7415c7e726b4c562c6299a19c724e495c66c0bf6a218cee636053a506089f57dda90ea1e93ea8046b1b001321930491037431d1cbec602e32670b3bd1b59e921e43184bd690e4071e9bbd386c6e6bb8c84e5b51b1cd55e4bcc16099406859a4f5a1239b2fbb1dc94123716a20353709a6081c16c7ff6c74bc55308fd9bb710c4318671bd2dde70dd1b02f97c5cbc61c15822ed31c486a2ebe2b72ced4aca72be419260722d226cd7754a084fde6efeb8a46df3324be4abf9b58044a090590c9f350e747412a4c7217855d77c77f4faaf36ca1b948a29034aa42e4e21c1badf9eb283527d74587e5caa7f340fc9d92598804ea9483ffd3d3ada9491a3f9b210940e6e3e50d9347c72079a92cc932f695b5cb059db08d2d0a9e95b85c461b23b80725362073946959a0911d8160a3831a4026616f114ed6981919a1f8c83254734b425d203a4d8c364c90ca1e8af8afb9e2a9cfa337330404b9cff185e013c001a2a2ffe1d72ea4deb0aab34348844fdf6214b6c450ae4973b3a0434eb27ed6f6fa90652b1210bfc55a37c217613beecec5802ffd91909f28e4323301410e1681cfe8d96db7c44930d6515641e26e54127198d1c8a771c3d46a9b503d9dfbda570a6d57d53e2274848377a6c548392851c44d0dc04066e8d3959754c9a02b3c320dc8287eda140729528d6b5787a2b479c98df32472b2a14dc91551fa05edf17eea63ace6d8fe31de4fd7d82de632735ec60406ac1e616c9e258bd36921152d23c421ff86805e1203d92bef3d130e3e5e4cc1cb3c659f2445c65ba0b42b0062c4c88b155a53cedecfbf26f207b073aa35b6169fd7a375357221026ef9a68652b49cc44db7967a6495dd3e1ef39e93d98af63b0d85547ca457f88843bc2fc6d6abe863eb9611e74755103e57ab0880d35d2a8c60cc77ad2f78efee3702a26f688f9ef612490582e0c2521658e3f083607acfc0c363dfe884701fab599f21565cfe8a44986d7004f0f38e104f51fb59acae9209aa83c60a44a70e3c7a0c54c74486ea1086b1d37822db2161c9c3b3988bec376fa3ca2a66143efd70803d8c2e625cb11358bf348c1062b5f9521b48abfd5b451ee66a7291c4a77e85716f63302117b7ad8ff7fc052ccc35b0d1d70cd0ea95f45c1383e6f15b9218736c8b9822c2797283589f91a243220e6b9af52dca0ec1ddf4ae83e0f18d42f4032b7c53e5dc1afb111b46a2f6d8dc81cc6812e2c0f0a291e3f5af73befc8393e568977401b16839591c3972d0e5591e70e42c7e369c5b30ed7919ea95f2dbaf2a878733c553b6f5496ef7d736a5fb1655770d9c4d49cca9979619ec76d26415fce08323a04d4c4034ab9fa8d5c30522ae21c66eacaa41d3ec342d1cee6c5e93b6351e23c2aa6451cf2738af12b5754a61cbe9b6399b683b88b0eaac4aa16ce31702ae61e832072b2ab5e09a401542005e0bcc380e7341a22817ef7bbdffeb7caf7d29295dd5bca2465cf085f08cd08dbb6adfc4df82b651126f855ca22ae92dcdef4ac0f1f9737e0b7ca2264496e25d9953d4ccffa9bd3affef42b50f42b2dfea8f3abf4e851fafb9226594dda8421f8a96a9e4cdbbdf7de7befbdf7724e32e2a77b191862d086a8929ffea402c5d5188a58a67bef088f2e1ee1d1f5c1600d517f423da84f20787ad4e955ba9a4ebaeac1f791fab0c4697deac11287c94deb538f43beeaa989b7a7e295858ffa1d5d64fb747b083685b2c517bb6e1b20403c6af8b161101576db6f44b6c725892d06c3aeebbaef706983429d6eb091b17ef55e49f6205ff53fc852f53f5a65eab18d215fe5f18355743df937ae27cb224cbc2fd2ba71bd4a5984c4b7a5f12635b5b06b5233c51abd497f3f6ad2abb4e8535a7cf0c312dd27d26ff947a21769bc0486a26894491f353f544ee72212fc7cbe5ab1bc1a8e57a4f2f681d81811f9f66b0cf5f6cfaae32dc05f16c80f7f0529e1b9ec0f0bfb56daf4acab6da066ea553435ab6843155d2ed1bb7ee412a9e86ab69e64b9c0a7224bcb58effa7a6b054d1092590b9e2f3c6a00baf7de560b1cbf0ab3ef2a6dfb2c8c41d2132180bad8f7f44a27a0c2ecb378b0ed8ffbdffd8ffbfe9b40dddb935e692393adbef532d6938f6dccea41f0413af35e54de25f3decbcbdee8adeeee68b03bccf8a9e89537607fe96fa5c90f5f2fb6d243ae1a8be52a49f0575ee559e54a492d4ca524c15771fdea7da894d4c258ef2a574f633f7d03050d60f7f79537c490461a695c6ab2bc15eb6f7939ddd2a427757e9636fd4a975ea5c547e9d353b1078d73a4cd6824fa515393ee166b14ff64fa52aa948d5ea4a979038885d91f695b32893feecbcfe7a61d54fcb23bfe916c8215dbd5cac791957a7b7a4b7a5b97a83e89bf6c2dab8ebf38d1726f7df5e3b3345dfda7c7cf31c1b721c704cb223966112637e383bffa1b2326581679801150ce0882a5ab29537deaa9487632f03f9dca02cbd92f622d101b5383500dd4c5722ef098a930fb9f8662db0765aac876fc8b84bad8af19a830fb60edc0b6b8ac3ad4c5be8e1f72158970cf3d2ef163b22b6d56abf12790b3af8d4c867ad5cb4e9ffad7c13a3a7446a4c11ff5f72d0491ad259ff53fc8925a18ab24b91fd4c2ba92ec0182e37f8fb32adfc7c75173d32a2d7e4a878fd2a33f794fd2f9a9d863236d40f07bd3e96aba4b6003740575685fb42fb239311d0bb3417250914d399ce711809445c6e47bd9916c9efe083677a869984ceccb745eccd31fc9e6f8fe2b1b1ba352a54ad23da559fade7b6f9423669bea60d32824e0c11ec7953f65366b6ca9544f9f3e0df8c213f9fedfcfc1c6847f457f5b7fc9bfb7fee090c3107fd57c7327db53d1e6f4294dfaaf9e9a2c4dfab39e9add100beb5c933d4ecf7a1fa767a51e67e54fef23f5ab1247e5530fd6d06a1ba8291b5ff5afa9397ea8555fc51ad286f536509355e230b151fd88865924c754fdeb2a12591fbe8fd58b258ecaaf3e2c7198dca8fcea71569ef5f8a968c11c4359c6fad4935d176382500e3222eead4af6dd1cc8fd065c7777e771ffde0b74e3f54b5961f7539a561ca70afb3e4b7f15d9df897023986328fbdf405d4e9a4885dd1fb5ecc89bb4b6708af6496b384e6ac6be5f39e4874c848a37ecd0a47dd69f5e4593f6592f3cc9fe4e7aa5cda8bac146e6fad6e392ecfec7e959ff23f5abb79aecca1eac3ffdcdea530f9a3435a9b97269d2b7747e94069fd4a567e9d1afb4e8472dbe4a87bf9136e2d37de3a14b53b3a5a9496a6a9a743537b38a3536321ec02f3da7eb4e69aa7362e689f479f42293a6660d3a070bbb224ded2d5d6a664d4d50e7c4ae0d0f7fddfb39a8c8a99cce4945c4b67dd0cff17e77394eb43d8d6d598ac8568a6ddf52874163fb8d09c194c86106202020dc715bc76db8e50433d0198c813210101090e3171ff259970ccd5073d8b7b0346e4b114ab625436011e4d79f21a35ced148496315ab06d092bc771b025e01d1e2d337bc2451745851ef249693c47d41cf68c3a7b228a9fee87967fce102a438c2f82904f4aab35c74be8cfb03f3f3f3f341a8d96c38f8df96193846c7faecdcbdd9dfe20f33c8e81cedca0918b2fc4e83ada5129f2597fb810a2fdfcd8d068b413159466ada59ff378395f4a27de5b1e5f7be3bea4497624d2d8d3f7f1cbbe0f5eb1c672da37b71a6f91b631e0e560b73de8baa1ce887c56da0c627c316bf2525b52e03f16f0a34289d5f2b540368846a3d5a604d162b4582d4693d171af4cdda129f17363b19d25625c994ba3d1683e55c76363f622084d6687c60120aa15b158ec49a6d18468343168432706562b004f3be6962787f99b66a0c8e7b7f89be80cadbf6d19e2296a500d1264c85954d8419030a613662cf3b2fd90e15e5e4a90cfdcea5a8630cec1025409b52038087551e1897cbecc80784023ececec743b3b4178d02c9177762a2c0356c67d852eec0a1d18a1e8b2d85c5073cc86b8bbabf0817cd29990aea3e9b4c8f6719767b01ff2496778b6e3b58e80b14f121856453eab0fc6e38ac4186358149866b10f4067ae6b81afc330f649024bf1c138c803c208fa817fb4cc826640b4cdc7c707fbf8dccde76e78852b847ef8f8f8f8f878f8655f403f0b0ac237e44a23006168d45e3ce30a4b6a2d4b5a98f0ac0a56ac20443e6bcd9d48a1f1f1e159b2f323282808e6c513774fa284886e85188689e0bbe1a9c5e2bd94a0022d9fb5567ba2eab87b31e35ad8f02a9c8a4d848f129e24b29d181928acf6c0ea900337a33a19db9f560fc2f6f969326b804d8f2b6634342be8ccec8e5d02735a1e51f4c58c3e26bf931e0c5b0eab342ff00b577881cf8f5a2d282868851d68e80cae897efc30221371848f8f4d90d050adc5f193a0a1a0a0a0a0a01c6035b03a3548e1e20b1fa059932120a956ab79b55aad56abd56ab010e03cfeab041b6246b3535b12e3a9f9d47e6a9e5723c36b89413e6b6d16f4fd08598ea822a33caf4606c64630a8b3b384c7e747e394e75532bc1617e4b3d6747696f0f8fca4543f0278b2c20ec2ea793a1918c725f259755e66403a3aaf03bec8d8d068b41950e815711bbccc42513402d2a93aa3cfb39ea793010fa6249f55c789973146148dde65f06bb49122c4c5d0db174b737d7c015dcff354c8229f5547e77e79b4dfe91b3bd430c8f6290f8771ca63dfae80c63e0fe7b6ebfaccf97b6b3081edf3f8f2a18cf16407c006f97c198305dbfe8d976d5feabd3c5e64689c161bdb1799d7cbbfc61f2dde82e04d4803f017360b3004431d43c2100471563e0c9f82616be544ba1e54a14a2f546b1ef31d51144552a5a5c2faf079583da87231e62e796f0b41e4cd8e2f43bd0abf15710cb71044b642e88cf7f62340632a931618a13a71465582ba78eb5dff837c95afa2cd4ad5a9344bad7d57922ac37f561968c51a9b128749479638ab07c3efae49480deafcf483c310c101870f7af81b29a02990f72d5b31e09f46ef67b6c4a70950921d1d1d2efcb61c7b8ceac34f69f055a7d38fba9aaaea539bfc7c9f09f5a9b2ac4bc21c43997bdfd145b63f656cd9f1765dd7d92755bb30a36306875deeb9aa57d4c5be6b56add17216878d5d67d2791b998c5ad8f6b2dac90491bb3f47204184388cf5702bcffab35b082277636be7c79194b3b9c808be2ad54aa522ad56acaf641ac1132a157221177221277e4987de8f2bd57f7ab57af055abd397687ca565ab0737df366ee3dcddddb9ed5615b8c29846f574df5c9a5b55ab1f34feeaba720769a352ad567ad42a2d3395a51224696a927435ef0d20a51cce451a5c6f3b9d4cd5640af3e904aebe146934ba77c443354b3ff221816f1a8d4e3f7ad368a5ab49d2a6fff4898a3544b827f14a5313ac32d387bfa38b7cefbdb7b3db29346d2793ed4a1bd3d34d3bd0a2f4f7294db2baee92ae26d7039573380f9958efaa58eb7a6a5a94abc4717debc956eb71561e55924e4d6fa16a319d2139a8a89c4af7df85b2faede76063c0d42ab42acbb2266b6dcd3977525b4ffaa39e9a274dfad6d243366b6deb4fefa3f5a7128709cecab7de07f9a812c7f5e4839aecb1f2a8f7e1fad3bb58136a9507f57f15ab48f65879d4ff70fde9b5ea539c8a96a1beb591dbc6596badb5d65a6bedc6016980b5d65a6bb96bad7dd43f2ec9eeafb5f655ac1d52e33895b7819a2a25d93dea554e8fb35292ddab7c6be5574a1cb287cab7fe46a524bba726ea5bef2ac9ae2472c300ea265283dfc6f5a457923e50af52e23079d4fb38bdcaab50f3f4e49f9e9aac57bd6cf5a9e76a186261f6b9eb2f0e6f77bb39586bc79cce4b3918994a36efbd05df8a3f7a8107b94a899d6a2c464dd49f5488890d24d37b9af47da4ffdef4a54e26d2a3bcaf7a5f0d027e8ef9bdf737df7b5fdff31e2c8be4f7bc2f52facffc7696c474aaf7c576ea92988e0c9d7123d4c5ea5061f64ba5efab31176b5c2439b05e23b1588d81f6f31efca6747513b9bfbd898a2457da7c9f772a65e183319e1bcbd58736b97a93892fa4e6f8def437df9bca224cb62f52fa7e2b6fbc279545320ff87bef3f6ae2586c94b3b9c808da07cafc07690df9fe06fceffdbfef5b6511d67f25e945c807c1cf3169411f48ab4275881644ad4bc686c4a29d8250aa95c77cc7a5589adba70df915426b994293666203354faeff40107c17784a3daa7399645c98a93175090f143e35180a9acd9cd0a4d066416c4c55a22aa1c490124a709707ea628f7cc0c7079e2a93d1195c058d26e3304274d021d7f6e3a75ea67ad4832ebdf22dadf2e489a305d1996e5b5ca7e49883bff23720f7454c0f3e57de7caf521639fd077e4b7f4f561365da4e61497bb4bca3175f26fa10044b5a4890d0506d0a6d48107fd9211ae7a52644926c9158f9b3aba522a990ab1571455c11574452a3be75f5afacac3c6925bfcabb4859d4d2b2d6af7cdf27fa442272a5258a5e94c996288ae28b347e555ed67a57f79de8bdfcafc8785ef6464f14fd87c9ef1361d17fa2f28222a9499114c59626f5cacab75aad959214bdfeff96fe9214fd7feb57c8921495648f9527dfc7b77e857c1a2b8a5787dfbae2bdd46c91dfe3fd3d486f905ff92233443e5f9cc8648b53d1a677e9d2b734ea497dfa951e51b1078d9348f9591c355d9a9aabd1a79e8a63a9caa492e9844a8d46a19fa8b0a973dcaad2265582e2fb50bda8c471bdca85b34271c6f8734c9b7ad5fbab542f9645fe55aa2f9263be7e59987d5216d9edbbfd5a53e5d207b1b0d493cab7e2f896f5b6f51ef31df24fe7f11f2f634aadf9abe6d7c97526f7499abcffeffaacc9fb2abf5265ae67db3e978241ff49a78035d49a890da548ab5ed429515489a92f7535c12af6a02269a352a59ec6353753dfbe0d35a636a9315b6c5bbfa8b55a46ad552177f7274f624f62f5497df2d51250978a44859d95091470653da21ec1d119fcf67bd0983a86e7ed1aadf6fd0eead238a917ff358ef8a95fd138ff2bafa27154def55793f8bdbf360e53657713b9db45ee3f6d239391bf7a19ebc77fcde426f5e2af681cd58b5e4533b9113ff52e8d237ad57bda87ea458f750fd58bfe6a1fa9179fa588ec3bf6eb143a633d666f57cd31fc9636917ea5f38f7af49dacf4f965a41fa9e8beb9a48d48243e58c5f04d8f2a3de96d6cfb8ef3f8cfb661adeac46a6dc754399ea37af8b91e86ad939323e842954255ca54eb15b178f115b178b1e85d5afcb1f5a026c390fcf05be1e86a91221631c618d750bcb886e0c5bf83de80fffe254276a54d8bfccd46264bbdea65a8773d0ba1b6f13273cb1682c8ddb77efc1fe4afbed3beab68c3b2bf1a731499a5e5a4c6593df82d8dc3c47b1cd6870fdad0c91ee3abfe667c5511d68f8fcb1bd5bbca22ab573d8d8fefd2aa6fe9f0497dc30adf2b6f567f35dee069d4a2cfa6ed346a6a9a4aa1281a65d267ed29a7f3910fd77b59b85257566476aad57af2defb43547f4b7fc32bbae345dd7aaf1256ffb0b0abb2f2a06e8561ebc35f0955441a87c90df9abc7713d8becde876985575a2b5ab6f2adefbcebb67befbdf7de6e731e35dcdb6a6d9c37de6fdd5fc1b8f5160141eeafdcfbf5c7dddedbdec3a5cdca4aeb2790b3ad0dd9fd0fd3b3fec7e9570fb634b97deb73cc154d6ee56fdb83aff239a6477a1ebef7de7baf87b7971b5b9516c6b67f65868e40053e210145f403089da1dbddddcbd34c05c0b64700c18e4196cf90e505c5085ecc6c0f4fefa48cd9a650caf8d92728825dbf65532865c8409e5d47967cc24159e86ecc8534669b59587dfc4361f5e90b75a1255cf8cb856c992304f98c8008826828f160df5fc1147f7990d94526bb0777cc5cc8b920e1207fd0d5a4fd6d6663700a28acbe0b809ea0ed8aa9089ad9186a026d5a10fea12e35f4d7fd823ca64a99d5ff84c4f8a6803287a1508a4004cf57db95a582b15df709eaec6a9ea0e549e2b3f3a3a4891043ecfad541b0ebd7fad5b3d8f5eb26dbf5eb36835dbf7665ecfa152f8197c05e8495054ef03ce1e1e20b3176e5c1ae67ec9ceb7f7e6fca17c33f41bb7e5786c3745370ac9bd24dc131ac8377ba2998a736a93cdb0c5e685e66dee39fcd35d980f6b664d3d976361d1d1b43cd9d253ce7a6b3fd64d1f3ed1b8f995f9980253235bf076261f51310c5c7f7b8246df07b365f497acd0cda4df08f85d5e7b131b88985d5ff19f38f423ca1fbfc3499ed8a7f4842f9eb6fb4fa5b50fd6db6018160080eb521e88cbf047c6667b1d8b62599431121e88c7d0908a15fec5b236b4cf6c5764dbfd831253a49747c674789277118b22ed99508fcb3ebe3597d0c541fffe026bee36e07793a5f11e35940d3ce23a7bd8985f9ecc55fc6ff5fd67d3f4c503eff9214c004cfb62914327a767d13c6c8d6ee00525af7d3df618e91247cd0430f784082911898259f34900809c107da0b4cfa7904e953168a82bdc1d0af343ec43f0720fe2c45643af36dff2099e78abad382c449359293d04281a0eb96a106fd2b36b5013d63b683d42b19b124676c7fea7506850c10f807458a18fba453c848b2ab8ea537b017db8546510cf1cfc11f4810ff05e4888244672add5c919beef1e3b2080f9b63face76c7252db1266fbae7be2b31dd4a6a85bc1ef03e65d13490767dba7d7dabc9adb4c95164210de840156bf2693b6ddc0876d8bb9e75af5296e8ccd9b8d63863d3dfa66caab9aeeb42d73460609f17f05adc07561004bdcfb5a9247bd9a2e2d8f2d7d8cadbcd39e72c9adcdfddc3954530606270e6515c6b50167fd10fc59ad70ebc6fa869882f37462f37b694e81c228a44a351e8bac64ba66bdd544db4139d378846a351a6389348e20e6ee3dc422ab5584f55ba894e1c4aa16b9358e327b03c856cf6ddddddabeb969a971d1615ba4ea5c4eb2faa123175a1b0ed221d807e92d944444f0487718b8f43de4f5d68e6b38c9f3e0f9bd2a39efe283f25dd073d148120289251a95836667c27574f526d293628da28d3a62915641a9ba640dbd2544d8ca6700591cf4c831692c867489d9450a79d52b8691a8506364da11855b51f127a2446bf69fa843f71292850df0d34a34f6c144983c5c01ed90da2c24dd3d90efade4b20ea47a81b222bde7003b9aff330f6ba8f23c9b66bca8e64d324a3dd1c22e96a7ea517e98414b675c27232696b9a4c2693c8f1e924732a6574cfe949da94023ded1be3133e390c44799a080e78535aa3b6b0e91846950b27c8678641a5fa9a28f2995fd8b48e124a09f9ccad70d33976d53da887a2d61c750b2bbe91a6db87ac8d512c8dff048db1b6c4c2b63f73a10a17b6498f3c13f8a21a572c9215ba5aaef0c31185d26ea24c96b280a254d8605b205d9a108a9abecc489a9a2826f54d2f7e2fd53492cf16a52c90faa585232369bd2ce24a5a6bb8c24dc79c78360d33a2209f79db151cbbea9e71cc98d3e1a66fd45a5fd460dda0095e9b62614e9b35f9d13e445dfc47da81405d82506b88a1e3338a91efa66d945030182943110b3226537dff51a88e95251cb2350b73fb12f4b24390cf7c42b8e91aa3aa060428849b06c0b621440ae1a65db67d1189083efa1571af70d32db070d32bd02ccc3f28068a0ae1a65598690216443eb34bb8e9d7f674cfeaabee195fa4fa4ff5a2eac395ea495ac6c658290ef3e762bb4aafb497e1b0270ef32fb913ce0287f9a86bb00040b8e9144c26d9076a22e0487c0783ce84efef3ea83944efee797481a6d171882cedd33dabcfba6754a956792c55b2236f8a81c385405f58c2c6219a4aa21b6cfba2a883cd12002c0f30c06cfba768b76ceb3b44fb2bc19252979770d328ac108a27ecb07b4c0f9ab457d3a48f60d2662164d93543c867c842b86913361eea41a150b26a1ec1e650cf6861d68237c291de401ce1485fd4485b544c38d2fe89aaaf2da84c28130cadaf93d660db77283ed8ae0a65c2510985fb16367c565d0847659935ad35502d849bd62554eb891be16ef9209f1926dcf4ca0094c4849b5671ede09aa106f90c5bdbd33de357dda37a94b640dace2ccc47150c3ff9cc32e1a64914f85272a5a88590d3e28d90d3218e90d3204cc8e9efe4d1421d21a7311843678221e4341743c8e98d26e4f495c1ce108a34dd9c7614ca816408395db788b545221de1a657bb0c011491cf108670d3e31e69f08570d32a17acc8678e21dc740a65d2560987f9114244042949120014e433a409377d1a92a19936a8cd70d325130ff9cc249d1d48cc90d33da70f4fa4d4bf1cf96ad2bc4119c24d8fb6c90ad1d988e202106e5ab4dfd33da827699f596b33b823dcb4b83ddd53faaa7b507fd236a54ddafa5898d72c495b9fd99d2c73443e330de1a6c33d7a91a600a640dea3173505c63d7a9f59303c857ac882e0f6740fea41ed432ed23d9fe945d387a8d2cb70983fb77b4ca58be130ff018091cf5000e1a6bf2dd23da8ff748f0e36512fea1e9d6ca23ed43d3aa3897a4edf60d1e861f7c84a7f049ba8f71ad4181f3a391574e6733484b26fb1dd6b569434c742496fa55289b270525a8902a1b1a198d9b6a4af95a1b6fd232f26a52c9c2a1c27a9a42b0b4746933a8ef3e443a832db5a1bdb7ea947e74dd37bbac754520beb31fd49ebbc692a3bea52ddc49a6e120c2fe8c83113830b323130386eb460838517026c116c77e549818da98b7dba4933fbd2196a83ed2118f3977d1a67b9229f78b380443e710d0b49e4d387ac7fa6f6476a9f524cc19c91d723bea8986292025a2054f767fbf242a5cc80895dcb33739b42a1c3947dbe6cfa3c2c0ffb425f86d2a00029b5b1836c377d110dbe81cdbdefd84351d017dd94be48f0bf07dfc51d7707325f8c4e1220cca65f03458843bcb1e9d798216a61d33f216103872c6cfa2516e4f392fc65d34f01887cde528d4dff240213009c8c31c8e73db900a1200545df05456a854d3f00618cac92abb0e9d78edbdb8e1bb4e00dadb69de8ccd923ec14c5eac5334311ac1496d40c418694cea0b0e9db58924f0cb6664ed8f451d0808b85ce98b069cc0d564aa019265e6ffa307c209f583fad464ab94263a9e5f39a904f63eb5954367d147c58c2776df0de136eb436fd1a21e4f3a2404e39924f9c02eb090a4ce4f3be56b4196c9cd2026346f5301d3a6edc686969adf04a6dfa3300e513b7a06a302ce16271b60140020014a4a8115ec7613e8dadd2a6df42065e424a67489bba0c19f9bc2ce44ddf852a6c8c5a0800931b3251f2897765254005f95b456498568e92cf1bf3d14c32199cf338febf76f4e0820c09666a76c8e7cd11621b832d4c870dda0b28288121c416e73cb27491fd63b0e589e39e0211f58993168cb1df6a5f5e5e5a5c5c5a70bcb0a568b9d5e230c41ec618e3eae9b8e1b873a2e3460bcb092e38aa7dbdee09d405c70b356f85b7da9c45aa05f5e20420845e735c7b29ed296db4f15badcd8d4d0f1b4aa3b49896fc6219235f7f7d62cda5dd6a5bc21787a92e7486923c923e5b3e952a401a6c70449fd8e0883a8972c64fb536603c8ea55f18778cc7b174eb96524a8557e15a6c0aa3ffe388b1ded65af71cf4ddab596bfc89f138969b3ec6d5860972bdd4dddd7df444757b37ee729dbd30ba7aa42af69ff8cb127b66cd517f9cb14155d8b4744a536b78698590ebff9ecd687ea3628dff578dafab798bcff8be5e281b29ed44b1497c760b5514252258d558adb53a4f7dd1847db6b6f8748c2dfe75181c5b148140628b409cf1740b1e7c30e38a58cc0cc113f817043b10db6007ac88c201167cdf7b62cde76981bf136bb08e283b5fc3dd1b6c7ab6f60bfb64d935f6b6f92082bdf920c6de7e70b281dacb458729626082d9cd960a27dbda24596cbb8120a22401e2452690e20825088543386664d34d1d0631e8d00adb1dc3a005d03ec30c44d9fe378a067870de00c852840e9d4981ced06daffe415d103094c6b6a27d3920b3c370b4af9d4666a12ef47bc867d5a9487438508530c222b1bd25d5cfe102cda10016c8d019faf985c2707fff0685e99e0c0aa3064062062d40ceb1736c1ae7f4d5175f1dfe6bfb3c6ef7810062163a63a9cb3d53d8f47f454fbc4fa078d3b72194eda61cb7552be4b5b9add4e76bc7176aaf0f7af5eaf5d6bf9b2b59a84bf51ed4a77ff674d9f7929b4c576f9075dcf8c18d6d05e7ad256885843b2472b79071e342bc41ec61cfb302a44176f777fbd3ffbccf6d5b496977edb6af9feedbbe5c89fd55f7a521dcfee7c659ebe58903fdd39e16fc321c9de707829b5be7c49a7b2f76ffcaedcd52079580f5abb93cefbdd76ed6564b29b5b7bbd75a1b725c48c51d1bfd7befc59c90a776eb6890f0d4dece626bad8dc11877f57b08d86badb520e7f9085d5765becd6ddbc66d9a017a4f61afbdd796334cc10410534cb16d75dfaf15f0b65a6bd7d55afe4c41ef0d9d00ab87e03ea9131d3232f6dbd65a6befcaf376a53114c86f1cbef1f252b35d87a177d722b4865ade4df3f097cfd0b2892f7ff9bf3accb1fc636f2b7d726b1cbdef9e321886d8c650bc6d0e38a433ec006263b8f2c6a36cd738c897d610fcbc300cc7f83ace73ec8e3b273269d32848bca821d1826b228b9b4641f2c403f9db340a12285ebc320a92263440f1c5350ba3355896479b4641e2234242ce9b4641b204c94ed77d1cc579689f2367048f3fc31f16dd0e3b9e130e703bd8084d926c321c89753f5c198c0c7146f80010b6b625a108c719877989c3288f0c329f3b763144d5418a0e5c645c06ed071b4464ea84c3a80c3c38c15908e771db348ace6c8f9ae8a8a5b45a0742ae8f4f212cbba5647919218f9b42c1010ec430f2331192914925089364d2a65070a0648603241d931c2e812b4206c9f854905539007fc8785328585c814f90459b42c1020c2c6660009d26f852a7b3a7ce032bf6dd344a0f44d8e738db92b015ecea87bddbbdf5b67aba1933915c6cad58e3de83a15863c110ac023cebaefb37e87fdaaf6ff5e8faa45196d064e3e07e1fe46e79adbb5f2dc06c6de528a594524a61f4fdad75bb5d777777774a29b561825b473069e49ac3d50f89ea76b5e94cfdea77032244125ad1078237ee76ded758d5a93b7549e75e8ec5286c073afe0b4667ead30c44ade1e5f5a291f193e3c6159da9b774ae67b430ef366aa40f76a21afb184f68e4e5f9e290b6b1502c163b62d2af6778cce8b0fa949e4e3bdd09df796fe230e1fbd37d3a113d80d1225382edf807fba4b45b67b1582c89e95f0ce14168a72aa944f0f860b17d80dfdd5621343a27f659a7602280b19f38411a4d7a40031fa680623ae0082578410ec230410f3a98b4c652d081098684d8410533d881b9c38c265400b18408664431cfda64fb130e98e10114d8e08c25606092a24832042b900405619eb546973084190e94249942889859c511469840820c50f063e47b7a9e9eecb3d5da27cbfe9ef2b0bfffbecf4bec2fca9125ecefbf072af6f79f58f3bd72a8b0c3f7c49ad05b3ad8e0833a586a39fa2b28bb931d849ac36810a6388ceed84be765476689c3e80e83c761749f14880720b6f7de77628d1753230b286226ce9deca7a6c33025a17d3725ec0d53189fc562eec40986c10d97096c18b4ed61158dc0b9569accbeb7d2b00248187146122d40c294169867ced9e9828b1154d1040f123d30ebc65f70419a413e595876d8c0b6dfc22b3708430734b4a842073d9b1324741051b20c63db67612386185762cdadf6b1163ae8b0ed8f628df51f2c4101aaaaae30b2c4b69f126b2c8e2892d882042368120616b708128461e405370002c3c43de8112aa1b0886db1ed9fc41a7b3a8ddb26b1a40919bc600b219ad831b37542821e27982801e3034bcc1b9e582c9601d35a6badb5178d6d2db8adb5d65a9358634b27ec3394b2cf56152ee898ed933e39a304dbcf18c2128058c20fd068b2fd5f281434c68092c6145162436c7f52f6c7461ce1ab30f92261db1f893516fb209fe18d7db6b6b7ec186a900432cc70419013660861bb129ad4b88c8c50127cd0b1fd45b1c683a690d1dafee1083cc05518f042f18935964ac1031142280207787e7e606e167b0ea44831451c6d0ccbc852030f96d7bd8fbdd834cab6dfc15006126080c2f6e740c0450ea3a7a8d4ad1734350b95a1110000000000a315002020100c874442e1709e26511aeb3d14800e6484447460409908c320ca61180521638c31040043083084cc0c518d06010e71625651d9212a2cbc410acf91ca7350a732bd86f4822cbead6a4c32b188baa3ced1f98b8ba531dc51457960a6af2ab1721f879515ef92ad607f2eb148802fde132642a2f588ed3d395191c8cdab2fdeae1487b7fea8b7e74e662548f0d056412f0290911195935bd422cc405567a0874fed7b9a2f74a1ab6cd159581e6ec118764edb00bf80bc60134246a8e1f01f91ce2886a2a39f6efcd95f42c1943cc542a02c0dda82a98e5221ecbb39218e8ce0aa9e739e4dcb6a4557778590f1b6dce98f469cc1002495aab91fb3ef615be7637ac299aca29e1c818adf114aa3826ad259515f23738a22f097917c645c3b1ade1976b1be93411d1a83c8750d0bb54f308c15768e7f9d123276b8cf66002680410e6a1db86d82168eda1f1fbcb393ef4f0dda5c4f5157fb947b81df3a38968f111c6ab2a173d0d5c7d9218adc08f6919a608e41fef269c8fffffe3a717b7bb92c6dcd1c1555b8b45147093fc09265aa287efff7d1a72ddee8d0d5512287561578fd5853a4092c9cb0f5d3a5f493269ab0bfb96b01412ea55b0d8fee73a8f44877921aac49e4af57c6af282d58f2f638fb5d959d8bb98b13b5f5877489f6f3cbfd57b646e94185e3e27014b7ff82719025d67af6ce92b552a760843bc576ab750bab4e1045e1b8fc75d82cfbb7b44368bde265bf29ddef0ea4c79c5bf7980389686085caffa0b125080a5847d81c2d2d5dd28f5d975c947b19a4ab04ad4f240488e5c1848220e7441b857c5bb50f669941b1c3da3ef74ce1a178eb5ff1d6c558bcd5c49d83e2a378592b27668716be7fb58dfdca6f310511f9fe21350bc7a144507e446830253281fe4f6f753a57938adb48d22e91167b5c42b950263cd807c54c9c2fd225ac0be8914083c5b09184adf7abb9a1ccbf8ab6c5c44e68bcf50965c4193e53c840ddd323983f9b28b36d78f94cccf7670f718ffa062103f84a8e245d07962aac0f850ed5ff30fb78e1e12e9b549a2b609f14c52daa0f4d5b7e9e127ac153306b85b67037e12d4a759ed3c31ae848ed4da17a5c03a83923aa220a808262dd23804613c9651d3c4df7d25c1502db1ba6938828dae52cf88424afbe5e3a73367a42719b74cd0b362895b8163a82ed52a475ae664e9e52fe471163cbf0168195f2751b5cab62d1abc940bc71e0558e0616609ba1844de5ba00cb26e9f8b3920fe0ee96413636d673054dc8f09edc26838dc3aba55dd362b81b493b7e525c441a24aefb4a6b50cc6f6318f866277a95293ccb653bab2c162ea30c66a0b955268f47172baf78a4a846cb82432c8b8b7d385122efbb96c2b96b6ae274fa8d9f51097c5a47460dcb5f9a00339a0c40136426dc875f227d91feae01aa7b77c4e03563b2ec8c43d93c96f4420f9c975b499483a1bcc704bae18194f25f234092ff465b2568b2c64541761732f22a6ce945a070b16f2878a5eb407dc9ac58b9b9361c0346d4eeeb6bd088f0c02484b702ff8f0b27b3516f1f0442b7e4000f3dfaafe40c16d5b28cc328ad9795501137fb49ab91a5b0dca5eeac41d775751b6b5733e3935bafe05ef11ac0913e7da15c14342f65c521bfe8e47d185d7930500952c97bf41c9b78045cced921fc71b27a305e4183accff3d21e2f21c8df02e930174f436e4b112da36a59301ae88949269fe84f6cb732501b96dcf04bfee2773508e694381d7ea099d4a78c24083ca007e4275abedec2020ae0c31b8a8854c8ad281015036ab6aafa0e2185c21f1ba9feb9771083a601e0602d0865d1000e0e3ec09da07fd1ae5e2e55eeb210ea0d1f628b0b29feea075bcf88def11cf7be8bfc5c7ac6f30dce2e91142c18394a2764e92a95de8198f319b89e2077a4ab170b22c98324dc7ad92b0002d5312e2beed51d55b5ef38ecbe54d83f97d08051428eb00eb5ff5ceebca23992c935d214286a65b3e6c62ca4fe148a0d857db7465e03726f18c8b2df01de56c207db5a67871a5539deb032d9f03e4e8bf4c6ba546e93c1697b12cc80e6ac30a767e88724a0ad83d3d8f3ba04afcd4d46d13e2995512142734466e578e1763415528da5c7872d343e438b410c10dd92fe234c851cf459aebf729ec13180091c1dcfb620f1e9d7157cb069a92d7920be82915d8ec13e39357b50f12543965796bcf04b92378a8459bb4190b42f83a08aca95651a44117b1040410bf4da86f1c7a9689d14e2fc416c3a5b3a328300852635e0a5763a97a84a47bddf0685ae3bbd52923b18df7051e772fa5be472e0c26d72556253cc56f2bfd09398eaa471df2aa854aed70278d4612ffa2063dd0866fc4534f8750d8836401aa7419347ebe5d0751ed012fc689f0a207895639651a72e2ae8a338f6815728c71b7a9f86566951aa45204b9bfc1b548981e4c02b4ba878e637b88b3c9c71d8137cf6f323aa21189f9de0b3dbbf2d493a025cbc9af3f6dc9a124a8d06b4527f8688f4c5ab96af9a498d9c17b8691a9403cae90dc406fc6fd4bf0d295211c78aaab6f7837920dce4d5d1382f17e078b98dbcb2d4b656ff7b405c9a6d47ec7b1f6044e2bcd69bef0182e215c9e1b5d5782b8800b5626dac2af14a34a11a88f2f24818d9e3699c16d35157465e8021226b1bc46b1ecf4127114d73cec603219b13d2ecfe5a33aa6d3d50c2d8378e705889f277455374090a3c38048f580f169c3338715c8e1de96347b05b9d25a24d7e631e907458f29e0a96d4123e0cb00c593dd20ebc1291ef24eaa958947093018a6295b08c2d67b58899c25f8e53147c48107dbe22bd0206efe9a0104436a1ce6c60d82ce8563a0d658373e94a1c58dce6c6b2f334c9ebc1798b96a5d2145c0040699b0216ff0849f8d46ad362f3c098300673f3e955767b942f2cbada3e0e111c5d7ea97356bcfd62263d33cfd6006f3d43c531a581a80a8ff7a6632906d0232a85b8870e3a1ddaa8bf714b1845d321c6be15871317436da252ec315b63abebec7f93d18bf730ed4477ddf8b75b7221303c5c1911b566209367b47234a61605b833e65a6ff12d7d3016eff6329cd1df512ace6e9f2ee1b56a9ff14db58c16c03d00b8474802b6133bf6c7bd909c1f0f57f00e269d2bc855968397942cfabfe8fb3314ff18a6da29ae431d257c3598d1d22f31ef939839144cd46ed687eddcb4f6b5c98a18f440579470b39ac148db66e2078d7b8fc18837e5572c8863e8d6e3dceac85f2e88d61bc0b998a58275717662fda713ec258da38e4bdcf1742c774922ea264fc1806bf38078943396ac6d50f28a46f4e4e27558c24c167a7c6c26a5ec7e0ecaf07d1bd1fcabc449734dd2222a8438767bd3b79a330f70883252865d800f3680d15b61be832f3678cf7284c8cc5770de159246b4df4ee671bf4da90cf6f3f5f9f54b85c83dfd6e9441c78fcada7dbd3c77f41631a9dfa523908018f2613996ee48b8239324701310ff8435b1a4f4541c9bbc161925e23c3b386a8d8cd2d4c6941a0f5614784df88be644b386e1c3927f599bd26359ad52e208862df0606ee94a5952c989064551c6c9a9b454d8c5dccb12136baad4019c3bb31a031cfba65533462a4ce8678bf12cfc55d3f299ca34cb12f2c9436c58d7a91c00bc945339c034e17bb82d33a307076d72baa47ca4b6613da031d4b6695146ea973ca8382e75dc1446ffc371345241b21333d8bbe2c37d43449ddd8a595a2669f0aaa352b2c94af7baf1e6aea425e67a543f178fe3eb08119ddd10decaee9d9f51261c91cafcc7fb69ca21c57dcadeac41e8380b250f38c87a94ae054319c57ab09239977221deada1bc94e75b9a38d314478c84cf24b8d9de1f0271d6acccd75cdf798fcc30566b523c656824b9adc0602d877fa9c4503b804796e188479c4236e5594a9b3be0e3e25643b1816ba766f24b990a5bc070dfc2f70f0da094dedda06ef5f33540fcb84164ab4a67a60394eb5dec82116680edf20339cd3389e1dfd06f50070f7e8982ea4cf6dbaeee897d03b8ef69aca09546bcaf16bd129414c2f3d0f27084a7fd2487f821559d0a407ee7861025cc40ebe8991629f1a12ac0e5bac90ca496661b90edd076aa0e984f4c2a35d405b1ef884be45b6f3d311df61d1c90155ca262aaa21fc77ce11facf1a6a781f74e6e21ac7c5075f381cd87d60f8ee8b4d5625ee9757dea787a1e829050f7b7ae7f28099824a7baf82b15b3476e0b775f0991ed86bfb962da7c9b8c1c42211b74f0c0136758633ccae2e9758fa035e2f506936ebc8d941a83b246fd7d2169ab95ba6435f997d6d4cd4e51e778354c19667fd79bfb9bb1b04c86d866b84756aa5419a306228ae5ad45019f7744ac23df8bc21eb9615f7062e49d73f5dedafc8b349511641747ba63b9c158e98049b265291bf89664ed6adfea1494d180446f2317bd3c9e91d9592ead4895065f764d211e47a8a42bf507c6c16f1803fac6973ab6d0706aab649a7ecbab1c202a2bef0e9f8ca858dd217d8222ee0a74098c6ad068e80badd29149c58953c509d2f1c01ae817aa279bdbcdd67f24aec72627f0f7a29873323f962eb6eb7aa4339e5e64670e5f37617c27acfeba579c5e11b20f57d743d5035f463b496b3a601b577c816717412dcf18410461e8b0dc05d0263be6d8d1fed71b8e8bef93ba0abb369655d95a0e1f11d6a109e0054fc4a315cdce2f20b3c03f636c001f3428cd9f997dd948dd5e59cf979b0c8e9e7523886a64a67bce9c7527a342708a6d7ca66cd02493690166c3873c62c92f18eda99700de23a6a1b214192691f15c07e561a57a748d39b59da38f33cc1ef3b50101cb8751834c8cc29d8f92828c7cba84dbc80cdd502f267e08deb6d91acc235a3cf7b4b511cfb678dd986e5ed08f436f4c1bfb734201779455fba149e78f11b484c58a89f6c4c2ce7b2c85af6d8344d8d82b145bb21f19d6d41dedea59aa9a72fc3743eddd6e740088bc6330bf49447ea6401f6ee5f1ca86895073d39df6cb31c06fedaf6290b844f685dc12f74aba365894a688cec70f25c4fcc35d72783c887f4382d383218435a568aefb4628fa02dda127f17d442377a95113d9d7d57317baef4ecd3d844592f7b2f5a95edbb413820457ddef5bf3e2ff3bb1d06a2a5305c927d22e74c8c372d7b6740adf7087eb42ea0a9b662c896e4cade00de6705d20de4bb37eb77210210a3a700ca7a6b24dd85dab399b7e13bf62b1dac54c53812cb56536c7c4396db8330e4225091ad5aa4661b6874983fb12520836eaa115d81c4d861d7bdb82ee3ff5e2394fb4627e536e4a8552bfd75ca0c272beb69a90807b46167a349263aff085ee68710e05817d196776d7e6e933d5540d26affcda1c472ebd96e5265a63476e3c10c60673fb6a9025f85ca69285d706582a4268ab4153acc38d2739b3b9e4f43eca5434f0f20bd1ba82a149a347b363a29847409de0d34d0c539a6353b4d96595548c5d0d443cb0656625476bfc875c272a26f30a3594611288e55bb934d7c5dc117fae098720818656eb005d166a684bf62fc1bdf8ffe6065fe9bce487ea122abaab8b1471970de90d161e176ae19389a5d246140059387cc8613b9144a47e37665371270155481c96440808ef7b6eb35402a867423d1003aeeb1c4d2942850170bc2c67180ba3135b647e99df2c57783192217b4562a85043860c29c1c9c68018518823d228f91708fe0d4547a20009df3c6da03c1f64f8958837431182bf34e1ab21957a3e2756b7745d19765687b201b2b65c82857bdfdb999f173e07a5648ca679f0c484c36329458b47cb52987e275ed55083dcc1bb9aeec762df29b19cac397d70bd17c21521c1b82aa0482a6345fae37cdbfaab3a77036baf82d9aac13a66f01627eeb8caebbfe3035f9fb57ed230e42570e75039cb1629a8d07430113ad15220399934c6314b3ea8c49837a4d7faab6575f92e9a5db068c73343051ac2289e3eb7cedddacea80a11a5d9ce207b19aff148f6755236c15cf7558c56119fe37388577c1b94e762be317b3222a82f3a4a1965ac290236ea829d5513cc66bb85424a98f258502585456c361dcba1e78c6f34735f8392425994042c2199fed0fe50e4050b8d511bfccfdcd19bcd1590f2492666388e3fca812d821d3a8ac15ff625c455cee30a32cb20ac6268a28d0128b1fcf2ea9b6b7f2cf10c1b0cf2c9bbb0cb577426c5158a535c6218c2cc2646ef58e4ed7b5c66574187ac1db7408ca00a68af5ae3633673c6824eae8d3ad41d5095ddabb2987fb6f7fae1eb8ac6828edb6da67388002786c77a965fcca8d5d36fe87c4d77c6d7c67f5acf4fc494513f46134170c662caf61b0535be0923a213abb34dc62e83bb4e3fcbc0619b908bbd58a100e365714bd2bd4ea0498c563f1e4599f484f1f0d62490a7803f9690739c4a6e93adef3065c69b86596699a94c563c2f71f5d3376e05f387d0c4f387da61c311c4817f0ab9562045853d5edfdf05fcc110bb2c95ad7c064ef952a2e5e32c2d3806b95a759108613d1147bb708667c85592226fd1ff9c36ed8c112e068138d8c167d842c8738ebc4b61e8b57c231b114c3629be0058fe4a6d927097d571482d22da2cbea02893a7fc00e9c93c6f96cdd2398c399fc294053a664312557e37f2a33a3fbe8dec595b13f041ce0c051b58614a12428b56df490508a4e791e896644a122cc52bae2d02468ed952f366271ef55ad673bd8c83fe59f541530dfc810b0e79f0cbb39d30884f7475f4f6491b8b8f4cdc7957a3920d0c5f4dbb8e42be054c0487513c064000024e52365b6fbb39a47b329cd6ad1742935370a8cecaa2670b5d340264219bff2c88def87cadb5b2090d4c68aad2ff4ed56016989331833e5a1041c02ccc3d94981d4def37ea8ffbe4c680eb044445ab51a9d54ea713c1605f2b067192d59a9c9f25d41f31a805bea11204af1ebad76eed6ad787a0d3aa99c780186bf413864aa7576fbf2254ddd399b62c29fa969423ac77e83d02d7efa83a034b06fb1ed92c492c95d1bb079ffbc681ae7a8c482c4669d8aa475ffa88168213bd023257bde122297e065009591a1dd0f8ff19ecb94d4ca322d27c1ee34ee86ed0ec8a31b2afd59d7624903903c1bb6a41cc7d92142c48eb9045cbc53a01373688c8093bf117e512ee47b4e0e8f4e4a102a6d3871b0e60883e0a6e81c4d6147df34bee03bcc6a75d9930870181f3737aabe83e3db0443401b6163dff895a56ca07e13afe04fe79981da66375955e397329f693ea3b93176bcea550d2f8660cc56d08d01c173c6ade8414ad369fbb128f8f3c0816e184a3c43e03015a59a24d4acdb0f328fcc0f95b7e21e0d2c655c3f2a5ff373119269cb5676952fedca82d0cb063851523be7eafd6cc8ff76799045f0e7bfb7124b33c8bac4beed87165b671cc96f916259311c94d8a84d6e8ea7d61e551a3c7ca79e1bde16ae067ba4fa17e25a5671ab356d405bbe97ea8dec3376e01e09b69ff9f3db7aca0c55e4fcc42015a0b4cf04548aabc7ef57ed5a978cb52e129dbc444a0451f37c5e639e2e1820cfcf64a0ceea6ed758c1afbc749b29448e6bdca2f74e2694b17185cfe163f792fe4efb54a8aa64279d71cee54013d403b443d72df2455789deaa548ea7ab6d12c29bb9f36a74562a7025d43390eb4923b40255380a83f948ae2e7f039c830890145146ed81207bfb019ec4debc0040e1f9da0a038c5ddba99fd23a819dcc3f648377e5fec794946d0286634c1f6d6be4ae012a46629c687125396453a6cca0053db1f9c71d9e88b2feab49dd944ab5e3b5c064e82b51f5afe6daba66c82a74450836baf0bc75ea5847fed1e6f428abcfd7100459016c75f8a1d0d9167c2a6c54253454662560db2c273dc7ef93a6c3fc09729a550a5bcb38e836a83940e2d8a80f992bdd2714dcfbc92b97b1784c7a758eb843e6519359dd2618ed708677f5bef44b5b49fb27c0e62a3c7c8a70279e61c6799069fd705956900bf904c40532cf41506e9bbe5363053eb3d36995d5da3e61d51ce426697297ef7eaa99a877f769c3dd58718d7b876f3c6cd39a8875a8333d5e4c1cc6e9092ce37621cc6efd8779c440ef92313ee510b3f278ac0c6bdbc3b26512bdd170e6242b42123420f39044ad8d16a7856d6eb3da2d10ca83beed39322b58de772b1cb067ea6385c137879379978dc83bb22e333b781863af066ba8f100952264883a59cbe505c55d447484622e5d0d4b10a4d8914a48a9e83869601c061878e0912290c4d3daa30c36ebe947b0a765429fd9fa2783c340100db8d5653d6505eba5da0d84353dbd051769e8d1f500c79b94c0307828f96bc6b91caf224437a627d0d312a19a8746ff9fd26f140d908a7e0f1dfc2c2c8877d8ec56a71cecfafe8719e303d3f3032c3d2999d90073d8194e764f8e589fd908ba4706ce2eb20eed214403f5924c19767f410dbc28518d5d2a769bc65154a0e408113d5b393e8b25552502cddf6869eb5e444959da87f8053ff27788f08d363caef5ec803e03ed607fa6102a5d9714ba0e85f40ded38cf191e1020976c984478ecf9bbf7163e6aedbddafdfae05b41f89da616bd6461b8ee90f51112c5bd245b06135ec4b2869d75a7dd340a8e7292d7d4e8ddeafb4a06ac873a58bbebf53ab413cda3098bc7a12585079582fe8e709bba12e2e161c552ed504557657dc5d263b96d635494589567f28c8f27c09326eabdc9ade823ecaf9b9b36c5570fd8c0c52b703e1f348c89c2da85ec3bbe58ab3d8968a09ce0b84574fe12e902bbfca0f3c8164a8beec859fc98c6be009392ffbda6e472ad5a5a0abd0280da5c0a11e7ad7231daf4ce9d85aef423861e4515ad4806d0b67476b17d4c4be4929e3c58515b417518da2f55dca1a80d2fc0617b11dd6540d012351da1fd2c8e8a1232b0c35fcda94ea7956694330094ef8125a81eff3ecba73ca20fe419d63b4f7d0b814a6eb34ebe5ba5a8082441d804e4e431be6b3126d2363b512a903dc8c9df8857c868572b7a94b239a1b4bab318c22f01f93f14f351095e980f5c89b39b3f87434088f448647a6d131662ad86f73ad25194f064af7def5ae1fe6195cc1a3579e5d3ee8d7ce258f4156fee21b09c019806dad6565a5232f30fd9cbc2ce1b997f8120d5ae2ebadc8005d9ee8afad3198fdc9f62a53a9e275cae9d052988956e456e0249cda2151b2c80cab82d7d848559151a2b9da7b2c262f83475c563d96bf6099ebae1b41a9f49b6b29346e611f6aead35f90137b47c890c59843095a1b190e407b1cff7b99ae8556e55a4568b8ff9c38af998f9bba72129103a86f7a8eeb4dcba4630298ba0ac9139b408497825009f6416801748f62abd4f7e78694af2c78fa2b341291a80d493be8b324889060ca1ae0048d745d9ee115554e30fef1c3102846f7adbb4dc8368d1ca15f2809e911b598a1c663e2977a586a85d37aa90f940c8f54753a7522d32d1b1509db5d15410c9215dcbe2b62741fd53eb4b31dc5fadfb12dbed7531ba6f1a2d3c0996dad3d1f0ec8808604f2774e53a43abade45bab942f7f57ea2475e33d9208546b7a85313a54ffaa6440103a28c61dc386b16e45194cd243827c292cef028fa83a94ce6ba3634ee27087e34788d4e1b8e064fd2678822c36cb1192e92720c2e485c74bfaea8eab5ab6739cd0282530904241abddb6b10425afe7e03d58ca3bd91b54b0c8e1eda85d3c0af5b148776e5a0b3bd90c6c13ddd3f9c567f782ed159f71db476bdc8f3987ddb407d7fa19a5e536e84613431334fc4575a17e49b9ecd889b07c80a6c4f92c7077364dc842804599d92a039ed6dcbcb7eec598ff6ec23c9ffc7195aef446243ee17e7856cb22bb9916d6a8e158e421b972921a1ab08bf6f5c1fd4cf1a3469a4fc15c14d2b672543121584df798411dc68282108a1e841f1caf290357e71b9f9bb8dde5c0d3874cda00315c6fc0452fcc4dfeb7d33d185e4f183b2f5a94a833c42c061dda0b09d36a3475a2ff3fe31588e4f888d926b78bd5f2d9ec417c7f49c23f6390c0a1be82188091c9085df42c8cee99ba79934468f93ee1dbeb2ac0c89cc828d80bc366582b98d3431bec38237d43ff71a0c57f13c50f1aa820869b3f09d1e252cfe1d48fd51b4a1873f7e4af589151f0d3e202ef49182fe7860307f9104780f2e971c43f6a48ef5a78250138f8b02b98e6dbac950de5b14037a00e7e812e56c1b944425fa86966179cbf7dd0c69bf0ef2edfb8ef55c69674899071511f8e0fc0bb6e9a114aba1300e372bea918ae54de18d8f5fcd05ddb71c4406ea3ae16678f6a1e45483c7567ec6e494811b30e448f5b84ffb7d7ae098618e838a7c5c505494782a2c5db9f94c14ae61e1837595026664d586079ba793672e3f460b43d03eac46c8ec3b920b79f4d5d19d6d51fe9b75291b14b5992aa990e73b0fea3663e018673158cb4471d909813f7bde7c10aad310af3f401fd79d45898716fc1176defcfa47d9efe240051ace3d62fef687bc4122bf29255efd5516b006e71e3cf4dc8c504cfc84bf40cb0f4f1882090bd028232b99be0f953e50fa6b425beafea70f302c6120d3ccbaf140cb0ad721f56eb2c8df0b4e507bd8123ee52d29fa35a9cd16080a3a1f6498199137b781cd52a96984cc6520a967eccd78188a2e27a8eaa74909c8b4330f19445238413972a426f5ca723b7c1bb99a11054e6e8b396d844efee2c6eb9a5c00143b77205d09918ccef0f9c58cf6c98a4dad1c031987ebc0011ddfb7e8ec17851b78a1a01abec3698a5dadd0488b0f141cb0134e70abfba231fe50bc48ffeb2f981e1f81021767947734cfe638fd001d79c2993472dc64831955a71714f224d244c32b0c33c24c0617fa127a3a6ae0c5eaa14840e8a79b7e3e768de994fb0a053dd466f5302a714102fa81c0c1620ca9eeb6de1f81219604098d668cf1b47df140973158125efc0460bfd08948a582092d146162bfef1891e27797824805027f7e11c516c98a50b0dc2fb7e02a970169c34fe17b7eace0ace60e75726d1ebb1ce0696787ada2a2c7dae68900d07edf4acdd0a32b3cc4825099d59161fc61b642347c7a9bde020396aede6f1a5ed9ced58a79172fca85e2cd9a44b4de9d37e621dbc2764ad460a331743e1979ca2146d51c14c7bc57b64c6f808a761dc102e3227af442d254e18142970168202b10a205e46268621dbc0a8d10d4c8a0d17d51c113ae907c3f36c38cad432ae2f26a0b02c818aba044a36aaafd7406b429ee6703c604dcfd67e5b21ab451884a3a2fddbdc19f39540730b18cfcf4574668a3d78f875978411591193721c93ccaae556040eba7d7846d60a1016e5f0ec1d0856c2d8d10c4d35598bbc6af64521afc8491f973c643a40adad93b544b69c9d980e53a1da6655b8488557a958f6be1c8688dd12a848ee260fb31bc9170b63d610a172c6485e9a01ae69805174288ae5279ccfbd88c3795449443dfefebe3ca7e1860e704168cfd03c1c9de5f5e342c81502a26028225655c099e76db00a09e5a6d244804efabeb60deb1bd11107103567a4bfca732f4f0684707bacc42b46f043b4e0896d14ee18c56dc4d4cf29a7eeeb9be30ff6487c69c3229fc2b1c65f2c9f7836aa438b4b10363a670b9254a52e2dc15bc79f6da9c1b46a48adf3b49da720918f93583a84d37991baf76032850c59f86303033bec2f258c7df1ab2e2de06d9045f21db37d027d1c3a62332fa5a51728eee39e5af4ec741dc7f5f65e03e7ad99c008f358f19b3f8c1c95363acdb30ce8319875fcf7ccaf1d140a205ced3e6e2540bcc05efd4edec11ee12bacc86a0c262dd2260802aa02f81ca11093c098b78d780c95b0652f657de55b68998dafef55b86c5437d509bcb0288afad2f08bcccd9e4d3f906dbfae463e20aa733a2fbeb6e1dd1cc831e1e21af7943dc8d08558a0544b19638b64af2cb923ce1d7dd64331a62cc05d622219b0801d0ac6163093a1d106dc3d6d202fc5c7730976c6b9b9f6f6bf8d02f40d00a397fc96590e076d5e0f310793cc63f008df9e3a8b1210b4004cebc3ce42db85d7ec48c321299272ad77af9d54340bc61bbc15187ed580c4213270d7e7d817b11c4dd8af85d84db08c205c2a0e798e0d5162f15dfc53ac6920a1fe97745c40f68f27d14bda19eb19ec60efff4e9d64d18244d63078f6e58b4127a070493784f5b4ed56bc28e170079f1265419b5a1c8a47a04c4899d660c167e59584877a919c90875352bcf579b61421725993df5452f3ad2fea5dd07de709706e33a7d7188d7fca00ef90d3eca0012249517b38894c24d2fdfe9c4bd1b2dd6a1a1445c462285e1ed867c02065c30a90c2b0a12ee95c9f5e5213d7b0fc10557e9d67c135ec444aedc5b3f0e4f5417d8729eb9ba89d913d8d3f1a978ff22f7792135add1ed565ab63d791ab1868ae00a354f7a15d222c90b00cb471c63a1b1c88ff6165a19e655cd9651c5998f35ba4f86aa4e013263c3ffbfda7ecf30a39a776e476b6075631b1dcfd6a7fe4f95adf9a6569aac928c3787bd0299f097b14678f1e814a801f65ea842439dea52683d5c145053ed2f4ea140fdec6248bc90f0d4afafee254f55fd2bffc47aaa8391935cc6596244c776eef42dfef651d24c7f1caf1659c589263b14f6d029ab9c02dff96a35c910e27c8a9c485cc2aca8e50ab288ff120596cb50d9eaa3bd6a0a18c666727774ccabd89308971f6b62aba4894c10f12113c5a679729913ee6cd529ca5bac1f9967c6940159701238a62518a908a2538c8a379d75e2298f10e6622d271eee4156a0018aba04597a02162523d69dd29ce3f48ba770d75031980b8611f09f1bbc929a6f77055da6af85462e890cbe1fa319206fbad90c71b40269fe2138a37ca3b5b44952681ba65f893867ec50ef84f938fb7ae3697eea45611f865261143dacaa858718d49d0e80ffb61e53282aacc46ec27ce6f31f9660b7016f40cdf97d16921990d1c05a178dfbfa609925e168b77557df93d214ae731614d1238c25440e1c0d53bb5bb758e719658a96a4b26cb0616c21f20a990b35b57b02ccb113ff64ce67ffb8037213e1cf4851686c3e49c1b057ab386ab0d34f5eacc5401f8e7337614bf006a87499dd30309422f261af13b102509bb3bd72f9035ca0911f4150b7e82e69227d3d2207f185478eda4d01fcd6b35e868f92482bf04c675bfb52a6debd4e6503b3ef9c72a948ecc506e410172dfb76c1b63378e8974b22471473926b3e590b8f69a3421d6182323de1b306d9c7fd9ce14c8180e28945b8887775160d1912c0b628e46201c9028113e32f8003347c83ff9a722dda8bf0d8efcfe115ee2473bf64178772ce4e6ef3cf378840b609d48a3ebce97e0040afc76afd5c78bda869909c5b8c7adc8d5f0d06cb107c82d9e38106678c82baf2057ccf1277e4c512e01b827c1194173e26e04a6a21250f412d08bb9e61a9cbd86750fd9b5b4df168a3b37a5a246e53c57b44e1d14d59f7785ffd63d507b0f408e877b9518893b98a3a096c2f09fbbe3d00b99453a131418c3463b0ff2e500a820cad6a82b02fb9d574d69cef042170ec9d9259082c496f5a91eba4bd9dc17694319dd7a7ab30cd216ee332a2a4428c8a52f49f9b6b153c2acea4765c373e61d59210a53bd310f3a408fd92b3691638e57d2c64d31ec33a40dce89eb2c97be9fae09bc28afc5103147325c7159cbf4e1b78bd670bb5e9f1fe4651ef8817642fcccbeb88db673c92a6dc69b861360fb168ca83fa1474a737afe4867fd13fa6f4601a2f77c53c14b4d3f9159dd04de460ee9618a5579cfb390bde169dca761038c3012d0e48428cc93f32e1c8da3df033d4e19346f6100f306e235d761ae472b51aa6095dff40940907f6a9b713c8a590ad02866f81b619e0aaebbcefb5836ec396976f082bc1730b5dfde5154b0c1f13d13aa70e16ac52feb7e4a1e5018b1d9987555f80181c414756f26e77b1cb9bcfafcf23799069023bb2b79c35d27861112576607150fa52354981b2d908eebaeee4d4665bb3b02f4f1f5e8a02d11fb0b442418d4861614025abe42158de31b8838969d7c8c435565597a5b1c0193c90488a2471d88bdb9b228c5048a48482576014b5ebf9c11dc8ff11417d0b709fbde45e864a24d0bf06aa06227dcf455b67793ab57e879409b4b487c4ff78bb071d7dc9d8516aabcf8a259ec810afe262d637d166bdd8939e0acd198b04cf8901d2f7f9cec243829217b4e2e114fceda6fd821ecd92e676c438469f6cbc4d416bf905ba9cc820d547145202d6f08accbae089e3977804dc7778511ab5053a06e2d1d77727edf901581262aee6bf72738dadbfb21429caa6f73c3202327c5a6cc2c919a1c489f3149c1f23f4d2d783da7d6bf24eb3528024bc0f432077e368dc8300ddbecbac3bcab3d44845e6b64f4087b9b4d93def71a502140e1685b2e09b028fa6b17b20a55175479ba6420cacf070c7017f8a43afb811ca8dcd7d3e262ef9c94b1788c97102d5d14eb88828bc4b1956144514490b306e0096b71a37d9eff8736902e96da6212388b4443f725dc4fdb802b0d102cc9176af6b9b8e1f7ed644e8518a84439686aad674e50628a3b42281b08da30f2396b8779277a15c846ea3107c25da8b7f82067f08d277684a6d0f0a6a4cdb41af2bfa49a4c4a6998b167ae2da06ccc5fca296a764456c8a42e61f0ed9f535c3535650abee5812bb3fd426d1e14430d9c367b30eaaf1a8623c0d460da3772a523d2dad0b3a5e429d9841141bf390b810e9becbb305e6bdbcc7d1669ea51e1e53062f5ef843cd0ac53a11f045e83fedc4bcc7aff435f2d6202900fccfd560aaa5f96fee3e4194a7ec38978a5d52c1e5cc70e2074c242e1e66791fa55572dc18ee27561cf1644580f85664b6b2809c6fe83dd5da105f94b8d54734c2ad7d9758f08624d010530e37d6a6bba340089c7d1050340c7841a7f4a6f160d0eb85bd738845a868e127dd17176ab8f9f67f85e48b70299a18bf271480cbdc25d10a9787055f6497685b046184d76fac0875cad6e971d3ea41149ef327d9410e72cf51c7684d295c556dcbca31ec2f8d02489540eefa7cb760f1f81750d6da82a92d2f92a000c095ac51db43161c5d9890f37ffa9a8f6e45abf8759bfe0dc7e954214aa76e29f8632da35a869038018011036b2db1e0b14ad9bd151f72c8058fa6ac2f1e291c9558421df1e4578c16d4b498158f0f78460932235124a0c815fe28999a99d13efb3e8c3ad42f593f58518ae1b60757cbf24c2b01fb75a47456d18ac98f2d5d519afe20b1072d820ebd131c45aae24d466efde1f985188a4212d1f0f71dbdf6f729b0c8551a50768948dede77d0078203a45a2661fd748fc6160e331008907d8208e994e00d6ced2939dce35ede557413de5960184aa1081ca345e69272b6823e4e9e031d3eaf00dbf4470910404af020117377552ea82f8230f554ce68cda5be4a7d7d07422784c2512c7c6fb9b8f9395559e1b14073b20d2ace9caabca7efe883119dbcb655a11cb7a6f07d7b58f0f827b875a02f7d24fc620aae547c1b3dbfc775e2350c3847c2d40a9bfbdec11e0665da8ee6cfda1f942c9cb6115b3c2e224b224ae31b3b1b8e625ec255c6bb5b2e91c4112223a6cfbe2c0c317b8bd7cdd5f610dff3c5593877b12df029a68469a955a221f973902d4388b4441691194e577bebf278b6bbc2f9116fc519b01e78139a5b60b31c39141144425972dc4595be9a545eb5b6607d1312a179b7d0d8479b213d63aaaa6d3077b4b9d278eeb6f3f1f3c184cfb00f5ed8ddd718286b46e7458ae8ddd4fd82614946a20832565865420fe71f31c8a8023afe4b45a1dc064d9fc1b405076034f109f991c820c1d0763811bc02237f5d16be74ade0831f4c84789475db45506f377d4c512cc6976ef24cbbbe768652582a32b868e9d1988699d7b55e2a12b0ffefbb771fe26dc008ed41687ae90428ca666451f2d59cef8fb761c9823618582a34419132700513f8013b3efd135d43812025dbc77e79483ebe5a6e12c1f6289b92a0423c7436a0625a8283adc59ddb24aec27cd07d5553c6f116785048f5ea0df4a50ab5f081a40c1fb22ef84e0b32a835080e5cc15e5ac41260936471a33a0909a1189f389bccf1a4cc81e056bc23f485e02f1955775dfa4f00e8e60f992d5bd3065bc22179ef5b314199d691287faade3518a8586c7e01de6cf329609ed855e431776f86e6ecf44f7ef11f3a5997df0a1772c3226ba640dd6aba1f2558939067e5a9da09dabd4a7152a9bec03273682b1d3a3abfaf82cede2faa86701410da39e330c7377ae001eb52cad383b7cfe620324f63a006731d768d39a67cdb73b7c74fbfc2c12ce412093fae9cd3402f40b7cf991ff5baa36d84769740da1dbf46f9ab065b50ead450b187a33a0b9cf417f9d525d53155afc5b8fd6656ae79682c106a6dbffd2639cff54024121df3cad272b3649370a82d8f55f882cc30f1e97a7068859743d4e34f6747ccae2479153dcef34b4749b9a1865818ac322127ed70c124a3b85662be1e74262f03223c7a7e490b9d7323cb9d78f71ed4d5a70ac255607750d8e66c2e4c294c1e2a0e4e35878a0708a6b614c9b82c1d6b5d1f7033c8e5bcbb521044a21aa03476b958b687c3816417cddfe38d23a2b89988b0f3f2910ba3aec2684a5c92bb34fb504a906b5baacb1bde2aee4a0a4f5548a0f3139a1e61bdfd915745bb70cf7d8db27edd500ab2429500b3e850541d66fbb0ea37b9da380701ba2f768b79b8ea8991375b3d2c46b64df3151e41bc3a524ed90926a27030ae51a881875cf503df891805ca00e0f4c8ce4fccfd4c0d5988cb6c284efbe6321d66ba313c414700f0325bf30ca5d703617ae8889a79a41d60f4a32fba1e75457cb4baede347f3d116782f64726091fb8d116e1e0fbfeb198121eac0a9f6eb6c519a1ef496172854a52563d4f3c62e7313734188baaf0385868f7fdd7fd8d8fde3b5f6aca47f57026251d66d6686d294a1b7b3171032bd8ad4102e00968026bcf9e489e8d64a083014a064016dad249bb7cb90c36a850cd7b31fd5c9ec1d39e0fe489b0617126e17e1ea6e143938d946320fc839fb846ea7f7b11babaef2243529fa0809f1dc43827a93e41fd78145a451e16b25015ab369556f3495b5b78c27027de6213da00d9ac467252dc0e4f57424c075f21e3749958669e1428e7f0d6b67f084b79b76de2f8dc540125fe8c8f3259a3042e5822cc33ad719fd98642d746133c5b07cfdfde0fb9642798ba13dd7a88aeaf19c0e6e23c6baa4052f49ac903b3eb35cb6025ada1af18b3df6b2956d27ddc12340cdfb90e4f5ac7c3ac4492152273d4ee68c8aafa900165270a0ca128e26eb420a76dfd70ff985e90b71fc4b0a504b875bb608f07f1b3998395916371677ac0f1fcf0075aaaa4fd8d2ed2f9aef4264577b233b22494ed2f3b54cb7e599dd5cf7b44d3f994d736d298f8bc11242959ccee60316d9aeb10e75537cfb8db1dacac52de02bd9c7f518483fba9d196ae5ba0df33abd3baa0510b298c6fb797697bc21c13a07a40f05b91cce9fcafe25867558a5ce0a2f4757a8de24d0338e9306087e674c4cf91febfdd1eea07b9749e0c40914ee3b42c1871b3864cbf9f357c2b97fff21d1bff6fdea0fd3c116f68e7c0373bcf42f1d0792ca78d4cc4737b9609cc55daa3cf2aaf0c136732d625594302ed96c38595fc3da43036736942b6ed3b828448083707a569ab6945c7ca2746a9e0acaf4887e91f19b35310283d15eb6ee5eab5ee75b51da04ad0423c159363a4e49a90fed03e43463862147bd2415a82c09ac7cc76c3c8082c3061d9dd3acab406eac471fbfb3804345da8640c378f46eff9a4581cb6424754086c0aadee898b4dadc03755dc878ca0c5de81965087460dce41509b50e1ca1a2f33b2a206582c2cdf5f3d06a0a80f7594e6c3b78a232f2247a11662c36112e342e3cec3712e79d858a06b7caf683fd5226ecfbee40e08eb875fa1a810828e8d5b6c843165da4e01477c6034269eb5f5a3462489f746585efe50f784195e17ffdd9c524887b9550f4ee68177ec97846c9ff9ae0d5b15115e39e95e075e66ae7f730fa024436606c048e81ff80ea686e3560e480443c5264583b16fcaf632faf45bf86309461022820fc79003a3e4e250d8ba3aa3bdce660fcfb03edcb58bb62ba5eeb145d6dcfa98348e2fe1db89450c0c6ae68ea8d3844ec34111a9cbf05f83cb342f778c1baba9305e0433fb16e6fb36dbf753172176033c1d1f8dbd35e700f4f4036072df4146ab7ea4ec04e8b0fa6b8ffba994eafa974321379efce8558db9da21ef0e8a183bb5cc702ae78617f0ef341ce3f22c1c834e8207a4596be57bc6b4b2a11b32c802267ed83ba213913e43a1e03708d1a80db0ba5b75a8c101019e5166905dd9ee3f258d9157c9f78ffe563a5ea375792105b1ac4c809e40dcca4f922a78087a85e3807830a88d9b40f8185124a477d98f545978b174051ddf33dd3487ac584b65cd429872871e805982e98ad8e177503df36948902000f34bb1fc39940e9323261be099fa1e4b29bd5da458158e35a7c97a40012b9da29db6966036b01c525d0a620f4f4f5bb0ce87c2de6fd1305f924c8a0fbee20afeffc01b226049e56e6fe1ad307575e8c586708f3986b3ade407d26756c14d899dd43fd361e209dd8f88336688b69782ef04fd00f14f45747961a84a74594d957f7ea703c3682820971a51e8a2d79271deb8e7ab8e9ab5ab263d19369407a94490cc0d0fd6bcf398a6e0e3853e54a4ff1f99400db80dcf95d0a7f0a579e96f5d0457c149acde0fc354613fcb4b4a0e23013a90b3e0609bce9f983d71410b43208430ce64092465ff942e3343e42d085056495b86ad6d799f828dba44cc267044020c973292ec88683b37d0e7c1e6079c8bf1ae649964e6fd5c4997f7b0bd76cf39f4de85166033b50faf65f6d26f92d78f73b2be7ffaa7bcce141d6c06f430b3b2ac572700dcb15e6525d59cff1840b70f02588f5eb45340f6f3ff78d076239e91d0e9d7fac049745cf6c9b106e8a4d01234ea9d24651264a0025fbf947f426f203154a6b4b7c3a31a55794dc8e8f203a624959d85863992fd728f18929a1d5d18c63b5518965f9671871e9d678b20eae902256556a552a2103b0941f2b02765a9ad025c00dff56be8b6c00280d6c78f58dbb2c171ceb22a35324058da5849cf45dff8bdd37bcf6650757527bf4c905b16492eff40ac7936ff8becb24f51f2d23f2d991acb5a799e2123c9662613a0f6afc930ab76a7ffc797e84a2d79ff0720e297a4f01b6196fe575194d9685308de7792ec2bf4440e38509811b28d919ea07e81e8971262a466724af647e0583c70994b9bfe39cb73aa7198633d939d56d6a7ccbc4a285a648a3077ba610df00f5da617e26ae369de9270be8829ec98222e6467729c17403129f22db435bc16417f5866f0fcda8bfb240ebd1cf090ebb0f53ac7457a00f518b5468a1c76fd0897d3a09f2741178ceeaeb20b79e552e8a2a2707fc4eafa9432d9fc983db0729922eb89cc520d31f79f7149a4b0ac7310a7c3719b6cfa757f4312a9c1c0d2245ddb07353e19356288fa73ef3752aaddcc184448ce5d72936a1987a02ce28c98347a0169fc894e6194d682dc3fe5e31435a1b72da57d38ff195d053d33f2a8d400dd3c0ba31f94f5c6903fcf16c5ecf5340098651df2fea8abfa652fc32e36197ab9a10489adb09d7d656edcf5cd764d091662a8c946b9432f38286a91188ff257f91fa455cbf2903feb217a6292d9c52b48d5d2318c7a8227874cad1caa65a59998e5ba05f7a64e9fb5292d0e3cc573fe98df6d751e3747997dee705250ad029f5c23ce30f98f33455f411a0b88069f085850c341682025cb5e37560165bbb64bd1716067083272807b3afb1dfe109114c62fd8998ba96092fcc88bb71caa9af471375b08a53027df553d80a94ec12baf8fc1d4c538c6ecd6c29eaef4d142159204346549b7a8ce3967deb60f87e98edb776b02ae9c83298b99a46046d2a15ac794b3c33d759269638ec541e3b7a327ba7d2530f9e0dc8db29d5c9461d2c9c98b1d30605a25885176e1a49d4ccc4db0fe2e5af1f2ae82542a149bec659246b1e4b3f021cd6ef90a40b7e1a43f44a4315007997390fd944d7e0febc89bfb6a7d15d7a4107a043cb8ab33cceec2e36a9d7c8435a6bcc574df0d0f6a951c142bc12b6860bf7d0a783503233913b0e36b4d71c3be7aa099047f1206b4b9166479768972048df9a538e0e543bfa8a608f6904398d0f306a12a922594a5163fe578c0c00ff07d52a3171c753823bcd1dc0d3ab035d3105ac459887ebac7f65c311435f0ea0320cc8d8340eb1b353dd45bfc7114b1aa739def5389c10b41113c0bae6aad28d54c96a1318adce2393a6038f39384c75d641ce044ab6ac168539943d4a89c7ecd11af92dccc0a246e4f111a28fa3b0cde9236be458c828d4bd3ef47d6533a2c582333246a9f295488882563fd02c8fa5a8d8e6ddd263b1abf329d93e50475cba1d5d61dc2298f01b1902cfa1c813252a155f543d3d4e2c81a5c91d57fe3a0da6ce0b99ad1ecb723e88e6c19fe5892fc462542446671c46f0a439e704f35b61a807e1f000772325331848d0578c69c4dec3906a75f50e751c704c2a56bb883971730308bb8d5e6f46305da67c0bb1f70d4f9bbfe0cad0666030c9cc2ee99ce8934f159fbc89cfe265f83434c27826b5067b67daac97456bc31c15f2245a238fa86089d62fee73da4c1d7e33c11828cc4e63d4e1efa539d84663b030729a897c3504d81e88bf10741ee354ace9634c27dc6660ff94e1db86e1b650595dfc2fe17d4c5755443f9a459c5289f4c586231beb1aa36530d0dcca2e0296d8119d49baba189e65d58908367f37a7e7dfa8c785eb327eac3562e9011de6c8c3ac1da9a65400cae72688ba461e71a5e2787448511bb653c64b11ac3e3bbfbb77f4ee391c3995cc6f8ccbb7fdac6364c13d124843ffac0fa5b9ea1a6291399c8e391571dadd28e9798c5b7eec011d9361da1848716b1b6b4c8006867ee30767675f7bed780e3be1c9665f7dc1d5a0ddf322c8858e2c356ac4857b6782849ea9dd06f79046166d54652f019ac08b101df1f725c2512c5ec2be3fbaad4a3ce486edb084437d82a960c1b1d44b0644153808c59bfb9597a9569820dd093ee8f5622c04650498ed61321e27996d02f34e50876888764682d08081446f0434e9e6146cf7bd58b005d22f4e45dd8d2fbae727197938750df889f2e4a921551da8490db1ad39b29fdf447f75dfd2d3057480f9f224f0eecc9d234345823ed797b7c968c4974027f7a77d541cefeaf15e47e579d1480f054176849717de063b7b6e39cd86ac04658f41591a532de7ed170bf9875308ce07b9c167b902f478037bfe675b8a5d0123cd50f73ffe921b83debfc0f41f09e04151dc7ab1535e2fff32ec2cf4e654f615cb51d1e722ea50f12ab24a009cc84190f0971695883a7248939aa5be4aa809c9e74e0a37eac83ab04ae86c201357534f863acf41195bea620a6ee5a1658ba2d4910c536cd26ec1f615b7362688707ace9ba249fa8d7a76d5c4829aa5b213fa93bd213228b38db9724422f50fa21ede5ea823c96c0347bfd27bce9b6134eed15b75b8d10cbf333140c23afc552ae9f59ce7117a36e3c61c31c3824fb491823a3f59fd87450453bf0cfe4e7f6bddc4dd9413f9dec5f39e1c0aa4631b348dd8445f533e95965dab2cf250058aa41a819103180a00b4f2a6038418f3099a071f482df314ede9c8488cf8cf0a88c81c7c44f87ad68cc4d844f9fd1f5fe476b0c262005115eefbb0c029497116cff6767a3ab41233371e3aabdf58092fa90c70f241fd5f5c7692319efb77e1feb76dcf8c9c295cd2287c01144fd7d4e3309e824893574ab739737acf548114f85dcc9c44fbd244faf076742c7a34c5d219140ae149d0a78fe50ce0ce8ce94f35027c9cd55da68e9931d7108a1974330da51731919355448b82345048af17e1d42677ef6fbeeca9094689efb330088384e0f763949bc79af5a5b498b339e7e540c81784708ac48c23339e7e8750862219034c726134bce3927e85928005882c5464de08ee1dc14f6231fa2c4a8c18b671b0f9bdfbbe6410fd94eb85ee5db46f39fe17cbffa25c3ab1837e331f5a906a3d633f28881c420ba43a0c9e589244a025666a065ac5476d0667d3a22ba118fd40bac93e1ee3678b919c0f673a3aa2d83637f2727437e7c41adfdd829efa23850c9d87783950497bedd72e075ace818943ec136c10247cc81ebc8d9e4a974964cba3c96dc59addf95b340aef693a01a5216106fb9c0c66dcfba581dcad9cef8e7dfe6bfcec25c422e11ccacb1c803be37536c1d5958db580df092aa3929b372fce2dcdd4ed36d5809e37c906755187eda0babe822086f9a3708352a900bf36075c59a38b2fbf037ac722ba3bc3f21978c6a96828f6f9fdc54cd5a23954ed0172470f68cb7898c3f1e5658ceaa37b97802a7f1f11b3058b31196fd701ca0a6407515acd863dc04a8b513c41b6bed5dd20d4111cfda7b060b4341771a70f7eb63cf9e50200191b289e70456cbc65146c9b37c74d9b1419590acd0c02cd33301fbe372a0295fac06f9aac13a101155892a00e105a13190df079b035d50f328e8e647ed299c6a18dcd3cda4c2a32834a009846cd2d053f16bc959ded9c080f401c2591288ba3d182cf00850556a1507d8a6f5e788bc085fe15063f425d803af138433e1cac2c209d7a9f32620246d187a11df7845ca640a5ed2bab58aa42e1c9601e4d92f31bf74633bf27fe547861956a60a8bcd3f7902725ed09a261c45afde8aa75b44b49d73f4e9001575103a8a1ffab05fe7464702e11316b353d674d806186d41b5a880064ea11358521d2b6db53187a930757c1d6faee9efd7a636d96244b95213708cd66f83f46b1db1c5ddd54bd93eae2e19903ea458b95bd83c6b7b5c98637e7898073d298e9d2f8ace24d29efea67614130c8d2291f20e283d64e6e6b61dca3a194418160db584c7e363876c3b4766d83a2f44d83d419afd9570ae9aa6370132e0cc2ff23482de7c5f21a8e6985e1836b30a9159871e68dbe26b6b17a60392b69268b80d147553776fe4d88e6f9150ea50b0c1f37052d5337cfd5153bc4c33ebd9a138912483bcf1fdfb93c5d3b9275e36008496c51b263c24dad45d8b377484b7956c89b09aa50468199e92044b50bd6767c1b127c060570f4366150ad87b5ba0dcbfec3a77fe3ca2205fb984f4f1b1666e34315301cd4d70bd52c81162680957496bb94e00868108c3710969ce0cf432de5a5e3a0a7073b24444670e05504dbf87eb640f12b3e350943af6c318fb3ccb1d5b27b89b288c0b4095bd1f444477bd67224bc4afc8ce4062705b03391b7b33785c2e6a9b504e22196204d76098aceeb85c29989c7ab024deb73d3dc3b10faa2f77a56e0e967bc216f5fdc43d9c0dbce8e00f066be4a26e50e267a27c746c572d0852f74fdf0ac8d701e1ca713b8bc5af8a0e0edd990cfd2d8f125dd88323a99024daece96f4b2842b01ceb7b39c88c00ef41b45c2e5d863fc44fa6be122be97f4222e84c3a6fe45afa8c1d7562338c290d4c0cdd68374c76c58adc62181e46801440649a359c3919e3000fad1e5bd6624be4391c71e36e9be97736e8779909f9f2d92e14574298b1379de923e8233654647e48f85de139b09db4e42070dbf798442d2b47bf4b8fb42f7b74bde9186427783913b50fe74079197a52cc6463a4a0c7ca40662d8631f33ad35b243d0db9d6e9cdfddad63315852f394b9bfa9961122ce5893d90b23c00daced31bf7b705d1d8e22070eaad0a4ec77d639831a1f4541f0c434f92301921ea43c33ecd0d9a748e6c4447ea4a670d708f87b325855ebeba02a65162f465c5cd636edf86b1fae92f3c8afc32d54cd34d098e89164ed46b4d61bca72931c898be8a1080856e086cc6aa9608683f72087f6313d8700a5ad6884f317e2302a6fc37010337610eea9661a32e0e939807a3459bc7a8920c9b53e20ea9b4a85caacf019130d372fbfea0d9106958bd6fbe46e27ce59bb03033f1043a718314e4b5df2178d685f1bd29e28b3c29f4892b60ac5da06f5f0e00ff2b1548b021d3f2ae5f9e0ac390daf78cd34eff5b47e1c9406a779dfe3897006923409a21c36bcfc43b08358138df0423a8b00b16a73edc577766fe23d25ebbcc2055c39042534e1853e36e5378a857b006f123c13185bdd60f6ce0bfd186c9a0628b3ef78df82d60ee4eef4a7e4e093a5a8efd8474ff35e5f8ac17e5ae029cd9954b72cda4998ab60175aa62cb230011e7dee2c53f21e340d7d3f9e13066aa001868027bd104fc204c009746ef03215356b61cbf835d4b240ab34c2317d7c83f45521ccb0853009f7908b6ce8e66ef9b1ef89525c6e286c2197dfbff5eb9ce5565b181a6ec8e62efaff835ec66ce1de8d2bf015f7879555fa3ea315adcb2ecbe81ecf43b4a2c1b21dd245b651318103c2c52f156f0f6f7c333f7332082f16b68196097e416bf5128e55299aad87fd99fb5d621a00c61a43173813df1273f193a26d296078c0fe84b58b02958fe8b514a440bb702d7ece86b5de5c488e428396820115dfd81a66c2e19d0b98f0bc4fa17dd57e42157052372a7c48dc2d004ee688435daa2a44fa7700adb089cf884e28530f8a79d72311b84856dd47f155458193af087bf2331545ddaae678277e24c1fc585c8f9e4561f08546f9d6132b0ebadb533f887244c7a6e9a7868a84c072ad99a76d72546ed8c7ead1f13d7877a18cf36c9bd37bb833759a4d22fd7cad947262c847422bfa1dae8064d4dfc4c8edc38ecb1252c4c43c8f0fb3b4c7ee8a285d883a5f113217cb824111065ef60952f409e3d4f48c53b9077cbb15523d225bd4dc8633c776679747481ad37a60da57ef9f308cc451d162eda838f4d005bae6df5bf07bf3ee931298152177db6035014c7859cb3ea1a4916cb505c22e1e6d925801f30e0361d287632a2fc3d2965a618fb852c451a284830819a305f9973d9d7fba890026d17c3cd22a63be1344b1f09e2646036e143acb776a60b359d9f7fb01421a41e69c7336393308ad995a55610b76023e70771621820a6bf5b2a67f2a2a3cdee9fa56a44662a7c5e55aeba1e708cb11084085755cafb895adb69fbb0692e02a7cffa34e58d94979234780923d3761275745c5168111fe79946b9d6056722d1127ca98c8298ec824683041aafd0264f784d0040ec4e3cf414af6364759aed58d1973a14ddcf645ac4f582f4366dd5a4329e06ce53865643041962168c478eaced85a038346baaec0d90f9e5a1bac040cb9b347548d364e40797cd4c79bcb8479d7df1b25efdcf3d5db4eed55229e2296b119f5f9ed566c0bed00644dc13a73e7c196283055e116ca600bb268b38971792cc5e12c1d7c694cc915acbeb6646ddd480d99db790b3c5ea3c7ef1cd02e5d651339ddef0b85504249ed496fb135993f0a32534971602f8dab328061c53ce46c37b8c57d0624368eba5b0ef03dbb2892f92adde877e1866e2a925d545508265fd7206d0cc06c77df0cf2be516fdaca2c75112c1225d7c497e43e8fbacb5e5fa8d95ea0444da88b48e0736e74a11df7834ba636f78d5042e83eaee0f57986c137cfbc913b45bf98a48871da198c0f6fa3905b848cdb9cb6f76889739a985eab6b2f7c4b7e4a3f03c3a8f510fb28aa36f99fe1f829a6f5bf1fa20e50a85c6199aa1de82109c1883889c45f1a655132206046fa0ee7a88b6e7112c3a8c94052e45ed78ab474a195a87889069d572ca7bdfb6d4343c296e246e4d2ff79e4ae9f45da0ad9860b85702eb27da824ad154145e057584fe02a0616dfaf6381b8474be30c8849e5b154c04d48f1d5b4b005e10581e776599f26de95173c41885710099df0f3436652d8291e087c8a18b6cb10edf1acb36cead113c078492c43bbc3e6846f5b7ef4dd3c7d5539883a8f0401323dcde0c7d5649035856e8256562677d6e958e187bd4e49ed692542c62c9082a6c817524c72f99fd05c031555878b4464e837806c0e2187eb38a254a1e04d14d5207f756f42a8f3daa02e2407555496def12fd6e50204f67c6ed4c409df3de002389f047a5650024130cc8c191ebfaf5929d38b2dded686dbe35022a3cb43cedeba6de755e8af2bf14c6a0f01327ebeec5d30b0eb6139ee158fe443cc792f02102c4d65b8b6190fc3a8a2c2455b453e60a3af78c7a08b05f551a1253946b479ca1f6174e0d9d969fb616c816938f99738272593e7aecfff1d981652698136ba58158322c1a0c5ba5c316f352bcd8d09e4b364c1be2495405520be9791b20a322924a73b87bbd1343dd662645826a86cea6ca7be05190f38b84ff82e4d82f70767a4d33b98d19311b18ef59b34f80e8dc6767bdaa37d0bee5dce4f4caa2a49c65695dda795b06a6338b62bfd1aa6713446cf590ec25087098444ff18db3ec824c81eddb45f8ba8bf20ce98d58324126a12c04abf06a060fae1dc15395e4c3dbe0a35430b2f2f6a37efbf6f1aaf562ad4bdbd9288232837be068c9ba0a4d5f31f29ddd7c8f8beba18358198fa27f40ad13e04c537c3cf7c587803170d09ab1442ebd0c1890742a39442f55ccd11c366974493deb83c79fb77ebb62ddcb3b1234f5704979b6d47d566bf9813e76a233e00d5c21485bb36c7179938a66e45dd8905b025d179219afe3e52086bc4e18659402713c1528ad7d62db100a09023a77256812c2eec676c41a7018c2e6e4bb80cd0de13d4565d43907d7f01d984b971f386a9e26195989d9bb51a61cff05aadd2ff924a99dd266d1ab580303aa265bfd45bfb4961afcd19d1107cdd2fca1a13561d21d40828f18c81e4a2d34a67e456fa6b1572603106fc13783519317550a3ae9b5e05d06077873f7c994ccc1adda8c5c982a30d83e7140fc22d1f8d3d8de34864dac08f20fbad5147c06e8aac68ded779b964268583d30e6e4184c0d5336a36426ebe022308eb28ebac54aad39f4980cf41aed7f2f2e2e67f0801c2283766d88c8fd89e734a230e3a22c000661dbabd3ac46475f852198ddf73322d4882067d79aa942dda4e975cd43bc7a911c0e5a95200e50d5fcc54b8f1086c16c444d42f8363d2e152829522e806f8b432306f625eb61c058520f049c44c49ba73505307ec29cf366cb7c3b1251f308847a57e6f26c81cf04917de7ea68e854af5f8b65244d9cf4294010cc196f660c9422c903910626daa89e54455c3b538edd7003229b09d6f35ad5eb6d88121f14694ce6a58d600839afae788a4ff38cddf9ac2016bcc7188f3de717c6ea2e6a1b1276f03949593c8158418d3e8129f1931184316979160333fa9c50affb10a4946fcf5350e44a201c60388406e1339fb2f65881ff586d001285dadcd97f42f1426f4bb18b42c9a6695bcaaf9ede7ee7e3646e06ddc551573223e5b10c92e54f959e5c7d4ac64663b0cc7dcd464e3a97be056aba79639308f9a67d1f89a68c9eb67b509f0e41ac49b28206a7ed6ac2a2bc67bbd44c61e9637e46d0f9848ffbcca522fa05750d0e9c44a9aec81f048396be3f3df00a7229bcfaf7fce6abb6d57e26447af3eb57e1c8b404987a6c3d26ef27f4d4240ffda3bdd653b666b2c05315cc7832e93a07a0dd9a06efea426c6f8775b1c044c05b04a04885e0c6821b44b5bf0a4260ec1b645c56c5c84d28e3439208173a0854b0baf1728135889c95f3cee6e1b087b05d04dcc098ff96fcddfb968e04cfddb4a9ec33ed49741b78fa97d6c4ff95e8ea1872b1d388eb7ec2a82505d2dac233c2eec9179c3bccbc7d4d89351645c5129a28adde1292f9c0c7ce074e6ac5751a5cb0a449d294f71a256afaab3c28fdbc497613d105b3e55e6b7c160a4e88fc631985a591b7d5fc0675db833e504199917429ed2595db22508c24ae109e85d8822cde5aabbb0e1247013dc45b6aebc87cf119a1fa0c494b86d1e05d5bc647ee084abba536a03318e8d1df1663573e7d611ab026e6f4eec22eb809699704f27a5db6904ce56228c9bf2c24b1ede3835b75bdd79987fa43251e0c04e9377105ccb9791030ae6ec1b20cb183659c4330ecf7e52db970bdad9fdedd77917ade7ed8313a93f14b212e7c8248e95647f0b96b0a9918e51b4241ff6070304470bb6244751dfee2bacde56271baf1065e835388c7314f8137494149b7693f1733db6d86c7179766fa04f02df5133d94eee7a186620af37ad8f5c244d865c43f42363348095d34c4b4a3ee1a3248acf0e38f7e67bb37a78c587d32d70fa2c74fae691602fb0e31a03a7ef3b1838b842e623f536eccd1df900bc106676a439e7dbb1ff3e5e7083ec556046fb69f80c29a76be8801dd03c862ad06b695ac6b93febe9dc78e128940218c16271e180b95393b0791816f9cb433caecb3c18099c2de05690cf7bab907791e25a476e138e041465285dc1fc4fbdb812704d77a91a413bb05c02dd2caa90812de4200475076be300dc9cebaa7e656ad18b9668b977e7b7f8607934a163deb663f19b6a5470a1f2205bd73df1721c11fa6d47fd231873eb651515f2511a57bab8140c5d3f4408adfb52c26843850c7533befc580ee09087f4e6ecc6df6ccce13418e63af4077e8695c29fda9149cfcb0dbb15bc5da8f6579126dc12e4b33f4aef49230ddac68b0c9211b93529aafb94dbc06095fa3f92eaacb7456de1835ed1935a86c2f26d5d8c73d64e60426cfb087d4314943e2d13d806f1f6b4a0b1c0102dfd92b50a5ca3278bedf0c2cb93f42a0ffdc153095cfa261bbe9cf549554246066c9887b4842ac0a5f111ff47476ba91eee289a9bf83f82a96c9e9ff706d022c865ed03d7285d7225b2ef49c0b93e6319ea54277eea530808ca9ee4c212eb29a13eb9b1140b403781e189355d12e11007bb4d977b153d24533263de5a3350581cea4d48f4322e8692f58222f4fd27fab080017525750127b11a1c1fc1d20400ffcaad487dc27cea2e6be4b77c133205208d5c9afeef05a1a5ad4a2b172178f6acd0bf858173874ecc70f6785fa9fdf9a1c025eb366df4c72d0840661736fb0ac9f0c567f85bc2f2ab92e0eb87e4171072bf03e47a45708694099c0150d35c02aa4853a82600e1bf710414c31e5548e3950dea021f1552b7171f1f26ab93c80a883e3d611afc31925a0e1007eed49f9fbe5a88086d9d06b79cd55f2617394ea3f895b3f03891178967dd8fdd26417c13572096277f133e2cf5b992ac0676a19591db896e9e818c9cd3eda044c022da5b2db11efb170fa34804c7995a71b25669b08c8e4ae247e81c575f9017bc56bfbea0ec65f6c2076442f664460a8b2a4a86a9c92b25a8771f09526690ac37010e3ee126a96f7a6b4efa4de39119be377dabefeaf795454e121deeb7cf978655a92f0861d8569d935077629a834ba42ae516a0dd5be1648fb8247d2c5cf1b9b421eeee3a0dbcf716d6f253b4640f07e1aaf9a8519c6b2b914267819d532bce46458c68182bd88c46a7569991f69aba03d4c8930e3930612434022becd55638b6bf75082796d479370d5947c098e27437f66b3709f1e43230b3a2d42a94f79b7252c3ec733c3247868df068dcc5e875d82022c0cfa32bebfb6b1c803a3683431b83956ec34695f99f1a0c7c86f6d754e39c599f8f8dc113843c43c205fb4a6f409bf613f83fbe932c521253ff1ce14304596451a6894df8249f7e2c03b742d29545cfe3f9b2b40b9c1445534462e020ad92f20ee0c5ff36311d92557b55688d8489d940237884a4d2972d0849a489d9246b82fc5edfda3c97c62f31cbe915765405cd8104ebe446817c416b6f325f7b972d159d0ced25fc544a2a578488bd692a1c0469fdce5ed6d4d8acc4e301a8792a18420c71dfd062fa6d81d5a6323293e950720b77a362534038de28bd6a3ae76c1843575d0cd9932484769cfb309b4ef695e60bce551c09c82a43b6e11c7e564676de8cc3e96c3cb042f022d49bccb7ecc73ec7bda7fbae1d193293277d158eb8d39a7750f21bbf0b06336e424d2f8565b6844189c0391d37beeac341bdb4c659e4ce3b2c75258138c2f60031cd577077dfb1faa7ad4067d77dfbb2667411b1fe3e9a9d8002e4ad851e5482328d4f3890c9b95c47744abd5d8be9c0da2243bae726317cc18eaddea04c8c28c7f790b8eb016992101deb90506551d4969e8638a62d80a00fc7e41d77f9e398e2a9439127c431f95beedaf45dd193f70115605db48b20422ffeb1f42738d0e1004eb42300b40e085e0b6f8d2c1fc06ceabba0d7c05d971b5c0cd77ab93b9ab77f47a883628d4d8a81639deda07c5a71c4760efb60f540d26caeff1d1f3032d06a250ecab34aa8712cff139c02f4c4ccd54a20f08959d911efe65fc4e868dd30cfaf7d2f659c964ecdc5fb9c934b1f454c415839891aed8115e02199758504633140cdc3d79f8736caa1a56c5ad0fdb59b1229aa5e296aaf1f1e459c8fde12db6e20842b7bf77b8f9d5256bc474304c2f725f343e751c339c11c3504b7b4bf40cc0a2309217a495bd287e64e6020934486ba513bd4705f05673406020aa4615a5710382a6b3a0036bc32af29a65115767cea9f0f25b6f7e59b720845398b65c7afae3788a490a60d6cb6bb1970da2be8788fe4b4b7a5e5ebb4333dc62c09198c3e16f1766647639bd8aec7b7432cd67aa991bdb794524a19c305d1054505489471d2cff203ac9c18bffc2648cc4d115b53ec1d316b04ef4a0a62bd291eb884e400a1bd36a90de2efc71565a606cb0aa98caed9e26b82ebcac63f2151c486e0ac6270c2f42003eaf0c0a8913af3caf9f5d01ce921e16a23cb3ba8ab7e961f704d41ab6505e13ba3021ea5109a4e0f73e510bb42483a8ba162ac807a43050fbc3558a9193353b5576e5705103927d25465311da3d5830aacacc29df4aa077aa51383673f5f0b784d3c2d71067641da0b82c94e8ace0d38db3d01078a287a5231577cf97181236ef4865e16962c5d588823ca5bd3265d82054d7a64d3023442f4007f53749882051512faecd02e3eac14857ad17e271882b70312d449f88345248d1934ca516ab50b020a14b4cace59553112050d3a25c652d0cb123733d40b132557c65e390606a651628840d1887957841a2cb40d4d83d4976e41b5445aee0d10b9375dd00c94b31253c59698374f62aa18e304ab020b2b8a340579f5f0be64a566c6342111451f9a26de125bfaf9419393105fa102db9d698ab2d393cb3922ac623f20ae50bdb2d06c3e9ccb2209ecf7b342cc0f0a04149f9415349579c5e85161b503112b29719ad8c476e81312df130f4f8439b93489a9310923e0601fafa7039622a1022a74d8c3c2be2e697a5dc230d1050c1459566026ac5c50cdeb02429676ad69c2e26796ea942a8717265d83818f11d9ef77856e7645103bcc3640730aa49f250baa58a15db04b7f495859d24b624a96244e10e545d43bdd1829e2f0c6b8d932e64d2a26f40244abf4f2849681d1508ca6d9e153c208d64be6cbba3b1eb9de195d8fcc2f8afc427d6c723c3639c00973ce3767ac412faf99ba67d9ed076baef0f48c47fbf66bf6faa6b4a1e1c025b56e69d93aa266d942c26e4d61633bc41c2157b421cfa2bca4f695981548c6becec87acdc2d5866b8a170f9a90590af2506b53b9ca5a6131355c0276c6826e7214194e962e2c7493ed2124bfa09cd42837ac224e559f2b1636060ddac6a25a19cd7939d557902a22d14e76a2bca8322d4b16f32ac3e6895a441315b32c2b30637f7a2da2090b1f23b31d2acd8a15bd846260655e58398aab03ced77f8b547bf5b1f53a060814ff5d89cf97bb7735f22aacd8bdd7e85efbbd86311ec56bef501994efdf0b840279e6cbedc517df31ec3130b4606d14c5d1c7ceb744c19ee4696f3d66798ddbfefd756d85651b33c276afd11de21a067e9e213ce6125f7e9297c47f2bae58eca1ce39679f9cf31eab3e79c8f3d6dabd57c447ec6a42ae36e79c6b39e791d6467cd92ade106b10636c83405b987bedb5324eb1d75123dd6baf95918932c638e35c6bad35c418e35c6358fc63dbb7f9b0ed6f28f525c2eec6815987301d82996723126a1d3ec9a00e618ce3287bc964b299088630fd24044310a665b131cbc61818c2f4130d86f9a5413ede52ac325e3904f5938b6dc65f69b41d0cea273bb21ae0efd46ec6608761f83624732633a89f6830c3f0cbc683bd5e8fc3c7e2eb5f6208eafc24df8098b8386b30145fe0c3c6b0c868e803197dc3b001a31ebd7e6718a4ad862d0ed918fad74be70d4324cfba3b486e18e338ca5e32996c26ce66b39c10cc431b8c0fab9a6b9d874452ccc99f535f62f939bdbe4f4d5691b695916f596d95017e0567c020288ad522815586feaaf3ada5be1d04bb2601d87126b10e8d26ab919fb68377766435f2efd4eece25a8a2ce35590dfd35dbebab11ad7eed160d61a171dbb0c854c8fd45da1a4314edcd5929c9221da0cab82ad418779ba03b2653c061db60b059d599fc69420c45311c83ecb157305052535052606ff6ab57305069991deb150c14d4eb0a140e0a05c1d76db34514c52db92b2b4088e8aa08e941f1418437242a0182733b4d047787641f382b04c54255fca1a386213e2c54c523576d66598449ec9c5ebf5c4de9e750ce2e893864eff4fae5ca49a6db621c134c21ee2093a5b1c894c9b181cc975187fdeaf50b19d99aad7bfd4286d7a6492fcb8c2cf6992d1017017afd1648707d0fa4d4a31aa38f60ff45403afa28fb14c5a0107afd0da8789d011eb060d77712ab41e72bc763876dbacd50821188200420f040073690010c5ca002138800041cb0d400062c400137543880015038a106099d00232085500482071dc8881100a10d5eb8e01ab400baa0c7b6a393238bbd5e93404a4ce16bdcdf4cfbe36fa67dfa9b6985fccdb4b9bf99b6c8df4c7be46fa645f237d3eafe66da257f332d93bf993d9c745894062612c810030c1fc8c1010d9c2f5880021270e1012db0806305a5042421208502d830a10493c60044383222fa60c69000607050022088fc0c30f8f1e1a9d1f66c843d48022981e2837f336d0d7f33ad8fbf9916c8df4c1be46fa61df237d312f99b698dfccdb4507f336d92bf9956c9dfcc9b59df32e1e2d5b66f97701f257ccfc0b2cfade36512fe4df6f948b811141ff2ed73e808b76184d3c0edb316e1382c119ef4c4cef117ec10ee026f5b215c061b84e778e21607845b745fd9a7457f70abf3c16dee878de336aa066e53a91e3c7af088f1db31702982aa695aa2c7114f5ab8a8814a011a2a209cec0eeb6477c476ec88793941112e57746803a6d6bb6a12676b88203d4cfb5607b7bb266ed5ecd3a2dcdeb82dc1cc3e2d0ddccec02d9bcdc4adaf04dc66dd609f04dcfe46c0ad56992d03bfa808f8c531d931f09b0b01bf3a1eecc76000010c20d0795d002bb5e18926355f862c51840b982d426e806265daff00bfa907f88dc2b273f0bbeb00bf541cd8000736f0e251e3f1aa5b64aaf0c1434cd71b2aa67d0df09b017e7ffbbc27bf18e0b78436fbbc2ff07b017e8f70fbbc16e0b702fc36b129c0313a018e714bec4b80e35c0438d635b15de0388500c751337ad8274e1fe080073860f6f3b520ac593d6cf9761041c648161948cda409420795113798f65be078b7c43115084aec13efba7d1638e63580e3aa311b07c73d06707c75d4639fb8d7edafc0b16f011c670db19538fe2980632d25fbc409b891801b23daa649cfb034a9ca7262a688ce459815b841013a84922a4cfbb124159254b0fdded8c88b02ca4d7b88f54b145318dfa0aeaca0f14225c6cdd50b28527e600521049c9f691f013ca307e019f7a3827d66b4db4f81e79c0178d691e0649f39d7ed1780e714059ea340f0b2cf9cda38c1c6093f1740028a87113880b1e1c9089e4cc1822541f0a43431ed9bc0f3ae06cf543f50ec33efbafd1278e691c073959b7d665eb76ff2dc79eed1ed33d3e099003cffbcd9671e00cf23f0bc7fd86716816b24ae770af6a98fb80e81eb1f27f6a98db82ee29a0424fbd4445c83c0f5510dfb03ae791e705d4542ba4fcd9bd1c18c0e7a78e20b269268e1a1c90d0e3e6e525300a1a50416545bde98f687b8eec9e0fa6a882d00ae7d31b8ce4ab34fedebf66170fd0b00d75a20b0d9a7fe75fb1c701015e2200e6b9f200ae636e0a06ecd060007d3171c8c12b34f30edf68338e882833f6d36c9411ee760550dfb0479604f030e5ef5b04fb0d7ed67c0415f0b0e6655d927e8ebf631e0e00f88835a7bcb3ec15fb7ffc343f4021ee24a78629f21daedfbf030d7c343dd0c35fb0c73dd3e0f0f531b0fa3ceec334cbbfd586da7b643b3b2016a85669fc6431e8270669fe12ee4e1b00a0bd92741b7cf9017f6c22b2c649f076a9f612ff4e1302bcb3e435ff80bb5b090fd193eec33fc856218c279a170420b2069b2e68d1240b4286142161d61b63489a22567da8f815c2321f103cfd4bc9aa295686591eedb17a3709168258adb0a93e7766265d817ad44ab5ba4414f1c23fa44282e11eef645ad4b54bf3c81761bf542ad442c51145f4e6254ea2415a15c22b0db17a95ca25ca6dbac1ed52d900170c77f02eed88945aab21ab2fcf83367a1b7372a8ee98956a7885ae15eb924b77c21b005e3cc4bc442313bd48107ffcf659ff52ae74cc53eebd5e3abab372aafbeea2fae653153b1cf4fe1ff710c6551c451cb945dfbac57b8ec7489f029665df9c62b64459164a2c19c5911e3f5b39cf58eb0c1d16c28144a38b124a76ad2dd13748b0ae814a4c9d60fb22a456c0921cad21f9a243d343c6c690979b987644d2f490d5b47e01078bc2e678688a55faa1891a0f5764c4cd96222963e053bf68975bd7ec9020e8b945f6b54ebd05135867e5b97467d15eb708aa37654bc7a64b3eeef6a61145b8d76fd35168e1ad5a8c6e99cd6e95447e55ed6cabd8c05d6e55eeee55eeee59e0eeb445dd7dfa4eb7ce496fae9e65c2d8d9ba3f294d86b7cb1e32dceca58528f2c697fd418faf55bfd3c3a44c055b80af7ae2e11ecef7dfd18eb12bd5e3fcec2faf1af1e596e618fe3a810bef83b58f6eb711cfb5a6680f045d2567dc08ee9dd528b20c5b61ff22c7d5f8faf1f13a944d6871a858b46d2e2b0907efd1a068c7edeac1c519cedfd76f7c3829d2fd5a5babc5b757bf7ca77711777735777d31bb5b357387be5b359f667b5ee8da78dc385177260192c1a13c76a916aa58e6d9fc635f5e7146be533e7bad6bbf0b6702256834e30d7f3c7826ad86705bf2289e2de3e3edf4b22ba629fb72a69bcb2bfa68c64a2c11cff46b69dc635b2414db4993f86ad256d5b1bfffddab539be56bd03c81f962f51dc3e58ab1ecdf216d34c957599c83e759a7fecb3274db30e07522dd2a8510815497f7e9f5a84b57aea91f819aa67a3ede5ac5a3239726de625fbac57483188568bdc76ac858b6c1516caefe3b377cecaf9e25085f2ef20a23d43ddd0e6485e1e164aaf09aa8cfc414b36fe18c4ee81b08b0bede05790b4c5d978042c3bffc5ba37eb12bd3effd5e9f8a29873ec6fc7bdca4c08b3ac86e6b683b85b6618143dffeb77d56f8a8bb28eea79fbdcf4b34e7bfe2eea141755336a47d573ce2916aae6d6b2c127d0e996485d4ed0e9a2b7bc91bfca926c1616ca4fe366994dc73e6d15cc66d9aaa1a1b2fcc71967fc59a268737e2c04e6684e84a90e09a4a4a393331b9f46c25e947149fd4cf177fed6f337f382bf99407f335bfccdd4e06f26ff9be9e26f268dc644dbb2d887249052f8af7f914caf0fbff6379fbf993f7f3331f89b99c1dfccff9b49bae0620a9efb70793ec44b226870232d1870206e0389fdc35dc01efc760ea234fbc43ffba80c6f768ddbdc0eb7b823b6fd9348cd3ec15f88e2220ca70addc758e09a72fd661ffd5e14175513d7c35ca8fbd51837ccdd0f75f74314fce9aa1dd5cef6313b823ff05703b5765ec9b6b3f33592a9f63b5667535dbe9fafced294ee885ec14835d1c146daaa1e084eecda6faf5808fb4294c6995a0c61d25e87336134555539983b9f35f81d48d939a1fbd85775de86df66fb1e92e9e648ccf437139320b8d93c5fbb33d45ee767a8a2542381f2ebbced757e061e12289340376acfa3a4f3b6af3d0fc9544589e76d24539553079c356dbf420645a4a68e119c78260d1914919a367206fb7b1ed2fab0502d83225293e76d7f5a1f181b79512c744770e29935b262214c56e12a2c84d3d418978672099349e769bfc39968b05c8a0401854923ab10b58006dca36ac1145387ac8289b8ee89d3f4fb15a7a94735639b411a09a41f08bfedab59754820fd2be8bcad9a35677d6535f028cb61d5c4826cd8f8578f7e2e91d8ef99717de77bfec6f34ab6e779fc3c3cdf4332e930eddc765421eaf3d5bc1fe26c361edaf3d0f00c355c757bf7ab8cc449a3e08860b2a4c9027a44e962f3068a104f6e8d04d23b24507e20fc351e34124893d7679240994cda79204c02ad40a3fd0a3a5ffb1a8dab4366671417dd80f828130585b5ebea62de1d2e529a5c91830d28d861dec7bffb58eb8254ec70fca36981bf5bde47eab2cf10fdf51ba2b84827447d7e3abcc6c9f9a9dfecd42fbe5a9b6394889d63d4019d718c93719c0b41091cd6c5384e5b18a1c351afda109b2a34e1b7ed9f986ab74f0ca7dfdf0c2edb7e98b6b8e94ba22dac767d0fa4d8f56bbc5d1f7fc61df8b0812ed025694468d8b7617fc888472b8c56af4c56182dab2e42bf3423fbfb8c270245948af0c0c1230a0c518280480a020245b972f776af4d8291156331ac1cec3613ea84b301ea17798a1b0bc160e0dd4916e9923a1556a5d867ed9df6c93ed1f8aba4aba49eb5b42e4fbda7382ee2700519a14090112351ac49b1a1129fe2fb60a1ab7dd61e5352ede10fdee77d7c5099957ff04936fbfc147cca2fff7b47d8348992242da01152b2cf6ac6a7fcbf5704eb989bb15ac06ac18cb5e90e29a92e175c2eb8b8ec100c1dffffdf4203721cc726fbfcffffbf1846f9e57f6ff684935310948d20a82449baa64cd9c1851db87cf8e8fae187ae1e7ae0baa1ea8629aaa92e9c0ddcbd5430c61a6b8cf3bdf8621e5bacd552d19f79bde52dfb647defbdf7de7befbd1adf7b31c658639cb3d618e37bf3bdf8e231eb0594fd020a179417a060d94a58b88ebc70249683472dab11b363fe25a9a99ad33e6f9ae7d73e3e308c301e12a1f26a55ede59d46ac42cc126fce392f494d5d22f0bb95d558929a02472b03c13b0582e492d4d42d2b95be2445e512652a3baa2b4b52544b52bc2b5377977754a844ddb22e4951b965ed639578c3aeb7ccb7048f9820176482ae1f513f5c6ce170b185e40ac910198604e5d25c978b2c925c64010e814c308662c89881010630d26c0c88f2d0d0d0bd9f49a321a3a121981441928254acb3fe62ff3158aca71b8109b3a5d735bd82e9f9fa9294ae7fed78b469d9278eaab11417c1a2a8aa60b71e81afbf222e921185e3eb308f8a54ab8c6bc174fb27aee1a99fa2ec6330ab6effc543aeed8bf6bc616c335e92d22d49e9aa95e9fb9a5c92d2ddb2f625a95c5f92ca5da225a9dc9294d64b524d6e59fb9214945bd6be2495ea6e91d5f525a9237d492a57fb92d4d32d6b3fad6e49eac82d6bc7e49254ee96b5c3dabc38a2f5e248d7d60b5b4e9c74d938b55a2d8ab2cc37a87c7172d071ad56659fa59256ef67afb65ca16b7b69adb5d60e95e54db70f25494a7a24f500b2ef57144857ae8b398ba2921168ad0ac1d34e61bbbb38213ad7436e03288319e87faeefb6997d8f37ab84f9417036e61efc3470110c7c3dee59ed3aefb567f5d4c5ac19d303d06b1265ae6475b1c7f44803ddf735787197a8cec89bcbb37f3d2e6b0cf196af146c60b1611657d6a30a865f35af515d7f288e2428ab11065df037339c855f65339e57029a3d93cf03914a3c7f01c974c1f390346ec86150b2388b16b18dca12ef7a968999caeeaecff6acf1695c23112ed1ceeb3cfef1939478fe71cc9afdf8bbe7797e859f07ea799e9f9fcd6c5f6527e45bcf30e46e236f1b2b637c1a78f37c4b996c24eb2d651fb3a38cdfafddaff11d9e697ce4b5f67031fc5f8fd5d81df7ecf71e777e18db0a66c9afe34747304c8ee867ed31d9a19fd58c06fdacbe3dce6a4cd000cc667f82edb32bcb9f84ab7e19c9d4f563d809fb18d7b21ab15895990074e357f80454d38987f9830a32515059216583d9c3e3a41a320407254e1086099387a4e1aa877feb599ff947d9cf64e4156265c07ee4a78deab0d7b07c6130f2d645f147a67ec2703b88cafa78893238d6ca33aab5d65a79d5a8d65aab51adb99ddb831342081e78b092c30a0e4338089141c88ea11ddbca720e1c4465dfafb572e97afd0a9fced7633920987dc0db784b0b823f7084e1961fe4b0c13f7707499f2d6ec9b2fc319b33986b1609c48fb3141d639c3908b2cffac339876d228a7bfbf87c269568f52a4321eceaca395bf2ac815f41b266db6557304b74b557fce2cd56ed0a6609ae57590d9d2aab5c1f7b12fba01a1b37d13fe60ebb6178b3462dd2d53aea51bef1b4cfd2fa50896aa93ff616876d139b4289c2afdfee92ca1b1a2dcbb2d63233d9e0df3f2d8e89e7e032700dbc704bfda26eaaa51e7d2c522671fcd4234bb26065275c9cc5d99cd5d9d446d99d96a2518da2a84635aac71701925ca8344b19cf92d6991911194020200033170000200c0a068442411064411e07ea0314800f5d8a3c5e4622158ee36020140c65208662000040188e01008062108461408a024fee1567e2b9d02db50411e4b7d4259659c8e480de127d09c7b6b1c56a8adbb0482449e6f239f318fc3bd309249d05870e332bacfcb2f3739354bcddca9b43f0b9391c8440a0fc6ea3e2b87f8de867041ca0558cf9f994385824cb077801f41c3a3a05d475cf4a5d58c77c7723b95812daa20bdaff9a5a2a40c806ef28c1cc2406398631e7565cbb4d632ff4805772cae4437207599d001aff554c61d904e744f1714601d8655d62852c087a65acc777d57c7fcf86eb08ca15ca31919b295752c318d85cc1706e257914615732ba43f93e2f260ea85ac6d0de7c5f7f376291540ec35c1356c1623e1ad43273aab6f83d71dde39a5a39f51a6d719b40fc846cda52e8def910b0a64197b6ed38dd31e46262f46b44efbbf863d7d117c866e3e90d12c13007e9e1593c294e8ab4c57514cdaa52a84a7a45f4493884db5c2195a57294ec4e22473207bbfdb4ab402be6ab5634e3975d5e302de7025622d282bce216e76d208cd63aca4fc876ec7beae6301690ea656405f8923e8bc2c12a3784dfbbcc75e8b675dec3e3352c94a4d4ea1e45b73b5793eea32af345fc53344aa7f980062f5fb8efa3b44a346276c06409ca4024e9cd3b44ed50d1d12c4d74928bbcbe77997dcdf782a4111aaced40d0bfd0bd435d170c5a7354d8f2f44715fa883577945dea787823e161ac423ac992d99ae79b432642ff69148102236cf63a058e869eeb60265305bdd89f6a817da423d648e0690b7bb98d121de56c8857161414d02f068d46f82bd0c112e6920ce14e0e5a5920f9767cdf84ff820ee55ab83685c636cba1b106439583c66061f3e6b2664343e7a25afccd3ef78d5286128c12d5c126064349c48938aab36d829183132a00fb0b33e4d70d1a0676e04f0cf0290bea73a5977e2c56394eb3d5b2fd34c6ad84f4f271ff8a215c086545214972237e9be2ad7d6b97440fde18874c7204024b1c01ee35aef95ba3e04850933ae8b1899333c2aad6268ca94cc2b26649832dc0ebddb1d65f46a3923eb4ec78396bbd6fe4f15fb25c6fcfb1e53067aed66af87e1d07c6ebe276cda7f2b611e9a207ce18b67c0a6c62e24ad7b9d8b9e360f21df12fe1e0b65b887e41fd114792e42eb63b7c6c21bdc4c0a5c292df8ae35b4843a70592e222cf2c62a7417f929dc567298e6c5ebc924645598520fe3f49b05b0cb6c239f4e5911c15cb2406fc775258a64d7a6ab9fd1ba77321ab4145bb97e1ebb5caaf0a98c3a722e396e09bd8917e03c1adaac56df2ae43a2389bc72dcff791bf9230bf96937b0d82aca4a4948897cf83d81a07dc246ca4ef095703f13ed20c580f659b7aed56d4f62cf555ff0de35efcbad036b2d3cbedfc32df85ec1ceed9f0e01758c12332921d08a3da911ce1d53c1fa30ab950381f6ce80534abe6aa60dd24a3470fb5bb9488bcc480135945f2bde84f386ee1b698b9d420b0b818b22467b19de011de559a21883fa713c2621956f1213f488880685418decd1f2f35ad3493d7cf69b84ffe9ee5ee91c57dd9c0299256850ba5c5159bf9dcb98befd94a1fb88a513770d5a8835b9f7873d73e71c071984b54355ebd7825893b298698c8b4d58ae464e143334fc0c49216b8e610bb3921150bf05fe61e360dbbb278229af0f58a989f4773afb8d9c28111077ff275ba8fbbbcb9d78c909f6720cb9f856525fcab7d481e8629718d9d0b404e0a3fee17d43649952161d5d9f0086ce514c515f37de1644c89c5986d5f8e22216076db861b32f5a4695f703519c546be386a2ef92dee3179cb973035931383473125d21635e198fbb0e698df4efa522a432abbd617f2b7a2cf06d9d9c06eec0b21ae048ade97605bd0c98f3c930ae1b10f4f26666c625f3d423c087ff97bc18d853a5e90efa2f91506776c1bc9a8225e81481eb4e8134aa5f2963bc5120b9924d0bbe89b70bec2493c8f27c69c027c0af82bd985d84af4af1d2ed195db8749e60e79e405bc3ff19f40c871e1b647565815164c47647e59f4b92d068fcd80b13fcaa9c8245094a23942d9776d252c226cc4221c9645eccc7720df6791574d8be4a2e46617185e0372418d11d1b0ebb8120c66618002a83b8c9318bcb9ef333c768c9791222e0131e54d0e00f3036e9a8bde8119d03fc470f9b6625f8fe0816d139c2c67bb2c000414700a48894762d6afc9f10d275db13e216619d4daba3e8bd8d35125a042ebdbea88291bb9bd42d0d0b300fe0958a4f89f58533d7944648e14d5f2eccae65db9c5143d904e93a6d3395f5f6c865a31844801716a457275d581abfd12ccf36cd77050bac582673c403ddd8785b633f4be7e67f7e739bea7fadd5c3898d530e59397d988359388ae625da182053aba783cc75a98ededa4174495570204d2b1e19f9b1180feecf7df9c998a6ac85e26193a18577edb7144c8aefac6fcc69716b149fbc0f1bd02dd39c6035194a99d3185fee14fa6e89a4f92ce3cacf2035137ee470ed1a025d358010f6b926214b7b4efd34d39e64ccd9ba380a20e7bc1fb077f7922a2f242c8c04e0b5ff031b0749bd0b30420501e9c4d867f3d3438c1f8b0c2b8d0fc87b204d2f680335948807855cef1618195ca40fb136e9279c92c19b1ddd8f2658213602cb8f77facc89e4b3391a999be6eb5ef0773dd9743e75978f7536595aac82676f2edb78e48f2ba802ac4076b50163f09104f7fcf75154cec06363a7472371f7308795b9a9f08807450d8490810bb5dbf25ffd8f69597f226fb79070c235681b86451481c7fdb24518bb94402796f19dde2219408933437d3edced118fa6659126e1a4c3636b83728389dd9c9f5e2f0cf2e284e2ba360a1871c2233527916068939f3703d464bc87f87ba78fb4a6715f05503a5af058badac47701aa4082f572c20387ae97f1d6a460738d99256b580e733d85e1a4bb012862f3d4ca6a905e8c840be45fc473ae6bbbc6a0240ce546bdf4aff6e65e3b5ed434629793deef40549d64f8d29e24da714a8958c1db7a6bbb89c1864a591f22e415b4357f66b32c3979a399469f3c02f23f3b608eb87206ca49dda44cc03ab662f99472a6e129a09d9629758fe854e71045e52527f4d1ab209e87226d90830c3d451afcfb9959a6681a012ffbf08ead5427e75aaa026494064ac3a2eb59079446cd9d50f78bc039de31766a948c8b2504254dfaf0ab2b350acf638e6592f8d1918541acd46a885ff11c77419902854be08e342e4322fcd6e3951e7eab4c7b60085bff78e6889d17b1c37798a599167f876b816f9bf8b9e0cb786dbf7af0f581fa2b2b13ba407ab1a3cd560b61409119d89db1d323a5e96ab004d11f8a8340486d78fa139fa3c4e64a0a8cf7bfe1ce9fc816fb2c72842c226e0fc5c66859a663a74ead22302ccc853adafb2a941288b6d23ecee8685cbd1361e79dc5bb7e3831ea16c6be6077b287ca67f54353a51e05b4f54444de571648a34647516a9f16c63d93c65ff640571861c7880917c33765dd8d7cbdcd8a8435352ea6eb009c2ce06b212a3abc5b69a240b12c06733ce955dfe3525c5f531ed1da1f07ec520bd675b5eca01f38dc18f0148ba5564b8ca167f067758e66f7b084f60ba934095e4a4be83a5fb29a2dff942c72ec19501fff4644755bc6957039fee7a084260608c84d240cc14d697c51c38a988441604e2ff122a06510184a619d11082aeb9008639c853402dbcb746c43524fd89fdb0dcf7a0f94a8be6f52a67c08ca27a094420cd338da9f521b67f847e898e32faae29d50f4b7fc721daf6f3351a04d4f6dc57b98c69f4ed8e4370c425b2c258a9e09edc84f0e994370447ac9ca8b312da8b852446b9a6c14a4f5a6e0b94ab3660163c942cdaeecdd64eda25e0392a3a327363778b2ec6d1697c6c2cb3a314ed8f5d01990e58612bcfbf2715f90a2d10d2e5d3da47d5630b0a38e04a6a8ea424f07f2ee3e58206114b0f7da80845e8f29f000d428f17117cebc83fc964d392f69c697d4060a92104c42d2fb7513775464d5681237bd4f618477af4d0e126243169845126fe5dd673a97206053e6775c28a9361bbc648658a36f7ea961d3a3ff2500f905c5d1b56b3d5ae083a1d462466750c79a0e545a6bd65f083a8a37fa37903250d0cbf38f5d649122e2c9dc8dd3d2be06325b4d96c0e19816ec612f569764ceb4d874e97e2301bb899e12f174c52bd80b8e06e1ce3d657762c80a38e485f9e548ba2cfab64a830e99fe1d48bb977b9dbe8e90a88111c48d6c749405e763c6163904ec48c5289130d8d930758acf743fff1b3d06abeeced0448a59b95d5e3e1eb58bf26ebb4e839277a3eba59088c271786aa5a06e83129c67c0474f66a7d64cf22f3fb7220b05978836caa26cab6501857e6a90a76991a5bc5bfce035b769da56ed127941372cb3ea144e82dbac412a1b7d427965818e7c07ab3e1c14f0ef1d8c0c7c8d43ce8a8ed6dd0fed45ca5509ae2b4dd101ae98e0a4e5855374fe42f9c098e782630b075a5d46773415d22c4e3a0c14148cbd59c77ec74624fbca9b72a85aa8c96843b8265cc9d2980e18b91c63deef641c5296d8faf99299b014050a6f10364b0b7e6b21020cdd9610760c27e234e50ed7f8d05bfee38e4099c8bf30883f2551d7ad76a13b35239ae4f67401bb1d2dda43c64776c2200b016288d6594ea757a5964d45195a3291df753be0b95434a2b4b058c3aac40b27c069a78f88e31c304c0a5c4313c2b8c9c605729fb5489e272a550b37eb8850ced62313f901601178b9c4dd55b84f8feb0615a459f66b9d8620de85ea25cf59e8748e3f1a70c1bd40df4973f92847b113a84865857e25c4acad1074960faba0dc24207d3ef532d162d3152fda7251b1ed35d613cb82a59ca6b211e166a7488e947e9e2e3624deb6cf01a4b0c2dc4e66e6dcfc132af83aa4021c0c506c8e656db2a2571a9796b3ae2fa74d818054f0b67c331b5055e4450995e0e30f9da2ce53384aa33618d25d8d1f701157e3773a1338bd84a21776d949163c8900a3b02b32479789f191b45a8178b1fe76b3bbcc1c7299c2e031f47970e9a40241cf9af93393f83a58c9b53cf14cfe0a20342225f54cbb0eea5ff5bb964c27155716035599b4f0f61dbfd7f218ef330b858f8bac76c1b46f68cbc2b6691e61a221f7db57d1f076143bb60ee69cbdf3a904dc97a7d0387b113063faa1077d7969d1fea81ef1150794ed9ecc83d9c070821eb114de093368f83a909e83c86f5f908d4fd68cb9ff79b457f1cec9f3efe560270655c50ac68bde0de7fd657b0bdd449b8d37f767ef6e0f94f6c05fe51e95e8d69317c83515d09b97dba196a8e2fe848998fef5de8a8ccc1256b7ece8859128bd8560688aeec5a7068e40d81c523166758a78f94b6594e37e1c97e9c396d8a0583c212ca08237c4e145f576e09b710a5706e4349e8c09918779a1d2b2368fe85c69e7b6500f83ec42dd8ecd7faf37916800a56ad0cd32ae2b8690257ae99ae3c351d48e2905075dd2be1d21b30088465ecffd19832ce8155c377b1d96b06fdcb1826cff1846339cdfa59d83a6804d7adc861407fe96ff72c3c93fb5be5ea3d2b767b91e0b02d8ef8aab0938a17b3283c9a3bc40a125493d18b1e3e1a8950a5293670c75481901215f4fcd865c94cb97bf2b0825c1e6db06fe233444d826edc6372bf5666ab5d8f56d7d2487a9ffba74b7472bf372f9410522e676e5ba869c30c1c4fae1090df93590a9b42dea0d9797d1f0ccb05fbadc1ca118a31451540fc709f351bb0007ac7d188273dc2c21f46c747b61aa5347c47c88ebd68ca45ce4a730241d17848f94b275804c3e1bef0707b75ae6ba26cab22a9db0168245fe557c78ed63100f7c683e91e23e35fc3bea44ba432d323cd2d6c1a73a9494a389679e7754f540bd983b493245bc0883933e66932277cedcec4a6058b8fbf20b07baeb1e1a47e1a3011bac26e2fe68458844d2ef96973fdbbea5aa16d0eae820c41124960d6e64e187b0c33f19a486c07e64e596a7b4a0ca37f31b592f0d2266836e7c95d3d76067f9eed196002b770c9bfaf317aee8c0625674382395cad75dbc5a5147728e11a6ea402de06d369ee3137e03ef91342b5103762317112033d092b1adb79775cf664a6e2f11a8f59ce4631434aa34db003a6e244a63b1bb83bf4b9d65f47073da93c3d70e1de618384fb5a3106296fce5a19f6e46085877d3068553e76cec1e5a4f0fe4eef501dffd60d89383951c3815defb94aa182410d0cfad2f83f7fad894e0cded27f44afbe0e45654eb014eb1908cc0d94286a463b2194587d09aa4bd9d4b98e4806d5e2ec18d04d7e1489792ef4ec013e23fdb58fe6ffdfc26c09efd60851a371d0fa89e0473f178c977140f5b8bce688276dd3b51ed53b0d7e2c628e4fe6d74febd26b8a92cb0c2f836e2120524be6a087ea1af227cb3223ca58bea90ac14acc94b52667383cd3865f8fa1d08693130d551688498e4a07e9f51b18753a2d4250ce22d04700312d861e1670c453bf1835065a34f649b000c40c99020e7ea86a59b4a5552323dc1dca9088b63674b1417b0ca684e94630ed26f424fd3fb60e0bca921b823cc81b79dd7d5af54c663579f115a7dfb40a693a1284b197f2411cba7bf31291cf0a0eadce56829be8c92789cac0cbabbf4c92f904682e5a6cb25981b2a86f375ed4334bfcad0964d647024844622790b31e4c4961f5f7b7d89d0e0fa3c75e906160aac6cab1f6f59c8a16b88053de04221e01cde57eee32e4ebcc195c816f59b7a1f78535cbd0a4edb990da15da4515d52900ac1d3486e8f598e508cd4929b660e9ed3a1d06e894f70c0252b5048378a9bf444f1bb812db8b569015ddc3f06db389df4ab880b26ed4587d7da5dbfcc8a3c76b4822c5c04ceeb61c5b0a148b2bda2829178af5fbec2f7b81ea0555d17baedd2272e6d1519fae26e7d8140a397c96e5b8a17f22ead94ee66f8322e9aaa0b4a914146068e6203a51b1fd6a8f070d0b749d93dffb88448ff5b9ec11976b3bd2e5381660a4f2b4dd2adaff3c8a5248c36fa14eee0d313481779cc51c7570a05f1945410ac952f84c7a703cf5a343fe39d15664947913b6d43c94b097846731a1c33ae520b73f54c1f1fed389144d45070d70c76b916f28bb3cf101dd1ba024229b11c068609980a984c9ed73fee9953c0e2f878c83c885ac3b65322a9c7b6297ab26f89b1bdef3a083b6146c608386fd8b1e56f989b21fd06797cf1520b0a9e34d085a8500a69faac2a1e89b9ebdf9ce500be0b7ed3605b6d4d7c7274323044ac5d7e1556d5373dbcfc17259ab10f6995c6a7e96137e4bd790001d485f2ead99429772ad2c00713864c9db7f9d7d9fcdebd9812eb58936990d468e871961c0e7ce0723212704e1027a15d0e86a1ccc55291482681394a7e0bf4f0122568e67e950ce98def97190d0d22172151719650282dd0bd3fb1192703130d4c762bcdf73a21b268e1ee3cd46a8edab28d52405310fe0e52dd3a8fcd8b078c944bb15a027401adf1078a76b5011719957984c5d1c6add8f1e7bdec77be03d3f5bf798ab291518b764ef6d041cef3067be384386f589e3ff5319fdfbd39f7e98322753a59a2fa901a218c2ef7537da1d4cb70eda10643f3984f74d50de5f1cef39f261cb7604be9d6e6a61812e39ae2a825e4ebae53c2316b9eb0498019cb2ee78a3c7184d7c683d89024aaab8eb50671f74edf77ff54951b088f053465d2589afd44db37f465228d1691e0ca6e23c2f5d7a524b0d19705984a054aa3fec455af64bc772a637b19aaa2f47f103bc6f515af69cd3848bab14f822d2e60ea0edb0710ecae3a7f524312cab5a9ebbc53a71a2aee616a18bece1909355471290068396b794b24917e2831804e27940594fd4141d494008c0412bc86c80107462ab281118e44fb16aac891fc40a188cee499cd84a5357e77519d24b09938474c8fe226556a0b6e1db8349f48585105408397861a191f7158aa3c149f7ef86686af49090da420f88ddd39e5d3524c32729c4f4c4159634aa8816e1073c6fe58e2911aeb4d7c700f442f8c6e19e928dcb17ac606b57a4582722dd5185198a9ff40f3cc56956acea81022aca8485dd52b45311c05de55e3abf88fe0abc25fac071903d170d096fb78721c03a38348599f63df690f3db0cde1848367936835e45cf9427bca69e59dcf3db3cf50d22d62e8a4169f66a7e47b5e862e9c9ada71893a49d4684210e7d6667d1f377c8932c870fd61957854b64138725b92ceae5f355c4ad8e6da79c7f207480f596b868ca153df563f8be427fcc9fd47a4c0d548c5480820c02f309a627f5ba7b0bc5001ca6188bdac367c5e6824aa54fea86891ad9db9b1567f8155d82bf99c135d4d8879261c9a1f53956d119662f175d8eebaf0fa806108e724bdb00f13d889f1bd63dcc62165b0131c6b88490f7c1d0ea7d103542aa0d44aab0d4aac06e11497c9a81545a544916a9c07c88fe5878a811d55fa55a83cff7f8fa46498ad156a0cb2ecdbb1d4a512ddac919fbcc1194359735e93944b23b5f7bc272204abefcf57e7c781939e8516dc5871f2b811de55ee8ee7032e055b50d0e0e2f05ba4b9be0eeb124a1a3b08fae5c8e0c3a577b35a490b7ebf06bdb84fd40f800445dcc46b62c376596c500b53decfc40f8e5cfcaa147bd15bb5d8c147c956d839bc34b80ceda2eb83a3c59e02aed833b979103ceda56fcf03852e8aadc040e9f25491e48bcade39b719d77ffe1c30836cf9781d398a0f195d514b29932e5a0d7d9ab50ebfbb5e4488bbc1786249b1dfef4ac9cb5cbd96fe04ccb7116031ce214b7b177bf5845c744b872164d53868c7925639388700e1d16c02a338c17999df313192f0a64202fbff034ee8a447e3937b1a668c03767a01a66c05bf901df7d0d68afb5ef017ea94f5a7aea5e42f186740de3a298391812a434d66612446da8cc947ea2d9127967ead3c252cca8227ca76a43a6ac998ddd105cbba6cdbf11f0d32728d4007e838c8ecf5415ddc74147f46328ea23523082c795e8a53dc49fad048387b9e8e788b16eebb4dad5a8b0fddd208744b24bc2d9b11768451ca2718f3062e25246456ef72a76a10eab18521a0dd124c5e3dd3e4757bbf4b85d11a5a0a1a4323fb14af72bf5300a407725089ff935f0db13163d271fc61081d245184044949bfec4e7864fd93f9fbb4f0788a44aa398cefc56fd13b7b43cd55470268ace669f5d31a8ee0b31fe5881027b5dce27b0341404cdb54a3e6912ce48473e53200256f8d0b7920b5e77eeeb0dd784afa56000548401e9255eae1ee340e193e27f22b2250ace80b692a1bbd0da60f0658169f50c821108b716d3f9979bd7f0826d787583a1d427be70a103b8df71f3dd4123e0e7e3576055360641c3829c9f110f4ae6665880b7d02bedf6fbe25bd746075511a4ec803d3bf7b0433d871de875d8819e830ef51c6a4731ca5756aaa310edbd278222ee690150a8ad1a32459e5bca3d1ebc11218767fdf34c71adbc35ef5bf9c227062e91ab48a17859bec91c5b62f7566bfb228be6478af2e5b940d11f833271a375875917fc456f0c640dc0b88cd0decbb851ba2c5ce130dcefe0aed541c934515305ab887fd8d4b4b725495a6f9c9aea39aa04cf5f39ea4e1f7661b0924a12b6ccac0da193f149b5d028610e94eed260a937814e85619392ad3fb9869fc311ac0dbd4548a2cc155c317b305f677d0a90547d396b8b23327d853e18290e1016221b889f26f9dbe42e6ba1f49526fbf3f39990abd0e0cab5b44e3e2f1364b4618329bfa0d8340914feb92b6e8848f5904228ee5699916a39e0ad62109e6b0092ba5dee4f97a3b69dd5edd583c6e8369d96d2a9ed1e6173bf6047d038df4384c2b4137596208b3e3f965da382639ad5556d095ac9a2b2fd37e423ef66900c701fe33cebbe43c1a5cfef6a62df2374ee571e5c8672b045daba3699251d15ecae9baca37a02c25f8c18f9a8e13a8a15601d2f37034905ae3ef126896b62073c57bd4767b8c625c94336082f46227810f3d1bc69a5e31cf1d49397334f3ee93cf7978a748b0d35418a7a05f65843519d3a18d03b692949b94baf3690b38fede4bbee8bc4957d3b565f2c71bdc64031a42d545fd0d536137c9e9e9d44ca4acd6875a9ccbea709a590f5a4fb410fd4ee26201b4a32188b9b6ce776d2f2de96eb97fa1fd6a191984468682f3065e980d5f8a153496f10be69b455aefea116dc787554aee35487c7645dddc826f43235648ca190bb1ac0239b980fac0eb0ddecd02033e82e9e5bf0a52b05fe6f11ff092db77f0bc49ad05ef7b7c8d862c62c89264ebec4dcf2e548c8a6cb7e110e726567237b219d372555f34f40ca1fbb50986b199b4087318efa41baa10f6a4ec51f14921a5ebfa86855d5a0c1d2a76a7eb14c67628ced0effe6f89970dfc1ce90138182821200e966c2cbcdc9460529b1d3229b2ed12cf79a48d6e0da2f89dd2093725a39194a1b8c383428a07dbc1c11a2420e214fc07ee6a9334ed720fbb3802d34df4037e519563a34b723c7523988926f6296eed52d93fb22604a88e53ecffd6f8f7894b9682e1ee114f2eb5ea233555df1c3228e762bc09fbfded5ba17961ca98d05de1fb89a895703177d6d31cea923e5ed1c98c5c51511c1bffb863b04eacdc2b4148a944d45ba7ba47c99e4ba649afff258a3b037959d97098afed20ae83348533f8809928a10f523b507f9710992518a61a58b5f29792f32ac0bbc19451edef14d8f568ca67ad56d1198d69e1d88b0296b11801e978362f12e385279574a73cf02040d69040451d43074e2d46d2116bf05f4289d2fb78669adfa8fa284201d32d44a57476a9fa3125702c13d5311f7311a301a4c09c8406eb0410144daccc8e1ac357660f17cbe2ba9bd1ad52d2fe67c9ab82ea9c1cfc9dac77edc35e490986a1d1d69da4787c1b3d22406daacdf9eb008ea16871cdd991c72f7a3060bf0f0f04f5734dedeee0f6150fa7111b8a4561b130dfd006ceea74ba76ad4ec005cfd8d3c2b7070f10faf0cfadf6f9109354ee3fb131fe9c262174390368b9c4763a82f17779d43638c4d9d41ea58dcabdd8288386c508848f231882b87acd6df071581489701399873121583601a428b70fa26cd7d55c91c7e207290a2715e912d4a129ef76d65030bd99b06ba09fb3043078c7fc29ca0768767e2dbe4b9fe58e9877750cacc9fa262eb15a4dfc061138373a69775ead784fb907f83e0e6d03ea970470e2e8673e9253e17f9e10db1c54f781951bc3b76dc8c88e4f4ab910804c0b4af147badfefcc47c98ac491ebb6b1d6f0bf830b557d8f8de79e1e8cee885bb0f6c2bf0f0f0fd22b21cc232bf7a8d7ce1c214760dd4c037e3a54de7ac1548a841c3b731e2a5fa84af02328f1e09162fff160b5eca8a42a738166aa63bd3d804d983356ae33ef8b5c00a353f12a0aeb93d5bd147f7501adf7fc97d78a4173614fba11da7df0a689c539579edd5aa4fe5abd840b706580bf8961eeb1377a94585f84d6b5a03331e0745ac30632af46caab605c0f7feeec3a085002d01a2820cb348189865809b1ce2686d83715d13243f897bf36f6ca93549fb2e10d348d31ff46ab9ada1a998cbb16796efad31c007428e408422c6e17db02625f087b3a8cb3369b6fc816b702408d50afd2e99d0fef8f943b4ddbecff95adae4ac43ccbbec3cbe2cb548baaf86146f2db5663ca1747117ed99e55aa0837b350386013e53dc732eb04fa1e1b4a41bbcdd7a19f72150f66045863e5a636c8a48f33438a640696c7facfa1f8b793e26ae262c7dab3e33983f480d5871bee9aee37cfffa0a8429a4a9fd2a308926779100951fd56c2823a16b63a619885d24645f6ad85413bb8d88af58b0adfa33bcedd7dc5d1e66c60a7f55da8e2991ab0433af8e5cf1ad04b9600cd13db96fc48d6eef82b56def2eb293660594deba7f8705aa1163b21953eed845b013fe5ced8b4beeda6e04c52502c46dc523edbf6d991a7d06079c23f1998814c91d8b26acc689af5d8e3f72b910a0b01ce60d62f3a4e08b9ca3161acc08a46269db14eeed8963d71132c28dfc1f14c9db69ed2043ca7165b382544f4b138214b613c5653385774962f9a64b8f30849401eaae91d236527d21507904efa859c1aab094cc76d29c85938c83668155112ca7cd02a9247827d9a8b00befd35d434adb91ec111e8bca492eb7f05b540e823a392d5d0852d88228775893aa0fc4d44d46594bece62a8479fb34ab9a6d279567f8c9da2043965165b3015412bc837817a928342374d02ef5660b8f5e130c3fed1a2eb9b173d2f8f8a8e784251bfbf6089d4902233d710a4b9bd89112e5eb87a26340d64b188977221e11624942d4ea52e1625bb5e5a7de4509fa4ebec775eecbb7754f9c3fcc4c9127887c65d5f4d66ed110dca43c443e0cd634b48c625dbf38320bda7a6f499f6ef04e6a0f210e9d7e4ce916911a448e0ebbfc74a950d2d83ec35bc9ed3507435adcb89308f64462b9400c4ec8c66b5e034868767384b86bafe9251bc27defbc04b32f318f3ea5ad5beaafff955a7fb3b634c2579bd34b439480dd77b4a0bb1c4e6e325b9bc0bc84326d0539f55e0d1f1b5c5cddb3227e2a183acff2bb3fb05307cdd0ed2ea0fcdc800b844d0cc8d0acffd0a3626a208c1e9fbde6293d8d0033b0570558437f100ff8c1d00ef3d5a7b510d8bea8ec6a2205f33d889863215c2ef6bb824dabd04e120aab7cab7c5c4e54a4f4c66ad0c0e2c66a9aba3337bb83e910e62bbd61a36048863a3c4b431d429d9f6371ae103707e4e0faab918a01d38c302ce2b09b02f03087285cdde0713879642476f1081762b9f83c1dc7e27b36ad72fe63c7275053e176814e8ba808a03e46b4ed449727b8f165fa3b011a6496b1ff026a893fe0227c95486d9e6857257f7f90fed0a165221d73c53087a1a16ecd40a05cd693b03fba09ba8987d3c42b7a72719268b0226720ceb962808ecd5bba6a6bcaeeef4a9d02dc91cdfea0b1fde7788e502aa0b2b98725da624ddae518918fdf57421ddc1a78b5366dae9794a14eb8fe1abc355606c95726288616de6aaed1253aac15d3c0d5f6c547da7670aca0a8b7e1eed977905f671b5d3ac65543b3edfd4dbe246e555b1704581ba93ff2ed9d2a5856d060b58b3faa4593a605ed922af208519cbfa506a01e0f7a270bf7934e10ad4339c5b2da2cce04ab262c7a08cabe0b24e6dada8fcf6b3c690407f039dff0a8664e71824adb28f5de87c00ec39dd7ceb22a19b71555682c2c5335b7cddd200b130a814287e65581b65c21e4add2a7ff4a6b3dbd94650d604b9c786b60ff861bfdf8fe447a9233674a25359c65c6b26eb8329933b19ed6459b362455f6b80313f9b1e7cb49cd2d4fa515d411b49281b7a8ad524cb94654ecb7b7b35a618b6517ea7e6bfb671094e46204cff485f3d4b35db042d2d9144dd38f7bb92ea507d22bc9dde57db70a82bbe44ad8f7aeb4c6efd9f82766f11bdabc5bb8442fa4215965671cf8af579b5e1ac9cc6f4d5c63765322253bfb174624e0a26e2c316791f538a166b76bea9ad92cc92e0a5f11dfe9b9bdbd7a8bfa62260c8816449512cf4557e590e89aebb36611277ec4db3f688bb1910f8dedf6f6059388cc9136a72993512d2761a508ebb4edda68a06dce7516355f8fa357b082ecf78bcf6a1965eab6a13f25374156d28941040fa5261bbc2eb7db66f39d1b93af3d9e96e50abab6e54adac4e74c9f1fbe12a6275f57e283e9d8de83fea5cb299fa3aeb60697a1f35368b946edebd2ca494e34e212a92c072826a515f13da1151dcf702e3a8ea228cf5cfcf7d187cba3ea4f00af7544ab0ed17adc3d8d0bf6f9cef3619bbca22f5d838fd58b1ba5859064e53a7c97b334b915052beacf0611cce617bedcb1ee65540396a44c86c2676abdbee37823ad5f22cc7c0946dc2371d456cc8662e63489ded36c4755cf63ab0244462b43251d0d39e638695e2b9fc04c3f6a051776ea883893835218584c174adf4ad1ff53612f6a556640afb884723b37b4087834223dc1b58dbe1f6d0ded9d0b3581c5ab754fba242091b8f0e15749402664462ca0ef389dee40841b9748685d622fdc10a16a2336f0abbffd818e4d66ccce922c903aca5619d24e1b0084d54a29fc3a4a1ab82c1308d916526ad0358bd70a3214519ac52599c9bc864ceeea268a018876d98c282137fb4652ebe76896e9c8e2e3c226d22ca11a0de7489befe158933308b221f129956cfa7c84602c17b93ca1084ae300dd7d528b1e940f412ac97a98b634c457c83372212681dd99f0c1d46a3b56e66825044de22a2e0dcad88d870808a487d0def45a1a679aab215e9900d63a6da21e73be218ad6f13fdab5423fc4c796c2b0d19acbe7aeab8dae2110b64d4069812d227c42d6815488f58d6d5ae6f52218b17737ddc1e452d4a7b372706fd012227ccaacd432b77c42dbb732e7a4297b11b5ac3be17d743706e9c77673477bd98d89e5735762da123692ec439f40022fae148c816cb04bbcb5b8d9107d56b4d0070966880869aa7e3b6193173be21585f4e75fd1cbd2339c99984ac97c943d8e4fb06f6288dc37c008a5d17625cfd2ba8248eab0c0feadd56f16e6178e783e7e668646a16402d1bc6557ad4e061b1fbef7732e17e3d3745dcdcf68c83ea9bb09487222331acd3184a323edaae6fc03f9de8b8ca13270cec68bf1ed52318c71e062b88ec8b1e188486bcca0883fe0483c96eb6aa65c98e71fb69adc89e6eb174515c2573c44f5720f351df38470765dd52a8dfb2bb61230b5507bd2f9f8850e0bd0acdceb9d4d104c855fa5f9f4ece855628734c54ad558fe78bac127f9ea3ca0e5a4ce7bb717e30696a50cdc3153b1d8b7e50ad5b4425be2bff7a07108ffc685a93719ce093fc8cb79d494299091a9b2501490a550af3b06e5164d0189449c9617a967dd5b2ac3b0b45b5da189a62de4b4ebb81dc14af8c2822f57e6bd8e9b22bf0e09fe18e358b35408044c93b3fadc0cd566275ba4cd858fb619ee4463ac8e7519caf7c99b532310b586ee21d33011b459acc7fd773a1b62db495819c1d1d67501b09f5ffde4eb9782659bf49c6cb557d7c09dfce702aac8995c582050524a0769d62001703733d18fbb7a77d3c502c8777333223b6f5f409f0a6e00ba485774fbbc621188655420429dd832b9e5413086c4d6e7e9ac1f566d98c385529f108b8f3739a7ca031e939690bdc99652ca94924c019705a705d5054f8adfa1ecc6b82af3570edfcec81350e46d12b3b37312e748f2ed354a5a1c140b5d667eccfcd8884a0d542393e520b5eb8afd20c93899a9dd96c93a8643662403329a93d26924c32193e1309219f940dfcf80f68767b76ccae3a451f322861f24197ec0d6ed1793614ef19de0df6058ec9661b7fc73a5ce3332a5b9e1865164217c1a1ba802bfbb1884df3e0c6bd8b099633718b637bfac1f03411f4fee981b2cb058e24c9402cd7602e4d0cd2507e90ed1873f77a8053ac86f01eb57df02eeb7dfb144ac0eb0100e86f1b2e1768870860a21a13c4f1f7e3feb57bf02f79b6ce8067459cfa99668b58ebe60fd13ab6101d6af9e0456d791c0ed137defdd7ad44565ae9d3b5cb44569cb455d56e8a3944e9655c0ad0d9f47291f7646d2e5aa02f086bb945d92917b0e1682ef9f24618449d0290fee0edda14ff9164dacd1dcb0c7171cb802871f768361efcf5d4c968022b3587d16f2392995c56e30eced736ee6a177b43dd0fd994f7dfbf39ea3a6d454ee624d07aa3efef67af2e79cf53dd4608ece886149b38393d22e69be8c72300c1ae5488233cac8492c14714419ed0ffc39238d9aa253235c1f584394820131ad1950db5935fea6fa079ffb20470f76352ca0fd7c12b407a203ec4898cf7540563f1f08f75653f5ea6e480ada02eef7a805aa77861d712f203a60e0b7dfdeaafbb9471fa4be6ed64f34beef98bd8f91be8fb1eb39e127a008fdba3cea8bee3cf48ebebe2e08faa6474dd129bb6c17e0a36d46a3ee9225af6800b5ffc5e0bdaa9bc160cc68541b54ba888725222879522c74865bf5b387e58579bddf5e7c247b4752cd85c084727d2b24f97a3f77a041c3b0662114e4a3e063567e1faefaa0bc26fc43c3da60b241fdfe966c50bf02e450ad03a20309dbabb68e7ff46ccef7da239613c775405c70b4750faa7ffa35a6252d657b93ce89dad0fe1f3de472edce5c2130a18f95945e505f376b78c714599583edfd46676c504f8ced608526916c6dffd64191f6331975e9fc590bfe4cdb465041c8bb73c4fd9079b4e158721d6d3f9b5a277b3618763988602f15ecc69bb1a37f6e6c9dd6c15ed5cd58eb426042df7661a7326c4752e7a01e1912a772fbe61b90a2f1a35c39c04de525d711f7db6be98fb86e47ff243d1ecfc6db304e7ca90e583d60d3f8b9a669ab69ad62f99bb0414ce84b7adbc5075688032bd49d0925bc4048826e9db97af887df9d36a52ea17f9e09fbba05fa5e7b62bb401fcd4d0427f47111a687786cffb49f7a54a534955cdb5352622a49180b117ee2299c0512399264c90c30d87f8a0f633cdeca02ef68fe16392841507a619e154a0fb279efd5a9ef65dca5a7234a6f93bbbb495868a3a2c04001f53d3ff114be618b9e96b5f1fe3de7b0448fcb063da80d7aaf003954d501d141eb80a8b8be00c010250913fcf74248a8f6aa7f4c3d64c46fc4ac54e7b579fc70d4a10cc5ba22f5ced4e5babdb7b537145ee556dd93da20fe5e81ce1a0aec9c96fe283e7f436121ef27fee17e5be843f3a418c6fd44ead2fa32cb29be11bfa72950a074b307b759687ec8af90098d2238a13399ac87f888dfa8878dd5527d9cd0998ce849719911f3b6348e2ee281c2976fc43818c6463286bd95045e8ddd0f1f3d8ceafe701b1b6b6049700db030cc08ed2c5d5b61183f511b2b959f060848d0f78dc34677ed4c69e24c115c3821035da38deebe6bf77747d8d667d6504ee812d18895ff7d7c054041dfefcb28279066cf3c6c1f948e1d4649504b323adb3073ce09dd656c23a8f8a07265c715a0974149a9291a38d0d95b32e74b1f33094fd9f580c1e60c208c5932e64e538fa60fee00f9e08e0e3d74d82084124a081dcea387affac9cdd75ef08d7aba36c8fd5b2950d812421f843fe7ca6eb2508c51babbbbbbbbbbfb4709fddddd2184504228bb18a58410ba0799736ec3e80e1db252985fa8ef536c080ac4b05884a907934f0c3d7c62c8f223cb0766621f98f121c9870f2e29d5950d7af3ee3e33d78000accc4ec5f6623498d5fef0cbe801c371dceb182f34f6e7ce4700953ba8def950568c6556e536e889736e896270eb04112ece14d7921ae55a3d1c171c1825b83251d18c9a2e1c53193541d4a066065b176a6e78e2089aade74f17f33c00ec22a067837f062b9451f90095e18b7b179dcb93bab44da5496d4a1961b37c83debb376c56bff6e515b17a3bf4ea2c34277f0f6006dafe8afaf7bddee138dbeccdfab57e79bf57b74077b7f75ef3aeafbaedeb9c615d101eb6ad01495acc63b6e1b9778c6d677301f273c844dfb7b717bd18a530e4564e0dc628068af1d65460541be73c9ca81f042b570ef0ea2ac08d03c3bd15e2ebad0df7158460585193b3adcff3eafe8a5e118c1c0b747255be603f46c698f6396197295b08ed7faddab816dd60c76383f8dbd9055c7d5f8d62f2782178433d14bb1cef674b45e52e39bacc57142315950c7832cfa8e6490b13071aeb463d11a2754d5a10c9e104ce364d5164dfc3e1d78c2d9ee0995b8cfa5e9bdc9ab026768a8469e2264c932492e468f2d4a4cc54932d4462b0a40916177230796a92030c39625067c616ab2d2a28d228a998a0abba659690335fb004156b96989ab1450ff5d53b339f38d4bd7ed97689fa372836f3fadb2008e17747eee4c665e8fd7689f60d7c5b8c1a75bf37e879436fc8deccf2f5f419fefff7f3ff255a281c00a06eef496d1d816d7b34c4d0f7bc425a66a1ed7d3668efc93017f208294fffecc3d7ae0b4f0a697f7b1d128100d8201ad56724a82d63610e8012c4d70b871a0a6a77f703987e1b73dfc27b481235ade18057db23f42921edd11b0b6187a4ec5afc3282720c6bcd39f715738df3b8e49a3ee77b627a7a4b4c52e06842f3a21f93944c6faa3453a50cb454f9b469896ba8422a5555fddb998ed47e9eefa9ca078d787f924d7336384d1bb2a8fd7285d49409343528a9326ac8c10621b53f7e2b69e34f08ba07752abf57d14eaad4fe5229350192232cb4f1418b0c64e80c1c7192e60573b0d470e7a87bbaa9cda4caea4f277d0670c24265eae402538621a175aef91afc9c0ed5d7e0f91898cf4ded6175a5477eb0187ccfdd53e1cd1bafcb3bd2503cbd856084c6ba2f89e2d31831d605542a94f1b99bf980b5144b40abdc71f2f56283fae30b06bb7c450662980fccc767d31cbe4c7852959faaf2ab2ac7c86cebb335d7ba435df489b8a03df87dd3a68cd09b1902b04b4190da833fc80c292857fb0d104e60a0b346082ce01c6de526fdf7b0f7f4bd6b369c49f44e581bfd1b2346ef500a3c0423f4d5857a3d9628a8f6ff581c08d91756862212ac8deef7578f118e213d1bc52bad9078b8cc204ae0c081da32840cb8288171c4164e454481c39d2a48b044f2fb4bb044f37bc2cea17c4d77087d3342bd2e73d0550f78bd662e80efafa9faf892af13de1d1faf9eb0411bd4bf856084cacac9ad1ae570811ae5a8e1ff6af82fec1628bf11e748321a52012a34d0796305981ae61c75901b54e0e18a2f43aacce1b2492e0423b4eb8d20b506854395967afc5822a30deaef7e11b6c8036ba3bfffb543550075f65f17aa0374e85bead1ffa3bfa7e17052546a62b158cb070eb5380ec9b6ce4c56032d0be06fd559ab07013ba4816d0e07ff20c1d186c18ad61999d0ca603d243ff62e17a57071f0764350ff99cb9594dafddf5b188415f013fa0e171478776a8702f7bbe0ab80fbadb34ee8cadd6e50bfab3b574fec7192214567aea41ef281f0bbbc0d5c3d0bc7d754d12ab349a1995031192cf630d7ebe81fe8005a4fe851fd9dbe14ac4d0cce8a6783e09ba13c15fe91f642454b8a4d9482b97da0d88d1d3d33599d3871eac25d33a16818290dacac87643b3648099dcd5ac2081886837fe073b3258b75b2961194ffcdb633a7a8cbf57b3c686efc0c16920c1692cc13d82cc5828d1de8eeee32419779ab1d5f1b33a0ef9784d8e9d81c0c8bf0e3c71d0cdb17090c731d24f8eff00875f8eff00930ccafd0f5ff1ed221f5efa53e47b2c8b1c116385cf1260d463c61d26036bcf0901ff590c308951fb65a31e861e35a1c6df53bc5f1a68e0005ec8a940066abe56e040c9aaafb27b9bbff5c71e25a315595d5a684f0b5093f4a18dda1730f61c9e101863a8b7da1b40bcd06ca7aa3ca32a5b2a14ad413ca5337aa0a5495396160b1c413059a1733160511d6a493a3d4698917565030f13899e198584e5db62998564e3fbca08a820ae744a505edc8e624c585d98649e5b4a4885cd27a089238e9e428d21468669d22108b94f2a6054792622a42e142235111064ab9c111468262caa5848101a98a3652867001a94d1bfa949b934694396b9e682bac493297ac19b2d282b2eab094a02c2a92984ae285293142a684602541b9ba65a668c02686a586ddbd69143a4bc91de7a370bec90e5f6854833effe046485b0b5d92f9a3eabd079fe572fc8af8d9883142d8cdfa7dbe51cb97eadb07ac2aef9fadfaa91a028adda806a83e2ef9d39a1c75692ffbc1317bafadbdb8ce15d283daeb4df8b29ffa1e0a66000f601c6db9a0ab9b06cf0a2972113ec9b55c4de3c15c1c6d7151cfb3b142923db5368db882ad57e16b2b7c3dcc3ff360caa83da032dbf6fccf9bd9999dfb355b2dccdcceee2e658c8f658c5d3b6c6666a9cd602a468e0dbddbdd613f8cf1a31c5a282323f8fefd504610caa11a4a462328a3308b46c62adba3bb3b994e6fbabbd35150551ff0ddd85d20189d2e9959ce7e1a14b3bb2547e8eeddddd19b8bf8c5e9dd140a6cae908d67d6b5e36cd6543c4be7a6bd665c5bb68c1bbb0bc4f35ac1e8749e6dc6636eb1bb4f19359e2c1e3b8cdd4d51ceeea6a97537699aa66a9a4daaadbbd55a21c5df57c4418faf5fc2e89d97c971dc8a9bba69d5922c1825e74b9b589a8c220b374a8d9b9ad454b1a552a936a8e5e05d349e4a7bad6bbd14b49fd150fd0c469dedd4b6535babd5b9bec5821a5bbe0d183b1e74a82afa2b627fb845ad6743d69d8a4dc9a6603cc4833ef138a54c042a1e4fa660d12b92cd686d85d4258c80612680800b990866f098d25a6564349683d38b2956c4900285aa09cfeca12942d37caaf63b03aada8daafdd250353055d37698aa1a151daa46458baad1404bd53e562506d9a45c663d55fa54095425972ae5531db654f9ae15aa8c9a01982aa3762032e54e4ce33142c29f422a9c82640a143960d97658a2650e852ac00d70e80287a71a07892c64804149e988e994f65434fc8c324740d3bae18b0f15ae980acc5ed800fc94a5328dcafc7444e51b98540618a1b3599db6a83ce9d360ab7b827d873e6085dd6c5f052f48ad2d84e7099575a3a4f8e0268a1c26a4546992b23404290d540a2c30d1260a1768a2c8c112a58a25a4292c51988001498d52143344909a801385cc10242696e6119455b74c136536209ac842441353b634e14489268e7450b7cc1310f2bfe0377cebdeefbd08611c9ecedc5d777c6cc3beb7f5c573f177dd1ef7de077ccc8c1423945383106ab383f1e5c31fc318a173c3e8febabb7b97556bb65dedeebff89d79f7c541f884125ebc5d00781edfdd10767b8174580be5a67733cb58f93e3e1d159f85f0cb8433648eb0262614013956d41047881662b8ac9d2a72b083c40a2e9a74f1a60cbd4103511165c608940f411071133c397385942655cac870e424b8bbfbbca2fa162aaa16230a3a83c1a2a414f19970ae6cbccbab37b5f7ba1938a0b3196321e601cc40d5b4084ee8fc3d9a2d17efc917b08f9e518b29e281ce7f9f238961cdfdea674f4413b144dc6fc4dffcaf1dda0e4260421f77b39cb6e71506f8687bd5eb2901f9b17a95d03f10d89ffe59070db7cea87fdae74149a8f7b257c452ccecfbd143362975b96435f883d41ff0d51e0c7b30d83f869d6c7b94a80ddda70102124dc50619c3f605f0288f6498f794e93076a42d574cb625891dd85c5a38226e9961862d42efe55a5c94223b18253d21b26431674d155ce87c50c4116fa248c2063843a8d1cc7c004683a3b1994ecaa7d40027511479a3429d2257b0400921c2402951c68a3441ccf152441633da8a6f9765c32b25c56664a7f2f3484189a76e14143475d68d8222556701aeba65daf800d5ee8a0111e05d2d10b45f18bd75030804998b000778021ca05fd3b486dd310d06038add007a0274dc564bce90afaefe323e84104608e3b666bc185dfbae6db9dee57235d75e213d97febc5def72b91aba770cc6d236bba7478f1e9923f5e77677970edd1749c713e6e8fa08bda137b76be5642e3520d03198bbbfd9abb3f76af5eb9bebeeeee6ceab6cdbfaf07bcc76b6ad77bb6b9ed1cb39bbff267de6c36f7bbfd74c9f2e236cf229236c6a6aea2e3e72faac0be8860f0ff5f44c18ff04606df0778f00bad7b341fcedd1670fede9e9e9e9f159a2ee6648049a0904a9282929e570c43d515241c4a9fcb3f5b836d307a8331fa0eeed4266b667d2d45e3673fa1179491e941bf4eb42e69da9dd8fcdb3a2f69b0354678f0b156affce984812cd4da0e0a8339ed29ca536776132b5f90c149a1b5a88d47e9716266aff6fe9a1f6c3622cb4515bd8d4e62244ed3792a1f627e960a2f6efe852a7f69730a6f6f7f8c1421be5e508a52f5296be5c71040c104b98c024f1448585360a8c14b5a3c24011092355032834536294d4fed7e6c111f3ea88c942698c0c96c6d8394246882545286162a18d2ac28aa7325da860810a43248a0da3e990a02f4c5d2d6fa4eaac559f76c5b582e6ef89239698424817364558a0018b1444dce034450e8e7829979970bac4603ae7933b2e083afbfa1ec6af0500282444d871b96af0d142c49227028b739e669bcee44ccef48e989ea8b04b4969891450fbdfd276b73ff58f33856005769dfee99f4ed07625283caec33033efa75f092527969a8a23b5e128a98dc2ebfef87a4a1bd4cf061bd4ce85cf217233e7716ee8fecc2bf0840817ea2cc62242575db08ea06e87c502a553a8c2501848084179c2ac8ad055104e5069452b624a548142a7b8c586190cb164ce91550b432cb5c9c1a43c7353c9c8bac284c896e385d5152344545a2c7157547841cbc1c2d26665ced4028bcaca142f483a529a153544e2a493a35ac0b1024649164fd38a0c2ea74dac4149d3498244a709ff6c9d4d6aa5c891305652208234878987289a203d511942e9bbb803c50a710ae5ecb0a26894c3524361dd326cae08a2893b6cceb0b0b0e9e2039b2b33b0799abe8fab8f6c8550a232541b2629f17dbc37ed4de92a6eca43b35fffd6aa5ee3cf1757f9fedb6a85e43f3df6f8579f73e6c1f4d1e40a0942e89c4a6b9e723eefd1e0afcf1ee801f4d9332774d6ca21f4d933a70754ce56a7fae01a63db56dcb62a6666a60ce3e674b960ed7a6da78cd099236466666e66665ee60899992364e6661e8a4c99237ccccc9a11c3f6b81d4639579a8a536dcb422a16075d3f6332d8fafea42e8e9bb3a6c6e2912a8d27520a5fbc70183062b8b7c768cd87c55eb6a2dc9441612cc4da6670cb422c160f121933ba28acccdcee0eab5708e9eece6ee718abcc2757c8bd638c255ec619e890e5cc659c9943f8df6f8fdb679411b97dcd2295b1eb3e18f36bbcbf66323ac618637c798c254177cc0b52635e80aa3be685a7cadf33c6853495df672b09ac74b43d9dd1eeceb2a39c2b16c38055c5699c8b42193c2f5e4cd9c1cb7d06f743fb295f7bcd135cfe9ac1b7aa80ac29e03941d6d89d00762ae8ea54e3020b75b402f92b984febfaaac65bd5f04ec78cc90ed63f5b639fc78a764d4e167207e2d3559c4f3b74226308fa7e4e39e9e89fa88612e81a3b6798bb77b7978d9bb269ca28aebbbdacbadb0b8b67caa629a3e87bed88f528b9a96993856475b87553b10f0bf9fa6b020ce32425f46944d0f7f2b5c349c78300accdc11c462b96c7564e3018ab7d9ee7f5c800c3edab3e6b023bad147dbf2ce43edfb8e69c8f3a962638fff2831031ba29469a0602894d8afb97095b68ae0cd7b30d4ff5915e528558aa2fe60d26942a7d9e1512751e9e771e9e2c572a0f1cd7b259fd0681c3ec0284131e6c61aa2ad77e81b832df1a2533513f483d3358aa98330e0b131fbed01e22557d8718c73100890f48aafb4f286454b2872974c839738597345aaca1c1d18cd67563449ccaa8d4edb994d6a9d1000000b3150000200c0c8603e2704020cfc3802c1f14800f65823a725c3a9c4843510ec330866220c8184008310010420c5186a9a23203252fd9050c3f6a66d05f400298636e4abcac614b49f581d6c11fdf36509bd384c70070196da858b152b9159517190d7503e1209ef9015a317532b6cae00eaeb25d81ee2cc0c397c60983739d57220db27fbb64410618b757312eb495f79ab6101b795c7c15fb3b978daba3ca9984bf1c085f85adccae5f9a2182f5133f77904ae705fd46b40dd2a34a1ad9aa19e028c43c4af6fdee51c2534b2f44db85fd45059c2250202daa9894052b9655930c56e9d64372ea12dae6f096ac0446f55c989b5e9f27f86efbf4d8eb2765babc37abc838474a585bd235844daeae89610774f3e6982753a22eb6b82b49c63b31864c8c57de911d97890eae87e0455b851e23577d233a8cbb2f43340de4cb1a898b678ca71ec1d02dfbc9b54f003c01c8c4e96ce0ecb81a51b74a641404ab5522757b15b20bf7c251d95804113f776d24ce11cfce0ff4a1c18647273dc7e2ace0d94062d08bc83f64bc00fd9d3d7cb813bf9c53b02e049f011a38632fee79f0aeb27eb27a50a158d728175fd19a8d29c38fbfcac24dc69a9b61d40317c9ce3bcec654dea8ac0b06971e8b56be374ccdd3512f99717edcf83c2cb9a5a85176a92120faeb139c2fcdffc40125c326d84677bfdc2febc3ef1f0fa6272e4c6e242375cc20884adc72191cfc824bb74470c9b807868ebd39b7753caac6c4134a30473efd2f921fdb6a1a19e2a03f34c3210ecc118bb94920463ccea2eb2b5de68e06703936dd00e66c0203b3ab926506053cc54cad6e0eca7d8fc3605da960c1fdd0742731a8d2d80fc2fab789d141a7e12a86b1934773b41c2bf4a03b3cb03ced9e60d6b52cc93e2a82cd83de0907f3cd2d8341fb7de103425ab4410c44e45c5061b03b5f5f4bea19cb20528d84c6a27698bc80982d1e9e98f273cb4b3225e982b506874e5650a19e64f201451cc103b38756b46f1dce78750c87c924d7708b436175388c1faf38cf9b3cfbc1d689ba53fc3461e9e9189446dea7dce68947e88512c492acc484f7fb02cd57667b8cf4062297b76d4e0710db9599e4bacae98a0e67ea5ff7fb1c89de787122878835caa9b7ba775dd62a0aa73844b6c5646f1626bf90b4812b6a869c84c571e5ad26e3c8abc027057699eb89bd4572c520d26de188eebf66c65a55d7c0b545870b91525273bb047a56bcc200605e93fa12023627031d803fa736077108a05c2ee858be2462fda09803ee5050fdbbf1280a5c6e006adfe47ae71f08bb0c6a3c013ae97df0c2870de16c1f8f3d07eed5a07c91b981625103c63fdd585b318bc74e4da883ca3970c600c761fe19987747a30d091ead9773d32970091463bf6fc6b981f22beb5a3d836d86bd47c38e48cbd98cf938ef16902e210ebb23b88ccb8a1e08a4c2622500722d1e3b881f6edb00b14bbddac7b88fd1e5f93ac0aeb9561d6fdd1971bccf5a6120f3e7e02a14eb8769094379466e5c1c807e9d138b34424fb81cd888c1e86d502229d354fdbee028a7a5c7b1c58586f4516208fef0eb246f158577071088c2ebb42718cfd9a75aba4473f9140bcfeb45198c5af3ea26a3be1bdc40bd53148f1d6d50ad5211ad26e2458f258e6dabb4d8147cab8118ae80f69b278e1aad95bc5d1655406735b4f5be6120b7ceff973e122033dea1c40c12a810cc6cedb7fcd3f96fa95bcedec125eeee9edaad33f7e2182e4dd4b373a64d341dde3daba3c0479674d458b5c473bd801d375055c0da819ce9d8222e3fdecd58f223321b2f9af2dba95461acd91107c66040f92e3be9c7223a1bdb096c8cfd8ca289a4080820861e6b1a07b80b25d370738cee2b337035a726980ac51e67ca4bbf6e0cd372cecd7b2e0c741ac93ad843c906e1859d9cc1d71025162539d3909b8973f923342adfbaac64a12e489f95ed35ca0eb9bc6e6088ac299acaf6e0dd8b6888c2836183538f1e2f00dda01dbba1a4f9b579817d96f1499b154001cc499e597e95014fbe0eaedfbf2bde9d1333c280aecd54b333701354fc8bf95fe42774b1bea148c2dde1f83e91f62fa426fceb506bd81975e60689698a02d51b0554d872e037413d26e0ddd925c8cce9afa7fe408a7b8435fc0194fc603572615df3adecb4c129da34ed0ebc7780fa8f256e87b30f5f4d2ab48dae10be88b4d36eb8d8d2473973b197d4851ea80922d76a130852e6a7e8ab935014803c71c61482731929caa00a419899dbd4c84a30822a051ad6bbadabddf8bfa2da46a05c52dcf2cca5d1f5e4f38032b3cfbcf559bf9603b6ec125135cf784014dace90bd9ea4d52d9c9303ee6adcbfc649f28d59efbd81673031465fbe9b2ee6d2a4bc1f38078d4d6a33d7dc28e025dd11ffaa23e61d94102b61abd40c0971e3c2c0b182a231b65cc0d49ba165c0018565237263a38f01d8a0afc279096967037d41012d553a2a05759050c7d6f952451a20a2f19b36f3f49f505391e2c39ace5f0bb0516d1cb81464601dd896bd125468ae1519118296980b1a318ca32adead0c1bbf6eab9a302045d5c5f3033cd31922dd2f4c4cd65ef3f00907cc0d81c5bde0e8a2f20667c6c38b96cfb90d676034f2682338a4a632c54a034de5a3e900489e1774d017fa4793f5c59e4ee5a8b14a72c1d5b044d1e430cbb8be8ddd741814c8ae02814043ff4d97591eab38686bb7da5d7e82e04dd28286d42e80911d2a708342aa61456f06e5d0f6dcd2439c269c32dbeba7ea89191ab1bf0a0538ef5097b31cf02d00857f31c20060614e4519d3172a8e2c841887d157fc8e4011eeda238a993f6266a5892dfd64ee41e1f6a639d2452ed42cec7744f24026cf17ef6b9866a838aa06633630dce65f9ec02eb55118d2bec3cda3e2af5049ee56077d6e0c5b5fba9644039f661b946448c355485fc3fb9a8bf0446bd5e48186aa66d2a917eeabf405032fda24bd95912b96ad1020b618924e6ee8cd0282c2d90e1b614ec6c2dc198b90900311f7621881f400ccb46d65a12a97fd200c47c2bdae0c39494535827b87c1e44a6106bc039aaa2d702ff08743e598ee59758e277bdd03e586be446258d861e5b38bf44200d46647337aee44fd5232ad4c84bd2d412f6427b719feb92c579e7b564d87294e5c9b98d0f1653a39e7b0c7bd5ce44c3382d711aee58638ef789d2f46ef2c53ed8c18abb2b774106ab022502449f7b6ab72a16ba16883f907b9bc40cccc3474ba38808e08bb30be7fa8c67f9a90fcaf2568f2094258c8084c9f096faf0a9d235662e2ce70989ac2e55a4725b4d22bd7c5a5f7232682f2a8a861a16308e470f5048eaea0b2d232ff2c449a6d3e24752393f3f731936f2287e48b916ded9e1860678be8b363f09aa6d203bb3c3238cb1593e97db9f9fe844431eff62c9d5321637244f13f8da2ac03a466ba5f4c21559801b4bda5ee636d0efbfa6f39a5f66e080aa94ffeb63f43b2111ab1c8832010f4b303ec19c0e42ee6173856cf0757c2885eda29f6e0b82c18193628cadc197672428ce227f9822cef294b95c678c6409dabc51cdbcdf3e402da41eaaae8f2384c4dbbf7b5025c70dd18c088becc8cabbf0a32d2a1069062d4eed56453f7924ce0db231d1460128a7ba2639bc0659d313bb7c0420555e9c9935b08182fee085040ae82c6ea6ba348d649c7e9792365c4314ae3b366f0f38ac4e116ddc17f79dcc270e5eb7d7c5b61246ea2d7d17d4e1f3580be8b272e8ba5141f6f212f721ca3de0953367d196483cf5473291330f800eba604875724eb5789e6b9861c4d203ddac5bda3f589beab2fc4ee0be0cecc77d4cc07fce793ad910ad66527f24b3a28b8a01f4b91251bf2b46277fccd45b0bac231bec5d9b009b223d1134d1c24d57deed612b4277f4dc01ba4b49d9f05605fcb082f6edaa0dd7a36427988f501d1fdb43c75da33ef6806cbbad532102b5b7ed80c11cff0d702131b5cdaa2cd6d77a90191eeb30b2dafbb92e74bc2450d5855f853cbf44be5cd1ed2569063124bbbedeeb9831df0d26996ab6b1e5fa693d8e0fc7a2a687f18bd403bb8d45de47391db9547eeb80a1acb76550f9526756bc6db477c076e114f2aaf95e5408018261420e3dd0f531a47756fe131a8467285e4eb071778278b260f571b4b5745103167a04e3ebb422727623b11aec4fdbaa64a1f9791e97b74dcaced667165c7807aa4b9078cbac5f48c875ac26ec16d82a816312229a9f25f9d8ddef2e8ffcc61650f9775c68beaeac75300787e135b76a9081026fe4560c1759755dc1afa61b9f3bf3f939924df966737ee01862bcd1883e65ff3c44154c9551373dc60eafd220c13e606645b63662b11cfba660d19a584459f1617b627b16eced199f4eacc3ba46822b6207e02b309c41ee97238c81778a52446c6ef1d016f364ed8a8f46d17b266ee2041423767a4b8ccbffc3a26c09dd04b1902793addff2bec5de84d65fd59044433453547dcc5c6388fb4b8af3a027425033f5dc518a10f7a55d3631ef6d900567a45c3462af26600b43f14d6e891e127f620ee35b62f58526bd93c56651fa1effb02bb36be8d904a64c30a224e271e9a450d98cf34b825ce7f88b0800bd6367fb7396ed68335d50d83d54f5fce2309a020288ee302d07ea6f637c0d2d42b0c9ea1b8e451c4559c363d7adfb643595368a3bc00c86fac60edb4459a11f82a5d728c18706acbbf0db522f573d0627e499f141611b8dc7c06b58b14af9b5a69195a166b5efc2a08fac6fb1c14f29a09dd2cc68b6bcc5fbca18a8adebe8d5d5bec3cb0df4f70a3e8c4189378164db048db02e76693fadc48cc6175066a68f4801360fbc7a4eb7fe74a011339ade4a7e8f7909b0b304e4bcb1fbb8fa89866b6ca91bf28726592fe452d250f320130e536c22110ebf425a27dbc64a85f9e631037bde653326010a695350821ca8b694a9c273d7426b5501f06a176ce640e31d1a1f1d664acc6fece445d4d43ddceab238971909ae445a6395188dac592202b98e2a4e52fd3e51ee5419158bfe39a8b05b20386c4360d4879852df470d64aae2f4e115de59a117bcf5485f84bc9d31b7a363e86a9ba2a24a22c0a5b6250c9a3375563cb752cb719265621663e46c79ec2c31513b95d77e054ae055012c529a20f5fa2b8cc7f113f5e98a17eb83364d48ef1bdfa6da9b90f8a0ead8887fbb27c433404ea69ca35fa11329cad0f981332f47685140a87d736b9b295ff6a3a8036468910e1d317b440e1cd476247760db732dac0f24b76549c50f3f37e5fba4214103b26deaccd0c4241f1181483f044373fd9784113ed65f85756d75d9cd66d1f1d5c186f7a81cc0e0b3066abca5ddb430c06fe964683cdabe9ea4efd598e256f07f77b6877134b8e7ba8ed2d0dd8077920e0086d827d56f62c74bd4332c6eb118b3bbae953f2b2b8eb95063513265e348eb33cfb743148fa99c431deee49bfdcb3dacd6208dac4bd8909356208f6a73d8b6d5121bf11652cd1071bbfb7a7e881df84bf8b3b850ad88badba983bf1ecadb83a06e3494801276cbaf1c9543c75eb59e8cf9c86627b928e440caa2f300f7ba7d2e5c2f9a6c9ac5e5b01ad3f099eb4bd4828e4052e4ccdbde53241a6685439a9f6bbda5be8e4cca9c5ae3949bddb5cccfab563500a6d86a3aed0eb3c72435777939742dbcfb5c194eb7edd6ce9a4f07ee18d46b85f8f991d72e462f923b5737566a585053e3ea7ec89224be893f83f6291d4c59d8d28f62374daa93198fbdc21c8e5afab573dc5519a208749cf7949eb1872325a3cd6c620ee8a2c83d0d212484f8abdcf086eddd3e5404b680935ae8f93ad57169165c1e196ceef505c37f22b984bf27d168197165848f8f6e19d658917d76d9e65bb5241fb44a22a29590ec1b8ad18cbd414612d31d97f514ed301c03b0609a1b865a7b34a0ec72d8d69cca0cb1fbba0422703e4d0a98f988d5a09662fac190c402146fc040fa82cf7b6489ee51c581427151686513aacc4269cf7e7ed1aa02940b2f82116c2e215999ddc40d3c74c3613546b5b552898b6f52d2c595d21cb26fde7fc3953246d60bce805bacf09ca670d4d933b2101b2ec13956dd636cca05a2e70265241c07291afc1a8c34ddb044452378c7ac5f96adaae4f4d42c09fe28e40e0368ee1d783d50ae39be7121adc52895eb83da179d4f85210d50fb7a359355688206e56a22a84e8ccbd8790a2b3759d6b52e42be7f76957287d2fab5e5e825e142715012a7f88971df552a3811539a6eaff5141e7859c38e2e1ad8c6b7170dd5b4cc451217ad079bd9abb1e958af2f385668b41dcadf615c94524aaa04277ad88c28ead2ced9dda377596db392b2ca302d43b570b645861aeb355a08c0a51ef1c2d94b1e2b9e6fc069664701fed59cdd801d943d66a3ce34ab38540df9ecad7a7cd7c9fe0c26639cf5ba1192c507ce755e5d79669058eff0c3524a345cfc7f9f9741f26cc18efec9b98b95842c2ef6340abdcc2f4f794d982b2ea0d92089309abaa3e13a60b1e4aadd4b6f4d33892666a302a6b90b8a3bb191be5ad83ec6e4d73ab1cde4635b0119b602a0352d85704f8fcae13c1615dd1461bb74faa68bb503070e6d68c8b4ccf2abbf917bc65d8ee7b12a886215791ddc06c7d462b1a85a9aeb83cba71fa84c5ea1e4ac5a42ce3811e6217c8fde2448c66f97d92b8bb5841837d3677bf8411d9c8b5fe96e8610d767a7c099d7deff95675a2f4aa2459f20ba8597ca5b6c6d4d9397766de4f2bfe52b2039cc8f73ec6b1ff7fec5e2fc915591ce87f0d48306bd972ed18b56c5ef5e219674152dbfdffc2fb2b51d440d83e38bf33405930f3e71d1b6863af448d65d5cb16ad070c8fd19d297534a23efc62ace3caaed980f1639a970518a5b75f77cd63294b2ac90b294381345f24dd91f1879a4299e881ee52d880ba3d32194437e133230a9a7bbd01fbfea9a703e41531e7b507424aec8e843bfc82185aba8cda2cb2985dcb62d1925272523c974a49f4f79b3970e285680cc182b7074d5c95515f41458d4c201b2800733fee7b53770e0e1165fb1515791f743383ceb925890ea0aa154226f5bf4f87204f71eaebb4712928d0fcc365c91df0eda64f3dc920ba276c0c1256f7746eecab4444ebc2ef611ad764b59bf0d692b1726fb64cc5f3613cc43e2af4b48c6a70944a427e54ee60e8e8f4a975c1580f6f1570183d7a904e18c88f762ce8f5c4327928c6bc15142d3bbc8c888d7d65c71dc759a30597785e7f8d56e23972c968bab4186e34dbb0470ced4f68d32f51e400221c011cef7c5298b79830a7cf857d63380106e41e402c6b79e00ed8989ec30710b3dfaa5a20533c34dd18faa510efce4780a377bd26569d0fcf6009c11c8ccca8cb5ee6e05544d3bbe1d5c34dfa1d0d6d4ced213819d9ba6d94bfdc8154d9c08e0d1496d112242acc43435b01d972635497fe3e99077e101a52b2fd48749ea1ebb6751dcf59a93cd1c4c242a157d2d1094ae7644f38107fcb3b716fa26c7cdf30de060f5967740223006bb606e3b1e7a9fdc5a0c6a6c2f957bb4b495f6540151864c99035d24330d9cd446a06c48f373af37cc9b4ca6cc3d177c3ced5e30f3400a73f96be58ca4d3952651b9fe3954cbe861a85e512d967de4bd918a38af69e9531f46ffa69226c484101ae396e79d3b3e6fca0a319666c27acc24c8409650c4f967d27aac3498c12b0f23971e09aa3e7407bbb843b60d75c652e05fc37267a1867515dd13ea7bcac01e1f1de25109343e5ee1129458d3ce43909f16f8ab6c9bd9dd82a41aa34811f5d3e6c23026e38fae41331ee171ab33b4d5172cff4293dabce84d4ce6972e70ba3c9d52549fafd589d5942a05b0ee315be1deec95becf567cc48520b7499d3098db190653426c63299f99d8746a5a74104d4ae3f79c83c8217b3e674021e9690eec7e77034d3d1bbda8114af884aeb160030f910c74e263c6382d0e6e1cbee2d67c5b6204b130c45c1c8271ce88c4305cc14c6c8497268fe909d10b383c5042e591bace2e78e1293d8b4b38e8b7c9f90901669b8c14c22528512164190b293e40c4d271bbf8a503680e2fd5ab86ac84178c150f617661b08df7e40c47b93d58c927c258479a636ca8ac5e596c3a643d33fb5e2226b76ad0e4b51892b06816cc1a8f3b21cfdae043a2cd0e5a0b9565e284bd4999a07ff7978cfb9f402cea5e60cb251b8ac6c972db88718f6860436960f88aa9310e5d424121d8e8f3c8140918df1fc0353fc3167a464ed3f8af69dda0f3bb726d53d4864a7daef4b445b7c67b127266dc8b4dd387b341bafbfaade2c859e32ac41b4122a66d69324c7c131f853592dd39ac9af3c2e9135581d777540fd4b2462a940daf7ae62c098d0c4b7b405a718cf4d624bf0afe579c61f5e7c69179ba705c46705d34ebeeca35515f369aa06219100223165e996bf64e78021a280f5f8a01094883df205b87fc241837fbaf195755fccd9ed219e73629b86238b5d91ac95e8dae582c7f0b51200c036c91b981ff20282f8a94cf6cd5722f492418b12a295182f3831244ef8cd14f706190cf5dcd6774fe2467e688455fbab78ba344a484757e6962b456b76ad4ba573a5ea4d1e649fd90735a6b89c9c7ce84c65a7a5a6ec33e34fa700a3a53718bf69e10b3023c25bd429bbf384b2c8486d9398ea4f3a55d95372002fc893659002545a069c229d123c59d4a067fee66f9cc187dc98c26c73d8edb4fc1520ecbd8ee44a59f880092112de02568585ba76dc98b1ea381b2430b720dea411819b998b049b76a6ca3957037e5d4352c8d4968605e202bbd42478902133ff06ecb392c3cb09ddbc14c033a5eeef212cc30c4d8c4d6338fd3ea84606096572b857aa781649c226c5caa1c0772ca46a529004cbe7199eb90d92bc9e27b62d208623f80e0ba93a91126b7eae39a6707012f4dd7aee4a31f53383699bcda162591897823c4cfe8996825187c5812054dd039ca28396b35e9f45ec565e8b28243ad710a828f7a142cc5f5147c8f398bac031295d59b8847eece207a051433773902ded201be7d77da93c7a93447e7005ed2325141d5c1c2b26d7735372b636f4456938c9e4a888e2636ca49712f51ef7b68dcabb0bfc3438e0b7e7e373956c2d80934eac1b5a151e60e81af18e60fc401702804e57b6837034f3701dbab261c443834a243b105498d120e84ed1652a9d1075f35864ab15bbe6a311a9344cad02d79ba2656f7effbcffbcf5f0caba21a2282e4dcbf5eed24e2cc3ec3ec8108af4943034aea5a668f59b116b9e923b68e83487a8d00554dee2f4bcee95e04fe2fb5e8cec4dd1f4f16afc28a4ab266a347ee2c580fe648e0634deb99ebcef00da842e1d298e19b51b03a551b22bf2c204154ad490ae774bc99cdf3e2f275b9eaf0f84a7be94800146df29540744d7e1614ba47d5778f8d883b0fa20b787b1b1b6acaf77786bd9da362b342836be41ad4812bc0b826677982b07dc3acafe7af056d15a5e449d20f3ada97bbc4c1e565d372eeee7f4abfd361974f450c56b63a86bc66f2c0e5721e9337063ed4e12e42e454bb95761c08dfedd889f058f5fb00064895a8a06b8ea05f2476793f799f82d5784b1d7f93a612c748f41bca8faacfdb283ea5841894445189b3ec7b2dc1981c60aff5b4eb484b1677c80a365ecdbd240637e169f609134611dff9264dfb6bbed5e28e8462cb217a646c69f12e6941a612ce1211305772fe9d35cd07ae8f8ef0c5708012a285e2b44a85cc70463a12e964e4829b8f2ef2b3b3f9afe5ed2ebeb4c7f8720fe968e6babbe05d28a6d9ae107d872109cc09b21a8a0ef9516ee90f5437aa2725d87b61e5db5d1ae39ac21bc013fd89395080f4f1bacb7181083258546b34ab245d119147b6da98295c31e9c58a826cd588bf8d4aec66b5a7189fd956015dbdc7d7b77bee2dc6189c07a3da1233e3ce09ae421a179c0151268c89903f89ab4eb3b668884e1423859aa10a7d13acefbdca9c100eb63025d9935babe943a548635a9bcee3361a92b118150cefafd23dc3f53634d605e7a904afb6a59597aa5b309115bb48f13eeec4857876bc66fbaa6d90c61629ec8d5a8bae37291f7957ff92eb9328df6cb84e19b669a77b986f3af99f7d680a64c9149b2898661ab69d0c9604ba551c8c26f114760bb3daa5b8e9782ba60f0e970e2541c696ebe4186d6fc0b9e5a83d35dd59de3827033b9766c9ae0e1ec9672cae38a6347c4a48cc0f8d943d304584a6e269f0531c7dc8589e39a79cb9d39599e9281cd6f59c4514627d80056bb42435a0f19d71d13e2ede9d6ebeda953182ba7fbdce4e47adb1a22b90123f2ca5cb0b3b72e8f4a47341f49dff7402077793bef22c5b8fa535e7599e2d160916ae3bb8be73cdff0cbaccc9e7ff48130377ce5d2afb86e2219a0ce4bb3361b616a6ac5a052a58cd359781150f065aceefc73d0be2ede046e0b7298e5ced671563e40ec4489894707e5037c3366d0dce8d228be80f06d95f086d9e49ab8e5dc01d5d26a9ec5958a2fe072e5ade18d735a8128ba9af22c46be2e57b3c11cf36e97e31a96d2e0913e70fadad2bea5586ca2688449db37bb1af17e2042e2499ca65519ab9a9b82164a86017676aa845f9087b7fad80718443910b9067453a98ac1d8fd0f814a544b80bb1a53dc18bedadb5898f66208707d251bcf3d9bd307b0762d695cb1ecb498fb966ad17458a65285605d91d8b7f6fa9fe350fd27c0fbbe6cdf473c4e7895d1d88b7dce22fea837fe7a52e9dce1a305dcf99b70b0ed7036a4389cd0c281908089c3364bbab3595608d4ac8817afb30c3f3e1b70de12d3e05ccf39d28e10b8d75c59ea2c740fb71fec4c411c8669351b99d67664cd5e1c3a6bb36a97fc2289393ba64303ac58d9de8fbc42df1cf2deb392d6c33adb3c67140ed03f222b9e8c15e9117bfa30c5ba13a8efbfbb0253b4a29adfff19e79d3f6c6466fff8cc50a58cf94aac561ed4bc6c4cac1cfb3049029529f926fea1cbe00e6427e441aa54b47b24eb95a29e4f17435cd7b7388a789de62370cf780e0475b07dc567cc3e7fcd98720310ff242c2cb961a2533c06204e9dbb0ba66f6d07e0b2393de39a1f64513253e5e945551e567dcf03b5bc2ce89f4057be6f8ef955453bcb4feb229cd4e39f1e16b0a68089cf942ddcd7f9007a14ad1db7909da810b1f42b8b1a8c241c1b272badbba7ce76adb2a3a6977beff6496598db92d761097cb9ea79886075cb6cc0fa725f095336e9a8b0a7fbb209a436ad29cf4704e55a6a377afa137cea20e4900984537f71f2515000cf688a73f266823827e908693e5153373bb9f5ae546da0c58afde90b69619e6219526bf44207b10187276ef931e134050f8d0cd4c5b05c5086806db5217e72c8f09ff8c971180f5f674c3c19f8f91b73d425a3077f86852f1d6994fa77e978d536a747c12d72fad5ae05d8d52150b7b59dfc20aaa8a4c7b4a1609c2acb9bb8e3d2a3d6cd92373709a60a354ab0e7eb1ea094b953858401005a728c1c0b15ef3052ea9a610a48f70408d563fe9c2dca5545e87f377c4d8dfc4caa9799f1a8bce8469dd4d46ec031fd95b75cb91570976401e0fc5a8ba7fdede5ae2a964f30071667ec906bd1d454b1b40df2d7e0130ea806297c0e1d16bd1cbef5370a00a5835e9fc8b50dc710dda51caa54643a66299e1156afc1cb3e0ac4cbed84b1b9f86bf07097b65dbc9927184b6b7f2d87a0e236984f2b37f0a5cdd7cb6024b79e851191d89b9f884aa20fa7670d38794172d8583f64c0cdb1e36830046208a48d265b4d423cda69408ad7223deba03c3f77a011cb7967b413ac3a0c0c774cf262a194badc9ac39d71ef13c2b691c6d3dcaadee41ff9ca1e03cd07e6972e20b980156524b370f4cd05ebd0f65323b4257650b430bd0bfeed768ef71988fc529d5ef2a156f722f37d86b4b9e43e4f13e33e13300d481e04a270582383ac07861b6116f87f6085c5499dc0aaa3e14646e63940e4def75c6b28339f837b5314e92d22fcce72ecb84711177ab1df87d1b781e3cd4a700b8dec1cf45048d9eb12b1f63a4e3dac76c2e05a323e9a1e201c20214b0b65180948de6df55f6ed7be2ea620c6ab7d3012eaac8b73a209375f3833029ea65e3c95a4fc8dfbf6223ee800c7ea4d432f67738d72be278abbf03794f1c08a31a076a60d84aa33f7160417b219f888c3ce1c49cc3913158dbb8034ddc0d5064422133eb78fe4d881250048402abf2726782ef019ebe280d3976aeb0b6a3d870bd10ed8e14d5470c8492a010619dc5c1aac93a00a93d18e9981d6b9577f549b51546d0ea2a88217bfcb479aa51937bd75c26fc7ff096fccfe213ca0037dcaa5210fbfcd832a40b81eb2342212ae9c67ec57366ce7d7147144c2aa8658c8391a106043efefef35a0837203f935fe6a4ee7d6bb086baea1178206a6ad00684a590e65c3526a1339d548b10f9ae85f2442ab2e45d74d4f8b87a7375aa93ca1ad35b9a03684ebaf2d346872c38c1265c2cc7b179a6c770ba344e1b69799d8900b709c8368bf3174670a1b82cc6a2d5d55af2f09ebcd01bdcc301f6178cedd7acc0210c708f75dbf589b2a7392ad1b7ef476c0f3405f7451223d13350a11b2090753457a0bbc7041b12db24621f381adeaa213d3b52b99e0932eb71e06e44b8371518695076b2566e505cefa35e19ea56dccc2d52a4cb04ea812ed7ac86ff91c2ec3804fec1cf597828bee5a924157c13364e061fa67bf28880cac22f0e8e0704627d82ac08dda1333418cb58c81da5dfe77042cc4671888c85b8782e4b3ab60e179a389522fd8bed9f5ea085706666e9beaf4ee804e1ace18bf679263d83a5d3b9feb66e2d191b2baa60b7be2a6c122c41873058419ef28bdb9670461e349adda293e22798cc278059883f40499c088978ef086a18bdcbf7442d7a5cda2b908273f2b79fb7be5c615a7313423964fd8b51b7fff622040f8048e48633b276de6a7de344806a57ca1d0c32e2022440832e410bd26eed38b10ed8d2db9538fe1668109f537ea4d76b1f750678d239d1bd549cc92cbea319ed28cb3b1895d79b3bac9f02c570eddc1d3696cb8198d6ff85d86df14fb166d12d80ab43335ccdf1478dee68c6d914cc555e415e21560420c3dd7ff47b81c73828ca9414d805d98984d61945f19384572bf2dfe0da3488b7f018704a77de187804b48fbc25ba7ec0d3c53203ed29a805be4612f8ce11d17a89c77f31c1ea7b81e53a010a57c40eb3dd9cd3438d335a1f4b5d8571437b2776048ff07d36c0da1eb7caebf9047b5cd5354a74253d60d1eafe53339e836936dd8fdeb35a09f9c591ac55fdca0af3a9c6066a4c5ee7120507200e7d793f209d31019c79ce0b965465ed07ac91c8669fee2f26488e1d20a288d5eed1aa9674e5313f3751a4d291d5806796a171f347a189044f7941bb2ae2308f7e9b4206e165f016a2e95e2313bedceaafc4475dc66cad929805a88cd0bdb84a55bcb4c395e0a950082ba20f3601cf7ea05e3f7536af45f1fa01ad2b1618a38055189d406c06ad48a1a483a91ca48874f9e26b3c03487c8fe81f9bf22326a95b2dc469eed617734071f71986b8237c48ebb74d702e090bcda5f87f35657a3ba9bb52407da106d1c035546dc6ba8e4c87bc169583cc701ca819a28b261161f58aa5e6926e19862f59bf201a39a4afd71fb658dd93b11e2f8aac96f7ddadd012a9193a18d69bcb42c99d06ed265a220d7b343a6a55390a59097f805104cacd14e4fbae400a46577ec0883b2dc9b77b52d1bccd51a0b3d86763285e4e5c68af07be8a4ef45e050e1063e8bb318acfc09c860e8801f2a00d4404715b9ac4482dc694d2d2a7c152671145f57700d00fe482c49165a8d69d4c1a172ebc6fed06e257352815cadb40ead3467823c9278e00f214302b7c885379fd05c5fe84fda35f5fa0ba755175d9cd2696971be19a5d3c975a4f6eaaa744a557af80bc072faddf52a10b22a71797428598f37b1167ca074fe2a00abf5b0b4cf28418bbeec296be4ac6ad74c485fa3a992f67751f8fa5f43c920ce486161ebbd79bacd11303369194a5b59b278ee37e69eabb45cf7118ddb3d4d0592a05079f006bc8de3e1cf8dc4ee42197fe1d1becc6de155d6a941a050b7a2994e2ed155bbd3d330cf5a5e51471538d203776deeb260766d97054c198623a9bc1ccf8e4259453f6b2f89d8345a31cf87576cac5c20079736175fd54ce44518c86568a988729420d822d006b475b3dcf8a4a625650e6d46dd7383b4b60c8be4fde59f2e0ff7d82c5d61c3a4fddd5917e5b67a25147f4f5e96022a27b0e623491b78a6c964d097ce5094213889b21666946dcfc0b2343a5fc0134019dd6a10f75bc41a385e0c291d9af471b7d545304233167f476d5f1cb773c92dee8621ab0e158a6a7ab9ce12dae4744b9fd3ccfa3aba2c41e6d44be312382545bbcba52f8cb6f588676d716e393576270598ac7529cc4a538cafde22d2e9d0a72f16a6e0c07e0b4fb11e4ab320a2a19511833fc6245c96b6414d107e424d5ec3e24b71d96101a7b04d733b555a2929551e21a69d67d73236625d37d28a4bd1b50c3f4ee51b84f3d3075527172cf007a9843f7a321dc7fa96fcc46b7d078ed24a4b9edefa198ad7b60e0cfb84059840ee42fedb227b5a090dfb005fc9567d871953e809a0db2a634a17c706ceeb29a8031dc289fa720f864ab426161672e612cb110e9a4d62d21a91f5322af380a100df62d5d8c48c81294647b7fde3765debbc5c7d624ad04d376a5974aedba5738eec6a2dc74623d7e0f9da4fb87b944b94cb58a551dcc251b861d900357b6f86badd8bedd66eccc877d1d9536323c8cdb5d41888b06c6b5320c1fddc310bf011808b3b1e4b2f00b0855fa17762552c9c41d074ce54f0d22adfac71c165f4e18277c8f0bf9233fe2139766797288743db014e5a4389af37fae0edd0b358c8fb4b2a201308ced8a43a0e90648d6816965a54bae4f420a5236b86b3dfa3883894ebb9af95973a2cfc35f017a1286355bff9731e2e24a45ec19310a0c5cef3d2b09378ffebd28898ead6af2e8e509d2a7433dddbb894d720996a5a517df632e8c064721bc136749c75ea9ef8b8b45aab81be9552da13af2d8b9f10d7c46db33385e4dbbe6b4690ad3b75ec93fcdd7a9b1fc039e539cf0c0322b2ab21874c9b059bd8e9806fd724d136ebbba50614acc59a0fcda87fb60eb4e0acf7ec375e26c73b20ddb77442bdf8c61bf737deeee4c1e59402ed9f749722f6adb04d4c5ea35ca087265753970c12a237bf4eb35c03a8eafb7fdd8cfdc73728b4b1e255e8a40158d64962343f94613e239394e35a4806c23e23e42800d28d5212f1c3ffc61baebffe155e92c6a4c37b60f0ff9a355a444b314fba88c1341442b688d8373a77a49d0958733103783ab78aa6a11a494910313d9874ac52aea89f26da50f6a23903553489790dc6f1c8237538c82b6b920e8893dafb97629d0231f4bbd0811a3d1b4b1122d652383009470659b59de68e4ce6a4f3c6813e0243b28b0e26aeb07cd8ae28b9f8fe7c64280157758fa2cf510e6104d41610cffd07fa5957659c055d834f0fa4aa513c06e9e6a1cd42d6176d447984b2d20f54f0164de7f032f226dbc8960681b80eaec135f7eaea08b6fa86fe1090d14876d241c9a730942b00afe93065723a44395dc37f5952c1f3a6d718319fbc16e4952c6628850c994ff5a44f43cb481cb3543f5988dd2307f818684e93230d4fb45c8572b411d7f9e1980653ad54d2d30441a58718aa346ea560a3fcbcee30f493931451cd2b72697f98b46905b31fc4283a7e9085b79f7c5b27eb2baf7f46638f0f532a7c13735a23db2fe96be4970d7327c2afbfcc018aee6932cf2683f86e74d4a2cd7708b3ffa92107485a96b33e10ebd9379b687c9e98f1e8b44384d45df63a3cfaba1d56fab8ecb224b4646fe47cfc9a5107f9303ca62cb6214617cdfc59b02cd0e8d47fe8028912db7fbede22c29d0f3f154c8930686f5a3a7f6072a4b62cb5741f30f708e39811d4d2a5c7ecb496ae3fc2695974d309a4ca30e95abaf3ee978e7e560b5b3ab81a1f4ccfc625dc294a73c4c319e9aa0e16a60e27e14c9d98ba0f3df558c9a0a79db7d0ae6eac3bcbf14941111076b61ca76ffa3f44e1098ceb3ed95bf87759dafa15a17d452d49112c6e224011f5db454dbfee19556776674e25e769e9f12c23442633d70e3bcb2d997ab20b6b9e302abdfafa79205badbd883b96b0f2dbe14a998964d5ef785ff4ac39ac8adc41b73b8e78ebc792dec5d52a58979b7a8aa87b860dc4efc465f345a847395b64e829299ec67b81283fe12cb14e53aa9facae95f5b99981be75de19afba2a4c555fc0e8ce012976e95ea9e7c4dabff2b1443e96232014ba893c3fd118816d53f7e764dcd8b9371851d79d557e31dd41b235095aa84d37de9d3912cd2107a7edc1265e981213ea22c59a02bb7988d044106bed6f65dd5eefa9972e442d38e1832e6ccf4631d8ad425ca73b235fb775921cd0454acb771cbc8fefbcebde3b754ffb19ccd7cce32f841ef02c94bd51906844b218fa290b603e3f38a0c62b3aa674410b47524940f83b9663102fe180c2e95025bce7ceec40a6f2a9f23a90407badabf850380581b727e5448409712e00a831d938bdbad9d4977014bd9c4989f3cf88faba663ba1a498704ecb9cdf4e2c194cdd0765ad9b01174fbab455e211e7cede2bee0a750f12753561f12f2d842357e3db6d6a6826f30c8329503a0ae771cdbab052a4e739b926714f26fe6802419c66ccd843711d6afa73a2227cd5e5b84b17e728abd5506be9144006f7314103e59cb0ed9b1d9c0786132360e1874fc172394429338e0a2e1fb1350ae59cfe358464cdb861de16b34bb9d03486bf12ad9eeec934d58a9c93296fc8d1e0773954872019fb410ba4433bdd9a74122020e2a67987b8233ec68735060ca6b4e8e7126e2230a022d3325a379c0e8956e7cdcadc851ec7ce336ecb1b1fe011c7e401626fb49dc9c99a1413456b39916825268a56f22792f587d82b1869379707f0089a8773f87e61280ffa3aa1b2c0658ff7649b4e3f3e2d7eb42f7a9eaa9df59c6bb613a11f7cfb7fad35492df1d0b92288dcbb8e2381dbc0e5ecdbd2f4db8eaff3e383f3400fbfd86df6b949fb25cda17904e5513d0e7308f524fce7e5cdc747f72071ccd82d35e8440f3b9bbf8a547d4380266cd5c96b025f4bd0b061a0d5071358f35ff71d577c620ccbffc526a1c403af911f7b6789ebf144cb6d29323d787575d1b1900022417dac8e3c351a287a1bcded5cb9d64426eb0ff53982237a03c782dce8eb106e80d728002e34a78fe58cf242c182144dc1fc2f6511e93505a2688a74e350cd68c246113f5cb7c0975f3b91389e287b7ac7ee43579cfa807a1b22d8825c4146d36287adfc1c8200215611fc5ec4221af4c62c56b4b0ee9209c098946d142341eea0b6a912d4adafbe102899c8359f631cf631f0081c05c72004d13d089bc03bf9e1059297cd489d37fa1c6f0142b07ca87efb8a49c4acc5ccb8fa11068fedc6a1c20250fd736d1a6d08479ba28939737212b1317cd9931399561d8b142ed6258d1171f5639d05f86920eadee17be5f6fd9b2ada99e588e1c9548e2b48e9e2eef05314018420ee91e5caf52223e231433fc3dc2d34f000ab47c3779e1cd80d5d610ad50322e2d9617955929cd0d7d4496abcfbf3ad072f7f710cacfbd69c7d9460644d5761622dfa2030026902e154aa0da49cc0c41986164f68cd9896ed97a6e534f74984b39a9d18791c382a822fb5c213d51158d1b9389122494404617cc138a4bf3e56898fc2cd961f9a308e00e87d1249a9d15c66c7ee5fd5565191b1e4387a87b370b9086901d51b1a25ad8556d2bcefcab126c5cc2bb7976a8abe95cf46526dcf7bb504a6fefa21b44d482f7393482b966a194c199049c44e25b74da5f4675ea425f636be71ee27ce65ab06abe3726096dc47f56ff17cfb733c11511f4f66837215f5375370132f63e4966e442583db395cccd860407c12c74fd801f187954fce4895e4ae84fc96111f4e5d706a47315de11b2a43c492b08234455d399e43bfca4e0260ae483068043fd944f90dc3a2a415dd7bfb18013f614b13bd2b312567482847f5fd359d9ca83c12c88048b345abde50e587e0d29aa5c9bd09e6b40565db283c26a7417cfd1365174235a5440a3d1f751f03f5ccb567513f1b06c1b6c070095b07ecb539c024e8943008e24f67cd415b6e470908f25fc0dd4a5dd2d98c1c435c619f62c6fa037074185fe5d8e9f8c17585eb865b37b3312aa8d03ae6292ada8c6d212e13a11bb24d198cf010d6d9456eca1a9ad0561ce0ca784f66fef4267cee4637fdfe840d28d4ef1921f8aa360361a6fdc2b82566ad3cc0c884e856ca39ab6fcab21373faff9d5152ec111f877a176483ddc0f93472d1d9609e8318a96ea34959c34bc5d2a064a7143600c72773ec249dfce8d8e0dca890f65a4d2cfe14b4ca7c8a660328333e51eda5381c36835ec88749efc08f1b2c1baa61c77998828e245ef7d277779607ec8d8fb4abc614deb8da3b10221757712aad52193348ab7685ac2eaeab73848bcaa44eccc6f235fd801ec649b5523ca5e0c12cd581d3647b0ed363c91b88b63e53b1f9b1d00fb9904f46412dbc96632e95c2687dd36af2a981b1fe4d3d886cf01aa560a11ee536b3ca339e1adf7183066ae9e246f7ccc8f8fed5cccb6946eaf521bcecce996c1abfef921c3087b843af559d72c16cbcec317b005955f92a2f9f59ebe7f7a4ab3840edf2bbfbefd7c81ad55f97efd81d5dcf2afedc06dd4ee9c93ec1a4d9b7049ee34d9313ef1a82e7e42bceafe8628c0600a68c2d407ce77629fcc7f5235a7c5cead76bd3f6bb0c7a04b4c40437f4fa38ca012f013f1f63bf9fde21d537a0302268e93a822c024928d2da9f13bf8439def5b4de7998f54b111b6b2f4ca506ce3aed54e21b83684837e99f8c0e6e6f5221c5da82e4f94191f4291a38c6e306a2badc328720f988df3f151d14882180f0eb0a501193a5679936e8385bf20970feaee2e1dc0fabe15d1810a66748e4e0d85260ddbc49d2da9532e2c217f7c1a4831aa514f6b113a3b648548e33d44897d1791b0a22ba812b611708a7a9a390dab94a41ba10a2c1acad85f0ad32c8b656d4aa0cd688e3a729230d642dcd40ebd8cf5b7db867195169468b02ab07dcf05681bcfa6f7acb58c6371e04266fae61508f201e74b142db9095a09be1c569c8ce6ec266d015401310244be72130ba5c95781a192fe2186a3cce07b1ed4981a21f9b05d6957519007d8736f1166bd6de68237d83c43c60cd0eb6042027d866134a51de780e6d87dd2172a1212009c8b43d34c746d06af5ab34f48f2c2e701975ad754209e113a68f6b00a003e2776d7abd81919fc691ee213f38d72d31ebfdd74efa970f9d4df541bfc467170184ac67e423a3f268c03cb94397f2b62cd5008be00ff0758dbc134fceb5fa00797fbdd14d3a5834343e082cc4457646cc6ded0a85efcab4e7cc18996a3f94bdba59d32b90e766767b0522e626be4ec7dbf30323d7cd108332c24a4189f9f2c665c9942fdbe5cfdec0f928cc29d785e5034ca8c2e279b94a732324715d4308d3331b6c3018af438fd366830f2346967c9043c8ae5c5d48ae08126c61ab39aeb6e2f12d8e1b2459c28f34b8c2d1955da836f4230a4767e5e497079a0c00de64bc4959ac0f68263400ab67d8434613062d305825dc5cc1d52929ebd950cf1f012a741301800d04013e6831ae256cb1fec4ff93e74d3e080c6217605c048ff94f10c827d4929c635bd7811d83e5a5e15f2f082fcd55d42d25495402f81e02e5089fcb0741ac12172fcd2ab1cf143c1b097e623985705df9221d95b19b98dcc2fd34e995709b459a52cc9cecb6b6491fab8de57254c8cb8910e7533025dcacf9659c03ae3cb8cddf79b4a244bd052ead291daff44e309ed4200695edd936b56005bd375a5f998eac0960ecd2a126cd10454e2d72d819adb42f77de437841fc5746c79fbd9164f9575308ab579d12b10841c884a473d3abd29154c64f26ea73923be628699671ee5f49f8d26a935998270b72fa4689911e651ffca744533f130594ae984eb8d41b29b412af3c301be74555f5c4cce729e055061a8d05acbcf33f7e33ce63f84d0c86fe115b10724ccd7e36855bf03d81fb970a28cbf2af221b5815fbcbd80dcc9f523a5d9552677f31f5073acb01ccb69b14792b0eef414f0ac333208d796678ad22cf41cb606c3201fcfbd443ea98f494f02e6948fb28fa709798db850af7c25021d44b3c56424f39d78d3e49e1221a34b3e3ff108813fb6c1f97a06d22a8246d0f21328b6cf11dab164972482672fa82f3504903ec6398c723e12c35a85480e428cede46f007876744730e62e32670d7d37f62ec89a06764a84e34f5490550166b51187aad21a5acb0880b9b7ab348c4008d0196537d0e13a1a53186ca878d1662ee74b3f3db5e7af531cdce6d7f8ef2006eb028da171e5f21371525b15fee1db7d7ff4dd160d81ce5d7b9cff9f9cd78c9451bf450a4229a48415d5920336123a05c7c0c94ef48644d2c480b440d8e02872ea051487e09b95c4a65658773916c17d34e96f4ab4f5f32641a5f3ce0fd6ae5d024f10e28ff1481d2f27d8961e361a58ec68be38ce8f2a63fb43aa3468bf27ddcf2a097337b87ebb27c8b74cfc1c20442b0de25a0bf4312d5d6c30e9e039b4d10433bedb9c2a5a689d41ec366466df08b0b65b90b3cadc26c717a8268d20143f8bf205fb7ed37fb01c734799f3aa8fef4d8d3e12050621faf15de95fd5e8b32601f3e7f09b0a5df6ba44319d00c5f07b145bef8646c16e205b51583580304761040cc4a7cfa251386220a1b70e73eae969ca45bf069c816cc667e012f29825880b304d5ec17052664244d38ac5f1c93827ddcf5ee9b1c7755e7f33e5fa103fc3b083abebbee008f1ff6b55467dc8efb44e4547bb7223cb81266945f448151a364532477196330f14c89513b0982ab5f019cb7ec7f62afe4378a0763ab06b0ba182fc281cc34ce46266ff532191ad8e2d5ac9d32ebf500185608c79308b5bc96fbf474b40bbc804d6edfad37d898bba9254382fbcc39f3961af12e0ba30343213fddfb9b8a45850c3593d8b409cdb889b00aa2f4929c50f9878ba620900f345565da58454a1a65036c08e31fa6444848711331698a9bcef6f10a6e542cdee3b96756a3137dcadd7d0035c9e525925c3994bb73355374917c1ed76e6ce756ef0273ba927cf19fc86ebb000be40899720c2152122218efff4b4e99f2a2c2a917fd5f2411bf485e45c621916b3a7d2f2c8d82ecfda3de9fa9dfeb38fddc6a8403c3f15922db5a804cd9f890de56d4b83175c4c4fbb07636730c8f382c8caa6a784224c70ea1e80beb5450668eefd22a3f2d9790bc5dc02dead1b9102ad81b578ced8b66aced4379293c2ee28f80373c9454722834454f9411d006fff9c71c15a059ebcb72702a35a479ce5fcff34d44df005d1004139f9260de3a564c70f3591dc72ad25c4270a39a9df90f6b019531d800cf9efb785b36d506294ce4a1d4936082aa54b5de3143fe39ead0830d4e81bee7e85c4efa4c5a46681e4c6cce41afebac70052bd7052a1bf0b42db5def71172d1edaa38f9ab4e0de35ef7fb46348450431fedc25fd0e193ffac827072e9736c7688ab8edaf099ec1759d43807259465503fae0e33238cc83e27bc2d9917ce99bb015456645db649ac2e821428c640dd441ec5cacad3dc30e3597f4a13bb0333b170a3101c40ad60e0e202015f9ccf03904d8f14a52fc0782140ca3b18bad9634e59730fa4df235029c44046479721a28a00c40ad86a9cf240114f160deae481786acef15ee3ae5f7e254edb37987045e531d29a95facb6f1d68091a76e603b1bc1ff878adbb2ecc613d728eb04f2113d7318110de6d14a5bfc04b5679b4d891712d987dc2d92d07b6fd1a9c1f253b89c4ce89d9cb98eded2c5e273ca44876d6a85045208fde3bc6d29c5aa590c10dbccb3cf0dc7445380273d58ee1216cb6bb7ca8cd6e87af451e53e6ab020ff965dbbdd26599683ca9843dd8093abfcfea72b01da267776ebff5ed505bf99a22c22506ed1518274705d3197f7044e1a62bae05480f08e704ce0fcfab84149f61292c500d7cb244596c2f6cb0001a790d0cdc0c42832ffd3014c3fb9be53741371de2870d82c3565885a8be429a886194010dfbcbbc34deccf0a2700216014f81892184677843f14a3575baab0bf460211e9ab64b65366979695487214a753406ca2889f6941c4226c629b74346d8f1666683899d586c357c4a72459421678a53bf816f059351711c1150cdbfbc1debddbdbc21cd2710242f7d92477aeed4bedf86ec93ffee0986db5b51ed8fe748d9b3e943c4a602cdc6dcd125d3daae0222baf43e2c3cd9721a61ae6007af60fbd03c7d9705a5170cb69e4dae00c4c019665e746f3feacc5595214866f28e562a63d3fe383b51d55f970ff46ee09b69d9c3bcd23db5067e3a2ca1902cf2282d7741c1d024155d1b5997ac6caee451173d8e5440b3129c18a903588921317bf9082aabded14a94934d7378adbaf64bd6dfb64f75177a7c06bbc283361abb00a9ce97bc95b04fedd1a14f619723d6157ba1f835a847670c9536dbf99581ddce4cbe600401badcf2f3ac2268a6615c2219e78aa1725f24eac31bfe6335fad22443ef6ece45d9ad9b89d20d49948323918906462011cdf886a08fcef6be65f06f17235dc7350261a0c4ea2d6da5ce885d5023a856d684ad2d0e79715a8fb7001094c21fde9ad22c338f774ced8053b41a5012085720fd96ae2e2db857fda30c48590a01d672b50fa6ba746ba8faece32230c4e1ba387332f0c7c26adc48185d74a42db7752d445ada5848252b133bf56bfcbab42ca1891287a459eba68652cd459020694db443a4405e8050f55fe4c2adb3d107fb92d8054e0517b529510badb8a1e3374b73d29376f02b5b6daa16a4c2a8a4a972474043071be9644aa6e877a0223fa359be415273484b646ee2227918fed34ca8dbdeb05c6c5c0214bf34d277174fc8e927c809ab59c7f52b22142e3ad902b56ada76412db406f6651c09aa1824572b71392bb3364e002477951c4a9973044fbaa51cbd6c50035cc507dfeffd388edb2a2fc87ff9c2b3a640fbe63c40989d9be7712ee62d104e21543ab0cb5df97ba21b8a3efcd71a7da3b215b3a2c41645d6ebc18eb3fba71812787b2e7d64a5ec3f8bd8a47f601b5033c666a422ebb53185c74b27aef7bb2a8941fa02e77d54bcef4c138f630fcc3bc307773fe7b8dae66ea288911a08b33f0317c606a1b13ba8fa2b25290c4a535a5c8e6be875a3c4f62b3b4677137311d081d75c2c5636b518d27beb5afa9cc561ff4c5130ed92a60605c10c2533de3e55fc08e8b03a5282388ee39188120cbbebe1e19a3578c4080104fc6825def02f9dfdd573863fff4bc448436dec05d679ac803c56a0815a1b6a0016e82bec6ff52bad3622dcee0017511af6211ff4bb77d72f614d3cfbc4eb414cef73027725f4884740d8765d364a36d073a1fd7e25f08ad6bf6ef73cd7df8da901d60d55cbb6873afecdb6289c327e7bd67c5b0efcc3c87dd954abc6d62ddd67f1a9a69c6c8704bd64449b1e86f8f8d5a6f38dd8f0647ac2a85edcd3c4674116de878465f753ed1f788e58db4ed6371eab746bec1fa9325fac29da37d286205bfa22261b939c39cb3e5ea8dc413b50448604a89f62528aca300f837220e009ff606fcf98273b0f52b1acb159e267541386586178b9ddb2a6f4d92acfc3dee9645e7759039e582419aa5a89daa90ecc632d562343773800e1e67eb5526420c9f27e8241a8e2ef85eba50774091342d12d1f6953305d496536243f9fe3b7347491af27680464add6c7845098ab5aa5190eb59303e72c06cb9f3e32e17d9a49100553f4e3e84922086402e7ac29933123821f2d0b9c7304593130679fe8a609c30e6003b90690825cdaac8aec0488dd0099cc8bb8e9e00c955bb643529964d31713424193d0afe6ed9ea8e0f097cb894981b5a1added8ec1d29839b175330c5a31bd84128065df8daa9241788fb09597f0eab2726b8c39ec14f28a1bfbf84ff09f10840a107187efd69d3d39859cc1efb2bb9c87c8a22e6093ddf9b3305dc0d6c6de3287a8fbb3af0a116814f4e8316756d3037f1136551cbb57ddaf8ac7ad36a8c3660eafac3df4c9fb7dff72c557e65d5a9f58e639ae7f0328621fba2c43ff33cd704615c0aca2b8ca7e51f3f1fcf769df083cef3e0f8ccd125a03cc5a82acb33ea3746feba022b386837081ce13e8ad34d7471d7167c13ae1e9dc9ac2a35a5a2f4804fb3650c65c14369b760dc485058704d470d415525a4a24fa915a234c6af51796222ca5ae628990ac58eb86ca2c3e2a2c320398e621c0775a2741fbd28d676ee88e623876415ff6a51250925ac08cc8451631fb289474b32b294d9201543b99336b695c9a4269d72485a6296a93328df461e2790669681466eadd32c2bead42c153a9b25f8692e93780f73a1423c9762d110ad3892f58bd127ba72775af24db442a26e893f6165eb66d64b2206a14738e84ce722a0b64aa4018b1f04913cfb0cfc3c471827fc91a8475e698a6d11f06429f488de78896be8e0807a49c209d795d4cd8896a26f9504abc8cae2dce4c1c45afbc19115ebde90d885cc1c4d711e198c279d9a76ad6049b939a87c6f5bef7f4227fc8e4c12f872a6da652092fbd62ad8b7bc2d1eccfa1fcf364eb57e9c72e1ab649f1a987235b9c64a4d0763280d61a7d025180845b855be8338b028cc4283008a96dc211b2b548d293089cc94a29430f44b12f3415de2ffd53e9a3834a9c4a5082a8412fe4ba485e4addb91f8bc3381b5fdc089c299ff793fc3de6ffaa960cbf44bd224969b8015fe1150d0f7ee42cd97160e96f17fdd2f89b16b1a598a882db37b4e358877cffde7bb9924d696227a9c6cf589133365b987f8f4b7a08b8a6ed0a842a25f449fc8cdddd6127fc2aa12750bfe44abe8aa96f825ac3851b7e04fb492aeb0de464701fca703eaad928c5a20cec24a074d7df00b6f4f7917fbb2189e47f9c5bd24f2b38a9528e403d782be7fd28342c180fb72fc2231a2bf4cd331840b9dca29421712471b5b0b40d1cfbe45751d700bdb4253de7381309f7d2209d97bef2db79432492903ce086608fb0819eba966da9852549cbfe451acc4932f753ce9efdce31f9770d8dd772cc994ce97e08ed7fdcd75298d1cfa237e09a290b58ce93e937d09ee90f3a5ceb8046f7a05a6f94c29fcf8f1f5a707a8eeb163490e772cc975c936849ffbdb4d2c6aec12f14f2c48f633539225ddb964736d221286e4ee9f89496ba2ed3d5d3404c4a5a0b61fa5948ba902c90f2175fa5539bd3d7ea64a749b9c5e2b6aad2e8761bc615af5f5eaeefe51b1e24ac58d0670428daf21056cbb5f43410e93efc19e41a0079b6efa2faae9dddd6bc8df833d41b0dbaec6a33d44bd29db6c2944eec8af5517ad1073ed555c2177e48360449e62a61aaf8de7615b9dca60d253ab0ba162ad95014ff20483ec1f913b5455356bb50c5a962f83499e2f9d4a87e1bad5cd5a5bddc8949bb55663dd63244fbb54556badf5e96cdaa8b5d64b5f524ac12d2615354267f408d48ca2a2321a8d46abd168341a8d46a3d168341aad46a3d168341a8d46a3d168b41a8d46a3d168341a8d46a3d16a341a8d46a3d168341a8d469b1b6b1eb9f37d25cc085fc2be77853c431a843903d7d7434698137e9e1e81d068349a138d46a3d568341a8d46a33945a102458c972b46d068341a8d46a3d158f48b98d46bac877bf9530c9d6ae68d2b24107e89f32d39693e934994c8f362958b969be4096ba67c7eae7c624802591f2ccb49aed92b6df94feed36a853786addd629ef759cffb3aee036bd7791c0657ce711d0671589610b10af9914f522a48ce271d3e8db5ac9a319cb0c601b6fdf9d4e380bc6ba0000a85bbbec7c91d5b4121d6cd4173c0f80a08020c2693f93483908c5d99c6d0f349873c75a497a3582b0f773f9f9c7e9ff5e8a2dfb3f498bff72ab0f14fd1f338aceba6b1086df2bc42452f7432a1c63535c534e1c5ea9e189e288c3ec64ff3c95a2f7fd2bbb22943c87023c92471411395315e90a010aaf2224b9a1ab47063439917d8325142bc8608dee188a5b2430a2c942e55a47901882935362e58e1c40bd593353f60f1220dce2200780ba6272f4774a0c9c0bcd0c4902f29d842f694e68a315b6437027024513754997a624272a516812a55be884112c4154f6560c029f3aa4fcc701aa86189299260799306cc510b3fb0404393a82bb250819913706692e4f81495374e9886ea3f98695ac24c1120d6a24c1476893265363fe25defea024546184eaea7b104ca66b3a04b2861457d5a42841541c703ec1925f64c934d1f73b0a596332d6cbb37376aa07491c28b272c9e14d992440d28367491824407d91246e8565f7b7e509a8c3f840fa8387fb27419e28b2e3e6c61648e05960cee82c31ea5d3c6449713600a622daefc618fb20a699c4a86d8e3a44d2a33aac91e67d511539878e0a28b1ea6a88a8da21650cc50e1431923a2aa9ea6403245e6c20a86d0214acc0134293aa4596a2345556c66003544bc80480b4bb0b4101b27131a353851250999a4a530b171364d0ddc64a1c1490ba65c99121b672d290b3743402183922f42c4c649c5a58acd8fe0f285fe94bdd9f4a753175976e528f628427131486d6a85b7e128972fa6ba292eb822c61576d5a4a976534aa010cc2db71087fdd9edb0c9dbdf7f0975f588bedcc955024950fa2777a8c8db1ebf1ff5c739ce9d82150281775a4e1b9f779dc6957b4ea7c03dd675871e8f76f77277ba52714e5f752d3639e7db6193375d6548a70dfa30b84d4937e4b1cea86c769392926649b3a459d22c6926817e90ccae3ccd9ca838d1d91293999257b94f454261fe35c96c86c4dfd2a8ed6fa1e48e5f1ffbe37793dce7ea8aa4ceea6c4645ff1a69f2e8544ee55acc1baec6d748c9d2e4b1ce66482a122a7a559a01b599dd264ab1912def774fef77cfe36edfe9d78e7ce57d1edd5f6dc444747f7b238cef6f5abee66fbf3d8fee376dc444c4fdf646d23bcd63fbee3b6dc4e9fcb17ab113408b5c7978b267d709482385e8bf84e8d77610ba45e0daa310994cb683b8b6cd2f66570d010e2a77ea5390d220a351352a2aaa565ae974e944acb5b43a55295e9de48eff8dba51178a2b86498d29aad3bc3193a858259d566787c9361a3c1c636888343e30db3e058211e6ee61028feab4019333b9fe589d6e8dd6aa53ad3ad50610959d2410cfbed4c31145f6f7a7b511ea3bad51d1ab135494d3937b95dcf1bfb55bbb696eed0030e4b13aa1d9fef5c75bdb3e5e344e54fe45336f54dadc207bd2beb4ba688598fd3496ca9393d3ec46915798c5fa4f1b311179cf7a232eaf24cec7781eddafb4d1eabb8fa18d9888566fd4bdfc8e2cf57ef080be9de74bffec20087edf9780a76d015164ee4399380cca4ab94f7e7f4be53eaccfb3edb6cabf3a552af589f65c718c7376b9fe459187c79d6a282f93ab848a7e97c6ecf1aed97ed7dc27f7b94b14e68f71ceaebbb4fd2e0d202a2ff16cff8a447beef6af51268ff7e949eef8e390225b599549a0babdd27fcdcd0a5ff459ff9a8ff347318c1ffff744f8bf9fffb11e471779cffa22ee31fdd67f0f86389fc317fdef451f47bf66f74438dffdfcaefb952eeaf48b7efed6afbe084783dfb394a8b23aab4a5556935ae19472987f0e271595ad42f9d1a5ac24a5c221a2132a40459f9f1f1e1e51fc77b94c90d961fe15898a9e24bb9145b6c92cf59c785e2779dcc87c6fce89f5f87b1221d29912aa4495f6489596f8beefd354a9d2a8c8354a25828a37b2e4f91d752bdfa66bdcec39d54c1b733674021115e7a4da0988419e60045860bd7933411e3586b19e545eeb925d8d4f5111c8a7a8a8151e5a81c04f0a1e52ac386cff994d90627ec2c9f698b452b900b11d011dd0942324b66f775bed81dca908d815029bb576f4a0042ec47aa372fbe001dbfef474246c7bb924e963f8a514b70a6cfbf3bf306f77bbdbddee12ac73b298ec3be4d476fd5110e35a372ba0648e61af9c5bcdd84beeb6d4c245071610f986ece10feac1a5065976e5bba5162e31ec5184bac2c3b4474abc79eeee964e15a4dc09b2ed1c724fb9e33ca0f16aa53fb7968455ffc0a642ad4d591548e2786057ff6dbbf5abe90a9bfe64b9a6643ca933664ae77631be987e23d8b6bf84b65d7fdbf5b3ccd575a5f40ce642444a0b94973df2a881ba5213e22a413de92089ca614996b16596332db0720649166768d0019f019863eefa1ad4fb5b0c1581864041f85981f40b31c69b06ae8eeb38d78c8eebb8191b745cc76df07acd00c06052aff66e98ebbc0f5cb1728bd5c2594967e1c4005931e68d6fe7c8f06464d0b132d0806369805dae3c63c6dd6083ef555fdf0bc461ff05e69899c60fc5f6b79a93030294ec85dfbcc1491bf4e513a7b52777e86f1ae7661a00f80010001a000ee4f734628c31b62d0e3e6771f714c12d8ce78dfcc979a395f30acfc72e1bbce9db635929f54b88cea7d6eef9a25457b943e9dc21d5734e3a690a3c4fc60b1c6f37289dd3c6b5d569ad7ebdd2ebb5f61859c21c16b435237cebb64786cc4345f91cde534cb7774b9262b5186fbbba9173b7b35efd5cee5a6b078220ab8d278aa308eb449193326b164551c2a828778ed45a54ef4657a0f872b6ab9ed3da6deffbbaff3a9d8db94ec70bab08555dc81376403fa0307153d165804e8b30d0236fd575930bc3933a35d8d460e3546a6a539935dddde994f60537551bbb725602a160a2a553c39c60532b91ae1827ad0d1391020990bb123586858bb9d8946680892b5e7600e28a0d415c00a98a942660d0022a9ec43e299af8d9de7b200e2feb4f13e0656c9953ba897d6edc477a2f47717b9e27a58986edfd037ab88f74f2de87fbbcf740684fdddef3fce01b5884701a72c5132bb29817f362de7bcf8138bcaa2e6777628cd85df7f8c8ee3e479166779dab56fc388b8dc324d9d98324b2bdbd05716c20ec0b0514fb628b058c9b5d5b64a4e8210c24992c2b6d707a5844c135a00537183b79b556314bf1d04d2da3e8404a140e516a367d179819360553c517309bc7ca7f61e2c1ae5fb1d47f630e54995dbfd627a0ec5adff544d4aef5a5e4b1eef934de89273bdfa78314ab7e157f57bca49182872611f173cb8d71ce9e4469d29e58eecc9f3db77c974295e80d550c85d58fbaf6d21b24d05d85367643561735aba464b5243abb6fedbd971ea951952d55daa6d4549a5ea617ce265919152d9295d11eefeb5b240e872f218ed32faf4ad5a82aa6d630676756c9ca6c92949454084a4a9622d53893ad6c4a4d296a652e1aae4a91669db579e37aec86abda4aea07bbf2d319feb9e5ae511456a3a2ac2ccacaa26435aa46f1ecfa730a7398ceac6c4a5919f7e39492e2b62f843072947b3b61f27dcff33cd04be17bfbddb7c2fcab90f5361c6709dfbdf7bbd5df6785d861d79bdbf37e156287790f8623de9efec214ee77eff957a5684f7dcfb553b8ffbdfd6ffce1f23eb832d6a85dc5ec9066f6f7eee00e3965b7f77d5cf89ab52935a7be90dd704acd9a10530a6c22db09459f1ee130376b534a886f274c4ea1fbfb162ce1befddb09ddffa4fbacbaf7debbb72048c10bda3b5f2d2d7df52d643dfe705d967d1f5d17e45d2837b6e10f5795a262f5ea548d721f2bab5135ca7d70ac7e95b2b28c459eb52945c5fa4058641b8537ee399ad481247038319e8989fb2087d567f1fcae3c38fac565fde25a4fb4fa968e22624d280e8acab825abbad2930a565b9f9f85f3ab5fad9ef544ab67adb4265a7d0c5db4d238bad6d6af9e477e562ba65f37c961f555f7d52fa5a8aaeacf1a8b458f5023544667d386bfeda80170f0a824900af6f13bf7ee3adcc7d5dc7abb2ee83e957b6750d0d1cc31f790dcf12c2490fdd0c66cc8daddae35a97aef9c373c5a001140dcc76b0eabd146cdb421846aded860080f95587ba92809e5d95ffab62b0ea93c8a0dd8e36b07f7f6b9b72ff70694ea8c8ab83e038ac8639d5524d46746ac7b8bdfbe84f096200e70c60ea254d447b6294209cb133e6041432656a5962e4cec5de9d7a5caa4ceaa92100af397e1a43c73753614a9de9db3477b9c5ee68e983c53b00f4eedb96b9cc95dce5e6775d669170d57b73109f33b6fe3705ee9311bae7615326f70bb565adfc33166bfb8c72ff7bc2177fd21af51587d8c7376b9bce635b953bdf6b3eb07a13d1b37938008a9b399dca9188804aabb0651910bedb6a126632d5dbcecefc197908df70d5f47bb86177966432054ac6278b4b9d0f7060ba892add403999b93558806724389bc63fed52fa13bd67dff6873df8e983c86e06883ef352a8225803bec5fed81235821fbf73d9004f0afbebb06f1099600ae3c07ad4dc1fee546986f8228d7e9d78eeef1e7e8f418c47f047373ef3dbedfe7a0cfbd0786dd0b0939efc1716e10cc1b06f1fdcd0d7edaa9a858bf46c56a6bee5367b5be53d559cb862c0408156b7d2028fc6d2ca9d8fd4bc83e7eac6794b78124a0a96dee570077cccde971470fd9be943245d20ea237845ac262691913c67f5fdccb8d7f4836389c916dfb5d7d9d57ddd6bed59ba54416d269206f3dea4e39af183d4822db574f31549c5054b4fed549f7e05473cd1e27d5a41212039f1212c4a992ec518e753bda9bddb68b47ec638f3f5cdb9d80e0b11f447b44d0e1922aa14aaadc474eeaaa9a55f267fb77e03f8ab2fe288a357c0a923694bba90a572aa33e73e956e5fa1e9e7bc38fed92046232c9c81b33c9f7e374327fd8d6cea96d676daa19e7d3cacea54c65d65a9bc3b63f4e33dbfe17d21917d2bd79c1dbcf4db72e9c492c4d9a39d02312486e12ee2f69b53278191fe35dcf44a4c1b7bed5fa184fd4fa1858039c7f74b132d0affbad3f8ac9d0f95b4f94bf85f3f9af2662e504d120cab166ceacede821e35f9269dbce268759987d1286e4fcaccff918cfc4f48a00cee73c11cee7e82226ee8b7034a789703e862efa71987d1cdd7afa0157f9c1e7c1fa55d62cfde2b48f181087d97fdd6d6936d99f34fb37ec012e61fa7de13494fd59a34dae8f9ff56207b4a7e3b4775f42fe1ba062b53a2bc8a204e29937eab68f43ded09936ecdb1f11c085b0ad7deea76c15fbac709c529b6e0f4fee3758bde7719c9e1b0ce75e815e56f375b6ecf9547bd21adbfed0bcc2db4212b6dfd143deb64ebf76cceebfefbc0777f785b51d3d64eebff7bc25396b19d376ffbebc97bb1b7f7bb9b9507661e5d1e20d1e0279d6d954a23df53f3bac7e210a5063f644012a7747956627ea6359c6052eb04089490b364870a6d0c20a30aa86886a53c39c39b0650b0d8a13d0ac34895da819d385931bd298a9d110f2233489d162861866382411eb01861a169828e3e485222295daf7bddffe47b1fb7356ebe3aff55d17f9d7d8f74515e3108739bcd3e9fe7cba579c717ac294051928bc88dd9fb4490415afa5340aa5529a01d644ddafe098e3230209bb3688dcb95f001df2f54a696ee79d69f6fdfa4296404524e666d23877a0e1a947d7a629ad9b4db3fa709f177e16fe9e096ba2ef59ba08fcef8b56a3a47ae10f72d8fda3d82a7c61ad0211f82b15ee83c00419abbfd24545efb0fba03e8af9cb98f78d9f80237936c99dfb2ad4d944ef4fa7f028068647b11d6d72fe7b7f2add1d6ef2389b684e739fea34936297f5f929388414d607c38e8a8a770ded7238a56892dcb9f7290d8a9452cabe94d2babbd2b4d3e37c9aa10f8751cd262ade57409b4c7fc87dbcbf59fa94227d64ec624e8fae8b31de1e632a95b1a047f28fdc49402daf5e43721375311482f0e1b03984747f7b242a26f9e0e005799c4924e1247db6bf33894db59442f2ea1f59eb7fa0ecf1af2d2a4b402dcb782377bce6499d514a99e00f744476d1a03d4f85eced69e84a1214c2dbbe2b8d477bb30f826ddbdff3f19833a6eff45dc903c0549e5b6a29f3f269b7e7f738c9ad7e26a05953c44b551063c4b480481385c40ad49414338f63e1839f10a613192e3978b236408acd95bedf1e879482a07eeda00f7e0efa601d8bb60786927a1f448fb6e747a68dedb970a4537bab4a36a6329c2c54b25032f2c3961668588e3ca174e4882088684064cd10554aaa9021e2036a508082336892f8128321d88b94923a4241d5140b4080e1d205931831f490430c609e94c2e06455a494dc6a153f3f221842454c1524b87cc1a1069a3664b8b020c50c3554d981c80abfd9aead2e35291564b44c325064b66cfa58eacbf96a6ca9854c1332383891a955ee0475516bad38bcd6d1eed1ee5a75107f4c454ac1a80868527f82c05ec190c99dd9da7262710150e5b122a0497677cfb11a81b5ab745088d269e96a5461fbccfaac537f9cb533a6ac1a04f3cd8e9a5abf39a7cbcfab5bb7e0038e5e748f3733e14d6b2dde1c46ad00a8f2f86de9d9af6a9d9b437be8638ce96fb66afa23de96c3db5aae560a8e40b7ff47abe5b6d52f216bf58fcff5e3db42d4f36f5609ca2ab52877e66f4660fbe39c61c6339c3bd39e4c7beaa4d489fd304b707be992586a0f62c31f2aca6dc3e1f71c7c1075eeb1f4e99ed3e37dac47579893bf14ee6f3a53d13bffac672afa0d73ae0d615bb73cd82ebce66d37de6cde5e5fca6aad8e8e1884949985dd9be1c8e3e4b55aba0d1140497e9e6da7f451468db276afd76a7f7c662ad2fa5debfef4bab5d37d660c47bdf62594b33d7c09a950b7eb6cd73f7876ddb2a76a05418b7cffa33db27ac77dce559d2dad8f45958ab2c78e55ffc8d9479b05ef8ddc412246943cbf524ae928ddcc314ea976f7e12e848a042893e7d3f9e5a05b841861f29421449e329ec85892e7cb7ff2537e21ee41ba1e5f5e37beb80fb794b2c7d70b3fdd7acf3dbeb6fb737f061b68bf2c4562054572473e0e45903bf2b730849027ac1489976bfdea34bb66f6eaee1d27e957af7998f648995df5ad63ab6b0c31c2bccbdd550852f712d98bc78cd99f31ab933e987c09b1b63f6b2f2981d5d861d98536546cf104963335bca04b0a8e78b181694a132b5e8481c1e8828d0b5696943821c315139ee0a1c892206a5d3cd1792ddfb5609d07e787167c4181114a2b503aa2b139a24d1659b0c00087d8c8a3c3dd7c41e38a15168680c2c5134d5ca0ac59228a24304c35c9a1628dc144a6fe540251b782a5801350853922650552b0d4a8a2cdd31217ca4879121b79bc686305191534d1788042c3962216b0039b25bebc80e4cc901860e4d1d5939390886cf72d24973648399c0953054b145088990bce1c91c609305598cd14279590c2089b3032b0d912c61114343db46922891162b06071595150040936446a0033446c74edcab38924c55d5023a2d85c69c2780186a937554662f5452c81e8a644f6a65766e5388ee3388ef33ccfcb2207cce6353143190f8a9b9970d1e7a18fe9bf5dc14a4c15f795261fa2d8d4bbaca4a09ec7858fb34826e331f47f7a9ee7799e1e7ffc6c5db7e4b965d4c6dbd5558fdf42ce2122a7bc315f6a4002b1b0e78da927121123b1515209e1032c733e8ab5f79b1ec5ab479e4df5a7ebc51b589167107dbd39b9f7709f892461f48dd4a8e6d7c37d64ac463559f8414f2554a4f4a792699360eab4d2ee93405e0123097445517c710950de10c102f84cb6820b1c42a6e2baf201f5d1a143ee20e5d95929729cfd29725f9fab9eed386ee801ee434485a40d3afe8c3c7b87dca1afe3e889be0e29c71003db7f86f6c89bdb95a58df7e4e00d174b4451224d11283c145112028828235c50f246cb9b29ab375003c832854a566d134c355c2122831568b00091430d539ca8e14b181b72c091613e254d52a07480a24a13278cc8e2822559d8c0c08508ae2283e17362753c3925ab9094e4993757c090e50b1c68f8121bb3c8f324a992665257aa4b79010b2928d98e21a6a039a3545352c1529421f6e882fa9e58515655e4f0e9709d480d9152b2479e24d9db528bd40d384d9eb1a516291995142871818d0c9963339557693a2261ae179975c58b3148705db2065b6a19b304882c634b2d638ea0604c91bbc40233fbb450adbc4015f1d24481558a746a943e26235c8dca3b0206bcd415f1c2a6e689f321865b4514ce41063b05d48604869a46e97a992139154d0e935e9292685dc28061845a529735308c404554064acaa069ea8ec833b6cc82260546a069a1cd192ec02bb96e99e54c166faa70c1192f33e40cb6cc7206094cc4199a4b4bb85d3326963b73dea8d30627d2ebcaa998eebaade6a637c755b9bb29c69a5afb355090ad88b72c3d7bfe0f75f75a6bad5edde9ac3589bc3dfa397287a756ebee5ebd563aadfd601fcd39abe049570e7e9e77ce61bcf976f126f250fa78fba9f182b3a8d72bb1fc15053fcf3be7b06f575a108cc8a1b4ba3b9d53e7cc72b91ba1546eb0c4a45eeddd30d7795ff7811db8eab88eeb56ac8f95bddcea5a381c4e8c1839d573c779ce912123830c401c38f60b4ff654294a7b64e71ce2499dba42c7ad918a023f37a534838f8cc9ec537197b32bcfd8528b993719ca2669c3792b38c121895645258a1f887c4a10a1828d49ce965acc5421842789789925e79437a98bab6715cd373edcc7f5524a27305c5138b125962da9a438783ef8114102e53db59544f6389f7c364e2a9f551463ea64fa50285a44baa640c180d690f323bd01e747bac3a6b489d3248c7e067ac423ced131b4cf70f49d51b98f439130fa523013798b769adca12f23294f972be719d2a136bdaeb04ad87d0dc2fb39fbfe6809e5a25d692e57ced4359fe69cfa025a4ebaca7ad215e89e9b15aeae5b29dae7bceefa99c07a5a4eae844e4f29deb7b3debff3093b2d3b6d3ecd710014d881f57c694d6065d0169299844a3aa9a4abb98307821679bad7d06db5b3cd769b2091d29f0329ab4fe947a2c8c0c990525ddd7d1fd539a578520f9e749fcd7a6cc6ee16d60f648f6da18c5d1bd2988c4d1fbcfd127231552019b2adefb9ddfab672baafaa969e02d7151b9529a6385c040a165996c2387981f3c51150a6b0808813292e6ad3951655c3cd07b85cef2af34215294852a22cb1e00831426ea0a57112b504d59533d9866f910358a505338a54c0c40d5b289151338504532f4471c2cb172da4aa7cf0aa541561837b01873050ac8c614a428d0492c64c19f326862645a83029c2d3b03817c04861c10e6e6a37a079e108090d47b879a2298629cab0a9dad8bce1c0b17009c3f5347a780265858c95305e92482b54c46048132f4ab0400aa9339c931132f3e4872b4d48646621609a218635475430030ba8582634e05a68ba4a5f112b4f4343139725596268f2048512496c7902061b9e30d1c50d5db400e49044d0f100fad34c97fd66a6d1d13173c547c66a8c7e41646f4b2d66a46c9e8aafad3e5d5a6c66684e30c83e6f7bfc3cb8efb8c7dc1bad5e82e0f3e87ed53d883d2f0cd231e447314fe4710ad231549dbae7e1fefbf07758e6d4933449ecdf6f4ff4fdf6f637efb12ee2defba2eebfecf76a22fcae8be8e32ff2dffe2866dfe38e621df79dcb61b57e6f828cf977baa8e828467ffc317bff4084386cca8e625c78141bea21a9a08008711fd9508fedf1237d5abaec5eead4ea42cb695fef63553aab2e9a4bb0fb240cc9bf7a2622f0bb4dea998c759fbb8ea53f9eef79cc2b9e5891c58c56007fa5796e7dd90aab37ea569ac93ef8df8f3c5a40fde9d7f6df6be3e1fda78d8c78749fcedc1771fad34541afcd7ba2eebdee16bdeee1b01ba3eafee67bb9199d6ddb06ca1efadb369d362158f707b0a5fbbc26f73cfc39cdc37b9d1d24e2de5f93fb4d1375efe9a2d79c9ac88b5cbfc3e41fc5babfe1ea3efda3d8bcf489fca9ebf1674b22cfd33c0e93d267c81d4b002bb9fe7721172aa08b2cb70cca30199b7faf1246e40e3a98b559137574a02817277c14b3a1fdfa445313d5bfbae82816e433cca16206618b3cd2d8747aaea9ceeb38d1254feaf809efe1378404ab240cf9a2a22f6222e2debf12e1f7f0775aea3ae618b6dfbd8c79e88f9f07dd9e74f80822a51b2f526a24559008d55a6b8d4223ef39fcfe28744f99883a9d1d6684b57498cf2ab557bcedb770001bbb8f11137e23fa315ecec779f9ded73f8aadb6fa44fe5517316d5f547fa5374d94f39ea3a5c3c03f8a81ad574b8f4077ab03ea239ba0baf7de7b2fa5d252c6cb85c282e9deeb4363add546e3fe6b31d3b42fddb66d9be0105094fcf73d074bf036c77d178e47bbf3b6043b07418ec3fb9bb5fc9fd7ca61bff5477bf55b3816ededc170cc1bfc1c8e73e76f85928aabf7e89743d64b3087477b0b83d0cdd2b3ccb4f1fd2a1c2711fb7beebdb0d352878a127c45807e8c27a21f43634d341f670b41aadbc57b09c9972f37fd56d57c717e76c950ce1ba07af8183ac1f5d45feecf6e9f844d63e7b0fa95f347bb87bf0fffa11384eebf76e0df7ed3296c8ff5cb45c3c7d0095b98805a06c0969f634cb6624b2d65d4ec190455e6caf61f22924e73ce10a838ef036013d11efdf673d4b7fa2579a8487f3b32db3504da935fccaebc2b500376ed791d125c76407b441a1b6cff0ea828fadbcfe16ff5eba3626d5575008c0d6386d48c2c61e1e60b9818b448c1e64952ac7eaeef9a45e1cbbd3f8feea936a2dfbd6ba337f2e73c8fe72826c10874dcfcbcc97de775a18fcfb3633cfffd8383dcc733c2df61a34fc6b0c332107f21fe3dfc7d7c2187bfd346a027e74b4a9f0d9adc7d6e6f4266c4dde9fcf10fc108fcefbbe71e05ef31183211798fff0b8d3a19f326f53a8913834c7f746def2177fc55a8d47fa0621347933bfe1cbc204f2c2490dc3e2e2cb6db2de652ce39ebcf49655dd27c45007ff73cb8dfb4d1f6dc77da8889687b4ebfa69137d43dde744c2454a44296e40e7d2d5a241094f4915192fed4e1b021f1e513fdab27809fe4d39c734eaf48a850771579e88fc3ea73e1510cd79738d72b8a3ceee35fffc77305b50f87c5baf738ff98587f04f13a0e5e902793d944fa742ed855caaeba3e0895bbd7ea7bff03658fbd16aa72e16d19cca0a00932766b38c2dc42a838bd6fe1e3beb5a583235024704830f6943bf30d076e691f7c145abf7aaf15be86ecbf4c90b1178fb738cfd22fd712eb57b5cfa385f3d63e0fd6b79ec5fa966e79e862858fe37215c0e9ca17698c98e207260e20e60624b260418b0b49b66f853fdbe7a93ce4b0ed6df8aa5a0715b797b1996b0b0e33246270022e3ec436a9041a375ccc90a87c9121b6fd9c6d3f9586aebeef7d0bf6bf0524c9e344dadb7be09cc99ded55a8bbe5a58b926d802dbd3451b5e76c2a31590a8f622b9cd6b6c34ddeb69f4b5b8efbc4f84dc6b621a4189f3384d47a1cf01581fbde9f60fffb9857282a6e9b182a6e5fb7cf09a753386b726773da76da43913e317e73297bdb7ccbdc6103eb2a94b14fce28b399646f93c9de90946cdbe67586a43a4e38ab1cb67d6bfb560cb22b5171fb4efb8c8a1bd09aecdbfb709fac5ff5c11eeec3d2af0a3e0fcffef746f73d501bd9ff5ec6b69f48d467cea68cf6f86f0fc47d56bfcd69646f0de822a031a8744db6653d0a95b21100002000b314002020100a874422a15024184f4649f70114800a78a2407c60170a644910a3280c42c810440c21c0000000888c0cd1900de63f77015a53d7a0b0523beca53829aa8cce751d9c4c70a755bebadd30f9db7754c8593168122aebfa84593c0b31024152241386e7732deea1c46325100011b92024eb53ff65192b510d68d56910e5c33eaa82cd3ef1a2d213bcd3db8611ea553551cf5fedd5c652bb9fc6751a514c2bf7be981efe5299b692523f4555845c6048c21e1e9d37c0d6308130ec6a56a355283fd287afb6ceae822cb73a1eb7352af2d97c13cf554f0fdc7c6cd67fe08625c5dcd104103bb2a43cdb1b9b3f7f30a11d6f079f191560c418a84326ab420ec472eabfce4dbd96410ae59012d749309bce56ee176eb6736b91f90f649e676296020680aeba530b5f918061f5ab4bf1d19156706e0560d5618a770b535c6360ff2f20a172543e4b951ba0c6f4dd19ad775c3d536b5ffa186d207a7972d7f966698a3af4a3d21cbe39e2d63c2652a86b902db004c9fe1e3d06d1eb1c1198c8f4b624b61122a9274b825d18c335d8efb3474b6849411601060b1ed05a53fd78c1685898221659609e009d611f87b9a91d21b20875ff9049e626741c98c6ba8367a02f2611020793d587eb473816fabf982b3c17c84ff47d7b27e1b804233b9eecd390bf8e3567fc98a9b0c89033ad13deecbf3864ffa31dc58b57f3a585a99a4c51ea7e116b71370dc7326cb800c3ca4a78cc9440ddaf7d11db5c0b593e7c8c7f8ab61ad9d8e19b41d0b50b10b8203874bc7dd4c474230eab4824feaf70f3da31098c4882861cdfd6cec39720ec119214a391e435311540b1a4e2da6095f22af838a5a3b882c26e4b991245f2138063cf67e41b963baf557701c2772afa857eb635cd952c82767dad11f6a26347761d627377741eadb4bf0590b9a20193ed66fb490327d688be0b2d41eb44e167c6da922db7a96e2eb7b5157197caaef51db385d998faae93189e3a84c2ad095f78fab15c81f08e1bab49957aac99e89aa00316886712a574062ad618f11e48f7cf58ec390363580b77a4e307eb8695789e0a9e729913b10083561e3ce6944edb0580a7c1d72517e247e8f4433b83e4448023b65adc481b54697d18a37c594f0d43550cb5ac9e059760d5423759a21a38c2a587e3a18e0225418c11337f52a016470f97b6b2f76779bbb10581220271b0cc4a9d087b438275fad9d302909090df7e55b781d6243856eeda76b84b508a1b63aa36d40e8238b97dc1a1afd406a3a417b58408b7a5026fe02538b80cfd27420ac1d84b11189c60a65dfe649480ed203fe2d003ba822cbe50d1cdd04eb25284680fbea7c12d8034ae06a48fb40cde1fbc05b5fdab4ee3db705aa5a40b4fea82e871c272147cd89a836a938183e92e7977f085880eb3d0fd92a954e0dbc8ba914d75c248bf04d9a47bccb5a7b5ea7bc855a811b70e1f6e9dcd71950dfb512d6765414bb108c8b02b010df4a09290fdb49a4f1a27ec251aea8201bfe010b07eac2ac71af5906a2f6c10c1c461910a282cd8a21eceb4aed5d5e6fed0e7cf10b81f3bfdebf10414d6c474f9fcd6279d7d6d55b474540d409133b7f3b1259bff06a5efe83e67e350ff728f59e5b53108b7c3c4100ededa5d5f900419d4a1296aacc0f660de6c1a02e342bd64085dec535759f167ba35411c1cb92947a7706107fae5b4625388140f46ebaa882dfcc01a8d8dfb467160c03e8b3f994669e7d3f9b82a8d590808746b3fa101871d31d554a0cc9f10547271ac48e06beb5941666a55225e6fdddbe934860d355bfeceaecd2f4dedc51cd7b9fda3bd6de2f5612ff2817e927ced94f1e9b3e2dabeda231cc3ead7554f5236439c9175b9cc1523b67c3d749cc69674afbc65e7ebc8b82ba703ee60d3464854b20a8fe8f28d4a7c7531900119223743b406c2948b7a5647ea04f8395b5f6048d790d41937dcb922c98feff30df39353e72275c6a5b5713755c01948727dec1ac89638b036e2d361f76a4c827911f50b0b567a3d6c3f8595cea3610b73192b871e72f4660abfa21f33f104492cb996fddf47275ac5a9ccba625ddce9e9891c369c8a00448f81d16c7782a4b18e5b4563c1f2d36f59e2f20277e5a3fe691ee19ad9bc513044aee44f34a3e6ed366d0edc7897cab5c9e4c16f5e1cb1ec190c4ce49f4ad79ae529962beac22f9add437955ef65d92a4f6605b629eb86447f4a54ba20938d694ac5eee48e79947f59678ce609db88aad589529d7d7133c9fdfcd15e2c00934a8428c9248513e086e3fe065d74d7da07d12ba23ba8515170961086143c58b7ecac71b6a6a614f2ce1700e7fdeaf8ffa7615d0ee1822286008a1a05e842394fab8d6712e83c9f899d812d6241f9d753d622b6bd980560cc39156be88d38607cb989d0801658927604ca7afa6b07af5d2ffc754c8f977d942d1b45a05446bd21ad159021eaa6362a31191b910f214764c0096db9e523c81074ae65f504d4a29b299cace5560e12ddcda0b653e0be31167b24a4a48ed51030220aceb5992b3803843e2be40fc2045f50587ad3138ef47db58016029d0a659063b435ec3f68df8e33da3bd1ea8b883da913be0daf1043522191ffa316eee4b25cf646245a71591c0536e23ea5da68514bbd0848a1a1ea530880c98271aa089b20621e894dcc0702d5edd99e0927312104bbe084a5c33011f81938a5559b060e7ecddffce7dc4ff597ee39b4fe6793909094fea9086df8798429662ef34fed02fe29e041dd23990c38de40de9987407498d49569e098029ffd41544e0882987404cc9c22653017b462bf2ef1ed0b3d80b9d90b9bb98bba59637282e7dcee515d3a9502f3336fe27225d860450241b074bec139578fac4277c6c68fb3733f36ecf01f7a47820c0bcb18e957058b1e9142453812b30554e9403f50620bf6b2819cbadd79967821a694a4307f27e6b8104d5f7f86b7e8b21e926e662f3e5ef26936ece0ca5b15e424973c71a676328e49673111c6fd6af4a1999016777bbdbb55215c8d782a0fba86a8607e6eaa7c46b2c90cf760abc39ecaa491455992ba6457794d9ca7879744e66c2f0fd27a834d5bba83eff7e5c5e3100bc3b1e1b310c02959b984a006bd97ed325999a2e32154c4f702e267833dcdbdb259f437bc0677ca36e96399e41fd2fcdda5577c0113f64452f15707962c187b908292716a641b9042ddc3e0bb1127e3f33ff42d913366f429cae8b573d6308ce883811a75cf93b365ba95ad52e69bf9e674d957efe04fc95962a9eb84fa838a8c4ca23cf3fd953834344244271c60a515f65709a9217d564eb5aa454bd0d5cf71fd41995119a2a2cacc882de974b13ac1009cd13a17d2ac54a48eaf28810944942a0c50576055a92c98065ce5860bfbafb5047e5f2f6ee783069f9f794191d5fa5c3d1d273467956f5518fad8d5dd354e6d6ca6b93b3be20f3d4cabbf84063c44cbbb12172814f0a73f98d51b1796fd7dd4e532a2a1eedb47110b23f07c5a05eaefe16e7d4bd5949b2b17b10b3d517f703e1b3f8c3f68ae7d2f7ff9ba54433b707ce66420d7589bd81bd974123a5acfa578c6a99f4c980f1b7d3d3e592a4cde2756dc711505a3c0e36b210b792e6575fdfcf3455c9c714f215f10cddb116595361462a52a489287401dd8aca59666e101e5cf9feb21487667896cff7120218557161e4872ceabedaf2c87e7314b2b71fc5ad62e7a480869a1f4faa7072311fb239e43f11e9491bac007e16ef68c048abfa8e1d2cf138e1b48f15a40b9bf2847d28197bf60791e37d3753f07df056a0f081cec8911d8a22b13fa5890c8cac31dce65471ae78ad17f0b7b322ccc88e7dc12e47b2098ca8f5b6195e82e45e51431f782dc3748f8942bc27f67cc02544e2578a06cecaeb5de31b127a0389cffb356fe1d781794512ff1c078196429060f94c1a5457efeec1eccc0afd63bcd26c0c16178dcb15f040e26a50f8c5ba4077ca5f301e244075a54548e116276bcbc9e33cf8a07b7af3766a8d0fbe20f22bae2be302d51b30117fa6765dffaf36fa6064c5817dd83251b4a4c7a1a1eac87e67098a25b0a02149ad7a1adcdef75dd30d03ee41675d05268240af85db39a12dda308059dc2be253e4659aea19434ea8a068d6774d129b954225503c0952623186885a3fc360f965c8db89ca1632f64436654e7a4da2c7372013e0bd9044acb5305d8e76464dbe987be3513bfacbf47fb15d44bece6d312725c51930facb2642191e8c08f71fd6737a4439191ecdeaee3d8a3661974fecfb1fecbe486f003b24a6f4688d34e01914ac8e213a506e6f87d79a38da3ab1aab653a48d3ab0c7515d8066f9f9a11e80216e647772fa6b880a589cc0dd7abc49c4d897c486a33a2ba3b81ae6bd9874b005def390f7d580bacdb4476f48acad2d0eaeb4a5e69514478fff7fc0501f3877da52d383efc8c7da5c7a0e14aa73252ee8f29e168cc18d8f86aa508e194ee0293b1133d2883929f873a230e70de420baa642df22b19ede64d583959376f4dc146fe4059f515c9006921c78766c5d2382beaea59d193412bca0ee2089879cc142ac877ae7ed28fbf7701e0faf67d5e9d67576d9ab571838aa48594f5b578da3deed5b1f95b0da8128aead2666e2b9c1f1761fa468305783d2750858e7631a8f542bf68feb19beb6104af54d7a93b6c525bf8aba295f49632e4a2fae92fea20e223cd626cac3955cda8b08d915775ca3d68cc9f313bbbe5c00dbd4c5003d485d64bf8385d2cc417728f71b7dbeddd4e5f0df9dfc24f3b2857e007b658f5fdf475d3d256afff95896c536efaf3a1dd3b95ebc5f2550614ab8b430b0787cbb2eabc40b4beb6d72f1fe2f45d84c778816faca60470c5d3a6d74fed8ccb948ccbb2b3b0cfe944a25146857948e8df89182ad2039211a350b37ed7d5dfacbf322a02f485d49c25ae84e0998fa07051a61a6d135764b344e728003e94adc3efc7e640a1ee0e407ec660b59daf3d2d477cb8943a088a6869c4e8199427612fb74ed2da77756d92b5109bbc53b1c5dd2b331b190756153a132e10877bd057b4da911e39546788bdbb5e2eb4433e5e058bb868d86ac14624416939b6a045a5d50d8ebaea6a80331957f445e44757912276e5b708164fd2ac40dfed8cd0b8c320e05dd925f6de411bdd7cc9d907da53d0a840e3f2973cf100aea445ba1ded29c5fbca72a73d51a9ece11377964090f2fe71b896b6419e614a6799c7682bf3bb9d28a682a109b62f0bd22fb71ce1d5dc451b4c1ef3e337d48ea5298df35adc7195141f0f2d243c1f1abeef4867d45bb1daf70acfd711e817ad803caeff091168fbbb6bb10f9a7b2e8d23e1a8f9c90afaa84f4d32bb665540d35059c80a7036ed39602418939abfd1242b1dd34b5e2852967cb3bd2a305e7a8e40457f27e10924bf55182f443007375c28ad83654310332a04b62d5d6e6f63b9e69eb68085e9ee331ef6d64192242b028d38e4509186df47cfee266e47225b0ff6919f8685cd98cb09d5b1e9c49f6a2c86a3a9435817fb17081b74df0e58b4864cf866b6cfe04e70da5850a1abdfe0dfd2923380f69bb05a094095b68106bc276c83957e510054818ea9904b37282b00c8fadeaced5bb6776f00295591a36ef4956b2edd6f4da68c34b27ebe1a77877d55e10d64188091182d9fac8afc6be002631b22bbdac1d8900088e044c3f0323fa677e22d5ed6fab7c48218eea83b3d5e1aa16c6557426e4494d155da1cb2d3e3c4e71d3e9bbd894634dc3bf45e023b98edd88d06707831eaf1bbcf247cb40689e75e660c9ce9300609516d745f7f90ec6b16647b090a2a68255fcfa6e21a27ce36372895a520a46f38821dcb9cb4da7243f503e8343dce281d52dd338d2fcbb640e67da8d59ff7d622e1581403013ad14b8899abbbf8ef32798346c70af70e54e62deb529e8c99bd3d5d71a0e7fe1f2f81c3561404098aa3e98e5cd5be4e009b8fed101357836f59573eaddd00d8125c817de727f3e0405851e2bc986922900ccb070f52533fe6f02ccb367ebbf45a8a67cafb9df952f0267e58d0b8ba043e4481f68af7219e20e125f8d06984863d797f9f0fad9eac0c923eed6ab2f36d89ec4bbc4d6c2c8a0a87f426d16a34ecffb42f5eb30276d7aa3cba07e0c6600e494303c12b9ad6fda8d24375445252f8919e28883aad828b527064a95b9791a97f6bc20bbc56d8b0df03d58397811cdfdb0cf594462bcd867e856270953c1ae0cafb18bd72af2aa127afac855fff17b416198dfdab3741ce8c9117041d775bab55ba7015f02d106e9615b126c0c9f53dad14e1df6752da14508abbad3df07e2abeb3679ac21bf0b6637a05d988c8ff3a6bf786f81b6dd573c75531a24c60f3b0797a649771954506be27401b5dec2fbd0c5d22fa1b9e6f11a63f840468b6a58bcc406c15b4aa27467128d419aca23b2c37c67bce666d7071dac5ecb54faf395d32ea56dcba2308e411d4bcd52cce8479c424e9aba7bf59fad6e9ab5f21cfda72aac330ffa1a2b50c5d869910dddc3c0cbcc9a63963abf7dab17764f801e8d102755cfd87f06c880898d96cd040167f050429d4ffee36056af395e4dfa2cc6e87d88f9d374241839c27e0c73b840788993d16a619361a531773df76ed78c599dd176f2ca2e876e81616010cc4081619e6056cbf7539340887fbd182aaf57edd8efadd5025face91bfc29d89d8dbada9b534696c0181075108de9d317b8d8802ea0a4a87d687ffd9c217990d0a208891bf62b32e3c4a997095a528f04110c006d86723f0782a71e0bd5b81d6ffab521fd04a8bb796ac5f5e911ce3e0eec9c6b41610fd9277e2960b5665bf61618f9383b47ed0d791fe904b38bd4f4b48196abf3ce358589612425c8e5a6709664e60207a96a725d61195d206c0fb438c0a0009eedb63e5d1ed5d6b2b449a3498ea040392eb964236090d989a40098beb1f7774aa94fb65174cd26db1c8809c00c82f931bca2639087c8b2ab7061f5361355fe30e70641f59745231fbc63412139a448c1db54c2555d6723a96a292e9091abd0f6316650dd32c051bddc62e0d1b0eba581a91e048dc30b0c4522b12aed1a873d77638a024dd939e2fb8da14c1d882bb6cc9ba7eb9c0edf0c680b9a07d1e5de319af51b5d35578c781ac03cce154464d0da79ea68687fbfb1834549a1a972436d9f7788daebbda8f95dd37b7d44cd240dea5854d7346ef357ff3845f2ca6535f25ffac15dc1bfbb7569902be53cbbd8e151cb6f452bad51fc409c6465d5142514a0ca5ef838987c1d872b6755ed4b5f37c0de59b193f03d6e49e5774066c37465710c6074e0cbd5f18618f0ec935aad34698e91e1d9494d357cf1a68a8ad0af00814d8d8815c2d4c3f0675b7e79270838b743b852033076e6f1fd3380084c2fe2bdbc8d17342b3a1a59a16b03690ed8945acf04e21ed9f5b87782088c17952267928724afc6be7bc1ef0a6eb623a706f69ddf15409f8187dfdb2620f698a50370bdfc2ee0b6714fde18c33241d6d4ee9d5a1cc52d5d98be0d0e84dbc64d4d355c6d11f7de112a0bd4fe6b883eb695d064757b23344666f26745c151819f831b866485d1a6de416ac0b44e42229315243803cc66fe8d93a252028be6498a8c99bfd70ab16c7ee51ca6556c84be17b2bb142d8da8a8281b8ee32cc2bd61d3ded6bdaa2bcc68cab82edd278c79ecd63c543b48666875d811a1660574f9d7527c592fc64b1713ace08b7145331958a671784528b57596c2483f72a865b3a82eca248efe5c552da39a5a4152adf6c2c06c00f284aa300ff1a8eb9c3f47f29ff145ceae9e301a00a0efe2d7d87141d4c371b0a23f3969f980867159e9011ae0dcac9f1e8a518a872dbbb6ff57beac07cb8169c4ca7192ca2557dafbb8d3feb4d69566d233f5e775306bf94e3973fd9bdd5db2e0ef82654242301f65cd0d2388f68526b912c291795fdf7d6796ced7c749521241fb83639b11f2967a4c72e1a3c84208c01725921006541fece8ce649ae5a5b67f89a6652c065ef3a8407a27c3fa7ae5e919d493ff9d1e3b016b400143d489b4bad0e54ccbc5d4cb743963207159bd240692159cc36ee9335ea3de1d3d2d67e4ac86c77cedceed5d41cf1e3e9b9c05d662171d6f6a79970e2810823c3c9dfc45f87d9cd58a71924138d1cdb66a207752ab22ee5d716c6b4929217b3b093d187b68d343737e05f9d07fd535bf4b4884860f7dcd7211c35047bcc16b75f3e8ea2ff3c8483fca61ea6797ef311590a460490d32705149a5c6717fa16237fba6890d40865013160c7362c3292eec11257f1f354837270eea551abd1ab5686aadb5934985851a5e5ecea9d0fa613eb3962ca903389114f7314dc68836b9f9b50b0e256b81deeeb951472321b57549c508f7c5f7883ee126d7fe2886632ee4c9c5ec2cbde1b76ae6a2cdba55c1b7584969edd1e56df25f53846e5cba1c8e2e8f1055ba2e835c7344ffe546f67ae0704bd6e1598d32c9c2e9d398bffd077124b5b1fbbdcf676817b4e3a9129a671974c942e62b5e9031c4547d7e1e896be5ee2954d3b8eb891dcae0372443ff6596ea57305d9cab49bb9a4ad97c43b0702dcc1fcb0fa0d1687021aa6d2d2615f2cb5bacdf55b7ef15f2ad47825f2348dda863a5c347430038d0ba2ba09ca25a54933aacf1cc4e6a446f8fa44593ba82dd2427e03f0bc45da8ef7ed42d864a33271086eff55472180c0f5f95830e4d630c712c1cf036f9b532382559c2fd02cfa2fe90c84960208ac2672ae4fe499193b86c5b74fdec4089255944e17328984f6db12ed5e28e8510547724b4d77d1c6782d24e3351295712045a387e59dcc4f1a5c716930c3708250f5b4adc04c75eff7a8b3af0c1d272c685bed7c90742673505ccc63289858dd1245e27dac1209c92acda29707d853830a6e481d354c7329ca6ebca7ba6a71c3bf039855325260a4ae038e7cb8f26e5423770259a5d2ce53c6d68c2c1fefa704bda0bb417fb3e8aaf2da824af3ee52fc7f0ec1f643a3e2cb65adffb10ebd8330c3ae3e9a427525ff4a47b780aa7ab86e950fb5b75c21ae9989f179b74b9ab4957d340dae76218354775ebef6cb6ebf84edd36d9dc80730d7f0da5a69fcad9c651a106740c1c78f0c930067b7561b5d5614051d98393ac92f219032a7d47e033e6b8c5610088cf84fe89373a47f5152bd4aeebb37aa41f4cb176abd5be404d62cefbc5cca683347c644efe3d55983302fe9fff4f774d6a06fa443a28cfcf11654ccb0c193fcdf8b91200f288dff1f298dfd97fd4c0e53ec8b45a1db20982d3984246c6015d4c5d679146cc6058d5e3d7518d47a623275ae700a6d20d188d460f37e8c0ec389bbc73a1a9e21683f069119b1fd440e4167e9d772cc6f24343bcd9c9c25c290604c8d1248ffd679fd1188ba129727788fc2a4f062b1ead484bc87a43be3bd16d68dc95bb24db92591e7a762caf8b3acb7d2883b14cf55cbed3de1a2668e4a15fbe8a4fb2cc22d456162151696879a7e3a31554007fac41640dab9a3cc17e2965963e73ca736b6a262b5b393e60fdd815dca25e027f8a64e0caa04b076d050b489742200cca9c2b9fa8e73200572b548cb8790d444fbe870aba5abda9acc3f25ffcc05200bdcde9290ea002c28d774b132c79ecfdf87a5e7aaef19af2361e5c2c8d7bde759caa8c3ec39ee16219d0b7ad13274df295630bcf3a28e9300d288dc810887d0034366ccc09e0af0b9f81991c3381c0c02e04f66ed09934b83197161789051ef3f515fb5e28abba4c6dc4bf51354e525d4e941c87676bfe3ec114d75a83ed9b0cf6d6ca2adb328373e9c440ab2f2e1a6f65509dd518563ad590f09d776bd78a00df63f8496a9c384a9c118507a2e1ee6a2736ed704df0aa1d4319761bdcdc4941527c3d8595bcfcd2c31b71eee50b0b66ad9bd7eb29ec6e836efe2758d4520cf44080e582389461fc64324fc4918f1132c977fac9a5841bb7696f1a7a20f7a42b499857e426f7a02ec1f21a65599af19a1113da6a03cd9f4db8146adb6c0822128153498f2db2d62b4d44d94cf83f431b5d0afbab8e4b8107948f831595f895b1e96ae19777a6e5ec509b48c995ef1534031bcb915616cebb814c66fd64cdb334e131b1f9fdad992a6580d5bd3339f71fed3a727ae666948c758d9a14d1c16ecca034a164236f2cf4aece8ad707328ba97b0ac67bbe5a3fd856582393eaee5a624f92418442980558795a69b33db5619a157a9e7a200e2e9736a2680cafdd1249094a29c981602c98e5f001fc68519f41dd48ec91daa69e1043326c237f1900755bba8fadd8a3721efae9cc9718456ce55c81e7e5e243e55a29a4e98214b26dd401b4d719c1d3f1a9f2f50531587ab173b894e1d490cfc816a46619f9de51c911d1cd4cd8126c1269e7534c1f73254558f998851ae210085f8ab44b12eb3ea919ebcc8104e17103d48ca1bd574cb8c9d30dff9af8623c86cd9f457ca2d920307343308d351b2433a019697e408b796c99f93852f337784d8d320a3765b353ddbcbc999ad39b78bee50ef68f74d7d87aa41ddee76840b803795f59bd464a7b20bfb9ea8d6915be3880adc4d64250ca03400cf1a536e3a95671009001556ca01c2beef1595cf4dd59f3841f1e4358accda7540bdc8d8cf51b23b29810c34d36ccdb92d80a5b7a182e694f2d3e360c008f44ad204cb7135319c484c82a1df1131e4c9a7ffe287b7812a2e45df9d46aca9056a9ac3bb3ed91b87beaccf17caec269138a88d81c1200fc2959e8e130d8d2c953ef1083d5ba9c0841e106708c50d8f79a165e4dfcfd5c3d88d65347bd180256ceca595624188c9b3a9179c84bc76ba9caf4b7afcf7a63881c83e2516f8a7a8733169313fd0756a0f7cb1414755ab42e20206f13ade73a4c59506b1a4ead516dd8a23480dd7e18984ed00ecafa8c8f9cc70be7836cc0db13497472fdcd22ae1228f12910425a811aeab7512aec16947a2cdb776374cc3a394dc2576842e29f46dae0b679a6bcfcc83affbfc58777ada0bc8e964ff130ce815edc1b59faf05d4cd4f2f93fd8860b61f339d238beb330e78c78711d419ee03f4d1be97a862898157c429ad8e5267b7855e9e1202dc2fe88492e61be115cfea9ae2a05a05fa300429a883a50e83fb45f18e46ebec186da0f7b0a0c27c68a9c0f1ae506ddcd6261ddd5549ad810282bac77ded134fc875458cf1b8e4251daabc9ef1182dcfedbd10c0792d0a4bbddea65a81ec4213268a04bdd20998388a66b5c2e447f9374256efcffe7dbae08d35fe99850950e988df62480f7b6ce901a6595e3d01462042eaea49c24b0e41279c97b64d015cd29b029a96815f33a3920d9abacb5dd6e78086cac4d4ce93df30f71e47cd51fe4f86a38fdce86b7440f1aa1de1e20ce238e1d8228e62c7a460c01e9cc14ae58645bd45f18b88f3c9d9f06598e1ca3ca71f875c69473b4db0674f251f724034060a12c995a917404c3bef079e50911b788b110a92ec5d410b1981163b7c07f0d76804f30ce52fae9967d92a47e4c0a4bf90deac9a1ef3e35065bbf1ea382d9b53e2f9e225be74341bc2b4fb6cb5c017db2916e845da7b57ca1114ea7a1f02a01d722b370de9315b95628317d58213b6dc5e97bdd60e8713acdeae4bd804a989cd172229a91721f2a813eac646a9717da56bcdd98d911b7ce8ba4840ad82754d6cac7179427623c286f182f8c03ab640b6e3b58000d535f35a5f16e72f6eb852c86b5b1610b881c0d6b28cc0be6893e849d5e01b83515cb2f636744fab3d2f70762354b398847494687998838f8f103a3e90b53feaea3db4d4b8e8eb7088c80add78686b0243c6bed68b8e0b7ad6c546c91628fb19a33f4d65b52e53c6028cd29b6a30b7a85a0f625ba52258900f2aa8cb964a6d7a62a439dd8254f05e8444fb85104d27aed7466582998d5a385265cd0d5735ba71e6eb675121a762944119205e4615180e31c6b41b1c54eca0c702e551e5b911a4ef756306e48613ee6d1c1faaa48c0055001ba0318656255061b687867e193269414527f6be18e83a9d7472c650325f130ac5cec1b16bbf1cfe60ac45cc1f515b2a123451548d9e47323206b08336f9fd0d099f2a345255b3905784ca88221533bc62cf410e8cdda7a82b704c17b1ace768215cc8a9c1147d046bfc5033ac90900bee174ee8481d44b950f96349e8c8f621325e4931be7090031d0688077da2e9a789569aa695b464137be7296628c962729e220ec88b475d69d5e0fa53c962483fdeb095f11b017670779bb37043eab6fcd29b87a91804c5837a04222afae909ab42eba01ef4a7b8524439a1c5290cd7c854861b92bf456770ce54dadc72cc35ab94e8783b89fa25408331a403218c71109177ca38090bacdd0f7f26e00d2c2997537030def2cb0040c7dbe53333601a6bf20a308fd6d3d56c42c811bf1221151cbdb5e96f521b316eceef8cbe2313ec7d3cc0b40ecf63792206d8fd9712259f8913019fbd2d5d81c0aec2ec4b1361010d0066070f31f22329869b0c132bec062fc6441ffc2992be1d8f573275a8ec17e5e57c3ea254a191a913aed0ff8a1838f05eed39d3502abc557df69420e0af53aa2a7572dce65a8afa3b5c22f9b7cd1d0294bb730e55e466837ac9d5530f323f6bd7f87aee610cf5161980a98242086a30d8716a4e50f9f0cfa3e700de6732e823c8f9eb53a6832e413c5a24c4ebf0aeed132ead946e97a81b1d55cb4852725e2ab6be290e841973e2fd741eea69a14c8215e44982b7404dabf4e0ff14e3434d1fac77bcc6565b911a6cd2761f4ad84d69583e0d5d2c0b8785d0ec0b252303dc14a9167f76eb70189286f7615ce842c6e18d636b536d74680d513413ea7f2a0d9423ea5d9e18622f1c8fd42944100b7b7494a2bc1c0b4898f3667464b3131711b37002e5b61cdd7cc4349577b386f59eba69b3a595b2c265afdd5ece4b2ff17b91ec07335145bac19a168809344bf4de601967283b63b44630962711e600dd616c006c589799cbdd78ace77882dc17da118e83c306dcf567a27323cc456abb8faf2a1eb0b2fa3e11bf76dfabcbd2777993a65471190ec8ff5828d5ec0f0f0ecc09ead9df7af11d542cb0ec00c7841043e5e9908b21df01268eddad070ac5f5803484a75df141296bc7d99f9888505d07f44797ad5c0f40dd0730d866f81c40fd96f98045a6a7e2b1e2de57d844018f011ba9c6b8a62f2df6b52ced87d00f94e887b2f27f12785c49a6cf9e07c02f888fe35c4ba5142d60ff1e34edda24631fd47a2466640f8a984e5a3e886a6ae3f98000098af0d025ab0cb158da7eb071e14417e4706db0e3608b9dc6beb719da818b6e7e99d394093b4b4c25be144813081a032b00bf0e366689ca44106c5354cf2653c1b5310acf9041c5da54bc639cfa4ab24c686acb283c8bcca1d91895cf9121616c3ad567c9bc206c1bd5f3c94c706d8cc2336446b1362e95e7a10ca82d4861af4907ff419cbdfc3b99f9dfc38746c93386ccaa80d2a1269a0a1bdcb8d05323b155d6e2e90d4f66a556398f8d789394639a9789243e20202383231e5774c15ecf0da2e1e2cc36b5e2a250d9196ceebc15f2ce455a1409e815837d69f50ad19d2d733383fbd2778eb66740bdb6c8624934e197c06d00e2be0fb9e8bdf971f2d96f551947fe72e8bebdf43607c70b6b442e60b9e814514adbb8a09322f7335c7d06615b22534b191dedb88032eadf9afc3d79159dcbc62b6d270b63b7c9162c5fbd61b8227a2341c445c90282baa5a5e1fd146b014ce6b159e743b72b85c1cfb8427ea64eb650f092f3d08cb50f9100fe9ec08ff6255760e500c248eed4b2911d9b53a4e0d5119782b3c3d6330f86628079105a41068abf1488952374d94b1a701da15df0229a15c234c87c690dcdde41e6e8804a353eb9cbd6d684418b13c7571e0bffe8cd9b6719dd81c61031b3479ae085ad3fd45dda69027bb7285892affeda5f47fec5951dce3ddbad7d14d91229f673c7d2e4274ea04ff011c4c3d79282467c5098a38e57eabb967c89972e693bc68af2ab301d3a1c80a467990782a204d204791cd133423c43186b08d42697c702457a409ee9f07703c7c2193e600970e268899a6718bb6c7bad3803691f2521f7ccb55794783e9ad90ebded845e9f3e7a877fe1eb837f2fe5279f8bc5e973ba718e4a5f5a969dc2d3e32ffe3bc430f353c985b5b87296ccb752aa6cd8d6b388e82b3d056c90977b27c288d25068ed84f1678c00cd6fe5a69e02421b37a9a5a2e1790b75c4f58874572e222afc76be6a945fcbdc7f602c664a0954a8b85975300b4a8b6e0612e7fb66ee3216172af58fbf631d06f3fd45ee8c81da6e46763e45559787808669fe137319542a91ac824778e13edb4474385f0eb26be004793d0eb82a80dd815029104bbf3050e3f040812e2c05bf1b328da901e27ebf2939ea54d0c1cfe033317ac73101cdce28c8cef524ff9c49b80dc2470ceb3672c6d51778682a7a03d65e5a0420581ee16b883518d644de2130946dda7b15f7c38560fc6f0561d5b360a3fa6a44e0b771df1c53ea5b483e985ed4118a86c094176fdf6aee6e63deeb5b7a77d3806d3fa7eb5935d70235443a00cf7e81fb04c80557c28d017321237a93e2cec541f0c23c9c747767613c8ff36fbf4405c33143776f51c3504dd15aa405badc442d0812fcc00ad238e73fc20efc4868b4f5d41b1c407e5847225a007222a7ae28c82cd1a82871f10680858cfa931a97ee6a6a3b4ec3654bfa383c4eceff195a07c0491ba5ba08f1783b52bac3e7109ce30a1ec770178f9500c0df9a717c040cc09291357b8db6d7a091a0af305ce81d2dfe36582dbc713de0e30b2b9a21a49bb1d248812c6588f90a7fe2f50959a3a696b67288db67f7b69f087f87103030eb39701f2158396fdfa70f0c2bf8f636e484304b8214a0e13239c00205fab75e26032c90406f4d638f20e71dde7e82a76eae0dfec0028a0c8e42c071fb72200ca014310a8ec90beadb52704706802cf161ca242d57030e2e8dacd3be4c6d453912cb48e17cad64cacbba19b8c0d57b066a4173b7b3a0026f24b61136aff7ba8a0cc2d6d70ef5ee4ad3988bc2d3a3d9dc3c3599651e33500162a807cfabd1bf1696cdce6e2239b5f0b1bcb4fc53afbedd427610698501cef229ced01b55b463b31a3acf030794a4dc7f64581c71b484be239ddcb89116979c517cb3ae35a3b3ca26ead23b8453ccb85885588f65167ceaa442a145503805f0f41abe55f16a14ef0063bfb8abece5b473598746c59c204a59e0dc1e4b67cf2a03314125d9c2cf5623cb6152754c517a5a59e08cf0cdff111ba49e7262abe5d4ca893886489cf1162f27e965714379afe2cf7fe2a80de19240a5431f855876f5f2d892d9babadbbf8e983ff48758515f53fe4ea2f3182d7e2dc1e48a72a9e7b3c5286bfb9277528ef4ebacecc31e483ab0bb076ab480b9e94684ab12cdc75ef41f188d29e5c8e0da7f1e50da81dc9ffe979daf78690479e8366bbc03b0279a6e13885106c57059b1ee6380a0a24aed85174a37fe4133738a4deece1052c6aa9334eb35fba12104705453e6f2a0c6ae892e090f791dede96332740cf57dc0b80e3467a40580c0a4700cfdce4ddaf30066e6b55bf6bd545366e5805c88efede71806b1195ff3741d9a69b62717347e9940a6c8088603660b3e3dcbf6dcd8c42d94cd32718db4b6b606e7a834f6bd4fc82d09f995a4b3339932bfa808b830003b80e86f975221080ba1b44012d255a34f7dc255e282ee4229cfb90c40fd58fec1d0f79f386836f10926bffd740c96dee5b8d8e26b9f816acce78ebc1419c58b7b9600d1fd6d44595b2c8b5a08d94bbb2a706b5e14f14e5bf36fa15ad7e16265d6d9e9dd74d16255ef6240e93ba319965a532eb66fea8a491cb13cb72125dc84b61be5ba9bce7a149e124d2d9ac2444eda23c990d6ed79cb4217a85ca145dd9d2c68ac2f0732918c9bd33bf600310dd1cafec6c85e1207b200f3ee92822e26450c9606f49868f91ed4bf5188b23798be3bb225accf69091119bca15d66c4f096bd3ce6c35bf7701e7415dea1c189a3e67a64acfba8d52de7f936702fb940a9eb2002fcd5ffc61ca43299837d99833a64c7063473b0465d6ecb2424499f39603f199f98e2a4730380f3e3675f21954c2cdc828496fd83dcdd10b4e881da2bdc9f668701f6bb087d2a39160055e1d233896a5cb10799418120d3ed581e81e95da35c43572979ee66746c14fe677439d673549edc9e9ca39419c28ab59900b1e96706edad1c3ca1dc2f17640d5c7209ea6b1485c72426cfd79c0736c2d9084d5482527b16236c36892a7ae3b4124e5e8844144fb90af150e6f67a90e5364b9ff0a62acbd26c066efd96ca1eb29c2752641ec195f84ea579fe5c1a30c6086426f29376168529522949a4e60b66f58b8846f4bb06b3318d3fdb469adc3964f30d70cfcb99f1ad9735d9858aff521c08780d10cc7eddc119573b1e0c6a630e220146f64657ca7d6cfafc97f367677ac30658e324283c89f66402b842660d879d103ed9e8939473a9fa35538a7484c3d4132c541edbcda874f455de3c6958e36f3c62272b0736b0e4271fde6af42af898033b82bb894768f21fbabefa87cad46f15fb6717ccd49ca77a55161af8dde86c64c30e6d53d20645a2bc1dc04ad11ac8901e3a8a62649959e38514eb0f3d28e79c58f2465641eb82114cf4f790acca9c2c2bdf1d2555b1cf4bf4f0e4f555a6b452ed236d594515cc382a45a69232461b30d68a1a137a04817e65e4be2d2b98a87264956bcb73cb1d96a3288c5c1ca230940a081b6beecd78055d73264cec650729b56bc1acd42b2aedeed40b7c128780c64282747258ace79237cd4ba71e74b2a22f495acdea47e2edc68cdb04c5d3afb68708aa669ad5fe21f928e90223a8f8755d63c80908e7f6300075f967f6d291afe6a32b35e17b8b575aa96c9048f48749224ca51b39d466414fb7ed50a0586be5ccb2be105cf271e4c18010f6c6ae1b42319d56ffc675a266be6b90db378d6be2809eef58b2d2b6889a2966b640c4f8508a689a95c8ce614cbfb32f7aff5bf70770bdcc634899d594afb317355d1272c78788290954c043443ac79fb1ba36083f393aa9eadb29a48848a5024e825b21aad44eb7dbe08935de9f79931ffc8665d81b3bcc47c0f4c7c6a0d6d6136bbec1fc1616578762e13e9f3422dea64f52bea5af342a88ecf79211a251dbea518dfa5a82a52d438f0e8184bde2a82414e5371b01973ef009900a4b0aa23ee839453d35d80b75a396cb5ce05467e4c9035f7dd3122ddb8d4f0693e2ba95c37529883696ab1ecfe4b5a97820ed5cb4a1ede75275fda71be598e474c187d51865f44ae801678c930cd7d420a212bcc30bfeba4d073b08de08ad1fdea2fde3364ea4afa6f20e5c556bf374089333a234a5510e44addb5d8a2f64334ad04938579ba21187d2881f17fe6cd3fca4d1cfd98833dd775ead0b1ee2c3e074ef8dced7f685b922f73febee3518e3d268ca676c81a8a424c91f59eaf5714a33e649710890de838c8b902cc6a987e4af74ab2d3428d5240a3e8d34c3448036ac1968e37ccabc07be93d177cd2a72fcc78d1b9249b4f5bb3a06771e133f49ad0c551ec9b4c361c7a42c54e679efb3587b289af2690803eb53222bf7ce52ea21fd665d9a58f1d060b99b05180ae8aa35ab5b65d57713d2427140f1eede320b9c07516b8e51a9cb14cd2c7a63f22231842823cf75d4863bbcef769e79abf4a6e82ac892ac9ef74a0d8db33ae4375c22631f2220560ef3004ca44ab612544f602b1e452a501bcbd87be605e8d0d436f34af338706ab43f5bb8a807ce023735e660e93929a3bcd8b5292027754e686f369500a8d30897950822d9f6da548fb9f8edef9548178543866c4a8709a80f9f78a8700d5a36959ecb3183f57ccbe784e260fb9a389c6f4115d7146c72e6429fe4084a53005d0dfc9fa9f465ec547a1c2c864b0fbec7d418dc62334c219764c975f22f7557484eda4bdd805449868650b6f0bc20588a0e768fe08d24fcbc2486be9484929379ac4b2c1dd598836253234c14959720ea02628bb62ae7b52e421887f1310cd5e581792be168a96555b69242a5b5aecff48cb94e6e2430932a4f9ec2d839e8981f6219584b8b75079063af2483e09d572ebe277472b3dfe8baa4b8b4cc4c010e4ca0ea4447b0d70edb0981dde0cd56c569b65c86506feded7944704acffbd35b99511486b8fe57c09029b6696ad1e9a26dcb6db90e42cab43901a829c2a910de2305780a97f68843a0a2e39a5294d18c90d300906eedb4b013a5284e629645e19bf22cd6d4bbcd275e82637e1e13913ab728f7841df0c3a806da1a61c3e1a39368d18e3674b98b67c4c2e518b878ac43adf92081296af0aa63d87398d624d35484211addb5ea6a9fdee8c7c6ad5ae70efac1b2067fb7b318457680eebfe6dea92509f80d77673fd33eb6583b4ffa19dff8049938c9dc04ed31207bfa4eec2a7eed1175312889836987184e877f3c0d72f03d6bee0d6b92c45d0d23ccea5008c108b11671064ceacc506435061971cbeab7f042359d0f77e9f8505ba9b9d56890aee19f8a9c86116ae0684053157d1b644ffeccec8982ccbf6780ac5037f64cf69b9b6ae390e9d64290e8777bc252dd896f3e39286e3516456dc7ae577fc43816e0245ac61f221a6e48a6e486c5294df38b793aa899f4e80c33bdfde7300a0eba0a93aff8bca2ffb93ce4ed4d60998c6fcbec06224c2d4178f0d0320e59c6bac5d087c8ed80de545596d9b39a4a60d0d988601924710b49d1517cd065478a574c9b4233a0d2caca34b5c3d3a75671dbd83135b83d21888f59c3ca73488aa71b8e7a0cc8c3329a1f8b9218fd71224b4614fadedc5d8a46921940a2db8ece6e97b2b38a346c3a17d768ced5e0d98e0e9655787ad6d06542d2212bcd79f9c06bb2233f9877121cac9e3d8cf031a2330e3d7099ea0c527d6963d9dccb141ccf41ae20c24a35eb12f9f7bc61874d901210ccb8f015afd4c261dd44ce1861d58c4c52217f8dc503f220aaac391d2d6de57eef936607d56940e0245ffaeaa2ec1d20b29e9be979cbe8afb7473171e8288a0a4b73dd1af52433bd3e8625e6f102460de178eb0a57d6d0e2ad78ac486114a8054d3b247f6d00a01470aa2580c1f3fbadea24c6ec4ab02fd30b19bcae72c9bc91b18b038514b1a99c53633aa9d74bf7eeb41d68741aceab856f4185c284e64785e6c9e34199d6647d1f1394026d499a13de1cc0c6f84ba3b9465ac6dc48c0cd09865949e26c38967d8a9fddec3e6e4e9f888d4386d45eedb021f94b59cfd8d2bb276def39d9f00380108d1fca2d03b70991cc550a6de1cba88a622c37c13e43e1446307fe88be31fb345e933bd4b9980a8a294d478dc8cd805adcd17dd7f5cf5983004b6d6f5f3223c2a65adca2066a6db79cb320e428b6d6dc3ac059a199f7084a477d2c8516fbe7ac0807a273568666cde3a64c15de2d21b6ce86e72fb8181e460a2c660d490efeb8b89f7a8052ce62b13fa0ae0f744b1b1d55acfac1e754afc5e7607619ec4da991ff721a10a4b34d60dc672b59438d465acebbee85d28e1da18ae6464796e33dfaa6a5e2188be5ae301b55f6050e4d4ecf720052caaa3733518d0e3f67d34e4e73ebb9a3a2e194e75c8dbbc93569bb3dc4d330e44bd97b089cdff24dc1f7a281b89d975cefc225393f210d0fe477538c0c69c8a4a0a78460038191c0f43cfb8a89a8788868e664300569446005e726398a773c6d027724a375b53042722bd78cc8a1f5f004aaee78755865461e84a1056eb751c285e657261bf0d9cfa9a31266ea3ea6499162cbab60214009ac927291b18e5f90e4aa296112fc68fdfcff000a1a582957a24e06212e7fa9486db01aebde25c701d5f03c0805f23e406c102e2e6c1cb5aeb1c8389930ae06272b588d12dd165f3150d0ceec63465d7e92e691482cca274c04ff9b548fff5df3cc206d475cf38022e022bb27c75e79a45cc2c0d96db5a10f521955e8eaf78d2eb8bbee3e0d8504e04344c6a12e423fc47930ca5cb1a5637b0f6f634f568cd39f5e8a1acb4db1e89508ce5a90be0016b2cef327edaefffb81b085300ef8ca4d729af4d7aa37c7bc4ed1c1303f722e3123b62993bead3fa5d58cdba9f5f940c687393aa6e5f09ac490a10a35406e994ca8846629ce19dc9e1ff823791a63808728e28d406a3ddb616a251983ce0faf05a4166f3eb5e929994f7a852ef5520b70c45ce30ecb0ac55c8e783285f95e0d44804ca1b541c4d0f0b5ffe84ef9be16114b21a8f952858147ab29a6444b06e984329273a30b9ee5c72d2c55fa69298859a95b1916e16144534b68970b4657f2feceebe0e0817f9435d36340e15c56ac82a1ebe7da24f29d9fbce95fd0851110b4e2693afeeffc00488e485ce51c4f28d81287f6ddda51a92933d5bd20f2c3bbc5527b571e74a5c4eb1c7e6f6ccaac064c6031e0dff2d2228034607427f1253a4eeb1cb05667b91a8f21f835416016f46a060d0655df8538d8e9205e1fc88309ac94c37cbc4c3c5ba8b704c7fb4cb33b65d3033d0897243fbb414f72591c6db1efaf08c2293c1e61bbea802acbb4af346e2f5a531fb6ea40da1b03953d30613511c6e01e84d29533c55a1eb20fadda5f561238ad76618a1e9214d06ed17022eee1341e266efcc0d4390c239b7efb26b93dc976505e03a11945bb3c544ab3a0622014268172bfa4b25e867cc8417469753b1696e1224c1d9d97f7739dbfc1a306a0cb7b454ad6ffc3e8b3fe27d59cf52113055dce206ce48bd92f31be9242ae9e2c58326e8b94fb8b256f2f6d8174e5ae3ce5c64cbc718fe7c8e48ab1cc7ebc9b0c49e9c783348ee6833336238c208b66099ce02a05b42b298610c41d1419b122a4ea8c8f3f2f09829e8be6261164c73c102d25923f28202602add6030532a7fce7b46fc85e4eda585684a9f0bc3fe9d355557ba0364af5111f72828c3e1349b8445e18eb2ee333ea666c185f4cd4a18c319e8e2b2f041cd6f5ad598dee5048fdd4d26748324ca7e82939ca972bcaa5b09d941143ae4d4450590af81dd137a4b8345291084f4b840d5c2298a3fad5d289906957af71c57cf7c7fe85f1fc71c8d8e1f14a56761cea07f858fc2a60ccdf1806a91194cb65a338f2e71a6ccbeb12d1f324522c0d0bd78fcb71b83217a7580281425986b9a88aabcd303c3620827843d36e2ac280b85b6dc208435f95d3c494733329273ec55f372f7d7248c77fa348ebd8e31d09caa02386c9c03a923e6bd28541a82e678a58a90d28b6b3e39090405be2213aac2f9e79023f2657c7056d6c6af2d88b5bdb2477aa8e830400fff993f4951570b466029287448bc2d3bb5b74f072b19473915840dc44688175dc108ba101a61fd23884ead5e0a2073c30c961852901b2547fa7fe8969976d4808d490b0d8f401658d8a82636881d00b6df507f899acbbe021f0436f143bf87b4a382af959574145b61cc67ce97dfca304b89b81322cac33f9b23e71e95b6b3d22178c8e74e8480ef1a6f65a3c3c96e0bf8385ea0c1cf7d06b3f86157152819acfbceb4346a266324e7fb830576e0173475f45419f7db31fe924b9a4bfcd8b08e27d78c6ff2667a77bfe1f13b821ae3dc9497ed45c58998fbfd05cd073c10f1eb791fd5fa96442f09252c12be4abb76bdc1dec89fcda378b4cb0a4f91584e50d4d1c9bdf67e52f41420059091dac8695a6500da7a3241f0a3a6eb6aa5fccaa06a8518b658c1abefd01b5079c114feeed7d57a953d73f858e2c28581a1afd35ea6727f966d4e5825f8dbceb1c73fa0025407f271649af76b03f0c237c92ca417847d22acdce6d68afb14e981ed99eb5a38332c2db498535e68341986123e391a4f0bd682dabb590cee5010f3ed62419912e5dac42a468177b698066e218963080483462e2dc2ae086e843c0315d65994ad48e86c119e5b31dfaa001dfc4801fe92d34153c55689d79251a3c16ff0e23291be1804028691ace16038c207d97f75c13e7eabe3e3bb5abafeb2020701000decbb24bd70aec515d645a581695dbcc6c9dffc094b0bd4cdad8223653e9acba757daa8c8f977222863f32b5125522d47b35734f177cf3018a6f01572b91d29e4c164c1e3f499d9ab3dc960c04f02cfd24624b0adf854ea33731aa3ea605a7eeca4a6483b9076cf6e290ee1e04e5aa3caeaebeb2506c6a1c31f2f435b3f51ea15433fa6de02c1fd093b086edd1df02337e36367bc378e539f4d823ec39f85f71666b68ed592268e109781ddc16dbf8dedd74a400be2ee89fd20e6419349c1964d402d1d41106473eb9be211c191cf939a98024bb3a73197511b1039dfd6c3c452305cb4ce96dc1a920f072a207226e9ac2824e39168066c9ac7a47da3756692bd1fd177d2e4cac3a78fd17178492be5439a3d1a8ad42cea72036135e4c6eb3da40b53e920a008320ca3136144fb4e22c9b53cbf022db2f32c4bbc6c17b28b87020e44fd38e986c510822e962e6c7437d78351146b34152cd91942c49df692d643404e7107854b3dc027c8ced2e8543e55aa81ca10d68681a1018ba3084211a82024a72d033689ecf0b689d0ef6f4bed477c2b6bbe9d42669945603f085f08b4a9637153df1fcd6372092424578fadc2640b51e17478dcd99e7b0e5a12ab4d357621220ae7a00fc4c6320c5b0916218f1a269201c613973ef6bced57fe5c1d7c4da3f329b30b72803359bb5ad88fc973c960daaed590161cd60d1d970f809b9594c73691939120412267b6b3d0dedba58a50d542315d2faef9c5b087dca16d20eee7c3e47045e43d19da54867b045dd00bf55ec463c40b9c42816bf15ccc35548fc7776319eb5f8a611dc565aeac100fbbf287453e278c75652dcd415d9aa9ae7cc93949678451fe831bd1fa45a07ae225d5df3af97ecaee1d9e69b388134f0a4e1769387fffed685093042f5b0f147eaf6f740a3f027452e72295e011b23ed10e87daeadff897ef634714d9465829e27bb38ba10d3f4010612c3d1b62111d0371e006202556358479409a0baa5ba8f03f3a78a4f9fcea75b5de779b6f5652cfbef4bf3afb3c74aeadfcc0d3517df77b5402d9d9a2231e7b3092c72a857de758b0f5fc4b6486e4571ef490c6333a667e49b73e2f652b366f12f3152d8b941f08c03ac1201cb35ed5d2916db6809757e0b897fe6699e19ea38c0363e6afad79362eceed060b4c0653b67d59423c47acf082c484599fe43dbc083c2b444458edbcdb97c38d1603ed6231f999ea99643b7ef28f72a65da5c39aa48af9215a6706be73015c7363db20cea2239375198412ef006aab32e8306db3b751b603efbe127d8012c1f8291ff18a27e622861d4a23a418806576372c0243c40aedde62265261252b62f22218a4025e40b798ad038a140c32865683180491f9a37ff26ebc4215ce363244234e06b0468fb0383e52e0dc7cf019ec67dc33783bdde842938be501cf56360a0a3760cb624ff9cd1b508d57fb5a9e3c201d21a2e5bc456ef79130651eedc81e6fd4bd73282d8100aa4efc05c6e1b58a3689df1523728b8501a05f672832ca7c10850fb2a3608be88c373c52b047f3317127688b91aa35e933101fde9765a75237a62c72321d016a29e625c2640bf3a9ea2fe083dd8e7291c885d31a71b8709a5cf4ea7a83b420f763d0a027243e434c6cf04eaafcb69d468ec0681e1ef6d1db28e607ea11e1d77640dde499e5b974617f10cd3453883846558f84ac34c447183eca8d52add9ba4eceabfadafd5fcee11a29be5e7143de0c7c08af439c0411dc8d94c92a3247ec80401e17f88aa2b1f45d20247b978ca64a8cc32882baa268cc5f1d1ca2557b93085d3fb40adf4e9c525220e669ada0ad452be51d890704fe839ecc2401d7e6fb1c45d7f0cb8b52142e9440c672358391a0a48f10f2cbe557356151cc36303aebb1507c1b366e2cbc53aabb9678404316cae888632fd2dc0f689f39d04d502557aee93c188448f215be8ed831e765010fa09472e05427a475802b34b5ad124e278e498b33bd2d1298987957e4c8efb96dad8b08a786d1b9f5372e67bd905718470b7c574ab8864499caf1c27896e79cbcdbe9e6696c3f73d0cd646ee16e5ce84f6e9991b4abd973375ce3e40680e00a6da0b92ba675f41692e00a7d22bb9aee36d1cff910fae77e93319b4db578bd3b0cb7f35fd38e166f344bde16bea6986b46839677cf0913921b6d7d883b9f28a6a1b4ed608b277f6a3d1873f7ff55f56c719901e7109c7a0b10fb2f0649ea7d75e3fe5b760da55ebf9f6223b3a7830e6933e6c62b06d6dc6b5416636247fd11ce35473d7ce3ecc89314a23e0fc6591363a9f3d9e28fb9214c5f83c7b17b04a2159b1b0ed994b27ed2b216e8d0ab3544050bb2b47794165887d1d91aa90273de990db16ccbe6cc273a1afc17d3bd9e3927bba4f7e8aed6fa26af0da74254805d6414a2e89479be651a6a87b778bb384e43281f21786db04934277fa2bb418a051c3dfdb0c7a57c2db71f61739b01824c9a520fadcbcdbdc80c0958c61abfd51fa8702b99991a2d4c01e29e8ed062dc048fb5023f9d45785a5638bc824357bbe99b10ed907467fc19a32a3f828e816a27b7416c803a81d50aba541dbe43d55360a823c7dc881d5b6fcf8dd2d5fb1e05c0e0a3f785e9f797b710d9f7992738435b3849af3743257dda0fe1ab04d1f5ba97284363172b5716c0c696dbf427e563480fe6a3e47b191e405ba27b27786c995f84cceca6da2a45a718f6996b332d360e82975f45f8fd1ae9eb61e708b97528182068d407f922d7b0e4719e4a7c13f8feae003f5b88739e7e56f412079ed2e4ce5829debc5e71034a1d990c61c76185d2883b9f747b1510c285527f37dd0260664acddd8d5d62a8f80addcbe15e3a6fc743f2679dc7b1398c0bff781ac376460e969637d1c1d65f8de8780b39ee9d1e49e3ad8f45809fd4c950fe96502690caffc77c216e87792783ed548cf4db2f43470ba6cdc39095480f34e58e717735afe593ac3dd4dc56732c2259cef2e3deca8367f6c1698880da57246e2343073a9889158cb69ca884f0e9be8b1d6859024aeeb083f1cf546b4f306a10493800fdbf120793f3b7f776762f80ca6ca0df66c70d728b80e011257cbb1474d5eebfa9fee4ec70256600c7b0abc44e04e54fc03429e1443ac2723924f12bce7fad1af0f4bd87e79ce9fcdc71880dec9d1368c98947418142485d8a55fd134d767e11b3f4ce196da5fae01062aba030f375cbdbf58d379d09403ef2dad000898038d8aadf1afcaec1e66a1d0ce4b48ac4dd01ebedd5dc98df3138fea636c32f65f2648498c02dfbb86d3c37aa59e7c766923b92cc08652e9c65a0c247a835f27015a1a994c6fa24b93ff27bf0f687804fe86c635313601c4054dd11ea553e066506ee69d45b89d614b3322279284253445d54a3e4eaa07060533659d083f281b4a1098cb89147ebce23e42bd14391bf65584f88db6980b0a76acda84be3f81dd341035b29d74948cde3e4572761b2b92f02f903ec95bd0b91e2cbcfeff4d1de81221028899681507d65c143d8b04a3bcf744b10cb83c221188481d48f19f227bff24a197d50953f937fe1827688ca4bf86cad47a8a3ddaabf2917455e4d90883eee15bbed55bfe92644457882dc2618510c666f1ac0dccf9af6e6cdace35cb225a51099c2629818240b815888d58a8b33767426e4ae46d87432f85ddfbe7ce90d921a2d163a1d8d55b61bca7fb90bb420907a7f6880a3de7a8fc7922b1661a19bc4afa0f84640d9c630aaa46678d22bd1320f4bc9b461232838bce35ce12063e7ca592cd0751b32238cd337338ab8e1c16eb008b91f616ea5e53413e990248b5ed788b10dac3735e146fa0808ef99d8d4de8f921cd7c744db0d3f2e1a9be086fabfb3d002238da66f62af2f2b54e65cc4c8f6819cecead30c0cdc2ad3cb22b4da5d13485bb4ceab3d8ca47b612696e26d7c485348d495e201e703ca119546405fa8b8d9d12ad966d832a91de90b19159fdca4f93620a0fa9c7d4465460e7bfb4fc6bc945152fa222f6266da54f1bc8c4cdc364d5968935b7af6f00cb2ace96524ed48bdcfd1eb233f6435341ead834c6d40f75dd42d932c6bef869951a3ef29e263e38ad12e3d380fee230b469b1ba7de4d850abf4c83e08ccd35281614d862aef8b8d9f4fe9f48c1e9c64957d7be046dc7dfdc77a1b64acd87105aeebcb58abc1ce7dff1c3f8f2b1e4bccec024d6b1e5cf5e2ac23554062f410bdb15744f84aa51ed55d81e2e9cb824826bc94c17ea54cff0adb108b255986d65a5285e5e394db8e0a12337dfef971a4c64205dcf935552ee56e6efef210362dd92eb8ea81f208c454d7dda3b31da32cf2fe84746d2c50cd84c2be9390506aac295748a5f6c5af7262cad9f25fa89131c0dd7ba6d531eea2e9c949f8a11fae75588f150bdf2bc3d6c6ecfb8cf3631a88711f50936cbacc6e52826025e76851b1b19c8ea08e578e5e125ec4586a5613678cca48232433c5decd70a1249cfb24c93d25fd1c0951b1e283ccca375c2c8153156a93ea3b168e1e987a88a844e1d041850148b859eb1a6df8ace250701de4f1da70fc850058d00496c7fe1e6d4b9104b680f4e758a8553aab6547d64937e684ad2c7be329ada6d2be546969acb4ab2bede44a99fa524bd102c59519469448e0e3f761d4b9e86227e9961a16d50f8ba621bfa2c58eff1bbcb74d9d4588287f6ca53562307e6d7bf2d815864cc371b005ca518238281cf04920c082b655fe73477e78ffb77f518b57a0e6a5f8a4126a1014087b1d4a25e8816727f62330a6fe18cbd61e7371fc1b1e83f5d2df729666c047c25f22fe27b5c6c03dd69f9927e63c3fc5a05fd2f076a0b8a527f9aeff847e9869fee3a42ede2d59bd0c6815cb0a364a13e10ea628985f05d7f80272c165182c11baca59f3a5643e1a20116bfadf272cd3052231bff976963b43377eb81a81e294499469aa21698e083d8f83de80d00a49a042500c9fa3d646db17a396b79c4e87f4d0d475448b71f40e387e3ea5a5c8fabb34be537371fa08740c72377e438ab41a72e7c620939ad18311929e17be90e0ee02de165a38a7958609e86734847168af7c118afb9e80c5986b790208eb411f53ed9766c220fd82f70e752fe56a24829198980a56576568484b01319d8a0cc883e4991c05bee6c7d45510e2c96305f62a892a884c99d7316d9017b1ee377b6e0b99b162025dd9f60bd735e492b18a0133e38c4bd9d34834ead51a842bafb1c8b251d738a7da264c9579296626fa36cb50460d96eeb2daaa5aaf6b60f45681c381794ddbce13201cdd4eb6e095a79b7b971dab25702c347628d1d9a6f71497b9d4e4298a5826d6fc86c4755a37fb84e8d14c2d5a2900a0e8c66554b0913a695a1588826069907c307d5d2676bb31583c3bff3bee3dcaaa5f8ca7be22780b0123f2a673361ea5eb7877876907b916b9e04a5d85644b83bac29157e18a52c8947edd9e3fb3b3b21bd81958b4590229fc95509fa01e41a14770484833bd1cabd20f5dbb1659f80e495f52b0008391fd49123bf820dfeeaef805d33ec73da80cd8dab424506e9a6a02ac18e7998d8837e5314815ff8cc376262f3ff3c7e4022ebea5cef9e621bfa4b8786bd9a50c32c91248abf84c28a8a5253b133d4dd4669bf7e213ea303fb8a7ffa749ff3a276ee2acb4621d31ad2bfbac589f4921fdbadebb4f0db7d45cfd2d5d4b0f5235e9dabf0ee90ee33aba7316c9e84ef35731d9a46102af28f2de7e126e7e0b4a40c692125bd895aa5d691959eeab9d0b14147a46f1ef765d9d670deae3b77e8a8c79bf246f6dd7134041c010200fb885f06d8be747defc7b2e410ff162a7f43333811b20f700f741d2f5dc73f920d86fd55f8fe0ce43135ac72c24cdc8428a7faaef4dac016bc71923a60dcd9e7377ae3b98a6c4c13a01c7e3d78d8cd2344255c9504b4f4f0ed80b1d69e4a44c2b6b4a5db8a5e33c68091be64a374d39e9d830297422b16982a80c05008d961c64c87acc52f6f462688559ca99d85139f0017726f3d489dff12461cdf6e5df72c4b3606ab9f437993f4d67eb08f15bb0b7e5274302f969c018101d24ef5a23ea510a3c3919053c02cf82793a2bcd62bdb1b6549b6baa20750704ca7e36437b34e5b1ae6cd6850143b3028054016e2fd840f453ce3f476aa5eb5de393eae1e26db8f93d992a77408515895c975846c703268a7073c26df4dcb69d71705ae2d2d12e75716f39007b8f9e6bf175c01866d723d5b29d7a317e952a7a312eeddbea8009b275ea464d3097426601c0bb51e3c5245a005cff11317fa57bac37605151083698448f9053a1e4c004bdae74be3699b6c9e23e2dbaa07d248857028d1669c33c360e30769ea001eb2514a967c7c639615e5f1278ffd1e2fd8b616603700b1aec42dba1380449bb443cb8a65dab8aa56a427ab1c49920faffce2e42a88169da45b8623a68b2ff3acbd1a165a1a21a675dbfc1e6883978234a7b31fda13676f541fd6aa4018e470165b9d1f9ba2bd0800f34be4997ae4860e424572a5cdc1315ccc7945e3829bc5566bb800e55e06253b539f3fb3c583481655e67ad3d21f6eccc9a82c0fe4fd32da07dcb7d6417b7a5d54b1b7a61b9bc7aa7fb606cbf68786339156daa617b09f014b422d1c0361fb6066644906823ab55a02eab2083c88b5fae595083ff60726f17530387f8134ba48234410d2e3f6f18c6f1179785cb17b879d2e587b8cb869917520e42070235a3c6f14ba372819c73c1dd720a731cd5128a1c70272d222642d51b4b08896b583cb8a010df4d0070f5f49a50ea2fe58c8bd444122137acf165022a1d7bc3ddc177b0f228d0456aa7e33526f80cca2d9d5b22faba30d64a35fb8d62fab9a4aab969cda23108b7368b77f4f4c1d55302fde388df7d2f117381c18cb480350aca3a771120d1d3310d3b4566a543f1d8a8a4dcba6e14e36a03607be533dbaaab0f004ffe8f6afdcbe4447ba168411a3a4c09c32eea9135c94ae938e04daf16f024530e40ba31dceba6e4f526d030d9dd1b1269e971da5423e4578a409d9e9bf2b1404d42258b2bff7bc108a36651be8203cfc96d8d24fb2890342241070ea3eaef35d227e31e0e45c02245920bbe44664280f1c0cde0e9c4e102acb1141cdfc94959bb8422b85eccfaa9c7e01f89823b4eeeec86e124a6e178a998c88c29ba709e073d2c1789e50c71ba896bb25642f8b062154879faed85fa0f2b86451aad47fc181f13a03cd6e110e2001d2270409b88ad5b8dcb52a7e1ceb8b7745966860906ded58d2ad31cd8ab2972f07cfbf2d6f13d339d569e7b5d360265c07cc68fe96bbc0338026cf5fd65cc804512a23c42ef4913c640291f919d9794a6330c20416291fabf2c042474038a53067c592090424e0761798ea5f5fbfc282e260f109e7384dbbe8de94fbcb9e01d3b96acbcb08616296836dc817d2ae5b202805b2ab7aca3d1c990fd617aad1a5676fc11fdbb71f589d823df87f98428af618288ecbdb7dc7bcb94640aa107bf078507646833315d74f4dcd9c589fdc6f96a9c9ace90695acf5a8c133be5fb3ef1fb86ee47743fef13b7af73eba43bbf8fd4b8dfa72e4f68bd86a1805eb6641a941f40dae7f3e6ab60d43e5beefc1484b0e0716b717a3a53a3318959fa02c516d914e289f55a889d13fa6b9515f289fdc61815a138149ff22070b16dafed88aa7152ddefc1cfc27e4054a8754ca14c5d354f4d779eb94a6cb929b9f329195aad2319a699982e5fb46cc1a284640529094a0cca147aa404f6d4aad7277edff7894f77d2235ebbaea6633eddf7311b2c0b714b67ba137c4ee4bea770ff99b0fdb7fd67c2f625d8fefb90b01c860c2b77fb4f4c16566ec929d02e151382339772cfccdd923f9f0fcccbdcf88359f441d103cca26f0199c579fab7a6eaf69cc8837b174bc071ff7d2337ee9c5082efb7ffbe1bb7ef2994fbedcbed1b4aab684fe1fea33ce07c09beefd8f71355011c1c31859bb1fc702cedf584bce3c61fada217a0c184d2531a69003978d1a0591a33d9185f6663308da1c5bafad5f369ed231d18cfeb4571b460bbcbb5bdea7dadb5cec7d182e570b460b7cb4f3b88c196aea5d65a6ba5b5ba8cc6e8942f0cf4359b5a9ba634b4324b5bccaeb8f4882ab92e7327ae7bcffd9c35ac3b2c4e0cca58a32264f825cbc2235f1d1192b9139b34b5324d5bd0dcd9092bed93e45838218e78e9531c0af8a52bb91ed3e2aef05d280577a1de2b3896762c53a36a3af5eb08450295e849ebe699980e6480bdbf9876cd23d345b26cc25836612c9b30964d18cb268c6513260a4d1b936755f9cac957fccfdfafe699cc3406707e92abd32a96cd8eee5c815e1e66b907cc6aefc177857906b3fa594cba254f18cb61c688f17c7bc040f33210933e429a63c0ca1cd3bbd63e659f71d5b44f6dfa2277e6c05eaf9791efd922c60c6e19a661e2962931badcb286aacc41bd417fce401128cc9c0c0c216b15cfe7b1839d5f76edc857fcf367ffd1f5d77606e4d942dd62fdaefb0ebc1185ed1b51d87e66bf1d2cb13b7c802df677f396206c2030cbdf8f18e8e54bf4fdcb65968b711903dc881503c4d507e22dfdc5fef2fc358ff4caddfbcc99aeb58f9a766a9f8d7e7ff166ba3e6962aedf80c2bee61772a702de4ef51e09fbb7c8115efc6006cd9117265e90fe45eee21ac0a0cd133030410289cc6391856c0736529c9942fa1947b2e080c3122ba834213d0a3baf1156d6ae0902034dcf03e17a09420090b0fdea236e6ba77953c020355e9745be95e3b8d7657187fbbe7c2790adbbbbd9df79305b917e8b2b10b9ddddaad9a555b30326b6ecd70c92799786c25b98ae0e62aee67f1f0d1a0210c038262001376efc284d1b73ec1a4f1357d2e4cb96a5bffa08cae5e76ffe86b56bd25a8953520d698efc3e0b6d00855e5d03490d243590d4405203490d24dc35905860e6000bd0c682b316a08d6d9f1d0bc3b483cee5305bbcf0eceaa865776e642fda58feb2de19d4af326ee9e3a4a20535326ae4f8d121051831bc281677ce313d7bbd5e3390f3ebb4a18b71cf610bc04c7c8601f7e9889209c58beb4ffd8b24ae7ff1c5cc943066ae3883e5faff9c794213031a2968944033050d607c01038a3090c284c1a616e6fadcac308795e7063155aec061091a30291205ca92298ca0024bc20b0f861a6a70d3eeeedd218da18a153961fb125863a9553366cdca4da0c9d65287de08ac2227eef4f8dd23517d6f34aaa31157842c92f295d33187fc263be726c0c4cef724401190b0f345d042a9ab5a55ddbbbb6b4c1bd46773bfdfee8698cd9fa3d512a188166d1f6b7fe3e83683e6876c5bdd6ab55a5d5f1d76fa4ccabed456ab6505acdb053bbcf38b5c9f73ce392765029c5e73deee4e37ba71ddb7715dad2300c472b4de373357d07bb2c771d1ddddddddedb4bf64666eef927677f786a64ef7e9b48a7b15f72aeeee5e850baf307bdd98459faa2aed6ff61aa5621a8e871be71c779d023efc20cce96fccd125026e0720ac15b436952307a804d882dd2e872963839b1c58d4e53065a89081c9a1cc12540ca8c44796a52ec26072d4451730c8ba1803835217522cf1f143d3144f90c0bae802830f209cba4022098f24485dfcb084c71125eb8457e5cc0da0174b6bc8b204d4e2cceb0b33627840d8efb214669afeb214612c59e3cf35a5943e08a278d08e52bab953906e1bad3cb51280a73df02340075058fb668c616b25c10c1e1b67947172bb9fb65e5ed8c08a26236ebfdb16122f60a8247c9937e00201b77f96f0a4c35b8666d4e00656dcb6b408d0bf7ab57adff7a1c6ef8a42addb0fe99efbdefb315469e3a4db48f48daaa61ecf680d8620187e37daea3d87faeed97bee89bce746d47723f7f58774ffbd504bc67d7d22eeabaafb6ffcd4387f487dee8778dfeda0509f7ba2fadc98f2be1badafee4772dffdfbaae7f85d84ec3a6699cf24d7774eda5d9b1828e95a5e9800b3753a429d900907fc38cc9a381787814e185908dc39c12fbf5f9e7e1935471a34254cca0b0f7020c4ce0e1f10b88111211f3bccc0a209303748f292c48910c43873c5cc0518bac8d2c6ca4d103f5e929e2f4fe8801483180f6d3633386862860f352f2fb4a9f1e04089a531341d35d1e60b8e0c165627d5fac971822e9e6082d15e5bb45153c453115bca8881a4091cea95db32ef8809145415c36dd4c1d4354fde0e6554988e6946a86399babc10eaf4c7c6fae5304c5c6e1247c2504799ba6d27d31001a81e3737f45148ab8044b125cb5e08e563287cbe44a8312c0002d8a7730db90a58e01055c02760150be61116d385a5206790e68e1acb8654e0d9ec8c1764fbefc146519052f0ab62ab553520b5d088a5a5a2227785e15218860c940ae2c136ba07b3ba565ab4d43b4a5eba454b4b4b8fc305960bbd5a4521db0ef8f3823e76c071070472607f0081b1fcffedee4b45de14901967b27cb065edc196b4852bb6ac492c1e583bb4604baa832dab15233954b125c50189ca0dac17cb06d6149614560dac28ac188b06960b5833b0a0b09eb09c34b165851db1259581e5028b096b094b49cf19ac185830b092b08e5848aa12e05ca2566b5329da8f5aad4da5fe5558d8ed4155fd89eac2aaaab6714810857a14eaeddf8c466f250a2ea411911c34e48f89660d79f345481c716767be1d59c0198d78c4902f6ce4cd98250c5558d85a5b3feeba11996c148fa19d39a2d024cee33c6a04e2ab7612674cc10419eca66220d7c4d2ab5e71d0bcc2d307663d8e314613074d60e9421a1101c11043debc11910124414e2c1d423f917ec96044002ca411911ae4cdc81d021191448d59c29f336906cb3f68b4133030f389ea4613e67b3bfe53c876c3714749dcf17126e5681104c6921ed8e8b0c5194790fd2cb88b9dc2288181431535c8c00664efc025cb15a61e5e6c9a90fd29b8ab88114a74c94153104180f105d92fe45f7f63d9b2ceabd5f338aece593914b3583dad1c32b06f98a06941fbf1c35db47144e99b1f2990805da9b99a69669bd4083ad8926922e0a0145415daa7f3d9b81030103784e2d1a33dcf63cf63cfa3512c0dee29aaf36a45f1e07e8a346ea34ea8a81e3738a2d800dc13045084caf5d8fb29566615d96110b800ecfaf121195c058c8041c0aa12f0aa7fc8608cdb1f984d5891068868de972ce667e8e78767fe0028c3fe7017d368a227b6885a55a4811f601136189c28136e2ebb1a9b72778b3261e3b86efa9cde759cc83da9d416c581a8d13dd3ffd60ca2239d6501825acc5c9cd881089288e74218b27b66e2f27fc0ae8fe4af61438b81fe7221b478a07a34b33b77539db6e0135bb670b08b83b835837e7c17abfa37110707f1aa5bd306c7e0f6ff50f5d4f062b7478de58f8f256b72df7049d8b275bbc5ad560fb35a395a2d2320d5e2f68344c0501f829f576f4654ada1b5a9540553f0e13faa177e20e9cc76ec2dd875f3224c1a038970bf4e72cb3632dbcc32a9b11bb5b48ae78b57fd3d4ef659e7fc19e4a5fc86194d3edcc537ccb07d67469c6e9ddcb675dbd66d74ec99b449a3b43089255b7297c3ad9af51b2402163250df7757d8a11a2b32ab793a338a3964a09b1d3096b3b81ce80eb0171cc61ccb6673e7f59cb1d2ae133951eca1ef6317ea9bc85c90c86821a9b87385154c42b83093201923856b5106cc139d81193f64b1859bc854ac79e1455291004cc80134919b68c45fc8c8f28424e252786143b760948e76ae20a997430a175a482a72103ac078228924c26264e183139e2424119d17481f5f70aa011249c553999811e7a00c316224919b27245b5cd042b6b8c34412e939670073449b6262a957b7ad2291030e6a806209bad123c048aa5dd79961f3022b4c456ca127ee10551298aca19175ac3f451edc4c61561860439046de13e9292f5021b3b827328a4737c5b225564fdc21f258c82bfdad9bddeda7382b13bb8df5561f99e31ab504c835ca77be2548216346ba087e41821307982a602089e8c4d8740e6890c048eae20e91f324215d064994c848177992cc2340aeb151ef0727153f14a1d4c3840f5348f117b694d942676c099727928a3d4c90e0f6054910579020a7c3164090601736d1658c322458432070900312ace126ee106dcf8581a24d0f641319d5b001b98d9632f9f873279e701283a4620d1b9061800cd4648b6e44151eccc8481741304a28e28a16d245268d1c8c284d24111008923b042a1af591304a24111d55a43821e9bb68345f2411f642d2310b4d32831849c4c6196d9c70a37984162389b460a8f1d04dc860268d1612ec422a1a4d233d2c9144fc05923b8432ec38ce6390d17ce1a246ba084641b6386f67b9fc2a4a994826f92d55795007608014aa79d09059fe054863557e995956de7a2ef67c909bcd3c86aaaf788e4466f716e08d2b2966cd9299993d804177773759059cfcc4f4503c6f706e28e2841309a4aa161d55377870facf405365eba3784839915231ab497739d97da352a91888a5e8c06e745e6bc420adf94289cd9135646e40de78e36de38d372de60d2db4b073225d77df28a53c67aa55ee4a6c498f7a52dab4471a9cd2a6811e5158fb7067da6763a02e0c3aa34e502ed408fa027a0587a59292b94ed312c5fbeea71afaab9d92b0e0cb96d665bea58d5318575a38a8a268f1269ec4c8f52fbdf63efdaad510ed1797ca576e9de99e89350d4d43d3d034340d6d6b384a8041fa9dc5faa294527e6f71870aa15d0bb94de4eadccdb90e60feb3755ac5eec4ce77a578eac871ebc7b4c64a8f0fc6785903a54b16b3bbb4af39d25dd4dc8c99cde4458c09ce04ce6714f3ec2eee8579320ad563d616c910e2f6a31888ef9613b6cac7805ca30c615a28a52fd4ad257669ab6a69d8e5b196397dea492e7523973e739b4b297d700cc7dae42baf352f39a5d269342f39252f39252f394e2996da9c969cd2f57aa4555e8f5ae5f5c52c6fba2e81bf74e4acd46ec9292df9ca9f870eb6e4ac205d9f6353ce0a97c461699f109604e41a4a60f3358fa8716a3a13002883c69863c5969803158a454298c58251ab62485b5a35bbb466ce0499e8e8ecb862bf5609c0dd2be87920e879a0075a66a598f501b376f880c09c5c16245d0302a41602a985354a29aa870db3068485f60147f0a16b35aefd6840a8c9b2afb821ef4e5404b82f6a554fd40944234e0ce611101618c88130ab7f031c34b3b05842093f3f0c60c06a258a1f7cf05c9b5852502104352607022609c335c632b3e88be9b8efbdfa20c871e0c7c3408d0ac3f0c39b30bc41856118e6e876f868755e68341a8d46a359fb0cd43d29ad1b254e12147788c20e6e106386342282ba01973103197e111225ee10a11e7c70e7e7583342c5c231cbd7f5b48ae3c8b9d37dc94b4c0cb4dd39613ebb60d794f1aa9f4a938ac6030fa6cc0c1698b5022a7744a149702cf255c3962ec040b36e61cbf09c4d93c604435347bbed395583088c93f65d0763cb499bb49ff91dd78d3bfe7c7ff4ced5c0971fac8c7922460d65fc400a91d1c4115ce000cb4109d9ff53eb8f8f657795e36ac7711cd7a2d12c925a797e92b025cf5ab5ce98d9ddbdf270b5eb6aed3a2ebad661b45cfc5e3d5a9f3dafec75ccec71c7ef3133d7554a69e7792fd495d6e75aab3bfd6f7377779f1f6d55ad1ff0aa5fd52a276c7fd94b60d7b731bfeffba68e5e0dd574009b4aadd6a652ff31d58cd5dab106c02d5537b7546d333663136984264b9f07065da7734bd5093b0f9857c8e4c96227ac551ce6969e87844221274d1092a55fce5ad7c4da5bfe8c122b922288980d9454018319c8fe3e9ab5e974d989196c1cc771b1584b9195904ad114a5741c400cd600b20f52e28a1940294db18c3b1266ce282ca5c1719579e63010fdf91ebbbca7e1ae22586a4a4d4a44c101490ca48f162ec0bec0814d1a18d9fffdaa7e90a286ea0af38ca1218febb6addbba6debb6d4146ad5e49a7b922d9102afde3b38439409dedf5caf86e2449a312aecac27b4c13edd7310d0e1f658c28c4160c66250588002acea9f3108cca0a16943072e2600c50b0645c94c49adb5dd7d362453530b836f5021f8d9f10767ec7ff02bfa01dd297d9257e0557f9bdb2ffaddb46e7efcc8576d860520402a0361d6cc72d33dcf3d6f8e3dad1c3520b53d1ba60c28d051620fc7a1542e2eeaed13d8c5cc40f3cee00a4689a28b20fb701db04be5ab19b4a3aa76ba54093c8029c03ea68d0ee18e71401716fcc817d50e95aa8b534a878828a5fcc5c71461745c4fb6547155e9e8e8e8506edb386edb388e55aa2b685a4cefc7e956f7ce54ddb8d975f3729dbb44e0e23fccead7c1644ba6a530bd4f95f365dbeeb00fb76d9c3be79d7b37eb5ea8ebe78943b48759defc9c38191ce63077f1388c87593c37dc795b3928c5f18487098664e3f67b8c813cb82eaad07ee4b1d1a1b4aa9f870c3e5cbbe60d64df705df423ad0a22a2c1dff19d07b4927f8ffac6fee2ab98378ea48f5a0cf0456ba0557354a1bb2033cb0bdb56b030ab7f0ca0335685564da7266206d11fa68dee21a6dc20f3069934cb14fbf6160b866d9996560585b1ccb225f75ed2d24b5a96b46ce346a93b1d51dbe65abc09b3dcc95c4da5353dd4bc86eba39320a6cf3855f3bb090371bf7daa075be576ade1f6014a87c198d5b11925c640dc0b785e9938a05698676c1ba3e8c80ee3605c7750832339950f719099415cecf6fb7861000e4a41bdfe1b026e7f0d1b686c3fedd936ff90817a6e0fd290fa65fadddfcaf15c0bb3d96c369b0d0d79aba552fd7b5535399b3c27e3b0c1fa170db56a36c44002b8fd4523dcc0728f09deefee2ff2712af191e3c5426047ab829eb0ccb9739c3bc771def35d71efa6354d48d3dc2584d5d0580d4d080bdd3796d8ed96acc69bcc939985667a091921c9fa1c61772659eb7fa3d1f746f5bdb974bfef235f4da54b0b21cdf576e6b833418fc6e71819a13ecbce50fd093059c721436e3efc0a704e2e3063830d5f5e2f72c8f7ded11232994c162ec1401ec219bef26ed9340f4826eb778ed84d0c7ee28b3606b6bfb4ac63b207ff438dad07221c6542ad39240b51f8f587846398237ff9ea06cc762c76a669fdd46a6effc3a6a07141cd5ddd44a3d5a6d3eda3dbb49c238a208105123488a25633020932480f425c59f2c14b0e48c806610660c6489141152a4ec8fefee22eae5129d3448618a6a84113e48d2516a75fc0aecec9f9e003515cad9a3693caa689c04928d07ca5e6889d4eb55601d58ee611cfa30ed5a3d6dad3b4a671adb3651666683637706e3f419019c85d3fdf83a1bbbb833f7d85d9331b6220126e48f6ff0841fb50ee7fdc8502affaaf68e2d260876056f581a17f1f7e63d92ef2e8a13cbef0c1effbc0ef03bfaf86e1a6815b2347ab686d9f2fbce0f780620e1958f0cb9edb1a73b40afc30fcbe8e2b7bec1a02c752c876bf0f4718f653b5caabefe017e27081fd6e190e61bd2e53a20a35be27c7abb6d8926743b3a159ce9749e5e70744f5e81fffb93a98b013b631d00c22f2e9d8a94122311de00c80808b6a663070c42c28333661ad9ab0ea9ef2947f0f7a1ef8757b9ed7d3cad1aa2122662d157d5078182e944f31c8cdad016120d4bdfd42eede9a48fed5a7184408d8e1dfa12277598b1a8d86e0fccd87396f34248bb55f84cca9cd358ef3bcae110b1ff5436e1e67673e11eac36fd4ce1c51407df815408d76ac00cecd087a6117ee210a4d9a30c5b2afaaecbdd1c73956cff3e6f4bc89f2bcd9d3aa568e1f99d01015566580c152b086d50afb77584e0efd22dd491ef39b39fdebcf1278cf3d3879436d94720f7a281e1b0864587f21a7a209e6ec964494bcfb9288d2f58674f0463b44394fe373c6161421759ec6eb7c7f2be5ae9c17d9459b70f9134e548f39967376e77bdf816834648c1427c80e36d8068581eceddf600c04ee10d130d2791a5fc4831da29c00bc8ee834d19b7ca523ee1001c0693bf5751e001f007187c89bc69dfa0018e911cc573b7544a1490fde835167a4d4c9d6abfe5aad4da53caad4c496944669eea24a35e54f6b98114b95dcb5c17ad55fed58568b33963675339629d8a34625d45899d06ef80d63a05a3297db428e8230acc4481a2293a118648a3df806a9ffb9c87d8ec8247db0a1d85275990a1f2efdaf765f6e9b276e4d503caaffeac8fa586e305a37d806ab309cb6616661b85677d59afaff215454c44004b825d3849a74d90835d872d696449e1fac10d378b2d8d934cf30ab730a6d75729a1bc771b59a0bdb6c0be3e44ed3dd3727272777a29bfd2697a51d8e48236f6c225e0ca447801f48a36f645f790de32106acfc71271516d65145f55501fff9118181aa1437485f61d6ccf62dbf9394b48a0be3e44ecc6a1ebcf716ec5143a1241c3de98d8da5bd93a83fd1d7e84eadf22fdd696669636955275db1a53bb993b36fad1ea7f9eee44eeeb4cdc235dd7be3db5ef9105ef53f3d85f396bfdd9f417de4c4961356b474b9589e19217379fb6962e7ad0448c2f2ac85a3cb5d08b184864d9424c4a891750785eebd37cae26fd48ddd4e8a47356129a42458acc85d13964ae14e249bc6ce23466b9e82cc27ccb2d13f73ce983fd77f9c6edb06834d50cdd25251916d5a3b8f52ea793b922ca53eb5236231eeb97bb5f3baba3461decf3004bfeffb86888a90d29ce105ade8dd41b0fbf3c06dbe5e33a856b9fdb305ecf325b9fdf3884f0b7376c40ce2760d334cd7cfac72513ee783efde818ff7f3cb315d9c2f2a6cf913544203d855f43383803458c44b4ce6ceae084817b4c9829110359f073ee8bdf5cd8f0b99361a9552838455fd9f385de01878d5f33563f3c96c41cd5462566be0fb9297848020ab013f6c14aa51a8b0875943cc9a536706a1f07a85d3b60014424b12962948b056311466e14985da0f26a2251f50b0ac958379b4902d71fbc19b01d490c91828e752306618a8fb7eb036d5d45ae9664214f65f474058a8b5d552b5ba9fb98b061a3349c0d87024f685ca92624a7041a50d10b057d3acc91290a664dc9e35e942ce9ac8eeec89d2e5d913a43277cadc05a4572d5b19b1dc837565843966ae0bebacd5998c9e67926eb7131adc32bcb02aeecc8916d9cfad3ee5dcb2a57d3c1dacf46c09ac3b0ff03bbf87dfd9aad5da54ea5fa56a99b0dd89058a6deecb29eb21a45540982c17657869dae28ba7a71ec8be21228b921f5e5170e181ec9fb2fef9a50152ec4c063497cbb857ab57bd5abdea3dad1c32998c0696542a9512c2b2afb61d288cca00834dd884c160b67134b17ecbf0f6c5d1c4a26e19d68aa349c740e26da1b9ea6feaf781c296133642cc964ce3f1c19613c6b2199b0ff3d77247157af4b4c103ec9a4d7070603accd8f27518d14064d8771c4d6ce862c94de5cf2d12bbf37f8a2a70130f6138fee8557ffd91f3837d240b3021e5e584cd9519b8c0623f8ca68d7e344b53dca71f464c7b0a270df309aba6145ecda0099b367ae670fba79327d991a3d784bdb8aeeb601346613954f41260ac7138611a825675531a52d8149015fab7d8a24c993465eaa6acb841668d597dc30d549a8706a28bb8fdedeeb22ddc8c0bb3533b8959ded8494935c9dde76f210e27b66fd949aa275bd224249dd45718687ef7f7d1a071cb4ee2b0dc4ee2b230abb18060852d6912962becf27aac6312f749d8db53826c9c521937c8764b9a749b26c9c072427058681216e67a9e9b7d4a74d0205b827dfc553af3081469a09044a6171bace082ac3a82f89620907054496f842315e98d46dc98249208372689ac5f0e40680691d3d57135b81dc2e4397947abfab28dfe0630ab5f8859fd0b78c19240426aa6dadd3b6eda900975466c4a1b104a4a4aa1522bb5b60dbc41c6f62dc311b2d87222592161d34968897ff06abe0c694eb93f3e4a0c456fdd566a25064ac0ed6f2d958b75e28e00b3d40430b66c25a516c25b4b2bbde006195e6ab2828935505e4648f655d889a084f56f408f07349625537417c130605523c1ab6ea569a39f97dcfe1804c1aceea68520851fadf4f2c6525fb5b1d417eaff774a299192d2a684c3c434d6c2031e9052176d0c152c4c76a02d29c1e6071dc6ece085982bb8dd6f26910b4cdcb0a5071e8c88a20c0dd650f1e2c81a999aedf5c21829485c3c69418c6c276ac801cc1055929a701c3d41155e94805561a40555908da6cb161b9ec0d8b4b0a4eb8ac080092992cac8224d1637587286991bb84459c303965aebcda3be0a2294cc6e584a93040d19822d74c0e18922ce3ced40f6b7dc552449152dc8a2768495272d1cb0a60c1bb8f8a0a60c11647b9e7fefa8100443100443100c5120387b72fce8106ad1c0be89f264fdcbbe61860902c3962d9ed9a57de84f61a03a85c0a264a55753ca9d51d8464f2be097ad57afd8948102b6d1e60ced7b1a2593019aae1f0670108b6d30d08d8fc5f9fe1603e57c4f6145cf2014d8c6fc92a9987227528fbe4e4f42986bedb8fa79202acc099f53a8d44df6453dcb0cd108000000e314000018100a068301b1604424524445fc14800b6f923882603a1887a320c9511883084186284300008000012333534305001ece032de03d00b0ebcefd27e2ffda7762dd5408c5ecf73737be811a8c2606c43acfef9e87548d4b0011ef7288f3d92cbe5b751dd8015e81e0b85e3a900017237073203f815347a4d1205b911ccc121ada48f22f6ff6f45862f556e6880cbbb6e39a7c7b40186af891505140d065097429357ba36c499a32259fdbdf4404b63d021d646c591494f314ee021cab8514a49b221287f0c1d963ce4361401a79bb7b822d3884686a2764d0f6154f6adec847c18ec6697f44778428314b265268d990392198d57078a42dae8234a140bd814d1b0f21fa3c74422fa1de5c4c068ce5c9a05d1c061877e1d2d243bbd3d963ee829801c61eddf1fd29487790108d178cb7750a0e2219374c8f8237dc258aac5cff6d3c410346bf7b34c39578f0263ebe60914920b76f1b52f294d1680d0e3e90820ae0c1c06c15045cb1adfd17dce25e075b2ee662c155f5f0b70a9469a827285485d9b4f6a381b47d1e78d33ca09a992fe3a915629e2aef486725f3fe482ec36a2fe43997568519cf3d34b9e89da68de0ae00cc12ec9aa7b787cc94fb1d9a3be99d70400df305f9d0bc2cb0a971bddc89ef6bd3217c4b0811b2d6853c4e631a8ad4e54fd6adc82408bf5a929cb1684419a30ba6c8087b1f9b7f905c6465b5a7e72b65ea9908414f6984ad98170f3c0775e1dee7c66ef627938f5b9b4f3ef62468f0292052def6e506527c3ff1a5113212abad055c0d8cad916dd629f210be63e39f93c7fdf656a59d2643a88d07727bb76b2b4805b27d4d926d0e98f351cf401705b3426c41d61fcd925455f857115e076dd12e8aea07589d61971e9816b83743b4fef9175ccf1b54c8ad672ad05f8458023c4493900c470293228868c1238a3a462ef89dc98ffda5cb5e2c74696dcf4a4d3bfb71463e0c69e0f2be7ea73b8cde6a3d59eb54e5bfc7768f9e382f38810e1db3c17c8290fc065fce74f056374020aa2a391f53c5b26f66f46aef20f2c8c720a90442aa08f68a6b87f22c214502b55c12e02403c8f066a4fab87c0c393018d8ecb94108cc96638d75a8bef820e031f6b525155d5bcfa8840600b9e95755fe012f94c282219bb6d1461d0721e780e132e7883bb6aba9d7b253886d2fa4c011834072ce78a7c504a528f0c06b8bca54983c1ee0a53ada35bd8f7fa530c84a321080973a1ab461444610202f27c4fce700670841a08c38e4ea3023ee5d10b0c2233b9d75af571dc2c239673c6d2b0c02c0c993d13b661f035d078319fc67a53c95e88e5fceedc7aa0f800f93a3b8fc89953cb9170241e0c3baede9d3246140e6730903053ab5d3fbe6b7f106e4ab1c85d80c05470211d5940373ac96929f197f5388c6fdde67b9b5f4e60c37838fe7318e6becf8f0fd4f909da3bf7c078d3fcea69c09808cfba40c636cfb423f07035f6486359408f48871ec27c0498a65bdf1e697fb7168228cd86ad98e439ae7f6588ffb4c1eb18c59a2e4557c004c83c3c196badf846c24403d53703ab107013ffaf95f5b4958192613a5214930b35ad7c2dcd1bd90af8ee6ba1fe5dcdec224bd12c4dafe5541dd18647944c508378727e743e8de7bf407c692f66802882c479ce4014a57399db1a0b6c50cbaf11ea15d6be4b8f72154ef0abc11a71a77333e1c9e823f1fde69726f246b6cdd6da9ab0ae434ad61e608406b9aae50ad1c1a72c9579d4828a676dbd287f685126c8cc0882417a2dbc82002d7d74531a2a8a2ed60382713013e0d169c84e376c220fde0585d2182f83d146c1b41e8f5352250a62f80afe1d1a7e07c34485594ab65bc8d79e3b307d1e0d6b8795296f2234bd000ef47329ad7ba3f1004be92fa4c33859e54844b1a689cdcf7f0dc72b6c41ae2194e878cc2dc3bc64b8974c66bac1d93a798bc65ae4c503b8ad913fbc4c5865013773354ba907ae2c4258f1583551ad97c5dcd54ac2f882c057d4a195fccbe8633e4a14d358b46b49244ef313c163c3dffb5de71c8ac2e3b19a2de96a1a68e4ef12cc34304cdfde93a23e7b83b3629e10c73d5c6f64da5bb273904bc838d06ed80b792b57d73280ee359da2d445c1dafb98a65c6867885bf7513a48fb03a7568cd153f34a68f057dcade38a84e9b3995b2509e34cf471e296e0f9c925402c4808e046ca89db6cd53e81aad4e4d39b0a980e8404a58d7668bef63d405d847282a4c7c66901e391b886756b6d600f9a6a6952dda551fc89f6f781a9db8423313425c5422239aaad526c228ad819372e8600e363ae9c64c12c92824f16114a0d7d4609f36929c18a8a3713cbc3201e023913a0f5211dcf1149906376ded33dc772d5406ba59c1bd96851900ba4db8e5b773974abda232becb499f26e1a1670b8e0c74a7858f47cfa573730460a6668736d392898396d1d394423fa2199c94bc696625035868c5947fea7248182e59b22cdd3754798a07c06e5843d52f6ce4cce93b203b7559f90ed3ba393a4a172a67c0635a803e61af4acea78fde5cd2949946a94d298fa8c17e69502911bd551849d8094905c3700fa08afeccd29e122ae98463db11a881429de82502203c9fb3aac5b1103ad86bbc06832fd8006e97074d251d7fc656e3e3443f5d03963dae74c5ed5a0984838d9f3d30cb310f8eefc85c247af793ad1b872a6efc3a1305a7da409e10c9e3520bd4ece2d2d5ee4a950996385a0f51b646f0f3e4469f897aa6fa34717e9ae260993e6cba2a7028996d2fadaf2165e80d4a68914e2b3cc911545cc2bee11916cffe0bc2643a46848bd77334046083c4aab82206800b260d59127889236af36d8b4922b7c4a8434ae5599945addf5b6d482bc4fc3c9a0873f5f1d8bea4d35948f4c82b99a5b4a46d333e0c451222ca42e2c948be1755932c824c5b4f4b20eb1cc83b2b50d715c2342005c6e7d3b21688c3424eb864b14388e78218bb0f697e1d4380535405ea99fd459da1a5854d032ff5362974365a4f5a0e212fa4714858cc47020730317d1df7cd4f2095da6b35bff474cea7b77ccd42fb809b458f81675904d5721af79fe6225a88acc845426fa7f697ee88eaae396ef326ef9b892c1fcecc2218d1268ef2ccd8cbb7ddb52a606837761b15e78f7787294c9aa9adbed2b3f01f262456886f015d89fffb5cb83c2f81e251100bb425855843b2dd4ca7030096e92318e59dde4273dc3075169e8e028592876a8fc6383d9c60d279747fc959257eb4860e6c190705d733c899fb02f2b40e4d9b7098d862f66c1bb8ecb215267eee5af240112bfe78f024056b606e76f049d1286ccbe71ce5ce1ecd07aaa557c01c5a9eb34ba0b568f50ef4ee1d1fea95cb9cb1edda39204551b49e39128a420fe6573ffa6d394660b66f51372fc2043b44902ba443150c51cd696155de577101040d6799486d32bede4830f7d1ebbc65dab64c203e5a7a3a3928effd151995eb2e80fde3aec6d38a5aedf0b63b2fdb9c14731f76183e2f274540a132584dd32056fa1bb9e388ae05e302be48876fbb5009ad3f3e0977289a2b82d90e411666d4c1771e1079a4802dd9374fafabd83fa1095d132b1f6a8acba20dd7532440f2c324c5e6481fba82230a0bf02c4d6189a2e14f4c72f6971cd58c6464224ca0e0a1bd8733e46d2462be1b48c4f27f9491835f5617c6291ce403e8b98444ec2e54d6ce6a5b89435733651d61f64c234f10a1dd879c1a5e89c193c547a4b987e2ba0d542261d3bf646d560e9f9a97acb830b7b2b64b15f109d5477e26a48590c84e74288d086086df4c41b722464f929c6ec8f539fa3070e7d1b587d152ef826b7d81693d2c3f2eb424d0e5284e150bd25eda3904ca7602515de4fefc8f4092e4657dfb03e4e13fa0c3e6524b385d771e589d96314d119ac5d26988321c6462c0287f09344c67760a49fb56c1754ae97aedd8a7e09e3f3228ae6e3256440d46b8f744fa7c571a9678297200f05ff3e045f1a6fb139c6c0bfaa90647e61b824a8bf0db6d72627c11893e0c75c49814097fbd2934ebb85164ae23020ae1a96f097015725cfa4510fab7747f675ec9ef2ef91efa1104a3e8c7bd30e8abbdf7d832baf963b2a5c2cdbd8a8a55683f62099802de726dd8cfad8a67b39b10ed55d8f8f09ea2c54a0a1c9ace12639f688304cde6052d707f3073f2738e2fda7d84b361a26eeebf6c9d0085246d00c887aabf1f6287351442fe353f6d69dc632b8bef10938d9d12bef97bb0c062ebf55644f180816d517d57da41592dca6f5c7cea2804a4ca14c28a263fb82590616081d8c26515509c63b69007d06a4335578e848768a6520335ab14098020cf215f0950d0895b21622b922fc64ec1bec78eca2abc290455e17005208da83dbdf18eb0197cc525d301e08b8398004dd906e92260a67ab84cfd7c83dfac1438358a6dac136b79b02afe6049918d5be3f82ab4550b1f67f06c9395762da043c92a420c089b575330b7c2afd1cc531c68242c9a982fe9eba4798bbe906e837d73bf465da80c9c80d78b58f3eb36e3b7dbc902489abcd8d818f4c5a81c834ee872f92e0964a381de7f8c50cc998169827e2f34d0253ac82669299ab5f173c606895ed41e3dccf6e8bcdcc597c9870b9234f935aab73cf7b6c2b58dccda2bb9b7bb24030d8bc61719c6de7429634cfabe63b7e2d0c3477f6c99a91020724c8fd881c50fe2b85b6539f862ecffb45c635332f527c6047b74718cbc7cdfe2e229969f5338a38fdebaa78aac16e7e6c6b239a8f5502a817d434ff1f3f80514ed16494c395dd9c5653e92cbf3a347b14950c42dd1ce1ae9f71a68fbb7462b24c688bf1f3e8c3fa08cafec11bd4904b984c6111e0fabb87d54d9efd454222e998f97b06acc08cbb1ae3b10bf2a244ee7c1d87643be00c5ccf2296fc4ec741fcc4e1ad12a9140c0e218678854ac7729bf806c16065899174243a9c32a2baa80415179e3890f69c1a628538d0703c3c044fd4424b53a0346d5337c11788a75872a8ff8adeea50099a875f48ba631611a53ebac0938bfdf48dec61ead2889397b1d76ccf39b9984d8759af100c4f42c89e7d0477d3bfc75dcca69d9f6f9c0d04e2effb2e06dedf812092d3eb09e24421838455593198822de495685875c6fe75b225ba3376157808ff112fc55783e5ba2545364590472621b7b235b47d02b5a4487f127384d839a3510d0bb5c880a4a28bc680449a268aac43fa75f1937718f191ef939669df582012860fc0cce4e480138d97232250c242d79e2c7d992fa913dc91103ce2a97297da75d3e7cb20b866fca96f83532c8da2a2106fe611630f66846f52b6489491d02b2563aa4f0c1d0afa452fe3a946cb778006d20cadaa2b5f2ed79c2fe78f873d8bbe35ca9c971cb72362af6c604802ae196f5bc181280dd121f444255c0435cfc826758632d4d9b28e1d89cab0267f18b542ae4ce9b92ad7541bec5495e3b8f75505591a7caf7f0beaf54054aed6edfdda352be0799bf299355e1a3fe859e23957b45b7fbd5e5fab6baecdf8207fdb7b5986c48daa148fba859a6e6602eaecbb00c33025aef5e0fbc52dd9bf4f07d0d8c36dbf5322886df1794919bcb718206be0855270049e1924921d3c1b7177d164168e0f1c58d3d1923eb9b8c23ff83abc96bb6e5990a7c2ccc517797e18ea341b30a1032716e26fefc223407771d57d2f26b7cdf449d0fe6274c9eb86f2c25ea0b963932ee3b36098e7db29b16dc90139cf400ae6054de0117e7a70e38c49b160cf60d6a0dab8ed2ae1f0e95cfb436b5c8cd73f5a5890bcae90bd5eede19341c4f455fcf802ccfadee4c6da3ac27bf6ae2b9883b358e285b86508f00e7dad2ab2f8ffbe683ff1da6169148a876966e1dac4a022771260f50434b0b9ea5947a2e5ddfa2410dc6761963b6f612adf76fb82c1f5bfd74d2f8a9753dbc244b63eb68eece7f2bf63913bb69cbb078dd745e570d55a454897327408a56f9682def834764f4085683b7151b823afae5edf00b561fda5851c5611f558b6a05d8eca4b992f7acf044cedc821cda644bbbd09a3aef22b85e9965b5a816001af0ffbbacd772ccb640c8b6490a012ef89fae32813c17228d7b0626180885695a88217b23f54424c52ac964ce2ab26e17d0a6ec88f71f9bb76a3578c9af6c0ff9c39b3e98ba4a8337aa1228d726d9cd3f4a89645362c2296125a70498534f06a4a99cd0a35ce240d904583e02a762cc021bc4689e42a54ce8d67177957cc00c80d5d67f3ac8e25690f763d3fb646ffa388a6c55924908b3d939f5bd36a8b6426a168110f2b19440fcb4c77aa725d5395dff13d9db683d9a5a651f78412f5fc853209928b6247bcd7f70343dd47e4c5430a4d1ffa196269d0815dc5d295f7624f5611ac9051f2373d0f8ff9bb98ea1ce664f90202402986adc823a38f29fa9408d78880a4a2aef01f8ade2211d1464900c77beab032beff75f2fcab73b0ea6016988eefaaea29d52fb4f541caabed548672d5ec2862d7f78be468a26f121dc68e1b3beff0750c3b3a5443e8c470ba15ec23415bdfaed616a68a5ce6e6a42a54078db4c4acf084b69844635fe2e25807d35b29fc24dda59ed59fed1081fda80b30960158040a9c8247f8bc8a0b653e4eef4060968ae9e4e8aed81dd22a56287ab4a0d00482a0eb4deace78f560880de53b02447ceef219133b3029e21b068f49672c7a60c5c39562f743327dd0c2af6de12d353c247c727d286b0bb124ee9d36ea38bdfaa4166673d938fbbc883f71cebdf8d332b95b8443a174e6db340327b2af30f0f7e6510a34244024fe0222b67789a5b23b172969a770919a6168ad773bb44f241e2d20565f5d12a5dee2d0674f8115604f9604c3226b8d6c14d85361803ff58c6184fce4655abbfb9d45c4ecf6cd45d1f3c1426eaad6cf25833f07c9d9ac0c7a6be0179734b600295f0d45d805c15a2112a70902c5200576e0c561c83c295ecafe103b0348d9b063714b3b2bca06b5495216abfe7bc0fa088ff72249f91ce234bce34727d42c1c712eb24570384e8f8b52e5ff59769b03d934a2dd81a52c5ac6402ae0841a39d092399018809097efb0c1f6a025e12679098e0b2117365d2e6c55894db984ac24ef7370057fc79d505111e9e6fb7f4dc4d793b4c354a33dd3135882e82945bface0321366d15eaa9f1ee936fd77d6605636c56a98be92f97daa5d7c1622377aae61b3e359f1df80c7a51164ec06d68d32a29bb8a4b668bd4ab50d0334fab08642d389a5b2a2c71b46962e9c35c56758b5a993fa0a594b2d3a296d853562a6926b6b5141c3920ba6b981e8b034c239d76c3d2d115ead6f6851c9c2fc64b2f5435456b5dbfab9a563965260d6d7d3931bf82ec7ba14c081133bec7496611752030e3df770c40ce68b030741c6982fb119a01396e79487e601d837d818d6bf760a78ed11aeca429ec81a9a30393e7c3e435322d9f827d16296a8b1e6fa639c34a8bca19192acabc91ac88f717337e8fe4b29c32b6b6ca88cb08c22ebb0fc95bbe48a46a3e288b20c27281562d34d3045a7634b9d37ac1a7c98c215e6650c09dd4ae2fe75c60fe4a879f45d1f3d268d114bc2fcda146d1461f00d3688e47a1a8d46be84feab9d4c4dd8fc4d80c7b66742e2eff1a33c9749699e4c77f1492803aba92f99b39fcab382b95697d0598723f8f9d9431595a28e3704dcccfaade77293d1e13cba8c659e98893d8fef6d1981d92304499d8ae29c61d17398c829a2f699be09eae897c4553a6c3c7bdd4b49e5f5440356dc5d4f316f2b4bd0c1c2da21a44da19a32166a04af220f135e3c669cf6593179bfa54f3a0bb2eaf4d6e66b79f0ce6e82c1c0badc3625a86fc4cf25ee5b25b0ae87423cc6458b10e073ffc5e6e4548ae54257a2bdbf50ef6b7aa516816ec0e703f470b26617e31df0ee8977056fece84a73cccbb9e5d7a9076680a9ead682e0dca115bb79926246fbab6979d48065524fa542aaa53d90f994ce6575a4007a72513a568fb8ae895f89bf606895f7f0eb382bb7d9a0a384b9eed95df429e928db9f5df729540840d00eccffa1ae1b078a4f7d15f2740a5083b90eea5a68491894b45979a12236b49a12a01c23902847b146f5c4c702c4300ecfbb9dc2deadf7f01b4a1a5a1eec2b31ec773a5cd7289dd98dc90e5d7130b61a0273ee4af26421108e525b78fbd5e979811d891d0afbb5d5e0383a84d09d15e6ce88ab67ba3d8bc2c3c1628087edfe639726464a6584b812ea498902c372e8e0f55290e6aec30a17bf0a1dbb8e41712e884328e43cf23caff9409e632b63111d834231013b32cc4ea9ddbc6842d52c31ec7b1c6dd5189f9e8a297b41c0fc7a70f9acfdb7dd96e12d48bd20fd92c169f7057fb7956a2d3ad1401ee36aea282df6ea4f8991171bd1086aca4bc5d32352730bf2a9720025c33daa745d970d7a76b3fddf5634581b511d122ac3f7456db4d8b7320ed944403c49e2e801217034b20df80a0b46050472f7bc4155c0930ede421888e7f14c6c338cab0eb301d00fd0d42561266c70d2786876567956355649523c4143e8d871e522f3b3c949a674de38517a4f4aa97558425f01f916ae7d6e5fd335475fedb299e4a6e2703c6da34a17213f0ac0d983b249c26a3d1e652781d5a6a676544728611d0957c16ceca0a3a870718dffc502140813e930788fec7f20bcf2821681b673978f61a4e9dc4c3ad1d068e904dfa97e017b45c4345e4b9b86e79d62b31b8f1f4645c3852f6418757c05dae35fa5a9561142958211f13eb722d8b34f371697191fb9a98bff181027b4ba5f083cbe36fac6cf943546a21ab6646ab9e076c66f1bb7ec326c0ba88029838f37f21d41f7ffec0df94d7105c3ca375445af25ae46da7321bfd4bb75003f5c35140e789a1c07b3b3a54a55fa62185097517b85b9a86fd9856e810ab8ce81fbafc778ab715c189bc42e7b88cf47494b86325ea9224efa60b7115e32e6bcd5604f35c3d1e728cafa6542af10432d801afe113adbe0657b09d7ca36ab2aa71830e52daa813ae7c6f78c037edd32abdcda2bf3079f884b60ef4512859c4c5f0770aceac847e25c7890d5907053461af380541e0424297921692334d49307f31462cdb37290e0bb49209ff74066a48c65b0717e032dd714fc86c8db504613985e6cd356ce9d04181828f2e6914bd74cd4772a33b90a15a6aa5c0369a00eab2557ab5ba83aa6de19092c8912f61ff3ab0bb9311ecf151c1a31a4f255ce7a444ded57922225318eedb96193f0e81213da3717694ff3efdabeff57b8d35da9b972bcbb8de713770aee52a2163f689af80dc50267d5887db5299bdb42cf149c3a9214356e4b9e1da04bafc11c2a61d5ddac0803475ea3f82a9ffa2ce213619c54d9b32976314a72a59353436eacbbffc59377784ae3c01007db58c4332d5e70ab9fc26005f5d19bcd9b4714d28a7821b6e5c0320a3f14b5ecb5e9297325d89598aac1da0d67825f01738ec6e49147ebdfc8d480c0625cc21470d3af10224508b4a529353f1eace5982ac752a512e4106236d86d3110529b08f77b96d6c6ecd8faf6bbc61cea8020166efa2cc05110859212e63b28c3d30c4e92a72e129cac814da2813e1fe62046c19dc815a505b60ddd703208a93bac53587369bbbcd89b1d41575b80cc1f6b778c96d739bad4e49bd3586070a637d8f35dfe469d82a97cb03cb2d1d6c3e21d02a6d6892a215b8f07e88972ea1d87f0e40fa7672de87bb60552636c5026516a1472175e89c422f7aa20945c76e10c67f53d2efcc4d6772ed33c1b4da41c5125e4c39961cca3566c0fe311bd931e1ab8d342f2a66da83947d057eba62be476331d762048a257acb76f59edc167ee22904cf0af79e695aa9bafb963dad129e6e8960670e5427c60e8fa877e8d309eade59f6cef62a0a8d60dad1c85787070af4a1a1a9ce3200224cf4f4eb0e2fa82d80bfaae14329170ba3ef1736a84a7ef6886245de109b027fe79f642e071cad70b119c6a3bbe8ddbe031b06448bbfddfa50f8ed8db896356e1101bbd6d2e8532cca4e3d62807304359423a021608a43f84a04632d3177577eecfbd62aa1d220651a7bee72d4fff2d4be3576c8914643647009565fd6bf68c11557a69c6706270ca61cd06ab748471cda011f6f5d7c04cf4d6d8a7af2f025c14cf66210d3ae8e976c6cb8be9912066e41ad728c2b4a864b9612f1375338e14d88b05771eb791a6bc9538836d00810b8bd51c6d340647356e98cc91f50ebe0905fff4880cfd9e855643ceb201d0088034adbf904aa77b975c143525a816c837e31972ec9b4206f9c4d41a23263d48d05f2d08601009fb70ca1ec6507e7e82f408d124de84e1cfd11cd149024554dc5f85645c0d1b028518b33bbe97c8909bd4e8f53960186bc870d76031bb24b4953a3c48e87c1e0ecd824dd93a570ba84e7a26c9afdda9d77f86452863ca784d07a43a7f48a2f873b979bc7df4ecc660fb54fdf4c6b5c5cda83271d0f82bac6985de0164951cc0ba95d3d89e6fac3918a324842fa008cfb567ae61089772383dee9833e0dd26f7fb92c58c04e82d269eb85e7c4f33ecbcaecf7a074fb12b7184a7ae842c59abfc53250da516e805841e989c4d1e54c39aefe140c8b2f7e8793929469158ec464912d37c605294ae930ead965983a49892c21b4b5474b2fab4a3238c995f969b5905be5c35e38f7d992a29da3831fcc855591db8c29b8d41106233a5a3c1b9cb8d1c1de4a715309dd0c5a5af6d00d0fbfea3a47e68408258b88dc5ae74ca0cb850276be428200d97d604050735b0d255349ceb6bfa62d14711122a63a527485d7097c112730e5eeb575f6fba0547050e348e1f9c88a9029dd6dd500c8ac157f38dd96d6603ae70a03563c3eea9f42a44a178badd4786d3292685bf7853f1000adc7e57466b39b6911cef71a322a82c5c1a0f7faa4429ad1032352a9c6e28ecb5c0c2fb662cdb22931038cbce64c7fcae71c029312de44921ff56936f34eaacc62cd71d96e0eed60280b71efbd3ba6752e168c1c47a9d29b4787a283160afb99f27c8fce96079e341af86d40754a0b7630bb3e64bd44053b999e34dccde878412dc3d0221fb42f8285414237f04b3054dbdc41d108d756515c90034384bfa733d40e27b988119bd81c26444d463f2f9545a2514bc2b65076e0b105755166dc99fc70bf27b8c4ff3b8e91f5360369a38e313afad199cb8928c19d51afd8396ec41928150d6bc41fc0e707703a1bebe6c7ec50fe1e998a5a3de3dfd76ee1978a8ed61c11541b7e5150d9038292b44267ead504302d8bfd140d909236b13c7ed529306373c18a91546bab43ca25859fea9bf229e451406ded0045396ac5f5390b3d26f01a3f5738fe2ab3166c56e887e91312655f5b052924c7a4a3d0898b47c89841a06dc7254b2cec85c66cfe2fda70d4c251939035a37965452f952aebe7f35728845d171bb264a49d2fc56b0f248442ddcb51c69402847b159c685f06ac98fcbf6773cbcd21a3d828bb3f09b362ce3a40098b813b7295e82db6724e3987c3a68fa170b589d3c0bf79457c8ef9965149b82b0c002f68c3b5696ade345b3f0a455e9b6a858c2fcd1143e1a9b37d8d75d18911b38b07ba4cc668e4ed8a09c55511ac109473cc20eaa422c813c5357515d590b36011abd58cca51a341aec9d11e6983a9d5fa65bf77cb3219cb26394ca03e82f23611c97dddd885b3cb4e36b75207c6c68561836b0c3aae5255cb48e35cd05ee572adf9a5e80524674d993da043a99a0f04d311ac10cf64f527e79a1bb0908c4639428d7ec8020ab4e2acc5d251e493822489338687d0cec890ecac16c4ddb377ea90fbab75845f6ef61ceab0574f4baff4fc896624e04c829d0eea5ecc46be99135857a280dbce0be855741324e2f5e7ef317a2ba9c0b3b67b4cf6bec757fc2831ea56e2f5223281712aae630a295460c4ce902504e3de4cc7a7fbc9fb2b74fc0912b175a992951c0ec9a25854327735c5e4b64bb67523038488e80f4102d343294effbc0fa68c1ebcbe98075e231fa9ee55906005103d3543e6f5d1844e4f683a7a7ad834652337f61302099cdbe6450f0f5dbb890f08c7d97d769aa625b9ac5c578dd728055d7749ebf1121b5f18925c74f5671cb5b8ce1e21470b28312392f648c905d25586635b66b7e11fca005dd62c44c011b53de79d45dd512aae301b0dfcfccd944b0be878be8719b8f1e61150735082d114d5f36e821e8684de72826a87840a80822d11092d499b80d7504286778fa2203560dacefe70ead0a9ae9c7c60fbba5e42cb9c66dc826c27c311f949b38d65147de596fe3ded750d79aa08f8565916e59ed9f43e57db524b4d70820c6b93b505577790705086446246453cc2d4eaef72566312d6c64a66ed0a575eb0945f56cd8ae68180c28e4e612c9bebb8f689198e20cb2311109609b84d1215df983238e1a896278ecebb1e179cb71c86cb1e0503740cfeab19ec118c6832b32a4f03195ebbf25c5821440a79ce482b86dd2d141095a2016e8dcb00318ded72a8121adc3af017903e3caea84b42e797af256cde03bc3c44ee0851907ece825a593eeddce615a5d310ab910b95f2a6e5fdf4701578a0fc7c0d829103b60796bf4afc9ff9ea39d55f4c61990a14e869d418b6ee17a0a74690be30b4755d683ef0008c72e705af91119c489328f8a4a32f0c09872d890375117dadc01cda9869fb4b927f03884d9d37da1a61088b3af81f274bd7d9e0c2081e4805fc2363df252bfb3431c376efc8e068d031e761ab7d3dcad5b6221dfcde4d9054556bd61646ac3cdc40c4e624ca8756c3c05e081ea289e7d89d086ac7826cd257e1875c6d4476ce1f1cf2f15c9422ebfb1fd9190bccf2de3089a1e6e6429982951ce9c74862d77cc016371336b48f8ef250d2dea2de4a4457a40f6aac6194a3a0729e07ba5a7b7222f00365eb458e113853b670502138bcd0c07a2ac7e12fa21eb893496f434eca6e992d7678ea4a7dac6a879ea97d461a0952479b14247b67005aea26be985f9a2db1b11cdeca9a0f10379a755c1ba694ae904fb4ca242d6a9b8a36a8e495e6bf0feb8320129facaa10eaec5b298741c0a8f0b7a25d62b2bd1e93d51950be2fe1789f8e4c9fb92630205c3b8e2367d16e231b7341aa02de51ae4deba2b6cb1184ae29ed4525b3bd1c3be69ee90a42cdb369d8650f3a5811509c22e9c15336f06963ede74a7744085c6fbc4aad1091ef6247ed30b81159648e00c96e5a7c7a77685f02a9010e410adaaff42ab677b384f31d78001ee8700a584e1621c9f03d26809408a1f9bc18d7a8c7861b7e3d82f2804eb64a9935bf6c0f24c64672e10824687b6b6aa9120f7c41088537ca9d9cd7c9dcf69b06c48a04fa689e9963161e4c16aeda5fce2be4e7ed65be8256af3bddea9e138786246db93f2eaad9a00704e935c5ca152e995093535723a14008267e3579700b7438f31307a30cde645a1e000afd1348d8d4721e3889cc613fd205d6784a8fc4c877513bc130c39c708a78711c0cb5adbc83403477556ed1aaa43d0577bce5b4cd44db6e260e3d6006316a4553bf8c3f963ed0daa753ef160326d3374c2ad3887c45492e995ec6bc5e8d06986f21ffb016d6b7db41ca968da95566498683bcccd6c1edfc15bbe97028f6108e9bbb347cf6b1bb645a6efc27dbd74149f7266fc82da26e771851aee7de4f5c7a561b32376319d90ec4a6451b9f8aa2b811a974556ae52d89941c029fa508dc1b4c0b90956579583430f4d8a5521132fa268f07938ec12338b03a6b9cb4d78531cd61c414a2342c6853b2158109126a00b42e00a7998160b6f6633ce0532a87390c41cb870ef0b7e17f9327290d04bc26512326bcb84cb082e1cd001e3f65e6d62f04768aef185b152dd0b1d401ac4ee899c7a96da2c0dacd94d7ea75b00a0a97445021929ba1667435c718a097390ba98186add3fee229d1ccd95d1c9946a1739d0d7b8a84bb036410e353fa2f475f81460b4c4c005b052c2e16aee90cba83df3680cf78baa82a1b3a79e5a74b5bd1c918c4b02f50f04628b820de59793b37cdb0dde0d9c3a48e8cca7dd4a66bfc2b660b65faade0f63263e7c015f2169652695fcd45c096bb8a6b07fe4727a71aac0b8ede5c104a53b65f2fc019e66f724ef8eedb4ef37917c136de259e9dd3c2c735586d97e1ede09452ae467d5d8e79f7aebf60e110e80b54e7549fae59ec86e83a2e2c1baaf9a62245adfcbe9daae0a15fb3977b7fc0664789905581b7b8b1d3bcf95c8581ad72adb09d2bc386850b2918803bf3ab4ad34793e2eca0026224dd30b39aeba26f2c40e33e03f315b06904cb3ab100cc6fa7b2f8177d04cf4150049316dc6f9019f44e73ba638422f06527d16bd1743558101c289f0d9cb04a3a46c02c54676d2af2f4fe1d55369b7f866b6c93ddc40b166ddba3a5a229d6168da03601079b89754a94bcdb328c30927a8687559eecb4d9120024f6da2dbafae9e96cb698848c1ec63fb674e9b4393310a6d7fddefa04b84bc8824a4b4041d6bf450a32ad2709720ec61a9164614f4476309e6d228c35f2e5c486fa1c03fd6264e362f5f2e6b79c8c356ba422d2b4b3395efb1c733d2fd5196966b66c5a667e65b100da990bc9656de1e45f1ebca0550e1862c2ca9001aebfab6033503930cfc4114db9dc48aeb6c73c074f3f5cbba4633d29cf91b1e031202bddb1a8a17a864a092487707ad9cfece63e1159c323debd326c951e7f978b9a6691a832a1a3f886a77e9d97f28b2e78618067b8e826d8c1d46576ab025cf344ef19b3b0c3347f242686cbfe04bfc18640c774aa8bea3facd9731b350e775b2db57dd317f67e49b8884bdbce910cbf6f05fb707ffd7031112e59c7571428c2653a78276ece8622a69a02e3a59f503c1722a0a5b4a57fdd0769f2edd4ac2c10532832d08e03020001df9a6e80d861f1959464e1705704964aad81d7ec8631ece7fdac0fc246f0b6272c34832a301eab4fb48f166f3a305639549cd13ad33edbc9a072eed934da4f4e541e9e0e518f9126ac3cb8ab3b543646332e590f7a50a0fdadf366ec9291cdd22fea5cb9f66d3bcf7624a174a0215f8316f128d0cf18bdabdbbefe5eb3ec005d2e36b75ad508d74b7d6b201bcdeebd632c584d54c169cd59bd008ccf8b0fff2866fdd65a0064462b0366cd04cea92ab02a44c7d66d20577ed67df351f0ec40ea413349e21395f007dc7afc6fe1d2d03ca5c8735c96cbadc1a476678ce7cbf6e24ba01e8e74d79f01ce552bf8fb34a60937107d2531da168233931330c36e82148644b18cd1adbea2c80e48932c46fa7caa0511a04720137d61e6269b31d142f32561f3a26b73ad70eefcb5f2af5805b6e0601a6ace5c73db85b491a6b9b0d606f983a1bb98d64db591700e9254185d003fde6a33d63a3f939663a8fa5f4d7d6f9843a9a1e3a61346b3bc6a9e74cb784bda3c1b7aa8d6b9aabbdb9c9efa47e36c5daa2c51ee34a3e0c99ef00de451c9e8c4b877ea0f4c3d75fb76ace321dba3c3852c2b29e8aa7fbfb5a135082b3c6dcd845f4b69558450bd76f0ceef0ffede393ac935e41d3997f701651638fc3e16cf9a8a8f9b0f093339432e333912781ef4e70b900a419744fedd55d4dd50462ac254f996124f2fa76449f5a518dc885226d182fff9257fe657c35e4c73b36063a38350420dc9230fefcd949b2f978036a51af2ca7fcab474f4dd317142737e1c99b1699219a8aa51633dc56754da3554790b37996281a97f8304926beeed68ff823b3fd2eb0b920f292819839e6b1a16c0576735f8421ce3a81a3e77e51ba8d2296bfaec19d2c55ec1698a6dc3b835272879f69500f0810f66cbea68ae050853ff31b5770327b1cf74ad3c18f61b9750e8eb92a1593b2eff904d7c5ffa7b50698e878434543711967620f41296a5d0940085c237b30b58107d36a774043933295cef2a925d8194240b41b0d09c033c21d932c5303c5f0ba9a7c78ee4b2d030eff6135fd0c11fff5d868578597080eed4f4c14699b04198b1cb4fc70437a00117e0c0ec256337d44f67716db83a09b0c19f40978a5368a10fb8ee2a940874dfc7874c03152f94752f69f1155bbc36a3608a979de7f9780fb4efbb19c5d2ca1f56c78db3f3341aef66745847e10511279aa04c5565487e0d2f6cbc099fc71e2decac28cf88b5cce350258b0de8cc6de9b7b2d3d63079a4683de3540d415323405c88a88762e55463aca66e71855cd5ed81085af72b4501d7c5447f0ddd6f45ee78fd5b7055dc319aed23f77242402d3db6463d12d0756e919cf0cea388cd0c1489b5c5ad871ad4818ef66d9d062d56e2095d5092a019a18f901d75d62cdefa0be2bc90ef3ab7ac91c12c5fa6253616f698731abf6235de0b39af11736dd6335cdc1cf3e90bd91184045000c7efd09882931392ae00dba52d6e76275c8e894fad5f6d221d678fc0f38c81cab12345869188d304970b1c6b0389d73933a2b8209290dcffc6e0cf22f202590feac1d9e0e55de06a4c3b353960692a363711f1b60ac0fbf8f33772471bbf4dc315caf11b0ff55742e841428116fa3473783ef277be2cf08f9b0c0b980326fe1e0fc89ee9bd424c0f2b116533235b26529ce7d637ee6a665c7409a3e28f6637b994070f7deffd0b9de5ebb7bae1a085db27890a3900a0bdf77325ef23d00a44667868261f8bac1a4e11713133a14be68a0133685947c534bf8c549237f231fc1cc7caf59b9df846001e1bd580c7c8fc9bbd1fe129140222f5df78e0a8d44b02b26d0b26930f53b2dfa52cf25b62155c5c62cbb20e9c0486d6897f4059cf269a5a4b68b388dc2eeb44b84f2fde22247262ad753e58adfe0d436010def861e06d752ce8e5b7b08f0573a9900e1806c30e6f8bdb9ba12b8866a7d05a4a9bfbc332069f9d771f246d14bd53088eb5ffdfccb08e6390cf981d2d10347f42039d7b74871e80ab3e37048b6d72ed9559e44e4c99daf83d6b69c2685a3b681f049a05ae7a23c3700829708a82e01aa27f537d30626555874922bc6fc4e5fecf4149d766c14bdacee8a607b89b4e1c256c61a538bce9602966eaec534fc082584a06f48956ffed8910a3ffce655a068c4082e3401a392c02c01b5e7f87aa4b9e03ae75be1c4d4023298548e4ccd702c49d73d6aca6d323cb4052d3e7c2fdfef93d70b9481a809b484752b28a1f50872618f2bd658b063a11cfd512a8224cfe365333593ba87f9af5c35edded1f249dd8d02c2dc27ec2baae8f60b0f85c54f9a9cce00acc80e889e71a92ecc8a6b7db15cd8c30adc6140d7be0c2f80a0c4a49161934d9a73ab337b1374e853f32f2d70f2a08c8e2634628ce8670a84e8539306711104bcf44bb84fa0a338d44d81f2aa12c44c84083a028286809e32c927495321ad2bc083935fcde9cefe3af06909807f9ea0be92c98c360f1ad3b0116f6b98342eae67fa1896e8c35b5956de082323bf5e50e7378aee2aa201c33ca0b6a9cd076c75ca80725d2c25bd8207034339ed8843f68dd161c42cdcc11ac79d677afc091868d9aecdda1b5c658f453b8b2d9a5f34eb0a569d37dbcf8d92bcf81d64bb76c22ca2d9d4d0de4b7246e0a9cce03de9d42e04f29226c0536d2e77bf5a66b31746bc3666cb301cb61145fb3c798c53af8e5be3e68995078a068d04568d07641d46da9880ad6f0c55afed2d5e206041bd5e82a7be9d3a58c5c30ffd884fee9e2e2352a9ea3158619e5c6a8782c759738758016db1ca051538a5e9387720e6a26196c83a11e6beea1798a77a94b9fd144cff60dc1d69ac2e269f62891d91b03079bf1540a90b3c9aa78dbcc8a327855470522480d284f0f03a5a1c6181dc0c033e277520495e0107dd0d72f24d0f297631e3865012fc35d080e5f114881e034e84c1c283ce8ef4dd76cc2cc1fe77f7ba1895f9f11288c821fde217ec6e819a27333a5054014d9eaf92886bf28dbd258123e0aee8fe90b616905d85f622de36c633ce7432129f3977c0ff4b28f5f459a1ba1d017595e2c4d06a52c9aa4c0ccd219ac99bb6cc7b1e105ba2430913adc00b4da3353c875bab42cfc8c19dc90c57a1249e48ee75ca109dd6b47265b889abc779680ff716843768266813a002a90e06f08a758f5df36ee828e85115c33e9484d85fefe2e9e953bd1e68db05b92fa79880f21e731d561e72513245bf1407d80a4b977baf35269046bc1f4002744e3f157da567d067e03da273368040e111e7e06b2462f9b0ab3ef818b3e53c595083a14ab1e3cfa6a715cbd8afcd9f06277ceed81d214d6723db23f96a256a68d68fd85d6b4b696c59dfede58fe0b74a3deb7e28c970a7ef07c5321f8e07f4a04c4c2e3be206b22460310b431f6393edd1d5c00a20506ee751780e8c3020863b96cf742e441042e451755ad55078870d397ffafc13a7a82089738f476bf1728cde30f9b8fc7e764d4c8457048757604538ab310687419cc39e21f37a1ed8f971926c18899bbca436e07e881dc0ec7624f40ce9fd483f6e6d7290b73f73c048bf9d20d77a37da51a5fd15e4b0f911ce4a1a94074c2b7f0ec5a5de0f9ccbb527a3e8704c495d874c12e854c4a21f7b1615dd7f948de96f5901f669c780001238d8febdee3e53f0c31f59e29fcaf0fb517a35d05056cf229426dc84fe0c0de1f656bf3c6537810ae402f072bb02a3dee8223421826eed58febf9aa0db8c70597f0981578e29d24e36998535dd50f2e8c85dd80cdc4ae5e892bf872dc4704b18999ea4825caab563f06641de894f281cbc29b934e5261c95439b91899df84bd9dd5d7b51a04a6746346ab4e2c219a0d4c0f79aa27ef81b040911dd3005ee670f2e34d2fb4deb670b082cf6d2258256482922cd2d2fc47509795a77cb587458b929692023867c294b2fa826289443f463063fa8754b22521198b325d2bd7e2f92fcb1c4b39de2d268422b424c5d26aea11068a28e8544c9163232caed075a1dcc9a696a4a7a96eebfd52f1131d4b89b70ff2caad48feb681e82cf36997fe28140b8d8b2d1094e2fffe8b047ff8ef4f8796343f94d97c72d8ac65184e7f337f2d929cedca9e1bd40f99a113c209007f7924dc94846fb81b35bb23d6ec686951f5eb90816fd90b45ec9ea11ffff91ad698c1848fac318d3a556706930d5c072d060646231c364dabfcdebb23c8fc4f5ffab53996a127dfde168d5b9ee8ac54a6f05c5aaff139f4cb33352fb30a501b9d5bb183ed39fd766912b0f9f8c8d06348c4dfc607677b69b41a868f0cdfb20668c9381d569640dc019a87b02c80788758820e4f62c1528d473bee4fc67f1786447085fcd69575cc0b3859a21840fb00e46f3ab5185154c07644ab22849f64c2f8261304523c36ca021ce732e45f8fa9c309ffcfd94901dd0804cb223c04b503bec64602c879a49da5363077dc80c38e1b1c16e4835e444b53d010b285d1998b5a829a4a7789adf09fae21948390746ae15865f2dce7ff7b75d16a4a5c559b58a6aea6d1d2cf46e75de7edb305ebb938c882a4f731e3fd22f6d5b019d11f677a55d8ee434bf48dfe3d6e313ba74a39191118bc11baa1fce7dc8387b560808881f0f04c5f1fb839e60da4d01340a840f6911e72811acb2070405d8bb3b8ea311a4fcaeea79083b4381741d52b3f2411f38a4d3e18f0e481e9b15b798cd6b8d9807789c9df5559682c0503c3cf5e62502969589de5b35034b667ec574280360af0b7b3fef91763f5030f5af4ba6414341364f14a66cefeec40792adfd55d7317bde4298ba3ab2d78cbdafd5c26b00441343b213e78b291e24ba0369e7c2cbe111d78ad2c297f90492b40fcefca21c4ba0c23c82c319053d77e00519c9383e4be3b2159366158d192e39fbb940826221cb6ea736078ab381bd0f329fdb69bd80b7d5bbc4d4b6f1799159c7007289c175727efe0fae422577c23bc938368cc5fc670cab290e5a30a4fc9fd7942ac07aacaf1198176ba6a93eb5eed9704f67b680d0207177422b8d383667db1beef2738df713d78c5d0206b64dd1ae15dfe3917a05a60787f39061c5fca0fd7959055d413db2428832516d2b2177d68f5790c9fb016dd4cf501acd4f51c1207fef3a7dcbbcafb956247424d43c80953c1263c238c8c30d82dddd27dc08c45f66193bd037b744797fa89deca38e04d9a8c6edff5872943b1a251f95eba02359b4c195db92c125508b42a8d177fa0565ce40c5de878b6d07e1a3c601a7fc035e8dfe84431d7d75b1583763296f6274ba722cd9f67d34ffec8a4859c3954785751ef8df49b54922d9fb5233619f74897b8d5b6bb2a429d8b7efe25868d5fcf41bf0e867433ae528407e5b1b31f9583a8abb99b2c1ef8f63c91302e5ac2c17d3b7a42a83812a015305bae386c18e80cae7baa2cc28b55f92236d171378334d0b9b65b914fd73f235ce9772a43bf83c8f91d2f9bdff12abf036c69d3bc561b7f8601b0ba5d9c1a21032750b763a93d5f362ff5cd8e83717c452b036ee2b732f8c8c5679b80f8fd02c05b7bd41a345cece0d45d5232bae40a5d3c19d1645d114d0bee88ed4d9ebc6bdbcb7306cc570bdc0a4984ff25380bab191628e9f7729bfe9047167515c5ccf1848e36f7398dc5cd3f2c390c816701e5db18737b0d5de1a48a4fd97e108a030b86d83b023019fdc56c703d254f8a7904126795c06f35b37ef1af3fcd18ac48ab326a9978316741da4dbf783f8bb3689ad29cbac2dfa182ea7eb0257cb2b9d8a728e275e69142d499f647affb669c966eb8cbd2b566dc2be29b120cb7622ff1240bd2896a29a38f0f76c70a0c8c4bacb3807adf12a9c42ab5ab1dd4d9fb0e19010c261f8dc6d8a0df370e3d60f720fd039a4d7afb3695452a07d0a7460134c691776ce571aa079327b38b80478b62ac6d890e6441a3720e1d7ea4343e3e4084ab99ca8f5c7dca45ba2fc82f082ca58bc113d7920572ef557e0bd65b9d1093b3ca7de14d31d1b889bf15d229f6d1022fa33e127a21ab3b466bc8c37f4e88b6e98909340e06ec122d3483ef2b625bd0e0522362d4dc099e79f59e6bd97da13db8694343dbf2256f76586cc1074345b96562cde5726f4ee2ee6f06735ad3a0afe9210d1640756f8a981da0a4c25b93d58124f3344e2d9011221688718baf13faa66c1fe9047bebbd34cebbde7b8bd12757b1d6a835e59ea1c31e547e6f3ac19d245888ae0d5737ae04c2acaef0a42964e2aad4ddf1e96eaa0f3cbbb5c51760209aca0ba06cadc62182c3322788f3ab5925ac03d80dc05ec9aaeee4c98d18861c408ce5b63e77283f08c2afaf694452c0657fc8aa0a29ec8e8a6c942787b757d0e49d305612dc85c936b0f635110c76cc4f2302cff4a5dd7923c055f42a8c30eee23aa92ff5fd2a9adc438ddd2ffa181da2e72a771de22331daa6cf349dfa266331aa08ab2e50b578ead2d285104c20be7e44280edf05cf1f708e03f83d124820187b649dcfb7c232eda81bf959f970bb470f81136e91b203b0c07762bc04e2496549642cf9fc328a2616fe67125d9a786b0680165f3d8783cfcea47bacdde07517402c32bcc77433ba4fa8d3f963e8fe9886edb01006a127eb0c79cfb0a540e8db47c97651507b3b5c1ac7abc9b71d2e8dd093493a902e60775c61179dd912c180e251a2122a14777b5375c53d8349354494ac5070982eced9a067c0c0f5818f846080ca20b4831a0e3c6fd33a8e52c09443bb5b576adbdf059a502c382007151a2319fc4a04d53739e10399f67942e742842c722a3624ce65102676619545a910af821095425026b570207623ecc5c9023c0a05a1ae3d866804b8e1581a6e8701bc36a5af35e313c5b151ec7dd033b804c4528752363badc9d5a827c030ab9b7f39154e9bb7dfec3786576abf92f996c4027756f9444b9df4de1c23581fd2a0abc4a3c4a79d9e6f02143e577c1780764bf4cd590d3682f5dc49a13a637101b706ef1655a9842c94563d46adffd310c06517c7a177fa2ede90b425fba2f585ae2a17a86565d5730858294a0cd5a380820d8b2d1a37561938d559880d20a89260158488aac00888a66b635858299bbd36725d6e5a000bd617e0a00f1cce2831cfad9eb8dbacf0a645aa15a0d788180a3a1e2222f2031fdb297b862a1b4107acd16ed0fb058a3259d00a1979446f4272592e12631945265f5661d1104f970c3cbb14d91e0e7bd1048df49fb42b396db8647d36b69c01f324b82eea32f40a427f0f0a8a852b0ff0300366ac47bf6d08d9f51001f0f3dd9db9ba40bf59dbd091f41323ba182304a83a066b77129001a405c2b4b4cb30dc07c4951991eb5eaa417e82a7dce1ea80f2c747e150486f20e774fca9dcd7b75dfc0c4ebfebd618ada22360dbe265d9967bcb0466775762141c8b64029dfd73eff9936e31e7df02583b2504eb3260a5d7b8c3618fa6d55cf8cd0ce478a20a78316d2a4bbc017584911e95b74e046f813adcbcd79095a8ba2fb17b1bc7defa8b64b7c05d4f2950af93904c72b8945f2e16f80116a92c13194b1709dddc7291d03b9592415d899756bd73cec85c0ed936d96f0b7ac784dd358f95fcf2e515e0deeb05409a1ca187fe6b117a0b56708f51ebf1562ad034742671ade82c79b242063a0d7f8c1bdbbafe2b5b1844acee67c62f123c7c10f7e97970788bf81ad083e9c2731dc0094a906f66953640e47bdec858f1f936f3a3bf2b80f3782d4ff15589ef26a7d25beca41fded433fa828d476f2e20aeab3779a21fc4b9cb5ff89546ec72a406713ef76b57eacd2173ed20a9b4c4524705b2d1259917759e21a93899d9f1ff54f89b54ea3e5a928686505ac0db2f030e4504b9c1f37ffd3ca2e70bd89ec0554b70fff6546bd112de5335568931bc3870f339f4d518463d48a2c4fa45854c55edeb3fdb8132e4db73229fe63e140cff838ef1fd2b7cf927373b5a3de23b7123d02674e24662bef3b43693ea11564f13a1737c2ef8fe92f24d16ac8e5c4965bb48a7135f06d7b5fc501ad91d1ea85ce8e0d139953e1e3c1a9c9c466482b017b137d5f325b8ce737428298318cb73c8cc5cdc352c46832cc0a7b342f90025ab6967ccbda9a95027a881a4e459d3ccce16d4b19df4dfd795a148ec9dac30ea14dff4b8f4a59aee3e9135aada93d4e9e2b53bce2a1db31b35919415c1aac9f084d9cd2b53a72c247b5257007dc29970247633af3462ecd366ab0eeb79f65852e5064c9d8a4e4220d3c6081123dc249b33cbbc6e574c4e66c754216deab84e7d4430bc75a3335a024d40d87129ea87a611f20b8721a8fe8c9807e0166c0c9b340102c74e698a531d7e1d1b96add42138dfc292fdbd8d9d9537d49f5fa0398678a9dde8474e0a797c67230403f07cfe766ade123707012453ade4bf22f477c92e068b2b063052ff418ea44e5cb754375d3e97a42208313186dfcb989d1fd8b43fb160b37edc4c5e92c3b8191f8bea8a3d3569546aefa8a25cb918bbe9e085ef8b78e18328fc68c08d7cde99dce6a3fd3ef234b82613ebefa93ec54bcc2ff0c682518a3104be18151c7211015f477a89bf1f07590ec8783f8a04519cbd8390faf44215e48b4419ef56b9f79f8ac37e79a25c1fe5721abfcf4f589c0839afc503c9f99fc8672d020959ff413f3a2726f2359ea0fa8fceda84552ea1d1770f9f7bcc582da4d08486d3e820efddd3158a9777e789d90c2c8cc0c453ea3d100f6c576ca0207d4c35018068c5e445497d21ab07a5e3835baa7e1072e8ab42463c0890dfbe7adc7100ce9a43d23d4c04aff2142070271e444b8b991090390997d49c538008008d6235826105a216422fc278457f1eac99566458fad64c0803a3fd6be7cc38372f530caac923ae45592ef33516999bb905a8bef2ca856fe6724c75df46e1ab72fad979e84a44864b01225ee5faa3b748ef9f495d9c80ba179ce7047918f6b9f374670525141814643e2e1be62794923372168214057be2f59fe6a6b7a07adf6f3b2046f8e303878c53dfe19190ec55f4a0fbe7144ba782638eff2c8485e0a7385e8c95406a1effda6996812059f9bf54fa9922f98051fa01c94eaae58d7904f8bdda24063154c7d84077ac0bb18f9379396c7b204de073957d25640da0d87b2826e8cdd7d5dcad8eded51f3f4d8ba32e4fd0f657cf4d11b09664e7f323de51d9f7b7d37e2f2b17749d61e3d14d256099a4b30ede5ea41fd10a25d1997ce4467be86bc7b60ec374d3f5cb419c25f2dd8471708e57d70e30e088904e7734456dbe06a0c66152114f5fe2a3c770313dfce4866113c83b4a963ec6bc607434b05190cb86cd02f1c0817f6b482a706add1fe044d272433d7316829efbdf301dd96448e30c32bc6182b8a17be30c964e94ced537f59cd8310e0570de916aa5cd41fce4f258dc99e0805d6727ddd13697988cc94e2e2b206c43017842ec816db75a56b4d4eafaa18b5ecc834caac210a162e70cefc0e79df19088265fbae6adb2d2f41a78acedb94419a4fc36b0646258fd12dc9651d8edcd62f1041498145ce68d9e7d04ed20da42e42c7d9146bcf68fc57f19f4bc48c5010f9c01a19f8f00008691767936d499d94f77622b8a3811405d3ea4a6d3acc6d9bbde6187ca7f94b5b1b82ae3b3cac328e8bdad04ac82fc8d9dc5d1d8d948bce935ded0b511d065e3e381aa4e2af11218fd775157177b65e0b16e46888924ae3c6f9486be969c6b3e3b05416914455aa63a8168fcbf6010ca89f0f77ad347c8755f32b6aaa2bc69febffe8768ed8109a1e5b70ee2f75dbec3904cc8bd6b5ff2dafb1ffe3761f9a30d00aab975fd0ec1a90e721b00ddfb6ea7581c1676f06b82d78b4449015a7954fdb223a56a0042f51dc7a289c14439fd1cbb604c86a65fce89c7b10620f2d5700924830db7434d81473fbaa996ac5d3009cfb6259407689e78cc7e8021cf886befebad8e67e8418cc2f1f15a58c5e75ea38da346d0241a4b17fd4ec188d314cfc6f2b3e49a8a60cb0e07f13fbd78cb996d0933030611c4a0760663cc7ccbeac5187bbcd30c8614f6bd168bd10612fa6e6882e91e7e035a6d157e7294b13c3ba20748b2aa85ee56df5c52e2508237db28b27c06ca294fbc5594837e3de2c834d9b94516a75dc09b0c24ddfcea6ef8a465449abffbb0c36bf15cee3a2f66d3eea6b87a0a599fe2762ada757b32825de4ed0d694e0e2e88396c212fe9b6f3ea7817c89d968df4ead225d8a6d808f4869ce859b3ea04fe57ae46e9ad5547097f1e41177feca4021fe1c7f134d486fa4bef75ecd5cf5d045bd9f160ad3a59592e165a3c6a12ad2b4384bc49ee3f2b3b137a8f1d92bed2f0903f33f23e54542e732827941494016c5ad949391e89851d69d618941b9136f62dffb5fc2f97d0ebce7bb806c9f07e60d8ad498f8c96858095ea6d050a2e107d7d7a50750b35bd7f24f1120235edbd93a7f34d56dd701a06a2774ac401f7d24768fbcf94b06a14d12435ac35a1bf237f94ef76b4690d1271ec3fa7a24c53e8766d53c3c22f820fd045904ece12fe6b23c54a9a38c3fbcafb09280b8b88103cb3feffb1a27a392813668be7a56ca06ad87fd14433f4e20b38141c145dfd2a61f0a00df0a14e2ba265cf2c4e8440dd3959ae37962186f070601409216e52ae2e69885c6363d8efe1b06aa2fcac3a8cd7ffc482609d80b162e8ebb69b0631e7bbbdd217335e146aafd495a038109407ca2ed0b50942687681d9eb1f59d2c928aa4fce437aca8e4c03607d2f1d2af84d610334d6fff4e2d1c7e6db0f50f724f9766e83cf28eb6042cfc9203014aa12450da3719cd64576ba998f2e4445b191c2719776bf78dabcc1574f89661368d5249862f8aa8ea4a31e5be6abdba0340aa0d6ed480bbb89f6ddb0aeae7ee7e4a5eeecff820397ea5bbf44eef0995c8cc074cc58f473c959d108841b335fb75d554ed9fe815e4a73ab48baef9f3ee6cceeed067b91c7be9b9ffc22c17cbf0a5a3a0b417ea0c0784f482ba7493199f5851130a3961fdb64c708d10450bddf0a06208b69daf97957e14ae277a3cfe5b68fdc350ffffb965774769dd2a09c0f57f57325386c55fcf45ed4a8f766f9652f0811a156d49c67dd496003de0e2939e20012e856eb0545aedc2b64cfe78d5050dd74dbaeacf746afd8998031330e7729d3a5f74c69b865264057edddb38151dd2010163178daf19a8bbb0a7801f74395091bf9fceef406bf89af7bccb253c65dbe14838bcb0f68a4f262eaeb12b6ac7cbdd75c336b3f888275c97370b43a8958a106af9a2429ae234ea18838948c9d2349c5cfa2702c6ad45c73d8ec840ec28b2c6931a2b68b6e159a895e58cd4355399352969a68815b4562f21ff3bb65110ad75d63954bef8c58e16c22d28165cc7dc617f9378d8f51a01b9d79e9c8013007b56578150b6d910745f103fbe5a3110c5a3ad5687f06734da411990edd4f7b4fdc61d73bbf79ac31dcad08273ec5d9404c70b91da8731c7a2331effd842486484289adb8be3e978779f5a50aac86cc9aba8e9bf6cbd85efc4d2537230d5c0786968a02f0d567eae24752f630f5e95cf1184c40ffa2d279c8d15499d536e158733e257452b21255d30eeb1f9a854c023a1f45945aab1649b2a138244cea3f248cbc82b2b4d41c12f5813a147781b79e2bc72d58efcb8df04320e0a76eef95f53b720e213253866f99116960361c8a69cb481989d3f8eea1a1a1a4dfcef34f1de4c3bb8099373022d6a3cdfcf20fc68e06da81a2fe938976363bebc0d9ef18726fa65e8038dbea08d1bf77abe399435705060dd510f6b8f2c56fb937f9a2d5e784b25a7e954fea721596724d33a9c86ec8f77c3357cf2f7254041d97efed056117aacfc745610121873e3a456c6bc422e06de82095fbd5b2a40c608828c360dfb0dc097dd7dafea38249768c450a1d1ff59ff254123c8a1149b7a6db10091fe6ae05fe4cc8c27c88761ba154b92fe39ad02645ebe6915473488e933e1fdf60b033d1a98e95c02d636f9357ef23a8cf2695a39c853dbe1ef289eb5afcc45411dfd4729d3cab601751fc33f87ba52b0e623002f9684ad1ef8cebfd6f6b7d644b8a7ce201706524e28ad8e9266cecdfb2c28733c0cb1aea1641aaf992f6f63779c352b93ae975c2b30df925bc44e3a7835b38f0ae3c2e58084a4e39dbd3fb6d6b28903c00f49803b7a5b203e0e65f6f4be7024a5c3a8ad9826ff60ad094b1ad42344976401b94d6187b3627667d3687de6be39e69945fc6650994465b63a7611fb72aa410c3bc4c844cbf61fea5aa8f3b6b12f60ff1976fb0f5dc2318e2a1727cb282bf187dcc5fb60fdbb5cea247602b6ee6d3711d46b21c0f16a521912a651ebc82b1b55e43a9e7a42fb56f8349676c4a39b234be8c7dfff3ab61e53ef6773c27fedb35175399e9c96cda9ea886721ed271520e656c997f288281cd1e551e50660b20ffe68475ce517c79c3e3451da8ce1e232f21594327d7a3c98b10db5d77365974afc175b9ccec5e304a0a618bfced03738916117bb6c6ad52c3f21bd49cfbe2f6dd9b4b4be6391285f3c4ab45b203107d006b0f2d666640094e5055aef567191fbb23a991f916dd9d3122f7616314ba2c59d516fced3d5f2e3be13cf2b199c5970527e3b1316bd45c246c851f675bcad1b694852a578fd55b96f1eb6840bcd35eeab724d02444bc980678cc0f1b9e7a7080b418ec692249ad22651473b58015d8c53c2848852c0f86a5d85f3b21e3d0756308dc6224dd99885de80cf2841fba2eed8bd2dfdd43e948b273e8da822d06a5817bd800c368e8bf2be1751914e933cccc506d817c90cf17d56d30b0e447e11ec182cfc6a8542a0c4cc39a826c826ae2e29399ec4fcfca02305fe7a645c543def2164979268152a6457afe7b84a9f1ab8517554516790ee9fc3bb965979ddece0b8b8676d069f6fb1ab5df866660ce9e09ea1666e5bc0d913821576d09dbfaf62d80ec3ef58b351b8fbe8da8b578c3016d1a6eeea90f8e29e327226e86b3960c3c951fd490057babe04c46ca7d858d5dfe923286ef9573831f92c644af3558ef254dc55b2a1a16d63ca9dea3704478f638f2542bac456a5c3fa249a78b1d82f7eb2d4d5e14e2c2ab03f08b6f214ebc401b8133a7ec98a404b63f8fe433ccfa41eac0b7aedd89f8bae34fb6945a3ed4bc713fe5bcb69207960438963381fe7837817cfcd8f732217f1c62a8218734038eca1c22c9f1438337f75194e15d43e8ab259c64724188bea2c0962ebfd30aa747f7360512c335d2f898666e62759380aa47d75073dcfea81790ca851706dced04cdab8520f1e015c5af48a318c085185185f92ea5c41c61cf28613323bc8efc41fea33562531293300b9148cdc0b684a139b4dc8057769f242e8e9ab079e722b2d3b5e2a46a7fb9f6f5333d954a72fe789a8a36c044928c446a9f24b2e778d15bed41758376a3fea04ba8d1059a4d9497d18fd63380dd970e205ca232ec766c37e97cf57fa52f8f618e03ebf9f53fa74050c61a3768aaf2db02952ba6780115dd0b2aa64100a714b268d7d50e6ca7c09d7272cd2b1e66ae5c83337ab725e559cea893acd3413fc511b0cbdbc5ee951f839a5ed994670b6e2e593d859b223849c5cd5c7c123b1cf9220622ea5eb4af6b5ad2e184e9a0691726f4cc09140b82fa6c0becdf031a7fae835a209232520717c2290ada79544b708a037732f59c4915e064abbd5207f67aa2e1588aebd5581d22955387d16e2a443b5e35e5020a730b0382d4114d82694cd6f6d6834a085ce61c62dda57e347625e20b227b37d972cb2d654a32100834082908484a2f9174658ccf84a975510a2b5d95c45a6f7576bdc3090e335977bee02724589d4430ebaf7efa94c436fb86c959549d609bc9da46ba2ce2c5ad4b5361eb9918474830c7be61a69c8ad66104f3c663f306bc75a13219ed2e9d8e8ece8fcfbc99000f3ad2792bd2610e435626ab42b1bdaa4374cabfc26a85d55a4b0490c17c88c993459f05a72e0a8c0539cabc81c52c0c6661b429edaeeb3a9a733ad9212f603f7e64f9c104eed7bce138eec76495ba041be09a1e574dd7b42805fc6ed5f47c5fd32dd2d7c0d02dd2778b249e68ca8ff48c884b17f9e82e73cdfcd329ffabc49d900e65248da3b5c05cb9ebc79bb8c4b8b98ab8cb456f16fc41417779939e6b5ccfabb5ba5cd7c1d807a57e5de714f41d4260f2391e37d4f8f791478d20b4b877816bee39dbb99e2a927bda713698f4808510517491528309c68c5a1157f4e00b2b55d8e8a28b247c8081e172c5b0c50a51d10a72108296963f87f21c1daeb3b6b39db59db5744ac98529cbb2a4ab1f775aa27e8cf0978dca72b22614d99fba26abf3f734d4468be811bdf9109d5159a6b412c3282d964b950930f8e10e231c93a7512b7c1eaf179c80af827c74579900cfd6346a91eed172de34c1a4d36461f820aaa6c1f78911a9eb4be0db1a07e371afcda3950b7fef4f651e77212d71c09e679ee67de4b818c00fc5184c5fd3e1fbc87c587a191cf31883185faf9a1efc184c0f8a351d838d07df67e68d803ff32dfad07cf8347fa4c5e38fea7102dc2245326fba037718e19b771815d5ea853eef33690affe7815e445732e29d21e5183e069a1d46b894c95924ced05c3af3320fc38c2803032d81c0a4c34a1ff35cd813047ef843741523967272ba50e4a1a91e2e3cf3ac6febf572b2bcf7772473e5654922d1b23669e968641749b755779a8f3a37dadba01e9f333075d1720ba634d567f4cdfb3548fff5d7d44b42757d8a6a214c26d9169a860ae8af1f09d5df1eead6f7502dcc793dcf16da85fe19e873a87e426b1ac859cb856168444b5ada92e4248ce143566e77c5eb93e59e29c78175d65a6b53f1e6aaa798a9d9bd5230e9aed99cee9af7627c3afd8fa3933a79ced9b1399d4acf548082abe82ed614aca24f2b156b5ca0a1660a662a0aa19cb55ced5abbdad88041b85c2e17bdaeee79dcd4753b6130d92ed244c5557505a453feb5286edad103fe32690a59a84f9334ed5711989cb3ac80d9800981b90a4281f89fb145e6618e3accb17b98296f170c881ce68dbbcb3ae88876d0d8eedee372fd40e6844cc683dd79e8eabfffb7e05aebd7647f202fb8aa3ee9f359fffbeccc40de4af19e84c2a81925d88a3e7874c1f4491e37d4e091c964b2dc55f93c8cbd9f487574edd6521d93e5ee1fa53b9624f96c3eba83d1316305265b36c24c918a35ad2a86fd3b8ab903829bbb6ba063b2e8aa893ce5abcee2373893d558e68dbfc5916967f1940ca503269dc8bbb88a741bc77dfd649ef277db174c4e99c93ea9e35efb5cb5e2a8c3cecaa1a6b5d35a17ecaba0e046e1c81665b3d89ec980c0e49489300ca1a92c30cf64b913d994c9a64c3665b22993b9d0bc9111c988a898f70ae7c2eec0eb3aefdaaeeb461e3a72666e70cb2eccbd184f3ae6d0ff5a4e0954a41f75ca1535f307d4652b27e7cb9243c295800bf255bd493093ec4fb267a1b9a2e6c4213b8a2e676461cbeefe298881fbbf7b6f23992bd44cf95ffa5caeb5d652b082ed77069f051de0fae0d327b992f4f7b9076b8e29b89fbc55cc5104f692fb4412c627aefc66b699e4acf8e284b89273754f3249240c9017ec71622df2d1ff4b9e5cc9c54b15277e509bc28a1f5a477830410c64424d605064a5e5693cf9c11733d88112524c58411a573c39fa0112285ad6b972ded0306132e54ad0385c19e4a3378e3f871aa171fc679c60cec5e2024f960fe64ea73171544dc61cfd9d6ca3becd1bae09e65c5cd922d95938ae6bad9528f7975c79cb9957ad8b9672dda65de5ce7194628ce96a8599f2a7820b0b3f60808b7296ce54acf97ee6a3a9c648d362648fe91b6e457a87a749308f4c15f716e0f16832398b50d7c12325133e48f901971668d1448628578c5060fb72c3142db721c495a21891962947ad17c27001134510c1c312565a2df433653fd68ae44dee06638e5e5a8c5adfda8c2f8afc356f8c74ad36d678d46a210baa1044b0176ec3e8ea8a2f78ca1f46026f188624f085c92ac1623d65ae806490fd4914ec469a2435bc7b69430431a4020d767003aca805b459035e5002294cb000838614149072934204134b7aa832832caaa46183d74c891e0c5d89c20755b03441434a1817632e4e7ce94e27da1042f6bf7b821b475c44cdc909bbf84a3c1f3667c34a2e4ecc728b3f7ce491c93158f0d015ba3ac28428160445163cc8010a2c060b83bf7401d53008820d6b58858954aeec3aa125fb0ae55fa70da2a06288960da01247b4c09f7f9aac56a300add92249c83e668b93d1d5486364b2c99a4d1637c55cf1506e0ba745762ff20d126fe9a30b935c97ec4ff3d1b964ff28344661b7749557fa592be228782a09ae359504d3efb9a1c43d3105b7e26460e01aaad4803ffc1a621e542dc1315f43f8f86b001f7ff83e310ffe0c6b5a1443d14815d1c808542c51e30958d90ac51367430526394ee6aa492ffd17c9dba1288c888ffe202a449114964a825b14fd13491bf2f78d22a7ecc931534a29a5e20c44b8ccfdec39e7ecee43cdd06fdffec7a1c8cea48e7edf0cfff5ecee26753f672f67c55bfa90a0ec24775137d3d982c13aa314909c2cfbb3bcc0e494f1c864321d9c8c93c966b2dc8bf1e9742fa53a2f23ba2e5f2718ca14211286c0773ee9b6e057e5382ff885c9691b62a31ee95e9277efbdaf2f28b6561748b901fd3493a61d4fb037ce7d1e2752644815dd638f3d7a3e86d8bed8f5c69cf0047e184f96535a0ac18fe4dd52087e24f1bbdf1427087abfc6852eb9bb288adb4df0011719e2e33fd919c29d387dac3dc0b5842eb0bb531d9d2ba6c0fef59615009a47365a6bfd9751ad334cdece7237e7ea78c70510f6be302cd19480ef0f146448679f7ba7a94f33f86433c9fe2a1978243a66d20347c831c77c4ccc25858c355c21eceeee09e4ee800df9f368073a7fbf430558a69f7e0935c3d7355c01ff0c81cc8cc59a999fc13efe1931061aae71c13e7efb588cf9fb32e2f5d1341d40f3367c68de8678a2a998d2cf9085f0f1878fc59f3731222964cc2591ec0741f3f857ea40872151b9c509fcf8e833879ee85306fe7c2409171caa1c11842f4d8668d5e860888a20a0607245192d159eac40054459645d4469a950050fb8389a8204182c681160a6fc71ee2a016ec2279a9a37a899eaa9257b0fdaa9dc40320e9ea08e61b3d9dcdd5a1b5de5f01c3972cc9b1c93e54e73db6c7df31ea60f138835dae6e5e95549e0147ac0e43ccab1beb243a787641faa5dbd437a7f0fcc19260766ef9044191ac7ff3e29360f3dbce04ed4d2c4103970618505b12f8c20830544602879011543b4fcbb81742d9cd566b3eec91c391a8dd966ccd15b8d99ea9db65d7143195d73d8d117235b1bcdea25fbb3541a40124c7f8b238ef28e2070cd648e0c03f83d28629af23530d9369bcd66b3d9421d7407014130085d81e0d1dd11829020be7afff1083c2107fd428604d9b182c9e7b11c8f0c8d4385ec3930c31c67ca8394544c3566a491509418ec08c623c3947546393c8e820c959193338ea713c6e49475ad9f453053486c456e80719498bc39375f1e25cab22ccbb2ccc919c71c3cf657570b98a92b881a74778a29918b9dc70b3e7a9e87777cc1fd2a32b0ccc7f93aa79c17e68d3f094a601e1f5b2485cc272acb06f8f43860e2f80b3eca0001b74b646981efbd65594bf0e642d0ccd088a61911fcbccb9926cb677fada84c9a7a3cc164db88687e856dcc20c355a06db2482b2033a299162ae68e0c8de3114d561784a68ec88e91262a76caecd80c2a46047df43ba328c38b1247c0000c1a5c26196970d1a20a2c3b2071448996c4b6f9e8230e4ba5924ca92423f33c5e2ac9c860540bf59370a43f9a0890998f0c6dd4c323481f51580908afbc61daf2605db69c297f5b7ea4149cac6abdb9aa86fb99e9fc92c95a92758a59657425839fac5bbe5c311a9a59caec649dd99715b2a575d9d29693355dbdf3659b24fb9378960073ff95f085afa083c9aad9d7681ce76a47b6dbec923d4479917771a3dabc119a37ee64fafb77fe1cf71cca33f7a852b6255de198ec42fd54c450eeed01de92116d2923232323da92a6b81bb706185bb62d6d694b5bdad296d6965e19e3a119ff20f8e08320f8e083208802ccd17efcef9ab429c4b0b56c984338411347b4ba7baf68c4668b960d26235a9d6843823b6d9b1761e29a5517b83bca2c584aadb596ea3879deadde4f7a3dd40cbc24644edc6e458adc6e5dd715a1ab1e3ce0fa6e3922370043044cfd21326b6062485c19f271a873f71c1e3db72248803cb4f7f25e4180004dc164f55e749593338effa79351f62f8529f8ab46d95b34ad450d5ae4a44175eb6b90a6738f1de8e9c4d11c30596d47ae3ae104b8731794c9b906596df9c806eb3cd8731e0a470f38051d60b261422a153752c94882092c2d1ba85098160e1d30e9bdbc17e9275dd9c78103263d7a13c99b31ee0fafd8131434f341f30950033c839ad47b79afc94a40f6f784bc27aeea9a8f32ba6a58a7fc4defef0dd1d58d9915494c2bea44ef350a400a4c5a1b0a69e09967c4993789367ee67d70bce971bce97b38c1f449ef8509e00426db466d6f42d5f4db68d1647a1ba2111b6f7a2323dc40d5e03ffd91160daa06ff8d3fd2fae80dc7cf564d8dcde3106bc0f13638dee66b10e16b7e0680e601f03090f001106bb0f124d87812be86119ee6b381f25e9e9017a3a994ff08a8232d1b365ff3fe336cef85e34528954878ff3a1486356ff323a0668be649184184c7f1d56583a2b71a5402c2c0e07f4f7aaf9e20d448534e00222cc2e378eec9313b15ba1eae406ac17e672477a829f33394f19e0265ef792809559f80550855e3009abff13e347f43049aa7a2cf8d3f894670dc781e4ad692f7f271031475accd56be2c187b73d51a5d50e7ea9254236a6d26e791e7f57b4a66ca8907e36aae548ba7c46660b23c2564afbc259df2f786f07e28a313bdd70bcc5f0830c335f6a7ccc823bd17aaa456b2d317647f1fe42f740cd8ad962fa8b11aab52541a5425acf50b260bbeb76b2bc2f4c96beb5c45ad2d88b7e3081fd5d8bcf1efbc57d7792f5fdd0c956589248aab86bc265c35b5d8b2d0a11c64120c734626bd589859263d24bc2bd9edcdda5c35b58401e3aa7a4611d6d6b16bcb4ce68df7baeebd3c185d1500cc10b07859d2848b0e2d7f2f465718c8820c2fc09052baa0072d7fefe509e178bfd1223902a1573844cfdaacedc6ef60e3d4e160c27608345e09996cdb8c273321936debf12a159924b80ed5985705930d6b22a64aca74c15cf54e8d09e1166b98e783d7c31c3d2066cabd57e3c4885812f364f3a6edcddabc976d9badc64a4acbb2bbf7f2e8f15ede0b2c1dc16e802cde9f94caeec94c11a6edbaaeddd5693d4970e5c795323fc3bd724e0e27c4b9caa0f273302697beef3faaa4dee771ae2cb9f2492d7c2f83aac14f437ad31f697d6550672e88acb130e6c99bc3d84cf9875ee723f334a2119a977912ca67e64da2111a142daab121d2229aba4ff336de6443aca5cbf42691da68447aab4bb84af31a8b15c58a62b528bb938ab81d708fec0fde6fb2072da166ee1045039749ae449128b2ba4048d33ecfd6d39701987ef7d71f46cd7c09d5ad185450100edf2a3d0e39ad98c78f51ad64a2b083ec26d90f40b60fd9fb4937570d8b9550de9ac18f4b28a0203455e383bff45804c22f23f3336210b1a61f8b5dd2b2a4ab199643d404272a53ff84dc3fb443f29e34812c21b78ddc0f80b90272638e3055f6fb69e6ce041ac777eef7cf4c16f74d666a36808820666a66f2aed027e4c621953f1a2714a9f84d4bba2a4229951bbd812df2ccfc510e851970a422bd03343444a9781ec166de74a71c403ad973866c449837feee7e3ae51eea211b46c084084d9c4e12983c598ee3baae39fbaaf47a5ed10fac341d41aba7d3ff38e6e4d44aebe974e082bb57a5f76a08c51d983734cc20504a49a4eba4ffec90dbc309ec3f2d8eb153fe1709ad3db0e0396f3aef02edd4c6100001baa26fa0d1508305112283cd0808d06c56237d2008829f48e2d1e33364cbbd189f4efff762fc4f29ed2631f4aa555044af80f43a3d930b1444585a36d41b80302226d1c2c1b640b14a3761e204cf79c3e4bbaeeb6c1f099fe61d32bbd975627bf77af77a3787878e0ec9c11d4c2693c9059852da75f77623193d3636ee3636366260faa4cd548d815db59a5fbc4bcfbcc9edc54a0f8af8a12c5b64cedba7a82f57ee3b190b2dd2b7df41dca388d85cc389324bf0016e635811628a1243322faf253a9081066d5645873d6880c91c522ee2aa7a730f9918d8cba4cd13b9c5c0a54cda80979c37558d0b5ceee7728b93242301255c99cbe4f4356c38a1c50a93172c110493d60ebc2811c615330003c9143544f9621b638b1948acd13ac2836b0740f0c1065282b0d2f2ca719cd541da62b20c8065aa6c0da68a5b01d114ecc3fb3d94020c93fdf221ea575a0aa1a6f54e4934e22efca4df90bdd578b2cb9011c93e8a1181e816d9c52acc40238b5024db8a93484e1ff4acb1b448ce21784006c864bf601003938f1ce7969b5349bffc45fb355be4c9721d586719b8df7b829ada4c593ac0a429ebd05287b33a51c864ae2441fd0a2abbec3153fea1cebcf1bf910626fbf532b98a874fe83139c882368bf928a533ba9acd6efcfd1e3189d921847b8a99f2df526482147cd4aefa44ffcfce4a2c7aa58383aea26f30775e681cffee2d0fb20eb2f3783341e203bfff4f10b24b2c76cc11809f8a4fb2532c3221fa0277263b76f2662cd8dc62cfe60d18191c60bfd97c6469c14dbb698cfa348e97c00e5be899a9c7e0b478534cd6b541ef74f67740c318b103ed36b1dd43efd26dbdf3332b676591db660dcec059175defc1138f01fcd83b03b8de383d6f66336a238cb642271ad3166406a136ae8d18d5123c690a67ee18673b409af6ac67b4d6ea79ddd3e6c0ee02b9821625063bf25e470e8f9ebbc536c62773bd99aa9584ec4f64b266d6821ae92a3553fe5aea12cc9a7d51a5fc438a3bc4366d43b85bad8b076b1cc7bd7fffff47a9fdfff45a11bf0a5ea7df7530d73408fde2e1f57a594aa9b52dd41d5d30e9c9faf9ab77ae50fe5456b4ce9439993328d3089cf3cfbc51325544601fe0767926fb75c51f4a9f3ca986bcaf1cf773ea74aa5354ec548bf49b5f056d17a6b3620d9099edb730b31563a0e1efec7b4f92f27de28fe72edbf5e3e3105eb0d8ea062639c80088a11c2cd15aa1088a302f38010f6414b57c67aab86a44e7a7a888abb6723f3ba805b9ca5769efbdd7ebbaae7bbd5e322ba0d17aeea5f4d22eed9b52488f4dbe22894d6ee9fbc239bd4b83f7446eb67f576960d2ea86817c3ce5df620f1a989c59c0340d4470ae4fa928a4fb660f55440413c7bfa2bc9f7e1706ee58334c7e872c50b1e79c1e8944a2f590b0500a45ee56313f5b06cab87bb97bfb49946e714e1c510826d6da910bacc323a7776e268e3f0ed86dbb6deb9837355c9a3a560df394af3ae6292773a763d91eea44da64aadac91c9dec44da42f3c67f004558a80a193259f6cd10322414a2810df48e9724e807fff2e526d438a3ac854a2820100c29f7a4e7691c974dd6130d45ef78d64bdf1d82dfd7eea1cb84348e509609e1b8efcb4d1c123a0f7d042f6aadf58414e0ce64ad09719509654d75860d97ec290001e4aaffbaaefbaeaf64f011c8477f08f8b400933d79867e9a027c33593b5c21061a05df04df4f9a22fbefcc2d2427d727a12eed7e7c147d66847010201f7796e0e9e36dd457c1135280dd05af92e9c9555cd7dd0ee81bda418b1ea82c4163468496a21bf8c001472c01042c58104611553cf1f2781042e835635e20e925e42a6fbd60b197d017e378c86157ec932430bab24a66cadf49760bc587ec146a3bd15f2ebb05fe66ca9fa356f6318f9f7418120e7328b3e64de0d2f338cd0ea3293b4445d25eb12f3bcb3e53ff0053b0aa0b96f999271d0683d1d76bb2a6ecd53b602756f1057bc1ec0bf6ea6a92c671511b9d31e5cd283bec06c6366fbe1cd56233148caebc099f9245244f2fba02f27ac5804c3122bbeb8abb4aa2c35eb058a9542a89f6e5b2496cd0cb06bd5eafd7ebf57abdbc17e8325e1c1d0509528f68adb5fa20c2a739a716dfe94483534a2d4d81528ea31ced4087f91020430a272c7020858f7994812048661a938ceebad1870faf8acc89dbad48917befaacb77b6b3d776b5118089217165e836742b22a3c14a0d4c4edbfc6980ff02e6dc92dbe785c9f226113519604e9cfa911e34516aededdcb442e8a592974aa138e70d0a95c3a367de74a81f8b22e2e310ef861f5aa406a71f07e3d429a54fbac7d40ea0d16aad2693c964237fd601341aa5dd9112d17f812445996b5c689214e54f0b708f8f1d70cf11983e39ae8044cddddd4e2935816d0c9b6d88c96433d94ca669fa4c4f70779de73dc15d264da6c99a2693690ee91d713576097a4c4109f697a1e787fb151818148d54f1013f7c2b424f8091f913cc7922f9b98f641addedbaaebbf6dadb755d77edb5b7ebe6ec4e6db9db4d1cd9f44824af6bedeaa32d77fe62e807c08071987bc1b394a1ccf68b2bf5ea7353c53dfd9e2a4ea43fbd1c7b5d1f6177e80a2c46440aa5b010638aea6894dad65afb8179231221810a261bf67919b2027e3ff306147f68d18fbbff1cf130c105b8c8a47455127fe837898ce43c8fff1451b1489418cc4777f79c5b111ff2fcba684ea3d115e820cdb738e8a0b5b6eb4e3003531448a34d968eec96baab53fe341772139860d25daec354f13055dcaf3c466549b880c8594c2be6e85b4ca7f95112eea58a79e3b4f4991365f151e63197c53a6c80670f9a373474ae29901902ef9400ffa094524a690e8f1e1a0d44c3725dd7e50093a7ecedee2da87551ab0101d56a40b55ad735d79150c335a7b0021f8dd35e23600c19be273d3965b50ffc13460999d3066005d187f4f34707441ac201b90c9ed2c0c4f11f43c80f203cb376e2acb55647e7a10b88e747844cce9a119ffd04c7713b9ce01132f9ee63111f81d8c9025b4aadb596ea2095737e366c421d395cd591dd3377210b3d9e0072f10a3da0c0ed3a0011b8fe0a9f837ed5315b90c929cb62efa573458228b234c18327b0fc4046abff3457475010c40ca0b8016184850c5afd73f6dfd93f79dcc3db759702f16265598275c713ecd56a6dd9b9b443e4d589b6ce12ada3d382cea197b40e133c73904ba7153e0eb7457a1c725adf835fc53e0eb7153e2d5bc851f00f518d644e143e1ef2dcf15126326c45134acc555be5c0fc0c292ab2514aa97b5de7ddaeeb2c57962523685a68b49e1e1aada7fab0c9d52b9d944e4ab94aebf9a1ae49d3d17152edf1c4db2304a63b4438eb0c9fa6628f8f275badedaef8238b0ecf0fa0203d3f379fba7baf8e1e1a68f4342dd9ffeb4e055284dcfdd487d780f2a8e0636a91657a81a994512e3103db132b5a538d328e5802882586aa80d112412d074cb218caf24397234fb43011035b185b5c535aee23cce467eae27cb8b876714194528e6b9755a930477fd246c5f32a8830477f170a66ca5f09e5beb3b0628ebd05ad71ba89972ada4b1edab45ee2def5430a4c368d46a3d1381e341a2d8cc1e57e52fb96f60e8e8961512d90d8410a335a3620a0092226ad928f18d148ff8003162d1b6e84d12a95a651a6e26d1cf1e6082283034da077223025f0a3052673149127130df5c463b2bc079fdcb94f2620072093390490c91cf949d60e0985fce42ab74812312b147fa8a96751e87961686d7824bbe7e8184b681cff1fbaf261ca726300f3668a25bc3080c9ea10a03221c7bc8940f77386317d86f35edbdda82327470ed0411e74b5ae8b5aadd6bcd6a84f8e3bc225e7eaba7a3153fe611c9151d3b8dd5abb623727c75dc9fe941b2265ff793acab3d66a6db28e7aa754bf64ff4b39570a3760b2d69a8e58a9742c0adc1fe6cf434ec847ea2529de7bb5e6467ee4359d1b8a94b964d2c6a6e6b55aabb55a51e447eebd7b9e27d65a2daa5db8d45ae5e21c773a9d6aad3a726aadd6ba1abed2b61e63369bcdfc3dfc8602837d813d3f12d7f350b3ef3731c164d7fae9adaa26708df747b227a6008527f64c47099e19d6b3990d7ae022a2d55454302c05b8862a9dc12f3d396f2028c6883a3a6072de00c004be71612294ddfbb94cfe0f5dc5bcdff0142376949be5666a22846d267fc717982e80cbd48b72b289356c2708c6f1b810eeefbe431d1d1dcff33acbc160b67a84e4314dccc88820e892015d96eb48e017825dd728005d0fb60e2838237792d76475edea7208062e40f2ee938c5e50217cff1cbe3f10577da14ca6b66bde30c1258c856aad3ae64d0e8f1e9f1f22f3a688111f5dae26710113020683611016935bc85353da08197837140abb32a80dabe290205760b28560340a9b2cd36479d9e9e9bf8b03bb35de1fe049990ff0a4a3f8aa9334957c05169b77761227c2e519fabb9f08c0dd93447848813b5bd01d04adb5dc0e2cf86612dc81e546f6f2e7811d2a607ac9ddd37bbad5bbefddfb2dcc7c45efd2eebbfbb72829a4ef97af48a44ee24c66c8c9b876ba60fae49cfdc347df810507e9294a213d8faf4862c3601763d8cc0bd3a08a0e491c6d61e5073b44c0081e6880050b961d50d18a81e1b2c6114b8c30a38c56cd0c0758e4b0c5892f64d0f27f2d787c8075c0603018cc84c30c733a9a4714070e8c57a71c5f17d9cca27f1a02ffd05796e4134592c66c221ffd4a0e4e5e5ed465094c36d1954681caeb8a8f4df8e84f8f58184253ddf98b42a14a2e199543000c937ee447140573d561ccd5090a7632af92ecd7d6f6a39972c7f8848a0126fd15c6f4345e9422c96e75a0400577141b34704d8ff7b3754cd6cc3732797222195b23e1a3ed26d6508e1321937e24c2407a4a57a5f17b1eff487e458727faeb1586fe7e1261ae3c0cef8872a10ff8de53d127fc5287bd8f7918488fc51ac2277d8c58430da05310047fb6c09949a81afa31d4c72391de0838fbaf670306d7f4907e66b25d0ebe7fe258f6932813a1975f7991447f1bd62880a34ca264a9b5524f267444261d0c165ba6c0620bacbbd229d9aff4cb5d0598f4a21c988f517ce4fc88e3eafb91af6ecd6d33735935695c927894a3afe4c2042d095a266992ecced5a6e52b2a2f56c5f097944c7a94ec4f51b41ada3d495f42fc96a958d3890ae0f295c9bae2aa5bc586bd28133f9a374fe08e72b4a50b2432e9b62d5d50c9fefec555ddd5fde5a3bf0d10f06dc604d93f4a3d4ac4c934e15841c064d31ed02d8fc79be6aa2a522a2a80cb32479932c9fda7c90a6782e64d8b1d05d6aedc39399d9740836f32009f903b7ff38b71625ef956ccbb725a314f06e0b26acccc6354b768454991f91894ebb664be87462ef014737cac75a8874aa8d91ab908a3d0a8946e561535756866002000410073140000180c0a0583017160482c1c2f2ef614000b658e448064389648a324897120849041c6384300000110012182da0601aff441fd71f53909abfc97e8822f5dd56e0e0728fe2bbae5d579081d8a501950948d2e5312e8becdb36a31ef7b6393516e81a4db310745827bb5e22c3c10ac6444e98dab61e2ec21e718bd06c95b507e76e068c09e15b9a6f7509d5997be5bd995669409296acb360ec8daa2931a3429200cf9fff8df4ddb819b0cb861c93581d2e64da04e8cdc8b4c57d242d555a11aab8da04169b4839cc4748716a8789a732a233b1ae7cda64f1df5e0600d0ab1290c803f92f619eaf11384151572c7823c48b1e231dfac005f52c6a13cc8b9037420bf3dafa021e1c5e9a3a9fcf9fa4be4a58fb7213e56ea98c7331a5f81c462718647da6eda4563ffb775ac375ca0091baf353753fa2b2f070295a160882c06cc1d55bd4761c680f66872d60d6ed52fdba0bfe43ad0c95c5e6b8c700482ba2fe9885425a0360d01cabc4431bd9fbaeaa5b4e4cba729cd0c224173972dfead9fb433450434036eefc52fcac30d21a268431fa7c2df7e4d054389062f897af32c4a0bea03ac417bae63ce0db068cc40fb817d609f0dcb82f9f57335c6dfa99e00713a5ea97ae4d01525c68e8fd34c768f24dc63d62f8174a694adec8c9204d8a10ab19755ce2c107728752c82d8810c45fde76ca8caaa20c6e3f345f300346e94bad8c5f3cfa3b3813c64c5116fb500c5765387e0e27230f8fbded1a310b67fbea3f8e9459351d46a97e7bd2c6725b30b8d6a16d71bca9d36574ee79a896175b7b0e51b6d6fce99c6109d16fb5702074e9e739eae785b7cf2e34276bba101186ec585fb8662151d399e4674be21cf47f0505975071215750d7a977d4673dd680f45a81e4f64241a67068c9772df3fa636fb43a57aef4bb948e390d4bf2cc391544d2bfc32be54481dc7d6e42bbfca8a85b4ab6302ba62f7198ab73ee06b0b1321c71b921de9614a2862328155a0f8fa0e1a908db76731d5fb6321bd16f85c4244a287493b68a56e3bbbb49f6af9160eb19b7d514512ae5fabc792bb033d48b264ae1091740cf24797ecb5c4c9220d60ae77d1f9810a9929a7aadd31f89c394d13ce50caa80f3f03b660d24d22bb60eeb9c68ffff7b7bffa6ad39d992d9555ae90510b069c0baaa5241a3d4dd18ddcd1595ab6e44de95f42f7ca7d1e103cc2420f48e9201c5e156f2d6048ea01e5d5451a72a6673cf55a83cd4b34187ad96ebc7d352d544e73e681ab2ea9b1bc6a1793b46c93c03c899e4ef61c55a9c0ac1b3d384765fb4a4b90a79dcd7287acbcf251940e087fa1767891acaa6a57446406b0f344c909961e30439f2b69071af98eda394336a6dfcd52104aa0d20db157d4d435e84f90f214d5da086bf4108ccf97fb9dfd45b0dda6b5404cb1379b454860caa34a749a0a59690d2b289c72f96c14114b31cd3646a6109bd29c445d28f18018c36058451ae1ecc2fe8e356cbbbf9d785ae87ace6f671223f81a0ec797e7080b0099baf0135b68fe807f7af28923aecccba6eb10287f7306535e87b9edd8eebd44e272c8b93b383155a3c711fdc2dbc4119e903817dd0667edd0a7cfc4f882a7b97161b4b87a1d023e7e0d55be31cd790533284775699d7926981d29820164508399d827f6cef2e81ba0ffd7570a91054a59c2d508a3479c521a08180020dbeff324c215a47a22fbefa66ba0a7c80bf1850b8607331c84f9b7b47164862eb4071c21f307f6cfe7f3498f5887c5ff170c13f00cb99227b91740462efad61700f54b1f739e7de53b73c0855f981a0d471fab1a24a194fad12e4ce3860580fa80d378804efd83e86c8c708fb4babe0ff4c88564340a15385483a7565a68b86b20ab9030145381b3caeb9879076bb3463870ca60e0e4b80e4b26a6399642e0442e8cec4f5a84cadba594cb8c26d0703832fafbadfedfd691855236de0dadec38d8bc7a9b5d1d2598f25b982ed0ccda5ed385361ec94a8ecc7e00d3f4136d06f0f98aa3c73c5cba3525d89d94b94b714b155ca5bab6923920bf8ec53bae47e2e51faeded2bfe55889bd9ca2a748869e69fa75f2acb602b136e6ca3c11f35a7de881d6cfbf40001d796ff789d4b7f9f3f608078f90cae895f54c9ca3a55c432e9fbbad3b3df725096ac3c6ecf233925ddf3abdd170cf6b762a72dc1a12174577e14282d05585d4787528bbe22ca678aa2c2dadeafa49958ea37f3d4717618fc1fdfaf59c6d31a717f446ccf1c3610877f3a021726bab2b4454c70b03448a19340f718b70d6ac55d71de2b741d97346bea96cc000f0f9dc80fe2063cad1dd47073ff3614ccb1c7ee485318691f27fac564b9a0073a3e66ec2cd61da10dadb0f8e6e5e40682fef700a81db9629f03751d89a4ac717c303e99dc897e374d4e5e11e2a46eb970a579a4a230f48edcf3e950b8c8e2f33d4c5e4adda2a0604b2e1953504cb90dfbe86afa2e9d15ba4d9b2d0dbef450aa193ff9660132e6e04097a0fefe33029671da916363cf1f62722325d3671022d95eec5b5d7bafc7608d473f6fd477468a33e7530f15d1912da2577b4b11cee21a57743cf52f61865fdc9dd5756b3d3c686e42c96fd5a9af6492afed09364f806e00fddd17d7017b7ffe383cb631903e3055e794ca0555c08bf19b3a06f459c613fb778bcb9bdc85bd62452b861f52e0731ef7f166670a397c730db4dae460a5b9c494fc98eb1bbf307b29df7ddbf3e25ff41d394f059b7429adcecd39ed492cccb7187335636710c43777fb0359854c4c003d028cdc5179ffd0c58acd7ad8de712fac0183da5aba9587d26a32e2241916d9cacd0e0b0f5487f499a0cbe7cbdc7e2f3ba342cdcefcb43a121709f96e4d7e19acea09e70daa2be35e5f6d8cb123a85a073c9e7e40bd8f658026321d70b4a41d3052a2b4d996e15c204d3060866e24d63db4a4940c9dcd664ec8b7e52ea4b9c8b4b8a529bec5171ae67c5f662a527ddc3e50b966fb0525c7979531e99f8197721658d6c870413d7936df591ebbca667efc0b45ac060a57bab1986906e3f32b56020c4ef63f6fde15d480d88fe42eb4cd730aea9aca445c7393f740cce7dd19aebefa32d653ae3165823436b688a64541eecf66c1a41b3904178d470e225ddc28fac4a8802ef6eaae518154b64b0525814da76449985526440b65209534f7a6f574b420771cadd3f4b3ac16e870c0e90a6c31f0ea04164808a4406dfe3b22547c9ba6b8bd51d522fed9644afe5f991af2055566aaba2af7627a44203e9d227a9b7d5f502f3db37579e51ff5f1e36c69718cff3b2db0dea43a1f64f5faf28c841f53d6ca2771003aaddb0590dfabeda1352d44532efb126e02477abd9506b56163c4eabb920c7239d43fc0bfe977f80cc623f943ac1be1c727f516ae759e28c31187181881ff96fa153369cdede95ce7880f36a944347aa0fff8d6568bfa2e86eccc787cbe0c62c39e855a8176a507fc51bab2cc961ef5fcb290ceb0decc0fb8f95dcf432fd036a0b4df8970d765fb01f590f08e8c7876b32d9fe3a17e1812952c3560465bd0b1d7ff0ab4019b227342b9310c492de8e2f419f6b8790769354e3f7ed4d9b021525b6781677ec3711affbca766b5ab411b6c8a616ba35e52bc5ed49db0d21b7d82d820549f8983e4657a65671b815e5c94c0ebd3faf75e29f9a02231454cd2a66c5fd3d15610e6feb1b2b312db699a42923ce469bded395f4adfc4d02c7c9cc00c1a043dbf6bc4f3b953cc37066b8a1207b6a95142eaad07bf6cf91d5b3e2fbe4054fb14c69532e05e767c6282b505a26b745026c09ce3d5113c08ed7c631a4393e7afccd4c4bd4bdc08c7a36c19278be7bd9d9006737c7ec9737b17bb19545b4ba1d6bcf524992f091f7f1b2652ca7cccc1e8c9930a3aaca40cd463f9a467be9996a5bebb7e758857f2266d02f81c084d7df93532aa14e1b968b87fc731ec0db1aa3dd415219cfd2bfaae31abb0944941f05a498924b99d51c8843196c786406ef8f3d4dbd62023f2688b3760a7e3ec6866993297b0cf1134fde4fbca8e52f9da51155af2ed38aa1fad4d86179b64cc5e31719b46d244f4af29bbe39a1ac10b1945e51e91f9f5c72b93ccd350b7a585d128be34d4d10c4ec9e41c9e298fe19eeb4d4e31a74818286bd864ca20d1d4b1414f14969cc9a62e444e6e915a0d5492153978e84e6eab3e7745bb4810063b9f0fc53a56c17e28a640f45a6cb610fd9be1c33fa1679fe7db9a6d3e1f41105885093dacdada650999096d90d5844d9146eb38fd0f7f31ef321ae862b8ee5acf5fb95fbef372ac0dfb1fd16c8f184571b556c64a59174ac73d15f0455c16070741c44002da3aa250d94603fc7f89b116783da36dd0e8b33c9f25f43d2bc47a80b41ef91b336ef07e1c7ff01e4cf82b0830c2466d56c3447166071247779f38a4ec4b80715b208c1c3d7e097ae484ff44849b86283f1558790bd81730e56f9e1ccd0230b4a04d38304c6342f094a0940ba6dccb05d0c2683d86512f092462303864f1469bf118bd89e399ee1f327288d6e2c9485c9aa4f9c338e9ee8b21298fff04d92ac3bd5594fd0dc98c15e3ee20a43b425ac701baa4be2869cef0436e6cabd5b8686ce2a8fc304c8527b7a40fb807d563a43d5b681814e54b8fc06bc31a73c6689291afd534249cfcaef348c16e11e636cb6a9e50c985bab44d9fb367fc7227ee17f073e894c101210d36fb4c1cb0937329503e9a73dc374c24a5e88b864da0fd8480a6270844ead5d7c2f46cc770d611ebfcd734bda6a44e73aa4c7444bbdc14a0014feb1b65c9199425a89a5bc82ab60c5de43c22b29ab9ab6397810c5e0fa10e937a882dee31c0a438bd7cc5eecc5d5cab4fa446bed1483464bfe9a193eb2319847d4869c3ac2f89b617818f6b26112078183a209f73d7813bdf04c137cafb250284d13eaf83a6c18a121d11f82ab958b6e76d804943735555671d4ebcfa32bd48555bd4f7bc5fd0e2d414c9daa0cfc0fe88380874bc1ed183b78f72b43f076a6648c59ce84239a962d00c1a28c9af2e2b9563d0ca80ffb5bc472e8004481573cfe07a8e9db6fe2071987ce33541e11a6736b6e0d6846be365b577500b674cdbde1f3e635f32d46c7c20b9e2ffaeec99793b56b9b7454975ba1f320e631beb2e0ac1b02156dad95d33ef2e8476968cdc4606f999da5c998a3dcb862bf7f09afce2d6bbe4c11d86170d65e839027d6690aa48fe43b4f80a7d72132c6ac4a4a39f0e9b75176f7291a45c9786d9d9ac9d08f541a93a5f66aae43aac4510b5dfe9309462c1e4e334ec9bda2182dcbf58d17c680eb59be0619c15a630e99937a1e0937851ee5a28ea1b2e3f8d223292d01d830b1f4cde2e1fd4a80ef65745c38121c6d01c52a2a0c08de1c508f77edc73013df13de498f243e0ea68a9b80fc99fb72862e0203aa83254ccf6102e0095d8504a14ad7e70eaa914474d38bc6c2f8b8d69a77040bc33a6e806cb9c221ffc36ff9b03b010224e6608b89851485e2d98f696fbead36ebb4730800bec31e6cd96e566bf40f1b706a7ca046e72338a8194e87a47771c4b50ffc493d32ca4209de82d7d468e8f14d84564f9fcaaee19316db0b8a603e0f7134ed271826de88bed53978e4072287caf2a20a6e42bbcf22e46607e36c0d8b7e855814b35a5c20f172827ad5ff11448a03af8131d685845c305931887c30770d1aaedd575cc52b4771516cb872384f8f891aa80004c9e08e8201dc768db3b953dc8afbed99d3395bf953a253d52a48eb634bc535726c73b71fd5176666279fd8449f6ccaef44f69b616623efc6aeb16c990161b81e665697c5b45bf687d4988f65de7c99f94bdca1d856b2bc7f9070409a02215d8f31e43c185677fb842fff153ef7c08d5b2c71ecbaea5d13e6fab98dcdc96b9ed14bec5356b0b86a1836e65ad79a59d46accb27302048aa702f9ca77e7cc1fdfd9068ad981b341b0d3b771875185a9725a1ce25f10c99bf0816278488cf8026aff5d0b496745b4e7b6841ab51f9726d7db74746126fb2cb403105be9c1a35862d78822a4bce646e9c495dc3edd41e9a07ef5c66a0583aa89f297a0d7500961cdf6fefc07b3b741b36759c0cfec5596427d1034e2edf70231eb8f842af5a243e5bb2cbed551dccb028a65e08d1b1a175f1e687fb70399c5fa9cb1d1527b509252b80a21a2d1bb4fcdfd4782ecb9e7d8b1c125440ec79dcd18358217811703b0cb832f8fdcf3958abda64d47282806a9030e5499047e4f74a61a2d2f39a82d349ab835c08244e55f3648b6e58b751b8f5c87c790bb4ee8e430718c87eb4ce5165ce0791309b81da4f37d7162f9153f150a1c9e42906529a6b539dc0a89093dba62a203990475311262265d10d8644332071dad2ea5af1bc0832426d1e521689906cf14caa4828ae43bc6c3aeea0ee137db2c469e1f9ba616fce7e7f774da176db20a2f1c017ed0eea8a27b7cd8c9e8d4b4c0c3d04e2e4c62288dc593fd7faad1262161ad54e33d8b30042e7ddeacf14059e586ccb736ecf9a53f5321283f394a52cfd18d24afedec7c34209bd17a30a1f6b7f2366e7473e1ac1d50b8e0183517c2926dd0b363b75d4a475ed7a91a54c9c0e8774223853a2ae77829fc3458edccb95ea4adf13d5e4935ca7f8349985bd3e88b2caafa81eaf277504641041b176bab7931e130b9335b8325514e80841d5e4531f06432e48730e5551528e0d6936100fca9e187a137ef692f5cffe9d57c5357f4d8029177b9f6ff05f78c78b44d64afbbf2e74afcc8c3d13fe0b0ab72994805a96373d4e7c586df359a05a0d4ca2145775c19c98c52cc9ce861014527c977b5f6588c5261a9ddb08d9143b95c21df38891f3c790bd586bc3bcf778c3b14a135f57aa3685b59c38f092f17616883319b2fced6d574005888023a8f3d3e9329b2b452612ff28e515a304be9195404ac12af392be139cd0fa181329472cef5abfa6850171c6304741c5017e094b8e473c2630ae7e5ca541f7c00a1ba8ff0eae6a428dc116e1d72d04e8a2f2aed1f55682edf100db790e19372aabfbe7d31182fa51d1b5bff2ff7cf7fcfcabb5ab4c4a5a0085bc94e66e80d95c2f7aad35330002969e417307ba5f10b4c7a26a384c8d8d783ccf2a4db66fe3449c2ac109a14d8d27445ae8ec5bc2c7829a445164f3c0a246c54df520b4d1d7d79020eeb6e8ea490d6d3105f93a3a6d9a5e5217386d4e7855a2dda31375cb52bef14b322d7c2a2056a483631d76d03c721112f42c6cf6daed1c3a21e493fd9921cbffd7d863ca6f178ea32630c811da91e54fdc3cb79d14f72868dece1fcd7c94d52f4a2167d877cc3d9d11a3c3d2fc98560119f10a8781f92b791e9e1660b1ebceef35f78edcd6e2e88725b74fa6cd06409cb5d853a8fb87dbee4e2d67d2dfd483c30f92a2e2eaed384fea69c13cef59168443ede089b5429c90d4342d20063d9bea55e548188080d8b522ae579a4f8314929cff7351c7c36e252f38aa3bc5f3d3390fd9c079fbf9122356204f77b6b5a20548518ed699ed8408c047913ebceddf34dfcd75cca4b2aae5f6454dc06d8237ca7cc04f8ecddecaf6ea695b67d4f9808e5b86162a7927878595a2f552449a636c07401d13136bdf88bccf7ef6e06c9df38d0978fe1db230b27a48c80916b35e0408cea46d373ed1e2468160f9cd9bf20ee5c61cd266d5c1ca22cecfb418aaefb6b12eded5fac022b26ea942836dff46556528ad6e243ac71bc1f2bd1636cd4e74a72e151c07a03b62507d06da6d786236c8077167fe9407c2863d33adceb23bcd5d7f2686f89da48747148c28a9c20cf06b8d0d6a9f5bd5e45d4dc9e65efe56b5a9309258cc1d9739297b01431133e5e49a85b72e2e62e053f8f3190764d9e98cf2ab6d03af862c2529ddfe3d4244385dec618f763b950346cdf467c5fdc22a65d9208e23872ce820d798f8b7c94e8b2d565e81fc780c8d93e321bb0778c18a93db860d3a3e3e2ef142520c1a6e818ea210d4aa7283a55f466309b27d0fe1dcce0af88ca6e4dfa721c86592f9e1deb83af760a4f2462ad287f8612157211e7878f96797e03f827405aa69f9ff4b7c2fc13cb61ddd4ba0293cdcfd577fc9abfe5cd9a523a737f2521bdbea468b7e772068e43ae326fb8a533e90a1a7bc07d196e1346ca8a5764ec48dc0b8fca3952cd5847fb485a5cd7045ce5dcf485d5058d2a18b74f21080c64bca07981a38135f94abbdea05cc75f0a077109969b53c5cc80428b2ce7cdd2b5141a3f9535013083d2e0bc954b580087575063647752b05f2801e2f88c0095ad96386581ac7c4191f526798128ee75da250e5b0b49689a572f4f18bb0349ce182c58af5f1cf035a8946cac883e4e97f6e1a771779eae857864d0aa220c6353e8303fc50c0ddb22eda72413734825a9c9d62e56d64a00b941cadd4ad584ed8ce96bfc68b92565f88cf577335fe4bc98e29b74135775dee2a9a6c01bc1702502b4c5a3dcba5104c67a7789b0fcd456212b21fa5afb2b78ed3c51789dd123f220dd32aae8122831fbd12188128399908a474384634a70469bd7baa679c2642e73544e239c631cceb8fff1d48999bfae0e7e00cfc0d1c49bec18c7893b5f4a35edf5d3a076256b8f3800179e73c1a4646942f759552212d22b58134fa97444602564b04f69cc4314e375d583c41878ca973d850464fcac393037158f27286fa35f9b5172e514c693e0d8260361f242a896b8b11394f3afd0d77d4c3d3b75d64c4b8f47817bb29e692c54388db6c2c6878f59d3b9b8b377e4ac2f687b38ae4d271fab45f491902210659d0000fc58844f9650109d2144309d12d32ea9769236dc4718b106833ef7977183fb37a5d7e871f6b0f9d2713264c96966abb33b570284597704981307044b0b929f90e421f084bfbfb3cfe3a284a516b229d6f911b20c12941794dd8a975b4a75ffdd00beab0e8b14408bb274467396b795b5b053a27c286c90b1aa7fe7ab350027488997a2c4092edea164c32bb25c1aa8ec9b73e6260689c5c97671df7c6896a961c19da6da805c80a8d55bfc8e9ea53456c75c80b46af1ea2543fccf194187fa1d5d006feb7befde346bbb926517130b8a4c81ed2fbe28b74bee8d4e6f9c5f6dbaa8afa851d89952d69bc2f28f3df4a545482618d1b961a104da9cec9595e674f81577694576c89952bbe06c2948da8721a33b6baf30ac74e7602a7f64c7b9c73872c3214a3c11efd76b6b5e41c4f34fa3a48d04ea46cc7f2ec98753802fa1a1edee7c16153cc104bcab44d4b0647e22593e448c5a436b04d6584e058a934978a0f149b003ccb0df25549e6a7a10996d095089308702d85426d287aea426064e1200fbef79653565ce3fbe1f3bd8675477a55746cca8fdc7973575e7b8d4c89105ed382ea5ea96c33dd74a5e7f1cc5638da02902802eb9d2aaccae3fd22013046e2729e06845939570ab9f6fe97a528a4a60b69308a565aab960db37460816dac7c77414d829325054502b14dd0cd4f771ef95dc259d2488c83a8bd3a250432b5147902fc6e0e30aeaba237b6a460cb98d5ad589ad5fde6beaa09f84f6c9336cbac751ca063a77de48b83c140d11ef55f727409acfd7a9f40461a228e441be329c734e12300f86af8c2d05c2fef1e7a0dfeb3cd4944f1bec33e9755aced141ae2bfcf12a4cc03bb44a45ade230df594d0b597ebec7a8eb88a77a7878ed34dfb7922e3609ab279c88abe527aa0e099d3ef5e809d2292585722cec2a9457314c4a1aca17b7e1ec3d35436a04c71816c22a443415550b3c5fbfe5578f986e045e66749053567c46ed7b4e1bccf82c759a80f905a2b4c47ba27dc217e43fc307d324bf1f94bf03d82bb1af307658068ffdc11cfef33801013dc10aa8162b25a5ec0c234789bc4df89fc1497f653f19601a2a704ef0bb2c914f30c322f180ae340c31f797294e7a9cf827d48b1c7b5340975a80598b1b157099978d1fa0bd524cde83a97988550f8d1002ef1033fbb169d2ac49bcbe7246d13b625d0575a679a06b1faa39d40a2a4e28853370a7cdae715f35f9321bf56c936d8f87d0c5e8a3384181aa25378c2a5c428d0f2238d4fe08db30b6ae42d971c5aaa1e531bf3b007a4b3daa2aaeb22b169c41639d9b0d224be4ef14137e4ead5a12f2e8dc31f3c759970c57b2bd4a201e9db3ecf47c0ca00988692d201c77d2a2e14e7030b78461526669405f1a109d855e466fa35640a229228bee4e839665f8c6641632a0399b3d2451f08a1176dd805120f5aa7e86e658822c99d17616e6dd59c230290fdf59dce57b078250e35906dd20dde060abb64863efe6d18ca30df530862e587772ca08fac2180dd20d87a060a088ade812c52e3d8e7fb58daa4079369a4bd220be90a93429db3e8c3bd760197b69a174811adf4a73f7bd9a5b74010b00a51697f483e3d63914a562e95e199afef403ed4cfa77c4e2abbf044bf6f29674ec3210212b1db5026ebe00402932f47971e5dea7bec61724702f04679cb6ea3917717bdc768e80353bc45f642d66502ce00fb6d8c27c2d807a5a9d8b0ddb73e42dd21c6ced053bcc3c3a489b53d284d494f91520163dc1bf769a5acb34268c86c2a8730480ba489d6545db76f48072119debc58acdab0f88b6f1b91ff10a6ddfbb63eef5c0ce76a0d53ee94dbeb70ce3ea1a8834742badbbf649a5e075b93113b5137fa61be694e705bc996c42350386837fa6228a041ce39519f68bd1d0ad2e925b769b5c673f5db043cc5cb1699d71b169015c29f68ee8cd1a9fa4bf36b2bddee1d99a57b9621229a9575132b3efd91c89888deb9918accf40c9596a01cd7a888ec5c15e6a2012b3eeed590545eae19c64ad26ffd18042df16b456b282a7e93dd0126f20e4eb97e04786f385aa5aec934d29464ed587a1a828980a64f4e083bbf4d0a6ed8e002c3ee82b9b0905c4e9c1062e309562e92ae00c9fa882e94f78a3c33e89092cfa988cbd59329487251a6f048141e085eee974f145f69780bdac54bf174fa9329c63c640d39510ffc405c96dd8032884eb81b6dd756a762e193eda3fb2b0e12184a067f6dfa9242cf123928284cdbf28cf20b8d5e1e10454e96cbf3428f6da2b1ef3cbfce513edd5f8c521930ac72172ef5d17ad57f3f5fb78b7c2bf17ee3acca1581aaca6d475d30e35ad69bd53043dfaba9aa6c4b05d4acacd62358c004aa1001fec32c949fc1c9b259333575d2a0b66711bd396a66b90e4a3105045352ab9fcbc9cb94fb0a026791f1db5980086af4f3bd873170f151b8dd34258baec180d97babdbdb75b6386c1b91ca383ea839be507140b1881797035143393b1cfad6ebe7ad99414395537af417ae90dc18833f913dd2bfc24290be3228b57c14f7ead0a3390961b506309aeeb3550dfcadb96737e6046c6ef81e227a68b77054bb84ccad995a9bec5afbe804ad850a1168845b2f9d2c85d467c729c3870ab1cd1af4d0bd0968ec9eb64d11bc1d963161abbde72aa8ea585a6473ea77ba9bf5429a47f71a1d46c00899d8bbfdfb7687e4e340691568d5aae2b8b1e891b997eabfe5f104707430bfe077a5271e7ccc4fee2e8852d1551df06c690bce79ef93b0ad9d0c631b5186f78f98a63d03d207f97598e3eb93086942e4719e8d32b4a6af24884df00344dec08b6bc51f8c951782c06f74932bdc254cab03b24e13a6cdcd7177b67378a6e925183bed3493e5d13113dd9ab12479010eae8db8c6286020fc0b91e0e8dd242a3548c2ecb4cca2f16b6a2d12d8ba82d0c40894f4276850f9ef54d852700bbc6320ab6659911bf2a57f544c61c8d872be8a55655571ddd5424ed2381bc0e534329c3529641ce777bcc38ef7704e211de3a26648506a6b766c00f2ca43be7d7d200d098495bf90a0cb5b3ef160507b5c5b568f3133d5b45f7401b415ff8ae25aa69d4f48693551c0ad04ef12d4e5d3aa50cbce4244181e8937a674c13ee3251c70f009883d082e1e8d0af4648003c5070a94292ac725e02a9fd85a09700b0bc7620b6f7e0758578209d64aa73ef4b44155eae7aa510c04587721abf46d645431ec24833f31eeb0baf8dca8fa5ccfa687a7b692642552a1e8ba1211450558d5138f9fa1698e3a9c088f0185945901543e609118ab9a6120f64878390d127cdad830c865343d45e04f2e46aaa34a9ab7c73c4c833235b068f5e7af78b77d3da14425e5075199a0613b56f3010f4d6620e07ecd25703284f932f38793321e3fc54605f21371d97a428e4b83bfda36d4f71e1b1c20f64e3390bb433c05cb289e507a129d2280f16fc13b2f1ef2d3db0373f5a18f199e55635d5c49db85cde06e911a89021f61816c980df7d393b40fa5e92b041fc7e4b607011cf23a82068a14368f7a79d3331df259c79b4a9d6827cf69527f493b15f44284c0e4126a05802102b80294a2c0e32687955a802920d7c711a0ebe7f8916788dd3db5835c7787e38e95cd3091edb02303889186446d00d92238f76dc73db786c6dd4f20f06ee661df6b854bc44c03b401f5b26d58d4981825d8f69bc07e1f11e117d3fb4d9e087215a1130c87e20f21b90aaa73b678dd06097b9f3964b5423eb5a9cef26f5ba50651396c2e027fb2454499010593999c4a6fb1072ca629c960448dbdd73910b7b16841e963e02b77d07999e28df255dbe9b19e4bd2ad372ea7fdfe258e53ab331c5c2ba00f956677212e4398f1a45c4d1875f612870da14dd9f3365902120c37c393a286d8990aac22b2119a219670635a34df430cab8b4d0fccd74b7d0b440c9b8ae20de5910859a2cbf91a95a410c38e69fabbaac6614b93d5c2e2b56b1a0cf72aa729999b1fba0ae0e2b801059378ba289753073964318eb573f0d32d175caf239508cbf073024e387dccc07c868c45baae0f9f7274004aa2b85cdd09c56ced4b35b9c4709745294566fad92f6954baa9e690e6ede5d843e131b11904a7ccfb4c3729eac528ffc3bcf83f2c3226db5b18f109214d7b50c86eefbbb1f6f2258f54b1fa9c8c5f3c3a1c575e2b4f60d032c1c96d24047d91b0ee90902162b40cbe4ab80126b77facd178980abf02ce59456b20c8f87aa3d018a311d1fa03fe3b521fe55a91c3008527ac878783902d8b2632a76d7e3de767f7896362f91da226e17c4828ba272c203fb519a4b135cca17c0e8e23ea3ac9510aa31998cbf616e7fdbd1bfb54b4550a4f9154d90ebb4d2e8f768774116a117373bd2e58762b1b256f8de5e7304181be72c5e125620ae92cea657399ac1488c2e75c0b02b63b4a4296150e743f273dee4c4da96a09905812015ef8f2a2adfaa3bc136265ebe859d2775eac5374a0e4c141bf583c7e6fc1f9698821286efa60eda19a5f2fcd4d158c90368d6d0e85360991bd23467b7721ba3e66e8e980aacb73eb32e82b814acbad88c7d221583470917e7acbe631f4fa750e6670a056cdd0169ca24bca6cde524d43d7da51e03be458e83ad22ae2ea8f9d041dd997d5edbe0dce52455f25cfb82f9be508f7063b9234d1eb571b5c9dd77bb3943782a6b00537fcaff6a57bb357710485b766976f052c4e803378eaacc0643193c9a840f709415ab7acea4afaf007a88b97a8fda5ed83e8c1fa3a844c0314369e1aeb7fbbf813ba2f0644801daf0b578dd500c23fb4e2d7c062258661d4364bd79ed0168af9bfbfc054be073201833c730634f857f03b367dec3038fc6f0d94bef6d628a287b37d6c046fb847eb41118df1da52b15ea58efb79e7e10b9a6a5f0445605bab0c61ff273d3b9a42f86b1635536f10886501709da3db4c4ca29e0648edd6691645d8494161f3d7665d0cf00db2a213d21ada802537708abf5e9941e073fd10f4391024b3b6c1a45fc0268e3ea03ae473b6f8810adae884259dbdd796cad31f4287cee567410fbd112e5e20b66560ebf25c2d8f2b0a8ec68a8a8925862c761a5e524d9483e985258f63148b0e02706df70f75207425a7cf9a5636a05417b224559469ad44ac6d21861fec0cf2b00a57291f55e0b69d330ee1e2cab623e69e65690409b8dd6c42d0340a95832a0502bba0c5d362f8312f9a63da035f40287907790b74e26657e5a721b54df46b8425aaf7e8208106464160029760b8a4f5a840650c4f3f3c3bc92a07b2f49aa671a333e9ff4ec1bc8a866ef6e6b64800cda089dee60539c2dd60617bb843785c0fe565a10fb0331346808283f215220b596f13194296a57973037ed8181e569a1e867b37f87097a7a9b08d40a4b965258cd8eda3be71542a7ca86e6410c23de93a80375156bb01d897868d3f6f4528c6991d1663e9457eae3f95fa1bf2f21d9f5f8bafc135a42d2633c51dadd794ed0c262ace8b29b30d3597b499e9cb7c71f4990ebdfe723758d7ea029c0b8b4712b696d97d386b14bc6ea4acb7fc801a04cb038fa570c57b79e8426c3ffb78e36dee74cf323a747020c81ad21abab04909ab51003c2b9d90ca8a9578f15b6ca106c07bac5dc2776b87f26028ab48ec47b244d8a88661856029b273e99cf3e3883b002768dc5b0949e1bdee5a2757a5d60a1c3625a012a83b1106de08f220a27db259d20f9087bc0eda99a52480423d8e75b848e90daa310bea3087b9bc679ac23c953d18cdbfd23d9e0f5aa09644060ae5a1f43fd096086368394dcea4c37a09c3b908ea3677f1e96ebd5ecde584beb46506518c7aa279ef8c2b7caab72174f2ac8379a86b15238df94ed5ae6ee49ac70e65ea93b4e97815850c361175a0f8b460c54429815c36a37ec69774d7307613ee97682317c9b7626895577d1f064c27d75cc60edfdf09fb061d8db414cd4e504d4752cc3c6643b40dead87a7de8eb72daa975a820c689272ebe12c03929bcdd388ce3dd32a9f92339dac062e757801f11442e2597a16a605ad04a4092fadc82daa871c558b59ea2cdd043c9d745ae41b13c30ed14bfcb147705fb3332241ca3587fae0b6436778a829c4e3b59955d1a46ea33dff86a26bec133898ea969ffc168b3abcbe40901258da88e6da637ee06c1328527bdedb6bc754455bc2b801d141e802d07ad5291c20f0410d7bce1a258dec0b163129218eaf12fcd028b8d83d922e9b7ecf401439d13168eefd649320426f91fbc8a705946c48199d15755d29ee02f3f1d979a64998d833fe7d03976f8923912dea24fda65c9fa0fd943ce36226567c3c9a3771eef253b1b6ea21b48a964c1286b3bb5ba8cbe07c02996a7e8442d9d9fa2cd7b1b66e42ad369703843adec0fece6a42e582b69a5ba105cfb7f0e374171c8db57c4ea6b6448fc8ac63635693174037ecf32abf826c743329bfac10e8be2bffde6641c1f6163fce54eaa0e16226dcd7e1392132ad3112a81c48c5b7bdbab1523670296759a648314147954536af143c0706d43bd338099506c6f59d6b5f6844f9a39ec304e48097413abd4e314286774ceb2978f3daacf05e923d8e053b213b662de7fba2691dec42b2c9890173a53be862562b0dbf32e8ef436275a9b436f344131501d60e7db9eddf484191e38f1691edbd64fa69b755fd513f96de3dd3cf57a4fe10a851d544f61f7fd9174fe4a1f46eec5b7f2b83af6246d16ef4f37ed57fc619805213a48f8922ee134567543f3610673e07cba24cce0c31bbd46a5ac669a1345bd4816bffc6fa01bd8af39ce21743877f12f630372a24ceb71a0321ceb93217b47e5b003ff0e285250d2b3968289b87bd936e53043418d5855e4fea7269595ebea2801ae10bc350201b3a90db9fdcd36c102dea4461811aaaeec760be7dff99ec06bc3bf6ca06c6ea91da23ddf0b93528270a81cd1994fbffa810d74c674446152e0e5bb91af12295a72d73016f1bc470942345dcf05385669bf07505a232e95fef7bb905731e80e7ae21e4c9e98e2da55993802a81be73a74842d75afcee045a38cb40184389aa0a42cfcb537f7c25acfcf3e47461e97f78036770240348213dba2047ac9cfb638b7c2f35ec4717ead5764bd404083ed60bce3aa87513e080a67cf5aaf9f491f5aba323476fbaa8082dca66ba5c019a7c75b02dd6742f9affbe06daf45ad57876ac6157391d28ba38f6866635dc0ffb4013e24405b1ae104b273297a795b5a0d52f174f0e505d1f085764ee40b09fb76ae9537a4650df2622e1c08b6e83eea3725605315660c1b009658b0ac5d38243823741d73c316db324b911173d9d751f25c0ec141b8d7d4d6076b4eb60b37ae1a78619b096d416643089954df431f2d65a124e543930d0d3ed959184a9e18b0e59c35fcb5bb14263808f08fd5b40a470355ccbe2872e5ad570e6083b5ba3dec84096fc22416209cb5410fd1cc4da164fdb6510bbc830dd8a82b7d2ed03ae4a052da2a00a138e57edca0e0d05a2086393a2540b9c8ec8f5708fb4a49c0d0422b10a60cc6eedbd121cf867e1086e0cdec9eeed8584e744f02142505befd5ed15b841bf691e86a623097d64e62e59bf7be9b2e507d7773ea3ea0ec2c5f3462a9952059107b6102e34f46586fa50b7bad6af7132492653e7ece06e007b76df77b8386308f5cc10d9ede1c1323c9363ee9b0525872919a568db288fc9fc7e0255fac584d5716e981f85d4f83f29d7220ddda85d2f6d5d09e901e2adeec8b9494338780b56ebb7f91aef5eb121c1ef5b3ce4673416dd645037e578b16b29676cbab3ac3ba392effabdabecc12a6a7504043c6dde753583d7813dc2268e5673177baa903182d2ac1e949fdc62dc9561401f47616229673d00e6eed800d7ce30968f45e8158607a2e80447183dd6c50d2d9f8ca79904cd8879eb3288f9ab1a4b23df012a0c489dc3410bb132b105efae1f759c58d4eb0399bbf77f81b44659531d53de7c71c00f17aa13160e94c90d3a9477f350d75cf9e1e3357d61d5324c54600e64d33c6600509a9ee0f6fb3bfe3b142988f8e64730857c821090e1bf80cedf2d7eeda8d689ff62f500a7b06c41e080d8914c648e46ee3fd767312def8db8895aa0502a707e7f71b0acc0f31a2e507c798ec829d497d2191403edceb0adec700b86e828fe9ccae239c26e415906e78a6e7b92c08010175ee135c0ed252adb9cbf062d0e37ab9b480a574ee4a3f41aa878f1f208ac9b8129edf7c0d6ee5b2a27375ac6425571c5b6919a52aff57df7b4ab4397e7626b17116bf65574dc322e0afdcc61dd8091c882567425c9f7c2658e8f8ba860d12282cf7e385b354a2ce1b3eac7b6e07bdcd80e2c272d69399d5f54380a917615b33501cb5142e7d236cc687167cc2d74f24a7dabe53d4a3a596bcc997a2fee99dc2769e57f907bea2d3c90eb5ccd85503a13ebfaf54550c018406439e96fe59ed80a168a5a041ad425f4fe58a31f66b41ea214bed856cc02bd15178e3f044912b5445b3560d5d92313a8d6fcef0506092215fd95d89edd8fc777300a1fdd2c258dc6023c0ba5f5c72879152ca7126ead167cae98bc74fcc18ac7a72662d8bdf5f824e722b2019edec5a25d72e3ee9ede757d81e4de073bea0a9b47e72fed1679fdbc843b0683503eb0769c25b4d1a71839cf58c2522c4e30a0127798b5201d14616d1f2093ecd4196ef4cfab3b7814d960d063541c3954a9d501e9fd1f276094f6f7bf11103fac3dcdbcc09591b78e9934f3361c584badb39c63ff4e37f96cab7aff5395b9acadb3aaf856cc8ffe6e2dc388943c3123db5233a212578ccdb65e6872c03587eb93db429f3a199becfc8138bfb018037d8338ff2fa2fadbd6c11008d99bd4288ab4d31f2e1228cc4d2b60be9f726ca37724038be9f6534b408cb0c4e94e8b47ba302508d005e53d9adcd6a0148542bea1a6977226d8a0b4d1ce7e8441b5c6ebc6de9841061dac6706082e660683137c29617fe3a71504aaecf37bbd25c540f771058853f13850b4534610e3a127da9c85b0ebd6e0840fb141e0c03bd2ba466144bdad8585047b71c551e1315d79a0b70b95982d7655311d9e2bd110958539da3fc29603ed8b43a40b48e5ab5cf4fc2a72af9be0e426c027a533d4ccb27d8674d92715b01da4e4443c84f82e7a9847eef31dcb81db2af502bae887c8e41d6e73132f9157d7682ec458381df59f45a64c7d4586b6e60c01eb4467b13b848e5aa24699aff0f1053d1b62dcd8a23a12ca2501932a7dfa7eede1361774c342f0b88f51dce4ced317e0f20b1e4dc9d5cf9a7d7f9269a957a3f739d8c7c648fb7d999ebe2bc0c36239f35f1377e4a295c6254a0817b864d7f4c78fccfb6db1f06f3c0d1cfd3fdafb768d632e994d230e125a07214dd959c022be824a78ce2fede0cde50906e40cc0e648b9635a125d27d026c364276e901a2db81116162a6465cb5d96bf0bb8d278aec0acf2b268f68078beb289e82aabc8f5f96d3df44c84dae31ee74a2ef95fff9d5e6502b510f48a0e8afb6f56624a373f919119ab42100cbaed9c627f1984b7a7d6e35c0401568e6620afe9a97946fdefe4aa3037c1ad096ece6efa493f7ab0c77c7855ad7ffa7283e782201d37fb0b9ab56832e71bd4357a537d412347a5d971fe9a4a83bf5fecdc26464a2cbdb75b9ffcc204028f98c3dc8f4f0677cb64d562c01b945c498823dc8e4af53d1add1a20e5dbbaa679dc677cd3d989f911617dedd2233c374f2af8865b538be72ee44b27073e6c789fbe24247215961ff3458b0a5b1dc74a7240ae1445f33a76389f250070b373f65f8b4d3dfce1d2b3785c6f0c7583a94d9643aa09272755bc980cf030df2982eaf3a23f6b233987e01dff89954fccbeec56d3784318b9d40e6fb3ae4c5e8a94b3c5d610372b3b400310e22c78e11175f5c7410fa0c6e3ba1da6036af590e4a8b1c2b8214a8ab217c28d93dcec434e8f11110870ee2e3644be9b8ab6915100e71b569dfedc65b6abe5ffdca3877ef085c5690b716175f79f68c0e81f6f2c257653e2008df070c2958beba87b44f972abc08c73004ab52a9921810f71c7b7d4acb8ee0c9653780aaff95956fdeb299a9eaa05a0b297b947c2d443f444e60c3fef1a2d62845cc3679ac796d80b16b443fd7343f50f4ca63e722094190bb1040afc60ded123deaf2fc913f98eefdc98922f25595298c48f3a693ad32308d08f747150936b001c7b2d5a7a9d1e4c9ba759b7ae8f24a94b53805550ba2b4c8839f1622418afa15706e654e2ecb77e31b14d27b83604694a1c39b180691121b101b2fc94bf45be60a9b41a279e0e5d01719f5aebb59b35234d4e514ad560e3fbf44a05c942b9904c6d1ff0c1ed03711cf3dfd53a36415e5310e2e111840e0bbad112b3089c81f2fa19e0d8d06a81c046937702d8203d3bf31cfd69fc776d7257e4211db113f07eb565a16b1c247cd34f6d12bb0e61973821dd2fbb76aeea008ddb5bac0d0194a2d5bca43b1324270f4abb6436a7f925650b03cc7b65d2db2bd159c7d6a4ec0af818992920717bb311f69473866b2141723a290eb28fa4eafb44dcda20ff2ab08a17093111051e589b891559e8e14f8a721089045b24f434379f14d0cb2bc1d669cc1b8b8054e3103f0e7e544e93b2e1854cb33010eccc9300e58f40f7e6ea05944766f20385751a1c47ae9b516f87d6236a9f3e57492dab6717ed77bc9d3d25631a7655d9c1f5b2db8480beeb89677ce44989788bb1944409c1d3e718d234cef5df9229f5e6c7e69b45d3e21d7c62da3fa8f782506fa28989ce28b89c114d0e6cd1f496fc3c134cfd57dbae06dd735b53d3cf57ec83310b1c24bc95e34250d90d2f55231f3586fca24c4c97416fa3a2be5e600c9a631d143f20edaf3ea5849bb40e5a0911adc0a295d0424a46da378f5f8a771b7e45bfa48605169003924ef597da295760ca93229508b90b46d6182215ae0c0047658c46ac4e844cba031c9a01c7df20dca609229a2f6f8ec43a644755cb47109012905f1d237f2525c6338c26f1035fd4b384438e1b2bb9d4f1ce2de2e73722c24b3fd9e623b7f4856eb42ce1f58d3bae6db1724e6571a88596771dfef9c9448f48fbe4b65023e8bf735bcff4113bf87c2a1d93a15a44076a08578f51d46f1762559f257e7100956ae7a24df25e3571ccb857492b26d89425b37c26b087d0da5e4fb96660e1f97cd5662c80a39303f880c38beb398c68a172208fca65a1aeb8179c1a103160d49c45d8cba3f1911f174bff9a5c926361cb072481b59bcb11b0ede0daf04e066f4ac3d4303d08e28667d4b473516d947a1d560b59ac2ec9dca9b35774b1079d5ac1065c51f6a5f53a015354ffc995f3cdca7ef6fee4d282c70503c2ff5481b89937207d263192c0e784e44b2387e552456bd6fed29dbf996c57bdebb4d441c3c7bd58dffe9b0fd78436696d03c0402c2e203376719c55e85b81e117a19cc3624285132021b2b6e3a52cc98763b3eb4897c88a2bdc2dfcc73a43aff24ded2ec836d1cc3292f64ec26ec8e96f1241a8f83368b6e977719fd5ba8010cd5049c380f8caff05c08a37ed2951a9408bce2f2eb2eaaccb24871ad00a69f92564241325dcf3ce29f1b57185d4e8769396512c93b0bc54dfc87752fb2fdb1a6102278551f7d23e1f20095336435ac0cdd721666f754c13f6127b0e1742e1131550e8a320cbf1e7a45737fb24acd1870ee77b7d95285d8a57f4e8bcdcdd7aeeeb2c4930f7becc945577bfb7d71b3324646789af40c9c022d216448fe97bfca1892f6830fccb3bdefdf39505c2e6499b0c63145eb539bb05779b1e743b83e5347e77bab33554f53b179c58c7d08d54f5d2b991702cf02723def8610031297ed77d2002e5e197a00331ff78b36f1af795369fc2d508c145abd98dd092e6a161de4e0e46524c69a52b612d483a62fb2ff11931f1ffc00d1f28c387f31e0ed1c6cd26dce8379e6dc8fde452cef463592f3f5e490df3327838a78cc8361a216d1078b8565d039fe39dbff331351fc062a28deb8290ce17b0c9cf7783c626b3da1b650e7f326452901de6b505db7b782915cb57e30cc095703646e1a51f61f2455b3db62135a74c62da351a2b5f4d90bf280fec5519811142af2bc6bbb7861b3e0e8ad8d7eb8a6bc6a31770d6a1c1600490034d58c6a0c5fe2ddb6fdc2224f88733f37a60f14542ad74323cffc10eeeb169a549a21a66798b37af016c2d14ac9f4d181f6318911103cef69c5a7264bb86dea46e4c109e37ace9982ad10a084581ba864956a539474b432f966d81ae52fb1a668136c357d20978dd55169742734c81bc4a5e589022a3b4d28ced6e5aa14faa50dde8118a87593d9092f223eb2c165d6e8460667b92b0c12ba48d8204dc4882da7f4b156e985af5d00a0f01902c6a78c62994ad7d74172f49f850a61ae5ff7c14b8663db6bc0b5521866e5e070192de4f325cedfdfa1864c1d246ded01ac0cb35a528ae8c4b6d3435a0a80223aba5bd0bf44ea570f78c8f6e46224a6453e178054f887337af41373d48f8bf5055f6ce84ef8b303c05dc99388605036e775b5d90d5a56b21837c5850bb69c9eec4db03b9d58afc771fb61d1b7c1efaac41f1085cdf1197985c86ec4711f22efd2976647129fcd05998318ed62de2a1c4ee97db84446ead270afc065545b6525510ab906bcb8801d441b483e1997270df21b6713863302513194b84939d312733405b43502631250d3201783101014cd605230bbf261057e44fd5b09b5e62d500d596380f5a77b9eca04df14489d1108f3302095b4efa7ea510c53ca7982085d34ea39b82cf56d8712c045d3450ef8e756f18056a38d82a8a051d1b271f13057b544620f73d39d72b27bb1dc28ef367a852319fc44011d4df278a65d2667e1882f08aa0e52a5f45d1aea0c1f78d239174e7e355d1328919d2e63f075ff1b56430a1ef21705646e0699ceb621146610529952fe34b215ad0b7c3417e8a5ae901afd1c55ac01b6621a817ba58bc4f4cf628c49e75ecbecdea1fcc6c4a4a247039ee493ca2745778e5345f9757a520338bf6a6105b488066711e2dc3b866f3e81428803f09a5bf80bd657fd45bbab5985a222763db19806b817803fb87172112a945770321b8e67bca988217c1e515abd7af4d4faa3540ff9417e670f7e0989eac2dba21daeff6829409f6977dc8befbaae63ff3e77e5ab0e1f57dfcc8d4f962b2eb8b47e9fb026c1264c87c1cec001720b6e50dd5258f91744663a21eea3ddda3d325c8ec7a62e765d8a6cf3c9203ac79bc45f84a8baa915af82a3ce9879efa21f81af3c8c2caf523485a83447dd5d4a2f3e0f24542d9be081a8078c65ad1a3ae45ff737d4eb80be5c6d13779d09a39253dab6d98c9f01a5aa0d526ec55886a0ddc8dbf921cd0035826914098e73ab5d855bde1bd677360a824c6c96d5d4564619e6aed365424d4c4d7a326b335fadfced92a7e342faf00021c34537668f59cbbac89a4d788aeb6dacadd083ec6d0cd6be5f69fec07e9dc16f237f75660b17713bb62e2380b0f14312452038086674ce5403e3b96d46cf8f186ed11ff3bebbbff11eb96658eeaeee3c208ddb69239832bf42bbc39c8135d317ea392d4d67b6e2d51940d331c2c84bf5037d51a09158c6f01614c2ca09b5af45251ceaf8f17b6f4c36f325d8c91051d5bb6bb3effacf5ab865b057384c81573854a5abc3eba2d71f1312a53e49f204bca80747d0822900fe583a3893c4e3097f64579f5d0d0e4e33ff28d62dacbd1b07fa0e4d4b3c8b7040524c8f5cea2d1256c17394cfe804aa7b8b92681c88bc36b87f07f888603a67d6fd051801c829c2ebfb1f94aa86ee58372db262ed82caf006e99e07dac7af5f340cbeda647a2dda00c367b08f377436be584da8876585cb53f55edc8f7d7acf25b876a20fa31f0043f0bac5a192a45d8f005be1222663200aa80174ba3fc24cb9575d350311056ee449a70a06eb9fac3cc96d2b57651980486b7f6e4f9769d7413162cb095ff77f6b039ac1640c0e63601f4981b221cc17295cf4473c6308b73e36b82bfff3238a3f8e21c42da42e08e6f11e2db754c9095041b3edf9d0bf52fb6e9fea4e242f01916e383c9b682ded23eaa254882920d0f62bd6d14fc9302a899fc9558a8e83003af1c76c455e391d25615824536a43cc07df677951b145b960bb2f3478d9c7bf3586603046854bd238dda479afce95207958e3150d396cd3fb31d16ab77005082a63b204c76299a8285d90057929f09dccad46176c138754d8126501e5396e8576affbb27e7172a2edad4751be2fbeb7cd3e5d436e325ffa7666838f8dc714ce72005bc7d9d9a5759412250bdce0d29c6ccaabc03f5e8cd5af83299bd4fe6a81875c1ea73eb43c57a7e81b1d501f022afa0bbd81ad232a183b2342534e1405ec64ffcb448d1bf09e2eb6dc0f1e89c4c1b9082aeaf371d79d42b2a0c52b28b157a9c0f4476d9526c41c0579028c3d93a3f28a197ffe807efca94999578cbc08236998b1c319a25d34d8593cc09a645ad71d87889f7797fb5a4189597095680ce756494ee2704886e3a68871483ece3cfa2f6626408d9e3e8f46da865a4558ff487d5d4d881fa5bcb09252eb84b51960d4ec8c6c9f7d26a12f0820507e0f421c377d68c6ba11e6cfbbccddc3295f0a29a4a300486e0d4dad846cd40d81b8088011888b4596e88bf684b54a42c6fcee4a180e67702403932cfdef75a6ad7e6c6b9d1226a67a7db8c393aec86fc39033add0ac1087a0e1279fbdb326a4d01a6dfa8da2f18dbb5cdb2f94d83084f5b2a3e9943a40cf5e6d486504f0ddcd246e3387bfb3df84fae99fc2212fddc11dfa573cb949b113f27e49f3bba4a675d0c724bb05e65bb844bb41944f30ec48936fc78edf61e344c7621b9f82253c667a023a462ecabe2b565777d3468434b935226c6b405af65fe18b94796ef7206499403c9f129126a9fcea154087ba1507d790957b459eed65c669418f29ae954e2c4179059efd316848dea1b41ecf5bd7368a4e50dc44babd153cd5d4a20954c0b9e2cae88eb73f97569ac535926ac750ed62046899f6e999e8b2064034ff97f9b032801dff2352713ac393aa2b48b8b2c210a912bcd72f9d64ba1bc7a44f1198722a45a62161ba3f5490f9f45205a057ece4d2d39bf1aac172e32d46ccf5157c9bb6ed538260c081477d894d482779645ca6bf85c2cdf012e2a0d5b2d51a01dd20cebd5fbdbe893a8547c34cdf20a5971e5bc858f0fe1b8bdb930289743fdf5a8b0148b5a8a225835286e655f03bc149ad5475258d5f6965853e0d30d3a820cea9c1b2594920640b51cf991eea8eeb4864424629548fed94c54799b8e3b680c4dff61c85185df81e08d057298ed544542a0236ba0ad1246c1c01686458324d59b49257c6949cfef0f4cc10c0059aa16c0617aecf5cff1590e699abf940e9ca5f1f5c0d2a889c8582cbfa795827343428f22ad24f9ada4a6ad1434aaf167f57843537b138cd66b73292a7f9995e4daae5e8a30eaa1c449b2ca972759c5281abe0fe5762e81df80f51aed0daf0a806b813b267cc3da93210ad560bb4b6fe26b0765d919c4b57c4d18b110654129c3b4b9da309d284a1efc515d3ce46b28804d6351b56276b41ddda0dcfb1beee0620c48617d809bf803587f5d7a3e40b458f20778dcb962964e1716262e655ae42abd36aa57a937eec3564c2315277f2e97a95683b5ea58d53328335f0402457f1d0f335dbf87e1b707a9514c7c5bdf18aecbf0994407bec27347fd491cb4eb001a79a4f33df6ee5ce432cb5fd086b06b17c3228c5d821008ae43c6c054aeabfada6c519d95e399ebd0807ed8652ec107fa2bbf4e0e24628e6d3c5665d993a3883c4061042fa1750f71d70f67e5ee5fb823c78c779b119815cd3d15619a8898ca778845c108ae253bc400b8a9cf0011c0c5700f4c6c23005a11bc6c0d4c83532e281ea21012401a1aacfa73c00f0107323eef80d1891fe2f3e4e36b12208bdb40eb2751fc2a63e5ed27dc3f7a366356837519cd09dec29fb644c0d55f239b14ee9609f52e34cd2907b97ada44d26dac64b996d38550bb94ed9dc5a2472465e5033de7337376d8a75d41814689dd8e5ba5c4c7ec6612158ef39adee6ecee608ed708f2c71a793a38e5cc620067a4de7af438a063ffa48685b637f56e8c5626b38c43016491e6596e16d03cb09c8264256b8a1c2a6c7a982b31bb45c89e1db5dbf6cca59c4fb488d9eb8347d372507790c00891621dedb30ec7d2d3b078871add1ed5f633482dfe2653d09485cec59695c1a367b97b43ef94ea43b35d1fb2da7d69f883e93acc0bd0ce9bfbaaaa9c18d8e7ebeb67e4cafa5533c3e5bff4a7eaf435d05b9e5b53b6e8b6538c26ee02ed353cbff75f111abfbc61da561eb28ef738b810216929b059eb41908c48d086a5e0a55d58898873cac6d3327a3ac1ccd57bea3cef5a11e423e4510f5c08a5af9f383743f4dd2c7d27c82bdb494498e293de77362c54aae4ed8fe17e1438a6e01de67ba103efba19a33e4a502cd7ab0fc3bb847f9cdcaaf5ac14355a53ad67063e44425e5d96cd0b22e142bc312efa937f1a3cf25ab1820edca2e227990b63c3cc8d955f07badb088c47ba2e268052a86c7f27507c4767fc4a54f278fdbfe5cb61cacf1050aa519f69dc27b1e4826c8ad0bfaa2c025a01b26be5862dd12962142630ae414214c0c82f7e8027937a74739424daa1dd7df54b02bc0c83cd4441c34978646cd9c4851f3288471e0d1f052f5e4bc4aa2d2c3e83e9be682e0556cf6357019d65b7f696f42518a7ecc3c5802b84ed07ed9e950897fdb5fd5d2b28261d90030456b35357e399378d612cd9f6b82d11968b9af52159572ed48e04d76473f76242009a847c970d4544671ccecd258c611d09898b0765f3a045d41a94c796f15469b84c230a9a9bade513914ce448ef64c7438cb429cb9a42f5f06ca7236a677fce534550665338f6a800d445d25fb9c0c16f4a1081a1da2d8808523669eac7d96803be6625628ce0efde99a6513b053d892b11b71e86f8483ebb40c3b26e4b0439f3cbd67028579219a37e5110197b8cc2b127a00e1ffc1696fa667ba6976bd8453b949e3ee97e16767cf5efe4626fc80a5ab74a86b525b7347f21ae38c44a95d5d46360ff4dc45427521f5993d2b3269ea95f05302a27c9f41f0426001e90e4085f2b011bac97df9df5090ec8833f9ab6500ef93f506e14c248df6d51f6321476f63d77439151965c8ef227cf20a0f93c9ca0c9f81cafc6c681ff32752f865b024fa9bbbbe18bac7ba797bdf00d19d8cd189a1de7a49a9cf3fb2dc72889257e7eb38fc987f5f4a13d6402e43d8249b98524a07d159972dd7ae750bdbd4b170a26d139e3fba6647729ad59e2896ce899ca1f1eec899d9431d13c5db9fa401136f086c7059670323878374a017f4774f04036d7c0b737680784edf6afaeee4fe89a57d67fb23388a58353e4085bb483d68ffc8578bce7d212dd4287d80b543ce534a7a2f92e5986d43834f01590b873f5ba4cd835161ad495da01e4a3f68c932102c91d136fb2b1eb4774c415e2af486a1f2b429370435af37c091b3e4d16395830cf7269554cf38e4099edaf9bac3b4cc217fbb898f97e9ae147c4a338517ebc20e04b955f0d8651438f37d0a1812e0ff4ba3c9405c980d4078111db908cc5fc9a95e337aae707680678ab002f1942c7e9a67aaed7a9156108f49073d156dc62b0ee33753f9d6c3890a730d7d6382256b516a1fb95db31a3c7479a549e29f23f1e728db434c106ed5d180842a82f79cc55e1c603884999937feede03f99df10477482064c9ffbdb27d0a35405831ddc1b7b1ffca7a8b68f54db066f2ecbf79c1f44cab7448c5fecfb9461198b41d9ad4470a5345fa4138287d84a1246d6f9a59bf00218bf61c0e03259699e6df3e559c884386ee5aee7f7baa7c10208b195dcca7e83c1d48bf6fae748bc711f069a14886be70da980c4a12ca5150c043bd679ffda45057c292c131c0d1677af7f71a03230be7f76910c652be28aaeb789370ec54ca41131bfb59f54871e48302fcd9c75f400cc01a078c075c84a80587a59f910aec6e5e7167110d1ef6a094e6a851791150660b05625aa335ee6031bcdeccf2f6b858ab2d530dd10fe5e7220adecbb54c738a6fbe110903d1c106552445c034f260cd1b2d412d1ef2fae92528a9799d98dd825136e71bd721e1547a1fa734ccc77d3cce42781db54979dd463d678e83ca0e41b542d10f6df49a3a256d864fc372034d5001bcfba2f26bdf0b0122f50f2b5e6bbd6dc122720b03a82d8f61a48e2d0810400b9d4a13148ce3d0c4719cbc02f80adf71a136be9fb4cc5612f52806b5ade5e6daa04f95e2e97e3f2b25b37fa5d2fe461369ab041980b2b04229a1ab9c254851901ad8c83dee917a46c389c6474810373718d02d36f7780c974cf32013b2a295ba25728e077b4847d4983919f5ce7600421f8dbeab8312dc1e97629fae27e4037a04feb21d96ad5d5f0ed2e26600b91b4887f64f21ac0ff504a0633b4752694b670b3b17e17291250eea69c1bf7862e6fc61a9d1663f0b130c84fd16a9509db2fda84a87de068b45188104ec4130ecd9524edc3583264d1c07eb30ee11da7e6450169f3ae9c7ec2d49d9c0d5192bfa67467c70b43316b8c201a6a58425c6d262ebabf62eb1e542b3522fa144ead5f12f672fd974e004cd87dd1b39f6767ca3fe7924117f9238ca8e78e23e20c21d3a163449973562ef22ca9db70b864f1d0aab268dc36cfdd84504034aa604dd0235f8af6f299678c5de57b22d0abfe103694147c753f98248ff0a4ce5bd270883be3603165b42a1d35c915c959a868123a78f91e2b540796b1659ff1e5df759883944a9c6be1340667c9fe08889aa60699bf8af00559fd9cb0e72552036c767629abf7e2253be3d58f1fe82ad1f06b8dc2c7162f246b8a52d23560cfc28d369d3c5910461e071b09613480a7d9db5c06d104c5d541a39279dcd3d524253150da2e6018579388ccaf6b6c05e46d6b025365c943b73dac6866417336a99ddfbfdd20a903543ee63304fdaaef94ac8a1e686043d718d60871b7ddd12a3d5acfa265fd73d2b5e103bb839cb90b62e9cda17a2067e061d07be3e602a57f720d944d7a30849e892c9db0e5085d90568a80aad2052d304756b9dfb80ac9f6f712ef49ed5dbda309805a5f4978e57516705fe6f8d07d81a6405d7dfdd6cc855577f33d5faa4677926c18be631d59fa814ebb948204b942c6073262826edff50d099812b203f906d1a54d2c1f7529e063616ef48b678baf83bff4e9c7344a05d11d43f9096ec15ebf41e32852bb28b2e798bd45c7d6769d20282f684c65a0fb70adeef430d358d11d7b80e5212a50d6e7dc7c2790d902fd3a1103aa8354697dfaffa403241d9aa7b12c59ab2fecf6268e239e6eca66e504f3cbb2f1ccd2f89779d1edf8dbc555970d3a960e2ce219741f19559808e705035bca2ba1f6e0b0edf56eacd6a124deabd340874ef7ead2b10745fc7e8dc56371da70918ca51ffbd20dee7260a204403393bcc6a1546a0a29e1b5e65078f603b299f442da35c9917d1e8497064f63950f673e16e710ba9ae3c4c2db70013f9ab0aa48a85dc2e7a6462ea883066d038154c3fa9d5826674677580a848b045b9ee07e259ee4ff37700d625d6983838c7cfb115ab39b41f583a92e7f02c54232cbf81810659b5c9a231cb06876853c93450a688e582630dc1730e4673b9a664784fa2f254788e28258960d88abb532e151558e5fc4f50428adf9e4b9f31b2e7de697bb92cae80a1aa153bdc0d62a3217bc4aaabe91f7ef7c5068465e7a2a0549894d310eb98e823f64709798d9249a926bb551b6d3162171babf7d47408dbd2c46b081a1b9f4570fca74221af4a092c28e236be8be64194ee59eb76170aa3ca5db161103f429a32293422a309260c6604402285951ff3a35f363c31c12a439b6529a73b12dbecc19df50a56bb701149e5ec54c7870b11b02032d1cb20b870170056af0606c64ad463dc2f445c8563c08aca0b901cdf7030d60f5800e42ac88948741c807b26194d382dafe23fad4b2da6217942151774765eb14e1c7c11e67b68e7e606cd3a3931b4e7199b52dc79bbd6614609d190d5c8f9e5a3984dfc1ed6a502821ccc99e2e3bceb433702e9d376a6c30d7b591eda394f92371b1936aacf5ba5a1cbfd584dc69fd296e47814221c09b6bda3ff465a2f85c12f4169b06d4fbb65b8207038fe288ba5e23d60df031ce921e3c52747d7017ed9deda82a30fcf6d3cf22db0400ed624ed99a10b9331b084d331075549023f17dee5a386fcb9b09cd1b31093ed5c887d31f6309b5d1fd04822a7146673a1198b62f132444a677f18ab83daab1db0009a4a539e662ce81ab41f0c5cd9a68a7633c065b354e8a725878d02ba9572c3c526fb0054f9d058cf2ccf001c7f4bb432bd55a145cdcf689a690e4167d752a12d51ab3313559db19617f73b49bc2fe1237662f7658bc4d2e1becc1fb1a3dbc3649c5e2b2adface80e704c3f45cbc7286496efeb1859fea702b17cdf0e58beeb4389bf2d7a07c0e881d88c05af7c5d7e73c3cdb0069ef6661a92d1165be56def080e71f594e5baae50153f49680d9d9a6288a6c2b5d613f2b475bd889ccfab09036f17d619c5d993e6d08023d52ca67f91641d8049d046ad08544594c01a7cc5c8341272690558db1354b1afc28f70a2e8493164c94123370c2267c3240a1baffe622fcc155e41450fe45a579ad623727b2dacee57b235af8130005c01308f12429e67bf0d59104252eefbcaaf8e22f2e6f0851230e8dadff378889936b45cced9f6f0a77b9bd601ac4211cf2540ea02f9c21c1636f69087d59b87361231f54820cc2377f00619608f65a1e1ccbf1b9f2c9670b522bc868b7345094f2eafd7349f3acb5527d76eecf4ea2d0248c155af6438875009fa2a47f68e018ee2f1973e9aa3a1487700f61426ec37b4c99094a8d1458d0451f29e40a75d8c335f4660869cbe1d26194f1f0ce82b4f73758b7e52ff64170e1f937e699daca815bd541365fcd8b090f2c649db707a06a5f3ae543894b39bd1ca0db1d6d297822757ba5ecc3ad9bb51eb37d578cd564e585b0f3677b5202f9f88587a0f6f7eb793656d4b44f7cec7a8efe0c72bb9799b085fc342bf7c5a4663592bcc36f07c1edd1b325e83e848dac77ec8d278f0fb653f4ce67ff2ee8ffdf52c8aa93705c434d34491440cf51d1e87c1afe6aa4f3ef14e9e0470738fbb605744f42017c9ff0cefe8637fc5064a405cd45c122bd59e5ee1932b27f9deb0509b615979c4688543a34c22d9fb442c20ec4f62001fc6147390a2d16cea79b28e46b182cec486debc3277724ffb5b1e5584a92d80a67dde3d2345a4126dacae12aa5aaa806a75b4a1f476bafa8238b0a18e63f5a50b8db7f15c59243564eba8f20db9ca0b6a043cd4410d2e7f3c6afac58dcc6f6bb8434869c08996aaed037b98f993f45bcf98d1db912c8682eb95427fffaaa520340616e529565217db936ee9d81e9820f1bbdc7bd1d2169bd0429eef2e3d3fac67a135140bf8fa1ea60f0b017efeee40d8508e15e39df6609cd313bfb6622bae3d15e38996e7f4b1b16df5ed417acb4c8ddca34d6306ac270a0aa35a12e814fc18e09c1debe9acf329c7e9f151fa6e9ca5a79931fe064b8205278d1f9e5a618f865f128c19cfaeb9c4f24e1c0b7974f6eef425e915db5a3aadd5080c3853b113ab6fdde0e0680cb3b0396fcaadcc1821944429d4bd22671ea1efd246f98e88095f3faa385df8e023d289a5366e8bac2014222dc60a96862150c1a77a4751ee7f2a05d20be64b9d3ffcb4cf039a8791205e9a7232d0e924affc820dc4d22b6ea7e7faf25fd5dcecc8b312ebf774d8c65e8d603098baa2f692abc977a34dc42e81975b569b274a87b7f7ef981e255c130bc9a3c31cb32ca14f28a5af201ce4b34758f91a3b734a094c142762550ed20d1c4945327d2a90bb3f228e3870fbee52d3e19d7b29b4983a0a5284426d7dcd9bcde048e32cfe3e479478b0c57b3222f5ded3e64c000497dc6f9a24ab1c0ae91a82db85a88cc543e67bb4b11a5c59effe3889ac482f8152605107613203b2331365e825859b7b46a7def84084feba443b4eb2316a9af0dc11d5a55ac1de4da588cf2e2a4a9b290dd52be6c11ddb8783c58afbf8fd8af113b2fbdd3853253d2206ce4a621fad5f521a9df7af40a2fa60b1a32fd128b4a415c424acf27aa0041cd3e555ecafcc492f99d1b94c39fffe00ff0427d30fb432fe6a94ad7bad465987a94ae5ed891cdd283478d0bf048bac26bb61d75f87372978d0554d1e963b888108391a607e9b5ae7afcb4c2fe7af49732e5d841f1b4d831f8105189f202b55d9e6778895950432a2b54677fca6d27b1f818c51f2d620faa5697bdf408e68db68b7323fd015c16dad98d87439ed023f228b2dd4be0f612be6fdfbf913f655b1547cb94d2481b07608266580ae3070df29a9f4fefec9b491ee8b2a6a8cf4af488e19266651ae23b304e243ca628c0b626910236d5186d81ae3226c7be4982096fdbc68c33be19544f2d175e2db78e60c90fa0cf3c5eea40e3d5dedc83dcdbf369f8f4cf22ec3a900a3e41c2d98227052571defe013e33dd9a4ab8c5ffad227f3093eee35467ac400260c2e0e7f5ff65c22285097a13fc6a0ef024d109a2533c6fef11c5c807559a0c36599acda8b778c75b680c45206f50a67208802199e38140bc3a8e8e24eca5602a92a6eaa63423342c8b5e9b460ed18eda4271c2652d8c3a5b042eaa5252c78ca22d5ab926bcad9362699a107333d73b9a8fa26acda417fa10149efb05ac6c6ac068c64c50bb21189a1aeca6450398ab838f6e11852ba8c3c1ff51576fb51719ebc0bba6b586717285c28c4af5a88c1cdf05e8cd938c297613b1751dc1b4101586ffc241bf5d72aa47d70e42bd2587a6ab486ce6c868122058b0f7c3abde5c2ab19681c650aeb07313037c9f7581443e01fe9e2b2396fdd42aed9671e73b149386b65bd2237ed54123e49ddd73690b155f50511775e6ff143baefeb37d1e27a08fdca4e2688ba3a05becd1529e31d69d26fe0db5bc3dab4ab939a167fda527f6ef8c859e42e611035af8d3505844f110a6c5dd5c8fb94996beeae7290252e98268fca734ba0021e5992bb86bbce94d20192c59c4a0fd0bfe5d6e4e37c4fc9d77065d9ceeec68b93275bfdb3a8b14c0f337b47d39bdd7a7db021ced89993498bff52b0aba60c1e97cc941d064ce7495112ca911ffd78d9b3083e0c5bfe0614da5232fb198e37602acea1cb71456c6498288b422e3b32a05efff1f9822d52c92617520fe2d993abf5cb6f452586abf9d8769df4d1e33ba8d542ba658ac13c436af22503cde2f3cbe475b1131d2fa42d7f09cabe7a2a43d125723745852d12c209099e278ac947641c500e84f5863465c515cf7a1b1a95be1fac006a034baac6bbe86160757dbee4b22125ab2b398d8ddc5d29658d76f8e683cd353567b586b1e15da0c5ba6c806973aaefdaad1b46fc2d3bd361d0a911cf5380dac1f4acdb198d853f6193e63a8ec9d78d22f87ff2a7c7eac49f02e06aff913376b8fe54697b7e93abef89512a88f7da78a1e5e0b0f2f772ca394f293c8b9dc5ad1214659382fec3c986cb7ac86112359322f591dfea8f6caee578323b64e38ed706079a900312cb782fdb4c9c9691cd834a013e2b85e1bc0f9ef5ee06d51bb22d1b6eb7249dfd35a416cf443e24ca5dfdaf09391983f61d7f9cf27e83679574222e3a27ff4ae068147c716252d69f1436a9aca294e30fa47d0ef19901142f208b8e29b2b811deba488154fbe2c40f4130ed74368d4858f02ccc51b9f080d1725319b5590476381fa90795a976b43b84458381bd108fca507448033acc8d5f5c3092aa9a0e723a08429d0f49914a152f0e34a0039f323a0e23e050e0b4128004a34eafa8eb08faccd366f199312fa66ebdf51dc0c360180ef1c871ea9e064cd5fe83368270e69d542dd3dae803277241a3c55adb7b6fb9e596292519ef05dc05db053b4f04d9e5bfc3587139d1ffffad175564324aa9e7b9cc9a714dd0e2a2b287c17e1c236ee95441f03d8fed4eb3d5960926f32445760ca23c142a952aa1041450286d7c2e398f58b021cd969823124ba6aca8c9114835d93ce2e96f5bdbfeff5f26f3921affaab24a39077ef4035973ce39e79cf3fbb8efe3ec0f6b29fdbeeffbbeff8f62105bccc425276d856b48369f62579f83a083e067e3299a8e098b59155f745cadb5d698100cc110e4e1071e6e386738c3c9a1b88f079f53e6af5831e525d7dd519e4b391d2d79947ab6db76dbcedafb556cf72d58dc7f6b7be7c6a620c8c810445c01c505c32734138198865c25e0686e97068c47982964c722c82060a660fbbbee3b4abb982eac4dd569452c83eb3906e31eb81b47e576bbddfc76b3f65e8c1b731cc795ba8f2be594b0c96612fb0dc877d1c50e9470c14091fce04ae2e1e9b7242ef27f924018c0930b030177f92d3b01a6b82d507208204529042dee3bf155872b2cfe621a721aea953ee8c3209e38f0fcd509dfc03efb5500c49ee510e7c388f3531584db6db65a2a0838c41b22f94220a0fef6a9d38dbf88e41b91d68648fe11795944f2a59c5644f29130f953b20300f525277c24f2d14f3dbbcdfc36bb8580c5b55df48c9c953a20a731712bd88a669590ca64cfc29ecdfe228becac5fbd14ef37d6fbcd6f9306efa47c279ee8877c94f9e863cc9463cfb25c00882f8ab72ff25b5b31e76cce66cfe8d7aede6edced86bf38b95159d9ee1cc7b1a8a876d7181e5e930832f2a4647dedaedd6189d64a3110c644e26a77ed6661769192fea40308c8f3ac73c9c9146c749c4e3a80584ef3ab9e9a06ea19145a5de361c736b355f1cf0b05dfc7d1762f3987d4f32b5603750d0baccb026281a348f4869458ac634f31c7715d67a2f9886bbd9e22358051a4e757a7d751fa53c76c4f91aea167b6721dedd9cc081043cc94774ce682fea18b3aa633a3f5ec0b413004c110a4c95e3391812307c7d8842a1c47676b84ec8e598eb13391220b35b6b8a14909e30347808af8837ae013e4c84a15191b99a99272e74c0d5826e72cabf1931dfb983c7e655d9765c9b55d4f7ce1207235f6b00f20a01497c5f406239da1d90d4e402fad30b9383fc00b1a174c848a3c612486256bf41044c5124f98f8cc92088e5081114041430cb14416bb29d9e289346c70f91860f0c0841a40f460c3cd851364a624a8075fe4000c4abb5abbfa3d94f42425b9fb704d3905da2567520f105f9d7c5c88d366a130574ca6631b201d2a4190b89c78c33a514a3d1ae6f4e982c20e971c6374d8ccf2ff29a5e3d1cf139849fc2ad5387ed6041a1566fcb860701c6638810b04023384c405c38a12172826b134473f7ffe7c9b8c23c68767c2b8641bd181290a531487aa78277f459129e4b6f9a10366021feb99c33b3c73b3e400968873e3a36d1b1bdc1d9e1e3a94d253ad3d7c65c24d87851f4082b2dbc0a06432cc38206572da7020caafca511ba799489d714829a50e9848b9c70a140f5b58ee8aa9e7572ea20d6b5bee65399d2ec62b6252524ed1b59fb2b50c41782a8d0558ddac6635c56109044b21088220cb471b1f6f7066a17f38cc3963ca3451ae2b8914cc20c618341c4071cd3480789812e40c2a587083cbf1b44ea7aa099c27de5a5556a9a878d12aaf57ad3bbceb287802d0f5683e8699be5e5d435330436b71854fc1fa1414a726ee11492de8e9540aec0d97489f7ec88e0ff0e492fecaaf991d5cb29bd57d47bbae63d12f95700e0188b8242b77197b262ff722cee19517f194cb30532264b2632f87f9c80264692891340e49a7d7d17d173a7d598f7ad6c66e130c8f95a5db4083e3d0af5823d9618629e332245bcd5f35ff7ff7d70d2bc2a9f3fd7a597bc20ef7756666eb73b3da2d901f21e247bf78b86ae8b00e20c46d204e43718b5587467bc572b0436d8617e6cdffbf878f9714fff37ffe53b1edcc95ac1a038d22192e30061a3b63eeec3886a78517c99d3c42155d6d47f5ab50543dea052effa3783ec5bd5843c5a531e352dc30b83bb5da8e8d523e51963737657953e2c88e7964d105f731d226fb6a764ba90dc66d3ce492739660dc7b9345ca719ca5d5ae7177ed79dd5932d806bff0cb0688e7c563859c9becc281d57e68b3bbdd4b5e4eb969619653b08dcc780307b32a66b3d96c369b51fa5ee4a31b65d61a943ccdb29806e822fb18b945449f72d0d0b33e9a32b3a222b78d9cf85823433b090aa23928c0e0b6f8ff2aaf055588888888888828a55d478956b53b3f45910c0d1111113db1a4c950d734d10c0994a026866c6624dd886e5de56e49b72796ccb19bcc9437514369a26db19e5b52d2cd1486a6521886a18f44442b3734acc2ba39ee478ef2e8f1c687a2ae30584ac885d2c4163eb880c060a9d4e04a026218544518a1e24a6267e00317aeb25fed74ea055ba25a945df04bc34c70c9ea93eb8faf58b05317140cc52f380617578bc42accc7c66485550b030117fc827db8e0978b5d441b18480b7e591181acb860f0ede3afe4020224898f971711c684a70bc80b8631e9c0702204ba27379eaed2cb0e70ba5cc0cf8fccd6eb91ccd597e527f959124f0327c8afa1ec91a71c7b283bf3d12631538e5f5014c5cc1ad1203bf6212a6cca887668ca7c3de255085561b6e6952ad6a017333037f0a5096619e5ebc5a3f630c71d2a1033e55d536155a80e51897c59cb477adbd72aec6130180c56f29725de5ab1813ce5449cd0e47ed9057f7a4293fbd5e6c0ac2594e27ecd56db507eb376cacdc6c325fd158bc562a4cde142739d489e4e3e906e6b79915df04cfa0be5fe7f04c47ddacfb0b8e4cf4c98e22f7fbd5e598034545c09cc960520306b7acef8f09fb32948b57e8e09608860edb5496a6bc3f87f4a2bee4c9e383a39cad1a71cf7b8677ae6461a341a8d46b36178378f4abdc5c43818335ba67aabb79a54d1982dea3469f4cace706fe88e480a48dc8ad4675cb2de6c945cb2226524a7a9d8365b8f4f2fb849d8a80d09c7d1a7b65f55dbcd66abb75fcd396ff3566f1d56c17327fe1659ca8dbce334d4566df566ab664c19c7b3dea654a47a2bcbaea3b4eb68d735b6bf2aa1deeacdbb3df16a6cc23d829974fdbfeffbbe13cab8df2e4309d9b1fff853565b19367ddb54b9ee3a6e8532ed4473a2ec2826b7e20e77a2fbbc7cf4b9f3532c7fad4a70a7ab5d3329282828882e00c90502ea3002cab8d3d5835ff7a284bc1cc88b88b1841645c400881a90bc70855f784219d77340dc336f2c2d145cffc13ae4fe117bf8eb532c4c3ac8b31dd493c48649c31cdd719849842cd0413d1d94742aedf03c10f44a20e843c702af57e82f485cf437f8ff36502ec5b456fa62ccdce82ac6a3aabbc6766d5037281e2b363ae09cbafba31cc7712aeb4d99f2c6c6a88c2aa14d7bcc34ab50bb5c26e93462a61ccb66ab00b3d5adc6e9c10a4af4eac74c798be105173db0b0a64cb62c062d83ec3885222ed9b276590d11426e8024e8e522e7ac6f631166abc3dd1d0a06fb6ea2960e2e396f227c71c996cd8cd33deb59731ca7a2b2b00a020471dbc5f09adbe063b1582c168b597b2fc6208ff1e6c7582cf6273baa5a053608e9c105a405c3a05282840cae24216e1193d019233448e8dd86902f5ac897304575603ac91b785cfa7192e7ec6728cfe439fbf1c91efb55cb2cf8f8c516d233dc3e3e0af1a1e2ec679eb5368cb0330fcf197bdc78ce12fa4db8654fc515d98e0afb86bd094586c044761f21b8eee40f37d875ff4f8e74ce89b310421ebbd80626010b6ec124b8d8063e8db38886c86db918e631056ce08bbb04f32266b9d889dc4e3aec44493465629d07792c766a613a9171e206365cf17a2742e6632c44cdcc829aae6fe6fb892ee4c56ddaccc79a15dcdae38d67721601cddacea9bbeeaed3118bd54c0e421055df5437940d15628c378a25b7185df345f44cdf549fe4879ee86531d971cc9cf36b2dd700e76a7cd594c98ec118bab61e06d2895d7742801777ba7af8f87cd8621f107b3d9e14979ce54d5902f1f669cc95729a26884bce92f3d20d1f5c1d7ffb71b3ff7fc67d4c86d92b37e7acddecbad9756eebcc3674958e9a3bbca313c9aeb1d8576be6fc6302b326043653ec2eaee2228c553438e382990cb9479972a9c3fffffff8033706745fe48a6f7cb2547145e083274794370c09230b1719c507209a582246910d2ec73b3c31aa5a15cf994fcc6958d9288524e8c97d48751fffe95716f684e3c6cbed58b0e336729a161b371e585a09d259cc94e3934876173844b2bfe8313a69958f7cd646a82ef2d1890c65bfca7ead88640b316b25916c1664c7611b71cbf30cda9479bd5e2f19eceb6badaf570c38fa16a1277aa294fedce9633e9d4eaa533d9dca210ac801e682613651e207249e7075e2c9b6cc8b7df400b4e4907249954a87cbe768c2c5c5c5a5dbdb0429b76baddf72c13893c96475a8ca66b3598c8f3eabd9663413a4d4dca51f8f8ac89e7efdaf157fcc6745d384210dc30fac70e30f3fe6268d0bd6cb8fea6151383c72e68e157c44a0e2d963f63e2aeab324c6dd1877b587b78376771c56050cc47dfcf88c1b95dbed878d8dcdcde6e63629d8d8d45a6d12903d97ed6888dc0e83e2b52f92d135657018668c69148e9e1bf95f50b98e267736e338eef683f38f0b21b7a5566b8749708b830bbf61248ca8399280ca8e614566eb73007c40f198320c98292a3d7eca4d99521b6a29c7319ec348b91d2161d884c4a846d8b823a4d6163261230c0683c160dd3022404e875229870f9f0b31dd88fe77d6924be79cb1199bb16eae63aa6e71b8b4e373c3864c19ff71213e306f87396cb65c666b25bb8ffb309d05454664a72ad6ac620775cc7d685cc8611e2b12abc0ec721c87f222304a4557ddf050b1686a701f7b118fc142a852a54a1597e3e90e83c16030180c068395a2f0b8ec203b4fcfb8f7e189f1f7b15c9f6843c8137b201871c71578f89833671cefb08972c9c9e3342ed0ee4163b2fa6bd76960ca38aef5ebc32ad9b5c3a79e210d32789ce4e06c31032a78401b3c478e1c3cb345332ab37cc6059d4d139786c8ddf994db1862d3962d26ab2d574c4b3ba62d77e7a8aa48760bd366011d1f41e0441f3d3b3cedee3b1f915e494a4a4a4a4aea19478c933aebb2a89ec1c80b6a7001e9441e300757876370c120b9ec0de428ed50d3d5a59c1e3b64d4ba9f821b59e0d999493d5e522099da2049494949493ddf0f6c409bd5cd49bf3929cac1effbe8d7fdd940e2caf4e082f8521bbaab464c6d7c64c275b82b570cc390a3a51c2ff98573c49d9ff27023315d30954c9ada4bf2ecfb0fc39e32f6004fd48476a2ccd5cd7fb305e260529a8d84c4ca091925217b71424642426df4f22f4256680abd4a2693290c4dd8d44957f4cc0ec89e116d61c59429ed08f1154d86155fefa06fd05af4ac67339049336144087e5ff8853d65461f757c609ba292b3d46e546c369bcd66b3d96c369b6db4f825dbaccddaac2d35573d8399726cf3511fc96c4795eb3c9510a30f301bce7306b932646f34becc91e45ad189dc9db84d199806642abed0b98a433dc64cf59339243bea943db19dd85e2ced17b699d3bc874c1f84985cad1c759bedb682c4fd1d9f4e2b5d62350db3aeac24f62c4709583769f6f33c7b4467b66bdca675dffad6f6f3bccff3663318e86095164c5cc2ac69a19e7179c1e3abda84f2b12e13063bbc25ec826a974f92afb4c3d03d0c435309bb347641a526021cafa0549e92c98e4b33d971ed1a14e64c0d0b7641b9eba25aa86b6acf38ae7e3383791a904e40739944180a98f00a5e1149a0e3d22186ab24ce4fc5e01212ea175c981d7e34c214976c2124846472cc640f912402d3b582dd0573b87d309d86d90ab1975a666be6cfc3add9311f3269bc393a761be6ca75c88edda76b72b4004a9071cfb807316bfa488b53c665478c64c7e078649c51e45e4109afd01feb2ad56e25b35d30472466aa85ba5c92bd057d84f68102982dc72f2817940d540b0ae5a99b42c6e26c913065dcc729e32c18432121215100991c67cbd47272c916c2e1b1828f2dfc78a1a7242434f36200bd654a8338941a8180bbb80f7bb6ab9cc5060872cbfef9f1dc8aece5fa8a795ae056389e3a3d92948ef93c32c238f61d63955c2cf6de3de9aab5b6abf600422e8dd53b66ee6aed3affff9e51a20a0efb799efd40775dd7759de7799ed7d1cffbb0f7799ee779dff7799ee7799ef7791eee58aba259e8793a683a2b47aa28baf9920333e53c50c37e0b5cdce9e337cbd9fa2736389e69d8a6965e464051380946aca0a01a54fdc60fa7ffafb5a4c2e95413c68b3a1430c2d1e9549fbe026ae6e80b98ac9e713c4768e9e061dd582c162b46a5a307cbd660ba8395abf8c5ce5a6bdb72311c3a08a96c2d89b6abd687602194830b8614a6d4c27085a5524904d23fd05c30b898e10a459bb7b6ab96a5c47d191d717e574f51d4eebf7bfb6f2d4dc7073225ae528de3ede236ca9b323e4b3b4618e2921d13caa42db243031df11d66abf3673dcff33ccf7b994da35ba5c2f8ded2766f55d8e2c234d0af7a8438eea6f4a8cf869343796b8b109694f494d27ec17fad569b2dcfd47aca9671a94d0c72f8c845d73c0af016355c0bc2bb6bb5aec96adf4f690e1e2ea9faa7949e86c26845b1c10dfa4459966559e278ca7167108a3a8abb1e7305e2eee6c184d25cf59c30579386c38d55b3a68be089e7ca84bb431db98fc98eb5ce29776511c8754138093128c2f408612880812421bf043317883be09257008a24c09f12cb2fc1cc55c221266f490c95d058cb5ef66436813253de250d49942028643722278662b296e9fc534a75f428cb5aadff8fe33417a7c1bea4252d6b7022dfc873e633cb2017725cad2aec709d9665d16c85b979ccf0959fa65c247f29f6d5a03efeffe3244788fb45e550634b3a2df3f81884100fa4040ed98504396187ebfdd669df64ae7e3c14b3c53deda33c149a9df62cf816340d25d22316a4d34a3a64ca38ee50d0c9dce0f2007d49b798328ea5d468a5159be8877ac671a934f4648e4de60865a6be7c5a141fa57c28fee652bcd6388adc51d09e2861459491d32ecd69bf6a6bafd33a6badb56f733265a0e8998f62a6fcb520fa7f2a9e0914377826548b2ba6284b22262667c5b4b34429a575a47d59de40c11c33782f0f2b7706bffbaaf775a75335a1b1eaae66e3536e6cc21ab773ceace2448d4a9519c48a0c71c560c48bdbad4950133fa0e29a4631982149901e60474ab866a8d88ea05184c3ec07ae172cf6faa11cc771ff1cc7fdeb050a01c3768528181f200e710876ddb582b41bd9310f8464516b8d51d5eecbc877d68a0deb195700111863b860e8cc20728120cac611e058a76b5cdaba50da75363eded44c19c7cf42e3543956194720ccc7d1ffd37440276490d011f9e97649ba4de434951699ad1f85827a38810d479fa94619638c359a89a684c97944426aaeb05cdc82aba0c289db7461e8d907bfd0545ac137ce725bae0db185e5ae984a21f8bd67bbb2a85b1a2452e5762b21ca73178a2da5d6aeeb56505da335ec6223da90b63e5c212e6aa23c3069ac08e6aa69df427230e5ab6450846acbd99111cca23a571a6e0511c90646464d33ca81d18f175a804da11935cd681cc7ffb7229cee6ba58658f700b33f21a55d77c3b1f3ba64ff90538dfcd3989c355cb91e5b94320c9beff4d46a492fd004df4769de05f4bef3fbfc6b3c5ef2e445d7856bffa2c5068e971b3854aa71bc7767629bb188c3da1bf7be9c4e2e18db105b06aeecf0cc9b148292cbe112f6306913904b2ef74a67d4e470e74c8629996c19c7718fa29d3916ac92ad60fc541a976c99ec7125b10a177ff7871f65c22c288e7c81bb256cc2423021ee1ce250b91efef0cc2de4167b28182bf691ee1c24ee8dd3ef9c1b9c92cb2faec08387eb92c97ed5a19c1e3e8e000935506e9913f958ca71e165b2eb2c39c4c4c4c4c4c4c4705c4c6771496b436c6a228ba778f3292bb2ffeb5726136ea9f9e6c325ec0314613c13ee1196b015393148e879c20fc946b6d1e192b384e9d1a56f9e9fb71f376559d6c73f6e601532980c79c933f541b6ff39c1309ce10c278fd96a99292ea9c2096fca5287d2ec1e3eaee6cc9312e0751f873d1ceb38be71cce3cb37655996379506ee5cadb5de472a9f284b2fbd2ccbd92261b65a72631f9d727cfab955857a418d1fccd61a5d639798adee052257c5715cd7e5c8c195727af8085f5cd28732a99a47496b945e8d5e22bbd0b9fcc10b3415af7a5ea861ca4b0747fec49b38142f69354479416186df889c18f2d187ccf8ff7f4a69597265290dda4e4f20721f7b0bfe520e0773029122a68ce3d76a84d75076a2ef22b2639a94c9307b91ee6e2f62b602a075a8640f7874094b12000405d314000018080805c3c18050402898ce5b7a14000b5e743e7c66429c07a44914c348088218640c4486004000314486686aaa02c89f7e81cd2851053791c960ccf1ad9b54026f96ec7e5b07bb2d3d592eddbe1c803e2d238c60c537ac4f6b0afe46930c27075d0641746c4e77e04e1f45040b252409390a44c30b13d1c1182724c01322ba35680f845cdfb6a8e943f70e97058f0e1353a48029fe30b62e349a3bd1be4c56bf2da7b69953ac1ac8f6937394094b508cb1da026f311c337bc24c8d99e27c8b7a889d5ba5ac93af63203ecf146572daec5080b4493739d758a4ce4702e46cbb3f6a4bcb300b41ee8242b5e45e2902765cd52e3f915375d7592e8a22287995cceda34cb9863019c8cf2b414ea5c549d7fb492c13fc9093dbdf7c21320c551b729d0e65bb5de7d7ce542d640519cfd413ed9bb160a7222d7116ba09195a3ca43ee0672efc8f8ba6e3d8646872923b83cd2829f22b0f56ba758c8bb4328ae143aa2dabb92def9b9b89408f8a3c20e4f3184e7f1d12b9cb63be30fa35d1eb8c0303f8c8d9fc69535083c3f395e8ee7280e13a33a2d464a8d5500bc0da225890d97c3f4f672489ddfcd5b77b26722a5a3c37a7e0ab707ac458f2b5eb55ec074a45b9320315f645b158389c7faecf393318789121ba9a3952e70f595e667f88f65142d3314a3d761d9479a232be199d1c42ac57a61326871baa125c97bccd911cde7b82b0edf131ea6f82501a2af2a5856e242bbe34f6221a49a89ccb475a074483fc6fbd61a5cfe02a4fa9429f49b0f75049c6eb129bc2369c1741bef0564fb0253aa38541493dad7f4edd6b93be0a88d1f6efef51b930d372860aa9127a67153b193ddfad3f56c6401257003c1f9ee20300d1ede56365e9b86d43d006a75adf150f4f2b68476c8e744a865dd896e108709fa518d3619f448c5fe7c301ac1de859c58fa984c02e218096bacf8aa956fc0fed00bf13ffbcc591cbec320a35bca3a0035e578935b29f91b4dfff77781318ce54204d915c5d250fe0891d102c328a81e17e5eaa98973b82a09e38027e3b08abf20e0b76a84c1216cf841594dc785527643f9fb2dfb24e2667fd5a044a07762bda109c79e052f6d084f3ca5d5eac8d5c438e887da9f27b69b300378accc190f1a38c5ba0334226e3d99782e825af73ee6883b9c3e453269e8e2063a310ec82f1420097c3464a102e081d07947a0de3bf49f288f57e95cd9fee7161c5f8128f1473ae52663c08302e58d18382570ff201b46fa0ffba483758ae6a30b2e90bf48420ac169933e5adfd40fe5a519e15b7427868f92a3430ccc32821f32641766018072b26ebbcd56ced3ed83593b603f449e1c49bd7dd6db2d5c7e6264200cd81f39467363d9d2e30eba118f466b8440a9c223bc5b726b428e2d67b64f7b5a3c53cdb36607a6bf5774d41c0459c2eeb8b469de48c77b7009702e51477ac00f2322406b987347c870c8d3f0201e489e29a19e98e13ae279e5227c011f5086579c89bf789d23210681321bf7da87091e41d7bf38ceb2366d9453792173002ab4a62e94ad445da5add21f4a403cd0347daad5c7159510ba0dbe79bf44bbf08b49da6ea76fa9a81c9570e9c60cc79eb92ad151d697bfeb0630da5a72815d929a75db7e3564001d2816a82af67b7b369d641b246b45592e7b3e66316c15750757b67886f0e3bc61712b8227aa111392b63670c8d74b4f477ab6d5bc4742fa8760c0ce40601b03b299ba4c87d141afa227947710fddb094b4f0d7ca748136874e6a7fd5afb60e5d395dbffbb19cd9358df14c8888246f16640dbfefecf2e1c9a14d3941930a4f80ac70b9ac71b194dbe292dc0266751a6cc6053a665602ef2cf91427676221c1164c568e0834af47030e7490c134512890733b0e0c7c68a7b5ea96e0dbdeb768af32b9bac2f6fe0f9e974d58a3c66f2df5fe561f1f80c4b835c1245b5c2a7beb3508de473afaba089ed3ff49b684ef593e113ba0205b0bc708bff0050677cbc3dde7fa192b1a3ef4b531b1a26511c1f2673e66b57aabdb765a2ac36500082f9835c78cb4638257cefaab79953dc1763e046b7e0984571a8253e84ad4023a0701e53295e37cb2dbe05fca2934a7a569706de3c045be1ab5273f29499bc64cbb82a997f1f995ccac9987b3cdd256f357346bc0dd93b5f7f540aae2c5c869cf04ff1fca0aeda48517ff279ddb3f9979fa4081320783e0013fa4a4ebc2901e246b2f5707c31fcaf6a9869e746a4926dbe636cb158858c9db25d3b333d16ab233b6a4000cae03f98c0413800efc4c3b2c46728d81ecd73613bf6e6b77a4609e108b96f02f6fed42ae3350285421aea254613c510afaa326b0af2f2f738cdf5f44f9c79b0a6218bc66c6df8d1938a2b525e2b967d0358662725bebadf552def014c1f65388a69e6bdd5d9b6904ea930c65d4f3ebe06f3f712cbd5f336a2c57a978cf3b0da0bded203ba5bcdef7cc95e1df2a9f395e65f54b4f1743feb515bfd0b39d00b6a3b0a9f7bf403ad3c83398d9141212228819c25f0271116ac8437059551518877439f024873093578846fc079a2314a9e3670bf0782c841bf15218638b6dc929edfe7e764d235781325cfc5d52dac51502ca584f3b4976f4eae4bb875c7c9f90762213eaeef6090188d2b2b95e274eaba50b308c8602908e89546bd90f47443e12c094ae611dbf39194cc8d621ee3672a2db30cbdc17ddabbbd7a98e6fb035ccb77b6e3ab598b35398ee9e11cedf4f5a838eedde2358d1a47ae3652c55195636450d6552db958680abe9009e8c6adfd2d7e9b5906e7406a4f81fe08b68f0b37ce780432cef0f34cbbf0bb8e64ad81ffec82eb2b9f7d979628d50de39cb53e600a6c2305ae7c4a0d1bcb0c72cd6e770b31a812a9a110aa5d70515134bf2dcb89a9b4994d74ec9eb18e83ffede488fc16dd47121304db80c7c0ed9ba0b61d4778e15e98948992819e41ee15c86de1b2489cfb09c189fca36d05032481b0acea0bc73489c95824f8fa5b037b9c883e02fd4cd4460fce23aaa381fbfa5999330b53bede496c6b79073024476b8801b9cb3b8cacd220b4200ba9209dc127ec77a2d627346b99d07cd9d15accc4c59c1752f7bbf6de492de2ed7754900371269d9a6a7a04b27dc1a25ef712ac231463a6cbdc104f13dbd43f88f66e98698356458b16ac9a7d941e431c2dfe1cb0d83bd3b408f975201b7cf110fbb971dc3ba464b16865d244e2a289c39268423f3577e73488f838713395beab7211e4e3153cd36460be67d75fcd180fc5b90cc271caa131dd60dceee977de6ab76646f138966d9417dd732adc13b9177e3f8a1d78353ffef9398a9c8067e32a3fac147b17657ff9aacafff0831d27ff029693889863baa07c6f1e2042c4753063042d1d21f1912d213d4fdf0006bcf1404e6454c837b8e7d17a6bd8987eeff8cd8d0e6c77e7d96f6c07c0f69b2a2942cbbfeb6e0035c989feafb785170b220683ee881a8864a201aa7bcd27cc00728490cd8bd27cdb2e849dc338496fa8aea8cfa8a58c0247ce0f25b0244a9cd25d82e91d495b17b1f2d6296a90e1ef3db6fd63520fd818391e064ad553dc8fa43e65ec9c8025b898acf20a8ee79741825c6fc59e1d701bc5b8c29386d04027f7fddea474d5b4d27f34f4bd941c5c6e1b6758f58ffffb44039541397c4bcab33de1753e2b8f134164b0e6cd0fe9a80af51f26f4539ff402b4704010b9b83b0fead40742bc44fede4ed025d1737ec6841be874f5a4cca7ecd7861da22fc1a0c26259285c4b677f88705657f8e85a41961016146462916e0b9091da1d591963efec456f63c6432a88f46a3404e50a82859acdad6718ff06e22e6ee71368b1d584eef32bf0bbb41532fb3a16b088bbfec6d746016d2d0cb6069f3f38694175750f0a14a00ca61dad4b492c12ef3188de087f10a26a8e39246f519ac6b7d0bfd0496071620abd6b6c892a9bfe0fb3ec8b26713313d3819fd04f3c81dbd734ff81a0bd4036c480858e481c8036804f509fc5f7cdce76acdbd8ec279b4bed6a84ddfff14388541c1786dd4f50f7845d46c208edda443e0b94f80d255ca33f71df9ba129da81595e0b6ee73dba53bfd1dc436c02e909e819b2c108fe295004308a3c4ce8cc4a1ae5346968915116d5ed4ec9233b1c4520f3e5b4b47398b49524e76e22216bca1536a0e31cf2cbf3ec097a6e3fb3a21fa09cec3da1a8891d7535941ab0f8ac77527ca271e49f9dee15afe45ad267862d263facb3e8457711911e19f6d89f36ee108ac528b5e17d1fbdd8b11974b0f3165ad896c3e9583633590e423f72a401c78c165bb7f8270cc1b53ff005bf6fda34358c8160286fe49dbf6447496c55fb5add00ba0007e77243a2911311d04fb46c807042652db21a5d5f8051bd50d3f657cca10c5690166c99ce986d452d60c7d0df678218a4826464708768e9dc48166951d2a654dd8fbe894e0124cf2419f6bf60fb6af26c7716e27a80549e17b5bea5854757f3ebbf5aee301c748d7f08bc80c36288a021a04b00c3a0b338ed806c5b7c93e704470cd3f5109c4d6aa848449beeacd55dd8ca83720819258cbf1ea51d49c973640e6b917818edff0ce97ebcaaba3ffb47eec0a36a8bd38c12eb6a273edbe1e1e778bfd4b2be0df1bef1adb39ac36fd86eb6ef6fb54be7129d8cbf500b1bacf0318c96a1c19446a9110b26a7865c3e13abbee49569aa23c6d29d4162f3f84afecb88464aecac65d180bbfa282dae56d4570a393f215c37d906c08a449d0a334b1932389c181ebd2bb6452c59bbce711c721a410660ff00f6789556630da5fa27732c4b91962b51db7a46b598efd9169d9d147824a1f6a875feca72e7a7bd9052c7ac7842924230c39839d224ceedeb2fe2377096b554a7a8b15ffa7884fa6765cac21a4420b67b24ad7345338dc8a829b50f9408aa459db8b2479b13ee79672511d900271e0598aa993a67db2df9ac4371f335a0236425941dbe36ba05cc39a130c25634985cc9902905a0dcfff19ed54186d415d6478dc08bf7a90fb1ea0544eaeb299829e4140dcbf9230d9d2395eb496d4b9b094fbde68bcf2ab91216f133ff565937e2b4c2d5d87ab64f4fac71d6f028293e4e95950d4d8d0a1d19ecf929323a91d71884ad362a6ce88503ab6d0889a88086eb7c3040397a3591196d10654981affbb411b67410d87bbf139a5226187b33a14a1a24fd962a4185ba85a3d81ad526d96d9001578a73e75b55e0a87bae1528d841a783280b3f5cac510c099335b057429d3195e62d456cc61e5615d26c1175868b1ec62c3af559379bf3b6dea43301621b9ed2894d89276e7749ebd293097137bbe4d6575fbe6f275d50c85a720f2ee0a67f546e0853ca706c3e977912ed20dd054b004bfe3fd9d08abab001ec45e5a38c0933481c87054953fda0a803e8cb1eb592d429aa698a25667500b91dab12a36ea22fc702add2891968e1c1e8502ffef93709373949e8f9924ec7168fa252dc8d908ba0b2a8a8f07ede0cbc3c3e5c53d5d350cf3f6bb60080b35bb2a42bd1a0d666a4cd3bde1d98653fd5646757b405d092c01ac8d9cb9b6dc3b729b950d7b26c8aa8539285e4ba3debfefaa56be0bf8c2065545e08e4151dbe56cac3250cd8d0a97d33114609e7f94d7693d0442823797425800f2484cbeae58c9a217a081161f29745d18ae98c29e016da3d5212f1875b64dd2bb411fe4c523921750ade3e2f778b11023c5c811c4d07dec40ee8c6c5902e9638820a63a48d96536e3d4704cd121756b93218783b2b9fbaa470e0f92b5704354e07a1bea1098a8c2db697beccba596b34b408bdbf8ca6b04214579173fa51e26b9e40707dc4cc7a9d28e72082fa273e0c7e355959ff7e5a648e98ca4660abb9bf73eb1a3fa3a08fb9a9d91bc2798eef2e8c8eb50976afb008068b9de0eb695151547666729d3952cba025d2aa214081ccb5f9e4b92336e985b37c0416319f0ba952ed917786e903aadb3b9a912b6cbacc5b9e0db71d42993c6b5f57327dcac7cdbf43f7e9fab02e3bdff3863df700ba6e6acca8333c426549cf6f93da58c68b3ff740a883c6f665f1b0d68922d6d6260c390bc353b58084ae3feefcca2ae6315f90d82e64d0a073b162086c1c69fe946764a1c48a16f439275d73580a62a9a2e629d788293f068871b17ec031151054f97e07786ec4c3092604d98db07210558ca7419d34c7a4289477c492a550c02155d2d96e1e40cdaa3ef44e96a512146f6d437dcd218628f032d07186ce4d7b00164197d3edbf190d7b836f019b4bc86882ef9d7003da7cb54761bd3a60e4506e75adbf333844a60ac8246c3bdbd2150e3abb0ee789ad1b07031a3d04660bcff96a8838173ffb304eefbbe06a3f68cf66bf022f68f603d0dc0e29c373b475d268188128b84fe6378582086fec3d8cdc0159ee410dd9a8a966b6e0848c333c113777e3bb6854aac88a2e486d0652537906f5409bc91e1e38f82cae75dfd93867387d34b646bbcf1062e2cce397899639170af4f09ba791579d9389cc8f770d8e34c8a5db809b78e8757e616640ed56c1e4d5cae93927fdb8a5dcb7c45fd5fdf2ba830ab58db0660f679af7e344f54a6f08a3a91b370abac711cb7b88cabe7ccbf491b9ad3810ab497007a7b54206bff5b65113e429711045278304a508f26c437206c9cc841a4585ed82211a3bbcee85664d68b241d3fbd9232545b8265de12ba119e4642ea95d4d31af264538c2da040aa58bb6220128f34d240d64a9381db1a7dcb3c2e93736c6775035447b9c575c07bc0822f5dcbc189fab5250711c518032e0df18b585501bd604e0664a9397251b7e1dcd75dc6ef1d01492585223e624dce889ad98c15c92fa83fef47551f3527c15df57c99f122c0644be3746aec42cc23ea20a98d6d4730bbe099c3328fd0cac04c39d4cccad6089f86880022b84ba9d926331b81dc0e15bb01233cdb27be8815377c7609dbdb9aab22a7eb8b79b03484482d5d084ba9d302099bf407bb722ece770a679c39f9d6b43414566feb1ee0b09464e5d2d87335eb9e24955b74b076f1c219a66025d3b44cd8ac06184aee8b53bc563690f8bd0cd5aaeeb418779a7f0b1500ca823c4f5d8faab0ae276e3c4e8242c0f36e1f73a6cb76078c1ec7226f4a260f497af8c6e038747d4d764e7ef70b423c351bf5878f08f839f0a0fb3ab4abd196491a331e7d480a9cff637dd0591f665fc937c04e09d124e336f92b60a19c3ff7541c10d095b752ee1dfa9502106378bebf4c7668e2b8742c494c65d63020404ad272d2dd682c1c96b229c73c7db6459d2c39288494ada0714dd66688bab3bec76282ed72e886b10a7d4f480c17e0ad53e83da16be9b329e7841555ffe23b786b9a7ed12bacfbf9d050aa9b9bc65dc907cda9a8f53787261f37029bc45fd127d548fc12b92746faee9835b0b6f56b96ecfbce8915ab20f7e2604a87f6b586166c0f94cfc1f2afc20813f3d6556f42b46d427f65b2e413fbd727800628b0829825d74713a8a721301e0c0788dd8c8d658df8208fe8f92358a6a302619e37d84de2a5e3018e39a1da91d4ce17aec9a5a76e4e57bc8888a29c1b13e8d420d3bb703d0551af54fef98f12ef78b7402ca5bd825f2d0df5690e50cc76a65689c9e72b2294d86f911749a21078a89d59b0731310783576d10f14406ef4dfba6c6f656919063e4f5c90f15083cf86cbb68c6b56909d740f147492526d92284816f8c831cc78e42ea2a0f2d385ae4682a43f695f11dd7c16807e14975ac9f1abe1faffc4223487bc64e0899158b3b3af9bf2c10438422867a86e2444fbaf2a4601de91b5934cffb870df997ea64047ec2e671dabddb1f284f14dbaa1959debba21cee13bb414f6d0e4fb4f40b6ceea68743bf414ca39941cf3cc65df9d6c948858519205c9758a48d6b6a14080473af653e61d54e9c01220465b75fbee7fe7f5556bbb9fff65562eef16f77c6621d37d3022c145e6187916dce693b16d9995fc5e667ed5d97d0e3891101ea63f397a25a541a322cdb4800cfd5b9c7ddcf9ca3f5ca3cc56f99ee96973c076f8237c2fec4aed905c014e51866c6cd5cd41cebf392d38d850eeabc61c9bf087694be628d2ab1a0850d8479998cf64e36fde841bb2b4358b285042dabd1fbe6bc315f1b700ab35ce058b5367a2e1a4d1e63be4d44df861fbc4e32218ec8c9b44ad3652e8ff28c9097586e113d00ed3400880c2fd002dfae0a2b517033208a9c533cb5e044174fad61a89caa5f0456970804a17062e61294a99a6e5937a2dd26c1a8294f30845cd19e4f63923743c2c69d9897d16e3e999c3092bdf860b0814dee6acea2d88002a734e3fddc839cb7d1350e356c60e455039b69d10f25f01b4ada2c1559ea40cf8a80473d4fbf870eb6386f481d2b2f77fb418ba89496cef3bd4e2f2b1474bdc0d6e3c85951bbe44525c3d4f49c704d9b45a3fc286e2235c426920331dd09145a71acc5c044adddb1911f63eff5348fc93bae10e8d175ae93e9287b63f84e3731110810d66d0a2c4799d5347be817f3c54d24c5dd59357c91380a88a96ef514818271a7c6aee1a1037288e986ca956939b1f39b6da6c1aaa546c8c1f14d15b46762c56d298519dc17b8a0c5ae760be8e05b55ef82088e56b0f465ab5fb4c8b83535fa7e80ea36a9f4d65997ab5b459d385641ca818d311ad1b412e87746138177d9389d7945a769d7b662286c018f97b3da964e1d2b4342d8376d1c4b2df2b94842482adc934226cd9f42971f9ae201adf996ef175d12b0bad7f89a280027d0b3e6af0be8fd9e97517d1b3c6f941d7d006320d3f5e2f2706961419b2f8d4c492a00f1bd76ff2c282e8a8112b7cbe0a789eb672df5c6b89e6df3237dd9e8380ff19a265e6b584f92ccecc1ce8a25cbb9169140cf4b1a8602f06dd5a674d17d713950b20323d6a3cb87784ea88f84b28e08d455ef917f786f16b1363d2db1b987435d90d76252bbf6a7530a88fccfadf1dcf4d6fdf4a1c6cee1512b7bdf5e345d0215fd1c301e9ce056a2aec51dcf5a185f5f4c882a99d50094ac5387e6223ae266ca194cbb284f9419b5214238450fe3f33e7c8793caf98f57d6e200bde002a3ee09124ae539a53cfa2855aad1a747bad66fd725017f9d140b28862453dabcdf61ba94b2886e2148da27cf28927d2d904af68344b1deb6bd46ca4d57dd1f759b4bd81e508a28c80df10ac4d8e9e95dc44323d9d212bce132970a75ef52986c2a115603a1c510ba2b92ad216e37e67eb45f99205a13aa23b99258212362d398afdaab965ad66cd39d69a4c6edbc0a19a7a2b615402fda922500d164fc4caad07721e6affe1b106e4ea7310bae0bb0137504c47431cb206c1a815ade418e428a36b2c326918a62f294665138bef6a8acb38bb050066eba5570f5d4f0b19132c0550bb0e1be91c2d1d2fa23c7f10ff36a410a174228aad8100d20f5bd1be17ae240ad0b12c4db257a4a98bfa7ea8f54aa805dffdfb1b58455694f5984bdf44f3285e2d4da87068c99b416ea916696a1a9ac07f4c8487a7611f670cf9a85a420032c923380b1fdf97c44b14a12538570e2164a8c5db2b988e4c47aeddd6f62862a6bca08a1bbb5cf9875778a1caa97dd289a5ad4bae0415eb2e7629f9a062a2dd3d610cc35b8645a7da24ca4953c2867412ea3901537b77157ccd7375686caf4c4fd14eb06e26b512c7623540f55955cbef834998c3dd811e8fd916eb292193d2874923d311d2c55ac47038c569a22ebb23979825341909699a18851f0bfdaa1f542d064343470e7fe2f3a7493938258e092448c891551211f6e8d646740cea0115bfda3b58e4e8219a7e7e25f4e606628c2ee144af690186f9d2b61e1689413aead2bab3e26343d273c28f442826b47c90ddf12ae280f727fea436fd938a1040a96417508acb0e5eb8fe8fe8e5e86aa6afa5683af9c62dd7713b35756b010b5df1f2c5d553b28011471afe21ea373040d60ce23a8d8bb8fd5b34d3a39142e23693a720dc6093ce6c264c70b2041c2fccab1611c88f0a5cc0903d9b65646ac1426d3d18227f87e1030de879111762cb285f8eccb9df8f705bab93635527efc2db20dc19374730185e65b1b2150d775879e3c2e97c7207b332a75e528fa8b6d72102701809f49928eed327b4659831e8d84e9611032274165fe56cec828255e9c33480f64867b822171794a73cc31991915d1725d8ff1144f9bf21235fdaad32c07d2918a17579cfaf33848cc4a8d433bc324a2aa915b8b1173a855541d9e07461d56796d8b041f72e369541db9aab860df73ef46729a6c96f86430ade953a62db3d6e0c24bd35ff743d2a45f404c813c9184f9f6f8878abd7d26da9f23571ac317ea6e117b9e28aa15e8c8f2d4d84b74cc90ec9949bfa83c355a2d5a7b98e08f062e17842ffa1d510aee6edbbb0d2c0e8345b504cfe54b7c9afaee1f03922b84ff0c424f540ca5ecb2fca60ec0b582cff1072f8af3029fd2b28c45ef055b7413696af39bfbea3b9511011d0805e5193920059509b34622b45c9be8a602d423823c8296ab70c951cf45598ad370790442e09ab8d1d19ece8029966071c84ec38b67cc345ac6a2b70db45a16bff28cb5a1c56a21ac7ba33da6012a03cdce984d9bb4db7aeea0ba650bb47b0905ac919e567f94aa0c44374af9f6e66e7763a8dd2896a3158c7178c3bff3aad05f3c468e6afc9dc84a9ce39a9a7d5a96c0a15e2b4cf403705c8969f37ad645d41603c146b505c99e5292df2911a57d9e75a71a9aa9446a11b20d68e418dc24c37bf393f47649bec659723f095ffe65121dd074b743e123384a1a9e02bfb176959e4f76991aa2e832e656146e5d9bf716afe7589f5b4d0f8bdbfc33228b80153deb15f986ae62e8cbf519c435d818c9041e7c3a8c3d4ec1e9cb0f0e0709ba7b642a1495af2d0af615d8f807122ff7e58c9d47e8a7154145a84e674a26283782b8ab902a7eebf3ee46601aaefea1c09811d1fa24558350587fd5ef8ae4432a17d358bc41e659ede7af42e511c9ecd849deb22d964f1b968d67d735e5c136e53f662c3bad23c8fefe075d8b857db372be10bface120c0cff68bef08b23cdbb90544798bbe57003bf53745687c68a7409502506eebfdd7fb0bbbe02d27c82419d7cec69e69234a320f69f5c8b139e45019f4c81941966cc9a43ca3dd10c9cb53a03a071d4ab21c19394ac4a03074582be387f219c8b45c6b63b187b7f671835c3302ae6a4df43694c3a042eae61b510bb2e626ee0425e01d3ab7a6f5d13bb26337145a39ef14839b93151cb76ddc11241db222dc358884a94952fd6b21c8a9bb32b1d0945feae47fe9ce637c8c18987f23006cf08319ce4e285ddb022c5d744e53c121a4ab8e0810176d56f21a8f39bb7397e8a4f456935d41a1e29069e7ccd4ea7c0dcb112705e0cb83aa85d139af056da0e3884c5fa9f267f2ed27543932356fba22466860e5fab409013f6fdd8ba4892e6db0a1370d8407777f10e0d008b25a0a894fe209d8748388d41e8aefbb14113cb06ad9eb00fdd6f1bcd703c9b8ffe6904511be479220bee7ae2c0ba7b2e4c717c6ce75883d56df489a7a1b42dc770f64b96bcd3b46624ff992969efca8b6633539a1f865ad36d5a345b0bc249ce1d184725f2cca2930327a343e170e2ad2d3e4a132992319dfab2c4f733bdc63609909130b62826b380966dc4ea394f5743f09fe9817e3e1e2ebcf9d66cdc7913f135e02a8757aaf5f284129e973a8cf44cc2b204ab4fdae7f36ee872149b7db4107465ed0975d08598403a395c693ed41ae1f71bda62257d6d0786f55fdf748f21f7ea9819c13ff2fc7319333f6a810de3030070fdb665d535d88877cc8b4d0bc32993633eebfce54e47c27779bc543e52eab11c3ba373ccc72db56003e87659236c05d8e41972f7b6a628557462681d06ea231690c01d1014b36f30adae8dab7e0b5ed95b631aed20dd07d5f4f89de030b765e9e9d8dd7758fe0e9bafbbd072faa303ddf2f71d2f0d7e7fd9a7f593aba505126ec03cb52100dfbe73f7460ff628efbd5b76eecf7b473d25a67087f9afc563929a6bbd5f2adbe85959f43977deade39263c91591414d3b5b6a01ca5873972feaa064ed0543c58d78113587a1f88f6af0e4e2be695842741e8962b9d29119f21d802c226b6aee210a4c70f7c47b171bdb25cbbcd633f4ef8136c94b58dc11c1ea09d46725621533cb37923846ced90fd26582fb1b4ff7f7cdb09ac5f49b9232d3543b0f42af2e9ba02c822310a84e290f1b6194a2248c0fbf5c5ff9e4b74d2d0851d6b2cf06a6d57cb140dacb9fe83c887a4cd9b69f737df6941dc4f8c253d303bc773f3d486b20006e99a01ab103a24fcd4efaa4a736d88eef5d9094c38eaa452c2776271c3c26c5d6a814f2f09b3bc8f029da09e6a8057bd4f556843916e0843caac18b145fdb667f7c9a39ce5fd0b629e7dc1e3d5d6c9b29d1a623c3a79c8bd3d73bad6f5fdebfcfeccc9aadadb6012295034459b07f6f74479425153ed6497f4a6973f70894f40adfd80550e04e1fe145f8ae9aeea748dfcb97e518155d3fe1352c0db31c02b0e4eccc1fa56e24ef922e6f3606742f5cfb02998d104a1b5f605688e9c2ba50536a7392e6bd1490d55e77188ea3b82632551420a74c65b179061579d4648f42f6558c2c4eb3d8883250ecef843c2c08ecd0b6b89963adc20f150e8fb0bd51c390b88f4ed8efe494279385d6c547e1512210213c28d14df8f680d6978637a0b4cb8ee9db83cc87345e0449cbb44e65deeba34c62144ffec33cc75a80d2ba5fa4767db4ba505b8b578ab1f49473ef84c1653b7e57fe85438380515759bb5fce96cb2060de215d68f1148300036faf5ac0df0573de16ea94b606012de9d1eeb35fd308e12d819c781ec9fd9229d207b2d77870a1687465509dcf57c5ea01ffb6ed6d904ac78a34fc17da7183cf1958a3d72695f25c3a623c571c689a958e6b636721ed238463a5aac3cf24a5b5d83389fc0f8c4cf6a4ef753b7ea8861e2e4250a75917381eb95bc80f2d503d54a68bfb4ad8387965bcfd3449e2834a8241b7723f88492ceaf95f40f8f05199922efae2bcc138a6a22a21595d58dcdc8ec2b0fe91bcc2e9a27ec594ab3230e0fb5134caa41e0036b94d439106a814c824b3123229fb41db206394241b8efb6a88ed6b88e136ea593075b057e574410475c92d653d23e47ed4d6c5502baf0d2baa525bf9fa73f14628329217950bf7f9c82064cef1ebe5a9544d4b7c7e8396b5622f5f740e3ddac4aba0f691177d598a48de06d31c1828b0bec7d8b117e2761889d75034e39b644b95296c20e8cebdc9c388568b338a44a2d695384feebe26b5191c49d228b0de296727c2a6687041b797b3f8b0a5e6dfe6f33a65b6963412b847e719d5b4701d0cc772bed81af7e23c825e402d3ffb991f614d0278800f5c9b510af79a37b1748edae97f713606674aef4244e34b82886fb5f5ec8821706fc157b780055aac51025bb507ad945d6a764fc59bdd7d527573e9ba4e575a4c4fc47b76176a8882f13a281ad10a515e92220765922d24ffd9cec7af1c26788f580641bb3367a7a04e4d79efcfc617b6d259a2a55b4aa8f02b296a3193bca61e9e509eb2583eeba5339881fdefbb93d17265b456b3bd3f9efe31db2ee61f64637b3b604b09d1b6620708984a44e074bf3a70080a2dd8df09003bfd804585e2bf31878ad5f706c07771fca2e2d1af21a80461c4b70a7911d42eb3f17061ab6407cfebd4e86546f1a72a1ebd7ccfa8db29b3aba394c1c3bfe132378810956a7a173980dde1be578674c3f7f0587f384f7e9d32c592fa1b4159bcfb60c2ff43bc7ad0d598839c681a2195978c3eabedf4d82e9d33f1b163efdeb3d84cc7886bba46b5018d75a0bec0227240e7deb874865427490ecb19070dd7a15971ecacfa3d66d1c5d08efccb7a9ba7238eab8a560b1a88a12564c92922136ce469c10801c66a350071990c23d5406051367b89ef52031a46bfa18ac3ed3b977fb62bc61aeae45c1003749e3827b4ed0f3d2fcae7d895b25efa2bd7efdd0fec7a732ef4100bcb990929cfd27296a7fce845fc2632091c76b5e63008aca5ffc1c7c80a66daf65c63f432f17effd5a862493c808da3d20a8fd5699f8a37319d54c423b565ee35c533308694bd6b47bd973b5436cec0b86bb0a8e94481499f3926c9c098962bef457ff54970a5675b8adbaf787cf22c798e4088503ba0cb32ba795383749b05abb85d649afde854e3a04bda6e799877ed3f0a8fc6033261a22e310ecab75c909f810a9f1d24a1d9c7024eea96be42fae58a43b1a6d855c49c22136a68d82a41723c085799362363eef5be472bcec26aa61012f813281823adc159f616e87fd1ff0fe5c3467b45b9d5df06c85eb7dc4c131b6c17f1838a6aee3e35b091c3a45e206b05d0e0779eadcc4445b31296f6c05471213c2b57abeb3252490ef7ddc135d32d87c9139d5d0c0379583f164cb36732318ea6fd606415003de064691b75f1100c2c820d516ed213f8000fc255a4d5fc4a27b7741a88a20b42b513dca5356318f071143e93cecf09fe4fdec0e99c0a65ef78a58c667594485ff25d4353888dda4af2182f3c0828a855ca9536116df7d6f2fa353ba35ad549ff5a1a4e765281f112b851f2b4678b4519e34973e8f3b51b091b7838ef2512d083359d1728e974e62b592038e92b14cfc9eda0901c8dc414131ba27eb15e1be605d8c277fc9c8324f62caad7818ac194f4c546d484223d2de3f8a2f4d15f070802fef8829570c10bfac92a9428d27b10a8f63497e436a3da05c8e2eea52e65f63f821820143034b7a3c9bd6bc0c2f9dcb0caa22b36df23ae4afa842f7bd13f0f6e02262e13c37af67719c67834da802ed53d04c7bcfdee32b4ebd1d952e6d4bdb1830e806d624833140e61fe73034ae1fd6925796f755fae94f3f9db0b6825b638c1a4c25e5510224048ad14af55cad237c1ef3706922f6f0c4dac94689f42fc41e6974d6f2c20b8d367b8276ee897ff0225f3a2793a74b3ac0e5233bae45247596ca3a5a23aca8241d9c0ad6c45aec67c9a587bfcd2e2050480a19d344fce105ea201fa104c577efa3810e6a56d7cd69a8b3c5bfa497991d8502e729914488ba5d332d50f3b8234fa84d025a03197a3d4c4a6468f17ed8d62135a55161885a422a79ca344a621bf5919fd6c0146b254583fc5288de304543f82c476781ff90b24e01d805971c5f59b33250e29adfa4e5ae838e99e04076cddaae2fdcf5c11f611a072bf44244a31e50e0329c22f94ecdd2a89e320a5b4249fd1140225956ebf296a33ebdcc873830c6b4fffd399e5dc13a5908843a0386862c59b37df5fcea184a7f4a5a78abf6b39db5f56e20a38aaa740a492695852f818083ac165ed6fe61287e77bc58a2aebe2bc02d6c90a2a30676caf5f54dadb549de46e86798c4fc62c3626b00d018851affa80e93d939b4e52fabb1660c41cd9e420f48b908ec8f8d288960e8ba0938e23f219492eff471a7e4168f31d341ae81d390036c38c4ea220e0683184030422e1d3b4401efaf4bf91719b25ce00ce557b5a9e32279d6cdf9850ef546c3667c938fb61b73d49306c4774d15dd11c76cca5f26e0eec70abb74e85aca16b47a80b929abedf5b8b092e7e20ddf9cf3398f44cbf152d0edfe623f8a813ac58a1979bf89ca8b5823d9f413e42e9b88b80c27479091e3792bf5ff7b57094c9a6c30c5f39a61f14ec0e302daeb4e97e6ea2cb59bfb2c9151dc5e7f053001b2fd7c7cd294389be63d9a9a9f46f651d1a0fffa94328a457fd2a205da1f5da557d0f6557d94d3995e728feee18579e7288977d59f8bbe56da0e1439e63efaec398c143e0008ced5b5fb864ed35d67c2697aa3cb2f937dbde19e307d2606fdc1eec9697ca2d60f05752b9ea0b0d7e9d41b057a67ef781cb14f589e43f595b11f4143168ee4cf065bc01c097d546a62fdb9a1d53bf5067af3f262427281e02bdb1931f06cf680493835a88939ab2f606226008d62a66e76dd6031f7a36c2aa3edbfe07123ceba926b796597f44a1e7422376c7a4501a905190ceecacf6804e72bdd69e4e39a6111017044678024d81833e3eee001db908e4456e53d4b3ac2b02fa8834f8d0097b973700df06ea899dea020a8ca2f6219cc1e7c9f5fa15367818e54ae2467eb05b2c958cb47d57d3687fad3e41813158a480c6efeab89d7775cfb772b7086e0442d333eb1558bde5084f23748e498a6b0418728948a453ffae1b326da0d4e181e22d1f0d0128f38ed935ef8f397bb533795c9b3d9abb8280dd2dc78ea298e67cb3ca435c6e8de5e943a086733110f25df4915f4e5b3f36fcaa25c135b705a06e27af6fd70bd84c8995375960d262bc5cc949aae2ecc894c5beeebe4dffca5739223e34eb3c7de9d52ab474130c3b317d3b2f2bcdd7f9b684bd6f677e8dab4386edda1fb7acbc461a9466505c0d72f8aea66123e8a46a98a95beffa681ab7e111fb7d6cd5755e6ff466ddb8c2de501dc323fa43fe84c703dce72e0c1c6fb942e47f79cf1ccbe9073e5759bc713a2ebb502e01689b2726f5f8efd09ddbac1292006e8da961393ca2582eee1948fc06fd4f522eb85eff1f22051529c14e29634631111026d00fdfcd41264816caed73f9894b51afa8ab06f603c221497c3b53234b3a5fd2eaa393b1d0418859452f39b0c15a148aac4de4e1320ef4c5b940b41b9b5d43058274115f48f003a220c90170b047b6b78825a0835c87230812f0762e8622f9dd1ae6736e2c112376557898c145302274c9a8063f0bdc40cd5e490f526bd60ba804a9cace7e8610cef99dbbbddc5cc4f3270be38e84964344cc6b43f036895f7481c0ab7ec66a44c6502860993539a5739da5a0c27c0745300a0ade949034358f06e1e83404610f1a505da9886b4350acca111dfc0789e39a5da982eb4ed4716ca5c45f42b932411f4710d0bf853a081d1226060f6e241536cb22728aabf1f0ce001c26d293c88526ce203815c633df06c10d5614b60fed99684bfadf67eb49274c0dbd29e25bb94f3b6940acff03455b9c682d563947e192c8f0a53ae1bf80006b36614c890a230e833080b081ddedf4ab1efd286ed93d3fb4390e344f6a8f27144885d4539bc25c3252e2a490bf076de42040952737b3188ed31dd1020ec49eeab80078a7d6908ae02e4817e541ab40d8e0a2054ca1c72cddd4022d044922a65ba60783b26d78f0c742c94f98ac2f4ab8fedaaa14355d2a161c76c27eee98d83efafa2264d1106fe7309fac372d5319d514b83d42d15703d2aec95d5ce14f57a0d3a1a7f8052c53ae8dfcab0c00bdc10bf757be6eb1af93b268716a48f73629f69a07d9750655a2f9c26fc879388aa39dd79b10f51dac6644f15f912935070f071e6a4e2dcc1aa3994987aeae2901f3b9fe9e7aaa46d5322045fc16789688b5aa0ea8d692d24acd975444263675264ba4c430e584723ae997bf4885961cee71a920eeadb2b46ef920581e8ffa7828e00b5759438e2e47b7d0569e08cdd992e2ceab722ad63ca27b4bcd200ff099cec09769471f9dab5ca81395f4d4273454b67c148460e71c97672017e33d4e9e106b2b1bc47fef6e2e1ed38dc26407cc21c974cfc9f050a4f93915ff4ba29f4b9b7a5a79f656d2c3967d80249c41d1bb9ffc633d8025c8500fb564685e35992a04abfa14c5d3fcc4e0c7f9180a00c76a02dd0e102a4d2a778d609b690a90c869e49522fdf10ecdb76b388fd52968e99a15f4439689c5837b74b3b16a8814c68c8a86a8f6ee8dc21baf6fc4184573b0a54c35d621128081f1440484f6adff219dbb9154a6c33713525e587112a6cc9e2f45e3beca7a7983274aa4cc358aff8c84e60dab7e0d8ce67829262b69a74534480ef946280f481f52527a3701ea43685d402e2731e48783699aa9fa9ddc2d22d1613b41a225d48a591ffddb69c207e2a96edce7f31ea9afff2a232e6ede2279ba237a6b9a66adffff9e544bb3825c8e2cb713a4b4c9665a5a58d2ffd4d32aacdc5b11b73daf7fe0386ea6d56d955849141eb23859d98df4bddfc4fa0447f926117cd344fdc8ca27b1472a86e74393a5805efb8b01bb5f03c64238f58e36301e422260d0829bcadd4d1b768739e0616b671c6c3e6ad96cf36e629734b73feb984b72fa166c100357cab6eeb5be4bcfe21f05d687f1477950673955cb32d6a7e21b602bf6a9637939b095a0449e7a15c322a4ed11c8891d8b4889409726dc7013fa1265b4122bcb1ce04ecd0f50b88cc78c32289700451706fececf969109de48bff974fde2900d426af07fbf234ed6e5be26430efb479f4364400c5cdd3ba545bb2ef2b5680afb4b6688975e058e9506295a51cba9d5fc701475124d4059f1330d17b6e8e4a08aad4eb5a435129cb92931535b0322daa15ee5715dddc5c6da20be0fe352cb3013d07cb1f21d427da21a0105abf1d127a5ec63fe783eb623a1ff90b65094ba7760dd0cd2b9142187438b44591ce4555cda59992c3fac92c89885a4496071ef56f00a884a443aa2b3162e35ff09cb7798d65a83e997d9d1b773732a5a56069c846784db4e10a3152e037ebb34febd0b0abd6841f8a9d1a72bc98acbe7015ee4268fb1792a0bd823900c96ac8a690bc174ebb3b25aa9f6e874dfc19cdd25d4ade1b442f5e05455b7caed7b30a67c0c23ec2a3d762db7aa9cd40e6f82cf287dd08f98d0a1ae40337cc1e5191e5342fb719ffb1d851efca62a1180edf7d534cf9af2f7f33e247b6ddd65e77b2963cbb09e98054220e7ccaf0e988d87e14f9793c5c2d0c9bc20bcbd4ce6af8409164cd5097f4141bc052a0a26448369a1b02fbf8ae95c5500164eeaa7c545e077599ca74e783bae1aab9f9620dbd72cb4e127c4ade4a845eb53f283e3c9c2b7cd3cf828a23acf54895c2d2c5921009e0913b183be070895e9fd065f417a810681108738bae902536d34bec81e961de39b6ef37dd8d25101e106c740437c21a3ccf04567fe071be80ba40984df4b4732d7fe9c0379a73c038fc71fdeb88f5fc30f1b15e370e5d5a2640b342ce2cfad7474d3995ab55b6d87b85ed141ef66597cf19c4aab6e3e21f6fdab29afcaec9dc52fb2e77d569c31fdc79cc53e45f957455e4feee9dd73067d5a7ef0df84cf2bcab16e0e03c95a9c695c19e0ec18d38ddaa15e8256c347dd2cbf32e3956cd52b140c6c4aa3aea4530b94c2ec1dd135ef28bf5f3daa9fed7286cb4bc9f5fc2a62423eb1368bac597d1dedd90bb74b61ca60f7800aa88105fd4e412efa32c0ae7e90f26e70b693f400442fb0f5f2c9599112e1e5ccd5218bc1bff1f8264769ea01c7bfff4c62b0509cffe7163cb5a5e5ecf5a3c6904f331e4a185a4e7d4cf121cd578c5e160223696a60d95801003e5c04fb5362f82872b55e28c828270de62ff7682c1c878c544061e04d22d5bac56de4869ba49cdfde847978060d390f0857f59691e67603c65ae2f50d7a7d474dc8f4d1e4816cbcba141b746b932634f9b347df30b47d9dec7d84bb0ce0396e68c7648d245cb075160bc161c7e7c81a9a8ecf1946e6351575e7cc54293963f174af2922b094359f1e29d63694d1d81cb84835eef0e938dc1e2f3b8ce890f527b68abcbc8e1e13501d71d6f110d27be84133589f9e3a68ad13284300bd30a4d6a930d6a01f707a59453037406d9a669496b25905e4c5408c6e2db16f4035e1a890c4516de582ef6f2b39b095019e91e2dee750a61251174386086c81db5d917c58d6eaa0336c0e5c93a489a85320e9b63cb498ab227902aab60dfcc3bf71e47c5d77bd028ae37c3124d583dac4a19305b8d48bbdb1886787666c3a37f8b8081a97ea4fe7a2b43f2da3b90ae00b140058fb7d249fd9c70441f3e74a4c13a1f37c2503a1922842305d108a42fa2380bbabb7c20392d3ff9af9b165cde227bd20ede93127f7b0ff9b47a38b92d956cd0d2d036d0ea85a08f7442fd4165ca38df625979e29fc2f21d97a1e80cf81a90502f0d9041e65a93d2edafcb0f0a23334d2ed3b9fa3d398f47bcc67bf42d9f49680b342b46dc5c229c51b92c7a262af30d044a63d8502611be80e075bfb4c2209c0abcb9b2648af5eddad4198cbbecc8184e6be985ba2de46e23ab4675302e34a77db7ae2f544c56c28ff3d4b2ad9c6652311efda28b190c9789d52651617c448e61d8110595cd86a3d51fde3fec89b781ac4369c9d80bad03687f209acde8110ae9be7fd6e824914bca21fb060bb94109ea0c1292e7775794d3085a20ce4048f968a313cbdb5ba80631659a6b9fd25bb545558f7a8e91610f3cd676d1347cb360c2f2f873139d7a650c83cfccdd56ba246c2f04d314b8aaadc6a44c6f9607fa4d37c75abe1b6d61fa4b00b6086cad6016c96a3366c623bee7fac160d9f0b2da34e4e5f903c74db50f8906d4886d267d1c9b413fd4e265254296a112a3c0549e13800ac910cad1129f71928698394183e9d3f3ac34a44185852c5ec99f5cb2b68aca565485bfc173e6a5d5f636d1101fd511abbaf71e9616157f643122cfab554589e6861db150254f90bf905b55743fe2e0b3b30cb80b45b8ef788e18eb643ef89eca182e81f7a311bc052dc55edb257c8a783c38e62a15714a3f5bf66f37df727253414ad92be21450a856caaf64ffbc6608d5dfad6c02f525be4fe4809038c318c21cd6e3026bf5ddc12df3adb5f5b7fa29dfbb585171046b3384615812a5233281faabb318f85cf8d7a80c907b10593413b27e02f0df4cc553d97caa3e1d067ad6dda1d95d8356f9af161d12584093ab5cf743f328976c1890c1cda8a856697534a58096edf914eeedbcaa909b7da68e698f9986e380afd893049e976e7135a9225e29c8d9d0e1b08732c2968356206ca80982e7ca30ddb6581c646126e6dbf8348e6778a212bc95246be01fd8427735120483ae1672b56ddc3d1113ae37bd167c73df60f5d530e2b94adad332b591b3174fbdedce00272076749f3158fb920585bb52b27d287e5f98a50209e38e114ba6ae615f0cf5a26d08cd5ca863422d14cfb42b537dd8ff73b38a9bdf6ea562280d161566cada45e2710922e0694fb5f62842d113807f38c86cdef35c51255dc0fbc65811a7bc9209d56c35b83aa3dcdb7b2691dbfd61f98a76128347e664b6765dc0021d0c566cea80edf0dc66672e768edb8f17a4f559bc25f337ff29b653ae15bf8b2be3f49aa752ac952f9cb7ae16b26178f36dafa6a70c4963c710173508b0f27731f083b2f4089eb35f3dbcbf767a1e2923f36f8839eab70a08361e8a96509f60a82953fe4333bdf502289448fe0a697ecf910e75190f04af498f83e6f3874b2be30548ee8400b1633653a76a5c9fa9ede2c7fe0b71bcf5b83338c26be35b39ae44bcf5942db084b2c3126c00734fde0081f293da115933c50081180b957b1158666e16b3b164f6bcbad419d9c769747954545eba7b495275d5191e57c2a1b9b86b5d6139ca9d125639a8e865f6574558209e62f42526d5204782e596660a737282261890a5cc5bae96432f60e520f81a15960c8564885f22dfce7b6ffe1bb3a40db13f61dec52b6957f956c9a72eef90ca68cf41f8511490fceb2e712058368c7c6a7810d1fe59289192fe8f040b58ce31527e6e6ccde7884a7a5311aa2f9c75b9be0ffaba235d831e6c82562bb7a494b898860b063a98e9d98dcbdb8d0602e32139956ec2bb3b32d9ac734e982253eb04ef0d3138ef865e4f934feff7da0e8f43df647b42c2fd7d8a252dea2e835e785859dba12c42e609ea7e4464cf4b43045f3b85cc881cfe12a56b66a0a95120d214ae1e7a8e8c241212c6b8c0036e6584a2f96e87183ae2bee2cd3181a08d520474bdf747f783dd6bf05e274cb5fcf64c2ba5d9d53961d8ce24be1917c234d6c4488d9c7b0e7801b48f9d08e0da780205edba7397fd1fc006cbe214ede3687125a8bcf3b50f407a501c8035ab2b75626ab7b4331471469b343b76aad672ab4cfe7dce790071c7ac74c9ad606cfb59fd79388003d253b48e8f04253835ec60c8e156610d02b895b9f274b2fc93e7fdc150e2d3e77845cc8c284ae0337fc4c3c675da1bb28209150bbde3024e58714a43799ea98815bfe34ab21f08b6c6bc4911a0182c3ad98dcfa6c5a7f4d4389aa7332df249bac427cd74bb6550d5f3ef23b1b6f68fe1b277c132e7ad4c56dca6482003bc1013d243394dbdcacdddf40c404e0375964fe2fe0c994f8141c7cd6708f638f34bbc644f3cd97d4ecf9993918a99ec56bebfff907234b047f12ffed2713db9baa5451fd73f035e3c370a0ed2a9ed4b503295979a3c1252ce0a0b6aade304b0013fbeb089c3c8ef39be7cc7543550cee034ab196ce81f13e45a6e473f582a1eeb247603917bc91b8e83dc99deea34da0ef1eae31933a9b45db63f75b7a689451043eda378ac4d194fcebe5dae19a6697a2b0e767e950b7e83c3d41fd3855c57314b4f3bd68e5f8427ee1edcd5254e5cc246795bd662bca3fcb1d120914824c2f54ac5bc4a23c477ca9aa8d8f6957393efa3c4f0c1d3fa6fa445d9da14e69069f209cb70f42d5a98f49de8804e6ef89a4a9c342d271fcad2e74bef1adb6245387698dc0be3c4e5f6b41c25ce940ea703bbd61eaa498ff3b645f12248c0a1bf121add21e17962ec12f03631fccfa1e2bb4a0142eb7103c0cf628e56c8103fb79c43182c081b10e7e62e36463b2c6a728ee0c0c4b01001e43b8d81b97ecec3d943ad23895863a8dc44a801bfaff93e27b920a061f2b555efa5efda4d20716898da6522d2949822c345cb282d03f4974ae846800355b8d42a54d59c09b85a035c352e99dbe11c2992495ba2e8c4b49d1d034868c9387ec3f605acdda45e779252b0f3cd2ac63bf53f203294035968f9f1820b741895aa0ee4a033ddcdddf9e60cf226123be1638c2ec87475cb38f79ad7bf3fd2afbbfc1df005d3fea946024b58044bacae38ea2fa13e111bad27d60bff312044174dd75e0dca295569a9f56029852ab33862309ceb7137f1471eb3e4d5a654c1fad2e339ddd8b7c4b10e733aeb7a1f31ae725d6b091763dc4a67c40eb5e7a4fa6bde05ea8bdee888bb23fa0e5452d2e24fca970621bd6ea41692e1b2e96ef7d3617c0cb872aa92d360c07ee15876beb16f863d1bd8159055be6885fb6331547bd0a501b84e1105ffaab774550c0a6dc091a6c1e0f7367b343fc0e14dc384b562c477dbbd21cd347fab3e3670012e85ba1460a6dc0086da4bc83168645950d9ed3857a228f57b067e4a93901cede3898751869ac67f58fb1c16d93e1f8607bcc414f7ac5b7b3984957e8ebaaceee55365be83edc52012eae938e837141f2a0122b57b375cdc4abc04cb81297bdc1fc1c2b6fb33db6ee3a52902915fc6f5e99f082e50c5280490662b53960e77383978dfe32e56ff0e28e3e651dcfa2358bac2166c99d657be48658155db08aed18192f9f82d0e9ebd1b37e24c81113ef54dd1ef2e1198149fa396dc6660458e1aab76ccf2b568fb4d3cede8e6cc409c00ecb5340fda9d18b59d983d5b78ec50e5095a2ad2972fca0f6f0424c5ebbfd1dd871def43e935fad93cc2074a08a61164a7d1adfa00e9bf542b0f4800775f35dfb7b9cbc346e7aaf3707c4d19c194f5eddcaba53c3ac9693098d0a5caa012d526f16a618700d47873c5d8d1339771111351f1edb8ce725a723ed6fa5563f7d22a01a16a6591191f63358ee36ac2eb6ad4811e1f60a3a7abf16548d9cc29db3f8b7df7f2475d736689ca941dd082fb6d1fc54daed91e4c992a3aab59b683149075235319a243ee8e5b824404e7971641539f5e9aa4e986b2b7e4675c1d9fea488ec2277e700ce110d5605c4504cfef359ba03ae98303ee3fcd1e9ac1313e515cfa87f3f028977603e1617c80db678a954bd3e4403454201cc292d1a2b840127dde4e6391d223d2886227ce9a0c6b00a09c459b81bcfc6ef33ae7793fa5322e3a99fb292ed0ed0860221ec3420156537522840b710c682f84b9c2a5fac1b5c9ca577b36a288bb0bb483fd5d9826f3578154f52b698d14e0117373b37841e0664847378a0334ecdd9a6a34eee5e046dda5f6280c8bb7f67c3d123f0003091b74dcc43b3aa07abfa1907db5fb5e028095ce44d0d63e2224a1ad908268a2aaf2b2b9128712c56ac0e262775d25d368502218f919784b78345bc6d8a54968464b829c224b5e6640d6c8d144535e2aa9cd48712e89e20b07d1fa0ca9e89dcf627db9eef6ad57d9a9489d8a5bd1cf626523afe1a8b08110a83d44370a84ac45ac1d46e47f430c25f6183c5ea228ecf75b88c994e934a839efe73f96eb4196e2be18ff8e0b03d45524438cc59741758682aa46acb50acf8231c9d57cb5c10963f9bc7f2ecf703cf1cc27e0c413387df23b300f540f5d043b8249da1486791878303354c8331cc4f78ce14483faac4648e7fd40421e0bcfac674d5bf36feb4aba5b8cbec4db4d42494946c963ab85df24f895aace685483f0050aff0e0761c809c05b496a63080cd57c4ef23432301f843c7a69bf98f144eccfcf031daeb52c3f06b2d364495c5c2017830e7b3166c645ee5000ea60d3a2062e4bf84e6a6b2298268b659782ef2a673f4e0c1a845409e436870ba75622fc920b7f25f3ab79246fc4b50be0c24e45b18fe9bc0a9180e5906201025b3c2dc818e49ec762dd9e581ad75ff2c34cc1d07869354ae64307c5e9a38b4ac6a17e3fe99c06a16bc45d89ae5ef19787b810f485fc8a6f1dcfc17980cf788dab8ab48479b5fdbc6ad33b1b9f283ae32c3142bf4ee571440e9c5dffffdf77b3c04f32d8fd69ac2b2c93236873c65e048ce1936fa2fea1eb8af7e4b4812a53edeed19e251708d05a7ef488b2f9d5958a1a10dd764c6b3c558cc00dece48e161ed020bfadb393c252f09081d1b77b56c11df15799dbf25bd4522390af4765aecda63fa9a1a47363a7ced633679d5b8619b4ed629d04efc882a6c36d0fc7aef3f17713360349922733a6d68331151c510fc38c434c50da3560e20051a10b12f3926cdb38c3d5ddcb37124e7880116f476122c6d1ed271ffff97c42ef8d6889fa6566db513a1ececec86bed8c20e45a88a6329e732d0dbb47bcf7ca54802bfdf0392999c360aff2b55e2c9f06c1f24a145092833fe106a27cf1cde44a555cfe21ce2c0610b249e8f89995964660a0c367b70b79b996e42c132ac2c1d5afacc77a6e1cdec6e496fb79c057997b1054b17c3d5b34874f5042bb1ab97170f22d9c5b340da2158ec050b357de4214e4791914ba1a1c65ccc132dae190338650639196064282cfb462d09d43919f43755a648b6675587910ec34ec1bbc3dc130b0666f23d8ec82b4ae7cfd8e36ce8d3114618732624c31e9180fb98819003b65c61939bbef048c70ed68027909994e9d9957c5df2ee14f823dd5d2b6d0a2b7f840fdc443e51dfc08a0516c9485105196109d343bfef51ff5e2e01c4888d01e040643ce417885ef4c9e979f2fb7ad1d73160ef97b1ee41ae0f31b3a41457c2cee9133ab7d8673a193ebcec033058d6d3adf7a98c955ab594dce7f6e58448ec1bd38506cfcec61df378b7b3f1600f724829381c3a97d1d757ebfe34b010927b6202420e1f034283f423ac26804a88f3ef2cdea0e27c7994fd7abae5136b1c69b125bd9b7013825302de1a536eb6a1ed0a2d28ab8e4cf0b4979f7af8923353670837b82c5fa4ab7b032ef1b8285546c5f425ab7e9d5a9715bda38de9dd01a90e99ba3afe689e42b1daadf14017f34d7b0b5091e84bdcab886b50c3959488b047c33e06a1fa142260ceaa7d3903da79599ec052d76b9baab39e525c15addd3d0668ff5a61fdb50f80cb02dfc6dcf502c2d16501fa87c07aecc3be7b7d6295ea9591fa6dbd38361d58ee48fcbf6778afa06cfa7fcc19b3ff5e3b1f2c8e22e4a1a2a90d63b7f09eb97d6629f344bcc572800062b014e2c624b594865d0f1ca6116fe539d6476cd32d42d84797d54c783bf323c223732d7680c770982aa6713ba072f9804cf0102efe1a1010f2032b0763cd94ee13b86b6378fa35fce5f15fd82c724d99dc92b27db4f07a0316ec75c554709c519c9834d2a84821fdd800573e5d75590fbdec856e74a4d4149b999b7dc77f055277e982f3754490bb1beba5fd0b3c7c0bd48f6b6d670d6381ab81c41e40164fcb2944b5cef615f1fa2f4c53846f7975a1954df5ff49740a53b2f2b752ab73f6b082fc98636e0756ae8b12b36a94c517046e3c5bf3f778e60c28e50848bb5d8e1f7bb82ac657a3202c3ae3c6388d6677bda5203dcf65564a72326a76b07e22c05d7618e7d5e3fea3f8217f453bbc00734a4c31df8862333d0636f374c03f4c557f6c71d82eff6ea1959ce47e6ba2dfa61c8de78ea340f431c45d02856ffe813044421a5f2bd71442d12d25bc2321897d84b193befa9d3327d5a7302880ef053f6ab2466fbd8fef11b3fc5f881ecc930e46bb90fa15c6faf549720ba4cb229698318dc00268b88dd19d0d71b581ae99da4d21d5dd2a7e2d7fd5622f6341f805792350f14e24593c2011dd5c158b514a02c9cba7b6aec8815f4185871bb0a6ff682821075c7c285c09effeed586d0b656c3808d5fb280a1efd1edf3279935d5e6eb01e6daea3ae4d0dac5e141790a9b38dc534a46aae4567e94a757733c7a517c314a1bc3539c7d8d5987209f249070b8168a19d174c0abb1312e330c0dc829c662bd6e03b14cd80a41f16a60b96504fb17f4d4ad73aaac0c010ebde3a6ae1d0b524d20d30ad67147d4ea8e76f5ff12a117d7a7304949738c0ce2f0a611ca83348618ca118e3771b7756e59f624e1d3b22ed6882f74362f64d5e72899751cb2c138e60214856efa3eb59b3df29d45f1b048d6b0ef6c35226b7a1b2f1a7a61b8e7d4c7ce4d3061c9ca587cb1b27bacf9c2e447a2a90d2d0031433a43076701a9aa61c1270a69661e45fab88e820b20d5411071e271202314fd4d404894801d1c45556ee4e071f48530abfe27f70e114e129196c0d80f9298e7ef4bbb922f1f0fd3b7912adca7fd799225722607544202ed284ed90a900f3d4665cc6bd5cf7b4a690d0474cd3c4ccc8d40c401b2f6c4b739bdc5564314ae17538b78d4ffd10f870a11c0ab9243b8647e0b001e4a4a31fc4ed2b1cdfa029e56d0d1752db0836048a4ca6aee31f4f5408a7649a2dd8713d66edc77507e5387cbb6b18ffcf7c0f350077a38571200d549f20c6ea7f1a08403bd72b3cd7e11f0f492e4a12381579766e2b0778302ca9f2b818508ac0598e73d3e889142927d708ffff64e1de9266e085d697b67efa15a2a70d515e90935d7831f5113a836c0505646911f75ec681e1d0d37a57187611bee2206736fad5f1c99c41ab5cd0f6b6e5b8ceb0bd67675f7a1201b6dc7f6ad847dbd3625a953a27fe0e1f366a62f5a32d2e25c7fbec682b07a66d3b37a2085442ed3f69033641a65f6aa0f0a1e8445936d16d048ded39114c9c903b7cc45688d37c47be89e9a56ee541d1692c49c84c03f75ca03d6d39d1d9b4c44ba395f1de5724a5072df7b3636c8df97c2918879c664544e56f821e18375b988b8ecc2593e7278b98ff5b1704df6ba64cd8a244509499535d5bb8d8855dac72b3896233dcf4159053d3835a6cd2943f3217c386d41c06581464f00a22e0fa28a58f3163a5dd35803249459282c10bef8e66b413a70383853110f2c0874553b7d11e9b6997f5088cbd4abb5f574a8b1b1b837d1732eb34c6694a0f8eec7ba5d0a3b0b7ccb2af4941e647cdcbf6298d9fa9aaae3b42385a1b610c6e5000c86323a10998d08e65a57778b061456611f648b3c9cd0c752662b87bad22397c9d314315b0b99f00ad440540356a827e6c7ed5984a0d3ad387461d4609e6d3217f6cbe46b6b1a56bea53c0aeb84adf07ac0bf95750a18cb44b2fac610c0f599a1f1d5b308890eda7e88817e18118652226043e66270e9ce473d5c9600fe43a45e4b012fd27a34408191acb3ca78a9f6b1990d7fb525b6b2665e83b47a5d76938d75ef5e3a98a0cf2eeb26dd12b1f1c79817a8f2212e41f78522851da7b22fccd32df7b76d8f23fff8297c98cd12cf2763f56974e30652bbe151af73a0cc60d19d310122069d3d375316b17d861e7f61c252c0d39e8766044621f59fdc41f62c376a2737ac8f811f7757fe743c3b79e76f66e5db87396b145be5f8541eb0fd9a4adb6736997d656eeaa28713c2be37a3f17ad54707791d8565a7e23303dbe2f5dc0d8d8355871f3e8e947285ced290a78debd07a7a232826b38d5fe4ba7f280fc53eaa1dd784d4831d9073938b51738a29cd6b59e2cb7b2aa02cd56b077413ea4072967a0c5fe120361b29e37cddcdfc13ed3cb67ad1e11e1edec8aa16e700ccc42cc1ef58f157d4368beefd110fe38f0d5226ded4d9250378f8939f23f8139844664a5a8e39eeaa856bf7e617f01e3e454e5bfd2c52fa3e695339f53a79757a7933c4b10e2ab1373f8897a0580933694068658b0bfb6a22295cfb4bce79e82f85dd505ce343f7d3c2107128a02285fa39c5d0b461241020314ca4d6578ba8ba43011018df3059062a7ea54545f29957df5e55f13e09fa3b4c2bbf53e1c797a1d89fa22bd7e65331e62eef6ce88e79b4d4f05b10ccc0967b3d7855fcacd658a2cd5819af226a71c595b927127d74642d35d8e2f5711f123ea090290ddab736b719e763a8b58508af761eb2cdef060c7c1b16d084a3e26e45990920f2aaf4d8017b002958d4b60b4ca0e6bf1634dbc2af8daad90155416de2001cc42d2057285bc6a5e3076b73b8f4bf068be3fdbc71dbf1baf2ffa1c03e4f0f256709971d88bd1a4754e0c715af37758d12edeee4949650d907020c19677cb5ca7fc8fb74756d0b8ef6cd4b25984069bc75254e60c318129ecdc44ecc8936bd8b174b5190cfde24152dc56a222cc4edc2e38ba4460052053f22dbdf41cde341806a5afd45e7f50e7c082f8ca1b7c802729b5cbf2b2f523027474ea1d630718ef53e958b1e59620ed6aaf2401ad09d8bd2aaf16e5a582aa5583b794a18e58aee42d82050b17c254727869cfbec6fc98a861a0b2fbfdd3a0f7f3e3840da5779f05570eac931cc0165afd48428c1bb2b12cde7e712dc3bd673252e9dd486294b0dd162a1d411756825ffb21860268c91aef9a35bc85539b0e398bf9ad4781d3b6917781331a2d7804da017667690bdfa108fc57be3605a7470ee3656e20242a016c7b039a33f2745d301232e21ca55d3a289f22414084b6741bfcccab332962d72b2b25e5f08b2deb7765db0d1d28997e126d3130914da58363886a716485c314843188678865c14870d9340cda4fd4408e451acd7d0885e0ed857ee9a5a546922491324919460727073b073828a0c5dcca021b204e8212541f4060ab1db0a93e3bfa97fd91464664ae353636db1332923b5b9763622cb646b20f6e5947480e8cd67d85edcec260379c5968adb555c9c8c868192da3adf04197b57693a9063862b5aa62fbd79aa7ee5b6badb5d70142e80d7eff0740206fa173706fcef75a7b73920fd41a2535876ade803c70f307aa0728abbb218001895985092b43d8d2b70e5c1647ce93b20c7059f6c53fad8be4303034751467b3e99a2dc7e529e9451bf46897769ca1e9563245c9f76290e983bc7c8d9737bd805fead9adcf829e0936e8229d250b65d9231be040bd197997b2f2df78965a83c50c0e039fbefcf7414c0f924af49bfe234dafa4f42f4f5b2974db7e373a1794a68b5ae3eff9631fcae26f0616dbcf1d3b28056541591607c6be0ef8a4d7f95efc2e6c006d755fe369ab3482af3fc8f7354825e27faf3f9855994898ee4d2ffa5f3e48e94da412f14bff423a8cf49aa4ad8e2c338c2519003ee983803aa5179fda992049a690b4489eec8c97c86c676276c645144b5f72f9d297f985449d56a8f0954cd17979d22b51f24292be5cb9944821334daa39cc841b74e941d692303a0db04135bce08927867cac8a44ea90c296ff90ee8661c1fa8fa376387ea390c9962dad243b47ec0e4222852f7eb8012259433287aea0db252d5a402582215284c876f3d3896c28b2514a6961cef7d5c7aabeb74e44693c84104aa58ff4d389f7d860afd7ab7aa3d108c77972e7b7e3b9083cc47c88c562b1582c467368d1f8b568f0d66aaa261ddbeb1347a5cad03516e5894f16339684a691c6b525080871db658db58674ec5d0778e55692baa53525a328a516636bafe5ba9085eb72b946fbe3403c5a1c5eaf97f6ebe50a0484b1d6e097c1eea5fdde7ca1f597370594a50465794159370b2f95bff4276e4bdc86d86e844f29524151680277e7a1acd28dfe92dba5bb7c860de46880b11d688ced39f8fc69e944f703ef054f418cfe7a39056e8fbef6d4347ad2b8591b4410358dec0511c40f9069cd958e05c18badbbd83d17fee076f7b502d57e5b33043267a04c28aa066a77b030eb2f1bbeac59a98bf791585505baddc85b05eae979bd347db97c894422694d22f9388a87d2c0506bdc63701258db63c376298d746b87c1a1e867915e24410e2170977d591a48b6078b8316b5f85ad424f1743ae93063a58345c811eb7205408c7b73e72068efad0658812e7d066eea456d88a31c88edc2facc6794c6b9a0344dea0d146ebbb972d66eedbdd699b04456e54d38d1752dae5b615d0aeb4d38189c6b61854be1339ff9f80c081f2b435441d5d90c0603930a11102402899e701c87f10d91b65f58d15b583588dd68a15d703d9c98798df57041261bfabff7e20f068a425dd435a1e85e9825746973674a38815a41a168554862a63424327fae42975fe6d4e7ad78803fb24ea3581e0c6540d43bea862be4f0befed78199b2bc86268ca1477b851cdb3e17e25ceb4fffffc16f64513d1cf5996652a1ab95f521d315a0ac7a631f9f4e63a041b3ebeb751ac283556b50a052bcecaa6706b01358434ea0523481c46af5430f388c7488898989898971c5b8688d19ad4220cb6136eaf27ba31c4f908cbcdc551b3818472639526d8abe124c50459736366eade5bc31f416ba6e8ee34c3224ea0dce58bc62bb6f6c06b757534bcf095851d8d7ebf5c257f073f4ba2c1eab6c56eff7e38a2a93c964f5f57afd2061649406892bfa8e2e755665e416fae2bfb75a2b448ef22d34b74b938ea36afc6badb5d65a6b7d551a5e3ff480c3f6979570a8167c6bddec461534aa1349e083a0bba9690a3b5b8af83a5c384a111f1c5fb925fe471a6b0c453eb70a92466702458b584b1c4318d05a9ff364c16466637842cbeb32d1e2767231cca0871a4e42862766dd959e34f20e61d8e81425a0e21a3d51e2fc40d25873c02286594b1c6f70d1fac02dcab8852069ac3004d160b6c44f14b5589f34d2249628c1d912470098d1fa50e841975e5e1fbb84dea06a0df72ecaea466ede1a5af2c628cd0f94c6c9fec8d236b12f1e47b996d01a7fcbe44626cb4c00972e2f4cf7d4bc4455288bc3a55d63bba4349a16bfe2aa167cc65f4606070e1d25957128b25491e60cb43945e7a69b0e8431aedde81b771db638b40e61d05aadedba2e17d1619befbdf75e8ebbf7d67aef8a43d172462eeac3d4a68d55b946b9a8e1e5aecb3977f988e728a0d6f823b9592a9480da29e048026817585001e4e601dae140c3121b20ae980fb1988dc5ac4a46262643448b8c4c2cc87d28cbb4b155657bc5f674a38d92e2a2f4703c5a278e7a02035d5d8e226107fafb5191fd6e9732323987381fc5588604aab23f58194cdad8e895e41f3da764f4f919f0bd1764347af771fc61f8229964f4e127f94664926fa755ba595247a5e13e561572fff9154a138e30171c45f04390749fff84bc665db6b32f59d6edb32e6ccc0547d554068468b39869838468b35875cd5cb02f57a2de5c236a8d5f56fd58acde228468b398cf4059f55534586d66554e44e433a219d1ccda6bedbd77667fa034164a95c9408475c10d0a12b11f6644b86005b1984f0c081f2b4354f9a927d451ddbde51170576e845981fb111d952020c40835fac60a138246bef73d2c57042c2d50dae0ec0368dac6e6485a83028bede10a36762673786ef175b48e26935825b2c022f4e372b5c027bd8739ba8e9476030d36d69e70d44968234466d977dc2f5716a033fefa4484d2f88370862682c13e15d8c2b0d97cdb74e8d84e5c87cb1954a582a52e58740a7456852ee90c63ac6301f55352b41d4fbba680d0b65a1b0bdc9b3c849b1e91de09c99f6cb71afb81aa9c09dbcc36b3cd6cb38ef459b5557ad2cb71dcb58538a050ff6ec1554e8da3363628945eb95730e88c3fb8ab8f1543073f0051858ced1fc3842e1d763f55aff5bab91187cdbe77956363c31c667d605aaa6a44ba1330bc209c2747a96974fea4165592dc42b499c32cc9618c6de20a6c380c9bcd266413b2c19a00b1591510219b90edb3e19006774985b01894c63bef1302855cee0dc11cb745ae9a86350162b3ddb06b766b56f56255e05fda3d6df76655f53ca35c1e3fdda0fb7383c84db493fd64db4afff2d582a1b5d1edf2fa2b195adb9207981ec6861f44fc902cbdf841484a5e9e9447218ecd22d631e9d478181bc4e5c10f123e080f02a944f7f01aa3d6f99a4c2fef85393c2532d429b9f47c17e6f0b8bc7e1c5a9b69b333373b93c3735fae3374e9b297fed2db97de26db4555d520edcd44ba8db4ed20c7b2e003b734d002d993cb0b594b248cfddbf6d7248c257ff8e6a6d8ec8cdb2630fbba41e3173f92f822ea398e4cb9347d7047196f6db6efb3364a63c5b0591f7a6c76e8b49d9c2dba599becfc48608e21cd050ca7c55330dce9c510c7711cc771dce52e599be852a974da6cd8f6ed8c1c0037802008822068033579ea88cfdc24d700db1fc9db9a3f35862ea98dcae8959946e2a8931147bdf473a08f94e5a9b5d6cb719c0d895aef1572e26e01aaad150bc7c1dcdd468737c39c10926a4897b4765a555afb420cccbd9cf4c06ab095ce6a85c571d8e8185531a998a6695a950b4379c87481d2d8ff5ce8f1d2f57bcca0f17f3447b9d5bbb45accd0dc2ee9900b94259a2626e206949502dd32c849681a6c9f62fb7f90b634774b734b734bb3b425bac4e62cfb885080c781edcd53f46e1132361de545682c30f5895c455b749b3ecad02536afcb5169b88cc00719387ee60b70e34b3b4362ad4fec1b6134bdb89434490cc1efefbefbde76de5f0d4f048c6dd41aa1e3ef6aadb556dc711c08e0cc12dd91d7e5a87aa29786864cf242cbde30d18ddf697d33e38d718684a94f83cfed7f83bcf133af73e367befeccccd3904966480c7483dc69dd182936ed8cdb130794c6d66833236df9b0428ff807129a727846422d6b6d34d57aa386a7b0a7b0bf0d194f9dbe3e2a84afaf63c5c35322a4bcaf305f1f488ea7465f5fc753315f5f480b433c0580afef02114f811f80af6fc453e1d73fe2a950005f3f89c8e3a97f35f114e92be9443ff1944c2cca008270f9f11401806ad08db1caec8cc540f64920472047b2c4b4ed26b2c4b5ed4f80b14688339a46ba4d23bcbce9c544d62012c6fa3300d393f02fff99c611fe25c4791961847f19813c82b70b69cb962ddbe5c585ace638de4dc2587d6446f897ff5cc6f15d429c97717c97912cc263974aaf2b5076c9a564f708f6c9f14bffb98ca62f85382593e94b26d2a44bdade3d8e15f6a62ffda7c7979797d72f64111d9bf4527b428b4dd224b23671e11180fe9727fda7479727853824179727b9886f124922595d4802e0f2a4ffc4b1f46288432a955e2c914570ecd00694a216ec500cc9238eb274bb8c454a1ffe278efac31027fc50836f0243f0eed23824467ff81f38924820892c22b3bf182031b6d81ff8912d883a30e093c051fc4ffcc6bb4da229e76ed2a88208e287e128248bc46cef4d210b324ce410657bd407c8237ccf0b713cd01bef3681f94dd9cbe4ca517687a3cd97c7ef7388e37d9fe933e1006d8c79bcdf8538df351db9bb7b53c80202bacf8e4610469ea908f7a65c63f4be7bae9620f043ebc6bb4d21909d9dc92376e337852c6447d9bbbdb1561c0518a99d494107fde5ef4e67f5347cc00d6b86f973639c19054084c6408ef2efbecb9fbdf7463ffafe031f0c3f145f243d49bf2e7dc9e55d5efe852c2b09b3422d4d2fbfb35d7e67977e67ebdfd9a4dfd9e2efecf07736f83bfbfb9d3dfa9dedfdcece3bbbfb9d8d9f43435b97d17e69b428921882b6c9b6efe5913aea06a5e1b71c660cc1e46c1d1a096858118211581982073a502972d8d2530613514c00032b84d2f86313cbf00c9b1808848b31c7616c03b4c1d908bbce343d93005e00225c2e97cbe5c22e6bbb93cdea74729d5c27d7c975729d5c5d6ef2f19c3e062d2810412bc90b5ed10b5a53402a4ed09ae29d4ea7fdc2310cb3aa1aef6369a6a501a572a0f1bc5c5cd1e68ab8db08639e97cbd579f80bc58b2f16c10f0c41f0555d3b5095354d13c852b0441051d8ae7896392aa7600ad00b64414bb8a27045b179c44e1cf7b85c5eddb923314c0a8de6ee2e1721fb8f92f53875bd37bbbbc55a78cd3967ab8a89c9313934476161e2c7fd2746489755f69154e8fa967c800bb28e1e34dd95ac3fd4ca2e65462fb3aafa4516030d7d725f830cdbaf47217ae2a363bc89cff88dd3406bdc6ba034a3d1a87e1f0e8f2abaac3f5f0d92410e71c4d725aa721afca57bd0d6433bdad8345c61dc524a5f4b64f5b133fe2431fcf0495fd6af3e8e32c3af1ffe05ea9ba5b5d5a706514defbff7eecbefeb7fdf584d1f1168efe902bcf1f317f8799a8459c1fb4aba37796d7fa540bf5eaf97fdbeef4b6297f48a5dbf946981d2dc6c322f478c44af13bb91973bcf7770420b2bad17eaec89ac8956288a62e879b9f37a9cb0ba3199aa684a833f775dced6b3d6736b6dada9099121e6031431168bc562e2d8511fd02d2bb1f4221c67d09ba20af38e54426bc8a0290f78911721b94d310484b22ad64012a0807ae3f9500ff20d925ac3d23616bb813d64660a320b4abdf11effcd005276dde037e2aa7be8b1588ce2880189c58442b0c16e7817972f01b0eb4bc86cbd50a9d4600a15b44a2e24cc0e5aa5d2987dc7e5766aad18a8b17d81fa395b7b0b5f02c8a2cb6adb459e46b62c30344d5bfba4d7d6cc7aac3447d5b6d065354d913441b23cd55f9269d8f529adf547f9611f8984d2d45b2980ed91a533e1dc77a32e8bd4d8b6a4097c429747b87d8fd0361becf302479531b4d0a0a837feb2e0699720c6d812ad50699a0c4551a206259ee810011f6ae08419645009226af93f6a8949c5c6c6395b7bf801053472ce5790584b6fd65a7b7b985028c5f1e15adb79397b5ece9ea703c370858b616373d6fa7442e57dff6b3635544d474aa6ebfe30c61c17e2d8a72cdf5fc7e19f134a10f871ed0cc480215dbbeca85b4ae9e13bea5fc0c757180c56c4fb058c643e8cf10adde74fa12b42671b7b23299f915b07c394effbbeef7b1e19502d26f607aed6f732ac5a1f09634b65748fabd0199b9515a2457716c8fc81c6a4fdfa09b09a073127a8c494a801075a6aaddb4507fd32aa0550113560e18195320840fb22072f21a21418d1f29cad699664e0228b143451c045eb858e8a2cadbc63e5281e60bdd9416b54a20e1fe892ce74b4d61dc65d877187bbec511a1d5a631aa060c30d96503114c99c730e1e56b21e2ab4b072d46864330e71de515b966539852cae119bd266e02963b60aa0d3622872d063c12e411f36d0f6ab2579e868313103853f3f0a3fe816135dc67cdd7b98024e15d98ffec7e87b3be6e7c6f20887f254c6e5f7345dcdee9e878c477ac381bc47df7ba32f47d8feefbb7eff756017e28c78d027ce41d04110ac6273ce39e7ece59aadaa5ef15d6690e3b2fd82aa72a8eaed922a06ad51d880a2e044d799f55775913f9682b847648dc590b34e51a161ecefecba535074a6ac6a4393dae4bb5ded9a509ab7d6da1c1a8dc68d27c4a06dc795e0a38f98fe89ae9bb6cadff93196519a6ae5546320ab4dae544b652ad4afdbbdcf0f72802eb1613cb2f31e1c17907de34c76f65e47e518d275e3fce0182680bce5dd97b36f391c8fbca3effb64b21080901d017edff84a8239248eb2e50a73478ed46a963c5237a534f74fa753ce48bc2eaa344145eb85dc644acbf3c61ebea3870f14688d3f0278e48047adb55adb514c03d0e5ea9ac080e4388ae7e5f2225b445db47d4d704bc38ba028aa292b858bde68d6e5b2516071017194d384d46ab577b95c43d8d4b8d7938b139e9747df5dce5d672f18342868344ca3611aad624ce3b81c441c8d56c3593c757a6a7665469bd168b42b573c5565324721818340d83d3c556d9ec966987667180ba6095da1e52bdbdfde7b310dd3683d271e58747d0e638c31d7c36854d2f63cadaa44dad376a777a73dad285a22cdedd29e5714ef0d4fee8411bbeeec4ed353475095111fba1350d6f75b76c99da72a3414dd125d0c3a2a9d94ed8f7f50f11514fb0067a1acd19f78a82732b40e3017dce9a921ca12bf3bbb93b210b0fd3b22cafa82b24240592cc841b8ca9eb906aae2ce0e8c7abaa283fce784025d029a75c83cd05d0fea29c3b0fdbfd3aa6a4f0f77f670670f77e2d3aa2a10d009740259d3e66c6b6647f7f78d7457dda37b744f482201d98074d79acd41a4477fad68840444aa916aa4efcb7ac60368faafd85940d8dee929ee47d6096739aec7c2386b44b542d01b4a6bc4ec02caea605089a829ee896a524224396f34b22a9b33903d9d4e27ad61d9ac59b3567267876dcd3b01a5f18ea033eef94067fc9738a1b06715a797450c4e54b494ed4f1ab30f284d164a937f5067fcafa033fe3c8800e6c90023e3a403cdc5f6a7667467374469bc3b6d168ba53b39d262119f248ae28fea16c970d440fd06d499fa3530d156642dc0c0c1004a432f876b4dd639277467778e4ed19f0707c10a82e08988a3bcdab7d90209a9ad116b2d1e87742ed8388ee3b8145cb046acea6bfdaf9c731cc73df7d8b9b1c3a394fc43ac2a933dea1e42a487ccf5328284bb5f57b21c650b18a42c07b97bb91e2d38313ba9cd46878d4482ef47da440ba49c2d7184e1414bd41f2a091f049fb640bd55d09f81b40c3c8d2b589298275ae28363128a84175064ad242fe431f0bf70e3840b64015ffe2ea94c76a700ef052bd8611b5056fe23282b7f26ed0f2742e3503fa2469773e7d6da1d6c3085962144728434f1dfbd174609b7d69e4e148debf7e22bfafeca9e4eb5aeeebdf7aeee6a6504973b8cbb8ee33adc71197318cff024d4c02dceffdf1e379d4ace5a9f4eff361685fa07f75fe711a44b6aebba6e66d5fdab069942576e0368abfbaf1b85d819af853153b490215eb51d59cd26b09759ae56ab1587313e4fd69e4ef644a32cb731d52b2e149295c8042bf4b8bb2e672bb4eff264c932c9c73a811efde742477ca38454a0f34cc8518e050156e87cc5273de8b45089f8e18330f9e90e227ef83484c9640ee91b405b248f7dcf00daca4e7a6874a0b14fe935735f0b93c34473a05ff1d4bd4fffee1ada8a1372e41167a1de719c9929a18413eae934bf029e726cfef234fa12f57d69037eb9e2a1860f92e501c4ffc83245fa11097b8f2c07b0cb0aabb5052715d0ea09346a00249b7ad6d42eeb1992394ed33c78e9ee6d6ab5a936f5721c87391aad34d4991d15d3bca669324d93b280ea4d785108d2a3a29b3a546bbcc3dc579f7d4f2a070d3ee9be8e82aa3469039ac91b0efc0693e3b81fb8e3f2e75042dbfd399843098d2be7569422be1dbfcd8541bc25923c3accc08e7d0446876b854fb794b0eed2975c13eee51ccf50bde138265ddc21e80e7f6ee45c178896e07fc72bbba79db945dc232ed1be367badd019ffdbad45f16262fb7fe47d62bda7070b5d5eb3e79ad7bce635cdcef4fc2b7a814965d5b276d5ea3016f2bbee4067fc290e7ef0c042dfeec4755dd7754670fcfd318772d46a35bac27e2664319d5fdcb0f90cfae5e7f1486a67aa79d621995f51c153f5ed391b3a6b59b09c582ac638ce1347952a83316e60d85205ec06180c86df44598e31aedaaba61ceaa9895a91a82822320934945de9acae00656750f041f3b821cc6faa37fe229960355ca17bce07d6e35d8facb01859c4081118aa46316b0d4b0aeeba66972342868d236289883a5849ca3d6f16d6625c4f1e2b1919137d9b477a82162f4f35594571fdc4b3136b7fce212020740dfaa9f5279ff51c82c12acc7216b43992d09c8cccd97dadb5d61fb202398a874d97f53c2dc528bc02619732433f3520134ead060a6ab8028c99103e4cecb8a88035d10416566a9881bbe70f4c305e2f78093182225a3fa690b1a4768308769822099d22f20c9cf821ca367daadd528cd2540db43fad98f3aa93e5e9a9901d71bb214172cb19094eacc31dceb8ebaabb0b61f21184be8ee2b208d65a703402c1d1081c81dfc843a900a462234e2f8b3088ce7ce6334897178873e2aa3a0392712610d0120e5672346c7f5a522ce5052a2f101694cffb0cc618e393a8de7c2b10b46c7d7229e99349ec8c9db1f39ab5c6663391aff2747b8ab0845a6e9ecf2c0b96cbd9d3aaf279e69c6be053891a356ad420f1590343e32c58f089b19ce7799e273ef1e9bdb86883127b319174c98534d6785d1a4b4ffa1aa3fe97b1b6ec83f5c67b6a8d7fcf7bcb34d6961e6174b409442d4dc204d12f492e19360839d14a42224b5f22959492bc2022d19ad2fd0b2427ad29a3df697de168c4a5baea4d5dc2e4cbaef29ed0461a7ff8a694260c49ea3ae8d27b7eebb05da53bf19ed2bbfc0b384ad18a037ab305f51c5095e9fd7d0cca0adfbdcfddbb19d40e5196efd3161b8bee37b242a564339acbaa5cfec5c6d49b6a5fc63cda18411847b2d6f8d718fd4da18ebdeaee94461ed2977848af513ee37f479b71a43bfcf528838d0c5f02adc991c3510ae94be32bb7483ac01d5bb51f88b7ded3d35343f2ff7bb80f151c05244747480b435cd0a49e9e1b0bdd058d16ce8dbbecddb0b972bcd6bdbcd1885579a40f1580b430aba6699aa699bb919a6627040d8a582c96bdaec3b1d84d18baac40fea4c78b307651165efdf9c102899d8102cb1135a81a5181d2a85b627ec30fa8cf70c21f3802bfef4b978d7a3ca8eba9e44fac067139a8bacc632e93618ff914a227b11ea09e582c56495a93dc4551149338eab41a2255d31623d01cc642c88ec83ae7fc61f0e244d148925056a58247875be1ce76d6e6fcd5ddbf25eebdf7bedccb7196bbf8a34b3480ff48de17a73e0f17460ad01a2fb60bac58e5d05639339049c061425ad039b1e4d06094721c95d4141f01fa97ab5f8d201942048320f8234716cd712af8e8211b42c4dd6d0526708121634800760e39cff33cab8ce3bed1479eac0da13b59d2638f6379769e28cb31c61ce7514e54566fe8fdd2c178d9a0d083be57a8dedc27284b76679cedb1aaeffdfdd4a361dbd6aecfbe39d51af7981d3dfe19ed24443e2d516c005c68981538ee7766ea8b675cd999210ddc5ddae828218708b19c63b69e413b9503f98c7fbd7964acdec82a3c46696a9ab2561b67cc9d1c77ea21cb162a58fcb4608b019078011a5670c1a4870a1450d588ac355b3b95f576b3aa0a74abb750d71a7ffb852e2bcc1f885c6588988d25baacb0d89989b4ed7cbd57e77154965d4d3d78bdfc05f343dc9ad2f873f8bafbe907485356ed5e56a57d86b2c49d6368a04b7f595b7150cf33a122a8d4edd814b164342200004002431500002008088682c160403422968cbb7714800d667e407a603898c7634996c34808420621e30801000002446088a48815556f13df586d503f4dda04decabfe7e488438e36eb3147fc59ea966366b4800e0502c4d208c9c6d1b4c81ada2eca0c9b7206cfc86435575d67f572cff46faad374886f6e19699ae54ae45bdb318e1902dbe2d05d9b96dd110ccf0b41b63d7cad0de6898c61d415499f73d8e339c69797f64460c6960a98a40c4c27c6ba305dab995b3307779c5d056258520f2b400458590e4b92e3160a3f1997e38865d698d0e5905231bdffe92170c31a6d399ac7845cad18066cc28280d31d0aa83bac1cb6b4e54d7ee7869d8bde9c595b78b3b1654219455f50cc8069fefe90ed7adc078df251361a53c4843a43b31040cab7465a14ac338eac8054665cf86cb825d978407e151bb06d0af33f77597f38f2108830a307e25a3bb08da9e85e04e578d9caee77bfc6920b4ab9bde37d94e2f31ec925b9ba676e780d5babcd1d81ec5ca2c12d79962ef530dc44c6acf97795c866063ecff1ab4574452e68e544d2c43c443bb9aab2108701fa2c6c5e6dbe9c1e61a04d16487b6e93f739a85d2af714f8189c44c601a4fa65210211b5fb5d871be2e4a34b2e2ad7fb6101bd5b8acf80084b1c205fa328896e5e8156e16047de4048a646edf152feafad3f9a9936a45409cee55cf015fea86b7f7bd821bc65536bd68504338ea45bbf0a1adf065be0d20293e9150ad7c6996a554566d5519382a9140b2cf5e4c41c66b52bb0cc1c5a7b3ed2f9b1a2409afa2a3a7311456971a98921bf6136f860e5a6e13106c7024be9999260feb570c8fac7b9b69b7ff03a43cf0ea353a832f327b973feb561fefd8974f2dcec0efe4534f3527be969e9357f57a687ea4b8226cfd50e4a64e8b95e8a18d640fd3ada352c47298b07b7d0f39778445dff0d0f2948b05497dcb4012e54fa84208e680601411e5e06cec9509120ace9af9a9d5669a7d134b768d6fe1b1e01786ed0f7ca017aeba201f30b2f5a21530c692027f418fe4f0c3578d1a9ec962576994e99dcc4ef9dc2445820a4bda38fbece135fcf4864ab1137ad82e13098b0a7b4977d6900391103c1c03e1a131c910aac7c149afe62281bf7e9381f734d238210a69d9f084fd5b367b8779e0032c514fe142ab7a0cd8fd39afa966090ad3cb5d727dd1f6b262c1f32c50758e73d608042bec7615a43f712216466232f9dcf946142ae5297c64810468e5c8d131cb25fe4f430cc10e17e105f11bfb11037050d62832e765dfdfe0cb35ed92fd25bef27a8152dd54fcbdeaef4812aa7ef915116dc3cffcdfbfc976b3cdd0a26cee14534581f61811960d7a157a68d25185c01b4298ff2e49352307fa8e0e6c2197d97400c7f21508c89368a9f8f78eb4f5a6a1c5fcdb22a0f28a6e385fe03a3c62eff1d489ab5b2469587ce21cc11eda7563eeabb62f42cd2693b153bbe177f120f56f3e0a8da4cfc75b0f4c1c81d0d40851da099cb6a15c6da271cf6c4231b74868e45cd829c0c5f940b84e4d0ebb2d22f14068c22331320c3cbc9f0440f92684559af6d5e501714bbeca2c28da46af8576b3b64d6703671d8e1d0fd868789bd53939f17f9ef5f8888edc2f5517ff8ad6fac0840910a2eec7f24ec1a4f251a3afa0c1c2624d60b01c00ac7c0af0b674bd7ef19898d860cfa9405304ec89c4d1504a072dfe2cf2743fbd43127f03638eb9cbc53c62ccb135be9a7f04b4b193981cecc81bd59da0095611e2a584d5843325c965fbfe116c17aa2da7c499548db2381c44755d50f9fe8fae7ce3c5d94bac80b583df98dbe8c5f54f3c1191a952f1069005548c7a3eddd1fbd775dbf7bd82e947897eb240d628e80d00c908c79e794bd25bb9001086f50bc621d52bcbb1298b24db2f6803c90404087969e15431aa5eafb676d0b29f96aa082788226cbcfc6eaef4e215fa0bcfeb2999be2709d2d190c8a8b70881f23c8b0fa9fc7fe05b2546d4a3aae7545ab5fa28d7579c8326445079485669f36a1a904ab4f6b5985f247a3c091d0f50fbb1602fb6b11f6290fba1ad3dcbb291dab0f1be7de419c7b5ced2a87f3bd86618138d915fa6df4cff2b3b5d6d79a3510af0a291e475a98a681591c88d722475e6a11539270421e595e55371ce1629f233e3eae5be65682d850ff16ba22fd4762f1b7912814f4826277e05fc2d5d84e6ee9df8208d0d33d17612d97179951ff7f09101be38c449498314af9a071e2c6c7f55e2f0cc6ef6e1feaf95573b93035d7225f7fa30b9a95bc4c2709a4aa9550a02a58c29c2a14255f66004f06b94d4a221f14ec7ecd21e5b1bba1c904d78c574aea1391e4c60493a9696885328915589300f85d10437c80efa82c7abb1bd7057696daddf042162464f714190275fa005e765460b6c6589b2ef7dec0bd9a9c5ffe4ccf903d6c9d4a07624aad83beb6977ae07ad550f360c202e8130e8afd0172c4bfa13f6205fb467697d5bc7156e9df41862c9d75a5a533ae5d07d5142ed6d35899eb7ae07af60b92f481a5f4a63dab5e2cf791eea9d22b8bdc713859136d6323824a0d72349700f6b723cd2e580e0306ec1a02bde83c443875376bb873541e484114481da026b9fcf4d8b490ab2a831ea1290020061c5fc55381aae1af3aff89c8f40b7e4311b789a36b5ade54f765a126e9c068ce7d0a4e2b9e9891cbd29613c34c04ec501df7d719cb2bdd750aa4898d2d6128e861f3ee98b1e2e32e34c74a17b4e0845e385f417663d9945789954df57ced27cb7e98531ae1854d6ff344f4317be5b7317536163b002337fd44c5897b4fb5e6bb0211668433b7037426619cf9ed1465c7f049ad5f60df783d0b383e98f62bcf0fe17f752036cf0c350a0354fa94cfb0fa2c1784286b557c046a4c30de0b868f42d28ff305515cc57a5bfdc33dfa18dbc122e062b6b47771ff99fa3da63607af614e11dac4effb84489b0f2967784600734953a125c238a4a1b9678c6810143a5c1e125ebbbfefbca38cca2b77588d802092cab9b868e77ac690389c3408e83c2b280cca98cb08ba15eb0ddb6246f6ba83c3e3577a5bd04bb6de7b1833d6d380e6d3c68a33fe81dd886e089de091288968434c51fd0dae1643ce7bf54711137d5d4a69450ceedf77fc8e48a1b271e089553566ec7cc944461cefcb39e0fd2c762652d78e8811299997bb52a49539c1e506da2d3511d60ff36f05ec2a4a7527b980348efcb7ed20ccf82b9a2a42ba621c440b7c76bc5d6c82e553ec78c3828a075c9941dc8d6f88b950b387c9a00971a97617a399990ec86fb359f0dc2f658fd17d508bb45512c29162240eac3292426102f702b5d3401fd4b506ab9c458ca272c3e48a96798788b8b63aab713bc4481058a12c27474462d8c80428bfa45e64f383d53cecb08e5b99acba1dc9b5191cd23bc297553665c842f9f8560ef737949788622390562ee4e19ac43c660056cbfd9228540fad7e2f53767bbe4ac709759fd1ee5fdb8312f4738deb170a0c64f65d7f3fd8f32e62a250c31dd903a45db7bc0be551e2285e368036136ad590a4adb3c49b5388ac8da31aa55004dc3f77296bb9a4a97541690ad3a9a16111e0057d9c0af102417f4b03f0f3c3032a8dddcf075e6b725a400d5c146a628d628623b023e177a95385ba78b62a7d9f82eb21c5c5ea12d38e32d7311d8911a11318f8f5e1c4865216b14db30a183569b96485d488c3a1822e7f5f6d09e3f7178faa329ab4bd5318262742095f50418bf8a45f0623c3fef1f83789ba04a98e1ef8b92f4563df9a3c00850ecd58ec30ccf2ad3d9182bc6fe574d257fd277ee46625d6624c6e5be878f486ce20a953201f9b4cab47cb945e24da51f7d0ab053c0a486d94158936a82f0acfefe5a5869247f671d55364acfa7e334b5b12d0c33964aa50e09485f41d6853a319ebca608f472c416af4573552225114a35ed0472f16dc2c8144a0ba4dd55e1c20de32fc9b9f8b6755b752143ae6e410c7418e4fab807a8738be72dd3b5a3f5e0ed0bd0b960ce19973f247d5e5e9e4bd839424ec4ee4aa6acc6d809e1732d2cb0a3a9006ca022d8862267269426f1502444b6a629e7651eb58c8583c60559c26fe56bb72f1a0c25bd861973174ede3d46105bb09bfadc543aa975c2d7fb40145da147fd8443c37bd5a8e699513f371b82326d98eca491f54dd6618b3a14e13292d64507f3a74ed6ad3c9df5875645bea0913cfee50c4da5ddee5fd0d35f2e6a552990a457981b1d79666a6698d051701b844f8988ab5e961ab8b1413a6e0b6deb8cc04aeb8e933cad954034c41651767dc6e2f25134d0b2c00ad92850f31020a1bef11ae5332b9c427284609676db89a2bdbc036fa8b460894cd69962952d0c06840595493613ab9d354532ed23dc3164e0f2357d12c4cd4748e4f14e73584d5b378a2e458adb293b44a2e38b085abcef7e2e31d3b6a2f14236dfa387e90092f7ff0ab09f24899c469b1eeb0d7fb6b44c8c2b5f0db8926d736ffaa96303f6eb6f75f6c878d8aec2eb3affc34e171748e64cd2c2f71c536659d71071cbdd7f451a56eb804420ebe63c951f89dd87bdd8c6e75825458bf0967721af534b1581b26dba6b2c16bbc2a1f46ca83478a97b80ac2bb4cb287e8226f981364a0c2a53f37d5258343caa67e9c7bbeedd4df065014ea3514ed6252fe9055280893e0f3810d96d33cd23d29f844fd4436de4863eacba47272f8dd09fd6c1c08b628ae052118ddd6129603bc334cd451fe6a8602de8719d03bcde4f8733bb573cd845700d3807a1285b86a1b3a72a4408d6112d03e318652d77707edcfb63afc080210b99f26a0cb725f04ba0506034233f5d55074f26f3f85188e25856ff2904f305c4d37cadb1b5e332197f5b09f98b93bf0480728c5a87ba7a9d3b797322b855f80aead6290817e49aab4f2aaa309049b7527e71b13ed19a62edaccba635bd5b06d7a49e6ee4472f5812291c4716372bd7ea75448d6ff3e7a6f3ed4530bf748d07d2a0d9993bbdadabfeb8a490e6fa1b705ba90ca993989786232dd5962924bb1840527d921c6e45105f3b37ed6d2ebe9fb9d5834dbde965cb973af634d1c55e50e0e5b35713079dca9cbb14e6ed69f840bc4248cf8b0b526dc04531b733997a9b049b8149d66f584414ccec7f00343355e84cf11308b1d7427219bad022d9ba11906598aa6b5a7a51d35f4ea794fa05fb13385bdace54bcdea937c559f7bfae285b68b4b3857045600933317be8ba9523b80a2f2eb7f06b35f060074abbd7057c2eca374580c90ffd59286c6fff9016b6bf5689e4b22ae853efba4d2561c47c484bf627341ab5c58eebe15115e2433f752676068ffccebe9a97ff8858d0d7ab66e283b8dce9ab117d60aaf4eb6656eb844fa3ecdf4c642e95dec9a81a8c169bd1ce76a97d5e3ea8ae52a6e2f6d6a87d0632e57a1e805ad6ddfd50fc14fa3aff32aef2653d889b05d994f9ea0fee3fc08569fc67e72a24fccca422b543936b65ab13f6e3812bb492442bdd8d51ab1b70728b6fc6b919af20db67de66e4150f47d2afa0c887389dcb95ace68db07b6c830dbd8a39c646aae12b6bd210c987aff98e92d0c8f0d6bae1c4ed5d9825ff869ac6d26d3776d7f30cb2ec1421088d76c9d89e5c00fae7a36b289fdf0dedf51abc07141f35c1c539d8eb7cf94e4b5b80a99f289d6aed2e6509a5f86c12c383ed29acc7d10d71eab1a0e3a2da2245ead86dcb5ed856526bf3f1bad4bad336aa493aa1d5839ea77f8cf52797c2d7eb73102e1e9a858c0de35b44a5d44719c40456bec32080ffc7449f9d09a836666a3f8c73c5653c96c6d6a51534553a43b907205e4b8a6b7f1c29e6b2840547ca12f224eac489fa07e1c8c75ccf57cfe81dcd979bc15cda957e091ccdc9f7887d32d169f1b71e36517f45776b23b4d4bc93a19f92c7e1fd699305016d51bf9ea6eff02350e6bd906e4594df114361136b626fb6785f1739830ddbc6def9f56477692ad656530e4776d381b06cc2b749017f578dfda7ac344e5e02078d5c1537df8796ab63a964b541f72738b839643e362bcd32d12c1612dc6ba2f8be0ccf9678cefc2a74aa9cf016de8997138082b5034ac3e4ca264ec9115f73c56e28df2ae8cc8d515a7a11e64e558cdd6fa7c60f0b275b5d4a7faa6d72efde39548af0b79a551c942e2e107b0f3088a0989974adb34cafa38a20ea0e510afa0b1bd385cef2b9f7ca58fd2a2f34078056f8b0583457d3803fcdad4947c9a6748f07fd8d16458850f3e467499047d62cecec90d34129e65d34aa510b8cf9a423d2c58535650af39fad82bd2ba8bbb61ebd61bbcfa38562ab3691efc1fd13c84305df47b694ed9fd30008a7536ce6b8b742e1714bdaacc7113f49805556c74b2b08191e46c408fd54653de052b270f840b6e7d0c6dd785b26452cd45ebd16dfd7ef23948932dcd8af0d2d6a122828d46146948732eaf88f1fd344fef966ddcd76e81841dec398b51113cb98b2177e607adbb234339ec12bbf85182fe31bf68714621c81ce4ae6d019255ec99f39ab6d5ff3fda978e62264ad428024f3a957274704d164058f3b1472b0c65bb927c9582179fecca089484897980e4b55944eff7bdad798badc3a04062527ad6dbeed982f761eb52de53fc78945d1d864875a762886b4ce76ccbc675ceda0af75c84624ddc79e6761eb726112f770a522f073e657ebc16e2bd040bf974281419687f9e6b18e7d58ccf191cb81cc0cc01624e88dfcba77eb0d1051107e4c1a767e75357e55e1da82db46b208b1e2c67c1f5b2414aaefda79e358a602d5d1460edf9c0891e2c7e4bdf57c55296b9c64d62755f20e4606d2a39f1ac7bab5fc7e63131812e5ed91f6a01322b3ced88720055c270ec3ea7edf1be8058fb73f9cc61e33de0bceda1d38f3d20edf6309b3e535d06967fa662920df13dd3a9cbceb5bbf67bb367960644876d5e5ce63a3e9f05b278976a9ccba2cbfd24b07d41c95009e57e09cd1b364dc2ea7051b0d2ab4800b9c6feccbc69c2b4558005722ba1ea61b3eae78034c0b7006389b5947039f5cf88972a80c664f27978a904998f33097fe6f44d1f2126e80cf1df817f87c1e68ae51c089b40da2fd20784c342a6a27b6228102cb5cd61c1221f0c64083fbf720739268ec49b2e0ea96161e351bd6ebc631a4f47f5ca48f38b46523bf2cc0f650f4698c200b5cbcce50578db1ed96b5934b99a01ab7d2ad55b002da4704132b2e526267e9da16d51dcd4b7b4c60e55b959b5daca45edad964b0545e6acff56033970b36f24fe9a491065bf1dcb94b5deb8318209446fdc6f852d7ffbd494f5e515722227d8a0b234542e846f0ac29109c82e97e5d76f1f743dfdb9237620a479ba2019515fb3fb4f4e2572b9d81f86f756ab18ef44cf98913b0bf2d6886df6da356142c975123140a6b3c3729eeba014e02877ff72ff06b54864abf00472a1f6fe3c11f8a374a9571ff36cb2c4b93a0657fcf5d900ac0177343e9f1b00cb951dc8faaacd1ece7049dfd96d70d4db588baf75018324bfee185559b304027da3ebfb5b32ec22616278eb6c14e26384f3bc37fb678c21a4e6f66280d336e9bbbb0725cb4f6149b80f58a84cd9463a648316a9b556b5c1f3af8001f4d788498beaa95c27539a5e61b7aa41dea5ca2bcb02097c4a30daaa4a183af7f2c7314a13e753ca0fde226014d33795280a25ca56b2f9249394cc484350e318a1ad315be1c620ba7b9c0a2c35c7b29129a57002cd26609a9879ae0f5c634ac9c44f02238c03725baa6e193c06f40d712326043f5018959a8f47093bcd29cf29e59e8e5aade7e39748482a3d314ad5e1d147244d6134f539ad3b80f03a308eefb3c919f1e1c1f3ce4df898e5948bb42de845b6301fdea6f2a3c706b6d537168d5a018e909688eeb604925a0d11ee876534d97108352df8a7e01d79daee1611a2c77a7320258dd074054b261d9fb389d21724484566830a620346c63685e45df9bcc8a0a04b7693183317b28bd3333b615bdbad523f0377966ed1c07c3b2068db17cb19c0ae410194d5cb51f906121db6cb29fc7677a98d5e18a941a3561a27d212c7bbf28ef71fbe6b9014b7d99dee141cea11094f1907c08999e56d2db97661ef398c9bfa304639e3270fbafec0fdaa4d4798daeed088a0046870e06d88695de6febbe0ad9f6d0406bcf00426747caa586a5da5e12d3505cce8f731f9c326067a16bcdd96322f0f5326896a61142c7e017d0d140da2b2d165cbb8a838877b9e8d7d2de2c4e1eb5c8eb4b261c2d56a8be55dcf97bcb92b1ae27f292d5e27031d7e8074389af1ba78d0ecda006def61ac6f72c36a02ccae0e0a6c9d50e6974c8a2752bc4fa499b89cce0094fa14fb0d602ce6d90dc6f25ce580d1e0a3f88aa777328139a9955e3633ee664d42ea3dfd093443c81481d1e04dee5ddaae452e3d4f8bd63399bd4f92d2fb3609fce5bc3f641fd8266aab63f4eb22e1a2016c2b0fe395dc45ea17574366db60fa07951eb23d113c4b6f047b28499d9a7111b77af02b7d3a84f07e151a9236a83730154b4072807030bbfa087e35b9eb3fdce1fa78a5cec1585a916dc364c9d14b9f60154a1804540e94177b90eddf238d1250b87be1bdbc2fdb8ad6460b0af5b515c9f5f8f80e113617aeba090c3ce4724ea38e8210d507a95cccb02c35b5aec3ac63c9288afa7c0dafd95154b875fc54919b4164f10ba86039619bc8d0d5a8aa02ea58c43bd08778f90e14a28f7474a48f467ec7a109381863940f7c65e39f26f035fb5f5eb8e5942889f6410ca4a5b1d9d045f7d36d53ba7d0ab83c1ce62c78c6565f64a7a01cd5e62596eb16010dc862f35561a9fbb234e42ad473570f348a5920f05c24b9a5dd167c2441f10ff98f572b6714d53e6d2eb5c09ccd6ff2921f579254b7d60c5061b28b517a4df5490c2a421ea2f81d2916b26116dffed50f90636dfc52606e05c43518eda22c3c6e63e87e4f385cbe0177a389d74a433658ced8445b68eb79d32ec744bd1c2f5954669b5ae406f8c348aeae12d6ef81044de685acae74a9df45b8daab105c911bdc35b7ec4b3f197a6b8c44ed384c9f36d7ade31d997d166768e19247453e368cab74d3d1f0fb047f70412ac13b42beb7f5b46d78442475b68052095b6a82918f2a3c4bc408914ad5d9acafe7e9439b09f07e29679e45db03a3055522b3e2350203d9dde605671da9f6041eef14dd8251aa5894e972ba41fb98311787228e9be533754dabaf0096f8c171e9979bca61c62a5e99726a599a54c6b91dd47d52969d5153e3284607c75d195dcc957c7391318c611d15f10e26066ac0146cce68de8ee7669cc7060faf796f63eef45facb9cec2c1eb9b84db21873cc60aa69890253e1ed2efafa25daff2da3503b7085805a9610ebf3bade1ddfcee16c750d752e9c9cc3b3559a9018656e9e72bc94cc6516b2b608d1f2c764c88fae4d6bbe4a8286819565c9a450ec2cafcbb7be18bdb1c1f93c334185b8baab1a80ec7224c29b5afd508c5e88be691520c610567db88baab72b4dd48719dcad1158a5d8af0068133fe05928f8800c9e2bc96ebd9ea102912ce2eabc816a66355a3523538c045cd52ef4675d199811d60046eeea780422a50707b1ddbd295d12b116360c17a9372059a784e9b60d052dcd1fcbd6c91a3db1565c8a77a3e35aec441e0396efd126876ff0de89e897a6473800614ad52b56cc09f9943f19526c787ad6380f20171260e53212c10d49f4ac30b4a5d04427000fba17ad8facc7cbf2497d73519f04c0fe76839310d13a0cbbfc572ef33838637cff1e5276e8cf6b25cb8905922caabcc2e7e88f7f7239d8d49ddd6225d90ccd7c16204b33668be003ad65b9b229fb4ede2934c18f17e43139be1d14418802572beb0d53e75e0e80f1d8cf3855c35c524c63343dcd1433570be80c4192ebd841b34be9a4b03945bb425ba223ee3a3ee1eb5aec55b756401a59e0ced1bcc3a402b7dc1d48ab9ac6ac7d21716dfae30a5e90b9ad32c511fd889a9a936e83d79ed205f2274dff6f31ddd3b6c32abec85bae4955a7fe331eac3f889c4afeb3b280091aa109935e645f0deb6520fd53d23f20113e541f9f282968a456fc45310c24693aa6085430c1a41423f2c0e4c3a65e4e6fa108a42e9121261187cc5cb139e090550c9e11caec2c261c51f6b76b8e31942aa05481cd717fcbfe700baa83350cb766ae14b5362b679f02095efc80568982078631021386c28d38b9e348a81549cf72230ff19bd83e24e9c736b93cb066ec014394de80b9b0464d85e7757078a2372e974ebb9295b126905c268dd8da3b5c1e84f61222865c2719a791553989c6a6050ffd0d0f969fff6515bd23fdfd922c94a33166048bd3ece4dbda2d07f5c0aff485008edbfaff0dff66f013b254fc3806b814a656d3385e6607454b91a31ad42d5edd3e3cab67aa7b00242ab1764789d26b2840af957df6f6c71be4a59536a3a9d82d3c92eed5d448e823e1e218fd7e980554d34e7b0811c38d17f1c19c84eba80803873e7ea4d6044cde04946e1a183c23d9595ef8cfdb63c4049642f01ab71e8a0df07ab089bd39defbfbe222dcd36d9ed526c41765312e16bcd1ec8665b189322623f5e89122a168957a7eb3009b2d0484580160a2a4c9ed7b2d3d07e5220e2e1cf274f9638cad7eadedd2b68d314f9b4216ef33b03edea74a2b84af2e208476be55141565c842d9555dc0122130c24d8b3651fff9c2e91c7343069bc010583ade6f0dd0862fb4eada4c749a5255cfd2ee6793f6045b4eed0a3721d7bf0522d031b5a1c9f8f9d3ce6be17967d6dbaa9e4a3a79093e8a8577f23bc4e6f7c118784344ab44043ee065d59e10764183bdaa8062fb499091344be5b3b402073bde3c4afa730ed901cad31e0a80bb41f10e00847cdea5ea827446f50f61665d4637c3a6558b6071364c52d9c5d9f7a65ec17cd3bb2578f85adcf045a87f23484730a3a077c7ab0d3883bdb16ca4d0ca0dff24d4ef82dacaacf8e803173255cde4c1b5ddf8251953d9b3102a719e012b531098b210c7fa0b78672cf98276618d03b4524b88dd1d68ba30451de036df28ba5f0d00508be8a0ae7c91f511a2cbeb499f917daabcf81aadfac587ebbcf1c842929441dd711cf2be5fb54cae82ffb7b0c1ec845e0a1f3f71c02063ac435f818023ea9cdcbe9b7cb1ad4d96650708dbc5b929092d2d95c03e6b3978e484af6da6191fab9d4f286ed8aff0919fb60e94f8c57cbfa23bc98288b984676d9758068d83c4ad5120843124ed544cbb3c3a8b7924d297e49feb075d253c182e515482dac13e869498431c3b3a8828722b9714673b0680d4f532543f8ce3f1c1777773c4f31edba509eece5723d989e083d0ff5b867a3b03e5cd222cd8a3d174ce348c818dad221e9f68a45ef4aff3a64fd205b66e19a0f4c4df8252ed05d8ae5c87ec213d3300239131b6bd0415a91eefc968a4682c75cb29e1435406117142bcdfd44eb481e29c15e7ec59df13152e1f866077ded2b286501959b454d9f021e488c1bb6953d570a89021533ab76827cebd531dce57acd7abfa4f7ed6c92bd01e8efeb1d05a91c2e0385422abcc6ea80fdde8032219c322873d5d782cd02435625d953c4e7d81ec8702a761853b3d2db53f7c3a76db43ff6187c414a06734db8442ca12e2016f4c2d5e9be22cb84e6e0bd7ec9847b0fe561223db4b2b831974bc3717d6529489b919d132a3113569573376e45a2c901aa671703b5836418bdf89f0b780b61b23b2f8d9634249cb6dae152ce507e48d4ca69e6ff07fad8227427b2ba5696740c1f59c754a973baf93bfe087a9151db32ce98c83d04199e49c22eaa9bf1495ac30422ec32895f980d28e19bbf34b1eab929894444a1c16097aa887cd39debf0d51ce98f236ff099889d053bd3af9ccbc4f1b0d0ad321939b23b5792fc57eed89da72187debdbedb7ff1ec4fcfde0219a5dd84bff527fc1045413c7a3ccd519bac1bd51db248b7faff5dbaa4761d696f39de5e25e53a983fb2fb4729a145b8468c0bb4b13e509c42b0638b5be80fb14bd3a9f59663d0c39bb7b412ac062336887ea141ef2d42d65bf20f83f39240898880d65f488417c2fb7221d6bdd72f12dfa47a8248693809b26e1665da680adcc0b2fef2618ec3dd1c71700650bb11bb85d5144cc36baafba6064d512df3c7b6fc726e94d03b64adce7f5c28294610e2ea59d02729bdbcdb5ef112544ede7316c4240e034815c7e0235c62980f6f1ad4d71c3147d93178a641508df59cb5c9e527cedf25c7bfd26ac01236df81728635628910b4d2dd866b274e2cedac19c46341f875104f190668746e835283e2acfd6f0ee7b8f622679b2e97ffd65f48d11cbb97b0a80a11f190bd7702b056742a22a642cd109d301c4444d634cab0201ad8fc7dcc7d85c06842ee6b5151f2db4f55c86bd177994e05101282f77ecdb48f847e0a42c026e4f2057ee454ce50a88200ba5bd9251d2494ad52840b1714bf73b4532f360ca0e66c1cc46602398367b169a9739e71233ac79938298f1d7086821517060ed4b2f446ab8d41cc51bfd969e6ed2b573c8d5e52128fbed2b4bbfec767c52127c9df30f1854fa92af96ff9ac26c32f00052f8566ad31c0e159eed11babece82703dae449e25f0328e2c7bae562207180a98b635adb1b9a7f77db8428ee1e4acae4ae537d746138e8b472b8b94f5fb7a4db017103a9955d70301c0ff6f1524d41d923701e15db8ddc41a56805779c8ac654d162634bd1b2aa48d2d2329d571b4b674c6e6486c1993d3be90d1c752917b0c691a1e92abf434155ac254444c238dd90494f3006cd84737303e01946383f2f4effc9a32f1fa80f093e42674f425692dafe48e36af433372c3a637559259e36b699a0463f1132b7c065913249ba8c9431506b3b031a6202c34e805b6fb91c544391d634fd1a8d1b7d1a61763c8e94a7012fc3486c02106b98d2720bd91ca632bb1b1743b7d8b0b02635585cabc04b7572200f5be703e11d7f9c43c4d811fe8cff061a31d7bdf43e564fa401e358aa8d5671e2e5a6e488b3a1dcf1b27d65e3deb6f5721f21340c0f7d5c7d5274a8e365e7cb3d14fcd5421024f63758203829a529129e931814d362aa27802ff5bce053521557b4b890dd3353571bcbcbb50e48a5b016748eb007dd03b46f6482b2376644642916811eef614e841072c7fc37caf38faeaad493a4616559c08f14bc02b3b52a1b7940cd4f8b49eadf3aae2ab5181a84a3a78610c12861d4881f0c6acadaa31cdbb061e4111af712b7c95434c74891576bd541eba319cc6a728fbfe877cb46afe45f906519f5957029aade11e425dee50a6d84cd16ced58950106df6308dafcd566a0f3e8e4a954ec1a5cb1a203ec9686202bddd51941b23d5ac430ad548404e161aa52ebe92d504b49790db56e8f486340d63c3f180e4e52f1bd573b58cc9cad09aa796bd5ecf716568cd8170428acda2950179bde5a1d5e74c45baf114c2c1e93a7a7716c1c01af67ee6a1b3e752a9ee3dad1748e09544e98339b943839822992b91dd448d91239c87a6bb46f334960a27242de2a5ab1a8907af9b767ac92874caad5209c44a15780666d59fff70833289bbdc9cf7c68ed936158b1ce959a6663d987244ca7ed30e7f381b53100a02d284ce48cbc23ca826fa33fa0fa77ab266ac092b05e566f24169c4237fca70a8877793455851d50984987019f90b3167c65a1834cfa7c84fc497e9f1b78e334b0743cd268c00c13138b50b70567df6930e607a37dd7c7138588068f2c5f700eabcb00c44b740e335ab5f868ea988828b69be6add8f6e6d8fe45249ea54388705c43946679c03b36b95f910df7666cfe6100c179045b2714355a508b17cf85473eb1dafa4faf7ebbbde21f0debb8e6e2df931a05ab239954384aa2fb0e1dd04fb968e07a4b409752312da622f720b9eae924a9b5b30184b0385400890895a8938dad0124fd84880f2065eb2eac50b52db83c3154c5ea9b2021a255aec61e23cfd52ed9bab101639245a190c9d12a91eb541241b0b799e3dd8f1769670c7ac71eb032199a2dae564f609d6da0951f5a39957ea29481a66b37d2bb75b437c7b12e935ff421824307a2d33cb5aa6002da6526ccd7087923fdaa70d6a6b25eed3332743c9ba93b5f4b14ca09a8210c34dc7ec0876981bdacdbaeae86132ab5c0e8b30903d834c3a15696e8cb31cc89e5136037cf34d4b0bc89b4ba585081a9506de8074cd859c1ab894b834c90aa853a9766a3b10483ca2c179b0e12fe06b5b47798ed79b43934865568a24c21fdd148d194177c2f389921a070ddfd7670bb3a472a1858b15dc303671ddde862832dff5e3e010988615fe44b4dd20cb6df84b47565c008d24d15cf75b250611d722eaa34f8c32c12aedc17e0613c1eddc288a6b3e1d0c1d1a88119ad27e162d68072f13f74303c16a11c8c3e4d12ec4e903c0ce84cc79192b9a0985c438bef3910dcd41d5cf3ff0d3632c0809ae7cc1b5fcc12107dddd857b54cf481132c074494e0873b8a24cf80f4a90b2197e70d85b9249205404fc74f82dc79dc88320fe2fe028cf0f0eca4eafade49d200c0913c74f82809a9d2a7c0647d9d50986045baa0f62616145663704363ad207c6951a2f06ef7c6050b3c40d76bdab488dd66049eb83b834a5ffb9c1ae057d99fdd2e5c0b9026f94d04d48ba7c530063720a720e10b9fdfdff3228f2241fa485409645443bc35f8da8feb49a808f74aad9c1a474dbdb2b57090a2e6376c099099930cbc4708d201b140168d8555d96cd7add053cb7dc55f805b8778da0ea17f27b54be908125a6a94c5c7ad0e4da5e2398d6999ac2f773574c4884b387428d803160007b61ff44809c591389bbbb0dd4ad910b826340227fd16aa8c48f18a1a2b8d4681ed358ed1014f7a9b6cd7cc48dda30364aab67b32521ea5153ce001ef9714f28f4c193b927341d0905f174c622e4c511268f36ad0db37e4003f0dfbb06cae6310d5317753474999814a9476aa10bdf385be4080024f803c9dffcc9e55b0087ec3106c74f4bfd6b4d8a549e46992d9e4b40c16eb7c5a1a9e20d96cf28a0bc757860eb538182e652213c4b5d6c283c0188b54cf16e11c2f80ca35cba4dc004f369eb11c12ea093307dd33de40f7b1f57aeb0565dfd012170455bbb489942c1addc2dd94717e72bce5f922518b07c017fcb16a921ff2b11f0064acbf730faf965d5b7287b3e4227491fe00c553ef4bfda6878e899d1a43924e8faf23ca22585e7b767fb4f17a0b050854aa8d71c1c803507e60b8194df331525f43fd94dc61f5613f509e1a6acfa3a60101ccef8fef14b4ebb3ec187974cf20b48046c828e24ae57407168b4c8155f24fa6befe069343eb598b11c3eceaa3a074a7bb21576598204e6320bd970b8317cfa284cbf21b23faa9900b3eb33106e2588396e3310ead573cacfdf8371884ec3fe38ad6f32c17f9aca164572824d66705a1f40c170b655af9c8b7610a50969403a43fd616e3dd171784bdf9ee6a3777ebfaf05761a14fe42be2c7016ef1e3e7f7c718f82b53d5551d7a74f242a5eb4855c987b21484c9018630a2a38c385d87ba7a6386c38720e27e242db248c2f862710f2b956b766a201738f7b284f1cc3774a37e7310227550bbbe887a46376a10226f5a31e86526aaddf9b00cb283d549742d6ba434df4e7fa03e451e1a9551899e10c98e06bbc5104e9b58777fd9312f3cacc782a39fc5428e1574d12eec3da16b522cf3af5e8f7b4cc9399dafaaf14d5b0dbc6e6eb32cafabf91d22cd518458868d2eb99e3915b6e2c1b58cf2b80db0481ec0243b3e7952e7137a380edc6d44af3193e8391ed8528a7dd1d043a9fdbb397f76329d6996197d3fcb02eaf1204168861ad722c71a5ee325c9377dba6af15d91d27e14a1d7090d6494cfa139844287d5e4e4f897fd7ffa49caf29eb0e07aaffa15669325292e5d8bbb8fc8a6abc18ad3d65fb5da698e5f026aa925b548e9f0d2bcaaeeb432a59c8544e82b41212af28ff14e05c8bea6c941d74dc9dddab90f4bc875d312a4334afa6fdb67cb58d3a18c0092aaa328bb0b0c54c0997bd394f9b19a9d97b62e43da61d362ea30eec967d0ee395c8d33164c2d3fdc9850f3266382e5404e616ff64c21fb6b259c1a3a930d872b87900a76f8dc4a163894623439dc401cd27763f78ad202996347d980b2feababb40fb81d21b6eaf6d84d0e174cdfedff8f0cfc72a4b71533c3960d2bc6e565cbc6b561bd0b8df963b4875b9e152d66a412a332ae1e238f781c9a047478c6aceeefda613d9a4ca2cd50c52a39fb60670500273820b162a79e71d5f197669e790566a05de8c8a1fd48c6fc637ee20d9113d2e2518d0a2892caf6f7cc49f80437a6be718bf5760e63eb1b85dd5054f2e1915b97079f4aaae216517f2980469ca7bc5724a229baa3ed771998dd00b495ba8d6bf265ce497aefee5f76dbfaa8c6152d528283e49e6c162608f7dcad3abbf21ddd25e1b682d804a0fd9ee5b2e18feb5450258da4090112050343a482df1c6a224bdd51267029f708a2dc08b8103a2c66a183d7ad72d70df41c9d95e2f37fc904f9f53ae9595438e8f3eb7316bf53f34f90f72e45ee377dcfd66cc04231ef996b369712a946865434d99547e69a60b96bebedb89a5e0d8c83b1562087bd9882bdfe705bc02a90d86658ea3c7862b2a2f8c2a25bf63c1883be98039cba3696d36cc0318c83f918ebc67ce683e3115313ba4f4991447d7380b8f86e86cab10bc23e06372563223504c20097909030a59d735372e177e94e4467669c09194609038dcff4fb865c17aeb2d6f127a536b8071b7452e142da47a1197e1d5c1755fae2078b3562052dea75ab831267a4a7a4e2391dc05a27d525afd11e855f9e7530142944db9356ca2a69749d0d727644c6028b7395ad758f2357b0521df1645b0cb3a50847c806922a84e56d85565582a82a21b7f978d8166a1843ce2ccab0a212fa5152ba66a5393a52b70c1e52711641b6f2486d9174b15acc014ac71867fb49f5975ea0b69168282bc95e1a0efb86b1bb502fe9a662f803791f5beabbc971135b3c99d129d7dcb188f810bea984117b616a6b808f15e96ab19040d82c363b64d8c4bd721bd365b18dd8ee9d2802cb9c4b5d10c231a0f98a0303dd5a73dfbc7cb202499da55703316890f5ca9a1104ac8cbbf6c21fd035befdb18f8710740dbf54752cf24e51359305de36cf7a0ec236b3274e667f46c8a92510248c332b2102b98339122da74524080230bc902ba20475558233922afa781160a478fdf2ca18bff14326a957cebf0bc5116411692df231079380c57cb14ca27301457c436f11a9a1056c247840c2a545efc360a472dcb151d039f0adbcb473989a72d718418b7b0eca395eb57da2686883bd5eb6f2d20ec3a239b164e96bf54566b0d05f23f4468eec0608989d2c034dd580217476b955d3c49ae4f43dc126fd74b6317715dd2671936a15db58525127f97acdb5ecf6c427235cca2fa8bc6a346789f336199a3f94c536e09c4fc028dd00aab21c4ccd9e2aab617b332ba4fc155b5f1bdea2371e35632951ec5b4b288b953051504f22ac036fd5343242c1f15789de861465f3aa1d1e51d12b5cdf3b394240f09e171cede3b6a8c747d61ee8d3a0f129e96be57347f7bb8bee352052f59d7370453f0c2a64c91c37c9f3d7ba8bff4ceed920798d0d676e0034c582c95a10804db4819efd4029997912c863b2f4af5480349a620282f568e8b50251ec8f63e3c48d9219d2b9216e2da675a66c3cc5e8d1bbf0d94212c4b05e5ccdbfd53ff226bab22f7ef29306f00c91aa8a97440f765691fd7cff3dd2f75a5992badb0e604d98ef7d481b006c5698fb7cf5f52be0aec9810b4599107cafd8963dccf972a8c405a7e439ac5e2b66cf03c14f42041ea240f9737b75b846c397d8218a1b4857cea8e24db493018a6e9ee84f3b6d880aeacb219693d2ea0573b13fae804c9e47901e11b3661ddb0ec3b5491f21387a1d499dfa753920740384a34a52f5dcb325adac2f573006447a3e8ad5bda27a8e4c3a17032404a6d0451e82a1873b0b4463cb1b408a85fb401c85467b7dbb907378517157f1b422485119680aee22d89f9664779e0c315ad7238ead3a2d2b16bfbe8b05dfef2adcef60ad683238e21cae11aa724af1462dc8a6d18eb1d72abc8afe01be8c29c589ba53d916a4b6121a9bd4ed240c24121790a76dcf268fcd603776ec5931eee4757ca09a4212dba27bd82499f28bd1b16bb7f2522bb9a5b91bcd29eb4c01ee4ab309a1aadf0db24619157b8cfda9bc52283171a8dfe79478a450f79c042d69ca011db2916d220cc7c68c67e6721d96abb72ad4bdbff5f04c939926e56f34a0fdfc56221f459e85178522e89e91c8cfb176d4ff599123b0bc20d781b0a1042c2588a230459558820e0fd8630b00c781a67215e290447cfb5ccdb6b575e2819fd169859ff59f7784ae0671125286acddc11ad1caec362302131d47d0ac48bff99d68227d873daed229f767ee6f88c3912be820d4dccfda638d4d3bfbda94b82cac71f53d17bafd79b1865595debe81975cd9f9d7016f6ea3727bc43319c595b7dbe292464481c9c59d295dfb618e756e4834e4e85b44a44b85a010c60bc8408bd131c428eced2ef91d3a24cde51c5a62104879dc8108cbd56c85d0a034f47342f4ed6da38640538acdcc9a7717d9530c0ca148cf4001089dff412e8a7bf463b42334638007597611a432aa90374fdc518169293a720746ffcdd8bae159aa53ebd4ca56979f72ac49c896fcccb79184089f7cfa98acda76b45ce7f67739c2d6b45d0b52278f8f3e62f45069c3045e1065ed156d78aaa3fb1e250d78a5c1544055e08fd6b55267dda8a9be11e549fb0986672d4b1014e857164a2ceff2e89e7df982afd9db7f9575b3198f818836b0804f1be4df3998b2dc127f6e1c22a6d6dbb858137cc4de540eb1d69d21da20e7dcdbcc6be7ccf7c528888d4b64a85239e7b54107fc4875c548ad322e55c9c33c8262af970704283418a2d75c34ab46c2545335bc825afc6b922c8dcf401c6ec596b63b766f0e8e96f554e6c0fdeca62f1e6c2bbc5b1b500beb95dd4cb158dd86a21ca53a901c9a897a213af168bed380b3adf073b08f2d7a900b285e50173a920ab2b04bc022240993a4f4f3858979b5a31f1b0112d5aa9472a1c5a9ee48ac626782a87abf181a14503e7aeac804cb025b75046f279b265cd1063979b957c0080c2013e1e75ce04460dd05e9a928cb350f0e98f824ab5653175ca68401b58619c388db9d500062be8a2e87798f267d9cbfc9423790f83178700234aec5a3e41f57ff049e5657530ef2e9e14b3fccaff5c926dd96f534799bab83eb9ecf057b27b20869ac9884636cb1b0fafdbdf0f1f7b8236d0e323143090f776c390581596c9000ecbfcdbfdde8ae017b9b18a5f28f84091d05a8de3cd57127762e5f7f96af0bf0bf16c697dd1c0077b93c132687a45623050e21b17ea7270584a2367fa1bdddc00039d31c685a3aa6bc92131e2944cd1871938e344c0a655616b0af72f115e06231b0f6d8ecbcdad45a84fd2b876bed624dc25002ef62c7ab430c4e07650bc16817f81d00a7dfad4f5e04eb91cc476d5a7fd12339b19d25c48b6d674be35cbf3c4211830acfe5f6864c9eb73f9ca254fcb58bd937234b27725de541db94a04c62954dc9037a83e1677d4bf74b7323e273b4b3d81d36568a880750b468144622a4d1d4ae82fb9c825d93d9aab0228fb4077c2eb6964f176bc7ec027563a005b7b18e093760f02005f87dfcd3042973809d88cd7e8b7c1fd06e6ef9ebb875681f8c67d270a356294f814cb019103eeca1c8b810245b211ea24e02be48c661570c3268512814dbf7460fdedfbb71654cc3ded90e284b605e734e8daf8625739aca0617b2a1c57da7365cdbb038d597d7febc2bb2b2f0753fee6eb2c7897e56f883d3701746eca490ff57be7d9b3ad9890f8608aa9a69daf1c89916ba4cca9dc1f165596d587f6c987de304ffe18ab0d17f78ba648f3a8756ae883042042ca894260001799e5689f2aee54c959723f305c3c868260e23b04737c3c6c437ce0b7bc614c7a017614f957c8c7f5c31840220da38f3b82c289dcbe6604c5a63ce70ccaa13ffad6e58fae0fcfe97ed18abeadf0d21f593274c07eeb57382717c5ea49cd875a313dff021041e02492b85c9852620d45fe5befd3a5d7924ccf856dbd330841891452c8d73ce0bae2e24fb8e22c70724cd10d6ad46e46bfcdfd1a52dec653e525a5439edee21e25c9dbf1d3aca1469044337fff94b1f9cfdacc162dec34aad7669f2fe058f301d23b81b35639ef77dd71292d61f855132ec4966661962fb1db03275a23f30cc92fa98297a88ebb4b25e9f2a3b0bfe5befc7e7d70dd87d27b36e452141429deb968ba95dbacc34f36a1b950bb6d715097ab1d489cfa6c23e4082df2d3c424a10063959a3764d5e16c1b5909d67245021e54d12d5f078a669072b7280c6395aa7468d1bb17e7563612c0bdd819c00596ccfcd1a311591b0acf0ba8405b9b8fd4fc3ddaa211adfbe96d42949ff4e878d0286fae68478d1c01f99fda51efb811ef8f5612f1aefddfc8935337c398975d501e1ccb24eb2bb90ee727c7478984523f4a43b15a328690cad947a21494e333445975607330ebc9eded61273d50358a0b13962ad15238d8a4232d52b39846a65d5532dcfc293e00c26156b6645c1e3084150a126d7361a994601124df2ec4ec26cec61be1ab4e0f723e79324caa11b11fd266a2b357134ea82c883c94ebe32dc5511db1b93e557a6aa4bbbc9fb882e8956bc8e2b0b14bf00a0e2258ec3ed1ab85c7dd17c902ee4c4eb5ac813cd89a90b3dcc8003dbbc3a237514ba81e15887f5d0086ba6097d269bb5d4e1be11ed0f077ab4aec1a30492833758d1022ec668c87f0515d91e7071a753d27f04c9e5de228e571c283b8afb4356c353837ccdccfb4a87f79c659adb1356af2382bf4aa37574f7c824e1af3e7f5459c3dd4059a71d588b641b7d447476374ec1285522046fc508dd357153488af4e714a7ff9c3813721d5d21aef8c841171f68914b16edfccd4f198eebc17dd1c19514eeb1591cca3d01fbbb1cc9e084e3dd5951c9ee2d4577b0343b5d5aa21b704cfb40ba674dd18e7713582d8697dd8086ec9f1e4bed9bb56cd30e9b9721883a05ec27d39784eb76bb886d5972f9cad7186d64637283db982919910ad0b98ecf0c047b41f6e24c9a9958158e0e785c38dc806392428528de9ca48fb8534a0800ad9d576794812ea05d5076617ef6e5d76e9a7931edd77efbb835517fbb428e3ca53eaf808d1f6dfaee3e8f3630e7a06f203ebb928442be728a8f25c2b6d178616c45f94c0416dac64aba3c7ee2ab7f08995e8d80b93c7968e3c199b5809d783dcd621902383b4ed5a8904c05ce50b10bd2ac63885ca9a5d0e4b6e05a0e2f4289716df3238f82527728e72d96ee9bd6cbe772a4953c41e1d0a567e371d85658ae58df81ebd2ab23cadd9b62c55b73ec66c8cc4354d58dd8e2b43d3eb552f15bcea73a9483a705174aa56744d54d48cc196475862def065a2b76f46a7fd024956d8f7fb2b735a6ac10cd3c66814bfb7e5fb1785b4b7ae6b256a2fce18f3209cb56dfb169be093e2ca526eb355dd7c48da30e411a6f94ca44232a973c49e3371d594ff425df9809250426d6595df2fc218e7035252f94029bdc20711471d4f18aa67a45c67092530ea969bdff785b78c0ff6eb18c3743063c0a3bb65f47840a184b3ba80cb749a2a668792909abc643c8c8923b685cb3d5260ef505e9027ab93f1369cc6fb85722abb326c05b0317e76283375de1efa946d0588952cfcaa69e354d5b769bc54fc56d843493451d4d19ec000163ca6e843095b11232f3dedcf0ec9b107b06bc334cd8772b93e409479ac21e41ec011b069559bdf193289344a8816114479ce7ba35edd2b72a3788e4659907811ce94b124176405ab9445e44304e565ed6c1a01e5962a5ff7a1d9ccaf1ec069716a643544b1e30f7d8b1120890be1f304667cf1fa3ea87b7100f4f0f95f55faa2abce52370f2144b353ea6643ddc7048b8d8922f6e94402b5620c365ce76bada0c4440c9d84c9280b4131147cdb90ca9653d31a1a8a035d436db769d44276a37ecb5f12a618033806efff8494d13b8348f981887456331d7da74771cbbba40d574fd8354ab1234f0e37a41ec9ca58a75dc18b6905cc15dbff99daa7e0feaaffee9a2d701eba9d9180eab2276a2a628d6f87e55d2d124045fe4cba8cbbf914e9a18b46eca8561a9da837dba8339fbc2768820d1df4d52b16ed59a287046bdc723a04dd300df3c29100ba15cd842269eac42a83ae422f6c8323afadbf9dcc726d0248ac18116640240cdc8dd806297b58ea9dde565843453b290cbf36294b1e80157e252da1beba06bf9b7aa93de8603892b76ddc2f56c7e59c6a411a31afa3a56cadf86a67b59dc7d6384f664aa92695f2920ac6fe146de1053620c9418c78a72f3dd53670df01636843043011fa25d401a2503bd1667452f05adfdf1fbe8b7952c3edc65e3222c2f520b0db5c43c2a5deb071bb847db7af3195d0fa9a92fe087fbc902430577ea593a4391bc2b42e9c076c0886c3d9257ac86819015cf39b1a2979e89cff116c0d6b476f36096d0cb2148da6aead967177d96fbec8bb95ddec2ea57f89ee032a97b34c751921248edf10d7d45aded1c27d5058ee459297f15bae7c3ff5dda15e2e010fa69c5a0674b0418a3b675e5f94dce867de8fbcf982167d73d83577bfb6965f23f866ae60517800059df25201394857b9a4b27807b5724b2fbf2dda939b78c49ac1447c1b9feee7d9d02a8f4876ad253687efc1910d8d3464d127437fa0ebe6a6df93b2cebbab51710d18c4ac58f87c1a527b189f26f46829957af09064562ea3e33c67efdba339bb071a0c0dcde022871bf2804bac25b41a1820982495edcc9ee86607525f559275f2d3d6ad6f2e542497b2b9cd6c4fca04866a0b476ba3abccba6ecdc163e1a2e0d571e8ca1d704f8420cdce1ab27f6d3be7d53c8595a861a6dc0a5216a4ce55c208a22885f6e339988feacced0bddb7b6b02c5ea079dc4c053397e763fe36290a4135fa8b32a16f7fa82b778b9d88e2544570a58f79cbbc9f5f7d2779d0ea2f6ec537e0a9416587c9555928a3665e03f8cdbd8b055a429afcc8fbd6a88c0cd1cdb3ed28343a3050a7b89bb850b136d59139755e6a36af1645bda4c504259c63ee24ed934c2d7646465925a4664d6a5b17d39807a613f04fda2814086a8e1b1baff2462278ea7350c0aef75b50c3bbe8e2be05d407cd1084e0d6df9b6bf1996233603913fd6fe76a112b361aa3327dd6d697f0022e09636d4fb5f567b4ce8521e214147fec858615e0535aa6882fb5a0540a677db2e8ad9c4101e4b8c79dcc1279fef5108af6858116beae5093a778f7420e329fb74d0afa4bf069a34e20716559641bbfbefbc139197faf1c081223b88195fff04e3d68bba41d0f5c7abe60a550da81f19da4fba043e7165e7d5531b5b6f2c74d8a095ee9ea5294298a78e4beb994d53c4250bfa1a4a2a60d105b82bb00654d53f48f3c5615ac8eb85661b6157ac19c3b1ba386fcde1d56eeaa4d58ba436919d7552341dc8fb4e0aed5de36286e02bf40cd27a1438569d1bd1e50d8d93599f18e5b300ba9379ea5389adf765116ceea101c9f0e9e2ab52e12c820411a67d18391441e51009ce6f4f06821bff5b0b1da2d87c10b68a3f61744dc94242fe9aab9f64f6c29481fa0948094ab330c61a7fed8611bc2c5ed2f6de6e6b7048d495c7addfb13e081bc6dfc89e22b35d8b2f99a44ad467bfa6eb4aa18cc39c0277fd9c3be1f1936001c0152cf019df4749010ed2dbe561785ba411b2e25d6a97df1932ac8483b504f2842064249e2cb4ada26cc3d17f624652a4a48d5172cdbdc312bf09398a224fe1a48b1969e27fc6ee6c693d10e1288351ad2cb5de4588baa1fac5f5cd315e7bdbba8e12baa78bc358c96c110d4f93b06f08945db5d40256956220de5b3723ade79a7e49a525250cb8b0aa04c9a2dd21cae6689e39841fb0c97f89c01b5df616f60fb323d146187fdb35fd65c3025b8aaa28378f40a5d8581e9d55fe7e851427ec1b4be83992c244ba8dfbd515764b524284e3bb25c30ab12e280df68d1686146d8c26337945b2da679e380cc6879f5ba99be41b83b8d9315c75ae2e223a66fd50ad4e81a4affef05784c8abfa15d10a89558f0d23a11b7a1a68001504ee4b1f24aa16565d55c58a98ac199b3fe3aa0dd992d62e2a1c132ba273955c102d2b4533c4f39dafeb28b94941d61cd0ddaa679e63919da50a975016c617776b6e7a9869e7161f44479652eb4c49ace0a777dcfe53ae5ff3c17fe59bf82c0b96ddb8e308a0918de856d070c93ac6d123b28122c255ec4b822450087ec00f96b0cdae3e84875c4290d843e2b6528b19818f1dec24eb69cb11362e591e352a7ea5f900fb0e24371161caba8b7b014e85d72ae277c1eaacc3998cbfedecb6121967afef66e27cdad5a23bd351e9d2994a2a2dcb7043b33ec5e86086b0f6eca0c55c7995f8c64d7bc45a5be5415281d80e511d8a390e75185e5aa425c0b1d3306381314c2d32c30d439a263331a938b12fdb526265c6db935cce59d01ec7ecf3cdb012ed580331bf34ffce3e2102b8115a099e5f583393f058b6e66617424dda862f48782b7e7fe518ab2a43c5a5dec8f9b8c2ed6ba5875cc60d332c2ad8a0922e3911b6d06ce6478c9bc95ffb468182a760b9a4c7929ad3db190728c085d7cfdde886305e8bdf5fa654053a9281ad9a5b749f5b08afefb50601b53924a9f4cd1063ef92dde5c4d61379cc32c1ece0fbf87c97f3d9407a37c5d9b2f4503facddaa594a9a701aaaf936d685f0d30b2edf24f1d0b4f772bf39dc3d5addfa074aa17eb58c66d767a8034b12705da90352eca02144167f8f2c4bdd4d8fd7d4d8bb2d0db4fef4c2f9dddf112c21855726e3b2fe5ca2cd485d172912a587832848ae554547307f6440b3f43868e62fa69a2f7fdbc7a4c030d9f120e9d609ab07e410aed0d6e5d9fdfbc3768e620b2a5a2ef7bd5757616e3b5eb3ecbf74896e46794ef5b07563c4fc27b9d86de7bb07d75799d966d8fc6cf25f0d3a61eb041029428d3eceac0f0a64037e6053e853a723dcc1814d3266fa6f5c1376ec6f745087f2ef66b80f9c8a1294ea17adf5491746932d2b275943562f8e7886d504028187b1520cf763eb1a47497affb77e8ebaa6be024c2d5fbf23667c21de17afaa193ea3dd0287225b874bd7961adf1b66b7af3944986a96eecdb233bfd0969a5d8ea1ef957f848e43d7259f0d153348e021f19a2262e687c4e65ed42432784329ee09629ed30dabe8ead953a256681e5f063d27c17e273008bf99748fe31e81271bebe1f9ff156992b91a7bf2493295aa2c83cfef57d5563da04c6574f110945aea1b76d476a5c9eba662893ea5f4c9a84d3fa15bb2d93f9e2b4254bcaac10b71ba33343cbfbb72793aa1c7c2586d46ba2169837a800105b22ad6d87458758a70d5f9adf4a97e31232eec61b17eca70586cc0d5060fe69d41153fe4dfff47ffe117368a37ea61142d2494cc5c1c4e53e610857b29fda30f3a4dc00c3e54e2416e20d2bee3b23a739a4283266016564d7edf0eddc6c47a42c405d9011d942341f33cf4dc4fd79b644713a15a90ba206db550fb7bec4bdc0e95d503b5b7da8a28e409bde91e948d7b96c812c54a3af7b6626fbed45a010c0e2aec1f7f91337a0caf30e8485f9c25bae12dc34575cacee1d0428e7e1cfe64ca08ff69a4b31ad2637c61b3d6d591feb200c756589f6f6e5eb999c9d11384b89324559535b0af8b6d6f19d6fc3b6fc8a687c651dc98928711939021c0e0eefd1a3e8d358dc0e82e009cbd327710ab14eeada4daa6b4e742608fd14922f7cf921f0451e1d90ae30f971ce4a6dc37cac37c4c1c65b81c1d8580ad145518f9046e7a1e571f9ba56a890b98d068b894d3661c332a092d6bd4ea91bf96727f54f76b50c71b2457bf238a4887e9b43ffcf0286bf5b12674fc0dc78ed3585a83fcdb4408520fab419d4eed43a95612644b8946d96ed905bcab1224ea429f6b6a8b4a0da6959b981da78272253e1fe4ce62c203925e83fea9c61a08beca392ac2e90c0c4af0801b8a07031e0d607bbf02a1ee76c952a6b4220e029ab1ce88db4e9fb67131a8bcebeb44925f39c4c8ed4e6e5b86570f4473b07cce6fa09f515947ef75946b72ffdd845b137615cd38ecb4ad1bc5251923c26989b3353d98a224d24f5eb1304109cf78c8597ba5446f37bc730c5b133bc314e0dd73ef95590f9b776ae2041d90ef9b95720233cd282d1f6583c537fc753c665922069c36951a3402ea8b21dc44059409b279c611ecc28e23bf3d06155e22cb317a20b2a1f455902faabf6ae76758959858c011ffd2c82d3be31d9f713f623300da40a2c06eb9facfd9f29775e5a7c4726697b626eebbd5fcf9b4e6ff4ed67b1be406583e745297ce8f3c7dae535fa128e14f1ab497493801177bfefe5179c6e8448617e10b4dfbbe928832ebefa757f24a4ead8cf62a931d7cb9756d74c7bbc094b3fedffddf3f72ff44ba76780040b888d82f44a640ee0745174c9ce15aeb9c90041bdba8ac620fdacc77396a83564bbd73ebfe726ba21fc489fc9d387e019a4bfdfc3aff355a5f735cecac32ba21a7dab978eb7ea876d4da7c2e4b9cb482d6e96aceca3b237238c8eb90663b969569535d14563e7a113be76026ca72ce3d68dba0d56003754e06852b51aed87abf1718b6210c95a174f041ecc8a4886ac3c5bc60d414437add7d0c1666ea6f1d9cdc9a5d01dd526aca09b6c7647a150f0e48495d51c1e4cab59581925b78317a2dc58723bf846dd5091dd10a1d9d1d011ec1657c983be82aeec046072156577f425710354ba939bcb5432aec5f23f1c01ad28c8c332a8de6e7f92c8834e9c28f7e5f85e5514622367e32470e7eab23646d645775aeb22dee2b3488eb0c5a0fe9fc1582cfcc0a0472990714ba69bab9acc8061b53a0c2effbbf49fd72aa2bcad5dce952b01c31ec40d7b9505f7b655c83540d50498122242dc640488dfe5cf6936a1ce6802229dd65bb2282cf40566aa3f9ce911a6a940c975bf2bf5639f0519a51c41b93b5c077bd00d1fb45f2eb0b6809b593caa0c8eb08af9cec2263922dda4efdea4b85291db299362d19f8e2614c0d16269ed471fa8ac10d6253e101ab016b6f6fe462c8be1afa7a979565a8537ed7084301355465640bd2625f1b5744626bea153f573a5b1ea081395671fbe50efce3ce1303bb1aa3e1437b870555de02d2b8b72935c11535fb3bda55eec660e15f544d895003edfe0deeb4e9e47eb304a14b1852d5203c88149e1e99382620a9278b8d85fe96f66e37006377bafcf49bd0137527eb216ccc2ea176419469116bbde5ea6809565363cfc0ed44ef5ca1234f8dcc2688dbd5ac4939da37ea0d80e035401d81e404a975b65f20e8ce2986e4bee86c507babbb4ba05d270ba021bf538845bbd071ee3743dbb63a451d336397ff49afa1199070b53617e99afc1ca50051458df0b89e5701c2b4185f09f0564b165b95b8045f065170fb7c874f460365116584405d4ad01e256ac06466d4ff296ac7631fefc06ac5d0663ad1e80288c6b57587684522320502a22424c21b48cda3c532f80c6bfb6499a67f9a56d8ef75a785c7c988e4a4e814e5139e517101bd5b4bbcae143e94cab769dbe4f5a1ada3424130cb5aa20caa63f36b68f9c4f0d89bbf3aea770524b880984d94696d33a820940efd400e6c78f7a0b615c7003c63e0838e8a1d0d3edfd1ad714a9e522f4999816ce22af2cbc5a162bc4c9422cfe6e248d811843d678ace4946983a2811db0b036fce56d71f6011ca18c6573c2708a8d1acee38281456fde1cc03082c406849daf14cd68a8ba908e4430264998bbe63fd4f391fb037dedbdd0d5eb7cc6305b2442d2e482ebb5e5ac16226f9dad0b774caccb134a357e44544baf49ed42c35234e4c6cb1149e93d12a31863d8ccf1b9b3872411db2716154fc198ffab802b4e0aebb163984940a80f31b175809f222f4a55ecf397f2e51cad953796797a5480dd1e1411c3fb91c87916aef49757e1c55860b92ca100e05b42a0c7828360a72bd52af2a5b0da29598e44ef20dc35521093a8a9ef6047550bfff1e2109ad68b39f181eefb8f64efb2d89f00e490f1914fe034e47f5bf24c328f5c84dcd0145944d77e215817772f0d7cfbbe45fdb1de3b21edd8eaa8089e1ac87146e45a2c1e308cbcf1443d6a1b530a882c52a990a2c1dee1311d60cac89e4e2ca7caf251c6fa8eeb33e5c1b0bec99265258e6ef3918d2f58bbc7ab2638df9f00bfed7a7f7cf922aeddd4d47de4222bdba9ebe81c536baac31289d7326379c18c712f2b55bc773ef2f8f62d951adedabbcafe520e4797a9d975aaa1207476d4f4a81f13d880790889456bb29c1d371b972ac891401fbe8274755d6913665172e6a8d6719da9005b26d8270e080704067037f44d0a9592702d06d513a1990c4ef66672d078358d01a640e19db96ede7d4b34c1284bfea6d2d97ac0f3e300402666f9259a252981123a2849142f962811a2de409e9091e4c577a5a1e8994ebcc719c40e73d2dcfeb6e99d9ff93450d5859085e590cc00be8b167ebe60a1e39984671189b79517eb06b0293a9c19eb8b9d2ca1d823a19aaa68dfac58069a71c740fb7deb454d3f0b3ed0fd401f3b90179f4038b9b1912caec0c16459cd57d003458dc9e4d2ca632aa7c422d5e341e909b2e0faa6fdc22dbae95f7f6f542025731ddab45fde50f6719895adb98b8c4bea1adc8ab309b5814163651fe48bb7f633243fc7ba97e147a68491e322188a41124aba759d268d5bc9ca6b9257a26434bd54007a8ae7f7e1dc76c7db57779f871a89f60d203240ba36ea51623285beda8a2918f43348cc13149210bf103af01c951d7964ef4baecb1e28595279557e1c22eba331a991b681c55f09917dd0c336eaffe499beab4be9f646c0e33b33e5d58d792ebd6621090b0ec555a85f5e7c8f12a64994dbec01488f964a9f7470d4e242d8689c6e02b3b7b2104dafe7c69e946c482f164043c33ba4ed9da693da30b2972170c0ed6164742055a87540fa6cc45ddced85c62f2ff6b2e3fee6859962654b88e340ac4db2592570d6a2c470e4bcb64233e100f6ee8785861e2994bc0280462778e2bc54462d63e3b67c59217362f7b1f8c0b342386ec214ce4befa6891de13c1d9c9737242e7ceb6a16c997bd226afe4b641e2f4de47e79dce559e27a6af620f2f7a04445994efe8a6d5bca33b557ca28c9fc450f60f56ee8ba1d7fe5f3ac8a74f4a97bd3fe51ed5b39056deee548cf77c6c9a886e012240d424dd65f94b086df10eb8729998f4053d2f322e3642cd8dc95ab529c99665dfb9b090d1652d9195953a939b7bc24a5914b44a21314875b3b2eca8424b380ffca43a23bf634c0842d03aab8855b5d30503a6e0e8aa3d0acae57c71c2fd6ddbff5ed1e9e8bf7bb11f45edd5281cff9dd13fa90730e4bd652655171fea84ee176080b2d2e522c2ead0030ea5df66639fec8fc6374ddbf16638f5816098a037bcf1796c3266a24644b99529201ba0596057e055cc682664a6daab516b5537bde7c126e8067c0b005757ac063a6df2eb20692c42426c957614c96a4c05456832976d52fa6397eefa514d31cefbf9c981cd23a45bc7279ac47ea90e819025560da373f4f5652976910b8db03ffa436afb1922409c49d38e22dcfa0c08d3d5c6cd00591c76d29854efc3161c4ea62b12af967657dadd65725abab470b54a76528014df50faf8aad22d555f358492cf08b231669dffce4ce3c5ec93aa4c8255557252b38d22bb5562195e862da373f43fac6f3569dd01c2134c756265549c5a192956455f207cb881019ea1092e4c8194c287571ace1b946eb7416c188278cdcf0c5102152c000315b411648aa1871d4e34d50c1c5062a525a40839e12c87c68e9e0040ce417940a8fad56da51da51cae36edb566fb4007f208e95fb72cd29536a867a94d475df65527743840e200f7177f9c743a0529623f3780702ddad7f5ea5c367b747878733c0d0198f202804a027cfa703ced2679a81c964329d3c4e191b6a9529d1cc6868686868688eaabbf8c9736bf193eb74167ae3398d45e5b81b38e01b7ad05ba8aa894c62602f5a072613135d12bbca4682567942f45c8216b2a01b3860521e69483d3cac998787ee89fdf21477c4592842a14ea79a9a10429831a3ebdc95c3c02380341eda5881c726b21fbcf0d8b31b10f142d621916a68df743d9b01ee3ce3ac38d2d41b38e0a67dd3651e27ed78c85365c850eb9b3ee357dd8bb1d78963eb08516bb51604467c49a227051f64e9b9e00b3f664c4f932d8fb8298d522fc6dd27cf38acc0637be0d8df3d8451e8ccc28f1973830b0633ed9beaa46f3ce38762f22db5e594ed52002e13919255629bed8e0d372c2600293d7bfd30041b22ddbe0940f75bb1d69368aaba995e192115f8af8ce8a449b96de3366edbb82dd392dd4c1e2feec53867a0d50f45a1c2d0cb2995e3d127cf9f49087ae2d8c2711ca7430f305a29041e41ef406d6e3cd33cc15ff6aedd61f23e93b86db39aafc66835c3f90067382fe7f8b2979b94401f5ef641df851e167acc983162c4bfd94b81c644165e7c706c510426710593b8fa52833b5f60af97eeb0591e7409ed1d68e8033df9104a48998bfc26573f3a94258fa0dcd119383f65597e5084d75a5d0491d42384d943a74dab8c0ad4c6f39b6868e46cb9dc7bef75bf1ee6c0ecc60cbf38de1c0e905ad581f19248d5ce66dff7716036bb2008613aa3a19486e6697470f8051e30c1016a8397549aced687a74dd8a1b31d1fb000706c48d829877e80e9a0369e1bd03b74466bc08417b1b9f0e2c5cb8d19de2a0dd2b183e4791e2913b3b97e06c05772b735deb3caa10044ff98c063ce5f6b506bf5ec63edb65119133accc009184a2c390248f6254645173d40a9719c671fcf3e9fe77d9ef797db2c6a2623c4344d1c1c771c1cf7a867672a50ca5ece51ca9ef73535843d7b9b0e34b00f78c4291ef0684a2dc1e30a9f3b8f5d96808d0e1401d5d2e50e5ce1c110ac40b5880d8aa0c370080e8038e27469a7085cb3973a2b009504b7ecc3a966d10c29397414dad944981f61868823ce298310235f3ae1590fc4f3e861fe593374dd753f80920a9027ddf70f89ddb5d4f9873c4565406a10a9161c744ee725589ca0e29148a42eb7e9aa0f6257665db440f91f8e84dad40287d6423b49ddff0f9ea234b802f64fa2f81fba3bef7822d2c3202ee42c0fcf28a699c5df7cd60ffaac8e4422d57810b218191995a86a07fd68314aeb3a377ac0101e296d6c18d8dafaece14582aa76fc090634a7a9ce1134a76b19ed2a524000d0a811edf33cafeb3c0fd641a8cd0c7dd334b412239a0d62cbd0a4ee193a194c4a7018d22da3c642ea2fad45676952d7795ed71eae7678fcd4266db54a5c7c7c6231ece333c3df25b591d17044ac4bb01238040148a8c214534c61b2e214dd2d560bf948820044e0b1cb13767cc02a6880aa40188177f1f04c41ab5acc0c16b40a6a40944100d14034100d84388b99e0218f8760088da1051647514cf1e26bad65f92da107309d44cf3e13a8d5940f4005ff122ac6ec4ffa878f81e6bc389bcd667ef34f338001eda2eda2b276519902bce58524495cc92eaa3b0070c8008f4eb64972d9f3529f1e92720e0fa44feb599bc6689daf8118a49334d8d931994c26ee72e40543a885845ace7221275b88b6905009a290abcb65e9260e2e983aabebb205684f0776250f34c9641278ff9449e0cc05482ddcd89fbeecc994baae8512e8b3fa40a098bfbc9cb17ae6ac1d2ed64869dfddb9207660975b1d7873975de8a13d3d45cbcc67f98b88d21e3326336271b9c199201f2e568be84f660bb1a09844ac8de3b81a3378e0386ca297dbeee5b86e6eab4694c003b6b966d3ff9b4c2653773fea05efcefa00d5526bb5b63e4009eeec1e702d0d72b475747448883e840f4130c15e99db075718d2d82cf76da50810401c69b0807d74946a33bb1105d53aca1493b39c75bf7f2cc63449922449926fca395393a9da18a39d4c3dc13860786c99739c15c79cc37bae8d31b04cb73ca439eea2365842086186ac6564cb6acf059dfc5391194070bb48171e5740b9e631e46ee6ea46922452d691322757e0b28d244b5c6a12349ad328ad8b07a84d518c87da506ae3b4cbf5f0b0561b33cc3997b2d5b03e79ee86c5362f778a7039b618f1f49aa78e5225f65c63041ebbd54734a7b31754e769a0373407652d1b9d36b6cc9d46cb1f84866143c000095813297e6e1143cca2bffb2b077aa06fa0a9cf2a2fdf634dfcb583e8201734dc8286de053d39ad6f9ec525e6a2362dc3f212a550a9b16f6bbbd65aab189146333fb8c19636890e1e201e209ecf71d7c2135541ae3e79aea93165c1589ab88d8307ec2a410aec1a22fde5ed4de88d3be9a5b596e3746c1f0f50fb0fd4c62b895ee59fda95034d42777092742da13bd0d09718c2955c9288880c7a15a5f46b5f6ba5363f6569f117efcad00f880a86a2f4a4004716574441b5888243d11c1a225e35212ec0713c944119c123c61bb6f8ff51280e499964f56d96e3b8d58a8b8f1c581c715145169be5ec4672ee8ef30344822df179306af38115e627afc2aca5c1b6cf8319e0717be229224fd50c8b4255b407ff8ccbc41258bc2f18823da930a20dd6ddfdffab708331b18232f394d7130ccda1b4c7481633895000e0e1bf56fb4646464646281c23a02b3e4abbd66aad3bcd7bd89ab9fb250a5cf0bbce5abb6971f1bd5cd77597eb804c40027f1e6b4df580cb511d1c12aae498704cdcfdbfdffd77dd77f927079037e5de5a75b6c0413e58be32f9cc535b8f17688f190a8e5e4f886035d812ad56abd50abd562be756b75a4f543902d39382db9aa2a7c9a342128ef48c5d3689ffbfebb2a8004a1960eef8c2245a71447d972b1884564a5be1bb6651ab7539211a0ddf32871984888a6266cbfc09f37f39d05d9ccb5d25fc8047ea52891544795853a305adf345f48d0dee723d11234a74aa9a017926a24494c8a8d65a6bada61ba1368e03d143e184494c89e938f81139d69d381357e22e779d2048880c3f6c15c2f3fc9ee7f99dd7b3f7bce7ad5d319eead0744f934bf4dc953d62eef2b0ef977b7ef7fca46010826012c0034cc13328d899e6f2cdcfea5af7d68eb044b8b5ede8cbad8a15780b91ca5857c416c7ad8ba7c6adca154f8d9b162db4cdca26dbac68f9ffdfaac882c0db152b5af0b85919bfdabb3c558fecd1767474cf0af6f0f0de8badb5f69ed6a786ca942b5a2c276eed3cbd53660739380d1a3468845b24f04d883431a633c06ad2b9c9b66d546ceefec801dfff377958d70a33090af427300c733699eeed4a25101b61238c6f2c815f1c51289ae33ed48a951802b6f48c214a2cca2ef3d40c9d91c056c5076bccd49182c76ae257794fb71525aac07a362b6ee819431c4ff0584dd13480185c8baa59633bc0344a0e68621b99b11a200f75fc690c1e69ac55f0795535cdcfe7a79a2da8324c69dfd4ff0732bf31a85beb33a2b539d3a0a1417b045bc1ec211424718b526d06a196840459e924ba054705880ca0b8fb76df358b3969e2cc2888e89994a9d8a4f20b722fdd9dbce58b74dd90e2c3c3ae79a4516fae359ce839f9dfac160a37270a3a010a5ae52492071e88208238d2da58492918041b5ce01e29c4720055e0f32e4e9da808b5711df1d04b771be88dbb107ae319867222d4c684f6e97ac5ea449e22527a99f40e7bdd203ab5e972074f79a42f437992428f1649798517bdfcffdbfff68f82dd812536fdbc9a1b7a38b6f881171d5281b7ecb9b53dccf3ca88d46c61d3af5fbf76cbdcbdf7a2363072f208de129babfd22c8530dd39fc21068ea7ae89ee96b84f96e2318e11185ab587b9ee779a2fe5e8c513c7955cf339ff9cc673ecf9c6df859ca57d6aa116df97bbe0fa4adafc1db423411040c5d5e9d3dafb28d31b08bdb8fc9de7f19850dcc9c386614c68e8978469319a97cc68c10603258587b5c76543b6567117df25c2315e1651238a6bedc816309175603265a0625d9f9c94eef5ba51f97c164660c46e43277e24abb918c526aaab5ca649d7b00839915d46b351282e8d96e338b2da3276f180a8381c52fe20f5bb53c6d966556dfc72bf695ce426dfc0a02e0594e18d882630f755bdbee1e54abf56c362bb5cc243eeffc403fcfea5eab9f0df072263a698ecc23712449a82a4482c4343e123f432a70d581daa0509a9ccc6012bb09a037f40692bef142074968b71d48fa913c927befc5f9291129939465599665b565ddb6b24b99d67125a2e756d2a628b0134a5c26ed4434edf054774f897d34d9ba1de99afba6f2739cb035888481556d100c4a4899eb4891b2481059ab91ffffff8fc29122a3442e6f2cbc5841cac2d72f71b5725cad5cdfed05524702abca61f4cae86dbb11694e49fcfc317a728f55284fa8c3761cd5ce7f9d2f1811dc3511fcb130a8ea536168aafe50df787e1bcea1fc53a8cd5c1c0c189e654673a8cf5e43adf345afd6ab5534f47ad517b5ce77e91bcf1f7b7decf55f247a181a7641c30f839efeec9bda7a014c2debc7bafc0dbcd40d3401263bbb38c1d417c280d19c9b731a48a7aa1227ec8cf256ced3d2f08408763e0c06837d0cf631d8ab9a2461248cacb5ba8ea80d98be792fea0c4d9662889eff0bb5793075c897eaaa335420bf833fff3c85903de860c4b48110c5e85e950ab6cbd5fa97340a7300dd31565e7b670bde38eededab59ac27c213ab5f1bcc4aac85cc28c99e666fa8f6ddb56ab5527d4351e05ce2c81472afb799ac5dc9a59e1aaeeaf096eb7a3753e208289b78549579849cfd1a3df4284145e781012033067cfd7dc9a7b7fe3b8ad568eab3574ccee15341ca8b3faff2412a9abb5d64a3d544e0181473a4bd900a764b8451a1a6247ca9d3faafa389a201d3b3e4beabe0401212978d7c81069894710a9eb48a495ccc689511ee2fce400524187873dd3f1d12875f7d4101c0fdd67270c1e7170dadd573648282353436bbdaad612d91a76a5bf73233894e0d1596e72220f69c8f8c1557de42ea49dd5479dbfcb2cf9727b902659ad1caea460fff1596f6531b7bad662faa893824b36bcfc775f5b3ac1c697928d2db0e70979e81e0974166a95c3b65d5f263b8b7608e4e5a9ed7255ac380c218937a4d8164ba8f5d4088a8cc6864c478afc0a0aee5ab8556fadb7defb7f4bf536b5e948e28800d1d288921283b7986f76d31caf81aad5c8b6995a50150f7af21cfb2954f5f3614840e963f92cdbf65388fe577a983487db589eb259686b75f904fb263c816da1aa6fd2849ee39bf41cdf1c81c8d5f02822ab451f7b338ca21f99acd66a32994c262f0dd57a499ee77920a9c65d7f1ac105f852cfb4eb6c177cbfeb4a6882c78ed58d8685144f340eac0bdb66bd0ae712d09b64dc1448ff480b79912095e436f057b35e36a055fa097aea58cf5a8aa6426d62fdfaff078ac564b070b95c34342e1a178dcb45530026f0e8664a0865768bca2ee9822d7460bb4839c504b7b73c0617c9e522f550072894c9e425a0a72cf4a8478bb6680b04fdff57ab2bc5e52e58fde4b99af57fe706de5dba1ca915624d8e722683d6f92aca1898a54985508b655ed900cde9afd59a15a5f62a57a2672da0a2c4155168513841c5344b2384e8a1ba69659aa511b9066c9d1118b0e327cf455730ed1b93174cd822b59a7559d2892577c6c0a3252d4942c1a31503db22354b5a571896b4a57d59d2ba6a6358d292d7925c7091ddadb5dd20b5f673de8ae0380e0e0e0dd8133f9c5583ad05a7042b564f36f3330fce54e0669b735cbbe50ef461f306cebc8f2d5f70c6859ed51735a67c4d426d3348fbd389a9c881335dc15a5bb02d6c27cc5480cb355f80032fb0814d7e9b7fa2311eafaab976998939f2cfa79565463d2b5fa46be6fe7551e3ac61abad71ba0bb08b22bc387eab07eb33f809066e3fcff3f473e361e7070d1a5d69d01caf11a8b55b346c8a06786ca27b3fd7d4203b0ca98d97ca17e9b2e1e587be3aa23249599665599665d92a17829e9cc669388eabf5fbbac05f1e696aaae8719f8d2e6a78d0659739ec697826ebd80a1ece48a0cb5ffec0d105b103fdf525095df0e835d1532b78e84f501c5097a2759e84a1860529abbd0af513a8d5ac901dc9eb3c528d7c1848d7912ff24586a0290e063485045539ac75be88cb3c26a588bbec8bb4ce8e120d776b7e090d77a0a10ff4e4444ec510af84dabc8b7956cd43af39ec612e93955fbbffbbbfeffbb63f82e664c6c4e8a3a623b0936722822ef3263e2db23896a625f7af6686e840b44eada26fbc09cdf9befcf2032b15df47bb884d424d80dae0d4d861ca6e6865f9b509cb8ca2fe5e8ccb1991e93da859382b67384cccc968d516400513402c81332d039ce91c38cba047426069c2840f5364678f0c4f26b7e0e5526ee1cb32796c236b29a5d4d451ca1e7d97f94ad9cb30c8e44fa686c78e0eb08f263e68145314c1a58619abc70313f044982a60f602dfb973832e8854c441a1ac78c19dd5ca041e73023eb11c3f6254007af108d2b1c36d975be02a52008bb6bbd65a7a50b44343cb6cf07abd5eafaaaffab254b5aa75655a99baee5f260481476a14c3662b5d0155ad6268cd50e640c4445faf154b056ad3371aa0605e445b30e065000334870486cb1540463dbca21821c45784acc1c7e7559ffb6881bdaf842078a433e06a0c30c33702396f62e76deb68df586a83f2c941ad161454ab05d56a4a4e0da60896d8e2c5301c4459def22bcb724cd79562497348103ddfd7ed81e6b4f82aad602ea7b0656e1beac0dc1d4bec9a5b7a986305df3cdef2b2c4f1961168cf9d8960bd573ae12fcf77e32db72c4206ace0cb12a938de929628b03dec5520d086e860a4872e37f0d0e3f912bd8a6708144ec46c4144891a7a3cdff2befe5e8c4d6559def2963806a91a601ac3ad81b2f60814cd66efb5dddffdcfa1b6314fe98f19c10598ded6b9a26752ebf8adb5d65a4d88826338866338866338b6a3c6ec83bd6a22d1a74bc1824f8a2e342b87d8d4ac4bba582d6bad65b1bc2aa6699aa669de8bb169de1fe2a59ab59ab12bb32ee69169a48576c6bcc8b49845e695eeeef6e25aba0842b284c4a76fc282698da2ea31b3c81c823da693047fad6d9a5128ce949d26a863314d193a2893e02fe70499564180167d222dfabeefb76d332168dbb627f9500148c718b859414635aeebba7bbbeed640e144314df3cd6b5ed374ff863757f37bbbfe1743f14588494f0a64e050d483b30cf08256ecf3fc0cf3dfc41103267979dc5a41dbb69d826027dd3cde2c7e147a9af2b237436a8a32323299beea4bee7a58da3e710c2bc0f5fccd1678c4a229de3b669301ce484046ae390232c01eb694ebadd94a353c3cfcd253f5bb726bf926e41bcbc39b61a02abb85cee88cce4c2dffdd6cc531c439c70cb0cbf887fea92ba5b0e38adc7b000467178c3c018382c81731c648d273c2921860e1ea92c5935a8f0b34688122491632e8220a263d272881dc9044862a7620ebf1cc639ad65a0f7240922449d2581d813b8b2f7619c78f0767029f2ea8342fd86ccb680000a005f31400001808088502a17040342016eed3f614800b5372427e66469a88c3b130c8910c04310619670c308000420c3188c6862800a190a769de89c8a21100653584e802d9f7c02768b25c0d030bdfcce82758d18587055acaafbcf421275abd4028adc592bc49cf66d98814ac47574602e93d170ac25ca6d0054d3b30f0560c217cc2314f32bd1f5eeccc742e11a515486fa732838bf4f33a9550903ae08cb45d3cc3d5493246422dbbef52948bda67ff3b2e0303ab8d68b043059d68572a82395781704200f54c4f2c6d34a0ea26a0c3eb07bd1978d3cce2ae80c85b57f1f9e7e2519788dc23f6a4111d143da875a6b0b1e3a5337a141136756f23c0d66e5a87c734c8e47c63f1cd9e33b9262b43e12f64768bc9eb8edb68934f2582b3f6db33ac93999b5fabae648b18f4d5ff6c67674b4b5989c93ecc6d9f9f524d8250fd33f35e1345c0bc1dad9ff3538aecc5eae7816d0084f45c0fb487ad4a8523fa2fe590e5ba9c7d1fb767e8a3d5dc61f39b1dc37af8b4946eaff17fbca3ffb6533ad7c38170b0cd85a72813717fa8c47db4560a9d723df5e851dfbba77c919afb1330ae01b2558cec487d993d98791aeca63aa77205e8d0c5781895a0f7f101851e7cc11b1c64bac7c3d93ae30b2585b1cba563d19fc3c0e2e086472fef3069f1c460fff8fc19502cdf589c3b7aee55b702a228d7af80dc1780af6c00eda222988d0f072f41aff7b77aba4ab7b956c41374c568f4aa34c6075f345c8cdba4025552614ea2b40278786fd1d097eef43bfc7c646aee44da2e2a2a5c18a2bec9f89e62170ded53bafec52af577d4938df746bb4171d19052989bc0e76ebc5d8e140f5ddc13d0091f4d9619a25c3656b3feb27a3401bec6eacb0d9aa55c1d21e04bf37e6002093e60aeed8207019904ed4a4ec30e1aa87e0b1152694d26a8785acba161a4df698f8505d3e346cfada6447a0684e6b19af9b00279d871db58bdac3a865c7412a72499bb3e4c823855ba34198f5f046dd4c2ce480979d9fd124dd1eed230794442a464d30dfafda7b87406d86a70b827a764e7a642af6ce03f8451c11f44c445938cdf6ff2780ac44f11209c596d61c687b1e5c5aac34f77e495c3811598e4cc12172b195310ca4f768302a097863f4e6e38d3db6108a3304f2b3db57af373214d034f4a13164bfebdd269a16ab57a6eca9e3f7aa45571b0ed6d281429d6f0b49d8b642ae4a206c8da63759876d5b557520a01116bf193ab496d978b5ab768ba42ba8e0bd09558bf7eb3b387819cffa66f1174cdc88ba1780d3d5cd30198b74bb0d700d17dc005bd669c3f8e83f4412855c913f6cc9709268c1e28b0aee4450cae7952d69def00bdcff57cc2e4685b14fd214a4230dd730dcc4cea8350a307f031fb4738cba83b1cef0e086c80c232f7389418ac0f0c2013b32dc8fbbf06dc43b6b0a0350600047d5deb161f974f9696f66577acbc1b1d0b77ae24ec21954f38a319c0f7e1d90b1e3235232cea906ab207d057c19bff7f818acd4f0a1a4664aed07527b942937b929077ef13a71f8602357ab57d2cbf165a9f8b14dd72801ca8124abcb70948794efad203491ad8248ad1e3cb51df3220405ae8e8efac9c5583ba77af42a35b198249e1455d475f6ea80be880150935a2849d6add4dc005a37a01b43343ef31632858dca2a5f4f51f2518ec473fcaba36e68b53f47c45f1ddd9c0f886fdb3daa870bccdf76abadc53913953062272f0d2a5f8b766899cf04b801216d8d165c1f8f4525ea2bbfbc26df8e7a929fad245afffc281ca4cc099397d1ea3a32fc25b45435f8cabca52e9b38e8e76d25f06d5ee5824f120aa54b6785a6d101068102e201aa578ce51a023944c213d96935881a6566c956cd06952c414b3c8f6d22618ca238a51b8551635658aa92b1788f7045ee19ca865282d134413b1ea3d998ac802e25961bc204aa74691a3ef1c4e3100bc013cfd56c1611dcb287a37085dd4cc666be882dd35f5081696568b52b3ef20bddc0b423c91cc80eae4ebc89d9b42fb5212e1be3500e48b0c29348982782826a5c5e0fb5af97338ecc71634f17a9784c29748d1b750a243eac515bf59667e90499c3837171fcbee84d888d3cb7fe17d8d8300e3a537f22326bac6bc193d72d87b5481b41f887c75030013d8193b2b05246a9a8d6b342480d6b3b1abe409b568635b078271fb4062b09696f95aa3c91c0221af8c987d35c84f6017949eb8fd24acd692485ae6e05150bad7ed6d6b9ee27335476e852a1efcda97a8047058f1b6a7526475ea51f3b8a31f045e6657d1f30a33534bfa2d0b55094bca893cc768e90a2cbc52ead617fb3e91d51233bf96f5bdc123fd964b16d3d9a3b38ed18db3217e40fa75633c5d79b3547b42d35c68cbe338e1288bbe7c753a0e40b858a464f9a8b2ffd3d875079540d712743a8eaad990290f1a8b65022255121bb33c06fe7f0481b631100e4fd422d077aaa404777be0fef84fbe104654002168940e8b69082d99a81c50848c16c81241c0b7298bcd27b5bdb0080268cfdb31a149870c2257c56d72b769505eff1fc70f7ff56304ea8289d385d0f433896215d2ac6797e3a79f19ee97b3f0a5d39b51b5f3a37842276bf0ebd9136ffeb8f999f86ca320841bff0a8e0d51915905aaa85753be39f58905e3d6244f17a662f15487c839ec88d19d85ca778f81c03eb746d4caaea55af2c4d7847eb6983ec041e5d1023cf15692b8e5976ee90b0990474a6653aba3ea9f944ead33c5b3fe07cc6c932e11b6f603bcced4ed60839924d65d5b0ec19c4c1c5c0aff3fe6770ad60ff10f967322fec6569fdbbde912b647fcf5c544071e2b736fa1886a05d6477638c55a6b8804d1dd8a3c9f6d73be15f970e29e87ef3c54e355e647297432d4324ee721c902012a68ca7ee0321f0040c061770b8ce1b39f402ea0339402424468cb0092fe8a9ac60d42338671fcb3c18da7e6b8feee1c0d49db3eb5f2fd3f208501685d597339819b1a203f911d4a3297d3db1b1a4efd4ab574f1af78c140afba0806cf0758c17f1a75520a10d76ef41c632456cd4331700ca709a9769c65339575e4e23fe33fb0c5c281007529e0187c94f2669cf0bc143cf3704f1f50d30a83b7f4367bc2f467d26fc28309c8c5a21befb866930c63a1f2a4bf4178f32b8835814ec448f8eff6f2e1ad51219ad4db1d266c5127f0d24e2742490c8191253dbff0bd30009881398b87b55bc3462a7557325e4ae436e6a532967eda128142d840709dc7d29a8b644c689bec1dd2f7f4b147a7c41b816ed93459540e12ae409eaca6658354cf7c148dbcbc76d35a601f46acea913e0287fb75e722a5917aa716af5ec4138d21633686846f688b562fa7e228fe92ab34e0a59ac20ea2d049c5282d53e7b4d77e8234ca58f8c036e0d7e1bfc2a34fb869bcb6c4055c63e427253f13e70c93758c759d3c0f664ce753a4a89a9ded9c520da85936e4930dd9583b7562042579e7fbde4f219b2f7a9a46f62adc0f9c3381ae8b11a45f1555e8553837d9afc77894badb35cdde9d6937f07d2b63a7e615331357d33073d2c6b73883fa1431a39bc9634d5b7f0f9696a55d87a2265c285ee248d664c66203f4fb7b997245319cc2065cc125039d6ee921fcfd81158df5f7204b9a11061e039586d8c2a1b897dee370ee5e49f72939b7be399786c997feff7e2f476de3b672d9c42d4c48a3a16140fe135d43d4025d76d5162f64c1ad235f6b489a4aed3b4e331e1d1725fdad30b34570991a9a639089915fa4efe57a991291670cf30633c5395f145617022237bdbb66081a8711bf84eb42149297cc14ae45595ea690f15e06ee35587c66eacff8c856e001920d4df2b93f8966aabf88886a9a298eafd279136b01b78497b6664c80bcb764b94393ecf7e2b7665a3794e49755f72d3c2f16cec100762ded2fda6b7438a58a688329e44140a18d25efe35ea761f902256aeb72a7af29e9d9d369ad3bc7bc2804e0dbf4c6b5f904790c5e4816e6c6c01695e53c02b24c2831d621d7340f4e54bb1da760cf19073fef20da141799b4430c191bd48671c88f4aa947151334cd10de18d9d6e0d4b45aab776312169ec29bc2fda5b8c51426f6fb72c06fd0624867d746343c6d126f56ac6536a6840b4aa9472152e85ddd3bbb19704180b129cbb99c96616d0497a7cd7f230a7b6e618065d2317e0ddff865b7da8a2bed0588eb921a14cbd50ce36af648308c8efe693b032271b09528fc4fec212dfa6f6b5693ce675680928d4d2228f3ab089e3e212a7ffcb237f7f77f6ed3d4a8629e2c6e5cd4c1d44ec0949049fa3ec018f9ff8ae83da1d9f39417257a7ce3c627fa36e885cce284423115d7a0628be883b4ee6f710c10d001233856fc363cf83bb2cef91eac6259ed0573f4c4fccb8e4cba67de5f1d7103af83f928cebfcb182a44a093267ad14523ff50ad5c6a8c315d352f1ff8889227e096969709c06489d1bb7fb67d5b52033df22e301b689950abffcac100d9cc8cf288ee2185c4c670483c2330f5b989aa0e822913f1d315c8e649c4b22a649b8bc21dec1ac51a08a358a029dd6e13769cfdddf10237441824e8f14cc229f3acc421320b15b6048db0a534359e96df26e78ac2650c927363d7f7b4c2d8b0fef22a64c5914939d05ece9b1c922a92af013c24a6241fc6019e35a187c6e0b97399151b01b714f051ef5efec953a93c1732c3ee38294330f55b17ead46789d7d2e5fa548e8fb95c6ba303845c2fa54f99af4883d953e57f26568046b5927d60a7de68a718cd9c4c70d99d9ed8b254c0d02d1d457b14233b14e20e3d667a4a0fc96accbd9614a81c8093fcf9513656a3705f90d0a938bf43af8d58964812107c676c508fc7e323d7891d79e251ce710763d7aed914fd49ea098c276d042a2ceb45ba4916fdee54e16f611cefc32832c6c1606d71dc44116277711a9d437edf24b678ef1e6d78f3d45cd009f5371d3e7faa96bf7e25409d944cd99748240e11b2a2837b3bc94dbc9b5f2a262214efd90643f69dd47be1c2b05452fb04ad35ba13537d38f273a0aa5ef1e5df97fcde215b22ee97156a741ad5ef32a09c9908b7af122f309326ea5cc3a03b87216933408947610773dd70e7009b087344884a065c87484121deda941a34ffa40f9027442440c1477013460f73aba8bd959aeb52f1f1e46d717f345806c2231517e8d77a91a2f8b10e10c6c36d444ee2c05ce24a8a89cbe1c4193651740422f77e2009558f4dddc0f7ae67a0969649f46c301c928ad9ee4743cb0efd39e98a07b0f60396b52cf8122c0095191f29c6bbd9412e033386191801e22ab92edb9cfc839666c6c2f5a4ccde2735f4139af129fb6b89cf6dc03918c554a6d4969631038a902d905ef63c602a09ac1c26e49778ed28578ba93bcd447c0579141905218ee9b5a13ead830c1c64b56c128d62f4d3c32ad3aaa430dc964ad27e8a4626f0af6c434ccc29dcfb01db7c0e44c6140d0afd0cb300fae653624937141cbd1df5dc07fc95bb9511747f802c816ed0c6572aff0ac8fc8bbd40f13cfa3c54f1190a400bdc58331e61a94e292b7f36f1fa746a276af106db7310097c96b17b2e662830d769831d6d85a322408bf8b09ffa4b05cec2f3785a7f5eb9a223e8b4c014a65112dc02c1afed34a4495d5f6e6b1a673a83ee134f2fe279e4c2936014b1803496bb9577494abe5aa2aa669bdda8a26caaed94bcb9f6e2259b28158b3be90e2c53966a684111eea2b9a8f760267c6e8705f37bcaae6301b2ea8459ba3a08ab1209153e11bff7aa34752f0d4a589c51cfede57ee7f78c2b525fd2b88cd26ccfba956eb405be43ab16a5e1c83dcb162a5e2fb3f42042941db5be29942279a65308d84204ed5d628d178c8786faa54848a68ba5eb94c40252d1d0b2dc197086928c743a0c501060ac6e0af8232a1a8a0142078e07ecb7103a0c7346706f0c60c2dd56e72ce5a1b3de12b1246342a8e51fa5d43dd6b94e7fec389199960275c6747f55f114fbfbacff57798c658227164a5d6e7541ada18a67d1e117168f821ba92428d3635c67f58b2817ead7fe61425a9622219ea2defa780d2875d50c5150b5120799b1884203298a01ae8a507ad7700dc085b84a55d60531e8d793702de851f2758ff0d36e1a86854c16df4f7a511c0cd982e719018b8097750ac3c8d72e49f4d1272181fac9da669642a45e0b77e978a4238886cc6345229f66b009919bce5a55fdd90ec77b9f47842f79595a3bfedebfa2aaa6ff05e3b76bee522cbb62485c3c647edb821eb8527365c8c22a32396c423aa9dd0cbc433a82c18eb2bfd133e502f61e50d91026b75cb98acd20e1b7340699ed83bb729ce521f6ca50962d0a4e93c44d0bbeeb8fef69adf802e6c4d205fbb93777f28b88b1cd9f816b41e5cc3de466269bff703945b93596f1505367efe8824bafd7070e6038c5bd13f74ff8401138a308eec19fe00128bf6565857a0ee075dfc0660f7b8e2e7ecb0b454882d3ac343eecfb13bc47be553b6e97543112ed2d4743a55647d62060a3076da0df22caaf9718a7906ae36543b9779447eeefd2f64ffae40886d7a6dde648063c9ab759593bbcd56c78c9384bc61ab34e2c3720d2ef433fa71a1f7e409f5465be7bba193eaec48dc1eaf5da99637c56cf90a38d1fcdc9a64463007c5ba6f2cc909d24bc87091722655dfbd1c1422e5fd4c50b42f5780b90747d5a532a40e4288064e6761a7c6a2a17405ef9633bc8fac73a30e29f63dfca9c0d24a2075aca2da2d370c1da45834aa3a570c6da3fef1a85e8005fd5471509d8271b661dd590cfb63c8f6337e6b70a08eab3861acd75b2ef9f721c17fd4c345d34e9ef7ec2a13af899bf4c94a5df3e8c4f4db1eaf2a96be779b87462fca09e8e920f8f2495694c23c85b71d70856fbda816ea210ce8d6020a1e743109f438094cc3063c896b3b926f95caafa1ac621c9ec772ab8f9b1130f8ae322cce5cbb7954c456dbbd0197e871c5ea07799080d7000842147bb012b92e35d3d1c042dad14b49c8bd2e1ff9e76b5ad32868e3ea42af49ae1cc990df715845a3654b272b8d259f8c9e177f4b47453c4a3d8080c06d2dad965d39217148921e28ea013a41eafca314e4bd6e62b5f1556346537b42784accacd0e3a47d7b83ae656315bc361db680a6799139a4fe2ea7b2530dbd15f6530f4703647100aab288fe6d0dfc9c459f66c489d219e43b670cbc5a68fc4f3569eaa62a58bbebed44d92e0c17b2e03e5eda1b33d8381ba3a308690518e156fca00c9a72a7a7c57b25af4ab9c93afd094afe83a0018c2ffcfe0e738a0082c86c3a29a0b0ece641f08edf7377b9a57dc8405670d1101653e063a4b785f9c28377190817344e61a76c7409135d93427e3e8a576aca3aa1d47987b57d1ec02afa3b87b804472c13db1d40f0f9f98d86320dfedc11af57723f511627051993eb814e015f6c802f5a25b2452f8de9397f150943019995d09f5ef62488befb1a9c00af643302ae808fe4228e31ec8141382a81d918d3c828f803d96877462a7899013c040a70501828b699b72139a7a16e3e1ae6b13c85096edfbc355513d06530cda636577fba28ef9503bf404507541e57fe49232824f5278de9bc67bfe28e673cf16afcc41298330692e074cd5793f3fff00e5a58c9553ae0f5dd8864ee9699f4a596e6c07890ca47f8014bd317213dd108e06e0fcd2cfb5b8d4ca3d0afabdb01c0da2d74bb09dfe86450d6146367326662e979ea06511850ac340cb3efc2f0ca3fe41d15c989cde9d5cab020fb9fb6cc0016b6629fe1442a58f49ae121e85cd6a9b4b03581b0e2f276573f8aefe296404691b70578041c4b2ffc36c111e0bebbf1045ef65e8565f42925f8177240c92e615126472aa75f21fb2aaa1566da706feb940923033fbf4345a33dabce4dfcd2fc39ae3595c08b2cadb4251936f091a985e5b30ff1c2dfcda18a9e2114b1956d24e373157733597bc9066b48ca64198b5be1ad5a0b5ffcc44435afc1428dc3a16c43f1d78a9f75c08312f6566dfcc26a41e51c1c4b91e07e5ffe49c03b48480babef3e1d03429a44aaa750c6240efe5003db2163e217a7bada8d8ddc474ffe8bac87b5642b1fc62920ddf04ada97c78a632f41f64614470d4828d7c949a2c518b15f80b5f57222d42c1111da4451f4ad31c40e4058dae8b9080cc2d87639b2e4f36cd6c0f225603f55204bb15003deaaa4b76380ac979ab0017e3cd1a89821716dfff38da7c2ac53550a890ecfe8ae655eafa59644a1fbcae4ab9e197ba69acef60186c64e2fc2c62bf8c8ba6a8d2f3f8791b203f8d3b6c19e96b1c41c6addc43a5bb52bbc00e05824cf3e167ec6b4f2004ef0080fd0d022eb5f417c74d9f4445c8c89132dcb808d71fcaa5bba81df7919d0445b89219db39811cc8e24cfc991cf2ac5dc94102a0c08fc0c908be1f500f5e1346de82192679879428043d04489f9f9a87dcbb9295a3cf43d4d88c91c995c634abecd32ca08912b1215a4048106a4a7fdc124c79f8d1b55f2550884dec021e657b28f601a44fbd65b9caf29072cac5a1464ef245cdd3617cc8b2f00bf3de6aba31c2a69337572e4513c778f356ab1ed2cd6419713e23b8e006c33ce4d3ecc9089c77ecbbe0286b63479ae3fd73f5e0483345d4c8db9db18f28d923dec649d84e2c81302539302c58250ec2deb21434e4a15244f53ae4b1c49fb8c7190ce9f56baff2ac181d9733a51f4cafd035a0e9b5cf2c0743cf2c93db712e04162d15b5bc3834e4695c643ae17d66604c9936084e63b3701f51a7d9647075e4e583a04dad2b57dd92427105ce25af82c400a22728c15325da7c37a5df8cdd3a12600dcc6f2eacd17e67540d895ea3767c20b809a4811ab028defd334ceb04a2031044cd9838e1917ffb6ac151fe8652910017dffd00a86bdd101235441f561bf54b9a22aacaed1a28214e0cf41002c91ce01bb820bdc26bb515309bdc15244cc0dfab8b987227400ace205dc58d539669739bac3354c1f68899a45266bf0d84259f69337eea1ab67d38628a28e02444f8fa2556f88c7315ab84d1807910690435bc2175720a9c17dc8b269ceb3bfd51e8edf576a4de86484691449b792cdc40e340f17cada82e0808919de486f20fa744133c60678096db422911ba11324e5210ece9d5f569c1ce426469b5720a789e671ed7d51e55f98a151d5a5a05ad0d29c8a395dbe911c7e8894c1a87ce6a193722e3c0800696e7158201b697737a990f0da43f88066e3585a431b011e9eb909c41279de9af3a3c469518a4e0f8e0b16ef205c3a0a64541914965e892d73c52408bea08dff3dba0213502b56ad282ddc914cd880fa3449fc1284867f6939d4da5a5fc04ac474b06760ee02162293e2e7ea8875d591057d3616e35bf1ccc177f20e8428c65b465dc5007e573a2ef37489055c1f4b6f16662c7c2f303a39255811e4738d618757a8c87f60fa9c25bbf19f443ec6156933083efe49a227bfa611be0be03c26ae603022cd6b50a3b62a796266aa3f5d878614d82137f5c67c711665c8c46713008932e0796b241b424f6a4f12b44805531eb2c23ef356e36e6a91d88d2c53d30869c7b2d846502a2c1bcd5c9140e4e0cabb895715ec8fc023635a83c0f593ff2d9bd38df1846facfa1d2948711d6503f5dfa855bf9d3e5c01f89a668569706e4c3442b73cb47ca9f37918c1971fa74fa2b107f87384d2c3fc06bb3e534dceddd39dac19ba066e7486b18354ce488a8aaac66376a80244430d59e5a183536e1e6d4f66c012bf3a3226b4cd93b5cc2f72d7d37abe96e1cf195deb3ba6875332c5bf934160c513daad8b06a0d55b0b161b9f73241ec7df2b195aa38ddd344f5ae906ce5f0de87176f9272b44284dd25dda05f5ed8c5bfcfb9a1698588ccb01bef7608c771521f4a92d1b4eede43039328eeee076940a4fcfe6451ad28349f381c5d0d40ac3bd403da904b9faef4b1c19ac2a82e23661011ae14fcd19be2c962f5f60f45c58f3f0784e2da2c6f0347a2e0ffdc896f6f1636235a00033e16d47d47203be32fdfd1e26157856a9a757f9710a396e37e085a5211a6b977ce568bef36b802648e206929514b99f8ed01f42c88b394ac1aadab4a697be0965ba4d75c7a9a7b42fc1e79bc8562462a8334f609b15edc5ba051b41fd806bdcb134f8b25392fe58292c6b0aec25c915001537a0226fb5feeadeed653cf732a765ff9ce4c292c2d523bd5877350c97c9baf4c39a4fe4babfc348ca52fad0d56485250b18567f2e6bdae83ca93f5a0628b0da31b57c72c4f77574db0435dd2a82e8127031de742623f19b93bd41c1b4720f16abcef4ef8e0e8696cab13ec348b121641deac0218bcaa322c9f417fc0aa9f03e9aa2ec0252972664041ab965106a7aa26410a9313ce135c7289341c85b45cfbf728ddc616e8b5b937aaf7a280336b58e0aff87b13e311240962c7030fb7c67a86332084093805cefc06c1263fabb4bbd1ec021125e36796ad8f89c069ad1a7dd6acff259f69970174c8614ebbfcfe5f8260bed5aedc2c6825df874b7d06e19ec001a349b0cd6d20300a42f875772ba7b87a935bcd2d6c735d779e7dca39961f3097b68b9cd980a3e9529b4b135099f16682384c21b3a0ef8e8fbef2bcb6c2d7f5ecb449169b816fd75436d0132f59b46bdbca38f5449b1b33053c40dc6b31e94abda5dd161dfb25209a1067b294dda70b65e8d9628b9214db98a6e8d1be3218541ee2dee69c3ec6dafb4ceea6d705895130d2f1faf40f0d1f8bf3abd63cd7b96e04156d06b9aeb956309e8d333a547ed2e7ef84e31eb0cc23054993a97745062707f1756b807acfa572894135e30ece92e904f3650e82ba8573e09612d51a3106483f392b2f14c3c702a5cf1a20b7a424a9f5ba4731f07544e4c40a33653d81a52b4f0ad7195ee7806c403d510b4dc77e86b43060145a17161e39d98821dff3cb3e4a408fec945c51663c760a3d8e6a03691b94097c77b0ed6f4532964d32cbb6703bf0061952a179669a31c814c3fef7b9b9335c4d250ac0d1bad3110c7fcf384629b449fdd17ceaec5d8e3095bfcd4bd4f69a160cca100086ab8b03d3e6bb9099393aeac6671005cdde60c719b0f3da5479857e8e524bae7ae3662404d1ccf281b133fe6a4920d824b08cf7ad51d9cac102a69aeb123f5197797604b1f0d75f12e3f8ae74d33d1637f0491cfe1154082d7fb687a580f7c8cb646e9844d809b43418050a8b80f1885736959d7fba07abca4131918ea64b62db1a2e2c7d836a60f5db011185cea7e56443cc048a4f338b52d9775a858b28a0d3ba3d0c8b562df278f854ecba5bec72e0a5747563c494bc5167cd92cb03e08467f1e9d02e6328858cd926374f6c9f2750a43c1450611e287af555514077729faf195b12630c161e5e70256634353c876b99550e15578af1dccc195adfe04ce60cefe7c819787253b013032fdb356acdf8956bd579913e4f80eab38e7bf0f5882fb2d952d7aa2444e7223ca22733e983aa2e39d2b1960259cd8267e478a54eb36152efce98c941294c13776869907c91ed1d4c4f4e29ce2e4e8467f5d01f4a764e8b077f6e932dd6c3d4b75e6d072c159ce437296a1510108373b75b28abbeb55275652926fcb243b7146050eb8342079572b642b9c39749d58f9a403f13ca13d8b68ff46f443db0e3f9487fdaed09a4fe791dcba76cfe85ee02f438a678331e5faf03c0fe3f35bf3945baa8a56310dbca4770da756df948c9ea5a605eb3167af4b9ad1f4f0c2b8762384a39887746dee6f044c9913242774b16a9d97e430150ae2223fc37a0ca401c140bfb9e3e839447b0b62b254f24c8359e339a9be141dd0ce356edf318f581cb0a65e80d65ac6f0646af0946ed348af8c050f4e30dbd10ae2248d65807887d7b887e66f05b9109489c1913b29ba4f2c6f6d50f655c9c0201721754602817463561961f79048a215dc43fa3e15a31819c0f77df1a690e10b3a41a6d0a28617719bdf3151473070b86bf74c02913576f1771734d5d5df92cd87a97442c1038d8d49b6aa75862eab362996bb8930060bee5770f217820b15326eff2e2ca4a7e424c5510f5699caa9609dbe9d58713a6f6019fc95854b56f749a2b96a1dc6ded1a5f012c0a928c26d73abf552fc6999408a98fbd5eea81c7b8a8168f64c4bf6f7a114e24eeef57e4e1f8adc319d1f8ba0fcb006d95cf23d415f4944863939dd40cefc27c87d5947c0ef6f3b10d0297a6ef2230291b0d66c7f2809522f8d00a7e996680a820b2a8c48ca2cd71145306c4efa6d266cd7c46fbcdb37482317fd0488b420e61747f228f18f04488ba5eb212a131d2b547710bc73179c542fad1e5373c5a75469ca65144520f44839e6104f56620cb45f1f40d9c5e2980c3e350c9178820e9704940ea68705a144b372ec92d57fad50773ff6a1c389802e518a6561a2617578dd527cf33a1536c4bf37071155d69469945ac5efacd68a7ad23c622b16a1d6c884488109d6a39b5d561cf31b035dca416c1a0491396f175c7cd81a1fb39d75c8e246722010f0c6c051ccd690c80bf20111946f27c559bcab2bbadc61069c1d7a92d76b04d3666c76644fed510a61fb4c58d8ac1b00dbb61417c3cd6badbd2d28f235aec2cfbf6bca3136ca48b58a98032bc33dd094d3f5331d47d6b9fcfd5225a46167174d9a3ad9bc51411c61f86031c7a0ef0444650d52b3bc0ab4d837353c7de7e779897ff6135c81844cfa8c3966cfa0d45ab2ee5c6f4c68ad1e71235e4f0f9e8ed36d86e8c11b52658c00f0b600c76167ace2aa7375b6c87b60b39c15fbfc8032267aacba6474498129e7a99d8b6949b2affe865365d6ecb21799da4f0fd345366756d97d171726c00e1d92bcece6a21df42919cb214b556f233ffbbe3305d809e271b70ac2767cf12d3f1e7017a6a9a02c5d3cc9f4ebd674850ffca5323ba7ef7ecc71388b53443dd64bc2de2f8e707e7702b1009fa9c302ea77b82ebd355608cbe243393ed0e0aa892c9d476b02d639a044915ba815aa9a2d39f2d6482c0105633b21418b280ed08c01d9aa97806fe4c2a4fb94da511d8b5df5bb1d9a4b87775c8094096ac092684a650491d3ed561d6ac9c6472bd399e5d736c480930f980af60921af124ed6f239eb4d0871d459e880a06be5c140b3032bbb8f46dc07b7f201ba445d82158b64befd2b980634d60d407624b3c2fbdaa2a8cba79adf7d30a58707be82015ddbd66233e76e6fd4cc9b5521fc2d07536e3efd8783013c2c330035049ca3c0de3c38ed3e3102d4bd2e65fb7a155ec55c2a92e4a6dbdfc524047abe773ea49df39913e6943858c21ba80690c361245840c471558e679cff1450827935864cfd3c485ea98415327cf291549b3af2d8b5f266c2a0f89860ac187f3bb45b714175e26c9ec37dc9a1428f4cac5b0b2f226b58abd9ca21c86d582990a8153558cb3dffc758b8ae3a1df2c23e25dad40c94fc810e550c240c95ded4014c1896a4fa0bc956997f956f31b49b5fa907be4c264b8806dbf9dafb87a11dede5d4317695d62092d78da866e21ddd08bc068bf2d14952cc78d2134f15aaf4f1bffef042bcef0989c6ec24dfb93629b0eda86afe46e2e6c56bb9848e9508c035c938446779dfe1c32bba960674b63f3b9b90c3d0e508c1f8ad80b98bda6a588da7e415699906231d57e09d9130ae4d3167f3d07cf4214015614ea91f3255f777e3e0389c216a83fc32758f42d2b0bb3350400db869a0d28e07c92a4d313f77cf87cb262730fadd282f1540790b835558247da7b37f626be64117b83f672dd56e271ac621aae1d766631690b494e6a1d4d97581e0066a7d12eae4bb5ba96bfdf3ae9c9340a9fb302c629d0685932e11fb950e46bab3a905e9272d031b375309a990e5f5a2b1699a67c69a62f5baa067e69f3055c591f905fd80810b3a23c659f46c129a5fc598ac49a9c05391367a0dafb79186fe80b105f5c6201a59eb684930353054a2c70dbdfe28e57a6ebc6732c9ec0b4c7b6dd9c699ec82a927fa35fd5214f818d06f5b11bf1cfcf7a2c9dab46d50ec0fc06cda5563e5cc56b4d102499c7683af41b126997301315af14b3d7d1a668e64988d81c4c6dd9404e9d3a381f894cd1d821d9c7f02e93291ac8d2271fb2473aea26fa876c8638994fffeb55a3e879f931d863559849756db9a72d65441edff712dae18341ec04471e4642e4b5ebe80f37ea4da88cc64d3584aa91c2dc58e106b0ee1a28268d9f82dc217f688be9a708da9a53cbbbc2907287e8f2bd43872ea377c8c63890ca367ae73709558947ee96750d8f2af2837936908e4d30d7ae415bbd72833af6a82a81fdbfb7ec086c027eb49a5e7e20c17276331cceacef6b69da4c01e2bba6920ba5161b9cd88a17ea172979e6853c7dc20c455aaed55a049fabe3873ea37dc44dca1bd2be37d9f518871ce5265a4967e8ad5111af466de5079864e7dde0c3f4b720feda7ad568f51d1b32b1a9d25258ce2e0bfbd669adf0ad67a67039e0c4240329863e36309862e946442409074e5d71aa6d69a712ec449978388bf2abe0bcff5af0862fb02c7f8215e8d30f098c2abddeeacf12d4121a1e8e0e691e10a65875432d1b5c93741266dee16b55c897db0c9bf77e989205a833956d14b9b526de43aaecb325744273afa181d4ea2681b678a15638e0467b8698ed3d2fa4ac3c1bd6928996832a8223520c1d5406a8a0494a1949b1d89d5b510765fe49a08de0c10a78271186d38855995f1fa3a4d760d4ed217d21d437c430ada18319c91760b8905a30e4aa79ae2b9075622cacc008cc076b02d424044e5a9eec52e4c1d81a3e3b6b5632658536ba0af3819402964205aacc55a052d55d16e3c59c5a766814ad43198f92ca1f5c1f9cea69800b9ca4db0fdad582942843ebc635b34320f5206a1190d9a1c3697286923267ffae756f4ad0775dfefc11296fee1c73ff31eae556959d2215fa21bd8b55691803f9f7e3f93c14defafa621e81d2e721db087f78fed7a98e437ec3792be504eccc90a5acf10a18ad699dbfb58183c1b4f3d064e73eea96ebf29de6eeb6d05cb95e4a74155d5e87aed000d5c61c56fb0f45a45cc89cbab1255b28dd6dc5b47ef755e8484b3b449874ef8bb3d7a16950832fc40e053fed84832b99e946891c41d950b70f9cec80f1ed2ff477a56061fb9b1a7950919f3568c733f3d301a56f14eca1f49f22b6fbf52c2ca6b40ef7fe7ea2265dd57e8a1a5875bfdea6e24296685cc08c6ed6f15a4b208ed97656feee7941e2b3a850877f48f5b6ea99fd212c88426f28d2eaf54323ca001e4c01fbd2b0f43db3ca057026125c835cda5ace6d69e86a49867ad4c5787b6628e9021740511ffe3411e47e3ca2c1f87231f5cd992f9c3377ec9f598a01f36d2e3e8d3f67a9f37b39c6633e86a06b38b13b0eeebdbf121d5ace7f336028138a9129c0882309a2fadf755359bc752e9a6a35e45233599389d45f67f05366a764e724b103c38215b599fcdc05b171d3c33b6dc80d4f06d8b2c2a0b90de6c5b50133d23f79c226a85271a9f9a3f187379a30ea93f137168817cd3f72d01f7410498e8c57264ef80cf4f41fd68ea1e71ff611a85a812449aed08fcd545bd6398b8c144db36899cfef31ddcf344072493d366ff4db104d4a8221c4ba3d0f2df074fa1281ab565e34d7c4202c0445dbe513c97f43adb75e656b18b57d6782c9bf848114403954d67e38aa6d7d3656bf2d41eec17ce0ce87102ea1decd159469aef328e6e6b3b5522c08ff62c94fd57b016a65892d3c443a18ccf31190ce94baf0ad615cfa1e26ee0910d608116c1be83c9dfef6cd881ce3c558ae7061d00c133dae80f20f415a0551b994cdc8baea5c4f34f17cc65f135453cc47dd637272a3c84022ecce97dce84d536a13cc23d10cf4e800ba7158fadcd2945f0d878b5c05f0d35f2c979b60683b473009ec3734e99246172152453262424afc7e331d7c09303e19b050bfff3f9cd4ba61cc93d6f0a2e207fd1627b2ee7c6534e4d66875ff20439acf7f91665d8fd5bfd43c5dbe4901710f00147000416c12a8b9de31d7e51674acb9c5e3bd1b406407ef56617f0a316c9577753b0f7ff20b005705a597cdf8e97078ef2a11ffed8d28d8b7e502aff303b79bbe74db063b453e60b977dbeb50e343b6c6047d43dd9d8fbb6317f649c33351bfb35679b290691c03370ebc6da7c17bcc360a1ab184f3f878ce2343d0e36a48aa93091f9d0abe9be82eb7cfd3aee54b51b2388d43e4da9dc4d318f9bcf9b9ae9b0b7637751a6f130f3f9885055b3bdfd8780a63daac9dfaec77dad9f129dac4f7901a729989c0f290d8cec641800905dc5173dd6b1835f79f9e3162c444ea550a5fb8456dc7fc71d0c4467cbcb6dbddd10cae74eadc942acfddce8a1c48fb3a23c809270702b110d640bb1726140908ee9d40d543ff2473990120d6f51371e28c48f33ce532c9bbada6d9bf951a1c8302d67fadc74e26271b9fcfa94cc97311f3c964b2f1b18e4732bce8f527301ab20be6ab9136d25cacfb3e6aee618749c94880fb78fdb1afb137d5f5c56829e61958dbdf75bc6ad7638908d422d53f895b4d71280a6b1dbe2620b9bc83d2a3d630cecd4dab53c826cf4d4302b1c81a868d2bf5ca04b45ea4956262b720e54c695078871f2236fd387e2f8279d372b6c9088ef99c6f24d8289f6560b7c4cd0c14d29f368eb47acdf40d2d9c9407749af508acddab61c8bf6b218c8359ab6afaeb8469fb6f8a8c0280e60f11d0c9fb8758a8dbf7a099f15828627982de98b4c2aa528e5f9b010ab2755147b8fa5d9a47b69185aa81b8b4e124de4d80c42e468b35ec4cd5de2eee8574df0319b2258398908cf54db106cd966eafba51e307764bc7e0cb3f3b5f8c9d0d492dff69d23e01b05c5ed52bd68bf8621ce5249dbb97e61c1fcf5e844411b254a73d77235b272194c5c39b742c115ab5b4b762f4e733eed2235b092b9dcc7eb48c3429d01f77fc61a46aea66c4b6283f381c1ce04bb91b09d08c6592889ba08141ff4323c2dd58a890b19ac052d024f477a2b6e1636f5e9c3ac729de03d806d3f4feb0220ba1dce6a4b13548101eb29d48b2071e231cf6fdcb83c449c253d9c1e4f09bc3be528706416afd9b14645049be50abc2f71c8f8f3b9e6a04e1326260b58fbcc383561a734a301493942864fa10002ca4b98f544e3bc5becf579fdabbf01217caf4c00200156b9e04287172fda7852bf9b5ac256c57ad9fc0adb063922fcbfcb4dad74c8336e7b5756f8b06c8317da199f5362c050b9bc4028fbf140e033fc0826b7231d44b19d4218864b3138a577e6030a4407700ca66cbd1b38df8f9f67563ec2b41113b6a2ed1d12d801c111d5c5f5bd529c01e42387d75ad1d7d65e00be3010b42bfb33bbc85cd1bd5722459b536a55afb95458a8da88fa382631da49063279648cbe0b5aaa34e7e708b8d03bac75790fb4971ce277cc2036d4f4d6ddb00eee3dcdba18ad03df1e30d6fa33681c19b29c38216766f0b4d298c33dea46b968e952793490465f3242cc08dd8cdb914018c20aa777a09274e3e7e423e11339838d1067e52b584d8d919f6a4044c93e30d20515e44ad11066b823a6b1e81940205c384d6abe8e52ce15cae47e77438563a3ef64d8c9ae81edaa63a1c484436f5589af4c71a703b494dcbcbc8e41e5488ba26e6fe80025a57cd31bff9920be09e4efa27f881eec112a45e0ee0ca6db8b682a5bdc6296ff2bab4b4dab4c10cc9216a263bcf7977bce4507331d8687503b44739a1f3984c3b519769b16d9c0a69216aa769ee378fca6a21180ce3ef4f706edbeac33046eda83464c447aeb88ca0fbbee5dc2333895014aefc8f5522b5098f22b2661c6e024b28a23453a84db60d773f417b42ba1aaa599964723da91968696a15b0b5ef888039becc82283a53183d230fc4252461ff3cc4149781c0837a68048fea3f7df53c99b5871e45a53d206923879cb78e96d7e12c16140c4c53a629ce5b529d89c98e7bc4b6acaa274bc87bee8cf47570ed06a31a9ef0ded30dc5d703e8ae4e06caad283cb809705b39acf9bf58580c501e33d8c42abd4ac594cdf95c0382c19e8bbd1a41b53de9c22d8bd75c8fbaed708b7b4edaeaaa287c628deb11a97a027967f8423bd098e31019c45367ed1932355d76641e0dd7e171f1464674082155cd94b12b1306074f789fd4906fd37d018a6e02af523a22028b24d94d6ae5e72143be9725000cb0bc56dd6c281113a6f53c3d371f0999103fc20af43936d9b7467a7c13099ceeb8a9d96e0af1f8960b8caa6c87c50434dd769bb9a9fea568e9a2c5ed7026cb4a03bfb20a26cb1b48067d1103a8f6cc632f2b2dfdc5c5b1616df525decae4623a6534f489a5de3671046c2076513b557a7500e1a9d730ad42782c2a8e3054225c36169ecc670d9124f42fbe13ea7d6d7ed8f445da149e8db7e3f8f6af7f07a8def23bfd188d4230887fc77e4779b3a22758fd8ed08baeec98ab64b875878de877c8dfa281fc7ba453d73c2a352556b11ab4978a0b80f692a20ba00772436fa5f40ee6ea42f99860841bfca3f400ecf217e0ef989ea74b909723f303871d74315a4c264b4e3cdb0d2bb83a0a4679094834fd208c6bf990118ac1fe433514cd206f5e317b643a2a65f123e59cbdd1326f7223cfa200edc746f17e8759ed9bad6aab1517d4d19bb39740a8f215c19bcd3c6a9ed9602faf4fd3cd61578b00ef175d70b21217712b3e6849533a6cd79ff9e29b31c6d8e4d778671348cfa9fdf97b1477549d7cce0dfdf3f5fcc172dc4104dee0a609ebc87a97fe66150f3dc6c5bbc341d09c598b260b1c200914f0cb8c4aa1de85b1e2b85f269cb71ac85504f2268128f0f900b8ca49bb9782d35eadb01febfedf103a1e215c46f2d135564435e9c0f6b7f31affc999a12b87cf25095ffd926e0ec2efd301a9a29417243f728b5723d1b661c5eaf170eb5f06d5f2254f528511e562b49e00cb4e09a3d159619147fe746ff8d222e6cf64210bd1a1742c574f831fb0768288337a3ff5776f1ef2d78cefb809239dbb68443d8046fb6c62e6c0827d7b982de5d222c1328fbf97be1cc62c6a1c8ba6e5997741f1f2c63abc82f8ed81105726f11e97d16c7cbfa21f9234566c4d71e32727075a08efa957443bce40e183090d157a1d7b177fc5a61ab6407a537b6cc6ecf4c6e1072c5472347b64186690d15b2497614a480e2bee4ddcc3ff857335e4905c03e49c2c74289ad3ad8a7283dab3911356d3c70102a7b6e7e7af01d27386f63f4e8eb0af3a67c97dd91042c5bc8f888c4a1819be61a14fb8c64670a004f242bc2fbc3291be6c892b21878b5b1ddb71a4ecc7278769ca21affc8b53d31134a35b0963a7d3d95baf845859fffd6c42848d2efdfaabdeae68abadea02435851a8a61e17c90a17d5db4fde6d117b9780ddd5e6ef5158aaa7321742ca8b1a69ff9591ecde3d1f7814636a30d5833cb8867fd06d9eaf668d97776c4764c7c5c93df2dca97ee2ff7997fdeccb57e420dcb817e546052144eae630de5b074a7496a74e2af731c8f02e7b3c9b090d80245bf3bb1efd1606b6ab965ab7b2e97b0e9f9208b9012a0c8d8375aa1bddd24cc75e90eaed6b0f8a23cbe9e440d924ffb2b07ed6adf276ac225e96459cb136dc07db906573a86d7a0468618b3eda325d84ba2e29cd3746eee3562c9d7d115597b64ceedf99130e4675ad359d05afdc67d6eaa32e17720c8bbe3dba3c9ac28ee74fdd65d279f5d1c503ae596b4b78debeecb5254b1cd808e36a4eb62519175f34db97d0f53a037d51f0fe8455f5537a925026224ae716abfdff7487d1c12dcc0ae4b58ca02cc0f9ed29106c8e8ca01a63223b806ed057b4e2522a0aa197d1d5fab048a2d06d44dc59eb0338a0d4643cf81793896d44bf868b50e6023c31dc939807470b92beac3c57361870c25f53eb8628b8c2d9818d264518c35941515c845b4e40a40ee7fe3a63992991ab07cf2d1f800ec94b74a98248d01e645d0a6c3670b7803af64721b8dc3fa367e1ad3bdf80efb3d55ebc150c8a0adf46598cade979633128ab8684f6a4f1277446b4f796a2ffc45b7e725737adee43f95a93843dd0f716afd3a8b5a80730de5ae28583b0a230479967999f98501c1acdb1847ea53ea53f50fe8f55bb022d07c247a375f94a794f6cd748eccaa0d80b13651e85a0e809910d689b347ed1c868a8f4d6d42dce9f96e5edd8bb9e5de8c55207ce3a231e72e8c683ee30e2afd3ffa5d7fa54cabdf1d8c9836b5506974c9e0f77128de501bfa6fc2c154bae431ad8765e67fb1b454d8bf70cc9143a377d320db0c8195505f07dae7c51005645ea701cf969b7e99b4d169486ce1e3d4691c9ceb0f7cc65e7408fd91b61c94529f2be3d4b157800ea0f13dad2863705087171f622feb93da9f4a13846e6550810582543a4ce1b3dc8d86a7cb050c74162bc4b6b38f9a8cfdb27269510d5eb2e1377e43a8c1e3d992c975a5ebd5f01a87ebea0c73ee31d2800f5a46df0c33283da1793761cadadd8126fcb48f3da9084ce9ccb63a8df86d4acddfca22f591e7dbac055efca850c3eb233f90db0e222324fe6c14fe14aeeb1e4429ee622da10254f678dff94bc1b15a48b574fb25d3d12e02dd2483c237924d36f140571b33efc96ec7350d3ba0953455d23adda4e8f1aa680551e734c0d8c7188096083c9bf2f50b65ce3cda48790e8343b25e40ad6803ee5a9b94b62abee036c1d07100b3b856e1c0aeaaa523e1ccd40c6155022506a6737857c997816da233f3adbf22ac91297a4aef29c7710a023cce6df000e1bc08cf6d76f070359710856f71cad0a1ea12ceb7513522172335075624853304b6a053a5a6b02cda1191b767b370728117b7161d329d4bf6b1e8b2b2585d6794ca53ba48ab5c4ae783299fe410445918f3fa36f4d8ca56e35bfeb0e562d369eb26d535772673beebe9b8790d15d98283a1816acf573cf8becd8f192cc424103c55f2e0d74b552dff71acaf89f5b5491b8f1ef7349174bb68ece410718298258fdbc1722723c888a63d402026c6aa027a3ea03ebf6a1420fbec0c6f67ccdf94c42c71b0900d04fb5cb7775884de936fec3ac59805dbb68053395183ff8b02f01a3c182a086983a959dc8c3b6f9d1dcb63faf3a1d73b8b3362a73ff10238cbcf8022515b77dcb88c1cddc2849e9899226b36352b4c3f164ccafd5c2f0e0b9b9d471611a4106a7697b540cf56cc798ebec39e05f76e9d2636e64517494afaacf22627d1b18b2e8c4ccaeb8ede9e6bfca4963d4617ef8448d0cf10bd7d87704a92a76daa44ea7e1478342846651130450468e8623f5f9295a297d17a80e35b7db97c50a98255777890be2deea3211e4cb786801205b5bce905c8d46d0695e9bc83689902ece18f67e97e16edbda36cc4a05807bece39d654f02c44dda4ba835c6c105c2aaf29d5b63a7158da9e1c299e0df824a3069a4e878358375f60053999f7de5a022a127e1bc82340c0bdc669f0eb31b1b053851d9b9352ab028789f063504608225843c01c1bb1208e2a23b4237e48892beb951e6187bc57ce33fca74aafd5612fcbcb1d6c2d32110957177e56dfbbf005cf6c6c7700c922a9b45b923a6c9f16c520f301834b6f7d68fa0091c747b9d527f79cd117ef91cff2cebc76aae37f2549f60a4b0aa53264f1b066e20ab412a1fbff57d17e3651960237542d6a2861bfda31173d17336930a676544f363821aa20e5c6821da50c4e59985598c26ee8aa99d490ec2a5a5e15baca7f3110f8f9ad580cb3d78c5d7e8a2eaa26bb7a9983bb219aa4f60b56bad8ae0dde1cf0da6ebd1c1b6899d556d3589c8e0ed7b19ee94be4634f9d796a985ee0d345a0dd829bef543a6455732d8122e5a5cba5c36391d0dc5d396328908870bd7391679aa4f26e6bb00fc997bee6b34da8af8ab18966d679ab446380b8058d24ff38086525ed2240ce9bb3433b96c7e4da05e8f65a893f145716d45b16000f5d2bfe6866fa6b1bd7710bc889ad2c1738bd392e98f9a52fa9e9fd417d3391527c033b7d62ab7ef7113168e0664241a253e3058ef629370070392959e995f9c957dc46ba23d94063e6289c53957ae45d0a1c5391949b7f937784d5318cecc19ab6aa3de1db67a2ca17b6d240e3142d99a48f0424d3a053af96da66c1f13d1737a71966abce83eae1b80f3892118a8daf1fdd7239255a4ddcfd69be01a09558f74adbf160e535d3f0fce3150673bccb0bd28d0621f36e007408ba1216a4df9677154d15899e6cf22fefd2c9aa7c656145a9776399996c49bdcb4eccca965e1a96ec2d71079f5b75addfa4600a545bd0ce8c2e412937d57dcd5539c8b524f42c0164ac7f0f6ca271478b7a2e12d8520fc33e7173ab05fb19c8d4cfe9f4a33dfb0a1dfa753d567e3b4e11c2c5472e7b557a26923fbd6d6e810ee922f8ed6a2610e596b2f10425d27425fe1aa1535653cd1bc3610ce610c71cca6ba745419e40e93bc64f7c18bf440e76f8b43c3658bcbd640f1c51a1c20f73d6c4b7ef75b3e10b00dd62f3d798f5a060242761cc7765ba8ed71b06879bd4aac40a56e0225d19599a4bd658e3eae5e907f941812fecfbd68ff7f9c747ba61145cfed9805ce7d29ae2cd1f0c974c53d9d145ec707833be6c93fd6787dd4853b4c29169a35f2baa590cf7f34b1572f383e200335902e508b780952c9f442399ef24f5f70593ff2e60134a6a303401a4fc8fb138ff019b5f864fcab1be8c494891452e9f91ef20fea7e18b7311ce1a27a50c75adcdd3484639869753ea2726151830803d680a4872d2db4e78affbbbfced7df4a4fd11d20fa78461918d36cb9a55fa662e4044395e970de88e8754603d342af18de037d3cc966078a5f87622394557098c22d457cd1007ce75995457cb912b7dd6d32a394871722e9322a1b1a30b6dd26502b66f1908f215d74f2ae2a3eaf59a2ae8b5e3b9cf1ac30c16858fa4358fa62e5769659ba473672d98fe0aab95e1f19656e29c28be8dfa87cc3cb206789317785ef1c260683a0f8baad1232bb1a11b84a51bfca698860ca527b179e510778dbd2a7a3edd1cb4ee809f69773b9a89be57e1313ef2561bf0915071ddeabee19f5d069901e6edb2793589f0465e293781553f73af233a035a122177845e85dd62f7c9e49135f39e2bb572f5c3b7de695741c895cbac1b4cf85a9d06170b70bbc3ae405936d05f8186628704aea444f8e2648fbed1690de86c01ef79d98d48c9edce26564572456c40d008b16baf6f24f0f2683982f2d48179e916e7df793135b589b0f10379c0b2f201adc7a911e081e4e8eb7f9d5257b51d590e73c31e64ad4ec650f6a1b38f4db11cec1492d503d5abfa238019bcac762797d6ad687deb222fad86023e23b015d12c3668dc54c02e7820b9c20288e5e50a71d6745e653bd0389eec1941671bbbdb6a041a96d156735e9600e9e29abd0be2f786a84293f2369058216d7a5a0b30bbab72b1cc54e0d4be8383d038ccf790b9a919423909924a58d489f998ec76cc8bce035d7859e9fe0db00cd4c48d1fb08406abc85602000f57764f78cdece464b60f131dc96f31c1b2d2472c07a5168e82c4210c65a619b0868e5f6d5eba6333f355cb9ad9c4835d929fd3a21ed4323fb246bdc371ece4525052702147effcffb0b1fe2d3345a89d8eb858625f1ea0b953a56986ab06698906cac55ff0f92bcb2b4363dc20062ac66b6c51af9e0de08054270ab65c43fb80a0060ffad938d3350076b677fd7008a9b056376208bdb48b588e5f0f0474534ac33018fedde3d48f3f294cbc25c6edb99c03b9b40a84911768222b63d6541ea8761c61da302eade2728abd4e64d8441598ff0f4424ab2024f1582ca0a26698e31532145581cb96da81253e23ce4935965e278c73dcd68cbb8cb62afe17702fd0c05993025e633b7a1486c0db56b4e472360fdf728d35c94781074e1a809a45695e9fd66efd3d91d18ed5885fe1ea8ea5fabd44220598ca1d0db40d93ecc3030f3b8be79db4485d0563dd8c0589571da7aa13fb48b85d1576c59e28478d10b3842055b7357ae3ea395cfa021774592b534719bd7b30a165f2b107cc4bc6110d6feeba8d11d420456e3f32bacc940b36ae7fa290e787d262bd486a6d140c0c220d2520f08831224052feb37fb1548adf02ce51f8bc7bfb3044ecb547b8b071db0b94b75a84b2b0111a42aa928f1d1c371a70a5f66e65bc205a95bfee9116cea11711725cf871f4f5546a42a3d5271f86f63afb8d716778d2a25bdf9392d4ed10142aaf8c0ab2d27c3ca99dc48246399534d5e6dd7159468902e21a4082eae6e7c37c18d8cc3088320a49d18e66815c0488102673870b002233c65f5f05bbbf1556117072bd39e056e7c17c842f18da0dabb333c81cc29be3e32a6d63eb94f2e6f69e9ca93c8eb340684f10a1deec0b166535690246e36da49e97e1374dcac83ceb10f28adf4b73efd609af1d7fc088b1f70a7e4d4facb97e37f511fa7e05b0f3980a3ce731913c9b3c25b0fd34a14cff3ca6f98352b39b6acff160cc01d653d530e3786c3acaec0c563b0ef9e7131d718fef80652a50fce9ae8f4d7352b3c7bb7a7a5c6a035a00a9f5904d0f915a4ab1cb93d435ab6cc9535150919bccdf40dcdc63c976c2aae4afc503af510fa366b3c08a9d2bbd15d843afbb0ba2f533c1feee066af8ab31c0077bb63534e4625fd80e1cc9f260b4dca0b93c30f08eb31c3af997c13d1d194b4b2803431c58d77c86039c8f8bc903fa56e6d02cbdcf985575d42c1c462c209588bb05a17c885ad7f5f7d98d599677281a0b4db977081df64d717407993f4722be00649108b759d54129642e77356373c5ded1525be9c9d5cf471a6fca4590e3dee09446e432947782da11286ef961664ec573ecd88e4cd9d11e1fd9d27a5769a1094b92b122ddc778ba6c02ee7db9f7e17d83bda9413c7c753e107c69b5af2b8737a80bb89c517e248805bd2c833d54cf7e69c2666418f4710f43e7e5a852e5760e42bbc06307f0fe4260a2e34a902903a0657a23f57973415969492695b4760b59e303c82383677b7023ccdea9c477c60a9ea11348ba4c091e9cd06db482a7ad4a317461816bcd0150320654b4702a99494fbb8e3ef249499f09b80272b9357c773e46d9b7bd9d2d3d85bf7c708d9f96eaa5a4cc6894044e5862980634ff71526bad7fabda65781b6e6e7c558e42c79c566e0cd00d65b6d40d0170bfb8acdb3bf4a2d87825a6d551b92e6a027ef22d494715c7f60e9051dc195fc97de44236154b99b6b700fd296a0fff6117cca11e2c9ec1085fc0e28c10e6cbb1ec36c7ef91f670cf1f53e1664451fc467cfb1121666d51f0e30e1f065a43cc59383b73be9a29074146fc205a3eaf6b6da9cf1dcf07a2c815f13f2847ed6d82fcd223c80952e8eabf02e8b2d4aeda3b351ad131e1ff1aa391e4fd8060dc3fa48903480926633dddcec83dd5bf328068bb28630fadc5771720cbb5d8c1159ebb62caeb1b745ab76c9d99664d792089cc3a8d273bf5525dba79be0be7e458458cacc2f39ebaa4bf2df9738f1d20864b969591ebdb85ffefe8b550bc1b88b9a7a3d2c3816ed80f24e7b9a535a570a4f2b771b3d14cbebd3a68b966018c5829361c3e94b6354316026f84f7192289334f1f889c6b275d4e8cf43928c61ae5936425c6ea81bda378dab8c2510cfa069885beb067b68a422ed58ca07be4b6f8ae848546bfd00f0a54b2c8902d024127c3012b9374ba310326eb34812306e4a02c67a0d092f89558dc802cda1a21dea5122b052a2a4a7448e4425ec2f27a15542de19183e8c8b5c126303672c735e6334134b38bdb6d5818013648672e2f8c326b844099978a9beebef64281764f26c6e46ccf307432ef8192313184d009a264abb9a286d047971ab88db6b22ea34f3561e40ffc1cb502e7d5eeabdc462c8d1ccfe9f38d8adaa0feb2013840bb10093de966476c3c689ee5bd0a137cdb6abb9af10bcc5b35f38d409bb0bec2ee094dd4575ed2e86f4e6021a59ed2691639e29caf8c6666b995503d71177098e6754abaa24c3ae3fdf4441e5bfef5cce3f48cdf88fe6074800b5f46e1a1a2b5783c4e16adcb8ea2622c99c763370eedf3d2601348d82424c53b26a8641f9802992ea80ca4f9d387565491633bed91e08a09198048cd5d13813027efde9fbfb3d46395f7f6a19e55bfe9434d348aeb0285b0e116acb215acff6381640b3c34860bbe4b3d52a752634ea4f8aa9aa1cdc4c1987a81f684d615f2008820550c8f457ab4f3cfbe6b38f75bf0576ef2c051d3206d6bf82b653e9955b3f6af92beb7a015f339ba27d44fbf8914931036a3ef9b31dcfca8eb3daa0b65fba693292cc863835576777750b07986bf646934c66274b688426f9842c370171da80fac5b33e8d4909d93fc2f19020ecc09d3318367c80d7b3b755e9e5972e8aba3faad00bab5105062062b9ec4df4e6ddf91e7950f4424e6649d07ad8b59c43132dd39bacf99c0721029c171e5ded2fae0ce385a9db631d09baf08ce0a9ca2f6b2c82a7ac0dc7431f193cbb7bafd29ad08e072b65d09a7e00b35ab7c7fe28f63171c1a2bdbc7d6da18b8fde297bd87596e35211d70809396d91f632367110638e8bab2a923faeed9bf0d5af35135337add650ed0207ffe8c026e00c76d6b129dba561b47cb255b10ad5686c79c08751b6e92d75aec3fc92b920cbf00ab4d1c248ac4f789ad855e4a802b5c7a0bef13c84c0db307b6d6c8b7b29d12eba1b35ee9ecce82c9eee9a8dbf00a58e0e86bfc0a63dd51ddfa8183422323faed8f60b5ccb3aabd76ba692a86798ecc56268b56bd1e0056f162ce3b7dbc3d0b3a1ebca7c72f4e45e433f99ddb96f552a2e3debcb0f7f5634a188a8613431d8089465873cf3dc494db13c0190e412edcd82cdff4dddb469027cfa073424ebd23df46ffb0eda88e5c9c4e4b796c43ee07c905dabe7589e2e034149c1ad8fc4099037792f9579122f40b3d6943578ef018f03b79e828d6be96841f6d9fbe19a9b62df9e824ba34cbe9c87180b7691975470ec658e7d3b0a102d5c35463f8465a5d8039a49a20e948caafe53b8622d6c8c8bb56ca903c5f3cb64526e2154bc1f417519b1643268cf583fcfeea631c0695341a9eed0bd16ee060076fd97b961b641b875adffc5766fbfb5aa90577a7b747d8110d725e67aeb6dbfea44cf7bdba763ff56a9b078911c0c16583980b15a32451cbebef74ab11b9534f86825249a83f78281e290f5f929d02aac2f7f89b9d05845a1ae3a5bcd1037a95f283ed18cda71b138c75d6e4968b7638becf436ec6ab87da286161f55895523fa1ed88a284fac8fc87751cedc38492035ff669df90da34fa7411ad3351b54f49af31642493f9d7b29dc8d5c4d2a1116702b5fa3282c18cdeb05fc105e19cd535ed03c04efd1190cc014c09baa686c69c36d8ea73d141580c69249cf007974e85b28a25bf6066216b2acb3ef2543d0e6d781da0d29438bf34e318e600b54042d0a589b8f4ee45b85979809ff50be41254051b1858eaad49d7eff994ddd2b2b08e6eb8fc5e395786474a654473e5ffc2a6ff399c046707d23a5c59a969ed197d8ec38891bcd80d3ddc36d1ca97834ee1d493426094c2c9e3d8ac5a93529d967169150140cdd99b19fa7ce6df125b3ac081d2676e2b3830497057f98d8acdba6469f51962a7844aca049929c84dccf99ed434147fc4bcd12d8f0b9f191c1c26e430872a8182246a8e319b927aa4e6365558cafd11faf83b0b92210b844d070338f7ff82c4c6a03cbe053ddcc2b6fd2a7ba0bb4b36f0a89881e4728a578a56fa812a1f5184382eb1af3243b02e5a7eaa70f32f45c27a13570d85586955a8660284f80e2b1d3bd9f2eccdd8def501de6aa565d3ebe6958b1d94e59377888975f80fb14b40ff3d9f839b09a547a4070814f161dd6aa5264e6eb88b5d52d13a02aa55378e8148fa43cd902b101a618400de22f0fa50e2ee832774279d5ff20b85cbea843c46f211ca82aa98e14963350fd569ceb411f8d0ec18a921c74baba6d2fb583461cd376b29608baaae023dcb9c3afba84ec34e1fd03fdf250c920b264d322e6640046aa833b4a7d5893ee1738e3e627702189b5e98dd898676dd0602715854f8683b0060ee3f5db183bcfb7025f1610f0e8497acffa53868927217c235b5719cd187d5084519b58bb558edbcb621d30b2cc1ec68b142e719d90e25729d1ce334d476b70b548f1c8d49197bdce36a5fa39ded1b49481105f0be36d68116e9dab2961d86bf7a8ffb474d17b107c29151a4188a3eb92502cfbe7e3aebfa4622042df4b27211b35893ba8beace3244de0a9ea876a059faa2d07d40403bac1bd5d5e301616a903f65eacaa9cefb71f6c1b2020020109ebbdbbeff71f59ecae8a33376f4a2b5090aec7bba2a4d8069d39af09891f28ccbf95d702c31d0d795c2166788724f240020442eead1a61b604e4ad2afe016b42d2f66e22b79452262903c905c305bf059fadd16cedbab4d6df46dbc86dc906b4e56003da681b8da3917c450575d6fa37d5e249e12702e2efa6d68ab1bbdf22723e81d8f4aaa0131de9cfd3910a192a881f66fecdbbafff437fe9858cfef4220d322d01092aa4f209f111427a953ffd0479b400a1081bb010a2dff4a9fce979f8783f44e54faff29dbe21a53ffde84dcf63f4a62f85bd8f47e94f5f0a7f392a7f1ae9cfc6a3f81d18b5293eb45dc88bcc1f46dfa1a30e73d64c50c4f3d4de7b3b2fc90ca05133cf49be3b13daefbd2a6ae335502f7584fe57263399c94c6632933e5e8529291ee839636428586bad1beb46d4c39c73ce964af5dfd1edad169dc15cad58364220fa4c755cb5e33dea0b68061488891329fa208f14157d29fa1c8f2e45bf14fd723cf2a6755fa440b55562ef7cb84107298c6cdb6907ba821ba51bae5dd4404a0d10a44819c791526be96847277ad18a6847a236368716b156ed616b355a8b6d5ffef227a2f27709b0d8626b6d0bdbbd89b683375669b82f888341c61a391be90f85c09cd9f2912122807e643b522289d9aff8c66a41663728e172c118148b6d152583428d2b26a8d40373a280c25cf9a380426e89406fdb0a37d0a929474ce1c410bed0414a0b5368ed4f0029b4e8c556d094a0a029f86e17e75076608a4cc9cf581b33c7596b69b064827041bc288bb2cfe49c3f555df9091f05a594fa86f1b661bce10dcf2e0eb002ad537afbe22c7d66bb342b60aee89326fd911705a4df957cd0ef22531d400f639646bdb04874bb81dd700ecab1026def8679d45c6bae35bb7b8eab788884fc0441ba8b83cc957f2da816546bedbaaa84ced60b3d654609c2ac11fdc53d5a809241fd5c6cf1fd6142de204193657acf711cd7751cb743add8b40a5a830a61aefc935069a905e85551430965d6702f4a82942c4a5afe9448fc3cd144125da79289a58009e501ab68b0a80838d712b61d40df76449babd6cd5572795c908ae270836dae6da72ba1369e241b0d5b91d9c6036dfb2168738d365368fb4d57cdd55cf98b5b4cb68d5ae557b49349e3aeeaafec4fc8d3df7849df1189c5f22d2f3a293454abcb356b5a3bd4c6035d8f4a9ff8a5d79fa8d2bf6d2e71b336909b6b73d1680dff966d5d5b665f3f2a192a2644565835e23b3edb2eb4497fe22bff26a615a4ec09d9e6aa34399b6b96d3048df6842c4876fa9cdc5ce4ec743a9dbecd550363cae69ab26daecdb5b936d7e6da5c9b8b73693f3df130d4295a602c030533a0a33efdba531340210a9dc2a95983695ab891026f809eba91ba316352388116672953fa188918c7f1e5e5e5e5e26a6309bd819df55e1c87e945f60968cb172d142f5a1fb05e4f688deb60e4ba13565aaa9af8245048e822842025993494e64a445fcf08c99cb9b23963f3c3c461fa52d082f7eda880b8a1bf9d5638b2514c1beea34fbe273f00dd5a311940c3ee3b7c2baea41eefebe8050fbdef6657f39c7356acf5276486b0ebc02bbbb07a775ca5e3aa1bbb3c7e817047dbd6ec505dfd582b04a546e14aa2f411172c16ab6495ac92c58a75f3d21d9866b55c7508d57ae9ed2b8d8761123dc3440b61f984db8bb610caa3c50a5c9be869b942fd4495f515eacf08519b494714a99f927840620c3b28427f1c1b5c68bb430688f54343896a3c2189ab504af468bacaf2b8ca472eece08c12407b764a5ff9e7ac350af55f525a0eec673cf9a06df84089233e331ac46094404c055254e1f299e245ce2a284edaf6a27f407e0e733b75ff7e39542ba1e96b874ea1bcb1b8d0f47e94c74d37e807775000020c2786487284145938a1d841124dc829402d284148c40823308882e70821e0b922e4d10324ba60c2862c481045e8b408e581feb065ca72a5862848809a59079c49694f4c5aa658d43c519d54eba43e8e7592e9e8b55a6b691c15435b881e383b2e031bc860cd343f1589445cadf5f5e6be135c85adb801ce82dd6b2f7773cb2004ac1dc7755c7d58a8fff4e20d9cd9ec55f448f4dde72d52b01bd5da7da283dd979edba2e67ce5e5ef465fda327020e9138daa9d55f4d382dddb7b3b8eebae0c0dd60d8eb7c52a16070d290d90baf2b903ca820c3be8982409e7511ff958695c5693c892c8aa7f0faec32af182d4cbf85a140b8597c9ac26a2e20f006324a286607ed6a857b1584c8f430e597e8eb6199ab6835df5502befb269c86272d91ea2360d59f60c5f2b3bc563652e6941b8f2a55e581982fa15989de2c18291b08317b02014c2f2a55e6079975218a10f7e2133906e087d443fc376c30d421fef89841128a9c9f4d446d4837a96bd9343d47b77a47549eb927e96cdf238b0c29547fdf4198ddaa6b982b3ec5900cfb47db40c8132cc1afe463095bb8565abf6ac2bb28e74e8376d07a7cf6893c9f4a12002242e30df71a2594341d4b7d059337a1352f9b7979fe18c5ff918ff02cbbf7c435e9ee5637c437c78bc3ccb0f89f12b3f431930ff65983d63cbd85c4c2f725279d9d41524c6b6b180698b1bc38cf1476dbd5175b5670d37e10862e559dee5f369c00c5b5ea649234fe5d3fa3321974c26d39bb4c9a4e9488749bfc9f469ad7569c7983139705ca5801c57f1e811011f30fc888165a58e889c5c05c91428d1821bae53369cf136d682901c0da8a53840fa3f80d0cb8a8184fe396588228c6031822f6a3882480a9458a2061aa65051430e217d1ff47f50a73e6826e953dae71504d6d6582c5663b1588dc56275db6c8dd110c7f865c6828b89f2822c6f74cc860f5a447da83a946871928f61487d0aeb30f4e798722d7dbd7c682154ab0f6fe4d58c451d97bf1df5b70d5c707bd14e714f41ee475b8cc9486048719f8f1ff9ff3fe6b95e0268fa0087529c4ab3c25cf9b74065441a365a3672ce331cba029aa9576bad79a594bf15289a8667194d97d088c1096659f4a3453a2bed5322cca2d8dca035eeb6d9f8419740d11b02a9109dc54aaf36a1b499ab66f83a8f0eb51d23f09417f3d84067fe72f1b85c3cb5d6fa375855451a428601fdbb99204d9f03278d062d408ab76ddbde86b1b2b2b292c3065aa5caa256777fb9ac7b594e93c71c3911f83aea30c47ad140900328ce59f92468bbd041e82dbe17e37bf1adac8a69435ba8807e602da5d46bade46cd65c90baf613afee872ac13eb3952b9cfb7705dfbf9ea300118843a34194ba3ba5e448d680246f6e6e6ad0de8c4867f0437feceb668b1f9fa95f4303d1ce1803b3a6664003f30b6ac30a5f69e8ebf5af7f751ec7793973de8f1ca18e29050cace10f70d688a4d8c10d6e4891053365c9b4a2bc902f18e36d7ba2932049018093bee6ca3f3fa1a380a2248773e6d0953feaa5775ca8a17268a8d2c8cef34877a741937468e84585270bf024a003e60cbe3942b01904201a0e8080bd80e80b8895f3d531d148c43cb9b4b0aca89c46d388473ce6ef64329d4e279593ca496592a3c71f1eeb3762210c84c79f1cc48c49957e821e36827da036f7fd75407febc575f90c183eb3d9daaca94f4bcb854332922ccb3899acb4b3e7aa919c8d3f35db824973fa9cfb6aa4cf44c240c8645805f8081e491f3ee2309d3f1f680d6c8489e96ffc058a57a789cb82616b33c67a316bd8d27e010a0dd9b145ad6cb4e3184372c455355ee0232557f980d3bc3b7972e3c8f6f8699037b505ad6ddb2ccd1034056dd5f8b69c6cb55e7c835e2ac85ef765cf186f4e547fd6aa73a2ed753e727adce04cd59c53c489449c4824e2442d1f22f8f7bcf7def3de7bcff372d07486a1a5d02ed903e9ccd9c5468a169f524a69dc68c1d1381d80fe5d0bcb8acac9a45b5872a6d13e9656516a379a9e1b6dab387f9b496f1a76a6ed39ec80839fb0a39e693b4f112e18435ade004a2d3c993685c28310b0f074abdf4ba7bd5793eea6380842422d3cd168b32688da5070c395f6234aa6b7d746db68db132e14f54613613163024083166d0d24fd04bb17b70fd0990936b94d4c1bd7a135681707d05fbc3800fdefec8e95c669c8857af6b656cbaeda685bb9096db42dc87e31694c5f278a8d3e8cb11ee96f9bc19c240bd9d636261b6d03da68a36f030a9dfcb84f94efe7db0eade1dfd925b4e7e8bf711c9fd93e4055be81e03ab934bf4d5c359b31b78959e35e1ce8fcf88b84b15ee0dda13aa3ff8ef36e7a8840f11f74180c36a2f5072729cc490a7392c248fc55d88c219d062144cd67640d6647cf23f86ba529f2a1fb125739594d45d034065382ae3b3c2f57c1604efe406910548820b5d1c805128944e3b684d1c386eb098a0db3aca541de641fcad207b5a52da9ad2f5abfb7dcc2af75deb88ed17dfcfdba37d0e2fc5f85e1462acf8b519ff3fd5a37f4870f7aadbdb796655996a39eacadb522d18e1e36a5c6b7c5a3d51289ec9d3431503d6c10bedbc5380378d4715cc7751cd7b90c9443a16666c9e4742e40e2063dd3333dd3333dd3b31f38aec2ac994214d1820bb44863d4c3aa835624d406168b598befc5f8de7bf1c5b703022e3115358a0d6a0867702794843e94d6324aa5aeb22c4b9f116124a317b18cc6563c4ab2e9f3cede7defc50749b9ae48afb7266d8fdf85ed6edf3df67edbde532cfb46243157d5254c260dbea19634564b1aab258dd55267c6b80eb896b5c4e5288c144ca02f800191a8083045a8f5867e302780216f6e0edc6b90db33ec481ec77d43b8ef7ef4759dce21a9e3ba27dd7b69c8714e96ec844266c84608b9cf07ef9c00fc1be8f04e214004e94bf4d4c8d7c33d9d3f7ce5ffc3552e845f1e5847a4278dde8e72484f4923afe32a878492540374891244e8452f83ea112f4b2594f78ba0ef57d2f88ffffcfc608c771c4a15d5d58324d0a4cc3c0bd2aba8c1ee78125c8a67e1a597f8e6fc249fadee1722c2ecb2ebfe19b35d4430a0f81e729b86db05a7b55ad2ab664cf030d05a4288d4a04413b4502484024f84f9fd71442f4484f9892801c88831147d33bcdec578db33ac78097ec4e83299cb688f120a61685126080daf22f43563ae0802424728a60d0daaaeb2e837ea026a73678df501489d703a63d12374f4a39efa98de84a7afaa343a3ea56f79faad4aa3e3b3f232747c54dee5757c4ecff2943e9d35ddd3776a337afa36f5f4e9df549a18b47a1d6acfd0bdcd7a2d7b86d7e3bad3e9a4bdba1dec669d493818533c8a3ff126bec455f862923362a4c2d0623e79781b0094e183162dde3884d0a29d610b60b7533ba88314ecf0be01eaddc3f2b2755d719fda2f5bfb0a1c87b74dcdab808526ae0ac014bc5b34a08c0516e03d0333c3065acc2d1ede2bc82a596732827cf0969911434712b498511ede365680b70ad355dd17c09328d1a26595f0aeb172022d66188f0033643c41cd2026892f696922e3490a4ef0a6019a4c4822c306323cbc07b083085ab42a017cd7757b033138da73d620ed39552c7b4efd20d7755db76ddc77aad58a122a9026ba2c07100198e920c1cac33b0515602e1ede28a490438c87f709780300ac0d55a11a546795ac344ed4f86495acb31a546b8cd062de303370f8a0c55c000fef0775382100ccc925ca094378cf004d3a892f494146c333ed1ae399b67733a64d41bc65802f7b56133c90e3fea5e44f5c85770a6ce160c304d0b47bf6ebddf35fda3d30bfb27b66bcca7e98272e515230a2e5e11de385640105be08c105246dd3ee79981931f674ee5536f7a73d5df5b2a7af527bfa099b7b978dc3874d40ee4d98fe71df327d25836bc9316301777010b1029a760f8b09b21d456c3cbc55c019315260a2c50ce27db2f1012d5a163cbc4d3225404eac708fe22a98192e325a52b468f1d6a51864cb8c85276e7878975af0f026c1ccd8e1a3c50ce230ed1e981930335a3ad801f3a5ddf3bfb27bf6abec9eef4fbb070030dff232be67a92e006caff9caffdb3ee4fedb61b6cf7ce53f63fbe82b990be12cf871d283fc05080d9a585c50d1d1e19976cf8cd7bb27c697768fcbafec1e9619315cf0801633023cd3ee01c0ebddf37d69f7ec5fd93dff2abb07e64fbb67c6769a9700f83e275bf6e73319ff79900bcce742333e1faaab560a32d8edf036d256e2409ec49778135f396acfb00583a6dd934a7db9aeb8ef683cbc2f68d22ea40ab404984c90a56064011ede1534b97c69f7b0fccbf6d17f4c88f1b96cdb20c4e50a5d3e276d00c2f2f909546831839c0170b470c34604769f38049c33867b1158473a288d9399993501221d41ff3a8e9e0d341a8d55693f515d0b8d46a3d16874db3620e66ac53a02b33deacaeb0eaf195484061a8a8b890594171fbd7d1e43e2aaa019834ff5488f1d82b060008d8631f61115b532d1aab7e4331e8aae7c4a0b3cd078136516a5596b392e7f1db920ca9c88964eb897c9e151fa28c91ad46a41eebd18a3aebd16db3bca0491426b7dea0e52908e5033db3aad0dd6522164d6da6db34b668d0700a4c1a12bf71e40d2fb0d5d4c1575625228ba9f7e23a65ae2343f6acaf413e49a38a1514c1c9dd91885915edff77df41337154a957f62ad31a8b62dc74097d08f9274e64426afc0e9a21cfa019010d00a65420932880736184a32ca545e6b2549525353173e545a55359e62fc418f43ea6b4b5f40c1e301710acd25c0309bd95a371c286830a13cb3bb909050fd413313376fdf8eb5d67e37f75fc049448745b96a3e682d8d5264ee88ecf4d1b5d24a856e5cf543484828ca0182d0f513e74c854306fac655d4ddb922ac7dcf55f6abfd64a0958e6aadb90ee045345c93ecc47390783359c2692908e501807eed0f60d64cfa788333c65739aeba09698d9aa3529c9b9c7366895c30180c0683c160b0087422b8d7da1cbdc160b3a606a8e233a3ff501d3be823f6b3fffc70f77d74d5cf7d250e748fc460aeaa309f119d0453f7bdd2eb7f61f4dea7bf213e3ceeeb27120e197de97b40e9f5f320bde9ef9b4aaf3f21dd973e7f7d44c2196eb81bd2bde730d80b5eea7e39a36fc00cb1572c2e36223a1006dab6e83017daa9ed5d89cfc0e0aa9b00ba042bc06d7b9219e34343501b6bc4cb07f6825118cc98253312267431beb556168bc5625556855598bea2a4a22c6b594b26b556211a6a149ed70d1ea8d568681273b6c4c988fe74f68a9f207e7ef8e1e1a7c80f0d7448674e9e39736730e5827e41bba04828a2447644490e32234c6a696775f5e32a2534d01fc86d11b3c692171801ba2c56574233a66201bb8287b2080dd50b3aab5cfcd472ca502d4b24889ec74210f4ac201de9b02758245a065afcbf466e24a13f1ad74eade2b15e475d9952ea9a35ee4e6f34a165a477b9e8e73abe726b7fbbd6fedc6aad9b9dd64e6bed2bc0356b28d5190294428bd4455f1bde86a0a150a0608105175cd4a82b68c65017b5459c07ff218b44323458404441a91803fe0ac430ad88017f73c6d8af1405956e2144cb0de75c6b2e91f9de9b73ce7588c66768a5b9a12bffd9cb093cb4520208a1455a0ae5a747268d8f227367def0dedfc70e8df7d171a79c38bcaff4a33b46bc2376fcc60fe740074e364c7780f4c0834daf984120c22c698df6408d5085bfcab7d66a28baa1212043f74ea1efb75c75ef44bd10a7d980afdc46060dcc187f1df8f7cc3a0fcda13dbb8e34a3e811836868a8e2d168848768a0433843d522f4b13fea1991ba9dc3831e2a02e8431e6408c8ac320d02a92015670d08135af4167e9195690179919460b11c85ba41851669d068d5da0d0eab552fc6d75a6b2d0b07010a4d07b55a10b796d6e66c42c346dd82155a6c618c31de2c7824e62ada8303b5a0590b9a3bc80b5ad7f60002b21768c98c24818084545710144bc609d96b0728309eb55699ac833c6622ee78c7d2a86937e8d69d4a738b982b7f2492b8e33805d6c13bd8b5c40bdc19c759f3738168413868f18e77bce31defb884d0a5b5060628be8062dda9b19aeb4e5ddd318b25eaebd22bbb4990b8ea22b9e31df3680490aed64a8021b4485ff565a4762fc801095200d2124c9bed45da8348345b0aa001a934d31da43f3058e961d6e410501bec0d45a1ee23075269e88b0201f1bc805e5417419224499224ad2c9693efe424fd8ddfe090291e22d11309b3c7c4a7b35658a127a26d3fa0f39a85794f263ea18f763c48bf3b6d20ac8e5e68a8e6a4cfee08460add80193a2945e3f77ef42457b10a376857559108589f06a9a0a36f0c4ca15e645a44e1ef7ef4de4ee1e7f497fe01a79f41d2639630b89333a6542a9d364bb758378cd0a2c36e8c5a7418f69ff84be59486743fe2defb198a949643fa74b82f85df7bee79049ccfa8a48e77c5a854340200000000131500001808088482a160402c1e12ede3da0114800c568042745e481888c4b1288771100431c61847102080106088310a410dd904342c4770ae2c5a59eaeeabfa259724264da163ced0cf3e7eb69ae1a8b570a57c4e6fa8dd6b4a9df1b1a39d9eb0c6ede7087eae68774d46320a9f7a54faf1317058bba45ccbcd023ebeae75ce72adcc958ca4688b88e52613cb2981472f23e6d04446ab91cd914bbc1c74b26cd42ddb1fc531cd031c7f942bacdc9a53c6d25d10961bd21e717c8a53c5a28bbf1b55b1d4dcb5b60196d2ef4b93ee9cab9ba5a3155715087a99967a44fbfbe3ca90d04c1063f9a8fc4114468958a3aa965dd51898d15d7b02488ddebc7a694257838ca3beb2934ca7ddbca2a81c2e690275502579ea08cce993df165ceeb4431f912eb4e9d2531268ff92e79a76ca173866735a76f6434e4d64035f8b9d5a39efe7da0d5e740cbe44e98a43f09d51fbf3ae0d80590280d7823323e412de44710a1932e62651a8452a40d7caa6fa808420b66ee9c77831c894e1338aefd26d8997f855242394d35b4dcd0c682004799426320f743236c753e3fe121d605b3e003b8282fb33ef006a8314b8f05a47c32b7d4776ee3ea2170dc9e81b0e5d5e213acc9e30d1477ba894f8f424779ad87042dafe2fa794a8bd33b8bf84363f3b9bce8b9a8fa594cec86e41b907f763e28c271f2971fc113223c8b8c817da54981241ce72ee713ea1c73d2b3496cb57490d4aee3920bf51fe15bbf0c48fc009832995f5b563d97b69ca917e2148b53c9ecc691c3920176327a1a6a6832bfaebf51111aeb0aaab97cbef3c74777aeb6996e4d4753e4398a0313af1c059b6bf7eb5ef7e8d712dd1892054c67c3584b0d929e63c492793512c4f4051c752fb801b4940bca3ae9ece5f180a9125eabf5a3e7591bbf7d38d33ecd31feca92bb7f6ae0ac13e1d83a853f69c85a0db64c527c261818b89196308d899712027d15dd7075f48fc4981b574e241a3270b264534a188fe83e422d51b6371a78ba05d432792c6809e8881fa1225962bb7d79ce03376d444d2985ac0fabd6c16f8b2119c059b5a0bf697f4a42a93c085164e578aab4d052575af216dea3c847d908c16c19a0fe58e3a2fba2a0c1204e60ed81e9fb418ee5595940056a625611d825be25132cc486fd710c5ef6d4fb14dbd6c97c89f7771c52ab259d4925f7329830e3fdd52dc82349e9146ebca3223312eb2563474e86ab03d34d3e00b6983343437e24fb666f6fb1302822395a257888d246e872157139d05b7e589206b65ec8ef8c65b48c9488aac8d680c57bdcebfe2b5ba14d5c95abdf61a27c53a049c36ddd3a0ad09458daaf508b99c48d5bb799a291da561362541c560c5204289ef2fb09a0ee2a4040ce4e4e27b53534423f6ce841b3de02f7b1deca73ef532d72a2854b9564dc0d1b1c75d5e977e1b29fb3cd431af2dc404ddb0b97943eb5a226ce1ad96943029c777f8c45425c4078bd2944b250d0505f2ee3bb555ba43259bf4dc6041cf98927e2506569689ba2d97f6fe3735c84532d86358dce2f3ccea23f152f6e954a66d4dc4f249e4009877b39bb7df27bc2d5b1e7162997161095879a5cb9710da0e83927b93266cf8b4a60b82366aff013e5bd1ae84bc7fbca44d57e4a3d9b5f149a0b7392925ed0e24ccf7d9454c162444793d505cc41041b5616888554117e6ea0517e92503941b2bd92a895df9ef4aec5939b18ce6e037f4abaafda1a4bd57d473dc150f06fb86c2cc9d0358f2f39e602faba43f00f2410c22221b51dda25d1e2e2a986edf9018b021630f751fb0e3b85c8237111693921768abf392445a74ced5d2f9a36533b4dd7471b02a69f725ef924bded6d5bc3743cbee9033c5640abc15ebf07763bd026eab7b63f5c54197f6f6203d602f201eb67d0fa1bc20ee8822bb32ba7fd6b048ab67681990fbf4d167a142bcf7aa88b098814bebcc36c26ca8c65886c8fcccb954b070e145d72468938eee75a32ffba0adcdf2bf1fdea532ff2c2903ec2c411badc7425d78e65c317309aa34bd7726536bcd499f229be61526488978c892c7f06b868301a9105df84f3043013cfc2dc25722aaca4e77536f9382bd18eedf1679a0b9e2ea5b8b141d8182bace5584a46aa065b781502c95d69324aa1d9a3a50322d5abd3fbfee012085e25412f913c01e2bb7ccfe96f123a6801d958a720a3e92d7459d5e5375bd9fce4c010c9b9f26862aad867bcaca5bc10a5c5bdfb7fcae26ec2a56c471b9f80942189408d38807c8ab74baaa1d54c631bd506430e9f9031e9a0cc91234202e31d9f812a7fb036f5741d4c133a6073487fe8482fed43453ea658a3e9634af6f68196b417b2336738a27ea0980811e7b226e36560cd927eaeeaf8b7539c847333b2fb5c620bf654d94124c9598a207cafba40df557ff9ed3333f643e0118f2656b8077d0968adc69b73f496ec24b4ccc237f946dc6f10b80f3d876b51dde067c3e40e4d50510b10ee98ed99327a18a1c01409c0ee49708e56f85ce476099df4eb663f36f59628c573bc8399b9bcebb132518ec5c8116eb40154e0f2c16976acb7460d98676732a4be0073d314e33d71fac61a82a94f61cd7912237a48909033082d88f9b67e487004167aaddcc46f31295be997d24c93442dc8c28caee267ade3432ad282c2d545762b13ea5272b88c6ae68bacf79e096cbdc5ae40490302e33d63078b1d0613c2908f531b10d53acfa58c104b09b4cfdb5413e468e13376e1c47ba9fba9b17b02cc6a9f4293b28d2371fcf70b6d93b2434bf1c187adc8bb37efd4238cbdff730e8044558a9a01ce09b507cf63181157fc15aa42ec889d8668687e9c0551ae8501f710f1c93a473134d3f26a9060c5a1c15d2d9167f207d1c39a02b821d5588174affc417b0b5c1927cb1e0286ca9dda4f6d753157ffd5b04470d9159e14887a80e6ab8a1f19043d422ed06be8133800ad9578e78bdc85e72cf42d817d9a3c819c98941050120501aa10d4de31c28249dc82385b7c7c5079d2d4ab38951ac56ccc445a00f0edcaf6546e1ef0734506c443f17cf3f8a7f84dd7597042cdcd012c9bac57d837d45950092c8ae9c65ca0a8d9da75aca6886013415f3d126390a30173b0ad845894b7861572631cbab4fe5a9e4f804e90febc3d9d8b99d0a96e44a64723347d901114d7471a99ae7a7b1debca9eddd3e63969b47f0e542204f954fe485b08757f91d1a54f3d6564c7c8bd2fa04022c76303a57624f5a3f0f194a5dcc4cf8e5ba42b0f51486a55b283291d3a00a3fcd8a8015c064af9da272174708b00b5d1f420aa4365c78c8182ea06f016fe9d5108dffccea4f6ddba764c0605471df50127fb19ceda2504ce0ffbe79ee29366aa9c170e063323296a013cb86aeb7760595a80928c8f9ce47207b0f84c77ffe809894f92ed8c22fb13f2dd029258824b78a7ebde0aea8d088488c7eba769cfad6b53389416802edabeaba8085290bcc3f5264c8a24623a0206cba54e404c6198509b4eb80c56d16640f104511f4c08f2d70b5cdbf0d9cfe5965dafa1fc55c709e7e2181260be5cfeb56c0712cc5eb46a0756de82b6578c148f569c15c3b8dc144d4a78a75fb96d11e3a57efc17bc811240a9740bf5f0e4c929a3e5b784ede12e8040cba8bd32056a8ae4bf87504ad8e575f5f7038be725d76b822a682577709b4671a67b64ae04b1e81eab36c969cf5255e760a579e38ccb751f0c48c389cbfc66119b9e07900c7463601eb44c4909e23d00ed40af4d0ea61737b4cf042e1ef5ac3aa3fcf47408dcd0f7fb9d19927cc8d7df4d382b85728fce512501a61a09c5a60dbeab43b3c4edb30522f1844eb7e4460b3bed72d4f589ba3ccb1ee83993ad7ba13804a0bd040c8d02b2380c2b94c60c2751713a447a0685e354fe192a7e36bf456d6586e19664584adb241a239646dc1d1b48ee3cfa5796a1c21e00a4aab3e96c89660ec1fb088aacaf8d1d6708cea3c6d1b3639abb8a9d05a7172c691a2f417d1cda14b39edb4de4c725920b46c88e49c8d26fa526f4467d144bbb895335c0acfb1ebf24260fd659596d6454a00ef7d744a8b5ceda0314057eb9dc134ea9162c4e5e3849f037e9400b3752a6d3f12413a5db908fc47ccfc67a9cfa7cdc20764db038f0284dd70dea8fb7c2e488d2fdcbb6392f225e5ae1b50ff42b6f844ea7c6a7f8fcb4f748d02998e2e2cd768418293f4a80e4e35eae5ec0a70e68ba16bce7f227de3bb51b297bffa5bfd93a3394aca82bbc86cf9dc90614fc67f245f2a7dbdb3b0f409d24c3820a2ee6eb676ea9b4f0f829eff62ed7fb97f7297e68f9a5130638ad2a7dca2825be4771eb3cbd22f0114c56092e3f5bd468a83561e6e7729d2aa1dbd5b094e46606e6306fe2e6649a1b5c0154bf3c3c53325cb1621bf692245c16f6e879ed3583f4d0904b38fd47ed01c387df561ea5892d4ea413b86275773cad9f198ba5adc1f90bd017f6f718a7346d4592cb34c24aca5ce127072a53a83296ed56c4f38de7b9b74e346a45cc2df6b35321a19c25a947ae37e6183e755294ee80d7e97db28fe5b9c0e6c5c3f3a049453f8614e0e1e8c53b885045ebcd66bf04c5c7cdedc4b95fa55ccd1ecb93a0288904fd7d12be14a930428093ec45eed85219faad90e2d7605ed62015701980f168b026bb1c4a929023e532d1accca458db0ab53af14701dd33c031d28c5f2004fb5265bf49a9204f16067dc4742924888de3f50e2fcd5b873fc20094a8fecb1ced477d2f5d8b3a7eb2b2093706d38866cb01ce69405e105faab280bfc4c6b5b5b30cf1102c398ab5bc6d40bdf4ab4f179e4376605479504296e4edbfc932884fa2272c594a567bae4f7ee2260a6f6d3ab329e6ea9212417753a7da37a37247b416f7ef093553d53bce42318ab71ecc0c56a2622f85a5f46fd81d2faf682625b16e3884b583af64376e970997446c5aece1846615aa870af143d19aedfc69dbe1d388729804fe725eca306328b54ac10509cd2f6495d2048d746fe7b9de9130f83147eecbaa14be8e2101ff76974dc6674247cf211646de732da45b46f8821405f935196c6d17cf7e34748f65408d3a256aaa1b8f3277e265caccc581672012ffc1caddafe075810a73c58a6c6b695f56650d6cf04b300b1e9fbcaa7b9e13e569db14180c1206e9fa6ec72ade567bb080a2a6084b6836c1827dabff80cd56a318962ac2954ab746d78ad049b7fc6aeac38e346edc028430e7825e470c68c44537b1fd26c01272bd05ddf1e2d85d921e16f61140b8356f6809e20237555283fb0584e664b5e6717cd841318944a333442c028c14b92c6040e7e3599512ac7d61c822b7ea8fd4785259cac9a4f6d012fa44798781ca6b56e4707f3fcae6e4d9917a1eee07464b8613f7fcb429d10b500cadc21f41ce00de7108c73eb4781880850e28989da905b94b45075fc2b240246286d5b44696686208c8be10331c5c1349bc28f1af235ed644c6ea0106d11d38d2495c514522e01c0adf9384ab8ad7b65ea8802d629d62ab9861ece06620e65fb5883c0d2db596a1dfd2574eb63a153554542e10b701f6c65fa263cf1c675756d76f3e9977316a6459162b5da2287fce181a7c92c7ae6f16db564a3238fc982262bd0345c1def70b8c4b898ad59e53f43d3f9f521c0ce3687cb010d68e6b764e5ea6e75583e4e419d23c0c5de011eb7b8b975f36411e286b0252fdd2c6259c275b0cd55f7fe97aa9ee0543bfb586582dbdbe334b4695aedefc2efa566c0534350f303e81247bafc3de31222d5d854facb8da3d84d885b7cd0cc143c705bf51ed1b9f8f0136cbed72b3266a890a44b1afb5dc7f10aae153c4b72a8af644a9b66d237cba959d4280478e21c4e34e7b717159afe10452c7b43cb99b0b8e65f9fcd9bc8715d0aee04f79279e1e6a5c09b860b9297f788c28d3208ab73d14f70b9e7d5cbfa2ec46e7db7cff55d8672e4ffa599436a0c2a04057b5d129368450678b4a2aa42634be68402b9296cf4723ff0c6572fa205766af45a161a41bd24733f1abe2a573f29740a1c42275f7ba9943927398ee2b9b8a3b78d12a5c021a158209027aa2ed3fa0c888f619bcdb3fc94871b44c65d4e5ca5ebf336610c587ca372d817c3574c76b22fa39d4c16d1be8c28dcd0ce90a9637c545beff40b42fb93d621a3f82802ecf4a67c0cfbdaed211ff8994bad11bd7300aa29431a6794914b92984148721616309c4a23a49b4c0e9a0cda204b59e85512580e4c21f4d370416a7bbcec7dda02b20a2d5a2224320e3573b39d4430cdcabac878499ce273ad229e70191931a6c2636ee928488748c2e1fb8edf42693332782c547e70b70f7f5cd07c4bb7ddf9584a4dd6cfba13694d6677e1e20e3246363e762ffce19269c51fdd4510dd3c64e3e682bdb1b9da542f09e144336df0dd1902346a83602d9003054b573d4246f042643d24f6590be512214420e9dfaa80aea3f7cfb165bb8869acf794c1ba2c4d965266ee780e84c1aba4481f2cf90c1424600cd1b271cabb406f0070a25925ed4fd0c88b13b3c6192eaae156a8c5d614a53fa50762f42d67603b65f7f39aed38f52e615a58e3cc09462e2d95bb5152e389c7d861bbf866f87c3a286861ef0824ffa8bcb3da8abb4cd4c7f7b19057d69b45b3264b7ef116a3f2ae862f09f77c748892e499ec374ad2599beb3a3c6a802338dac9c8a9bc0b77868a024b2bcb889453ca7d433780f23091c654de6d582742796c93d6bee187f59a90dd0578595870b6818b108503ad85b7ff099bfc6d58fb9e6ce50d40cf1c1bac24aa1f795ec2fd9dc8531a7bc2a4f2be5f5d16062e5a187616e60dc43f68b3b4306cdf3517b68311f66b2aef0302b0141f461dbffcf7bc2f99db2f1d50d8aa415f61794f7db8ef979a3204d0f48b58efbe3446a65e103b475300046febc8f4a6703dbff23f8697cc7d6219aa4cf3bbb3bc741a42e5cd34a8631dc56425705420ec5f8d081eb110576aea5f4490ccb773bb2c190115bde56118d7b9bc03a554bc7347fe3329729dcf8094ab43842cfbece87677fe7e655a2e8cf448d95800b0458e8229950a459e2e12467f4eb246bebc4c119a4213ab980f48a34ac99b9581ff5ece98171067b4e10ba86828013796591b0e09d5042bff08698c7f4394cd95d66177a9a9d8ebd3a006fec018ad1cb7d23b3db21b7ea8e6e597fe3e8fde2e378690ed4278e440a5d09da71e3a1f6eedec6a5040c88ebbdff81d87a2f831880e3ab94c5c1abfebe5ce93d345e585694e62110f078b74ee7682adf5d64141c0f9eb03ad82abf3268b1ca85be5098c154198e725ab2db4eb6ba03b9699c636c731348d7b79f456c0eb01eed0d3e3052a292c3172b653ad33006894b1132fcaadfe3194333ea64a25c1e8631f78aa477bb4c740d381398f4d0916849fd903e0078e8b1ce64ff10a415e64bd583898f7ae50fa67c22f374910e264107935c459f5f602832509b91593651b1fd3700a18a700974397857b0a4ee8f53fbdea3479fb19fe37fdedb5ea2ed28e5da1a5bdf8417f4c68844396a1d2fc0fd71986768569d0d93cd6d61e753bf5a526d5a66e109390205efba8364895d714c2705798fc650b1b0b0c80c9624e4d2fb24d1ab5656f9be8587e57b1ed564be8d4f98970a8c5bc09dc58caa415bb5e478b987d8ac851a992af03a8c0f3201417f8932d6c937f9a886d73080398241d119b391cd2439a2e2c3c8417209e69f32d7c076923200665aa584129f6ea3499d6c0c2d6efaf0e4c3733b4b9134cc6c8905de4b79349a3450cd6492ca29c6b14d37bc8fb9c546e55d092e6ae24d3470bace5d035c563c0d993cfb1e1a20239e530684250b06c742c004b459779453563af7b2ca46f3a59cb372ee907fedc79bf24ba377f5f39c9f5a7449138bedf18f007bd3060c9a66867ebe7f039a80064aede76f3d1bbf82bd2f320c7529945f936b4980b3bf25516b5c5327bb57153e3f03d47ce3d82b99499a401273e89acff3434e6526a0871c5c5a0da18f1534cc37c8955c5a6ebbe1c4b6c464bd83c585ab29b61134b3df09eff43106c7cdc3dc65674ff3c80468be491f0e1420cb74465ab20d97723f3e483fe586569adb7afbfce0aa6326e86d1bc6ab1acdd68b685e5f283145ab0124532acd4a003e3af8e573bb3425ac32885fd64c3d484ee1e891228728263f41b9f01c07eefe8565c047a01e020a4c742c830e5158cc1a02f124b3924f1b43e47eeca591213ea336c531287844c6e3e491ca2d6884e9e6897154b018aea4785bc66e320fd4118136c2d2646b5d8e3b3adc87963f44ee13f678f1a6ea4f783bd17049171b40eec2e01b531ba03767a1c63c5c691cbaffa04ff49e5376a33c141f4d604f8f7242ff7f8f015b6254ef14274d355dc471caaac80ba204c0519c780c868ad8c1374dbed5c0866e74edfd9ee826f8f2bb987c4c8206f21e79d9a3141acb63e752edd36008a862567e47e0a2287e20e3540ff21611c0abe5ac3fd00dfcb0039269aa28caea69e70dc2d26378f54ec8a53828160f35ef822b5e4629f841f1fcd299745b7ca8883180820eeade6f0003cc745811db4b0184b724f9ee000f5532fad50d971a6110d5bc2e28ac8ae9890d883726980c7b63453b34cc3040a4d63971635ca44a76b4d942336483916e4d44e71793bb05d87a940414175926c8a5707b796e801110f72d11e589a4cf828e70e1986d3637c14c22046a89dcf20c404facca3c8e8e7ef41a3d7bb3474c5694ee7b1be7e99ae84bbb812302d7f8ee5c23d1327737b9601e431e85d929c9f43fcbcf28bd247481e904658d7d85bb2bc0e0b684f42b111802e29e1bc85d6a41ab408b9be2983104f56d111cbfebfc5d4074c064eea8f6cd38d5e1f9a5ed3897afd84842ece3c10f2d581279ff1b70e161abe92e644586ff021e1a4d0ba46b3e7bdeed7b96a092c08ec495d1254e2e5af1b310319efaf82af5f28e33329c6e0cb52ed8fcca8080f0b3761260098342d53fc86f305741bd065331ebe56befbbf83b78c3e6a5b09493385ce68f4fa58bfabd63528640eaa8defb3c27441faa748b98368cb8e3dc2384ef2fd5c819228bbcaeacc395d691b21db099b6525976409c7f4bada593cb173bd9725a181d3d7556cd2b33d922b965d2ca8350218f0a2bf5844b9e0eb12f94ae726d560ebbd982116df8d38e09740c588a38912fd72f2f985ad403c4d3af76f81fbafe1b012e9a9732d35e9abc33c615ca05a6a33e74407464f76332b5b8263ec25cbae8b140adfd76c30b8f4ab680b48189584a526ec8b5f73221efc3a621e4cd30e7cca2aca1ef15b6285c8efdb9104989294c19d37a65fa8c7bc10349158e1f7ae0c8eb426a51e7989e4583a6817df53863da0fdd7a1a2c584ca66c151fbf4ecbfe995ecfeab2ec4fdee534652b5ce88ca852d7d44501bf95f5d0b3648f60a43e3d4846265bafc6fa74d6deedb6bb7564e64c9504697532c160924dc9ecf4e5e01ff847fabc02772da92ac5700350ed3065644070b83dbe1202ab764ed76e2208720481dbf91df92f6fc2129312d22368bd604889f5a176441818e30a18714aa90879dc8c0f27eee1cd0402e232e96ecf12519c15560b9ea8354b59d83e03cd39598fa3aebdae2fa0353fce1797c53bb7a38cbf19a1afa0792ef4524dda345382513ef7a1e400f79cf80c2df3eb14db254e1f807ab8e22bac4e2b404c8389cd071261944ac79bbf22ed1055b4d000d2c93e59b1f630477183c6dc74c3699e5629fb101f712abaa2c2d0a2794ce35b3e2a13f21a02e15137274964b4fda76a9fdc978024325f8b247de1b75b2aa5458090fab5b7f5441a3cd5d4ecc5988c739885b1b9216939eff8683904195a2696bcb3ad5cc673f4875b330ec093181c9f7237728a9442f88cd25b5541b44b93f4c875947c67b7417b039c38f90320a31690200b39ee8683db566ac001d15cdbbbf710447fe5dc2246f0952f1378e9ef638940ec562d802d8b7947384e6140ed920761bf3c36e1c570a9e1435acf1092b8bd7e632d2878b91896392d00874401422014d1c378ac5885c5f9d5b426991557544aa98503ddfce52026ddb16764bc6c5f6d146e81248ce5d11b0c5ff15a09d63c44d34588081e39dab85aac4ddbfb1b6345a2b6c5be7bf8beb20e4886dc71599904aa3ec5b83efbad00395a5c6461eb4593be78b46829acbb6d95649999c8c400ee6880913d196a4511b7408a51fe4e0d67c548a5bc8818faffa6e42d1557d4b01a6f6ba9c658a60cbeb33c161e2e09f5f259cd7877525c499dd5d5be16af96ac15544d0957dc80d9f86e65e1a1b1f7215211a9692cb363d61345a30275d25b923593fae9d4c8b5cc236e358afde4012eb3f5a8ca181ff30ec340f5a370e4c5c7b128d9986749c42971cce72b57955bbe54a34cc5c68e7b999060cc031aa3da4ee547472993d2492dda3d23aca792e62fbc3ef94a924a87b8c67079319eb0968c5f7c9b6c6ff2b7c0cbd5cdcadc3928500a511030a66b2e496e10fa9235951e8648f9442c79fdd3210e78c75cd351ca397c879955091ce3c51c9b9cf4c29d24014640fbc0ded77651e96c0c09f2cc026b01f85ab1ad2430bc20d993e33cf726ac62569fabb6458fde05ae14d48d373f228a2096f9a1b32702c3c041532bb7582991874fab10c90070cad5e39dde0722f783e931bfaab0443af50ca830820a715468123e0106494fee2dff5abcfcc79e62551496e8de000d5406762560f470855c1393df2a85072b9ed60027fe4256b1f72bee1abcd74052a747b858f5956c17a1e39728b3bb0149fc911b0cb32537014f028454aa7f6c115eed667dc4326552ee28cbf5021ece50be0383066e953d330458d88e48a7009a2cd50197358a44b5098f79f35e3a325b9765ac22da2c98361df2d391c3650280b335b812f561437c9549a23e9d4c16323faf334877a3231b6a98c5ad35e6f0dd6509c777aead8b5cee83c79d5b7e761988334926118c66e3f2c438e39fe767e2a197832a4a2172090ebdaa3bf4cfaceecb2acfd3d4d67f7f40f4fea7e5c19faf79c2e5da97fa2d69d81d703b1a53035264eab7c0ad96d1766d75a1126dce4652da256542ab9621bbe8b7be68c911fa76f00cb182692c48e6966f7eb8205606762fc009e76bea5c5194f7de077ce8a12e1efd5ddf1a4d00bb2b2dd8ca55d131a2649715532d65fb19646ee50038af1d4d4b9f7220f5b2534d186ea4e308e0f6212d6047c72964d2c0a5c43db9b93a08ba3bd2075ecbe4a9515ae6a646d5c111f4386e3f616580b9695af3cbec66140b77f44d991a5d6e52b0f5b05b18696b7357b69d983bf92232110632673e56c3987080866481b682550e0ddc665708c1d5bdc75558f2a95cea89852a621e3dfea00d2912a885e83f2cf706c24d4a8c2031d35e10feb98ac288771a2316111ba851c5d26aae7317bc255e3143d42869bd743bacf0e7bca92d6f946b357d657893dba7b65ee13b64b5577389f460beccf921b994a11e8c9d1f933168b77eed1a58cc3cbbfbc6c02308854268d48b035d3915fc247ae11f3abca80d29910aeeba517314c070e55f5453517a1ca3d4d062068d36ae7953ad12ae68e1c4f31f98190a6ecafac15a0704052b6228db390a0541556da9a1ab22b7126cfd65681408f1cc6e88b08c9ed640721708716a1fa7356e47ba9ed1c99303142d17e54dee081f31b2e3cc3253b34446d8be5e1ef08a9b1adf4c9e77bf016a8a09c9981a0af2d882523800538f09b52e0629045a5a876d8fe42d8a655acf1b8206d0bbfac17487a87d47caa9447c8e5482a1ce153f38c108dd0bdfb85401e0b03058323d79258679728901153a3dd1c097da829091be99ba72de760974ac7e05ec584e5d9c1781465857363a643283363305bae0730721fd0dd4aa5181bdb60f76182f1c247fe8dd5ceea0b15e809f9235888a4488783ae21aaff0efab170f9965756234d23a918fab696f859b3a8e4dafc1bcb169573fe74627e572dff95d8502a9a07d00e83bd4f5b210ff09584c7ec3cc900a767e164606665baf260ddf89620c95f4b22abd938c51f3907997b74ea87e2b5f702f9c7c9268127dbc5ffe9837b8ab8c8353c64ece2f4b12c99494d479e249ebbc28e7d30e514d0b2c4764800198e92454f9c5ee89dbbce553ca91c16703465a85d2c8a032e2d457182c798105afed62f9c455c750bd9ecc893d52be17011e880150c5c6539efd6d7f0b52e0ab867190212de8968170ce9fa56c11676576d5a26ee169f0ab4f715da24b14fae66250a2a62f87d9d08c09e5b2af8856c315e7389eea4a079dec7f6cc32c1e12690586f6722c6983a13c8c6509efba993bd887a86cb5bd1925204eda7b06e1b803643efe31fded145872774cb91f76514a6d36683b7ed367911e24737f9dc9e33a2eda993bc477ffcaa3540627488d18217b6ec0ddc177f428b0fc02ee70c71f9450d5e17ac69347451aaecf1ae1f8f45ea47518161a45d1fd5072bc0605e83a64007db0a310170bc6ed6ee3aa1ec59ab5677025586283d5e2959206f0539322e8ae217c8d4188b8346c6cf18f0615c9ea9010ffd10515b87a0fe1efae3a6662a2593291092ce50d82a972244e1699ee72734dca67208be14188d2bddb987d982f9738730fa22a9a521504ed5fb0218997db7c05dba6caa996ed6e161b5f4c793ba9cfe20944e54088d470b612251f95d92449cce73882b700565f64c924bc135d11e503ba444ecb0731bef22618c27632407f59b51aa917463a5c300a17cb821e88e7befe9a61dd9b0e2d64cc69257ac27e03e624ca2830703808937a440e5103d576791cb8a6aff30c0792c98489ecf63aa271b564ea565dcb56ae14ac992fff327fa37035a7c67fda8343c7334253a8d49dcdde040207c11ef456ad45ca319152f00440dc0daa661f48b69b32e82084888aba470579bba508ce1d524221a5ab876b885abbde06e9dc4929cb01eaf71e588028603786c2c2d1857f6fc3d89d691104522a6e539eb51db6c0ed27112ee91fbfaf421fa77d148223b018b79e1c12c81b98ab3fa28733bfef18090a64823300a9374cd7a40d1062fcd62599cc8c8280d4ea3b294c162692b5437eaac1a1d8cbf9988f587b44e71f65bbf19dfe7f235da5bd7795e2c3a0293533f0109541c3f33113681f675701c81daf1d56245577da77b376c7b73a7e10254eaacc7628f3c96206e56f2c4116d069abb50f39d466769fa943fa190d264fcca790411fd492b9af819f0e501de6d2ac28e69e6606e92865e908d8c19d357891300d12c61012408bf1b0479a20d6cfc5a1d95a814d4479aa656cc070a6b4078be6e29f4108164f61202a9beb077d10f190241f7a0ec255fa000f651f29ee21865b37b5d7721cf7ec1da367026fadfd06424904e4517ff3b582a8b0fb391d4114b3db0c0cf7d4ba9376805709f60d297f5203ede69f9a2cbf9c814b9cafba620b604f9e066e583561f5c109799ceb5bb731d4c8fdc76f220622dcbd0413a1da25ee185713fa53e82614b07ec6261fbc559e66889bb08d48f3c4ede89bb7361c220bf83e95697c4da8f560c7840c1c02aecfb05fb51c184f391579d017c094885f70245ac170caa758213aa5ef1474bae2c14907a62d69c88dd6ec448273bb077bba77b0bc3560bde8e0fb4d1d2eb3a9efdafb0c185d1a13e14dd70c68d09424197860d0df04c2cba42e2961b8d665c61d98eb95de647561e207c53f2b6f4a5412fb7763bd00c90a94681abc0a04cd9e05bc38549c66d18f14d46b13108790d2535ef00c25bd2f9a28f2f75959832f05727eb054bd80acc218404474f74b4edca44213aa2874c230cdc775749236d257d18da6942bb77bc9c3fa40a67bc10f0940e48e49062acd79914a0e57d915b09471591f967c5ab1ad3dda434abb8ee3f2374b8dc396741756742ce7d55c2652815b30340b3d651ef2bca11efa1f3a67a8fd3b3802016913cb0d1e3c4a07d637493db1678786fca68222cd43377749bb94be14605b9b2ca4faa5393be75bfeeb96b413adb27ecc991f56b579e5173c1aadc29230e28bc19babbef88f9b56ce35e54accc2b360051a9f52ff306c1e4265c14a11524cde6bc8401509eb9b49748dd7fd543e383b2d59b4e89fd25115020843f53ee19d92e3ece51f2ce9d948eec10499c561ae8e77d587a89af6450288e5fe8acdb2f41916291f408f83f0663907b97324d9278d4c232060805482850845901198e580f28ba6309b0b697a94f8aae4d03554b98dfb8806017bbb44460337dd362a6284d62a28e709c4ca71927aa949aeb24472745dc3f21fa33ac61a6adc21070d33607c18578e0b66f7c6579e37e7d55ec8e043a8e385043a25138361b4c6c68251970b10256befbb24181acd0ea9d1f0bf9496a08af91ff9505c049d9d45ef31a2a629871ec18aa2c5fe5bc541fcc091833bba17b939c41cea89e9e529d747dbd81f6ee0f446fbd0d91688e90f083b0e44e13dd0ddc700550c40f8999171c004aad5b8377e2badce024b570fbdd89a772839822db177e56c9a4b6b0727514295cfa6458b2e72f8782192f9a19b5d34b13fc555b6cd5ad95c212f6a8d8ade4cc6bb6cdb090486582c18e59109cae8276011ea7aa4e9756df3dd149f0154170e9034ed46a129595bfde196fb720b858c9a112d7804b33b435d949498431559ea03d1db49e0b76945abd88a7ca92a39651865526bf52e999cbef3a6a8389b1a2d3323bc423670e0b25f026b504022d5024c3813c614f7ff0416a9b5b01e04cc1aac201477ca613fc4ec4efa57b25498d3bb1a63cc9cd417babc3bcb97e89bef90fbdd88fb0e3a613a28a4e1daad0d2e66a9c1249a37cfad8b728645d2e51018af5f62d93aa1e4628f6ca8e4a814a0d869903db9ea08af733fe4c55e29c1361c999c2c57cf984f3b48d7c44bc4459ee519141bb81a315f3f43722e518f31be73054d4e1274ded15a455b70a06318f7c536fb0d3f086982dad870824657584f1dcb9c0a0a9f16bfb0e02e302078278cbc5fd36a9f2ef257b84fe970770e0c3dfb030d1436cb162f16373df92032a136c6f406c5fa5c0a42f69b1fdec3719dbdda40bdd83192aab6407482cd74ed82793706ab619ddd4afbcf0f4f45f8e282bc41574061bc8eab606d306df24149661f0b75aadbbb3347af5481f9076745f11c4d65c23393c90218c066a2aacc916f0f9fa610aef344334a68d5d35cc2d2a69f9214bd113807fe7d6cdf75d3ad17969ed2ecb69a5ff9c69d4eb8162ee0ca05dbffca41a17c56d992e7ce3af445a32e9628d49cc6f8f0072c69ce55909d23f52863ff1e1e3701247f2aeaa25402d793135a02a51cbbf9c094184782ebd767bd4da4d4447c225d574bd5414ceea20fa0ccfd231b4e022ce8873625f51100ac7a90cd08502d56595a9cea435098ff91286fea9e705f756a27d5fc31f22b4d808ce7658f46b8cd880fe44d0261f36ff3d8fe94815a6392d78b8ab8bda19b1f40722540290ac07ff6e054d63133f74658e9ede5a04a06c84dbffada085db26dc90f62ed6eb658c065ec2608389d8c1352adae201c7e4b4e5e39eefe6318df34c597105811fd0ec6f5e815b77ea7aeaaca36f689baff5188f0b4b42f05c25df77f997c54dcd2b89596c73379cd2f095487430091ffab44732f6fa9191796c6928695190b317f14bd3906cf26887486293e2e4c10da51665ef00f67f14fd237d3178a55c04e8f02a72239324ab87b0bd3a0275a768a2b183e39871c1b0b0122baa8cee25f0da6fc86e1a8c89988745b1d9d77ab20a6d130b5cb61e8059009e88cd0209e0d1d4be27ba547ea32d51018f4d703a4888be6b077fe0091d64129a484e072adc4ed03bc529b5d6e723e7b13c95635285188127c5283ab050311c580afc2109036b879305555134605d9814b5f97118adf11688772b5011ed92ddee29a722ac269bd8610e583d08282359e3bf11049c87953ef4dd838bfc7bae24e73bcd0e5d864990ef62e355d0845a2c68f2b01675acad28ee294eb3b1a56f3283e6de45dd4c401dde567571de0ebd3db26de12be2e115566205c9621e2466a8b954832bd4a4c6087a1b2de78eb57e33a6bc57897498e4f09eab90edffffbed461b94d882227feee1c9fb5fb29f766bcd78a4622d4193bf638b02ec20481f3a4f8bb97c4aff3f2bd447c039d3663ef8e5dffeee0aa7e53a03a08ef153d85147d5942888c5ec44e4606fd488ebcdd4bf3969a3bd8ed5e09f49634020933ca29f006a8dd0bf972cba832cc85e4115a614b6fdf4d31efaf01a0613593cb00cb1b73a3a5ce1dd5cf4cb822bb1748f8a3ad8bb76afa0877211a51df89bf5342b71fa1e528c259cc465a1222e765572334d1493f025be1ab8bfa60f1a7468a71a394e807225ab177b6cb0e080f7ec4419b2b3e2b9c09c6325422a1d4613583a310099c09211a5340838f6c7e3f1b448d3eef8c2f34d14852a9f77cd0f790c70ca86f66c5dfa9890c17ddfb31a8f9f2828712b6dc0706ea0e8fd56260d42936b085606bc400c20b02e5323701e28028faa6705741f8af6195baeb603b6f174ac3d0dbe583a392bcb746c850716f539b130c4067f29b5dcb8d9da2f78201eb1263150127c5e82c078e3bdc017bb8b2e545da42d3b5a37cf29174e723604e1e7cef99156aa9a24168a5ab91189d01483b0983300245456e6a4d1df07220126ca9129a8efd137f553493187ef73aa19217699fad7692cb533b0ef33d783442b4249bb40b53221d407c39b0bc19e1f10b2d001aed148411379876514438662ae5b24d4108dd391f9cdd702a1f3ea7d44eeb0e22aab692eaadb62ff41c408f680481786caaa30702bb3c3f12ab9a57005baf36bf71ef24df7a2f599768ead937a7f69f1f393abc2400811acb1e82232412398048d911c0406571e63a4dd91ef7284eefe7f4c87359087117c55201c9e7c885f2b9a94a545b6a629ee6e74d30d4eed5c0c904e4780230b5255bff38d0b907293d37ab8e2819d8f1670ec99429ed1380f095b586db5b9a4cacd2e7ce401470b577f67c19f12ae18945062e49c51ac4a069213b0d22c8f5611830d35b91887a387e697b92e84b1387eb7436abee06940633f5d097514c8e93cf5e85f1c634f94930d3ca0f8ce76d179bea1286d0a1bd0a9fb611a8a87687f347144a68967be0f3e07b1899829d296d9d184e532da2be9b5762fc5c7167b4c145c150e31c75b7d59b23172d187f8cd73f3405c54bdfa0eb3c1e10117d0a39c76f5c51d2ab054027940e940351290ebd3eed5a6536179c3014bc056e9b5739ca21ec8881a8e9be114ead8607c231de73266366668821daa927b0602a0e3152c6056013e0eb93edb1d8792aaa4c69889150f20af0e315f0282156ced62979e171e487b599e84121169817f572266728b85500083462fe00cb4a49479ace0bb2c89198248004aedb8cc1da2eb70ef7555b4f2d584213443f0fc5d8844fa00f445cbf9ab570076f2000a8ac6850792122f7f1b14edd455a53293e91c364e2da02de937326738491321cf37ed1db8411c04efbdf42c0c7f420a523863cf07ec43f2b03cd98ccc3120d0ba7cc4051a2859ec667d8fa7f1833e43085fd7e8b052ebcf99c1141b610058d5e321313faf83817856f0a5051859eab4c762c40a23f5f4ec797842c7e45c49a660711ac8ce1ceb37a4909ee7a6dd8c760eecbe0b1ca9b0367c0ca3c10c17a2a79bb8dbd59edc805dcbe26758cf05c54c2b720676f8eeed1f1066ff8cc6300ea581b7efb71f812f14019e6b7bf676f56bba43ee8ec66df9eb9ce0848e5db167a0e465816455f4618acbdf96cc3c847cde5fc1a8ada8e6b45e631e0fc7d7cf94d33e32f6ce51d93d88218c8875268ebfcd0b2bcadbe152fce1f7b9f93a3794e6f31e18ddcaa6070cde02593d574e12098a0d5dec2104bd32bd4a6c641c1a1107bd8472d2600f43ddfcb890a820ecbca7259f324b126260fc15248909ac690dba9d1ef3cb15a48f361193baa9ff2a27247d53ac8c25bd4739e1bb8fbb4b97d95a7ec4b2cdd3baea417ec02fe0ab3c3e5a3fb014a3546232318907c58235520a0745f314f12bb048c23110b3bfaf2584ed0da2ce71d8a361daf9689f7f8673034617ba6d3bcda3fbd6684a11f105d436c5a176a6107ec974e496840d83e9a481a7a2a76703cf52bd359f98df8d7feaf4d06111b46e5fa1820bbab3af416b590d95257f1c19e7adfb6180e731ba5df60073086cb5eb0d945c01792b1cb3590696c4a489ba4d8f4e6e00f04a1df1882201ac3801bddc4adc62deda6f6978631f9f84c680477e4bea80862dfbf2aa5c83c3245c6617a67367dc1c2f9dc64693276565a1e2ab64afdf4bd299b350fafc1e66aab68640dbaf77359515839613b5dfd57133e1ada5c1010aa8c24b084486f8103c1b9253c324d2c2434ef455a6f31a228f067d6b1c985c23a29824d348dd0da6f114a41477971452b115dfd2e7de544abb40f92c658c516bf6791f7bded223ff99c75bfd3b9de101b9227a71c3951643c6006a84147116c8c9632d6ffffcb310d340316b25d6e9c6771f0316f89d6e1b984a92fd671bf1b5204a0f10158e712f2fd5fc4467964bfa102eaafe3a8fefd35918145abd073d1b0f1aa4d6d65c4594aae0ff125bc9e3bff4dd59371b8c401e6083a0fe8e335bef96e1ecd9be7d3132f9054cfd3ccc507127881450489773f12e746dbb1dd5c152a3c09b8f3113938e05d7eb7f03c550c2ef196c799f10978fe320e095a4caf84eec65e2cc1c3cd9bd0d07d7d507c1e16234b34215701d5c60a24a851e584cb4161cd3eadad885fa30a141a023729f621299cdd80c2416e8323eefaf122bfc41cc9098e8a6585fb7420fb829aa3ee0e3332560f3e57ac31d26ff349acaba6dfbaab5b9c5f20248d5a7daf268933697cb787a1fea415a59a30982019220a0296bce135df73cb65daf0e03039b9e5d417e59553abe5d1eb9c11bcba9075642084eeb32d2cf582122c00364d3cece31e90211fd0353bc85069ca0dd45e20a0c9a9ef0ab82030b23d74215b59d8bc807b8c5ef34a37c35fef496d32640ff54ac0bea8993b8b9bef04bcd090d4daf3c154d7ee0dd783a0559fe33b4a8464a853afa0e222a37139e0eb6655e307447b59833536967c6dcf48afd9ef1828f8d185d173f546742abb4f02ee8de6e1377474ae8c3557e1aec4fe97a8777e60dcb109c31aa257742276b75fc508e22e53e4b2abbc0f0fce14a42997d08201adfe051e0fc146cbc5f4d232d26eef64e2cf337a2f7643d34963056e57c968a490aca5ba7cf24297bf0028fee7cbe0db24547bd0296c5107c734db5dc8f31f809e0f7503579b832865c32041c7259900dcbf8a10c31e5ecaa58bbe5ac006a0d01b010c598273539d44052d23b3100f3209f0e8338beb5869e7edc60220136af86675da1587c95cdeba51990b1b9d36d23f85a8fbabc0418414b982c91f6689fe41ddf3fd7156307279ebaacb623ce59a5c54180f312ff0f4af2307146c58090a554f2a7d4d618358c9afcbf0e5ad73b540c198e0fe962428ad6f899e8239b841f0ada88e213a955baa38760eb26c9aab13ba841712956c6ff7ab307f8844d2f3ff169b729782205412b25dc2e9445a049d78854c8ee8691e25210b1ec42a382c8f858cb4e83ffe80346441079a23a54302d975ec988aad437925ea399bd0d4f4be4e896f3c7ec70a2e0a092da52fe43351429d59d0982fc7a72ddff202560958f59ca66f9c23031cca0d0f35cd2f24051c160a0d38e4d14658461378306919490927f40daf73f76f228e1cc06f47ac97ef53f3e0c0fa75ddb40d6e0adf147b09f1ffe7860d10a54f91b0b32135b8ff5666bdd73b2832eb9f0fd3c3f441284a8974ef8474c1c7aef773a71617207db9e8651290f7d2b558933cd6070b8866560a82d43d6085370e58d069a88c1b705e41fda715c5de3d3ac0e31ac1706f4e5266b3719f1fd9e196ead2d4a109980812864bc7042c7585078a529313b564568e40c0d24e25d942bba6dede0f69506fd43bfeff359e16b4c73a63a21161c7bf53c527c6e1418cddc8a5393e55e860f436038ddd63b25781a438b5b989175735f726ef65c2919634104b078930fcd79fa5de01632d696918479a7df63b6253f94a2185077b42101028aa72a7b2974c19d0ac76deed13a24263731d358f76b119ef9cb79e2ef04a10e047f2ff5639f4e2d2e19eaca271e0bcd24a768c9035a4802ba6a670169b2cf1cacd2170c6bd8778dc1b2d95485056f0db2d67375b501b00c30f80584cc87bfa01c21a61acc222b9a37416bfd4c4a62ec02ec5b371268737aa96266ef439d0ed11a287a0863894f7baff05a3af8c43c98cbf7372c66f8109698086b1e33c70db4efe44d053592a8a8fbe8b46ed135521c9ec86181169313fe17255a1959aba3f5fc92a267df10fc85ab080f115ca3a8a80810b3940a947035c7edd8b131bc32665814814a73f7fd7c5a72e163d2a21e30b174a70dc310bef92e8d1b64b93aa4be73ed3cec1438205cecc18149590c7bc2030c681e47ba6b35001c273c533e3b1ba2c8ac531a3563f3a31e0750998319c3d8c33c90ccbff092b892d0c50cdf3ac60a4dfcf6d29ddf4a9297fa303041fd65ed9722ec9728edb6ff463ae1b18dcb8fbf37ae5b43412d03710e1321d4ee2ec486817e42c46e2a4d98efbc14c233df4a4266ba551a8d99adc8ec3a02b08cb64d31952c28f6bb2bd1e015c1217fddc5eb21032c2c9f4fc11b49044a0b334762cd9e61fd392d3a9ccb22926230cd41cd68a583656d5e16e33e2fc088001de92281be3bf23f76443138ec4bcaae88c1dc1606cb733e70e41245b7734512dc37d112a6653554015485e675f8cb22bb7314ce2842fd5399d4002da9512d3f1b2c6d277039909ba06eba829fcdff81dceb0381622bfe7e0b1fa54e9300c1d40d7c43827b743dc60f59b64096283ab859a255743a12d11abb1ab338f8148993cdd08b0f3a55e64ef41129b67de6ff1470ea87b80e420c5580baba35d8ec13dbe9b2f5ecb4b1e0c6a8d3fc01614f26194b321b361b125a078b5dbb32d2610386a108b5899ce2e660b19261aa6dfe506808ff415fccc7112294cbf08133cbc36fe4ab2366bb2e51c51001de1c3f849cbb9f297172c62af206ca6e8405cbd31115a41ea5a681f24d28c74a3b8d364902c4d83faf3254eee66db3af2a3a6d9be8472cc9a6abd3347fa9568279583792079d56011284c33f215a171189e88b8680df42aa4c342b573afc949b6d51c36cb33e73ee84e933957e3eab0b290a61aee3994840fca3db66faa073c1d6bec375da15c629fc09962cb7ca49e1cd494ba55367f623db7879e0dca6a1c32d32d8156d17ec0e23287297f6b6e99fd84b1a53f37c1d680ebefa8b342819292204e6b7d1d7bc7216e7a23e890c6412aa8191b40b582e468ecbf0d7034236a1f78b18c3fa12b740106e1c274321e37b9f04c2f77ba46c8333496e898b84c7407077858810eb34addcaedc9accd5a0694f8e5ed5d4264adb1ffae8fcf11d8c9096a0a78a10c98139d3e563bb2f84d8121e780f2cb099e740fc44eedb40224efb5ca1f8927008ead24b0521f9daa42414531b24a9b4d989adb424f7c075d1bc219094e807e436626ab17c11198d363f6c780d30dfde11eb643a511134469216edb3f4fb03951ff6a749f1660a0d0cd833e895931c1cf448283777f8ae0726a1a41b98d037c9df3d3b21a44652cc88639e3deae6dc2a2add5a58a6dc2668130084c87dd2380f3b38607edd9cc61bbac8b1d2630a667b0b4f7ba69192869506659af33a05ea31f201b9a836d61aa39667f40cf89f064c8a362d9ec78946e8b0fc70abc182f5c4ed364597a59385e13eefdb8981f6bc451d35c05a4d73ff2ae877aa8804d6d9a1300e2a75af62cda3b97517c1f5ef5eba9183bc613695aa2af3e1d04ddabd2339778d75a677870917e7f108bf0b855d39e9d8605b95aeb00f54f03704e6bc07f95f7c0261365e5269e5421071bf125a5a5e17eeb57407e5e70165a36eb0a3e0e58deff89b75e2dc608fec0757523daca3d815a68a0b092e04c08f6e6b413d38ca6b844ff8b2b4518c5b6db538bd0d1c0e86a0a98e2a89a526d5e81784a7039c9902886eac3d66d0411d3c29b2bf5af65d2ec40f1ae76b0798e753ed8575400aa1a4f311c864c8a0d704512fdb8cf8f07ca53a35197287e5ac04523bb2dd82e56abf53de474fa12183ea878e7be0ca847c47b4e5b89a03fc8e84adf29a752fadc33c855c5cfe17184d0b5fcaa42778da632738d5b2d4d03c3f15f44f1c639de4415e69979bb208b102cb70339275d4a53e1298207eeba7f51019eaf2134401f470d0eff44f0b37daedde3fcc63eaf3725a09060085a36dbe943705287b28a406d654c10eb2f54be6ec21bb9d3dc6d9bd470b60ebc888c066d48ce2c0057c79d4135975abb070e42c9e5e2794d4e0efaf10a9c2e566f1ec4a0b4562631ccddcd80768d66d6b27f8e33a5434e6a81417168f1e041023e79c0bc8e26c67c64c304d9d240ea2a115fe8327113afd37f247382f59cbb6ec5dc9f1c9c79d3fbf226f096c072132870d59e8e266428ad98baa3b04c0942abe64999dc768da41fe87e45df464a9b2c7199b12c07ac6cbc2a461a9d42205cc086ce8b587a555ccc0008a4d0bdae34a1580424aab2d0364b6ec858a1856f3b4736404ddd4e90530c2f3335842cd9484143c4cef3f6a90066283468a23717b848a7213482bf5159a28d4947ba6435f56402185ca5e8ca5fb5ed22890ce052f88b500133ddf419f9f5c206f3f5cb41604c60df9460e6ab8e66be8923e90c52b70b2fcc0bbc2d3453f3fbeb9b2a3bb8756846ebaa62e4782e04ddc6cc61850c8ae8416258e4d1f55344422e967467c064e8b702b80f532d36c902e4a0f8e8667ac039d61ba86282fa8ed04af4b10de86643601aac1e77c450793c18e97e0913de08aa131e3e32f5a23c17fc96cc51d43c0b1b735ac4ffd75ee1ea4383c47e0ea4122bea8130ba868488842ad4bb7ed4a67103c7d359f0dd82168e27dbdbf501e4b04600410ddd0d20955dbda259380b4bc5fcd464b9658b4b5f0b3690181225bac5be818adbc961c00a4d18f40a178acda1ddb5f5f7bf95c5cd99871b8feac827abe37f9e3085d580db0caec296e5da5071853daacea299a412513a462fc8d0323934dc09a07ae3a9be02eee5233f7596e28e4e17a3b094e83ad672b3d001258ba3b5ca0df08525f10d20921e6761924a4b25ee117012149094ec307b36a833283734abe029adaf5b8405d6b38da3629f9c55ce67e6a6174ddde5f8366980549bf5844b405206151531240e3e0954b97e609c8a7f2b25f2f2c9f4a6927fb9042eea6cdcb6e3cff99223ba855a47c417b0baf89a0289576ff5859df21fbb8bc831df189acf3f4cc2068ef5147232ebf2a8939d1f490c6a7921591ec4db5e7872d0b2916258bb753b41c0580b13edf9ef32f90b02c8b1f671e6861e85f3e0fd0c187a4a12eb37b23ed45ea26867011398eaa17928a31ce6a696230645250a4c2f423a9c953615671d1e88262b725f65aaed63b349e097c292459e2dbabf7043c45b82a78851db38d73a4c5558979c0f66112b4fc45a0c7b696dfe97399fa0a32eb68f68405c213a42c3a259ce85fe8275728ef8b25bb2d1101a55ce6798ea686b57db1e929be66befd0576e75e2c66a3918b502065d280068a84db3ce172c1b1c2541c71d613c99996f5e055898e0f8c9979b1c5dbb291368b9c97b2412487e8e8ecd969eb71a69ccc4729319516a8c4b59536c34a5738ea38828fac7fe34c4b35ea67075e3682914d60d16ed9a882e80c15982a392418976fcb3263b042262ae0a896042c499f1ab1c7861c1a1e30b5b0689e0cc78cdf27ba7fd0695e3721257caa5354cca72c7c9754bc0ef339a85201f1bdf273ad2a6b7137145d99579d6648546252127dbaf1b0c60552c5469f51e7ffd661ccdc1e7fdb1ef16b97f2ba6c5c834ced79e14b1829fbfc04e6824701aefa87a7724ecb83e6a52b821c0c5bf8817a77f09843b7fff9aaeee41c7c9656638d412c6bcb1364b0a3c467a773371a6839db1d4936578ce265ad3d9e184e57fb3d796ff2a6c74181df08e1935d4914381a43111a34eed266548b58a29a42cf98fa7295cb0f939af96014041327405881c3c88346dc9e7428e4d4fd03e77eff7f5f31959eff5b7bf261da7f5eca26d68e43198b8368c6f27ce44e2aef25e60c393df13780e310c52ff93c77cbe69b997d52996723793c2d0382178359358cb98d489b237fa340a14e5898ddc72dcdb007465527310707328281bb50e7b5d326332a1a7daa9b9e1a7e3dce13bf03032113f8326cc991c8701268dee1574ea80585aa565edf49bf028e3be29bdade401bf9890ce3975c8bbc6e41b50b65bd8be9d2791b34c0884578c1051d50861d5a22057ad43b35762224664784813738cbbda3a5b4567e5d64316a67fada093daa8b134bd793e3c2ff491922d2d4503ffed5622375d8528715cc8a9cfc75f73392da3c94300d5619b4afe24dac208aa4485e37bb165c291c533c59e8eb20355464c08062469b1842010a5092537d8c066810f9385e74989c384fca51710d4893ec8e62f22c331711a15eb30f749ef3e75fb0303580512bdcefbb0d4aaa0b36092788b80c369310485779b164c88dda72d73481b4a7e688596c6a5725117c008911d7e05a139918709ee1fcfdf1b5e85093bf2f9632e4cf0caecfb6ea13029d195144d18bd26ecb007517ec6fc099735b554ab853256357d28d479c26b9c058a326e9aa1522db965c809910998e68127c5d94c15d2c12a91d522cd928b2668b47e4dc2109251c6a177a37b468e599605b9315f831bd4d3885eca2eb22dcfe750d53308ca80b4eb8a99e15ef1dc334ffedeeb66d2f69078c4df9d86cda9866ab7c602076111a62028f09ecfcc34e6945c05e1f458d9e955ea9ceb0155e014c64eb1ed7a0c39e52a9876b90a60ab8d402432195488ceb0f58609b3efae6001309186ab97c94653ffe28cdc027e8ec841f8de902f76e3ab382f685b1d24892bbe79b48627e12a174056582b1153f69433011f61abaf5ec36a5238ad7198cf2527f1b27b27d0155cdb12f4dccf05d256cce7facc58398d8ea5738a5b80050e2828b66946e34c2db2ae40b72c9cd6d08e6b1157140aea15fae97a7f40e85bab7814d82e2d02a767a3a9791259ed20994f46657fba1af839029a4555e9d19db2f2abf4512742903cb620257d7cc063dedc98b08300243ba872ec2f63241e59eed000250b7773b12501f7e9f019347fb382e7863bdc5005fc496c2e72af34d726949c549409d0018c044fe40e983cf2440ef265bc8bf129d427df7f40b617c97ddd49f833736edbf9069a2690300c4852475b7d7823b7f907e6a4dda07c539b55782c3de81eb7731d8bcae67f93c26c53ead1a08b2f2e66beb24983fd529e95fdcf6b18ff836370ffe14148ee0bc90074150797b00c9074cb663412cdeb5f0c7039138569b0d65d21c0e2950965e1704affa1fffb664a2c079fb8773e6e043a4efd8284cefa0d430e23f53835f7bd45a5d94a995e0378bb52f7857a977655a9b30eff6ca5caecc84750b73b53dcbbc51817bc47b768579aea12be903cafbda4f921421c58af787958fb193ae318db34febbeea56955c3fde03942451145c10745e0f0fd1f56815498d8e89edbec9737f02165abbfe0def474cedc58c30f57a2b77ce8a58549f45e5f41db071aa2da0248e8a212bf23cb167107f8bd1f3e6afa28dba89bff0c305a97bd0ac588e14b15de8c66d57a2540d7a0f08ada9fc1e75d602407749f366673fb4e574dca04eb973f31f71d8d123f176055a2f122870afcd1a7beb0e17fad12c21c23dc5c41b62b060fa4a2f2b6ea74423c4d275289de43327cb9cfde67f8830462f4bb0cc61fa194c4df75aea62de04a09342fa16f8933e66eb64d3e5915d7079d5a93d4b4d19f49ba84a39144f94c88e138743c651a568aa459abdec76fb0f7fcb101323e5e7a052b97c026cc8d1e2e9c3aa0a516e34004e60a0fae475fa841ea0557a5194719445a28da4580c6910406ea54ab1580ab8a9cbb9fd35fa5b3f1284acf34c54b17a80b02e7a19b8c3a9a855d6c2d70c538c82d0dfa9347d36e0229b2776c1c8270a3d48114ca269241e7adf10d56323eef87c595439c39d2e814a856d7c40ab00ebeca0e25e679fc474fc9942d9987495e84da7f2d3e1a2089716b542ac5d513b00ba4a7de1bd83abb2738514379263513a41354fd0c3f0fb0c0fef72c20564cc35e73e3d89b6f9f3faaa11d34835e47233f28b0f28a6f363304dbdc52d1046c3c027a5179475d300c526e0e49f7a2e0b9f67126cb6366d3fcd0d859417cf36d175dda8850f02f71d9dc7b7c9388ca44b084ee00186cb2f9b9b95db74716ec51923f8b976c5d1498f0ffb87e3dd6f53e194f58a478fd2144b586a0f5d226a14d6492520658043b045f04a1c558f012c682f2075576868dac9a2b445ddda7d7eb367327bde654aa5fd9601886b5da05a78dbb330d0771f4271b26ec5565f2ae45659460b331618c5b2d844ca89de7894f7c629ce3c427c6f8c4273e63f567dc75bf6a44b61e1a7bddd782c6d7eb6e749e479224799e380837d6adf58f860e415114869292bb77f8c50b25f145fd497910c2720dfbbd4dedcd005af2a76a01bdc9d96d136dbfc33128f9868184654bdc1c5ff1d66497de8e0c10a2bd8d77ad15e337eb9247a34d7d63f32d669d70a9d72ab0076dda8dbf831bb4696b35f1f34fdd4429d8a624c6d2b4310c81c25784086295eb88c6a50186baba34019d7202267cd0051f070c2c2b2c3b4087b3909064f4d6d10c10a2bf1d963b20e4165ece9d3358eeb45ab42acb6d65e103389202356d131a34bccf66a41a52c6fa83f4eb656baa57ad56c3ba89711c47258def0a14c75014c57114c5704489e328aec0a90c0e9784839224c4152a35ae0ed2e7429a739ad3a04c25e72b9f7e9a739a5329dabc29ce11a92ede8811fa4a9bc8484992333282be75e14468285367e57cc6ebaa3e5d4ec7ac698a747d447059d77c0d5d1f1aafdc2bf7cae582ea0a16fefad7cb4a2dc56bf053104de92d4d797c9b032adafa0b2b23e807c6d89b82fb92732af6bc0e2aeb7e8e072c085dd767adb5eefe223d2344bcc85718ae560ff47d40de1210d291b640e12c35c3d90dcfd2a514cfbeeffbc21998e2e0051dce66e12c5c59a08236bdd44b3d674d92ee4da94db9f80699dc437d32ff66dfa941150d32951aa4408bd7c379376735c1b38dae5484b3b0289c814956eeeea47ed27bf2520d9ee80a0399eeca4b1b80843641a65003283394d44f7ae97f78761d03c1b359d01210500740402820a099fb545812cd08ad0979291a6d697785673568f1c7afddd528520199aecb96287cd0387c68d36de9f7fe5fb9f33d3bfe757ceba5decdd66ecde8f260eb8fefd8a6073a190df906ed848c22fb61df0763d7c90c4c3990e199bbcdb2c0e4cce615e1a9a0ae3c242aeb7aa9d7848f784960d41bc2f69d1e9ed9f00ccf6c4269da4288674c092e90d92b550c691eb112b85c9f199765bf9379eeda36b94f0d9725a9eefe7d200882e0d7e45452586b5bdcc8489dc3ae9bb5f679a4f39ca29873e6c93c9927d3dc878727f3649e269eebcab59c71c7d32366d44386a246624331b4c7c8537f52f7864f9a149c275917b9969bbc9cee7cdbf72dd8a1cd4cdb395dbaaebac307339756ab55b672122dd3a268bba5c4d04049b3ee2dc9a3b951a639eb02a9d195e631a1d1ac4743b14d8fd6c4a4fae4ecd1322da5c10e574b5d71ffbab247fb92d06848349a5176a38c9493682d54aeb56ca325b5baaecbb44c13693ab9304e4e0840c93879c17dc1e1703c381e1c0f0f0f8e07c7c383c3d59f0678b7a51bee865bda4bd795ffdeaecbf2d8f72b4ee79e704dd8087cc3370cb6896f0ef0ff56162c42d7e5b7f486bb31e1b82ce1dc1d1481b8b7eb7685d9eae78e4842a2a3b98c958c9b1baa5e8a14368aa56d499be0681e086064d4156e0218bd3e76859cabeeba6b0a03936c09b5494ad66653ecaed3051ed92bd8e688665a126a64adb5e7064cad1d103488edee7d2accee0b86d9f893b0751c1bab70e8ba42dc3a5af47b0e0ad45871a1c31e7102ac4a6ddc669ba0eb36dd957d26262e5cac63d9d6ff2a559fab5459d5be91118de6fe1758d9bd66dccc96f9ec8c5df77870af9584da732b10f8d57d8c5499e0ac1e7fb3e7db5f2acecbcefa41d7c02d4b82df4f05213934e493d7ef3786650b92bc4a5d18c2004194073428b9e0f3c03004c50e65afcb5aeb210c3105e617772563866db5c29ba1e4d09ce7799ee799b3d6ff674bafaa4daf76366eb5562b922c81e077a3fa51798e8a75fcabed45758d6e83ea576b6dfbca66674c6569a28d9bbb3933b96aa69a31f35225c0086ddedccedf35d7655aa48d93ecd363b9a79bab2b5cdc3895c5f5b9697248b9ec030e8f5b6d179c37a713c67adfe775ddf7753797d363c46f48abb55afd6b1242d6904ee96cf1fb40b0c79a7c3f8ba0a63a925882918014b3042ce7d124d765547fbafaf3dbce2c4631ba3da6a6a4bbc17dd1da44f03e4c717696cd417a9b8f8d9ec430043f46187e0e55de5b6bbb2ed27bfc44a74ad32e794d77c5e4e192b874a93e5e158c26613409a3491845eb0a4fe98c466150045b2b6bb64918c5349c84516c943f700caa01ee08d8fce1a24f8591548c31c6b84811c61917e122149e9e3ccf4351013c0122bae74884654bb12ceee77d67d313ad25cd7cac30da34d64d0e9bcb91a62ba43eac128eab5245ca87745798c914278369dee4399933e16830ea4635a604ce4dea381c4e64b34202850e0a7c5938487c514433a53e7c7ff3d5814a8e235cd787aa3fa23d92d52ca9d4bb8a03f05f20f8166c939c5d99b32e0850b8f145d7bbca317ddbb7a1d6392a152d201933ea0afb37e8854c86c362c9aa74a444492e4d16135ca958964c099286a9083466da001541a12c97273eeff34e155dd7a938657e00eca88dddcc5a739b91d378c44e051ce9efbd376d8cc757d2ac91cbbfdbb14d9be5b19fcea3aec06757e29bd65a53af1fb89fe70946f170709abe97e63e9986bbce7d9c46cb349a23d59fea48f67d9f9d7585cb1cc90a4e43baacfb596bf23ea1ed9b1789e6b4fa63b743d94ee5ca0270fadb66de9e2ee137ff2255d7c19dd49547a9aceb34b7f90f4daee36ed3c539ede22ed275771a345a0a8db560c61887a14dbd5953b746e14ea92a6c964587650bcc214e7bdbe4c9cdc07c43284e532e890bdea871ae4d6f10e57244e1b7dc7d04dc0faf8df705b741550018e46c2f2d17dba5aeb05e2ccb9eb16330e80dc9cebbba984767a428032e4fe743a92e9bbb2b20d5c73eb99aba929289e8a30dbabca1ebc21dce596b92fc7fbdc23067ad1f872aafd9de3a6ac48bcadc2aeb7ead61cddeea8f113583b964842c89d570a4ba926a99e4208aa2d8a1bca8aef0197270178a6235b8bbbbbb18e2a5eb32b112c6e228fb58a9c86bd78510c51d517477c758dcdddd5d0cab2eab2eb5d65a6badf5de7b2d6b48d712df55ed965875597561e5f074c64fa1a396eed8165555a3112766db06a1ab162762bb3eb8ab963871b699fd51bb6a8993db29702def5b3632179e78ba917323278705de0eb8c9f9e0c64d9bd60ee9b0f5515d7c30e0802486bb45311613c5a19838248a437628271345992833f56ef1e92540106cc5a0c40c0c688f1de2c0704cd17283127088d8e1c4037657085373e188971792bec0469072844a910e29fc0003ec82f9836e188220d8fd7042c00e5eae173372ca72040a558429026dfb228df60f7f045c8e0413846a2c111a31c69e8259ffde7cd407230c0f83f9bdf203dbd10073f962460d21a5efadb5d6dd53a131e810144551144573d69a24572b8bb6ba16a98db695a2ff7bfbf494049582e4f5fb3e6cc1361f158269b79ddd150044b82f84da8c5038f77c42dd73f77c5c1ac5ff97adb7fc6028a62eaca6d801a1e6b6d70400f9255c2ce9ee1d5b777fbd2cd8c6dd499204a3c14dba4febb2eeb73ec8d92d03cca05598d5b65b4617e70f04412ddaac37af844bc3ac4b9c6fcaa8c91ff8e50c86450cc5f9116377b7f7ca1ce3af07fd3b0553c814e1e688d316d87542f2638a1716ae2801bb5f73ab455543c3c173acd539188fa37b5efe9856d8e66519e79637a9c93433628436a16238826268d1157a551ca8277ca06ed09a2124e3aed071e5e56a44c7f7f61dcb746777623c5e1f2c735637b42f511ef54d81607654042e2ce7f58f9fd22abfa976744abfed7ca9d4a348e9681fd845b1b4228d31f5398ff29bb3707efb72543b34743ee77572ca9deff597f339a9ef13bfb7fb1b55155661226acce37986170512162bfb6c48b5d49be7fc8207ed75190c43500c41300c730ec1303b19dd92c4d02a60410b9c15702a13a686d1edc8880a1426b71ae9d3678218eecbe79d5527e40f3d0327f48fde005d531e3110cc1f80a8cf2ad3ee2ca2f88a82a1f341b7deb67942eaf3778f4215a4a37a31e3aeece7a884eeea86510eb0a5992aff7bfff0833cab706c57edf1057ff37b5409823baac4dc4343282c6b20e9d5df950b202910ea5d816069e26dbb6d8effa110692a24948e7a1cd331f571f43caf83409a7ab09fce0e5230df6380de87df93b1831f972f6628c180e1443fc65dd7d554280d89887ab5fad7dadd6dba4cc00f7ddff2f810aefe952655f75e152d9b0cb087b6208f3abe16e4482cc638085d2d8b6fca166d79ea8f0fa5f8192d8ba3f3f4188046bb7b59e3ae5ae579566791607948a0fad8142aeb4c6d3def2acb1a016c93e7f318d2ac12f12588ede21d3d5f10e068b3a699c61afb747a9f8a54922dd36ab5b46d5d8d3156d25729d5a2c7bf67030c76eda08a67f152c507dd6bb72d7b723d0a10d2e34c119b12381902ab6e9e98c858396570d30446812637ec00c28394a11b88b2b461d24588344a5b60d7b6f0d78a34ba9aadd64e92be28771743c345c927daac351bea4fdd3fae23b4a31082269c4dc7be641b8d1fb53bffeec3de397eb5361b27922efadaa0bab0a76571bfc31f996d55d8b36c71572a5ca818b788511c1d0ac65dd2fe5d69012cdabf62bf2174efbdd7617b9ea7587b6c8faddfb3f218ced575b951d1f6efb92eab623b46c1c0dfa9c2d7766b94d8a9f491ee6274a5e7d214dad9430180143a2f8ea8ffc0ef54666be77b14ffbda7e269818326772090f3a9a791f3299dcff9afa4917a14a508f4a7fe1d558ea58eaa0bf21c5525afebe3b92eac3ae17b0cbe7f7967958dd6feca9bafcb7bf7d7d795af4f86e5cfdba2bc9cdd3f3346dd27d8b8ff3dfeafdcc0cdbb537d09e3be9727d4da17e5ab843668c139eec49774336a01d835fd21cb9133202bcbfa0465dc65cf0b40f27c0ff93c35277e553264d0f62ec92f64cc209fccbba63f62643e12c96dc3cf4f84067dc2af713676181dc0e709c306c1f77663540816983654e1cbba18ecd0f6af971874d1d653f9bdbc608b0eeb9bed7dd0b57546165db3d470db350b152314f6bf4049dfb77ff1e7ebf2b2c35ee7295b89d0f6ef7f9eae22d61d67012dd85ab6f0a2f1d79fea5fbd565ceb180b76c9990184be28180b38a2f1ae299111dbfc8ac3edb542b2116bcf9b58d583b19522d61e5363f7fa9f8169a3fe5dd50fc0d252fdfb7705ebaab59ca2471289c69eead49e39ea8898f01c7887205100d126e3ce73ef6bbd3620c4931b587893e3852655054852d4cc5600a5c8c8d119ef680d02c01d6ec460650997219c9c3019b94049a18527a9122b3ed83024f481684c90d6beb745a40348542352b2c75d5322226ef08bd5563f6b1a6d62990cdd18e73e49b5cbaa1b3f96b94f8561fc26cee1af607097557710981b4e370e0293bec0d82eab6eb335db18cb5e95651f3f49eae8e024b14d545760fca3b2f01bd9180bd91863cb84ec5e77f7fbe8b667b4cde9186374aded1cdbc4b28ddf653334464b32bdb6b1aca64a6afb93794ee0efb6f55d77ad659057fcb5c618a3bfc26e6966bded7f41c468fffbf863306970d79428b6f1d71e6ced2daafdb62f0c248536b4f3878f990c30fb040f5acec86085063137987db2659b7021f66bb6826307cd072a4532e8c8cd90d9d4c0348416324882f460d380111d46cc7005ce953536e230f1440d09071598008452c714b1523b4233c41015ffa100469abc71c18632678c8224d9c2ecc8414b8f255ec854279ca014c9b005dd61a4c6983640a820c5c60091e4a4cd119c2692d0d2820e211c0d41a64c0e9da1e9497dc306cb532e8e106d5290c3b638348db9c579a286851c0e25b9204843868a9096d840a45b96b306323122206c4a224a72484213440d4570100123260ed30c689cc28c6049981c4e3832270b19d0b28492d9d0131f4917898a840b79009a21483625d40b1c383a6e4801491037585ac0809013ecd04397363f5610258a12399c98e488f1003a01ca7106290284480a03d804c78e203daab0c0a689992520937d011f98c47a08a3020f47306b85c80fb9212596a8f005669fb4800433d85025cb16312c60218092214abeb8015205c90738479e4b791589814c8bc8b0efe731c5981211eddf3525d2c40e774d8998d9dd09c4db799e67ad44b6b9dab6b5f3ae28dbaa626de6a1c47b155e7c301c3138d61de6d2b451b1ecef9d00398dda358561cdf6f754f82b4a842a667725c6a0a9f6dcebc4aa4b950ea874ae18e5d4a9010d80800053150000200c088542a150302018134bebf20114000c587a407060409548c4912c48910cc5300cc470880100180008300829c350610789807ba54710d67055a0a2a0a24d6f17f3cf9bc9cd147b19db6b78fd3d5138701b0868dad515c98a150eff147aa5ca8b549a895c5048b933a5a43715687f887807a3ecd4dfbc49c289ff9f31f64d905c2e8adbb18bf7aa55bdf1100e7782096a14fbbc33a1e80e27ccd369aa49b399d83222ae3673679228ad3add83733a9fdcf1718a563c5f58c92db2cc50218c20bea54185ead706025c0967de68492b9211f7b6c8467513440ed7c59dd0d3b484e2f387429c9db7be27cdfda139cddfa1d5c3449523352b0c85a923c4bba63160e1f538d796a56c372739cf2c46613c8d82095165049a21bae577e75cd1e9b57ac8536f111853e6d7e46d88ad7e5c87127241d4ab0a81326c18807d2c1b05324ddc60f80593d42067720c066ccc8b575da8e075dce74c4172443a7a8f7ee5d2d07b6026ca5dd87d460f6189a890806ee7b755e57782c62a43baf5a04a75f1bc06d53da5b2f2f66541bde20c51c5158899b7e0c0b14bcadd258198e26e7d0ceb889ab7d5ca4816cd36596b5e3858700a1b12b66c3bc33a845ed11558a2facd58d7407e0c3ff2217b223952322f87a1a53f9ef7a0607e47ec3a1fa6578ab76f34b004d5588f1fc30ec42c36470be3f1c730bc07ebad59a230961882f96ac7f3f27093e4bec79a0bfbce7f87658b9059aeea97521e578a0d8db744507b6b1643a5ae8f222b7f28896a8d11b4e0b063cd5b92fb70e23116bbd613926e705c3491899c865d816940eae565714ca44602de74c4b3d0a6a963b56bee74be562284d1561810ad20ffa5365e8161d8eaa3714673f902ea00a7ea4fbf03ffeffef83d5f29b7f0126fb4f52ceab4afe4041176740b282945120443c2afd69cafd3d2cdf97bd276c935c144998c844618781a3de46c36ec9bdea238159887202234cd517d28299a52b4ad2c9844e7f3ee534fcbd9dda4c94e151afe552a01aa1d67f7cec618e787c620c2cf45df2e60885536a4a20fb4dd4be7a80aef149e1d2cff777cefc13c683b40a14ca743682779243f648f01d9945efa05b0e57ee5b6e4ef9a4a322d24b882b13d4b3c90a0a2cd0dcd24a5640abaf28b3b01bdaefc4a470c3446a99225d9ecbcf8cc2e64c25ebff7456580df3184e546ddae662d62576e9d8102d2614e7421e8c1eb121251762402723307d2303865ed788b4664cbe754e6e64ce80e9eb85f3ac2f90880649372570d6f783ae045b9fbf08bdc13d75c1316880ebbe60341d57987940218895bc4f1b09159082d19c1f60bd76284f5155e3b88555a0c964dfbb3681344baa51707cc64814ff0f58f98bdedd98e71157cbc909dc104c9f464976af551048e8628b9e49d7d6993be5d952475cd764eabb5aebd933b5c78a336d3da8b4062b5107753d920e8480e8ead32d06c80c6f5db00f2607dfeeeed3f71de5276af3768ae3cc3934af14d523a121fae51d858c42d667c433cff7620451c28a6bbcf302f0ada9104d54983bfb5a5611451854fa9e7cd949e0ac91ce34ea798cd376e35c9c683c55adace958f457040dbd30877470fd423df0e75ef8600dc3da4dfdab8d9fbf41989aa134af4430f9d31b38458954e2ccb2e3dc81ad6b1d156aaa4998b47280628ffd6d245f5d6d976c7d62bb833219210e6c34fc801e75f225690e37c1a385cd0df6d1f719129a79c65e891f4801c6081dfd36d3ecea33c9a3de74b03f7225933c9519e6afa5f90a27f870a5d647dd48e47682eab946025170e1144a3f5f29300f39aaa6749388a7484ef9a5abc71c53d987f0e2bfa9384d730104cfb85d9f41613b3ccb98ff29d9322bd454ead7575dff1cadf9f554eea58d8de8ab48e83d4ee54216ff3036d128b2a550bda2a19782ee0cdc65ed4b0151456223eadff616ea53d4de6bcc244664ee298ca493494b9a71c8da818871d7b3375d6c75152a1b2c647afec8e8dff6aaf8d9af7034f943dc4a605efa6352750851e3e00f3f8475378d7ac547e352fc641b502132aa977a898bfecda79d5c9a4d0f771eca0ee4f489ae7156e8adb184a5b22de59601759b9203087f71e26d107e51b12196881c67eebbe9a3da3554652ea3827108d55f227c2c3e7cc06c89909eaa2a49928369257f3bab9590ef8ba39f7aaf2c135258dbd9bd72743389a74e658b340fcaed63e384d0ff44af7dc6b6863256e9bd743917e175b32317ff6e63f429a30724ddcec735abc31b89f1ef3f98d10b120775c8885e6e7874ac44d97eb03f40d86f6d31d0c3afe4dd84e09013076590cd2e1f7ee284f01c9faaf92a6170e4e1a9100cfb90c5417dc9210db0f1b565be0fa17a2d6a0aba4d0f81772a66bff73b9967f8b982311f7f28632dc02accc5948acb466eea7d172a48885b7321395e10a6ef1ddd0a2b0526ab49960a9762fb754c8ff1aef4753a4486682cd9519e8600830034e8b1d3253ea61403722e9afe6fdad86335aff66ee1935d8e04dd4c7dc5f805f3bc00ed4e9d6a6cfbdf4580caf05f0bb281cf83f6e3fce5d95504442f376fd93774d437a268a3d49fbb81dd797ef54ffcfd0d65df46069c72401667b6943377804a827ae486a3a35ca073adc79f64f59480970893b118c3bca7054706e2c0bf527e89398fb56519677f4b2766ecced5112340eb9e915339a6a3be1a681b1776d260d5658576bc063d54023aac5680afab9c516b16249050a59c23ecea6604b5fd5d93ea6406dc36e05bafee16192125ef355644ac3f5107a3ad94f2669d01a0ed5984654e7da04481964ba5a9ff162b96557afb30a527a9a1cc83c4bd9a8fa22056957ba24aea560efce8cc40ba6c2e8a6f5bb8c509dbdb2871b0fe6d6e52739543dfcbbf1e7943f63ac2aa74b37cc2414a3b716aeb0ad16b77b066194deb5de571b20b61235be9b0788e24cdc6c5d19feb41e72e19bab7a84c9d7e5fd08a9f3a585a93a2169f7c0612eb5be670f22608798d7ec1d388f0ef5a4c421b4ce037635321578df2988eb105c08480452e0d2bd51d6d97f3da155d4b53cd7d6c553049903b85253ea5f8635f11667d18302f624a6c001aa072164ca370402ef5ee0a3671e53f59c627a92198fa9f9bbd20ffd5c4d53dbe0f1d07b76a0afbe770366e8fd126dd6c93dd7dd7ca31e24e6523e2f9437f4a71d1eeb34e2752b589c04b3656be65ced547f76af8c3da6bc8667cbef4c31e3df3217949a594bbe9e7c55260dc33489f10edf5a294b90a799e75be6033959daff278981c4c934b958e5cb9c54e4cf829475358c2caf2b448782e1b0ba3f9e1ff1561855a1cec50a4bf4bd69d5ae0be24ab78c75825b187e922d677ec7c1fbd091310b4d09378a3ccecdef27027077c9fad0640e1baa26508940c328488e1488304c8f73e64984e2da344540e215ef1c8b364aa0af328fbffb6f8ebf4a2179965c435a33304d459af9775afb8fc9b5910ea0f62b547816f106df03c3339e265e4d808864985bdcaa1c603e5ecba0ea9b71031e2889af7ed422a4df665b5340526859be0d7c8db588df8c15b3e6299b43aacd2c16a596bb908c305f1bd0846c66f44ac957fd2fb0adf4ee80a9335d1e849b219b0617cb03160ab22918de93184991a1bad9436cad4651bbcb29d60f5e8e9d52a96f77f68acb0d44ade373c44ae54046b2f099183ba49b78bf7683473d83064d718ff6cd93f5efdcf20da69799c4f769cddd71d5cb7d12f37ead6408167f01482957ab5bd8504ad5e40f07c391c97d420ed09b3092e34334d93ac82f96c295a29010750fb6fc0d16496f528d1ec5ea4c821d8dc357faf58ab4640529af37a01b1fcfa36cbddf0ecac11ebbc1a2cc03688bd2eec800000ec880c3d5e88e46101bb490eab2cef7970b063d6b7be3e16fc498e072f1d25d88d91a426d5f0ac21265f759ac3dbd8b6c37eba7af835ad2bdb8ae6d6207b5bd23e05025a6244b8fb74f53a2a91c670fc2d71bc66e50988159b7021bc66e81bee599e204418211f25a378e47c188a66a47cf1b6eb65d50abadd04cff24ceb44227d3e59afc56a98febc50ed3f61ffe5ed08790f67c64adc1f2524b4b5476535ba25af7c0f3f0540bf75fb96af188cf00ecf3bd43904a4e48286e9e697b9e95d8a1828ff3ff33258efb5d45e06402c82cc6ac1f977d4a47604eed57f4c7044655d8366566634b408de82508034fa9d19722ab1461b998223c0a9d2c76c5c538d698dc0385fe3b2096cf0abf3faba748252aa2cac1587f05285c0981f0d11e6f6fb5c622e8afda608c68126633fd3f64adb031a1a367b19aa20976b3bc1c18d108d6076021aa414007640e67a06bf592bc268d45a1a576c929e5baa29fed6c675b72df80f8e62f2e5ccab5cedb38a802ad3d593c8f5f11c562228c50064086f7387ffa9c22f9e24cd65ae6f9908a492e5bd3f652f9bd65d82fc4fb3a4d30d0478bd2f4cc91bc22d7e8af1eb13a88fde93f1a647b2c8c8bd8767565e6175348a8720e8d5d3e30dc7d791781fd687ff8412b4fad400f606a321a9115f34ebb923d645c4bae02970694e95013700407597f75e0b16a460c0ff4421e5ffb6b8f0309ba90bf78cdf1d0a2fc517b23b45cfc1fde2bc7128266411a16c0bd9a8032c873f8ed7f964c9b53dde4a1f1d4e796a61f411dca0ef9ba4c2876804ee73f397bc56ad6313519fa8400291e8bf42ebf712f5a0ff17aaef5843e5c4a742a7774a11384f8703fa9dbbe4a73adeaf4d77149e62bd2c47de97743963be6194473be9efdb35281bf8b39497e030c4c544844efb9c4d203d906d21cc53c21c5a29a6ff1012cf3032ec6ce25b2d19dd2c1726a9f6b8791c349d0d7e863b62fe32526b829bb8b82d8a6ff1a17152f330d87056029f465666bfde6dc11212cae69a46371a2be3e444a57dc836e0b06751fad26d1bdd0dbf9f7b8cb1b26621f500fc755ee4a1314a44c0405b5400c972ba6187bacefaebee7fb1ca1ce33e2cb72566b2f07b7b84b0a26d47e02d7a8abc40c1925928b531b13a2385ce33a13991d6ea34eba385d35cf8d5b1ddf1a21451b23189b09c0afda35839d2874227487c3ccb9873a7be71bb76d6fd4ff49b561ff58b961a63982aaf8a44b0565bcf834506ee08aa18d1fb6a4cc542cf9915576a136dc4ab1a2e436b8dcd9967e94006e450b875b06fe19db192708ea86705d4a43750791f033520921a04e1952b21086c0bf7fda4f3c2b9aed7d56ba718ecd9232b1ea4f6e4963978087302fedddb43bf50e60a6c2ee5fed7555681c9e5c175db024a1786bb2fdd07110eb2dd45051a911e050464ad5efe798bea4dfa74ad0bc0f2b1f67aa895fb635bb10688c001abfca7534827d9fd5ecd2c2882bd36720111a72a5cda2191714fe3c1cce1a3d9c8822bd5bfac65cf219a2f69a82ca27047e9de980869c31fb439623fcd7d35196d4beff53404ebcb59bf24298e466b4412511624c571e322d07a91699bf432fd1a12a8b284d64f8bcc0f0366a7dccd50946c6d133d7f6e323429ebf21edf3f3614e2cdb851b48cf917f4be5b5bbcf0f2fa21bdde1a637491c981fd9b101c5674347ad087061ecbde9860037a3719d2ff4554059a384d056268b486200166618e372b84008b68ba7384a7448d5ca40d6216ed7d25ef6587243a8d810a87d3b5f7fe66ac856ea13592a781a5ba9d9c91d63f54b1171744420890fcd07ba8921aea4e7d44d51c21bf488203296b31dbc6e5385816abc02773c596b486d9caac7585fc126a49a5a27329de02c196acfa8fac8b5420976d32d5177034a368c4e260053d6339743a5d53d74f47d851b02a1fdab11300681eb5dfd5f2b59f5b1f4bf585e51b318148586ddd5d45d7683199c1e378c1b5ac54203ff2565d045b2b2359b64b5f3f2c94ed2ed6a0197f9b242b7ec0f42ddab5eb48f7568051bd7d06811ff9b63489eee1023801fcccbca751bf29cd569fac8895df24a34048856f3d1adf46229670d57af6f4ee3553f3ff5c5ca90fba6491eb75c254eef0e1e618e583945e64d65123992a5316f5e44b39837361d39ef3add19f6ff32967fb70ecd12f80c3356a5e2c24a62c95875fb10b340196b117b270008125050540e818c2327b819eb26199bf0340d6cc62a6a2cd258f9c387f86040fdbcf673e26837c4e7a3b1d8f7843d573297925013f9c9802f9f3606e32550b4ff4c0a80d902074b70bebe76780d5d7b84cdab28faa0bb30ac35b1f3f74b4723e12e08cd26d510a09f766a36cdbb93518543e97f33b9aa5c03fdc3f0710aef5e4faaa88bdad22b62a6839980962ad047293e609478108b29e51d47773f15c32d455fd53a8384697dca2001902cf1bb891cecaf7ba0b30d9574f63894417d48e805ab74d3beb13cf4041b34ef3efe0f25d6bf823c77b16ac978931bfe0e8ca1246f691f4f8a505eb88a907e61671a23a3cbf41c40ce2caa29e0eb493bf4320aa168a38cd53a2bb92cb921abc25023abe204d5167929aea9417010d8e8931198838eee65691d82bd1504d561f5039c831a2f75d0f4e58a0b3f121fd57f126f9a1275127b6ad3752cd2b339746df0d385d9cc4e9530fd7e632c4b05be6187587abc9cc9197e7aa0b331a93994bf2878685d40cb20d2beff9347ec2066a52bb595ec439ae7ba8f258ebf7204a2f77af75997d8bbfa98575bf5afcf5e9b06fe1eb2da793a9b901c70057ce81877977d54c80172a1e5680a21380aa937a248fc4c63e96075a5d9ecda98196d3312a656b04a83d15cd1746445f3e63ba0928e29a89927d4c964f058cd657ed0561a2121943b9b902f28bd20471119a357a3a989e6f5a1b40eb7faa8d69b9072467e626aea033de5fa6df48c350faf00a8eca8cd5caa7a5625846737186cf2d7a38a701c90ad3bb4c1f6fc63bf3c51d72681e5db79b989b3974319a761dc6e154ba1413c3427b184da19f7c853b6b20dbe16d42168248c33aa35d33b30084e40202b6bc5874c6d0548e990dc23fac51299f121281173d2d100e141caf3e4d459cb8b20e1956fc61f0d469a91ce608764ff1e629f626da5d32ba1792354b16abc4192890fc4b4cc2f157fa583334e23ba59649e2ec814d4cd9ffb163d88d6bced7fa3061487e46ac28f5cae3b7ed3be8e33df371c2a379122f8a4ecb6b942f85dad560e56c5a064ffd9a9bd5e93127a3fc997cbb9356050c9c0b3e461aa1d781351942bd27291f5248bbd3deebd57434ae1a5c49ca415b0282ab55a881aeaa73543a4198fd88e8ee200ef99665170df5580f35cce8d22537c145944d1313ca921febe2161ac96f71fa9a55f20485e6a124a1ffaab7b690ff08496852569f757eb17b04812ccf9509ef09f4603558196c76aeb0fecdb5690d81fcf550bb8faaa6035122ed1725a2af35c474d9518aaf7bb39ae5b10dd21e1fe48bad4f05ce7d4b48497767fe07ba571cc50a79bf14e3848bd159ad96362e8645eecd4ec353a17b7cad852c58d0cb8b914edc21d868300b64ad4cc5aed911e10dad133eb459892eac41b23635af80f73e13caa19e74fd06d3073f969bdc9b22534cb35d9c3896c17632e3457c1b895e99fed3ad489cccdac20422a116bac6462754a8f8d9fcc29a1f70b3bb990ebd2546f7a9c1cfe462c8ee9de304d00c26c52b6f431a271363baf71a6258e10b1370f7c932c86ac8a2cf3cf38f2c475dea8350c069af02e8358fe02432a0ab60dc6a5b1e11663f931f8e41ead14f5f29a2d56b45158329a8651ed750b233c582935ba0ce0ffd9fd6268f92f47ac4170a38166386a0f145ee7a573abda43fbbaf599ff7373903733884aafceaaaddfa2974c2b8d2506601ff8dead9f3d2bfcd4821cc6a9f309c46ea1eb78eb7288ce2c252a25127da7a6dbd71a65101992e89b1048cb2f15e522d68a13f60cc2bd260b09ee77c7206ac9eace3b562e621449e2b4845a17f96a4148c178c2f65b3a47ead7bc24591dcb467717942813fdf79cb4801e8c2cdf4668f106c36fe867020025866e2556633edf611ac19b88f53a7521599cd70f321378fb5d3990aeec572958b1e30c2aad269d638252613712103eb143089246f06c69509484c85af1d621b3bb2bf5d9bf4f3c09966015ca3796b7129b02da4ad8eac3824743a294b2da3f462026ccb747db1242b810450bc03f909ff7fde21c952506892f493bd304e0bae26994119be47443443b71d100a5c04a77109e915248ec8ac72112edc0f9f08813d7825e8603ea7f7903315b27094b936a3b752b30b36b2199f89ae73e981367648590fe1e7c729ddd1882d6976add1b69146946efc8f83ebd65605d4217df7588052ee5e0f67c4fe145a6e718d09871126ee249269dbb79c31541107f1042d50805eb49105dea937031ce3b3972b3f8ec7c553b04bf59d4688aa5839d25326e063c120593cd0e4fed26e2e00547d0469d46ee41eb4037ef10964d1188051358a886c35721f1f30dfe2d4b4c4bacc2d4bbda22cedcd8421a282658c4b9d644895051939b6550221cc63ede42040df507bbd4a93108e92a0be6e870d638ecd2e2c92243b31d9e78c83a6bf0004b978e0ac9f5ebf38cf9afa2ec89a242cc44d7d013ba8e7fd945775ec38f80602ed4b01f7d660dd97bf402e0011d9d69eccb483bb54ecce57c9c22d89da3471c2722f54c3eb6a0d1de9d68b5c073b3d8f86615788b38e7c8d19afade7c2d8e82ac0d1c03ca65802a62cc7e111916f26516dc267e99dd91d6b3baf2acf3d092f94b7a082280132c79a7dd75070649340559d07c073341442953f083b49c9da8210eba869da95e440708a7c76f7ceafabac60b813977e59b07e0450fb36de173ac1977fe0bbfc536052d5511edcb47264208b78913d89e783cbc4a2ad6bfa53f2f073e56b477d79285a7ab514d93fb7090538086385906e45053e7926580a9ae1073ae9852997f9ed3e78b1d03201c844ec10f8c425e738f421ff1f12126a767bb359513066237c7d59fa78a5678735ee8552eb7a2c577627d1e9a102226fec3414e2b25af46e35e3fcce67ade014a7878afdd477a016a03488df35b8a69d19e9a03ac43a38d62ab8b3ebe4ffa0598b1154d1b2a5d63420c62b27f9f319c29e773dde348c3a815ef8fe1c16356b23a91f7c00cd0fdb19dd0d9b46509f827847d5e91750689a0b6a46472849b12cb38a7b846af3f33d6340223c5965badbde24353a68102453e083b4ab095ab6ae5a410c44318564ccfe5b54cf0212eeed28a1fee6bb59d9f0df6367917861a184b83ffa40d74919ce48b156c635030058b702b65e8cd127297dd742e424d380d2da9289cb1540a7f85f2eab17a4ba3613effd76e4ec8937d057f87a2d1f7d51af95263c62ad4dfc0582e06b3ca88e64795ddff961206761d91d81e81cbd78c90b49ac30e94c3c231e2c406a9fc4cc9b8511b8e137c7561611a92a540d21aa5adcf095a5d070f62c708440b786a11d152ee934b4072dd9dfd95ef376b58349a1042e4130cad39e00a2dabbc1b6fd5f4fcb1b83b511c1258a21f1ff46c209345b8d2819fd6963911b8706a8404d794456717c46f9de401de1d928a31b3094f0719e99ada354b8a27fb2101816160444a923fe1cec74eb83c2f4d92b04bed0800a0ccc5c9d4b996f189b88bfff77e2ed0bff9f6358fbc0a5e719932220e7f4170964ac41d69b0128602855b32d89c38c997ba90a6626dec2895f70e8dcc4b9cc3af424ee7b6f03049b88b2115e0940cc6352affe112e9805255cd73aa7046fb166864cb4a5bc39e1472008bf2cdfa370e224aa1ce19a3adef5a5111be2ed9664454a431b10b6795d80ca92a68dd092065fea2bb1552e3c0b7a26a335719c5b396a46decd5d18ead3afd380d4b962f510ea57adb13e78b474157d0da48bac48356badb3e0b883ba89b495f2bd5081758fe09df89e9145a6f7f42018cacd246e870177536035992738fd63df5a97011970e2165908a88375b9d41c2047b40aaeae86018076cd2c4626368dac13890fc0274b9dc2368f9532676f85174d6ad1cea3f402294aded371e438e8cf5bb78bb13cce60eacfdfb60812a9f01c786feea6981b6f8901461efbdfaa18a7f1ee7792405e2179770cc6ddb6f105336ea139e493850483b1a368695f595a5ea41453367925a1cccddf2ee2549b97ce61d104371b82ea0c7f998a75a3a502836892d8a4d2fcb240fd7f214925056d1220d5d141d34b6343c04c1d0d55265c1eab7063e7f28420d811c0a83aaed391cf2977daa1e318e1e16b40fbb1e0d18d8eebbc56954f637e0c3f09e820b91209eca4a8c8992b5075d296ba59329c6650ccb771995c2b1f39a7a60c334b366cbcc29b5aa7dc9c848fa33af3da550e058a70fc9fd344096b63e3014af00bb409c14148639f67a0477d6b8c7bc1d0ec03d36d5f8d1ee8eb9778ed3155217885ef3c29a0d074a0d0426c7e1897a5ddf83d5bc347083210db8fe5f420e1ce945508cb8aaf1fc11a6cd2a34e70b24d0315775fecd3cf3310eacd6a239bb1602718f7f7884c5549223507b8af8160a682c08e4972da2c1bff914e1bec0951215c4073837a55f9286f95105d9658a05469431f3d0af82c0b5fc8829155a526b4abd4ef1a29b462b6e3b5d49eebd51233bfb027cc628a969a60540a52da9a0374b6719d386dc8896eb18d19e60273cc051ad8a41592ee299e6ddd05f1b882a7a3b611689739dcbf5c78b4b3bc448d68cafc2cd88766ec0ee80545f9c09eb80656ed4d72dfd3a3c8bcaa799ee24fb5c8cc8280d9cbfdd0b7e788d251872e924d6599b5edddb5c8a813f7411d71eb5d29560d57ecea4d09f3c2be88cfbfc49cc0d9db5fb59557de34c8261fbc67ee1e0bd12cc78c10a903f30e5fc4179c45bcf590ab925080ad5b42c278c799ebbc3d9bc4e3da608bd4c8440155d650a2a8fd18d832a532b667ea461f0d4aeedffee6199c108d8e58be1fa7284d3e47cd1cd74ade8e6e2011ed4be754e99de0ce0f4c557508a3b4710109bc108c284201e2473c93aa34b5c6746a63353117baa9a6df3a896b83b8434f22dbcd1317dbba679b5a7e2c478b679150de101171be357f38dcce178c7f9c0d27fb2f9c930417c014b0a6c7c81cc2783b73cc14ccb94ca9a29f8a362344b2a1e3c0a14e29fbd529e0bc192bc58f933e5345358a820398432799c9c661a4195dfafc7d759562a75ab1e5ac1132f61c8e892d99cac614ca6de3c4db6f9022808b26e93b0248ab4e7ee7932299154bfc3a84a7924b63c69ddf90220024b3d1c02ed679de1e7a5a36dcf0d89784000ce61c9db6a9d5cc2bd2a1eb84f8f631b30ffc0cd1776db399a5387ad3845b975b06332ec2959fd1e134b27ec2a002db7aafec4c2a5c1997ee61c8042d3d7538414d8d376a0d38c0a297b2f3f7bfa4d1de85c084f7b8d5daff6de8f38a9a32517b6e74581742c6dc7381b0a9ae092fe116e1fc461dd48e2e5904fef1de8005b47614ef13d1bf58e7bff399b3cad03ec8733d919d3fa83e8eabcfcf2de3bd071dc0795139bc630cd7d9d48ee8b50a64e6437de13bafca489b55617ec4007293a504b0289e529e472b7f5b66b2e8033bb9062d19a56049341f7d3b7d72bbbb7ed33f5e9789b70ddfba2ba862bbbf4a3f4703304bfd94247bf3c644bd76f1c91483bf3c77a0f03a736e9af734bcf9bc8cada35cb10ed5b73414357ae1becdce2212019a488a329520e32cf99585f6c9e5af1fbb337fc2119a3d22409bd9a32fb73399d888176166e740dfc6a72a93bee4b9e63723d2256e4efc3f3597279fef88bcb1ba0f35c06796d08889cd3ec3beef295c11d13582690cb285a29142d872adb5fdf5e7578cc7b24ec68cfcac54c8e4c865c1e688485e38ae7904e87a68bdc992c557f3cd9e11a1ea0e10f45c69a5e6d1c3d73c32c53a1670acc3b19faa54778308f9825b341aa72a013b11183d2c10ba21d4f18ac61631eb4d60263444b1feb7537f6a927c0f50405b35bedd00c5a20deb3e11d517c3c1ffc10e266641be77fa6e7715d010efae78b242285050a97a6cb8850e0709d6a50499ec3cc9dfddf08f0e9ced1ca2218c642c0ef1bbd420eb2bbdde5cfc06fa57a677e85420edd2e587b65c5252cd6bc1e9140250e0d68c23c31220dca12490f25228d8d8d1bdff876966992b409cb46943b5c66ed57c18ae94c616a43abfbb701aa03a6f396e7f505f7e5fa8dceb6bd62f463cfff95fb99ad46853191320bc92adaeebb0a17bd3064df3a10a63a72df22aa01c38cd73631a9bed06f06751ecb1068c66c40e43b200fb54eff49f0e332d2657fa7b6607769b8c4401bf49f64a00f456b13031a669ea28aeb90188981fc85bed69df5e7013d7671021c66fad1a9f6b209f1bf9d5f0a01c96fc355b29bdadcdcbda8c81f8909002a29293e17d355e79665d56d80758db7555326a0f33baa1140bf98d19826e6ee68ac63b75a9a5c2059d565484b3c5c00f17b24e4a51b8f63b63b230a67ca0525ec817978c7de346ea9783665c391451564044a9dd34853d85b05487718b37ecc2f59257cea41b027806ccbccbcafcc485a21b1ac0c883e5747d0824a6188da288096c23c45404db38f5e3e2eecac1e069785db3bebd360945e6cfa7840e8791ff71707228fc3befbbd38638c4605b25e4c1d100fe1819fc01fc1c75517d1b66825a4a9d51c6066f52c64d2a5376edc01197b9ef628c6fc8cfa18a440f6c1a3ce21b5b87c4d6bb0e60ebc24bbdefc87b0517fba1616de1cd58266b9cc9febcfaa6b575ce4224d113f5460fa141da4e47c5b1479d882fc2bac3723df9b538ba9a8788f6d0b0b32817d2cd75cef2fb7404218dd825a14fd6f417d5e7004ecc81ddf5017c63b36c685187dc6ec0c41bfab9e748b39d3fd16ea58c57bcec7dca0c2238ba06001d673f7f5dcdfe7f53b0ad434a1a12f5c060170d96d222bcbdaae36679130dbb9c8388e4ea42576efb303c01d56be7dc3a352a0f56fa4f32425a327cc7aee07ae58f9bc87be86952da9041786b27cb495dc753a8c9d015244b83926a887a78d462fa986db6a9a06b8772e232d3a229636c745632f8e97e22366bf1f1dfff1a5d191a19365aca3a0ef7052c1d3ee20007f8f2930bf34483f1ac6b0f9c8b0236192a990f7f15ae041f3083dc8cf9a8ed19f94d71614f659fb32e75e142f7cc54dd6324b0139547b19531e3d3f3d25ed63093f1b2a033d99a88bfa47433c28df248cad0bcf9356ca86b23c662985efee7f19cebf9b5f985f66b2cbec7f734209ad34f25a704ae31bb75a811160d61db3129671d8f9c6c0b7492bdc0ad13b6eecd4a74efd08fff058445e350096f8adff7921faeb7274472728b106b565efd6d686f167dc909fab8c804dc63e622e9a082447b41e0891fe77b3d66acccd8f48d594fc4b7e0536f0ff6cb324fdf4b6ffb1e22ff4da5fc8ade14cee7aa60ce8024ce40181c83c492de201b9bd0ded5424096e7b029af7a41276bb8022901a5d5ee40b0859c035975d56b71d2ce2f356f3ae9f365aeeec021bf6f98636b89905f05aa3c4e988a9a276dd038891c510d6d5f145680b46ba8dca7f7fc153720d4b66411edfd4a848efd36a0bde2669a048e109baf239c4e1f994cfca477e38831ee58515e2f2bc6982710a02f382af8a6e04af59bec870110e3979f2bee4c8e199339cb2f23f546d3cc65998c756b114289698f1ce736f2ddf8d387bce77830e2946446a94124a3f4cba013d2641d1280f1d921d34f81aa2c69c772cd21424f9d8507e57236c8cfb706763eaf3efa468d18a4d675bcd27ba3a7fcb15213c89d812dd46acc05f55216bed72026a8038ae50edec93a574385a1fc1e286397f4803908eb3cbca8c54957c2bd410d4fe37a3b95732138f02e31b182ed30912532d00c11c6281d244d2b940a44fbeffa4076d09e6a4363e60e9d04ba63a7439e7e84b7467d62a26d7a6a9dca5a2fafca9674961e9a02c35c9d3260049b5e7262df6d7a86096cd27ef692effb8d2f174ae6b09f2c9b839391bca30cec65d91ed47ba02ea94d23852b819f9d89204c2659ad05161e484a33790377c784d5e121ad05bd32de6ca57999dd63af8016caf5c3af0465ad88c8f9d4c2c2ea65c8d7ba0f4ccd5c7aa21948e568566122c8b8e5082aebe9fff55315e95596d3c6cb61e60e09161b771a6657b531c29c4b438f55b97bf26d20f9cf5dc0508e14b649b98795faf64c0d904a3893d81f27ef5b2c6d32600da2fe1a75ce7b0b15cc22aa5c524e8a34337e3ff464660e65ef53b19caddb5ea7b50a1254b8e7ffaf54ae41c5ee71cf82e168a632c93e1576aec8381bbb61bff0f43c62994aa4d13160d137b472a26aa67f31ab2bd38988dfddd7b161795b210757f2816a3cc4f2ad4d92a18e37b4b85c1fbdb02306505e804c4dacbec92e9eed544490c3669524aa244890e7aa6bc1cd3c97d0c218f1aca97e01c2b8272c00107074970a68c0bceda5f94481e0f2da937a4052bea70b54cca949e8eb3c25e2ddd2725b98c2453c94559eb2d2417954ceb0bfa929c7089aed337d5a9258c5c0eae346e0def7f6c6e09e7a0c8be0bb91e6ab4a2db493e4c3a5826411eb7e197216147d95846775f2e0555af46048c145eab01341091c5a9f05b43b728af0cee081684a498d985bd5ef68bc5c35e6acc1c54fcb3449922bd908538b92b983233c71b4181c0b9c5fe33dd8665deb2239680a68601c149534173efba9b6dd0318458abb2b059128428104c3130a7bc433ef5f093d8487313469f4456fa78bc0ac941c5f94e8bb20f5b0b340d0f39693579130f8ffe0a0f370a0a2e90a2881c56a7a22c2657c02bb3170d4eb919cf59e153e6ac925b93cc172e3e3ce765054373cc188cd89ba5f3a3b2bbba2d96ad26ae5013edfced6fa53e326334f542e7edc23e2b5dfadbac0b2e85883f55174eb5439b1ae400940816e654f7ae7de9cf9411ad085bdab476c48ca988e993b687f5e1d81caf1b757c9c1892a3bcecac0e607c941311b2e0d9cd2fefb1792ad1a45b76637ffca366af1867300108197111c50958eb8348928afa9f7d727598e9b937a3ca30c7deaabdb58f6ca39846b22f6292b0cbedc90e52f54edb25e4bbcc58945cbadd9bb61f64e64599bbb58fe94b9968490b1865a260352d719360e6272ead31b3f6787bbe7824207b66603773b1a106a72aecb204c12492a23c3d049b2f5cdac8998e83c28d81cacc19141aeb5591a39abae57e160efa1ed81634ddef69126b1984704fe3f768e0f746a4d763dfdaeacabc4cb29d24d108a83b80276b671506a3fe907864806f00a65f095c508dab519e8a3fb279e0e140a58919c0f25484ffbf5b7c7264ec676d2e0957362c06ce844245f66c207ed659cd1cee202f8e793c44bf0e36db9691e4ca0b8eb565dac8695b065b9c3cf7c631370e30b7c456c7dd8dc32623cab73d3f74d6104d9cdfe6ff9d6f0308d4e74e6c68517fd0fb6f37dea627e79cba2a125325486b19a5ebe548aedbe47fecb27116be9de67525be2ebedecc677c74f28b684716913af57a9a7092ffeaf2482c9c143c7083c37f2d1f015434a4046dbc107b802b1b6019328178bca2effe4f51e2355787d842d23ea3f1eed6df558314d2f31492c19d5518a0f6a934cc748519a4a32f50666ae98043e44423894b567aaa16386fbf512f84bf8268ba228a011e30816de0a0876bb6c878c1711aa6423b59a1a924c14570915faaeaa65fa6e952d6a6370ad28a0d033f8c18cb01c39f7c7583dcb70fa98a078523275d86f6c71751efca5416243055baa2e694873252216c9c4b18e88078d8ca3c779f59afbe9f4070ab44f7c0d356ba548673f8cbf060684a80effb9fcb1007d08c45fa8ef6cdf68f1611d5ad69d63321830ab5bbc7d24ea966537e811aa8056ecb7dce590fd918dc5f58616c5cb4f38c605ffea7c1dfd6c11578e4ecc7d86802b6610f63aaa593d8818c8d3a89913ba54cdb0940712a006a891a7b3c821a37471c7dcbbff55a6eec44f323bee82420764ebb71a65c1b4835686a6cfc67d9d818177b63e3358e8d3cb19a042c3e159b6323bd83af3f9698259fdc556f9d489209267dec776c44d7b39d9bec01ea2bbc6d03ef65b726b38bd699796c34d5bd5e78e08a0ce9dd62557ef373434f3fea62c5ab4067d6ddb7fcd8d8ebd5034221b5f600c691296a00f35197884cb10e6db87710f3bdf3c7a2ea66a06e876e95d3d59930e75ece076f27a36ed8e0fbbfdafcf63699ff1c1508491712a4bf16410bfb3dd46c1d42059a8d767e1ab6303fa22a6647b628681a2a3e213c024d2f18f308684509f4d7bd597dcdfa21a8f2bc730697b54c8f08cb6a8eeb4bbd845829f71b0f5ea68cc2a9ac60012913d5921f52e44c1f9297d86f5420301e73a6a2c63b284204cddffad3e1b5cdbf07b018cf494752a566fc3720e4f7267de340a2ce834152313642b6bf41ffde1387fb5c92455a2303e51b8d1c9c62c492a62c8f39b9e5b93d18a07d854719871ca6c7acc31e5578a577ec1e514254da711987d331b0070718669fbdd4f18d7b92c72a742ac8adf4645a62d79a738e3f4d3e3dd2eb7bac69bd975ff1967d6423b7e149ccdd00aff96bc8062b9423ff7183ae513834c1d15cbe58431fb9d829ca40fe38b8f98274975bed07fa47f0de4c7a7a14f99e720b4d1c24496312687c4026f1eff75e265fff9b482a6ad7434dbdb31272894d5d49c0a8ded8e00289aedb1f31719b4a808da48ea3f9395638c33bb9ee8b934fb9127031fcb55b099b10afab18fa82c95785b9ad9ca02540eb687ba81211f54d4d5dbff6307c122cfc904e25ddfcd674e19232fb5cb28772db07ce74ad6379d98f15f3a25f462833ba9db7874f1dfe8fcdaf23cc5eea9c77e4862b117cb290711fc5a4a6d048e1e7278f2b72c165220c9a57d13e2c347a3be16d6d4eeb24a3c66ab8e813c15b81e5477e208c8fe28b812cf74c9a57a68c8d65f21512d04263c4ee8ee9de350a86a4ab7bc466c8afb6f001fbc60d801263e06f5915b59d2ec74bb28721958491f219d8b7407b0876db4bae6c11545a24b8c76d8fbca2bb1a67645d1f0e85a76958eba89f954b46adfb820496900e4d000ea95d65340934213c3119cd099acc6f3c983a1d8cf4a59c1b6e39bff5de41885a7780407e19d6d4dd099092f35e2943f87663de08cf77ec3f329b0d98c2f55495b965327479a12dc807df0b0d429ee3af2a1d09f43c82ea8b6951e4278c1602e29e2ac7f4db0162441b2be3369739a99ec39eb8bc36e3a2cba0573044be2d9c3c09c4a99e8d622826a140fc916bf9fa033200c4cfb76ed4e01a5d86326145a6549150d8f49647be80a61040961f0890708598acab07ee12d6f2a274179a5e753239c93f80c130e0b47ceeeda932265bdd80e01b7b7c125cc498e0f9fb14aa85c31448296999498b2438c325fdf941749b2da80b8b83c1c8b1356be164abdf926d91ea6e12494b5a2428ce8660b93e6c335ba382f5b95dfc777cbcfa4ccd266f903279e28e5b7e8f52d96069e997ca0ae029c14f30f7310d35ccb5c3ee56d29cf3fd2a8336a5dea07481e2640d4689a697e208fc4b49f966206b2cd9acfbf16148b621a51f5582f73365e5c7f982204214cc4f24fd8ddb1679202bab58539996b2268a50cc8fd5b6c2ad4428e54ef72763d7b940597e59b43ec639da44d93240fb1d471407b13eaead5fa7121dfc0269e2f9f1ab3fedb0c7dcd42979ed7244b6f470f15464726cebb481c55f848f6be55c1027ee7398d5265903a52a1a2121f6ed2aa9f64ab84377268c9be417c725d8aecf236069e3a7ae2ffa51800a6267d54b01a310ebc39c0f0775af519a76dd5c0aaa20050f435ca9eff7efa427446514ae9062d52e00d8346b63bb3343cf095277f296e6cdc150ba799bece0aa1110badd07afbe17b9fb279811fd4c78c73b80727bba0a5923564b216eb15ff7aef7d53aefde08eec6dce13bc2cc879d3b5cac88f1b251971cdc9e6e78f556042de91c13210beee928e8168fceaa0684e6ef5b43cd490b818ad1bdc09c742da13fd86690513d6fb3324499d2a4284a769bb0e2e51cba2c4fec8cb1a0133388722619c22078a19ebbe3618b64fd987095d7fd3874e1aae6c8b4395b0f8f17cd395bd2714c0d2c335fd1f825dc9bc15162215cd305524a71f79c329c6d10b729460d868a0b2d949a9f5c6f7ad19e018a5d74416b92cbc60354037b03af585fd05d81419c7bcba5167093a65c744eb0d4c0c7a1295eb52dbc199bdb2eda04487ea94252d6594935df85f7d866fba18d76316fc40f2d1330f339c3dbff49246e99cc494713b2210a0a4c3e12c94b47a45ec8454ddcc55e01d3c1fd610a998fa997646819900486373d73fb06671826564a7844c3821b089e4f216aa87ca8c2823be577b73f46753d9b6d4bb64d6c8e8a43c66112234e1e6734083c8983da64d4a7fcde2d3dd2a2d1516b861f2b33f1807b40f64538d2e5a36aec335dcb9068439dda8678b52e1041ba00f794321d8f67725086a2cfa063e2ace8c775648b88614d45997c9d5c284b97dd43b2da053c82d1bf56ce06c24aae167eec2259c12805fd12efe91cc06ecd0154f7d0606dfaf360d5cfcc052d0789d40ca0c8b78f10a6808c12071ff9cf7c45a8683fb9016ae8b0f452546f3083f0e193638570bd16bf1f455020b4a085f8f81a4d4458d6ee1ca78379ffe0dadf1a7e34e6b2f4df700bbd809a0363de9c79c5622e260b2de7360fac63f16fb1afd5f33010d94880e50c2a54a9b473c026a06607c6cd75e58c143deffa9c800cd7e156dbeb03d880b7b8d323c68a35fe48d5f8cb1392779b16c816b588c5046987638fcc02e9b9d14b399d1bf3930cab1ef86b8caf58065c96ed8e4b0e59c508781ace21246b4e34a601ee6781f59646d31f98405e3e89e1384e590ee8e2afcae4dae13670fa2417a81978ec139b00ea7cdcf82826ccd6c680b01c6716ae81c38d793402fb547098614a7d7e0b00dd5f316a72c22dc99d550da7076d5055d693dec4cbb765799ab6c31da745762fb2a6868c4dc449ca6ec25289fc4ba60fbf46b230bcbd62a02c3d709f0200ca49d9c63d1437b18721e1cdb45b8f98441acaad64f291428183953d992c4734997a797f5f1ce9c512fd5b2880519c2d38eeb92a9b2293d836b5028aebd1957cf13547da7bc6d38a6ef40fc9e58bb4e9923b7f29b56734243e9af6d199afe3d4fa34b6d71708bda3832d392d356bbe132ef9306fe1e87c7ab96d702121d11dcd04387f9263f7131fe44049e4d85e7c9a29712e98e1b036785c02410bf1a54a539873dac2e5a5e4b6316a9752c263b2b89595f1b3ede4bd4c2cd1c7fe11ee12579695745137118e6f23dc3680d8413ed095f9665dbc3e649e034a9926815c40d615271d9d118ee2f0fa33ea43b439cabd5df1abc96c35fc84a98bbd02dbe176c88330073164bd5705be1c82a9a8356cd1dbd5aecabc8b99be58512982beabf2b698aef5de9893cf8e4d88a847fd618f6cd136228d6c42b6dc72ef0f08d407140831e2f988d18ae7c960e9bd7ef5b48bf2a0ecc7f038880c78727cac07639e0763f7604c060fc6481ebcd5d3ee89cf4ab4dc3312d9a84467a3901fd98f39d22586f723ce8b9488a31243ca5fa878278ec13bb10582a674159552e930f6a2648bd0c3580ae51789a51495f73f184443bbf42f80bc98457310e6495181c16321acea951bfa2eb04e121f504fbb2118db3c7853a8e59efb53fa71c2a42bd428fb08133f4d30d1d19e4e43443de888442600e3a7d01db808d0b9226fc608a045e5198b46b4d353cd46233800d57a8e724ae27045d5ae9d72a03f2ecd0e6f764ec68e50ced110110f27190f31885465b647bf11fa88fb0d3712d948c4d3b13301087510d081ee29984add4fc79361c14114b78c0f3a6c0f9cf2de4360bc1f93c0708176c17d0e7242826919ee627abff01a31c0c00778d1e75cf0604cc6062cea8c513443741bb0a8d9fd601299191711f57463dc5efe837d03ec40b68d2151ba5b6ba25d4dbacf38423cd6f246bd6778ab7b3f76c1ad95f799087c51799f9380ada8f3c3137d80e43cd6f2202180a92ec1ae769e818a518f189d088d3c486bb25b3a173b940780cbf0581ec353dd7a01b88aa79dbd78573a6f88b5277e8cff8895bc21347c06cf3ec669ec63a06e2d10211e2bb2f222dd0c323ec37fc4ec896fff2396f3180da9dbd3a46e13e3a9b3a5a1e1f6d6dad8d3f01fb152c90ea1e13264fc470c0580a34e0380a3ce47b15c86b5917196dba0ac00fe231643757b1ad5edf936001780b5b10fc06d625cf51fb19497f358ea2d1e10211e4b3de7311a1ebb98c16309800700aaf2543ceda6fa34788c2355fd1882a8a3137f76b45beacf402f4a4e4db111c54620f5dcd7215d50326c8ccbf0a8c7c312316effd12bc33b694fa1bc936681a0415dc619006397aabe0c6b83b250aa7ec40e631665b5c3588c7fa65bbd4ebb8de1911ec38371eb7987a2510ded6a87b0a55acfbb07210c0fca183c183cdb9c8a3c52d5a75cbff36250ec8271588877f286c0f80b930744887ece63306c0dd882b0df87e116270153fdd62ebd9c07ef8b900b35e8d52c13812d8d9253330bb32e4e39c1c53c298c92c38ff4078666248ffadc772122f2b438b3271a7df9a721dd51aebd5007578774e9aebddf03be64ef0803d8aa4044179754f5fb8858c487725dad149892700ab763ffe4216f74ce1375efac4bb480193bb13aa46ac65ca2a8ddbbc3bb9df8a3ff8885bc1373dc6d7ec4d8d36e14cdd88248d5669b5352c200a630d1c196bee6fd005bfa99d7230631b9a40b1051d5973d44066a9f94823a6dd71254f94db19870f6098084aa723f530c1d48c742f674201ce386846eead5edff005fe8edf7e8d704d13de3146ca15e952a12509d877df49369b4937eee98e7c1a99e5fbc8ed81de3f61f38353d1e9c6a1eace387a676c6c2bc38d5b04789122534dce2e300ea815b39b835dfad03a802754320f9438744171656f15938c592cffeb1ecc858dcca2c4bc9cc22399b2ccc626953e761fe585858322381852b2d4b123fa895cb0573bd602e982bc618638cddb1bb9b1b06b38425766c53fb0851c1e7fad146d00544c24488192490e0841682d0811717fa20e104b310245d7fbabb638cdddddd1dad92ca625556ac2b17faa8a08925fc4c298494c08327665764436826ab1cdddd1d636c66dadddddd43b42c161ced027ac160807a098e1e72f8407d9078828b08a9898383834324067f4a5b768a1fbbff532c5e051de014992bd861b2a45b480c748013743f884408215348c20a90c0c8c0c8303333738c91819181b180808074441c90988216a8703f8844089f15f0f064173ad1e48afb411e2120a183c41429441002124b309949882c2e58848991cccccccc31729431362ba6582c168b5b9087c707890edcb69087c9122ba01512d8948048a6e81e15b4e007c9f4c0d4b2ecf59ad37edd3de79c3de5b45ae6830e1e73fe7bcd39e7242de99e8c0629d6eb05f382c1bc605e30dc8a31429817ec057bc1487ec1b858509c922b2972700ba25edfca87d5ebf5f2111284179349058b0b068be1818981c5f0c4c4c06078606031b361312fbb923a7830b1848799613f303f320de3e1d92ef4518113789a70713fc8c3449b41fc41ad5cd1058b7f71aa3fbe8b3d98ebb1c5549a243d8ca384718c2e58ec734a46970b2e818951c61863649eeae2d692170bcc121c2ea8922ee9b3020fdcb6d29539c14918d6deffa8d6da5bfb8e7e0ca7641f8653323ba20cb7a88ba497e1949412892807196e3f0646867af04a1819c9e282401faca20abee4a930dc8a919799e196ecd80d032544427d5620e4b6fdaa166c20052739b63be04f1ecff5ccecd7a3c76e78626beec8db0177e043bb837b76f6f8796dbe376f47f6cc7e3e6ef6eeed7df536f775b0bb73f6b4df06939db7a3878fcb3bf8057aed2ff0d0823ef5788881bc8deef3dde74534babbb5dd01df173df3e8fb309ecd7d3b4c6e5ebc5364836fc71d7e33137ddb01661749f98cebcbd91d35f2c21df0f06e5e8d7c81beff020f2da8f351073ebce67d99ad913ba6ad9117ee40baa7b636f8f0364cf78367289ac1340b9f214c6e8c0b7d58b0e47227dca147b51f972f1fe996d9a85d528f87297a5f7bf14e1f33f2d7e83b2fd2873c2855914bdd48bf79bf9dc73de46d8fefbe79a14befbbb1c19fef3c0f6eb71f0ff6c16533e4552a55d247ffd07896809be7b6ed945b70dbfef13071da49bc2d49a859bfb36b55dc6c3bf57664dfce65a1d06901f2dd69f89c7cb7013e17b25fb679daa9a73df3b4f6788a27943c61046f093c6812218f929e265e16a04f4fc4894f28f9161a8707415d4f93d83bc84f1e5c014258b220a8f239d41ff2997c9f7b61f69f884570f1518bc843180590a437adef396c91d666645352d5ef512f4ce4c1589fe33c188b30c6e2569ff31a00fb38604b5f48cd2cccab87c96be2683c423279ce7310cb3b7c84c6ccc4ad61661e2df24cde812f2ef2ceb31022dcda59d21dc648788783cc1e1ede09e209a23cf3bc3383702be8084d7efb26779aeb0ec74138d14dc8d218298aaa59c689419c9ac7e189b8c3b588a8aa7920e2fc778631f6889bb285c19679be240dd4ccbe2c8b87357528939e73fab06ace7b91094ecdbbb0453cc28447e4d67464c8c56d518dd1bc0d3b75bb3e2bf8d23814c1272af1e9b70fb74eb039354f7650333b8f03909a3d48ba4c972552fcd4cfc3397b32b9f3dcebbb4ff438ba6fc7217a88f34ecdddc04585f7e4dc35ede4dcf6fa1bdbabbdf9cd49f791bde1eca9ed89da056cef4eb3d9537f3b8c75a7b9e8216e47aa5c39ad8453f3212f2e91aa5977507b89ed6824061bd4391f7d26dff9b8845b3ef35064e364e2d43cbc30e2cf7c049a8f3ef371c9777333bb822d5303355a1614a75a9a54faa379b342055160b283387fe68c31c2eeee382d8b759bbe28a5f4c5ea76bd58af662d79b960342c16a53d2deb473443ce434b39d51d25396006f3d95fb4e7297da4ddb469534a5fddf32f180c8d5a7cc15857777777cfeed990c90eb42430ca888270f5828fd60583ff5c90a1fde4e3597e324b963046ed91532ef8d78c082574c1202bc5535df01042085d3016974bba9a20e5535f76d9d1cac338c5f02f082fa1062184f6d360bc178c532c0f7bc140a9c9178cccac8b538c5af1390733fbb06296cc2c190b423eb082197453bc98cc2be2cf94b0572f17cc05a3945298ebe572bd602d5d3016a7e6cc58eebc0b06b3c4e572cd1d972b0759641263ccb22ccb6876d697652f98ec95d55a2bcc0bf6cafe82c1c4f882899975ad3835ffadeed4c12d1fe67cbd5ed9ebce17932a50f35d2d693c3838384262f05c9669daa56886a675a89bfdda9ccf3294a6ad6a9d999dabce00ddb60d36bd36b76f3bb5ac176b7b716ba3dbb6bd3835bf792c178bc5adedf3aed74659af558aa7b2b8f5e21685cd4f1a168b75e7b1a042e4827d2a0a85ea60ae97cbf5c291835d4cb2cfa1e0121e387a802f2edcaeb00b139017103045c5215d4bba51a8d3fd50b74fb9ffb89bec3a7b8a81b77b0d78bbffb8d1fbdec3e5771e0f3ef51cffc7658fad8803a03038d5264e75e9f29fe3a3579a8e8353fd52c7a94ee3420b1874042b24c3292a9c3912658843a1986dd4c5255340f21cfd7629bb5396216fc66634ee9bd745ef07d822e391904b14354443369479d1c80f1bed01e113ac05258216414c05c8c5cce6bcec02cec3a9654358169dbbab0967035be6b919aca87c1e0208b772b8a5c3ad186ecd6cfb486766f6a3b56a539b2b177736f06574271695ef8eeca12d147a0d4e69db763afae68d9ec13cdbf3036c9934361ff3037cd1ee9c73ce198360cbbce85c8ec8fbb667daccced92cdb913d1631a9cedc9973ce1977a2ceccb2c777a6c32e3bdf662310cb43706a9e81d8706ac69d8f8d98938db8739e8d8838f0e7a30e106e15311f77b87544f699cd2ccbb22cea40d5fc9c339b7366f6ab1ce4b00c54160b96811a7fd071030dea07816ef38840f465991f976dcdbc9c922b56763f162be6c4233436ddbe5695e0161135747a63c713f711a70584be9d2664c33d74ee226c69b6ed9c0793b123b0a50f6335902046bae800e27e04025fe2edcbc842fd62ce1031875bf1f66dd9304cd07f01015654cd7e9d748943e4906850338b8291a305188db38d60cee07a3092db9a941267c62de0cbe88a3e7a5fe2704e17b743cca5eaeaa4695a7ced3eba4ded46707411155d647fc4429a7dd73f62ec71ceed2bd2b4432e8ade599b955475e8bc82557bc2c3952412896c57adcd48941279246fa6cf22cdd274afd686f4ee5cdfd5ea43f25233420ffda391e8239b3a39c9da8c7e622f55fcd5face6add45b64a95e6c14a451ffdd53b852c1034f59da9b336b5a6ea5f43873191e5c8238f9aa42a5e5479b8c5347019a98188cabba14318d2097d832e9c2355fdd043a7f025bb3bf8db43e7e001ea76fef6d56497e553e3ddce2d1ad5ee84f413cf2482227bd3d19185a790161afd46fdc88eea8d9b131b47f6b128f2224e77bcc51611074a83169573a44ba5a67a53b3fd6ab26f75a3dc02b6f46dc0a2c6508b6848910eb209842d2b1aa88c78445e04d9c981597291b3a71cb86bafc165fce36eecc1cb476c04f2e6e51ca088831375e24e3313d8d2b7a9e1145fea507e81052a7011a594421e3e89bc44727b668c3f0dc93a7b76f978e4b106b01584743149957cad26d39f4aad564c621337076c91278016553e7a5ccc91d91fa44aa6d400a6e483902a7969c4e55aad52a9df244929a8d1676ee1085cfc744ec4f9010a314f9f7d507a0103e7acc45ed88045a52fbc53bc97f2177ee3c5613ce52f7cc52bc2dcd99e6c700c86b835dc57f18098eec24b1e90d3570e8307a47495cee469e0a44993935764fb8a27c463305cc513e2b1d34b5ece63309c77f888252c052b11bdfb61211e2bddaebc476fd2bbbecf3e80ad6824461f4f86d23f26d2c373e4880fe7c820c9ffc5a09318511e7f241528928e1ebd9aec9e4492ca47de10157be20d89719497f3988caf782abf81bacaca6f6238ca925e64f41b2b471d656f54be721893614f9cf3580c8b7ae937502fc5f84dca51bf11e3e6c5631c9e9cd82131ee59eb5dc5f37e13c3ed614c06efc49fe13076ef97f11b327c067bf3e2325c86bd2942f3e232fc26e53f8ca1502fa19ef358cc9947a56af67cb48602a86a982fa0cb0b684d2f46d4793a4f6047662cf0744f031a400fdf00f8d2a1af58ba6e76ac9a2e2618a59017a18abf796c1ac285133ae1b2cac1aee6e7ea470e9899330a81cfab30157bd85c7e574df30639d092fcd265c66abd0ef8c2dc71c09f0927bcab63529a4cd2c6ea7e14b87d19e3b8db3c8e715ec893148871738e481fca95a4db6c2b6c9170360c7020236a05592c2b1696154b320b4beb000b121c447dd00706a31f8587b9704fb97050f9dfcab34037737fc57c96cc1608b9ea4f1f973f594abb6231bd37c42455f3dfeac229c05c2f247de639821bc428a39431c6c899b42cce38bbcc6696d197647e65f39562b15c4cc36249fb55d60de08526e859d816c296ef871a53d4797823072e740247c98d3c4d9ab8d3099c2377bee3568c976366e62c8793cb4d606471c1c4c0c4c020a4310c038b990d8b79a55832ebe02125ec07e62746464a292533b3641f2a829e60c51674804c56af1818192431323032486428a554062606490c8c8c641819188bc5076619866766c9cc92855441052ea6d002f5a303a49ce220fc90e4368dfeb85a28949d3d9209ea7648b7b3066366961f840c431086203343c8cdbc45aab10c33333364c890e199997b4b824a2959ded5a47e5107c82f3fc4a18db3a21fdb762a3afd0deee7b2903d65365c66b373d6a648666d42e76ed37d38382fe4ad2e0e4ec9cd834995e4ea8d27fe4ff476fc2cea44225127ee64ecd1d06e0e6c91f1e2902e3406bf725d29a59cb6c43a4a260dbef310f5ddc48730ee6b96079f6d37e1e00e6a6bf8cee811afed4c50330bb7a8f190214ab212300b5a706c17b2505bb6404bf053c385909974a747bad1bbf1c58d27cdfb025d2ce41aeef46ab85034c3ebaea50a6e62460a9810a405175958f17282fada001416001469d754a081f1f130f802218410c618638c31c618218431420821845910947c08fffab4437b1525d505eb489a3ddbe369aaedede06e0379621708fd02dc5f340e4e17717062a1472f74a1c8429e5868bb196a6e1ab510c2ee6ed8524a182f9ff281900c5c2f1a5ad032052ac290821a0580130117b680b0a589cf499b4a2608698b1595c6285aa050e3e177e821924a521430191c343994e0c8419343490e93c964ca418343090e9a1c2d9b2647cfbc6294046dd1c316354a687a70f4e4e8a1c7245d6894984c4a4c4a94683a802fcd26a8f1cd1d33d3ddddddddddcd718686d25a636cd8138520a85d5e1ea50816170c2c8607260616c3134329a53130181e18580c2ce6b54ab1583c787828e5a1150b3c3c3a29e08239da303825e55bba283d66c00928909e80a8d50b096f6142c7844e02922e9819199a243334323449686aad95466626c98c0c4dcc8b05e354165964c183c90f41f0d4d8f0c064922449d2446c19cf323133326646b2e43a13236562666266605cab1899191a202967685e52b6947247d2e01e6d221da9304a2d4d285940ca9652b6d4023c6587179e33081f5930999819d823c329863686533333dc8acc91639d89e99189998999817175cc0c0dec89e1560c54f1a1ecf140474ebe38253bda550e792432a5b59a4c504218131d0395467b9c5242da14529672c52b66ea75430aa90f38667240da4529056d6e75403a5a8b52a9540fa16762d5f4acb05115930e4a6d496547487e9329c9e393416ce2c267f173caec93cfa275c15c30ce38a330d7cbe57ac15aba602c29594a2925b364c999ce84486009c6852cb0e7e72d08eaeca81d881a7a2f1c807c8de9ca2369e2f6a78c12f6a887bc9a85c116f94127aefc7ce5d6f72307b7ffc1ee6f8f1e6ef75193af806d83db47bda79412d5cd2c9959b244c2ddf246241149044a253ade70230e7c81ddbcb261a7b68254794eeb34c6619cac86246a4b0ae8d3758c035ff8f20f112347987fea1199133b9a23a5125b57c5163a9c8508c6de22a242c9e43b73a64a81e4e0ecb466afdcb84e24e2c1a712d9b47315ec72627964b7e051c7554c1a39443acbb2dad9c0841aefd7574a23a6af126969650791b6ff02451d459c1c918eca4e3f8e44331ab6c8735b6cb8f5283ee270139f7a85ec36c2aa9eb307c92ac9a461840bb9b835fa0623dafda21123b3063857f025c296dd590fa7fa74a23614b2099db327da1d93340e4f5424dc43e7818720e6b4ab6e829a5770dcc334f8c2f4f4c4a4628c0d21a85a4f4c0cff501304f5ba1ea28ee8f100d2c18373f8b06de77e137a77837bf7cede6ce76cc469202958c3f6900724c715dbac0aaafa42d0d80db75d6ed770fb303964b188d8e41606b6f45116c61559166464c2b09e9e9e2aa4f891e2c26e29b3985dca9ea984398d7063cf9c73d26b52dc794ef34e37beb2041868008bd38c4d119aedda4f34b729f20dc98931ed31e820484cb337a66f964ad50c7d0b59a99af334965920e295e7649412f62806e6d5f362ce5ad0f104976bf0a5812d4d69f4d4791c2813b8400e02be0ce09230005f328d4d307e609c2038d5ecd970aa61d0b5e151c3a98671659f694a2ea9b1ccb4cc16c96ed33da4854236e264fc6d41990d82eb6dbbb1bd3b6b92aa1a8f802dfc9896894437db4536e65c8e381e8c15c1ad2268b48ebb598a688c2e07258e1054ed7e70898806b6f4a765b1b8ae60093121fa1cc1aa8e1dbbdb08b74535261f015b1a72716170eb04a9c0b95fa402e736a78e30c2d363e4084c2e916f0844bcd1c78dd6646ad2f520c20e50839a5d27e38b03b630af6ea3dc3e17c12d6621b72f610c113abd0bbab856f0f1eba8c7a1c621a76ed6c4291963666e3255da334533682c5dd9dda837dcabed7e624f5e4f62c7c5518b08eec00e0a6874111a518b887a73237a77c989b88f7e83fb88079f1a81808080808080628f7c1779dc7cf4b45096697d33585b091c39ee440fb8990fed9b56136fe5140f3b3d4b6331a8b24993fb954a26185cf43efeecddcec3ce2ce6dcedd1fb681422abe26e3ab85ba42d6f7fb6a56f20556b2b25b40d2184915bdfe1fb2d9540c81c55f231f0e0d979877a140fead7ad3a0335e8676b1933b336629e5b7766ef337535f6475e0f1f5774d1612ce2c8ade62092d0bf178bf9dd89cea311eb883a1a1dc6230bc3e3c1a976ad52bf96cd1e5a3e0621fc7434d2458a01eebaae72a512bf2bb15ed0d528da21e25cb625f65ebc005be46170ca045be491d4afbb529f8f7026e6193060642b38c09656826183142af301e200e4350fb603ace2b285219ad1235e03c016195f3cf5eb4a9d6442d32ebca615c14526d825ea3471e7ef106acd8aedcc2c7b30b2dcec920497b0ac32f9e8f5f0711b489178211e2bc2f0ecf5003850bfec30a9c372dbc61d2cea0797f8c0ad21383571b08d40b80188a05efac22104223bfa1193cb72a14f0b905c17e0b440c80dc0853e492cb91ce43a5e79bf0afcf8e87df11727375de5aaec88974779e6f1e965cf952f1d4982c8fd2291f94844c89d8f4acc73900b75506403e56cf9a11d48eff78db48fe27da46b4fc0c96b5440bc27d9b79048079487443a64a77a69bfd30ea49faab54122fdda5c92859ccadaca93cef537514cbc27289687185469773879db1d27af7647e9b286bf130b39f5e25929076aa3649b532fec4316724ae5cd2915d621e52b87221d52be7218a7789f8fbbf2bbb2f228d2e18bcf7ad041de151db21a7953ec7773571e3a15e9c077255afb855e23efcaa18806fde782fd7edc15ebc243528a6cf075e1d273213b7b3cc4a0d6c82b1faa8957d6f495970310413de570f2684f366866bfd0ed1dfd51e8f2e823ee48a41fd96346fa095f6e827e740ec61b54e893c4ce1dbdef1304c8e520b775505483643fbea4ab3cf3be206e44f9ca8afdfa66af47f92a20494fa927277d35ac92722aa2116fca493b6af8a6580bc4cbff6a9813d9e0cbd74439d08f9e896cb057a368072d8330668f2f27a2c1f68b9987f2af2fe99dc8467c86f2896221a748874992f775671bf2d6b3c7f784722ab3cda993f3ad76477f357cdb8eeaedbccffb6c4238b78756132f3d8c6da85c6a5797087506264686865b3029d48fde1ef2c2e50b39ec1299f0a212f345d4cf14594ca54b6a16208bfac1f9696f15f5ebee973ac2c37529a7f8b339652402b941a81f0caa9957e73148109147855fac406adfb6f6e0ddb66d8b5d7335a6a845b810081aa8e2c6fba1502909049c216e0c85766c3636ca5e0ddf33bf4421a564494445b950feab6179482fa957296c16d48b163228624359aa2d75408422014a8166851671582bd78b4d17fa1841831bbad0c7882231e09e9442386167b3c67ef1b3ec6d61643299186532991823db18638c31de076ec1c340553c92c81122090501c63b1f5db6c7c85e049ab72942c37d13b10df7ce42a962d1e827b791bfe1de67eeec8de8f2f1e4dd4f2e353b1adde8b6775d67713aeb63e623bb3a6c099e21c82e8a66cc0011598ecb808f686f7e78677b90aad9c19f254e2cb227b63744e744d6a608941cc79db33e6e6210d95d64a34ecca6f88678910e14221b8d48d53c0f4bf4e506b8f73720bac1d993f6ee86c89eb48b4e5ac83b697626b41381a48a098948e5235ea2a8339b3c30f3620f8f0c20a81f17011481b82575e06b4cb42ecd4f8e0957a8264ec5ca8f9f1d1fff12458d314e9a43102a8a537d2323219b879f5de9f05fd7df01bf0e46cb5ae25477f79d5eedbadab6862f9443644a3645684a27dd06e56c4ad1c048d686f4928d3d4152c52291fd66aee833dd1389727928ed9705a756ac256aff8b4cb6c8c9b9b05a29379b9d05c045251de5a1a09ca8d19e9eace7e7a7a747ba701007f5c823b209c9843422835c3ac62e30066517128783a26c6973da0e51accd69b3435c388ca19cf4a08e9133a393bc937cca614cc543b9ca6f909e626f524eba8a25fdc6a6088dca537052ac8f95a75cc59a52ec4dea28368aca41765ab0a8f1dd3fde39ca574c50a0909638a2c87691c76375fbb1f3608cc4e2a9f1f0c23848ca2224a7c1171a6bc19d38b9140b808b8a72d243b68b53a35c95e09d2a807eb8a78766d9a49ac6943e3b8ab529b2f2af7321a5a4507a61ac79bc23853a77826acb09f5e3a07b215409440d78398724b5065f0ee2145f061054a9334fbd78e790d2e9bfd2fda40eb543508690fe492273c7769c8a3f2dd904b7267c812e28968348b6964a1647eae87090ac958710c0152aebe4c4a07f9cb3e3d23122ac840e650e2275a4ad108a72d8ec6986747a785b16c13b5215040b55eeb014eab476c50b42aa6e8ad4801bb82932ed3784f41b310a33f8014eecc607e9242252c53aa48a3d1c1fa5df44d20781a050b150aa9640694b8ff20f06419162a144a952256d730ac6a20f0c23b8ec3619ca04354702c117949b3d66927524ef48224c8294000165212550eca2bbfb3e464051809bbd3d199050575cdfe81eb2564291665364dec64e4bc3495516f2aa07a54b278b0c631994d479188bffe00b7df6c84e4055762aa8c0028b294c61753320e2fd561108b664510a6e7df18a9b3d8b4aa292acab1099c894dc0c4208e315f02502c196ec99669907b66432d0207b84419665d107926913388892f14122038a2a6a7a1a8e5a9b226d43afd99bedd96db473d96f429fff11bb119d5ef3e86f46d77e8313eac89ea288bb769a8ebea9b79d653805bb48cfd36ff624e969a676b690da576fe6cab7d7cd6375251440156afc5755702555f0fcd42af443728320a404137c09a186a8644d58443dea18a20100000000e3140020200c0c868362a1582820098220fa14000f89a44c644e15cad324c87198420a01420801000000000018d1847146b70595fd6898e236d4dce1e960b595ac0598e0766eec7193456577fc225558480254f7237a00b7f0fd7f262018f00c889c8cae15d83b51bfa358b43ccbac67db2d6d3eb15e60467d7d1de98edcdf4043a82f428d06199f04f273dc2aacb20f7224b0baa990ec769a92a8c29d751a0aa6615db7d4fa6a8896836c674f2099cf1f48c63e070b894cc6352c01e78ee1cbd44e9371a5a35e1e8dcb03149282fda6da6a6d85602a7fad5fd0e39c6fd0a388e9c506598ae8cb7f9ff076b4f51abbd858423727204c7116ca533dedd20a83a11dd2f79a9c80f6137f2c7c0373847906671b332db158e16b24219841ea94043a52905b38effaee4100a4385e10d04f7a6099c20cb6141e191222eb9231caad812e38ee914da8f4978dd5a5eaa61f404c8112073477c2f45e812d5fc1b28b6b55bef69c642cf843e1aa89936a0a9d0cd43649bf7c7004be86b281b9b2bfdb859def19fec785bbafdb110d6e5c16175359c1a2669114d0ff213123779e281f0603c1f1e3c369efc5ad1479e11d10b55a63737832a48901fd3c7a1efc71171207ab942b7d6deaa71a639946750af577ababaebdaf3defe381f22e7dbbdc90b37934bdc51c798a0150475658fc01702276e19db6ea24403da1ac4ff5590950bc74860848a205e41c5833d1908721b3335e6c68b70a456461d2fc4147e84b2f67877278ac09030dc2a7aba64ba1e2349c6cf5a2a824f9cb201453028d20105350c7e93d17434eb27305d48dd9c6752cccf4db29aed80083407384971fa0224e0c83c924597eec6cc4df2b0d1f58448e28882fccf3928279d177407e6e43b4db6e72400b95ce2ce15e44188001fd3d02bbb8ca4a13cb26c3cee2e76470712dea66f321082124491e45a173fa413f6d1d214455e4d5dec144106152cd364234d5ba223c5466e3f84e700b8cdbcd5431b0447f23997c6d83c2d2c5f44352bb6251c0cb764f94f054202d887a4273e0167e50c62e7b5ad28629beffcffcb0cf48b42ac84484528833c3f3ea53c0343183c04f58a3dd6373b2c60da18a4b8721d4b1c9b4131ef8c64bc2d6f9b6bf8aaba9400695b81e57372c4250e9d608f182a42304f54528807c4eeff100b2d8f6f134e6f33f892c15945597f0e7a51812b71d93b63db85544c7a9b2c38902415fc0d3531433d9416ac32104ddec90f55e910e432bf043a511c3a492b626006bdfb6d09abefdfb9307688d788eb9dbfb41694a05dd4377169804a1ac03ff7502f5ffa3a4a314dacc622e61809206afd59e61a1a4d1ff0dcd9c2011d987137ebc74dc4c7770649673b239a23e78bf001d7a37897d86e4679b13d73c2a4dc232969e3abd5517651ab305938a41e143b9285cc330d5673d6413e2e5aae7e562d3a5c89ea5a4072e35d11540ff155c0b596f895765d8034729fc0f7251981d69203008f10b36bbf00c321020ada4989a8215b6ba6e69ac1e45e04b78de912715f7aa96d9927e720b452505cf0da6638fc1299671e69851c614e67fd0cead18a36c5d1cdf2df8c6786bc8e453f36d6091a7c884d29722426a6074a6865f20706b257a519ce83f9a8b002840442778b6eab0f52d13d4bfe1d93d6f10b5cc52bdc6a75d1239bc8197261dc4efaeb68faaa2c84efb4df7de84dace0b314844e421df015699f28f521033a8fd1c6650a6f809311e35d9ef6d94cbcc84633a9ee06e00beaf40e38c4591507b697522828f920a286c4dae677ea84a98d875708adb5918773398d47db9b8dbd22c8eb8da7669035e28e5d42bd0f3a63054e0a9980228af3e586aef5c23c8beccf6dcbd867403e324544a987247d7f76cb7b545904aa0c3d6ff62ac71af4ed8591c6dabc61cda1c496ecce1fcd9c6eaa12fdc3719ef92744ab8f93c21fbb6dda280eb1598ed0f81d546ad83ee2685f960448b53433341c29210bd30700d810407bee20c38038339e150046aa1420029937a5338181857fd3ca421d50cbaf83c326664213821b77eb33782d2cef0a3cf12575cc462e15fd7dc789437dc2901c1589ea264d0853f29e10dace0ba6b2f41e0c9efed177929f9c7f794040663e399fabb44aefc3786e99d62a8a1b3d5c2fdc7c3dc623516d1b63b719eda8a626d41d62167daccda45e614cffdebad17f29e52be0c648a20dd15723bc1829eada00f5ba3cf592b44d2e5c909ada6da35180bd5b5ee11ccac572adcae56608c8d53390a4545483aea1c3f6facfd59a559d39f9acd539dbdf4b66c7915b67fa45dd115916179a05eba21967fbb21c9361d768081f7e44cd4f8f1430bdfd543183f13c683af701ec6081c6e6bc3b7b243f41c7cd4e68cf278334958404a7e5bcb4bd1c8d4604b2930c5860081419b647aa64c374ac973def739047e6b270ebcd6242cf034fff720b0aaec4da7140b3fcc13623410b3e15852719d14cb53b3fb649c49b275de532c4b423847c7a1639a284f31157009bc771c6d2b53ce67dc99e4032c210adc1a961079ed8195288ec17ef6a239c86727b9dec7de60240094a0d667f345ddf487925e127bb948d10bf63c4bc21d6acf5ab3c3551219143483a2c663494da97a4308f6ca61093a4864566d93d7523d8752825d4335cf6baa9bf8aff2c394b3d4813e678506036b5f9104f3a2b6ff1de400049eb5111419981244908bb1cd7cb8d18297eb1c33a0b1ef712f9b946075703baf65d54858abd66d07a22ee2d62d85b9f4e4ff5c1ec549aad1e8c6664d56ddf6ae889eb88e69707ae1c611bb898374fa39f0033c71d660b28e10c600d135044721284bb5600c636fb472e01cba40241913e7ed0621acb4ee8d191d08c146b21b41f3e68bb37f71b946f865124ceb8cb093b110586258828668deb2d82e46ec18b9d627a74805d9ca8804be2af48b15caaa9b50047494d24ef691dd220c2c6f2265c1ed8e79c71a099195e8af3472106210be80394a892314b8dec05c70fe8cc15a83fcf928d9558e4fdafad5110a13e0e58f2c8c11e0472ccd59c3ae628cfb0e223bff2a1bc0f883e16c6cbf465b4dac86c670323dc373110a095c142c5af642a908437f0a94f6bd2f47044894caebc07cff60e6b58d3ca932f9bfb4cb0ac90c5dfe70061e1ec28cca7967c620afc6aa86f4d1732a152d3d51bd5b26dfa990be685570508be43e88c21ad2935c00be18d2a56a7762e6acfc75fbf2626a97e08a4d99fec638cfbf29a8affc1cd0199338bfeacb9484eed73bb1fd907d82d4a3e57306e291c46de1c928f96ac6746f9f364224496260b8efb8fdea71c4a7e4844503a254ddd5a2d80290259ad64fb677e6fd5f660f159a921f323102b09a185c943addcf940e5238b2c5c47f86abcf43635563bb7b12f95b4b80aa375a3a980357b927a9b9de6205473faaaf9bd67e57e954e875f000e66f8cd35a9fcfe219f8e033eae08031bcfafbe503e454c39eab35b836719ffe807c76ab20e20213dd37ae5461aaba82f93fe74b82d82d1a982aec7a6a82fe7d9cbc75ab9c0d652090b63c70614819d4fbba6d6cd2d66af51a51d80138bc4f4989144a40f7100b41d2d2300a10a6dcbe53c1f546de31a231b8469ca8986389920527e55127ed8bec1223d8f21a00ca73b6a406ff031db606cebed93caaae479e22252f37a7868dabaaabe7a6aa988dcaaf473624b0e03c5f15c535b763151abdbefcbd51a54a51d7b0b8a1330cd9e7cbe72795fe00ac2ea1d5d5bd0e01860d3d4bceb9ae0eaecf092b1e18d571550a0796110a857055af1afdcca603ca2e65739a9b08600ba7dbc3c60c964c4b147f08dbfa335fe00ce69948cde820630fed654088f85e2ffdfb22e1f12b7717cbe6e01ef2d491a03cdba9545636bf449be2bb749c8de520fafe0f8bcb8f84921dccfe4ef7309d12c4127891be0b412b46d0d2b786a1a0f20eb34e8ff7015f454c180a9c35c09bcae99efda5066daeb1c955d6f2dfedd2152c1d28d58d82c61eb7aa4fbab108035db12671c7c3253f6be3e15f6dc379dd623e6783f5a3d681b02b5ed49c06aaaa9a6011469226342b13d036cef54f9bd589195c7b1cc1c78a2782a20f0d2b2b352894f04b37d806bacc539ca6bbcf4fe9feb4f200b36934e25d82e5eb324fb913fd8ee599b69b0cb616174a40869eecfa981074b9d13e5c601dfb06615f5c9333b2bc3453da0c38b0747ea549b6b2aa4c4954891dcb93e843276e84a7e886fc92142201186e959cbbd0b89a11962d4946e4adc1e09688b93045f6b95a68b71247415cdad2f8fdb828b236a89def91c9885182726fe555a8eb8ef407e081446def63dc0b847599d2268391d4f90a4a101adb2b889d294b0e8901d0754f846c30b5bcb361a49cb95737d8be182f27f4e1ea70246511bd93391a17d819abd18713bb54d3fe75b768bb0e09399ab370f31e7f0ea12f8b4e65dd62cf852f3c7f28488f34eb59b86351d64a936d81c600a60ddda13652ba8361025b9e9189dde19dcdd56c59c5ddb940aa1a025b2c03c785deaef07c64518d666003a6b5e05b7cd29a7f34732ab078554c67725cc8058613c77b6abeca634cc3c1b12e1653a59f202405b4391fe639cd4bb69f45b944aa1fb8cd98740b178de59feac2e98aee6f03c3baec57d4f9c13295bb4955682877edb772c731e15026e4775e9f42cafff8acf0c1536a145868870fcf40abc0ccf7090db4d0e83e0bbe93891d4b8c12b99b6d6a89361619e43f64d6183652370ea623934d817d2dfd79549180ffda7a8eed0e3b55a2427f68cb7591c441f7b934712a541a3e8c416783300f5c6a3129ec1d52f54bdaaab7da1da110f9ddda026e6ff419cf6401a999cf00e89ed6acea2d5401c74d1fb501c91dcbf398a1510937eec374fb043265b3d29c37a3f6fbab1122721946ce6032194bf5d28403b546b14c017cb4ae2cd01c0536f5697e4f860b908e6e0af618b9d4b20d6172bcce31e0d15e204a36da2b27fd92439b29440b291711b093cf7820c24f9586c0732b0b5911f0f193ee35a35c00ae6e352472f10751c2836b4c1f18b596c5868ea2da621bd2dec73487285edc552d8256cae5ae8e81a71fc996e7393e6504fd03b261a146dba674d99a434a80200500891804d0351f32d9ca0ac762da4e4bc19b2c544800b7c6f120e84988b627a487646bf192eaf3852a3faea20adfa9a027f2694036b7ae15900f15e586ab14443fd79d7a26ca73041800f1175cf2435ab3ddfc14dc414c6d774fb9a09e35d7123ee38a8e5d4e602ec3e85408937d54c8a4e06292dcb312a5055abaa35f9ba00eef47dfb347d84445984e965dfec9daf9b5795e52587ab7249df58c35e3f9c4f1ef82e81529d19cefa4c39a6fe64d76109bc8c33cc7e9cbab4a83a072d42388c535705d293dffebca2816dde9c7ecd3680377a5c0e4c83eda656feeb2a9938f0960ddf027de062aeb0890d50eade35e6c0720093205abb85ab7a549fc586f9317e53095636f3d301c53280673b3f47001607b02135ec179f9d12683b5fe97e69a0ed988a8011fca48cacbbf499d819384a300aee7e267270d2c87adecd83ec6d7947dc352fa2caa6d43049bfd4414d8f00c24449ee51a916c623cc703b1a965c0b31ee796abdfcb0e4a2d306ccc70fda7bb5137e53924a754d826b29ca6ac27f8de7d447fac9818100dfda5cb12325a845f7eb311b7c12fb9c578439c7df2420be13c5e4ecd08f6393aa2f25e69028243980fe36a65b239ada95bab07c8d46455da35840c1764218dd7fdee674dbbbe37d38a9d65d35dd7efe2015cddd31b7a208c4be4e58a358c5c1127cda73097c9a00ec1fcc9e52c93318b24fe5d30b970927f69b68406c0471682b3c4d413d13375c7e3b6c73a5734d1a42d65c3002e6caded025ed160fd21ead7dfb94238715fc1c8a47504e7056b5f41be2d335334b234391aafa1e31d0fc15e4a14adc928fa44a5a2d30a378666965f2273db6b3d418269e344197ef1875ae114f2beeb1178ceed3b690a6c8f9c705f19661011ab234272b791d570d2f031a3a32d75ce24b48155b35a520ff44c4dcf3733f0bbac0996b7c477d36c079aaf5d52409d1ad547a5b90648c23b9492d3d3abf4cef3b02f7637332257e5d719a0fb79c999cf60f70e659afc6158a436a891243fda4fac768467e0065f643fe3118b9e52bf76911ebff89e083ba8240f09350bbd1b6cff39b57b87e17793118cfa187227a07d80aa12c9c7ea99fe5d8408d073df0259301f14b49f75954e5479c1034ea214ced6d51f16796e22651547b3231003e07a73f5745f9b4cb3f5277eaedc2b648482d49044bde3408b043adc74d7ee0073ba8ee6ac9a6000cd95dd8c5313fea0e829fc81a5064df36f7eee16bc86ba6622f51931a43b40aec38278319b73f09d707edc7b1aff6fba1c88b96d018b802b91c917faa6930b547f4f8947c3f869596124359e5802d73e800b5ff5bfb0b563b08c27128a24c50703eb7844d3d473364cffc263426c5f4c31263822fa012eab40d00c0b6ec3b1d640be90c9aed600742123c16acdc514b644f6606ae79e1595e9d860a7e141bf6faed93ffd5483b856aa6051ffd46dbe7fabc3af0fc3cd5ff9ef0fa9db62a7b00f5c70fa4238502a0d43a22bea4bb95439c2bbb9623cc38c28e9e19bce12417b9693124a7868041634538f5855f4cf7120fbeadf0367d4abe182bd8c58a2c7807448b0033e93d4d43b8888c180503f2c978a5d12c07084ec51879c4ea68fb9f77c1a1efecd52a54f8383955e12aad07203c7bd58fad2c1a007634c1c6a2e66880f368075e143f290d79f09ccc27bec65992a560bfcf6859e059d9c763e245a7c5b67cf48f2dbf111a60d9bd8a661974add7a534796e3381292d6b1c8ab69a46a658109e615e8bb6143ab2a23b1fe8734a4c9a55c1740c513b710b2f3cd76df1578aab055c5df87dcc4a1a49c6005ff48a4a3c1446d83997676664f1ed80c589a9dd2145dc697a56b208e401f6cfe212f3145b114bcac74c1f75e0717106abcc997944ad254602ed2cc8b32c8539851a4adda093b36a76b3781723677fafd38dfc0fac5e09b9e77da29a80aa6581bc3421e237309706f845e650f5e0b5650d8150e7bb237175d9987abe91a733e35998f4e9b8ab9a4ba3b24e7ed54571f5cde71cb964f6fdabd367d650c973f6db2b369f98f73af0d043c1c0ca5842a75e2bbad906738b0758fcf2d51014e410271c3903fe85e1623f1ebc57fe36ff82a057568c96de394c42e41e5e6a49234b156bbd64ca8a1bbf72f8269240280ddddafa4a08a7b9ed97035f95566b9b6ddc0e1583fc9bd4cbd7d0a0ae6cb5be7c2bad88223f23c30cca89c9a3e62f045a6f5765048a46cf0ffb334a42aacdc26a6ff9ada55f5ff309be45cf526a8a4db2c3b26ddb8095f8b8223c90f74e4c55eedcc47638dba7d142bc6b9c68ae9aa3d84a43e86b37613b3ef87180e06bae5f564522a4815cb092a1782a40413452215c6ca829ec656824132348b15b1f82805bcd0369a11dd0426c7a51ebb372d21a47e9bd114bbaf222d668c25f71dbbac88c1bcf7716cbe555159b506fcff39361e86eda88f1a04fc53b428c12ab5532eb671893658e842eef0a50670c1f7c67abaccd612e6a6f40cd321695dbae96cb6e83685914383d97e4a86c911160dcfbf402c92d45ca7c2491a7f0340c84cd7f3e11f41a30c6e2919c63a5a8266876dc6373231b57c1d5ebd51328ca61d010ee729124b19e951c21b84389228d2fbae632f2accd638213782baa35bc9c0fa52efb28e9cb49ddbe2cfec64ab8c7e7bbb1800eebee509927d6cfc97bb5ae2b9e749e3e95d139da7de95f4404bb31bac02e1630524c094c36d47c9cb0ba69dbb91c186a8d9a60733498d1d49a78834c09387ed7ebc687b024adead635c45620e6bfeb2fc6e7cb50efd223be5cd518aab14349cb6a02bbe8dc81a50b840140a1d574990234319d13a2e6c44c6df214d7cc4777a6a9981ca26aef2a9b54d322259dd2a38d2588f559d794ea3f6aa1e969aefe91efb2e2e03967976c4bc64ed5699e2ad818e716d1024eed4f6fa6e76ad474be8075872489fafc1f938605eef5a647e835d3945a000f691f101d80a630c2d2109d4f3da50827aa6de276c4a5a082a8245542e797c6cde66f0949765e5616db7f1f31d263f38d921ccddd3a4caf4712c75804197deea6127ec25647cc7890557d19c6a36ee2fcdb093b6d04bf511d5e60990d76beb64e09d10c3521f02c1d719c2ec6681536f5193fb4ad9eed13d1b2d7b9d030c38058e5c9e2ff32837f211f564ba5e5179420236ca6a65530cd4e7a99cff909557b0d214d53b30bf744159c202af05892eb91ef4c41ee637ceb5d923b3985b31f006964811b758159d425747af10dd0fa2286fdf2f2458708a498125618b530e5af6eeaae8c0a2dd2295be2b2df005b966f43c1d623707eceace6d316498272a4b53a6132bd5515907a72d837e63c62c2deef62b3d3a1098411a0219075623b106e9c1f9c599c55f5e8c11d31865259b135bed983cc872d84d9cb2812b95c03dc4e8e829743a3af5d017fd25269f84007c25a3c2721350ab9f551d96e72213cbc026c2ff4a329c5436e76dc8943e6350ec308a1c9cbb84eb4ce441429c25c0a640e143c35986081f11abef6f66b0d6ab012ee8d18296901614cb7f6cc016003d032859d80fe28dad3684b2a50d34332569bdc89a150044a69066cdb0b159b3f56c79afd961191d2b6869debf0620111f3436066647c99ee73574cd5b4e9bd5f40966e9c788c2334f69602fe72d7c02896be604a412f0150124c8963196bd67412ecd1e3f3623bbf4e110ec67304f4c29051ac2d0d21870a0e8de0c32ffc1fe252ce8adffc148b54f512d93b7f8739c97a50fd60782cb7d3b14640921c82d08df04c60a4265ff305674c67cf917feede9bf863e17bb60bd6b14310d1c2c1fa8ec2489b6be93721ef90cbf94b830e9f136c39c9bc32a9c5262e676c61701eb99cea96293790ae7e3e529a03114d9075f65417809822f2e391493247ab3879c8702d84e01dc0842f510463d47552012252c60e4216d42184b2e5e51c7faf3e88ce373efce723255b33899f14d736558fc7206ef94f1826b2c3f41cdb96e9e0a717844fc5c9dad207cb2e69519f437a61f814bb6f8fc26bef7127442d51aa289f870b76543d2a354160891b208e26c45205227dc6c154e622016fb1d63c81e9d90219d3747856e613ce602036ab343be1c960d2e874d66635db6f7c43ec7df66febd22d88fb4b64e2e48d983db281887a164df0a84494aab1001d78a88548e333d124c171f2a3b2064cf2e02b1634878c9dbb5f5766e243b5a15089dd61c502466881deb67bb47c1188608340bbae7767cfc868c6100a33fcf7149287efee2aa7a1c4c42ec0fcd9f4b2c53c415e981e1181c9774113c3324206a73b4173ac96f3025038f5f6da1edafa3b092f764baa9d82b7abd4bcfb37ffd66525578610730f1f03dd9f4b12c87cc2d7958a72fe0192470f76a365ed762cb43018ab084d31f361559f1070dacbdb66ef7ed29a021f76f305f5afee6b177dfd2df34a4628be00c34bd299bbfb542ca67651be4f04905eacbc75c406a5bbac77c5300cebfc539ad8e5f840cea54d2bf749a53cf6c06c45f00412afe47f1a8f2f3d5a5e7f15aa9711a255613f767bfcc6213f1ef197b95d8d5b1aa676cb942eb99d85d0c444c69dd15c09df5af9118b2958389c41ca057e9f59bc2eb7a3e2b017092d57ff81a4f19490e2d7f7e09c627d44e889d7b370bd0d2312893d4c924c3af3b90d509bea096945de3ac93af6aff6d71b22be784c72c93a101970788ec6724bb94e1dcec82171c44191a9aaa500d450051e4c78227e53a7b596b112c39489423f0221ce4c3dfe0846529c7c42d51746897e4bb018b4108049764e860f8419d5df3b93b8ab1a112685bcba02cc86216ef5c28f01548af6ae49bad0756f6dfab76f2fa75d27cdcfc5355e5d4946748eca7feb0fd9cf7c9ca9651a93eb8d0f0f0e2ed0a3c5fe096e35bffde35df672dff4e89ac0e7afac18f6ae2e8ab8eddf92f2010ed7ee2b5d72aa130f52a80ed7280fd2e4b7594f13fdbdc722aa89d9c5f02578fbfefbbe6b6eeca2c51304ea23bc44dc5efe27156f50ece6f64e5df44916a0d67dd5fb07d4db7c876e79a0ab68613b9452eb076fcd529eaf7dde254ac5a7dccda1dc98723e7a156954477f7bed58e04c0c3fd50e63f1357e046757355ca274053715873d4d801ee7a1ab5cbf63b985f646d474542fec1863e32c075831a560b9105d95542b1d8584fcc798eeb84be37759f5db2b8694f3c18f1a82b8f3e716929812dba40a9ef7344b823e9ed0e8abaf22548d4c4a015679a2071c4574a82c88ac8e372cd210405836dba820912437d78bc1fb477af14f06fc29eaad166af164115cb0956548aadf07f5d5739d078c8826d1185b6ebadfa04595bc41f1c60d7ef88eb9575342710be7f5fa743825ea57f2488dbe31124c67cff5a054c667d56b255cf8a19c8903091494266b5a052c75f83de2e9c443c818620ca894d76b9dbb07d8044cc7c7af591264543eec9ee2433d27c038793a40b6628ad51991d50f355267746b1079cd10787d668f1356b640df22719bb4c84f7529320f0d95e9bf8b3dfcd8ec8174a86505e395087a6be9b22ed24e6777ea4081150dcaaade80bd4653dda66c174257de4acc8bfd3a393773a65656093219202bd43cfb56c84ea1cba6f142d7c287dff6dc3fd309b2989d5927ec70927fe0472b02a9c9d26f23354184521672c3cb7298ddbac180f2bb12da1d1bbba55bf206b45da93237cf944a1e7ca00e785758e8be36e7d79b68d1f99a44d8a61aa1a2b276e223c0e34bbe005b575b3dbd557973fb3d0ff1f2d2725f595b342dd6f9af36dd576bf56db54b89c654b20b0006ef40908c69dbde57f97fa7a56d4f88b34d18e66eb94a477a44554db53ddaa8c42a583a61b5ae5ef1e45d582c86f852cb5b245161582edad59667e2e933f56ef42184b749096fa6c8fa342e9521731251d8856ee6c4285e626b0574ad8b7623391e1a28e055a6d57b6f60d2a4dd467382a363a8475c00744ec2b076e0c8722c8aceb712507ca88906ea8c8336c0d99efa93b6d58e6f6fa81b47850645470270dedf317aa6ab874f9f1ef5d5015379b7a44792cd64545aced67ac18d230b5706de2da434a3220be04922933301e139f8d81148860dab71cb42f9dac93771025f3de8e221ddbef7f71676396d51cf6eab4cefa2a9bfe855e54f4087e93b0d09561f96a197a04ed61788c1e9733cc674e099249659ae3d764d1800c0fc1c4fd45256a43c053a147257fe6b96837b2dbad4d7842f26a295605ab64980f9241d5ebdf086c9c48c10fb9c85a95e79f2b987ea02a0b586d25bf98df794c139e4c5c729b867646a61742d953fd9a9babf6084f28d1e7f2966d06b04ef01399fd78046ec8136171d9938fa4203f1f073a5db2b7f2e8a24cc56730f12c1bcaec04a6af0c10619ea70b163f518fbe4513ecf1fa3ba61c70bc0d14e538750c4a058cd044f5ae72e821fe1539db5f89d140c97b58fde172971f0395e597d2001dfa154535f256624fa48250b4e895a24500022638b63440179523f83132257be5d2bcc2b9f7b6854f49b0ab6d221f91a3624b745c20fbde797f5a161f798592d53aa55f815988d2487086ce0bbbc3784d610a4db00108a14a2f6e6a5e81838a61ab29397ce8ae8a1e9381d8e0155d128903a10a52082d84e758a89c37bc66d2cb4bc73f7dd6b962a598fdb9cd2a8e719c37f8da099e943fab33c98867c9e9c74e659a7f5e171891ea114042fbae80b3b544172ec8ddae7c238d4c8551fa0db7a41dd554bc42344e3d8a42a13071795589dcfd0c80d93891df51f4b2e68c6b21f04b7789315541b62b30e48a87c6babedb2274e6d93ce6efb0a031632009382d60911f74545752021b8dccaa47362f854f1fbc7685f41cbac548d6aa8d5115c324e260382c89b0fa113c5188dcbd97be1f666fd897f8838f527c5221a2bff9a39fd805013d0964bfada318643c6ef828206f2964cdc5fff09186f12b0aa0cd76d37182f851701c2805ffb21e3a2b8d38fcd507bbc4e4bdfe618e88bca45c2ff12d4f2ebd5eda1f8c4f1125ab8e7688ac36ab9560f1031b0b879137e5860c26e31ec5c2274fb836be89794a4dde0abbd029eee48bb9e2f8233dc4373b09ccb3037bd8698edb1c91e08a525a098bfcda45878c364e1bf52a3fc8af9691adf1fe754dc90b9e1945bb64d2a512fd0f20bad7a5819a7cb1494e170fc79d4675913520219f1005a6323df6f96cf458bb80dc29e61319405df4c6c577fff09b7865ee7e18950f59b5e6d70b148ce65dca8508eb4279b4180e0923d28c9265eb1ea7ac6c89dcf5c3fd7e4a18a8524f9fd96c80079c3e31af52b7bd34ad399a13bb119a6e851e3b165a267d47c1f843f8b23ebe96b552d763b0ca8cd793dda8c75d42666758dbd44c4488ba5e5c1e377754101d2c09c72708d8c528b49619ce5c768e83abce525a5118c1d158d15293626f100438783e4abbe5d2ff74561fe973f4b16494b7e92ef848652f2642f9f91e26213a0e026134f6aa89ad2c430b3c0c1250658da1fcfc160f84b30ceaa7e89ccb1eaa9417561168f94723305942488066ac0a768ce747181f2cf6c8d428583454564c342288855dbe42b2b8ca4e9444326f2ee65b20e40c569b3a7327d604ef4a7b31f93ce6d070d661054224a04facacdef78f688ce8fb0cddf74aca0e3c6ca66dd61b9641518ef68e4c21e058c4c1ad8e46eb306e231591d8ff7c61d99fd8a7e0c5f554d1e072521ba5f963bb4de42519415c61003591c05cc44880eb73444236840fb8d0bc031f09072a8e3590b04eaed4602e865da703678be5a96703c65066503008de4f72fb82b69432069a049144991dbe4834dd143c02207dc6dcfe4dcaf29f52f0a417eb9f47043d9c6cb3b06209c0d1b61c70ec14ed33027206c38812471f3b9f8ebe9f95ab925f8c012d8441f983d483031834e50812e65750436b862075c19454bb89f04f1c3e4a87625d854a26486e61448c830cc0230aea392bf35b549fd37289c2603b335aebc0e219c025a7d24040b4ac65640127c81b74f078914a74023e19b17866a63f3f820d18f9da4d13799bc57bebf60de88f934ab8a6db66fa3526727a8f1f64a1ce929c0d5507aca2368a3c1104c4537a3197b1840412f5349a309a00751d755de6edceccf5ac09848f5878c218a21ec609f954de4bd6225ae5e4dbc9868799e50b277825073154051b7b3eb2927b4f6f6959755ed68eaf1dcd210ca99109772c0550af674f0214088947ae9f71d1b016414468b84dc4eabdf18f858c813dc5a121fd0c798bcad36570c04018e0889887344c9d3b45ad8604fc863ca9c7a25f3621d64286e1b72b823b9992c68042374ec82b4dd142aa5deffb92fad08dc4c089a81b175a8f37f139c118395eb870833ebf62de63d7e96774126596c810498c892315814ef270bc86985968a59b5323f2804ffc468818af6f978b2460c30cb86e1349b155b1817a430b16a30942a842cdc5fa1c0dbec1d3a6181499acf71b5a57189985e70a3080a5ac8e9e3c6a532b5c30b1a10cf431e2bb3721c41c7afdb4d413ac8d4fda4f71a40847bfe135a1f3902c54b750f4c9985fe61bf9cdebe5a037e926f46550cb6948a661e3b29134e3829e9f7c4b9795b0cbe3e3d71cf28516e37e17f596ed4ee00216936c9edf44c9ca900deb533c4fc78ec76fb1e811a869a54088599da11bc2e3b2b1cf48c63c823181faccf4f610701b43d71e3164969aa0c675fbabf08a9e9a79fa42df1bbbe8a699529c09b640e725c52802ec0fdb000fca0725e1c91150021e4df99ea61822153f09bfe5cc3fbbcb720ab8478d674d4b40cfe51216f36299f4664fab28014af4ebe2b8626f0befc1de9f8b2e73f7cd79dcfc0706979a1eac8f39d31520ed6738be7224cb8e5423a3d88bb5400edbfeb7c380006b4008c5dbd73a3cc99e59a1e4bca8ce9543e41dc3a2b9e9d6e3075c1c01161e0228f0b0143724fa2b847be3c204b6a8c5793c594fefafc6ba423d1757a7061d132a531e10e4c36f7d1bfe0d00c0341e49086ca8b34af1e289d2a6080b54ef87184837d489e1cc7d946e064e7f892867155d86600a9a812ad39754730681aacc82d1525d8c19f98811e6ff60ad4134a9813b5100c2d7200704af006d7ff0dff113b49dd3ca2462343948acde48d1b7437f7f50cde689eb78c5afc4b0234ca450e152d17f40ad801fee619e0a2a9379e2928b83c83799550712351da34c41a30c9270af9e82c79cf69b58d125815edd4621ed9ac486c3a780a19c1851168458f97b611a3ac588150214e7bfab4e6435f15884b44c126409a4f3376b2ed67ca6e45128c17c09b23235561041f7203436d4ecec45c08acf72b0cc01ddad88d215b7c2a069b067fe4b43b712b4b49c5b51f92f5a11079660d05bf830e7560ab44b790a5446bb9874ac4d239ad60a268beafb402cadca42ebf69dd1aeacb1b9a646f686c6e794c8caebcf0726234bb80509d349312dad2248a02e0b10313168e2e34ad308cac14c358c655c2600c55fc23d82a010e240d3ee58158dd68b2e492c875f5d37d6214969141848b044032308bb3d20b0d48fe8a95c7a3ba39d64148c82a60788872759dd0562d48bf8044c1b7e8dd2e00bc92e836c0d497a5289b940a3b9517e90a587a62471d5b7bfe9d4554e417d91d8e88c0d0d4d302b5eeba4496c0411c8ca157544faf84a9b970e9d5ccf26c8e4aba4c6b4824b0bd1ecc41270447971e18f7669b9f85bcdde3ad6c32275169df56aa135f659ad5aa1ddb6717425f83717a3b1199e7724e69650ce0010f570497c860ddf7cdc06d8e1a00950b0ce1e1e5538bd74414f67a1f7aa9c03ecbadff2274086521c13704f5bde1c56e93127787a07e80787fbb89fcd94c483540777fd1a649732489cec022452ad165695167ecb41ebce33be8450d1179e31e334077f5abcd8a2242fbb04910db7389530bf5ef19e8ed5c485f785ba3d34c52046624722bf690d65a3e2ac7dbea0995ce60f823b8c6b1852636acf73ab91520dea6f1c25310beb9d0195319ea4f142075522006be9c0bbc65c792784a948059e1b6edfe972b5670fb254691ba14293fcd257ab92608f9b009b41c24473e43d0a02f06a768c7e0dbf2ce6c887ddf3f44ab48e81cb56def327356899ba31606189263a642418214cdbafb7829662832040824cd0b4234c48570028b8634ed4c16a045b3e8f4b785b64667ee5039c5d18a06c4eb6f0493d72e1754b15428cd4a424b7295b7198496ade06fcf9b4745e1be7f773cd55337e4f608d30436a877a51ae00eac43bb861ba0a0c7226f916f48ab36d8b27abf6a0ee4135cf0a05e0b168946e471835a969b254e77b5c34d4ad45d89a9197127a9025ac4ac0f55a676eb5bb549cb003b1e1bcc7661a639961b5fe1eaff0f65da6842147ea33a04aa06fa1079c04285d7d2e47e0fa6f136b03eed212a0b6266f1031a9148fdbd5850ce6efcf1182f3fd2445a78e2f7941f9f662b63b6dff14a5fe53e2ebb745e5d0349d0b2023af1b087a819965a129c6a6d6c479815954da1a5a3cf3343bab87f3985833e284a13662a8c715137872e4f733867252887df27bb855fad966ccf11b9a0476b44be34942ff7b681bb62c66f3a3b8734a343864e2ae783b12ce6fea8158f255b784410638aade72bb82284d0c7205e8364e38de005eba153de5337bbdbd1d74bacd138fd1e3587b9e5b715c3b4500d681867c18aab4d9f9c82fb444fdba812603261d96c48827449a6077b8d8ab05fa1403bcc5068b41182f88195414cbe38b2bb155485dab8a88db43663be3b3c65768a55f5493ee87ee6b820aa75e74cfec1be82df5a224a6d4c804c165d30fca3cc126c01166e5a168813e9b5d1199645b229fc4ead6745f91a420e5c11bd4c5e1cd15c3c238a50954d131d131015e79fb898371d7e1a41ed51658347d8ee19244a21c3ce950210dedfa6dd3963d68ce034aab75165a0f8368062650077179ffdaef20ac4b999a061215e64aab40075f2aab8497b0297a5ff7a50fe7654b280445a9b35aa06e572448bc6fca3a54c0b25481980f72aa4a6bccc2fbd448efbddda4870f0ba45899b8cde730c4d764a569aa3d6727777aa3d6ef4e7db10c63a3f42540002b7bbcf8590812ae48fa8459392552916e0c51fb3882ffab10254d58cc4e889505a047b207b1d385a1ba1d7d22d219b90724343a7fa3e1dc13ba4bfccd626b158489422619d75ab5d26a2edd61ad8371c37bdf6d1625073a745f624537bafea4111d1fb68ee4fb1593af4548a1b0e7647cb884a1265f7de886fd1b4a64b0b92216205e5dd5f7526f45d625721e932d15aceb40be68608c4457e6d952a5a5a042a33507d09eec838a9f1d31893b93a553c2ec9d34b3cc4696e7aecb612314b0ea5f0243e143e927c0872d5d4a28f8d075db201a44228adee55dc50375336882b1cbdbfac3e86e1c50cdde4460ef1dab6de835d12d49fdd2115cc064cff68b92fe4142fe69c1724ffa2c899df01ca5fdf794baa4067eb044c3c736a62a3818a29fc0799e4a593bdd6306305958930d2553e15e1c0615a446833a24ea4a57957a419596796668b1bc9bc0c320ac4afcdf4ff01231e36262c9e1424049dd1c3e903587fe0b7daac4470bc2eccc8bf9e7e757acc39a95ee435e538c6deded77948a2c55aa06d70e288a28e3577c25603c5e98ea3e28d12a6464405eb98dbe4eaf78077d452e6808d24d090411b96d276e12ab17d918eb946f0c37771ff0c33646e0e4990b93af6029d92a75391886aebb94ec37175199409acf43aedd4ab6ab1c9cfb8afe534d4a76c61952fa5fbe945a0f49534d2a0fb54f8902be7fe612c3f58008d19181ca3e7ef6a8cd0ef201db4850963497e8a85d72a3af2a2b37341bd80df313542daa44756c5850eab92e7b780965525231130f2120441dac129f7fd8f105a4d94dcc47febaff6dec16c367d3e041d10e00b849aff65ffc1955fd1e11f388495dfe2ec851ffb13542aed555e4a91aa562327420b806fbfecb53873d6a668bac32e09e7ed96d19243d24bd610dfa28fe44494a3a508b2940780181dcacfa659bdc08a445a3623aa41a3c980e3cdc136df6c63f696293ec9e3e7ba28d443c2e0439aac39b12a716a5e2231d0383be01e316af52bf380510a0af35a59916f4932417a1ac0e9298625b93911344d4c96824f933653708f64a04aa8bc5fa1fdaede063b0b63acef8ddd843ee3791c66cfc504ad9d3a8b2dc35b3d5941dd4cb7046973037f300295adadd0afdbfa7e478cf0c44f3e8bca7660198a84b62be5ca4d20cd75541517060434e6d669eab4ddbd21484331e5c76fe8613179e2fab65cc15bdb415ce856a834017909915143e17c59bfd076dfdef280c382764fe192516f38b0bed01e342601c36646c82e43cb3cdc0156e1ffa1aba925116e104e6fac9fa9aab8dbff03a82c28da80d603df05aaa246898b803c3dc72e08c1281ac9aa0a1e62b9a05ec0848a5c182efc3db019a9c2f137d2953a3a535fc3693ba6eeda428bd904852cd26c415c9d71d5485edefb88009f87a4ecec610c193091d3f6ea97f6708a29429d480672bd71d97f6669482a1d61b50247bf2154dfa92c876b4b65de9d5c6e75b8a37acc0d9d07509cf1e7b91422823548a82b07974031e4c7703d27961ec606c037f41d9a96d576892cac4e3d99e72156ce1d29b5738a5082924b335f801f583ed2b242a3c935985235e0a1b4026f41d006c089f4b9800ac7320df4119db693f99bc107c69072681150646d652cc19118c69490f5529236b356104ebaf47ee4260c22696d88e3c807204d86583cd66578a0c6cc216c0ad3bde33b51a15174a95c6171563ce6452cc98d58279ad0b932efd13c0e4010e7d12cad7bd4ae14bace95431fb0efd791a00b4be247bea50b349ac4f7442a3b89f6b39ffd8c8f35cec285ff33d39a0eaea7edfebfaaf2cbcc898aa3d797ac6c7e0070d5b76bafa66495a8402e8f1a51157189297c8e939fcffa11a9bea218a3f2c036628425141c6b3b9fa83ecf8c915ef02636cff1ec10a64751fc422ef0549aceae66e13e17b3c1c21ebb6145e29703b3f3d0239f4347468ceef4460f5ab6fe0d94b73f14e0f45249c147e91ef2bb18cd66ffdaa6ee251799a59fd6947659ea96b8aedb4fee50f78ac42dadeca64a7e72b2916ef85751f9c055884f5c241e60eb11877f3ce2875b76c79ae502baeee2a5687d88c53a8cdb23ca5be1f8810d4db9d9fa5a26f241d517777dc4ba18e5ad8f77e6880659bc685020717004bc27dab398777a9f600b3212a7f519954799384cc8f3ed0bfd0a61339d04a25e0750d2df8055d6bf45e1d7c23433566cf5dcbaa4852c1145cd43ca3bb8529a26759d610c1d54ee45c6dd739c9be619e488675577bc093b207c55270bbb311324a354d51c7fe2fdec31a58f91a3aed017d4968676e8f767d0b9feb70a9419f8a254af94ab9471c2655cb9a700844babf7941a98e3ad53c2337a83a33d898902f30f83e9fb0546720a7a98c26261f0dd5c7b842192b3a9092db54dc7a888dd8512e4038f90d8b3d27d84e209ec2031727e3da96a9904761d98217ee80f413f3a6a641ab4a37367424014707a9c88a08286b4576b793c5f52c5d167b9659a7df3cc4898cc70a39676f06f61f72eef46a4f3938ed9485884ae249af3ad381c6bbd836a61017d59c73714d6a26fb679acedee7458520f30ccccc01433637e983ec42614c568056b49981cfa1b61dc72c2461c5a2f6595c0e8be843ff2ae9097620d568f11cbd8eb2608cee2cd9d035813ec407d8f1df138e5be328424281ac4182c1a3333c3fc18ee2ecd7b4df67641ea38d1cc21d931620e46248ac1ce67039a022e62bf63e89d1c98eb2e6090cc49513c3eda5d1e1fcfed77b6eecc37bf8be1a9ca7e8c172ebc8c3e4b01c125fce7398087e960070d7297c45e8ae909e024c9e0fb63de00ccd4fb16faa83c319e829757ca19056b1e65a3c0f7a437afc2561c878858830c97f86819e46db0fc301e98145c1fddc2121031ff793281f13122281d4fdf3e2fd9d1552b025d01d385e6cff72dc3f17c1ff9fa924114a2fbd335093a174938566d8d87f8969d69106b2bf638544ba45e1c7c4a8a74957f3893f2e484f0c9e98dc584a5d7106c5738fbe6a8c8d01450563f17235f33000c380713e6147e53367c2a2e844b6fc0360fb956f8f51f5f4e39adc7da6d3dce2c6d8a7e4d9565398ce0c9e74bcaeb1aa50e7184c4d6236175368c67a137aa2349cd39cb4c530b1e0ed242c3ce59ea0269c57eb45b8e2ac929193546cfb3342c5c632696306d917c35c08c92bdf082bd6ca71c5560f192a098132e53ba0ab36ed4efb9896d90193c307300dba261e0ebe113dab96d9c96f54d0f1bba23cbc606fea1e143782c114a3428a3f706dd98b0ddde52be064a1883eb36aaef9feaf982f8c2125b92afdc678eb7f71672be2a8b3098d71bdf131e4b9317826959b6f984621e6cc2df3df08343fc7901549dc0a4cdcb16aeec472535a69826572a9341fd0ed1a203028fcac49dccf155f705a659505af3a6948cd23401b311b2ef2666735d4bda5ad9d03c80e6acccf7ab8a92d05ada1176594427451892291c1803def269a687e36c0690c02cd0bcbc5d67b28a33d0d49e6a2bbc169d9d8e2a8bd2abd878dbdb20ac7ac635c0e0cc0793c882041c6354f15b77c8cc529c8b8991ef306cece5ede9e7ae8628eb671053298282a1ccfc76be23328de04f1868581e3bf2ebe0fbc971e7eb74cf62b63b6aa42023771f1d6dd506870be4be18cabe7d861c3bd989f0215d9bf5c886f3212718b3d5f46f0f29fee35c11dabd60eb095d0567f10e6b55e782af0ddc791767906c93cee0e290fe77253e60cd5d9c66f12e36cfa710134023cce53a9b53602e4749a87fd79e7d5fe90a1a7193f0a59e756e455764ba988155f3a01f7bee9a3ab644af95956ac47fcd10827f4c5f1940017b8ba97351b210cf4593ebce748d732671877223f9c86906bd249cae3930053381f0cc80273886bb556b1250eeeb255876ca638dcd5b3844f335495902b87116c525384f0856cf821ea6c1e1d0c11611de9089cc800c86fec976862a34bab8a634ec771ed35d0a1c70601ef88bea53ea691b20f8da2c2742d850672440a53ecf217df3ddf40f590929eb66a675c4f7bf9c82aeb69f3f672a73bcf56ae5b12d2e6d689c116d1c6306305cab83e79c18c4f2961c7c9cad5d7b758e92e4674d1982660199b1c4d92b5679dd092e00bfe6fdd45f8e63150103dc3181feb186d80114eb3dfa917cc7ae73e9bf4505d4eede1f7c11f929c8220310593f467634f765fc33aa0aa68f999ddb5362a7dca89a9fbbf7c16c0893a8d19d62b56556529d8b922253d23608d8b99916dd0068dcf923003b3af91dfa246fd2ac472d5046241c9c0b58263a8a769e6d03d6dfb2b21086dd8afe4fe32043a63d5772b769012eed2c9579c70eca0c21bc717083050eee374d8da74109ab32eff2fbaca863665f3d8b141cb8166d55ada969b0b3b66ac130045b3115144baed82de0b079b4caa2face3ebe2dd614677ddb4e23c9a3c0590f4fbc17741bf2e84206fb1f9aa7a5f62f83393b236506ce84823d6737771967202cb4694f3a9a3cb5a65f9e8abd7067b83d3513068a735e7ecddf8860e62a08dbfbb56bc99ec5cb44adad8aefe0ccd639cda40610084d8c272d5d991c220df87cb09548d2b05bc2a1d99ee74f410092cd76e010ef303706ba61c13236996736b529870e64b25806450c715a6ef88d7ac930f539921b2814a288c592e1957e80e5d0bee9c5973e121b75fe5437600974dc5aea79ff071af110f1c6f0641ea5f7992c6f5591399419bf46f1d00aa89ac9a67d26e9eb7b64b26623bb2aa0ae27c499932a10b4ea7784e0478cccfd3723555bc1ea5dead605e2e8c951d185c5066a4b994c803042d28f46f93b87199c6108a7015d0e958920c53ba6b14d7a536be32c7e10c14c21df379b7c057a85be67a90618d7072207f36febd7a1786d3c0ea9e094796ce54b8278c1151fa3a331ea4067c092f8b21cd239baa57f7028101579fb889ba2a6a3773a9706fd46eb51eafa87bc981ecaff7d09368e9ea501d344f54632fc793ae238c983c74c0494a1fbb86794539e4da263018a20533fe15851826b5c91bd14c34ba59f9c253af20d77ecefaa98ce34329a4d5b6e80063bfc39c9ff565c9a0857c3008dc0e2f7fc7221840b208d62521f56eb4c29d97de4d38a9aaab92d953b318ea0d569022c98f76a020d58632798ffd2edccd2aebd63fbd430008a599bdf468e08748ecb0ec1ff18fb82359dcafe2393357aa4c0c45aec99fe9c94f5469e94eb08991e4658265e0e09ae177d910a0db07c8af4f128c46452809702def9559fff07bede948a06f6d611852c3bb76266c8082d295c951596388ab9190f0e11d00a858d8cfcefa5d8a2157c8db778d81d7deda7ef00c98ee5dc7102f3e9f5d8791df870d9f20332d9405f2cc7cfaf972f6f6c143ba8b78520de3bec55a5900fc326d418363155d15da522ed7619623dabe31324ed5fc17c1acc2c8b45693332f000c28db4ccf68eebc71e0462c1bb9b5e7beec50e81c7d8cc5680f75d77ae0ce0963016e52fd13d04094a808bc29f92cb501e663c7eca24909219574ce832b353e954029504d90891f9a8443f079a408f167db47928e9ed9497301057e6aa2940c32723d7c0d6a647e53bd08dade58c0e758284c9d91f0c7c5e07cdb52e79e03f486a95b1506e74395bedfda26b9fd776887ac888008eac2d0bb1d50ca2e97c8a1ec99f022d28ce4d79a7890ed85d4093e8e94d419e6297fd15325b8a79aa64991725e21a1fc857fb2c798b7367e029e37d57d1cfe3a0119a03b119fe7d05e93379a59fa47cccbd8e3df3c6e6c25434e027151322566c565a31705cd49e701696202ca567952e96fb002066c4ecc50c9587bf4a1c197f5f4f360db541b0c0fb84e81c6453a13d221d0aba9324b048f994f7887e2063d8f72fde769cfaeb9ffb6f359849796bf59919b38aa86c3c9f96b39e40810f833ee6f06d9353fd4e81ea8f8dba56636a8a4135558da35e60c97b83acde92e49b86bbb8b10f9c38f1522285e2b9a2bc5ff69751f5f7e100ece0465baaf515d2332c6f01dd4aadca4adc236bc986588628654105b955f7596d23f933a62a9d489df54ff0bea7a403d9e036a48204a1034e003dc4990c88c2feab7d6b1ce8be48d3225dbb4de353fe4eeb9642d4fe4b6d79d53ea69806757a254199fbc8d66ad13f264c324807e84d067fbfaf7005ee94118484055dc5a7e8e4a295613bebe2c311396e297adf14b0f2985dc5c1d22720a4fdbe922857dafad63ebcccb0d3860ec4aec2bdf0a08423e1752904fa99b364b07e47e27cca5731f8d1462c4d286a997c715adcca003242609ce603cd64611795acfe0a37bc1bc1a855fe6ea12aeb62d7a51458417ccc15bb72236a48ae4ed05e750a7f666af800fcebdc602938f4f3556b2e8cc1ff023dffe33d144708604d62519c22c476156c610c7e1384848d92d0154c129f498b534712f8ae551650125f677c4cfc52a89e2ab047987d91c16583c4f39ac8bcf47ce471b7461c38856a699bdec9df8b89371d1fc19917c8260cab3eb5b12a1a3f413fc6613838cc155e1e94f0df21655c8d08f8f4e24f77806d518470e36f3c3dc2f34b20d5a511ed1cb82bb477e890c6011854b9e4d866610797e216038c140b6e096d127548c20b37b7a08d9af9bd674e01191c3456c14f346cb2af1fa6188ffb52d598ed656d399106efa9074879e46301d5654d60b5ad00759ebff3e884906526d9e219d79b7735607640ab18abd66b3859456679f0527098872db45e651db998828cf656f442116b05ae4fb46e6508a61194d534816f8d37f48f175e16ccfdedd9af7041fc235c35746b4f072dae94a351d8b04fc79c31b6d73db42cdb597b43d03fb5afeb09f4a0b014e5024fb1f912e640fd7715f4e344a6956e427a52c0dca1cdcf6dc471baed50cef3b0ff701681c107064881d2a34612eba64a75a2de6431dad039b106f2198f155149b43e4d745b7e81cdb363f3c43a90d736f38f2f6a9807c97c4cba8a7f9fde6ee1a0d6614779fd9e034e0ba5b7d8f1cd2f52156432a7d43d3813990f7a21b2149187788550e39119509fe8e8ce58351229fc2d5393bdfa1271af55145d4411d8ed0163e4d695ce6fc389f28427498507ddf058ada152c89c6df26469e0884d21b3039b749254d7a5512f39032f56d3d87145e6aad8d1e69729727460944b2fccf31ab8ae1100bbfa7f2711bafdcf4fd57316cd4a20ca29b15e9ab7666ad8847fde9d18baecbaf941e26aee559a59bbd958ff22b38632640bfc0e2f130686f009dec67f585e31d6e7b6bd665ad1dcf8730a3f7e6af7aea9fa12603e04b5358ab3c87422afa6dd8699b6f1ee2f12624305531de5b683d16f20eb883248bd83c6cb722354cb03bbd950a377b04652aa809f1b96dc524fc72284eaed222f4eaa46f52c3eb46fac74b2f0c3669b7e111d989602cd671705b39a36e459882b27e9272c430736bf99997916c1c89b31998ea5fb055017d76723703329912c82048ab9accc82e976ae7405c77f8ac40c9a707fe264ae216df9eed6704d8cf5a4ab8b306a7213f30d698267a417844ba90f9c16a4907fd006621e7555f7650cec97a69d8c9a6076d45ad065e6f2d1ae94ecd7bc109f5665cac71e6d55ecd74824bdf5989999014e295fe0de0e225f15a3ae4ec64f5f6b64bf900e0242bd38f676e8c45aaf1f471eae518ced357c7ae543db8035907f284e61024892352a20609ef153011450810537ed30601375d08904004b225b0b6cbeb46012426cfe7bee0141f9cddb85d8b77d23a849790ed214f7783efcfcc8ba50a61447eee8b0891887c2d51fc2c84db43617b1b58df2b51f5952111641d97ee0883ca084a92b7a8240c18eae9fa3e4db3d13d8d4425845883c67c3e448503c09add8b2923bd5100500a642492592118bcce9ef231dbe49c575fb51747c7b0975f495c7464da9ae96e1199f615e9f2f0c81c1b0d74e7354c028abf614ad2655a790a726f5693388cdde89c1fab7f818d02fc71893d8f91aafef579e035487e8715f4eb6e46bf7fce57536fa3d5a93d2d84381f7cc0d29f343605411b666932fff84e299a03f6e21e51551377c8a40b0c71ebf50730316357d5fe350b3144b8532ee124fa6ea48e17af81b9a57ba8bfcac9d89a41ff151e77a96e36a7ba410a7502bd3da5bb88ffcec7b856f4b50bbe7ae23026f014dd37dd7f1d3e46800c521d67ff8cd6021cef1fa8aa7516d47bf6e32c04380fdb8a353c5ad64780deccaa13ce21153f252153ececc3dfe247d64d24aac1f79b4da3c4486494b9b30ec2ac6b181eb2cb1f58430830c3ec320c13b1af121f8b8dcb2feeea81ab0caa5133b878200349232bd571e240568ac4791c2bce92afbc32ec7b51da103bc7c1cbc8fad174e2fba7b8547bc012dbddbd940deacefd01201f3786119d7138749b89a8021323ec1dc7d507d14aa834a65ebec42be4d1f5d40340e67e0118253a54e71c207218f4808e616fc9d571db0e66f2bd832985c8b3a0e1f8d8cd3c28aaa2c9762be80af0540299d95cad6d4802fe99624fb057b1362faaef2f9837dcc541217e42e503a256cd6dbfca98e9c3ba4c91f28c18b85ff2c0d7e4e03c2eb68b2e842ddf0a4186dc648d772097fcf0fe68ace0fdc9d5a25babe0468b65285cce41286ef321cc7e391cb8894e0124af3321a64dc70fb9011925c542d8f803b2d52d6adb04d8110f9d7c49323c9e2b897185794358b074c04177ec166936212f09936370393cf4ca285ad0f05768453470d6e510a613e820e9f8eb5e32d6199a12cfb1551dce39747b81c51f6710f298e5da4619946bb937b7cc8e5aae458a484071175ceafc49c397c6cdff423d891d1c60e607001a52c0ffefbb6335a4249a95e2078fe8968f4028695c7e1f7ced2b4e353c610dafcfea7114217da1838e5d01a1440724c93e006ac819625fdf5528b7d340b407de4995f6461463604b1fe457ded880713c4613f6b43d669d3337ee5581ed59f22912474b96dfa1839aa0cc9737ff9580ab9ee83300bf7a6df034c5025f70a2b7573c92616f0a13696a44662376f51dcedeb33bb1e8d552c7aad82da6f46def9db7317495b92593f849e13a6cf714bd4338bad960953c08903ec280af831c9afd96d94f016d8e0df2b9fb88e000733da6d7507da650edd5e6ad3a1bc02257f7bfc27aaf2cb82b121f64ff118671ede3956db1aab530f2f44485bf7861bf10094ca6e66290e50213b75c0741aaee26b1453711d13d9d3b952d883bdabff8f9d1f8c3bd0836aa9702754f70ce51605d1715ef543353444dd30e0e909e23917f13fd7eb8f085aadbf6bc6ebd64696b6db41ff1d3a3de65f836afdbcd45ddeacf6b2818cb1e8d1c1cae7ce02f09d3220f54f8e284cb174180d51a86d979bf78563dfd3060e1a96d44cab9c69e72832f759eb6168a2ff68863d00344d60b87664254b5ca882def701909216c75266a2f01a23cb668d022efe2493815b61d73151fe29e4ae595d71b2d92a8e3ba2713ab457ae4cc82abb7a180c11138edd1baec700966a22c99684bc9512fc8b296f30f279d37800ff2a2e244fdc2f5463cb5f021f640f7bdcd930daf466e6e9abcf8d18e5673f23dca72c2345bbba78ed78bf04a76454140359aa64b6f8c7c5ca230f36272f0e52509e69c1a4a0d256ebdaa7344200ec7921be9dc7ce4115f60184377d7b878e5b04f9686948f6b9ccb485b87d9da269f81e147eb88c1d8ecf537e49d499caa5977c9d579047f6f84ba402740d614c628a02199b1f3370a461e7f855983ff1550ed8f2b3df22f8475450ff212c4b55ae540b516dd34ad6ceed32a5b926824c2b5b5b95c63d139c84585f2d3d83e941d882a333d7ae5934bfe4310ae84f3aa2572bda09099f9445ad0fed7408f4dfca61d5bf90aae67a5f7059cc3f657cf3e042ef1ca43ac6c15cd2a221f6fb241b7ac765b6e9580c64679ac1eccbcdf1f15c5fd9c7dd531685c2555ae4240b6662cf98af8e8ed0ea48eb2d1dd96ed32329027fc1f6c3d0f3b6bbb3fc620cff88a4fa03d4cc040b7d366fdb90a2b66cb3966e1eeed47701b45db04ad75b823d5554279599de97105f7d65a02e4cd3c8a667df1df142d89d5ed4a30c39d057196a3c7cd0574a59cdcb72aaeb7458a7b133da5ba7972d644a6998112ed068faa3b4be62211487a7d6a4baa174d6f064d6612d13d35186a2c3f03aad55b23eb0d667bb9373fbc3a8595f8604113f18426d90d4d517418828dee97139ecb0075914ed4b849fc5d3ed56c3d647a34ed65bbd5549a3ccf5e3ca3a17874fc6f988a6980ae6495a423ab7918ec66b68fddd8db5e1cc0f83679a38ade4f68f0bd77df29b8b818af80195362228c05d003646d25e811a08f86ebbd44ca85d9b78c12f40c740f288058e7b2fab33b22cc50240baed6ce6e6a3fffd2e8b65140cbee9387a54e809b81c4c26518c85c96dc410112a82c134d4e24fbcd82cdaf0c3d5da6ec9316d2d8eeae89fdfd6cd79e5c1603bb8b4306bfe7fbce4be514839225f77057e2797760d26e5ed7d8710090089c90e1df11c41896641c5825ec257ec58e892546e4e15361b3388b37a0d331718e951384f00b22e4c17b5c27c0a75c85957a748d5ff882f5baef2ffade51aeffa01715c41d3087962862e04cfcd7d3cf7a83b7f813981b13d7953183fffa4092f19370634e13a545ad29e99369972c64f56ec4a283d347ad2aad4c72fdb3366a96de7d83af1869e20e80cf22422f29c9ffce4b3d652c05cee1a93d1048935cbce41f022633e118cd04bc209eab4eb84112406eb5652efff76e2bee2fff10e3b535a57e5895c823ab5dead3b3cdaa09741f6f2b65c8f6bc9f896137b40a6b7559a7d04b11573eb2d17efcfa62ec252d852372c399f213e95f5742e0adfb8a2b95ebec1b3bf674ccd928267d340363f662374e37b38eca4d4506c08b7b81f1da4d03313ea71e685e314eb09d69fa5eeeb5bcbad880e0dc7972d895a99c595daa01fec9af7678335b7537d171750a60c70f7bad757e9179f35b0ed212b48c7b89bd0555110ab5a805d48026c7176141be4c59d4176f5b7aa1b3fd9603c8602495098304b008894c3b249c118658c0787059ddedd2294d2c394f251ccd0e64098c8a331979338cc48f1fb217657793de91364c8b7568140c3862e860724126d4d31b45c56e7d3b120551afffaf04d2ce67a086a047e37fdca296aa54c2e7893fd44b81ea407383b0e97afff8ac509b6841b0af544fd32a8488b1ab9bda772a3660d06e18369ae2b1474a9ad9fff688046050b11b1db157436799bb997132c7ced0224b1492d206774a8da92eb7b52d3f75f5b1473ac774a9bbf0265018789e491ae6ca91b5fb0ccef2698fe64fbf6dc97b5226d4e3060af64a85317d5c780cb80fb8a5b1f70dcb01a6c0272a7c24b71a149f88abcb998fbbb76fa796b532f8d18c5906b976288058780eac53de960f836316a3d0a099a1db656e1297d99cd5d9fdde291a472a334b48d2e20e5bd1ca9819d1d26f3766c8ed38fe57ae619c2533d1ab75b968d16c88d762a7cf2dcb59cf5aafc556be32292e7a06588df62d51ad1b6896ca179fdf64617880dc50564a692208fd82c621ccb918eb45be5c715633c1544f72fb20d446ea0b95db47e316531f362776dcb04db5baf394663f1075d392da1a6f193ed0ef7af8eb2ce81a0e6434cb741f98f068c1952c8db03f14f53b4208e08d3eb8a74886986a4abea922659319c58f90822639fe6691175675b926e24430fc7d539cd2d046aa5f44bbf478857b01f67e2d17f192979a9675e368850464b629b97d1e3b1df75a43cc490daf2cab25dec1fec692b30bfbf4da0ec029165ebc66e31637f68eb07ab1c136e103d1bab052ce95941939865bbc62460dd0f29ff44a03d67d7d8660f1b956e94c041fa2def16be260bc5e38f80b1b6e735b14809236363b36f501d8ad921e6f05938b80fb1c5e4625a6d8f7f5408294bc04596621566e5587d4beed45ac81d92030801faf7802a5bc3273230fbe4aeacc01214f0c340cff60c3b4138d3071790841adf613c2f6d81e3c9c660b2c6c1c0931490e3f4408502e019b4555a9699c49625f93d1ff579681b82d1fd60738de647552d6a9573a234bc506392ee31a6b842aa2a5cef55b3d8e846727f1f8e9b8798afb97754144be0e57a55b68d9073b929b6dce2f94bd8ecddb128a951c0fc49aa3e491b941a391a4fdf89657e4a9d461aff5cc28755e3d55e5ee069e11ed5996544c18924353f0006f2d511f9db950e1a74b43d7b2091e013c9a48159116d77c70645347bcc15ab1f8e5d97a87963c2e5112b0f8860ab9f5953b9e3ca8f03c55f93db9d538c7ed30e3a4aeefc95126ba45f5c7c880cd31d94a1133c218e84d66bcaa800c6320c3e2000379b42b69ef800c07e95a268a44fc1da033765e2fcb512a631edda258abd1b9fb21fa4431bd2fa48b3a5c02c95ad5eb5a2d4bd5d72ad6ad087a1ea5a795122da5251ae4d2c54eb13ff39d1f521b7544f7f17324825edc41c69c34361ffa2082b7c0ce3c221808aea2080ab688b386cf4a302b02e81f916d57a97c495ef157021e770354d4fa8a11eb0f1b35d8e61c4740b7a98c6ee94c3b16432a24b96805afd735b29cecd529d1b046db4e5fcc67c4342c8986517c892a8ed99976cbb8f14edaa00db96f65e4970496f4118f76080cf32438bab62608594afc134535e4746144b84624f1b7c21f40d12d6e1e436a60fddc508d90d455baa57828a86e9963d10737df3c4e918aa03e98593773e1ae69bc57f612977e9739fc0683da1bc2dfb385b76571828a4f4cb37e5cf3213744beaf7f5a081e8603498aa5dba3c0469b21f2ab1911dcc02d5ee9635e33ffc4c7d26dd433185958fa0c601ea423c2ee1b47e8c9293ca4a610da5a4795a5b229a50644e6c2ac786da4f62cc10bdc1a1de4c980db10a66f3c1185334bed14758ef170b49a8e899c4fd9dc1f6ea02bc06cb35ac21073f11c5f8c30ff45e08620037f1c68e6098d862600bec31e9f0ecada94c188c07e4593e830f91b5042c250234ce6758de6084b56742834d57a0eeabaadba3b7067f39d8670aca2b53c3da0a6a4ad5546da150f6bf6dd856b4205025e78f2ee93c2772a48f841ae2dc52aa379012a1b678965fb7b7993c1910d12721430735ccfb1f32148f66446d8dc93f8e060e3857b56363d24276de56be5e6b9eafeb38c2c6311dc603ed03ce5b822507bdfa6e3e9d322d100e619fdf0a0f1f2e0ff56287824f8517309e192a6afe893d2add87188f937b4ed2984b362404e7035697ae549b63d8e16461e0203ff36068fd4f82b819ad5db0bb102ff0f29987113a82ae7acd381bf8f74f78d9493b7baeb072b499aec9b5858e35ecf49a8095ec43a5d0ff34d8b15bc28814d8cf136effaf4da7efae2a320b7f82f3ed73f9abe74d441bbf719425479c39f558310b93b078aa2a114f1052bd5f7a1d18188d45265fb568a6da4b163e9739f880bf41ef324a5b7586ef45ccb0933e12ff91e02271eaa4f299294ca29ad5bd4543448fb722419e8d85fec32c5d4fc7b18a0d1bd64bd275b02a4a8f6e92815d98a6c2dc0303f3f91e42392cf6c4c6dd22b7ad98209e12db588b5b49830dd2aa7fe2531fccc978de35a90fdc69b4b23319308be01c7329f3a74371a7b5e59fcf60511c00130ff57eb04c45e13d565ba8aacecdaae95e3ef8e0e5764610b4b6b4f1e34cbe9063bdd8615aa8995457bf44f1cd6deb676339adc971bd9a043cade7596d67db74a04d54d08ef52d8a46f58bbfe233840e9165f60eac0557b4a04c6b0935f6b9fae9f27ae0de1422d4d3f579646612025018d0742c107912ee4be03aa6787b15720d0ba6dc6c39307b5767a36befa80711d1c4658a5e30c0555020bbc265c8c62c13be98bb30a51dd619ef97fc1b054581c94abb3db4eeb31b828abd30dc795fbc5cbeb232969f86d64646d646d6577776dd76c6f29a50c560aa10bc10b0fe1ddfc3e2413abfe12abbe0d3e31016e8b747032fb1d299d45be74f274495ebda1df91d2676619f971f253bbf216f59c2ebca926c9efc0786a1f1cfb0901c77e7ee01dd325223df5d43b64d19dc93b7de539c01e78e0c14f5ff989a9f6e01e649def53a954aaec9a64499ec42e1dccd239ec05780bb3745e80c3489224c9f11b4292aeccd2798f7390593aefb92bef21edca5033933b05ed3a89c9ef4de7979fadd65b2ad5e7d76aa9ae524d575652f5f77cfba95479d3fc8973c62c9d3c42cf79cec17b6496919ef3bce73cef426f07a668ea2b0a3dcb4c69a2e957caf4078bf998668dd0731ff791834aeff9d4943502cfe7670e2a9de7b3c78ef7e0808303e0435af5e13da4bf77954899c9cf6f48eb3eb5c473f2d8aa0fd7cb67dc2abf453d4b57e9fa741129bfe3abaef36fc755980400bca93ec1f2bc844fb03dc7780fe91ed7c17b4873c0a3a46a9eefc04aaaeea15fd9c1a707f31efcebe02516b507dfa2eec08393a607df3af8fc8878906dd17b14a0a7036c8bb03503c3168d4d535ff41bd07059dfb668c7bbeb79d58777d627de9b66bd9b73b2ee5359a7ac7fdebd77d72bcb97f72bcbfb0d99deedb7d597779075d6bdd209abaee19d7da9b60c127bd234acfac9ae3cef3ed68575beafa63ae7f87bd3c92cbc7d43c877f3fb976d91cd822d1198bb6d11c5c1c1b14feee97df93dfb3ee707aab22c0fa0cbf7983f7c5e3eab3ee64b9c8780712e0407c12a3c278f0e28085497e5eb37a4a4a23f6cad1918f9da644533e7b75a7b685b547d50efe1e96d9aeac3747aabc6e5d23be40eddd976e8777660aa3dd54d78675f3c13563dc453d32529cfbb0bef98767d4348bc334dae5824f6cef2bca2d56ab57ab7034fdda94e9e85774cb3de596f07ab2c310e01d5f3cbf33965d94393ef4a2c3d015dbed1dff7bdc8d4df63bac41b53e0c3e551efaaa7c2adcf6f0a61ddca1dd00dc897787ba0c9fb58127b676157cec4d417cdbecc0f28ce7bd3c9fbea9ccfb9e773dea4ce794523a6c6aeebba8bdd531d8f8f3ef27862d31cbce9b6453bc3d9c15bdce004c0423d597753ac13e94c6f992e59e26ebaa4a2e9ba2e7fda1fdfebb56194b362349d3fea139a183db5327a6a45418484e0f343ff20601e01b8fb0feeaef19c3e78ce10707721784e9e2078ce202808544f22eda262e898ea03009f755f974a25243ba34d2ab56890acf27e91795f953759e67d33ed7c8841f7bc4c0f75e800bc7c86466fbaeba8e7da8876ee3a0ede318df34ef4bcaf087eabeb3cd5e93755de88be2165debe21b38bc9837210c7ddb60bd729ce55a7b75df4c086de16551fb34c0f6934bd3563d31499273fef8432a14214eaf41b92f36ef5f90dc9f7a965de992e4f9e7e476af955b993b11df32c271399b93cb9c2568c92aa77b22d238001f0fcf52acb6fdee7f3879c9955429087f00708b94f56c1e7421e4256010b90cf855c85101ee4f32700efa857c696c9ac185bc68ab1636c996dc7774278903f20841c8007f86421f948f446a285607ac7ce8e9d1d1e9f1f09d97bbebdc4357bbdb000cea38747009fdf9001e0caa5bee805803fbf213cf7a93bbe9377a677c84fbc7bbe5973de5d08abccac12825cc881825c481ec2527e68da0914e4422e240f553496873e488efd94795fcfb224f1eab39c391fad4a12ca07e0f8b6c8ea789965a4ea32cffada39eaf93e76a72ea1df815f3cf8852b9118fa93d5a079abcbb22c83265116a22b59f60934ada34b97724b972d5cba9438045497af59b2907f25c235cb7725d2f44aae59ea8b86c0ea329f40eba85dbacc777951fa89691d5bba10d51fd90f7dcdf2f3c5dd35064de96b0cd5c7ae68343da575680a05874a454ab582a6aab13f623ff45d96bfe3d3fed8591d66839c92ab9d1d590e4000b2ce8ebcafdec97995bfbc5ffa050b92f39973ded96f08758348d5e491e8158da3fa20f3a69a3c0de17bf3f9befad3fe08f2fdd2e56f7f087979ed83a7e5c165ce7947621a477dd1e750f29baea1a91bf7a942f0b43c41f02704d3e5e79032e7b4fee4785f919aa9999f2e28a5b4bee6e9a4479d7c895779f7e8f224de4080f43cfd864cd227d674f9f2e4499ca4ccfd4b3cf544e14ddef5f90d590100ef9c7e38ef764a15de54a34ee27d4d7e8537d5ab77252e3275f9ce7a3b78f5f92d60ea52f5af2c4b55def3ae7f44e6738ec2aa954645ab702c072b19e99dbc05413770ddc76ef5e572e5acbe68ebb688ce4daebe2fea2bafe37d92cf96c86edb2aef7b37496f9fbcccf964de24fd6d9d6e5b99f7d5ad56ebe0eb0583b5be81b430eb18db6f88ea1f9ff316de31dd3ace6a45561faabca9569dbabe37d4eb052bca5bc948abce7aa7c2240bdf175c15a5b6e8b4fcaefe3ef2aebc37f21e7954dee4771fbbc2ad9718e7243e323e27e7e4e0a971f0be4efd561facf2f4a4ea1bc27a1de9727e1ea340f5cc42e35b79c7f47816a67a54bdc4fb303dcbb22cb7124d934f7de22d04d3e4512a92fcea65b984288e729668d03c5196e52cbf0f4497dfaff21b567e0329bfb7f2e537597edec79618f5895327f1d4ab913cc1ea1185e71c3fc7fbd42163deea4bf4268ff8518b3fe5bdb5b4785316ef470fef63f73d5ca4e948bfec4d03e9519e58a847675fb2313e30dc9d559a953940a53344d1513a9118e14696263b3ca1bbd975f3cb324db34a2e2de25d4a37a8e16e6fdbc696a67d831aee68ab3ef08ce98d7e45e8577a86f790ce6277f2e0444d378ec4e56d4836d697a8ad6ed1114834d3fbd8f90dc9c61e4190ad2153efadb56d6cca4489218a14eb6172a3253c67f8f0340389bff96edb7df7819955c249cc2aa8e0e507882a98f27c62fe64794f349a52ede35e3a11adc88d2ccbadfa22c7d1cf1257cb5b08497d7d3523eab6ea63ce8f46a7d9d54ecadbbd5a3b0df3c4b1ec04b5d61cbab9a36d24d8cf46ca864cfa461a31a091028c2cce4c11c01275a001431565e0282a63b4065b3758a049d10317210cc801a0ac8192464b573f772811fa46d3cece4d278f22568f3f4cdc4d6abbb7bfec8f0bc4feb84562e79cf4368e0adb7489a6625be87eb8b899dea93e7a7a6462ce3431d3ab1f91ae7432a53abdfef5249e93c7bb0aa730aaab9834e2d6ef3b8ef896a7f4899ff6c7e9e3814e1ff31096fa6531ef0de83474cb53faa9db4ab4edf44a7d597b0ea2b87489b51fb0a3fae3da6736b3d9694421b1da135a180a02d55976c2736662f40690ecec5340f561bafd4efd81ba7d4ffd91bafdde34e9a4a7f00b856fe5e16eeba789c13ba6c15d9fd0f5f403df5151145f646a318b8f695dff85bfb18b95683acc5a18bac1771f0b7e99b55ce99bf4f2dcf6ddf0ded1a3de421ecd726bc94bed316aea21d1a35cea38fbe68ddeb67bb5ac9437125dea0e7080faaadce92908a36b9ff4878fe5a9f955b95cedbb8706525f350b117e7ed3f23cc0be79f313e60f342181c9fdee3dbc782c401704022fe6a179f0fbda376f7ee64fb8fd01de76fbe68df6d9b2bc495db72e6fd8be8485603e55bbb6d16ffb14ca23e4ccd042143adbb0d16834fad0b7c1f468b41ddc907899551aca3b4685552a95329077300f79a5bc4fb086defe71d9fca6f68ee013ec4669e858b0953c0eef0f68ee94d26f08573a87956442b04c01665c7b2eefd8856dfb7a6b178229c9f47652de99de5e7a02c645775f479fbcbaee5f47bfd16aa461bb6072e5882e66b88c41c483086cb4a0a2868716a2707397fc70461b1a5628030bee8c0f6a6c3813c68c1534ba70660210e5054ed64861e60d1c3bc074b0c2491b3480834b18311d560083c49b22226090028ca9468e30deb8610c1821d0e0be60b530a68a35558eb82245037898218a1b32d0a207388e488306151aa87993c5192f2ce084055ec8e145146b50e18aa074d144126fa05801050c53d43125082f60ac408c0caaaca1320693293738d1450c0546a4008618d424b164063b466c851994b8418c1632675430c5024dcc504710536eb8b2a40526a0b022860d0a8eb062db8c0153e5851796c8020e2e6650c6851ac8b0450b2aaa7031023351ba5851a68917da6cd125ca136268f142460b0f1e1d7264a901091f8e4863481115319871c1143d64a1c5971da218a3055c6610c70bb208838636596cf0820654a4fc7019e38b20d2488114504c2f9e54e1f2051d69d068824511689aa0a24c1a666e90c2de0082366368a942264a115570194c3041420739d63869011d4f6a28c289376eca5c11b301082f5a70e3041628c028136bf286056cca6ca143125848493db1c54b17265ce49062c2d1822a52d8cc91060ad680810f3b941103362908828a34648a60f384122e4879c3cc155b1119687c98628a0bc4a840c31858aee8824a1c6a5841071b450c81851330885a187346115ca66041cb1862b4f0400222b4a0230932494401870d443c8c91038c102cc85105114a2041658d342b204386a322c80835bed060090d4b80985700f1c4862a7e3043082fb1272838c3cc9a2ce890410fdc1455c6c0800a2765785183174e8c9e230b19195e900215bc31c190a68729339c11260a1040781163881cdcc0f005274507a0a001952c5ea01081c185098193247e00034d0d986033803333e0f2060b1b58c4a00443b09152854a0c57aa3031d144716286274ffc60c6164734994fe4a0c30bb668b1b2a57e9111b1a4873254a2f8b2860313b3018a1984c04225893438f0404f9c362265a44d08881eb31a0c21850066106521439b2a5954e18124aea8e109304914b1269341891b2e55a4608a306840c197a21798a1e202142f8071822b83c9972b56a8c20a270568430e31735461f243132e0abbc3048e406383933155c8c026b799a30c39caa8418a125e1c40c50a675a80c1153167705070808d1eaea8228932b0601385021aeb2c6f6cadcd28a554086332324dd36aadb4cd0674f6b1faa81a69ad1097925a341f33d3348df41aa36a232dcb42afcac3a8b3fbb419edabb6596bb3aa65999675c968ad36ab95a4de1dab9a1bde2e2931eef674cdaa96655a56b764d58e1bc902a1695996651ad5b22c0a4dbb7db5767b9666ab69b4d60ac66a9a66ada5dbd4320846ad44d3d6e67a667a282d28496e5bad359394be7aad3b0ac1b47dc5b4b596a4a4d14940baa8659a969190e828fbd48cea3336ab73c35ead34ab76f37ecce0d99cf633a8041beebe77ac3e328fa4b555b7d03962a10d969842a3a6bba53392ccb28c66d6041510afd7cc6686c1cc322bb2bbef1d77fe8efd5fdfa9afea59ba53ffaa3aab5cb66d948d46d9ddb63b1a8d32728599cd993ddbb467d9282b63e62de4d346b3256e62a171d4a2d336a0353b1a6d128f5996a710777b1a26bf80d212428d1a1136900204481b2d2391326e237d743b1a8d48588936d2469a0d22cb328de5ee4c238d60757692dd3c2554dfaa026d6acf344ddb485d52626842f38bcef2f62b3ca151d3fbb4b9542b6925adbd72238d0a79d40ded4ecdcb3608e266bff70292d651006b2d5b2dcbb489f5bc0e9a134f4d08eb2c672d64a34ccbe668ced1361a8d46a4111d8d5873f2d044cdc11c5ac685481ba12986ba1969236ebb3647799cdc6682d63ec2fba5474f8d7147a32b60ccf2c6251b6d5e7543d346a3d148bbda8e46cb8434f1beb69aa6e59d9d94b3cc53a2e92cb3f50c6d6adaad77476d84e95659e84854eb515f7394e96c34ba9661f5956531ed04b5da1fbab963a55a991f54bd6f57cac24b32e692ee5335d2b597d57ecb41f677dbcc327235e9775f3d569e6cc3be63989a65abd54b377748a339e7248d4e5d2e359369df5996d56b9af6595f549b948cd1e8d69273e66b9b565bd05540cf4f1236259a9e19cef20a667de9a38e033da7dd1fc0f3c7bdf51b8c3c496adbe936ca33a6b7973025cdba448aad1651461340cf324550d15d687137fa3c37b27b488fac9dd97764d617250de96c48ef7925b51ea10fc28ace4c26cda4a554b38c36a1f2ce50a8bc639a9af2164a6d297c3a651bcca09bb89baaa13393e984427d88753a3de7a80cd43aebac3c84429d72b26fb33f724e3fbb1c1cfb61b13025fa869cf0ac2f14901789036483b2b5f2e9947705347d9e96c795615b7457bd1c3a51795fed262db362abddbe22a96b63eadabb49c5e060050dc4a4d11d11d2c98b98fce9dde92653ea30fba37593e93ef687e92df1acd5fff993f37d4dcb556695c0baeb0fc8f973eecab90a3867bd5c2eec63794ecfc130cb737a0bc32c8fe92c9cca1b88368da72813ca64c2da47bcaf3e89a7d3298e69fba5dea5b0f60d31bd9b1f0a65c2acd34da71f31ebf4f1344d7d65cfc1acd3739ecfc2acd359ff7130eb749ce3b730eb9489501296dcf09b4261e58ca68c739637cc95b37b4a647fe064271c3cede9add373f0e92c7c3a0aa350f5f8e953bfa36ec2a88f780fe9f1149fee53517867da749aca5b7d9d4c26cc7dc4de292e89b7e0c71195778c48a37e3a7d339d7e39cbf49cc77e5857a5329226386f9d65ca3910eb3979084bea433899657aec47955339270fb532cb949134a15028d1633fac6cca2430b9bfebf929589eec1fc20294739c0f6101623de7435880f0596fe5212c40ade73c6482e5c9de3a4e1ec20284f3561eda80e5c972f2d0b4ac3c2442fe9e62bea79acf9f561ebf67514e86599ef1f387953fe32861fe34b909c7f43c21a9aff1282c348bec88b553d142ef216dfa76c23bd327caa24f9ee0bc95837170eca785633f3998fee064169e3fa713e66ec2dd7deca659f64b8378dbddb97b780fe92e2ba97ac4e58d6564744abf86aaa6c2bc3620f4814c77d5a34f680c27fb131df5c0ece9237cc20988944ad5d45dbc7bf425ba525f1a9e1487fa1ab299e99662a11d2dfe1c713725328917bfa38576347dea156fd328a3e1d2183c35a9576cba288a2613cef4fcc49c7afd8884bfbff8f4106fa11e5d3ae5d799bbe76bc9500a3406da248521325a7374f421c87179e44d350f235dadb5d2696463b1583110ef79b02ccb12f6f993dfa75291a76a4800a8e69cd587aba35fbe0bb72ccd3c176eb55c34682abae3bced1b92ff619d3ce45dc9fbb0cee747c64a5f916fc74b5f29eb5ce72bbfa354961f6de435b2fac82ff375f2de86903b77a48fc8fcb2eba539278f8cb7a8493bc9d7cd9bd587ebf3dfe737a495b7a7cbbd8d5083acc2a4630c003c92a4e020a589e69162c50dcd739e6bf145f77c534df29086872dbae73dff482670fc46af1b4b3c1cf09c6a1e1e1eaffa60ddfbc4df377d6a3d7d4328ced995b38ba31377f51bd2d1aff5f90d71b95c77b95c9b4a9577a6bf933e22e475e808f50da1da47847ccf3facba8f55e11e3a2350dd73da731f37c07d6a0bef93402eecc96bdbeee70ffb84c8f2d097b4c88f03d1424b7143ca162969a47ce9a837fa88944eba0e26cd637c1d3a14030184ae82000208200cc574b80f009f40846a011c04ee234ee72429e4dcf78e7adf67de9724ba93ac2ffac14b0cd26f00cff0318b08791effa7ce6f3dc885dca776744800f4633fc001329090eb3c14c2857cc8e7411efbe9aa2704b30ef09fcf9f20987580cc2a21c8f51f20e43f5985102ee43aab800528840bb90a3e0ff2f933bf00004008fe3ed5973ff3565fadcfcff5ede916f9d107804f18228083908900b9ce5d788b1a5f85b7a8b703009f40b5ce76fb41ce745ebace273ebece2dce3a3600f804aa0d90b7000ee4c754eb608ef50d6ab8dc17f33c2fd641071d7000e3e1e1c083f9cdcf6f48017a7a7adca7eea0a5effbbe1d7ae2fbd41e968acea07c444a779dc42e354553e29822a68727bad3bca9a3a3a3a38dbe51e783833c042ce44030790160aa31a6da12d92724796f2be7e707b9cf4d08927d6e82900f6855537a80410c5b8a6040b482596a52420110577ce0a20573cc10460cc2b4118122329ecce08933369c516b0a40dea4200292ea63ea5a9fa04b9800c2ca0604142fcc9bae32d1b57ec9b22cfbe144951a6220a68d3555645969052b6eb2d80a56bcc0859934cedc70e627cbb22cabafc9a3ce608519a0d1344dc3f16209346544e1851353344dd3344dcbd8d09ab6694dd3a28c1958504114747091f2a3699aa6e52de46952d5344dd3b4ecdb283b2d71a7c74216a586728c71c38515ecc084882c0645e21ce382186e9858710615363fd95f61ca8490c51631bc6185092e749498645a036bde18b102305ca0c50a995bed1857982d50aac862861c4f4a4bbe703c5c69a34c9b2c5268b1c4977a8615244c150c07c060011333e07883cd146f7e80c2630b2e56c006942948dc10c5fc3104112cb882284a193aac80cb0b68ae2c718619512657038e06567eb8d9115bb4c800c7982f28f8c9feaa224c142cdc5004c46b078b1d336666841564a089c116434ce1eab032c3098544175eb250d1c50e6b701126035364d1021cda18c3cb148e0e2b2f684aaa2803862d5358504588ec8b9222a028b2818633446ce698e3fe70c30413374051a60c932f4da630030b176811e344129c1c150b379c8f37d820e2428723dabc30d9682173861742c411c30d590e6b4604e0a2c50d992a4ac4b0e603bac21254e850b40415519a48c9bc84e1c5a2b821a3488d136fc0e030029b37bc98028c2c5e30828ba3ca179ade60091826a6a8e18d23ac48e2eeab6b19d924f3e40b29709c6122858c0d0e285622d8b2450d4b74d18415547c56b89bdcd9d9f99165d6c2a60b59da90418e2e57c888e1de304205176ab8a2831a2c48a9a29ed6f4b0a1396ed6a0c3cd0b4457a464635499b28034a4d84284a5093284a82e80d56a6d20c2cd0d3bbc691303181031031abe336a96cce00d17d66c41833036b429038e216a78e306333837aab8409a68ac443106942fd4a471e3031a267603155dd66879e3a5063098768836eab823e8f2831159c258e30817c4313fc84a526419509d686400eaec222820db6cad606a756dd104167040f1869a2d7ebc5891c38a1d68b8c24407cbb1c1b92923d6c58d135faa7c09c30929b610659001e58d175a300608c9a98ebb49275506942ec1e264adae154cd5546b19a0c842070f5f48f9e267933aeb224c1351ce2083a887ed4b962c59e127a381758129491051c0208ae205172dd431bc58a1a2e50b13177e3ab0e16e7f865f3aebf94efd517f6a6b7e60c1e8e8b5d77a2071ed35ea0488b6a78f46b01ed5c7f7d147b3248226755997755997755df71197b77bb71a50f82c7a3b0a9542dd8929a581a73b31e519a3416f17f32691e88ee11ef8e76e8a8475ddbbee7ebc93f0a6fbf140f763064a1d651af3b43c4e5226e8eca87c2d4fd66516ab84f1a7038d3f8d2727a69826ddd78584809c608b799564831b12e9a5d537d44d27c7974fa9cefac0771f160f6eaacd1befe68de2e7f5fe15f9b6ed5e92fc5faf0dd320eb8607df6d1b2cc3ea6b6eefb60c84935bf996e7fb86e91b92bcd7f2ccedd909ce5b1fde2ee21dbe3e01e3b67d07c57bdff016416f9fdb762f496edff74b6f5b6685f7f26615618599087d33b508dd875946c27f671509e73fef53c734d5f3fbef04e7add3eff74038e187e99b93131c134cd0de87f3d6bd139cdcca22686fc33bdcc67b787f17731224ee979f6d3968fccd41aa6f4240f4f689f7978580e83183790b01d1aad7b3529b8a445dfb9677994aa15028d4f61ddcbe83a8ed03c1d56af50dafb6d2b6711bb8b9f94ef5f799834e4ba5933e52e9a4fbd4eec31e89f4128837100d7ee22d829e273fed8fd4a7fd319afe924c8d2656ce2b55263538e67d0dfe94f74d79bf347831efd7cd1ba6c1879ba6e0ef6341dc7d92beef3b29efd2bf7bf523017c07669dd6f38170aee3c2e07f2739ae9cd3d2c138cfb8f565ef2d9c8f83757e8c9f835d9f78031921bf75273ac7c96f1d48e738cff90f0480efe4cc3fcf3b01409e96673ec66295f0e303e5dcf51fe769e79de45c673e77f53362b5f7ef1b01565fddbb7713b78eef04e7aed38f5542ebf840ade30c847357bee5e9ee3a3e90cef319307f9ae0ec44275fcbd33dcf6fe2ff40aee7e0ecc4f59c0cc4f2748fe916eeeee5a0d22dde42407429935eafde220029c55875558437fad66d253a1b651f9d8eb08fcd46d99780982e7d2b7ddb7476216f03425e89562fdd066a5caa6df5b873ef6ee5f492ea7beaa855d0bdd85d7cefc993f42dbaa329f889824b779f1f7d47c45feff725bcbdbdb1bc9c8098eebcfcd27decc5f720dedeebbf8717dfcf6f01577c4954a2ef471f09a57bde67f8793104311d6611b8b49759dd83c27befc27b0f43257a5e89167dece87e17f1160fe624485c317fbf39e87b9883c85f21310b79fa53bd94b790a7c9d7af50f697548dd77ef34ea150738e378d378da6f9fbee8e26d33b9257c226f1d73bc9f4d2bcf83b9aae9d647a695ef4f2d6aec46ad39ea593299f4e2fe153de5497ee2ddd7bbf956ea9b4811ae2a9163f7310e532cb88fdbcfd9c9cc8d9739d68cf71136f25e04d9ff54769cae1fc7d897decc5df27de42f744d19e13cf89a2288a197c884d9fd8fbc5dbd3f7367cd0bcf7f05e0e6f4a411459e283eee75946eee7bf87d90a79bacbdcebad4a74bd15f2340a545b9b77e8aa8263ec964b3525816a6aa5a39ef61da1dfde75dd3996eade573f710fcfddd373dc4b2e77b3d67e4650bf799f708d42a98f84e7381004c1312720a64df7dc41ee28bcc5cfab3e8e3c0e73aafb542e27412223c1f4f0dce82301fc154551ccac04c4b4f83bfe3e0c414c8f5904ae5d017dbf2ba0c387a36bdc35d543bcc3303f539dcb41aa8f39a83c77f10eb3124dab32587eae6ebf11a8913267f5c5caf756ab7bed92e45327efc17720a9691e171ed4b8fbf020a95de3ee43316f8d7e5fb0ebaebdbb4fe570078279771ae6ae1d7c8903b917299d3b6ccb658d407578aac3dffcbd967417d47d0be94742f7ad0b3148bf8d785f8f17f1ae801641306f97067f8fba79bb727270705a2d16ab2c572b9254a95229146a1c4f27934914ef0d4310fc3ecfebba5289e3542ad453784e1ea8bcb7d437e983f2accff901ea5bd39764e53dd2e057abbc47fa3e852f9977a6ef53e05118fc9c3e5007c1bc4f177f5f376fefe37dec88e7453cfa29bc77134681eaf0d967a4eaf0f41b8186dff2ee1e3ec420fd12109b558779531d8ab7f762ded7b7ea8bb77712f81057fd5d8339a83bdd5e56a2e92e6f9f257cf5feaec0102d43a3956446507a45c72f5d17f23073f5290fcdd9567d04d56b24d46b4a6c14976a4dab3e32abfd5ade4e4063b5d2383ad2cf6c624c8373d3cdf9c1d4b42ed3ba1e61eebc9d348b554ad948d2648d1b9a4843055eb08182284dce5c91a50c176b40008d31d24071051d6784b150c42ce638e3852b2f2451431217d044a1c10a141ace10124614175e680186346f646698c0092b548851c4182e4fa61a6cdcbc4143515111380cd145066aa0f1c49825aa14d1a10b296ce008430e2dd480634d151c5a58a20637dec820bb49628b14676048a3030f7484a1831639dc50c1951778e26061873698f0c043511b09a8c08a2d3364c172860c363a4b04b1021fd8400193367600b303176ba8986283932f30e0850c2ad89c71c40b66d634c08a9b1bc4c082891a57b834da343106161edc00c20c2a6228b1c5124c2c494206694c3abc3843060b186b5c918246ec08346d56b0a1ca1438a0a839c00a486ce1848b2229d0c0410819c24842062d4cc1028922b890499306073167e860c30d2c20024b0ad28892b3c40f31b40043182e9c099758230c174881628d33689409a2090f58e88832c50c2ada28a30e315ea210c343195aae00c38b398a00b3c64b1c4af8d0840c3b6031220a02aa00b3431b2d51ca5c91a60b30533081a589304ea220038438b648638c9a2996c84108357c88b2c5104e8051420558b47821c51318961823f6031b62e850470e5288a4d829688421c38834825801872652b00ca1c60f5ee67062cc14265e9851c30d166400610327c60b64c810f1c395175cf102874689992caa6c014208354ca4b8b1a40536687250011847f840650829722083a50828c26883821ade30f1618d36521083306328a1021a50c1c5182ea6c476f0c24d1c65e010dbe685e3b6ed1e988fa32ba48d95dbf2be776a1f85c6eae64fa8bca7ba9325c781e03f145ce0c35173dc0d7fb951ec4450e48474f8d14702f71b8ebfe316d2f75b48ef5104f106c12c3466620eea6eca41df8885460dfe8ebae3f2161af5077ea793e7799ec7712a954af5c428743fab8f8b0285c66ddc467d2fb8e9ef7bd4df28346a14e847056cdb924ccba38db692075e8dfc2b091224b05a4313dc4954cdcc331d4c82f3d6bd24f9bf5e4038799bc451dcb67bffd72b4c82f316104e0b896914c7f1620e52994652f579564a45a2ca540a8542a14ea8d56ab56aa2054bd2f23c1007a8751ca009b33c303476554327ba2c054d0aaaa7fab4493f81a483ea297d0862babebbdeaf7a7a57bec320088260a7711cc7e1ef25f1332b951e86a1c695b8d26f697b88bf833dfa1b5292ba9f46d3fde4c8ca9d722a43e5fdd2197716d6be24acb7deb56aeba58ef53a65d20d4316789f3a8ee38b4c3d3ea64f9884770534c984c7d34be2e747b22149bce176107f39c37803698ecb5ba867db9937a41ea6aa5e0e5d6e0be7e37fd65dcff9ac3ef077a673ba2ec4f52a8cf2b4f98d803a9d4ea7132b497755deac3a359056fd9437903ebdcba1ca8620185640772250afd6632e449ba7c2a8771dfd8c9cae5a5df5f91de91e26e9d1a88aaa281285caac550eaf3aea5d06394ee4448ebb8f0ddfe9904051fcf7e97c9ee889a27873a67a473d1d3c7fe6c7d5f9e363499f02582f1fe27ad227423dea21f64efa164035eb1ddeab7b3909127795857ab2d71cc47a9983f05759a847b3f2acaf1f95b7508fc6237c4670ceeaebf9ae9c9c5a71703e1e67f56e85537e45965fe194e4ea75d56ab55aabd56ab55a75b9a4d75ac56dfb88641f90f546aa526555187a63188418bd7a4d9dc4bb4703e972b5cafba557af37d5bc5f3b3bab564baf4ea77c1426f56a8f57ad56afaa8cfa09b5ba69f5597fe4a33eeb8f55def7e54dcf78561e53f63e5fe2d12ff69ee23e237504faedd96744fc9669927c9d773a231dd6bf775953a9b22a0c555ba8478bff2ce91b01285fe73eb5d3a93a37e1ede9ef5dc6b73cf43bb2cab3be2a4ac43ba6c577d6cb78fec4f46a952ab189c4aacfafa24ee298ae2ad453a8a3f0bd884713de40f44742d5e0c52bd493f56814a8ab665878c9bf26927b49f27fbd605b782f49dadfbe5e17098c0a2cabe202145ce243d8bd24f9bf5e61188aa129bc17c9b6916418c26021120d7e23d1f7d705ad160c0683c16048604c64d946d2b2a111a556702979a6931f59a078b04c3dccfb844ca380a3516202621a959394b9dfbb83ff70973299c404c474f7520862facb2270e92e975e3289265369628de5387adec93b799ee79d3ccff3b87c6ed45a6badb5d6aac4775abd2bc5879d884dbf1e4a7cdd7bef288a1745d5bd07b7ed5e9214474f545deff365e79d565df77ddfa7c4cb042deeec80a9ab5419f5d41ef52541f0f7de595f184ca5f27eddfb20b6b3f01fd29682ce8e9030166df2f8c01a2de34b9deaa9f2b43a99c4ccf49d4c2f0d89dfe9fb6eca412bf1f356aaae4375a8aeeb3a54d7756397c771dc362da69f4e79673abcc843cc3bd35ee871dc263ecc223e81bed1e1e4b13dedb5c9329d91f2b41fa510d3283da249c9e49dfca90451074754cdf4bb7fb903bba3f0fe3aaff33a1035a46ff8bdfbd4435ff86e68e8eb3c54d59df72e07791773d0f89292ea81f3e5a934ae4a7993a753189a4c4fdd149ab4124e815d093469a52e6f8d865a09abc2300cc3f008d03b054f0f8221c77ddfe78545bebcabfe3e1ec4f7a2c08b4789df4d3ffd7a7734ddf42f4849d5a68c02d521c77d473e31337249dfc39cd597f76d2575de6d88a41f197b2d693713f46834daec56b2236d03f1b4af2cd60d23baefaa32e4b8cd1b517069d3c1bb6df792e42f82bff75ef186a1097bbbf79bbcf715829816b3085cfa661334f86d820e1fdef0250abd5eaff2ebbaae33c2f33c96e7791e088220eb7a1ebede3def050b57d0cec27fb22329e8d1b551563db02958add22bb070a65359fa0d4ba5939b377e76f41d29597de41e38c1f22258fe1ebcdf4bbf78a7a02f4b7c296fd691ee60e9a1912e3c984b9f3a051d7660f912dea57f390912b794c3f2600e2a2fe620f2a510ef9b95585d7ab3543a9dc6d3783a95f0693c9d5e3a954aa6533695b0a9542a914a252c1cc7711cc771dc9682663de4386edbb66dab2f6e92f0d523bc5388432ba964f55a7098cebe8e441a8d90e857e93e497812deb091dd46254b0291885d1231df9ce4035a3b2c464508e6d58c8822ca73a98fa8b3aeeac2df87d8740f832417fb6d66dee9a0e960c812c3d74b7b9ee779a6cc1271805c39393c788ffb096f3144dd14a23c1312efe07e852117869925fee6cd62854fd23ace93b89e730fe6cd12332bcc25b48e73a0569e1607c8953fa0c1e77c00890651bfa873390875530e22cf09c1749885601ae5cd772a729562a9549e97fa98fa981abdd4388e77f452e3e8ddd12bc75c96a55784e7ddbc63fa1ec41ede48b4e7b16c49a64693b5e071be7b780bc12e4d92c4c3c1396f61178c5502ce730e8473a096e7b14ac839ce8172be037d30ba04096c556f9a7f8eb65d01ad4d6d6a539b9f73765bdea426a7e7a344b3410c3104dd3b9ad4d2a45193b2fa639b9eb66df7922489923eba67356f2b69e7b2f62dab3cda2729cf9709af52b56dc084e0544775a9972757e0ef416f65adb5d65a6bed78ef74efa3efc83d78c474f16018b24ed98809bcf7f03e16dc2098ba08a6ee53b91c9e7e4d08ef8120086696e917bca66c04ccf7539ba03d30f58bf7fd292741e2de9c3a9783521773d00ac4422fcdddc3fb66a1974e6516b9ea542549866146a98e52a13c150a85ba07a2c2df7b2a142afc0551de43ef43e5effbc27b9ee7799e10f754df87f46178bbbb8121de26e8305c7db33f5a27c7f02953f831bc6943e57dbd9ff2263defadef21de422ff0de7b2f068fdc7bc57b78bf8c8417b38fbdb86aefbeea4be835cb642f4ac326b3d5cdda75590871ec586bed9c482acc67a4913aea51da5124d507f81ffaf2b65cfa9d6d1e942d3a3b85f2458346403289eaa46a16a5f2d078d40fcd19142df4fc866ce1e9e1efbd2008bec8d46005343de14df5e9844d9f1f0d7fc2314d4de1c530049fa4ccdd31224d8566d1fdf2def6edeee81ce9c7f64331acbe46b16e44d9a9bcd9260f7b25b4cc9d64a4a0d1dbd3d60a791b373fa831dc1674429776f498c27067911428221cfb16f120033d8ba43cd1f358e84fcf221eb668fa0b74f494cb269d3ccc644b749923d8686e056cea0b658ec0c1a46791182d253dcbe820263bf53c4c569eecf403c6ddd7d97baa8f7d7a551fd9bf537d6ca1acebed075b874369c7485dd7bdc8ac1d67b597ac0d7403ed9b964d0f6699688fcd0365f45a1e1a8aa5d1213141fb03b26b9a0af45966d9f96331f98c84f9880003526b5dd3cd49661cddc0d41c973b406a9a8348a7a739d3e8b710a9b98f48d9d6d2dbb67d7e43c2cddc0152ef0de82c07d1731bd05c1622a777b9ec1d895befd27523e14dd28f8448ed491732f490430bd480210540945800e2cba90406882c6d3cf1069a2bc04cf988987c2183e8861e6230c249a64dd87286182cb461c64a141ff470f75c439396a79611038824ba4a9190e142881cacc4a1468e589f8ca8944b98a80329c9985623230000008315003020100a864382c17838914435940f140012899a42624417c7635192a33090018618820c21c610408831648686846c015569737354042fe1e6dae4987104d3b641bc0b7974dbc693e3b5c3ea9e30b56da0d73d993d4637db526277e57d01046b3b7a8819cb4e9784c70ac8241d4aed948179b189ef4b8630997d881927fbf473188d691f53264fa223836e61deb83f80721bcf53491c53fc8408e2c093d652959b57ef71a87f2b6e6dc89ec1d6741148be591ad332790bab2b01dfa1c85d024b3d69663c438cde5dad8e207dab036c159e81402266fabd5b3ce3fc2d5dc69e17bcee05bd1e7d847ef4df4dc56729523ea38987f6c0b9e9440ee76fa50f8f7302b710b5862449a97abba262f591a9af2dd89448d2c76c464b88ce7896c2548790fa9a04a4b87a23ee34e308ce90db3a37339b1f038ffcd21a6f3e7702bc187489b2a06224fd05a8debde37b84641c3f7f9c7665e231471cf79bb857fe2d95137beb877dc7049639110ea0657073c8c35c31a0bfa84ae043868be1b2d9ddef15f88328c85125782744683593010141c7449c741d4fb272ac39133a0706e3d2c342263b3b1ddfe65e657342e916f356f6992ae04e7684a0601b7083e3b07746494870b6a677d0ed22ba7678c44ea02bb2c66a52023786891273ef9c402068d276024bda5bb03c25700a2fdb4fe8daf184edd6ab7a02f45157203b236cd724c49e7096c83f93b7639fdc3970380f45287011d47387fdbb0372de5dc7f6697f420180ce2188e0554d0b458df0efd57f940f8a854d3b9298be02e320b724249fb82c24dc95a652875f2900e530344a79e604fd8d381eb8cca928800b83e7a78e95e7ced5a4d0fe197ea960bc1ef1f693db783c2e942b0d8d223cdfb2ea0456723c0511411bc2d1eee876ff50f99587b42a8bc8d857f0cd1d82d3d613339318749fb26310ab8ac6dcff6588d338d20eeadad04e7a36abc3afd8b333664f4d654bfa87e36d06ab69ab995a3990e863596c879f252aed27ede483f431797e0f08fb55697333b1a32ff2ed9f60c24a4c6e8ff3526c8a13855b64e0a3d1016f869016103dfc10ba1b403f28ed3290dc0a37ac51620a305d5aa15444e8972182d3ec2ba534246aa9273cd7f9b18b6df2dc01ee5f775d8e98291874e9fab7484b82f2a5ed368c685b27aab4e3b12478e2268db54c117520eeb52c2af9939bc87ce3305ce75e80b432480afeb2cc714840bfcb28a17b315e7bda0edc65acb82c387638ffede75e8e83da7c16c7cc5233128392398b62cd78923f0e8a8eb17f980b7918562f33c3ebfe989cae3e75b5d360df2dd1a5726bddf342398e43526981f5970df95c0affc4864fac8f31a678d149cb8cb51e562f076ce279fa8180b2ebdb130844983cd5c698240b648078936127c52d39f8f6d5277c622a06f33a16475a4acbb17d4676fde809977e5ff52c112879b18afc78e6544518614e6f05024b44f625c2c08434535a702fd835c965339ef764b9aeb66ecf66d8cc754e21d4b450a0f9a01e6b2607ac8b54b0cbc4c9a1bd95b8ad8880bca484b9bcf8c875058666d83f0cd6973148677b2eac6591f9e46b70a46d750af5f12320607292e2815267ee28c1560e34a6421abf021dbb560b410bb1a150a3cf6be47e0ae311602c58ee668d4a49993a7216e401a55255d7e1ccf8577d8b57edc1630082a345d9e53b34af3c3029bb7cd54b360ad9ddd6733e9263ccfbdeb5bf44645e26cb500d9c9ba0bff273ad9d66383341ce634d304e5ef6e7faad372c0e7915a3f7e2ff5cfa9877ae9b55ea163c1b574054668781856e95c5756dd73a5e11c0b43108aca21e818a26998ccf6ead956da3a152fb5aefe4ac106e1e754c59cf6f7d00172a3a147d37def47b5e0ebf07f960b93d9e0c3e80b5c096236096a3d89461bef64b7a65b8f1495c8a3abd811e58ef5eb1bfa57e90da95fb886bb649ef11bc98125b84685bbc36397ba836cf219c07800818daec5ba00ffc66358183a1236e303f2377def5428685a9762de41ac31d2d77c2b2a5405efb145574dc05a443f62015baa6354b0c997e4101d5fdede76022d79377597c34b3f327cc52168dea75fe0cc6b54eae5c5cf501f3808dcc2ea106e982fc97202f73470fb1ed0be1b5ece80bfee05800634c43ce86c1be95b5aea8e31b9b6bb5b708c38ac5be80857d162ee5c0cf271a817d3a2e033587d091ff5bdb977d2f54503f297ac01493e7a59d990dfe5c4a2fde91e6b28305fd68da2d5e6f4422225ff90dbbbf64226b5c010ed8bda03eee8d2851aade2a1adaaeb52c351da077255dcfdf2d591bdb638f7f6f78bc2ba98757baa639d03abd87a14b7016427e30d24fb7d9d56c70fe319ff42c7cc829e98ca7ec136fb6e3629d8c2e0cf95ecf0d2e2c693eeea5b41c779f70320725c125b2effbfca2a47caaa6bd2466e2a2269e5f0a1824c65ac2706642c0cc84c9e154f421024113bc3bbbd1d2d44ce85a563b16ece9e6c52575e69a7007e5878b5b8e32d33a8ad374902156eedf6c2cbefd6f4973b07172e9272e6cbb0dabdbaa39791190043d5129a54d49d725889b3d25537504a666eed02b4cb391eeefb2dd374e752bb5437896d12fd5228e0ea81b8a580af79f0ee7dcb41da2b4b122fda0a488ad1c1d6ea3cba560990e662d2e86cc53a4e6c7dfa873108295b1711de275ae1120f5ec8b553ebbd9cd0a22be76c46448ffe0c64de64bb66358ae402bd7ddef9aa2bd0f322a178513b421558db1039ba9bdf13fb454cf47966ad7c022b48c2b9729888d43436a04e980a3e908d496343c3ba4266329c8ee095ebfd331e62a1e5295813774c9bdbe97a3b2d01b50e66d48bf0945d3035cfeafcdc1de791cf666eddb087a92b26f40ee2d92098cdef0e506545f4afad86a6a0589ab4849d29f5aeeb240f0134660163837c53350604d770816f2d8178a047a318a5f19ca9bfda9518774c61785d0d7c84c0543c11568806ce7b1041e212780aa891e2d73c19d89f3a260cb3f97fb0fb5574a7f97f5aede619fad2e6b947b3e714d15ddab74b5eaa58686a539babf19439e17f778af5e3850348d218b49b7e3a3be013ef92076a11432f2dc807163762cdf70bfa74b17b770da5f5d68cb27953da090a1e96a4d20e1fd3b4cc2611cfc0ae1cc57b8fce2957db384581b8306b494c903f015eaf9bdf27684d4016b4b39992ef7ce8ef90dec1321dda2e1e9b33b1ea52c426347ccede0441fcd715d219464dfc10c6a2f3ef82046d7ff36f83ad66008c328cde0b1136e30954e0c255eb09b3c67f0d8c8efd429f10a3641eee0d751fa08529c206fb3ac858ec94021807c82abf186be8e39cd3838a782ce3811e5f56188f6bcc476a2f731507cb018cefa44376fb089f38816b1ad70b3d1b606ec93b1c84499a554a44c0112be88af6bec763c1f6c0f40415d84ebbf1e6b3010765e5b31fb4cc0ebd92d7c0a6e40db42a8ccfc0b9204c7f0a2adf2c67368100ae3ab7a52b6cef5e60039441ab5ce394c3deccc2178244a33daacfd304a0887807523d090432043140107b64baafacd1c47c41e248f7f772c8f9071ac6af8b14badc281430a41f94b3870a184a0128908079e5a0832dff4c6c1aac70e07a6050e89f86245d7099f277fa8137779b8c9f081df6410f1c7b77c3bb240fc7c1e3e72cb71fc160ebcb841fc9c30194b7fe33307c28111e67338422833a0bacc5610703b26a58e6055e9b96e673f9ae18c456d971eb47c85691cf0ed400075047f650641aa35eb420a2b4968397d6473ae9254bcfe72dbece501e50231050825b1caa39e5eb987203017dd12ea5791e904d625eb20a4d4bad5a63e499065479fb85f80d8fcea8880ffa9c1d5fb67e5c201543d9a8725de0e3bcc6a9a63426cce713223f37086e6e08e0e065821e46c6c4de3d23c56f8d5b51b1311b24691a6a3772b6996ce27721120e8cf801899a12f73198fc32443a374cb01f86aeadf8287004b4aa1b5a5c119321c0cfd144e9f7a56b50f5fe7c6d960a30dcd997b306c0dd6211812fdc476a4058dcfa173bbb0d22ad08581290c7c2de8837c4783507867cd3494e3c0208cf882d27d3e95f3f975bb0706f58ee69fa917d11a039b9b7a0d9cd3ed67a4ffa7bc1597802ebe77d0812f3008409e36ee04b427f119676e9a9f805851881dc944d65f6fc308caa7369e6c647e853b5cb0f4514d45bd86037ff2ea51592015e091f235026d2123d3de35a272d72ae9b970feb00c67a3d229e21805e0d2225ac1db97bca222d89bc009c910866de5170cc81412f730aa29ac4cfad527a623a5a0b3619ce7935bc856559787b0d885cc6580c43eb4518c1b707ffa4c47b27999894ace9e9cf03ae3f221b5c6b9ccbaf9cd7073648844fb1bc3984d0fd7b7105da778491db8e3a66ba45a6df0a46a3225dfec1ecdc42aebc07cabf605eb7d7cd372c79026331c124daf4147a2e59d487f15c1f09400ceed006379f39f3885e7975cf1fd9df6384bf121f320c89fd384f845ae34053bcfed69aee4d7949d113c4eaf35d4cb3d3aa69d47b95009e90810d8a66b70f3d8f6d6e855e9eb9b3f8289b90cec0c7bf5cd973a21458939f7bcfa4438dd415ac1e532ed45c4d2112b0080bb7fbe1ffa444f4350556de2cd8107fa7f0f2398b33a68dc18e3660d3716a55620cfce4faef47ef4d2e49a9b0143834fc24c28a3d1416bbe00c20d8dcb06932d609e097bfbaac172d5d8affa049f4a1ce71d34acce048632f84f992251f58f35a70e41f996e134acae24e80d970a61623691d0fcc786f98891688c589f8dcf1f373b1d10a17c3d6c890223f06ac05da386eaa073f23fd0c826cb7db68cd07e0946a4c93f8c4c3648165cba4d5dbc2fb8becb64eae61f53169361097ca84a73705d8bb4b758ca60347192b205297cb0d88e1d3b4b86999a6556c950868a7546c12a7b1d9b4901cae2d3694a709288d1bd1a2d24f3e8f3cd6c339ea8c1e496b9b0e28185c369da1b339a8845739ea6d593417c9a2e08e8a0b4e0bf303049f7c074d8406f1bb1a7c33a7997319439327d8e40eef12ee46ce140519bb1f8e9ccf16db3559f785054d27412bc6ab192e10ce4327253753a2de5d96bc1830ffd512dff11f3d8906e622bab21d365e57b97d03c71bbdc0da17f3a3cbaa86bd452c7ba216c760c935a103b78142bb196eaf4ec6150cda97f0fb35a3e4cbabc5c5f1f46a3c31b093f8c6a7cb4c7554264e92d04e6e19d0f73d38d388f18c687bb254f10adc3c916e64c22551c49b356b26ea1ba1a5e696fd80d8191d11bde72d41dd2bdfb62aba68ca01290b3e7c48fe5d2d04161038eca599c9787c31a64807be94e6aa1f220bb84225db936b0d52ea2d90e6f6f316a58532a868ea22a84ee488f04315fc3c0e06e70e80c110c2554a67b8cea3a05482e49766a15c16ad019dc524ccd219d5270600e97153950799d230122d83b20ab90fbb4474fdd5b40f45bb3f7197b416f433ec4355dafdbc945ecbc513148ffd62daddd3772202c7cdaf236c943f50716d5291e8e995b3351a7445c4893886f46e2d2e3fcb55d2b38675cf7352e668a7bf4c10af1ad6071ea4c049ff45167c9d3dbc0e239ff93fbd107c6e679fb9901c660569b62afdd07d7103570dd38fb5bacf462017a1c41da201a351d03050f16863f915956678c5ac05be3d2e603065864a3f69f27445564db1b1cb29902bbac944b8f2e78abe8240bba6fbe3213677d8a80fbc615e2830a802e6ce9c4f3c598fe6dd2d249bde87bf1ad22b60ac4c7bd3fb64d6dadc744758f74429826ce129444c28044437bf19240c3510697ff9c9fdf460b6ea55d382a1c1377b9e731377154c778e22722c482d49dfbf79415ac4dad975f4ca6fcf7e0032122be369921bb228a589d83cc421485ae08b38059eed2fc7fa9fa5184b5760fd24021db2f6cec9719e7105276b9aad901a54a3d9cb1d1ee85051bd6d90baa2be210866b596e2db4158eaedd9b83f00903a50fb532d550d7e24fec28e0bc7874fea93d48dac3c20eaa3bbea4f56dd218a682b9ddb38cb1f6124d353644d00717e48260c614604ab737a1b566c1ff08fffe32f3e60746a505d08b0735690a5d8ebcccec3469d767002f677471b8cb345054c9fe7592029134f97ad3a32cb4eccf2c289871d11c125d87b51480ea41e9827f28a6e78f1844e6aaa2e19c5193af30ae39cc3367f216e095ea96639e439273b8fc38588598b7005e4ac7982987e2a534388fbbbee4b8f5267ea290b91fcac098ed61254019054227c069d4c6e6557cbc698a43494bf34999dce548c10fe3022ac1ba87ca3ba6b77c43112d3427b78805415dbdd8cfc16046b6b74d7053e32f725914fb17710689373a6a0ba790113c38dd99c47106867c79cd737df54e6f35bbb7d8b3a1c5180c95f2ac54ad3af0d11b12f6d68c2f23a0c43a62c5b72e3aa25da1bbc231c7c514af49d3c9fd54f9312b1c9dbe455266e096a264373b9f517958136850441e3b944883b2518d1dca2d68fc8c9811a5abdb777b851dc940358d8e63e3d4ba910cc4f578a1455f8ef59a713820d5b2eba38730855813ccae461a3d83161155b9dde24c8c06695cc34044e4986674aa72d6490ec6e60d6bf1db534d0c2d4cc88d9d98c44aa4d242ad53e6456acb8495027a251687ebf943a95e6b59ceb9e9a030cac5058daff6e533ccdcd466ed24bea7e739d01ba78a62c093580552e38865cde4ec76e43dbe10e055c0437ee2079aaaf83203d8b8cf0b142ca372de7d6cc031c58a131412a03c01ff7c715776ba1c3d64f75b77257a5bcfc20a887027a80ec33e8f6faeee9434928889929a5302b0fa79e4096b6814b807c817723d06ccc808e5de8a6ae4de072def9d008f77c91696d032dc5376ada94f115c16b4d095752eaeb533caeaffeb11b42411d69da55b38a35617c0ee8a1f27e94d5bb7d74c292665a4024e8a3e9ce0f9d6a9b0fa0522eccbf106da5be852bba9400213dc8b1099d317b01d8eb5ecb8beed94af616b44a1085fd4f63aeecf0c840db1d0fd51d1bc3bf6ac21bc4f1077a22fdc50fec98c9cbd14d0985605b6653a64fa0cb3dc3e983dbe84284f8c90dcc81b83439956c86c517c8b36bb76f2025c1070bfd315e39d68c20be64a3ab239d4a4fd367633cb36614d48435eda8606e72c9c2f9c18ee50adcc5811082affd8aaa55f4bb69669985a72e6808bb31a679787874734af33b8a682a8b1259c6bfd859186dbdec2b845143a9ee41e2e97e02e6834638b3bcdb37972526c60fc327da3f04d42a0c2c22f0876031a803bda6d408ada272613e59fd8939c3f986815ced89ad7247ff5d59c089ebc14ced331a1535385ccda96bd9a82c8ea043ea43aba6fa6d11a9069cad2af62b508eacdeda1ce7b11a69fa25502c74a3497ce984f459bc7651d721dced10f34f8c94d4cebdfe0930c2dfd1883d02e9083abcd6b700228df6ef0ab3223ca5b1224ce0a4407b48270df5c811b253d53790da64267c59e9fc757602b24034c854ea0614b258f2a2416d9c0538e393c2bd15c1f9942214c2a8d36578d370358a941d7572f95c5cf952cb98863533bbecce26b249974ef1afc3f882ef99bc84e0b9cec42578c8d8c81193b2905947d45784f651db73794d40c84f392eb6d503cca5d48c28476d502ba5b2307ca5c320d41a8285a5aa748f2e19096882ff4f041ba82fca171e49f020244b11cc450f8d061e96ba2ed88556ab9506c8f9e74386ba5e3304a390f60cfeff72d478e10d276e85ec1a9ee41983a6fef7ac4aa8c6a593c66676d5d322bf93d3dad087905af36bcbf2939778ea5b247ac24133ef45ec718a1a9de25b75ebabf672aa941153f7f883cd156fc05f26cd121cbb4d3af94a73721cfbd672bf3e4a9ea8738303adcafda6772382ea7355ae288f438391871ad9cf4249ef041d784f2103ea615de383b744c3fb85178d556c61d22ffdd9092e188ebb3180606a5494bb23d73047f48d55dd7705bbb7971b916a5ca322cf588446a8e39bc71c3ec1241cbc387bee3aa8809e8ef7a1b3132cf02e5111e5ac96ae2e204c31accfe4f0561e8fe23a8ca26336ea089af0353d732dc9be5b0a8a7b8a663cd98626886980229608217c324145efc45cc226e8fbdb97713b3c4922604fcb144520268212b2632b54b42812b04d8a32da47f5ba19b9020cec7adeb091f31298fd91f1116f1251f244d828496295f88fb543889b0f214180cc21a832566e9a52ed9f1bff3df87e8e558569cff58a9e4f707fc1726454fdd2d89addd6841443afa72481c466de93726949cea044188da6ccea844ac031c8bb2f579a47e52d5e79bea2472a23a992eb33ed7f62079512b56dc84f663fe88bff5fbca2f0445f398a4a11499df2a9a51d18238d47df0276911fe0fae0b97898ace0977c79a6af666ae9de076fd2a5d6b10b0dc32b22279e43e347938311b5e757416a68b468b828b19e7e542f1f1148f5be5cd23d24a7f9f228024bb4113406792c08f7dfb2f9feafaad9895ec671b1f1c3bddc5a9ddbb628f5c67d02c3e7c384ea31166cc16fb28d188363326d9a14d7a444ccd242ebc0181be10ac97933da48dfc53e05530a38fbe2bc4cac15cddc9843ab6eb25764cd4f7050108a568599e08a8b362cfc1d2d2b7bf63e7f5e14bd6f8291776738099a9452341474f5b482692521392ab4a4cb9fe274e3161fd383e0e605f958c400cb165c9c88427d0b4a823b66b32975e436cad6f9a422b449360368d77b32417bb9f0cb963e2ee4760c38c71d6ba3380be83fb09c7a3103741cbbea2577a5379b3eeb7b6d7d9399775237373e596785a15cb6ffe6fa7eec938e19a1cb342fcedb616386a272497fbe22850485c92eccea0a3c8507a81ab70b8538ed54e95cfdf0c22dfcc076803f786b3bb9b4f6effaa623d036fe22a7af9886e95134ebddb63897cd8ce711332063ad01fe3d66106f5e0523d619112ff6880e29acb1d9fdfc4b72e8e6a3229cff9a7980c12ef945312f0a346f75893bdb412074165670be3fdeddf67962c6e0feb3a9a39b8fde831642400e9ca93e66bf902e91a763ef7c5fdbb4410bcc090aee3d71af1d417460376f4405cecf01bdbab37c4444a31c1388276a513269d7d611d7d9c8d308c7c8e18ee022d1ed3d0eddafe0be2eeb7da66fbc23a1edd943abb1d25a2407b246ad3b9ec0e5cd87e287558e509e3b00ebea1a99536300a3b60f92fb3a92fef2e7ed7c4cb87a6e241ed3a70d40ebcf0ece60a7f5e2ba47e09950f32f30764b793233f21d7d8634093847ac66b0c87d434264dbd072f45cc732014df9b24249cef8a28ed22f9932409eb65647653d2a3acb745017a4ee6071d642dff4526c7740d1b0b35a890a9347cdc0b72e27ebe9df4d3f417a8a7cd44e3fd7136495c893bf9f3f307f52087d8565700e216b519b2d421841d73f3c97c7a51c54f73253de0915b166ae1a1fe6129846e4b960a92a16807ef682e50d01f60f924cd67e584ad01807a800e5f5d05b949bfc82c4664b44896dca268d62e966f86ccab25c96f9451fa5f427a7af229d6b5512e03e2a87727b7a081c82514e3c1bdc55e3195f94881d22168330f0ec4130173fe925da4930e586ec42d7b55d960e000d43a5984e0b166337e5efbe96c1730f69440c6916ad32464a73d4927f0e1b89e5baefa12880417f63f68de89165aad6d95af003fb9fd3748e1bd76846143a6c3518650bdb27966f85b85b928bab48465c1a309d5c0b9bca4f90b21b2cec0321cc4cf6e68d0f827334d0a8ae4e1e9dcfba758ea70602e312188ccb39241dd75f30cff216de87f3e0d09e2f5fa19c42e0cf244c349e84ac463efc04e53553d4c1237173a7929ec75cb0dcef9955ad545ee48605e94b99e93bd7c3dfaae03a3de150a4fc60068f8ad728404622775023f32a3cfe6fafa7014fba47b0f0d0df3c71404ad368870409ce38e4fdb195507b9f3cfa6a4f97fb83d038143c8970f1ecbb9cdbecba1205ac2f2a686ab990ed78be27ca3d22b382710305f5685bc0b5c95bdb81153456f0c9bdfcdf46fdf4277adcc9739590cfbee13cf103fe4fe3c0a161a28b4dd9aeadee39fd5331c5d65fb5f49bd09f43c6e656b1cb0b7ba9c76e10e72c6dbd577b03baf8f2cda092381907021d9cf7f4228f728bdbde26322cccbb53fdb27babaf91ef24dca99f76bbb0547860244397d5d5331e88c15be0e4f24734bb7de906cc8925cf71e668ffc17f8753d8885805abfefc554f0e3885071ccf90f88d3326bfa5e67ef0eae0ad3cb42ded23abc082cdc4fd4e9c00bc6140d48e97d2b8ae918a8d8c58e47722fdfc2afb8fb80b458233f33942aaf91c9d55092a54908bc99afdcbdd0e1c2bc8e18dc0c26fb2f34a5651201cca331d2e0cf6e6b7d19afcd155ff89da3de82b07aa3bc71ae782c35fc02c0ecb1dfbdb1bf5427f064133504ae2b59c4196e8117b0db808f2f73435da25d2ce5c6d9d4d88e301b78767e2c7e08e1eb1d23e4eece064037cb36d1975757c0c440c094f20a8a974cc3d0ef32be17d7e06e42025c96c590d61cf9295217041327dda795c01efbc26eacdf25e923aa220872a9da4722d111ea28a564a390399cd97db78973d5f15ab808583c0490024e4c282ff985c215872a664ce42fd0cac7d55620ea621f9813a7f2ee1b3604be9105b423f8d6cab1e22d0590f3a596345abb1384abbbbc27e75c8e310cd599b3af6c350e797302510113d0cc1bb953f83012a16b7d249a03685dd0730f5b60ef142e38cd6b41180ed6bcd4108b2c9204b4403c035c1b3c741b2ae2730a74a541cf2be1a382b251267073d96c08a04a9f34b8f6e9d48225819d3795e9495c4a2a1add8b1fdf04202f68438efc62c551b3da02a4296cfbce944038ccd70269077cc1bbe048a59003425b931eaa12b644a0115b63786228d2222cd58096e4560129686e1efca7374a7e71302dac8a74dbf1bc90b6b4f50ea389ee090c74697db604970ca205bba09986ac1ca127266431f11466568df9a1b92413472018fd4671a3049fb6ff527b1d7f7d3e40adc4aa4be025e72e8ae27c2e20619626528c68f0b958a829d08306716ed2b6072624c752fd900f36f4ab80f90747eb820117acf0b7a8fdc2711f6708049e67b6dde95ad6bf5824002a69275272c37ee1afd41c75572a6e21644d46addcf78fdf96d9bb143e637360a30e3949dfe362f0525cd412b0d753363c985868df1cb5de5aaddde0674041b77df857d75f5f1613f296ac8114bbae132a042234bbb2cdcc386c145e49a348c657ec2a6c4f7af16ab8e675a8bc0bbc4f26967691b5a52d9ed2bd744555e4ca3516438de66c8a5589094960a535ae3f95e7b079c14041ee590832b2ad5132765dfb6efb76878aef7de6f3582f9ad72a9088eb320beb96bacf929747cfd056a5479f262008823bf6dc61c895c6e25bfe2cd1b0f67ec72ead77d0a2b694225b0f3fc70ea00c0806d8cb9fb506ff7f61e16d68e7ed4be0ccb29fddaa78484865670d58a837b90042c299a24b1603421eb870fe8b180be91d6d5316e211fd4659dae1828e56772049c3aa80315c05b7aa3d5859d153c333a02cf41f457a23ffbb0a40bbd8858809ac79caf6e88bf096b478ddfed03be2c9028e2825c0db230e3c69fd150c4be937ab364a4e090db3eae12a2d05f3ff55174382f205f58a09fdab5dc60fae704fe93f0b7b0f5eff5a35752bc6aec79803a16013b0702e408d3c8c69b507a01780fff14bfb4ff65dbb62cc4ab241b9356866b1869eb23183f715efe16f63a6528913f94702ba311056235a58ec9cfe72eb623a713e3e4932208649d366c25482202b5d7f6cc544669c405d3f37e6d07bbd3f2312e6132864a6cc1add4dab4018d586fc9596d4aa0dba4d87f30ce18ec2aca582ddc69a481184a1f0db69276df36d8cda0924b5f136a638576d089ec3abf050e5ce36ab9ed7f47e28f432bda3a646882c3687023626b051aba6a6f45fb79f83a7b4a5ff5d29b5163746e8208d4cec73dc98bb373f6f5cb7150b84f1653302b6cf50b302ba8add7f6643c5cd691b23a143ad2bf019f6cbcd08b40f9a2a25e9c42dd7f2a8b58d59cd69bd97d1ecb28f166255076cd637019ba1116efc8ed9603c4aaaa1ffc6b43d3789faf5b8aa88190443504c413182c70812232886e0188263048b152c46706c413104c508122b78aca0588263088a152c469018c1b174288ac471520d62fb92ce1d3795d678de4b2f4891a3acb5251a73a9d845cf4d2f2aa02ecc891dc14496477ded8bd180f4979987ec3834ba35b27e0232413542b905806acad8b5806960d0d412caa63b65651941f657acbc75640ca9fb2936ddde15d18b9af8206e4e31c4faeaad334989af43f7a5ebc05fce7a691e3931f1572422da1f3632801dbd25d7229748d0db7a392713573b0756c952b0adf97d9ffcd13cc76f6162bf5ce284e9892d602286b7f3d6099f89028ae4da76d336286808bedfe7ec8907522703129662c69546f2422ee0fccc5bbe26c690be251351f43a3baf3cf762b3a49fca0d23b84b7ec62ef63b359138fd8be831262bf7e3931f83edc9d5ee8c168921c828af3a1339ee4404f08a4f05afe0280066cba53d081f7f6265b5277b2fb8f4bf1cacfb49c5f29a781e47e558fcad61c5f018a879f98620b475f3fe9c2f2e530759692c29dd4f923d7001b6715c8656dcee7299a8e7743a4fec7db161af512cd8a7ca1bcbd78237dd1931b2ef4e96d769d84cf8c83cb97440aa5751e9e344e25c34f08e6cdd7600ef5866a13e29ef7849bdf5c417f8c489ec2aefa763c18b3c461978d1dc1b3aec5e87e789f52edcf6524ec2f454f58c7622215def49ecdb173d90c683e9c93749e6fa3190e885927e772077e2c116c67d69e513a6bd4b3dda171b8b90f29f8a56497c6fa3ecf03d06d579e93b100650ee3a5152ef88f7827adc75f4a613046c9d33717c47c972ae7dba00891efac581c49e4117dd19e9910c2e8dcad3606ec66be58a9b1fb460d96b73ed334d9aa287db5b30f2248d531cbab9efab3a3ccf585938a27cb0d36df6019a9de3e18958fa4528ca6010c6dd673caa00b2f3a61744e4f58e38bbf3169dbe8abbf461302eb5ac15acb8710fc58581244e189450673ca92fa8f2a4c71c044be2a08bd6ddd0d9bd2eeb89fd32d1cdc06a5fa67778efd8b762e529a03430ee452b7a1af02ec933764be6f24e0977779f4e4687f77c22762ed3ebb1aeb73df4774bd3eebd53bda17c62db656412751c41036eed534b06dc01bd50628d1702fb285c3074654cbc3abdf41fb160fdd549f1e146f766fca6a3ba429e4ed103a2c56b1f2ca2ba61aa1d5cc449a7eb024bf1931210cfc2ec0afa1994a8e0db345f2ed915f2ea143d32a22d4ad7baec8158c8cef83d0ca2802c35e32003ff81fc735a5d7fb9bc8bb75e0a5d98e178d1bad1c6e7259d56a09a0631e980459a36edb22e9428bb64d2c64261c051d2dd7667a74e5a4de071fb1ce84b5d1f7c9f461feec9efa6d370f9ca6bef896f7509e1029a043dec1317a5b9f30425ebe665f707fd7b39511dc5eb6547eca13c020fbc2605702ee7cb2ea187bb37050a55225fce18cf2f85ea675f5d234d731a25b5bc9fda38248efe9a4653232d3465b7bae6d5198b154ae6dd8815d119f1aebd7888ff74434d6e4cd33d2e3b4d141519988ee70fbed78f9d6825f489e9816c9ea72a59612ca236549d7ac857b2ddc003a2c5d16ca89bf7730ffd462856c90bc588bc79e606db8501826c3f5a10c80b985175676903451b8ab9216181f4d9abe2bec225270260ee1550b40d382ee53634561eeb5094fd51e13e8b1fa132c963088dcbd25e426e1eafded106a4f7cc00a437b0031f7588bf3438b3fc52a0dd86a622faaf414ece1a060cf878397ec49101097ee1c54928e5e03da07c6530b50b5dda32c8d31ed16845a19438b0b7f6e1d57d0bbacec332b52ff78d20343ba01a6c4570e4038e6c3953e828fe74a2a5a72d29d085cdfa88716d2531cb421b2db3075c336cfff9d785d76687f30eb1097d49f61e98ac9013f833bfcc516e0eceadaaf73c26e5ca4e3dabd3113ac7c733fa02cd6e7fbe34e69490d6e33bef7bf71bbeef44b4b8622fce6adb1f271fbb8aa041e9210c3ab7d06368826c74e633e6503e5169a10d9a0781fefcaa63929b1141271f5113964b112758219b6abe824d9e876aa960b5568ed0e5dd451f80e129a0c6af255ca3616aa563205eded48f0507191656bbe91de13b231dcc6d506bcee35da11f6912dd5ce9cd15c6fe38a688632e1668587db6a1ae0085c51b0372314c54a53c0406f21c985b6af6aa79bca027efd054c4ff445796ce2b1cac9807351d0ec328b5117f16621810d05771c6c670c78095de6d6fc60833d837b6e913c18945c3c2afa985ec801f60fa046c8954185766010c15e0b8fede2b5c32894e87637e4f2c8bf27128da1e903648338797e4ce1ed12396aef4448e1d330b4f9994ce30fecac82f78aaacd466ddcd43431e3d1284cb5f4897609ae1f44f3d309a048d469705b8f9a2f147a1b1b327a9fc89a08faa2a6f217c7413a3a08cb131e5083e8334d9b6c6380126f3ade8fc68a79eed8c5910a270809b7a24469c216389157b0006859e26fa5248acfefb730071551946659682b5429c0da3a8250dd88c758b5cb17247503c0e8ff4f86e9a7223710307365f0e6385f8779ce1d0cfd3a397f5e3d8c8d604d2e0a14d0e42fb5139db1e3ca5c3da9301af09708a5b7a241e0df810cb1f7ddbd8a45849f3b7a605ebef2b6d9cd9570895451eefff868ae0658f27befbd8195465619d293a32a520cb6a2c6418d5cc5a32439f6889ad2c4898941431960ca0f91f78c5627f25e98d07bdd6dfca0f764acb4bd20509d19f7cdc1afde4e34c46e32262ac2be45a251d1f98df7aef62f63f54d6b87376ce94c4cafbb27dff3aec0dc150fbe12afaa76353dbfcfbb2bf844ed9cf017c9a4e44760188217c80111cdda5b47748bdb49e7e92e0f4cc9a813fbcb82286e90c79326a07eb647032a79e04b17286474151a7073ebd8b9bc1c9924f684d85746c8a2d1de05aeba8ed67d4d897287563ccedf33492e91f8d5c839221aa47def490315942d6c370a93ae04fa607530af7a97e1fef60c6afc09f3dc6c4fcee84b694a800c254f84a2852552b6b40802f2dfc9d1a48ab77bcc7ecc6d2af656f5dcdc42fd33fddc443a6cdd80ef6c2bfbf30aae536219820717c43243fe35196109a671358537be3710af864c6a0e520196c6d810a34e98e864c050710e11b565611976ad23ac4b463e6c2faf0d10a217651f9b484865a8aa0cba1ccdedbc3491f99b0ac03378d750378fa2abd270e6c904a4c458728ef13b33e03acea70d3a99d17132cb1a9bd3c09142e7126c6943615f9aa2ef309b0cb2f7e69e2206ef12b512930834434dbc063cfe3d1e582e8b924a0b1f1fe6523b334689fe39edcb189eff107bc0ae332de8cf5434ddf9b81194d07fac668d17ee363aa4838ce1c5a93038793dac05535730c313d11f84a7745d6ffba9cf430f790646f99773b69c501821ab9a6e8831e8b30a85f89433d70509b3e8ad2b90c1bf75218fbe87ad25b52d0a965b54108f3f11f5adb256c427376a34d274e71592c7a03f406f21d9338061c3df4c1b5c55ab609cfc51110c110434cae5eb0517843475014711b1c414a5e28090cee4892286af35554ef8873435840fe96b6c3da02de1038b85de42d53adbbfda0a5856b0e28fc3a8e7f8245a321eb23d604557827aa11e828283ee239da9e74091455128c22a8b79b19333b2fa3744ee452e494151046376e74eda0027ce634cefeb07ec5f86feeb477b9f0f21916e5d8303a8c9e2b9ef819ad4f1b48c70a6cdad71e5e63923ffe8c660feaa5dc68efa3c5d4c7b32aa840130849670ce1ff2cfc2a01a3d2c7e8701c42b0b854fe741304ea8f4a1e579e684114f03f5e878dd3444d3cb9150ed5342c2d447c8340152ff0c65c24da9b9b3adf1923971123f5215ba90dd2c0abcf3e871e085e36f919d1300cb79c897ac4c30db143e74374658b66a462d63b132962efe22134493f44a7fe967070182156bf06bec214f9cbcac7094e2fe70b11060cc378616712ad62d3356c6d48c1aa6a8bd8d8f3b2143501afb6c6a719b6a882c506ad1703b697f098084d7bc29eaa52f22ddad005fd57208f5d69192908da2b100b0ad26b57c47912717357413ffa7364944f2cc4f42e9666bf4911ae73822e0dadd3fe08aa3cc61c8df1a5e367e49aa76a0c050346fca4a9c8194b530bd235e4856e084fa69dd2326f0f99fc60e5c9bf34735cec08648d3024940662df555d8dd4d382ff26d0fdc50a1ee1e93334b17c0b4dd7fb70b1c98411299130af26ec0cd1a6b599ba688e8d05244eb31a946235181b656b91024da5a8928a6a6e324704177b1438d6cf0f4aad179d1b4ab63c311cc5d0c713675e43fa19abf58aa0297e834314a62e86a4d54f06e8d9e68952e7da48163ab6d4e6ad8895abfb4f1845d01be810c8207846d5ba6e0793a5b47a3d511f508bb7b95c17f77d8b000f2e181493942fec910a66f2f2c2cfadaed0ed37654b8aee2c1983cdce2bc1acc52f4a106533349c4a2547d558b9fc0e46dc5d32dcf0d8a95ed81a0673d3f06fc9278efc55cf95ad13ea3957585da66d53921d2e43fed1997eb2746bb9d92dd06661c1179cd67d4c47fc64636eac58cf2b3d4cd80d3d1bab3371ae06018c3588dd4636746c7a9fa7f3b7540d25522d07a263520bc7549edf087de6790ef925618e406533a76175a601f1ce79cce21e7db32b8e3a627c6ca2e551b070e37cc8b622db7faa4f442316a5ab8f20bdc95b3373ee3641123154d243941820b03b16456a5eb62b64d4c27fdc5b2c94811fc1e5382a43f76c9ece85fe531f451941fe3eaf40ef74894a24ac81ee4ed2bbab8c37d52d23445bbd0ea4f40ca0cd1d7d13db20ed5f6803a3691f6e460586627956078115d694365dfa5d8dc9eff6478e7d42a87a88b1eec1b41a7e7948014513e57402b5825c65d03f675c1e845464c9760034d8537b491c33fc58c5ee13c40fa69d6f6b6b0f3f1f7318b04d930c0ad30e6c6dc7000647aac13a640f1d218c6cfb7c7c802d2ea146678f3ef3cbe167b57052ea593397e5fbfdc25ff4ac496525737d3c109f3260e7339494196be2aa5c0ff4ca8ed0a4d72e1be565e7b7c9c1d995d658e9419a43c299abf04b67b666526136d106661082cf510234514ce65b1aeb3531a25972f093776913cb9f711d3b7b41e133e04224a695f62fdf3dbb8c8c00575019f6dd9e81bd848ff55409cdca269ac04d9dd82aa0c9ae796e0f9d71d426e2d1240676f31973ce059d1b0ea3ae438d4432a4e671e640e073898e695ff040d2b69e909f5c1c4962c4f03c0278e3456672098992fd8c3e8ab5e586b218b825077c1446229a99a063b38f43388938ae9fa8c19d532b687fcc38e0a7b59c42f6bf87a5f4a2dc501dd43a5563593df8e19da57d0833510ed678a072a86000d720dc59136f0d8dc4111b54c1f2a383bfd777617c60a8fe295227adbfa0a96c23913bb39fd18d6363368ff4078751d46426f272101823f089457ff51d58b1ace5277db1746cfc6a170724d4c45b9c8964447df521920815b38fc4680c7c248118eb9255cd9a02b43e521fb2d085cbc65af4f54ba9506926ff716989ec05fff3b81b8164daad0ac91bbeeccaf940ec9759425bb0808e0d49afdc1934b1a0258760de40d6c55785f7086c5888d86efa52a76a3dba29e11fc024b08574f91f5402899700a8a74a5ad70b70c1e7a8b35f776f24ca61898e513a95e15d05fdf5fa6214d3032085d3d10188187eeca6f7349a6a45e84b71f442c84f4976f822349603f37c0717ceb4e792f826b7d6dd5b0647424b9d4e6e15d8af79a00e0240f5dcab8304454870eb08c1c390dcae8ddb0bbf066275f48a6920c49d121c410ddd5cee47d1ad1572a6725570afc7f691e37429da54604a51ffe92a4f82edc1e5374e3df7c22ab4600e8d9a496fd9cb1582d89db9551866e7830167f298d65a611e69d56adc6971e2c1318ece2b8e92206724289e08a919dc3417b82c90bd273d1962689edf0934032807701f9bbad0e8d78df6d4b2faf57b7a5109b8cdcb3657b0fca42d8d2d78ec617c37af57ea90aa3abbaf31086d63bff97be34b8dcb72b6bc81cd86073373faaed4831495e602c4c490cddb995381abd0cc75fc050b223d11a69024bdc32eccd076e89e5729b6c797e99ed3ba6767feee5644a6c3879a5121b3dfcbce2b5909fa152db1fe63823e5978a52a4d86c75fa036ff301c3c16600582de5387d292421c01a8c15a9595c85efcc1fdbf4c8dc4f67d2800a3346724ca734a2f742bcb3500d4ba9b4679d783f8f4bf24c54e7609214f7d167cd44e2e9c07c5e95610f636d3bd654e17aba51fcf0412e0d9f08080da6b0338d11011a07b97fcd169b58ff691610423e4d4b39bc9a302eaab3ce94d7ee328f2d4ecd3b9782f1c82caa340331c9a29c0763ca9e767a707573bf1e7b7457e6be9a625fb630a1827cdb07940ee010c20047303bdd302ac52990e925bac481823144574b4323727f4015582652312ee6ad94abc3ec128f1063bf976b972ec2e8c1ddc15e700f1fa4f4ca5e83243c579c87005d50d6a5da9cafed742fbe7091395bd3649ecb7ff3a96e970dd40a7e39c14782dcc58cc52b67efef33bff79965543eec33e33b168e9fcf319421577def97f2226d14688ca0de516d794edc9192c0338c43176fe09e77d03f305e21e641b86fc83bfd654af203f9402fd970312613b340e027e15174c7428c281bca211b1ef05560618ba4323b7bb60650f50a04b4255ed2babd46fab6be3425e7f8208161c108dfa8dbcad4784779a62229f7d069513fb73453fb0e225893c9df1ce6e2bb7f457623516735e06aa23e8d8f00792630f38c94d4dd0a22e708b0af0fe33a96960d6496da705a04bd48a726d3bd1c1760b6fab9de603125245f7f9cc13e0f509c48b709081c251a433f45cc067a13a65fffc808f29819fc32b05057eb208fcb41cf033df42912b8c619da8e502be6a241910527b7393c03f17d10e57b81342620e318d8f8f1b8225449deb2252eddb6ab9835eabcc3d16027b5e8d65a865faeb54ea34ba6cc057f47ca2d5fb3f3d830aacec4b06296593afa9615215554ab9b30ea17f1b9e5d8a2f8615d721ee471aa11d346c3e6195ed604883e22c6ebd1012c0a76a2fbcc9528d1bccb5e263b9a15b08d795b3be66021eb492a5e580d0b5b54e05643210cc4e358942afd02494f62aa92efb41bd14f0226693e499bb53b7872824ec8b30172ad941bcd2762514f29719e134cab4f0e3b9571bc442d8e8a3da025a574933c62eac3072664342ec5a80de274226d0676de56ab5cfe82ad507005b5977e5addcc4f35c16b7e43d1880dd65cc44bb1110acf94ffdea5fef25ec4b2bb50826b609e650df71ef2605e527a2f3a0069d6feb32a862addd41f4f98bb96101afb43b358629010e6aae3634021c426a65db4ee23cdab7f12f08c21b8d88975719fe54ab7da5a14c918a69ff88828a2e643fe68319b7b3d670ecf624c5aa526bbf01d8871cc643114a48f2519a9602a013eef70dd483df8e14b45c078aee65a6177c94d69c75a99662874ce6dc193fe5877b8fcbb68b816a92f8bc55ab1afa4adcfa7721c38a3501427c090822ed011a666727e8c2c026145b9d936b5351538c99e5002aef61050fe89af16109b787f375b1313d86d22472952070c51c471e1a7b54d286360ac6931cfb9e44cb11cecd0466b9d9432903ac8173f286e9ba779cabd2d4cf70c2caa1fd90f49cdbdb9c79d2d7b4f354420066e834140ae65784b24b5716ab4cf6d90f0e74476fca68f1ef98ffdab656b2f224cfb583b2ff7d2e2ebc5a71bc43a832ea6b780e3576b5d0663d0deebe05ebc8bed47e1912c4ba6a3843ce864ed8a8a8919e5df31f28ac9727c54c63aff87a18cb6fe69944855c7bf9ca310eac55e1186bdab203ec9ff916b1e266322b9011f496ad4909ef8a3b7cecab34fed789c2347b064c74f48ec635e0ddb08a28ba3984c1f6cf23072444fb8a288c85e8e1ae4b5429e67d68993dab556b6a95885115254fb97b438554de3787bd850d8b92acb63d6484af983cbb920b69ab1213f8038417d6fc20ece113f8032960996cea18b9c245a35b902af2984f10992a00d65a629d48d383c29f164cba7f65daaee8dcca76ae91efa6f863ad3cca0f4ca3a3982a755b27ae5b591d195bd4e6092e26d7d198e397d1262acc9f877ebf96631ce3594a188d00a7f46b633bf895c9b9d9e9c0d2272102de530ce057572b3c13262d2b56f3386a3260022e3a2a549c9621947e71087ce5aac7b7290c6f4d208da6d37ef30186c1da8467efb6ea7508365e606f206609c7fa02d849452bf2cf6bd5a3381b05709e7bb0f9541dbe5b8c03369505040781d78824e0fa7255d7f4a73710bcbc24ef80bd6ad5a650685c2b3a203a2f1f2706e10a35fd4425021d2fed91c72d0f91c01e437ac1540c5606e42597369efe5816e5c4a53ede7972e639ff9e9968fa4282bbfc0c6859b15cbdb0381fb71d19b534d27942d8d6ebc11ab817d2b235048c5e42f9cad8dd32c8e46ab8b78582b77393d029ce596cb8955223a7011894e055f4a8766db4873abd887cc643b119725bf441c7472d5fde88aba00a4243126c47dfa1487cdb205debab6a7911439b1d4aa99ddc6a973811169592ebbedafc8b39b5cd53ba1cb53ecabed7ff50318f8ab949ef3fbb6652859e1b24d78c32b6e9b3fb15ea56c515746f5b716d3ccc54e2956deed03426cbd8856d5cb9b3e963431bc93a583d8be925d4f39b0a8d69bcd4d17b365b7a21b0e11c313e64464be47ec02e128787723a0ed5d69e134cd4b164a2a676a90c1bb01ab77841c14f07f755eb19d8ec08fd4e82f482139f7676b68d8454bedb9e31fe1a922bd17f92f8a51a05d5eb40d52e1a3319c35ae534031662761f979ffe0ec4b7f509114ffa1f1931f9b716efe09221dc917385497e826067f5d2a7835f825fe6a4467d00becd964ee8ced4326ab42ae112a76e9186f78ad3ac4292c1bcf39deebe9d9687d70d81f2c77d8817fbe591b771d30d729948d263b82d404d49366d07c3af835e29d6dc059954a5292835067924926c8cb553f5512b4cf840b72e2b11bf14a6181c2ad16afac42cc803679d6e2877e14b4e4e85495a3e7d7b11a6fd921320d2a4ec9b8c2b31d3b7230c5def8496088456487fd4256bb0cc13f32b8f85a5297d0a6e48b597f6834cc40f888f1fae8658c5c041d6db52f72cb4965740c964414983bbea81a408df875dc678e3bfb00d25ea1ee862fa407fe0be363a1798d95a9a26e0741378f4acf3678959e39c21ab717117740e38a70e8407322d2dc9f25b5a5b068efdba344f7c80f37e2f05b670635e9f825926621f41621978857670c29024822774fb6ec547f97584a0ee254cde28373315dc5b8bb7dc54a611e4da783500387ac294a6ba925fa3fe6f5d0e4df65d359c367904cb5f73f1e27f4f7dc9a10bab44bbd34993f7e301816f063aebfea8973af6fdf6843a8d2fc8b8fae9087efa8bea09083f0f72977a1d64f7d7c709f20c584726e3a043f1f9b88f3a406c70c25e1e18fa22f93c5a9c9b6554170022919cfe0b89f56569c92dd0ca4be1eb0780971ad4f446d0e8e5750859ff8650372c4e600d629eea0ab2d1bd1ce9b76d7238eba2b082379523eff4c492d7355e7dfbd6add7e4e583995a74484b4e09425230e9f2d35134b3973973afa6497ff21322e19afe59d06ad4918923333cd75956865ef8c39a383e0f88f63fae03c81bdce43ba6a1e630745bc09d05a613f1eb5e96fc9e84d73a8a59e8c3c04722cf01c12b553628f7a6db27522ab5ec98c3f2267af96d406aa6e41f990c0355274f2150af3d8fd10574f1d54c1eca8992baa410db7f26adf90a2087b7d8e2743e45b8ba15b13380831ecc11e36c339352115d97a59d3286ea586b4c38de38684ce7bf3ba16a43a1d958022f94961439fc8197faf2af07330ab77d761a1bc486638612bedb272936cddf9ea63e03b3fadbc60781b0bf0f7b11ba3e8e787c2afec01265cab38c7f2badc1f2730d44d1ba90ce43ffc62fafeb73527d5e87049233fac591050dcf375cda0a20310a60a37c0c090f719fb5db6186bad3ab36d9a0106abecec62360cbf12e2676d712a2a343a5251532fb5c17d45083340567c46a673822c3e0447649b3d118417e8702787982f434c1c5d6a83eb83c8b00c565acebaf4a67724af25de94c7eb4bde3d8c66c3d6aeafe50a6cd90d3672887f95f33436f34dc80909a3942d3ac69d96a069981993255018fdc20f1aec272fec8014a18bea4d573952439bd9392b6a03faf44ec15809d361a2d61d420e74c16bbb046c5c7b5f8b9c7d179916225930cd05c5b704c3c89a1899d949bcb38cb28a1a25060b3ed461b6b19b91b526ebb3998dbe671802d9dfeb1de6ebbd16d43897aee7c0241d6d56b98551831e9522f397e4ed2b2585eff6acb918e3bd17646641b05182af656a92936f13f7de52284dcfad028c4db77061170e0ecc4e61bf3686cd16c4c9e41cc03b88eb47312f91c708e7a31879e54178dec38fd6f9dcddb2e10c89184078280700b199f6c56cb803d425b76cc7894bcef247c2a4fdd28f001586d15d9ee3022ddf8c35bef30a4f7a1573e04e72016f4d71e23fac9570f406dd044b90169f67dc23bf666282cc86788a926c25474cdcb0b52f33274e274d63a16e59fb4011996ede2e3ee48ba76ed7730bf8f8ea664229763882c1feb3286c1f808ea389c9cbd1f5d113b1c641bdb90668e3c26c18028130b4c729e98934a54f37ac942d752def5f7971ffffcd4e2a298abab97371cc395270e5a719bc52a9aacca8bf081f7742a518f95ba3474e488816010c87f27eeeff30c9c9e9f837887464f620c9545147d75fc0e714ca5ed5a5c5f7e16a0923609d2e85a16c95dd35d86c9136766181b329b49aa3611055006f59214a12969fe212d6966efd46491ab7159a55ed95038b00292ef8fd994e404482ca5526b63357e0aea025465f23130a593d02a181ea76c782580c6ddea994cd4415366134b82efa288092e58aa61d39a83e8b1f11fe332d204a913867ecaff7f0b6ec4d1e47987db450aa4ba084ce787e2240ca20740e8b4bd915d1cb081c28c6db9197c1a87a86c12d06c1988868806ef72abfe9c3064b9d15218f45ee9e99bf60ca5777456e968dc2b0d5933b380378d8f66f02acf35d68b756682f6b0d5f3ff83ff42caa0994e303a80dcc3eb11b700e697b2d640dd4156ec1fdf2572c59f95ac40b74f1344683a87c72ac636f8aaf20182cfd2d1341a9a2f401187eb08e26fbb55d985d91b8dd99c35ea4122b664135fab3d4714663329179f8c2b004cc1c95aeb695af1bfdcb22b1744c10beb15fe8f2e292be2252862d2c7ac78ec8a2ff07670d5cb4167e406277d10b6118c509a49ad88b783754b174fc2640110ff73f29f13858e699add6707c3532b9e7e998d04972a1c0fc256d66bb4e0acad44ffe993cf6a26cb1238d23883bacfa6886deed47a5cb9d52df7ffaf7987098413662d0d6895b6fd24a88283ea2829d98e54efc9a30e7227b6028fb467e6872048bb7e95162b398475139189334a8882b780fb1a13c842a7f44b0da06c3c370cc6a992faf8afe383369e12c7031124cd836f43950568b7c8d2d64e20af297722e5f6da50853cf0559c5b996a98b17b0e966a39f5d10f474218608dc6523a48cd30e624156040c6d278e9b2d855860d7cb80afacc01a31daa7a9fe6f9bccd1d68a20ad03c6a0bc2ada17c9cc7c56bd8009df1f188faf090ee758537103c20edb7fbd4641c5dc5de161e4f2b67998ccad6e745f5e34c5d06ed8e7cad43f5b4d5012e354debec613be1e6e0d34d41a1bd2be49756f1e1c7f642d06b0f17953b764a69a8a08e21946da7715055438768912f218624cda72048440b200bfec37e51309cad40332e1542e9e0f4af0d1fa152c044196d847b0ba36ae8619cd62b8f22db8c81ee0ea0024de133840177072b39b3495f20676fc6fc262d51f10c5516053305226e99db507d6e1b9df7097e195999c2bf4550a5eaecf86b7c6b0cbf2b70fb189138d3274d3ba57f3b07d394e3ec6edf170240c30c640e29247236b74f8fc49ac8297b75b8a0468fa415c51db10b07516684ca7f8f74489d2485734cf8b11f7a0f80402b63707b026f536fc67aa096ca4c0d1929b924bbbb349fe574cad0fbaf9d964b8fd9072059e40b2b2fd558f4c05a0a2681de55e70366c0804acc53382a964f0ea18caa61ac861e6db8b6211e9441a2cc110960d4a1d9d997ac3417b4ca1a2e0f96e6e5277c3e0f7da26a1d0e3c29f28becaaebfb46a46c588d92b646ba050a675cf8278d5243a67aa0aa3982dd0f9679a3d52a4b4b662aa4829c326e9e31895319214ee7dbd52c1354b239d1388e9f2f6eb83b56075e1781446392f3a4181c2fc8e459ac7039d546ea98e5bbb3228feb80a8e33d964fc2e546edde908fa63d5ee061957d2ffd60f394109d3bd08680e75ca139d0a7b1e1d044fe07517450a4bb080d829c6cec1d0184c4f41ffac44394a8ea194ad6c5604ee476008fa885ab24dbaaa264b62fad8905b599a7a7d503ac82d7decaaf20cf28fe00257adef57dd58a0698812b83dbc9755e679d548e3f91e89a828df61989c2d03fb6ec5bd4a65ab26d925e6ea0512436a1c09c5432505edb978b76adbe55a8c4157a39f14986eec7098094a1cd9de85d572b67a55924d86ea6999d4015f6b62e0d74140c93fab7352315c3577be251266cb6e655a0593c29a0539aa8f2922c899ef2c65d40a7dbc43196084d9fc40a5ed9a398f95861b594a9ccafcc93ef37345e85acf780f6bdd3508f5f84ccbaf36ab4617a16c8cef7e3cd73538cd2ca57b18469393401ebbf27ea29a158cb35fa8114487c01e5c9faed616615ba4010d70e81272f47198bb7426983fd5af548ed61462752f12875b7e5b13d4a5b11e006c0a3156fd3e5efc39c8cc95f67cb3828ba669ebed0bb47a54705272e8edb13ba4dad7db21f7c9cdde08eb9c83af4fdc7c55dad47d1cb0f23fac071b738b9896ef8f5c28f8376a05af05478329578f4722cb304cb968fa05a4d4bb949b836a9272a6553d2e3ec7e3f823bcd3398c510bae5c901175d4b79bd1670f13678958a951a126677ad6a8423c6f5e01913d61273dc94453eb03f86c71de63516578ccb25e95191d495796b27c885f106fa2125bb2cd6f43b67daabc1b5374a3d6e5ac4d6c6df4ce25f07fe0397cccae9a45f67e86e9933857d5736a27a5e243d56933e5099ec72c97511c9f5ae108e81f53c8a249f9b31347dac4d16426f7d5e0c8bd9dad1cffd454753ebd99153df522762ed1a55bf022e66b00d8a76947e38f2e7c0c001dc0b116f0415fd5ec210a5b1ec1838abfa098de526c2b2e3bd2999c3dfe774d7a6eb984a7679acad7514e6d65c459cb073a08f3090aa037fdc9afb0992fc53034aad8943eaddb63140da2be1db69f572b4ded7a5d48b6c1cba4e57da6c87f05e6b5d6ecbd86299767d4f32e3e69408a0abbe776d291ec7efb3c4204a95f5cff237e84737c401d5b34bf81b07920b0ae1b4aa580b21a0eb20098def3f63d58dd640998594177e72e79c52e730ab10d345efe16fbba9e2b492b7cd504f92466cb3ca861cd353e9da3bd34a5886d4c78710f26dc04b6033d735fc01f38f28dbdf3ae9aa101271944219b1850feb2cfbb90437144ab3ecc530c800bcc1665da1662b445c10b4a16e624dd6cbde2407d2727613d9b44006df05d2b370bf0c0d9badbacab60a5b65ff783936e4093a83fcbf14443e76e60c4f9348b0eae11ce802b80ac6405f46b550431056b305bb0fcfd38ade34fa696e14a5c9f8d4398c307391dc26518b949f4814343e2bc6badd8364d82c5017684c48062c219e9a8d856488f85bbaa0f69a0f95b911a65d9e272ce7c5f0b48b87a2604936854688fb527dc6bddf4cc89813fa4e507062d378bc2ecad6c4411a53845461ccefb18f81308f3dc665b2e0dcb1883bc7aa812ba28bb2fae20aad694afd42eebf3d6bf398e8c3966e28b40c9f53c75670945ee5719922ea58fe3aaa6c355d383bbfe9f8d9165f55a2f145b1d8fd823f165c7950528e06e86c95d2ee7eef98ed9061d13048429182994ef64506a9850da4bae631294c2022dcc1db405bc4a0cd04d9e86791a316a79b4c35c170e8ca1298620cd5a12116bfed9a44ca507b5c2b33d5b3eb09fb0b8319c3369c57413b1a70dbf893c3d08e0cff7827dd4e41952a07ec4cba52000898e1e9ded1c2b3d1682d50998d66eb8e1a128948e476080dd4170733c57c1baed134f780c033c0cd8e7e39ac131146663b42b839ac249af3affd255e2bd661e1519bedbe7e86498a25332edb0da8df8af561530890ef4ce210c34b4b3f3060ef975ede6d71c7005046f5aa07a8c4190e8205a2e4bdcc9a4eb9600149dca2202ff743cc1d2ce3691c0540de91bcacc31801d06856b12a2292d3d8130428e503680009a50a1a13a1a011401f0aacd3d748d140e4b083520c437de1b832ec411218991c30093015c2c73693ccedb20a7df998e1ad4ab0c2d9b6942926059ce30a6d6599acf93925bedfb04cc9d9df2fc28417243017d90f920ec24ecd642aa18b6229e8960ea96ca5e4ee23a5477271c7ca7fa6237cc61960654e79dfde072041661d2604e19af6292cef0783af6aa2065e934ecf63351da9833d42edfe2efd2998992f2f25ba8e36a076e51e0577ed81fefaf5dcb2e904087132bf0323cddeb5a9fd2de17cc4ce9d8d9d086947233d5fa501883d9c8185c0b31a5d593b167a0ecfce67a82c7e06c22fad1a00cbeea448dcdb687609097ef1ac4769092ae5c01b7f49686e4b101e6e5a0f9c840a9aff6fc4ed9872820434f06c632b124f91480f1ecd5bb9019d647354b8d5ce8832d41a525b8021ee08e82e2af58b1865d2ad5fbf7c2c82cb8dfc616e3537e41cdc531ac9e5b855bde7fae2b3d35bccea048ddbfba85fccbe3c5ff67cd5cbbeae7494b886467be04120a29562daf332138c498f167ad3776dec17e11a18a70255970e4b50e26d8592cb86c2c07d7dcf308ffcaac12aa58301afa4f92285c32ed503a47204ea857fa956309c15251d3303b15c6b8ffb733967a3494a003cf76a3706378aad7ac7715c689d7a6b848a127e3d5dd6701b022cc86d0814e06129d62117f8a8846b1086636dd196cdfcbcda2ffa6dbf3542c8269bec4d36d95bca1d540a600b2e0a41a0092ef7edcff4edaad13638d991b13427c3359ecdc6909de34edc794efa39893bcf49db9dd8c2b63477648c813a173558aae95b733071e36c137d4bd0ba5e8263228789064a3ef0fab9079b5d0c7766630d194709293559d86e828fdf210db81fa41c056334922da79452ca274333cba66ff05a953c9fb7beefbacf6ace19819bcbd79292a33669d37defba4359bd57713c0bab880919bbc9c1d7ce399e97733e40e643c1f1f8408aebee5028041e45b139e767dc9dbfb952dbce23bbd374d5c99bebe2fbf46ee341ec617c5d652bbcf7de7bef3caa57bdeabdf9deec37afda3d73ce096d0cd1337c3cebef6540bcf9f7ac67519ea68956daf6ec6ed5e1e3a9eae64aadbdb854b4f1266731e74c48742e8459bbc01f00099be381e7f1a4d4510fabdd80b870cb6e756e46adff68cec51936de0b7c75b71e42c135ea8daa73630cdf19d8218c9e21dd0b3f038246101dd33105b89079be372704dcad76b3eea4eaf6b61f52dc2bc699782d4abda23eb5ad79a4d52e2e3e5acea14d8d804ed0bd4c87f04eee001ec8a677e82e3c8c9b6a8494d276f064f0ffeb89083f8e98ab108853ceaa82959cf2bdaaaaaadfdc39b9a97973598350b00ce8c58537e00dc54f082f4808ce09e004f0a985035b33641bbcf06dd3ede194dcd78ea110a9bfd3101c713f6bd43187c18fad8da67ddd0d7e775ff8c6c1611c9ccb3bef043130048ffb35330d32e9ee64d6d2bd70330aa4948f652b8110c2f71e0c0e0ece07649eabf1ba8831322022a0d6caf3a6a94ed304e1344dd3c43c4d70baefee9da26c10292932748d865742980521e4320d681b240497e149732e01fcd69c3bc00d03e9662cbabb4667d18d51faea0d08e199efa0fde1899619625dc850f6b91b04945223383838259079149d73720e0e0ece0864e4e579b3ae02dc11b273dd8e087676443084076cb88ea7081bee86dd77025cc753a4092c195eeb2a6173f9b00d177e632b1ddf0564c17004ad2cf4b89d2449121f1d45ddb969fa85104ed334f5d0a6e79c438173ce39170a79e1e0e426f7e2c0ccccef356486dc3bef3df8c7ac59104208dfbb6b972040071d847683b93034bd7738cade7b903a749475ef05be0e3858d350b818292a42182184ce2e012f74a18ed97e2b2a9b55f5aa57bd071d74d039e8de7b8f092e4e11ba43373de79c7b4f50e866e2a7699aa677aa070c3de79cdd207c69f87befbdcfd3ac7679da8ccb341838458c00b1c15c273f56c63364484bf70d88e414c171a2850cfef154d1732d05e4f02167210b3977fac3b9fce9e64e53bf7e77fd6a8ee9af1b42c6a1c58dc6bd9717085fdff56b425d0b85a1823b82e8a12a766e7511cfa5600ed1439fb41cd8adb716a53c8c1532c798d6c4bb14bfb2253e7566177a13ef96521ee52986dd49cb2a61779789a8458b3d6accd40282a3fa35b2ac3366596720b72a597797098b7de45e6956e9b25cbd8172b63ee73b92105869de5dbe94d9f9402f8d6a5b3c6d506720bbc5d3bb8db7257ce0dc2a028957826fb5db4d64e2e656d6391fe8dd6b753e5c67128eeaf1952dd1638fb674dd7202c3783cd91866379a95638c73ddfc318dce6376639c3bb15319eb41a397f5127ce32dbbed5839886f699785d5b2f0ae7e66ac4fadf4b14dc01b5f91ea49a0578fa4fa8973ab25706038ac5f4dbc1b2d8e4cc88db6c47729fc8fc638f77218e35ca711515df4ae44881edab1f251146922bb8934ea5bcdbbd465f5d0ab87aa30721d1b21733c3b7042296571cd21ba6c4bf17ca73916cd559a955b51bb4e2b0dc32acd88bee2579abb97b639317aecb9d00a6995dda6ba63c5869cbcfc8af66a0eeaf594d2b8eb8e155b73b0ac3053c8387ede8855db98b8b9f57c5a81569af6b54e7ddcea5ad1d83a68e5b1fa8ae6de4b75cb65a058551a0e4ac27e59a797162dab56ecdb75eb9546c22ed265695642c75e5d51237d684843398b36aa349487b40ac5d2b6cbb27e1de5f59946c2401a3d8a0642d1285d822fa5613909fbca47df304bb3829d451bfdd2f88e1e35ec9916cf42b382d9ed6654f36ebcb38838c0e5575a8f77a36d02460a19df490b6649c66f6a4a9cd2f836dea471e3847a850594ba37e34d4e83d66a5b767f5c7e6f3be2b7fbb37df380747313649ca669076523e5847b2f3e1e73b1839c1c58fc85901907f37d3587ebd74d270b561c0da77a233ed61c51c3c1efa90ad19b749546f2ad42d67787a142f6deafe6e0f75f7715e27de2ab6d1990b74308de6e84e0f327d468e4a775efe59ddff7695b46e3acec1c3fcc13401d584131e798212fc1b7ff1e5f536f7cd3249d2d9170f0a7f3dd9dac12946d0203dbcd6526a63331bd89cf9d2c13fc9a7a192a41b56d822f371a9e4569ee94a24fdabc4fb9c39aa7f13be6ab78d6d12e5047bbd874378982157a6874147851aa7f8e9d7eb4ec98761d8423ebaae6a8fef91cd336f891d445effed16845b357ff7c5e550960bf2a897e078c93aa6a49d4d6afd0d3c0a82759aa5e8fd4ea68171bef33674a76a5a43cb325504ddf14ccba0a14aaae4b24ba25ba2c914824bafe39668944a24b745dd7755d51b8cef73a865d1fec1feca28117973a3a31edf3c9b2cc3dec23afeb54ac38aeca3b7650f1aad6e7f309ea681778e945c3827dc5ba779d063b635647bbb8cbea6817089fd29f32b420d18244cb91169e969616245a5a9040a2a5a5a585a70589672d2d2d2d2d2d48b40489a72edf8c394d3e2e9470c73ca5d978938fb88307cf810b5aa7668da415b2ec56b323235916ecd667f6c96af6f191ed209de5ba4543b29cb8a04f0dbcd9adab0662556545a4124a118942a1508886326ba2a0a0a07091f9b816e87396cbba6a60c672128b46ca584e62b12eb50452faf0017dc0345cc90c91ac679ff4d3b2be428f65393ebf3212b5383ed39a873e6e864969f9b8960f1f3ea8656ba05503af5503a7dd6aa065854217894417365150505094643e2e5603b32c6b17e8c3c9ad79561d9ce08469bae41ad5a7575cc3ba3badb9f27d1d421cd3e92f6d668aa77693775c35beb38590a78e435ad72e5475dda42cad6219f0f2113e6a38e6e3a536332d8e38134fd55ccbb218be2089a88eae42fa7c1e3b9d1a3da6659d819e7df2057d624b5c07cd4b96911df449411a0eeba05fda8c654116b64b761ca019d02d10e8ee3334b1c3f7de7befbdf7e83f359b245959c9b2a42550fe390ec732369b9bddb18c4d5ed03f7737fb3cfdd8cf47c361fdb27e5d379b9f092dd07c16b258465956536a0a06fa1c4bf980a64824126118866158922ccb66c078f64b9318569f812486e178d6b157494ba03c3b8ed041d63da4814e330d47e8d951b49910f60c4776eb28da4c76cbc2703cd2129f63c72159463dc83a9681693840c7fed1664016e2c09efda3cd60cf4eb1cc5aed525f636548906f468c9fa696c524465268312b69ae482b448fa1cc5166591725cd99c475cd39ef6e12a44f6d9bd3f6189148b3c7e8ce1ea34bea315a514949118944a2299a96150a85425a4829a594524a4cdb92b818ca5db68384a1492947d4881ab5cb2889d1eb1128292574e239f1b4800494f2946de5a2872c4be5236f13302ebd32ec195df967e503819b7b317173a9d5408c7bd98aae7c567ed9d20a5d4919a9a4886a45a928b5d68a526bad14858485654e2955dab202357118b200a1b0d451fd5068633305ce2a21e75249a0430c5c47a06750446878f47022094fe04e1629b89b5b924510eee69864817337e7e47337c7062707c6e120970f5fbfc73954573d80b0195a53e35357a5a5ac4f4851713aa5599f4a3c9e2e99ad9e554c14c537a46511f13eb99e4aad447da3ee96280e7aea956f7105a5a4e60d09e7ac39ac5376a3b72c6c976aa71933d0304998a456aaaf4ea99c1a57ad479f9e52f9a9456dfb06e3c6d0664139a76ab196817e654bf2d29270444b22025238a84bbbc99ab6464021c748513176e7dc7eec98aab579eaea34c96a9bce93a2a8eaf39355c2dda8ec857942b64969732363516a6d6e64e837a983f6a30eeb2423b2bf93e2a95bda0f7a9b7aeb4f7bf647c5f95169aabc4c7dd2a286fd7a3f6972fbb1eab0accd8d8cd55507b536cc3aac5fd2a8f9e86f4cf38c40c4b11332c76384253700d7f118c1c8e5ba233b8d39ba1f230ef6777a982db20d5eec6a3fac5f9416b5a9063210ecf594da0d8e68b8c84b7da34e4d31d4a431d5db0da5c4bb2de56d0d24c20175a81a0e668bf42ffba316512d89866404fd3b9d2165845c47511a3dc728336935efb63504074e16e10c500e4f1186dca6e164824c2308c72c4a32e39239128e0ce74ecf5aae254d931582716e84dfa124cb702eceb5d14f5b81833782efec0ff7a308cd0fc78e5d0ea8e327646e0b2c8c5cb7c51341ae01aedbe208525c8bce204366e3018e67088e0941f62e4f5de2c0c52193a73ee2c7a322a6c86ec34e76746fddf885146cc10cd71dba19ee0c43587206218ce0086a7022e31cf5b6407f23c3a799eeac8d3bdbf0a71b99e9efe547bc19a40713840a979ea1c20313c4103447a417468e34b9d60e114a7037b7736409bb25fc09b695c1b82d9773aebcb4bb1b5a2a6ac8fa30e7e670d7b5f0ebd182c70a9c4bb1e9a42228769aec933c4df6cf49455caf37e2b2d51a91bd9709381990657f1499fe39fdd4ae3fcd7aa565971af6d6aad749a3a956c77b813faa0e900d92d9fa1f3fa8b5f15ee08e2eb267dfdccead2e37c78359ebc3f2782fd7adf76b55d15f9a05ffe6a451cada2d2d3bd511a4c22eed8f7afda87e14a1a9acdbd145b5a30bf9cfab04c1c7c2c0efe8c17cddd183cc3a8db5082713a46df567a5bc979661d33a6dedc77cbfc22e2b79ac7ada8f2234d392a6fe8f771aac8f4d6b237fdda67a321247c8eb6fe0ddc9b04cf5de340a6999fa4b0b128206c8d40b6999eb94a6a33e6a137032f59366c493b93eb51f18b5364142e00019eb99254d364258c63a69d27e14a1c12c693af68334595211d9abd3609fcfac8db5a1bf28e7ecf02253c2d1e1327153cd6fa0ba93a9ac7b97617a03bb7a82f6696bdcee3310c2699a8470ed12eb8c8bcfbdabce40e87c707d39d6199e61763eb8f36d748c1ba25d8c206147e6e81091c2880f2424d1a3a6c7024f9cb0716207098d8e710e27488e8e190c11019a2434da65c911481cb1e488254470e078ee7c0822540099c1b80b0c10346c58d248127a7494b48e6346c23c5c1822757460a0a3a3a3d3b3059123dc12132411e2044e901c1d33182202343ab2f7b264490c2bb2cd2d3962099ba063b6ec023647f0f0919283c4114b90e081c49223965442420e46bb486949296518e6fc7cae83dae4a0f3014a08278e73e216f05c5c5c8e0022022e3041d81842070d8f98cda16104a3458877a5f3c1c5650444045c6082b031840e9a2378506fe4321a1500a6002e2ece89127068d0a0e192848fcdd5c1a500405821185bcbed17d72e3468dc1e1df3002468d888808e23785cc04147c3056123081a3468e03431b204c6f9d024891e493449a289912aa86b914d60b044a7c60449d8e008c9194244523c7a70041217704ada258826a102c80cc65d6080a06123892649b8264690e0dc932a9a501104064eb8cb29467c2021891e352c0e08abc5c9d0e82e0580a141bd274eb827f03d09dd8e11684bc942f8091fe12155b01026c254740c774cca8ea470ba70c286831431c9b8bc17296510a102c80cc65d6080a09e908e812c8485589925a57c021d624a1a4e480a05b7ff806c94f50b10ce874c525918b2cd251922a3e931840e247824e1a3c6898ec189d4cbb208bca723024986f8c2494649ed45c76cad33672f692b9470097276783a26a5674a8a48c76c8d86db306829589e8a422e3fa376e11275f98d923674e5dd251141655924758c308018b5b8a4583183a9d754740cfc4482f75ed7f8a2c638a842edd24dc58deaef5b5371fb55f0bd5128cb9c14a14b344e757a7950bf71ee529eb236efd2929c8dfc9c1aa549a739ca2f0c198d37e3c7849179ff415ddeba735156cfaafecbe3cd20d1ea49bc19d4df8da0feec8f2234f4c7bc0c7527f35c2a1a6ec85ed541dd91dc6bf892ea6928be5223b9ff2842fd4791cbd2c0cb3f8de42ca95a9a79ca9264a8a59187ff012dc9599876a94ee3bd543450909128895a521173becbff809f3742fe78977732ee1bccad7040552ba04b34ce74171798974da3248ec7f5d803ac803ac955b63a3d4dc59686f2782fd3f4e99b8c1ac9693c4b48ce395ad170713ef0e53fbd5a1aa59ad3a45569241a2bdd6b1af249f9b46b0ee6bdb8be8f48f7b403ea5a2475ef25c24e40f5fabe9199b4f7a0b5819f6ed37fef4e66d2defb464c87f687fd518406fe31312f01beb42942f38efd591def259e44ff7e23d31a895ad28e4fd6a608b53438ef40a6ff80819644ffb6246a97a0816f6b9361b608cfb16f30773298b5f14a24b65006da2deb411112117ce589a0a7f6fe2842331dfb0f1225cddb1f9325514ba2a7817fa7214df87723a011d3adf328226d7ddb14a199fede7b7f16c8f5f7c9fa782ff1f159d709d86c2ee504b5364568e0a7c769b2389305721d67b2ae13406dc5b9b41f9ca3d5bc4b3191f7d283e9f01b13b9f196469287271531fd9d06be651e65614bb42536125bbae10181c9a50ea96fa3215afa41300b9cc0dc94db7f40cfedeb8890ca3a66735cb0fa0a935582309c0f6c750c94e747eaf65183318dac113cc3ce90295cc6b9ef3c8383641be3f4753b2be8b94c04e3dc1c5913f0427bb3c1937054175a25b0fbeeac7061eee6eac0329cc63bc81801ee5c95f87d7f164614a86bd9e6ce659aebd62d6b73d9eb73cb92682c2c24df0ba3805e2d89a666eea11639641b8a268362491fa15812dfe5bd305f1956c80247c6c9a0b09341b13cde0bd71c2ce47084203c34bfe6f7a8192e643dd7f160a1e4b6eb89499cc814381e2caeb81d95741771c3e3cdb82c4907cbf038036c90c5216e0146a4b8d4b7c7331a659973517e53b9f148eee79d44a7432920918e91031c32834b90f39ec0205008cc813a10064e2e1f52d1747ad38a8ed926126615d3c83cd231ee0a9783f05e4ff929bdfbe89a76e90f1bb276894a98748ce3f981131e01912540080137e998142b905c7e74129ff40c96999f4870f9746a660ef291ed1277a00661e3e08a48dae53909020e845ce67adf899e719d3922e917c8cf851f934424cf359920b87c16b48d3bedc242c0e12029b8fc243a865f76dfeb2cee74f3b819ae0b206043174a188116eab0859b11b281172d404114a2888318642a23ef0a2f5e4f90bb452547a8c1154c1e9de4dc2db2c1b92d64816385448209764c80726915e01a6f8b5a4f0f5b0a0ce1aaa20544643e1a8c16c850b600d043186224085ed809c21c82c003eae6794fda9073df0369a42756b044e6a3c13022431d8e2eb28d6f122c833fc385ac06d7f108c18bfb36d784a763b659c5e56f712722e918d886cb7f4e8c3c27710a153ef2bc19d40cd6f085205ec4410651c8f0e39237a3850c59446148142760a2850c3feebc198e0e54c8821856e0040c4194f066c0e8e00d5180600d2130c21264986b74161d0832abe01ad8cda20341268df7c2c7341bef859f0025d946e332cd55638b1fec700dea0ef15ef896a6e3bdf0630821c3725e128ec087021490208c3d71a7677c70629229744c193ac6f12081c96527972dba8383bbc5259779769ee0bbc52697a1cc169f5c3eece74448c76c8fe7f2e53f36740cc4c2e5bf27381de378928005eb89bbc11b89c88dafa73e2d5bfa3651feaa9d7cca6e9c626b9aa50c6fce793e4b938e79a74ed2a1ba3795c76f2422f7fd437d9aef039d14c59bd6a66253e64bcf7e6e4d4ef990786aad5563beda92a26092ce9d1fc63e3f9abb20edc3d2e40a8bd956cf1a5e264511f9fdfa659db265d5c9a428f88a6d0a72a793a2e01a73c70fb21e3dfa88b5b194e15a8f54edd147ee7c9c8e692c65b8f1a4284851b03421454122428a8242e1101056aadee91c77e8aea4b55676936cc59596a1ad6a9d115d1e760c74d513391d036f30ad37a0754f13dda154f6715541595dc2d27520b7822955c57ff043ee5693f2b84a79299d7351aceceafdeb1555536dd4a55612558755455d56974d41d12b4a9e82b75be75cea0f7e83f0afbaf8d056cd96745d9efab1ea6c37e6b7908e3101d7e06f94bc08ab332b675be28b7eadc8d0fb89cb0acacfc7729da95e8276abfe57f1a57b76abc16cadbdd3d3bdb4782fcddde6b7c67c896c34b7096e75aace88387b8af679a551d645222a03313d08c42c6d89be3adfca27b8c6f62888fd3a7557aa36caf5ae6364f5b08e79f415e8acd14b9025cd2c6eb23a75a65eaf6f6cc4c8a51eafae4efd89ebf52da49fe01af546cdd1e07467a4f4774adb4fb00c0a464406ea5a54989bf0910b2fbdac2abe9ace6c23ad33286ce448556f4c1a8cd645daf549b31efbff9c3afab13ac668bda64b28998cb1ad68a3b39a83adbe65bda6ef242d1863fcf466ed633168b2999c2ead982e1909a595e881dcc96df0f229be42866c893a15c59e547288ecd67d0f7b463659499d7eab8144d06849f47d0be675b2826b4c8f72b250b4adcea87cb2a5e928a72afda74cb7de5525afcffef4abeae9d6ab6c32456a9a268a627d622b66501e6f69178ae66e756c247b33dc271302d798986d3cb41b67d8fb42a0dc85b76437ecae4a609e314ba26cf4df0c09e5a75b35f0d64faf7e691384793360bf588796dd6a200b419ebe1202d77037aa2377ba9416e79c9fd34a78a96859082c63722146f9a256b9a4773049847596e4dc39fb65daeeeed1a8dfb3b55a3945763eec98ea6e95445cc7d47aa3424a51b4ec2ccf6eb06a5b766bbf73ed77dea41515e540eed3b677eb1d9544ea29db2ceaeb284ff4877291ddfa699ba4e2f67befcf9ef97d7bb6e7ebf97abe9eafe7ebf97a3eb6a5eb287ff5d517abb4a294bdc3f99e24c29752708d779655d499650f9d1fabdd241537560772200762a93d7bf6ecd9b367cf07aaa00aaaa06a6badb5d65acfda9332cb46a3dfc50506667ea38162e51496243abff7defc7a2945a5e2a2d4ec57cdc1f39fec7efe4ddecf9d9bd144decbfc67a3b1c16c2edbb7d1dc78e04ad53a535fa2ecc6b76a0eebd637915b2231ace56187267267b51b1330ec468364371816bbb9acd8ed23bb8d628a9d72c9251269ee5ed725caac9c424a715f76949066fda168f499e62e68fea36d6e674a22138651d5c422bf1e935370bf6eab2d5b9aa75e2faed7ac9a9459361ad54a83c6ad95b1d7ea9825c9538f6f7a4268d080817171f947a32c93535c548c4e8ea61d1e720a39050d1a30302e2eb5a7274a22720a3945c3e01e8448d1042b9e30e4c25cc7e30426b7095268d1b385906bdd7924176ec17313701dcf163a57c9934b875c98916ed55bdfb8db5e3507bd5ceb8c4accec1eabde6824b5de98d6514a53b913a1cc59ebac75d63a6b2d61ef7352f3d40ef559aa4befd8b18fecd6ac6d6fc8edef601babb3f48e393af1e43989dc2dbe6a259503b9ad6deff29cddf1b56e4f67525b5f95737d3cfdf63ea7ddde9049d5f4f6ec7cd37cd37cd39c1f4999651387cabbf2a7ddd892b0d7c7db6021c19000bfedd6f5735a6ac70f321e1ebfbd21b75e45c3eacc7cdb525fe557cd51611c447a28a579b03bd4b9439db6deea5718761b91ec96d9ad6662b114c974b1f8bae17dda741b53995139f5a8f55734eba348afa2123fe322948fdd465946553563662e55d9695b7ca958db7a97eaa9cfcf39a95b56b635b3e956cf2c491eb3f15ea68f469f8f98ddf1832cde3a151feb0cbf54edf6a9e6b02edfc6a73ab99a89ed2d77ad1bd690abc16aba325eb9815b71e056d5adecd4e09538e8a5e2c4c22b4ce0c9e9e9357dbb9b07a78b255d24b93f5cc7d3c590eefed5bfa65ffdabafe9b02fbbb11074737683315eee57bce2e57ec5cbfd2ac11b637cf14f89677dbbeeeeae6b9aacca124bd16eb7e2634489f4c57f34903c8acd42769398adb1d55140da47cbaaad99ae65b79b6aca9075b5a401149cdc015cc703052457520861698b7f0702e3298590c2d3f7eec6376ef05ed3218e7e2a98a7d43a45294a9f14a5eaeeb2e628659eb7a85b0f06779baf696a9578976e406ec9ca51fdf51b769e20f3b3a6211490f6d19cf5796d351b67766362c36c4d5fca9e7fd9ad4afb54c032a69594dd2ed6940bba08c285179762707b3a77eb37b92ed7f128d9b95c28b902b88e870b29b8187211701dcf163d77cbee8dcdd43d2f876b58f7eed34a4ad85c6d7b52dcbef0fcee6437fef6749cfbd3a1504017dd6ed67ba397d4411ae8d451de43367b222d7b2fd415d232395daa5db06aa7a9e916a799ede656b666baeffd9eb6a6b79a6e2617beff54c035285be2bfb6a1760132dd601d7140df1b06c151d301acc8b6ec0040c84af0d3dd32ebaa80655097d4df34e32e7c821cee96dd02f03c810db71fe24a59c732b69773dda3ed9e767127025e689f0a588683795358410d4a289c8e715640c393fb1e9f748cb3421aa670dfa31ca820f7ddc87df09ff73f6f12b4dea7b1deafd6c6e6c689239218c22569e296c0db64c70e2d4d48d4ddaf96047f9060ce7dd969bc97f7876e533f0a59ccdab88468d8d848d97073b1ee642e586f04f61afa8fecd88d08bdbeda1fa287ee64361a3baed79360484339a6819ef21b19e6232a4246d686a9d0394285109d144ac8c63a2a548ccef21b99958d8ff0b387b08bac8db5e126cfacc8da70669fd81cb3369c244b72df458cb1d61a29fe73bea591a2251541df37e2235fd968524f16aa60831b88e0e0c85807bd08cde7940a7a90b5696a9b8a77faad85501d2a52fe847c3e284d4029d626e5d62d6b9362fb63516c085806d44f5856469a8ae6b2bb2659f6ad9f88ee64449f6f4fc8e87d9b2234f4a2db14a15139bd8d1007c8a48caccde8d645d6b23623db49decbbbc8dab48a0d01cba4d8d0b73e12b2a4f81b9987ddc850427a0976d18bd0846eddb2ac77eb088d7591b5793af61da102458b208d1212e313ebdbd3c16e51f103b3249aab5eaf241dd627e05e12212d831dc8ebaff71d50784bdecbc3ec0f2038f438a01028e4bdbc93483adca5c9b0e300b3afc97b79db5b124f40243ea16719a8f35e2e4ba2a127c1439dfb4846b08c7596794f9adcf71d5d5892f56a49d0ea884f7064b6f7e4be7f7ab2bf6ff1c97b6cf21e79e212eb5b3c095ab8d32eef5b4c4286ac9a1a941a15ef12e8800c15ba813de201658c87a05f60c07d1a5f7ece8777d2344104f0bcf7de1748ee7baf73bea8c1b39c3ce18b9e277c31857b27c8d6cbc27d5615820878e167e085508aeb80123ce3a0cf467414012dd27f943f8d3012183821babbdf2e7cb9a38429308e1cd8855f808ee107e32d21fa9a461b01f7c2afa40c594ddf8a819899b9dab67e8853bb73eba151a69452142bdb0588ff871edaad0eb224e9c4689465d37fa8a7daaddf7a6817882beb4cb54eb9bc19fc99a6b6c154cbfec0327e204255f3871d88e0e0503c54928e5192829dad880bce416b74144fc7d41bb1dea0f8faf54aabef199454124a09e585035154124a89a4a620412814175ca37a0451f2168512b23c379e996da5b1f5eac578c553573c457971b7ab1ec88d5a5f7fa7945053b8db55292eb8c6fb55513cf7faab73654b719b97a22edd02504ea9c4576c49d6df2f1cf154124a09d788a7a2bb55a478ea4ce8d196e2ebb1d08bbffeaed0f55e29ea295a0c5defb2244e9431c618eba5e4d657bf344e398a865d4513d54a256997c804c6329b3d8a0b9efbe47b6fc6eb2cb3a4e9141797e3713cd1c9a59717c584bbcd7b7de32bdce998269d0fd753b41e8e47a44527379ee282e2824a427111299e49515cb08c48246b511b7a989e609f92f480ac4f488e3c79469c3c2a7afa7b319e6b2da624f5c69bcc3831be0389e51aa584a8396729739f939ab725ec19c5d8b31efe7a9892bcf7fe3e7bf836af7da3aed9ad7bdcfb46cd779ca6508a412199943c8ef1fe3625b1db94e446995dd6f94dfc267e1363fcbef862668e41c59019cb9bb478da36d992b2cf96f300e35347a1f7762624efcdc7e8e1317ab093162c63d67aabb5f4f0addff2ad7b7ab03513db1e6c70cff71e3e0f460b0f770f00761b596b354b9f5c6cba99e62ef6dee1c5b4f7b21876d2e24d486ec778bf66bd636c7f76dab13bd84dc2b096c56ea37bb9dc6907e64e34eee6766880a8f7370cb3a0490bab6ddcae9e9275ea73bad7655993169405d1807139efbc97e9342697d1a40545d98d6dcd64612ff1a4262db8063669b151af1365a79d498b29c9a485c61a171444cd6ff4959a2ccf154886a46479e96551da67524a6929ab94529f93a2d5c9fe8252b5bedaad3ef4cdb228a592294d912a525eda8da99cddd34d3a86c2769154cb4e2933b39c6f26d3c69354a248495fdf4cb886a413c5962ef9792a4321a6fde0fc361fa2f53af66dda1ab8311118b524ecf39494f23c69ad4db23a133ad3d07c7fb1891e925654475324b2dbb421f9529df2b3deb074aeebbab08c2545d1acb796f2a7a91c6a239975cfe7cc6c49937ee363dfeab14f89fff9c6f673f9e92f8cb0bd5646d8a9ab6899dd305bbbf617f5567f41ab595555554d49a1d44027461dab9b50568c91c66859b1b9bfa0dde44e305229b32c46aba799603507bdea0c76cb8a4d6abdd15664ec4e2525442dcb7a33b1d840b592c8659645df4cba0cd512d1c76e2afaa89bc0b6a3b6f5a24964fb8bcfaddb00a1849a49a45474eb9856eb4cc4a2f5518a1545b4cec49744550c59140bb2b3dea8eac7dd5a2bdfc67e3969fd4cabceda3429b4fa0b6a599665f9d162aac176c17aba1b5df291edaf8b4796b566ac97d86e4c590c19d64c5f700d2b9edafea27bfa8bd84d668c524a19272862511c7430aa753e51cb4ed948254a396537b6822bc62a235c3545551a46516c847ab3752097aadd14d5133a375b14e814c86e7debc64d2e9fa26c5b6d4bf556f78d4d555515b3a1240f04d2aaeae1325454521b37a1fad1aaa75489295b15ac5e51caaa2c5b92f57ea4288a39d4a4ce60675bc27ac70f42160b8518ab6d2d4ca75ab5564b52d82b148d422de520ed3a95c12de3ca7156b2aaf853594159f6c2c65658f4291a86452b6ea4982936d284a2280a4527064c02739e8e9026cdd230074201751e8f6db4b9d02b04aaeff5835254ad843918730ee11af3b51f0c5ba2eae76d74638f71ae31746e73d7c0077b4629a2674bd48b500a960a73863c0883382b0b0bd48150708df708752ecab4b0a7b2a0a0b03c96518a08424151302b774f45fb051a326b65a92c3c26d73348d7ec2d0f7693cdc39b316e4d87993160f75c2a2b300945756370c865eb4ccfa2b94bd258600e0c4cca84b2c1b840087b20141242d803a1807933eca7f37833ac9d96f4f0edf6db286b81e9c172ce5ba40480b516420161c5a63b0805166d4fce1d8d600e848289ecd03b5c41a1a470a22e3a39264040ad4e29a584afe9524729e784d296b6ce6afa07ae310f25bd655525dea88d67ae6c4dc3700df9093720e4441d8c9c58d61b72d2e829cd6e6ca63b98eba256aab06982a17137d06563b6145f619fdeafd9f863b706e24a90ad89978fd292aacfc3699ace97879140dcedf3796ad5197aa6f33f708d8fa5b4aa33d34b1f4b3f6b0eeb4eff816b4c7663c2318931c6db1507bdcdda74aaced0cb438d9f6973d2e06d3cfa03d7a82da7ca7285b75a52fcfcfd816b4c8767a94eedc6fcc30f2ce30719298aa26e9cec0f2c035a778331160527319cecbc23d727e3d1a87ba5df9187457571c5525bb95311a19cd2ebeaabf40ee472c5724a99fbf2ef0a242cb604ff64436681dcbf2eb696b9aaa87ef594dc8d5a3990dbf0fabb826b3092bb552be76f6fe73ab5c9b773a957af5ebd58bd58bd5831a9a2a4ac38567eada864a32b816749cf06b6030fd7abbf2b2a29b79a7e3bf7fa8a8cb112e3e26187a78cfeb088f1ad7bee755d364675f1c382871dacadd5097c10c2b772c5cae529ad0f43ab2769d959b4cf59b3beb2f28ea888de20e669023d2ca8eb967aafbeabaaaaaecb57e7aaaaaa7a5517f5b0c046232ba9ebf18a577c5848fbb078471e166fe761c132a8c852a4e74b72e5d341911ae8b47b5648a34f16db4c2677f73c153c9d8ee9aba9536a695937cfe6d93c5fce55c2aaee979372be4a95d5d5b1b64276ebc99f734e7b55c73eafabbb3779ad9441ab5bfeba6467d993d7e5e9b7ea7df9fac6b2f7b7cac6bfb7edeccaba2bb6f27aab5c5ecfac9e175ffed276fc20dbe46b77375ffd54d04f052f4955558c65fcb4d1a1c6f2495b79d4480fc9db78590642d1aceb2010261f3c8fa6b3dde4e97651946e26d605b2a4eaa940622c593d495bd146d727b35b33b9129b977cadb5ea58b4aa347729a5945653661da262c87b432866a2521d41cf3d943213940eb5a8b1f77b0ff479762fbc67d90b2ca70e3ba6df11ec8547f5ebaab1dc8d4ee97563433155aaae85a220ff7abfb8c596725c6cbdfe6a61269747547f6beeeeeeb6ce3736fcd7f1b193bbb11cc8650d5edd47f4296ef22e1616007c6326672697dfb35b0f6beb71bd7eefbdc979f1de7b2c2cef0590be5117c6b778fbdb747988f1760bf8fbec16a0dd4aa0f25f6b6c492d7f0fdd4dbdeb626672a9b3d4c7d2540f5fe11700ea75777777d73af3acbf67372602d003a53dc46a69d1dcb52cab85c5b217585e01a0d15b0d744dfbfc5af6185aca79d0b0efa089481aca5b8bd559588e689738b29b5461e785dd54de7c4bf6025fd7d6c3ba4a7dea97c597d59700e65be5aca9645b0feb5eaf960a45e74343e7035beaa5cb5a9fb8c6b317b8066537266ed80b2c239efe087af6023dac3728934aca399bbde05a26dba32c7c2689e74a12912ba9cc3a326d2c65606a4e4b8ae21343b94b9da509290a12918ea1dea426fd7cdae6f9c7f38f54454f6e42bd6dcaabb6549b1445fdd5211291cb7f6f7bf33d8a8a14a98abbc53fadd4f3d09a93a50949876bcc3f92144ccdf83edfae53940daaa5a8a40cf8a4450a191a19000000002315000030100a8744a3c1609ee881a8950714801098a8506a4e97a64990a31032c410600c0102220020202033d236003a0507627c72fb8209aa54e14c50321e288d3670415d57ee83289e124756f6d824333c68547f743d0ae31a9b54a1f152568659486e6824cdeb4e4f72829715d95a9f992012ae4f0330b5233025df043a82d05f3e624186c055fe2a57b19ad7464cf986627b18f0f4e74c8c14ef147a3358d8f10e88ac32643c44ce34805e33915e0e1aebe16c543cefada326d417a73b4757c08ac83fa83b1c7a5c865b1addf62bd772d466aac5cc6edcc5d2c97860ab64e1048afa3cc2d4a4d5850f858480373d383eb155b69fa3e75e3cc7576c2a18d940cc46a7c35d4db455acb1961a72d244d3b406d90eeb981ad2f24940a74926fc467f2eea9af9698ee18fb91dc168d97b64a694babc45b5b0700c98c35a1c03d122be0bb2e5a750303ed53115b8ba2c3ac7f2682089b6bd892be8343e3955f15a5b9d354ac481b9e315825c39f7f2aefd312edb361f9b8f065950b11f7d27fb4c28c162a6191de19076fea308875d33b686bfa7954ca760f7298a463326ee653d534013a30570cd0bf755a0fd03b18a8f4dee64bbb5351039cf4a658b8d33fd34a1293e4749f61c4f2cb9aa5b00810220e2d8eb8199c20ec0bae4d7ba31235ff98d8f5853cdb8b95d56b7568daf75b2af008996f9be033340dc57c7b7c1eef32c0f7cb99007b0ce5ff7f2cb56a0c1f202f834bad34df4d93783633e3a4cd47697068a7228480f625a9ea9e730ba9018323d65837bb251984cb74d06460e12724052b6b5fd3f67682ca678116c851dd75965bbf6593873fb9dd913eb47af3f049d0d56cb044097acc88fbf1438fa74cac330911b113c3fa0235c97c027840c65f03d946fe774afe050f0a38ea912b1e17c9b83381fbea016e9feebdc740129da2e5b9dfdd39974e719bfd0314739ffb350a2de83c1859854a7030c75191f4352b9fc1e6478e0ae9ae27ff44eef585561f57bfcd971846ec713bbfc19e828b7ec04d3ba8bb97c1ddea3080bbf6766d14d304cb3bd4ca331b47e8a7e8ff2c561888b917423592748271b19e171de8337ff93580fbf35ccc7f0b0ae0f6bcc21142a80539ea79d799af5df478e7349e69d33e3f52c35e3a39f6335091dfa798349028d92801e7672a2222598b44eabc086428ae69a10a30f95cbcb8d249d67ce4bc5544a411021c59d38d65b1c01bd6830894ecf817320921c56980fdbbf2cfe00f459cdf186c1a228e8ee7d54e562d9356b580083325c371c14379813f35982b9f12f526ef85d7ab60e476088584b047aaf08aac7efa6287175f719770f84a6021c50bf1be83a43a1ee43c44dcdc3ea2fc55b7ef0caad7214c43529520b6c98709202ef0ec3e7746e2f739910b014254c0422fcf2c3398bf16e8664b1cd9ee2f0d6aad47cb891b527ede27178397cb306f8ba479ea14cbded034cde4378a4213a4511565574f2df312ea4fbe48e4a81edf199d078118a219960312f0c741c7a8738a40abcedfb22f4f873960b9e12b0a96388b2767fb96f29bf050dd148c906a2f4586136bcdba10f9e0b99812641f0c7fbc1a2e2fb26c96cb12a752c2270c00cb9e51478f28394549edd5d39b4dfc38e3c8e1df6af3c4adfd5e064f1841771bec6b056fb0bfe02c4d62729fb01f3170c55adcf467ca4e69016cfb1e06880fc057fb2bd7f241ec207e1a1cbbcbd6d3b1cccfc85d7baf8cea47f7db3f888a9654f933ce76018ec693d2689e025afb509b3a3a014801d8c4055eadfcd5ff077f41bc1c327660610bea9118722b10e208b1d9980b95dbe462da4d1d5f704f58272eb9f89efb695e6332a15f5ab6788c7e797c944c71c4ee2d973b125c14ef494bc26df200164af0e2b84e22562a4480d99820a81c72d00bc45e7684276252cab5678b0a268763f9bd66c04e32c08ca4563eb1c25c815f27c6a225c3483d3d80d5a16490ed1df77353612f371db4e5d46347a6a30bdb361940776c8c9ac4b556280dd0eac49901b37821273130a637c88f6bd21cd5ba34c1fe33583cec5ae70cee23bc72b3c70fc6818b55ffd87f3b7c4a270437c924f9fe2bfe55a9960a1d39b002a51ceb3d3ff86ded3ce3b07b9c51f7c0579b0887166316da09f391cb01192b70342ab513ea9fd0f4b6a0f8102ce63febbd93b0bfb31e392e114c554b90a1456a6c4b049b83d588859f7b19705e14b6b7e58097902509c21f5be01ac7c04c7644e0e2e1bc950979a505ed8f526e8416b4e026ee3e7531238d355834f687a11a61a9e72151f476fbb7a6d6c9ee36d4ec680c48e6d35b5039b23a23f7a222c0d338006e721d59361bb4321f3d2bdcdcf1fb3907a022f466f8bd09f712aedb227c3a4234c03582936353675a2641ddeb6fd2f85ede359990c5556aed0e5bf701a6c2ce724419b6c350c7e807f69554dd817237cba1a4ec6da15dc7b79545fbfb12e43037d5049f8854941f6d1e3ed05afb525289351c254f3167c608bdb0a6c0f47ab92b6bda0b19954fd8e8442540dc5e49e9761181a3b7c4d6a2e3eb392b0606e37bf3f75d7d992312f81432dfa0da8f5a349f999d98b30086b8bc2b43e3c04d270b90cbdead52402d0455858bd6499ebd7e0cab91e8637d81b8239822631eee4813d3292edff0ea8725aa392bd70d8d7082d32779d31b9559fe9ea3fe058d3ca7154c6b367ddbd607bf57e3d10d672e295f26e2bc4da3815586e1e2f2337142a2afcccadee46866e06798f75089f057a5911bcdaef9e877288244ccc749f6465a96355d66c870cd71153644f235a06c17999cac29fd05e34aea0c265cf4e2b14d88224bc3b0436afa5fc4931aa7eb43d04b540c0c8ac658b0e0c02c1e3e779454381127aeedc10a5e8b17942b06ec60c508da14582c50611bad7092fbfafa862cdc7ee4eef6ffd80afbd3f6f4ffe6a54e287c711bf69014c3f11542aba16925349ae8b2ccb016f3550a887324356b3d41135afc99bb04a359f10a277c05ddbdbd79d15eaa5f9b10d06836f93137c4e68c619becdc04eb8ca1ccdb6e70a59cb9760ccf89d315edecd404b03aef5c6d491372092e26598785925c3a7aa77362ff3e695cd8d94c14662b00bf0324b7dfd81970df55b421b951733732ee296db3027c4a5ef4ebea151263f69100cf8c1d05164b06d33b35ac2187740135682c100687254f12fe412462ab701d7e9a3f3006cc180070d246170b9d58ce1f0d40efc7bd8bff963a49d4cf89c6ee853c08be3e22f78ef7ed22c15597b61aa5dace8fcfe9fc6193eb34f82f7fab0ff1a849b1ca18fd835f65a1dea21ad0ddc56d2e2273678d1d7158f2e0d0dfa15991d07c0c54244f9040f9c4ec96c4a24e93e7993bfa8bf4e00c70563b5c95dd2e289a93f5af72789307d819d2dff9f054e801f137d298921d55dc3b71fefc2f6959651373428289c4d97141f8599a4cb5092c842ea4056a1823b220930e3ce009c5a4b4e4fb3ecf16efd5f0acca748c0e955eef0920ad937eda4d766b5301facbbf5445111b73809cb5a71eea77c99acf607a6fa82546359d1a6f0f699c21dfa4c6e9ec0e77672e9c844df5e4c9b1a43fdcb0d8342aa5c21c6194218388d321a12fbc34326239d2bc6f33f6aff3b15f61a9ecbaa330dfe63d81417617367749ba25276943341c85b446f59871efd5e4084e265c6fc6f0a9db85f57f85a24ecaca665b3ccdcd5309bd14e10b535de0e2e9bdf6ca3431b4588cb662272b072e8f9ff91a3198d8d0d365350975b3860fabe91c68634a9ac6e6b62fa108095e746829d4b6e3dcf7ddc0cc185d9205d48b719fd55de647d98a9c7e46917de8ee9e7ec232c72ca968ebe6fd8feabb1055c9c37eb19aeb08391b99b6ba18496db20b1318067c3d15753016a116f654fc5443e166f93a91f708ef3338a368c0f6992fee4e74461a48159fcde8e3157a6c4c7b17b7ca22b21a581ccfe9325ac2450f65eb23503c220f3ee66064d6094e466e1112cbd33cf80b8db5fb7a1b1b889b4855afd42e04c0ea05ed19ca9097fb7149e1385f69c4f68bd26cc9b234bac46466f049f1348b608b9235d04b332d9881bd955809913280c1d3952f2d3e56f18a7e61717d8fbc741b814a8fae0dcadf6916f72ef22f471ce11d75e876707ce22b43dd51e6a49e7f3d864d0c8afeab52f2be3aa3debf3352a330e1a76e3975907650e41a481194b765c33d3583215ad94c897fb74924063164bf26e155a90c065df58519f2c9b18067060538c0646bfd141f85338d555e5aa2e1b9d259935b7c1ce2becbd83e91c407c76ddf8b97c511688f756e57377f411cc2cfa3ea6e2a4b1f8b3f3ad6b3d1ae3c0c994a645266052c7aca4c479b669b08724a6bd0f6c37c7c51c2f5281870132608adf0f0cce4b1bab67a6f8d189358dcd34a0e4cbb04431d3e947ff4f34e41e898823281e6cbc4838a66c98097db2e1db152f5e2ed981c01610c94ed844c1341c56fb075453fcf76ac7365e2db54e20e857e50dd97ebcc0d8436188180454bfb52483819cdaf27c453d419d540427502e8daa6adf28ffc206383628c6ce474b741aadff2c0b7d6eb42d3f0e4435f02ac91f32c1e0a21d5be29f78e62a97cf4c90f4c78a9bcace6d579f452698dc191b00d30a0587a4857147cb04df1c69b28dc268003aa445ed87f4a98e36324f56cd09f472ab26f0f546834b1085b992130498f87b53be2c43db9d8e574365eadc2286fac12e02c63efe9d4090dccda92d6aa0bcd866e01ae2affdcfc2dc894ee2e056e7b5121642e5a9dd605d3e4e60b6918c4cfc09415a930e17c119256bbe9e82c409b0f17d60512288b3f0d11989ee57d7d8e0e6806da336d0b3d501049444d55b64fc9015e2171dd974d0c4f4f6c591ae61a9891ce93a6b847c2d0b693f70591abb582154bd51e6bfa28dba280ee74edcc472b521c32e7ec8abef43075dc9d47c5246f76bf553c0686e3cd63690fa185e76a6149b8a1bf99622b9e419536fbe8dd26162408496c34f7ff09ac1a47494313b4cace830fa4439f60ab968c325a97b2587fea9e491bf6b8a95dc23011817c2c643f84db7a8cc7dda28b1ae63a19590587f97dbb576e4e3c3c37ec1d3c85076f08760bad6baf19160050662bf346fd4cad04ca6ca98f8ce8f72d5f91ef62b14d26cf61373b3c191b96a6ff2024a4544752982e857588a3b7273b25d1e1c52767e2145808a50dc0245788be43e8f6893c5f0fe6348cfc20f636cf894f630b652d8bb1098167a8f33390924cbc722b4719393470bd1462b756effeebaa3ef89fd0529a6b4a6202dee900d87c40d3711294d3017b4d413760227a0c87eafaefe87836079562281ce381a4775625ad1242ad8b53d77bc8ed62d144f8a367d3083a507da6d2bcc9faadfaf68682de9f6e3b514be69f965ad89cf0ca1ac160b1bbd28e9376091e12a5c88afaf1506cfbb83f83644b2f9580c5d5091e425fd8c69bc1c8e362b8cb2c6428e84ad571080ecee34d50a2dccbe36d8ea8da6e9be635ec079fa8941b95743975a5b4c892b535d5cd1970a972372e2a0d17525c87466ea42010af14b9a51bb3c7f8bda87e08ce2ad0bd5c56bae024eda1f364679195c1b8e4dc2de83abfdd20cc96756ac50d221f80d3d704288e9ac705c9e9666cac3a8c226a1bf6c1ab63858ddc49149b34dedb4522b346bf6c4ec6592498d50ed6b25ee190568df070406da6d3787b8a58b6465b864f0cba294f9ca14921181e441bfeb590d8af1b292050e2b9d38bea2390c65f04241b555ae82cef584114477e05d2852153282e8c0b167707b570e2bbf29432eaf1144d11a587897f483897f05c4a10e327a81606013f26e56562e75f6593c4220236e6831a5a96a7923896625557c3f0f69f5532da237674f798bb5dad106e2730d5c60f97a4755d4b0aae9aa55732daf2c424f8a5cd1d9e0e6ab7e22a39039fb9b5bf283f7304cb357306f4b0ea67d3a5bc240504da24d0dc88e60100e5bd45e828c096aa2d60d903dbcfcccf556c551ba9840a7b3a445d2635ab46de8e1196170322d5a90a87ab19928dec45488a71a5ad454ea6ecea9a6364d4dbe54c1c7e30ecc9a7a57e9a9d38305c84faf2ef5c13384f6a846135622cb47f14c3e0cf851f5514d61e286c5d92a458ee3fa730a79fdc7bf013b9023365d6e648e13e201568eeb1dca837e6a5acd52bfc1c49ee51c9da6ead2b96b78581a63e405f3ee1f751e2a6752e05c3b1b7740a23f6dd3b8a2b4746aa0bf3c9a5aa185e447d9fd91e21c89b826fa2c8b90ff350ae201ef608d65d561e29d9afd99d4b485be4b2d2a8424c8accaafb478406c39746e2d9da25a4ebd4f66dd8f01b76adddaf4dba5f76194a9beafda7026e78cde93f0638f3cafeb03c8ac3643bda288448df6429a9abcb31e6368b2b7a1cadbd44d1adf178ff6461d09f26a3a9f3089dc024b2ea5fbd22f861ca63161755c028a39b83a3d03243c544ac2e974b1229b49ee191d8fa46d72686c39f3b90db4c83f54edbb0da90f36b6fb85dcd270b8e6646eb41616651449c103104efe878f64463b7ce0b4f0e793475cff891ea52ecfa083ed7b2c85429c067c6321c0292c1834fcc5542cd8ddf29f642ce0520b3ba6d2e25c2e89f5fd169822cde5cbb28a56057f9cd23560498800ad095b0be0526159aec3e15d908f362096977ecb02969ee91bed732f8e9acee9cbc8ab326570f370e39269c62ea1c58d747692dfb047b31a85c9460d22bd1a1f5ce5cc72da2695fb5d0f6a2355d54670b1333faf442a15e8cd438f5de2f434ab7d93f339a5ae0db7c391846364d4eaf50013927c5ee56af7ee806aa6d13e7179ab9983fd6df8901c046ff2fe1e9a96b5a1689b452f073e452144b64be63b186090ad03248a0558cd0b8120a16e3cf33fedbd39b30a14883ec5b654971998fdf08fa8aa7d1a5d3e7302cc78eb5d8dad5a4b48e00a93c2f7330f99dc9200d03013db01118776589217a8a4cd04665530a17474e27db7b06a1f345f516caa849cdbdbbf226988f7b0f5ae624a4316b72dfa371c420388bc32e715f8bfa13f3f9b301c3b60812a1f809c340aa8617734fbde9f259f4042c3cf902e446698f84163be0d4facb9257a056c992755a04f46844a7a665f10e96af45aae19f4965afb714c9fb7bddbdf721177f9f3fc39fe659326e5c59ff78eac38f48d5fd116c1e8e046e279306b1e54f193c7cb62cb1a7916751d600610a428eee175213bda04553a229d0a02676346d3941643df68cebcb4d18c63f9d4a1346e1ec1760bb3545104815f845daf3be45d5a28f7a357ca5cc4e900a848af782bffe61c66328c43529a31ba955d512351dbd76aa4c19fcb46720a070b3bd662140555f5a4e2804d53a1065076c32021cb27d6a8f18b64a9ad1f1885bc6f157de387c348e225f7177023ed16d39b5078399bcb0b192e57d0607942cf1606d2c92bcb0962767f937b897788c0c7dc03a639f0904b8e129c3bd0d4e38fc977a70fc4112540bdb6003f873c30aabfb33e94bd503de417c2f9d24f15d4321bdce684e449b7882e3d3a877293475cfc74a8dec6687b2846d550d019bacaa5f1f394d8b4f77b30d55ff0c315d5dbd54ec469808288363faa5ae5878695a94a1a4874fa3088270b874c6428836634b2a08f3a5f871c2afb37c4fb824aa754b67383462c32c4433aa313f7d2c10b413a70b2a53f206ca8a8cd5e00c92948e2c10f0951fa3c9d082dabafc3a1b25d310193c1cea15a625e8a90670a55fdb2d9f0a925052f054a4c4a2b1cec3c75ab9a9fe4f1b8dd04ac4c79ea528cc6f45f65a0dc74a7bb0eaf2c2400dd616e2fceac67789b68c3874f997fbe32c7bd051cec631b97723f39833130843c05488244f7d7f1aa4c393c457adf762d7cbdc000311ff32f3c25a4cb915429cef994b93ac240af78e6700e4f5990bc7f99eacc3bc08008433f83f07a1c4dfde86677546af9219ae5c104081e0d4ebd48087d8d83bee9e50eec92b07695ce67bd1c2c485c27078cb9a68bc83664dcfb7392e7d413a4c0772819584e6606a1c03fddfd56eca74ee4d6b59b13d339155c49dd7ac31fee77ca52d6ff2caaa691cc65b5925266f06dc8ca3806cfce721de009ae4ed0c411c4993f9b30882068dc144e41504243e337e5080b24e1e1d0c0637d28bb7f9b2dfac49a7b89a071fbc4b99da9f1660a3dbb8432c7a88c1aa3be4952d7538bb7a909898da46b710a7d8392244dad3c62df8d312a76ada9292e8eea5413d6d7d49057ed3094998cb47586fc854e58ca4359010c686aec809d211d782c25f71f19dccfe61f234e4e2122719150ab1bdb11dd4169ccec45dc30dfe3641dc05ed1a5e17718cb795c292d5b6edd52bab1ef9496eb82c4ddec5d481d40ed9a04d778016f554afb44fba7348ef6030ce6f80c74d4909d03b215f2d2c6c589fd2fcda5f9c46bf46c2224a467d004f9e34d58d8ca49a20b1337bc0408e5ca0652b323192eee3e60711bb5032e4752533cdc2caf7f1099620cd110c58981f668f5e020f40816452563e402ff9c32bd6976d29338ad28d225e2dbe94beca28d50e675037c03a8e1c14c3d5bd29a465b65d1c174d11f4afb274c449fab329bf0330585d1163dd49a8b2153550215ab20819b1aa0d845e8a61e0a6255c9dfcff02a2f497fece7b3bdc316d4638cf00f14a09bf7d471347f8addeda38988436c8a91eb4cb0b797ca04b8324070740db30910b01b6290231111666e82ba2f1ba6ccd745b4cc86bbded7819a6e31a9057719698ce9854613b606763ce3d6ba666a5705dce715ab094b454c7bd1c94249397715c8ced25fad4ead674514fbb4a6afa13518d0eb42c93c929e3c214b4ba140d93dc8e26bb73a5d9243683c6fb267caf5d46d15726fbabf24dda85522478a93921656ad42d8cb8b243f1d8af583f7ec3d29afc98a3e205227baf74aa35ab6be3fef0809a0d99f578cc173125c3ec80806722185431d62e406bf79f2fdf68c4c2afca5f4f5e486e8a0c80111a0946e5a90788353753325283ae1aa08dd5fc3b7cc30f872989640038000764f2bb9acf904965a1a258ec5dca7bacd82919ae11ec5f56d4b9a054a71eff3e90753d59e0c137b6c487186a6014e39ebfd51f30ce3c4b46bcf2845ad1b633c9aa4020af6a4701e5d213d114fb92796fd2f78c9f06cba43664a4353e9594a256e40817046cbba4c9acf6efef74f078a3aa23fa793e205a8d2b4a3ae66fcdfa2d283953369d99369ff1e450e794c67b7d611e5722f19cb236cf8256e5d6c488f2c530c01945ea0969e28f66fc4ee51de8bee3d4e012c3d16038b24d0f80ddedbb1c1c8a367df12c8756a0c96780c19aa5c810e2646c331a3571fb2afdd4c1728175151bcf15253e710afb1c2d6b2137291d22150fafd0bda4ec75d47b4c229aa0315581ba39cfeead39f90cba9f3aae12976bffc54fb928733bf776ec125a427615452b084faf441afcc5bd8100af87e84c0847ba77c15e39fb82c90242dae0e6cd7a069c8887ef46c5f3a1cab85a6819605488a6dc083cfc2886136d4b5b4acde08db3ac28130c5a05fb1699ff0104ae29b1205bd6e139cb1d70ea05e6326ff1194254d6d12530b3546d91b067ca82200a4dd7e45d995f3e4c1d49fed3cd7973244621776a1552d2b3a6bd2eabcb1fe8a55c87515be1b5222b356b95a98148659315f54d2e6282a5c6c13b8dbde855001e2fa78b8d950a9bbaf14edb42dfbc941ae4e02b8cfc390cc51ac214a68d0b3f608799fe13c365cb3510d59bcae41016ea7c9da5ae3704aa1702cf5efb666057d9f6aaaa6c9af27b09357df3109ec37a8ad2a5c034c5d7b2880aa0b2b15f4202d26b97e07c749a79ce002e3ff980e7048548252515dca33cfded4c4aaca8abdac44f8ddd1b05340247620d8fea9c464196d234d2c5544ed11794a1269ce37e2a7240305aa64d51886543c8f487944fba6b7a5d0a7777c9e4df6dbfa2bf66fe2bbe634322dd015346f42badfabecbcf15218284d1e9d5ba17afb0d7d68fe94224dac4fdf7d318386e7ac8701c3d1376d05f59159e29505654be35687720ba5da6001e1c9d1ea91c209a3bb06d1d40e4a98aa53c622299ed47e85db5db2506443785be762a38fcb0df581c42b2c8c1fdd919c7ce900605d0744ad17fe31b91619404fcc4180f458f760d86b1a0ebcbe0a3d778b741afde361b7a36ff66a998e0e8da00e89acf9c091da113eb742eec3e21aee0ec498b7448bb41c127ee1a09aeea2f7b865efbca1c4401d48894e81975365acd09e200e22da22409c515229aabf63c857b638f6bc61f35f612a8b5dbd884f60c70e52697e5ef94346a712911591c78f5329c5a145c140f9e8408e80751589c23376685196cb47776219307fc9a9b3fd784e7b8977825bf89e24b57ac2792aaa36c006393636629e1690e50e8c10b5cdab41dc60548ea7bc4bda97a2d1055ea186ce0281a89d24d63df42eeeebe66aa803e7a8821b11cc2482f3505207a4b8474051a719c215f7c446ea3780d92c6c57338ddb4090d7613f05a3bed1276ec926ef71c5526e850c8b95681d75194811ccde2513a24e13d170285aab4ddc467ea91632c87415bed096f155a2603d6ddab2b13a866ab7883ea1430f2ac191230582f24ee52930eb0bf1df61c7463f4a2db1c4c776611c673a4a0634413336097bd0c9a6259b623559e910115b935768baae22183c7a92271be6c0815e95d144843a19d938db7499e9c81cae02ffe7a17a024fc80750277af2c9355ad07f5e773ae89ddb88b2740e96597dbe67c9bed34a34642f7c26437274422c51bb12cdd48b2468e84e26af2726f29a02bf466482d6b21cc9d98c3591d68ddb8dc4cea0c874dd7050dc149702ec824d99232341981a3d8fd1216b8d85071b4dce5bc181db066578e44b62ab5973d1a70da4056e3c6d3341b2c6715afbc9d49561ff116977983ab3e8749379a4508a970f614b413edf52bb2af9656ae8f8d8fa125f7e4b1e2ee561db486489880d02b94456db9a01603006ce8213b7804234f330debcb0e67e701218386fcd74bb19718d868f56e0b7353765cfca67013c0a7978cba2202b3fc9bc984e34b7e6e6ad7b6b32f5dc68321e58dc98fdbf241483418a8ac5e2ddb579d5bd39cfe8fc7c1397523a38954edb4a64e539a947c561337d7ca826cb4f7277d330e3c426bc82e41dec3c2f92376efc7a525eb7f8d7356d57f2e64bf053aea949843ab3e67fd8b76d807679381dac9483c5ec67aaac8b19e88327085d4c74f1e260c81c44c484b236e358671b25339f665d016170e6544ab840176696f24379c7dc28901adcf2d56a8e957e062e04bf1912aa6fef72ed186e69b24c188eb29ff0f4ea7a1fa003959c62551f1c97b4938f12329baad60e94f2deec95261a97fcd96da74601ab74cb1b02f30fd51e4043c2196ea21b336ed875f4f70bc0ed0ce827fba57b724896ee672d7fbeb9c8dd122a37d1dd801ce6a9c9441525f49f9722cc93fc632ea83d0f8c74c67f2ce8a56a11c20feb8cf92883024b78d4d43475cead2672ea134f0e82dc911e51205138280b824f80dcf3df9eaf9e2438cf7ef999afabfe078ba3270ac3b4f044f084942751d72eaa5f6f6283e8535a7328eb68502fa07a085b42d193cc192002160903ed8047b83b1af3e45518c559427aac4838ab8643370ce32fa0c5935c92edb16c187f2e2cab35bffcf4e6afe7e00df5aace2b458022e4e7ed82bf7b4b297fecf81fb29bcb5216cfd8a438204161e8462d4f55b4a711aaa510e817af658f4c0306ff0ac9a339523ecb242114c339db6fcbb948b4d2224bae63d8fba7147bd71ff4f1c969fd754f7426093687d829676eb3b71c8e3d45a24ce1bf50ccdd6966ffae90812cbc76be2789e362344517a7f71b7b6637eece53c8373aa0a6288d6a3ac0b2eff5c995a18fe44145f4c428c3fb152509165db430f33854107a8ef9de6f44365459cf7f109c0a554b92b81a2b62c381b851cc2996648e2af70690e53eca4b2de0a58c17ac2ece633cc64da8018fbf3c706ee46b6ca5d7100347ced5d4efab79e42705b9af104e2622463565ec56b3b6660cd29011201e56c862d0eed154d4c947900ce5ecc8001182a6499869bde8c0c298f5b3e04991ee32086498528336a9776f637a90a8e142f2ed71a1ff0be83a6669adfd10d549fae6e9bf1f897b1aae88cc11c959d526c9e6589b195a084348d3bd4051fe2b5e449974e9f68b40d40325fa7e7c2102fbb1996cd174697d1745952d2e59c847b62fc93d761e932c6e842cdafd446c5778f70537699c358e41f2d303c4ba1cc4599073f095091f78bb5c903fd910f448906db7d22d0bd7380bf3b300edbfd9bdc9d89187bcd965a5ec2e47bc96c4b1b12a6c015ba0577e2230c4aaa1b1672f449eb17bea91ea465136c850ca5c58503b1c61d41d52d0bc5151b7f261559fad8dd82f8928bbebe1d58ee26347efd42568cf2330d4c94a9adaa4d211c19a312b95d3918860ef99e3402e39a8680a979aefa4d651726ec4b0115833e3121491d5b5ec2bdfda4e829a26525810e70a51eb390de9acd63430361cbd6ded2da21c03ca3a1d98c9f9591bdf78c7a2934f9aa3589acc92fd4258ff8904c67900b89242004f37b4b19c4e756413dc0d61fbc71b6e46834beb743c88b6d03ca3c06bdcb5c69967f8abfcaafaddbd60f325e1a73b588c9e8f5627978ce90ca63ce3bdda9e719021490c13e2e75c317b93569084fbf090eb28e1df64f40546385fbfdc51988bb68b258492f4928e738bf5bdcb1e9de83c1b38234a68174465215aa850e9f8be2fb758fe039daa9d8c5dc9eb365765852a50ab692bc3ccb6417229cb7be9f4177cca8e86e568667950fb63abf8c1cec4b5829d6b61cb820a85feae59b9007459ae8d9fdab20c25a00ca62f385db75c1b14fb613df2c3c47c19816829b5cc32d8531d00eb9be9d135d2e9583f3fd3315b34183d910d07c46d4d29d13a5cd38476816ade1e8f1be58fa88cab11d089bb26c3299efd2113954b7d253fdb84733ca5dd8b3c843e3ff32d47b4f459b45058abb3ef4ad146e0249b08c36ef0e195741c21ca315225c8c425867b1911d28e0ee9e3e22c1c2125ef461e42b459f6edf3ff3276e5517d181d5396595c66ce84843782b5b4e8e1d085df23b4d08f510bcfeecf94fb64153ff92bab24ad11da90a951417ef0ad4b9c75ad6569c3e7869467ca6725b0084c49fcf4653abd428aa610570886650a5c26cfc4f2686b2b048df6e50faf1522353c48fcd6ac561e05079424ce0f1411cbbc6b335c9747bd2f3b9de6a691b51cc896efa1804214f1204dc504a0a6646a1bddd5a80b1bcbb0f043e941ed984f5a6cfa9cc4763b8845c4504604f1359969a5c92b505d7143ee4ddca8e5839682c804aa7638ccdd3224e9a4623a9a08d579da484ff4c03503f9f3c21e28ba6442c784bda70b07b50e197f96db8255a80f28e52f34a5478eb29f1d590a935b5e21ef60534d7671227a0298456910633e4f325acec3f11005b37d810c81df445a6affe23567915cb53c527d66ec146745e53e553fa3cf4285d82517ab2e79602a134e1cd74ca34d90121baa3322438fbdc3a996e2be0469dd770413d0ff2e503594812d3ed341b615be2ced13e8205b0dd77c80e1ae84ed66f21e20e07120f28fe7d9918966977acda8fb8fafbd99a4540fd06209673ac9fac02c85936d0c655823efedcf86d89f7c7e4e76a531c8b3199750f3445f3bf73a252e4c25165c93628188ce57f846f6dea91586a5eb79db3eda7cc0afc59a536f56a5f18147e287a706077bf8344984dbb20555739a044d4ffd55b330181f66ab3e9ed7341798cf0eb60eda843d9dbf14343301479c780e2608979c0a8c230c85ced874ca5497f7646b24f50eca6b4594bbf5e81b77e9c7c4e6e739ffc6085addcd83ae9138effbdfe908cbfbe2cb75000bc06c2233fd9adc41e7ef1d627f270ff91b965c9f109d550146cdd22f090f6b9b772fdf3cca50c9bd7bb6d642e5c5c9812f1d0975c4c0eeb6b5b0ff01c173600efddcae2403745e1b8966f21b707768e4f5c524c765e4d8303f09e34f3619bebb4895170f4d9ea070c33a205b73d1068eeafca61628d328a5d5a4d3facedfbe189187b0a72860147e9685588e78d9e171f12bb3c13f2362126fe65562aa165282454b526bc985610a70c6d5ef57de9d8d5254b97bd6006c97222e6b547d0e64959e85821d609d581c43abce225b99d6492a3da4ace69fa34fa607ab4aeb2a654520d599c85792962ec8746a9c59046c79f7a4e0f8935b6e337985d8dc88991e201cf802996f56eccc6075f8745b480853b3bcc589718e7b7c4822b725a90de67ebecc81b5e3c4286d67a73b00a6938bfce2a0ab2dd0abbee880da360ff17591567ea2c4a4e80013c8898a16075e8577ec1060e47bc1021d66432e0d6fb151a26f243c046fabba90025cb32f1992ee113c6dd58ecf643eed9b185e154e7b2741f59a13e12c5b0e7512de893afca3f52cecde89addc77ed2711699d492e48ce0673050a73c89de5092e39169a0e2ec36639d29ffc2c441e1c595405783aabab805a2ec41bba67a76083327fb3610547dbbb72488d782f5787117cb39d8f4183a20cdc87921de32f892bc7a6ed0d48b067d04ed143d488d7b42bf7b81274d3c3611d74c918670cfc2e81a9bcf1a27fb52f18f53535c5add99725313a5a642d4bdb1cf02e8201fac1a8f0029a6a6fd847d08bb2799a64e0e112e3118138b5556b31455799ca60491e65d7613abcf40e0dfe93d24ae06850deec5f4a140bba10bd4c416e8e612dbc1ee302c044569dff215352e835fee67d00b467bf8bd17090681e29d1bb0a9d91220b74883b6ec3465aaab1aea4233e4c2ea6b9db1e899edec971144aed09229ad43ef168418a382428827f5a6b6032f0ca500763e41afcd84b7042cdfdef879fe712806d3b3e3b79e04ac92286faa7d1964b3bff5fa642b73595dafac9976c80b114a6614e898f1c15ca3761e03e77b7717c41e1ac342e462868dfa03d3036ba94dedc7224ad9f8b27a1f747c9d4ffe30da621b2b4c69701985fdd4c84a9190d087e03397a22bb7b7352581b0939d50a97d7a0a37d3cb0a90494cefcfb5b7ce3843a4ef4a0d0dc571934c9c4591d6aadf69cf8c08a7c3a38491e5a693d825a47515819697d573fb3b7ea5e3902e2151e6b2249e0727721a7dec36cc10dcb27579a0bde8ef03a43b51864b9eb8d15251e291930d60441387b5d7f405024fa96ee86e469f41c46e98b68d6f4898821184e0c51d1391df70a320cc245b5db46202b683fe6307196a749ec87a161b2a8897500203cb0a1df1bd0fdd36364f80c23328e61e87ce5e98e6356e97b312644af3c56ebe71b1f6b7c402c69ea8fdd99e6a2105d0158b81cae4b162f9f7578a01f540575cb4327236cb85b59a07ad1db2882b04e61ad5d0a084d579f08670c0473b2a922e1bcef5c8b115af9b12ee206f46c8284c005ec9dbb2c8d407532ca71c676bc169a6cfcc7984974d910ca7d1bf54bee301e6df630fd8fa811d7be077d9f40777d6ce6c210e0ad5c140537a93c8e28ab92c80f036db2c1abe07f677cd6d034a915afbd6026015614f0a59f945037a4494dcec7ce2978f38ec72c46dbdec161f36a4966eb440409bfc6f9be3b8e8b3d79f73445bd2258e5acb0a3ab8586798c05abc134ab0cd8ac5cdf403a16928561d3c346879c63056406a3dfd413697b7d2fdbd262ecf18127fa952eb88d5dac5b127dc8d7ea557cedafa105cdec3b49ef283aa5646431458ecdbbdde765257db6292c74e9b7678cb1f2f5880d6e841296c325fe6d79cd4ee4dde314cf8511417eb18383727c34ca50794481330a81891bdc12855b52bcb9c35a3cf0e5cba1b9912688250af479412432498ec5f9a44855e594fb664aad2c0efbd9115d8f3b5dc205c786f0f1c030782ebcd9b952b4c3b71fc543d12e5926563b9bb757f08211452e2571e69c8e83a41e1366250f60c7964f0b2d758da23679e9ad09fc65d92996a42e79a77eeaa96283e247f2ba1dd9af244a8f85be5ced7649ee867eb33542ad1bee9ae85b239430ef2d8f0aaebde95e483c9aede5d62923f832d945f698858cee3e7e826d609e55a0dbf9c79b7ec678c2785110d0e9de9093f346e2c30055c86aa5e5150ecb3a702663efa0ffae731247d4521fd99d89dce6eda7315e7b92e07fa3455b1bcf97f1ca592396dc465265c5c8b168e43be26aeb1e79b959973a141961a9ee2698c7b170d1f25e37a429aa86fc1526df8d5282c3090d2468990f9f6a9309e2281e52e265686c1e340670802181ebc7db66165c50dac4be5dc5850130a69fd27b71ca9e2e5f69669af05fa5ff7001e00ffb4284b99d578b4ee7d8077896015ade09d3d400ca3d1302ad2e80e674933f572e6f30e4661be5aa4cd3b4ba150a95c4d552356d5c483db709d78c66f7c4f94e4c326c74f7a01419e11386c209525d8e0109559d029ff9aa3e9bb956648a3ff0901d7f2836d0149f89a0b1ae5fe746439bd47ad96b25e0c08a703592c8d16e1375c0cfee00152aa88fa84619fa2509837ba15f9ab0cfa28f80e35e3b116cbe54a455e25682ae88029a47397c31f760b91736410d08716db3675fc626053cbe341182ae2ed2cfd398b792d69be0556422d2be398c7929497a3224227dc53f43cb191ffdfd30cab6abdccca97fe701b3b91584641895051f9ce23702380b06856e69e298f4d2bc397198d68c7846f45170eab6c283f314383b8554c4530caa197d853bde7371a6c66e4f8799e8a12919a5a3cc7b4a3736f1670804162e8b695b7df26bbd34fd778b123334c89b8c7612bad1d37e83e1fe4af90105dcd3aaf6d34992619267efec218b771e7cbf99460e85e71c3c0c1201fcb35782840bff09c38d83b6c170f690fe311061b92d29146b16705108bcb24c36f133b1adb2e20da882fd165b318bdeb86bfe89b1b5410d53d9fc99c8e248d37c1d347f8cce89b19ded9cccb6d78209b39176b6b7aa00907dd9f30bd95be35d4da305890c1e0b200694aa9a30e80fd5fda48976f5f2c141afc0a78e63d6ecf4b00b276139264b660ebb4dba7abcfe3645a85ab0c33cf0675a90d993f22fc39d50e7e4f236ae9e14aae22358ea338a54c5e90569479343cc3e22544946c3df3bf39f75d3c2bc99f1282fb1599844f8dc751c2e65d24e02cc0981d81b2a76ea25effb4ec1cb32034c8c12b7fc7745bb3305fb070cf3a5b8a501ecadcc2ddf665cd296dd4b2085431230e60b70dcd984575a284e80eb222fc48d5b8e4d853c170bf8d842d4bead900b1d403105168ebc4f4b94e8a2c23a92adafbf925fcd2b7360b1e8f59501cd53a40cf918dba17f29850648bbfd296016b2818700a9996e1a2cacfdd3a182efe13d2d33d48a1a072f9be48d179115480523ab8b2949ea946105c81937138974b52a39ea2a4eb9d6e25994edc197fdf9d08c4f2b47fccfa097eff4e4e03e455092fde13474bb3523e5b743c4d6b55c6813d54fdc2d76c8fa3a49f4f01defdb83bc5059d8a316cb1160455d69abc9ef72c1dddc6701eaf231bf208d3adda41c51d9e43b4c00a497b5f657a889c9b6bf7ec9793f1720adc8e4d81ac192d9aefd337c38698cdb6a78ff306e1ddbde571ceac4ca587d9e136c0f95ff1d5d027c68e3e2c156296746ce39690b7f39349c5d768e1d8d50a7d5a45d5760d3d2e423bd6765b82dd08bc9ae2792b1d429e755f0fe35e327615c2da6c5958df71e796575fa5aa68b372ff28733e5e616da29d45daf88d4f423aad36aeacf26e9bd82235228fece44539e94eb1f02c07312bfdb01d523e090b5067955b3ec0c79a1330e0e5541d31c4a8cf633d0918798c51271f32e8fe5aeab0e2fee495551b6bd621b978b9dd12a10eeb1118e9199fb554ee26a80ebb7bcf965431bb049ef00785c73c9637dbef78bf46e8b1dd6196ee2a639d9842a48d26680f28c4cd45672862ddb45f501b06abb72464b100e2ca5cafdbf2ba104a8dfa62f7d2f012849d822e4e1cf33996c9ac8107db5857eaae326daec5f4d080526500ef04c2190e8f88f5b6a45fd7931b7d75f0498891f937491cf9785f7bcac7da5543e5db9420806e32d02300671264e62ccc4f244a54ddb8494e3480b0f238d872f547a635a623635b1d69d9243b074b43c5d7d71ecb2d791da24aed8834fac4267d3f2134c22446889f05687faf8a4a8f016a5c31ca4a5a64aad1cf3aa0d357b8d3d5eb248b7f954997c8ae05295a7c71ebdb375d2e081dccbfbd26453431d1b585de6d87e2a888195472e5cddd266b0e20ce13f7c2b1dd27783a744371c96ce122f437b242990b4b97c22017af3c54ec433f141a63c855d2b56d5af9170df4df5f895b44eba94207a7b56bd7ddad0430549da6163ef102be9a6748255be8e4d1502ceeaedb51f9fa8a28e9e619e4e64ca09e90b1947e2f65f965b3acb3508d06560720d15448d594af84f3ab3a6b699d6749f910e56dff33513e10ea966be448e3a63af99afc9c1749ea3a9d61b5d4a11b689cd50a6792fc8457259212a9bcf8a2afbdb57bfb32b50f53383b164d6f1f54f3c582983c60ddecf9bc2c193c18342bd95b62865692389618695f02876125d1df3f9534d460711d0a50f24ed8927e5f54432d2ab49cc303ba8ae5459913c8efca3dc000a6548a8e5568c3af76cd2c11d75954c7bee734919fec37102a9e6300521046281750c1e45fc16f178d24b81d1880d7ae787131bfabf693f551cf3e085f3085830ff0b5421755087797054391fba7e29802d4727de4e0a07198284fdc8984ca65045996985d338850816474dff5c45d4fb5ce5f58b2804b90b653dc777f6bca1ea984141db60b1df291ccff0e538cda46e18c74e211dbe2689c68678ae719202a361bf6b011d85dc2a625088975f6c441c5977eb483df11486408fea008042f7c42e1680ace55475657f372c91c25594f6b3fc3240bfb54366c991cbab4e217d12d60bfc6380a0f3b428767496953a0d8f6cc83543607853820a23affc0de1d8947208829febaadf6d2b5c80fb02d6b7cf34adc23ebc91079949cc0c45df44ca567819faced8fa04832c5a1e8a39ad451cf7e7b3ab9d91860b1d833231a939010929b5b76b16dc8511c7485fe598ac865c728017d6518e618a80590a6e723ff174342f63c83ed4fccd3d7ddd77241cea2a6a4b42e64782fc48056e8d6339b12bb1e4083d1624839f2a60e2a4afaaf42f311f7abd0f3834fd67e5a45fd4a0c5645fdd591a704903e3605b67a109a4ab85a0e50b88d878540ba0eac5d1921cf2c3732ec0e6c3ffb247f073bbecd362a71cf2f96bd6f16e58fc4fa7c0c964bcf5c9cf8819e1d9afd68eba3a846a421c428dd519ccceb72492cc14b3054dc88a8f8096144046204c86856fa417e2882cdba168d34c1afac766f24f7e4775f4d253449f2adac7cc2ebe34c1d3aa4cc8c44546dd2ccd18d31e89ec89d53e2b4b9b4c30f4fec88662c269f7992bdcb9864e36bc58129328df3b3709a6015bf7ea0177cea1c9eb85ffc90552733a8969d2e4d3cdbba9ab2d3ed2acead80652634c31dd4fadd4155481bb4f028447592c34f581153f8d2d4c977ee51363c2cd26331c41ffada0d614a38ec88903b57566966de8657e2f3280261ee480d7a48ebced22890a22c611c5435451a40ee5d7ce7b202ba16777b7e5fa028d636c18768708aff63c159ad7514860dcb2f28fa9a138210db38eaa845e9a977f45ac8b3307d87f00682a26ce3aae64bf2da17ee9e8be31d909d5edf71ff84f7177f50c2f97378af98c2b5d7c9aef4cdd4a91acc5f44be4f8c665060edd2dc5c9721f8666a8bc8e238d3c31c696a010a0fb4d66256c11773de598a4f21a74735b7d8169dcb4b306a92cf24f4202e6ce1965860410fe22c25f64c333a96c74203bc9d629264e520f8388d1b18ad995ac80ba8c7fcf207f4ef19ddb2de673f832454260e83358032d056e60b1c5bce782cf0fdc33b10cc0ed8b8dd01366f00f29f33d1faeb5d036b2dd67661a4e835dee9316f1a219f2f8da5f594b3ffa21310f4a89bc0acb1a9f0f294d7a78f27d21cf64c47ab97a23cfdf6dc42d487be7be28e5e3dd1d1d0fe7d218c52adc077e5b5ff444a5070f6fedc5d092aac16445ab202636e9e957f70bec62ee34279d8a4e790c0b28ea1c00351c5f52ee92b6ef5c46684e3ad3616f8fc6c6c55e87f4770e1cd7d19cae800e1ab6d81f00e0166d80ff6bb054bf4b1e72ce338ca1f1c0c3507af8adf220519a60624a425e84e2272576bc6402230989a4fd1ffecb9813adb66ecfd89614398c897af27b06d8e04258d4c00b6bb9a013c02b081d191cbc51224f5acfedc2f8b0866360297a3eee347ca5a8050e8ad5c76ad37d3364395a0655b711ae40af4f4d35222580561d3eea5d99d964d981f63c5a4a50e8f5d665463cfd4f4fe28d8c76fc024794cde100b002e063ae4a6d95c343b94e995383b66835b52dabef1713da8818ba5c65348e7e1676ddc1ec25ab17af2a8d80496d34cd6e092b5cf2953348a155497cafd020f19db0c242f95676890d4119d5f88cb7280faa11b70657d6f6cbbfc363e051cbe3ea8cbd8c525a7724a39f90f2de628afd713890330ccc1d1af35ecab313fd31ecf719187578763e22ecfd181584bbd81945bb8f4bdae2a1743f2699498518e283b04b3c8f098247b1da2b8cca24b1cf4f48db47416d0f920399f8b41779f1aee2b5bf3ce17f61294c2568c2d4c208775357772bfe59488a45d402184b5aa9ae1885cdbf848f98b716e02857e8f6b6eec6033b3e871dca9e986ccbe6ca4455b9e96d830834933c4b039f0ec40453d4f90e432b1f73874f14b2d076a3335a75ca63141fb7cec37f195a109a67a9b2c0d9880cb6ee60fa01194ae9458c070c3325e53df4e98cf779fb9437b4521900ca6706aace6fb275f2de707eab86d2c48e100ba9b693c32543b125a527a363d8b685d571b0fc20dead212e13b0fbdb2d2df421ddc9fce9aa36afc9adcca9c8e3ae0cc52024211778aba00858076eff835e6d33d71efb42206be25796b0b5681517d5f005d1ec9fdc116ccd3ed6c6764bb527d8025d4f5711c8f7371a213aba917d72483df981c2b8d911a391593c76ac793149d0021c7a00381edb40b3171c29d7ea8a517fd81955a6dc935058521d1ec66c9e3c49d2d10a7d5c34773c9bce12bf5391cef8f3be4ebff19d13eca2ddf8bd6471cc7d163dcc32002931efd42f6832a596f6e9ece33bfbb7a0e7c8fd8f406c05be9f08963e42c0a5d40437d13955d34644ee3352f6e16896b4d6a625e3ac095196d3175f05d82fb0e817859cc9cc1fa25ad9d04fc54ad33623943336245760e17f610b86383a8f0ba8df96f5e11de5b4b81b4cfcf45e63a95aacc4d6069dcc995195483036c1c2222643f72a2feb63cf457eedd61e7976b4bb2405e5f14988151ce3b5b47279868c4431a4ceccc133d33f23617149ec32d89a101ab30cf7c31f2a1c5417fe0321bebad7b2fb602803a909562d601f4128ed8dbc1380025a6b17c2b172899ed3edaa17b4a0ba60e2512f91ea1aaf37ec8dda58fe01c8c6470a087e182dbe2fa5097ff559b5fb36c2ac67df45da261aa12c2e19a821f3acef606f1155c3f50d6cfc8a9f8adeb94447cab1689c0dee83285e27f0112f1b52975fa3e04624c9244e68e31746dd3d69797bf455395ce51b9fe17d99deac81ef6acfc84e737a558cb90e9de8f9d3929936c5ed68784478c4d2cc8ecd0ec5d5187a912fe2321564258d269083658eed512bf4ab3d85933226039ffea35c4336a59226e849447ba5c80addc98faeb0b92b91ddd8dbe80e0fe6a6d98d38d0037f18c538b17833abacd6ba8c19995074a5e452a3bc761047044efa286e6bd563ce2cc0be33015a6c185fdc04a50da77b6c581d59590e2af7dcde576d05c1c3a68b6b4c58207c4c751aa6467e4954f8693a794ae6192dc7b50fc38e1a7c21443b8651b9b58d02b7eef927e5bff99d618ba29651851949d94cfd9dd50b7039b4cc27348b8d8cad4b3ff4d00f6ff8f52cdafabfe9112935ac37181532d06229bf4521e8f20865f07d1c3e65b0ec812d958d4f1fcdd638b2da8150923e144c735843c2fe23e94b58862f928e7630ebda05c728e4db21e5545db80837129b341f6b7fa7d7c2dda413c761b2a859f42d286c88adc4bffcaca298a08d209f0114999160325fc13a5a5bba61966b6604ec313e88e1f9c447d88ed89c3e9ba1c577d5912878038c65040ccc990f12d0ec64910550a0d3be2f5626fef4af706fb63e48586b53d55a10296d75e83cb3f178c5a4eb07318e90ce71ba5f32f9ba60626f42e50e8fdd86c52c25a055c1c97794a4d81a40622049b379c863c39c5469d6f335f681db04e2e62f265ab58ff0446d135adbe2085e08657eb58aa10ef9cafc9344af66c0fab292e87c3d6484a1fa8476c2038f840b45b6e7c0b74b44cc91938d0aaca2db55b849436ea8d166f67c0b3d10cf519ba7ff6e2704be1c723f4d34f48bf2353887bd44540d163763f22bfe54ae2c1075847f2af2b7a4ac84337df7cf2c283f49261f440c4912626cb8014faca5ed0a13df862414e2461dba1b9f031c43848226df287e8d163ef0497922a6516a67a0ce44537a134be9c6bf24a1fb927d632d826e24715918411d0274a846a80236e3e52f71b04a20f031fd6dc0c0eda0879874f9672162c2fb144ff5bdd83e601ca6e675654aa3cef95f413b967620c961253da15a0843b018824d65688fba40781e9d5193b207d00f88fb4a2652c9ee0ce1c4a78e890935cb4ce640881cf68680fa2d0f054cfa7d09eef2012a069bd90c62c430e40ed02d7187e6c724402f4c64aee31c2bb922342efc9e268279428142a75a7a4593897a104b54c609665456a3de2842c8b01beec0093b7d31ce3ba114d579b52c4fedf11cecf672aebb4c5bc40bfbedf71c987910e1ca8421c6232940bf637d4a1721b039b17680ce9d15662184813627cee22d2c3a6a6619cb85d81d00affbd157d7b716050f0d9a1138a09a6b8a22d20cae5f6e0ecd2677580e6ee6d07ba6c35bae6bc435e31b8f6871cd202936b6e17cffe78d2ff07586f7ad818d94315b9d1f2742932ed8f16434735e0b78004e86a1288e3d01d87534906b88811d1099e9e46390e6fae8b81bd0f210f17845c1ad1b386afbf51e9f74b6321bd940517fb8dec3f79c2c2746af19b287211c2be02cc5ba821304f54abaafd6f363a8c5d1b3322cc1beae8c7fe5d01f37da03c59c5aeb7ba0602a58e0cffce6fa88b4618f04408a814d792cd7da4820eb0db00d26b287860c487497043008bc1875b300e849cb4c7491737d8b1c0ae81622cd32886703c06526a285640a6531650a60e6e28dbd0edbf06d0c1b9af3d33204f06a8479f163b331af3813a3c47e7d755150b713dcbcf8369f03274e717b1391780d29ea10375e4849dc191c8c0cecd433a7dc1f28be8b6559f8ea44c68678f57d50c6ac7c612b4388f9fedd825081b13a7f998fa2499099db42415ca4335fa89cf1d0ae5ad9329ecfc90423cbfd9afa9aad46564a940a964c20ae236bb3dea3ee5d6ed52dfb17aa6d060adb48b71261c461fef0d75d2a68acbe8b98aca8f0dc1055af9b48e05e45e496bb4eed86f723d5ed7252cbed12ee57f351f07a394607e04a774e7f26134549d6abea419b9f356796f53091150b44b0226e36e0e90ac653568003a9536052c4b086c64da8fd8c1ced5a2662d10bca17bd11bd52037cfa4b74e6af7f8c0e9c797c816d3e39ff4067feb73b813bebbbac79670d4a0af5e84b5244d9eeb9ae6699e149846dde76dae55f52489e53082f2ce319fd7298abc394780e9374f5992276f0f4321c23e2f4b4406f609122a3c33e4f7cb87d5f999c6b09a652c16eeade71590b069dd430793e10abd681d7931a0aa379c3234ac5f248ef47971273995ca442e250618904fc98000fd73a9ddab31d3786634f5c304a34eb52ab07549b733ac9307e8f6928543c391e1b2cab4234ac32a53b260a5010b97e86f14d1bd5f2085661c4d569245b6ad643de69d3dd5b66aaf464987b7a5ca5e2866edc3365a50cf58e7b946b0c7fddae1b7600cf1b69305a3d6fd4bd3c226fce14ba2bbb0eab72b8137f399e004bdc3635a9cce64084234a6b1a2d995d957b0f18db43724603d5a46cc342c266143284ef363ce960aac7fa8631fd8ad59b47216c84ae5bd1608448c16ed3353a1c8f2524db52f207b8527f15c9288e08aeed43afa9d85ec0c071f0fd3cd177e480fb2db61785bdbecd08b70adf449086102f5cdf1f3449a11013ac2064e1c9ab8d89c6c36a172df675cd2e31e30a5b111709dd772c31b72582ca47ba66a8b45bcc32625faaa51668b20f7ba1b28349716e43c436ae225f6ec438c5bd6a54e1f76947ab4636179506032a0e81f98904925aff952339f1022ed33cb11b304422db02a59031204049d8624eb50259e1697191effbd40611d36ebc319f4e52e3c4d1b51b7290e458b6541bab564e0177d3febd67eabfd7b321a754daa652a893896db5d6ab9b26603413bf41b57fa2e801fbe2e6aa6134320a193a05024d37e5071b8c0edc805cf14600ce839e47874fb6d36a31801972de63d37f93cd1e4aa38313a252aecd5a3b6d7f816ef577e908a5b00890f469b08417cb9952a6b3aabbf741a87055a9603b967ac984b91c1c8048918b7adf4dad986ba55fe091170ae1d6105a0fa342f16d671ba2ee7c153ff21091e9f324c94c8b0373d3a80e460a4a2cf0cb4b34c46b28f1f88443d31d0c5223f947701dc98f64173a24ee04d8b898f109e6d6228c17e9f87f0a34854016c0cbf331b10e53436afa087e8c9e663a0d55a6ea59e75f49d4dfc5719bea5ce795874a5127b84cb65da2f6d40c516b2c10dda4c132de6704c7be88dd09284c0ee854525f58efb765e17322344369c24251904797347f14355fec558a88f1c330723d4b5a14cff97212ee1b36f6192d5171105c7cc51d4c3472540647a688e5b425817b78550846680aa254cd704732b500a5591489488a75933f0555fbb9888ba39f65682720a08d91b461ca211963ba22530786f3a0eb2616feb6a4623546171a9fafc0c88c86bb6f862d3cd85c43f9941c7a9c4fa84734ea9a22762de6a8471648444e4025d24b289681b3063e4f56dba011a0249c7d6c9be82704e6769b04bc0a4f9de181fe6e200522ab2940c9ee1e5d1828c4a6f11cfb08c80e597ffa1afbbebb9e6d1a7253b6c061a4db7689ed6b69b50f7ae71499c78ae4267e100cf7d93fce4d993e3c1ea7c1c57a9dee0ea4a3b2793097e9971655478641ab0c7a49184d97e79a5b39fcbb264fac42a5a17584000094475a02cb98511ca2b956816d0b008bd5d826d1eff83650272f2b519b5cd70f4bfe988e1223bc538105f2e37add7c584a4d938f81094b7774cc4761c131aa809f61a4ff1b038288a5459c10d2237d13486f15493b21425e3a1cf6cd074c27193d0897dfdc0314389685e47a6089c8c10b782ee4fa9d4d0be5791337bce4c4c93621eee3550a958a3856ea1f7a5a36e5185a99c87b1d6717da7f8f9158368f43a1067c1bb88e1a7f4faf124641a4dda0c0582f64fc11d4f3d3bed533677f82ac87841d376eec8287254f035d6086bd50797d4fc9fc8ed91e21c47c25a32249a3822d4cd9806ddd482124909ba94d60c087e084befb3dcad6d277c11886946f5d1823cdd55d0a0a832f59f902078a0857245666354e77a66e3800275b71f4484d56d16be224e6c7ea9cf288f0d9c3d5b2c07698bc8b897836a8a40ceaf07763aa7c18f3c000c1b970ac046ae676e1f20c40af5daf65a6a167a24208e38c5e172a2e1679136ae5eef032c449860a9ec9c1ae2500a0db78560fbe876bcfd8b970c49299d8fda0d7de22f7141701cac7f69cab9dd8b895e14ca86c3759adfe47c56cdb169d0e88020f4fb3c99c4b27f32404d1961b7aa764bdd02fac698c444fddcf6b255074c02c08bee563e65f0b8b43cbb61cebea5431731715e0fa9863e8bbc7fc8cb6be64f421e8e809320dd5a0a1bb890c3a8ea6e427239f6d61ae3f551e62856bcf5429b15cdd50ecc3eb68129b00acf5e5bb206ce922e4bc6f8426938fe18d3143a654e2bdc16dec276fb8785d29e11920a2f3094927f988cd23f74965409426c31b01d44ceee21e9e5365e12fc5299d6c751111eb27f46fc4fcda024e3ee03308f3362c59fa03a09142b4445311bfa03bd2a1961f198476554715038f154980826566d258848306d03f11d67a49dc74f8c1799199a7e72215829b6ba8d558da86b5708f0c876824d78709bfebfa2b92285e95394dae7aa76db18ee916a0b23b2a0f93037110f15b38458e54e0cfa59e61285de884538719413f365d036dfceb7c87536adf8a7981af839e30e1ae851f0429bf8587afa4c1458e12b105730b4d1f77558a452bb39369e6528cee7f1e03a399f9cb5ab83b67a5d6039cf4a6cb2d68a36c76744793d5e5dab671448a8978d6ccc46c409e500038b4592fe729bf0610d8f8c1a4eead139e6d68061bfd6ce8379d65474a59a03fadc863410d9d87803b56b220886d3c2409d5bef9494e50feb9932b4faf4ba53294472f8cc009e05726f1e88270da9f454d4c89f8e066ced73eae66da5b0fc2ddb4a0302e2e5c58fc31dad3b6b7b401db53c2dd46997f68d30143e844f9e0355b258200ef3e248cbbb2d49e6810789ed96abd947415c2787be0896a9e97b66dabe8aaf3b003778f41b9c27f5f116fc9d30615d4763a74edad11499add7de1ad3971142eed780e83fc91878ce030b868f606ac2df72a365f9783084bed490cfc3a354ae21fe3965fa9cfd1d7571f13a572f3877ec8fd40f490306e243bd726d327fc47b0521999f7c5ab097442cd1ac2286dbdca14bc7bacf8ace263e422e422191006b4a4bc257a925aad8a34f338c71fc882433e2f3177199bec5a7d6d98cb55540e669817a8ff5ea0e1897639820fb936081a299040cb2f9f9de75dc8c8933b7e18de6847c4720194a1c531496b9de62021b882161de7d8d7972eb37d213a8d46904e07adcc885ecb3da464a8d22d63bc8bcd50d6b313ab44316b13a3ca2bf3d3ac3039a2ff4a1f7eaef92004e729c43f84a2f94d4e80b78d38815fca6972ae150245b71467144040af1473b50b6b9a10deef7103e333bd87d15d91d4510b9d3e025c159cb161e2d55fb6b14405a04193697502628949a2c9c1d9b10cab1e454fb4b0fa795d725bb896f18d56c0d042b6063b45fd69b87358a5f0dbe06519f3184ad62d92724283ba475a3a394070a46bdb18c6a61fac61329b0a7b33ab8d83e4795f9092c9110a93ab10a7cf872178dda4b1144aabae60b45110cae0d4671b549b0bb4ae42d2f383191ebbd5c21a70afcebd94ffa840488675a516190133cd729720fafc2a4e241175017341129a625e216b183d67ffc836672834499a45d7e75d015e4042aa4e85020c9d9923b56fba9f4ba47413b369e515bdd6beeabd7726a5f91b756f8762026cb6297a57c3e75d810ce869b2eab28424736afac1017ce0733f209d230b89e26232dde1757a5b205009a21f227f62b119a822557765e99afd510f95cfe1d4436a32934d40c21c18508dc4708258d6bdfb4915cb24196c9f4b8bfdde1e387024e76181c8af128358d713729103c66fd5c9542dd5d65f1f51680ddd0024b49dec24a135190bfbdb830a208f488e58ca6d7e604cf602e55924354c180c38b8899d562e8136de27e0ad0765257b416f40d394838fcf5426696e5f1967b407602e92ca9b34345def2d16ef8ccc010edc9200b5e68507b37b81b8ea40136777bb3a73a9d5d5c737668b90944103c5e608508826d2255ecde9f44e59cb6f44a75a36e32161bf2a996ec2324f37c4a0a09e591336f9cb2a27e84fb37fb26ce1b797d949f26e320ca0c67845e7480723a48217d8a6620ca59d6a9ea579834c4ecdf329f06a745418c4984056c7f13f1dbc05df359deecca41310f73f59a1f429aee7538c8a6edc7613e4245a6e514ac84fd7f911be4650aaa5cb24da978069dbb8fe7956465dc2b6c7a707840b2e1ac027cd9e28a80952ac376547f3816f274508b0908542395e28cc04404125b935382f403064178a58627e4b0ec05931dc3ce9794a87a77d1a3acfac94aa4e061d658b0092147f5847d44d349aaf77210a59038b3381bc54348b4120e450a12e4814824437a9891c5b5db9ef48bcc6445239ee0211330d47ba2d020523fbdf641a07d0b75d13531e4ee37792203a51ff6c7378e30dcccdbfc6749f4540119fa220d4744b134a947e4cd0df30dffbdad01ce1800f904735f6059800c07f9fb61c6cf73c90b12b9fd81d8a667fbc3a71d7dd334466e933f918f0bfe8136e2a32f995746bff54c99bf410acdf7cddb513f8fd8afb2d4c6724b07a7f285014cb6d7ce36b875c0602c3a1ccc3e4eb922ff898bc5b0d6b1cda026a0e784f4799a02205671138e1d8dffd6b16d58bd393e57265b6b8784ee4889b4eba5407329bb0bc8c626af366b3a32409600d209818b1cb26e50191d87478f449b7bb3c2756726644dde29002436d4b8bdb204d7691eec80696ede3c4b6a8991689da1d1baf2fafe7e01f0c31e158607104f6c73b46630cafcb946a52c89ed24ee0b2c8714296d1cf9f0e8226d59df0ba481f40c45aa9c7c943f60ce081e4c58aa5e5699d826a9a2d9478a8c542d4c174e067522b2d3a2fb4b05be1e478b77756b471078e58c7162bae3fd7c05b2ec5f5f99709df8857651249ab13646340c056760f89c316d1dfa1addc61149e848570d049e6572a91a197d29411f18312777f1d2972483cb00a9ded358c4b535ad9c3e0440bba8adb1b35c3baa186fa0c80fa6b7f331411f63f96c28e0065c4d71d53be84c53827352c1f87c51e6bce75341f8826edea1f8da25ffba762f26df72af8ebb475d58b68bb14a23b45425047d94eaac0fc92235096ca701e6680bc8d531a5092356033ad052f8158795578d7856b32718bfad978f76dbbc1bbc90f447ad75043d589964d00113fedacaec0d230073dbe22dccf0b08aed110480c90e0db97b5fcb1c78963935fb6981df7460f5c34f011e10e523ac4a2f9bc3bba29ab5e9497cafc9b0e1dbe44dee7c188550724bcc2454b97a7bd51172d1f114d8575f998fced564aa59191e9a085af283a68c2c32a93501e39270220a59dd881676914c7f349414de57da858514993ed8e840095ec7e6990a1f95798e3a36b75e5aefb36c5d8ed145bc86d43c98e7fd89134dbabf0ddb4488b0ea400b09cf13e55c93967df38162fc42a441e0c312918048c0bd01f1be597192a9dfee9c1b159f13592573b2b337720855ef084230f7a7c88f6ef8f87f851762caca2d1077a0fc55894a6c72a662448ac2aacf3349a9fccefebf646023a3fec94afa853ed8c0572daf681474f1916c0d8d181c46e3618489d7f1809d588d846ce4868c67e45bb124b6384f5937990e644c667aa27a4f4d5afe843344a6d9aa4710bc3a4ebb429289dd57932aa9f85d49c38eba399af88f4ad2dafb99260fa0c94f831f011e1debab5f7bf4b7c6f1ee2ebe879441eb5bbb90c0bf50506c33d7bc2c9ac60edd893f7e951b5dcf77e2a5b92972d4b4945b15ca7f02f15890973770df99b5f96450dba60882e5c34f422d2e3fb994f9dc075fd2c88b5704372698ed7cb6bb724670ec9bffe9b21da6986bb54cda8c7ed2e0f7d344b4b5d471b26230a5a29a0207a22ec69a4dd0e243eee89358521781152563a2e22273f28811d3e3b61bb3937b332b9f97b9e296b5bcfd63e848241e74f81afb85976d6c50558b6edc40b0cd67d9eb08889ec84ccd7e7d8365c17df00599d60cdc66bbd8636018d108a37dc9def7dc4302e3e7c73fd452e62f5cfb5756ccea53bbe359f065cb709734a69d8efd1e0913121f30d288667b85385adecbe3a34f787dbda16e4660f0a7b76d50fa49074656a51258bb2871cc7144762ecc56e2cc93a45559839100c4ac9d6043ef827335e0e4ff41f24690fb89e7b0e06d9bf6cf99dd8f6ea8adf0f45bf0e1e0f5f43c394b2641196af6eb00d371eb008a3f1f295558406418100a761a079f7515ec3764bf36fcdf2feba3aeb40d19d6ca4dcd46ebbd62774b9c97240839f1c9ce130720bdfb59c1c7bc4b26b16fdd04790282392c2aea8efc6907ce35dd1603c508743f14324f20f29275dff003f93d397a91b4885f7e482e77f8a6b2b8362d8c1d94a8a6432d57c4d92cf5d332c8692171c310faf92e0c6411d7ce25fe56593dcda13ad106815282edc2c9ce11fceee5bf8f9df3ba30deda3df5716b8c7745ef546a0c575883219225e87125a70c33bc34f1fcacf0d69eda973e32c0bad6e49d2834db59fc0515e8b3817e647badcd289c9a2b9368cf452384570ad1d25e5ed3904272a26dbe126de442a9725b067e5c1716ae859b410d6dfed032e6f92bfcdb5e0d6cb7f09f41dbe58159b84875bfdf7b21b2ee2d249c6e1da57a3b9acab6a01b64166273e3190731aea699a895378408c31719548e3f16fb6f32661a056182917fc6621edd9610132898e5afe8b9f48012b4e3ef8d2b52a93284f3ce256940530d1625ba754530acab450f6d487841ef763860f55ea606c7ac0f6ee41519610dd8bf50528b1f17ed36a5262a4903fa85677a6960263becb2d7a4a45be93b936b9a9c1ac343e610c8673e872c549af55cdc841d0fe158060445d0e910acc688455e21830b027e8ccc43976f75c82b7f16e26cf5d31aa2d8d2ada3cda739ae914dff17b058991cd0b9f6ea191dbdb43861c42218c6cd838f690da11baaebed2d5edd4a0ea1e49569e479a3d7137d85eee9adf77fa47c1305978b2d294b2a757b586bc7ef6d0ab5fbf8d6e3a23ec9a2c0c9deaea33873a6c4f31797b2307dcee555fe177791b4b6e914e40aa629f7b0a5b2aa04cf4abf2e524c340c509dc0cb737f40e7bdcd84ab09a8cd14cf99fea52f0ca5e334d3eb531700ea66d2aedff178a9bad5f47d0299fa0d30e1042df6a2a3e1f7b9d35cb50e1dd3aca06aed1db9066409117952cef21e63a6adc793b6e146660c1590a6b65838368fe1abbf13cc9308d1700af7acfea72c5081d209d034cd31d50c78903138626b75d33beca62d5c4439b4fb6fe900e2513d4eecb1e6b8d83ed61dc6087a1ea7a8d7e4113e6fdcde5acdd5d6a749c2f4f2c774c2a275fc473a767d1f70a21030d459a1455486dd5f4c7e27544faca7de608aa4f31dadbb34ccfbb769ec2b411c9621ccac5a83b97c9d3aed969526c98e9e2ff9f478c3f10e916a3e09e0b429b9fec9bf0ee6113de36b78d8f91611bec3fec0772460b321bf97c60581736de56cecdcaf6dc97b712b92ed46b7cf47caa287d8bd034063b602087c669af5116aa31b6d704417d343b3a331e1ff4b560cf486ca743b85419d0cd8abdb1ece1219c7179d2c610809061e4916bc7af32a1597fb0a59014265d85f4ffd27734326ada6f08928987d129956ba583ec9dd7c0eaa6cd5f67dc45b5e07d4298b4068161373b5ba336097e58f857010f791fdd51cb94e8b893b10dc029c068dff9419697895b8081ed14b04833e6c7b10b513808b05f9cbb15a59639b0d8fc6c84fa488575f9059a15d5d5eea59a90f960ab74dfca486c0d826ca57eee2899248f803c69accc55b596bfbcabfc9750a7bc75f85d4c9b02f9db7ad8dc70d5cc24e433a1c9bcdeb09fa2d6decfdb11a1e3c96d939095deed422bda53b7ee85b3255d2930aa352e2f79377935bbfc6ac548afb85ee0044aed49ad8e74e9f1e95da8a1a1c0ab8fc57f862f7708b290b84c2bdcac74438e28f09c981e029385c5c67e861d0b5dfa306935cdcc400e996460a981b1384e0fc183703fce283f281d772d86fe0197af77b88e7abc49c48d28c318842458508dd664871359b8ff59349711ce8e94b3fa759de68572481a120fb9de0aa99d777f556db0d541971eda86819a10a4c70847455e2c5a88771b5cf565550c718a187eeab97a02edd7d7452ba5ddd67ca7d8e91a62fdb008135e6c8a8fbafcceab149e7c3982fb57eba5ed0b2ce53d1640cd2c68c185f91037a07ae94a7a1672f24b14c17eb9c9843e0c436fb5b527892282b7d6d36234ab95d722f9a7b2ad6e3b70aecc2151f20522f048fbde3b991258669717036590814ae2f8fd14b319fa323295298e2d9221585b1e63d02a374ef1c803f017104df8031255d04b8ed54a71488fa8297874d4804549acd6df4ce24f926045b7b64981e0f233b0cbb9fc4c00be86c965c190997f7b637f09e466776a7c8b701c74c417d11b3d75d697946b058b1956b6b5c0ba1ec61165af81c614565c3767ae499bc3e8258a2fbcc6d56779d8bcbc45ffb7334a18006c71d35119f36a37cfd55041320bb8fcddcfa47d42d8802b845795529656f64bcad4c3b9c79844df80d3a13ada6f367a9eebbe103d76bbb4bff2e100498a2cf703335e6626bab79ee9069e7d53200a26a9ba056bf7af8dba7fbcee162720c308fa19036c9c80a93a7c40b778e460f3a76184b3da75050e0a55125545ee73ccee4d5fde4c8534811aaea58fdc0134bb51ab5a3255ae4aadf9d0abd5d6671972b0a7942a2f63ada9da76f71b75cd753caf6fe10149f6a21879bf1cb960964640d106a4d8139a688774186b2818eac825a59f59a5944ee34f88fb4854bf29d4b715b9f78e7f0d8ea162f17ed5941ad60fafe1bc4ebe173bda9e8a9f77f005b712239b0b88a7d302bcfe5ea2c2ef967ebed8f9fda56e9016c9719942323fc093a1f0235245832372809b9e68b6e16ebfdb8afa3d47563f3e3911ca04efe230b852763750623163083fac8ef05624c42ce8eff6c0cc96bce100b538f62227d162f5820d5d361f9707ef4699a37a991dd8c8576d644417c9baf5a11055eddb650422b86ce70dd1a5ee091e1df5bd5d7efa148b2b7cc1b288b353b1b50ce6c00ebf33c2f417f2bbe74fb26735541bc0a40ea2ab2c97dbff89d93510ac57408fbd215fc86afba56489032e083e870cbe35309de0a1350d245e7f3afb86bf3f6a0709405c43a00554f3967b47085ddb9a2c88ec340b7ac401c3ec443c704ca320767aa45e6d1dcbd58ebb5506da256ee92d76427bc126d22c4389ddc965212e597b16d43a4b104f8e8e66ac8df96f77ff5b863d31925ba7292c5dbd74631b34d11a73616ea95200703fad1c469494b5f52aceca46443dd2035620add6018565e64a6e0d1d557e09ac5854fafdb87bd2de263c6cf4d582f93dd54d7894b6bb0d32bc75380d9dd1fa8dd402d17772fc2c280b08915a1099eaeee299507700b05855e4c25f93aba7bdbd4a51fdf6c32c21cc8cbdc87925d4e2af015460d2e5bfbba61dea14d4ccc34cbea376ee9bfddf03bf60f00f6dab9180b10c3743cf9776dd81251a66d8cd34892d8288c7181bfeb84f259414593d4e2201a2a51e6059a5d3eae338692a0525d821b1dfb304e77111869988feac67ec8f2e7b2a6580f52dd5c9f73ac29f8c52c6386be5483c40586c20ac96d9bb63a58c333e8abc7b345ccee30681c37c2e82c8e82a12b899b8d701c3ff5539dadda325d9e4b777d8046c505a01cd747070c26b336b15c1a62ae5fc5682c5a0943d2ef3339719fca16dd2edb5a7bc48dca6f4ae004328a8a27093b9cedf7b5c0f62911cd943d0cbe9ff845964bff6e788d7679195953e9b71086746cf8d88aa7c25765144a356200ecf5b47bf24a4054fb0883aeb2611f7acc9890f64a8547a93584a83924877eb2539ca8c56956b08ba8fa4548dacc1970dd053afdc4a167d5969ff1e8cacccfce293cc921edfa0fcc4cfb380ffcd107f4aece84f99beb0f7736f561986ca0d4220c411d91b025af691e65c3d9e2469bc7c2c4809e1a6b1f4b836a5cc541a06ef8eeb751eb9ff11ab0597c43eaf7fc235dcbe6219ab67814cce44273f8f312abb561c0ebecdfd206db887417e6fc0934499d83861500e7d7538e8042363e33fdfeb79069e1c418440f4254f08c7becf661e899bea37492771edb741e37ab1c306dd69b603a2fa8b5549c336121506a9ef924ea16d208355dea09fe7372196c0cc53d8ed4d82dacd5957c82904254ad0377aad85fe92493f21a14ffa80b086b7e114f6dc2ec0d8dfaf44944fa98a3962afa9388a429f9c5ff5435d2d4910b4bad75f3bf474a511b3774f7c88e23f5a0a34d97ab1a5d96d27a9967119dede877b05316d3d266b8b64f409b1517063feb16adfd5e1c002f4bc15e1f1539c4184f194c8ab5c27731e79b6035a3dea4436bc2d4d1f4ef7afba1ec067dfce652324556281c167a1e1424924f054f238028ac27ad6628dfd5c640b74b73259f71ad2ae6cfeed2cccbf11528717c2eb8b038e18b85f5b71b463de12bbac8941fc09a58f24abfc5b32c080558d1eb8b21fbaebc1b991d2bfef1c91981bd5aca1de7ca47d6ea4fa2606cbb7ef308529a596a2754bcecb03fe9e606e582cceac60b96578f6bada7e04a050631d5121e922cb30690c02abbae81175741a8bb84048f394533031c2118d7c2784ec04b6a07844b345ffa530b29e072c9e1cde1cc0d618c213a1c78c5f26cdea267766f3d6d8bed3d0afbc280db033cc1f64214d8fdc255f24aadfcf66e92a7262ebf2462825da25adebcc292773ee7cf906aac175dcac37370f389afba8d92f0cb9a8f3e7879caadf9cc84a3527bb836805a262b7ae4c6920ff95144656f3bd1553dfdfddae4c02dbac1313010aa5602f2ba47f54cef5d1d63a60d0315e372241dabf273c5e329df516ec0b3edc4aa80e394148bc05e85b94a2b2e5d816685ff50ab2da36114c013ebda51fb047e9b1b93cb600a7f8323bb7c873ad2f273ce9c97611654430ccb12790eeb8a5e800b4abfd4cd0a94320c6e81c645b7c4fe6c1488b94288a8e04f2872317736a115217221ae4d162a12ea1e4bd945a24f2b7f7a1d9117d0af0ee1f90bc3a856b4165e335e473ec6f5f347f7b2a25841711118ae8728541f8db4b5588f2b777c11c9cf7ead2290e2a023efced03ece954c26b192ce9335595895b93de95fbdbf7bc93431ed17d86caf655e58a8085b3328cc71be48ce01738370cb9fb3b9a0d1eaaa7268834ce113d455ea719a1060a56a965f8259d5ed5b227d0eb4658d7ded16ab2733d1bf4d5e6595fbc9e73235291972b5b7a60e6876d0f246f5ae2b5d7dccb2375f1e46fb79b6203903f7a0e4314d7981c4ed0f7bda7da8b27d8e91edf43cb63e81c4e6fef6738eccdac8a70223301e457e90bee1cc82d7f67dc8fb3fba15682445f662c0c6cbd46806ebdd36db57001e2589e460ab03795b89c71afafb721eeb8ec7be298680a76117db1aa7f799fed661d3965448095ef50eda224ffc1dfb22c34876e6065e3d8c4fc9337b6dd2f3271ec1e897037a6c91dadd66e7244305c804023ab6639a1317c0055a519291c1aa3ff051417a186940ebbdfcc06cce85b6d274e0d1219ab6ec2330d6e922c7d38fe92968149e6e9c2859694adff3b23fce0a12876a5a838a0eff9c42e166673200e4bf02935463b580150f9760bfc3efb2393a601d48f2b12a48df7a235e8c2371eb01c68857201fb13c25283cdba443e7190816b481b4076317051cc737f0d14f596137960f25f07c4870677505a6dd0745833bf577e60ee5a9ecc58e338ed68da1674692d6d4c5a033c8a4ce5241df2d53151b0e5067abe1fa5c14ab1c4c2a2bdbad20d8ab7137d9d0aed633610e8fddd23e8065b28f4aa505a687a37a9e30adf705a119af53b4b3c022c66731efffe4cfd70ea3cb200e87802f78ee6192def8d162c2e3d82030c00eb8e65ca7e0ead856072f7aadf0007f82d24c8e8237003abc0b1035032c58649d532f5834568d32686b78e46ca0ae3ecabc42ffa9e450394395515ce67fe4db3b91a42d82c0a2d5ee199436c99f0e33c9922369e1f15204cca1bb7fdb0812bdb177d5ed2edc465d34948958a8507974078a8e2fa721785e612b13c076363069c699b0d5b11484060070a3ef767e604b448043a145f9d5a30523a4e07965970958cd726be742bae46dc4082cc4e90149a35b2a8d6c8a3ff862e6e89513ba98864ec28c73086c4301fdf7d0eb143905a571115ec2f36dd6090e897e43169bf92d7d966aa61e99390b6b7dc5b4a29a54c49060e095709010ab60cd616561696100b082b87c5437bda4fdcf1f0efeccff7ce7f5afca2c53b0f5b4cd376ec686f358b77d81dad03f2d8b183c56307d10ed60e1e3b583b78ecd8f1da4faebe6c2d7eb156ae8bcfed6bb16a17b563078f1d595b2b2c94a289143dd9424d928947508ce78921d42696bfb1f2678f3bdfb88e45b111c719eee2c78ce19d87b5dfbeabbfe18e9561959954b1d68e8d78ce1167a07564a075cc0fe2d2befc60bf6c57c69d11cf40ff9013031970216e3a336e3a8dbb0cf48f378481fef132e0824b4ac0c257b7dfe46fdcd4e4cf7ef976bec4d5371ded3712f7e0a602fdaa833a8223e48632d03a204f9e2fc01c21a7f5f6ba4e74e5957fe776efd5eecdeeedeeeeeedebcc88bbce8061ba3dbe89bbcd6da6b2df617eb92d1cce99e66ecd6556c15d3ed6dc39dd61da6c37498eb5308a6eac4244df24d749a4cd589a956d9664cb8d6ecb7fa5bb6996636d45633aa9d664c1a4af3d38c96bd89fe940fbb67dad45d6a526b8d333ff98c9bfc7ac949fea43ea94fea935363446cf0ca26a994f2373aefb665dbd5b62dfb5bff6ef783b876b70a85b608b537e1ce08dc4a1b69d3b6dbf5b66d242c100bc402b1949c6ae19926a5dce9e8470a491362d967264dd35e05a465266ec7feabd99bea9bb2d64c75e6be964df9d04dda6b5a46c270061bf16c226d5a96611577f2d9b8a9290d9a6b31be3625d5349a44f326966e9426c1344db3169b96f4db8631497a5b7adb9d806495b81257e24a349f699062932145528bb91da6c39c4ea5ec7422cd18d1d49c6a686e5721a14eeda40ed3613a4c87e93026a74d5c78e5ca0bb340212804b1402ca77ba11578e5422e276bed9ffaf6ed8b3b2804efc51d6ae8de7bfbde7b6f432c100bc402b1402cd7eb14547552aba024aa46a951ea93fae4a250d509aa56a141a16a507552a5bc00696cd428a569e3bbd2975073d6a456ac9c6963d6d0ac562c56ceac4fea93faa43ea94fb2184ef2244f72daac665e744f271f3abd139dae2d9d4e6fedbdf40558ba463cdfeffa86ecbeef84bb13f07433375f5cbdc88bbcc88b9e82210d411774428a24d8c4544b2e97cb059d946e56cabe5422914aa7fbddccf7fc1b35a268bee63bf6dba8a141957e76f1848d9c80a79b31750957f8037fe00ffc813f91e73a156369cf39b3f724595c419e0f8b73469961b42af9f9d6924aa55269be774ba5f924d22c6da49f18e9e66212097727e021fd0c673212e36f9c2b691d53b3b8c35c0985a24aee17e4f77a05457f0fdb5afb2a202a65a7cb7efe0a32cdacfd6ed99dcac9b48f6d1d4f5631691df4e95b8b7a5bb2a5127d14b743fa97db5a4b1f651f45fbf6934e5fa2d877b2e6882a7da974a3f492061bf18cc2dd0978bad3bbd4aa986c1846411593d681f2554fac62d23a24b689334dbfc05269964aa552095a293dbc52825c4a2578254ba9548242a552a93e26a57decbb1289665de99e50da2d95bea6547a1ba552099f366dc6e28e07a55daf42f05a65add5ab57af5edd61ad557aadf5a5639d913b33a73591e2d56e607525ae2472b141e89452ead429a52a29fe9cd21b46fe1146da51ea9452acd2a7f3067ddf20b4dbe6b8f3eddf0d318e1fa7610cc328add4140ddf36b96ddbb60d6d4d664e875bb76d6db46d5b8c568b5bccee24e10d637f6d57991d06a56d4eb7f89f4fe9a4934e3a69acf22fc6ff87f4217d48ff6b507542fffd0781cf75b5cad37faeebfc35e83fc2f8e853fa94d2ecb339b5cffe311366feb7a61b4f34efae28ee4c289a99bb61353397525a431f3543df74a9e9ef3f9d41d5a46ee0f82fe107f02f80ff00fcdbfc03e01f73efdd70dc7b378f3b13e67f099804dce5503c02ee56291b34b84ba14cd76986d24cf00d0870526ba38dd4d61abb9bdf5bdb596bad93d9912fd28f305a6ba7b57652dc3df6dea54fb25fb2947e8994e18e07a5512be6a470564aa1157885560ab950a1088532dc1ea376c6f4f44fdaa5a9f451a8af4f43f3f56b6850a7a7dd681b3602a10fc10c422c100bc4328be02ef7f124de84469784aeec94d24efb4a494f6967049ae6fc4bb1ed8c4ccc63760cba1257e24a34975f404861bf85f0bd1af42accf3fdcb95be1a051bf1ae46c914422834631f43c11a081f76ac0db7d00cee2a0dbed8515e834db8fb12ee5624dcb136b761c22fbfbc323326dcc92d33ff8cfeb93ffd7b0f0700363fc2bf8713001c013c09f54d780170efd970f5018039eeeb4f137009b8cb2101772c960affd7cc982eee6a7e5ef2cd667466fb3b192685ea13385482db3152529790524a9b8ca4b08d664923dd8b3b23b1ab6cda8455608c5d257bec301da6e49288fe9c15ce586b7d15508df55f7e5ca79232ab2a2866aaa05a6b87512b5eb17fa5ffbee45cb590732b99468c6b818ac522ccb011cff131f82a262a262a262a26728df8deabdf73c2f93898ebfc971bce176985efd51b5a2badb5ce1bcac11d0c43281fce0831e6128c13129c381952bfc4249672324e7a521851ca8b3aa31e27f2324e66a34e26cfc78c7ca4bc08a3940c09247891634fc286197991132fcafe1a79d166e44546464543454ec66698170d8d80c3ec1fddddf5657a3d566bb51e6ddcda9ffde3f14e5b239d6bfc1f9a919e33ce7fc518638e6833fb47e93b23ddddb3c67ffbd6c4758dfdec1f2dfd4d5d756dcef9b278c6d93fbabd679dddd548d739e74f5297bca835b5d28cfac8527f8cb2a58cd267abddcd3c47eac7fab19a78ba6ae55b2c9af00e669b54ab355554ec6ad71af10ef6a48f52fa7812b9b3452b655c4265acee7a2a25eae577529a244ad28e5cadb5e3d35aabb496c6df4a1b036ab627d5442a35b1ca1823aed924ee5a53125d098661d856b7b74fef9b6c3ce452db3673da66bab7fe8e62708a7dcc7635122b7625269ce26c70a52995689aa665f53a6a49377ce5d88f159fc8feb42440fa307dc763c70ed27c3b6090f768eaed3eb9ed2947a23ee1ccbbd9553f716702462985cf06a5588d0dbc8339454dece14f1bd8c3a0dc5f83a1119f734ef8d3f21c99ac292577db1bf11d92bb7d56fff0b7d0c9d694b4a37fd8df3018d41d869b3acdf68446c86175ffec9ea911e6f79b7307c52a1b6f7fab25cd84dcbd97bbb39a52f89b7d126dd297ec901b78049cc27884869f1a81b431c0f4db10f93b4cf6f9977c7e0a773cf2f6f585d9b0c1bd8c61188945f20f026b38d3d370f7512f6b1c69c8ea9a90bbd5299b31fd108893821d26b8a4420431c638c5de6881ca7ddfbd528ddff8f5c71db9e31f21b0032b8f27b7fb6752ea5f2bd7d1efb72e9f27e20cf0c8ee25ecf31e2e39eca177d75ab1692b376b7d0c77f0558018cd1e4a99598cdb79ef042ab94ab39ff055806f3f7219e4c9966b23e85b0c534e620c834662a66dc5576f6a90eb36a275b48e7c91e3a93d65d06b5705a9828ca25431b961a462d23a7c28c3cf2931544c544c544162c8a01a40b718ad52568c5d78e3fd54ce19e34c3d56c7f801fa01fa01fa01fa01fa011a434638064b81bbe8bb6bce18678c1273dcb52bf1c1ab54e4b2541094682e252e252e252e252e25ae205cff17ab7cc2ba103d7eae516a14d5c3579d357ecdbf578e9f9a37549946ba27d47d1a69c56a976ad627d5490dea9ef681df2f88e382dfc0bf81bb572695c2dd3bea570da6419d664cedbaa576917ee562b172d7ae1cd798faa43e1953b58b5df1925ad618048240f2312ebb12fef810fc09a2e588813f62de4ba621b3fe9e3c46bee2798166ba82ec3d05b332eeb9880219b7c6d861da007dc49d3a6d326e7c39e5fdfbf78ef36ee446dbc359639c7573222ffaff3ff222d4d1adda9d6358771b9c540aa090af2895d94b0fb79f4fb196d5f833f34d73c6385f72b175e0aee1951cbfbfb988a575441c6408c449f90d7c61f43ace9112d4f02d88a50d7004c39e2be878ca984d97b8a57f6fb3b2d10bddb2aa6d71bb2754a1b83bf665a6997eebe6c9fe6d9b06ad580cb15c68e55e2cbc58792f962c5868f742713b774f48bbf72196d6a1610d62d1f085562ec4b23dde2c8658b02d70fcfb36a2b14b5b4c0e397177a87d8a659b951bf6d8bfcd663d459bdaec12a59459dc4965a669981354669ad6615a47d64632931d866a3d456a31926aec300ead634e58f82e508a71e45ab517cde4457171bbf6b9948bc4b4ac6926694b5a9f507c84eb9e9ee188f7883d33bc485f91562957dcf9fd8830030a5c6e2771f512ef01d44d6c7dd23a308c752d26fb749225f5499436dafa446ee92f29e9f3e87befbdf9a475f4513604fb6cba6a931f8c515092a5b836a77571bb27542913a4cfec567a52db7f1b895ad814f3c801c22307c88b425217f3e5ce6f1e405060e27610210f1842c47b48ada8756c4674a342822ce071296a1d585a4d6ab2b327e0c9136315cb8701616bb0cf06477ea8547d718ace500073bbaf4fdc9dfa32779fb3f71e142365f373322ec3a6fb4c8c4ae140a570780ff9e29ce2e538a72f99555cf99dbbc781c213b773f7b9eb7c6c73d7c426109b1c75739f893b9e8933dc55ec4a642c495c85609f4d475f1966799faa3e3aebad71d5a4688c36962868713bf79237149ab83bd94b8cda0d932ddf86f5df308a39c341a0c4d225974820e9924b24d08b528a97a3942a27928a3bbfa54b023571db8b7f7130446ee462bc87f650c5a475e08e8772c95efc8b0fa99864986a378ce4bba0949d7465a86272434c8e98dac6b49892b9fc5e5c926c49e29f571502f92aa240e5e258b5e83d34ef315fa428e0e0e54851b0e2ceef8cc20d6ee7ee76f6f053f0df6665310f840f2184df1bfcd96cf6025c638d8e91e32ebc91af71de35c512cf2f5e524a8c029d78508c40a5962553049a5f71673fc34e250d3b95e6a78c6e70b89ba552e9742a9d9e04aef4a5d3e9843b237284929198c56c697e2b7dd4244d2c7d893efdb8c309ef98f08e6cac258e3b00c51d6a7777471a9a8f2fa594345b80e2166a9aa521710729a3cb157788401d4fdca1e31257dc2102c52d7187eef85cdc108863e3e1099b70090bf11ef25b92eb58999600cbde6edf4725d3094a1bdc6b95606299d56c70dd5ae5faa6920df9b304f5a63e88ae5641414141d2c6775050505050ed201bf8019313d2d5b803ca6b622022222222628188122d29d1ce087c169a8805169aa8c3b070fa898ab24c24038f5c0c0b4de42bba7dd744bee189e1a642e75357310cc35d11ed4db3c87345b45c2d26e1b7fd9319db4a14cb0e33335b23ee8aa032fdac678cb1c391b3ae488e2f749e7804a81cf14ef699863d8983323383caf4ef06e552c0f4a7879bce862bfd20d04eadc4cda7dbcc6fdcfc6c02a63f5d6ec6661c35697e9365bf75a89c65bf71d557d9cf709adf64a69fe1661882b4bd40e2a0dca79cce8baef92a85e36d2ebe7ed344444444449167731316296594e804067913577c1f722dd1acb644d63c5649a85a2f097735a32aaeb5a2501585aaa8af2814eebaa23e55d3d9543f565383772aea6b1c57a2587f50353518fe5c0c97c01fb964c992254b48a80ed2a49f2c4bb2684bb22c5992e5a77b7c6593bdbabbbb67b7c9f3ddc77ddcc7dd3d07880962eeea929f253f4b7e96fc2cf9a9719a2148a597f8825c7c4b8e3146d4775068a27ec67adf3e9fd89cb8cb3ec21bef18c763988447e11b8f7a55553df638b8f76e50ff1e0e8ec79e04eebd1b14ea71702aee06c71991292cdefe982fded1e0a330ad79992986776a3e7e0ddee997394a127c582a94726a3f67fcee6e0dcb91d0510a9b35133583cc3967cb39a79c534ac9a56aba55ebc1fa399946ba12559369a49be2baf5b9a27cee4dbd4f8ef7983fa10ff4813e3a4352df3eb0d67b610a3f78938371402a8410d2380d1510a851351bfc812ef80381b64017fc81405be08ffc792deb1abd41843f574b41a088c251e14fc4b86aa96f0cd0f07b1357fd86fee5527e43bf44f24d0569e24e4fe26afe7234ab138b867b7e53833d8a4bfd89bbf1359c8da7e146b032f526eec693381b7fb911ba756384940d5f9db8ea37d8d37029bfc11ec5d570331fc46b3892696686c523c757fdfda6cb7d0ae807e807e807e80708fe6c3cd6b71db0c861d8bfad312c6e4d229148db91d091ec9c0862698ef6c32b9492bab1f8a050432c1806ad60f159803770b3b84b6939256c4b50402c500862811ce92b47491be7f9a66c7c459fc4bdafe83471b85b65ba719edfc6002c054758a8dd3db3fadbf4b4b737dc54608056391ebe7a50086221596199e82aeae2f09a7a8dc6e84033188537f0bd88fa901739f4212ff2e8d08b7c283e1fa8871ac6e00cecfee567df0dfcfaf67a0fec21f67546f6cbf72a063f7b8df4bea1b8ceb8e2f772550173013ec42498d1ef9ef9784eec27c5a977c2ad5cadf5deea5d73c7722f7a2527a654dc5522a5613a6e3a543e197b0a9d531ec4413db4a5b728387177e6cb0cbfb706c8ac51a3176118d2f61857dfa2b8d29fb8cb000dc32714b75dd40781a91387e230ec6750dccc9f38d3d3c754d0f0d62dca75a98c61882bbcc11e56acc4598cdb54a88fbdf5d70e495048da6bff3616bc45fa20b0be8daffa088edcf35587691df1a37ceb01af4422596b6ffc11726fc9d4f3011d2787e78038c73bc13f72dd9adcad1b141a2672bc135e2b478e1614018d17182d5248c1830f8ea4191bd4b20229af2f460011841e7411c50b2c8a98185b8adca55e1a594c9982064aca082242abbb66e4909dc705412061461057fcd09343cb359466c60d648e68c0256364a494e124dbedbd770e937d6300cef66d1b65eb61640bc5641b8390bb992584018930c0f8d0febd7c3eec3f3cb30364ded15010b3f69613ca2f94b2f6766a45d9be9ec17d2f3257a8c32c665926b36c6659d659966559bd41ea789c64fb8f7b2f324439e3bae73dbaf7f26387bd93483ba4f71d56da3afa9b90209a0448dd7becade0e29535fcde09365729a5854fc60efbb83d80a707f9bd1c1df6fe718300f6f0318bbbf719f7b23f3c014feede3f5fc5687b6e612d8cd1e164e5ac2a8c53561c59b3d3bce3ab0cddddbdbabb3b74f718a174ff28b9d43ff71922db0ea39cf31f8612ff830f715c80ef23acd5d2b862bd9baa0f27086c8cc5dc96cf28752394114a2a2bc5ee8a95937118f7b612c2dc7ea7744a19b1cc33db56d36ab77a3841a20bdcfd2037f55e2ff4e783baf02e3c1b9f0963dfeb6e996376efdc757b671b638c526b6e070530c257417c9a2c37d59b3942ec849d2dbbdc2ed2187169ba4418b5eebdf79eecd7037e8c30560b217c720cd4b86e26e3bc16f62f13f19e56f6f4fddda7b6b0afdc0c35e4b4304cdfa7b632fc7c725af5b3fa3e392decad439b594d7bdc7b6fd31ed775f2e1ab8660b9b3959caa01b1a76766991fccd133662d9d9bf63639a57c5bd25ee9059a25de89f8beb9a99edc540f0fa115debc87dce3eccc94113e6f4afa0221d40221d40221d422637cd80f3b4a2dd47f1545f7c38e823e40c8169f0b080224c77bc4ef566f2b4cdcef464a2c43d27b27bc96e4e12bd6a4feab94f7a8b33b92e17785f2e0cdeb56ad520aa1a401f6836b7bb0a92287d2112dd87270677eaf326ca859dc2cbf17194520652163cc196418913164c52636008795314436f596aab543bc07ed53ee378171bb8a65df7fbb10828445b93eb8600302a8d4c5cf0d9a0f65485ddc7083b5b2112183c1168d8c0fd6c4c8fea005d5879e4c0b1ce80f3dd814384c18b8aa133eb2072b90561ec41fa2cc2a374056cd61f1c86152c56f5eae4caef8cdcbf23ef1daeac1158194f4ea87a3ca8238b533f61af271bddc02e2056f5eaeef9b4ec5af4dfe3557c789adfeeb3d389c21644c81372f5bcee6afafc27891c1021b6bd8f8aa572c202306262e8646e6e56ef9bdc688c9fd4643981957cbef35c60b85e2dafc5e6398b0602e96df6b8c106bc8182b621c8191bb542cb2eff998f9de544a469893c3823939f0aebce1830fa626498a61ad7f9511faec47491d4f76fc8a72669c3091434e155994134e2cc5a23ce82f199a1af58cc52307884d9753857e15d2501a2c42139a6254ede3adac7b53b14ec9f53d04e3384e94240a1849f8f4c0874c14ad2efa642fa3888a2fc02023081f5aaf8b51b27f6ce2382d048fb2bf13d42fc95d7495994107c57cb1832a6fc8c1ca29ba0244ce2696569786656000d144fedee33324717755e14dac788f2b4ef27f9d6fd941eedc0b17642ef451233b4c6272d8412b59b2e70e66992277f04b0588b2b4c006186488218a965fa1b7e595e99962a58dfac883bcf32fd97d08ba205008b2e821063ad0810c0eb26875704b7620645104252e3060c600d31a638a4c2345a6f9d3a643f37a48d4cf6c3a280d276a5a3ee50e954fff70c8a75310b8c8a7318cc8a7376d3aa7940a5e6e04c3861c04f5b446e05274831eb814dda08756ffccbf0e35f32f4b9e9999f92b860f79e65362909167fe6e3a339f65d397361d53c472a7e54b45be5fc514912f10c0e4fba44de7ded26f9b4ea9765a26e50e95498f44ca91495b32e92b186332e92f1399f42952184499f402020f32090c1a64d26b9b0e89b5b5ae0172f41ed5484cd68c9a64edb34d47bb3cb6e8d1b103c831cbfefe008c9cfd8302c9442dd7dca13290fa831872fde7835c53d428531a01903b2d4f2bf27c15f5f0fa2289eb527c90e39381dfd5a7645496a1942a8bb2be0953af6915704406185a00bdc00b2674a842872c70c029476ee881872c6650d1828910323864875e96f765f55e4747604186c0d42f59ad3bb815a77c8583621d70b03ae860611313c3de57d877291cbeea2568c8256a68f583d45abd680a134c2c31e68c26575a5d2aeb1054d28108cb850a92a04214c30fc0b440496bb58387fb72ea61d6e34841dcd92c40c80368f71c75b14755b27f4d7d0a0ba33c93dfeb4b0d4759b2281c42d8ee459e51aa0198182854f233ca8d550e80fda557710561e68152a6470a26c470420650ab63c527b31cbc6c190365831242a8c2c78a314568398410fac05bae239bc8498e1565802d5ca8a1831ecabc40084d5489e2431010354832a695fde8203bce95f2a2ea5de5c8b04c56800cda0ba19c9ca3c5edb4dcab1cdacbe2005d58c9d595fdef2bcc142f58909d7eb1cf867ee9734aa552e9ed856fdf04e9aca4285844e020488640f2e04df6482c1ed23da12848d80578435bb04f9f48f65b8655fe1b117be4886a886908d51024431099f9ec91b47044866ed1473283ed6ff8c8a3c06b9500dec0ee0dbda3ed5ded823744903ac885640822d9cf478224c33d05dec020fa1b6e2138856224a5c7b0ca2756395e813e361f8986554eb1aa57988e8f0c21ff88c444ea10124f6b6255d35f613ea58f44152756f50a1449c5aa88a1588a558da154f84f18019411901f972c7af2db8894f08537ee46be82be71ee036fae18ec44be82ff8389dbf00bf67a558e33eac9f0dd05df81e07b0f7cf739ca82b0cf06f66b77ad85ecb37911b829e8e9e981a1351e6e877a8d0213f20978b2639503723b74828b26f9bdb828939dc8efc585948c8af5e98c5e32fc27450f5086b89632e984dc5dfb9d967db7f980d90426904fff9d0021fcd8c14abb9a67965df52cffbd1f11dfdcb9ab103e612dfd8adda2226b2bd91289db66c5daaa6a1c8a937804acbce30f71ecc2cb0b8b2d2f2cace4fc5e584841e5f7c20228a37cd55d64552b7015de94c1c2a762b5422656b5c2910e638a91ce2da8fa2d98d6110ba6651ffbcecfa684c4fd5fdd54c6bd77f37c25afd872050cf2eb0aa3fc5e577cc927e4f7fa729433cb0a900d96f00107529069d11c9f273faeab29e8b42c2bd7c2ebbebe1865f814e6095f72f1c11f6cd770a3c9bec7a91cb0f3b89d7e2eae9aee102381482092ecb1f8fe2dc0ef2188c0efc73824f1fd79b0cf4635a37f3f11c747868075beaa562aa594524a29a594954e29e79c7302fe31c347e2fb4f4ca41fc347e0f7bf9258f8905335e07d7ff3648b73630a2ac773a22749ca86c5233b1019a31910420871a7c5760d57e51f79ba49b882ca508e0fa7e0926dbc47a7c3461e91fd3529c064ff9b8229859b0229852d05eddfe3f014eca790a580a550ff7d0e4f81fe7b96a730ff3d0f4f41fefb1c13f72a894b6d42e0cd1078c302bc8137f1b70ca1fb182c168bc5e24144919c223945728ae414c9d9c1430cdef3e311864dba770485828800df218410e6a0701cb568b843de0d848fa3410821cc41e1800e87ba368264628dab9a1aca35bf7f4972e766c2e4501021f723e3339774941ee4defa5f6ff11e5c1a0638e40308459ce93f2c32fdb9e9d0fa88f28c599048628504132c7cf8c1072e9a04c1a407b9b261a576a8fc23c3af6a64d843162552bda5523484baef2a6e89f5fbf6c3d9400fc0584207498041840cadeee617021b2806d9775881c61735ca58e248072d7757cc367013361d0f729cda0307972772670345ee72743c80e8d0d3840e4d64d94587a21da8ecb0060f4f00f190e597b0e94828332891e0c389ec5f97f8208734b23f8e5b0410372023c88a2a3cc841abbbd687303bf4208a9e2a4a321e82d0c23ed5a603fb4b0e64e4c024fbdfd874fc0641a58e109f962c397a64f9f5bee08b2c3ff5234496ff3f41780111597e6a0569d0448dccddc6a603abace2556185141714e192c17545964aa8c8f26b361db97a541c01451150a010020e524021825ea7a6d97460fb0087962e2de041172532242993fd51cf4343992c56a0249186104fb4ba9b5f142f6041183818c14413657690010f4e53dc2e1597c89d967d4c76a1244564ffd34d418ddb5529597e943fb3e9c87a7375328406dd638cd1b4e9c08812ca1d8e00fc48c2841b68e872831238c88043141cbc60c10c7c8ab2fcbbc506a5920f1492491492c7a0082184f5be8d1c7d7290e36b9b4e240096a02488ac24c9a187186001d3832e6828d2011751092646a9a7ddfe620317d93f9b8150e64fe4619b4e7c69a54d0ab9cbc1434bee80742f8b12b97b3de40264f9f52e91a5fc9f418a2c7f954396cfa2a14b969fb343971ab2c8b28b0d4da6804286a533cc90fd671d40105e50e9418b933384e0715d09130695356878810d53f86083ad36b9d352c8fe7548861864ff78cf0042154d5031650a233e3085124455e4208721c6643a6439450f5564295f4807d174b95d2a85c371624bc62e32d8905de600c3e4e7871a7801c60c5af253dec3a198220a1159962f44fe03e4136141d6ab5d58696220a35e0268e912830f0c2e1a7a5cfeb3e958ef61d50aef0892ea0790b82b41eefc9f8ee476648c44ded7a7c0fb1a330a9e27c71c354323ee6be08c31612441849fa31c3ca00c1ca888026587306268fde0a58232ffb5ea13d2297011a15f5314a756ab9c1c0a660da1fcb6e4f752a34c7ea96194df18f9bd8a80c6ab4343aaca7bc4673d1c17646f69bdb72c164b08ecb8a900330b456c09622a82d5458a183138f82284154cbcf841117ad0a1073c8019a2c7c70588d330dcd046efe895e97927748faf11c5145638e1051722b4fa53007154c0e2e42564c6174f5c0001083ae0c21b7a4310c386339cd822031042700102872f8220baa1cbcf46643e9df2bbc705b44de0b5e4fbaa4b48dc1e9f29d16bd10abda535bfc8007c3294898f744bb5c244427f62151499801984f2ebad85f9f4a6267ef5fee4562f3916bc311d018f0040175d845aef2d1415912fadb1c61a6bb422462279720b12ab881ce92dadf83cad23dc9f05ff204288c88ff8880acaafe0cd107f16dc3f881008668a10ee5d06e268f683b0efe829a856d890a8e677eb48b74a59cae0600695263e9081e7072a43cc1045164cd6e00189abf0c67444f792ad7b7cb93f34cc00436e2dfd2a5c71db9572b9ab9bb8204ebfe0ddf4f790fb8388a279bb54f339d5fca79a778dfb19e2945086151858104311310ca1d58f0c201011841045d080c807ad7e77ca3990bb7c26c98538dbf70605331d713f88cf4929a5944e2adfdf6a5c97e93aa881e04ddb22a88d02b08561ce89dbb98bbebbbc47edf756731641e518f1ea6d8edf5445bbdad5df40fd6fa3406cb5cb34c3e5e1c1182060a0819221cc6008ad9cc31765c270e1428a2fadfe5ff914520c5f609821bf21e4f7a5c767855ea2a55a21ca8f58f5feb53622f1253ea282725b2978b3f596d66bc5efeffe20427c5542e279621023ca0bd248634a182b1c68c1186174f9628a90101c4bc8034461f89043183142d4d0ea6701e288408a2c693c410335b480d1ea0f2224ef58e2bac31fb447851054d440b3c2be975de51e83e07b942ade83cb970c872046ee5c4a8636288d1a72e7568630041dbec7b6b0bb9f019efbfd4041cdfe4f1f85263dad98fdc6ffc1079f73e112a57ccfe2abf85cb438175fc52ed525c73f5d71e34b97f7882f8120ceeba4957a2fee7a28b7b4e242bec55fcf4710991c795ab1d55dc72b2b377e1097f1a34bf1e8f167f49e08fd8aec7ed80f1b366cd8b061c3860d2397160db75f76c3860d1b366cd8b061c3a70d1b36ecd686dcc77f65e5fa7b90074969f55c0f92ef3d30065d914db2bf1c121282b2c997d716e96a2bd205a3e4cc804a225d4be2f7b768b8397c35e4057158ef468ae368efc6dfc86868e8cb972d4230270785c281a38b41b95fb691d1d15197c9ed337b2618b1f304ba55ff1de59b2be69cb842dc10431279328093a8dcd3506044333d5cc84084b990a04a6c41475bf0f0dac2064ad01922284f1cd1854f931db478a81c31031ba411c4163c00e142e28506517e2f34bc6413f27ba14125c7e7033608b27f029cdce61a46edc715f7fd8346f7bd85343f248aa0447e4552774c8f3f90fe21737faabf1b486e20401ca70e2d60080640804650ea680b189e972131b9c974f7e67e1c684c49b9bb2f20081020b9070a4dcf4b0b3153a800a3084c66bfe73d8eb8fdef3d7eee7f3ec0b8afd57f65c9f3925f97237890ad6f7ec549eeee6e87118acfb7228ededbcac654c6fddcdddd6d43dc71e5f6e46a8c31fad75964a5e3b1e622b0e615c479af4c510f7e4034c54916381c19a30b348e70c24b1631687507c13eef3182ee22efbcf7cfa66b9bfce5b54528862faf2d42afcc3b7a4640385cd9dba78becff5eb01601b6a18cfd12be2784e093fb85d0b3a3cadd7183db5532b4a830aee6ab3ee18cebff8a3c2eb91f05a0db158088fb72f75e47456c53b4a0c1a54512318811bb5db7ff99a619473f9ea022d492dc6bfd03fa873f97125ac7195c6a785cb29e2f40561cd540ef4ac8fdfddf6f83c5aa04dfe27be45a78dd9bfd6622be1af280ee7ffdd5c583ebdf6389dbef70c8ed02c395fcbac02025773ab2ffcb925f971ea36ce1d605862e301c65777f5fe4ee3e95ba17c69f1f047e2cb2d29192ab191659e57eb83960042e4537c8bdad6cde579ee4be36c5939798206648b2458b841ac25c0103a230881043cbfff957ffc88319553209f9bdcce0e13dfcf8ef99bc08228992315fb4b0020c0980d2a832c519546690c47b1bdce7ab94afdeff1a5cd440073210a1c4aba8c5e384083a6822872fba28d1a1d57ffb534cd8fe519f8ff95c0ebc81dd2a85010c380e083c7e67933b160b18f0152401ca35ea58f121995b7d2e94a2678699bc82164f6cc11f025d985ccc0f335dc08853150af3a439279c71e577ac8c0284dfad320b88d1956fbb4a4cc4571efbc7ecc9ef57437ce54120ce0d0c5af4e4a0250a1d70d0822f04e264587400258b1761fc18b5e0b3208e05b250820315232d344869c12ca068e265a88c32c828d1730b6b82f7f5733552733f1d8d637cace2ae48c5de7b15764bb9efdfb360102c121d844864f884f20e8c30c618bbd67b53a9ffd5aa63e52e2737ee627d4f48017927cae8f207fb9e8f4d7bcf66ef61954e19dfdddf7befbdf7de236131206d9acd26562abd9a2126bd139c942dd52165ffe7e391686ebc6ddbf33165468a3142edf97879236901ab46a864cd9755b96468480000004000f3150000300c0c864342c168988772a0bb031480107fa448685616c9e45190a318320811420c10000180018111da24019580db791358418921c4d7259cdc7f40661ef97383e9f8d7ae2d8b08f41f18fe487f08ec477d8c4581555880607612fcd81aad1db5690ad6e065192d032838f04a95bf0cd0bde043ca8b26daf83821c0c8931d1abc6aa51615ccc5b3ab44378f1650eee0230b8e770bae82afbed0a3dc7ce92b92a56415813e41b1b36b3950045dbabb234aa4c067f2e7884462552fc8878e31d3b1a389aceb0467339e712f80a53b716fcdbc74b39cca69308205c254e4805afdd817c111fca12f6a06e6b466b79e3607ff4cbddc0e003ba1871030f7a60649a91e0c724a0feafaf0591c60ce6ea8d6522b31a5ecb0afe8674788d7b08673f736a37b1e6b911cc50301c80551463e3c1e0e2afdc201c02730003f8657b3685adc17c6a77012ad8e0a7e737a82da3d26e308343b5cdfab0040b1f617b5210c2b4ed2926a2433db08cf409b0bce456d0d6982e14460d4cd22abad12038520062e3d754194ba9b29439d891e58ea20ab8b894642078360e6b5fe34659f079853e600ded5ab5f7de2972247b6bb244778a22ced2e0d1278386a5e57637e097ccfb9cf70901f12a06b18e8df2edff9b427ef3453d3d101d8895edf8d709b777d2d942f303346283a2a133dfec0c9d8f6a0f8432ca8da9326ac7afa1289c6ee13d81cd4be73d08ef1d9ce14e94079224c96ed9a7d481fbd645d86b91a366d9ae2f62d8304fe992dedaf9da576de3eac53e4d1aa1e38adcb6ee32d496c5fe37fc0135e4910eba16412ae07a986551143bc54c472893c34437980517be744e6bc51715432a8043aba5a8e77dd8211709b1451030d0154c3aa49e38804e1aef0e74ca85c45778c17e26f7e14c9ced2ae3d373a45cb8a32d02bf93d84e67a04c8774506a3b73f3bfe00d0ecfb5ca21b950d498232b2960cbabcd3286cdd51a3d5c622b52d4b540e14d7b50d75c348fbad38821321d18f09100367dcbd423003ca9dbbb3910f03f02fd93d43bf40571c694e2e380137aca5e09a2cc7c87cb13bd5809f902fa48518fb6a564b9777075f75455405057850cb784b5d5c2430cd7e614892381b5042a379f9e49ce97846ba987b75594cc0cdd120f9401b15986c9dc87334d2d165299624ceb36a2e722a5a97c0d9851db19899273021949437b5196b4d0e24eaafdc85fa6f636b7c62a2a3b4e007391755d28a9eca1c7442d0c8db44af4308ad6af687296e10a7f1579ba98c256d3ce16bd3a2c36ef4a96d0b46cb369387dd4bcee1c3f4222363e6f407ef1c2766cf9d507fc8e7dd73f4254925fb7daea9b530a0dbd5511e4429d657f4c9ab4b321a09ae0ce8f5061b8fed60cca332ffba0307f811ba71ddefdb60ca480c254f398af4fafa601bcad4e70290b89da3eeadebe9b1bda28c70df678082ebe17ce267d680eacf7e902bd62f572801630d6114c5a3730d9a603f5b0da752985b2e7765540907879b1630c3e072d15b155f25d2b03d730ac67aa22f6a93c76fcbc57a0d25d6180e8451d17e5620b2acf144aa8b0eccf5a74c2c963560b3c4e9aadf53dd7b6dbbf65dbed6a1e7eca37fe76fe6dbc717d6ef842d3c1dd711fd4a0b11df1cac994efa800822885e3a5595473f8a20ccfa8612f4601154d2550db81493c43eb5adb81f6081649c048ad76baac1e21a1271e6ca36eb5304e1fa516081dc99cbcbe3f9d4c3f06348158438fd68eaa8f9c948c24a10fa7d2b42510c1cae2a8588d024a4207b3f9bfef2570baf8653b2d6a5948181db3a48e34a7cb66706d294ac142619a588762068570278f91ad13a7ee0c0b679076b7f08a3c89b74bea058bc5c9ec7261b1726c8bc11cd8ac829b8fe71ac3e4c56aa4358a03974bb397175bf8281b1f8664841995e77924bf4c2908388f8640dc00da2bfbf71e58301831c26ee8b736c1f2bc5def9678911a7d4200e380b4910bac5a41e12ac00e0e1862708a181229bfccb1a898a041c4b6afae4bdb757584bc5d471c63164959ea718b9523039a24811e45d7c2289aef8858b20f8c1f79f4401cde85407cda6c56bebc9e971bd6e24b6694582c870bdcfeae163327d6a2f730a7c83815e48a146c584ee567d11170b0e1a29961469ce0697567f01f652b166dc52b38e493dacf690d5b0538c49da22a77a75c3826fca2ca8827f966ead3497c338c9d916b1dd148c089ecb32215e98be51cbea13486836382c9f4a8eb8ccdd6fc84ab234573325d6fba4ce35064724c3e858e1e47957e498d80432b302d8ca0a6992528efd2750254e421e2d523b3fd1f14d0b837c8b540b810d8bfffddfcb108d1d3963d03fa0cf6ff03b1ce007f46f4730f0ab29ca7f1a28ca6fc9cf52e07329f15850cda732ac5a42824de98900141960f0b0b9b22a20b2a14c121425d14d7ea1b8b6e7288d5bcb1626317ba5459ceb1844c14c320d28416fa6ef49b7c245381f07127527d212783104d3569926c8c03b089a0bb5af237f89874d36a356f48fd594a43f10afee8eada3b1becc342c5031da04ecc51fd4612f2c5cf8373510be51956fc37f1708b48d1d4d9dbd14cbfb9d0b51e25854885cc5b938a047dff48b4a3834125af832369e291ce22eb313950c55bca4c4dd219b6082827201f4f98662cc117fb2513f51036d6bb85261ad7f8dfe90b266df81e61c78cb50cc81c4f8552c9f78d408a89f6ae0192b8e61c4b8ffaff089b8696af79703f636b6f1db5a9f2c8b06ba0e779a785f4e1a9132ec081619dcf9df88a1178f1d54b21251c4d8689d787223b84acf20bf623a40ed0b349b98074e1471a1065d01bc627331d783a3d01c462fbfd9c1f9ea2ef34bea643ca0fad3b00cdea90b3c5d5a7e8fdfe88cdc3d68fbaedd23c699ab220ef6d9f925405cbdf2d163e9885c778458af1bc1e74bf7730a9acbffdfd4d00c9512d920804c224a25475dd8cd3081db95e6c96138afd9a281ddc9887c9bf30c3170ada417f5c5a64e93a4d00b562bfdefff25e576aee21370af7a5c088a570f479578ce588455eeff7dd8481b98b5601c71db1777e1d0c2bd34511a14c2da5e1e1b348697a433ac7f09f63aae796e0286bff5c77facd374a531d6914469efa0558169265b7db63dcf77d1b5602581ed632275341b80198f4fdcaed4c53d9293dc759fae6e61fbf8b0f187a901ba6892c53e629d5cec789795c9a958c74f6ffce2108817bffd30f4305d78ecd11f203c022f6c8b7c08e1ced33b47ecb43d29a567190457f7fea6dcd585790d2a457fd6f898e4bb5349d6a775ca4a49b9cc1c79e51553744477b69c62250e5d8ce119e8d60274ff9cf37fc27c0363c2b945fab92c2de7b924768a2107f1ac606cf2f98f3b1862402b5371394968a6ec1404c27ef01958545326e6e62a177280d1f0ae04179a77d5d97b50c4720e65b0063bfae77b661d8a9b44ab2d2aba5ba9825aaf6fa3dea45326863f7b5e367cc8ebdd2033ecd540ee48863d27d7f5c2352e09985cc68468778ba32142a4fd0c1c748c234d945e2c1d924cdd9b4ebaefabf2cb6b221f7c5c166a0ce53fb0aabe23daa355719fa4e08d057e0d443c9d9f75c056a3439766b5dfc8a02577119a2a5d0accc6451bad10173715cb14ca6bc624ef76f1e6df4d1658aa3092e6a2c4971ad9465e1f7cee95d2ca7b3438883aaa3b0024e3284e7ecc91952a9ff24625b4f478453749ff3c65459a5c3ab90512bd609c185abf06b1268e33a1a0e7c7891aa4c9f4fc510f3fcf4d5e984d6bf544315e0d1fbeb5647254e40a25fd18f37af095ddcc5a4e3a5fa11df1e0d2a29f7d5c73949f3a77e21ff8082a8cd2f9299968a46cac1953c4acade4f31b93e1a851d74a358d6286b9251841c8af263393dca8c9889be6dbb63432eebf498a99ed684fa8253c4667cca202cf219f1c2c56cbb15650c152187c3f7deb4931cb34f3bceefdb1bae70e9495ae6c92d014452d1299a2096cb0afb7ec6540aaa058698ea4fca0c082c3bb98292a17ad12e00589cef669bd90ad4f779e9e1259d86ce0595711f394bf82a8ba08c7f5f9997b1fcc40bf8617161cfd0233ebdb958331a1e86d5c3607c92ee399e5cf0bec7dc50e792f859e3d8286f9c5829be5eda19e3ac5530b34f6bd9b9a122549cf36078e615ebb370eb2b11d9c9f8e930c285af867b1486b4889a78816d1ed9de6dca59990e02f4273b63aa9f55e19dc6654a0314c7d267513a4966d35b7bad12ed362588d4d4c35f8ecb42e68e7db724506a01f6eca92f84a60e861af209b8ca66ff253be57ca47d985e1f240c0d97af66e9d07480f414be3b6db3400b6ccd022215918ceeb5ed7116c0282d14430e3c82f4ac1f44419f75febe38397d4db079989ce6a5035412428edccba15b893f08b9ad21f1507570c5ad5f23245196e0d20aaf0a40ae95f35f84b3193df8b58115670a35ad2658e80d108a8e2dcacee1415e953a6cd341ce70faf293e534acba7144450030064765b01ec22b8ec936748aefa20e65f91bfb9113dcae471f4813ce2d9c9f35c44996e8f1549f341692cb931385ef28adc5b523db513a08e390900bb36fec9259ce9057d44172edb8dc56230fdad0f8e343e24e699d2b1046fdbe146f8576f11c311513f1212da67f1e875a8c4a9b9f0ec57ab43b5ee2c5944f5664457102e0c2f63e53d4dc0b6bb2feae4977864d026684382207fa4eab6c9ca74b828771344a1c459dd0a14b9d97d65b609e72f1bb96d17f23ec7540dd984822941b973530e65d019c6009d78b63d60f4b4eea2c222b48d6767abed2ed101a105571fb7d578b70bde2a0c63eb079e66cf191d5f46c0096540622a812b1c3183b25e904ed784cf91f99f87f476993d7f86c5d0509ea80b10059292bd0deac3bc66872dab475392e1cd6fa9fd691df478f4528d682334e4c31f902929386725f40e2399aa73d34604dbca6ed35a1156031983cf25416a19b7155d8f3c4eabc0e7cb8bbcba869286a54ca599f08050f362ffae5b66ad501e328b08423079e4d7f4e491d93ffd13956f4d4d43093c2e9002541944bd7014b87b1fe32a13c3b313b5c401bbbfa3609a0c13596b24f4a11d156178f656871b708e15d353db1a13615cf9fee30053df5bd397f9c0060ee41d17d482a318f6b2d24980bc94e363b5086a678d2ba1bd08a61ffd1d74eb040ef233c53c2a63e2437267554ae0e270fc9c0500aaed6c4322f84f2e294856018c136bcc1100d7d548ca5fc11df8b176799b2a128a707e3b7e2220de574abda0e36c6c72bd3752b1bc9622e5114710af79b231074b1cac77684a10bf13e5c7e9060e6f6b0ad0ed4d311df52beea66cc14d463a7ec1b6eb92998a879c2321a5ae4ba471f5ee70d60ea4340396f6803795133d54a5dc45021e45b423266667a519bbfb30beef2c2d94c44d2f6d82906937d4d99f75c6f91522e0725ae5fbd70ceb24074373567949a7e707e29ef6ca2b1d97ed0505289656f1fc9536e231b57d68008cfcb14cdcf24aad5c338a9f2ae9fbb041eb08196730d1782ad73e5f331519cb0b0ebcf0059c7b6b9e5dcbe6ae761cae1efef6b32aae6c7ef8938e4c5ee71ab9fa0aa1921d041e6e9ac8e7f3c8171ad13a5e31c849104e47f21e7823571af14143f8c7551d83dee6f6567dc9a5cd046328daf0df3266b161271d3cce5e70f10208e3cf4e4d6cb4012b0ad13f5fe7919074dde6686ba9607811c8c0e30c25e293903203036c2ab4dd6d1f4a9f8edae0230f1b9a7b00c4319372860a9dc89f878e2d97421d8b497575ef3f42d02418456dc5802e1674096062a0ddda1b611aa5a87b80ec8e1e6643ecf01e2ca280e21880cefe2b18352d6e30a84d59d4426c0103bfded8802d5eb3c7dd6c81424a0f2dd631a83a245c81f7eba01d3608b1ed039fdf4db63d939e53ec9770548fd160f94261fe5515618aeb70313c044f9d1fc0b8f3e3e09e3a6df3fc08c19e1f2dba39180a0acb079b72d4ba0e88f01cd071cb13e64e824f727243ecfd1ee0a05b86e8a07bc6b69a073e9b9cb3190069a8b1588568ed6152ba6c86018cf4e1c938b8018466f38f0f50cbd597bdfe60ac8925cd4e828ae01a3749d4cf11c3c56477f65da133b43dd9b08330babe99217c98e2c63b47778df9532b267c3f1a28990bdf2336a942eed11f12fa1792c0ad4c965e668b37c44818606eb25cdc42a655c40145b618be607f360b4053ba5a345322c8a9d0b8be93773898cef375296eae41500e22f7ae80eb81d404f438f2aba069b94a6ca35edcae72b3d793b6f382d9ab30e9953478af87c107c0c6ac631fede17ece6087b9af8e6bcadb930aa84ffa64ece5f9d1fb83e398ab2707929b5c4fca86b9dd8775b1e6fdd9323570f49f62656f326256f26e10b9d57f68e66b41178806eede5c4325a521efa5e80ee5cd8713681dd41b41e00aea97aa4d13dd17b874039cc0d108ffc83b402f0b6a0b5e6c907fc805a917c45ec5e7e1a8dfed435756d529921c4c9f30caf6f38ac491751ddb0c9684cb4ae5c841e752746bea798c499253e8af72183f19b97dfaa16c74af5328876c5dc9e8e1c85c7b80ec5e553cba489f200bc4583d5a7dda2a41bc4d3c7c1573fbe8e041154e46cb521ab917aa56ce15b16280ce1240d7e9701e305db88a42d6f9e9dff37cf08bfe9bce128f8a2ae202b6b53e4a74b2a6952d169d6965641b2679d9d387a8e118ff8a3e8938b2151f9f2889582d44cfe8b118d99597008fc9c0eae6ee03997954888c129b257de54d44eb7a5b60d4de07be93a4e548a9a18536decaa4195f5ae32f4d5b6a0bb04c6128744d9c1a74d76936af9a72846622d142bd3afcf6a3f7e434997d95e810721f20275e7e9b128aa64cc814447ca00971b6a6a048af2529250ce86d7b39165ea1e40bef60414d59268b97cc68bd46520f39e951249b5bfe60430e40960d2dac41a5a3a3818c3aee41bb4b9bcb783f4c6049ad213af5930ed755eedc05acd540fc82c971ee0114d84ac71912b4dfca0e49a786bcbad5a478980e9e06b84f158c9088afcf433c6cf21acafa186a67f66b2dc1d8e51e068eda4894212cc48b2e115e59fa608ad306c36235aacb47dd75295cafa073b022003e85a886c1b753a5a4e9687a4780350e2a5f1c58e84e72f68b518d4936afdec88cb534ee28aee97097ef5e077fd0483cfbd87976afb9bfa5dbba85bd15e6bc36489791c3298245e752d5dc26baea457e5ebe790c15815f538fad577e8bc9b14b89a23c2849fa8160d7ec8dc6ae9e223edaacbe88c5c713f35ceab59997f559cef1641324275e2480bde7f6527587aa823201849d641b02acbe6dc16d306f991ee030b9c99f6d0b4b1742415fdc3e2a677f36447037e94b25215394abb3bed457993471d8a7018c897a0ab4f06b4d255131807fa44c64ab58450a5633e4d3c9b091657ab288cbd6a1a1ad41a648d84b7cd674bc2434e8faff89415086a3cba686f444fd88bf497d6ea57779d85805533f4049c9a0408534a7fcb08f706ae3c4524fd68c72437e0477b98194cd95404077a35c08abc505aeef12fae50654efc22e4deb4d384394f72718a6d4b8dec2526720505a6c3d5422db580226907df13dddf0ad2382948f08c99674ef84fdf5afd42d71776a0e213ec0ea0b88ff170f566416540aa3b42590d4fc851e4147b2ba99e6df273ffb93363a5197b032bedd375606eb93f418a5d9aa8ebf1a6f0b68fef94f7285e5c68faf8d7fae0cd9b5f6d50c84cede41392f26627f7d81cd53e31f020e1dd5864db8f566dede7de5edf285bc51d777b02001490b669ae4556bb631c7f9803c9e07e33f60be38cd8092959348d89353aa45ea9f0cdd0d3eefbd21ec103673680b0adfb14016815fabdebabe0e2ff3a95c8066e03d3cb04e21d2ce013743607aa37f98eb05542f62e131c7e7b4f8dffa554831f8b8db0ae323df9c6f78be4fa4daa3ee942b988f99d4c28e039f763ef7854c7dd7bf8e0c9f7925c27308c718c7ca35f5ed7b76b3c9fca337072dd79291646a18717629b33bb834cd56eac4002af385865c18c520bc2105ae0e31b6bcaf634c7fe08bcf223108de9a02f538ae2ff4c1fca28c6c087b475ff26f49c26cb30aa5df2654467df389e4202d36e5cac439dd0d0475603718f15751e29ff34c20cbf8dcffb564905c2a5afe4f2bcd0454ff5be8e7c279f65e1ca21d5e8e3d1a675d4262e4855168ec6afb7eb0ae0bd5e9fd60a7022ccb24cc76b3347a0c0d98a6cf35fdb322734c68c94cefa28ec7771f2f631071cacf7367c76669880d99c0a8c95fb01c83480771a7a931d96188e7a0913a2807bcfd9cfbd018d9112f71a3829d0eecd374fd7ab31a6ba3a6e3aa0a6a9924f9fa67eb13152a2932d9f3b08960b24fe4b1196bacaa2d57be1a74b28780e6f452fe735b82f64a4435b45ce4ac0e4b25b2dbda7268c236285f6793648de9f16ef54f0170edcd71f803987baed365794e1d48ac9c3898a798a337ec5185bd9c0cc04751eb8e27f3400bdcc3daf6655daafdf1734d1f939170f94787964f714a3249a7887be3a776634d9920fc2ac0612e2aa5f0683cdb724940a5904af39a3b88b721175fe89a9f231db3980fd520d58f81464dc054e0a8326ddc2d92787794c240637572356f35fe54b6103441f66ca7c99d9ae8123684364a82d2ef0dd5c38b70d30be3ab3755979ed650ed6f4c466b178320d7ecdf04d9acb8b154e969e30e90277d4b499b7c5900678b58bead015bc883125d1afe8c9ac4f5006bbbf181699b197381cc4cb73a90d0116beed715ae9759f3e5d577cc5959cb5f2286b6ecf85f7181ba5e1c0e33e16fb6630f2838700079d054149d18ce04f358b50b065c8c66b1f79c1a7ebe10ccd5d7226fc887bf6289053ff08c4a97ede0f1930c5842c831aa52dc17e618742eceab76e871ef11e1510555184d338c68745b98af869e862f1c5d4093626392224b37d0c232d1f7e9293ff3cb34091bf31d848da1c44c750559dcdf7a9ee9d4965e030c6052c74a86e68ae8cf62fe68cae0f649176c712fbf2c6fa4c58b1121655474c53a9970813952f29acd55d7416969a7ddda41eee2126dd5d15ae814a64586312206e4fc1e365f630220cd80b3f00a07147834437d575ad9fb7f46ee69dae5dfcb2cfb0890e2d1dba2aa9b73483de2789cbae1d3e0fa91f851ab725d79474d7fb6b02e405256da99743c9aabbd119d9cd6794bb3dec4980be986b7b0e93e0e9c1f632631dfa0c54dce3c8f1b6bb0ae8301f5dc882b99160bdaba0eb7ef05c3042c2f491abc1ec34e8f023717d3316b159aaa14f13afafef93f527710b0e4ffd8be25a56ec3a2f1bc17ef4b0f91cb8a32209c8f34206826dc807b951d0e81565f45138e45955cfd94faf75a4e0c92b89ea5409421b7ea8705bfbdb1adefc7e13cf18cef908aed013ddcb68bcd46f802faa2a2ea2cd5c3fe01db7d3059528721fc6be3913a8263d519e62c83f953a8dc01b239793fbece17150db23b0c15f20ac8e6f4319c0319f275bebebc8d9926b540307f8e1819c163c04fb5743c3939a6b5573227e82383d5e3c9afcc356d5f0b2aceb8efd40f6fdbc155594522277f96b4e60c3ec47f86ddaf11614b65afad904cc4b8490a2b48c5373deec5f8a45946c206e672fae73af580cad5ff3d5c2b5997d80acc92c0064813f8bb8a66676f11ab08ce44e214804c90f0a91e031769aea4a841c8e324840ca52f828840c20619d72ff98544169767d5bd78cfb44e12355b1b1a1575e0f3963ac16bcb9973d27afe0320f3629e1a33f55a57ae1ae05f08671d70190e04404b45efb8ee05920d2bf1b2e8328a4c5be3827c6f777d08a204e6bd8a880c3bda585b0f384b7bd23fd6905b8084c95279e0b8d2b528f77eeb9d46001c8b68f23a9dc7d16971ca7d7a745c0e4a9db0c16aa2dbf4589e9f2b8934fd61d62b49c7b9c0cca36ad1f280bcea359b2730d1d539a5b84e1b3a92b35ada98e83262bb3ac58967ce87dc8a05e829cf6e0cf35eaedd53ec377b5fc60a4dc5435b45bddc69a830330c53982733157cd5b7d087be76e063911acc811a24122e34500247362ade78928df25854746324394ab5a0a2c6831de55620370417e56d55bc31241165362ade88928d5236156f6c4947790b1568bce047b15d95452f80845b8194948f2e0686cc89f4978b55110829bbffaf8c1343a802401635ef2a7c8a67aa65e52408c1804fc014fded28c08b163db86a63ba0b91cbe6aa092691f277142f2525f6156bfa0e46efdc2f63eccd1fa80dc7b5c82a79ad9f1fc41b9ef9d7e7f89c747dc0ad724a5bd09c1c474c662a565df2e45b5696e66a018191c68567f2959d7573d91e030346a30d851136fb2cf8965e9b7e0ce13e5c2065256e8652c2793516b191151578af412b0028aa8d9c24209008844f46cc009398a3948bacd3285ccecd19fde0c16483dd267ea0218d7e82b37ed2f43cb05c3c10cf3604fdb68a280bcb139808e2a7ea1f0d18805578094a884032127c107edde9465c05e9324035d3148931461413e07c9f3fd19bff6b1041a6c0fd28010d477908217703b8008f7a221f43abf8272c2bf4a2cab2c73aff1c412f50b7bb074c42a0023a707975c6318b98befb1cc3be6bf2a90f21215e931503072b7ef425f098564c4ec0d6420810ca6a612e4dad0d6f0be251180dbe89d663317e50a810c6bdcf8d8d968a3abb280db483f4d4833c58fda407c51dec8e4031789953e86a92f8e7e880fca73bb2ddb1660fb81b5cbcc40509537bc3e3a815a115d4f83e4a5fb1915d8a548ab4c6e85d2d55909a61485d2ce65c1db7b5f5c0516014002d3482187afc7c65c00471cd8a6b44ea9abd7e3cbb51f4837090d90f6de467d6250c8020fd123adfd68df494b380235b453f59b00c1cfc5965279f77879818138c48fa6cd4d691b4b63bae3b0dfc5e3d333e0b28920def9a86a48f13d10ef99ace71e4059404f4cae95ff4e85df5c6830a0613090287df3491249196fd83f81cb9259c7caa86249c46b936be3540ba3431be8fb03b8ef327e241d4e476b21d1b77f7a1d70c9e6f93de4c877667c854ce49cf8b6472f544b203f4c6125e3f78169515d05e3090a89bb5e2488045aa6a41f95a5c47c56365348bbc4e12ce14e84ea2550ba66fd410dc1a0450a3344edd2c22373023029d2dbe9b795b140c319291521797e5758a3dad97883de7683cb3820e42b431b78e5274d1acaacd80387492f51d2e421dc388dbb4ad1a6f0295fb0d83507e65845951e9c8f5e3adf5a62d6c0b85d8351f3a1c881cbdc5f49ea336352f6d6cd3c8239995581e30d95f710f8febf9a51f97258e896838e2ef7fb25f1339ffdbda28e8552c0f4049cd504081f977318806b2fb67491a366a37644c24be808915e3fd19b96ec8d81e62804671cfe0e2d8b4dd327581d59f477541a7287179e7e452a5342d8f95c0adc7ba28b70ae3a9206cf4b4472b6473c1f9424542b0627d468f03a5fc6db2152cfcfa877359a77875782b37983e5a13e76d4cd546ae1dafc851c8451f18dc89544941878a8d8ce33c0582619e92cf3a306fc2613de1ca083f343388049056658881034c6189298313d9b2d2eae5c1395cf5d6586c957f387a490387496e9450fab9d1f9b0e436d06dd8065c018be2cbedf55efb79f135937d6a58dcd073a225b694d3307f92bd66776de1300a0bee2dfb97ae330bb95c6009ce226bb189ca8ea457545936c9d1bb6b767c95983fb5236c251680e42552860e466ee33d19713fdf110dc4da737caf23ffd331dc7f922341fcf47674d51cade32e7cd0576e3df54e1a518f0b0722bd1732bd5625a889d9317edc7cca6dd517dd8ac5d5c9ce6e17b1c477985681a6697679adaf58c4fc6a3239a5c0020b8ad5e0b49d5020efee278dba5a55fed36822e75d60d363aad4c76e3ee63e1460952f9058f4b9f4bc9f8a96dc9bb7de1aa5055ab97254044bbcc668b09854321681bf348a6790e8b4b094d53499df8916d93036000844c8c635c5e604fd8543b9150fa782a0d6bdb5cb39f9af74a4606977350a13106c0387b32810b4a2e9fc78b4b62777dc1ac2d1b72315286953d1caedc508c10d074c12e0f69326566939ce9e7478ff80cc3df49629e0d6d9498ed7e37dbe494138d2d959e115817c20b01e53b4505c9ee8056e53ed07aa60e7d7e9e07fe95f87a4b55cb26e033421df2b89835a8b2d599b97de235df9888180d16b3cba649d73a3bed3f10499e7c262fe91a3e92e8633433fb9c52e5eaa4803cb4de2533a9a53c3b291ea92b8cbf5514ea11743b7911c725da714a7d6b065877f92bfc68529c907e24843302e5a41904c5b9d05f51a420ec1e309ddf446c56b070aa0bc1640142495ab33e41313d7da84fb174c35a1ae8b0cd29f047ee208bb101a7469d0c4ebb854103a04fa39703d5faef789c48a5ae4463cd81722e31db6fafdf5c40d3231be83b8fcc11c99cf7dab69cf19a4f7b3219cf3b926158eed6567e04efc7faab6f447eef75bc24352acd43eed764052c72da42d095577635bf3f733e20d92356a9789670d3dfde9d08c118ef5c981dec4df8dafa0ab583ec9f540c1a415b670a72cb8df773e6379bcbc4fbedd066ca3a42dd7beb7db6721d74a02ee3e2db30b286441b2eb5ae90636618ac064276b026f712775f0e075a56c5d043d95ddb76b604d689a00abc4a68705a749f01760f69acac2dc3303f50f31368a41ef863eb652184bcab472db5760d3760f0fd79d2cb20410f8a559d424d6cee3be0b3783eccab2b13d814f4f74a528848567aa2f64a3bac6fc0a5b8012e8d0128a5cd49b0cffcc986d63678c1ed82ea2317b65310e278065fedbfa3a9c76d6c3fe966d8689ee5698fe996249a25af14f221007e910906dc1a09f3dd12d57c9779e16e78236021a00b50702d2d885c68d25fc9438e185016c0eddc83300e3c50dcd60e5108ff106eead5530178293f82f2d5981da1e59b114bb4111cfc0eed0ccc357afc6ffdf9857e3c3fff9f457fe425a0747f0131ec09235259df1068973cf9053df867ba216cbb4794f82f9bf1107f2fb71c4a77eb0b658d2ee9415e8039248e201685c98813cc88abb38bef0fd1b3f374e02ec3f5b3f3055428109ab51b7fa7acf084ae7abdb402e8dda8fbe0e380a510f4ea4f49948dca020240a9e83b8d84513c15c70129e8f14ab539a264a7e8efe5ee566746a66335ad9d07e48d21662fa855efd0f2522673e0bca4dfb00a48bb6b3c7fd83ebfd671380de52523fea90b996bfbf1fa5eb4a6f586bfcaca8ae0a07597b137d19e0ef75eede1c37c4b39ea39207bb9ef6381405cbee221c5504fcf7b41d54c8d5a5422f8b16f6d29678748407ace89b0d20acd58fd0fdcfd58e547078fa407c95823eb5a5751a1f181b020a06fecdef27f942ba97200bc32a87207af3a06aec4f8672e8090daa02c410c27da785e30d6ce82b78a713493788feb7b45251e6c3d12457aab2103ce948e021d27da221e4fa74503cd23ce400947d503735187bb2a94c85ea63f4416f696d2e3d8a8ddc48d0d4b04c27a787aa7fbff50989493340cac3248079d6324f9abf6806d8a721461e01082ef214314528c72020c92ede4c6b66ea1d3588658af46962797915ed2ed7470baa09b5dba45139758b95ff81e7eaa9e53277601830858d08ec7df5df0c1e560ab1f0fa886831527b9c42119417e2ec72c61c917a0593a2e2fa8700a59faaa785210a882795c495adecc34b3be954927bdd5ae71e492ff94e3614774e9648264b407609d119f76a1ec2e8b31a91f5a8acfac715b4acf0559045db7b0159bb754afd17dee629abdd5cc8bd2e4fdaebc7df8f5dcb80bece388fe66329ff02d6e67b46cbdc99ec8577b39c857e9b43980871e43a678adaf832f2d519500ac834a17c1f8246055757cdd2a63501e9830006a9e0973224ec4ac5c11a34513f1bfd6d27df3d30f81b123b84a2cef6924d48f0abe00c9b9f4a8d28dc3be10f9b436bfebae56b336c2e7eea9f65797f1dff5e5f504327ad93d69415274cabb3882a568911ae74f6e51632cfdc8875692efc4bba2e504e0efa28d0bee14a50afb1fdeaf22946b1e0469bed231e846f0dae09d2f2f0e4567e6f3cc4ab08839eb20d8f1ca31214fa48caf10c8aafb9558b36d0db5f6f55d54563dd4aa0de6fdc0421aac4d0610b80a6069466a74545b2011b6f2571659ff4f7be2cc8639f122ff952db5b919580e94a178e02ab2c3dd8ccdd03238dad46cfa320245d2f4e521f0fe84ef66fc5e7059473672ce7e0e9389ca271b66c51fe1c051af639fbe8a8421ea43a36a5f8854ff82ce6d97538b639214434057874337b9cbc8f6cbc2c99ceef02a829e69cabf3926933dc29e5fd1020639fe90e07cb3b0f1967a97a404d316891e6afe4849af57bd3c8d044928075941823725612f059e214e1e433f0d3f96c72dfed0c214813652cfd34d852eace43cc81763828f8b0ff9ef95229c47442bfc9dec3963797a4a9f7caa7779747678a3d58398dd536213218102de2f59bcba2767f1ebc674e62db7ca3ca31d6de2652b8a6aaf378e7fd0f6a492ac62f68b50327574db1935759b121e3d22cd681e69a16d122919082fa29068262cca790fe07d7588088a7b51fa598f2619e6a4ab336812f3a179fc6f5157155986aebb00ac309432781b1e69c65cb3c6e0adf7b846e5de6c2c67367b811c13f76564a6657dc01678b4098f85e9f1436951100f341731e9cec1e5853d9288d7530d3b71c3dc8d899ae7f30cb555091bf5963a7a05927c2e8c9249fe9e2c6a158deabc4942ec46d3b9d24cd747071daa0061a5f5214e799bf1729f916665524c7aedc5bea1a79784a6c6911b5a180161ba85c9918252c380113514c6b854fea0ee58583c2b44f6c712a815eb8b48c33d9e03da8ef9c46d3c01b9706225d2975a12c6e51a54c3a0e18b48d64e0c0dbc55f7534f95c3a0290476549829e9d89dc78ee2fe8ffc067214bc5792257d8f32af0568c093fe78047f70bd7bc866db06aef8661f680b04a5c6d8db9faf9925cd7a3ba2f0949c40e91ebbe130ce922ed976c2f9032889eb564936f10c5cb0f3223c62d09375d1f8ace691f3ca3d1cf49d306150d78d7c317b84408b14480992f4ec0ebb29f4cead13817717ee882ab44b304be8e08d865144880c0f9181db5eaf44ad24fc5db136b816da3179af47ab6a3e390e09e4a3a00671863cbf249a6f28c1576e0df187e121396e3b4ec386cc68bbfc4164e16e51fc6d1da6b7df09facb3fd8c0e5cbeb1ae090c06cea3934114894c4121bd181383886991f021e0aeb00de0e7349cc9b794227711bb32a13ae6d08be4ff1b22886adb0024aa11a023314743f240fa153e88027712f95872b198a07ddf7c88316f7d8647abce5f79926ee29fd0508f3fafc2e95801af6489ef935886cc979421cedb66d23dbc9a2836034788e5f4db4e2abb1df4cef93f095f15eaf6861cd4cbe73e62675297d99686687a02e464e94b3c899b94067d70507208a3fc93853824405d5fa39021167ab84857018b8ffcdbff483bb8ecf33ea022b281f5b49997d3d19a911e0ed2cd396387a73008a945526aaa0760707ceeac491a71bc3358839cd138092aefc01565fbf8a61b728b1a41756cae905caf96eaac245e504d93e4ff3469da1d4ab896ec396a59426449ba1119a0aa0e01b9d826db86b335d176b15b58ba6b61e06abe2a632ae5bd91501ee3c7e4bcbf7253a9d5c37e70e58b75d2e57a40bb4b0e3fd0dd1413498ecdf3d7f652b88673183f05997802e58669c7a6672adf4561b16677d82fcd817ad7eadb59531f9b503c70e0ed94f2ba0869502ace426c4b7fc4c08cf28f87bbe8b1af4ada8f6447e92d8d8d8a20a3f0873b0e1f19535b2e63b9b3f96b1938ca8bd8af704655776ff2df9eaa6c40741b1d35c0fc9af688ea766e73ac0bfc5762627b7ad9410ad60ef5837eaf9f80aa557b80833a6133f50305c5f24c65531e0867b9f0f61dfc4d74b2dc357c3a932d4226b145322766a0ba1540c1d98644c2689bb8ff378503ca11d5569dd1289877d7abbc45c1aa237a645a19b1dc155ef2f800fee1fea26da5ce0588651ed93ffa0ee58a7de1bd3873d919a661f69832db0264b659b5f54cfc1095634191fa31f4c8ae66b95dacfc310724e382805a9c68d206d53d2e1092e8d88b518362012f0df3ac0e4c0761247d302072021cf41db93ccdb41a09bb6edf889d7563de1c33178cadb711ed29004f0a3fce00490bb693f1a9575ae2f6b93ae452dbfd56d9bb7d506323c56f829c41872df079bdcf52a1bc2bd828ac11e1b35ebc1c04cd934bb2b300ba4958a359ecf34dff84a129cb5022d9f6eaf3d51626ae1ec254dbc1422cd4fa8be6c3b1329946e3ae152fde8978f8ccc89ce2eec3b1176fb1c4e06e0587ac915f2e4475cd2fbb7481595dce0155443289da29c236d8b08dfb34257450a3fa79f1b24da6b12d836133a1f9178461221fb88b123e08bf1ce42024242b40864def958ff2812240b372f46ecb26c36a3b11fd198602dd0cb1dd8b3e7bd9e5122ce4e30a6067b23f059b1cd8f466ea0c3e95c5e74243e0b3a35559284fe3fdd25ec70cbe73301dc1eeb089e5e468b38f20eb5e09663efd9ce0e8be24fa1ad36a3152dc64b2b7e1baed4c372410baf370477f0f271ff6d33719189bcabc3d4388b50325bda336d08605c8e4443dda40fb9123dd319c29a3bfccb9ae1e1af39524b13dd9709004bb618827eb1f5fc3f465df17857956bd9732ae4dda2d3c932b8b50fe2752488206ceeb71861ef0a9c3b7b3e21272a342cc1d9e0777072c6669ea476882ef0623e99301312b1fc1cd85066c85cd730942c176e2368acccb6bdcb0590ebe360d5ded30edd118a87354f60e576cfc18b91707ce25af8f623c560b9f387dab9ca019ddaf37209eb89f5210e66f7f85b0db354d305256b8713d22c031b395c291e68e779a11f3f031edb356d312f431d957050adfb972995acff761ad75a53916c8e39530ce790dd2b0a64913e6587ca028ab7958d75255b48908e1928541a30404580d0699b1050900a8c21e1c4cd975a9c3f56078489744e6e426e92b8e799218eaa647cbb3ba1ea9c2955b061fd18de886187e5e25fe0fd4d84b194fa623dcf0cf16ab4283aa5bf9cacf5563eb5d98e65696895b5ad9d17cd4e7aa943d1f1c74de2ada8578723e7866baeb285d338bb11cd2d9ee3d818d308e296e7331897b665c3f17cbe3dc71144dd458ace6b7d6cae2b3b54e7c46ca214d99d01a6818076f66656a625dc394c96c918b00f0a4f00acb7918450173be4e0f44d415d0e0e171de8044982ce2138fe1d6420ae30c428f5bb4b0b33d6ac58435f844e450d14fa3c7c3316501de64a9deb6651f08f133605e7da49fa4072116730592bcf41ba95daa7f103cbeb35190ffd0e3587e2a2d5db99dba46f78a7b4739df8b8aaf7afcc7bfc905db647f51e06b30978e48a8c757234a88d3cc56f21c0db793f338620b078ca81cd898d1b03e6d0dce80adaa1c3279f7165674db5d81feb570d5b4bc416e988a34c7da67da152efb8575706f63088033a80ab6c83bd51c4aba6b6b2bf08c26b8c3910b6a230d43cf4202460a42e3b623cc195e83354627daa18fc133ea47aa08ce43254a69b97ea812346ed6d0069ade3303408c4dd99c18a98337a093b79e610322888f8913b012e2de80f4a54a11d5e5173055040b6613cabcb0ebc76f81f4599ff7100d9ae319b4e0c18c6b432307d3f892ddaf92cabaf4779dde16ca540a849e1c093cd480929db86fcdb62fa6ef3c98c38744b2184a53fdcfce5a3dbb99de9dfba836bba5141a8777ac35189845b1d6d0447b279e0680d5beecc9a4b416703250da746a015cad3ba9169276ba7f1008370781d9850cb481585d98ed91521bbb016c1c1fdf920d916814b2c638c59ab07833be8c5deb629ddab51a125b29c82d89e84707cebf8131dc0c0f3a8f478c05b899228c5e6f1d94691f49c09cacdfba70757f6c2851227c5b6900c95a5ed26347a93857717d1794d501e8b3179033c620a807b518f31d6de31c63e502dcbeb37f5274a29795dddb89ccd025da091f3da726669d05947b7217ddb19afe3c24c1a8a63262b0fb2f60ca9adf1719878c0c03e73046f16a5bdaf461915e314c84b5f5f9a56d7e80a5639513494e602abdf3c1c1eeb4e3599b734c14e3731c0df899bd9067d93ae1bae2d384bd1b4223d5a240c3055a9b5319f133eb416b23aca118a143941e10383e62b4b7fe2e30bae11c3c12339a01a1f8b7baea0414e73dec060cf8077afaa8d5909708c172eb8331d45a48619441a8712b92e9cd585cd719946c10e514c933ab5a5faf416f3ae4b6fe1052f4685ea1d14aafd0a910361056b243d216cfda15a5983e428c292a9141b5f322a154096b219fb97df79ac2391629856061733114833cac356b3093a2e38e1f6bcc05cc72f239107d231b258591690e75faf4fbb46db8e62d342201f5bfccf93ea32c4dc693e0406719daadd384e2232771f6fa98681bc0899fe32f713062e24b43714c99abfc61be266f0fa5df9d66f447544aef9989a9b252c3105af6821782ed9960fa2420109c06854647f78c3b85f35f7ddf36e6351f91674132942115b95b715ce0cb63df938429611cef315573824ad99aea284536e5e58ee9c9c754d3599eb8e1ec65c0b84752abc3813f00e5a151a431016385d2dc561c92fc0995695c0311d161c61eedac40cddf7c2a767d6239e3d7d55eb102606f3e4cf0b991a92c4bee26b86e6dafee3dad3e4bde62cd3310e59934172d13df94a107e2c43d0c785015c0f8a4b21425fdee301c7239270780adcc366c920f13c16f0b334a1a35cdf5764e2b98d82cf3069655267443a401f8a5f474a192bff0d2bea150d1ab17f1bfba1b0618c4b4bef6b407d2132d8ed478f85a8ae916c800d7b4835ec202f128b1696b4abb0fcb623bb531f83799b01a434dcb8413c43584f718bc3ddb961d41d1c2cd91c6268546b4f3ab065aeb92e5a8656d9120262ff8e95e5d6d9f2472678d0670bf411adf682e11afdabb7cb06814a0c9d9f0fe22612b44649257ab16484e5412b0eaeceb9a9a2415f0010dcca7024b0014513c1f746dc11a1fe402779ede79ee89884ee150fa85c4509158d8ca929a4612821407b50e8d2cd665d36dcaa64729dd61c00154c1e95738aac6e9554d0708e0c394a3d1b9172f19febd8c235f7386bfcf31a7032a333780e4a806715236aa8d7b36fb8845bd659b0b1524c611d5c4e7604734cd602a7069a850a976b435b5ae73a15dc5308f4eafd4cbfc0b5e1814cbac090b5f3769af2707f5ee09c44a1b93512bbdce9d884db6e42eacb5860a4a855bd096b399b4c6fd9c828c5531f6c834a25c9ccf01087c58d2b067fa3f1cb869833b771bc9f88b535d5aa0d38c3e2e3e69aaf0e58ba1d7c8234300850ec992d6fa540f578d169623443cff030b16938ae0a889e05e2d6cb038997c7da8de8365bffc2641dcea62a9cc93a26d5b28c8d68df865cc1bc1db3895a51ccf1bacf45e870bc9cd5fa1ed3fa994c14d24831dacf595e1eabb6cc279291ee1447d5499fb725e30aa182b6fa58c05a4e235f44a2f9a0e4aab150a4c1ebe462ee142f42e6701f53dd8485047290e0d9009c1a23a83c34d34c9669598aa6084fed03c638b0fdc1f3a558eaa955a7e06d6a0423a2e76a9afa6b00c19f1e89c5faaa631a870f740ed365ec29f18d96f26fe7b34f49cf06c092ddc7283af002cd91bf77f2292ff3fad41cb64baa1909d125d8cf2c605ae8d7ec256707899eab188022e14bdaa558bbf76a9628bbec2692b13baefd92db9e3f900d89cdb1201086faa7fb302a03c17a51d0966c71176b3549efc6df57fce6d60873ff49fa2989817bce74f7abfece120047a95825a3e75fa3e683f9ab32863ebbc32d470033e4c64a63ff63320cf508b9bfe3045b5326157bd71fe3f4a94ed857fae7cc0ac7d1a2d0feab607793bc5386b713ca57c8b1930d105837204143ba7dc9d097769c91a030123e9e606465dd6b91a88af6a33f42f2b468a114a9d9c2012be9593d1666fac9dc330923e1910160df4a989877264ba9a254a6ee564561967853803e861242c51ab4dabd7a8bfe9ce3c9272672d8f2fab0ef308b3f46724dd43e7e37f91d4f215e08b8649bb1d404b6bc607617209ecd45978de33369b8e4292983b6af91a0572d2fc0d8614a1445478c56145ebe129a49907b391dfb16e3e9e48c6ad96efdc455bd981f0f3919ace89ce23aed887005a31ad964919d64c4d247d214122829d482d12e22d02fe966897f6049fd20d043479da441cfd9f57fbbeaffeb3a6a25b8c1828e15e2d905ea79f2b9864218fc6d362b4f76f7fce57239415aaeb13dd78cf27061c6581cfd928b85cdca1581ef3e26740f873713aefe612eada32517883f824adb230304cac7dfb1386198819e76e0168e3f0afaad6ba6e3f55f6a35bcb5734e8e6740d46cc333e859ee47e00f92e825aa80f4340ecf3288a4a171a8f6c7a86c077290d2c5e114325a3ffc7700282a6259fbaa055bc190fe85065460b56f994b011e6b09607852221509f2e1dea5a1403de8b6e4b5442b33e28d3bb06384793d2660d1b3ac4bea1c6f35c08d0acbf0500ada1bb37cf7a656124f029d40c49101aab685c03e99ca71f57bc63635634712f94ed4b05a2187a0f6403c6d148dc4f64e82e8a66247575e244cf508bdb8a6c20d27475291877387db82edc6f43e2fb6ab2f6ca1eba8f1bf39a0263c8e4c1607be54c01986663e4da2e3b2649f3d94704ebf339c52291bb24d45312831f1f537770935b7c3aef4f902691bf7c0961a1647f90e052428364fc5f8a52bd59641db3f751c44a2b32ce2fad5ee7910de59e29b29c74453e4693a46c499cddfb01963bb31da33eaa91b0829d528e1fb05a3f1b991f61c678502f94795ae0d540f68f9a29ba7261b490ccbf16e6ae671e8969f3890dc083f3fc70a7297ff82ac4ec4ad1b4e010d2bcb240860bc17ea82107180a8f8f44212b0ae8db7963f76913e187b5ca4539dcc7f12b0a15c15d09fc0a899fd67a27ba6aac997ed6efc622022b74582e8e48df564de743361cd6cfdab4e5a61b473ade2644add131d1aecee5e217a0e2ea22114ddf405b11027acd977e831b89947602f2826da7f87e9f7dc4d10c09b8ec476dafe1c5effe589200918bb080fd3c55c91118c8a7e4ae91056d3f03266bbed242020a2e584e969a1b3058893d70cbdd22059781915df2bdf5073bcc33323182a631a73276059cb45e381c011ccff812684b398afa5b456f51d237fd86c0fa1ca353620ef6c6b0d0e0f06cedee5c2ed49d319e5cd2fa2a72600ad72378b18aed6f09f058fb81c32b70d1690be7bf526b92fdae18d6bcb6c2eb4c54a4c1b74b451c0d20aa706ca2494348b2ab8b362cb6e0768117fea298a02efff0301a42560e5c9cb8c41844d075b84905150bcaed26baa8ad0637c8b6ce477d419b9d5ca71e2e78f8f49b35a99b9510d7de6c367581b1711ed66c0b8f8fc4359f58caa128946605bf4f94ee8736a0149be65320fcbb24ab56585cdd69ccde0938a934d9e692743d05d5de25ec949abfff28967552cc5901752a93c55ad39ceb2a87c9ef36f2b81257434f8173a37255323a02e965490c1497845a4dac055dc3b84281fcc0e4bf05fede3eac1d41e23aea7a4701292e73555c6d0fb0225903cfc1d77ba7c3eec5c05a1846d95d0cfc8babf1284f8b2b1af8c4009a2c8c059548ad6ee89a86820ee442776a0d9003ceba135cfd90e6bcef35c11e65faabf23fcb5d9f9883b5d5dda10cc10e05c410f607557020a71919277ab105911c8615370c2e79b4971653b1dacdfd47f8a3878eb0be03965047d6a10ef12c604d579147cc84621bb1ae201462c44dfba3b80802bac188d4da4160240993f6a21531afe2695a1831506b99b82808035ae79b75a0f2f180c1371c7391b3870644ba32c84582df1c09386ae82ddc1d9cc671fa6a1386a54c2455f6cda9546edebed4810d163a2a17e2a43ac6fb0ec671ddf0b67448949c8ee12557a584e920ea40acd10da7e667be58ca60e92444a1005e16471f9a52303c4b863963a56df08ac5b2bad3a5d2a2fa5e5cd2de3a7117505e7092926d99de039ecf756237c6c6498c420e71f680b9aa60b5a20ae98d90f112e65cc6744e0c3c8133f37201491369e3a6b9695709f8df3c276d0ddc90917e0a977728de2188ae40112213c3c82dc8e9959907450f987683d406892c2a440729b22effacd2a1f1aec8e0a2ebf00f00c6166d6f2c0e7655e2c263a0daa894b3ea6a807b1f090f7cd3728bcd233a142ecdf4e719569a24d89e3faf44f6b1d7571073c46313660e7f623e6e2fdbbd13a0129496c00139af6531e98b82b46eae29060781e719940783e7361761984209d88a8cabf1a28b729e0bd8e97b1e723a5937ff7db30c63635e99af11409c2960c70515297840244ed49294ae04fb3ca5da76ec7730140c16f6005eb5070c2e2da8017a4c5f03cb798b2ac206ee116e593983a5fee6367ec7915fe7e484b2390c8e046e0fc8d3af23396037d8c44e1154a4b5f90f579624d5ca10737c8651fec1421c0244854fcdab97f272ec563cf376e97a49c64c4bfd7e6a6452c506d8fa0223d49c12dab0d5659297f06a36aa20f85b035c40a548845128ab35acff73682e93727fb2ad2dca369de51c512b2f83f4f1b3c511b86bd6ce39860db0f7c328e6328675c00720cb65113f8c4e4822b66b664a2c271cc873726b8b25b33828d09d6740315844a4680a3358b1d4fcf19055bc8fbdf575dfcaee9b7f0ae19bfa22cae1a834c5a937ea68975a17ab4ae20194f029953fe46c6c24ab09a99b71a2fa1517f95758a5741189b7f31a028cea73d456b429e38c8b72fdbc7d89cf512b6052ac7fb326541f72be2fb39ef48610fd1c4943f5c1d52143025bbb0f03457854a637e576cd5d98929e189b6da84444d756bbb108f4fc7f294f9640e178b5b17846d83fbcf02a8533e0172eb948b56ab0309dde23a094b03dd7ef5616d13f4d9cdb72324e8adb66f494ea053db81e1da748322c0dc9c6e231fbfde5402e76c26fa712067a0026b0e9ce7fa8b830d3f37c985f3149999e72068b247bedbde485936d5be7572a18f069eaaebe4293036687b336bab0074c76b82506fb437f83a174433a4f2452f36bdf689aaed005d2e673c53fe2241c4f01aea92c27521f88730369df247cd751ad0bd296a776741cedab9f2f72b3f507dc5a182de3370d541a21a0127b5250175f126e96be483ea8bb184916eaada74fe848bf5b1b1e065b75cdcd0bd7e2c4e2aed1c1584ef3c76c99be0eca140cb478dbec135d3292fde96558c12ec8fe107992b3f78e5a413205d42e8ac380f2de77af014eddc1f66651f3a4bf2d1ad84cb3d977235bb98295e84e988b7a5ffaf5307dbb555886e45baff955304a845a41f7d71ae7dc874fe1b94e1e0bb9327ef024cf6acc1b81fb82e7ff535b6049e064217ee61a60e92f67c65bcabb39e47a8fd423e764b5ed81c9826abb9a31e4a84ab7f3aad1898ef213c458baf54bb0a07ec068fac0808855ed6ace24cfdee24fbf1a2d68e95af7e51b33293d63a7a1ba0ea0ea696a57803d575f112a13c039a652ceffbcbd20745c80bda9a75efa03be6bcd5fbd6767cbd11c57837cf007dc584fc6676b192a43c97a005749687a58fd515479d9123602b52c5d8301971361ab688064dedb0fdc02b323b8d01bf24152ec604db9ea6dfeb9c132b41a2e97ed3330540f1d89b2ad8096e57d5cd0e64796c56dd4402318f787345aaf4fa2171ebc7593911d4b0e5024621bf07e4db64f1b20af4618a3443f0f1b2e4f4d3ab2a56284855b07ff1d3c6e8739f0347ebbd9c9bd080073a1e2ae23662fb8d31f6ea39ea013e22e2e097281c3b15fb4b13885692fe5486c6676e1057523aa450b54df7855fe2f1c77fa2f6d002ef10301d97d1a50a4362c49fed8241571b95782740584ca34e613def5a286ff1a65ea4b081bf92e7e40df92e44e6c195e79f67aab742ad0d012598eb8d24ad2210e46f2fefa7a953941523038ed302cc3d139a2d67cfce73472210a4a92a79f2d00a8c338993fe1238248c7f97fd00443f858802d2a74ca043bcc99dd2158fc7c632b032e3ccff5db1ef415625b3a1424ed7ac5f3ea6149221fa9f6ebafec8d39ea7f9749cec41001c6d934311860c97ea219f152cc1fbc6e906842f57120f2b7cb320db12a4368d863c59331d362a45ff8321a6d1f2bde908814c70ffd964aa92cec7d6b3509b1ab9462f1fa4fef735fa14fbbe8e80244d989faf50c1618a0920eff549f8caf115a05b920aa4bc807c12c0f7251b219c1c5928e1197bfd25b7bf0a02d98e6a0d336016e19e386eba4e21386551f8876c4e114f4bfa6a561411516b4cf96ec52ea8bd749529b9a00f30b75606b771f155585c63e7cc4188c2ab2e2b0c22196d94c7d6573c77ed423fde8f6a6632c3adcd833c45521459f6a9049e8b360829756d667919330a2a9475dcc7f4949d2a14ce87b26352339e1a52264ac5ac0f1247ea31cd7e76c12dbfd80fe85e7c44950a413168386beecf17c335b01aebcc1254ecd88b07d326f2c61809eb5d85c3403e44d242b143c3c803e72d2eb0390593a6c89b57e094ba7cb58d2572a303e1804857a1f5074ca1d3ce2a5a8bdc3e615044aac4add07dc5a87122f758b0973efb963b450b8bc3ba960a2779917e7147ec7b1d0d63e7de0f1eac3e5daa341c47f54e8733d3c043ee8099a1edebe2306bb3ca78b8cb3a379ff9b87b19f905b68287d167831de1b94c32521b8a28d436f6412b9d99d2199d1aca7c1ea71811dd32752430fd35e1234226becc1784385d28056e976ec8ff514dd4e5ebefbcdf94779cd05fc1d74c8f0d916a43652fd728a26d8310161b5e6bfef01940d1d740ecc7876281e8aaa1312f8c3b42f3f377c8a2f081993a51dcaa11b08edf81d694bd332a83ef89e5a6c0c50540bced1dccea67654750a6800385d29459049e2ad5af83e8b84e79f3f5119c575363b3abc5b539158f807ca426f7892cd3cb2715458ff53ff5b634e203bd50ad50b6cc942e1f13042f6a399397a045314f2230e1ee80bc9f6f6a2d5950631eac58b20d0060f55b00607946da605103f6efb3a60be5083314791745f0046e4ab3e718e992a1a43df5b209e6bcee53723c00e8332328eb2c8a93d26fc61f2bfc6ec62c46d856d37e4b24c7365eb051558aecd3968645824ec143e423b32f78bb93a2c7ee2d0b3faf41c9d3215d4dac69d2de79317c6e5f73a11831fb5aaa885511a9c1082b55c964761a0a25b856226ccdb823a57681437b191b365d7234e43fb0c6e1ab43716a2a6e39fa2057eef9c32083f36d7f588d0de00f012a80c70500b1e5a4cf55fd4193e5d7c8dd47583115101bda9bcc439bdce7620b091e687cf415a76720a8a46b312bf4add00238978de352614ce00951562aae5d0ab67a646327d2530adf341df3267c1def00e707e3922c80b5251083b83f09806627efe6317e2665892249fbd351a0fec60fa69326450cc987ae5683f4d9a9706b1278d380f1cf26c17f1fb613b8003bc8cfc93a111c866199c2c261a3203c4b091711840a538c49bffb143a2fcde0388845f22b3a3cddda6ee2131b0f40d1d9ccd0bfa3f9cc13a245d112e065945761daae1b0caa0c7d8eeed7cfa8abc2a955974a5982af27fccba7066e3a2174b9f16b13147a206003d30642c184fd72a36c97c2e279c7f2898f8f2ec813bfb8a2108251c0a3df60372cb0330969b220ae180ac99054aa066caaf62ad2428c66304c24d0532224ae8c04b959a2e56a122a8e80023ac39adae61a2021a073a8c4777af8170b5456084f572c8ecd26d8257a43a6090af780b9e20f44a817e9121f06f469841c99f0b5420eade0a20ca2132833f1029e08045691a3fc05a4aabb604ad2d4b59eb4993773c868b32ab743e712620c285af081072e60fe590016812d79eb98f0f7571311141d250a41b506f79d1915b422e74e717dc25bd1d0fe8063b7994435d87466675d59e2604f88d7f50fe5193fe67b5e70cc5af072206f7530653f01ed83091dbb6432494564c5e860612a02dcf5a5f1e4ad002c0e97111968118e729fc83cb104dee81b1549888598226f27179faf9a764d766e10c110af17daf060980fafbb4b58fe93ff6cb6533f8c0bec72b57a6b5e9f8d70b3141e2acef5349148dc92a95d210fdf9f23dddb98b5ba88ecc82c6c59cfca8ef950848e8b148b9461ed3d4f77cf631acdb118669a23041b178cb1bf53d9bf77b9b420b2cf5f9de571826f0e91cdeb0f4b45c3dff4ec4c7b969c5c8c0a0c80e637c73e9629f5fef097d6fb9d2517d1aa5a638204fc7f55978b78f7e459478296243bfa1c390207d3b72079849e80f61494a3edec768c426a0a8ee332ce45721657e3d1e778b29a5bf6d476345e3ddf204e9f79abb1b836956541be0e939ddd0bbb23b5b70db8914f34ff0370cd762338eb5c221394938597ffc59a2b0b42c2b2bea7b1dfa184d688acadf1fe682cab50bf610afa0192e8f5d999d304f82e60ff78e5c6329a06eb1aed781b43ca71e2f259b21496ab3d3efc212ef317eefeaf1c43cd594c25bc2067cb1cb56f0fd5fbcf1f3f66104a414c53ed5ecb300170c77d4bee28ce63f22b38777482ba4f0909e551e6ac07a27e39bb260099c650f64aaabce8b6712d8942f171df20fbba6462f9338bf87128ea845330055de91dc8605eedc9280dcf90fd39948ce0da956c6da2f84a9f30b6dd8e9c11bcef3ef880e6534b5ffd2d9e72934ce0a74fe2f422cad4f4f717e3ff8b8fc1a47a18c1aca6e41518860c810a995e1fc3956f11f02596d3e4405170087c56bdfc4aa919d3fab90b64a29006dc79edefcc0c398a374101ba7117f09fecb69ba27d0c966e00d8ede23a54b6ec467b18e08029ac02949e6765a5e67feaf0968b85444b95f0fa0118229475b34233bedc93bd7183ea23b540e8cae9bb13dc879f530804657d3535422eb6e3567fb73fe7afa6b71a825e26f00cd5748b81385e2de219fc6d9283230117b32f9561a2c1ddecb93ee97e54fcf5566a22363d8fef96e517124092b5fd04d4c59a74424ecd5e68c645ce68840c934bd4322501665a426e081088dfd37d650a5eecb088761f1972b8f31e82c93892906df4791034390259aa81ebfc1b4e2044221dce56069c8f7276e96e3f0a0beb2858aaf772a0767641cf61514b0fa3246215cc0e26f0b1f1ad4a9c951c757a29d3066c12be9fe9722690d77df944499c653ce81b40c065980c83bef82b0dd4ffba464b47d0d9b6de2da8256e9010e3aea932ca09a4a0e39011f4edd47c33cc0d11de2e4ba4f8851a6e5c6e3dbc8c1289981763867a97cd04189a3690da2b4b892bc6d7895642ab93bf2674e1a037ab6609b83a34122c9b11d1bc678f1933dcc090cf9d07984bd9338e68d886cb4b55181d17ded86906abff2d1424859dab2442a8136ceea9ac02a8a9904c5eda2b515931dbf1964418f3edfe51c2296334d946d9aadd052ee1bc890f8617f34469f86dad8c58e62c5e0ff3472a0486919a693417186d183fa935c947598ac9030ab8f1a14d8e47e10b6838df3219810e390c7e1b90870cba0e3cd9f38486dca6b811119835e7c0ca608d405f1344bdb5457f84902c06f77b11f382b67273245c1640dc4f0c2cdd548319d18220eafccd10e1c99d4ea8b91cc3df025ed7d3f151ab1a031e637132c5eeee196202c928dfd3d94788773ff8af5e113491f7ee71d66790098299fef65bba6bed13e894e16036f70b40e6169788b2f2b51898253dac0050e74ed2dee8b39d70f793eea19f017fda53b9700d82ee9a968b399c175e5e4dd8297b93178f22c3b97282de573c0600867fc12218321f4b0dcba39f0afc577ae75ce77c8df1ca8ff45ac131d625d63295d394242237b18796cdff7c1033c1034ae8176a88c289dfacdd21b941fc3b6929baec2e0d7313a6deaa68ebf60512da418e8e444a60edbb6c61850337247ac7315c5ccf0c4ed9b5d6a4eaa7503110a7a7719617056e772654ccb46fa0d9e1445064681ccf815602b9283dfc71cfd381aa4c0962615f8a82501c21beaa526abf4b3a3aca14b6796db1e2daadedbcd7bf483a26abf0f5fe422f1b728b14a0fd6b8e041540c667b791aa8299e701f5362441d9c2e0d934fbf5dbf0f184bd7fc42e3480cdd05ce792306494fd8a1524b4fcf356491acc84570235995eb98401bb06da9d235c7cba03284a028c54307fabb503286e93f2ec0f4e0beb73b65e73c4444b9a10bee3c1807fa87e0c721771906b8d7446404356b79b14dbbed28b0b6ac2a3a0566725ebef101816cf8044f5034b71000f030b77d739d1ee4b63474cc7c1ac1646704ec8b125eb7808b48c20adc8a44baa88d341c520fcec46b9aea0a60288727cb72ca717aa10bbbdb09e4ea58c9f221717af5af310c386a51924f94cd3e8170816e884faa8a3d37dcf9d3fc00e63cc13ff463d7b486a73dba226cdeb096910afa043d86b2f8306af048cebb0a5000ca89383b782e472c2d5f0c8738061995ae9f9f6b0cd3f490ef54ddddc266172073b2ea3254401e4b2ebdc7ddeb0317a8eeced16610d1f9595ddc5fc56226fd82288b7d1100435d369883c1032ea845450fb2c0d8dcee865951459ef00f9ff0a36ebd6be51a30146758b23df359d1cd3176ee58a633133adad4692222b85555bf3c312316620526309c9d96bb86d6c154d2f9c7d7c4d374e27398b54f1b355dfcb817be00afad7ebf52156d344fca59c7ec105f9a542195a5e3aa3bf8d51658b75d5f20b3383acf8f8872d43788d056a7edba96448d4d8e1263dc8bfded247501cfe4c6970ccca5468fd406d0b355893d2d2a0aabb3ee944a837be34582bdca40306de10ec956694716a870bcb00a6c5e9d6c9f5b0860074741afc1e983ecc1ac4ffb5cdc315fb0385228ac81078771be64a4ff954fea57bd99124597a98cc3a05db00175d5b39d5c40f9b34e6b373fdb74104de34923d793631b0af383b58e7949b546062c9b4b6eaecbdac0577f15a55f6ec4d193ce3c49379713ce8b8dfebcd2fcd56ea0643076e6c8635b37b03f19a70393d3bad6477dce9092a36492d4e4e51cc8ba8eb41ef44fbfcd5827e1bd2fe1adeb60c1d78a0e3c2307b292e8aa0adc0e4c0e70699a18b32666376c998e7b2230279020a6c7a2c5d0e4fe9d3bcedc8f6a4d977d31962328133ad50162314c086df21a986593685fd3d346674c84e595dd1419063a637a1ef74cc138d80da7235cf7d0517bff4b3dacf1394398a1157cd6f7a9e220c00d0834f7fffdde2189037509d4945fb818af4abf99ccdc7e26b6313be2236b26d084838ac9a3235d2f77c30d9875650b0cfbf366327f15f6fd85367f55043620f64e9c4b8ff4a2ac4879c7416d565435f6538f47847d1c668f3e48c9affe824780cad883871d6db8436c61ef8c60a0dc42130a1613141b5bccfb84f2f2a31585cf4b98bb76f545b4c8b7b09df8974bd1ac3232ba81f1823ffff1a82cc55fff0255dc3e66c9e2580f48525a21bdbeebd87bb03c1edc1243d7b4d30c62351e440723fa8d187ada9965e9ee528252eb2533436b180f94f023b9ed6164a047c0a54b72375bd9cd7e89b35f9a01948d3a028e71f4f4d650d7b98738ef87fa21dfad9b939e9888b2c21cfeb4ff5b7a708b653e01fd81f266f7bec2808bd9b2bb91bb2ce9a3f21d339a9ee528939bf5b26f3c4beda746500712aef710674909721f20d05b052ca181ec26814623cee001818ea58d05e730c801a0e340b21880c03c3fc03a73f0297f04f8ceab9d55831bd0a22b714b07c4b0b95f0edc1d4f385057604df9c2c1b84af299c9e6f233b21ab3233fa986c0263868088c4e7842d86e12ec66da9703011281f090472d81067539c0bef519c3f10f1cead3bdc3adbc1c50be16d072e0df4b67eb43696af6d516dd26540d44f3ddfc7498813492fb73b40e81b82cbc1cb0cb9547e9e4035043879506debca1e64b5347a4167500b27280ec3ecc75b1173a9a032bf3f10a79e990dee7cdb036a83ccbe0417a1cf1a84d8aa41d9260948d681d6ad854413fcc68ddcf6be900ae40d0ccc03b408904af5ca3dbd24c90aadf456db7c4703acb924506dd4b3cb13f85cb7be45d502cc67b175b3a851c038739da0302d7813d98e287877ffe2efc0cd6804787e3fc2dc6d87d77359defb8f1fecc337c062ef8f5ff2b84bf4482161b88a947068226ddfcc461c9e67795be396302c2fc4dd171cb1c6d051b95fdcc5e791fa9113014228008e6426b60b01b3f3804d50fabed00ca16e15fae99d3ab5b897f7350e9b8edeb7f4e6829a3838c6005aba2e434c4f571da6c42a36d62b28eb7d1aad1e3f8d65e9185e2b6d3420c61af20aec8153ee92bf0ed2e911f085c1cf6e1ade1dc280b07e14afa24c34b0494fdb6c4dc66140dface9cde77485f5a11fc12b97fb015e049280cbff892d70abe3e7cadfc2642b16204da49b2d20e0a49e8d941bf26dea3cd7944ac554d77e444d7e388966f49317c2046a49383c13c9f6763626c2b7d592f6e992c4a2823b1e45b5038400f51a9470e5a6196170c505e020fb0e38ec16fa5d87d130568aa03b87f0d6457c68b1e8e16665e1ed64039ee4b41d41eae61182ffa6ceb7b1c12d08d21111addc07d8c21c9a57aa842af6166ca5587642fb8cbbd66213df46e6542f287388c8796d58aa3d556e56b20fd426bad8dc429f1125c6ce07fa21528a6205a795801878725b0fb9e6f5b87f1f01ccf97f6de6dcda2f94349d1319acb81c98629790ee3155b0f16c0f8d2b5945b40d14e5f13791ec209120a9c1ece1c667723291beecd5fdd2987dc5d391e670ff8a9c628570541842e70b2d321b6ef5904eb4f084dc5bdfe524633b52d7d9653099f38c2307571e039c5ca81f126599f050f0d675b9133b8c81d72723da5c8501446610aa90e4a5ef0b2e3027631739184b0648f3098b30608001b99317474b115617408eeefae79fd0884a8fce80a8f15a00f0fe5a187ac37543e3235c55a1503b5b7c0039cc12cbe3edbee3930ad3877fa54e946bbd3de86b5c8f846d5b53ea22e58bdf6c143167f250f334cd66fec9bf2c9dcb56c498c0c71eaa139c89bca137a18dfeb9b20fc72f4bc61f9b22cff1411beb698a790c572a311182187be37e3d4b0079bb02ee193c0b610d0d91921a74a4197fbf78b86e069178e7db87107e89bf5b10b6349ca7fe8e24be66bf954375e052b6be6992d5bf404a0adbc55019448a29c881a578ed96828e3cd0e613f89db1a4757866b3cd78eff24f942630a326e1a07012b1fecac3b67de51fc8647eae12c85072e20d4e6b8c13474dc37971d4a73f3646dd450d6b75092d3c27c976310378863e7056347736c9ad7f28c1b1030d1a357d4bdc6266bd9510c6cb2fbc1717ce5ee7c5d6b08ff820eb25778e2c8e9ae63ea6f7defced03e57936891238c313b18a04934041c5449b0714f8d115d7fefc799838f6f6e14d425c2e79e4e9aa7c453bc1932b9f1b3d1fa9ae83490b877dd054f9f81825406dfbff817a780b1e47be500d2bb2c7d0f5e8b98a9fc61b3f061d679a3b8ae42c4b81f1504c961b266a048168d70a48f776f037b0e75d891b9850a9e1e83462cd7841725e5054e91a5108e1980c96936b1d160cd64a3b27a4f8d23d342d180da253d18fa351a559eb9ff6f1e128007f354ba5935364d3a0c4f46c52d49a980df99a81fc41671d1c2a964bf1e2eeec630c22961e5ffcd5be628e49410ab73e4d7655f2034cb05706d5effec00c329b1aa935d9f95645298744dc3b0bc2c1f41a4ab2d9764028e2908b13a368d1c7656dd2a887309a4c856012aacb904d21ac794d815578d4ab0a5c342bf1cddd9509667563b394a6c9b6ddc56908edaf108e1643c6a9be38f1bf151ff6a8bc0b84b98f7af4d9c63eefc38a5fd6b746b733b59b65a5205939ea838c4abb91a9d931e3a805eba2aca64863870b5af0cf67485d218f336f4dfb4344079819249b7922bfee920808d9c5d159aedcc4ba4f21ec6d8489b73d38d474bad9e1d9f751867d67e4cce5815fc8afe6f2b384a9139c383259cc129659ed910e1f4dd6fde5e2883b1b90ff34cb8740786ad108433e131aa5b5d971e534a4636ccce2ff11833e1e2cfc9638508dbe828409e09070a7dd78b79384c307e6972e42ffa1107a68744b91236759115635400ec2fae79fd904ea8011670f2686d812e5d3c002aa62fd00cacc8a2781236e844a7728790df0dcd784c6592ceb95083183a359d57f312a042f56c854a40c97374b933be9501d39dc56c3c2c924c7a46ecc760944f7ddaf64f8faae7b7a0225119691bccf4077f1457f0b5fd50224d25f1d3325a8da055c3f98017a3a2029e0dcb8e07ce255b05a4f2cfa727fd9bfabf58711613e4e565a87bac19b2fcdb03a71961a57e1fd50cb685a6ce84da5774c297f24f493147459ac1facae33526814163c984a6266664ba6cc29d209afa8aa5ef3894ef17f23809472d204f8145fbcebbd259a6c6db5f56eb2686755d61bb3187698bd7c89f39d665281509609abacdd3259710b4625ce01a5deeb768062353cb59d9c1b5943d975f05724157dcd575581875c8a8d08957ab7d20e02e9e1cea51d599cbede813260719e35e092b1fef8247e5e3408c5b9751cb027d35ac3612fa96eafb1d62922ed049b0715c7db6585d56ea03e493977ef16969338569f91e30f31ddc48745ab93e4bf1a82932d421bb854721a5a1cecad2301461f96f573ef50382be4fab1aa67b0b23c4d14847e4a5bb078c0187aaf84e7905cac1b446f3d5b554b18461bac85c0006f3a822b7a81a8a43b0f4ed970f51480ac23eb32b566f2ba6b991e591f736e97d2a3185e4c658e718312d594c9788d28da9a5add215ff6001dd45cb25bd028f690a64048d85e47d0b7272e7acee7a739f6c4c8dd17ecc460ef0c452d9a269895fde28800a5fe7c9d522417a0b0926d3d8187ba0a88f49441cc7b2fda2857ad6bc51662a8fe9e8ade0cade635840389a44c1f9f6ea3ed37a44d14a20a463b49c9b682a5546b841b48ea6418f973eeef3cc43bdc8309011e3cc1b089723cd642750f8c8dfacaa41fcd0574fb2d138af1647727f164a91eb597fc54f1f261f6f014b059d2cad79c86b2acce4af19bc91064d73c88337a7bf8f2f7698cf61588a57df1e052159e9ab7bf92f2e90b295ee4f25136fa61ddddda74b0864e23d31e3646c4afdfc1c622df19dd2d6a6f03ba8d46b7b271d2c85934ac635bc9556ccd5002dbb52f72364a8182ff33e42a5e6f6fccd54b2ae298b4a0f370074c71c6cf30ba7544580ea207718257fa23a06ff502986f6eb56d3941ecb6065cc51b52c32ff5f477ee3abbd22e896b59446d99a15ee722e55c9b34a07d3cf5b14e8cf3acc9c6d1c8a1eec660956ecebe8292d21e08f1fdaa59f3a17f29d71ee675346ae9c3db7f5943318915d0a41fff4c883f0a8bbc04e97b2f9b686742023d33627d90cf3dcd26dc83e8af4d3385d8efd999cbf6d474923f2583f4b2c84058e40ae2a31793b55da6df0329f65b709092351ec72e9e1b82b69a09d0daed5bbf576386f72d48c971c19644b332a76c1df462cd2c8f14fcc7486aae514fb985ef52c81118a2cd210472f85d825b3674b95bbd0b460d1405773d4cc14389d2edf5273199cde313259d18f3266c3034d1c4c6b009cd5d5dc2b937f0e9b9fb331a965eeba8024572493d66dec37d752efb4491514c2f74768ac21b9b60ed3532687bc3eb9d070df79dc0cbceb52b72c158aa2bc9cc2a0ff6338a0b341194134c9657c6b5d1b2307fbd4d59b62449395e2f51637b22bf5a7aab5642de92920ad5a8c2590be427f68052da9ad186d97ca26d8d6f3e49a2b9c8667a017cc0900415e7764d8e1e52fa9638e7e05edfefc355306cf19844db32e5082dcbc28a41734f8d0fcebe1d0bfd4c07dcd4fbf0c8b1da83616dffb32e234753d6797a4387db1af970634ec01376612607ff512e6d690d010178b7d3fdc94f43cbd5c6b4dcfcbe481e2b563725a691de3a76c8e721feaabe1f075e4db4be7aac2f75e08f37845d356f425861f69194a551f50750299cce7634c60e0c4824da124b4158ea02ff1f5e15159332ebc7386a9e02ee6858221e9eeb502f3ef701a7ec03eb857971e93f098990bb9f3e3c2e509099adc6c1e73ca852ff32594f28b4a48d5d729a822b3f12d3ed0bad06bd706058ce82a384572e3a86d9ff9834dd2a0e13b2ae0d0e80be0a255a93bf9ef905393117b3d62da18933c1e813b5784548fba1a64821aa5f508273209c95efa0f2cd33880bee4ef01a3a116402f0df411566d5a0e12abef4d386025127a8f45a140e77a38267f85ee85e82512f7126421e78abc1a63440dc2d10a92677e03e9dafca07cb162edeb4b12c3c6b4b357266244cd41f5410fb334bd0d0475e177d2645417e3a325dd4edbeaff9a0794b4bb45af4786b2370fda3912facfb69a7b45dd3c02a3352ee73d119155f2b388ebaea76f4fa69c824be35291ed42ec6ed84b918f500bc56c1a4523f861bd9269c1119f5c8849ef9cb8cd9d001f38407e99266543c9098c0c2a50ebd9f245f00020f44ce1db365aac3e64f440f308090e3b4aa09680111aebfd0b16907f1044aaf51cd1435759ce7c864908c524ff1485e4379fcd3c081bdd63851bdd7c30baad9bfbc329fba9c27855c4b8d4868a92743dbec8023e1a9740fd00cf607585d824c8c6f15215b7017a431e6f4c7f502b6f72372cd3c9d9d0d9c0b6c8bc5f39de6492315e1251c9308f3187dd96a867f54751e1df22a9265d5e9647bd438a7e25c394fab524714c9fcc4fb591ba5eb58a3bd5de98e7d8028cac36b9f65a2df264cc66f473552961f30b1841bcd5d18d9eec99d14196cec778b209f1033432ebee00bde0fdf88c50ef272708e64b7fe6e7b51143563350d5945846585e5f3f9541ebd97fbbfba818e44250870d46ce37b535b0dc453c1d2274bec2583910e34d0fd9432dbad5d9d4f742f9c2145fb828418c821a32365faff9cecd262ef4b78f38f1deb4fe1417689e40a4aa7fdc3343004042224eb91feeccf8f0f2d1217a4c943d9ea3fb95064ec34b9898d8f3c2b15e4992479eb8c75d45daa2319820d4bd2184acbadf455c52a64015ead04dc2ebb62c6570b2694346d5032498035abc7e8d5920d2324e078dbb6d39ca0f1d53b47706acceb021935b9ada3fa3f08de17f035b3694035084eae39e526a230a9c59351d00001801ee0e038145ff1a723a49f1fda2c40544ad6c84789756611125fe431eb5bdf7cab6b74c49a6c308c508a708930648fca401979f1ec4c94f1f32a108fd9cf3b503cacd4724221b35e1ca0cacc4c195f664c2c568b319e3d9a797a64fece7741762d83659820c9a3c3b27590245892e4430c144cb0e0b003566d0c50aa01015210412473041a28183e130e1e9912dde58c38c1d98a881b11aeb8b5d258a1430000210a64cb1f256c084172eb44a5c3a5358c4e08acdd2982b31e8e1d2c32cc7f6a3a0439d4faa4f95e79ba710e47356e97089290c8961f371abfc36bb38838d1f49f80d064674c68f417e23a28d7ed6d191939fdfdc07a7d68cdfbc6647a39521dd1b3e26c1c0f96471086f5ea8b18448090a5c90c36201820d1948e9e1072c2f94c5cd379c202e2e2723012b8a46a7800f6c5c71840f67709962b579905625f909420b7e2032020c1797d5e6beb9b8f994e962a94460b5acab34978e45f9b183be3f2d683ff69016dd5ebe6b424ef33f6e84114e5c6b54cfd93d3d2ce230aa41b17b7ae79ba77b98f8760030a92dfad844ed6309c8496cd47494180a80d21fe176b75a35573cddafcd29e2d40a69c1c4b7b3174ed17c3bd7bae85b8726881a9342d8db278b53d27b046fe75aab7e78fbd46155ff048d4d03a9623624aaddf366667af408432040fe841ff9845fa95ac9272e922534cc871075c4912eb9d35d336aef187710a748de912848bd115cba046215ce28637236ca2149b399913d5cdad0a81ee5920f801b6155e852498cbb081ee4e5ccc4a314fe702ee2c2918663291cbd261c451b9cef700c6243c7ba86e1483bf7c2b19ec2118761a28b617b38963817210c01e53ec2b1ba299445402a45cdc470b62c7291ab67291cebdce9355c441316f5fc5cf2b3c9587a01f88f988e5561184c3806f92286a373f9e95ec7ba8ed170a473d2f6114eb2d6a8295973ba42def145165eb430e257480b9def676cb8c8c2d5034fcb0421a0f61502a2e25708a8c96f872c78bf7d9016643773c10155fa3bb3e2c426c7ef8c0c2e93158391905533304a3a8d464454545463addcd97fa9d2914c4005155248a1a6c6878f8e8151ccacc627d7778645adcb3046790656a56f10be5d1b7caf7fc1424b45ae516969d249e9dc972ef8a2c21453428051b163a888973da4d451c23c6ebcac91a0138ec2b297ce33d84baec245ce5e24eba5776b8a973ca4ac2ea58c94deb11d5efed851685ba414c2a2c9f717297df6c849a594524a295f3e3c2465cb7a365912fc1cbe477c8e1c4eaf58e373780d89488e3afa1aa72111a959e169ac903d8dcf9088d05013ac665c864464865291119291f1c92903bccc8fcecbfc5879192f59f1c4cbf876f1325eeb8fe0c7c45421f4312f68e263aae8e1631c864424a604e3241211181215533cc9411211d20793fde71e89c8d7117dd7d120530c5185b8e08964fd2cc105433cf39439a44c0f28e5707cb8d9361fbfd990d0021e2c2d58a389124dd690620b1c264a51b431c212334a3da3e062dbb624be6c3225e70a6244e10314dc0fbe76fe80044f3464604a0f94fc4e71e34b09bf53dc08fa21fd35b83f1dfc40ff26027c683be5c67c78e40c224b0b38a8edfbd3885f21265e5ee8891f4e4927734a120b72ce761b14541d16b9c52273acbd618ea8514498d471f28a7d22f163bb787e943522541288874660b3b85b43dd3b542c8a3d8b97b127cfb299d0b38fc2510e6179492be3d9bf89c615341ed7b8b4263f72a3bc0a2aa490c2b834aef971694c1b2033f6ceab8680e16a06759c63c7da87ea33487bfef4040a27ac0775fa287f292df5111b46b2b7156050bc9edbb5053669ed6a9edef926ecfb268c5507e0d4ce389565f62c674ccef8713a799e3226433fce2a73e8796e99cdfdd0aea14fa02fa985b11d04f23f1f79536f57ab28adb554f27cf409733df7c98415d4716930ef8867a7e102487af6f4239c92e1ca19432fb082071da8acda4babd24017257cb0e4f003295856edbb74dda78ea3299e9d8613289c309691c015436d9441a5cb8f134672c0ae749062c4e1dbdbd528f60924c5e636b3297b66186ad8bcc3f903635156371f27cc04c356434f2a8301adb7fbe05487315060cf3e63ec53d6ec13d6eca54f8a60064e73bb23eabbbba7111dd123b347b343504a25c014fcc58928282842014bf6c50096d07880d180cc79a465170b9032255c831ba46c9fc736e736bd4ff257cec92406c0f3c46900bc94e5f88df536e73625cba9f3f1eeb6bccc37c89f7ea4bf8b6f5d4e8e9b1cc7c2fc3dedcf1fea48c24b975e0207f19b70dc705220617338972b724acee66ede4ebb35f8ead65ddf215f5d55922c54000bc28aeb07275424d1e16583177469c20729bef8afee7a69d777d7e9ae2f024a44c0bc5e4031422f2daff344ec16507458411b30255d34812ac232b4c314498cb145942fb1d70f16f0ec0036f1438b2d4c0b4845456ff0bc81450b60563b61f8e470051a5e9854a00b1762b091c51238782326f4f2d159a2d342092de1448e5c4eb9494ec6c0fc521e5eb7424b04f1369a5e474fcc2d9dfbf9331c25cb288494181a51aee7a643951fe5f0fa112d6134b9f66d341a391dcda7dc367bd2706ca741b57f7f8ed4472165b1b2c85d43fbfc1adac1a6e0de909e3ba6b2c8c2ac8ea3d15cc1cc7f523e4bdf17d8393c02be34bd70a4e697c524dfcce277687aa1c759d31dce2453ce1cbeef64039900d706a007233b1d4ddeb66d93b4ef6596fcbedceddcede3dc86746fa7111c8d7c1b85f4c4f237003e171e017fe57f5c4f22db089ca7b1fbf500b85103e046958efaa5f9f596657333b07bce39e7dc36d6960cf06ed116c9961796456d54da1998ce73899c869fdeb43158b2ec3927ed64f66634ea1625c301b9a8910c77473e6a39b76d1b6d73e3e6fc7677a5dceed136b76dab340141b0ce7b60fe043ba456aaf4cdf54df9d6d7e69793b455d15d29a594bb12fc51943b924706c04b5df745ed0cdfbeb4545a4ac377873c8d90dcfcb455232a653843a3816f6f51331bf8f645d19fbe1b085aeecdc626f8e6b669038bb3f6539ec69a97dddd2d65ef72733208262005f5842a75baf409f694bdde1194bbc14ee3044901278520b346adcc0817bc603c53f8e8c0c323459703a98d3af32b9444104c0baa8fdfd99516d0352acdefec0a0fcdef8c8c1d9a68c91c5b64869c9c134ea76e192e44ed4dfb0ce9de340a5454ee81e226c7dc33ec8c0452b51202abda1dc1e6506f2fd2aacebb6777aff1bd687880ce6aa9f445c4d0b283910cdbc6791156a150640392deda3737db271543e77b4e4a6b955f4452e994086a6f7e04e4db51b0a24adf4e9d0f612c52b87086bd81a2ee0fb5f396616fe4ee6c77490ee8bc130c928b9f4956df926098cef976aa6186a69169141a617fa2c6ec6fe8df40207f734eca7e3b49d9cfd37ee730697cecf3bf250de9ef5bd20af9a18e7c0520eac82d2a366773390a21845269eee4b6dbc2f66597774038e70475acd5f7d7a643cae28e209852b640f75b2a31b750cb2d198efb644915c82fea64005ae51e6eb1cb8a217b23d7029b236538ae9656ab552c864449d722d9a83179c958f646b692d66151eabc6ce656bbbe14cca2672c3f4f805f212c27f8fef99d036bbb29520681a8a4a58af1130a6e159d3e9bb379e9c9b6b2a0627150aa75bfa355c7aeb13210ae00441dbbd6b556b1368789cdd141e6d084547514123587789ef970c2093939acaeb1ba06454b8dda85e312c9718924375a2279c4e66c196814155236416913955c68d4b7a355a794cd91ecd3cdead9c5aa5ce8299bb303996a36a4c8ce38d052c700e3b907db831fbbc63e2db4020f6a2b9c92d6aa1d258d5bad12c552d8612b0ba98554511ad4294fe5d9470e7940b2cfdeb0cf399784580a6659a0f87132cf9dbbbb3e9bd3fd536e611f06e22d7e675312cd50d2a449ca1aab4690cd9a4dba365db367a6464973716abfc0a2c3a9e9c67ce347b077ba256d73da9987b00041e105553a936698e9a2aecf7451a5b703a07021841058f449894693ed5819ab55930a15636a79f65662be264fa36a7bc3d3a77db0287696c96225201f9f37be87c92e6e491fb9d5a77e1d16794a993c3ed46eb17addb4c3323c4eddaf537a42ced2e017480e4bd91c4969e52952b5bc039992252ddfc33c78cd4f04ade22912c54e8525861142cf52647ca8395dea086447abbea47cc9d7ab26c3e66c498a015ed64c78e9389b53abc9da5c9735562d1616b394704a72797e31edbb12841fd935c6971fb9875fec3357cec6f032dd10ba427b96af8ec0ac3a906eef10b537eb459e0ca4a4a1f32b850c2fbfe3570a1962306139517b76f0849f988e549b684157b8c271968eb876b9b2566144a2382ee0a410c3b6a9c0a9cdb7060b1870e91e444133eedae1eac98f9fe0c47b521dc8c46c5ea7d415bad2bad27acef7f3e80a5754aee39c25d1d06f3e5998dded9bfcedc5b90d9edbb89000466cf9d104cff90bfc1c052917d6d44a4944b8e60a2e5c469c8f5a5d212b425666cff96e3e2cb6365816b0df5eb009b1e2e6333b709cd7cd5915e81c8c7462d6c6aebdd97c098b1b89591b0b582aebb58455a06f1b9193dfa2d48236975998e516e62d0bab76b5e5372ebfa5b6d4540cea287960cdcca27586632d719c9c6dce31ac0056ea0df44d9c27792e943ff22b34b15c6dce4db6b925eee4a3c4acde1c8a16159c05cfb7361e7eedcd2667b4cd25911c12620dfd4af9156205f14b225244fa340a4a1df9d5f9e633039da7073ca5e0a83e2993e7791e3bc7543b2516c717091362e9f06cdbb66d9b7bcc711ce700d04dcee2e672652a22574956314f1c0c5952b6323d0007134e90d02403031c3e0d71a1519bcbc060639b7f27234558dc7626797adbfcfbf8fbbccf6320f450c4cccc3316ab70a7ee3575b8b62dc64112c6dc8481989939ded9179dcde5cf9c7372a11c5a3da92b64e5e739eec479ce79a08ffc9a81c5cde76902431cfb7021bf90d0105b91dc6483081a55049e482e49111021b622392904432472053a78cac08906169786420efbe01239e394c9f3fdce379f277e710e1a1574ef24bb530c14160e41625481e5500617363080850a8896803df1c197d526058d339ab08896f8e18bd5f6b2828d2982b0831b5be2586d3e4fe029e6492b872a874666c9ec505750ea0a59e1798e619b33d0e6fc621f3f22cb9847388e2b4261cab736d2870a9c9a511451a554e9a47616b0540fcca72ccaa13ad990a2a48bef709cbf030875a452accb2ddd1015fc15b2e20351f57e85acb0b69f679f20534a9dfad031658105eb7c928874555e3ec85aa39656e12112c750a396ee500195c10885e1032c75fb150ac30bce8edfd90d54b0d31c6fbccddcf267f3c86d2b31c7736339674b6e96f2934cd94b30404a2a322ab2a522a322b3b1791b9faf8423aa646729c3b79c1ac7c9bf3da5e4810b2eb808615cccf9c352d6d439431fa5d2732a129127e4b6cb280e4f566a50a55cee2c4a41c2c8e22d901f6baaa0f1eddd5ec3a8a2c4ac203f8499a8d2f2e1f169d580b79b9f4ffdfd4ba2637ced6bb3b5e5162f9fc1a6cd62162cf701f99c7327f9cffa6db9246c6833d291be94cb39fb9c7d8a40151bc7cdca22e8aaeb236d2a351500a94007182e236446b44e547c888a908d20142bc2b5332480d910114544b44428ca32044cb4416b88961034ee8b97102cd76b052f805c4a82a885413250060db18c624b10b0141011a00b16105f80f8a6ec2871fde07229b02f4431b2a02018095c10f9d0e3436ba33eb6c0df2137d2a72c8e46bec9d168340ac7752edcf58daeafe710da9e526b273382a315a43c309e296628681c1a04278520420c356a2914201440040f164a86081aa24a6df2c38e1205ecec306a7fa495c4048472858b38b6da0d7260318b8338c6286e117c6e69ee98734e9a39e79039ca26347473ce39b7d973863047939bafb1ca988bbb5cdac1342a7ec1843470178e740b479c668521e5c2511842e8262f51496be7eeeeeeeeeed3c9634edc2ceeeeee6ea72177b708cd8a01807bb8e87fb2062f39f07dcbb26444e5367aca521155baecaef858aca70f52243b91ccb9f1b6bb93dbc2d24e95cedabe98bd6d1b770e2755fac7cde63979063854fa90b67043877c054df1e24712a260f1239fa391d71d7ee4a51a08fdc81d891fb9b805118e08b1d5b623cacbe74792fb615649e5cc4189d16e93c916716071460dd0106235d69e9f73ce86a0c1a1831222ce987d734e11941ec423119950e2383d7b47d5a8d27b4c1f3f6d7e92f0630a3fe712e017053f7dce18193f67ec8d9f4f641f6e5ae7bcc354685a2449562419667b631a79d7ce8d42df508688c53dadd720e0e70a3f717ea66a3667daec0d4a56c7b6f939f62fe194cf9cd39bce09fa602a7b43677b434313f56ee41c0d4d23ceb9cd6652d601137bafab49aecb10c914c97891a9c97ce194e9f39d61cd38b1399dafe77c02a150cfe5a9961ae579cc933a5dedf9e4f17cb2daf3d9f27c466746c9ccce6fcfefcc925f9ff1f9f5f7bc1ef20b679715f27559aed52ace3de7669bf3b9e79cd0e650d99c18f77c16f51656edcaa3efe5f8baa8f1dec8e3f2de1c7aef2b6a54182b04e62547439c22b9e7a32c23daa8cae680eef92cc9aa570434baf25e0dc7529885abbde71c18abf25c63bc9783f7b834def3597b8fbee6ab55bb2a71ac5af3c6b935aec31f90c3778438ecf01cae23c4410a233b3c87e3a0c36b3cc7c9246b4e26194acf1122916247886487e770243ae6a9888e13f782e5e0f101e23cdf1ca75a73aa3b5313ce9952f5bc6ff69ed7c0f810961de8fc0b5be8ffdc73b58a546b94e7240fe62585907664099ec3bcc62e0ba768adaa711006ba4017e8fa6276254f359445aab50a06a64796c06aca6a52ad49b526d5de7375b5f7bc167dc99c3eda97e51b62f10be38a1260f855d91baf7dec581dab63c1bc607a62605e30afcfa1cb4b989ef7d6d379cf67ab555eadc47a4fae644e5eab519ec39c3c1d163d279d3c168b9e83a7eecbde784eda91423a206c099e7b5d1cef9176def31812cf7b0eba5a05f35a94e7a552ad0b03bade1b41d87b5e73fa688df26a94be5ad5bd1ae539a5b5bede739a27ea08f385f5b138e5b957f3fcd361158d7bfe296195e834a7203327a75576acf748309f375bad567db44679ee79f7da9cea9e7b3a9c8a71af7b79b5bdf162c22f0b8b5e8cb7c3a2e7f1b0e8794ce8b958f47cf46aef8d9eebbd22e9f97a5916c1d3ee0d6535a5b52eeb3dff4266c1c44c417c6b3302813de83ba2d946d5b81edc793007eb41ff72286111cce1aa79b520543dff28fd0124964015f8038851a0afff08da9b58a53ea25c557a11951f9ad8ab7be1a803f6a0eb80b1087268aa5e47683de83a7e58047d2cfdab5523077d44b91e6cfd58697c5a45d3923c53fb2e1c9da6d52a1a9f4681eed1b42a4deb419a170a33a8cbf936d2bc1e74b18c15699b231f74118d07778d07451f3ce83f683f8838551d74116873fa411f7f6c79f00797077f143de83227ea3f865a65922b24a0832ed2c4a2560d000b2037a69ca0091ed658812ed65a35440a2d0838d2b8c2082456a08b34d04522d07f008194d61afe007ad0d7060c6b0002a336a035e1f1a202a292cd3853f49d7f13a05cd8445bed3ba7b5277b701c0d7930198e52c2b400469531499771120b26e9db578731c91086ed6bf879cc100f0d3dbb07f360cf6104aaa82dfbd1bf8938d8e6b077ce51b139f23be7aad81c18ef7c236a557b27c36e2b82e3471829bcf8ce67ac5574d5f994712a6873a4779c7713e83b9fae56c5f834ca8a150202c91110a77678e72327a3588f7e364787efaae4535f3edf815a7ce7e3088befdc0bc1300bd7b817aceaa330a850bee3baa8c1c0bef34d364bb43ad45be71f3df170eeb4ed03783817e2208511ce37c7a187f3f0076c3870bef9ae4845746868029d3a0fe7a8f37023d4798426d0394fb23232da4213189a64e0e19c1be1e15c88440ad091f4701e0e869c6f9e64254ff287709146810e6eb52056f1f0968be3e9389fef3a992f5eb86ce1e1a34c96df7c94a9f21d0e3cbc87839bfb70d03f597dbeab3fdf15fd18236b221959ab7884750ba33aef6a3c422eb3efaa171959575a11ce39f7e13e600ffa928cf0084d4536dfbc87f7609f0763ba1849a4e44318001d6861679cc3167ac6470a9189224be89c656666adaab1d90773f2681fd08c4fab66668dea7c264896d079a9d41f50cff8f48c4fcff83c49a6a58e24d877ee435882df5085d526d587c5eac496d0797de28b6f48475897ec4de743588422eac83c0ffa0802cd6682e4cc0c269c09face613c528ce484539249449c7ce74dd4aa1819ed63644ff070d389146b54e7a513c9098b9def38918058ec5cc789f4b3379dcb44914248566c099d77242cbe9389c29f4546f69dd758ab66668beabc54aa35f62419ed3b8f91d11c517b7c43ad02871ad539a5b50e7de7344fd47166f69dc70401cd3835824331324e6d184bf47ce7315562b2702a87d71289b484e4d32a1e5e63df9180be731004817a87378948c99bb439db390a31a8a31f9b88c7a9c2863687e49de7e03d201f1c8a91ed4d579bb0d879108b9d0f6199222a69c662e73224c958ec7c8c917de742a8d491240b7a920f7de7e050ab7a78e7208d5339bc73700b48c4291aef1ce4c2a9ea9de9246b3b4eb28845761d27c90588d25a3fa0ef7a9c9c8413ce290516799ce4cc69c689bd09029e4ca093605cc62b189a603eefb42cc6f80a3fd4ce6976eab835da77448b82f10e666198d5238bde0b0b42b4d4960c9955b3391340210695fb25c1b80d304e0a7168fd6822b94c58c33ec2b587f198d3d83bdbc384265208c3f6a083a10c5177610d3345954f4d380b8bdb999959ce14b2b83a2af9b96d8e92db9d9022c0b199d1a941f90b285b586f500aa5a7c64bb40015e0420c2517e7afd0184cbc1db46c91c30da6942535ec0571e299c11a1f42578884c66822895d55f786a364fd9e40305fa8bfdebdcb05f822665dd59aabe97d325257b3ddf482f71d7620e69f988d6a148b0acf5462d1d0fea4b5746692680cd74cd658dc6a6ead71bf941ca6a393f2945877a335bdfc287be4924fe2e5cfd39de2832638a8e2c5172d44b023e1d43e89638767492467bcb20a8b2de4872afd0752e50089e29ccd8421190d72724e389d78f09021c439898d62399b15492636677f777757c4314186cdd948601c914516473d3a2559d5d0a18933cd212d65dfdbdc662f9d7df6ed7c0cb4393b3b4a432b8b15452f85db3d592a655968d7e54a180db476083f2e6da9c8b0373b5a55c218cbe6b437dda6fc0399a281452964e420bca46248e95aea0ea4f40fb62ed757061a38257d9a6ca1d384c7d99b752f06dfdac8954702a9022247a0ea02525ab9616bd9577cd84819c2091f3730b3582cd60d2ccb90476419738b1afc8431d9ca11127634e1658a2324948084118595d2d2bc30a2b0b234da2217f116239ae0a2a1146886bec8410a568e883c82ccf839226e10c9c98ccb060ddd30a22c16eb86510d0a47049d51638508cb1e1108aad2d749d24130a7ef3628493d89cc293f094bf9c3b74e65bbf7e4c1e5cfb94d706e345cd4edb9c2937e084ba29f253405be28112708151a51518dd572f1ec3a966fd9c7d7804f4fbb3761d7802379f0b17f2b7d7a92962f2c270143326337b0cc42ce522babc0b23ca7cf75498281553b84556ce27c75ba91ef6934811166ada877271e82ac462098bfb9e905f9fa6deb9049262e2c32f27d237545392eec40cc6fe113d4f7cae3fc1c25eb594f4f7b2241a3a613b9265cf98df14879e95f8ce4a16ebf319e282f5dcc516b96080121ca8fa5e7590273544e49e7223e29875a51e6ef502bf6352cbec1cc2e673f82d27793015994bfb199925f1b8e852114472cd4f1c9b004f8491e2aff0ac101f3097549e36b7cc0210b7ac2e5d16dc95cc85c3b87b367b773e11cc91ab31c174a6e379e64c424c7259c203139ddddeb6e1e9b3df450657e857e10f423cec80a905fa117d00f9c3cc162528423598a292cea384729b9e76699eed4bb8575cebf29e7b67b13df2a3d2c70e24a8d0656b4d1a304107490d881c9152992849dd92451c79dcdd0453687c74b37928241a5b3376e3bcc32011649446618c96598222c4adf5911233370188445c9399f4671149f36d75c73deeeb1407db41d117f6bfacc6deb93fe643105d59f06e919905e64868631c207b22126b102e4cc60354f52081e7ee0b392d1a2c436782f590671c3265f70168b05c6b73623c99592411d29159bc3f990944f96c54bff785824f2c697df01e294740ae3d40abdc1e5a5d31f4e3175f25d4461a9e6c2228cc5eda7842ab8fcace442c4a2c4d1f2fa62a34fece1178b92fef0b46a83491e7e6d30192f9502c1581462451d9ba8893865da18284d72c0ae244fa3383a9acd92c371e4437a14fb869ac2be59779feca5df38a934bf42352592f523fde16e6250c72f564423b5a41076e9241f98e7a58fdfa9b534ad687336d8de48ef3556b5c9c87434e8e5cfde489f42ac8a5ab1515eba84b128bb5498dc19f3541ed20f3aa8dfef9538582d6ca9f3f74a10befc4861ef9946beab8e564a6989ca28fd3658ab28158b929e05d093972ee5a584b56a5740b19732d811b1c6b1c1b6d826db601bd06e302534d63020920c72d5c1c035f0a97d396fa19d0b398e0b3720167f5894bf9dc20dc6a294e9a1ba498bda9fcfcbd3c8ad7fa273f13bef554737d8cbb9ea420afb622fa57fb36fe88b7d32924b8712baf50d254c5c4ed050f0a2073d4ef42c19a271a3c9929f25ae9817272ca0b12047a88d2039e27a6e4dc09e09d8cbb003a32f7f03bfe90597e158821fed0d8fe801bc4e7ad24772341a49399272240d7082c90406880af32bc4064d84dfd91b3c346354e9ebcc416acc86c3cb5a76c6629005590c5d1d3de10479c6c1c1d99c6d19b0317b5559a2f6e48b35684b5459e28422d8123c4b2c49a91145092f4acca07cc1832125809478d18006a0ebdc2075658050bc388ed26572f15a63321851804175bae034d2b8001c6db85a289869c1440f28612041841524da5863e53a004154d3618b1665ac469c2e39e0388a501734101005185ab0b1c3952a84ba087589753edb6e62a3d6413a7b8694456fd40acd6f9053fe1d7aa0fe689a7efa7df2a66d086f2719f6667d9e2afba067f5ca22dfb0fdd69b9c93e338ae86eb0092af3f4bd327e7dc0ddb6f21f8376c4986f0e6822e4a946829b153a34216988c175c9624912509d84cdde95ccf0e39aee9fa9873bd9a31eadc475deaf3e18593c5128b74ca11734d0f2ae8f33457dc7cb77d61feecf9bedd5d4a5784ee76f64d763719312855c0d145ac31a3cc0009182764745c0051fb7cb04589a30b49012ec4608353f2d2f62b9486cc0ba63e1eb1791552605106d941a5bf4269c49ef352b95fa134b4f88d288d178c4ea5ba3e8628c08518604085cafc0aa5d1c477bf42691cf1a3386363075cd250f22bb4832f7587d00e7492e849a225644ce205acf6ef8c0c344abf331c9c20071815c011a36e173fc07ea43ed028586b8c306bb5f9d6b0ce29699adcc9344316565bd80ac2382d4e5f6da3df5669c5fdb6ea6afb0d41d0ffc40836e74e2dbada9c494626c98864b18c6c6cb55c9bdb36a7747738a707b693142dec6f1755ae428043d17881f136df2498b1e50370060abecf10e39ba8c9b78b68e8e0a8be2c2b5ac6a4bb672471838ef339d613e7e3a4cdcc2c033388d0418be338cec9739cbb1003c771dc1682e1dc17b7d09e594557b5b665d6d3430b400e887aa2f4f86cf1852a072c24908821a08c2f5ab428a179af47193b2ba0ad805551b1fffca32018b29e759e6b8a9e6bbeb0c8ac67d7f3a8e3f5ece2cc45e39a1167cfeced343cad9aa9358a279f3a1c6960fff9e733b556d1f034eaf3aff3666affb91af579de8d34aefffc870fa5b5fef0f94f004dfe137dfef3b5f9c21a50b129c587420ceaf64b43e7cebea4223a9d7b4e7a180f7c407e3ba525772969d8e1a503418ba02531a3e38dbc3b7dd3797a73e1686adfc7a1f59c6fa351686a9f5c386ea169ce1086eddbb79f6f6dc6ce8656c955d7755de71d9bdeb2e90d9bde40b4c872fdd3405cd830eaa23c9cfb68a39a382c02fa7e8729e9a58e22ed3b3fc98052ac255174df50c64b9d813219e9a421d8d7a6ee86b14af2008b32eb2c4e7a0bd3b6fcd84e7e7a45597e307da9fcd8557eced9443fbdb985716a4e375cde3f4259a2fc741a36d04f87f9e97249e5bcc319168b52d640178b3b3f37252ccef96ad4b4418896f52c2c2eedb73bd5b03ef2cf04454d22b29b8f42133be7a71ab6f008d77e9d6bbf91886c68e251ed27d56171b6ba168b93eef050178b93468a3a8e5edfe97442a8d4f6756ef4f2d14665ef6fb4631aed8c1ceca70fe8f3d520785a12f5c2e2749e1c10871cccf5b3d3f9e9230773805c81e17c753a5b0c09c9617c91c8f88cef4c2c26e375661da8552623310eae832793119287401b9abe2f34edb248c7868d1bedb7a29fb056813e8b7edc589fb9a8746db4964d0b15a20104000000b314002030100c08854281482822d635493d14800a7d98427658990b646914c328c818430c2100004000008600903234355500f3286c3ea8574f59b196ee75747429fa134e1b9db931a41485e1712d42c927badc9f0c8424232a0fa2dc62203bbfe7998d2243094f272a40134727a01ea60c0ee838a2f30e1a96d06d4f76ead125dd40484742e9183a061a6dac53b5401f15facda12b7f5ca68c8da14b7f20db8fa5520ee870af31502d2821d2fa145dd6036d5363e39e4b7960036b1bf4c8d0b3088a38a89df2d4c1496cab1a74f4c2f74d028f8a182763d9d0b85cf7aa0fa156dea69a7bd7026edb5c65a24de44c71080e13c8f2844c4fadc9a2adc4b6d5d5d90d2ecd1096889b105eed1e48c1ea0c28647b6bb4aad974f4f1d257d270188478cf0790357fb5bec5d80877581f34721982589e96dea2d5e555a31b30752d05073a6046f432f51930ddae8681cd6f10d853227f3af1db8db3e92c6e6ed8dc024103d28d8fca5e3380c9edc392142f58ffd172f6d52d653bd83ca4d7a9d3f37e9aca76406cb463bdc935c82a01ea9f3a9ad4506ddd4e20aaef9d6ded1f26e00722145e8e85ad196ca1156136ca8fc78ace2ed39049082ab091da2194ada06bb9b06ea97235b8ab1e7529ccb08131d74f03e9c19327fce12176e0e5ee15ec61403f5ddca70c18aab9d2a3952fd1b0a42f80a4529d1d462235f5f983dd4c13beeb157fb76a7fa8d61a268e2f5105cfbb485754550567fd18956ae2cfcf37aa8039b568643948a1d49013df743e1175a9d4152cb028ee28804292a5eeb35a27fbe0b302b92fe6ebdc69a3e0b809bff7fbf718806e153514a32a92791cceff7d184c2be54d7a58b909e564593bdd913213bed085cb06b6744dc4ee6ca9c306d4e8b40b5c9dda19763722e0bad6a045573ba54c292703a5e6a471ce17a00fb21ed29e933776ff65cc73b61e09a56cd6fbe2f7ed6db320bc0564d4c352edd37cf52ddb9c532cb5169498c1c5f67404dd6e7635874edb2d5c578eb0abd6b8e9367c5f254a389b4f02712e2beb1068ff0d247b54110ac9997a2e76044452df765c81621a40afca8d624ea8e15c28bcb9de8aab5ed41eb5c56ba232561a726a80856dd35c8f8ba0da4e6454b64afdf85aaf3cf46b7f74d6e8dc94a451745392fbab2c365b92f2782c553cc2e4e2ca80df1665b99f9846c4847044815fd6da5ffdbae09c807b1f39b417fcab4debdb2d2e244fc7a31aef1366c7cbf924def74fbbc62999581668f890a1f28b0a9e338a098fe6d47ec74f4232691075e3eecfe42434ccffd082eb64ce28b411cd328b4cf53c75d334c563cf2c3875b371622ac30c3ffb47e248af8af8a8cbd24f6d757a75d043c07cd468e70051c8a8713b63426e696061a84545b925e5e95261b69ee837194db9d750e36340c32c459bc3fdd69e3b2c0b4b65f0f4c6f867634dd0078614bae4b93eb6f1d873094b3240b91bc6ee3a0fc52f7c6262cd87704827afe09019e446b1c411502d5faa477b76a2178ec99add22c171ed85b511f902eec47282d003202b2416436f3bb04a113556e07c8c356aeb4410bc750acebbba3054247becc97c0b9c0c90b95818f75a31626262b5f65062175b538e70110ba4838b00563f931d2af5eea6d4abcd39e854d0892e4a585a6370a08ee6d8ba3ba403bd210a557747a534de67dab970c03de147f101340bdf049d9d10706c07fda4510836ace06c1cb30870bb6ce6a112fa8c24a911f4430a62547e185277658586255572208040ec64ece5a977f951cd66920c45f2416ff83e4dc5b7ce15e7a7a0b9b354885165a717b31e3fdfe7c430bdecab91d1b7457e142e9a08d6a5875735d2fd481d248dbb4bcd4cc71a8998311809f709264b35dce0073aa658c5c76394fc96c5f57c948976f0f31e18465cd8240153e2e4b1f18624761e4564d0595c32a7165c8d9204cf37d0d5f8abd49124ee3fe15b7220880e0e936036833722a6de67ee5f8b2e52cca8bb79638f08d8ae29afa6893d5557540b8acab2e4f87e63038979cee9fd84e421c104a1be9b789b3dd3a556548293e0b6a930fce95bc266d6422b716ebb1215c7d5b8241d8740fd74c5f10541c42e22b851507a642bf13814c9e7980a9985d8cd98c7b8ab4fcc2c149fa4675ec314fdfcf67eabd5c5b1c9f7b85d0f64886b231ddb7decd8e2c028035acbb5afbbb51304d66751d86a87a2c4da2f5eb3f09f84566afb86a94288e10fe56fd9edc91a5ca9980e0231a6e208bc9d1ca907008cbd2d010167b3bddfa6436ed581e9e99121d1085e92a469efcf5ca6d0f686ad2c59aaa6abf6bac8412395b894dcefb8643f2fce62b3ca3cca6df1c1b6f1ec6b9eca2a04384520905c1e73c5d5e7b87b88dbf76ae7675f19084657abefc66791550c8b5ae1900fa244139dff28204335e8355f96322e4d75b7833e6e5c25705d5cd96d2a5f4fe3442826a6173c6262c9f1cd6b4ff5731322570389b8ce8b417f5b4c0d0571e6e0bd24d825a17d1f3feafe21fe54468dd02b6f0e8e782c0c1777ff116a509a278989c912ca80f624128386a90fd44db316a3838e5cebb8af12c37028b1b555e2806c3fc586dff51734376147cc3b8e129edc4e4e6251411bf04813b50e8b06e74417d7820185ab967ef06fd39922f20b4f81b5209725f4727ccbc1525827feb02611c222e02d9e6803e980bbe02a5e2eb898318fb64c31d16c9c9bde6e024e55b2c51235c24b758434d0f4986700c92f337d087e70a6a0aad919734003ea5e3041fbb20d84c4ca57e5146970f1361e4f174a534b35fcbf589c248bf6f4ade052bb12435e7c7214d664fdf1f80a25bf2e133b0488f610a84f3ab2d11321a2617c90e92ba61013cb3826a8ebea6be22f20135fee0ef028fdc65051f24d7aa4fdaf51bf99f151bd49700d398c1f1497188f75eceaab7e049c5a7750e22a74a36f72b9e4cb27357182ac8600d2567a9ecd590701a575218247d0a736db06baa203418dd55907816e027471cee6dd2519d0e435fc332044603734df8f27b5bac628f964c38c1fc73744d2b23b25dafc7365121861ef14aee9f89402831ae5163cd329715a8ba93faae3e3a022b6af01dce18827118e1928165d8cd04ef415ceae8948b39a1790fbf5f1bffdc347c38fc16d52877b3af896dbfe8b8cfe9b50b58d483ea2e18819efd86ff8d6f16ce42011297b18c12e51c5625f7a7b6cae17f90f4b1db73e756a3269c22c0548f0562f0be096ac4a1d6b7bbf84ee6ab7eda2f86c1db513dbb194ebab833713b8554dddaebeba834edfed71c044d4f57ec1407ae6cd4542b0ce0afe34f9e31a6f3ba545b6916061b2ab62c5e650083ae8be70548bac2d240146cc27470321a2fce9e4d8119c97ffff0bbc75a79903d4df28d2e92b9209e5563682b11c4a16f0dcfb402e32a250469ddace2ecfd6469aa036ee292e5c2206e602f5e42959dcba8654e84f354b7ba4a2a940ee14153c61de61048bf42eab34e4b61f22cbedc17551268a32eea0c8f25ed0c226017d86f35f61f142e66196094c9545eb9464a9695b27be977aafbd6491b397243771cb9cbdfe88b9c9aaf693d4d8e291057c73541f4db43ad12d273071c7c225c1276d8c6484ec2800cf8bc45385d697c53d31dbf9225b6cef42745d24e089ec94f8d2446f0e27570dae0b78bd54f7bfdcc11801723921fe6b0812c776a2cc537e3983d106c57c0644d0772851fab2407a70a021d7f0f2f2a9762869cd198b67ce6b100e50cc403bce0d4b3b18a17187d2675df78293ea710100ceb6976e13351c9d6f8e989e90ac375fff39bceba3030518a6874ef213bc858ee482246d74844ff66402baa9734309ce79c13ee5602d30d0b31628e838290f279172c275621cb5f0ba6946a600b3c26be048b9d0c5796d45df5d1dbee2f40f462bba535027ecbdae370043532c5c919043eeb5f6062795b62406dc03595a06b3935001d32ccd187558323022b29c0076b1c76f283fe8bca186a922a16aa4d3b8dc25f370e2e9598746ff076635aefb16e86162ae9869b1cf0bdab1ff4cb9ffb2c4de26e8d911a75374a2fa5ad40be6b89fb24bf62efca4d29fb4d720767f3f6e94f1b5bc2265d2166f8fc4c65facf5bb2eda28495ae63fc6d0d3c340e02b065ad5ef8b898fbe4b0cc11a557509e1c7ab4b817801593622bd8d8ceb717f4519f3b50a5e6d1fbc8a0df02d8125fded20982f7702fecd7be7cfc652ea2fd8e4230db2b726a1719a85fceae7f60fa515bba467dd3aadfa86503bb2fc51b9daa870428a16c791c9bf7d4b90799a000ee5825e844f6083ac16407c2079da04b3c1df7bf91fec5801b16b3f60daf44fbf757312b01fb4ce18bfa8085b4b1600b68b7317a27f33483cd8640b32f3af9678252084bad0ff5a24fd17686e2d436a954e78ede8387e11de18985728aac38176c34b8d11610e465d4e8ff16d68bdd92a111951118510ab645ef7d342e14a3f493becab499f016812fa60b76548772ee46e9365eb17e86166343aa7ab99bc5abc2a844b04a0a64829bdffa5348fe411c8a7d382eba3752526d7c85422574b45e19bc2b4d445dcceb4ade200caefe9c9e17ea4824a27d4936e2f01f5329d7721d7bbeb45140bc34995176b63522d7abee5a2ba0b99e5fdcd12fbcb590f8af437dfa7c7088eb4fe1d9bd51e4dfe8bece5bd8dd1b49ee8ef91fa2505ef0562fe6f03317d914fe1899baa8fc5521c8809f9d6f1217e04e4524da631714b8da6f81cda3772f28f67f52f51ec2f060480295e82acf94394f8fb124d6335a99638b67570ed68d76234c586efd335acd0aa8e62735297b75c4bd41433de608545fb12a01c99917db7dff8fa727ef88a70f0995c1f0cc9bbc5bcc4c9a523673286a3bd6d24c4979254c2b8b4a1a133710fb54df03d094b55df61484614623bde1ed6549838aba5db8bbd0acd455f133837b40e10243baffab0fdabecd39e39132d4d5788f629543cc4beaea7e13cd00b7cf5d3814213accc030174dfde2b8119fd7623d9e8209ce8d35037b589fb79138752da8475bce5af98d17e0350af3714888b7f95580fa7bb2127869e57a8b3c7062a0d2eecb4f7ae739c2b217441ebb300ba46bd5ec58fd4c25e196b71f331e23ee66a33b17b6f9d0ea7d3d0e3b556d727e60b0fa35d82327d351ea5d91ae7b97ec106b2331f1ec2e055452f49c6ae9a8d172ccd3342c929266ceb22a5053f125de3ab9b1052b1fd74179c8514ed8c92d1c5884f64503fc1295d61dd44aba05ad7906c160d67659435ab69ecf41c85df1a4d8623315016eea4fa7513452f36c36f368d3c476617cb82228f7bd6f0c7764622f9125ae53940028f4534ed2189856f88c2655fec5d4659e6e3967387eab37b3e0d8d2651ba4dce500de17928631e632787b8381e477949b595fa02867c144bf19ab52adc2ebc6770d100fd3d0e052aae21a7430dbea99d96889d1f126629232c633fb9292372a0ac1ffa0b023255fd4f3410f6a38a120ef35e5f8ec18c5315a111f16f23185a3ca21d8a87473ccba08976ddaa1530fca0aa7002ff8d48e32b3e6494f4dbd89baf14478f6fae2fa08498f6e76c7041ec54ffad77af657443e1424c7e5271b7d3f2e1087625122a3d0344c189b8102755f625ea2f41a53aee04b25de4a5331b57a1b7bebab6357a60337ba2207954e65a275eaa0234bf5ee24d2e3c4f0d38c36aef6b9820f96af1708d72bbf712c166f5613f50757531f7d49de1347c19eea7772bf957191312ce62fc7336980e9bfefbed9bde0a37c1ac1d32e8db49191f475b646cecd8f7430caa1378795a0e276c0869ab2294e2ccb97a49175466f51b2f2efabaa33725d930506154690f7f37aa8e74d5d14c1c02a6a0326346fef11491e3a34bae2aed84e8256a27cb5f0e2405028d2268aaef83f53aeaa2051d2c5d183acad7b78604aeca4ffa4d05574e69bfbfba40c0919c23493e4d642b6cde7f9627aa422e9dff2f0666b05b5e888ed5d51299b8942f06c66b0156dd13bb55017291582b75a1c5e7e512b1bf52d72da9236bd965062bb471dada453878b8fe7b110a2e44b7682453a964135cdc5efae8782439df8c36cc64318edf7cc7a31273d26782d008e2d0883411be09f1b2f5fc1ff040cf2fc6c1ffeda22117f84d0833a3846c3ac693e61af8b6964d89021e0c446b759132125e3db4d48f591e40a8aecfed0dc9e69b89318a061b93669d4e9e113f134033812f44bfc4385e16592f164c1f0b7ac41edd85b43a95e8c491a01ce8a2e67c8d7197b72a3b4bf4db480ef012a39d8cadc57dac8dcea1faf89d48af2be5dcc01e27c5f567603f22d13f1cd8525100b79854ff56245ec48902a21cd8187f710cb895750da88721f87a0e93ea2140c7ef5b5fcb8b9a6755c537d55c37448fcf22c663fc8d3ec9484faf3d72d099fc7ae6c0e1020d0eb9f2a2b21e30cbe3da6cb72e22036f17296d5ef9dea17605a2029f2b4a9c7447890241a2cbf992d08967b90d985cce3953b8f2b2c7123423754c8dd41f3752e5d2b04a0888bb8abab4d03d166e923679721f2beb8351fcb4834348b4d4c605fa9d05a284fe5c4f962bc9fa77762c35cc8d12a21b337bc67c913760a3f0932b24fad40bac4a564bec5dc60287bd64c0946c7f87323c9c56e1ca628c15de916075b4969d8b5fa8fcb25fa489b093ea711b771cd616d1f06616fb56d5050ea2d1eaaf0b872b65ebab83f5e9056483f5dc1a28bba7b18dda5712a6d7f5eed5b204ce3728ce1e3efe9ef3d6a50c6f0a3835d5a5afbcd12ef07e63a469aebf37218a19664d063954256624c05ab1b9e23468a8140e05866ea81dd15e3796ad2a646413613d24d325ac4921594d398ded0b0d7c77d645137560bffc1e6928c1d9832fc9018da0f68c753eba63da09da86e1073a429ce48c47686fd665dfdb13b296ee7ea55726bfd7aef8e217fbb2b0995111a5d036ca71630bac1741bed00f95094fd13080bea1593a511e27ac30cc0b3aa66cb9faa5707bb7fa9377efa39e841f86325befbe23f0993d7a90a6895f08723961220b0d73009353cad1bef09468ce1446935a0e1d16796e47523ed652c707856a1b714a166c173debb9844e931506d18d26e9dffa43f2b2ccd3af2432e8c49b21b818d13487734a6609d10e52c300bdebc30a96b1d3d1510f9bf4e44465c0473cf273a91428230f71ddef7f41362221c4667cb3845d716fee55ae9f2bd41ace10cd3039b3a36add92d66f01119d1c486354ee33280a2a665c18ae153b20b6cca2f25752574dd1bcddc08a6bf5527d3ad79d28ab16ac7e584ccb8c405a0d8a3cd6d5f4165faf6a295f2ca9085691eb56044389f020e88651f0217850fca73a418d3994951231104371c69b26a8c17ef2d82241216826142743d65a9db10289e367d3cde02917b86e60d952dea35abc9bf3af4757533aa4298dd28d4e31e5b56ad89a47d08ad74e3ea7821c5dfdf59c6834a39ec67a731d2db5e35cf1fd2d0a51c159e8e938b19c662b361a16fd713c986db431b6845ea4fd44520c4bc8971e07938880580c0c4b91b2c793a05823f248b6e1c2ec2512ee707fa20f975fa0636090fd62c7cf8ebc311b40a77efc529894e05e7acc1841d73212571abefcf7c0c46a497da59618ef8ad35ce0f58b651bf0c308bd47bc2e68584c88e30469a4c37d225d42b1149641514c48e87e6b1ee153cc454dbeb27336b29e23b40247434e8d45a260b59bb1d53f51654d6f9765dd55c55870eaa5ddde185281a1aa44ea8dd606454c62de2bb7be756ce9143b5638e56302c16a948f437fab9d7d3dde8fab411f43c81a64eb7d193af4ca82d0e48670b13f51a21f00354dc9e3446868a3209b92e383df8c056932d7f6b7dd5d356b4f075c5841577f8f29ae73695d0f20a64bb0e4c6fcabfd8e2412c42f916d0ed2d022003f72fdfd8ffe9ed24fbc1235360b87e6a4dfcea3568774572f95992e50828a0adb778f9a5fa69eee937420608263d7025db93f6c432820eef338c60f7991e269f5c8b55226b7f60b2e517fa516b1146c53ae5aea614c396d4aa13b0fe3de0e85829bc60a5154c8352462d96f2a64d44c69d555d1d780a66a1a61456f0d5c8bcc290d947c1dab4ee0a936696abcb0e10e36bb581957ea69aad85a043716e2ad9040c11742a4900f2274be010f38e8339077c19d1533dd8fae4ec7c850fe6256bc89d29f1790bbcc48e9dcb7e26e3a5fed1bccb9cadd2ad375dd000648201511c56f6496baaa278bad4e4085c6f8107bfbc2b19ef600a2db67d78e120efd066c683492980d020fc2e8dc502835584da2f8a36f8c51695a0f4fc9e331c6ef128ff1a01ff0b2cd7d81b3eeaf9ef07218df62a7422c88a9e3151d7550b33c91f0391cac22f8cb533adae765ecdb78b103376f7c8bf394b0049832a786122aa8b2779dbe12cd3d5f5738221800c4e87ac0e063d148994f031ee269a7677323e280eb0e6d85d4caf4e9b5b532179d8268f78566d108c2cb5c1399d62b52941d67faaf4929600b276d68425666ed397d4862fa80e311353061793e22c4bd2784275938bc28588e5ea8ea5f853810445217c0e12f4f79a455ca30c6029dadc120f4d72e344fb47f7d996c9819accf4bd21ab08c482e29f593c722c73e0b079b24ae0696efa31aed9dec043911db0b0a7b1059e0b5efc00d99cb6bc2e4e27918565432429526e9210206a3cd091930747e5b58b7d91f99d2e019753bcd08c9ecd2ae8fe882e7ad0aee034a381f7293046c2312e8c390b8acca0ae6844221f0287435e870bea92c85de12d685c5dc8a0f9dc6a811a6b35381d71c973229f1d31b5c31d859153d919283b5fb8a01d6c5bd5f8fbd1b74b05a26a9c6113db2cce6c05fdf035b79de40608284807f8f84d4e34729a62c93547f885c56400ec80fb11390d8e6d81c41626e1b809006d5667a0dee5e9f4fce3949182f740197b23fd42632e08b015f55fd2b4eb266fc26fa992d20142863e8086dc290832dd1f27d09e2da991266ee0e49d62a771cdcd91aff050dce04fbdbebd62e37424870f3de3e20902e06ca31199265c220f85f31822864427977d9bbe4a6ea0ef3bab6dcf62a979f4c6684a4dbbf8bb013e8bec0bec946840618cca4242cc82bb57c7c34eb0cd1892e503ad567d9bf162b50f64971884d4446732985731c58c805c0f957f396b1601b53d5230ca0d248557f8879a3d3ca2437abfaefdff2bceb4938a2843b7e4c5e4a33042c9c02cb00e3da5fc953794f56e47d36d7641eaa9105a166c7e646dbb6e83bc410fd4d252a1b9e55c3c20379fc7801fa3b463a5f8711e2094ff6fbfd47156e327508a9c4a1808cf74dfebac82b155488b676a8400b510e3438cba631d1fd952c16c316a0221ccfa4fae082b2ecdf49594ecb5c28ae5792a35ba4b9ccbeeac900336e238938bdb9456dec5bb178a5dae05b332830784aa5e456426de67b05b7b350f7473cbc99a2d189e3747e30c9c67012b7fa9150b2aecf01e024174d55d140b4527a2d38eeb8175b57600aa21c424052096ab3b800ffc6b00fdb931cdce3856b829b9591f1c02c529b6681268192a9939af94578445af9ddcce58585bfd35521172aa4ff4612795c58ce1655cd9cb4f769a8bac30d5d425056d535247a7c4f84fe24028d3bdc23a50369e7e9c3170621083f39ed34105adc9de92e3d797cab1eec7ca25f334982ec85a1f77c477069720d336a61606cc0d516730f0989567e64c8281f2db4eabb85bff83c9e3f71d60a71ca8e8384f5a7f98dc2010a98e6ed7688a592950983edb7527b517e265dab9529f6f711bf237ec6f5d7d81ed16c5b484886c88b0d33239cea158607426bf08bb28c1fa0c50cfad241fbb3867356da4144d4ea02c30b2a1c426ae52f3f99f7d6d6b821133b7ae53ede870da5035d809b0abc01856767d43f7fc7377b9e86fd27d233f0667e5f96d64b18f4bf6705eade17ca0255e0f0e83b3f8ae06e2c039bf3d5aa1306d711d09ce0b07bc8876b403d5bff9a5e5e635e353983358a5dba89bfbc0cfe61192844fb229bf2d81e1ce4f1bf090eb4167a68dcdfcc3ed7ea347b7fe566f545a2679880df31d54789d3441a6a1de7db983845baed632d68b870f485867064e0f6f501e53d652063b0550a0edc22565a5d0f2d88f144266f8fc314df0de4269b9e4cf3be12c0dc87679bb5f1e992de653ea358253d8ee05603558186b3d1b5923e54394392f7b8f717a03723ac45f72e9464b954fd4e5259953b5c08bb53b495d9c6659ee5fe2f718807e714099f2bf32067661b7ff53ac5e084c1fe98e3f0ef9900a17b42227f039be73d215e3b8591c2f824897ce4f1e732e9ce02454f9514d1097c3f39b6eed9d0e4236a7bc3befb299817c4cc6a1274b9f9cf4fa38edef61af4f919784a38600efe1635d8a942b01556abafee3730bea7e257bd056a8d8cecf96d40af99c42159ecc10d88a98bc416bb788f5ad54c9190e63caac6adb4747b7523abd574b8c30c3b7a01f603e1448afeab8debe52a0cfc954ffafaa3d0ebe422b77192abaed458c80ef9dcd66d502897230ad26063a83abad4916604fa8ad10f4274d56cda717005453b70ef07be0bdc5b792097943d686fd3032e79b18fb075458d324f7095b34442ccb04539f161eed7dddf6bf46cdf87d6f24ad2d44ead054f656976e8d4eb2784cfd552ebe04de43748d2278a16b579865a1e0465e3e5975e175a3ea02028b569e5135c112d4082bd068e45991774fa9e9e369850a77c4f668d7c90c9279f175c052d02ed81e8b297794e67e007018de500979018974603f0918b3b282aca6d803592bac3b8b0a3df18105b7d182fae7a83d1699cc2e36ae7848426e4cc41d078a1b0b7d994fbcdb10b3c52f0022dc458d974a498c9aba3edb100ed951da668addeee61d7a3b082eb231ec188e15bd2451a911a3bf5604623ae8334668f64cc301957a09d550bf85d44fd4e414989c066a745fd6cf5a4aeb64ff787a2d2433a68f2553ecffd1d5cbc4081b7af4723f8c0d1c870d937e26e8e0c5362fdcb2e4a9cf592288f52286acc3fcea6fda254fbc1ff60a3ed1101fdf9f54ef5d002583a1e432f5757f00d0437a210ed6eb4f4bd762424e20c5246ac118532742528fca806ce8c2890a79555509164af5f54dea14b05aa81804151c84b0b9fa2406b60c9945e8568b46f54e03f4570214fbf7680dccefa0f6646630acd49bec20f8853bf72733eba6e7362de42bf6a4275de6379c0408bbe9e3c512e729975b09c040b3d89872fd87c072b65fd49a4d16ce5fc4f2ed1c8167a7cf56b92fa24a28f59509cbae937c9b859e81daef662600a7dc2e0595e283873ba8a8c3806cdc8bb6bfcc43daf9cfa2f0d1ac3a2dbfe335c3991ea8dfe4f5775af5ba50c907b3a89386efc7431e84537de58f42ed38620738e9281c83d110ddbab0a68e985b8c622fc6c0ca01afe281a0b6e2bbbe522698e0dde3cc3c9ba1dbf95786a2857389f595eb7d01c9e4b070cc684034517130018f0ba4b47b80960e189f9686c83abc6e96a1f427798a876732810b1e6c8215245d82dcf32d75903d0e610c2963014fc5f6d8e91b6fb7fbc334d336d8ee410de7781c938e7ea7b5b44cf7cef72de63e3b8cb61a0a43043050be69b9599a77465e547dc7685d7b3053aea78d991fb22530cd3854947cad773c74689fc0041ed4ebf5f6dc5496073e12db24bd515ace1f2b041911fd69b1bfba26596b517001a811e5d155d6f2ffb362a6a7bf76cdc0438bd0646196bcc6bdc1cffcbf5efb6b37ce28e8b0a50a0ff22caaa98107b18e412daae1ad0a38899e8b6e0287e21e87be50dba2e344c2e71cc2114a3c1109910fc3ab3fb94438400bc132850a88fb695f2b26cf2296ca1d0f5c9cefdb8ab8e83d0bfd946db4c9bd5003c3875c7c21f1764801cafa5dcc28b360dda07f575ebb1486facefd44701184e9ff2c4c2b5015ecd6b5025b51082fa293483900c3e99c2e91194996ff65529e3c4421f46316b94e6a5549b03437f4966fddb109dd641d84271473c4db43321ab0b634db06c02387a51c5f7e3d0a1f8bdda2dbb2aa60508df4921535b03e012ed59908eb4425f498da639c012d1124a837bdc9847a3deff4de588b46890144c4a6236d33c2accde227e6f7fdf258877c104a3a45ecba279215c1c061dc0ce7f65a5d9836f403b4682c709d09d0cea7d4af13455812be94a59e6e243f0604e4c7fe4bb3c4ea617dad103c5e1ec0f9229a60e10cd7bcd1cc47b0b96ccc4320cf6a26c7d8ed2e10e8a5481d0d579760e594ffaf942a0e84c42b0ef5d7f033637b948ebadb6a706d2dc3590880747df5aa0733726e5f0fd017fab356d7aeccfd896f9aa64cda6f176aa11080ca1544010d36608ba866e29f63ca8f929fca26731e5ca29f35b647f99b64aa0546eb94e23bdea51a52f8d5cace68d2fe0612e68462ca63654105a0fc308dbdb12d62f421227e0cfa289e849a5732c0e87a642d2e1da61e70849b6126d343d71c69f4e54d2cece5342d5c9cd576a4ab8c4de9e104e8851b4f43daa22db92bee95c2e54ddedbbe22cdbba3caf2b1f1862ed3c8de9d0841ae3944037d39a0c35fc49378c5a9b4d2895eb53b5d84822e1d28f8e6adf48846daa19efbea11e0c8e7f0c7f2da127f8f8d3dcf3fc0f22c6f4a99383cfd62a44081c3f4e7efecd06a9a04e11968128cd52e48217f52ab81622a29ce5148bf97a63a523f3e154380bafdff1c724309a3a3e01b2b66e84ff721a28bab023fe42750fc09887b278b10089e2d3acb3cf42a64bef5317771ef48bc5a3aa3d8609179e4ae757be2c6e43b3209929972be41e8eb960d3b2461019b4ff33168a93a5730a374a3af5ef67b015886cfa85ed162dee1caa17f301de2a88155efb2768e9ad98ee2f524b13cb8ffebc7426fe487021d0b81809f02fb9b9a290a8255e8caad37446dfd54304f7907b0ed797f0464755f6d7d34372846684cbc10532c54d21d3bca59075ca0e888fcc1917b0d551f20c83ef42f3bf27672595c678b9ac034f772741a40a1532190c93c8e944d9010b3865a277c7f67a95e70c93deb03e84288f74e16122628a07ba3e264b0475cd9966faeebf0aa67e056e08efbae2c902c49e6b36c334d8d58e8843129064d59e8723d66791823ce761364e36432068f1ce992328d31970ea9937be833080be6b05d90548882210a1ec9a72389c57fa3c96534ece2f93c1edf57b6a59c3be7e32f9b96775c7c36dd6c5f6c330bcf12940416bc8121f2886114eb9970c07ec1b00578558c2fde82d94d852b0ea7f70be8d62e5be0bf49f1ebafc6e9000d2c8054e100e9ac4083aeb41d3cd4d861f6b8f92b379d49e157436964d88eff9a67b0a2c682e7d32d9f937e25a7708b938330063521a2163d397bd87126854b7327c73cf73ea39b61fb284d9b1fad0e65cf649e9fb3a858afc934bb825083fcb29fc18f53c4c7ff1e7cccc73b483103772a691f9b9777f4cf2c18fe6ec615dff6b1e4ae7e8437dc7363a1851a722d935c5d2c1d68bf52cb47b66ecdd306346e81bb177aa7ecc23aa920765c12830fed45ff6313a33512921b837464b3605bfc7c22370cccb6be0c248d0ef74fcdf46cc22bc5fa1904ece78bae910d0390da4fc59c768b32977cbc4d60d546c2d73d52ddce69ed91a5a3f382b2f31f4f5a7e3a69f14a328019e8b8054475ae6300e6e292a68183825701ea8117ee41ed46cd476f9035fe476351c4d0804301f4fd71487a4e68cecbbf418275cf528618886437da93eee873701ec798f34e2c0e02c587bebf106f7de51285b5763c7d0c53ebec8ef7f6fc05db1e38188d2aabf36de80f6032fe5fd80c98dd07920646be53f22331b497492fc2495e7b748df9c61d22a56bf589c70ed1d10c1a1002c713a0fe2eb826d9e812f5c1dcc770fa16a092000d0a703ae0b9735103c2d8fb75f3d5531770e5d58c7f242cda6ed9adaf1feb5777f5f4490b25bebdca7e271c253cd4b2d18323a4e377f457100bc8db55a3d5a01c5796a76797cbbc6b39227e9f4431301bd20af60d65605f33cb566a843efadfde33a167755aa455bb77c653d1ce25e757341610fdc84721a714750b31574f5385645e158df768579170335dea040e4ae9a8c6c83ab56c501e85490681f48fd17b8a329805273ab9f3cf287fe8335dc81c21d6ba256387ca29693de36b4b321776d2160daf4769b8bcc02de2c334ac70720a9744898e34d2678f1f6515954d0a7611db66eb31c38328f91e3a765211c227c8e546c5358077aaa66ae973c261cc1348f5dc27dbccc5b1df03e808737b72f46d121ddda28ae2f72324314f4867451e94b7854b10f6fd509eb3050ff09ceb509ff1fb746684dbd4b9a5dc3d2546153827f4d18bf655b0981d1d1202ad321c697d6f65174abc7d0507b465711f03e26f01065d6078f4b93b11cf0633bc7ff412cae3676e6341694b2996f0cd23fbfef9351f6847b6f432e4e55c38322dc12d7344b433149b78d0d8e71df0902608f4370a3eb081a61b9215226cb979214edad347baedc3db801f8f08bfa23667f8b110f809f732141a9cf3c6dedd128a95cb47b0bd0eaa34b06b05648c21683a44fa096f64ae166101e131fd0903001dfe6008a532b04918ccc2580781016be21fe7aa9256d829bfb2debf979e6f296700ddb57450aa2c1cfc5ea3a45a5a4b477f2c515e76a90344cab7f6e4032fed1f79ea3bc9005d27708c67218660eb1d50007326028e8788a73ff87282b22e2bce0df4d337cd0ce2800c1623b98bbca098937a4bf1fd18d82778cb255ab90b05dafdd7d501393bade8b77106e1ca68f9786442a438d5cb8e003f750e5badcda3ec8591f659a1422a1b348595ef0ffc225e9d4bb2b9e1e7f3a446d10b9ac72a6efb22d181e939210b335e5c4c8f5641275bebdeee4a80172a6093bfbe4353b8f5219525681cd28646a11288e9aaaa43d0950ad61ea85523d7b0f01884a51ca4ad094052b480b55085eb96944a43e8598502cb653591d6248229f7e26e27a7086199ca9f511719aa8337709e413034a4440423459b5ed38a4d8ab97d5a8c8e02f0796d2009bad781e24c76e1608f03ca170f780f17f544cac90086d0932d929d4be4dda8887735683e07c962723157ea75800f27b9ce2bf6b0ce995fdbd86b7c1832573dc8c378cfe8d3696d2948483c8fc313e01c10d8d7235a10ee615b9309c145efd70b91a43f47e5302cf87d4ca437872310a4db955cfcb710fb77a2acf2088becee09fab7189692b76a891e667d00bd4d5b4d360c24a98c4cf595f6768edd42ada9bd09e4e98af8724fa86e63eb4c3d88a712075bba410a1a3480af93a888c78d649fd09838645b82273c7af5dc64057f769d2ad943c2393ffc981b8db57435d626933ccbd0cfef08d04378766ea5937d04b07f28f8bf62bf3865d0634060e0c22c373aa30341c708e34ac9522cb9d903f9bd542f3635093a621d79cb341c33aa9930329d0399b495fe6dbe0250550c885cba6aee4887756be1f56e91841b3fa66eed43a45ec490ee62f9d90f63afbde79eb0ead59b4044d07cdb2052821a716b9a02e78575e98ab5925f649b63731e4437f0e8061adfed0d331ab350af5664382f67c80b7bae0a55226eded4cecc14112d21fb5506b481adc2107b0cfbb7f2bd18773d2c89886f1ca56cc11fcc9a5402741fc2b4287c76070fd63742eeed20bd8cbdfd42ccc04451cf6dc024b1e4f27e8fa16d84f82d544fd0041454aa960db83ac710f6901a43f639c5cc6cf2d51fd4ab40115244d51de20f063858056e1a1c21f3a3880f469938fa143c0609c3d886d48ddc7dfe90abc6989df2c04c61bb126ed3ff2ab86edf64625ac76117b6526ac660745fe7428cc17e56050035c2d3a3fa57469a8d978242ad2f6731a6235b2c7beb0fb31ac3a1189c4a5a5a71d25387deea6f922e001a321343f102328a38d2524b0eb3e0e4edce1fbfcb0a8c5a6dd31696a7b0ee414346e0b71107436b490e49b19f7039fa0a3594c4149c27b509ea75b96723d7f79422dc5bec097179ef09e96414e3d63294730f0fa37ef92a1f5c30efa83bac9dd9187bc6488ba6b1a8d1586db70cb9fac6d328f9d87239372afff3c60c6e518cd753e1d72a7a9017dc5d4c1b01de3263c50eccbc06250a7d1ed0a8aec7d15cacee7b22748f5d4c886719120b04ca80f5dabac317f02891688aa02c2dda03bcc2a702412294ba88a2d700ccb869a06e4c483ec0368927e74ee9e9393037e9228cd448c8edcefc5371991c4e4cf1156164865a2f1fcd70ab71fbc4ae6d17de8ec19447e4f8f7db1d9cacfd1755b284adce2fb7ea2aaeaeba44d2c78301015d5e7233a07308a52379146901e885a910848b3ec795b5883be7aeb73712e0a42e733c6ba2932512f7181eed7b8db8ed494ee80cea288858c450a9397806f39104b8f4f431805a181672ed233f2380e83aa793aafe14787521b619f68f9180fb432aac071bf68c539d8329481fcc3a921e249ef8bcb6e59d1478a26ad701d6965a7e8274016b6a53c417204966e13173752a623299ac13342006a8664d159d63f86645d9212942ca78814b87688b02d61b5d0325d0f60d61b2255c336ffbbb6c17b7e48159b68e9518de10b0a2f526028db901a686d381b8aa10fba3349376b233a07cb2cb3bc7596c898cce9ab8ce211112e6e5e032d44783f1ad90b26c767e1b34c5028a7e90ffa6cd9ec008a9f7bc766b3e720cdb4036ce20a522544362328306801e18a726bce5c2527a8080ada6a0069dc71556fc638355b6131b0118ec91708fea9ee64f3ec49d1bfff631e3a2bbd706c197a8ea611e040388ac650e50c37da1e6aa76d34c2bfad620289acf951aa3a451ad923317bc36e5387ba0dfb91f252940d55efdd9c020f95e749325ab3057ce9b231f906f0e4b250821fd1776dfcd6931c316852ae569e72a84f2de8b2d8cd4e37317445e43ff2691f84fe43dc708edc078ea87cee5c146634563efb8315967b3f685be54d88da17edca5e742c26797e934806629a8801fae08881cbd8840631382f3621b3082f550c8c31584ba8378ccbed36fe5fc370d53c819ffc307016eca3f870687a4cf31bcd1117a199fcf5ba56aa0576548b9a36f63d0edc6aaf9ead086037e2847105d271da8e7e42b178c1729645cf9be8c0b3953e4638dff79f8343ecb5d991dcc9dc87d50d40a53c9773d47cbf0608ba3f2d3da952b91240a54b380da50b8e5025d6dfd0b024aeac96e8d99220169fc887335b5761a1be71886c244eaeb11520811e3848338884c8f5c7de90007f623f2342c4774236546dc725f712dc6eed5aa16bed7c8663a72e7c275422261a8224ebb78283acf822d0ab6efd146a41539e84999b932c759983067b1437b2ec4cf3192f27307c973ba7ec5c9e8edbb2e8393c1d646bdfb6065d473bbea5aa8459a62ff498d34a54badcffa5ec4260661120af31809c4b8b1ac5a02b80327946cfba1493acebecdbe774e14932188a574d549d95378b809e83011097942d14d266d375362bf13cc266f7daaf5923ca215a88356be40780e5333482f090838fe93e78f8b3b8f52215e91a975045a3d901473ec88485c79e35416a6177ffd86d74d367c48853a74b0f6093d17fd75094003c2a07f2af6d75071c6c082087345dae7bbc4a9a74e471769c5d883dd6809d0130f6201174c92c6e545b1e4f8e6342b8d2d1a6221da213cb3204d513d8db2286a2aa7decb6b2e87910a1a405f4078a040bf3fed041723f686873a6180cb3007ad2febf210cb05a6ab8c553548daa5a956ae1df5862fd1d00b6ea06eba6fb0d6793876757276a88dce60737a7e4ffa861f4ff7507a28bed65e662e56c47aef2e61d6579e2a136caf8ad119daada01b127acc3e9ffca57e89b269d18155443d36892579e78fc88c47ca596ab9c8d2bfa412cf1038f70fcc5d28c8bd1c16360b7c2a3f9ba9522154be929451730a492abb2b4d8142f9c49b9d3f39b3e82bd9af0661c17f1b6c81a2609654c5bdbd1a92d32c74e36417cc61a0cd66ddaa4cd98196065d7cbe3d2abaf63f64c2b139708dae57bd4ce1bebead14bc2d47185a236ceb0d3ec20e775bbbb36337d6ec292948bc1c00c11a8f17e2cae06714d1f57117d8dd2fbd5dddf269dfb4be2962e9c4b2a791bac8cd4e549e5484d0b668423674b103a37bcdf2e921d4f5212e51f30f6752c0b65dd8cb91b1ad473b9c76c36fe9e1a15eea4b731a7267165b3cce815d16a3acf1988ef08fa91ed6016d9afcb424362b4c6242b76d3f1ae4a4c7716ec267d379378a797ed46e459f5c56e35b239deed0f637b2c8de12a4961d4a8b32e60dfca70e022337c4e26e602bea226290d7ca24789fe8c64500cc77044ba5a04ef27c58a51bc6e8ebcccda7af0d28b44a6bfb8d14e91a7c27fef597880e44de005bb6cfc316891eda4f0a7099d997712abde09397502eb857331a3d0d64830dc63c35ddad767107ade5a635e794e9e3908534d95226f25de86eb0e1d428c0174d59d64d9d178e81ec0847536141159e8bca0a13ed98a3d3a04006b096418d57a3ae4bc7e7b79b7f0ce8f99c2f863c6b707509868af67af0249f50139b7044a069f4046fbb99a2c15a6749fe517bf78a3a5407df63cb56ef91b74ea20bdf5ff29f520a7ad2e06cf2d89154d281d2b168431b246c16c2956a651932a426c21f922c53f20e96b04e2c87db662d0be89ebe45393106475683aabcac52438f59902611792ccce16a68f9d0e2315ad46d7084b4781f9192098ca2c1d74d57445cbb1e55919a730cf3055aec6efdbc0041725abf1ec0c3a0d92e60b96efe73aa5332417581003c7de083325d0f753718512903033b43eeac0f2a96d39ee8865615862f6646d9795f60527d321a9750268e3ff28dbfeda7c5f342e28315635e4d2aa018d70239e1d8f7d1b816ddd7ae1cfbe05f48fe1927b80182e9c460278229fd237832f87faf10e35f984034585244b458d2ae1daf7343ade8ba21695ceb9223a4f5194702872236bba423163f117140e2cb2e85e75a5dea7ded2a62abcfa9700acf90b128abb36678f926895e78b1532d9fca89e06749e874353913aca161bb4e79af9b2be07fc8c5953be308012bb7730593aa80a221b466ca7919c41ba800f41a52158fff359ac0754d7ac6ba37e23418f56be39ca9385959aa11d5acd785844b8a1c9670732d11d96f9001cc06fc5b78702d4b53776fac357c89c85e8a65c28a03139866b7df888916e6d0ba18d5de1252876853e703b1238ebc95fb13a44193d2e99e94a4194ce875da2c54e9faa76add2594997a7147d85efecbd21fc11de2baeacedb4b57e882f73002c80611caf4a3e27cac53bfc0fb855212df90f8ca3f7ac57c6e7ea4cb8cbf41d755bd9f3d66222f15badc717462422e65bf425ab6f79f2338b31c108edd359b197c9aaf16ae22d5b158a9a47650060633ba4d6bde119d4bb794b98bd3d6c2b305cc074daa0e1d98644569f24b450b9ff235bf762423f4704d3c307133d3e1e5c24ee4db8c57d27abf66fa29e4e14d3c3f7841e8f2757812b136feffcc98e3d9ba49f2bc6d4f0bda027cc713f658fbd4cd49b8191a32cc37ca0b43294034a4acfe1e13a706bd20dee5736d9df047d1cd1a6944f26f47cb919ccbe4dd0ffc44d0c03bd90f64a63dccc594b7c2f20dcb5f6338790c247b6c6a92729593b1b18819bda95377b9f0d40d48013dbb6129a0e86150874391aca223e67c5147ef0612d3b367c612c47874801a111111c0af02e130bc5208d8c5110067fae10a4920842f6ad0fe90ae6468c748d914ba4e1c1f9084412959acb9b422d27b537247309ae9dab33807f51500c6617e5353b1795eebf97a15f90b2d4bc068543e698c0e1c63afcc30459224e3b05399f52a86531de1f5aafe275dfa1235bd9ecf39f717174f38e7a79f5ef390e956344c309998c81975d3405ff122a35119ef0b8f8f18578b4094a0b4f40968fb75b94b52a1d33050bc83bd27f13393bfdb58f45d56ea74aed486eb2e96dacb1a7e27e97a607d2516768ff8e38a05f49bb26022f0c760f4dcf09a7d80475db724bbb9bda7ba3ae4794c38801f04beaa52ed726c46fed92b2a9cea543af8d403d483402ba36b019cdc9da60a4e42a44780b44414990db000348924d721592f710465c85da1c7b26d9427fb0955f10682f21d1010a088648083744070952115dc59b6a43fce8f9cebc7d95c9e7f95943e53077689d74686712006ac5ff9f40bde24e39e04f47f5b90192b8709a5b99aab8b0aab8d2605c7069ba12e25d99f3b8b056bdd2c99fe2e090d00f67469a5826da324b1406473a4e4a635fa329f72b2a291822b05280083365ccafe8c30c81fcca3800b84630b529305d0028ffdfe818283385aaa901692103b025f6f02bbe035b2266aca220e54682fbe17ecd6181d0077ee5880c55b23036aa8f92722c92786d38a98cab2a178469e8573cab572c1a9261541ab423582db4682a83e4780ccf111bc28573d7bd93dc6296dca21711aef631fcca380ea9b06a675ee2be3f5a81eee1578888a8816ed2e88592f3cac82a2092336b3406596da2fd0ac59c61a2c4be5a43d348844ee16a54caaf6c35b5fa5fe6be605194d35900cc58b1497781a38b4b5a09f40573e0d177bdc752f97f6457d043570d2dea7b9a587e01c0f0183cd480f4757b294989c46446ac07b17a034225563d20b6d018263bbb7b535511be6f2fc2c9ce76f603616e88abe05b7677b33906cd469ff4a7181663f88e6677e01329932e62c83adb6c330123a88cc26ce3dcddbc6900a34c1144f1ecc052556b6e0771748331dd5783f1da67de3d337f35753fd19a643bc9ff9c21dd4ac14cf2a7fa9cad4ac5c6465eaa36d427a0d748f04ec0243397b7c3bbbec65a938e8dc5ec296933bbe73d32e7ee81fe3af3ddb76562a1f299ecd266f87623b326737bd46ec05ee5813a5b3a91c2fea1ed2c44c02210260094f485957966029bac09f89ccd727ae195b091ba24f8e2b95b7a00278f0af0d0ded7321ecefda8a9b934e6cd2b852be610a2981d379286d33e3cd394a223d6b40e9f0d6389705a3d6484f7b495fdb07c18d2de91f52e31566f8fea9439a62d8fabad33de5635b1daa2ce5a20e0ac300eb60f8796c4347160e243b16d75761a26b3c8ac415bbb5d76491c4c0c5c0a40d600fcd11f7ab73edcacf9ce7ba318e25bfd05a6ae5e241ae8ccf2c11aa42f641a5672a11516eeba56d217f1cf22ef25310dfcab018dd7c887289dbd75a44b4f67edb1dc6e21b1c35fec57a78024782dd172681e2e4d3144d346621d2917fd5bdad67499bdfea275cf5a358539e50507a66b2ac9b3df5c07f79ff80bedc1a399538cf1ffc11cda71594159ddb22a66423161958fb77e30a77c842a4780ff38daa3419b4ec7494a504cdaa063020a5f2da202bd8a3c604b2497410841a674e273db6809275434691bd991c2516343d5b2f76a3cac98ca9130f447ce07c443ef5bcf00dd57194781e12a324c929e0b77727a2fb3aecd9d7a9730b734a4e3e62b2ed3c1f9a7ce6bbd2655ddcac5b208ea0a4045785a8b6c7159ce9b9b9add0942653ea86bb171307d5adc1b4aaf9e903afd9f8b8ca8a6c248e15378d94e8efbb0ca7e02c6a49231261eaf22044e7deecce9ea83abb4a2b98aa7e2d71e1a996ee75ec89973f1895a4890c3b9f6a4e020aa682d843ee7f6c19f0f2e19dc2f6e452eb4b258b00132397ce765d8527aa5f4f77c94e9498135ceea3ce3a7b3c804ee077c88e276d15d46eaa47ec7ae802d85f448849ee9c8853e7ca668307cc351e6e4e53fa1383597fdf8e0894b2eb0a18ac86f9813accdad964f4efb744ab1eb2b4ddf28aa24d9aaf216817d108e05d8b45b4900f00667b7564accd86dfeccf5adbec3293a4d72543b0dcd5f9e134beaaff6b9dbca087d229756fffcadf869111e920edf6bcae9ed9c3c8864c4572a2cfea0a31872ba872a72a8e6a9ff0f22ea58a98cd2902dcc1ab2856a43b644824953c1796c2210b73466f20e2b61b0dac12a45f21b52760d926dcfaa5323eb103d64740253583f6d5dc55dec26def604861a9d5cbb9ab4c8bc6976432011979fab6c778f194da842658185c9b2f9094c8f49c831975a3f3921e4618bbeb8787c145c7e9996c0aa43f8f8c33d1e2d7b9934112f4558ca26f93589946fc779b8fcac7b07947d4c977b2e1a6279f199f5969d3979e32b4781390affd54923db1ea71b86ca8024fee52de859e10a47657e9ef284291faf1d93e31219a12e422d425ecb2f3f8f2a136718af844d78dc7b1edbfcf350e275aec774b787ccedf921832950b00a609053bf269dff891e0de411d153b80c9180624da248052049a9bf0bd37077cbf62827ad08bb3b681e46baf16b128261c185e23062ee2507ca210657fc58f5eda6a449d244df9b3b8157231d67851aa9986da9a80d552eb795b3c9ce8ff5afb1ace095609597847375ebf12287db019572a86bc4a0161345beec150c3517da8fb94c5b59e2fba1ac61ff0fae3303bfc63d6192f6e83ab1202d59893174d27281437dba92975b6b5d12e5a5480940df214bd804fc0f3a874ee0c442a26bec29fbe6f3231302c838d2b4a1ac12a45925e4aaac46b93c9e6cde778dd0958e0b6d3b8fcc15cf2cb5e8a878dce08a69a9cc9ff53153a69147aead3a822300450dd11d67a3275a5352822d4605f6b5e8ee59255c6b44d945ade65973571659a53b0d66a68b00faf8b8ec0703a60f9f5ba9903bc3ca8fe90d73179d5c50963e38a1e8485828347cb346403026a4ed1c5ab75875317192194d5b07970fb020fa720b895535ccb5b960caac2824edc644c968b993c31c4dcbcaa2f8e93c7d7f7968db1e5352e718773a6c5e39c7feb7c3e220a44aaf8f0c1e2e434d69a6d7bf89341f366fd560be13cdb0f5ccd738a26bd6866039abb9c250a345ea099db9cb645afb322c136712106f5ae96a279ea622e64ee022ba55db47b81558596218ceb61277bf397dba4cf31180a299e1a5c5cb4b7e924be4a96d849f4ed8a3ed06e7065b226c8e238b645df5d6f411c74b94be92667cfca69ec47c1e980586661ccd1c7d5aaed59237b5f5a94049aec19a0a10a29e53a70c1feffe1d0d5cfc8d614e9a8b2188e3dd0b35464e96adc884403b90a0000c779af7d9c7f2f69e4878efad4a58a0bd816645de87b0e01c71bd65023fe49a40a827d357e115be9475754665543ad052ee2bc7fb27fd812cd247160102ff1dd38f63d169ae2aafde21b42f21ece227a7b00fbd1922b52bc5576d68777e6455f72e56923a626a2be424d183c5132943c2768ed6b9c8a3f7ff4c9193c007444fbb675e354409551392456e53e053e5861297bb087922639987cf283186fc170569af4419d6841941b8ee2daa6e9d6c6ecf87cd28a026f151b65069e72ecc006564a7838ba7333a5989cc0f8470a623ec7964930f3e3eed733100a653dbdf18d1d031711198e37633031a251c6fe52de5ab8b46bf5a3b615107ab1d6fc7194af6d8363f7e52bc93bf2be3080a4e30bd3292ac789502db26c4cdc675649108cf8f1f3f61d047f293663dfd01174ea8e164a43dcc59b2c6c796f4dce4a7271d8adbae63f3f1764a7352d0a5b129963fe55a26bbb966bdfccfb61b494aa25403463ac5d8757e15505425524252f347f8639ba2322081417672b9794559ab2ab6202ebd67dec1366b0caa5211a5543f8b6d726dd47f5bf34ac7f8b2cdc24334f93c51c7a9d23043ad04c929f226cf749eae6f4f40fc372664241f6deea59252c556adc417c953c5215e172dd5fdfaad75a2b5305459667468074e917759417dca24d25b64cf142b88d75123886539ba99101cd156222d4c881a73e26194fc9473f1933314d10825311180b8630f7e3cfb50c7ee87c8e31bf3e5490bd887e7c8f910429eace17ba0d54744108389ef0834e279fcf0953ffcf8c197fc37124eaa7093b90d325b48dcfc1c894f52ddcca46dfa585f6d20d50431c22b12b955a58f1093328e2ccafaa8f8afac49f2aa947f54b9f4d66fd024d915ec2e303463a8fd9db03e8134bce36228288cdb4ec36eeb919194409e81c209120af054a97438db5c0a67a9abc722917c935b9ac966a4a99c9a918cc43b180abf927c6936462236124c2c077336d421d56bf3b03a2cac3b09481141b9d0134c318cd58a6ffb278cc62911a961d88b3fe1ffc8248a2d4d787eed41931df13e51c274558f702554c21391c15fa5edbf1fc605cce782071de9bb4625bc90044b2dc5f05001788dc1b12bdf05173f521b53ea111c64b49f7c63b3491eeff31a3f9670c88db9a0745f7510ffdcae00411793f056d09aa63939a725f81f95471d109a95cfeb018b4481f2309e24ae19d401da359df2c39bd8ea1f915832813388bdf1c5dfa4021a0464b9b7b75e6068be8da19001d0ee05d03c07c1f6d0185840d33047a85452a070b04ce0ac030c2db171befa494a5fe48130dee54ee565ae025fb95768bd1a0444bd6e464047651ce4ec89879333c02b789fab4cbb01891c6bbae3e8e39abb6697f0ee3fc9320cce97996a74f4db6f643c9da34ceee04e3d34b8ba3b8abbdfca0ca0582b8347d3d44b9211cde43620854d509cc4a3798aa4ea910d599a9043c0c80b8ce5e549b875c00a7acaed438aaa38d3d6ea1d6c85a79b03f4778a43bc60245c3ce529fcb740cf74b47010c914ad266a3850e9f164b621ee9aa43e3cf6fa744c8993abe4c66ecaa7260c02f4b3ccad5e6129123f589c7cdb9a8e969478baf8d5b6c670a6bb2cd574dff5e8d469e363f567bc628006e8fd78d76a0435a28e4c9336faaf910977b993f241f6cde33a4f484a35f58171e414dadba835464cde3ef7e2e23f0c75b7f53aa8b2fcb78655131a902719235533c8cbb05f38c2b3ca28fe0b4cdc69ca872448f23d4c58484ad289cb1d89f218bba0cc88250651ace53da4e6ec79da81635851a78f017ad2368d00d0329eee1daa27865c238bdcc652377f1c88a1c44f1ea16002847cf5bb9f43212e1c9f2150327b1f87dadd29beb7fba2f944ebab0fa1f93d8efec3aa8ae098ffaf2c701bcf4d06997685f33860ab47e8835f83d17eb639bcc7f168ff471c71e1e6833575e7605e8492c5b99015d7acfb5cc7307834784778c5016491714cba05912c0232c6201e92c9e943131d2b36e99932a772629cab5751657b6416c793bc94146e3c71a27684722f79c76980d0cf17a581fa5aa93d60b44dc8c2e8b9e5656f637e75e9c7403f494a44fa04ecc14c0056136243b14ff0e37b60a102bd484a3c592339851894c03e8050330a0b26da52b810760ad71d440fc1e7fc805a4ad2c19faf8901007baafc6d179a84073026ed553b30e626e25b821226f70d77967250ad26445c8c98e119089704f27649fd2ab4e3c80a70122e32e79533159194a5aaa8b4127bb2a9f4a916762b9a486676438b2e1d08c97e0c6131ac5ef30b0a69391dd5b39d11038f2bda77e6e49a64b68481b5a31de4a93e85a521db0f89bbb9ea5d4efc18814aed6f25d090e23f28d6f5e583f7ba79a1406049adefa198954d18c2af988b6091469613329107a1a48c757c50c5d44aaf747df63c6ba0e5bf2819569b46908aee4d12ced774b4e76bd511a8c969cd6cc74a3461a615ade962ad424ee2a01d17c357810b7b4959ab9de467aca5edcbeb31a4cb4f550606c5f2b6eeef35e6995e0ad3070cfaa68950cd07be555ebb0a66ed5dfb39f704e9fb60ec39182f48c1c0150d663e97101bf77c608177cee967511cc1e536f6fd73f6203389fec88373b2673f43b6b13d6b0766989899567b980d73e350c524440336f59c56437972b15a17ffef7c38811b5e8548cbb103f88c0deeb56d96d239231afa529b4dbe791ddfa99a9a127bbfd917dc008e642e8b51e9132c845a8d7bf9412399f6132dfe3fcce6b7de6b915eacac7821ddcdc6b84c8082815d880eb75829ef0f5a4c20274938aa7225fa5f204b79e24a6ee457c16300cac5ae1c1bfadf01b4796366bd4d64f9c7eac0e26dc598861fdbe2bb727fb13d22f79ca7379a9d5c5f8eb1ac1cda103f0130e8866da0deef4153ca4c71c3e87634742f273f19a55aab19812e91b4e21e919a2a5898edf2163eff7626c95ec8cc3a674200f49514c68d089269603bccb66bba70a8f7a27fdcccb8cb90e7038d88984a984232dc2a61425d59162da75c2e522e9380cdf39371c8dce00d0da648a69cb164622d310f1ed6691a8fc79813908def31224b7e2ba52f8d551c622183e4befd9229ff4dd28bcf98e37ed651f9b16f55d13bcf37c2efa07eeef93c95239c691dfff783f990555ed6cfe6cdb6d4994438e6fa6c708b108688394db2d82c460a00d169303941dc2914c27c0bef30efe87ef26c98213d5600a8fba1eeae264daf43c698bdd416bc00fd882a1cd430aa6dd30349f028630d120c25236e43a26ccef660c0c8b514a198a688780f405f08470b0fa2d0d041b07930d490a8c510d4b04931199c9406a247cc9029660749239a2c341af95461712445fd829a4ea22a90fa043fa50d9fd8335923691fef317d4e7857198679e0563c3827e0bddc4ab501e5380c1b8c5e17ccb5c7205e523b57ce141d5e4a2f902d0b881841dca0a7de2990013f97f6721894bd0bf428c14d6c32816cec73216def32bf3f1e24b82e28e186974fb28838775008c1d2dd667f05a1a4e1d361e2cfbdbe720df6b59faee37d2a3befbba0a0a32773d42239a0e51620374f6957db79fa0825a64572746a0c328d3692e1de51c1a437b91548357cd774b896c9f3200d8e13605b22bd950106230f750a3a5fc062b9eb6482cc569765724a573ff7c54db281eb71535d26cfeea39482181a967474e298dc539f0f83f4eff82f3bf0c6905d7ecd823121d0aa83e639025ffea17053c5c26396829dec1bd351143ee5f77dfd2c25b24a1c952617edd57b5d04822c9cb563c1a649aef919f8d35c6be590b4d79b225940e04ff73bc76a61907f1f638a1a6393b20c632a2e53a1e97d31c13572db64a3af6f8ac63019bc4a268d33f4adb3f51a85bba17fe1c551b99c110f14cfab0a303e872bd55dac151781eee1102b86df8a2ca8473da2e6368c110703267ecabdbf1eb5639d3bc152437f6448d849474053a3a6d7d688ab809d6d30ef18f711ea068b214214e4534034dde9d09eeb2de42d78bebe8952793df036b90441224f851627c0199e5d75678611974364d2ff22c00d190abdc8e0a38eb19825f50c2c2da753e7fa5b9c3eed7f30d4691cbad27ce34d161e56ad1e00070395b7019129178f30eb58afc635eab3d3bef9d9c36af5b033b180c626bb2d2e1343c74d7368f7b6ec0f3bba2dc7ddfbfc4ea86e06faf6c4d1685957dece520329b6eecc21ace1dcc302e9a903f099200d813ffefd34b2667bc3191db9cc2b0aeeb7d65efd8fd85cb1d2c4a57869805722576e44c8b7007d31ade5e11c54b2c41ef8320d3308e26aff429fb8bb266c32ac6ae2edbb376d55a741b426bfef2ae36fc81e2625f7d598018483213586fee80d2da840d7dda06bc8b9134f2ef33cf7df6513ad00dfdd0269795d4726ec697adb9956a0dba41899b13dcd221c56de9228ac71cf1ea3360ac41178afddfa36f97feda8aec3efbf31d2ecf6335f9fe87e67f37fea203d79feffc804ec014f276dda8862f2c7b7f004df7694ac300682a733d600675d9f99afff19b67e9a43a8fb90746e9ca5e96da4be8d8b8396f8fc952b3bfc9c51f17cd58da15caa187f1f1df1ed514581795d2ae442f348a2bd08d82a72f697de4e80ec8133f12ea4b99521c8e51c043ee3dc2f4dadfcba135d3f01356ddf8be174b42f5ea3ada7a17fa151752e03db40138498b4017aa4d0b93816ff82dbd3bc1ea97cb0279c875904c5ce6a359b4780ac0a9465ce3d1ea11b28e6a73c306aa591f0f3f3439e055ef929e9f08c74b1696ee6379b821c0f23ceeb450c2ddf3cb9cb82f70c4c56ae9397c240963fc87257c4f378a794ee89c0cd87df1f6d68a88cf4c5dc4142e5d144fe49a230d908e27a3d40643306cdb3fbfa55f7d916f2665d00e036dabc3c52b1878f753865bbfca80873818d4b545532b004a50cb06cc94351addaa52113d7042f009f5190813e3e00bfef6b060d63f3807f4b150cf7b0630cc3b8b09b729b2085a5a68a446912f3d464727c7fda7b6467e0b3a741c22f9d8b8d7942bd3470275baa5a925bf704f19bef79bbb8f87bd0050b6848c2baabf1503777ba23a5c33a37e143b94aba23185d88b10c83852b51a2a36e86f2e5c2d0a9e191836ad399a65bba5121ea46c449e2f7b1ba76d79c016bdf795541494dc81e94a11ada78a9971636bd36fdf54b819f61d6d020f7b63731e5482ed660ccb0259fe79055e82e0a03a7d0247d00de701d91d0a34e38d67d00bd94f3b2f102c3837aef327ed3600e2348a6e64d8e55f2cfa6898df48118efb0ed2b7668db712f0da202b6337c06ab01df16ad215ee9f34280cd2f17d5eb85a778bfbc3aafbaacbe1cb13792c20ab519730ec777beb423d56b31c3d8288ba63955dfa79c95aacb2d0b75a3d2d02bafa1c2c26a9a4410a4e90dc917bb097f7b43439a98f59018bd02b2edf58000dd32d989aa094db57a36a3724bfa5601023b8e7a3aab16cdf0c5328fe1eea4cb194f52ddbb79066e1af61d0c072918e3b2c0019d523c9b0740f8a6acf3a7f27f57044388d5605ffd72b437045a3f7fa559304e334a07440f406054c522497132d58e05d5d238def5d305607691cc151b9be6123577b5bbd520f640418c2c18c0c31faec82d4bac3b260133c14468bffa033ce9661574dfed3bf53a59076bbf2484ecbdb79452ca94640ad4090e0b2d0a34449cc3dfdce60fef7cdbab6ebb3efc90f9213f0d510bc2ff78ba470f2adadc9b4c20877a308e3ffb8536dc23afb719615c6f2ddcbd8d08e2baf7096ee0a1831dec84f08e098fada494720864ba431cc861e94fb8d90ec8437d0f7cf76916f7c339fe28ae9be02014e00efc57be72f8bf1ac2d2ae89e25899e038feb52e1541ddd9ad828461bf2e925d87e2e11ede8176c9921bac4c41484343636b381a0ef209f5a94f627fa60b9a09ca12944a4012f6badc465de4df2fb81454dbae8bba48f59cb23ff33541a84ff9690301f5a9ffe9a646c3411a1a794ad9477d92994f7541a99f79d4cc07a1de3e7b59d56a38f666b84d7ecd0b79296e9333ff939af99a0ec8fecc03a13ef5421e3c0dd9e4cf3c7b280ef5f693a46c171464693610506f3f84d4cfb8cfd4c860531c04c33df38b38c71f5ec141ba09eee004bcd32c348087c7030f707038ae478f9999eec239b08b212c64824b65eccaaf37e1519d43a3eb10361a36bf6ad614149c22f95b4c18cef18f74c629ee462e450ef170238310420863841c614308218cccdde6eccc6f822ca24cf01ddbc125c7899faab593e2b7173057c53d29943442aad2484bc091754a857bfa690dbcd343cca3ee7a0b12a84f3d8c71cb8d317e23f94e6c729cf811691586d5a28a3904c58d71881b93b831d5e5ce21dfb16fbb6ff5d9219a5a67ba59c576b3ca8d56dc138d0a599534449cf3d9b7b5f65476adc439a76e6badfb68b74999e21ac535798c4d58d774a3140b3312508dc2724929f2ea245c42752438ce52ebc8aedbe4d77eda1d12d78171e2c72c376eb911e9c6f71ce657f9b49bdd26e54baa251323e39b1a2af6a59452d62aab9c524a292b9d946f640eda5f998a7bb8d2aea99bbe75586aaf559bc526266ead6f13718ef60938b2d77fd2e82d0a55f3120dee992fd3e09d9e628c4f1a311a9f34bada43a3abb597042061e57f65f222d73e32718f7f91e86a9fcb71356fe36afe824bb99ab371b5bf7e72cc345f53bdd664ae6667b7cdcc4fcd74dbacd577541d10f4549fa9b4d7babbabe340a825c138da6bdec4d5b4ff0870b5864d5743758e44aa3bfd89696ac16aa899c1f67f5c051858e60be98c84c9b1672ff4f8f4a4591e6151b31cbe00899ae5da9d1d098e03bb4dbe8c1f8d50c0cfaa061c6df0ada3555dd3343dd3b653bdfa46b5d610cb8e08b4a2719b8ddb71f8b4cee96d5adda335e8ad2100be9f99a00e550dcd4c0ac27954bb8ce13ffc0ec668d355e17eebbeaa41f7d9ef013b861cc367e687fc909f07e4df0175407e15e4af81347006f25bc89f82fca8ee5b5d0e00706208f935c89f410cf25f90bf427e0af9279490dd37e0e753dbb456a58bfa853622e18909ad239f2fedab135d6f29d7ff8353a6442a0dc43f835266b5d65a9ba8687330cbb22ccbfa2bd64529cd721887940fc67171fd421b751cee58d80fc671fdbf385aa789e851c66586ee172f06e678e1b6332b7a85dc239f3f75f9230734d88f97e6c313f76841cbd30384a014d4eda1848f6d168480fcae0261d8fa0fa8c092ed2a9085854fe30e36384477777677c94c395da49442f812c33bd973ce39e79c73de5432438ce099c15d4a69c4a7cfff945cf6397d4ec87d466e131e66ba0d7dcef67677f79e9399997b2673c480b04a75045e3ccf39e79cd367bbcf59233b479fd3e764082184f0a6592fdfe325c59583a56c77777777777777778f73ce39e79c73ce39e5b5c30f2eac7fdce0888c8ccb8b29c6b802bb3cc51852b0f70ddbe52bba186d70f90a2e632e7fbc7c0597322e7f6c1788e03099e57f73ce39e7646ebefbf449b9e9ee1cbf2c71fd639fd02770e731b0f1214b29a574be62538639c6eed3ae4b29a594524ab95a4908a594524ac952ca2bc88835881d198caab4447077771741bb7777df760821842474377f23649eb5b77be4e8cc927e70e784943e85369c431f4208218c275e352bce39e79c73ce39e794f1f4060094e06901490b4b09e5e5eeee3e84026c1842cae529b648b93b97a710a28b3b99ab278882fda610a2cbfd62f48f36dc98c51a5ddc68b303bdf8da9c3346376c8c6c528831763fbcb04e04113390ccd16b70c0177e383b26fe18373784cc0dabc4879c7f6419a98c109b8191962af33329a5cbeeeebeb93ebabbbbbbbb6177777b7777c7661fccccccd384e7f6fb8c3ec5b0dcd337b27cd860e21cbe5fd4f161a30baef065f4e18a306c4cc8144238e19c7c739a9d6a0ecb0fe99c7c714ed49a153927fe0f36ec577bce39e79c1325e54a29a52cd25e481f524a29696497d2ddddfba59452ca771c967429a59492a59452ca18690a8644d90086c92c33309965062ec73132f9fc543e47009391ff933232771f946b349f917490c5126580ae7c28777280c33069c25f8cae771ce0ff80eeec3eec3e9f22c05f8c2e7633670488809eba59dee3ee925b5207d51c3646e6cec2f3021b226c7cd72084382793f8aacb845fc8bde30087f9b8fba05c868015fa42ba8af34797917af7a95477ca18dd5b3e032dcfc9c11d1122ac7c7f318278811af79b932de7b8193ce79cb3bbbbe5ecee6ed84fb339e7d48674f505f6ebca46a52a436b7c8d8b8fdae45576b98a1abe98cc91ce2965cc6aa85ab3e2471d44f6024274811df0f58f463fbeb0fe91260c397e06f78b31c63e8275d304e0f82eb1827deb7e6cc60b4101aa5fb1eeea8856c8f1ae2faaf1ea7fd58bfd842efdd6fd5437725f8d0fd1f5b5e76b7df408263b0e70982f7656f8e3193ce4f82597a4832c9628e341a64150f88b91c7ddd0c3ff5257769fea3e9f42e02f461eec80f8578ea3ba6d5021c20622b430d5bf38f62a37147d10410a50c021098f68851c0f7e518dc7442bb457bf88011efc8b2b62805781b2fcc00752b2543b20238ee37fd5871589dd8802859534b6e8210c258f3d7ea112784902052858624905633c9e9f1f1af2a051ede2871896bfbabb3b43316c52b8f95a5ebc065c421cba4e804e2873a7ec3ae0173e932aadd5fffafb1401ac76e6e387ae139f6388f6909452b29473ce39a5a44f279d534a1aaa286394521d61e3cb97081001470d10a083ed7fc83df359be641144b84fe46dd51c48645e64704bac31c628b4e536612f0d3b1a2c96e3c7662d9131bb3b757767ff2967d701bff399f0ec29a175e97fd309a41d07384c731533d8e23e8157f644c2625cd9313b333373cb868c6f6d1d2f9ef878729b681afce8c2fac7da3a918bfb456621874dc58d9ec8620537daa229861ca268daa21b6ae1eede4b5e7a0b77f7cea2ddddab4c214e30c5ed2a5b54efa569a7bb7bc32be4cfe69ec0e8eede5bacdcdd5bcc160e875cd3c2f928b6167d45ec5ef2a8858feaad5e727787efbff27687d10d12680193969234328498216909ce0b878686ac38a14ff0394e18ba22c618a38c4f60155d1f01000c51ba7448282a45c40069e98399a22e29f8a04b2a0a171774595acaaa3862cad212c7719042530bac58f593c847318bead1c6a1a8dea4a5a3872b7c68d27a32ed0c9df6a88715c5694a5c78b3e8533a7bed4f5c03f922a577a0121e7c864a5c21cdf550173d4ce2aa2b2ba5943435b363c661d5752688e2505a028cd2125e886ca7694150b02eef05afdce723ee2aa83ee590f1cdf6b36d2fe4f5787e1f30485ff83f9f9db31edcf6a3c1f7f81e1d90cd6bf042dec66d3f3d7efbad03dab28d836a0c11c58fdd5e486758c5b06bc6054dd1b1ab9a30a4d587a9f71311774192e5c123cb76d8548a7b224f43acadcfcce3b3a8591e8f1447ca84aa2375fa1397d1d39054fdda3d9177f5f08484833265cadcd58a055b41d81f3e9a15440496959ea0723f1f57d31e7efd54ad97eaafeeab7f4abd1087a721a754f7445eedf9c2cb27ed559c95adb3db110e73353b045d80c4d8556bad15021ca68334acf6a9cf56ada3759fea7f3861eb63d867d8894b5da914863a0a83ca85dc747d701731855ddfc3a1d6f96ee0b35a87c7c3870fdf869b88aeebfa227eaf99df6c38f650cfa721436a4ad88ea4feda8ed44f7daafbb0af9df64257e8f2e8b6d4f3cdba1f3bb82df5f0a65e07b75d0fb7fa704bd170a9cc2d97e25acd6a54b75d0feff57c7d401f1ab784e52f8ac0ea7f3e30ec7a1fbda3fd10f20025589ab81f8f121866dc8fbb2881b1e57e9c0406bb6a1158a66e48fcd62fe2b7f6e0d8831f2cb42fb0ef8371e0c3dae43e7c5ca355af8e68526ac116a521943852f24106a521ae0ca180d64ceec06163664353ffcd7bfa4fd6bccf3c7f730f4d97458e72aa66c9ffc183c5fe535d69d33ab1fb80bc4ce8f3cb972fff79304bfe67a3a36a160f15a7e37770fe3cb8fecaf97c1eccaaddd783c70e0e041daf5a714ea41f39fa1a47b4c27b29d4e96b3e4b09253cb197e69faceef54fea9d79bbf1c65f2fcb8d35229b93db5a0d0dd79cc33fc3412e352f3f8a5eceb938781a427f070ecb644228373b7216cfd53226fc410974c631e1af9f4dce3426f3f9b1e78c1f7b1513fe207702811d8737faf5526da39266066ba36a96fc204858f82a8e1967764e609954635f9290a294c40b4a4a5051c282a4a48414a524bab8ac948497fb71990b7f009795921832c2335b082ea630410aa688c20d0f7e9f1ac0860d0108cb5e065f9e369f53b75d7c7fb22ecb86e4f26bdd76b1174f3e44da9fea76fdcad3b8edea7cace3c0b75cac09240481c2522ee3b0af7eac0b7b0b169071010b187698a2e50626d858da9286953550f03840a4458a30bc00f3050c2e4b50e142851ed41883ca9034e3484c18c7a2c4f02bfc55eb0d141056bb6cc59735a8b0f2b2155fd09857d87ad98a2f61d87641030097adf8e2c4cd2e5bf1850536296ae10410262432464078d952858f314ec4300329316861021e2817a248e19a438e3b51f08685528a15c4a0e1061c6420c3024c6869a18d2d7064e102132b54ac90254a194100e17dad36e3f6bf1bb795d4b8f283152cc4000c307f59090a2c2ebdac040515f76349295105cf058d1a4a208337cc50c2b15c08bf0aa540c60ac0f8d00514610c3d11869d9795a08082cb0ab5c36e3f334181c46dbbb24a5890ae079795a070e1a22e2b21c96193ae963334194dc685cf423b9811021f821003c6d1178fa1d8a10534dc38010a17708102d628a74f8a1da1ed540f6af72a1931e5360eb65e5632c248a31dc9c8d84bb4420ced9b0600b1171c8868f2a04431299c5ee04169d5eb65061254f19aa349c2cbda893160a018f2a0402bd4f0218b9b1078503650a2b90dbe0d0b1e77ddc41944435ecf0c515c391af2b2e81d1dd5515a38a108af390d8cf03259460c2a74f1a05025231e30f0a0b43cefe2d49a031200150f0a277144c470c2111e148d4b972d49070493608115613c28591b4078fdde01c12482b0a2020fca490535bca63c6948ea6204c5616fc1a58b1e9a2010304849f29a1300952c4e807139b21411e5f8528482a61d9a7cb87205896a5e9bcc0b60247169128191d7dc0651baca113b685a731b98c0730e08b6208314193c282834ac18557821e33517002f5e86722a44c830c583a26591022e01f0e241a959ba8ce0f0a1c96b8e99d8029322852a68cc68cd09808ae71c5013c9c1c31b1e946e820aaf3610f8348b175ab478827e01060c315ea6aaa19989def0c42a1e74cb0f5a98bce6b8892c1e9486be54061632b0583186940b39a7004f30955902bab2a0c0e441612e46b80003cfbf39950f9e77dc40b809186ab882855196295c4511596829c10a7228f29a6b6df1b249b318e34b91d79c0d0b1e948690876cb5f257001cf6abaa9bcf870f1d926ac082e465708515fc50e4658d440f475ee65de450c5cb629829573cd86504522479d99442cb0892a81516b4b04082388abcecc28289222fc398b822459197655dce2003c454a0a034c683a24af2b8817c364c46465e86c2828b0d7178598a09294eb8e265960a198430f2b21921c84cf1321a2680b8e28a97d5d800839197a974c032e4653a54e01283a21d28bcd146130fcdb956a1cb1526afb9d69197ad94da30f2b21e9a739068862998bc4c832a8a8cbc6cd39c8b3068898205c96b0e56b932c6cb6c34e7a81647c840e9c86b0edac0022e5eb601165e5cf1320068ce31133244a1c5cb3800c006369b063d563c76e850d5d0cc70f070852396b8e23567c38507a56194c1ce704fd2106b4cf1988915b09064a30435e736a8c5112398e2f11663aa1c795b7ca6228a1430799c74440a96bce6b6d86d4a785b188f93ca4c19f29afb61c5bb69166c1a5e1073e4b918637040a2516690e2435d818c142fae25221778c0acc86029d39cf3c00a0c2a30c36b6e464a0f5ea669ce21e0882ae4c0c16b6ea6892b5e76d29ce3365a68ba82d29c834ca0317425a539d7369029a3c96b6e53c2cbec0e3f20cd68ce7970a58c22af39f6321acd39fe128229495e733f80f05a30861b495e73364a5ee4e0cd549a73100c2d9a60f29ae3e9c2cb76cceca8417d42174a1102229abce6a0085cf08420946e2f43c68a158e3c10011547ac8c7dc78b5e64d84432f61d39d984db0f87b0175ba73b264ffc6ede1de98fb10319937ef8c46f77db11f8fd01bf4cb85910b6d8cb80788c32e03063c883826531c5cbb221e130616e07593031e44181552e7c66a52b4b17764ffc72b360100f32bec91290844d5dfe0fe2028bfa2742ba6fb4e11ec8c209d7a10c60151e0634e3fa338e7fad59d7f19c0febac331e81d105264124e80582b9fe9475676ace5ff9cff922342bfe922537d859648425cd8a337e54a9baa099a0a0d4db67cf72334fd305d1d810669e86c6d2fc8f7d9a974f43f3351d50ea6d6a225514d422d2e9350dcb1e4375b43b75d18bd6c52efef08afb02ee179316707152014df6834343737668f09df3ce25126281647c67db92a452cf5eeafd9b887ba62c9a9c7c8173fc539c1c528183c8107007fe1e931a50adc724881493a016782526c121771ff2921444c9d61a13d8cf5e7f9a4fb2e38b20521053a68cd7016de0862f71986068c84bfd4c1794e527657d90a6ed80b2cc0ec8762dc7f10762c7f978ee67853c212ff2d0fc8a869be152edc5cf521029a6b0a8fc6352aa23c171925aa7bac6f5a364ee070232dd269f765b7c23ad77ac90d56b06f67f0fbf1bf20a3ecf5cee71717e2a4299f0918791f1cd279b6ef69c7dadf06eda5bec5318f65896f592e3646f6d3db257cc817bb0cfa20ebce343304ef65917598675be8573b277a4af9724d2cdb2772467cfd891b2cf9c72ef38d947ce3a4e26b90c16ddecb1131acdf429c99a4e1dc6850f838a2ef6995be0a2fe83d2744fdd87bd8671dbe9318dc33a7e376a9ed6f9fe83d6c93e7b21d9673e9dfd8fd6819f65cff29dfad9db95efc85f8961a6ecbb0aeec17e43bd954d616445586a558824d5fb28c38677a9fcd5a1a121fe22f1b27bdf86b77e77429c7ef2dba17cca9d13bf3d74b7233d9464450d0dbe822196e973b112e3d2ffbecfb8b4fb54c43f525ec9fce7f7693bd237be137e22b13bd2d7bd04ff8804de26ab79fde98c9f8dd0640992b53d632cfce8968b6d324210289a3a8d8c6f3eb630ca4cca069286955c3635204d767e9440ceb0f3515180c0c0ce289777ac7e743c108fd7d16dd9abde67078fe7530794e5f440f275fca9fbd9f13c3aa0f83b5e489f54d6712ef64e2e230c8245b91106a11b08f2551f42fc1af93afe47be8e2dfb1ad5cbffa9f9d8c557bdec74bcfc9f1d1f5fc767bf63f53a3ec9ea7574413b9ec7ebe8be078f0fdaea6f59b781b0e335f8243abe878ed740c70769f03b9e3df656cf9e759cebfa55759c2b85d2543559f6a9d363bf3999799aa7e988601df7ad6ef618f7652aae488604de5367b926ab7bfa14b7695faff6d8b5a459d708cdba9e6f13dbacebb18b9bb0be92220cd24570ab49e2cf74415982fc699ea60bb2ef4f04081a76ce7cfc24f661dd6aad40f1675ec8c33a6291cf80991da215def32f7a6f66c766f5cd80f8b28b24ec000b64b9843a4e3ef185b4fc25be33335b66514b8009ec15613bcaca8e87a724edede8589c10aee538f27570461c47bedf48613f5efa58fd4a7c87e6a5fc2552f5abee635d687481ac95935560e94b24f2d2f81eb9a02cf0671e763ffef6fada3a4cea7341fe3b3e72413a3e365972eb33844ce0739f0f11e4b09f34cb8f77dbf5fe3a9e0bdaae6e83fff3b3cdf83b3e89bf8e8fbfe379870e081f9b9f65efe47aed8f3491091f63249cb3ba18f01d56e3c897b27af2eb0c92154149b3e4ace1d8e590eac479355c8abd13a7c472b12d56b3e4df484ca8b64645c637dfdf0983704ffdef341967d62aa481a06183b2601f147fe6831c6e20c49ff99ff85bfd998f3ff358f7e3dd56bb0d84998fffe36f3fb34bee76a46f09d8d3df8ef4a5ef04f5a93fd217fb544704fbaad9138a43022fd67193d5767dbd17b7daae4ed5ac3967906ced7ac6d8c6daab688acd009fdfdc4de3cc6f3503fae7b37ce7f2e7ee369f9a65cffdd9cf2a5aea4d0d164e996f02f79cee7c38c43d7ca3a6753c8e33df87cb3825bec471e65f5ca5375358a0d6f9aa09ad039f833be7f39cf339e01ef9f301c03df1e77b136c39259b4eb3ec85b0ffa98f0165914042cffa87dadf8f04cc04dfa99f7d92ebb1ac0bcaf283fd957dd0f5b5528e3d99d52411e62f99ef335fc994f07feadfa096dd063b10fcebfff8d7971f9445763ffdf4833c763fb413f241b5f3f91e901758f9f1fd66c2965eb40a42defc7e15843cb9c5a72f242504ea16cfb3aa95f55b3ccff2babbbfc8f8868188b1db536e8bf37ffae74777e9b2fed505c1af718bfdb39b428cb478e21462a4c5e3cd213e44fdf099c963f0a41bdb5b25b0ecd187271fbafdcc87a722f05aa13fa3473fbba9c10425dc73baf5790916f1444759a9cfa724edd56ee5382d8e47b2fae6090bab120d785eb0d0db9360fb1cdcf06917743d0c62e82f82ef6cfcf5853cff25beb331845f3b200682dffd421e73dcefafc45f881197ff53ff6efc4159e207f5d70fca32bb1ffaf083eaf75fdcc6dd263b10faebff78ec7ee0d30fa25d0b081956de907557e65ae38f66c93fc1b382513824c401b46b801c16c23ad9c76dc5fa8c715cd2ac1e8113a1051bbf02c11a46a00695210f080a57314493873d9454174b2079d9576e8466b508cdea278284bdb969067003f93ed811d238fddd3ac01cf66326ff51927559e61365a9bfc27b5897857eab7ab8d8af09cffd4f755bccf56eab2498e03b1ab0e18a29de68030824c478fd222cd131c37ead16f774d646d391d7bf847a2bbc97a5be4ee594b47cefa691fb800b1fca9d0f23bcb3723f68a0b022400c2841b21f3389e028145c45f0308a2df092352151c41594031a4d30a862cc96383c5834861b2688c24a0d4020e5703f25242a173a000ccb410bf66bf2f970e8b17b226fab4c854e1c3535b1e587940bae647c63611c5968e102155fbc314411dbac5436c25f1da08b1328b1460a54ac40a5c51f1f3ecbc25fc167f8f55b524b9448603941879a279876c884a460b3d5df167c1ef80f9f151d1086ed8fdf411af65b5e58567a22e9f2fd27902efc1b56b5f152e613117ed91cb97b3ebfca48ed8c30d2cb7e23aa15fc5a3ff2c7fa43979fb5215b4575346599326598ee93bef42be7845eda396940f7a46f7f12fd8282143db434193143520f4ba02045e5275e788268f3e18bf9604ee470f98ccb4a4d14210405dbc4159e5613552efc1f1ff8b48aa004f0c57eadbb6af1540d16e0c5f6d38e5f486bdd99e0c118f66b7df0a3c523c4041ec2575d31fd8e911bba12e333311d8941fa2366ee67ee7aea04e8ced390eb65274fd1fb23f742e01b81df82cf03855ad9f7ad1bafcc38a6f581803a208c1d4ad3e517aac2ef0448cb6dbe1188d7895fc738f6f8e4ddd55a0aaaf6600c18bf27b2a5980ed2b01f5371fbfd619741e829617b87ccab6bfed60331ec673f202f5fcd21fc4184fd3ab8feb1c85f48bb0ff8959d770ffd178b857fd52594524ae79c94525a21f39cd1bbca38fc505a68766c62d81e297d48e43bd873d3056a9d215efa56b546f81d674eaec99266b5678375c22cf96db870fd8864d828da91c03992d7b81286eb22308efc4b3619d9cbcc54e52ffd39a710b60c69d3a2a16b0c5396c314b18c266c8863cee8e16c086161a104532c5d69010a171c400395221ec058a2cb156c1005a146cd0b5a0b0fb43b3a668bb9fa958d1d9334c76071bb9f5835eb8a70286b5ebafdc4fd98ccc762b8490c346ebf9031b75f84398656bfca2e2b7559baf4b252972a2e0a495a55c7d9fb8948c63ed6a90e4a43e9a4d1f19ec1a7af7150a583a626c6c824ce1a9ad5b7a2270d5a6979ad14bdd79ee4e05dd238138ed0acf9708eb0a459f2ab8eff6a955fbf49ebd46ef2749f734d283702e4968cd03bd04392812b7f84254de6690885f564842fec4468d67c25cd9adf47f6e330f347286ab26442221edf198171e6d7cac37327182766b8291d34aa55f7e978ad59f3331d9c4a878ece366bce0ce32237f37e22723df6f05424fe0cc7493904ce701b12fbf1edc7682f8a2bba73da34cb1fdeb09ae5f33f08eb84aad6815dadf323a771f62fb3d5544fe4952f64a1cd02f3c20b2c88176890410f2efcc034c585c39624205250228c347a542182062d53962853c66c21063fa4204b0f61c0889100910e65d670228613bc00af2d34187a416905393029f170c6169712172a4356d0e8f9e2831c947ce8f9e2b92874e91f99b9b04f47e2c36ebb7d8acce4033989a573e81ce60542bf77571fa8e533272f4ce21becca362b478c85aff9631d3b4eec7eb007eac73a68c4b916c7913f05e7c8be0c06070b97b883494150b09fd65abca30a13420e87c539f15b7e31ca39e5947d65b71d91d2bb872163eee18904e7e8c4c8b1835bba27d4d22c6ed813ce4f8273aa5c7177378253e69c3de7371c5a75cf815732948e8c5a9086912b1f15640c4be68364a6148940922cbc343ff39306928943c9f599a7e9201bade32b9eeb4c65c765a5232ff7e15de285cb4a47715cf8abcb4a472eb8dc3a5383a7225a57a594d3a963f940a8b04653a2b09919dc23463ed459a24c615ae7089e9020e0f69fb821b4bd2fe5e4090902a60aac4f798484d2d1960b617b67019fbd9fb5d0867b5cc52bd6b91ec20d8464b6ef678d3800e35a8ed3b6b7f98cc240ebc4afcd82dac5dd1262a4c5036f8a4b9d80114c4fbc11831336f0408120dc38a10b38b25c81c1eb6ff1740fe09c7e37ecdfcf3ecb32a9d2051844a050841336c0a1050ce3c33fa0cb04fe17b3d688d460e50789ccee834f9a65a7724ec203299ce08222aa445104122cecb0c61152a00087257ef0fa5bfd3c2510238df90e67e704943b6cc1a3021ee69cb375bf0e085dd76710602674b62eed3e6ef9ccf13c223b9b66a16ee45669441ab213cc9e6660f870ee3afde99d8bcd3ab9cf0c5299b9a6c1a750a319d784c6192e3414a47264114a960c5972c229c1a034eb400ddb5f6bb39a68b7890685cbed487c19e30c17423818e1c409d888e2072a21781283175884a0888a1fd2a06e742b8c9615f9be233be6c2d66a9fc886168e0dd4e0628d259e004385223e8283ca11339ca0841765bcfe96114a7499438c0a54a0c60be4104436435eb4fdabad6a2778292ef6d79001182d94b88860cb0ab2711ae29a6cf2f77bd51a5687effc2227b09aed160fabf5acd5bb75ff91a591d45cffcaecc1f65068f13cabe6e0de8fbd735857fdd971e42d325ac2bacda752fa8cd1da73ce6e85d1aecec57e95a8fe7ca2eb69542202b55cecaf963afe5421731ffa717a785cf82cee891e5ca81383bde027e432f1ff6a75cede094348aafe645ef9365635130314c3280617d678230949c983ff2cafe259b4c4f0e163468d7b50d753eeca5ebe165fab443026eed97bf67c2ad28590a475997c8c93efdf5f4a39d5e69d66e70801cc0c272003c6071da278fd467c0700608e38830d2e6658e10bafbfc593c128a6b3e6f83a41e21289972953a6cc9d2e3f8bfed1bb12a49f88c0e6e09dd225019638010f50a06006461479700b99236050861816a8e1c1b74d46c6375c072677247ea04be800fe93d50dc239d061fc27f52a8073e067b15300237178fb7444de9670f295dc073a428e28277e63c7c339f09beb00bcdb11d99d56f9cafbf1dc0feec367c1b7f0573364fdd0aebe76bb33bceacc735b449f92ca2a65a5b3766b1eff73778fb0a33d56d7f93f76dcac8985635614c08d0f2f70fde19457a5f0892f0332aae0b063e89676d5aa2c16b689558f7a31944264b0f9630b7ecfce0f8e9dd62cbf3a90349ef19683b1cfe34470e08a193138c28526a258718024aae8c1081ee018810e0cafc77e66b5c62126314d4b6492908e8e90927cca921b7951952b5a1a16d1dd700816d5296dd4454c629a96c824211df1515d8acfaa7f8a55ab1a17a79306942943e65eb51fe39cd07b754e38883f39be250c899d8f66f10f81cfaafc333158fe15333fdf70c7a495750593f10db74ef63f7e48abd923d8021f2c8021481b4930789452caffc123a5645db9cd6d5eff3381a290271f9640ff49bdd347e3c8774efee44a7862af0138473e0e7720bf4f445097762cce91ffc1142b6fe69c1cbc94ab37935a6c09d9e344518e5e78b2be13a3ac3f3b22f26dad5e4536c12adad3117ba19ff840fed703611f5f3ec669eff5c2fbc5e6a4e48ccab8fd689fea82ae3f3dbd9bfc79e1c520476f8d8ffa5367e4040148ff004a582d18c75efccb6b2f9c434388dd069f7e0857b74168e438943ea54150a074e538b659f499e8983132181304858ce3039a45bfd23136de122233fdef54ff53cd2b2e31c23d3e2e7d9f1f25be733da5fd010becc748466af649fcb32e2828be7749d91539d919b9c17e3c1f509d9d1d96eff838ce492705bb1a63676e09f1d267fa81109ed5a52b9ba4560129d6203058f8469a45df0785232a47c6375944400cacd797ff535f769bbffc0d5ebfc14f223feb826850961ffab20bf23e7ba4ef277495704e7c681de706a865cac839710ace89b10b08a65951bb11b6ff90d1b8b289abf615cf8afe0d8b7e9084c5b42e28c6207facfbc8f98a2fbcf5a75ec139f4e114abd258b0d0b9ad72db4f7cec7fb02a41888f7d08f1b16eabcf5e08defd90e5db6e246d68baf4330ae3a5cd491476350853eb5031adf34530c080491589eeb060e567110131b033f78b5d60139c43a1980e32554a19422f935149e94b1a255de23bcc46a8012ea5ff83c7a953a74d9b3695455097c539f43f9842ff5b8756ce5ed2e7130bc81c763e64eea9305eb088d0bddee3e9068cedfa42ba2fe4a87ced95c47ae3a908bcf1b54aa419c3d0b0fe361576d1acdac13236ca457dd0e983e2a3fe6630f521c84f75a84e04c7a91c16e566f08404de4fe892c039f49bfe0df4e30904f6b28e4886e11cfa37fb10640891d628770ccea9d4f67c613f9b4b635f2dc8a29fe014b13f68be7f90fc960c36280bfc20fff941fdd27ffe8ffff49faf42bfac3756cb3df4c65fb56cb443b0fb868c6f7c0321fbeb7fb2bfba0dfe60bfc1eef4d3daf70b79a9971ef458be04d8bb3ec54d6f5e50cecd07453d99fa9f9f7e55ea6b3ec8cefc4c1794fa9a2c35f3250ca9ef33f39b8fb5bf25f9d4d3e7664d8eaabe669b33897d1a1a9a59a39aa149d9c98ffaa24b3b6131e91d27be008922fff46fdeb7e2f3c4fff82caa09c9ae5632bec95877fac85c632d7123acf93c734e204db6e7ed1eecfaac66f553b0a3dccc358ceb7b71f4f6694816356c48f43fbd90a6f5ce534b63f1dcd8346b46cad92837a35a6c1d2c4a516c1d4c8bad53a35414bd40e0b0d1abcc9e2a647c9365f2e743ef82e457f93568be08946392cc17f2a9dbfaa7765bd3ff913ff3e9cf20ece927a9d7e69d091e1c729ccbaf2f6148bfcf25a5398f18fd5ae9d1e942cc434a82f485e6ffc89fef3ebbcde90371bfbac2c12a4d962fb76011b08a94b2e140ef7c6015c7811d4f5bb20514bde71f14b53cffafe64a06b095ce56a8fe8f4662302bf527274251255a81c7f3aea87ab58b969060c2eababaefcab184588c8b7f73646314b3cdf82bf7eefea06b2b61963044be4fa5374be8754382cf12c78991f5cd8aed4c4a44fff9d9d34f82fdec82e6634fb10fa2ec43e96f4926127821ecf8b089b2c74e44a04f5d52a10f51e60496f94ab9cd7f93d7f549e69431e3aad319634482fe8cad1fb1451f1af9cee6d1ec3d7b2debb6e94d4e087d23f45bf479e8478ea7d56a166df963fe91bb3efe0f167f3e36afebeab6f95bdd26865d7fea824e7f9dfefa20d463cf1e9472a28fa29f71f4afa54b1f6362ef6a390e8553a051ab4af7bca272b63b4a786d47ed0c0ce8f457b7d5d7303ec5bf9e764e679db5f3a9de9c67ec5c2f63000406b6e9bdfe27fed56df3c7ff7a2cab8f6595db9c108197be04328ebd29a5f52e6ea39d0f7b61dca03ad06d68c36e03417bff24a7fe1376753eef3874d52ceaaf9dfe344fd867dbfcd3cf6e03e1346403a163751c0ac40d6802f7beb25c2cd0936651fa7c433b2670280cafd52f4fc3ce8f9dec3c0627acfbd11ec8be963ad9674c7bacfb39bd3d6129d449c3bc8d8c6f98725093beb3d1aedfb356096cf6588775d671249037ac4b15eafbab707dfb78b7c5aed69f0b88e39b498dd218e5b28f777df79febbb03eabf7ea395dbe85c62399f5a03a529a8148e1485412c99aa19113010008314003020140c074562b168341a87cae81e14800d8ba046765097899320084248190208300000400000c0008099a91a0db04997dc97492f5b8c9e634ab3e3e8f7242823a0ae857296a0832f3db2133dca4cf1316152cbc9fc12e011e712fa26b08fb8997f7bcb630ee44464b5fe49db07b57361c210efe34b1746427854f16265ffe9279117a01c545acbd631dc5172fae5497b9fab7654ae7db5c5535e21ec5073d357705a99ed5483a8399910b54887a859904b3e29c48e25fcad3737aa8bdf7b17444dafc6e7a537e96897b3462fd1987ff94817c55a9b0e3cc1ed4fa53eb362cf3e1ae532d36a02ae54007213544ed93fe5da9de364a84a1f4b5c6d155c7d1430f41b6b7ae1ecf8b328459ff6d6f956e3c501f956205bcc6364cebb0a3b7fb8283e794c9c584c7fad1afa81ca222be33cb4c69ec10ef65b76dacbad62b693458eb25af207bc4ec9bebe81b2a1fb5ce55558202616e6598ebaf22d9cdf7e28c2425a6ebce523158fe01d8e7b974b50a443e2ac0a367750263f5d995b55994b1999e69912a64a58a4b2862b531ef4772e792893d0c3118389e895ca2cef57dfe7210c102db3e837fd79fbcc8a24a2b2d37a229f52039aa91cd6b540e69ace8c6b3c99f92e858261c28070fe0606d15c1fa04f7f2a47b35375aeab5b146c2f9b79690bcaa61e21a35082127703d01538fd3ebb6fffff47c34f2f064e5c1853e3af89f83d6688c2c4f92ed416fc8eabe23feaa607f94ab3873c50b52882f08acd0389a5e8fffbb30bab5fe0a6d04a6098e376a77f1e94d8ccf2793029022d197474856351f3a80b5094b1e652cd070fa0cc32b207ee29262bb22aa797fbfbacb22c439daedc7c983db3e662b4503322413302fd1fc45e3abe95002446423c4341e3e67fc02c1c1ae285bbcdf67519a5a339fbd365cb5612cda85b9dc9c9c34e667e5f77f23480eae255e76444e4b0fd0daa5267e402751827598a410ebb52c6781ae3bcc9b2888c79b7efc43545a2f3cec4b205c7e0e7d070abec866c7df63aceabfb823b170a6c42c6253a077a58397e65b28e0696be3627108b452069e87238b2993d9aa5b5affcfa1c36231d0c86a77a84e5592badc2b2723a5d426b2bf87c935c0ab9abbccd83844655827e66cd04e89fe01e99b9c18ade17648f66d8778bb2fdd4afbdce849900a65e22ad420e50ae4f58fe0d317243c7602277525d9c97953aca9682e41b3d6b0d8470a02d3ec46b0fb3917e6ebc0c09f2698d9212041ecd2dba7b720e82ef29d157882f68d68230a611701cb2282f777c7082d9e33f3a2446a8900c208b92871832d6895fda480c9772d550d85ad372bfa090ea9ae57da1ff9784aa873d82aaf2a93412dad93eb8110d26cbc6e078ba56c835ce01b65fea342280c0fb203cda09328a165a14001bc3d15a6f5b09c2a323495d9217106dd589a294f1325f647acc55489fa549fe4298793e0fd2ff694dcef647d7aa792e258cd1e8065df70f75012d210ed90831e499a0c6004fbed16a160d1b5002af51d5cd5244dbb5f93557e6d3fcae7398cea137ac3388040a04a5ac8445e4b2252e089e72422c66172ffbfe37b558f00247d73c38966839cfda97400700b042802bc146ead07c52460046eda79cdd3549903acb6c0836d190b056a1da681a5827c49451d9a6e0064f9133f26ea05437193592dc1e236e6e6fbe61f60b48d4b3000232be13ba183582df6be59cc3ec6382b6b44c5457e10eee3704d5332d630aa08955c397fde2aca1041c04186240667fac73b6bf78eec4d67c640d05da20d3a06f0573d42648a6413f4fa681c69af28e67a8bcfb7dd3a9b2cc0e26f05bc2e37b879e2f221ab43b6abb7a4bf6c307c1a90efa6d56cde58a0902007062c3411595248501d5731f8dfd2df29a6354cd6aa539a20d78ef63206ffa996ed7bc408855a8c381f33e62d460098f7769df8407cafdaf4e6076602d31f686bd679d30852d500caaa131020839229d35cace44bcac052962c8a7eb607439eb3d00dc7162d0660a4a5993f36f04735be112ce4df92ec347aec461fe6667081836c29cdb4ace0fd36bfaa1cbef5646819846c4bf0e9a049ece18b273ca6c3936c664398381f460218e885daabce9aaf1c24c76090ba0d1921cc4454cce42eb5ff8e4b1357ca3f2d4397ec3a25491d90380552d402ec79ff0a078a38201b5764bd49233186e2fec02ce16e0ccd00c701d1cc27ae652eee94125eb5c692f6ac77be3e8310204c0c9c276ef0665a6a4dc0898b8a62e9414cc79f04ec10ef1882fdf1ce508c1da251d62090235fb1c702795550ea5f98920ccc912fd35fafc54b896fbdee38e8005ea4e1e7f084614bfbc4e152f4f6c5bf77e5a974dc862e1fb9812fe07abf10e6536b00938190a3f611c443f235e61e6105461ddcf81721be2011da7f503438d5fa168efa70516aae1c4bfeda11db4c9144d384f17e40d46900a5de8aef5e7af880a881f3efe730182d9fe7489963abe4dfb20cdf83685dfce9beb1ff211f3aa8ae6db9cf46f099292c72ac2cfc950a26f43e8382be393e62626b6e57ce6197823199e10e933c2b0720201a1e89c28dfb97cc33573591a636eaa052c21312545a07c2d735d0ba040185978afe6eafde605bc7b5e82130cf4e6c87db7e71f02384ff2f5211a20aedbff34608f2f3e9cf1bcb889e8767803bf5687679a9ad1f3e542c3737d10103e42d9a425bad1e1691a25d7651f56a4c9975d0fda237d5ae5d7c849f34fcd0f085421feb496df7625a6e8cf093c5a29c2d80984c0122b500f6ce6f51828e68b186e10741dcff8a1869af098dc9d1e54d6f66f5c9a33af13c917c666e841865928050410bd188a7ef72d0eaf8a761191d4c40ece4f85683ae958979e22dbaff27276b700ce475369880e34613f173136ae4ce24ad98e8282f685041a070f58b0a80c2be418ca925226edcc28441356ec32297b4245fd1bfe9d281406d24e7d098a4d5838e8db5ab55377a55e587a492e12a5e14f5a2b32b76c0211945f3a0f148aa453d02f101a8b662159a1137e1577459ee91dbc05f9515fe66382ddbb21b9babe85f48c83786510182750cde3638c9f7f8582373f10aa7fdd3fead967ac275ae827f7a6645da8f3c664f141b942a29b55b43b8391019ba5a549064f43a1ef0a89cae0db0093f1b7494eddc42fb692727867eb6cb29e7a4fa9f8350e3ce1e7848af80be40c88fe319a5f255c88c6a47774bbc33519528a5771d656318592831d4e5d18a7c4dc87ca7d12b7c1e08f0feb9ef6ba447d91af29888f158633598f8c583ccf87c2c95664135042223b7dbca1ca0614bfaa4a479816e0086360b91b6fdc493c89dd50880c3a0c24d02b01e20594031d1280b3902441f3629a063dccd730a09728ffdc8bc09d0293d847399c40ba7edafc8ae7a0e435dfc612fb814f717eb1fa2f9302848c6d8decb489265aa873a89be735f6aa5fcfcd2174a216941634ce668b22032c64afa34cd8fe20c95d0a2d1301b6c3b81f32366fe08993da74c80c22a63600bd8289b476569b49ceae744f20185527154646e7ddb8d46c9ec790643aa021b0f27672a05e362c71440f21ebd0842501974ef33b4281853cfacd13d2cd4e0e79f3319f1a58df0c6a36d220a5fbe67d2f355c2807a500f2f61bb4713a128738a9973e1c52539db2cc167ffc308f8399bb084066565c6dd0869a6385e0d40739b3d0a8571cc378dccc8bc1569a34e92b8e00d827947bf2ee2c20658e0dcf319f75fc62fe7812b4c816442fdd109831e39d214e67df1df4f3a6ac71bf10d372fde042bc083637f0f488204e0bf6e2021b82f3d9fc887cb2557149faab9b1ebe08950211b3a984c4a0af04661b820df2b02ebe8116c5624bc7caf028f25a1dae74ec702e2835ee78a78c974c20cb5a069d0434e712d94bcb2045a262b085eebe2c9e9124405d11875d2a0d5611e036b124a5472ac553ba44a9dfde070137f1c02e5c01098412376fad78c541962ec1381e2001dc4f72eb770510bc6a886ca996c03aad5d12e4d45542a072e55315db48d472b0b936fa925298f59aa3f7bace5e0161751b5d07fa11799391d21212ca8a174c2351185cbef26777ab31b3f3840ff7d8599c27737129d3aa168007ffe6d4624e47b1347c526981045226a8fd9ae289c7e1f22869603bdfefb6158f131309988a41442c1de82d340b7a57b85d97b0815eca9cf5459512a295cdd4a2f30eec231ff28d1ea12ec3a83a0013d6a61bde390d0256ba299489ca1fe7b79634821266eaa5352bff05a3f312c4ae2cb9ec55bf24b11579f0677e0d750265d4520a2d0e893a3dd285b84bc41c09c20169766db95e901e4b6904b8cea59fea1ca0fdb1e91c889bc58a2377be86f9c9fe43dbe813d27e1e763783007e400c1630c1a23f5767392d0b10001a1bcf743b75a3f9951441f822cfc2b832bbd270589de238b56e5ff2d40df43b9a88228af2cbd54c8bf0b8f120123e85e8408990823e2228c9a0e894319fdf522e20c5985dd5fa87bebd0c0481ea6baae1f290a3e6c1df37a250cf1df1ffbe1a58fdd8f8b9ca7af344a3b2a58916611969a65e1698f48b50601513daa0d697846d548d1a4ade887293aa07ce551ab1caf30241e5ffea2960a19e077001c1d46829e210fe7c7e26f6ecdaa7a560e45bea622b9c0f648361fa0c0edb3376554bb0c0b5891031c2b477b7c713e0ceb256779fcfcdebaee420ff12235d2a2f585790a0615912d51aa0617f95a2b67d822e9a5db3413b1d14450b8667defed8c632e672a8ff7103529b494304d55fada3df48ab7a7e886c8f110be9eb2b20376fff250d524cbff5150d26fadeca0c6d6eac867ca9bcf9bf7243a51c637889f633fc8203bcbb9d1a4a8d45510cf09a281769f5d518738b9afb19525b25a718a8886a826412d7f16472cf3404b13c45046acb6d06f40b35354588dc019c708254a87c4d91d70968935eda83f16242a8d63088ec8aa1126e38d5822d61c66c4387cbf82034229f19f2ad1d36fc09dafdb2b8cdc72bf16f62c23c5bc6d814a176280cb950f77706c21a12b4c55718ba8258c432a849409438a44271368ce5c4e3ab5e0b69802eeddb8a6b6a04cad9f9536d8a8f0bc2a0d78d3428ce5890be0984713d6f8af49754b43ab038d120bf2daef8f05b5ead42901abc8cb0a880123d3661a4ab579ac47c2bc479343773896bb3d40989a7a9275d10c2598e01103a8b06a55c274ff387a6049d0c24a2b0ccf2df1a33d85f85918ede4fd459e7978872b1b2d94144c11878d24e67b1c0eda89229a194c4a08326f99ad65685614ba879e659d85dfdca6e2651c52a4f57a49f9f0579987c8422af13e43b508c245d7a0c3a8998bcd284b899d32d15c54f25f192d495cf3d84cb1a0357523db80a311deec097f3af5141a5e96bb5c67225069eb1e0a156486d0b7ca55b6c000c4e19393f2131fdcaf0e6e8176e1442c93b95650379262ed95e30db96ccbd7f697bfcf8f1fac1c7414bfda910d8e088fe278545586e580c9c7f369a68d0b3f514cac9cb730f4f249fd14f19027beca0dce162851398521cdb6dd5bcc9455a9493b873ddc2d251102b3679a89d7c71c507a85be52a3b38418ae5a11f4df355f3ae31d943f0165b97e1035934761cac6d89790bce5ffe0cab4eb6ed910c061b97b1e3473dd18233ca42724c4f270a22f83b0aa25ad01b4ea65a764d5f59c41ea16f51f2a0ee68cb52d851d6b5146b8d30eb094d4c9d0349bfd48f824e597113d705fc72dceb5210262703c4c9938328da4317b3b9d0e6a253eb35743277c3d99f99132db1f8419ef3debe2cf3852a75d720351c8d97abae50e4f90c204d2cc446ff80f3dedd7eecb52a6bc9488ce35a86e0003dcc47d6df09465aa28c8baaa203d175aecf743303c033e096a57b0462ebc95522be51ade81b2701fdb5e39ad8d1f3950b2dc8e81bb13da0b2adf8f3ae78cc4b0530a2d94c1157c9114829b6471f3795ae607bef77124d0e7829c9ae5c061f38298f4d75700196f8ed5523c1cb06a65c04e08c50c214c1a044988c96825091a44f89d93bc004bbdcd04a2e4a07d34e3a13d2537ce853c55c326c849295d1c7d697b02ab866a5734feb34df7e23c05d745d11e8ce5bde924425af720091f80106e0b624597fb6ef75c8f242c3fc75b248a11fc040ff0cee0038fcaac0a27e592acbee9065fe94d877b649ff2b227be4a9f6c580f9cfbde5a304c5a9e2e150b7ebc57e79bb63c53aa7d67109dfb7a592107c47fa90192dc1a068ccc589b4e9e87987baf6649c822aa38753934c80027a6562dac5397e8c8dd059106dc2a51d1d74ecbfd44f05711946cb185cbd054ca56ddfc0567417da19db0b2d226f061b6bc7f27bc185dd453b8d7e72187fa713958aa3c599f31fae928b5d6dd0945eed830ca991252afb5fb68ea1c745127c2e47c5342684dda275788a9294e3c527cf8b1ffdd69140a26bba35f83534f09b39edc26a6997505df3a0a09e0360891d64044f4ab96c2361a5303fec0c8f1fe7a9c057fe495d2284b34fd6149fd38c4843a739d6874fea573a044692d742ab3cd059e74829c43c0b0a6a59cf2e8815015a42284bb2cc1f5c4cbf0bb700790b914c4f033bbeab8c419f5a160f3968d3ffead0409b55597df7760267ca1555b0ec1ad36050444b3be4c1faed3ea1e56f26ab300eb7f1ba6aea7c35ced849df838500f1576a5e56f9ec3fa4b3a3d091e525897ee4079b7c54c2558e539c989ad5a1093f0629549b84d644b347176a0ade2d8a4f07d3b15247b89e7a874dd8d98cd4fa920c300e7b87149f460620dc3c2038db4a5820777d7d8ffb786127776e1f1788643521c7d9b49f17d3ba095e86e3dea1fa25005f5383c27cfc458d08ad69312d661c96495b1b1d8e075ef64dca20d14ded09a0574c7fe070bfa75c77bc4740d27fd65a0aa68c2bdf453efa09cd7d4ec22b7c3fb7548e7a0cc149987c207d83e35e8383939517f44475d4e71c29411bd7b92728a8b71963c8d5a6c6812687b9814c629ae0e964d952046316a7a926b88f88b60bafbfc2ad9d2f0b780b7d60d50197f32bae75475c87aafaf6ef231548a12bab0d1a1606e03c8ff064285d5bef504a76f636323495bddc190ac9744e247e02095b773d3b780c45f420b0bf4c1d18b0ed46acd45fef5d3d15408390860bac307cd8587a743b2114322de19b466e8266379a84f0b2f6a91bd1bd8f2524dceca1b4aefbc12845e8742b58f8eb6fab9d1f2f687caf97aa1f916c2a3357f0f3536871742b491ed938884ef0f27481b6b1cf37c805d35716a794ec895240c4cb4d1b78d09a944e4d7bf632fff5f2b244a51a1297f361a40bbc0b385296bbcc853bb2620f92c766c893671174551e7d0d17bb36c46165b2a1e14218f06b3247d684589df04e58b2a10ad65a249c7b69e1413d301b0ae0d4a2086082b3eee40a62cef70283b0dc23bb0cc44c8516d6590251c91ea0d5637cb99b86f042049502333068a57dcfddcd499000818ef1d72323d69eb1b1dae36111bc91506bfe52d157f8f9c2fc35a704a83294c0be53fd50cb68b797c91f3d7d60c1edc8455f691de736f8f67788e61c8bb5506a0029e6b8159b23017eaaae5dc4439515f9389a578aae0f22b75776bc3994192e427ed5a202606602770bb182127853606aa4f4cf41ef3addf63075ee52c2f30df3e254c821cab441adaed010c5ae5d8fa91dc2c00d29d690d13bb432ff43113ebf138a9a3161711e7d882038d1a6ac8d584a13733e139cff4650d8871217e102872093831ab54476c020ba2c4a702ab8042640c3b9e6effeff0aafd7b98835453eae6eec21988365036e8d52b21eb8a86c94d2d5d411fa3ab75c14ba7018b793270d442bdc7c12df9c32eebef3948a267f08dc012094aa2d6a040c36e5b26a65766d209d5e05be585cc93f43c22397911c7cc1a15fff6856c967bedc96699eda5e9eb7b8957d3182ee09fe4243e86d2ba5ca075419a868217cd718b3e3695732dd4ea60be88dee40f86354c4e7d48fdd4c384d3c3aaa63a1e28de65fd644ed4c31f4a6e5835ab1bc134c990f3abb1dc95c08870a4b8fae5a1cad1be7857e432af28efab061cb60d9eaa24ec33a6b86bbab444ceb3d8ed8d8b9c82809d8c469f1e814230739adaed3c7ee66913318827438d47468ca35558c611b0193f5af58ff71f551844a7bfb215b51159a0a1ee53df203d21af6c5cd016ba872d30d05b7b46e1506530dd0627b59e53d37a4a36e6f40e1feffe9f7cc0c89b100d7c82ce2875823511332faf0c59579204dc2207db356043bc92f61a8b06d69a59b0b5b5b1926a8431fcf3ebe033a3c24b553330bd5aa4dbbe1b69f26b098be19d9dbf3dceb8de16680e073e3ddc533510da312305bff0d7ecd821c64a995a0cd12287e50e48888fb4ea68b3684c12bff85915c30e737e1cfd029ccffbd1f3e7ac0252728b3f3179a303b861ddac1219bce6527aef33177dde5d3b8f9056561aeb485982f8b5b8be945e43329dfc0562475ae32733fe62c3a0c2cd738193dbb1cffb3c04629231f71b536dc1638b8aedb95788428eafc6a4f8d58d9d6b1e290e1b07d5d167681511f651417d9e75aa28bffb1e8b5dfb26cd68384abe03b4657ec85e72424480d010779838f5a41e8cf6f5f8b59bc7931093f9d1f30877480feeb16802e5067f433e2505e21a8c2cdc9647f2cd25e4481a5ccd20288bd4992524c725c64b56453ac6b6ff08d731ebdafa52745e1dc86791531517f5a5692071a78fd148281f6a64c17825e0d09831063dfea7d27e8639bff117cd12de3573acc2d2f14f859ac1dc0b56d4359f9916417daa870c7f48859dda0942acea52a4fd966c44b5c057e9dfd6e163217cc18df291d53fe4401c5bd7cfacef254c9e0f038ff8326b4ad0979443ba07db0fe6996e0065597ae2d79e0bd8c2bfd310d74778c68120baf69f03ae07f8208ecddca2c11a2a2506d72765f19b98a68cbce5ce78fefcc38e2fb2b91c06a38d7846537646cbb1fabe8ea9c17e804574eeada392f603fb0e1753f63c522dfa6669d8d2392d3f2a060e5bc2ccbe856e7a383898b4bd7b3b3c23fb201c7f813a87b885251c0249180581c55a980c3f90310c8c3d54e480a2495044f5e95fa2c34ef8352c4108a459fbc19709758d44efc2f559463172af4bd546fa0cef59e1527e94d16992aae32a538a966eea0fe71bfc50c8bec22ec5d4646ef698426c689402b6e1e230877c3fed70fb1ac8e459b0503516e1b5dd979fbbc5396128ac039444c40ee94af580a2b8113992592a8ad5a0f6fa68aacf755635af27e0412de3981a940a4bc6c7ce8b861a522ffda1644600073c940ca86e2773c8dbd8d3fc71a6769f36d8969098e2f653730960b1bde4fb2b2ff89363fad9974fa02b0cf99cff10ea37952d205b6c98789be4dd658a66bee7cb8015b75a423183146f6c7b7b1ab587f2e2f411441e85fb4f9de746a3a076a1853c71659c528296b100b8b5ae364d1868b4ade12cb87458771fb7c96f0008aa3b15bb0f510162517c785ebe862abdefc8623e2e0a1bfd2f87b15b22a8686331722a7c6fda1c0a33c51da06bd8555c96889c9770e69a2880a76093478f47c795cf7bfb9662d6c163fc4e386831de17bc623c3611fd2e7e6bf869cb36ffda512ee709ac643efec9ca26034dd88a4e64cede8700dac5110518fe329286040e7bca29d102622d20ccf33e04117f2106414d9ae011881c6f61370ad5fb01d34e08d14c2acfbfa72c8de23b02c62f9e2dd3167850913c1e864cd7324ec6950df485c25c9380784000bfe7406df07217cf8b5fdc05828eb4791b042c3efcfc2577e0e6813633323a11d03ae131d3e02ec935bdec1b573e3d8f4c8d9f8ed55c319fa0b0ee67c920591b248a9c5a68c2cfcf53c561255cceea634528b39b7d148ea6f803228089e5318d8d5a4766253f0fa0ee5e41d4448e79fe26f60373035b4eeae2ba23ddbe96a4d4ead0eede9abbd5327d44aecdc1f3cfb10e0328043220d8585124205d2ab2d34aba096b387e9412fd4846f762e8ddfd2f3a51fdeb42de9092a8ee40d83aa4d16cfc27930860a9a4551944b34f36d2a1ea5966c5f956c6f5c5a4d6de751755f3b5a54f3fcf1b62faa21ef4348280fa1ad7d5c089fab6edf5d0a617f7b2db0250c7841cdedfc0137359dcfe762392ba1a5d245266c49eb68492762613915965b8714b5f140da0d0fd2bc4b6710dda1b223680d91a4f48918b91c6651cc527d6a09698c26dd4c5d54eff033d822974bb68219d60c4e410c16805c0841782c9b92e834097e23d11f7f885c6098c05c2f65cad072dfc1a0454e01cd83cb02b9e87305be56b493a9e3106068541922305672d1f57970e573d589e9bae9c866b89fc08f080be830258487ebb1612f88f0e6bbe491ab88662377d33522534ea103527556af446698486be496d8f72ddacd811e39d08448e6e37623f9d2b3786db431edb9dd9181426e2e0d6f2a3894265207af41576406cc0fad5a50af9fda8c6b36a24c2ed9b34b5f241237385b9355346abd770f52083b9227b93367d3d7e504cbf0ec37e1199d0c3481cb148aa62778e5a17071b9df623fc2633cda02fa8078b0f1c6db11b2622897cf31654a4d8059e584ad8304c89770f2587c4d7332a4487990deda71bbed9ced064afff57d5a5a33c95691e4e6714ec321779936b62dcb69f194d87e2b0ab78e827ad704a95fe98fc21f2f36ff5c4b0d3df1a6338374f041521b9063277f7d0703d8694921e9544fb00a38c7044ceb05e99bb3c691fb916d92711645071662405f979bc36b9c2bd1c695d724a08da6102d96b6351d9c2ecaae0a4d30a3a3b490d2a7bc3611686efa682911b09a265c9d776b47f3da3b086f924314485427820c9b6b7f96c33e50348aff576632af23c984df7b2b54dd406a0cd81b2296890f16b755a6f857fbda0fe7771fb50d33151fab5c53d7df5df6661815357df149df9fe15795559ae251f1635fc6a727b8dd621fffa5ee4f4ff536e35b51a97e4b19efb3e06e49238ee2ab5ab25a1cef31f860fc196e9d7ebdc627ec56d3dbc8941114b36248365d5b6a0787a606c7e6b3bea9544c7d9a016b0905c2cae75fb9ff4ed92fdb662143441b2a9479209a25be38a3db8cb6495b5d5450972641ae10f1510829eff854d6a64e5514eeb8d8951e87ae6becea687ecacd86a79cbfe6ad542d84ea40046efcc01efd7b6aeff497edfc19ea9d7cb1f4012be568ecf1578140454a5a1faf47ddc0e786722019cda130a645f0370ce6bb16fe59ff912b5ee7321734916eab65c1720d5c009b2ac1980a66c58a7100281ec9a8ec589d97d36714e13284030a23ee6318a4225c5f46a8d9837db34700d7913bc7450dbdefb51df6e4907b93d5ca73970206f2183b872b1f5bb0ab3c7de19980684029f8ee138cf7cff5718ee1c83a231602e8d1405c430032d3b0e50b5a29dd9d1680bf2d4f1bd1009a8661a774c25082c4c647242c60e9ce59de9725512368577be277030776133c0c8056cbd7713fcfe540cdd6576270e70045673cb2c3576ad49dbdc0483e8c7a6be2a0b7ba458391ec898e021744df7a1934b792af5c5560ab7b040a40c3f00a8a40265e7d38061aa324f4e0dc44e76f3193b81c2aef4047561c8557b539a0d0fc3aeecb11ae54c55f86e1caa35716ab3c30a06cad6d8272ebf50f9244ab9cef355b366b046cf6fc064d27088a2ee844433e04ec7054ee61de2ac04023605f361f9a8edd557df1e6f5a855aec71d7297e800d4f3f97c81f4e0fd05ff9128eb26e95a1097cd6a328979e0366627da7e450ca552369c5bc7d0967e186e713590881be97a9b55c9685250e4ec579a784fa8bc24973763cab6ddea69c8453b55097bfaca346815c57449742c1b3eeea50b77dc92e069847b348b5bd8da6f6002e8831e35188d7716e49f4c7d312159f3a6aa41973d290ff66a5c8658f4200f227a2028f4506723c8e5cf6d49464af4a4b70ae331dd3ff160b8a408b4e32b21bfbdf8822ca80c4ee7a1dd49e67fe745e5ee1dc4c11a66dc121621528c848b3228535cc8bc0a0cddb36b84271468c7647b6e44b497fb70641341305e224fc4ac10308c6e8fb4b675e7c744ab102bde5d1c3fddea055889efa84422da2c898bf2a6aa3be282712410bad28f82ae7ef05485a352c53900ea576f6663f08755f449dc56e0b2550093f196ae662bd7c1e6857c5bef075c747a0659355da8f4e05a6108ec71ccf1669e041449c9380799316fd2e3a4ba5d08c44c0522b833e54ba7563cd0182908943ca657324f4b381f06082748a37c8259e926d521c5abd5c72364003acc155409b15e196540d5507c8556beec130edf42791ae24f6ed4218999c09d5f75d26d553407b59b74e2597338c44695e005c0ca1a4a9dc6f0b94cb1e3b079728069fa2098daa67349afe1e10c9daf2a6bc32120aa34ff88d3b57620e2066060d66cda3a32637b764d76e227dc7e180c8cf46f2352d305532e20312a0d84675e01449303f34403cb58f2910e62780525c902a377854db803b5110e5ed20867ed792f017a54c4b111fa2d2d0889e5fa35cc101b5f2f2a3157e7c710f0b541b6fa8243a7f451bc97e4c2adb903223a6abe241ca3f3f2487072c1b1a2a22b0fbd1495758d16f9a260fe609e98e1afc50ca60c2444ca6c428ffedd360b0f59a60ec221eadee9a8bb07b1c56d5f7f9a68be6fa46c1b343029f92f9f64d6c2c145039651268200cc8377070c0351cc4203d706563dbaf6cfb74935ba18f2e4c93a404376be9857b8fad9daadce0b1598161b321f6109c679ffe399d6db920734939c9310230189f78c5f10a90dfcbb723966bd0f48039a73b317b6f8f2abadd3eff17f0b16f6c68f17babfa2f5f996ca6879e236d74d58a257275496cd8f5591c6fa09b07fbfe3477fd85c2c8ba7ab26d01f07b171526a1484658824c980f938793816a17d34051e1b85671c2df674ed35076feef6aa1feaa5621a5132bf3f1fdbaa13f0e21b1a0c1ed724cbb67365ecc37a916d6ee61e1e686bb9530570e862d4fbe84fb94c1eb6aa01ddbe210929cb7998086cddc8d2918cc0eb4aca4592148022b5a5a970420db37e801ce6978480d83e26f12d6ba69850c7545aed8577315f34e39086eb94131b2197ab8e6e54bbe0390a642a97861fbd3d92b1c4cd859f9888fc42ebe95e4acfc0e956fe9177c914b0a2cc7751eb83fdf1c0b8b98f5dca84edb6ee6b7e5e4170a58bbad14398ca7257508ddc6d4e3ad51b1108e639e88ea372282b7fb9d41ec58ffd8976542a26c7617a37c9d8cdc8497930fddf7bfa2e88a1f98bbfee1291dc4be74ff4119817ac833e18f49f315e5c24cd71f47f22025c73759fa1ce4d43405439c0d7be6015f9a728b34b9fe6a960fa9455e5d28d27285bcbcd61c582119f20f1044f5ee6ee52e90bc44bd97c64de35b25df632b382bb1ad8f06f079c6bcfa944432e1ca96f0c72203fbbac21daee47b2a52f4868351a28a4ed3ec4975e7e3081942cb0fa745ceb29c07d786623bdd34d9d7751a3958e6f00080040e520bb76d693dd8451784414bad412c366ed74b072771636d59fcc6584302be3c66c79a5bea158a8f08f6b1c76b9790b0e2532a3d5255046da4055a5954e18bf4662f2c4a1424e94c35349c32c20d270e9a48db0a445d66126e34b050bf4537f3acc59d6a911c87ff0673732e4e0390c66cb6e1011a96feab427be11d39f3a3657f8c5b8579b91c52bd5077334e82e3df9afca91f94eed4553801ecc9353cbe3bf4fae39a49f03c01d06a96378212a56930aec8604760808f1a0f06c981979874c76b246be07d36e24bd0a4eabdbd822e872b4eab2445c8164414a4a171dd7d8733f392af5176a0ea29b922f90d901440246ac562df4a315dcb473550237fbdd74977125a5c5b058db178a10a0d7a2e5a949644d230f82f467296c188bd64d781cf9946097fcca466fcd6da0aede3549d3dd2162e6da833b4cad46542181883489b967fa054af1c25b3b65ab02249979682c9e091d41294e686ac3fcc51116618349bf40dc20d5d4aef278bf5952801c7b83d5340c8d9bd654f5eec2af0aab278c9e645c514e9093df4ec4740cd4402d457c4d1a420e02253f4d1ac00e55295ea9f110fee874988c7ec231b4f01fb539c46221d5c2377b44c287ab171d57a215559663d91bbeba3c65f515c29f97df47dce401987cae0d5c1394351ac59d60f15bb5d701a2c03a295db0384880e87f89c69d15f27efd5523e9f86c3992db16478d98f2127126a4c20c06bc65115d1eb00e0e549d6b0a07de841d1dc84c6d9888cfa2ba8ac0f396fb3fef561255f2e0741adecef9189cad2172df51700e47b8131713f021adc3bbb8218b300151044736891822b78d0ec1a00a3a35484dff4fad1f5a33ce31543043168e674b15a94a06ce09f31f2e60448a1ca094b94505e11d39171f20b2fe576adae93b7d37560c6203a751c4064793c406490bd54009e69c0a34cacb942aec8ce8663a2febc865ac86cf04694480c54b42a29f4a5c710b940a592811cdc63f20a5459e9c4a0b123360cd515d848d2c7027d1527d69f0418322b74b6171e86d29c869ad493fa01f292f9042906c4555b853d4d8168ca986e570a5a81400c924a4a9b292a1e11509c75880c0b66baae016ef7b506b495599fcaff0b64e8ba24092397c7bd8975aeefa0b47fb6ea9e2fa979d1026dc840e858b749262df708cab48d97f59ca262bbad2df117272b7648341cca9b1f4143dcccfec7549432055a898c98fc88f864c0f2b8cd7e6f6a8b2e2cb2cba279303db54f60b2bfac6a53558e3021530b873f11831dbac0c2edfd43262c94b02c94ba3f7c8d663681f80036e91b44c71e95e9a5008af374635469a3d76517cc4a2ac69dfe0dd8f28b36f6437dfbe5ddb2fa4cd5648277511f7546709d099841598ae711ae69d7fab5516864d73831e396c1502b148f8fb9f2461c193c56c05d0c31d31d6e76a3c07df2a8ba24ae229972d53cf0f23f012e19e487d2620638ca2c7f3bc3e4b4bdb8d87560d048ebfc674f130bd592e6a8d5cd681ae919c4d7331f3782e7f100b85b32ab0c59ce87aefd2de69530373440f3981b6681a1d9f47b1f70174ed47a166e47b73e077abef37582603c7c7ea5d4232d0ba90770a12b4ebabac8156e20fb65b763db6d85afab7452c4a32e3552d76c6a33e0650cb91aa12678d5a2686e3cbbcd62ddb39da77d5ed9332b835e4e213f4807bb5c0fa78a6faf4d0774eba0ada2ecf113c2b315e75899e1837e16484466c52cfc0f3b8bc842d737558a0399d7802a1596b5596cad6491b9d28ecee4f64ab652c6f66f73404089ce58bc34a25b9f7724434f9ec181470d5fbf94ebb0daa1043277b0c1d0588386e1a7b1a95bb34963dd9300e9d6e42cca1235479bf9f8e12c86dc685ab8ab2d609af458255e1073b4cbcb2414e976dae578cd801d55efb2fdfc7ee1dc415413efb5f92c196b49161034ecbec9072f19decf4a83c6bedfc2a84fd7083450ae03216225db80b4dee5099e80f4a206257295c27840f3e9777da1cec705d0859a03973c1e402bfdd6f5616336df9e7348666e9ea3138baa5f08fd69c0cca24e8f7c80066c1b40bd3dbc70eacbad1f6193dd4abac9080aa4711790765faecf1bc905b498df50c73964dd82296cdb830418a22ae457c34b34c07390d05efe17eeccfd16826ff00682adbef208e965eb5a2edb23a5a0d67db0522d4f6b3c6750b43d2c26af8743f2fb7008936109e1ef90a7a7bb23fddfa5e7c91422ba89f1be91441846b7c40199642f499ccebf385d9492b73f33c699c85c811b09f07e40b9862775696acab3a809b163719b4c64ca61a797705602c724018eb0dd6742993295bffe511f06e34b56f41ecb8bd24d65cf24283841d2dcb266a66674122c8cab851760d077244e4dbfdf1bea373a3f37440c6c02c574b1e2a4cfd42d6afb323b50fa13486a9f09d6d1e41f8d12a28e046831bc843a20ef368fda14b2bb1d6e7543323d8b16067ca3e930eb9c02f5977f2b735afb2da3aa1d65603891c9be08d7d3ce42bf97ffcc61b1943c698ac666b43908c7f9412a9f422a174b1625960d88a596b59a32761209b566a2071193fabd1b5c85894b6bf6611f64fc15a26273887df43a99afe63946f4b7e011d4399710c4ab581370c96e943c3108ad1289d48751e2f724d8f9400ebef18fe51e1a62d2d53ed64f0c8e68c8fa5786ceed51bfc5ffa504b34dc098308e3770884a52b5ceba029ced8fa2e039743516cdebc786b08dae1db3cc82b29e92846a0468d5d7c6841e2be5c3532020cbc8580d6fd5adc6065795a9726f053c5b88adefd76a65d8b7fc1b6eed42f52146ff5d0bdfef7ac50dbfec80d789b90dcd37a02d6ee38e92fad0464e039b10dee6437b4f08e6a6c5bf0190543052615dd85ca169d33258ba18a15e657908a0658d4177554e71656fcf719da98d4394c840ac0465bda3c1414260473fbdf812a3aacbfbde06db207ed09c35f221d2069cd88adc9f6ee07535deaecf093430a6f3495fbf803b425025d185d6cd6fd94c37ba3a4a39cb80ca949e2cfa40848994aa5ffd54608190487c2c4b6db47590a62e53753bcbaedb8faef1661afdc6a52aa452ad33c264951126fd7bca0e31cc7618dcbfc150b8c5b5c5a49ebb5666248c5cb04eb5629310af4ee37648a2f482bcb03465e0f4986ffb18d59099a67bef0b56b7cf01867b408225c05b96dfdd79064d3008cf9e2a72a7abbeb7dcc2cb2aac6aeecfef411e89f93e7289750d01b16e2662b1b623d5cbe3b2062e992bc4e4c63f186fc26e5ae84a85a977860e90e1f692f1f70b7db306a6a0ff24c3e2a7de191a7b1519e4ab3b85bd204da473707b5088510a62cd8f7415282f28e0e999cc7e54f81db2cff2b6f6f421d589ff71146a00888e7ea89b4212f94b0e432045ba37d42b43b8962855acb3a9dc2642f9a8b723ff5cfdc9cad5394d3a9e866c16c151ff44cc4b65ea0145901a726d09a91a7657ee4b0a808bc8fb13d661a01c6956d27f17f639f37e09fd40bce03e5b16361c634397be53c84cd09cee7bf84b1bf5d9c59e10623eb8be0766d1bb890e8f3c90f8ae24c400c68ac458942d0cd7937e4589561591a0458c5a1fa0c0336890e40c82925b9082fde2b8e18dd401ec2cf6c2d1d698fead0ebf078202ccc5ac73906d1004a050e306c98bf30a319c3265492186c0e962d63a161ac783a907b1514843a509b1fc10e07c90b28d39ade2d285aecbab20e20be0143bff24545235c95f9b7a2630f1d983fbc939aed3087a3e028f848cba33db8fe89c5ac95ba848dfda8dfb23b47fad0c1376f64af598f063bd18864a792f18526c4c621b134ac213bb3f194068e75a8ce06a9c68321882083b2097608f55c1a2b91cecffdfcd40ca5821dfc1a8e036c024bd8346b034c0720d16140e0823281a8956ee2830e57ebb643e627bd210b0d87c26427de6088ab546fdde63e0c8941aba42b221e512a70e48881edde10d911a314a2c0b550d1c1858c469d6f071129dd3bda2daedb08c71be5a2343e84a92c9a0842a5b2f367993027e4986bd36a618f7e7201df098075da930b9e8be8dd62edde9ed2e152e9858b4021a489a6ad4f407266d2dbfdd0c1482046fc7cec778b0699c548809474fc50ed0e9121e9047327999681a7f8b8b6214d4313893280e357f48d0bf737b822af53ae7b306ad781165ff492e05e6e618feff1512f729d88320d71dda71459a3079e9e2a7aa2746972b02d8cdf12a55836dc5e21c676ed62109ea186c3aff445daeed92ba82b1d1bfbd5b4c247b8025127de7cb353c1f32ecf516ad04c180196e4cc95d5fc62872c1f0720b92ea71a2aa747a10c0d4f382a4a49a5bb45180e50769c7065e5e0579389bbbee151deafcdf9df5aba160116ce7d8a6feba6460d9f881540061d9a48cfcc292c925fda83e66bd26c30ee7e3c3bad0652e5112bee1f90c30cd02efcd281b27dee8ec02a8f96b2bbb1fef04fa095505ab941c0dca43de5f19fbdfd00fabcad205788553da6ccc3ac3b54c51e48d16291eb13d8df4c6f342e74215bc4bb72533fe74d6a0161cf4fdba8848d04678b1e73255acfafcd11fd429dc1f83519cacc9a08ed74ad0d3f07d651edf734ee26c8bdfd7a6916ed86786a96b6cf1862a1a09384b09bd6100fe63ef753c03c9647ef343ab419ebb5eba8b7205490d56592a1cd6223797b077d054911c5a012b2e63a7efba4062b312eab80f2691e315ab3f8a105b4a615e9f7fd986b2a2ba1898f4de1e86723659c7149449148307a0d176481ed05b9225f6354ac396d6c61202225ae1e75e23e01f1c975b73639ff3015263abd7f75d36a81ac30089d1e087ebc1192e7de172284195efb77e4db98b28e2579620e2f8fc7d4fbaad99e8f11e1e8f02ea80b9c4749cd791423565fd591b4efa9a003849f0fc421fd59b05948c278038c6c219081063ef8ea94238e38e45a5ab3159c78abd6c7f48e433920e61375ae923bc972582e3cc11db35ba20c929cd015420c7d18b796d0bfe4dc6c229eb1a5ef1e73dfa70e6f3c0de3b59494e17850a0fcdc6cacdb509c55c55f27f19c738456531343faa12bb998b8d4a7bf8eb83f7fb1264432564321545640c40d10cad4f3110cbe766b21df45b5ba1168404dee386a2f6f0dfaea035cf02395d0723732b489a67444ba6af5a27c80b599d448c66930f9dcaf97ab3a2c1b1f2cb21930d76149553b73373c785082b1894930a70119924ca0458bd9ec09bdbf9fce04c43d5799fd8e9f08356090af6c873faf9f1cb1df326445542e31b0aac7025df49f67e89c986aa575359f6781caccddb6c06d85b83b99dd03e6b11bc799a5974c26fac7b54914b091cf0468487c785818075936004f46e202be1a1e206ed28c30f2c919797863a1986288b9d3448722dcd86288dccbd100feee167963a0d11db273ac7bea9523e851cc2d3c7c4c1b528c4e05979d210b9327aa5edb3c5c8b1c31108a6eeac0b1538c742c1f5fb081ef90a4783abf5171de6bd12c02b39a0a127e5f0bba4f7642957da02eacff0e130d9d4b7493fbf0aafc7cb2b10f4a3c7e7818b7784a504597560bd2332cbd2efd943a0681d63d42764c12c9492ff0589755da1672fb8550e51b5c037ce50fe55ad90d9f5ac713e88b9a01ecb5fbca5a587a9d291c5157ba34cddc5b9652c102347aaa09f65cca1c29a26effc17f771dada2c802975f967e895b5763292de30dbd4055b09bae36ec4566c007211a00c47f020e27e53924398acaa361beb18e9550805bb94f257c0c1a4761f776232856b27807d5fae6dc453d69c2cc99329e46ed9080a429b7c6c37882bf3dc02bf20f74e27a5150acd282936ec1f6394eb5552be442837587cde71781b398439895393a406e22cfe429a34e8a6ab3d5de75326bab2666acc072608894428042ecb4abb0a3bdce239529e0024b3d2f057216afc256bac9b72935d12cae9f6f633d28fc74b50a7c90598f9543f2938c8c355f4cc8bde888d359dbf1656dba999c5870493d730d71bc18d321e141b69c9a0dc13561577aa8e6317a934c1e60eeaa4ebc8550391c076d6296aa2145504ea2e2d5898149ef99da420a92dccb0f302810695e9e041dcb077deb8b0cc79fdd621cc48e0b798b85a32ed62e2bf031488221b3765c5449f9d183320f8e9ac7aa77949da7956fb2b44542b75785b94dc2d949e15037b605ac04bc0362ced58c965cda5e6b92bd36623fa009bb4c84f9d0f66c0665e189cb9774143aec6a9d048fb37e408d8d05c69aaabaa56ec5a2a2899f3aee7dc1df6cbf951890f549d82732930181c5353289f1071bf9b6a46a3533ee1e4552cd204e6b5c93d4f17ef6b758cc467f4e03ca05891a9f52a01c84e0bca10f928f4777300721da8653a6ed52429e12804a5d24245e54fd753ca36ae481342110ae4315113db1cd53e715fc00b684fbd4f55ca3d3cd4fb637a5fe8c15efa5cfc4858a06856be00b74326604dfefea9a45e84e4157a6b202200f5fa87fd664d6323601fdd96e9a8513458a4d5870b68030546a1d4bc9a4b7ecdf53def95dfd63b61c2e12cbc2e1854d02ca86c66696586e0e5579e404d6528b3e497e347b41963556aa26cca3cad9fcfbca2cdc8efb3309c648913462cf03430dfc217dc77e3afcc704d759fd7388cb1d9ebcae93f8bf3681f477c983443cc47acdfa3e802dc1f44607f9c244309325d30e14bec7e6be9526be02a990ea7632557b9ac29d3f30a734e17b0caa3011a555326bd5bf6945e74626a3c84c776ffd532eb9fb1f64f5cba14f1c8f4b10f273e1a711bb6374b2e68f430d731cbbc3e028cedea3c99d41bffdcb707ecee16e75ac3de86e3c324f384016badf871b033ad9fe91b8b1d045670556c4fec10a00a032c0041a621dacba32383c5a4f722a0dc5a66383250cb08531b3c68b2f7cf73c3c1054c759c8007b7e33a84029a5662fa6b86a299b3dd0c0fcdf27b3f59ac5546f20935690c0d1d9ac081a339f99d303bb5233575a02768f3e2ed8f686223df6c3fb26078412b719c8983c47888d8306fecc5a6e0d8a05d212fd164b76af18fae005032f4eb6fd5f3d4cfd701bb296242050e607d05e1947925bc750c2502d8029168b48100998a1ac1290784051aee98f99ff9aff4b3cfb5e5ec473157d7933bfa5ef49fe2fb4c08f5fa399cc38d68592b14ffbc0e6829f9aae22c71a269ee7baedd908960d9145096fd7f2605cf913f10abd08cc93321a8aec645f076045c4517c08cad0c8fda0d7bff423932d398151c13650a84b1366323e0d03af30049de57cc6ac3bbce3e7d148e49c8fbae89d53689289f422e17d0341796e564bb05c92fde30ab0db5e7c1f96db073b8da89c935d9119b726a1d9de9234beea20dcd114c93c8fdff205439b418c96c5233221c70196d8a99ae49625cf6ca662fc32065382d9892b608baab89f073b6a0f289fac2e05be4b0109ead6b971fac89fa0efae322120cdc32ada6b63ead528f948bb6f6fa7cd15e2462666e63c988635cbded8a7f5316e803bd06c0d88d1e3bd988e948a24898dbb27ece6ea542fed349a8e6b79b6079f8188fba31e88dbdf5777f93f5d4cadb16dd043f41668166901b3ea7422a8625408e940ab16e1ce4e4cdc91b9be549ba360cc491ff63b515c9422c20e69b8a2f3c3b8606293042cefc87b86084ff39924aa31c0348c9de92ab27ae4ca44db4b23ae3efba52dac62050b18cd2b6d4370da18db3990566693c85656661057c7614d7c299d9febef75700d31c0a2b978948628e526b2b847e66e00c72b3d3db5319ef56498ed918ae13bbbde99975e7c810bffae6a7580c5031cc0df7f84a1fb292c6cdc5f67a73a5ab87f18992c58e42b0b02326027b2df59811b50faf0a98ff5f7bd3b47041d71c88e19a1c52bfba7523ce0fb0cce8cd5379b0eefdd8df6e1c74162ffd2d44f293cf5e33605179f71223daed8460c4a287d5bd1ef4b1b05d61d9c555f8bba39a1cd3e5ed5456a9ce7053e3be9b3f4dfb5a22d85ee6002a9811d0d0321c544d547d1bd3120d0d15d4b5d39e097529a61466ad528ad8d2c5d1770bc859b0f3f585ace64b3ec67219d1f5659efac734ea8a5bd6742699bcc18923a7aa1b8945a2c43148a2fa4876710bdac19543aa2fad4602dc17b46e1e0daafd015441dbd56518ed7edb34b49751cf5628cbdbd6815dec98e20e80acfc177a7f424b6b672b88927508e7e40f41b9b315d86b599ea9040d1f37086f5516de176fca14324f3401ce1d373a210874e520a2c543c1d28fde692f1b4b19eae8e40e6e876f89957e7fcac7a41cfc9edd935f8c42b49ce2732cd1554e89866d21ea8c8d5a17b0da8389b32a32214fa9ea9c0897e2752eed8d763bf2d5476227208986f4e545d04e653db6010326ee07231822586c29aff77be512ba2858c41d606cdb0f9b947e9239b827cd0b7d6e78b995af90aa1cc365f2def51344a6cf330130c6a9fc5caf58829e3cb58514c081cd09aadc88f6834aaa2cd3ef437b887c8a41bd3ffff84880e2b9a27b24284ab3df1602e9f5c4550fad6dd57f5d4c8ccdd375ac42e15c18d44b9147e61542a7fd69797fd0d01eb951fae66e2c228cb1c2f9cbad25455877aa157baad814550f2fcb01f057925e414aae7875596e7f51d80523416944162095656eefd55c2546b5b0d6baa33fa85676aef18076094105d90908539c099b75de0a7b61a5b580b59d89979a47bbba23f6638f9a34a7874fa7f70bcc29d581a551b3adf149b67ec48de6b7414b754065c2a0d23e998bb49bc7d7bec6ba851d46f212ab83df4117b711e76d2c7e93554d48beadbd1cc789b77aa89f43380890a1f79f6954aef8aa31f93534579d95fc508915ed5057351cf4ca96f359345a3191b2592f9a4964f221c6421acef71a3c85f45cf9d1b76c6f48af25ecc223114514c64fe90cfb90d1b4da1a169b89ae610776366764289ddaa93f7ae54da39e9040c60933923217312cca2ffe48d0649881eeb154d4af3e4af260ec7797532d2ea084a0528cdf0469ddfa6d11c8eaa1155b63b3d31a53dc99a1064eb199ae3e7ed9ae5b0c3050c9a24c33bd2cae68e324d62defe6d4775d27a0a379ba36c98d46d4c285ca8b15f24a93deb1ba1f268260d16d88c0741e83858dadf20a17b9b10d7f6f0992ee045e82c2e7fd9e1cc33a7f4b498e5fa313762862fae2b0ac433c219f38c362526011b6c74e6b3ddbebaf62f5633d4700be4f8752499161e2203a383d753958a9abce7dcc20bc53fd64b2894d7fb85769a5594a8f166f2762f2e193cc125df4d539e419ed9231fe9b53f90f049195f72c7cf0524f3bdb8293d3f2693cc8e9dc467c5e237b00e9f6eeecdaafeca8042bbfb96cd7e61ae2179f28040996adfd890b0d708d33099ffda6282d3e5cb45754c91b217f994657ea30ef5e61e533f4471e5fcf6daf35bc42c5b43e28a465cab57ac58a20564b66b44009515a9f950ea06197deb0c8931ca05855d9ad5692008db260b0df7d6d9c063cda08342c3b7fb256714e4ac31053861e585f6942ea62579e725e901fcd939adce56d74e7b3fe73404001a2f7468d1fac0b3fe67c97d37e5e1b60d419d68cf3622c055393ef68e63270fdb7641727c8d0625a37aa036b3818b86a9fd7e3a53301c792c6c019ff50ec3f6a37df6ab2ecd5ae176c718726ab70b3b26d8ca65533a23540fbc005060f5e9aa9557ca4d5cb7573642ac237532f5542654a31660a8b864aec3f549b93f03be1cc53659ab648f11b2d7ac5c39d3500f201e90bb5c62649d162c926bf72dc768ea3d455225f0c06a86fcdb0ecadc94a801b35c6bbc2b72f73bc6fdbfdb08502f4349aabcdfb23c3f2196f70f8819c35c7d380b51f4eb185280b9e5bb5875a7ffda9c5827eb845644ec511a976d93d614e9bb093e71aab34bce96426692333be0cfbc411ad714c831ef062f56e3ea648f5114a54d0e2803a5da9e2ea7aec024d1b607dc4ed92bae8db6ef5386962b00d602a9e6b5ed9275818c708bb96cadd003f0d827b6d62a5456ad0dd0c7755846d21f5b6b488db3da86dbb2563fcce10640bdc2ed70d3c27cc979b845ed8fe6bf95319d5c459b3184726b1ff91262106cf58e0de017bb9df24fd78a6b2d9c2454a65d23daeaf4e0330c341958a6e2f659a8e290e7676ee22b87776df2d2c537678816139b2f06a68d6743ba2de259b65bdd7605354b9be46f1125a5fca109daae3b4517c4844d944adcde23f3c931a2b162afe6e0cc78dea1a22061fd5755990ebb215615db55b40a613d5361676b1509cf75f6d905a66f170ca55fc93cb07563dc3564e712b1c1f8903a71fd1d3f5dcbe394d38d564ad01d0d110b43c19ee02e89368948ac6699dd8588bc79a5acef2b7cfba0d97b23760c1ac503eb5b0c218b3b96aa58aa96f1b20031d8a21eb5fd3724677405ac320a6118d85699fbbe799561ad479c94846b5df98a4dc16bf419d72c19f0265f6b8cb6bac31d6b08d4d50bbfad2cb653e8c38047049815850bd4423cc26867cdec1833498fd1b91c55453c728d060fe99b88d014d3a0ee6e55689141d48b44744d565c956d82138cd255888d6f148645acc5923b78ed73c92633d64be82b5445dbe4a69908ad12ecc821d47e83b93dbc5edeeaeb71ee3b5bb2f13477f809ed7414e879e874e8fa677c11c20f03fae7e6e88101c1220397e9e7f0cff5dca7b831ee5e87a46589c74952df2d0fc0133a2323a34d98b48fd751836f58d928538885c00c8c2d0c97bc4ae71b585d6678ca6026b00ae39bedababab8516f8d1502d543800886f7e9cf27bbee8c7dce6702fd48f435057b4deb2b23a45906edb0803f01238f9eeb2082924f4aca104a1506c6e0b481501a17e9e0e31e8aa2689fcdb077ec01dae9a9987e9037917a0f05b9b9a09a818826cb0e67476e8591a42733690b83f3c3164e2b1c1b3e866682b952967a99b8c4801f60bce2d072030bd13e41608f9e5158f6046556bd82eefeaeb5c28e1ee085f8d51d98b504b29ca924260f2c58d1c8a9411e463b102f0b841e4ccbc1e4a6d1740cecc35ccd69af7736f0c037f91d426282b29fcf1446aa14df181148a8ad7ab19b97f54b386135d01a682a63edf22940a5b6ab52965d1523fbe098f5fd87ab1136cb85b41da99072100776a0f2f64bab65ef3881e0c428d075a5ae83e0d2866808fbbdcc836f9867897083e524a0401755a3f80d8c495a8824c7502746742fa07228c69a7d87c0647e146e3187143bff91e381d1ad4ccde481a5f0773e3f253b2ad5e6b5647d881e543398a100e792c39c2a27d1d629645d024a04db4019999741ab2b3605acf86f7d424276294e32d21dc1270fe236e2ce8d78ad568d1bc9fd912621455c837840adcc02c27c76db7026095f02fe125229281ac6d838391a03c2d4ac922efd029c65d6dd5e2b180c9333fad002d35448c54e6ec41adaff4b4988644d015524f8de6c520f0144df558b594895f3ae80e3e9233feccb4f7ba8e1b78a22144101d6637b7da63430ddaf23167611c23d52538cecc15a9667963fe09ba48ba7cf5500f7a4e65658a793b61a7aa3253d7528413298f0a5c00682273b91309e5fe0ac17b5891bae52688559f3b9e18789901b919e5a6160338fbb60366618f8bba04050f0b9615b6f8eaa93babf82a859d3b879bf9a5ef37e83514647938642725f1cdc3b936ca31499038018d0c31540fe6e75caf7968fa3109180072a90c1c812d6b8221c4552d2449aa2d404c163d1be73dafa029dd3e20b353fe2709026b809395ac830e9c79d2d0783480c1d9eae65a207338d53423d6f78a73b236e9b4c761f7d6a248ab817f1852f74c359d6b486a8c50f0939c00a86290deb5036034d40b70e451f7b2e3d8fac99a293c11fe19bba9349fdbc109be35182ae740d31766998a424c9f8900d0c66175b634e0d8b7d676c77db6cdc2bf1069150d56591d84fc5fc2c1215a504c55a953d492ab7805203c373c9dad242f3cbffc8bea07d9db268d050eae547db6792b104c6b34b97b5f2d4a9fdf1aee5b017f7d13a210370e30566a59e260a849611e7427e4ac0795151b0080f626834fc58b4be0ae57582e493170b4bc90b38e0c8562f38a997188fd00c08d0c69f3cf72d87abb67837893e4bd0adafa6441e7564195c018700d96b2e71d01bd02580f7b9c8cad53a2a089d88aeb53814e5b99682b6a13827245454e468592aeca9a7d5b30f462a53229f9aff6147297b507726390e82fe65c30cd15a9a55722fa7319925afe902befbe7663486880b4ac9d6d5ba538ec057f9377e1fd5484a5a86c8f2ac3995d084d2dcec61bbaa7c6e7e6adb81ce383bb5e62936024103c9d7065a4cd71d8da790f5fbfc0609e67b01ade1ee06994fe703250dab662703797a87067461d0533a945dc82fa74c20e711a96a9028bbe18adc5966d9b65b35a6f06228b1645b4966bc092b22693a8b65a86c88120467d5de4ba97b69ec033623e7f514d434c12fc73a532c99a9958d8cda4027cb5d62f3cdd3e2c5c0438921065662abe28baca72f1053185c27f8f9e3c02327e67a06399732114ff0597d163a293919038205aa573ffc0a88807a0df93a26b241d430b79288536d88ccf349bc42d702d49329140dc82b84e1cc13e0239580c1837dee199826e11b45aec91f6135df9e7634c3ca406a0c895bbe8788c6c7a3d9b9de1413746d81d04a27ef665a3dd4a03066e2f3dd0c912452ed318ad84a183a7f3f0c49d56b846698ded957b5019fe68ed9d2cce1b1414abf42208b9c0fce077faf4526b030cb226a94114d3385003fa1db483a67da7d23c601a679507e832e41f9fcebe5d556073d69a823d7e07b9285f2c3cd3d3cdd50062c75a5cfecf531603c330ac356bb1c36f2ddb15ae2da0e4cde2007771f739742a5524c28e904507aa38cb90daa9a7dd083b4d0a1613f72109c6aa1a3575b4bbe9a03495d10e741035e5c20628931e4ddde727d830b763039f29b9bd575518880571b515e449739f9551fbf46c265b74548cb0e10865255a155dcd798af7abcbe399564a1912e8b59b8fc18497301901ba9ec82c4c7f2d4314329c0b2bb2e2acbfa9c1d61088d0aaa93e60636c96284da77557dc3ba2dedce33885a504add674be485a71a4bda1ed759db28432690595e20139ccc0886e50ea0343ad47ee7e953fc399eeee768d9e967c978d411d75a568676bc4699353c3aed4147f96f5e39532b0bc34111af41883c30a495a9fa7b1d4c476e2f6550981833df5e49551feca24ffe6479e8b9a1831c0c0137ae8ad1a73c27185afa6b33373423957c21f92d1997bc220ec76a4000c6a8f38a1eb8543b0eb0d046a90f526700869d96730d8996f8d3da4145b514aa8fc5f2c841bdb711ad1b64866e0bb296f93ae1ea0a54d58e84748570c01f384e1c5284f5f907f8b6adc05eaf1ee5861ec118f82df2b7f6784770fe5a947641b865d4c8fa0e43d1c2308a890c42f132052bdf930e80a3f61983c32acc320dba980a727bb3b9fcbc9df18a2696646be688af450b03417a09e8bd07017f18040296053cb9882c125eba2ab875dc93526ed11f3846187e18990eab2d5bbd028f25355a161eb13869d4cd5d70c97a8ce95711bab78e0eb34333b0f29782a9ec828fe8d0659d5e7e86603b80760ffe6335a01136f456586626c3dd1003dba24b0bcb3afd7cf08950972ff005b02456078fadaf4f684616dce2d497172138d105e345f8d9ad6ce481ce1a3fff7bff187c4e52e4040070e9104407f4c8d2678c2909e728f4d54773ee825f07f16313ab2c910d91306cfa3b860c7f508a137af477a67186c5183fe7ba386899d0d83e38aea8ade393b452f627a2897d3a831f0b855aadfc6b9a1d4058ef1d14ce5867a796cf3d4d6a5a9a02c78b1f1cf19e8e06ea9ef5ed2131849d21c2a949abee623b989860aa708b9cfbf0b3e0c19edb14a2eb93ea1609107ce1e2b4c6cb903b7e6a36a0bc2ed7f3780126d9887230b8836a8a167cd55c339362322f5a15e0bd4277e04334c6b7b30f4eb02629b041a9c3456c083ac0b4eae74459648e49883180bdbaf30f7d7e49a4f743c4d0303c14ee34de90c021889007d5aba2cbd1166edd33ec646f628121b2e440562396f057149846fb6611d10fc5f207a2b2025bdc0541ad5027efa241c185662a31627dff1c20d405faec4b9d5f88a3fddc3e5a103b650899e547dd5167660b040da114bea78aa867697f4832b87921683b6978193ad6fc4cd223b098570c0f1bd4827b1da05a6155bc988802c26772a79ce9831474ff2d5a2a46a6088f1d365b7b78f162bb37303470c47c99fe95580627e641c9b01c855e44172aea35b828c073dd7b4c3f18ba5e4e731393a053cd2cd231aa3b7cfe82e78122eea1abb9e3238a9975df3c3483ca28b4ae27cf284aa54d6df2c3d6267fbd8dc82bf2b71abe6a932b58839352bcdd8333556ad8cfbd6a4a0e532d7673f0b3d0eac0e758e2a5201f159422f4ab706df8901504a1d298788a2bafc80794577565fe17e7f182daed1b3075776ee3ba6c8a4768f76d4ab38124ec710b4600b6ccda3964c78628a28ce1885b6ceab8bfb1174fa4099bda9725d3eca27fc170373cf58b2f6fe4076976d3f710617a8e521459f7cb920681487f6a2e34f3a6bdddb069e459986a70516d8da28191a85af6bc6c293174986c80c2d1fdbaaf42034664ee9f2286754b187d8535e488c57bbdea2395351396fcbb791f30c7aee041cd490f63e8824ef81f711e2076499ee7f6342ecd779ebb40fffbffab39af0c02de6c9e6c758003723e4815128a7ba696ff9307ba345e5fdbb9acbae99f179521d7a328987971b81b3038093ef1eba7fdbf050e4f01ebe4fcf83fe465fdfa065b821b0ca34d3d7fa640089c4cc707a7492af1be8d57c756d79e5e2859dc00ead3c7c68f4a0932b4f3bab67ebe5db6b48ab3fd2e8a2372e9ea21ba5487c30c468cf767430c8c041b81a3837284d5de08568a7cd8b7089bec24ed9b256b5a1609d9335ac66aacf5a3a8c16d38c0d3e4252960b6067083cc30505c2222b3fd84903945eacc73febd8d15010416dfd5d65e6956d3eb6d737e667d915595b2e4846598b7c69ed2db6d5990a1578dcf067d16f24151a70d4828380fae00a0ce8b128e0e9804ea030ef6feb263fc51ac4e64c89001db242638be85e124ef214955719c0d74264a1a6737478d0291c235ac015a488d62007d3f58b977ae79ac4f8c88a1065e0498b86b88a0bd7e5cb35082df69bb88acf22bddb693223abbb4537cb0e241fdb79e6712b2803d170704fe371e45957af9c9b64845bb8479cbf6472fa5683329ece421298d96c9869ff886b737a3aeaa884b04f8d47549e0c87def0f988d5d818bbb837c0414fe86488ef0076ff137cba4898fc058f86c01ce7ea026420e3e49a1d1601d5ff76cf95b1111661d2b187894ca6a70df0325d31b38c41ea0f99b89945d546de7d251c702c9a7ae8bbbf8ebcc0b1b086c638517705e8e6b773938b6d6612b67cfa9d3f9ab304e82ec746f279076ae0acedd2ab5f9c8181e2e2c07b5b95265baf6d9bf8fe84c0cc055169bc157b788078cc6c7677ea9a05a43746496a9d5a0f5cde9ccf976decdcfe927560e7663e5c4c6f508e5592928aaa64bb4432079f8509e5bb0ecf3e61828233ba07780f089e3dd27d3794102c10485bdbd568321b0883cfc2961a32e352280645e0502d8dc30850614f838c9015f533c843240058b4c0c8c32cda9a7539098af163a04f14a71554cdd97a103d0f0e500e9c76d9645425c03b5d400948862de10115b52873e94237893ef5ac3d4de7732fa5a4ed6a6f2202659561dfa1b4c6126ecb913f1d4d7d0c5254db2956c4332e14cdc01b63fccbd5f1948755d5d22923c458ba06495a07b544f179d482062fb1e6a58a8747b42bf159ee91ac1725f980594befbda37bad625edc9148258e9311fc28ac82b6eedb83e72fff413ce837fda8dc78320c73724de11ac2d66346bef890024e2330d766fe497c80c625276a75b548b4fb1376e3325ba240eeddd24cbdebcce73c6f89c2a75dbf4e3f442043c39cb7f3f8e2905911fabaf7fa04eb1b7fef097335ca81ec3ed983053c46fd200e4d180ebb04ecfb3d741cc0918bf22d485b47aab1832161e4b378ccc71c88657524e24663345d1ee5cc592f3a665688c6145404d560241600d628393327f8dc9817e604fcc328821da30f094d181e5d97059003d50b7e112bf553d7ed28c7442445f9d60b49b5deabf1dc598c59f7cc485d9b2ea9cd32c0f2a535ce99454777f6aee323e1c849dcd48e6fa6529e76453fbc115054ce6e597306dea82cfff7c1dbb972ffe303f82ca171705076267f41f0351be7c417a9ff6af611ea4d329dd75c53a19b6df8e66f0087dd04f579aa9b0382221fcee1ca0b2ff939673c4d656264f3acb183c0629fe5e71709fef77a69dfdcccaf23938aeedd25bf761263c28d166567b210ea20aaba6dd9fb31ac0d611342139c13cdc8c5ab12c27af329d8b05547ca19ff027e85f45a37fc05e2d6f3e1adb948d4f02f9007918998c71691805a29f11261fe5b6464e8eade88fbbb381d7b020efb7356bf20ce19aeba383233375ddd0390264a345cb0f19449dc5355c401fe7fd9e7dd613e382b3a9177b913b13a3dffd813661b60d9e38f116111ca4ce3638cb1ba66740e87abb11e4cba8b3e5a700ef34fdc6ea709223bd257e39b37a2517b70b9f7c1fab46c465c9c0cfe58a422505de8a8ae32247d206762f89e6b42c226c82831e6653bed378a95af5dd216648bfab5f772f38c72c9423334e2b1d32b7ba6510a391a0182c9d77cdcef078180fc0256aff8c12a93d2eda315f45e97d12aa55774bc45888cf9f7fe62e2d191628d20dae6154d725a84e663968687883023c40f1a2fab0798ac29822900e062aad97e549c9e25b0e0c28a6aa5e1ab3a600335fa4dc3c7b34d40a51dac245823e0b1422d5b4d1cc31d4400edc050693736c92420afc90c32dbccfe0140f11ac0c31b82e3b84ed0afe1049a84ee35d3dce9ee68f822b7ce84679e0c06ed1a080447e8a7fd8e2506d33727d84793430f251380cb9b838786e48051a236e3189730095a475eb78347727e76fa979ffdc68926d4475f7757e89a39bd6577cd162637ca1dedff62e23472386812f2077b1048c98cc8c56852354ff23cbab4af8993ea076f46fa2ec2e9de3cc10ca37b23f488a6b5c4d51e0906903a11c06fb7e124e4d60b96adc3fbda97acf2e9b38a8eb3d4a1654280e6bf9b1016ecde3777c65a85186365081402f6ec4086567af78fa718f24ca07c95dc8d64c62c4b2f6b4c70f4571b39351e65aabe8e6f19fc3352ad698c28443f88a2e9f43cc8c65511639e259bca51dac84bc57b149d369cc17cb29ea02c8693ef82044d1d71da6b95ccd4773c65d663cb229746cd13864f9df3fad209cb45d4426f7a0cc8543eb0e64337c973340370195c92208033ea93d3d96b426ef3e470e088f058de84ec9a39dd9cdafde20b4e28c6c2132f972281cb5511a6903703a4a6d48d95887c70dc4ac0c5f720c7ff3ab82c0e266687e0b7fc2d022e4a83dff6ae46a3c6bb5ee343f59034db47c7044685124f08b388f6963810a8ec1562ed9d3bbc5a97dba8389075c18580c82717f76e382d73249a229765ee2a5b73b286cfdb039bb4a33a00dc183aca159420e63a4100a8ce755a3063b51a1d2b8da7365abc46c85fe89624494545527a5742596fdee3fdd322f9a0a720dd0a0f9433925d1ef63e16190740efad81c7a7d99acf8ba021ba8d821d23d75a1b274fa71d36eea65a8e8aa982a1ef1894e9a2c008c33533455231e6985069c0166f3836954af6479e65d9a99aa25f3d55562e6100c067c09cb473aa4da6f1d31d421a94eb481a89f6ee025816cf43b19694a25551ee6a8364f25e1a39b621f2bcb8296743a2722d244382d99f7bfe2ee84a59571480181aa429489f42b15e0d3a5024ff622dcf2294efa574d6c74bf7820599ffaae110f311e021fc43ded5011cc508ac9e9fb1c755b70d7ec12aa74bf26f123c33f209ec9ccc628953aa463f1a6ce919fdd5cbb97eb1e64c81a74333114bc6fd0834b1ca0488441c6b514bf73fe95e50bb1c16b7f5c894b608b39bc1512412598a6b35d6b99b666efbe9e8c191a73d0c1804d79e607e9a6e762c1b96a8a86a2b4d15762ac5694288f37721811c262b284aea600f8258e6fec5831b2b6d8f41f6c0270e5507350d8734da4e7affcc43497e377a3488f9d44aff4ffff0f0a785e61bdc81c99b77a911140da47c598d0e7f519d56b8e583644c877c47ce45bab801d015b6f0030f257415ad0bbe037a16d3d14fb9f0f0cf9ec5117618066d9f74af6b8d4cbc188a79cb7cf9d4e7d97007978bd7244079b45d11bdfd4a1af3ea2bf919f86705ac97a65ab60a0254e0b226fba4e2b38f6eb98bd48e7befb3bceeb18d804f9567e13d7f897dc884e2aa49f467107716cb4ba2c509ce1ee596e6773bc74b2392801e68f56c6e00637ecea1bd100e7cd62a807fa5315b2be94109c6cfb3bbe194cb5acc9d88e8d26882e194feb67aad45b21859e8b6d77b4a5c73ee01073196d7effbdc643cae5f5f66fa97dd6f330bc42b88f0ce29dde77b4d2a855138665191caa5ef12625311283bf18afc908f54d9db73b35aac59d8e309f5595bfc761662530e7a7c90003cae91f2d8c28a45b10dc9d7513b652746abf3201e35c1b8377afc2fd0b8129770e2affe5721702cd2cbc60ee0f641c0807495195d52db948b94abac1b14b2cfb391bee1491d4ee77835299f482fcc6b8a20bfa48d4be4944b89df54efbb8c0dedacc0fbbe08f94fc3d3bbae8d2c33128f07c18b56deb804baad7d1b42628d5ace36f366efc5304bc7888b04a5dea8fd1fc7026aad6b0da5575bbfa9fca56b6426b3ff110f85b5af4243ab786cd9c3bd1027d0ca8ae2029c1eb31a3f2294b5eaf472830d6ef9cfd5f546cfd0e1984276b44e949cb9b8d0727212261c8d2130ceb253adb460b8244a7cadd49908f68b905a553d3eab4e497d0fc806661f29cf3ced368b17d618b436549c9b64de1cfed952bad2e450b47b50704bfaea092618f8854716035b78251853c9463ef1b19a6e5b86082486b2965b70531a6e10212aa8c8126d09888f82e1e244b843049aeb60b85bac72e8e971b55eadb1a4843423c0c9e98eb20a0620153db6ae0a8444c1d0679f01eb77ce44afe49761f9160eced1bc0c6a06cd689f98cef9b074ebe79306291e45a0319869d3f311b962bd42a102bb9f5729b99034a3d7b63da37573c467a2b780d3efa000777f0d9696d06db7d90f0ea485702537264eba29a0a29f360b9d83bfab5aa98fa942673c08552a9509cdff6d7cdc8b55053b7b398dc3b853b3e616499472d8f16e5b17b0e9ff964f2055186f3410dbb9918b386ea4e0b835d7187d5498138d7af8d9e09fd91bde0b4cead67833a6a4c79ee2edfde4f400d49ef8c558d3626b6f271b7d8629db5821b9728f3e0a7b367247745264170fb4df7d77ec71f69ca5f2454d76d44ec618da621b5e00fa433d761797d5f362c4833c8f4b0113617af10baf679a4b6e4148f39de3e1bcb2b6fa14b1a7b571c6a308e4539867d0031aab7b10834e92c29db9a19afa96d399efce46446267b523348a10fd9a4b6cef27e55897ac28226249495a0d387763dd5ed1bc47ef947a7c534c44efc6fafd1b13d0591d5ad545cd1ccbc64a7425fbbdd43a07965de1fd3487ed9838b211db0e7c66739a265a6a3cb0781dbce7eb5c9bd5360ef2166fa8dfa7acb516e5ef9c240c6d788414fd1a4011fecf3895dc235d4fffa5dadbac935f38d1c3c6be57a8e347b81383e7500e9a40a8282ac8debaf1145c60a5d775d592378d9d3099f7dd50374845035431ad182c96a2645f762104b94a0ad66422f4590fd00f6ce6bfabf7bfd2cb3426a2ef5b09b2f56a185f3a24ff52aa73bb2f165e62f3d374d76cff8c6a104319ad98e6b4d962fb3441af845a2bf56415bd6287dcc7a40da067addbcfd8aae9b291a025dceaab0120aae956e678b1d45ad504c873c7c9cb549e98b8312daf7813a0466fa444c998367fbcaf127c165969ca2ebde75a1c18acc55756fcce6a991d75aad6d435d68ccdffa2962e0e340e3a988ae6b9b1e00e133444689f8bc596df0cbd00dba2ca21d5a34247272674c6ed14cde5f6039e8703c44e02cce4029ae079655b200e4a9b0eb9cf8c3dc7b9da5b7fbbbfaaa42d833d308dbdbe7a53fd6564a5fd2541638bbd7f9926a53bb9c3ea53688ce0c00985dc32bb019070bba25ba5a28f71e8b45e61ac7fa934c975ae6d7512b1828dec6e5bee2da54c32057106fd054606fe95d65cb5ef9b6e71a0eeee07f99193d381e66fc925ee7ac3190e0c4c24e018e107b0d6efae92bb3b28f7c7285201fbbbcf19cad0d4c7fbe56afd2f2dc50bb6ebfbbee7d7594f59f75e9a2de9860ba444f0f8de7b70ec5b37f6cd3532dd9ad5374cc63597bcfbfb945d55d9f53d955d2ed774f9dfafa31589b1b9be73bd5cb2b2e639e79c73ced9b9e6ec29f26c2bf274e168a12902085c30f9e1c8dd6340858bc260f0c32f1b0b7ff97a2cbbb917267bc9beef461dd635313002388238c6e04e6693d1641c81af573645e51cdd2ff5d4946bec16fabe47afa77277bf71d07bcb9bc9fe6465f7fed4468ba2b198686de7061488299363728405b7f924ccc7310296cb4314bafb024e4e521e3ed2b09df7e3ddfbcd3e175841eae0ec9e39c4c3ddc9bb3adff7aae19feb65a3845c92c00b7d9cddf0355faf1718f64d08765929be603ffbd9cc561c1c1c1c1ceab341980f08af9bf7351bf1642528e1e60afdd5b9d0c7f227b7386f6e6edac27a0e81afd0c7201a356e066137b6a398edc8f2c04a268c63e2cf8fce4fa5be3377da83951dc0b19fd8abc60d8ee1bc68b4f883f3aa71837172725e35ba8c439453da4a22eae26c0b2b75e46ea1d0c79dd0471edb8d4d4ab23745652f818727f49188468b570d9a5b843e621ae22bf45187868b17d89383d313ebe9c1373db09e574fd8d3d3d303f6f4b8be9e9eebf574b6d21eefe9993d5d0058f981dc5332507659198227270f12b824cab3887eae4479fac8fd160abbcca7f3cc4db929936132058acc1616489c24e04498227cf070420a5162602cf572961fe00226f2a21adaa613d9e6519e7e8d28f3644c9b16500dd1c1881d31ac89e18a2aae081ffb8bfeed7f69ddf4bf71776b95f1c18b1044d2c010058d225128f8e202102c70de7847712447ea5ce6df25f3e70f94e64481f12bdbc682e42a8c15235657e45040628a135868f081091d6ef3fb89af561de8cb74fc6259560842cc0e319c8047111db05093c50a5caae05e095bdf3a695483c822156aedce616553a6323c5f445379982f3e086c5175d2663ada8ce77708563f4c7da1e1071b2a3194d21ebc661d0e5032248d145a46d050850f24fe2f728c3c87ba0a11515772566aa29c2064c5092e306165081e907477f4bba11c6a699698e2a4090e65a29ac082c31220781069e27403f93327bf0edf1d2d3888fc5959d62fed979ef7c94a32f7bd4f813a7bb58ad95a0bba7b8e10d06c6404aeff72bf40a84e4e98d69a8a0b4dac4c2dd1a54b9415dc22cdfc9e3c50a74e9d3a1b16c2ec20d282214e7298a2872f567e808902b70310b78964052682401962859927b739c449182f2ad890660926ead47392c8507039cb7336cb93a475a43e9dad072a952d91b9b1d897fa288786da280317d2a4a00927c45c79bacdef0dccd1858becb1ecee63a6e398fb4543043e8298a20725d84851856ba2aa8a0d1b2136b0e02b884d6609ca1249ea74d1ccc9b06b62d13b2992e49c73cb0d97c8aeba21026da8c97c717ef79080298c85952c26ca649105f617fdefad5dd6a2f925755ae47dd88df5ce393b77f6e997c1d9b36785598ad534a2dcc9bcebbaaeeb1ec97dec4009d9b7ec1c69b6041c315f8c9a7f6db4cfde354c819a466db6f9e2fc3683a383cc47a9be01325046f2271d82c04db9001715644d961acc1c9932c40e42cc24aad32027694ecea01994272da80cb244b3ca3c50f3122d5f9df9e2fc9e7f5fc0421bf32416331014d484429a1764b5312305c39923d2d0e0430828a2aa40e236bfe75f0eb8ffe7e93ea584fb913c283bc1ad83664fa3e607982c884803260c062ec8c10aaa2156e872e536e71c0323ea89d49535546ac805b18102e409062f4064716bc0541649cc3c89414d1437d88e2929c6a810c30a9c747ca08b951504e962428f2eb71945952844521044cd0e205594ce5c8be5e77e4160ce8966c602196eb8d204ea480bb41cf3c939cba6208e48f3050bcb9827511cc921cd94336a7c6491029322b21cc14289299478e23681b43143c39421698c2409627546851d5220620311574431d1a5c813463855a1a65fec998ffbf88c7979da7cdbfc9f4fb280dbccf91d42372db98226890a5448228bd5029cb0da218b871f514cdc9a98bc10150448d5d3114d6e1db821ca962e5340785441cb31258a2a872f48607062c5ad993c21062a081fcaf478baf56311803e3efb29d98ffbc510803d8b61c19fe78bf37b021ddcd0c2d6ad93b8f5777388c290fbca0a219966eff04473a526eb8644d9bb29a35b666405bb09347f9bfffb93fef38617980c3ef66fb632246fe20558eb0fd669b18b68cd7e57493ada9c24a2599aedc93e6aa17e2cf65f29187a76671fb0d3aeb97f8a4ed28cd4fab41229f1a21e93c764d0434aa912cd6b7d445557cd2b2a685c57559ca864bd28edf9b785fcee3be09229eba85ea3c7e4f913841ea8ec83f04ff2a7d93c2b60bb5c4e84dee7b8dfde83397478bedf5f025cd796b3c7b276d005bfe845d37faeacb3f7f264d736b590e54811520879c24b104d2a4cf9f821668720d0f4a04ab488404205aecd0d16d081861e392c25550491a2b35a7ae9bd94de4bebfd39e9bd18bbacbcb5de19ddb950d2f7afdf8d0224fa7d9bedfed604ddb7f1e2d1f6a42f01bdefd934835bcbc8bda0e7cd39e79cd3279113dcde778d247ec1554b9debf7e69c73fe939d6f75583cc1aa7a138011f85cb2be6d3aeab67ed77548de759d576bf5ba204f3623ddeb3aafab601d73d8afee7963094ee52e979aa2b2fd6e7a3fede7c9cace7602bcffee37d6b8b2f255b1d8b7ab028a53b6df574fb66c4566676738399396e0b2ab582b33f27db2a6ed6365d82e89b96de9fd1d69b9731793b6eeca12f2ed7a2c979c249ac2f7bb9f39bab79fa3fbdabd95f5f4b1e14972bf27c99da42884296c2b928be47ecd8852c40994684952c6872a586e938b159926647ec8fd98729bff64fd78d4df32d35a4b5d3782d96673d25decfe195e44899c60da435d006d83d42f8a18df4b92e5d372a97399046d725902a74cbf8e606e5ac33496c6059228496a48c18e158cdce8e1e425cb13d5197fd29b10abb03948ecf47b7d8ef9a18c0e3280396a49f300d3af947689a4f0ccee32bf340aca841659cde49cc8fe33ea8d219ea1eb3d1aadf5cdd3d165af3e7d9056e1996bb5de2c757473566b04fc4b6ba04cc7815c67b6bfcdfffd496f29cfbb13d03c8f091c663087fdce73bc66a6e398c3fbce9e87fd2a67f6bc3147f733e7f6db57cc27e763919e99df1fcc70b2ff735214784692d75acab6ac9cfd3f5ef46345bca4dfd65da55569cfad33a9ca906678dffb57e7cffc117fa68c3b87a44a7f3bc232f853c6d8432de45f65a58ba4655bc1d1353665809575d28cdcc97076d83611304147c0048d8bac604a69adf6abace9d69f7d3e92bbdf6c312cfceedfd7a91548d9dbaac164a51b4849e0b49f14425549e7f79c4d2d520be506f20793dd59d086e66ff37f7f925ee1455933b4b08ffdced7c7feccb6f10bc4ebf36556f86b3773955d1fb03ff6effae977a50e2223f0ccfddddb31477b9ebffd1afed652235746334d21042be8c2021ea8b88a42e27f50c109497a3ced40c16dfe93322dd88ed8fdf6143d81cbffda2c60c7b9c2af8f3a85954d09a8b903b34d2c86ce345a538097145660b20295266a3e60450e44e484e8018a2c7fd9285f1f7e69e415ca4ab82db5150a6c9cf2956d207b5f65fe55e6fafae3f7e04705cfec723d92cf1cb7fa2ce07e7f8dfeabe3fe575dae799dbcdffdd68ab125fc6dfeef4ffa831e43c1dd03545243e0d6444106eae66b5e807ac189902a4ae46efe4fd6eb04ec992df2b1fed73ecdf6a44eac47c340430e495811850814b77e1badc1586853c50a23655e80c3adfffb4933b72f068d8ec0fd25ee47f2fe7e39c0bd47c580d50f597610c1034d9bdb5cc20aca96171aae70024402606e38e1052c58f9f1c32daa8b0942bc400bcd93db7caa05ec1905f71625a2b27dd915f6f18ec1e5f7d7d25d76e9e7a0fe751cc01518893ab5e1a3f724e49b73fff474d05c5bd6e9203a826d8dd7b9e9e0fce0d921b5e48c126b582883441729657c68a38411616ef39f74298e7f6a95393899da2a974de49c7376159e38fba3c1dfd4420a9afce0c48992333268f0840854135746a65ab835f938d282144364c87191d267a2346981052a98c169f14a66abd2b2e856f6dac866ef47d0358fa98dc62a2913b2f74f39477f793bab656567e556fa3bb7984868ba5581bc08693f081b9d07a923d6dc5e1eda9bc73fe70b1c0f1b3d2b8817a7db6ba445dd7cea4f1c218e11946ee0f01fc15fe9860b65ff1b6de46b9c032bf02bd694c64468b26bafb585306883cbae62a240feaff1de1b001370d9550c98efc946c0801205f2bf1941345b5249341bad723101da8e889c9c3e672e84c0227811d6cc8b02382a289c673d2aec79ee3aaff30c85f3028503620557854a119452dc142922562085528a8b4229c50d2104144a298e528a7be2248826514c80a094e228a5384a298e528a5ba2e4bd7c0c1898f60bbf3c7e72ffa4b7a9a7ea7e2e324994ab54990af25a5010e5416cd1ddfd82d9170df0edab86e79b8f2767a79c456a6a723f085ac67c22a1043adae8e645f01a0e0ae459dcf022d8f783a0d446ae3022cca1f7ee110e0e8ee5c8ba85707062f3777430384e1cc659c4693e81d3e906f6c25182100b9461b96c91794484296312f16fe2e0459c3c3289cc273f95d470346798334c291c77f1002905e7bbc2700a813297fb9c14059dcfa61f8ece077d37741d276718ff88ce05a49dfd6cec4a796e28690ef90705dd2f585a1f7c008212addd7006d0680ec87d300582372add089a32189085b1b003823e980aef966d825fb4ee908ae13f194201efcf570dcf9576f6b3a012cef995aa21f5d09150cbb811d446df7bf7c8764837fe7b0a743259d95f01117e44ebe4a2e2a3e21e7dd5a7c1f2ee07ba7ac6d1575999538165bb9fdc6f3bdbe79ee779339cf424efa087fc4b1a798016f2b71d1dfd8822edc129cd567fec97606e261dff5a0639875c9fcdc92943a887fccb20d9d0acb2203a56511f351ff0fc5a0f787e2d099e5fe301cfafed80e71bf9d490e0f95d3b82e7d78ce0f9351df0fc5a0e78fece2bace100cb39b2dd84b51bf0fc1a149e5fb301e7868846cb810591b522787ead063cbf46438bb04604cfafcde022aca9008735197cbad9ff8ffd11c5175507c3083b7b8cb036e4c3da139e3ffec3aaba2b903ecd5278e6be823224b793cd81105c8a6a88dae032cc575ca4d0a13a54464405eeef725f7181224f19ee949d564ae5628c31c658a43e7acbc9c9090524584d9e47583946e440e189e14609f062a9cef51a27254f6616171df2cd572fb2dd0d725437c4ae5c8619e492c12d3f5c6941c285b75071efdfaebd68dcbb257b5727c0d8832b2b28f7e22cbd2553fa38892a147ce4a69bf972418ceb8ab7059d0754a8a6e0c97e33a0c148270b0bd9bb642193afa86ac8fe2e0eade992ddaf074bf8d51153b2ffc5d40810bca0e779d4bbedad314ad1d649ef753aad37bb6ea3fb65f75e52ad6bee4d99ad4b01f4b141733fa553ca54e2455151da08fcef75f31336633f9d70d0b2b3fa2289364cbb97ca6a2d409952a8643a9b403122d35fd2646d82a57eb2a9a485ec12aad8388b34907d3c2aa9ba196710d85311acd7389d1ac8062961ab3a15f1644899764760b155d69934b15a328411519e56e82e536cd640810514352da80aa3814bca57c3121caea0426a873438ca9c80c4901ba496e8d05181e184972b0a170f667d882f97ed44af293bd75558a018138a59c26908d4460ed4461e5efaf3332fba4f8df8f85bf83d5be8fbbc6ea1af1a79c9eccf2f7516b041b6b2fa6a23a1bb0ea5b2d0bb2953a63ff1751ac567484852a2805981d50e3ca4d0688e5c71250629b2a481920408d0358412315f1158a001a9dc229e9250212f1b40d80b52843ce1e572f0aa30b154b0746eaf0843c20aad74a6a0f00961735fe8e19d44991782d4ad172522beca50bd000548164676f4b895a412961e82687172e5861f6e256d0c0c4b9557ee2b2c4ea0c0395fcfdb796092244458a0b31964494e0ec160ee2b2c2ee41267248ac5c78f5abdb5d19ccd80b138f9c0b8b395ce48faa00a16f14deeab2b53e49234e3794a5600a3d96844de85d1ae8cd1a1cad708a93467a6784ae894d24239277d4a36abc860a14a09f66e7006bbbe1f741d8dc1e5acea771e5e54de84c9fabefbb9c67dd4ae9c555574f7154215fe3c5f73aa85ba778db18cdbc8f59d0766f6c0ccb3aa853a0ae4c9c98ecee064d7b94200024ffba271ff0c76e5b63fc7178dcfe9ccf7a68d6c9133670460a404b80115f8e6feaeb3751d2c77b79b3a77e664f757f6c34116fcf3dd8847117764da887ef7f348b798dc5529993e46a0b5ef9315994f33c8745ab3d57d32a51944239decba20b0da7dab8fe47e77da0e133cbfabc22905d8b35b47665afbdf51c4e4d390aee01b14488902f9bced5cc173aea1c2a3ab424af6aeae40e1b1349ba1ce1cea845feeab2b4aa42c9b2f898f0a74828a1024666bf944117b8bdc575786649cfbea4a0a49d45a6b8db550c52dd4bfa365470b9e5f7e10609572e26792d6e62170f960ad98c47269ed3c7b6f77effd9f49a335d7d771e6e4a5d1f9d819015e434091235f0d3f3a1cbe5c197a581baa3c2127540414a9eaa680a040a1d6d8ab291354f08b6b24f154e75d93c20c0139f8a0585cf0e39321a0862710f012c475b168b372f99fbb5257892824f9228922f225ca05265127d8813b369d176cd7c480632d0091c03b57de127c43256c026326a1192636b860c03ab9af9800716d610104c3a270055162755d802f1970078ca3e54b825d2c08b17028c5095728dd14b86312051039803ae09cdc5740b87005c40f2427d82970cd7d05c48e90088655e155c1b1dc574bc67c6530ce7db544cb0cf895fb6a89152338cc7db54488f0694954854017acaefba111d98ebacc90fbe29ddc574e54906beeab2e4fb9149580dd80163c3b3a39585859593768ed06059a8f13c3397cf1077cd1b0ddd7755e0840607fd78b46e79f3bec1582aef0bb5e67b192288df6ff77bc74d26824691369b4ff7f120707fa33c69296960696b4b4b496b6989634b0a4a5a5e54b4b5a5a1a58d2d2d25ada625ad2c0929696d68f4f4f522e67232997cb254d7d9064232997cb794149b99c8da45c2e9714cedae2d7c225a385882a643c79e848cae572b91e9a3a9a351a36b3c79a3568d8f4984074245981a149531fb415144a9583496934210e3aa89376ad3d1bdc992d63f6900e0cf6ca09ffe77ef720ce8b46e7e9c45e34bcd7074d79de844af70bc6cad2ea5cee68369b89b3a45965625228967a0b18289492acc0d0a4a90f926c2459816926eaa4337286c1ac8d7a369b611cbbc1c979e984fd4d5539cae51e0725d5496934210ed064ef204f5c9e5fce1ed346522e67232997cb254d7d9064232997cbf1b85a7c626b5d175e4fe703c349f1b5961cc81fac932edd4cc0659899bc686a60beff521b75ec7351b656e92208057c0031d86934e5cc656dd92b8337960c970cde7090c19bc665107b5ed7598b319e62688b496fe5f11dda3af54bad39f6e274552caa314a29a5771ad59bafc25cfd023b0cc117a5d505ebaf2ff6621dcea536a773e4ad3a94eed8aa88c54a2f2dc98f518baa08e3e08a7f9d4eabedbceb02c317ec06c770727476785a882e5a541e173d3c3d3e3be016d31a1f9d9f9f173937baa6d46255d328c68f495cb5c5d4d13a1163dce23b5b795ec0c0b19dad9dad3c3062c478de56ba13037f8c182f1a9e38deb83a7ba9f77d2de4df2f9919efe379d1a03a4878d1a8b21b0d787ea733ca60ddd696ce4bf6020000c2d90c0310033100a1ad4c01f832c8e0325512c803d2a0ab3d1a886b3a5b7b041054fbd2946862d597247b65d7eb7111244471edac0ba10138ad69d529534973d1d93a80a129de2cecb5b3b5b343b4f0e2bf345bde6262a25689d698fe997c4bac61b79108eb2da636ea203427c07276b77737ddc93a99e2640ad670566b6de775f7edeecfdda9bb6b3e514a7550ba450904c150d6f47abd60e11c5b36bfe94609c762311c1c9c1c9deedea9b5e6cedd29d928a5b4a04a69a534f3b4105d504abda7a7c7c7c7e727fcf979f1e2058ca6ec038196ba8dc0fe08ba8f51dbd9f94d79d271524a638413e796f9d870d7f1cfa0ed270ad2385ebbeb0afb26f6f251727d6710dce9063ea6b5dadd393a3b3caeb0c7120c7b2c5d78cff4f19ff9c261cc18fe7374d904009d390601c88004d220001990401a08200312480301049140ddad41d85ed4dd2e827c5af004090dc03644a311e00a0d608846800dacb53086ea8b2dacb52300c21e01d082a77f3aadd111c65aab4423805b6b3708db8bbabb006159f64fd9d18e8883a230354a0da0d442fd3ae1b5d6725054b319c0c85a5bd4dded45dd6d3380918ca30eacb506d8d1390a3b183db0d60ec9a804f81857a664a3056d7044140306071dd460bcb07960f4e2c75a2be300b5831f1f6badb5d676d6da0320e55b7737780bbfbfde7fe3ed8098a99d61a92c8795e1dc5e0cef61bc7cda36adb5d65a3b236c1d1ad6b11ccb5a6da5613d0266c018305ed0da423eb9a49452dad3b9105b7c3cae9d2d4f3b3a614829a5d45ba8ffd61c1c584829a5d4fbdeea250d31be89c170c2574e18823be1ce168c039e2e9eafc5153d175d8ff5a93ff445e830c29d2db4169a31c2dbed751807abfe87954df9b340e1a07050388c4ba1d65a713d504141e1a0a07050382a281c8ee9e4c462b118ce4ffcb1d1338831c6b1187e1c7b8c635827870a0a0a0a0ae772c235e79c9feb5bf67df5a2ef93350e87b382c3e190808282c241e1a07050382a28281c15148e0a0a4705159c47a8f42d7aa3d6a9911a008002e3150000200c0c86c461b1581627aaded40314000e627c36685232184c83b14890e3300a831886618831c610630831c830c7a6ac008c4ec10e8e1469781cc7cf4a6dbfa1b0072f4137acb01d9d4575dcc31611bc1cd0163147c18b075859ede4b8cc236b59c87a7b4ca219300713aada56776a7190a5ad764a228a413dd2530b18c99e83be6cc3a4871ef459882ee8cc2e2287fd8e2803f74a7b124cab47c396435437e2a98642c5582b9e1a19f208cc9c5a66aebced608c7594b76d9c34da1397176a48fd73f8fd48ffcae94c86d4992a5def1bf2684bf446761ad768c0be4ba33bebd4f513cb31274012292fa06d739b0441c70818a3bbeca2f1d1ded9b2cf7c94143780b5096619896bec6dd08d4901614cea38c162daa939b89a3e12a29a8058998174d8635ab4e9b14ddeb3bb924595b53b8aa8ee51f2b9fb1f8071b720a4cf2cd4bb23ac8612fc298d511a7085cf49fabd8cabcfff2e8a34ec4fdddf547a42bc965f1be64d2e756704e5a69824c0cdd82336de40db3050e4d3b436e252e342f69c47f014c9d00fa455026da72cfe24e3b73f976f8272d6220e07225ed10e4094416a3d7c9d5c1d36647543a869918209e272853c1624ed9aad8650e74aefb4e11fe4b20203545e2449da4e3c92f852425a0b47664dd834a1cd5f75e6bad253049da95173a9faab0665339480dd56daf9bddf38369b2f1f59de5253a7a94e1274420494ddd3f2cec465336b3b1c047c1896a6feb7e4ec79014ad1505a5100c70fd5a3319fa143d3780b80fa0996945253f1f98c6da61d98af26595569260d3136607b1cc8e6db2be999d0a6abaaecc01b44058a7cdb836101dd6f420291f1b54e821047090a5a55928f211f922665296960ac848eb476c3eebbe614922cb024bb43f6addb6527dfa18963b55e24076db502830fc506d340ea48987ade2ea453198f827c0a7646bc2886799d91145974e4ab7e74562ed487130ec2eaa02065ffa88885456199049899284b619d743dc0ec53b26fd2351b2c471379b6c5c344857299a3c0d3941675f3a8e4595f76fc8e6b028d626fb5258dad07a1517674b0a43ea8932829a7d8a1d246f5de0be87da687bb8f1d7602b9df644334aa6c10c6850bae5188fe48245b7163f402b6ef8c5590ceea779c0a288229b09980e9892f75d2e8a4c9e39abf5b05124b9b705cd39e8231754b719facabfc796f41a5573c40a723268e6bfa686b1448ddd080428d2d44c7c09dad73155c7210c8b8c918ef8aa2d2e33d6fb99808a8138a285cc782a66ba4d5d5174b8e6ab23758cf81b159d89e9ede45ede24a5d041f038a316df49be844781f905270089204da536863a96a2c17c9f5ce623bcd67ef477ced4e9276fa11d7d789cb4616ce8e5813cbad3ca3fc29d4fdcf061e5fbf8e131c1f83650623c5949b71d177750f113fb3d11d832760f7875d542abf6d7ce35c4bb8a7ba6011f0d20d25082372098b5595d9c9fdc8e64799dfbff4e26d4ca781df965140bcd1da65ad8b3e29a4e1d7dcd9800b6726904c2b6994d89ce937bb564ea0d56d0315efd108f1ba3841f07124de7e5f2249bd3f6d6e51965802edfafca8d2059818f9c857400f382e84ca083d6e582f3cd2ab29ff56c7764c809fcca345ce9eaeb6f7ebf1280bb36181c2c54b5c972da59e45a37dcfb04a3e522a68e8f861d13372de2a239d946334b9473a9dac0d621f6402c4c51bf84b987bf1223806d60f14806f0299e5709b0fdd51678282f78532a0c13c20eada88d25633e28b3795514b50f443d59d025b123eb977de1ee8c34ff54013e3ee53bde0099aed84a3aebc3f848c172438e45108e644f5a3032b55494ddff75ad04d7b23c28b8b8523b87dc9f5c2baf44df0fa0e07c8a3876536b2a931ff8258cec509a23d41deced30617a997934b1e0f1485bdb7030cb2345e9368417a52531445ef0c4a9f0676ca42195c292d928f3443592a2c920b746b79f9505565d629756af991037b844afc894ad8263af5f6883be5049d5b8683002659ea1cd38d248634a7037c5711463b4c16d4dcae3e36b51f103c7dd3f48e95169e5a5e4975347c1b61a1555dd8817dd3ad9e351b39896331643ffdf712ba2f13d0ae7b879f42f73109222d2328515412d59fba6ee3aeb4b645e3067f29dd82ef2be18e2da468f7cae36c96d722092e9da15eafc5571e1c80c5ce7cb77520ce41812532a780dfa54f09abb131993753db185ca8eb7f7996f0e05c9c04918b7ad953828ca278eba6fc88e3c64f58630763fe3a0015112b003a89789a1bd3c077269dfd836789de1ca0b90a718e49df9cc60695e7a982b97d437d77be763fb80b14fa891e093e599fd02b0a17968351453fff6245ce36ee666837748d4245cb7cdf691f4a724f0c092ceb6f5f2d2e473c9ff791ce436c86c3eb9eb25e7532273bd43c4bea763dbd7e6402e9bd854abdcef56bae3e8197bbd177ffd965ebeaea77b73e63485ccf0653a2c525de7633a41e3e5cd170e324f4d52a95d31514e43ad1c14ea1ff09a9ae40f4f3c7f2a92e77444337c0ca8996c7998e9676435aa2adc82592aad0b372a2dbbdcccff8e72995e804990d0f41d9b78b1826383420a0babf01215acec5f4db3776406dc164c08587ef2761f9dd34273c7c00066c26ca681f137f953331d0fd7cd51fe72d3d41aecababf7eff55aedfb957bfbf944fc712bab2cedfef37c433581f997e327257b8f9034a9aa839f287e552bafffeffa6620508870119cdbcdf451a2c2e2e4f4c3057db058e3eddc0d117ba1abd678b9596bad940fc73f43eaa4adea1be061f55497ab8496830af6a88227586d52aa55675ec670645c5b18acfd73164aa73e62121a86439886944f849f30b1d08a6906e19b868d07c8051318b726caee5f8dbd2a4266839bda04fb9e18c82a27cc2252ebc7e590cf4fea472dc80320d529eba39870dfde4649208cf81c3c230dc593834d2c59d61e1f7b3649a71c8fceb18ae1f5ff92f8322563db54c4a5c339c043b2b8e7bf55dc0e80d17b67da6d86ec3cf82130337d891b18d0f26dcbbf5b682c1866eaf1e62a5cb575352c2051ea9dd7fb5d9b4cb0fabd129892b839dee62ab5939ec42665f657a1aae02357bb76d66d480379ccd4f22a368028e9a654c4ab246885fef61b1f9ceb476c074030f12b5b5e5c8c2b63d237374b2844c82f1b98d571659978a4ab37b0bc5494cd0a335661b2afcf3058df691f65d4ab3a07eda413a790734792eaea89808c13d1e6a1fab908912bb9d210a4b752af2afc005ed4fec82927f36461a5a92cb7e1eb0f9f701a5298cfb3c1e64f5640dba0203edd6567073d173d2cdbd4582c46ac2bf1a8981d6062ca25e65ae5ceae3f77132fe2d54999058c44566a7b9cdbabb9a6d80f9f0fd7c72a2dcf9e0fe108f5e7e8a3fa4de2c19fa6f224c386be34e347d354dea178afd364e00e64d820255669c79b1626abf5a31600af23071822aacc0383b20b95dc9b4401aa263ce6f86f2ab68c048723eaff92821662306b684b8518d10b53fe04628858b35766630d81081a6a793e3205d59c388702f6b70c40e062b2d338f8a2de7893e0138ff84d306717bcbc1039c4e0c392b9c78d443d0955eaec703b1a6cdbf0bda3181efed7ba1a31381888f871a4c13bb58a9580ffef23a0e57826de71e80d0ececdd09b345ff1e582a439e20d241c0d339ce04aa13c1087967693a7c10e3d0c1b932f45458558d9db36986634a90b4984e4201480bbe200b24bcf8f6302fd6ebf7ac1e6a38d867c9c661730897172f5a5c434718aa975337052be6b22b1634268eed3d489c40900cce5ce4e924f71c3045eaaf89a011653bdb0df7ad6359110ff13a1c984c7967ed384b6ac82057455b98e93b0978fd9f6110ef24e4997b1cb8660d7aea7794825511de6fc2118c5ac2e2b1bf3c3aed96768d10a78b2c6620244c7d229cc4551726851052219a16eff5ff92d5366c8151b39670b7cfd36fc683ccb9a4ac00c2092f9a0862a461e41a0c9d778656ad806b887941b8dea25a856de1be6caef9f15da1ebc213228f6835f0788bbf736d010fa9c0408c8c4e1fcd4482ebe2c8befb86c2840df9862785c020627d7f9c0e988ecabb6ff035f6a04ee124e609911849821c9aa5a8f7e1111194188aaee92fdd1f984feb6c2eb4e8fa19884d235668cf2e38d615a09dc05974403944dab2d7428202e44113ac54c0716293bd726168061097173606b873e2d6af7ad6eaa0e07173142a09b46d7440002c292d10b6ded4f04974837152f69b34d1e0241946038359e9edde413f038a1f0178dbce0bb527fc3b9824cfe030179233765251a811e19f9d9b45fcda104f2e8414d1e7aa2c1f4909e1aa1ab2a048a409071dc4ac49fae30213c4b3cba6b0459b26e8400b0687c446d17bea27d90b2001b23101662d934781265300ed3a0758975fca77018b38cb2bad324595a946afb7dc35dbea173147fd3e2813c8805da637a0a9cfed96e15e984f5cf8317acc8116056e658a1833af18620b1ccc882602bcf80e96f2130018b733a3011b240378ac0f506b1c970d1cd508c87f8dd187ccfbdfe30dfc6794408f68f4f8c7393a54e6f634176371c2a6c600f8403977cfe0600ef74ba52cb198d55a53b16ea5aaae77146ab90e9ab0b5d9870ae7bb96375b440f0a4d59cb107ffe28c0da529bf052673c2e817d386aeb9056a6272a3b71e414980435dee2f752a7ef327de981844e0d254c94cb457a9ae32df46d7a8751e20774bc68faa411d39827913ffcbc140c3900ca976f33a03b500c8ac6be082e6e2c3c8311b2471a248d4dd98de8ba7b4d55e017b1cd2c5fd39238a231907034c33257cc2212c4fa18e999f62d6a3cc8992f9818b2d628d69ba81cfa1378d39785a51d9fcc5a70afa0add26a0b9b730cb71bf58670f7e0c83704c5f3b50ed51983460ff1d5b8639a2cc40e4f3e3e5383366a8a53d40a902ae4df2fc67ec9e86d0ee074a30094116849954ce9c5d006aafa0399fe5496a02bf9d1357d07da38440b35a68389dda98f1b8cc150b93d5c2d10602ad87af8d0d457141c9f3b47bdb0b68f76d15bf2f055ba2a4f84b404cab876692e5ef546f28d92f7324f1b62c1ed5302c5aa89fd9060da9ae47396254cd1f7ae6c3adbc902e4b2b2e84121457a669a6d0d8e9d52a5b8e76b8a5a8cb2751ae76494fcbd64e49b2141f3d155b935763cb4c4aab21afaa01bdd707014f31232b79c8c67f64ad30730206ee70a64da55f87282bc7266ca1c246f4f906e822b474fb1931fe7bfc7032a000ce3cfc1ee8d48cb22aebae88ab146c6ff32b091c9ff280e66797790f450f06bcf9c46555678a71198d13eb6e0a4a99784aa2969c0bb908da405200d4693e7ec296a48e48ea473372ca0029103862075064ed43534f09492bab4057fea779ad20993f0a1e856a6b2f712f75f21cf9a57246263d3b7b49b7f57923655c6bb66792706cd1ed66f176c78426a29595cac6d7558d913838cb02cc7a123d85b135ae4d5c66ac0522f72877c9e3e47897359bff040cbb1194894ffdb4db60318c72e32f5eb9c1ee05cf370612467ba3107de5cd5c83d4a7e7cf36203f194fce8c6ea8de4dfa55dd3b42bf79ae23fc423ecff127515fb0b410acf83db10ea47ed88f55ebc29ee1ba89b220a2db89192501a02c90319979b0d22ff11ffc243c12fd9f7c8cae9ebc25d03534656a4043d849af34747cc697a8db5602b27b13e05b1d8ca791955bd8680b8dc8b049ff7602fd70d3e49484036acc7ae6bd8ca64b3391dd012b0227e9287d62468b2a5171ed7d42259e5d2af90ea9a169511677e1ecca449dec0b97a738afc4ee0a1fcfdf2a23e733b6a0e4bfee672ceaffb81cbea1a34c45cf205e109a9fd9a32e54fbf3bc244f2f05b664bed65c3134e8afc5d1b359474db933d399ccc7bc4d8a70a69fe59ede5719d746066ca86d66b1ab0a3f80400cfeb652cbe6b3e6a6aa5ec07e0b0f017dee283a487f01fdc3611bed4fa3ce83537941995cc85de082c3690dc19942029bcb7effbc7f2c6dd274117716740cdf4cd5753ecab6062e961d6ae835395455f90425dd1901ff668c4892974515e3cd2cd67ca630f7b61d350f58042017276aa6fc72a224746af552c7bbab60a9b5766569c5ca067ec23f3865163d7d8b8f9df7f396d4c5bb4063087ef31d3ef41b7c6ee2c070915ec006febbd525ca39539266053968111d619192c39230c9b16499e98a060ff5ac62a08463592220bd61cc817b6ac92e0b2ae69a41996f526e333325a948dcd22d4b91b1c9331e79d1287f5c8f04ddf078365318d0efba590003f221b6a59386e42fc665846b456f17f7622aa226186ab2c0b590117c6e9004e8a2ac795f08cc48b3ad29bebc0c9e182d83a5bc260e548652b225fb43ecdb1ab67b99927217663e306373637dcc89b24cbdc1ba79ec87bd1afa5326b41b7711650d9e49bcedf67efa556979608e773005b568fc01595464045b7d487933ed0efb5b5c2cd3d391903e27d446789f9db9c75ff5434efe28f51632d807ce5b153005b7d109091ba0d4e76af459b3aebdd620787f959ff743f2f1f446903a2ab2eddb25671892bb9fc6bad8146c4e8611824013f92d775839b18ac779d453b5379b8c68fe7ef3fb3f619ddd1ccd095a8ec7be6cc4e8eddb57318cfc9c08db272069d986c0d39650186a2bc9962a1b127049471a354794f6126d45cbe7cac69de63948a972ef8491f1b1b6edbd870eb0d3cfa64ae71a98261e89c522287a1bbc572127e35e6963c0c9a23a65356e77c57adaac2825f6fdb379919a26a2d28f2f2a21191446a5e41261fe8c62276733ed6f93e1c9c0af9b72a2e5ca7935404beca85a08ae9d54ecb09d9ad32742b4e0989fbc8647eaf03cb5835bc8e7f7c45c89da17dc2f3da2f40c587eeb768e4ee972a7fd1f2290fb7013612c07e03364b8e2cc331d0f3cadba67b96115815aff2831007290762195eddf1e8b6a12a6d5c0c6504eec1ea732f69476feeadd3dbfccd7487bc59928c7606bff2dea14f1f7d4132451eaac347da4221941f2860ef41a5d92963e397f31a2d4dc6b73e650df6b68e943a0d3b3da0b3075aa6334b8743ace7c1d7058d5d4b3ea6d551dbc062c34033ff5004219985ac7a45d78badaad25f0b7ebce72121232f01f1d9280a9fe58f3e951af1ef08af44013ae8d0c865c3665159a9cca1596ba7c5959a2baee44c15b2bb28f955e8c62ecc00dadefd9a3d48ef97a8bc0b38c788505b3352e1bc77aeb3f96d4c955fc31a7215232dafe3313379fea265a4950d0b34b3289a0f0c6a28887cab623f4b0f9bebf16e523bdb86696eb6a712c7172712a587470f3334488ae3795c0763d4c28918a1cc026265cf98bb024c51d63eb9f3882099fed9a3773d0bef0427d816667d383a043644a275a1a33a998c47b33e85a933f1e506b918072d4ef336a81499df7a4b1135d47ab02cd23caf763b487061a082287d8e896ea5efdc5eb2101531001225bda91ed4f9d470648bb9736d36b169b046e7617c9df19054b43149019dc5e00bd3bbf89fdcc92b9dfdf45c73be0460477e3a64815c625cdabb31aaf901194eb2c6b86fa35866d228f2fec6ee8a8788023d2122217986899a5416bb2a41ce32768d65fb441f3c500ac70f679d9d3b07924348deb53482d1e5faeb7335396c92c684984074e21415535a7e56abf5100c9848fe3e8c7b58f00249ce510c93ad4315f966ac4f4b1f21c571a01beb0851c3bca58bb99fdbcd96d88d52cc6ac356cb7cd6da5be82e60969ef78be80c280c031f7b9012dac8aec2a4ff964945cef2fa52093cf99c61b26f1ccdd8504baeffdc51845d5d36ee84cebaeb29689d76d40a6ee7de086dda49ed717811e94e65adff4b2838c6db7f58c30727553af51873466a12d83c5fd5a120143912fd5d5ad3848a667888d8c39e939b3380589f84852f1220ce244789efb3103be32100064da9c7955b64af2c06f4066f42f9e1dc912cb3cf520d0bfe11b43cc590e2f28eccb83d60543cebb1db68d17fe2a6fb196c3e4cee9b4ebff1f5591ee3123f4f9de9a431d261e8acb304258c187b974e79e14185d6542af3c9557a5dd2c54681bcb0ca997799f422fe36e6578ed42c8113468065543840ab6354fd8dd811ab69d6a61be8a02ac90300ace764f8aa5e5d27f811490718333c3c7d80a69d25117af3a76c6f04fd310841496004c7f42b07ce6a27d1af3784ab7276f87c8be2aae2261d1163e4208e0cef7b570325101b3007dc8979f195826e2d429137c48a028ec7247d731d23ebd5d2f5715de4ae042e870322085054bc2bedcca026a8f0a26fac40a098f65abfcc226271da0c2fcf28ee3bc99f2678fe9bcd2134fd3ada4c3a8e47f65e7f1544f92d14d34b64bc8fc8b9e4a27513e819e78657f96d98ac6a7327a4b0427f154c56ce9f25316648f8e9ddfbacd4681b16d1c3801114944a55037fa770c2f060b0958d731699fc5276f24bea515465f53625d5609e448616f5376e19b03accf05e62d45d1e15752a6b8bf949af0367a1fc71080f51536c84b87190812fd0a76e3cd58592de48aa2afd48fe6d80c84958a6645174200b5c3da53fa6c9c5ae0d656bbfbf55e7181f107845424d16586aaa4b809a55687c53fd97ae19cc8b8e10ad78af7ec2caa72e444c3c0cc286ba6fde657f3e618a53526b1474f07c1d1558c2fcb391dedb75207af153559ddca6fff31a75bdc4bee270768f5e41c2e3992f68724642d54ccee1462a7b2c5ced29c91dfff21a5e1066edcf3456da63153caa09c96ecaab6dd6d7b7d5412302b533b80dca32669550b82d7d5b7e6e5d6e7f538780642bc50d83650d736bacce5db4a8a85b1a2f3d8077b9eb79f169ceeb084d34fc242da6f663017b9b835c9b065cd1b0dd0ac66579f4696ab587f2bd64f28cb8ae695c4da4665090a9fb57af985302d7d0ded828146fa1ed59277c768aa599273becf176ee7c008e7b3adf969d052e99e2b5e30e1ca006473121601f187fc16ab48f272238beef6bf0600714371e6ad9d30105b8f136b025c09ea4cbc7bf0f084efb4ee637d64195ae3f67c761340975a67494a60970dcd7ba6623161070e2660aea2d3076a1ce7d18b4e1dc3f90dc9c68dbbaa339d04006384e94c9194d8e3a8536f23692260c0ce8dd96ca461d2ea7e7e237540dc1a37042d03f3dcafe5e87c92e7a948361ed21d724cbb1f22e4eb0cafd83c0177ff423cdd0cd05db6e9d333b0c24338807357f34ae6652010928638cbd0c4fbba9d0e0a8808488e093d362e5b7e04b797682a0eb50f2fb9e26483ff32e1248728c6cf3384c55820c6412c8a1d82e91cd482441be99c7da17d784d34a93f199e9d6905a748a32f4aa566ee5b178480a565f5733d253059df7dacf0444b24767f031554cb83d2b7bea3f3ee4acf1343ad916b2a219578cb68f30cb7b20539021a7ba8f87c7510f8d0fbb2939ed289b0aab0d6cb6e24516dc3fb3a6363b4edc1845e023f397076ea63aa0016428c1b33737a071a67f7c9d840cf29ca39e2346e831e41c38434a506d4176eddbbffa7e39abb7d742926ecb1e0fbac32676b5ab1f05e6f5f0140cb7001fe9771be4e99a3190f71feb60f28c79cf6e0a2be81a163059940ce49a20db9bceec5106c581f0a25ad882245be4d0592af489e3fcb80bbff0caea909354da0c88931b8b23580f61028cb804ee18dcf2923bcacd76907bce447d2f6dac88bdac32d9832a17ed616542e2f83dd6b87d5435932e1ce6f1bc5633841db6e406e409096b2d550ee0ffca1723beb64f8a354f62238d99c0d04751b824593420463b4e5986dcf53f73733383812f4afa2c11ed8602a1b513158ab2e46723a5ffd66e78079d13ff4fd833604425be39a7df91e69df5de5c4b8e710748c4afa184a1ab80482eabec451b85148accb9b88ab42e30e9b42755ee039a76bd660608b4dbcf70814225aa3922c3ad20a43c6fae0be8302c7438fa9dc6aaa122010073d286a4c9c486dddbfed0673aca0c6cc1910edbeaa86ef038122ee6515925004d657f99f7b9a608018d904aec6f3fa345381d87301b754ca7abc8e6ce1c54eb11491c53ee611e1a41280699d5b7cd1551175263b52ba8033b1009b9ffb44636910d5fc0e6cb5c5dc15af079926e3a2177f7ac3ad8981e829d026c444a4212e09294d1d0af60ef051b0220219913f0e17b6859924c688e811e48fb4e0bcd7ef74f8efb01232140e3af5b95f8293f59e9938a5168044692b2e8152bd96dfb2610689596abd4ae368c64b36bd6461d0b6b18632fe67904c4d12b31d86bb87537af7775c395d9e419f88e388b77884b38dd45dd9b7ee0210f273751490c9c59e05eef88eb40c871c3c9bc740df6457b2b42c62e0e48ddb68d7e75c5b710faa0102974a4d940de9186bcf38e642ee661bec52870a7dfd0b9099cdd8c5af56e3e945dd032efde8bc1f4d7a889d06e3740f4db94358253996203c6f892a08d33c322be2741596c075b3679f8b5805133e884e0e9da55ccade3b8ab7f8b937299e625ee5b9a83b7a820c09d130e3f20569d2162b082b61c7f3a1ae07457f823097eaef4605c38b35e327638a81014e2ec7571cb41f3aa7c0cc00f7693203cf33c7e651f657c66e701087fd70f868395f5c26e5e3e2136e04af22810ea1410aa9ca437a8dfd4674d9f9cf35bd876551927dd1312dae9c3ba82721efea0a0a53ec087670f0bd221fc97c9d346821294c3bad41a015b6dadb3ec534a36796cffa860d614d40439f83d2861ac1ecc0a185c51e22f25c862223cfced158979d79255a9d0db52408ab5405bfa79e36049602d55a41c0b6c7053378d6ba9be6c30b216d8a5dd0a641ec5437530dacc95309e9065a17d2b5250835fc6798f41d617fc9a94ba49dcc9bf5705febf53e6965b803d7f039f1d983b50a2e4bb9973e940145fddf3a0307d059d92efb6ddb54f64a71f8ff64d48777d81f57c3bb1f5538d904ba9fa0f1e73756f170660214454bee1300186e9a2d83eb414261c19a86c9ac0013a77219ba8bfdd149fe56f9ad96443fd8f16b40dd8c43ff5427447cff3510ffbf2713cc0370716b470e0515b57c8d3c921b5111daab06e8a4d0aed9143cd6f8860860f78b676a849a54f752319178b444d2d340536423450f072217879e039920c5e10d4ee834f9623118c4b37b6216f65b69e739cc608660a1ccf76fabd44f39d54f4a469ca6c9e053b26fe123bda99534d44a808b348d87369ce54614edd7faddc09f3a25a1008110e2fe24063510cdb3e933bace519be4da50fdd21791bbf343453881e1a39c52a6ea7b350f19833ceb9893e08e389f5992139e724ddb1ce2897bc0fcec16e0e0bf30248d6f1a6bc0ea881eb9489808c1b124eb11a281970c71637b015bc73523a41b8bd10369566c9fbe5ba41d7fd042148e515e41fe68807f4a10f4e4a14e2f1d76e50bea0f0c10b5c4eaa2e4a4de27457d08e846a84e7e191afb0f3ab530f86831ffca3468cae76d5f00b9d929c67fdd15a5ff31c71bc620170194d5d4ae1196fc55d5a6bec1422512cc11b08996764146ec38b0db60863f4e308802fcd7ee3870eabf1ce6fbdd8a544593bf959212affdde47a03a34ad1c341aa7a05596017b63dd3e55d100e4fb9f248828fd8058b025c3d6cdb363b7fb9688c125856b45081170052cce054f44f1471d9c7d29bda67f767a388200a3fae59eaaed5c604cd0061335516c21b577a0c9132d9466bac3860907751206953995ebe0524e047bd48ba212da95f44de6725dadccd0f29e004e0885d7047e1c44335abc506d00986712973a7748734ad86dc482033e1865deaaf0982f6d29230ffce5688da14bcd8f3055d4ed6cf9d9cb5b566de6dc7b87ef2a5ece0a61bf788666ada4c178bcf82c8ce35f63692311dc0982e862ea3a8820d6881659cd663981c34c9beb434866892bd426b9889d0ad61725d40cd20481967df13e5688b2c7010b261c868050ade5ef7adb7502e505cc0ad7410e56961a0ed104c18dfffee5a05ef05cb08708e3c98813e724f4b3130c8ab57f5738446244e3af4fdcf400bcc842417b4b66563ed3de3f7deaf02b40cdabd76edf56876ce1ff00e2063579550f58177cc0b73548161c4c035360937f3d97ada49169f3656ac9dadcf4c4ecf12feac47eeb6a88ee5f2a15ecbf8ce64b52b4869db7ec5384ff155c2e0abba688e5d8daa329727db3e92d32a1a233afb0563ca994b4ac2fe328143e08b71adea15d6398d219e5b898a674e40145fc72512c2cf52c5670095d49479c58ca26bb1b91ebeca758fb233e26e7a6b52e8dcc5899dae2707f786d1a69b9d591daa60fefc6bc9afe3be0150e4545451a34f5cb3362a9e77ef1bb5e12511f1dd775c79dbd90a057da63a027bf23d5a02394551d5043f2d6d993097a104aa6a7b294ed4b9c1596d3d7d6fbc0b1e6b040caa042f28c5f3604a334d2b4b831d26be2f6c90aa84ac5768b206b079aed20ab209760239512c868a0ab2e8bd70f1a741b21070dbe23b2955ff248c8b7ce099f8630589883753284efabeb661faefe3a39175a5d4d4f37cf2f0f3bf9a409479531ecf934108f736c323957c55cc0ccbfa5f909502b407ab376d818d0651cfa03f58a6f26635b585d33eb8d54bf5182d0e1d4b96f5149bc10093acb0f82406612be958be6dfc41d1abb1f0e4d3790e95d4de39cc35e0a7e6919cbf009913884ffa562e1aa0fead35cce2aa6a641efd5e63cb67993914c9793de25b7623e82aec13a9915d9f23eb32dc5a555051673ea2a59be452cdff3bfed2bc410c9c84e97a14ea6089e620164a366a012abfffd7de7ea1352b1cd0c3d9ede027df5e37d58b67d1567c54d69fd10c6cc3bac1e7f3ea3a1214518e8e514a436967164f88b024ee1010b73c088b9ddb2f44d21285c99447aa505465c71a90d559a70b8d58bb2ca013fdfccde96afecaa5c07cd6ec58adb198e56f2b221ad943d912bbcf0d7263931530dac39ade999ddc1dbff42a4b5453af4e5a86729a0c6430a79b043ca05a06ff82c0ee801fe1e7953ec4fa29fe38af802f9823401f8162c7764bee40a8b562e1c5a68a3d4de66f5734203efab2360615b9fe42ce42cb2d0d12f508181895b8df3c1ea99e1d5876c4f096d11ff193f8db3c3fa939f376ddaa1aa8e73e781420a104ec97985dd097b470d99e4045771aa97f262c591aaff6bc817e5184acdbf44db14415eeee67da263b730a668edb17fa8302fb604898b353afb4ae96977ca8402d1987da1c2c31436f863dad539d21d4a4d51009a8c7b522c9c4c891eb339559b59d7e1152683a0983e7224002d56165e221f357e9bdc2905fd6f523bb8516b06c00064bb578bd8f4bd25507a06c7cbf4fdee45715b0b603b2d600c9cd144f2ebc0a908f3b89df2be24a3183a13a8c4033850a50a7ddef4ee8abdc2107d709341a2490ef105427b01b0c3ca4daefe705f555911bb5273fc3ad3ffda49a75aec4894296dc1eab125d6bdcdc98e8ba05a6ef7ad34de85d438e18cde6064b3337151603ce2e65beec861c47aff5c074883c7c409c5a248c84cb4f2de79243e963b5209b72391617fa4bcb8681d9184d15b4c54c27be1b519961a588359aa1011e5f095346db108722cb829fc39e12ee599a6ad05caae15f41a6cdc48b89afa526cb025292df4ce0c8c4aadcfb7c2d261697ad41cb7c8476edd6a65740f1550e2148508211bd46b20ceaa579c229e5692dbe750b0c5cca084d4219a5e151bb94f1127822116b09b29f297972eeb5b0d766cedf3292e14299026bf2d7ba3bec2ca7450c30640f8e1ddca19fc1627b545d72636b3f8d02dc81b8199561c018a4e51c59bfcc0ae2d6ad1f3dbf7749c913799262652dfeb36a209b4a0f7a65672fe94904ad7c41349ddfcbcec0b564c6ad2f58c687b6cf2f08aa6e4340bd504482ca47ded3441be6639aeb7655170bf58aa8aafcbd38d178487d7415f81de88b02b980e8e66bceaf5604c23fd03795f405bffdab29f60fddb487a0791892dbddad1fd8fdb7b464b7a38f79929b1e91051063fa77b3ba09d40e7842ebf9fd20755ef85b3147f86ecd9acc707e0873fc3e447bfbd6a578befe7a5b0252c0ca8a3028e1fd8ef451deb8effbad8bd842bcd3fcaf5f580124de22a0540c2afa3ff5fa279da8cb0e83c4669bde1566ffef8923b836ad0cedb7aeb91e4335d4a2b7150d58041a7a4e2282294677ffdf0797ef0800d213a2f6483da6a2604682cdf46e610cb60900364a690b88894a8de1f4e7eff20b3920eee0fa67d4333c798ceeb89645f016087905e7728142410bca6b4d3a31ff9f8b06601efbacf9d58b466d2503fe0b0e90cb890e93bc6fd2357ee045c49a6e34797c3c12493968ce0250e988628eda561d488f687bf31714a5873d3750321d4a42e127200a580760bf52f9e210f311b26d1c3540523bf31af722406c6eb611b4d96b9d94888f16f284e077325d7c758f1065c95ca2d2c3bdb9d8d2a053aa25a9a7ca065c17be8df388f8efd65043bd47bed60b3c6fc853de1f989ee6351e3d44883a38c297a66847f85dccd0b44c236c8c269332076354b83763ce48eb9246642a2359efda7e02fc0da48c2397197800e5b6f74695b4225a0316449bef68414ad04ae452b8a9d9b4caa7a0c34a74b599cbdb518b79fc06c53b7b042652d0b04ccd73dc962943383668bf90344b66d7c868427b5d4caf0d87232aedc40362780e4e116dfd9a2d26e687ab6dfca586fcb0be4371492450ccee69cbb97c3bc8803530d213ab485ac76be76ed8bd999307d66e889b3327d8a4cff3f84a95e751abd43867d9e5fc7d7696a3c6cffa5e835d7ec365bf2aa49e07b82bcaadceecdefda8d07f40806ba2f5d3663bbf6c3d20d4c9429dd332ac43fd000a701d4b71024379d6b1e639de8e1c8e7bb17e8250a0b7aaad97b83f8967f54d5222540b0194bb218fe8ceb04ceb16de0f44edd3483d2203d0aca5bfe2e23ab8bd9a1096cb6c5faced6a4d4817c212101a6ab362d9ac179aa711ce46d12f866f08a3054c6d23c19958f33da9dfb76eb2fedfa19aab8b062afb90a82cc12a5163084367cd6df1c7fd9730d5109936fc7183c99d56187cdc7cd321030241fa5a9b41078ee13654ac596eb600d601a37f0d9957e94044a670e8dbb1707eeb59ddddf7433ef2d8fc81428f12551976f51fa47761d009d1375b2458c3d5ecc965202870b9766b536cc8b7513fae5705360b0ecd71c9e22cfc0c55ac516dd8465fd9653df49c3174306adcc2797e688e01bbfa5f17234b427be68fbce63ff8409286f80282603b44b4989adb6126d2869cf5e960563127690b5e95ff11aaadaca394fe84ac05f3699f332171c6e1687b3f3b6ea9cfa28022b3582983c1700dc5f9e12e106a0604a22c6c286dc4e7437e346c66411b283aa8039670ed411343e168165390ef5de9e5b1465b463f5d0d23813d78a82f99c5e732576a484f23704fc4c68f5cf4f6c3ba30cef6d04b4f4d4ebe49d5e411857cbe052827e3e935d491a6c81077ecee5fe7635002b3b7ef6bd3223c1f35bd83a9a150a0c7c12be2a86a47db27d27a3f9c563375d501d5ee62c5cc71447701ba3c51ce988bd52370e3381289070fbb6f4430ea28d728ef0fd946329ebeac0afe242b39cc3662dfbd7f7c1269e433d22fa207f78910e68ec113056f12e551022c7745faeb291ca3beffa72541b93f940228d6473a855731bc5e71d65771d7c942de95c42071d6689e018c3530c99dff27e265c59cc36900a8c99d5219064f2c1b677df8c5566deb5d6c88c6f44da52bed98d79971de76b6ce92de821c5ea22da1a368bd338eda79c2478b57729b291ed674eca7e5c9c5406fcb0f0ff93f0414d01f8227ef10069ef0ab6399e1c781bad31b0b3562c900191e05ec602adf67cda4801b781cf2de0451d79eaf9a1c537d8bd7b80eb13597081718b5bfd4e713dc1505a0612921d65cd5c70928061888b63f9de46f0178e6e4243a3d30398194c2d57ae49554927c0e751fea2b1a02c29de12b2631c47d12ec44793e265993be2d62b5f9ee6d39d9c0689b935845770ddb421cc2814eb110d203d29c642add6a0d55ee70aa699a0286dea9467a683413dbf1b332bb29853e4c9cd6b5610482382098a8f7384612f0a60beb608861c8585e3274a8a4e7e9e09c336f5406c1c83b201a60aa8f4be6c7067915bcb8bcbb3634d36b068b9d6a0b16ee7b7e0eb801cb4c329b145d24da239e87f84fdbb4780ef74c0667c3352f79edf4092796c2f9ac044079c685f9cafd7331a26976dcc71c7e3f1ac3d5ca649eac4ac886c16594842db3e4c3fa650d3a9afa85598a7f7a29db0245556c941c903ac00ac685793e26f4727fad1319c29939c1bd1b04fb8ffeffd8f621fb1051397f8e9ecfaf8011004d50c54694f4ecb01e6a44d7596b936a24b21e6c1ed675edb1a64b240453e216b589951d0ef38b657512bc1798ffde1e1c439bceddec02e08786c2f8f1e36320de96bbd5ce6d503cf07d3a4291425499ce463374b1efb99dd225fabb653312d75f0d15b367f5083605cb625683bf1e9b8d9f986930fc92c28cd4d86a8cc7d532572238bae4e7a27aeedb1c6da0d7974dd2a53342370d52bc322cd9abf3b55ebf1a4e6d169045763727cd66d223854c8d6710767793943a4d20275178f85ec25800df84afbab1732520b5f1ac61d185de801ac667e8dea2c05959c155747cdc7c880d6e5309ac174164d78f6128d1461bc77209e22fab1f9128cdbc5e0b4602010fa64020c51c200315878419042eaa6a91a20d0d8d88eb309f99c6db2420493a3e36564bbe4a69b65a513fe39efeffd33ee3a8cad9bdc4879550be08548a763d27e9519bc4a0e475947b4d8d3ffa1436caa314a0885ec11d593eeb873f9d41767e1cd1e033df7088e70e4a84ee12c8a335ee8d4922ce8216c1f049110eba5bae2c3d3604a6781209f7652422168fe1c58c0b584122e1e2cb81b6492e0e40e2f9d3ab31fc0a156ef5e268faf6b9e94dc23ea8c710ed386bbf81fbd2ab1c7ca1402e3d917f552be4382fd4951ff8c076636a92a86d680f14662e36906f23380d6587e7e76681f30ffc49233ccad3e5333f33c8b6a9bd553c9b35fe453e79f713eecf6ce56979340d3df06de402f7f6cb12a769457522ac972a37a5cd4b2945a8e5d5d6abbe5785d39a4a27cd6934f250c84e850fef3286c44f9b6713ef11615f20744b7103bdfaeb0bce786f4c939f55ff80aece4c3ff0ca7e6a04cc521c280e7f630344a0e6467d29b64175677ceb2324ccb9ee95c810e82a9d7b22ed41be812b002e634e66889da005b461abd363356882e3509283c62b7eec44655393ac48ee8ac554c6b3c9b6a60b4cccb3ca8ae4d1c3ee458bb05c00d18d32896196a26007a81ad95b64fc5b2437a28549378ceea3191befea63ef8b8140a8d5e1769ae62515b03b739778c07479f2ccb105e4f9ec5d62c657a375cef0ffcf472e70d24b076ca9afa38bbb0507ecd5ef33417bd2e83022f41c8a6eebc256b8abd368007f06b909678ba3460403aa5eaad909cd2f30aaf89a9bd88d6c157b36e9f4bd406175d31c75d2d50b13534f3cc486558d612cccd44f72af020100dfe92bb07db28c06b485550f9bd9ac746693027a2f4474b4602138070f64b5c5fafcd977710068eaaec8547a6ffe42b08d1786e249891f4421f04401d0bd81381aed468c85769649b5a34d2306b109baf340e05ca33f0e29fec4c1638b55486cc7aa4a9385e892be067197ca945b154241cd529de9778527729457eb6e36ae1bee73e18604c1f72788693ce37493a409a500fe98afdda75f782cb2e6c0a2090e2d7f10a831b6fd9c09030fcc0f8994dd7c56c56af9d59ac70defe40e6f519770af21169173e17d5458db2c77b1c18d46151cb148b84994b3447a48a3803e97ab7189158c77b6ed90faef913dd6b9a42022a3068d4357165a9ad38731ca02f8b36c497bf9b5026469c1c0474233a3d2ad383879ad8a8a1215c53bb3ac31845cc6740ef84130836c10dee10a5b41f3de2333188a5b71d083b2ec3407ff627c7fa6567791e8e948f79af2fa97d023ff5b6f397f413280962a7030142f3d99fc6dce9ed63ccb352204e912312b40d4c5e0127292cb8b316fd5f0fe004de1ce450505d569dd278d93069f5f269fc0bf9c739650173b0d9786cddc30db004f160ba3bc9419c53277c8531626984efb67d346d5ce06febfb259a5a940440e9aeb3af86519aafc46fc7c2d294a1b973a657e418b3c0515978bf86513616872d5ab7cf4f07af33f962dc4b0bb30b2ad75e881ebbae54fbc4e42d306b50c8214f24d84fea9415c5f89a2d8ff880ff99ddad7156b03c794aeed18ef6b64cb333961cb15b35e0175aa7b88e5b74cef9b406cc75df547db9135ee74cfb901062fccff6ad320cb66fa17b3810f394ab39bd2207acf2e6d289343b2aa380dcf7c4d65939f88edec516fb944ecaaffc736819310ec438b81b0c7049d45cda323f3a717390b66a13c0577394c80535055a80a5f315ef7966d2f855af91990b344e62d111259fb190f32b0717ebebf839ea7f00509dd7e41f7de560c57721d33fc386f839d783455f0b208e72e542c5e3f09b782e5d633aa10cce6962eec14962fbbdc2e1e8722926a4fb9e95703b791e1521e15ae97f68dd23f6deb5f487a542e973aef59496da7ad73cb1a875c270feb19394da3926add7c69d3b389285108d94759a4209c75019d6de736f7092e15662397c2a0528b57fe6944e396b50213c404d40c5f065e55ed54c6558814cea6daa163650dfc6d25e9c88590eb983ab69a1db2388a6d56804b6b22d993abdf1e06f8bf23597fb4ea42d9534f8be092cc89bfc3ed2831da54e6f2c42488a5c40c5bdb83817f065c478993747b055bda05b0396da8124e2df39323acfbdfc63706fd9c71b48c5ab194ab9203e496929ea88852ad5830e4ca943e9a78111ec884d90db598c39a09a73a0ce654d92539094be9fdf9cb91a2d732aded0b86ee764e7c401ea40855c17fea4892fc7fe9890818ba47297868339437fd8c74efe6a807346db48d10bf94ca5b81948bf4300aeed3e8bf475264a7b4112fa46e72e534c8f11e95e1451d50663daff5edb28549bf1d0f5010b60a8514e37ceed39bab098accaeca49d9f13aafe232901e1fb0ccf8b88c93fc5432023bb6b65291bf146cf3e0632f8a0002ff3ba9365d27fa48b8717594749cf45a24afd5905298b0bceb270d6438455066f2c0170935680609975233e05fe78af718862beb5cb9fdc2d08eecf8da881de44143026d01efbd365558a2b7be3d09f077aeb5560db2cb6f8e4cac55e8975772c9633534215c1e03c463539c42a7dc9895364cd45052ebf46ff0acfd3f139e0b557ed56b2811a34be5a32214a4a937b86c301290f0dd43748f874c2f8464ada6513652e245898358d4209c2afa6ae163887164adfc598f2376b51e9db2c78541e5483ec9942fa3d6e0466309ac0ee70ad7dfbad64dc1886eaa90bda9a837aaf2aa6c29f814239b529f7e459e2a26cd649964efa0e228a8e78d5f5226111c565bb5933f58e0da23f312601511fe72f8266a66c3175142dc8f5984b09d7faaba9ec4395d658a76f5d6a26512cc943f662d567ee676cc8a469c63947bc71f70aab80b608bf547a96bd4f4b6fe907060c680e6df9875f3094a31d84b17e7b7c86cf54b7aeb38c1e0273646a30ac6b7b1161c7e1c04665a87f9870da88f97ab53067bda1ef54fb76c5a8d795e0e82d3934f864d85d3b902f0eb4a56958495b4aa8341ebaad367dcc3a12c83631ac76ee110f86b404791d2829a03fcee61d5e713e1d9073848761a170db340ae7592ba311d22cbfb5d87cccf94efc6ec9caead83911f0b6a94ceecf2f1a0655cae62f24c33d5cb6b27ce891f5b256855e127d915ec0fdf71d524ae01ea65bd66c8609a21b1b64018f0862c2f741c1c12b869b77333d22aa528ea3646e675fa1062c69c712e8cc67e71666a8ae7a2aaabbae2b574b1295d0081aaa7515bb8cf0a3c193af60500d549e873a219d3abd89c5eef06f7e1501c1d800057e298b2e5cb1247e6c2c27308eb94214f0dc87e6d0fbea215b7f96c4e9aa3386d5637c16c66a001b84c9b15792d763ac6ade6dead90b424ee8abe0bddc8e39df62e80a702b181a6456b511343f2bb65f17b756ceb1d0b5b2a0e02ce9d122f214d007be9a6158659cca21b4b8e0dfb29c905a50e131852866f4272f4f9d22bb0e6ca3c590b8053da7ca787b2a2d880dc529f4a4aa0ac37b04882c806469838dcf6d61c7e29d8f08fd9f7403c0c17d3d4c1c4adbb69521c8f37de20c3654aa0a0ad5282c50b4a37403c56a9ac7d8749d9d9a67a8e76c970d1479c10d5dbea2df546ea174008c6990003a749e936618f108fc0f91e7955f7d40bd6b09f80a947ebd6da59e98d9ff0e1da22101bc554018831571eb326f53e1aa6b4ed84cc62991cb4ccddb4cdf229574cad68437b7e9a8adf184249310c6d8275012ab7b50e345b8ee005e83d46193b199b825f96c3070ff647d4ec40cdc61bf8a3e6c8e6595d20b32a147738d692d084819f08e97795c2b6ffe5a4abb8e14937b5b538efe89c7533ce4af7fa29d7691fb8b4b05299b9ddf2efd5f38ae18c48edc33c768af311a377c422ab74a74e43fb5bb0a1c67553e68e86d0fd46201fd8b8407f7cf8d7c3748b21f253f80026d8dc4bc484b4d14a09e7346eaf1ccab1fd6ba476b3599bba89eb5f13d804b264ca2666d6ac00cbf3d8a38827c3381e5d613c792d916d529cfcadfc2d57c02b6df0b286c46fb6a149b50a8bdd989db44309f1bb9b65f6bae4c46f7e279ca3db512f9e4dc15c4c8de49e6b4632b7c758dbd8f2fbff2fe78a8d69edcb1d365a9c63156cfb3ff48ac99fbb50484303ec2dff6297a4317d62f8e7797fbe5acf1288e8f7524ae676cc02b21fe236ee532150e241c9f5c11c8ae37ea54459cab744b0a39e4bd3823a84bd0291738ba5c59fa47f15b766d84bd46a1b2d3717dce66f2befff6704cdfe106accd2317203d55ac102a5d9ca47a445086c347fba29b353c2f29e081f8de785eb7c34677801ada93832107130b4b78c9a0a1141541b6ad636a67f36269355a5c4ea78f7e859427b37abec8d1c86c1813d74d632d06c265cfbf89948cc67f6c9e8020d09cc0fcbe89a2faf4e24aa144fadffe567659001a19b11e679d90c479d501f9bf6cc1656211a9dea605592ba438c88b0452149ed9dc30862c217ff69a4828f5e2a23c9c354ba071435fbbfe7aa9c2ca07ad269b6030bc49dd702dcd622b575462ab3918e8ee3b577c4d2ec852007f9d828fbec6a6da64614f01639bc6c9ad43e18f906dc7c49ed268ece8d1fa97bcc22f3884200546d9e2b89ebb6e2921657e891510fdab5717f3a56360b7cd883f623af5b0c9dfe1f520db6e7eb502789e9a06ffb100e96cc4baf404338c89647172ad9dabf89cdd52d44d140006809f045ffe7f11b30ee69e0011d387a20fe05dadac33220f70d947b3a46ed0e248659581b9a1d6d6897511b1125838cfffdce415bc0fdbaa5f4e5f80a3401e9f6146412ca3dd390e247e9375f366e9887dd244609c1461e2f58075844397b557163cd54e6f688a5aad8a64a3fa3eb90d2c93409ebe54d7b8054633c47443d55bca8587327b67ab001484b10f1b5d52f8ea6a4a17e54d2b0477b1f60d3f98de7288b214de0997ad8283e03f40377989a57824764ec5093efed9735080a55987cd947397d4c809e556b911c1712425e39001b40dbf216af10569bd0a40b52479a3e6b13ebe4ff9a0dd861ee8f7c2b15398aa46c0c6356309ea273a54d149bdedf71180aac6986dafedbaa1f4ea9a77fcb80ccfb8fa6683922101e00b10d068d0ac7bd0b63f421528fb8d2d6a05bc85aec476278e61e1b947ad0178adbd9a7efaed19eb6a4db3b151b1cd5cd0d985ca3409384dd93a692ac884160d9a9e614e00691dd9bb9415fccb6a6172c684894a9d7f0e0580081bdf8ebb45680a02aaca25fd250d9190d603e49ac9e30a28f1b7cf1d6880307055b5000dc174f94a95043a66eb787d21f004a00b9fe1fe73936bbcdc44f3d01e6800926dc54fa9e66f76e803b7f483c97b391ee48b4fcc99f249bb5e200a1bc7d8fd3ff14312989002a0f3f5ac6240274bd3c0126f96b9e0037277ec2bc08344639c3e0fe6d4f89a56eaf162066f6a25c1d1cf6c9a94a7d8d3467294d63006efafb1d6a12e8e35ca8d3931fe9ff1f2497ffd718890bf32760182631ee8048a900d8622696a9000318e6c9d2a23aac58de55243afd5feb8c0e202e45f0e14b4452583186e8904756b0d9079e1c12d4fb664cd9d023fa34a288f8066f83db736dd75998a62fc7b1f5e6b61aae6c8c5780bc8b93199a702a71dc11a9d77883c8b18a86a310ca6c5f115f7a5804421623beacf9b27d2fd7ba66fed8958f666836480ac3128a076759794e074a19ad773b384161bd73daf5f0d337ceca775bef405b6682eb8d04f230dbe6faaaf8fc517d3365ae4b25984585d6cc88544d5395a48f0d37751d8165a901b9fbb9c45cd91a910f9317f9b033742aff293c29010bc60b10f71638276a5a260965dafa789bf03bf786043ab116482e6b2659f4b48263cc00d7bcfc403066dee65227450d663d32207ca2100244e69885aebd3e014cfb8dacf05b1d14a34b09c7bef0c696b04f6ff37a8e9c30949bf0d4df875179c43c98eba90af9e24c23a33f86ae6a5c2efc4ed5e2e2883628866f588a1dd737acc847447b65424801a051e2248c01748bf9ea979845425e5503eebf418498a1aca8d3166e0cb1da2cf36a107422790f186dbd3a11b33664ee2d1f7a48b79096655e4eaf5c3c91451e4229c417a7995280a76643c468eea3428e84a53a29702ecde916950c3966b93d9ecd414fca09bc5bd8401cc67c2e9c23e413b163cae90b688c3d1030ac8602a35c16bf8717c42b72e6fee0d02994a4e30239c79e053964655af26aeee8a7a88b749440c3a0798e1de04798fbba6511a1019330c864a9c30731d8a5b740aa36490715c16708d3037e7230844a247604e955843889906ed04bf1481a7f289432a3b61cd1552f3c47743472ffd72e445e2a217d7c0788eb64bc68f006686de658bc7c22633d9e691196ffeb62c9a1216d6429af755c50d53fd195c093896ee0fc03cbb780325164232a8234f7b245dcdd89c91d3c78c5f2c0be08a6d2781ef4c71d14dda5473b678ab631ee631a70c57416994da668459fe2cc1c1193c3ea04a8f367352e8c0af9bc3c77b1bd406958ffbb3ae4841f147281fe4f369ca24c97b9012eb8190f16bb7759620797ceb9345c64110b1f1fb6c726dfdd86acf096009be458a63ae520b0b77858b67864a9e3e5a25acedf36621deb0a0ca5b9a69e4a6baeb3dfa63324c51c16f38424a5c7e4cf6879365d8881f4bed51bbd7cabb0abf4985d75ffcfc3e319b8d9b78291782be08b5c2fa780a020a08479c670de8d8d3c8404492857bcdc51f78bf243ea7e47b4de6d09bc269085b9a7874db4edcbd6a70ff3ea707d8b426ab72b09b8a666641970704d67106daa607b46f221d27592e1d1b0387e4ee03257ee6d760a7b6335dca3a2651b1ab04d0bf3545086375aec2c46afb022d40f041da1df4ba57333ed2fdcf880304b186fc980c9a5a99b9c8e4e21440d998b83249aa300edf72220767de89dd8d20addd6fa6c38e4502bf3f00435930da85d1fa850e61e24f24c79082658303a09174621051cd7af2c189f2179011b2eb372406e5cbe0a0605577dd7b1587d17c8dbf6e8f93e023d05e8562c4d62f306a05afa43bbbd6a8641870137604b4382953c701a3e1d0c06e123911b0ab106b60ce30872f7d10e8e11ecf73b3d209e88c167b8aeab1b91a2a76bd734779f615698783d42713554505d579187046d23806a0db69e7497f49ea0fc7fa9e94dea942fdbd596acffda03b429044f1b58109d55e09d6671b7a2b401c883c3c19bf3d44b80cd6ab9dc3d38acd53850ecae15aced222080433cdd8e90fbb900d9decda472d1e7d776948e45036e0dca71fd95f460c150bcbe4f4060b1bb79a8888ca3f50d7b118f3551538c8e37ab5811261562418b36749ff23d964c7db8e84522b4335b0d9d06ae0d4c5a1303e2593449da71e4d21f865c769ed1475bbfee8c564e3c2b38e64bdad19a51f0686d95f2634a6dd9b4be281af75c14f102208337893be87ed6fa6d2e06843103da5b967b5c304eca4a07ba1a1904a1aa223e5f2977c2a15a44b5a346371f0e83a92d4d776fdf79107455332ed32f1eefe34b1de4c9a49e74f8b821fb4e1950e6372c4c579dcfb3be801d3dd0a868ec73b9b4835316553642f6de5b6e29a54c32058f075a07a807200f261a7863e75b803c5edacef37869e06b04d7f33c8e9e6f011ef97ccff380474c6ef87ccf1fbddef52db2f81e62d7fdff78d0cd77df53d6f32dbe7bbdeb73f880b2ea7ba5c20d9f7f813ca4940f092dcaa909b3c1c3f3c221c5162fc516dfe2eb4759f50299bc42f050d05ae4f9514ab9275777b25837dfcfd7e2c3aecbbdd78fded193b207f170726fdf8fb81367f223dc777ffb8e7e5badf6abbdf952d9411110acfb2ca7478ebb64b8de750745b0b49e5dd1e0646ba4ab8166cfef3e97f9386c45c36553e0d113f2a0fbf38b8cee4755c000eeb68fa3600a46dbcdda57d440f3ede741c7985fbff99e0b79389f42817fa809cba73574dd414de77be8633605ab9362cb6246ca92d124d216bbae77f9e47ef272e6893cba9c8e744e3fddb47677f774d76982c110fc2f78c43e22bc5a3af80267e0b440ce18564bf0ca0719257001bb5c5778a9218f3df332c30f5be9c42eec4508b64d948e581db617a4c159945a7819c102a4aa4a7959408046cea82142f59214e5054876d7bbba50919fc8a3cb69cbe13b943f639221fc5c19c37dfa2e6882e4114f185dd0fcc8f35b3eb5b607bdfcedef60bf7e4eef07d6b2b23bc00b1e3196e17990f77423bafee98aa660f9fd1aa1be7d1c94bea5e0cb5f2289472e5fba745066210282634540f04e98748a3a73c688284f9c3973a66acea86fc1a39ccaf49dc993a6727ec4d99df84c9f4c5f2174efef9d29f774490f31994d24d17dfa63cfe49400a23aee7b85c075ee217a02fb134961d60ede8f242171f53f7cc8362293fa2e5c11e79d0417bd1f3f5c7871f52ec444d6dfdce0cf99dc37937c53c9379bc818344703e79206a2d287ac82ccb3a906a2934903d19f4c53ca7ce2f324d3d7f99c897e0ece27d7348c3e76275d80d159c87400a3bf906907a3b790a98f2a7a6fe43f8fc472983d504ecda861e4217d9fd9758be6cc190e9e920c85397366284c1591ce7e066e969f01579654663a6194ca0edcc13ea5df4dcf6db8a6bdbbd40eadba9d7352edcb417fb2a4e0e19a446d97b10863021f521d485ad55a6b659165ad2e273cca2a6fba1327e2f4eb1259758dd8ea4cb9d6ab2181b2aa4a5649369a2ce361ad6a7156970b6f1f15e9d71d4efaed9ee4a3ac4f556b11f5b9d48a65557d299d3c64e361b5406bb07f95a4539b0c1c14c1f0649ba8658c9c96d16820fb78ca122061f62d0b70cf22b27d565e21878e099c60adedac025859036734907d2233786ca8b1b378d00823c9beb56f82b371a1b1dfb67af76a3e6557ed8630624253d22c5454308a6c08f2414575ef957f7fa765341a76ff72c9f7c70cf21d7ff2f520133cbc7f6f9edea474ae9043470fcd7c7f02274c19fdebd7afdf2ff6d11954e01c1e34c64cd071ff369613fcbaa0ee7d0408e9982b1910acbdfdb0b334640d116684f9de1006089e9d48035d2fd240b7e5c20d85f39d4eb60a2a3154441de8a49886691fb5810bf0f859d3ae8bd083b4d71e46cc83289a2a8d8906d2249877515f7324243870c1ec70c21a365fced94330f2fc580f71d95fb6705884058fae31cc737eab65529c47a4f4285430883ae085cafa6f724dc3ec7bd2ec210eb27d47ea219cec4cbe64bd09f466d6be6d42936864190fed7f724a9699fec9a84f4ad1efaa0dbe60fb128d0759a86cdfbad7846da030926802f13d04a687e45bfbb2aa81ecf78422e59444234159a66a9465b27d8f5e4ca79450351175808a8a8a8a8aaa082a4e50515191e99f8e00672801ce6096008ec09f3d888205104606853b8fef133404d7b737b973ccdc729ed040bdc58b904454c84ba51ee222959c1a887ea081e823d93165423429ac2450b17e48dfa11a887ebbd38439114ae9039dc12ef7f120a7d22b109d7f279d7483d289ec6f974f88da3170c6d6cee595449e54c52d8f445218049c3c7b452389fb6c8413667ffb82c81f362c0201962f45f9c4839ef478f084e5cb2954bcf7626cdfc549430b43450583880c19a9201f54441da04ef25561be3b5276ea24a89e473abfab79fda4140fefd7ef7e39dde6e5d040f7bbc9fe7dc9d4431ccc64d5bcd795f2bd7f5fc36f3f2a9334d0fd220fe05132ddb1350a65716df1a03b8649482877ed4ee5fbd9becca1873cdfb73165f5efdf71cb7e7fae46a8620595c82532c919ece57b5f68ca98f8df379ab223fadc5f2647f5bbfbe194ddfcfdd8ecee2a013df2f65652a4ec9fc67aef73dcfc4aae142033eb3db0e7fd09def09ec7cd7bf71da981ee4ba609bbfff2e75efedd572d076843c8432fe3501376df8bb2c0670067eda5bb909007793f651d7841399bb02b993cbc2f03823370b3051c296b6f0199b5af5e571d4d035d4fd340f7e5cde1e17d09daf0f0ded6bddf3f1744813ae9a8381aa2ec902e5dae07308bdc4f5db07ce962826ba58b0d9b54970f683a606c858604be91c2228d21026a895a066fb99fa08af8414a8d01140f2b2950334421a48e81f2a13959f1b485c835027b66b619c8744fa242b084125b154b18b189c15aeea7259a96983d2db1a429b9f8ba3816600a3f5988cb0f427462423119424a762e171e72945a5c6800010e0e4a74401004efd09413bb5c5c007213138ac910b221ca06291c6c050b0946036475c3cd8d3df101efe2ebe11ca058b705495d12272b2538d18b9347040cdb91a90e0522b83a5439ac911c7677487258e711e7fb9cab0442b40e63d884c7964ae104da44df0bbe6cd43bbf93da865d1386c359833a09618207e59050d2a9104d06ecb9edcfc751dfdfc8fdbb13a6699aa6693dd543d7801e227df9bf62fd1481c71fe7521833b23165ddcbef5ec822bcb07152449717fcac082f2de4389393271289e9a4e7d2f542807bfb5e36b87fe1d8bec7832df335a7ac5b10e54f64969684b29c4941f2a7110fa23090ee2b23efd3daf871bdef47af18d0227d2337c269d6896a54ce2373e9e5cf38246aa3be942c74f329a50af0e877019470bf0e5209ed873031101126898876b1e7e197228ad0195533fb0588a5a96656bf3001e233d238d12f4b45e4145233a6987258e7f1e22f4266a84122210c1287bdeb046b079c41eea7253d703d2c31d264c90bf7861eaa7cf42005b7821e5ec022f713142a33283a67bfcbc3adebe1966bf3e9bcab2dcff370cbb5855d570f7f9ae847c6f01f61b9a158df515332c6588691b9ef677d366414d4f5f95bb5bf32847e604534cf8f3ef779eee9a84665c88dca10fa8165f9de4d1ee30000a176ffd27c6bd56aaddafd7bc119cb422bc9d16a699d99d24b2bade10d432efcd1c209a3770c699e7276d40b478ed6debcc5958ed29ea3ecee3ba3ba0d478a618ee5d66cff6c4275524a29a5943fb9411930c239a7a4726e90e5f7c8526229a51c3950c1745d7777b7badbbbd277babb6574378c2f7b4829a59452fad3dd17a42092aeeb0ef2a7747a78eb75f7e93e152505154e77979552d0e9e8eeee3889bbbb778f3ddc6fd4d5ea76b58aa4ca79ebbcdad7efb6d4c5d2bad738aed338b0350dec7bb58ae46a48e66cc73c58f23ed5b4ab81ad3da56023413227d82c2b564ecfae68d0b7b6368f56cf8edaa2587800ed566b35edb5bbd1dcbfc3860ea92c32b4ef460e72e3ebea604de42363785beaea3aaee36ad7711d078e3b727d59c1ed7dfeeba5d635f0d2f95b7f0d0f922bef66ecd97778639ffb673401d7da444d6f3ecc72d1cf57fb963b32ed0972ddb592187f725151e7799da5d4395f2d41b3c45360a8e048243046e8c8bfd46708cc8f2ba7f2c4c1f51abe0a0822860a0d5232a811238e381b497db1320310212e6841748eca08bcb074b4d49021b9c505134c4ccc90e7741df1654cd0d4e2734ef7af864b183e372377771f6aa2364827995a8740bbbb6ccaebae832298866c0dbebfbdac6afb76cc09e8f0907653120f52e2414b3ca8be7d6d45c3adb5d6ca231e44ff4ef0c8112c25288d7848ff95670d79e4650d7ac204750c35e1f1be9c80873ad6e0cedbdf1fefd5d140f47b05824f1e52017d0e3aa88396d55852c289c81b26690bd96ebdc6522bd14e522e9149fc479944569fd65916ec06aa4fedd32b896412faca97021dd2af9f043a44a1615407a5ca9446a08168924c951a883a25d282c329f3924822d931fce9778f05c874ea90a99572456382f9c60f65d5b09393f33a3a3a9f335b1327cf9d6f8147addff99cd6effc51ceebd4d6ef8023e87ccee3d00173401c3b6008ba260f159552e48e546ae97c37e7ef5861ca7296a63c928d3c2707149a309d6fe76b7d3f56f0385dfd57aad9f40805c1fd61ccf5297838a74c68cebb5ac23b4e20aa01b7acd94439c9f3c9092669a4b97a7d95805a3badfe4bd34e70190ba51d3c88ccef29836879944a4bf335aef653134ef24e9e0f63054207d9ffb997de43f8b9a73d84f39cf763cd9ccd1c37e2cc5dda40f5f1e70d54ffe6930d549fa5e5faabfa5efdae36507d9d06aa9ff33dcd35f7caa36ed6ccefbe966d803cf1fc6e589e9b8c0abc7d57ee27addc93505fabdf711cf75b7dad72dc083d61b57edbd34fbba0e7219114eccaf35d3df422cfff70cae46cd7fc5e4d254eda273c1083479aa72b06d3bdd3eba008f6dc2f33c80ed22b6eae3fcbf3773e27b2e4e17477a7ff720aaa70a3c5bb9e84167f9ee77180df031ef53cf83ca0ebc805f268f12df25c9e173fdfb774defd73231eca3882edf40fac31612dfe65a3450bf055a5c8f32f1c92a7849e7781474c6ef4bceb79c057fda31e90490b7c85d0fafbadbfe02b849ca79ff3f45d3cdfe271b8bee75ddff32dfe80af0a82afeaf3375eef03f260e23d8f57f72fed7d5ee0ebfeabfecb036fbcf89fff0179bc3a50851bdfcffb3c8e9ff7018f981cb90079084dd8fc0f84c201fef71f78e403e6005f80af0baa70c3e75ffcfcffd7e3f87f81474c8e5e803c421c1abcc0137a886337bdf851c8e75b7cb5a0be6fd1c58f61fe163f90c92b041472bea5bc179f8bffbe0cfee7fb073f0d781ec706effa0ada68f139360099d0eff95e95878767830700c883e7370099b43a97eb79781efcf9231e7005f05dbfc19760840b944913f6e27dfee7c11f65d2cfbff812c0f7015f365ebc78297edf4bf17b23eff95ef537f81e620b1b2ddee7370079b4781f9049cef77c0f917ef5bb9e8f07931b3ddf02e4c18484167f68f07fd462be06dff33e5f8211d8c5bf7a40a964c25cfcebff35f87f175f8206ff025f365cb878296690c14b3183377229babe16793e29d64f4a992f99dc88073938df897810f7f37dc969e6d4e4349351b2090fe7dfa7f7e7454b07fc5c7c39df7f3f1e563c61f5ce0a841905cec131fcc63077bff3f510597c2c9ee76fb0789ed79e27492b2a3fcc2c48663c2d52607013e507ce94266e95166851946029c14108a16d168959914ecb0f47b6193544707dd893fb690a1aa6107243cc0d0aa670414614532061e9ba82aa61534576dcb66ddb6fdab6690f5e0bd2da734af82e4ce794b429959ef780a58713245dd2c49046cc0ad860b901138604655ec0440c42a2949ec012444a0f4c88b419009028448c90b162861f546c161777a58de4aafc38b352e2a4f997c980164cd9a2e4022857ac189538594a82449436372cddb4b0030f672588961690bc2b534bec8ccb9227272e00b1021594c1c2a50b1b1368a102e60446925013c5882ab0a899925c95326accf49a214f5a70c51369c038e17a971a971746bbc2c687ed0557bb32848a626abc5c5741f6ffbb23849a28ae479134432ce174868929512410058a2e3a78e08929ce10a1c1fe38e2663e09c970bd96a7c68727b35a8d6e544ae0f9a026078c5d58cd0b69d6385d6981e39e77daf5b129abe0cfa4e166be18610d31a319c1160638b86025c4115eb63c6149338446c402812d960d4a0a6b0adf2735608dc94d12cea161d5429a10581fd2002183a68d07a618836350bfa0913a73bd269008d996ba1b6b228620f7e2ebe1d98475132f80406a0c1b1868c4d034c609199694c6407dc0c910a7313f88804611a4313614a121c31825213496a670da6c60801041967fe302103e3c262868a640911ac212c372024a122918c18fae7ba8a59383836fb66ed92bafe3b61b86b1588d29732039344400020420005c96524a19285dca5c563aff6331d9ff61188bb9762407a4df989955abdb76df6e2fbfb673db36d0ab46c31b86dcf4a19786370c393a572b1a75abb456aa71d4f3fee7355a6badbfad2a57eb56a9c7ddabddbf17b43e5a0d2ba5d45bd1a85da5b5d2d9cf0cdd0b8e640c78eb745d4b2767e238f61b777797ce5a799d739bdff9b6d600dd563a85a64ff93e29a51474df617500d6489fb445ab4ea5b3da1cabe168f8de1bcd68dbd97638961175ca505cb7ea3ccf5b7595ce158b63dd6c95ce1b7c318e86e3750fede4d8ee2640072073393db91fec1930c0f2629ca353755ad467a5b3b533775878936bf674ea3c9d95058fe471fdc78c2676a33abf4557e7f2765846b31e6aa029b0bb5faa02cd18a8b947774fef6eeaee73ce2983520ac3fabb7b2cf44fbabbd6f5d0d427c5c0c66997eb56ac1b9c1caee55dcdf3562b1af36b7fa3cd7405829cde0eeeeeee6e9ae36a6d77ce39e7a493ce1daf57945ac03579e8d534bb93a70c18d68358d01f27a5e37cfa1da57452570fedd16cacd65a6ba596d2d9e352ea28edeeeec640a5d13fadcf39a766eb9c73cea674d639e79cde4e12de9ae6a45ded6ad756ea74355b690e2ad0ae76fd6ab6d21cb43be5d4ee19aacd1cb4ab5d5ba9d3d56ca539546ab55ba975a2b5529bc3d52acd41bbdab5953a5dcd569a8394eb935acddb364ed39163f6d00f4b5afad032ee3970072804bef1a17fd7755e7dd7b66ddba6743df91e954b2ed9cd29af5cba74b55ab1a6919090d08a46fd9576e336a4525196203e95048348069131fcb51d3229fcaf968954d276c824492499c8a41bfa37f862df216338be4f3cf4bf2e99764822c9a463f837c9990f0de472c992abdd2b371d2a1967f0139a25a694775287cdc7fe01f7f36fbdf78439679d73ce399384baee3fa11af5a3df0f11d85f3a49a7452ea633ec4b63b4e49c39e25219e9a8a2b84f68b870ae3445952677996aa1dae1da7c2996335d2e0d4b6579f472f520d73323300326574c296d8d3f79e6114617e5b1c8490a2af27c570c9cf2fc9f5292e7875357e4f931333848c143273916a6933c3fb855fb96f627cd615463cab49ff3e23a7fae6059e4646e91b34c335ec13d000d52248199fe3dc00d51644a5f5bd1a054681459322cd30324d1d12bc325530164fa54a68a4cbfae6850ec845b5436e5538efe4817266d21f2d84950facd26833ca924324a2349c82599ca27ad94e9d3bfd8f5a154914c5fc8a8860d289064fa39743c65fa27ec6022d35fe10928909e48a221d3974a1ed44f50d890e9cba5233f94bc00cac90f4f30b022cf6ed001e32b45647fa72dac28c60020a3a463c3b5329df7bef5e87fb07dd2a693e9f75bcbfd91083a0efbf7716c2f09e2b8200e0e7c10778c27d883e6f3f0903ed20a3560f9d5c8bbaaa5152412a5d456798d09a33a6cd8daa4058f5dc56385aa0fe99dba5adcb7efb73e0eb31ffa07f7adf57efb6efe7e3eae533ae7fca3ede9c7b43f811c22a5cdf6650824d494dd771181af44b923b0df928758ec8bd14096d57546be6daf1bd76ff7b703ef1fdd975fbf93553a6b87d5fb0a871457208f1e227ed949272c259dedcddbd50a34baf8bbf96a4c98fdeed3b10266fd6cc132488c6c3f4624db0bbeb4e77e6ef7822fedb70b767f1f47f777bb7ff4d2568fe3be071e797fbdbf7fb4b2f6934a1366397bed6f1f934c9a305bc3c8436bededa1ad873bd74477b5babdfdcbc532c74df0e79c200a2b1250a0bf6d1cc7714ddf7ea394b9f31bcdee3d77a7627236eeb2b4ce5be19c1c1d9d1c1d9cf33447e7e61b1c9fd21dfaaedbe1e0803fb3fd5e09c079fb9eedb3f85ef8fd59fccef7c2e06b84f93b8fc39f85af123067c6f92c20dbe4168b9dcef99b16b7ad341d9cc7f83be7dce0d0efd5f886b5f23a6ebb1ab536b0dab3f655df73e7561a028f2d95c2d57cd096c3e8bf7fe04febb5d6a746390e0c8d6213562307b6612c64ba44a648b08044077cc8f4b9150dfa1fa4a17d65081012485532fdcd4892d55dd19843b4f9d26648f6d77094bd424b76bf4904e5b165450c32bd42e98a14321c1152822656c411f708228a0d4ac48881820c0ca251930d50b4661018dc99662a4afa644593ec5628a554872832bdc994524aa9076ccc64ff66b144277fe3644b6ff59ae7adee6faf11b4b77f437b0b82bd7dcce71f599f1b388fb87e0dc4f4489bab1bf62f48c11bda77a0dcb8cd1b483ef5ba82ce5d0e3550779353a5d4041d0dd41f94c343efb92587093a7a68d3f0c5df060d73f9e01600660142c8f5e78ebbd5409e2fef05e9b41a5d8570b3c103565fed1d1472951ddebb815c6bae7903bb81ee57cd16657700840de41f0443582995b606329a9928e80ca31a2254285a1811b244d18245092e6aae88818a263bbce023062b32e030040b8b5341edbaace809709bd9c572c49d4b66e7a282045d13acb355db52a398d544450d68a88801df255a16aa8e0a21d9df08bb301548790c9db868c11244cb1522b422afe5ad81624d981338adcad4956492541e6f161a825ff9355f13e4401e9c7cff0bb4ac03651087d120072905e9df06a29b34d3305a04048f324926059132c80b462b68434edd6ffb5ed6febd4a49dc57b796ed70ca1248c3e8278ddd26d3ad822a7896407aa83e750f23cd34109d4d3834e0b965666101f61f6716a7cb041c53e82dd5354dd3344dd334176dda5c91b72d79ecf1246bb5b764ad35edb51f8b726b3fca187f461f4d7b182d83e1b5cc6b98f6da77fdaeb764cd6e09901f76a8bdfd68871d6a570361589aeb0f76f5d57293e54fc065edb96577ce23ba8b77cc00321a8421249f1619b100f70b19f590cdf2674c2754fcd4806b60c079f8082d7389c9f46df410ceb40bbd0eebee4b697f356c78489b82d030fa947609c53458a381e804671411295194e9e3167d6f56d1c9bbc5aa46b73ba5fda9c5648d491a933139ed9431a159939c56ce9f43f4908d49199b4941de3fc79454d4a4d3650fc95c3466cae985355454b9e228044484a9e28824aaa801c4fefe8833c6b2540371e036cad94f50091bf9d7f08f09752d0861c1f5a3948240470364fa3d72fd6a1e2b68259b99f500576f7bbb5280b4b6ebb61d60c1ddea65ac17925d701fd162f21287f9af3e99c461feb57ef7f6de5aed8a46b59f9c7d444ae0ca3465d24ac3fc87981dd145cedae00e9452e4139944c912b9a52b12b2424c5836c9190b5e20c80118417219613aa94aea49adb6ba6660a28d0f619e346923ba00ae40a9c28b133e965820734d98df27f2378010139ec44f0db8875ad96566bd070dc1ab67fdf42c4dd2a903e5cc4337aaa0d08c9bb5d6e97dadb5d65ae7fceeb3000772d7d9fb2c203bcf1a81c1a39067df3d2b33cd5e4f093c78600abd2577e0e7b2dfb2bf7d57862492f6c720bb000bba8001272167fe2278f843e0f9fd444aade057e4a1d3286642b3269d301c34908d39ccc23a86fd1ea107d02dada168dbc5005686681af0e872bd078d9acf8f07c9bfc95dff7e0974bee6832e2c5847bb330a1915af7d5f77f74761cedf3e14e6d7afddbddbb66de0fcfa3e424fd8f4ef45ff66eaf645c1960f91145c0022f02b3b61620b10554021a209517aa0075a707f65ea3c69ca80c47e579ab2f982d8ef4b537664ca68192e5149c4860d11db8a219630cda64c4a492122f67bd3947162bf3b4d99074d68a822f63bd494e96c11fb3d6acaea17b1dfa5584c4089fd5e35659ad8b788a403b080050ab19d0462ff3c32653407b17f2aa14d98a4920e66a688ed1ae234651fa059420245c5fe29c56a9aa940ec9f5553e638888d4412eb690468968e4c997646ecfee00c0e3888ed2510fbe96ccaaa0fb19f3651a7296b2e6b740842eca75053a60325f6d3a829935134816008b19f4a4dd90e0e624b229ca85421f6d3aa296b7111fbebd30e3ec4fe9a3465210c94a6ec2eb17464ca660c3e40e58bd85f954cd94e0f627f753265445c4e3013fb2bd394e9a4994dd94d0f4d41a06ad494b952c084d85fa5ead4945d29c4fe5a85346531364124294d59cfd3d29129cba0044328d9c888fd964903189c11fb8afdd669cab626c47e0b65a3a66c674d9a16c46e2e62bf9d9ab2dac5071ac47e5b35650110fb35a429eb1113f52369ca7a4aecd794a62c06c3d294c92353d6f9f041899329d3816202b15f639ab250ecd76653b6f1e001b15f6b9ab2297e40e64716b15f839ab25613b15f8b9ab20fa0cc8045ecd7a4a6ac9524f6cb2a4f421247ad6abc48b99190903a80248e37293712121212120b4848e27895727b89426c7105260452c4161b9155844d13710749ec290246ec17329ab22e860f8853e46040234eb165c593d87fc28e2963c1021688fd2b204d593b010393a49d19a4965a449c408993296b2d25616a1991a5094a8717c46689fd326aca708e8411fba5d49459f11a11fbb5a9297ba4febbe44100d821f7f7c6c4bdc00d3c9440ca10499024d10305532471810994406386480c37564880b5644084152bd83204c90c49db0d21a06282272d422081a2d3b4c309d14d0c315305072637dc2006862b57405184102900c20a182b63b82c77460d115c1faac0e5a4cdb458194267f8d3c29e4b865091d7f2c981e2cd68d4141e7aa88ce1a922029d20c02081a79409220d4bca122d2a3e565294b8a214b991e2c35545871b2a41b88298e1860d8b2a647c68a1d413658c0651927433a99694194f94a629243a25cbad42b593822a6f76a45525898e4a8b1914a68205151d56526858b1e04a41942b88a76e76654545894595293c4130ad52e0c54ef9b24dd9725305ca7dc202a2069d62a8542cd9ca6a122a433300000000009315002020100806c401613820184e56ce3d14800d79a23c6858980a244192c3208a6120c418420021c600628831c620a5c87800e01ea2989c61491c76d5a3d007307463ea9273e6607c3dfae697dccb074739424342d4cd5b1a094727c44054bde51d34f4c82c4be23f7933c95b0bff9f6203c453197126ff814c2d3a4b1dafef06ebe32816f836ca247aabe049b1f8d3e08a368d15a693b8586a8cfd82ddcd3790d27ee1d2ac28a87b533730abd7b528c8c5899c1a44dd75133b7a6280ca3b6e1e3bb395852902e6e094483dd9c7ba584ee11e3893dae3dad3a014b8178af0668c43f7d3ffc5d046c35a5d6b858a9ea47af110250eb1bd7cb1859565bd7da26d95e7c7e10b9f6d3b10a04aa2f56e8b8ad1beaf3735f8fcc867d9de9c04da32dfea01403b3c83116f6763a2903b92f3fff07230bb8f7cf097ace31e5a874a1fc21e43396b1de42263f320379e44d52a1fb75b7738c0ddcd94403ccca0750ae106c575358c3fd91f54c36dc8f203975110c20dd88de56fbbfbd878ddbd819dae07acff2d0268131a5c2552eda664078139b7694ab33134a6e8a54a0e47b87068bb4570d2ca05ff15453f9fcd4e6da97c5b1b1443edec3fd54657a2edfec7ea710629bfdd5cd00b21c9cd1b3db20f1899e115ebe0c41663ff00e1ece2e9d915a745c4f11734ea23a6d02a7d31a4011e3d05405e25561b7c9fd621796718a5cf6cfcb45b05995abbabd42a685040c4410e5e86aad5de9e3ae089f2ac21daa6ae8e3c50989520933d061cd480ef61aa44d4b9a96f53c89ecf0a0e73064d06e4d9b5d136597afb8b3031b3fe8083754bf3d640baea529bf7328cd6065be285572ea8a757e8076dc6e41949224cb2330243cfab9417214ce5f0309270fb3aa73ccfca6399ecc3d647bceb27ef3e9c222d5be4fe211fd43c487ac20e6c246a5ff3a0036438d5e713c3fc5145db92b122cdbcb02b7de4f4e764538ed42370cc719bfcc1e5c3cb9b23882c5fb87bbacadf2bd02fe51bf57068f8b144d893acc8f64bb497537e6bf84e907ff0d27708f2c3b174b2b0f8e6fc3a684bc47e6fd6a2133e8495f54d8b0bf3a4a0012ebd76d5117d5a662ea45f25c0ea9d422c782eeeffe2f1b2897a3cb227679700bb8047dde4138af16211f00a858c3c4f5dc1871c7e9efa0263aea5d2efa892c651e807c668759ed2feef344d0a43c1c6bfd88d3a27556e2bc26eb22ccecc42357848b3098fb6c642bce4065ea67e6798f0ce527c497581ec3dfac791bfd4720047ae257d9eba3fac7f43cf686e97128a7ea463457eccad0536463c0201194ac9985443bde53d1207e3108abd91e746b544f97c0d260640d1a97946cb2cf6f76e6a35aa99674c8a9d28a4f6a5f06e601e8594b925c5f3b5bf9b118a36a1424bef19d7cd594c5c5bf1a8accd2395397a26491e04a5c527bcdd31c1d2aa5cf9396316e725137bcd39c327f0fc91bf2235d560ca9d9fbdc6dd0f6033e9606a224d4b4b98b6a59f0b60a7cafdbb81982ae89c8504e1673083287abaf2c78ea297831566cd68e250961e832e42405b1d9fa23928688ce9f18c7fe89360c44e91ec6667bb2005fe54ec8458de954ea53b204c888399fac203a40a719a728e303066217903c0c999abd8f9ccb10b4cb07c9003c9cd9df1f8dabea96a6695d46890ca111ac498c5a03084684c2d82646d020d58eab086b13520f151f6385be33171692073aaa27ad62090b4401266c3b987b03775f1a39a3a8e9c2f269027c9aa92f36ff77340eed666cf7f838aaec279142a9edcd93585852c1c959182d4852b80e4f36ee283f86179636346c63e53e6b9eceb6babcf9f9d00c6e36ee272af6323cd42c206386dea7c82312e1a28e3c9416a276dec1ca119e3b992516694d0d094c0b6862940557c4dbe430becd51a07f6c8dba879aac93fbaecc0d55f7634f3a659a201def37083896a278ca1ccdf532a3aa8fe8d81c493191eac0d2f8219f7a9c4ccfec233b80ee1182e7f30e8268d2459851772f9ba2f314d3ac90579892a7f0ed206f74f90b34be89f0b8d1d8215fbebcdf8f6c43e3119e26432ad6e8e8f884c806ff3fd0a8a387fc77b3f580b696643037825c0b8f4822bb998a565567253edfa81c04ab2da966864a2a3c3f4eb34b3d43c7661388c6af2349e43d95394c7317c0587f2898d94a8fa53e3a0df190c2582dd12b1c65b25f6cbf2e9d3031fa5080f3729568edcfb63476f4412df7a045a6fe5891ec1754cb4002ee8880e12482e41ec3c110d9239c0aeb8d613627ada0dc416f2feb428a56cab2209f0291ecec6d9748f618c5b4da2d646d5ab00eb014d986347d99e77cc3d8c08908e60f5e2c58b63be9cddb6b41970a139ca2114b22bd8a1773de3a45f8d127a34befd48c1ff782340c0a0560db95ccc2d84fbaac47319985d7a4dfae778875e24a0e976af3583898daa8abc7bb62c40e32326eb3973495eccdf4d29a4a84b8c3b290e523f5524f9533401c870b6edce022e3443fc1cc0efb8f0dd65bedabb2b99b6073800fdb960184f1517edd2c9dedea1507e5ab679b014a9634aef92e89a4b667beab96b4a011202bc013d2f659b461517a50120855d5c23c62094bdba8402ee6f9b7bf73ec888be0dcd2b20d95f5a3c472cb18293333a3450a7ecb6951ac5e01928ddc9526c47c613f655836ef5920f19bc8455cf14d13634daf42a05f7691d3db2fbb068fafe89cce10ec0436fa093844406164f66c365c9b74cce3f0b062e235f390621e61d1f5c497bb4db2a234e8cdec3d175f516ef1b5ce9ec3f6646e887bbeefd1fae3071ef45a3e4ee8ae2f517880081e72eea4bc0bbae042fe41cdeb6619d8630c79336a0a7fcc9d3d11929b5f25e715c6b437722065defa53b6b78089ef787c070b6fdf70fe33e07b46ccaf6df44432a8204d935ea69768c632c86f65a37b258778faa06e30dc20178077fc2cb6f60e9e8fa4ce1fb8e9941dc7008e69d32830d0750413be05563187648a78b094347c8fba6176e44ab2f5209368b9b441f681a3cd9ea50932f02262a36996f607da71a33c8b58012583bdee0baf0872b18c8fab4f8dff3b484a879c1c11fb2522ea06eed2af6cb3917c704baea7b8cd6897cd9027e9a264485f866c382b4e9b4e131748c522b44f7f12e707991eaf78a8fb83c028913427aea85a87eab486bb08de0dd161e3c18ef0179a0e69d1e1a0702aef80d22ea2cbe49efdcaf406b7dc257b90402495d2a035b699f63f86cd5d348a097076198dee208bb2d80254efb81f30d4431f4cb06454fd377d44e7bcb22c78ed4e5fa9a79f4463cf1b9548e441409c5db8531d0a8da541c6254a8cf78b8cbd42a36a87d7455322a91e2ba919e607a678dbab4dbf18931d96a5c1d4aa630856788b8af58cb8acc984ac588db95860277dacfbf952e0c7d3adeb203a4535d4ec8a28c01efec8925aa89f2b212e1642f7660a29b4ce4a7dbd0792303729030b59f7094eb2aee24b920d8581c64807c6dcb4581972a15aa8e68499a09828e30152bf9963248a9fba3c5e035214a1959155e9adf638d6c6483949fe6290053adc37a8f5d86053212bc148bb08dcf8feb04306853e3d2b3f641afccda1f6c90c986642fca22db0d58d2ceb7c2e4ce380f4cf46627cdf581f8faa038c4ae640dca3b053dc070038ef388cb834fccac153c3e9f7332cf58d5303de2572bab74c868811427730da9ad83a04033a9605ab1861cf48620edacbe572e4e4b92cd3339e27986f6a8d7fcca6f15648c1048dbc91d64e6d9472b1e4251bef92e746a4b050b0c503036aa868bdee16e883c9678611cd6e82853ed46027d4ddd1c7520b1aec88aad9b2922764a1f76f384d9993551f6410dc2ea61e71160562d18d06bf4aa399bc2efb8bcdcf23651039ad73069b4f7d0a4b167a9bad3b9c22397459362abfd5af8dfd5069901792b1089c9f639fa4e7dae3f493bf308c4fc32637849b354e677ab13b7a35301062d5275f0415fb01a52ac4475b9c8ef1a40fbed23c19774a6637c0da34d824462e2fc461cd8e7ce9d403261c116f813336688c98a616ba8860629d4ee6cd62319098df3521fa93769980957d84095c5a81f3a6ca5311565ce4b25c243ab8f38d230ba0a12e980c7f5a95b8bc42dc19baaae487c33604f5dd1793ae17da3c0beb7c63342c8648454b4d2f8f9bfe50307c3113ff289cfa0abd6ba4bf8fb721a070328c260c8e9d75180000dc1886350492bfbc1c319bc999cddbb8c6333ae26c8c96faea20111a06feef4835331eb680cc012492f5093b09098da1c3af17c48447b516bf6f21ea54da19001149849d3116376f52592247648ef806a40ffc320044bd978969d0a8587dd26d0862bd0578fe3c87badaf9e28d93c4b1fb651e9613324429849389926b7794c09a1916c9ab02c8233500bbd0e92c81f1181af87e380214644b261a7c99ee7c86c155f76ad60fcd772f83af49ce96ec661473074d7a5f67c32cc2fdd71d8721b1346e0a6f61ba694a7af27f452e92ad5c24834dc0149d854968cbac5ca3e355513b00692cd64e9f3b61bece82a1f57c935273a0d8d458345f0b9204c23ce0776a902f373129fd2fcbc068f3cd36110b6c9f6f97ee1178138863e7c863647b0c5214a1d76c2b7f40dcfe4cadec1ee1ccd6fee9d61ef7efe665f1f4fe3471be7725c5911cde8ee65eee77e76a6cdfeef4b5a25d25cb9ac2c8839f84c7d589ccdf9886869eb300c1d7c80b49852e9b8114ba52787545314538b10a75e23a30952f4d75111dc428f66962e6fbaa38329d97f06aa655e227cf1cadc4d90409a84b831ba926f66d28888defbfbb3e8d1674b10a93f155afa178e0f509da2bec741b1a86dbe6446a57faefb90d7dd7986f60c556ed133e8c1467afd4c0b77009ab8fcb59f1e1cdce6ea77fda216eaff9b43a5be736786360c1422776f99e4d9b08439453e4471abc97c542fbd4536b55ff051486b1ac200a90a25d53b7fd92eb21a5a55f6c7c5fcccf3c7e0f93579b70f9ef52533ddc762e314dd7246305787e28bda4d3af11c92572db7824d26a602dd8ebe212d131a78995f4fd0d0dbe272ba9d218485f5bb63ec5b50c854785fc413e204d73797ad3d6cc67ee3a931cec9ae9c2c05f8286ec279fbd7eb3d99dbaa50bd3158e7d605531f6ec09d89c908c84c17e24edf3e6df93236ae9bc8b1ad359829cab42aa90a3dbb29594140bcfc40448aa6713866d3dcba092823bd6940b6abc5bdad600fddfe5cdebc9eefc57633b58a64b05c6e0bf7e98344f717428226028e07b16c1c496d41505a1651d684686a1579874244ed8a70314058d044d0d12046c4445ad28a84770735ee0b851e816135ce441f1e07210ce445160d20de1091810d884f77eae6f0984208904480d12006e4440a6d21c64024c20488633892d80fc1602b224023909144162410050d22770f7c40db12bb28070d321e4df4440c72d75af40e0739da2b9a62224bd0683c1a5d56fd5ee9574480ff01185fc8800c44a1a1f18a12bbe60b82b1b2693a0f672ac44ff5cf47620cc298514b0311de52b2f8f1a9fef920c33213c458b5e705e6742f194d2bae2bf5fd0129d0bd406cf05329d427e8fc66fa622b80ea5e48699615fb3340489ba78c9858b5e1136a8a32778c927fbcc9cd99d9a3bdda0e311d029d50417b342dc917822f9fbf6eb38f90ed5b12501aa30dc2d09e46d8523261d9de2488fb16522ac26cd18fa1746c085e1670bdef78c1f3d35e8c27a54816eb94cf4fe5ff9b6992a72df8d5c9b84aa6254e826096d247152efa6745f14ec1bdce093e3b2318204a5199bc346e4890f997b48dd7e136bba45c6182bbcc9819b05c8d764b63723af69c9de24cd6bd1137d7d06335fb9542289cc3f66dec9dfac08181fc7ba2ce4b587b5aecf382de876238d545e5d41c04416dbeb0db938b197833034539f5a9c91b0dfc25b553c7c8c1b9718ec9e97067869848cae06af27a1bdb31e92b821baf98a2f5c6640255b42e23d61a3c9958c855b5fd2f79fd9d74cc5215178c38dc8da3727c90016d9d0304d2ca6fdf3b3eec1aeba6874132ac2fc0dbf7968fb90a93598d6231f390652d22c3605dafaf3452c40e9d422831b3fd14c63e981a52fae9c42ee25c80fddf7300bc184685b121589b2137505a14bbd0edbc3df4d21d3cb400badc6cda14d2b5c5c4ec9e0796e21866ebd815bb461439dced4cb12b73136c4f588fc8444c2f2c775db0115b63ec9002b5137aea0849f75aeaf739301f6cc4cc86a2662638c1a0c655ec5e0761b78e43467cb3cabcc616cc2528ef77d47cd753597420e7efb5ce59a8b6a7e474c55a0f8c1b11b301e51d94c549d2031bae82aba29a049b37fd0eff0c22b0aa207d0abfa295e82504ca37bcf896abb4dd06a886493613311dd12511c7d536c1a0165e62628193417e898aab523d961c1187f01ff012b8ee45fbf11cf436bc041dd696e95077cf1a90f40ef67afff645a9340e9c6ae96039551c7140a76398e2818ad5130ff7442c5d396c51a6235caed36dbe4bd7e1ed537cfda69ddf48d9102bfdfd65b4dff1a7b00bd5f0a4146e07478740d7605e72d6e8ff126f66826d1dfe66d4eece22976b90a689d499a27a3c298d703928a56cc9e529e35d453e353ede195149b458fbfadca109afd03869102ef118fce6562b6f063c12da4a56587364b6157474bff42533844a8b2939218dd1cd7970d1f33ba64f181619a12bbbf7e42ae6622e8d327d64397a20bbd718d97fe692755d20db31ed5145f442253cf5c407841e03b1d63b703f04990ddc051d0021cb4b43bf3901a0032ccdbc41fb4fd3b87d8cc9ecd9cc45d9033952fc448368d19e0356851226615096244846e97a808f496f55fc7b5bb1b8675ddec3c0f96b5bb094ba5625369c7657296ec46fa3e1ec58b046ae1ad62e110958e415ac591afb4165ac5549a2f6c7381cc339889cb72d4538d31ce489beabc2f735d057834a21ba43b9246155e431f03dfad61b104e4276ad835e70ba978fbe717054a12e735943ab2ebf89d0de1b38a299f53097715077f62ef5ac50b2a1f386097aee0db10b9fee6a3494b62c916370d369a96feef23f31be8b1dbf7b709a65318e49042a572235a4d09337b61ebb6d5c39c3013452bfe310ae1df3d41329907b7030e4394eb1eb50ae41999c18ffee47760a15e239a065e43e0d581cdd5ca70ebcb963a51f8e971efad02e72ef49664b4a4c8957f8d90d457595c3eb388f9bafd3a9726276ee2f8a70e61bd5ebf5b46a6325c5099cc09a6a9e7fe579db68cc08395ed24944e1861c34a91e7201c1dbef27d7a236a41a90f1177cda02a288e066c1ea2762cdca334b5975bf05d7d8c9bbe198c180d847009f7d53767a2fc7d3f02274f5a7e0de9ab704af58a1a38df604bc4a6010e66db9bbb49338514c04ea5f6dfd281ee8bb4da483333043d87a717143aac5a2e6b817e969da41ffad48c5e0815ba6445bb07a14cbf5af81c8822b3d027d7b6d99a61c4ed3adab77951187083a17ee1417406fd158fb6184ece0a64d80b6c4451b39c6a2f3e148e717e6459bf683a2f862fecf26c50f08c6dc8b02553918e0dc304db43043464addd20f1dbaaa8ab34a48bae1365bb7df3020f42dccf362d10c560ce3737b8197ed055c074eb4e4e73cdf74a4be69737de89ee516a60c2324638db9173c46c670d226c0da116c141d37b932488308ee4cc06439babad72819a1c52f3cee4de2563db977cc2f7cd857c8553afde077dc44dd276658de6f2f052549125c38a58ce5b7ddb6976df5af50f30bd2a274d99ff29f29b7c9a1a10d7a1c69e9c6005682d1a041220f08604ede65d79d954056c9dfeadffa5f56e0049c6e87fb0fe8f050ba5d1db3b87bae7ad5179d08aa213066c39bff808871fa34e70a407b3f4d5401201267b30d3046f31315fcd97b3aceec55b8b8fd89fd11ff2c3a9661efcdedf6f7751bfc4c6dafdcea4458ee5c3608678fb7afedbfdef456bf7e5f8a797a0ec9946e6bcc00627346ce688970fbb6573a721114dd2aac32be74a4e06bdee0a87c573cfa75968737a4012e0a8b2a0afba7c13e2aff4e5739c029acd636c90d546a9f2f870fb638c18438e418c3355fb01b2d79fc2143b325c5deaccf16ed600f6ea1467ccbe0b5c50f816924e84473a1874f096bc2a09edf43252b2377c906ebeb3c0dead7c2efac61a9cd81b313f98fc13e527ece2039c051aed66dc90c54149fa73198486d0838b1007b82d92046e599a61b177fb7ab30828441da23880e47401035fa4187b3e23453acfb91deca1a108a352eafa21d8f910c4416fd4a3bfa1c8749b8019a8af1b007b52aacc45cb3b642863687d64353030e1037622797a7b2179c816004a3813de4ffaba9753005325327b9bb04548c42c397b3092a7ca27631024e4d49c4faf4aeacdb4f62ea59f163f386add9d9cc1474eeec54968b50d33de79fec9a12494e958059e170ce02c52aa1b8c7ad77ed8c18080189f310b2ff86e5f1517d5141445b741930b08ae39451e071615a1b900e761bfe953ce0fb08fe26dbd9b175b43d93b01cb413cc54df8d4c13cf43da7c1daa9270cdb00ffe6f2ebd1d310f01aedd4d9c9038f4453fac5894b0e250aad8ce854f142431ff6f615892e42325c0f76b1b23c06e19691dff0f1091b34f7703abaad8e0889a98f7b01b0b574d2474fe381c313f7164125f519631b037e60454cce8cf511fb0f1b194cc73704b9d85318539fedae44eb445451cf5bcc1a612a37774b693f9e34e4957adefc7748afea7b7c8e3e0a02fd1fb171b34a3c7d1cbba47b30831f3eac4cc12c5cc570748024fc7c298e876b377f545c93c5b554f9a751b4b28eb7bd56d96a01ddffd751c9f52e9824e41309ee9d366c1582989fcd1ea027ec325e10a85d8f3f9fe171f09258f0a334e04adcba5d670adccf922fa23fa6b5c53c095fc75567fe99e830b75c0a22fd642e63ddff1aeaccb97a54dee287a200dc6281c258e17cd9087e9fca2fec5a550aa195e7daa02c58790e306383b93266af2dfd0d2a55dfda73b0eded1d65413c22fb335f307215ef4c57ff17c541e338089f486e651eff93c40d80799a16af9465bcd661e9703a6b4ce52ca2e8c49ffc554b3903a6e2501921df31542b871865952fc189e1b16c873550179015ce6d7cb2053024af51c6afbe8698e81e1a41388ecc699698e0f71ed5743ce14bb94ddc6344fd9bfbe039ecd21cc128bfc03c94e98354dfa0c3dc70033ebed5658939acde2595cfb2d5dddc79cd81a7de5faf94d51300ab54983b5e1eb283d7d134db08c6d5c53509bd84e6e42d96c5d3e74a50f217282f5f71a3e33aef885a6ada89adaf468bf7c67e35b287be6d5e36a5684a41f1febddbaf268336f8aa095352cb5df155685d89c8fd3104ebe6f6ac21aeed3206cee6c8e5ce8132dc8de69e6b882e7570b928d2f2a572bfd865393a337b4862a924b32f62ae1d310638eb48660c2eda9571aadca56326536c4a5b791dff124de5482a3efc0289192abc7d5e417fbb158a7f598b6f704e7cc7aa0eb563648728bcc120524fc5ae3f40dd9ccf149368b359ce5eb8623a206d255a358fa126c46149a0e2ade73b9a05b875a4b3c84a9b53d08fbffecb1d778f5ec935fa796fcb6336f84af73ba2f861db3b13fa34ef852ac7a3c36c0ee39dc1e86fd7f7eac6bb832bb9bec7c2486d9cba638964888e227180255d8c8f7ca4759ffd22c02579885843474fecc2192cd3c49f9eca53d0ee9c05f1431208acb737de6b4493cf25e702ac52cf4bdf79105e87352698eb1e0eee19b3123609cbd135d99d38ea1116a87c4312c442584921d6375c7560d5b226e818fdf592e11412470aa6967608c3728d5a61681921286abf861a32b3f9c8b51a797aae957b509bfe24ea82c7daddeea23162f753bb324003069a6de16e8d5b0c51c9ac5e7d705c19a82a9f4a313d24522d00c815cbfa3a84c82979174ea1603a0fbc5745936c7b0591a6c1048f33d43449ebd809922a882ca4656b959aa693372f3886e13abc60e6e3baa9207208740820c844511f055dfab74aeb418a4163a1b26f7305938a92aa47899905ea38947985b95a67f74ffbf70417cbafabc9f5c3f537a4f54c203302cdd42e2816b70b6b6b8cad507d9a17f1e0ca57835f45833862a7eadaf4a98e3407e10a159d6f3c9cb1805650e088ef5c7fc425415cdfccb57930472134e307ace3f75f2e3a723e77c96b40d86bc6ddefd5ba1a0a67854773351625314b8752f848f44c061aa22432544fb114948ee409028a8c80b8267768990abc66b9984f14f32850d87ca1082157842464d910340a0b5847b4fbf0ae60149fe7a96b86e0a1bb8aa2cbcf8f9d8a8d2c458edcfaa5ab132ebca3acc1a9f0476c858e28c6a9b60b602e5d1bfdc260a481cb7fa1a136cb03ae4721e072e4a138b1c05b661fbdb668100db36eb9abdb9501d33f8eb02794f1226513a457b993bb5e604a370bcd0206facfc9bd177532fb040c43ef520723201d7a675066a83f9a0ac9d0001d78d0b4454f9e87a94949311d9b88a799b64b9156e67e1213552394cb1ce5d5c668888f9d678eb83ba9cefd66dfbddcd3d2d02ce5d9790f2831fb218970537a45628f745ec18d24169c73d45ed12495f7abaf128a3900bcdc1a5a6af65c9c7cebe7e2c20a224dfb2034f03976767a0e541f6676700776af2db31514663d40999137c17afbcc38da3e62e021d83ca3edb69f3f5a674606e1647da29940edca10eda257356e20c24877b57e85067d8c115c508a14304a05f9ccf0636956034d7caeb20c50148df4a3a0343cf24b772f9737afa0d170f6c84d103122e4ea815fcaa643240b481a50323ea566eca04bf95930081cb61ac0fee4cd00d5e2936d0fa57b55a3e38a5f96bc2626d7ffc22385d173591e99cc0e7f77ee07fbc020c95154634c1f2525503e0dc3d80bca79ed60de85f2b16f7de8c5833455c0b88ff1cc5dc8709728efd426c4de9a64c96696fc926d72ba0f54c32e2e11455a41990d7e6bb2415088fc986d9dde848fd84904b85f284eb7ba2a0e220fdc009032418b4e370f62322da7ffd6662a857513b5d9304400df16f92b905062cf7ff0e33ae60e916ab22c538f8fb48bcc9bb10c20012cd81531533bb913a60d7e485efd0a122520a9ae216736f160c5b37531385de6809ca92fb1bdc020dec4ef678f5e20693e7836dfd855e2fc8e0de1f028f7b350c93b86d70a149690282e7283cb73430013a8a267ba31adeea48e8b35dc2f69c5eca69204da7a5cf5d3e7867cf59d758abcb6d90c16c1384e2a23848207271d629ed7e760e3ea2894f87a88a8ce353f59f530dc3f0e52eec4003e836bf4c30fc5109c7d4cda88203de1abc9746cd59e7c0c6dd4cfdd3570608f666eeaf52fcbf816ab3de6148c789cda37f1dffa1894949d0cfe03693874e209651c536f301e907ade071b39f7dbf9ad929594fe992f208ed57d169fa558c7992302b0e8e5710d35a759b47b3f0d15ed15ae15f7b50707287ea5c19961adbcfe30d9622cfb35dcb174ba2d27b6c6392a5b26ed0a88ba8b591999c6c695bb028d8a618b93b1bbf5baf41b3f4c35dafe57b4af893433960dcf03f64a3d7e2f384f4c5e76c17c6605faec9be775edb2f38e4f996098204194de9582097f154bbb36c2ed56a161509ef8910b2bb5b11ccda5ada166c44463f70c6e0a801f836dd6975088c570fea583346e501185d72fcbc567699480a50f801122ef565020ac8920dbc9cd790450201ced064909761e60018d206fcf6ba4cb2fa30b9d8598a6d387070809a4bf2d83c05e3722209c6b4f0c84d7696f14ec9cd3e2adac063066a2e6230d79eb125a8091b61b825c40a9c108d74521e4a1311137a0fbde91338acf8c0be96eef0e0a478ea9539365edeef508a0684751b66fc0201781f39c855f9a22d9029212d5ef437dcdc3be94cb6df6fd5409e95d2d64c4a851e6cd6ce0a3ac16cd3e671fd360b16a7f4129e6d7a6bdf75132b5753862086e2a9e776c89f4afe97cddfb90721d0c85d612b5a66515255ef55bcc93ebed4ca6da3b97d0e832a795defa4dbe4884cb356d5d7b230539d3a3bbc00e033e561698517547e4426f1ae932d5ad2223a5add10101e92a45339fb0d01892b5098907f77260e7ca0a708efe7e7e7180b9e145b88656c7a41770752dac0c51cd1c366a7792f405c8c23136fd7d7a4ee03db40b9902051e153bf15d3a4fc627cf4196ce3b6d98048e132561b9eb12a5daa0e555d795add1cb2df255679d5c83efc198419a13aa6182dc60d69f661981de801b02763cdb04723e2156c90bd48ce5ac112fb14e5300e6692c8f80eadf6ff26c19e2865d72bc3177b9046a58fd4352f87bec048772246d182665af97bcc41a57e26864819862077920b70a351d5c1cacf57001c8393e920ec752fcb26c78f319adcca7e8b9900daa0d38be974ec7be631c3c590176141f67d7f0f4e8f98dd8a3fa208b2f31421f02598d896d55c45c2f8531896f2dde5dc1ca2751f356fc31d34f6055da806bd84d0b0a17466571f2499070a70c144069463dd159f4c792322872559551a9d0035409892bd52c05e2e69eff27fd3d0cc35d5be38200e08e79031074eb147e18c426752dd94b38af53d20797b3136753805bc767c2b795b5dcde0f9f7d4d9030ade3042b46c764ac198730baa326f0280a215e5579c819013fe0912fe271c193e15f3a99fe6670bbe6d40b683ff56576722ea0ea7f495600ffb5378b829eedb82bdd5032ba6cafb092125b9cc314a5475229a12b3b01d89756e5bc661d733f995b5efdb9b78cbe40bb6b9fefb0a810e681933283664be12e8237b1d0cf423839e9e327e798a828ed914685bd547f6217b200a77959452641da76ba019b0b1e3f016b7fb91dd34fa8df6ace716183af11352fcd9093faf85a75d86b659fab04e908740c575f1cfdbfecd67854ce94b6ed15dc1f81fab7b6102f4a1afc4dfd6446a154a5761819594c02af86ed22b1247424e5ec6a9a577eefdcfe0c852555e03ce4166f100ae381380fd676550cbe85288786c79190c9440b5d6d3dbc86d511de39ac12e07d5f4a15aadd80f03b548ff33151ac6bb104a015416be267a8785e35c550fbf1cb2f78d03a9822f9025ced1503d173957e52e3044fbb7f487a00d8f9f3ae63344fca3edb78bf7836bca40531c2154481c09d70f31e2bdd12c114eb9380f7b440b107e70d48a4b8345c9811f60d1b827c419ec02aefb8f79c941e3b723f96c4bb7ece044ba8bc20fa9affdc726c75ff726e735c0505129a07db72e61bb750baba4ec5e3945a8080566f11a54497261a6e3c00555ebd6b2dabdcc23fc6bde7a39acedd6159e703c1cbe852d6a7081a02c1955d4311e98b273d33f92c9266dbc0417492c4cd3b4176235078a4e794889cb96829681b4c107889b6df3018331d91e4002d4aeb0f5437085f12fa4ba54d8928d74f939eab1eb3d51b79015991dc52ecf0ebe18372e29104ff7255a290b7eb5973d15b66427979caf50d711bde4073e6a8492f6a1cd861ce618e2517fe8565abcf128442d92c3d764e9dbba92befdc0f94a235ccf43bce0a0a76f95f751fed663368504ec5977b8754015797b729d06cb489896a0d893a0797eda31e5546392ef60a2b263a63cc69cc444e14f973637a2e123308a602c08244453f00e1c8c749e3e3f317cd5288ce4179458f69dd46a11c69c50de4de976e4033c8904bef531dd5aa4fa922deb678b649d87c9acb7c895649774c255e83eccec761dc850ff6b670d36159b82af7e33a88e706025b5fcb7d9b16943013f12dfdf34c1c601adc0fb5fff56e72b43f97a8213c1180c835c4a6d9df47a2711723dc550107806561e00da0e9bfdde88023b49804b8cf29777d6e1778ef0c28814d83ad20e93e597e1cedf4947c38e02d1c4cc89799fdcf93eb98af0812369f65b9a4389e55d68c15ff3b6bc3214509a91ab71c6b2a44f9fb79828f0c0a2672a2696531c3015e049c9d4f9d2768401741bcec27987730d705f0eef34e10a020ba022b030bbece461c11d8edbd96cc6fbef5f38fd927b4b2e4e789ff3524974f7224406cb32888ece14b2d15ab5458e90cd03cd9348897bebff1c587d1b23135f78a9b55375dfa828f56d85729ce12658cb73c20dc2e539be8b89b77587967ce01d2f084265078dfc1221ef6a170d9ec3cafb85a99dfa38aec413b0ab80c269592d8eb49443053baa46b01e9613c16ee0b9d444f6b4a31c3f4dc0e8de1592f9103582c0620ad26e32c7aad8ce96b6e661de45b1cbd13b8506a0e3d9f4125e48de5e06231fc90d9f7d24d6284536d1c5911b88da169e64359b77d5840b23f950f7971f4bf3b91165093cca29c156450e9ccff1286d920c2cd9189ed6487af7087e8e7b2bf925bbfa45cc6ee3853a35beb0bcd3dd988e786015d67f39d8bdbc3ba1a3f664c69a54e016ef72f63e59e6af0b2fbf4061890803426072881a9b29df4d26c66b74b1fcf74c5b14e15f5e14d1313bfa0b60f2512f684b179ac73816bdcc0dd800f536b92a505f9947c91301188f2f1d72752200df409213db55fd6bcd4b616908c450a38270564962e3b69ec30af6628e4a6b53044bfd8a530a38dabcc250a8f6864a6ee22bebf5636b3e3400cd2d7d1d6e82a860c2f85ea29e87f9d40a7d8c9303724acc5830ba6bcef02108483ee5c3b50b59b3b8d429891d254ebc6b08cbb9a9723e70cf678a9528c618166eacd10f068b0c2bcb6318651beffe8eddb8199879d721dfe063854fc67e81239d9980c3048cab18cee98b80fa7c7b006877e0bb5b15f905a090258632177b4a4724eb9d6b477ee672f8271c3a08495400bc0d6110d18fd82340863c9b5705e02525c71caca28b32fa08f1f311878e4191490bccb1ce7b86a31de647d58c02b00f0e74b3cc62620b4ee29fef31a4a270d14b448145a673fb3b1b572954e41a7ed3d2808b45c19f6a9e0ad9e9ad85af9d5d3bc00528b9b1c26e3fc06e34a59533e8bc262c9bd0c44104d213bb511dc0ed514987c91d60a50847e186a3ebde90fc09ccc67ceefe89278f4db8aaef2a5b90e010bc7b03d7c559eeaaa3e1a503ead41666a717192e82b42a94f1da9b120766bf6275686c0decd357a68b5ed91ba6d5701c1f9d131234a1d8083deb01639189056759bdbd3d99243c8ab707eb1045a79ecef56c8ed6e84f7167fa4c5863690a2c4d4e2faefbeb63d1716de88d41030598ef0e2b9efc226370ba87d108a2e8d34ca4b177a38e1f0069b4c8fa20bc83389e21ba1f7065bbf5da7bf32ef1107705e7350667bcdbe0ec779aa1b53b404358498f4fdc06c767c3d829d6573341e69e09823fbeb7f64772941293b0f5c7ea0610232371e4328d00ac7162ed0c3930edf6b6df98e6fdef3a450b7d41045ebfbb352cb4828346b24c81b87be2867a0b6bb0a4a990284a3a2412ddfc07aea4d146127efee1859620f3d81aba54e76e9ec1ed28991141e624708e78fa244664471656988be4557b198f2d61827222125f4135e31a462e96e0eb041c32504ee7a2c5f3ac727dcf038139314a5457bd1e9298a74bc0436c1dc057a252523443d50ef07f6fc786ce65b24ee0610cb7ed6df45209c5d949564335e3e04956d5469798ebff43ee7f5babb2b6b0d17d102f8f3e4100640f235daa109892057b3484092dfe85fb5533271ec0b2f871348cb3b87a5720900782a7c08cf9631f8b773f7a11f7f9393feb133e9a8f79eb00c7e0f38d6ae533f3e3514013657017d1953164c5325c3f3db7766678b05dba111dc7910c228a8b403400ca0d15b31d5a6b4695c07af55c3fe9f5d80a6ac6290af1741b948b0863f656965e333ef48f65638e7f23a75a7be4703648407cf56c18b88c8cbe6c0e6f6c4cfcb77be10debcfbd895eb4f6929676f5c8f235d3a08fff50dd968f0b9adc8d2438fb8490796419ed35077e4b34f41951d45c1fbb9fbc5bf082306094bd5cf4c5368b8becd9ee0c9808546cef65072a088edc88a6328c0b2e8ddec8f605795978cb7e8d09da1599d9c5f4ce4c732fc141709d1add814a225fb53ccbe2a294ae0f752cc5253bf31997285fca6116fc30e2805db143796e63011a7d7832efc5b74df7547ef65940e1c96e64a08803b901b1f40635939d506e1abb66a058d17632c7c4786840cf4a83b94573ad1aa0ad4bba082707f0b6f414f4ff46ecfbea5065c59d647ef102f6dc1d87a051fc6a0a21fe113446c2738d826fd770ce0c0ab9116e7da907a89884358b9b2e0ab76ee455a719bd2b2268e44e041acf23080371dd8fc066196dd05628db71f7f3acaa6c4ffec0cbb81b99dcf2dfc7bc91eee0302b20cc35c2bfb549f42d056f65f591b7f64936460c1261ad414c14f15b795f906afd0575a1763f26bb4da5738ac5ca0ccd04116ab7643ab4eb6fb3df3c6a519af41e4febe6008c3508b357d4e917f76838d52b744e24137d3a07a4b3340d4aab33769bc84c57318c62c4dcc363ba3f0e0108afd7e23fdedb713a6e9130be07d3b202e1fdf8620990d7f6eb80fa30a3d64be511e32c50c835bca0a84728913ff84fa35555f7c4be035cc4e600d555ee65153d06f6847bb09fa9340715270244e3051c12cad84870b51b937a66e2f5d31394613872240759f5884a6d1292a97b565089962d0374d6df49a9f0edb13eb5a9610677558665927f4dde8f58989e4a411149cf3005c986415c8f85def019881c92ada8c12c9ed8400fc054aadbf7b21680ff941e9c490f272cdbb63f157256ca3f0b51715f668b54a47015e218495691500a5ee397a62a9879e637cedb7c33954f3b55511fe01835315970eb94673349df8a906d6c7ef5e4df4ca933e41eeff6b2ab7cee574f5f01875e73d8be215c0f33387f37f9746c9b87bedcbab17c523d2504438444489a2032abcbb7925a31c0d8606282fd9d82e201c4db76e08d1e58193691642f83716c4db0865b1da9ada2898ce71251abc6b776a218170ae122c4111238bb0fd899de8904b68369360c0b542f1b1da5863bfe66b83589418725a526dca268f9bfa91b916730fdfbe5ccd3354861e3904b92aeb82315fb95b0439e25ecb9a2d7d07d72d6b0be398316136ed056aa0e024bb1dc5b94a25d7e83c79c2191c52eec2862d59562d464762cb659281a9c2bec6f281966ca166070bd80ebbfb51f9556140efba22ee686ec8c71d7356649d95d61575810900cf61fc6dd4691881e572183173710b423cb4565da800abe3131e4f510df14b0619b6f805ae5e24c99b5e140a77a6c144334cf689d7714e4c41cf8fc6ea7521ccb4258e2fc88865ec64b149e483efd0ed92308964a38326a86021b08a6d42c181204ced0077c2ce9a264b51b744121d875d9ac6d35846a970ac3184b54a8ce02528921166ffa5595999a87416f54e0d886dff1f7e619efc70a27947a8b4c090ce6b2a4e944e39ab6a8e21b45595dda350bace195804e3ac8f554c12ed8e2b6041b2f38da400555bbc8a495d5dc41edc5399de47ef9f7addc22bc1352d4c2ccaf77cede6316c0a669bb8bb3aed39f2110f6ddb82b44f1eaf39508f609f63a1c8225714b35c707c5255aebbe19ef9440292f956c72988d629fb06dbb2533746c61dd91c10f07a1d5659ccab9ecb5ae0bae4d0002be8321e39550464518b7d0501d7e85d4dbbdb057a226f4ac2dd08a5f7110c094aa83504914e8c99c1538b4ed2670a99f458b434e72e11e1be7be731c924cd9d0cf1bcf3656fe0e2cfff5173eb1a50b221938062e945fe730786d87da04e45305e3dc405620087c02e5e7bbe10264d146ec8d33d9b6f9d8ef68713a33c588f7763c87611e095689f18bec3e9caa895cb838ad98b337b7ceda4085cddd31776dc95c0528d168cd7b709f23006a93e3a8acf37c564df094f58e055d371a82b548c46167a02fe45fc93d9599d31059eba1fe749a1f2a22f61294bc8b932b95753e59ae7bd9f7e211242c1afef06a3913d700e6f7870982327ddd61d35399ccf58afbced065153242b43c3fcd5703d1eb5a8252c99b00260a6e62f57013ab02eb8526c88efd0fede773b862f0c59877ef64604e404cc42d8322a9e906b0f5a682d393e3fd98c5ebca3bc74b3e357cc1bf977e0ceb1e5c2ab47488127b00df2b2905005152b8b588d2c12b69fbda0e3f989f4feca920cbd676800a9030e6ee667e6dc7082e15b265fe3fe609875ac0bc538a6d7521ca840eaddede81ebb0bcc356f7d970269a4756e5b1d89019c1b1c74a16999a7c77f0919ecf13a965e99458d8385ec013d2bb983e3c6a8fb8b5439a20916e7a20c762d53ddf099cfb5f4904240e7c4b06ce34f960b4ae784138b52a971c7861a0f0c1a1d4e93f94ae8839454d28b2060a54cfc8530100e3e9fe9f20554cd7ae8c97d18a91fb6613dca34180da3ef6eedde174e4ae7920962f2f5e388bac8abfb7f402a509570fb9f405b165c288a7ca3c4d0b2c0e45012fb7684082c45e83b2bd232278e5240b6078f54120002284371385a764648da71c0d8f1edeef5504afb6ca3d0df3b9ab11082a2dec94ae10fed066ec468739a4a14c350c4bc7f312841e2afc2ce9f0f3dbea93d5ed669b3d11a0e1720031f77200eb44a0f545d070a3f860591382b25b656863360e6071a2a6c1f201daa0a0057d477845c35abf2a347c9406f0e564ca85c1aa764293c20b33364ff1a161facf12541526aa755774b68543a4b27a742d4e9fc6ef10edca2e758edd6aeccefeeef7bab27af527cd9197f1e0f032e2420f6fb4b03fdacbed0b5d0600d6a724d514c9c84a69aebd2b55df40b866939cfaeec49138420ec5980580aa4689f11b478638e36fe1eb39c06d021fbd116f4cecb7068f2e9746366ed30ff24ec23c544aa9d5dc015de1f0416a8c39b728af707705341c9a734b876d4ccf2114322eaa78c9be14af093f6242bf96559caf431d3c0bf6e2b81d27cfe5c7faba66c142070ed26014b6b710b60076b7df290f1563dbb6750652416355e356bc2812a6b0ee2aebda7b806e456c7eeb9c105282f322ea143f6a716f9e8b88ea334afcaf6b441a1c77208d3da99d847650773f92ea4769bb350932fb71c806439b69747e12faf51eabc68df348474231c074dd14890f1695ce7f6e94c4cae24c7b7e7bb7bf608eae8bd9f2ed5d3eb5c1efacd14927182b1a2f7e5893258fdd6552709ec7915b4c4c715a9972198b62b0c45aa7b3cab599c10dc7c7fa28139e5062c24c35dc5a77c4a3a0cc130501451efe5cb27f781ac2f502916ed291f0c5a95e521034b6477d8ce87430077325839dd934f8737584bf57ec9cdf5700400153502fc02c7f5c10d9e670ee1f1e23ca05799118d222d6d4f7c32ba4339ad3248414f08060154ccc7fee1b2852b785d65b1d62741f04a69836d9c54a4cb864a63d40cf8a70c6a49051e102d4784e210061fa21c12aae0832b854caecf4c2a793c71ca924e6ef604639da79ff7273b0d44fba0510e6b6b2cb96af853741746cf78f0ac003d685002da5961e010bf3d116a440e8290374528a0ec002fd88e34608729cd2fac2ccaa294cd17abb489b6a7002813fea329082f1a611cdeaa7eecf0058a4ecd394611151ef31d32e91bffbb6f137ee8080eefc3d941e5ed5c2dce65c45d053ab5012e1541cef44dde5dabfaabc2e62cfc684ea76c7288a5c775d85e165736d2178174d411a880c95f0572eceeaa97928f8a6672b14cdf5ce7e968ef6f76f2d9821287b2102fb73de73a686ed47d05929303cffc84f3f510b483376efd99c87a10cb6321191b12ddb2599d537193a3a1e9134d099913379d60b118d027fe6fd11077de8d9234ec7f556d4667d642c467d4fe4b7ec30999cf09dd966628cf2ff8995655d260db8a9c5bb4e606b40f4c7481ac4c116552eb3be48dbf8f0bedc6b820a103f4e4189dc669b9dd8a99ea82f54122dfd14735d70094a33a1f8dd813129a5932937e8f5bf286f90e50e7d0b1e24fc164421e2d2bd673f47117a019d79165c486c0105c6731d41bef6c1d212ec937060379b0ae8ff08c2aa269c58c923c36ab9b5a07dfb0df64ca2ad908bef26f2d41f33c4935137e7272923a819d33388587d95ed92d02e6855b819ce0bddac5a484bfe9f8e09d06437aa929655458083eae31992772e046dfb5d7e5ac0e01c42a304ef15a63a928c60cb3721202aa20ec74175c2cb3f4a037da31a1627b069bbaae59fdb41a63f42aca202598af07606279114f851bbaed19776752cd4769855b08c7d945c3274d9593c50811b461108c6684eada87b2a055fb34424db1b259b387b95a88ed41ce1f7c02615a2e2f602bb45f107bc26ffd2cfb034d00baf76269aef1cdbb87596512b07fd01aae62af958322924c8e9bc9f7244f93b17cfc00e3562ed6895eefeaaad61da13bc7dc628b9bb506962f60b3edb105a7f2a66b4f5fb7d09f0909e0fcd754f8d36215d5eb3fc574e339bf0a06e25fb4f2c09933ee178656655ddf653da8df164b5132f7f5fe2eace746934d392676dd19bbe679cf0d3a548989b302b42a03253a8a488955c9fa392be1bc763e4116c301636a4abe2a5c256e039495cdd159f28ee991da4b2452dda411c5dc32b0f465ae22b834f2be037c56a59cff20f7c8d54a218b1a859281acc1d5248a95c62330f31c26dfe6014b3bee45066844e48353b708200731aa1650488884aa693ef2b801bf86a82537663ed25072469a78cede37d05b5654bb91e5f3e30fabc9aab35a21d89faa788fd012c9716abb856be42c870c5d71b03b76ff206ad5176bac882fb9dc6aaae6f626d5dad23fc2e7719f2e902d36a0a60f977452d985849eed5809a04ff2e96506e8a8416d031e76deae5e088874916662844b6717f251818f7f224e49c6a11e45a350548ee24dc1c45bb0317043bfd63158d0aad300462a7c22cc6f103796c97531e5b3eaed67eb82ae977e4a79cd00db86122c4ca1c15af98905f2ce16e499ef06acf198dfecec6ee3c1c5ba7e08c85ce6821916f715a47e5c338d9b775091be26bc6d93e3eb1bb2c45503995e98c3566387d311efd63932c99d519f1418267eec0698765432a04f57a236e781fed1d3750d4b17a238d6f89349d69bc5cb38dffbc39aaf9474633c4e151b7ad2d1a453318945058614c4de8355e6e88d217312d73c1280c321d5223f299d8aa2bf43811bfa273aa780a8b5704da667f761eb3f49710321d58b48a5eb4de9b0cbec7dfea1d72be386898a79563445a63d97e8bc286c0a26bdfb831a71c36806a30dff25f77eb6aef16c6b2e412c8d3469376a3744fccdfaafeba0aec16deddfed29ae4db4e5cb3b028a0312c7c9c0606a97847b477fcfa46fc3e2847a584e498ef1250b44ea1246f911ce76e406a93b434616174794116e894e947e58d18053c026a5a5a67a1348651f597da61841a209153aa5aa8116a8d10d6be6753a068e8b1b87d508a1516ddccc482e4373a83b39202136bdeae1f0b1c09506b425fc4067911f34569a5b25c769b7446beac9691e3c15338f5ce39d6bd40719a37a371af9aaadc8a188c92a0b6b73ea205997b31ee50958640729e878168cca250224432ba1821cc7a3c69bee61cb2200521c3dabd79cb34804955e08909d8a6d09c562bd265ae0b2a03db28a17a9115309c7dacab557e48726b6509fe70b488355e45b7a3c2cf2825fefab0fb00ba0d9bc956836282c404d1ba5c56f29ac8fc562e4a746b2611d457761d11ac72164b6407ff1ab4531cc2b3255e7a9bcd1dac27edd173d219ce5a817537bc37cb8456fcc83a52cf7526551367d2e6121aa274d141fe00977541a10825838c3ac9aa8324b4a5b506c5fcd2d142c1f2c62e36610a4b123466552dbadf45606c430a0052dee6edb93691d1df8d442677069ff56da1b4c6562b775f373593f08d9603925b2e0740522963ba4d8d4118a4aeea0de1b841d996b6e9edfb12c128ce7252989b6e590fa23c429b873febab00484e78e46c9b58d92c4a526525ad5963aecdd8b2df1b6a6be4962e7f983dceedd5e0ba56a52e690700d7cbf83f7e37b382e30108ee45ff943bda54386b1fcd9b81f1660c84bd1c245bfee112be6d64ad627a7c48f953386742fc5c91a7d05425f801c854fbd12465dbd5d7e6a30a38211d0850c30cb999a9f31315538a04babc0b005d38d1c8412427671d30458cf382d1071e030fae549851a273b89e62487b8f77522c8ec2f40cf9ba8ec0ce0bc51aa2228d4c98a65aad4e1a85e0f0e4b78a8b1f35d77ae1384ba9020f27f56043cc7eff35f219e1c76e157916a964afbf57c5134ac36408c2143290e2eb322d5f8eec3f174bf6945b405b599e370d223c9d72bc6a210b1573adc43c71d8b0723cf9b66c649141f21ae69839fb26c9a2549b58cf8b3d2e0ba9bc14f369f28a46f11fd7334f3dbeba38e9959444636231f53392498f52da4a7bd1733004437f7ac1fdd10cdd7e62790beaae8357d2f05aa4acc9a927618c73b736d2d5f3c53dd9d81e10b796a095fa30ef410152892b7e8acd94696e5d64db177246b2c7986a6c1ba15765cf07bce620c5f8a71ec9e70cd8b1d71e7a6da688252d2fb73c15a251657951097ab96c7248ae2980c0d2cb6d2b71e3917ddaad5d848362e3d1a3ab7911961ba34459121f6056915c3f49d3c5c5e61d81cb248d456255daba15b96312958d931df24331d28ab73649a43f61664f426c04b736d153d52f9e62bc1a3052cbe3a55b42bb400254f42ccc568fddfeb9d1f5fc2037691199374e25a17d5834e515c6b6ee6c2d837961ed1d8a2650aed62c21c1b1d644b608bb91258710138b4f778f06097a9e14b62451ac34b5a2ed844065ea2450571cad395b0ee8e4e3e63fb7805391b7386ae932932f1145b933f09c911dba929aebb9392a01e67ad5ba5cee0365c86ac0d813a365a5d395f9b373128254d0e5f62e33df5a6d376da5fb0c15caeacde812d88001b6b76b0b19a085ef8c611348117228397fd9fc85d11999e493567ada83172e31e9be76c07319126995470162757f088873ca77cd8f6823063e152a879a0dc640845e2fba87e2bdf307b71548357b11810ed4ebafeb2377562da5d4a907212fc015d84ec91914ddfbb0471fb540fe7eb3fb0c5b4fb141c6d36792528c02b1e4690fd2dcfb9083c629cd2e5d8e8a105b3fb0d3d201223cbc28c27220de2843429b235c70ca40c7b4d4cba3bc8cf248aaca4eb6c2339496e4eaa1ecf65b5e01e7e1a3b530ff7a90902d704569c7d15fdf05d1aaf0ad65ca7e37e0c5a8423e7038fc7a8cde803a78ae014cd0b50679f121160ecb204406f1ea8803864e163c98c2367359e2a28e706d1da41189111528e8e6d0b82c1e0f8d0440228f6205db3eaada553e680e9920a1f8ae002559fc3045299421b99a02b4d5e1310917201c0a228bb5d05028f55b22bdd79ef2e3372fc203da4675fd192e39310f6f7db4f28982e134fe748faead1ab4653248a580c01902e105fa7e4a2c64549884b479680e12bab4979d9998da9bda62b96cfdd8adc9fb718674c8b619c4fd40241046dd9fa030026185c0fdc06a6a96ccd437c5dba8392c62d5578d16a4029f28a37a1e146d3e5cd16845b325ec4e8cfa000337d6106908b5c820eb6252b6c63264c9f715612810220e53314bc604252d7c2e7c7bca2b3eb84fa06974cdf52c1f4637d6b51572e707646fa5446fa8cb1acabc1a110b5ddada989cc2c9647801d3b7e7e87fc65030dbe58d03900ea28e0a61d549bf2b56030ea2a3e027a6beb59506747b418a06eb483953ce802e33cb27af890d147e7e9974362ea6e7b2c302806e4fdf01f8065bee41f2eadaa5e79d92767f92095b2fddcbcad3dd91a9e96dabd0a622869a8f26acce6c211a069e4cdcf8a66ad2b3adeaa94e21bd8243afebe76ee0fca19dc05986e21aae8785c54c6be3fe74a47b50e4bc9dd43f80dc471d08025b218bd441991dc9c9febfe69a027a3c8aa2cd8b6aca7641c065d5ecfa1e180ea341e13a37e02e25c901d9bf9b4b77689d1d900a4e9e1992e6f2c65f590dfcc916555cc20c8b073f4492d60d6a52d6dcfdc71cc4fdf903980976a0553ef851c7291d7e758119e4d280deea6268deab1c91b229bfc1acd1665beeabc62d6c3f0fce59de1a978412d0209c67ea8a90013631f497383f02f4daf0aefd093a47ad41c3d14488ecc50eb5315f77cdf109f45367ecb68c9eada858e1b73c5dc14bffacc21e837226f921f56d7a434e69543a0ea334e4c410d9b0dedeee777508d1b75db98b309285498d06f941e8b8a14e5fc4076e99d7bab364a74493114f9243523ff54fdc80bc718fe723e4a9b4b738cc065b6d0c8b94d16a5a74592375c7be2c4eadee99b57a33a3850bac83f0b48010036b1cda5eb8e051a1e34ecb76de5b4f0c0d451e50b0aa6eb9e61ca3b0b407b63c0f7e6d81f7a2b3990ad792fdd59ce9914e6b7308163b8f666ff6686edb67c817bd680661bae96b69dcea14cf099e75a8889e7217e5bcc81b1aa0b483e7d6c3f23cd0b1138eab81dc76b7a57b3934645289ed28f42c92ce4b5b7be0685315335bd1d5ea06d02c006dcb2c401fa95ea3ec92231a12a2dd11402d4ea81c127bb8a3cf204d4790fdb96f7976af08133fc5b5f2eb0a99f5b4a8bf6eeb714a269fe8eae203c0cf3f8e59aad36cd1a984e16bdf0a20cb95b146322ada5e5a5f6641e3e40c5085fc1aa32e09a2be9b0972d32152aa8c9b8c43a59188277a3790895ab013c3295419ab9ce697a127a1e0d86ddf6ba6be2a2e11c3e745d5937a25b27cb8b5e3916cf45d14794808892940256a01d12b418fdeaf2ceaa28f25d35ac8ec4f6736f47af1aa4284802932832d49322a231395586926d061162754130dae049cda9764688ba352403763a392e61f7e525eb65a3bc3166a1c03ff27f7521a2644233b1403813fdaea0cbaf1d287a8a45736578a7f0add88051cf9e748dc9a11b84673f7a26cce39c49d4723b42847e39d1405d158019546c6f96b62228ac699e4e6302ecd470442566da3b8d057f78eba808010253bc9f571089a15d5412c4f3f60560db1e7372c75a6be34a5b5275a6f34fdc25177ce8e59ef557f6860498dd14b339240a009a6ea2443da18a1d368c4013b63efd8aaacccae3fb9456dd1ad2a34bfbe5e523194fcdba2e365c88d7440a263480785b7910665055de12449ab63415a697132a5ef44e52b430c8d587b505e39b2280ae065784cf54e00996c985ab2a8f437f2b1a23c86fd3b87cdf4eefae29d7d54b56c2278b0d9f92301cf5ae0672459030a29c676207ce34fdf5c76010446e440cff3603add7aee719d8223dc3a28051992e784ff8e456641b180405b199720178cc86862dab73fed4d2b7d1ca893dbf0014884638c9f82ef923d662c582289212bac1ee0ed1cc0630678ecfa9ddd29b7ec1c009b9b6cdff7a6752147d582c5e21b901a4d00ac0168e93895b0dcfc40ce6b9f1f62e7931edfe3514884e53b113514bd9db14cc7059741ccf41544a9e8fed9ec01c4896256499fa4322cdab86c6354a87d8de7ee0df1547bd1e04306cb6b614adf2f5c91983225faa22cb98ae325e02bff326edec7762c44d27cf0c50e04f96697315478c99bbc873935f3ddefd19a5fd3257eb6fe33303431c766661da568f712ac2367626c4e341deaebb07b72e6edb768e78fe63c7d1f5dc0e6c4585d4bd1726ef9917052e1db8835333ea7e30aa40654a0034ab1668f5510382a6b3a181f0a557c5178b3f05eb09ea1e9abcc5ae50331c8eee76d803eaa79a87c6e3dcc1b09464aaa1881a2a758f6d8bd2ac8d26307a054925acf17ccc2e2c8effb26542183db480b35b2bb6db9a594524a194809f80895084b149172c5116038bd8962eaa8da8b7948c88e91e8fb17d512c0aa91963458649519430a2e2a9c28251a47153c9cb18a32b3e40afdf1a1239d21b0406fd90686447f483e8f1c5171b62c298249135457565c72bcb800bfc9ed9005182656539cf1622683b1d69bf2418b2f4d14ac2d1a8c00e309244588c9c2093168904883250b979f7c25871812043144132aa0d8c20b29ae18a2cc185a3d9ce04d97c49626865c56f8da9aa3880748f3b10293c4c35e5a814913456ea1c59b3324d04a0395e3747941fe033041822b6e78b2d27202a4aeebbacea7ebc4fd82955a3f48b016eb2b16bdb60386deb55a14424670a5ca134cdcd0a9e2892e5fec0e3667b4ac96a2682286144828791246115ea2c2e4383d88007b5a6bbca0000e124418714254d799f902cb1a2d4c4220610569ebefbaaeabfaae07aaef3a2c5172f822491d2a5e7081d4755dd71d751d767b71d7755d57ab7716db1d26f4d62448a3fbe6a396c8122974bc70ea414e1a6badb54ebcede1cb5b3bc40d5223e8228b0f4b748164adb5965a5b9d5a183c40137de8a8466fdad7329f34411775f9f948ae4091c59c20d654b909d35501d5e4f3a1c5e488247298f4c0c57e10455d90689727d220b7b444031048d46ba8021c68450a165fd03c8571c605821db4c0af2e4450664b962b5744d99fd1713b48d1d6d270e3041c2d7ee081092e9ad022f502228302345773d8bc400934a0c7c107b40033c6043f5461e5824302dad7253db091420a2e709c6c017a4d1e512ccf4f6ebe56cfd9133beb799ecc343a526dc54af30123a760b344d6087cc86da982092c50641b303141141da8b8a28242d621114c91e20d166b5ea003120a9448d21fd2b5c4571da6e8f9aa84872fba9441a28927902a28299db2a209cca9624d89bdb162c94b42e6d526891a10ccbdf7d2ca0a1a25dfbdf7dee9f53abef75eeb58b477d22c9dac2e8f664ab3e744efbcb4b2d2e5c32204e641eb975656a8c49c588152022b361051e7871540a1bf9756554a0045046da6803969efa55595aa324b8047e8eea5551536ef895586b881ca6c3314515d347e6955858c54152f5de7c25d98ac69d4c9a2a9476b469d3852643cd154abc3840d3c554e3d75d448a1c1919251478c949d38583c757c609a5935d1ea509181a06aa78e13279a89393d98a033d32e8812736249460707581353ba8a571359b12450c038503031ac983e385a2f31a89eb8e0308162a0c121977160a2e4ac33a8ad72f526c58072322546952754622cc1a14795560b5090430f1034b5000b871e71722d78424a0f27a45ab0464a8f27b05a4004530fab2b0db8c82f2a108bd41a9815edbd8c23954608a9a86f0cfdbd8c23a5e5c5464a073a5249ba255890a7d0f9651c325e6491094113649ec8556492e854a06b2fe39021e38ad2335ec62163c5894c0d2e2c6356000343db9771c6a4c0cd183a3a8cd982d65ec639d3250a213e298d340e77c5203ac66063a53197975db9c3b9c22abe165758157f5ee087c31515dd36784a3576b70d7e9442d3d35ac7cf194a7ca7963119ec83e2b5994bd2f1a7cd2e3d9b63ad302bfed0f187dea6679ab39d15043318abd160e1f8e34303ad9d551ad197591ac9e7f95923fc622011483b190625fda13e1da5659b67be65db591a787d7bae39a5900d336edbf6e83371d09c417af3c9dd688b7eeab7fdac49a139933b349eb6edc71634ed8fcd83976e7efeebc019fa7f199ca1ccbda5fd075e5b29a5139452069bb9203d63b2938e81c3a47c0d4969c11b56e89973ad663f9c5dddbd7accb55aced6abb53a06d90bafed5cf8bbe0acb5d60aa352c66caddacb396b3b64a50c86a98b99b4da8bbbacbddcb9276e5c163b1cd2bfddcd1e16a5107dc1305f00527a7af6629e0bd6e15bf4f4edacdd3825ad302b8ed7f5fa64794a50f6fa74cd2bae168de314b5c3fe82b9469ccc565cae65a53cd2d16a9d73ceb2a29ccc93372900394a0f25d1e857a9128de3388e323c9bdd9d9126e3a9550061f494d1337b6435e9b263bde1463ada910ec94f061bc7516b86103f8fff9b735e1a98ed7f77f6d3914829bb2e7baecff581a07e51ff5ef943180c267bf9527e9df3476b2feb9cc5d5e50ea42fdd95672f2d0d0f8c3742df7381dbf6833f4b033328634a29b5965266716a504a29a594960e4d4f3663ee80349f1fe9d6693c32c0a12873dbe8cb7ec68c69ab75673614c5a6af40a3a76f3a020ab40d43cfa330b4fc9fd99455a173cef5deaabbe498adf5b5a594524a49e4aad5e54d239797a5bc19acb5d65a73ce99e6f303821d885f77088aad37aca03c4f48b92d8f9c21285feb8ea66161eb143d3df4ae5b7ceda56f45596b75e35d6bb57855f421de4b04f76c873d7b73ced6f372b0989dc1d6cac5b3d7b3f88a3896acc7a5d6eaa6d65a6bf5210e4ab7b3da19622f11acb53998132775c8c90cfbd5ce5a859b5aab1bcfe60e5fcf3a61bddce1eb64c7c61233f7e3c91958210fd378edc55df65c2f03d8c76ec10acbe2fc66e04bf692c78a15772d871ebe93f63d91d1f33c99f372b0d895e1e29876d707829f8b08387b255d9fd59dcf3abe4eaef90118434f3fa2afa3dc8e2b681c69561281ee792f25d137e325c6575e6920c77b4b21bc0b881dd510f6c9e8e97a6a7806c8c5e8616d86961d490238492d9eca2a9e527aa392deb49c88607b69485bd5b556fd480a51a1672f1bf579255df7a901e6089a4ed5c7678440474ac2cf91caa213d41360e7a8c64e0d33d9bacdb599dd666bc70b552626063804d8243b01ec0918e5020b8f0d2f22321370ba95bab266a87ecaf0e956ceb65658ac9f6eb3e890b4aa72e52d9dbbf4d32f131daaf9f40be552b94e53ea9b9c2a55ad5a629aca696dfdd4e267ccf0da2b6946cd7b5e49b524be870a0edfe3325e493d5986f3bc9264f0e4b026db1ddaeff8fcceefecb8cefd8ed7546035858acf5cf64a9a5d59e14026d684c5c71cf64a8add1e962cf82fdabfdcbea43cf1afa62fffaa53339ad3ea862d2e6f0acffb79cf83b2c57b518e78ef031e002b2836e8582380a7a5b7707c847eff183519c1572b27427c7d520310a385fa1953469aac7dbaae5551e1492896c8f9820b1910880007dcdb2f52709a60c945110107c9fa9859f03609396b7c70c5decc38a2bc2268870d4b303d3d653ae2a98f4db2d820e5a96b5c17e9e6ad5bebb10f5600324123a786276f1da661e0428bab245500e1c49c2f6f827822b5c49c2f3d4897125abedaa44921367ad368d2a8fe84e2f69be6a34489253c3cb55a02c653265a9efacbad130d3cd65a6ba71224ba78ea9f06c1062985d16f9f24015d7c4f1f7ccf2dbe2717df7307df9307df338beff9e47b3af99e577ccf2abea715df738aef9983ef29c5f76cf23da1f89e517ccf26bea713dfb306dfd306df5389efb9c4f75cf23d93f83ee2db03be3be05b06df1bf01d836f23be33e01b06df457c5bc0f7057cbbe0fb05df2df8a680ef08f896806f167c3fc0f70abe87f856c137037c2bc0b710df407ca7e01b01be51f0ade4fb04df25f836c177017c8fe0db87ef1fbe43f09de4fb7d23f9fec03708be77f8e6e1bbc8b70edf1ef81ef2cd81ef0e7ce3f08df31de45bc8f7cdf706be6ff806f29d81ef1fdfee3bf45dc3b70ddf347cdb7cf7f8aef9a6f9e6f12df33df30df31df3fdf9063ddf558d1a354788bbcb32c20823b08c5093264d9a22c4dd5d114104115544a43973e6cc94b83b2a3468d0e4d09c2953a6cc10e2eea6cc98312365a68c94949410e2eea282082208a820a4c488114346dc9dd39831639ac6880103060c10e2ee98c28409d32d8501e3c58b972fe2c65b5151515a515eba74e9f283b871960f3ef880e543972d5bb6f4206e7cc5850b972a2e5b76d861072871632a1e78e021c7c30e59b264d1226e3cf5f4f424f594c5c9c9098bb871d4952b57a0ae3855a95245077163272b56ac3459a93265ca142ae2c64c39e490035eca618a1429527010f7dd6a6a6ad26a9202050a941bc47db3a244898215054a93264d9e88fb5e3971e2a4ca49931a6aa88149dc97ca061b6cc8d9508312254a9888fb4e2d59b2446a49387f2a595a5a9a3488fb467d929904aade9284f3e7d29123479088fb3a79c0031e68f24038ff48073ad08119c47d9964904186bb244338bf031bd8c00638206ebb15430c3168c510cedf8011234634206e9b95810c64002b03e17c2330c0000306c46daf8a14295255249c0f83052c600122e2b65417b8c005721708e75bc005175ca880b8edd40b2fbc20f54238df85165a68618bdb465180021480a24038bf85084420021310b77592800424d02481707e04586081050888db323de0010fb04b0f08e7b3b0c20a2b3840dc756bc890215a43c2f92ba8a0820a0d1077cd6200031880c58070be0a0a5080021620ee7a254488902a21e17c050001022488b82b550a29a4904b219c0f040108404002c45da7504001052914c2f9085052523a80b86bd409279c007542385fa984124a3080b8ab93092698d0644238bf840214a0002488bb328d30c208756984707e017cf8f02182b8e9d68f1f3fb47e84f37d841042083dc44db3929292b092c2f921fc3f01c44daf909090aa90c2f9ffc1071f1c899b52810002083910c2f91fecd8b16300e2a6533c78f090e211cedf51545464246e1aa543870e281de1fc220f3cf08048dcd4696868a869289cef01071c709043dc94a9830e3aa04b1d84f339c081038700c43db770389c162e9c8f2328282800e29e594242425842e1fca0dbed060071cfab0d36d8a06a8370feedc68d1ba3b827151010500e289c7f23830c32d040dc73eae7e747ea279c9f81bb8be29e5161184285e17caf51a30606e29e4e366cd868b211ceaf4183060d1f714fa6b7d9e6922d9c4fa3a7a7476ed56a3522b5707e0f8d4693593c3c3c4378c2f934994cb6236e79359bcd9466e17c190c06d3e29654b158ec2816ce877ddf57048220eebf9cf3e879de77efedc45d7b8c75bdd53aed44028989849e4650169abae9b9fad78119031b5fe37ddef61f06bd90c67f1de88533fecba017d6fef3402fecf9cf057aa18cff3ed00b79fe03412fa4fdf702bd70f61f0cf442d97f31d00bf57f1af4c2d87f32d00b61ffcd402f7cfdb7037a21f81f0df4c2ef3f1ed00b5dffc900bdd0fbaf07f4c2fc5f0df4c2eebf19a017e2ff68805e78ffb3815e68fff3f96a803640cfc6751a1661f0b12382bfad4e7ffe11d552c626ae371d9c338bf7e27b49088265731b1fb0ceb795d375dd67adbd17d3e0d99975375490878cdee0c7c117bdc15934467b9ee7eda29f5eb560fcf4bcfa063d77a18a34dd753a9669201d69b57679de16a4cdc817b9ff426dfa3a25587a23f4f77c9b08dbfef8164915b7ec37f6ddb927628c67d775b5566b6b598be73475a9fdba992b3a4a6944a71c9a7e6f756bab748600a423b5d66a2a5cd1bd15c4786b8c7157290d67adcd5ec6227843daa5d191d21c7e572c7281dee0531ac5d83ebe97862da87b746fc516a4d07439822fa2e38de077af094b2bb7dda9426ffbb512816ec57ddd82d68262bdf75ed10bb7dc026beeb7fd9a7b18863c96b9dcbb9457b4f6bbaeeb5defc25aad75246fc53dff059c4d3ef1120a4dbfa9754ccad1da5ae7948abbfabdf6564a77add66aabb5d6fa2d22a59091ee7dc89f5248d2292b109f9462a561c049e9f5fab48a94d229379c000cf0d46717526f46b8c2d3296f76fb872b3cf5299bb30bad5f40565d461ae81ecf2cf0d4a7bc5937eabebad423e0af220c728cc7a2a43e63b5522f9ffcd91a04c12b7edf5323696715ab346ac256b72005e9ac13ac7604fbb7bab86dd51e511f6435a4e0ca9232349cc11a1246962b9e4c21868b36d26b52bafcf9d14c69b60206aa82b1e2c466b9c2609c40a94f55b7ce0d54669bb534592fa24c5c112e47d10e4ef526b39cf3c487962a99bbce8595dc286ef08145ab8926515f72517c6469ca4c90488197447b5d7839edc2e285258e8b0d9a24b2a021820c1aa9192fe3a801e2de6bef9dae17b6631e4717f55e9dd7aac4d85e7bedb5b7e27aeb95f75e91f2c831831e07f4d269f6aa81e71957ef8270393428b20f64ddcb2f6ba717ce9f39089783b6b961695dc535bbd76a7731f670add973162f76f9581bab4b16794ddb49ab1587f5effce6c5f682da6b2e29efb5e28f149a5e63c977bf0ad26a5f3d24c57336f149b78980a5189342f8e52b694a23118ad83772bfe2466bedac15ac5562cce6fbc47a71975db45edc65efa3d4661e0fe71a5f0e569b3dd7071341afb04aa7042f155d6e3e233c2fb5d65a6ba5f59f597dcbf03f5248fad5820b1737d966dbe1cbc5e60e5f2e5cb874467c531a7dd665af777fa4517e1914847fa411d8753e7a9c3868fd20fa933b79edad5dc63ff7b30e0a0a0af2c01f69044ee5e0c2ea8b14ce8797d2691c21ee57ff41c2bc7db1e1338d6614470c1334303149e205d2d61b18c20468d63ce1a1082aa48a42901f754b9c104c755fa7fc8c46e8891405050720cd0a93808b215c80431424f0a18c0b8aa8978a8ed5f35aa9f016492491eaddba76efbd172bd32cbcb126a358948ae6b06bf0404a685bab7cec5bdaa1aae3a8eab8a93a7622529dbe52d54a2b1a29541ddb30be54944848ea565971b3e8101875df3a5fb1bed2b95a770b5f9aa343bba299aa5ed5fcf01bbcf75e34d2887e757a0089849beaade20b878ef55661f152cda1faea9f57ffe8775fbe92e6122954bd36216d8591208d988adcdff9711315a6228570131d2bcda25874acd58dc0d0d437c5f29ac01b3edaddee9640839e7fa38ebdeb9d03c1475c9fc5a260d0250a85d2794ae912caf4b4894e26a46f004f7ace79c473ecf2dcf975219e63f7c416ea2debc8b55ea323f5a123b5b22d2cad3997694ecdaa58136bfa9c998545c7297ab941b06afa8aa3925328b4d2fc26f7557eb5e789a6de03456f8cb5beba0def141d97e4ce15e774e0a037ae4e5135d2c87abd4ae4adfa939d73f8ea5ecd52ebe1ab7735cc57c757ebeb158b5c1b56353a9a76dec8f4f953b4550d1d6bcdd5293ad6dae57a9ee8e9d27ba0e8eaee4453518810da3a5de2f1c99f5d697d29743bc8d2aedfb6560cba8ea411087ffd873452bab7864e47fab9cb67f67bc2bd9ef1adb6fa79ae2ecf2212244bedeb8dae62167fd4db3d9242d78196d036113aafde5dd1565dcab694ae07b97e74fdc7f5da42adb9aec37aea1f5da243d5afcba2a74c4d352787a25195c6efeb84df0ee049d727dd53f7d475e9a43a351d1594aeaa7beacc74b9ae4d07a793539f406982529fd05792d2eda0c8e8ae4bf7344757dfddd353372385a85fdbbdd7891209495d2820a6e8501bba2f9ca771c49c2037a609bd6a9ed25b67173a44bd3e51af50d415c553add48c34f241ed14c3e986f7490a512737d6080cfd39f5a4b8fd3f98449f788b7cdff85de4f228bc1a08f2757ad389b2de9c6e4ca21d80dff5e9af53bdc9a0383df51d62f4c4b2f4ebf2c99f9db11efb378027bd733c86cdfb84bc611d53f4be559452396ddd55a75b75b16ed5bd9a3baca043fed6734dbbc44cff3976395fb6136af5bcfa8049212022f4bdf2b068053bc8d2b3832c7de548a1ea57ce9528deab7ac3a077b11ebb052ac22ad55b8583de3237b367b0936d555d2cec370bfbadba57390c81e6e818751442919b45deb0f7500be3658ac097cd67a6c7be29d5e35d9dae1c29846f151d753465e90cbefa47e5913fa272643ae87b75aba634ce582e2a7aa2e89e2a9a2ed1714e4923107efacc49a34b973cd8d25b664d0fb6f4ec6229082d21ba5001e794124d322b27252788a7ec4b5c0e569707661be89d0301bd13b303c9ddc4e2a57f9dcbe53625cfb32e6a3dfb117555afeb3a3ff2cd99abb7392552eea6ea94149a9e35023254524df435e912263a5e35618046efd98483241aafcc2d5fd518a931604cf952eafc88d22d9ae464d54a6b0bd35f2012f5d34a0c9d9fb24eadb5d69752f7c29ca24b7eba66a38950b18539f5593ba7285106337735e7c8ab49676a564d2b7e66fdb4b4360551a1d65a6753250a61b609011755d1b61eefc2157dc8a75b66a99954e8383ddbaa389b9c9cf4ccedd0a25ba8449dd32c4b27edc14153efb94153efa1a2dd5dce3925d27459efd49caa5f9c798ab202141891022da4eae04b0e51af740953d18a87f7eca941e76fe639e3effafc28d875f50355718080f3988a15106a7e836f05edea908c2346ce63ab02338fa9485a5f620ec10f83f0d8f5383b962e97b20ed78082733507cfb4b6ba2aa7a61a3ae737411d3afd364263a17c25c55e3d60deb90f98778ee4b78732972f89e4656884beac869bce7922ffd997df904647ecf495f412351db1ebf842ef49854a1733b3100c3f28a7a719851d5771cbac2e2452898e70915651bd49591bb9e34a67779b742b45db0933bf0e84e65614916c9ed883be97a34372e6639f74e890646209cae3a2c718cf39b3f73a594487e4124ad43c761ef8883dc2e33bd7672ec43acdadd376c223d767a24d22515169d1e58a89324f7a40c2352c4d4c710595991c1824ec3357b14faa8abb3674c4383a62ec31367a52d1117b877d471a2d73209dd10163920897ed9520086a5a0da4e928a47212514c7d3cac80a8214cd6e7975661b09a7c74ce1cf25673e4c861ab0a28e4f8ea455b726c94d6db83faf7657a7d7a63b842eb3ee44f1f738c1132a62f71e8c3faf524f953edd6ac31274c98a79f4942aac064f1b3be845469d74bab30537e4aa32aa44acb5e5a8549f2f3be0e20bf3893c5042a5092c51a132049799b5348957ebdb40243e73bda759dec6ced26089b5dd0e7e1a477a5f2d5a96cd13a5fbdeefa4a95a9122dd12d3a5407fb91ee7af623788a2860ef9630b99e9d09f6ee478b7699a551f7d575bd8e25be75ce87dd66ddeb0dbbc535871eac40e325d53f5b6fb3fa84429a75b6d9d14453dfb38d9d5e279d4f9f072e88791086de60d6ea42743475908eb30929545f56294e3921d0a09647b050c490a915866080102a9011028402bea4f003901e508042809613b028e9600295127018e186023cf9c1e48349d2a421042448333c0740d0c00718e04164470574eca2090c41c0030774d0000e16800b82230142070832c00624dc4400ea7183003f47190c203472221b396a08c016001a00a88d3d1af088340c663eb2193119b01d507f2fcf953b4c7d83d9898e2c84bbc3fae943c2dd55fdf415c2dde57e3a03c2dd49fd7415c2dd41fd7421e1ee9a7eba02c2dd2dfdf414c28db57e3a907063ac9f8e42b871d54f47407842b8b1d44f570a3786fae926841b37fdf412c28d977efa08e1be5a3fbd00d37f84fb56fd741f61521842b82fd44f470a3f0421dc56eba77f10f2087784dbe67eba8e705ba99f5e140e85db36fd740fa677107210e2421ca15018146e10de42a07053ad9f7e23fc0937adfae919849be67e7a187a6823dcb4c916d208f7c4fae9b5b027e409f7949a857b36fd7459180b61e1965532b77138bc549aa0302dc94b757e524ae9d64f6abf03e3a7672d3ad2ba837e4f35bea711be671adf9308dff38cef89c6f72ce37b9af13da57ccf207c4f31bee718df138cef19c6f7f4e27b46f99e01d9d39e2be69a7d30a925b7aa13ef9b812f1580b6f0c0176803eb35837d575741281d7fd0d35db358d537486ca63dcfb3b3dcd58c38c0d568d0203208cee276ea3c5544115f0b3abd7a05f964b3596783389558d77e76b683b5f4f47a1564e706a1cd683cd68e384dc5339351352e888c590fadf928a9c5e1705741aeaeae7a66b53906d1b63643dac7e1705741aeae66cc66b0201e441a490cbee0bff1f7c1b7e59b774a53dc53534ab3b5ff79049042e17d0dded663fad03658c4d6638eb61326d21108beb29ea11572948a70413430c77045428ea051d75ab3ccdaaaa884efd4204d4a09661938c3fcdf8c52ba03ced0a6943f1a38799e766997862f0f6d874753b1b3fab229b9beec49292f78499042d273048d3ae3e9d3532ac25d196e1e6badb5d6867f67ef02bef7765ffdbbd805de1d1a8da7a7077de93629d2177fce78793eb6ac418dd06d4aa3b5d66a6b6dbef67a1501a450952885aade08f5a1816d7cfa3da2e3d41b19a7ebbd4ee21f10d7c2ed3aa23db61a3564f0cca5183008b15f7c795eb64b7bd9aea8944522f566b78c5da594b41b6e09d67b036fc050fb3b7632787277efb5f7de7b2d00c0209b527ed903404848070083167c4022d0d3e78f8c4925ad7657c43bd67ac9734eabbb1a03ca42c33c170844051be94054400004aac287063405d097e9d0ae2e5d566b5d36e6b2da585550deea24c543b6d67c67d3eed080b2d0538694c143dbe9f1d1c216dbcbd365d62383674a1a340a04d00868b65651ca714ec9738567ce397d885b5bab382bb6d8de10587cb94c282eb6505c6ca19061f17d228a8ba3b051c49159af57cce0dbd2e3859e128bad5d6ce1c462b118977bb9587cb93871b1bd5ceee562f1e5e204b6d85ecff33c8b2f971bb6d85e272cbe5cac9df2867d1662af17981823f93983a490133d4161507be7ececc55df65cde078bc564b31d9a9427a339aaa73e79a0663d326a3c57863b830608d221ef8501da771ea64df1caf1da7c6654ca799c785e22dc996bdfdecb643fd3210e57086be89fd268d64b6dd8b08101a87d360b2794ec048aa4b1d03d18c0feca703d84001daabee66b461c6c20bd3033a1ada4134012d12859bd46a34451bcaa0f24850ce974c8bb161f55a21d973c1098e2902b3dfd854e6cc1881589cc40c718e8481d488ee60927d38e3897ac7448b5ecea2a91c40cbea79e9708f2c70574023d7f34f0a85446921aefadbd4410c1978baf24988b37720c73892ea140875e27b8948a3a3cab665576a91f290b27168bc5602f39548d4bac7955d47ba4e048495197a174e5e587061abc92b06b90813a22728b2e2d6d00bcd4c4413bc757f34a8e9c2c475b41a3e6d0281228118da2371a2585a81f51dc49cd1df40b5de2c9f34a0e6d73a5e6e9154d96f382ab02021a315db2785ed1a86fda1941298d6ef7da2bc3579fdfedf64aba7edbc0da2bd3b9c374e96ae2a0eeb51b52290ac4d2bc9a3be81789833a5dea681871d3a7d1281a0580da7f3a9448b290cadbf55978ef4412d2325d857a6056a455300a802716e8e93b4fd24199e3047a7a093ab668510794de7ae797be330920d027d0d273185504bafa90677ed3f4734e2626789855610567099c4c04f19d13d95e0c7efbfc403105d04b397fa5156f9cfefaf5acdf60f1d76b4998f9eb3e2661f5d7715440fcf5a2244a50f1d77f5c574af2d783d02169b584d55f23d70cdd7891bb1c3cebdad47394f9839c951b323272164ac3fdf661f305511b304fbdd6668ca7cee33f90a194524a29cde678eb920d126f7de79564b3162b3651b38c6589354e6fd684e0a9cb5e4954d778a0e016577c60cd53d7fa693211ab71c9f19b96b3e1ad723a3c75d82b89860182314ab0f0410936485bd7a82c74765e9b7684186f5d23d1e6882d6f1dac794182e7dba0ca081618e1e2a204cc0b409c30d478d1b52b579e523a84524a412ad4582942cd5bc7ba87acd79d4294928a1c639a2488807aea3e12b1e6a9e38a784ac343122d3ab202c6530f81524a29a51a686aebadd502a5a7b6228a2532787aa68e159aaba93167a6783a678cd1faecf4e5f9372f55851356e1a5cf170c3ae6ad8b0279cbde5b29857067ab12f2969d64bf33973577d024b4e6a57ab5a411089ffd6e49a33a2edcf4f9cbdec34477beafd695ab4543081c2dab5e7e8f124d850e69dd2d8c9f5c2255cd59672b562a1d3a68df57cb8330a60e2cfa8a3547c75878b7eceb6ad1313b50115afed59242d981d45424a491fcec346ad6d1a26aaea05948ba851c727976fa0269343f7ba5610e5dcf5e6b98439fe72cf5d92b0f92287b75328926d418b9a2a9643eebf0d9e5249ab26b92cf4ebb904473898660ee984fd4084934a4de9656808227acec4637f17953287898d173e7b1dbe4e7acb3f4ab3acc8150b729c16c40605aacd13167980389698789360c44e631978936cf2592cc63313fa2351c1db3cbc2a27acbae71b8ec38fc41c7ecb150a9deb2c3325eca8e99b25fadec772bfb845233775c3a50506a30c60e4acfbbdfebbb97cea573efc59e979ee68e0925eed7cb7bcaddebd9a5fcb8b840ff2ae80a2f0be4fd428ed9c590136aeeb85a1347f68c993e67ace4f34d8114ca50d682a29442d7ed904a54b3d6589fddcb55a29b73ce184a0a65afc2a163ae5574ccee89958a8ed9f7d5faec3bde684b479b7395c8a37289520a59973f5974216bd18822735d1d3f2f3bef863c72494574ace20c48905ceeb92befa20a82ae44d98be858c5233388419a570472446b9114aaae4307ca245beb8512c9d62a73d24741b98a8045991bad7351bdb4839a52268924129db5d62a9b6db20dbbd79bc56211143c77d50e209160388044eadc25ce30031224dbf9d6d9e28a7e2041f24224482384a15d346747a8a371454752954ed99ae7ae0ea6689c14b25ec4fe2bc95a7779965ed1ab292491cbadddf40a056f1df7d213458c1d9c8ef1b5ee2473a3e91495a2e3124e825ecf5ada4a546b12ad511af443c71f2e9f152fdd8a8e152f775e8a5b861f5e933f0670e878ab9aa411085f1d3b49a3d857c74f7488765e71d457ef81a26955759aab9ed7b94ba455f526ca2b6e7af5952aa2c0a8944c5a096a9a99a10100001040100073160000200c0a064422811c49b25895dd0314000f6688406c5832978884591cc42006628c530410020c01c4184388aa681bc20bbb24d9978a9fd01c927094f2843e5091b36470d0b85ab66b5c8dd138ea6560c8a1984d2f47352c8b6c883a69926311a9631110fd2081fc3a11b2e1afd9d22ea727612cd34f8972c8de2ca24eef5fdd95825427138d00ce62197808b9204863e0e868068b01e772a692ec88d259b648ca1a20fb16fd3145bc9b2c782c1572ea341b8c21752453d58ff3acfffe499796612af24ca8163c3ca4f3c997e71b364b7b578f226469032512391c8b745af095a34eb2f3e13c4d435687a1c099b7747bc641cbbc9b05adb839577533823cff0bda4209debf310e8b6f7082e3988343fb5ae0bec0ca17cad83cce1b4f1aeae53d60366c3789b03f960da6b472a34688ab04f9be9c863e597fea4c597c3c8b0043c7c1080a32572de8bf40771086f2abbd9b287f6d5ddce33304caaf21c599c3ba0380931e10462880e20de7e02e635223729e22b3b952138eaddc1fb41dee558251f596265c448f1a677a0113b8d5cff52bd9e9cb4cb80b760700e199a193ef5292b4164941ac7571533c83607a2519ce769985e5a299ca1b5cec32b484a1082f58cdb8e5860215a9ee06c7a6db0a892a7dc52001fdb03ec5d53d6ae381e029f6becd0d4d414e373d84260288728de85c3e336d20a092d769f38dfcfac120d686921358d2d0304394c901926f7aeb0bb22ead3adfd18ccd0b2a056e1338fe7fb28420b9f02d761b5d1414412793666884023c2553cce9f39bda6fe534e583197b4083bff851e7823ec5a5f9c5ba4cfd8491be4c8c13557c0732662efe826ccb59d26f496d32271950bfb6cd6590c1cd7a8c305c2a9e2c29d0fe179b60b74f49c3c73c8c8d4d4a532b891dd54254cf7a2886f3b1b150a305e632e0c7fd273446fd6134bbde0940609e4326939d2571c2b84f872bbec0b6abba7802d980de6a0fc46e8b98c694eaaba786b8a133050718d1ab29ee2e895bb395daaa8cca228a8adb82d2dd8a07a2259e50fcdc008c390844d6066651c8aeb33bf2bb0825b2afce5ec53fc338cc750d12fad3561c4cfcbac6500b9e0627ed3a1d04763a22d6b4f68dfccf012df203896f0d2bc2812d0978ed0ff076a06dd6678e38900610660c58c2adf183c4a01d7c8d02e22d70e6e280d3426e4ee9d6299f0f88e2047cfe25a90154ad14fb02c0d2726a38a72d9e99a055742b3f5416b685d48790732634f4883bd0478a74525ad4268741c7f678d625ad46830d473821ab487a33c82f5a44d1073098b2c1c9034c200add96418f913272258629d4d90ad11e6a8d2380f60af4372b43c1caa5538d29300946212a824338896bef87358ab240c7cb1a046ce58f2c447c406cb836875ed8d042c3319ad94a09a1a84689067f6384fb0c5f4e8b58e30a93d91c65eea2b8ee67e9da1dfbb7a917120acd1947d29f9abbfea881901a9fb129c1ed2b68b2f9d1eebf7d0a1310966c4780362218c480eef3fd90758ae170146f36195593fc59a91ec0da9d3d96fc8e3fcf831d5f464ee4d95f540ddc6ef4613d6782c05c5ef9f788eadfdecc8b0fb14da252a12717ebeb64298dc355e57058ebfc32a63381414b34047dcb1be59b3e99b887b98a780fd71e45c2b89674941709777d74706ab07bc1eb003f8afa4a2656830ac9d543ee6a4b5b1a505aaa829d48801faf7e08500fcd6af7aaa424f6f05b8cf9dd4f5565c7c3836d37aa9dea0f29d4ac5a78e8a6f5b6654a4168e374389646acbae89d47539c2498eebbc18138548891883e4f13e3b9d61a2d4a07e58df60ce2d8eb5ce2387d18b98b4c1d206069ba9239b9817022d2e67280bf4c2a17b181456c982316820d42281d23f68f12746126802a4288ae23bf7f4b0d6f52c60d5614a199894ed8e35b2983b6d122aa31c28759c987da4913a7b0a1b2d29a61a22820ce8e8a1375f67edace243d18cc9ed364fb5af184cf55ec948c4d961a35df3fd11eff603d13facf93e04e72e2a6f797dccab730ff70391c423ebb3da48038c3d18f43e407d8531c8833bc1dc876f91faae634f342de19be35e08aa7727bad8c7c494b2e81b46121b4ec8477554781127975d7b842536e480e208ad60184e498d6529d79fb0a3366526af683548809a6d0b36bf7443b6a15febf844e72de8c28bf5be9cf058a2c494513b6d223416615ddef6abc17426c032e84713bad0ca56bc77410afcfc13e8d7238a05e26240d3d665b593595273202e7b9957043220a65d80e4bd6f75b509ef98249d4bd4310c5e3a0dd6b84141ace0c8ad9acf2d928e9a77c2458a64c285eaec173fb7e705a4f214ab31f688149927ff3a77794ca27e74083fb1e94ac12d7cfd2c319e08457e3d98636cc44e9ef5a9b8e365e18b70f56186a5d510fa05a3f665ab02aa03c2ede69bd122d5be77972ae37ad5fe20c9057966f64ff898f9ffbe99ea6ea225bd2712ec98651e4f953a33a8db5dcef31c4ed75d43c34a3031806dec63196dec9b71ea20e91c39183749c7526b866654ad21b5edf51961243d420f4a9b3fc10d64c2806395c61ebb1b922c31a47a1113334ce6d194ebb25fdc246ef3bc337c64ec11c8603aeb8833260405a3ffd64b4aef64a800bf97bf7b6d1087673123035407ef680a119d61a9693cbc4b5001c24861c57cfce6bf81e3262fbd4df15df6c3b1a9f9cae268a42f549c35f1b2dc5572469b3f2a65b5c6b60b2f6a3ed22b7570d1166a945de45048b478d55c8c2de2e241aad80b572733174a054477b81df6dfc4c7e31907102240bd6306a82993e13d181cf87d5aa46191bf687d57e4001684380c071122f430e65d5643775e79f3d1af79f30986f5fe123c136153c660f44b5fc117c54fdd8048a5237664265fe6da7d6f049d5bf8622632b2631babf6ca32e888121b13890ad0cc920fee51468c0a5e7d89858a69718e6cd49f150feed2738ea84868e88119d981a33711be023977616f4b86a62a5c815861bdff35a5996c79facc3c6307ef5581398483e3918d54b35bf3fb967aa17837e3930eb1d582f67bd4a5bd133815c62106d7caad7bd58ef15eea21522ad420baec735de0fde628d637825d7284d5aff932679d2336e3c8c0fc758bc923b4a4e43daa340629faf4b4040a73254c0e8f4bc836e9c932ed5cc269ccea3ff89692c73edfe8861c7e49800444e23e03ad78e1856d95607788e787f7c67cf3b000b43aad7348ee86c8bb5720ce922c61f71f0c92ec50e138e49ffcc3a93176f3d795453fe2f86aba7f57dbb468e2055d102331962e23d2eb8d08a184ab78ddc8a2137f851baa7b6e5163bb4962bf872518dc94d9904d04fb3ea61e6330720aff970127cd4b687bdff5992724fb8954839fc7b619c3606f1e8536ea593d36565c4d6f5adc01cbb989b6d84c618d76ebf697e195e769be1b549b7e622a03529ef421ac0ca047ebda48149b10f16824bb1a7294fd379ddbb05e358781334ae78dad50392eb1c3adf7560f94cae0bfce0be3875e5ea2572564482f8a315e36121fc551e740b4779be8ff04ed6c19c63beb03c3027dcf0473aca08b01c52845a82f095280ac1e5d3a565cfa196979ee120f9b0245b20310f264937ecc38e6c833f25d6b18c87028adcf9135d9b7175a3842c8b52bad5f4b29c652896c4396c59ec6efffc09f82e45df4dd4fd228dfc9d286a2e2e95781e3a7f302545abe5e07c735302b778ec9b0d317dbfdc8fe86341c22979f47243bc92ff619adfaa28486953f814881e534538b3f0e89f104d630f6b173b601c50766d391ebd9a86d7277921ba4437af31bf71d64d640041eb484088519db13aa2f4bfe4351216acf5be64a97744ae90d453d4340cd4363a16dd00dbd958f4cffc5a2e90c38440fab5d044233f530d78672dd3d80b7f96eec7c309dbb8667263b8e9704284fba6b307c47138313972b0d26d6f944fab5d0ef25c150ca8f8671026770a16068cb934cd8296ef85bd9955dbb3b3cd21ac1688b622ba0ec2d5048113e2d0d30a456712b0e86780c9d94507b0a8009c0bfe322e26c326f6a1b013065d1028aac045c3258ccbd7492b21863efaa8d6d7000c92d99d934b27418c77d4707342349de433fef487c85c9e5952c9334d29f5ce4dc2635b7e5de42b621469eef98920eac5d6b5192652d2c40b7bd91062a652b6986f957f9adb7623d77e86d3da542c64407797b744f3ea6ce42b3c31809e7d5169a9455b2907677dd447151aa7622a46e64b26d34e488a616fa5e30287fa5440ddda78a19997a90cfb9a422978a86375cf178c52a7e8b3bcf95cb0dc02642dca5934ce994595c248356c16f628dae11371eaf75f58070dbc7c1c5678eadba2de5af06263dd268651d04a2dc2b30c561e7755851951d4d9e7b7558dc85e1076d5464b935cb238bee6490cdf9570cb020a94f62541f50de44bac21941e9e7567039f67b817e7969b8e7a213ffad8aec8713f77b0a66a28f2eaec7284e2d708b74e109b7650a3e41a0533bd81516bafcc22b896c9f53cdf7955834d47163e4ad93dec2d81ac1decb0cd6b5fa5183115df5510de59f1fd9aa5fd02e22f6c2fa93ff4f001ac995320f7c45d9bd451e4ad6d2321bd72ed7f126d69432657befc5fcc7762a2ccd8621ca331cfe208cc9ca13f1359f482de354983b7ae6721c1f82e7f0f2b86847e6136a9304502a9b04cdedbdb660d21c6ee9c7fa13554ffded4b91117b48a14d52d0a2168d12185b9ea81dd88276da5cbb55940b01c4a8627a80a8cdb08f8d1f5cc0abf5bb28a7f865838d665cc3b9b442df12b676daddacb993200a6607a6b6eaad1d8448e004d6f9e7bc34fa03e1fa995241a668953636c758e65ac837fbe212840aa29265fbc13e29482666463fdda61b00618b513b8d88b99096f1803e19c931cb0980de048636aaf22420d320d88a0d4005d45cd480eb6574e1a9d0a3d5458ec989bbe782862c3dca144e5849f5e7a7e9cf3c15393bd78cc80574b033ccd59792dfbab594b66f06a3d13d84cec2622ecf1e3852556a51a5dde3e4834758ed8f7dd446d17b92599ce12c35bf073a183cf2576e960d2639dcc4f2a97242c1912cfa082e8d26208857568a3b66541c8447b2b8ff46531879e242d7a044676388b8ff3cf2dc986e1f2584721538fcbde0b5baa6e7f0d1796f1081eb7881947188e0640d0b7907e657103405fdf6ffd5eb31dbb22b257b9160b63984be24fc710d7b50847cf096de19ce867e30b0498be2895793f93132e514daa0b8ba6f06c9bac4cd036e271358efc4c18939f4bce9504f2ed7449526bee36990e8d7887c3d9e729e267de33365e3e63130cf4eccb9023354f4b761e3cc9bb2e3c8e65988bca0a5315c99bb843f5774d68cda26f4fd88ad45b593f120c762d05f6ac646a6008e76895a4c8e4c89bc6ea12758727868a5843a4386fbeeae9501d9ccf2d8a15c397c611662348913df1312e1c4ef3290ad5671fbbf4dde45de15e8a6cac3207884daeb03aa0dcb4976392643c46f67f52d4c0bd080242930e1437341a6f582a27355290c90cc67c1df378bafeac89f02c41ced2ab7fba6226cba2d680e27cb6925ec41dd2210ec25c6f919d81c7558fb1150a71f3e77d73bc4560076dfc9bc8f4e2f5d178e4cb4304008d2530772841edb625431ead9720e025eb6efcd590b7d462d202b840165985ac528c7109d92cd36ec1b52f5b5b1f4d8924873729c2d022d764b6997c938b846e1eefade05da59c4bfdcd51f1b98a5b70c4324422ff5317e905229d91e046fe7d9f6044af553570e33f680577b6d70c0086c4831350a73e83965713abf7f643c2997a2de31a1682ac47bd1644e94da1c25112529104fa598ffa4abb5c9d7e21d56df1f384d1692a804683cc595cb2164ecf99156264c5f9d2e9af537bd8062add5eb471e0e03475392387e9d69058ce12089b404bb54f00727959b9a38b9b67dfcdcfba4f38ed5dfa947123332799362fb26127ae25ee523ff13d185c9a54630421dc3484522394c74b806235a91e4f41fc21f34d6cc241252a90054d40da1e22208a9f63e1d44ddd9602dc46a8a795c810220a2cc80774fd4c2db37048e61435cb21b499008e252793a8f5867a03d6098e466b92222cf3372fe45b222604572a76bd5b37184608163ab81165ecbdc8ae812c3c7df180220e3c91326f69b1bbac27a073b237f58868508578913ee2bfce65529d76993aaaf1e4908e4dd88a91731cd41985ae1670d2c6e141db08a2f634ac5b94904ee2a38b97f529ba844f9dadd597ad2ac22b41025d2e4880488749c5d59761aa0016a6453a20890e84c235346d19c240f5e93a5c3cb8f48d21d4135d083cca26701b9e927417455dda89ba1e0e86d006d7934586ccbeb28e733d5959d729d0895199edb36c69cee14a04e8ba4a940398263549c5980d69cae9697d74b45319864e8faad011b8ca52fc185fbc3d0e4f8cb645d7822d077fbc352c9bdb09a831d086a2f16a5c9d8f5ce893e31997432c69c697aa9f9d987f6a51a737601b429387acde9814bedc094b6ee211acf839c36f406c4859fa9a27f78601ad9d1230f44fb937e0881fd7e5924b855eb03a78320b8d528753bdc41cfbe7b9f3d977ab6eb2b05ae0907915948a0f1ab6efd81e2b526535c12531c40eef39a6c31889ee1fdef7aa07c2dd6ba88ce0d1d301e0e80929322925345fb442c7fd3c2c41e88492ce13714bb0c07962cc68c2752d8b1269175d419082e781bc3342067ddf6d2bbd8f9e029033a0bce5a0faac32358c69971e6b77ab5d913596eaf2677ba5aed19295eb5cd71db5bd91790bcf67d7050efaed44fcd67b94ad82836af9791123a2c60f138ec92e6962e68f349132ba948963fd8eb0db458a43200160941242df7ef7eb386f82c6eb2fdeb15fd1e337d1a24f93d4921b602e34b215dc2dfa3dd2e4c6a7194f4d3e8c9c2b6540b73b0e006dbf590fd42ce903ee4585b1dc2c524f7f9bef414aa1314897f43de3e81089a0711b27776a20d51ce7742e63bc6e61b664b35a7113664d68499f4a7e159356cd7298cee82310433cd3586dd50e4f29324952ed2237166ce719516bebdd21b5fd89cbb5cefe2f76f8a1122ef7e2088a93ae7b26ea22675455262ac959c1ecb9447ff6d99c3fc886bafd5fa254e0f36d6f5b9c0eb47efb11f75bbd7c14939f9cfc78e218546dfafa657668d1d4ae03e9808fcc27ae4332016e2518075b31a27a5516515a5248e6c008a3bc11a1e74124af9a383fbeb019a74a9bab6be4a407444f1220281b88e60825d4c99d3dda903dbaf4415dbacdb3948130add493caf39ae5e9deee2e48711dd8a501175803b37afabf35f475d5c4d7a23e54aeb8fa8b08d86fd3437f4a9eb882a4c7a1a59ea09cbfef0582ea728a51650e15848ff089295e02de491ffd9673a87ba6a1a4e967cbe3738deed24bba55154c14238fbae1f87a895bc43037f580350393f1c33b5bd926b6a85d126bc76992d33ac573e55c47c412ad895d6a6a9b69ebdba8ed9acbb78f188222d44062e81715342ee9b0a39427979404d377ec92482057e485ec827e89dcea08c830d6fc6c5edbefe40d73b41915f89f36a70de8f53ba6a75357117a146d29aec00a45febc4235e3a3ce48240b1c24ea5511ea3998d38d785eccef742a90112a3b8bb13c19f86db00f7a4b3efa000518838a50c185760049ebec7b3805c1e83f0923aa15aaf75371377fe5a58b25188522ecf7b4430d558d2ee13f9d611ed3da7d8f239b15d0758f1afab2a2f83e6d44e95e65cef4f5cffede9119240e9ce2a8b1bfe893b6140dfa8b931c50cd7a64d27dc77f05b54218c014145016df4e690fff0c8736c7fab0b8fabf9d294fcde155887aeb242abe0814c743d683ca4c1bcfd14ce7741f5ec6f4ac09961acd297ebd3a14a6a021b8d232c7e8a8ca8996676017d38e99a21cf0c697bee201abaf45df1e0fa9cbc40edaf7d41af87deb4c7b1f2f772206c3e3fda4a577882d0cd13be9c3de35e97db67a3c53b704f2e4311b42bfea9f07bbb387272aa77d97cae531ff90da05bc6faae2bb0c591677a2c0b22411979b894ac87ffe6b79af6696f58e24ef557eb735a35a911a01791e9c2dbb74221b45191d958080110b55c5e8b416898a365b883fcd8950b9c6d0add71f352001ed1b81115541adbd24c3259ca30a783243ac4aab49db084cfbc590275f053e55141d14585730671ddf65af48f2a88537d083b641a13be5e69b32b661447599a303a3df50256bf3fb0b58b700090145c40e5f9fc33a2803c0b391a1ab3910b771bdcfad88b4a5dd183f91d0063d8019d743129a81368e7332289d0c1540c39da3e5a7722a8526016973b3b27df95ed9433f07e5838525826d8908309d95357e4fd5343a9ed8139191e6c73340a1b015e932a0d6d20ef8c7094bdf96e8a7273d39d3157f12aba590be857869301bab1298930035e78f5c6feb2bfdf5e68f0ea1c849f74a3217dc658860265a57dbffb44a0d89cd6b731fd919a697e2dc5fc3d865d88c72ed39ea84f2acb9c7114252e0f6f85a654a37361f552e199f04e5609dd3e27ee35d904b26898e459b35b1bfa378741425274b96db32edeccaeadf7621bce02460e3cc122c1b9f9133c0bf105e75026a18ab0c588211415b13edfed22e0981e36ce292aee57d1a26e80ef5a3407deeb13f1e2eb0bb5952faab0bacf568a5b62ec195753d60620922d15596cedc821bcc799bb9773091a1cf61b89ab46cb32dcc3cf009f8a6f878643974715a7a44115cc62faf59cf07ad69970e2dabdeb6f84c73ec0ce3445aae4f345b7ae32988567342538800af4fe4803bc6af3fca9727e52a0c45e45ecf4eedc26189c9dd54eb415476b823c7e6cbcffb15c657cd7604ec67be39714774924ac3c28729cb6c0e78b39a26e6863b122cde2b9dec1edbcc7d052eece673841e5d938ff5fa55e9881bf47015e6d23350ab55ce85bad0d13149ec22534301248d2ce84c21353f5d2b13552b546d113616e9085f57af45db1f3f38126fc4a3ae57e18861e3afc33ba2b9951613e0ba62f4e001e64674f5cce7c42364308470ba7fbcba472320850a57d4a6832b72ed7eaad50147924db90849e6ef49996e51d394eeee59439cc4b28ff16864bbf4217268a7c8f6ff50346bb40c3063f492575a7d5154c3211f03804b4a16830cc6712704ea3cd1069e2fe39555d30c007e74b9482b179f09fddd9fe4b696a8782b16a8e16e6782c9a8022c64407a7d9e8f0a8c37adebf33c52d315745b9a863ee8e291825f47597cb947ea21ccc7f2d8d7235af47e10384db94cd3bc088fca2d1e6203f56ae705d74c9cc65c8461971fa7c95d7ee6f3b94f4ea71cda926c9707c93e4a1ee15b5e2b6bb488e17a2a3eb09956ec29480f3431b6850db735aec82180d833c49aa293060588ffc60477cbd6f19c1b6315ad7ee0774c18acd60f7ff2256f84312a03510743ea157f1b8c5ec79ecd5f3cc0302dad0261ff3671d753d626c006ec6244d7d8dd1aa6f8fcd89bcac710e1943f036b1e1f4c50e30b2c50cb12ae790a1ef79180c31504fa26d007e397dbc18aee3dfa428a8e57655a07572e5542a7d110103a9149bdaa440dde55ba2c864dc66c5b8a626c4890c913767dc322f18f7110ad737d6f7b43e7b636b0bc62bfaff4952cf540001e054259964f86524f46685d1bea4299e0b7ef6944f963002f0d7eec03ea8949597aa782e215a33d531f79d0706a458f91bb38d93f1187a58dae4840b915f5045090d90905cd94b4612846ab1b56321e6f41da24cc49b6c40427a40d270f42f0f7233fc1472f421ebfc9145d973441d70ae61252291d80373a0f6496ae32d4a98892cc606e176d52474d9fbfa032f641bb52bb071270d6272d73570dc066c93a5661ce09c7cb990edb29e9c86bc612af15fcbbde03e64a929491339fd95ce2fc7765ff27826b8c3a7a5ff70fb23d65eef772e542cc1f9d2391795fbc52d8fadb8df3825accf6f0ac05d3f272a92709923dc29d4d99fd26910521981746d19827d629d138543f98071e049429033bb82fdaa9d26ee5e9ecfdc6ebffd94438956d613e87ed55da8b7ace694ed3a9c84496448dd38fe0b31b0d49cb789aee13327fd73a29f6d7af2fe7b6b3a66572a621ca5167fe95f5147382ab0bba3eef5bce8dea1f091d68e2307f52a84cce1ae5b0ae7fa114934429dfd9a764dda3556f47937adf2cdb32dae2cbc7900fdca769fa15e3eb854a914a0412cacb1710d19440330358b4c5bff94b03d04b58a1868d52310358b52d106b144f9b1021854e32c795c9de1ca7ceced60a6132f3fe49b0d2a4b368654f8a66f6e0a8c2513bd1e1708db6d9c8f4039ffc7fa56b18bef649472993397286cc0796d71fa78fc5d932556465522fd2a8b1db0fd9663e27a4fffc39aef3cb515b020eb3ae2c2f85ce2379b14752d49afb3b4f06a9cd44129254bffa4e15e5d0550ad810f74979c9eba44207bb663e88a1bcb4ce6e1a09dfc4b835a52768df92e07805ba2f317fe6d646864b36c5f54b3c94b64df05a3af1d06b8e556a04275acd8281c4bb80148bd5d4e0ca71e74fb4140c9ca8135551253e78f6dc2f249d2e57989b0f51986baa98058fa68da88215329bf5bae43ba865f33f095dc5f0919518200db02ed797e68930eabf30cef2ec0659d0887dead360eb74917cbcdf5939d520f374e8530be81dc33ec812d5beab1b4cbcd332ec57ec4e16b0679c1323646fac6206f9e0ce7453f4a1ca8f41bd3c33110f0b1b0192d7c29c4c2240b823a9be553388d2fb9ab063206404160b4ce1b4aa2231c44aa68fb89c4f0e6681ffe91279ba41ad80de1387b4897ae46eeace0faad46733295d810d20d5c97b94bc6f269718c5a652d682bcd1a76f8281e5ad2710dbe96d06fb0d40d1c9f3485660e080b123f316443f97061f31597393034b062120eec716cefd5bf49ced0477393420a276d21853fe52638f1aa0553da7081ac04b3ef708ccc84f4bb27058008ae4ca9f948c522c7afc442c3f24c8614e490223b713cfcc3a111cf4cc6388c5cc609efbe5329dfb6dc726a59cc605034b668a55eaff9d954701392ee588b19af356b695ccc5603a962d60074c59ea391a9d482532b10cd6c9fc21ff1a2167e76dc5f21bd0f94ae6364bad4e3faa2af1ce8272909b292323e30b5e9b146a495285c1376e44cc8c4ca6d4e782fee0915a1adb5940268e0a8285dc94fa19ba4a64dd8e0f799c9f10fadfbee10e5b215681290147d6978d5b9fcffa470a8db0096d67daef509eb82f17e3c829f594cc51618ad0dd2f728d3d41934c2c6916cc4a49408c281fd9e82e346ad2bd83d547d1e98ccb7e3d37fc78943c38985a4a091c64ed9b289bd5107287d2920c1b982eedb1f5efbeb710d255832ea3bf6248467e861338bbbf519ef2732e3c6427a7714aeaa4b4010ec70635af08f1240eea14810f7a01a1ce69475e268c67ec1d279f9d497022e37d9c9ed04d6e5ea7240a3db48aca1d03094f69aea6dc0ccd903765d208208dc0eca583eff898693f017f43761f54ff63b9a77972751011231c149e5a8c4778dcb4eb3d839026ca78c1d9b934c4c04faad227145f67cc3e46d7d4dbee359e27c8e5f4f9b8a0f0f210663b1ae2ec0ecc33be24504f6bf2b691eba67123f710879d5b1946ce976cbf3d6909a55754e3a16b1fc75ed1df6244f5cbb5d9e7482d4f531afbae747e1ea9e6455f95d4197742428d7ea044c112545e5a1c3ee396ca24e8b72412dcc7a17e9201eb3dcb2be964e0f4f51fef10caaad441f2ce7c1b088322c6225d5808f687e639e2222e8ceeeb6aff75e938b9ae9af0e6002b095c024344cb37e480e81a1a252c97cc1b3fe0160305586dd9259a6a1142eae7c914bdbe714bd39a860ef60fc90e12a520acde4acd2605c943928292a79c211b034fe2f60b9a67e4f71b11cbbd309482048763625129f9c2a65e66a520cfd341676e5004807d20f482330dd3a4a08efe928e7b7c786d0a4ae22645f2aae2451bff736a90efb154e3837bc4c055200ce6150b52fa998f97e1e6b20a0bbad0f110ed621b9bd4b08049bca3f73755076e261deb3fcf7d26f37853e8ea7f8175f5228f0e95edbe59008492015ee532757602c5ea17026fc29b1365d89b95d8d4526a9630ec69faee96fb6f0e07d4e6f1dc8ca1b0d5d701b99c5016af19ef5b1f3616367f090f24ef5245a892f6dc6c5849119d710e8eb61a833286c8fe646c433dd0148f2894105582af390a1dd9f20aafb279856ad74f03d0092c9e070a6aa5675315854dc024427b75e788506dbdba8489791ba290888d3c1d75e5125ca984bf82b861d4371cc9bd47861bdec1a1338f1aec89466f846e9c7946275c6c1eeb1ffe5586556dafc97ed3bcd5e9cab764320935b925fb97267c94ed266c4c1e86e4f4ca4bb4d7e2cb29f09329c0632e1e3a9d195aa171c1446fd84290c9f215d160c227dba8c43ec5c6e56c350375d73049dad09e8b348736973ce3c5ee4d21e5d80c84b08043091b53e397b7da1ad11a46dfb80afea9edad0fe3c3e0298a09329af41175334e076308379e4554346d2aa70fc7b45f9c4a7a290c9c10085982ce86a2a14ac8a260160249c2009a0e4e1b386b28b7cc1427236f053da3b1c8a6400cb9dc5e27d326995edb314af8caf8e4fa14ed3e4217503bfc26267df4f546a748022bb3fd9d714b70296625753fbe2974d8e8ef6a670d568e872faa85a0f23350faf9424a811348ea81c9f999cf22da88573ca1fea0dd635318ddc84e7b69b7c5ab69829ef45c02ef0c4a8b321892e7e28d483cb8830b2b7c4d09b15854fa15ed13a407234ca4ded73cf3a692721209bf7874747f68caa0dab9c52810cc7a5a123bdeb57c33bb1d58159b648c5275ab1f2797650a6ac8dc1d0c7303c20d1c30c1f9c79d46eef02b06fe356b9675cc18aa5a2ea8a51a86633b7e34c097e808cf2ed1053861a9b197377052702365ce837cff3143abd8db10b7905ed711f436e421556c87f33634f7b4e7ffdf574605535fe33cebc4e3935522c690f654555167b72338efdbd9f5134f23ba92c4ef239c23677482c8c113fb82cb2b224bd33d19731843490d024902d6c9757aa6c6d496f7c1eb071cff57ca3db00b5fac0fbe18a53494af30883473361160f3e68e73c9bbffcd7f6d50a78caf933d06e56fc90107a674c912cb93ed90153209e88bc7e838756ab4a34456fca2dd4ff16617432c8c3cd9b2672312dfb074a932aae983b66441e7cd1283e2f5e3845560824f2a49999d4e208ff6b14cd42b9b940ee0b0a7da0ad2c23bdfa63b35d4b8d0b7e6514902402a8b152aec3f95c9db0441d040c8ef39488032919e545d42659595f79d44a97105e5bc3503838c807cfac7e92fd1379a68b69e6446d9d3bf443054879110d93c47b8714abca2073c62db8843fd1945d6af59e46232a442106c02ab42619cef22638aae9a43937282ff2d7f24577c179ae57df46ba33ec5d276334a770db4c536cf2dd8d923662d106aed48eed1d50f088065bc4fe26e88db240074d3e769f3562e487c660b32a3bcb21bc6290f9b5483d324dbfd62cadc68e19d6470176170e42f68f57006412e6148ebb3601f7c5e3987bb00f13ba53546a4caaa63c844daba852ad6f548917246d58fc603818782e956cffcd5161c56c7ebce5aa904e390827f88b261ed43f602aeb4fb9532b4f6b9cc696836077d430f4fb1d6d2ed47629c0f069c0c963b7100448020e87d478838ef1fe2207e5949e3053024245fe695ef6d8a41a96465919d196d7074006c19c9dc263ecd589968b4361b866baa7113080f0153ff62d3850b36fa48b52a8ba974ce65ef85c385fdc04a2d4a3f5d1528abf839bc26dafc47a4e32c7e3fcacdc0d4ec4c083f850f0fe82380efc4cff2cc46b7adcd6244747c86391bdb792cf063781cb8df13cc3a1a1c8a06bf8267013aad14594a8e31192687a4fdce5671e1027b4395953ea21e8cf590b4f978242d7c45fcfce4af4cc899f0b8f672a8772caae1152e14805f0e9e863dcbf1046abd47acfd3e10bb03c0ac8264c3d5270c472fc172c3b9e02140e3e6fa03f88b7206bf36d7acdf62de60ab8508bcc92e1579007b5a728765b02032dc3c9d708d258045cdf5a32b193565170bb80721f442ff2025bb5a943433723e27bd3569fc3a9989d5be48191f9840571a86489ea57c7c5c729a08cc7f185cd9cd20af141f37aed64c0d50994e1d0e330b311f4ccb94a26396d045c558a6118fb54827226a118d68cc524ad1080be862512cd244235aa68812772c0dfa0ac4cc83440568b379e8779202bcc944f0035115de6822fc41400d693c1bfe22a08435300d7c9254429a98863e90aba08dce435f8855304d67e18fe40a88c6b3806f122564c349c8379102bc6132f4934805de34610508af0fc1aa6391303c64ef1ee5647c0c2990075849d3e3e967c28e7efdbfe563ee9a367d272af6b1429e659da0e29114bf8321a13b648ff2a50c63eef5579fe1337baf48e6d083b063a20cc0c0dfe7098a9f3d3f7b0de78ec94209b297a12a83922419bcfbce2380ea338a2e0e72838b4a5c3aaf9a6b493e38d6fb58b6c259d44e5f79b3b7118f948fcb5195c8da87719b37b7aaaa041765648df2cf2643328012001d2809d13d95e9e1a0ae12163486d249ad6f34e74b3038a8c1b4e45ddf80cacccf505be76c236425824bb592c0a7b0ed9049d50fe87befafac32f9515b3560425dca1167ca8105013baa4a56dbe8ebfe8c12312a61d316171b254059eae4040d9c200f1fea471a598009cb8b8d1a502f75768a064ec0834b75228c38c884e56d4549280b3a25a11937e8c185ba48461a32c5e22a8158b95cbafc1a2845078f39b07405b98105c498042e87238d2cc084e5c5460da8973a3b450327e0c1a53a11461c64c2f2b6a22494059d92d08c1bf4e0425d24230d9962715b5013cab2ce4f69c20d80a55e44bb82b9c50a624406150791c61c60c2e266a106d44b1d96a0811be0e343fd48e30e3161715950128a850e4ed2c00d82af996425901f18447222ccfbb02b7981901dc6a3545497c3d984976f0c31e321f7fb5774c181e75e1b761e42375a395b00996706e30e68b1e75b8ef636be036ed839f64d2430c78209a4e87c4dbfc50a5fa32dec9c129392e7b0c2842072bec26f6be549c8a6154fe18cc4498cbda0080f9ef1dbd87928ba61c1f90284bc338c3b428b9ddc76dab1f31db8d1ced1472ac10c164e90a2e76b3cad567c056fb173969848328f150344d1f98a7e9b054f461bac798533254e30960d2570f8cc6fd3ce43884d0b671622f2ce62dc0145fc748bdbcece77c10d1bce3e090967583885149d5cebb5b0e62bbca59d538254d21cac1c1045cf5778da2d3c09deb0e62d9c91608ab11668c1e1b37e1b1b1e463658395b88987786714c2831e75b6ebb76be036cda38f44d249cc5c20982f8740dbfc59aafe22d36dc121292e7b07284283ab9d26b63e54978a335af90ac84098cbda0050f9f79dada200f53049faab36debbc91fba0f3cde1f28017b2a565f6cf87320f9eb0102221b3abce7ef95af1c02da126e2c1cc314f2c9cd83b5f26c18d6dbc29f0f92718ba921cb76d72df96b8a64072879cffca727dbf35b2791c22bbed83c175ac382b0706479c8c8a3aa8c9c6e9d0a95ab4e738c7e6dedf9746fd7c28e7d0a11c0d0e79d0e4706da13827f0d0f28c9ebb62c298f39ff4b47cb2ccfae28b51cc82046dca4331462cdbbb7ef04e704ea0023bb5e861dd62ee15facdb54a5ad3aa98b7b7a250c3ef1e9adf3d9bc7454a8bb9c9693731aaf555999fb30ef216860c3bbe10eab103378c487f3679d7303b97ac4183b193670cad2f85579de8896cb6e93aa33a8c208fba66a4e7263af711a2ac9fbc8394b1f466eef7b8afe5eeb940c5750bbc8b800b9a8f0988a05105eab20d834040fae61d19be2fd481788ca0c4033df3d7c33a5c64661c1b8ccabc78c72d4b0835f54e4a72fa038c1ae4c885852ab00111525f8b815593b107948c7b5e54186d999078cb3763dd59cabe21510f64889aa0351178955c53b2c54a62191b61fbdf2159e703a0fbf30d9903523994273f89d011fe7ed84bac47468859351805d7ec3c5f9f31c0e3b394e0107a34f065283465d6f6df9a39e8609ee579d2053a60b3ff09899cd945c6b724e3f0b65a3e73ad04199788b0d10a374120b64e318ba1518b6bf2fa6c71baf3bc2e8a2566e3e16b2d0fa8ffdf5c0d423282b848ae71ee19e36c1c521d91807a41d76a092d9e49b148a46943a03cf815a9612ec0ef40d6b785adcbdf778baaa760fb1d1fc94df6ca4609459a397b3130bfda5210c5d4093a0eafbbcb5ef06da097404af33f58cf1934ac8361a82937486b731e163ded0c3b701c6fc38dc6a2de15a5474fa4463d7b58a58dc46313d1ac564e8f25b6b9bebba0cc4b8703a0da66913b29f04025db7ab83b1632711b50eef81a825244c15fb070f476f2d0d642f48203a6209275f1f5dd5c13c0e793cc76f173f812f2a69f68298bf964f45a26855ed884a3d6c080797dbd82183562c8b6ffa858d2cc10663f3385aaffcf156314c8019fac96b96395fe0a089773886caf5b3d0536cb30fc2eda0dbd66ff51a03a06ca18256ad7af0399a2e96b754a949a2220e098169784a866d2592bef7f04bd6b44cd2aec0a9ddbe02ca7af4fbe566c7722c76d05f8db29841957038af752b6f685dba8bdc3d0c24852099715f1506e9c052839b6d5c492a5806214211253a32256537a948f8c9cce8db56e41841a690640902e6ed06637aee73cc9d88c62e841e1aee4a01435c56445f283cd4e71b4a4a1b6b24b6e09cac4439e24c78e1ea20d68d2352edd4e156302b283c368e460bac0c6b37e85b1376a8a3d8b10b9ca76e976b7d0a27eb30e3fc3228f824b5ce4672920d0321a4504b521b26fac26410647604a2b9e218505905ac6830e578d5da9a0b1cc5cef3836533812e601048f36beb6943a0e29d2e4e7581ed82c6ca3264b2388c6344093f7f110dff0e24671aad4fe9ab7b2e5068302b86ad44016639bd73440f0b09369768e850f2a527733564085d65181ee5042d43939784aa4d212dc150ff9169e34973722e9988d59dbbb64ebd52c06e32d1eb44deac95a6a7f9dc6ca0a31929158303e25a9ff9e78c2d5d2fd8336c544269062dc07d5e299d89dec338e968e3bb37384b699555d934a44e55dd1350aaa7890d0e1bd49392abaa2ab6a423ec45b2e1b972ad0a5e4312a23200bdf8a861816f8b798b9c525af0a7e9225ad5d7829f13d29ae9d565afa74c0b0c834c540da124113df24eb437202451145bee4f9ba3e4629d8b3fd6ee313b0c642f3876e6330271856f17d7f0808ceb468c8aa4461501b52cdc11f25f052c318aa6079b3606488eae3ef3129e3b50c74ce954b170e47d49708ce09d2707e1d660fce5c7f96ba51ac964d6b52872ef167c72408151def05dfff55d3bbcc740bd2d1e95376fdf220bbd016303905ea2e37e0eb7b4461a7c7333775136591d928504541cbf053cda8587f82097cdb9a1f29eb8d35ea07b5b44bd4f1860adef535e26e0bc64d19d49bd04441a79729088a13c44763ae102d6fc665b4e0c5a3b5473f297c8402adf68e9e350753ae518e990e50e98ff221f2809c38472025d73d0a57835a9949d97fc851be3cf7bd884cc0bb010220dfe4904b78450a1a987f9cfc3ceaf122a569415cb65342143e4b474d50797d3671b3cca55159f0379c516f3f8efda9141c18ac38664e8d1b4880dd31ff0a7dbd87f1d66a276cff943d454262b65832355094e2b9649f8def5fefb1a0ec0c0b460081c1b46684160e0ae4e2b0aa333e1966300a7f536fba290ae26901b0b1ccc9fe6d5499c593c2b09650edaf9c0df192f1428e57306ec859f862591fb744c930a1375081ab442499567a4ae94d2ff85c04b626511394feded1afe38144b8961124058ee6b9f7ecc8195696248c482af462c79a6660820f62309e36e529120675e43c48ea4576c3ffc69a10b65e59b521483c7cac79633cd62ceff5524624e986d50c6f121d24923531d30cc0d58a9af881fc102010677fe03f6f6d5d2e53de4fe093359f71f4ae4c54e50d28ba4f2dc0a27361a03c1b75569a16612c883dd0f07a3202aa2531253b9fc6c3479ae718e3661280e97c0881cbd3324ebfc5e28c6d5426821712c4c6d2909f2c4bf6b05d55c34090925a069297e83758dd70484556b70592587941a15cf8b51b2c566637a5a0c1e11542ef3efe9f1559186843cf92a0ac7649a01dfd07dda670ea82b4761e3ee08323bd45352a8a167bd1d2fc6e57b00db702b5c653507ea6bc59d30e3b4314557dcdf3b5ba99f72dbb0cd50b521f907eb9c0c1a23befa716c1f17c360799db9b6af2c098ac58d3e0a1e7e03bd1a410de8acaf49809c48ae74e4b74757b8742f469626b17c36353bc2f283d268f43a6f3844c50b049d90919c8b880f817c2c38f47b3d112977b0051a67c3603fa0a7c7bf6b85b00a61a8bc0a111fb8bd057e4c3b31cb51f590e6010ddcfc07f1b07ded4a11b11b23ca1372b4b4e754e0b7e0bb2fab952804b629d341694df23501e1f4cfabb52c2ce287c3b1d8aa6fe9e1231a58f92a90184a2a96e3fbf97b897f11cbf23920c09b024999598230e0dea10b3419acb3384a51f8280a98768b06ef0304670be32ccc4885f6913fced15c970c3edfd1d3c3cf304d14cc2145c4d7b92b01b147f48d7ca1a0df677e6eca4990d1ab1610b34934809527de6605bae023ec0d991cb67ff3470c8d8064a2bd746515a18a1cbc10b7c2c37749177d46e54e1a1e711d958600a2619b71c1e7699f69e10a1fbe87f1b0a5dec69fb78e2ff026caf2a01d464dced4d9633ff00bd4be747558c687ee30fd97b2f670145070d9513cb64562900faf0d17bd2203f27d0b24b3de05970cb1cc77c06ac4ba1697d590ac6ffbb1e9454c76bc028e038d8196acbd1dcd20a89e401c8b55c0fc636abfa2714314d76ff0dc10d761ce848d97758fc9cf7dcf4b187dc81c39a7b1175bc0023f0fc832f52ae71c49e95c49cf10dc9434fb0d45dea0f2e9a07ace7e4bb86ae6b417f46d0ce51ef69fbc85a53065af3334bf8f4e748f745753effab451ad6be05fe07b63f27df957c1c65f207de845ba474de70896750373fb5c71f06a9c09a1f559f9af3fec83b460cc631444930d1f1049cc506f40d16885c7604b1498488a98f009db89c8ca7434e6681529e08c7737873baecefcb2f910cac03f19f934c75b1fb99a5a51cff246b9f882a62176b04adf151dd5b975c23b4b0f1d1d5a97f5efa529810b57fc15a1558a9c0713bfbada52bb675b6253afbd18e33a0f49af35112c48bce3848698c9c1ed690f7d7876325a294b55aec2c18485cde97a38a1efb6947693f73f25b846829c1a64dd2447c7a02fc607c41a074142282c6a375081916b0c3812d2da24872c38c01c34542457093e3e2fefd6441c0186e78f06fc732a3ce0808d82a4e8079d19e8c2deb0808eef02bb3c837a0a41a981f0f56d15160892782141b5454e9997255bce5a012172870c17ff4deb187d770e9f9db018200ea7250a8fb0060a59734ded0e2ec06c429a6bb70ee72d58761b2418a69ffb6aeee4d32d090e8e8ddbac382dc4d503295a2c6990a3d2702dc814566309607945eafe75b77e08e52da6be0af89890d0a82499ddfc49dbe206179abd760a955aa5cba994477afb55c2581cf85d7351a131316b632e76194256e7e9ad19bbb15bce9e1096c11cf1dea108713f4c82a6197090ed74f73f478bc85c0385ebb920b6e1aeeed21097ce049d507a5646c955d1670c9613e59db1c25bc3cfa0fcc26cfc6fd83a90c0626e6522000fde8e28145d215272b915cc86fce2eda39db0550f1f4d0d951ab332de1958f44438a3cf36236389344427b332404b0c887455849c8d1a0db2adb4efdb40ba4d260cad3a412ad91b6d0706ad68786fd1708a1435f4a61a2247ef48c3e1ab8de7173dc32905752cbe09906997c4e83c48b599b63499a37ed0142bd3567451231872407d621431799f97d39a4ccbaac6a528d3da948d961ef9a87dd7c5beba82ed1fd8295fc009287c730499cf7ee891f3d4a270962be5a10c33a16fde6e67a302e3c447318dde6bc4c216f87aec37c5eb5ba329b836568602ce815cebc0e671417617dd14be1e69e481b3b8105fdb5332d2f13831cc7df05283bf72f89b06da0e1e2e63b60259c18a03604e42d05abad91f70315f3e3fdd5f472e16aaa34f3542b86178eb53c144e412a196f32e7bf363a86a9262938e63107bb6ac7aa6010bcc913745e237fd427abba480b278f36d6ea78521bbd4d860899d5df4988fe3341210dd1dc4b606e22adcc6713ebb2a4a38930ccf4f6bde8b0450a51d18b504bc9561aaf2b83cf40d96a153ffd0d00022f1ef56580543573aa08e2964531550ba6b2593e9ffe35b118a2ba9ae5017979421b9dcb1c6156620110c3d9896b06fe2bb4ee778b3a5d2182a799a8ffe34928884286e4ae20658ec769533c74f0aa16575f8831127854f05eaf03092c97108b06260909a46e6ff2bf7b90e056e57932a19eda3469e1e155c8d350a8dc6ec49dd49e86e23f4fcfa9fda9586ffa48334b69bd52d16596445475d2927d469c2ea3dd29585a60952374a97430be42744536196fa057c627f0455b90bfcb87bff138561c8fe44e73c9131b50e0b62c261636424f5737418f3ee0c3f66343f50bbdaee30fb96230855f7386ba744b24675322d46105c56dceb46cf6ff4cc819d6af61bad6964850fd521f0a03e200a2c7825190efc3d346736744c69bc5072ad4faac8b11bc0733f963e30a316118b59f9665c3d16a4191ad801e83a325f27fe1410e5fc8d884f903862b5d16020331e7f16ac07063043ccd3deb3a28825c729221daa2ac5640d4deb58907f2df3a9340112e6ba446679294605ac38beef203c8a3009e00b4c83e77d6c1cd72053d0e43638fbb1051912dc7bb687aa9a84724c13f69ea3799280ec7c92abba8b878d5decd00d3a978c2719cf787e6be10855e95999b4b551b327adc8298f1bfb66a9f4244ea388254e32f9ab336a2fad0197899c45463a9af71a16b5d5ecd450b21430281e8d9f92c1448fff85d0cc2be251aee44b377b084f9e38d93c21bd01d14d016ad3a729de1d07c2b63cb745e6e91483302dd2c3bfd6c4648321e1ef4c2c7dd9ea9f748e9e0963bc0fcd071e232cd5815e1ae84f8501661a45ca2fa44f229864c2a6aa6875cd4776a288fb818b3684134574de2997a99eaf75360ed73fc5772f90e89b502825feb2db4bc3cd548013de846b76d8b6fd192baac6117b24e68d713b2cda3bf28ca84dd3aaf26c516e906ad1b827f4a924753ca4847a2930dbaf9d54f09e51e656794ee9a580b2c8f4eac7bd964d17267842e4c3730a434b9248bec7f7a3c12e4cec3c6a6145e33962faaa1dcfedcf7f1d199bbad576f24e0ea7bb989f8b4413bb63f729061b38d9d6a07456e5886fc57d09e9f3de940903c8e29a887ab1003d93365694cb9c059d6ec112b5d6d3f81c835d76ef9589763ee2bd5a827347a80966140a5dcb6e133cc357b5850f866f6906b6b58c061d5f6486ef53706b38e4a10ff7985056431b36c5a3f1e5d265a97d0db41937a1f5db0be88c326e6f21b70832d6c1f853a6ddcc4eb855d909a5f82fceeff01416d016f4923a1bd793a90e6c9e4471a81be286979a7a84ae3a2ddf98321c1a106517e7e0ee97134fab5ae0c956c21035e122537d5ba0ad278926de1ae8148866203ddddb50107e34386fa75e6106e2cc9c583cd9fc58d8450df13691cb70cecb4c49329b8c409a8fc9b25bf1b4f3beed5d83add75e2f95e21813c78b3db41327691c6d9b303bfc264e57f8bee2181edd163cc8cd0ff912811d0f8b6e8686ae14f11ef6ecb361e5d5a1b848f132829486048ab820b66ee030565542219e824c5639dd989b14fb9b74d9008f13a109f49e318d37a206fce276a2f9e2d787411948067d1ba3207d3f5d5c0800c6b44e8c3022255fad9352465e22e4bb624b87f7ee355a2d0219b14ae94232aa2d72d8c53e8c0bc2b4b4dead3c5a496c7686a6976d12c905dfd9d4f68843759a4c80cf486f50ee812bae91e3eb0eb516ff7c503b3fef5ea4ef8c0d54bfd5d160bccfad7d7256102593ff577473c70ea27f72dc5fdb6a4092c7336c90562e986635d60a78452d7c206b647fd5d151fd87e72af52dc6f4db090f137bbab1d70eb59cf2ea8035ef9ebebb6b040cd7876ac08bab1062d3a8ad328c2291c0a34dd5dfaf240346ff908310003b2add040d79507209b053a884a99c6d8236ae52dc496962ab718cba4a00c63ac9282f28db1b4eca18da3a7dd1f87a6f9bcbfa46a35df3277582592e5a2844eabd3bc375f398a24710b95b0a9f3c38f3947c18d95103ee7286225a428bb619f5241994bee27c45b49a8d620aff560d6c0060a35b427ea2faf917ed1c2693d2104554e3705216b0289e4c7b28dc2099417b6cb78061254073de602b18845feeef487d73d49ebf2dafce58e9a37aa5923deb507a1b41ea378655ee4b028333e2a3bf4f0cda3c39c701bd10e0cd29e24e535fa9e0caaf2a4ad60846ee8580b2e7f5b9325cbd488b3c76ae6e2a90ff03591500fc3e0391083ab640bbe8d439831c20529d7e50aa209c5c9c3fef4c4786ffa195722d7de4aed5ef4d914be37b6e66a6c3cd63ea1b031569c4c172117dca1569b98f245a331ee00cd386d5a2e49a69d47185cc74e30820a2dcac48ef6e53e9426f03bb43985a2876145bd3f277e71593e9b3b31e66ff0db51e39bd64c544657237ebff429925410eb444e6b11c7d98de1c92ec47760ef620a77ad4a57c31ef30b847b899c44820092815419910696dc573b4aa420a4901f77519fed92aa0f800a2537c87b3828b7ec3b1d2eb33324590bd1828a2a7c5ff7fed4953fe0a5cd9056095cfc7ed407e7df2c555707d461a058375cdd84a1935822f837c7cc1f5df3b43a7de0d4eda3bbc30ad0e7927ac713c15d5568d2044b8cd5b1ffc5f5a15683250c43b70a687f898e259cc800735cf525932dd925d288fae06072dd812de86608bbb3b82e0222020ed3e4324c75aef44cb3cb14b71546280bef72b4c341982a0a86e78f2a29a100ca9d3188992b0e43368dc88f73ae494d02895773b818424b7dcf633c07ae30c90eb9389f6d0d475f0c9422813764fef5a242c48a04f151a56e4dd0db8816be4801a5055e8f61f2b5f1a0ae3a2e008b679a8da0abc5cc1eb5f5552edf65eb78aba4c6c966e0b683dff0506b294583ac14f7eda8bac32b440cc97ef8143b1d76702853dee6792f859fb056069f3a780f013a7c1b994950be815b448a1aa8f5e2facc5a49d5b0e2e442a0ffde8b5837c05cdcb91eae0bb3dab8c827ca01cfbdbd00b0d094f73461fb89cf308129047004b679549f9eeb2e4c23ae7a59dc821ad0dffb2168b6000a0d759b9b31f39f5da37b728bb9638a7053d65897ed26a6096f7f41ab00e3af235b0156300eeb837ec8ac889b598acd35f2582dd26852a3f57e4f95a8aeb140e1b4d16056a1c9b6e3793b0f42936c55cf9088635b82db19ab9357401f2848292dc98c2e18bbe28d493a995a8c6e6ebe5bbb73f58dd37e28b54f58d1eb861e34fd60f256974e585f7a1366a415a0c1bd09fc62eb44fbab18b9f53576d34817f457c3203041fb41d13a64d4074fffd502c355cfa80391f9e11f376670be0712a8b551091b5ab37060ad205a38e9800fc963361e94b6ac19b81ebddea86dcfada726a5faf4db8d20919bc0aaa5aa89e04b2956ceeacdecf005678dd6d52e1ff45cf743693c9f86e0a0452595f47865cd3d16d13fa20bd13ba6de2cefebc226574aea3b25012475bc5e29eb764531f15897ef13c0c8bba924eb16eef9ad0be4c803155fbd69a0abb817bfc28632cc4c0ffcbbed51ae63b7cec7d2a8f5bfc306ccb50cdab998f8497229dd86962c94f82adb3a6cd55706507eca0c5f7acf584124bded87ccaa6f500d5c13376493136b05561e08dcfbbcae73f94b575e4ac8593a411ae58bfcea4e106b0e3c8c4e1004eae393c7a8fa88a881d243897e27095a0d13524700b0d72ad3751e49fa58eed561a93dbd5010cafa687b7358b89e13696cd8820b264bb94f03afa50d74f1faff45b056d34b6b4e9064553e798c724497d6271f6a100da9ea201c48e9393e129a0fffd22a85869dcf87c9eddaaedfeea8ce468a9e786c6273ca72dab34a18d3d1cbcfa05b25cba931f48a47fe266378efe9727191a393c0217b302987e6cbd973a04e24f7b03edbefa327599e932bb9c6046b1cae71fa4ab740a53186b9ef8c57493b60b805bea53e0fc14b34a699a1e08c53eca84429a7cdaca5ebe92cf92fb1d5e43ef96103193b7403310623e68b37987b45d05b7c845b1bd0e0cec4d855f68ac1b45c0f7bb403fa933c87f619dc29e3ab9f856ac159994240a795ed4ef91491200f8854236711dd823b6b9e52f6261e62ac9d392e2b3bf905015262ad1629e511c2174081811e7459f963d6dc97556f2ccd11e8acb95fecec99d6d752a9fbdd222dfca4a0e1e2c34b460b0a878b1b58b321a887c1b9816044a835dea243bd7934a35b940bfa8d974c722da2a1d2fdf943200d80dc5c17e93e90b2fb2c5d2021c280ab7e59326cb8b24aa99d3062941a47dd1b9e67c5a681a98d8c4f5c919fd047862fb30b69e624e7c53e9ed518e944c4eb5d1fa1f8426e8cfe03122a338ec7bc61b7d4533fc7ed8bd89faf8c81baf7de9dd6d0f46ab176ea33648dbcb7d4b964b486b259439b4ed1dad2f7fd6f95c06c673745aa06505f5be35add950cb9090f625747dc20183c5d31889592688f7ce184787ed77ec622f8336ec3e7c2f6c33ae064ff09dda6575c96cb64532e4e2d7f28e6244fa8c3201c1111631dc14181451601ef460d2737c79b0346fc73f10ed8aa919aee35fdc674b947156bd2949b6caf4cc667257eafc8a3d889b079c37ba8890b8ea14bf6890e60309a0e5bfd1b5b1b8553204c717b26a89cfbd59aa99136c2bd420c96f938f10dfa5a1ed8d619ec444e8d9725b08a3e4c4bfb71ac199c318cf1cd658b0d316132d8d2236111fc56580c0f7da5216b565e741cc8b799f5da90ad105146f4437e8a0145a8a553de5b3a8db826c3b598ecfeff142199ce555b01ab3c7e51f4d6928780656d8794b191b0b6d9f8e6089d1fb9312cb3d3662d53228d1a8509f456f8a395045210388ea066b18f65f2c958a07a1c94406e3316cf4aadbc6da3521aa76b33761b00934c7816a63b584df92ac417672f715f6d36bc154585dffaf515af5bc12286b28d8eb435ce45d132ef647595f81c2cddee13af6ee708fa83249d681e5eeefb0b140f2c58b984f1b6a3eeedb0bc8438fe6e1af80364037dd882a6991b4aadfffd2b8a9269c50d959c9de32e2ec3fe7ecd99280698221bf73816e82d918431e090e12ac6c65866381cc35cfeb7095578aae65ca0caff47f48d744cbfb6133a347a58eb23537521648dc3838987d08ef272c233b69553259102a68b3eb2dd6d98c31be862343dc14bd4f64296f7f0954ad61874c4acead9189e407a189ecef1d3963ed3829e94722c23b46f2acc1f0ed2d2cdac1b9bb51eaa25558bcffd1274e88b065660fe571d7956f1e95975cc57a163e1e157ed2cc5478a34c5b1889bfd91a05dc8102ca43393781773a1c4d26ea28607d3cb72397f54fde069e6e5653cc46a03e045566cd60a67ce0da8328e979ffffc2a0f7ab157fdf1c64ceaa0d1b0e2fb4d06027ebf26064b3342af12c669cc928a14c874ac3312fd31a7bdaa113fd0291d53ea374af4431f951e33188b17216588551efdf57da7617429ac8c6b147c24f1d91a517b12a098576cf8d41a4e8e976781590151875479169f0390e5be724b1e136689219ce81afa7a9805fa4c5f527e3edbcf45e25694391031862c2d6b8711d9ba3fe0dc7836e43c4972cab2b0a6038465d5e6370e7c66ba06a3994db37deebef7de1faf9a7ef8710faab31bd8ffee1a0ec6c108aaa4a220fe98b998b274707244c6a34a7545240b4d103ef778cd2091b63a6dc19298bdaf4e931fca2ee8e6f1687d218fa8e4c5717a419e76d4911c4d283cb4d4fe9b0a57d1e8fdeea10de8cc45931718d7b2e123c0bebb612a13fa77527e6769a6bb10c71d451e001f0596a6d682fae94a23e36a47ec3e55c29318d8811f7e736a3cc1e1c7709140e0b681d5b977dd3eff7dfa0c18e74306dcaec4276e9f6a5f254713573e16aef40e33195144efc32af99034dc8a069b2b5cda51489565c38cd56d639d31edb832d5aef348425f867f8c4ef9817bd0bbc6498e36e871979f7a301015c8323d82a3ef90d9e14886bfe8076f53068d239f89880a257766c13f631557f5d1eb8e2b78a95e65311277095d3057bf10d46bd1b709e1019032467331f8cc6a49acce6f261f50d2a201067f994005f04b9582e2d02b2ed6ce5131753191a19c81c07af768b00df8d12ac38f536a40dec12a51012bbc15aadc87acc3e64db45c5150f1e6681dc201ec8abfdee4f5360c2780c5e0179be90b4f585b396bceeb139289a347697ce88a800b5a7fc5139d28933f1dcabf8d64c30ff5c4f5251ef5177c0563afde0273bf4f7758d5ff0d81d21f6a9e531ea1a662581dd9d98bfda00ee955ec609b747d5dcd9924ed998cf870d973bd04dbf112d1a2ecd92bff315cb1d7b37de6289f6ad79360d3d65630b526e87052b7543b3780c4f393a7bb6186b275df4726b07dabc82037ad8dad52489922323883f2e249fc4e698bc07b735afe7eb5a9986a324964d628a399530238c8427d739a08621523579bf5b131146f631023fc87cde8d599280cbfac588487991e48e8ecd461446bd968805719bca5dd0b98f491b27fef6571b831183782aa10da8b92f9431f9818722341b804095c5d87c3fe5e831aad4b08b0cb0dde4d24c5de9ef09fbc86d696b88dd505e60fd3266919606b48218a5742d224a7cbd45d156e9192171142c25084e6f4a95e282813e91a73fd0584c185b5db1ea8dc20bc6f12a3e3220e496a03116ca34614698cf67c12bd9d96ee2d84557f9ca3487e8d7c1dba210abf8b67202370ab46c724c9fdb170197c8087ccc83fb2fa028e448f9ab111e80ee4a5fb68678126efaaa39c4baaca109a5efb75af28ef154a114be33b1a6af9c2681694f0a759c09941331b1a51f3c2a570a00c6456e75fc03d2aa37f1780d19cca47ea1e4f3b655303ab4e90e0396461fec6860f37612891eee6f0f8519c7ffbdd69c0e72f223a810f1744e8a19e6327f60cf19214e21ee2438e5c0386e155e644afd788e8218f44850964b24487aa304d47704828192cf0a9030694c3904f6c878c2cc638623026e90a4eb2a14f823893c6933f32375057f0df8950af3a2844177cd52d06315869bf088b883449182dff8c3a52c6d3d464ca86bdd0f256423f1f88ac613cbda33be35281316efa0397f2fa1e486400d2d54aff63b27352aa70c386c64cf91ed5aac00071e84fcc30250ebdd80dc3017708f6dbbbe62015052cc0091188a7b88180117325a655b41f02ec624258daf3069280da5e0c1339626eedeae5c3e87d470215aca51b498bc60635cd9569a88c7a4b5b7afbe2791e29fa3defc7a0c62908ff3bb2f9a34fc95b3ea42697a0039ace382befb5695c22afc9a365044aa0af392e3c206203fa21f9fc0812fe33c50e3d459bdc9f1e5d06bf0725702d9ce07746fe4ffe17f9abfdeb69ff821dd0c1fffcaa9d58c33ec339ede10acadc67a88b35be2ad6ba651b7d2be83a0c669e91079f1f678ea15d90c082b1e8030246f188250b53170eec8da2f364dfe3eb228a6a37f85fc410144cf275cbf70601e3e5ae2056e076745a603b88eeec486cfad35591afea8454c428e08040e281d05b880c9234f2f59614197b754b5b575ffa751303c990b2974a484aa6d70395e8185b2717d276b3baf91e9fd56f63ebc7ebfe8bb09ac224d58caddff39e79c129cd31addd699df9d5f73efaf1b53c45f33745623b9fe36e3ad02ad08367131e7f9e5267bddebbd3ab3e2914c210cb1dff4b3b0ab13c3137011a8758c231a121621fd5608c88713a8107a093f59b89759841f639f2357ff1c4a9707fb12bb09fda115f8b7e1aac1b21cb05ac0cd6695717ffb11f42c32d1323acfc26a42831cb20e9a9f8f573af8ecd394bfd8034abe6b0f71c06ebe41df2ff59b04e016b5b3fb39b76e5c57c5807a101da84f539c0f1a807d8a58b9f1295588a9c7c669f44c2ad601d88cc0638e9be03d645c09187fa03d4ecddd319fddb333a86bd14c243ed5c23799e39cc946bb8c2a764294c53ae263ffac935b8b06510862ebde36b20444f1ab9c0ecea55616f802f0ea416c98a0dc32c364eb4de35ee4479ddcdd06c6c6b0ea417291171ddf1176438dfe996233a723277228bad2e6736b7aac66c72b82d4f2c5efa7a22b742b401c6efbe28b6ca6d7c6cbbb5773d2e599f1ba0f13a6784fa838770eb38108d3994274e43200922ca935dd05ca2571ec4ac87541e43f2ed80a8c92f3a4747ad83af7e0f7f3ab1444e675b8e06e5d2020d919dd402201217a7754731c1288c7913bc0a2311d02310e5f54b5cf90781cb48a14395a7b9319812e496de7548810337d04edd588436f48eac34b7623d75eead662b7edcee37deaf56eeceb8a452d8418ecb7d9fa7553becf187343a0f9541e28a3b007ab50db8f18d7fd473628377221aa70583e8fd980f54488ad7b031f9df69cf16bddc61b4176d1eca6b74e86b7fb568c79b5740b8982dca8ebb5cb64c11da6d761fd2d56793982430f3228b214ecb2e5f4b8cf879bc13b944311f0031963802ec3e039a2036735920cc69950e45fdd1d5c3ba554b3aaa192c97008f30a8184747850effee18af06c087e97c7c8f77c722cf6055b07887030ea49f5d664abf6d0e31b153286459fde34f80c89e67a2f75f78f8431a595a42f6de5bee2da54c52062b07e806ea0636f3a9cde869e5dba39b3d47d95b52f61db9a3b6bd37c9a11b473ff4950ca0b6a3b2da68b4af365ad9c31ed56fb21dd597fd0b39fac435ec3a92f8eb25c81af97e8f4912f7bb9944761264dd25f258497c379c91fe42efe4d9fd6c04397b77bad8628b2db696868db089ada561236c628bdfb46f649ff6e6c6676d9bb4a7fd99b791491a913472c95af23e26857e46d2eddf39ae212444d63da286b9e937ba852a581059e3e4c8eae5e657ac86acac5c15ab66bd48a2a5f88df6a0144ffaa8dc4a00c87ae514d40700599f38053937ebd3c8ca3542bdbac2f2a4fa7ef32f9ed461eb5eee50da7977241f37eb386ada9fa6d1dbce3c2bd6ae596e5627ad11e9397b549f46525bd62d0bc49e7eb34e305878f2a4ef85ed452a9f8aadfd8ae55b4350b65ad91843b694daf5eb039d79c2d8be25cf1db5ed9f2db6d8628b2db6d8e29a553a6b38bf25bf771f679357a72c5d722352051bad9b8d46521b6d49bd55ec49f5c959a7906eda7e57ba8eaeac4f9ad4b7e1b4df2a58e5633f9f3cba5d734586f0d75a562e372bd725ef2009c16a7d52c1dcac7f03732ebff915bea9f00b8410e2c7a1f57874dbcbd98f509ad7819fc98f3c7f7f9e3f0ddd697f9fc9f37ef9cb5ffe7216bfd827fbf2f7b29898c52ff6c9befcbd2c26e6373fa5fc7df9c9d892f540f0fb0fc90ebcfd951d9c4dbb2b778b92068444bf1e69d6aa739d58c15751c2be2b291e84399babf40b17973dbe8923e3025858790869a6a6c8635bf2e68e36e15a57d0d9efad51c2ec49f55eeb49424ab362cd9b7ad573c1d6d3c6be5f411a3d529ae1313c6f63f2a9d97d5839c8b17443cd76003dba237dea665f14760c6d8f18404d04fc987941246df488e670cbc4b0ed003e19d44b1317ad41b7710983bab83f807d13b0ed57ad6128605ba07d3990c389479b40f760873bfc911deeb0cde13aed9c83cac8d83d2f750adca3bd2e5ae33ae515e6525f601c54a7293dea6e531c99a97d9a5932c4c11336449626595d611c1045081fcc38a9528203be72612a06d845fb729836c998b0fd3970f236c5918102924b61238b9dab1b9e703524a159543804016626082e455cf0122505170642ca28115226ac041a488481831526ca09b48cb113163103cf20051104083556aa4850f3011d4ac025668b1811b8805e5400af09362c31a1f3c67dd2c04d7164845049a9893351873e395ad2a57028036fd3f73c990d3ab030479bd814a743081d08430ca1699be2c668b1a0536c8a1b531592d1e3a6b831288843f4884d7163828465f46c531c569d2b2c375f169a20a0d0c94070583ac8bc70618171824583122c197e4ec0615181353400eb4993ac4dadc91c48483182d36349828204a7142f8c5084e409850c4c44203af2a4480622250c01c922c293e40411ab212e13424ee4da951a4e18b3cea24e0265a296afac50821235a51a9252aee1ae10912291751635130957d98a10268c18c245c2734d8c9359d659d44c50573558f10283922024b799152925404e42438e6826205341467e988e70013dc9a6b415a721b1ab9f2094884c2370c9d61409999ea662654600a3c098a2c2445dcb3714610a329573edcacef9459f8d3997e70edace9f75fe338bb9d42264f911e5ca39fde5475404b0379b784c46acbe24473a2561b996ab0431826b4a35242510e28070c7cbb53827dcacb3a89984f0611a02c48fe83eb34e03c554c2540e489892e4ac903015b9aa92528449c9935a563846a7d8b4cc1631312b5bacba235b9ec44ed027362db3c5c8123e5e122d9bf3d9d14169442d57e01a2d564f5aaa7861b43851a3458536595a92c4a6e8bc69192d2248d1429b96c912265bd3c1d1409b96c9028477248bd60f0d59c44465a9214f962be19e2c54baeef314603a3ca1528d82bfa497aeb22a757149daed76b574437b976eb79fdbedb694ebff073db5bf74957580372d28a98bac2b7501a47fc41fd1eb7ec69fefffe7e747ebff9fdb6d1c75fdff374dffa73fb29850eea72b08acd59a8d8123c4e1e077439795baa820497333e715c461dd657c6f0101368b9df3a9a2c4405871606d7a00eae2c3809bb5a662d76741805ddf825dbfa42e2a08863327aab5adb4af7e626e0babce5a72b33ee9369b4886b21ff1faac6637ab26a1a4f4f3238bfd5859a52e764c0c6356169e1069edbaff3e1c6335be5aa27e5557fd357560d9e1fc4bf623efd7d0443511b3d1b43b13310d52fc2d8b707071717165ac2f3390cc1f758bdc43ab8b8d56179b375b5b5a5d6cdedc704141015c50500030b59a0b4a41171caa15c54b730f1b794ba7a9d5946a34a2991876ab7df3431d1c637660d3c30f366eb5b51309a9450d0685e115e0605e4acd1f2180838b0b0238b8b8b870a499000e08e0e0e2e27a318c4624de6a71a499000e08d0181bfaa68ed57a048a129fb7980aeb0fd5f11caa43344cbfd02b240a7628fb91c9646fc210286b7d7fdcdddddddd699ed459db59da794c1ce144571b7aa35b506806a119aabbbbbbe79de3f1b336afbbbb678f5aabc79acd7a747777cf5ef6acbb7bdeee1e242bed54b7178b5e0ee01530b10c08453e2ba9504b8823b92a0cd45a93c4abf2f5696d89d061b1ca5a6048c0563cad2d215c2b2e7b44b39693a82b4e5a2914c9f2a4153504cb97d6930c60e4a6656ac01a52f3b55bd3af75ce601a2e2d33badcd03bbb4659e9eae42583d269d688436252ace49ebedc15fd0037524d7aa082cb43c656b9e060020e688884b161c488dc913d82b6478c18f1423721a1165be885848484fecd3565d65c2720202020a01e9a6ca01e88d840406f7a12c5a9d9b281d204b1815ec76a00d56e677e66fb9ced9f9fcf77f64f1a313c4c8da213146884c897088726b6ef97ae3b99052e8f1a2aed7946fb24da9ed1f6bcd771b6d7d5852bcca34923031c1272bacb193d1ae90c983c6b32fefda17466002333336e0470266a9ccdec931564f666992961fbe39cdd4d7b47cadd5de88ba63b5bfbb46d5b6cc9d9f6afddc1866d77c8b3edbf69ffc66ad89a94099ff517fb2422715f5b5cb63fc585d9fefeb3595312254068b9e91056041dac1f9ca881f2c2c3858dcd823c98773495cc16f5ebac087742193edbc5279d53103ab6298ffc31f12b95e14967f4699d76b54e27907572a72f03dda88b2a7bfbd603fb99c83e1286461dfd3dfebaf509ec5b27fbf5768b3d8dd5b8ef79dfd3afbcd9cb5ef6b297fb02e30acbbabad11bbda25942de07790fe401e5a02c94958032500eca9e5010b9643dfc37fcee660f7bff89a5076a78a5d700fdcb10f879833567adc7f1dfe985a2e8ff9bc91e3c6e19a366bedfa80beb5dc262789dda1bd3d97c572e6997df3a790cfa66cac9c9c983283be54952b49cb6b5b6c9b6d6cab6d66adbec793d3c09e73c13faec3df8398600efc10eb8691f298b879b76665fc87e1049da9b49f03d1074bfb987f5468f6c8c18b59a69fe8fa3d6b6de62a796fd39be683bcf3ad923fb598fe38be55953b24e396b3d8effa7592b4fcfaffc8b9bf6a9574e95d8d6063db154d60906149d94c63ed007f5f0243088acd923f081486abdcfdef7790f020f5fd209d077c0c6002a3d6f1e9ee43737ad7d0b65df4ad9a7ce49c59af03ea5d158c65fc14dd3af9fbffa5fd97d06492537fd491edd1ef24aa43da3d3feef6ffaeb1157c045d3afb15b5e609ffe57dd48486927cd123f7cfa35dbef3ebbbdf75e2f753803bcbbd67ef6db7de8a48d2d805a7b99dcac346cf878d22ffa329148ef96c66e5943a36d698386124dffa45f3aa9d02fa6310d3c1ddedf5a9e9ebde46dd15520ffd1bd2aa4344a8d481fb908336ec26ce6d3481fe010616c4626e9e3c70a322dd802f054f4d460a3bd11e9e387680bc0fbf8a1cfd800f03f663dd868250ce0eb161bbfb6f6eaefc80e7eeca0a020124ffe92ff2ff954bd02d002454d559f2b31e081f142159c0860e4b481a29be84f7cd15bbb73fa74294932a0afef56ac7014fda4f429376d3ee8d3a3768522fa9ae2ebcbba32c49ffdec673f18508c4a5af92886dec9a1d0f1f5a7b12126bafd31a0dbcb086415bd934545b71d357b4677a132f28f5dae0546a38e2e7aefb7767d15a563b969d62f4b92f42f24759306989ebdd017bd97622477d4f690f56cac86e745451f82e56c8b68cefbfb431e8d1cf2eeaf7893eb96430b303232cb217f16bfe28d4a67519666bedad7e2375af1464f339ff60e58519a256dc7d881dde3bee326b33dfa9e467eb996f4b6cb1204ddf65247f926ca37b13b9a5377bfebc0b34eebbc0a059575b52bd71dc796cb93ce0ab62b886657a75de06d7f3176c358e8644d93138dc81744b060edf5babbbf75cbfde6312811372727270fe26425d9a763391799b07dba97dfd91eb6abb5d6734cf4c822135fbe254b1547ffe387dd671b83f646bf01ed8d86ec9bdaa8f431644b0f6c60f466e9c3a86400b529d1ca7c59fca9442b6148f1d4b6e24f73570dac0ef79ab62d7afb63397e0a52477ebd97ec48aa7815cf628593a7b71d95487e647fc98b9ec65494b5923ce92df62479d2588da2176335c2f7c8a22fc9d89b204f1edd0e3fd68d3b464c345a6badb5d612151515ed1877d15734f4283840c103efdba178efc0c71e3af1267ec9efd0d7580d143f43ff13d360e8c7efaaa07df9bf6d499667fe3245798e1b7b493b6fec53f63a76d4b689ef4810d43db4876a5974d113d5a13fbd97fd890f8b486741333257ac30ad2d7aa2efc8d3bf28a4310c8aca33efa2bfdf91a775da5d1657ee0b2c2c0cec2bc795e553fe84caea767575b3a2f2273e0516e64efee4501bbb943fb95318d8ed2a8b2bf7f595e3cababa55a82a55a7ea132a2b2b2a6b2d0bfc4f2b4ca3da56da260bf3a66474ea71b3c0e5d93dd1b358419aa491ec976c11497717e659b277b2036f03b58dcbf3c6aeb11a443b6afb44114937dd4427749c288732886d131fdb26de44b981dad621fb1bbbfb1cf6a87e930dafe0c01ed51bf6a87e07df3380da8c7e45e9c307933daadf643bcd8df18a3ff5f65890be82463bfa0890d13451684ea8ec746129210e0e36ecf06466052c261001e287fa42cd1777b6f33caf0a459ce93d4048d9a1238412344cb2006962431f3557f4c8f101496946c5ca3366fb2dcf97283cb07fb997e7fccbbf56b0e23a4fc4d9270f8c3d8c3ddc7918d617f82b3924b56b79e2abfe5bf7ec18d75c3de96f0b21bdda5b4d762d79acc8f4daf0f3cd9fcb5c9239db286c2600374b4921814222f5e1bff7621d1767b2628c699a7dee103389330573063ffc34763f2f67f2ac395cbd72c6345809b1e0b90d82975e6c6f393f8d792197fa82bef798b4339c9596d6ca72a92ff07b745f4c7a37ea799babc63a0ce87651d44eac6c1eb77ed55ca5aa5f19534ae9634a29a5945660479fe348f434b3450d4969c60cf7ca44d612113dcd6c5143529a61698d65509dacb8c29f93c7dd5d57e3c7f6a4debb25ad2fba3f6fd40955427d11c6a0b61edd9572d39bbaefdcbf5e30177099215600a6cf9925b22506d4a47768db115aa7925265830363bc43dc98562f376957bd706d8371cde1a86d30f6aa5e5ec54baa57161ca5194b3466386a9b1ac86cff7cd3e7ffdfc230a4b19a739392766bcc93cd62d32d3161bbc7ae356cb251f5d64ba32efd90c6146091d417f4fdc9fa3d6c148d6590b757d2469167d3fd4bd65b2713cddc1cdfe893e89c6dbfb181279d3b68b3f1d27d49b146664dad24dda1a8ddb479d1e7bb7ff1f4ec70ce0e5dbce488aebbc3ce637688bdecb0132f1962d9a1275e92c40a3bcce225df8e07bb8e17f8b32d49714208b151806a72b3790947aca86c92345f5f3627e99735540b8a859bad02d153e729089d3352b61b930fc06ca1273a4944e40713e0a9b2fd20f165f3ba4c3f3e383a57362789b4d87e78adb790526de1bea88b90688acd964db4cf0c3250d9aa2d9bcc9cd32f51725b57431bd8c78f4b1f48736cb66cb220e8f9f264b324bd61888dc804db257d781b243b50d97edc32586cd429e8da7cfd907989b3ebfff889ca7977a2d44a1f5d9e32555eb0f9f8f153848d3a053e7ec882d4ffe105c9c1469d8293de7ebce6d82e39b4812d6b383a5efbbc4474806cffacc10bdaf07fb8f4f1c3e641ba7c0066b364d1171b7e8293c3859bf384fbe1697f2738b5d79d4d715e5e38af34b50261fdad4ae55e50b67e5df3143f29cf30c3765afd40bb597d70dabe69168efbebadfd3e0d376b69c3cd4adf8627e1ce4647d2a076fb33751fb3d144e3688b2dce16fb688795ba1b6db73530b0650d5bc3d2f842a3a6f466b735dbeedb072741e0db9d9c4694a02eaac7bc1c6147583ba32eeacf76fd9ad29b36082febf38e5ccec86a55617cd1e7cc73d8fc1543d3acefc03c1daa0575d3f7ae3c89d6fbfe4f6e2a833e65d95eadbc880522687f4ae943550fa9e3d888f110702fb420ee4b29a5fef6de1b8556ef9ee2aea4f9917f1d4b195ac4b4ae71c8c4a8a83c333498b9e1bb3293064ff132edf3706cbc0c01838a4d716c98b091ea72fad93e7e17a3dc948a6150f77d5ade6b976ccee393204b80f9a03db6d51ba0605b87f7e1cf8797fc294f0a16fb38606e3a94ad20968015a94dcbe891b26b939c3e1dca00fe4319d40735a87bf675cfa81005d25fbfaa05691c2ae84fedef50d65f28838f633540d1267b4a654f6992ec67e4ddfeae4209a3053dfed0cf535b8987122acf1c549e1ac8a14a9023d0190dc43ebf7d5ffc8ea45406f8eebd8c3cc518793641ed1d22e9814a9e55cadb6099a90bef97dc9ba134469f0ef5e551604bbcbe7c28413522c2880feb1775e17fd62f25252a4396e5022cba2a61d14a0ea59405aa830a4a32e5838a71326589ed476c4b9626b6123f923e422ddb8fd91d5b8912860b4305a75d35c03a86cc16660dc9a76c8c31862621e45c9822a78dcddf9fd8184243b49828b9253121059bbf43b91409f23eb941e8d3a13094900305019f669072216a06215f1d3c276c81e3a5d06dfc7f6d97cdf2ecdebe4852dbeda8c56a58f76a1a8c7861871772473d19c54cc20e4506893e1013a1c8e07f1fc61f06bf0fc49928671422febe0f9ff802fc1e8ed5b0357b7342183bfc2177f8e301bc77d4dc6bb5967aa1ed3a4c2d767777a7744b7177f7ea79e7755e672dbe165ff72cf63aafb316db7baf872dbe960be7eebb7256d68093f312755133184aa9bbddeed6da3b6a7b14626b65dd628b6fa5a3b647d67ed7f3bd17dfebfbbad979b11ad7da7b3faf0449f762ea6256c5de5b39d8f7de7befbdd45a6f058cef576fedbecb5f87f165010b634b86a9ded55ac36030c46016be6152b8ddc518bff83e6e0f638cafefeededb61a5d80526a058f8ee9b5b98a1a5187796f6ee0f5a90ded8c04d5bda20eac62eb7208467f72ccec066882c97cb13fe909bc324d7c6e676188149cb97f51c16915a53aa2129d57055439687696f535c0ecc999be7819d579585cac041a26f415d477e64b002c2014a76d365b0208959c9fa11656596a01062998a9521c148f87158add91e557c5f04f85ad237c5d75a4b44299dd15de9bd53420ae4b553e1951f58452fe6853786bdeecdda8865fa6a6bf1f5ca9b923da2232c11c616db19d61f9009a020214c3413e9bd2348688b3116836455b8566b6d77bd9befcdde78adb523b694fce28b31c6175b6b2dc6b8daab433d1dc664eec5f7de0c7e93310118b726f8ca60b258a78a94761da6b1912ad56a39f068cb2e879fed556a41138ac1341b81a80518a82f62a4486ab2033bdce4e118a8166880bef0fff8e8a02ebceb300e039a00b20069e918667ed572e09d634707ba1c6095ce35ebf17a16bd41884a509448e5c4ec9729b32fd1afaa5cf570870e9fabad3bb6b35251a00998204c96c490e6832036ec18e5fa3ae3054f940ef7643d660bc854d5da02c106364efb5efc41572e1aa185a829dd55dad772b6f540cc1e6bd68e5530acea3acab9e2bd5b5fc0f6f5f6bdf75e2d5a57d865b67fb6b3fd5d0b218345cd095b6e18f2e6e6d1424344ca852646b8d8ee7d0e986c8c3a755fc993c039fb6e75c9ed7ba3c634b69ee2ac88aeae13546ddf72f2603b958724cc4f6943e0f7f4d27befbd4f6b2800047557273769d2109d2f9e11cd3c0924f38b9e7441d093ccbff7f7b53953fa5f455a69a520054d7f30d7bccf5f6317640fcc48370d481df913cb5afebe0349ef7b5cec1bd096682a4b5778375bdde6be680e7c0fd7278c023ddafd864792209300860df27b4f82af84e1d46000bb037cf68ed9bebf01ec8404da1e95a02d0264bef235f8de9f1f81acfadf90fd1cf6c8fb0dc0f2b6c1572e5905dcb72500b4680f2ae79155850c25e5057d56a8f392b01dc78d4d833e698e83b7f5c993aad4dbb2427d0534e8b342f570da157bb672335b6b7f44aa593b8e395b6b62535bddebbdf78e39b6fd4b2ee5d175ccf7de7bb59b14a3e065cfcbddc5e2178a26c45ad3e308fe077e5ff69e80b9168715cba9b11ade8761adb5d66e1ca98cebd94b6588218c4d4f323411037348e6300cc30c7ee4ceb55e990886e55937f895d74d5b4b52bbf95ab1e22f2e26cbd3162857f208395508828362052b9755045b310105ceca15516625481089bb42369b44d8d30697e5862651bef61b287b4ca0a10d14af3e5ffa6431338e444f1b9fe8a74ace55d123d6c9d993828a49f979aad224579192d77405e1e10b0f40e0ac00f406082b291831534454152b5f151a8aac0f6cb604b1424586134aa852b1e44a941b3442725ec02a684ad8abfcd5a7499f237942ac31be18e3f25320b99acf94d6ec91100f30e8ebeeeea69b540e953026e6a7e1d36cbbb9470e3106ad8b64b5c9c84a8f301007806875d9d954a9797f04db71d739e85786f0535470671c732edfcb58abdbedc665062eb79b1b9ad9c2b4565c6e57be686b5a9ac31ed151ebabae3c95ca7a63dfef61c3c26e0e1ba34e4dd1504609642cd127ad407a7852a54ca80c3adbb6643ae9d573f0dec29781a90fd8ac49218d1d2b3f80a91a322667e68c112db1aa3002b038542101ac7242c84111ac5b9511ae84a035442ec80b579c3061a2a76a885cd527e86ac98d3ff6f160e7afaeea49feca94e05699a02baba8c0294588dd49bdc2e8954884cf1e100d163dc7f6f91252979868e0fab411a26d887ad47dd0e84e851d53badc78e962678b8b4898224cec10b142551b2a2d8ca0a24504e550f9e1abf22014aa2a82ab8ec4e89d1eb6bcf96107189c64d9010a1339568a7c01e2ca0d1f153224c03896e6443e70301f3a7cd454d9fba7b5d6924a6e76a5fea13517521a95e105a0f623a93483deb0e5a594d6ba1bd9fe8d8e92b45e17e880544e10f5c8a46cce8bb25486c4b8c8966830d990e101da14c7478b78c40383781346a2f1a37203c20183f8e0ec9372a59873f594450a081e34b131c14192439faaac21776c425011a24a580c7b8018b19df48a005a36cc497202217b6eb693667d5d7ca86cff9c1b7fe4e3c23ec7ac0c4797403f85754a2b050285cae303242b0aec2b434410611d1719162a2ca00e5f3be3a68447569d8436c5f111d3e109e11a19f2c037336e61066e757cb85ac1ebc916dba9bb3cf04deed56cf122439d2e50e0889be28818a3554b8c1e113440391151b54fd1635cda4c8b549ce1c216f5a638224a28f2f3c3579698303870a61030031a306e52d8810a991fa6d0f9f13463c03332d1238248470409611177b24efde5ce6b614f1ea418daee9943c44715f44cafa95d423a7cad1eb3f4a8b968253525a42626543edcd00311255d301c69c207873e47aa58e93285ea9b9245067e7989ca7553c27433f6586d8f7261076d8adb1355a58b2174d2c3270b874709d59d183aa82e3f4350d6a94f8e4e1120df07578e8c0a170646851b020e14ae4e1cdc105b722e4e8f5308cea020e58549102d521260030f778838e1852e3b43280c499df81a42e1c4d7d0d4d094df7137eee539cfddf13b5e96a78377e5e9e05d79595ed67f77bbfff7bcefc357f8067cc337e01bbec257dd5388e4799fe7215d3dc96000f505ae6d8c07f0d65e4b7fde494c7b20b9e9d6adcdd79b72c5403481504396992c28f4f1b243e3742d81c24212382ce00102496946753852c4992e03c5046388b489e186d5a485ca107284908345c70737356fed53a90b979237392c01b341ab098b1014eed8b1020303449f9ba804ee57252d5433250000400003160000181008860322814828c88355b60f14800e659240705830990723490ec3288a612008628c2144110290410619a78cc80089a08ec5ecc6b50385a3c7e16e4b3ac6204e4a70c7a11677d0573c1d8a1fb9c3c5db8b438f1dd72db27e029b555bd268142bce3a86328ce7afa00c4652cc0cd28c2b23847e7cd3ce6a9538071026677883348d752e7c759c9445719078e2d32f2fb21e8633114698b1ed628857f92246930e081a23a2f8a4a806b40ed590427e4135070ebf65a16d95b4e88e215aee3e2b8485601f12ab2070a94333e04aa3fb50278af5d30fca14332ded896a20ea2c817f6b59a3e1962b263ece7380f7b61b221d3ac33b6f2f37e354a9ed3775b71939f1a6900c7ffcf1f901737a33eb50131a1d56e7c57c6d78e9ab385ab7f041afb48aeb60b5dbaaa179017da34a96e0951b09a5734a35bcf429f7ab5afeb5aa9e4ca828785987c2c41a2245e82d466af3eb00fb8b7d1ae490f46b54acda3e37a48e40ca4e17dc79803e58ec9ce5ef20e16ed5fabd530e8f306346c3a702f929faa0dd2b81c84771cb65b14ad1fb8a7ede6ebcae008a10c6ff2993adf0fb0d7853c33a26078232ca04d408fae31d738f0caa4385b99d5353021b6101c1f90d4713da3c1590c3606d208d077ec80adb16cf17f39f02d8cc73c6ea6cc774167d4000585d0fd709f74a830b0f9ef65609016e02447369671c29f3e447de225d75e96bac7dffc8899aec6f4231e7fe6d66297715a7a38a16f9d9fa4bd8d667a7b7f08174806fdf626cb5fceacee6fe4a44703681dd1d4e651c2f3ee065bbe63f34857f7356f54dcb3ad0a7382e957d3ee43cc6b271acf67d353df1a95e96b595c5e84062c9ee37a175c0a4929afdb7d7e3a1a41b672270d0fd31354238a0e40f0eb32937d6c9ab140f6b1b043724b406bcd11b821d4942699e0a4b918cad76d35dad72cb5b690ceebcc2a25843ed933092fc3e8db74f0b0c3755dd458957a50947e06cb60899d2a3ef0ff9870b02cc34d48a75df8765d82463d30648f9db7be5b54bcdfd6acd84bb457ce407b321cba67c61519de667af293181bad26d8a38f9e36eeaa4c3289f4ca65c4abd318d1993b5e4751ff04254a9b64772bee43591b9b6913009d8c7b7d25b22017fc0c3720a480897a087c0b1483690ca124cc6cfc0b93704665b05fa216ea54fd485bfdd2998e520c70f4839732d3021bef567d27bb16f1e1a2745633da6d83910cb89fc5596800f90091ea1f20117e4db6a440f2db3a1d739e2cfc3900ecffade1c3987f2536af13abedb35614b542fd03b5a3d34ff6c0070d7201280b5e9a8950bea63038754f261b96c10db7914694dfc57ce128c55b62c79b6b28ebdb8d90dc0668d7d986dca71dd84a2dac2190a298e1a59513d329fd5db60d2de4e7546becbb2cd95e523aa740c0129868fac77806c8d42fd7d5e8fc1900fd147c5c2dbdaa904a8e6b87cb0de53491870cd9b839592a045ba39db0d450d809530dc8d13f24152305c304b3c6561021b0215927081c8f3e022aed9c0cdd81e731258fab0055dccfb087eb3eb6ef68b7793f549604c2c18193d768326bf4b3076b458e440b266a64ef41598a0881d596bdd06f9299e167872ff78e0bc71b4ff268c74af96d12bc1c7d108f7a1a8fce072fc973fe73124e6d8ccde52a17b4198d4114883a402eddcc61c8dfea379932a38a454305ede6b11f51b2da45b43d859a6fa92394aa0c43c4f6cdec0c435c8d47258da03ffae05f42174269856b0cafcec121aa39dcad8253f7b26452c506fd3486e407c3020950da996936642458810f8596f6ff1c6b33abfe32ad210d50e01b0a1e2ad968f582e968c633183a432d00d2654d7ce4c62f3ab1f9cefe4274888f9dfca91e99016ebed06875ddec596a9100c87520edebe3cb89bfc3a5e43c3b396f12ae7b02398a7c540baf676cd24f07c2c4721fb40e8aafe9c3f467d71c3ed8b846b89d1460077beee7f92f5b0c5bca01483900fd02610af140771e4cb56e1d10a522aae162860018eb6a83329d42a2f3908a4d34a10a94a2b2717c99b352bd7ae879decb7f204199651e82d99e7c51451c26334c0bb1208e5b7626406f891c05b553ccfa9ba4b016b17a360fac22a4650bf36e8e3de532292f840e74495d6ff2881859d0645907c6a1c592710d631b733ac234c64e40fe7e78057407afc69cb2f2040f99cdc466e341af00bba42a30bf7510035a02292c66534e0f1f55064ee93f95efe6d5050264365cc033097bd1c61e1e5615c4786307d7ed1c2dc507520c80844b74c2e19696db3edd5415300f98c5e163bc30584b144e80fff39cbbb35d45d51cd97dbab17e65ac88c60cc5150100b7a6be68d26c9b018789e13157292aecdc6933e8c61aecc0cdccb02815e73a098a3929b570c97071380124e008f0931100a85914423aa0b5b40960823b06f5b922aa309ca69a8687f550b1119d9d10f31fa73938a80d3d54a3f47961242c7be3ea392da81efda3ac46d8f859c164db19f8a26077e2102b2794317a3c9d5737fd5506633352f6e801247c36fca19fd1296453a81b9c71b661e7850dcc74f2e337be8a169c7fda4b13f2dd9db5c94d3c778b8df4996617eb1908e2c1e028e44a3514b834c83ebca41aeda3b817f62dd6633b1d85954870eb31fbe33aa1aa18a57b42597282a348bb5cce3409d4aa974e827e07dca299408d2962e7da59e870d9e8030a6ac28ca0750a303408d75265f43d220d96031bdd127c324546e4183a0ac3d494b0bc014ac149fca2a2e72c305534c0d8a36e42763d905367087384b7a6b68839944a0a5f3cebe2df83aa1fed908e1924e9cde9f77868122902b2802041d94fdaa2040cdfbe2297dbbe868d21169b4c357ed67d3a5c5d2724d7a75d3a0a917cef126a6a9c93f25633b5d9795736bd0a746820a2f0e976cc9a63ab12a594ceb0a5d23fff954847aabd02fcc066956c888be2b8a1ab5e86edd97fa5b8aea1b956c744eb57340b412c84742456cc8656abdebd5abc13f873b800f1f4f162e8bfaa840385d2f8e2f5bbb8d7d03310501a03e254ca5e3316c400eae29aa8ada6b6b1fd159753ee2fb16e905e6d1d33cdb18d36f7ed0158733a40d5649c2015f48abab8dfe380d9ce769e87a6a2009b97c343bb70da5e79f2c99b9a074351217d20b8473282cc84973563dab26f77ea5483e3d994caebb1f40e639dc16ad8f989be0475c7ae8b3987ac71895bebb7343a8ed83e4fd8aab779368fb5315256cf2fbc5b75e22c8ffeff59088aaa7db2ba250e985005034ca137c589e3f201b0c88d00ba9565e721322916bd0c454eba014c92f77e31decc0abb7177cc9f88d08b72d3f00373daa77341f5d35e7b2cd3efa44aad9f644df66d33f7eb7886d16e3b4193a3e8e7a405714fc8c04c34fc06440ae30b8aedeac72b2a257ec12cb0bbefb3eac04267e5a0b68cbdea7a79dfbe511adc12fdcffe0cf7b3817b25b9099fff48cae5beb1d504bda7ff12ed8824609957a25bef3d77b2a0ae642baac5bd8e4ba921420a24503d8967b223101f479449ba42d0ca345bc954d61ac3727d2a7688d0fcf736c41809ac6307370546212ca274f1ced59cd3ed4a1dda9a047d129084b453b1f7cece4e551878f507e61091cdfc9363b7443362de12927036dddefef31fbba5546d90d38ea361a32e812b9f07f5ced69787bf51848833301044f96e29adcb21556e1d02b57997bf99cb4e2e81a89cfb9f2d40b4e429f68d85ee45307c12128cb7a45cf0dba46b024128b010976b2fbdf90c378e1d075ee17af4a253011837dd73cfbc62377f2ee58cd143e256158050c62358a5c0e24a53f83527366d152888bbd2ad25e9efb8fe1c47ba01c5f38bc56739f3fc8e7e23ee3f06a2c2089f29526df8e000f0cd6778963de711efe3652dfd5da5c90f60953270ec6134374a348ac672036517d632f991500ecc61cbb65c5f6db9eec1ba32876a45da5bc408eb9b15738693fb5ef0b42e846241148e26d72314a32b237191d6f6bf721da1f976bc62e8dfe92b004d1cac8d93e426143cfbca78440be1fcbd9780f9c3b160addb1b9ebdf254def8e263b0c68b20c90750e4d2ed80a482e88c714566ce7de511e8653cd740827fef7d7939b6ca45e072609f31e4ea09a873a0de4162a4825046a239806586cc467127cd737208b4db04aa6a27863f9715b4c4f81c516998dbff19c39b50e366c5f3b8a21a6cf2c26554641262dd18b3773e1ea45ce0310deacdaf832a1f106b2ccb51cc99a3bfad6ec519171a3d09cc630ae1e9b5e300d1ef6e29f0480dd4dbc0e931907f2afc97711ca10c92ddc1b743d85fd1aa656c1318074351926133e5e07c557c0ef705603754920a88f5923ec1da80fab069fd7d374178672c1e4bd095c95eb6fa50fe388edf2bb4f7c3f32a47454af2d569e78db0680a08c5432d49548835ba071e08d4176c43bed85cdafee5e5f72c92bda638e6a9ecd7d48b3c707ee8882bcda7d49ee988dc87ac3f519ff5cbd292d9d1505579b7ea139b1065a6f38f00f57ebef5c36bb22afcdcaf91c43942f35bc781ba50736b327110e3b15d5a4f76e48d55d27db93704280c9254a8c55dc0e63328febee9d7bc6f724dc2002fcdd10fb6cc24126fcab96f8c8762289616e0a9abb3585b257b8b3c9ba485414c6efb86b1920d4f2f66bb841ee069ea813150bf9b460c4e864fae0c772421c2ec807b38b050c2a1972b93c5b6f5eaec7faf37daa371d4f6402689a36759569bb1b88e55580d99350addaa702ed763a0bf5d9b684cd8cf697176b4cda8ddfb395d862a70a75efdef19aa87859448d22642e2f8ea42881bfd1d7b0ec9457972208d4da25b0450c7afc4111593541a6296fc2929ebfeaf52a81c61bcf0bfbfd4a0d8bbd399d86abe19f33aa5ed089a9d733476d7c16c9f4656a89edb63487bb56bbdeb5ca67ae2b9aa1a852444704f2a2f6abe92e6aa8a87fc434b4ded6ad467805a397910a3ba78102cb6969552fc670fe15b28b8b8f11dcebc8250dcef90c532b22ad9811e83d80d1c1ca62ac7ffdfd1f3d8a97f9816b3977e054081103d2eec4e98d55a6f03f9ea6b23a51eca0fb3213ba9fd3cf91a19b5889c45049ded2f2a4d166441bc4abe8c7ffd39e3d125aa4846e88db2509c3f36e17377336cfe12d3db0644478f3781d8524018920aee3bd47ddea14092bf962bb2175e24a0522b248648d4146bb82da8990d8c85136d533f116811a6797fcc459080370b3c61d58d9d42cad5bf9011df0a09f7f5041562c4c1c1e24f2e47d23ddd65b54a14cda9effdf7f382ae6b75ff88cb1e6d4e6a0a47d7c3755677a139277a0c17cd03aefce315248b03cefacb0b5274488d69f85b591779ef2d11124716bd141a2f4e4159ababd6f46e500ce4c055d492110b274fa1f37196bfed29b8e32829a05222df63d3133258f357843802ae8c103325b01525285f0b5f452a6580d710837ec9810c3abe26ab37eb02fedfbd9f13be96c23f0a12329e3086fb0b4992bd6dc5992a6b9b94f5666c3885efef916eff9e344e8e272ff8da96c3aac51babb10845c3a0eaf8083a352af1a1eaf61a8ba62512bdccd5b3c9ea7bf232b1524030466c39a792835b4233b9697dcd3760e84dec8fd008a9c87936e6d0ab2719aa96afea555cda4e2c7a2229e935dec3c0af2219951b8d5d19408232296925c7340482c9018a74cd576bcd69e962e6ae764bff3158ddd0ae65ea35410f8c5210973d15925d78a757bc599ceaf2755feaf1d0297ca154cebb8a8083dc68f6585ea8bf273e9ec654f6a1b6f7706e9ed495873743c6982b80192e4929307d27f6ca358c33ca1339fee1f25f4eaff5bbe0f9c3caa9f7d63d0be8bf466d0f9e7fe57cc5f04335321a1b0fbc3e5736225b489642e59a9fbfffc2182a07119f4ff0d3aa563a12840e03055fe64e28a39a013368f69dcef30f1480178db2065af7534e25d8e12c8ed138850acbb3d0007811d2b8ff66424079ba3e51a5b04c763b7747dce1a8b7deeb936e10d07c84054861ed3a7bdcea0e17a85dd14fdbbe8a34fe0853e895d6e682191ac3cda49798ca184c2e664561f13123faababb60e424a39b3726b82fa094741bbaf452909fd8add1c7212c6360e660b5eb91a6ef31abfb477909ac68dff3e9889533f4c9c2d5ca066625b0d9e094a4eb1c88bde393ab0cff0d4fd13451ceff07c4068a0b514b95013747aafee8593e20308688f52c71d93aabdd9324096dbea50ab28da40e38628f7194a615dcf415feaa5efde18ade536aed37241f55800aa5f2d748d36721c5de6b6f5888f67b7da7d99b7bda2b1fe124ad6366916c8c618d86cd8f679354b0c57b863f3ed25a08c1714bbf4fae4e251106a6943e878994a8812abb1a4d7fea6cb49fb73a62ad74d186520266f21670159e639f37e60cf665c99c9341612b85a3a171dd976abcf843e06063a665d44527320f0e794ea9ae38f1ba04328b30295168e3911a95efb4cd2c8cd89bcc0e5c1184dea20d7591bf94fd1338da68a95ef06c29b1d7b274254432567c017bb128dc90d65cc909f69488b1abc3026e826dd186c57cf550b83d8e68c356c351b8763498a0da2cbf570fd57839adeb45029da80838031c6a3b8c6dfac3f4928e7aeaed54ed51ec657ffd4d26c65722316699168e1be546a7f84e03ed1724abd494b957ef5ca853c9516e7416fe59a85642c207bcbfb7ab5631b161ac822084a122edbd05ab5c5879a2a7e522d971fbd09b22c927e45ab27c84f859fe5630245abd22c2c564181065246735e70ec85357e5242d74ff517091aca58cc7acabfdbe98055ad480a9e9d69df6c7213031a47550fd4ee829f0874e807dabdcc4fef881549b4f71764e144a672e0080ef2fd3e21ae7a6d54280888ef895cea07b48ecf87af5af0695e25f087b50720edce651d45f58aaa49ffada596298c4d54efab40e2e7719ee4a0ba18f5e2790e5e0fc2f56f1d4f3cfeba5a4680829f727b9e7b8ce40c6d59ed2899d25fd6e323a21f90f80ece45b1d5c61a513fc3f747e9d033762a1f76542810c88ff4f064156f72eb4fa8146b1d71f45712d8860dfb8c3afce5257d5e6141dc65fa0c0c89a0326b79d1c62802ea2ce02fd005103f8648602104a0511a32c4ba3083f37a3b72839f4eac73646c3d1a58e02f4075243fa4a2c214898cde977aea283f033344a1f2fcab724db18008926eb58007520b5485fc552089224ab5453b4fc8d22bcdc19b96de28057af0d4c7f4386b4db18a8f84457fbae255f61a93e11eddee4ace560e3d67493d3649bc3be884ec38155b52e2808d3e300a9184230fb5006a25204dac662ab5d06ccf9014453fe6739088f331ed94374eb598afa5ffddb898d0aec1080ed85a389296a20b5691d6a8d9e225a354d8d062b9a7b982d148c6b588d1340cb4851a505c9019acdd14aca3c4c48ec030de5a39ac8afd652f031f85b5332b9344b565a3be765dc29e45f47d68a86ab6f1411925b420c818fc21cee1dbd9a7558b98459b6b91da68fb922b10b82940fcb47e16bdfd708c7f10290b6222789b00fe0e70610dd83b9fd76721389833bf02b187cc0b0f661f2a205ac6e6cc4c882db0d208fcaf415e4c6c5e1b96b7d19a5349e7aa9e96908b54a147c8b26d2e6004eb7873b67ebead61b9380b59056862a96408dfa9e0173e76aa0a0fe15f81f9f2e7aa63b9abcfa3d754b69f4babfd909180b58be58728cdd686bb5da5052f96821975a647ce9b1dab42ae879754f82bef03e136d3e83929001aa11a0bbab02527a004e14511d0557681e36861593e3ff18fbc0287c2cafe292e4b6579e5fcbf70d73af5cd1b1717c86015958af8a734586910016a373dbe68020573a129fdbc6a5400a4d7450900658889221fb121f86b32abac4030b1e6b6e5c53e0fe0b087cd7220b67954d06cd221c615789e564a0e0b9c1661308d2cec40e2d53d4d315909f32b54ad71e645e28f837f491307cf0eac8362a2afe0025b0cd9e40af46e73c0acbe9bc2a26a2be29f6acc74114d61fd8f82b3a114ee4ee202a050f65ff0f318d0e4b4910d5e9a9c7300af44386d2ffc3c06d80285ab9e16337e289d08660fd7df3092d25430c8a6c7107910b2104c7cf3df91a58b8224a64e5e29088a126fe48be2d5b3527231ad4efd165106322840fbbf4bfe783c4cc386464d5d950b50d470001226ecc721e0ac33c6dc90d0c7ce761f86ba34e049758821605463d25a4cce7f79569cd79e12c4b0b3248183eff4e282089048dbbcb08cbf3c6eb101cecd55930d3d947d37f21a301f26272da0bce2c5f5e20898e1007a518c37eb309a52f871ef4a5c4630778dfbe65f1ef402b44e5938d9cdb37c13c1f10ddf4ca823826d3360e649589267364d7b369ac6c654d613e1a89b40e1dbb305145a3d6a5aafd05d23f5a0f7319dcc8d22bd7d66b567f2b2203b8329135b514f8d2f723af78d51ed7358facde509deb9541c642e4c57455d2b547e478467e18496935b09e2a3312bed31a01a526d8c51d82d55728dc7ff5c676cbe4f23d1b18a0eb9861a2668169590f4472c5ac786719ced85eb5629067ba51452a520c982aea512ee1c09f54dbdd7f1bc721cc0c44dca1bcda9a8244f5d6e1cd5110cda2f294a5dc598b64df486409192db1dd7ca97674a210a83cd1360e59c1bb4784fcf7f7fddd6fff5bd286d5c3ea45a386ff3e49ec4928b440cae438ad546b149b5310efb1b7068b5b379aea70263528aec0b415ff761ec1d5f15eaadcf800b516ec42fb82ba2a1325f58080ebc42796f630e24a91bb080b98bea04c49a6829d26b47016775f2686f7880f5809e3bbb9a19249bf9012a792f22e347bee71cef73720cd040b0f16a6943eb22bb3f6b0cb2c9e3000e717839bfce074eae591e61f6cc749efae39128240c4c5baefce3464a4c5b262677b16d970dcc4b21fa5705a395d7c5f53a442654a8a1945b9e8833af4b4c6365ed66872e93de86c6ae38cc9c82e1c70769c404a17e3a06b838b92355a64927f54ded317b805e81fe19f9a165022c680406e1425764ff8577f1278cdbc551876b7b041b1a8411f5e0d70411bb5dd252d5b4778abf35bbc0b23c760885ead80c9a3dea40a103d7b04dafd900e17008d5e00cdc075772a685cf993ad9fd0f1d0ea56fd2679c5c9b5f2c405c00761aaa99a4b7960327062dae111ecdd42b8aeaf1e575f8c138ec85b0b82a1a7ff43ce0b3026a4962112d9a3ed66802aa2aa3a2af9d6380e8188fd2a7088914896fed7b7c1af9f34bb266c8c514b18a3ad4c64cd432fd8367f250b60bd22f3a2facef34157cb364c2235e9683db32bec5ed00985922189e13268936e01caac6bee3d92440b7f1cfdb1fdef838556c547ae0d391ff01d4331d23fc43dddd58bb04043a217c1d283b980454a34061ea395b6ccae6719fb39d0593dd991a0551731b47ac9873512432daba21f2099f6905f60c88f4dcee2a8d6173ca6fd5f790b6e0552fbf6991d8520420a5a512a80e66837e24836511660244bb0e0941f1f8f94dd523859826fe04a25d9219c68fabbf72157c81f72fa16b0cdf07edb6560f53ea51fc0ba7d5fd1acfb0751a5700e7e825b68f43e2b1b8fa855b1739e28b9f318385a5a66d3e102aa5bb149210a327348ee479975f6e7d6cfe905b20ab7f2c4a0fd1ac9f424a42d24f64aa342d59a38b9b955a014de36af376e01bb1be4595a431615cc7fab4840f3215355a04bcbe8ec1e7ebd7d0f9cdd626fca489337bb215e216e717f3aab178d100f02845619db3eb8a602082d3bde1136d0e1240a0c3a1a627c3906da8aceeb45ae0570e182b924d6c7e97ed579ba4054c1d6fc1f524cd916df1695ec4a16dc3d4e6b8bb5355d93635f86398f004a435634004210ad52ebabef5289d9a4ef936cb728a45d742926f91b757fe3f89c3ce77f7038c6608af5aec80e136afe93c62c24453a383670d9fd5f81edf55987d09bc64a8af5fb35d922b84596e9c6b10b9b2ee52bb5dd7457a7f0c4961d3cebc040c65dc214b965b7463c436a55fd82850010713f3aeb61af79e1f5f2f150710995b611f3ac4f3079c4044a986b4cff2e8efa36401d9dd7eb44d8830dc2cff4815b136e01d2f53468b8f182c589fef4f3a7d0f6b15f239e089301149c61f80535e08ab2a3c4ffef98e9e3e2ef789381dd8a4eb5067fb00c5008d2181472f3611e98c3bc0312e9fbbf4acd9c48b3d454dffe0699424aeaa6862a580d186a891e4c507f8e3af002c5ccaa3f4bd6d61353cf774ff9927001a4259c988f514af7d2deb2e304864239f145621f06127b1e62ccd1bf228428729708ba030aac0171c4a4d705896f182f1a717a88410274e78b5999741676b774f1459a9ac5bc08d286d680d5ab161889183289c5af62a524f4a546975609e4ea191fbab8c9a1b3914a9d1f85087b13eab3b339010909bc5878cf88731e490eec7e10b77e3ae230a92028474460b7d047c1d2f39376cb6e7bd44e7a279052d88b0d9aae89dbbb2e180fc9f57f1883107c37e67b084053bc7921d6ee1064dbd4df1cc163e1b22159c84199077e3ead75aeaddccf5d43292b664a3036ff86ebd1586e4575418a708f6b353ce6a661cd479add97668f0c69bae1ff104750e27eded80e9ff1681476701425fe5adfd06e335efdfb08ba4b5de6a2f800afa11c7653720e3b43e07bda4416542f0448149d4c68cbd2de185549aab74861b9e2d11587bd2cc1de1d18471f0ab414936ac06747ed2849671b1a313010d4b0ebb77f3ca47f8ce5a2418143309dc7d51a2eb5148e30a3afd566d49ee5187c06b9f536ec3d5e4ac843bc35dcbee12e4ad085edf0da32bd934a4ac64afe57d46505b3931829ae0763e31d96b3ce8e7e4e2b0481bc7933fef0e763c8e51f7d544ae74ac7f986aa6a2c67caa9a9930f4ff51cd48d4afe9690aed280b8ec978a6ced821c26e61bcba1165b90446ab0a0fab1d8447770e517ef79764c71257464a25d5090a5e71e989e5302db4083399ce769fac79de9ebd347ee17e9f9597a6b323eb416b9b3b0d5969ef79d3cecbcd09767a0fd403200dd3b28a812f44a46bc9ed7590fd21db75f45e9a0eeab6d097a8400226e388069a05792399b3b44baa446899a2b511545f7c46474b7d1f906e9160ef42930a1c0e00fcd7b207b637448f05c31cecd30ef2de918d960edbf673f911520054586426ac372b08675a2f82aa0cbaad5e2e5002ae8908968448cb5cc0d650294b3ec10fc4172e3dd734f17f6a9564f6472f6a370fbc33b8cf540c725b6cf605cf93c1076011f760b97233536a52d1684b724e31683b8d40d71685740d7035a0cb74b514728f1d456109a203d014deabf099a641bda0b9d2aba895f9bd49b71805b15981cbf4b0810833094f00eb77a28d68485a53030e068ad23e88217fd5998861900fa449c392c9d8efcc9d1c17a606e6e16d35c39e849cd33612b7ec428f0d9748244a12a119f8bd9e487e7fce258648f7e30686f41618f4d1ae385675fefcbd49ab60a47900384c6b4edce6883fcae47f45429694bc30ddb48177e1e2117119f3126c38b7ea7e2f129d1b78080eef7ac120d6ac7a01c372fb280949e8ee8095ef92c67f7acc40a27594ee1340e333e3488bed63ffdeef568c81da8232f89a758b89819cf5a2042114baae794485f8fff7b8c42443f32cced72abbe1eada66e10b8a87a9045cd247bb3af69ec9a77667d6001faf35d27713c0bb5fa75081214c94000cf8ba14a3f29cadaf6aa88d27e10f125162e5a252958ad4e96953158a794314dec7920e84227b06d8c2440d8a5bf354a176867b6771ea06a84d8b34ede22dd32331d112e81d6314b803212e3fbb7a0628b7e686aea5eb72d1c0dada41c29b9fdf9a310e1a7031d98b27c78b5b2c5f920689dcecab0cd8f097b98743a352307f579a8fca096ae11fd4daffccf592fc1fdb6ea3589adcf30a0c3e2147ac7383909a86bce55903ae0932cdd35963203db82d3c34e09fe912a884ee14e640a8c02377e73a356b1197fcbaddf9ce4fbb4993d07d4e84566166fa77cb70609f34948c8cae671829d9fd4de36e1e13ebe696121938ccb438707305de794e395b552d2d86b2d4de84e0e3549a1571224b41df40b8371775b5211e632adb06719f9df86684988dc88a6ba2f33ff78f8b46ad04b094ede7b5529b19bba7bb7ee3141d468c81354299fa9155715442a67e8181013487d31c94bb9a4c5fd3e5aeefa56ca40bf60ed38bb53f8ab469607b7d6883e449495d3934798024adcd4916b4011adf0b5c6147e566cf12dc602045bfb60aab9e220fcbe0ba8397185a4ec2e09ac0fc4f788e80deab0508fe955044578598e7dca5e783bef9c9c6232ddbf858523fe1cbae943301cd6b0b401130f8d0ad1021097cd95897dce1a3b20b1020f83f63f73594fc199704ce165143e450b8384822b012b9bb05338513b29e7bf882fa7f20997a006029bfdd13ff66c86338307f0425c8a5fecac7df9a688b9ce3c921b0145d61170b9a424e5f174544b9660e54bf5e5c684d5a4dde5eb9b0f9dbd9e33da5b208608003e0e65fcad1e9049956f22c1640f2964494896c826a1d94c127ad6643b92ad1ac0c9f20b1fd169ec8a4194fc1aa20813485d1d91ca92a322fe2d061f63befce25f0ed5b862d3f80064a7efada36b63ac46d729ebbfe8fde9d04264d1058d02146d405d21d6aa4c523e3b7cbada832c574bc6d3d91a4fddb0934b0fe7a29ab49a5e1d8959245b35faa9d1f6cc59a63478239b4f009d75ed1a11ebfbf43714298694a0f593005dfbf6049923df5f40511110658b0abc4c10d98b3179d6eaa289c0eac23a568012e1a59d805fdc3fda6dac2f599065b708060faa0ca71027de4c017da1faac38d490a1920536d26109674248ed4149c2a4b508275f2177a81f7744bcc6c0419402b7986a0b7c62340ee682130c6be38e38ba8b55802263138d8947dd897d88fb91119efc36af2410161b71622c0837636f76852d92998cd33383142444c906367b9a94dc2459c38d93478c7ce4258b03eb80c38036cfba0bd122ad892307d19574c3867a06877738a1726e6349d718b48834f7a25c09206cd10c8be0a32d4ad14526c2968523f75146309707eb7ef84046338128ac830984a97e1f186837cd09e0d30270a3c42fa8c1fb8e2beba3794d67cf561967fbc5755b04f6e9b8361fcf3e308bb496c9be2407017ded84b05354109698bee61e57b394fe8d99263c64f8e1c8746d102562499f02c04e6651e47c89ae5059ce72611cc09284963c1a1e047ed7e74f746d2cb86228b294c935359ec94188a6fda346cac9d8d8c65169517862187255e0c1b2fa0c9e9d7511a6eb5d1b97cd253e8c37372e38a8a8a346988bf1362fa22dedc0c364ce33d9b587e7e1ad0d86bfc110c3ab7fea7812c6fe98f84fe751a1e19a20281937d240060753c6f08b71bd76dbfc6d4b4071600a8e6aa237b8094d8af12c28cd67b29fa789d7954908e53564249ae1c1b9f37dfb6840de99fd968e2aa84bdf3a3081f4963cae8f08b6b81ec7a675f301e51f025fd892c872ac46905710a4dd2c49eca34ff0be4030ac0653d51a3fa1c57691b0d19813a1bb64595c936345dc63688a805d26137099f0d17d22f16f59777d1ecb7f942eb380e18f765060157488a5050badfdeaa64d6e43b9e2d5626406308275250852d856c79dff1e132c4607788cdf29864a2fee188ea9de443a2acecca8b0fc4c083087238ab9ddd00787da6922015d41cc5d2a412a709532bdde5ccdde01cc00f4aeff6edfd6ee606c82afaf47a08082c8f84085c93085f6926ca14adcc042dd00b010c951328c905e77cce18f1cad7128b8ecde2c76c13511ab7ec5d7c3f6204e9d37c4c2115c81868be48a0105276ec3140826e0ba0874570dc805d683e3ad35f65d0bb324d98d85515ce5098495ddbadfb657f4b154da43875ac134ef373b49e48c1a203a12f71b454295213f79107fe7e38a985da07f41d330600343b31b389e6647d239af73741a6148936259a1186f8c294d1b9f78c4dc54ed95d21baf758f79550c364365be90e02cc6d1762880faf21ea3f510030368da5e9068aae4ed096d5e1ca73ef32ffa5e8201589ec57ec97a9d88e6d3350c2a4466d9ad56368c2ee56611b27e0754ea7a4293618d773452e14465394c7a076e10f9deae31c49234e075e057ac8afd525328b3d0cb1283d2f046e81f0b6e833f6239731fb89850b804b3ed2d749a3b68603d3640ba8761510d96af9e6cc3b3c8e94f678f3973dff4addbdec2ae20937bbac861f67a29958662f21ecc67da4a628ad831f69a68b77f8cc1a387acb74c0fab64c724663526d9d1bda59bfb9a723ddca90281d3913c837a1c3913da2f3033bfd4b7c8491d77a29816885b8c050afde248da8146036bd8d2b6898a1a578e69b74b7d7e5c091a808fd465b5b545c98c7cc01eaff896df530f84167488bd399d902fb6d0eb359e11fef640f85c807db3c1290b7a07909d2028c156f08c671722c6e3d945a205b8520d12a9bcad1f187b99cddd5defac042745bdd30ba176ca44d71558203173a31050fc95db451f689567e43ec0483c035eef5708e3f2c1751db9fbb8eaa06c9034f284dc2a764eb83298f6985c7c24b7cde336cffc9da0bb2d732e4493a79cf1e18f57608a3b00a4f77389a30f6e629eff9f34e2bd6cd31c0a5a4d7d4a8eab703378e4d7e0ed53bf8d372d4f1c9bd41ec5ae45323d38c220138ff8ede3cd83fd42dbe22667a2f84e0d97f26d5602aa01ac8c72e1c07992e26c9feb308b26f4f6d4808a2a0ebc88a66eebb893ab48bc9a022e3c88a67e6bb8939b48fc9a1a0ebc88a45e6bb8929348bc9a120e7c2277a151b2c95e6892416db3f8ebd3522c9aa53cf92b92818e54026f1056acb30f83dfd38f33a97481a031727c3fe9197dfc2696147ead2b5b9a0665e61e35dbded24d84c961e90b1986d46b3c48551063ae7c94da64a9001edf0554525ef33addbe2acbb1ef5c9b3c1e883e8533e8cb6a7a14a4538ba06deaecf42820748e903a9a3bea27c15bc47735adc7a4d70a085d4b938c7162700268a69ac6ba30eac2c466b3b596f05d8d5587d3625a9a58ffe81f4673f8a2175c66e3138ad9ee01a4f81faf4a75eadf6d965bc13980bc3862af1798b7d48b3056fcdfa39b3d692a4ed9754d129ef40aa7549ae7d0f6463f85dd300e35d9b22cbdb4ba83d742e87901033e041d81f9f3f236d5b0d76812f10a20461f5bed8b50f681b169a6307bc9b9e23d814559eebf3575bc5da933794d16b52f456ea78a5661c1e50390c53c7537a0f4c60b9368e4359397331cf3eae4d338536391791a59eb54bc85154d53704c15042a2f6b5f8187f42be7758b3276a9049a799f29707612829b9a8aa57a0f1e9f133028d003f0086577f2e2919b32504b1ecdc33fe655afec54c51b2a924120e749523ee66de75d296a4215cefe6d44b15bfba0494e052b7529bbef9817b3e90a210eba8fb8c58c44371833af97d72b6af3ce99d7c06b749d680101a547be0501b26f097d64ddc28a8f1a2205547c82ed3a901eb3159003d198b59e27675de0925e0907043941494a6845792f00f4236d459536cd332d97aa800a6caf6636a66f604700527b33c4b22803b556515e407064ae7e850aa170ec50db3d49a2c1c3f057b260ca5531e986c9a6f1d0c314e772a9e0556a54fdab21cac9051518f530ec657f20c682df8694fc32817e3f710d5e7a5e099401943ceb5af3c5b130a557c3600c2ec8fb02b9183c4b48574605158bd58e1b48fdd712ed9c9c88547f04a737024197db6ec5ce0e1dc2f9b7dcc84e16770444ff6277cb406878d8fff2d6c284addf1b3951f08a098612a3cc04539f3fa510fa8fea9805704cf2af6ccd76c4392776274bf851e23eac0de82a61eea940726185572b6dd53c54574474812b3ec91324cfc3f6780927b1b7cb03cc093f71c31b68b2d6e4069561aa2979db9d8ba3d6138edcb59303fcdf6eb9fa3ecc931890e45b25a5c8c5742eda855a5633d62d1b9b618b4ad7585d87757d11dcc46498e6ab32dcee448fc571998ea9bf8101448d61ed48a17ecae41ef5828967ade4b90164e8b7bdb8ac3e12bc6fc28cae766e1fd182c12c873bda3253d84e06a1e0d1bcbca3cef8c4046226b3bb1546c7025e9835ea22bff336caec1e97665dd28fd9ddd0057c51f7959c00ed9504e8892f9e11999f9350599f00fdf0f23323b1d90296a9c9900f55fe07142f2bc7952a15fe61a5370d5c8cf4be7e37f65ea0bb2ff9cd7ad82a716a985e0f6d6a351e5e52ff55232f5b81358ad0d199ea79a42941dc1677922ad3e30702fa5760e8c55ee8d071d045ef39614c1de5d5404071d73bc2dbd84730b50384ccee5e0cc7f4a720a47a8842879636dab47e7a64e04fba21653004abfb194e94a2e75c7a8b54135be2fd6e0a543769950dc92a98a3288905cb785777da3369e64d219595226408b8a590b84c1925c65d52c8403b053663473802a8b8f80e09887fe30e1bf497a113ee60d726f53fd503af911a4e8014da9751066f907fd82be5a47ed97c76b912c758324499200f83c9a406d807c960b2a62d388bb6b90f936cf08fa5d5940150cab5db561a6109e5ac40c9dac307b75dc94da10078443a63eb896d31a5cddf40fc17438bd6499e712d0ee8b261236762b41b07cfc9e5a963e62b4200933687b017bf37ff50fbc20d25bb9a8ca85fd1cf0dcdc4a55d2bf602cf4fc86c68f44e6c263b5c63af3e2e7af2a618c1994113e50f4bffde21e03762d2cf8d0ffca20ec8eb3e81babc3d085b30f7a33709a34bb4f2f209e07b11b0d274ee29a52d4ab2d1f694ead3d90a4551a145909d3df4c9e87aa764d073895b47177b336c46e1f4bb05a08d674059e5646489a3035726c3b5fdeb7e643d15220bc0c039aac733ab811c1819572746f937e59bc028b029cc04b459644b9271531a8c56cb95c7bbec71c2f090dff5dbaec2f57b617ba555deb634e9c7c0919a18c33c3c0ce6cd117f568ea39d3a4ef9a85e3964e2df24eafd93f675c30b932ee45438abe0208d26f878f26a12309b5296b2b3db591fa0dcef041c90c38ffff9230c204752248dc4f3038869963b67013698b62db401ecac705e741b686234d36f619ea2be6c950f9b3aeedd3e4120842f620141f89a87e19e1d38c4c96899b4528a76883e2fd08298e6ae5dbc2a0da009c3089b491d617dd7c52ec429930943e5620159a97d23ef04dfd09a5ad7292cdc674c7e8e36c362fdbd2e5029796741fad46de3f8a9c823095317ca2b92af9558522e63dfbd9556e0dd52bec9c890288e53a9fbb118ddffd4c5825d34f60055411f5adc307f8ec192bbb2a579d6ff9069656906d22240b9b9b63fabad970d7fa9ce6620c87dd0b1084aeadb3567182fb9b9e20211ac54d4954f6bc42d369764768c3d783f124e4b2ecb5f85742d6164e2e9683b97bb642a99246b5de7bafe94032f67521b44610bc7cdf74571332002ab11a1df1f68b8921dc466420c142e85218c84aac191d98eb63a4539569c4b7d2f33c9647d8cf5c0057837a2a174588e52df33c0c24bc3356bea0303ce02e10e0021d4d369dd98ab725da5d08859dd40afd3ada1007db3b00d18cba2bac0f6bff1711d18e442eec49a4b56dc70392e34d5844871a1df80ba7ebe092e631139d3aad90935397ebded6fbf05b412dcadda937e74255e01928f3300831c0076f2804eca2b76673b150cf44c971a3886e3782189ab6731c83d3fd8222a3e70edf48dc2fd1a6e4d2b79fa2d776dba8d3364ae86cb8613ab6ba0778e310c72083362d4da0b721a5ae3a5a9cc6975e5f48d1af75425a5ea99c9073d8dd9e330952e15607aa75878538484e9e6f3d42c9b3e6aa0b1418cc7f936cdd7fc9c0404075a6de0474c929608aac2a8e891e9894bf29671c787641c63522a2433dc5a193e3948264eeff2bf0094f737c2b348da08660495e4e25054de70bdd00365f6281794559a1362d6c7ec1442900583e82a222b24bd36ac17462f277a0c489a160e6f714d887592ecc9d15eea744852c795ce8e6a1f65267461fdbac8d53ac8703a2a96afce07eb42992747fcb1184e0f2f03dc7260829af1040c044f8957a3c02559190b8dbc5af6f9839b0dac4ce63f0e0dddee3ebde0b2ab06349d3c2518505eb206e82eb575da5afcd3f77e370c944a804d5fd8de20bb017f4f817779534e7d6f12667de022e96fca1f939e08256cab6e4aaa81793477e30223e9f71c0d955901fc9ac71adb584c3a3f1d6e824a6f4d845c0692e9aaa8d713374d62c74fefbb7a755443a697388607475eb101148e149a704d8301b3aaf485705fef4cbb1d17fa52b19c133103e9eb8c14169c48c1f9d4221cdb6e53e4e45e5982db657587cc87935ad6df4b1cf5a69dbb8494b3ebd0fcc8842c85a84591290ec4e145d26ac551470591d520d76567ae5bb7a82995e336e2597f0ca9cbc912d0a8a348aa5e51d6eccdecab6b69daa079a0301360b94035a724c04062771a8fea96b4a27b7f19e115bf78e9043c2d2cb7ff91dae585453f5d27edcf63446c21c05f6da82f303d6c5b1919948aec9448acd405e27389f668fece64058e3bc81783605b85238163ab74389c3ce90337637e6605dedfb775d20fe8170ce50952259d184f43ad72e275297866e1a70c1c844f6a7785832ce8a481aec15668221f9836c229d8b1a66118a24ab4425b46280ee4db31dd87a3e1db4cb629e9f02b5479008918dc8e51c8771392a259a21256ad9063ccde1161c4390f453aec89bc5e3e81092e0b3c0bed64157911e518e92c0bdfd2072f41e25f42593abc22146b6fb26593603611ae581293cd9a415660ad1c3730f9aeb216b282e654a983e1832ffe12dc95d774701961cb287cd11081e4e6850142f5b2385e80978a842373d2f37164606a5fee688e77f2f4811ec456399a83db7fb39da61211b9d5881d458adc34a5b201233eec45fd154283cd997daac77e353028dd164a18e6d53fa74283aa8a5c47cbed55b1b26934404215ab9b68412a64eea66f852ce1e6765d53e64bcadeb86cf327e5425fc4de2a7bc7ac278e8f44cc8ac1a663b2e8db1c6028e6a86fc916b407a64df6ea0d647d71340a55ff6e45108a1a730e7f21db7fdb50cb66dfdb43fb1f80e97ece03ca3dcc1b7f4259e52585aa1e1ddea955b66c326bbcc74ea4f21297b510f59657c723e5d36e5012063155ae5589044ec1e40dbaa7b6c8796ddf3bcd0d4bc02c437353b477f44091335246fa3490085b41384a35584bb4f288239891fc7ff88b9374c269024d4bfe6585f230ec816ddf075871b3ca52666dd70271d9af7612ef2d14b33feade82cd67100213db3fd90adab5c5fbcc8accef30b253841080d07697af4fd11cc11b5137e4347a33c4193ec8f01e8453174188558ea0167e675b3e89586c44ef92568890cfe619bd0b4acbe25ba94c1f74a216979db87464b971ac82b86517cd725730a682e230742a3608edebe78ed40f2fcb153d6d11f1a0f5f18367c7495e23c77b2d9f0e28e07f6d85ae25a749750cda3d55188e78ec484093fc47dbb4c60ee0bfcb457730812e34cc97eecee80e13a660aea2d59ab0208bd76bcc74d9d39248a7e2f39407878694deb25130c5a04c5ecb1df50c06704dba5816f5cf683be29eb309afea75d33b6500e4f4449b25b5db10ded110b19bc4b3c08b26dcbddbcc9d92851228053e33b3e84d4a017c69a89c98647c99e4b7c6af89524f98abf9505da4afbcbcd111ffb755d0a27beac96fbcc13e96a1858dc4b25ab553c23fff255d78e17d1e91c065fd539b3e4256c0a7812f2c50a27afd3121e1ef75db04c472fd768aa26548cbc3f8e7da9ead5af75e0aa8bb7fe8262513228c4f751ce18dc2984c428b617ab78b9b0439b865f51797a945e7fee41228dfad01b36d41820bb2cae3fd811001f4adc32cddc6ea2883c552bff3e88a3110bcafc5b583a70bc48feec0c8555386789928ded2c705dc0f44a2bf0eaa015aecb087783c52c2f8f06e5825eae31f7cb83e603915d198e3a08110dca9b6835870c8d01413a43597be51c37b0c041a600cc26008d334aaba2fae16acefb99a0d6c1a4b8c742f8aaf27099a19611880ef30a487e8a6585e1ef2eb6b7bebdbfae23259271a88937216a9a9fb676281111c923d3a975f7e39a8eac8ae4f007195da429cdb464802f5934d3c417b2bcc1f2152e5c35e8292011d910a612140c097368dfe1f1fe79282eb988a291f65389a71d9e8453184234367b40a58c0db7d8110cb847d1380a32ea10f50274e6b29e11cba607652038ecbb0ca1f7d5cc0e87ebfc5a1d3835e52f581cf68b4a7075a1afcbca5bdc11f92b795ee2011f511c70345615cbe4c9d9a01bc1ee8a3c959d619f38f68f989548c2760bdd9269bdbe581eb505462329b28c4846cf8c9003f614370069a1f4ba80e260d6a9aa2e6560aa99322bf102c3fcd68b0a4d796c9e19a9e799d4bddb465d73dd826f569f00771400536c57579d2d04974c5b41c58135049748d33d3f692a603182fc3b31a22492c3249afffea38af6b05b186f443294012cbffe566eff3407c86e195791e924698d9dc8da1b6e8d81df70ed2fd3c129085745858f6b605008eea737255c6c0696909cbeb1c1faea6590ca5373538ddcd6194a48d13b49596a3705d4c25b3599a3023aba69c9b10c0ced93842be122757ce9b016cce6bcdd4a48d7e8126891032477b86fed03c219d49f0e01b63a3b33a1f14d3777aac2f6cf51e4e02aed5baff6afa1b9d442889831a3e1772074dd7b4dde87709d551631b86cb73fcbf6f747a11e7456bbff0d06d35f9720b40da3a4e8c9b2c7b54fdbd02f79438af659eb2139ad4c4c2dd929bdc391a43c32e64902c6afe1112909c6eb6a5cf2126d6d1903f4fed8c2b286f9cba390ce511b40027a701516ca6827518f94493ad2603bc19b5e4dc3489c95a033c668e29043f2d3e376a6517d89dff7c1a380a042f95c35807b5c66c048ffedc973f8581fe6ba22b6bc8cdca83d87195ec2a1ef8b3acaabaa627029a1be986935428c89b441f08fa56e9422a0aa293096e184ec709c294864c015aa98092a01920423181ec57edfa9a9d46301f2f8cf320aaac68766fc7b4ec232b27a784246d092aaff2814e981264647e6e9475cebc0407c88469ac083d840c88709e92a0fc410b20f2828f0851aed53a80ceac5ad65053a7035c8353c65dc9b829d6a7bafe548cb5814809e1b95e22266f6233807819e56b21184dbc28704baf7269d3a09d0c4893d4df8e0be73ade0633c939210d223e82556a33bbb4b22721b41689f70d772a41cab5cfa6597f1991b414452433b4427188645b057035648f78217d751a65412aff4c884762fe356ab5001ecf0040398cef8e05509c7dd11309a5a7d91c6efa165b5d7adeb9273f3095219a96af155127f474004a04f14b2c0a41360596a9870868f6dd24953704ab77e292809d68fb0de40090e2549e297ad547b84b53c3ee8891eeb551fcc52c328da0e36b2bd2d5b2c0f8a6ba9ed0acd9f56b094c460f4a89254da68ebca74377e32707d70466c9c2529bd1aa914e04a3c6b83222856a06cc17dfdd9783abbda1de096241f3ab169a5239fc8840e65d7151874a36dd0ddd8d0615994260adc58b7489489ec7fc9e01011310a405c12777900aaeb021f0a8f9f46c961f489d187c68791dd512418aa094da1732a2cd55debc378322df0c1f53a3fc3da6c48dbb020f254db993689fb39a6fab9cbe284a2051e001dd671a4c836d472bc464c7a8754d72c3518aaff87eec5e3548fb350e03ed6504283842602650307762e69f300ddaff62ff0bc16928a4ab35c423f2a956ce50beea911bc7413a0fb7b8b2859bd42a313e0714a76f8c57fbc39adf864652d826350cda02aedba41eb638937c326afd0c8f8aa977c8f44f210ed66e8460736f3c95853f17d84787aa3137fdbca122ca428ebb988f168442732676ed18528648e31db6ddc06a9a97e9c27468d326ddbdb86aec40cdce5bd5e6fd5428b2fbaa5cb3b9989c8d03a1f3cf853532cb9b78316308d759b726537d17d763b5cd65ff40a5dedbd8a53f4e9e9680b7b9c33ff7e067d80e67914370ae8f83e2c65369c8af3d83a442e9b0b22e147ba98f68261407f15267d8d8f3144804828a9d83308c03d138145d87bdf8dc84aff0e938694b09b6be647baa52dbf6009dd62c120c27fc21636ae3a98aba0fa3caedb93b66418c68f573a114282b01290729985c22c8de55c2c05f189d9061b96a5e9964d5788e8249be690dd1c320104566949413e4a9e7863c6cbc6935f26cbfcf6d1325cfed63bfa28751816a725b963e702a4203b0f96e0bfb2463a1bb5999c572046b108c44c83fb47adb096b08e1efd49fb0bd769aa4721dbffd58947ee4603f1ffc04b4a399c85111f1b395a6b618c085e01283ed19cb41e153877c82b0fca1827855e4ca187eb8dffef8b6ad017f9ff21744988c2c8d7e9371266ef4861312cea485300a0a4f3fcd34efb9a751ab1c14f0b3f486bb91d21bed4c12a45f14c71902869c990e280952f5015ee3c7aabe08e06d84706f6744ff26ce1d2c2ed8b47f2699bfbb34ac1d7c948e2e63c8ba070a5919395c0e30a70723ee670e8a5a4651ba361cde2959a559e249431fbd71e2c311cabde6954cb9f076c57a9a71401716ba7302d4a23dae069675ccc3608209a90cad9308d3e954a07d61301fdc2211976f55903ae56eb624015c75fe22d66384f77f8aa9ad0408f71398ee79584da8c17770b50d4f9d7b47be8d6d55e1ce3f61caeba146b1389b199c32a36f704bc0f5c59fbf95374a21a9a89a9aaf5fe69e750e15a3705c18a2d68fd8f468ee9d66aeb51696bc51174f96c3b8c89696aea867b001fa891267b2ed71e06b0419ce991ed7d7722673333cb973bb8b2b4c5c6c6623e55531e7050930b7d0ca68bd0a8c94f57831604ccb164155721c67517d3ef0dddcf370a4072906d1a106f51b007b3121d21f104fc4b79a7dd121d25f1de2c86e843ef4f7791d06c7cad5beca47a2947ab0c5015d2e0f4860a2bf8589f4d7f9af2ae5b17514a349fef5bc9e937735cc5d4c66fef528b35496ed5f0f62a630fff983ea180c4c2e7b459481eaebcd8ccd29ed770b5d9b1b444dca34e2214d75fd79bc28a421b881ba4d1f921b036825d8efa35b939648ee2b0559cf129f679912b5a4242db58ef784f8724a0698f67cd00831f01c3bec5d884f46c72cc75b029001ef37e872f5bee8e462a76f21dd8e130625dd5767837cb51d1193322cfc76079b296a5e2ae36c1a22d0c88d4fd84b35581c10fec836e632025dfba33727e8f462f9d755beb3d95839b23af0342655426f528ceb7b0f2b12ae4ad95603625e4f153534681f5c0c8ef62988bbaf464c3c695ebcbca527d59f102e1d06671d4b50e36070c4a279313d9147f1902af394d9fac0c1471f64118b0df36442f9d8862b78009dd6bdb865052ca761cdeee0cc63af1a6c299aefb568c5cecce8d2e4ae20e232035b52d8e82ff99ae81a8a0853f99a3d9585d8a9e3b7534ef7752725dd17285f83c6a7269472aaaf2bfcde747853650588c769ba15cfe2f48a0010d7e8755351ef2d66df1e8b424c5697ec700093ba2dbe3b6fe59670d1ce04a9508c7d312b71d58c55287dc3e2196c1057242e566866c6c8def9f7057af3ee1dfefa7e84a7061c21bcbed84fe5db9b17810cada1f20ec828b16013b97d9c677a90ff8bc356682f295eed6ada8c9270305a76f649e3d53a9a36bf249c2f5276f649e1d54e13cd2801a71163ba7268ceadd40b6ea03366be29f3365418e3a838e4348f29344a8b00c19a72e04692d8a25ef6d38d32a3c88d001d6f8a7647cc436726da55177a51f1ea8f3fdfc2424f3ca6a6674143d12e821caa5a6375125bd1de6af832a0cd2572af1ebfa58edbf3b755a36a45072c57b593505ef3c7f022868eff51a48ef6d9cb4be39cc0664ab8c29125ce04633f613befe6fdaa567f8629712ae52f12b8f221656a11cc775d957d12735fa6ed29b702c4014f8ce47f88fc987eb4147d86b738fe8941f8a3fac276b19e495717a014b48b2c84d90d0bce959a1768ec38ae716caf7703e9022f3af946cb55364a4aa658e3f46e1fd15e8df797457ddcf7961a1c4c046778f2b1aedcd4e0a7e6cfa9a9fdf45e6b70879de5e02b9531f74c31af5b4d113aef46cd39e02bbd7aa24f26f7751890512993967a3c84481cf11b398acdd4672c416b5dc4f18526dcf1ca2f55e2779160b65323ebfa976cd2fdb815d04a21bec2bb1c69d6c9c1db8b18c73ea070e7b2cba90580f31e9423d6d7c22768a5eea1148d3f77e19315ee16ab650cb176ab057f10c0219ffcb9f4956ae71221197d4697ab813f17956dd566fe62bab484e307cab3e0df47ca483d5d13749518a909b2b0476403ab55b64c32d22c7234533b7732911e8056801f77ff29b016575ba7aff3cef670cef982943e122f7ccf449c9f31163f1b85492ad207f8afd202131862afd772b355aa0f8440ac5e08f5d661353be39367b2d0d354f5ff5baa62d9b96d1a8977a524dea3a6c28241008ccbb61e8789d894868fa052c07a4e00cb6e425dbcfa6448bc5fe099e4cbd6b617e5a460bb887a8b98148c66a1684b004bd6df4e2864945203a9f69516334b4bd3d2a2617d35d73755f10c73f2c9000dde2f2bd446937dedb445ae7dd88152464836d0cab7d0fb36162792fa640d35b10a8fa7a5ee2159e7850a5f2705c3339b77519570adac265fa65a8b13fc38c02c4b41017d3630dbee9516bbddb24abafa94e90836efe772a6dfc49da900bb17afa4408c79da3cc522357fdb3e417bb17879310c3b5034eb7cb244c7f90bd7d957039de4916559f5254da6258bb754d8499193b52d32a315d58b75b322eccf2a317cba884cdae1157068bd11f1ff1789b85e8d2eea64aa3a295f88e077c50c35b8a06aadd390b371e1b07ea47f0e6c0505df03df37f96a5a6fdb69f5f2e8ffe09a8f42956b007599c78de0bacadbb2d612fed1b6fd36cd12d4d86ff560a2759935def45d6ce42eb2d299350117d808ec5f8f5cbbaa2c01aaad19a51263c146112246f654b25970c43186b6bebab56dacf364b852470652194a82db0d86f5c12d5f7696ebceb50299f4998eb7d5f781f39c584049771deee45691f293fad3e31879d24e02b1108bed5bcf752b3b2721cd480fb34547358ebb585381d00e6172b621cb96a0d0bccab57cd27ace1c4c6b5bdf18f68b5e41fe6ec3beefc8d2a22d5d2bc3aaee5276d503788f0e526ebcc4bb1a96f29df9a444ce87a44a7bfa8f692b22d2d01f03020a1d13025b7a05665154bf1cf236ea957c66231b4305fdfc4d7b7f87183e3b40a37afd9da3b753dd51ebb595cc44b265a5ff53957b794b9d3537bfcb4d81281940bce555d2845d10a7a66b7a83b9831f43b19659353e9bde44604d6d014f6206986ac278a1cd83995b391c3049987bd3072952642ef523b506c8c5c9592edbf7ef52158069299b28c859165bfa84fa73a7cba110748fb97e409fd5da731b631f3b5e4ae45fb190cec222a7c48647fcbec88124578fe2e0c4e89df43cce5bc98cd31d391192a7cc84d2e4b8503d8643a1bad0754f5a7926f965da98940a9e5877ad4d38e062a115b035f9aaaa07dbe64db0727cb368a08a89384dd6e5626de15d5040d3bdf43badd62cfb55bf8b92cb524e284c18c0257a1860de1984e2c8a2f04825fd5135379d9f1691d9a5dd84ca1121b004a1ba0034d30edbe2d2572f652da10c4a608db55e849cd07f60b50c48b29ed014448526343a82b353a331dad7f7e34279c1099dc81583a1deff98220f7d373f8b88c80804de8a498cbe288cf1725cbbc689055559e144241dd2b556a54e8fe0c07b13a825e459e1f76e677dbf7a780f7f3c40336f6baeb20142e93d41b0bb8586ae4c1f415e38bad55341eb67887554a94652d3165cb30c25cf661e2df1a6190df099e458259c2f7528401be069b15874f6a824f3cac58dab617f3a0818b6a313a70d69ed6f04b72c1788e98d7ecd710dd05cd515cff7cb0a127134a9f1cdeaa551b13ac80250a786a9b39891267f844c7e502c9b2591f8f6d81d2144247a203c9edc82f81005582a9628913fea26df3779e411a3ecdc0b372e871f5fc33a1ccf3021a4fed5d4eddf057175cdbb8117db8897508d9875284725fc7316ebb9174109bd043a03a96c45b8748e9dad256558808495e8a163a68b82bba54e2208d87e53a3e419ba4596185b8b58e7374d85d02ba001572b5e2b070d0a30217d61a6fa63f3ebd6ccdd9c42bf788984dc8366388cda2666d66c7ade6fa319cace8f965a550b9e8befc19f4e7d51ff1118130cbda8103850b72cf9ab3895b6a9cfe645c545726a5144ca495d5420d2c54ef19465befd0b85db7d3d8fb82f0bba69b85043bd463ca7cf24974065c0ce5abe243b101d389083f883ad80612cb2e4159227aff180c26e94d7169f8ac9df0b61743a8c2c6b774567dbd1035dec8f186cd6155ebb7f25ca5d6462dd1d57072ba4cd871cc48c25c56e07c472a8c467492025a667842d2e6d7ff7e450d21f618d9fb694015d03b66037bdd1da1ee4841c57ad84e40c7f5d0745e69bcd2e042d6c411b31e62d87c66187323156f74822cb4e5fc9e8c7c220718dccafbae10e9249aabb8213b609a16a1f2388950acdc1c0f1ae90d1fe3cda2c7a2ab5f76b33308db4fc0be2d069b65a68c4eaa65b9ed5cc64179f0bb733935e5f947e61f913801be675e6d9cfbb28206dab6e41adb88861ba9bcd883bcaa32b70a42b78a41dc6b5810122a655bcdb02f8f64c9567293e5c0c7d3ccd6cfbdb318693c413c29412c9eb83d6554ce21bd57e74ffb279721e0f326d46c7d2f1d31ad1586002c0357966056252cc8ae981a71db47ffbc698e2f09e733912fa9fcb64c0efc77f3bcf8dbaa4302cf6d59199c5f956f4fb52848dc029c48a339174a1172f9e076debf93587c01b00ee33b527fa41e99e775cbddada880645270d8b39de3d5dcf3c48d8680a53d0af3516a7bdfc1602ea6189475f40125a4d07af4168d388f23dc68eae670f835a576a9d7243333c7aebf76db9fb729446b66f5c1dbf9cd977461f2983dd09c15ccca8e09fc05f2039f18f41c95dbf837d4df404e33538a200877eb70fe157955aecf2dd6849937b6f99524a017a046f045304b2868684e2a2486895c3a5391577669e2a3ecaa1a589988f853ac6f8a0ed04c91044e331644886b145850811ad16155903528be24a4a4c7c1801a19920680b1e2c756d486e5e121fb517882dcffb568bb0b1e53de7799ee7795eabe582795cc7b5605c4c8bb2d52a82b95efcfd27a29610449af810d4f169391e0d88e0eca0453131a194a62aff98aaf2bb7d75bbe2975408c74a903ab6e4154248b88610013a22c410a129900c01848812458688011264658a072c8891a18e3140868070d15ed4b5d5767e6c3414b898c18810181898998719aa1254c5923ac2b81d8ccc406406ad961195a0a21d3490cf34587d2681ddddfd5f6513d2a23a911d41757c9accf9a42082e3c3fff3c360362437c0523d75843db14f5480696c458ad8a02b2cd88ed4d0beae98564c4ccbe51de3e2989898a4b50509550f475aab638c0f17756d4bfc60b2d96a5acc10e362ee7e74557e0d743366b8f85db019eeedae198caa6b3392446485a43aba86b06cc1fcbb19351d07aba1c19c9d612ca85587192db12d77d8d7ce612dae09557ecbd95bfd62a29b9e2941ca6d6f5b9095ea2d2adfc2484fe2e07ca03d20d38f43555f96d59e74e9810ec6b25ac258b13dc9bd27bd6bc9c9e7aa0ca53cc56a2c7cbcbbda9fce1c8ef42bd3f0d1dd5f06ccea2d91e8e852dd3f02ee3990124350ee3d7fff4e28f0d4dd7bdd3338ee6d5ca22a9e68f2dd4df3d42877febe526175a4c1b1080110e090648a5995b27f03b02a391548599db72a6cf48c093dc328b4e40d52764414a31b14d165409a1831227239d1a3b6515169848e2a950b76e55c42554127399fd0c6e1fd4fbd13068ad0915699dadfcfcba0f70e8eb264e293cb28a3f277d3884d55eaec80d7197e80abfc81aecc2c8d98587cd073d3a209a21b122c26c836f3005accf93bbf10f53a6c663853afc3a6f4fb7d2a34e9b029b98723f7f5d1d746dff735fe7d449c13cee5fa4b7e0ae4401dbdefbcc93fecc3d57befd7e60f40a3a3acdc73dc737f7aee25c73dfd3a47a1c21708f4a3de01fda8d3e95127d0f4df09d4513d70eb07e290d5d44da43a2ba33ca45613dfc250b6993dc351f041558bb07ec93f000ee808347ac60b6512b4e5e9cf3fb9705c692279a08d09a4bab62592aa02eada9638a2aa7a66d26ff13b81a38e7a9228123e96f00502f359de01f3595e472d810ea640d42fca75540771744585fc8465be2f81358e7ac0acb34553484b0ff0c439df9333649f907e8d33c7851d0c52b40026067aaa6b6b21e8e4022dd5b5b500949a51535d5b0b43944e40bbbab616662df4243d291175493a13890bdc8e77450917a40d0e8cba2b41f0b80d1520ee4acf0b5af85ce189c12609e88a4e0c365adc2655d94250abe3a398b09c808a3ab664906234a350afab440a931e294ff4486102069aaaab44ca901a21a0f148a2f2a2caba361e59d45185836f37269da50fd29ff3e9759ccf8ef339bbd3ec7c7a539e9a53b54417950c192d9f83325aaabf0880e79ddce4ec22a35b2f2e8002ca494f72725151a4bf3ed304dbdbbbe4d33df75086a5e9a99ae3ee96b2bbfb391409dddd2b84dba56cc939c7759273aae26ababdf34e30025e7b5130470bc1193b7464204e82c8a677865b4691b0fe629bcacbcc2181e34215e67677b74d55ce21ea04141bc495bcfe97526932d0ad7b6d2fd098f6431d59c8c7a653441d99484756475ec2468cc45347b642d66a178e7f038505552dcad0e5344457fa784fd86baf9bb9e32f842954ca2cf83605e56eb5eebb1a0d12edfeeb403042bde7bef49f8c1663d040a1ddcf709216fd9725af73a96dd10b6b30cc57de812082d2d17ea9f4a65f9b9752f83281cf647a15beb00226140dd7c60b4f327f994cdf177e2a98c2b59937eb2baf439842dd6ffefdfd3d50c9d38812b4ea4f97f42a891fffe17fb112362e64594ef30f610ae567b22fc6a274f3251b4b55bf81d0021d79c98c772dca5d6e91c3917bd806b6d445f9d7961e2817ba9c6856a0c9964f64ac073aca1732a0dce8795d4759dbc7978ebb99df52b936a0abfc1619d639c896f284b0841625cd11954614f1fc9abed13ff39747a9eaa50c210a0ad6716bfc837b68c4a81eee773cf3554b14ff551249b6dc2817ba9c629037b923659247eec81ba4ace764a5041be3efe71d96c6c55fd385874ea57a9509bd9a93521186d0d2cbcdfc19e6609bf93a6c4ce0122cab798769788795e937c157cd3c549755a95a8ca0328c6dc13d52be8519a55195f363aed2a2fcd1a29cc99e16e50b217464594f77a37922536851f6e41ce6b12fc66157f265894ece69cf59967c118650af7acec65255a67e9de54f959f651b93c1505429a5e423aae413540944956c02274c45955850a9321c55bcaf171caeaf52e13869b8be3a85a3aa7ade7f5ee879de7c8f6b34870e1bfa6b435f3edb3646d433b28841b96459f22928897c25259395f197ecf1957cc980392955a95ef6d41623e80c6509244f8bb12da8e4a9f29965cb924fe384f60ba4343af547848ba0196588910f233d7cf04c61e40a2b4596e07164091e5a02707c2845c162c507756d4335dc3829a5949d94b27bf95f27a5ec6c18758725c09228bb5c48b8ac1cd5d1756b8296e32571b95cae2148b63031e99290ac70244a4cccb412b382923ac6f8302da1e53471b98614d95142754002450e9217ae3811edc8028908a810e9d13bc347888ad494302da1e5088d20c707bb74ef97eeedcdeeeeeeefdeec5d43c367b4e80d10a2e3aceeb4a6151952db718254e0dd503ce8142382a4b0cc5033429300524b01957fa75d09ba52840d478e628c7c18f981c8941a8f224e76dc00c4e5423571b9861881811528589083234d4a3c6a4554848608819c9d3bf73d3af7ddb0dd1d5bae16d72d59b66092f3ce39f71a36a6e4e622f95165d0163f756cb5c0e5a23571b98c68505c2e1725ae187589eca05247d79023a528808668aee47fc92ba9e3d3726aa91e1f34f038f7388feb38ce658a6861e163e6607445070548d775eedeeddded7d8513b560ad8eebbaceb9f3ce39777ee143198913ad1691c7c0e57215a981ab34823aba86188922e8ca147fc5873a3e2dc7c404882dc8a83b776758d73dc3d8b9bbaef1af52cef44bd9b94bf7212855c2aa844223c1111f43518afc10b4c513d261355e43437e4dd3a094521a35232cada3e1b203292e8459567f0a749d6579d7eec2ae7498c6855806869de1de3b06383491dbb02f9f390d3bd3bd873ad5c3990ed5dd0817ace8cf81cec48afe3ef3972bd9957b8d65dcc80819f8f812cbf21fdbbf9396e5efce3fd5672ee4de7ea4ba9c54ecf7ce35679a1a3aaa1f55307ea431b8e6c18fa8d992c3a233a27ecc3cd53faaa3ead8339ff347296480720a96f17f01e5d1b264ad885df9134918464854ff0f421aaa03500ab1a2bf0b288958d1ff05286958d1df05286158d1bf06d3c819cbb8b40107d3481d96f10fa26991d461ca17aa3f0af428eb55acd796e5537648e2a0eab84939a8ce4ec53ba13648410cfe22b7a3a3134cd3ebbe9f3309bca961a3841a534d95c209272ccb7f8f6ef4abc31cb7133c858de16ccc54fd653ddb73ce90c3e6cecb918213baa8143ad5f8447c449fdfe081726f7a57854562372c01fbb200f58dbd5759493c69e105eb3eeecd3baaafd56af102a6ffbe54ca610a55a1d862ab7bc749e1a645af31c308c4926887299cdedb9d996dbca0708803e5a3da853f985ee52f1b53f41777375af49fe28720dc5dd6a2bf8c09c239655e4326db5801aa3ff7602ec1c6bcfaf30e1b338d6cf444134766384e25e60e9182ea5fe32ffaadd66e8d1a14d817e3c0b2b54dff1714aa8210155408676ae0f7f9355e3c7d76f12d5f011721fd0abc086b72a48030f223074638362d1770015d1bd60a48860041e37092a0fa8f05a8f307b0343c8295f19f2ee6cf7f01b24cac1ae0ef7e72cb08e5da7d57c38872a3242080daddf895957e821f7f72a61c707ac0e9595e1e80faf90e40fd0c6196c592d2516bba7bee1e059ec26df10bb7c51836660ac5bfe1af399dc351e5813fb4842c731aca5afe9236feb01a590b2817c6c4a0c0c81d54a398c8dbb4d96c9c15f208491ec92389e40345b22dcb36b2ada85f3dc35624b12dc9001be3e6f78eab54a59022b5c843b9e6387d8eef51a197c4553aa7451d3e99ead7226881423d7f1a216817f229042936eafe4ce382bc793e8c64d77ae5ad752d6c67ec4c3f8c9fb3a361026f6ab4e80f0384f9ca5f05d696e5ff4541bb4f402d7212b51eda57535142aa75ad918ad858abfaf76d635ff5775bcf7cef8e84177126aa92eaef3560b12f14a882a03d54ffe5994353d91dfc2d94718f8c03a8cd210845d4f4637f23f9ebe563fc3861203df8cbe29730c69c30c2f0048e2880b416bd461a41057404206af3848e5cd432dad87cffdeb1b115dac7c67e6cccc8c67cd8970d5fb1b0ec645f2ceb21d5db8816d23a74f063db50bd616871c602ac231775ea654d232dcb7f842128d7efc114fcd51e247590e40c6403c88190908ab688c5db7158526106ba464dde487e8a416d53d880653592affca7aa3a01409859c00096d55dab9d7f23f5a36eb58306c0cd0721a55228179e6413c919b974cbd0890609f9c78f1a3fff38ed02b805d4340d7fb10dffcda454a5e21af37fddd3e81717d9b929e1060e9d9dcacc6b4565de2a95bbdddd5187cc84a373e32b7eca946b2ad146aafcb5362fb668f8ca4397538ba7ebaff5d5fcae637cff78f0ac03d43696f167960cf005e49d16bb8b1a8b5df97751d18ccadce14287ea5b0e280abdeacf62528ea1653fa81bcf4f0ba53c303c60a1144b4b0cda02d436a6711e14ca0320e6b1390f29d0757019cbe4c093e2617a43f5ffbe130b9d50dcc2d245e1884275e07242b90f1f2b35d9e94716ea5b5ba9fe1db880cd32cd72b6f80117f94b1ca77392dff861ff244e4ac95a76fab1fda50a944fb08cff07a0b42dcb5f062881c0752953f5cc994ff577f1262e83153d8906bb621a2fda51e9547f8a53bb554755513d8a66c13a123b41c76165fc3dd07558918715fd59c75f5e647f308d03b18cbffbd8953f133a2ba8ee2d3d504eca68d851b58c231fce73124ec24938c927e9c149885ae63bcee33b3bcee3322ccbc599bf80baef7e37b615a805fbf21d6ee62b13fbcca4e861262e83412904721f916863fdee37a85ec5afd8957be8562ccb5f041bacd8e19bdf9cab8d5ab9b3b1eedd035c2b072dcbddc67a42c516db7ffd6d40650843e3028ae341217b589ca9de67ddad9d7981c0dcdaa5ef5f6fbdee2e812834071a870d20769ea0ba1fa1f2a0eaa55d1beefb53f8fd29dc0e3deeb9b5a2facfd4404dfffde8b3cf67ee3ee3fcc88d7a76445113278a86821c6859fe6c547403da3df71de8bacb3ab5d8fb5bc756ac071d22f2243ac885f86c635c3d88d39ac63ef3597bbfcbba000ae81a552f1cdda76937eefeac2b6817ca1b2a854a1a9d530c53da240f222965920ea5504d0a49a19ea9f590a2a78ed406ca27c972562964635c852cab2bb5410a887c524a5974ee650cdd58aa72df7feefe2df68c0837505999b971703c9fa7d7d12b9493b125a6b0aa4a8e5eb9cc21c20c5566a039fab90e70b56663a7f7affb7a5ff977b3c6045f2dd21772a06ed1cbd789eaefed900b16a80c65b8b478c4c5773e17e2413c48ff04f169d11f014dd020eee30e837d31154836249b0dc983b84fcfc47cee41bc8e1ea4fa4e8eed4214b72be665f59f24951d1093bb1eb1459fd280d961632d1c24dccc9085f93974d8ccf7c01cefa614b2a0c2cd0c6ff84a52492ba594aa4e52ce208fd8078a64b3714c160d04d3ab24eeda8f483f6e6dd68c84f39d024f18e1c65f30bb64a433aaab7a4ced9156d1a5b60ce62492868ed6a3a3d19f9f9faf6b5fd8b416a2a185fac53d7a48b1b19a57b11e656750ef2f61d81917ef2f69d89917ef2f85d8990ede5f12b1332eef2f8f36f6f2fe720aa691f1fe5216b172266d58a35a54896812896a0ba2ea20757ccafad0be207172309da050547727343e5454fe5996dfb2406159fd44db30bb36d0ae23ff7c60ea5f80a57701ce4775cf3f5eab6d4c6663291098a0df83e0847efdb55a8d6ba8ef9cef5b47a7a87fb08cffec65a745e669b1693eeb1ddace0ec8bd0b68faa42b6abfb7fc3a8df27527fe71ce83fffce4d201cf12fdcf9beb9407210aa0290b9d161daac3529a73a8f67b3f4bbfa9f3381a4ed067de4d16e526ce89d775de3f4b1f3df18f739d7707937ea814ae7655397548060000000933150000280c0a040362b1603c9a84a22afc14000e708e427656321107234110c74088650831c600600000001001c8cc9088e4017a58dd516173ff35c5748e782b2ed75a52c60bc9a654c885f44dd6bd08416cedb934b8284e61d96508ede9a551db98880082b65502e14d4180a3dc77a28a21686e20d256a937cd6a1818c3465a52d7df01b43fa177bbebddf917210d42215d60ecfcd8a39592fd91e4843e7b240ed0f22af214cb75aae305509725e924e472d83ff1186c9f95e45cf87d1dff365c185c6fcb5da06ebd60f4e3cf7cbfc6f78600daeb0c1f687a00b0a21ffe5a76fa2830461a8bf670e64fe43aef1273c28af297c1eefc5178682d292d90d865b4202e5e1f6e4f5260573ed8b1fd5a7ce429c57be209ea190ef9db5cd6e8cd1c8e5822acf7a085e5dd2e874a0a316aaead1be32f98249bb9034591a4b1b4c3967a9800d9564e8f1b11a47abd2023f2321e2caa89c57007810200fbfa05477a3ff313476d197bbff8dc0e24b71105a988e16499cfcf9aa8b37874e8ff20c2364d821c4c1b9870eba6c0915eaf58bce7744a913bad9701e34f27dad1196f66431a11b2f71ef24a11134a8f36c122557240fd7ccb49bf0a3b7f5464b2274d06acaa6ef72af42a9874447478388472a05029e60493b23657a40171aba4de5eb048d737301c5cd4850f7c175dcddc4d4953a727556c713725e50df95d56f1b37c9029060b3f1ac8be7814528dfc7e5baaef9c1c134e2e9b80278cf79eb1ba31a9814aa5a2ad9a584290889b5853a9d46b62627ce05ca078d89cba35e6da1de8ed2b6bc33faf40f028f9011e403bec9fab59a17f5e40aa07809efbd9a300efc334cd730de05696d40b7370fae728378efb3b77ef6d2cf817b2bfc8df88a370473807d7c7db4c65ce7bf54fdb923f66ba8d01a067649727a1cb311bb004cfe201f8e4fad7bfa7392f143fa7ef4b587482244489a23079c999699084da4a7272a143589fce2194b8e541affbf9b3ceedea5768f78c4beb3934164b58ca5953e7951c4d6f9acac018eef4b27c35b02628fa99151344a625ae5cc9e66296a4058100ef90c6422ed045d3f9094e01454d590c6db4bd07318c7b9cc5e2917f059b334b0a142d0dbc6e348ad7d2d8789854ef6536a04634e39a1b80d8845142f176a1a5d38a449ae4370f1096e88875b5ed8535ca258c707e8132c3ed570531715bb3760ca656e47bcdb8d842eb4e691dee6ed5f5a4ef4b3cb4f5e44df318819cab8cbd16daadfa688867dc62795936ea2dd6ce77f7140012b7161561542def92c374b65191e5511260eae52e3a89d5b3ca223c02ec3d2cee42eb136bf9bd49f9b365c8e0a4a04c0a672515a3aad2551e09a8c900f1aa8d299178ca9464d45e37742b4be22128451e9a8befbf4d79afe4af9e827e99ffccb9dc1410b7cd077a387981567b71ee9b0c2bf841ff2ae1c100f10b768bddfab62c5569648fc25bb958aa8c96e6a916b51cd4fe961ce45c81b78eb30ba61553333b375cf2c6bea03e2b966e8daed1ce578afde83ebc61179b67aa47ea612450432fff2ac9adb0538deb9fd17a4be46e1a6c950d3094b958b95a96adf21ece19218ace7c3432d2f60d65abce1d31dca395d543276b95d94ace4f4c028900a8716464bfa2fbdc8a947244a9b0aa801e1b103bee1c7d1a3aa7b2adf2f23dfcda996e66726c0ae39095fd2433969b9e5d0e940b966448cc542da98a714651b2349a2352784bb22f4ee173b0e5e87c3fd72c5a2c13777a798edcda571a5810a5256d87aa0509aa68a666388cd37937d77e34918f2840a3c2ba4522b3a443aad052261b2d631ea8360b8166ef6012e2a2e7aeb4d146e021f1c21072f95d861f4399f492127634cd114d10a27b1bee1e634bdb8efc3777d05a600a2caeb7450a1790940c6837b38cd80536ec8d2035b43a900ae44d578b0d3c3b88a3351c770347430e6d732d65b22bf2bf3df0b60b590866d448d92d2088855263fc23de03f145d22eeab0124bbe589676955f41896ab4af70c077075ebaaa3ca8fd9b42f0b5548ba85ea0dd45a95460d505dafcf2f8038bd7fd488a924052a455834a4fc1ccf0a760934ec1e44bdc2fc8b516c05941c2b665f054c3776147176c2edab40b0e2b1f2685545e9cea89f4bdfa57ff443f9094455c53ce5198fcea1294cd0ed660b824af66a547e189269fce4c37d43091c248817c9e32184b06ae67499d06600b3db9b478b020407a97e7901039acee0d027e7558a2c6d53e27a3eab1e1d9c1ea067042aa0bd40d876f96e8e14023d4b814751f632c963f263a7bb8ba0f78573eefc237171bd0a555d47c2eda82b2270e13369bd4c1bcb4effb950aaa866b2053882da8ebe700a0af4f374dced2b127e39fef51b0d99d60241bab13e23754320fafdccd1b75cf2103e1bc30c82d1e933e1459485cefd4d13ee708cf5871f8ef1e44e2945d493303275634654d730a00ab60d0c084dc143d67e1e2e79276dee6198403ed31c7fc0ec204886b4c4ffb64eafa1165ec4ab947c2ea9ca3c0ba8f563d98a069b21a07ec8e304d068249b00493d30039dd5f6aeae516fdcb9060e90ec8ed801ea25202568a60b4ca0c375217f9c1085c46425b07587af7054664d415affb70c01eae648dd5240bfc50fae1d3945bea29bbc6fbd23cd1361152b10009c035370700b741a05dab909bce354b20c1a7417c610786c3453b1940d3380b77b749a8cd07906dd3e427a950c95ce26e813124613133068120211cdf09e98c934d7a0096e6e6284ba3cc0479082c17eaac4872eb2e3812de1c9088685cfc4436a49ceaa603835d712c020fc91b0e60d1127fd83a37ad0bb4140d37c4211e11bd190af53588d1b2a2b8a0d45e71e37ea67ee8351ae7d6f7194830bddb80068483511a993e7a1c6224074cf6d3fc44f7d4e7db301d191c097637a409ba03270090c4b10f8f850f6e0f87a47b6798162cd42540ab8cb014de249c71814506007ce73d55747fb8a4faca1f0eaea7688669f679d148b506070209284fb4d8e36c7094e72f43a2fc6dd666bbaa911d785ad1373f6c415ea1398b1bceb413d2e12fa6d0432cb89b4372806cd9a09a429aba378027b83ae7d03f8d1f520974b7ee305dc9e9a8882c02e84d1b368eec5f37d786801200ed4549e5d3e9e639fb00829ec9776e260040ba9f8815aeaf6555a390b8e39c4d590b6e9762743a7ae144a5e54f679d1c2f38c338abc817c68c64b5e263713550f4d14ca9205951c139b669cd133b2c145814a29d596a739b872c9c70c32f6d59f07cf7bdc8f93de8fe8a1c115ad0c699a83757e33ab198830316fd8b9a1bc4770a47ac65cb381aafaff1576f5e25c2c5773f4f2861d2031c75abc460c75ffd8510792dd5446cbefb1bbe7c803e7bd2839d8bb2ce31f4813bc20688b3a349e67e06191adaa8b16c090befb2edae40c45adf59460922563035b64c6c45d35470314028c3e3120d952288e9ef8212a969183c75cb38393df8091d61c67a3d5dc341d24a32e87b0885a20322e413b96e9ec0b0b580454d57124e809408cf8ee4c6b6d0abc47ba679cb99c31d96ea2c1ec3d09b1483fc60b58626a9da6ab08d46412d7554f6719102565a4c7b136e3beb9e560684d20b6427783447b3f911336cdd5225d5df64af4df3f414553b72509f98639aaadde425c81f129a0aedd01668106a9a9a29fb4c2005cd6c327521b88674fb64e330e2c1e65ea8a67e4cfdcc805e74a1091fcecc09a4904f6d6d36532ad4313cbddac939b9f49e30edebe284d9618171844af4d28cafccbbaca0d1e88dc7d428fa8f291228c9ceb492f4f2fb532448dbd2dcbb2152f75317a0dec8255f0f68a20e61909d8b730b2031d2951fd3f10254d908614958fe887a2ec8f0f0361ecb3649124c3b2240ae57fda13fcbb1cfaff1fd624cbc25b0094101bd6fd645afbbd30e1093e4dc373c4d0a208db9813d08fe0220e477b15a28d4b8dcb528d9e9e78d9db27a78ccc65c3be912962bef251c07565405c852c3b1c1b5465e424280420748aa8a4213f622209b2bd8d39913e9d3a4eae631f768ead2e241b2a31959740e534dd8168fac4a2a385d9a5fcb5ec55d4cfd4df004581f05c6f8eb48a943f02eb55ec533bd0d3257a7515404ade3718955a4b7404bab1ade8c3cc80bca42170647878974f57c88b0c83fe2a1cc3abfc1cd19b168c26069d205f1b87e2dcb7b971ccc0e728a5d08f6011be1ac45a35e5950558375863a53c770b366f56b673c401265445064a63e424ab0637b0b50d3891d0350027292768edd50ec4c92a6211d3963d65cb38845a2e366a477674a7aeb8447a697e358bf8f04613585866dad57006182b04747caa008e265ff748903534e5729fee367b48b4413ac4954747e900f1cf2bdb2e7dd609dea62f6b7b38d42df814e63687ac90296b22e075ebdf397b4f4ac564314d71b863243a80c7db1b4ebe23ce0f454ea593c46697a79708cb76a6091d063200b71af2f048f6cb40a65f51b0472e54de5362914760d0a4e61327a922e0a29311527a390aaaa5fae42360279bd1ba8ae5a3f14de66caa7c4dbdc792d9b45daa473bc86dc5361a9846c7b1ef9ab3c59d3ca4590e9d1d10cb359933451b02f1b9935fd310aa5e789eaa403ad83711a5747a40a2be215911f3f51b46eb0b984163c6b3545fb81b3ad0042b1380d0e4dbca36b0c5495753182c264338b9bd496c233ac98dd47a99f6bbbd3fc4e38877e38d2495cb58579d0b955b657d27c4c4c4f703eb9ef1c4b8555ca7e8db3180697556870e19670af909d53f35369f016f8bc852418cf055dd09c0f769e904214576c836a86512bfcff14340a7c35e36f446524f27e795e474191db65f611ee87704c3707c230282306e39104ba727e3da83d3894d7a7884d10d7b0c93c36b1365b3fa8c5a5e812e1fdd339294be421bd63ab12df2fc0ae8a1d7ecf2bcba3c4c088ed78df1e7eb1a555c42471961dd9000f48920c1d25cc64c2dfbd9e637a3c17f4cbbd8bd9f58bae59b54824057839017aeee22518f62c377db1e355196f523e932facc22f95e8451e08864238c6214c0c264a0349fba88cd932e85a467432d514f95e0ff3dbfd951439b2a89c047ee0a32d0c4d452024348640e210d907c670449ac41c7567edf3a070b4671a87b0a1c22e5a367f2e4b9aff37c357a120f66496abccd55b2361e4961e85486122601ebcd36080dc7d025bff66870eaca66355c2a96ec6e9172c6c3c2d37779e4d396108920786348696341f1074637fe44e3d74df701e2c6dfbc606bd4311bb28d2cee20dc60419b934f2c29d8264d91871c8b4466fe14cc433924895f7c56ce1e35de8fcfe996f0e2f35901b0b864a9a9429cf864a2466474c03cba046e434dcd34bfe6c7aee7faccd304337c4369b2e63b0e5ea353bf400fe520df42dc9605cebc1da379cf7b0cb667b0320a9692300d684b51cd44d69e7d00aeba305527e87219cd8e76eb94f73161d7ba5cf45a44a18b4e85351b655243ca76de71d96834739b7a9c16e362c5310510c01ea1f999976ad8e26fe0f3d14ec2777c4fd73e8cd6fe2fef0d475208a00c83dca1bd83d76eed1ff042e9a3a4881a487ebcdd139e6db6c4645c9aac8a91545c6501ad556299d38b4399594e750c1c27ed0678190dfc95ce06149967648515571bacb6d3e012d8cc6bb6df8d6caad7e2b8fed577e7c17d4b18cf7bdb20645112ed0a290739c32b9d0fe4340dad7d55ce46092cf01dcf1b9f29e242435f312329949747993ec1709ac02ea28d9d06105ef8994573942020ee79bfbadf28cee938c39ee4c4a35d7b2058b1c78a593a99a92af9e35451659d24bacd4ac8011a3d1c935cc65e9b03d17e438ceac1c8b259ac5c59883202c48bf51fd4fe4e8e26dc2d86e0cd1043fe4f935840c1308bc8bdc8b79298e272c53ad9da3bd77df0e4f808d2863f2365df23b49094a57c82ffd71596099fc8d952c4390d3e41ef92bc81e054cc5390e0b223502e4c791f15c12713676baea8b1b109e16ff2af7620ba12569f1349029b6058fd8d2caa3404fa031d7b2a3b569e5f45d42843efdff21faa5684b56aa30ef85278a85c67d894f2486636b74120296f04ce4cf50b965258d2e274e03f7784bb1259515976939489f71ae4d493fc2f8dc60249d2ff67cf1ce54d69a63d169ba697f6bd1b36be7af760a3ba95b093de7a4e3625ff269b85999b0157a6828c6b367c25eb69921c8f48d4b80f18c3a435be9a944a587e9a61a26773a4365fd7d1cd343bed38d706dd8f2049ac59a76b41e78bd36f6ec8f4584ad592efd5faa0833364d9707c63364d9fae3c332fbea9d1d5a5beed1c524ba166e77d69dfa1f2783fb30f514145132ff63e901f06a06d3dcd3a58515bbfec94c9c1d7d431e53b60f9fddf586367d3d3e545730616a35e1b08210b7732fc3c21d83d71bd9dab203e668b2295dcc3c24e4d5d501b438f0b0a508244c29eefa3e60c7b387d55dca4e256eda1df02c9650343cb5a5345895ae92214424c0078fb39d3f7e60cf2420b2e0e4339e5165063894a6c644612d37123a15e7cdee982501a4c9dd6a312910787ea0a29a746a5f19ce50318726d5c033fd3bae8c5533490d85524fb5262c98168284e2cf831b6b09e849167711b1c7eb08b1dd529ba52aeda9c1b273000f61f9e03fead38bce73d9339d548c2328c50920a57d9f008558f9a9cea3c05ed28c5b64560751b6c2af23a082428be1438fd8cb9749502ca1d49223c471c534f3b8901aac76f12bc4f664945e7b01f547c97b4d805fb0365660c300d47b2542614e0c98c3f69a763d67e61a04cb5cf75d32574245890713cf4ad507289a95c7e0f5c4134f19966417bf9b5bca8b10a815aac373092b8ab2e6cea84f3c1f740b1ef5f5ece641962eab202c0bacecf62fe87c5a905f5f557f911dc5dd1a363b0d130130308a272208fd2a5f1fe2a6f9c478a509326dc8f77d136cf3f3b3a5f7fbdd98fc1f7137dd9fe2e7ae22044c80a12da31b77dcd804068fea15ed4dd6f3b19996ba6d4341a281c7a56f791158f2ae96d418f14f716b892d6e9d8f1383e08f33eab2d2eaf0c7ce1f7ee9e14da3b2ef46ee794f95befea57bf15d0435b6fcd8b254e74ee574233c1161733dd1fc483b1f2a00c9a7de4511b0d5ca543fe532967c1e9e94dba2ce6841a2829b3259ce466f6dd394b2784e9e11b43fcfa5a54897d0cb82b6a2edb4105f3cce4cf68b5b2b3a2b77f499b3a89d1892b35a88c00ce6266e3ec15909baee94282da0dfd1109f23a58d91e15112ec2744046914ce3e587c0871b6427e5281ce95c36487acf190348bf547ddda3175b855c9a0f460467b35e0048e4c517226f35adb3b89aaf5043699266a2bc77331b3342f3cc150a8ca9e6f700f9db5006bf63f3cbca95e994516fc375b932a30060eefc0cacd844b2255729efea9c69742a943b6cbf2bf2c51d50b2140ba640a74ba926e4b8a1fc9691df1da3f2311b6bbfebf30fd9b2c78553f781de8b7dd83dad9d6b721d322dc8cdf640fc3095720b20ee922fceecd0e7a139ab930cb1bb09d6b83f612e32bb2797a2b7fae204eca9720ee7b3cc68639fcf1f2c2c21d6208d5355d6816e630e7653695dd9d17f914c8faaa5768493e71f2a65a174c64864bfaefbe77d8a68bb6833eff071228343c0bce822f41258d0c503a5079a2f58242327c042eaf688f2ad84fb2393868201d83bb3b02e6ba54193baddc3ba0a77358c2254f9988023f44c7816be3c66023d184d1c11a137048a2f55a86593c080dde93621309d9be30e071b12c8648ae2926346ba569f38bb1d98110c3bef65c0b11427c57334bf18eac9870f3c041f0cc95d159117e7bea6bd8858f49428bea15c3af0c67344166dac0ba5feed217e9ec965bc4eed8f8744eee1aaa14cc05a03acf1e2108cc3e71f6df1bf896b9c419d0cb5752d88bd176b3f6a5b43dd57e968770f5698372ddecd9ccfac0a13a30bece9c305f82eefb0ca4c6eadc02254c85860c0832d60435c7b71bbb9834ffde7024f84cda445f030ddc7a6fb7af451bc80c9987da007f013c72803d084c46d1105c83bd0dc3aae5164a6dcc5310c3c57bb0e43611850d2aeb5a30b4b18c74b98af635f76727f8d7b4b593b14dca61a358222c2e5d588dfa03dccf00f88da5a70294fbe644785d1442025a795201dbb60c8ea89e17bb7f4734d9d299a7bebc8141ec997ae6c7ace9a0d7f7f934c72c719a94264e6ae7bdafd87831edd4de001f6a6f3c62864fb7b9636bc2dba8fb69cce53b5560a67faca9164414e2df5189fed0426f18761248fef023d3c0fe763c9c603b9833aba2db16eddd8a15ec6ae960ab388437044feadf0bd5ada03a7986b60e127ac99f2f2f9942a489bafdc340eddfc7487a6c3b7a87976cf6c540c4ab4d3f056f7441ddd81c08668b0a074b8117deda47a42204134a598ec15ed3e49735093dfd3a29c3177e24915fe1a650c1bd801036ff41d7baeb0cd64d4378a47fc56f9182da1c75a5229934ff80742a4b01c7bd443f9b9bca9ad4b38d693b86c15648bb29c74705f5cae1f360a6ad49c99cbd434f6e05da748d3adce522079017baf0ca3fa5bb20fc83755f8d755cb8b8cd78d2d8a803e3f134bd6e343036a64732fc08702094bb7c69d0518d60fc239da90fbcdc45e89cfcd05291afc8e266de3e20e0a52325226539f1a8d576c372e759ee78f78615d3c1b14add56846dc4c680eb4097f0dde6783135abeecf8ec0ad4d4cd141f8ee517f2abdd11d745e380727d5932395a97010317b428349df5e750a1ea8dab31eab93de6df62f8cb9b469006253cc91d2b001eeeb67412f434e81c9c00ce486160da0dadd512b945e6980ed1e56870d2faed534e1fa311f68c305c60295e03b1104a0be7cf7ade7ae45192d6259238806f2d9cde03be5d03ee6eb013e6d2773635786d9d85d8b70e4f23f71e79ce7a034cd6cd8c130db3147bb2f1b9788179f7d648d13425e5b65b33ae4dec686c742da71e61dfa0e9ec3859226f7517cea9479ea66fd00565158856b5cdeb8e3923d44671c05944f08c027e9a3e0ced3886d8003891d40ff71e114c46e741e679639ef4451a7cf399197fd1b9b3704e96c740c8fb9b0e73adf3e9d84d6c2bba871f3db464127dc6b7e8e8d87d65ffc23c7434f7371af125f67df4b85f1be53824939dd1a047ca897b1bf5a8f0b56ee84c5b12a3efa5dc4506da3c6ade2b2dee80993aee3a9d9c70ce7e631608e81f16185244150d5d6c6bd6f483b6279c5eb005f2d208b93a9e263a2221eb64cd4c58ec5fa6fbbc7fdd1fb4a7e75ce963163229e9d2e2190f06f63f73250653c0bcdb18400ef4481324629da9b29b3dbe5cd035aba49fb12e26ca43724ab2d7040c246b06be8eddf1ab1e801279f6c4cc1b9e4995b802c63ee33b885120b1c35e41a91ce3b8b8a62cf2957d12e7226fcc1e6bb63a0fd7eaceb4a912c30f32a498b4574e19aba24a803f91eb9e980d4f792fce5ece14e7018ae505751c97a4ba96c39e74283c8cc182d6848d7b9f22c219cf8d2a3567b1b43fcf360bf88da8f1881d97ba0b79f627fec952025f4a956f649afc0e299aeba8bb256606c244b6da2030864608847ffb384b86bc889f6beae6d33a046722f5ca1d4ecd2ee9a28d92951c6ee25243580306c321c3719f13ae2e14d69e395f8e049ec339926f382f9a8c3e103c8043bd2b9ea835244f686db62604bc86257fb595d62e1b2b3d61d6848ddad1cbd9741c88bf728182fa164b74f23d0028a56800b892dc49f486677596c294b7ec900d5d2605c8545a9b4e19e7dca2aa245b580c33e2b1227f69ac3acc7d5d8426b4777f03bbf5a21cd940874bb09624486f51119d0445c2530fe2c1e97227c277aaf9e847966925833d78862a37990087d24e6bfd55e4ca80c3642bc0aff4bf577a8476b4a9d6c88599b2c7e932efe894a16ab387b6da8b69412a9ab5c5634048fb1aa3df60c3c2e56d39e27ecec38e2507d5056dbf15407e849ca1565e4e63ced4a3e026d5b9e1f36c4b77d0eda26d19f0aab29afa42513b5eb209bd542d598c9505ea140a7c518221971d2eac7aae166ce50765cd83795e0d64d0e24882dab4627c8befe5cdd456ddd0e721e08cbea589922e65d5749b48827de4d74aed8792c1b4fb7a8b3204851a22d8f018ba47105de64cd79342bc8c7db7f6cde64dd8482d493eb6f0d8703ebe67e7ad4b38a2ee6866dcadcaac3bc5632a4194845b7dccffe256b098b23a946eaf2aa8b294284dad006037ccb55abca6c4dd19f58cdbeadb0e38a746479834fd50b49aec082344e4a7d32c8d13a2471c14c3f5dc1d7d1b791671a47cfb92e6f9bb51aa803127df309c089cabba0563e42fbaa081c626285fca90d8f2d66adadbd3f40a788a210960ef749ee9d9275610b6db1bcd16c4b894f8adb2b1cf03f3269590f7cf113bd5ce12832a3012378aceab364ffdfd48e9e71cb934029d537328bf67469850f3a21386547006c4b90cbe31976898d8b0d2476f106cda0dcd84b25c5c918e460f4caacc12233c2eb90f0db75ae697f0fa5b329709c7272a79e1fa4da6fb2e607e96ba69933ef3c17e73df7d49db499a52999909b75b14c71a5a99368c77f72554ef990081dc080bc66c67b0518c32e0d53898c370f5b390ad9a621a8d7825a20155f9078197ed216e34fb953c685638b02f90c623b38e95f9eb2f204bab7a3157e2315f9bc34422c0f6c2adf7d728875eb052cdf8b8466cbf1418b23f257ac007d7392c3bc10520ef9d4d9540de9c5278ad219dab47fd2515f7573ab60df44d5f0c877b8027747db7f6215de6016fc6bcdecb63588d1ba14e39d58b127256750c07885b800069f86a3a4e6aae05ca790ad995160648d2427c1548be800dd2337a20f09b5c9fe18a327f41a61c91bf4dc0055bb83fb3f6145bf218134aa53fc18402b8df3f90631fa2a0c8f463acb5fd5e4c0b0376b65591e9868127f7275bc994cf8909fc927998a4e1aaa9818d4110adc19a3c1da13a51b619d654c40b924b72812ea6a8a8dc467f990d1f31c3ef30d0bd359ffaf7dc5d66a98ef3f4b887e96e364e807a34e057c6d60e5f2577060c019c998a8d3d45a9ebb8cc06749245f6da7309153751e1b6fcf817f67f6206001f539d05f5d6ff163fb6fb5ee7b53fd74ce4ca5188a76ba72171665538c457430e013e7110810cf02ad8855442297b1f2adcf584065dba0216bf60bf6e142f2eb6a1742b9f78d83285e95e6d985974160af989073ec96d428b0d51c3043f262c53b2f87c8ba8ce53e911bcf30c28bf4ef2a19ef5c3fbfcd808c69de91a077e183a2e5dfce60278590123a4fa38483e80fa6e21a4f374c9be3962053b11044570a70edde2ba6d0f1d59371484881acc708ced3345a334691fcadec490d09914dcacddcf2441f83c95a70b3be3952b2f1463af3661705d8b6cca25dd6a5e83fa8f62b9a25dd4c18cb623b5bc1ae897292df989a797ab206f6e6526aadae69395980c156878dafb980514fdeeaabfa8f6e30970189dc966ba2aa1b3d86cb6e65ae2fae8dd45b4fba2fabb45fcf33b8ba81238601ebd7989289b7b02c8d3210938900e6c6b87a43720af64df591198b246ba533257bf7c2c33c2dfdc3efaaf1ac045bad8e2d522b66bd70e979faf4c42856332f67edc288fcdb994908fce0f8c6fadb2522e97d91445d2003e0dd6e41dde63bd082f76d014cc24f50f3711fa1594e1453c61d3bcd5d3502b088ffedc4c71fc9d44d81fb9abbb5e27ab036711629ee96b5bd9bf1ae6ead20611937b6d5a849ee441e0edfdc2001a67d15ca85cf7e1481eb2f984e6ac1ad5d6decbb2655c1825982d9bbf5a6884feda079c23dbab5a7c7b28582ebd672ba12c8d5fcb6c413646f3f8a9c530ee0f9dce080cd49c9cc0def8928817ec08765a37dc1f6ba2cf4bd1346172c779ef3012ed0fb9ee26039c7dc04c32a01452ec7157ebdfe80549e17961523a0bf401849131d86915c84e28502caad645d2c444cc0b2709e83275fe29414ce1971634746fc4f9682f06527d94d9c06ca3762ef1f3d965780741c870ea8d6a8acd31515407fa8aae0cdfad39f460c971e4a2c7c7276321163070611fa0a0ccfcec47a811b20a00590e2ce5b42438c7f9cc3998591100129ad74142f1e1ce018110981780d2b928b10d9dca871f8050b0507d7efc305e12e101c450c8f606c761e4d6cd38c0051dd2416d72e7d58fb88a13e968c240aa16fff617154add0042729c7ebfef1070782cbee3388dec3697f0ce519f07c0b71820b227291c0d41494644af1805e8ff08349593e78256983f669b8d727d3d2a42db853ebb9a632d1b688fc44681c2c9e812b5f09114beeff037c72c7f4f438314940c61eb2c2e03f433134d6e7eaa84341cd86c96811adce338b54b6db2a45b6cb6c6cb8bd7730cae480c873a94230e88b055cd04e411dc3f88d400e835d276d49637dcfe9e991342f8124aea8a06d79abd81e0a926c9980863a05b42583ff35bd6c5308152071d1e3539c00b528f8ff136b74ad0c9b179d69b148924289de496206791a2a03f2e390000ccc9fbacaf355935b4989baf8fdadbe831963af4cc539727b89824e4b8bdb8f6d02f3fc5156277dcda27efd7f60c12e4111cb37c257400b0f25806ea31f91956f1cb73e7fd4ad41dd17d40a42bfbd8e6f0a9f6c09d45451af467f8159a47de2745aaf6193c7dc1998f0b4c99a5c5d6ded529cac189e70b21bc23b56fb68d2cd363713326fe5dd8f9eb603aca8b31964dc44e2e6f6735e827b041c8927e74a579895ff0a2affe224271210e36ad7b2a10b1eb090b5f096c41a7a69bf30c12b1117adc2b6f5eb1b0eed1aee8a83ce82c028a604e947a951ef5db31e6ab61696099bc77f29feb128d0c03963d96e1e26e919a6921543753db54a9c996509946a29f058a2c4b43930b8f705902f3f3e0a6bea3bd8125e718d08615d98369bb91857a64aa48f2afabe117dc8138ec8814f5afbbf6024a1390ca610aed00780e4e44913c12b4e02d45c25ec853c36d3afa51260cb6191a08bb90ac8deb6ec3f672688a20ae4d7a62befdbf43935aa6706387f3903583543cf610fdbb6c6338fd43fe0327a9267b6308ce3d64c29162081f4255fabc64ce10b58212b1d185388ffe1bed5d130859cd4f621da9a06e2976947d286bf919ebea4a0be54eb61d7739bc0245b26c731c7e58f4a8d6eea20f6de3bcd05f9cc47a848cbe40eccc95cd43ab99dfa00d7442ef0a17c68d5dd80f643908b36b1dbd55368ac85e05b2dad534a16bd3c83d43ae01551c42e58e6d11c90ae4d0d2505a1610a66af5ac855a51d3216eb1d570a61bb11a5052a3e5622a6d47d4d1c985684ccfd27788153528f2ee461c3bb73d904a0c45c89fd8ead3569c65ce89374070588ca007594db90b9ad7d20098a4a501a89beb730e0e0af911f65ddb8b254855160f2cadc26f7d1fdb292306201445a0a180581affd2910f279ec38fb07bd5b1224660e9fb60bb6af7006fb521212f742aeda4350c4f27959aabf5cc6cdf0c27d95ff85cfaca4834f9d0adceac380ce8d9ff546e150108038279ed1b4a6de61a67e99e638b820f6681a2af569658ae860cdfd4397716b6c5ce59a84acc1d0553514dbb8b8a0fcfa0133d384ad8ec4cdc60edeba54c2779ef490cdbf73f2826474a75b540452284782a0fa18e941922bcd7d945f38df3ae88886ec68017a72eca77d8b689d70070a44d8913c864fa00838298613137d408fb8b607adcfbab1623b96876b0c9631efcaee79e5120d9fa7708e771cee2f572ff3879e0a3719a840251418a8325ab00f7be85bcc8f9c4b978f28ed1b7c989c09417c9515fc67d3245470b2ce0cf526a1aed41824914df193388ac74236b979878229aaa2600cbfbbee0f451d0e5159654222a8280e1b6c6a02e73b5f19c28bbde2d6e3f5b6386b6a2eb2ede89d86c5a925d9a8cbf531d3ffc5a6a14f7be837d1ce917dc6f2d9030184816883384d393812f3a959a493a77c448f06a57a62b85467302d93f2a6f00aa8d1c0d7610008d133016d1c7487c226b521e40546c290b2ea436b56c218854c898a894461648062998b837b1a0b804ffe079f9e1279b5d1d900b57eb1604adeaba520f42e639c2153568c2ced6614568cd71e32a58f3f946a3597897b450486d99850ffc1f3e2fc46036d439af5423713f5cf274225bfe15fad0fb2ba48924364ea42480c023842af652fbc8b6bc210d693d00a6fa8e0492a490702496ebceb56585e6ef9fa93e1d4e39701eefbc9a6f3122084650a8c019632e2644c4193031897ac91549730b98db696570e10242b04a2d33a29420a35e0d7738684861f0f5bec23cd64f222d3c7fc726882eea28b768914c74cbd2bcc5a3cd1f9865adad1c4a45a189bc4ce3cfa4df0d39ac9887d80b352727882dad4b842b106d2ffb003d3bdf159b030c6598f713ec7422e6cd0a26b69b1c52c20680d7d11c0de647842328512880ccd9c076ed969f1870c706ea17548b7a25db15151ab4ce22f7bc2a9f26580006adcecf9040f9664a71706c6d158cb067e086abadd5cb754da93ab3a51ad013532c84d8d198ef887fb58cd5174dbb996a0627bf3f0549109fd18060b242040b19679fc80d32a0f3bab83eee527b1c231ea02596f027c33da42c1b1143ff199f793d067e73c1056eb12137e1ba530df963ba2042cac27c1ddd8855d155c1e74f52841e761576b158b34d1753c0da6882fe769fa1d8055306ee078c8ea62323c19c37dc740ae528960d76d62ec0d914115df95ef34343d842642d0c8de2385d382f5f6f4151ddf7ac001002c14ba586e51e8224c31786f65bad82b7a66005e726d4c41bfb3d06a4a69a8f383e628d10c94e8911378ea6734dbcfbd10e51c90abb25e669315094ee68b3c0519aa3ff1d81730a793a910ba02ea1679b76a713623011ad0092c933fe6924234c8df402172698954ffed0358b7036efd2c3f31de8c3a0c840f0eedc280dc292228f592878cb2df444697a696a0f48d72640ed6ffe1c927c78c3a2cb4d8e69d3a14827d408dd8a3032a63bde63e33b410ea11922b64fa45a634d08ef2209921224afcfe8f9b814670128a8535a8f9a026c3c1471d804fadfaa833d8d89c2b24034797342c4b1ba8ca3d0d14d617067ab4e467a4a50ef355a0c16f6c98e523380f22b5e22ba6933661482c47db5ebf70d0002445f10e22be6d0f767ae9bd01f8e4f18dc0ee75625bddf809b1879a3357a908b8ba93f771f3b7071fe47b451805af054e18de119f17243c77d99d9c0f8cdf28b752cb93cea820e70fa829d04a433f4c4cc0270c64db6b83bf607c14d9b16c7c22375b992fb23688026c405852e2344527de8b87925101f60873a472d4dac0584ca4943dfd19b5fb8daffa92eab5915082eccc28e4accd85c6b62e64b1bf67dc2ad52304b6a672b770c9e16c9481da9f2d0587b8631fa4199d96d1c52aae6482d80781970416007a7c029561937a3e9bb3e13d9bef41c4b822b9b4f4e37d833ebe450541d7953edaaf594605351914a8c081c4146ebdc19e89db2500d495ce9b64b64c26b848267f2b47f72d98e2ca60266db58756c4eb46c6e0d89f5d691b0fbce1134ebed1aa222868e8fab38cb34587ee98c3b42c03935d76108d4509e2fe67539279cac13d4aae7d67d030badc925763093467c89a4101e918204fac6c79e4c104dcc91efaa0a39a8c5fbff700b68524993c02128c3cd58b931ac62c773d6eaea6c1e613eb9280bee13108d807563e181f4594e648be83ceafd651a6459f470d13ca5e4355a708c6192f10a68223ccf3d7760d82eccb06f1591b960b5d8fe7279edbf639b685a37f73a8ddc4f6dfb81471c5da1b297e4bb21d1459c11b6f9e34aab64a44491e46d61526fae139e0d88f127c8d91bdcb50a73b98a6cebb4be5cbfd194960704a600d361232470b76eeaf47de2aafc9190e7a112c7374c34cc0f824de0f5325eda020002740a11ac2ca98d8643232a402e3ce67a5c20790da1662570033d7a343301b9e9e64a32323f2219ca7280f729e76724957bddd8d6b23e5949418ff6c36d973ba4660ab72a0948186a74a06e7cddde1a0cc107fdf396f614b6580feede3bfb86ab75f57707ce7412e0fea217450b4c09ecd41c244b982120907527e7f5abef538de547ae7d426b5f5191f6bc59e34cb7f78dc8ead2eb671fe6866b50ceee81c9c91100e3594f84475dcdaa6fde1a4d56067afe228dc5bb0a5a4b3ec522328c9052eea12144c624b02ff68580fb4f6bc8223fc80570e9bd9f18f61014548e47a4f87f24031ea79bf11098e6eca045f28be8c3c5f58ebc27b79e232e2cec32883c377fcd65274baf86ae26227a6e6679ef4769ca29f175eb619f7697d29a0c7c742e414d0dcaabde8334b7dbb0f9e1458c55854a6f9f369b5a40771371afca36f906ff8dfaceb925fed0a37eb820a8116c7e16586bad47459fb5db55d85aa5a6566aa6d02ee9abbe842b69de7594f016042d36a1e4e3a93aa56e51ce4f6e0d5c4a530635bed125f5b9f332537da2b7b5f6c5d66e34471f33aad5004712d09365f0199e2aa820f4613e09707787f41c9f020ba8dfdb71549a60a4bd7fd353032ad9074dd1f02828c2f8746ce7a15c6971726a78a3d6ddca8e615db417cab8c60d5542949840dee9c12fd5b03bdfa70d9434579621a4f341e419d000793e514d3ac82583eee180e8364c6b9ce1aa9901b513f7112cfa9701d91b247e4ba8e66d8df455eac1eb95b1523165c6cc76ce858782d9b19b27d3c1778b7634cec59717b784be23f2dc591df4391e920fdfc02fd0fab076837d14016861902a2bbbfa5e230b31d6c37bddb62a8ffa9adc8035a1dc563f7bd9b1aa8dfb29a09c9f16cc5b247aa113f58814e40e8bec2c5e2d58c4b80505deeca0f7f9834a96da26761ae9db4b2517e7101485fcdc3a1df6f09349ff14a68ef7ddee90a21f6cd683b1c38c9c671e20319c9325d4a3a762809d0b90edf31c5966c4ac8dd051c066da30a81788d9f75e5db9fbdd17784ad055160a181392fc4e2664f43ca04180e989f3c58cee90181821d436a286deef75c239b0690d5b93169e5c1037665143e5ffb3f9ad39120d388daf06b91a45e33ba1f82d1d21ce548490c5c395e89ff2884317acb39b3a5d6a1cac8855576d680d84e7682ffeaacf73adc28a6aaedede99e52e5db1c83b3e6184f24fc873feea82a8a72140f5c55448877f693d9f2479be016cb9cb3cdb3d276081b572c9cf694d26738e2777e366d29859df5a1d2458f55626c6ee7730652a149831f54650e60e6bb6e257626bec0cfcd445cc104d863f0e11ad37a0814dc9af842bf66d79b8ff31b1c1747c329581a3ee490f364882144708978eca2cf54e00a90e9f8526128471d453982936dca4ae61ff6012110590edc75cf4d213e03cf5db2ecf7c374b305a64d5a4b8969324e79408971c1f7dd8ccc70824206d7a5fafc18c4484851911e21d72fc7bc369fd613632f2066f6552f06b08544fada6a5019796603223cd8a6dd7d8eac000d67a0f7d910baccde08cfba1c7f4c91e2a98fabbc37c0f60b2687e1486cd321668769f4056486c374ce682bab0c1cf924808bd6dc9d7ad55c1c379bf268c035c807280c907c969f116c5cd2032a8f2a835a309a15a903b999c6dcb53c4ecd63b9ce0df31b75cd9af703b44360461bb311bb205afe39ad47dedeffa627a6be329377003030360261d43489fd5447e57b806a4d445ad02f20f3c8c9051d95ba0fb2559ea4dbee267bcb94520a030822081e081dc3152828a70e45851f486514c94d5ffa6d98caa7cc16144555220add6695a84ac57a95964dbcbd6629439ef751e0e61cce59b930ef19f6f5cfcc9beaf6b7d0f7d7607fa1ae79b4bb83463a5d91f0e5157e4867b8a20a81200882e0ecc1e41a0a85c06b2847a1ddd7be442291177a0e79629190be4274baeaf55adc119ac038e246e5b9dc0e0f813f3ffce33770e4d05103a752cde93f3b4434e7800780efbf8347c744ef64870fc9e576386063fc835beeb6c34ba2e3a202ced66e3fb79fdb8f6a48ad6d3b3751c8b5a64972fd3b18d72c512a944b8d44a1fd700cdec606e9bcb9833ffac4906b37b59aab64f778bf021f8801be079be520ed24e08f7d03430adeb876e3da8d6b37aef18d592ba94fdd4c2a9a14d1a4491324dc346131a283c48811234c9ae5dd3dcdd3399e6e5be536c2bfe1eaf44068a2ff9a0f43d37f1fb629f51fad39d1453dbf49ac216b128de94fa937d5a03ee55be553684dea513fca52241a22d1382ba350298fa2a63fd11a9537a54edfd798fe84fa14ad393d8abe7f2aac9457b154bdae705de12f4934a56022dff19c0eeadc3f8952908ea88845d9d3b00cb0bc2606891e5c26be17fdb7b3113ff8e07f08f20eb86d8461beea7e427df5fb3ed5871bbee9446d9850946f7469e1f3a344741584e94f6f434505456d58aeaf85aa450bd577da14cde95129d1dba0de947a151e726a21a2525e4469529ff234a64fa1ebadd48f6c4389e1f676ea4f2f4a21ad8248fde969527fa29364a2364c7c6f637ad48ffe3da6426d4eaff26c7ad4d3981ec5a239bd0a7d37fd29455c7d0f849612519ffa032c2d456b765020b45f1a8a16c15fa0997edc1c0d1a8ee0b7aef04593b84e479d112826a9876631a53af823b173e1e819a86118d2af811e20128de8ea87d17fef8348f4de7f22117ca6015224cde2125d240dfb768280723fb7fad51c1f6123cd3212c313928b908523758b9005222fea16010b5ba8cc43a2c1e26263ecaa8ef3987fc83e43ddf33c8f799e6f2d1efc6f632a0fd2b1ffa3ccd3d3ef51ee115544128f17f38ccc730373ee4f752a120fe999a761a37ca2fa8fafaab2faa16b84c87448e4fa7d7356d2cd0de9866fc6579d9e3be987d015cb37a15c6d21daa8bec5ab88364cd0a86c443c21111643c671a129038e3c95f7279152502614efaba44fd1f143d17156d29f28e9271dbf92be44c76755129d31bc7f0e8fa9b4f811e509e9b73c30a85a809479d695c554f916ffddf8dbc081f1ababbcea6954284d8b6d7d7486722d441591d44328573d8f7d34679ed31025640704d5a6258c339d38f1e1635df23b249c78de77abd02a34b2d6e4795e48dc75f99b44bef196fc29fad859e947c7840cf91b90982d23c075f4b29d915e7e0eeb854f1265eb928f52923bd62573589c4b951f1d5955ae0e4e45c87a30629cce896f656565e5064d0e4833e3b1efc3ad2431f9a50c0b4381afceb0330aa856be63a5f7d06845be649ef14e8aafd993c93f1312b7be9c4547f9d24b145afaf685a363eecccf3beb9ee9e883c5d4a806337c21e494e9d023fd007a2391691e01fe028b243a8a007fa1f277747d705dad74f79ff1bfe11fb258a4f49fc74a74a65b8e9b344fe6e23a914813fa8fce34cb6f34cb4337be6fce1b3334334d7323e4cddc6059e1950f873bf3e7dba3822ae9e26614bcc9bb54ca0fc97cdf8fbe66f928ab8fbe1c9ccc51e254aa4e0a21a90faf12489d2e059b80e6b3bc983ee13eeade0b7da4b09dc763ac50446b4c7aaae3de6e3506b0317641ce2da7c6ec04b3c116638c9854a8557f956ace1c1e55d004ea2139ebf2494bbf3f9cd33953b4618af9de2a328d4cf14311676eb20ee748618a1e7c1758cc915d443ff0552a1ae6d80dcaf1f3e32c15692e4f93826822dd03a9441a06be01788921a2d86ac99091431df7677f6a786c836e5fed1c6f0599200d3d695610893dc63715cfcbb6d240284408b70053c6b20c70f6a95ad5aa9651655b6357cca5fd2853ad775e47590577a8645e0f24114d601cd13c3efcee8c1c3718c7b71739735c1f05eca0face38f41ff82e7a042c8c0cbbf89bdeff87c7509ff2fe3d2f244788a47e0673bd018a39aae3f67c34bcef26d118fd8c9d9592308e6f23712472e9c11f5f15e551eafeb03be9c3118f4c27d3b7a0ab0870e575f1cbeafc1693b6789bd4aba88d16af7a15b5417d0bbab4111dfb866730cc27eb99e3fa7c504c521db7876fab1f58f429aa4f799516afd2e25578900cc07435001e270c67b22845a0eaa36b6f8b4a02347cd8fa91be75716f97469b1a5202f08fbe34ead1a4ab1fe687efc3a4dbac17f825117cde018ed8d5397034db7e78cbdf24aa88ebade9315ea265180601ebe2dfc342f23ad24414b0aefa993c530e606e93ff0352ea1216ee3dee3d38b723477670471ac6497c788edc7c5c704a72401d08b66076ff85bcef7ee45b16b36f37b71b3c309989919c4e489cc7857059ba3985c51cf926b4953fe0a250e5dfdfae3628ca4fdc11f8051944e6278b843b3e42f5e39bbee99b1f3ebacd62ad244da9b4303b0a63c4e4c10947a350c7ba1c26373d9188c2c0607a52fe4a26001121a594524a29a5944da494127492645df25944d525c923809ae03ed20dd43115ecb591ee6e23bc2321e935f11ef4be0ffc5eb49df48c64d102842cb248220737b2a7a787831aa8590d3404c8494b23eccc4bb08e821b2c4cf4c4c294e04c3802c3a8de5f2ad9598bf7f7112cccf7fe3e6467e0fbcb1d8fadfcb39cb0b11c168eea66daa650dd87613808141b639bb756b0310e32850de736c819d2d33564eee9317d23504c799468fa93383f14515e2496de1bfd27a69e7bdc5b6aaafa3b91ef63560d8f7150fe3e54f501ebf2188f6ef98f46360d5362be8df7a1b7f91efc7e1b211aefbfb701fee74d6104125b28428d69b4bef5f0d89eca2f4d4c665ac4fb1d1efdbedcf6c860b14be8d800c8c7e746f7f0d1944750eab9e6126542b9f1aa7255e5739086f97b49f4f98d1fde92cf35dea952f67a95e8c8628de8f82a19d411c9e2882c6088004a02644a0248060c54c3881123dd72c946d6e546baeee56f6c69dd15aa69023736d37546fc391792dec668f4a411e96d461fd255471227900c0b735ca0872d99a2f16f406276cfccc33ae8210e619c08a8f60ad38f33907713fef4102244080a110c23c22107260dfb64ae1b603ef663e754193ffbb167e2d260c4a5c910977683b8b4185b5d2c645dfe455c5ea66f80629aeac84284ecacf4f2b0279d6a48787ce74fff226716e185ca0d2b354c48c352de631c869fb08b0d2eef3ac83c50cb8f3de4f5b8945781a1d62c77df99313c0c313c0c5e6d676ef3d68b67b5f8f5180dbf1e8067f1f5d1efdcf91026ae54bfc303a1bd882b954a456960bf03ad7179d8d7bc542dba0a6287e7e16976687d4dcb5755dfa2eb2dd503a1a9e82a025c55efbd4cc3c4beb9ed85cd87e4f8d340c7af8ede051d3f163a7e757e00e8523ace50c317e938c3cf4047150064a03b2b2b5a821903f52030d07ea2f2f84b63776d2482a24a4a8bf8f236883bfc4b84bd8bc8830e3060c0d0e15d688d0dafc3d7b43c8c0742931157fc2e0f845f4f53c3bf9eff25f32eb4c6e565bee6f5353c901651006f8338e35f22ed5dc4fa293f8387074213c0cbc39e1fb6c3f3406b6cf81dbea6e55f1e08add60742a3c19e87a7813d0fcfcf03ad6182290d0f5f698dcbf3f035af873d10da9238466c9d1622b6ad3b880e62f320f60e62d70003f622b6cf1386e921d6c51fa816f1a43a0c71693a884b63b196c42f465c1aa3e889b2121bc47dbdcbdb20aec2ff16f1e5610fa33593befcd25c7efc17faa25172115f620823aec287bd0d3f1357215d05f1f2afb7017b1bfee55f6f12573f84ab01781f7e380155f5a1aae17bee0fa482b5eeee186248305f1ef62edff2a3b7b8882f0ffb51d622aebcbfe1e2f22d7f80a5cdb8fcd2602ee12fede5c7bdd51d8ff1ade5fd9dc76335bccf0a135f4419228cbf41ac61c6e5651a46649e89314c629118df2e3f3c069b2dae8ff1e3ac3fbce52398cbe720aab6c5ae12fdc42f06a3eb2dc781aeb748540eb12e7f91d844b04b10b15bc4d6e95c0d62bbc4de11db06b161c490f17333c4455c5a0c71692e71692de2d260d41f1e5b5a0de2d242e25797e4830f1e4c7c05e445c7b044187e3765cc6429e73c190c4cb6b3fdee6364befb1daa1c16e6856b78ccc5777fc3632fbefb1e1e6bb57cd72dee876d22f8eaba6675b29d997a9449b633d377cf358fc5f8eeb77b12fdf598ebe70c323c007e57e57755bf1bc3ea577e3b949c8731c4d5e95fbf3497b83ad15510ae77791b31fe15e35d62bc8d7cd72f2d00eff24b3b0580ae8278bdcbdb78bd8bcbdbf4bfe87aebf4365cfef52f6ac3ef429776a2ab08703d753fb28f4d0c97c83b54a4b27575ddb34fb733dc0040c7afa2ecce50f757749c818eaa1634a57b5309668af29166758fa26c647684b9cd32757f3299e818fef75ba738b24d0814b1d4ddf07855906bab861a6a68b55a35fcd25a60c080d1d2d2f236f261fcd2167c1734d040830b7e17fc2edea69f865fda0b71b51fe397c61259ef7a1b2f3ec68b77bd781bf9ac651177cc68115b620f6f75ff42bce1adee5d8835bc5543f734882a86c9615dbaef7ebbef5e6a576b1097d61297c61297f6425c1a0de2d25c6c5d712bcb52d9baba0f7530b7b9242033f4080837b579f0086293ddff2267c63e21df2a2f7f26f56dfa3ebdcf0e0fe7d0523cd655fa9468fa1c0dfbf02515bd0452c3efe7d163f4a7efb731fad3a71ee5b95f8a312498a9f9238f7e9c55fe8b24ae24158286f4f30fb03416ad21d126fdd24624d12f2dc54408f5a3eff93de3a58422e778886de9076d429a7dbcd56f12f9c638fda57e92d89475bcd5cfd3d159c76552fb675a52aeadabdf2910339a05739bfd2110518329685204b838c761248c0409c3b4ad1ba813db49d79da0a9808393483a1c6cacadd0408ca4819030929d956a0f3f98be847f00e7b8dace36053b133d88c3e15c34992323a9ded151b3bc81c649477469a3aafb8e8e6c80ef43df89a4ea646507350b685685e951d944a7926284f3e1845d8a8747e61bc6e24a0c27ccae21b3cd729997c2f4eafef7f2b7157255618678c6f7fc3a1a1692717161f6efacae4bbe7c710755ca1f658c2d991dcd923ca88e66b9aa30f9e587688c9de9df74d9a599aebed50f2c51a0981e55cd8f05d3ab65d192443bf362c0fdc7ce50321542799cb2a359fe2891470f1f37523ffdf29afb500a539487e404dd04dd04fda8c0c638091b2484897aaf757680fa06a806749373837333e4e6934ab9f1015a1294f249adc8a01595d49294ca8f0fcac70745551e0af5a81fa7d742be115b4364e0e49073737373f3add68dd776346c857a20156580d2a37228ca3eeb72cfc6436a3ca45dc8ce038302401a711236e643d47cbce6d343a9a2641d985b534c3f7a6d1544caa77e3e8dca7fde9a1f8a3c1ba698ae3ab24f127c76167abf11c18a6087d8b0d9db4b4552ef241b4d4bd1126926f5f37251fd5d48c3405ebf413dca83a20b2bccd16b283afa10da10736c20ae282066c10fae89482ea8986ed3f120ed427e3ce64184805e2332c70d8af1c00c6a25cd3abd7ffb346cab575d2c618eee411a36b692eaf3fdbff92152104d5b6f4dd3ba623c314f0d33bd7f3847364c3159bc9dbd14a25ef49fabfc4fa2499ca24a49e4243746b26324a7596e5b97d772c841868c564b146180816f82685a8a7acdc76b3e32690a0f7a604dd8a1d71d61b3ad2d7c1bf0c370f4a2b70957418c5ef43646a30747741b87918d2cb12e5af84dc9449ad538d6e54b9a49a008acd12c97d130c838cdeaa79931691145e1e948d5cfcfcf8fe879c54b6af71de7d919a97fe5ad3ceadd947ef423eab6913df724eee34afad62c7fdfa1854cfda39cfbf19d919d9084709d66b1fcc8ba9c8376c64deccc098609bd3fb313930a3c1df9c40bd5aabf0c0707c7713c8043a41da783dc88b4499bbc911f685815a44dc88db4b9f87121ec51696b96bc9136eadfe738de02e58d4d88b4499b14d230ef69843c4fda5adeb8ac35cb3da85936fe5106b16dcbfffb7096a9b4a9200691e9bf429a55f3c1451673f4a0204f6290b666791532543047af79cd63d2d62dff4fda88c4c062f617249d7475749c06f2008eb45569933712a70b5e60185e6279f847665d54b08bff1276d67509ebeae44ba836e202aea76786ec99e163aaf275c82018f86821192db42b882208a7baccc33bdc7276ff9887e0210e85fa08d09350b3333387a458aabce38cc43f47b31cc6dfa16f1d3b60de02854278cf22ff954804c600e7ee7e0492eaeeeede2230140a85421f1d5fd4b18347b35605c587c3c99e1e1a1b73e11242f51725cc52fd71e4d041a3093354aae128071571ac4f1dfd483ea93edc6677241aa2efaee1ba30c21cfd481c53e1b2af9746a367d28f6ade8724ea43002f87e8060e90cac84274e58d989d7cc1e8eb913a2de5f7873c24ce79676732b8e7d679673165edc183e45679a759f27b1cd9384566477178eccc7bf910d818a760998c33051be31aece0789477d6255f002b98de7b8948c7a44719c9c8467092ccee19c9ce78e7fb6a3233ee930593518e214c6e1812cc51953a42baa64a922449eec78aedbc23fdd0217757474ee29e0f32891195a561ab1fbaefef28cb4a1545ad8eaa286a285030333b2901b8f9bd5e1a6b6a475f8a54d7a40e9ac098429326308ec8e5c03acafdecac55656d47799d9b5aeaba99cf6c1c9cd0df20a178f36da0fca4286f63daa0fa44571ecadf40d195478ba47e6928ef3fd0c6e84def899d1884e84b567c36d386099a4957dde86d50e8aaa3ab107d115d7574c68484d9b91f181f8c7eec5ac7a47f3a37a198303f9863f300e00693c7bfade877ff610105fde41a07e89b38d56bf8ee8c9bd8a5d1025526e6a55952bc8440422d9202e587c76bca4aa4125ee2f9841d4a9e9d9572a862f6ab76c6fb4357cfebf7786e1822437fe3a337b6e651d54c8a9f208e136ef7d766f772a6542ba3df85616117ffd1872c2698234bc606b1ac9d9dc0ea9ec3978459c5b851a88e8222963e518ef1eb56d2ef6ef82cfeee2e7f91b862826276b2049d07dc0a2b7420605ddeb51fafea1fe8d876b7f0103b23c27b96bdb133a6bbae9766758cd5adfe959621e0c5e23aacb082d5b2f2ddbc550703365681202bacf8a16a966a45a20f454c8c936566ccbc6408d859f750aa3a9697bdc414012d2c506001fa9cf8763063c02a254a68e42aa169993025e6f7e083629050be84c4185146fc95211f1431f0d1c0178936190da4e24a398075c92b6647576650f8692dfc7c4a942801ca3161261de31ce44089bb8faaefd8d59f5ce8a35934629ab554d6accfa5c894cfdfbb0bd1364072748c6bddf2675bd77c1f7effb84f70ecac546be042df620f1fddf2f0bfa72f0aa92af4a32af4535628660f1f1358980ecbf20771b2961b17f070bbdf3cda3c3db2ce3bbe428bcece4ab58d541d9c66b9bb4e7700d1c3f0e1b649feaa647ab7a261a3af4ab487ae25f9fed3b0aebe55d47c07c911aabff7f8ad6341c21b0e54a161dcd3b053f5f7250d5b254282547fcf75c9241d47089155c20124554e51fda59432066eba8e7f0aea656ebf924ee9b7247ea5671cf9eb47765c470b33c4b91c93d3a73e75a2cc44f2ca52911856bff25e935d11196c344d065a73015a0c38f3d7514a3addf237fdf8c9c74129c1b0c48ae8abced546afa223159aa2272a713ce63a9fcee83f9da8337aae7ecdd2e1e9683150c779cb5f4608e6474759c75ea2717a837a27288b197272aa7c854e32112d2d1a858998894394e158b284712c097c1c53964661d88370cee97d4cc31c7c955f1cb835c4b1805d32c406f5296f93fa16dfe2536fd3e2532f9bd534a816bfa84f791ba84f51d11a2668bc6523f52d5452a88a65fad39f3ef49fd975dc25530c3b5034f9401a00e941facd3af980f2e00904c193898e3c514a23bae3575b081fb30710100ffc8932313568c884303bfad2d202521172ccbafcebe1f6dcc38cbdb1339759fd75c09408f22bc3bd0f7954dc96bbaabb546f55ff989df57eccbafc25cf98a48ed0d3d3d3addc6627f210957bdc5bd59ffdfbaec1b0aad17baa35a4fb8621b38d20e4871e6daaa81ede306486aae8c3a711fdc8043d3742badeba0152ae79cbab1d554521c5a893a254b78198a9d12cd5eae858cb776b268803ecac7b61d99947775daa66f56ce5e547963aaa3a99ca5b5f4d57cca620910897657c761726e63e5724735c592932b736f9770647944a22981ea284c2df1225ecd3ac6625b5db6f3ce67dff529824e67ec73f48902a83b3dd67d28ad3919c5de1b6822960986819ccb850821ac8a045f612f31213f3227b7991c578bfc4bc583c2f4a64e3b83ecbdcccdccc041e511824ccfd511aa0b777b777bbb7bb7b7777bf6f6bd0af984ed6750bebbe6fce8ff232c770b77265968e5f79e628ab31fc3233f8fb54aa7e9631371da7ac7632e8468baae3a8ca4064cace0bfb8611cc147f9f1a551f89c6c7ac9a23194c399b62b2b45ca249114d601c2159f61ce1d20c9f5bceed66bbf1cfede64ee08e6471841225343c7614999db7c3631e7dd1c83010e62ad9c092ca435d251ab85525340d13821db02e01578089a2dbdded425e088b39a6bcceeb7c848ce8286654b8a360e0b5d7edb5d71d232323bb773b21b07e5db3a01e3460912cd5a59452ee0cb71ebc4a1424d1f1e133dc0b163849e2740339e33d0d55454ca9611759d1342df44d0bd19a0bd03cda5598219c05105cf066042e29b882655e184247786427c7c81238cbb61f4f7800e5b0826697e7f5c2c2523913c22dc0d481c6121d682d7508c291f5363585c9dfdc759decba6ebbed56ee3a7ff33e7f2f6c99f9a7e3c0902143d887f04b08e648ce8008c0c3237bf9efce9800240391d9141debe5257b71c7ddca5e2fafd78bec256b6181c2dc1f592abf70eedeeeeeeeee2e149c48ef3af99ebb479999ddd9797999bb95377048b9524ab952d2d57a1f80412247ea888f063323b04e9763e65c7773ce89178c1292254df14a4e6f1435068e1076665d0ca416f19ea6a379b4e602341a9cd08085c93fd342b3606558c1a294d0dddd323e98fc2ca5cb9ad57513e50bbd7643a707b002b30e22d8d58cf738d4aeae64cd621cea2cc7390f00c94e3edddddddd5d9905b9effbe217ff6f4cc68934d179eb75bf73bb4dd5a53c541548c5c2dcef13c8c0022230c5cd2f0605084394fdd6c5241a210d141e92e03347190324ccf13bc21c3f1918618ea301c8faad4b8928064598e347049d39ca21cc51e2e628a58842084960008320ccf103c21cbf1fccf1bbcd51faa00773943ce899a3ac0bc51cbf1de8608e1fcf1373fc723083394a1cc800494fb3f661dcea3e0c920f5c6f3047698317d460678632463cd0c0091e9a98282f241accfc1d77fc82c30d38e080830d325e2e315c2d3070a8a1c57a41830b161c0240451c1e07550b9594140e3878f30e606d3ada54a65f0e744862f2ba06baee97fa1193715590cc8f4aa93aaf25c5fdf1e3dc0d54b00b16a60993731d8a892923c25fbcdd8df9625e642f2fb298971826bfa1ae65c83bf75ddfdd755977f7cb8b112f2f3de1921f9f1d2447d6b57b03e484c7e26ab4ecd64277ee20bc8f841e1e1d6c33e4152054c11d58c27c7fff26f31b10f2d7ce52eb7a97f18568e75dcbeba5e5653b23c8ddf556c2dc1fe513ac8f555dbe4cbb20641e2d9510784501a6d65357c670cb4a6549750c26d3ac9e4a82292711bfcfee2f7edf0c8bb98cc5be6296eeeeee7abbbbbb3792f59ee5d1dddd5df984139d1198e5b36429992533b3941287052925483f6fb54ad67091c6259d696f77cffdbdbbbbbd1b881eb81f358b93524af91e9bc1fde31e84016e715d177064f5c9e4ef18998c4cc65b6f598c8cb74ca65f2ddd2293c9a0a8422693b99309e68252e029c247b1d0370ad17179644ffe5727cef0effb3e7797a9e12cf301d132199ee5f9f1b0c0f107f3d02e9dd13fbef8fbe4b4c2743ac3c2e41f257bc1bf5011f097f6f97e319e7773b3777777f78c1a40cc0062ad1875747b772bc1dd3bca6df577559e9490339f1cc9118bc5628de427e53792231a20a4fc4693e53129592cc9923fde12309859d10c3484f0db172f8c2fb53ff06fb2cde501a728c2d403e333ab42a5f27f7715abd2625e604030f9af8002a6042339bb420fac8fc58a7d26d8c1105660fee669c60c109e48336e129a07a23d8f3b0682866bc82cd0b84c7c48264024d9249d90f985c9f292458ae77127c1e423e0ea386befbe482d9f4367facd6fee4f8ef98dbe6f34bfc941f8863f20a5943287c7beefe7fb3c1a84cc2e26e0fa347ab48aad4f1694a0c48e143953f8d06a6a4dfc2c2187450690a0f5bf641e0b0d79339daed01415737f4c751de0ef474e922409b3a0b2346cb5cd72f93beb6af88fd3ef0b85de7b1fa4aca1a88ebe6dd63681d1640a4d881044052a746a3c79c24f74bcadc2a3237eb233eec2c63a063a4f749ecc3cf1561555feb17d6e782c5cf1cc144520ebf0dc7476c0d701e94ccd3a088220b579d1f763eb00600738b4294548453a04e1a1e16ede7a32e4a3dbbb2c674c51cc4ee27a743e1c84cb32763cd5fffbe654a9fe59cb9fb7c4dd926c27f16e147e4768a12e143d4857fde0379d09655a05f40155256d452fe997dba31014736e4039b7f680429f56a86fbc7b78c0011dda8a0d68a3aadedc6eedd5d89927a2fce3ad24b81b03796c695b4575ec9bcfa56cf64a495a7cbde06e3041668d75f9cf88b9c5743ca11466de00420ffe0c5f08650d0b19a0abac6120eda834ed749f641a0a859e43a15028140a718843ccecf2a594ef21c1235f2e4fc736b649f93558529044835f1eefe0ff483498bf10f5766caef2376367fd7d3716b3bcb5c3f6b11843f5c06a6a622e8f2cf452ca6e79765dd7756cdb96fc8e8e936d35d20eb268e9421238d5ff6d369bc73a396d248795d33036c2dd367e822d27676730761656f7dac3f07bd17be2ea07115d891e48153d4c893923430473e49cf7754eb7fc737239b99c5c4f1666887e9d63053f411eb182c393450b1092087d1fedc13dda47b39c67f5efe1a361a13f7d7787b8d6e3c7ce264db3badb517acf240a47a4f91ff7f0441d252b62642f2f206f1a7ed303a17974bee969e69b4e3f290be527fd75d087093d50501e05e5e7f79f1e45351fe544e70c0d455c1a7b2714b5997fa2ef3419991544316a11502db7b38ec2c6fa085b2ed7c28473beb3578c12fce8782b468e65a0601e6996cffe5997d3c679ab8ab6350b05dfe7e20add361acc50f78d1566c8e79604a6c47fdb37a24e016d1c9c39f2addb76fbbaad304374c493e39e66ede46c36183e71da6c36dbcbb636994e94693225bf80a0d6b8c6f54eebf491d6a9bdd3b0edbc631bce1be7a41f5a36ae713742a3c6d1e846fdba61c804699ae538dc4fae71edd354a77578246e67bcad5e77afc41ca4a6594f424c5a24cd92253864386c8c529d8f344ba759a1c792d948e52035b57d620bf5f821058eb7e251a38ca8040e172541ead08c0000000083140000200c0805c321a170442c1824c9f714000d7a9e427a5419cbd32cc9711443c818630c0100000000002232036e04f21138f086a26d8174de93a0b79f8d060c2e606b5b94034534f10dea508859a2ea977cb6d9d12633f2feff9da8591d725e4c6dcf56f50d41c7de7710973eecf0a694ebe91f8a709357a11e74c332d62599fe6c6011fe67df07fd7a127806ef13e0e7b9aec0124566b7d859ffe055f9bdfee0347e3518b046817fadf7083402ede830ce1fbab6bd683e84c020b4d9adb7a0425e4ba5cb4cc0728ec7f44f19d88c81074b042c355adbe575cea458ccc445c41fb351e8fbf39e4b3ee58bffa8b5a3359ab41ec10293ad7043c9501d0db7fdf00fa2b1d9bcc1f69538c682de6f4812a7b81d6cb37e0c6cb9c27e8055f4d0b7d2f7472efeb63e7bf5640a09190b3d0da15b86ac1b79e656f5ad19dc321f910d424886bd76fa1fb8e9b0a8337dfa6e786c6b94c96ceb4fc6b3120cf044edaf53dbe2d3e8acdadf238dae1c5c785c9ccd8979b11b1b22feb1b31dce10ac3b39302474d1c4ea9c0b4e8d53a5003ca5375fd26713e80476fc1795fac799b1c11fc87f36c23eca2805e670104a6fb5ccff4e8ca96216683ae4e978b13f1ef060ab35b0d6b8aa99a1d6ce41d312904c413a23c08502fc2bb7fce8b5e2886d844837e6b81b27ba90ce2841b4c044da2641b384b93722079bfd26f71b60feee521b77e515c6869423a1f72131ee22c380b43dbdf9c2767ff2edb798741419a9d07ffb34a866298437cc04e75a1847dbf046aceb23eb0a10c32d097f03381d406a01f8b159bf899572f31cfe99b89c9b56196361896c07ff0265995f18f492ff637a6241da29e5f1ff9f4d62d194ab91e76e14c7d93bf6918947ac876325637a5c39c002cfe47e0617198145a1dddd513e59829386a85cae04d834ac98aaefc6598e536a0d7a53d8cdd030267b693d154a40772d39cd545c62441a1b00ff39700ddf970d71157b8ee5780ed065b9dd2f9837e5854124a0b52c767c56d50e47f4e529b85fb8da61458304d042c94c8f0c539cede0a02eb7619261aa9e5682aa1986cc46031a05dc879ed465567e1330f93b479479563a870405b145e5367d43371d5f4a88b2897a7de2947e45ba712a280eac449309db6d7ededbdc9c9743c93f718b8ac2999628d5b061c0f763885b12f63c7e86fa2ff3d230e168d30a991344c40dacf4df4e716e4e05817d732ea67e28852353c0f063eeff8eed3df2077fffed366e49960a7d3ba2bb333e5aac7ec145d83e6645fb9dd49fc9b9427142278ac86512058a85d7577f6cf81cfdb41464baedb047cb69d75f1d65d7320b344599a886163e37303a3313240d2a907d06c12a8850e96f771d1cf72d6bb99b37f28e5a9d62f6a1f69a787aa2e2ff46e226bff9444c9de4e8287d0e4437f54c82b5696703f55aeca38ccd1c9e1f25f271557341bdb8df98600ba6a7b2103b210918e52657a914ca30ff4270c3af08ad7cd982db6ca5cf4ca6fe057a8835fe1bf5a728993fa6904fa4348340747456bd85a3f754d6903f2b08cef30f343b01fc802b01d6f5ae8a60a4db33af15428ca649c6bd56693b55b711d9e8b5315be2f912b6f95d2039098e7a4e34ae86aec77e804ea1422d610eefcdb9448078e9a24dd8d78cb9f81df3e3b29202c1c3b5e0d81472d0c9b8ba3348e92e95d415a7d30e0597fb570fc9ee94855c07c225164c49a6d771a0a95c80c4cd8a3ae1efe1f79177f31723b53260292539947b4420320b28fcef9f7eaf5df0b79d12afdc452fab477d34b5431636db1946f7f38c68c17b6f42590d494a921f199e75dcb415f59c1c684fd154da05a9c84a9c28033dedb882c61cf8a6bf54f36b46680cb88b53bda81ccb55d45f3ada53f3d1333cadb8bc1566c390fd3d88cefa01a1030c882cd688eaba7680cfb10dab49683f6b9ada778dfbc8c9d6243816a74485c856eb5e85f09d0bb12b9a830000c5ff697466f79f6d23169dc7ae60fdac5f029b81067c616851868a55489173bfb42ef610a70040d6b221d08a190157d6ea70377fe17fafa30aaa5a4e91764be0c6bf28fc0afc607b9a23f945e7af956b314eb3a23ba1af9da054a91ea2c8432f9afc3b19bebeeee12b17607ffbfccc786d7eab683137564ed65f725f0820d5ceef10f63f2e370eb0971c6be685c20af1a2fd83a1f61deef5710b095318484601fa4cccffa549119a08df10667ef0deebacf0a180e383587800c505f13e04d3cebfd208d8af0569bd4f0728e7f6014013a37976e8f8ca63de6eab440a7feb6d8260afaa7fbf805ecf3aa69b6f6683dfbae681c250f8a7cbb01bcf767248ec3f5abf70453d97838d47d66b83f3c08d88c4aced51522a0d8339a455e8fbf3e2b89104a4ccdb644fb36b7bb1cfdbcfba2084ae1bc9dd8caf9ba3bc4c1144bc3cb1346622d3246ae995e49269cf63ad1bc65de68d3613eb3413bd5fa7c0438b0a9036375a923279633b5a33a0624b643ee0a272d526eec98945c2bb93b7a1ed78b2c92ca31c6cdf4819b580f1098f4df44257a87faa59ee85836cd19c1c3de57c5c64d01aa82ec5f1415d6792bc06acf8c7b849549919de09c97b780e8c65e47f3a0d9cfee430d2c3d862b170d4db6a601cea6fe213fbeb8e6fc5c234f6535825c322f3887f87d8ade39b008d9d2ddbe86f2261ccf8515db0f849c4a005453167938719bce1cb55cb43d94e844a8125c34a76d614fa1d71c8400fde0ced8d5d1a102ca34679d1425689bbe84137c07f4e1214276211042e4df0d2fda3f84a7bd871a58361f530070ca09a960c7313adb8cdd5ae42f7ea55ecc44477f719212327d346777ec7d08701642c12160b18600b076281c199860fe20190c00308908c4cf93c0cb18ef0f579ebab3882c39d8e6c0b0002249e57a1c1fbcec000c4de28aaef644ea0272a36681dd125961981146497b883144508c7d9baa51a2df88f4e9c81e6cc852826e8a1c264e1592286906a788f2e11113108b8afb438a6d470c21175a322867cef98e7d2d3c2022a058a9f90ade9f671a7779300dd43e3bb5c67363e09720e57a2ab0287df9fc5caf70b65cc735a078f55d72fcfe1e0e9622bf24fb6498036dbe48663618d34c2bf306ccceae14fac60b4409d19a1132777248a86c2a3b1c8c9af0a4f888328163b24dc38fd11e116889828961a92b52660c16588fa2b48d6b9bbf0fe7245295324f6336a0b1d9afecfe6f6b205c6300db9e6d3d82ba74bd1481a8306d25719f7923510393136621741ca1eda700190fd6a447925920e015a682f99e6ff998973dacf8ee54ab797b9736a85237c000700966415853ac9786a38bbf30ee37c91f3a39677636388c126784a2ec0927096fab42fe4710182ff81801c8e1668be6f3bccde4f9c2a8abc79929f066e6d5d25a95ba5131f3689ae2d24a15421e2e1ddf54effc56ecb97cc6c04787f57003de67f0558e4def11f1ac1843269bfd0a18f89d00c434eb2c143b52ad02cc51dcb9688be3d29071d88b924d64d2eed43691c5f34d323c1414ca78bf945010200667f474007be7149edbce05a15408a8fe26d78ff2d5aa842e078b88187313b70d8bd5d105e51095a9296b91cd620620720d09fdf90a5cdb2d52a23c85e87faeae09b98a1982a2873ddf5d171adb78828761a832160772532a9933121e670a8aa8b80d9353933c3416d41b625b10bb7f51ddc3c3e2b19659a7837ba5218da65ab87ae56454f8ec1fca696da0043a05f576909e6898de12a35f5978cd30406dc478f9637ab5c19c46956ef07d6027180642dbeebe79bb1ecaa8962ada15fbfa025292d1bab20304098d1359915fd35fa850f6547059361563757f2697fc85fe2c2f463d98827f765005885fab559105ecca40997e5350e105a36e3e7bb7bd075bb539edf3a76f3e5c594109585adfb17f757729fe78ec26518e2a3a6771038e1d2829d2b617fba8ec711d83e242616e06da145c3995c24c68b3e0835e1e8e7e191848d4e9583bdae4e3b1cd0d2db9a0976d734f589c6346ee79a70e30c7ad49a4af99f6b9e690734cccf81b6af145bc9e6632a08ae4056e2a65e02674d058c7cf6ec78f660c70d49f33cd66d34921cc8f8030c110f2db3d0c518bf6a01f184e2af97373c7cffde13dc9c39c7639e44f706e8f0b40913a701e8091d57838dd1ecf6545e8217f3e2e65032258b4b5d04e86d6834b526321038adcdada57b38ffdc0949d1ef0ff28afb217dc0c5db5a6ee74f6f6b593a6e4d670789f1ea430c7a90a16cac5a376e802c94c718594fe1bca61600fe2110efd2883e86f128c85dd400dba73c17beef7fa61cdacf5ce0206bd6cf4ec2c935fe85bf43ced728c53f0934b78c4803c516127fca8f29f4c7e62a691abebe5c118969db1ee0c3e695dd026d2bbc7c67bae9b21a44a5b78712ffc04bc084e4ea48a67aaea1c7e35a16c671068dbd8298f2abfca822449e46e6e3f5eb9b35917a64fd7e6ae849b23c3670c94b8da05b64722740fac349872ef9e65579c9029ec918d93306ecc8c00e5d4863f369970331416e6bd50cbea9af2380ac6323d3b97453f01f7a995ae1de0d204b6fd87785c94198125f5bc7df14d77aeb7ebf6e6c6131270703f307f9a71a3c27281951a5c230e6444873ec19c98fe041695ef2d15ccb4ab8b988ec8a9bf4e327d96b50431d321830015ff29e4eb73fb66fd3902f67f279a9c9e5355b7ab804c4b53c65e42dae13b039d67fa55dc508f957c9ff81df8e70e288730d771ea4ee8b7d162ee2182f0df15f84763d44b544227a85c491ff4b69838280f9bd942056ad7b4aee6df28a480e8a02c6e104c321c353ed8b66bf9594e67d75f3b4b49f7b0804565ab828ebc110a2c6b6202e6ad045c26c8648a56d88616efe03c22d07ebf0c7e58c222dd6f5efc0f3b596e6f6b671010bc7d7f839831e0175acbdcbfa9257553d544cfab1afc5f2626fdb7de80ab359b97ddc34133b713df27d323dcc724c4ddea9c6e55d1fba87437db17cd7e60db7e6a2010482ec32046800b89dcea6c4016c060e9204a4682bcc4c46b79982a6e92c97c8cf72209d7b09ab67e899801425246398bea1ad4202659bbb19f57a5447827edc0ae2fddd3614793ea4fb710e005f5e4bf9612d5eb36f1434905ef2d85a476826186f853705d6f4cf5c69a46585996cc03f9b731c7904f445da73761e1419e0e8488cd6bab22c0b07fd9efa95fcb197b91ef6dd28c29b7c12883c62bb8f114347a9fdc657068bd261c1c4dc37d7fde9430d4adea46f7fe1ad42ccd51d67341fa12dc8fe221fc7d3c7d15588f1841c8eb26ef67f3156814d47f8bbebe7478892ba6eabd3d50ca15ca63752f62acdf52147b2bed85d74d2ae64a240554788824c1f06fe5d169a84f1f69105e5abb2ec19a949b04b0963fbd7d7bd325748c37dc48d51d0ba1e6f53e9f93c2ab7b11f464bc1fbf3ff615118b32d87762c0d456268dc5a3218084881125a00ac02f4438cc56fbff8067d0ec237cacf0a7be438e183f623f7be45d936759382106a0f16dac6dda3a97fb8b13800c8152a5a33a9eb8bf09d37387432ab94f2d24227f39dd56c3e891032c109b55ec5d61d732aa72da2d9b73ed07815c608d1d4e9dbd8a8e4f028c694616a02599da2915247827cf5fdd344eaa351ab5a4c3740ae5b9ec60f51a73f2b95fae7e3c88b329bc197043d65ba5170b71aa0d0e8fe7cb503bff38e230257713147b57e2aa94e96294e48c2109e0c4eaad7d88ef94b1d395e1bbf4448d5e3acd45f215c1d0ed61e652b0a74f9fd22b3bbb303b269a975ace313b14e93e906467e75da4d38ed430ba0259dec537f8dac59481e79b33f9e8a66cecb51a7736d37e9558e7a26d4a9f3e702e9a987bc94a46deeb9e2512fa3b4713ac5040235ba3a54d66a0d6cb10fc090ac403bb3f090a3045d851648312e77af32e0ae0bbd0a73b1ae75941b71491c4d2f4e424ad05d8fa40e65daf9071030cc69800d30d6194e5c561fd82ba2cc2683bb7904eff45cecf824c5dbf77c2cb15365e05fa8044ae612cd1b1ab7371f5cbdf1a3116e1695101ad9fbcfed4844d408cad23dfad499c56222e18e06ae6e77fc53340d17ab85ce3cfb7799f37ed4ee48b404759ebe0d173fc2687aa52ea772b723528f467a86571a587ce14398f9a9d6e4f03fe0d71dd1fdbb5b6e28dd05b9e2d419a525d1838700048f74bd05afb97565de2c03f3576fab4c44bdfaca545be77eacd97838d7478289631a586a8bf7c24893a52d02b8a0ac89d50ae341229020585fde87b6dc3394a3ffa6ef756e3c745ba832bba575fb8ab9110c24271306f9fd842324ccc26530294d3a90b35135430df4deecf91931776a4a87d59ba49e3ceb05b5f900a80e1876e8d0358286898f8db9b3c7607b1672bfee5a74f0cc17c65c774c1ed930fa4c78fe7525dce9936b4b5b5aff06bbd2387e77aaaf2d05e312716ff9c9887378896eabd308feeba6aaf49ed72719c1ababb9c18ce66e965cc5ef63687c98dfa8f7ac5385357d46c303388b9521417139036074eff470079d45d798cfc0e443d984e1bc23c90b587f5ac6d2c1a9aec463925a689a9c9ce877fdf71c15fca262ce3e60a8c2e9c9c90026b107d750137a44c2bd8b7d593a993b848a2d99e900dd4cd2252a7b38e9e4e2e441fb8f55d5f722725bf36c6765a848c371b46b4be9d3dc1bd0ca444a91d1e34a8e11fd201cee51bb3a4b4e0fb2bfa491f9940a921bd04471d0729300f8d7e3a958f643d080d17d304dbe1a58a94fbaf2bde6d95ece43779be591396ad072c6f5645fd0e4ea96610bc3a021c1d05b453e06c5f5dd627392898af44e4e119a2cdb0663a01874017c00f934a54ba42f5af084d5a4101369abc1524f94f4e7cd090ebe25cac9f1ecd3f12c8b5b20610e894e0626b8da1232e0de4a5a5754f8aa2807211b6b224e8343101e8b5757f751afeeb72f6ffd089f622e477a64f14cdb6b2fb61ca0c8382e37a1ef54ca7943fca4ce9da0d2e7ac9af3ff239e1fa31254002c5e1d183f3b609f41b82a5e6015efd1e450e6eb1cda3fc6eea970a838af0607adb25171bd5a9c7b52821aa899139995b1d4ddaa81526aef84a296f974c0aa1c69ce160a1f7d48a46c837110612d1e7f724bf209f54cdf6c63d8d7417b6aac4d6be7b2bc04cd5f7b327bb15f7bddf43bd171ac758911f1455df41392278178011b5e418569e657a00ca902c24a74419312de07a869f88dad0834aac19caecd37009ca063ab226f0969a9558b88a84fd0c7c7a29f6a1ade841afe89bdfa09f65d9a1506fdd633f274396ff619434fb5d74fb1352dc874e3c3ed512f4383bfaac7a54294b23aae417f9e036192813bb681345a7039e79fceee439a34ff990fbe5214766e3f2e3f14bcb78db7de7170c7f669246509cc1ef24ba218130deeaaa2cb32a25f84c789db97adcb162cae85b44c403f4f8ffc7f9dd6552922d94017947715e16fbe6ae7f7cd8637a4020e9cdbcd0f9b77f8c77c56ca3b01dd79f5294f169371720ec041862a7e4c30ce4b819c2700ecf8678ae7aee5a3863af7c39c259a5d0819524e60b2963a281f2df93956e0e3a162aa3f40408918c4b2138c7b6a49a2ecccad92f8c86a19b4b2db94b9bc018dd6390cd19d9354f2c3fd6906713ff0c069489304640476b1b916ab5b61efce9526204bd0b0067ff3aafb44c001d84cf1238620a987be9b5f305ed233d75b37547100ad663d54e1c8978b21bed1f2b191ea8cc26a94322acba4af9642a23db3acdbc8891daadd3fc6257a4238f283cb2d5b257acc30428544d8e1fb9160745c5aea9962d22f597a81102181412cfb6bab41e15f954f091152a7d52e64b82d086b13ce7af0383fd7b6bfbc45294f5454c78180d549849b28e721963e33fc84aac345d586e63a3169252c4d098a7f4d39b591b847eb62ae7027a4952ed174a993beffb7fd0cd407b05972a542f31b48e4ff4065232e86b7b4819bd18a9ee2e7985b1555eac3d08c8437d845e1c091d256304d5f5506ff6ef0700cf7444c7d7f928b45e88ff0eec42e2a0c41954128c584f57ca052b23c5a32520f9fd24b0078cd7e9f3cff57fea32e2e4bc01faef453d942ab463c2ba3fab5e81937f3f4e8919961d15b01faa21ea5ea82c78d267aee0a5941e980fdc0c32492827fcdb0b883ab1f68940f5c942a57820bec9cb86ab55a045efb727c4188b2d0ddacbe1f35719e5ecae190f02697f40592524613b954e72f48c60d54f1660e5b02b3b546207edffd0b63ac089776b6e648b438abe54f40c8486520ac7173d0cc9fdbf8c244f2b7e809558096424bc4d937b10035b5e2cf0a08224f7f1fdcbb37965d7f0c7b4e1e3ad15c43ea24e67ff35e400495de8431df386d169245899f5ad45d4011a4cc668ab4cbedbc8691d92fc40857be7d2d3eb0eec22bcfd313ea9b8bcdffad548866e22b231e452c101718bf604270a57165d817eb3c5f643592cd4215dedc8805853d2a87c1043670989c9bfce9d79562f3ae900238116617cb0ab664821f5235e88861d9a2b6bd28c7d9ab424cbc55dd36fac67ed8e20697a6aa533d9d7e5f2b8a3400c7957597ace99893e0d4b87f8ac73425be30a8de1f6d5a4ddfda212e0d683eace481c2637523c73a10a7f4584d62907f6d6361e4e052998b5b24731149660c2ac004ed9c36c999bad832ea5e0a245c40add4de9d359113180cbba091811342069830b6e606d34bb19acda4c44caa66a1d4534366d26c082ac0795cddc4fc605e24a7d62c08ebcb49806bf3cd9913c225014c7bac6f2cf16c529bb3431e45548715922702baca4fcf4a3f52362abfe847329ea7557ae2cdb53af211af38d2139747281999ba277828fb849b1a6bce6e6f8216f80b36ec3df186260342b20e130e3176ad48fcc4dc3bdeb5234cf601f6b4e787ebe81ba5d3927646f2462251dbf936583d109431ec8cf18c32c25c47ef24867fda5492554afe4b3981b51e0cbe0db12c5e1d26f8c5fad41ae0d85580ae6e9695bd2446c6d545dd46b15b573fd138de308a213e1bbfe9733919ba79418fe28bcd3174cf2ca9f445a3f2cff9209e988b2f543492795f602217947d44d384c027a4a0f71e4a69a838aa6a7ca799e7c11b22121796d8fe2315ca593b4a23371cf65fffd828e13fdce71f731426e470c23c48c50a83f94d79378d541375962e541505741716d3366983b83879fdf4d0524794aa75bbf79c1cb5b1bfbcdbbc3e7e1de71c7e59dc37d6665cee0a7db05a70c4a6d1684123051b18ceaffed2823864c0b06d703294e619c295078ef6766f32db19a4d2481cd7ec32c2b669eed07378d3c0aff739ab8a6ce4c83e6d18d60971f0a78082efe1e2b105d3af5131719259b2a3bced3e777731009cf785e7105c7000acae448d70f302e851559087f3ddd80c325d0f8d96100086cb734e32971726b4108a0b9c86033c71e107c636b9319ef5df26d3d6c77bb89e771e0e80a603d54cb3dc5c2ae97f7a1c290cb4d1bbf60f9b6c63a5499867fbe95ac603b5d9ede6fc21116e8d65da4686e6edb34313f30fd270d24d4193afc97edd605cc1f5d262544b81212dc9083c699ef94cdb0ac897418f46df8270a4e8862ffe798302db6525cdf3efecb0b872b1a889addd1d2d2ca5c433b9a74199a9947e05095e80a68ecdc4982b51b5e6dc05d41f5201e871c1579a698a53509e7872e60aa8496c626323c21766ac2d53b3c7ca7289f7ecbeadc0378370bbde79e9271e953de05d7c4c2d2dc8835924e93d6f5db8c900bbe9e7a6b6b014b68d39f32e40144541c70ab611f8d30ee6bd16051b1896164b88fb9ab474c3cbeb05f327914f9dc18cbde2a858076c181b39dc8bca9700dfec17bb32babe54f1eef27e2f6cc78745038b821b853ac404285d69880841c5430dd5035b3716fc6ac3a26047e672f400d6bd69d248c6d5b9edb47730f319b26fa20bd0f4b111f6b1bacea9c8835d6a5a0a93315088c842417e73c4ecb765280f800934716b94a0e3516a2f951dad0d0e8d032dce19c4b5010b23aac79276553472e50335b0f8c77dea5730a2a5efba7e419d64f62a8689b927b87672352d86139bb99fbeb75f704daa7e30a4d86010337257f9fac0e5bc061f6939ebffc72fc0af120aa7d6ea30298003d1faa4e3df383df4eb2888c9cf96a105c6956e823d52e4efc4603a722a295bc590b7fe22198aa7e4de26ee28d3a2bd9f47a9c5a80b35193f1b6ae71377b8b2d339112636b96f15580cb9dc943b8673c9b166a2d8983f5c6edbd90654c748b10ab4b7933a9dcd39aa1414bd36056bc7df3f329008c59b336e08b5360626dd559054c50643cf9e1fa6ad700901551f75384997fa659c39bff51f98ee859709ed11175bf5320da9b86ef1ac2fab63dd86beaa5e066d775683d37b1409bb44b677dc88262caba51ae9d7622261e576670b4678a83d2d7f492d1fc222b1acb8af0e4ab26f21c944fdc81c5731070297973a867ef2a803385798a18eec2e246703102afa33df22ecee2180b7a8f21b0b8ca4e5cd96ab54e56d468bf392c976a5fac864e24297b1a135b138911d5eebbb00fadc6eb78fe9793086263dc045ce6aa2eaf9d96bfed8984611ffe2545f0c87e8acac7ce5b09489feda4b946b868613f4250372b91a3ff3fe96c25745c38d4de7781a36cce7735427800dd4036e2b99924340b9bd98147262933282a8879daa27cd65134989dbc866a4e973e4f09c88ae8b0a0132b46c457379e4ccb16130cc218aa8f8da847e6f596bb01776c866fa7cf2e00f3a08350f1050117ecc3b29cb0d1ece790a7295d2c5377603fbddebf085772a1d24ac1f940cf120bffddfd2f347f6b3c10de5167405a524b079915851a2933d35a9e1db48ac0a2edacd7f0f76904fb41ebc9dac14f2670bc63d4632d87052c3e933453e8d6b683d0f95587a8b3480244e0342e0310e840ad2d7c058b9254e1dadf0357661d392f5c9ff0ea1061af78e4a3c33a34a07b8586c8cbb75f6bc05da05dab142ef77e3abcd9578c5bd32b07747712f873e00fdbab702f142892a9c7c62b90f71b7d6c71472daa535ad3885cd2bd51f285f8c6dc0324ecd86253ed932794d6cbdeaf3fe4589a9bec0442a6ebfd4edd96cef34b501b83a5fbad5e42b679bb48c048fb08a1077dbaee6e6c95db3e86b80461e1823fb4cb65d8f5705e0e46d2038461d32d66c4c944727220ac5b1006325622225e54509afbd1201b61895ccb4da19c9d02cd5db8d76d67a9df008ea885b23689763a64dba58f32e85cf14b573193cf276c614ed48737b8b01fce9eaba17016cfa0cc56abb598abe6caf1a945be48a60e65e0a1f886d951a382d2b3a3e34cc40421b0089e9a6b9f549c7c11e9cd1cefe9266f8b89cf4f34b1646c30b15d1134645002d520cf46b6dbf7b28596086f8f3b85ee37c038c1cbcf543b543be39b10bba64d64ab4633dc8edec1b9506ea1eba86d7131903253c83f495ac11f07212ca36d693b3c3a3493511098d02da93723f51a6824629fea54af10c9f6b6fc5c4194446caa6eed6874bdd0334100325079ebd056cca3797ab685767999216255470f5d0e473bd2b3bd38fdcf828574e203e3cb68ac39581ac59a1ba6e684853907f37a884d613c9c0f30ca2994fe89b69b29f96d47d5da6bbd0df5f9b473ad0cafc39c30ba97d580e5484069f4a150358cf28b585062345607ada1f8453e3ba153c90a8062d1d18a27ba60c313b8327bf2b5c08d80ee4b99abf0751fc3d99747250e5391eb0caf81e76c316c08eeb6a123063b07986c175ad3f0fcc1925d46ca8da2abe03f5a80ae63a803b526bc8c6502b8b913b99e9d6fa9f61d95340c3370e34b0b3445cd7cbe979f8a3fc23427db719327d9098846438e49ee6d388bce89f938acc6d8224f72e0ace12c75024a80148653addde74a862b2a181ec0f54922d9819bb5ea53ba7063276e2688b0384fd1c71093dc969422b7e2916d6190cf8a211d9b000019fbf62456aec45131c9f4c3c2c62be7a2098c91d613224da346fca103aab4b880563d99759679e826b874483ef6447342c9a2a3a15d45be344933df2109fd6be18b18547950e50494e5301c7a0487b4388e74b1c358288e7a21a35069023cec0480dc6ffab02c7b41c17c3aa70d5ecd8e4b216875a15645cc155d16e46c54cad89c3264b655243e1469ddc5a703db83b61d0f8260fd28cc656d179b285420489ae4247f9b188ad0ab899ab48d90e5aae7abce313f654a4f40de77b4af5da14f31032b1f747ec7f9e2303316293d4291b47505c875f0ce40ed247aff00839006e0b93ffb686e6a5ad102b82060da94141a5fab1d24423e3ff257f3d60f36ecb6c5af05086c7c897cb04b55196759facb42f2ab78b8357de7e0dc3ab26e64ea975257f80cdd97097809807236e41c6e2e12110e18d20774f3042de283a0cc27acd2205f760ef3154258a134155596e4a7fc0017395864da8a98e2f86341d3d54cac2283d7aa81f40c9eee867dcc7d320a6535c415e9a463c39b497afd32fc6fdf58537dbe90c0f41b4060ca33c2f5507b1c9d8c698041c2c31144d897f477c29421b41f785161476ff6560ae0ec47e8b284ebae3721077ddec4178bcc80bb78bb8659befc228199339be3453215ee4cb431eee5b9a63bf88880844d8d55e2fbacc52a6054944f1b3ed07e33d91e9d27bc7262886c339d354b163b43088dc9520d4c1119b9bcf63bf5070bbf55d54fe04d7d30c9e7b11a94daaf9157063d3376e27f7d86bf5480fd890c2107e42407f13492c94fc72c19c05a0bce24902e19c8166605ab597260d127697c8fe0fa31836d220e603d01fcfb68c267373216d8deac63ed79d75d48086f6ebe2bcda02c9d2a865709740fb60c50db99f84fef737eefeb15f027abf047fffb53de04dabbcd30a559fc53a6eeaca32fc9292fc188a7a118b461b3ffa8867ffa900d83fadcb29aa91d3e17e71fe72e41beb556f408e9bf8f708561137d69bca1127720a784b6768065dbac813abf5ffe5685454bee0245e58dd4e993e39bfa27ba262a0337aa4b82251958a2ba643ee86422f392757c83f06b3f3cb868b955e2aa69adbd68d2939969d67c31e47e30096303ff47d13f7bd44f1e5d2a822ad997922c9f1ba9fd8f3829b66f6bdff4dd6cc565a1077df70909e99df54177943008f96f1fe2081f1c697af1e80eb26769038c4d452b08a76ce208e3bd20614a80055a86d95ab4fbf81b316f7602b96ec11c59c98c37cc18679bee1812923e4d76af257962c88f0625b7972d5980a085c56df4c6ee0fd15656142f2f28906c0da8728cae313da934b5d19358160e097341956fdf33c03647768df0219bf1dc5497ed9704bbb9604b14839bc89041ce8dcc4a35b23e8a54602ab7901d828691dcd964c3919f60887b4ee9bbfb2214267a37e84a13d3ac2bb0c176405ff458ae43b493d5939230939ea629ab6bf27a9a0305a68fbe183adcce6e403941b218f0ff5a75f440f7f24be15ee1e7ed11b6078456a7a9cd2d0d14fb065eb44de89473536c3982694025d43ec1dbefcb136b9441e63049392f4f4413bbead581bbe5c054269291122138137339137c4ae49ea88d388f7396856c0973abc921010a37d692ae3e89c804a2a7d940ae066f675a0cbbe6ef0ff49a852ba807949b87f2207e2e42dfa57efefdfd62c2235b14671d0964e1aec65396b51c7785182e848fa37d9fb8571b2dd7191e7bd93f6519e6909506866e7f881d3278c24715bfcaa221945472896588ef8d54a73d77c666815fc623e87ebfc62b065e7d2eab60b631612001da5c2db9b6f650870be4ad9d9d4cade9357e8774f611754d8b7a82c27c1814cff74c99b853b8953eee5822c8e35aa9c05c43152e8f44de2e2fa1901df47371eb23fe9251e86106de8f63fd05105331143fd3e3af06a1b843b18e64c9756e52e8e8af28930d5d159665846762918ed5bcb335deca62e5669cab7b3826459c80d9ca6ce25e5072ed8a46e8708d6bc0db3929aff73b1bde7f6555260effdee7d0fb69d94692caaa4ea47da85043a4947e13e17330a30ac47f4ad1fbc4f6a63a8ac74f81d0d2cbf726d0a4938cea3893f03dce0ea285c5546061750fe64967222543823173d3828ed2ef899b988bc40d319f1ee9a5a6d78fb94166cdb4c05babce61105d638a44fe5ddb114f363c1d06b2e5523778e59a336b99dfbf7520bc5b2eb2c35b52bcfaf2e76602a8f350a8b6637c483b7cbeb243ad6e476b9664e4dbcb919ed8b2acaa70c829cb9980adb87acc771014fc3b7a75de3cedde3011d26b709147b4c0f0f08e469945b1710338f656cbcf56428d44cec5e0718337f9bb2964b5b1d83269d717c6c130a9bf7c58ebe4f88307532dd34264638daa436eb1d0b6cb0589f8a9142d0bf42e55f589853d8d9b18a2b2b12e2c8ea9b9ded0f1c08af20dfcb07289910bca7204a8b5ff68d1ff4c5e7fd3699d33ef4ff143306b7ccadd3b6a6c52fdf916872fe632f463ddcabcf2a402094cc868a9f470dd1bc14e09f9a10fb7f6f25b3af5d39d6240a6d73c9b864c436fc1c9f0f1a11d97ed0c027f24803d0a3a48272f6b676c9f1cb41461c68386323b017e1f0be2ea21dd91bfec274ae2a73c091096faaa00b58d22452cc8c04bd89e338797bb322f244cbc8ff9f6423ba9175a34fb7093a45417863d5e0c1930afa4aefd00935b2b5f9debe4438cd44c04b0a76a3573b7f4d0073ac267041a4817693a775bf2f3abada81cbc2e25670c98b3b00b2a688bba695014b404e91dc1c8f276604b6609eaea1a43e728bcddc899f453786e99a948178eea07df96abbbf674e02d12c0eaf9bdce74d5075a917ce08ca61833ad5dcc7b84993ff38d7f39e98d6208f9215fea607ffd4e9b8eff1cdc429fb5c44be09b6e7f78108c03644711d764293887ed67d3ba2611c182b32052793c109279d1744809e50855654a882e06086628ed7b8d52db821d7595bdf1720218f89219350b7cf0453e022ffeae8e730307d0e8b25e929ffdbc0d33c07dfff3172bd7a2bdd6eac8f1202cf19ee73062b9969251138df787b83493304478c57f06f0d46e6b9456885ee02682bba37043bfe3e10344ce3f132071adb73ebd9bd06cbb2c481ce8b800457b4ff916d77ab25afc86d4199f1eba7457364f55cbd0600b494ad642e09f71eee6cee432980385c7610b44bd0731eb47619badee14c7e982a8f4c8b306d7d4823c6e944239fd5e7a9684090f2afb2299de427e9b92c102320546c10be345b2d0c01d1bf11c28a3c940d7aba291ecb2d5afa4db7f83f09fa7e27a42b168d644e81fa40594c255c5fc739053582d09de92c7dd7034c83a47e006af3e0ac8ec7f0bc4cc420815c22226f49365cd0fa8363a2b44698bfbec7c041465327a06b9f07e8a0893d5abe36c2baae08038fa8446bb99294c391e90c398efcf7c211fea491fd2705b5caa39f6cd753c090c95841bd5c94a40408a1854459587bf0bd4f79e3cc046e80818562d351e05428221a7211ed2e1a38e0f1cbf88140914c20fa8e4ca828f2c10ac14fa3f134af9ea114cb4181e133338eaed6c28bff429ff1b2f7da5ce783477195df6b8695479cb8c37912dd1693bd29de5124eaab16ccf1c6714761b695ec538d1a8f82a331930899f2d0c286356d87204309014d1a84f5ef9ab766742b63ad0332ae3ebee42bc57324fe78319ef50fb8e6884a029c4940326c1ef6b7104040ef25676426c343b8959a12fd2a6ea7978112e378c4c7d75e02ecf7fb4581b0166d6eb223c6d16179c2b3d53fbddfb9769ec2d024cad4f1010d14b2ea38125a5ca8f0fa3b2a85189fc9630eedcf24813c984ab805df287e0689f84122d9841b83a0fe4992e1ef1cda4ea8fd7c27a5c8f3f6ef1cc7a509cbdbe3efbc14d0cbc44812bdd6dbdab6bb58d9e85bd87f944229da0ffffc305f263cff91c83b27b8c548e1f6ef50c66abf165e00943e6e0034c03a4c2b603d404635b9fcff8ea4d7d1a41f95bd5b45e0a393810d64dfef681102031b6815fb3e271d795823fbbb8b97dfa080c731ae137ae3eeb5f8ba55b6fb8276b142c8aea4dd3314ee59ec841ed45ce245804b53e4971e02d72bdad10eceb1414cb85f32e9ee03a44001153fb52469690f81f490e5ecaf9a39ff048ca4e3878c309675e14bfc1596412fcb0168917fcf25f7b03d51a5b0f358884d0c70a7c4d9dab167ea65b2b120914055ac7738003c7fad1b4b436dba458386d62de80105a75513e3691fc24146462855866fb0ef5952915238588fc1786613299cd88f6b5246a32c3bd2f78f608b3f9ca48167d3a107ca50aefdcf0d75adbab40314c80747a6258318402ce3a9720e22c2c3886bf5a116f5448425499f3b6216df01244e8f96c47b2bfa658f6450fddc903645189bb63c16f60ed07907cfe52281213f1704ce0a81ace2a21510b32fdcf612480c06840cf2f68a4b6e7eaf1151317f69420eb490dc94ee817704f05e0d7e0a21044518c973237fa21138c5dd674924f020e3f590363198787c26ce751468b91532a4faf274340bc7c8a2bb16617036a3c8265e17df89281edfa2c50a5457ea44fbe041648f2a878f49769126f1100baf0d31d3d4b0445ec344d769a1fcc8525ad0374db71ecc0299143d7ba2afb0e138b84577103e202c2afa82b32ee77e66076820fe63c6d05ff56ccb692ae3d93d231fc5d76c9c872ced7b5e4c196c8e3115114e61835dd77498624b3bc98152339838a1311fd89f842387b19f36a8f81116d5827934f50933b6eb5946dfecea787e884b09cea7b39ebada1fc8b39a587ed7250c3e9e6492552c9b97ad88c7980a6c911c2c74e4b3479b74ba5f1cdd3ba535e58b0be12e3d7e393e01c074573f69cc3a0026cc94aec90955824c3fd7c0424fc6beb66e80b589cc2018e1c49db953cd3d5b6a81bddec5c4a4c64a24dd4864ded95d7f14b4b7613a7d5295c54563610106d9e04e9a974586a588f8a3aefe1e431ab23bfd4e0b48949128d9148f808078b6940f49759fb3a186664a707b945aaa8784ad9804fe9171136863481c3e40d89211903e05780bd1c652ab55e2f47a2b3ed324f34e85f4bf7667949e9df6092ea000ecb605b40843b62e91c4718e265665da59119b2730b5bfc6c05f60d1061c310ba2d5129b49c646fdab9b75797d88305256c71e909bed1929133d2c5d220c5b832b35cd4e207c895f747f1122f35c93c097d9057b95fbc0a714e84ace797aaf2658188019fdb11b866a36d631914e1652aa82e610a5070e89fc11fe38eaed52b855100e0886261240229524e1ce485d0cf7738343e6dbd2f9f4370732ef80f34d72868f39cfcccf733bf4fe3b35ef00a6f9f01b13b010bd70cdca028f6d86bf6137fa9af5c5bd71efd07c89d2c5a71eea84df62655eb827df3b72a192deeb0073e3413c196a5fe67776ee9af90c7a27a940b1af25930a9c3a5f17edf4ed1c7a24ac2836ee0e6f3e762af211f329334eb79c3f13e098877def3c732f3a8293896dd7a9e9900eae64c9fb8120fa03f8bc0fe7cf9590bc76000ffc32573f1c7f544c353265dbff72d76f125d263cecef1a4f0e88ed6a0015b5fcccb6a48e6cc27985803119cc97647e156eb28f942bb65a145441023e0bd611f29965f14cb23ffe5b8688868b1120d05c11029f03051d787e0f9fc6517700dc168c3330762339151ce6c8bceaf8f7ea760abe3603f5d32ac51e989ef777d9fc8b602c6ed9a6e8eebc24a256878aaeb8156f95bb55c50bcc50b13d9639884be9544c2104b02b8cbae12863277b7616a194fe180f4f74265b68c767ead0fb9c99a61485060185fced987df378b063aa9409c8b6a5695ac1c4fae6fb3c95e5688afb28ad954edd4f4d690843689a484547323809dba4f1ef2e05819034847d5a1aa1fd5decf91b5b8771388cbbfbd4e58b9293f6fa5c6026853ed1a32964f32afb98e67afb6d6cc7444b41308a4cfea2417cd2631cbe244c5308fff45880fc306290f9ca992fca7232649847735969c1bf87eac7963d859c6b40cbf0a63084a9d98e9ccba0d2c9d22ebbf83ad2627fa1ee4098fca710366e5d9d3b15805df8390d18aa69c2447271039a358f32d66e24c417b969c6f8e82494f702ce7652602b96604983f7f7bd959ba2310a3943a459c635023a5298e8509f4742d804e2acbedfcc549d82164f0d49cc75cb13a9b0d28cf36efd755c4b00b9e8072468d254fda368c9cfe98fdb20ee977d8453b6f2deac72d25f22f7d6598d550a953d480feaa63237e5ebf9c70e110f1cd8abda2be07610f471fd4d34a050d90768e525b71169687f7ae38fe39697ebb034a84bfd1f54bfd8f4c2ae37245662cb6ee739f377eec736488e10b4142f89fb262f38fb92e96ad27a07bf12f3e1403d48f708d62b1b27a011cbf217f36d2640639797eac2e54610e4db6747c602e8382cae67d2eca09f3a0d85a68450765c9a1f819e829e8b57a85f4b114fe5b2dc8fe70cdf6ac77cc2f31abf0480a3bfff57c9c30fb7031f5698612941b288c51432fcdefb5eeb3c847730c49845f71ade5aa187e7d896423018316bdc401507b03cc000def18b477c850303a485728d9e3b0476591735b61f678d402a7aeb920dd4caebe2ce2b7a201d15ad89c21f259c46c8a574bf643488d4fe007dca14ed6d199e58068ca19f9bf19d517d00672072bbb1abaeec53e2d9a1f02ca568ec7e71e7c1c12c169f3978e18ae0e768f260dcb93cd550fe305cdef4f3c18f0ccc566c55d17b681b0bbcd73fd692cf42a7701053b53c8677d60d25918408001a31866ee5af6c77b202ffe58c49eb2feb623c7bd816dc4c66e9909d2e5d2686c62792dbea9fbf5b6532425e7794e6ab7ac44a48f50f31baaeef9b0dd92a7daa9ad88acc45f14cd09a90ac587078e6ada386f612daaf33abf39b4217284b0033310cc8064fb62db6d7e96166718bedd14135b23104168b4c1326986bcf5cd2f57f913da6473d98fb07b31e576b0c5417a306bb8d64832ec1a129411686c0bbeb2932050934f2a4273a76991ef6461f57f50762528ff656892c17ee211b80eed7c18dd8dc2353ef68db418f84065b7ab1d5ea2018a88b76409ffc8ae2d215255968a2f401d27ce545678885ce11814c44d1ae62a888f59108b7f4126ecc70329141e1d1a97e4e600dc33fe1eecd839a766deed67496406ebf59676b3ca2c9620c9ea80d62818eddab2b93ede383f5c8acbe72af2ff85920a4bd305a2756cc757a74b6132678a65133b4c38be3168eea52cd3972d97fe394ab512eef0b90a42bfda0e01ec9ec81051a436b9fc5ef553e695f25a9ee86c027372d6ab9ef4d74752b39c9d57bbefa642a20b36f6a20a2ddd44d24bc8ba0bac4fa6cecf1363a2e7fedf221fb47d67a42e01c8a3cc4ea5721108565cc296cc3639f02b82a56c49bc3571f0220efce405c5f762a50aacd007f66c49f89e379ebedf73cd0285b16778eb96075dfaca1637c16b551aa653acc9999927fe1b7c6d4fb863f048f8852275159b3e38c52f766d40ff70c4e4e63302b9f07bb0f1d78246eb4adcfab565900c3e0ff075adad763f5c01e71d106e1fca3a81643d82e937d19777c838bfdb60bfcad21b68a951680d57b8cd864e46bb5bdb90e9360539ca34eccc0f50920b33e9969e390e9b1f63955b74fde13c3d32c38dda8ca447a76001bab8e699714c8d568628ca1b4d2a5e93743afd278c4f1fb8315b4843af9ec19d7a449928d70fd7226eb84f1e026e81eb75e1e8a09a6caca90248bb90bad554b28f6f0dceb80bbbd39923d71d0d944d6e4f53c7cf4bc91bcfc011636ac5258257ea48aa1c810cfa976d241cb68bd1cb7622a50addafdd4b974ae96baa3721af1fb886a9978cc197323c3057dbe7269ad3ad03a563eb854fc85a02db467ba549a1aa14b583e0be4a01c6e66b3f2fa94f137eb75226f91bb0c6f7a4152e422d91c7ac121f92248ed51191799daa31a4100bf2117d41efd048047644bf205e3e3f34fa89263c6a0f45b74a8254bb6088df9b050abbe5630a93714165ba1d6e246565f898f9c85d1b12d8731615ae28e3e76b8be8f6c6ae15b58a44ef4c214f72b969f44dfa995afe0716a8009e5afc5eaea88d292e264467b32fc6402e1d0463e1caad6d935e35aa21104dec54b4a1480594e7a32c49886c3a813eb22d3fcc19b07e3b537e089c0670086dfabdf25cb5d2af562e1a6aad2f113491f10289096a01a8e2db2e18c8696abd7fe225c08362b9d3ad0cd638d68c0c5c4c613061e4ed5127c5d0853b9e5001346504449d9fb1916a393f0e1337064cbb15427dda01f3cf9ee2e6b8a5bf5dc22c55a84f73ca9cfc558865ac85a5341c6368bf4084621646c668b132776ef4ccaf2c62ad5708bceb8d1eebc52a299bd1b7055bad0c36f16501912f8bc845109f043d30b7d77c33dfbce0bc0df563a5415bed1a0149c11b9bfe24310a474453089e291f67afb31584b98861bf2fa4d3b4e3a2eb4ee51d99d7155936dc5d16896e348be69e2b44a48a9172cdb90dda58585c6ffc438152031fe36022d99bcd6e774352f91a0c3cdcc25991243126f9da767286cf7a56f0e94691fd804dd4b50add99b8da1943c6e5218206b205abb3f0f6d0e6cdafa5286bad0b8b11600acb810bca4e6a5435a805249098e89a874a8a05d7f93fc3071d7f493d41f493d135438dcbdd1bd93f9cf007d40eb278142b69b9497964d768afb370914f4aa8eb84f202425ebce2eda41124a10f3ce4a78b5b174011e5cc8ece39a063f992c3c3ddc82f94e08c03a93064e73c8df0a4f87bec0dd941c5c4ea96f12ce5ac76503d91f5ea9c31199b77b798bfc89e7f122b480f70414d484dc3336a793dca9a9daf70a10d5e9fdbd4702325e473b88c8b15c333ccc31090e42479a36394247fbb4d96f9a615d0618d78aec81538408c490d23d049c582e71b12cc1f6f918eff58176cf7a4520488f3a2c2fff1b47e023aeacf421c7df7043a45ee5262b50f7ef25d62bc2c5855f58cdeb7214bd7cb460ac9c618f16498464e7cec6fe0734b0cf3c5913f5e757876dc878e73820ab7042e2c9f2d9657146d5e47ec08f7ad946f78b30b6c090a581dbb91edaad10065a40df62bd400bae47dc4c8516db045a70cd98ee559589ee012dd80f6bca21f78d5bf5bb008e7551b59770ec03490bb94ea5dd8da7184bcd2da14bf674dd4ce0568dad763b8895381058848ae17c8268fa97c54c67b03865c27120ef3c39c50f31daf20f81b3c6928b82b5004a205b3f42040d7d965e07a1e34558332401e4f98105e846a3bd5e3bad05b5b564791d2ea876f3007c4b82ec96aa6e5d83be511d700c6447b45189941da2a7566364cf0e0589311f4b944b00eeb0a28e0c3ea0be08c2a669b71a867bfb625013e301a92065082773468c07b895c2c1cdb2f8ddca413f31cf9e8f6480f6800784dbff078e55df02e103a887dee0642f43c800f2b23fb2cef19f12c4bd4ef8cdafa33847bda588ad388776c401a51fcacc47c738e6f9b6d012612f319d1d1ebc73a86d351fa340271f3b83449deb76153053764efe5d28a3d0d3c6ce2c83053bd31929c410ab9d3054cb135065895aad8b8b3cb16c541160512dc200ded9c7478d5147bc49469e40e655725e30df604b2066fc74bfa8f9dd28602626e3fe68c65d2ad2312bac7221c9082d176acdd3ff95680019886945fa00ca3222c04f2e7f4b5347fa8dfa69fcaefb27052602614630c007abe5970af7860f5df5302c8f00c3f745c77c59783533ec17b1f729624cd743ead523c42cbf7e50d21364707cb59f25a5c53af8d7feaf1c2a2d81970c37a32daa0adecfcdeefa8ec3c955bed9ef995856d24cd927e9bc135d0bce5c7192e86867a0955819c26d47b7d1b23e6e784e4a2087b66772139413601e7fb2006a89a4c7078d25a8052c989f8b86176dc1fb5ef8833529481cd08b8e9dca49ab8e785a0fe66a137653a7871e1462c0192ffb442674818a33241a6e4b4c810f94ce72679cc4721f93870d85dbb4ee8a94707a9e7be6e8c3c6a512ce2dbe2dd52c9434c998db2e62f7b0b0e9fc8d52d4ce4595480f261d9258d92d560dab2697685ee14188a53ee2ed949c72fa0c381fbe5150462c030d6dd94db38581bb10e624fa8ec4c5bb77f4617d8c03a2d8e0a01208cdfc5042e24e6f637aeec05aa584f4c2aa54a14d2cdbfd1ac86d753ec32735c961465b92561f0a34ff2af7da9620d664eb090a7bcde854d9551cf2a91a0d9a443d19a5bc61165b3edd0ee95bb8f3e5ec89eaa4ffdcc1092c588e74a0fb8689ba4a9e0d5a3c411868256be31dde95a8c5312479497b7412f0261a4e1f364b45377b6bc1344ef9172497e6ee1f1032af9b27701183b43a1de109a65f117e59ae35bd1b94ff5306dc6ff31d45e90aafd8f73c1894792527b5065dec58155905692fab45aa0e60ab6e2092137430854d111b76b743c91106ad144ab18c2ba88f8dcee598483421ed30fc93708594688cca679ae403840ee09cd773803eefacdf83f69f250936fdc23f7e47f65959bd0221d6fecbff0c10c0264d804c2a4a2e468368276e205febf14162d5e57c1f20c81c0e67bfafdedac01060c9ea89b13042ff262c7efceaa33302ba9f93bb7cb429a6a2e758e8d11535042aa34f0ef65afbd1b839e1db6f07ddf1dad066a54e22f092578ff0efee768f0925e3749685d40e232c35b7fd4302125ec8bc2fbc04a501c694b3dfa653895befa82e6ff45f067a417e3ca21f616ddfc981b556f4998680704fe65077df6cc2f5381234145a649cb95294cb753c69260487d736925610cab000a62c4a4cfbf3c1dfe3d8d417499d5fc7651519faadf69e3a5a84db02e00bb24d9aa119c4619520291445be25f44cc6b681d7913926599156b05cbfa4b3c03c476b50c7785701d9694b2ba5188ba8e8f5ebb07cc1ad883c4155521f1fdb0b0a0347be16216e265915b103a772fff39a87a6493ec85a03a4fe71cf19056a7408209c780973b651a406e99de2b82cc340766d1db6ddfc27e2db7d4bdc11a5589f405630bdbac20964d130360c23c14f6f45d2da3c82905a9dfa9696ffb910bb8d657e2468ca0fb2f1cce04b19f86e6a0adcce24bf4d44da98fa46a32bc118da0a57ea44f86552f67dd313939c1b860facd804104900d56883cabc34000e9264604d424e87d87acb11f244017695876e888b0d33fc68ecdf25ce9b88f2e86d389e74f921594f61900ddbbae6080df50e07ad08aa3db8324d0956adbd0b6e73c14dd7ef93d8bacd9ea6519a23c726f785afde34fa3c68a06d171c77c5318dd054d367871e24cc854504f8ac40c37f9c01a30fb98b54ec47e4672672b03d9d89539368cf329f5ee20c52087b22ffa558ff95cc632c0818fff4600428e701e59aa44e9c2976d718f152e33c8bfe2d45b3af309ed9de9cca3ba56e183d9620f11658e7dd5ee9f495188e3e1c196700063918000805286635b45bf2a5b59d2b1562f2101bccc74f9068952805a472ca959656780d241d8b509208c83d74bb6329ff351cb15b994f9be9ac93db54520cc80d32c5adda835033b3e5875b9ffddb97a16e9cda8703778e0652e70b7bf80bc8ae7d1d371d82869af3a9c0555af2f11f4888cc8c1f35481f9cd5afa764ddace2051d950fef47f26caabde2844752ef1ebf82b92bef567be6dad51442a7569c6f0b8fb47ab0536ee1d0320a5130ef5875641e6d3b24ab066f392db9a37fda7365b01c51b2d2dd1c06f3d8f5a8f4bdbbcd5abee7cd247c189176425511eece639e85fb76987a5662c0f527b31c2fe3d03cdf81acb588dd281d9140c02f2765413bfef6bc8bfce1b158ab7a54413aecd31f3bfa1de8c1b71fbaf314d6709b8f1217bf665314c4ffc4802577c460111f4ff6a673c22af4b4d74adaee4015f4e79e5a49e8a8060428ad66e611a838a7b11560e5aec9c7bfe29a000830f3bb8ff83526201031c53fb8ff33edaf016800b73755b8d04e20f645b6635a648c07445581d5cd56301c8f57ec3b393cb3c56b9873487ab2aca76807dad3bbb8188f8154bba40b6809d3c8517782ed095c57434348d7d4d1955aab683726722c9a43c50474518006cdd5e8eb9560a85380665a4444ce43df07e42d40ba6f60167f62498af9f28fb7c860665bcf7f2c1fa9aa69b8977f67a1f206e16654bd3c71af4374f4bc2248c514bd34727e9cbe30fef93f7ec800e47c95e2c225a18c26ce8d86dfe23668e186d1c13c910a6281eabd574f7636732b59ab4c4afea3e70856d24198929cbd34f3138d53306b2984e4e1447231927e2164cb74cea35741a6c1817824ceedd6e87fefa4632ff5ccbc9f74a486221fcbdda0b8cffb0dc99ae2e6fbb61f3f7444939c7acc46f868c602b5707a347f2378b8d5ec98e686eed90f871d4ce888c907720fefd1185e6771d6fa2ecf1cc954b806d190244eab3c4dbeed3ef678966117a6ceef04a6c26a47556e24aea3375ea5b78f43ce97eccf9b9aa179b0382b370303f8a08d85ae406edb99ea537dad5c06bdc04f5c2865eaed568161f2a89c06be9c55e9ec4b1b05f3177cccb4a43d560e14beb58be6986bcd6cd078334d84f227a1ec3c8b170cb5b0aa26f9c67e9437ee27cd024e2ce9ea3e10f9bf94215ff73d58f49cc19b9ed00fd26bf6cca39e28c95d52eb74fd5c72cec4df83ca33881f607bf0c02a3ada5264cbd941e7361d94dc187d9bedc2d6df5e5029c2720e6456af66b0bac316e951e2634be30b8e0bf49068deb3c5436fe9b1d30f885fd31a1124bca86b999f9a4684a35c064c0b9e4cffd14473fd59e63dae7e9ede0618519157cfc46a6abdbc019633897a09a3fe4da9770a3ca91d466545d71f9174ac3090e7c2a8075494cab96ec7d7046251b89748193eb3d94293a7c8be2b0177d40ab9aa379f2d87d982d156a620ae3921e20c620bcc619664f8c39ffb6fbe82d18f93a8af9b35c61715b93bc8fa9729e9908ac6c60cacfe845fe7b26d948bcb6815dd05a6a25dbb208736d225de54a780b14445612ecf59c1f515dd43cc0fe68aca96dcf2616fae9b3a3336f869388c3f1f796083bff32d3428db3cd3ba88bb090dc30d811a71fd8b68e458b0cf715a6374e533bafe9c71c61c895a19a4779485c1f5e1bade9dfb8ddc68bf51adec208536f3e7458d3faa88edfc02e0aacb9014bff5163bef3bf4688ff5c84d147cd55d3b9795706d18b892789e7ecaa2b03daa0928238babef22679c6d24312866091910d706a3229f2904df7448e1c904c4893b4512f7bbab4ec431bd7e622f5a8518f2988f7db6bf667516af133df53bf13eb100d7ced76f7deef28096de9db416a1dfbaa18f0ebc4feb89bad14bd5f7d6ab2d1b3da0835cf726977e1f2ab8a9a1c742ec4a13f77baf8ba170c759fae2fc46ea9f3a384b4b8c46b5ff6a63049e1d61762bc68291b2672e759c19a8c581ae5745b8c56b2717d700d3fb813e67c3ab0b89c6d1cdcd700c1d5fc1d91dbc182e20b70328190d7262e58a474098e1785eeea45bb930126495e1e688a83c6191699976034976d6fd46093678d78053b1a672f90a0682c364086fb88bf334aaef5cb7a6cb8e56750e5423db68dd875413ba2dfcdd68eab3e941a5c71ed0e5369322f8f64a0bd153631d9afa110457a3eb4a2b5c0da29edf5e40d2522f436c6daf7d14d32d6879caae9bdaf82c3c38bd71f237dac6e624a2470151871568be4cbb4c52e1e17200112d6cf30ae90c6509962b98814c2e14f59b238361c8d1916643693e83169506cb72a45c63ac3009081c158a2bdc70907415b6656420934c036ad6a66412b064c23593394db9679e35b712d0b41b2ca7a19332e2a8bc3389342331a5ab9199d5ab99aaf9b1c2bc26d5123a82732bf4d8e74520a2042950de9a0a5e35739a51900e77577b0b904ca1d2eb21ebaba90f22cb5e7b7895b23c571492e204086a79d39089a01f5f8d9473e3aa1557561da5f3de90a34f6c3b54e01db5a91ebf8ef8d3b18d90845f7e8a5369927368891f3954e6820407d32f272b8c8f1fff5d81fcec7a3db46e8add7afb9f2107e4e7e8b1046444664a6ad829c0d991cbd073b5b1ed9c2e9493bf458909e91260903b9df5672b4a670007957e8e80f65ce217ab27aea8f14015b448560de6e80ec1500ce6fe20f531d57248a3917a5cc967daa524417c8ad87969b51a83aea7a480833ed1ff2d130d5f88d686908caf755c3788b632d235f1d353e9f741d3d41097d31f49e5b5d3a23143f0c881d0ab104c18c3f6be8a1e5847f5caf0e763ac14f6d32c79f0ff54faa739c0e71cace1a52cdd4e6508e95940ac34409ea4afba87b1580aaa9c1a512c1b95e0f718df8459df60f21b751db64597fcbd232f20adcaf0c6ffd34e7eb395df1cf5e11b7e60c88771704c216808155a965aaa394614697f47d6183568458a9ab7be894bd11b1cf051ed9bb4942ce006a5305d92ad2653a07e7c74e3dbc6967d950742b7967cb06abf47d1bfef6612b24967277e33daf798a49dc5dabde057b24b90649ee0ca058f7b05ac3f93328bcb2c0d214bbd02f28ed0a1862b3c449e0a1667fa5fc58feaa58ee259d7d2e6433a6fc008a0038beeedd849d4dc3a10cb29ab52490ab35034f3b39c385d0d17e9328fa142b24c79f3fb8d45100f6eb44479c241b51023f0519daad29885833a37a08f1d047d7f95f2edbe9d0df5657e7c6d9ee843477fbfa01f1a682979ee7888025ef078ecf99a6aa0eada9ff089711f77c16e9898ca6ade88cba48476bd2a04940fa0b657142314c04a902194eac5194d0263d299a25ea32744fd3514d4e925d948d8400784bc2036836a6c7722ac6add6132aed6deb8facbb22b4b2b994d507fe9b2d7390c56d6a898562ce97980f5d7a37d966ebc52142c362c8af199e31e65abf0b3e194694a6e1b1ec68685581d3273d418cf0572972a42cd856e9034eb2e35d2148ad2fb17f7cd4cf5e6afdbdef2473c7356860ccb6052aa5183bc5005bdf24e4a522794e92c652d11dc1c8a39a8c3f4a6a338d69db9b969eaf5ad43aa845816dee64fbce55d72cc69a12c76463ae066fee88c9f561d8f06e8cc9fdec8b5b0eca48d19be93cc3fa7ff95c7cd9a1103063b7be637e60005107892a3b83ffa412ff5137abd9019bdb671aecaca265283b4f7f481a095f59f40fa44450b6a700ba674931f4540018127c7b88e53fdfbf8991ca997b06e58c4abdec5fc87797916d9332f863b62160598972f408b5d5653ac0641ef55005ade563445dd80d13871652a777798f95037462ae89f5c0a2d272b958e80fc2819c22aab7014a8c2cb71f1cef1ed1e90103d3bbb2d7bbf63ee464127bef4392f28c6faaec6280604b241fb866975e90943e77acea7600f641e0cd4662e4d8ab22920e79ca469be09800d2243175f815e06cf6d547c97a2124ff74dcbea101aeda11615ae1ea3b9690f2e966e773966fd0d085746b79945b0650e934bbacfb323514a6f5686b9e6b65251fb6a29f9c8a81622ef322c339f2f9701c030e2b67855792394a296bce2c76ecd6a7ee0a5046be9c639895afadcc10d0274e6b130305598a3e552064a3798a3b2a7a3b2aefe8d7bcab0c81bcccb0a6a68dbc08491e1a832b12db36f2c76a112b32255d7b12ed08e017cfb60dc49e3a0fcacc912915724e88ac4ab361cef84345f763739bbd6a8cbc135a83316275217838562b4ab3d4d5a7b74a10111f53af02398c5725c5262a7c8db42b262b904e5ced99897a30f29eceea2a7ae50745d50b0d562c12308b96358b2f302379c37f4751b83770b9aceea6896b02dcc9de7ee81436d661a854750fa575b43028847164b9aecd406924bbee1e32942b34ee0318b1eb8bdcc800e8d7aca0e3c1bd5f0ec02187e01e6421aca2a9bd7e1e1a652ac9350ab1609a9e71575199c3f7ff1156c0461bbe8e6cc1e8066513f0f0dd0a02207e8943fc687e66e1831cc540290af2412d84ff97fcf081eee225d09049d931c257802524535dc865b086106c6740400f0a44af123e4191f0bcf11dab56df630cbbc5a7729592fa3a97887a2f38c26a13f6726d08c4099649301b4e1255d5ddf8d66ade3f836017185793c6cd7b33d6b072f94386f207aa4746bee32aa17b651c7736c18e18df59c39602fc6ed0014d61d3006d5217531610ff88ae0151b20b00b06d16042055a1231987968416dc139c02ca74b1bd0defa15e2df460dec291cf5fc5f7e99a3554e907af67a83578e560aa99ff6416c992032a7bdc7e31d3c71e920a6d5cf755894b45537e970e4e33ea7493a3f0d9e09d559d60b9ba3074e8169ee4227e6534db8d1c712502d4f8dfc26a78ae3b3a0e7810f3e8e15e314f6462dc94bd3c88d875b358bbb3f010073a428294231fae84f175413d1c84e997887c4fdaf85b51112bd2f7c655369edd5a5772bab33c5655bced747da7d5ef06d4a2ae9333d5a3388a23b81ad9f5e421400bf7e6f564782e2177cfeb57ac02b3c4f30d021cc1aafeee030ec61cabf6e57cc147ecf68621657d5a4608a14f8102725a8991971483f273c84c843bb3033cb2cebe1ab6c66840895ed6441eab5f987526c26415fe14cf6d313647ae23129b54c1d81f9791cc9332d35ed688309cb3200b982095333f507c9706cad5c7a23d9fa67f1d9c8a804063ecdc4dc61c4fbf73b44ab477619012bc0eda4209f6b3c0b0c4574b021fe8531031f6b6632a1cee79597710a805d3d0e0dcdae0288bb2f9deaecbc35aa379ddeda20ffd9fad482c40de8e44b539d08073b2c5f82436678bdd25bad028c29eefd86f77260d4bb3852daae778f76261e255f8a925f8678bee54afb389e443bf22826f5ab5672af10d5e0f2ad9d6db3ba03fbdc5e7d42ac5bb380ec2520e708a6440d0878125754871fc7888d8f82309c7b8d7e946b137974407b11b560e77b5c916477c253ff96426e4d4844781d4040c01d3806975c8fd0cb24e9100dc9bb224d1954ee8d3129ce307a60b80b6d700338fc48156b341dd209cca1bb180542bac67e8029e80344679c9b82a5e931de3b1eda64869dc561c7110949a88a5e7243342632a20a636f812b4f540bc5b8e8cb105a8d551fe589aca5871ad20e6d7a9a0ac8d1d324858377753020e7610052343b9875f9a56a926f944a4f274bf18f5a48a1d8a742300cc466ce6805133007aea5e992a78ab660c89f9a74ff4e850ffbc4f1faa310e4b86ac374da238a3214c073bfded9a71c0a33f2875194435fce2a7ac44cfb2db62b07db32f891bf533368c6a50f3da0995c95f968a7e4c5df2a51f3e30a8842a9a48980eaec1c71a25bbd27a54f8c99b6da16b70297ad61ffbda1ad2db29343a3c4083d55835a4a631da85f36f998d9ea6b82e357edaac79a3decfc88789832366fdbe8158c95c5e515d19aa3330d7d078d6c98b602d770e3de256235f50d01c4153e91b32c05d2d8117ae6478e9a2dd6996b2b1c5b5c8ca4f5d655db79022b6e0996ad0a784dc231800d24c81e3700e2658ccc4362e5edaa70e1116784abb7f273e397664254481e349232ca98494d25e1fe11e8a425fe6574e328aa44c972c5d8d6adb2f3f42b50a66a5bb97a6e1cb36f7a7630211d3ef1cb34b4cd7b4c7d04f9e8c3ab6ba65cd03406362dbb92d26a5cba03438da95d5d2d954473ad6a5d5c74481cfa4a511ac25518362279988c64dfa08a87196bd8cde3f79ca177ea0e090fbedc4d2178bab6f23f71e28a5e89d5dde0c1a108dd7bb1dbffba3530b3e78a7fec0e10abbc46345292fe9fafe43c69ffccaa6e69432892fde7b5ed90c298e87d4bd812a17fd084c0b5af8479d4abbd1b878bef77fccd006c6df9ab6244c5bd70852640e07ea15f6faba72bd79eeedabfa4e45da0110034b1fb10dc2513ddbdf81e2da9d000eb03673cadcc382cb4ee2cd3638b52ceeaa588c9c25ab21efaf0cbfe9c3e1b8c4fbed3e0a4d483141b0b072f04bffe779a0c4031a2b2d332281551b51b465be58f3d97bb576efeb11a30d27f648ba8400c795e33dc9333c4bd47420c289805a6f4095edda43563452fea7596b2d77127c4d14fdcd9b114e3ec2556a514ef4114316939afead83cb6c202f99e9db0c074f3136ea6d0c88f77357fbb28808e8eacdb2bff30f548290e8b7eff815ea088b103f07e7f1d48e6db1abb9bad4117f947f8e3f0b1eab82630faef110f492005bf80e96b01099c248a986b9c224d544fc24d7a3ab496fe02a8ef34da479cedacd4231e85d5f38e841405d1e82d4b0dd4f7611a4171cd5f4c13755e02305251d90f626c3e66ae010946b94d98621ba14aed95d69dc01a7c95259fedd81d508ab4dd82778e08a388c17c49398aabc70684f0bed2d7733bcf3eeb82b2e43bfe88f8bad72c3e879c200fcb82ca6c1c76264b19390e58226a7c316258845095bf641bd7ca488db2c30ca4e4eeefd00ff7f9d053b796f19f021fa98a6621a83cd2379062537a3d80884b4d040a48f2755476cccd89d80ee6c387fdaf8abe53c76c594a793ae1610df2bbcfd63a041a541d123073d2c0c9f1513db1165f92c66f151ff88eb172959d1c57a8ba5338fd254c75fb4ce751536c80c93678342117fab1e5c4c6dd70b4618fa57a6dc652bb0ab453677670da8dd755c59e22e6fddcd86afdc6d3930b463d1613bdee1103e60965b3cda9eb0c8dab2c2d8a4f35e14f93d653d4a2cf61242f5b86965d5aea84293ae865a7d229ba9b997b002a4af2b28410de3701ef69b0b508edb4bdec687ed253dcb0b264b479e83f9d6a8114a4658b4322386ea3c638c1cc9e44858eb995d65bcf6f86568d231c48e4acf9426c36583865e5a6c33c30796e0c0000237b15d8c9414b580d4cd17787661c8ad0c179fa1490a78eea595d3f6a175b87a0e1a95b5290f118d1d6d85e706ec0ea73d6c3744d432ab52afedf08d4750585b8f3e97ac3e493e5ec4c9dcfa7996ca2f8ddde640778c0a3c2ff2b46ec5a99fda43eb6d9295f859418f4e77ceff8a062e4250880cb4687881252139c13baf33539e931fa9d5dfc12fa669906ec56e736c1ed8cac711c7b8d01771d2c3b6382e3985d1a950f17e650a349c6295077a98d737c38b187cb331ec3ea10963be141e371383e2a6efea28013f83aed119f64131728e1eacfb049e553b31d049cf4c63c64cc23a69f92700f97526eac9aa95df640d4cc4c6cf79af33198f7171dc43e00f18d3d22d1e962676e5f43e01fde1135dd013236be3671d05548730a6ec4fb3e3c4117966094d4a48b17bd6930120d0811474e39eb33609e363b454ec4d86eee0917d45df6886639a7c5f9388e38123ac49beb856616fe200f64da439244855af92abc11b1031728c86713730b3d84985445be5a99500d59539dc2cb6de10bf8e6060fabfe47a4796d1e04ee1ab5780288c0ce975a3dcf9c63c79853868de33f35505022ccb83a52ca9a2842606b394edc6a00102655289a3a0f79901460c32cf10ef69c95e21ed719ff001de1c7314d820e3a570a4b48c7f11b503a88e0c284dbaf2a1f76d8dc5a169cce965872b161382aab0abd50fc95b778641a1fa5f4704201ca11a235aab41ba5689f3060a6841379ab08b55be85bed7e8812732d13e7575fd6b2917dc057b53a9459ccebab11becb41d354edab599689fc84eca4b85f31b57ef280d5c2a289e6be691014a34ae56ff09202413f264019cc98890cdb2f1a54bcb1b6101497a069a9517cc74d0f7a44416166aa9729161605db49d95aba5621c8e92db5cdf47219ba423ae96c622fed3e544588891943f536832c653c45039ee88ff2c87f36a9482ceb31c625d0b638b4b7bb60523650886227b2de0e211b80bec600679185e534a5958c4de602c9804927780c242bba1e4333727cc33fa6c2ef3653c1953e4383b7fe4ce798d7e0768b2f9e696c6fed9785847d2a6b1b336ab20feca0d328a511ef395fae0aaed0038ce56fbd771ff47d621b985dbe7934a87761e76767e86627e87830b5ded92914d090ba4bc0199ae72d9594f0354e467e8dbb18104383de2d8323f084fa9a89d0ae60855221505cea16280a410a7f5e9567df099decb13c44f00787e4182efbfbe9e69aae084c6babec717008f49fa4465cac54423b9958d15e1e6c296e1111033e608e070ec59ee7b0a50892acf0f25d8756a6e205a2092e1e5f2ade37278f894117c19c20daf35dedeb6df57d69183c53c6b2470fe591e306ed58befde135b0c90fb55098b3207643c1ebcc762256641aae3e57a7f01efd1e086d18031280b2c11d3c486ce67c563b9a036a2921839e048fca52cd995fd9867b7784fe40c5838a077d03ac5f034a478e765b30ceba4a07c2092e381a1a1cb94e325c650eadbb387674f220a88071098c2c2e3f0d1a0706f8f915b4b7f356f6c6e3fbe31aa00692cdd727d45c41e3805a4aa6ef74a1de0241b395bd90416878df3e9164ef2df7967b4b29934c010307a6074b075c00f194c587179e62caa90b1b061eff158677de13e40830861801c609a32150dd05872e6b9831c5481362bc281746a63830916996296dda51db01c923516477dad5266b35dc2c1170e6c08f0c27cb2a9e9a73ce39e79c79564a29a5fefde458e8b84e58eb0f4d1b4750f37cf746d0b4eb9da67d168e3e35b17b27734dd3c4e6a1fe95b9ab60f0df4afb6cdf4950b9379166d1adfa958b5ceb1754cc10b9be06a343395358bda997dec9018f348d5c691ade539d694e26f7f99ab478947ff12afee45eaa9483f129eaeeeeb6ab3027afee6ec96ff992320be56b1adda6f2fd7310297de4a0a27fff8eefdfc2eb5d0e125479be55214f2b522da47116ae5fa54bef01140693cdaa23a80f70f7e9230bd49d524a69d3ed714f23f7006218db6671e007c6a08e0b470e8be7a78a937d23754eecadfaddd14c427fc9f42f85c164a623d04ca7fc156c96bd33dfabcfacba687bc74e9f937e454cb982b9eae40aab728d29b5fea4eeeeee2468b93ed129a65bfb033e41be06a4854003f90464c0b2881402f4059620c0222aa8688a84a4a0a32025b07c0764e101684c1096397ff2f84fd9b2e7f4e9b3faf41f9f528e3a3c7a9cd0b19a83c78e00ca8204d9923291d0964e6a2da59452fb945a493d4f0469f737f4bcb97d06c06cad18bba1edbacf1371b42e0595d8b3c5fd27e268ff8d4338da9bf089dd7b6210a63c6daf31c30d80794c2167a0bb22e82cdacd7f1924de19beb3e8a454fea4920ab9ef3d53f4617ffb7b834c115a7ac0bd8ff9dab736c3116ce9c17c6bc37696e78d4703e9579e4c3f28081dba3dbdccadd11f69f6397e8470fc64ea80997dd4dffe47ee25176eb9865cb60d246daee1b6ddfb52c4a9a20ecff4bfece5a66208d9b79649f92325f61403182c8d4459249598814759c4434e99b0c31961a4591c57a8598a43de2333d6c9dd63fcfddf5f39e4ac291f2081dd47ff92e563c7353f8213890c92d946be4dd82d9ab07a42f273f80adef3f9cc5c1f9b9ba7f99ab77f13da843f5b35a2d81ec2f02f29f3ef95ddf7bd4aa592f92bf322749611653e48c6bffa1906c91d02395a852bd48cc589447af07d8ea9fa689cd5fd779cd7bf5bf8d45fb24e0674a60f0fcf196a6a5af9f605a88b922d61c78e1286807cdf3d10293cbeef9c851e0db4e5ef1d3babbfbda77e94e0cefdfa449c210fdf7b6fdf7befcdb4ce0bbd0e502c1de31d1d4da25389730d8606f8989299bf9493544b65592682948c92c79f2b25d540adeccfd9ebcffd015a80fb68b6e8974c95485130b1096b20cff739205346a1c026caa3fee91defbc92026b22cf8defe854120df021a980f80052601a22ef21817efd9a699106925a6868a0166514d3880c9252480f2493fcd5132967912bf101acafb7d37777ffa0693bedc8be0b5360a177e6b35855d46931c7693e0d256c36655dbb8ae0a37ee7ee2ac5ac3d4e60a2c70e6735cb0059e0b1597787f75cee7d7babf96821086af6b181a06670fb55b86960e8e37eb7fadc65f0a3d5a0fb6e9c90355b3335fd346f13fae8a7f9db373634e18d8d8d0dbe11c77e10c86cf3aa0f42137e369f57df8d2d0dc6cf9aefabaf1169c499d5cb88dd7d1c4aefdbfbc615ee8e128678f4005b6a95e4851bdf882a5521f70ad9861af8a747d1102fe12ceb6c096b5fe98d9faedddd5bc4b2ee41041e1bea041efe527a365de4ecbddcdfee6f275af1e9142b987df8db97568793e06fffb58c6f3d12b66c7db4ec7e11ea37984160bf93baa76192871fe71cf572310d06f9337b2db3ca749a55a6935400d1bf340568ddd6b93cdb8a5e41bba0b9881de8af5ad8e441d6872c8d4ea7f9344595332322ab3549d3c29d2be65f70faf0b8e5c161489e30a40ef7060d597f3e08fe803f3fe10938f27b38cbfd67e503a6587445b775a6fff06007167ef8d81e88a7c2f401d2bd7b14397dbc97b22c969294540f129ca1ee7178dcb0a5b423f7369459abdf63901f297459d82c6bbb7b64b1e02c7f2aea0425e17e4b24fbee16650ba6083a154f1c3ccef219fef0f0fc4c4fe238119c2d0779c0e011943e64a8893823ccdf5e84f9dbb8c2cc9af6b69338c9893c3cab253813693aa027ea3e4c25b2c80710057fb6af6d9bc8026bb6fc37d172afbd099b96fde5b82bfed87a4c214b15749c355471a4e3c8cf8a8ea214f94ba31851d13750c7728e7a72972cea1da762114d96854adbef811df6b5dff11e60e10336b2268e597b29c19515b88a34288a6c4177aeff75c504cbef2ccbb22cabf45f4a29a5943b46b2e621f0c89367965226ddbf7ddf7b174d68f1df5953068923fdab850f1681b51fc11c0dc716dc4c7411959b8916c4f2c89327e8e9e0bea5072d8ece851c986bac91ede6893c1a0ff81a8fb362803391a60b02b7ccdd54add0388eed44b0451c2404ff68ea294b724932c9a523d963fac87e0267eb48f5eef6b36f29f698d6fb6765f720b057aca738d0bb1ef300f2b7f027b44132cf6a1822c8860b2811e44237d814cb9630393f7adef2268edd77cf85e3cd3299392e6f6390bc6ddbfb6bfed459dae7f0dbc459f63717ed3d729615d2c4fba577ac8d2f387b7989b2fd9f256cbf75ace8e3837dfe4d1d27b88172a44eb8add342d32016e02985e449bf48c57a07072c83bc85ecc1b86893ecd730497bda0199a3bcca16396603762f50ce0a9a026a6ace97636247fc788feda9afbdebd6b0368bfe16024969f692d21f397b993d7ddd50ec567dae83a60f42aed9d70a8852853f68563d000979be0c7b0b6b757f179b3221b2274f4e509047d61391ee044e90b849e09b1bca490942d8514246639f0e3dec90048a0f4f20bd465687d1640926b01b9a7891e235ba9cf490fd2d069d2c7112431e594f5ed0d802af5c1006abaeb044b46857e08f0a194d94a4e0a113027bb9a19a2c8102cbe4866a22244c199f15fce586ca41aa3a793630a18133ea6c7841c9260484d48dc116712e5b060d9a16a8cd5a171819a2c48a089560cc14468492a49a2892222a52a4048922423f3429c1a1895014a5992a304c93bb0b194f5eb0e4b2800c19b4a8a1047f5352308e7944b08a8b6a097f4e705ee0ef889bdc5dcc90c2873b59acff7f106c17690e52e25abd4aebda94359b99ac34e0967365a5525a59ff36c57f734f30673f629acd6569c02de7fea5af859ee7a4974e4a9375b39b34e76fb5d276db37e5b0d5b2cd53728df20a93eb6d5aadb3ae60a59382a0b5e2bf8dd14eafb4d2776eb3f75389b9d227ad99c6b5b659bb5970d3382ebbb7761dd89bf7cdda0ddaaf5bf3eeee76fffdba37187877534a6bad19a595764b7707b1d6455ba97986a154daddddb34e9726676fb6879639ab9452cfba2cf3acbb6f77679dd734aaeec6ddfdddcc9b9bcd264d366797d939e76754d5b5976559f677d565abfa34137d544aad8743412cd3ae0faac91529e51529e5151eae4829af4829af3cf170454a79a5c99355e34a9fb46e3603294869160328c4ac76428fbb75992c228bc822b2882cc243f39eb85ac20e271a428eed3baa0251c8e2fea59222231ada037f6d8c3c228b3cf17e3c070455b24891ec7fb94dd56d76934a0ee2d5ea29b5788e61426425614cc0008d90646ef002d227707822871f56eec58b6030580d39a440666682b1374821f15044c5088c111819d1d264898c3562a31f658fe2511e9b453333df59f2cccccc0ae31ca81c94f8de7a9ed0873d1caae85eb6cfea7e8bb15be65eae3629b69aed89bc6d4667e4ed862b46463c074d1ce118c1004ad129606204b4240a8bc7e419895f60a975896187c2408161c58b192b20a2bfe85234250c17348000e34529a5d4de90b44465852e41a279426eb7980b5a6e08430a115008752942055ee010a5063040703ab1224546d499412267368c415d88324319675c09c3e435ba32fe105c31156bdaa1c809a61719504f20b1b5a3e9304d951cf450746547d3619a1e6a0394ecdf1c172ba0dd40ad5c5f467dfd5ba19ce5043b5014b6af7dd572b928513e39ab7efd1c272c9f2494fbf40a5e7505596a7156dd826d7db081e6d49828474c54da6cff1ac048669f2e7027fe90d2b3e5893fb07fad415a388309215fdc3024cc16afea638bd809a87041080c94bceacba7fa32aad2efcca3c5a8828c2434c060af979e96bd8fe052b2d3270d8a162b2f4a88acbcdc34c0dea154cb28cdea9cee02317d0517176218e202236430890922440d5ac2a8a10a315a10e68749e7558464712ecc114962f842072f8ed8424b12349c0bd380328c1082891c9678c1f472ef68ba31528841154d68e1e50b274dcc44d1059727554891d1f4a455c18d9139d1648c37f1715eba00b300735e27c78e10989062092b4b340c718286ee82059435ca8851b1c5134654268e13634ac934246b05c90f540b21c78e1234f0c1245cf2cd0d95e40918b42451228f2e9b06a6b9a19220d1b59024885b846d6ea82450a0acca0919bc319f098a74337843105d22445d12114784e93a91619b418a6302831db31d21d294ec112222990c51da1a31d4a66c0c111a029154b5bf7d31c3e4d9442d8e485111430831184119b9622404198e6e6eb063602f7717315190e0ae891d62090703b6b9bb8831b299a08b18a22842b42398e6ee22065693bb4b19360891ef5e5c3bad46e94bfae35865b5996561bf8d11cc28ed3580668e497b7a524adb29add2bd29c76c6a6aaaf429fd72c89836e6de6ea0acbbd2d9ddad5149ab80d179d6accab4d6bef64ce70c42a50c73415003d3579a0281e93e480473a99e259c00253ccaefbd9f2fa5a68a3a774518873e852a69a9429f36ed70e8aba8f8948a3cbc57fd8feef10779656a50f1078c0440c42b4ac92182efe3ef7e35fe96195146f5de8fddd485aabf618f4e147bacc41ef2e585324a044904821a38cb43425454f53c3a1ef755a20958c4a12674403c91051c2a02e944ef8a3d666baa443b5b13277bfb5ae64abd33bd08e9c154f24cc1c9a4948592f7006f842a4a39c6def7d7157f90e0756ba6de08a374ca3843ce9a3d8718435ff773b812a5d962ea9d9944b786e00262c973e50276a320232c7f896ccdb7aca825b2fb4d1c0b904759f4561c0520a5105249faa02475c8932580ce950a30956628f2f91ec53a9e02e267d5c0840c1224b2c401954487cc4af94d79a441d2444ed6b4c75a6820a6c9d5268f39b93ead6febe38ae4a886a7946a51609b459e8fc12f79d640449e4531e4c972ca34f342888c4ad008262a96605f5401c38224a64b10f09727d6e4d075e1cf6c9a539ce5b3ca5c9241338909e553cbd15ca277fcc78944f6e726d3dde97afa74affe7b395aa9f56fe2ad93c4963ec52c4ca5e42b4d1f4c04118e2e66326d89ec320827975a6262b2e7f88ce2ee3f709de74576f7291733e606af7c892cd96f7cc6bc47e6fde717fff69f6392645fb9bbbb3f552a23bba39147fae4346aa45eb2d358f6cf711f3c067746767777777777773772c3193110e3c405ccc79061862e5e189284f41a699308284072068c88294938bdbc8a178e8c79418b2b86c0f0b289c2c6e61b4ab6b1b199f245b6398112d9e6693c219bff20d77cb3c0d2bccc162e1c344f9e9971cd24d125cf3cf824cffc2b1126cf3ccb55439ef99f257248e28893cc636900ba62b2925730c8ab5779422bfc19ff477f4c6044b6b0fc7de7097d1e8e3ce6644f277baeec798f8f68cade834bb287c414d9833aa2287b7f3d218f1505cbdd739e5047abb81fe43127dfbf6f71c8d70831f25d72a2082c7f04862760997b4bb56dfb6ddbb60d8dbcbde6096dacb97445ca10b10c13b1a40a27929801851a30ace954a90f2a5119028d5c7fb284d8a2c5194d588e394344e58900213f4b525906b1913740608be54b502aa9364aa715504009134453182d0429c28a14a2a9a526b038d2054989993c764248891a6248f6efb0141833a48248a3c9882118aca00b198aaa6051c46b8c0e26a094524ae9b51d74c9fe568817a428657f0e3b51e4518c04dea4d3e4310784208c647f30885809bc647ffb2890c186d8941748a4d1b384125088b1c61640bc2891194c7ca194d21bc402bc021858d6244f07d94b1025fbb71ad941f7256b64f7f198bbbbcf69294da639998679bca14157590085ca637b69305dd32699be8492411e65103c0491e953ca43984c1f84b294e93f1435327d560f59327d17540f607c8021d3df8194e90ff5f02196e9a3904444a69f02914ca3649129d40f44c05e202a3a92e94ba3a32599be04828b4c9f2acd50f14289922f9044c12288d2971d98f8a24412519cb852461313ce052534904f316e3b70450998a0c089520ad01081132bc218230b1630a5e0456130a82b5674940663fc84090350798345f57dd28d5216252c4b5796ac6427b434133dbc070379ddb480dcdf63027250eeefef4704e49f06badf0d02b15bbf5835c3e1b13dcdbe860b65a8e25437aa1b117beb26ec97fc1e9cadefb95066fff954c31db3f57d9b54522d492d9cea47974b99fbdc0b657e157a2fc3d573a17c0fb99f099b98f0ffbc7f72ff97674299ef5e15ae5e761557ef7cdff1e4efbd5026fcdec3f18303202027207f4f12ca5bdf4be9ee1e0028f0289fbc69945af2f79f5ccadf0d483f10515f65f4fdf7567ac9ab3490e7597c1e45fe5e3265ff71dfd8e5efb14fbf3e2c63524a3ec928f79edcd6b19a26b5eb9dc5553ecd5615d9244539a577b4cfe10a40c29d35abbd8c4d6b316e4d05ed59d01e05ed532872ba85547a22c8cc817efcdcbda1cc69c01cf6e1c8ef973d922f8fb850e8672a05f059b639c8238ecd134af25fc17de493b7beef4ea33baaca513f31cdd6f7230e1c1e9fcd7429801a8e09dacf9f22101c1ef4a7f6d7614f4f0e7bf29e0b75efbd5f3da1fbf2db384e02415e2e2611fdcbc56bbb9715f80320f0289f2494ef71ab1e6cd577abdeb6eaa727a47acf7b1b5a6f7dbfbda4b789379459feccd6f7360b6958c3a609e5ebd60f825f137f48c1e28f99d7fe87ccdb0f426ba59526940971f04c8883451188f6336fb59f7920f665702020f3f64d98f97eb63ed5f7dcf7f7fbefb770eca7fcfd954c73fbe2adefbf974cf3fb1cabf37dffb1fea5287a11077572dc95e4efa538da4e9cfa3e004930164614c973ea698cf78cf2686a69a0eebfed3ffcdfcfa8e943f39fcd7f3fa5a6cfcd7fef58ba9d4bbb15f9fbdebff728aee44cdc7f38aaeffc7d9fffb7121df67df4bffadfdf84d60f70df86fb9ab0bdc5fd8ca2832493f4e0fb4f892df9fb7c653ccf84fdfaedbf6ddb7efcc91f75d6f734a14bcdd6f738f42fcefa7e0b3de6acefb51067fb9aef970dedd3bc09dad78840665e7b1aed81c8482619e459b407df7f2ac8df8ffe8d9fbfef65c2efddbdf4cef70a40c238dd8f347fa29408f42b7b69edd7f2297fdedafefbab0a65b6de5e87c5efb3177def46df3bec7b27fabe753ed10785d588f1c1b2fd0de62cfb721392edab307d6e3e13ebcd676106d913ea3237c659366220fd56b94cf336798f5be9a00b931e104d9f6d6ade28d32703fc1eb7d2718265aef92e94f91235504eb67f8b3aea46395d279c1f9f83fff13265fbe36dba441c58bb01c622f7345bf66b5e7a4235a19d0a6d1abd633f83d0c666cb3a599997f91177b788b362f81639cb7e265e226705a1008fdc93f78c1b2cdbb75397a877ec1592af9006ea7c13cb562a5b1b996f7454e91dfbb7c959f635082fd3bc5166cb3e185ea56cffc264d0b5d2dbd4f4c1e278af647b61d9da2b8e185c1d8137914b8313e32cfb406b604e4cb6bf15d91bee69fa6420da23d01e714ff6887b02b9341a28fb6d2adbb731689fcb45b7ec5b2eb80033daa36cbd6c5327349067db256a8cb7a26c5febdeff8e74a4b99b79cb025dcd344d63a2527d7b9e2abc1fe6cf02f97e5fafbfa357b42457b2efac33b1c5d672e74beebd97f2be9454641985fc04f464f625107ef93332f6527fad443b036e5677ef90ea55affaef6ff737cc1d16bb773e9538cafc89378817f6b83ea4f3b6c7d08d7e2da354e59914a6deeab7f80c2d64e3ccef29dede7121a0562dc13ab9a150e04213fcb9a1a8b04043830a944705ce724351916253c233b9a1a82cb10415a5145041526272ada042430f545a18f3f6410b5a6cb1c536004f8e90c4224d3a4f5ad821346a024017383c0d4522161d6cec50145a17d2114a38b0d876d807a6477a926403274a36ac0b29c9911c8b6d87718071e0b248448a589c6cadb5b607256f35936dc24ee0d347b162de6a1d3d4879ab37304303a429485590b42041f91f811143064a9a70ac6b0ad062dbe124310d906872a3a306a70c7c28b2d65a6b8110e2ad2e629578ab816802fabbecd1112635ae1f17cf8f0d41d8b064c3941b7007356aa0b1d87658c70d4ad3c68671642607a21aeb5241918cc5b6c34960de6a221d498a68c0296858e9009bb1ae1da828c116db0e1735c9eca0644465646a655d3b18197d16db0e37796a1285a1769881061d3a34a5714487d1141846928ab69841070e515d8a743cb1578ad81c9cb8258a684ca03009a20445d6658d9254d78f8be767c9d292291a86d2c1083552c488126f75ceb0cb96a164ba7e5c3c3f4cc654eb02834847114c8b221d479c9c6c39d2564752ecbb17608b411846ebf382bb05d6f2e8ba4380c1f9806b72770963059230546844c2443145135f11f8e6ee12c604aa24b04dee2e6190322cf0e7ee12a6056f0cac1a03ccdd858c183435711008840e4651ccf23bb0200065b955db797aa1c592bb257fa3dcbcc1794274a376fe536ebaa764523ae59c18df8cd23ac1488940bf5cdf634f489b736a130c06e66485e06c59d796837a89792a1aebf151a812a8538ed9e5707a8a9272795e05a3fabcf0b1709158b858d1551a0b172b7250d6e3b054ceaeebbaceceec0574a377a4d4b1e24f1ff9337d7ebc60404a536df5db623d6c4ff6b44245d5fb794296b351435946a57c2dece6ace10ffea1c15dccb5fda497ba6c7842b871544e1cee3db2f3bc26fb6f3006406e10433fe50f7ba73f5f5aa94e96415cf96a569b619b535a3ce9dbb073767783a0b5dadbb809e79c737663b15c7006416bed0761ad139c93ce39e7ecee06416be79c73ce39e70fa5e29cf659a05bba85e29cdc0666489fb4669addb8ed39fb8431c6371c6aecd68531b6b7d35c2e978bcb8040081b68fe66b5cd6a59a5199749ffa638b4c9066aefeb341b628c31162efd99e28a29f64f45f1ac7456cac2ddf299f6e1de5743de729cec42433a543a37ae81fca7d270688a1b1e9a7556ba929132ad0f7e68e8ed4c37f4eda3748f81c95c2c6bed83e3389d62b5562aa574f739e7389f52f79773ce11fca594726aa9928376349d77f79065c5c04c39e5f4b029cadddda5fb94534e9c11a44c9d9926b5df727b52f3106704cf32aa518d8a4319eb674b4a89e367d3b4eca60cbcc9ea09512b3717cb2da51d9b618f1226180cd474c9288e1b5028a594563a452dab56f39e4929a5f446ef349e22eb9dd59482c1400cdb5aa9463d21ea366a68d2a61afe484a29a5d67f862738abffd640614a29ade9f294524a5d1cb761518a2fb5d65a57344a4b53ad95524a2bb5b556eaba0277961994b2c810cba305735ec76ed9477dead2fef63aa415897edc3559f46db811812ffbb7769a563f876ff669b5af59e9d96fcf8a2ea9d1afddadea6e30b5d65a5732b19aa9fbd4b239c75a65466bba3a67bdb436f54fb7fa277735ee35ee8a1ba7fdd5b8396b959bf60c5082e5ed88ecebfe160a81e1e77545fb44f6d5891bb7fdedee5f9f33536e05767303678012cfb3dc6f2a15c771bff2d5ccccada9b9b95ab21c54007dc37b469b3ce7cf493329a5ddac13836f394f68560d72eadf1c4abb370fa7c1eeb7218a1e009d3a00fab76f07dd166a6fb7d742dbea66786f643f33d16e2f02fb38f76bf370a4153b6f36f3e7c4f17383e3c1bdec6f799439c98a3f48f0d2c47c43962c43926c4142421a92640bd290245b9ea0f04fe69c73d24aeb9c73de1bca27f9924e5b663665325941421a92650b1212d2902c5b908664d9f28493a2954e5a33cd56ee76deedbc95cc0c4d8dcd0d78a3014ece061cd800c07dd9e973272cc9c74031661679499368b6bc068a49a4a3e309d10f40d72cecf48455e0dbc0a13f71b08193538e4be178491ef358187a42f605b0fde408614709433cb0aa078e067ee49f811b81ee4d49ae04806e00ae1facf25242083b728e29d5cd274a292f9c4d369ed010036a089d08e6b0fa0360e968f6c79be7d20d1e1c5d85524ab3c944c3c3649a3e5c98bdecadb586dd6b7670c3d69a65f2f5249db86c36cd294c359e8c75e0095102d01e27a0e03dd56732cd9633354d27239f6964d4e4a8c6683e08ce4681664612c928b3e52fe325c9237924999a92a452cb13b27f63e6a86fbfdd6a2b4fa8d2264f688a7348b52385cf4b428185d97258920a04d8e95ef53da3647fa310dc671acd96d3474007cda59fc934992693ea0b3d2fa05fa8446dd944b574664600008004b315002020100a86440291389046921a4d1f14800d678e42765e341ac9b228c6511403410c320418021000c41860903145b40a6d916956620e8c58b37d54eef245da5b155bea42f3a11dacf81057e1df24e24b3a190b16d2d4b1e62f2937d08a8f33b05fe2af77d11da4c9398a2adbbdbb95974b42947311ba5a53ccf73502fd8f62ccef9cb34b3823e7b2e8d8f7457033735be9cd65aa6ebd83f3d0fb7c480c25b469c6858b20c8d549808d634b550476138f513aaa2efe168b75d8858415751abe183cf4eeb31c49b2a3c0c746ce03fbe5b1e0af7615314f012a284b5b6e980dbbbf00103f60b223375521178fc0a4bd31df5bafb1b3250844d41541a945f44b7ded8bfd978a68896f8aafc8422f87c3be8781a6a7d8a1a0b9078ace9cb141cc6272d4976a924b755b828c71d3a87d715e5432fbac6d3502a6ecb304b6a6606dd18ac2bf784927b8514c8903fa41f6ce0e03116ac97c15af8589b5ee12d39d5b4d026adc10e10058766c39e5c01a91d99427cd6121d17c57aca9b46ab3aefbfc0667358242e0d0b2a1a0717312a48b6d26368d42c183ca6ec5e2c2722a46d4d82757dca50bb6aed971b4a284ba88b799ee9d880099a5df40b18d7bb9879e3c319a1ad929985a3becc42375a63e5f55ce05e0e8aef1d5e6068801db59ecd681221bbac63574ed00be0123d27dc2876dd0bae5e08698f3878bb07182073073d6c3ead821e67596c8ad0d9934f90ae125f08c56a0eed5e3393d857c2e7ad79d9bf93af4810fe38b75e87d97cfebbffaf1d079fb3ed6112b0384416495f53ed681882762b1affad5e81e9cf72d3ade4750a542fc8087338ad20c37b63e6fa3c261e5de61b3c05ae1650c3de4ce4b4d87365ae249ac6c0ca0a818580305c0758528688d9e2829ee61d982e8c3b60ed0ab791e7a771abd60d06a180aab63589846fc65ab07e8d29c8ca69b86ee03d2aca554873403fc0fed71fae7903c2318bc34269d82b582e67c434f4e32aaab3afaa44198c45e94dbcb1b95b6d04060128ee99f73ecf0641f06e5751aec2b42f0e7b2a1609837bd7fcdd21498bf7ea219a5e92695eaaefd6eca5bc78c9cda1594fe1e40959720d3a3d8b7e5b2750ede4dd2d874a316461d5be8935e05a053eb58b5fec4e06e4589adc2de16f04663d8e37a827a9a55ae5de0d64afa3d1efa510a9b13e4599a9bd6e2dd50d38c4a575cb1dc29e3850574d5b3958f13bfc3432b2ae570822dcb3333ea2531200a94e874242c4b70e888462c4bf084967145344a22003420d0e0c956631492008a8516519cd0fcea7be6804e09bc6a7145e7edd58455bd4a814228867858e87f4e0c972f9c98df63a0179db413ad65a014d323766d5556b3d953e95f34900ce9471a290f951f26df9004480fa4f61e70f9c6fca2c46e23054437d45bc50d654e9c64d52f54ff785e8309080529fa3c095b72bf81c3d77c5d13c7509a52a74a4045b8988bf6317e831195a57ba89720b0f957bfd88cb496c82d7a9046d764cf3d20ddfe7d30269f44b305c762f63776b1a50ea21b52d352a586561d7ecc3d80552793ff6530623a0b5af3f749c5886a3c5105d6b39912d740cfd41c84be6f8699c4d58a466a7d6e7055d68383d613df19c165ffcf18158e427bbab91b74cff2b4105c889e168be03c20287dcd18c93667765d8caac025d36a8db9cf8d17283c0de50709571f90082c0d8ba709ce94125f4be8f6666a296d5b3b0f243b699d1bd92696e3ca789d9675ec3ce11ef78a8742a7e97de1e698cc81f30ccbf66f7f1d7f677da7f7d6e24264ad236a9a250689775c192e99262d2712e452b7f0657bf4ab1a2cbc2fcbaf948d0e29d772efc7652be3540b2031fd504d7e9072cdf555bc09ee79f704f39d706cf1947590bdb2d0d324a1d174ffc8aa2ffee0229ebdd6a75630a705f280004ffb726cb7df248e7ada78236f328b56ef198c9000581a79c1eaef57cc0576afe52fef41aab2a477c5d73341130fc1e4b358ab2a26419c3cfd298d7abc04fc80a198fc7463570b53dde0ecfecf2c7b93816cdc8bc145e20d036448f13ae47734ce854ad4b8db38b4431f7d05ddc0208e0e27271260988c1ebc2bcb3d6b4d98a3b55c54c0d81984956fc80f9f5ec79456b0305daa2a275451b67858ab06b7dd9f62b02962265254e10df682fcb360240e6031769baa2e88c714b7632ab2dd0363667531e6587420fdf257fcf41ebec6af34e265cb49dcb40d010e1c92c9ce6fcb2b7db9803c841e01027e93bb0eb84504d337ae80ac0c676bcca8e9afbfe043ebc7374014e102ed9ebe98a81a273aef766f334300309cf705643327fbca00d40600b571b9a6a22bdad93d8a6109222c0c87e6f9df96f47df94d00744c9d449de9793eaa66c31203b65d458e6e3dac7dcec378753dcc71f4103bc32c87abc59c0a3c47374070be298152437dfe6dd6b50311b8680c6e06c96a0d9e84ccd581e6d1f04e8b6443ef004af06f976d1857f2a7b2b400666361944f79cb100fd1472d5ad2a261055250ed099eb5c8b12ea6ac426bb67d570a25b1c10998e878d97a536ad83c82e6921821b3ed246f3a2dd7522a742862bf335f2b35a5ebb31ccc8db8be1c81327a5a3bbd45b548ab5c47416dae7ef1490148c62b7d3834e1a2a79a15b0090a9b990e985d2861878b2aedfd75edcf9fba90633db695cea43f30fe0094f31ba909a8a72cd14bb030dfefcf61567b4382aac035a1d76e7566e25533c60dee34234e1efa37523d220259627cceb40762edfd30156a7538e6719720b9676393f2e28c722f96153298b696cf3c0b5d7fee2aec84eecba3965e9fb7d7d3680ecc43bd0902bbd0bf1098ba9f9276d225548d69c251b8da579d70612e2be1943e4c0090eb4f499868d51584a51eb071d8e6b7b9d595d9748cbbb902f8298774aa3e2615cd59f82cd2f6d3d16bd47c2e578e72506a49cf0ecddc40bed31e0d77a6e29d081d1c9451e5110c4d7a9f857da3deef7db39496ba48fa08641b77d4b1c61814b09df1b657e629508206f295fff4c435dfd259a04726ddebc7540789ae0ec5c191b2179f7b30346fae97b3ac7f0005f75ddd4da66ca7ef85c024523d76ebf71bd29510bf5cd9732f533eaecb425a30509825ab8e40e34b11de98057fd311d3c3ccba4da0aedb1c7334e3f4789a36eb97a76f22e6fdd030f978f7091e88633a909adfa74bec36f9a7f239971e35f4b053725e7379550e0e13e88c5cab75dc6864f7fe6a1616050e1f8f1cf32ca93acb311d8458f743405bc95f34a5918a52beffe11d8598b9f95fa4dcf44c2512cae624f3dd63c1da8f33779a0945c342a101d28d47a7f64cb26e6ed1a608d7ad26733477db03b8b700ecda15f598715ce119c3845fad82d806168c78b37c6fd4d8518c2ec7d3f23a0104dd8baafc4ad2cfa3d08a23da2a7e04db11f3cefe4a8b02c1be4b78b3a406fe049f7b8ab8cbfb6e48103a1afe69dd19026ba2ab23e477c9e68f27ae3113597114ee84a40942b2c929545629d964452bc194ff25e71a602fac429fda47b6eddb3be87785668ae60fa851e6406237b456d63417cfe264596c8fadcf9e577cd287c110d9cbd405566fa30b5fced956a6f96e0463a16e08f6d41185542c3647620533df5141d81a5480326651f8d0aa95ce2e5bf62f4072e17b40406ac9fdab54257606c65ac937e3776f24a2b02bfbb7102547e257b5c24b76bbda887300a612b7f4117586087a4563e78dea045fdf5441c52bc810e1738ac247a54f05fbe4ca7c87b2ebef1a8605590052caf7f124ec6a9e8f59736c6f671f5164a51401354e7b8a79720149fddfb7a24f2ab030ef1e7353c91a8024ef50aa3be7a1ad30cfd9a01faf33ad2b298ae753fb017f46139674ca244aaa715519a82fd569aa10d63c56d6d5fe3d2da7f622274092422470cb5b010d755b8703e4c90e2fdc6e8b45e3dac4d5b1ba81fdb2bfe57a6c62aa552bf199468d2b04c1ea40f40607d59efae9abe0d52243535e3dc4e57dc1374d0ffe82a910beaa59df453f07210b539e742b9a1d05303ccab01b019e557b24d25d7cf54f134bb68ce5b7b30957d49e114edd5e1d039700edc20e1669d719aab870ec94870085f75865a51c6fe2699e1c4c18aa010dded34d70112a1aae67e3d02cdd36a86b19146420b9b6eb19224bc1ee5cb328bb01bbeac0e86d3b40dfb23873e34b13381fc2ae6d0691719da23d4288ec6a8e64e742ed356bd52fd36ed0036df0f99eb438deb53000aab7f758b12e9d0ac954f3f1aac958b953805b7f78851aa12824bd044c624eb7175a477c754a0db6c69ea96ecb6e2e50c1515e336c2fd0ba42f7c3eacc76c4491bf8459bd20378c611f0914a6b5a17c62d212394aad36a344ab78323ef1d2695caa085e24ea773291412f51fdf8c778637a10af136943c017b69a8ab737b873d1d7197923158c27b1221a96dda1a15692661ae02ce3452ee7fe369801a4eb2d3413a587975b55b7b1cec5588caec2a4e126565a9bbbbef83b7c6254e30d4674b1c47a4cb095bec488d3034224bf0701bfdf3ae718485554561e77218415408477bae4123bd473c74b7fda85ce1cc42b0cefbf765f86277a09dd14d50725f64a0b54a0bc504428b29064502f4796c6b8cf14dd4e7b8551dce428fef22b5b796b732e5ce8edefe93f0f0e0b9e5df7892fc7eaa67b2b85b2be6ab035e10289ce1bc2317251041efb5c6e5112778fc3b80bcf36e6da6c08a7152952bf04704b2814b73c6d13379aaeb16eea29530b27b04f2cdd32eb2c047c96fadbe1a2333a9d39f56950029e7da6c525832464cfc103901b02dc1498089b8ab53c2cba92f969290eaea2535068c745ce07a77efee501c9b9077b3149fc3531933f63207e25de322e5aebf5924f00a6d645953561506a1c860b761ccffc90e774ae7f4aff4bae41f420a12b99f2cf176b748e267ec28ca73bb5acf1fbf8e7acc68120a42f1d3009a58891baa7bded3138020351c8d1b7afa8b3b6b450e648b106d8e350c5431898a518adf00f264eb40e9368a79261483890ebed124996b0717a3a0a05ad290244dc970f0ba2c9b12fafbfa085dd82cf10c7e457f17288c366ec5797ce31fc680853335b8dbfcd1f3ccad320a2b467c63480d8698562f6eaa1f5c5c5a0ea38a80f7c80011b9e02e718a1081076a89889d5000008a069c7760d82f0adc5410a769945bd81787910df212d58b6b0f01010bdb5a083cdb1a5ce5a99a6075ddb84f9829b76faf59cacf41cd3031d167d91e1830c1e5c88b46c233299c3946806ed05c51cd834a578333719a03265321efe8a20e79a0e2730064919505a25e563ecd6ca8c98e0a292830d1db2631654fcce44bb50acc3e232957cfccc560c5853fde7f9f9acfa18cffff42d52aa572a20cf07de87ffb85147e25bca90b7f14a07f9e04980dd9ab4716ce3d5fce0c4a0f85546aa662185bb931f3000c0179275dee29bdb74cd23d33ae9e5805dd8e1a6439c53621d4e38c812880e37dc9060a8a6c00e1f5c9084bfc6446f67aae3147a6d786b612be23761ed939e811974fec9cf1e1a92fb4afb3e79564e9e714dd813f6ad758de3987e37c41558eda4390340fb75fac9af9f6ac10722f5dcfbcb44c5d413e885547e0ec26c29b8e189823788284447e76d3b7322dde764de8e8911575e0d6af14dd7af28cd01bd16ef8039d6e41580e78cb4decade2f2474ca546104e310dfa1134bd32328889f80607e5e32134f9a21f14910f511e0d55e803809545b6845e074a0f4e2b77d3b9d2a48a290cd5fff6ee97296fb613801b7bf3507abc7d1b06a1d8894120c84d6de9f2947acf90a9a0a85297781bf30aa293a69b301451ce3c3c83eabf684a27f62c9bd78d9a615730486729aa993df6fa5dea438cb9437f8f051e38211e9ca73466ddca38f1dff61f66297b316943d5b8742b3f2bdfb799b290410473a35b797b5e8396529d5ba00815e1d928099e0afae79717eb40f5dc55176a045957d444a7a2f7b589e3fc7f84aa9bbbf329040b57027c49a2855e655a13a35c617295552045b5382e07eaa667dbba8ec839b38b249ce1e2bcc9f2e81bbec1fba1930b2f8f9060681a902f3e1bac91ad338d9076a7bf7c28c71276e843c8f671b546466be6dd8b0ca945e4555a9fa251a36d8b99fd301e89c6d7ac6fe80d6e05c8507ed10957d932c8dc1924a6724cdcce52c323f47db4aabc56eba40d266825a85ab9a46a2b745c3595772f6b2f8c40d734427600e15715098fae1118a132141d2d133c518b0e4442441f44560b8c813b109be0e7271cc416b91f4d09265baf4305510b14c07ab1c81211182ad45f120d7276849f828515b6ac96cc5884ae4a07a0263da8b1a2289f3edb502619d50283df6b9f902a0696d22664c8d972dd5bc51695df7e9d2feed7dc56ef5ac43dc1ef657d3ac67c4bd747a18e4435a2c4b475e091b4b926f456dc0225c6f82c5a6bfc02a96c48830b1f900aa14724c15f4255a345255854503149c943c8d1912b43c887383e96f0327038e2fcfe04e153dec15785a1c1627c6ae01c9719e40e45dbf21bdeef25391df98f56dcf8e15b5c30d9994325d3a758698aefb99d506c7b845bbad58aacad11dc07edab79fbb3365a9d9e6ec62ccadae25c0bd7ccafec03ce8f8ca16562d866a658a33bb8af0d325f64b906428df367f7b40728ea24755700d28bdb2e9ed568c2af293b996aba600bb664f4c1c554832dc122856b3fe2ba88be0dfa969ec8e6d9ed853e3d57de1834756cbdca898a5c62608718d9997bb40b8defa59e9cfbd06c91a5e3967d793290a6b376562523584c4f04e69eb2d1836c3dd31606bfd7993250fac35e292ab671ac61c3f50a1f8dd8c57d2b1a7981b9b501c973f18f094eb33135f46412d326b3b41b1f466fef4b5b69255e95a2817a36b60627edf2aa0b63b00109381c6a4b264dc58e01f41addf1802ab195c3c06e5430e326f671a0701d8345ec6714a86e0e03750a2998e771f48747ee9c0e1528d17cf48c73b555bc6d205b04c737ee262dcf5919251ea47f8982c9fcff04fe098fc141fcff3817f4342113b7af5f81cc161bfbe20313b1715702f9b4688cd64cf38e40e76400b9b816e1ee3395d67be7706357c8965adcdb9d970aa9035632d38588cc11143343e8688fc8a02e0b325d58082166f4b2952b89a7325cfa2735dbf064da98bd1247c37e73d0c3bfd902471b354ce1e6b89ea8227079dcedabbdfadb4470302bcb6ec0f036f491484f3c379f0933e713d884034267f941fc901fd3119c7f888bab861194849077ba1cf4a67880c12bf71aa3d915d8a71072ea3d0c1ea9d2c05dbc7437192b1e9147468382a0ecac83e95862026b837b0d94652fd882ae70ed273931fdc5a6efa380bf889019448b845e2e8e924834ba325467aa6549851475dbbe2c1e1bb5057461af9b91fe4dfaf50104850e7c5e421b4db47434d3affb8c2cffd111ba4890e8e8c0d7b992df9447d0d1cda3b5b3d1e5153b3293f9bed0543562eb46a6d4895349b49659f139b8502215b4c398609af22000afbedeabf2dc4c0c26a0b9da6ba09bd1da83d3700f050d5a7ba1805be722b62c062a0cd766cf33ef4f72eee44627a184c9d843d6ee938a8328ace541f33704e00a53d3323f9f5c0546bf23f6050e2577084a4d8d005ef5cf432acbc5fcdc806bd504eab1344ada1ef6e0b1163f7a19e951984b8b5ca0554cf14356c5d579400b9757068c570ef9fdf6b7aec8a5e876e8b1b7438cc33f07c20b1b41afd1237bf11482aeb32d43dc2370ab3dc2f4fb530da018a8e3f635cbff4663df06a8fb4dd4c81adbcba9adee52f4d92c8fd68245e0dca4377683e384d6a8b21ccba260330f66510b45b2a4c03ab969bb456dc3e17636e4c99c22e048cb737b939e38f15638b14296f9b24b83507fd59a2393278aaeff553cfceeec43647ddf76a190708f00abfdcdafb5add6a42bb1d395a68efef7f3cb766bc2f41c7a3c99589143df4a7f553d7602f0fe3866154c98c4cae8e2b4e37f3cd8db19c2cb4024d5712a4a8349b56f9580e216c61d357b87d6bb48e98f9a19f546a4e3d055043647b00a3deace05a316ea7b195814bcb2c28b04fefaf4fb67e51193378097296c50d66f55bc898bc631197a93a0f5aed536e6cf7a49c4d71a4b6a7269e1218917003db263bc9362b60746f72942da2aed59d4f995be093e0e2b3bc3ddfc6e790fbbcc579228b6535db55981b32d883c564df2b77612084463f24fc78f656f3df4055dc1e611bfa1ab50f54251d345eaf89339268acab5d1e18e81b4a6001f9f9e5862f4b904c3e72985882a7e29c7ae1b83bbe6596b3ff0d2d5e47419331bdf32501a61ffcc042b08ef27a71a411eeed0a89d67bc9bf560a62b46572a6fd47bcef7a2afa6b51a8aa107af529ff1a20724eb1b7d0791427391fa62e2aa92f9af1b6a9ab2bc60a98fa040a5f66fe3a387527ee4a53a97820506ced5437cd33fd8a35af6550abe21c29ceaae221801ce4d7e89a3225585e01baa4ee971e765512b6635b36806aa610f9a1ac35b1b1fb46297bb19490329e588db43b749e586ac4f86bd901d5af4665e349e6d9ef5bc363ef4e6cce8e0c6c3a2177c08933de42374f58982a5975e4ca8b1f418b7e88b0026c85c06208ac88b7a31b15b9b1d7a31f1fafcf8b1ea92198f1c74219ed0fe617e9aaf627367fa9ba12f660324627e81082a0d9032294e97ac5b813a1110f512338b48deebe73d54f3a02f6e14f29e3a6831be8a72eae2f1d61d85ae790a2724ef56b30d4e4cc0b93109543dc613c52826511f02edd499b44400ceec3626fcdc6570f38f0291f39f2909d1aee015e336cab2f5349c7ba224ca740aebccadd730bdd159f1efff1e5107a282c60c96ec4ddd2d16d3d906f054ba683cd41d941d3a570abbb9d8e0577a7448b48bc959a732dbe596aa2302f63d2871475c2dcd8d29dd55cfee219dc966e97d15e794096e5679934c6cf078f51538e0236374e88ac8aafbee992d3a7c7431a7906de67a3017a3893a2b19f9fe28779c3c17ade7a3cfd7bb0d03e231c15c46c85e8eeafcaef7fa49d71c057c6caeac87b873e054637a3f99aec924d22950d64332750270d0a703f1ff36c0dc162da8459fb4935ee5e617a05c06e0a39751af72fc26b5288c6921a0ec69379fa2774b304fff014e1bc1795e01922e20fdc9c8f33d8deb067456115d058575911238801f079df83d9819e51f084bd513b1e8573f86bbf53f2ccbb1045c2db7c1eba36cae4a034b4e410eb337a439717aa67cbc54237a9542d358c3454db16c611eeb9fb5d250ad19daa4cb502d451ef10dce1c34b7f030a16971226b5c6a324bc20ee6492becfc21f7857f68d67a0b01d3668e58860c4273f43c8073861776249e828a117908800ea5ba11ea5c81c3316a7ae630922517d57cbdff26ad6db1a876043d77baad1dd323797851bced5804135b4f642351de7d2cf83a7c75d846c7e9f4d8f60f2916c056404faf1165ac6d89da9d72b7de27084c6cc010f2e9dc6fb1ddcaa7bf2630587c9bc0ab4b624bf0fc27b9aa3cef73669d18175c05aff5ff06d7811c8b972fb4f7467b6431e0c9326fcc1b6c771c90e881bbf6becdbe4e7ec16dcf77daccc4eef09c7400d8c546aab43953b20be58fbafe64050e9cf4484fb55ff126522893dacfa6d39e4966efc2e973b6203265d847e568d5232a82a03bc6fb4e206c228cef2ea91cb835fe2d71e17514ac9b695e4cfc96119448120dec4480a10a1d22a3335cd01b90a31eca42ee435bf945f75e62a3d8c0d27c855e3aadb90703895311b94824099979c3f6f487ad981bd74a4a754aa5d143d27a1149cea54b94fb710c9d4bb7b6409cdb11c42c91f228ba60b7f59d8ad747766a5f3a1ca786dcaf873ae366b6426c747b93d414ace928ccb6d6df6f5435fea80a44f80c01e66c6f55612d5db7be661f5c3e7807176590ad379253cfb931d654f981828130f97b1e725c77caf5453c4fc35f4a82b323899b4d963593fde55ae252ec484558bda65879a68b2516c1b6cd0e583dd091d91f522b8e1154520d580df0231cc98090426c2b9b3a08bb7320056a5b6a9cfa809685440cc3990e7dbe38d060613ed7295e6403c30884207385d2cd6429bd3983be82871fa9c911fc1eaddf4252bb7b8833aaab00374df80c7cf39ad1b33cc77b76c375709c5e268b6bd9eef29a94bdf6549edad298462f0d31a8539734bf90ae6dcd90f1171ad21486bcbd385700593592798330c32b353534b50186cd5227fdcbd329355b037924d64c4a7fd48bd6e7a1ad6f662985cd801e10092a1eb1da00651c59854281cfded3cf6bec228f9230e0d856c988a826e6279bcc737709ee8d8e8e12b0e3812f16be3939a909d9f47d2798701705035f485280440e7695b2a6dbac0b1edb237f6e0acde3700f00d4412f09206eaa3a033ab95ecbe831a931c1b962fd760507b5aa125b554a11c010d740220c8991e784daded71795c207e27b5f447983a0070618d41e7cbaf9d78af0d3490c6ac202817b861892705aedebf2b0f7edbd40abab70e9edeeb1bb9a867b7cacca47f2e43aa7181c1529be35bd483999c9983772848cbe3182833cd575208e4e4a366e4d0a6fef39821f39b942b1c3b78c20a95563e51d97bfd32505a91bc2ff7244d7bf380d7d19d33daf94ac0a48d9ce05fb2497c4ac92a3b8a692947601f1ee0b1e2575dcca72e8bd902a5e6312c6a2618bea8b7ebe8be01afb3561a62b50f28e2547ad342b42d2707dd0e7eaf06738521a4ade3c56cdd890b9c94e043177672f0e106da7015223eff8054e276eb1876ac728aaad1e67a32cb0a52c5d86259cdc1f4966c67bbbf187ed05b1e12e4fef4c5acd572bf729a323f03020060bafa77df6aec7cd1412dc618c99f2d1bbe08507a9f26d86b4d2dee9f9f5ff7e60e602456214021564144b1bb68db8faf2561d86626c18d99d7253d05437119b7b5388e88599f22e2798d075747ba1da6b167a13317f483b9fdc6cbb251858d3ad00340647fe37f310350e2e0a7d9140476ef2357e8b9a189ea6080fd6c2979033d90eb3f6783cdbff7ccc6652d36a00392f1bda244beeae5b8a4a476c31f288a966f78db9ff48765b103b253c9720574c907fa06459ff00797f7b07b52e80faa79b5f49263dfae3da73d6b2a0373d36692278da42fe252b0bebed1bbaca63d780e32b81037dc336ba12253dc93a4eec58c232b2edf82fed7b4a40ba57e5d797a52ac222575bd47d961cf2ced1125b53a167fe5fcc703e195b3d9bdeb5e44093a5c648513ead33a7073ed1e79ee41285e9e4124c824998ddc7bf322fa86ff56011fb36f9a4212639a6f1575a5637af72a65d30b7b78889f43a5723b77813a56bc4913b06c0b6d99499466570d36e85cef5dba890b0f7ce43a85635c4dae609146e5ab2a94c08e6d57109f42881b2140f7297100d0d72356555de740be1f4b31b6ed929b0b5351535a3874d563918bbaef92acca310f18103a8f537925fbf0315b895680fd01b0afc22299e88f1aa661db0c13e2c31bfdbcfe29e8dbf154c37b2c112ba8a4bdd968cb85658489f13c9a5f256d89c484853ddd4a7ce02016822f14616a6a8af8c5dd6df713cfbd6ebd33b65e99f5a77f2bc38401db81260ad13d866daa323cbce6aba3701495337f01d16224f0d1e02fbbf77c115732236e9c956a8cd3b001bab860b5c17ce9d9838a062b686fed38cf4bb8d4a8b7eb0822d240cd2b0ece3dd99bf328f6bd7e71dd153e852ad50392b38a8f6bf0d2b2d1f114815e4cf74523209000b030447d11f1f3e6e39fc532bb7b3ea90192de1fb582757edc44535b91100d064ffca66575cb0dbb95533439fec815a3e7f4b0524ceb1ba2d753798b3634a127b064f86c04042260fdf2febdb873a509ddde666337058fc124a07723a37c7c5585e3aa0ec57aa0f4037eb9168ae0463e0ddfb82f1ea74a9bef8b7246491472f51806363648f661281d45f478d00dd0b491d039dd9a3d81a2bcd1181d92ca4d1a9a882a5f38ce6e24b59d4502d1e88f9c83559d676354490993936a41c627a6b24ad1e29795a9a1b389d938f93be1c2e50a77fb8adf4eb73f69515c60f24efb7fba077f708da86fb816f545e0ae97f3b1f83aca675ff14992f4d58c542537f05914bd981205ac485192e3416b3644ddcbe5ac449c418a834dd27658e38a7a402db9dd04b740d51f38d047605cf1d76e826c79984b01a887b9758c47de2fe538732b70b4922de84bc1af641b2a91e53da6e385c0da3a37fad30cd08e8bac486dd6780b10885287153a673f0ee92b204d5405c86b1d28849aa960987cbf294670993c9789b4187a23a718dbbdab911efed32dbb1c358c49c9fc99a582e743b76045da1c69aab748e654912296d3c471b3774fdbcde62c9c82c6a3ec03ab8772086ba742193aa06baf125334a13939d051728ef62f6fe842498327332c5c93e8843f5c8597884c498449533d91fe58ba1cd32453c7822c215c40bd0abc6fda7247bc77e9440f17d1717c406b4ef97da76967742acdfc2182a4c924b9e62b2986451a9cafe8ebcbd33289d3abfdcc6843f2b4080919e00523816e6a99a893b4785909260ed00a6b1a9a26d680a7d31f78fc905b3ca8bd1d0b7c9af7181c15e2bd246f2ebacec36a69ed1626fa5f7754118de988e8b78ef10be8d0dc9425498d33d07b8d5536256d141fc60ff93da79c362d9323a71f88819cb75f65168961a80c7546805900c08e342d5c3348230b355f029299f22f6acbdf1c202435f88b250a198a047fb2f6e17f69a1176f14edd9a98e4b8008ab52ab48beffc7c47371db0fd8be368a1111cc3049053936ce37a355d7cf38b966130daf00e68e828b681d2c8046cfae55ba757fb7868e21a5785af1d4eec3d2a26229763af5c5d51f4d1a9f4f468454eed8281922a29487540ebc58f2882051eb442e9a4b108854d89cd0f8647a3fd36c3d86bde8640e5b6b1495bc319d0dc8876dd0f6ed56e71d7e52a1b5fc3a67018c18cb46a38f35f32b4cd556e1d675a28d3a0493fd59f940419eb41e9d95ec19f4265d259d61af14d2046aa8f68b00b1878ea9017f881990d456d826ad548478b17af4714426d3df086911457d7361f3ce840a00b4bb5783e4b78e800d1ed38080426612a410d84b4c51c6a12883487b9f675e931e4d03646a231162d0120b7a99f46fe7f0006269fb7853cff3b706c8eacf16a93166bd95442ca501b8b2ec7d2b261b52f3446c966475c1d35d7500a5ac4dbd72cf7e83640d6357e3616bb64b81e49ceb2d51225f978e799b2c508025e5ba29026741e40e07082d5bed1c36bdb8e68aa96ac23bd3ef01c168035530a4fc4bb2a9cf31fdbd6b682dc52ef0a5d184727d4347c1b12c31a350000a0f16d18fd4b3aea342e04a5b7f1529842be45f31bcbda12091de6863667a720755f17de09a9ed53f3f578bf21a86047f51cd0ab4c985b255ed73ee57dc7f81bb2895cea88a6f6992ee76ac2a01646a29e20289df17575a6f259cbc380e811e30e3f44c64df53473a7557709ad0add60d6c5656dd299118aede3c4ed67c6515ba8f06a905f4dffd4aa7db21ec1b613c0c790122f0f66a150daf39a5e85262549773848c5cccede8a142ecf46c7886778316397a0b16035a0e76f8f18a76d59ce09f244cb621a039b36782a9523a59e86336bdeb47fa8b06a65bff35235c3249e9c80a9aa9a7fa854ba6589168fc539357f929c3f6ce02c2121957f6395a357d2d907fb19d5c0a3dc445734fab87381959be144076cd474863902d85f2508dd02b62e89c8dccc53ffd1f91bb2800896cc13994a7c45eb268e3c42c4d551d8aa5c67b7c9a9a260394404e798bb7a9db60ba40cd3dd80e270e4b8988402e9f5ea39b75a064589b8600c6e03270c20d778c52d45b7959b2de1d0f45d89ef64d8d470b55e212053401cd480af33975abcec57a1fc5e9af6ab97d4d00ee299ce57df730624c77b0b2820aacfb622aef9411d836f8881f8de5044db43016a58e6abfc4809dba0165994d4c586ab84e9f6e396e5ecdd6a98faf4f8d9f4e5f5b76d6a4884b6959fb736c458e062b0d508782fa11e11471a0736510df769af70fca3466d2d060d69a0dc352f150a5ec8ad35ff59709c95d041d1b883cd34e8b334de63bbd1f4099499e0428cbe30d6f3ae4537a006b61108b594a10375a9bc0438463727118c26ff05c9163fe302f53c34574c098dfec94aa2d69c475a9a54b1fe69846c6caaaaf4825812730b05460c63c6e09efb9331d3a2fffcc0c6e395f2d598fd1f9c9bbe09b74b7d0b29baee2becd8c5b046a8a0ff2315894a283c514fc1250dc1818438b057209347b41b8e6711a73c08f0c6448578bf5791e6722812952f4728998d94d9f2c3443b3a38754e721c2286ed37d0d9c6e44ccaf49bbe2a3a1b432dbf116ddb98a5e0d9dcecb4fc062910c0248f5d218272de66d1a1cc9fd7b0b12de837bd1febf69878ce9ddf744556ee11f566406b2beb1c66acc562e737bdff455949c082757ee317225346ae9be6f2d528ccdbb430f1de269760c40bf35381a3e888428bd35f865975ae55faf2d0821fcdf776fffa3dc8fa0410fe27c35fbdd5b0a9d3fc4aa7b8d98581e3f93f78f768903f1f25912554abe9114f1ed04833df5c5727af743d981e8b710d73241adb7e7073c31a0cb2a7b3628d06b9e6f4baf1d622ae21d94bbabdcf0a347cb2eacf1eadb6bb46c3239f31f2e6d60783eb661e8f3ea88122d3ad555f365e0a40151d5ddb78214511787858e8fb78939b99a033b4b0789a5f6894b4713fdf034d972a0e3276c82f171a380d860c962b99ea83888a37e484d1990366f6a2a5e335f45d9944a4a39471030d2ee451c7bc8709c9a04dddd7b078445425ddb654038f9dbd2d840456155949d37dbef1c4e6c9c989f7dc606775c276db65f522ef7ce3996374ba4397bf6b0ba7b149880b55bf9d6066b214317799333082e24107def603b0273f71be52afd80b7568ba5b578740690cb627a190b5b04162c7487dfaef0f06d3afbed25d1edc146ff72cf42f6610f3efdb106ba6a888351b87d9a36d5a802ebea03a8536c5a9782ba7b875a63678b98170f2362a9c003a2c0106c318845c3791d047dd3bf51c5ce182b707a5462bd918117b4f275a961a8817eab4851155bd3b07d73a2f4c7da3dafcf5302487c92b7a665502b5e7931df0625a753204afeaf8ecfe3ccdff34778dd722b34c938f05fe22f46ecf19e7dcedf6c6597e8328257176142b7f25d8f28402ed49eac6915823131958f2ed75a575431a3a753a659b5caf2dbdac23adba56228142015f2db1be32b0156b9340d753b9e06095d49bb80d558177e1f509aec1fe878e6ec6475b0fa169da5ffa3984a78423ba784aa027d7d67d0813c0c7cfa97a5a1635899fc237ac74355f12d89757a42177f28574d1ae64e8f5bb9c44fb31f77c7068df78824e682d26040b5431c1dffcdde99893adb480a0e2ed8166b1224d0612f2bdcc7f2883f402271aa0e84eba28d81df8bba5dc065eea6a73498cfc265286122a0ca8e1dd9a5b128cbcc7ec125d004d72106f4dd97d33a45adb0616570ca3979933596592e76ee80192d8b10942bfb54aaccc036123af81f81af4e5c0941d4c889ac5a68470f65416bf5322370d2fab49440ada3a0f4be2fe05d2e4e0c6a16d30d5b2b7c24c184b964948cf2c092d1bc767b6cef90372848d5de82dc3faa83f57dcf2b7cb7b0161a34eeefbbe82982ada37143c72af06fbb5a1a177720e0ea4315ba62d36743b4b8283ac22b65eb6c6013f685473490c08be910d21ec72b31b80f56c8026393050b9cbfee695254c6daf7a0951211ef2ac0942b78624361d6436f7815607dec81fdfa2c56b50c509f2c16d72025beb788d543941aa7393e32e17a9202d4f013d0fea20f77f698e82a06f383e0891081c523249800d3e583f9323eef43656ce10a69705d36a7dc905c2f291406ca79b4389411f23a71bc53906262870c503d5f8d7a8369afd1c262950062c6db1239ad2b5ac257bc511b7cd47e66d08fa0f18608a7ade9329636352602f37aab534b4d3ce9b9fdeaf6d549de3243b8c8ebe393a8fad45b707039f64f61e55f414a5c7e052a83ed94c33e460cbd2692cd2c17c0806c8db45eae6ec8826187386051f0cc1bc7102836d87ce967c543148a16c2fa22a512e8428c6df2db55138a4a3e03e8471b8235cbcbcf02ed95276b83603eef0eaff6e65506a81c980b2763ea216b88339a4b2194c806e56cb4153cc76488108447b5f46343f19c33cd0f7fb12899aec011f3410bce5811b91c53e84440d359adb0d02a787796b00f5156f9e7583f9b1a0134ea0204be8911a3b7dea2a089cb22442d0192db6576b7f82bd4cddbeed029b5454ed071c5594be0a265104458f40bf823e057df3f28679bc8b748b09b887f809ae7a435b7bee2642d2af23e0023e0ce84a476e38f471a150273967ba7c40c998f41010e524a385b0792d43610a106299bed1329354f384d48d9f929d7daafee3f8146e803a2a098bb43cc45f62d5c2f30e10e2c0f281e0ddc485458ae01058ff1b380de6280f1c2bc6f9cd81d79545bf84ba7e8343930b50ca43756b0babe1db998d66564cb985cb7bc9269eed6cbba134246552944c389b5ed76eb40de2b4012b1cf68c68f6e80c32560b0e871c343a6b0bd10b9ab7837e005c82c10666d3a3776cbb81a84b593709fc59f1581cebe649ff1c687425b26e282d43694065acf58b87e8a21bfa538650075b7415a5461fd0718536d18cc4e60ac178044840a2625976c0c183fbf650a041f0f1c9ad7e8fb460e68bf9e2ab9b96380781752330b01bb7b9d0e5fe706d3907989b312afae4bda05aa447c1dd1ffe91031017f29ffb7e6f21e8576761a729e957f99d7c2aae498b5f33c96e7034f1270b78de5c54b1a865763e5e193133c2c65a9bc49a73019c0723bc9a4a0a5394e89a10b4c4b15c4429abdf06c979413756ca6b9dc2965ad86e20e49b65d14bac68e43d833011bbb5fc77ecf5f7f684b0c3f8f213209ca9e58a0f070cb5636a9f7cec05aeed9ba0c24abe2019ff43607ca8fd9e5c942fa8c18a2c251fee57f9c3b0fdd3a4f06218637ca01a592d03df0564e9d1af6eb395221220a6df42b33afeabe88c2a3d0246e3565cf71e0fac0a9a03c72cdae5f5c9b4c9c31dcd7e7950c88560d3652586b5d8c74df89eb37b1ed0eca69384dfd6e485770ab1c9cbb8e8ad0133e9d4c3e35dd902e688b0ea279ee9223bc002ee3554cbeead9602ba6485cca9498264964449ee694010a14b94dba915cf9f43632dccffee58ac6697790cc460970187317b4a6f3aa256f0eb4a176a7c2b30a0ff72803640c3fefab02e6e9835485331a0b129761082eb7b6f7ba9ac78103c54b0f3cbcbe61d6b1a20fd46a2bcf53b04466cf4f0e3f9e35e381f83220233d44c0b94dbe96d740b2b7c01b24bbef0cfb085ca9f3082dfdfb30663dbcdc310e8f43f5faba4d3c6fe5073b4464eb07745f0b2c93f015a89113cfb93328394156e83ea1c2f0b97f120d1e3a3ea3f3c7ebcf2643dafa4ae39bf7fcb8bdf040a925e56555cbddf1a025fc6dde47b57c4ff4c0f3cf724e383682ee58103c6225bbea4890c8e24cfc52660a833b18f8559d98aa5c4741eddccefcfbbbe90e45329ce1abd361ef13f861ec4197d5110ab04b0620dd39735e2f2e59cb5b7c472c002d3eab503c04a02b0bf4213479d5d7b527e96298ca8956d7d98e379e5b9104455932d2cc808739aa8ed0cea12236c5d79ddd5a9478ef8604e89823931b9fde23fd4cf666f931af0c5067f9a1c6916899f3ad88d645750e2ff43dcc86e0e306291c63bfb7dacd1534edb888bc835d5dd13378d2663bae31320f6136a3e8cf959c4cc76d23b39f144b4f20d1cc574d5e3909fbfa16495bbb1a74d4db1907adb1e4f29a19208c6d00baf483506c2f1835f4b30e74321c5d84a92959cb6a90b6a21403629de4d097d26143441ccbc179346a63f6a7f104c442a8b66ecca88938a49f49b9c5624953142002e35ea781fd0f6ea1d443e94c8f28bbe45b1e9caff6354fe43d0417cf16f02e4c77a3d11c77fd44af2681064cfc141535dbf5577522324d6755d66fcfce695c90a6cb307147a2468260350420dac8302e8fac2155a570f145707c34100dbd56d490b5b9e173e6394a4e7018fb34ee2951380eb4875af48d33affca621c05f29de67442054e42879f326300fb0cca8170735fa1a81a6f0f65b2560da91311ae72eb4237e949fb2c944a35b1e248ee854526fcf4d5f78c48e6059abba76aca4810ff3a8a9b914febc51ebba11c762457e069db47a295853d18b5204aa8778c534593d141b09859d2e65d6678c9506440dc372719424230ea7d33dd02dcfaf590954075867db284b8827539662baf9cf7003d873e56998b760ff123c05dbedd63d4818980b44a6aeb830901b886d89acc14f26b4e10a47072965f695a42dc154239a13ae1be903f3e04863222840b24cc81806b2f2d012c1d681075a226d681b5833b9016762a4abde920852b063f56177a411714b5edae3dd879073275cd3d38ba2fb532e3c421c3dc1c34bde6050269034ba7d5718934057764ca7e28866e5602119d55148184552c59e4ddfdbf6e2c7005010fae21bd3062f3dfeb7aa418374d4b90164364f3434284f55699e5036b1c9cf6116c69770d60c2604716f911ea643f29a2b2fb3810f548688b6ba5e6afddc6100088532d4a52e3ae0b76142a43580b654199bba50ff36892f8fcd5fbd8a6928d04582a96ca8d3a04e3cbe69e3012e268b2b27164c00c31677226a317621c5687b8c15cd4d94ecf3c59c530d847147fe0016522e02220a7e78f1e9cb38c520b883e1b9d605d48ffc1693b7a80d2ba063658ad1ab77be810d2c59dba47eb9d6f17be8ca2a8cc02612fc121203255041683609c3403b765d2b3c7ca68ace78671ecb6e7ddcdb1cd71272b6710566bb5910ab54c90475d881eff80d691562f927e3bc03f5401aad709ce2a41dd818550c1bae0852ec06845f16c5601e1f92d90e95e00d009c56896652f43113d9fa1f841406cad4d2cc74e9176bb48b024996b278a511b6f9dacb850217e292182006ea9e243409de1dd989e5f9823690e2d49ccf091e91d8c8153353cb66fe8a5c442dd5eda19d6bf68502c3b7ba0c2431eac3eae011caacbeb51b41eeb0eb9694601a13d284cc504718b10990c676384c901553a1b1f2ae5bb311f45c6472a22ba7632998be14a4f68fd434f08a0044d863097d9142a14072b9c57230a9d463e145ac9d9242f1faead3d4dff7908803c2e3c71fc1204761e0e7b121ec52a23a2dfeb85fc437adcde11eef5962c27bbe8a95e7e2e0be3af1d261c0b2c677254d60ebb9208dce0659ca155c3c4bf9676592524453f7f9705a6e3908e82fa7abec471524c00bb421136aae3646ca3b3652146daa9b88ee0e67e78375b3a3c963a7a94a7042b5d53934f50cdad2488b8a3c534fabcd5f960adf1e8174016b48acca0d19167d83abb4dc5a3c9bba51cd0380ef6ad28a4826d27e733f168f5a40ed76b8418f5ce0b5cc47dd77cd126121042f22dd09f5bfc6eaa574d9ee8da4b5b2a5cc51ab0447e084930fc1b5248028a60c0ccaac3d4e33e02781d6e735793b940e63a6e385e2939663bce642364917985c142042c449c71bd0bda70588c8a9c20f0c8cd34b2f54979ac734a1e74d11321da40aa05ec234cca7ec76b05af3f170af125485d636d19e7e2b21a90111855b66ed81dc2eeff3a1224dc7398f302cd480a3567d41b29b7adf03b319684649f5e8b7bd45349a3a3c8656eefb1a0d8bdce6456f69fa02b7bbdc62ea42ba34c28e8da1e615f1e2dd2734549a3ef49b025a369eaa58695d59ae95d248d0e43758fa5ce6a4768e776684f788dbfd7e64a30ffcaf4fa705c6bd4eed61a075a68ad115bb15ac8184532af157edc2368f80b9b772ab2f47e9b4b2a618472a534a0e1f6a835924a20711187285709d06aad95851ef2de6d0499922018172aad358d8e540202ba09017d40f84134488f8571c85c6c43975b6375297097c46918e60847d112ac3de93696ff6c4ae35d522127cd418d860a216717be8be2051c1acb4c586093e68c2d4d6eb7c2824586ec8b81ab2b05aa0ccbc5c425d6c4bc4d790348fcaeb82d938819b7650cef313840155bf50447fa6fc9947bc4f9f3c50474b790f901dd508a2523bc6f30bcd514e04ce0804b94f367eee160e4e93d066f8b2a4611132c173129404a13d290222685bd154ff2415b123bb4e58e88491700dd9a1331c1985be862f069a3840d1ffe455d9e3fca579d154975b8b446beca7e1c72e07eefbf7f71e7c6e7482558bbd81c3a4c01e430fb5249c9e732901b39cb77c654cf219007a04331a207771aaf6ce06105e74e64fe005d2542403fc6560dfa0375df2d58c8967ef4e49c71a2dc7e87396edb8cd93ee9b8f4f7b435dc18251b25c49b95199d12b91e840d40b6c06b66cea8013f9e33bc9997ed610dc65f753a2f7160181747372384c002100a11c886489c6a08382a0865d33db4cae9f711902a634ca0d1e698076c874f4d6bd713cecf5ee5650fbc3cf95528fccbb54085a65c60b7233c8e5355fca3ba621b0a5e871ca542ea703455ba56af3cf10c8c78ed888fa855f158156d57b8d3e1f30edfb7b3e8c0d2110d140f1d7be830506772339f5a9483de4b088069fe33efde23c613e306627f8ff67db00f3c93c6a7e43ad0ff523ed0e7be0e21e069ef49563677791fe8ffe98b017ccaf5e6ab7704912cf755b5d30d13c916a673b30c66af7b7ee70ed2fd61629ed1ec1c9d5871e6c94242d5532b2ffd49b2ab019122be7f0581bb858808df9429dce57394e10d97930ea9bee7c0e41220a5795380dcbb58593c9c63948f9fabce719db3b9a84d3eda00568d124f0c06e08a5a05bff5e6cd111256709337526cf2fe5993478a264ff096620f357f7e9dd85cf8ee3dacd4f89b62dea5824e3251e1dbde5a9a4e80d4a47f9e2e814d679a3cb812791148dcce87dc31dd00ca505b053182aef93df5172b1fa130c1a09be3e2b41cae1cc5b659859f5134847f6cb51648c6f67ea3656e19ecb0638f1a1cfb8a6646a7df48547cd4263f034c091e5b5dcdf940564bfab504a0787b8b7ce0b6309a0218c22fdd246d1586855e148fe7db2f9e4a577a0bfed5df829f5fa22d53d282e0f1eac17c078d641170f89118d1a542a073870efbc84de03863a5d3204e39227eb78396303d870324be7c092fa063ed1703bb8e7633d297e3ba94e25865ffdf44185acb0e41fc72c035f7e415f7658a6ec084799845806cd5a7ff07aef731531503e1fa0c043e275d95bc7a55a51ad51a890a5ed138f688de2426c5d86f3e0063420885b70ce7d9794958dbe23f82692c5c83d46565700c91ed7faf2c12503c6150be834cea2294e30ead2f193d83e1d17d237692efe463a029c5715c4dfdca9c617d52880a71c1449155dd2d8f401b86e9856d4d89cf450ed081808ec9d70c5de8ee4830208c20315db396d3ca9741b0a0d5ba00a54163b5dbd5718ec21fb21f26b71ce327e69c63b1e31987407007981efa81cf379265f44427cb3a53036261524c067f6a0e52442f1736aa920fc2cb4bc755653a82a3647b68af03b62338ab5409236b3542d6985d0e6b662be25f5810c54203fbb5239b7a6f30ddf09b6c27392cba0b1ac875b263aa5a5785e2d40caa8eed95bcb2a306119da4e448ee11a4ac5cb034d2906b5917a1378e6b3bdad42c8a3ce0ca482a4dcd72dda59befadd32c1f522c80371098da17f430925e3683f5fc37bac7b52e8f6dded7e33315e83b551eefb1cd78fac6c62baee591085fe75e69f37d8698f570cac1df4894e62d6d62b0f345093ea25aa26f4d336e617ec1465922cf6b527fa287d705890de29d39aa1f0dbce662b88d4600c9a0705533d6c9382c6b6f3b2ed1c5a56bc29c82c1a1585fed7b18c8130cb426324c1a98b1017a52ff883c84ebd0259ccef97573007346281f15df7ec5ed12743c38a389fee4b75ff4baddcaed76460c8890bd5b56826b9ecd45096d2153d20620ff29112e164587738156b37fb51af6a06da165a3fb60c01ea409bbcfa9f392b8ea4ddbb37690a17757d2d3a32413bdbb55bcc31272338a85865d7aaedc3f0c10a7f23a6cb97641b748d10f18c7849d067a10670dd2043f9c2cbb11c7652bcf60631c20c1a60b48f21d595e4b0ddcf204812d111eb51e77438fd6c63073548ab5e9ef0e4ebe39b49cfccd39ab2a053f560aa7f2e7d8e67b541b13a27b295187c896bb86e8729eb7678a8202d18a801bae4d63c04edec0dc0a648efcc39bd54f654d0c8ba4a931b3a37bd01aaa65b9a0ecd3b66741dfdb0f6cab804687df65eba3d5bacc1f617ae41dd03368d0c385bb668e582a87e0087d04d9aae52ea39343a3a6696b59e93a12c1cd51642995c27971d465a0cf702fceea43ec2b85dd3b67aad9a0368d8e249d8beb26b867b371d59f0e67b22b5b334cae26c61075329c337d3c1144f81895a1f9b97b301b89d3b06f924b09dc92beb76786f700b6f5ca8128cd04869a7ab9a7d754c4d4d55fd0bf90eaf516344479eb6f62a675d191505eefa0fd64280f4fe05c9061f67df2bc79a973e8a77a7b7751ad9d82e7bde92065733814337ef4014ddc8ede7a18e44a9c90fc47163e0c0aab48ac59e08090f5d7a096406ae583e0022fb95735b459153c813cfa54a1fef8331b462bd2b9a891695f3ddc5d750163d4d142eeb03ff5e14a05813d2130218bfa6e65f046c62c80f1ef3e8549e67d9251150d50e5a1e5e1f83b55ad6750642ed1126f5fb3ce008af817e615cc55e846a1c68107b107392bc63c79273f3d818309adee725ba3405a190c4f6691b80ee3166586c8dec212a655fed37c24d6c660c09ee0b4b8e64826cf4a76b3407b337b48107c288f4ef177176228e857a6816d46d21202bfb981a5feb844bd50ba19944e05e950465eb8443d04a230b74079d38fcf8714237debc24c654c0ffb3094876371d857cc3fbba565fd5fd483bb1c3e786af49e2bfabcae0d94ff3823b74cad77208dbd1d31656e2b485aa1bf7b3d61375a0d595d64ac40d220e5af3b65a7f53b1d01a16679ed30ab00f949fe9c50ed371081cb5dd9d9d81990dcee806dbc59b850758bdb81fa71cd691aadc8bb2638f399c632be119d811a9ad20b10752c5bd806942a0238ccb7a0c51e65655f1a0bc32a417fe963ffd05c25708b5f7f4842467fc60f6892e4689bc7f2ab0814bb339f9a3b55b5a787a52092f86ba8b6c757fb78fe1dd7e48ba05e078a82ca0ae6de26549de3323964423902217e055abf154edac81abb6ca53cc5801c28e0db45b6c4130f67b1c459ad5f24be964c3044a3d8273d31ec144f8ad4842592a4e8fdea62d1970dd7655a1b0b0bea1d992ea2b05a8d2c247eb436c39eadcc07a96f3cc7bd2b5c89a2ee606daa53cfacc239d611d4d9a296644e83ef9202f900ee5149f34d8511698f4496b32eacb6f1d0a3b2553905d2d24293970a1ef81aa3e0a074d573a304dfd403ffc7910236c67c80e49cb522053f7d863721859fe1f01dd03ff3cde1b41dce93f9a8d779b3ab9367c05eb82ff794a4170e5462420e6cae523724631d2bbf16fd2a8a82f12a15a132765dcc0d3eb21e58a5155d6bcb22274032acdc069b2def4893586938079a594fb895293075ef1c16ff5a1aae402d28e80e83144c0e5c4c95c13e99a68ed7ea1d32cc69e0ff7d5a9509bec68962fa53e002d5fd9d0d984f1c42d7f9490a8aa81859304d2603f078c00f6fe3cd59a1e36ac788bacd4582203623b5ec37d9157ed28a71f9eaa647b0c0ce4b72c275abf16c0464496fa41c23cbcce1d0a9ce7ddeb58f07870cbc51709c1cef4a9d78731d3af9b642bcdc58cce5f2fcdc0ad48c2a640dc6922e37891824c941799fd62bd9bfe0dfad71622043433d57b68f5c75d52504274d99a0eceec21c0d55feaa59547832b85c81ed7c725cdb80709adc955860ce2349bda6b4fbf3e94c1330cefd314ccf370453704ecede1c81e54541d6f697c58c991e1d678a4ec810c02d945a4722323115e9467043df975539bbc042f1fa40c00318a9d01470b16787bb4cf0638355438dee1e1eaa5f3a0501074c0b0a8544dc04d33e68ccbe35902cd31e1ecc0de3bb9be69a61e042284793e18d07b686a84647069b8a11cd5ca50df0230da0baf3dc144a46ef159a8533d41059af8dd2a6b68e6762763444bf5902796b0a3736aa22d42c40da87559da452136131b5f827d362dcf98388e9b63c842c99fa56f0738cf818426fdc8cbc20ee9045f17a323d9720305a39389ed3ff085bb65861947e1c08db0dac8abb0d0f04242f748098d342882d5c79fbcd4e980f63b2da194d67a8ae398cf0e4df40b819fdcb5a8c276487f0d196613878d26fb943ffcaa260367d48e256b271067b289da4760a20faf37daec360b591c8bc40c50bf3a19b26426191caf704b16c68989368a48a1c9832a733ef582c0a7b6d566fc8af3c6927faa78b360d90e2a3a950a7b10dbbfc977f7f50d1bc711b205f23f1dce0846d3863b5d7d4d9297a4b40f46cc30b03de5018bcab5710fc6528b5d79245f2d776ca8717e9eb8b60b12c856c5cf9a0570db69089cdc31fd40377ce29dfc839fde87a49065abd2cceb3fa3ba8d217e0098f9b82d0fae754a44589232c0b6baf46762c8ea4223874b33b45dc4b868c9f4024dab8a3b68616525ddf1cb888089ab57550c7a8fe5957020e95df3cc1314ebb28f0308a96371b1109e6038f3582cf194b6f887a5c93e905d6711bf72723d9b3ab541a8e828e9ba899f3830feb85e4a2c82eb79f80b7bcaae280dc2b60e44c5e5a63bc3cbf2168049371d640eae763a816a9d36d912b6f9482d79189c4d1a7018b281566c3b2d601e37ded892c288a1a6186a391567ef8a6a59dcca0f88e394c352c697f478c81bb2c865cca694409f85bb7e435d4ceaf7feef94e5ccd4bbfb9bcb2d45574144662bb35dc15be9825289b45b9ab2a431b73681960d0ba6928727da9c9f50736d813d5d45601f4cf993cf64c5a693432a3542152f4ec44ef4e431e066c92c9cb21c0a041e17b4afc1dce702f577a89fbff9af316a5e7e16ed27d74111fc3570860c28f805e2d5a55536aca1a517b23c57cdca7cb10383fe93c0ae2d4ba860a67b94d09c82a62c5b18aa37dc48ade0c87f6114f299b1118f9e206f0d4e88944fc762413ffa2087d220ec70337c2a869e73d661c1835db528b577efdee421ad2ba03a9031666c1a38fc22f1d62b265d615da3d2e879df0cadbda0b923ee1536305fd6d419b9fff68f1c3c0c74d4d05df886281975d1884e4caf883911517b9f722e262903fb9de44800ed7a053691100ff4f22b2510e385aff8f08a33d89187e33234eeae9c55c22f264877166456747a370c60ae2454082b170b6ab15f73d73028f5bb6e8b2f09871efe078a9c8cf9f51f646a41c9077de38d1b103f75cfd01b7cfb0b64804f6f166d6c9d63bee9d34f5356d4bcef05599f283c935d134ca1254bf8d0b86c9db13a5105a43d362a10d3403182afd047542d334ef539a260577281cdee4fefcce1fca712bddb4024525e0bd10b830b372573852264df1588ec4fa3bbf3dce4a04a9d6b27a0ea6cbd36736982e4c8ddbf4b99b42b1989ec3ece63d314f548f625798c60aec3c7b89d2ecc6a790abeedbc5bcdd41c0b03166cbcc67d948b1ccbb4b1d02106fd092aab6ef83eb531f3670485cb19b5e0b0c10ce5b14c475e5de7b5ea23933b614b09607df15416357cbff29485e0fe633ff0f34ae4f07237f8140d08279b6f492c9746ca8dec28ebed31553d268e01a46c6d0f7d2509191021b9d8781ddd0e80944ddd8303083981d5e19d10a0434740840990a183826ba29310dc3cf887b53190522c6b32a22462e3ff4a3bd7bd4007bc47df731382652d639764db6545c6b28cd5c6f498a6a973fb6124d008d1999ab87669b7e7617bc55bd604fef642b0e577ad6873e97e546219015097b3d57848dfff4c0b7ab1efdda0388bb038196fc1977cb74a11790b4b1f1719a93c4865c3ec2092e5a311866e0d7330345a93696d1f8b0374969c6d7878d170adeaa2f800deaa967238da4fa2035878691ae5f72e119f9cd181386421025417007d9f51bbc24ea020085e1ceb173d673ee93836b2cf8805ee801774da21578541170be1b63d1a6af288431c4497b491f52333d6a3d7aa74d54e44d179a3178d766bc17fd4e00d0e184f4ef9267e270e51457e0ed3590864b6422fb44d38be73d781bc93ef091e0dfa905418998659db33dc8543c0f6d8696dba26558683ad1bc1fa4779df54537ead4d1de6c6f5594cada71af201c119f51d80018b3f70e1897282dca043fdb9a2a94609ed2afebd3920ba9dc90feef029404d8dbd509cc56606a6553f35aea69901da90653278480d890c266d50b5d65831e42d3b50e73e27a0cd5ee11512f8db3e5c8453edf88c32e5f30754a884b6687480593957c6f337bd28388d804ac4b29d6436ab3a66bb7f9b3b2869d731a608bc972057098d1d8647c48830dba9eae062c8d2346f1f00a46b290c7c67f5704ff2af02ff8eaee996c7acf330bd047845a64771dac4100c2ca68bbb459820bb935f4c643ebd3596445a6dc459efce4a291bf203ee637a781b2caffa65e772370d2398e76c23abf3013ea49bcef137998e719e5a692fcc023730e05da4f9e186302de5a46fb61164519efd07c19b42f613d751bfee1fe829d5c9d11eda210aa94c12fc98141357334600d425f8fde2f050af5726a73322549e9fa86841990d0f0b6526b35fc3106632c556c755c8a89e808dd7eb9369febd0eaec443aa40bcd55d050d4ecfd567ad80133bbebbf09999dc3d5340cef0904c5d50930c00969c6736d644e943dc3f50ce4e408caf46c8b478fbb86bbae3bcf8171b661220f76f1105377a3b2ea1f8de2a5658f45cbc1e4495433b5a146ca74a6b6a2a832080a806f1c0a38bcf1e33e079289368111404115429e9072960ec3f8442e8c24ea10ddcd9d9ed2cfc6fd6c021ff273f71de82ea92ecd6aecbf46bda10bf4e06d7530f0cb43a8829b55ecea0910cf57abd839dd824087efba3cff371a2972fec334776126fb156bc804751c1cbdb14f16bf2287f1fd887fb48f882cc2e282f2240fb8252be167ea6856cdd60112ddd6c509b52ab3330cb8df515439ffc520f0fcea97845b41df68d13c9703b73b69524815032d96c9600f90f538d083ccaa62550a9afecd950e67baa3019fd142fb7d0e1becc641ea821003b6389903f30df073a9530a4b228872841c40e48a504f35bcfba4e54d2b1eee8444b800b56f6896595ca9d1ace803b2342b7f3de4ac6be5e63fb463632a3cfaa30d706633674d1b2d44e1a30222451d5e07d04edd125e97c9c2bade003d84635c92b544ca59ec6799d5648c732d7f2fde9aa90576a60438b84826da45b66af406a796888192b33102e9208fa7470a8f711fb2f915f5a232165f0d6f84fdeb50facf6d824d1d5dc72645fa5f9538b04aa4022d8870679d6b1ab4b32abe1589b383cb65da3ab2bd28945c85af1345ee70ee8e31a32fbb75ee621d87512e05b7a9cbf2a17e3978c00e957f80c72ff46dcf5321e3f4fb820f6fd1f552b76dcb2f37e4f712f4a4280bf4967527e05bc57d5ea1b45bf19d20601d2ba572749c2cd29ce11f32e9562cb99dd5f6f168c81fd773551b9b7d74b8c1d144a8df31a2c6aad9f96542639f7b80daa0c4f0a5202f30d5858b009ef4e25d0c5c27d5c451b7352d86dd81d664212e1bde6826dd4f525047f5a43a6d74821e3ede256e381b88d7a2ab46e1c2e9731a3badb87b765eeb86e07ff05834456e19046be120362a7643d07de4a7f53c0ad4a22d76d651e63924630f756e9c3f5f71b2fd3bcf852cbafba83c3b99190548a67a3ff50024793b8a1598e92662ef5a6d2c455e71719027267817d45424760134d96c903612ed99b597f438ab82d665fae74965d37dd7baa936ad462974ae074ac27716076877a23883e1a3c796ab5339e64b6e4a2c09bbe2c305c22c0102375d2ee8e17850c381ccdb04c80e012c12924e3dff7ad2d37fcf8c9580de65ab0c719926bc250ff65669a8142eb4276a647d28a56486150b895049d78fe63d3e20ae12731746dec6d012bacd99a00194f5024a52e68255200a692b1d6a434983daeeb6a812640150a22a519a05414a902885d2c146223dbb904bb074b56cf6fb1bc11500c175a7fbaed72ae5a8e3034038670567f8ed7305a4eceff30d36738c241bd97b93bdf796524a29030c098a074a08689e5ce1157c29f2c495c5e54b87e893cb72903525e28824667563a8eea8720cf50b7f0791325c57527ea879adc9d8699c5a541b1e9e9aaf3312af21a1f7862151ed980164c6901849d4f6ca39af2b1d5f3cface68a1d55003c3813373497a58a9e2ea5166c6498d351c2bb8918121791b81cefab4ca5c2182a546bdc2d793ec424a2cc70d151919355a6c28e5236a6d4d5ef6e8e4f860eb2181139688ef840581f19304709454e1210707ae0cd9a50605adf2c426e7628a4e2a8791ababf6a5a3d683075b354e94252c2e1a5e31ac69442d8a3f491216464eacce855d9aba4b56466dc9eca0f78533cb9b21050d1a5b9139224ed3246569a9460d2c189f5de049ca538e29457a307982a783a4a50b0d952a727a775f7862bcd0ec4d5153c5882512454f67879e1c15c4b0c87049b9d180cda4c0caf2a54d0d3d3c23e49028634c1e5cea964819ab4baad320c4c23d6e319acb642fca050c2e6269675ce2510da5b9207b4e498430f180d93bdc59ea884a2d4d9e1e1cae361ca61036920a132752da98d1983163a745d9c13f781a189bbd1642b4ee8ae4206690285a3f0b755c49bece38ad6973319addd2050e9b1c7b566c4eb66c00f5b2fcd04bdab2c6c42d910a1b9fd190c7e5879a316543d20099b1259832d75565c98c194db4be1c9cc14d41a3a6858f39d6fc1125c94a1f5c111c3e96440103c096252b829296c7c3f1143aa43550a6dc905d918d70689591237d5e614d558e6c0e5e6c49425595c38ecaf431a6a9529283e7d53406c4027496ee840548640fd6086324242424352d45a6b0c5ca8e322d622bac61538bcee45c6ed49ab6967c1c21d16e8c1e6e5bd4ca10018344274903b347788b2bd3f704a5491e06359eae792c087b430477566d7ed4f092c3fa2246e50addd415986cf630b3b0a0c8325313e38595a7314588cc39995a82240a19e63c63701186b4365f90c0886166375c7d74e82f69645c4b122b714ccea45459e1342e0b189b5d024809337b9b915406c6e4816387cd8fbc1f7b4f5648b384f665f4e4a6aaaae248c5a52d9168e32507ae499d1834b8ebcdceee478d2545a49026d604e62881ab8225ec0b0b3cbd133e79884b570e35715163627770c0321c2867cc0754e16af3c20e471930180a142f3c1df499d5b235a84df181754605048e8e01e5c9856d866f461c2ebd34176609c09352d7e6870a6541aea00011f9b818998ad3a74587d786303e122b8d1031234e64f6cc1d5076940a80537b930705ef85d7984877ad00babe5e90cdedc831450794270bc00d699b2383d7c6ed7d2cd19a8d94e67f194781b244fe7ebf9fba96e4d8833d5c0d75193006cb18af366c57a6ace2907d6a72709cc1407a3b72a6e6a505c6db1b1753c2e440db13cb336162f071cd68aba149cc79d4f0f54cc272b6081836ada8a6206138d0ea7e3f34572aa0b9d8f3e1026361e25e96e80bf6b22070df3bae1c2683160745e6055b41c3729ea1a5fd3a687c0647099d8e1b5996aac24cb93b32726f4a36ded6f67e81858d4d982c344d546845d0a3a7305bb2aaa2be9ed43d29dab363e26224a9b1a912c5ed065ad659415f53d4dd8dadb73ebc81c9cefb39a5e12893e3478d1f36d0a6b6adcb9bbbb2c1860a952e7cf6468a9b375568b0c9aaf1b4e4ee05d69b955db632a7d0902c5cd9d32226af490e2a71c6acc0985458daf1c5084ebbfd03da10b1bba52759c2985265405d6e8a5ce18115830c070e1c3c60fd3e39e7b2333daeb6c9bc52111657d29e96644dc935ca84a155bd711dd15bf3d163bbee3d3e503ab4ca7879d965d9c531699c85298f821cf90244ce0f236bdac089d7ec0918146334359e8d66eb78f0d93df1887b43e22c8b8c05db5d182d73c6999335373833318c0439bb137282664d96387168847c893a4369e2c2c5e6652f8f8c4a32822c5736bec8c0f184a94b6b1d4f7c6968bee400b3c7c5842ab213e0068c0e1b4d577b57f8aced0cc8887696b5ef2ba0ca4a8c257d726258410bdbcac2b106a9ad89349f328f1f2a7652e698a4a1cad22255b5064d0c8c24153638d966724c0db1220246aa05529671e6a2832d3165685c2d9133032487f71a1e8c763b484224e9cb8d0d0dbd36273136ced918342e9680c5a0b1c14c0ff7de979d5616042d4c0e3740e292cc18666aa206fadc6c619183eb4ad275a3d7228cde1b30b2206693d9d86f0454da9c9d297541b282cf709b19987846c61a1a7c5fea7684c1303352e6e842c6c7624a96306e3ddc8eef317a1bb0652ddddd687183cd466132db61950447d8962147b4409560018b4bd0db4d37373193fae97f2c04b244f83bd6a03d606c416cb8bb38523196285d3199bd883362d062ba13e2e5d5d5830e6f0c4f6a4d4e1e9bbeb5bbcff8f6c6292874754bd6e2f0947cacf5c0df5a0f7688b35388aaa62f6d557a5a7864d3851a9e0024b238356df4da4cd9c08aaf16ad095f7db65c9094295339663c51f1622e3d59e1e7012a0cdb585d1f4603b323465918b63748b0b29bb2379201514eeecefa9ec850528524f605ef2c0a9f9a120b262c18582cdc146192566475c4c692747c79422565cd16683d1cccb5f06a0af3d196c403058bd1215cd0607bd3739bfa81b39325681a24b51769e20c61d241a36127655c6a974c07eea8e8ac24c18a62263d511bb1b8ced810c337e662857c6f117ec0559811344c5630b8489345590efb16173665a349d252927e21a18ebbb66497fc5db484df8b54260368494df2295170981c1d6be5f64633b20b82be2e2b6821a3e3059a3591f248235294b6b459a345ec0963035ce1c29e87fc053ba0e290a9427a6361e780e1aa8c2b3fbe58ad690335d45a6bbdb5d6d9ea22b9a9d9f31284e90513312bc7ca8e8a373b2371e4b8a511c3255822bc5f843ddcaa8a1416300eb7caf310138e871829dbb85b74636b6e38a911c3c8d545c6f80434e4248919c3c6ede9ed6f0a19921e2cbce3b78cb658701b2b389eb498f08919ae45380e9990124846b2d6aa7e54b1186aadb51612ea5efceed0c9606b8e05d414b5262c701f8ff2282a6d46df8f28a73eab7da15c2c9a86120fbe226696ecd5e9b6df0a645109e8e222cd131e5f5166434b6a95c4222e8f18be9e1a2c08b1e3b719e334e29f44f8fe20c67fdd5b837ec2680f854fd7e47a76b2a7e84f5224d1ef8f0696e8feede93efb5651f874ad7ed66f7c6badf5d9ad10aebbd6fb83bdb44439695b6b7f3df9d93350ce2399b925d2eae3c0e0686eb403b28fe8082e7ea0b15023b1e838011a09a973558fd04848dd070bb9baa200eac11f1fa321f00f3e085fda382c01dca17cfd2598c19e2f53203ddd5a10bfd70004ea294f10ee06cd3f98e2b7bf141bc04210347ce8baa887eca5ba5a2bb8eb5eb2215936b23e806eddd8a2baf9f303c20b8545451e368087f48f1d450918174e0c62f885b3a7203c608e8f2836803df4e8ef49493c547e6a83f3c7bff3c1b7c1df01d2169c165860836fed5a64df07c847b81b82a94645e48e558d7e30fe7ad4b1b544c1e7f8773e98aef881d808a72060a17e60ba925d8bc82276f0f846180412b843f0f58b803bf0d7e8984a200458a83f98a6503142910f8ff5d2f59b18c4f0124c3ca3bfd2420f05e7c59aa09400ea81ede35bd5aa3c888ad85d0258a82d68c257a05ee20ebbeba7608baf64df51cd0cbf16fdea4362dd0dfaea8c35f0e703ddf1a700545158222c4c81876e0618b01b8a84423c1f1f2e04a1014b74b3bafe122f78fe9f78c5747cd3dce745f907d335043d2802f8fc2f3a02f85c04cfefbc11e623787e47b53998a6c8fdf7385d6f57df40ff0181b0f08aa66902c7078e1ffc11f8e4aafbce9729f0277ef913df80a8d3cea3f8fef0fc09c12f9f4725010bfff920f8e507bffcdf1f759cae21e8fc81e9aa3bf0777852abb17027d5798b72f477d2a3ced314b9eba8b7e96e401f988a7fa6a62adc3f6221ee80ff760980ed469aedbb72547cb56f7a04fd1acd8b951716bd6ea974eb7645ad9bfacc43da83047648bf04d643087648bf07594391f0f390b6ba58217cf610023ca42f6087f45f75fdbb0e78c7c331fc7669f2bd56b28ba5d0bd7c136d4571f6df9fe8eb35c5e51c68202cd31e0d181d812f3a4205baebc286ec03eeb00275f1c50f1a746103d64551b4d2a723a6bf2b60fda75bb72b569da321acdee9c1c22e5ab0baed82e6d52fd6c0bc924a44c6711c1330aa160b8df24e81b070bfdb15a72e14ddac4875511455f4f153e89effa77ceb658aace3744d9185fd83fc58fd29d53fe17e70bf547117fba89e96c85a327d26a32890d43853890f7c14033ebe8e1c7800c298a91ed3651a766885f20f67ae2893ec9982bb1f2c2cd4f809f6ea2ba69262b515f88a9f90277e62415892bcfbcf17b19f023cbce2c7380516558db1de5157e62fc51d9f6a26bb21742c51fecba1880d5f757a7e9d8caf69e6b11dc24e473fbec3c26c491283367ce5308ea336c79f26c7fc62bac930dc05533918c7afde8bbf6e06f782594d3e87315dcf7eeffa41838e31067d397321dba8493e9aaae824e658b81f03277ceffd24f246f7a99a18773875f8893e4f514cd7cfc772e767b0f3f3d87992a1a9908eca39e8fcde7cf373ab03d11498aee8a3e85137d314bbffd43c7637885fe2b82ebe511ec58bb4cf087033b87decafe5508eb8b7d4e548e23eaa04e0c0019f31f55ba1b5688b3783dbf7933783fb5b47e142a407173f24b21f853c670eb9a610c5df4ffd1931feef45dc0d475da72beefa4796296e2755f16ec86f94c7fbe2c6588e69854c0a44755da1d657f1f78b188c023c0ac4ffc17133b8a7f8a2aa9bf05577adcde73f587dff388efa3ccf1781fffca35e8aff3beaea0f8ebb613f991ae5f107ab63f5a2fcc3bcfdf73f752d7f63f0c533096d6a539bfaf7faa7f5bd2850a734b399ae3d28c628fe80b986ae5513fd6d51144ffc3bd3d5fcfdfd87e53a99a6d87ddc5b87cef8178332be72cbc672d0bff224c9f2f6944cd79efe23b91dba9ff9aa814ccb924cd7efe44a7ede7fd4c59d3389f59d398a62f9e24e49bed312baf996a71be8a6ba964f8a65996994a5a86220c657ddc7c73ed9c3f83db803f0c7d7e74802d7a3fed37911d84c57dd4df344cb14bb9fe49be41be55f7ad1b2485f992bbebbf86ee7f18fba98aedfc512eec5757703d611ef3562ea37354992e41ff571bca21c9869f178f3932f223fa9ef28aa99c6dd80bf848eb53d1aef1d23491f9f37b70da0a03680da006a03a80da03660da00ca92566b1dc28ae3d636e32b8e98ca34cd0da0b815921bdb9b1f609ad7da10da6a2bc4b8637cf1bd434cf35e8c73d67a6f714445e09ec2129118d3b5a7dbf4878ac09d8425b21a7ea6799e680ad400d4d1e17c672718e4e1e9492dd81e9e0b172e0477b80ef0027ae1347f172e5cb870e102be18ec08658a22ce2f8aa2288a22ce7908c72a99edcd56efe17d7c5515290c53b818d3b04cbdc7a228e80e6489503ce78ab014dc2bdc92cd91ea18254f60b7647394dc9876ef9c5888d6ed6f51ea564d817b078d45c02a502a337a43ac5a1527dc30ab240f15cf8f5f5f7bb506ee37c21ca73f25b04f1e1ae6f4a744fe3c34ecb0837fe8bac36ac924a03da8384a3a5bc332c4afa2026cc33c828d23f66544042023c3fc1ff46b803b94f931c644a448f16c7ba4a565e34a8baa20369a4859d2190267cc9b384baec2ec82f0d59295c102e6473c381838c8b45468a2bf984cfa4a8d65b76c8d7969ab22a64992b52fc6ba09298267860d923b136ccdee005f7494c18bb332a4c89c99334aa4a644856913c49a4bb2f4e07823078563eb6a0e8b7da360bbb53454149631e1e34bea4a93677ead918947376c9c5d3951d37285dd2401bb1265f656246d098f8816217130f0f6f44c25615b004e6b94f425c9bb93c2204d0693b6acbc3033405cdc07f5c34b5c5f18365d6c38cee69880b579135666011375a68b4697385856277e2b58391348f06263b156d663870c138ecad41a1adfd458978992ca091559ceaae0e022b514e74509db9c212ee4662885f180dc901d557c59685cba284d699333f724c8942126721a104075a131d584869331788f015b6669747664f26a9840e60486d37a42b54298d3163959e69bd0182e62764c407ca83dc99033a54f096d070b934b03b6b43859f2baf3e266024f85346db8a6d85083b2af48e14392e68b8d521319266adcd150212d4e8b8c581967a2b4c28547f605c3ca4d1cdb89ccc5c49713a509b9ecaa888eaf1e4bccdcba6c518ba34bea6aaa73e1e68491ae1c3eaee6bed0985aec1aab232ce2805c2121b179265a18798ae174a704092acf9d28cb98c072220bca0c54962a4f7c48f6cc1392204fdc6c69428273424a00d6549172a3e2820549db9591f364ce1e0d2e24275d5fa4b69268b1996e47536cc294cc9cddf812c344db89f20d450b2049beb264d0e833b31c7952b24b43650d6d8d893ef783c98991aa334f3059082c4c7cdca89145cd1413d05a00a92226ca11b2246d3d8ee485c9115912838893395cd0aa8624593c272ead2770aed4da903961460bcdd5dc5919a52b26db52df155e1128b9ac1a274a2f299ca43e3c2abe2b15b0c4c981d36a02034995a50fdeea946c91f3d1e4ed4a1b34ad392433dc04a1020128375263cea4f16232add83742d4a8a96257c766ccd665a59105c96b732a3b0bd242b20294903268b6ac59e54489a625634bad2d4a0e342526950e676da2a4b171240c088e528e39a1c12d6d0a9b2a47f4a2769bd7d2560fa92d34785c264e602b394889464da3c42b8a0a31e86e0449e392f555a587e5628a9e9c99a92b24be271b271620458e555f929b2c67a6148be624cf4d995d9f0e2f1ab040c29155c5034b0d242382b49129a387b5e3aefc121ab32263af0fce0d87b9c6268994293342ce50697224a6d795430d08970e366a0558f3834f4b0fb4a7bb079099a32b635bc12e2d53999075945a30205645162689999524266cb939337764889a1965a8c51e192d70796665473ba4da7040a1eb92854a1a0962d87c2d89a9b969f161871b2151d4e0604265b3d17d7929899125af4cab94b35686c8615252f5058d0d281b60c3d2f1e5c51b1b3c2dd7376565ca1c327668b6cb91373092e666d8d130a1c16c6d1913c66c8d060f35795c59b4584ccd1149a27624e34c9023545c52c27c996747337adc484386c88f303586f6ed09ac26471b565d9529382eb6701aa1227d5ac0aeacc151b9a1019347d543af87dd100318282e9eb2e45ab099f58b5584ec4b9e19932bfb45898fb92b575a6ac67887eba47d6b02c3613827dfaf7d1243b3acdfb73859f296c8cd9dad0d2f0f2eafaa1b2c8624c10deffb583551bc5418e2b4021bc336ae2a738638d56036b4589a74850d71aa416b98810b8b1f64600c5340dbd21f194b67e07819a6d0136468b101d6b3df6d450b27ab0d6c8853a0ba610ab65b2106e4b7688972985f036038482c728bdc227f905a2416f983dc12db5a8b69adc5f46eb2b5de60b80916c3625e2338393935318dd0e4b403458a32ef0643b8062cbc422096383ef1fd5e04b6ef55ef6fb5ab0b0c0ceccbcb07070e1c30c61c386049a33188e1faaa28cebdf7de5bebbd350f7c775787e9b01caec377f8ceee122ea600c6368e02189750429b4e91e9e8e6e42e1d551a3030b02faf2f3030bbb7d3bed74974da7b5ba7eb9463041d75a37013c64c4d1847e5d9bd61065fcf8e339698b136012c013256c622d3517b6f2cb7f7defb8ac96e6cdf285f1cb5b7b8b7c64f7a6f8d9d98f093c651380ae3fd984a04aaa2f8fc37c6a7d6fa49b424b57ae7ee06f2372a42a73e5888314f817650c783be7fc72803afd729928f2d693b89df74c37ff74ef38ec9ec61e749754da15f5c6f9906d31d4caad7eb7addb9db75e78c9859a4d43a89458a5bff6eb1ac79f51f1eca5d5c7fdff32befe758fea8b3b7baf2a0ded13c3a45a99a2feefdc037371a62cc40bff6f47c9e3cc11d31fd534e5bf5fb3ae68fd4515aea66a06d50e10e3884a9d681a98886c02a02da70545d8f8457dbb81beef33e9ae68ba7b6713358ef85d4426af350464330bba96a1b77c3feff914619a777bc726f84f7930531894368bf25434242d21ae2fcf7b5d65c84ed5bfbecad72602c4d4b94f7df5d5a22fc1db85d2dad1093e4169fdce41637d903649b98a5879f8a87d60fa4ca3df0000b811cb0c4b5f620670da2861194f84aae1a7ace36d57987eb4b25977314e98c9d243f909bdc98dcbfbdf79324f97b92fc1edcc1c41dd027513405be1ecf9d66bd75f6cef94dacf356d71419b849f249f2499224c9fdf9b78f2c1a82ae45fcfef779eba023f0eba8366bd4fc6d9aa48a4937fac450c5f5ebdfcfa23f7c6a92240109ff3d8afe54cc847fd8a4daa6c48145ebb883e984adafef17dae807e4a3ea7af4b3f849b20b33e1a79bc1ede46b340419d5c57ffd9bdfdf40e2389ae8ffd23504fd47a62b998ac88ffe4547e447558d85e4ede7efcbdb35c230add06acdb2dcd99920edf6ec45bda87b40ed1079b77a22408fefcfe41b610f4ffe4e4b34f19dd3124d3cbf26b112c9c487ffc8c447c8849c62c2a40a7ef35ebef6f49bb30511fc728704241cdb11932420e1fc773e04e698738c352a62f7bb6efcc194b444587d8017beda38fde301ee8c6590a7642f43e820eef2c4ad0375db65eccd1433c374ce9efc3c3cf8c0b74516c4ef799007d160f0c7c3f3c1204631e6e9ed3c5cbf8886e09f4f4b941f853b62e74be06989f8efa41aff881f840f3ee75fa6fcc79407310e9ea77de0ce58f2ce13d460c9843e0015f594fc7a89daf21203cd0b14d99b32f8b7f361b154c63a9fda7d4376b19cec7479d385bb3eb7585f4f93e70cbe2d53a11e4c85bd27f836a8ae1ab8f3b67c9e1fdfa26379f200531290f0e007bd456fd15bf416f7de7befbdf73ef03ef0febdf7de7befbdf76a10bad65a6badbd7d5878557d72be132cc951dc411d0c0683195f0be5971016e62c667cad3e621f042cd61a694d3702071a981f2c914dd7b719dff27e99c74c6bd513ebabb515b7b05d51e09b73fe9d73ce188c3cf5044e326b7df71d4991dc24a94992ccf8922469f96db3178ba2a8ef632d8a9d090b358945718b3be39f10d3344992d47fb3d6bfadd5e338e671c4e338de711cc711485fb918e39cc9536fa125b2d68a7a1c3511d39af762089856bdb883cb97b8be160be92d4c14ae940d60a1b56f7a7aded7dafc287abac6aa25719a4ee7e22b2984af9a4510be925b1d48ffc182afda075f492da41e597cd53cb0aefa0ea3395d47b7ea393a8e5ed5a9fa8d6ea34f75a95ea3d398c157324a89af1aaa27f5a72ea33b19f5f518bda9c3607ac157b2bbe0225f6f8173d67a036df14b5d665c9e7a6f511cc79124715a0a893ff39aa659fe70ea838620b1baa210eaf7b7166ad89f2f0ae679a22810a8c3b7e69c732e8a181571bb5aa9210479a22810a8f341838d02813a3a9cefec047974c63c9707a8a3a3c339dfd9e13b419e0b195f08c173e29493757545a177be37f7700891bbb5443cc405d462614f0809509ea0cf8e8f0fd7f101faa03ea78f8f8f8fe9e3f32b7d7cc8d1c707fbf85c9fab1e6d1c1c63c6348ac3758ce2709c2fa61aca2a9056f27684de0662de8980979cc8cb78fe1edc4115d555fc4ba63de2c5a7d63663ece10e39f4f5471f75f18db0cd633996a34ae2a7ee7dc2eff73b3fa2de4fb7f7de5b8c0463fc9e3d8f63d639bd544c6b33b0bfe68c7bbefd847c37d83771566d7e8d73cef95e8c35c618cf897b9323a9da711cf5a875b6786f718b62d65bdc1b4a5e72b5feedcf2539fe2febfbfbcd9defbdf7eeac4297e498624b94357ebbe2dfbdf5d6f9beed7bdfbbef8562ed06ccb7b68e15c7dfe7bef7034f13486612a8f0fd7bebbdd57c9a29b644fb7fa9b644fb4b7214fb7e31456fced23c6b9d9fcc2f3ea9da71dc59d55ae30e27e857add6fa5a8882d7e49f0550f015fc083f0f347ef940153c862f01f4167c058f610314fffd1b61ab21dd4b5cbf4dddba75695b13a3d2dde09cbac9f936bf84ece167077daaaaa9aa22fd5753f5e7fc39cf15f6ee344d007c90aa62e8534e82910c2ffcfdc117d10eec035f688719d29ffb5f22fd5757a81f54b4e28f86a9fa7345c8f0e9df4f853e485591bed0ab08fa0c455c5d8743c1c76f9a29909f9ffb21ee97b8e0c834f17951115bbd3f3628fdb16f3f4dff5515c24f5f05003ee88f32fc7f890cff6f8725845efdff12eabfba828808e9ffaf087af58f8625fe877e485d91feab3f56e5c0ab0cb04312766884df0e85ea052a91fb76080035a323e404a5a91d9a69111b5f2d5dd0d2019f248d7850d00a75b5771ff441ea8a578df290a9a656ce7ef08db21cb2fe641fcfb86e96678986d8b168889e5f00058fe149a0e031a83f97849fb720e8d31721e853550591fd2a7eeca76f8741eacffd20f5ff5f55f163d32f91e15375051111fe857e45fa2556fcdba1aafe5cf583d4154456a8aacd4325825e7d555d91410d52edf06868eea0cff02582327c890b7e5b34c4046fe2a034839a5e60dfaa3ff645c8f0412fc205affefc587501fb79dee479147d147432a4417f41aa9a3c13f09c9ffefc2c40fda02fa17e8909b8bae23ec15ff89baeff63fefd9fada63fe65ff0ea07a53fa6aafeecbf20c3077d890b54f533a836e88d324f2dfc0417d21350b8fdc2a320010a13a4b6ab413e290ab75f75b5e65b3031a416a442eae7a1df9b1735bf2795e042bade7ee151e00ea68aef9316deb460c66f37df08ab41e77d23954b60bb6921e82dbc852fd11016d420b2f7a4d60d0eaf5ff403121625a1f44657356ff06d0a0cfa7b173492488337e5799e06799e0427fb45efdb14ba9f6fd111e7a73ff7d57beffd7ffbc1d33eff9b7efab3ffff6898a641ffe607a93ffb55534dd5f4835e84f4837e7fd0bfaaaa30ca43fbff55a47f343c1a1ae534f828a4d0cff439eee71b610ca91d5a6081f40416f274bd3ae97abb4e47550b60213e4f6021b6db5eb4035377d402b8c3f6c0f77ab415c23867ce9c39ea1b65aba2b06f9d0416febefc895f416a8740a91d1a65bd92e98a42547f520ad2ad9259e5fcc807fff499367bc02db2e6b0beb00ceddb0b788639e2760a32f001c507b60c7cf8c04eb1c748f2033bcd80503f016bbc8e4fea2fcb543fe1e3db32d55d630f7a18c2076ebfaa563320d445f504fd5b3d2f8f71f736401c6ebb05627cfd20b46eb9344c5ff31bbc247bc05179083f49e6375116041619961c0958e4f0920e44d5deb2bee2256f327fc341b8f1df47f960b52449ae878df256cf2db7994a2834caa08010c152422765b3d44145adf968d2c5ca94eba0b6e66d6ce96def8803c8d4a191c124060b29305d65a298a060e1ab8333717444ee4c128d1e3af6a8eec2acac5690c3b5b57406f7a943a6a09258b5388bf2233bb141982045ecf09ec6b8995f4cd0b960a3e66d0e9ba60c94c5c1ea32a3da824bebc092922c3839394ef04ce00265cd0991b1b4a5333117e4e8ab01e7346329cd542104207967572c8eac9162c2910d1b30ca845dc971a564c61dedd89323460ed30a48da4ab5ced7654546d8d3d41c13019926a8d44dd5252dc9102309020000e31500001810080685a2a148922489ae571f14000d6f883c60483214076381681cc66114c4200cc4300883004490328c39c66e6a02a103ae0a1969d27b11f88bde1eb524f45eea907f27b00bff8564610f85d88d78e15668c26423e40002a69eb9082f542ec8581aa355e67aa6efc2e2b9d7bbad5ce85443aa71de8a0df483bc2dd58fcb786ccd0de951a45c30f19fed99402717b6e8a7ba38eebe3224bfc8a1ca8c9e31ab1daabc72436715c79aa34d477a4d771fcd3f5cc9bbb74947ada15909a406dd04cabeca59a1dd9c7594fef0464d620d300f9412f5a35be1ab368f8bca7b0835f7a1a15d55d65ce05c422d24a10d2781957b4310431b61cc474535affa406364ad3bf0a38252aa2558706f29ccdc41821062b2ca70845f93a1414d47d0c64b7ed7de4001eb89fde72c85fbec0ea3ed7bff404d9410650be29ff890fe668fdafe2a946f88789a988bcd96b0fa4fa39bad54430095f1c4f22c7bd3b7dbc06edab52123d4ce053e84732cb62b6a54f9ee95776dbe75e98ff81cb37780c523b6877ddc7b350d65884a95878cf644e644b2b9176e288ad4c2d0076a50315b920be867f4fff97c63f9618b9da68388ad70fe6a558c793bb9668d132a95a405ae9ae11d8be428c6bb2b0fff921d54e47245587de6701abbbe4d40d9e92bf643425aa158335b5150bcf0d7d1b48429d0201220173756653b1c9f1bdc575c4d7af4bf3a129ab78fe790af74bbdf19222967ff541dc41a286565c4b79a1e2d5bdb08ffad14dc961e4f08a0c0a595a0abc59578a3091780b445cef79ac7ebb2287415a21b37d7baaf13f3b5356d9d5f07a99f25b9ffa40ff5da02504581fa9f4444ca3ce6ea304507c0b42776f97bcc9f019ad9c2094f75050166b8b7f927911107b537a736a4d5f1b204c8de8cb56b976227f746c6e527397661ed38c7c9bae67d2aec81f2897ed185de5bcdc2a566d044977850601b9564b54368f31f2f9169a8e1c433dd1857905990a6d900f437ff5c83d4899507c41ec3ab25309430d9362cdfa2bbd66b82ea0e515b02c42e50d368d0cc6e2c204f65819735db4d0518f4d382a5310ff509673bd5c088bbb42be1f7f46c5f1a57b78c95b764f53e5fbec1419788b42b1e078363193fabd1b36f62907aeb78772080608d4028b4c2671db70bea6696ecbd16d6ffdafd2894476b83f2c169cd61d1f28123ff457481bf1789f0a20bb3bcbe95e9fbb072edf345ffe2841c7da15bd75632ec0b9e62ef70c9ad9f12b2904965f6a4bf40dbd7cd83452474ed8449f59b5d0bcea2e4a1d13851706a127934257dd3f27589aae5b9f990a4410577590c02c4933114e3ba604bd1bdb620605d269a582fca19c4b6ee2b0264fb9a0f33e73466cc6a23ab1df0cedf21af33c757325fe3f7366f870e2d1ddb3abe571ed2f1c706a97ca2b4cbcee6a899cc8200d60292ea6d7a844d3c017fb509e82f9d5d165fb8bd32f025a2bf6e8baf4d74094a7513be7256557600cd9352d0630ca0067469644b22baa07520413833a2757b4a6ba179dcbeb426dfd090b064243fcbd59ebf77996077ba5d6361aeb778c6bd75e0f1214c93181034b7867dc9255aa514cb7dcb2bdab8301c1cf4522faaeb787be8198905604542ca8f810de75c7b7c6d2585e8cff598e2dbcfbc1fc753a169fbdf1dab3d7e05ca9e934cf8707c63d59aacebb4d03cc304a9d905aec5fd2ef11467f0c49f3ec0d58ae5230cd2247462ae30ac889fa7b97dc73d455b7f642cdc10f1083bdc510a9ef87c1bc79b99db137edceb344957300dd67306e8e63e8c0840c8da42b86c0b07a55d96bc90e2e1c1139f7fce336e884ec44b67de51a3e34a277013648684437177a3e4d877c3ada140847d6d1ffdd20a6453edc98ebdefb9079e78b358c48727d55efcca8048d0911f6ac49ff1c0fe6eaa7066e23f49660f45d60cc06b521de79e39bfd7a4c23a709282275ece0ca3d070c89a25bd318735ec8ed53d778ff3b76b611f3fdc497a7152e3abe369a901a20a9f6d1dd7ea813c2cb704c8f21e7085db91060276ce5c165c228156909b9c8c8f706380318b4719bd6f778155bacd134b5a9aa532edf96a922024eea87aed2dd54705b5eb5dc7a4511b3767a2d41b2cdbd47c616084c54887d796d67b1d53c222aa7adada2b3858e142a6606592cc517f6e05bb8571820a05443fdd210225faacaa0801b4d4a977e962dc5240d491f1ab247237bd613ca03585710416524abb7a7b7bdf3e3bc5511de5d57e5755c09de8aeeda81c5c73d3bfd37bb390eeadc50d7f3be5e5da2f2e9d18c8e072e1f962d92d1a6cb12c227c9985ce50262448082176b40e79fec48aa6df965c0765e0a1e6cdc91f85fc4ed548f53661816dfc51b0b0860e851320160f3f0a8933f1db6f963990ac6f3120f77807b9cd64b3b421c76c6d984405e86debb2318d96e3cfdbb50ef076728311742f8e84e43d4f860f360974406d2e8c3e90bb446782762bbc68abbd5572b6021159e207f0a3f38c1c560e4021d19940454044b38048a3ec943a91cab3bc08d5436224334ea309b7ac20357d6e4ceb2e8cd7bbf1bea1f9a66ce44b2067f527c8aaf3e491cb0763488b540adae700ecfa4eb273f9644377a321d2412be7283e694edf7efd073ae200c0a118628d136c5953150a456485eb4550eab545665207753ef221916c3d42fb2d602252001802cd8476b2922da12e52b6e27832939f37b0deacbe421d4a58913087836658a80e8772c8385574ad7b634c56351900b3523045857f579c01481943798b5f10615571d37d273b0895158e169d8dd627865038dd84514a384f6273ab82dcfdcd4de9680ddb61e97ede1f988a2a01a025e1b746a9f93961cb53c16855a3d854fc70b254c113925d789e9e59c326f110eb844d71ef2ed04efc02e35695a4ec4b132a68105ff601118fea23ad0aaae97fa633f732acc7c1c8dc9a9537a04086f2bb673a9eae5ac93ca8bb05dd0430d56ee8ede56c91b941c9a5ceefcf8e6affa545bfe08abb1d32965e8642656b6adf6137198f4f69805045f15d46548905338f12532370625a4e8a7ca1f2a79e6c8e56c1cc9d3dcba144e2e3b762e0df2d569d522d9eb11aa7e4c2fb63ecdbf1478e924042c78f7fdf25af73b975b6c98e3eef0568c3ba41c3a58bd77b143cd2626def1f24b4526771debaeed6e08f020206c267d5dc02fdd0c2a55a6f0e8920814cba51aa25654e985af3832947bb14a662332771af72b926d47834464153f69478ef45508c3024e41c9871b588e313817f0603d6f501222dea7a6d3900f8ddfd44f2d25a9e5bf392f6a34da07eac86ecb6f69268c511ac47e1ed926b204748e9f5729f1908231815348c84758a80da68a737b01b0d7beb4bf13b8f74d481b1ca75b924df03aabeae7ae2fe627e4155e16beb30981b402416ae19c543373cffb98ad47b8312de4ce948fa267b7d7e71539f4656d335adeaa3ed3c73041dd0664aa94506d16ae0788ba0b2b46846444ef974f073ce6b3c069be1a3138d2dc4645d2643c1e316ff85f1c9ef3db5ae9c55613b9605d609c4071df1d4a5c97f711dfb1f42bca120a907eaa2cd4ff0420818a972e2c9b0e9c0e35f30f230d6601fc22cfa532dee04286f8254dba9d9a52ca5d2c00f0bfbf799049fbb1257ff27f425ef93472b8e3a850c1c63a2023131f88bb6d6487816d01aa4d6b20a3c6e1d2305b56aeff1b922b1895983e83a478445a85da53f4da41ca3037341a996221231ed7c48c1574de7b22373bca74ce19a9922a8b49c469327f141e3c1c084d1df12db7f449e34179f8446e12575ef746e53002fc64dd516774e82e59400a84ff1500d9afe59433297c55d13f4ae196df199b898162088bd5821b9ee8604be129916af96fd9d54fcdc2007895d7e8cc8eacecfc943a424a0c4032a285515a52a9e5242e2ef48ebd534f5017190601ec65b201b3985f8e19b65e9f93567fd016c877085b480852507837c7cf1c930421e92fbaf5e3901e541150dbd0579715263d782fa60d5aab8b98e9dbc5cdf1e8d47f248b79b1022e41e895b7b3fe9875745d73eb5d5850362280889f13c8853e17929e8dd69e1f3a37c49749057a435c8eba8c03c367cb1a5b7c5b761304c2ed297d43c037c81d9e590c144470510a138ea471e7dede87ed0e0c32bc1d757613a606a2fcdc2f5ec163ba1f035dee84c16da41d759f8219072b53d424478546eb066a00edbd6fa9f4ee5dddb97ee28c611cb48583f1e88e8adb251c05fee3c40ed4a7053631c15b979a3d4a6d45764befd3d3cc12621bb54a7b90beb2afc90c7905e52b2d2257059f1ca0c2f80fa0db1fdd78098102b9736b0d3e4725295eb8813e0e6e09054425bec3d34024bca6cce7710a980d15a0a79af40cd6f95129cb8d6c5b4971aafca30277cc0861da498dc87a4661269b8a0d5189d2dd2edd2d2c2fc1dbb02261b4e0c5da98c1ddfa417138bae4e8e66bf8711fd883b70e5c1023b11064144180425a371cb0b4ee7c0c2aac3909617dcdb66615f1ab567c0647cc0ce1ebebdb56d04c3cb7630a08817cf7b4e80e3b6ca76213b206a376a08368c8819d89468e49940a7e8e25292aeff6a11b139d0c5a3546b871cc60a96b2c3fcb5abe3c428d4c4f8b80a85b6cd410d948d55d28cfe0ebfcf5febaff81ae869c6a6fb34dbf002191703fe977dadc0088aed428b61793e636924526f0a27a074a91d11e976b31ae9c3c9ac2fa919836f65afa11698eb236de7c7c6ee072286c387df2c528c12cba0987d115672ae48e9e278cbbf738d33414dcac9f1768a5a0afe71ecd773b45633f917bd6ea6bb3e912f9f302c9416843a1d5b9bc017c5507d0ba297deb1c5142af09952e984fd9292a9b1b30dcfc5ec9c57442cd8aec535474262d5e934927c790b16581d5973b4baca4b8affea0af3ffdb0c049de6f0682289f7024fcc9ecae3a5ddb35c1bf21fcafbeefe9a32f01bd26fe0e73a742d26f1ce21179198800cb2ea6562caf689174f5497f30f2564a3aac024419d566dfc7f17ffd81a0e1feee7afdc35b419636592f41f0da3deb1c9f25bea81b3fe8934fb64f9f365754274db7acdec06ef3ce1d3fba7ada2aab20c5e2266f1bc8cb61a2c9d229db508bdb5a16fe97cd751499a4289e4b1a29433d3360a465e5d51ec1964f67724ca4bb50121290e95ce0f228337c85bedba8d1a561e98837cafa2eb8d4d1ed01aadd257896012298dbb6a81908b48b572603104fd5e1491f4fe841d9c14b3d416e4b54ffcd4857fe5acea50368b372260d8eb98193a7f0185a20c63a792b04fcf0b9bca71f09d41c3af6ce19b4cf5504b5256a2ad5149607f8872166a6f106d7dba820a2ab77d1cef3b80126ce3d47a915bb9949b5f1bcc0fe7bc675ccf91346bd0ab22b29f2cd3b2610485cef35073c8a0823f2f9144a2e5499c5475ceca6d88212630319cc805b337152aec3b052079c3281a0d04717f893d5eec1cda7c82f2305bc7bbf821a13eaacb3096168c0fbf204fd5a89f13cde65f625c99e3567c682f4235a963d14520c5a05ff8db50c1f43d127196dad2a496cadfc2ddcbf23f83e5d577d1a1c4db01bf8b7086abe278692b5f4e330e8e184d509dff249b609e305422d784c2aa4cbd72641dbb6052c8a5fc04503badf9a4fd543d3b10c4b0fbce26f5b41ba0cd21b19848a2e40a0b8f76827970f48368051afef507513437c40073e2393cf0ad489dc2f51fa68aa7e93744db33efefbd9c48a7b1804c2bbf3a273ebcf96ce613d0a2409cf84f807935fc5d265a4d1e6d7d9928a0f1664d3ece1201523a6be67796e8503baf1a2e9d19ad50726b5ede99514c19f6ccfc4c3d80c88927a486f5f3cb7a8c51ab3685dc5281cb4750cc14eabe02e921cecc7ed4480f0bd973e8d1ef1ff38b50c452c2aecc5614881d3fb7c8522022f3f8e752ad58f202ab7586d58a2d1e8e682aad17169b3deed859162d96e6e0a89f7fd1a2eb4a56afaec8a41c58c6e51a5b0a9cc02f3f9bec167230b8f38899b3e4620df3f4b289ea32a28e9a4d2c30c34aca16329e39c693aab87630be9ad685019b3a3aab072dee253527442c7e0f45ffffe30a26aa363b88256a58d70b38646289e809d83b154b066b1dc78e62511778376f7c966e62e7af8675f262f77a4b86156006f1fc9a6c6c0284f2ea539c07f6227a94988a8e87bd08e649712168666856ca83c39c574bf152fc78202880f85be15377ce051019e1f41984b0cc933b323deb5c27c94bf341376393b224b9153eec3e2f0c7fb126e48b2e683f8a96a979c2c8a35f0e5219e250f917e65633ad1894fd88e67be06ec2544c14327ae39a487fd5357190bb173b100e30baa54fc3313fd9b2ac804da72e6411143391ce0b48c3e7732d1f848780e6fcc2111ea6e3523c97886810893a0c05527ad8761d9f8545d30a969d1fe460e023e18ed9481f0b883225dff65b400494bb3907b876425fd9cbacd1097864acf0a6aa4dd8342ff7b722d938b2ccdfd90e9581d052f2276d1e877e215c0ae15bae9bc67c87c02576398dfb1a3a46d394d67e77438dd29d0f9cb23fa03900a8686adce5383d5baca5e40eafd53733e6d781fd7c6cea8a128f2451a11ccc9a1b774b892a43597a5b886dea4a2e248b59f2d8288c1e7801053b889784c5e9677820079b48e4da1f00d737c684e44161b47509040d70f900f7bfbe8ebae4806fdf307a509cc8857057e4c843febfdc81bbe1c372f00380442202462f652de420484fe8d97b5d6bfd427132846f20581f8f6c8ec5ebf86514a64bf795267bfc957de3dc2b4957f68abd28cddd838cc6ec565005dd259f8c2c6c853c468eeba368eb202caa24dbbc6b6de6f30c54c474c60b725651b7200152f4be6d610d62376f0340cbbac67fb4175d1ec61daf2859af4e511ef4e0aefa219951966a966d5eeca4f66a86b7f54e50470bedd44bfaddcac4799bba688df95dc30dc5e5e444520c40cfca2ea58da3a2cf2cd73d04044984d128037de785c3423c46071050e4d10444d296dbe4045ac7025f13ee37d21cf7cd64c206e1d72800c53d3fb7750cfe4fe05e158e95ece1ddf6c6b50dcf85fa786a3c802411f1bd13d771b462a7d9adafe4763093b951f225d96fafe749cdda4ef6903dc01234dc168ef5448062536f67401c2f98d9c3fdadff526caa37b9b68800bff1ee36a1c79d6126b720e40a7e3312edc42459f2aaa4ca285c42c8ff1989815bf94c4aee313aa1256af44fd9bea9085a05b06467a3fdd5d181f436db51335a3d964b5a7e42a92b01bb2d129ef4fae1e7a06055de666ee0a007ee07ad3d76f6542bf274eb48bf8c17efb4b509998cdfe0d2182ac6784dc9340efe5ae1e754c7e912c6879e0832da9f887d791e85571532df092ca1dc2f5328d8615a38d73018d32022565a89e92bb9b2e5e74f999ecd834fbddb3a08011d03fa3166de13d9eca3cc05d21846bec006b69ef49adf3c20b158717c25aee288be3d7277ef55e033e3ba0ad9d13fec49003fd294aab585dbd7297be99ab23940c805786d5418c39209a5263858e7943aea6768eaa2ff9c7c850174fafffe2c4c0e38816856496f09c88af33b643843c84469fccd6a6663bdbf02efb04c050469cd3070b34d8060d7951128771efe89ebc56c96bcbcdb7867eb2d7f1389aa6e047e4bb0bd0abef41208d01b42bc429e9be7162740d5d217634cf83c8eabf0c07ecea9eb6e90e35677063227072a2e343ed271bfc5a39b63055f5a0e84ae6f85a70dc8316b0b4b3841e79709ba0175069fe9dd09b528d0183f5aa6542f64ce06e023284137a0eec42758f182ff0a383b5a29847edac2e420eba0cf2cb44436b0de8c45ee24a273f2ac59a75d9601bed2a13922edadcd7521cbf728d21ba8a0b8f6c23c6a96c66747b1ddcdd3565a3f98010a942135ff25d54f1a78180a33133f40935af4311b611f157ee6d141d0073a64ded1b40facf8730229b4c40adc9d85b0b49fcf978ae33d622040823d0cbdffeff1e1b41e1d986889eb06908edc97aab83d763a9970f32ae9e005ce8477e1407f4f03b7e4d08eda0c3cc67bea02ad532b38e0b3362adffdb5fc46a2f01fabaf0414bf7da29bf8e60482846a7527a71df34587ac70dbb52fa72ec09fe10f609a3cf35d97e604a41557f94f172849bdb2058e63bacfe7ecfea4f219ff3d5bad72416b469e1b5ebf412ea4bafe434d214659859b04a8662a4818d8b60c08e2530c25cf5eaffce8cca0becefe012a747b3883908156ee57734f7c0dfa38f12591546349a720db307b4aaeb4b98b1e19a415afd00d10a0320588faa7e38104033eb19008f3256a7ca069c6211476612c1a032386ecd1982b56d4c9a19147d73187150415f6155471624c0ad9d3edbc2bf7616b7b2fb0f662ad70c3eabdee78bd45e30592c113af312a78c94afbdcbb62f8ab1eddbcb8bf318d3e806e60cc291c310fea417dce7ca3577717af88eb506d4a584960836e4885155e741f1b7c85190aef7d3b29666fa33502bcea229932796dac020aee7f098b868734c37fb99d727609b06666bca72e7048b21a42380f1f0884f4c2b67e41d8ea9e51bbb0f4e2d0a686891443baf17e5b76d1b98f03388872b760d8009ad13f3fa0996a34af36e10286e963649063d22f2192496c15ab2c56a156b1735bcdeb8ea910deeeaa8742838548bb0b8f368182408f83e5abc22b2e2ab8b52f25cd5ad7a1eba0368ad3a6d0440ab529052d5dbd41f9ac442446f7353b3c6bdf613103c2f1ca4b98da106803305be08ebb9920122d8079bc601466bcc9964c6ef0492971515c49061830cac1caff9c1c46d1ba2412b12fc840b808b54f691f427c19b4e7a33df872485bc2a4e837a31eddd79d29d6c8f1003b3e1da17b8fcc03cf77fb83f10a5f1827169d87e883b20de379e043895f455cc0aada7e87bb9fc3ce0cbb963e8128729849f1bdc26a3eb1b62bcdef5c360a4fe7e45c0c7a514e646fdc24ecfd7f0792ab6f72d38207841a84e9c0d71d779061189fc503ecc99b2a8509156bc0a2ce2fd5d5563f84fe16f8caeafca65cfb5aecc9a62958187e493c0b9bdd1ea8340f901843ec84d9eebe9b988e7868304661652f02d3c56fbed008bffe00d5f9b55b74246b75a86ceafcd22b6d817a1791f24e1f92433597f5f3735c494368e581eb91ac5b7f592ae69544a34b34fa500d3a23b9d908c0ce41d20facea5c9a8caab6794b3680c9f9e5d4cd96e59b06f5a513168e7eedd58c73d8e42e45ce569f02b0c43d177fcddbe4b143abcc258ebbbe20a285f2631b35f05c7ea5d2212f95f8cec1ba5f7d6990dbaa0cc398b9ca2384b4867691deaa3ba26cddfa8783b31d2f8d007c860d50b60010b41dbc2106408e1931fc126b981854aa9bb2e31a7b33cd233d730d80c6047316a0115603b460787b9b47c285d79ff287f54ccc21186ad04e73f6386e9c136f82ea367b68b477d9268959ec087d8c9389b2e9810a31877789e80c9bd5f0c2ebe355725a1f7b353c2a9e32608c4a5ca642235a3bc5cf204cf7fed51920edfea84c94e56d2592cdf86d180172369ac1249cfcc28722a74666cee7504f09c3e142aaad729fe4622dfc3f85981e2b19dd7285d1b49cd5b28aa29b15a20fea55d6bac7468597e204442beb636bd764e9b3327fd38f1dcbd4e924f978d90dc9b6c7316893da90e570c9ccadd39f0cf8b225143552bd252573104b73dae24f97277e3720075a8100ecc7b52a321c911664cb98af788ca9b98025f9f10480c6c19ca1cceaea1304981158138b6a53750333c983b9a2ea0ece929675d5d8e23637014cc8cb4b44dac0d265f5d3e9a2b69bd38d0f474749fa1d6c58c49b6a71a59b5d094e59fc3707ac415a02e28c37483823375d8e096b1f11b24906fd82c06cd05dc206b17dd81dc46757fe4aaad1c5442a270cf9faee55014d0c8c529be2b4001085d9ac4a490a7f2f95a6dd43b6f7e56a8194d030263e9d80fcb0f1f6c18d6ce9d41a07b37bdc168ecf68ca3be5b66da109afed8c551610baabbda141ae1c498e24c1d90588a5d17216a2a86c6e310c618648aa3fcc50cd3badc9e044249f24f151dddeb30884cc3f24bdd3f0bd5d6269d11061121ff5c40fb9fbf00606cf525960defdee762a17c3fdce3c9543a7af9e021e4a1c48fc63935f3029cda37017af701d06b42825f97817905d0d49c1135905313381190929ea02fbae2aeb3a03813c8925420ed8aa6f7761c5ce0b6739558790ae590023bfaf99f803ac7a5b542ecc312bacf8bfffed878dcced43a1b8712f62a48249af747a3909b874bd86e597f0c1bc07ec5aafc0a86b1ae59fd6c1f957573601ed25e71ea525d3e6ef7137c12ad605d3d8740b2632af196e3bade01704b86e1ef312675d891a5251e4a18d138d89c3e91b030e702f0c76e1ccb3a6d42e896ca48b244001a4c8b0fc541d882f55ad958663bf14aabdea586145b2175d43f97a7c96dc28b71cd8882210f5b17f436aac633ff9dcc852c28d00a1fd99c4cfb3188495677a608fb6134267521ca7136096d93b74a659551aa4f57a971b6e15a615c855406803ebddd2c96200d210d876952722205ee0aa00ca2cf86bc51543cc9afe10407ce7b30b588e73c4b8aa5130d8fa9701b4498545734cd6e9848a97694da7ac2cc6dad741677d0b45c3d108053819853517f2106cd7ee05a4d78cb33b49ad92d95aee05f2dcdd0bedbeee7637f6d828c7a6a2db46d2264e09b565182313e86899837068dd5f07c4b2f26655c3a0634389b50004196b93a2cee93fd6c92b289d6225826247be66737cc4b962281dfc3b19a95bfc04231b547f6b2735515f7c8eac6381341ad46264ab71c8640f070919a46bff83b8de0c7acc350c021a7eadcc2bb62a119073bf10fff9bc6a5c9495737d2809c35ab3958f99032962528f39b1704c1a8d5ff586e97cbff7093bb677ae83e9c3d4f272dceb8b266d1840183f2f4bed5cbe99a67e95cc4659dc36da91b43575c747801e43e2d1c5ea58c01e4e262cd95e45f1a4ec52f13b3531abbe49a56cfd3575bbbcd58290a1554606df50bca5112ad200511da2cd81e98038ac465e7cf3456a6539aa42403954c32ea66e4c9daa5eb904adfefbd22b86ba29f3c6d4a9880c89a2a56051e4e0ef889440e7e34d43dec2972cf3e592d6ea9ddd62db7fd4df3c5479991068586f1a41230a2c7e61b151515024e3f4423abe0891fdb8afd544312c79232f9a0e45a6caa3a1026d5cb99398892b17b74cd80d1efc8c74b023ab99961789f708bbcee02e924083fe38f50b2efa6f16ad43eae0d22c1178f3fb100f8d3bbbcaa771d0e6d39eb4e9f86fe5dfbe0bb7e595fbcfb0ac1bdb8604aee525333e57adc48669ee88cff3d770b433834704727d2fa410165201d906684470e441ee81bb85903efb957db8b26ed48aa28ec3449f335851ff532e65537a37f50f0bd855c7471177414743bdc06c07559e6b54c0d8ff267a852d706f79039ab0b82976d545b7d830d58c28ae3cfee65f361b7c21fbda1fdd4d0e1e01c59d11570178fb2b6a0a0bb1b052a92cf263515f8edb4776b166e600431458b1bc3b4be67615dff7bd6d89434f1440ea6adb839b7ec1781e608c40ce4b78c2d4b3ae5b88709d47c539992c9a7765d0d70127d9882c1d617563ed984928da8dc5fd8c901def4499a2b967ba8726d60d833696b824c4b4601186e8073966d91334727114448b9b432ec9b62ec243e3df69095910b10f890bf15298470a86e63f0b7165510950b257b8ac8654539787487b618fe27f89a53c77d453383a2361c6a8d5504352d6052d42b9b402675a1cc9c596b64f46060f3d831b8e5b9df4095bba40c41449bbc8a8bbd3a813b01e12c7509268148edbd4a0da1f303b832e625ac3a68800dd979f3e5541690bb160eb3cf65a9b6f4fef3e86ec33432a19f923e60778cd58b401dee662b832486bd91db8b2e32e7c59bf8d88f6949c8ae47dafbd808aaccce974d13c8138d2a82f394c1e1c5d14a58ea157fb962065afefa95377ce1ca5f8faf3fbacb3eac401365c577c7a44dc34375eb21e99df5624850a89eb08ea9fab0267f366cd4a581f6419777a2e7d1670e8f2f7aecc002cf9f05ee4d4a213bc0bdf465bd1b80cf0df2d6dc3be77c32603034621fe3a0048cfc1d7c443ea76cd22246cbbb1b4fee8a1368258e0b7a374960810a7107e4b9b0dd3b14afcccc2d965be636fa9a21a0eaee2c310f7227f163d134912f47064d1ee212da8b4b6e11ba609ae31defea794c7e9fbd1e31901583b5054f49d3e031e14022c8e0ca354e876cd71decfa7214c273647c5550450ba17a5f0f3e6fe227eccdec2ab5f01568660d5f59cb682ad025398d581dd1af705854f4b8712af28a2673118edd510d88b76cbbb66fbda4d2f5df8a19c93371addba590176cdec88d5fd40a171391788f84d7d5a69069df40c9df48e5090087e3a94b5a24bdda0eeaf37afa40a69e42ab5c0e9ed02128392b59a2bbbc2a05f167000951cbdc788a2d3affa45c772b9faa191160a591e3d654ced9b6d8dd84d1de5f0579c3f040d7f4545e7f5e4004a32e87c04e5b58ffb792ea53579b69d3d6b4b7240870a96cb2b15fc383e5e10fe470b2633f7bb03cae3c627c0e7fbc494038818cc494c74e16d9ee062f399e8d958a6f988b43578284e543ee8b62f5d76fb6af9999e73d59ebb7e3ea512f1d67dca9357f6e950492bc47b7073e78181a224589eb33bed2874a5557b235ec43a25fd069dc9f468013bfb1472cd11bdf0cb16962d049287a3819a314ea78e83c5309693621258749c9a86779ecc77df2779236f319185d7c04c8e4853d23e8da0e7e8d398942832a699fc83cd2e6f886c5a7eb4299dd0298dfe7270355ba9c675a2daedf78333fe29d5d6a2f7e4d93c0feba4557a25575b197e476eb4fa92e6a466725111e6e2810dbb91ad812095662d5fdfdc91d03d6d795bef265855c47c290e20cc41acd542ba1c8ad5bbddbcd77ab72e519edfe94f371868e79e53335c16be4ae59ff2edd1b0761e1aaae2c6305ddd0ba73cd0801a9defb1bba5c11cec3b44edb235ebd83fd017868ff2cd15b231dfcef03d33b32a19710c6d7d9d164617f911a2f233b49847c36f320917f82450ee9000c90125ad43ede990d0176d244d8c9351df2d7a4134020772984244d098531e509555b6bfb5bd817acda1b8df6c4488c91a8b063271a55aebc01442c0ecb0806305552e7ed0a3e19dc798b998fde29f7b4b3f90bee5990576897e2e1d031571c1012d4771c72aa13672d73660c90d7127c262ba3dd24fef469f1d7d194219a4880837e76d40912c685f0ffef4d973999e62e07ceee4ac16b71d7fad402d09226f99ef2001f91a2adf6d0620200d3420b5fdb915316ed854ccd66538420679f579061496ff9c0a12a8900c1af6bbdd320bb8113494125fba4c4de749111587beac5471687d8cdbac56a0b5e03e03e5bfdcba45dc9faf21a7b0177ff0b64b6928b86e8e7d9b48a196d2265e7ee58a656cf3df428c5a888e83d44af5110458505c1a03c5c5c8a96badd9af1c28d9cae3852d2187352965967a841acb07c66f9c32b96fae58c3e10ac01a0236145dbf6dbda1e2e15c6a7dafce1cce25999a970add79f750b7c9b0bf043eb865d1f934a68e7aee450fe49e6aac0552a5473f0eb24e08858e1101d21ad458b967d16ef8d8ec62257c3d6af7847eb42ce4441dafb6e4ae86658be707eaa259c1b5345ccbb666b072620d216bdfeb7a3e83777435a827c421226438f23bbc067ff8361c90a0a8dc12d7b767c731113d6eb735f09f083a242aa698548e7eaf269fcdd322d96aa344e6f43e57f4404d14721d8fe69c8772d029994a620ce6ea81e334e932395e6bfd67e43700b05686db6c15d909c974009578ae3c1097c8ab144ba4ef3ea3dcfe1650bd4d3d68f4e0c8abfc920e2931060fb99946b252326d5f8fb55ddc485a39f608066bad839d673ae529c42815475ad015b11b11d1389d26df71eab1467e26a6362d093645d3eb67faba2509bac49118daea4cd9b57ea0b4de89eef71ea8b5e60844d50748c14b591796ff561ebb0b7b2f4022108269967591787b221d1137eee1b4fa77044dfbcc08118f685a55f241d0080beb382fe214735ef24d03fd4fdfa625295b3c197aaf58c1aa14e5469f79a4eb17f09a96ccc4267425dc367f6999e8889e486fa2d1cd07b2882bf02fb174b89f56e6809a4507ccf50cc29f77b0247ec8f174d33f8f0c8cadfc1f72d768870531d7fc9e36b7a21940b83876360d49da1d4d1bc87b549d8cfaec3e3d815c56a581f5fd5d60006b0a66bb17f4a777633cafe71575a84138fb0252bb7161d4eb08437ea435fde3d41d1d2830a84e827de33e38245d4d6434ff449d1e49f719d4cc6abc54eb588ad7b0da4b520e59f84fa269ad901187495aa92d84f834304828d5427f5a8a81825a36ff470eeba6b9842fda37be63b484cb9045ecfade9d6b983c1ec99b82706aac42deb79fb281fd1140141958bdfa8dbaae12cddf557e40c2a9b56ffcbdf4257697d603b4a5e0bb5b5abc2e8ec68f3dc6ff54c1796564f87130a23f4e34fee55f829782c51666b6269c7fe80206c0ff044df1ae57822db9eff0a3e25653b48bc4cbe9cc73c04f47c70ea7c0c718148a4698f714825e00a2cf57b45e5cd3e5cb924aee3691ae0c0eb0c3e383eb64ac8a95c6b84a86fc84743948b7044eb26ca227d6f7416d94cfec32b19792dc2f55745a0b3225cda71f3128a7017d425505b3da82c1ed6102ed0acd28b4670175e88ce62564badd27dab17c4701e6cea4e6e446494b811c2b3b227f1e25843ad51ff0a0f5c7643165b37f7cd04fca84e1d462dacc3def2722e136450db8dcea44bb5635615fd9a14eb6f99814e1b57142eb66060c95074b2508839030457d7374d32142fbaed719fca72308d9a689d870645614113bc4ddaccf1b03bbdee4a3a26acdd9d145f0e410da54d4e22151cd522060e325a803539c27b3ca6507be8e5f35aee3b3854372dcebcd3d899e3e49664c547177da2d837ab8329c62cb40907a6c3a529a9aac6984f1cc5f602b9a81691f30b46583f15fe6b38e0e1cac385d1a2c9d82b44de1ab4142013de4ed2a905d657976fa1cdf838a3149d925cf6e9bf005c6ae48d9eeb4187144a7f7852d1468f7726e398a83045e5691f33ff3b62d211dab2059564be0dccf487f58f311746d74a52b9a76e89fdb4e4e9c4227c5e3d7b1a6908ebe333b8b2f7993d1e203329f45a4cc258955769f60d4c051655f05d395ff65c1e47c71daa472f0260b67298d192e57def0df42366eed5a6c18247f3d232497d18aba5bd37e3473db2a7a2bde756c9a45463f24739dd113a8e7498fe4ca7ee95d3f7bf22e5c5c37502df21896cccf26ae2a7c3086895822d7058787f52473f33977dd0770dd2d9106586d3b04696170d26702b0be433e802673a9d2a4d51942b55ec617293b61c960a6def0091bedbcddaee1dcfac8515d684b888e1a4497d8ed4a7cfa3b3dcced2a75bf50c8fd182822e0c7079ad3aa56975bcd1a31792f97830bd64710c2982090417a29c7026eab487d9676c75541df1877ab029135e2668d23d265dd909be1a5591c464fdb835a1b8cb25d940c6c7653c31e1b11b8df40efa8e6120976f81311d88160a7997e053ae1b349bd91b93761daf8bf4672e33f9e0bebe47fa67172b8a9b7fddec613a9e4a2ee4ea054ab3d052c8579f887f740a586489071234bfd7281bde169d125b982f87acb450422c9ee5c0167d02f26255ad23cb88b547c30e02d63fa1bc20e6ae5c9f832cc10251e08cdf96a50ebdd5f9ac94581326f627a811d434fab831f639a7392a52d3a712b3a73423236e764eac3cc2e79cf4d0de724d783f0fe06e223d8162f07ef1cc47a53bd9380ff6822a0e5a0efa50efcb363fe02490f431c41ee6dfcd3037bd8f3774c67b89fd5c3dba119de9f58113d1186d8ea6736c61295cabfdb4c1c464a0e45bc94408afc382be8fe3dde4c0cbaf435afaa2b36629c0a4fd0ff1f291bc92f85212af031c519f2cca22f99d7d25419b3f221271e2b6deaf21221c89da36e40c9b7392591f92aa337b1c3c264ba21bceee19833cbc609b3eede27f2f44a53cefc6e88a81f2f310b8cc6cac5649b04668f87ca875170479b155b6c2bcbd336a9e70f9fd938a3e1b31dc071aa7547ba0dba7575699a5b77acc0e94fe3172fa8d48c42eda17eb2a9bc893d3530f8ede97699210189cefd1a7af5db1f8730270f1f784dead135c55465e9f1915b232819a4d1b585cb717f794146e81ed4acb157925a30a83a06d17f0efb3c32fa3c5403c90fcd4dfb8c26fa44d5266a3569e51c390c33620befad12fb68d4be2dffd95809ab18901d6806bc638000bd2699f691e4455f38761c4841f47d44b01a321b7f6c7066473028a8279d3054b109c5d6cddd287db861fae151cd83cca06c25048f6a81b77c2a0ab804a50a46fa280f4537888ea1bdd66f36c3ee5ec0d42728c020889083f344a5a936c8a5a9c390b69f6a44e4c1faeadd32b7a3af3e4e9d01038edbce137b5436ae8d00dd62ef6ca01a21032741fc10f02cd59dd0ef93777ca7a2de1b4a337cc5a9f1fd3329937077d61b5b336cc9f0fb3b85a2f12f9e02b0e97f1dbb1cf49e3829bdea9697ad87bda68ea79fd64febf5f924586e41f4f3497e15f10d948477cccd15cf1ba772a272e44aab4d1521e9959c7dcab0ae6067daaf3ec130dcdb16ac8f32ddbdd61b3691707ac74f7be93c895443e1d1fc845e57ab96f94e8eb6f0e12549111e86e7ad1a4fa9aefe1f630106877031202fe8fb8184741d620dbc25160de1e26b71add85e111b688f7165625775c9b9440e919fc74af646518a506412e73dea1521872df68e01751e4c4a92aba0830469a6ea5bdc4713b891e07126c2cf4c99146b8b469f1fe4824ffa92ce9746d2659bc0db7311411a16be177b0bf2fd48477250f8ddbbc342d317be45d2a2c0e38fc2e9f3c0279625a94a59197a18a06f16d8cd62086b45694225bed710b8d1aa2678b90fd918d9c83f93222a3c59407605d8b5ce08b78570575a3f1e04e22e5027501fd42c0bfb93b22f6142f683cb3810347d874b7a6f6d64626cbea543933daaa81c6a224fed1aee30c239e13accb7b5e712ef8bdfb2a44f8598bca8bb4b463def79b1e681662eebed917613f8a512cf38ed56210f47b19d1e2ddeb79fac710ef6ca4ef5cc352ca75fd6bfd4448bddda1d23e78e096f8e81ca2f32e5ccf2cf1c30ffbf8322425a4bcc2d94991419a7cbfcb585cb5ce7152bf156a8b91da2c488c2ed840880d5471ea245bb02cbfc91b4432d7a485c7cb272ad8a330c87f5fe4f2c97c179aa0c96e00efdd9a9635769c3c37aee08f41dffd39b08cdf6deafe3a0eddd769755a6bc6a1c352ba629f58a5c6e1b37a4b3936fd9dad22fa6fdb216882128ee4d09895838205399d62f36fcd87481f01255fbd02accf4a6d8ea67a2fc4f0a19b5cb8354d2be13b1b6c43efb4337f14e3ab6aaeedfc7d48a4c46cc10893f0cfdd82bf02d5798686478d82e901747c0027efb8a93070d157e0ceff0d56637223d22781a90d4e7ea7090e620c979fec6b533eb6f89cfbeb577ad805d532a9af70948efafb9e38eba8737272ee3d627b1f24f96c6b6b9496a09200bc2e96517e084f98271d7d820a2e2016b3b5e268980790e374c108c75a98d2d688bbdd9552d186d33cfdb240d564b5535d0274afbe5aef2024d4d994475e4d0eaf5f86579e8d4de1155906e161e32de8ff9f6b9e854b30fae9134779a33084028514a21fdccf9c47f0224f47b9928ada93ce017404a16bdd2b31ae7559ebfb263741aeafd141fc8c017180e04ab70180dfd886a2b14e22864ea3a35ef3bb9897ee4272286a61d135115657bb08a1b3104cac48ee8640b1f8372897ff7f65101a1297aa94d4a0d106ad421c0a5686c2526952ec0834fb3d1b71d1abb31c165e3e288a4de32c42bd429d5160361a5a4a8adb1289227cb80924e06d95475ff53dd81b168d3178c727146c25df999416c18b9c731d32131cacd192bcddd2c38a35c5bc40b1e094beb5eaf934a408fd778c6646a9e4b9a52e5490b75876834653ac5b78432b11e2984ba8928c512cfc96768bfe57e4bb480285b57271d8a0ed04dd3505c504493069d3b336fd1c4ef699825d9a9ca7269549b062e59a31f3de1470d968bda92aed677bff39260927d613e67641e1838784f3d881b6f12dabe0886a85206cc2b1c83244f76e9533dc5cec08c69edc3a9be694c3cadc71cb8fe8eb8d7585e00524922bfc7c0c9bffa5890811f7e54a32471af10a4015541bc8773ca34d584d60340fb19586cfd12e7d554a9da065c9cafbd346d91b787d6dd146446b57e85aa02b2bcfcab49b5d60ebd610b16fdf7a45a4c2285aa5a5577b74d43189fd8fcbd926620f0f5c734dcd0808a7f34162b0248ad37171ce2a71f5b4ac61fa4bd94b032821f3ee45f1466183e03985d82a7ec4f51cddeaeb78933078a0370144b3b3531f62dba0ff2cfe0aa823b0f90ad0872f635c89576dc26dbc03fb8420bbc84d3a776742a83e6dffc822e2dd0a30a0c20554b97e6997c193301b0589a53890b56e356587a2e4e4439e0d9a2b72da7786a61eeb33aa8070cc5d771777d18e4a40681f973a99a0e38de1538c2202bde544fa498b8e21f384bde3198aa0d92068c775a7947db4f575f507b7bda31c2440df4ada0ac208d8e73c8c684426ab966ae463f7f7044e2e416a833ebfdf7d0ae72b6793fba9a7a59ac30b3d068e2c1bbff90655ee33bbb0fd0e10b303a0610f8171de2a608a44aa849df16803ba870e9ed722506c919ba22b666d0ae0f6c5d7bc2278824b307b87a66d0572c941772a25d6f3b0602c0c59917c74debd6bbf3447cf77c2d57d1c7cb0d847b3f4eeb08481e0c38133b4a0c4f98ddac679f0d6964e57354770c9d6437b54a3b0086ef793a3de9f1dee58706fb3a8bf2b8de1a4d6b0d86b1e1ba1facdd3ca00c8653f81795f14bd11f43a97a26886c096c54dea432c0d4c8d361d34718f04eea6e71cc59802955cce28a0b1ae62f3f06deddebcefd627ec7b2c4532593e5a0ac816ea044a18f0b878b3aa9b0a79cdf62d0aa9e14d4aa1b25fc6d3ff58b2839bab4be8045d96a0b22f1446df79167104df468a2629d2dfb283f576dfd2aad3ac6acdbc99766985e799f6cebf35875ac5ceb16197b22b76b346eefcce13ac048f3181cd3918a35f11af67f7a05298334898d209218e8ab9de9508e03c940a20239c921df0f9928f8d553dd9fe3c537c15434c66af1a2145b1e76b3c1b9483303eda2e3ee77c56dd7a1cb6f03ca90c0ffe93f17819dfcb6a35ef87ca4d5de91a94ed18643aec74688751842c519df48d3eeabb0dafd6ada0b807915040c9ae89395b20d0b8fa8e145028d769d66925951fc4d6df3fb5b0b2aa0fea7291335da53a23f440eb6166b6547ba30df278ae03465a620d7a649c30053e03bdc395e9646356474d091574065d398e1343327405dd4279a9171f834af6cfa4077d1b9ce003dda023f7faa2c452970cc08b51f71d866e25652bb8dceaeb8bf52cdf649ad73075331c0b43cd603545aed71c90e5d850b0b9c005f5fc5f55872a7b2b80a4c7546d5cb1dd60ecff77def5a87097d35337c25d9ac2a2108212bb678f4abc105781449c9b0c0dae8afa4910b33abdd76556b56db8eb0736ce094e3ff71afe026bea57017b066070de84cc8d7943b6e8077322ab0b321e1d1500f0d4feccbd33a3e2a4640ed861cfa5ba490bb95025f84088dbc7a6bc11ab2a134b8eb45f5ca0b63745682a3d51768cfb8183b09e796b461d9891ca4cdad0ac0db523da07bd0f841c6fa80b5528c68404d3481db5535773f66184973db9126a22b4b0bbe98b5b84a53018166054b5e4d0a655da773529944c7124234e59b15a6427ea2ede88f5aedcffe966c9364566f42044cde166357f4e701aff6410a0000321991bb46f71134f3c4531c7e7719ce905dace0aeebb63ad5166633d43aa4b2c651ec22c8aa476cca036fe26e9825f35d7a58c91b38bb478b062bb2bc382a324306b62fa55c50905e6e0b86e9d87ee13353e5d820d872a0000874e1b9d65afe9739906417018ecf656b04a17f21c3222bc3bede407e330ea778781322a6bede24dd8d74525c7ba762fcab2e99d893e2bf7de9a05ac67f2f2aed0f0911e2ebe18f5b701dcd119d092bc7d494e920950f0c4af4bda6644d3234f3eab96672fca00469cddf724e597e5d814550a23ad77b7518bb411348f71ca075a35b5583dc129f80b48ec16f113a7fcc3508aa49a7f7b6bdcc4d6a20ade6157b73202d75ef0789e679c368be93a476572b8886818dbeb113ed07a3ac6e65d900c178dfde9692d5cddf968e3a74f26c7e91443a4558a4eaef54d592fe2a02a9a42480368f57d01ca161abf28c453c36e989819342b2eb567f5eb8e67bdf326a310265d37f36c0f7a5c6d2c50f88837f237dba9a3453daf6e76ed343806fffd21e1c3b86cd76f50da203666917d335f766983ac8e9e6173038b812edb22517699b1b71faff52a75d4859cb28af2a55da3deb8a92a2116557afc22e4795ac3fdb53a3e3c7e6171170bc566a6417e65fc006ef73c52d32264bde24b10881a7fd2c0914a3bf5daffa1259e30052183f55c90b547aed55238ef09d94e55c47bfc27925d835655d917f3b24c8802d63e54cf26a6f8003d62baaaa5a6192f9066192c7454b8e679b64e5e189c211a0a06dc838c118fd06b60c339210e285c1460c3b4b2a82a8a745a818119c37638a070d74bae86e980c032671ba05bf197146e125408e9a3d8567e9a3339e4832ba7243142f142288d08706a224807542d8af117ad8bb634dbe8804413066b836a62236e6b29386c3496788f70c1b3c83aa60f5404c1538f4e6fb21857b4e9ddac807701e9c14d7f9a819aca651583acea0eea76877af747429752906c4116397581283e592539e59c7b08c25ae3209f825da32c3145495b85fc46a8a247dd51a08062b7e09de6cb1056e784309d83634a60faba861a22787e4236da89d92845913a4cecb05354f56b927c615af26e34c71a392851ce290afa386cfd1e22014b8c6dbbb29f4931fbf40858a539b391eb23f0c627cd794e25dd5d3c87878d9d338ac2d061266205de2b381907f766bb40a779638f8452ab66c7824593f20f2096e462d1aac2e141684e10bf69e89eb94111e9a8c5d6afc2197935b0bfe7ffff4ef021460199fcd2dee69e4ed8bae500856112cde53e1a2bc22b588efbcdb0138a751fd0639cc21c43a755cf42c6fa83da241c6e4af326bcba95cd050bbc1862bbaae2cb40f303f24df1612f7ca38280d97daea1075be425f15af6685a165b582d83be07767699320a9e839a6567d9bc905028eb3ebeb56d23aa14af276ced9497c0c915cca31b911c1c79519e80ce0475042cd2ff869564071ae1ac4730fb969414364394ec968e069ba2f9c6af3526159e5282c96c1998b87f0764cfd3555db5fb97e65744e9eca8dade53f8d9f0233e52dfba989feca061e8e688653fafcf3a35ed3ded8d252a4a553d40736e99d517b71a76cfa42125e1950b8774faca8ef41456f2810acfe28ef71c5e08f85a5d0cac50c7aa29a49c2ec93427cce3c89a12259a6cc79da019379cf8d3dc01e72390073273b1164a9da96be5025e24b8901ada01e4239a05e9495622a80c212895ee0a1c03a915d05b9d325f0682751a88323d07f4cbd5d8b9fc26b36b6801d8c3253a412b000f582d70553b91439a9fda9253f9b096b73404016344c863a1fdd31fa8b908aa527e3b58728c6564a50f365f51ee8e53c52bdab57b2d900eb3e4bdadf3fe140b23450180f798642c5c7d438b3cf275f7f970faec8a18474475f0542c6a30b3ef3a031a9c840b41b83d465aa39242f26b8f12f0437402e7a45e75178f717d6ff215e6070d8a459eb7a8a20508e3539f98fc5e0f353128dd483701933cdc1694cf0122d1d5a42481aa0a62fe9f0a2673087462ed130c553d4c83b1ed56eb665f78b919ff71f96d880bcc137b69c0bdeb64803ff17d47fdce1800b57953602733070545101c5e12b56ed86c17d7372484d35cd22b45bcd8dff8baace19c2fec941f084ec8317200107cb6d155d15c6d2bc0da8f72103d393d230061fbac6fe00d4bf0e860d23a0ae3bffb2ac7f0d64aeb2bcdbcc71d98b9aaf091e9af5a5068d40a46e3b18ce768528e7acc756b68bd10a41201f5b8705db2ade58be8734b81777280f809d0e126bde998e78360e30c3f0fae786986fcfb8c7d8b917fb34acf2f8d721d13b16443e94a504ca4fb7a65620181aa50d6dbb7e20421978987db5b0abdce628b77a77a2fa57954d6832ecf2d7ce88339ffe5cd523e4ffb80230c8d1cf3e6a98d21bb3ea0411a55ffcc50181214141910a2060dc1ae8ffb65b9394448456f6ce2403000a7b0a110a4a48cc7d065186201c8da8571b5a2fcc02ced44c39f19a88bb09c5b671132750ba0657646dc5152775ff758be8c68838aa9fe769b3cee45abfbacad687ae227dad51ac58db51bc6666df441c85610c6f3eb1882b2a2aca8d895cce4a94b6225fb13cbef9b82bee7f8a4f6f118e8a1f3f89e8d1a3e6150b3836a9144ee65e024d93524a29a994327b39a5f6d8534cd3e6ac2339e7e869adb566536a5b73c128a66123ecc232cc62132361987c0cc3f036ed85b713dedee2493a8db44a27c65208453333289b140ecdccccf7e8e16efc5128d4cc53b1728547d2740f7713831e57156891d48c2798cb736d7cec21b77244c8def3349fdab8ada494bdcc4b6b6992bdbc646e8b2aae4af2a260e1c478654021124349f6ef2c8fe5ff52cafa8aecefaec8659c780e954276a8253b1d23b7952b43543acbb20ff27266bf894c06836bc460998c8998376199ec1dcbf48e756d5be92b3dd45460eedf1c31ece96dbcbfbcdc9729b6f49b2bda8ee4ec6f768d789e8e2a7d2b69264f753ae2a96abc8db7a411b681dfa33895332cbfe1430c874a9e1101670382927be8f7602fa1e4f874c77346b8647a93f311cee8b322ac0853589bd2596bad35b335237d36a79bb666116ff431d29d4f47b7afe0e8d8f71cfa3cafc63d6888521a9d1520b188bb02dd15a8fd981df454f349e9e50de0582f988812fe57e3a68779d313f1f244941e06f3bc9af852ea264f95e1f8df4de2c8492a5f19f61b2a671976ff64bd26158130f7266c6850361028736f626624acb3fa18e632e9b63a37eea95febdd68f2c4486dfba561dad4a5674203a57fa259257ca459a5efd9ae267bc9b2b7a42f654f335c9fc7afb777fbed86ecd85fddad693242fab3ef8a4f78069bf69a621741b969847037fe36733e8782f773bb2eb2104dbaa0415d99445c8dbf94419346d2344dde8c90342d44932e2e2c04d5daa61a36523a79aaa6ccc5716fdcd3b5619af5b3a7d9ad5e54bbc416138671289bdba28384b79411be72e5ca158a7b8bd015a1182952a4c44c2ca572c9fe11cb50d9bb9765a82c732816959dfe51a914141de750fc4f146f27fbb65c5b96b83ee289127a3555582187727a1bbfcd1aa7938d396b58eb503a08c635255c11232be1b9e7fdbcd44d25e49494c689e139b1fcc655e2f9de3aea6138dbc500450c52f27c6c5e307e8e318e467883aee1ed543d276a4060c5d35159d633772a4b2839624a3894424986709b78abd9dd687286ad3d921b6f59e78bc7eb88d42fdd25fbd4ab5fd767a76a336ac4d5ea4c71919a37247a2210f98ddb39c5dbfc88ca17096fa7195c5556d394e4cea873a8f9a9a782ae66fe4c9e4fe767f3fbcaee76aa365e3fef186ade8ce456e7898bd4dcb8e77af9129b304368c84f849e0583a1d7c4c762c9312fd0d0a4706c3c07c3dddb03811f8661a8ec342030a03225deac8d783b358130b0db8445983daff8efbf4dfa493cd58b46fa8a9dab811eb7c762e6e3ac6479822a6734c971e65622be2eb6e4999588795edadd60d65e735a646773a2b133b9abb7db927b14d96d3efdf73adf1ce1cd36a6c4cbf1af35c13c1d1e3504014c6512b319de22a99cca105ed877a3c99db37dee1bb94b19cb9d3157e3e0570d4f7703ff0622396618f6a11992012f66e085921ce56717be2e92ca11f7d454f54786f437278534797ebdf2de2c6f64293900c4ca00e999d000e99f6816091f6916e9e5bfe01a57c2d3d5d464f71c79abc9f1a4eb5e4dfc99e56693bdbe96d937868bd0e41e255eee89784e58e54a92db9bf818393ecd16678866bec7c84efbc1c3ddf8a39e6af6dd7864fff7ae243cdc0dcf147834f9819bf2f21bcece90d7b8291750e69e05696686c67348d8377be3b7138e54d674b2e6c3554bf0cc7065b833d7bd1ad3cbe0b837ee4923fd8c17b633e9b719d2f3780b515cb10d1c834d58486809fb5ee94b09cf2965f4a48ca4fcc47ee55d71298fcaa382655aab612c4ab028c1a2a4b128997552a142850acf23fd8801797cc67f846df361a88ca532e6c373341d6c28eb3cd5137aaa931f954a09e938473da1f9a3392dd642f2d234dc5036607d8b63a9820cabf3fcb7b9e928f11aff39ad3d49c96107567b1eaf5038ca9f92279486bd9e62191211ac8c14bb3da1ef1ba7c7e293e7b5921f9837972294bd06d9ffaae12f4aa0f2fa79379f25323d92e9bbde317aeda976211776eb5cc494e747774a47ddddddddddd051cf94e7dd8ac83df1e5f76bf5358d52ec5373c55b0f715eccc00b19648a6586bc4cff658a8b98724fe3cdd47a5db2e40cfb442b799b40c992dc4ddc2630d22acddc4dfc6d02d3ddc49f00e66ee2bbd6017b0c5b47b516e4655cf18c3098d7d7dfa0f65bcda64c6732a529fd66437528deae979fddd2f5b73415baeb1f8c457672cfc3138904cadc654043e35212b15145bc3d1a2ab6731054e71fa93c710a4217e1479bbc0d91bbd539e22236b9710f7c6b4ae5688115037d4edf7bbcadce10f7f43b10c74a9873ca942bb2efef0c7befe494d94f88cc901e7c3df86ff625b1763228fccd07e88a1c1f4e91eda66438db0cea7ad8f7d03d5504da2c305fcdfb536700070f51d817807f4f46c8f3f48e517eef4387a777747eafe3568e8bfc9ed53be46332f45dcefebdbbd564ddcdfbecce9c1cd53b3c8d75a42d39958eb3effd0ea782f5bddaefe20e8f4e7c88e103caae02624511c2e6030425c3f7e979efdeef5dff80a47b3549e4f79e3b19747a4e0f84734e0c4be51ed8efd2571f04c2654feff5d4651f8364027019bb9b4f6a0265fda060f289371f1fb76acd6fec61b237d18fa95f437b1badd19f487fc33e0eec71dc79e374a58d1b6b5c1863ba0ed32f98744717bba52b4ad95f38b9226f32fbcb167cd2fbcf2c438cfa675a867594a1e6562df8d8fb8fdcaaf524b76a397773f1b874ee463ee9b6bb913fbaee6ee46bf7b91bf9f54277239fdee86ee46757ba1bf9d8bddc8dfc79a7bb917f5dcc452fc41e5fe24ce46fd485308b617f040673402ced759c6129c962d8c4b2acb16c846173f3a0ec59ee7665d47164f7ec4e05854aa5b68602734d33c2602016bcf0d659de1f7ad0162810fee642f199303dcc5f2f5ffaeb1be6873061181cf1102fb8b1e022288ec5135d890b396a87134bb173a16ceb2cd7754119143a5d8c9d49ff030aec36afaef1eed9cb7e75f9b2cd2c7ff3016292e3cba730309af631578dd193ae877920560c96b94cf25f2e3cc491170cc4ca9ee795eee6a8b84b1a699562ecf6382c2edece3fa0c0becdfe5dc7a6a6a3729b75c45339dc881800882c3feb9727a2067e895af6cef4314238150c96c9bec67caa172c93e1cf1e061fb141868780f91af808cc1f3161099fe761eec1aae3ac633a889f23a2dc05943a20280ed9d5646773939d4e7eef3d2219fe8bf2fbfa1cd692523c68bcd164174015ecfb0d6e3ecf3d66e7d239bcc938e7e59200011303dbff7c74b28b0075420e846f5ed7bcae9730073a473d2d9caeebed70e92d7d4ede819c969b9b1774adc5dd75cdeb647e9bfb892ffc124323ed1a0d8ab714f6d74fa7726ebeeb5dd2b9cdc7f90eb2133f02d80989558b2c57d0e2166d71974065cb16d039f80e46083d091cc05adc2c5a54cc025b1dc5530445763453be3f978109167e8f744ffe755dd7765d3f31ecf2108575b9d9eef2ce39673302e8e643f3c30b085dd499f918a373b27dd48f035136188eb38133c6fafe69e64564886bd2cca032848e821fb09badf15e555e5a75ce653f6ac5300ce51e96690e6f3e3319fb6b3a1781ec90c84e5ead787b70b174346a07af089d0ed6304fa0dd230cb64718ecd655acb0e20ad82ad87054d04e7a7081106681105681291c1ad46906421f972da0441ce5f0e6e3edae7f7757818ceef6e79a2807193608105486eee6e520036a41f0c334b17df41ec8cb0f3b77e32fa426c3f7f008960132dd6ff03554324f4000672112b43b8583b2e93106fb349703d64d01ed7b2653ef98bfd94cc66fe73a0cd97796104e8837f9ef316cc6394df321cc32d8f9d4ef84831733f022fbc3ac1f14a5949bb2e3706c52db0da61af2e99433ab0d9d976637c2fcf20da6920d8ea9869ddc59e94b4f7a6b4b256c3b935034ee667ecc1accae8deac9e6743abd486bc5b2dab9c2e8dccd9c573e4865a4022969c0946d2d0a1c9d17396403c61453c3468d18138cfc57833222495dba749924875cb409f3cbd46ba6d18b565aa1fc408536ce6aa943b9a330d2cbd4e52c2007b63ee9fbbdebac5db1a3dab10c73ea56191d6976923212c9da51678d660f5b61d93b7d274ded47259148ceebe618ccfd3e9a6284a6213d9ca0ca19d0925a9a311ba6aba67d9b5ebe314622dd88a91137d2d78eb9a41f694faaa33a8aa368ba2f2527e5cccecaab67e8e0041810c9630c7ace19ff3d083f5e07ddb540214d8edfb6be4be9675f6bd45caed59ea68c7fbd8f34f9c14c3323250d324ad0fddabbd556f2cc382819aae239383c0e5ff30d80efef26ae627dff8c2f9fc4f44f5896cef7a3604a7fa5973414de435c4e5a2c1a46b8ea636ebedf7b874d8defb74fb5f3fda7a7dac1e3fb759eea879761e66570dc387d7f11b8475775739ec65c97c52fd18122d549505c5ecb090d298697e1998bdd2095934e7de72a4d937ee33a3f5de736ae73372433069c8f9787dfb90bf81d57010f737be8914df74911453cc55980028ab8ce7bb8ce513c6c19c8353074948cb93ca6f4208398fb43beb979e722e077dc04ec64d37d4204114f1170edab919f002210709358d721111073775c35e6ae1e0631d70798fb32454bccd589b92a1f661073737e0c21e6ea18d59d6b80df710bc0e31ee087b83f7cccc5c9a6fb84c8c3dc27427c49888ff727be91997720f2f4873bc4531c3eb878a944ae7b3507b8eec9f7eacb75ce000520729ddbe1fe18b15907216e12e776700249104b8898db430c4835e6f2906b5c784bf5e5c61d328eaff1f486f6a3460d79533790c06ef0a5c65c1d4c54c4dc1cca3861613768aa31f7a6540691dd604c8db936536418428d1a7301f032058815ec064fb5c6d5e177ee00dee6a67ec70de24d37071c72bc4f08f004787a7373654ee94080010491c3dfdc98e9ab37f7e6be4c63bdb99ee9a9c6dc1a13116ed4789fac5429140a957dac00478db937ac543f50305377ee90df71757cccb521e755394f1f8c75888e9b13e173d9eeba350829097a4c3ac8ad60f626aa92978372171be45649acbc3f4d1ad606ed47b492df0694a70c35e6d2cc50632e0daa1500ae13f9aa6875afeaeae8a4522894552121478db938af78f035e65e1e26b0dbbc35e6fe0f22bb4d5c636e0e2e1e9444080a9a2c317786972950686acc95210be0aa9eaaae009ef6ce7de2239e35d4983b93a4b5b80e7f2792f8e17f5cc16ed0861a7365f2db27ec366fa83117070e316ce041ccbd3133f47fca3366c45c1bb9c6c7fb44859d63e733d7b9cc75ee37aeefb82e83745e430150636e0d1f546c6acc8dc9a7e78183986b1a02e2811c6acc85b1410bbbcd54ddb940fc8e2b24e6be645ae3e57a8ddb590810b7a7780f59a9c20ab25b1d9d745061a9a3a91a734b68b816aff197614646470b76833bd4986bb30f4ae0a1c65c520f35e68e80d800a7c65c2deb7461b799536b5c1bfee6a27ee7fe789b7bc3efb83edec69de14f37c7cf5c1a5ee6e2c771efdfb8ffaa9bf300b8353c8fcbf3325c9affe1f678d60df2f13e01f2a6fb24000f739fe47f01f2a51c00f739ad3d9dfe05fd0bfa174483dc243aac7f22c5e2f13fbcfc762a9ad3dad3e91f854ae9e8e0f0a6aff900dc2401f827266bc73f9162edbceae98ef6a306071e5a1040198777da0f1c70959adb39e67646ddbee13aa7c3e659be0dd7391490fbe33ae7e306e0b37c56c320cbe7f124cbffa15b90e5eb74932cbf86eb9cfc7f1945dc4496ef812c4590a5fccd469ebfe33ad7c3564396bf739ddb61bb21cb575de774e4eb5c0dcf75aea6c775ae86e63a87a2e13a271f5fe750f73a87fa1cd739f9335ce7a493ef5f38a561b789d9e7f198eb99e6d4984b55b60bbb41558db9598649a253632e964b45413ae043e571fb87db32dc99db5c64aee3b87ee3bad07528de5fe70533d3558db9578ddb438ef22a4ee453bcc6bf54868be135fe3f9cb01bdc5163ae9caf463edda93137faf0327485072b3fd4980b73bc4f5443362ce15163eecbf13e59bde93e513dcc7de2c3efdc1db7adbcac700ff9805be70a59960ad344c16e7388c70f3b3b563ee8a87274e0f44003ee317a2c8ff0c644b63957f57d47ef755cc71a6d5da5d1f8814b5a0b3364846d6508ec0209ae28c98e06243600f5e00bd8c1e81b6298b766939b86dc37ff9cd65e5a6f842fbfaad138d466e3433a3454d21d8d3e7b4d1b612f5f8ebe02c1b2e779f4becfae9c01c6e85332a9034418035e5aa08e88ad4d5b1b8dbe75a22ce10d2897fee5e5056ffdf623defa35d2f3bcd21dbdf64323bd4642394a92462398fb4f3ef9feba9b8fbceee90c7971c2c508f2fb09a3d4ce5c6715c39c4ff5990115ddff1e7eb7bff6ee8206f4e97a07f6338b77b33f3298b50eb1fda191f72eccd0df210f4839b076e73c0d3acaa73449ec2294ae61bf2e5dea1b52654fdfed38eafdab899873980d75efdcdd1d7e94eed10616f64f5e838f60e1f4a126970abbb087d8bce605afebba24ec3092602fb3ec6716639c1146e874c47ed711dfb9bb24d4d138082fec247cf2bdcde43f43f3a2fb138ad3811415a627bc162628046181108e078a4c51b0fd4451689267f4e99e369e41dc942027b2e3191f0176fe36dfa4dbc472e65bf776214db4811966348d80cf1bf5f7bf649a9221eb5e635853f2a377fc96e4a24489120124483f49f8c8d63fa4bb74c93d3e451afbf43f6182e7473845e902ba704336e8b798486af4a427ddd14da23bf6c439be6b8dbf7588cff32e2fd008217e48bbbbbb5b39ba7419437659b056e7aa84cc3de4866aedcff184f5cf7e734339dacec352f5d28f383c39caa777cedc1afd813d8518d486481d9ca0ca100a2a216b432ee8a47070503a987b0984b27777ef68cc84e9ba74e9eeded142eeaf4b1717d004e599e78c53179d925e9284067613ec679030f3dd04769328ed1c4b92a7c4b13816c7d279f6124fe23997bb665eff10f21bc7a0ec6fd3798e06219d4e6edc03047eeb48eca916d8ada3389c2851fc1dca51fd518cecf549f68ec5736c932e309bd57f156f47a090ce5e04f7640fb70c6f3567ff681ac20ceb8e5eccc00b27197a919a2106a2fdc470810b5c10734071bdeb981b1b91b14b972e5672cc35369504f5343428ccfb0a43a99d9d9c613aa9f97911b72503c9761d04e559a7e98a33d258e363c0a95a4a8cd8a72ea1da9692d12cfb0b6f39f2d6528a9c8bf19a506d33c9598b2067ed819c7513397b0c3855f64bb815fc0c6341f93561f3a2cd8bdee645a9cd8b5479cb7b889fa98b60d0196f08cb3421f0b137798e8b80532df18e70395a15d346f3fbea723a87fe237aefd5af384db09dab6989d2fb977ebe3c110ccc6f4d243520d8c3a640b4a63119ee22ea68b816dfb2bda78f43fb8d52fa9b6ba1cfc57328bea6a4f26aea752e5a1cb5c5b5e474f6f5476b7155b35c863d8b63712dae850917cfd9de12dfe239419e435ae2549ecab538e75a9c0a15d7e254463ccf84e5adaf6ca6d2c8b59096b42604fcec23e08e7039a3cf36544673f6d5e5689fbd7539f5b3c7dc0e23ad837f96fd742bfa59f6ae3732bf3dcb1ec808bb76bb8cdb5892d8e0d5c84c648abb8842a104b7d0ea0bfbbed1f02bb27f9c4d4c5e61cf7cfa749b48b2fc8d89ed4896789b7f65d46952b67c2ab1bfae2118186540c1492e22fae2ca73ed65df58decd6ef5d6dee6d3d6cb3d9b0580727f166fc5d9c2ce7779be2684fec41b951992b93ce4c2fefa79553be3755dd8888c42e6cf4b6aefaf2b3344f6e0a77d114d2c090cc33eae4822e1bd249c5fe156b815973bc9f3c50bfe25dd898b11310e2b0e71277154086c0b7590a37600c1fa101368940c73953b59e26429e54c96a62ca5943fb12f6c670c2b5273cffceba57ca61f32c2986070cffbfe27e3f7751999f35f9c979c34d2326cab19ba1147b9a5256cf166774835f7bc8dab88d02899c7f126e7bfecbaae59e49431248ad48ce1cd48be708ffccb48be9e76cd7293ff2efc8ebc8777896ee235de415ee32fe514c532c96ec50813dbdf5504aea8adcccca468b09c789aa932f354ba4a4ff127527df66fb3a3fcc0ecee3ef3f61535149ac4ab71e9441c758386dd5028179558290684f519c176eed3ab91f3ba66e99b34650279316a35110dc145cd4338ca7f3b11413f9d52293c4f2f05f3e905f65d411fbb1b2a635a7d387a24329c02e1832da17cf01d94d89cdacf9fb389e962d0d5605f2f36e73bcc275f6fe111e8013a7a49b2a5ed48c6489a1119c39bd4024208217c1042ec7b7a953cf2eb696a761d0afb1a3606e4eb338adfdd60bd3d40f600c2fad7ad24eded25dd23b286b76bde7728f81036f62da1c43037255738e7cf79dfa1b0b78f6e46e4eb9bfe11f9baa211a6925a7d9846a311e95f4af6884caa5390a8582c168bc551c1e2a35a139e1375a3ca193a40e29fcac77dfc9f4e3e05cbf43145f3eb0790ce893dbca6cd487eb4d3b05763aaac5594c66bfc33d8f8d3b0f375f77bf2b1927cef3d897d8cafe6877bb0c7b00daaa5949574693ca7f4f6dd2405ab825e35209de12dfdbb5bad106f4f460806f1d60a62bf15c4e5d207715b7fd6306fe597aecbf4d578e55b6a92829d5f7f08cf29a9fea91c4b67f4b4b512deaaf6913609fecb3dbd1a37c9f747a5b4dff6a6ee5fa7c1f4c80772ebd6e646399f4ff5f2d7cba557b59ee3dc9328cff977fbe53aef9cfa22eb232920ccaaecd95843884de9d57dceaea4ce391a84e179f555071006ad5814d6494391bf654b1091a2a22b57ac583961d8b5e98c748ef147c43242e6c79fb8e7c232e21e88532e3049bcc12a846a6972dfcda6dab7b3a1de832847b1c0f66f282c20ce68341a4199d103e5d1c4c1c1c1c179189c0ae70926bf9fd3f4de866626e3e0e0e0e0e05c49dccdd8934824ac0b2b437aa04c7ad7754969edcb6ebeee0fcc9bbb92ea877394dfcf77edc7f4b9f972224b1060960fb3c4459422b624a732c26bb8e4f7dbcddb68bb21bf2dc74bbda7dc5d7157ba76105ff59c773d9c9388fc4d2795e59d4f300cdb79b27f4241380de0583bb0c06e30728157a4de715d0572c34c7ad739a90d0212d841faed88dc78bbea236114fb11c6b0c6364dbad6413ecf7b43c84e0302abcd91ab8dd52673fdef1dd8d72739d5e9722afbf5bd7352ae77f4d77aedbd5c8dabe97fe883cb790ed59fe3e1cd487c7805db392a7b1b86e74f3ce1c8af28a815265c32fc893304383dc2f97ef2f4c344de5301a5f4cd182f28dd75c1f79f2d528e5fdbf51768cbeca5fcccadeacba76ea5bdfcea56a397afb915e9e58fdccabe7c925b955ebe75ab97975f722b9897ffd23b7c4c59e280613bcb76b43e7713a1bb893f8af27237f14b2f30b8e46ee2fbbf942ec9ddbcb777e46ede93aee66ede8fae76a9bb795f6fe66eded38b4d77f3d23abccbf4d248922975970390d84d2b327c27198eb124bbec84c8381ea2b09de143c73f462ea00c5f09f9cedd40bcf90fc007b0012901b3733732f36526f6d69567ebca55089921a80cffeaa705da6ef5d3fac7dffaf9c77f7f5a399ee65b3f399ee669f89fd60c6fc3b77e66781bbe86ff69c9f0a86ffdc8f0a8bfe1dd47b7fa69cd3c0edffa99791cbee6dd4bb7fa69c9bccdb77e64dee601f0ee2fb7fa69e1f81cbef583e373f89b9fd68d4f7debe7c6a75e87d54febf43c7cebe7f43cfc0eef3e73ab9f968dc7f9d68f8dc7f91e563fad1a9ff3ad9f1a9ff33ade7d75ab9f56cceb7ceb27e6755ef5ee35b7fa69997ef5ad1fd3afde87773f72ab9f16ccef7ceb07e6777ec7bb27b9d54febe5797cebe7e579fc0fefdebad54fabf43cdffa293dcff778f725b7fa69d9677debc73eebf3bb7f71ab9f16e97d7ceb87f43e3e00ef1ec6ad7e5aa307f2ad9fd103f91fefdee4563f2ded81f8d68ff6407c90771fe3563fadfa02f8d64f7d01bc90775fc3ad7e5af483f8d60ffd207ec8bbb7e1563fadec09f0ad9fec09f003f869614fe45b3fd8137921defd0db7fa69cd37c0b77ee61be00bf0ee71b8d54febfa21bef573fd107f80772fe3563f2df9447ceb473e118f80773fe3563fadf8457ceb277e119f80772f835bfdb4e02fe05b3ff017f00a78f733b8d54febbd11dffa796fc433e0dde770ab9f96bf03bef5e3ef806fc0ffb48ef8077cebdd4dffcf11f80198c70151c8fd0de891fb8d8042ee67008fdcbf8027e47e05fc90fb8b4800114ec8fd08d891fb870823f71fc00005f021f71311820060e4fe01a8727f105fe4fe21d7b91b213a9cbb09729dbb01727ff490fb7d048087dccfca3be47e9e1e3cbac8fd3fec2421f7efc821f7afae73373edce4be51d9f4ebb83846c8fd3de090fb79e022f7ef50e3dc8d0e37872d72ffcdb52942ee07c0edc7e13a77535343ee475d1b8890fb6bb84f73fb69c0b96feeed1cd767b84f860b676e94b912c7bd6edc79ba988d9bd5b834e656d3d560eee8e5924ad7da5b22dd97d185d1aea9de985bc386bbc1e16e66e095e1dd19dc4dbfdf1ceea63f4aeedc4db2cb2e53d74eb08e480a43d9b367d786b803ba327118e145e18561527baf72c2ec5f972e15e3d27aefd23a5fefd2ae67ecaa18ee60030b3db6ac70bad6214208238440b4a511a216ab4fda5db596421ec34f64862075e932c292bebcf5a7d470abbb54e8136a3f28dea10676c296d8c36bd6d3b41bd421bf1f3b92e3cb114a6ce4e518691e752983db852da2a082a1d0026fb1c5b542e5123d813fa0054ec116676c71b15069827753f8a49088e1ab0216da420a5a349401445398b201265c3da620c1079c00c20ece4081089a50821664b1032bc2d00329ac90424913412f4a88b848f1283c504294052e88b2d0240862a0288c2560449982023158402ae802083dc842052508c9a095c42c6817455d604294022d9a7499420fb078179a080116a7620b2650a6b802932d566c904611cbafcc0f58f4aaefba93a23008b1fc760a78c0c2b1c1168a587e1d12b0dce3fe7d3be79c736e6ed89cd59aa26ce81cf5de7befbd189970842370c18563b993fd0874db2035c3d7f3ad2f21ca182184304a08a18c4e68012506f9be2d2f177fa6310fde6301054c369f9c0daac0bf22cecdfed31645e877b3ff34b7f02914a1dff5cf27838745ee775af8165bec9ce1c515ce084319509240cdb84111cc9852850fa09062031b2ab79bfda722b87712801cc8ee895cc9417cc0b603e883f5695ee56edea4bf392a73d6078288114818d1715ca814a191654ba59b6afb9de7393f190fa1c91abd7be77e1042b146bfc5ec08e9b0464edb19bdfbd38c5ff451b9ce692d10af06086c966ca592ebd77ffef53e6d488ebeb5de79414a556e0561fe87ca7f837eefa3d3e1bda757bd7286755857d8d7520491e5f794be9197e75f58367a263430fa279ae55e4dbd1e9bd3c8cbae843ad562361647b9fcddb862b8c117047aa4837e382c61ca273bf75ec276ab07213e82c618b7c425365794fd02eec6bf9f4c7743e152dc8aecf07921fbbbdbe228771bd40596f0eba983efc4d2625d3e1d915a62376765c21a77e3efefadc2a16bfcff71e0c88ef22d835f03db1917ea68de894219087968e283881148d8e41d47e48a5c190e0dd8391b00f2fb53cae6f454479a758ad7be9ae7fe4019006ed50ce88190a3f2d3c06e3bf9b9f322388439799c9a681c059308cd894d8e8294e266d253689a46353a05cc144ec14393ced97a8adc2a8094d20f0233854131893671902b77d057613b08ca53d114e156f3e12bc0ad767037f0e12fa0553c740dfc7f1c385e7296b75476d5ec7690bb819fbdcc754171550f563a4a4328468655328457ae6c6b26383035e79c1de45631e76602bf55a001f1cef383749e3d855bf98313a7dccddbc0f6e7236c50ae87d9c36caa1ccb4d487fe2ada7403cad8ca597c79b0f2acfc726d63ebbf46e6ec865e1c30e351bca92e88d9c957286e52c679973d2cd8a5b3db00ccbde65ee7aff4c31cb4b0abe10aa81175e4499d9116da192a3a0f2dfd02c236fd5baca1179a10a361c256fd6ff2216dbfaf021313be671d44bc0e5d705dd950b7a11601c31640425236f1566172fe7fe82a72a1d74eeeac14ace9229b355e04a8e70860b1c9633886a5f39cf09f98591b7ca5384e738a22d4de41c3c08cc9e00b78a39f35c1c77f31aa73e8adddc950920e1569d86fb427eee31a101fa4f348bb65391fefaf8838e9b1a48282f65c7b277f6d1bd17bb5aae4b972e63808e5b3da2477fe7f29d297b6137872523e1938491253ca7bf95f8d0e419f72051a69b96c052c9c1e7664451250aa110348142cabf0b052c9ac04252ba820ea24ad4840355a491858544062c58f167472c43447c89460b9cd8c24262230c56848210c0200416929918b8b7852a58114fd7d134b0a20a10b0e0bdc10a96cc1071be1a1f431a54b0906867b0e203b16c60c282188805a3b0d3513a8ef07005095a8458481c041b28012b3ebc4764ac80010b090907ac88695c8747d84e3a30bc0841172c781dd10ebe00810abef840100ef491ac643b94a7944c4485254453b8c2c50d49ee7f79c794df7544547092aba08e067eec31e0a0cb95a682090b622056b43244c08f5470411660b0905c6160c18ff84867b9410c40c042f2acb0209e4d88b0788285e4dab2811534910e9c9832c6095848dc195a2c81e557a6f02228d6787d035300a388052fce1296ffe00b445258f0b60f78c0a2578db7b330832f4861d159e37568bc800915acc6db455e8c4088056f87208845b32140818226b4c6ebb2b8d2022c2c785d174760d15ae3c591c20b58a85623cc81032b23e4b52b32022bde231d841c24410ad61124971652c072ae030916450a96731d5470c28af7887f60075394b090c81038eb4a4e90e2093f60c1ebce58e20e77605bcb19565c61d15e820f9ab0de9d7182d585135144611181c917b2b0de95c182456185d77d31f4012a2c1ad3f082108b4a261009b1fa8926598458749aa08a2c51b00a6f4f01460d8458efcac00516cdb6f0842894b028ed4212252c5aad68c9c21516d5b8f0420a8b8e2abc3d06134c908545492c70628845ed10a898620b8b96aeb8620b8bbe54789d95339cc08445612abc47dc10cc60928585c44da9c2023458f0df3d3203041612130c58103bd761aaf0361955280116168da9f03615a6a440098bd6a8f0b61638e0421316b551e17d174715165ea7052ea0c0c2a2377080610c62a0c27a7706082c47e3ed8f0b13e223bd012ab0e0000b098d82355d877f844764ca3082dde6b4af260adbd8658680131fe92caec44088850403010b3e10cbbd2333dc800531741dfd402cea15de0ee240185858f479bb07471b50ee264ae08522d6bb3265b8134e9c382122634abe911d5118597afa7ffe75451921f2fde5fbf3bcf81e84f2c245e4bbfb12aa074e57bdaece9204c36274abec7dae76b1dc705abf5ed630f2bc0b9bdebbae7f2f49c74ba176b57337f1df076708ab8042a55032281bc771947b46c251b34ec7a5fb886909315036b5e6195f03f250d0f3f4e1c3177cb895d3f1e16e4e333f5cc16e38d97164a434087cfa40f9488e59168172bc463c639887d641d2780e8da3fc7750621fde5018134818f6250c6fd710a4994c112159c9755e339b746a738e7eced17d5783bd7689f41ff1310b6eabd933c764e2bb3c2313a9b0d8ea087683dfdee3df17ac3318c02533c43f7ec43dfdf7790f90e0042999263b24848145f617a9d320fc3132f6340ba8fdf011b89bf7c4a8f811f908f2eb2c44f97d6799597cbff2e7ed31721481126a50d4b983281187e89b0f5fc4db911c5f62df7a793e8f63f223bcdec33d52bb604337b2751692e1857508f694315829eabade69d64ae1110882972ffbcd1fc4b9623b77f79c71949c9f6107e1dcd13bde6398fdd6e1a54c560cf63dc4f58bca0314d6af58e9bf9bea9555d3a95ad3652a92ca3dcf5464e899f1fcf494e47824c2307abadf92bc430cec66adb528f91cfa3c25be05181ce881a65357f8504cd92106d68ae72108e3c324d8b8e379b32d636ba7ce5066488658063e50867603d6571bb0fdb187f27c4bbaa969df29265d1776f3bd6adf7b9d9a1e73108910d14c9ef3de3b52baeeb9eb1ede82c88db7cc8a8550e3a9136b21a8653be593bbb77c413b6f3e8eab3a282563eec6324364de03e5a7a5885513103f2d4970b1f27ed504d6454cc5abbfbbfb7d52b9482af734bc2636b117a3476c5edef2e71597d4aaf19868d5ea75afe6d51c91274e1756c751d5f20c6d3e8e7297458ec02a491912bebf2cbefeba2ec792638c0f73c432f181f2e9b9e822de805825b1ed5cd56f95c44a2aa6cd28bdae5a6badb55ef5ba46557343b93ea953afa6fe4b7d7beb932ecfeb58697d7a3df6aed51ae3755d92ca2b5f09997b9ca37aa6a37a5a2b51405d0d81ddfe8a6ff21cfad977c3ebe39cdfb342ec9dccd7cfe771ec6e988c9089fdc0ae8c90ecafcfb28793667056ccbb259c3242feba3242e4c44ab893117249eca6f772054552d9d3be7a5efa82c097bfc1afad753be76a4ada3b579fd423ecdc0d7df83c4fab52fb91b91cc7a8f7399803e85e318c08704e0904067510bfbaa15bbdefbe62b81af612cf94e4b6f8cfcdc76dc9f17b4ec722b7e4c925bf0d2863231da9dfa834ee75943deb108d08000000400033140000200c08878442b17038229335d1f614000d89a0447e549b89a3248751ca20840c20040800000080c860246d00c7567427a237fe69bccaff4755a09fdf31a657b065d8225c4ad0e7eb2b5bd7d719f2e5b290e40ac36f3e244b4135d48d9fde7020bf0e61fd5c2375013f6d990cdfc4972c12a934bc6cd54492451c1208cae6f9e063b928f3a42d2e89649e2769cbe050da9aa20e2c9b451c54f39146b048608e493b1f75499de3dd2db83ac386fe019bc8039f88039c600be69599b11b662a5392d5287340a22726984c3a209c20f1e18fc7d1227467056e064cdadf407ff6a806c6091ce0c41dd864dfa2c53dd277df428ac818a35fc426e4b6e5336bfdf957b9b1ea0f2d0df6030c32a60cdf0cea8865ba4940954cf9b9640ad135085351412fc13b1ef4fdcb865900f54c9efdaa12c3ada4c033e9a880286d9f1a5f0c9025978449e1ae7f16953d0551ad902f4b259771bb40b0cd7f192979ef667ce3abce05f0c1d96fa362fc9dfe6d8aa9613751432b77a55dbd50a2d28dc9998be4f76ff25ed64882c21d632be979b88f89c20e955a8d9a37908544b4470f65435fc743a3d39b5ae392d5b4cf16f1ec62ee348b114c8cc5443ccea367b6982ac5aa8d330295a71fd58cc9b47cff20ebdce57e2493094f5b355abcdd9702720f27a7d01782780b0dbdee241aa4eef4625e5de4219d78705eddecf794ed244fc8d99e06a9fb3e43cb47634ea879c91c254aae47c7c48cf71d103192191ba6b123ecb0029a8511bd9b80c5fd0574ec34c9afb04a54c0d77dda0cab9166a0976e61b8ba65626f1c3f6cbb49eebee9fae8c3e1be895cf8c53b5aca2726a262f481b716c2818acfc7e9f868b9b81dafecd5cbae4b7352dcd05e97e499d633fd81fa6e653fa7a11fd57d45523ef7a85b5e5015e548a272e8f2164a9550b0c09573814f70f30497bd4298aa06ad24160bac7ec1a07c362753e54070c37d9e59ee782da24b8c0dae23500ab1c9115bc9b774b78dce29e5de161e281cefbc191e2eca6a8c398b4bc66ce0d49ea4540fbab665a3366f31ea111634d5f4f472866cf8e065e937f28845cdde8ea6bfd00e0c2ac3ef87516eef8f5972caf66e7e2493528d8935ad88a3e38f5bd877ca109a199abb046828b7a2c70cf7747098cfc8315b9e780ebee85fa9a10b56da90a381a7a4b667b1a5270f940df25b54d947048eb88332273f2998d033e5ae797208d2398b4e3f7d543ad6009ff2dc77d20c8d87e12528142206d886ce625b946a4b291b85357c22eef7d30f1a9e71e82d865075960fa17162cef6ebe64c7385400e9fcac2b52411b13bc3b86bc3a43791fca36c738bd41363ec8c875b905a165d4bbafe0a7f152e84dca70095fc3d00839d77dba169a0f5ecb962f4bfee0620fa74741844694ddde40fca40adaafff4ed59d77f70e7e6afd8395e4529f0d2ae7e2b437e7d41fa237e9d597734e219431651772a607fb661bd96e16da9c711e0adb9ceebf1c3134beab63fcba165d1ab352f3c2d31e718cdc02380c409c06ba0e072ed0984e542e938090451254a8019f9d9a38f5ce1469397c960806b4d2e9859098f8582704bdac9f38b96896b407e8d018807906d57d32b6239780fe16ead02c6ca440eb35853fc7346a827c2f9343128623cbfe9ebd385c47af92342d5eed372ea7e4f4a90e01ae7f2307f209a3946ddf6c559e0c5b88e31b48ed4400cad8729fc97feab54b9173f9fb881d8da7d5aea511738d6ef6acc72653bdb404c1713ecdca4942b04dc3a25a140e5977b8d58c6a41501da2f4a6553f23c70ecf1be4047c79ace14b05aa1b1d45d9aafea1133d81c16120c1c6ee2f6237ce4098e85c0d30aec2a485bf83602da36999823f75344b948120dd9123b0c6df5cfb1fdba4ab650e0b474913e15eab1cbf4a520dcb4b354fcdbbf93cff471217397e344cac6d1ef6128a82f1cf9d53e81b8df98f444064ef708a32e8e8b1397be91d6532ae22426f29e20c2f6145061c4b5e4e44830a879476efefc3f2bb225d3edde2def840c08c1ae39bc3c3d8c63a259d191399b26ceeb748b4f807b6b8c73b71b6eac38a441a2fa870e6a4eb3fae0d50ec1108f1c74e807a7052c666921cc829d33805f8da7c65484ca279d2b8d8cef514a084d37343343520952746476c3bf82c513b965c0c3fd0898f63126440b3107698b92d2789224e7d9e6203f9188ab5025617585c3c9042f519b63cc99e6e7f21bec6a8e738d836cf2293c1e872e7af73daf869699c008992b43aca1609870a025153eb8c4f1ac66ee588d7cb19283eb9656067e18676476161856ae6f8d99b688cbe685b58c508bde2ee1258283919311c36b1e018d54ec204159d648ed2ce6e420639ea478ea077ceb3439fe3471b93bab286067022a0626c3287928d05d0131ace72f34041a53d8498426e52b7ce22477b7562f4d075db82cdebd6c4604066ecddbbe1eb48d73cdafa9b64cd5a556600d95a3145cecd9b4d6831c84d308706fa8f09c6263aed3a26cddbf5ccd6d823046c4c4af6e95372ea1993a30fd3aa413a08c4db989fe019f8b9c8124f32c7628047cf44a3c33285c8fd334700d1fd0aa60dab6339c5a9becfec6dd57fd99d3b4ca44a1899e5c51e08af3ae9a3e6dbad65c082d27c32f98047342122db6455a9dc9546413b998848e8031abf708fce40e00af7863db81e8b7131fb0643904120b71f83cd8e06ee4678a483f4cd719bd7964708e05dfea4f06d936f6cc4b40667d03d5dbaab192a7675775139bc8be5afb95c384451f3959d45ac9a2ab0168723be476cc21394b2339f48320b11d69ede81d5726a71233031b811ffcaf403aaa4a6b0b24569390850a85518bb26c0de7f7207a0e9462c96369590e0d40ddb35aee6450f98a94926a63825cbc037c222d75bcd33eeef30b5aa44316717da09dbf3f53aeb1197fac5f6f1e5d02133dca17e2986598b76b23de852df2811a7c97333f2eb4ccc549cffd540a0ba8089b464a200295731d4f1ec226b88bfd89e011c441777b136de76c78ab5b672ab2dbe71be52477b3919498b9d565a9f581dd0c52e77c36162ae89a195a9bb28e0fc41b0bf3bf34e57f803d2e2bae5d2d3f88f5d3ffd22560833edf8e6535639ebb6730031a21e11bb15caf89095141b9661163c7c85350434420cd9dba2d4644643cec4284f331ec83ed5ce313e48907dd60b741d8c87f16e25a7ead1c99a6ca57c18691b8ec7281ee38f678e04f3545d60f4b8b75a12721b240e9c8fad358e5de6c356677caf44f5488a865d71b9b2baa35e207bac6f292cda6de7b33bf14c1dab9eb00935f1d2a45ebfa8d55db2baa29fad3db302f70262a317450afbd1bb4875d0db5111117b6e6bb2b372464c3b1844029557922f80ac9c9401b986851210ae1ad809b3c71fdd315819b047dd6f89504bf090c1ce32d491f3f263d7dbcb7f86877fc72f67f977b979eeaa3faa562fa504d0c656e5e2e9e8abff8115dde4129ac7a8b63932f4889267bbddab219b47d74ab04c526ed49db2c1ea50fc655ca2a896b8f9c6004160cb436b719188a0431b144b97b22bbb1e49f048568d26b5fec0eb3315c180718735d01d789aa47f963d79180bb077ea154ee3cc51ac6ac452e0f840242a2da03eb919008c91ae2891a13dfcc5473849a5645bdb9ddce5ddee13948b57a3b83cafa3f96602ad3ad682634f82fe30a83c88ce9218ddcbbb2d0c4f526dbd605aa0eda3bac6726ce19b17a799c9e8ea082213bdeb5bc8fa8d72de9d0d8f132abeb87c3d7e01e2f7b5c0900f1598972c36f9b0078b279349edf4a09fa68495a39d73299ad3bcae2a0de92d6a45e16f46709bd80194508e48236e6925222acd96de5ada3a35b543e0338546e03521fc454663328e6c3a089faa2a8c867c659620c42878ae8e8814551b1718b34d750b4a900f824465f034e89d4d0a181f9d93b094684b36969e3ca3fb52ba6273e2a12a433d1e378f9940d653f7becbfbfec9c4091ab89eaad9d4d2038534fc6fbf349a260ccb411201939615b8a76188f7ca6b76be5631e1fa5f01db240f26418ca21013cfde32a80fe068724ac3b173ea880b15146bcad186e3a0f890433f506a7aaccf8acbab98fa42b653a54978a90361e3ab099ca2721ab954332c331aeedefaa923dcd481cd9d52bd427344a0932042041c7cf15787d2cb4c2f891af88da7a119206499a8624fd4892d4cc39e7d7d44302d3a98e458fc9a997fb51447183f5225984cf0b91dafc520361a4e8c142bfea5e58d13df566d8ae6f874c9994296956781976ce6d5d4f57e4fc9d747ac2c296ff56fb90464b5556d1fee69f8a8ccbeeb09f130ee8b6bdc93c16053088c79e6e7b0fe46992819a9bafa8346f0bb4afe84ba57c21e53b400704955ade43d347fb160745079f8a497b6c10e597c977f22f590d79076ba2e7a6fb92add06564d01fd1e97e8c35f6f7159b244c5b5acc4cc8f1d4ee6a9edeeafbf5e70f3219f059bbab1d700a40203bd3da4278a3c30df2a60bde8841e4c84b49ebf4e9350bcec77c3bd1774afc26a4b46e024f154b1f58bd95d5c955aa0bae47417bf0aedea18202d64e590bf0d474a1045fad24237fc6e3801714f0ff50d1dec8ccd98298b98e3cb803945dae362e301823b5735e22903785385767055280f1b8400be99de99113e86cd15d34a3179fc2329e161cc6bcb6889a7e15d5ba5a262d37aea928c5b5b67619294abc9d727fa5ba87baad496b5fc95e1357814b92b5a751a87285841476ec1a1fa6b09483e569a44a0f63eb37a83a2233be21dfac7e93fbacc8284bee0c2754e742f97f566dc64f69bd5cbd4a1391799714124bfea080c18e6beb0741186a86a78b8cdf17e266f80fc84bb7e0f56403526691bf3da67f80d89f6634855e921aff3180a70ffd4f37675e7eca48950e614678b0ac3dd6dca572b1fc0e0ebb4f536923536da964f699d537b16327fd462d571dded29aa9d4b2ac742b55ab8e4078c10506c86940683780480e6826c7be1719e9119ef90c058a10f1797425212a4c1d91988ce7bac71671d26d806454ab1844f5a73f0bc5f1830e0b67743c0eacfdee2e9589445a04a1ef3b702958ed69b878cd2d4c1d80694ba682bb5c69a1672dbd53286dbf910ec62da8f282982c34ff19b7ec08d040f24ea7aad50979b1093213a7d8d9f9636affa5ad46a5da97c2c898c55c985632833a4594590bfc64cb2c289a52ac8100dba887587e36d921bf8f7a3eb62f086e3b70dc243f934c2f52512cfd27a660564fb96d0f9e4cf49b602b2505ff5174bb77e1447d7297e8ef32b33aebe5cc486be79313efbbb04e49758b7f1b20b38073b30a710be51c8f08297f828647d30c348bfa007c4b5ebfbf653fc62a22d97f7eb67df31fe7a20d4214dbb2a434604b816386f5b4772a93fdf4c14c2232f65c9da60e0fcf53607cce6f0f81fac0cb01ceebde0c684274869db8704c4b640a896a5a0c42db0a950fba26ac6f702a4f9e11ae1103a1f607aa587cb973e1f9fbaaba9b68829f98da5157a6cadcb67cbc19ad6af1f16504d790227c4b533234d177c3295776123d0e9462be57aa4aa5300b5a0ee42810020589e991f64e7e4e6d0a824d6a0a2e3f9dc773ac33d472bd1ddecdb4b6af33f0946dfe6bd8d5c4eb5d8e28465d0aa0ec957c6f5a0ef66bf0d0abcdc311afda2657562cdbf869ffc3ea259a9c1f4abc27dee8c6a8d2915801bc21312ac3c9b05148c001aba5e8507c2a690e942b42222b93c46348e234d8e17c0a0ee028677f78678e8bfbf7637d095950b1fa3f1991c0d60403a5adfeef3fd94439eacea244af42fb6abc8805acee946efa4ea0a664d34cc567566214bd73705e8aace6e68407a5b69608552987983389d42ef08b044fe3dc19294b419b437f5148d1fbb55f4cbfc503fe06c9458abbc3a87e56f6e42dc43bb8aa8d87c3bef4fb12cf616ebd7c35dc2fd6196bfeb89b1841a1dc49c015a1ce3e3dd098d7e1554b68ab6ea83c9b8c35294449c4fcb4926cf21cbe47593396426467a41eb0ef0db235dac3357286ad13dc27d93c3c958137d3b104ea895054fe90e82d9b81790be19b5060b16074e0960c63accbebe4fa1105f5072f5f1037a8f42ccb7fbbc44d8edff83bd4e526ad346604f551bb73e9ae900a9ff0c66be976297d84a874a6ad269396e2e3b3fdd3075fc6abc4505cec6d8cb6f3285cea1a6e0be90a8f508ac3c0569dceedbc854c45e337c39303df2aceca66045187b2e01d17e97ab4b0a90bb98ad23490e52159c18129ef0d28f0c46211a65cf22d7c5154fb6285abc32e03d64dde80e49a5d9da9e95d6eb62481ab0857850e38c389a85e8325b12b867817c6a2c3b651c754ecfea3ac25f3d53ce69608be73803956e55160c386e10cd3498bc59bc695c136d6ec02e1a2ec7335d953d05f62b3e966e20339eda9a99d9bc307327846b4872e498f74d7ee0fa44cec5d174905f2f00fb06b2105333a47e66922cf33f9c76d522e48d4827a5e210c031ebca458633a5d7270104ef55a203563ab9d050a305f1c0ed6f262a9043f5916f958250212a757040ae1264ccd72569e293323093c770ca30d10912de04ef928526cc430184562c42f9004dd0318cdb421b251bf753fa8458cc7ea0d6ee9b012bd503e30242a0e662511c99a0b94c02aab53c6a3094ea2a0d5fa982c1d2c81ef5f2e3de688d3ca34183aa46d1809b92643efa9bfc0194db0e6b033674af13291113294d24c9afbd0e47f1de479f7a0574c36fd948470aff9726d2823090e0e26998e63fcedb010ca2fd39a960a9785b8894d7d5ff7387d4b16534141433b6e629c080b3815f2e50a19045e53e7599251286a260209aca05fa24deac6ff777ed22cbc7685e5c2822e20dd98ecd9e7c21b3c78751c272bc520ee2fc8d207c229b3608cb6a654d2624c49f33be369f1c6292459acd4079a11366ef3e87975b94d473e6d876e8eac10851ce3c92020ee020d90278aee8e3c6ea73755df79a78f34e0f58b0a49a0857ebd4745812ce72404f757a172c435aad882df9857b3193848557f69c7c47751620c812dddc098f34a78d43c9e879d8d589637800adf926ae672bfbf8abefb5ceec41e0e8dc00a3804f073864b58cc93a4fbd9984b95182192a686d9f207583acb9322bcfa4e064e35b328abe68af2bf7992765ee245158efa9393bd93ebc39a21b6708fa6c3a45aa2d87c83949ccd9920aa223266461595d889f451f68f25f5aacb43ba84c52515f121a7af11baf9d528bf5439d33d0d13c2bf0e56ba73c6a85c1458bf154d6defa1cfaa37b6a031e587d509960a629c7599a8592cbe8bdc893184706ef99403169afbb6b986f93168bee9fda5082ad6877c2fffab2fb9ee59d6a14fd5a78685c412d1a014c0a73f81a8012e6b6abd3991768fd3bac31f6387f1c2b095ee47b8a963b2dd1cbda3ac32ca6873bff8d10f462a0dc4ed6592b7e560f15c1e5ffa48c99784d9678bd2eb983b2365d0c86c8b4dc033c3706d3e1b624ec35c03240771d2ac7c66697d8eb506bf75777479d06c2d1794a5eaa26827b55e8aea40c696aac0dc04ab21fc832b05f64a3b8a450b8c75fa10cc2b888336aad8bc35b23dc1d6bc5042cd25bd4453308c2b28edef561aca92791d87666bde352ba61ddf21b7797882b53aa63d5d5745a7528dfd6e4370931f67c880d56014ea48ac4dd6a2bfefad439e1731c486f887969061402cb80b65a4424d11db47eb66fd4df330795aef29fcc29d489b1f7967b1d852c47a21e3a75f8cf38bccdbfaf106ed63eb75c6a08910c625a9a30f3949b7698ac59bb3b1a68741237fb1c0a827426517ca08799401ace60a7ba045bf190ed2c5597332df7af7f3dbcea4aa4821ceb884c2735036e36da5387461d35d06e7bb29f34925e040c2e9327a749727a191cd18a1f90fd46273a742a0aab873d84d10be53d6c2243d6b7c91f67e7876c10f496d1604af50660db6b134600a5b6d7bd2fa5615b330a67c5db70e335d0633309b92a20a00e3567cc82290b4965deaac3c0c3e724a3f663c29d94a4ac35ab1b1a87f1ae4467e87bd739f080a6c5b89fa7fce2b955cdce12f6817d7ae31b0f08c8dcf0fb94004bc64098e3aa57bbf936e35fe327221b8c30cf187aed011a2b292ee747a14f8319df54dd6d420d647d15f757414c66ad589e924341c37081eb52058e2174b35782a5db44d16a47396cf692acf98c7cd2db05411a3ee311ddca5dbb78c83ffd3c7c21236fcc9f55cc6db234a4c4f99418c125dd2f4630d8319d47929c3c8538b2fdda72fb62b34da4a84a18d4ac3a43efd0eccaf9e7ae352b604892da7c57de882ea4299a00b3bdb3044334de86797ade1abb43542c257162135ec1440b39f59913e9dd8e8e5ea26e3e045fa2b067e6eb75f0ec28b8988f83f96f4a0fe32d31e9719f47412b4c52dc82db875a734386b58cd921bedc7eb52c6df6958fb5d143d1b1db589de0160093dc995491423abe9ad71f339bdafe9e028d0f2a22910e49a6cadbdbbdce2f292d4a783592796733b620d4d80cedb2981751177f028b55c9d02321facab71ca81344f85220dc6ad63c9400e4a97c8d34bab804fee7a33904ee793b479ceee02aea11c9d169f6025502bedb5cf3aacd6235e2a7a51b6bfd75c922cc192619fd5db782e2ca1d12a44c481187e8e2cc2fedbc61a11b80cd69cb85ccba483fa642d458905870ed28341cc71fbddff1b059027fb1c031522d340e57ab6479bc337c0ef523cbce5703eeaf4a3b476561791f71e11e5011f0229309cfa624c80bc351c1edce23cbb0c29ee407eae56150cba9c2b85eda74455e0ea2948e871a59c8daaed04598b204539a580af6fbeaf9a8ff29a6239512852e72493e5c880f530180ee392b866de7d119eb418e8ae921da7e9e47a8cf6057ab35128ac9efc9eaa6aa8df0ee76842c78a1a6575b0dce3606102c4652e579bd866fc7187eaaebcbdc0f396393d627e203f51f0f1a6f07e0be97d62bbb7989bd88f53d899e9129501d98e52207aa622857ad79a5ec258c674e6960a130d35db58d6b8a0813b91c85226d1ebe84ba73e7bcff2c086cadb5435780e5d0cf53aeb5af63fc55480aafc72439ff020ffed4fa1bed7414633c23cdfa38418ef09b0977aa1b388fa60793c4b38e6a8dbd313b0457dff21401d728bd4547c5687255dd23002f98921484074c280b3fe60490737785273796d96741f97f3442145f2064252855dd27b2a6fad97e321c507960d502ebe13f0591e709c5d85f5e500a0d7265cdb622dc7cc5e9c6585b1d6dbfbd16ef367014e578609b258cd32c434b7f04c2e4153a4fc64d94c1823b5b572d074ff12610279e43deff01eed6a2a5c558f58ca845a375625bee8a0f76cdc7cc191522b78a83fb34839b7283e49a42d6bf51a4bf2f9ec667760d52bedc221c1c40577bb23d285417a6aeffd46aeae85fdb8b2024888ad362be42d02ab3e136962623bd9b12b4b706da98949fabc929cfa748adca76024f59b7a9074cf2b9e87bfacd39d4f5b0e2399c057859f3b7b281433bdee150dfe4aa7fa7bd05024d0699f7abed85af3c36b04d82efaa464dbdd701c5c903c1e3c4c69bfa2170c13cc79f61f385f1df7568d8dced0e86c42382632176d54552b80123f9a6556d61074e81dfe1a8b18e4403bc3dfd362637277fb4c75bae40d6b2d841c5b492230a4fdc21d6242426f61210b5b742849121690b1053ce7c745252b04ef0a166d50c44c43823393d49abe4b891e6d7c6a4d92b78ba570902403663b736562528a66c6e9d015ee279ca191dba139a46dc438ebbf01fae503d6dffaab8f143a73f10e6904fdc155a646c7d3cd6effdc5e2a9ebd30b6a150b9fddee990f791116707c444e4800bf04634c3b40403d65d982dde67726b3e9939950a8ce1c0ef02ab54a2e680df2f97a3fda8322c6f0d685ccdfffc62420283d4b4580ebc409195cceac5e553e1e0e09f59a377bb069a8cd8989e1c760d47649f26c74d10d4d96b95393e26a949761677c7f4e833d8c3b68453e75a1f364250330e10a8c86610fd9c5911a7e3b1c4947aeb52a15e9857597b955d4394836eec82632b442723969dcdc2ec454a8019692916d409a973bbf1012363c2bec5a79cfa8120d104d5d007a291a686772b4849eb8170c29df7fe551d7f129a1e2018658e5195b3820b54f18e2915ef39a7931cc388bb2bc8d914b2cdc78bcd682285411cefe867d20a4a52d0a7dbfb1eabb7fa37e79de4847fec6130a7fe270c9807dceb2865445321170423895d81d1fef681d0f247119a796b18e1125b3339025dbbdc586d8f25b16b9045359cbb9eda8eeff5ce6adb4aef8a4992d37189fc9b29395df1b199ee686d42b9cab514c07444590369b184406562a8b0fc10bbe9818d883790622dab528bf00d1b8e94276bcac6beafe2531d411ecc12adf36f78a71094abee92a4ec211f32e2e0ffe1f63e606439e2be3f116546bbbfb16968db433c775b74dec80e60147fc9f177163ee50a55bd366b619bd05ffd63f963159d4846984a5c18d572d4a70557890f124bea916c048ddf0224f928f207ee5b756c0709f6fc8f18597aecc060ee607c28c0c7213d97c8e1b004c86e9479a2c5af2c64dde9c6fc41aabba5ff6667d5348caba70af7687b7377c9daded909558011adda3a14f985c677370b5244dc92ad998f0e1b13dc1a941b4e17f9aa6d73e9f6ad14cfa3a58a9e7ee635a08851b8319104b78d9c340b02ab9eac2d529bccd4671d44ff0fe1c6b0bf37f3172cc4034525bdef76c1f3292eee68283380aef85745fd2f25477d067fcfe78c265e357ba33f1568a80687eeb8a8f9ef584746017d66156d5966012e0c2b03366fda8113fba7f8df44061feb95fe2e19967ae5b9a412b126fd353eea101311c7862409cd840b3f6c50afc8682318da32346cfe8b86741fed2f79cc191b5e562325c3312e98f41b61d8e4c4ff8d3db8c3e55dec7c1931d779a474fe566797944412e6a4d27898b7840c6484594e67d06c6730068a91ad588525e885d25109d3275f1c2d3e8514d5ca4d6176b14a955c2affd30413ebb93ff79ff6751f3fac268a40cb89cc93b3b723690ffa306557246b49ac2797119c5bc9b09021105ea935153bbc362a61a07d9a2caaddfcd4260d473fff59423575c5b12e97bcf60748d14f41eafe86976cc278e8c51aa899a112a7111da3e8e9f712895a2c9c38943dd68389eaaa51ae5cf3e0a642d5b3e2c06b503c30257a37572a41b99273a648b6b4862374d6604a32b74a85b450dc861f4a57ea4c4c254981b1845daa1ac8fc49e1f19bab53a96871d3b17347e7a99b50213472e875c25088e531eb723de3bb272610d389d8a2d954a9a193a1822faa5c80dd10a0a225149b2b9363f4d95c8a8981faef92af4d3c2c4ed70f4c93e65307bce287dbf93a06455fc1bb8afae96b2e457acc279b4cb5980c7700422088f3f9635ce25e2233827b81917f3819548a1a3ef1f15bd091921e398cd82e9b8cf0dc0cdc39dca3bb502c7cee509059a6712b2aca6c5c636511f38f8c407c0b1016a4e7a117f36e203e3415251e13ee382bbec3a08c9be9a51698dba153383f6c10f2892af596e0e5258bd280bb0d738b3bacfdf87fb00342f5ec40024bc666e97f15c5a0271e125dbf50f3e0cb78c52258b1da3f1a07de333baf4c7ceef5e2b2fae26af749c3469032b5509da491806eeb8b494582b432e4ce8941f5a41a31370777bd708d2174da816520f67656f5fa3008a2a9409bd06b13128dd4bb050cd827b7004d88c10c57b4af3ae4277824f497b4295a0f5030f74330f680aa34f30b2fca201697dbf5a85d44366ed13fe65de6ec5f84ead51d43f3cbb80efb1e70856ecb0bbf006c4d99152f5abdcc0c82bf3f147480ea0e9e9f4930e9e2cdd415fd39b6489a1c9a1cf0a1118461eff2a2228796ceb30f02cccbcf63e1a55b18c0cc6067074abb01a62bf1b0ecb3a16ce960a64bc17470e1881406653b275e3d32de206830206d04592c3e7ffe0ef5c11fc4e615db876662511e1fbb79256bbc6cc92b057af3d9d341b675605e538cb9980a8a5133a0fb2c417a3e149c16661964ed571e6202b1fc2de8a4a36ff56839060e0ebe5802f5f9a534a887a660b9d07557cc4a6bdb0d8798979b9e9ac5891e72b0bd4f48c471a8b882b5bd2d0d473c1c47f9fa4912ce6724f4defe65da12d2f2155888b0b3dafe95b842d7f69d8ade1103040971018889d6e881a1ffe36bb1210a590f3cde382cafd1250fbe487237a1750c245831489372b12f28d5e75b6cb8679e03aebfefbfe90a9282c4d18c918aac27e8eb3d9ae9934b323037dd524d301e4a0a1f8f0384987f4aa290c7651e1eb990a4203e274fb717076c851a0e04d53c43f84cade8c8225d07171a1af149f330fbea65a9b95d71479306ec22f0f9fcc15bc52dda6ab953ad9b51c00fbb049496deb7f60f20078d7303dc2c8b462355dd6941e11cda27ecdde726a856d39ca710f32b813d56ba122fd19b3a83c6371ff5d1fdd1dc3fc97d2649fbf2ca2ec4151b0cb9fb31bb7dbab0af9696e53761c13a47c5d2e1ac69427633cd4325526b51e702c6bece0044f4787d4df8688511d50a8570506866327212488624962210ff1ef51d713d867332ad2a57c542d7390f091a750888afba3030ded9bc8d5781bdd78ae83020a0d78ff95b721e2c4210be63c4e43ccebef9c47fcd67b310231fbda3eac96414a302494fc1751bf6ffcb31d1dda78bc6917e163f55b14e96d1138c91aa619bf0c24d16c25188170ae6fa6faabb602cb3e6bae72c18c14beb8a651e800f1d0d3fae210b6a1f467a01b318d38efb0889ba736811885b67a660e2f8255d55bca2ab5685c3e926e47a2264ac2992092474bab7affc4a0137bd6f42c433986f3bd6ebebe90e57cb086bc8f3c5c7c64c7ec57fc74d6d942b1e22e15e099007758348eb8cf7904c8f1c787685878f922e70fdf47ad48e4db23f6057ea826a0934110bbc3be7fb7de701ef36f1b499a884e3b16cf7e571c7d18474ad5f0d5d8eef65574ce8a0bf21ef4b043b8f65fedd0e2b19e3af6dd2d06577563ee9356e7f225a540a5f079e444c8511fe9a239de567d7414676b515b5f3a148a70c7c426a6324fef43ecf80d53496a0e109d01296e86ca2d2dc60bb9b886a3cc1b12312f3abc433620308c126f373bad3af15dc07a1f731d1a30031f6b8f30f8668e200476e5ccc5de3a288a81187383788ce74443146afd8ac1426f3bf48a01621f36c262c383d238117452dbc611a60d5ce85366c7cec7485a4c62ff0cbe2c403ae322e3b012adb77d5691b268dc36261d3024a58167c0241a2d4ad464112e8b890fa1d65715380f1b56a9cc10ca3acd4c2b090cdc2fbdcef51ac12b1893fea484ddd5d0229310168b86c4f4797caa667eb77cc81fe502abedb33a5f3c7b01f17aa056bf0249f3592215b50856d6a6c81a3c090d0f711ee870e95f5a99ed990fcbe3fe65e34e3f1a01bc3ca093ffaeb3071feb9c0cdf3fede17dfe8da6c5176006f3c1342483918e5013126444bc27970d72352c735acc3dea17829526cf116ba40546a8de231319901002d3a72b1841c064af9ea428133e006abed6956a1965619982f18fb98e372e063a2575fb9d80f16b94ef6aead98de46f89c359b01364f70cdfa3f31ac0bbfedf0d80f21823b67af0f111033cc380d1f1a0839592b87d7d8ffd8380e1c78dfe2578b60410434128160683fb6476c34d3b880edfcbf9dc3cfb17d1c5182b05fb1568c84cac0df054c78708e98f7b38914c30e5116ce603184659f5cefa8da8d92c6e1d2e5941388422361ae26b808d0f0c4743d9c8e8edc1ff6de0b32b19c81ccb258cd08237dc4020400c3ec9d22268263db13c5307452991038da9d2923bfa02c3a135b244af930e87325d913ccb4f5631a3d6cb90d9a45b42e8c13a674f2ab01e89cf7baa629edd1bc37e34cc084cb614b18f9b66d105be9aa29a60844866ca52d31311ef52549c9a12c38a4b413fa91e1a363aad8f026ca6429fccf17df9c320936a7313068cac1ccf85c82e5b8fdd0df39d6fcf824f9a26988489c43d0d6b15a928b6083edbc3113329b74fe93a40b4a84446c1f59a6da26937899570115465560545eacfec1bdbba8ba6375904baed37df651b7db8eda6baa8891d078fea4d3464e246cfc3249ed895c33b4530cbc5cd7a80ba2aaa18c6434ff6054d39e319e649873ba80a36d5a534a69acaa008a95af75fbef78bfe869e45a3394f83fd9e039b371c2f1f596c5b4e5b3f1d39414b268684c6c3a42a032c9125f21a0da6318cecf42704461b7887109e910336be1744f8cb927a30ff5514e0020955fe838a1b0411fb683caceb5d9b425d47e68c2201308c3b7899f8b8bf6e995793f6b9959de5408242139e2fc78d3f63c5930c864599ce72e22a8b5127e91b4944071094c7b3551beeadcd44ff17bdb0e11a26f33f027fa3a449e5347bf6df514abecd7dd05303bc004e3c561d689cf27e3be2330ae6e03e1496204836e9149b82c01aa876195af5922f16bdd55a4465b9fcb815b01327579501c046d234c7b0282c1b728099d0a8341ffbfe60f9a58ac8ed4211fd59a3280bf421869c957b8a516b1a5f18dc7d037519b1f88429fac26e17c468f47fc76934f81e70bacf91aae55f61bf2c485637267d68a894dedd927ebc1307b8c91863d0143ed3cb406851f7b598db29c0078dcb81db226421337f2d05ea38740ef3c19ddd2b40dcd918c43d8930ce11b966cdaf46f4320377ac5cf8fe8690694517829b3aa9e0a824d40f8c5425b56b20d60e81c0dc8421e18d19322739eecb8b642dfeaa88742ffc174b6c71d9959b21198ab836d50b0487189ae758d9fc11ee07644554ee62b4d889085d67232539ef160f4f61dad0411d4de9265d66541114c2e000962c177dd5e62ac89b9aab4e3e299bde016958357af087531ff5f7552b0d212e0ca7f099617e91134785544809fff9f5272034f490b9575839437d8b34aed5eefcd3a8ace599d8192b74026c5d477b72256a4d4b50a05f3bde494c27032b5df3c7af61647b0b08a549708b83653a12f1cd9ab2bebb6bb33a197699ab1106941c14044370ab88ef0270192b8520d26a32b2fb5be33a122a35b48677f14fde2ae07d6cc331b811a59de2d8d1995a0a331d428bd714b3c437782f579f464ec752efca8209030debae4e07b023b1c06b0c7a58fc0655dc2a6e90c1e0555b3f6b4c8e4bcce422cc0dccbd80ef560f4950ddd66d78b66e8d6c453784271e1f014b2f3f444764161e75d0b3bf37d940ce11525f95112bf098adbfe35e80244d6a8398c34b1e92e0f1c1e94127a938cfc9bc817347e07c3cc6a7a7f6d9c817e03b8ba044107a6a21fc04af6535366d90a5c11a6c0506acf4a855bd59df652eea4996ab96e66ade1485dd27c363961e2c64804e535ad33c4c089a01d788366b567b9550a442d7613fc2c59bb9db932e8afa7cb4e2e87949ef03631b2889589b2c5e80ca029a3b0071c3983c361e6f52e465e202b3eac55b1ea554344a6e84cf6e6095e26afaf87f4c128258e6d6f5d063b0c5f6f3304514bc9ace5c0c18f32ac486332a820d9ac039369883eeed7205303e826620f4d784c3d089bac468c0525069530c1444753d214861bd9ce8b85555a572aea51d5557fcce705784089ff338d90b6244de7e805ea6e44b7e9a027101bb803aa953ca4bb13d950b15d7306294da826a8bc83278fd6119c5a425c6a3c5fa93f7922ed4d07b6f30fdfce18092292d625161f92014c8db4dcc71c8e58f05922840d7b59de4d6379d777e678e1c466b87f7aff05584bf4a25a5063e63d9b506c8454a9a561f8987a952ac03a54b04de38a0a641ac3963aedd77b1faa370633a1ff35284c9bf0aea55b73129ac8edd780196681892ba2377a31cc5ce0d61b7054f234afd1cf33aea3806be81acdaf33309b9b5f38400f18aaafea9a52a9cc970d5382687624433e0551c08aacb01af267163b326ff00cb67053a4d30f6d1574b500591ba9bf823cb8f72ce2c88d897232dfe18722b574ba43364b171b6f287ca3826ecd76c30482bc2b7048080ec1b68534cb911c7510cf449079df6e4858a8089bd28cc9697711923d68829984fc2e5e52101e6f354e50b06e4762c2ad0bd1b5792a4842cff93840db2665e1bb92c03bb43e828722a9b311e59b11fc073f6d69c5dc11f985cb203c9648b42e478f997bfabaab116680249027eb920756b36deb34c085d33c7e05b807aa59130f0825b5089a5706bdcaaaa4752bc8d17e769c8a0e7a1310346c5cc7683e8339c6aaa1a26ba8fab0fa713ea7ec0416888e95c370b101787d13822ed7b65d4753e92ddbdcf668b6699c66b00ebeeca0b8ac3087c8f7ed0a1a544da75412f2590bcc11e7988297b4168d6475555096cf402f7b9ba32fc909b99eb6378a4a0b924ff82052008a13fc12c17785e33c4fdf0f0125e6e41dde25dba22d8f9328065fe1f59570aef4e4e3f4b4b7f9bf724c99c4f75968a8d1123dbecc02933805787220d613d42d0ad5b7bbedc3e246ee892f7f951fd94fa62a48eadda7ae675959226785b1972db0b7f10c5ac624740a00968c5f52015ebafeb2e5ed4fbdbdfe6b824e9ef79d6556193c0aae0116265f25ca7cd07418bb2af7f3ced59333a2a099cb94aa5a9f7b6b28a46b71d67bdd09061ed5270ce6485c5679da814125323e613d812012e8125df0afd1a59cdb4166508ddbebf646cad31a0c8b1827b49cfbaaf8d0029c63c0bd889a51acaac283f458325b5f8b6cfea7c2ef2ae0b77aa43a52cc9efe2dc0f9a36d2c5259b429a594908012cb771ea9d75b2679fa672b18859289633e66cdd33fadc45fa508eabb83e3f4b0608b32e81f33139d5beb949eae8f8c196895173c9063b102480b83526342c396a4166401ee3a49899b3dc14862cf11d1d06a75d9bb4ab421112af8d6ba9f057b67c9a185255bbdcd9b02f12ab9ed91ee59d85041e8a114a3b7c806ef2a8310cf9aac253159e22d4308da4d353bf81796dd3097f81c1a91b7f2960e8672025cdc9f94c20baa3442ced184c500048c8dd65ffa531d86188f4a5e3711a51fbe7929159b8adf36947e97a4de5fa06e638f89bf92e926c989919d7b550d04058f8c05b78bb4a13fd39e90226b002fa9c01adc9553826c54d139e925873989eecd2ef9c132cc21301be4e7e570940a08b1e530cd34687ab01c206afa612229072b0fad33787230a0d03a1fe67e309ce48094f38792f84341a0a4962a8720e2ff48a2bc8310ccf7827e2bfaf920fa9eb9c2d6e6b39a69fb9cbd1d19d274eeead808030eb73c00e86e7847923b3bb07508512fad8f6a0d174bc58f84f7f2fbf90b3ebc8f722ea0e930e05ba1eac1a5f072b04ac3e84bec9a2c94208153997390ae1dcd777f3eafbe3ccd209714221e420b5033a4b1d73aabeb01ac2777f3afae118bbc17a80c8bc95469b8e3d97558472cb38cc2ec48166f93e21f3898f3a9d9e95b77a8880b365eece7eb472a204b17b7488a0ecbc3035d40c0a57a0903d131fff6e537e75bfa2f75f0fb1b207f9ff9496610ff5931e3af2fafe7ebe44f12bf62e50bf44dbc3bc8fe1ca7257467df4a6cec38de047f48ef526c4e2bb111aa46ac0a8b07b0522c48686cbdb3af5b1fd7092513f0468a26c7f57f3e2e97fbab5786feaf54e8a4ea410b0a1a4abc39f3f8c065206dc2afdbae26626dcc0059e4abb07330e47eeeea02ccee7d5037724bdb6f9dc1e5b9e91fc3d59fe87fa57e4dcb452275be1fbd324a937c3db2e47f251f39afb03d98cd4573612b72a308381f9c9a52c6b45449afaf950077f6fe6b4be17c6490171ebae3f38ff08aa0eee9f236ee592b204b1745ec3c078c12855e0f055fa746085b17c71f19cf8e1665ff0c8e39efea9214b2dd60e1d299729d9c1595763fa05440c1b20da8ebf61cef23f833e089e29b2040fa613a00554b1ede3fed28ce1b59ba2836853dfecd268360f6baf468e1699e9077f5299553dee3f3b1a1d742e8604e3e6d71fdbe3fe1c90d24493364bafbc6bff9934de5f592334db528f86ddce7fc4e1fe302d3356b9c44559c3c405ef082879526a0100a953b931ec0feb6651a6541f487be180270abd4231bb323c6c4b4f9b402cbb87b45b110133f762c6b92762dbb7f87134453968bf6f9780094bc5b25301d5cabbde05d409c4cf85d254857bff861665879b939311afe4110490e4df6a157c01c0c8448a2d82f7dee4bf361c8b4bd30283077ce0db4935b0efd6cebf4e259316a48e00450fb75acdc255848286a5bb237462358c9792577bfb49181f2d1b37f8b329cf29898f0df8887d83c2f871417cdc4b117e92441c1357ff1f6918ad281619e3bcd7d1034ea277eab14b0a0312e9f6d16b86df5cddd72d1f32c529bcc073970e3bdcd831b4c6902840302c3bffd43b2c27974afe38bf98d15603da7522007672b810eca444da7507d9f317b798d9d101bee18f6f1e75b1cecaa467af449c67ecbdcf0b43a2ed6a4a1b90153e2c06165036fb6ff47530c782639655fd71ad6a2140c20f3d293b43fc05c08accdec017e261c803375c09699ba52e8ca0f6c32f300729b810bf8d8ac0716dcabb7a5b180b8fafb4e519148541c7797e07f8d30c839d4fbcd7c6a663b81dd5ab6edb93ed8ee03ac544e9cbea08f1cc26b88ac85f122d6807966073da97228c2248f1659c74ae0c9c5c02774beaf8ddfc412932314870c04945fb321eea8bb46a2742f2fc8f119f7c031b9ca2cecd3c8d6025def3b19e2a0b17dcce2c09acc1e985c66604b7dd5aae2d538fb4b99edf2bca62b42e9646e2c853c2eaec7e6dd5f0b6140eabdbc2dd754151e8261f11ed84aa22b944302b7bf9fd31aeeecf5c6d875cf36fed5767cf63ba9cd5b84158fbb6fdc54797a2e34d92c27f655d0888dcd331b8cab344bc5e572ad5e2e07f24475f933c60efb2c49750ebfb0b0731f4160e2f02bd7290b8ee5be507651c7eae33c35709973093a5f5b8bde91c928dcadbf50a97b41e5ac0f548c38c1c82a5299ee36812d224a521ec31cd307a85f74ad8a5973e4bde0424a456a5ba17e385b92bfa198db8def59134f086149ea4e54055b95d4dc9728d1380dfaea15b3aed2a2138b5162c818b41ce98b358b9e2f28f63524f1039c47bfcbe496c5330aab835754e6c26cf62939bc2205254d57668a838119d7ec1e9a2da82036815e2cc6f1636c1cd915011aed955e41a807b2c0c44782fd03af52647434f41a55603d459c7b757a52096dbd6e61bcbaea56cc9272941bd4f2a9e00a8ea103057d1a0524f5e12cb7db24f7a65d1a2477393924e13a02be668272562832d35971eddcef1c9a04e7c815856d5781a57bb7ee7b6021edddb47aaa6dfe6380998b9088ecf2755c650851cffd65751b107761e9c66fb13c20d69ea1c650cc7b89cb390b25c5c3a25e8db001a8beca6860aee3546cb03dc3978da2ffc36ff1def9fce3aec0f0c445a3c837540875cb429194648186d42387568b93ea06611c48f0d760d0578ace563ace9954efb12704414bdb8556fd0a54a06b973f8d34654b72ec5644e4c9e90b12ab3f42dcdc15d9b56d6f31fae19957a1131cdc51139d3c46b3a9dc4da3c15bd6182c73826ea2bc85bb8a9b3c70256c62ab00927973f30a4e04f67e1762728347f1b9c7329407e5f7a7c5dbe33800cc57123e0fe9e5f767c5b9638cd70aa3c0b3993aa73930dde9d38f6e88ccbf1b53404ac4b24d800a22917a0dc114206a1102a3e03943a3edaca5f5963f2c0b8d066ca9a8649082d749f319190998ed2a5ee49742a3041845412383221cb5a30525fdd5a36139a184a7b647e0a5cadf4fe1aa62fc90c95561b71a154cd23ba38a37138d8ba64ddc35e4f86fffdb23cb2d78f1035eb7a30db9bf53542d8115a31ae000013c2049a656745ea43d5352c7f4f71512b51843ace50a7d3c90491ee7775066d6a4a176ba1b14f7b8d2defb4fa6fa4d313a428513b2faddb897bff1523ae3e8edaf16173d8908901ad41255dd85056698ca8fee2099773887240f9ab762a550ade63420aac642db8ccd000498c62c18a4488f4865aa660a8c4d098052640a69b73e8ee092484c6709ba4fd8bdd2b767d8b95230d405bc90f74887414335db9e3c30e6778833f95641466b072b44fe77384f65c2083bbf97abcd3cdacea39f2cf4852e42848e059275d3d60deddb0d6613708b7dc40d374431f5665c19e7fbd70b58282de13043b477f373fdee7846bf7d4a9de1ca48bd9c2e58258c9e07bfd881a3182047e654dec27c3a302a6de926ec46a9a46e578649ed668593c1c682d8c62e69f4628be3f9d76bfc38bdfaecd9b60da95084fdbfdfc458f56a8dad3b0c47e920e28e2c94c13a9005454042d7618eed351028040a77c8967a176f53632e04fa6fd5b68c3a533657d0e8aea070696370d2cce073c271d249a4788b893324f850858f11af67e981a3b3b5a18497aff92c38b0c30ad212f3a3048a10cf54939606dd9dd5b4984c2fae8344cc471dd4aa1fb2c7e33026649d85d6b2356c306304968d187ff948aeaff5819d7e44eed7a7a4ad99fcc1fab6c0830270492a56a8f0e052acd95c7a39006f7c6bce75265e907028743d9f73e13745da33d9232237f74d62718addbb616550869dfb8810b85d16aa3962f16046d81ddaaccd75c913f1984b3e7ee0ecca206c1230a90606d70d90b863af3c7868df18e6814a83fbd3f9ce2ef5734eca70e316f6d8a6686ebae77b276d87403b598080aae200fa4bc5577a15409fe76bd4bcf825e6107902189b31a52d10d76663cfa1fc072ef1fbbb6dd07205d02076d74bcf5d3eaa2dc823630bbc48e7ef7bae57c9b9a9be71ce0ef4f818e1133a9cc3e9fe0887ac168b3f7f032b6cf817fa266bc362903351a08870902089bb9866aa3514a672c4c67647b2fcd1bcee91c982bdc2db7e27b9df2509ddada387a3fa87f4c0a6e9160d2584de4ba7f9811e26de9fda87df12f6f905034eed2e276a4fbc235f120c560a4f4e7497cf1d14aa5e57541bc6124b9fd6e9f71112d111bb310c7efa795cde848777bf982c25151c494d79d3d2d677c0e90ef921421ac0a559a5833e0b19ad87483178bb8fe6a7856874c602ed716ab98d467fd982ebca639237e64f5853a6889f9e027f5165ff83b90907467f65416237340d2b96d839eda917ac50830147e13c25f415afb5bc15a5fbe4e4ed341d7655e1d70c52b2d99fa448c9a64ad5e7b5e8c1cce6dc394a91a2f752daf45b25f482b0dee814f9291c4c326d75786980cb6ac684ef810a9ba153b1b4487d59aa9a02b90188f3519330747854c393360e6f8f3e307812f5803fc2b1b90d629202949a6fb6ff04d88dc587083989f4263c06beef709e16d9745e82cd03bb14ae74d5a0ab93ee99db40573ce69c80ff9cb04b18446b817ca28e86bb34d23a14646f514bd3732138af67d4559a534d95eca8349dc51aa1d348c8bf7225e5871d11694edd211b3d18b77220b3f6410160bfc2ffbb000885c203fe977047c764d146407a6172868e8c60161ff9e7b04942ac78731f2041635b0e8fecf37be54ca0e0dc2691d4158eeb06c7bc13bcc371054288d68cdc768f065637b0e97121fd3d6e9ab67922c7bdca61f0d0bdcdfaddd200602d0fa699e9dc5f521a97717fe7e6f023766aec8821d51c1c439613612332cd052bd6d976c1bdf1e11dc6cea223a6bb84fe4bed7487c60dced3be2129704584479ea17baae9a6ba31ce1e898b196636f0a182f36952c2c89cab691e4e8fb22b43da8fa7fe2eb09c0e05142ce5607be8ff2e337967c1b8feb433224b51aac19f0358bd22df9c4f4ab4499063411d6b72148a4395052de9177a04d29d20b3064225a7233a31a48858f2ac9ef1d18c1a6dd122f00e46b4b94bec604ea315b53aa8b9ce7270c4ba2493fbac91703a24946010402a579ef21b0520984740c755ad07a6ec691e438c205126adf89d769bfd21ef06080b9763826d7d76c5689baf63749b64d834e647fedda999d8d63c297fb7168db14111aabcea5ad77e029318f36d07aa69c54d0c67e23b1c40062f2c00ce5eb370b94d74b3505ea9cd1429318348253d7f82160cc7d24334fa1d08bdaff8e7e158bc09c9b7941e10f8c9cc90ba03d5d8776432d5e0c2173f4a9314ac649c4687521f70d08415718b4cdc2952807717d4f21a4fd27b46303de62c281a138f5dfda174947f872ef836b2bd379e5868039f3bf47b4a886ea962edb4e5059920fbddf408d2b188375f8b7203c2d4aca9fa7a996ec3b05e9c0078349a25ec4a07ea1835a54d9292ade33f8ffa52e5a7430bb0d7d8f47b97b65e4ae3915daf51f0fa0b3c0528b785902d2d75cc7d3331b61e84ab102e00458901199bf35480fceaa997de8b69cadf6eafd414b78dc7dd5b00181792cbbd5e09b4f476a0e0a7c3a87780012b44ba827620cbf1ef8dfe85fa84797a51a2099494d8a6c1d447e24f5f18141d02b477472592827c14dc5e6d47628c46373caee910987c807bd7ee148567b585ab4d974449ed33e1cf47f51c3abdc2cfbeaa5dc291a111e1fe27e1950fcad98669a4aae58dcbb5954d2d739b861f2cdb9fc8f1a91905117625c9707995d8a66081970419982bac52cc60798a100774ea6aea9845f2bd881a346fbbb1e600f3015958bb6f023724f97b309923bc602c5fe4324cae8bbd278b9a78537d2c829c7f18eae2ac09ed7a2550268df869c1eb873a11f4c8708313b65b47df63f570dd983e5a63e815c51274ec06d2c89707fd6e24e1a44c3f04e931ddb991f3b8eac9f84de2526cadaaf560341e5e6a2c92550c1d4b9f3209e91f36e48486c9e62afbdf7ce108841ce13e3bf2ce55e3f23d2f7d4daef5b5395dcdc8fef955fa38ba5cd323e4b16c11c65c1bdfedf31d6a99a6a2e9563510f160d3f517c6e6cb7756ea7124793542ac962741e4bf8f293029ac5d4107038000d520688628c220c6520858d9a4aeb9857339b6ceef2b8a33103d8425558bb316a64197c8c3c8b319174afaa9182ed8335b60f27433386fdb52ee66024ebca3313a566ec2353e85895b495af60fb385cc0233cd0dd0a9aa3308c60a6ee05ffac7e47170450b52c850a21a14308d8382134562b073cc5c4b20e271cd4303d650c20262036de0441e05c9fa715de2569c0e2a8f1b736e0eae1c71383e95ac6967e0c18c783adbd9a73c0be2cce6fc601b44202bae6f255cdd8afdf7ffc3c2fe9b997102e1fd0506fae4dc3b90c39073366fef59148b886537ef727a3edb19716bd9d46d351962070348fadbec203684c786e60a34bbcf8d403793979d2ff65985459aa11615a0f7cade3092fa7efd0fda359f761cc0393236073cc6a4952ccad0c1b26dc34404ad9e4011766e49985d3c1e7cf4435008ebc7455623e4fffbba3da2004cf564c67e02f3ce87280d1e9646adad44de10cfa4d1d44504531bcec036503af8bb9c8f81adf77d0e6df75f14caac56f04d5ead3f76db533777e508290c6aaf9cb6ee087e917fa22e19b786645caf142b67c38e6a30c9fc31bb355d2cbf1bf2e9fc4cd5a15b264e285b6c8f74f83fccf930671234e2ffd0e291f7dfd625c21544f384a6427fe3df26e08c03a67b051458260e5815559af3a6771494d999b3c666ac72028324cdd191a64a963d56eda3269a318dd9a791d2b8cfca3985b06bda4b40577c15843008ca3214731059bd481e5e604588e07edc6b8329f362e9a14409249e8fe5175826b846f81e785df8d92f6b0448eb977fbfc64470fdf056a9e229ef5f66e7766ee7e6358feff8dcd0528829fa249e178ee5b4985c8bef0e711f75265d7392b8577fe9954bd64faa70d3ce55a66e260779a279ff1c4e88d5f9c63a69ce4b555f24446fb5c40e35fcf8e339e0ba3bb083394069c786efbd239607aa9a00e04ac1277357cb04da1d3951fb9d85ca9da826e87c8cd9b71da8110638564d4a222051fe320bf6ed06828160a5328439b8c4b3bc6fae12e318fc94962b0e16839f224f8db2e04ca9b7b8dfb4976b85e8cc025c2283eb0d480949138c0d27910ad70960b748c4f8a0ab1a858d70980c3751086cc4f42acaef8d4f3127825a0bd350ac0c3a6f9332e96e262b42049e40c5a2a8bb0993a7a240264e05598cbc2b03491d996edae319c4dbe89ce6aede6cacbf8543540402bb61fa29ee481cb60448d19d41c1a70aaef01f51eae84702eb688046dc74a6035642cb4ef3ad6b828bfcd5ac500f1316ea79c075da134ab1f53794fea19e3f402710afaffdd3c2807b9cac984b61aedd6f21ec78cf787bdfa9bef1bf60fce8123bee121df08fc80a3b0058a19292e9bb1c1c8dae2d62fcb7bc0f750246496b4db3d76be25207bdfcfddb59ffc0c0fb05f64d7d8c3d912ec5bca39ea765800b738c95d3a29a59169c130ce496342ff30bb3ce313bd83cf3f0d63e5c8ac8cd0282d5ec83883875924270bf477729727b7195fea2c454f74e30a5315eb6632f2097a1a327faed917f756d7013c6720b9f2d543ab9f2ccc0b5859b668745492c64c14efc84eab7de440b58a28a529a7edac4f48f6e128b400ad299cdf114080a5489e7a86cd2c9c710cbe2e80be11f48ab885fc5dd605aaa7b57e8094c894a14c3ed50aab0f9fb55853271791be902d90c1d4d977e9f75fc7749c84696a7c7ae0acabf984ef781b63b30c91624a2bee9129ce96093abf50c85c6ec574079acf39f9f68c7359169a574ac3a0dc63015c7d300b0009de4cb9ca43570ae961e7f6a5a5efa5942e2132436144fa01f86ea07203da02e3e3baa4476d44f6195d8369a308793564ba1618f38b2febfcd0a6df70fa1d992e6b73960e2ccb20ec3a4baeb4779f7873aeb7077c758e451c17c69e2d425ca0c6a6685ca1ed58f0c2ec68acda10c0a12e0634c35d374799827a22da5c58bce1b108e3643cb1d944c8582b1d0cf0a33bf2385a77c61ea4d2116b71e277208528fe8554588394e90ddb739c11000afde10dc24aeae638606db5acf78842a3efd04c89d3240da5160a238fa65d21c761cd45013ad7a2a79e164e08934a36c9c71c888bb6bd9c1aaecd0f6014d9b92b8523006820d61bd8b340e0284ef6e6eb699ea0714f8dab91b905b10aa884220b0864908262ed46445aa3ddc1255259128364139f4350d1f8f3fd4aac1530230dd6781cc8bf9564976b45499a993407eea6208b40e7eade71ea67762adc854607277d0c92438106843b8807998e9dc2797dae672606f3ac44aa702a2120691de593ec4473143fb10ed15c45040401b8c044fd204782564eb0f692584036dc89273086849de118020d871e4ec8aa7c04e34b58e69476c810181f6f0cf22026a699801174d5dd9c112cb3d6efc15d33bb7bac5c71d50fff181e531a825a47a200744814d18f9fa491abd6b7e06e54208920970c21ad652c741d4467dd790a68f7854405da220ed354ea60149aced3b7237bfdb8d9f7b72cc49946505c932bfdcbb6c5508ef28797392da6e0f248bfd737bd862180faf8d0412c6c488d6e03c4c16d8658679daca56521d7f230163145e62b2e0bf52b2816894d55ac1d0e39d088681792a1fcce263e1c6a48138ce4092ca5c4cff58dc6139cb557c8f5ff3f23abf666c0364e1b576f97c5971e6684006265a01c9d74e37103a032bc13e2ee3217fc3de3c2c2f9ec8d84f9d46c2c684abc54b5a0b8599ea7fe90c3cbe5127897fab84dcb62e7bd1438f2b06f3f11791a574b7a88fff73ecfd810d24fcc54bd3985422f52fc2941e3f11e5ca0b05d83367d3e894fa8dd2cd3ccf8ce0f9f86c23d6c78e707ab004c3dedaeb14e5b8e291b6134e522ce0353a304e2a3fc22a5f08d59eac1b6d290ade75e1225a9ecaea54d06d1ff938d2f60c24be0a104f65a828b0f40a1c15f7fecb9b828bc9dc0f9dbe9d72dc2c5585801897a4c30510d5c56dca56e6b1dfa64b71587e48163f930fea6f451fda366070f0006abf0ef35cbb1b45103c777f8d9efaf1b3e1e0f91e5ce386c961a0ea23c290ab5afae5bb86e4f518013234317e13b9fb436a175b72218f1514051e257b4802c516cf6675c9bc4c0ea634403b47d762f5f411034c9a27ee7fcaaed0ea5aedd6f7abba011fbff5e4e1c4f992ecf3e707086d20b6eca98f3f5f10e188c61e5fad9ff2234ec2a834ae001610066620cc890505fa0731cb5f46b56349cc3d5650272788e21723e72f492e1ae09b1cb2ce0e4bce7c6c3ed164b6fa234ad8bf36894ab7a040bc0c61652ef1ce888b88bdb8590448eb724495faa63009bc9c11b395dd84c00e9193867cf5fff8b27075db4021c1be2731042bd8835e4d4a0552b64a85a9c57c463d4c3c640e564941265f6657bf5f7adf99fbd109746384bc21b8b4a0c0a558936ac639d05a7d421064686a7e3f1baba561ae42fb07dbcec046c46fcad918baacc44b5713cc136b7e8049865a686c7f044670b533c8ec36e3ca75583b4e20e00ba42408d3f2c67be4b41512b61ca358f54b7e60081710c3f418e57791c60e379b178542f4f03143f76b83d229f5602d78bf48d7a8d108e5047d4126b7a75219b0f67586872a59568449272ab2f7f50da98b7dfd2783b30c43665ad21b59252bbee7eb71a5cbe4425be493685701dcda3baf844961ef895fc603ebb130c9d5ca0f5a389c6607118c04233c41ca0a27e851226b85337fa19993293d5f6ab6eba0688d84ee15e5cc422e24103c920c4a3b5c8c3e106380f2a8328c84e846d71d9ff795a55ae6a1439efedd85eca853ed901cd338fbd2e64f0b99d0260355f0396f41434e2647320162f46925b48a68ca17bc4b77cec3a7472446499b8570c2d82a9fcea68503018831b762fb2197ce67b17fc8e9e5a1a714237dfcb5712a8cd5cac3486620521db69f1873a5f462347a838e3a66f6fbd1d448d51e57f057ba95dba1e4cc90f1c4e17f389fde60e42f7d5ec3a9045e3cdd935c990623748a84c4eb32a0549bc70373dd704ae0248c9163b6c7395cd07fb021de02e6102c9742ca7c82783a01010bdd1a13f9d985df8fd5274657df963ec1d0759a8a83ca8c8bd0da135d501b325d3576aaf59e8bd5bea45b6cc4d605369153c056c6b5ada95b250fd1c28e5b20335dc14c07b9746d64d60897524e017b201a89ad4fc79e0ca6ff6c35a95aab07fedc29a84cb1baac412664d8824dba63ac5bf59edad19ec7541db0db0385402ca592b38a4cf12613a24b3fed9c08095d87521b95940906496ca38fdcf723bb5644258ae19aebc052cbceef87f58ac0345910afa0a3f0ea2d32ce1ed4ec5e0ffee6f23856c1988a39595fad7ee9eedb022999dc1c6737b40879245127b1d6ea537f05a9f81742e88ee06cddfb979d4ea956e7b00021cfcc3dcc8128e4ab40825eb09de0dee67b15cd0d3396c145fb910b3b78d0d5788ab8c9ab7a8329e285cc57420f519c7fccc8f3893dc83982b2312e564eb82e110d425c84f9854158570e575f3ddbd608c56f6f17f6487c27da02b1d28f7c253c0f16fe8926c6ca0d462a2a7f0e4bdd60c0e5a0f434850cf901dbac5719fdabd1e635b8c70b6f7556e31926a4e6d6d2563e09502f46e7b4a0e9de6b2de312568102db6396e906a55d96fade184ddbd365c768d4f9e49b3f03d40530aa767b790b1485f812ea48d7c79381c093408c2a8313789f6a99d31acbb2de0d287de8c2f7913179482b850839f0a18aa948c137624347dab3f21dacfdf040a520b4794e926f4069fad9cfb69fc905db1d54b0cf476809625aed1a17a3317a071bf69ca596b1d09d5455bff31a1ed76b9a76255dcbbb0e78227cfe7dcdebf686598a5ea02d95cb9f119f892f674e8955eab069d780007d09b7f911158a14e77ea101fb322bb34285a2113479e98bfa5ef1e45e1d445c16c1f766f1dd6bbb6a75e99b794ef824ef3cbbc14455601c2bc675972dfd82d8072d4ce3a175c17e3572e3838866ac0add02f0fc8bf5d3aa6366db3130fe7e3240a13c8f83a398f847e7a889b2a2ac3ab43575524392a4a1a98e338f763f137e61e17697e55b1e6941c33469b9f42bdb4a58e32475e8820f2870f49b9be46743c601dd923c0c0166f204608e48a21c289e0a0c82784c4105de4acb807622928b8c845ec8ad470ba2a310e85c5a69adfad7199f19b95c11a6348d4d0bc22c0858aca5e967d694826802647cc7b61759122506a3050044c4f3679239c73a3fa1c1227c1b486562e0a210e5f0ecceebdeb7539c9bcdc6e1b764c57f0f1e416898e61770cf91bca7a7c2e470e273a1ff198f905c8497fa35428142b0b7f0d32b7fd76b6416d6dc4791e944e36cf2017a3a5e811075179b700ba323069c8dd50483fc9b940e843462b772873914abbb20b912baa3c2c769f5582752aa04df00cecfd117348281043bb2badd4d6738a6d6e1f5246216e3d36b2091db47f7895901d5f74209bfade052a29a741f434416f496da7fcc523e4dae4cc63c5c494c38bb892be262cc034d7b8af5ca2c03843dbc6ba4fb80cc0c763ea6d19b0e099cf6b5b1ee832c8beabeb702d6996c94a643bd31f5e2bf99e5ad694634266692bad9dbb8ca1f8c64a95cbe80d6bd0ff4302a619ea1f8afdae670dbb4dfb7aab6411d98cc36a27406ecfb473eb430ccacf7e25dba2ce5fedff4d15cfbbf301140fe564bba5f0782beff0384b32b587707d634d1fcfff48c30005740282a05b3b70ffe1f469807d55ff4b6a73253ca17fea517e9df72e0f081a59a3fd7fa1c531d3cbe0275e18de68c4d0c99d2173305a9becce8a12472b6748484b6283029d86208e4d014547e82e5a0fff0cf4bfb187dff98680bf1bbdd4012bf3f6a133de113b93a79110b027d72b4f660e4e9b97cb224a1542fffe9c58d93584b5ef0815efee3a2d0e721a40024abe06a5c4b1b8cb53d116f8b6ef7d9bb55a1499be1dba47e74c7098c51523b3ac698a295cbc7f0b67a4f0225547ee2fa8151fe04fa1cbe28252e76142c6d03dc3a4f1e3a1e026dacb4ce92eaa27f21565a09e94299b1c57fab03985ae31b48f10bb33db783a5e57faea561e3cd8a441769ca071e3ab6acc5140c05efab36e333c88ebf8421cd12337467d0506896a4130f5e77996df452bb2fb9c4dbfd5af228dabfa09cb1a996d28e0ab2f5d88b362d7bff37b1742165efb779c8f6c9c891fac07253c3c2872eab408dc79e988503b83428433562c5ec5f515f8d0bf12a5c4887ad18b7ce9be40e9680ed8717cfb27c1c4e29cd9cd5bece286e16592c38d09e7c94b891272dd8338cd04fe074b3750577c9330459145fcd20e7d2fd411e7ef6b99c8cdab3042f5c0e525a48ce4d79907141bdddb042099ca098524c696a7a62974c2f380ffa402759d2f3ab9b87f229d2945362c29eb9f9d028e5dfc324a53d49db106a83c230c979599afb2b4e892e1ff4415a075b99722991c0b531a5de7b1b1883294da647ae80484689362a68d8c93104ab6f259639ad22b36ac4be5dc3a49b342958b407e8a37af23d9dfae89fc5c4e25d26a4cbbbc978261eca70d042143b43b3c7c411330619edad92a18aeec462b87a6085b93b9fec5198de12e6045d2d466506b466aa050b8c9deefe9dc862af4d018bf26cbf03cec176016a23f46d97a9f9a465ccfffbc357ec63d35e847180e75c46e0d772299a7ca207431ab7242e5942023cdab05402b0ecb9e693e588299210be4553495169946fdb8c90356146c9101cd0f0cba6a4ac3d6850269e51b9646c2b2fc4ada93eec01134477792de2490b17a49f17084a46a9a5381f2ab8e3361b441d461e2e1e0b6b2aa89992794c5cd21ac059905ef6264a307bf9b1cd2745779c621eb2c3f0a929e9f9599e3038e6781827c9f74b5e864e3bfaa29163c8a184fb8736caa2fe02077f44cbfc657c3b68dc1e072eafd9cec9e38cbb1fd8d73e2fa1d4b5e97564cc200b7b95d70691a249a07c24799db6bf1c6cce2167247f567ebd02dc6188f0b5bf8c8d0bc11d9e1f4715187eafb2666c79e9a2587beb32f6c5a903fc07f3e5f5ccbfd4e242e22a6fccb3e19985fe52438350ba6075b6fcbed4e5439ecdb66c039ea9c33741bad7735d8e362572b8430ad506b5251506440b732c0c73bc186686fdeb9116c965c4e5e522038b3cda2f5a83466220fe49066683f3711a44995b0a75909a49227402247e2e6b4c427a3732c6c51b3eaa8c78b3c36d95af196ba22a9c6754a0d7f437b142eb5a750ad9b7cf7b4e09ec2ace7c299da01fe5a7b9cc2b2b16088107d4395cc657d0998f4c9e183dbb5e67be9c3e9c8dab72fc5435459888d69cac747766ed6cb682ada879b7005d0ef26d7384a0f61cb056d966acbeb7aa786d921a9e79106a8e0f4157ac708776d1285994d5902bc622422dce5976a1154d0dbaef81110997b21a93b84d07c7c7fa592f66d6f184bcf1f5f7b694d46bd5247a5be507068e1489cd4c875be7b6d0ba9354d0eb4a6bdd2b35d00c78e169d6ed2d8bbdbf86d2c69ea1498445ca4a9f8f922234a4b3319f49719936319692b46170884ea2f637616ea397b88103e1083d5a7dba14fa8348e61a972892b69944a4a5b78b8f6724078cff74cd8421998aaac0720d6436ab06e7c7dc0f9f90881a890285b38f6751168f53cedfc8d914a8d158438a56f909a662dea534d642692a7962c06946fd5ea149305cf125b5178b25b4d3c07ae026c2e25f6747adeb96e593d47dfe10964d082960d5a81a1353c52e93a92e64b350a41ef05b5a16fc446085249ae1a9c08422adf91882848dc23f655034e4a106796693c05ca26fb7c2651ba19f8372f6735251d83dd1a91745ac469738297ed21324b76a83ba6b3ddf3f89c644106ad4994592f7f1aa5c183ab96ad2f60bd7f002964d6be2cce299239a6b59870494e9a9f947deef561c28c6558abeb6fc111397e361f4261b89431cacf7d2b4f4864054fc67935705bc3c600166bcabd084b9b19ceece436142f84a1e6fdd3a5d9e114d9feca868ea4cbf8a7f3902e64d3d48eeb3afe933b03da9663925c13263c6293bbd9121ddba9b3ed085581068a10bceab5177639f456f2a388b76ce591600f5a24fac00d50cffbe14804bcaaa65fb724d21091b030cc2d410d551256c5d178a6c49cc70796a55266288cafac267e5b73bbff86f94a97475fea2c1b44bd01f49ccc17760958abad92a32636e4a23a9770a4a166aba6d8c0423d2b6d81d25508fcedb8e3acdd00b5409e02855ddaa260c4d6310b7d03c7a6096557077e61deab11b063760f07f0d56f707586c7dbe63ca3860955e85491f296a3d66a028ae3316ea29f45bd2799cc4a98f18bf374547e51a01691369613abfb2f8c835d525acc623f4bb83b415cde4bc9ac24721ed502d01ae2b301d7e39d879bcec3e818421be7908748762c835b3c17e327a4703f558933d1fd2bbd605b711f91043aedc88aafca742cb2863eff17b27ddffe90dc6a3fe398aa6308d438a4ae36f2c8f3d48fa7b63457eee74f337da99fc6c2ea93774ea0a7047c50c7937a42f8065c34783255d7835cfbc4014a8bfd2bdbc75f9b13b161c7804a93a59ab6518e1c4ff5de922f0ecb8a148b4afa79956d97d217d94ef4b85d51b6b805fc1f3bf69f9ffbc29fd70b7b1e7da6730d2e32c5caf21841c81deeb407ddbd2cb0245aa437855f2088e8d11147807dbd87f815215aecbd7702e6bb7c3044999079985044018afa8bedd9891c39a782034461826fea4c62005c20e804de197deaa3d532a246fb02acc2f0221626db71807050d956affcc22609018d1f2c2f4a0161187d87c0e84ee8647f475444b5551944acac4055f09427e0f2e5cbfe8ac8c144cdf31200491b26a2d1a4708f44ee297ad5a3a515c378cab8d83dcbeee5690cc34103660b46e7945c09a3d78ab9fb8084edcad1d1429b22604d9f876eac13c0241d6e0aef767b56ff3cb0b264964c2c008fbc0c5e34fba330d83696960f0280ee689c42813f34b33e6659e5a569939340decce39dccdb49c8960553367338acd141f9e2f63d3cb59625ac88924d18a2dd7c89596a71cc606a6bcac923c4e646332517f26444948890693893a16783818e3a760c3e382876c89b128cf62b013941a89c3e056c250fd26483aeaeb764a498706a5271b29b808789f8126255f5a71bc1a3f6d9c66c105ab5a44b09b629a77108eb54f7f08403cb7fc01028b5cb3c6b0ae0cbf258999f7162e198a211106c93c906d3241b68e23886396852c9dd838e6fff96827ac51c4aea6d3febfc6bf2c441d508f2a9ff0261b3161e152dba1c2a5e353eef1c9a94c59937a4a6d0b68249356559006cf05c2f022615a3357108b763adbb11142fd8048584eb3bcb122c9bac6978ad54a56756144c4da631311dc26a9a2a6396f0b083f824a3f27624a1a9c86fcab5baa7b14662069a08e98de30e180ff66da2ddde6699fb96fbc37f9a1333b5336f55274e6c8f038b3002ec9195d505f4861e07eeffd60f40cfeafc0186550b573a0a90f4050e12182f6e442f704ccdd6b159f003a54e1416a469a7cbfbf77514dd50c99d4b49f3047e009c7193e036270ffee0f7f89339ae26ce425b99bee3a35838c0d8b0b70955fe66897a326971b595b289cb58b167a03edb1f27017faf7e3cffedd55f9311b52445782161f689f3f852f2ecb6b0c3c3cf9fe06c11b6df9a88600f89b2b9d414a72d9116d66545a95d5c2346592ce580584c6d42c9761bceb764df7742f6325fbc45d3df794f806dc46c1fba29d94a72ed5a61277112fefe30758e5847a6b009533d9cfb71bea96439c97e4ca87b4656e088c239b6dc3e0b712eaf83152a847fe4c3879d2d4d38d3c18f4b8c3910706dfb66fa9464011ebee88f6e05c965122febe2fbcaa8cae416e20d4033a50db46fe5e5e307f316be95256b7eec9d90f4082aaa71fa436e7adf79f156a6a9103f2b9a10134d4f508c97af7af8ac71b2c63d413b1c51c3982422de244b9eea0fb242055dcdce964363ecb1a77ab3b74953b81519556108e2c78482cc51ad8c57d9a080d9f236f4569920f18e29b63446cd9d3b255216de1cfb516da96b825ddfcea983ebdccdcbb221060e8f24b4bb0f1626a4383fedf30428860be7b40af8005690a6b81e87e4e803b18166c9b398486066af254fb44928d0923af3d7a8a5e65228c386f0eb1605bbb6031c8fc8792621db2ba25ebd7b2e52fcb9894143aa0a82095b1bfb4a48725bd1f0a651f797a2e63407f933d9641ad898dfe4eabc3f9ffa16a202c3defc5c641d839ee055785ded33aee3334b26f89a1ba55619631ca80c45931f2d89b57b3adcd7a9f84b40327cff0e078bdc7a6e870050436b547f587526fb3e02d5962faaa2ede687743dcbf9d260d6db9228c2844c7c4d0e2b55188eb087d1419e3b0c006a996a6d2a2fda57fc520cfe182b26e9ddb10561738070fde879133ac64df0e3774f6013ff4747826dcbb20d01bd9556db488806d9d19d437339431ab15860fb45515ceca6b37e5d8a1c2cc33828f8b0000ad48d447e5c1e40389eb88354504eca21084c5aa3b0835b5630cc35351190911a8a714f8691e06f535356cecfa36d3b98ed745c9c7048d4b69de2c289da41ac5d009eb3243f914c14ade5547a8b9038fdd93b5483a3c78e0032503ac117c4ec982d2d75ca07cded913a1a10073155a503f89436e473d1004105a90c00088c4cc737d9cacd37182f619802b1d5220764e7d8d338c1b6d8903b8b459048102b9984e4eb05cbbab7f1d73aae1784c8b2a2351162cc2ef780636a740075d4372914296d8cc7d89a24af5d259295098c5f57cdbe5455394b6ed725b2b10c47649240bf968f64f0a8b240e89c4eded9133cab06bc0208fe68eebe8a1a9ebb16717755bf1a7be1a4e78548f4040461cf1dc518766c6d8b14d2f572adec29040ae9ae52673f9ca2876231ae1d5f3278da67bfe1b8d2a4f715c9212101cf76e0bb4206fe32ec3ee71dcdcd342ea0fdd8feff635c6bd3fb4c411b278217102ef49583103e803fb4b444d8e5e8f6d9823235d2d3516c288239624980780d1036249050ea844ac493549dcc4957bd7b848ec9d91973c711de4784f21fc072a753aa6055377ab1861fe6adc372404205538740b8dcae0064978f01de158a17307c89648559a4c2c74fc62b6452429dbb653cfac354d8c68cb00a8537d6bc1c0874933d7e09e4d0e58281e2ab7710f7e17aae15877954e9436cbe7d4a3631af0fb102414283e9fa9c376a7375df7a265ce24270036c8548cfd9b1ba5c5be651fbe1e51c2035766e951e9a46545ea6365fc17733fc96e7c760ed72b4b6c1836fdde62db0c70f52b5373ba00bf764df833943cb1bad91c2740eb2e26621d4d2774f96a4f7a2dc1a4b88798122068aedaaf5bcf8316f85f5620316d8877024da6b257f2b4d9e323b98f996c08ab1834656de6a7ddecb93d0539ce706088b349d8f76027321c84b9ad3b32d936adf93f71eea8915f4587a82c32ac033f6c2ad1c539d35468b20de1fb0d24d70a613606787c2fb0cae30ff8c27eab2612813c349a4842d25f237c31119a61adbf2cbbc849f4610260f08704eff4af9026c3d4b9e006c91ea0b871b9b97902f652f1b7681fe8097358981aa9d61e38cd9485b32053420f8a88ff814995d3a48c8c8c5b05d80dba0189960c1165190a881843439e0a74baaac4d9819ca405c81b4f6ca8b7427e860edc54981d2526639181420bc83879ec5b153bdf19c80b2f1b5318c8d38141abb13479445391a49c12835b811adf1e08a1c1d708d153df7e9f42520c6a4954b06bd7aaedf9c532556114aa9f623f704c905673bab5b626e262d305a4947ada152edc7b5a37735bf6e55bc150a12b71debef96832e6f5684109d564485fd46200b3667235359a4e6994c8649c36e490d7246606789cc273c06e9f166ec86b5124b134482804e3c4f0342025c0b93c9a6d9045101c116dca7c0ca542bad7fa8bb7810007e467cbac915127b8b688c2044bbd97389dc423421462b1bac00afc5c449406024e0f2151d0283ffea74a37873e129e791fe24a836d3df0d3c5d8f62508fd7acbca8ff3d3f599ad3946383cd5805886944fd05227831be96e2446de1eebb48f138550a45db0ae9aab2894254a22fac52060fb9d39f48f0e25d10e7212c1e33733991d2306723a19ff2bb3ee62820a94ccd2cb5dd882348c4972a413db09e25dfc54148b42c8b53963d164999e3d08c11df35d2a58c6dd0531a3e62260098806c7ea08d762db9010baf2e6a956df610c38ad07892d1e91bef56e0ff7ccbca91743efed47417da78a4b320f68041deae7d30090325090ca92f1680ddfb1fff7434e0f3d279e2067b0e2becfe76abfcf42ce1fe5736a828c5a7c7c34006d0a25fb50bd29d99f4b06586d6f9992d32394081681bc02258d5e7458dad92aab060a1911936b205f06021281116d62842cb7e79e695f9a368de4771721e9ec870a5ab58e8ed67145aa8f1973c5869e0e7298e3f7bc7491bd22b1aa287935c660c63a82cbe7b52a33662f306c02f8695cb2204b2c0acfba1e4b6f1769a16a2362c009a871f49e15a899d1b6dd473790386fd036dd24026880b2d4155d86bb7d3464c1022727e49511c07a721a86e684e80f8e30d7e4abd22b804d7ef28e4bfa3e70f512a27637f24cd88258e43a7deef01ca78a386086cc0ccea585367428df93cc4f05112b8242b3c1b62061b6c52552f80891924db9de3fea45365009731e9df2c0a97f7ea34540f976805eb060a0ee26ddee1a715b33ecc863771984a39e7ce43fbc2dfbcebfab129c8a900f426d89f9beaaa197f4b2f19aa8a3b213f1df2735d812a2b18bdb602d66db96627f6ebbe1de4f4311adedb5736547f7ad90eee02aa0bd51fecc41d4d0feb6088ffd55d7acadc736cb7308dea0c6353e695af3dea27b33918b15c8133110049c8c43a815eb084763c83165579f057fdd5ab3573167f1cd3480b4ee60cd02d1051a51b47d8457de4c06ead3ac6c6825bfa0be6df444f761cff51b736645543f69d3361e0334d64ff81d5774574066ec14c86dd062f4844b9798c94c4adb451d694d4a653b5ee8c3283ae5e8803cacdc777ab910288d33e3e86907eb85cd7769c49714fb30d423e59ab03179cde48e93b4246b410ee43f82e010f1a74978691e0de6645fe7c0309e79d65d73878291f45a090976d0e7ca4754e6c841421571b549b0b91a25a362e116325d9f9722b3fad53a2342c0bed918559badb4f6485dae51ed7258cd5f01c7785d5405b4dfe0fef022b6c1007491d08907954fef3f6892457946549e4bcda0cc2e683ee202740159fe51858f5ee5282b262fc68cb90425785030d00537bbf07bcadf446aef77442a247a3c174e955dcbcd55e72598da23825585475a53a7ad1cf638c320bf59a73aeb61cf62075a9043c3df0e66864ffe99ccbffdf9c3c08eba3fd4ce9f4eaf53892d3b9fe90964cba02c2b763a9111ce042ef90afa9be84f5d201d1c44a640edba11c0d44da8f98312090d795189f0badd1655571d60ef7a4056c5fb25eb87a8a586745d7138de373b49e8b2d2b0450cf526670c98d988b46a78e075acc47065dd7cba29a4537968204e4e86159a40e5f1109892bc9d950100d12cb26d7c25533022bc219915713240e760647944f0f5d582a8341b0b18594d0396d3e596aa0a462456fe44330be971ba56bcdb809b0bcf9dab8db200c8d1ec57798982d8aacc110c97738e68b8568c2dc05cdf6571436073d52220d5114c43e8d07525a827b51ef18446b826f9c98067e3a65a8b090c572da39977baa1519c98166385b5d62f6f0da47199c431fa96c567c102d77e2a8845e506edbf4cb5cae130e64fd9252a3cb01a9453fb70a15b39da576968d57e92632e395734c2eb0034f74358188087dddb38c9876a8ce45b843d9b295f68de3fb7e586536018dc958adc10d9da6fbb5fb3a3986d4bf4cc7c2231bdd39ef64c0ee9e0d263df6c55aba9c71c38c6804126420fd563636789bcd7654c846a3789ecec7eb0e52ae46506c7378e23dafde4bd248da88f01a80a8991976dc4a37b3c2827e6e581c1931ac65b78fa5d17f2ca4a0c7959a61cf73d20e2d8cc236e4a8d0d59587740b9b374d393361131165274e9be0cee1dd92112e3ea4273aa931fb331c31d58456be0d9843a4eb6fc678693fae8c754e222bd2d215d768e4a3da093838f3dccadfb97518f28c0e48d88b9ccef86ea0cca59b38a07ee18613edca6f32a20863441f9b6220608dbfff3796b39c968a2aa69ef20725675621a835879d0b077a1dbd105230074474b6739898a96e50c3a4930cb17c4c5f032ad00cb5496722f01fc071cdcfb28b5e286bc4d21b9e13d4e3a994ad0acc35e2c2ac43ef0574a3cce7825101c3140ee70a4d663642b0731b3c301d7bc90a332bf91bfc6e49b1f0613f17f789315ad4082d254f5c4b718596ab1931ee11b5c44ab0fddd95e390c37ea66c448ed4002d935c28874569ceb9b4c1fb05ce00c721fa0911dca676b06f4d05f41fd5cd1cf651e1362fe6fde357d7b6e3f33c10f7c746f81fd04c9f7a729657583babbe3a34e3607c33848b32aca679f241ba9b9258d9e24623073cbf1f5128bbb212944586a2cc5743319d832d816f3bcf5743831b8399d7b318d36a63fe767f68fcd53f946195be39d4107d6dd32dc63bca5602b763d703373c1d5e07c5c700c915b6ec8f331639253e87d3d66340b934c21ba383752c14f71665736a7e35c382bba307dff22c3863f4c22233c14dc1e36e5b1e9559b5b178bf5bb17b226010b46f846541aeeb0d6ec19f6fc0c35635007719aa6206c5d08e0efa5abb396554a7d42f68ae4c226e782be37d48570bc4008b2261f115e59f6322f386ef3fe396bdcd0da82b8c806d54db691b0d2693b4899a66cf1853f6d45ac2cd3b871807e8a29abf82dab0df31af51db42777757ab4874acdc13eb8d51dcc63df7ced6725e6e3c6909e7d7f7c0e2217350ee52a9eee1dad143b2b851b03352b3a1b30ca7d9f684e882888146db4c657a9a4e0364cbd3069c6534c32c59c1da34b924cc42419832c5a881029a6f6e0ef0973e533585e090167bc41c307214ac66fca79c125c3aa8750f22e38c29bd8d7cf08836543ecc5005f32b3f17a31083c13d5a5496df2cf303ea84bf79e1cfeb1b88d87b08df235712da8bdb8feaa32adb26e64d23ee7b62a6501b5ed4519c0969463160d980aa28b64acc256f8ed40de0eeeb6c28ff05a71d773438320c524df3d95f00a747b56cf0bf46e24b220cebed1ae1b4ddbb372ec3aedc050ab14221fb43a0628416a2ebaed1cd976bf2b19b481f564439a919f72e5e87660885e21400a3f11e1032952aa17e2b9d40dc9c09fe7ee4db62aa840ebd08c9456292fde94c059562effb44be2fc4d8ba8bf182c7b763ba587e2ad37a238d8b1112a09937921e02363f7aa2d658c257d7185650c4ed6ee648d9a705a6124bd1955dba35db7358474f049af1afce5c3aad9e97b7cb16b351bf952dfb02f66e4f1dce50495d96f36c19b80d178e50ba0aed2d429c99effe979ccf299beb9efa55dda13d4a281384dde48ce28f28618a83988109bb4991ea6224558f9caab8f400b33e87b3108a46a038a5dbe7b5b3090b29a0eaa4252c5ea577e0b8af765f9247ae8705baa5f2b9a325c1723f08e37fb45790a0fdb6c76a5a502ed32c41decf233f7e09733a510a5173db051bc09096a2fc0fe94f9ff752f9da1913a5c8b95d8f6de5bcabdb79449a6da074107220878fed01278fe10143c7f4886e70f2981e70f2581e70f2181e70f1d81e70fb180061c5a410d3864440b1c5ac2f3878ab8018788b0010ea900cfefa1274343e0f94342e0f94329c0f3879ce03914049e3f04840e38f4430e70c8074c82395295fe66c4472b0240fc246679f5e96eadd87d87ee5db592dba89f72612bc649b4582cf68250ffa6c57ddbc221dd7cc909c95e640755ae65f09802a6881595940b5f12d6054779aa97252998d597140b183631323f74b099f7af4dac2fab950aa545f68a2586e4309a22355f6e489494ac72b92dd996b2ff267358ebfdb728365f6e539eb8c89ecbcd4a763072b9c59c2c4da8eceeeeeeeeeeee5e6e4db2a771c586274c4a00050da172a365aff20211413c8102441942e506e583654022df7c75184ebef956587463f1cddf8cede4cd779e3f6fc6d2e65946b6799baf098b6c5a4f1316b56a9ee49a67854535b50615cb343f1316d1b0625821b35e262c627979e663c2a219992342ac68b0ca30af0a8b605e9aa864c64e493464fca9b008b7aceee4d4f7161ecbe17f6151f802bf8230e490c117a2c09f53f68c74e15dbbc5766f7b0b8b3a0264aec8934d087b916bb549f966b2d6c016e3d9fd7676a0c60c26fb632045b248e248962246bee842c806239880325322c909d808eeee5e9b64770288eceeee555c9632a59f0a8b680768b890e446f60fed6ab5467677770779e4d261368b4c5b38823bd83203ef85e4c52afbdf1c38386193fdedcb0521ba0fa27022a2c4bd8e6c36088974444f54f6af2f22382c24510509e7b001cc2e85130b3b647fc75544b04276ffe9025c82ee34448c996a62f3e9aa63a96f3b6a47477225ec31baf57f1c087403ae5a1cf6ea71b206f7a9b5521f72a54b5ed005d6110503dd804b8f713edd73e2f42dfe437d30edc41feaaa5448915c2992bf3e96ac1c18e01c2d3faf288ffd641d47e0f2155aeaaa4c7418816355b0cd2b4ca120175d00a894d6e72104973ff927670bec508ec561650f45e230989039a477b0d04051950a71b22279ccc95a7f0712f658ae98fa46f3b890d9b7f63b7cc5641b73215adca77d4281b25bb29d5c643ba9643ba3564edacf7e2bd50b4ccc5b9b12a7cc49bbca89c2dd8a07510c78e665befcf97922dba722bb225b2e660968212133635399fffc84d47fff55b02be713332c1a99c8fc27f692fda50749ef75f13775793a63cd633f070cbc9a4bf5ed4ffbc174d9b7367ceb5b5ec4a925db57893122b9125f1f4c9f29a32efb9f1a4b1bb9fcf9702c6572f993ed5876133132b96cda6a9c4b368ca6b5efd6aeb2b5bf02fd43e2f3a00a0e79e87198933b2f9e0e1aa8683690d39ab3454fa6f4edd6f5c0d0bd97d13edd2ea5ee5fb993c9dd53bac47d5cbefb239448eeb66eeb7ab8abfb2a1239d9d1faeee348aff6f1d8b70fd9d5ae76b5a3a243891ee56447e464e7501d18e68679d5cfa8cec505ff6a4c41f558351acd1460c6fa2d54bbf7fa5ec461ad03b817a13e4ec374753fbfc4ac27bf2f5f4ec374f9d4587e80ff1b4b98ea3d4ffa3b963a762c1d08d61c4be7c16f782175542f1d18367d5cc6a61f18391475d19cc46660bfe264f73eba15277720e18ef55db3ab793ab279bad7a1049e482ece15aad00f7575a9fc51108fdde841152ce6987c42cda54331d161047ee5ee3d0969e662b4421545970b0000e8d2a10690cb8934bb59d72f2fb9bd2cc674751e46f3743f8976c0653345f9e89c5ce4eebf13eea360f30928e0fcbd675425d03e9448bbbaef1c2a8c24b9fbb2cbc821775fba326d22fa18cdd3bd277a18dd41d73cdd5bd1b12075dd7b47c7d222e574ef48de951cb67df7aec461dc774f44bfdb68d6553bcca12578132184ded199761499fec4d1409d69ad4f1fc60df4caf3590d6493e71c1b488c0523604246d309ae9841682e59ba42240acb0a4f08cdc7acd9c3d738553099e9ac73dbe607465c018413502069718450b9fd1c379bb7edad93751babfdea64b5df65fb954a93f7bb610c88b5a0c9bfff75b97359c3037079bebd5e1f742982eaab7a001132277b62ec809998cb7e2281fa00a05df5eb0072fdfab58aafe6a9cfe46497b87dd25437de1518f16834490668449d118311311684912268708517226812a4c80d4e7a70e28b33ba980cb8a05d39438d212ecd93272ff84205265628091245053598c105272e1023094a653979e28a92d80c4eb129351808a144d3172d908184075a20860e4d784105ea8a1608344f8fe57e177b9ac703a17e921349a0ae3c5d4dbf7ffc2051f871f4c3c5110bb2ecd98c72d27f841fbd861a42dcd83292d1f7c1894d5d465132fd1128208bc5e61cc96ddb7ce6084ac8c08f223c846c32227209e650c91a5de4b2a1d6a881762d86f480229060654f21725849b66c069dfc5e90e9cc07058c489873be016a9eabd52ad355f3d0a11260b2813c840e3b6c4015e2e81634f7f6dcfcced6493ba311e60ff1c620eaf29fa71790562b01e07f3f82f7428680e3106f7c2039c8ab4882930e8197182d03fe47d4a7ca9a2825e1050e680421e4ef83029ebb06f86573473939bf85f3ca4926704e0daab4300228469821435311c31a4a673cb1c4062284fc9f9c019ee1092078a67f009ae918824cc716081c2b07f914f873f92fead3811a382184ac852359ae10f2ffa13e6515494ab0021690c1c48290ff934c95e926392122298c2d986a0c0e4b4f4da64cd103940861a080053cec00c30a82e0615a34700c4954930c709835412181866d52630951100f1e79664186098ce8a18b23505a3a0da8309aa0a2440db122b1269b139a195b641ddf9c232b8f40f29855f9a3e0146da9ca319995bfcedd1d34a2c9377ff6b6eaf781610acc3dae5c429b15c6aceec653ecf95ec0298e3e9c0402034ef105c4cb5f8ccc656170a6f57292e5ee18648153dcf2cd1fcdaa1bb435568c9aa7fdddfdc7dd7da715429de2a474ced9da56a0b501a758f37763e3c68353b4f913c1ee1e4f98b96c196ddb785d9c2c0ce200a73b687373bee50f27e7841608732ca7bb4f20d56d52f07dedb00a64e027f768c24f591a3575752d1ecdd351da51fbad103ccf257243c92d1072724bc914c8f72df765fdd252eaee2e962b13ca2f7bdd4a70b2fd6d075ab10c33fdcf82562c53997e3796e064bb58aa72f9956583e0b99be725cfdc7a39d9ff9265f207826158d4efe21782294fd1b8c8e051555f300c06bdec63d9327a61ebcd92f34947d50be86285d9ca983295c36fe5cd549b1566d1d4b46c6c748f935b8dfb70726c1eb105ba583a0f4abd0c72d20674b1fcf28d0d1b3736789688c70d70c07ba3f5b2b1010b6f00de27df364d85e28803272787b795fadee43aa43f8e10842dfbe8eefe4341ea2fa7fe41dead15982357ba71b98e386a707472563a600e1d97dd70c21c502707e862e91de7a2aba4ce7217cbf69d9bdd05ba58daeeeeee7691c9dbe0455d6d630316de00bc1c34c77de546eacde56f87076492952d2392bada3790b6b65a6bc5b5565b75802e9637f7ab3960f2f580e7977d4567fedf682672bf0727003a019e5f420ea560a58da37637eb053a3902edf02dce3962ec82ed77a005637e78dd00d2c1c6bd81c1a2da7cdd02bb26ec544929a5607777e3190c56589551815d7b5e46e801d3536bada493fd4047643830abf709349ba7bec4a8642a9e014117568a26ac0169cf5a46cdd3bfb3f359f0b3a19452eaddf4b571a37b44c133fd0a34ed2a2776edeeee3a7180313fcc174ef70b2fc14ef68ca182a98031542a2d73a60e08a4030c16d8877b5b45bca436a534070868747777b7c7715ccda736bba37b6bb7766bb7766bb7766b5cf75ce78ddd24876a6b5d2289b9fdfcbc5e24f9cf6241c9dcf675b35cad1f14810f60bf4eb9d5aba38a7ae2a49562c0a94fda511e70f0e7d9aaaaefd53d17b97775cee9962484141676ff5971ad3e9bb0deddd971216ffbbb6d429d6fb31201a4a4a661a386b33f67e06d2c6fc39b77473b76638562a6b31eadee74bb72b94f8a94d9e7711bc618731c3713b976d2596f9322e5de7b697d5abdb19b67a374dbea9685d3dfe89c20e4e9d57fab0ec58baab35cedecb6d5cac267aff729d9b6a7f5a9ddb6a7d4dbe826436aa3d7abd7ab1bb5d63ffb7dd6bb95dada756e5487ad4e207708e854ebd8ed727b44adfb34e2dd1686d0617ad20fea1e826ee36ab76d4f9de56a67b76db39d0e36be0d21450a2b0a28a1f781a192dbe4fdfb5cf79cb5cd739feb9eb3e0d8edbad772ddd83ad424ce90819618985146140cc8c87293e9a436d8e4faa36219438c30a0c078c11757bce8820bda165a6461058b2a573c59e102a7a62aa8c8b149f151ba798edc5f02054cf0b9cf711c3795e84ca24de7fc9a4f8debbce9dc91b5355bb3355bb3355bb335aef3e81d7b0239fa21c45dfe3e904bbe062678fe9d36c9a4e57f3ab9cb8d4557517614b97fc8c743c9dc2f91442f311b4a0fee7f7e5e2f92fc6f287903a2440ea1a174637fb014e441ded5e0e5dcef67896304b2abda55df132bf55c1dec9a01cf8283c1cc910d4459aae679b940b6b35df741f15a7b3d6cb2be0a03d929d83c35cc7503d91f446173ea82313f81eb01bc5cc79262d66c57159b64f25ce7c972ece464d64d4cf6b1d4c5d32e7f0160024899b2b3e3977eb75d1bcd0454d61e25dda096ba8072a8d9f856a62bd049206a9ea69fb55ad92fec65813bdecfb69745bd6b9fcc54999f9ea6d59d4611e5b46ecf8d40828f127a886004bee41d01c81ce47e6f1c63b8fd0682e208eea25febeb357b19d1bb6ddcbdd3db9ae4fe7620d7ba651034c9558c6d0c5fe3943d5be506af47d634c904e9853e1f3c41b1c75dde792c77cde4fbc4d7eb002da3ce62b9edbaadc9ed6f0732ad5bde40c015cda2c0e46ecef1368fc781ec3fbbdb81ec3febd156e7ec4585efb51ee52e41443da8cf7dcafac1de68bbb0c96da3150c3770c7daae0d44c1d22029ef0b399224bd4f1664adb5e597719a1606e622016dd483fa58a05dfe32c8fe690c2992c1c8fe73a3940c9a3b8848b2659f47e477cbed30da8392d3c98c42067a509f230b7407fe4818681eff7283ec5feb684205812de30562100441d067dfb78db55db5fa4f4b1d04de7dbb5aa58002f1354ef9aa3638e00cf2d55aa9ff7413aecb5a1985f2754fab7d97dc329fe6be77b0c0570f87811f7e8b53088bb35ddfbb881f06f2cd419efa2ee84d7acf7d205baea7a7c071368ff741ee3504d9feece6f15ca81d86f3e44d77e0f8868d8d6f75ac21535c59b3093fe2739dcd1fbc14c04dce5ee048e6709bb461b61be8ee686d37e08690b593db2a4ea6a4113d34c3f387a6c0f3875a80e70f4981e70f4dc1f387a2c0f387a0c0f3879ec0f38798f0901378dee4181af0fcd2dae40a822d04879a48814352f0fc1e8a32c444b895867705dfd0c034b00c1441e09adc4e4a4e3c1abec9eda42443c7046ed5ae171843793660d0ca2706fea8804b304c126012ec12c456034c93db69043478418c20086704cf88b1048ec9ed448313b705ab723bd110e5882737d0d0031534d8e05981716e271a8c84487885868de1d5175f0df8a58ad410527030e02fb7d30c4b78483097db698623be1ff0cded34c3105c92d30c4c52547097db690625332845d1d0011630eccc9ae87822060e9e623c4358f0c2062e98ed0cd12189cb098a8321478e9056903618b2c20b39664fae9a0b3a513421c7309263c52c47162fe048e144a789080ea89c265e18a758c21152040c22145138840481f4583c8d4292d070e38a9828c448111b5524fd1a2fdc50e1e48619466c5a40b3e1050c2d2a68375320a9b12266d304119a2a492dfb3aa20596d0ac5683822333425696684a902423f4e48495e4428c6cc6be5618e2c2ca620be2b72fa3829623305030c5a8f0050c2f546a2b159c9254539ac0a8808412867a41410c2e425494a89c5438428254124e0349286445139718b4000a45f1947ad930be29b5708b16bc2a33900a23f70aa6cf09176c93cc1b02493745edea70841372419255da849c963aa7202fb45085aae060a0422d40dacc30e2424d49755a2e8eccd7cfabe7e71b85a6c49cb05082b298e5844496cb1fd2a25b810c303e1a7679ea94c05e0b5c82c01f132927fc2dd5e0e493818c262919c8c0819b01192e5c2a98c68c6b02bcd2225c826972376591729bc80244d8248b1232b220b92bc03764909ae1192d72c03245162c475831b004a1022c25b837609b35ac0a51e11718e76e1a83e642049ec9dd34c613360b96c9dd34c610e11a4d63a080066324c1618c1674c0ab333e22f825779318579ef0c5225504b6b99ba06cb056845e604f8a4f0d5c9fb846e02e7793184be4f92a884144126238610092258ebba28d8b2c5b5b862cd93319d9db8a900386c935b7930c61c896d04a6d10ce0682413ff565e605f18842b7ad8166cd8bf74d7f9bc2d4646568db6c1cc6fdf6f7e28beb8afb5408bad414ceca612b12a0407fbdfe6bc696f83737c0c7d43567b3d72b88fa04fd7c01431c12fc6c5a3538687072e80d4a7b56302faa95e7e5d4afd5e3ea7f386151fd1a4492ab6e7b9cb0888a9bd8712e980d5e36eebf9cb088c3c16daa1dac13166d391b8f8b8e5407a108ee2382bbe603c0033000b6470030f07bb1ba6bfee0e0ac06000281ff2c16c673c78bc5c2b873683864cc9f93ce0c8398b05b51b0135f2fda53b9302cb2139c769238aa1edc64edc001b01ce0c8e1f7d7ce696584cea6669e1f8a443e6ead461c64daf70226d520c5767e7082ec960a8bb6d94343d546e204d17ce4c55e2a2803f66c16c68c8bd91546548c1aa87b969426800072df202dc9b363040328223d239df879edec34cf3c6a1e6f97bfd28d2344820891814b6b9b6713eb0e0e8c4c042727d38a2607d49c611ae98ee2387ba7d21c2dcd47731ac973ce90679e2f44444b14515491676391e750bbe6e779fe3c025378f4a0db29d396227ff409d02cbaf3eaf97198eae9f380791155e28f9395922e63381ed5971293c229d7e7d13cddaf3a9aaeab424430f9127b9cacff52c27f364d1d870dbb5511e6c7950823be5eecd76f262cda289d62bda1f66fec0df0866863fc70d8e0581077ffb5c2a20ec7cca9d1a1e930b5098bb69933b7d9e578915fc5495747aaa6115d989c69d5d0b05a3335359b673e0720ccce8b6a070777c0627daf1400c01a59abb1ec572705c15aad663d00bf00f408c082b8fb0d7aba9eaeceef07dcc1b1591db9cbbfd20f15e0422fe38bba66187313c6dce4601cc6dce480df0eafcd03a4f997669279d188246b46948911615e264e920dd28c1d557ab4e5c791078e669049e4c88b031d0b04fb028818cbd6aa650302cd37bb5e90db297fb49ff2c7b568f200f267afd7c271b25fcc39f903c31e275fa9f1c503abc0d50bcc5cc5c8cc80536c89f0446e2986e6f8d1d4b4c0297a966c26327f2f8253c4c9df08c427e702500c362ba0233838beaab4e2a0601de9466ba5b5d6e764f43b8ed61b5ddb803982d2178973bdae359526acac549d71e9c191a11b4e8c8aae5e606056aa182cd32e339436ad2c4a296d1ad24a2bad3bb5565ac159c2d7b2d9b3b937b45a1bdddd68ee3771a78e7f83e268c7a1b4299d399492b5da5a5b27958031bee9b4e674d652f7d56ca0a64da738fff6bbe77ebeccc1d0c141ebc67d4d63cd30d3ffffb0261743a4e33ace6e3eaa8fffa7f9a0d1683e683e7cd0a2462cd2ba4dfbfd2f56dbe94dcfe2ccddecad5ba059cceaa719e9894173b33308cb8264b2209705053dad22e1b4de207b1674b9778fd62c3664b43fdb716fbbffe9399e43d4507bb18a66fedcfce908046b66a6a3a3d3f3b303dacfbb9f772d13107477a7b356127455c7b998a0e6ba9e1f1e2e21f87d3896161cbfb199b8fccbc54e3bd66692fa18a694d8c3715beded455faf067abd5ea06f493a3a2b9b1756ab5509607474745e68ddb63aa5d0d1c154d8d56a75432a9cf6a3f0c83d7965f34a7a8d1ca63e4618e399d1347298d1cc6849a77eac1d01e020ffc6c2b6ebb3acb4ac7d82e8b5ddbcb6736e7ef9b49ff6db8ea3b6e3eae6d606511f1f9d4ce64d3e68d407adf3179edd5a738e2e2e2e0db48da9e649a51ac8da5aebd4a2b3266cb4d2950d4e0f8f9d8edb3a6eebb8ad3a35810ea5d4a6e3b63ac3988d848e4e63ccfad7bfcf73bf8df561ed67e810918028099112d1088868209a810809910c44317836b575724c129e2d90e8089e4f94440403d10b4446888a10b940d402119118958c0c488434e3c222628148044443888410ad70736d10a940148428b6861a69e0f99ee35b6af0e9a4409073e29b738e26b0b0040e1002cfaf3e7b9ca43f73d511045b6ac4082effe5bfe93349cf49148410283259cb9ac67bd8f7f51d8daeb52ac88f1c06f3fd189c2912732159fcc0b0c8eba8a329640a99432e8c90a5ed67c65f4e2521b34641a807c7cf83805f5321f82bf0eb7f74a9824f5b6c31d100c7590bbf9c35f06798fa6fce702ed9b9a4b24166befedc32f332331ff31e6b1e3329d027d39c02694e7134d198b5599b9991e1aeebba9914185e1046462c7d48ae1f2396ce42aebf124b5f21d7b74c79ce2798b134e1eb67c061def9f84ee238f932f600027f42a84cd640afae7ecc0a92273d39c9e43c8ae0d265b3367b6a7258d951e5648af2048629bf22d750070e787baf5d2dee41c7d29636e3d1659c11bd097589e258ba5ca3ac26abb98cba6a0f0d58596dd61c56e9af9cac329f3dc998be99c365b5e2b1bb2908f0b21dc9280ebb51e4fafe44efb02339f31ec567449fe2aecac40e87d21ec5c92af3a08accbbd7135dde5879883f4eb25e4ec238cd07f6f7cadf3b540389f97bc7e2510ed3f2ddff9e2ad11aa84ff7df57f1fb7e467db0023cb54c2c6378632b04efe9d3f71e48feb6ffdeafd098c36c9cfcbaffbc1695bfefbff7a8efbdf6bdd3be77a8efbfd93b90705f71f2fbde47a739f93d4f9689c561dc7fb583fc9b58f22782fcd1a8eba39f1527bfa7a33739f97dacefbbc95d830a923d9b95c358340e886d7a11879dd03d0a36cfd953038db9fa15878ad16b6d9393f589678cd90928e08f0602dd801b3f5939c3c83d9fe28d1ec5a320a0d5b9babbbb15cd53df8aeed41dd4ef446f6a9efa5cfdad3e28fa13f5999395e6649d57a69559aecf33062ec13a5381cceb4f9931f9d184f2fa4c4d0ec34f0e5bb19866488a50212bbcc234ae3b2ad7ccb2e23e2c9f57585a688e16d694da3516d30a33d1ca95334d1ad3a4314d1ad3a4f9a431b19c7625678b5a57933669f3ca849a5f4c3066ee470e2b31d3bc32a1684c9becc26032e53b9b5d1cf93e8d4299e814db549b3450fd9bfaaa64e5e4fd29e21a7d6225e19edd28cbb2f4aeb047f1282ea53d0ad109b03fb5d68e7409146d77ed73bab46444f3dcf0535fb2a6db20607b9812fccdd000a093f74f00bdff2a48a91b4003738deec31fc27deaca4c50a447cc9ae7be8bf4895a71f27e4aa432ba4491e80eee7b2255a279ae339d00fb148f328647994ee813eac32adffb351e255f2df25da2aefbf4ce9893f7ef7d9e2cf8de5f39cc820ea34ec025381d2ee012c43387952b6f72b7e25732e75832f72e82d8490e2a735d646e4be698969ce4388e7b9e2c983ec9dcaf30957131cbf5bf197d6a209c5c9f6e7158cc6157348b8b5cc3c8b58c171ab9bebb96cf4515e0d2b16cd972d3b8efbe8548070cf333bf7c39953cd62debacec6dd7ede080cd56f5f82bcb912845e264b54e8a28c289c58f45fb3354fd3741957d8c9f2651b7f5572e44621ce6f235e653311fbe23358f98af2aaac48732695733d1a2845697d263d925e61b4a0c8c08da9ed33dd35903d15cdff3684d2929511a23562cae4a96cbe8464a8721bb0bb96e4ab29092e6923ac9558bd77cdbeae4c083b40b0c52019753a93e110f7856e9ac005960ee91c025a874c2ec70f354fa34a3aefa5cccc92a6474d0b7e46ac3d159a6d5a750f5e98c3e711e54c11be47e96ff38c9cd544e4c1d32e0d297965ce698e51bd00ddb2f51b11951dac4c98dfa30d2254e6ecfb3fdf6255d92b73aa753e1418038f0e5db3beac8019bfdfb73f1a00ad6c9fd53d4c91d8660eb34f26dff05a95081646bfd7d6cf5e8a662f9a58ffb1d72dd571148e6ae157d8a939b8e27b89c34a62ee21a2a6fcf89ac59d3c028c8751081cbd5aa6a80039e3550f36d9eed7528b16dbfbd33396c4ecf983aa16b7c8d53724defd3a4068ac977fe7d3aa351eed3234b974ec9b752a749f295e5fba138450230c1653f91f773a2704991b4e4db519fd4df1975d11c66b4873cbbf785388c8bf916d732a394d27ba47a2042ad8af1abc61fa9c7ff23fc60be855c44950a664cc1e5f1bf8c784c01bf6a14fa7c3bba3e60e0101603c6eff22545a2dd94825b5874ef052105fce1a7e0f2a9b71fd287c5805d3e85f0f1a7907a97b7dfaa3f024e7d87ad3a26007ff80d70f9d40f792a292911c9f729916e8a64df7f681f12a8ebbebd58e53ef88f1f46083f35fe084792726f9dbc93a68c56c042e18bf5bf7b671475ddc762907216918475c489b4908b421389c32692397aac79eee7808129d2fd2b024d72d8f6f7a992c3b8bf37d44bafdf79bdfbcd1ba60f4da2aefba907c7f203173c95747239959e081610f9e2c943bea4ce4bc70f6cfaa4c60f42a3eac4c9fb64741f9cdc81844bf7a167f93269d475df25156ea9714251d7fd6b672ddf5b05a7723fad459ae77e15a991e6b93f69d487be305df72fbd21dff7b19c51f9a6e87d0dcccc01cf4c82a88bc98f0e23703995f2fd1ff721dfbf233859410fbf43231ad223edba7f6503188028d2d0a8262d5f24ea7a121c76ff9b95b6305df77b869448f3dcefd000a9fb443be0edef8be0301fe1b9d80c16a7246ae4f2f5049681ba55b2b85de030b7539299932452c0289224619dc05e6ea7244f522248b284d32289524a89a147a8d42c9a4972c9101100001000e3150000200c0c08c442b16012a6919cd90e14800e6a96426e58329888a22088611403310c630c21002802883180380459110d003ed9063ca677113c7d73d08233126743c549f2b5bdfc12376c4faa62ca3ff127cbfc600610ac0136c430b737b863f6d8d1b41c581f297cd801756fd8e037f7c31565d8049bff585fcb893318e0f4d85f968a65bb28191a5ca2fbeb29413ed3f974a29925de661299abe679a81aa0775b96e95012ae232de8e11960170393a29edf7ec64a881f66d5fe1c24408bafedcfb32031d88439d1398c066035cd5848ff49cf003c9d72960723b612a9d6a126f47432daba32d24c7aac74a85921ed72462e13ea7bbfe647181d41d2689dca5cf02f7708bb889f3c29f9620a56c0dc7c02ca6d508c6d6f38d5797de4846c73a7ad097a18c295d33a23e41ad3cdf628a84a3e5b01aee7ab0cd2a34f86f13042eb2cf05b7eab091491d619478c51553914da3a176c2107c5e3ecb8eb2cb014728a55918075bee754ce399d247bc53aa4d2ecbae9c4b8e056713dbfc0888cb4a6e2e9d19615bb60ce0f4d8b16de991b3de7398fdbc11e75a08f858e49cbce347ab4949e3676c2a2d4b7643b8be0640466707fb06ab96a6080316b780cf7bbb3fedeecfcd4df8d33e58bf9b5dd46746bb9e1c0c8a1191130dd3cb3b5df01e12e3d8201c707acf53b06999b5ee4c701e5455c01e1af535455f62963290870ef620c6ced3aafa09046d89c59f8c736f0e1a34c61aa3a7927d1784a93e779121ce3aa19e3696dde42f8d34526e1140eea93c428c9ea7253036e17e140782e773120d78e577e485e41cb97b51a81a13cb5904f5ded85b6b7029799058959e4d3089f0224e176415570e78ed15aa6d05e3c2e69392e8d0b1f3ec399a9e8fa863f2b63287d6b1d309797bd089a839b65c63e3e91bddaa7e4bd6a6dcf00d48ac5eb3b0e6681d84d74bac5cee16ac631e5c9921d87bf2d74242189a90347c25a77976f8b4fdce6b6ad2bb71ebc61665fcda27b37b3d0bafa216d11a32208f0015e60ad164faaf401f8b611b871d9695133e6085adaa08df2a049ecf7195b42653c4f3d3b1276fbd2f9d144cced71d2d4e523dfbe9482ff27a78b21b13a513a2ee4e0de0758db56e2e80003a6f3962fd123c2d10998b080d2b90b80734e6fad72609771887db2665857dc980c545fe04d5ea5e8715e94479d2b2a046f6baced740c7824278e3eda83236151715e48255ba8c4da2757845406833198dc7f60acde1c5c83d430fa8230248af4e78ffbc808a10fc409b5d5f07a1e520b7e5733d1ab8d85e24bdb5ad9d2a27e62aeb40140561e75f9405d841ba581300650a7c6c46e4d90cce9e970491f7e0736a97d675d98a9fc223049020c2250681dfa0a5879fc77ea00280f6866a95f71c05cac0a4951a5bf7ff43f40b668298facf334846952d4b5bc10ce8c7703f650710cc3fc8f290cda04006da51463d8a83c66d777ef9236d38709bd2efb3e132b83070d399d8716a25db2e392ff945223477ac571d3939bc9b1718c82f89f4f67a0570f8b67f5e2ae3e7f27da58ef97b47ceac659715906ca86fb89f33dafdb41e289c81657d2473ae780e86cf7f9f451436d82a3a1c36fe6a86b6288d4f1646ea3bd45992be9e8c28767c9eb8ce1325fd6eaabef9535e52a81649cb9f4b20de4ae75249b4405e9efae08584fb8a3d4d6d2e025f07cdc022da28d08352328bbbac12b5724be7d0eb2ac23aa2c4c594444d55223cf295436fb754011e02ac1eb646c2102ec965c894b49d5e71e9d601c7034616205e0f90ae5eef414bce0f1e9d54bee4c209222131773e8c36f1ac8f4f5db02a7603e450b6559665f489cfe45d7814b8db3adf4f002ec49cb7f6a7353651830ebee6da65f10529b6b3a89b072a2699b1b86ab69d2c53bcb6b9fae2b0bdd3636b1bab210125412bac0ee344f38325de86939a4823215a1caf091e76c733d018988a57bf80aafb41001c5730f28bc08d4c60c08fca17b8c8221ee9a088b1e5eba1f1b2f48f05642ef3ae4186da7a01bd823385b3be7befa0cc95edcc4ccdccc594e46e7d6b41a72411b0e4ed1dbeebeb7d4ea037381f4508beae08c46c39be8a1dda3cea5af10525b0ca3c0e9bd5b8b240e5208a8d7b380d6ad388a6eecc81235a8ced553bf11e119f25b01380cd3f90079baf188142e617185cda2e14d4cb0c7438147f59fea57ebb956c72b619fa43a97ee9d28adb0393d85b3ced555b1013074d6b9dde0e61c56b05edda5ffc7334473b08dde6ecc8756409f3af1638e9b0d79d8561da2bc3778031d200dc272ac13957a6c0554eec9a8c46fac6d12336c7662ed4d307a1dc903a7db459882c39789021b16a2beb48044af61e6bb62c8e4ce12963c16afc3fad6b3b86ddb4ece06173515d5127898182a4eeb4122569935c6500864f59973b3d511c079ce7d391d217f4fba75978e73c2b425c99a85f497a376219818bf40e91a0c77a8edfafc022957e1d2c5bb5e402aaea797826d39bb9dc4d7f17a47a541d0893e2590d3aa777786e9e0066d450ec5760830ad933796e90e37a027e02cd450a011a1beea126ba9abe479e26e1499160a0995a9ef47061afd0719128722ce862ab7cf4f1c03c094c34db66970859c747f0d2da422dbd49901c290d20e3eb66034268f87f16426488f345da644d7371aab2846fb1c4a0aad586cd854a307a895f7986988ad3884f60eb66da17d2e7faa29cebeecdc60ffc14ee007882305a136d583a5f57b5f9d4357a058ea20efe47a18d80aa25569885df38cacfc08d1cdcafbc6fe5f9bd4a0aeb2d7c563e8fd1fa8c053335f9f46bd0fa9590add0203d00ec5009dde2eeada48be48293996bd632babc5971d648d1dbc3a0273037bf2cf98ec18b5c86f2225ebecf8449b18b7d0a2536f53889a202bb3a68f1115d1b79b40a988a6b3e3567cacc21f87be56f8cd4e2338c0878eb4ce662e5856a58ebbfb0c89d88cca52db491a44ebf5536f70efb648a6562b9de8836bae97334f6253c74c575116a496ab79eff5b4a18e4499ba9e0012e42219b4880ae569b7681906d141820e454e6bb28a35a7312ba1593a2a8ae502acefe8c35e1dd3902cdd0d8436cd6caf0d71f7bdc4d330ecb300a2f6d40b865fbd9669e2fc43566452e4c1f063568b284622fc1465a4d766c14dd8c83ad9b81350fac750d7e3172befd0c24937605eb874d8b3642f45be346e1f5645b281daac029793d3e7abfc22acb1b0eec309fceee89e9ec53ed4391428d88fcdcd5738a995b74059e017c72d577138c02f0ed7809fedf521e88dd0b91765b4f9731f842cd3472c63a0ea2b4ce43ed7ff4360e8b45b0fda6657f48b111ca8d08cc07144addffdb4dcccbe1bce919a42659180c76b182d3ddf0c987234a29dd958d9a73346b5c8ccde15016610e73d208fa75cb6295e1eb61a73d64264f8e411c8651a25977c6e344e2352911d342dd6300d227fc245b19d92fb280ae53b4eab1a7e67ec58882e7b07757ed50812d315e9137a26f642bb823e97a1b005b7c3fb49e8123635ee6d2fca5e2f6cf9a90a514b55c4fc8c25c7ce0020f86bbde440f4745918128ce5bf1de4014c5ab537e2705910f6230d180eedaff4d444cf1a9e6c697600c4d45b01d5ba7b5b73c2b8ec49d8ef7c1b1252bd53614d6bd8e9e1bbec38744c7abb30b19ea9c743f253ad9f72bd485d0b74ceca8757db7582f32e4af7db94b8c5f6d24ca8d4a6238d12d64f4660d9f0a571da79695201ca39c3648e72a4fe3885ff96781a9f192499ba630fa1ab4a498c35a2de177eaea75734934f4d5936cd03a9c820cfe448f11f003b1d415e83f99e9f1bd97caf28cf3832cdc29434a7f3923427521dfd5b298efe99ce49ee772c1b64758b4f1a4e7f6d49c5f10e9a0b88fd269e3abc5cb294badf3032e8539de98d71e0aa15d25f1c8d11f3694a8ace32b7d811d2f7182ff8e486d4e840e6a2ce5adbfb0306d2871e64386ec6adc4ea9701d554af506c4be35d1d6bf691da2fce1c28da35008d94415fa02b38703b76d37df0c868e40f3d7d5688632547c5c81493b875b67372fa5e26bed8a869e3a26df606a8cbd35335b7aa401f4c7befa930f82141d85df58a349ba9c72ec19a2e7505667ba740bff0581d786987de3a9de838b12e242b5c718495492c7a75397c7302ed59d3dfc64dba009b563b1ab1feafb5bab82b634a49b045a905629e033af4a74c955ade00303e0257b7441e7d0effc1795d809adf0d99fb9155c6d710ff8ad38712a5054f5ff632cfe1314a2593ac61a73bd5256cce7f4707f88223ccf54bfa63c209beee1baf05236086251e4d89521ed2525dae51ebc179da8978a000fd04dbe7358a7fbbf80e3b884da1371befd1c5d914a3b4b5dad679269a37b48bcdd331c48c9b47e73978198eae368408a151512d0bf9643ba79cc0f5c9a93c04adb71a84abecd762c2f52506f9a52dd4e108776f4045b31a77dda8190dc2eeb9be47f9df13b1f5be40a52f25f040a548242a3d02a93499e84fd7b1b2ecc3d7449cc588e5bfe13f7572a2f100909b701095a18f05570e588a755f82dc61c585ce82da54acf704d8d95d6452812b3f78a448f8461a8f81f52ac05214c69059c5310546369297496f0ce391a8fe87d82797fa3132a0ec1db6990d0ab362ed60c1f97abaf1a049cd34aaa887e453283d9d7da321274187fd25b2029f64cd001fe8f27151bf1f1bae0daf8d061882a3e92ca4da6fe5d6472b1a61b5449f4bc3fed36daa7b5d23b36817af1571c95ce5df3363acbeff6a22573b2d95112e0bf6aa43e4b01dc641db603f1138da0e3fd87e69584f1dcc8e667d9d5f6be6ddc8097b9f8f7ce8ff49d5c50dbf318e35478d231b9ade87e6bb42f65c25e566eaaf213d42ec970fad0c42adc69b684b45343808ef430c1b9f068df3929eeedf1b71062ee305f3f161690502b4e36699bc4c77afa9796874f29b2e9cf95c52a32a7a96bc2237c3418abaca8da3d097b2d11b6d8a0c463b3b15b12da3155e70832a8e5f3f7cb2e93bcaafd637345b3037f5650cd2ee885a11e03fdd1f5d153a5e130a67e495d0923909405590f33160f806d3e95b27542a12064fbca394e4f4b261efe39f7e223d340e352c963b330e036e15d4b94b93f414ac5b99bcd199dfa0934009d2cf51a875833a68a55cf65fbe995fa88c421dc649d8e0bff1ad80fb2765244507d24f7ea5a0863679f42f5871b9ddda50593580daeafdd3edd59b4f60b6f68547a8703578dc23d4fa7be81df695ba36a588b209e52f69ee4d9774cf01890775b26a233f1041e15a8c7dad195c9f8b86434762e5b884da7f7ae4b08c32fddaf6dd523e7e8e79325c915ea1b5a785774b4954a8b2b5f2477fd275264f45ca40671ea5fda954b3e24f967bde6fe36b49f8a73ef864f71d44e5fb7efc7dd989480ff8fae9fdc5c4db1da642346fd899384d4e0d4484b5a41f453f56c88278681d6364915fbee31f582c35639180737bb52f2f754c053e3932abc6c718e49d2b53e6b114f9361e6de00941548a919d54e35394c9fa7449a9d43fca5e491dfb5fe6ce44e9aa1b4485bfe4edd46ac0f2cf33c092b3b40ee957be2974dd4deae48026b8295bcca2a1c26a76a8bb4e95f9422f5bc7091db8a7c9117cc75d0640280b2527afac13ac03add1731dfb83f4722a0a928e3c91275c341eb815051a6aa4b1694ccdb7a0863b479bceccd61639e19a5fd48d34922b90912a435cbda3a7fe9a87ab7d5a664daff1c0d4259a51351e34a7e89aef4c3db2b1070e66b41ec03847be76238c4a0bbe37f90fe5e7a3db097e205f5ed53fe1d77af3d08d493f5493dfde9bf897ba79a699dccf65e7597fe2df74c9b3de043feb93e7fbc97fc6e5b9c6c4bf909f8f6e27f8817c7955ff845febcd433726fd504d7e7b6fe25feae69966723f979d67fd897fd325cf7a13fcac4f9eef27ff59bc3cd74dfa27f99dd72cf61e53bcb057fe7cfebc7ef49211eff7d3e4dbd16b8e58bf103fb71abfb0c5fe663701c8a9050c5c3baf1279f7cb7da2b81e52988b586da2e5a1f9c2bb9de0f7b2f254ed497ed1374fdd9830bf1beb9aafc12fdce27f386fde7167a21f7abf054a5db05e19bde62b85657f78dd19ea17e293d75eded87758f99a0f4381245fb4ee09bfd79fef1d137ea82edf3726ffbd7ebe694df423d9c8f3d6bd097e2077aef0d94f0513d222b2c6e43f8cbbb0cd9c2af94c61a123be6e86f493f8c9a3bd61f13423e062a502905093aa7e4247c54657d12c49d2f130a238a5bd6fd08fa92e72f2f30c2445e71aa5e0644452a94a590b659c8840595b05346b830fe622724cc0390902d56c34336781fd51faee0212f512ea55cc3137cf31c5e2aa0a4c3a03f87fdb11104a526ac03c375e51144798f4cf95c1c58cd652a3af456a769300761a4f05f49c507b600bf847ea7aa0877f9901da1ede4a2d98a92c47d46893601ddc93a6803f457ae8f816408602aab9273c28a8213bc69e169676eae1aa67e1f295980bb46f87abbe5e5fd55f9bf95d3b12bd6ea14974c24a30d4add9a469453c2b039504c735b26f7cb855f484257047d3f875cb5ba438fcf24a67027f0bcf4204999bb21252b879128441edeaa8b6de22e1f904b907980238f5c0b41989a546445d5b0aa23ef66c44056290bf995152e73b4813e8a7068b02dabbf05319b272ada860cc50b2a5b2ed61c2a596ce1eb1fd8e1d12258ae79b7ca16aa1763fb9d67cb23a8105a11c41f0136a597d599cff95f64b6306462994000d0acbb0822417630bbf269dde7980e979a1117b3fbc4cb7345890568712a86b5e13ae2a442040f030579810bbdd8829730ce6dd1b7c1a82039e4c7150239ee488d19d8b4cb805908b02279b4eeb996380047b68187e5d88023b0317b62b75b19e4fb70e7b2e1d398b30a7b59a882334fb0a54975a602825b32811c88210dd15f39e4703e7472b44b170f1f7137b6cc361affea6c43d583318c49c6ac56f439c356b2b6f74f03f0bfb71a3881ac8ac77e105a142d9471151faa4ef4ba3ef9f454d42c43cd89c64f16b0f5935c115864193670983bbc9aebebc040e991fe24d6ccdd8f90a1590f2414df945a4352979d6350fd596bb9065ee06f84aabf726ca661c9d1390f356f44aa76586870257fdeb7d6ebad6f5aa58bb3217e2e060de4bf1345955767acc086ad929aa60a5323a03590b01b923362e6dfc0cb5600023cf504eb8fe10164a94e41180f44a919c3e7e275f44519270e9e4d44569fed71d1053b92dc3bc6509d84d7d660e005d773328c46766fc4f7492e1dbc2619c7fdc202a85179918c61b55791a13103bf5e05031ba251dfcff6b59bafb224e6a654cbe85a3bb010a593c30dc7fe0022ba359769c96b89c36134b277b804a1d56524ea89ced2ea2f266bb097d02493ab43abfcc53e7e1776f1b56d430ff4c023a12106d710a495c0f95bbe9196a55d16df8f4664fe4e2f72c711e8b7b965f2846849d2519d8b167d13a15a61aa04447d3102da5fa40c2fbfe50875b0bc3e186341b8ed9c9211941610d879f940f838fb2fe9f15f22e10f739aa9e2d82a2cb68ee69d7152d92cb2f5b085560cb2cb123b94a61797d467126a2a36e254aed10023e8eabbbe5f3ab0a28cd557bbc9230f1ca636eea29dbdaedb244f582521cb46212e5131802ab67a366cc6b3db067eb9b75f042cd00d96ee1eb2f05607eb43f0e3a0c45b7e02c4d5e289a9e8efb0fbf743fd007e14c4caf51dade03052c93c4f1150922e89c0657f4c1a62e0c7043faa3dd4b3b1a1466d8187659bcb018cd1fbdd9132e061aa5196ceecfd3384f7b452cdbd85fc011843a3a177f27eb06c874d89a35658f94592b932809ae1c0ebd47936df816ff00efb2fb8681df4dccc8db6be022612071748b2abd43a1449dede2a4deec5db597a17044c2504d427efb1e53d81b9040a823223b4277d388070f0414c4f27496e6c2ae40c6f793c5d79b1f29d5e424a9074191961e880b64b3bdebfa2d83cb0c03f7649b0e0c2e607c3f1bd1baa398d61e219c20bf07dbcd8c8f2909b8cee00b58040729c0e50c9bace0297893ce1ca28b0b67e32d87d832169ed020b4eeab59063186d9745575f085d6a2424fba5134787e200c8491e7282e37228d01cf0a5633e000f589a22f93c39b75733cf55e002ba660d5fb039d5f305f2564d39a8db9a7c3f803ae45ee0aa608ca15a7741dde3809e9db697e44d0d618e6456c1520c6b5b7689cc54e6893dfaf0b9945429e7c0c84bb5bc9ca6859b6ba1d35f9de4593a0a5c9a639c62223f3e72b6c3fc71c4d8650efdb87ddeaa53ac0552846667940a880ce300da04ad4ce309248a6eef74fcdd0c2f6595fe4a3e2ef24ee8abf7f59a38d1b1c64b078025909f52a8e19926f3cd465e42d79897509b3a407aa8926377ab689d281b795a59664b47ed842e14b1b886dc7a404be839f131d5161ee89c2431c948c5444cbe4529937ee40202770d3db6c1e6a7a0822ed5d666bcedf3764e75df2c6bf8442a03dc5065c3d07cdab7b195a9ba539126d1d159187b6f09de6f1849afd7e7ef7b5ff4770edd789913dd7bcb1b3a243cb480b299c8d11898f6195a8f7f583857511feaff4839f9c328d003c0c7b70b86b2868c022ff58a4cb8cd5af755dfd707ef82e2b48390954f5028fcd87825975858ff928853476d005819976a059908123d60a4feb20eeebfe7854f3a8583fc3a8bf86080a9949086e5ddb5a766153cb3d496d35244fc5775929ad9b687ee676191a5cdf0891ca709886de6618e45fefc8c6bba370a41bdd6271be2f788b8d6ca48dea3fa876c8c72d0c6d4223059b1f87f7282cd4d21d68f91569701665604fb5635117351cdae5d45ff4152e92f7d68943b2d97fcc3e11b071dc42d1ff8c99610b84705cbcd2334d357b4f9cda9b8a53d7e2e4eb83d8a3af23a6095e215450ea692332de840028dbe1d06c26b1202b09ed0e4819c772505246b98e49cbdf29a4e9176bf1f2946f1a50667687de9f836b4a221dcb5700834ee0c1e5f605f77744bc72ab0ae048525b4589d657dc476bee49f92468c99b2a5d4ff4d09c842661be6b3463260ac5d0372441d8b8f059fdc73a23371ce1fa173b9743a83039b6d49abccdf3d0c313f80f40560bbeea0be1990069ec5ba426a6659fd3090c39187c08bfa5af87f25d409e30db4f03014a9a85ec9336f108ed8f2dae29139689c538e813a20842040fea4f924c0663620d3a3c5103a5a50c951f703cc877d165e5b02cf906053f1ffd3e12f77b8cc30f9af8bebcfa0752d91f4d8f282be4d4d2e7a1a76823cb8add80eeb0ed486ee8c01eabd5a791eba1077fef62f266de1ef432de63ce4aec91f7df0667096b085373db47b802188623434d197b2f464e561795e4cef466b9b5ebaf845f7cf11b28da1dc84ee2c0b14fcd0c32d54c45d98a3b870b3d025a318b99c0080f1800fb8c6236069bf8ec9b3de507f90251cc7d47964d08eeb0009409e6062fae0f23c154f26cfdaff7935c20084f96fcd2dd09a830d5061f526c4c895648b950466c39d0132743d3c9dff352c2cadee1fedb9559f87cb9baef3b31d2de1124cb13ddd16a8587a54f7e04393249549105891627a92c8916d537a71a22ba0cc887a11f5e6800f4db8b7fd7c95cecb8cff7de58590281bd9ed79c760eff82589845a8c3ead8870cdd677e8bbb53f2366871b16da8079b3cc3d8bab855bfe4ed7a4792ac29826eb4f59d1f79b04c8a176b672be702742c6b75c6c60752c0345aaf42151c6da8cc4d50d4b069c61d8bed22cfb64364681f9fddad0835264638a921954377b67a30e502feb4dc0b461d1ee7586286a93412d3c1c7570a35c47910acaee79b1d6474965fa376e16f7a80edc1973b95661efd7db01d38b278ca6d708dcd653ebd5b19eca09d38e152154ddc0991a3653de2d993a06ded1f76c4604c43ab968a393b6aed5a0229fd48689821372b7cce332375b6d843db1f880b89d2d5b2e2c62b4873ba3988d3f56eda60b256aa4536ffe4b9b65d945381c66615f212ba17953b046160c09b247013dd2a3604d98266187f6e523d54862f782a5dae104a3a91a33ef20e15393115c9a3c72e85e7b61b5bc226cc7c80357140ed2dd70fd33c7499aefc159d679f56f2de9bd1ec32ed6dd796d194bd047f171752a889a694dd2b72259b88d674722b7955599f06736f53564428ee8aff271adb933a8cf3e822e93ac73147ecd1fb43903cb555f985ffc80aea41812639fdda2dd388c0c39b507652a82a7d55afa67625e4e527fd62826523fb9b9960ee65079309703ed53c8d5573a8ff05b48ba4856a5acb0c37b6df18866f3ec429cd0d399ca0ac6005e75065342e51f6e8a22995dc20b1f6d85625746bbc386e42646dff2751b5537c2083b900220faa2858b9354c484d7cdbb999255a2d67e2df642bc8e31250f0080ebee7ec4f69682dc62a9a081d194357047ec4541a972331c4867ae7f3fba9b5e7d9b04a60a5ee8c888d47eda1c576d5489ef882e6e5b72ba1d2df8e50bec9301f5a72fb0f6831e8b9afe1835a663dfb72b5d45144149f023dd9114ddd73e328d5a409a1e1dcd0ea8a564412c42cdc8df868423281436e3c288e42a32073b257a8171f7d9d6bd9992b45b6769034fe5e91f77c57380f0ac22d9648606158a9fa1f0706c473ee51ae57f0328696938b63659c619c116e03c6949558c932209b45c46225ff304ee250378be29c0db436e1ef7d473b260c4d7102a172f53b7428abce37fa32d7110a5aaa8ce001fd5682888c940611f776c0ca242fcac3323fa08c1cf128c9ba77ccd19acd79f89de0c385e97488cb4849d362382c6a1513dccd6e73a3bb0a5bd26e0327e0a260abbeaedc4194748308ee6eb91ffdec9658db6b6441d48298f7fe8b88331967bf465a7cbe283f29b3b88eb2ada33220d61e43d2d4cb8832da1a2071e0e61d0d2512bf56b8322eb699905b52ba55ec96b7e85f886e8ecf9ce0aea2f28fb6727238672b5651ee6575d2544906e36a298396ee85be525a350f37f784f1fd15edafa0d8dc122820b66d2e2e4d79890d845c120d937200e2997d0da6590481c9c8025a972210af6af8fff16831885a310d6170d9348b969e1331f6d8afcc840f80f4ad533345c366c14e019efe1628ef80d392f03c80937ade8d16a5c7d5333e025295ed2d5137e8fc9aee25f25a8689c8bfb49cbe9cf6addeddfd373e1635b37658a5a123ae32efa4a04b44c4522acd4fac402c4ae5b4c78cf58884729286d376dd46f4423919dbdd049d394262ce3beea33759b8dbb9eb6e73948872e59a4a3f05554374ac179834c0a8002219659a4c2f0e013ccd3c0d22f64e4d9813306f32f16f8f546878227373c72da61845ea4e40ebc80bdac41459dc1739725705d5fe68d62b26104f0c4b3eb54f24edee18f407e16623bc4d21856a6d22befec772b6b4c67dd55dde486d206b2c31dc2e034669507c3c54b02948d15cf4be1a660178d1dbd754310cbc4c35423fc720823107fb041554f8f6702f642f7d877eb6213744e70f9868086d90768b8567d5044546212d07f5f5c8a3ee0bfea10aada75e35fab316d587f7df6102a5ad09b43f292369e981c436cbb7ce532a6542b6312213ba581c55d3639f78324bde3e186989058285c6bc9ca52f35713677dda466084ed360f47f79d1a388bf52b1d42f51fd5e0eaed4e40580b28b1c083d3d93719380947105bb6c441ecca62fdfaf50ad084baff8d0650193748fd4952bb47b6cfb9b30bd2dae86f57af32608502e66191a799136062f90edd3ad154f51d4036a09e069b85cc53149da4240c700802e1aa43d8342d71189e01ecbfbabee0f83f651608b23a5b9b94792e3526ff922e50ae88ff9553212e03425e97f51d3d6d0d0114f844d712c9fb18d6581b6160f38ff937ca2c25ae3e05cdca6ec7c04c8d406184543dd73bf16f52a974bea88c7c206bea783354fb6a2fdd01aa2bf64f7472f8376bc0ae11caefedb2b70adaf4e40436f5b809514f8cd7e1b871a7f8257a436cc37bb271ee86fa54fe187262a4bb240065efa03249afacdb4a34b03b34808526a1595bce0f005abe8c2f39c9269f604cfa52fca6a1fb23958bde5d2ced6fafd2beef77a0002b13f4d020b8fb37767fce6dfde6356b7cebb2d7698e0198effa1580d1b816c45a2d1cf13f7bf402d6b6927dff90e3ef2274745b6c29470671db9b72f1a35a0a808f84e8099d706159cbae8bf0e36f6dfe957a241ab3e246d8e5f5f5b8bf0171ef3860ddf2271bb357901e7527bf302d1405119e1be2e950d73c66b74bbf01fe3194d8915138c5d4786780f4bb26bf067b61dbf06648e626ae263637a80726cf8d64ee0e6b0cb290cfaacf5ea2048c1d674139f164638c5ce29720124ef1a2d0e8c33232e25b1ab3dedacf81bf142914bde3cb018f2c7a7afd5bfdf4cc6e45acfed86e79a5ed0780f02c84049a6458d9fb5054dd8e54d473a1925d71dbbe5d5b3a0ac22c1af9616a4d34279542896ecfcb5f066f39871f6676890488ececf55a779e5a24a822d2af75f60c345c594dc787c3f796ef42ea9e06d5ee2a1cb11e796c801d65482b336cf4ca09838f4b49e169d4d3d14d1ca39b2c6809f707ecd27b1eca8c6dc0aa266cf19163f70f9a5686469f1a6657903822a67700e82d6734f2a9bdcdb4e5db8023b0208121c032fe2b76910187bcbd0478e9217f425242cef7473ec5364e6a4f496599a2afea41ce3d30b177745baf47c17c282cd4cc9a982510e758dbc1cf91dd9be177f47aa24b63d13c42a25467a382835472fa2f2f75ec9aea8be2e5a482b2686968c3eb27e8572de2549e8d4606580126de3eb74baadb895ce614bd623073e5725ca624e0e0a9b96a8170e40af22c0a5a5865609d7141484d46b68b811ef6578eeb260bd1e4e6a8ed79496ebc6cf124d18ad5ba162b3cabea296694c19ad5b4999ffd4396c1111dea3b62302d60817c9b0b77ead7377f00d4a9a734a6682ba56b4f097c462b0f3d61bd61d2bd4155b82603fae6b5b3bb3fbd278bfb2ef028651e05dd51cb1f507b15238e501adb2e3c09aba4fb77a772fc5eafe82443e4216d24e4eebc37eb529cc8fced2c53aa2539fea6595ac6481cb4ae09f14266dba3631a378e8000a95a0c3de6969102b4167dcf408599dab7f99ee146569986aec6b28c39bc80de8ec6c3f764b8279d501439c188f1b1127ad9cd402b129ad65c702b0e946f7eca1bd0f163e6d13bb7c42d1b291cf0db98bc41aa70a7da56e18715641a99710d1a21e3f35814d951d8d9b2e3681a6f64ad90800b954e5996d4dd982c841dfc56998123634de1caac483f61005989443728bf75e7a0a2cd0b39b961ace229bfc521faae9c641a86565c5ff95ab51632c6d974dabd2d687502dbdca08db3876411cb9e76facd8d9a777401484bcf2e96e03daee7858b3826017135a1932e515d6c1ee052f20350c46076f108652a0b2661b61ccf38fa72cd77b95e8a97ee9a566853c41ce220d300ef46a950b200e2a045a0892c4e060516c88bf5a0f754bd91e3e4e3a58c9680d6f1b2a6ff79aa904a084c730917b866c1f5a1bc1405b17a2016d7495a1de56ebef5031617a11aa21a2fa6bb1aecf6acd1b2adfb7c39b6d43294a5e7573d2a588562ec574d8fa8ee92e1126aa364620690d2f2d352e470511238bd8192b10b5752b7fe63f298a548ba20aef84804b98a556c15fcf2021902716f027b40fa00b8bae3b88548b6706d461a07197e67c4fb380e038cb3bb462cab9b92a52d8a5c31ca2412224206c8b4c11375aaff24ee7f96e6799b370344fce344c21196c9680259a04d0aa4ff28d4f1493adeebdb38f97cfc03d25bfe30838b70dc5660082cb72990a60096076e0bf9886d53a3c76acff95bc1d536f2c8238cffd9df5efe54fc77c0387ede582259a9cce8e9235c890423fb9a0f3574afb238611f6804c279cc4058296a04d2c8ba5c54e2ed67df6b071c8174d986ed85eb261878f66febb939ea129809067693f797303c363a06a07666ef35d7cb43e5564c62e0631cf57713a03f422f67a95b75a3114c8dc2e438ca71b0a54176a5dda715bbeefd444bc5a171a1005d26586751df706d7bda60049375affe06d4eae13fb94078c90eab671b44d4fbc07c6210e567982e58b11b2def2185babd11ec501623a82d465c417f70ff603a3c2eb1501f6dd3f164c652faba850f532a0ac59fbffcc9ade7ce0c7aa7c1a3654b81ddbbea51760ada565288b0b7c44e29735a541213ffaf1497658219882246a3605a48a312f506beaa71b8fdb957918d4bac4a535554502cfb43e8f6bdcaf0f8c2e036415c1fccfac6c1c6ff84ddebb212343bf40aeb0255cd3de6a02de6e28657221433971c5e54f2d44653f6e5ae6ebf5f79a15f1d727da7e4df6a68c80754df4683bfd9a446d0934393f031151e9672066fe3cb3370d73008590990a57845c4210cc39339860c906bcbc4087ca451833b9788ee2a4729e040487f0d10d1f4435069888ba99f6978db29cb64b1fe59793ffc01a6cecbf7a38628cd1f8b883b69810da2d585f6de842c710165a01351a2e177db75ddcf1ac44e2775cdb8371698d3880eae40ae36453870bdc19efd56ec4e427ae0ede6feffe97b0bb78989a2e2b96fc56bd204ea76298384b60f31266692406dbbdd4b630a0348bd9c7a9b43f4e169d1e487d67b78a600ffc75415ee80ece92454c028f6f672d069247c65925d7d3ff5bbdf6c51529f9e6e9aeba049db8286baa81c9a8c7d742f18f417e91f0dd83da4f3bb74e0fe3de2a73a48518c61e869792d60261531a8b742c93bf62cdee414f32d21346ba5349aa407f3dbbce1c0ceb7700eb287e8c0271b9ac69266e7beaa00b0bcae9deef95d5b9d183741b8b21c336f044d265d506d9493057272e805186f0cef2592a2ad04e1d0f0e90edeb5f98a815b4de5e0d8d3124633baadbcd8d54dde2f0458c4216614b31526c8561027c5e3b9719ad7ab51a746488c3cab2868ce0966c4534eabe50a6da3ebcf0d70a704e3dfe7ffec20e175c2111a8af6e52f3332817a02a0f29608e0131b8dc1fc6a528044a0f48eb999f47e628e0f19e461f9575daa8dc18e1a2fc21235ff0dde45de208bd24a38cf224b402aa30f34532eda938d465461cb51b993aed091ea180e338c79c3ea274b2d7a8cc81035293aae0f8986819419453fb1c0609aa61c6d3d9d4012d7b36b02906be626765482c25d87102c9768e94c8daf6f75325a4c704e96f201d8668dae76b98e1d79d865e36306ac9e0de83073912c6e5cbb9b91c0b9d2faf5589930aed93c78990d427937fb98bbc496c7280aeda0409473da5967c5da1d9a86800288adf340ab7818e12708a005b08dc54cdc4288ba34aa8f823e4010657a358c62789d94cc390000340ac48c541b4291c8b5d30eadba499abe51fdf8b66ec0b388228195259162678e68146f73908e1b2f72dcae4fc208029daa37e660a4ba21c9fb9f9fd41cf4c70860171c2f939589fa6b9fe339a7b804cf47b904752021631e2f83d9e156d4ce5163b6b0af2a82a96cfdbe76119b17447201f5ba71bc0de88d0601f521d8a881c942a7449be07f3d97a393b8cbe8ced83c608c0da00ab5642b04e760ab54c9e6a181e279cdbea657341afbdf096f71c1a42ac249ab8cff4867aa744bec46bd944ba678b5f10bb1d3fcd0c0301f1becbfde9c3ec8123fd27fbd8f0358562a7a28ffd00bfe9c32e7e4e434a09b05e1c60a393952c41af8bf9e4f4639954cd5a14c16a161cac72d8c57deca08b798b46161e420ab323743f174d0745cdcc1fe110484dc7c2c4d55891d45eb2c4df54489f7254db003f75a5965d919d0a1c04a329a613c2fdfce6eded6d2f3c0f447e873e48f7e1937602aa52cda070387a58bc7e399efb757d1313fa1a791981e66e5f9a581e46a182256dd81014a9007b08c1d26de9dfd397df906f62cac112552dc540b278524f6b14b5a27bb330844045c88f7f1fa5ea748b251a161da70d1125a262399522b250f85427ccf69c37c036cce58f1b69e60665b51ff91c8ef2c331a243eaf1a98220e1a47867cc664a9c05f209bdb9f5e3adb6928e32944932b26c167b8408c0a7ea86d72c861878da95ea9ec031f1c6cbbe0515a670763c854f770c68cfdc6f00d3c09c6ec53f80cfb1155bca0b6a10c771208eeaebf8622866625db23486ea60d212710ee3ff7d361dc9f2d40c8a1a510c410d30117859d388bfb860793ed3973e00bc03714f9fcf5e4a8bf91805824329b18095a915cf0ef49558c28f27bdc5c58e4a44da5253021fc482df8a9df9fdcddad9086e2819c6266b1452ad88f45a4ef4153dd23c45bfaceedf9d6ba5226ca8b4799f07a28e9f886275d96464dc959b74b347c9f0093767657f540f2443cc6e5ee1abf92b3c66ff5f9568d19bc15146d788b9f0cff069c2741aef44acbfba3a40f888e492cfd5699330ef804db96459903ac5d931583b2e5dfe6cde0871c5d264d72186ed22374a71a7b872856622178089751db586c1e2a78fb82cb5d3427be2a7f8ca4c0c65387504ccff9623922187d4c1688916b6a80ac9b548bcce372bd6188bdf3180cea7adb7ff0de72945c72608e3a64017eb42a5c6566cd414bce8217a460d11fdc87008aa17090cbd31739500ea19ba06566f188267d191adb84535a3045bbb559f8c7dbd51681c529fa8160e6c30e6b415862701973cfea8190ee4ec65afd51535cb68be1cdf0ce4221d5bb8d150e46c354719ba41f416f21f85ad04080f8ad584096f44c75dfa9efc9e3fe2b4403d7b78ad18421d89d8a4d75e621738e249ae46f6026101a29bccb9bffecb13dc044bf5a0d42a3a396120d1e5fd2a85e34e05f465f347d88c02c32c587f0bd565e2c1b4c09f1094dd096d8e31e37eb6615214c963ad7821e51e30d911aa8ec3832d90d84c2631973dd75ae09570d5b7faf2158f052aeb4cedba9d056e2a3c8124bafde1854a1a82865323d1ac9af38e7464015c5c1f580fd1d2ee448ce2af8a866312ce23a54e97ba04a6dba68c52301765563cb768d8881557878b5c0a94cbc6ec523748798e085b6fb499938d777741287da399c3f617377b01452cf782097a14788331603823580620b9a2b53f6094ec2b41a7fa583cb928ad841c647ac54c32f7481ea533e15f29312a8d2e4358d349a4741f62836c1c437c12d908e5d9ef1b2fbe9e4d10eccdf1c7737b31f94c4d6917f8ee8d35f4cfaf7534f64e76304f6356cc1c5cab2f2df05f2e1b946c3e862989f419a76a52e92d66ce9649ef8698bcc99882862ce97c3437e5256a7eb1b21d241801068e164c619d11dce9443d68c32ea0fcdd71a8877873c30a2bdd5f775453864463436cfc54b584390590b2d7dd0b604ab1ab0320ae8238339a22f4022ebd87fcafbcc12e4f5e961be4032f293e433b9d5da2397863c69312a60851243754138756b8ee576574fc1f3059c950b1f70264bbc3caa68865ee24148e88e44b69dd3e56504d490971cc1af51b823146188a56ac9a7c255092175b4a9fb3aebff1262b61c1708a04f1cb499c0647c7cbed73d8783391ad1c133c37ca8e65a9981495abf0b85e8ae8fb9b421ca3c8f8b3b3d6361e43d3d4d92fba7bfea307e70fd61d8d7cc02dfe5a6c532822a1c0725e4152c7224badf22ecb211fa752ef4bfca58f92195ef947b8690716b0224d38444c94f25dcb5c9719787fb6df66851afbf8b335245e580d5d073c7946982ab3105ea8a2f670f2a66c15f6d8fa2bcc7c128033643ce991c3e2ace49147ed9ba1acc77f676b8f3f197c959c568bf8ae82da35be6a004f98c537a89ef03da37c5c56be5092c21cab6a7cd92bb117d0e4a6ea78bb75fffb1e9be9beaa3ab0c5ba377283f647ca096177339730b3b261b11c97dbf39eb9ddfbeb744d338e167c93b7de3c2eac2a58cd71eedfadd061c66189dac9fc4971eb6e4f4a017e44bf0b59082adc9a1a5576a01edc1d01e52ed7e1dcbb7c9f135a9cae93afc80d58457af2034d3b90c576bf53c7c1aa467d4d3fc465883b08371b93a128fbf3020ce19e3a0fcc3da10e5e065f606055105317b1a46d7be1067a81924744f62cb1498cefb556fd484bca2f974c14f200af260014fafb60bcd021a35bb5ab69b81501dc627e67a8524fc2f9368a88b236a59b6526b59faad61e58e10154fc51ce295d0e68eec064ff19a5223fda606d1eb24c39b64529fdd8a06f7285aec48e26350e452a69bf91028c6870da3b9c70ecd80f2b9ba5db68f8197f415a40a350c43c8cf79819bb7a2d760d383fd11975f61e69d95538716c073efb037689fd67917807adf5feda02cf4c8533babf80a96043c688bdc2aa58988af6eaa9133f18cb5b8e883d7f62693c19fb7208b93a3c5fbff209744869714b3bebc18001db8f24b3350ba0df04144c761e126959264a2c6bbfdc58ae9155eae605aaf1c82d993d6f5079a7933a1095a96a01d761d623a4790e3a0d7c5d83af7d0860da54edb94ebf9ead88d95d7cc4779848d0bb3271a7fca8b9645381d75b7a0831ed5fcaaed22f9299c14b32ab54340bab5e2ac5289b97fb8b8ae508c161fb0a4ad2150b5863078336af7a683c335926b62c25c953450325353fdab6f1850a69d4482f8625fcb08029c1f09f3651911b006262fd34b34915713eda9482221d0d7047c250f04ddd2b9602432704f4b9143c99ca0bcb3fc4acacd1162bc93c1821b7a088d7f4116134c00e1489a615dd1d2f28a5d43cf41635592b506cc2b249e676c4e467a37d80b60872f8514d70feec4e99a4cfec1d02d159b877724bee335a1d75572656cc7d9dcb976790ba199b6f1cae948964bb06cf9ae2ad24dd03529a14cea236cc639938d09060e7168c4f4674b3e174de328b425cf79afdf30a622647325b143d8381d2bcd94cd3b5a014569098b5c5dfcc8db225887828dd661b4afe2baf5c79d480af5df3b73dcbf4bd29cdc5d45459e1ddcc7c00cdd66bed90f6cb1892deeec6cf36332360ce080f32b89150a13bc3ea5e90f06ec0bdbd024c05ad194d09eaff91ee7ad86556b435868619dfa8dc97576f91b68d9e9e436ff71dbc6536fa83ac8dbb2ed7c48b5111ce320f6190dd3eef7a9984933b95e2f277e8cdbdbb89761af511ffa79d5097303b790512fc709801df9cb257949730d5d07533601fa7358bbecfc3cb97af4e9cfd3a0080669e5a8c5daaeb05f08a38c44e0c86bb9ed331ce669a479d26a4d0f872463abcb49e78c43f05637e67966b3c2866a714f7bee8b63772f770c9b4cbe43a42dc31b874c4da95990300ee11123a5c2a3117b23248a7715d15673bc7eac52efde60c71f9ec676ef201c6e86a0ff7354a48582e07773b5b8e2d994d354b01e356609d2a6a7bd9ef202fa8f4c6e72c6d60c62070aa73b07d9b5317e046231d52c65df14ae6b968535e89a48e8d37e1a0e06ef37ab3654772977c9076a426f74f20994a2dfa2726c20436210b0404e747785a9fc7c4bc1e74e15ca288d5657be9aa62cb04637c33b53485fecfcfdb5418a8ec0a98594bc8f2a86aab3a269e1ce6494f4cb45cab86cbbf3c62eb62b8fcb874446f9bc98f7b45c40e1e7ad87a04020381e5b3ca7d25c88be6e95588fc43b8950f3f939aa1321b79a0eaa498395ab28774f658b43b2b8a26819b0a5d6f6abe7fa880a2ecbf7d3f543358e02793e4e85414ad1ecb3e313bfa378b3329b118eab1fbb9dae5841b8a6965e80433ec3fe7a294ae232cdd2e025e18fb5bdab1b9347bc8a1c632a89c236f96c0bad2ab93885aae207f2f736c60e11c2bf441d8d31fa3e5906eebdff2342ac9829555e2f2906b1c93451e4af4b1a1bb10c987355306f0348da6e946d0228d613d0dcdb4a58626b1f0eef9311b040a02ec2a261498f62e922524d764f85eb65a313be9665218130a8b60a4f8cd0e5f8c8a115f256d13c151598cb832d6fa9345c333d54541dcbb32166630c38c11f67da2a0e63e8e4319a273b7f6e685eea71a49890b7f4a6321db2cfb4863f5bfee6ebb1b34d40c52e57ae29070b6eddd642d0ba28d39258188f71dcc30b6d291bc56732e50befd68d7bdef703cba656d30b6b83da3918c87f706ed284474195a3879ca48f08a2f0aed1ce4d14f79bc2085ab55f4d8a62a40edef76c41ac4308ff4b6b111e349280b928017300ae247f0f4061dbd578c43a278d0ca52be9ee3bc3f83f418fab54ecb3c2f60bbd0e99eba01dd46a489a40e1485ea9a0a5be51e8018bb92680acbd91440f7c1b7660b77cdb2c618bfb23d930a27c03094da61d73ee5638253fd37495a42a6e30eff42cd84a52f4ebdd5abd089728615ce3584f7d9fd2e1500d44d83bc3483d05cb58fe37b09926fa863ac52651a2b07d80c5a119085a5de4ccdbdaadc9ed510921a9c609a6a18f1d4f0769a0afa8acc153e617b6c2596ed8cd94f284848291488e30255965162588679a7d0e28137cebf0e6935d0cacb9185c958f2b9559c71bdb31f0ae21e6ad6aa82ba119c8dd714d2cd7aee4c5140877962b4e2599fd754d9066f4826fc0adc9f46aaa4d117602a4877e28c3e2da88f6d9aa0e5b6efe9ee9759bd1059759241fec3cc98b39daa0ea5382c79f86efb1bfe028a2b114b672e61ca06a60959e9d19747e77961ed6a6da0e7f95d2b6b01574a0ee9a12f7df4fd91311a4480bac38d38a81f23c17a6d571e82375a5476cfa8e73080ec1cdb05d1906e9f8980393a19e31707f93d5de3eea2957b9153d83f44d800fa10ac18296ea6d4ecbe6cf4d700b0dfd539796d31bbcd21ced478c70a129c4dc7788e6b25db35df73e11dcfc224d3cd889a808e64ab35d54893a60d281dc06b81d8c8bd7a9be864a0e6678d2421a678c8627b5548f8d9b5b3a11bbf8d305c20fdb03ae05cc00cb5f2a172ea2d745b899bc627f0a23d2223286680132cb244d6dfc0a3eb5b4f0b2ddbea3faf63d69b8c2874716c4547e1497aec2ad66a7519f8afe7cb556be4146aeb7ec006cb3f485afe5654a130446bbe8ac64dc553a6dc29429b497587ad49736d90efe73a6305848b96d58144a3384849257ee991a95aa785e9657f160cede805283ece6fd12667acea12cf2e869eed5d6d801af31fd2a941aafebf2783144f109496c2fea50da0095a5e53d11e3efe026ee0dc08b17ad49983c8cbaa248d0407c4156726b533055f549c9673306eeef046fd868b7a0f1e4cf402f80fd74836c96e8a6527d11c0086e70571f4fd8ae215080c377899c69a01569aa675b34a25f1b3258edef043cf8a2969f2de50aa5f5bc524b7eadf82427947c062fe5c998aedcdbbabd6fc8b1a3f73abcad8aba938ef2af3bf9494e2ff4e069cdcf91d8be67b34f7335584278431a65b6b4dd5a625a803b1d3f15d8b223a9548bfb0a67d7a6618abedd109d9eb629f685c7806d5d495dec7e09cd34ff55058a362e05797ba528a02a1ad84dd7d92a84bb4f297d5880daf5043f52bf9f4a991d17a3af59b1ea47a1111d5f9a9a9695e8a567fb11752b5a7c754a2100e00566b76d5cd4e8626887c985b169a4f8eea845461ae8990f4a5e3c40d641d59790571bb0006810a1e3b02679f189ffa3a8994bc0443953646b39c711d5b91dc1d0ec7a13da5ef155ae9104a9807538b99503dd00ec80c36b25e77134161362cd5983ba7363e9098e3e3e8847e8c0ab7a080f6b152cc331f00a754a92a3f17a6f16ba5e2131e952aa2bd91738da15f6b1a667e8ae5b65eb35f1dece0b523d57ef52764abbbb2d5350f6da5f871113deb6a5cfda3427dddf3467e5e4ecdc7938b08d266776f9e0a46e1270f427000a2dc89722bd5b8fe7d958bad299115138bb80572a3d368d5a77967c88aedd5bc1e9682042ca45f2029f9fc3ab8aced2aa20bd6e1830cf33ec8d2fd177b5b0012a0fd5ebc117fffe7613c58ddde6c960e0cc0402302796a9bfb54a820531080fff48402d319104dc334e8b41e61ef523c78c75e13f54605ce25ada864ef67d818add487ccfc9c216fe6787213436a79b35c7d48a09acc2351e7c72b7cdd7cd831885864c7e49d7dc701abbd4e2d0a78cab1055d2f26039c385ab822291d20074848b1a048e88f8bdb80da250a08ce95a168e2031c5ed62e27b0b3581f6e2b46de7a6aa5560cdea94fdb2f4d96a5324d29b859d8a91b6fcc277fabe64c55e8e149306defc7910f90ac7ea1cc94ed590e95318fcb0af344efa6cf6540d575a1ba138c9a0d28e3d924022a52b54d04fba4e91ef6faba5ba9d86c2846af8460462b57ba8af5d91337e6e1f15481084818ee099614d316b9188f577241d8a0e05c4045ad10d5031632840b5821ed2fdad6ff1390bd616dd79f9c63edee4a03262a35c0d926c4cd8f03720691eaa554f7ced1fca3c054bd3483f4b0cb57a545fb8327d7a5c5d0bc6f51cc5ab92db3c0503cc1c9bd949cd4c13e94f8de1c5e3efd8eca8465cfe861662dd4c60c38e7a0df7a66ba504572ae8baecebb103bf35afe09076efc7ec157569715ee1079556f5eb82246a44c25ed0167852cb650ee70655fef3a1053485494bd8d43558cd70cccaeaa97123fe4acc7206e89c74905eb63475d6d71e816c351032e22949c408799ac97d6c64280717f6aad28b4a5d379ec66cf1012285ec647a56c2ed4da5ddaccd570c94ca7a08bf840e27b5c4da52f958d9c12a7959b0f1763cde07f4ce3c302d9b428388d0542b4d94138dd3bb2fda07bf445fc4bd34bdff144699749719e0ed388601f84f2bcc451803d50321e683c2835a724faad55345a6e76748f08a6dfd2a2270364f62859ced1981deb9200ccfe5df3d96c48894d96eda0574ae5a585ab325a12f932f5ca521c71019553e379ea82fd1ee0d091078fd111a4897044865ace9e3cc0d94479203e9c41e8e81f98268aeb9d815427753d046aee63a3114ef38d2bbcfa16d10497ef632f3cd7de8ca431e6a0605d18e2afa44f74da93279932fda9d337a2f8a478e9cb4d75d7601caedfa65de90295dd4fec38877d44f1a964256fa16b807c9eee32d69f5e448f2fb14a9062414b7fa6ae7c87c02b0b0c332a87ba75fd793786d9cf169ddeefa510c06ec8a5f8de83993e36a0c260c45ce10798e07cadf1927de11cbc36edb2f3bc4f6f7cd79b28fd71e058b2e25da58e8786499e372384a28547b9d06d200fcf9bd1bd84af0a1fa08595451b8813fc9c65b10da867d40d0835b807b6794ec295c5f98f0273bb0852b9f245aabda3c4858209da27450156dd3c3bacd018d7bd25d815e071f53ac0e521e8a6e7a4044d20fc8b202dd954c539e8b1886ac8f8ef740e6408e934e7e1354d5160a331701158a6485465d0a51051f666dcf8365019cbb530a84f811250dacb530328ec2d7c585036dbd9acfbe077e4c26ca4b165a8949690af512deebed421ccd38d97b7bbc6523fb9189e8c11a443e3a414335f04d12aadc70b752757221900a4ded1a420af496c45a04ef7cadd7db009e8a25f38db56a53c543d97b6104776958a03f281d5119e9070ff3a503e0e8669140c1e9d81881b80969aeb40f1c420fea83834a158ef4adc74a85e77f978b21a43caa66c95adcca99f6fae73d552e0fd3bdabeff4b9e47fd78a1dc0b6c1359a8da1343608b0252663bfeae34399a8096701fc086d08a178882339033ec1a6d28dc2b13448f3f8d16efc9d6a00741e6e63cb8772984f6882e4d8cb89c8b40d380862310d75f6f448911089fd035c942431a02b9f3babcbce922320be805aa02c2088ccbe705e4f1bc40b83a5613d99904758100054f16ba50b240afcaf677b7fd8d32903cb93060b7c90662cd8393555a543c2a2d2f703bf6ea4060fe6ca37150c86e2fdcce9be1a780039147c2bf668c37399c51d2e4c4ba96d0b8e122cbafc91542dcc786d9c4a7db8238940eaeaf108ec39e7c623df73bc7718006c476f98923ff9e2d86fd7c434cafa11082700541c44f6f1f34e45589942b60329d812cb48c08a13f98e436349d3031e38a73d53840220d67b11db65913a8610a631273e9a16a88bb3cf664728872063317d7ca3243bc4d5f230dff13dedffbffdb4da9b976cffc327d1ccfec5eebebb728f369fdd2c7e230ffa97bd061f2337127b3709b087b706bc0f80bad822086a0d022a61a1e1329377da30bf622ffae1d0098bb414eed94e0fb3103ef9e5fc1f4a00f44eb87699ceddc50a0d2b7c0b9eb0b0a93549b2ca12f176d77d2f426abd18a3384d3691b830c26b983ae680a1799197f17c607ee6e7d32bd663bcb988cbd968f0dee2b0b4ae655daee615a549d203babbb3a70018838d0802e1faecf57e2324e7ea08af9e67173e5c3f88cb476f34646026172ada7afbb1d66aa184467bc161cdcde0724e85d2fe08be5496f0a84229c70f6898f5f7525e0b4ae7d890cf6ccd3008e8a48ce1dc9837727592dbf458b54df3deece2240c7490f8b22703b745fad950e183724daffea64a099eda4363aec5127912398c2427f1c71360730b0f643d0db6fb2a413fc1ada6f93ee480e84c48efc60137a99f5a4ea244b62c02da2bac29566ec387086eca7ed920fe71d9306de8226b863af8f318961a3457e86379204c4af487a513b6868ed33cecd871801f8a72bd037217601250c215d6aca55382498943f4e1ad737c4e1689c9fb5f144c8a65999aa928e364c9d0af6ac674fcea6a643e09bbf8657fa367b2607ed6462453b998b9614b4f3d393f2dcb3218058d81e80cf0082371bfd1e7ba1d809618e1bb51b18c835b6bfa795d8de61efbd0ef9d4d18c20cb3a993c9c9eb0ae80995ec117d85a3d2957d1efa75317cffb0bc0976599cbb6541eb3a6ae1f2ae7e9cb83f3e6d59f534faa980bc8bfd35c8cdbaaeec7113041eab06c9795542439b696c50a4231c41877841540112e40f19c66001e3adf5104f5401990dc4ad88555a6a6449a132a7c3d85ce7ec7f2a860b51098e9b709ae07e0d3caa5efb569b67e51f3412d2d945c2f203cfa513c8b47fa7892f31fe9e6c796c070c677fc5ae08048e81625caa8a0fb471ca79b7b2c832ad00e60ee4f9ce85c2cb6d706b4d2145d18ced9c7d2d4f9841004eb2e6e60882b4f0e3c94e6de8a1dabddcc744c80329123fa1940c39f65e3be17904072d299dd9d9c25817340c66bfd251b92a1fe9517b0440061dcac1fd6efd91c981fc1c903fcf3e597ac125005d46eacf270bcec0f19ac4438e330f00cbbc34eb6a858b4fe94d0e911df98caeaf707e7aed2c9a0a91add106c16cfc26b67445518ca13d6a63bc5ad167003caeca2beefa8f54145cf6422277aa1c38b0c3e92270e21d6597d60fabb256128ca5a88b76b68d713c6ee26cfecbf863ffb15a147a552c08cae7a206cf6475a6f8d99fcd6c1010d457061caa733af476c95a0ca3afa4f98f7aec3103f11c77876d43c32db5f2e730f4af9b5223260d31ecec9aa35a30fd39ab5bf1fdd878e1bcacac7d89d279671f5ee774edbd92fdf34776c3fee43b1c79b95087a0b8c2964f68612d0d9aba5a23e04df5ff60fa56477bc8e899d7754b2d756341023536bc0234e22c7fe5cf9d62f10f95c688e43e6614d9d620ba07c3dc50f982352b82b03cca2d4f4f209ac325138421f2e7f71969775184727f5e72dfe2760361a789349ae3544ea418e8b5cb398bdfa62178cfacf97b11a6ab15a47548e241ce6f0cae787ef7b3931b070a8047a08c004502cd0ca96117ed161b3f58256c1641c9d898f5b94fc8ba169620e96ecd5bf0720fdf61bd5f59bf49e6c4664c05cf064f316498e3611aa6c530f554cddd2272290321f65c27f1159f43274f3613caf40c3d2a105878207070eed44db0aa616c1dbd3c806f2218dea41aac050927046fc976acbdeb9c51dfb5ee2e53867f290b8b65e763ba690dd206ac3ed948ada0ca9349e0cfa8390e9e52a3c1618aaa28281e5a4b1a3c1f900f806d3a760f4b0e6e430f4946c3dd2e2292329c85002e7f1ecf75b910d3dfe4ad2ae368e47bb9b5ffe71be38ab4bc537ed470a9282214679bdebf81860c56f6a97ee951f92378394394d3d57a43a0115ada7236a9b1b47d42a3f1d51cbc65dd2411682106bff65b93111c1d29a6719d4c0a1572ed4b6acb964afb9b8504b390c5896531f55f8fa6caba1a4689076d90df8817d344cd2b9401dcacc9bd3fcdb2b54fbe77126b4405487a1b7bb103d80466355a44d559bbe79643b7908a86c80cbaecbdd2a8388ef9bd7a2906ef4f7d193f05970e7f2a4528eb6a5876e343a3bd89125634556d147ab627252415b08a7ba88c99da4a2637e960e7153e1f1f0a5f3a0a06161ed7038310dfa95a53c21710319e22e3d5bba6fb341f8c7dbe4166832e94fb9fe70086a816b16167b5bb8b89d84ea2650852210f2d39c761f6e3a4c13c5cb82a57ac21a99b63df7ebf76755a496979a5658c52f4cb03004e0ad3159499837483f4f2d9fd9cb9d07fc28a337fcac0a7b6d1bd49644847a710d1ea93cf9ef495beb0ec8989d6fe79ebeae8f4e39c793d9147230d83a90be5408be30bb4afa40048189c35d0ff19bd5aba8cc96cc60e7de9c22e92bdffb122ba93b56b0ab7a363479b7f506d77f182c9c7efebe39df230eaa67841341d3b900c8f9315e7f61f21e55b3eb210a8997cc453448e10d728bde87ecedf54e8ecd3a40d145705265a13028530d659eea51fb8b781bb4db9b13e5fa37193eab40a1147ef13a2b514d85966569933fbf11ae8dfa3120a60e29d593b8431a6dba3d50cc820d830676b966801eff0098c7e9e2cad5b7427e7c4c68cda1bd24081eb71c0a14b078f9db68c2cbb04c16145c697445339d8a5fb7d189f7ca03530b8df9031d6e8068d3a02df90942c7e12822f687377eaaea8f48617bde48929259f146de5aedb4d07b7652fcb6e14d3ee7654d7ab48724902376e39439ef8a6a8fb960777c94c8d1a0adce84fb191e782147e510e179d8e18ac2e768f2a64994fb3ce1062ebacd0b4a5936ae8edca67480da410ad2cd49554571bf6d1559f9965c60e41156390dca234d37d3dc521e1818db600ea2b713f8c2a1f72d711628e6d4c4c970b99a0acaa45666f1bc2b31603f46b6428226423958fe28301cc030d1b0b143142b8a63edac3864ff63b4ca6ebd708ef1ca525363cc1ac49a89e1e3ec66e0f6e206b0f2ee71b6c21bb48f5804e543d8d0c00149f0b17f65b0e6a19495e5325ef487b5f759dcc4f9024591f9093ecd2d3e247cb6ff5ae70472c27906e971135a92d67bf899ebeb95a87fdc0bb525f7c6f2be156e632414ebbb823ffa8e714929970b36d220e542f29d557b4e0991bba76aa3bfcd242618ee59552ccb77d181d84ff6fddac64f467bef635929c6b6f75fbeb30a26d48450456dbbeab693b5b4c62e5d40976dc2b5c6c47dc1c9b41f01f1e843cdd5084a1f42127e06102b8f539e997b44c9e608454a2392487f9897b68f7f9db455c31140b5aaeeeb9afce46fcd8e5e41ceaec97beac7925b15bb13fdd9749424ea930c8afbc202c9260618c56a0aa1f09c7c35e62f589b78bbe6235365adaca3e969699c0f58d0f5f2b4532f455ac7636804deb2b5e70d6b82267a31f695edae591d8ff07ed584621b1d6fa8c977cb80da7c5a085693d071c21859878e4610aa5a3feb4243a4539d49546544c790dfad7283e3d8d0e1a9ea541dd351a9c0f2795c7e64f886628e76364ce248db559ff49f0bdd225cb5684797c6ce2f23cb6db9a31bbb2062552e44ec8c8c35a533d68303c53cf7077135f688afdae3320b3ef70d513d62ecf5c2733a26c4b623d888eba504ffa88de33079634d40ad52680771933011089ac3f2acd222f1920fb450de856ad8c23496f13da4622a96fba09c1c892afe823a109ae8966e11e244663f4820507e88144213dd4a6f14b90ecc1ae834174363f224c0e92b9f510295018102302bc6baf87c1a0ba05802161b778b8abde9f09e91bd6a87b8587e98f3d365c30c6b6ae517bd2b8f0d5c4b8b5811d1c6eca0d4d20429ead4ee27cbf336a02e0659f039c9ba888a5d4e9600f163c815fc4c91912a69d7897f8478a1c638409b2aec55e8c734b9af65ac14176e2a80cbd58e458bf03775f510a2ea8f68be970d7fc7c52bfe24cc83e44b09805e07e8539e441f1f2d49655ea693fbb25ab0cd9163c7f37b9958ed7c9013ba3948ec3dc14ff53b1f3478468ef81d0e86b10e3d6bb8b579adcb15f4760afdad3c997095ea25087012bbb86c5e5afae18ea34a13829314a5567d802954f090d81a1a2b19ed2cf7c7af805947d3f65e5c10d96b4e286db8c6a627e52972c57c6665142c8db20c441203faec65645d30d0b24a072afe43f145d8bc1c1ef95797196b736c3864b4324fe037f63f7d491c247e0e797612c3dcb0d426625447140040151c172148cb6478731f058a33d2c8e2694c960d13236f2f198c44d822d8109184ecbd3791524a99a44c01f80510065d062198d1499e39ee1697ae3674e75c9a1fca283037d69e17976e8e4b372eddb8347f16d52abacea54b82fe9dfc383d5678b347d780d6af4d1b32d4b9908c3b55f84a7a1e0d0d0f1e40e252942ca3489c70fef51c018418bc816501c49cc82424877d8493c33ed291ed77f45e7459c4c6923dc5e9f85c282e398dbff4299f8c2241ff204158735f1212bab23e69fd5af58777f515b9df0e16780929551188d874b34a551f3f021173a293ea0b85a4be1087281211492019742387bd24857a490ee990444288c426a7991f8f9056909948dbccce732291e39f9e53c469668efcd94b3b3b3e7cd4d4bc728873fde4fc05744e9c41d3cc07c283c693894df88bb24a936ac68e4d4b373645299384a6fbac519f4aebdcb40e4c9ef16b24e881129c552e21c149619d13856e1a27064970b64e903d979696aa27a94823094e2af83b36bf53affa03ac1e7faa0f0343a4f0f2ab0f03ab4f45a0a51bf06a95fa186e62ab0f2228c65e90b1ce69229e1282357932f9bd4c91c97310d071f327cebe994d6d6e939b2fcf7da11098dfbe1047fb421dd944cd3b311031600ed68d0e980f2733c929a780724a647226261cd2ce5f793289a6998f3d26f27c9507459e9ff29ec853aaa09bcec873cef99a3c6a9b28d8bff9364ed85f7ae04f7b6d332795c844a5c11a5ac4bdc029dfd76ee4fb9e848b6ddee9dd3a65fd64d0bc570ee5abd15713ec421497f2d43a37ad6323dff7a227f95eb7e1ba0c54c07b5fc7151c3e75699d9640a17cc235e4eb30e40b24cbc831378d95432011ec34f7be8e24f0d0951ecdbdf1c969eeef24915b2a6c483e3949f072915b2478efbd7fef7dea84024aa588505896435ae726a3de1f01453c87f5de36de27d23a9ffd5a1424e80ef3ac8f30cffa97edf3f1f2f9ca65080acd976f727ea1f5ab521997b556c9d43a38727d9945e234399013752ab5caa71aca2abe49efde5a7f52b5fe8f31f07bea79a436e592e7c4a55aebd24c6efa3349102cc67591ebc77013ebe6114a2d3f42b945ae7f80f9a92f895c6a1ef563b831ee9357f417dd413870179cc6c8f567106553dbd42363600b18c9d24e4c4b4e78c969eacb5a5f7eb2d6fa77a349a829b47ec5ae3c0f91221207bf4c41e2745e7d5782734a2e797a39d3feb5107fe48953bc18e5087796524a2965538e3f656c8a317e0c0b86f3895c785e6268bcfc9639301f5e5677837af99bb73de7854832f7f8b7d4478e7b2de5851818caf8571fe2e8adbc30fe26b5e4e87556a5b62bc1ed93a8cc1f85bb4a5fc9324ba88297e37bd14ada2c362cf0977bde950248c094638e9f2bea70016318d8169117628cfe0b3546bf8bd6af1a70ce9a6727c11963f4c19bd94984ae97386127f30a830f3a91ac81d62f2d88130e278edcef1f81340cd6cdc7a8ae062ccf1a04984f83947c318904a78e1658be47a127b4fbda56635f723ed6fea4f6a95669ad3ad9fd7e698382845a6726079804270e72046250ebdc845abe1fa3cd16f8ba7fd36321f36212267c3fec2ef9eab0826d0e63500cbaa89ba16039fb9bcee958f6df39f4b3efce7016e434f7b36c6e3106dde7ee76b3fb395a707dfa52492624c12009ded7d102c70b7471506badb5d65a6badb5d69d17f0f4511f2673ba46d6af3568edac6c639ac67edb1dfbe08d0f98fd583b3760db2371c25b2377aeb5f6651d8ad6af700ae519876ee4fb7c9811464be459c5d5c56e03744efd8e489af9f36b4933259d91c9fcc9cd18f8ec689b2e6064f1804b372403bcc29cd348dbcc0f7203bc23cf9fe17752a47c7977b40e114a3f6c443299169840055aa789481c21d40f5afd58f4d5c779934c24589ff3349f5187141ccaa12223244ef8b5861f5091f565945a67adf58d784e2cf206780ef7b276b1c893c8fad5bf56d9d9f1e1a3a6e6d5e123222a3a473e699afaf10bdba88d8000e1c18386c693993b49640edae47c88bc2063d869aa4f103a92c00d8847108834f5ebc51502314712394dfdcaa554a8fb8531865ce517b6195f88fd0bfb06b982396e740ce17cf5432175c869eabb1112acfec52209d60f12843f689de84920ce2cd3b54dfda1a3d03514bfbe64da9cd0ef9e3d7bc65f21006de32bc4336c6a7830c13539352f89a335657f306f38fc9947e2641fbf277ecf15d85fc6cf6aa59a4629edea1da1b9669d75d7da24a80910932126421db35293a42112272a3539caf17b244ecc1da3c0add46428b712932eb7120f55324f4fd753041ed29f8e15dcac2e66c99e6561918ceaee969f798ef28ed06e7fb9495005b86b5a2795bf2e58fbcc53e5c81580c6b8cfbc54febec0178c22c1f8028d71bf7d4bce6b399719e3be9627b54d7cee93c818f70df1d3d9a7b48d51ce3c07f224128ca99ca56da20f49307ef6b9ce1658fbd0bdec519f59cd6bf9288f4ec9f16dfde8b749f008cdfedda69be4acd05af5e56e226b2a212ef9882c2195fb9b6dd35a4b8f3d1fa0b994dd524a29bddc438829a594d406cde39c34f6a33a1ce2af7ee571231e6e07cd0deec8b28714cc93a30d5ae83260293729b19452caf8f325a5943e2a77ee4e822e039ed371777cf9949dcf809bcef614543bbf67cf9e3d7bb677ad29b451ac7eed3473be57fbf27dce49b7fa8aeef4e7fc2c0a6757dbfaab5ecbdf6bf95742ac7e413079e3e0fc58bdb3be6637ebddaf9e9d41b8049be74701cf415ca0bef5826eac3ee55298404093abef5ce75670fc195163482399a1ace57ceadb5747a747d5c845596b2f0a752d145466efb562b3d6c9d16170ed2efd4481c36b0587138a0a70788f7ea0f84901141cce277078abf8e04413389c4c18a1e0043f4f7e4cf0b3c44f097e94f849e287ca0f123f47fc90e0c7889f11fc88a0081cdea21f703889f889f213829f217ea69490831f10fc7ce047881f293f41dc13c8f7978be678b9b5d65a0bc8157a877c0918e1c077327865a425d039f7e50ff19cfbbd220e597e1869c832be4046762feabb9f7cf97a6d3d49d81ff57e9d464671a3f0e9f3e71439023167239e81fa599ea86c4a2394920c70bfe756e2e1881e1b70a5ebd58b293ecc109b4193143c0ca1b0609a5b89071caccdaa182849a980d954a8589de78bd74b8987201ab62de6b434a5c70390b560f55e2cbc6d2c97185dced861890554a476b042c50e24484181676ea51d8a90df8931ab68fe81d04347a5cae1a84639554e49cea3b165742e5abfc298c4440f3262cb0c1272bf8d25389c7e37ccea5c4272bf0842b44e8efd3bfd9ad571fa1fee0b48eeff800b0a96fb3fc021cb89411fd07072bf4f13db0f0ee623f7fbe40087372542ee6701a1ea71371eb9ffc58895c4097ddce47ed991fb593de0f0c2e8a8c2b239ca712546a726f7db68824608b9bf04306a6c0d42ee8f36e7bed8dd3d3a0dcb091c5e193012f53499f9200ef9ecd0ea31845d3968b0f1bad141949223058eef48e78817b20487d7fb249f2b1f8ea497130e670777c3acce95430ac6d33dc8d1fa6006e9081c4e5026c988a67b72754113b71c42cf110e6f4d8c9310226c5832e8d821c20c389c37aba3e601848a1e2a114a18c287116c8a1fdb8cab09c671e56449304960373f1a00b275eb5c2618149d6ddecd1564a747d2f59c6eec397210b25d777730bfb4c0a8ec5f8881fc01939984da9cdec8d2655facead9af5709567a371c7bc7dfeefa0dd7fbcc6e339f737ac434bfdef576d6eee636254e8f0af094e0a461fc9c342cbddd2babe8c10a9f1dbd1d84b2fc9e9b44923d5a80fbb56864a99f8082f0141a002961022726563419341081123c2851348496987c23f22d30af2f5d26dc3480b6a191058e1ff6148e4374797dfa7b61638165d251bc72a4e3c43f87fe7c04500f014e333fb9347dfa17caa42b615ca32a4b4870893c43d0ca8d7abb65fb728b13156badb5d65a6bad658a4d96842cf83e7dd44b26bf17b75b19638c71cbbe6e462468ed872d2c41fbf6eb23c9d65a6b65b4d65a6b3f3a90b5b6297a343c8018d96a81b2b5f6adb5d65a6b330ee838c1f5b51ce8532e53ca45e63c75265776c14994b8b2908005964d4c710b0d9f042d78a29ae8b7a372733e2b9cf0d3193361a727a626ca23b56ddbb622d91fe5d2b3af7948b2f3b8114a29a594d2ef98940079a9fc6a82c3bbbac930996c652abe419a709c749b73d6ef72c0b9fa5b25028f80524a25a59476959452fa9476a194d24929a594524a29a59452fa744e4a29a594522499449f4702e00338ec9ea866a98e247064d22ca594524a29a5b4a394d2a794524a29a594d20f12848da4ccae68fdd236edc3ae7d37080cf064f9cc71495c2214633795e2382e02e56dd3344dd3b22c43a150f75e6b6dad95523ae77477296544b28a2910dc8b715f89495812c5033b593eea26084a19f70322287690514910eae84d06ba7b5343d7098941272d129abbbb37691b9f3978e82e2593b6f15a6bad40f4fb1e8777dd742ba58990f67132691d5493d6f13eea60f8068c4ddac609171e68b0090cb2c70e78408b0d1d0043c88616c4c80ed434f4379eec459ebec0dddd5d6dd321a5944a8c557dc37dbd34910354e64f6c51a4985aa870473fd82a23a0a82a9c88a2a2aa58e5568252c44a8819e6065adec4a23c1f92e6e65dee75b7eb1982828675485d283fd832923a5b74829477a82a4d45176925b738a1641529281b80a2439631b9957c18238791c32e498a48822ac3137552ab0c1569cd64d433040598e68396eebb546e251faec84839ec92b22e7e0ce17e9b5bc90725b815f84084aa061f7eb02ff061c807fba40432cca2faa48806efe980137d020218e4d07c022528dec06e7cc07a96243d19a2a14707a08b5f8fb77b7177332c5d70cd7da50989133409f104cfdc579a7e9062bb01a6b9af340dd1c87d85065d5c67de2a5d743a9deed49dfaa4747a479a11a169ddf736ee96d2a9ec1a65ad5fd7f9389a02a1c57e30facfbef325ceb74d04a24acadaaecb285bc6289d8894767737abbb375add0b4d93f34e29dd674b1c292fa559d0785d95ceb6b1d6c6ea2eeaf4da4ae984e2b2f1f69cb68911a53fe94b56aadd1be3b4f66bfbd3d2ecd4e7ab865a4675a8796da5df8c39dedec0eac63b3de22f480af095f1cbb8766927d3ea6d271830986c01f862e1adbbf101db99f28b3272362387fd94e54d965898a004606481050f1c8845800727acec00e5880644c44e40d2c20b1762f0c4921e62619f61431355d44084851841b1b09d9ebc209f67862c959ee090251106732b11b520bfe45622528113f506aa45ae7a6cce91d01875c03b9f0f9812a22a370a2c732b1135d135e6e9198282121112b8c3915b8968286fb9958894e424dc391590a2c4c88b22c06092438c0b22259ac881942a3938993264451124c0b2022e68e8d1e1093368f0a2488b2d37ae2801069716ec1043164234dc49e111aa6169a3d5acbdf86ed86a515a1969a492be94f66694d28d3efd967f3fa87f97acb1b29c3aa5946a3452c9096066f12bcb45fb45ebd314f587d0400c557dad23c2fa02f5235c814356aeeff5eb1fa1d9fedd700e8c88d447407d9efa436ae440aeacba7dd6a22eeadacf5e73cf6c66ad372ac660547f48fd224a2970ca954bae52090a1e72b8e5252882ea93029048e229600441374baef5b1b5d606a0b3e45715e308d570adf2bf7eb8d65aa59435d3b4acf6c800c7ef7749e9929b64892006a61fb23a970427d5be10f7fb53af957d3f2df9fd64d46fdc90ceb4723ef41df5d33986dd316679d05afd32f7abb9fe5429c499311a0aa031662216513a5a31a23bca6f294f00b37c192313ad5f8f4506a0dc58829c7208b9b1042d916f96fcb9b1c85025274004b8bae65bcb84f94da7bc1bb5f6e75301749625c8e64ca0c9f2bdf9b9d78045862879951b8b0c42598b5b6bbec5eaa1bae70bdcdf5e8bfe2ca1451fccf62bfd4e00b375ead9971f5b15eca75f7d30cfdca8ad694f13a6df61a44f0106849d2367421dc07540fd5af5e9b7ea770298e983997ea004a15825315d3103882b38d800136710a9c66012061726e8e2882074381943894953182e34e1945dd04a81c6e4c71c846c21469d17269878897f83f82115ff4a99314c64e8e0e474032be25fb985fc0e062d7a5092c34ea9872439c69b17e056728294c3ae735725a763f1051c4e6e00dd45eeed071678b240b6809cc8004af282c88c26d7c91000aaf0e2054d4218a1e5078b7489989e8830ea0209c9b24e10c318590c799143162e0411e49485480b0d1886c5f282482102a358ccf2012a453118ef654b4c73188f05ce4a0ce6591e0b31528c2146512c46b210038dc17c0b538818eb633c165a90482cf1141bc2bf97d523c9f89164d523c9a947b221c9d923c9a84792ef237924993e923c1f496e4155c51531d63b19d83f64799bfc11ff65e54950e54950cb504ab22f217f843847399bc6c47c2cb41063c1781da331b81214573af9180aa42c9f2535154601fe1ce29084be25f847ead43d729b045f3e4d5114c6132c3b3cc1454c3eeea6069c38e1e1894bb08afbbae0d085328fe7d4488f31fe129cca611b7d64601e4913ff5e8ca3f615699bf8da6a04da534a842538fbb08649528ddc4a4ca404444bac150c7eb9b9aa1bd88d0f18171b92a0c400872c475f3c41c1a227064450aec4d003c6130c3d5b9e866658c236a66c2125873737098cea41cbe1de90197177d074c882c864f880fde1089b05ab9c2c11c64c348c19d42008a01a2c11a306377051b1a0cac093051c0bb219381d362b9e8830b212e94cbfe4ce3a3a93695a96c9b874aa655b0d2ec66767afadd3a98ae5944e3be74455778aa2b45a0c43ebd3e7381f3a33ee8478c61967785dbdbc6c9845376a6985c12cd5a4d4531c0a48220dae461687f80caae5b271034796bdf775f0315b10c1ee560bd352d2102d93d954282d4c4b493030256d99d1368ec6bc1b76cea9b328cb5de5ceda5e22cbbd0488a0d64aefcbc6ea66b5f4ed6b29cec7ae5893722bfc3576907b84c85dc24c4d4e3b72baca4e7ef900ffd5362823c2f0f46483326c004319b18623260ca1e20a1f8284c210138650f10591f923fa0b045f1ebc6c7e8c5033a3f79c1d7bc54a45c778f6363d86bbc2065b94f10591197dc80d0a434c18d2548cf0c4163533fab6a156afd78bc6a66532a899dbb2313333d4556d2849d265aa301d06159c8ca8f00015da065d060c5ce447231227ce9e3464ba1a33423951faa41b8ef6a2e6c79a5c6a8b5e67c99a0aaf5e605831346a64a86b6d752666a28cecbcc69c34684fd68ca9ed62399d2ceb13e6f67c41b9bb7b8635d5d6298e4bd5f8b6a98e1c9c73fa9c7866ab46bd340c2b86468d4e6666762bd5405e88d227adf6a2326de3522abc7a8161c5d0a8d1c9ccb45c366ee0687dcb6b7d33b382371666dd4ad8e3b8f17520d3c1abbbe9a3156c090683c170e0b6f1f2a08607ad1c346211dcfa2066561c42376c0ba49eb166b5453c27fb60364af6dee07cea1436da05d2c018c16044d080f00202089c8f87b09a95eef0f8d0da0a01d7d46c359c4f6dd9a89c47facc0f56056dd9a474e8d8c1b95a3b6e36afd4b1e319d84d8b8756a4ebbaeeceafeb3a3a9d478fcc0826c3f5408920c2f5e1e387fdd1c2c1c9a1365c392d18cbe5957aa55ea975c15a4026f56a8f680b069b81c1244c274eafb4d219a4b5c3d4c16030d817f11cd8c36030180c2671765aad140c0664b325cafeaae5727fac8bdaa2f7488e68eeeece72f7ed4a6d437578e3dcdd5394b55dd58657fd82eaf006b375dd8d9bd5dd31346a0d4a4387baf5759f94561b62960469bbf0777747a0ee7e3a32e79c734e0abba13573ce39e7dcb8940abf70dc8d1408aa0ee31508301b2ae582d5d62cd88d56e79c73ce5943aa9ac13956ac970d26a6bbad5b34b6f6b41a536686e0aa2167b66e1b9ec494d239e7f4c23893c3dddddd0b67b217e6c8d25936b6f642df70b88c6d83a65c388e64a2bc9dace1b36368378c8d38f305a6052c14be3f71167554da96da26c76d38cad4549de15e4d0be39535238d3b6b488feeeed3dddd7da6c68a3aebb45c4a8601d93f360d9d992c1a314f68c4c05e1d8450d32da174da5a6df540db71c39a355e494aaa1ebcacd4bc40b0836969654dcbb2c24e2b952ef1f0a68289146faa146789d4a982b7b0827979597d2192b9e14d534149719b06c55a28b35aa73e7ea87ee0a42cb57542b116caac562607b6b90c4cab59d60982a21568301625521b2308a9365c4248a035e6896b521abd317675d3e31c80b476b6680c0011cacc8be4a1a4f54bebf65b69b51795691b9752614eb562c5d0a8d1c9b45c366ee078efebe0e5418e0f401a77a7984eea208420631d26e6793ce0082063301f8c061cffd54108355d4d0d1f374d341b1a3a74ec88b9d55a6bab0737acbee17c288fe9ac5a2bf52bd303fae2d163be40b003ce84997b703eb5ff1561bedf6985f92292cd5252079c0ffd221292f55effde8e1d9c0ff73bb00fac6d454547472b0e3fde92250a4d89539c9c8ca852bd4553a2c2b66ddbcbcba669daf6f22f1bb72a3ae2360fab5253b86d8acc9f1951d24e3888a89024ff864f1f3f5435e6074e8a62dafaf183f3a9ff83fb9119d5f35627237187ec24227789a98948bd45465056884864129af1299303db64601a904c27082ac8dde911ec151c13c2c608422ac5365c4248a035c6d522816763b9c09565cb166d8bf2e4279ee8ba9933e7633fcf58348a545c9a8d4271876c1d8f37824912944b320ac520518ade21bfc9484ed1e24a406a1bf934d600b8828484848484346700b0758d991c2c30be6e24713ac618638c918b31c618638c318b31c6e854728c31c618638c31c618635cfd9438206095ea539c8f2a9fd8a8a46ddbe7d2a9990100000153160000200c0a870342914016a681b8b50f14800f638e3e6a643297c9624112c4308882186308218418028c318428c4945155e60467d84e991b9d893ec94aa9402d01e7c58fdaf601d803fc60699d712540198daf49acf35a37ca5914aca039d8a2a7cd2e1908798798d683718ff6b26902db5abf0f9042dab34b4a2697974000feda67b58e346f8b2c295905958f39d92753291ad0f8c9adcc4e90b74da889c27c2a104f525bfb9c25377e179929fcb5f8d158a9c79c7896e03a3c0f93fdfde1c9f43addb7019ee2063a708597d33db8f3810a88d3858bcc61f15caea3e8c96735a3207c4dfbf96f683e39dee7e794ab30ee9cf14fcf6bd0729fb83abdfd4419040522fb937a62a663a979eea17eaf0f28537844a5722217cc31b22380a98e68110aa51ebdba3bc0311da04c6376d267060f899ec06882b2017e40d118a87789c39fe4e02d00e3273dca89c3677121c5b8fbdd87186e2a7ca4ec6b69eeec01b837fcfce4941908966e28063b04031eb03aad8addb9fd4f9145cffa87c488d1d50b2fa347a3d490d749a5b1771d58f44aebb401ad7c451c69dc8848fa342591ed326200d1a1cf69b1a53bd266dc3c6237801186cf6ce14a9917ab44878cad4874eb962f957270d5700a1a2db3c208f124be1ddf4fcd29d44037a638a6508c2ba592e0e956266285889eea707ba81b4d9f52878167187b85fe4afd1f96e39e57972acca1d24107ca0fbb72ca6253bf22267b84ec4c4169280ae5d20a213e8dd8e9c14ca8690c1cd77278beb5b0dacfdd4114522ee125536915bd50e3929064f8c8c1258631585a3d815ec91adb146413fc163286069f4983338ead76148a6da320b3f5041048b430a2ea939c30188444218bfa05f299fa3dbfb6a993e2f548b40416c597ed224e7bb2990e46bf55b2e49b6fba68c0d90a60cdc2f5616f32abd491aed2340e5a89b2eca2997480bb92f55ad2ceedd7be6f83df0f7b1275814dfe88016fd818ab8805c381769000c1605366a6ea2b025eb0e0fa3b4d8cd336c53152e7986c8046f15c39f914469defefd82a631ffe9121a67e5fd2fc3693863caa815454293c51300ce421e571551d2c7827d8744af004c5b69bab94658d6e35d81e7b924e40a2cef0341069efc263080513ba9401dfc2bd5b616a5cb56257b5d094a60cb3ec3b2041040b38a2196e2a685defa877e85812dae127f497a489c47675bcb8e3100e29a00dd043fd4f4863662a532ea16a885812bd49ebd91c0be6abb90b77ce53474495210f3f5cedf9e66f877211e8464af8b40ffd7131a719717755639b566cf2a7ed8e6004ec485dbb69495587a91e943535cafb23b99ddf52b3974a9e324f871382d6a58444b5074675c0b3b273fb5248a24d3ec73ed29a304cc70072ac5e183da8d4b45b01cdb20f641036e643fcf1a0e74a949776a5785fe5f1e7029c1bc07dc6721e538045c45887099921171bd18c54071134af96af8d1bd01563a051232499138c1580f8840c63670269872083370c1698047cec28b79289584280081aab90d4d0a6c1bd3ba04c700316eb5886793a66af641544554c02d1d4dec30eb13d092703a2797e0311e041c3207e9cfbf6d20bceeedfcc160c090e765ed6c0e4543879a4cfb486672010a4370af468c4e45090e5405de95e62922da4edd1b281ef3f055eb0578d220b9de186ce899470f3d30fcc120448f72b0f04d77f82356b92f85d6f3219e29b6630fd8c3809626e7062d3ce2fb8d297c245387ce4443b8e43f4c69e3d52a4f9d9a05566fa8ea64565125863cd4dcd30ccc7eb21b31de03b45b95228f5476be7d6ad96b86517784c900e48d150f068a5cfd92f7e266d8db91262c3f117d842067fdaa06b3e57ea60cd9ab7182a205770e63b8b2b3446c9744e8bf05da34032ae00745c1ac3cdf9113c1d8407870d537c5f83afc22cb9b5b401c1aae9c4e25e942cfe788bb21ae84844b58cd77040d73a6fe42bb2d7b3355b42f8f8e72fb7c83753a82266bd3987e0b3022756f0ddc2c83a8e1951d064cee5059904b156eeb7fc10e0dc5372aa5cae973003fd3114335b162a033a54a6de3e9c00b9f0f8dffdd266890d1b02c7cc4cd95651c5d4b64c2b581967d3b5798229a607afea5b24e0a2d1c3b9a284ece13d346b81f93443a4f9d50bbff798162eed3fb9dfb39cbc40d6dbae8b6f8b6965f24dbeb386b655acc16b463e415cba2db8ad5e05472a8a430659918aa370346c010a9431439e8c97c1b8b68cc37e09d33832caf579f9e9022b0ec06db29ab76ab743d2e2d674a62459d52731afbc958c5c5cbe64e8b5e07f442d82b9a2d01a05768a47c85a52d42230476640484abcd5eb92572d04624e9f79ebce3a2c1914e393fda28d4bab978114bd1a95dd1e95233c2241fbb4ce4d609af4c599d384757a2a5d2d156babb87f74134c1de617b6db5638365b1a7499ff823d72d0d1dc4179f89ae47037f55df58a648a32f991be08d3be33008ff6f22146f081386371626bd9ab28bd6cd18395b69f9e7c3027eac23e49d55c23c69f2446c90c59cdf94d8c14a460b685cefbefb0b8ed55dc45b8d6d60d74e37787cb698ec22ebe58a987a12839975d115285e8931fd368d6e9435f6b3d2b9102c1083563e863092e848d62afdb9e98de7a7c593d092a5994cca51a7597bda4e2bbced1a0eb80f7137f0a20d7dd91add59f8a70b71c25ba112ce6b55d07496dfbfb58afc43b7e45e97db4e3a25ea356ba47955cb893ca8e3887638db2e3ea288098ed43fbdf405d9a7f5442cfeb0d7fa3482103301396cdf8bd6d55744dac625ee83d36a2b9624bedc77eeab67c0344e469e34430ad219a2e699720178e3cd87708e2c803aa6108375f9615efe2a878978286287d6ab70ab96ec33119bade305ce3e203ca45e27a4b2d61a55d9a87a1b2388164681d00fc1ffde7ce237c9b4468eced3c4339663e53a2dddd209bb99b9db966932659f2c127a9432e0c61f44598cf62a7a5dbead3843afbe90080d3c14375e57b1b7e2ff83ba964c08da0b7a985174a89995e82fe712b33a8f6c8d8b604caa8ad5c54d1eef7b7ba382c7985dba1513351d535960e56715cdc4e540e6c38611e42fa5b1231f37acb8b924724592f04dc3f19fe1e2eba0909e5a37d0585889cd2d8233b84c222b52e1d2e9927cabdcc8ebae06cdba7867c9fb6eaae0cbef2e56860a0b87fb8634d7642281cfedd8941928e0cc4f61648d9fbc913898bb4d37c40c8d1a5d9985f4266d03d733a4020a8e49ccd3c782eb9b68257366c1b2456f16b78e74411893441b4a3c8dfde674e89b9528eb895841500ae27785fe654a149d56e9e49b8a54e50e5b15d898c4d1824dc0c8b26a377e36ea0157099f4dc6fe9db50e0257d0a0a3a96bddeccfa27aba109bdc14b7b1c4d1ea296fb54aa20bb33146b7168ba13c43c1c604564b690ed1260db437ef9b86f0bb75e039b59be2f86cd838f0aee8225e328867412a7cc82f5678a73d066b3d608088291ccdb290146416e80f8dbf80f36a31c5a72713bf3fd5b735181eb216b56296df3421b8e397a160925d16ef699b73770bf317c9447a5287ac842b19b0b594da1b63210c8e13a05c023590786d2cf62b0e3145ca110b398426437209487a82f318475fc30266a43c87f78ca67202a684dde3044f3e6d20eb3ae509944a71fe3ab7fbd53aed7c502e952268dd1f6f9a932448a72d18a1f5bf9e56ab7edb04f29fa7172139dee9a848814ca28ce6e124981575e9cfd109802842cd21925dbbb40d773298a872ac4a27338558fe6e10acada7024cf6a8d4b3f0eeb36699e416af9737a9306c61dfdee6d1b48671fc3aa74e50ea16750a79ae5a26f34ee5e7916bddb5455f849c0fbccd13c3817a4d56cf6c0fa4d491c1865e468dd261875a268bd5006dca75d9625c0358172425df5cd97cb0923786a6103ddb3a8ebe310007a66d77beb1df18e2eb094677098b47fbb8584ff47cc6e0fac689bf941d4fa3631ac859e63acaaa8e308ec05d6744361e613800af631eac0404d792972b9f0e31c82ade05b875a813a62171d248db7202a2bea63a42eb1e347b461041b77e0fe68045d92af86d2fe25a2f5c2a5139e8658ab32c18ce1a83dc45ca8c255617ed2c50eed42510512ec418b8290f45fe4c904c0606a12a94e372a9bcf732ac058dc71c36c1818578c50a987c0b643020e843a09c1ee27a9cc772c95df4f2803fdbe7c6752f049934043fbffd97d30bd85dd1789d04c6796de9fd1f9433b1a4788931a13147036e5813574c803573c88e37ad96cab7959da476ed644e396303234f983b733f443cd5b8ecf060472792d877a38072d3d5f11c369ab5207d91ec67e5bd1cf0f6975c18506d7314bd6f569528d9bd05ed89c201e809a11d0f939d249a0339f45ad54484f0895e2cfb5582b5c6530df91e2d73182cce5ede84843d13fd5f1d7b4d41e72ddcff4af44950bad96e47f761c9ac77e5104fe9d34ce6e94ee76af93b41a430a351a85b09e286c12f3a48b79e89d95236727c8113b5eb991a021d043d1ae95023278bf1888b0722f71e1f7823d196044fccf524828f8503de3f0454de6bddbe5cf4b774a88be3bb1463cd8f7db4351c833e886d1b28247f8495bf82c58d626d66fbba1dc665f39d405afcb0b47f25061d8474a50d3eac2cf31f2cce064faf8339d0583e4c17d79a499aa449ec08d64d91e998a80c94704275ab919f68f8436fbca72a8d3c832b39b911bfe88808e34083e46e8b7028114150371fab82d7717d34af581c2f48b30744cc4174cfe15186597834ca14b6dd530e0d41523a0b6c982c4c4ed2787900c4ef1dbc6e9d151571d774116621bb4c8c4f907ec88a17745184568582260dc0fea7011a8bd60b777767f730d68bc130ea0d3f6cd7fe3b8ae7e9ee6a12c57a484eca0c4aae20614c5b0f6775a49c4da5194723b3b468e7743d71951e9c7d11c645a831481770685907962f9a89f6f5aec8c2fd47ee4c8bd1572858d45f78b7c1322b94484269b2ebf89909e7a20677237f6acb9c55f706048afe4147bed5393d01983a6893d939d51a29a41bd041c5b8756dc3386688885fcdb03519938480540f4f5d968032c71a3b670cfc4fef11fac1119ebb1a0c280d84bd1e2efc144f793bb1547999f6e6cb9d9cef76dacdd1bf0f1dec7875814087727cb688f25cdb03ad5fd24b8d582793b5280933803dae24a8482a1c6bbd79c575ba63cee8de9433a6cfc01f64704eec4db5094fb842d3a180f8ade1aa0cc1bca58814b9868ccb2f3bea44a27f3a20efeea67142755085c94c0fb0413f21b9c4b3c0858e6435106bc5eb580b9da58ef88991af47bdd505d984335cb14bcbb0902f5c90931674c7a4e781c8246d5106aa328da01c06c7947a760093d05f914341f0ef30ba799fd2f7f50e17894f3b1ab37a17968e2d6b1ec16692d861bd5ef40b2517f0b154dd7c96baf27018c838806d03ba92d02c5814e7b5aed64ad8592c7e8c462477fd2492959799af3dd7c893ab125ed6add48f7595c7eb8949351c8882cc235e9a03cd4f609df1d4dced884091684023e54809dde1aa3937aa5a2b3828df37f4ab74ee1cea1f6fcc3a64c8340cd0359f78e7cb6967c8e2196fd01a54162dffcfcbd53dc2f84a9c1aadce39efc69edf5fd4b98cff6f12abba34a5fe84f124fc5c86b7c7fb5a07e53d2bb32557b450be99d268f6ec034a92c126f63f3508d8ec55352c8816fe4bb366aa838a6956a6ae2c09547c8834c676abd429dbf0f30ae14c34c69258dd1799cf1e3ae50df3d59b8d6ec275e3a0783ae491f90f20e057280ab727c6ae1fa7f112bb95579adbc69178e66aee313761f98e57cdbb6ce794c85e7c239e289e69412a3216ba2ca5f71654833d8a911aeafbb73d1806dae5b17cf7c41f7c2c5e4de9b87c87eb8267cc2bfdf3be8df99304f4161f1948fe4a00e5d9aed2040c0318a20d57156a65e0435ac5708a7ad688c5a5ea4d3fb07ad9f0fe45cebdc96e7964eeebf351fa067853bdfa2e801c0d04f711ad80ae5e3fc42b93848c4718af2c50b8a3e66c799f81214a1b8d104428e7273c6ebaafd50e7c2569a1927e5a3cca796eedad6acd63908fed30900d32521b1f8c70f9560e2ec5e8c371064061b5101e3de2cddaa2905592ea36cf1fce723e161be97e30ba5c37edf2e2540ae8a4aaf69242322d764a99b4d0a2242610019fde458d1665973b18a60a9ad1bd6c7e7685a84bb6adf501b3d775c7cb7de5cfbb0a3bd52dfa33724cda5a84ff170f59575bc977dfc987fc385d0ba27c8e84a2892a4b56b1870e99bed0985b31b8d20ddd6ac03d2527fda11c5d8793e463ea379c7feb64da1c01522388d3bc1bfb8e7214efecb66461afdb0c9f3e10f6c6478e1d9da1a5d5b42d8d4909cef97dc680b94ebaddcfeac6deff2c50e42c076698638ebdd3ac2329b9449242154c30f39f3b58a2b2e8636cb1f96f9f2c92c62bdd584b22b2f346a4b13e1d25f30d497e6caa6cd5223ca9879d9d509ee91de7652cc51a22a7f6f68dd0265c964b50281e4e84a2cbcd18e8fd371700d5228662256bbe9ff26b66b0c1c68e6f2c25dc7d03514494106e2bbd555d509c2ef17696473390413366d89cd064fa8056efc0f0ab89086c76c6cb36216dffe00d207f95caf7394ae65684e09c717deb2a1eb76cd0eb0e0cb001c170300447446b2026db687989e51d6db7cbd2da8c04f3e991b650768b23d2450b6bd2c071bdb432b435a5a778b649d094cf70617d7455c535d1d7dfbe3f994276fd3ad3de4289105c5907da34993682365c9f1e1137deae4c772624589bde166cfe5aebdec5acd1544b7514b0a5f56ba1d0c74f5ebc9b7015498f9d2be41df21f4d2d2b265db9e40562d1ba0df59d2b14c18a6a7b78f00fe85de666f03c0b7fc5e553efd8eac04364412c3d006170e17cec1d97703a0119d447fbfb8e230d6c71f9ea41ac155039145b5095400f82f6eb3471db58a0d2daa3af945ffb19c0baa292bb89d1e1588aec2443d8b8a046be8f32d8a6251522ffe0ce1ff216443210d0050f0aa1c7a030c867a0db2e909ca85d5c0436400a3061e87955ac34c888c19a8066c9145fe02eb7adc93a382d4223b99d0236b0489e5e732bff8b37d28b8745192156f19eb13bca338c3973005fea942f6756aff2a143d7cb09fa24c9227afac8ed493a83011f40c6012d5a9b5f845092c32f51c85a0c6834f86ca83669f163486ca3dcc2aa087f0f270c2552437a0f3306bf96b21ec73c4a002b414c972b37b296cc37d4e66dc1e1b7dd5b029282c52e48071a0e347c08ae4690c8349dadae6e4d6a1cf0b6c969e56b4ecce1f60162961b9bf5cbb9eca5719f45b95fe91cc2ffbd2701a1c5d5d3ea6a29ecb5979e3ff80f339a9298762625eb04eee7d6967c3332d391fe33e6cdbddac8801366bce19cecb4b2a181d9257611f34b2f834546c5626f24f73f54224093ae43759689083523b663463397ce10d33253e62f2bb82618b7fa38c6f893400d6930efd8cd9c9c2919846660d98a839dec188450cd007a3c100ded1895e8bee4f19d27a3fcf04484d4add140c051fe009f049c3cb8e15771e5bf77455620fd5df94d0f8f3c459463c1ab7fabfc690cf9b766ec581fee763f78a15442b438ac4a92132d4e9e8b0cb35ab74339ac0c34084265fdf8d64f6791b100eb286787dbf719a81f19af2c4e3f65646918527253f376c50532dbab467ed952bdf28275378014f7744ffcf7113494907c3f67e74bc3c6e284a45d5b357d0df0950e1e088b0bebc78eb5da0d2f98a2bd4455a2b1faa603916370edd100b2a5260f69a0b95a9a1733241ccfa5d432b4f058038d56ce40125b736b53bd43af3278437a03be3270bff3614bc34b43bd43af327115a43e756a2c98297554f14d6af1ba7433b449e340da7c33eb02b224935b91d987a10f8d9e7b76ca4c85435a0742d0e699eb60588419614fc05593b13cb98ee90dff5d675e0c40d999d2bc3e0d78b6ac4c5adeb90c6e647d2d1cf86d43914ad868714785eae1ae3780328b0db30926f2dad68a7029e6e329cabff753435ea350a6eaadf6871498f50bcc9e023112743397421d69d1a3ce141ffb22e030b25a9257d166b3d58171475bf8afdbe5e1cf84b61a3f132418a829cebb274282bf92f8a5d1db36165c25d8abfedee3fc45bbb78715246bf5988bca67c0106ae19ba2e5175f4b4c36310abe8a30d2692e4fc946a1120ea8e1bd7148ebca51f78fdd4c22c823c36286d9c1eea5bcdbcfe78e04e0c4e138d4411d31b4520558da33c135c101d933acc88ba8e1c1a118598dafdfc8e4988e96c6c0f86c839d2231fa77e3144bbefe3d074d44c424642930f01823c0ebda0724df845fa1b66182577491a91bb9614d0a40fad050aea93b5d3ef216c9b112d61a50801f650c34811b30177414245d146d4753b280ffa7e5a9da7eba92c061aa533d5da126d04abed40534476dd618e96acbed05e91c81b213ff204a414504635ba6f2e4e2031694dac24dcb88e27c95b6f837185dbf8b29275af891ca97e713d6e3755f6582454c7e47df5a4a8d3ca76eab41d29c272d347abaaa280a41abf82d5aa2aedec4311581b39678035c936013efda69fd9bb958a6d34cf186842a7dc4a5a57ee056f2b3bf9209f6868494da6d4e38f9bfc7b238c941424ef64e34f30d12892e245badc3c2ad17f49483c1a4a8fe615a9d766ac065ff577cf5840a046fb1fdb19e917857599d722d7b56393d385cde1df4bc9e8782214a83692dc6dd851bd9c76325148a27a9a602b6bd4ed4773bd0d0fa66d340c1571dc735531a65eb9849446b7440787541561c63a6f892a6cbf44c0c59a6328ab21446d61ac1dbcad51612e2260a794804fbead34e1b5623f2e44360fe209d4791dcbb3b097011a5b3830f217114a6b4d42372af49a3284682d96e2fb151630540bc48d3a27f2fa336827eb9f363d137a5a88e394297b18dc8b392328becfa13ba12451f38073f1881b0086c1d3384954fb217645487a84679e3e2f1634dd2f56380ec6dac02b3597c656b3d7c683455d4007512ae87f3f2e86e28c2982412f5740d734ac51f64f61aa438ce09a36168e9b54806aa7778db47935f6e7a4c2bc4655b737b07a8be90cc4718348157ed260e86abc3f1c43aa65cc40dcc173eaad45e195e10a31572768dc93253cbcf7003fda3d400fa9896da9adbc08124fcce34e135c12247a96b65de612808bba5e01f403a5ca32fa863a05faec1aab09068910339547c7b74a3b6a5ecc11df6e26c80ca607471c764393f905005e7eb3f4addebc08b0f6ae86163fa37969bb552c93bf5991eb6ef17a58cce042a968e3c52e7c586464b4654363107c6d2aa0f30eaaee4000a13160982c01d2ff2166cd48ac396d6500610e93bd580ce651d781126f0350663b285494662c154abceeb74051aaae7beef4d264b82a33fcebcbaa178b6192301a5b4767b36de2b8d89f3997cd4c292735e87eeba3f4c0a5ffe01b64425f5abdbfb190d5cce8fd9c4b52b389743fea8e025b9003696ff47001c64a4241e0c06a2eea8b9034a7fedf5bd15739a873b3b5fec71b4d57bb5f4e6cf15b940605b42c79f744745bdb3c8ed6fff38bde00e83fbc2200016a2b9f2ff06a690949b42bbf8ccbb15f1df30d79c53dd9e32b36245bbf054900726aa7c8e0988708a39a94b379b4152c3fea5a7dbf092f8c28a30418678a9ca068c13c8079d133fec1c947f260b239af78b3fb321749d59248bf201406d0d90d4e6d40a9f5b2f5ebb6bff24ad3690f58085a6babcb5bded1d901246153abb8c2ac9441752d383700d9943c016bdaa757c18c0e31eb4d286adaf56881ee0438c8832292df4279d1d06e2c8349da7d1776bd61ad108c8ee87f028f775588083c1e81a1b0ad71b1bfe3ecbd60ab2a7e8dd75e9efbc1297d3236158ef92735afd903a7e0267a28ec474d693f9889f13cb73be0a9b857a123744415ef041101e5a89c49ca2db3e8ab71db1011ba4ac2479c3d25f72465c30f6847c01e59c38d128edca5e98c321245dd7248f3934d2ade56152a2f9a0c44edf82745435dc6e5922195e11a03e6ea8b53f0f5f42dd7b5c3247b245ea4c2bb3a4a3eaacbe966322e8e64a88b84f867c3dd580d25c485bde4d04ce4fd29895d42e68ec705ec73a0e43860b014ad814ca3cbffb6570cb509ab5fd24d33005cb06334f55e388e5861e1e16c270f29aeffdf249bbd0dec24addb99303c877a45d16de4ec9c68b7e3ab461a46833b62874b69a923fad2f6ff4917b2f17ad6471710ee1c42dd91e7e09b3006f9586c32dffe4b105ab119de99d91891abe298159ac71650a9100e2e2cd5186f5df1700474fa2d5c18ff1b64b55a5ee628a0fd0f28e1b851b65209702dd3fca5243ccc2051e4414f4626c02c7b768edfb0823522be2defb4b5b4a81103fea4acd53bca6753d40226d37ad598b78a59f885dfc6149a26f0cd95d13e21e95015f8cb58e37522a31d82ea738a766dfad33d88e5efa00c0841084a9718dbced58b56c431177321e7407843875c1eb02879b4674939e4c14e9f3fd97cb5182d06e2324f65208058cd1e55caddcdf2b20ed77b3eb08e5264e223774a75b92972e1d3040a22a21661c410e2662c9459e6184c089830c464c9f1d2119ea5204d597f48248491f6a6eafed264bf0fda5884f0e21a8b2266331e1c4a2b9ef3a5a65bac995175d3f806e01208656af6f6313bf84d76be6ad9db5d0bb21190ac142b7550d964684113acee708d5d818b8315a057b17f328dfcf55d409bfd76da7a8875b8f4d9dcb2df6a0d9982267567c64a104022ab16e3199fcc7a061a8ac2495de49d51463431140579ab28c7b5edfd6439f4e3ca48c7dfb8dcfa868cd75c0b9b93bedab1735e54f8c66be288aba00c5ac18fc14e157bb00f8ac3a90ed396d1923a84f425c236e87bb2668587a7022e102d1593bfdf22f3a2277aa321cd355e6c64ff038a0792cc076877bbb43d0b3edd9d650126e7a670bc0573b996eff39a88efbf69c94af2a80f5ba1e416cd1ddc4d8af059364b5a7849e1c7adaddaf452feb0ff2f068ef6b7e0049f5ba6adca581ccf110af13172b0ade8a460ea679b4cc32f45280e2a8c8f73bedd4295352d3bf7b99a9afd90098a73812b2542350a39837299c51cf849686d7714d42c08e757909d9eaf7028a11a02cee2a54d095e6e58111d94fd4409b24421fa212d97d2f3be6079544bfb706b0411deb49482ddac6241ae78943ebf6f36a7a3ce49ef13c4211cfda6c040d35db0d01efd2ffe6e80dec22b401bca8dff687e0f0fe874a25d4821e3d40e5fa69c44ec5d7450c2922a1e9e5df3b47c51ba24a86f178efdf21fd9accb1991cdf898508508178e69ce6f78229d99846705944fbcde97e0d03f13f73d45b419e07c71439c8b845ff5ed763e0b0a21e8137a728016b4c3fe89ef3955a86c021e42fa32937127afbfe9a3037fdb043f5f4a5bd1b93f56350b8d18ff562f68064238db0ff45a10c0f45274a201dde31ea93401a6548aed12fabc914273a9307d508968bc915afeaae8a1428b30d2cf15c3c1649d232ae2e0dce170c4ec4bab06d3de2be8a267a1276336b4c8fef202caee778d88217b83ed83054855f788b2d473e1403b434c8ccdd9166e0b039f08f8ceb19d5e4b0005d2ba5266eec0e66d911fd1e90c41c6b3adb9fb36d09c464f0f6fe993547fd349418271ba32c3bf59f113f9be037351e5838a933f76db034935311d27db0456159cffeb1b79300dc393f636533a1ad3525ac362444b1ee5d8870f1168726c9c3e01582c2bc9d3d804935c0c61f0cff9f48a1cf9142a0ee05c954372dd34a42420e7d782ffa322a44ed734bee4624a6751d095c348883bf8a0179eb2bca74f58d3772eeb628754f77baf99e08d4b3017d7e2d0185895e0bbf91070b4b065565adb4182e77a8a84e2496fc7d3118649cc27bb2a6c7dee4e2314a816ee04a712b64aa34d6cadf35b92fbcb0df5dfebd24e38026554630d237ee0c03146b1a722f1c23d1ba0b2ddd7631902a4e2ae2f8119ab70584e3569167ff8ae94eb015422c1298ec86813637a6fc202657deb3151074e80c3dfb7f95e96b13bc32c4a8bf994473e8661f465b3f51dd946648d30ebff5df8247bbe4e8a35497ba106e99f722199e70c5e0e8465dd53fac115a4c3f9d6afb0363628c4e81b9b935c4a746d27ba6a61b93894e62181edbb2dd7626bbd5f874db7a00dd78082239d62f0e4870016119487b62d14195a7b6badffe74639b678939957cf4f02f97c94f759ff8cb2f81d5f6441d13e9fef0920f680e927a51e5ac3549a479b5a26a762cf998460c202f0397b6daff238a33ee2af60d855b70d74949043ccb1648aefd799aea074948e144fbe96221552857d828522671d619d8caf624a02f5371b25ea392cf19cede80dbf78499fe39786413b374894feeddd3159f44992f871c680352ad87b37e6957bb803331382f3423bf70d97026a75c26142b9aeb31f3533e3182cd9b4f9917315307def6587a7fd3dc4211d68f3c4142d37c169ed3bdb91e9cde6f8625e4f42e109bfe5c3b778dfa1985c0f50a58ab9b93eb5482262cda7fd6edb9543d2207a7f516d06f93ee5a43449ce58901ce19ef7264c46cfaa9d5c3dab3ee59f915f07b75e73711bfa4c4920acd190495c1d00a836f5046dc72697f735e20f95ebd87401c5b9c673a0db6cd30d2e184dd1065921403b3af58fa6faa8379a7b3bfe7d93f35691c3040100c080a55e583e1bb5d6b4818116884a8cd244c9145f39c67a20511d6a42d612dc14ed90936a8d3f612a8fa7798e45328431f92f0901ef124944cced7f6c6d2e2857d1964074036f57705af4e57e7883ce8f328f336f27dfc9d2fb29543cd15d71898c21690479dd1d1d26b0741e3a4fd530f8acb28818f4fcd3734600f6f58a5fb282fb92bf67e6041a6df168d85c890ea2444840b0519aee2777caa9529f3b9d64dcbecff025a005531f4e6657f6ee9019bf689df6045c35c5c06e8d62c28206e17d74e61121d6729b027352e79db8a462336a2d79c46e258e6a2ccec15120d055c5e39122b128afadb3090b03e552798049f8c11c3f747245f7f9098cfc7b533b81d2ef94f19ff744feebc8ebd020997514c5614b9b5d2ec49c2287507aa781f9e8c9f419f47545b2ee7e4ca00e629f7e823d9021eaa8aaa543e179d278d2231324f28a807f7131e892f4048de28ab8a8ce9382c40e4bd631df9914e34e56c16240057088225d5b551b5a202bf57b4043d38e6b093ab7fb422ab21efe3e1bb280adc6679d3cc6cdf49409387a1dd772d04dc4843a894b12b58422040d46cde31892495157fa1cf1b4dbd33e06232a991ec46ad8d3ef9d1b92bfa36f649ce38e95834bd22388c56139eadb5e7aa1e24bef2ce9726601067ae142817bb1efd4620a206f3f2a4d1b747774b828ee00fc13c2310b05c886f9583dfa0e139385d111710bd8fbf7ee25eab516c668bee9f4f1291dbd0f45bca505e0e4434d02aaa7e2f9966dd85c3f254c291f3c679900d0b9f72107cd64cae9eea8547ad54f56df8fd45cc9380d23094d8fcc44927dac7b14144f72251c06371551cd5cb7d751919ede3432b5962f1d6f7e38f182b11bfb3aa8fc457f5011066bb3e5cec9e2e247d956ff857d2d607c78f7d8999f730005b3ddcc692a8aa90cfe68fd962bf74825a5743687b6eb228dac8bb7065a71d7d46e7252a4b61217798af1d7fc13b07a5521731400e94afe64184278d51deda61e7281aa5f898f42ed9aec0a6bf658133307f404ad896cbb2618d88d224be25e8a7ed499b90a7ed2003b4577c91dc0e2756dd132bc753ab087fe39894464c4976151d3c03f27e10c44c88c028b1f1015453a7bcfb282d93884f67cb28e5994daad2210fb5666d78b1a55f133e90a27d44b1a00a4b29e6396bce92050e4fced8751195fd385c726823314986cc572aa034e94510698fa6562ba1170105c70f7ad103987434ca45e9d127c87686933f7c00604dcf6e6a8a3f0d7679b316429b2d3ad074d65957c33c8f1cadbbbcb7c84e835d9f86c244c14c549ff9c86038b2eb65194a66d0d0b2fb750f42b6bf8e8bc7a331473b177ae74f3a868adc8babfa800971e4961177ed75448a5a7032fea197ec832839e8da4e02f4049752c84830619e9f0ae38e51c63a0794efad4863534a32ae3d584d40e90da2d8a7028e24290c26505d02a63a6dcde0a9022fc914db9d02146a753da9318175c1c42e4c38d475c03404fab8c262ecba2ad7a4359eaa6b32a86bd94acedbc61e96fd7c2507dde3bc44327362c7f5cd4c4bc23fe2ce197412c85c7ba4111f2cd2e6b446cf66693bed3f83738824373317634683b5cadb3e3f583aec2170cb2100661f0f7cd4bdb1b90544284e4845e9e999d557ec1345c3b9d58b522cd6599d870ed5a4c41b2dc71ccb9eb96081f24f03e92ad323dcab57bb2e70e9471d1c323bd2f89a9a5b0eec4a99b084f869015e22b423aa136b22a65a61e6a95bb17ad80856143e1e28349c7a0bc9da9c466e04ab6075d9c139e58ca7867a343ab9c0bc7645c80f4e3fe28b39883c69200b5902f04b50125e919c67d2c2010296b39acf17ee944fad6c4bbbc68a3d08514bf0ef4a20f70bdab537fa7834726d25f1ee379e8830c351d5a0c9b2946b9b9d7c9ed031e3d3cd9d79b49e75f23ac5d3da414262c2192bb0ced21f6456d63e5022af65a9fd22e88d98990acf1f21f4d66a0ba6ee945654bc34a18119d0a84789bc93f2bbd7086e06856bc704fcb887c280870e429a4c8f23f0b86352dbc01d35190ed22fe2a8317827c5c09a0115032ac651fbdcc899b4fcb46072fea4804d2a09d2644399933256728e479c189ceef71a562597a31b60f8027b549c6e18a88cd55c7a12dc89a37360e293b908108b0653cb3660bc4548d1f8651c6fa5ab13adbee233f0c79e8340d3e151e1c86da7744a1005533d1bc92fdb9da744837c0180ad0024001ba38d07b1efe5f2e03a4b0e0efccc035a82373110d9aa4bb93e3d42845538140acd9321678422f2c760da82b4a84475593d826dfc8005c22bf0c922f28d8808b738a472090d41280e8ad3b2ceb111809d7dd9a7ec43d580017c61721e4972ba8a82f88074674c468a81b0ffadc0dcb38f3737d7dfd41ad8f91b6103de804b22ff513294b2414cceb3bec599329db5c34ee615d22511ba4786120b454bb7cf4653fb7bf7609f6c9bcaca1ca77cf4f89b044e2f95bccd9f811d6082477b9848107caba3157e693a037741d728581ae97ec7ff59c1937b50b7f04a8d2cc62eb4ed6729ea7fac5cb46df3f9aba257057eb815392353f272bd9bcd896da6ee26f6c17a1be75e2edb6cf65ad61dd334bb723ec93f58b0388b256da73f51f08c8ddf10d6e13a65ff7e58777add4f9514d8c988e3f38527f70a271cd154ac60d233f5069aec6a1ad0cb72a64999c64c1415e1ba5ab417bd0519b2cbc605f18c088d3c0c408f39d4f9122ab5fa4aac90c9dd085d925a970f184ebd1673770044a406020f0e17fda2bbd3833dd234069994bb1fb60431dc622d3485dc63517812b8a2652c53242d537859f9e41f806c1ec7ff3e051231ba7268095226cb1ee8d2578e21a23c85c417685590ea75a001b0abfd8b353710c3552158fe8f559d885ddc207214344b9e57b6a3ea925926b4b8f2a899924a312b926ad5f87745dc48fe859723448149b223d29ecacfa4747eb3020fb2663cc26a2c5e614706614e3ca51424f6d305f7a86e283f2a99e0c8fd57eb6895887db1547d44e94c20b33b01c48b6c359025234766b951772c29697238026039ac19e602bbfa8b64bd55d53af00f71b60222baea1932350aea7145fb0b363ffcfa62a87d8457672b838b9019727101566b15a81e8f0c0081048126968643729615277689ee17aa8044d0df0ca842700f07c61b998db27c512d190c627ee0c8d7a1c436e93916e61423bf2634246ca8cf45d125ba29ab01a512355ba5c891f926105ac43824ce173cc7c9fe858fa31e3a5fa3b91c7ceda877c75d1acabfe6ae466a68b8b92cfd1fd737d6d553d2511f92078b0dfee0ce54a6a2c82459ed642c662dd5691fbdc7d0eb62b494664582a6b5ab8e75c4407950e82a426b92dec2403fc132e307c7c29b299b0ed7cb80737aed073205ab8c3ca3145b7e8e1d9d3e5b11f5b0c63e43c6df07e28724242311a86864eeab032737c0560889b881f177720801d13f476806a3dbf1ba51d76169338a7a3bf8287e0f2099aff69e05846193f8839dfe4bb284139f039124752fb17989c3bcf920f14edd1824d3fc928b041b6b170476624e3cb1b61c99d7578265f55a2b08476d2536ea5a67938db2786347c65a078dbebf1b821ce900cc7cf81d8c5f208a303da28624cac09585871bbcbef0dfb13f3726e1b31b1b96fdf6039d36448b26404ac9d23fdc7af3a1d9cded1645ec3c1a36db9be22ab65c9075940bc0489da3aae70da84b4c56c86a0fc967b447c175e258c6d3048464112fd054c684c2bcc095041a8eee1fba63b4c211efb3713f75e80a9af235294e0e11c1cc5eee563318d439dedd801e08aeff350fc1a76c1a2ac3ee43ce86bc9acd60c772f69ee75c82b79c240e41055661a8bd0858b9545e907e97afa523fc2eab5a4dc345bf2db68a240e4b34b114b926e85fbe2622e16c938a6966acdd9cf198e5dc925ab148140349927f5073a6c045732c5532baf8e39779db4de2a446f0bce485edcf44a31a04a5d00759df84ab38524e131393dcd1e3e0a2d18711ee62fc41b458f514ccf3af939999dadbf1704ecd7660d5c81cc48b23a9a9329929602413d25b9d9dacc80e7e91bce8943a91be4dae9bcf959e26a2813709ce2fd3955d927a66b26cf4568e2464b11f59f59e70707e11f7d7e730cd0679a2d89c09476d5ecfb8b7e10ea7cbe16a858fac702fece6d0b8de702dcbe97fd8f986347173b8890b276b1e74a00bfba74fa5f37499ecd290f8b250bb5992476e5cdc10e2164c56df092089eb06dabbd4fa0fa4cc030820d1c1c5ab509b3a4879d2a650b4691744e95328e20910dde2601d1f1027886133476b2fa2fa4d32516c17367ce6a7beb7940c1437dfa7bd29f9d78a6f6bdb673531c3908c087d1dfda290ca21bd87949321b6d56d7fb16c848ebe1ca713ceff432a3e1e72c7818530b8c4bfd02ec02b4f472245b74070ad10ae56253680d405b9f6acce5fb8eaf7591ee7eda49d29d65b8bd3542635406d16244d0a41da2b4dd3596844b5bd5b095d955e1c26cb1d37b69ff5ed8faaaaeb1db952972ddd9ed19522896eaa9e7f9da9fd4f13d25bdef5f78530bf6f2dbe1eca4e86a277f0e391952d62518c2711b960e582461758040c6ae30a6b2d45564fe2d47ad0b0cfc6fb434ce461a290c5414f902295088a9c252a5dcc5fb9e41403b6d96ff1b036302ce49eac1af11253e846789bc6dbc834791a18912e068297620fde9791000aefd446aa9a2f7e35427b540dc7007b696bc09eb18985d4c758c32d830b1e83aa8da46aa48df362873ab3742901e30759cf2bd23a5f87b8c96dd1bd875cb0064528bb47029f6e5d79622f5758fbcb50842a5dbaa5109383994b8592f22cb8399d4502029aa5203930aca8a2dc32c6650d40f2aeefd843c73aa3d9eb6db1054f234fb3d84795ff242c4ef376da851339fcc476e6dc39356527ab5303338531274f2ff603288c83629e6afd8be517ce95fb812f5993109d5e2b910974cc0b3b78b5edba501276a9c8ad17e6bc727a22dfaf6c45a10f277d95cb554398a0e93c5a235856d4af34338156c9bb098e22d4bb53036531f9d0bb931956b40a8c801379c5083961f08d1677b05800a06cc5fcf0458d8991942006226bbdc572daee19790b71f67b7aebc4fe714626edde31860b15f5f81869b9785c210b807f84d9b267eddd87a4051caffd98ab4f0c33c8062236ce76f130d454ac5d6fe5db576f49f715b89dd0668ed2c941211a677146f4c9507ea05ee7f741664498703cb3a0bf19249f09d33d51269de31f6d61ba225d02a1879110656e6badafa4772cf326c4a01f1b2934607efa5504f81c45cd66c15b31f0eb8bcec70af75757839fd5b886418cf899849410ca705a2b56dedbd6522bec4a70f6d80088c2eb834ba44a5fa4df2fc1630ed56da83271fbd111e8ab17c15fe49f622f408a4b13e2804eddeb0a3c4167cb57b155acc48948755abf0af4dd2172f0bfcb8bf992e3724c1fe65213fa4ae25499d81c2151652ce08a4b1e2e2ff083655384acdb1262b5a14b73a0d9e6b7ed3d8e63963c67b525535e00b6776ef7d8ab20b6168444db75fbc3443df24d94aec6bbacc3a093535bd033fe7c59b24917be69eee827bdbfedceebd461ab5cc6fe14ee2d3cd9e54ce8ce19f7c73b9f3a21a7712b441eaa002cea5b9ca8f5cb35ab635fa265e9996344dfae4f4d85d1302917b7d998272fef64552637c410b05ee84354ba60b095336c26cf6bc1bd65aef0887b92dfcc986d5e023b7baa820c26ad449bb4c756305e849d541fc3be7b5ff9258fbfc975ef538f2a96b2a9f1c1aca66d99a8bd6d38fb017ab6d88bbe4be940c528566deec01e29304c7c52779448be3325a6656f9c02f05181ae86ca7fc72c9d7c4372e336598fcec53e637055ba62efb4085e0cf43e9a4ddd76b6279051b8af55ee69064ce5f4ecb185f363c63053872681a4507742a71d00c2d9d1225af45c8a6f640d872ef0067a2c85a7e0d160e13561d339053ec704bb454db2f0bf42d7fde31c5f47a281a3139b3c13487a6ca13928840e36c8813019b1040e75d3b7eb79377a348732f3ad459a5680caac4cf8ba45961a02b006760b53eb0542cdf3a94e026b17619e95c076abb766ccce476ce22b93dfd151e301c8db134b96e47499420268db1ae30be310fe90e32764092c8d485f9169bc2d162e3928781b8614fe29fef0e8b636f6f8244e4a543078dfd4141144fc80cf86d2f2f468cefbddbc2d8de5c49d70368a4ba373be84b7fde463a99e85f1afab3aa3bb5bd36803bca40e92f45dab94c7d59ee438e32b92ac8db7b29c8c4ab49b2bcdb0ca2f878c7388fe7a4af65c4cf357d409d4fa0ec56c138ef5a6ed87180b3c429c50ea2f7987183de740a40999502e1019db1fd2766c21fabe152e2f089be0f16972761d52bf0d2c2ef456eb6d6d49162b8e4375323992a33e4e87017c1ef17061760a0e4b2c12d2301e1abb90d39cfa4342c2b4522a2bd03936eddd6f47c94062a0aa7fc2455806f1adf8f2599f081f498c852e3b63f2a7604d29bc8644d531427b38a2366d4572b28ef9dea2bf0b73bf73fb12ca7a3c8bcb9d3d100df8e2a6b26bc0c247664c82af7a87d93cf5b911a9690d4c91f75997d56180fcea6b7aed4d0eb7d4ed5ed8170aff9ee587829e254b26e2c98b2625711cc746dd005ddcae91116b19e234306ab1449b18bbe69dd94bebc288a0e0035709896fae66e255b85352b16ce340195d7a84fa55429b641a952288fe6d863e9280bf93c0f89b1373637b58f40ae6aadeaf66bbc766b1966689b74cdbe84031cc235abb91360490cd48fb04892d7e2f332e7336ec53f298185e410656f10bba552d85348a07b7c6d5581b7534513c1136175f94c3bd2c8c5f254853385059518007d3efc49699ce9ef4babb36fba0c57241813594c3d5151622d3c87424a64efcfeb5bf2ccd4851410d11af3f4fbcfaaa540fe262eb36b49b473cffb0582cc5d8e76c588e0a0b6670b97553453992129f27ee7401ad85ceae31691d1d7c4ce3492964a5ff587cf927400a433c122de947dfd1bbc98ad0d8f0d490ac48452d5c82be079cca27d8352d2898a7d513fc9d1af36774b9b2782f2c1e270a3a3e9256b3d59e31159149b3b7eab0e9985ce782f178e6ece47209f3d51166c4747cbaff4aba9635077452e59c795787a68f5f4c675fbcd30d306803fcd04d5842027ee39c94e18d822e997497612fc5e180ef193cfc4c77d1cca46d101460db53f4199545bbcf86699b07ff83b56f9fd2adfa7a1a29fb4d884a92c8bb9b79f6ae129eea8fb3e3b6ec08b42e9e5b3b982d70797ef19bd27a813447291ccfcd3b49f087aafa655a26e926fe770a457a2238a5356bccc5834b69f9e6f5052fa44c122bb70f453052b39b13553440dc454e4474c608dd0a72d24feb7549c87c37896771d81cd612c0a7fa462f126f2f5fe87cefc9440633b8113ddb76e8b049ce32d0b93354388f142526b4ea35bac60a43f8171b628af1808e4243817e51a489bb349d886c05176b0529eba3b2a2aed4815b1f39fbf8e91e8f5ea8ccf7f773ab22fde5c1ab7be3fda99a4e1e2b2d2390a35b00ec37d036324c0012e090ef1b7235fd962e750a2ab278e8e04f82f3ac169fd4982cc5fdaf0c11bcbf043ed3bea06e25fc5b1e4e04ec88ffcbc22c5537cd59b382f8654d2b8a98d1ac3f9856e0c466797fab0afaa009b2014e30de329c2727ee21bdc5491a0c17b07022aa3f198a11ad40b2838b2bee30970e5d783ab4af245bdc38df4d8676865ad84e9f551f5015685abc6fa4696719c15c518c24b5c1ba28274a81c2a4d07b011c0811e73e4be719b1421cabd6f5cabd4f77b1c1de5d84204b2b94250ab1463ba5fbb8448e1a09901d8914680225a727bd9cb4118d54fbc93d5e014ef5a9570f4f57c83f25fa23558ed53e3e94b5df8a29311f4010eae7e1a4ed5e6a041c24a73f25d3dd18e852d53ff373f85cd824f203b871bb85b8877697fcf979e049f9eb329f36058088a93a1552ae1e092da48ec9210027844e88fc28c7973b2ba89c65fd79d0d9d0c8d45c531b7ac08c7bbbd45a5dd0db86deb67a84609037cbef7c7448f427c9d4ea4d7f809e97e12de4b19c01a45f75bed8a2d3556aea1d97293a78301496da57b41d4d50c15e176c1c35dac4c774e1873b59b151290507c327b8edb40124b670b1a5c310f65bcdd14c2f79d7c4708c060db542165e50ca69a614d86857643b3e614c6da1e28098877ea402a4dda133e7a201951757ac83f16868f52bb64436cc0b1dd69e65748347dc625a76387d6519de7f7d2569bce115905ccae7b7408c92a6d6162a97c509e2e280caf7699fc466822c0311ae1b91a7c04a41077a2b725c89c4b805e40aaca6986120073812a0e211ff43f92e85aa7c952ffa7add42985486eb1f9702e402e3a761dc74f406ac74f42477bfbdbca6174ff36c776b09c810104393476d5cb9f910690bd1d33c338fd6838d2978d41989cd207884411c8235c36434611c30cd0dd7cc1b453c1fcdfb265771b7045aab2b4bbbe8114fa9c321713e8dc0c1822e6129e1ab49084935e3a42d130d4f8fb0f33b3bf90ad8ac38797f02d975369ff97262773c7cb3e0ab98e7a02eb30521de1b402a56c4106ebecd18c993228aca6358cbac4c573787caf977e3ede9767c05c9f97570678372b395a5202c0a3e6fb0c7134966206ae5b8ee56cdf838aa5298f194f6cf250816e19a23e580089b7b8d5fff3866a39ad33e74d02731b82a2a248b32c3dbf3822c01d64219ba9a408888859b6174beedc62517138e14cb3868acbdc79d8d1101b79a21bc6c6002285cca7f62b1df7abf14e20a3a0a1740100ffbc4a12fe1da8dd544e90d0e03d54866af0e79c6140dbba6d0b1cdda473ab2c59edebf8b6b4484d0314b50d4f6f6904c97d965dca34f2838cb5ab045b24c070f0bd3e4bd8770825ce049d77f491c4f7b1d68d8e4e991400f1b9e44531dccc0581b8a5be7033a1c2bf83ecbe495b1ab7d02e6297c71acff7e1747a0241f2c15b6a84324b5174e7c9736c462e1f7c41e641ec91907124b550a187b240bb45f129111aa65bd0112b2be3b81dff61dc8ab40335a4573a7173da5b3e45fa14c4f424a54664eb1f316305522936612d23c043e61623c08f875bb5ec834a5affcc1acfa050ef27329b19b69174bfe178817d5f0a4b903f3e30c9e93e291281398fa42bcddc61e572d67fcbe92c938a441801cb4338db9125583ade18742620d3ad0c0042a09de8f0ee06dafb2ed657d567da1844b3337c38e6e272019535fd6aae8f202a810f704ab67562bf701b74dcc851ad11150094e9c7ad75a0d8025b576e33e5e79f8c9b1f47522a5784b5be43a3745b10eafc18234482dd94eee176fd6fff2ea9764d0f3eae95851ceb1c17cc85399dc78094f8aba8193ad1e8025771ec020ec31c8d4426237d83b54ade64a91b52d2d35475edee1d55d51bb77ec2fcc10259cb61e8d681c40229b0d85d0ff978dce5be0a3796be333cdd3e6f7481cf5ebdba3cb68a9319129401cec509d64d52b2353bdb857e5a3c43fa4a343b0504d8635b15880b41dcf81081d00b921b280c5eed5172480d98468eae3023ad8ff45c45ddd1498ee517b1d914ad1da39e48208a59a4c39113d4b1b15b463d55fb5d9fe9853bb38376b5f3e3c02bb7cd10607c0a8166016a7e9408f728f4dc21132298af41fbd9407db3d2de8248fd67a35f37fdd90fb14967bebf9948784947010684f4b9251d60a876c1c7e47f4261a174ad0ba0a07ab33b7fa0e3d612876c13947e6370dc0aa43dd7d7adfab358aa4f0c4bf4a92f9c140b6104faa3dc1975bb710c85e97e6cd11eecbbc3a40650efac0ddb0225a81fe0e7f495ae5645fc498f841ff2916526727f76c2d7fdeb16c649ad53909e5f228c1a10afb75f4359f03c39c236233844a584c57da66764d5d75d02957e1ba432d9f32a33bcd4e478570b87dbf903539d32a731a742780b241bcbc13826f7e3886a56afdeaa589d239a9a392d22136a460a01e065f352d218c4bcd24236ce9c0c80da743664f10997d3ac50f11e05c7b971da2629d9ed3de0affeaa87f990b2abe0fb327be082cf518e3d25016e4432c6a80a2d17ee748d650970bb9aa699f05b358dfa023123f18e0013e20c9c7ebc20f5e98de5106045a8868819e72da4fc004099542a08ffd11063b4d3eb8180733335433375622c694f1b23b6e55ccc519ab4fb7a5eeae174758134ec8c7f725b11ea2af0bc65440298f584c60dd4a33d61503a0a1432ef86b4237769bdf0bb30c72ca6535684d254beb040055d0b6cd8b634d8f43de54bfbf5522eca1b6d0308e6bc17affe308d6c6dd15e2196279c4dcbca46387f7bd85f662042bc22d434201d0dfcf01ddbf724abafbc02666c19d670a7bfb1cfd43bb4b1ac3ce642c8694c205e4e41865843c58c4743a89a7538d0fea2aea2f6d7795498f339f8e9e5149cbbc7d4792ce5b3563bdf5e2372f4e27e112e3ebeef957aa0f5b515839cebbec3fc37945ee7ef9a3e24e263cdef0c46e677f0e652ac2e99c2a4fac1b17a7301a6fe4a3fa2a2158d23a94d7cf57faa3cd41ad248e22a1c99417d4d873e4f952178ad3a0fd6b91f5ae870f93f0c0ee6426fcb839cd1cddb2c4e4b92bd25d5866dc50522e38440d1334977916d7410c36ee5778774ce1c914e9fa7d0fcb07152d7d40a8e1eb5ab0c72fb2f340bbec498b44595e4cfe10661a583ac401349fe9c210230bc5d4ccecd631952965ea892bf72560e7525876084f6df3ea45b3dd1067ce6ebcb3aca6c0b61f817c92383688e3b95f2a23e24ee2cfad4cafb066a8009dc9542c15b265a3c08566b1c59088faa0340e150d40a69efa16969fc52151b847bba3fd74278d40e0f7ea1402093d10400a81e0bf2f164d2767c2c07b3590f9413b256ff988ecef871c34e01a65c92abd60935922cd38fa417173142d6cd9099c11928e3adb5e888fef6b303cad48a6b2cb187afc4798aba06708b01c3c356bfddd6003513ee38747329dea8e18c3e144cce9ca70a9d1f148d89cf9930be0f11beae664a7776e2273bb02ef3d1a376252c2e40a9bd5885c50620593a8ec0e6fdfb841d0ece77f309f20ce19992210cbcf4a1ce74773aea973c6d3ce404d76b0750dca0e24f28792f63ab084f006a97d4742390cc0a8f00949cf54619310dc2dbdd1280a2626975b32caf4e925c55e49f161583df94066dfab250ff2c621619352945c9070fa87ad121239aa8079efab1931b23a70660ec723a8719601942d126c5d04713fd75898495275d066b8932576cf2bedb1ccf190e7de2028b49dfc34b51ae2fd9ef9180d142812aae7724bd17daadb3d165a2ef0ee648f80c08ccf12dfa2bad3ca1463ed74efbd380e6b6249e00d3313814e0ce08aa5be795b94835223b61143d4ed95f22a9047c9083175c5cec5e9d5c4ef38b534d8728cb9f9fef2afff739f7fd4f771f06f87f33a9c17a992f650ddc7dce54b8f895a240391336483c43a360c41a8899a1f18eea9db60bfbf4186fcbfbc4edccc1adcf32b70aaa6e4db89246de711d0839294f078a27d59c061702dcf55525b5f7ddc6b2c59cb610d3ee735cde699a50b127216b62d620560297a02419c3d32444fba6ccbf41b86695626f14316a5de0eed9df31e4f564b7b0cc525c675bfa1dfc6ae789d229057a7dc03610d980117d1a8464f382e9f4dead04a06de0657d2a5078dee37586658f3d34dd930952defcc6d68ca06ec5c411034da686688f85e1c1556e7e449f0fd7b82a73e4bafee0077086af23c7b2cb70cd855d8113c909fc829940e5b01703d0d631aa590e04896c27dd9d56d18d80c949dcce2f8cf663404fab26f8538eb92eecad169d0b3fa91827eb5db8e1497a9a46eb505bcc41c9d20cb6072d64ce4e262008169a824287718bf1190629abfb3e75f3d0ea31e852b84743f4eb43ca1f1b9b7f92bc50891824c4c0f54c97dfc6614f1e40ed2160efb886f51dcf74af150363afa248bba889e2998e5eab50c403866f9b5ad2783bd5f7ac239acea1c9806e674569880afe532eb875eca57caba3736e0ed19b0cb086d49cadc02f2294d91fdbdf609115808732a3f811ab2d537d9f572393144cfd52101518cd435d1ad5205f7d6f7f04071c9ede396c9c6a963d28be9548be54694bb6c133a26e5574ad15c16eb124a9266a54e675b79346900e5a5bb40852f73768987463b75700eb140efb8ef131f2b8e3da3234aa7275289b5f376d45a472f70e1ea816c8eac45600c30379ebc6b017389b486706e6f371a0d1df94498d26f0de084c6db9397692f684cfabdb941d172ff7740f9f830131f7657187b504e5a20830667499623dfb6bf97fac5eadef9c2fa77dfcd10f3706544e7f4b76713e3528e999590f65802bbe1d115b0d5b688de01c486ea91337c89bc9a61eba7344213c2dcd225604ea21fb68981129b355132af2506f5c289206dd102bd13ffe39c91a3a00dbe61d08f3f0205905a7b355b6e9e530e27681dface3ec587b44311e017046c73114d3998c2d89400b6d522167fea76afb1404982c2b9be29e2b448319d28637d258c7a8bd89af6cfad31532c0a1b3ad50e7c336b6865e0da897045461c31d38b849b9cdfc815253eb4c5a6f96d8f486452400e023331e5acd81b79d304aacbfe25fbdb24d57267c1992a7177422573788bd6d468b10fb21f79da34ef74ff0ba98f0d8faa342ede8fb468717064112208bb73a116d1762715392aae1d916e092364ab1850e5285ef26546f0006e9b29d5d283794ad9ed567767b8cf9386a447bf166e389934d0789689f24a55d1c71b6e4b36917ccfe8d97bd18b2cc165a1e1e1ba800083b08caa4b7ed31f0f523a9d593794f25c8b300461f8848b78cacd37cdba52941d40ab430baa6e4e2461e66fa8ab84524a3eaa2238b3f2a4603e5c96b266084410f3c7d8c5fe8a89e47ab261a5aba240177a9e6b53200ba3598cff5820202fcfcb951110af13c5f3de33741fc1d7fccd62be7b9556f42e15ebc448ae8227f57200dac6b57d6af3d56cac362b2bcd03791f222478fce280cb6af84d114ba3be08ba19e464ad33d741f0ea943e0140d84ae33f650b1702d5d49aed42d39e350dcf367738ac063b2d0d35cdb2c3d426041297272bdaf240e15d6ffe8ebff2129d5cff0152a391c31821ded72b168a6eefe50bf0355696d8a82dd079ee0a5db629d67006ecf0a088337c60c69b45172caa130c6b82a83922feec0407fc0e846459e489440bbe1edb44b72ff7dcfb9027eefeb81df9d98ef82df66c2c6d7e9baeb54d34372fd8242c4005f77e0e7d1d3559bcf02deb4f389e9eb2eeceab551695e4c78f9c93e4246a01fdd5d1b28eb50b2f449cee1754287e2d10811cc9b26e60c6f4b1ed83fb879854557256104ef89f60ffa26ae06281276947e0f1a956f3b7d6471d4a0100247903106587e71f67ed090ce700470ef9a0e06d159420a48f64fff0d23e50b8c712916d560da404e780fe890f97a4bee1b7cb7ad97b7c7d2e1c66d2c854e3208057063dca7b18b15b4d3f1bffaf4740f04eaf2babf49baab41849b2df12ad94b7d626b62839d16863bd88c649eb8be0a056663937fd053602e1ae4d203ba98b6855a30d0b24a07c3b194cfc196c5ee3376757be5c44d44d5cf1a416a42d67615ff396c439ba690afb41e33a06e15147d8f777800423550eab25a262292b4011438036efd2b26d020f7afb6ea449e8a6d6b9290bde5de724b29534a32440818087e084830b43db0b0fcf0721417667935b9b19d8ab2c8e0e5f237162d3b46b6368f1bd819bb6517046fc464200ac738d63bf0bba82836b99130b9902573635702fc4f4229c49072214b5ef6206cb9d745dde22847dd82d7e6c22c426297bb2e029007fcf6582821deee6f1f30873fc6c84ca2641a5362d315a818834f356fe3c5c31a083bd63c106a8b34a2b8bd5c76d8e587de5dd43b353a5747ad0197fb713a3dba63ce5363ccc307f469af86c7dcc18991a2d531bfe13fc3d6f41fe07e07b8fe8cc4c8553d7813938128405c9f8ded68a898132331721de0f21444f783586eee079d8c42a88272504a292194ace851cfaeaa58f80168c2c20f22c2420f0eb11f0deb18c01816fea7e3d2f65c428aa8d0e64b115dff1afbc2e8b1079dbc61ce4e0ff323bef1a7f40816a933f98d437726278fafebf405b39f1f11e131fe9945ce74e4dbeee74cd7a7d115fea150f308f4a15ec09ca569b429f9cdf604bc61e21cfe5f05e38bd7c28aeb4c33f1a351655cffeaebfa7fddd2750ac53f1b0e600e2fa0cf1606e6f87b1a04e8c17e5b1ad77f53a2d4dad5eaff6b6d4ad7df87803b2c80fe04f25426bf71fea1519cc3df6bd3ea9bb99f1f1d5dffca5ae00db3159883992bd3f52b638c10b3fc7fe185339b958946d5a61aa371269947d3681a5dcf3e8a526b57abd8511d55e57eec8588eb9fb138c658da9522eaae801f24847dfe16bf5dcdc0ea8ca0429b30167edde162959e39d69c305f7b2d63d59c90bdf61a4cc5c06eb557c3034ab143548d0568f6f4a1abc602db6baf41d7d75df797f0a3a5143b443514d759500a1d94ee0a1babc602dcf69c05a60b7628d4cfbc9a13b2a7d9034161db7e7a35274c21fa93f31ac96fbeb09395b158db2ae6a99df85ba999fa29e2a0429b8f22d957907316a5c439b231a00f7b5d05e6f48f7b4e5c8e503e443087e2408dccb8cdc3ed679b26fb452828e7c99cb20805d5f1c8a0a2b22ffce3df4f85803e68409e7e02de1cf18f7bcdc439bc4d47a7000518c0006a6a66943e78c1fad1fd5637da903971971815a1f87d9eb0f6c228a0bae0e64ab6b228da9e45b96b7afde437fd4d6cff17a1a2a06882a03554688295cc31c618dd63bf94fe7fe10ebc0e80299cae08b102c610613a7862c411294868906264878bfdba4b7701729e1ace13aa5e4d4af5405c3527d4efbee357b19ac96f182a7df0b2386f2385fd743e1c564d3ff7405c95d55127d4e73ca1eeeb3beb04ee539e50eab9b701a6c8e5efa8e6b95e44f50dbcd78b2fdd82fc9c016cb09f6d7d0eecf75d3fc703c2568d7f7cff0bb5046cc5db6974ab8bdc8eea16f7978b867d7e139c07481132b062a5480c96f000c6c58f82f3b8b0030f5c1cb961081718b9f88148e0b7b162753e50bfb56dfba631e10b065ad0ade574cef701c8bfc9c0c4147e1a1b24abdbb66ddb46ab077b2d81bd9e3ac120c9859f4e7b9fce0d72bf58b4248d982408a6fbc5a2ab04ca2826691ee842722311cca877be487473e89d58066c62924384350f750910b12dfcb0d7cd2803e6e0ffe851d2651852912ab9667d3451723468ce2ccb98761888d9ec61b768b7b21ead2ecbbeeb917912c8c16edadffaf5dd4befb4c730cd5bd950618384b0dddbccc07a5086edaf4edf7cca02414755ea7d2620ba9487eaba1798c31fc4c4ba97cba9ee7ead0309b82be5b13efad9bb6ddee74af747b79804b9b1e832efbc7a07361da571993f2e72f96351ef6cdc51da6f2c782b0f9c4ba99774abc6a2df9ff43ed05137c288c479f8051cecea5bd1a8a85b3f29b01f90229c6ec10f3ab23022751d13a4a32e5f6be3aa777aa5027b3435ace06866ae77d869b00dc40184b0cd6f93d87e0e328176755294aba3ae53d174f6d73842ccc69c52cf5e5ba655cc2144c1950b9fadc01fcea1a601518508d4fd047db2ef4682813a0f536aed6a4573e81c582ada4f4cb75b0be7e84fc2b3534becc3ce02ecb29ed0904be5c9a23e721ec9a4f4499bf7597974fbb5a408a55b4830a7bfb5f04f2c02e6e827334a903ac979dce50020ed8261ae7b3068be285385369fbb0828fc788cd005e893e315a4771c56243ee7f0f4011956e8e53172f74b05e04d7c30e215379ef06386fde0178a85721edb637b6c8f4f398f8a60682a6ce7a28cde9225cc521f0b77de30eec7e5809a21c37ef46a1b8ded16fda01be8e63f46a4d14aa04f91b751c33a094769b4892ee59e725e8ab213f5388f225df9f1c708cbff8a9d7d41bfdeb8f47987d2270b6f758e7f60269829c7a5cf46d06775e9738ca9b00bb8086642d90936d98f8b68ff2a8a75c24a5c601f5cb026c4e7ee2917b1b808e6d06f2e30877e534a9f3ea54f61b444ccb2097e16f2640f3de9cf45cebbe5128039d2ab897f800ba7b840ed6054f9b53329a1cc81d450927a678ad4d22b2c50c8a3ee72c49df3649b04fd601be928491649f8e8e53c7c44a9e5a30fc670a40fc8b04d90fa0573e4f7ab8fe46f41e272a5144309fa402798f37c047df8e53318e8d32f9fcfe09d3e835bf2e551161863561fc11cf90d06e6c8970deb574e16563e77cd486e0b7c5be0259823bf49b7249294ff2385956f64039353cc85360abc994fd4c19dcd44daaf8e8a687fb12f22185465282218b1fd93a1b84bb7e64f8eca71e7cce67c383f842b42b8623f8eea227f3293cbf96d047da0ece26515453f1883e90332264731d46c567639aaa9409f2a1cd51c02129c391730675a1bfc48613f86e2c9c4444c34a160d298b466729e14201413141314930c6d9a8115cd0bd24cd000d4eb26e0cd7ca04ec1799a8a2f3370718239f3c1303db1084638d001def123dc9a3f6196fbd93b9b09e64ce701e6ccf79202cb5f388a290ba56ed5ab4a77c5da24d5c872454bc440f582b550da1996d3525360ab950c8c92255b9420c14295648717322d6ccc854d4a88cc2449d050f570832f98583b244993d20ab0044edf699671f4b92a13bb194f49aee33a9a955449ae83ddc7bba4f384865c9c976a8ab55a3d3dad72c160bf183b39b3adc61876182385127637e296c9c4d42943b38ae982ea4cc71dab15b5ea95a53dd7992e484aab69deb6d55a2b9d5aa6f9a435b2af9165dc814db768ec8fe982a255a562623338f85bb93d4a035cd6ad9363d6576342f764382cd578e36df38f77897b4243aef67a89cacc4c3977cbd576770dd800c2e6ddbd8613fab486931863fc6c4e7766662add6bcc4ce95945770827eb878c1fdd478c734e19dddddddddddddddd3b196e8f3235bb1564ec1d3833ee03294065de0fd6033ea8b699400264d236a5a4a41e1d9d2349bd55cab9a2f4151e7e716aa59285cc451aeb8f7092539a245758214adfde45a1abfbb802275780b23451d6a65451652389f3642a57652e63b50bfa37918d24d679542ef8b54badf0334df163777764b67ee3ededfc019bebd1420869b434ce6c55e3426ff5c1de7ec8ebb510ef0fc9558eebad1cc7acf62116761dcd3aabd5d052d6b0627975258b2def33d664b9f557496903884fc64eca59e316356dcbea94d28612cb524a29637c085fced5ca5af71f524aa992524a49df0328a58d94f261b73897524a193f2a8346e5207f08217b8caccfe6c62a6565189bba478f31c6e8cd3d3fbff1a1ad95cb6aa4c7c39579b09ed6f156fc8ca5d1ec2bc75196f6198b665f3d7b9abd963dec5a3a3d3f6752aa2ec8bdafaf8c915d09fc823435006063d5c1ea4600ea8d0e62b431d218bf0a207207352c00dc1a3317ae64aed77038ba20c7c1c598e8c11741b81f0cc0c6bbd07641f13f5a0fba12a0923b61e1cf2b3db61763838b4d5bda9ed09e58ca34cdbdc992a6b93759d234d7b65a37cd81d034d7b65a37cd81d034d7b65a37cd81c89668e68e9e1e2937af5acdb2743327c39be99e7663363d2ec5a518e5912897a2b3c061d8d997628c3099b8a464f9e352d63782a8b0635a10a6d3c3dabf06ba8582e642b764050ec2af575639d50926c438d8a56812eb806e351412ba54c7d5982d06cafcea868d814122d4632843aca00736c250180a4361280ca569360210cddcd1d353435eea3cdac6e2227dd33026ae7b3a7434d6066f6468966dd7a3940070b7f96fd9e882e413310c86c44566ba2067ddc0e2f8996e45b41519b19c61180c26656e74c0d1dee1a04c12965fc67420d32cf35a3571786b74ff38d8f46407aaa38b2744f7a34f62b491169d80e689991a92a8d1f4e40515d2c7509739aa0553dc1cb10545398aa0c107450411e646242862657a05b55c0f0d908e1ce0facf1f494c29c3cb962f96b8c1006490258c1a50a182a817f00f488aa0611e7671658111b7a940bac13260872756b0c086eb1fed02b41031e4fafb3b038e3cddf454613fce0994eb1f7b07e7babbbbbf0f20d7723d5e777777b250c9a777eec735b1e2f6c7de19c06d6a9283db0f391a6ac6fc0a5ba8ff835efa40fdd9ffde79a227c45788a4c10297d010c7c40b5cfe4243388270c51f6a58102e9a97f91a353ca18fe2349e13fbf1671e886b8625c3e28183fd6c4c17e3c9180379e4c7d8f6623a4ec6dceff7fed03dc7d237f3a3a745ca0efb164bc8bc8c27e49e103f35d1c2c82534c4352971cdbcd0908d2a9ad8e29279202e4ff29bf9d113fa265c42432dd78ce74a8d80f94243b08a4bc67362df1f888b070ef6e327d5dbff1c29363fe6250b764a769c34da02791c897b4d7adf2a66af12777a1ee3b1838d2fc451ccd085884b688803e30997cc0f35921c5cfe9125e4410f329e13f79cd88e931d27bbe3244c7daaafb08b798e15c3c2408cabddd937eb87bc2a2bf0663e15495bb8dc3955f854df790ce64c577226a4242156a26286934b68680b6385cb7fa8ad6ce18a421ecce0121ab271b9e7847f08527145cf89fd6fe5fa9d28fb39520c8ea55bd39d7e969aa05f71e7e75c8071e73b1275a42705dcf98e05facc3b553f5372aebe643702dccff9aa2568f7350db02aa4de3ebc11e85ef56d59b63d47f2a7f90ee5317752b13cc5f22dbc0bcba3ba057f258215365e87722caeb1fcc96770e77b13cc313dd6ad99391423d693dc6377fe4f0c96676c054395ef9f75f6e3f64356fcf9d4bf591fe06e1671bad5f2182bec5bfff89307f4fae3d7b86783637360bf8b55e87096e5b756e87d7deea8c7a38513bd37400fb6828103fac0ebee0efb57b09f429d2c959f851ef0f680175e48019d98d1f9d9f3f5a70e652b9b3638d226fe90a1d3486ab4b6e10aaeee8ebee9a7d4eeb8cdec6900e6f473fb7cb1110516faa458aa0bbb200f8d2e2ab4f111c2b0f2e7c3ebdf2d9b03272cdc6183e56fe6226b419fbe997712ff645e3b3512d0c7bdae02e6c41f216633990f6060a26883cdbca4e8d46a27274ff3dabf760a0ac2f6d720dd8a526619fd2277334f4f42988d14f693af1b5fcd135df1650dbd1f5f4ebe24912c922f098b925e5468535bfc27f0104438408abd2847790642d8e415bf78c7565d38b682486016215e6ed7f427e0c2e799cb453cc01fbc488bd7e5cbe306b632c746fc5ba0620a5bbaa4c041da8b911184626ef7be8672f95514dd88c78deb3f401eeeb968c579b1e6610616b01c9e8d8cfc3f1594dc62763daaf7b570fb5b602d2fa319903af645913bc7ac407e2a686e6d8e8dfa8d3c897a31158f336cf3f0431fc5e016c11c7e1e68587a61165892db4edde2e7384f68c8556bdc8e51017954cf0d1bcce5d7545e17c1dfb89d600e15feba04b899f77d8b7199cbe5875ed19622eaaa5ec7ccb05fbf5e30cb8b097e394f3b41591e67d87e7e7e01f2b495170f30d66ff81d7e8f1bb7bd8ec19c2ff6eba26ae43c1c4f77e91be7e1bc76f2950e1c1c1b4ba1f7adb87a3cccb0d503a42c4294e45391fbb596a8a630015e43d1d3c3d25a88e277479bdb3b4159d8e61f226c1fd580a4830f374698139b2c73941ba15cf09bdee18fe67e7cf42ef88ae96bef27073676f4bf5a1dcd135468f34110b2b05f100d6cbf334ba056e64f7edce1d29bd533bd48e96a15a37f364a291f462e9e46c9999d524573349db2618a152766802e1b24d172405eac2cd3ed8f94a3e1a64c992fa3a1295c947c0853851651846003224444905002a50c1d9acc1a6c541b7cd1acd86a4d5273789a4b512f706170b11446189a4ded296a4b6118134d31a24d4132e5e8f6fb98f2e4f6d329b0ae0b949825d5fe6f8503a88a104c72a841b694e408cd541736490173e9854d52c4b8df2aa659e922e5e97e3ad9173134a4283521258add5243d754a49ae2060e8b514a0923150b54674411366c56a0b8208868598c2a8c5e21da8c48012cb342a4351941c4c89c2289de400779e5298bb2c509829a625782b23845a982835294273704cd8028ca0a888262b1b71ca5365460638a67e3c425c60417a52bb8243dc12549192a30a2dad0c0162b2c160a89e3f6fc70329ad6d143135906876a04c6a2458b07388e86c646d5377a1f0bd7bdac0a1ad6e194218c5407e768b5562b6b29ad3bdcc3d7a99593b5c6da4302e7a036ad5b4768c252d6dbf84eacd61d877370bd23a5d605c9e81bcbc8402ad724b804b93fda8b5b55704b5fd8bc815add7d6ab971478c3146ef91714e1dddf218234d6c26dcc6bff643a8d9eed1dd21156751ba5a75c7ebdec7c26d2f060ae6f6286746b5adca689a8fa7a73a697fb7a0972e40bec3e8b3b9da4f4f75d9a80505a5369b134849493ea434a653e89d6cb5e3d3716d60f3f818c0ed6e0a05341a01fee4d77cbde26bdacc281a19b1d18c8a5f4fad379f3695aff88a4f299da114fa401b4a5a488570a1c731c6f79b125a98205cf65aa8e91ff2c6fee2f37b8cb104c6d1ad795b70daadd8ed68d49e99c708238c30c2082374d80c5b4a972e5dba74e9d1237402fed5e2cc248c11461861841146e87066375785b7f19a256594514619659431c6f9d5f8f3d55a55ba47994d1ae99769b1c69a7134c6544a15a3554d6166cefe9b2fdd8b9c945007e770bff2ef410d24cb9ff5e8c066123887f7151c4836fa4f330ee7e018fdfd7e4060776744e9516654abdcecb66ddbe2ac99c632c2167d48a30b19dda8909c9b063a149cb4984aa9a2e43a4de544ca89d56aab1d8b6fa65daa31771bc74ae104dacda94aa9669499b6a99c48391134ab467fa35f35c89dd23c4853e8567bd10313a71583568ef826f0eb5f552acb457ff201738444d8adb6b14302e9767b94b5764112074aaeea9097ba70330823c74aa15b9d494d03283851ae0bcafea94502ffe8e8e8d90134428f8e0e0940abd5fbb8f2995b467a02ed4c88f5508f10b3f153dde3c0e11f7f78678a6569c7fa6ec9137593b0a57dcc642c4146292b858ce5816e35ce536ba99563a8efecfb64bba0e9e369b23c90828f1dbd33915251685c591deb02232a7c7abd5e322081452765498a22d1e5fec82e68c626e453d984040a5c40656559177e38a0b89fcddf0f27cb115caebfed9d150dd79b929cb8dee402141c6144c74651a14dec9d1af9f0c228462e3fff20592ac88f3c384cc323daebd2d8035eab7aa0aeb0fef7ad692c781ffa743f5d4b4f9663e91b7ae5c7adc01cf4e1c46116cd21f0867eed825430ea42c183d15315191747a864002117f08a4b67d37502bfa964b5649388c2d598a433c8094b7f32cd25f8032f9d31b8f4218c1d2479669e90138a8614a418194f2f57e6d1025c31830648fd1fd53867e2d2ff6c8d1a5fc31342400faee9bdfc4f265d0afda6c6ff934797bef43e8924c4436ed00314322816565c4eb607e2aacec1251fa600c22534549f703989f9a1a9e5e572b221a007d7b7ba51bdc379e99d94c7c26872e95472e9f4418798f39830a1dc4e24a7494a97325d8134ffb91532ffb916977efec5a51f0293c76c74ed1d56b709cbc1c5cefce74a34de473d8fcd2013a0dfd4c84c18f4695dfab308f4914f7f32d13ba9a73f957a877bfab306c8239dfc86ea70bb406234a1269367af4be7974b67d4a5f3e9d239631336932e558239f4a593f3482a32d6c5a5dfc4a5d249c69340bba6278dfc86a66ec4c17ed229ce603f6974297d69047df8d2973fd0b7de47995ceac922a40b2efd9d1358fa21f40831dbddef2f0ad94f220bcc9f30bfa15e8fd8ae23c4ec376111a8df81cc43a09e61e1b0d0837e09d563c1839ab0fcd163baf45da975531e2dd22dce83b1eaad1a5759db854cfda55bf4ab6341c3d2cfc1c2d24ffde731fa2b401fede99be03c4e635563c11bc382d761cec392bed184c11cfa0e731e8ff50d7d4aad16e3b9137d8de5586870ea1de858aad4a2a6793ec44a0f4e18bca1bfaa4f678e6cac77605394182eed9ebe6be19f7eaae5d24f7dc7722cdda29de7b118586798dc828a70c4b2e040adbd3ce0a132fb026c9c3f3fbe0e18bc08472c3ff432cad2be4ed6c797955dd85108f0a5403deff6f46379635c521ffa0e292d50bc206163b4b081b501c5165be3c2262847d8006508ee0628299858d8005cd804e505153c2923e5c47617363d813af2240b1a4f96d089b2da854d4f9038e20992f4c276d0440636d8802176a309141e0020c3d3aa0992a21a435e369ad47003cd0b460098a93104981c646886f8226688d3cc104e462c0d5132432c1951c192628660822495648728e24317f48a52511d34386a29678344a5bcc0a106bdf0d44d51b405c5e0c449d94183d52637501a94826860daac103c18c96020d284a0e18629e488a6618344ca989431430c9ae1359974f1a0214692091635745010a448978eb04e8f8e8e1e199834e121084604020c354819438e28230835c3deb8108b972f68d014c58b13920c2f4ca0e18508272f401cd1a1c2bcc0b49051c61630c020838b3034d08420638a09051951a88cc888818d0bb1a0f1529a4438f3e4b88710c226a07f0ff489918a159ab2cc5587aea5a8afba158e2925ffacdb6f3363d16cdb26a5945a160aa821668515595061047d0070fd9dd828458ea0828a2d15da7cd1e8fad7fe76e8e868e1bccd0a071bf54d92d6d1d1c2799b158e1e9ae624fdfedc04e459c15909e45985b102a9d7b835aec3245828c01cff159ce702102a8c7b8fdf4422f0fa8eee90fc39c99f8ffac7c80adef8536aad6c3efa569c8486a324cd43b4fb59eb376e01ea37fe5917fb51a36883e5ffd888a90855d8edb24723a84d88234fc080862296ce881c67695663d4c03d6a88726ec90b228fa369d9d0588ee36870dc00c34d2828d82205765ed8b444837a74030c73ecd87da4d6d5c7d810b27497d1e5111e71c05acfcfffed92f53ed9db992aec9e932784317a04c33bca963176d76b5c7f564146c9b0e51f3dfa1f11e3ad2afec8517a31764151b6d7fc51e8ca6fe9c56ec5e8567461fdc226269a340662b6e6c22626882e06624b7471d93b0cc46c002e6c5a820c183bb24ceafb71fb91d46ff31e76df3d507310b62ae5c5904ac9ffc9792c68ffd5d4d397a9d40b01e24a7942ec779ec782f6738b4b546f55de9054d7755dd7755d974aa552a9542af543a9aeebbaaeeb3af9b14ba552a9542ad5755d27252b02d97a7ec12c216ceee620975cb773c69133a6f359480060ec67ef33e50183fd746eeff04ba65d104b2dcbb41aff8fac8fb34cd3895d507cc6719967cd67a7841fc0b93a5660999fc9da70dd340d1b5251adf3448fb57dd4a694524a29e5e669de0a55659d674a29a59452665996655996c9cf85fb0981f086dfde1e62c3256448665996c5185f861e577c2142fe2bbf813fe79c73ce193d21f1b339e79452be0c3d2ee909910f11c01f85a0086c800fc8fdb8df83d0000c5db1014cef10743ac281102c5b34e5c0894bc8493f101ea2bd5d51e3439b4f33410676d517badf8f7855d81e36f742405cdcd796b45bd253e147bc9bc702fd0f7e08fc2e21016702e7c500e4e58a4168288c12588461061a3808e3e25e081017e709e9be7a1e0bf465c6fa56b8d3e39670dfb186f8a56444040b02c30bae18601817ec868bf386702f64480810577daec7c5fd907fadb53e8f9790a11c25b86052250c2b4038b9ea0701027bbd5eaf204182c07a5cdcc35a2eee83c0562eee61d4c5bd4ce26490d7cbc53d0a5e2ece1b02b26406309c31440f42bc30852b085de22807495c4182c8405d31a8bebc5e2b570c591aaf97ab7e10195aae183c072f577d197a5cd51362a3822aacc09c14c1e18acb49ff4c912c969e7aa05203265c0e24499028820001451a5ac45cbec30baed890850ba818e25afdec4182b1372e6c5a228aa72592ac2cc1640b104b18414111a32a61722002abd245110d4f559c6e20825465c90891a82d502c012ec43246d3fd746c18634af6646d5c88650c25dc1663ecb0dad2721d7f5fb9e5967ca0669edfaee90999c02591706cb57474da637367515b514c99492aa57b4fbbbb5d3df5253527b4abbf5ded0999c035c43db1406115a3d4dad5ca85d613965f3a4527ffe242fcf2c5658c32ba5c3242595d5ac1ad4567ff8e326bba3441373f611ae3aa1b4208351ac3911209e1bbb9fe1f0140b8fe349392524a693665fc96ce6a8b5fa3c718b99845942c24a3d45aff97f2e5cbf73a631a9bdba3fbcf7fd8823a77fa5368fddfc737bf8f8fd3c93308b1b82df00e2766c1f537c1797474dc1df61f13798f04da059d7a9917718833583eca1ce98889f56f18cc83c917525215a4a9834d5dd854058825558c305165c846c4d20b9baabc9006952f54a29c926022e44b123b9ca04710a5245e3bc440d40306a72951443d62480a33460cf7d3e9a10c4e490c2e4b62589102438c2620c490c1aa09a72a239481dbb774765004f474a093f32f11b003c7c6f97e4b4745b36c4e2963556556669431de1bdeb2c1d1d1d19236383aace6cbd0473eb44c27c730674e1bf894fba3a18703736ad848adb2637777370ececc14eb3046e975f3e685dba39c99cc68a49af7e8b49e8158caa8cdadbd0399ed0201419f4053094849492903920c7d62dc2a4708343b2eec2d106e08170865ead5cc9bba402e37512bab05c2fd6a7054f4abe1a4a8d565ecf6964db7fa7a77777777777f3713cbdd3d2b143b531df7364652ad6ab4566e138a31375c7b1fef5116b189b1217c1f7f676884a0671a55b2b10b92b0255f93946a2e34bb12e24c79b133d571ac1859b7bad55ab94d833ef1ae6e5c1873614637679e9c18b72e4887475f9b1a58b0f5410656ab19da3b5204cd5cad9184d536d88a9f6a61634dd88a4f432025cc89f34612c459839bdd0ba247e1e8f4507162c71610eaf67fb16a4a733f1c06b89f8d125fae2b29a1b4448587ebde92ef5d908c36cd635d891f747a47eff0d7b8627dfa7ca0ceb22ccba6473d0ccb5117a82795c8cf0023c7f18217ae7bd30b945042875f400d56491071fd0a75f7418aabbafe2438e004142c85d47a185ca3548014fbd15cfe803c807a1f04f2bad2e38a5a0bc6e2688f468885ffd168a13436176884ded1dea7fcf911ee682fa59cac1e1650b79c08ebfff54877ef83572840cafb6fdbb6f98fec6a5f3556ab073b5f63cd871d0f9b6e394ce37ef1f676a98d94524afa1b2bbb52fb6e65251ce04ee93c3838dfc20183d3a301479a54a873c64d8e7ee58c29a5945276fa1953fa94fea4943212a5af4307879930fc8179b814874b79c8a5efa37960f74c3ae9a493663473eacc29a5943e64b2ac7d406ef45b37bad18d6ed99665cee29cd2f79a12b68d52facc449f91e87312942424286cc7cec8e84b164fe99bae07579893d9bec95e8339b2a7375541f0c13252f6945aebb0d31809e624319426fcc345c01cd9674f604ef69d61e956168339d967cc44b7b22d367b1d3a380c833e4c7c64df9365d9844e7ddddbd8a9534aeb9c1a4b0426ebf7a3b76b4a0002554b202931132371522c8b1281c97636390ba440a8b46d1825b564664600000800004315000020100c0744226138241ae8ca6a7b14800d778c3e74623c1ac8a22087411042c618630801c4000002222345c5194af49bb985e8279e531d72a7cea47480f407b73c31a08e58943948df798387cf9539882736246fdb9bf5acf6265b442900f40be0ae9176d60cdd391f33b295b01cccf36e96a8f340b25f245a44e36eb90fd713b454bed20f81bce28a7692431501be1c9e54a7b8039f3dc2025424b84bad7ccb61a26b967bf4de85e6d3b8a7fd4559812a9be6c6006238784f49fe8405f47b4049b78d15f7cdc8e1ab59d7818ce34b49b79bdd9648c32fd16baea024ea009f722ecefccc11ccbac4ed49fe24ea5dda4c2573a0446fb733a11194dac475011c7c39fc56bb1e2eca5514dedb54b8ebeb0fb5464bebca30d8538011888abd4fdc0a80d48f28c398993f6909864b2495fea4b8d7d573543dbdcf5a249515704fd5634c1c130915ae0ce00a79141f296a00bf95a7a686acaebf4c1dcbcc0e4fc022d2ff083f150150c230e5e98e794eb119f85ac08a7fc3bbba763601116a66c3ccb03e933f27f059855032a80ae0de4ea505885d5f84029d3560ddb283deca7a1589d78d1a4a2cca8ccaf0aeb0433aeb17d7a190b0facd831617df42cee8a7e0da68c68e4aa072a43e40a42626d1eed148dca90bf1f2a05c65dae79e4da89aa6ab74569810299795918e477e65a88b2637a61515d92e899c79969d1046d0580f688ed05300fadde1f413ceda6e68df983ec4d9df7e8b97d97706037c29eba1bd5a667fb04b607b61b9feb5be85fc9b5a38bdae86514f19c8f4821b8aa54d5474f9299b0ec3efb58ada4125dd47c32eca7f060dc5e8f9bd2ec70148671522717861def4261b167d28c9c168900083b364de97383a0754085ba819a88ab6462dcb40d23fb02bb30407e816d864422188c51d15f2d28b09d46beaa1bcc043cd337a722f0eccc3f738609a5a6754e0199547ce0bb914d30e13a9a035c9bcc994814d476c7959bff3fa5ce05a6d3b3e3309598d07bf0ea37156eefb656af04de03e0f640e9a6f1b57effe89c77f082ac7fd16ce7fdd49f42158a4770054729c59c3ba05d28658afb388cb08a09a167690650a3e0e60c19b892f60bafb2c58ad0514f4c8034a1ea932971be3329cd588847b5721e2b44d0e4e3c7116fc05309d3bde21fb82fbced9c33e840aaadfb75e98e953ecfcbece2914c3259de06b43611e5e3a8ab1ffab070eee9e815e416bfa8d1c7895e5f573149e5e6fe68c73cecbc4fcb2a9aa5931cc190e8a1d97996ad979c40671655ab9aca7b0b7b622d3025921a1df53e5e15ef77417ee024542fee782f3d5728006e84b759f16091a18f7de5ff1df78038c3cbe16e6fa708493bcdab98331ba3eaf596a448752f8a81033c5ce366ec705fe99e6560cb8eaa22b31cbd015c387e5d74dfe66bf7953d2db704a5331acde5a6b068edd33dea56db28499fa56d7b66a5676ba2572013631d8195019931d0f6bf847146c745102a3601a8ff8ae03c7d69a7385b841d45676b24fc180f3be98325489943301cdc84b46dcc6887cd028d83fc941b7e65c29a3444459031a572b7deb497dfe3dbc5c78709d630d8263eaa8d71fe1dea562d0d7f8aaa21f50f2dd59e66d342652036a934c8ee0a672b328c22e2e4728a516484fc28d3e2892c74bba9156dda8386ffedf7df75dfeb6e05daee4b3ede216da0f6d846011f98abad7869a3097f42533d48b9229eeea1bd1532c015157dc258aebfb1dd951d415f031ebdb4a4cd1c562c402c321270580e651b424c2ea7751611383decfa02f2bd6f9580902ab9fbe24293a344e1bef701133859d8e7cbbaefd0644e17bc8ad1eadb17359d26be2c1b48171d25e05668fc4655403bff80744e82ec20f0bb4a61de3d50f905770ebb9f4d74ecb35a3d3bd0b7e2e4794398bf887e4129a3c1a62996428f26fc7b16462167a155f47c05a816667951b7b4e92bed89d1a8b51fb9db695471983161c2c80272953fb1d286bc78d9a6913ad836c9c53fd0903cae00cc0bd8b7a02ef5ddc4195114cda30017ea9cdbc7ba677ac14ce158491b5812da2a68bbd7548000b348817cfe647f74c57ac6aa88d0cb9fba2860df32e567825acff64af4d328cd0225acdf9bc75a846f671ffdcf76077a288dfdadfdf8e93f6d6330b7761d05c6149d56c4f660d018fc516cdf51e2d4d5b4df8d162893551fdd944ccd3ad942f20f968e288152f3c2f64b21e354a8be8ec1ca08ab625d3f227963d2830dc17ea976fedd1d44fba183578bfe56c4dee31d2f59c7b3cbe7d8e3d905d75eadff60b0c37d4509fb1e30f59ac97f88fe01570db755afdab60e8f29735c55be1eeb39ff73337a1a2b058375689ac3b6ec473a1985e3257ff943dbe04fbf99f60f5d6f8045df5022c09367badf55c1bdcfa5f41d1fcb8d2b6dfa2e81e5aeb3de0ca4dc0385a36fdd17d67615bbe260f3dae54bfc7b61853a3d89beaaa87cc9a5bc2089b310f6124f3c0da1bb08fb11e44c15fdad97984ea676036a85438bd813ef2e029a64012711cd487d5383d29acf6b380a8c9361f8632178a3d2b80fee3c92c2a7d8850aafec1f7115b1d28ae24847f964c24cd00d02e160199f874f3dceff27d1ae12b1378d5ffe71bbd2d978a65a954ba02ca050b76eb8a4939a016fe073d81b42a923683897b9fb0fef99b98a1865472225d2b8f5156b689dd34bff3bd437ecfb1c1eb9b64ef6441d71818fdd38fad3e9e7b88a4511359645a6bc56cbb93ff2920483e6a32fdd20302d10bc1f452d70e37e0466e7b3fcba044b51c4dcaef78825eac7ea0dfeaa68703935817d65babe58ccff2216918c36372212584a248626c9091574a97d64766f4459ec0ff7ff8038e26b42867b7dac4c119c7c70f2054fccdac70e6cf18559788009c8ec7ddc1280b5b1280b44e37eeff3a680654401b1515a25805cd202de956f283b98c4e63fe3b59aa04d4cfa5b2d696cde12d7b72310e82e32f4dfdde960ad2729ac5d85743694d814c0602c85fe36b0564ad2af330bd10e3b772c248cb8e5f428fb72550370d59067d99198a9cb3af4227c8c941e71302326b9008106c97bd0f8e0bd7755f850baa3824bd1ea34ec699f4a1b860e11d87ca6d5d124822c21d8e999b55bad579234be88411a9217af81e634dda880fbb053fd9141b3f7baa7384ef3391102d02f8caf00481b82139fbd3995258f79c7368a36b9ec0082c6de16c923dd3eb47344fe049520b3a8b270af440660339d6782018cfc43ecdaae092151109a80dff08e3a75130fbaabf09f01b42452049c4f99119dd41da2b0ba9ee48a9884ee5296e4760a37f340af95846d3a6ad7ded08dfcb8f14315328ed93d29cd0b512ab845876aa1cfad0d721c526a8bf88392b6019b1a8d695927141de65f1fac6f3cc1acd01ca3be0a5b76cd7cd5347a5f59cfb99a85757439b9e1d992cce3e5d8a31368222eee680e00d74f90d98407ebb9802f282c6109b5a9c54f23ef5036fe64df1223ea1a20c9ad970541d3f9a0ea8d7438f46a5f453806c83a94d11a2790f70c95e885aa1f916ae75e61801318e6a6896cfb1fad8202976aa140ec9c030e585ad9355ca78ed2dc9e5470b988d5777310660081b61ab4378614b9753676963b075671d509b59c28018ed3f95fe18232d809cbefd65a8195f60acda0ca044a7f432fea8bf616f23bc53b6704d6a9440d99b4bcb0f6f25d2fc195b4a116f1e4e47fbb0595a0cd9802182f22e4abcd52c940836cd9834c0ccd1d46eb78e91a1e1ce1fd5abce67c15799c03d1f744a2d41a95cc57453d8fa509d15ddbdc3dd41ca66b404bd0b034daf1fd1e0a23709a9fae5c40fff37d2891911695b4713cf2d7cd9f57a44659365d0335db767af9695abfbf3828db358cc28585129c280639142fdcfd4712d7f1ccbef363363125e19f677000a108e304db8da468028c2f5c2714c68d5af40946c7fd2a3ee9a4f4095b2dae286414fcf132ec86fa24b57bdb1d5ef40edb93e26cce0d24e9633410aa8fd572b3626a365354e751a9084352c368dcf71424999a6fa99653141fcd8e83b8d2a19b7117d857023d113ac1565d3a6c48747699b054a32b7ed7256942a081358b0cc25ecb36f21ca063e3a5d56e4b063e4703769a5de761bcefd0ead6b81a65f8c8cd3edd45b5e89e66125d194ac749192c3b414b805347b3196581a69c16f409311bdd8bd6311e26a0cfc4f290f184fa21e92502954320b4fdb289a00fb8e530c8543f6038530601ba83c44453d19ac512619c474e74ee400df47e73ce2ffd9d952172f87fe88ed20015142c1d1748e9531ee933044fc25f4b27a4de8cbe4c63e8eababbcc09750b8a00c9f79da7c8338c319e6c9ed1480c110de39d3059b59b5628ba7a35cb71b994fb1f7782870e7e6440dafa768e20712c3e371b723f607d60a28e037e64c43fdbbb2a18898c521b4cdf1509073ba22520cd9decd7fa60fe2d5a29d07d036716cd02506256500d12a2006259a82c53a5a001adddbf6c8c41cebace94f56c93dc09c7b28d28c8809798bf3d8a7e64df04404956341f834c186b8b9f326905a78670bc854cbf836057c68969e047d5748adcbb7e27b9f09e3feccbba2adcdc5a4f00bea27051b011e4aebc1d6d80fe6338ade8e6c0522f84eba867dae387fed3fae3126b2b1bcad17ab2df4bf3bea0312f86d0b685141a189574b182468845e4b1effa60eeb6c2be0cdff374a0540fa81e9160050657f719360d1fc5498597486f3d0fbc9557c01e965ca8c9b5a6f9f7a45d49dc74c8b26f476b963b6b028f4ff129bb3ef91a9f11a367ebc4d3789e53e7c790a3af85accaee6f0f03930dc967600ba7aea62cf356dd47c5743b17beff5c169612b2b9179ab7d47c28ab6f058ba47298879455260da769e8c9675c9b4f38ccc0046eaccf71a17a96e157f26ce55d10826882ea81f0aa69dda31f5d53f07fd34705b59efc53179aa5c2050fe01742ae852610ec307d987d50d6b28202658be1552f519d3b1ef4229f4f35338eb0c8d545ca55faa7070ae10733e854c682dd53c9156c8621136a83575317f952a8213c41956eadc72f86b37f91b4a00efd6b96624eedd1c5a2517cf0b99abd9b501fb626f5d257cbb82245b6afce87f87a7ab99a2ee0ed661333861052c4ed505174db1cdbc19689fa1a618e6202bf8364ba7afcb088e047d6c5205806b19cd5e73350ba3ae1f69cee7850bc84d663850ca0c31c96518baefa56ae37c5df4801476f483235c86a41834125fd9f792f0eed5301ca37ff3bb1e0e30cc2f488124659c517d972001156329badfc7e20644a4e41620ded4eea279042377a3ad43bfeeefe72bb62bb483789d3d44cac88d8b3bf7dcd93c5cd02e07fafb8869f5c190816c26b9aca8d67923956429360cd1c077ab8e9d7a4c61345230dc7887ee44dde9f487309832ccd55380a4b70cd1a86b0f9506b5b901a5bdb63a060c8fc7b07ff08b3cc6ae926b81e0d0de93dcb9bafb1cfa7d8c575e43770cbca9325eec20301b9071b6202636be11932f08bd479e790b36dd3185c6cfe18f292d93b877ebb6a4efe8bd8b548a69ce7ddbf7b59943a9a27e32a11aef189b23393691ee43e59680fbc0db95622a65c4724bdc152159d1e5c79a7fc31352b43b57c15fa029fc1314e0ed5601e036e0a483a2ed97b4280f07800ca0d42672b1b0ba8bdf6dbb0056ced1a79743da785785e0ba87f475817080da03d261eaa78b0290ee3ea4d9f3d40d817d61a9e2ab5dfa94a27d681f32b2c1a9b7725c4b31bf8c4e1910fd0a25e418b932d59e6de8148776595fcd7733a93bab1e6a958c25832f81b4ab511a2bbf3622b6d6e7fd02f923349881864f4a0a3b0a945ec375ba728003f06b6f7b751488ce8c1730562ed4ed24307a0d0a59741fffb626cfaf08da0a829377900a7d884b40e7e4465ebe122c629e31652a256ee88f088753c2ac8f1d32f1683b0235989fb69b342900690c99fe41253fbd546ae62f3f47643ceff06fdc33a0289cc81ff0cb5387a56b57fac89adcfa4437057b0d5e860ea328d17dbf29f81494bf9555fa30aa19708e93b77f3d595aa35b202068ebb2b5688a89792c24874f1d10854ba0f53994538858fb4446f034ba06a09588b126e26c94676e07fe4a8c1151b44c930a03724f4c7a57764d2ecc61b8a9d61f225730956f3ce786b3b7d006b06dc8771da982f5f77a9970f62cab9f1ef585484a9f8816de7b746fb0b59adeb6063d8c3cbdecfa2afb603ba227533bc0ced4dce56ab5e4787d0109e2422c5d21cc65ca446968a926ecb8fc6acae820c73731e3f9b7baff99f51c3b104aa04b1ff1715a34a6a5f9ac3c0934aa536c0f861d0763addb80d90ef95576c9827e1c6262c2a5c99fda517be2765731c4f7911fcb4ad8b7f1eddbe0f1c61b623c450c70526f79ffecce24946fe08b9eb71a538d6f023325d02369dacac97e4dd74a7d55798bd25aaa2891f45e8969f19ad6a0cd1f146b2a9525cd76f550e08b872d3ae36be5de871d2e29d220d846a626ee6928de7a6aa0edf618fcd23269852c05f94f85346b44ae709110fff789879c5d86b3ffd4b34b740b489ccd3e89bb5bafccc4070b812509c684759e1f6f7d42e6e6d78ba8c58b5149a443b4c2057e0332fe854095edc24bec2ce6c62fdccb3a59438a150f23fac4916e3650bc87d6fd33d2c5bcf9fd8623510cbbdae4e1e275e0775e11994a645491222e6c485e42427c70ab18e4936ff8072e4369f3f27132701216f1b540f6a2798e50ac2a2617b295c1d769a2b8a860d1d6c2fab7df872544a08ebb280d12f72379b9f6c84a72107f0f220d97fddf950812279178f72d8906af441b4095a2c51ee9774c4460d415b0b06edb187563a5774223c108cc9bdccba5e7bf52bd60e6bddb086be449d0162d490432a29ee2a8c622a1dc206afb09a406b743253b33bc5e0caf133931484895a0573854067d574e5b67ae4db3c633752823f66400dec428792f8ffad3784291f297ab0de5b01ac3073b7bf799fb7867790dbb5ba827ede9d21ea8514c0f0ebe6469a7d82f10ab0e698dd6c91985d679a85a027f7c22bb89791e95c90840a177dca9d6ea410b7a41d2d2c0943352d4ffc33c0c1e504c4215536195c84e1f4c3c5f4c7a935c91adb8d1dc5e9acc4e8ff60dfdce93c23afef81f002da343dd9665bb573f26812944d22bcb99ecae794cec9211c465f24af6ef3af41fac4ade0e0368a80178ab63f949650e97d5bf9ccb7748a1caa942c11c01b4daabe14b00be588a9eb67d55befa0e5e02a10049c678899b4404d9f826753a0051a57c1959f2d41d056c81b67a4ddb17eb5537cb4106fa1e48d140114bed0e656b2c2b71fd022edfb3162e585350cc21a7b98d5611e19a3fb17bedda3bb31b7f93a1105e5a2bf3bc4e2be7209b5c3cb918a1d33ab9d436b91483b1bda49fced3a1280c679f868d8ca62a32fd58c19342148e8d13207d6d74ebe348c7438c07f430c6d3436e5c032a397e7ab047931365ddcb242d53fed2d9831514cc735f85145cd81a709b79e4f2c945f4c40251836afbd303b8f2c0ccd52b68f9137480a4b0b04234ad6ddaacc751a7e2fdc5bbb51310fc1ad61b169614ac03e7ea543512f1e2334b3bd7fc5081d0489d245ffe661530b64f686b205f1860e20e205accbc54a6008136ca350ec08cd35cd40b610069e2b25618057a1028c58136061aab70d16edcea2f6f010e1f547c8a37a1c9aa889707b56e793580aa2e66af9498f1888f71a3dc6a998d961d627e668524e856839fc0d710fc1294f8550067851d929e3dd12cd02df1e7660c33d5da422a332b7be7c245c3cf48548e8c66e21fbcf3cf1a8c18ceadb28b1cad9869444642e2586789494eafff3f9735ded075925cc00c2ff8433956cb755279f2cc91ceb74b5470384fe096dd5a5cf6b9558d1e4e4a2bf638317c9f83c24238257c357675f1623129d4b246b74959cba6b14e12390595ba3b8f098de3c45d06f9d476ce8dc530f523798ab93f6a0d8d17e0b2637f62fb40b10d1d003f577363e0b21154bd6ebbfe0721bc6cb873f22be800f673c3ff968567d0a0488816f892b33d09ea2a470b797165f1b02ca42b5730ec98783d0f2186d8e924c1f33e1ccbcf4bbf6945b8a2da5ff6465988d2aa93a9caa67899f49a6d6b1a81efa954c4dcb4e14fafd3d565fe80f83de55369d61b6c39748783dd75ef5eb411f6c45df34e027740962053dd14695ed3cc4be3fd1fe4c15f162b71d243a05cddd9acf231c22cb24440a8a4c91a808861ce1a60628d6b46d39dcdcfc973cd5ab868cf095190c34335fd547227c016bb6ea7713e598258b6d8c4e394d3413c655ed24b9c45f892f84864615a4d0b0c26219ca57b5659aad201b52044d62221b3445814cff4e9d6ebd4291db08e8c67e4919faae5989ae64aa04645d123b49aca54bc71990d11092fc2d8842c36679860f1accad4a9681c92066ca38cb3368651bfd56858a6323943788a76442194b65675783104406da25a5c4d7cddb5d48e18172514a1426361f3a13bed79ed71fcd4ddc1c6134a8a4aec8ad57ab18114a499401de9fb335e8896e238132ae8528a42a906780a2d582f95f036b0b22dec329dcefa1cfc412b63e45db687eac1482761278b5bf901f2434fc1b01e8bb74fd1245496ab2f3cd2ff2dcc1575ea8bca70aa1b7543da9f1b524d0b166137e46e1bff806c03dbdbfec9db863d6fbd0ca1a34dd8c346c6e32a73a0d48518b69cec34c290d00157fad086a37d84765bb5b8cfad56c90b39708ffeedd817d29845d077c9a09c0dfed6e1274e465dbccc8432dacfd696e52a0e1568aa580cddaf32ac9b1f8413e885753d8368ea0bf10f42add1de09829dc9b937a66888f0345408b0154c025ed5bca1567eb6147c5809d99428780ad83a9508829bede6ed726dd2e12f57c0c6b3e9e2a05384152524896f3f4ab0f68b97503a69f6a39cacb0e16b1beea2e4747dabca532d0e4905264345db8da4943cff904b8c62989584626d52603a4c51bf15c5b05aadd2c1e07bc6a61ea5d3570f47154333a83a6bc06dfb0f4c979b7b73017b8c8200be0f7c5ef027de64dfa93b57caa56bd89a62bc1b749f7fafca144bbe6edc5cc99b09cdbe793cb2b92c598ac86a717af7126edce1dcc872f3a3c6d8cee9b8a3bbcc3ae0be8ac026071bfb77e4d60b0ed04469645ec80bcde5c4cbf6fbfd15ba40e83d93cdbabbcd43fbc29fd55bfba00c484b144652e2ec87ac8930f4eace0c4522b61f70dd51627c97ac592d69890895c2f6e397085c4d583897622e039e71c111a2cd04c5dc9335ade5da4514599739bc1661428bb2e692a71a8455b20028c8fd83cb35877110766b948c82e8bb3ca4d952057c3c3a9871746b9ffc60ed176bbcc4d2fc6b110e6cfd76cd5271280a62bf9e0a0f99bd784f576ec256e30f16a0435d1ec80859f59ebd8cfbdec1aaaa87a6a46b79bf3db91f5c582fca901cd15e09f94bcc3b0e723d5ac3d42d564d16393f0f4fe64ca9979d83c81caa09a946a4d30968a6b33f2ff15fed10ddf4b0a009713c3681d8f6ba0ba6b81ec89fbbb5560d8a424621041beb473c417b5c3ea93c00058303124f157b070b6d48aa4638c3f3ae9dd4ffa2f97a46cd2fa94c2447fc3d05a74b136849b53f268a438af6c1e3471065c73dd5b2438c4748af21efed9d5893f9ea92a9494ac36dc4898a2f3aea45dabc155f27ecf088db481f29a7f4f3c0d2afb41ea64b5ce0db1b143a78e0aee73c33fc1841c133295211bcef1d0343be74557be083c791bfd448f268891eb60762529fc110db0854f6acb103265721abb96994053cc67150189145af36c6056b9f9f1b23e1dc46abc00792699e6e93567ec3093c22a56b6129f146e1ba290105a36e2082f4b5fe4756a212e48d7f914da404bdf13fb2149100bbf10fd98890a0b7fe47465112f44a6cc913939699100456edff935d6843e0ade410b6e94dc50e148257b59ebd53c00d9a4e4861370d93803e71bb4e28762bf9c0a2295f5789e04877e0661bcfd340cc5d8dcc7c38723902fdcd2cac8a70359cd8284e334d4231588b7a2bdbf7b681ec30db6e437ebb51c05d7adcb2b43bfa926516275faeeb2757b0e6b4f1cbb9b4936f70bafeab648ee107d91dc35c5784d8b6ade011f87fdebb87f05a259779c8cfb8fb21d61d7b13909ce5de991870e7dc1c32dab04959259ddf178925326451d2929016292bf05983486ea43039f9708e9f058b0b2428eb442fa476c136db9717516640ddcecd8aa439e0965230ae443e96563f01104fd0601fa4c40a4238a7bf6e1e0b134664db4dd0c35a0f1534756573c9be7c565bbf1630741cb23664f9edbe03f22625c286fb129b20f6d682c87beefd8ba8f766786597d4a14ac6823a2fbb92819b65e37977f5a18bb849f9f4996ac209050045fede135fd015f87292072a563ff5b506e364521703eae9c44bf3dba1c41b92e590c06403a762c3389317c6e83e359bb53550844b7160fec38a4ed70c06706d3761cee5158fed4641e944bc3b21fcc1bd03d30a334c3f1a4ab9499c242955fba86c82bf6a81c16a9cfad4f00d84f0ad19679ac889a09ca4b319e0043d59ffde9a3acbdda3d231d41c43ee7c1caebb9637efe24904a34438ce8563e4efafcb0accf64475533f3b5ef9eb4bce3cb42a399f7ac5cea21a422b2cde6942e13707908c3fb65b1ff1722e85a7bea45a1b507cf4dac699055c1e9c280b30f32e9ac1b6018d6ac03fc74e70809dbb7b0c1cca8897c50ca5d9b349b4ac5fcb79b5a98c8d7183270c55e3a900fe28e9f904549380c4cbbee41a517c69e81679b2ab14d5271a36813c73aa9dfc06bcc9189c811bfdf89df0f4621a198e1b918726ead1342ee51ae62012a2ec73f296eefcf8e75707b44e8c03caa1b8af6b6b211b2c3e0823060b46bc7c9f835c10ee3376181c571be848fcd1554f9a972a4cae71b1762135aad1c3cd4c021c603662a993d3bdde2a7253de62c3a77834f64717dcd1a02dc5419d05df95b4158860cb29002ab68bae6c30aaa9a15986d794ddca4d78532fe1845eba1260181d42d23e7f0811f9262b6230a0f1fa1b64a68f8b733fb743137a84abbb4151f4239d3ef0eea0bf1b2a778c342a52efd05eb824363d532ed6d7ac90d5cbe0289dd09f2f2091af6de3072e5f6a941514c610fecff02016ce9007c742273e8393ac6b32cd3069bd0c05df2701e88d6d151efaa1b1f9d492cc9d3e7bce96a096ae18d9846a70cfa3d9098ee741d1a3cf93ea932686275288e9c04531de8caef7fb0de90f532c4d4cf990c14de0be8d71b67abb5c52230e59d577001957ec620d22ccffd57638dce5b5c62bd4eb3c3057339ae065182525ed893799b07b69bc6c55f75983d609431e8a7462f3c66784f3e26d2c2e57b32c5232cb1acb39144e63266d7b189bc76d3dd3a76e2e05ec9259b69e2a33060895565f184169042f2f2486bd9ffa53e35168d5133fa32b91d1b27b793fdbd29a1dc1503d6db902ef2509a508000b63c3791589dbe877024bf7fceaf74e3fec2987ed9ffa0a6fa52b189e5d4ea02ee00700790d9050f00792eb82cc02b8793b5e71a4c95e78a20146bf98d874d480d8b04047781e16ceea71d82a545b00ac336290e1e99a9f8bc323b6bf4dbfef4c8da7cc7fd8fc028857fb618ade4b980506b95c268d2e46c91c8aadfba1ad3a0742da37da2a75472f48266d4d93f02d1783ea206c56a637e4c5d8d87917d126af480b5a9429d120798c432bb821fffc4f11be839c8349a8d22a1abf24051514e9e01da73669a9b7b318804b1ca7b2cce2be0268a2e2791fac952a60551ed088dda0fdc4c94ae3b8e3f3654d68560ccb8966ca029cccbdc5c6ebc4fe2054bc0136330396e78f5694836636d56ecf7c8ff07774bfce749d36e55c342b91f52331631ce64378828dcadc0120f568561b809becc9228e989c57d3eb616caeab00bd2e45542d2050ddfe597502b6f6bafafb6ccdb975bb0c0def2e271ae91292ebb50c2a13020f1586ba88315e76b16520dfed08dce6ef6ef29a28d7c0d1f1c26b56cacb4f62b8626d099a07dc9f7e8815caa15ee28c7225a50389961d300cf40c743b520bf863df8c34f1af32fa20d311539c7da5a431ec833fa952398097993488069fe40052f05f8142a8c975abb8ac6f9b5c49626c315c32297c708022cd1ac5979d59c9602bcd39b6752fce0556e412ecc987f10c6210c3f806240363ebe897762d90169d250052be3f9fe3bf580ab86e7021689355d42006b2006e34bc220b180f82e555180ce6b63069646787a697522f03141b6198157d7f63b2156aa638c9bf8dc4c442a360cc851d570333b094456b8e029024ba3eca4c0126725881185b26c32da7fa8dd7719ea39bba5fa74863955fa0adac253134a1c5758368f9dcc2d605a70b5d602e3960af88311227bc3228ec35e33dc08a5ab7b4742e71dd4cc0351e42ac0c47b58b1e70da64bcaccab2286ebd3f2a9c75a268dc005c20dc631d67d7e58d4ab01d410a21570dd7784f81e5a14d960e703caa783f026289d046e0593ebca4becb1d6b5882136d44d8d307dc75b3f3aaf5cf9ba26110475581159c1d43ddcc5c6b1ae8d4740ffa83a76257756e6a0249f9420461e688b990f3902f238520ba7b0487c0de4b2321cc9d9b5212a5479ba69b43c09768081199c88856c420f4327e44abd50652a43ea1120a9318bb4672334e95a9bf3dead0e21a0abd952e71bfa1ffeed4316e3e69c97d27ce7c2d0323a006238ce8fe0b240d5655cf5f940a67b1ee9be65364aa8b33bca9008c04e135c451d191b59ebfd672d4d2f0884a8f069a8c8f0ded4ea2bd221fd14e40a156c619655caee4f94ac117ae83a86ceb70a5f936fad712e2c214b55b027625d2b5edaa081a7f2fb0fee7fc458be654d779107c201a15e105a36f1f051264e801d44d90bb19e0502b84f7d8f2554717326037cac6cf37b84a9f27d65fc35b362ec6681c431e29c0dda3c48bace9b514dae66e312c956cfce068b75231c6d1ef9558d2660cd6179ada83b00abf7d2829a9f03a8481a3f410038833ec2281d1414273c65d8332713a251ab159dffd5583186e40068eccc91022c9851541e1ac499f484c57544885d214dfcac3e1f173a62a311583e41ea4afc3e28d2b79fa2f0e83f29d6b551dca32d456322ae5adbd47096c21e71ae6781544a33088a3da35e2c2bd04ee820221e7ba30e667ce8c6eec0183d0c46be6f0862b7deac8e93fdedc4e903d79a043243157874b4c17cf3f6b8c1de9fcd598797e4f04c2caa32693ad5503052a8591d6b7e716a534713135620362fcfbc761b26a0d6fefb3d29a831bed002e7c0f4db8ec67a02db101cf95c51af3dca0b2c9ae7338d7a7ca769612c3222157e208bbaf080830edc077c53e3c98aa07988b5d456961478fc47ff9338f37d4880a7ccbcf4f2d1dd9b981e386cae96f0f889ab1531eb7961599b838f12953e5fb2cddcc35989eb4c6df0d839bd3d83a6eb8debcc808848083e9f4ef103a60f9a4d020520eb0fd3119206deea91494d9bd04fef244307206e1b57013d8c7225e07f79d11e5771a00b71f0ae4473336bd038edba18953059acd6fb7d3e7b527504409829762337a433c26e973bed71b72cab6664018587386301db487584154fedb91b7b9a0fa2894e493f79ae644b4204a00bde12c16101a281eebaa587d0e648d4e8e745304c27313e4ed2072ac6ca22e3cbe530cf214040c1f2378f70dd2f1a80a668833a2ecf32c6f30d29cac4b5b8dbdbf07dcf06e4216b4c7a928a3674147a3b7630afb0a215d8529ed62e4948979cac789bd314269e03a03017ac08ca9b5d8cc68680e09a81aa1b9380769e5636a63cb0be6e2c68d24974aec66a9175fa7ea34147f9da0a9343bfb39c554dff7dec60ffabe3cca663dffead2b11e2428df922120af478bb7a9d7055b3992ccf4ad764b1f248b83383aead1f5a3e7d016d9fb61bda7305ede6580eee58e716a8222dca88ab27976a03d03eb71a053018ebaf80a652fcb6ff5f24855b0ef247035a0d8e4eaca6a9259275065b0c149a376f832c094565644a71519531d8962e7f5c1eb0ba754e93c52eee3b2bb4319ab36352a92bc04d5f6b920c02ed6e19582d0c5060421dbee544eb55d928dfb998617914ab98d5c807a62545d64e549bb520b47815a1522145ae9b68c585b47c162aca2e4b498ee1a5f91864663b1598fc062aaa98b75cfa0c468dd3ab37bdf60caa858a89afecac57c11891aa4598619846a64586957d7f4e3bd16245e8fd6c3f1681df2efec49d0fb1ab657dda4321ce011acf30c5d05330a76577b1bf0efe4f048502be036b9acaf8f7d2bc54434dffab846c4d4579623021ae2d3df61225b225a2da40599b54c9defb0c4b9972a898a2585d04cc9608ecbbc4926d7b69524dbc9177e5c73183f45f271025a98dbac91e32d3714620fe5f9a3c97c14fbfe196f821d277bf4fd4dbc96ca10857cb42f464b17fb0c7e5114308cd7d5ba042f7ac57970f1e19407a42c62a288d608a858a19ff4be961a26cf6eb5e4c87ad8a6fd4e3335268cd01ef5afd41dbfbe729d113b70165ca7e03ec1bea6e5f00d6d7a0dcf38b9529f5d39e2feaf069d5ce3e446c5d2d291db71505fed2a08d45ec1b5c21d1266b5ced2af5a4e9df01a12ac5901b87daef6cfab4b13c87653e742d8b74fb18d1ff4c761d50dca07b9cc0305aa5d21bf8a5ecfa9f861de059ac04a1770fbabbf3304d31b62b11ff19272fbf19e1f3a44a611794fd7109b8a4d87231631edaf1d47630263daaac5b85110fea333c6451cdb2416bbf2068ccf6e913919e569d0f1bfc2886d28305c9b9bc4a05db7834daf91536285115d69e9521d26c9d3d0810598d2101798360f8c3691d9eaf6b19e24f4da1bf13480064bb44334c06f8c3045e6e4868289677af995958145af994cdd28ab2fd1694fe1044e23a27dfb6d22940ece2a588883b40ff5034b11715cb1dc7558f0f0953558b4c8add36ff8344bc50e3e8663f725acefcca9eb954bf7c4ea821f469c472a6b6bf5f1fdcb2cb26561761e5553742a72e02d06ca5d12695fd431a238fb1c84671b7d25e08ed31fc92a0bd03714fad1fb42cdcbd3e3f181ec3e69d241f00c010f45b1719f3dd48b8b4c2490288493dbee90759c25a9aeec65b2436546fd271b00a465a0bcaf3b8f4a29d36477f9e4c2d432509657ddab93cdaa4f8a4e19ed64a3040cbabed62d5dd13cb8d5873757e81d3b3305ed73bcc0ea61dde5d7987c7693fffe64e48fc0415d234988406a8058916e1da536093bb2811b27e260de713d57e80c815c84ab269d3124eaa727acbb09f8188c3c596f48a774da611ca7a3cfa165cbe53b19867678df799b5741899a1e03c51c7ca356552571bdeec2043a103c1b02a8a47aaddcc16cb1e1482b1bd04caf56016cc37dff8abe412ecf4efa44377a531e9c9506d6fb815a40d909b7aacad2fea282d34b899982e9212cc7f0351e59e34113c3533f272930024b653d1d660704c737714f7d70ee674f207c09bbd91f092c07404978dd91302c4b92ab8c45ea3286553ac342504be64434f566ed0ed0ac011948b99b9fac464a82e0ef5447b00fead2488cb6738b7c5dc39bd97b6a4d515d37a7825fcebfc84da406e840f463a9a372b1af1ad5abed9ce2ffbc4f576c1396afe0ee8820492437302d1c11842458199a22f07a2d164ed48b351ad988ffc15af7eeca2cd24c863b83c6b06805fbda13f062872bbce0ef2ff83ab278e6cfe263121ec1bd8b8b597e21228ac72623c5bd72df52c780d84e2b42fa90bd968f289721fbe94022bc58872582d9979ec9651834eca85019fba4697afd3ff9f5ac701f04f004ef4deff11c31f4be97394fa5881262409e5acd65c0300830ac56b77d62f25d1f70edc8594e1cb3d406ad6f924aebf74c5780efc0aa55e380557c508b9a5c6d1f45d32e7a82a9b8eb3ba6b2b0f51739c84550900cb65b47bdaefad2d51ce8a034d1b6eb23e7223ba5ab91269a91f948be295ccf177f19e437a97e00860968cb301cab451703db1291deabad2a0c5758863ce343d671856554f24891025296dbc7a058f5dab9d878547a8aeabef760827b97f6477e60e23c2e80efa43fbadc0b4fe40adc49fb6d020c6619ff2f531110a00cff2f3b1108aa8cff2d9348084aa988fd0e0dadd4c8416a837f587663a1ac7bb744b62c8424c06afc5b3642247835fd5f66421258b5fe9fb253368960cbe21f19ce0282874e9e064d7823c20eb8b338fce4af99b3af378094e9ac10b6e82fbddbcb4688090af44bcfdb65e042c69c429a1e5f42db6a7a2761b4b5323c8f0c38bc5018f98ec00653adff939950045bfb3f2d7bb36804d5e67f90ed5427744c771deb30000362706df29fcc443d820d6d95d3525d004e720c7f86c221ea84fe0dcceb8098750df85d1590769e8f99a6a83b731b4f6d9d02ee471a8bb9edf3f236bce2c2be1ce1d82cc225e70dad97a7f84f089b0c371bb8c27c5f72ca47dd51e95dc491ae02a6bec5fc4b4b1be0d8d0bb1eb0015a70e5b6849fb29eb0d67e45f15bcffdc25cc44940b562b0fa2d36b94a624f95313069b6c4cd602b76ed0fd5de9046220260d242dc7f5fa39bf361539d2f2b8982eb8aff346dad09f4a62c7633e994284ca266abab0133581dfe88683bb80cc3919ca9db8311fd844621e2a6a6d52290000b0bac8506e03c18e5637716e97f33633c8f15700a1eec1defa9dfc86fb29a38d3c77f630cef9138ae18023b4a6fbe91f9abd25890b94ca7e2d65440b9776dfde9f30eb70d8234261a56b48a082e496e54db535cd59a21104bab4ddb54093842d0b659a30271cfd4cf7ba270ad3090094032006d350c3cad5765ab1f7e645c0008221e012a8edcc2caa5421fcc7031ffb46ddf39d4434cfb4cd3affbaa2de46e17a6a7eb45a699e6c6294a5b10e69268b65c3386d9d37450f75e67cf106c51a147e66e6ea1570c6c6549ff7ef3f35177418a43e258d25f3752ddc3d91877377dffc587410588cec223cd22862543be81ed70b322ad1b0d1f2c015d0cd16ac2e7ef2f2538cfb4769a69071fde90e72d6a47a38194309222b3b9020b33081173460f804c9cf52ebd72ba7e3a6e8bc190c6b6f356053be20716766a6edac61071c446107b7d4efd7250492cf0b99e95227711b367d003ee3e10bbb74158c6c792978db8bf4e636b2a089fd88fb4ab73c29837bb046a0a63902ee953eb087db5d3bcda53535b182968c133fe3d911fa00094431775c7558e38f5514a5deff441aede08525ce506f13f63968c6f52dbb27933143b29905b6244c8d9a4e2f0b9c683ce4916902b8abb6a4b92b7ff1e93d555fe254c261df38233c0f8d4def8cd27ce407b2bc188d97e59ab2d41dc46bad56d32a7001a1a9edf3b2152cf01b3639c25bcfbf50782cf448d306d388237fefad7e18813e948c96ff9a1d5912aafea140c6dc709280e480489c921a4a4b4f1d8127f432cebb4fde39ba2ef5a71bb2f04874fbf093c73511360e7233367478ebea65760397545c686573901e05bfdd32f9e3776d2f3358a9b7310e0bf3c91107cebd92c337b76cd007baf1ab28e205a44cb08b3e33ad425f67e591530cdc5aee007248616bd364076362ecbb0a86dff0a551a75beebe27007c5421ab60c6fcbf4ad8f03ccbbec62c31384d922da77c2a83a4acf31592efc169f289acab5518942fa9d9d692091a33ed187407131b0aebb4fedc93cc68dcd28721ddf78ff246ccecffefffd7599cec11f60f6efc056c77205a03f216e31311d48f6b752ecf792f7ed00ebcbd4ec417b19f4c3804744107fad37ea770e30d65238fc7ba6097b208ad38763644be9c0c332dd57ae88ebbbc1691108602eed0f0642561643eeebf490015da145adf528ac1787746becb35a47eb95921645d8f840a2b796515a23166342c79584534b711fa71e8774b0b9aac1ec85ec1fcb8c988a3735e00fe556f974a696d83bf2a241c7ff1e0f3746a14500978290c6f6c7eec8520827d7414ffe8ed2013d2c439b9ac45198542e21bb271b40ca78505a8621c375d9c68398e3b2b3779465f14409a9672cbbe4743504c6634bec44fd0f87be8633f310e4de63b45a85fd2990acbe8e75019a005402778247532a463248ba28d889b35ddc4191178dcff5fd1401780f8ed114d2077e44b1ddac8cc77b1517cad4504a6f1d910d446599322a166959480d3840a6b768aaec05e168c720442cfb0e4a74b8a8a6473ca5b611d383f240a1635107c47c6d8b9641a49074979d2368143485c4f539808d38923540a75045d65d79b55b565e2d0d79dadf7ca45e518069a415e848d11a9dcb44882f342305f675c40f52c67976c261250bbef3178f7a75bc86637f4bda01488878d06a207066431e3a087127ef412e8e92b280d5766c43202ad36e815feba3f2726e1c0ff602ba256a8965e74ed92a01270a06a1086b4dad7f2b8658a46964018f6e4567fcb000b87c8577a64b80512ff4bd460407dbc303e1f5f1e8422cfde372f803311610dd08e6608166b3d7c0a077521eff7478e4a179054dd7492ddc884d07e0e120fb4de4174081ded78311cb556d9002073c0c26e21807d4307bba4d2c257b162c48405e2c132cf618f360f7618a41dc2aa89c2315099a9574b3ab5e09e5d0a3bff84c9ba3000b431a140ddb782a7fe546b508816623ba46717e9f99ecbf5f40de79c2f6bb6ff3a486bb75303e18b5bf7b2cd160b32271872428972b5d45000472d7edc01413b89eae163f7814fb64b80da903257fcd88c835b04f403c1e12356a9857a9d48dc0c67276b3e9d2d1eb790ddfca080adf5ac2eab4e4931c1d2c5a59f2971e270b724e9ce5768ab0c6ef57676c64723b5081485d3f8207ac352adc0615f86f489d624a2985c4e418b881c069561164e8eef74a33a8487b99aae0d7b593fff3cd719aadcb002d1bed41d4ef199dd25004473868a9d741f31c004ca4ddde6fe2cee5c888c50e9d32d19c9d843f7bdec1f00352b0b7b2c93945b37054141295f00e34ba9b4fa53bc7e80129c2d245ac7c97a91197db488c55cf5ed5d81f523227fad38014867859f72497b25830095c76d1c5e5891906c5af208c9077ee5cc3b3b3695fd298f298dab667e40aff61aada0a00559a72f00b2bdd401385d401b6993f50c8a141c1027270b586db4010fd069a9b1c904624ed790b7b87ee7e107232d98ae644231941f134c74923c5b2e8ea37a0ff4d39d87c47adb24c9ead6eba77c2290343d7ad0860c7f5361c4d33b685cb49ac12b635b265ef1b69689b9b9ac3b53ca17872072e331ee7b8253c9f0bd3294a9a9d71b4a315f8fd3bbfda371ada8f841b608580f3643348a43c5c026185ec3c8f9b5887ae79c7599c29cc73a3085ac818459c14c24661fa1351282634039a32ec0bab491c87beedae85d68303bad40e2282a4aabf3cc1adf8d6eb8d2a1943e52cc0fec2ca82af82227a2fae015c33e3b35f8e88974534c25210fe64e1a9c3e09c835af3a0929283e1e2ab0c5d0cbf83d4779a7e7c13f670a6a9bd81bad53ac27af47db5369cab618196689002de052dff8c5d1c47056cecfaa2b925ec4b9f4c69e5575bacfa31c8efca19e85cd3d64b653b836fde849caf74b735f82e83897dc30d1f9c303364d792ebc6a484d8129a355579dd26f4fedef722e0efa6000519b28db121744ddd03eacba210116b903bae5db4da440e77d81e493a52afc573249ba5d875b2978ca7043e17faca024e9aa541ebcfda464a77f4c8b6a7d4b835f5fed70ca679c5048251d0b86b7c11efea11a2598d3231c10e08f9c3990cd4d0b18dc5534e22a2f5685401cc78128704d66712ebc6bbdce32da7bbe4ee55b1fb14267bbc1555be3cf85afe9d3cb0e9ac98123919b55d75b215a70a97148be493f05ab7848403e645ce6d909b349919cbb994e8f980f6f6a7518fb87912b90390dfef9071485c294b63453d67d5675e442d3f35103613f7ad10808af5eaf2022126243816b33077d0a708e3385e396088c9e26f53e97af59fee8515e349cb500e55d81b2fbf4b7f3065d295afe152841584317f1624c492490dc15941957e1b8f07c479d20e0d8a1915391c5c0fd8f93e3541b8d9586a35854f6215c0f235d47b1f118a8d3923b9e119304baabc2fe3c650038619203d9e9e8892a0cd8b2dcb3580f9feec752ec9e1a0543220a6068524b84d4bd8683aba7b3eebb84d4e41d2214dfa058ca7fe76d0cf6d9c051755703634e3e45ed5f856bcf0b4167041cb3c71a78e5db42f8aafe9c1c94a7e276134ed1d957624919e9efb612324de93bd50907a8655411db8844a0b656ca40f84f1c6e1329ca422aad7b84383495b448001cd248249ffc6280eb32c8db2a44f7387148fac0aff029474afd3445e6d0cc63ab5799332a597a37a79459036b13f63b60310218893645ff97cf9e0ad9adedbf3cb2dc293069c55e23ac8e9eb012434ab9de9f1f7f5c2448a35b47f5cb703c7d611e8a7355def9a2eaf53d87b7fa1157338ef8a2ebb68dd16dd842d1b0ba34dd75dec52754bb0cde440773827a512e0f8948b009aeef338b8c3cd4186a840607814f876cffaf1fcd0424869c45324e318f5d4b507d603d03e26f1459a73a6359257ff7def7e6c51a7bc095008ed98a14d5d2f7087107b414f1a11e30e321a71e20805cb70d9a16f0cdeb22a918fe3f192080c3a2e5b95511e286a074cacaac8bba38fcfb4863443f5601d38410c7f3861aa04a4347b891670ca4f010a31dbeb664d910c0f771406e3ad9d2b68b318ea90e620c6e293eecec196bed9d1bcd5b183c1378518bdcc1794107b186c5a2247d8f19b8a8604df6ddd0280b368e48fb11979666a24aa5d3d525b27c23ea8865086db817e129171603e1c121d4183aebe9b3cdf161998c5609111e28d41fc3e21b4ead80a0baa0129fae4d1f0e006f65eb6ad9268e52a7cdef8309019459d6bb1888d78de091e363b5446913a9a3fb0f688c81f1731eb5d0a28c2be480fe1558230b6183c8ee2acd68060fd3cf98d443c0700702e90abb0c3e2c739a0d7e3efcd017ee81b9a03f698de4c9f85ebad7367086226c75d34a57b5b37d964bfd30898ac4168eca3dbb0971087b394c331895ccc9600abb063ba2012bd769646400b3378db0d716ff1d45a827c3a80066fbf62c82f480079d70a5b4787fdcb3173d8c237bfa61d18377037b10fa8c8e162d1ef94e3f0b382928f5ad1825d96b44ec85163f10330f6f8d07de7bbffe4a8541099395d00398a9543d5b1e867e42934e758e431e53aa4efd8b2ffe7cc1b4198e41f0c23e49ff8ee6e14c301b29aaeb984a233a6ca3b81f4df4e618e215b54299871b5717a6bcdc9bc8ff4d51c9166b65c760dfc45d80817ddf84c9740e5ec3fe9afd6075a367b45c026be56b18a7a63d38cc81a98ef85ea65a339cedc5f2758929a47608a90292d63bb531313602e8c47027e7a46848c2bb484db15d12fd6c613c832a1116d69d071f418d0fcdb1cfb3f6ebd25f1fc28e196aa1aab9d2501d86e65308cf1750e89099b7b0dc3efa112568fe3f7123e9bfd5d43fc458adc2506a4ae2eca251a26ad3bca9dce3d3b28200eb27a7dc7012a9de95d53bf612c648e090fa1e030c57474b30e55496e8224457165e2f5330e5c92e7817a35a5c90298fb45245626f1ea8c00c1e124a00ece525c12302ad1a0af39171001458592403f52825a28955aa5e6ee004cdcf4e0440f500789e6b714d370d68a4b3015c084de6971e9072a6f632e45fc268facd22feccc254554304a16eb1502595770ee8e489d2c55d71365c22458b24ba718b1b953d8776971269f5c2926b0ad4822bfe4b56037cecbc321503dd19d970889c16b9d702242232ba90f8a37faba0fe883739519ebfbca019b9e9586b28373eec9e4f4096e4da2eb9b5b8dcac8b87970a6a0f6e699ffde705fad2196aed80e0bad816048e901c3102db30b9634a535c518f02149c0a35d530373bee5db1d0b6ce0c00294e8cf7868222343fb1be6c5309579236b23b84b9b7abd261385036769fb8865a5c5682c6fe16bf035a7e77b89ac619b0c748da5dece8eaa8eb60a6f8f1181d04993102477cae39891fb8cd5bf586eaf2acb1b2f470d36d5ff951ca5aee6d5d44f74268d18d185a8630fb00b4fd89779e21f99facf8d648582cd0bdb9d92bd0e846d8240614050fdbe4fc2bcc7b24b8ec99947c0e8030c4aa6078510240ad2372c54c46ff586209ea8b4ab8e16d53390614db15b1773904d08fac98b1f814cb0ff3cdd1d8bbc4378b1ca29f35408d380ce6c53bfe5070f3c01e4e668f2626e3296e95b731d81343b962f018164492f3918e1987b36c6cf46a0ae0f3f1528f28d0ccb4f003df31c39427f22b01c7f24045c92e1bde34e0534248acc0d9737c6f73f900493ef8938b0caaf35bd9494a7ef7fdac05a2b9d9b848cd2ac8c972e55791d587983628fedaeeb2d403c7cc9950a73d0e443cd3739182163d92e42ef360926e84604b5ff5c4a18cd76c4b82a06b1979f556425817c2e63687827c3157d21d9722a12c3f92e6f4dc280fd96263dc10bfb7626b6cda5739afcee376b125a466c8ab6f44076d46b871ef7c6c68b9d02d0becbc6bfb7d3a49260e324075097c88961732f4928bc0d6ed7d295ad5b3b02cd0eb64b3d9dfa1442b23c0e8a48ab4f9458b8eeecbd2569279cb96ebf03454f14d4df50d04a0d9378d2c4c87033ca54cacf0422d9e513eae14577a2ff9b8ff29ae5b48445bedc2fb2de3211d7dfda7130a5cdae715bc7ec21a7c5182b650e9d7393968bcb07bd233dc80919af51a0f540302b62fe5dc088555ebb279571810402fab0d9d5ea9486dcb2bc10e9ff43896b9aef03916d02e9c293cd912eb8d23c92ccc974bb1039446c6009a95e0a2d2f5f7e978e2740546228303e5d61410dd8132fbe4ffbdc585175dc16a03b4f88e225f7634a52536084a6d91b5b28a83f85f5f7bcf14d873ba6eb8c2e9dc6ff95784a01816016cb8a0f5b00a3c5f66291bfa8bd1a4b5c8858c73dac3cb9dd3a7dc451fe0f4163a42616bb7f68f69d57b26f62d92f1fd66b5f0016c43d4dcd0515f3b132e441109c8c0d55a3149d4081484f6b466a42745e331d9d30b61269c644092bbc5845f18f88471364d4e6e167463f18f35870e693555a05d442a3301d678c1da2469838a7836cf9abb883343227548db920af994da34c8e1ca78b63cf5cf8d64655390342be0b829bc72b3df1731679ec03fe88d307008d133ccb895222e66cc6f109c1e3492c5dc3ef459a2046e690772ce6dbe44d29ce048ebcf980e5df1913d5e65374d29df2424fa599d6db0e723a06a27edb95c6924fffaccd8bf0800096cdc991ed0426b20213033e40b47427e933a8d3667de743a0f32a45217248bb2f9446ec15807050163660945362040ae893f8d29baa108eed7a2b35365b70764d854722b200c2e03fdfe0780570851a6f9006c7950550be2f9c442aab1981f143773cfc4fbcea8593352bc37573b6ffb570283fd095bcd81481287b337346e3d76d573c62af2a067937a6eaff833ed78d3ff74b2c9ff949348d140c2ab3a27667e6e88e5904442dec120b154a80e02c69ba8e0a824c126a58ef6108da8e204eb9d6901a25e360cae0e72340bc871335b59a181c3fd79d4502253006263095ec7aa50676ad1d71091bd822be5d95ae0b28e5210b338e04bd67c2ec47adcf31007bc20aaa49c525df20f7c1f70d0ced04a0318c0fa549e3f930f9ddcc760b39397080f6965e4958a302c4489cacd095e25cc2c9f5318ec11beb077d0740fa17fba83100e9cea6c188ce0afec0d310982385bdd57a60290df47d52c4b1a401a359c412277f60f4365ffeab3b6e999e22d286b175a584c93bf93bc7ae601a85230a5ad89f846ce2c793d8c3141ea5f5f02946f7e4b28cdffee929b6b8f1f1e870200e48d078462106bf3dcb1be13ef7394ecd07c8e6188f376d39d89db7c329805dc63056097ce004162d821f1a3278692a3ea2c1e09da880f0f62daf8c5a6473bff8c4a4548879a98076f109a6e3226f5101178a4f0c4317c98f0fc17bc408b41eaf7a655966c521c99969e55b863746359342eb73cd0662d446616d77110995ecb451bd15f17915e00b142f1de06adeb50cd7643c591f12407cf31570e13fbc8180ca4df3069c61cb4b043c3e97fec4628ea5dafdd2cb418fe4879e40cfab697af1b821626b25f39cb6b8074160399784401933f2eea8bc46c63810fbc405b74ad6959b644b70d171c408926f94124010379672a9db4dc0b265d0639271418cb6529c91b12ab01c9ae054ae5e2a4d03d3b82481fe9f8e66e7e219f4c7ac5f20543b2fcb6af72ec928868dd231363d06e0405d5b12aa2733db510b46464498cc3e2260a2034a573f92f8d9d97639dc7ffd92828d7860a748aae0986665d577b1571073177368ebcb44aad12e7bbf9a1fb604dd254e4862ffb39552fdd07bf001514e75605ed659a5c7e4829e06c57f1449183129fab373e7ca442622171820eed2bf06379cc3177f12ed5fe42c4eef208d8382067c74dbe372d709250a9c0efacae6176fb2eb62ced80433253960e2518a3cde1caa9f91978aa4972c29e82a24730014689f4816cc525225f8868c724e19e350b31a5ead2381a92e446209b8895d9ae397ddb6e17d73b66e268b1d49a24bf5272dc30925f12048188dc8b32cffd0e8fc3c4819f13488c0905059e99a2e853f5df5744f3c635a9da6652109efe59df231d9b838a45ba882bd71ef8346b3281e3f795c0d08fb679d3aba634110ab97f065bf6c9f665555695594c910ce7b62b58963b4de51b6844b9a66aa24c023b82ebdc5caa479b0e0f4b1fc4ee2dc9d3f189dcec2b7f7e9b8346a0d735515db6bf155cbee03935e8ddf51258aa7771cb4a9af6da100236dbd9e5965b618c88c7573b76603bdff8bedc2a03e7d8f7098c95f05d09093aebc9da3c76e9b8698ef6b1296322d9047ce13040ddf960bac42dede694609d1094631968fdea38896a03884a59ec835dd0e228226a608a2064378623441d6834ca2585424f860a6c89b9aacfacda58f058e03a50000860cf7a60a3a48a95c5a7345d10c2cc6162d1588e56f0e0d861a449e877a6743e2578c50c061d976e5d18e397ecea535ba430365bd42e4bd2e5fb310c825962137e479288a2d23ee866eeacdaf93f9141801623e67a1c7e838c63c72590a869b9cc0c2448254680ea2d21009295b56ab1384f46ae5e9150213b94452aaea5d257b63bf9893d2fb4f0b78008882df9110d1718e1b2f1552c76688ea73908e32c14894489c2a354846a918343b8ad89bfcdb7511689a881cf16f0f14e7a3470ffc30836683567369cba27062688ce4d224b8f6749c7daf6be9bdeeb71c5a2bb16e58a60de9090f80cb34359c509bbd9bcbf9bdffb322a9ffe1f69b438c42605bb0fc04b2a2eb8002e6b74f05b11d38d3905bea4748f35f3e3d7d7ecdc42b44f2ba6fbf35bd5237f7b4c725a3ae0fd32840f411086e81b4f3d5a19524010ca74040ac4a2d2f2a8da413d245fe7fa8eca027734405e1fcb8af86e545bae99bfad45eef2eeed286cd79b4cb6e302513008211cb8d7ef89c219ca30558b3b8bc8e766dc377607779778e3055992e73d4655edae8685dc2ae58c746eae198d4e50bb0050145cf1af104dc4fe2155971ce84bacf27c07b31ea0ffe04e49e5549755c866b7ccba62267dbb3ff5631ef94470fcf39e081fc8c62b1d5840c04dc2360dadd39983d37f10cba73fc60a463383522ec3d1567c54ca3614e1bc4eb8d88375c8865c0fa9712f9ec62dfecb8f85eeceaacb7e6e5a81c93c32d01dd7214c1c0b74879bf3220b8f82b4e444025aa5357038acac67ac87f211c9aeb2e1ca7a27fe6479b6723d1939d95c171b694a6f8a66fdcf1e570774d938ae1ce2391924435152bb31bc88900534c8e5833c1d90528276e07ee705f7aaaf232fca8a8170a4f4c2e8ba5c52758b6e0d760b46c7f5f83e9b2dd7d0db665f859216c10e4c3dc00a392f7af14e35fd11f8eb1576db22eceb1d43105ac5787ee253c771f0bd230fa8a9cbf17f03eeb565318815e8053efe905a55fea9b8ba099ab8ed6b19750f25e17e759ad7056dffa661f8ba3c9c8c1ca394abba0c85c027e4b1f368e65a451e79121f3406762bf2463bd818987f9dcb0d409ba68a41efd31d2724a2567f6eb43fd347093cb0f7b8e31613ee03470908e9984894ac246120433454f0247faaa46b632c8ccb3aacdc47fbc927ef45ba978c32c2f65f551ffbc3c66304265e7252c3553265daf4cb3b157f926056b9ebba8ff5e35617d7fc37c7db2a4ee2c346f5277f20a6c7e29eb5f7879fc58396e40ed251b0c00573b67dfe1ac85457ea50fccb13d9296cbb121040891470d8c07307c1d454f1ef05f61aa9c79c05726ddf640f3145874f9a034314f603c6f80e7bbff935566df28d7eaa2dd2004e9cf0537f58da6c812aa485215cd7b9e6c2031dc9ac85f0104accb13ab2b0e3dc3c7d3f0d3ee5433ef813f07ad5b4ab24f721e56f8eb4e79f81936339d2d7469e58c8c4495dfad3ac0be05fe86e3e540d8c4485fe98894b843ef9d2dcac209542123136fb03a911dc6295e70039041b80d36a75688d85fa43f4881c1abdaff81211e1529dd2baedd24f8b4f1bbd96f9cd5fd24b54715bd9cca9d35d2e9ed0a7cb7b4ac4348e6670a49a13a10046c396cc901d6192b7a8a2ec7dddabc05503eaf70626c252f0e4d291714fb3eccc6b398a8e62d747652ed64446608c40a499e603b19d18a7e42c2aac1186d4ed42cd8535aa552626562d21f00bb019765f9ad5f3fdca28932c37e3b5a376696cb1f75a7678c64f34f25d7969e46615d8887216189859e79c1cdf8caf23c07e1da3abd5006e33b97adb5f147ca12b1bc77ed125520528dccc99698ae97a917c6aed8166ad4d8167856341eddfab1ce0507e63ab684d02721fce1f249508d5c9071710adefa5cd537988cc3052980e0a35eddf4b854077dd2c20131bf781991b4106e7365dace75d1cdc6b4478ea57d7b8ca55cbe6911740fbc902e876b8e6fdcf4f0b6281b2f4a0868e97d24332df7af3face89cb2422dc980f9441253c09bbe8dc70a66be36380b6ee291e3b63e23cd7826a26577bb52ee03e7c521b6256d7ed56f2dd87daf20133ca73ec09496f4ababc49210d6b0664f8cdfac4724a31ebc527c1c0d52d0e2b344a291781babf76f2e3772d9669afe0c0ff54e01a8d82db669c484b965902d576ff8f7fcf92e8129058f1c0ace677468af9d7088c62378824a30f5d3e2c89f5960572a5a7071b9225776841d252fcd4e6dd62b3c229e97040e0b1498fc34bb8833e766e5a0828d9d528f3beb161d8d577416e5f138f8a67a91d4a6e2e0b1c33807c5d4e9f7aa2ad1cbb24a6ad73fc98d2707768efd1a83713ec082c252ed58602a3a9476a731c9438160fb9f357f41d8c0caa9274a7c8a3fc36d6ab3640bb391bed568f99ee22bf1f564e1efded80f0262020bbb8d557a4d7cba7204888a89a448e978c229e7eddce182a918300bc5aa7190a0ebc0b179374083fc98e292940af4a9c1da6b5a23daaa5e4d407727bcb83eaa6840503c948b4a45a2888176236a2566642e1c0848c6e6d17fb5f571988e3ac5e6409e191a5e728489323dc27b7b7b1b49734852b935a3fc7df99e05f31e91f25f1b2b2fc28bb44742dd213d7e6ad15d781340364f27cc63fea2feb1d72a02328f2ace54febcc22e4b1848404d9ba0139c542702247411e400246ff117d74de2b18b0c1b3e160cfd7bbf28717b5693a91d9854a0a218bce995bcfa20e94abef2d2683ff6fd0ee714122ec896f00d907d3773795ceac77c36773509a37a74d1fd992957a906d73c1e3f433646de00fda9b9bbfbd5fc6d3e6022909ef0624cba181107fc31fca869c713c33e717ac2ddc741339f21c07295422e50f9f10d2e0d28a021df6246df066d446b7404b82959e4cec525cc4e5cd95a0f4448ca5d5f5d810700f8b700b3c10aae17046ca9cde0152fba7ba8855fd0139706e784e0c8c48f8ce88d6c05d8c06bb303efc9424edba69170dc5f085f59d24385b2492a003c036f8ad5b9d173293094fd1e71f0757428aee4dee07a74dfade8e40500cf0ff786a326259be7b371af12ab4311e8488797cd01e5f7b4c6818b4d6d1a871bb714c5b0dd925e6e4ffaf0cab497a596c75cc8ac01f5b3835ac4f6806734bb5b1b24d9985cf02bc0bab0d6603cff308f53e0c5806871a3869002a540a84016d711c93554fc5d8e569e69f3eca6b98e97c56a29b120ea131f4559bcc977ae1716b414f852e5ae43c214d2f084a5ab238a22c4dce1b2b41228d4b569d74b327fc9ce90d94d7038ea1aea4c8fd775257ccd984a5bb51c1c3c79d383ddf244e9060dfd85782f6594b10533d939f1ff4c829301f5a15d11ec955569415b421e3eda63026a70efcaae743ef9579a916b57800f62af5f48ffe397dc8d97dee1e406f7d8217b60381ee1f610f858547a209da33b2b5c3832fc5410a4e0c34cc1a7b413c191dc1c8fe1d7cb5f51bb66ff6db62b2be2cdc7ac165148353556dcba71904ea780232632932e020c33852d7be0db8f0372b04d73bbb93f35caa3dfb5e8982c56b3101ec3ffe1129832e91dc27af7d3e3c8d7bb12c537d81de5baa7aee8a55ad815fbf84e634d94d807f3e9501d08038b83c93422975c2387bbaa2c0d89fc81730fe41c7963f61d0c9dd36b47cf418bd2163d76b7460b15f607bac925f290eb29eea2edb11af0774a998655a4768c6a3ce3aa703e52038e6e23d4e924513d90840c9873849ed1484b1fc84a716d6c9ec08631009ef51e523902f9523f0a98377635299eadf8925a7fe7bea15ff6f1b5e02538ab60388ff1cab86d52f00b2ea3c7a19e18f35c14f320c0eb11f5a968755ec52b825cd0d0d987ff664022e82f68a6124ee601105d7a434bafbb5d88628d59e7b9e9948515ad307362564566bba74cefa66c907f3d0089dbc53adb72078ba2725ce2dc74d0a550dd6123b611bff7e2924793c35594c2e971bd4a13adbfce70bf3757e122b5cba99ee42930c2bb47e387f6a6da1a699f51ab4104100e3cc756748db49e72684d3652e36ef9e8714ebadb53bd825cd34cf4e0e44691437874a5afbe5c02b0cc78ce623a81e9bdf45c6a23f9cfa401ba7ae502ab4114258f420ba35fdc939fc10c2d357000ae777ffd91516a62a4e5928ccf19d6928ea149d35e0ff7094104333903d2e27a10f22520f0a0876c72d34eaecc101170facd16066e74e71018e82ce49e0a1291de8fb5397b5c3b35bd0f15675ab765013ef2d0aa1eb0abf69ca20d70158b48cffe9610a122441abd00ea5fca41a1a3e4d9aa49a90001f3c2c92fc63a0180462142642897b41132bd92b7c22878d8840f7aad028a818e6416ec2de7e50cbd7cdd094dee6da68f6acae7b21b9424452784cef86ff2b03d24f293af9fb164e86ac02756c4d50b6762b6732099aa8f5253cdd6759d79d3af09d0abf82a6573a8f0dca6692ca294c88911ed1ed053a1799d7ff047d8973faca9d87db452396b697712093b18e684732d9ff927ad92115060700e11ed098c37244a5e3ffc0b35e77de9e4f951cbfa6b7d1ded5e1ce65e704e4e05cd4c945e858254c7451c7b89cb6ccd32f75e2019527483a25146ac1a4f0e55800f8e08527974f9f52624c0b6f2d03f86e29c107a405760e8ebc17305d62cb2a8dd00f4df33ac8412dda055ac8040e570ce3b88bf66b174008db1e7f3b8ff1c210e0417ebdbb76338a6203e316da53ac0b2a6de80403203c27e4beedb640d85f3639636ab126e7ec393f54c174e8eb9fcacd92ee36bb3aedf34bf7e8ab2dfe76dc5ce630fd786e344d6541a1c642e59943a389035a9a6341d5f0a7e5289592c6cb96243b32bac6910371ffe8585f3c1243353d2327f89c8faa542eeb72f468d8b435b0d175198100f7bcbef34d27e1381d1fdeb7f9f4129e366bad1566a08ce35429f78ca9cad6465f7ebd43f2e051ce22fb8ba6619e45892796b5118b1affcb797227ed709c09c802b5707f2350e50d7c7033c9b4116e1a4637984a20fd4f2473311ccd2c9d807e82f91ae0129ac68e6398176ac441f6f7bd9cb99206120954e81e9e2117066017efb3c41f0c5016a770f4e85cc5a5f118bd8bf19e9ccfd981e102ba107c4851f892256e30201f3808ae8b81ee4eaf75c9de54d6fcedd2b14cab2168f7d754026db2ea97c45c9dcb651bf0360731231ffc6e9b62dac28dbfd9cfe107832f47e0693c47a82847e8f9c1d44adcf931e4d8370da10e586755f4504e6dcd7ab4cc86212b82acb94698acc6530faf6c7523d8d5e3a8b45f6e4b823b83116a09f33d12fbaf30d66f980267c3e6039d207c057d36d6d7d80dd5bfd5337e104374bda16d06ac78197652c8847e0a3b800922a25bc5e6708c43e2ca0528104f95d8512586210406a6b5c8273a53a14eeb4339b980ca48142a2ef97d6d2ac725f7112d6454c01539776d6a92fec8f5a87571f364ed7630c096cf2dfb3c92ffcbafea4e78b479e26297a5d7d4154dd4c20b4ce9977927c0d4f87b0fe735ce8335486d683b9eab9bdfee266b11421d1d8be64360fef9f59db4fed2acd7cc204a97472618335fd3556f995a948ff315b93fa26f8c6b6bb177b669acc882402e0073eb50d2029f83b22c074d6dbe6cc9209c860128d3b28025e0a56b691dd56625b7ac4270fc8e5c4f97b635c41c7ef4c9ea392aea5acdccc8faf3ec4779bbe00ba127efcf06893a829aa6400f4087a80546ef82263e5189b17fb5fcc035931e1cf1a2c3337d48f1a6dfacfdb0ef2c56555dc05888006657e047b839c5dee012f95b0058d2cf89287af20c06e56fb81a8383b2ff0712a64570038dad122b031febfead999235e6cc55f327201c27d19fa6b21d2796f3df47e08613f0d2318c549e7f9950dcd2c77c7720807c90376ecad53a179805523cba807020c80e86c740f2ad492b5d70cea33de21b4a2956b3e7c6e2638f974da84a41f09e59ce81fe8e985e807bde408d4f147b80b0dbab83426334b3f65158cd6fc2e0a4923d71e16f86e6c413f24debd14380b7729f81d3849ab4bc39b5b2f0dcf588ca62a302250b72eb8b56d89c3af52882a3d46a73cd61a2cf5c1f6e735cfd76e417e4a1e54957665260ed6558e290bb9dd96dab71ee1d74fd10c0740c47d67b8a83672e437fd88d47d33b00d4b094cb4162baeb52b0d193b65db0c1ade84f33d69bf53e1d8c69779c20eaf70c4991a9dcfc1b58dae396a74dc4f5e5179cf66d1e6de2728a6cda96f66ef8d8358f9890388d35da28fc3398e5ef81c8edcb7f152cacdd543017de061a22329c6c4d28a03f10b06eb6ccef50f14ca99d1b7af13adc281309da159f0828cd65f1c26f85ed3b1aedb2e0e94f9f3b2f02e191099909f272cf96f22ec0673932da34893baa7b374c1ae07b749e3af7b5dc7b8d9d59809cc7f85ee329205927350445010a093803153a640f34d9035df185997b4ffc302848df370e0962905dad44cb0401f9b370e865956424856a22b803cd08c30be7f189e577be836f93d32fa1e645214c5f7168d03a35bb7475b7cf7a35a7e4831917f645a54fb6d64a18f7e7d8c60a21cd2697a44061a1422ceb93a47af8461dfaffc17039eee1320831236fec5d03502cc4b750a858eb73c36e398e7889f8e39076d322e643c6a157aeccdb2dd661c8af331f7e78e350bdc1532090d2a73684ed6c4cd37f9387f29704285b33448fb3157b881b9760732afcd49c9ccd90a610b76b575804b18ce2eb51719cd91149039cf526bfcf9b69440b4c75c0b2be4180ec0b06d6543dedd3d07d01862bf0c91c2d1572038e775bf9ef033dd716c92f3a1c3276ad83430eccb6b7fab475586b9f6a1f48a0cdb94213dbe3bea78471138bb37b0b8235deb381cf88e7308b2f009f188c56f8247dac08ef6cb0b5028050578bc247c7352f197fc2c44c24ff0183936c640bcd974689bf9949744ffea2378231e24424cf0a027343744ba038ac4568f5c308eba9a0e2232c23b86c880f7391d7c8f3d3af0384c8026d16d9da0d788f5646e5c7a86c4e88e4606aee64f4462438f0df98973f9970a8200f4644ecb30a8394332460cf87f4a49f3c7bd56bd33b7de40216def6e5bee2d654a4906a908c508ce0837bcabf06c6cb1534a29a56fdb94726ea22b59fecea981fb6db3d339aa86eadbfbcf18ec14b923efafe715db3f3d040fc756dd5a48ea637099d239a7279d765d95361dc5a5ecff757dca75a3dbf65d61628b135338d297fe267e302f15c7cbb7c7f09eeeeef5bd39dbc5e29ce204216a72db3b1492673f4f6e6652fab56bce29da76cd14775c99794e969d544ed189f07e2e957f020a3a7744a244e77a0618f80657f2ce92edbab7ecd8aa4ce9e63e2512ee33b8a3ff24727760f7dbe07eef31584a65f5db9a51b954f77912e8dbdedba4ce8824d5d912364ae77b18ffe1a5cd386b21d7be7b7e9221d7da255d74c818c23552b323bbad2c2e44e1d66ebb19b33d87eaee75d7dadddd6d74ba2f41e7e6aeaab33dd766d13927e7923e9d3e99cef9336b4e27d7f36b7b7b8d07dfc1f754356bbfc122f63dae95f9004b2b2e94513d1736b92ca352fd8fdb70158edf05553335c07eae76ed6e98371f4facfbcc0d15a7d8bfeaed096fbe4769a55e2a888a3f0c2fa3c2350e7384ac94cdfceae77338dedcd57b33e1fb6b54b203be0445e8def3f8b335c2068bd4f8122ecf910fb02463c3edd7b0890dd171e01cfb9dfd1faf21138edf5dfdf48c91ef5722bf2a04c39951c9cdf5c407dcdc94486bd7f5bbc507dc5c164fa85f451b57bba68f1c2c3f0d0b36b22addc4d936333a1b186f7b6933ce39a7fb943269fe6d255eb5ac77e9dc71070c3d15865044bafa7d944a2e9ba76abe8cb1e8e2a864e66e4d81f0e48712a87b4e17bfd0481156fed8440d93e2eccd00ad02b0cc7b17f2d78b0dd089ad02b0ac7e57dbe50175511bb990bff8b7d06941d265556c02ec60470673e9cbe901195a40c195e15094274de43ff693cb2fa55ddc45621331987efec2510d1bdd87cbcfef2cbfe6499b2a8b0091fab1524a29a5df852930b9f4e973948a305321ab8b54fae3e7d1671596d4bb84c5ddda1b288248a5ab9340831f5011e6ed9c4a1cffad46a06fe7b713e7482d052ef5a70d2c60c12b9b94b23843362979f1b24834eecce25d91098290637623d7b06fbb8b3daab0ccb9b8a3c9f273219d12670c4bf270e2d8e4b2240ea78cc833eec6b2613b90ec46a7ab28d8638a233a5298b3590e7709f77c7f7a0341d07137a7a1148105252b58b0aaa5ce8ca48d07eb1db15911c10e965ed9a464d48452110d02bbd0216503d4e7944377c39197a4440e1587a1549208681ccda8ab3a5484b66aeb6769616ad20570a0477210e2926aa0611e6d494116701b6af48a0d7de406a779c5cb0d383c55196a3d624351b522e0e10b1967a4b2d8e9041786e5aecc4006186e0732b8a89d01850c8fe6e09f3f2ece10d16635b7d56a353363633337ca45d95143ce6a59ac3969f775f205b084a53445e9dc381a3a6e9b20d75bbd2e65c9a920307d86c6e6dbdae774f76ea63636746e939b93dbe874e9eebe35edd9ed8100badd5d4a29e58b2c56adce524a297b56f7217d235ff2bdbfebb21b47159eb461ae398e9ba1b1b93fe7c651ee3b191d3857fe903129ebca6be71c9d9ee23c9e0c82a46a883dbd56f9e37df27d865c9aefe7ffb79f9fa7d339ca3598606e766f8a74d26905e56a974a75ee74e38ddbeab6554e07bbbb4fea73dbe69cee3474ef7142e10e9b73faf4d0d52ef91531b6dabda374ce39e79cdbb66d5daabdef033f4ff1078220087ea96e73e9ec7c27a3836bae14afbb17711bdcb6551b3666b649e7067ae19e9df781aacf53e2eb9af0ba262a5d5921dad09ceeeeec72cd66b319078245582c2a5383b6e0ee2fa3442763c3b78e725dddbcebbaae6eef9b10e5991236b815073c69c375aa956be887e8fcecec20f940203c48591921dad09cb31b976b46e98ccee86ca6646a380d8b95aa36b3617ce5fa0b96ab61d3fd8e1a57a66ef7cc256c2578ad943ecf9cc50a6fa5617d4e9c1cc4b36d86e396402e94a0ecb8ec57824166363571c4f59feef38be5973303527039b32e62680004549096788d1123a88a1aac1081105dd40053450358b6e8a20308b6680225043c24357de0043d8ce1aaf3838a5e9fefeeeeeeee93b57829d2ee56a2b0e288bbeeee6ef979d24c2676b8ed04940d80f39bf5abc144d0ed30a6c0a951769c2fe5bad7ef934c5ce1001721cc888285a02ba49c6143130c180043e6965a4134c6dd698a7c8e09ec4843d331962d31bb36b7e7a793f2827663072a6837760803fc6e181d8581c40d377ce9061554f42001030e3886b4e08063c88b2e3870181d79c12345171c38b468e1916286c40d2aa8e841c28c11c7d559855ab4f04831c6931cd8fad374884f611dafe2456ed4aea24b9f7eadd6b2c6d71981e9c35867c8062b0035ac3e0bb4b022004c9da056832db66edb2613da15ad3f3333f3753f7ef6fbca81f5d7608ba5330df3a7b55299d086a23836f99a00a9ffdec3e7fbed0af92ea1cff27e5a86f47af30321c0f77b0f4195e781d7f3aabfbc297c217772663be26f33efd7306e88c4a14f5f46c636902ffa34342038ea5cfa5daab3512b5e45e7367daf796668d1a2a58b962e5bb66c51628b12f43dcabddf71de259084f91c061ce155c38792a79db82a347d15fa8e0f4694c4614f9259b2aec4a2234539d2a59313bf76d1bbe9b08503176ab03a2c6dd912022a6ee8c0430e545041dff37290389487fa45ff0699435f7e5f39715cfafc84871ac64569588de5944429a59d139183983c5c21e4d9c8b407a52fa15fb398ddb16631bb5f274940c7ec4c49c338142a072410412a7210df5438d385d6b288681322c0f841698b1b84c0b201197da6d1e721a6491cfab028b6c1e924880476645ad0a543e48b7ead960eb9949b4322d3865cfa33e4271618e29e4e9e537419ac772e7084ff4bdf864cf317fd55c843fe5a6ceacadf44a6b58b3ead6172d23e232f78a4e882c3090ed0feeabf281794b02b150de0c7c1ade228d1b8f48b47bfe52ff3dfab5e7e45d2f2aff132bffaefed83b030acbf44622a6917454134a15df47b6eb05efd45594a24cf7cbe41c676ae10519a7a89437f87ea5cb974254a7fed5c4ae70c76dc9197be924741058628f88bfeacc1cea70e7825758c1bd704c973c3f20b97beb4a15ccf32b6c8384d9f671d935550d9b404e6f64e95db3d65dc46e5179d9bdb5adcd18bba325eec5f27d508a8381162860509205a2c1a16a54fc5b779c2f6f34c6c81c0ef3598b0fcaa213c6933a662445ebe37fffabbe879bf231c9b7cd077c76fdb8fa7dffa607bca811176e47a34ccc7f3f81ecf60111f3cc4b1c9e5f11eba7b8fff69f77f09fe08411a203f6bc213685e5e4fce1f1f8e7c1f48d8b7455996a7c8bc045bbcc5ca262b4f97c70379cf3f20334082c63a5aaec253244eff8f260b0448686b449e022494796fd690ac489cfe59e35d355ec8abc607f1defbd1646bc069a526fc6ccc2b5a1ff098f3fc4d2e510e5f2ecaf9ce11b9a8269444dc4cf2d8dcbefd5c1137a56140be9f33923c35dfac0f22b2fe258eacebb15e8838daebb1de250a71fdb8ba2ad67b2f65ccc3f8ab5ff50d1a59d5fceb25aa30c2cefbbc3e007f9fc8f77cec83bc4f10518511789ec81391d7a7276cbd44203a780ebee73d8c1071ac2e0f13fe7c4dd83589d3cfcd6e7cdff871756ffc587bc29fef20ecf91bf651a8ba123440cb3a109ba8a7ff27ec79831de714b29c10e7a46142be9f9b499e20dfcfb1207932f87eae05ee817d3f1724795c3fb9299cd35f79be839d0e44a000889c90bf3a96c4e77bbe4704e240e47cc4564dcb0867f04cdb7224631baecc644d6431cacd6a4279bd20a1df202f21213fb95a8260bb5ce106ff0a87bc905083af09f94e9ac7b8d99cc23d4dc439dca4719376e794dbef65000b390be7f46f100ee9d720e4a7902fd744fd926b22d5e755afab41ea465dc54ed3a9abb849e2f46710ca1b24642689d31f0b5b35ef53e3f33d4fa4e6a58cc5489c165b35ef607a83de416454237a54bbb2581c359c90c8cd946c8e2f82c1ff348b913c4274fce803e747d6cd8ff6e600c08ff5e6c8b17a7d07f9aef9e640f2b8fe821fbb87a3704ebfcc7bdcf7231cf9fe78eff5122c12c445c2cefbbc0447e0f99e97601222df2302b5721e88c68aace7a58cc84b3049ec7d44a0160642c4043c900e0a96a0c97c3ee6e5847c7dc28e628a24594f4845e73dfe7442219f13caeb1302f18c8ca39a8c498783ac47a422e43d21e1cbf5210741b5abe33105c8d77c1df371c49175238e1600628fac202f0ec2d9aff9ae90a3700f2873e6051ca55e1a71e44bf37e6bfea7e7d77017c8f7780645e0f14044091a11c3136a9eef8fff08df26a4099b5c311c97f8f50f3f16b6e6f77cec8984ad29aad0c10d5e9021038a3d931b3e509151f1f77922af03023b72b3f0b959c3c66e4c18b2c25f5ac25d1edfe37b7cff4d28af8fb0e541edea967fd852dad5cf236cb9d844b78bccb09c90c8f5bc60b71fb9d9083ceff30c8eb0f33dcf601222ef23026d5da0c8883c834962df2302c92b4734d464b1fff15628ef8eb0c9d5118e3e2e2b1c25971ce1c8688c8dc4ed9f0989888c401b128dac3b32d1c81131cedc711a8de01da79196db1c378b8544420f0a596b3ebf4f6e76fb9b0128b8401a342e2c40a30c59d7acc04b09664e6060428bac9f9bf573421e14321ed14a99c71f910370a09443946c47acb150cafc0b9b9a794d36e81f18903c5d6ef3b9f724bf8b1d9dcfb56ecf89b4677b77579e35af746eee9bdf34e7db9c9b733ba2be78e1c26474544b1a8aea7298b04b8b5076a6cc6d74dee61c7ebfb3a12e3794127be1c2a454546474d4dda88d8c9aebad46be9ce3e30597c51b51dce8744a69374bc09b37a658ee99d38667d666ceb739e99c9b3bd7f5438933e774e741847577ef6aaa86146e9fb4fb8d7bf93adcc32f3f03eea9ae9b99e29cca39fd3760e09a7b26ce12ce0304fd1bc7f1008165ae6eb5a35dea9b7121ce6917e21e793be5b997fa5cc8693ee44429307c970bbd0b813bcad8e1b4d9ed77211e430879a92ea5722189d32f24247964540d1378fc1e5dd55c6fd5d75bb517d75b85d7ab0c60ee6eb3c3aea9e1bc602dbc2aa573bdf9f4c93993d239e7f4cd9b07119699bb8f86196ba7c8d16dabf629cd0cf3bbe5e956ba3333f320b2feec751e0df57672ce5ac5e6e6e8b66d949b3da1cca134335f8d02aec7ea079de855e49c7e33e990f030aadbb66d7476b30e09328eeea803855579600bc2761ae8b6d8ed023a58ee0948c392131b6ceacaa6a516be0d3cd182282f9a9e782ac25acf091862a846292c622cc01d493aeab078b12dc17464092ed562b9c2093da214c53999451b962c33389630144b520d5d6dfd6c135cfa256f6dc24bbfe41dabc58202189858c25284109621bb450b68e430023482bc235bc55431c6486dc06e5f98400c549415aa2936752593182625c42c31a5d1810ef497cb44aa6f4686256a00a618a267664468618a1f4ca0d4250b0764a3bd0500a38b101c31845017626695a1311b4e6d366be1cbfc6666434998f4e2850b17262625a5ebdf4832d65cba8964ac8b8a8c8c8eba764716ed8e4cbbe201942cd3ee970b75e51d594ed020d22f5877d2b40ec9437ffe0eeee19fef01f7f4cf1f00f7f8cff7f92e4bf2d43ba7ac9101fb3c5058f923cb695b743cd3ddf5afc13dfd343637d72b95b029d6eeb2682bf0a84f9fa292652597285c5e725932959fe5eadd264dbbaaf8817d0cd92295134833303e275fff402b6308249a4e80c4ec4b066a1e1882a988128ce08a0f4770de17587af87a5cd9a424e6a6ae6c520ae38eac252e327cc27ecdf31b9b78874ed8afb9a5abe63bb5c1e0009a14719beba212d79553b4699fc19bd629f723a59472fe537ee3fc5cac4daed7b0b5a8346b1597cceba27d1484207178b258b56ecf6ddbc6fdcc6cd44ece56a9445211df7c979d7177eb2fa71f1479430adbdc12f4c93dc39cdd73dd7f73ccdede5de67c8953e79c2c56adf367e857b9992a7e96d2e7c45189ebfa532495ebbade7a5358e1da76f5edc219dafa400589e54e5189ebbae824a60234efa6edfabe4fe8221d50d251d35a3a5598574947ddee1f8127254f739167efb65ff36cdc55e2f06f3c8d565e535f53294fa5dee54ca552a9944b97534e3965737a0ba8ac3935d871da509aafe31bdc25db9d0c869de30d28acfff8513a7ba37736db1a58939fb94e163373c7bc566b256b05efe35f76a67fbf94b3ba49454ae9df7627e39c136a7b2af9ced0b64b7e3353a4ee330db39706bf7d98d607f4bd7b098ec07a1d22500592921092e9d01102dd5822624a910c884737360193b09e4a0b04faddd3ef3ccfc3eeb950f5ad904af760d84e3ff0f713542a908411763c4d12d6b75e8207d8f134df0a81747ceb556104d843fa5c4875f0105b4f03c46406216b8954e8c3406554e6b342d6fb8bbd0c3bb2ba5abb62a959bfc4346c13534241ede257fd06be9d516dcfa952600fc94bf244af7695b0450d1bbd5ac7e5f28fdd1397e2b6e72e97e236d506aaf8825fc39b76b18be3cdf54ecc89c172af1295dc5cd0e3ba4e1c553f2ab9b99bf79b38761776ddff34d0ed3ab00b479d7bd3dd5c501c93dc4e3c41f5e08f492ef83757f560add6b258a999e7c860dbdd47d573e30c475054727339d1ab794846d819cdab7949ede2df918383f56a0d93e9988ef7c2793dd5cba854cfa9649ebb31f33fadbaf1123422f3363ad6d71f753c9653fa4f3895d8f2405ed51f915da70ac19477eab71c0f86e377abe3f89f6655d1653e4738ce8b43ec74844154ec8d1be2036eee8c7882ccdb7899eeb94d877b954ae53e87a2b48b7de060fd655ee6c7499379fb32cf3fa334ccb99701f3e54b54c3c6ee88e704769cb4b1e3d2b0b15b5af2586a969a2d5de60e9e6cf734afd57fbc0382f5d3a9594aa8436a5852c3a8d291c7586237a55ffc6277e421b58b5f26f494426fc9636a17b8badb46c19075db5d1c95ecdcee5bf5eeeedea5c0e4d6f7b09bd219855d9576a95a2a55f793d6b1580d268dac0c5deec0205dfe66d1ac328f2ed72ecfa4cbafeabc03d3b031350bd3b01415a999c73c24af26b412bd5abbf885a461c7d4acfbd1ab5dfed4cc53421e933214bc3b69a9a1144d060122386a97bc68d8b19b72f9c70e4cc3402f1d94aa53fd686fa702e704411f0386dc4de98c1af689a9e7efaa34ac7e082a2c5925d185a917640e7f0d5342a92089c3bf852927618a967a12c34dcddac52f83fd3ba666b368d2e6d037cbd1f7074fdadcebc56668ae213f595a58baf2a5bcb97247de513a5dd9230d0d4b67e75d520e714b9a2b9b9aa0e8c7cc4c37a71c3577f78d336a5dd9d4f484524ab9da143413c5711c57bb26a6a71d4a50ca0de0bef0a44ddde6b77a5cf97d3b503fc9401150b2efbdca24a5021f64df53a13f02984014a3198e907202207690f19be03109f8501483079a3882882064fc4848b820b07f4360471f1f010ce1c1cabbe3bd307d76c2fc68e1336ff747e6ed76787b6fce190eb934944d52ccee9c5c47bbb1eff60e7eb085f7e8fbf96143d8ed6147b67bef3d2f7586df1f7d46966c3aa376b97b7e1b2f8c0b23b25e48bf4b3dab0b8f74b1f3e5f5427065139393cbcccfac0773f96d7c927cccbf31b885b39bac10a0ee266661b9b04f0210a25b99dcede79c738670670a9c0213276eb8b472499d0a6617dc296b5f52703ff0aab85374d97cbbf897f8181b4142c7a42c6af584db881276f4a4219e2479941aa6c348248fcced2741f2d0edf9d26f19d92e3f7fdffe0598a0a44b3061863a3712279479a204133c975466dd7e65530b68dd3d63c9431a364a251f01346cf4244fe24bd3ae9d124c4042c2db94600212125a20f8e53fe2976f240ff72d5d39a1ee84923cfde36d5ebe37e7e49e25339c2614473472475772dc13aa61631b45356ce42b378c51c35af59b5f241877fcee38c554d9ffe3138ae7054bc45969981458b35352bba4919a1ddbe87621054c4df6e39bc87e3af94bfef56612472455e0b7d1f7aba586d12394670750b6fbef2754f538a2762959175b48ec8162fb5b4ac35a943f1e8ef3e9cab7e138975498abd0689c45577e0d55982233f1921196655bcb02c51f7b4a7314ef8c27518a3c1759a640890523198d0c329b6f22c3200818179dd9e3a3c78ff6f2f89145e467b136c3494b479264a9afff91bece0cabcd304752aefc9163baf2e5c84db9f225734857d2f7975d95d2531ad622a15df265c33c2da4d3150c80b02568615bfd3ddf44d66ab175009e27f24976be4704a2d2bff32d26e179224f4404e2f92632180e96c8f7bc914b9e22c9e31e6b2a69dcd2e5642c8e2ca7dddedddddd3e8d60b19f4a4a29a596da25534c3fc256921f404c180930b09051f9bfe07f7c13994dd84a62f3ae77894040dee69bc88e3cb17cb9b674fcf8ac1f5d395cefff7a1c1fe46f7c0c003ff3f239988d97cf71e918cecbe7bc34acc60b79f95c54c3645e3e07a663392f9f1353671ed379f955a861ab975f9d740c83975f9f346cc86319bcfc4a24a5631abcfc3aa51a796cc8cbaf47d54ac73678f915a926790cf6f2eb52c3983aac11c39a9a9066c64c0449a9d1c4cc09d788a164c2052b778e7165188621cfc2fff043717cb1f5818f386e7c933bf34dae8d6f726bcc7a428e27e488843ba19cb9f4218eb587385a1ea2eca711c7da1247bb431c593ac4f159e2e8ba2327790e71d4b938c229a65d37422a3413d22736424a14d229ed922f13d2a39022b54bfe2aa44bed92af0a299776c90743fa85144cb8cd52e1d685dbd026a55df263e116a55ff261e146f397fc0dc22da85ff28784348c0621fdd22ff91984f429a44cfd92af13d2247fc9cf09a9957ec9171252237fc9c709a9947ec9bf09e990bfe40320a44efa253f484867fe92ff0a27987ec9778513ca5fd2bfc531356c4c0d5dc911754c03a3d96cc6c21432be5cf95c15eea86341e0521943573e57e390e473490d536a986c2283e9cae7961ae6d43197c9efaaa786e4cbe7242127a928f253440d93223f55d4b07ef9a9290deba4b090fcb18ddaa85df2bf083b368972a57c8ec87fdc86131ab9a12b9f39a2f18210a8c6125638a9c998e0286241f6e38184402011322018a88c0a931984ec8748a5c5e2849a5fb6a7916b779c50a13746544d26e385afb464947a89c42955da269432aead92605a54bbe47738a1c2f9050ad195f23923e78e9c23fa96aeac61c26a62d341a6c870673a2b4598b9fdcb220398af5ed9c454e5ceb46b1382e9037746a6e17545789164440cdbefd7632f4f51ccec8c6d89c58b2828590dbf2b649e11312c78c4d99d3ecf1a8ada17a762c69d6e98a7851977fc66b4a199d08ec748e857bfdce961048c15c3f2f33512860545d08000fc19dc910077fb0f34204095dc7205506842b21ab678906de109ac2303f2d6e7a6c0c00e1ea8608a1a6ca0651983070fba2c65a1e20250596a3d7880c5d11849ac309ef0c18c2a76bbb2c907318af0210b38021f8c5881c087293757328da97df4fa9d9313ad87f4a6c0deaa256b8de4a991382c79b6cdbbdc12879d29933bc52a71b8c3beab7f974b4787b5d2d161d513de0b125bb7bad5ad6e75ab2bae229fdb64ac44ba1c4312575499728dfae9afc02274c9b61a33668c51511422292a1f1921a40d488942e3273c042ad9e121a60509b1936f880d27275410b482189e793a3c5b41491498d44d8e0d8011028c9212bc40754a5c50252471e2526d688ec0c0824b120f38ea818f44da686c96c0410a0fb954092b4893079a746c5c3753c90c8be6e976edec80376edbace5b8fa9bbcd62ff71604418e193366ccbc324f9eb4a92e965b967d16656666e62a8bc14a99834590d0f7ea1786c3b87f52d2d29293d353fb1121ebb55d8c81d6f34feb5afdceacf56de5664f44439bd3b674c17cb172fbb72a5b9018a886d13c6d4a4960906eb7b6a2dbdb93dbbfd1ba6c4e6e7f7fe9d8f78bdf876efb922709cdd9ac8db48842d127aa74fb29929327262f53681417305050a61d4fa58049e2d227b3f925c9c6341a2365d2c220dd197f6a988d7727a4309cdc2e92eee4f6bb1015b7a17c00a198e0220537ba6041d5415d38adda8976d2c30ca802e385dbcd546598b19d6ed33c0d588466dadbfa1658a435a463489ac78f3e37017249a746d3fa1d60119a9638d27cabd56ad1d0d0d0847c5bb2f24b09dbf13ac0223ba6b5d662b9568c2ed7da677d716d9318385cfb2cb0887da8309a2c8e30a2dcb022182bb061e365c022366c0aae0c184faadf1abf028bd440e2f65753ac9e58ad7edcd5ea0b29ee2aca03771565c61742e8d8a49a5dc98876258ef657dfa3c7af7af8f0f1d6c7df55c8f7c7633ec41e22cbcbb0aa26958a0395cf1d875cd5165745e4aa546f89aeea595fc6b8aa7f2f9cb8aa77cd7055afc3022b76c0b9441736d45875ba3437954abd15baa9153cddd4cb2d37f5f4ceca4511549395737b0935e56e5b9dbfc598eacfb3679779f463f91d1d99c49a3a3a66eca893071e90b8d1ddcd03726a0ab923cd953bdf6e01851651f33bf8216a369bc520e36fa6e78e34363743bc00c1c30b521619c842cbedd7d12204b7dfdbc9d2e3ced0dc5c41658b0a8454d0012c5ac0a2cb6d9def634207d3e69c73ce5985961b2a64160eaa48c38a2db7ffabdc7e575397daeddf79eae1a90a13dcfe9ad48130a29802054968c08a2358a404798076040e45c8a616222cbabb91a8620808c7ea0be0a0eaee6e0e32e75b167031e24e15c829ee38b32589c64bb3bad871be0d3f8b8a2b6e3fb1c588f57d4bb8a80dd5aa60b2c20219059e0082056188f1c20d5e649da4fb7b5e80488cdbdfedee6e234a586ea2228a3be70f41508631cdbd01800d5e98c2346919e3e4e5f68c189e9452cae973ee481de9ba51b2e34108f29b2c8f55d1a6c9b0a9ae700c3b63bd874dfa481e7a5fb2a823712a06a308aaf0e5ab3e1822f16c5779132710dd7b27b27eb0ee5c4f234e7085433ac105546e65071311453d84d1c5164bf87c4182220a2692b8c28b2b19c862e342c61b63074a1db2e3f3794c59aaf007c4194d86c0620c1baaf8816826460f5ae4302b0208a21b9040aa81c6ade650124c2cd120050c332c82803206151d4801172c3ec8604412403c303f02f0208454970503ac77813429a594534a773a5d3e3f81a40117fc8827580025051cc8c289042f946134d3e186212832ba033879d881c2819ab4e503f7fb5dbe03a5f2ad3f5c50cba28b1527423c41238b0ddc5a4881b401335ab882892c415a980b1b1b2b323848b3234b089b284c1f70c126ca640aa26d2ebdb28949ca1d594b6978d2a6c78ff57edcb7d5df2800f5904206c4649bc956cf04031995ef196876e14482251913190b04c956211597351f77eea8fad9b3711c9d49adc9ecf6d31480ee17e6aae4fd56df7314bddeec393d4b144be134bd59342c098114a4f7b82ea200b442bba8533a5360d46958596a3a9d84281d66666625fd37ed52815d28481e1a9abb64055e02ca30939560f6cbb2098da8cb328aab5cae4d6f1456f8b2448c3b7eccccec0e1a616666669ae491b9cc83e4e9e7fadcf114ef59c75903b227046e4672820397e5f5ab0a974435cbe49549b2569d40a15dfc1b78b14cebd80463c61c85c8753c86c443e01e259cc3cfd9be8c44c45198250e4b51c2fc4cb91901227032426f8bac2471386ac6cf42fc28ac60240c4b53b58e28ea4fb91498f0d1fc2de42abee4af297acd5ff39bbbfd07cd85275f6a675ffae24efef4a561adfa39932f754677742f9599d96bee568e3ce1a876f98b3f296969c9c9e9e932d411211d978a4824ce2c807ccd9fdee54e77bab36dbe10cd39d9cb9d93b6cf1a367a4d88695e6bd80c9a634c7e72676d899db8c649f3fb357fd6797fce6f09afb7ada7ffb66ddbb6d1ad678b38b4f8755c7be5dbc4609b48e2348792651020825abba423dd7e172ac052775bcaa507c39a719b85db39a48f0b72e418bb3d76705be7ca6d6f7169667181c84a2eb7bb9b4e8b84345382094848f0a5cd89276d98e54f2a999959cede361188896c030bc0c93611c7952ec9a3e322797f8561b5479f4efbd4dddd948698dbdddddd4da75bdb3a3beffa6276d9939d943d5c046cadd6b258ff2e17120f736b483483bed4997b9d55a14a6bd8b81919352c48caadf5c9e57f62e48a1d27adf3ee7fbaab35ace744e2b196398c7e1bc991bbce0376efb287c3a4661ef3a70a65a32ecf3c0cd19c155d66eee9daf85186138a0e32873f154e2993a85da9a076093969174d8525f6a65c6041e680626a7686a55766093aba50244f04ecd441f670df9207dc660d6bd9e7dbd5d4f353278f6d42fe5a7acad4301ccf34cc657ea25097e9930ded4cbb98ab9f3856cb52899c137f9d19ddae7164a55dac92f96dfb54297077d42eee6a1d52bb38295485a9998754aba774897cb16337c6766122502ff8ee9fbb7feeac59ea49bb6839949c3ce62df98b3fea3d28d65b9fc18e1dd2e5efa28e08754a28e5c4e88ed6469943f3897762902cf76307e603c3d5f5c24c2f343193e63ce5ba94cb516ed7f9100c769c34f113394e6c75af7aee37b1d58920b0d36c76bbdf5e958505a4ebaf0a67149e4f6a761694128a8126c6aafe7b951801ceff0b3b304c5b256fd7815bd7755dd7815d0786e31230ed12d3b0cd0bd3899150d0260b5fdcbb59c3462f4c8ad6b0d1137339a8619c9aa59e5c7e310d6b81708207a1b0a8048d57553d0a15a201010000000043150020200c0a0684629148244b3461963b14000e778e3e7256341809b328c75114448c31c41042800100184308819a1a2a00766067a0187d451690ce6f5b4083e6029ab844c220e6466c90c74fc562f89cf080e06cd0dea0f5f7377c061387870013390cdc4d66bd22cbc777c51c8a353e079bdc8781ef3011f74856db01f7a4eb182fd9b2af71c6f02aae2679ad50824c03a62d71115ced540a6f8fb2e57be6299c0f55991131ff13badad8cc2fcd1d610d7c92cf6c4d32794203d36312ad1c61309e97b7a9309ea8c86615865cad86480dfadbe08db847293e915616262cabc770aaa53108814f039ead86ed2b49e4a3d1eb6dd5cdeb1050e177807dcd278b020656aa6eaf3591bc93004980a89730f9284766db2cc5532891cad5e6207da738e3ff1230668eaae4cb44f1e8eae72082d60b7f668ff610c1de22cdf12a1a1274b9bf617acc5cdcd3a86c817a2a891311c4138ca92f5cb4af291404dde6f878c70982d0b3140081fe0f1bab77675d7602ce68966245181bcb60f3513a3c13ea7498a2d60f535a1470b05110ce47a15bb45d1bd5ca051cce600fd6e6149bc0992648c6321a491fb2877f3f46f5fbcc0fac8b314c5304ac011c6ac986fbe179058113a281bbf033563e71aa54c26358a70fd8bb23f9a85aa0708308135081ceddec37b3525242d85a29506e1ab411962bfc8bbe66713f605b4a6c8c4c384b0fc6bb043acd14258a280be1b0b020600dc6ac287df809d81097f788cb156e1f9f1261de8d0f25e38b1e729a0b0782cbe0eeae7573e2c1e8cb960c6e0f2030c2f865a8b70003b648cef69a9ff22da08c9c0980b141047296970e8988d895397c0d7781914fac423ff209b8dfd75940ee0ab4b11112a2640c2769cb55dd21892c199ad285d623e971ebc96805f0d8004be8caf623fc201410d9175020383db32fc71472116120800d16a1bbb17c4999950c11388ae22de4518946e06f1653f02220cc385006da03d832a03208d69e22e43357b4a3400560bc88d8f824740d591d484cb884a905f80f64be65509851a16defa2a1611e2073704e5ddc0585dc73163533d5d8eca34fa8529b63541668511a60b6c5353eb436e3c7ef8f52336e7859399b66dbde9df4d97b0e00d73d9f9cb0f01e93dfec45a0153aeb632f827ff1047c72c89ebd50b89c7c10a984f81c5930011c752000bcb270e47e33d076251be8047e39c877e6c7b9244495caabe931cceb4f8426da6218f25b1878bfb475a32d50baf834885b189a177630948308d0deb0981b22a03623999d191415bc208e46adc2083880348fd45855af551df20d2a58bfe85cfb653bf5e3b22b8bbc9e5b978a750896571814c0489994f3726e96907ea16362301566c3bfd7cffa8e9a1f94f66e3da1e65d30fa72cf74cfc0c9aa045d81d167f70d494e0031842fe8c33fbc82566918580d5e6d4a8c196f4c32d507975f4d0ab2239aa5905d28c55dc288926854eb734399040d68306d3ef4a74ad5b65e30ed265d30258c800911a3d4729c8eb342a73f87d827ec7f5eca1011e21ef927307db6833dc9fd911e2b0d547d10dc44b2745afd4bb39b0db104bddb815f12002214cef28c875c4a36a28d1f05461762cc58480f6c32f80be7a3ab9e1e9d9c27ccd974f414b0874e1336fa4f9ea387423ef4ad70ed7f5a445afba22fb745efb3b8b2258853168db11c72ca6295e8fd095cada2298b4a172b18c1c994f816ab842d316a3a861e1eda8bf1817e298b7842165fb0eafbc8fad3d16cf4629796f5573af112711428f65ad19924699a8d637717d3a36483be7a4626e59533ed39f31222a774e249cbd6799030bd2da87469cf852deb0e2329cab75194287b8b5c384400e05e30a09851ae8a022bc595935a28e5c0e115260404b63e2a30a76c7e0541292d51546f7a4bf17d46608447c9de29bdb50b256dc219427742a6c90951a641a97c481c78762bc0bd6b29e1af0d2aa8996f5309c3a027ffa5245a073d25cf3245ffa1d7aea59eff5c43a588da4f0488e97e2809a1676c0fa3516a367c36c77a183a5d5f930ef2de15d960322c84982977fe4640a123e3aa6eacecb3b039a1573e8421fa03c4ba918d12a2cbf8d1d69ae0b028a15a422f992f1207988fd18139e236e22fb8e1b7848bcb9df93372f1bea97d993b5e74583798cd154de0a71b4e7e53d35a346ec205aca748d1e5f6d886ed0e2ffea051ccf43248f69cd99bd303797e492d9ca946d99b335dc27661e326c806c46bfec5d72ef017d35a409e37f63825dc50a3326fd43ba23d440f05c086c59e6f22d6c6f1e672391d61dce519a6a7d46fc2c528d922a12c06f2dc405d3546136db240a2cf87ea87ee5cfb668e5467148f8f35b23e2757925c91b9f342bb3e5f05685074a17acb3967c747c425a344fe9295d0899a6f44da7ed8e225c329ec16dd2f9f3bcd4e4159a55c062c6125f635c028aa4dc7b7f1f91a805c5a64ba0011aacc116961608878e3780d9b5e62f01d5639f25af81a4fdf9a7d0e159abd58fe02b58e8e4cfc9e6b02e53071061c4f6088488c766c243a4b8bb69bf0fbd536e59aa4997011ebf1182c9a3c5ce8b4b5782571e11b70c6013e588b2bb16fa078047c7c98233f27ae93aa8f104e11a4de0ebbe8b813c428d48483b20856cb9d219f9f3fd3e36a95a28acafb2ecec901111e5f093a39d7d7d1613fd51ae683a0f4fc4e55d4050bdae2b81fc7954883921c7f3f367977316e898cd34ef00ff67c0475467b5e719bb206d49505da9a85a1174075b573ab39f968d966e3a2d5591930212c8646374a3415835b4553129e680bf442306026f239a7abe532b8329c2c505b6f2c49fe2f08ace8741f954c8de4a9cffc474372736fbff8656a3c946585d21eb20513a7158c014329aeb83a52b163a70aa25c501d9b39577a480212b0adafaaf4373b2b1d1885b301392720cf467c9e4bf02ec46798a3bc89290d49f0b425ed8bd65a03dde46bb07e99c88146216f7b507d739499bf11b944cc4c4a34bf452f17c13ce3222950addfdbb1dffa15b5937d8d336b3d994d58df5b9ff17e0221aa920fce212012fd0e7d89c496242c1d2af1057e4c126dd00b5e01dd1aff2ddc8295d4df765d9b002ba0330b65fa1506e803df158565baa39dbc7a8dc589eecda11effbeb8d30a3f3bfcdebd119efad522993869d3e498d1c9c9d0ee349881abe9ac817eab5453882c38c0ca9d3d8955110d5057ac61d02467e67481dacdbb52f657615f18639344ced19018b061629e6d16a618445a21864638ec255bad0589bee113bca774249aa08ade9fbe048ba85c6ea2e9265380cd5cb67db3aa378b73e154ec36e857b40ca734a25e55984e9eb095ed183da564e27914377f754a834a190a4bad714a8344d069c833385d90d805b8a8a121274f64302e9610e48ecd4fdf3b0db8ed911b11e5d2388eb3ea7bb02a7583be36afc8540112f76cd5b94d470a826d261e71070e316d2eac91e0d86f111aed158f7414a01fa636d53b7fdc5490e47f3c6ada79266ce310622b9d7d0ea00b49c2821e7c0ffa6f33cd893d8cdfaaa82b9e688ab030d91164c600d3b1a81d92f44fcec4adfd4d0c7b574be8063442a93439a7118d810a03c9ff5519dc680f6948fd3d9c0fdaac8072687ca904f4037b2e17575ff9af161b01ec5ba9b8a1c4e2f6bd1491f929f47b338c2d138a071d03173dfa5ddd5ba074cad790c384ac1cd6fc6a183dbaac40074423309bc0cd19308f4497be8d1c16138427d1ff002d0367dc1d8e5ad7904a263c1fb8312476de581389592c9ce251b52ab265fa84f64ef7edd07701cade87b1b5f577e78b560d6b17d0fdc5ec2faeb203dcdf8e003d425a8f82b884eca9e41263ac00e30d6dabbbb4a7e4051e2c69c2e3a27cf59c0a0552339ac0f4cedef280fa7c96e5e8b756f9b484bdb2cb25e6832371a542435cc739ec00015d94c896007b0368711a8374ba57dfdd3be60bb6e19d04b510b7446f09ce152c10bd6fa46f199a47d5413f5933a853568a8e34f254912137307035a89a2e3decb4873c08c803e30810915c95c0d1003e6366560e2cb2fa1381eabc0cbb95c81c15b7f41e899013c50eaea60713ad05273232429a929a198bbf2bd82757dd8c9d8f54d0d5c02e1075d04a9485728774eea26d44d4c023b2aadf1159bf0069fcfa1010036e441447d1308d0b4555d5f53224d65d85c97553f8c0a900173326e2cac514bf0659b73b780364a25abd3165953d71bfcc227fe960ac72f9c09b9b9abd848058eed5f1b95b918367ae63196fb3bfb60475ce0a92255831fc02f0079cdb8b1612fd4ad32c341d854acea7680ac018635d444593344c757607bf38d4a52c485cca29ba2ffba4d872a8f477bf661e555b214ee15bd62897b208fc57aab1f0765e74c4e003e8895a1a621c39e7fa4a333eb37138a9ebfb1462bc6fdbce0b10e6100d81543485db283535d5bcc18c6db172345e3fecaece6aa63ef90db66f27fe38ae1b491cf5dfe2387e021dd538da5e35423f4e3d6585cd983d412260861216b6c1974d9c015c70fe01821e3505d955de36ad443d0300ec2125878d445bb2b4461079c99681da1c8df947d709e72784140f5898254de0a44d8d947b556f16c98990e94a90bd8aa9fd7dc159a8efbd56fd5d7d9b64bc1e52db56be1058319bdd55b0f16ec5831ef6dc87dbaf085f9929e81df8859a8da2dbed1b92f03fe0b8915e826ca65b8fff2a006b51db2201ae71618ee6e210241980f321e12bfe09eed4deb83759a473a567dd16a388f4495191d3d83c6818e01ad3115f1d26ba8e50a6f1a0858a688c597d95b7ef70574518f405980013c7b3e6d2a646374c7a54e68f1b7ff944e6d7a15e66041fea5cd05eb1b1abc487804688c27e4550339614a14b51ebe4da006b4a0d267ecf0da60d9e76f2a3915ccfc6acf3f11a59c1b3bacc176a888b5944b868133fb80c1611e294f1df07bbbfad19da3a96b872300672d659840accaa6192221c43bf1a64b6bf8645a85a8e18bd9d5c7209408c0d5b9dc503e86dbd718a50b42260b93aed9c416d3b16e9a33e4462a26a0db111cf61b85b73e2c35812e56268f1e5a25ed432efcff124513d81756ae0cc7d61bbf8cba8b463384befef2c2bfc8e90f6a124d06afc82570d6e582f73bf34b057e59474502db1229c0a09483a5f0041e778bb5a2bdc8fd1b91226c452a30c753a3c888d5156dcc76eba7e2d5f126b30a6f44a658dcda5d3b70a5fa656421b2844e68459a988a1bf6df19208aa20dd4a190f2e9df280a74662bd004af93b7c4b9708afa656ff6aea36c75cc3c91f4b5296b95c81db905460fed414f790bbf7b304354dcede510cc9d523c86dc9e011771942498ff178ca373c64589e495837b43e3a12996b3b96eaaa2cbc953b1bc5c80c18e0ba505424f4939b0cd6d5838fa69f3f4f528fdf20099438bd0b5be215ad99d18857e8b20cc23b53de1aa4bde181b46e8556be0299a79cd504e73681b0c8d9f3a44e9e8253052d834a4943cec9d6d8f1abe8badc674c0e6df7c6d50a78b4c95177c09122e8db8ddcfc4edc9ca16b0aa0c5758e959906bfd079878ffef87855649e5f64c0f3eb3cf8837bb7b0ae0bef41883b1143612833d93e443a258f1279df04682b7b6691ee8c765bda73255fbccff81895e379badc4ebfbe084b18d2ff02984586a87605e705fe8255a59c6fc02cc8fc0f1ae97b1aca4f429609aad3bd7a95445274ceeb62e4f93b93a2177f3450a9366f1c5836b9a244c75b18e94bc5735ae7b40a213f555463b6167bc083f2a8063274bef9fd1ef0076b853064765002fabe0593750607256a88370ca284e1b595139b802c38bd21d399f6310caa502f994d2d17d2115ab8ee85018fbc9c9ebc95277c760ed1098d63af2b879c8c4bd2d9ea9c386226b4a8fae84d42e28f3316ff787f10566d4673ebe244eaffb88ac3e0599f6531b193ef2d04da79eaf4f2ceec87736b89d7519c941d07863bbe10d571ebe51229c1bc0e60dc731da0bbca709e2549f4a9b9ff935a383caffb3eb9defa1d55ecf551089824c98a8d5d11d5658b2526b40e737016410f78fe6c16c6145acb5378a3ce3179984b7c0f984368aa59b9967c47d07df9eb1d5ef1e937e7b9cf6c8a5e1b55c1ad73e8a57842e5d1eb681a2e182e0f61b610c2a2d1c410d98693f5275a7478ca9111e4f8c76797e954107048480170a6f533c8e1effd109a75650cc08e18ae80100e511fc1d9a4378713c159fef5273eb3916215d4780785cf4830103a47ba6c6d8f3fc75286902fb51c0f332acc2f0f9e88fe66d1efff92732c2c3eb3ae6dae913869bb60a4c98d8405a69e4cae68489119e19d87fda9629effa9def6a5512db9417ebba230df093b79ccdaf5d83ba40eb190361dbb87b206c8d38a3514a2fb62042ed97d6029e8f8a510143f7c9daf6ccbfa71a5bb288ba753ffe03e6f84cd7d409537005fc69936e3f1d4bbe5d4f426798585eebf3f3db9e2b7189d911d4e9aa3e643baa0bd420ddd8f1a29856a13cbe864b7f50a7f5164a0381fa70e9112fe0304efc90536d0c8e4c6057d758b427563920aaa96d47e68da7958f378ddbca396f35323a44819d55b4b93187b45facb13f3548aab82a40524360b5954a32fb8eb74a8843f8a59c2ad3d31b4519dc9d44f2b103f1937258ec2991aa9fdd2ec3fb9cbe716d5fc2e94a1d61b12e199232754455203bf84597a884f0e012d651f94122020a19579c4512d661e364735d7293ee9e2683b39892cfd690e8d6eb98d6edad3c061cbbdae68447c034206c12b222b733864724ed114d3aaa489af4aa54d3d4af4bf9fb7443f51f2a8abb0f7f167787c9f3d69772a0d2c6b230b52b9bbc32f6eaf826cd1fb5d024815fc2bb46b78758048e7601f8e76f1346df757e4c029464c27fb259748ccb0d9a2dc568de20d8d1539725d4b1cbbac3611c44cc6fb01cceae4f8fcbbff59def35299983118cb2a4fe7abe87f96b41eda02e1a5d3ba702f0ce07b98719e9f2006934e04a14b0ffccbc1cb1844da82996ccaf37d0925f2e961441cf43d8c3c84e3e15a4acc5aeee6f368448c6bf62c2438d89e75c466b2e04210cc685a0680f8825e86da903508df0961f8d5c98b0d5b269209b9c2fb9adfbb39b055a758f61f0f55c4bbba7e5e077b9a6c5a7a25d83dd851dd86664976ed149270cea136503be5fd31c56da08eda98857b0cee21ff55176e17dac44312f72ed5f559a7f524e50785417bd789ae410f26e9df6b99c93d55aa3de5d701fc08abc7650121ea35912f34ce43afdebf6477cbbefe7ae010201fd3d6a811f1efd4448fe6dba8d338763c8edd44f490c2b6e42ad0b7cabd6dd29af1b53b13db4bee49f78327f9495f11803e06ce8ef741115386dfd9ec182c464a25cc341360ec8a6a995d6fdddebb3ff0df687500d376fe2b9cfe19c433e1d0c5cbb968206e4713b52cec48630010df601df83f8e6207a07e26c89bf99ebc292d7f74c40970c270bb5b02e1b93c527ddb9d502652a62b9c25f4973eb007924ea591fdcbba09b08c1eddc854497a7704b8f2b3d41c6b429711ad9d4ccff9f763014645df57121a11a2a157882cf3c40a27631b345cd9bc48b6e8fda39951cfbebecd61fd6726e80b8bf8421ef927cdb8647c503584e026894e252025f738498a2824d5c6a7632939958a725576f145e0c88a0298c51d48761185a9dfc1ba82c634dfde779e31d89d705effe1cc92ed4c68ffb6e25fc962908d1539fa08bec72a704f99697aa6a39858790210c99a0007c6ecca5664902163a64a1b63ff295480a156d7baa5c1fc9709b76eaaba123c2791a8c04d66b98f39acfe99873422977a682381f1a19a8ecbd338fb79727593e561ea3bf19932137892d4266bd5155d922cfa37471905448f8cd42875d1e71a3611fa452de58739417120184b35995a323d271233a0cf6e26389b722181b04b8737aa8e700b91ffb833d0ae0a56bf1db4462df22ca55c23ee7c69fe9fe59a2d22f156353ed1e3b6ab9478c32238093da5a002d4f3a2197c777d29c3858a3a6d0d3f06440c3fa8c895912aee784a0a51c5e68c65512371de4db1782ecb0801e82195c23aa2db0e496cf3a71591106966443a7323503b18485dab8161eb444200ceee35a30441eda3d71d8a6da58ad29951ce59a7ead9a2ac4e55f18e55b7585e5617a9168cab0e881766cb0d6790af2198e04026defe04b8bbbacb014d7808270095774381246218df9422a39ecae19ee6180fcc024ba4355fae75d254450b331f196c9d2e7a363450ff5d989f3a5157c3b4b9ca827e070d22af5adc8969c73dd36b7cfd5e9cf74d884afd531306fcfec0b51b307685858375b9bc0fd3a457c22d8d22c09f3419baba6bfea48ebb436f240e3b8bcf4f9ad5370f9fa09d7aae2c3fe900f19ae88ec831ae1de921cb4fe0ebdc6b0f692cea495774078691aa34468534a49151b2c94f7a3e80599c9a841c9229fbef5f9bfabef6a4bc10050338bdceab5900df72419ed43478de713999add75e71800c65498098060d0a241fc319a798953ae3a7d3d87a0f0e9c67847b91c3909075103d307d7f7777bb8ff07a610db170a2e033eb002cf26e426c4e919381d5d23edb3f139b9a4d51403e7fc38aa072a772c388bbe2025049aa1c01218687ce2a6e678c5db6de46fb770c4b181a9bc992c04f927b62e212ec7062d051578e07091bd5b5ea6cc84b6c28b7132af0b2dc9df677fa6302c0ac7ce76645aa478a64d8ea9ec582c238624067bc1453a25d1d1c310019988592c340fd6489446acfb4315da1d9814df1d31cc49b6588614e8ffe19d6535605a1d20f6597831476243b6261f01a898267e531564900c786049b82fe4b5d38e1f8a180dcdcf82d253613c49d0e7ca110bc312a5a014b78f3ebf16f24de55028d57deff0caf046a431fb3a2afd1643e912ccd95ef9d644e1cd1133fb128754683aeee21383eda858915660f00b0f4f2c2dde5a28709c73e9b9af0108838b92aca28ecab8b61a464712a1da2a2110ad319ac4b955e89cd399e167e7d20673b6b6ed8a3b26c5ded6faf55bafa306f7d45958fce0f5787c19cf13cb5d82513f7693d43ac659d23b9408218581ce00f9d96c7153a6edf84cc5269c1dcd9b2945b81db4981007c6368645b63c8f755dfc3e241d824197572f6e9c72b69df630b4bb06ed107aa8d17109c6140d58b2a1c77d2c0848610dab52a328334a412d6b4a42f4255ca65d69a6f6b2521bdfd83745b26b65d58b6914152f811a2461052d1aec24c31e65c85e3f464de941381b0fbd737aa20b4da223243d90d891b62d1919eb8e8104e1f109f2e8083c24e6ab9b093660c8fa0983579a4feb7e06c22b1f94a4e84a775c1e104c3cf09d6bbd6bb3b92171b0c24f888e3fa11071d2b5487c6ea408a25d79adb58f2205ac9c02c05aae4204996e0b819ff894083a1862cf5a8d192994283dc1411cfff526754de772a5559f3d24479f77f8dd7d519c1d0385455c1b934225efb9f86d71f0278afa21fb14a0deed4312fff38960ddcf81e949ebaea452322439b0ada1441e2fd7d8830528020331d7d874d55babac9eace452eeb1e19e63a8a02271688af09932d291080805082a22b9d46347ad398455f4691a0af2eaa97eaf1ac0632f6c7f2fb49f22e0bb12d8a6f9244f9760a8d7d3b4d6d359001c83cea9baa56fdaf35635ef20c6591a4a15a9dea7200c43e5440905e176e58d70ca5bead30d80cb2427fbb02785267b5568b6a4876038666c2c1a315438a6fbf304d0b54dda645694bf0e2a1bbb8e37ebbc47efc83ac6df313854f6d40ef2e87c8cd8ab3f6fc05f753f2aec55ef06dd46e430023c5d9938b0f435016e3fba416c753d5a1774f4858032c79892462683558a0e2f9b5c3dfecbf92d8411049954fa364030c2c0515a8ac35e5438901654ccd79e07027dbb707af64db495346c8fca560c3a229a57dca621f0a8de7d1d3a53d35e3beb853010c45add3d13784b2c52f256f03f488d31a7a79755639d5fe0bb3069b69bcdde9315b61050febc2b6ce967a92417bb2af854b52ca2711f84940bd08d30ed9f72e5b1e2b217ba0bde52c8402563d60ac85e96182c5bd9c5f3120e5f995a51bcfe050afabd1be48950ad922cade3dadf3c62802556916e50ee2a25e25e7a5b88da86ba96f73d2c1c9005cffed120cd5f0331cd05af3eaaca2559400d5e26aa2f728d71ca19e026a8632138de86d66f2d0b3eae25407ebdc558ed996caf31de9a8ef93362d03f0cc49a47132642f0ae253ae223004bb79c72ab01ead0d2084e78acb7e1246feaf1d9bc62ca374c5acbb64be43fc791b51fdd7b7573db021c4535db2ee49cff246f4c7712ba364345df235779d7992da6ba4cb3a961f9ce9dda9602ee9e63780cc9f3d4bfa75cffdccea7e0608886df93df20b0cd8d4d6f6e63120d9cb42de6d88cd1d369bb693ee4c885c31c1a4bf55c92d20d98cdbf526e8de922a0039cb751797bc32a5015b8205e076e1d4d68c492e795f271889c738bf3b461ec7d05ef1617ec5ce8fedc9c35f332acf9e2b02db4b2ae34e2a73532a674509a4e62a26f30e136a9847201ace99b845a83f12e3a867f4184ab41df1b5c50834875bf0507c9f3d59eef2e399701e769b69978b71c48fb86888689c8c742c3c08395b937adb0e33f8f02aeeb3112147bd95ec780d1ed6db5143a0106fcbba45c1a5553c5d03b1a571e8285f768ef19fd7da434c23ee5704951c5891248a5051e830562c63be506fe116c7c91bafdbd193ba07a6355e1a74e7dd7410517ffa4b43c3df7c90a5e3e7e9d65e3326467b0e9c26862689daa1b4f803c6e2485dcb2f85f881aadc5b44558ac617d91b1102e090603a11bd80298a36ab3c30a50fded20ae3ca145399c25401a39bd30359290e81f44368dbc8d87f76080028294fce96fca942764813314748d19e1d1a731eb358f31699269a04e2be07bc5d8eeea8a93c02fb28b3aba8f1ce814369a1ca3b4f6860ed2b9a84b29649ea3e5290c91b391f4d1e41345d8d76ef512e673b320d1af3a4dbd9ba95d4b6dcb02783e7fc26c60308262af7d1d66f4c51b97b695938499b4607d39b8cb3638fa3c8cea4dc3a338057074dc0fddd013f9383b4ceb57421974a6680673e675776ffe0b2be1fe4c9eea0cbc122a7d68906fbd6b3779b7eddb680613c78c3b877a089bded723593f3a887f12a86649672de7787691b2e40d90f66b465a71d2542a096b28f89b825e8785eafce6931f60b074aee38f375d451f9248b551e87e7d3cf01ae8ba8c970891d1d326391468504eeb59cee3514d0d2ff6701c0d8f258c9c59cddac1302e655b407973f49dfeb0cf9f22fe784db8700bb801550d17034dddf4deb828c016540db6693095d1ae21a72c2871a1ee510d84b3a41022f6967def59f37687adb734a024216ce00e6dd9b40dd4fbe8bebaef0ce445c0411b509a86b7c1f66d93d7b7ab62a3bdb7dd8c9bcd3ae134d311299d8d5ab874036d98d0c25a2d63aa7918a442d504d147401d5c86d1d6b80e6b8ad1de9eaa5750d98438dc820d8f328ffbb1f939169e7cfada2b7009b5c73547d951dab5141154c2205009055c235b980c903457922858c87519ccc07f3c5f8b486c4437c992819f660faf5725832f6fa518dd6113f785f62ecbbbf5edd710151d39f8ed96e56b9986ff0e9373a3b000402e92857049e9d10c17f4043a5932174657655e827aad1c949cbf4a6dd2b114b1411fc490b7898c89182531449858e576fb70ee77a4c379d03b7918f914d627aecb111582fa795058175b02983894fe546f695d425d766f055aef7c1faf27b281afa3e82dcfc68d0087a849ca276166c5ac0460b239012d0a5f342843486a0e5d1d34ab921779bc2a1ce6eebea6c438d0e731071fd9b8dfd5f934483b73bcf62cc3feeda7ee83861cbc459fff4724a453d828b65946804991f4f4288e3d4f8f084d2191efc72431efe7c1335eec17f7c844d3f510af39f1999ca61a205bd5698af7f8865bfaf3df7a1e65a959f1edbbd3cf3fddb909c9881dc3bb88f90f2c1e0703dc3ec3917536047383be7aff39f91e85b6c74a6dfffd29a3ea270e1545831a48a6fc898d25b25a1ac3e849097f08e69d20924b9be6e615c36130bc412813fb94423c5482b9627438f11658cc4a28223a83ed88b211fc1f4367418c52959e820dbfe84823cac3d2ad5beeec0cdc6eaca0af997049598c4622b2f24af3ef034aa4d45ebebe11580e3f518cd5d4b8188c65eea26101924bab434c135db35672e7ce86853665d862cad7b2ba1c6ea874c69fa21d73f549aa5d45e8e00113eda51b3f11f2c7dc15bc17a2b0572476ba3e7ebee94cb91f8d295da6e55b4bef5762b2016148201b1d9029d8ba3fec0ddcaf98b72fc9345f63670bdefeacc41e3962602f69758f4bd6ec5ab1439ad4b0a14bc20239ddc2f82da3f1083976965b79a412f9add7735ddf555b7fb0507a66446b9b5b03f937b0dd0fa64f449068bd69013e9a6109556f2c36160ce8900b5c802edcc513cf0344bff6d5b51ce225bbea48b9e32647f5924d71bb3f757449b5e7f644088004ac0b0a7778594f5a0fb8c0f1ab51917b7d87467b70255776558a37dea4dd917a56d9f53b292e403f9a5783b3d3ab49cc910cdc25c3c7ea67089804c26f1d86042e598bd4b6aa4b5b6919c9d12ed3e7a4023449682dffbc5f99a98c7de42850d0747725d2ee5b0f43662e520aafd635f573ae7bd8528ffa25bdcb093989a4d6f73007bb977133c8aa25a971584d79543f89241322c45be9284236ea0102b6b01fadb32f9784008546509e1b6c4a36216c0e3685495a5eee5f477896f9c2715c0fc64e499e8329f67bda9a462a484bb28074f4b05555c816b0c0440aea2d044a50d4a6310ddfa8950a4cd0912416caf4b304ecae4cf225c92d69ba18aa50b22145f79022d7754ba45d60c951d030e5cc1a33772a9a610fbded286436bc1fc4e281d22d41d203c403f09df81a1553493d425454f04a6b5c8f249767b9e79373a8929d08e31af0d71aed4fff2f559242cc52a19aa4fe87c97995ada369020f5f99c37cfdd5f629f4a4fa400f03bf9ee97d171ad8c5c79c168ec83d2a1e4cfb578ca21a29014c21cefddf135d96ffdcd73617b7b073389692b9ca378ca632319140e5535224aea731e1a98cea752b237d91271578c0eb4ef1ed75fd5c731cf077dad34717eb8d6c879da14ca934e3cebed30ffbbea4f758af6caa13d9b1dec14e6fe7e3fa905b68123042ce843d207895ee2cd55028d1c325a52ac0935bb3506a7fc08ce1a84084de7d00ce1bd265087c271a82972a244ce68669b748014a9bec1d8e520d90b4f82c41830cd02b76c779c9049d337626bc0b0cbf609d0a05f42668f2a21d951d793668dca898f89d62cf0743bc80487eec94fe8085055247e7e9400b54dd36b94d50e9d61b9e842327c9c9912a2867e62111ac8070bb5b1bb859214d7a14297cf5715e7bc521fb59deef6c7613ce1898da5ac47328e4c800280ccfabb23d7ca2c08ff84f84b51ce8f4bbf594b6e6f92632637002f294ef33947c318d5072023930bc4ffc8bb10d25ff09bfc08d6e3c041a0807a51efca4d914dd9672af734f2146d63fef12146913e9e0f0f0cccc13300420c60d0da092b697dda657fa5b672091fb9eae2ead0eeec3149819c8167d8657e695b86e85c1a79c862e23acb012844f06f83ab9b88b00e814348b7c49b9220e6ec364227946acb29104ab516392f14f75cd2ef8d579ba3deb522857d01fd0cc2061412a7b63658b1ba427553fced0e80008d2d9291905ffe906f8d5f0dd06c06a2ef03b5557a4507b87272532e6d7dbdff3975cee9605b952371840fcd017d095b41963a582fa8ad06db727bf1f3414cd0e1b6a62dc05ff7246e4097bdff7d8f40e11c50b79362ca668893f029d3d0006bacb8646c9b2a9b5c28e224c4a3f1899f05f6c8765451bae523ec0e85a9bdecb9d086e9a1b34dc94af1776a770828f8421c8366bf754cef32a36a85c50ca9bbec802802e426a6024c60a3999858e37873b4379f5dfca6dffeb5c9ee02bd7949883f4043bdf2c23aca270787c86e6baba70787d14d5ea405b2657bb653892d85553a95a19c1d83f8bb31a52f7b1d26c83fd7cc78a5bf2a5b848f419c0092ead027ff7939fa74a00e9c4421e87b7131f305a36a815121d3bfd0996f42da92de01aa76d509de07060438b3dc0bc73ac8fddcf4ae40313c34c27a0d46d91a3fc6eaf7ef7f8a17b27037c535756b27c5eecc9cd397c4efac50f8947fe5cecbc810e27c70075a74cdf5d0e4fe354ae53822b5444faeedf3666fbc2dc84b084ba9fb42ffc0b75e52ad477ea4673c6959d2489ef12c10670d8f4f2674013b8122544c78b76a80ac5585811031a24209b2ca540982fac103c58a37ee3eb8809549b44f5190d75b832f83110038b4a9512981577a381c65e5aae214e9155ae619bfb8594e2ceaafa2fe2bfd95e7dee2e51f152f87c95f547222380ddc847adc8ffb9d378ddeda6e4e44a4d353e8bb9cb59f3d3b670371e4ccda3cca741eb073de90d7b4980d0ef3f95da05508bd5a309807fb48b8fa576e5c23b8e323d11d53919afc22ba6f9f967b7b0878052402be36d28c98efdc9bedcbdcdb9c947a5e44e32eec6ef93d18661c81db13eb6dd5e8fc4de1a1369ac9c7942bc1b6626a03c76b5c90e34479b3b24e4bc1314b8e3247d4e143b5e319f6afab3092eb6fb095ab745b0dd328319fb2ad721c849e996e7d549e29a4bd5c7427e86873966e7bd856702031c4bd5ba34b70736431984833cf271cfd453fa01291c2e13726d49e2b432583871cb96223b95f1f6170c307197ca8a10336625bf6044bcee1ec88f64eab3599e0974da48e5e2c38d2190686e88a2dbd6e14b93eb7a9165823ed48f246176ab31dcbb0df0f862296da4fe2a6164be99947caca63dcf76ed37fed9b4f8ef0c949fe73a27fc589e98636b29fddd63db35ef7d571ac090dd89f19683dec19765689bd02497251d5781342216f7562513078a6de19fef3fefd10a2f8b122262a9d2e1fdf01519c47ad8771dd785c803ed58a80969f118a8432ed7f735726b43e237280d42df4e4b190f86bdde570b8210d97e0f152a962c95286acb3aa2fed4856ce29df05551447377897f7fc7b5e99cab15874865fd47d55db0eae4b7bbbf0b5d33a3ee9db26570d7226e4edadce94ab5353c8b77a88156776a341dd1af53be64297e2a240188f3bedb4bfcbf391d63c7824edc40588390447f04293fd3e93d8a567c65460be121793156455b786b06cc333966d6f4467f8b36c61aeaebecbb05a1e773036b1c512970dc99a101dd86bb160632b308eea6ae3c66d207aebbee44c9fc9b8e6fc7105b3c46927fa6103e29b44033c56efe903e8a689d845afa889e1d63896ad49bb891d4d5c133e480ce74e6cd64d7495c565e31a4ad5a47f765fa001c1f811d86fed705ac93d7d19993cc5e8edc1855823eaa30f19a398c44856c1c9b576d3532628cca8f2d996b544b1f1350b5de4070bc677654bdc917620815921c60a262de706c7e5176abe305318831dc54268c2e043a24f33cdb9c88314c347309be5b8782447c89c580dffb482d814a8eea8b8b05d787835cc839815368d13a087bc7219b260df31603558ecb8e38a805b91b8d9b47d63b8c1992d7889b11cd46f1895a599e231bcbf010506b9fb2903fd1e6873622f78efddee860c673d2eaad68f2f1aa68a702fb1c7e35978b424622573f21475fab1b9aa5a8c2ea4673454310d3593d88e2a0b7cf340b0bcdf48e47e1b6fea8d1d3ca2600ef821e87953abf5504519abcd70be5b3daa7f34928abcf6f43fa55871ad081578182aff2c9e60c1783d533c5de95b6257ce08acd5e83be7fe28280b51466fc7017a0b8fe90cf59cc6940cfd0d879c4815499f9e8bcd05e943e8912eb18ec070cf0416a7d7dcae87dc2c1bbea95751ea43b118a9ca8136075c359ee697bfd87aad7c134a18ab2034f27e5246420f4e903e870873ca88331d8d09d04fd1140639c37d10114991a3dd168c92fe296875c83ad467eeae3ef23fbea92b15389c9524d2f4538e36ade3f01967d7e2244304b8772020565a7abf4f2266ca7464b8723c6e58a66a015a6ca323f11cb00e9b1ec0b9071bfa57d2aed00401fbdd84c2869b9fbac776c4275fad98de462396a93e1e280935068195f932f0ceda65eaab76bbd252dac70bc1a11b0739f4a2acc88000407854dc4088fd29d8ae1ea28afc86095b4885fc5ffd4a998cfc11814db41a998cd3e5e76224bd288e6b6960c11659d89c2a5e0c65b6ba582d225352b230a6ca44cd5455941b35e63302ecdb43a01c13fd5c724271858313dd38aa54167ebcc292b073ec440de624312dcc97d30babba114a42de9cee972359352ad898032cea7f0a42c1abb78b643df3c07c508296135d748f8ca12b457fdb588612203fe226d14812f14da80e41958490c31205ccaf514e09215c8f30c3be0b529072a5078724702cd6089772835196e467862549965f15fd4d2cc484236e23be7a25cbd36bcd148459b88bcc7b02d203991e290fe27be5aad134a0e26dfe5078634c8d5a9cc72b90bef9484f698067256725d2a0f180e449c5a8019b88ca6b132d92bc7aa817539560f3ecf7e3351e2b3806124d85b2d13f6ff8dad9c0361dc0d9ddc411e141cf475b17e9f1ef6084447ff069683df605e6fff658450ed5636062ae966c8da58c09f6f0183009f5039319345cf55b50668e1560899e6345981ea3f05895f2cc7eaed160b86d1c060ada035fd2f6b14bf8d64462ae02a7cda8fb9407c0c2914c9a10b953ee5b3cf4878f5e54b4c1c3c32567d8537cc57518efdaec8a874fd65f363d7dcdc22b7dc25bbad398efa313fbeda37dbf2d8942924578bcaf273c7a9ab0bc00147f2029a60843a29bf81158129869ea4c22c59bfad76783ea6823e690f1ff3ead35e9801839f773894c98b485265fd7e918983eac54a913d8074deb7b237baf8cd08fba369f651af9a476f7f797853e7c6909ce0236358ba9e76903ba5ecc852a1b7af67f117d45dc9faa5c3b1de39f7193c442caf69e2b9796317b4f4e6ccd59a2f3d4b88a06098d1877ef199e1ecb3e7d53016ca6c7c6bf67951e92fba1bf1366cb2c7c41384e8d722ca3986c3a033eaa872d6abce28ccc41614119bd483b668ecccb176a4250b656164227b6560bcc4a9ad49ced7a9f6f1b98344a65294d3c07cae6d8568aad8e49052535202dccf3279ebc20d2939da6d8e81fd10e01102cd74fa650845e83790ae82c0aa1a4fd6da5eb5533bf915f2a245c1b2ec890f0b2cdb24451ce299c3f5de9ae6b2d51f1c7e10712a134d60c3e14901dde9244e84ea1e8608ab576763b487f4cd9390da763cfc07590532ca842b708e5ee35b45f28a191bcd68282a3449331872c543a824dc0f81a412f2d472fa5c524e035232facf4c671948c5a3cab0b5c1a2da6e5d0d95933f344aa594e3ebada82435b90df4746be3e60c74688e28b1037d7c74cec3344ac6d23c2001ceb7da3185945683927e40c8762120b88e8213bb4c6a966c50cadb85254043fb2bc6933f7b16c70219eb90f3df15a9aa3643bca06d55d5a24eb794a4902f0a1d9a9180f4cdea1cd3ae7cd0680991c88ce6cce1d5728e79c0d4800243c073e6216a8a3159f689c463031a47f1df5edcbf8241e8b09008de8e3fba2c86e7a3468a69aa14f9a90f045d77d7b6322223554249c21db80496948e2d6ea1008902eaa391415ab2b1567cf390ad20fdb5a680385143821e814783c69982d90cd79649701847b144020b57dc9cafafb6db1608557976c0c86097a49119d5d76c1044f77aafa81fb857d742760b5ab68bf5be7ca37845bb9d140340be28a62900e660079ec14dda5019e4e5f873eec4f03e7dcd0603d043a417a7abcc1475a2ae8ef5eb24188e25eb9ee363e348a31472041a3582afde1860e4ad549e64b13446ff03c2f0a63af6f7aa626208e4c350615a5138b6ca46c8da2d4b5de215e457ee5ad3100e9d1972591531f974627a0b14abb170a47076a35fcf69905d3ac9a5ebeea54f99bb3056a2c004b55ca509dd59b64ebde2617a21c096b704fe1d1fe19d29aeee9e449b544d7cf653658ab3c590694819a98392c03f3dabe398459d647f90985450a522c670a8ee010878d33dc5031c956bad36d0d2ba96a3db61712a4a47a8e48b805f3672eae5ac3c8002e35860ef074c16af15e2a1a9609d47f886c175d4f3569a66ba1077d0633756e08a300653647ecea1e3080105e4b1994fc7e84037c857032333fb338a0cff73b3c7b503c223a7cec4b49aeed3d003a7bed8907fde8c161a1581f065e16256c432e558e4b327a756d1e6c7c3c85039b8fa3ff3a8ffa596876dc88728f2575900618d2ccd8993839ee027bf81258e8b625c8be18af64ddbae9eb9993bc2bac4c7f5b21c48406640f628012408d4e1ca9f8b8cce2e56867264c6bf2e3bd4b9e62adcff2f117fe1f42cc19ea256b9d9231160b62a46cbab57085fbd70487b5000d2ceb55d5a90b753780a30b37ae935a8dffa1a7960fa316b81047bf7dcc8c628259fb358b001086b94700b0e134810e80714de144c790c18ab2330de7a67d5eab27970134a3a10b324478ede76818285766e8c94c78dec356c2361afb55a410c97ba144d7b5123c3caca12b1a8f8f2763d2499a90cc9d00cdcca0612043936cae2af53da163ac995e3bfbce5b6dcfd03962c53e2f043c56448b1ea437dfe9f23e6ba332323913d385f791d999e4f9bbcf0c98f286ded240deeab95d80a4d369df17ea9a68cc3746b71a64755f86174e715a8d92c104ff0fbf05d38caf11e138c5ed3428d14d1f285c7bab6c3768c8275f38a4748707ef27a103a56017ce52828a861415430894df99ee532036674b30791e6186acdc3e5a2b64d8d3aeb7e25e0e9d739ca4b1c078b055992b8b32974a3b1b9ab8c7a2e0704077303245844aab630f18c66658b12067386dc09c30a81d49b2bd7bf95d5fed05bfe6c4120f743b37db64d28b35d9bf57cec969d00e411381941784c266e7d3526e364e30200ecb7c7157263fca73de6ed88189ac2e0458396f2a02357a97ec151c7da0783aaee9f90c698379308a0a761113a6f1cc746089a5204da330356dfe87733c82fa574bc9360a01aad5384366f0f051dea7eb1d7da3aec778c6fe4ca49e32a7bd8ea436c5c3c8ae9bc8fecf6066024f23bc94b60d8e947a126964dc87ce4e7247651bdb2adf66be33faf976597c64f981e3d0745386835bf7531e4da0680dabf531bb3e3900420cce39a3fa008bd7ea40d7ff4e7a8334cda4d59f6cfaf8e370464069482f7104b17aa7e39cba3c0f058eb905855fced3953a803751ae4e9923e169bf81b071685a667f5c70e5211b66d25c0a083c047ac78416596110e355d9845789c6937b4f4e5dde22134f4c9c6017fdc9db6759de205d0e5c8acf8a56a7b8841b4db057b249989f4e15b4e04ae8123b296504166dcce7fb4e63c0a511a86a76103ea5c9ddae24b7f69140d48c4d12d88c50f2ddd75e82b7d80f077c0dd0be575c7d6f249345253b1962a10e11c99492dd1bf6f3c233cf2d8922d49bfba6ff67917d96c0133163b12c70adf2b1358333ef4c3737935382b868092d838385c7df09e6747aeaa1205e994ae8544bcb4d05738850b17227dd642b7221001c45499ccc348a44d00cee2d95d44cc919469e758d34da8fe63ab51887a894c5bd388a4d3548a9fa71cff3e2c655b803d859441034dd7667506782e5247e7d2d02705da23af70a5de88faff74910cd823798358e6e31371e853b5603ef4d6cf4f35acf677473a5a34114bcb7ce14391c65e11975e11d51dcf01c68e2846b639ccb85dd97ffad74d3dd419f78292083e85eabde17e799bbeb2b12f414ab41724e5f8c672fddbecfab9526663cba5996a4311486f21f9814a8de6378ac755f3b95796d4a3f42ddab2a0e843bccef92da8ed07686c6cc9ccc4adca83747734d903f8def60e1209ffd9f07574fdb159f346547329c7192fc9844e2301d1993cebfcd4fb7c7e8c5ebdc31c136b9143ec69acfb6e0449a06e0c04074a6f0234aed6391f6af1d32340ceb96797ad63003ea6b824a57439f3101e14ab7324173808b0a95dfb25569a861f67b1d669f3f7294826901d1b1b2eafdd3b48c56232cad391ccb245119eed989360e9e02fdf62c2d6fd0d044cd7cac8aea08ca9689aed962a09cf0eae49ed9b11931dc1a7306293d356c9ded9fa4b29832300e5331127c5619b185047d3a00aa3ddaba4066f4b8160a19df85cf928fd17dbe8614d2f2cb69995b10604f5499a39e931b092f1f7c4548f7fb93c8c6123741d62efc1214ff4d9810ba7856ec87f444706249ad0482d7292184352af258dfb16c7341d98f01c940592b9c59ae58485e456788b342423c56a51c6a42f22a7c433dc7c1725d39c51a71d3761019c13312490e437d7dcafb116aa4b93a5935d836a241b05fe18f930e3a18472022e3a8b538e6f92bc46ca823c7c78c926429ea9005769dad75b5d217704b857dee97c3bb96220278e02d4e4a677d4acfd8f2c32e52b2914130623396850970583b936c22fcd94cd062a0756835c912dbd812e468e9627a70817c8a7bd1d155bcf34946c7c7dfcc6ce90caaaed9d6cea808b7f1f333cbf713ca955487b497de6446a32cf330a7e199f6985ca48b9ad549d1e8ca5a23d50c408a4230f2061084258aea9d87aabaddff53bb1ace810d0834c5fddac1df39227d3183bf18dd0fa887e8259680482f92f6cf1b3b0830db9235221b8ce15eb5754798aeee102e326b62ae51ec3f926e46e21a4c1dbde05e5a1a720b40ba9176151dec1a6ae6f5eddaa6452a3b59f4e4f96c22c65302d5d6f49f3dd181c93acbff5429f98f262d6a10e0d6c88fa2d9abecc0f9435ed1031809d92d2d5332c9b3ed416597de9910e239bdc5dc90526f7d054699de027ac80d13e4ad06f393ced35a36e09057eab8f48a3da654bc8643d5d5ec873dd01a96831feee82070581dd1a83dc227fa2b4b4d9aac41c0456fbf45a8836d43abf124fb1f8643f4e98894814fe9460b6d9649daefde08bc272d8a21740a2e78a66cba772db3250dbf364365b39ba73dca14f12af038dd7ab99d114677bbf64c7149fb693953074003cfa18fe9a2a0958c6a5267c6fb635cfb5a2fd1ab5ae5b38ddda103a32cadf322cdda179f004a3a13e5990debebb53d947aa1e1efda44015bf5ed77594b4f977b48b3c235e83c0eaa061b5a1dcede695c68aea23af2e97ceee87075a61b2eb497b08c0cd8f1db6019c315e0dfaee4639555ebb98006397141f54ba476b3ac7d341c9222023820e10cd763c3183630c5b19ae024c63e85414872ea3ebeb0987d3059ea14d3dc52bb184c99a7e920723988cc9d2dde721ae8fbecaa84709405216475ac823c6139489aa2479549b8f8bbc1031ad05df1fa9f330b7d33bbe293be09b2e21889250c2606ae5de6f14b0ec21deae5d61cfc5e4d11afb415f2f47ddcbec921b5aacd9ee089b32e43cdede2791d0db371d0239d83a1646f864f962253326179ee3a52bb989b9fc6dd995cd062793d49136687d95c3092b1befddaf63bd6654a79f891370e170c53fe3f1bac4105bfca66d353aa4b6a5523fd556352b4b3621fab943d5a7b1480b5162420c409568a74d2aff9bcc78045cfd6afa47ff2d822ebddcd8f0cf4422fc064f37311f4d9cd301a8e499a05ea57fb6e8bab65e136fb8e4fabc392aa88171f496dc470d44278ce01479820c2981f8b92e072d9541ecc93757e6bffab7de55464c81565adc0e8ae829aa994a7cc0479431240bb3561a0ee20a42fe43a0cbc3485425d8086553a508559e57b5f20981f25da1da0e32a559b7add683ab1ec8bd330cc33a2e358c0c643152e6f9492c4374797bfda145a0cb164c280e19298514f6a07c0ea7c2eb8a9057b78d7cafed8e57589a54f9371b81c8dee70bf4f0945a593006a4a701b18b6c19f1e1197232a24e73a185f823f22a8bd9868e75745ba8549fec9709b90ad1868ff2f154415d73982332c42af2749356aa0bc2ed45fc88c8a0f85cad04a81f50e394e44e4663a6a89286a6060ed7a6d0aa27ccbaa694ebba71bd4ab7527a0e6961333f45018a08325aeb8f92b8271888e8ceae17a8705cbb8eb213bfd5d5a83df8e6a55a69727612119daa203a662797af41915d5249e4e0ed8e657974064ae840a602b317b068c1f52e7f73cc0ab858520cb361c3373b46149bccdce2a07a943228b85768ead919d0e2f06405985b1636e4c3bce2a31cc3a54cd944bb9cae6bb54651d48f46e585b65f5b2a3650cd088b024a76e1b2f72d122cebade2c978889f468f8e0e355a37ef419cbd8221d552edfac258fa79998574d4a39d2bd23dc65d15266d4e8d8b678fd8904dc266663a4266bfd332905fab1e87d2a29bc1601ce4b2ff9898d81840267433df2415a92b03c2bf39be5c89dcc96874b1d3b951736f19c66502a52e92059847f1531ea8ccb1b6bf7c607ec5b7a9c0671a5055aa57e9624cd84c8496988a93dbafd88a1fa6ea15b12aaeebf5d1b7226dc99cb1d26071609e0c0dfe3aef00ccd7644c170bd340078b039fa6c206147655b6375bd91480a472af445be74935aad12cc41098bab334d5aa6b6e4298cf0b4a17208ad963fcde817a0c22604544ecd5d79ea4dd7fe27c6ef97454819360c6b08b15855a27f8131a1835345da04169074d8490ac849712b40098d8e878dc61ad347f19a8fd54e75632b14776325e2c750e21c4a442a358c83b855b38c2bea1a6ca12ac5082bf00827c12702fa1212af72f8e6f182998f0a68da4ade8cbc0d4eb7d150a769c9cf6b1b2eadae93dd932ca70e599089408f56d1b7dae3b0a0b5b0a4cc174878fd73c7548598852351787699ea69e6e08e617ecb3e341030711bdd1e94e165fb04eaa4cf943a1ca703229521695bc52a39378eb16f1c3fe92f69e51c377dd3d2268c013113b1f07391b609486a3dfa81cea6159254daf8a6747c9f7499e2668285030ca34be8432d35517457e234cc15acba02b903c9ea4a4035822ecdc32d34924c3e01bfa7181cb1cf3926505b7cc15e06da3bbc1d244f990591a7363c9e197789f7123a742984747b0d7fc029265cb2448a5888024b132a27879aca645198d6fd3a3937107f035074306c81908ca7af69e3320ed07f21217ebf30c747cf1888fcc9abd08239a2fb9cd2f5225e99344f1a83beead6baec88eb10b72c48c39d0942958393deef3e8480097d6aae04d2060958075582bb430b0091cca0993d35a0d7cf1076d51b384d4b444daf25d7a1b6be3c427c3a36cddd6f13f16ccf77129053b29667cf7b1eb444310e85b052bea5133812729c2e6a79201a0d4c60dca1e89f67223b4a9cc3b40e22d8488d66e2555bbe26db46141873367c1e00478b7e96504e5a45e6910f954d96b38d2d010bdd791a025abfa63f69ca7660e020b48d8c5a134ff12d0522ad759a9665afc4c009cdacec5769350a60eb6840271b6c930d348afc098bdcd1093bf674a925abcc806171b5bea6488a758c3522ac96fe40125d84b590a7c6391a86900f57d580a168895b597f8f20181fe5a774362181508ce294aa26e62f9f85f6934ce04612f62b4e53cb7496ef80b87ac97316406fb1ad0d39ab8e108b1444ca9a4647ebe3c720f237fe81abe98772520b19b4d65229664d3f5807fc48bf400f38449a7e9838d7593a173fafc78c327b8c1cf332ed57b27e4bc8a2377b91c5a36e25757e1e6dde547d8a23b552c580ac5a1dd5393924ca45abe2b0e7263ea20780887a69d33ff8152af981f957f58201a91a5ca6e70f2d206dc928407dec176874a959635e67c0a90948deb15c13bfccc07eda2d14020a57d8973d2eb91981fdf92fd1fb51e811ba287a82d9175c02de4fa76379c00102718f7c4cc0cd3ca20628399265be20e96190eece453d3d096160030999caf8297774c980e6bf0bca4d06738ec1d65d76ad576d61807ea344041faebf9aeebe25ff7d1a9958dba6fe21f429558002e0886acba0ea0b75d1802085ca49109848acb7b35737cdfa819ac93de8f432cb670b66c0453c637b61c9354e280c4d553f959d8bb109c4a67e9dc4b8c9e2a7aecec5dce46295da02820028e2b7376347cc66b3b985a8f5ee734c9e9fd4f6c4184c31e98156bed6f931988052bfae2db739f29a267e525cd13c546377974bc51fc537e614bfcd5b66310ab3f269a7683c743054e7e529c56b73a6776372ed5003c7fe2032ea9440edec39bceccb64d3a8c95fe8ab776e514eefe6753b88276553c09483ea0d2653922e6215d099543cd6ef3e5ac96347bd3aa690d80c94375fd95b13d84334f681ce46d5e879ada946dca2c0faf535547ffc09dc841813833cb66461e3945fe103adc26be4523e70231bea111710c2fd4e27306d706d38e40d82f06096c0854d2d29b6a8caad22f0a9aae1d583d2325f96d04ddde104c88d132985ee6470d9fbeb93154906747590bb838f08f00a9fc15e4bac88484351a425de90aa5e7d941778d233bac72029ad2fe2d6bdb185cf070b912f814abfc099242736d2119f9ea0f6d30fd56ef1e76db57e5fff18feda4743e40f3e2a5f2da21698b548abd5ea17a4d6975bbcab8e32b7e4ae8d13f028d49d873ca69ec0914a485f99b3a1fb4716cc7128135647b2010f161bde67b0564d956ebbb2b15c041c208db472e89d80880c895f6df90b66e80a069f3481bab7a0f4f5c4d4b113f3bd6595fd367b1898784400dcbf8290f1806de1b4f6ee3f9e7de132a5e640a0f4ba483080f2ac54e9bf1649b3d24eabafbca975e483b3f4c6bf66a24e8f5b53211e6d1d6ef3a19d761368c9afd6dc1d12f7611593f403a24896709e5738da16ab2b2540eb87c03f6860028221e6af71c63dc0cf757d1b84a6d4a2e211e2e36650c19e78a33f869d2cfed01db84cfac0f4a34711e86c05053225b5bbcb26a779739f43df730f2e32f8366a4e02764487bfa86bd0c2256afbba7d867efebecf7d7f5e98076e90d56304f7f610aebbb04f27f09de99116d1abae658b2c65c37aecedb340988f3197a57104b1bcf4a0e791c8fd5a7d872768a19a1702bb120ddffd0faa024cebbd52291f40b0a3823ddf7b3ae3813b74c80e4f6a1ec3240ef5eba895e126169b8a9bd295df1b9852b3864e815a8d9d1f365d50f57fadbbd3c1d4f361a64b7516efa597f8bb7e2ed0f7ed5030e47351fe7e8cba76aaa10202ac1eaad185c4002352ce779736fcb9931a7653b0f1df27b5e8d28406aa978c53d971aaba4ee18606b9ddf8e1d557fe3c1b568761440ff1cd2dc11d6417f9cf9a15843a409e0d49b51c837082e1be8b30120efa9354f84be366d7b33a6cfe678b3f6b8e13e842dfcf1e765e85e148ea9789b67cfb83971e3ee2aeaee426098397e5abe8ef24fde6c8f02d7ae7ed93c0546bc836cab32c7db000ebaa7f985d7cdb1c2b4d9dd3aad2606b88855bcb2f22791783d108d0748bdfd7fde9e77e93acfb98bd0a6ef5cbe93523522e5562b2629a984eef933c1b060dc59ae757f73049bd87c9bd7875ae2ed78b19857ea4e34c1bfb1d7944bf324e72fe0b024f1c8f41471719e8178d5b5db3e1825e1fe0e4d2efeed44a5a05565bba3a95d477a9cbb96a7fbd1685bd7a8412c7bb81b3232aaf795ae5a208e5da0a0f276dda45aba5e1927cdd3f8e8c8c228d7fd7cad7a93351184fe03caa7ed7290c2e549df094f4812a555bba99fac7102355eb1371c747f2d42fd1e6efc0b17c78abc65203da0dcb5d6c9c157df68fdfad1ee7c558dcec8093cd4cd1f12e901415d9f5a9f3b6ccb32f01fb73e838a9ef50d820b5a1900a89717bb6719ece5da4bf57b5683592a407e2a2c3322d002734539db62cdd78bbb799ee2695a0b2ce7de48adc52316f60f6ed28cbbf62243ef6988d5be4f0135d99bc91837a163dea0f2db42abd4490ea8cdcb5819e5dd0fa79d30c06a5772ceca157872b51c4af637d0db65f33d45113e5bdceca2584b45c057bc47e7324cf84cee9dbf11ab3069e682c676b40a0d714c8753e12f52a751d454533bb926434d12d9db91a8e2f2d16002c0044bee52c5378948087ab83d72d0214fd100399dbc1ffd728c0b50b04459b3fd056122079ac21bab2a3cab6c21a87526f5cf178eb8ce3bebf15511eba32660567dcf1ce57d17b95ce15153eac8235a6e07a7bb7d5887a376a924c89ba2d1ee598a338f94259d21bef5e46d6adb1fe294e8c1cce7955ddf81df6c9790377a653e494b3a6d41aa0effc9b72414ff83b9d59cb813951c168b8c89db45925a849d33d28d04cb095b8a0dbe3cb8d8e453c3d4eb0f83c78beba1cb747695e22f96f9c552077e9856796f07c7beabd70a1c7811d67a98d3a1a06a2a5f53cdc12beeb348e9447c8b9c020eece5d66f57f3ec10e4da8e4063e26ce47b70744b14264e63c5c3d9b0489583e6479a32f67cdaf87279d602b0b88ee17a019337ef9f4f0b1b60a021b9485a96498fbb78418a0a14d3e634acd662977160501a4debb48236ea803c6367ced697dd8f2eb4fa46f8b45a3d7ce6d8169054aba32f20afc944c5c41650c7b2f5882f8750785f56dc98b731c5ab679cf07d389841b0d022c976cf198f07c0f010e6faf1df94a9f5c1b8d1b44f807695fa4b79e7d078d7883ed872cb96e6fc78d1247d44dcd5520bc53c07dec393d1c514cc9cbfd142562a516ded2efd51639b92873911b4e1e0d43ec57b68dbd4be0ea1f793270ddcd0eea72667d03017419076de2ba8eff021db18861885f11638138862008df54ee9730a1432af9e3bd2a70289c438f4a8dda84f8e5fbf4685dc8668f08c7859cf1d1f813a94a2b9bea14d6f7026674069555404b5add1d01ff2cb7727c7a119bcae25386c787f7cb6cee70cb3c6ea541d037a9b4d95cbf3e1f5b9a81f770ae5f2085e43c6345170a5b2c8f9b96337a1140a985ccd02c82a8f35b3aff31e1fea10d7ff436cc65e72497e7b78d7e0be414d19720aca23825caea65c7f0988a235db9df0bf21102711583cbfb3285ee20f704e63470083d6782bff04d3efcda273c619fe08753edfeabb6bc48e48166770ed717f02f81e3dad4e3f33e5243c91e0d00dcb2ed58a17bd48f4c591757912013b9b8f8117af04f563bb85425b7c0a6876986dec5c6f189749600c093b93fe7ec989fa704ac5bef3dff54d8753c16f843d45e68ec9c66079649300f589619d9b455d7c4bbd2797a415f5033b43afe1beaa19415c5133ce77299ec3cc86092f5907eef26600a0b08b9337ceecf2ff3c1c0f195dc18abcb89fccf327ae0b1da24832bc8c25d89b5bf02675da6d5f3d23e309143b53862a75e1bfd22cb4267078293f6660946877a5eec66820b70c56a7fcbfc754ddc1aa80f12f5ff738bf44ebfc976496f299e900bed403e74fea25d9386cb4bed4dfbd39f77d3b7e9cee4ba932fa709641bb86d7aeb88ef00f9e9bf574945691514c2256d080762118afe10d9ce3fdcf909cfbdb5926eb858a8024d60ca80d13077dc08debf44790d23fedff8c86926807818c38b987e03a9f6449076b8826e9ddd53b314bc9e386dbd7b4507d12fc5d384ef4069424cef8efc610029ee93afcc74dfcc7d477e38c8f61dd0819ad502323b99ed89e13db8ff7864ed7199ec66fa2330718ab829c3bdd06aef761bc1ef2a25b3fe83de4384f15af2b13d6906c826a0b5eb372c8ce13e50c5bf256fa709acee26846edf4fc4c1a88ab1bc859dbcfca2f3e5df63936ee6b30ad57562dcfa772de3198fcba5e71acdfca6ee82560870c0b24fff9e1bffbaf62696e4af83eb2fb8c7bdb17ee77a1edce66fc4592d708e963b7d02b3b28e9b8410981ef901140fa34af5c663a52146e63d6ba25ff20a3062716b5e7d4f63948e3524e54083776301a1d460fa4477716ed4cfa99eb3fbb99bc16238e0df03db3a441fd0ab9097b45a1104463c2cb5346e6c5a85e8e35e03b1de5fd26ab26ef4b2fdf268d48103dc084c7a8aa03d1ca4f7fd6f2c227388faf916f943c9db3d6174618240dbab174c13990986f27cda070780dfcc34b710e9c75b955ff3cf88bcf05054bda29b7f0ea04f0f7257341cef005e24d5428bdebc2fe3c9d5bffa4ded301c8a3dd7796a08600a2dcb910af1a304d5f1fed10211d94b163b8b1613238749e79d73e5f0f72d4bc65fa4059bb7c788cc17a7265ae8d663849a4f7b389049d38f2501934e7669ab56fa568b57ad2c8da88fbe648f3c4dd8841c65699819cf724924b77d8d9990e6b7d0d66371f3c4ccc4bc46af3283a4baf10711bad70be2c35b83928bd3eaf51259f69233942b64ffc92d9f2a4bd5b3dfd1848362ddd742307cb075e1f0810dbc412a9df5f17eb52c36d559490bdeb446df0644ee1ed9d515d6bfee56c8947a138d508431ef4ae47874745bac83f0cfa0e5a61fbdeb2a1aff8b888dca79fc3597e3f650f39fe12e8cd8283fb48c57b903db56a1ee3583955073bc98d8129c936fd080e6bb98d0a8a2545f75460630d96cf89f78cb3e04d4a13cc553eea7992fc8ac0c295eaebead64dd5a77a353be02672ed1f1e5662ed80a7cab4afa259cd315e13da9afaa64cbfeabbc5cbc2986b467ec0dfb533cc0cc5601417ec734cbcde05be2ec80c8b3029e0b1911fdd9b593603af1b6fdd5a4368fe063d3aa5889a24faad3623d5e26127897a0c4ba70443e6e9a97be8c95d5078b902edda86802900f7ea1012b8a19742d23006dfd8af7828bb3b58958a1d267a9abc28d5caa98b33b2dd2ade2c6dc7ac56a568c29fad0abfe14a8c8269a113f8baf464fcded1e0ee57c3f4cffdfe74ab511e4f9d6235a59451f1b31920e3849e3e58f3d35104ae79dfa78a2322f0a6d58fa60dbf5675d649b90757a40fdb50f2198a259ac6f9033b3ebd4053f93d2d02085ed2865a4582463e7edeea91186b02bfd5bb6b06e9818190b07fdbb8f9569238a0f35d8d3e90eff6066fd54d557e0283d1c6e1a1b3912a3545c88986dcc562bb6391420b7fb1e917bb03eaf2262712962fc1ba8e82bd23f56e27f802453e448a89038405284b8ee7a89e3961adf32acfea53b305f584ed19bae39acca3aba58db044b8c488a1e96af71bc6a72a4d0a80948eb5f58e64a08e0103411fd0490017dc6b975c7cca034534b84bd2f2e036c3d1fdbd41332fbed63f18bb2fc90356c014a04b8d50780ae81e481f1d481bb2392fe9bbe7d285acdfd2b3e4241946f41ce15dd29dc4a87f48856172dbbaa4d0a78e5fd88587c7c155d38609c6e5c3621582fc4afc31908a26b313aa7e1f2d0e06d210e00eefe0b9a55ebf5a4a3146a7faeb7eb50a91ed2fa7667e471d6b2ca63b29733e31995711825216a6fe515a96d7a63b33e4eb125ca0fcfe1dc5485fb278c3d22f6cbd874dfa8a7ae410e0f6255bf0b4716ad556c9e1589798ea209412e36d43764cddb739695fd310f4d4d54b9cfbfaba1aa3e139e258ad13c9a716c008f162ca4d37917a88f72962319cb04466730d01fe08082828b9536e639adb8d8b36c2aefd50084606c89ed5dcaf35e346d651dcab4927fd09d8a18d56c3e5919ac82473c8540c5c313bd09226190102cebf556b2287f3daa256935de3c451b7f55598dff4a889f44fad34c830d438f2f0181873279aace587ff03768db31916e8fa0dd9350e8a325c80960523dd8b271e7f54a2154822e7a390ef42b31fd4b55026aaeb4a389887c14b1f4dcd469d99fe4f5cad26243c54d77b5be7b797b3ed7bfb62c78d8c570f897c5b02da9407c9c20e4ec49efdd48f1ff7d2e14e7381acef777418949b4f91c88fedd6b35273b10a3d04f49c05d5a7f3ed07e6a8dcc735ea4d8a4efbe33b09e474d35a7e35a88d8f7438620c9571145d950f2c8e3cbaa7e0e4a19ba443217fecf35f8937ea615de6cc93e01891e02329e5b8cce7eccb6b6fc7b131bb4ebd42a6f38740a3e4ee64898be16b0532c2f71cb3f53fc8c1982b7a0b91c7086eb47959be5f56f9c45ece67c11277837335d161f9cac7a4afbf21e6a8e80805964a2010a4405465d300ad2a20ea516e79b491f6f039562aa6ceb54145c9100856405255dc1cff179f6c5c505836e45bbc0323c1c2ca8d2e7e63b0f1a8148d54220588a41ddd2359ade796c17cc95c7f24e286a6be93e365c6b0b3455db5d42f6de5b4a29530f04390430046f33bd034c9ccaab7d3d5821870737b47d375330c1d9feab91f4058987b937c685aef4dccaad9c810b9db6d9cc39ef9a5b8e23feb1e53e9ab7475bdb7a6badb5d6de50c8ee2e4da7e5d2f07db2bd77845550cdbccc33a2b7f1e7de0dae09b3cbd72bb7722b1fe0035abd4092144591e76a7022021319d4ae0639efff23c13b54ce8fa7b5f65fd8acc33e398fdfe6ddedc98fd1ecfc590aef601b48263ec52349f03a11fc8a478abd8af7138fe2912678d9075d15a7acb562c5e7bc8c159ff3adcf51f1386811ceabf8a29c5ff147a90cc5e7bc0cd9e33c8acf799d53d64a91e2755e468ad7f9d6eba045512d5486ce3f5a246b7d4ce78b642d7448c6ffa9ff448b8ace3fd13f4a53fc51fa9ee2e0a09ee6a018c57964f37994a6383dd5393d959d47397769b9821c5a44dbdc3597865fcd5264d085063430e3cfbddbf3135195c516bf7499ae57072e6b477f16356ff9780a6b7d78b64e11786178ea1bf4e6837089d37cd8a99a80faebc30dc6943b088be7f8af2be48f41d7d5cbbc1d1807330fe56d7c811bb77e03a0c6241984332fff6e8f6f1c7ecb5bdebb347c53810eed277e82c7b1c7123cc64ab809c5075d9cdf9eb08d5f2ff2df31e3c64868d5b17a57b07f985bb60f5af66c9df78a964bc30f85f32fa0d0858c7cbbc7dfdd1e31c707e7ea50a89cc78fe2b4a70d5a9d95e0b4c0084eabd9e8c8b3c653cb39ed7a77f08b67d16995ee0e461d2b834bc30fb341e3153f56c27f83f82f963e825d0a98c86fbd0cf25b6fbfd57a57d647a9ab3caf550321e90704611997966b41395b4bae28a365f63d28bf6d3c1f20e3d272ae05e5b7e5afe5ffc148d4787e6e38304ba97a8b5bdcb218785b72bbb66bd72cb89b825d667c6fb62a94a509f2f6e06b02d9f05eebfe21bef7de7bef252f49c662b18db17b053c48fb14788b9b9c097bda2eed7ebe3da150e8190b69102587b6bbad03792866bc0b7779278a236e915a6b5aebb491bb9d4d936fc3bb9dadd106f0680c8575f9687bc2fa907f51f22daa6ad07ab5c7f52a01f67d3500fbbeaa02fb6e67c33b2b8ca34d74b90b675f9befdcd77ab4c5c81ba3a2cd815cb69d2d3c12ef4b4906027e0bb655afdb6b73cef8e4d946f7e85e6be6e24c66bb471c665c966798d28035a6a1c8c294389ebe93ff6667670594302738477095b0c048e6a9ec82068d4586a494c52389b128becde2759a98818ddf8a1bdb2bbe3ac058a339d3898d2ef3a655be4ad84d01d404e0982850085cdf09df75ea8d7353d274a1d3d8c50c1a7780cdb03646c546c7a5fd4c9a2c663423573bb65a237157482d188a48a208229ccce499deddf13177873c63e6ee903d7489ed1c28a28c53113c9d18995dfc51c28b901b1d6e1acb0bb8c29ee83073374f3cca1d74af1f101e2e3356e66f05d2e2612dd1042177b8b9c4b03002a55a5b7c88402b120a5368a609ef0425d86fed12e65ffaf9c3df511ffe3e666565656deb81ef1efe4c2e34b659d7755bf48a7f6b4c8961ec6c142ada68119ef8bff0dfdca8256afe853dec41d0a80afa8b8e52fda5f872e1c2e2cb6efe85aa20ecd79337377f83b1083cfd52fb85aa26386fcf100a5f35f5fb6efd0b04ad1fe928d52812cec35054287cfcadd2bf8ce8cfa04a3c4e0914877e24180c0683c1603098d65a6bad3fe927d56fa46130180c06837dd24f0a7bf145dfbff7de27d7d275d9d7c292106f5092d8e716d92c385c20931ab9971f413ae01fb8a1899633a9917b791293ab20cbef09643547c2e07018354c9aaa9252b04aef89c11069199a45f68a0b99d4c80679d08043089c826319237ed09150449ad27bcaaad2b28565c82f2d5dc135c1f49e322ca9ab7161f7338d4435e1a5f79401d3f2752417457763e2d336e961c88fb4845917b0aca452230d66d021789e2935af8610582590fcf0628563e385285c8e894f1b25c798a6f49e2ab6a4a5095e56935c043f76e84e68f9b55925f811c9c54c7c7a0d392bb8b49cc0c4a73de2fb61292d5198f8bc310493f0d27b5690c5eea08313a9b4d431f1e93874615a4acb1451495498f8f4304e88dcd27bcac0a4e50a139f452ba8cc60951ab90d3b4c812223931aa1507a139f37cb902374a7894f0ca4e9cc12da23881c9002139fd7071a22b8f49ee799b4087b200a8f1b40901a6970858aa9c80e49f2a54627d0a418c5e76d81aac7522a802b0409285d7a4f1999d4e85a51cd58e2bcc085b4c8a9b6e0a8911a8d3caaa4e4bdc03ea98508294a522371aa978e5e84b831951a8d38b0905e709496d7244f598b44c9744465218cdf0201a943185908e41b8963d674fc164a9226796afcea40cc6288ea8c31f2c467ec24f1cead014bf04b6a848548c73f4a2fb88f73fc8cf6ea20dbd0668b51b367a6296f80062a989616c70dddecd262a28d9d255a48c24a45b1a814221533765d1427b7343c4b21d21ba5f459bed688ed1f74fd84baf9dd1efc223cd1265c2c2d2f0588fb3eb9cbf0459a3218e38b62565616d61e5128f2fd6574b1d2a8fc72915f0cf3d32841f52d8b11defcd4947e7b64f8edcb301a8346fb236b5994e575220c78d08e77de5f31c26dd19bdfa5f95fa8d2671793768c05e28c7d4272b7e3f17e3f7155497115579bad2e0d67a0b7c0f8b18d4bc3214ae6f00e8e41abd8c6c678071ee2d67ec4d2f6c1eb2c31fea03bfa1d3d8b18eb74a67d498045072b30814bc38f7ad16604535ae509b2d8a27e2dca737beee3918867f79cddb367cfee8e532835f6f9b2fd45d4dd02d5a9f4aac9978d1f628c711489cac61f519cffde7befbd9ff493de472a721581418a901f3378b9a54519d578c7e69c73ce395f2d8aa2288aa27877548c31c6187fd24f8a51a4a36b145e57905287031e073c0e78ad291cf02a48d2f6d5eceeeeeeee37641c661267bc54e6cfb76de2d2c208eccbd30ec6e9b65513dbaf52235bf8f99c5ad8d7de2817c0a606cdd6f6bd3e9fde429e8684c9a12f4d444df8102f496118eabb637fc8161bf95f80e0ee98d8ee1b026597db7d43705bd5df46cdcc84994e2e8d1913662f88b83d26fcec1e7213e10d03e7898b8f6ddfa2b21836a3447663f45a1f4f931fd309c244e9ced2044962639626c853d22c4d866df705f91144c7566b3c293ad2796a3f4d26c651fba9f19817034620e1a1bb2a3245c9d192324e74c8a1a6d7831121376e84fc3071dc24c1d399f45027f64d59c0047f4d45b4f981c2941a60d42c5969a1cd1139042d5329f6458441b6ecae73d2b226c9491aa433af31459c884162c80a577e188718cd1bb1588ca746e2ed3e2047c478615468f30f0f56ce799606e7ab9d73ceb3349988adceb015912a3c796a486425e941cd0ea75c02764a549072958398aa29d18b8e9994bff69373c6f93dcbce35e00b06cfc813db7d403cb05bdb7d40783907057c4d385f902966062098f975536ee71e1369e7a7e1daedf117417296b3553518eb39f880e0f040986cd7761f90a7da9519ebee2d46d2d7137b22901ddb63611886e17f00429b1dbe6962873fad3a306f5af8e17f97ed1ffe2cacb155163b7c8cc3bb3da669903b635114451167db2e0e84b34351f4bfe22c446778900cf3c207bddd07c46963f4cb1a012cb8fa21d07c408d0f395f36978db7c00f7402167295d12607ca4dfe65ab36a341f7450f1a6737590c863890eff0e317ad4f084c487cc7f684c0c4c469bed51b2a6da76cdf2a4e084c37a7590c42607af20a7cdf4c2b5aa26cbb7bc18376df8f2b3ea635be1f517c3eb4f8987adbee36fe126677f8d7bdc39702ec6ee7570cbb4568b66d6c219b655f31ec16d3ee2c0678d5b1ed6fa11ce8046b635b286fe10f740212241ba342d6ee1ce884fcee2df0e32d5c1cc8eebc855b2e5db003615488dcb946e9968cc67f7d3ea27c3e40e9d7ad12b7c06f074a9f5dd9257fdc34218aef2eba189b89ef3af5ddb9df3ac9bb739f1cb38fa7ed1cd83c6b754bdf9e4bbfe50c36a28668d8ed7aa2157b5471160a768f2f14b4ae9b28e7545d2f64b7ebc5d1103ee2ef280cfe4ece20d5fcaebfa72ae4c1d16ea1360fcf1930c8c73fe3ca62908fff05f97a713db8afb63ea3a46ff2bc40e92ff2f349e38c61c797b576f8f794b5500fc2275fbd976888c68a8d9fc876708114761e72ddbace3889f21051fefb3466645426e43a15855d82d006fb9e34ca0d43af4411ec8be20f4f75c60e513081800d1a70940ee1171ab3b2ee43d92f61377f2359ba2cddba6e8b627119d91bb250665131d6baae5ba521131ab3ee9fb085eccea88a515b7e6c5159b617e7d08aaebba3cde4255b59bbc82fb5ebccb7af7b6333ec922a91ceba04a93e0ecef9fbf987ac89fdc11d721dfefb43775d878822d81f6094c8ee19b2f0f1a3435616a21ee4c74332fbe6baae9bfc20a36a04ec5665f64dd84477e8ae328bc268ad4443795dd7bd89d40bec755db72e5ad775139dd819558f52d8328cc2c84f43826d7fc645035356315805a10475564eac724a72545654acaa784e78352839519a023e01f676b95d103705f7452a27f59bf2ebad52562ec1e0961d925d103926b99e4e4a776372db3dd9e9764b76ba2449b0725868b064c0babadda870b89d1215a51e8f0aaf77c3dd7a6b6ead6109cad212d4921412292a2919a47a3a28ba1c951c151009b0f714ac02e6805f561956aa9b925b0f970457f583f29b2108ac275841602dc1aa5ab27279926bda295951ba828bc2ed7abfa89f1213a531ba281d152f069eee57e5d7538a41a9e724178c0a62f1216dac6b4a0e61e5d6d34dd17d5991ac37dcd5c7539ce02d865b2e4a8e2a2815ec5929b1a2c241e1aa764d76535252a4aea0e0bee470b92a26565c703c2aa92552c124c12cb0ab254d5b7056bba8a5295e145e550cb929a92752533fa81f55b04a90068d26382578052785ab9202a49ab23485ab82e3f293fa7d518aa2b45465a9f764ed356972554567834a06a184d75b02bc296c602765d76b2245e5e4a663c2eb492d01650076e9f10dbb8a625585a4c9563535f59a9a3469d1344fc7ac4dd6a92a2ab72dba24ba1ab4ef9e0cbb2bda770f4a57a544894a0a9617d231f07ddfe540d6c7d3bbd59cab26c029314deb5669fbc674c40469da97877c181cc819bd341b8e3946b30c48d2e1ab3a2169959442185274267d4996c4172ada23ca8020b41adb37bfb8267cdaed416941389f6d683d348c617cd1beab4abf631e9803093f788c37021a1f3ca61b61071d093d8c00846e84323a00493043e391406606011e3c36825f5b83801a2349507fe32b811c7863f47d00e8402b43fb41dfafcdcc08a0077dbf360342df9ff99079d0f7673ba021adcc3fa3efcfc8640de8366dbbcf4a6ec3006a01dc9fad07febc2f2a8b61d10cc3dab7f5b83914b1cdc6388e466a88f862648c2f09d5f8244d0e4d3f2c46e0aed27134e2dbe3b8c21ec7b165a236157eec9b267462db7d4fbf275e92288a229428ce445414455114c57c6939c7b6f8fac811d2dc6163d2bed5ec435e5c2e9711a1842d5816251de93cb59f28d17d3f48b9d22507114e9678647c008343182a401f4f4be3539013a68efbc4d4e51d3c4deac4fea9c6cd1120622d148bd1554a1ce9a28f3471c5786aa48924c61b41e03cb59f234a320c407438469bc553c76c3c60e0b1551e1b0b7adcee83e1c656b56641d3db7d37365ba55d164a9fe9c4de889a6ce4aa85b13099d9d9081aa61e98dcca20f9b86d40870f72bbef46250ce2c0665bd279bbef06e5d6e4a6c486cdc7b9dd77cb51a4cd566b3c203090a487841430526c6073d403e70295115350494618e1e5c8d91639a2d5a50812fb1611b35d362044a1ed0749d208af0e233a18be1cd1e13a7253d2d001d6979c931b5790b0920196d4d49a1e50567418c9ca475420b3066c4c4578b719b6b9dd770ba204975f9dff052d7cc7dacce2fab83e7040efae40b87c448ed8aa6b19b355e7ddd28cad7dd9ebd32cf693a426d5b4f96933ab5dd2f38863a4902d8a76dda2f8352da226d010e073e61725c2c2e5c2d3a1cd2ffc9ccc10d9a142124494922082a442122f10b1c7edbe17ac42d105ab21453805d98171e8a46387be341b63e394420e362e60e160e314e5f49485f039f5b6a344d7005743dcb04a7ae5d0c6bee933aa4eb5ed90a68e33a8246c58ad6ad2315433122000005316002020100e870322711c0a134992d307140009699638584c2813c7027130240e84610885500c040000030000c330008560140564240722b843e779087fb32787653708ca6b95c61dfa37e4572df62fcad75b96982623cb59f4ebb33c41f6310d074b16f32f2bc57d51bbacf755943c39049e8a7f2953bf0c22aeb324e3e233998cbdf34199a595285eb314df21e004f15fd33dc8f5fdb64c8d1626c96159f54d3db9923d18167a40573298a1fb53f3df412cfad347cdd28a93fff3d4ccea9ed5b0b0afefbf0954e3f13d415e4d1fafdc1b06cb11f6fb954b4cd3c802867ffb452943c82718f9343d8b24e0fd174e7e0a32b6293e0e5596bc33f52f7b36d5f63d2c97804e090e8615ab006dfabda22cddfe9329014b3febb2ac8ad3bee6a9286f4f342c2de0fb5f89d4eaf85487a59f9cf8b352df8aaa72df5f953df7b9ff858abd2afb1ea5640843ff5df24849254e890b9de5545cfe25d9754dda3e7e69fb434fd8dfa772ab4669224e0e3cd3fa833e0d02a5356679294eff568a6e08e8d1dd4796f882034b1be6ffb9981a079bca6589599af89cafd42c77eecd72d3177c6529224dfb7e4a0487473d5834aef04b4d55cc89284df6902a96d7c0cc87d92956df5f776210fc9bd20b14cb01afea214e387eb664efc759f26ee7af942c525196054f2d0592db3f4d1d4b2d53f913a0d253ec4168ae9e6f551b229f784b5856c7c52397f89091a5957ffda2944c436dffc7bf3235171b0768c192e3683edaa4c2e5b1ebc49a33c1aff400c192cc2afbd492122eb71f968b12aefb898753ea1f542b49a280358b843de7cf4bba1ff215ef7f6ae98816be4333f866dea43ba982a5fc40e737a672877a8650bca6f4101d58f4dddf1fe5947dcd045089e58508f56b4bfb1cda19207d6a9c620847e8b088ea53ffac644f2458bc832ddff3a761534d78b2cd89d12f4a4cff81a5957ffd294ecbc2bcfbc4207b552504502927479f2bf1f50796dfe9c72b9ace1c227ffa7da5d23611277bbf2643883929627ae1d2cd87f6ef71a57da0fc27f1df2f95e0906e12faf570a2b0f4d18965ce77bf2c615a8f2cbce9d75f9698f2018b07f1e717a5d23c04bcbfcf0a4aa5fe99204f81f764099892a7940ea9a82a943c524f5710a59df490fea6e4e503e09cf8214b5a190ad8eccb95cabd688777fe6a49e29f6099752dbf26d498a286d32c27cbf5ec53f5d4e9c5277a27c87eb752e97bc0b96202240abaf0760d4e627336fe650958932c30cff5832377e8d77362cae9f00fd77265ffe224c199fe3f68273ca0b4c42c7b85dbe784d609f32f4e60fa2f5aa2f23910794a09e1f3b7d3f12f3ed53c7c39276a9f917ea597882cd572c9574b88f5cc4da7d7cf495cce075fb8d3ec8eb622f0e489de09e2dfedd3c28e7e967a83e253b58b589891258c8ceffe4a0963b9a6b53dcbc97013963bf0ee274bddae32e07b22dac9f1e74bc23734e2bf7f975fcac29c7b12ef33c117054b0127a27622f78ce48376751787c58950eb434a283e7a9cc8fe284acf3c76b5200ecf0b8d515e97772b2416b19fe438f1fcf352d9bfa281dd47933c22b0ea84e4d45ba4d7a752dde080306fd00a2b7a3c9e0271682d71e158fc3e427a56ba7db764ae7f1663e802f783fe7bd372344f333a3af75e860ecfb5c66fa04755b39db76e549460a1509e6c0320c0ba15f46fc59e57ff09ef21a24381ba8a6014126f1238ed9a8e8ae0f9c7011dedcaf32435ba2897824c9844e27a38da2781002fb7bc75ea71477af4b8c2bd806051c52528ae8fefaecc1544b60a267cf7450db55bd7ee57a81c6564a9d1da14a45eceb236b842588abc01ab081780992f1cac061c631b8dfabf334c8ae7d10ff1e7c9b9d775b39898848c04cfe54e83232593802d32417e61229a68bf85a5ef0fd113618856607db49354f4af7dd55dc891402704542931330344301f5b0a637b24db7fbdde49783c0a2db325eaeae6da4c5084c1f933720c21218a0b60e3591ea02d895611f13849a635ddfa94abdc7623e27125e3c8831a5e0d1c779a0a062fbd9a665899aa1bae1121083228d8e76ed7ecf5ca98361d2489eae229d6ae8505118cec79ac18ed9e0a875dd571c9ef160c2fa19d57e3e289bda81689e8dafe6888430f9d0a8ce20ff1af2d88cc0a6930e8795c54024000ad27e339f2c21aa280026041bc4f82ff4e0bc7d64d2cd322aa8a12d7bdb2d0329819dc55630c46d05ec6a39b1901e250f3e5325b27bcabf7d4531c0b19f7c466c580926932c4e6eb9e22a6cb11366936a6c6403b47369d417074cb6544078d25885264ac82d297c825b7367f9c8cfc07103ec28a274faca906719ec9a97ff06d2fa95e45255183e1059baa17d7070541d34cb071fbfec699b8474cf054515f7d5e99366215de4b6109d72108147375e33e385f406aeeccdeeed3eb8f8caa6ff1408df9a5b95bbab717dec1125db5c9544196d1c1bbd994e93e4083a4eaed719eb4bc3847fc6a2996344bbe6227398bb49c467a78bbb80cf44aa8b1c51d4033b7ed3628e314548eccd4f8d1ea394636a274427e99461295c39a628d0b85dbc0947b83926bdf75ec0482cbd3baf97aa384006e3a4f06a4ef18c58f2f2289206b6e84644db437c47056f817ae3803d2045d186f825aeeb309ca582963cc327a1ca27e34508720088d2365861fa42cec1fe90d2c6efca6d4ab1d10865b86f6090daa041114a3e0469040a35833cd1709ac16cca937e24a653d3d470ff8806f7f306a0bc12b55f50f5178d3a2800288ff37fc05ffd457cf8f6279c9adab372d473b36cb9f72ef0a457d69d7ad3720dbb39a1fc54e185af354443dbfd6cf050b6fd0723eeaf6ef0a3d59e8cc963458b6c68b0cf2282b673c53f18e20d0305a2bda3b18fe45d5ac750e162211894065bc3b462df762657375791c7f0c75352617a5e1c53e98e3097b75174a33cc9fc1eceb965193c47877507f1d69d82a181e87752f6894eb227d49f31848fc5d14090865287040f9f53df8ec5f9eb33d144d6e2b7e03f74f6d6dde7eb6c8c0c80ecf6849516d928e10329cc67b5c0d8b8d58968fb86f4df8d2c28ea6868e667aece09eb245afc88228fd3e696d56259b9bdbbef833cc8935c55616dd42157d46916b973b7709ffbb069325304bdfb343d699eff66fa4262328805b59ca1570125c9b187cdbcdc312b82c37a1205c9f00f7f2d990fdb384d29045a01c6459dc4256ead8ed31fe489d2f33ae2d8ace05e3cbdff63ec087e13a712a9048cc058bf55a34d603c7e5c9e075e4e82e2d941f6f82117b886232c1d7d25ab5c7ca779d0871671c72dc28f0d8eb80d7a012781daa68381189ce8c6c0d7b0950252ff8ff4ab3b36b8f2209c373265bb278b38111dc41f382b129d7e8de35c83528afc6622448d3e7bab954c5618ad29ad2a13bd1140d40908bc1078a69ee0137a3196344c402723618823cb930ed73d3f0aaa4561fb4ce07dadd8cc794b2b23000ee88130289075e24a5b78489ea781032615168107e3ee89e14acf51b737e34a36ca0ba5e889fa6832103191b8792be0bfc1e96ec265143fff49cb8c681a3ffd44d6fa26d0fda9b4e8cd7d8425af5ba8a5d57419b47b229a5b2b101870d1f60d7a98e943731ce97697fc09d255fde02fb9c866ae53fd1554531e644814c6a69a20b253d654ead2291576a6cc409b6f054fea5e77682a510c2e836dbcf2a98f6b78b37efbc3c30755f359576ad8d5a72cb7d6dc34024132e2bdbbbd86548ce6aa02a2ca817367bf2754742e0b11d94d5584e2370936437b9e5ff6cb54e2c016d24d81b350a41355d9ca88a90c6c7251937de6794bf1ff51a94e3298ebe8f3deac072d9ea126aeaa789dce7868aff4befe39d90b7523fa7d5d68062bd120fa5f39993eb42e6dd50997025012318e113c64a908cfb9c0205f13ce1746c5ccc1956c5850a0a3a5a33c5381fcc5fa20ddc2397d08964c8ef2ea19d01f6848d891aef00b5df097e9fc95cd5161cefb9b72aead440a76c24829cfa364bf5978180ae4fee2bd742222341869d4d6483a9cef6f35a2226b58fec6dfa4d7a99fdf7045ffd81888c9ecdf6c6ce3408439fb51d6bbbe0b4f9291a6d2972bbb3c1cf42e1096d943bd891714bfad7c51beb70ddc130bd946e5218af3f45fd68f11e6e174e561a8d97430bedeaace87605f507e10815fa087ccba71fac651e17eeb73b4d3018976767c959d693fad5cfd9ce5125fa3c3b23ad9d1d4539a94596adfd0c09b1c607a2a5eeae17cc15738cf291eb706fe496cf82d78b7e259c6e7cdea995813af04d3896b88f5ab0eff3ce6130b0bccb5b4606d1dcc79502d2c2cc1085fac047e02482d2c9e0084a443bdc9ce476f241cf8f1c8e2a4009dcc79e82874e6e1cb23e48a6a76691187a3103e512ffdbb2a2da140b5b74221a0dfce423cce133bec6e8419692932e619cb57478051a4aba8053f0b7a619265a52c477faf4721a559bbe72a374227fd864879fb06665a6080fe77acf0a3bb6fe5cb587847f2d7cc10bbebf8ed038240b27568b7ba3ab8af370a456571182205851ab200f738b07087bc027673068c955d13db8210f873f9eaa3a2d8de68e2449adf3232b92fa8d98548a549a2a7c61e6683ce4e3d93f0d32fec6cedfb21f89a4b61c75b599cf20a447ac05922d8d7ab0e63f9c6d13324a36c611fb9b8c851b6795996c6f72fa171951ab01a14b51d4a9e9fdf8a620687a0508502ceb7118cdac3c0d633a2fc445e90ab950fd1849eff3c7969373b1d9679ff1f8c1fd408cadf83c2e8cbdd4902330ee20d12359c128662b920735d17013eecfc34b7b33ce6daeca0fe03de5c0454cf51b8f1522d5c20439944226cac612984293dd909a3bba2d10b52ca71cb211b81784738d2dfcfa8191fb56d13c29c34188fa1cd7bd39b119da6ac795d3ccf3e8684d7acbe308daab8bcefc6cc2f4280c109e2ec8346ff89f36ba984240e16c2174bcb00d191e24a4a3fa83e7ee549ffd23011565c8661c9c12b608b8c87dc459e879e8b078b8637d7ab294c04fac64b05887ff4859217e11749a455d5207eff47a1a5e586cd59613e3b6a863aace67ad403fa7a5cad32b65a614fb753fcb8043423daf92daf820b1edbcc41a124a0ce9e0a31ab3c90744b7f565ed919af318d99e2ddfd79ad2b8ee70f717cd7adf10ea88a037ad1909c4744d595b0f4a73b9a238b7601a67b766b1be15320ee79a2e4a8ec18e08ad4f75460b07fdcac6c5d3d4d44e4a0919cce6c4e9c699a9f761306e25d422a5d2a0c9770aab47089c6d93e0f5de8ded7fe0ee2164741083ced707ea6ac1064be77ef42998fa8725875629d1a1f065008755d0311f4c20f36a8b5c12c37b0fc69c7db0f4c39718dd821fbd05688a5cf0706e81513c05cec989e22971e31cd015344a6647ca1035168f13637933ce7e9e1b835bd7bea7c922c36154f5284e4dee52273d650a0b337f4b15f8000d67110ac04fb8f4091fb0d6360360e6a176b54861a99526467e8c7225166a96eebde5600bf49c79c97433fc712d8c46f10b68013345b43ee280d63626ca66c0c56f9ea501b598c20139c2ee7dbf82477b76900444c42b6e1b13eb678ba00936b96765365602094a1c33f5148d26a3874ab906a04f874b00fa0b52006c328394e27c36bb47258c17c3a67a11aa03e96771fc20424889a79a4eb06e1cd17fe75a26b32f5bafe2dedada4028740a0aecbf037dff3e66aea5035656767586c8f1ad4b7f1630368855484a1d5605c38b550ae0665953a6d7ff5901b5675df866b6c5fd9d6d4df3db9516c60280939b10a62669e842115e5441d5da4c6f6dd07003de6250eb3322eb58403c3941c639d63ce52a57e706f53dd831a112f8d297c48cca46bae701e9e4520ad40586dd028371d0ba5b915a9be5467c4488cef4d34c137aec77e73190851c34dd1852d97036ae28ba6ea29c1bebb774d2be486711a84744b4432a0a86cb8fe0cf373bbb22f71e5db5594b4aed0ce5a1e966622279b0e7f8f95c364e0ccc729e7ebaa3aa3ff114ed1aa140b9d63ac2d916ae15cb61a01bec32a2e397d382577c003d4eb06216802864dd5e0843155fa7bf31b527df200af9441c704171e848d41c62e8ba37fb8a7b5327d0ace93f96e051458f23005279e5f4a6500f3e6acda0adb79a9abd82ebf06a93d25e24b2c0ab50b2428257a651951eac16b89c6745e9c8b25bfcb7388e6f171a80c1fa38743bf0d78973d0bef36474e94cce60d25cea1a8bcdd74647bf4943db307106f59cb4ba8d7f9d11bd93ca0d3d33cf5b54f816eede88c8e7e25bc9bcdcb4739853055c9f3277e197850b18e2d942e13e378efe9eafa79afcff2016d766f9070e5ae0639f2b05407e6a8cb1283513199112ec927b207440e1a522bff11ef9dcb499b2f31e2e679b4d4c66ca6fa4a37d81b85d73b50a59fa2ef95d53b1d360d8d77626179982e1c0c35c9c741764d5e106ac161b51691254bf4fd3714bb8fe524ddea5243edf344c8754d868693b8584c5de338048dd59c617edffbc9f3bc462d9f73664b1ef2eba92d7c4718835ef45aaec7c6ae30c76445f02b3a1a0c10fa887d3ddcfbde39f542d14af1d8445b0480717fce8147e2e807d31806292edef0f99df3da6f1339ae7fc01f47c97529a9a8c7ff1977cc592f1b36f03ab71a343758e139652f3dbd70e2c7ae51553584aed7513bd7612f43518e056adf9dc134b1b8fcfb9025cf108b330b7e4bf243b4300fdd28f184e0cd53d1fd377d7d4830e0de3d346f500c7964a1f54ec301f9966be1ef5a9f7fbcb19c92461ad3f716857c25a4b7123895863e878ae05d12ecd511f1d3330222ceb713d2bc6ce122692b58d8e79f9c219090367454eff94907b730cb93404b4129158cb263da48b8d77d10cec31556a1c4d04cc3712879fead840b48eb73e2ebb4374da71791618493b813153031004b4f416d68f3d3689c10810df372376fd683b75fe525ea18bd0c8c017042e6f16f117eedc34afd6605ef06c5bebaefeeca854a8df53f91708a9a417141af2ef7a5d762cc48336a65143928ef204b35e3702ce28daa8d279e8701aa0b0cca0b25a6032b200cf05e44ee62308fbf9041284115b865be721e453e35ea1d1ff3b0826ad72460e8a914ff237860f227f60c1a262d648c914ab06a4f073eaa0cef97e4a9eb178c74379c743c9bde4d3fb2718ff9fed479b727042f1bfef3f1ca8367fcfb5eab8fb577a49c4bc911cd78e5297975446f1091cb6c3892cdc83ed507953049ce0b3b66043f88ef90c5220f96f4f06b11f81a40ceda9c4119a06b8533536c6311bc126b081cb07f6d98798e09434752a2e0967b1ef99d26f6c457e1c8e837d1536865fde7631e7361ff2289f29923e599e4ba730a5400c7b4f6de9b8e3c9132fd1d06f5db0843a54650dc9f69331262902f2094b62a8e0a88cd03031f26e77ff951b8b97424069c88b4675723bc79153206253be451194c422a1d067fd2f7675f2d6e27886ca695fe6d967d71be49e1837bff6a375705b15782808353d6a4839ba3a784a8e4b5d3327e59ba05a03ce49b29c8f0a24c7143a8bce4a03184f1f8cf4e5835e31a1548c83b328e7f3735a53ef2fb99e903c30ed3f19ed7839d7de572eff6331d65d8ba91c34485c1e3fbddcabeec863a2e5eee260d03a24849c4ee4cc79bfad446ed69c8e054cdcb49dd0b0b0f4c31450771b9df3d6aa7370ee666d66a1cff04221c7e3d0b48b45341cadc4ce4190241009d0748c91743b17530b37da69fc4d3302aa858acfff681584f2ff2eafdafb8ec81f370ecf7a5d5ea39a0336c5e827eb52936ad0f21765c6ddb47ac74250b0350f166287c7430f2bb1f5fd4a67c94896e56959d863e48bb3345336cfa49f977f0f21216cb06a7dc56e140c8afc7d1283f785491f015178ac5c5730fc1f33ba13ad53278618557a0e369ed1d0b06a6bd17e21a5fdd41432a979c2adac453c3d2a87222c798e31f3b97bc8d6598963f2a7590480347c4dd580dc0fdd0aa92c790525109a83706edefd132d35891256a0c585428acd8370e0fef869cbb369a666fb9e8156e1d0b47e31eed24e6ed1c30830fbdc9caaf5f05020c9abd084b2b47270f8f3509cb7cf55a17269d0765165b0b83957282d7794c0f26e9c0b4f67886bd35426a1704dac6c4a112cd884d4db9afd5b2c1de68be3cb1f35eee6e2c8458084009f97c237f338c42e79a2c7e434cc110bc62046aa3acea6c6970bea989c1385a364d575885bd28de33bfc8334aed320856ef8c6c99a162889d5bef0a6cafb84ab966c7bc28ac570ea2b54a5edd2a630026c3eb6946b8865fea2ea3ca1cf8e4d4861b68270315f424e74e41f100e08777947e664f9f9e6673633af9c994c7a1f7e27535a7b6814b124c712cecd6d02b102bfd6aed7318b584a5ba4affd054089e4a530ed9910b8941015faaa9601db321f6055dcc3ee531c883c853edbdf3a67de28b3add0e91a1ce813133e4a7670d4da87020fe3d336c728e246724b6f716a77a7b57c22a03731ba903b854b9813b751d4c7aed4cd24091a61acc5e3a36608808db461cdf461950f1162cd2275e34ae3b0052441240e922b51f7cad50184dff7187d84d1f0e5b3aa8c26dda20c80ac6d0b3f9cfe93b687006856d041f17316649adc019692791882f1f5aeefbb5a9c77d0f727237d3977df2bb783800d215585bb99ab0fb2a558bf76aa00d89b90e5f9c3b8e9d70546eb3937ba859eb5aade3b54a2ca3044faeb748697020b6be9ac46392c1c42e5b38599ee5559694f51f82dbc33f178f65be2ad1029deb233c2aac34c805e73f7ef5dfec3c5d6e2c10f16b0aff31b05fe5eb304adc8defc4c887d95612c4dfd5b210614f7c076387471778520cdcb8f64f0465aa74ddfe19e03cfe22c9a2fa6d6a4d8af389855161bc7ba1848dca27f51fba16b009928676a8e9cb4de5dbf00068fd7cffcef75b0d4bf00660ce46108b01c46977f76727ec885bc943fe9ee99d2ae90ee65021b4dab4acf14a56da32ea16219b0c282b2adccb41ca3248f0e26735ec69b858da11704aa7b0cc3e2661b92a01412930060895fe9166a2eb89491a8fcce4b529c56ef426a9d2ad9a0aca14d018c894e7e48a85dfb45e8509158a34721db118e9f00675c2d1845259ecb1b8ba26a61329d3015ea08a9a02678870963c8030f7fb985cd5f245b6095e5c5f1564ed0157133d7c97d6ada18523fb1224018a9518d86a2e2bc57d3cda81dc3cb2309b17102447214bb1f8efd2846053d84e290d43927330c1d207a3308fef562d9d6e3ab8ae9fb2428dbc89ddeb719da5ed05a804e268a4f17879590b8ababb07c26047adbc12c5e9359ce74f904514b47ccf21c5611232227e2952c182f318e472726c3df288db185ec057d5bd76675ec1f00553b8ea26bd73c714bdd5d8f3e3291d6440cd00dd89dd5fb2e7c6b8b602fb5afcb9b7ecc2788058bc27324522ac2c54fb9dde85ab4827e8e0f61a96e53bb0526e96acf8b4a4d6614b2a27cbf16d2182f6fbc96e5a03c0a0e2383eb2ca8e4e525290ad1d7473cbab31158dfe0d8772aeba026f54da5dc759e2889c242987305df3353ae29b5ba2b8832c69d23ff6c73045b5ce65d194d133c3241178a802e16cef12399e0583a3463360f05d30a2620876c8719544efe5866bad4270b1861fd0c82052107a9406edef16846138a1a2ebfb38b05048ac3d1a098ef6b40e08578e7f7997504f69d40c0897e3205028084531465b934f51abccb1176ddbd879d33ec398a9b14a285fb0f4fa1914dc791e37967882e50581d9bf9fc35e2cfb3b9172417656cd93d23045620d9706e16b29fd9b5beee1bb30315cad860a7bd06e68cfdeb73ae0cc5deed480691b75c878afc97b5df76f11e34a6c4994058bdac1edcf503f06ea0b786cf7706caec11c54d37316c1dd54e9ae9c707e9e3643bc80b94d85d4cefe0253733818687f2053e23c2ed4bf236cac852a706af82bdf73950b6fb9d2d9efbf650cb9396e0d8fe6a91bfdb66e670a1068c9eb51af8af00f268c83496a1351172d0b22104c06381c86973962ddf011d50293b03e17957713d3793bfe5df0d9fc33aeb36095cfad7dc814ca51735e5b3fd2af0b0b8f0a605e8ec7a8aff2174badfa5af875ce47f81ec29fdb45d7f013799a9e0ee83556eb29d926323f701745894f0146a2085b1eb061809935d1011ed549843126a7bb42e0eb9e54663d9087a10bd3a252b24caca7ed2b88b6bced9658f12b2f4f05884acb46344660aa70518dd598774585e797d5c8f5842a3431de05aa23b44a6268c48af30f2c2956a6ecc661dcf04447d5e89d0ffa13e2fb91d615c31174a73191e30ff34cad457c437eaea9feee8c3c27480daf602d1b724062db83f3263aed18d91af7a35ea03ffb1b6e9d62f2e1f3793fd5e28c9266213430d3c7dbb3b47e720e1e918492a4724109a32b8a5cf1dd31eb75bb4dfc3d6133d9f19b85a53788adb491acb90de6abcfe2f32af37edc4fb1e2e94d33a0340e99947dc632d6de9cfe6705d2b2e06d3366b4311229e9b7e268ce5cfbecbcea10ab198b5fb1dd275f28cd8c9934f7f6a3e8a57be574064df0291addb9824e0180167f7aa68d31019fcc9029b3b44a4e14a449a89b5681c46a1aca33dfba0a7c02b4dc2144b422db6edeb5519f29e222496cbba355eef284e19b6171769816396b9bec15341e2529055adbb1b9104e41627313df0e8b28be114a40133f34d390909534d00ab78c13b22d28128cfa0c845e6621bc06634ef8d847317cd5e6dea5a9901d2095847d4de02d20118981b97625ff129c1d791530062b2dcaef79946af17c527d66ab1ad3b3bcb3ad5c50c276910c1b87bd28cb40dc0b46ea46f4750c732f6f041c4de0792a80458040d335ca79eb8bc052fa4a98fa57231fc1628ae03fc377de683257177cf150f125d74576c5ca559b4f5c055e6b19f5400f024eec7bd86d83492742363fa1a14d835d468df1872a37524349661d4a0e705355a86f33055ddef89a449b420c1104d169bd3727692081b6b7d5019392be2badef2f752150b07d0d58dbfbec23cb62bbb13a0b04749a17d220676af39b894274be9402cf045f4dedf7fcc6b748157da01b0c14fd80e0351c6594ead1012d02ab60e53a5c12707dc8dc0e0d8140aa69522b17178b864cabfed0f3fe7c72a52efdedf583c8b9164fa64318325ab8a0c115e616a8b31598513325b73a1e773456cd14d271d546424e1b7fc808cf3c681199d3dcf0787658b8fb51e666e2b1f4048d0d1aea42df8a5c710b041d5178875168e4a4968f22bbb36e0aedae3db6dd452bf2e84c2909f15f53d3b9c3c0df8e8ba62c0d8c10fd0df483f5ef571aaa7109a8a408ff59ab382d6584821147b19d111b3573defb209356ac949e51e5b15978e3710fababd989dac5a073fcad4da66ae2ce5e5525bae32f20086e4f1600f95a8c94f927aa82f1470de872457973bbf33eba461d959ffbe892895ae29816cda4ba2c90ce78bcd94587ec00dda885c288a4d406c8997da2aeee71fc9f0db65f5a965afc13ef1b1760286207bdb378bb2335ae48852de36dfce2e1a56f8af6c03c70dc13eaf1d2bd93d0f16095fd8e190047e2676388db9c4bb1e1662532ed8d337c3563a083d6cf0546dd42831eb1536c71982b9a5e3d43d54626de5040ab2ae3af960e9addf4c5d6bae9fc431573c4d9492d87ef13386c1a9d3f7b598fb9638f05fe19411bc70c5c8aa53c56e07ba87e05aac3dbe906a9d80905f81ede0ab33f382808792786447b6a0a0e13a7ba1dc7a4a1443325c274100da5d1e3d4c14863f484694b08a8c0ddb0000d61feb6b4ea6c2759f869db7ce45ef84db05f28a469b6eea48a1a7258ad2936eb94edea06cd38660711c23e14f54376213d6b45ced5020b221962284ebac1b508b66d8ad8015acffa9ad7af1a09461428bfad027a69b668ff24b2267fce6935552b557ea4412f5fb7b58f8a2b5b5c0a9d0abc650ba22d17721405d04dcfd7ed6dd41151509c8d2ef7587dbaceb09dff7dc3e1cf4dc27f37f5130e1f51660b2a88da8d984acdf55d7cd5a34d2c24161c93d8be759f160fbeef313a44b8e30061a69acb60709569ececd160a7185c7f0d27580440ba1c37cd34501f033035a2f2c001928008057c106195e1accba37369f24a541079559ded6c5cd0167e281d774a7efc4a7f7e79a75d3608fd6d72076b52abec819accf527b970acadd40b64736cdf6679a2eb0feac00cf1706534c405fc26766a26cfbc625a0d5ced8f4ecd0394fdf2ef382dcacdc1312caf740668615ea5ef58d5e9d0283e2ad96698d11862f8dd322206743b74a98b7b481dd8e432af94574add72ba2fac1e6ab53d17a7ad6f42405a12f7fd569340089ca4cfe612c2eede6a4639b8dff0e7b4e833696cd7611d5f79032fe1dbef5be393f2a5e039219e7b22431f2839f286e4062c66a69467246d7e8e70a1140be9ba9d5848e186cf44f8a0b8f6426356f5232063ff899a29a9099b15a9a41f1900406b45902cadb01695b400a299d0ebafe9ad49422266c20f9756438086871908712e138a0cbc30107ea144c2b05189d408d72d1fa876c467a9a59b8c2d61df3344dfb2ce398f61c90be7171ccbf5434c6bd5412930ad6de43b158b5376db2f796524a290341064a06e3063c65374904a8fa6f9b69eeabbbde7bef7defdedaccfd9a5fe77942656b80d3581c16df1653148b29907e49d15be30945afce7ca1fdccb5f7a24f0204bacbeb7eafcf0708bf7fb5e6457616e71bc204ff4109253f1f1f4610320879f5f1119c3ae2a5f43a6f8d5e6b7f04eb09f0d6d8852289f0d1cfd0cfe2eb245e5fc15b6392a247728604eb91c0fdee6fdfa13b1e4fc545a77a89dca77dea95e12d60f7278f17c246dbd7fdec7858842dd0206e8f0742ef7a36dd5ae8bbdde953f53dbba96f37cf6e8e90e922fcf917fa6bf342bee7857e5eb070fa642eee325dbd3ef32c4b8040840efca9d510fc9f2a667ab5ec666f844d17e16f4fcd7f765d76b363a2dbe1ec26467ab524915fbd9f17a0e2b7e96769e2cf67d7da977bd65dcddac7a6dffb362a867e6103191f6e71f6f0f5ddc874b397bdf7990d7cce7e1770f6dbf11013f932feab9666b799e185c8d0af6fc4ed365d26434fbd6fd6dc5e76f3d4a7ee66850ab79b3c5e88b38fd06647790b40fff4a91fd8ec2bfb8cef657af6c9bff76fb7c1447ff69217c2a6a73d5ec7d0e3fd02da6d7af6f110034bb293d9828fe6d298bb4e4373afe91bb1eb67bfbe16b7837a2dbea76fa77fa6973c1d7cc4d9cdce93e9337d7779bc6e791b98fdd4aae9532ff1feecfa49d36fcfa4f1dde8faed65e7f9824ef2b39720e8e78190dfec32bc5ea1c77b1a03677c2a0899e485b87d84e993e99bb700f46fef6627cf7e7dea0725feec329dc7ebb8c5ed609fd7350f040f17f5f47e5defec91af533df0bbbeb3176319f503bfeb3bfd3c9fdd9b65cdb569f3e0d7c10f4b6b0f7e3e26f8fc0896f79e575b3721a8f94406bfbd867bb1e0b7c449b9ae88f8edbf9ea1490cbf7d03906ba8c877d71c74baa4e0376710ac995283dffe6187490eae0106eedeb325e4d8855f07704043358357400216641c8d2e60019f1319d8328106c206dec8f8dd1d9841a1c78b8d0b1246f109ba42a2610d12247e7b08a42293c80acea474bc4a515046ae8e3d432e54d69b2c4dddb943793233bc028d851a9b0b18d20c1a6e702290008d80a73b0ed5d405a8217e77bfb1221a4112e21ab48ca408c3336c1569ba28f1dbd32f2ff40a157e77c7300666331683df0b6664344554f0bbbbcd45bb6756c721dfbdc66d8d4705e177770b97cb85dbc9386ae197e6ceddb8d3c5d178e37ef70a41c2372d7e3be785c04478580428057e779f412a7ac352f4bbcb3029712d4bf8edbc28289ae3187e7747a9a674c6b7237efbce8aa833f670117ff7530b8b87a405bfbaad6205ac6311dfddfcf27a63c26f2fc7c06c6c14e17777d28c8cbfa0c1efee1bed8cbf60e3b76bb7b5371b1c73c1704480d2f01c8ee32287e382845ccb9b989068a8a5e7c73023e5220d6f8dc5152b17312961786b2c169f94a2a02cbc351679f47841514da56f8d451847a6ac32b188428a6b61697191b1b68a685f72317f65af21c62350f61a0343c2c46f36cb644388c465b28c96cf865ccde533b7355447cfd7daef5e72c970439a8e4e7c7732cfe5b89ab7c62143270409c140211ab68d0d7ff78c5434631685332931b1a295a2a0502353a0a8f49490ab9e26535b5b69a290a9e315a216d65b18d6ef9eb78a34318e3d5dc5df1d7f79bdf9bcf0faadc734d8f9d628848888063323ab20e7844ca3e9b3193713fa4cbbe9b57c05075780e6a2e1c82a6f3d6b1a4ecfe938b2ca714bc7e97e7921828415c28e53fc6ea261a9c46c8854641af1b9519499944c23654a5150bcab37255039f74b357575ec31326545c4c01da447d6266a6d2c99b7c620347ab86c2c9cf5264b5377ea78796fed62102318fcf6f26b7b05094af2faddc931309d9c4f13d8efbecdc876702bd9efaed1ce4836377e7b765bdb1d9ff0bb3be602b79f1c7bdae07ef7bbe7769caec98e0b12ea9af42011120d775d5c740c71d699973b462ada75bd41f1bbfb25994825adae630f1052e977b75150bc1f479f25289cf5264b5377ee501e940e10d83b2e994aa6f2a98cc239bb43d9640dc05300d51417b8a9df9dc703913b6a457c3bd3c2d225a861fdeee756d1e48102bfbbebbebc501a4729fcee6e8e81bdf1bb7b6946c68dc0c87e7712ed0cccd9efbeddc8352da163152e706f49f8dd3d9373641cefcbb1270b19f7bbe32021171f1444c3b79e2dc3df4ffa4a264bc1ee3e4b785916bd3566a1fd7e6bcc3a32fdee3e427ebb5a1695605d4066de1ab3c0944a505292421c8eb8c73dfdf776e50dcd2c8eb0bb09fc5be69d77d973d7f53ad9eb00f83a5fac3b36ed0ce05fb629aa30653d76488501c21302db5b8d153b6e78a9e2b93d45b5947e4a411830da886c41ec18f981070253cde00f3d598864162cb27d814e9661e1ea04753804b18069284c8e1ce12081886aac24aa42829810175a3fb09095588e66ee9165675881d7a436c607edeb713bdb1c0351b735a35b96d75a77e0869a244ede1a086081ca39f675377fa74743c04d9873ece7acd38006b76d5c6dc5577fbb2246411146bf9b35be02b736c756a5d36c40329a25e2055b8ee107361b4247daccf0d6c8a6824d0866ec20f8ba24b15249067572ced90af173f6f139679f8820b344b1bbddc44d31f0829df8cbcb3d282b4a7f97706bb4327c6b05e85533f7acd6f635178e0adc94316a3d86d4a4d49ed46408a91da5108182543ba2864596b036b6b686ed9035aa09d3d67a6f8d6947d2a68c69445fb3f7deba738ebb9de7ce0c6d4ba7d3e976289a1500de1ad15ca0fdadb1ca1b6f82b7c62a6032288fc7e3c9cc54893a7732f9b34fe5c0ebb276162fc10004dbdcc835467a0dc5fe42a258ac5029cbd2d419ab14ad1875168c58f1f135373ea707deea223b1129449c08de227e7b06b219510c78b2378bdb22d2d85f61bfe006f111b95bfcb6f8e2ecefdf8eadaf1782f6e16a895775bff1395ffb48ccbced767d9d57ed985773c7153821cd9ee24cd1d2624a14a4294890a6e498c2e4a3b5ef5ae0b67a833be649640e9096821b02e6808f160a5f770e90bb8390fec6dd47e710f0939d44de1a5ba05febcb17d3b4411d0e60ce8d39e4bd59ccec9decdbf25a7713bde494a033f402149fb10d7fdac4f0d6782676d60546a2f07bf5f7560879b547d038f299d3598ce19118f4f391238f608e70afea80993d76f6e741f0adc5fa082585aa83e083b9f0d678c43a5afdd0641438b3391b39e7ec533bf8995c77d544b394a5cf39e7dc6bb8f01a9c23454a9014e1ab354628fc780965cb904c3b8e0f5ccab6a968284f8679074ad830dd91bd4e424932dcd94fbca43e70e5efad110a0e284cafea809928761cf8b636738302e62d4fa7af3b906b9fef8ddbffe10b4c1eab011497e0adf18998d76f8d4fc0bc9a5efdb204c9c056b3b2144f96adc83e6e3fb236b2b3b0369c53675a93a71d48621626ca79496e93e75b05e535294eff5993a71da813dcd1658c4d40c96d62ecc46a13e5d6e469df77cc4f9b28af4971fa8613dde9cc923479da813a41d3cc8163f29af4cc6a13b526f75d2d703a1c646678e8ce9a3ced409de04e0f07bb9d58c6e93fe0061d999e3579da813ac19d9e137379b847663c54f0c0bbedbc26c5e93fe0061d0ec137b8d73d979170f6bae7f5eb55f4b1016af0ce7adc51b3c733331e2a7890f1c0f38076db3bf6b0eb1e4e0fba6efb06ecc1ec1e4a0fa487dd6ddfa9d0e3bd991ecf3929da03e69c60ceb9fd76b3d743f624902d9073aecff27ef4e7ae33c6703b9b1a93603819a3f4bbd2624eac3889026489bf9d9e0f186894d9e95152dcf9e0e56842d3fee2dce9294b93644106adbe84caa055a924852fbf4e647b16b43235bc353a31f2e45ba39320335d76f6574af0384fe27eee3746b12c7fef13a1a0ebb33b1f23d77d5f9fd52076ba4fe0c4e9490a8071f2ad716cfd5dcf417ea751b39721ea439055aa8a54796b81bb4e66f22412e5c9de07125f32cb90ddec691853f1f6e63ee9c31270e21603396020b65a822f7bd62806663e808dabfc71085f071878fbfd9d57a3b0dba9bbbf1897b817831d8911e5abb6828f44077c3adf0f6ed5ef27d695e277558a0919feae7410adc1119b126b7af5a7c5ecacb518d014e535c4922c4b0e6e1aaeac2abb4eb02c4bb2848d2f723bd8c2740911a5b082b6c5c417ae2b249e5289d9974aa6ec88a48f95496e9db119446b70c45a84edc02648ed8dd59900b84abe9290bde555956459fad28e81722f70dacb9264332acbb2eff47acab2244b63d8f1cbb22c7b8a3bf8913e579ad4497f3e3d7ad20e3436113ece5b639891b7f0d618467c55076c4c180d303899d4081684afcced60fb047c48d03132211a977c5d0c2eee8051f0783cb0bc374fa7d399a6ce9873cebd4366a2b5d64634da3116daed76c45c963b239acf8b868071a6616693e37eafcdb9f8bad87b67b00f8031ee80f5d6a6e5190c3b0fc6777fb607287145c0f80ac1185b9df72ef340687dadf699d84422c9bdf7def7eeadc99b8061e7293d94be20a11e660dba06bd68f1d313bc5d4f7079f4ed7a62edd55fd61315d884580a134c82746f57135dafea80ddd8eb09b2d504da6aa285d1ce87b818d68b4a8c9d1f222351fa43a44b0c6f57133d7ee6ed6a02ea559d3de367c56f05825a85542bd0978a9f219ab72b10901588f833fc397dce57b29eda9a0c97c0742d59244e8a0425f1b106240531345088594a210649488c90116fcd832c289024c961a58945f044060a5d9e50e5100bebd9f920060885b9d313266e284c16155652f09e6c2b1dc65c8528d013cb091665cbceca6fd920abca32a2b602b1718cc1c20b972a655b61b688c2fc2061a3673459eb09de1ac32c99e572939acc4c3e6730dc7eeee9a36a498ea844cd78aa32434689a715665a4f4f4ee2b4f0f430463a63fbea8e13c6840b2e624e8b912962ee78f4939b635284e55221463f393dc7e3551d926a0e470ab9b91a4122e4e690c62889c1c175e634303f503063a664c65ce534116068de1ae74cbccc5ba31c972fbf2f414e5e536e0a8cd596536b91fa500c14e1859b38474eae881cd6ab9ab7e8f283fbdc55e0eb70f86006331cedbc7eca5c9e9de53100fb6ccee9f17a97472684797b3c5eefec339707f7c8ddc99ed975efec9aec3bb9eb9eaea33d8e73d66060eef9bb4f83100c55ba236f48f2820c701a4860f8b9db9c99367ce6417db17ad56e7d29fab1cf669fc9ad7f543e8fe07804cfbdc6c29164189bc6b8350d42fe8cbbce627089bee6bebd477616e77c81b5d9a70e358feeb9e700cea3bbb539fb48ccbc94ce3965a8d70ca2961b9615306234673c86b49c856969c1c44497c4963605382f62440049b519e1007b11232e6b063d4a3d111981d2d6a4842e22b0f032c7095f006f8d7130e25ce8e024a8dbbd17f77b7106e13ef6e922c5cc21fb36ce788b9996359ddf062f6b5ed05ed509c27765505c0746829724517cf7d6e865c8ab298a03485a42097fbb0821c4575374841dafa2e90f1cafa6a809345e45532aa65753d448d2ab680ae4e8d514edc1e25534951abe9aa236bc9c78154d87887935456b7c79154d8b5c5e4d511e6fafa2a916dbab296a95f62a9a12cf5e4d511a505e45d32ae3ab299ad5e455349de2fbebd51425e2f52a9a5e6dbd9aa23a8aafa2e90dad57537407d6ab685ac4ead514c522be8aa63ea85e4dd1a7a957511139ba443d8a71ee02f539e78cd5cc117e3fe086dbc126b9698ad36f07eb0524e20a57d1477b35b783ed027a115738eeb6b705b47d14f8e299e481d8373e3df74bf240dc2fb654757df7333fd92d799ff4a9f796eaed1f94f8dc49e4274b2e441877297a3545616844418833ce5946f7dd16b186ea7cea883e0244d796825bb3c94d923e23721f91f5ae442f2fef1b22d2d28269bf190964ce08f68e8781db68c0414b9a8eaf99ea0a13dc90ba0cd97a70a1c6030b1a060045c7141e576a8c695b128ab2ae35dd3812a5ec1a4b508e10b3b6b088693ac1c904635a16525494a7b34994aa29b0154b17ac7ac8d0124af5e832b380e4485518113620b81c6162702f8cce64a85981f26483418c303b7c14e5885a3788cab2aa383ab224f76482f4c6d4dc989009115b8d134ec48862d2058b519953008654207342c98edc30a362e50415550ce08163c9ad0796a1196b066c952415442c9b4155011372c450db81a40ad1d814c1074e30211ca2830dadccc6912f29276d4d8c1071e2a4c39038c98d7d61423296a1aa4517165186e686c6703e08d3d17523081828333ad0386e21e244c6d18858932ecca957e04419935411b434310e484729f8a83a9a12d2a4898fb1518624888509223c285045a989058da4223830a7ac01096aab08972a37a291e969c696265cb0306902c01027de6d8102050a415a5dd60610c68952181f25a808b264068d2256b5044b38d7c64b9b9a7114e60d4dca094d699031454ac051c6b50a990091b82217d8d592245f1208298184135bb4147959434099702cad6b459426253416b2aa5c38b1116171e36dc514122517329c38497293c284132d503eb048d5f06da1513c363962e30a1227b2048f35b5aa1743a22b63b8a884a6cc18218556979749e4c799095b563c11a61d6d38c911c4a5c85cda91a76bd72daa28299c383a11a581138a60c32e45b9185d3b92cb09c38e11d8d88e24011561b0be40537343b28464ab575240348232429a1831c70937a5a0aaa6aea32c467c432ecc58b9502be2832d87932dca51f1927642919461911a09a838410695347745cc06625d6008a524117a41a449a6c45092121e26dc987445a9400864878ca363198ee26f880835aeaba11595a422ae122ece84868292ae562c424458717a1bcb7256bc2607d882ac9502eb04836719eeeaf7be26df10d042c4186eea3759f69ab45b0c96f8eeaa0e87ed0bc2ade51c0bc22c7be8072e1d612b912fa0311eb8df5d1be1c2fcdec4216d6384c0a04146856707f9bdb72983dbd709c24105c1356cc1b56f81356fce580b991cece490866e9da00e8720d1baa5103351262488850a292c524ac894151d624ca8a4502285a66003ca6976fda147aa28e7f4360fc436cd252c328ea2dec9574a573ef4c099d9c6d46bad75046e60ed6d43896bad75aee84491459d7dd889828beac27590cd8c5adb51584c9da08da25f8db2b5c618d80c71a7f5769d0afadcd396029b73c65a67df2af5f5fa7a000337694c8e61a6027fbd49991b9ffd1cf81d6b0dab9586115277f34e30831a4b3e771decede410199069e6dac17cc1071cacf1f5f9ecf9c3156e736ecf39e3b0e17cd860f69bb944a00223bb7aca32640a4f982f60665c6161495d3caa4e8d24386bada1a4036b6cd5942ac80d05f724e6c719dc2113fca142c3c6a631857af9a162dabc5d69b4a0217c95772d53c89bc9d529c793e42f8aefedea94a229ccabbf1d607c9b997c9a7232610b1a34db4f6dfae92d0749f28806cd3eec3c619d4f453e027c2468568e55691a237f40f94109362131d9686262a2aca96ba84cc3dbb589eacdb76b5314d93a236886705d827bdbf5db75c9cd3efd8c716052d22b13530e8e994b51c2300d67202d9505fd88ad4b6242e88f982e01f0765d223e7fbb2e41bdfaeb11160cfb8171f3c34e4f12d04e12e2a15b825c6f342657da69724139b974412e33e94b46dc5291d8eee6c7c7712775a54e67eaccb22ccb12e34e96ddecd867ee74efe6478ff833f79bf3c4c919f4e4dc819f397cb65ba7ceacc93dcda6699a23c8aeb517573908f8499f09f4719f7df2c9eee757eeb2244b72efbdb7ee95e09adcfd1ce1f775f6f11d8c6e0d35c14c54525b6500bdfa531ac33418ebac713771afc45bde0d6224892b89485752310908be425c636005b417c2be1984e78e923bac6f96d99d24efbd97cc160337e0701277cc87b84f5a6d7396d97d07df94ddfcd2e7a380acf3939f2d103016e25cb6f5db0a76915c4f2b328c18435d305a0c7f5d308254fc74956f57a43026207125f548bada62e2722a368d70466583488b1b59d4888825399d495325aa45e66d8d415c61680d8b70b5196182e58595aaaa2f4b625e50a89a8ab124e9c50e8e2b4671c71033835c26d294e7bd5d91c6f254c72aeeb9ffe87aee656fd7c95e82bc3def9e7af343f6dcb3ef77218e5ceced2ae3ecedaaf485bebdee7a4dfa7aadef257da4feb2dfb25bbb9700c1f293f523f8e307c6cd0f3b3d48c59d4f901283d624cad397947dd2d414448ecd688a921aa68e0b6896a232698734d44844c12c13559282914ec49c5d746eba2ebadd35dc1c8255c82bc1ac1764e5fae218cc32f5be3a785414c21a2a31ad473ad6175eebd17a8197d528ffd15a8f905ed5d121758e8a5e6bad35f90384447d580a50020aa01a278e24a4b01eb998b2a2c81891315c86d4e0e4dbf568085dabaa0a160d5dc0e0dadcdadc6bd1d9b9f7de3e8cce8cd6708e7db3ec6923a330bff726a188ecc2dbb5a8a948e9d574aa9797dcd845118ad5c5508a1f1e635a14593069b185050f6ebfc593b5055811d52f470e0ec10c88882b82dce0e7db9505d74f14aff07665616583f3b72b8ba80d40162c580c5f05dad865d2faa4489f083c3cb03df3d05dbdb1dd3e9ab3362faa7105b6931df71d49fa40c0a3019627042294c2d2c7e376d2d72fb6e0fa46e8bc6ffeb9fde68603d207012992ecb863d2170260cec91aac71fb2148cd9c63c9b3950bd66778bba200f752bf9373f0064096024c7876dfddf6266079b60f04c01cabc11abf0f029e736cbfc9e1c0da313ca46f276f0064792ccfce666d48f8e6c767de1ba961e7d9fdc6a74b6d9f083c3cd0d9ac0de92bb0fdf24048094520fbaec0fa46d89e1ff7deeef21cc08542a19067fb843c7417219bb521097978dcf8e87efb192914e3c5bc801a962cad11886a4c307042cb5bd208685627d6c82c26eaa6af5021b31428d9b87f9a04d225cebb2c7f76f0b2dc619aa75aef13b626bbee5a041d4b43acb8ad2854457225eaca53a4cfeae09a4777edf6e34462ed9fa69f1a397e68f0fc76558163035005d31fedf00a2815542b884fae2bac9accf4edaa2268284e8c8929b80e69adc324eb1096e1cfd29071e84bc64f8ca010128a1a69d1dc7815222bf58f1212ceb14c111846ddb2c7c1cad46ad3ba5baad7eb90a851369bc4ed6f430484c0708e508edf6f57a1a857d3a2144d5e786bf3d602062806bcaef2aecabcedb742e75de5bded3434dd82050be88c0c0fddd1fceda7ceb4f9dbcb0b7f3b8921fd0cafe129284173f30e0cf035684521c4e4a508ed888c48c892ccdb3588485a1d9674a834cb5aad6ad299c101000001c3170000200c0a8703418ee3489225937c14801467a630483c2893452291702c88824086c1200462000660108081204619e5a8a15a01043cd24cc6dab5cd4d0156a17e6c6ec5c41201172d0d433afa961cc48546634ed23ad1c37acaed98d1d97eb48429c682c50002be7b9114ff4435d0f374ff65c8926cafd57573b325edee74218b301cd026f2f2f294418fd6c49b0e0825d58b95d36e9b7ff6627eb932f86c9e88942799097f4f84cc218e602107b9200559d4c65dc9fea84c0b9247aa0139178febf1f59fdeee3f4ce6f01f81fcc55d88f2c6eff5cbd1fd89f8e40e63e717c299458fa87f5d9d2d6ad2b1a6e9bcbacb2135bf9165e254c91214dd4fe153f3831fe8463fc41807f7ea3576820abdde29abd4c4ce4cb308ab2e78400eef80d51286c078fade3b0cad00c09e9c9e05b21cb66198de1c5c8178446036385b971cabe76fbc8c09ae4c0e6905cfabec575640f874158f66ade8364fd307733cc57c6857312b20331883581fc9dd148f289bc377137b98060d3860e45fdcf738c4132404ee21d4d0009a4fe78615c8f3945773dd7c6cb7e49c4bbbfb7cfa8753a8f3ad5fb23dcd2b96dae73c5d7e61eb5d08b04c130e6abd9cae85392e907e25ea74979c994ceb540ee925acae51295c66cd9df57805ac67743c7b4bf48131cae74ee4d8b8b50416163571c3e07bd97265deb32346bc9eb873ae58c64ed5da342601833bbd7c284e4d43d1321500642a08c2cbd34a5dca0c767108944ca38cf85a2fcde067d9cd8d9a9687f9161ab8a96db5d391d1a7a9005c2553084feda74f498f3db76221e5b494740d3ae89b0985a15c8ee71a5a26429b63466842f7650a094a5327214c889df2e425955c7613e38840a6994ca68c3a4907b94e447ff1fd24a40e69b7955a86b5af1ec4bdacd6db188d8f54e29c5b5283c2ca4d15b9d0e9394810de6ee76736382845ca380893b106862c713f6fa3381fcf26a0d5164db233c4b91776e6dc8c841984aa28d4ce96b0d85124c901ea7a91642f28cfe2fe4b880ff2f6b1e1461ce9806a50ed353cf13edbd5590a53f4922ed2a1b30a703468caccbee469ea7a945982322822f2c09464b8071e90b4323e4948bf985355fbcaf3c2b89b890b839e8fc8672a7e617723df2a35f32d30b9ca3b335c379e72a67215eb092c37641a580c26baad2f67224569d03621ce9f5869e0b381651883547c7ffca8b7c0f11ecf7b37328e277499b50417b81879bb6814b2601462a73710bcc3610ee33a3fa7f242944043aea24b9b62e6be3c231da5d996665eb5911b76cd4a245cf66c880082bf148909e1efc6c24487c175fc7624201e49ba72ee7006ccdf60642b7a39ecf8bfc040096b991a5b967626fc9f500cc674e66d20c6704d1e7204051d3fc924b7ef00561d449b6c9097f670a24c732962e547cc8e3649d009dcb4ae84ba714e04add1b446093ff9080ad97df34e3a6284221c80095b105801a171b9d6d407125280ec5a6f806c3ac2a330628e81491dd69e9e700d026058254461b334b8b8ef3c1e89354d4f317386b838a9cde2838ce2d6c34c270135049f777329c6533ac686cf1e5fa2cc09e092e7db8646a534e7d1aa8e562c5006f8ace769cc9bd32d30db39487863da51a4df1a07e6f1a2cd40a1dfe55060ce3b0a994fea94ac571d29e8aa15f455b1af918842c7a461682129135dcc037642ef837b42c1e1750f556fdf8e2007393b07098f8ff1f9a4f7fe5f3e23df6bd235de0e394345852da1f79183bef7678ffc1d4930af94927584646a920b3d59c81f3e67c0a690020ce17b9b9f33c732d52f95d78a7fe1f026fffa4758f3be0dc675794ec9e23caddd4450d5d578108c995d1d4fc051e7e6b9fc5a772531936e26c39d25a06ce0ed7e4f5201fffbf3f59c13b5cc15e606b59519cb6e96607e6a4efd6da1d5be7d1ee4d0fe5c4db2679513722b05be450ca631e6d511da514929c896a400e3bb62834b5b41573a66616d3427e51a5c005c2c0a92940558d94e6cf551eb2cbfd0c88ce484ce09bb172e2d0ca5ea3a6201371dc8afd7dc30b73f54cd4a6cd1cb3be5675400c6b748ed5921ec56258166c69c7644279afbfa81736ecf9fb0a96da85c9d79211197a8870d758d7cd4040932414823cafb117e03ccc2ee876292d8e706acc1f855ff512050b27223726d9b2174f17098c40582c55f36ee9db125fde2d1e65152c4030d7bfc91e71e15cc8e9c9430949b13cc423ec3abb5a8b241d0a1f531221b678db7431c008dc307c542b0a59ef4e3c08dd2bf11349041dd9c274f5a0b3668fefc209371ce5f3f3466e481680d5e6f340e12344281fde6311bf0ae471c2ebc066f24712ece6f693e85a7b4e9f0982d71192c879ef9efaf0b212c70c1f5d9aff94539519e8f7bea037f7ea478c1af426408ba9186a69d12a773c89b1035190f26ed7dc4b86abdeb9695641854c24001722d3e7530765683edfc008b19352d16acfab4d19c7b4d8e09dc2a4cff448a37293c9026edf3038b9a0ddfefb44dc070fdb4260359fad39e7293e064d0413a4289117330061e45b0c48b5fd4958077dbbba81308868a3396c9c1bc102329e3c015ecb84729eceb79494173e9426e6210ebbc4f5a834003a2e4e71f9353f2b0a1e6df92666ea3aa5d0825e4aa9214c608efb95016f25109b96bc11402753d4f2cfd8f9250520a9d28471eea1f590c29549acdfc9e10b32879a6d8739af9ff57f87cf4c761ca76784d99dbf79dff01264eba9647bd55bb668800d5ee7ead1aee11382dbf8eb63c4024c483693b2f266e451363053c5608941e4c0307e695b62425ef95694c50d57c507cdfaf522a8f4773dd6e9742e9e34418c6954de12fb20d31342b32f04d83ccf3ec055f34f53ee911b9889f16298f57d4f45463a65799c64dcc9fee50e4a2673b1e9aedef63cf328593da5931d6b3f5902cc099ffa9c453583cf939961ff1838d66bc069b8454bd622e4f05e573ab09a54bcc9079089f907c97d551991f939701a98ebc68d3378dcc1f6d3c82da2eb2d317e07c865620a0a07417eab183b366ec4080e3c1fcab93d8213906242a646f559c72b8f1aadfbf5f6b6dda0a88ac5afb03de80291b8ddcd84dec46174b88dccaaae0eb2662e21471b0730d0e4c1457e35cac6b877dd6c1f5261219d9a8d41a86169337121f3d6c2fd4dc114d0e723406ca92b392e558eb494abdcf4c9962017228971e037591684fc7c2f2a967e8b634548e1a72b21abd50d8b0f99d2910f9661582606c205bcb83ac46ad773e90cda8ada2b0613970e41bd849c0a0e54b26c313e2259b736d4674c9389272d286f8849f129440d941889e0799526503ecd3dfcdbccff966dae7f62e2a1204e4f3e2cdfffb98de3ee58595d33aa463d6884a97a74953d30a74b89ef92b5170560d10b8d7bfa7a608c997cba582f802b8292c89430058a060e77773a901a5af15d929a77e2370aa462d374da14a0115e21113aaf80a7d6c8e4b4fe73630b18d306c367d0bac0d8ac62c6206353dfabe2293c4fa6d8b9ba646a3d35344235477cbaffed7ba7b40b1639a8b3c78179e37b04262a836464580826d42b2ba5bf3217d525aec5232348a5134b4bd0b58bbc805ab0a9d7a76490c0b53237bb62a14059e74969c76f1cd38429428d79ecb758dd32448ac7f960fea7b469a4eeeb3470a8a4f513e74250bdee9e42cd74216df44430446be82d9e3689a4f526aeef7116dc8904415222311b092e10cd230f193178f168a737512f1ab44b28cd6592edf137e7bfcd526154ad4afaee06527513d8ab240e4a76e436678046d95dd35a08d17dd13baa4e137e149a15d7ab9a356ab21bd2dfd273d00290c4a6f6c89b2c668e8bb6e6a38c2bf705b65088dda77b5b8ac92acf13a2b3bbd0839427f275697b5c8666cf411cab15e7b0994a520677e0cbffdac6dda60ba8889982b268c0c78d1d0ce66a0f30c58caa18ef9162d14dcc5a0d114998113189020ff7f339e7abc1714a62e178a0323ff239d9866b76b61e12510b4a29d56494671775ec792884da06ea13389df42fc98e61c5ad4b9cd99f85a9061c6c51a7064e5fb3a73aa0523394772811cdf3860ecea9c8f1ce546661417826713363405cd0dd3934125f1e68c117622e440abab6c1670c5bcbe11a5310cbca078d5b3843154700506cc684b5a4fb2c39b71085e6f6124a2abfa0e5b97f885e1e3d7d482a15f588652b1ad61e4dd2ca9536c5cba268733a5be7e488c9ee1e2177e7361c79f323f6c4fca51af103d4971af5e10ff803f6ecd01f43d276d5797af801ee97a1e2a58961488b651badd474b889d6dd50c8df6542320e8029cc15fec17c225b4c5f35581c3a6f54df4e72f6286f43b6475f1c8eb2f038905fbe17b8e9e49f252fa31747989b011f5f47399105ecd2f4e59474da3b1a891a1667b7f5142b56637902a243bceee5103a6ca1fde687555936e2bee22928bb15446b70cc5f296dc15cdec07441c630f3753c622206b9faef6ae488f77b739e1467603640d71546a93a600140c4eb82066e61a00909a8479b4436b994dc7f0ce516486bea061ca613668177d1cd03fee0dc1ecaeff79f2205e8bec5cc36feadb0db3725a45e0dcbe1fdffcd5da512735e2216cbfdc1d68e588b9d217f16c10a6858bd08683b4e19f892b1a858a595b1e0c80b0ede00627705ac13a4cf507b02e13f94c6323929ff4718467bafbd89d54ecba102007f70c4a792bc2b97297f0f4a161f003936e7b98b2dfa1e56a2505de1ac95f31d2dcafea7199173a1ba2a98893ec03511991fd829b76031b5eb04f2c43b76f062d9a8a128e9cd668e4c2b12ea15d849c9633d497b2c81cb57beaf15243c8210eeb61eaab3828cb060c712c247fe759a3f8cf09272889ac95c7d8451068631c3a5236b6a807cb6e5c543bcfaae536b431aded2ae0ec71f9237959cf1a442221927baa59a3cbd2bb0ac6f6d2826ffb457293c03bfc23efd4d32dde417fb3e9c0a337208c319f05bbe04bb7ae9bae32e9bbc1b08438019de115d86ffe20c5702717c86546d185b329d29e001d3c6fee5cc363d7893506204a95f770a58e3ea09094846725b87cbc7fc91c4265f62caf0317fac9fab7c96f84ed67212e932fa8d56f24d83665eb4646d77c767d2900fd22524002efd0c7f9e5aceebff89df9cfcdc814375a35c6c6571bf62f07b9545104677222ffce042efb7fab040fbb310638428a1cfe372b90a4e58a1c4511f1c3bdaf7d40d96bcdd89795266b231bb77ca4758b5ed1a086d311b13eb1fa29084bdee673b600e9eaf6d9f7d34e221b263bacdeda3f8662f9f0fc819d57b99ca7d38be743d22e5b663986dff6dab0300cafa4a623f759b0a99d2378c6e71b3f4994b3778f2eabc1d263ae988f32f88a0b2daf735725c5c072bfaeb134a1d6f01cb37a8731b984163e644bab570f6ae2b2da800d4eac7f55d67bacea1cf6e7f6009a35598d9867117d9dd580b28f2e2db04fe3ff8543adea00cea03e68b4f3e3f74df77be27b6b224eff648670df45d74f053fe7ab17e6dcd471e067be3fa54a7455535a81e5300a52c13c290e7a1127f1eefc566850a26ff338b3f95b2806ab7e532c13d47f66b42cc3e7ae46520d217334b016e16dacd29855b0050dd71b4716206b1514adcba7a682c798194a5f0d245bce5c5b7c910528cbc3118dc710900a31c0817e4f45abd924ad51142575cf3feb6ce6cd1ff1475a657a881f5b8a1427f3e549a771c218cee77fe68a4a3c75e54d5228c672e638f2b978696bea22e343f88c8e2d306c993a8a681a202eb453dd43e38f6d9c8fc1bdfd0b0ab54ad4826f6847b6c8df05bef3be840d080a73915d1046e16ec2943554eac68519a3f65850b8b8bec6ebdd726d21f9d7759037e0a0368050232ad43669bb84e679dd891585bac5178f04675a17c6242553085b6b1f44a1cb1041fa5aaf95bdb2cb6d8f68232b22f20aee7d848b1478f641b1b29820357caa6ea8956a9c253a2fb6977bdc6a3b3ebcd378ebf882ad68be241d73455648e0a83457f08de40e906d2d0a76366bbfefbda4d72a1a9d5d20bc4c17eb27c5196a8b18763f91d0f7983083e19adc22edf18c1a4019bbd5b2a841b32c16055bf5681f4c6f02739a79887c86cc3323b8b3c5b880419f572782edf3b2d64f626b94fc61d06c6ad0a851043a010fb1056e11172af6eca4492ebd3f86e3637b826777280aaf2883ae36adf307a25d5e037fe55ff034970963ccfd76ec6d8024302d0fdbb334999ee7e4fdfe855f71ff2c66ee0f0d8d474e0998bbbfaf3e30f4b7f7d59b73937143c999368fbf93955cc68f402d52000a23f4da19aa1d28b7a06b080ef35dcb097e0b85a05fddd537350ae9762d78b5811fd5c1f28e83e2e86e901b0545ed426697630db75c82c94b5a02ff1ad38e4271958375f4bb9a9c0901dfaf04250e430f7e8485f81bf2a2c12f958c67f1823da551fd53bf9a21aaaa70c1dec9340442071a25e51fd464899caa105551ea22cf65ff606df8ea065cafbe4fd988abfa2c28b491af4f904f5eaaab58a568b2a7cba9a38725cd0c7136dcf4cd7ec3179517604de116c1c77b071350642ed71879fe49c7fb8f61916fe70b000e11ec392bf29bccccf94c99989e32a7779963d99f30c0f58066bf04085c18771eb75c61cddfe1cf16ac2112214a76223d9274ec9ea766c7d4d03fdd24e72bdc4abc5e40ffafa4736b007edbb78af2561ed098e3aeb2f0a5e64c39082899c86883b1f1e5742d538c83906c57170f14c57519d0b4e2e265954c360a6f51ad72a302579548b57e5c74a186e0df044306ccb4bfba9b9e38ae908ff3f132bff0bd0eb73990c9bce7f15167492a7b0141e08bd9e2686f2f7de0247666193ee4d68bd8d28647e8e8458b7c5af972fae1b566bf56a6110da92e00118a21a1f264c5d7fb123fd98841f9bb7b9e38f07ebf43d9d5a1ae317fcd98de04990747484f7621e53b9f0f2957ecbba4992da5775d9aa55cf14c637a150e12a4cce510b8bd09b846a53f6566fe81dec68db21d5245a13aafac45920f6862b603590564f6a12c66b4dc904977643cd60c656124c759b424bd9ec657db50962553563edd1c7bba618bb0437aeb516075069b1bc2c9016ebeed97d7a67f21f9a438b1feaa3e52c13d1047e5a350aa11912fbaea32d2f749210e0ce611717ef19e6ff51b04a103ad55dee3bf483271b220b43ea340d24d0ac1dcf91c76385289af998a00ec512d3da0191dee973a79cedf4de72d51d0a6444450e84ce03178895fe87873893a289189de814def08aa5681435dbd6904ad436ec12d96b98f376c2ab803d0c1cb2cf484d5b38515861ff80d6c0e7bb6e9bc605de76473c0200a594283cde1029317526948598537928be3079e8ada215835af8e449f96634d24b8608cc0a6e991d23fc125085ee3b9dd3b367ac7beff58ff1d3bdf71eb3f6d78c796f6f697688fd3d677daba4c9a2f49f3356ddf25cda3a4f94b37f7a9c69f57db5fbab94f359f49f3356d3d24cd97a4f99ab6ef922639ba23230026941d9cd813ad80208f58367d1b0bae5f58baaf4c9933435f24215b5853bf5ea0e2869fa5f2b24639bfb59db88a94b1603e59f48a56afc915a5092b1018ac6254fbc98bf01e4066c8d3830296e864fd3a5565f0a0ecb0ea7a215c375f1218f9881a33d648d54b0cf6f88c667163cff48b5b08b543119caf5871685f17924989558d6103e7eae3d46a2eb01540917cc76f41dff541cad8b51a6833824c1d4279c2b8b48826b80fc4b685f23b89a619c1b17ab60e5005f1c52c8ebd8b36f44ad4940d4116cfef916360a439c25eae73402cc7ad9d9d21175c0d181f8cbaf20dfc06511aff30a9c11c91614423beea719c03acd1919c7f2c49a1280a76c2e179a549b99db03cee53c261fe669186107d36e76f2462a3d9fa6e71b7e5ece1f43d91ae933bcf03fb748a0fe0ce60471eee9c1ca48a052d930b81b74351deec2089a83bdc45aa80d0e9bb693e3b2b07215230e72a52f8b25d59fdc99d05a9cb9d9f14e78adedd5bc4e5e7d149f4f4f51230ffeeec2c77a5039c6c7d49c8cb78497cc170d6a87c2362fef80a1022055cf875515c896b7d39d7a075b7d6d7630d5ef76b6d3dd68075bfd6d7730d5ef76b7d3dd6a075b7d6d7d31a58776b7da5e30a0b7c0f4b7a3dfacc117732226706db8463417b11d398044a9544b8bb24e358abaa04d63b5fbc07c9f81e6ca45ff8bd06b235e7f1cdaa4c808e56bce4aab1ac334d100721eddb66c50420f052b4b1ac234d2e71fc2299b555732bfc2b1420db6f7abf63bbfb3dd809f48182bfb604b642edaa703b0a21ee2cd64c21889f1eb98066b8363588e6af7041b5adca044821fd5e2b1f266271117cc50208b85e834db5a121b6b151c48b1b5828f67945be726ad0babb5e360c84e17e86b5cb2d34d8b679215f691cfef7fbbc22942eb9ab4e5a51622045f8bd463e4d046e6a2e772411b68a0696d43d44027c65d0354754a1cbc2b6ad4ed2521e1b512f1b26891ba6d263b9aff2842949f0757c71d8334d244a18f55fee2b340102e97ecbc2446eec9122883f3246f8a7cb87355d1d8ba37e627157d8f1ac152d050521575f19d7c9114f6ec6ca66ad5839a6d87143b98f2b423941deab215d01f1118ab98952beba3013c24b61be865f7b1a797597927c3b087ff5d8d5f9410122dc09103c1af3033a40e83f30901f98b8816799e76a0b1a91d8a02167685fc39ca6a11b09d73d46049fe29b5a0111b4d31444df1dab07338614be5eefafb6a4bc4cff8f42402f21f34694e9e2085a52887f6bc1896bedcc6a8e35e166d9c0fbf73b81520a6f48a6f36f21a982190a195e8634e2b4df08802a2f0d0e6ff4c43de8fe64e46e3603671c45cc0ffa8119be62c280a00aa8560e3fd4bfaaba9f169eaff608a46ab60d4fd537dd15b5279c98528ef3049b60caae22b93f0f98a2217693fa470655d89e7af8d1dc0e2e86581e09d20163112be611b4099c07f8c6b10578bbae97c727889cca1218237a4844e8195d6c885b18b9935abd30b91ec2873dcbf5e6596716100e5ceb0d4cb3b0093a6c8fe6acb3222730b0ae52b2831e7b15d5c08a174f69de2d1bc3b8e36833d6f6617c40204ccb5eaca9576d521a026f1f262c70563687359bc830c8948a1e2860b420af495ff2c78ed02e7ba9a39a55907f48fbdc60e913cd8487990af9911277a88089f09bdd194126228e90326a1987bb0d8e55e8a9b0e463f0f72dbe89dd554236464939600c499b4a582e892a9ac0001b03b56c48cec7a69dddaaa4d798ba220cbe954a5fde53c07453cf24f1c8b125cad38ae3be8529df742b246a156c50f2fdaa9b3e1236dd2b3bb8e59bec47f998c90868bb0c82a30cbdb4f0eace1fef20f2ae24910e4e837376e859c1e6bfc7173d7316ca12da73feda0cbe900e12d42985b9ef8e37348259bce71ffc78406fd1e47f3d14e38d9e4e0367b380300c07057730e7af4b710241b3572a89006b35f5e39ca880c5d06f3a129aa1af56053d14a08f9f50907edb52c74423ba2c5c501720454d4249116c217796f51838707fdecd4c9b66548a102bd928c0c1417e285f2434d2f36602a158985a39ac5db4d198609d81ccb3b4d25fad69dcfe30d62e3de2b5b1596c13087b650011a48e0aca186dd8df22e3988ea741dbdfe081f4c3957589e008f257b04a471508fc351f9fab3c495ffdc81d5b045738171105780bfdeab19e84b5cecef6a3882236518a400ed129a45bd04a9455c75182405b3af3b6f3f769c7114d7ca51028495a4c26652ce11893841f3bebd8ade80504e21bb701001208cd0300152b05367a8a3fc0e2410b99dce0812a0f16598464bf9fa3f71bec132c77c8df0da111ea0e39dea37d6a4185114332c2cf3746ea596c60868cea91405d52c8928aa8b957ebf20ac0ba5734d6db63a841c04ee5ca35841eee54d967216a78f9f7f26dd26ea67f64c750b57cc97ee4ae0ee27adae3f429cfefab64cb9ae935d72538c51bdb1de1121ad56b7553395be42b42558eb372e79391c814c4135e8c4d3a9be6de93c5aacbdb8e81243da24dc5357c7091d588e9af2bf07464464b13003f895eda76042aa4e39c74e35321b35838130b5fcf36d37b706ffab154e07e17ce3646aa9978b674135e94c4496f49d0ef47526be6463e40a59e8d92d6f907f0eb79aa3fab0d2b049cbe850c1c311600c64471428b3842b5fc175458b7e75202a7da7ec6736cba74b2b663905aa2d6ecd8f8eb2db6421168a11e99f11e0068af4820e710b0b44fd8353be0175fd66fc69d612236d603ff3e46dda6999a6cea63fadbf5107c3cbe298a674cd003ede1c68d47cd49815e484af5a9e5fed8387ad281b665153ecae6335d2c37063162034256eea84330df363db1ff197553d1ba29eb7aa2013bcb464738a97f1791e3d6b30690cc21974fa25cac11f109ea7ee024a5cad9a813ff366296ddc4e04c9fd368446711da6aedb18b4f286b5cc2c5ab4d2c3956affe9540bbb5eb89351345c506d2c687262a01bc8fd03a6d73e45fccd8de8bcccdd81b3e67215a16f87c61973a353563bdbe53ac62781ce8567596aeb28c008f2e97273d218d7c190da9708180bcdec0216e883c1c2c4144d88553b55e7cd9d89064533578a8f4c85153eb781551eb6663114e24267f4d48c14b9f4ed0e0601dcaf1ea2c16700e88800bced40740bc7cc1e0d660fb1f06bd10af8015f5e7cb96d8e61a16e1ee89b80c1c00a1cde71cb7e30376393915cf41809c7b911e0c02ce6a67ce7ad0713cd124b5dc3575aad503dc6b83234ea2413cdec53166157d820b4a6df8cd8fc1f547501a3abea04ab05be98c44e226bcfa1cd91b98f925dc70576507fb2b6620121ab44facfdab28c40ca59c090e2295be028bc78145bfb32a2d9378ff1c98c1ea4b05cb7997691fc1bd5ee106de83539894dfa1615634ca0bfc3ac5abe718a3818bd1118256faed28b8e00e32ace908a1949b89ec03caad5761ce5a181fc7ab4b162b3586bc989914c4f48fe1ea0b383802f9deeae0bc16a8274ec6061829ab60f7a07a11cd3519ed0b0a267881fbb9c5c6e3a2c3a4314fe6573cc8823ffe8a6e83ad6d7e5156b83e1b80e287e62b8d03c47bc2a13c3e243b74296858e8799e26e4be41fb9dfe4d3413c772f59701fd9923ba484685fb0623337548e4be96a457089cb27b1bf1e03b385020cb8d3f79d94f890dc20b8d66f17c90445c8382c2bf5a7150c00ae6815ff129d8a52381488e07badb53141cfb3344c03deb3a33d09720f41b2ebf961ce0b11604071b9e5a797458fee3dadb3b0541a797b86b474bc30d1e85bd1e91665c811fcc421d93aab1fe54a4a65c12d4c6b498825d7456907addcb009f99b916c8d1e7a1128fbe83df2a76ebd11936f042916b295c21e96a5a9d1431040dbfc08f2c8320e205cb13118da36536e1cc4fbce538984f1d4f1b808da50a4472d3016072c59a1634107ec9337ef3d16d2caea6cfc948c3500b35927f4ca7089a02a31ff82e629550ca4d5dea35fcb42645aa53e27aed4f3c56bb4638b163810fca849adc885d441f8451d8cf702c0bfc27739842ce152e17f6ba873b228ef93530fae429734226bcf7055c56d852109c00750119e9339637e2c4c61d9adc69c3107647625b957120c570aa8e8ce2d6b2db7074eb0f6e1bf7a77826ded042be3087c350be23d33f474883a2533d4404700079908e21d656952214690acf9b34731318a7896ad5666b1553af19578394da64db07ce91f66650f0c44803ba4de635dc130fa7dca3da258e3bca4e72fd71849889b4928d4411152305afbc73ee50f1299fb9f9f676dd90743fd92bb68796cafea083474993b954720e9255463cb2aa0d380e0edd6beffd199b3d55dce289cd4c33a4c759ec46ea461af0cfb9db3b3272e1c536fce8cfb20d88d1b9a70cda750b59a31c8e501bc99ecd6befa9f12967e9cc139e5c926246c4f525e8a5ba40e3d2603012e1269be6d4a3d2ab1b91d7da99c250bea167d771ccef07413b58e48fcdf2816bb1d525a38b552360a026d2a611e8a5ae34f3a629a74eb52b68c2f562ff4c20dd063b0b608c09a7dfa298d2ee9d1052e527d023a44b2b0c0868b460967483152a116e723eee5262e2c94327a885250f44c132a91af110ac0abccdb7fc45975cd286d180f1feb4f4b72ebf877d015a586b00dbaab6848fb654be0fb8d717ee6045666ed41e7c308808905be6d06e7a0f89df27b613d412c407e9140002a3543fc49ba8b37e988a3341380eed386c7bd42e0758ffc92230f684d770c42d70037be460254da2f9625219eb16b77fcec0f1fce6b29e90d349bcb464efe5a622028916a29701497660c9caa7904094ecc142cd7bc43589f35aaf84331587794e2b11da234ec9503c452584476b28a194b765679500e57f15eca31bc81119df4d778cb77788807d0c08ceedf9ccda3e9eb8c0c0e151c1bf6dd4ea3ccdf67e915b688f554b9ba6dfbe849bbf8f70c956b95d3ce57a86385353a864374d91882727237f7cf1e8e47c68a3a5964d2b2f9483771e11a72668654f10772f40abaa93943dcb28be1a188be2024a4216d88daf0a3702447c9aa22bca1f3ba2b8d4a226a1437d2540ede494c4fc8b92cd9de0435d5fee3fbce3710ba7f6d2fbdc0e0711fd09e12ac53c4533478c5426aa95b353ba2cfcc3f497948674d2ee66c822d2327338bf33e698329a941af681b24f1389261190c855d6512dba747a952e425292645321c480bf3df160ee894383ad698827c11a058f18b795a24091bb34d296d55c1764c84755c3a2637c1291e115cd070ed49796b95d1e6d6c0251b802aac818f6a172fdfa4f35f2956e3914659df952156bef22690363505080aaf260667dfd8ccdc40e7268b3841f8f3d78caab0df9e44253e8b8a5f3e26a46582bfbd6ef6c53fc258d53f9a14e04ddcb14949abb50115888dd2adad44964f27b94aff1097af27a507d96a9498eef81c7f314b2a906bb36455bde05279774c460e98ff37c6c68bb425867d3a52e00e3ecb3d93418f86f9d1392c9dec4f092730a45b5d4548d3be03ea99705f6fe0880edd805c2b722b02d8b3aafb336a8340d8e500dd81193abcb76a2659403565a1464283c28a8d25a309abd9593cbd766cc39833112490aac0c629b3d07f51d4733f7b57abbdc7ad79c98ecac2e4f9bf5a5cbb1e7d9940c01c3bb2214f675dfd3edc328915fb1ecb2bbdfb31093dfe1c05e26beb8863acf83152db6fec47b81e9062d7c14fce2ddd5beb200d5e4d4115f68556b135b6f0954bbc1c2e85f4357321e8436a5480349273b935a9fdeb1820092215309c1c5f873ece10713d7666425e2abd33aeebb466bcc7c879833d7159a1503a3758f636f0062a24986bb18f8cb10f0c7fd4f2acd7c0496293cd6ad97cf47941785def7b7b16550ba4f26d9fc4272299aff73dd42ea8d0c93fe66b2faec0fd8b0f4f79056b810d099c2fa17f66584a6dadd7a7720af4e115d9b77884477dc0aae73f5231ed05df2baf6af7422b2d8aa21670b768e95e404f230ea82f7d739169529958a05b9cab3ceddb8eb21dda02f68b567fa2fb9440f813e892c547e5031f55aa2b71d67192e0ad1136f09bb52f23de56aad334cd46b3f82de6645f57b91e9a2d94627de5d0699e4f7dc65191d593bbf7982d173eec1d876de90957a5b5676aedf8eb0e633719a027f10c8346a4a0bf38a309fb04b38e13403ec49222585937fc44d54983f5bcc14155dcb797aabce79738711a29b53e768e38404a7f0e4fdd2180e744339e748644265b6224bc52b9698225fbe532c3a85bfce1ee7365ac25c03a249a48b88736aa7ccfc03b6f436b09e47f5b901e41a8c5659f19002d5eab3ed3332555e782854c23ca25047528564e779c5f08232ad569fb71165132c5d3d5cb22489a3d94ce9a6e395e0529232e420a3f43108eb0bdc8670396a43e1de9191fcbf68192e5118d4018d3303658b25ea3ad12faad2098efee02acdca6fee72e6fe21c65381265f76888f18f7efb46cb53acbe1e75982518d91673a979e78e1bd5444839ce90ce3df15aa7175d1b3494f35e94b008c6385c99a5b34b49295a85eed59e75480ad81505fb136363da4a108965b572f9cf705b30419c869878b1e6687d27274b412a2272ed9ef14abf86e713c25fc28cf207e00ba10632188d61771421e7dfcb2bbbb19687839d6a090f20f94e7f705e2d491431f1b0c701d8e25a4a2dc23af4ca68b093fbfa1e520ddcc69424ca08b07897219c7338153a180282209d7821bf35a44ccef8e4d0bd91173e2e58fab50f9c48f58a02d48710997f279082f90465e5714c9785330697fd7daa80aa4bf82a6dcbd5f8f0c91cd57953a0397edc021bb85a26115d18c325eb7526b5962b1a323ca35eeffbf15c0e2a49445b040886b10f3ce90d2468a0bd684a4195f8a68172d353c3540e945b5b28db2c57534090b0a6e0a5caae0a81e26e112c3794b40a9ad860e0bd1bf71c9ce6ad1accc58f7f7341fd80213cbb927d105270695ed1d3ccb021751a5e5c2dd73236b764be5627fc669209ab679134f1665336412ff38baf542fe8e2bf5299431f94a81bdec244a4d7f9ec863f627df833aa949a5fcf95949af54a2416776ed92c12611daba3d024f76e70b05396f712c2043f008a782cd6bb931ebcf57e76db30835b8f3eed676671f88e326e48252f8706e9e7f6f7f9c583dc028c715a56f22f3062ba79ab879abfa56cdee9d45ff9e5cb22ab05ec1d8e73da4d802a4d0c796160ec2adcaf1865e679d7b2799d28909b147c84d3d3e49f832c4b78a8d4f43131e314289c20e0d7c046c685f30f5b24964227407d309227cb10bf8d03ec4faa8f3c43ab350e706417d3092485b38b701efc8b49852751ed3b0c42abc5f47cb9d0cf849f073d12f8acf442117ff94ae3359fd4530f0c936c2c67d33d68ff5000f4f7d5737ac872773936c9a544e61da4a7eba5d2e9016d0bcfe44659c0e639373d690c066fddca5b57982ad13a58880ae0c2a7b17ef3a10a27e933372db79c39c529f32295ccb2fefaab7484aed35050c74e76bd448280a9976963f5bba21ff1d72bfac515c67799857674fdc0896f814e05446ab0599b4ee1716f775196e94c6de415a1af2689fd89c9fc8c48f13895db4df34749bac55aeb4a9327d9c71a3e04a5861d4dc0896c5ed06d7a3ce3712361d1f4e212eaecec7eac8d5a1241080c420bf95997d7cd9755045bac870a242246d1e9b79fd9335ef6e9e78ebabec0696048f20f362fa23a95ff4dc39b5fc58320508aa19ddf44dbd456e743867be551fe1435dd357df4bfbbe4affc0cc566022123aa8123f699d1a3269ef9f9e59326b036fa0a8158749c7164d9a709c15e74c2c326b1d7eab6a654ce06b43153d529a160579576b7a8588cc482eb382b8a24285c58019c85063ab5151c84edf9665015cc9c249ebdd1149b3927573301071b6f66233c0fa0b794a5c490e3abb32f40c026482c8c69c310001256b038f0871c22af30b326aa7cc7e4448eb8b62a152da6f63a1f4e3a68aecca017b38daa45f9de8c663adea15d741ff0b4c74c1f6b42c8bd529469c52144a96e9c4019f17573efb3e1fbb6c18b975f65887a7b87406fa09e2fe5b83e1520c95ab8c4e893b5f20503bcd4d58b592a7b1c5790c81fc4b076d6b941cc17a0b3bb37a2dab9e5c2fb794964c43e52bebe9a0b23dc09e038594174211c6b6b05de8dee9de31d4f3e0a265834f06be33810ad775c080c7c9f61434d1958ec132b4bd50d2f2149312187db65a3c94087a6fbebb4faf3fd3354d365a90a0319c16e87b5dcd8286fe41c8f817d4e5af1aa0617fc040968788035bd363c1d7951ee8b9efe10b07cfdde852d6a4584b70fd7947b2f27e2dece7a1e99a01c61e973e6faf709e881db03e888fc0e0b056a93f0801a42820ec7cb47b05b193bb771d51591402b7ae82c15e4bfebde38989819ae07ef8525edb38785c4eac20e80cb590990d6900503522606264f26dcf64123c30aafe185c392ae341ee4695abf4c0aa1324ea15e8027129be381433a8213e0d0fb1624dcfe0332099c58c78869b21ceb066ac32fe0c3e0374469119cb74324432adcc75e69fc9cd84661699b14c77a628d3ca5c65d25703921c35239220f3829cba009b533db19f834c2769f439e1dad0c38660ba2dafb7cc6883410b9603e9fdc866b1b5c428d9cd70af78ed4a3bce27df6e20d3620dadf89c3be500606e5cd917c13b1ae2fe50c0e3dea50ec6e6bc0d609d652b2c697b471eece9ed048ee0bd7cbfdadcc8ece464f20260b42919c170e62c014bd4d39b7b6f13719d1a3a08aa359b1c03ccbe4abf0ba567d09a7e4979c36c9ccf7bb8df1bca8a5117d772638c6af17b92f88069e566243e9ef5424b57a30485711750ab0732adf99fd239bdbfd603b133b078a729f48e3ed9aac0232ba5f86bf463acfb0d9b2303655520163fa89f8f88d7deacd504fef37d82a4034dfc021e1d57e05f5ce7c376aec8eaf52498fac97524ad38b728e51eeddd13c3dc2b8919a5f1d6d6f100f6ee7a96df6e80a59ab4f3c87d7be2047c67225c729877f5c5ead14201aadf0529a0ee525597f40930b9c4a31e5d052fa0947bbf814c8e46eb952475d32379fff7fb8ee6eaee478b743044a16e7c457349d847a4dfed91937744880e83c6c8ce4eed904a2aac0470769ec4bf46d1acb933e6600a063be4eb1e1716aaabba6fdfb420aa12f42c83ffd017c31ea0240500daa13224968e9298d5e498980dd9a1b4478142411d44c953bf855d08160334c2559f5d247ea1c83f4807e0f898e51ff894ec10775f1c78189b327403a20a663473a523c53307027816409ce69002e6cec82c4573d04714d4a0da019a52e31bdf0c88cf4d4080fb20df83babd801e8fc96d81ddaaf12122efb4f9280a3051c6a744ea5d924435f80943dfb5bd86bd4502faca8561c6e5a0096665ed3204d880d588554c250cbce07bf12a4f059211de24e2026dbd6a2f31a8b1ccff2f9f248c25cf66c87e94210bab4c4b801926d259ee3e83a10f9370c640a400ddcc01852df99dfe9329cab4325799df4c3e139a5966423c3643e374aaad0ddecc413fed453dc9c48d2bfd9e3c01ef9779a6d2eb5497ec715cfce5adf00960e8c479454e09cfd44062ec3cad503e36878418784ebb2304e552e15e6c454392afea39a6a965f65036e6247ce761a95b82b3ec6ff4e08d62f024b9b365d899b4ea1b51d3df1f686004d9efc000f1392d30e39834565d94267886814074cad2f273678dbee27a61c66ae697c9674232cb99f1cc6ea638d39ab9caf8338977010969cdf57fc161848262f72775a4e024b28bc3cfe7950a46e2493bec3d53019451cf46ec9bfedbbb2d7af5c34028c919137d008b3afcdb29d1c41748898a3fcd85338c211e058c72b822750fd789c40fccad59119f7224201975af948517ad1f54c7bf99f12754035f4545b18f1631a96e5a94550276a67dae0530eacc22c037cc7ead31c09e5e9c11b921fab16b20e70e9b62d71bc889bbf1a67d2f5ec90c1cb73fbf54ccb9fad7c3e5e0b1fc199264f004d1d1c83913e66d4c6031077afb64a5f649e47123b0afe78187e562d43bffbd3bb11c56046a94cbb45a3092324a8b014a04263eabc2fa490c3a14ba5634958289bf65108046a1ee48cc89304f6ce3740300983b350232a7ab081240008aa8000cb0629c487d61fac490c75793d41848fbba156e58d117e38bbe6d42884822422bbbbb77aa0adc0a200b30bb37b3eeb36c230abb4e3b90b383e82d686180275ec1f4c172a80d593266cc982a360da2033bc0b3a90e9a3a12f9d059d6e57bacdc237f6f84b0b0a5d4568646222a07c9cfeb1efd8088a254c8f64e809bcab67e1a026f956efd5e59ce712e1c29dbbafd8d01d1beb65f21f732a7d6e6ed183c36f3f74ac0b252de6ebffd667c2c975e046654fbb155ad084c5d9b450d87f6fd06539826e4c23968fbf552eeb6639fc9ddf6bafdea86f6f6cb6596cc538875493abecc9d76695fad564416b9ae1599bf5b90f74ae84ac8e665e93677f2b5a44f43eeb7df6f97bf7edfbdb24e6a19283f731aad88f52e7b775d3ea7ca93f70ed0d9d7d3dccc7d267732ba1bda42909483b6c38d739006646873da6a452c9d69f84e8044e06714032c5b7e66ef840fc00df7c55a0486a02065500b82b51ff32464ce2db7bd2504126d3b0511d1b62769f78524ef8888680bc9ec7b2994ed5bc4859d24851d5f09d785eac6fe0276a15a84856ddf136f4ea223490a1b4660685bfdde8e4b77d3e6a0a841a067bfb7a39b7f525bdacea90408246e1967a2c6030829953db5a3776fdd3aa594524a0d352d48e9f24b3dd27ec06b93f16bc9e6a6130e8ee778d4805c26a8bb4bdda176d59d099bfedeebde7baf1c14dfcdbdd70fefcdcdcb8028dc43a1a8a3c88dee6217f7759443772674c1a13b541738babb0e4eba335961e2b1a9b56af8d821e101ebf55b7537f196da900a4aad1eca6e8ad99d762b07951ec3ae136ab7e4ad09666bf0965ea359d774378fb6f6eb3b3ad90642f8fb0bdf452d14b71c42972e5dac74b0c58ad71d6043edf0a5cb0c7377e96bfa89f0525f5fdddddcba0b96c39143c769fe1b42e46b11f9fa05a2500f75ed70ae592f715a10589287d68d5f7726d05c87cea171e8938eba5e83f1271c2d35794d0b829f41598fad1bf234f29be4fe64fd49773b5bbbd57e58940aadfb26bf7dd55aaf5ceb4d49abf3cbaeb7b420a5df6b59be47da647c5326bd265b2fe5b76f649abc412b5cb6f21e36f198b03b9e194ce6500b62f11fbd0ca73b13505677a877d47d534d7726f866ee8e1841d8afc35986e4911043c2635fef90f080bf970e7a777542f1d25dccb05f7a9611b78c3e59174c300185fa4d268cad1c5d48786ced1d121e96c61dbe9bdbd2385b2d88f6202ebba515c9b67668c588894d79ec9d5d359de9590634a17e96015178f3e85e1886bd2762d72c03077ecc115cf6f733c222e6082cf6ce7e464704b1b17cd905d8cfc8882c49ec6cdb5b176384c4144648f46074c417232486805e32febd77de6a8859dce72116ec0f0c6ccab4300bcbdcefb52c6859d082d963d8d6d326ecd223ad92a67b22f69e0883b46732b7bab8b3cbe82e6ead835e369429e94febd0b2a60ed29ec139a48a01866d5578ccea2098ddd5e720ceb25d200ad627fc5231cb71b7ea7cfd7da71dc3f43d6631dd5d2d143b4d0bc56d593242b86399bbf593c163f3947dbe5a96f579ecb00b662dcdeb3c8759eedb84af1d8d2e4dcbce5ab21e64a7a5e7bd53b42ccb6f6b9a9671b04b10eed86b869fc9f732797bcc372e73cdad5cdf7e104b44d5e38c651043986130200a35098bbdc320f607316de5afe3c38cf5c99e7b3d0403a260bdfe467bc669edf5f73599e3742734b7dcc12476d5ac67100cebd9efeffdd47e5c9d27add7755d97b53404039a50358e3345f834f1a1c187069ebff703a9dcc74956ca4a460c5104162392b0991a3c3e4c302ae74a962231455c01c3cac5529aa44e943a31a61e2cc19cd856cbd2aa8afd02ca5eadd303916efd6ab9df343cba5a45b95ff640dbe96bfd3dd0ccebb31bcf8e5934b74e225d46432d24adb22eadb2373b903dfd26f3ed5c259dfbcc0d9a9256cd6c1b0bd92d771912d62a4eab32adbadba56955762f4bad8a5d7fa95aeb65ad4a533343305a46b82fa78b160fcd8cfbcc5b420f847dfea5e051d52a7a5907baa7f5f340f8f59816ec9a86479856cd22a0edd63a90f6794a8f1d48e6f4170bcdef2f0dbb489d22a0d2ebf1757c12d6aa6ab5cad22a15f6397f0f647d5ea342baf64dc32d52a708087fbb8c56d5cb9c46432c5a453fa35532da16edd8ad6641ea1401d9df5b5a657d3b4963ad9ae7b44a856995aa48d346544540b647eac85b8d5d90973af2955efa488b14d34e172cd86e49d5bf147df78ee65f8a6a8bbb581a6ff9a3fa4dfd24118c96860b534ffa98f235dbc70c546fb5cac69e988a55ab4c26a9536f81e4ab56d5cba2ab5a975aa52aba5e64646a154ccd175d7f1a903cd5aa07243fb5ca4a1d59236c03550466c7e7ecb0f61dcbda6fde9e656e7b7c3cdc927b7615b867dbef55d87eb56357413bf6a1d304ecafab60f5139892f9f5218e84bfe13b4921b55dcb4c9ec0d4762729a4647ea5262f93ed650692b9d52aed32979ad4acd580b6735ac57d7b91bc7699ccc36555917c9111ac55308581b893b4ea40dbb156a186a4812597b36fd86dbeb4c54f8a92a4b061ca92527752485627542b819b1ea6bafaaa95589b56b1979f57da1058abb1d4d1b2efccac7d46ec558029abdfb352075a4db46bb46c2087e42d9e62b2a8fdba3c9ed845eac0ccc489cda53644eed823210d29a4c2d81cdd78c1f993ff74d210c7da1b7d64a3b5cfadfdc7b549306cebddccbb3845bb0f150d30552473991b7329ea1780721ce74003b8cd1fce750c40e750c1ed34df4adb6f7cfb8d9390eda56f2f75f0509bfeb41f35ef89a6dccdbc83473b066c938ba67e01c8e63a0e94e336452f009d6ef31c5a877e365a65f3138eb6093a09a139769a637f36f9a56a7212b8a13e09c17ee3d86fe82490747c9a9c049e84602f1d7b69460bc97d1db5b9c795f4d1650b0b55b8a02a02b239ce258e564122a9230f80dfdca40470789b8c7398816c8ea355f936bfc9aaa1d40dce6d3e011cfda4cd578054f45fea462e815832d402b5489d7c9be348f805dd431b466d852ca36ff2504a77db2fbdb38cb512b93bd4e6b290bab50b403e003927c32e52471e00197a913af2f91a86dd6d7b2b77415047ddc1a32953a6c0231d978761a40f9ccb9b9fa46cf7bd94ea74278738598573277ffe4d56dddcc99fc3263fb13905a2e389cd9fd83ceb27e5293fb1d14553274961cf2e4e1d74a3b55b82ece32f0d29a4709ee3545bb7f949f504472fc1f197bab98e67312ba94554f685d9933e9cfc38ef8424cfce2b22cad6229f51519638c5a58f25a7e3e8f8fb7b398ea38ff3d33bac43c771deede4c088d459c108fc52375f12c3cd7368a29bdbdce63a34963aa78c93ad76e4a56eb4207353ddc92429ecfb671a5248e1b80eed04c773e8ccd22fc44db5131cbfd14fea58c7749739c1711bfd322d2437d54aeabeba0a0e1d029b47266c64c246774aea9678cbd441554e0fa27f5a36d4805409c1933af14155427073aa05e7383447a27d677e5af62987e0499d530ec1cd2fd48cdc684bb46f34963a5af6d37e18b1b9c936da9423d196dcd08d6803834b4f9f16e47bfab8cdc9d2d8f1eff13d528333e06e675ec9b2a3511143eccd801d1f59708784a14b185db9120fe36bfc43e105b8e77c3d5e885b28ee785a2bad35cb737759d42a955206f104cdf20427ef8cba1bda743f1c7bc877f433a29e90f820aab1b6304281d0e80543ec9c1d8f9f4cec186677d99ca71d0da2b793f422ea4514d402858bfd6e08b3dfadd480d0cb274fe7e5c4af43e41011d03d7710bdcc721f7c023fa32b416cfaa17d279d55fbc18126a081230e44e1ed781865acb187d4b5c99023070c31634728a18c5a3c34a3055eac8071c10c5f5c90c30c5f66a9647201510bc290b103d5fa2394d7af943956692ffb8759ddc508779cf424e98caa3dadd7438bd29f2cfda9d21969ae961642985da5b4ac84c165d34fec198e3dacd76a59d5b22cab5a41e8e76306ab65595788868f4b3441da9951ac6a1df6a0995dbbbbae2ef0ed11bbd29c33cf5da2b12e5f6365d376396e0f65d161ccee86b21011ed0fc84744b42dfd4215447b5e08db42b4b1d2966188baa785684f7d039a204bd004791f2e30fc3b829d34a55782bc0f0f6489945919cb94302bfbec00d76cf9aa01795c66e95e34a51b588ebb44838928f6127ccd27b87be4bdaa6edadbd33d5dd84f14ab15ce3a2d8c6a43845842f022842c1b6a4586b24821da1f1882020bd1c63e35209209a23db110eda993c830441bd35b064d905c84f14566465e73461fa6a823ffae27c4ec0c570b5b8cf185318cf1c51acef006b47519d89d7d166db869e7c4b0398f6113bb5eb522f4071c02637f112575acb5567a693faab66244d9d967ec31eb9c191372d3ddbf9bad1718fb7d0cba7a48f63973dcd3ba758ce5ae1ebbcd1d3cd52472df77a76b7fba4ed4fe04ed9c70d79c44b5e7cc92c83d338d01d1fb72d9f77766335ffaab3b4c77103e2331b2ecabaf5b4df57310574a217bc8c2f8240c2cb6a497f944f7ccdd65bdab8f97f9746920d83ed993a581601b560d04dbdddc3d12268952cf386461e4010c2e1bb59f1110b6ec27735f25651155d28e7a561662b67c263528f20adc590d4a0f56b0b4e70d565136fd4b7f76ddfadbd3deac70043e098953d70c37d196a7a1b26922963df39acbc72cdbfabcb2b3d7283b3b360a625bdce92d1f1c6d23314658ecd2f503295b9ede53ac0d91a756e91de9665a10fc6326236dfbab655003e2811a0f5c571b32f39a739a10c6f67ca75d83d9a605d1b4470d88bcd613336d08cdb57395be5a3988e43304458783e0d3991f33babb4e2529d7e88eb4b16fb944f2c00e9a1d69cf5f4d852f0144113c08e3891a5049bda7c3fd6a42ecb65eefe57eb30c6a4068de13e5397a92eee6afab46cde7da57101008c140b031ddcd9ae7b1a6bb6b539c83e4e9af1c440f827d7347b51fd8b55f9a6cfacc37aee5a01bf5ef9570915e73d580cce3530dc8bce58e659b4f43b8d79c7bcdafd5e60fd367ceaee5a0fa20ee9a3df66b5ebf5a11abbe47d61c34ffec559f4c1ac8d0de7e124273ee34e7ce3dd7d3e4acbe26d7675b7c4da689f336a7b9eaa0ec9f39475f7a8fbc33abc9d94d90a1bdbd27d2607327ef1da0a3bf87a91e69936fe43c9383b25f92e6c9a72119a7738ae8a04cdf4460088a18223034b4a7de349f2128b420a732a374aaf692fdaecf1cc37e9a100cbbbf5776a1ba9358db9ecb9624d1e13304c5be316c8be96b685bddd18d872604bef633e2b2c514492378d9070bbcc21158c613e033e2c1941de3e6031e3cd9cf68074fb68ffd8cb8d8b22ff778ecf460ca8e37ecf81d69823e55e0ee61b1230bb1c7db2dc41e6f7f73c1c4ee4cbb078bfb66c026cd86cd458c1d3f23f4a902c32ca29e7e2eb85c9830e21204171bbe5823673fa32f8c76ec67f4c50b78ec67e445128cbc08a301fb19794184175066c21061e3926d91624b4205333918753183cd183739305a25b139a35510373e5b30fce59ea9e6064d6946c666ab35c01ef76d1b7bc4b81f7dbcc0106ad94aaae6d305967f72eeec6827b1b612198dd394d4fd02ecb295641b3e42a29d24850d4f4404e133213db02fde78691405131ba394d967015316e061151c82127e7129d442058a24f68dba8a1da969be2730ec37616afa7829303b4bf95a9a5a0d5ab0e83735adc5cb8ec7c981526e52cf1a5c1d171e5e8950f420c54c31e8963a85c584b572cd400a26e67e0a2f99932e506b5245446d4cae2cc0ca02701a0dd8eef0441493c5d7083b6639daf19130b76163c0bf1b599c88da7e46598a30ca62454a292735ca32254b0f27217277310c6da9d3b82f5e98868f12f8196561b28d9cd89f10ee236be024707f6068537d640d9c44fec81a98d29c84fec81a1848f71d3724028eeffede9135700486b68eb7032a312fb34dff8c9c984273a8bc2296c323f6a8c73d7af4d821fdfac5b23cd57e5c52c64dcaa87bb96c71b96e8d6e9ce12b61cbf437d8b5eb97f643bbb43c37766193cb736379665c965c8e5bcb33a2b80c71b019b7d91cf045a9eee22d9debdaa3d0dc99152d1ccd6768472d3477f6a90d49e14554a6579e1bb3d64a4be24a0684fbf9f480312ca706dce5f098f3d9378fd163d8c64ab201b201f33636207ee6c41ef41e7ac9e2e9883cf709c46f97e79ac46ffa491ded43fbe66eee8bbd667b0ded9b21968d09cd6da5659f96215c1adf5d5dbfdd52d3b699eeee0305773b76ecc41ea4d3f3883d644ecf43cf80d8033b95c966f28bd9b79c1ddecbdb4c77f7f5f038a2b444335e878427e6f79e76fdbd21295b3bcfee20b0351d943dc8ba9d5da63b9e6e6edc3da63dbe1dfbfd7af7bda7bb2c83f2b6b33b66569d6f66e10413aa25c90fec36890630239b5e66eb953084e9396d86e2660fa560cbbf1f6ca9e70786f69c6036fd69883cbdd4948b8d5d5e3b4d0ec24e7399dc61979181189bde5a319bf9d47ed8bc5742769be3d09e43fb69256bff6bb395b15f995bb75a10ab19c1891127d370ba1398bab420d664adc9866a45e8eda515c12ef5b5b22b44fe5e18b520327faf04adc8c46e6ff569c8b57ae4cd4fd7b2bffad37ba2d582d8cf79530ea2f9db597ec1f41bf736b9db3e6fca45e8adeeb0cf4fad08fed4da7ba410ec33bf9183bc8dfd946d0ed23ef352ee667437b42d1d359e8cb91cb4698c5ed3f104e44d61dd396766efcc7eed85eabe2fdc6cfeda4fdd13b1fc0168ef95410d88759d5a9739cb41d6e9eb6174a2870ddfcd4b6d75aa0de4cddd13a99604062633c840b4df43bdf77650fa1ff8a993a87627e16d62a6c5a705ad4f9194d5446db5eee19bd4d62b77702b91bb8361df5c4fb51f58dcf6b2d9943bc722dcf1c8f7c867196e9f2839560605773cfbf1ecc9737858a580f23c1175b3ecdeed3de7edb75d78b36bd91521c4aedde760da2d0d7ec76ea87110b87b60b6c9070b32c6fb1481dfed638df1736eec6218b6659f22ac59c1c2651b75344d9bb21f771ecbf657b55a68ce6d4526918423ea08acc522c1a8892d464d54f11e693fa3269668c2ca0c32ddd832ccd62619b810058a8126a66c99656b6cd9c4932d73b6bca4f6878f11180585a4cf087067badd6165c2b1a26559251f1db00987056b032d4014e0b6ee42ec01b77521182c48148b8c98a8623fa325b8d808d8cf680921362ef5c499a38f11f552cf98f948c1468028c0c2065a883d84c0713fa325a8ec791983b82fdebf0c4f29f50102cfa359c63c924189a39763b31b31d5aea7afb41f4ea6bb9c5d75b763bf136cadb5fa78d5e7090f243cf6352da8d5f9c4bdd0b2644fb4d773a88d550ad118639c133ebae17ce88294c923112d2125065af6e5e8ceee90f0d8f3f2c6a3a332beec38cb984747b3067425a1f4e161461f1e84a6d034fa118459ddc10e7642c772d0dbb283dbca2ab4349079f9a019bbc8a6e06e67c78e67cfef80104208a1eea60f098ce4a0debd95e4d95acee094b81377f68ebcb598a6746787025127cef9f7697d90c0728a979c9c1df2393928bb6b2e753b5d68ec0207c7c7066c21ac9f3825c0274874824c226ac318513b66bcd5f19635f38df3cacc850e6b3fe6a7d0dc34967c6cc09d9d2998b562ac5dd9b5dcb16ff592cbf354fbb14dfca9fdc0dcdc5a76b14b88460eca11cc1ddfb4192e99700ee571c6cf4e739703333b5fff4aa014e7ee1bdb6c4f9a67f3d24dd76cf2bca5fd30599bfcb629cf5d936fe45236e5998c31a771af5a9e3b7bd5523ae3e7900952336e07722e8d992c0c43d4c0046c987a086386196296b0b2061b526882a862030f65c810c5142a68620662d068830b275eb03a220c3163600d88169c52fa8c52f8f3849e01c69513f4703404096cc03fc06205053870a2881c526c6061e309ed87ac34460b2094e8a1073ffca00bfdc28a2a3fec600b94236449d13f2236fd6483059b629b6a26d894d29f1af02bbdc6046b30d93c70e9888a2d18cfc07a9d300e2e9974b096b59a071038dbcf480d317e82c0db7e466af060fffc80adfd8cd4c8c136ed40994a18270702d874356ab03b941937c6287da4640bd247fdeb30f74a88ffe1e8d399da9e1fa076d349a54c7543120c35609084c7c3c363d5f801078f87c78927a46461450f5e7060e249096cb072042d8898b245eb41a64de1913e06a082308e3001154320c10552b280418423c634d9a1862a2616336ec1638919625b6290a0b11050836863d396aa86981ed610e2470a1b566ccbfaa9e12787348ed688b286939f1cf0b3918c1b1aec00081e7800041a46487d061cbc8499410c190021156fb2fb6962f0f0dc602dcf8f0d3f5038a0f920447f9ce4fc38e1f9616294c616a3303d48a30bf7839f26f6b49f511829c26489d3c87cbc668409fcf5d391aa27a09d8e544dff04a6a85661f54f608afeba848fc6b9a566369259f0d2f32303f61da963e79fd4c1ac95533e2d31bec3f02f25eba9d541efc8cbb53e2ffc12ecdc6f5e5204849dfb929821f67920ec331efba581b267d7be452c75ac9f23d59cf49a5f550474e3f1d63d10fcbd40269336a2a156ed481deba4d7689275a89fd4c151ab2e75acdfd096ccd9b7accd63079ac7b4aae8ba0a7ffed240f29956412952c7821a6b950b52c7c274d42a48242542add21e559bcc67a0354353a239da56094a992f45935545464aa4cf6499bca408e86a48e54bee57c801d6108bd4b1acaf6004ae4b54452abc147dfd4b617a09fdb33eb7fc525a965f2a1e26214c1829fbbef8e256e5138029aa45464b892bc5608cb5df37d99e9d6a409ad6409bd6b266d50691fa0d6d99bb3869507d771d5e0a099a41f0f55513025fb15f2cc331db3a062503785873d60a4b1485ba9a76ff3e21dcb24c6e3bc6e00e854265dbf61e65f46903f3b08f6b00d780274fe1bf873397c7ecedd97be2b5b44d4b9d2699c65247eabc5ff1d2e25aab72390216bb621973a78a9d6ae3df9a91b8d3079d86cc6f9fdf8e4f7acc41580b459a83b6bfadd993722714b9fc620364de09c5d9c9e3d7cbe4274fc97ccb9d6a6f8f0d90d1aa171540af92790c2f2a80f41715b09d5e6a45eae33d97e57dda0fa1b8491f52159927e1cf5b1a10ed5867a7997bcc5b50f6eb5a3e0d99996a774271cb5aa14569edb8484b6074842f1b9e7277de48ff220ca2879a107a38b4a150dc301275d9ed22bf65490c33cf4bed2614943e66c05296269aaf40181196a2b0ea253158bb83a49a486e51c53c1a5d7e042181b7e0a50667c05d0e8ec57701db96ee00bc7cc43a80ed77781e303a0889bccde8195e26ecc004a388683f3985c584ec6204103190f289ba9f11981658486ccb3ac3cbb6d9cf088c1430360491936384397390f0a0d1019e337ccae0f12923c7886d5917170cc6edaa22a07bf82729a4b247ad2a028a11083e6ad5a6b1d4995aa59dc054163b7c0f7f0f7fb17cb21f4a41a293d52e489df9a1d4933a167716a4cefcaf675715f5489df9edd7a6554674a6553bfa1d45ec2f05532fa5a45ebe94953bf864cf200ec8ff8c2b318b294c70e58c24a8119e6c7a1ef497830fa2c24bc177f8f81b9f561519d12a9882b76e8f483d0119ff04a6e4ad03c5f84b337192424afe494f362275e85f863b5287fe47066c5f0464a98a4e47e0df81e09f5615557878ab554fc227bb4c2d9dad17943e47284209296140599da0064564217eb0c611a41c0104a3302d905a097c8e78cc0873860f67e830e56698ba312fb1fe34157a22cc2f66eb50fb80045eca52e1a59ad49042cafa75bdc91091f52881a1943df2524c2ead2a3262fd4a595033c2e464245e85978a9fc0e9087c3c10d445404055ab6880a97a4c3f81a97a38e3dce8f38ed499bff2d499ff91614e2b25f7857166b46650abc04bd95f486bb4e47cd06e4de012eb4d2c5d430a29b8a4be49d535a4908a46628c3308a324101921218a0f12aec881064f6460838f193e60b4fd8ccc20c30c2e46b0651dde5afb86d8f111bb0bb833d94e685af9ca42b3838756ee5e979d15cfb77d5aec398eb3eeeb55c5b6d8614e2277074cdbeaae85fde35a427348bc0f1827a986522423a4638e9359526484bb8c560da5b667e5d3e9c8fcf609985ef393f5ebdd50cded2f292f914540f2a52fe1ae2a02229d7495ccf16bf209bee62fb5e513d4a723dcb709c8d768bda4a6871d5f9397cc2ca9f976a89d8ec89c3b90cc395b0435d0cca5b67989cc395d73fc91add4c13e3316cd882266c7a9196182f592224bca9c560da548b7d908697efb0a35f64f7796c9a6554546b8735a055345a21126f8242bbb108fcc735fa1c6ea3292d8f156195fb600f6332a638a0db51fa723dbb917d5ab64be6920ee52ab66ce59c7e2ad93119abf0d74e3a5d7e4d9d9d33dd03c7720f9ed3e62e08e074b61e725a4978ef3929ae35f2b85a6ee90986a7251769c97e0d33cdea22c0bdeca58bde2b30c447a09b3b09b2c78e3327a46a3a40ebda18be269f49222207cd297cc5ce625bd049ff40e65844993197db232fa6435c1fa64f5e91e0888a44f963e5d7d84fbfc04b6cb6f97b7d68c20f63b5d1cc6321077d2af7ca4c8eaab9eb40ecfeded8a78752dd6c29ed7fd0ab333ed492d6d854cdf159ed4a9983612771084ab5de77e7dfbbdb2ccb79ccd3c9379f6aa15e17e9d48d7b6c9e813491f399d2ea01cd7d523af7c7d2677f8efda4957be2ebdc99cfb95bb167eb60eef0b9f4827fc154ec7f90a398ee36fb7d09d48fa84f591d3710e74d2a4e300e5d02eec0cebce85cd65bfde23eba55d46af7004e6b4f64b076927e12c779cb665d9bd37fbf6bbdd7bbfe19b9dfb762fbed976b36fdbb66d5b10b8c3cd3dcb0e9f65dce5b0de72969d483f6dd9966d2765b965ed19e6388ee3e00a2b701ca7b7e3641c3fe51c380e84731cfa491da013c769ed385a3bd049f398e2d6c5cb36c07e465f98d897bbd7ea5aa4855d6b96579ef64554d55d0b7b7eea0e89a985ddbd2331c53804169c0c036f98e58b956d7fc9e0428694bd4bdd078636cd4d379d5ef31bbf09c2bf2ece33cf32077f9141b4afdb1c11a1cbe63206175b3ee366cee12232271d67d98c1622a35f44616efbcd1de9ef11385d06e7ed4f2302f7e93df1ca1dfea6573802e3679f3f33bf8e73d7c2c6afda4f766e7b6737c6a75311d2b7eb9cee4e325a08897bbb85cd1d77a45708c07dfa95bb23f0a59198f676aec8e99b0e3a5d4607d9903212d3becee50e6b24a67dd22fa24ccf6cfe7e73a90d81426cf48c28933efda5bb1afd22eac66744dde07e38ddc14d4373ed34b98b616bdc21cdaeac1d6a3f1d7ef617511d0b7b3bd57ee4d6a0f6d371c7cfb4dc34ba5bb2b5d353ed276eedd70f77ecc2de74472f24b7d6cd88ca5ed2ddd0d674a9f467cfae4c66c7b210dc974f18f834046e7cb8f1391d74a33e0981e70ecfe9a07b8b6d6cbf4cd93bf63322e3cbbeb7f9e2bc1181089bce72d7c2e6666466748771e06d3777d271f2933a59a69dc3f8501b027fabbb7bfc9eb815791b08d61ddcf85b96a526843b29ee2c7719ce513ba74d11a5c5bde9a07b986924a67db5fdc3bbdbe95ad8ef53fb4121d14662da4aa0109aad3d31069631ac188d41c5680c294c683003867f465ec2ecf7b7f9ace4a15ce1ae346f45101b522ae7a373be39e77c4f3e3aa3fccc62dc328b280b4d807f50ca28aff922fd3bd118e79c33d61da510f98acd29e59b4fcef9e69cf33d9a93c84d231d22afffa2d6f052e12084da10f958840cbff7de7befbdf75ed4e26632be271a897105a2f050e8e085e6ee02398842872bac302ac10b362d4111448c1e84104208a1052184104208ad4cd6e0de3b29a51052486b85b0424aa7126b07c5f7986dce862a943488f15d0e4e8cd3b2a4b4a494524a6959748a014304864fa40e0358903eb0c7b7a07a27ccc768ddbab597525a162492d9d230441454451493fc30225160a0a30d2fdf23faf01eabe08e015b648ee30138034839c7390034865bb89b43c1a31d3bb61d7bbe3c05620fd3e56112ef8499cb4340fad0b93c0bd2076a00970280569e16d9c12b7f771def787607a75cb732121e243cfbfebad789dc208b3d94583b888815b8c3b187cde5af4dee3adac12d446a80ad116b665c6d7447b590b52d5d335346f550c005184a3332586015b00bb6693ad9841a401640662100391952913af000c89009a903afe175e4277572e0c0b1b2a196d5d10e2f393810883ab24785a2831b14613f5b2b84b01281afdf1ce7f274995d1e82c171590fbdc02f1b1e02559f4814b8dbb1031e412f1105e11748040386af04f8cb661826a2c444143c0ef80486d9f09dd25a6b8c31c6582714b3e1c144148421a2c47cd934c051bfb063dc5213b92ba218aa0b441f17883af02dece05a2e5c80a20fa0a803af71d684d3b365d8aa98adb2bd6e5acb5a0f0b3906397463e40184dd5b995c7827a85e097877a8cd2375e0df05b2e39cec6bad35c8faf69abbb7daf61d043692cc0c0d8ed798b81cf9451d93c6915fd4a9b9915f44d1e8889ad991d11dceb624dde56cfbce661567cb326d24a27e936df225228565c1c0165e35eaf2b6d46a24a2e67c4f7cefbdf76cf78e5a908f5288fbbc70b169153dd13e2ff79ee61786081518bb18fb562e5d2877b0518a5589dc007736f6903386d92b1c815f98dd99884c813b28e57a14632dcc0a03c31442ec4064b7f4813d2d888e122b4a893ae0d94177ce39e79cb2033c36cb5ba457edf5b5d6a3620f2513bf92f28b3a76c7b6d7b26c8a28fb9b73b28d3ad99fe5ee6a21baef318d8a288be94794b56eb545f5931a07c90c7b97ee893cfbfede7b6fee76b68da88b2aa13b887ed27cafd5568e18be8868c1d877620fbb3d9e870138a2ee96b388babf51e73ede67f758be72d53a9b5448cd87faa16deb2d4aebe9ab193421da536ab392b82124f2049e99fd41e4892cb3d65ab50681828724f65b8d20cbe6b1df6a0435eca709a95b2b00bf9ecb23091cb3730210a0afb5b51451f638a2ecbb4cf34f1bd83eb3d6da79c9035cca4e144a29a5f43f6c609ce7a076d4284dd889720de004c7fd563d6c29ec18ebdbb792070e3903efa0a6137d016e297595b8857c62cefd2084f31416911bea3904c8509c59e4900cec79993bbd250765848f5a6a2c77b825ecc0f61600c76304b89bde5702fd1183bb7b017a09e5d4c1f1dd8c4deecbf9098351031880b5b8c3b6c49e0ef64ad81151f23c224a9e0816dcedd8f23b7678f0304000385e8b121708dc01c0f234d6626ccac972df0180991451292fff7ed4c0f1585c20d05e1a5b675244eb4fd1feb2361ee658a13b7367caf03c8dd2ca38fe54b536c99f24602d0f846b65689d66b14eb51f796bd69a5996654521ee7b96648124b2d5088836dc44a8e0a96dd91f90103eee040cff563b84d93042e8c4bd8e1cf84d78b9206f5bb74e3ad1dfd8365b7e5afa447fa21a42a8ab581c9849517cef3d119281837dee093f1c73ce39e79c73e23c07f502dcf0f011c2286f766ab855be6c8399144d7a2645513b792a8b0aa8b7b25503876bc235f8593772684a0698917924a0abb101b84dc3efafde0cbf7931cca428ca9bee8b0d88b7515f18c2055c8bdfbc2fa7d69722aa1e4754adf53f6de02edbb504f7fce38cd2c2f4f332c3385b3eed47961351f28fa81f367097edc3f82a75ea8a659ce1128101a678e602817b6289dfec41ca7eab1e8878d8b26905224936a232facef4321121703c7d01eefa2e5aa07cd955acf7c409f35bf130c57e9aa5236652246fbd27c2fdb6bc136084a47abacfc68578bb984911d44ecea4e8bd1e31c618e38b39eeb8a30e522104e389a1fd177fd02092054fbcbb803b07d80fa5b39fc9c65e7a088a200a55106529f6e8a084103e66a539e986dabe7884fbe27df00afc563b78d96f25e568773a76bc01f65b49d1b2a305a3246e39e58bc087a22290527eca9249fe905156d1f1d286fb729814c13bb9dd384a9a6d4929a5446640640695d26ec6cb38c611842814a25bbc0bbb945ad94402c6f2eace84f16567ec51ab65d143baa794a2461c3feb65fc8c8f0f8236f831028f939f31acb4280fce4a4908618b283504810a0f68b440083840830556a8f1026d0667c02b3b7ec6bf68c75bbbdf4aca103b4ee0b46c95f149e1821f50608328d0184151aa336d146caa8312318a4d297d5dc84002123e48420643ec2045270f77f6502a05caa652749843b0960e49a028c8610b0e3d1872019435b61003842d2b1fa45e16bbeaa04500649083164820630a1fa8f8a28933a4d041092ea00e43c01cba950e3decf76dbf950e4c367c1263d482401be4ed24700c7cab1cc0e4d04546f86417575e5a954e19e34a0a9639b7e040079a6062c33f18841958e183155ed860031aa4e04d481cd1c414206ef0418c1c2cf1683084165b20c1030eb0e041eafdb56081b192c0818b13487b250a95cdedb7c2818a2d031cacac7098b2c201071c885651d0882246adb55a7615858b1d57519ad8a563d9a56b15a5ca8326bc97e0befd2686dfc1de1609a9481dc973e96e07a59dca0ab74cbd65d30fa5e977e1e1d9d941a12216a9739329462993ca9643a92865103c24da8f68fb501541bdda3a72cb852a4894ea913ad2da75e6533c24dad1da5507fd883ac91bb3e39558356c20fc522f4535244ac93436bcb5e390970604620f0a44a1f250af0705a2ace0a1ba9957c002bf34f6dbddcbc196446092061663489084115491924e2041c696150b5c90851329b94496328c00b3c5d10b5243445461a30a1161c014c10829a9831a7ac8811a66fcd04407a9212066f0620729ba486395021d512021065078e1440d3252ef8b232456b0031061a4482325df237dbc948d1606f7c5d52a67c5b3e289d0c202ef94e0ad283fec2e6786302c24a2f010a5491037208111108498810d9698620442647186124d50d18512636e0042c7116588f9e106197062022a6c2863ca1536f8c840081478b1214c0c8cb0618dc3a08bad0c2f514c1df2af783de694710ba110dfbd18dfe77df3bdcbf81e7c4fcb1a56505639395fcc99c3c50b098588426962b1744104309966441757d0ecb7824203284b144129e28a1bd82b5d5c01450a14144099a2e50aabc3af802b2852767c29472ba294f57c3fe874708511a898420b2104e1862f8a2a20260b156871c4162bf0e2062dae58d9c065f5640c1bbed82b5d58bcdfea06296ec8b2321a6265848295110e3ec8ba6cfe6491c9082597f7044b0d506cba7a22844de971f69305db275cecb9dfea899616fc38b1849d560d4c582d60c296f65bd530440d3860c1850c51f0500422807992c60673c696283218634c116bc858012373c2a509193b05490c210561e400061b57d4b8011a5fa05c2101152b275fb42a4cac9a24b16df65b35b162d584065c50610921b3dfaa890a76cd0d4148a04a173f1461073424318203187931238c319ca07283186016f05cfbad9ac820af1491c1850f4e78610320c23881620a15599cf860821e686145d38860c1cf159eac84b36282c5fe7e2b2640d875bf15932f322df38778655a2b1a56330c410d26382ca182298cf0431b2b2637e4d086188a62240311a6a0228a2774909a9a05f6b4df8a86150d5e70c0c353c55a1e2b432758e2085368396295461ada0a708a40c5061414f5d0c40d9a10bb436df8434d051bfec15b78131144f0103104831420710615a3249e58e202014609a0c80151126df8a0b621c60dcc87367860dbc0029b5bb411c5a5fbad6600838c36646069546af65bcd70c58dfd56334cc9810e6400f1248b13ac649022ca936cbf950c4a5858b427b21f1e60b5c102ac0d2c580ae0173298e264882f4a2c018322a878420559aea8c20698cbc698016828d096656126f092c92cd858b1118436c410b149fbad64e8c1b405fb7231cc21fed920dc9773a10f0a489d28bab0d64717805dc2960400c04301054d88eff277222a5a3c46549073c35544c5479ef86859a73c2abc138cc0c76302587b89e733ddcdd5d51d4e17ddd1ddc131500c4421123d13e22fbddab164c12edaeee0982e72b7b1e3982570079918b3e321130f06c9c3834269d3aeaf612c150a984c189f052a19b438884048c1822044e1c18b1c7cf0022ebcbc600c1718d120268d9a13b4400a91228b2f4810a3fea8740d94b5498d32c668448000002314002028140c078442a150381c91b574f914800a97ac446e4a1808931c855114849001c418030001000021030344a6550452cb82c9e6691b405492e38aea6378ef0684b647ece952169061080c8e5502f1a49246dc6c58ca45eff4ff81dd2e46b2b579e3e5fb5894df318db07ca307c5e49e012cc6e9332a30e24a30c22be47455720ba6b40f75658a36d43537683bc228107829bd41ea65f1d85ee029b79455257e1a2d951cb27e63549c1ed86bb61c4edab37dca605a5a243329268473b7228290159e19d1bb2b3123321546fd2c714d316bf99b220c661d8c7733b4f3ca9af686b12943d2cab1c80e97cac03b71c4ec02021c663191fe9940dcca245812129c0bb7646e46ff2653dd3ba8440b90c33518bfa34b66f05af50879c82f8e5395f40661c6d9b3b552db811cc9fc711d086fd872ce30acbeb6b9a481d0264b0c5ab8862f5e6216b8e39fec8c63205dec57e630bcfa74492efb131004c220c92cb92b5c815f00fb3fe20558f5691209e8b7f29cbc3e2fd60625b5782e1acb61d654f8064f14c1eeb8f479a90c22515626e47446770ef1a80feb63769f87cc52c99e42492147eec3ae3bf8a3488e002ab3426f39ee776d09a02b7aa9b39eaf008b12aa925d5157236d9fdbd27dc0f3307e8fd22aad311c7e03ab4f5a3b2424ff93d9a8181df25a9c21c3027e759f6059b462d74d710387ae675c8e5d06c8aa458679ebbe4ed12044c4c574ec52d3a4a83e72632e333c36c699231161a4a4f9297603892e74691eee5cb5d44332e003d3f4ebb1265800cc364f1baaf4780d1b8ff2efa8176dee3a48707791a74150d3bd179a1363c12f1fc2b4e0007d762405380e88390fcb0fd78a10bf3509ada65a100ce00b689ae45677815c1e984d97d694bc05cacb1e92234e7991edbf4344a96b7a059ce9c910b5797357c896eb8d981d3de550e7f7ea35d90b57d6d23663deb14cd7427169404965d79e9f9767931582cd7c0306994d3e2577350d4a34c94bd50995d48436094f8613f9db2798028fd1f29877a535719c3d8e9982890fa8fafa618f5ed64dd0fb0573c015e2532efcd0e962b8ebd48aee5bb8df1b6595eb58a1b415410e1618da2523cab9e0f4a96fd5e8dfe1c53442a426fd521a1ef57b2af0cf5328e249bdc3e01aaf38a9ffd0291579b5143fa05733f42c859c4424197acbf1adfa23122348f4e89f45fac16e44a24b24794818701d044dd71d0576b545b4e427840293eda8458e0410784e4b47c295fa14dd9bb8b3a0344ca570639b3ee9ad6a8ed93aeb2734a7e4abf87bb893639356221ab5ea4b7da9589a6fcfaa820d5f12c94eaeda9421430c615092499f16097621a2953a27b3a1e5a8421fa24e25a118ad8aa7f5b7e778c4e2e09ae3d68d92208128d67b5720c554cc0bc4f1f4e74e0054b6872ae1cedc3b60ab156cdb792ea271b92a065c3ad26653b20429742a4a62389a016ddc82926dd31fd62ebe7437a1f8ba4387f08ceb28b897dfc48e0f2d25cdda975c433716bebe24ec4b0977a6337fa38d339f583a9ca11b36cbe645def27b288bd9c37aa54afec2f7939374fa10830ec51f17368d6c2ac82fc944f616849610895741ed660de01ac06c2d154e370ec337d0d89b0167793d98111c1dd456644b5a6e174e3e5c78ddccf1b9086c5fecfe5ce12f98a24b90f2261f86b5d84b8588104497acb4035dddaf7b989fff72e69948970503e3ec95575393aae02113deb1167b2ebfc5695fd78b14100137fa81e7bb74e71fec26d09b8c66d539cafbddbce8435299bd3c585664138040660ca8459113a46321b43157352e6c8e04792022d8544288dbc59836acd97a759447eb6af944d9650d469934095c139957b51976b27842571c8eacb93897199fb06223d604c9e7a8e3050c0ef32cf3c02c455f25b38d8efd62fa664b16dbb0a62593b5f25405d4602d6c79b6d0f49866ce8873db1e149432bb353198148e3e927cc534380128f9866d5167fe4ae4166cd2cbacff957dcbacc49ccebd46e1fb906980279968bb24806df7286a54d402b40e2776d590995a40afeb3bbf206cfcb41a670a4368073fed1d1d98834c088da802f592a16eda7f36f22fb7714664e93ab06ff231fbf38f43720f37c407b34592e08b59201738751bbad0e963387bd68ffa6f4f5f1075a87bd22aa2d0ab4fdab8a77250acb46f23e613b78cf67594960ee7e18309f3b3d5dfbb5bde671abd54191715a9afe280352b4d95649ab61513c432e3132c10c806137b0bc3a8754f9ce06f885f91e76c836839ca2a9019a29d6751d16b099cc99038de0be446f2f346b7856e05c48286a1369ada33b334163ed82ac3ce4f92b4a989d52825a4912646a076e5cc74a04c3c8be66384923d1bce381e59de263d30447b85dfb305c33fd9d42c3cfe564832a822dd7803d8e17b4b0a7082a800eaa93a3d4e505b19556a35408e64d64518de2152577164597a0947195bb94c1bedb3d83bc358f8d01184e78e5b4296762cce2ae3a55347ad2389d20fbc92e0bfbe5dda60fa2e80dfe9480e778dc6e69bbed4a1c33b5c2a145786296554e018fe8951cde61d93d1604f85260bbe6edf298c6364022e3f903d30c8b33720d088477ad3f20c21960a2a5d30e09208be1f5a0e017ca6d9b8b4b7389f1c3c631cfa1b0083f335e82bb70b06360b94708a64dfb1b660a14e6459abb7684a1343d1959522422223426d3a17142f530359e3a9c627b35c95c15acbb6698af361c70bf6a58c1d71c25e7ec1eabbc85b7cd20476b9665f56a1b5552f9c979e01c112410b96e09ea972c3ee21ad9530f5509a69bc4c86c1507701b85cfc7f3e78f1713c24adc3652ec1b1120d521eeb859b272a0804dd19c524a66805db01738ee2dff273175390b39171de3b59a46c103867c137dd8831d8e309552c4b0ba6b6a20df727ed8905a30ec5bf9957440f2b4607fcebf3231535d9e7eac63418a34f32fc1e7e148c5626e27c511af10cfc10addefa6b2fb4cbdc71f075ab9688e7204edc3ee57f0e96c629288309651f49f8eb5cf36d005832c7eb990359ddbd4f75c9e865a3d54e311a560e8d0bab7a8606826b5a9bd59aa74f5803ea9b27283d0b2ee72e573fa3ea4ffafb22aa5ab19c9016888b60080329aa40f7e032bee248a88817044a29e3ebc7a148b38f1ca34fec0274f6a84a1c7b76a96d6961c0c384afe11db67a21d8db14cb640c8b7b302d98779054ec9fcb186be7df6bbcda72fa535f89c739bf22d4209584513d3841244654da4135f294e582bfc3d9aa0fbbf48880df812ed0cc8e47ff9b6e1385176898b80dfdb47f762dd462bc4d036f136132652a4140e4f37c0b8b3a6ef14035e9286612a5609092c6890f230abdb93cee2ba16b984e514884e043b3137edad12bb09ad58a127e07f295d78b08f4b946eb0536f526ac7f801d6c9f11ba2bb9679aede6e86f72ec2c817a3f5e4dbb81325982421f35204f4762957e1bf49b8bb24a66bcc05f31c60979567211f74b6913b23a487074c524411dc6a7932524d99be8f0b1dd2f8d7703573338886ff6fd3014d398b96ca9dc37dadb1ad2f288ef0d90f3e0b08478186178689dd01b8c43cc3398b5db7f5e0472476dad991d5adce4134d0e6e013fd222d56d527c2e7361ef2e053d82fb87372e7adcdb17b7424f5d85904d058e03d9bd3a2d5420a2690c8613bee785596d3faea45fb2a1d72d033c1ca55ec7d6278013c3616a57842638286dd1d1e54cfcc61048dd07b0d54d03b16be8f6394adf79368d091daec3c17eeb68bbb8e9e7a07e86094aec0685cd64c0c0a83186a9509410c18b506c51ed7a7e0e3b24487b204082e31df3b00b31887ebaf1011d34008854592c048bdfcddd29466e6ed7fba016643140beada0b4d49eead2a4ccbd5e8d08b55153309a9446c08d4f21a8f24491156442c83cf81e9458a3e09c01ddc4c944bf2d84dcafb4178f68cd1d468ba85de4fd54756fbe6e2f46575b9d29ef552d10ae409fe1a1b342b6c1fef9cbe0b53b2cdadb5762582a1da42105e27951a1dcd2beb025aa248b1c4a323275a08cdabbe7e94edcba4690a41f91cf4c6bbe7c056d4eef54ca90814b77999d75d5e39f3e444e041310afb8188b766ed44d050254bdacb5482afe352191c3d30134cc650ff9d5da6fae9ce809a89950fdc940a47add54e849e87c02c504ff09e8e31b89bba22dacccde13334d605bfcd96a8b89344c2962b68ddd8b2deb2147d72fb23d2302ee015b7e332a566a46e80791bc682069b656cc1eb91f0748960ae5e612d8c9e562074e1d94c06c33fb3dd7858b648a881abbcaa5f57b148e31e5ddb7a5b8c920e8694d60b8c0171662b483efe95e476ef1a95cab490208787b197b6450acbd1d0da102df5b41f186ccc32d995a5c28330f78f92768e3d798bfd6bfd644d855a9387613031b49b93a4231bea18ca8c41c88a7d05f99706781d7f53e1aabb393aad27af4a4cef1b8c0e4e4b785eca3e012a14b148296c69f960d4cd495f330c5db3ea394bf0f1ee2fa3d8f29239851d1847fc89ec361ce754e77b79f6a9bceb03ea42ad13b58718f6c902118eb70d0015f85c3dd64a7b5f83b5a77f6aee01311d0d2c36da00ccbe1e79668a4996628de001290784f375af7e76451b0158ce2b2cfc5f34dbf4bcb328ecaff1ca3fe50be5b05315cb4929df040e91f8c190b6974426cd1a2c778bf12860784aa6d74e74a762b0e914adb4bcc6128b9ca1b5da008a63545c8a54e67d8d23bd2bdd7d306d012b65808e74867e471b2bb33f6c50ba9dbfe1f82f3d06f816c870ae577b30a12176af8f46356c2e0fcc1a832201a3a3e33344099cd65786d7cb1d27c27033569de93c7e97fb14ad6cbe01a07900c3a18f0f6a14460af0a277e60c27ec22e1e56fc049cb04f9f030303d9421e91d22a0c369cc61468f604904ab7ebc6c0b3b994ef198b1158abc3221f3c665a20b4cc871854180615e5f704e34ca4b3a053450e7d11fce21100e6c02fe7a7aa628dac0a7cd5bc5f01cb0fbb96d9ba8b92b42cb8418f5cd49df6c5cc3a0e2833a1df63f83cc3f6cf97f300a89ef561c87668333702239b74c2f45cc6e5e6cb2f9993f1280d78405f077f6b2312e6719f5d4701813dccc6259105b6f942b533e75dfadcf19e3a29a22a662f27e838273cba5578f3735ed094093471b4489e0d5a15b088774ee09b254585fc8e2d6bd65b8e271a2349d067d3f1c22c14e80475048f201c60316fb416c2cb293afc06f1f79dfbf5d5555845f8b74580ca35f24815e4e00b40f692ea614179fb1b6c7585d64a3b8935785b527c48f0b3973630c9fd6d36e034e9c4c91848da3217c923ee2b25cb155a8ac314d35158d69a42e71d53570767d9a6269122fbf89b1f5f3a25954ac8290a7c1ae6f445aa92594358ebac6ada4661eed1328e920563a8d70e793c0988cff95f800ced4e26f96c1c068dedbe53b45c11e4de722d86bbdc802b2d2c6b93b35fe280e627a04c175dc50db7ac4db4a527a274f1256c93c70600dd31d38976c6b2bb8f1ed0acf62f7a500d150b27e18bb04e79d922f73c75d89312e1cd7ab10b3acddcefcc610f6fc3b95a36c1cd444b09f9bbc14438641b903c151047662bb265a7691cfbefcf112ce601d5608dc892066bce65871f62210813a4fc9fa168882c2459a40f373e3baa9724523aa06754668211ac8fc4f0ea40fb0bf60431ae885a1c145151399850fd6536a1b284cdfe5d9f9e211d1190f592ccd5d69ff5e25cf57536bb80b0bdf03ba5cf80e4da0c3d9c9d7eff7c939bb3376b12460d34da87e430c22377a6634df98c6375dfc9de4572e340699681647a172bf4aea5980048e10a4904c1cb925c34a54e616e4b3dc7c252b259d95f6baf3cba58dcb5cb5a5e979ce457f8a65d077d938cdff615e627e0b5e8454250a13e7fc78d845e312154e0a97a607f09c47a9c5f791e8abcd889e9cb96b01d48ffec56ed50a3c2dac6a31b7528e7c0a63672923871011ca1b307236a7e83fe9f64513674ebe4a35d4d141cb4bc32a8a45948b66e24477ed5197e6e93d0cccd1c5ad8634e536de3c42cfc8aa21b0d95d638f252862bdacdc0d821487dd116c6f8fdd9b53ecb72cccabb753c214fbbcc664e3daa9f0e35465234d08ac99070414a6df3b15451549a3eb7d551ef738297a3bdf8d3129f8f37164cb829e7aded5e028e9da74933b576f8b1f8e00f39c415be0e73912c589a0ac94ad3867b792a8de13d0fe20866d670f755a76211779abf6b59d11229e1e77a7601e169990fdf24121b1e98582358343c9334cafd61fd63c58a2605bfae06a85af4f6ba755cb26323648caade4da295e087ef8d93ba185dd7a02c02e9496541bdd1ecd256671c03b08862b6c9f66826acb405f53adbba1dbfa1e59bb3f61004cea9dec8365405d341e95b690ed8091f866beb80019aa097226d410e693ac99a7feb35a8c23128489f2759c88b615f51c42c18600ad1b847bc09eed66cef7975df9866bc17e1f7b3e253db43b7f7f38fe5068252df58abc433604928266cb8905798c4b0f8eb603fdef6b458c42752440feebf81a3d033161610f423f138d08a10d1319e1a826c3ac77ce62c14a89b7abd335ebe21aef2bb983f630a4ad88ee2658443878e68fb39165f672ae7d718d2bfd6db3c2dfdd91f9c516f663c84877476321e84610407b7b6091cc9875c13e224c7514fd1e531c911713fcc695fbfc2e80d2f39b5c66b334f10f88df55e1fe31f2b56ce472f1f806cb7257facc3790f5bb239327ed08066dc810740f64bd48095b7f32b8e2dba6a8e7deac4d8b3f0375dcdbd9701611b3ee58494b10f0f1c82bd781b9250d17e13e74d202d775e1da912f49b675c4bba434d507bb15daee7bddff30eef16efb7d83c5c492b62279ad684e12d5b1ef001a69e2dbf8f0c5e01aa49913a91b6163b9e524a7e32d3819be50705263c0f82532a11a027945965c44d191b15f83705a2d370368245ef520954826ed69da02378033dd2c6a2cb060c4103a860f0b57bd0687fa53ee2074e35b0a68365ddccdc6a63e735b3260bf129d8627906929b17921f9cca089f5a9ceb7ba5172e555e31463b4798ca616b636d575294abf49a8e546f39458959dc029f805bb28630fecf32755530e6cc605da30221e35ddecf791b5922c9b48e086ce6419d32610a5b6432d9769db20e0ea646aaaa3532afd0130ce4a848b4f77e181f647f89a39036787d2a57fb2b20d2a0e1fbe299796209f1a87404f568db173d09a13d5d7f8524e56328d62dc8f5cbab2c07d74cdf82a4a2697ba4e72bd555f6c524f3de48d204fda3520b09241018d6dc33cd89a1e91b09121dd2135952a9eb2734777762ec985349b050711773e2dd373b24683eb903d5d1226f8c27dd75e8a74ac56638acf108c2453e12d9706fdcd673a159ab187cebdaa405e5dc61fb5dfdca368095e67427ed0c2b048ec460c6048589cc7d1099cc307a90269e67b32884149f030541e28eda4901eb2142314051c2872d168a7a3bdd8b3fc224d2aac06565c91ae5591ab1555e8dcc069e435616a311336eb8f907d8ae1a54d7fc5cc364b113d1ed599b5b0a28d408b88d16c55c733b2b57c5885cf07f30087fe568c05317f90c24f8cf51b9d88b1e2866fbcc71d394bebd8d2b1e2b58bd90eeecf7e82b1172404e6a889a20be2ab1248395d8233fca11a4c2e4d34a11df6c581decb6b21b598f58af902f386ed22197a04a6a8575a20270f07a0e43acebb907e537d1847fbdac8e44a9669d8b91ae0c1908c2035d4436065bbe0dbe7d2397905542691b028f0d4a4807000d36b90f9d1bcd541870a981b43e18782dc0098e0ea335649a3d305ca623c9ae8387ebcc681cc4571b3fca9a45fc44be6ab0d79488c517ca31525422f1ee6bd73bb8992d6160c21480e2cc2492435abc6500b12409ae345ffc8daffca79113573aedb874e325127cffea14bd88c0debd6b6b21bb4a45b97aad8873cf237e8382fc72c48ea5885780c4357d6a4b009d3b222e832bfbc8291996975cf1bd494b56e5490163a56fd1989492c6506b3d1ecbacebb776bf4d9771167dacb7d6f4f423f904d01ed9078837447e439b1b3ad1235e44a5e48eedb12bd68ed007e0b2cfd0eb65a4c3d86063e9be244649b0463a504031b7ece3dfd73b0814172d294e1fb1f25929d56a9512fff9d2b88bfae47d4ba08149b643a8bd46c48d057af79f8e27a8ef7d3faa8c3e90b355cef68e6799d441dc3b712135f929d2af8d02bf370c91b5f379bf88d9a3730640df0917de4e9fa227b6574a0b7fcba1982a00fb4fa187e8cabef64b285e0ada09d33d31c3e528b034dcb3ff862c88ecbe9fae4e8a9522a310e90e9592eb0ebf376b1e63c12832b2e8ba05c6dd0ca1eec1389fd4f08948ebe929c043ac3f686f64187741fdd5f418978695a1fac01a073e27772a866c2fa17e7526b9b0b5a82b0258dd288402a5434d33db65300f1e534cf5aea98a22a93b25e5f97f0633e5e65114921aaffb83e1488a0ee611e84f37143137a7301a059c3c3cd9c020415c9978f25f1410e1caf4e5653bb29383472da2a582d1db5aa1e0ddc26c7e917eba96d4b722377bdb6e24dbf9a7a036f64383bd3e546141956f53ba9b0c286f6364d5bc8c94b02f4acd2a41ae94c64396b9a799eab3b76aa98d9535922a633a0af779801ae71c3c1d2ede78eb2793a7d10d6874202e68244feb94a95890e7c55ba920e8f5b21596e29e493f84041fd7cbd236bd4ed826474fae0097e9c6f9b8e6705be09f2b7220d30a1fc5f5518fad12fa607026ff16a6d5e51ff0622cc529c79d41c97ad94f8ae66f1894a874f0a4723b0ecbb1446993360dc2e8aa139ee286bf7e1f5e99b3ea4c99dfb58cccbab3135a16eff0e8b4e4cdc7a99ec85a80f0160fd1435961a8e30e0fe29238449fa6ffe60544403a87c4aec5f668d46f7ed0456100465c8d56698188ce72c7012d9cf91cb52ab9ed380248d7d91eb1fb4d38dab22e9afa6912d36e972210a6e9aa58cf6fc4efd94145029fd76604b9e97f389d7d9970e6838d8aa9b1a138d3d878e72810bfcba9860844df618ba4e9a36c1d76a6b2fb68f03e48e9184f2efbc97a3e8ae53089166bc4d47ac1231ffbb59b50140f5a43c0b283b742eefd0002a5ea0d2379a07c2bfc610815276808f0830e6726a04c8e0410308c4470481a0227d635fc095cbb7dfb84f0a6c3fec68a8a331da93aacc558a7660ed998edd504b8d1e3040861780bf114acf54a3c76ed2fa078df91c10f7528bb8187a9437e7a875541ed345354fa3edcc24dc40930ea97aa93b94648acd6b0940cd4125d59717afad157ed702993f78bae2ccf6d26e9c1418ae8ee01c99f5bbb7bdd09c7bbdc2f9f7ca0ffa99a7021706df3f83d99fc612463b13f8d1f343c6e213d33a4ffe2e3ebcb87d154fecc54b535dad6b22465ea95d7df92ca4ea472a66942b3e84bd8211d634912270e7006170edb2cab6a9c80dedfa0beaba68735f49566f32e2e4c5af5a0291a10d457de82234d972ca84e15ec2b15f1ea5259fee783827ae87955f6a2e64ddc06cab766f6a27dc22d879c06a15e46d23da5369fbcdbd50ff69c0850a228d37a6040726f6e6540767257b1c6fdfe039fba822b750b17bd7c5df3b1035f51fad1bc4c95cca1d6e831f96aa7f757d0205ab5a8596a21af1451a2fe7d29d5b682cce38d4ffaeb00d492df65c48ab5a0c0f5ed1fd2d5e52a53be2fe1a8c04c62979a78e8bff48c33a1980dba0da84a3c77fb16dade3db2f42404d4dc78723a9e39b83a2ae1d30e03772bfff8f0c79889b7f08205e6219e6f550afe580c3d3a4866d8d393348d3a90300e50e98410deb27ab2bb789859ce526c7a266b514b46a93efdd27e1a7986b4abc93ad4346a3229c25ec4d775b7f1156fd2d93f3292e74f8f20eee86b3ad2ff95faa7d85ebd5a68226117382a393a337aa05204a3f1b91ddd24332d6c994900a887694c8641af89d272b502d882a3c0e51329707c855b7b8f4665d09040be88bf63a685af0141e79d47e9c7596a89a8250721b7fdcae8aaa5718912f8b4596706f0c790134059d5a44d64f221cd968347ac24864bd73fb2cb7de0161ff7f4d8984347fb4ee4c15bf45850cb91680f2ad6a1482b63173de91a155b5742a6413dd92016792bb1d845627fb58aa565274455d7d975410245a3cb820715c480776958837235ce6d01b958445fdf2f972488474506a900dcb017da88c1452d4fd338a889be1f6a5e399095140acf1505a4601990d26aa50121b4e3f4397ea4cdfcc83e2276fd479e43cd788b2d35abe048a87241591027bf1f632dc387e5dc55293b10002286f15a27dea4049295ed91ea607a1e367053af6e93300fab310e143de956e4da8267b57281a816b34f6edecddf4bc4b98387ea3d328dca70f2bfd8444792e9fdfeab97a0987b5f511926b9807c35f2f052f3b268c68835d0bc93080a6691f9db2bc8106b7a14c3529dbfd783cefaf4c33d871eaaa6b94aeccfa3ccf023d7e822ee2809d69410c3755843b22059bf032157072fb057b04f7f39ab0109f6356a77c445f7ed65487c5b924d13259323639b5426fb4782b3f18fec676d379465d6d0e9a6e34af7fe4abb9dd5e73ad908c051cdca185a1f3779e65adbf8bc0f5de63f4f95305ef3b5a99e96390ab1141d513e5e7ba3f05851a6c7967049b46749c5c3eb10954e1127038971bbb671f3d11afc4d89ed213801dad10562d8525feb4f5b06f44dd22a2ef5102f1f738026d5a8d29359c7bce637b54392258143c3a1ba3ca2f46f28c956c4617d542309bc8b45749202cd82e025a9c214fb97401055ae9ea7a4a3ca42f725ffa44af3fef85dca9644267af126b6a33f28a057041224853b7023141b616e0d78080ce9f5172e12833cb28c72132cbe239f11c4f074e2b2bb8278cbac5d861f104f064451be69b153a3d9e3e1a5cf53480804521f3c4a1fe8d76b8336a314529b39305bf2dd7619167f89e880d1c23f1d11d6c83b918271d39b156c163a8416a5f61353333384db9ac23d627089861882e9b892a28a417fa1ea7a59bd754388015fab313f34ab426629560678aa4abfb845489e0d9c4f5312c793ca4c87d3c8cd49cf6b08444ad0a49ef7f8ef612e0d1b45a0553f19b95d3b42807a1e34330da0a75e2783da8d21313ed19ddb1e9cc476507a8af043f4753ba5948b5a5b486b106450c299260a42e1c75ee3f920f2238914ecd72af13e83e28bbecef97cf986b9452a44ff7c39591b65765f44cfaa84b3a32d59de53881e326007e7a39a9108a78d0b0da620aa54bc2d25525f57af2ecdd780daba7f8e1d4a0f8263ab9ff8f1012e742aec6c824feab426f09d6d9187d1ba59c43e0fc135692dfd58982d7bbe2497e4e1e4aa3b1fe8af366c25448801615fa419116c567544c8de92374f2454ba9333c02cbb680031a4e7041a6ac54892c30682f7898990057873989ab0c7ec61b6a7414d63b7d005ec0229ddb9de46e65f2606b25e1cf5189797f392ad0317b00c6b609878d5cde0d39ebb0a5986b42e0213892b7b494506f9432bd4c5aa1f6e5cb9f0e5c0f9399ca8bf3341e6d155edcec56c1e54239cdc7211309f0e10c5024cfd9cf1822e9b18b21df59b4a46df3baa927f837ab5a9396b2c78a14837463eef43dfb480bbc230e3a7818c9b1029f29001d49a884b2a588147e13f998f7b4501e5c644c3d0e05e48144a97bb95b277e07c472ae41e3078f0b6a124c6537d9e46e04afaaa21e9ea788d7ac2ec875bca4c39b98130ac2b0fd232fe78068af35e84d44afed4d320888c50ad04b4898c706a1068c1b47ab59212083513c9e19df32a28e663282022d53297f6500e10d52042b59b4ad1c144d330d799cd4fb845edb5be65c5f2e8c08bb067758405c5759bc2e8d150ed91f06e46153f64b6bc7780304f1247d7e254bd6a1e40c7a87c91bdf7ee101d07b2b9ed0f67812399270c62103999855a6d173080288032ace8296669ffd88fe0a5d3ac5f736a165f3e76afdfadf4d0b4b5cd76620f9f26ea8b7426813d5482c4525b5455b55026d96260de72f545d61cb29f0c2ab04b5691d14c38d6b19c2686c1ba7cea880e902b5af141d2455923638cd2b770e25dd011e65e07538284709c5b504ef7a1ebc374fa24cb047249ef8b32932a15b4759d2c0ca1beab6952000bcd53795f451e6d8bfd3a68bbb467f9613090df0156f84207eaf9c86c84acfe3e5ecf51d4554ec12ca1c19c662c0f8ce3d4991c3f59b92410d1b602f1e1ece3cb68fac861224c8a49d01356d587c3d0bd39ffe899fa9a01e6223802482a028811c95f7a3ecedebdb09560f363534bad13ac78145b0043b8e7500502d83e14d83e96ed9ed4eafeedc210c360e3adbe0a039039e5076fc2efa569af52e3aa880da3196db323bc104c8a454c409e6a65b40743d55a4567a08af38683110f717814d7e9ea2c7a1cea5a4436d25a0d9233ce1c78932f3773dde2f2871dd7b505a9911207ff19e1bbc4d22613f4b153ec8c4d12169804cc190648450f736a27b7aba5d070072893c366f940111e1fcd2ca6bd68b163b5166a832cc87c0863f099e2f92c40ff2958d4963a7b4de1ad1b15bdadba059cab0c19660527dc228e3a13ca313bbab106ac50ed5675902649214631dc66c072fcb20722fca6c7904a18acc493d5bda609992fa2ff2523d80760c5b6fe161ee106adcd50a67ad8915f91a76e955806023f0ac26ebc5150f76d6c5f6ade608bd8f085c1d75e08d96ad76435e3be2b79c7a07bbef9bdd6e4e112f75b85aa45fbd5aaad0f13714621b228ef3ec522a4559108df1607921ab59abaad5586f051da1eaec61cf1b76e4428e9382854f88e28dbcd2007cd7904ffd490a18bbb0e0698facdea378a60f4a3832361c1d566fb637385f6cf495bbf69ba16cd3c336f60f54f1048855398ccc037a60d77640b4d58f7a7e29be37188071c0509bfe770efb8fc5390af6bdffea1d4e3d86ccb3610406f2fcab6bf207d6673ba85fdb9957a414aed29c28a5313d42659a5c5d48efc53af991fee8c38963ea0b57ce7fb5477b9c00787e9bbc5dc3055eeab72f2497563ee00823f014f2a995da3a247b0a807ad3c3529c76e98f61d40118015f4295c0e3918a861601122f807103568075e54c574004f1c0dfa6b03bbdc460f00f5b639a514adb86419959d50928bc5131be0b30447fb13009664783bb358614556f3139c7790cbe2d72bba7522376b6341c4f89edf08e8f350c757166ae4a73bf4e1d818f5450786c4720e86b8b1a452d3d2baa968fc0d258f609e782d4a655b97f48d6082dd7a71971b891c648d377e28f14a893a07cfc9903b6043da6da4fb1c052a9406e2839bb9b1f266b9b5998b5e81c92dd18dfeaaa15f46437ee409f512da9efe6a4b6db3049d417847cc1055f4ff99b8e0d4d95b1f3a9c1b2849228a5f450b1ceeb0f229378025c889732591ecf7cdd461603281435d7f49460443500c47a060ba676da59241456d0a9c30466878f22623d1b38a812ceba84a5b69becc09d2c25be70104836740f08df9335dc48f96f298dff02edd19e4fb011e968ec0a4658abc2e92536aa79fa82c6e047f750a3950ed08cf801081f8aa271505a6c66d91379f554c447c755ff9c2f37641e6f206567d9a754b94628e3ae7ff4ae79729fb36121af88f3ea415d6e6627f5111c59b5938cba2119a82407ba0445df11d2fbc3301399cedd290311dbdf4a3581a05c67b3116c763ed7723d0fb45a08706fd95641b8662a6e5c1cc6d71b3d32c37028fdb9de6a5d200d93d7fcbff5b6a9e9d4be6758f629a3b7d38bb1d63b79378c3189e23b67b1f4aa35f01514067fc255064e06236c976166caa1d9733ff6979a8cdc0f003d21c6fe95592ecb308dd3ee7eb9fd46a0775dc78adac575e999ee76a8b22a9bf4fb0653df6aa36194dcf4e3170c2db43d1d6dfb241b1bd4484d5133aca6356f46249965bb713341c9af87cb6fbd2048084d821435b6ea4e28093b9abe7d14fc663b12e21e6f1961f18f09e4c6d120f4512ef8b416ca0cd4034fe876000b141434318e531fd4d29750a4b057eb27473a63407c4d939a5191666e99f97a261930af7d0c4842699006d53f39d75e81a75bc962b2dc098ede320beccd0b8deba04f810ca131dd72cdc21932f0b8e03807c0e690981e03006c35f9e7b94e8d5dcb9732f07d02fc72d6cb98fece2fc459be0b2ce0b2abaa78faf997422b1d7e29b292dc6e3b291963fb50269389f2f2c035ee82b687e64cc0be2329dc80e606c8faf3f984a76997c0538ec2f447f508f6367bc0aaf1c902781e32bea062591358414884d07608ea375cba3c5856e2736120bc7c199f3efe4c778639da952dcbf0bbdb3b3e8848a10bc05234a45ba477616fdf94af57c5ef74cd6b3de5d2cbca1363a67310c3df50bc60a3677f9223c5abb6b64b94d21db33f60d278b39afba61204afb2d6eebcc5a1102803a85de684490b11222b1d2352e58f39dd8bca26c1a0755acad45dc362d0168aaf056f51a500d4325be8e86a8d586555a5e5829e256b4cce00893644b5578b0512bf70c3c3b084786357ebacf88ea5ed8bec5cd7a8897796202f8c05f053b17bdf8948656d2a83b3ee48c5e0130cb2327669cebeb745ff8b76a3313497f5dea600b9788ec75688ebc0c683d3c9b6b2f230d14874837c17929ec3fdcd7f574f02188619e07aab68565ce52b300bdc3142dbd6f63d04c30013c8fc3b9cdb0771f38649e2baded3b52591494bae21a384cb01c13ed0b9f6e27de8b0bf891bb3c6e1ddd288f2ee421c6ea1bd9d5831525dacec99342b1b6871b0dd9444c525adde5ecd2ac7f7c74c4c6d416831bd7721913182e967bc1e61d1a09b0125745b1e20732e4fb5293432ca290bf4413bb46d66495ac9ee218ef322ba6fcfde565ef24b2fe3859bf3dcdecf40f01a1f8498a053e5ab8e42acf1d256860ba1ce9cba2e23dcb6bba5ce0ddc32d112b745898556427e9075caf8a988a471abf8559736bc9a8b2c1170613b42e1747d15bf4849ee9db8704157acfa1836e79a7151584b1a486e052d8b39162f5a9e17313d7d4f7b2789109d6828b0d0121261beba518824969ca062b79d1a2835dd31e4a6d88b9e2aed4bab16e91c42bb1ca5b7be3c6473d8f359750e7073b54a4769efb6022e16036d61c781f37a814deae9452d059e89a0a2cad5728334d442bfb75f48e721534890635b85d1a02e830b441495c4b493431886a5023d083e69d39c00a79dc851658a1a7c49439085f3638f22b2d5571953d2f806dfeb5cd220e5f3056272fb8ef3c80c22fda10eb61f8ae7e5f8da5db4c9a6549cb7c8e22ff5fa1e3df711d06b3b5f9b4d8d8501c6f5302f69bdc7eaa09b7416155863193c88f47c82ae30fb416550ab466979526b76211f923b1cceee61240e37ce43f3c8ddc133ee264474ed4ac60c7049317c3fb5b642716ab506000d664d5a24c7b54809601436baac567f99618a8c317a19088c744fdf96c4564de20f692917c6c3d782e0e837d59bfefa905545ddf560d1e06e9c2e1073f01ae8499519edc8769c782fc109591e337984d0a69ba1b98281bc1561f5abb2a6788bf1e55f5446c8a89077889317de2e3898458759af0adbd4143239163d3556b514331b34536547f706e60f8eb25a31e80b8b1aba9560fa0dfc0026ae4d7903befa98906419b6a5445cf81df008e1c30b47dd19223c09880ccc4527161c92a5ad1ae81d8ab884ea2a6baa33642f4e53f4472142178c4443899675c0d9be44d12c7ee29baf11878956cda90b4c4ff06871754e30d7dc54d779730b88ebd9cdd243744c330f4bfd9d98e859a59b65d1d3db038dc65103e85913858fbcd2d2cdf023e7340783e47ca53630d9e82b24243d79df28284b21d6173189f0ea94280ac515c2537a3ed7cfbf226c1c964cb0cd0a2c2b3d1e369ae893c6abc50809a20b18915d0a70e1dd092bf2b15bc0d3659d4decf2bdbd6a9496f0b247db53a2bf5620d9d0ee0b335283c8713495701347bb5efa2c625c71cd32fb24ecaca3d27754946b98d47f4cf20ac16c9ef88e386014376c36c65fe33a3b1768920a6da2cee967999f72698b434bf1346ea3e182a065ef0ef55911cbf56c5962d737e8924eaf6de95ffa915df2e4406090d401a5422e77ec00dc39e1ba919e43e16fef9235480069a11dba8c616712a179e0dbea61a929b7fd4da16ec0c47350e7bd32332f9ace3c5dc24c5883edb909fc23c6e2c0c8d05332a13be3965a6b7876949a170b5e8e276aadf01703421033ca548abcfd1384f3f7ec6052f6f0a78736e054948bbd76978185b38cb11c20fb93a35894c14847590dc515db2f1c0d3106e931e5df0cc671816aab1da166dee43a4b226e4f5b2fcc5c594eb3cab9c9f8dd1ec6b44011a752ffcc49976331799fa5958ffb0bb1c485a4204767cb6c81c26033e792c35828d2d8a413747b9581d6ba3a2e7197b8fc8b150c53c3ee234e50a3a78961a1252285ef18a178b629827778deb3557d4f8cacdc24e386a921a1781540d539daa23689c588613fa36dd3798f0b4cf76c9c3685cd0ee37371823590587a93857f284422c468e78bd9aa9be7ceee4dbd3e1e2b5f5516e2f38a1eaf7582bf57b50d16b644dbd987d694b346362bdcc0001df7c45e2d61f97b6538282f6ead12358517423491e887785a51e39df1881c10440650be1563d9f1990c9384920dcf231f34928be9d10a4525f7e5a63f41dfc014a5050f9ae26345943e3320021d5144add56eac48f04e6fff3c9778cdd13d32a9fe78e1b8655f549ee997fccc747e1bf0f2b42bd4d9163231c3eacd7ee2a4016761b2a4d3ea4728bda545f8522857ce87d6c40f8bc953aa3231f8359d8286bc20fe89742bb5b8e9b4b813e7af57ef028eb7d602ac19f512a4252eea47db0900b1c169f8ab74d3a75fbc3fd9c0712b56ca0aba9c59052d80f8c89abfd9386bcbfe5f7f957610a324ace470117d56d38aea9d69f30fe404d47b952af434c2f0fbd2446b1a6db29ac06e0a9d9a4a5d38ec731e35c796d22230079c13d82d0b090b3da562b5b0224636a90462152c97164327ed1053e8a3fd0020db94e194d0e04ecd3e0fb3d8ed462363133ac6b69dea2ec5af771ce695577502844e634299b95b0f4a69413aae9244c7188cb59aac2fed8b2f946e898b2b8c03025fdb4e16f4ba860e8209a7c7d6f48f424444b6f0f01fb547325e6a18a126a289db793323b2dfa0a6d437bfe2a4567b1e0bf612bf05680da365b40359bc944770e676ad68724120aa22d20373da3e492c50208861350747b2ef4855c36aef9a8eb918b80972cc54c138a39bda6bf577caad35086d14b62379f8d122ff342192bd5b7ba585cfaf858d39ca29dc56fabb030ad29cdc049bd96ba3d8f72ef5d74fcebcecd57265610a6c1e8a9dea4e597d9908dd8d8842c08396a6c5173c10a80d28a04f05a073844f56929124048e19251883a16decb0c971049c370d2ca1b1cff9da73470a5ba541f56581fe9aad01da117f9aac0290a2640aee63e4b4c778984a187b2b8fbeb7797148222e089f3d1aad4732842e106c46d8113f0a952831bdbf6b4dddb4e84734715da9aa046213795affe0684136f9f2063cf6026b52bd6df0da98e020dd1d0a56dd908133f06365a1511ce775a6dfa07ff69c06e591da6b4211a1b28b8764fe0d9c2f0b1941927ea57f1e223b3c9c65764e41319f705d9fb9aacf930648d9796042ab5c8f26b42e1662355ea09948ab7038a8425479a65b7e6b5ab62f0b4b44e8c19a4e738a46bb989438226f91ae6abbd6faf756d6ca0f81d60d738600d43e7487308d28290a1008fbc0056f62de3270facdfa48b0b3249e39daa0d0e29d9681c7f96b44287e75ebaa22f31c5dc352fbcecacc1456ab71e7c37af97b96d74db19fadc5efe8ad4eefd413a862661fe9c17b93b3e5e3399bcab809c16c57769e63805950c97fd46b74e9fcb5128471583b2ca91f458c15428db0a9d56d10be32ce238cf8bcdbc2d3841eb25e31b304cb76626a18db8b1cb8ab6be8bc3e93e0b8fa6cd13979ac21858ca076dbf90d597c5b3d2ce49b03c2f53a72f1009fb4d43a95426a9f8c659815d92f9f70c848396a46984745ddfd3ebc01e4068683da3cb996cd77dba1cf1dea6409e8abeb28923b88de51ffcdadb23407f305cbe94286266915e3a811d2281bd760dafd036ac78d33be8307218b01aa1d7734a00b14894b7dc6eb910802704c7fd3096768ab6dd43b5217a54aa0c9930c4cc2d588c8bb6029890f813703b626cbb1b9956e5c0490cdb91b9a32ca4de166009b030ba1926192f5c1f5f634def7030f218e181f11d0868e6979b3bb87b8f6cde92eb2ca9a7be78116595b4e2a4f722854c0154f18beaa79ec44893ab006c3db117325fb0e27d276d28e820f8281ae5a68475a6e5597a1851c27328395a8d5a7257abe4d7445e80abc6d42de4a7402745832cfa7252bbeca86b7273a15fefcc22b94c52b3fec1815756b14d1e198ba298b9287cd9513596ac2142486ebc9cc203a1553890606120a77a7c5eff1b65b049dd2ad3e5dc19ffc52b8d3b73bb758c596dcd0a615ac35c7c7f35f9925c8fda4d4110a0ee0849b529dc3d142dca02b403c39941cf6bc98e036c332c82d67ce9c920ba867a0396572522dcf2dd0a1244adcb550ac71085b1587451c12132c58f354d05b28428025b93e8df244f5b010d10bb866062eb1cc63f8fdba5b2738671f3c7675f05f2b49ee7416b00702400f1dbcef537a4e03feabad017f3e5155dca91530e8d43081762311f806bf0f99ba30b20646cd634aaf02314c5ddf28d4f470b9331b9d173dbc719930e6b42692b82eff39e20b73859604c384a3f0599f5ae328fe18af57def7d636f77b539323cf58874a7723f7d4f4cc7a33379ce78c0c9b2cbd5f45a591a4e6cc4c6a4c6c8443320eaf5a4d91765a9f57e68fa21dfe435f371e332c6b631764357224f80767d101f0b98ed3fc83ad2d9d313e4181b5b01bbced4f29ebc8b8d1b7fbaf0104cbd1a49754294f9172e49b6bdc1bb5b8684a3b97abf561d873237ba23e24f88f3411ef32f927a3de421428f9f9f931e46f17496e248f8db4d0de5586bd06414512faed65502cfd36ce8a73f18ac176af163a9d0a7d6cbb1637f6db681104e827171313b24d85f829b9cf5fab750b7daa2a53af229868cb80c00eb5498504f78636fadd4cb606d4ffded591037de813e114a22339c483c084cb546611c7743642b8fba3c83a8adc287f663fb667644d48eeed8527e7307ed014b473847faa945d25ba932aca58b198fd09a51834509b1c401898974d97bd59a5b5ccc0a9dbd24fc47e6c24c7202600bb46c310b8e4ba6eec36b2dcddefee3e375ea76803413d6b48c70c2ed6e1dde6c3005f9efd9a049214681a26c9a3f0e6fd81bd64b51ad946ccb12a0424033bcbbf184047b8eee34aaf5f338ef452e23bc4dcf952fbaa9454f65f879a29c8447e8b5f2167a6b05620bbd183646cf1d1b9c231d494d155e4518799fb4b53225c3046112452d5ec6b7fa28f0121290064f0cdf67fe2429230dfa5d25f6291c54bd227b9b3e08021c484cbc142e044893e298e08df62646402631cc04e8ef86ce7ec9ae22005806e943ad6637bfdee962e2fac935beb584d4620d2f246e5795d096796f0bdb7ec0bff21244c2bbbda00cfc4e53f507096215078b233ccc827029a9ac3476fc446e87ccd5f06c49c53f80acae657b8f7db5eee69aa0b387c439c9888f5812bc61eebbc71c1b70c0645a2ee11e4af37e04b2a7eeaf8e594d4788e346e01a1b48523802a4d01d34dd9f56470a09d8bc96fdafad90f07e8199ea6250f9d5d01d0c4e5e4ef6388f4d619158a1608d1e71caa77e0bdc88ee67b35bed99c43ee04c2c61ecdc443404960f011b11c1732024fedd42c3efde4c88afcc134ebf1380e81e0c414ebc119908cf7dc80c04e1ee0d637058a2b44a987eb86ec8b2b7d45a2df7e2a255a6948c0b6ef4e8ed3a88363f29590c807e43a8b5d60f13b1622ab13ce037f6c273c6fa8443c7b77008462b44e329e93323e8532430326749e2f157c8ed40abf786d17a8c285ae4cb286102da0317bdc0f8c11b8b64803d67ae421087fb8a04478d4a78bb3c30e32fcf0d9acbe5e7251af052494b63854b42d01a03b0758dfcb46be6f990c3f736e6f8aac853a049ac1196db634ab9050f7cd1464469cdf9a33df75d4e372e8d4cc3beaebb36dc35a25b1b90655c8337a7cd2d06bceb3a43dc33f47bdd30e8bb5dd241ee53d853bf6480fb4e1f88b82b693f877ed187379a1487679ebdcbcea6ddd1859581afb12731ace8132c5b25b2cba6813c47cff5ca0d9d23a08ae32a669458a6296d2adab8dbfc5a40612e09cef082fe5f8ddca86f367396929e70661c67150d4c1ecf6b3e729845df5de9b085ca6c718750d59357aa8297b948748ad4102f48fdfd6fbbdb2888f04798c53221b8f6ad10e50a6d809ea717196853478aa0ff6ddc004a3675b0a143926a1db410624f32d273424efe7c7aa3c97eb4f154b17c6fcb7a197c0f38e92fc5c56c9d3738d256491f11d8005501580a8aa56e6d5e58a265b36413bf4086335ccdf7ca20a99fa619f11516d4c81288fb1b59e8da22aa2f6d235d5e5732929ea09f23940ceb45497f49f5e083a23c2474ae4dcde8d8c39aa18221f4948f3f9176fbb31487c4836ba9a4bf245ecbd0de070fcddd0401ff1aa251f0f5f33985c5ee7924fd18885ffa7363248ff8dd70a37096aa4ca205acca206f1aac2153c48b4225bd5e0c0451d5a487d07d38947acdcc9fc1223ceca88730fe7133a54b52c00a1596133ec50c7865d179b79d6512ebe2450eefc207be34935618b180fb9212e13365f105a5f942f97ca62c3ea6749f51161f294fbea57cf1211cdd61241d54320df6b817b503bab0a498550bd4750243733f1d2614dd910dba42370ec684042a45f885b7a55cbcf4aa69b107ce87519c10df172b424d80011be1d19bcaa420a9a4674ded3191e752ff22a1dc9c3fb63e1262b4f77ef11f15c261010f35afe41eaee49f2a0cfefc709f35279e7622be55536c07f55b0dd198ace06bf51489f79d27f66e6b677d3714d5eb961114ed1c089e12d8bc6f9ebe87d8d56a85fdef11b975069a0f89a36b4b29d556ee45429178a19173076e7bfadabfdfcb242a979f3098d700c71d2ed3500a06afce87b894484a68042a6b0314dc1c3c0a864e2af4c3d0ed3d29dd71946333e82c9a6dd7948db7459be2cca3017b1c4229711b006ebc73df2f3190ce3f11d1cebedf92d006c8498db9efa72fce3c8756d9f56e05f25911df373e729012c665d442feecc55b2b335d42dc653f1a207123ee254292f94934bb7aca47810b0d2d7906f18c44a7faf24e0670c799b23914f85b6bd9398e05b1c45dd4aba189e0ffa11dfe9a565c5734bb48299f381fed29078a85538445a071db6dc1dabe6d48083276811bb642570b677f4f7b137865841f8fbeebe57e1f02d5a1837a0112ecee6fcd36735eabd094140e88275861e2edd92962562bab554e3758c5e2fcad454ad32ea5aed01a4a9653281c78e7372855c641104d8164e6d312d41380713c4ed69840dbd107d048027921774fec62fedaedd11de54203446f23294da1aa180b338996ef99636be8d3dd16ded4dbf1cd23d49f2c2b083e2ce27cf8bc10bd757d49193a8153ba15f258ba29d59d99b717c2f5de10c173e237ac46285c9ba3a1a843577b3ca38f6fcc9959a531f43fe1aa37972da91f1c42379d31c6fa2adc7d29871a264ea5dc4f9fd4a2dd6e7194da293cc9e3dded900ea969b970b621eef511ea654c10114c509fba0e89785f8f1bdaf2478dd629fcc1cfa05efc72a08476e915b27f6c263eddf244b3ae6c18e5efc51f509239ef5c84503f3a0bd824a73ac1775817efcc7ed1cb688aa8ec1a2891a7f507d41541b0ef72b1f1dcb1e2ed125edec5c52313b04c76e08197d8a91688b43026508814aa92f6549b5044e24b2dc644d41878dd07dd51ab896647aa18c27ae553c7674a7357b01e3b4d4bca1a9aea8ce2a2c59d8548f9c217645137435f9bb32b2b0b42991a7d021810b3775b2cdc7b82887080f23879a996ef8236c31c70f07cf58efefcf6dfef09b9d67653aa7fe50ab9990362cf2fdf645a3d5e406e8c954c5c5cbe699f065552def2affcfa59643486904830b4b718d4d35c40109cd3a9985a4e32a7b0e8966207708b91d0027f1f57cff0ed4c34c5ed5c159ff5e23ce8b4265f2086f92b530f87e3a14ba6fa30749969c867a50038a9d408156f35e1e1f7aed63fff6e6b8c1dd1d0d7b3324854e9ddcfa179347fa6603a0641869e902da618107c8c975e175e4bd470b25daff241f85582ca91820a2d8df90df8d90a5431ef4dcded3e47ae8195739a3597c311434c7f7d8a95f2927fc2dab0d397042b4249633ae30544ef33b26d040de6bcd0649e2db241627430b16c3cec097ce55f6061ae8fe8600e8b202334881d62f1f96c24253fa419ec37d9520b253704e574a8118db23c442882bfde344bdee43375cf995267f8fa31cceb32d19e3a589787a4ca370ba91098879fb033d7cba073c01e6ad696a40180379ae34d7eb79732a5e59cdda8196f9ab9edf5f2db14f5590be3107e1b899a4639449969c34961bdb8369415dda75370cd347eb30f01a5711a2acb26a438f81a2293cc5895c789bf9c95ca2e7a46067f82745b833c202f82f8291dfa26bb4739fc6acd3a291ee4478999a39c0fae35a77b4543968094eef50bdec3c514e7b49c5299746d164959a0183fd3c5c3271bd46f3d17250daf4efe0765728979e733862a4b05484d126915d977c3110ebc0a695862ef8e61f05b7ff458c93c1fac30b8d8bf5bebf9756711763985f1322203cf4111fab43bb9b8fb1b17c08e13c8fc3c0dcd861aa9143777d794d9946c9ddb229d9738749c8a19edb2cbc40f3bffaaad3c907f702c9b406e1604da560601416000f37ed4540378daa55f79540c53b2e4eb3a2c800fb0b0327e02db8e6400a7fa69c1a9512beba480ab8cbfbb55f72a32ede84d019bb06640047bca27c7686ce63be9cf10634ceafadec751f58b8cd071c63339a6cd695e734dbc9e51a6d12965da55a839ae3525f524c73b1dcb555645462d82cf275a94e3e456f3fe24d44c9f90e2c000cd636cb58658bb547a17f6c3eb35f19d014fe476e48831855112bf21617cf53125a06012424407f2ec76b9d9624a406e0544e2005dfb9b5fd7b0b054f52ec4aae6ad3015bded45ddcb3ea0c8afdc5a8344c2fb20d2b3b9ed33be27807499ee80377152426f7df7de179d861629f01d8ac4fef9cafb30c052d1c1783be92ec21c85d7f6e15ba0df322d9096d9c18716a2f35144ca0ddc62ec6d508c94981a32e63790c12a81c14d2ac5763e51c21a880f7e52a9eded033d2540586810ed652614653d54179c484cd8bdaa27e33c878995b2ded7de47b46712af6851ba14ee6a0f7cfeec6075aeffeb0855aa2e90a2837522bee74dd245f94144dcdf8fe88d41d1dda7009c4233b6f5734f06e46d56493d2dc256ae0dce200866611001a06292e749539d5bb48f17a14af7e9640ca321e9620c69b7ee03add188c3cb80e3c3d160612e2dfe715c7faf8926bb7be70a2fab14d8b600f5300beb7deb8f5d42e00a7567f7295efdc63e36703ed96c28a6fcb5e4d3be8e89a2cbe6ef5fb8bcc8a4fab74a7bb05fb297abb8c2a54b14e1d03887acfa3bf4341fef00e121a1f9f6b5476eada36e48b98b15b12494e0b9be5e3d6039480486c4db50221add516250f22d9e38232c07fe3667f066d2c7b0330d242d80d433bc6da0d14919285939ec9656b47c28eaef01cfb3ed2d987254ea0dbd44747d871aec93c51750478817046fc66801d6bea521cb4d7c79e853ef0b29a1504590b604306afa7bb24cbe6f89fa2cd0121b4972617fa08fafacff883e5ac20e43baf1ece312009a98ecc698e01d95289dbe34a3659f0a922142ed8003a156364f71e8667e697036f42fe8ddd05be8d916bdaf48a2e5e1d94525926c7524495e5610cbc939529998e0c37fa5611fcca3fc313eabe670d757eee6361140e4d1699709d0c2ad7e150cbf9d816074e14bb2a14567da4da793a56ff306589fdb8b81eea48073f7625448a1d1ac777f56486c7067184c63ad66cdb760c8cf03c9dc18c4c744c6e702da9ca32d73b29407e7cb943e61f8b6e0cd6160d6a1639a3caeb9c4cf91488a15b046ddd8751d326fae5da0e2306de674c1efb08a19262ea058920fe35a13df8af139f94cf2b5f2e453d9b26804690bbed8d55fc4b848d2135d832eff4f8300e492e5043a708976b0a26fbb7ed359cf14c85ae25a10bbbcdb06d43ef9a696e1a18b577d08000e1c23243be3097cbe8b7b53364c88fd7ee7c7e968a401f81d7024fad662bde211bd2966ab3fb39a853061a9f4744d9f2dcceff405974885ebe8536e2219b3f9dfa10b33d3d27a33511e2accfecbe167d3425cc6aebe4993d96f8a18292896cabd8226f43747f07fd24201037735965a7d70c82913414d0af58e091838c5b0c40957a36735c6097c8b498c8a0f371399a3e17304d8cb7cf839e680560b31d8ec1211eb5f8da0b4a9677387a62c39abe72607be062c345af46f282ba97b1267c2582d8ec94d103c133b7c4112c0174ff627a79410a5c9c15a43417a5beb8c72812367cc8a1be08fde2e91868df08bec749f64ccc1daf1f9ec0a1b70f84ebcc0e10fc23c9201477a3cc5c0c02eb46d395e4e601e31d6e468998326de6b593f1ee65b91c4922bed9aa1550bcb593aa61f6fb7f6489d65636820b881f5b04d0f64a329b00819607935065cf61b9e451cca30aeafe981e86c6b662f9459eb2e83fa1608123eadf117ed32597a20e430b939a3b5adbb705b690134ba8f0816e1a9957e9b39cc337a7b0245b3a150b446a3eb1573a66c2a88cb00c5d1af0bb0181aa793952312a0227c58a54221030fc5910992d681b90d851e4a8696d3251fea5c2708e5855e93d4f6bd2381079955013029ab52ba0be79773eeb924d2a8edd200d31cae9a3a94f2fbc3be23fe72ce711d1eed3fd8d58a6b977385edddfeb2ad58d44b6695b9c5b66184066b91ccd8d7dd24630837d4c75e2d67dfeaa4ae75e396f143292b0a9ae9eeb1a2ee9b9b2f12b19b5edff9e3244f12edb3387de3a4734a91d8d8c14407b802d9735d723563128938bdb654ddb7b208402f7f610bf0f83138dd6a94e27aa5741ca64662670a6fd44a0dcce23b7b81390b998b889f60413538230cb7861616c48f2522c7bcaca4ee87c18a28af501c29c4befdce4eeb494a9916cc9be6b152bb672970a88342163dc29fa6a204778538920f457bcfd4e47d559c3faff61ecf227b80abf6e9f30a3735cc1bf4c03c6960a10fccb96ed7686bbf7f00a94754456311d911e9a7ea50f46f0d77ba07f6c6929e0c8545c8052aae05e109bc82f464408540b47b9667269bb24eebc1fea3dc7f7d9a2fa552405d8e979aa4602aa5d2296f8d284289bcd88b48d4dd07bf385842857b0913172074a60eb9a12254ee415d02ad49a26f81ded2c4bcd0b0b3c709cbbd7c13414ec09f67220ba9a508b2f4a05397f83d8a711a2015082c309366d35e87343cb7772daf729b63339474718228c7edd54b82a121e91e7ac276d205c4c0ad1205e4f401a8a5d08ef20d24755988584187a17d0873e95a8c724ec95768acab40ae30c048e1c6b63e5afb98daefb6386abd1a25b159c5c26006794d741f82d535b1be168302943775f6b35b53e94d7a88f9609bd77d8864149ef3926b12fe61a64eb6d0d24ab3a32157c473d301551300ac989aa7d96264656e95927e386d270bd120ba86fb8f883032775723fd934396b9aa67205a9b53e0169aaf4f0a3bf83c8f3d198ee21698a1c151b18de0590c2700a85058ef85875c37c0ff38028e76cea890e31b1f6d13834d4f8e1971dccabefebac74a110d99dc08468be579096cb9e57ec5cd2d226c23a1e1f804511b850c58e386ae988955bf44c27e3a0e321b2c4fd36fbf5da7f0a0507216dbe672f2b9cc8973cd348bbc20b5b73976af1da689be4565a5aa25526cc0215995c34b51e98d832296b3830a3282d9d8830a6d4ee2a60d4794f097e5ad6065293d7ea5ac6a9585a229319754df9dd172da56a07951fbe37f680e95ce34d7f821fef37e50065c31a0215bdc68422da12aa207e2b28df26e8e7fe7698fe5cb598b77a5c5a02748e05e5d02a4c58fc186a5e8c5d11f8148caf33a967d707561d81a126560f37023b53bab7667af1f23a8de1b8d3125cb4105ddd119c17f07d4792a95f3ae8bc5a2773446ae824ae198d49d1900363bb166249c751fc7d9326ed56c07075de28131c4679684b3229bec99b9a9bd162226c090fd6c05df0c32d612723bdde07d110f98a71941c5802b1fa992dfaeaf1a9b424b55e8ab0f0abd1b7d4f23b602b32676d736df7b45838572d13fc427c0efd1e84e661b73e59d2e10458c1652021b761723f9a75102eba633f90167378bd9664cc41cf9143f95ba995c685fb99c21f14a260e6d5ff8691a95e4ce91d18b39b75e4dc4eedde66ae31b897a8952ed6f0214cbc8dc06d0c8d19278850bdcf6a6b91b8d51147e398a1d495da66a17535510b0a77185428a42a366bd90f84d5b501898df9fab107e1bd18365888daa19498f19c7a6dc78ba720af1691d24a1c2304575bc4971c1024e8c5466b2632c701f857f03b2ee9ab38d969d0d5e782eef6af8d1c4f88eeb51ea9a7a593059d500226180fe671deacef9080148808aac15e77d338bef6860781a548d52181fe7c29e0239fb5ee2633143b96973eb035b0c67ba532495a4f9988cafc40d8d57d32cc3219edf4ca4ab53aec2c8b4d99d02932315a9d812e7558076b6b06f3659206d2959f12f70fddad10dcdd448cbcd91bccf4fd8e249ba4bbd61e8273e00efebc5b7b6701ff9f0e17df4b5f40814220a2ed080d0cd0d1b805019de1817b6232d8a559921d2ed22e8fbba4a8bf0edef9e6d8d7265caf7f0d737a1cab2f013565c5cda3dc10881a98ed16c8c074a5c28ae5396cfdb2c8b71b13e8595ccdb6cd07bd721eb833ff8c9cab96655e1886452c334879d4da83a057c4370076752ed9f69f32802f461b0635fdfc0ba5320ccb7b16d7b0844ec52a9f2027e670a4da80d03e6ffe52addad3682cd45ecddbf2802f588773361e8b58ccd3fcf3beef7936217702c500987959b68d9359660029c7e6790a09c630c55ef0c467403380426b8f4e3a871ea2f3b50840ff3834967bbead19d5db50beab9e9c13cc1b346c8d5f272fbfc5be5597bb17a3b1b851894763b62db6fb740fa866bf5af9c03bb7e55d396920c7b1a1a02394f13d72d8a7fd1c0613085122047da8fa06c9a6188c5ca3650e6dc56dddc95aed5ad6ecb980273d69a12aa9f01b35a77d309207f939dcc75a86610e55b4c8b38aeebb5a0ada5ab73b25d38a3c1a4c198a2e3a03c6d7a91ef47ca6a10029a6509a27c716c089f6d4f03089be92cc2ac260115723a07bc6056e091dde4fe7a4d9fdc9d1501a4eb2db08fe550841e0a86f96d9ed8090a104a83c1ca188691a63b40544ec252d8fabce042dace19cf0402021e977a7b3e2808f36899551b3bb2ee598f7d20d6f2aabed9eec7e0253e1823d9262aea3c2cad1ff9c5089be8808911a9149c4a9e10b7f5f1da8057c010c0cff3427b4a4212e2c0ff414aa86e560d0606670e364c5494af22480cc5bcc28dbe8f233775f0eb40b623d0d9c05843dbdaeaf71fc2db13a9dbf5b85d42cf8e85110b79c6301cd4379d279b7710166c63429bfe61f8838958e5be0090ac10471f07cb2cbad2909f574163b27dcfd41a39378dffc9bb143380c6fd4342b26db6c460d4c4a9296cf6ae456b2f7e9035a1578c69ba495bfeeab78b67de1192314a37dafb2260188fe02d39dd8a4369f7f419f624db35dced6ec7cafe63c869c721182c87990c8e99f019240edecca54b0c161562b081dabb6d15d41eee0c1d9dd2892197fd365c22aba1366ceffc39cbe6ca6ff5bdf021cf0927aea1c5224e9b8bb6360e7c394b40f240ca16706a52ccfc90cdf32c3e80133a26b816d07e362d19c36a5dcb77b82cfbf98fa4c9b629461910cb2b1b2fe062b48195c4917d94765fdd131200a4ccf3c9df75435b03a2f60a23e0679f19a8b05349c45f9cdefbf239c62b64cab80daf105b6000a87043b191359fa5bc29312092bb893247b7faf8720c493236742fc17fd67786af471870392cb440771f98d252c64d62920318dc21624b6a14a35ca07143db43c92c23789a67970c277b4f902052a5ec7590df5daab756c8e747e8bf8f056849ba36aeba97b21aad4cd8f1c4d11f48c6c0ef49e6d71c3b0bf172f477c9b030641cf89c2c6e085c8af7dd005848405868100b8d3e1caaf77a3fa1ef10463d81b559b552c82c76b66802674015fea0ecf1333a504f6c5f758000d7e52963084c9afc4cca6e8c509a50f02ed809a7f61d1763dd63b73d335f79dca7616adc38b6d040a981713329f564025fc524581340d0cb0f284c8d8ae011f35712c46b051f7843c5ce2ff33364bebbc16a12e066d4af6cc19cb7b40e2b9ff1500b2cc5e818ada9a04c36061e18dec30403ad9839e6b8c234682a64c5e0f5604e517d78c396d9bca1db9a8d2bed82580e718a04ace04ff19d58663a1faf40c59335ace69bcbcbcf8b0c0e5ed35a81bf66ac9a0432a9aea6a1a04d4da91d461260a4868dfd8c04de7f696ac3d691901a1198cd10a6b29f9230906cbb48fc927cd5e323a4d4334a898871e63afb60e7ef2592ca206bb685f6880dec6bb39449dc9c578826fb73b4ed9c951dce673037ddc8225ce02b2b3b25b80ddfab27659dd0176bcd818d5cdd5ed06136725e81e5159fbb9f63c0a5e648ecfdcd7f3d87da15b7a9ed85d87e41208bf4d14e7ae8b18ae36e8ff7448377979fa0fb119a289075defe6ec70d402312a12ffa882a1682cb9c055af9cfe21140ea1c35e6b6b614553fdf67a92b1731ebdedab98b2afe1b11b3945cd7d738fd661e87de3f0eeaf1fec9aa492b7e0c15574645b91d26cadbe8f51b7574e28749bac1a1adf08498fa834ec2433d9f6ab69aea8098c975680b2dba51fc64c0b95a405c72af281e1fba6c6a21be0149daf2cbaaa19f865248e85af8e2e4f0b5391a682e9c0920fe0e4bd71a9a64e9333bca1ec0cd1532cb065e0b177afcba7810d0074fba863c07907dae910d81c8163f890facfaa1c44675ca048f4fe2eb390a7838d5ca8847c241f0a9735c35eb52629d41d42e1253d9b0205584d08409b4b9462695734a373002c5d3bdcd8d789e33f01df38e2c733e9cc06043ec00da3e87c57735e21fbc17d69f0e736aa071aecf9e4a5dbb3eafdf4225180a2ece42a1e1e0fac816f15eb8eebedd8d66c024fd8ad72bb60a3c063d99e162607d7e2f6cad3a0168286640a4b67dae51fcb12044071614696781e3f291943834e581df63dbc6934186038d5b4b1fb3b1cce26dc7ee61a880954cd031b9fe8c7d181464357efd8159ac5bd922aef0b2903f88b43038c38a93bac7cecf2a0c67b8213b4874ab16bfc64c839de1f0422b000e89c8fc992e4e0618ba197acf4d8e838e4b4799c111390324bb5c5fce2a7e86cb26618715982de452a2b7a423d6d619433127980da3a82951c280341bbe92c6ebbfcc78a25f4b85f2742c44261cb6ad39fffdc07155bdc496b3df181b2d4d6d5a5204d677b03e732cb01cdfd7eb5f10c2c7b38688df1d90d3522490666732b15530757fdb4ffc65036631572dcdd1ca4e89fbcc8b4069f3a8666729a55eb86cad7620246372f92af37538a28fdc840e74fed316f00d28bb207eb9d1148087b3a940a729db3737e1dcac03c0736a53d344b7e3e107651f56e445d38cf9ad772d77d4ce909f1db724ee63ac876e95ccffa2e89f5630c179cbc0cf87560f641ff6979b7ff80ec9943f03838e8cd466bf64a614ac0ecdd25ffc6b29c9fcb0c722c4563b564b482b0b5411b9899eb9bce544148bc50361741c2b7d28bfc3edf6597d7d34af7fe7bc938f1f6540e7d638ff0d2b7899a35e4dbdf85105064cee6281db4a16e3e7756dedcb07921bc7f54864179440afea66486248409ab3fc515e836bce0614d8d4ec24267811ccd1f5233b22b327224e5cbab0214616ecb9c60fc8532a60c4a75914dcf849e76e7c3e212959ba692c976d36a25b9b6821311c319c9b81fe8d65bd11553bb04dbb8c14ff16a939dacac974ffa74bdd4e917d4fe69ba53477417ac89f9cf3818b009aaf1c3941140e549652f4176e91de2b703b35fd584e4915910b1318da60446bfef45ba7d5c96ab910ca2b104c1e29603d9cca243cabc01b0b0a2dc7a79525ca035b6459420455a1007ee13e9d54133a99029e2c254b16dbfa5311ea5c67eee7024c27e49de5ef7b4782d6fc4d2bb60310b51558151e0bf7901fafaaade8464463e178b8f8cddf2170bfb87fefe74c4f134aba95cf959e87fb968b9f160c9c01f44df61b85231010f34be2bc75d7b17f101050cd48571214f58a746b82add18ffc278e40ec290f89b3243cd204f913387ce6d790e12821723901031c98d16ce95f400dd0d61ccdc6bf04e02355dcb0a9fa24f7567c85b590070dd412d825d8420be2787caa907d24c985693007e6946fd412cde9bd3754c36607797c683f7e904c4ccec8c3e5936f4d16d976d3b653b0a31efa156baca65f968c1e115018f2163847f5ef7d70f6f6752036d782e97079db507af54ce056b02e20373d2a906e256fd2fdf0548dfd499931dd16ba8301d728b0907b3461929f87e6c4f4eed3885b41ecd02034a2331830ed353bf71982bdf2e2aa5355f0fd30e167958b766f17cddd621a253809e23b9f55df92728263d49f7ea97ad8476d2418ab3be75a0008de8b60c4a0920bb8747ced80f05af12643fb231e8a454292a138c70e57e4e8ad94856b7490df0792edaeaa89b203c397f0773a398a099e38717dad26c15de4bf1c19b16615f5280c298d1cb6271712dfa96169be87dbba565de61b4ff100a70670231422ec582c96d8a1fefa561768b2ddccb57af59dc1886e1a04f3e65211059646ee9bfc7dc13200b2b1fd76d74daea2b14590b09ed4ef028051238bc5c164c420cf9f087faffb2b46b1b4bbd1482f1f38888cef78ef6e4953760aec1b80725503c2eb02cde1d58085617926a135e02cbb2c099126d30ee57d52a40d047589a1cf60b0d4d36a0552b9730a23379c2bb9b2bda268bd05dc93fa43e0c25ed5db5eac198fb6d189b06c5020d68f647251fb0287d2a6f1c3130aeef20bde856103df6018560735563917aebdc0de2e8e047b42ff8d34e0c2e7c5b97e2ab204fb947b8d089677b8e679cba008265e278e0f3bd48ffcf4914ac78ae7ff484f743b86461fa571d7a23f488376dc3f9d29123c1a22f59600541ad738c2e29dd9bc5c36f542df869b4509693f81bb66fe149cf3a22a5af6fd27d45568cb8f2273f0c28f465646477df6c1bcb8c7abebfb94913df71e7eb901eca40d1e3267bb6ec88c8b380a42a004201d4791eda94aff7019c8270e834891ea204ebffdb318ffa97c59f72ec4606edc845f17f33d60c5957637567ca7d1f547ccae135eee0dea203722e63e32202b680cce8f037ebe9568871e64ece8eec5bf21d2361b4a28c0c51d4041e548b33a97faf45e6bad26301fb4159108418df89e79c4f96b4e69e7a895270b96173b935a362cab73c621b564c7e8fc16eb112c428a5e8c70b528f2903ba97fdc749bbb9c9f46db9dc6c2addfbd34151f7b2029e5ffcd5ee2081901adf68f9f780260ac11e3e8111aeec574d1ee2b10c6071dac266b3e046e5875fba7d64a284e01a816fe6c40e79a6addef73a955bd1d463489ffd45b36b26356fe0c9f1091197a254ab706599152c76b00102b045bc7930915d39b981075c7fcf0a2a00158e6b8d6e3020f834f7d68797fb746e36ffbd57d52b3208970a46f26127b96810fd536428edc88e8700090bcd9c017489d9a433afaa28f4476243ba8159e41e469e4db73803dfab3c015c9f728a1d6e2a8c6a52176ad2a46aa85ec7e3ac750d8289bd3edb3bad9d96b7a126433238f9f5532ac3f5bd5eb82a7feff8df64d0885236d54a8cfc10174b7d394e8b5f43b0b62e9a6576f78eb31a59cd0617caf2a6a42f4ace711c2efaf461453dd1b8179e400c51276b782ae9edce27cc5d7e000ae6d29b23ccc06593feabd0da01eaa2bffa9be0f8de506ea3c34ff22be55d378750f443180c0e12e44b5dd91161cd0cf433544a5030c324ca0df5718fe69e42d3db20bbabb517797eb0e67a477abf6f2855269adbc55a05cbaffa7ff83182bc334741ce3ba4e005c8201788c066f59f3bd25a09243a60742707e3148e39f235cb8b2a232f432380830015178700d5ac5a720c7b294f580d51ade1ff59b41250a338661ad3c15d4d8766c14894f4a90068dcad4e335c738f719b2b49008596663a782ceb322c449de283da19a3158a6d3a12f607f8ceda38f54be518a1a34c13b0f75923dbb0f12e15d553a0c0e1875ae136c447e68cc91296d72439126d9049295cba8fbb49f279a1b723447d3f79b5fa175c84c283f46b257bfce82848474012932aa243f1ac99d30099d991833a8c9374aea2fc470c213787f43aa3afd4291f52e4a38ed25403827d35100fac530d031b838f7bc3146f5dfc1173812908f326bcd23031d372594001a42f83efab9aad8ad63247bebd2a4aff7e0cb5b977451c5aaba6e1d4b23b72e622393269f0431ee597b193b48d576a4353dae480cf3f82dd263b99c1032a9a489e5bfac3fa315db772be2802816ae1dca8c97092fe78d4702109600b638f8c688e73a3a8c7c4e5499708b0f5915d42e42dd972999a4ff9151aed85c57d0e6ae5102448b4c1ab02476859430b86bd26341a2329973ec2b630bfa9842ee29a569209322e935ed5a68cb26b6434022251bdc1c122254892117e2a44579dc29739c74920315825fa0047fa529f8b19296e4d9e500df1ef474b2ca6bbcd05a58be5512d1b4877f7ed10861e3692e21ecc57e0131262e1e87842b43c5e7bf22ff754acd0d76241fe2fbd97ac13d2909816f97da58b582c03213aa78bcd0964f797457d862bfa5a3ca03be1196f21121656de414ee43977ee5f940bd16149c03bea6b515e63a92a5f6e2d5675b4cb5d6ba79d994c83c091b54d6cd081d78913e0626bb89c468fcd2405213fa34a25a36222b5ba3540f7ca4f66f47784021289e150d3a3422c6b3c896ce0ce4ef6eed5466b8f3ed8e7c8cc3c0e3fa46a42b8244378382178754c06a6e710cdb97b766d50f6c5cdb2e978d6995e5149e191ef913a77acb63dcb008f1ac8c55e0f4b4b4148e122d38a65293146cafff86d5f53113f877f063e1c5a5da7cb97f48a5d5b041ad8529fe4b85d09c543168a26912d369be6c85e87508db704d9d7393ffd66590a04de09e42d183aa2db3504db6316e8faf68c52cbb977ee88ec8bf92d547b521a2f26176c775e53a780fe5c9c4ca5a6177cb2151b5e7eeacebc81ffadef17df646b99f6837b9ff8843d8276a530e701d59c40554a9676cb8237e1806153ecaba142f24c261ef3f7d56f31a9219417c03453f135c34352c7aa98b8234e968b6f270b31771c3f54c1572b65b54f3733d92ad3f034d41bba3397fa990bbe8899a013fa426013ad3b83052604e3137d698421054c09542947009aa1389015c253c260c85a1c974e27eba8a600a730ac7804f223ee9f4e71769e11dbc9d280414b9e46c01d843d52bd7be5bcc2584faf2b3e7a2de4b8492c9727be54e29ff02e602110335497761b5f914af4501750f5ab3008c87f5e803b5957d53cfd9dcae3be5f77ddff77d61f77ddff7159aa0ee436eb6afc96eb111a85b90163366c8ae6b6c3403986822c90adbfbc94bf3ef50c4f3057ee52d8e12d43a769d5dd30061db35658e564871a120897e7c584c754842c4f97788f214614fd9735daccb6c02ea118ed7d562a458a1d5e3381c9fba9ab05ff4b3eec3c22ec5f3eeed794eebccfcfbec327179bc860da3ad6b51d9b58f7f8575949adf35c56c0cea6ef42ef9fcecf01809d46076e7ea7438365695eb6d6cd96c1d0505352f93616750cf3dd57429be67d734fa094e45b29dec359b6ad79d25022ee7610a6ac98a46f762286f4e8a3405996b83c391e1dfe1c973cc86b2556a38fb7d5f3bc6bfaf909bed402d40ddb3ec9abff12edbe7c381fa0d4d7cbe1b6788635832b75855bb5bf5ecbaf7a0d949f615277b99ec0ef5474a0025469e6675410ddb05827eb540cdd56cec9a67f148b158e4d84076ad642f75d9c8daa497b041b0889d41472ce1858d71b026aa0b901dd6d18add362401e274345b76b27ea9ea2ae462ecda6eb36bac921c2fa0281169496f4fd8d5139b579d0fcf06ef5b9bf8773832d46778a87955de9b6d66b3a9b0eb2fb883f4900ee351f3337e827b9d90e83f44f60818769aedf522c301755fe12eec9a6aefee515c2a64cffc3c6efd78b3474f91f97d43e339f062cfef9b938d3e0b6fa7cc6db383c711172bd59c5fb7734552a906139d544ea4b43681f689031b9611310d1718eee5c742c5eab5925552436562ad811ab1d69470b1d63c3df323d84353476336f382e6edb751a3ac66c66bf0fcae193992a5482ac58e1fb8e4013cbf674e30800c7a7ecf5c7926b25fab32dc519ce56ca05c8e5698a2516d5b4b394eb3bdaae64a86a64d2339d604f9354dde31b958c6c65e720c9e819a825dce7d1c3e92552bd54b440d0a98a331acb5122a40a44896ce7c691b7a49d7755ba977bf841b9edf33510e6a985603105c372685bd67425e8a762ceedb54f342cfefe67d94012d3e718f90b96574ee113ccab15fd3441369e33a2b531461609d09c020153805c330dc83c26834fa6ca3346d7465c8a18741b8b1b1b181417e7b5dc8b11987b0f5b8a1554fcc20e4d8e88083832343ab41d876e8d40d6de243361806cd39e64165548e792ef4e7cc9efa9f01fef791fcfdde1fce186b85934262070f3d437ef24cf98f204a92ab44444037443c444db66af434aa6ee0b3d0fffc066ebca1329edfd01c4f84003af2d37bf34c58cdf39b28cc3385fc26a21251f98e022b82d217db1eda55ad08e5ea842a99c4b87ae25c799c2c0c4317a0e64e90c8767085c5de7befbd77701869092333654e6479cbd9d6f50ddb5903d6fdb1b0af75631ffb0681ed0c237ffc03a010df6e78d039b2cf9db77330d8cedc08f5f02101f770bc59d7828f8fa4ebc11a8b2cb21fd963fb64f36ccd062cfcad649fda2f915dcfef271a9d25c79edfcf314f5fe52ecffcd8e0f9fd34f240cfefe7d3338bad5d873b7761d6d7baeeccecbd7776167a10fbcc14766637c2bf211e924cfeec12bb658d2da623b2c0c3f2d2305c49e2d542f591868ff7e3125ffd9c9cfc8890f8e899148b33d2c7ed6dddf6857f30fca353f34c3e45b7c83fcf6f1f15fef5b9ad51968b73d1f3db47eacff806b94326163f70489ef918c5c83c762ab22cfbdc9695e5e2ec93e399c86a897ee3dcdc37cfe5c8f13883022cce3e2331b10c15b8c3c8afe7770f9d6f3d1459bcbcd5175fd6896b45d2f64095f42899dc3d4623bfa3bb1401a1382379ec7a607a403cf3a3241864379400cff10c1be115d8f903ee911d713c83d880cfc7e3afe378ece8f0bdc85441e885de37cbc519b2ec020bc2c7b62d41ce7678ba3c6f983cfba306fb157e356880f83e83e89d851099b348ce05c8b97f863a0cb0c1f9cc7bce480ec86deb91f87a7fef5f87262d940cad397949439c60872a23d884a9d9d322bce8f269f6ef541072b1203121158447a20435d435e2bf53a0e6e250779636a78c95ab38196c1c3098d6509c01419dd8e0ce304c79f219288ac46cb2db3e62e0435d43ed0a647033bb6ea01eb35fe868ec5324c40a5be6002023d2ebb7e96816363a05cdc518985753eaf3f46b8e9082683b121f8b46e5aa45e6aae4ebeca1b0a345b89d689142469f5471a627a2d0927e8aa19f1de59dcd97d50bfd6375b2a2c6e7b9fb377023d468142b8df5f585b43edc94f26d498c88a687c6cd1f89b9ab12415215e24d063d95437b411943454e98958b8e5155d324224afdf932f5730410954a944a844e9a4137e794712f3e74855a0aa55b57d815fd8213adc2e8d7403f2a076a86c4148bce14094da57756e7d646ebb190bb3fd789bf86a5cc83a27190a884946c3ad51aba47ca6546ca443983c677c6b07aa383d2e8bcb29f844279cdf291fa2b4a344c09ba8ee76739ff154c892814da4514086d83f7220ec4855286d97f018bd90a4145cf3019413f940f198e724e8606834aa14d4085fc68de1781a1d45ba3eb339a496c8cfa81ac54980829327bd222f667697ea3a7153aed698486716da2fb736c2d6834dbd87f7a8590d2329ebef4e8c704d14e126b344a3ca7167acca9e4bbec91b0db72fb532de81732b8aad26e4a9b457d13494a18723c4413c9f10eade4fc4c31362652e82a1322df7a55d6a8a34ddcbe5ada17b3d26d60b414d79b150ba79ea33821ea4e97f393c47c184d29f45c938892c655b957476bb9ad48b3b3c681ed700959fd3027ba23659bd0d48e96935689f9284c293f8749e4c595deaba391dcd8d2be97f5bf00e6c6456345af38d14f475542bf6ee72b39ef18ba6829c5694964eb4a7bd5fd166e6d6950eb8f0146e371d1b6d57f7252d21ded08fd9d1227bd14438328a57c22251114d71675416ef455dab74ec186b87e092bbacb896e3afab7d037d9a15d9ccaba984f9694529624c2733da993734b4ba3b964d8fa436418ecbfa08e4895725174d4d2978afe23a0321dfa0bc9e999bc3ad74092f12d7b23a9f8b66d67b406b48c9a26b111ca0a9ce7f28b4b795f94f88acc54dcaa4a5b74a552c454f47431c211caf5e3b1c88665a3a8254558442222c846f55080f48d4ca7907f911ca57179a32b293ea8de8beb2443cd8e79d0aa4a6f2239e6b920146724114a56b06ddbb67585ed5d64f316b57862114954cf755d3706be6d98bdeffb06cca2d5cd934f5583b6ff8031562716975362b1e30387e454174e5c3302038bdcc8ecf07d6ee5a1d0dd45c3ca45f9ee82f13e9c298fa18fcb672cea8ca5948e068d98b035f79a13cc51d97742353a274eae14866174ac25e4ee26c81a6380949d9552c90ab3109df7a901cad50472e57089c05c294122b89f1d06214f94aa6a974d81c49cbc8a7ebcf0447c6d6d0db76e004a243df0a8b8c94143110a3a7b2a9b715adf6c60987c501bc3a1e492092e166764170a0a9616539674baa4aa5b46c943cf6faa0bcf949750d4b36515750c8b2aa54e7926b24ad2a778954566c91da4e5800790e5160298022af983ccf7b97567e60955d923046f41e017cfcebdc6b33dcba33fbbd1659126b84626dff27dfe825bb4c5cb2cb9f776f6c0ed731c136cdb3ebbb3db8daeebba3735ea5def7a11e6e4dec12b807d5bfdb5d197ed2e4c78fe79d0bdfb33b2aefbbeefcbd6becf300cc3303c338530ccfe8a45598ee75966f63d1686611826b21dd899097b26cbb22d3b07d9641b17e396e9e181302ccb73700e02831e1e38fb148073ccb758aa39c8c6549ee5533e05768e8d32336659b6cf4020106864c61ec4b8009f423c07e3d8c86c93c98f8f388e81b3d008f420ca4ca10819f8148073d028b3c836010f6ce3590396c8b22cbb2cfb807bdfcc7ce199357ee00a61de801e677178039d45461d5b205b2c5b362d9d9626d0e6d63aff7ebfdf5650702ba99d0192605358fcef4783a2d6498211157623af60aa6a311d72912714c46e8900f9aecf96cce7f3f97c3e9f1086f33ead3ad8c7e7d332f33e2d17f0cfdd974befd067c9b4543a26974ac7290f96d11d862c9261120dd836ec492e91a65dbf69d812696a3545f24c79965b1ef1cc7d787363dd74a560bfa56fcb33b9770cdda37b21af80ed5d682932c581b7c1b628958e49a99e89f42841eef93b33d96edc10823bb346106e3741fa9416e42c1aaf7e12b8070e5a065a7e65ad7e133e2479b57774cfa1e8f92dd5f1ade7b7d49e8f9a9ec842baa28493068c02a8c4eadc76211a800d20003319000083201c079218047214c7261f14000735c2507064305084681209c3a16020100803028180180804020200180882288aa2680acef2000151cf61122185e67abd927c32b011c500886765693e0e5433017d41c4788bf5dbcdf322e34f7b1081ed009c9861a220c503a2de261ca155f88fac21cea577bb90f4744cef322804f11b28183eb9110f9cd7489055e7169e27446093bc2e4af773a88efdfc72a6f11c878311b5328fa51f0d60d004eb11d03fbf838e6314cc8c0923f2a3ea1932c8482a5e867220b6fa7fea4ab065e0d0521e1b341ee870405bb700b12debbfc4306fb6ccacd01285719942511695f343eb3cfb0ba8dc495698c36bffa86e77bdf09aeb8224212af1eb4c85fbd0e8d964925940c40c0371448f3c7466fe5d90f950495827a8ca94d02b9e8c283aaf90c8e2713700d3645c4212902d18829404225fa5c4d015069a72ec9e09bc6a9b7702fe8cc256d4ec73907be7db0613786f02cfc367804b1d6ce250aaefac07a1289d54c18782be69e74d557684e79d19e5be4f9f168b84ddd4cbd5d647ee43df06e99d14efbfa952e9d26318c84f5e26700f7d7a12b8866d627f76caa95deafb44f55aefaf56add2b206e620a8439ebec71263642c2b89dea8b5d4378e7b436285846f7c846ed33c8486ed52b6cfc6a09c45ae52e1a217786b78d8d8f38dfc832450d60553d9b05cc01cad5bd81df1ee79d2f003d6905c459603be2a4bc05b427bf92ef866e23c26fcd8d403398bc42f76043560cc9d26a3480fcc7c73ea240526181af7d7595faa79cba19d8aaad28bb989593d1deb985e37bdaf898aa278fa903cef9bc73c2a51be8ba5143042bf11312647f52d16ee5e1ae8d390c52021d48afb44de6f45bda8cfd8bf579a6da833ec75a3361b6d390f3e8bb60ed1aa3c248844977a3a5b98ca1fdfc9deaef701facb494760086287189a75a245dec914ec2447575922ab107547bb7de6857f88a002e7560a74beb07cd7abb19f0d695631ddf16ac63c810248289fba2b37d06d797af2902522ffd74c8ac5f906070389feb3efa800830a12d44599e003d803310a675e3f7651daf49f52caf5f444f8cdcf38b8719db6cee5003ebe8ac3bc9c50ad892588d266ce24e9495e7319e8cc8bce888dfe2bf65b054ae4018b4d2d141dea32bf12b3ae30082cf4478955a885756edc35a9099a9c3ded79435784072e137af75d80d8009dcddc874e312f04d8ee0ebe84230e206db5f5db02983eb929ef4135a513c3565ceb151fe8dac261eb7d5d405a14c46be8512c20a208c5c23b8703263da9db095ee686c94c409f244409334e414e4fec7a859343dc1d190ae1c741bc650d3a1527fc53f8c0e275c145545111d331f7888508c6a8beb0b9c3f3557b40b2ef039103378dc8cd1a107c4bc19911b09914ad948034b84900c5a4a1ea8440d28e8460321da00f522554a34cf847c1f791289c49f0e0a70ad3a6af18fa3aa12676919dce5362a0b3ec74894944b2ee7060b978e67e759789fa192306dd785d01fbdeae5d41d073e1ce0a740f1916a605eea13464cd0b5402f88908150f1bec22970701cec3f09c8c5524e5030c3db845af3a419bceb1c03c7fb3d3ca37b5f9159c4375c27e9536c9abc888d8985e84550162a8f75d6eebbdfa8021dd7f3f757405ba1bf4458d1fb8938a6a6a8125b5589b793f93ec9b1cc7c03d04c48196de94987ed2862d8c2c459b5565ff5e0fd90c15368bc290ac9f7b41fdb885c121c0b880fea97259b84b9fcf33a699de0e83e62c2f9bed302a0618340b040208c15fdf773a94742b92e1677fd0a17f1255ea47e4747d4139305978afb17d8c47b47498eaa9612d64860f204234bc8710cd1c883c9b17ffda6ee115c43d82c8f4749054e38d2b4e7d701584f0aa2d3351416d8858cef26d15c404bc50202eea9acd45a2ca3927acc9f405706f7bb8e0c3d22aea18285f271f54adfc26e3fb6fa2154d0dd4157c115510b2d3318ed3e5f323127b1ab9f746803919bf0443d84424dce13d10ac3df62a6b291fdf9dc11ee53b475e317730527e48d8c848f48e8924666675c71f50fbbba9c04351aa9bdff65eae748f0ce77847c416fc4548d27e6b6aa79e62d35ce9027e772212cb4156330d11b8892c77fd35a97baa206e43fb82441731ed790b7328ce23dc4ec9beb67b82f5667ab36e6b4ff5b7a0eb0ad8c5824f4910ad839c10154ab8fdbf19a2cd95d9fe81b9f53695b085d724fc22cfd2b722e199f0c9b401484b3430cb76c634af0e016c4778a61c57aa05f6c3e5ccfe2d4947bb77da10a58c162465327f6baa0f531eb6723679a1b287d5f6000a91d801c837152eb0b4080bff666abb80dfabc1f3133ad384e827a4e1b7d1e014e462f9101d50a66bb0aa7c2cc625485372a58821d4369f85ac8e26d5cfc4a1969fa75f8223cbf97026d93ee87fd05596c907c86bc71ac1c75056f011ebc1fcd7e216ef4adf9b2bfbb8300c206119b8c7f85936c945e8f5c8737f683ebad4b1b871cf472a5477dddbb55eb0d3561f647cd48b4c0d15ba8da94a2c3f16b8267973c5124e68e879d386ec767b18ed0940ebee9cce7db83b8cf2f4fd6ee1b822ddb745a4eb61d12d27b5c69be1cd5f34f7a1fa84a64b51072b0aa2377194b65fac03db3a6e68fa71b1e71d48d0ed56405bd5d1fcc9895539b8737cb8af242bc74eaedf8b15ea3029c065ac4a15827bcb967902fced94ff3422d401f9a60f349ef3b8b960763c4f448ed2d32a8cacffda673f86387022caec0b3fe21579f19b7174d76f46ec8b958efbdc00ca2d0414854d5b6744b2d1d62441e922d1e80397e2c594f3c682138b2f779925fa2495ee3bdd5fa7e027ec003fe417630f076f6cb88758796d07b5231e398c492924011ff28d6d4084014923c2a5fb716af8174db66ec284d124c57f8accbe9daedb8b0d26b95892c38e304dab3da09641ca1528478b175caba31ff00f3a9af04fd5dc79084746a72d35e51f907caa41810f4dd51a9fe8c5709c7293c41211c98606bdb10902a9089e968bc2017c01e7a035c64cc4a9f625fd4de1921f883de1438e29463355d99654da8454abb0b9bf117f608fe8465536e772aef5a557714437bc96ecb4a311ff4087b84e1b5ed82b2998259c468a4fe917d09d26fcaae77d477b024582a968f43e484f583d341c884d9534df37c337ec115fc41773f365850754da5f487567f4057ec052ba8168afda655d860bce9535c9c23e5c85f9477c06d5d39623d50958af831f575be3a1f5a57e4574ca7fe21d4905246f3eec95a27c96573591660474694e05a7d250f2035365fffb530ed385d69846ba1d908890b935c9fc2037562c688200a96c983e25966561ac0fa5b601698ce6c4d0f40fe392d1788133bbf6b76826ddfb30694ad89c89adaa1d034282a3942b26c20adacd7f2331fa679916b350676793a59503847ef19dcf11b120f0375091a3132ea6d88d3c683a3a239277f47b31f4fc4642601cb1561cdfcac490d0aa8e110bfe1ddee483b7b05af1cfa00f9c30686f16ca7cc883eaa01e4eb45935186bb1f88d8f1cb46dcb272539d7648f121b3f94b74084c9f5e939b3693ca724f6618a5d5d3f9aced6a1fc452d4dee25c1f425558b8e36381d55bb10d3c735c67d0b109f86448de5fef60e03a019752d5384f71660e3fe4817abd7379a49d77d577d2ee972ebbf50f5309b642b47287dbe407041fd47d7bc9fe32d5a9b541c4b146e3c149d94ec7a76ea14f15de8cf082599e83d9ad9c98fa372fa67c16686745f1461b62ee50d0a0629ba00036bfa4c5ee1dd80874141136f61cc0a64b28a80011d17532c805f5cebe02bc6917ed3b6a6ea05ab2d285e899515d2c9be492f1258c6b214af3462123fd3e79283af6442ef14c75671147809831e86e21526b803ff53c05714c11d7850ca8fdf5ebe4cff6cbfca84539500988b467ac1ba81e4ae5cb106a598fd952c6ae8bfec1a663c2a7c4a0105f11946e01b8c9f60a6ef688b68629eb02e813939ef9275ec73f66f4185c3b6b9a62494d14fd0573acd738ea7a258892c8532fa944450458e4c3493d6f5d2c4691e8a969c95cf074d90b4602ac6bff727b767885132b6b61e41db5f745c5e34f1ac6401b42de86616e35eb2ca1c28b04aa1d238130c29917d177ea970ddee5173f5434c7d2528b8cfb0cd05685aaa1112f35deb90087115d5d6c17ead7872244657df6e6764be1ffe4ae97994a8129449ace2550d1d390592fb20e751f09a635df51f2370a597c495ae327059b4c5be72011c2eea6691dd58a7a15d8fd93c885ee8f6d07895ed3a4b0d30715353383d3ec265670fca07f00b1db1b884f201c4213c4f6299a493f134c5c5ec5ca6e1872025fdd9dd085b23266a20c9eafe8ed12ecb905dc2701cb0c592c3b47f4ced31a40da7be0a0d4ada2fc7fcfc6f1d1dd6392eaabf442dd3c0434ca38e4c2f31668ecd35cea080f3197859da05a42dfbd2b0bd8c0a74c2f924fb6689229eb155328e6b782650322e6eefe16d0771c287b8abbc313720f9381c76b0ec1686487c44507a85369fe34b618b630ac4aae6d84dee78d356ff661ae1095b5711c4023fd00e88e5154bdc5e35a6b7e561cb04deb1c5f2331218b63e392bcad08ddc566984db1e910e449f5a933499167d41dcf82bae811474bf35d897a7bd0662a83fd92fe6c61d505c280f20285f2cdd97fc93b55a87eb657e9e76f4a11dd060dbb20f3c8febbf320498960d39cc72ce4ae9577963e9b4ea447b06632995d5706ccf4ded0f215cc9f3d60fd81460c2802e42e2f27b7baefb03c701fc1fa9bd4f05005a41f0252f6244f45db32030edc0e53006587c6333ea6e6550f3b9c4fe7e27a31e59122d62597a89292df3138f6be42fbc8a2fa456c3e33cb498eb5123e2901f075dd738ae12d7820f0733190d47c85bc089265ea7df1d71fc60f402ead67f235ad0fa3e4442f3625dd9e197dad7ab497871fe62caf50d3a3cc3310f16741b190d914bff058942a6180e7d7b85d4c7b6c71cf9fe02cbda77aada85680d589984e7c619700028ee4a34c408af880d5e7e7c7e8f5eb61b2e1511cb151a2c29c64b86e55fdc31b399ee3e6e3317012b379574b3146546dd1822e10bcedf833691aa99a520951bd718c2fb4342c3eae6236a3ea4682607bea66dfb146586ad0ec8f963c59965895d7337cd69150f67da7374503cd660ed65857a84f89c291f528e1dfca9059b4c96c2c49a201ddfc182b6c39974e689c778fcef93f958631306ec7b931f349abdf15ccb6570ed81453cd583a0f2a519ce1b702a9419d7468b0b7a9f8c1264406ca2745ec6a92462920fa519034304469d4c33eee844df320ca77e5e7a72de18abed12889ed84fd9fdbbb51803217d610e6e3144944616c378721e3a91ac6bf1433b460d4ea35917ade6dc076dd807e2515a8132712573301c70800245c608f3ea3d0b1e807bf4a488d162ee0f5188a9311d4cc2217f17ce5b170ca25737ef854f2a53f04b2eba81786e1f5c7e4a12b52f1620904340e5bdd9388c1b136a9e9290b6c42145184c8f1c481191b1fd2109c33c66901beac8811fe318c0a9cfb04ad32f12993baad770c2e57f85abbc6e159e84ff5eacfd9ff4485943af38c3316bd4aa867f2f83a3ed6f03a635d4cf902c470b0e1720c3c5fafdd5ef5de1e2f6c2fd9fafe4d360d0f159ae6910062cce5a7589b9328a7df08e6b8c932745e12bebdfa942f9ce1176bbc1960dcb2c898c67457fb4ca2ef44f973fdfd0b3b6c112742e86b97b20a5d81757d1fbe71d6b2fd824bb8654eb1e8f539f3c3bfe12d9955dcd30047ad2e26085f2205ff8b5c3274f0c3339939821bf3701518d4a4cfc3413c5cb7d0cd638e60154a5ef3b8ca3c154b7992314f40c0cd0f40712e8987dc6670d5034cf7b1df1d60d4a87c16f69e63542a89f13ad5ad64f8122265c5c4e45e0057fa1b08ea91c4b3dcbd6f9e01e8a0ca0af1d0c69ce76d584934c545df5cd1d45c39d99a4c8d4e2efefadd4ecf19369a2f6a30b595fc64f905dc4ad0a66ff8d123fd4665e616633c654eeac408eb1888fbf94f414b09a87ea3dc1ab3b0dc53cbd986aca9dbe1ec39c356ea10e216742c2b7931baf51116023245f6fbf9e760c20d6038320accbe2e2eb14d2396db218b183b9174290e91139676201ff97d4b63109c55e48a22bfd9d0f0639e8e2437056a670fa1eb69a82e08dfc6687ada830d423ec8461c42cea0ec97c73743212709ea10a4d1c6e47348bc4aa1b8c1b5e22bf19ce28063960e2ece03a64eb284249438a0a1d0709d1ce02e2e09f83908e863d050d9dd0f6bf20044d4bc9d2a1cd71e7c890d5a13705ca839cb6514264a789b0487b0af73090f317470e8e636aa17b15b0bb901d4074180b4923c8c3111f8e111dcd175b0e977490cc697302e870d6a8224f0e223d2d91281d1ac7d9118fc3a94d27aa7010d168f02d86a4b45f99548d48a545b67e4de3522962d04e491807f86b92cca5564d2076ce117474c42ccc3445c6e678dd9149d11298f991278b56b8b16c6aad733136b35f62da76dc69e88120ffee88ffd3a4c4323b64c4d2c052d32e2284213e69a2d226c24829735d443c35f67e552befd46552d326451c1ac7791c8568b4e72d249d72509a32b9298f1c2e027f04f1cbdbfa27cd2e988743f7dad1f3e3ead5410cedef715bdea8aa904868a21742ca68c192919bd62c429691915b445fa21fbe95f64c31e44e0b16194969ff42e3d0e4a074381d6bc7ee98c1e1c4b1e7a0e8d8a7a388a9c3cbe61c2bf2ac58e073dc38d48ebb43de713af68e56550bad51e6ea250dc1d3d32ce7e7284bccd85f76729e79038ba323703b2674752fea07eb299428025c6b10ed877074741d4d0e4a87dba174ec39e6bc46424761c9832323284c5854a95725e224cac49af408cd2015d025d117627720385026b24c7a96204a3d9c33c4323fd2e9e07480d641446ace4bf2cc56a4a6096d9b941c47dbf5a4ef2b35ad1b08c8d22cc990e0e569ebbd65d32f640c2c0f3880e3384d4f73be905834ff0485c3b68ef4ab3452c68e501c0d47673a0cd1695881e10830475996168020da81ac9ed61c19b968ff4275681d541cae1c471951c82b758b756627cd2af1396e0ea3ea20b1d1442986d468c117d316cd5f2c544420a413a4b08209687c3270cce250d763aa1bbd531b0e877fad30c7520406506bf63360ff661c201612589aa0a5ec90c60b1daf11f952e4ac84ee9c0fc081bb4429d21c3f3d28d7c28fc81835aa266c818d357f7c14d6145cc8ba6999919168dacb086cc4b402a9b5485987ab8aa4e1258d9c3c71cc137149bac7209f4e261216e915251110a4eb13431079b949fa34c830af80872516878b66c88276b9b5de8d0d602c81dba8a65b5938ebe4af6b2924359a93581d143a22b18ab429286d331a44025a87d9254db862c84dfb9714c78e63513a90f6d09a26431cb445621d4f8ea576958c2389a3d0e1e1d8bda3ac89d64bc15193637d0e221acd23211d1235a21005b4155da71c2d92681daa8eb203e9287c07098a264a215bb591114e541777a8a48ca06f416226e84633602982d22405171d65355a7ec94842fb95148ea31fc16ca716c31254996a985e44a8b5eb7f6910647738bac390198d9c642448a345e800cfc176601d47e726e17a462893c468812eb3c1303292a7bb9285b2e7111c418c5cca0c564f7560a7ccb53009330f98f0f98617a63e2d24661c44485a13b93bc0ee2009d1de588e0dd3b212771cd0487d1ee350805956d2d4427154e1b8395639d6e23064463b20c1396e1c4b87d5219b239c0eb37b9a2f7475a09fa691ba9856a375e5eaa01c25e328c4419b20cb1ca18ba4ff5d5c710bf94cb30bdee1762c715871cc3af68d904cd7a0850d2c6406a24f832b86bd3a7cda7df58a37c6bfebf81275e717e900933e17284b63476ab34acf33b815ecee596c8ae88bf80e8b548521b61e5ecff8fd267c7a6e537bc703638c061e58a696c2af63468aefdf8a63f45e52a24b7e99bfaa99645ae15d65214908daef6c8c58b3dad837576e45613d327b6482049240ed98e144d318dd30113eb2f9904f9e47d24ed46ed0517b5baba341e2dce367a5f0f423c0e0ca877662a63aa9736ed7afd7d90486b11bab4861301c64c7779f92e074b5f38dff3d24abc5b719cdbf33107eadb19419d16b1f6fb88f08055a00ed1be8cd1efba1876542eee6ecb91f50069d94468b0b3b9eea169706e5960d0bdfffd473da1ebf75754af972614c6013e84ddf870c7908965c809869af0be619ec419c6177cc879c42e8d975d4d2fe1642da3265dbef1278c17981706688c2842643dd0a0a9d6f2f5f1095886ca26cfe1f3dd4b28ab609e83e38af4dfd26231564d6463b67c1c9d30ffde86697339c409247665c75befc01bfeec9729579b881c6d5f072c54ce359cd610a082385ce7501700a99ee050f1587c706304ef0dd846776b104624e998527097e048a650e75401b3ea92ca50d928ccea6101fa607e210de759b9284452b48def28f48384c8f19687b82b803794ae56405858804ad12cac790aca62d7a2022c1e02469eb8e9896cbaf1ff0400282c6da09744c5ce60d2cc151fc405b52b015729a99d9f0f02e23c950a923e6fb414289f10fe5e3d3fff31fca69f7cb426f2e8cc17c37edde333a2b667a5725eb15054b3bcf100a01c6a4e50246b9ccb592cd9d89f900588cd3be1da0c6d6f2f357fa711a00731751819043fd469628eed30c4020f95947b8aca970ad9d76d47326811da1316150a1d42cdd1ede93d28f1396c7d9ded52abce2ba5724aa5612fde2d8bbe79f9617fa049067e5ce770f774f0b14c7a05e5d89b401c479023aad61525a40523a4a078a700bd584ab82dea86d06e7cb9f2498b7f6172b9a4aa80927f8cdcc5f5dec8c3d3f7b758b0b56d147149950fbc6980b662a81295f7bb02ab8008dcb4e587be5dcd46c9087b1cca8598e6d6def4db69452a694520a52057e05d8043da77d9b9a1af4b3cfbfead6f570295b7fd5c4a8698ad214d358b64e2baf87ccdbe9b298897c5abfa7a19dcfb2a2258b76bad093443b7d475028e03f4f318d7ea70719fe838f9afd0cfb09c12fc187a6f2e9f1fd9ddab0de85b0597a6b1baab17e3755495a526310fc07ff599bcef89e8bfbfe4493d9df47e67b4764ea74bf3a320f3075f50492b90263048c90b985c8b4317505c59779d510edecb7deb32cf80f4a9f7e614f04ad87ef4b6fb987cfe56caa394fc6bebac8e7d026cd0cc8fd93a795ee392155ffc99d5ce9e1e65e093068eff53d9d9ef9f4ef9fe2a388a2fc912828ad2dc534d48609deab9e573e777abfcf3da294e668cd5ccdd908c475a55231ccf72f8a1e53a7cea469bdb72b59df6b1179f6d87796e3ca6a66914ff8443ebdbbfb4bdd5373b0f72cc3c19b348b7c9e7e50fafa433b4bd65b406fc95394a8e87e4b8841d3d3fe7bb72fd7c996294629f3c0d65dd97264ea953af9c9e50f6a0e6d52ff695fbfb7953fa914e63e84efa3f596bf90ca3dff9e80c7e45f79fa41cdfd952846edb34ce5d87ec1aae9794459c6433be329b3bef4bbe967dbd0025951aab6e5cf7b4d4db672f54371655e1fbd8768e73e0963682a9f2c4fcd56ec3959f14b7f1aaa992a1ffbdd543bb44051163d6741fe2a8b5af6e8c9faf8f04bdbc9923fa81925eaa518b5443b3566428b91e98ea90db70dd5cc2755ab41fe3d644ed5ad6879b8dd222e5d24cc680932f92f31b3dfb36c99fc171724d3fdaadc0bc1f7d1e609f8afbff8b79c1426bc6a54ee89b6af6f292485aee74d75bdfff5fc971baa992750cd515daf41cd7fb9a29d1c9f331d97f5a7229ffb433573e597a02cda79495507b95f59b453a59e7ca4903fd1ce27c44fb4d349ef19dae9433bd97ff08751d63faeb230f1e78f973cfda0666ac60294e08236949a3ddb4b598e676518802f0bca7cdec3bd30ff6dd48f3fcba2755f9f1973a5d0fba83ffef15fe6f33e4e58b4d309391989767abb2b56598c4cf7ae5cc20b3495fb54d1ce96abc455a336f40370ed5fbbf9f49931781891600a149899aa2a42829979779779991902342a1e3e584ea6f6689429537fb31e5d22a947c758a160984c7d2966c0250c3048e816239a858b1ee140a54cd12c517001639f6cf663b384cb04a498400b9c83342a9f1ed040a51c39e0083566eacb29105004c54501583892210304f490634895e8a1c224e21f9bc95255822bae43a33a21091935d0e032331d9798a958a6966854284082543c1a66a6c3ddd0d34a2ef066884ee8681edcdbdddbbbddbbdbdddbf78846353bc9d40bd434996a63aa8443b47f8420adc8cfac03360259c89426962f533f4e5d6199d2ad8a495a4a3a22b0220727564750f101467b59410c215d7851c4073b58a6c45e92e484192c4be69bbac28244513d2ee511f4892aea9c1073e50b208e84a4d5133eb03c31bbbbbb1f232189af74b972c5992d1e92169bca152ed3396df2440700e8a1891034c0404a163785111a8041eae2062b8af02490060746a6c701eb2e7da5051957847417d38fc1449122c2189145134d6ca1569e64e9b2850eb804c188952a2c2b5c644a458456b85841ba92a0314aa24a18187e3849c2e3052d66c6b030841855c40041182b4daa44998fe60812aaa039e2c4830f2549a23451c4882a5046b8228506563441c221895595273a49e8732ba4d59419a82431bb8d98dd0d835b515102699090e0e566ea8aca10a432ec34bca77bd5eeae097612b14f9573cc7f17a301491712a298b2654a94a9aba32b7b94c3bc6afac94c4de20cf8d358125e8723212c1cc9701484059c242e458c5d82091c1c29492e4822c58a169248f1020427892f2185ca54e9b080af44254d3cb19aa0d25d96a881d9dc2060ea4a0a1152788892440c3c76c8a0c1d77fdf25ad11e30d3879988625db2f1e1efd1b8c32e1054d75e0903c8cea7f955a19d0be903efc98f9a814823df0f57da0c4b28c616636606a16317c989bfd643f50fa96fd6c075a30026c76bf3f214ab86053aaf42e8f71824da9d2059324aa6051c20495d26c78a7e828d1faf5df7483a3d998767963f0411351a0ec156d05607ef0850a2caeb0a28a3047c4f4107eb454ace8303377fb110b5378e912c51628b4f44a852742685c68e14758ec800c1929a4c892658ad9cd4257ee7842d3b95a039218551e53c3dc7dd52663b8f8a204102a9a00f1c203309b05120f304a5753a1529a8d0ade52a6103f58220a29504c6182c40e4b9899596b8d77c0810eaf129636cccc5abf3e3333738c394c02e8b40cbebb9f8bfefece7228ab3e18d5deee6e77d58648c2cc7c841148ba884e22a2bb7b880fe3f7088721c427fd0df893825823dbdd0dc46a4bb41f76c9da60d78715c2a84877770f3c30336b4bb41ae8eeaeb66487a64113e919b40e9d430f691c6ee8ee6e1bbabb5b487777cba0bbbb6be8ee6e1ababb7b868d419985419995a1ccc650666128b32f28e382202fb4c005201fc66f0bcccccd9b7118fb6359d8f5b1bbc22e0b7655d8edb167768c1563cd6c180bc67eb165d68b202c01c2eeee12325d8ce122690b2db21083c5155654114673014c194d7ff0a5a9d8511e7521a6f0d2450a2e51f41628b46459e93cb1ab13058b0b4eec95b5b25596ca22ed943d5a293b446b018a0f9a78c2c4123d70c203234d77e085a6d305257670d0543e775bd0982c01b25c44d3283b482df022a1e944024815fd61babd10d3dd5d85c35c268459139060e61d5a8c0469cfa2f107a1f1777790d51346588c34204e14b9a201b1d2c3fbf05578d0de072a464845a61c498902c5073568e209134becd0031a3899010f6ab0831d9400827735c66c9af0f0f8f3304adf8417b47ed58dd92d3df049fca0031be4c0075e2a3f96dce0a371d0727f870c9a3f9cfcfaaa18a48c52a5004e3835732e6f302a6bb94c7076b358cec10a70708466437b77b7eb7ed7edfd8ad33eb4891b6183a6c2e48e18fa514ce3048c23931f27356f30cda68753a2f5f3ef8e1b689873ee4948d31dca32792e496210c2061388c84153451cd408eed96df476194206dc47b41d4400e11b682afdc27207124de57323c634921c61c402418b4c78e8b40f73c31099fb376b42109a4abfec88817683a3390ad801034de3158c1401c40cbc3f68aab8a306ad9f9f75cbd46532a38777de381045d3d7f6e32e13136ca0a9f48b7492a98d55e9f8e4b542c45293d3e11b3c16e011ae570f7c804330021e217b7da215327b57f6d36c3c3ca3fbb1ed033ca3ffda46c033fa4b5b0a78466f7faf4c5568ebcc6e2d469ccc064cd502449018b6c7fa205346cc068ad054a50718b5379ae8480065420d34972afd32350707a1dae98ce240148d5f7543cb0f4a66ff0da6a15a801832fb71e458c8f186cb53eebb45954f3eb9c73eeeb75b997aef7d537120c8a12633603e229fafe77d3f74b5e1f2f49e515be94b12054ff11d0ab5afc3c3a5cc640506c8d4d50f86acbe2489598189c284c7f87b753b611a30fe153bc6f8d0c745ccf17cefb7499387e92269bbd9cf22399f2ded6e496a8cda8de746f8debb234498f4c32e137ecc01fcf8fdee4b93e9fec90841868cc7b90140d6b34d26942a6c5e2f55d7e62308957b16d2b29f7daf26f37196251d8ec64c383a372cb0e3032348818f1886f8c034905c36580038c38860561400e6e273fcf77c59d9cfaebe206de6131f3ee6b29ff679d2bd57d9d1d0005957eeb994dd8a0a24535754f0b09aa2cce4cc49f72b0b8267ce9c01820574f2e7a0cb172f48a6fef230f5553c66173253df799961f6af171fb35fc5636e919f3ac7a9a5fefeec5c22a07d7d98013da9e2716af923db069103b9d74f3991cf065a20158fd3f3d3be0bdf6eed16e34627612efd2f7a4c662d434499efb5a7fecb7adeab90f6287c1dfbd0e2315de53a715bc8ee744fe331d76aab0ef7bd5d9dcfb9dd5dd7384c77f7768a9af3367def71b0bae7aa465cfa9bcefd1bbbabeebebbebbaecebeeaeabeaeaeaee7c89683255e8a23608415c336964904c7f1bd780f60c69d21c97694e3fa639fdeeb9cae5aeeebeebde53a7ead4d21c22da7a73f3ac549dd0db2fb8e00e1db47ebfc1a81c97c34280bbeb42d8d405298ee62c87c374837057868c87325e860ccf809c54f1983f50aa8c59903392f1a54fa51c4e0a434da086beabb16e9f3e8f3c98cb7448e7dc67ee71f03e8e76388cf24f310d4d31ca4370d2280487b95729e4dec9b8d23b0bd2f711c2af744641681402bc02c8ea80f3f4a32e841cf07a1c1c82c4c133f85fd6c3f3baa1bd4ae70111d0511b35cf2f8187698e5395ba26e83994428f59f33846d09d1aeee186c3a893f525c09d15f6cc8e8c3ffde8c38752c848c6ab8cd7996daa1bcb812b345534dd441c3c036ed6cb1ad676c3bd0a35e50ca540516c80da287a94da4839740fd6e0bfc14e6a680e7f8d1a060015e7d85f5cee5a5c8aad197e9ee755154d7ab637abfb9d7bce39f4e1d811cc4503959de020cc80e2eb3bb796abe19c655df082103a75dd9c2a8569bdcb80e24375eb2e77bddbaeabe44ace39cf80a090f3714116f61193bbbf2ac2aaebeb3764fd1ace4186fc9e624e7a9d3aa70e7b85ba1093ca3336936acde0521c7eed9c73983ea0dff16f29f3e1b5e2aabf6de78fb8e3dcaf8ae0f27537507767391edcf1209eaa39fd8ec9e558c6af34aa71b7dc55ab91cd998fc2cb2184d09d5395463466ca3881eed6e603eeac90428f1d9a2f19d1fcb598d23c0abb43f39e01e94f766541d288268b9f6d2a8fcbfe3698fddbb2ccdf167954f09551fa42f01f94d255e5ba0d8beff97b9967ee590f8453b7d2c3cd49158f89fd40e931087b135cdb500a3d66499edcdf986f4423359eb1438886694eab8d22d364e80fa5d03efc2ec304ba6c870cda7b9d0ddf0d46f9f3f8731e3f93a2fd4d66d7dd7d03606859e66e0b980c657530773bcdce5c4b97217337393de355750ed2787710664a6fed8881b6df6a75299662c9da62c4b0f70cc8df7ab8a50004fd1de698636f6d187659976559cea827ad7fd94fe9650f33ccb984d9cb72bcd7feb2d7ce68d02e7e45c668e2bf626ade1b5dafd2c8fab8f958e1841e3d4a7f6d407e6799a1e4d9cd57b0240a0ba4ef324a4c75c3088869c77a954651fe883b56f7af8ad0afdcdddd2aa566399caf933ac64e7ca6c1ee23a636f69da326bf092d688eb9c7752608632a37f569960234eb80fe0623862f9ec8acf7b21e969e47663ddcebb3b73658c3daae2bb332cbb2e0fa5ed603821098019532b870db855b9661980abe674096107ceb9d2523075dd2a8248d7ec41d1ae9c3c78fdf711a01fe1f3a3b501fc0bf2a02478e96051742d798f5c039640424eed07cdcf6e173f081a034f2d5b5da88469e706dd6cd8d7169c817dec7b9c29870b3e6b56426dce0bc3869c22ce6e557cccb6161e6f5e05b757164eef6a66faa45882f136edd0591d980a9ab315dcc8bb12c47a6397eb9cee3ac2462ccadba3033dd9b9a4c30b6cc975215f6240fd36094ebbc8e7b94fb94049c8769dc60549c9007062dfed31127f4177a92ccb591518a6121048a2048f0554b191f531fc2572fc8ccfd7e335ac45801322f0b3b134fb85dd5b4f754dd46d35eabaa6e09aaeaeccd2f0a2f333373777733338f414a4013daee2eebb80dbab96f4ca65dd74147dbdd75b83199763b4ebfa1bb9b9b7dbb7db9b5f0231dbf62d7313373ab14ecccac4ac3b50b7b1d84ba70775b07f756adbd70a7ccabaaa9dac0ee9c73ceb935dde0cc2e17f3425666b87075afadc110fe933ae0e468e57277cfecce04d09c7ed38d3f6fff72ad7bc1845777ddbf07e7aa630ed39c5dc7c2c71c41b3f227adacdc9a6b3e539acdcdf69720bdcd13f43534197695ac089ff366cd4180aabb9adce46e63ba61c7c5e5edaeeddaaa9cd26c6ed849717527092180e64008618fa98172e4dae56576ce35e7d6f769ce31d6ddfdbabb55aa33f3a6349b9b7774b93b6c5f4ddbf6b5d154535ddf666656554f693637979427276db6af3ac7103ac8acceee9123bfdb62742793e6e8eb545656a9715f74ae539acdcd1636da6aed38a5d9dcb0171b8d35a5d9dc3096ee6efec9cc6ce269e2e6666ee7f7e6dde16d0a55dfbed53957539acd8d167ed4ab6b77779374eb3a3bbb9b7897996fb877991973d3164466ffcd3633bbc7b744477bf7f5ae8de906674c0d148fa25ddddd57b986d642ccf23f13f376667a26e67dddddcd4ef987df49cdc67483d3fdcf79bb2dd34673bd326cb4946673a3851f0db94e26cde1d56edd6e4cedeedb7beaabca5ec3d5dddd7dd3dd9d45175d5d651e74b73273332fa7c4945117b36a65140f71a98be911b1a5c09b2d553add4e567d570c92b9fb5428cc9638baeb36a6ddddf7e6cd61adb81a0b2415ccab4f3a38722f676353958aa99268e7981a2863cc88d15155ed02553c7258f2f4b3ff5ec7ba979ec7d48d88674942601d1055aabe97ae636aa0381ed68c98f72ccbfa855f8a1285ddb11e6640eefee9bb766964c91f7127066000fa007e192ac2b4611adaed5b1483d66196e550cd9be60a253abab1f75ebb0234c7147f5caaccdcddddcc49ea98ad603299579f4a0513d31c7d1d2d5544ae13a4bf526835c8c67483c34aa84ef3986e704c6e7b1d42f77e8eb90a2093b967d5df53d5b66c96e3a98de906e7ad9ac4284c7cf76d8451c697fda8bbf885126624d6b2c5b96e353abe476c29e066942a9d1a2d68f1553a33da306ac798379a6300cdd11c472ebe4c7e4c858b37a082a62b2eaecc55d26aaa629c51d5bd3b8c37c8c87a9646f0df03f23befdd0a50a2b03bcfdff9b8c4a2cb828c581a3df923eec057393b3f591427f33b770371d48d4db32c77c46056e0fdbeda603c23009ab3ff98801baf2e35372c6d96552a954ad0b9870fa1b3228661d8753908ade8dc4107dd83ee3907dbb5eb86385c4e5f3a95aa13cc6c06045f7f61673ebabda7da15dadf1761c434db9f986ddcb8a5927b2900c12c6a0e974a96b5ef498f59509446501a5d7fc168edd3a7aaf1ca14eabef7e08b8c916166ed876666e6b96582cca1c5e9228ef4de6feffbc67f5b8cd6b3de7bacba0b3703d22f457dbfbfaf4f629cfd3c1959553c7e78870caedfaeaaae3a2ec39b01f13399fd980e9eee308c65e2d27f1bcd69667eeb76ddaea3badfa6845d5e96266d8b2db3dfe6c64a7bb97c8688f53384bdb9bf7eddadc595953898a9b0d1a216618430c67522ae1835cde10d995aa854cd5a37316434230000040053160000180c06078462d1701a8639aab80714000c709446684e2c118862711cc75110c64008c2300080300c6018200619a720416c5177cdc3464866a258291560ef9bf9700674b97eac17636c071c21c6f550c3b9ca1715bf028b187cd545d0fcd02081bdbd2f9a9dfc8c4105ba99b90f0897a836c61c6d796dcd9e95a61a88c5e213b4f4bd754feeb5ffdd7e54a7ff251ce73ab92c52374632f03fc2fd2ca10648bef7fe763082545d6a00bc8b11c9ac3d73060455f7641ba8041562c71b58a93fa1427805d2353db72dd5ef37b33771cae17d5c3c65904ffc3ce290e18569644972ed917514ee41c3e5262ce5beee7ce343b3b1f260713c1bb4619008c56f2a17aa3afc22120b09ac589b5c658673e3dcd6daac686a460372ef3cb073372d01bf8b5581f8349a295d219cc5135886e32939f2422463d38764b6b56c446b0a692900e59aed016d59e100980906abfeb0e84784ff2922808034d562ef5f2ea1801e49e7cd39d58d7b4533ce83904f4c8254049b052bbef83447f4c45afa192c29679518f9f5d91ab48e8f066c1426f30c324e4972ce76dd044d9ba8ce1d4f2004ab18ff1b773627d7b0aa2776ea27c06909622ce2977d9f4219df5e1e585156f7cb19ac0454775684ad92463d990d40b60e868ecb0bfb2fdd2a4207746ad472b724d1180a66c13cdecf6e71790a4d65cfcab58e08215faf8f5e50b7c61490291cfa28baaed16c673070d2cc6441b05a31351480f6d99082bdf9e97986b5e522a34ff7c14424f965e540fa7b443fd7ab29aa0f1e5e9e85225e100397d830d2201ad80dbbf45f697287ddee05f268e199d587e8cae595403dca86ef084240123aba30e7f63a375b2fa81d8d45470643c2b4beb19ef99f95fe5f49294457f2e57c83a7d5f8a9eac6a380d3bb2a9fe79db61b6a09c309bc66fdb42070b46757735980a4ca28439ae83898b7b8f9630ab3da9a0b3fd996ba7c8401bdb46fb018225e8db16c4475aa5b4413418278fe03ed6a55241eb7c5e0cc0876a9a15c66a064241c190bad303a0925d87034cb81cc865afb80769a03c55a02f89c8c4c636b493d1db50ca34249593a372082c8d17238f17ccaefca5032fa876a304c58f82c8bf621532db9053897231bb2db98391db2a9462d34233e81628589331e28893781df2169952e8978510909134ff7ba20437b7a6ae3d0094439ca65d02344b0d7f95a65ae0b654ca848cdd64bde1e825208cc20b8af992ec05a07ffa226ccdf92d9b0e61a94658b66dbefac6294dbf11a7953431282948f72ea3fe8649d6f26ce5a97422591ac71076fe080c33a08d210460d436067a172271d384d1bb495c69473a619631626b752d0c7c3a62e2cd670065eceb527f43f6258e8e04d0a0b0bd3488437668d085d5a48d112c3372521b317e9bdc6287d34447343ff7aa92d4093b6171b7d478fc8b502987e948a3bc95b1cf631bdaa151c88807024497fd7e0ff9c8ab9b506469048dbd3c6e8f92966b25466efa79893251f0ff6f72ca1a39f1f14fb9f884a20c8d7c4ce56a7394514156afb9a89cbe7397a44427b166a682394bdd66fa977dde62d18c89333f9294c37f4f3ca742c241cf9849f6c9dc98a339fcca9c15e3adc90c6312e0a07eeaea1de0e65a40d983d5c894429025ede68248a5f803a2b3d0a525c0a5e4798557a2bf95ad1fa797d22e772b5f189fbc3cae7b9c018aa20b7a6d21adeceb1d7092c67876aed2a236780663a601371321f0e21a12744ea76ac854234f6f6feb314480541ea304d7c565359b024aa5fa81bd73d4fdd1bb4bf7d4738d73a3823bdb2bc115470b6b3c7cefe490321405fa6c9f0890eb325442fe2809f2f36bb981a7f1015de17e1aa514fd6e87ef5966f63f4615e8abb2229f204541c3e22f2429c7ee612c413404ab2b21c44d1d5da592b599ce283ef1744b367063c6880eb8bc05f77ae9cfbb67119c55975de7d1dc16e648c1dec23b563914f551645193ea12c94a9dcf5adff85b74138ec6e4cb8e806a23465f9cfa8bd026210c1debc788854f89c821b5d2f19e5f1667330cb7ecefb330b061284bd1cfbbbd8062d96b57dc40c36702f516ba4a3ba3be43cc3dbb7b3a5a5078ecea82bf6fd15af1a44e1a627f30d987f62190002a2b7256626594a323c2046cf9e11fe02db056a058e2442abc523f5dc375a2c50e543a106bca667bd45d17b155971c4b5ca2226e3e7bfa72005e431093015baf81f6a39529d89a2837ccd072dcc7fcaa56fd1115005cd6cc2c2ebf48f6eca301ef7c330675ed71bd50c9a6faf4288985c4c491f937169689c2899f0a2a0efa7bf2fff8b1e8f0a77f7863499233a702e45760d7371509553f513b68c7be8de0ca262787d51129e97590a39da7670a7aecd39dbb2a1a92cb498c2c77f7d689cf13bb8ccf70d964949049f197dc5ffa83bc35c559d094f46e74cb16f8eb30341b6b383ab168d9b065a3557a2c6ee8f5bec404be35ac477dad6f57a11620ad0cd8af5962f91d39de81db323d3a14910e28708e82e01d0882b1d0bcfcccbd9075fb9f124224b8c9f1b280bca826a53b138d5417ef1d469cb523a46b7c28bb88831c1f0822aefac07a95a33473fc2b753fc07d2f1c21720c26e2ad9676548709832037a79c36c7961148b0906db7d0235f15e029373bb10581bbf548dcf3dad3c80efa22c1ccd73de8e76bd9b43b5f949e2c67ebe5fdc3d79f89c175f724edccab5620d1ce7e6250f9b8a5d0217ee8a2837c5b0ceda08e6d71562fd121427c5ed97218c00cd5cf607b3ffe282a60aa950ac7e54220599b27b2c56be2e71c1ae5cb8e8c4aad2ccac2f08d2ee30ffdfb5f2a2dba680e20f325b3e85df67933cc9a8734102b11d677cc457ec2be44f180d2118edd85126b4b3fe8898aa6717430f31817b821e6a39840f5b37b80a97e380872f74674092fde529dbded0afb9eeaff1ce4caeba3763f5e030f90edb55c8ea87d84d6e27f3721bb6138f1d98540e322e45ba1a8337335d0f3466dd5fd8cc9d3faa0dfed8d0c8c79fca3b0756a301c9cab529c2396841db3e47a348d7b0e4cf0c950582a1041cc50bcc4a39507c68289dd7b105e013c0cf00bb817788861511ab5021392b9646a375e6b81098d9beb358754109025c95dbb78855f5e813fed9b1943e1764542ad92184ff8b2b5da598dcc8bcf868422fffc145ded1c49001b2ae3079c51a548a5c0113674e91ecf017e35d1afee3321b42de49dd111c572c59ac2119f289a745e2c8781a9dd8797e2b06cc20fb38cd8d949dc19f26ec82f1538165403ccd34156f651c85fcb452ff353be420e8cb9bccc10bc12fa81a106b7b28c67a1a46729ac90c77545060d266b3cd5dd84ed8deac4c1a2fe45b7271a621d3479dc8de2892094dae836630efee9bac805041f6de370965438afff893a67479e0280b77382c87cef24ee44c1782ec142ba3b45f0c125600bcd765c273afef149efca26371642e0e5a926a78b193cfb890113cb924f393e6f591349716040223901d199cd5930892890eec917bbe4c10ebc210a4af225a3b83c8ecbd73197f7ea48d63bac93701045ce5f2892f8b918903430de63152577119fe8de160ae027bfcf43dec397c36faae48479d9c9e1529c2871ab9a833ea2a12d2917902ff69a42632f496ce43bbfff3f60d56006be354158fe1cdee7478da77a6045327f4635c63b4b8e2a96bf92a45ab41846a14323c34a203fe069753effa89015dfb1cebe1f795b92d740df78bcc122978daa40f38686ebda359b02bdf01a3b57ca119e03570a011c94e8c513af8133c363b8d780a88aca6c00266f670a3723eed046fd2cad3c1886ea8da39b5d0238ec2b2a1026629cee80d406a32a513e815e8cc2e063e73d47b615a70aa439448d7c1620f5d297da21e3f747076ec417cbff048c3db7afa2f7e228615ee198fb59ab472d358ffc360c85712dd5ba0f015d5f49eb0e6674a3a3e190ace40800f772afb012add14d8d0ca15abf4d9d75824f866e3852a4206712aca22c31be5f418fbb95bf34ca5ee428b0062e113edb25739782a9137f59e332898a4e27b159b136c3c162546e04f89c1efabedbeec6ba416eeb606e9e90e352515f207ee870497e3906aea9792197a9da29000bc0493dcbc31c89259089ff2fdb9e2399f3d0a679324ebdea54ce15967c65b0ba708768922daf77319dec688cc62ea81de072dbf1e590016f32b1aa4126aa8143f23afa947fe1a50b3b1ed68e0eb38e54fdd8faa86d132a86745345095a3e02cad1c411383de3b9affdce802d14c9ee87c53dca49328977e748220a78b1d1bcfb2830747853e1e62bb17d8a7943aa3e23ef5f2b088a2d45f2f1cd696fa0aa480083f90eab3aeb398a72fc61876d77f06f92512feb6f20e2c8e89a61859741ef35a23cb4fcaf77fe50eed857bc12d2627db8b66caac4613bd6d4d80e7cdac6b6ef60a213ad578d6397c2a0611bf0c1da14c73ae6910066ade9e43049b3d930ccb3e76ee7800610df363f425dd09754abd239cc34db29652aaa5330bd4c1ce9ef910c7c87d1c85276d14273ad6905fc5709c81cd55011b0c9abe1a57a0f8bf7bdbd6810c6b8c866cb053fe22b470cb0bfc3544e984bb1d30203acd5e06265d599734df5d934bd618d2d60ca74b3488c03cbfd197f423d092c7d37392aa45d9fceaea60550573aeff5344678ea17652da17e5905b1da8e917afb0050d43621b7ba11c3a6859b5185294ce301776dc15d28cc322394802f21fc3a16502c38c54f0fec509ad030572704a551382dabd1c746a3db534c770e5ae08a661d3630e27ddacbd029d8f0eb0072dd0649d28989e418a18c2955316dcb400aec257b4938d37e4ea485145b6f252bbf15931909b817eb7a170276e427bdb9a2f4690c8e5527a4443bc8ba82c41994cbe5e593e76225e1f03f537aca08f74395022cef05e4a154d1fed094984ea0fb7eb45fe31dde358ac901dfb78b1e84adcafad78b978bef69e190122d65528f168ab14220c848753830547e97393127c2d73a3350fb91644b88dd51829f3f04c38d8d0f4fa74fbc24283613e3fae73f31bbeaf1ffe6d436d2f09baac2810074c981747aea5f9263e91683c84e76e9f23907d19ddca6dd126e9c40d17fe937dbf62dff37aa17fdd209e0d1cb64c9a6a6685533ebff03756625e7a429ad5efc99fa46999b6a46aabe5ea45c0c1cf468223db1de3468d401e02867d30392d371e62994a6c3f1e22e1490484e2895e686bf377ed894558b4d2d99e7255886d369da58c5d07dd8c22bc0fe33572504e6ebac947eb7d5aa9d3c4c24d782f855e0848f17a6211aac4f7e1e65cf9782fc71a74d4588c0a361b45094c9ee0612e5fa392f8459c3bd4045f35d76ff18e8322c244eac15830ef5d8af3ebc702a79df4100c2d2cb357447dce25422b5b31628a3e140b0846358c30b1a242e53c95950189ec8c778a70826ec59e7a1591957f4ad0fc07edb3df4db9cb3640dbf5cbcbe06ab862c2c5fe3c4d59543cdc819cce009219f79a632314f1f9c0d2fe5d1cd48db093a403998dbffab63bc162c73cca711c35540151514faca446bc0775855ea54eb0712cdb128bcce3f859647bc155d9770be8f020905ee72363ac8212ac188c5b3c12d0aaa87eda3d0af6a2f867b1dd2ab478ae024d4d8fc235f5b032eaef3ca235bc49f7cec8be21760ad9af9b38b52a19aeba10b209d152c3eb4b33df30b2f5a325ea62f1e679a1f6362c6d122b3908c6fe91efc90d341420260c91711c171a1e204a5401d34d78dabc572cb0e2eeace982e4138fca407d2a99434ea852ddf743f667182c12608bc134160552c26b3d852b89a93a0c22bdf42520fb840cbfa7480e639c587c852f11ceb6340f46818aff784b78126135b298950cb81f756d402a2757f9168e72e79816db566a1e01418b01b036ef59848a4759194404a4f04c53b48c84690cd904ea908b34586f361f087f4a451c57551b9491d4fd52fe51d61f4ec9feaff3fc2ef8d5d5888fc3d28c01dfb8f015e45dff0da31415f533136f2ad176246d342e3f455560d08d1a8188ce857ef588f6009f1760d484f3c6450f454747ca8598b410d3ae9fb0571ab888d355796aa9c69a52d778d4360325ddcd18c8d56820761a17c48797e9fe8b488e9522a97129287117e4efa58875e3d28e67e1f1bf09cdbb724dc4c30d4041e60485ee4c16bbed6c7364311a9477200d5116bd9293887f68cfdce82cb6a48ee3b0393a884f167cc37bf4da504a899593189bf2a3df95f1e7daf41b6f0525565608efc0939f5e885aa5dc5afe6ab4f4dd9fb6b9ff88910a7c2fdb040f8f8873a4b777bc5355e1a9cf38aa20a8b66ba146a6d95902defaca81e0c505856c0e7c06240de16b04723fcfa7d5f4167a0857edcb23352ad6c2e7f40e91c89b9e4bd222680820f557351037224f6d4ed63cf87ddb2c0c42e9473c4d869369a8e5b5c57d222eb81fdb890342d42e9591d25e86f934c88dfb5940a0103e716dfbd9658a575286a80890079b611f6057df18f4ce3af97fe36030d2bb67d465a0cdceb147ba569ccc6b18b8859b203859e100272c807b14504a400807f97c58deb81b238b8d6326d960ade89d3259776dca2827f4ed801c77321ca010cb7d1cb96a6dfe449f41899e7e8239f44d49f395871d8b2084ae832ef24e26af29660838f8c54f2f258ceaf1e5a06aea76a16c983d6165770389806ed6d29bdefbb0d3551bc6d96f84903df0d7338570e601b75e71e6f83e08390d98704346102c9e157b87f38ebb73ae8d41312df68c1dbd9138243a52c860718a08cf056724287b1b999f7995c58f3fe805351cea43d127d9dc82e48cb0d43a85a882bb7f339cf87a94457a2f47c29175b8b1603bcb5d2dd369ad7c2ca42382ed7e082ea339d71678fb156a63dc09d5e8d2fb122b8915d39b89d7143b2704f2d65b6220bd9331c357f685f186e750bc7ed46633b4dd9a79e5ae5b89e0d7ff29930c194e800e1bd213d7e45c098d22e9d51ee96ac53838786986babbdbaaf5377463e22bdf986d4a134c4a8e8b5cb7f1e8ee6556911ea124bb3a33279131c6b5fa6945044ff7299defe8a47313b8aa8cd34fe7cabb8e1c6756ab59a48f2db1d9ceb699e26f68487baa482b07ba2cda378d1dd4992216aa6b75d282eb4b10fc4a51d378ed4e50fd093ab29373e28865937bdcc57dbbd37b937c22de4c8e4b925b4fee1f87d99207e400029cfa97001e8c27b37486ba3f4a6f8d7dbfcaa89787cd17f8a81b61a2c02d78235de5aceb3bfcae9b6c3541a115264dba6456f1acdb87310bcc6dda9f9732e1857a1983b22028b90b7f5159fdd093e0acf03b576ad56861e051dfafc036f03233c42f00f72f7b1c999b78bf4852d7991668123be04f404cd0ad36d83c1b587f37055416f729bde56f6d4e93a13ee0365f5f610c802818293476d9f3dd4304d94c6d6b2959ceded4953642ff0db1dadd98a7a21bd5dab2af40a590e0d1f9d7234ab7bb432d36a05a64a5be631043f62f267d6e8ac93c4719228cb7345d3c9a026d5944a4483af37caf814ee41973276f38a7f315ebefac922bebaa84984f256ee65c62566ab75e30feb0844e988a110029e4efcf12f91637894be17178a280496eed139871a6c930b6593055cb19e4d351370c7f8fe38f16c12f68ee1aa6ddd30e8fdd1ebb16df0e3f0d480b9c9b53ffa252cc6f20d1514adae316000b2368d3905324db205156ce94900197f36ace65a9792997b830ca962e4a48612d0d5dd73ac8206779ec50d7d221ac365d29a53e99805699e8c7f06cef9829d2977d5981cd1d5b53e59b3a75ca4d82f63a28347cab6011a44f114003baa4f415b36bec6f8f3bad2f2547e239487c45d52f612773eef6cc435a48e6ed4bb6424a3917b937b9af1f75e2158262403660dd90acff00ec8a48d297bec589e82afbc4301dc8171f3d2778c94f06afa13ece0f7c4e6dd2b977f453a7af23c10a19069dd3f10374b95464a27a4ad414ef673005c6a045b95e2ed7e2cec68b2ba8c7a282a1ee8a683e0a221d1588bf025059a4cf5a1bb8512249b80576c3834cb3cafc5d5a81bbccce827d8044a6e0bfc238c48063a40858fb44d63f327f2b01e7e03240713dd2883e31b14105ea37a8ae704704c61b5dd2cb34ddecdbbac152d30b0b99c304be92272db13124fcf5a85fd59849c812664ebba632290ea7739398b9d6ec44b4f45631dc0229380b82fc1dc364c70545280be999290284b730175df45dcf30deffeba027c4a08733074887e69b4f7c811a93636f06e9b0a86807c2dd5de2e870419ba798ee42a94922b601fe9daaa4fabdb0327aec31eb8ba3cd29da32de87f77648b543a12f9d445940ad17c3f44aa6e5d4bb0ffdb9f7562eb66da7d99db184d58bf732d9b56e251c1847aa052f30f27fd668ed1750d338f87a89bbb831e86871d091f7c22ff763c88d6c7180847110bbb9c47ea649f1abceb6f9cbcb93f9e4e61fa81b2e2556bff3e02be7aea1c9c3c73332b0694058d72d59ecbd53922b3d77d83c8eb6facba048aec7d33503da4b01bd24b42e911322510db8c567223fd1199d8f93c5643dad1977c2625243aeaa29a1917735bf184e29a7b5c12c9a929d43b79a30a7c86619a933d9a815303b5e6c65f0dc0432954d0a697edcf3d22eae5e74109b7437baf4cacd325343bd85519ac7589fccbab69559eade6ae0ddd1ef573613c21b26afd3e4de52bef2fa5f59137eaf583818e3224fde165dd8330273ea8a76f6ed278ac2861ec0f6437d573a3aa7e5a7f18fc52a31039d6742da0e188e82d0232c80b433447aca86fa0326eb744f69c4b23dc755454f380958a08a04d3e60980251018fb8fad7a7ca1a85a4c640949c304659d16f78bb7913825d611bc3a852bf0071867cef0087667ffb3ed25dd910ae354894e80be5508c8609562b54d94eb52f2fb427b0144f574ea7c53eb26acee4be4029965b1eb5b12bfc02f0c2a8ac72360adb41a7a564117b14611b6647358ed3ffa866c4f122ea9d2d8a22a501ee918c4755591dadd8243062b4042f6ec84517e1cd20170620309922b88c3a4ccaaf8cc83bcc1d34704fa74efccc6e5bb2cb61ed26e222666397355c20134fed4872e6f3cc66057ead2b28beaa9ea7741d99453b943f05ef48417738ab108d47064b030616c21ec3ed415a4837bef51ff3ca7bcab9c1681797492ebf60b4b61b16b386d50add4ea8ad1546a526d72f8814e8dc59dafb6a9133da22064ab3810d2375af3854ed055bec3bdb08d87f2dec66757d0c23aae5e5a040809ce35e89ff950c451cb0044ebc068ca538b7cf54270ec79b87cf83568a5fc639d5ab857d5c9222ee01b92fa89d27c13d037c9f1c4df538fa243a9d0f8a0a9b0ff9d20c4954ad50e04ddb79abee5c8d4bbfb0bc30360c5b14523c53a693d289a21989efa761de1bfc6227aadb5b7cfee0d98ad0aa87b7c6010e1448d2d9627d7301dcee4e1fb09c84041bf5c05501acc3426a5542ab99a64ac7d910474b078e67a1dd55349b0773ca3b03c1e2f5036f01fb388f824f1d8737e618b390f8bf4ff4d59cd27386814f360b9a203f0dba0fee9adf6bd7e2b9d5adedb6948b948c2724c1804496f307ec3fd59f67f69a44d373677d5dee66e33d5b447fe95cf2b63808079d62d941be0c76155b498feddb36fddf95b24444598bce32c8a879f1bea3356f4902d28d188e3bd27fa7454c01a83cee9592d78ef23f3ca8a472a50c428588ed77e81930848287c014667bb083ea17028357ca4a9dc6491c1f14fa53dcba00b9e935270348db07e36a3d1300b4230e3b6de0f6fe9593568a64e745c00639d5269090635f8b24c5c5c2f302b1b96415e9025bd215d36f67df61f622657f26f9bdc28ab67ecfe3d2c8d1e8e1ed2f95c567edb16625a14cae37d395a8e4240fc3751a6f082f906e093ba25a319c2444aa1f5e41264fc38119848718c6dc0ad0e55c660177212b43f262bb606ef073d202a1a10bbfc4d05b11a91e3db9a436c2a6d4b9b1b2626b8178b5a93ed6ccba4e7911b7d0823948fdf2eb8d4634df067a8ee52803a493b4cc587d7b95d4646b8576943e1004617e0d59462db654a052be024d6cdbd7d9ec21f0ef1931092c0b04c611957d3357aaf058aece6d1620a6e5dc715cb928331f6327cf2893c3a883bc50f1e2bf51a11eb58a5c4ab2377ea3ccc0cca29baab83f55a0c56792f2261e14846eba0459312bdf0b713c54e4a6d1ada034e043db5ebd49a9e9a30e12642bcd2265c1f033b3dc7499ba4e86026692378ee06ce0f364f96f9680dbf1c6dcb78640deec1f2a1092b3fe5358520530233eabf290d19258e053b94ac817a56f117f32b3a43793753d57a7a7832a5cb9dc2c554c318347ede1b0f58a48ce63d87b1b10de59e4c8c230aae5870fd050532454979e024bedf5ff63104d8525b6f162f29cbeb47dd2bc078bbd60589c98911d35af7a9c00ed25a848d904fca76df07c118989fc8c16361ae53328034b011ee5ef7f5ec2f6cda1ff163ad21425f31fa363ecb2bddcdcb2c2cc7787f5088f388753260f72de33b4b8b4940776ef015269b3eda0bee9fbcbd8fe31d721a4e91e85636970689596c2f72038eff7151727103e2c147e2a962f50e9cca129ce1f4a034de7a089f993769167acd1678d4322e829de27d4d9c2a912926a7e73368991f4d663751bd2535c39ac64e169e8a6679496bccd2c9230f79f04992a941b8d9ac7cec4a320554e49ce903dd5658133c68353fb4c0eb249217859f9d2a9597073a032c22fc275efb541d0c21175e03945715ce3dcae8e1a4ae181cd245939f00beb5a9ba36a63c0f36808e882da552b9afbe36d0a5a03ba2739bee83f486d3a67f2f1bd0b3a6ba0d2a89d01681679210933e2265fd900419a31d8e22d7595dc7c12b81ea44145a9ebbcb6337f78816d825d70d261120b8207c3a3ad564254efdaf83479b12ab124689da7a8f057278f2e932a65a2031f46e5159fa4edace1ae753d3f2d6a6516c1b1bbd93cfcc049be28849cfcf0f792d8b9b91da14fb9d86dc0638cf57aef16b6d8d0a40e306a2352c20a9b2627e233b5f5755ffe0d9d2afa4049617bd5c55b2419acde89132d42725f80fc5b8124fd1433d3c258906f09cf204d4a48c58b125ef91927a974eea68c8b29fbf642b58ab9dd3e61e980ba14edf4f45f31d1dd59cd3a358662c828ef6272de93f115f72d3b9c99432e3736f30736f88c42550a3f432d93e2cba634deec0c04e8e82148b0408614c1fcfd17df493e59f81d9af7febca1a4f893e39c356b2070c889c74c8cf3df609f7a9648a9b25c913fd580a33789dffd0047be933a33e8cbc35cc0a9045b016281b452cb54fe2af600e3bbfee899d4043becfe8f6ee7fb93a3813ec04cf772a105bb3efc4b6c316cbf717c8acfb77262aff281ae00044d4b652d8e8ffca639b916ec71d422d37e126efa1386bd51a7ceab5737a03af08ade481d189300e99c8180b7de993248be1b76cefa21e73e362cdfee4e05567c939081f8b2e9a66725df056008b179439146a271d701844e9fc9a631dcb8e47980005ef236260a69477c29241845255b2611cd6b9b5ba476088a1ece3a7d8ca1e9b15cc25baa01104454506e05412d0ba5bb9b14e2f8a888878bda9c7cb0c36bed9d22bb8cc81136f879c693858b3ba36b5235754eb5f4b2688f48025cde72db8c78397f6c04b8f2c01dd78e029057706e244ec0326e6f6362dc5f4bf14884bb03464c52069b55d64b76526484ad0a1645797192095503b7e9d7217d0724a921f4ebdefd2d0c1d9ba3420d20a0e5526ce6256f9453a02fbd1e7175a92ce6ddade762b0a584dd748c7094b65fc605e2ed157baacac7285cb6af39d77063f88cc81398474ebdf2ac509482fc38f349eedbed794257e0656bc277f5f57b748f67039d4bbb614d265fa1da03477a3e5c042def7d342a9d1462acff42e576a0353151464c6af959abd004faca6a412d65602bf41f08d6f5735ea2908250fca911f1e6a8a9ad54c4b8f3f5e6399ca34856518514ce77daba122e44d63ea574024d310e2a067ef56c51dd3ba96c9ab428b09d4a9c4ce6a0200a0e54a591288aa2bdc5c2434884940bc2c5bb71fd123647f9ecc5aa04d01139ae8e6d1340d5a776007fa0b889ec6d51067990f8a7ee1698be0f28f7c939be00472072e1a1d1045fbd69450a88c0f7e6aa5b222b3bcf3fff3ed38b46cf503230e687facb9fb899be2aa4cbab0c4fadf2b8daeac3edc61904b80c46f47e4a9d8663c3820b54b222397f2d9ce1020ffb648c88081b1dd75b656fdfd8786da7f8a3ff4fff835bfc93f06c20074e562ff0c8d5a68382440b14d4e8608fcbfe903a2d1e164e2603322db4b774f5826204e297edc4f62a74b6b2e76a88c19fa3dc7fcfb4e33fb039f254f2152cc759353d35b7e8b27a2d66bb7424c5c330f2c4666f17b0ec624302028b9dc3910128fa1ee65932785212de462a4a2da7b4cfd613b7d78719176664af0e594350c5c403972be92a4ba037976d2d4d0719f5a2a47ecae8357a8d47b35a9616333ec0dc26b6316e92beb19390ec223004a544054dfcc0f7d4ab9e42a2cd391c5ccb86723151ac2e5826108c696c8ce9cb248a257456490d045fa4f01a37cddefc5bf463bc91c2bfde1d595e1e700c1aacb09fa9874d7f95c4eb33cb542fa335d71735046296841a489332938fc76bae21ee8d1854ebb6e6586ac032d6bc9eb3a16798d9f60c070e87a467d831e26ed28cef70842ef9c5e1733c8983c639b4c2add2468a022a1462aca8377007fe0c7dc401c2b0299a0eb83553d1cc1fd2c17b7ef94fd6545805054023fca65465c7f3b1c1d4e799d0126dfc216dd8f9bf838409bb281c29ae68f8b1bf39efad6c80cb5d56b131ead66b0e760b056c80abddfc7607c89c97514cecf5189cad71b7ca9f9d71dbea8746ca14ad9a4891640a14799ee5d4691eebbb6910d58b3163235640468e8391540334f646118fd04c5c980346dbe512b2e3a513f77e3729ea5a327ea3d4188fd8ae9000aca83cfba5bde5ec99fcafb7092def5f0e83528046e480da12d1ef9adc30901cecc29afc39fe34be2f2d1e65dbb162236763d863a7b92718453a32147cb99383d18250ac12013b2137a6ae1264142c94abad14845e27b9b2eea4d6150ec76ae86683c99006ed47640ef2647ed0ef1a5c33b38dc82065b295be50a1cee8346b274defd4fe90cf6be3052d6ca2600044230f7c7aa768abc8214f02e5afb1d2b6f47897a677db69b7dbef3cfd685005091ead7c4432fca949c4d4008105674dec2664102096bbab666932041b2357d5bd82c9630614ddf166c122448b2a66f0b9b0412262999745aa8e9a217eb52f4c563058e775c275e8e25f1da01f28c524f3e5d0e016b5ebd796ee7d993476f5eb9b900b457368e30a8317262168c4007ef37d2204bf5a1803734db3f3c6fe81016c112c344b9eabe0a4e792ea9b6cef202dafe742e35f0cdc62be0492e45782e53b9bf88877013876289c338c1709c3884250ec7898670e2102c610827f830468d26e2c6b1aed08fb58713d5eb898c97121ee5672d8ccd7c35f3efee7adc3ff80ed10ffe43fa03df01fde03b4c73f81dd20e7e877487f07510702ed8869c26b0425d4ceeeb50a7a574699ad1a7c721c8047f377b0d782d32927b596c8fcc40f054f0c5924b26adc61f16cab6f31e8c26ca765e47df38a3949eac26384dc8c28795528652a104adcc55fad3da7595324a0aca28254e854fc252f4a2ad857626c1b8154d6d2397779fcd4ff1521c988e58555b8b666d8cbfee70499d01ab1a6b588535a8f04dd4586315d6408d6f52614dabb006158e85342c13bc6548a822f9a175203eec3ac81e9487d1071c077f10462a3b540f3eb396bbb0e0f5a4e7f565e120770ad2d1ccc04ef8484ac4d909c5a7383bcb181983629141c5c92593cff1f261b0d67e3adf8dc64063c7d204176c391efb2fd138f1df7f2951a67515a148529925a8af3a4c08581b48110208c638dbbbf159e70de23893699125a07d943303708a2c41bd298f2a5a691fe14e464e95c608d17a2abb5cdf4014769d80cc85f9bb8d06f2f992d29a6ea8038dd89b7504af5bf019bc5c4e48d0e3f76cdb94b46ab703afeb448623c4c7dddfb389a474b88137d3e5b90eb72ea801c7f0c78066f019a617ba08863f037a83ffd605657f0f3a5dca61ae09cab991a68fa790256b344233df43a04c0daf85e1a81f7eb4c04c7936d1f522d1589ffbf14d7f6fa3cbdb0c777f53af573b73217b2e024cfde5a08b1242d6cd261aa395a64723573ef351b8d5167c34f4962a7c2a1fe9b02fd4e063a10b3142cd0e1a0f1a75f186accba89f59a49bdb01a02f32e0e7de2361de0fff86c0731e808731965cbd5f0e4e4eb2f31887a4462f5ad068580f9870c7e48fc41cfdddf30bd566d46bb1190575975a0cc09c100bfeb6f88aa8ce9c21f5c048457ae02061f77e1c27f0924a2976250a222203d50963b8941ec076671b8bc00ad048accea233200c3fee07e3e5ad58f279bf0a2edb400f0620bffb63d7d6caa5abaab447aa95410bc2743c64dd609e3d72545dad897a6f7e1b3a1bce02fc2f3ca3fe037442d94cbb243ce723895a6290bb513b00d92324dd7ef6139bbefef6f9554330809c6f48f116c2f6212963309aa8f191a478eee941c0fe9bef1eb84fb905fb70e51591970f742fa206ca5db4c9a0b58f0ebdc950c23ffdd176e399e5cd3da1be4b5033a8d205f6d6db2c31c6b8ddfcde99b1309529dab56fd837546c2bfd6ee57638448bb308e49c1d96ee82334e23118ead56adefed6022c5a06a2fe8265b0bdd487257f267342eb16f5435688a5895a232d3ba0cb8f02bfe4b9770336e1c3e5b0910e1cca0cb115ef2aa342a43d479220f4a3bc0568223261866d49752616516900e11dcc640896a4932af0bae27bce3d2cc9dc7c4c15bbf98844c56aaa194f65254d7153d3ac43b5118106427496c0bd3f427b6e98cdea7c44402122659cf9e4d3a71c0a0c44bce5dea27ad80d22c2d2f6f610430238c396d6b8fff413587f09e4a85ecfc2d6b37bb89758ad1af8bf67d34abd4cff8a47319ee1d090f32abb1f4dab7c8cb8ee2e944af7442fc0317df00b9c5a719cc294058b6d3e0959ee1cc310d5a16fdae72f490c1a2159b11864f1080b5c6490f0152345204430217600048f45b932960dd640d409993a2072dab68281aca3fd518175135e79134e01f1b0ae80500d8ce38371cbc572794eb97dd4b33ee7e140374d8ae2ee9bb7f74f7b8b47671b3018808351471784fac3bfe53e717fa35579c9c5a977850234434623c255b47e6affc03dbe0784dd07beb74a24028f4b41cda02ab1c9240011f31ede84a720a95434c9e71fd31cbbbd4c9b4716975653795951d23fbac6b02da03283a8797d5c61c962e472f6c94738b175863682ef1fb6f788b5f90176ea189d0174f31433765244431bcd8cb3dfff0a547d64293cc82417fa9881da480b8db04b2dd2cf703edd017ff7f6d7f922b4d6b4060cd5bdd6c82dae60c565e14088f8d7a7e2846305e9f8b1703e71156698b99bf5daa8d462a58af2e92868e2546f79b90b9652c5546de60de207210834827bee7d32e8109def1a17a7033dc5d1f5a2a49dda4ec32a45d114cdcd0c4b8983471b9cf0f4755394bd765648023df73303c1d54cc31696a896f15b79901250337e566e8d76d417277d100f327d34ae2b0987b2619ef0e04382e8d0abd09bdb8a1b55055e86ea015f09ca81b74358de93443afcb347275f12328eaf809460e1128d5112f6c1bb78ba6e9f74ae04fc16c834b872177a2ec8a268ed4bd1bb02e591f4964049cbf810ec6b5688227ea7956006a6d47a0f33ca1bca7dbf30268f74bfd43ddca8d2c6d17028b948d9e7e8165626bbc5b9103efa80a30a2c2911f0cd978e382565996e012bc816101372a8db8dde0ffbec0e3d0e2d84f84dbd626b4d1ff71b69ec55160552ef64608c15b3dd7e6dbf5cb103153bfd92221fa20b34b22acfc1c8a7690480ac7d5dcf121e5808b58825153238ff5a0550a72072e5785f1ff1e4296b1ec28e182ae4281211f6c07af85ab1878a34ba39e85ce73c5807ca05a8cbc338ae934361e02b01adc65346b3b8ae96433b95a8cb3267f0f06af7a33e7c803d294511978b34e95e76bc796306816f867963cbd2feb23cde3dfec5d309d4e8459b1519c22da7256c11b789e584be0040ae8e55d6ef6fac607649fe5c3d15cb142d60778031175e1164dffbba601cacbf84021c4a310380e2aea32e26b6b751d72b44718c08ee55a9174f14aa28978377038952877d19471c634875a6a2d6521e2e0e3fe2ae84cc536fa0030bf25cb88841f9cbfc4254199d708b1b09c045b351443b4d50aaa71e34982b593c7f36d1b8e1c6ae5624d85660e6fd7e80a4b3a08807cb0f3beece6d7c8f28df1f86c19fd98a3267ee013d933edb7d698d94dee52dd3d18fefaad9468e844cfe52c75ee067451cf403c45b92dbedb71bcd592c82a7880aca84ec54c4d30fe8b27f67d6cfdc656bc86951b1e0d3e92a17dda3bb40545aa07b1519dbb86720d2099fe4f2e69c8d22fa2a8a30428872c308b8b1382bc3b8e2b541fc25d73fa06509a7e7509f57c843c56cf4ae71f7652929218e6783f7acb7e26c4292386eb15c5a3dceae456c49d77e456b19d5ab53313596e135a56037b276486814f1d402bed87e2af7e89065cc4ced3890e103bd712d5f5ffe555fa55e331501dc41c5ea96d55ed87e4521d9dfda319364b8f3cb3a67057c2c0d220e2bf64f8e46996c40b60a61400716f0e7cb443323a65754d6482d780bb8ed62505b890387b263873db188f370832a1ac65d5ebb145215ad5a82dfdf347cf09a05ff8837f88336769cd5617a9260f1a8080e64446e8920496677731778c2f7c9854500c68420cd33cb0807c94dd9b83de6a4bc88b8ce1a1a66c4fd72108fcd963445b642d230f3db29c5f085252e6c9a9df4f54e8107809d388fb98bad8be1039106fafdec8c6c6ddff10dc2405c3c0eca8cc63e882422456e962e4309da13e5b2928cdeb1bf817516a9d850cf9eacf9ec5e2108dc114ba08650c97c90a5f869b802239bec11d81e8e40c5f47b7a408b2db5c34a9ae969c680d1dc6e480bce5032010248b6120363267d0cd4ce68b160a4d924f0003a6ba1854d617911975c99f2cba3c5d9a96ea6fac94f505e982592a24726a070355a9237f5e087015651f09af564289410505b886c244b7cfba70661e836c685105aac76ec05004195a7624dd569376193766de4b59990e7555c7d8b64d9eb7d4c565de12909a6f8700e4745301543fab8208c75b3f88e7caba4b26333198e29172048695a2b7ef8d9cf4be40e6808dfdc40998cc5840d2aa763e45a2be891896c319b67ee783123929a7fa42f8a1fd04b6f05c40f731e1eaa7a4ec9a2f440aa43ee0241200ac4e8b32b3049c492a1af3f152668c6f51b501f4f420ab9fa6500701b2ac01e764629b46a69584c7223a2274ac08df52e87572152ff0ba7f653f723b1f939b3baa9b30f471eb57d40f368a6002f5c792c76e9711234e92e5638b9f1622cab69df7cf1c07e8eebadfda52f22fcaeb994bc1b045fa8e74766054b55ad2522385ae89053525a12bff04e6febf98434eb51404591038462f49ce36c271b4be222f1e7aabc94f9ac83628e39d0f57fa792ec11533f9eff7b84e3a06d26c6051bfb0118b6e4921b142224a083ce6a04b0d6b2ee5b3d13268e6c4a1ec5eafa92122fd7e2a0fd90a3bdf5052d37ea17eceb809de7a0a7305066fd9789ec09de7baea3f6afcac7ceccdefd326e80498e9cca5b0768e062ebbc3baaf7740f7ec5402fc81f45bf5019ec81f503a41bda1e557f34c24602024186cb88ddcccdbf4b57524416952e8abfd2134fb60fc42f2906c532379df9dbc179cdd4f1d503372b152df47c3975eb4e25049cc6a1e9d5a586112bc4f187cd174eea2638c7d2f3fe15bd00ca3ae5011b6a87ee0f789d0ae6ead1088a1f93a47311480b6d4067452049348d589848ac4c1b225972b64db7b34832ed4ec260abb59f79476dc84b16fb84ac2b789b0905757eb02937061b93248903a19e87cc4fd8e2ba92175d13f611d8cd6032082e4cf8da902b69b2f94d6e6e309e11b34ff14129316827ef91e7c6731f4d52d8f83e8f1e83ecbad22a84394f1c08b8db97d09bac907dc8ad8ba7dbe463e1e4ac30ff4c40472abcc790661968874405856de3e0705d184cd5860af5fff64d3401e5a6bb106f91797e2c6c5204caac241f416f5c3c505e6760a87cffdbabfd4e479cd52bf5b4e501a7f33d564125f6db2d7d5ccb32879988f63b3425a3f23d607c6a35131bda5dbc68cbd0325127683093ead55a1f217d9c8c036f622ac425a23bd4f8fbe45a54cedf6ce2ff17d96ca09bcdf28166b52f351358a7dae917f8ab92a95e21dc6b99d06d3a8cd7b0f3ccff7fbe43ac3406a26ae536fa89c7342061b6b0f6d56b438076257425e4cd8ee9f8e38e36ddd6f11bbf538ec13a18bda15822773994439090384242a8aa335a8494fba379080932d40f409a3814271e9ccf59207d04fc60b5a58c4a4e534918c4da20b735d4e403b938b3f1a4e33b90b01010007e5b8367effd6d5902a91582a83a5b409fee873e4a57e5438bfd555814e972d1439d468510068ec5558cf1a98e700707d8cb7a25bd035273a305e1b874b3af14fcf301f7c5ffd11ba203b725ca87697fff8cbd8fcada923d01ea52b01eb9be3f7752594a790982d9ac1ac9f4db1be26bb050d4bf5b8ab08ce6a14634027c62aca89875dcf2f6afc3301efd31d5bcf67cd2d20eb43797021771c75bd4f68c97c59d11c97505fe3bdbaf6a5be3394189c34c138d814cb633b0653d3bfc82040b1a7c64752e0460ddb14ac31d14e952cd79d5fb0ec08e61b8cf3883d23e7e09cdf78b3775c4957a3a8c3dd0310fd540dbe2d608315d8376c9f0a0c06fcd14a0a599321ed74d4be3011e0adb2c9fd0f021ce7ac59ec94c75581306c1528ee34a167c1a8045981ca1a4b5936c0dee4ebcd8439f473337cc8c15e1cd91b728953ed3aa8b195de9fae766ef7779722b1e7e5e8ecba222f7ee094484f27b355119f59e21057013688cb0cd4ea5bd9f59a405e37106681ef573622df1259dc76b45d1d61c1c1039728685a824418ce25e11d754b5f37b4b03f83e10f18ba7870ae97ef406fca058756fc0a9901809478d8a78f86a25c6f7e2e382c84fcc40bd0318296206d1d13b79c5d7ab38637433f675f906652f050ca516be5df64f63d43abf0cc8134241544e2acdf254cecfd13932fc923d668f413f0edcae21c72bac26f451f1bbe535c5e959bb2a0f6f1536f2ceed08032ffb4b2ffb93c3f3d101d17c5d3adbfffcacc984aff26695452b13c0334b4ae7eb8a265cd6cff9c10727297f0fe5ac222910cee1250160248604267a07da55ff8157837b66fb59ce59640c0001655a87e0a6a3efb16064a7f5ca9047a43e9405390781f39bc05c657eee75a9fae4aca0d35761745f3e0e812929506d8209e5efbbe8a55d7ac2f93175e3d5fcd54c5a57292f40702801a5df718ea85e31537c00e16423f35e45dc4711eaccf7fb8faccb050b62477c8e4165d354ea638f0bf61f04d47df732392798a870aa4bd6fdc71f3c61e3856ee1fe146525000407466816dde00deca08ecb9f74fc4b8ef95dfe0bff49dee4ac22378220e2e80dd9588ec02eb7961eecc2a92cf82e03bbf15dd8886bd7780798c606adc39f8edab245115e6bac18c263cc8f444f1f9439c0442567835a53a473289c8589178ac8b7e5f99d4a9c45b39663fab28bbd1ef93976f77f689dfe785ac3807f9c96c70bf5bbef5a5ef8469f7cad691cdf8726423986e56209f7845914814c16c7c2537ad6f83901b43a3947d6bcdb520b36f0261a405e9cc80b78a4d4548e58698addd602ae24248e6b84ca055ba3f2756cbd96cd5bcadb0595be1645d9236236a578d23ca176719d689155be1fc1036a24c2703b260738b05b04a6f7d95c103cfbd76b8552a0a64c277ba06b99ff4485be3f781b1b52ab9a2e1ec54e30ea9fa566e23c2b67d2468291cfd00d7e75a7a90fda82685c39eb71890d79b273872cdb82f5b42c10b163cf36871a50bdebce12b1e96207d9c434ed121b292105e37168ca979f473f53a27f211be0819f6c8bf0011bbf9625ee8866553a7c2d585c604af8ba2d169b3ee05352eb6f9b8b7a7149603a2639f621bcd057cd6fe37b641e781a2e013db14dac3f90c49fc4a0a8c57e2f9774b7cb968c885ed56e39ec640fe41b230f20e730606c4fd71ac8a69ae3fb996e524940525463525d2cb719341d2fb9012e00a17309a43bc039b669e6b3195f6b50f4e108d19cdb7544daadbe38592af0d60df72b2da0630142f7e02bf488729a24252efec5534c67b1f44c3f2a623aa65c8487308c327d8ac158db2b0174a3c7bd0d20e1a9be6462c19e0c2a8c28547bd3bf79067f8033d6c48809f55a11472da2d66515d4b6a24db4baf1501c3787aa154343fe0c3c0660e1a8981ddea2e39020c0a21e998388828034a9f8ef77fe8c46d030a13dd4ddd7edc246a40f3892b80018dbd08590400c964ad73a1c8c24a0cc06d5993a560108e7ce642659d27a0187cc2733c2ccece4895cdfd948415ff1391c3913d2aa7d104d748c5750f673a7ef313288799d09c9ba9806ecb6faf50c811a81dc96db90b0622581c72b1505d6041b6d0e597f1dbb83e3515234a11726500452b70b943300b7258ed1c16a20229e80a3cb815590e1e8380db9644f8a9dec293a02b9036b83956d5f810868d0ebdea1d683c171148142d28682088db1874b05b17ac6012ad84ed1f02835707de104702b405a4898501ae0a4d70f9ec90b3e096b6255d0d8a022ff0195a0ec6816c823a8d97e1298ed2d10ff61a0261ac3728c6561aec0df914fae10e2ef9a8182348bfcda1f3ebc8be14ca870831a34eacf9e274af6c37322bd9611f7913675468c2e169adcb40c44c61a6ad597ea04a314990d422016a5d768d5e27f94421acbd29e23be3865f3539076b070964fbf2b628189d136531e363735cb2d06115d89e9b119b291614c803fad7ca93541048284b7332302031203130066b7048b5d91f1f0ed34534ea65165ac0c2f60e3eafc78756f3170ec667f541a9b34c26d676b5a8eb4f6ed8304c1415d12b13f241adcb25aa0cb289efe3fbbbbbbbbbb794292519d408050aa308bff3dbf6f3ddd3cee1faeeb7ce317e676748263d89e153173992e536f585489f0c7e97e6bb9711baf404b5ba0e8b116cc9f300789fef2ee0118f17f008003e3048a03420928e2bce1add331a305fd00405057d018f82c0f45c118687892b7c78809808031eb182ac20f38524d0136118863d3ced44d0585bddb7c8a5ce5ee1c303f4ed0478d433e60b49a09f20aba8816cd904c5374197abebbafaffe3fadb7deb7fc892de9f56ab146dd93dd0575b76ef335b41412eb289dfa0672b4014f806bd0fcb964140411f7e8f018f82ecedbea1008f7a6cb38deebd9ea206f2fff9d909b0086969e3e8feed6c127c4cc5d731d11b1464fcfaa32d9d6eed7e8aa5f1eb8700a85da647dc827aea07914bd532f9e5f99087e7390d0f006cc9d365c0239e09c2286a169a137c21e9f32cb2a70ff9d8b2c9cc37c11f5b3add9f1fc95abfc847b25c1a3ffc4a963f5a26bf403f410f4496f402b9be6cddd1f5a57847d797db1d6d59dfe7475bd66f7d9103cd1b443619e1caea32f9ede9f9a20622e7fd219bf8ed794603a2c0b7e75b306cd9f3ac0fdf875c62f2dbf3e13715e0518f9d6ca3cd80472c3bd946d9ddee79c82b4024ef6eb3460aaaf882884c1fe2335f47965634dd2bbe6fbae17b8de60bc98e2cb72526bfe187ef4d2ec364d8045c02ae6229380a8682c7f013ec049380a978042c869be030cc042fc160f80b2bc15eb80b4f31174e8291e02d2cc547b011ac858b60227808cec258f80a0bc15658041c020e82ab30100c02fe81a9f007d807ee81a3d803cc03efc053580796c2393014e3c051180a3ff113be816d609893931a68e8000736d0a4811964608a21034d9860e0021658b2545600060abc3001251288000492b8d0c20390b0b08203948e18492ad200062c80c81005085121850404018284c2d18f138c6e1102660cbd0240820ca13108e887a708e7acd1fd0eb9e99093457e5bbf26598a572cc78e7234740dedc49d6050ee011556db94d0c645c8dd7d9b427b8f02730fabb8fe239437d7dd59bcc32d67398ee35ea873704cab14142a2980f2b4c387c8aa7a0af3a1e0d2272da1194a29a594524ae998db426e69bf2d97b4a5cd9aa5350543b08a8205c5ed1f297f4b46a1cee1cf330908915bdd8227653e2a9e8c114f101b8299189c2a5638c59d31385f6e77b75ae39119f61f6e4bf14eb7c19bcd5af2fa394383304b5eee55d4dd9d16b9eaee464116ce30a794524a9fb16826da82d60c162491c5925616a3100a7c3062cc82bdc85577777b6885aa074ba69972cde62c84494341a74794f265b20d7b1cd4fd925d218df8ddfbd674b36dcb9c6e463217ee94316f31777676767674befaeb0ca1df9aeca9f5673195ccb22cab9f81473a96bf54da3976ec0cc35fdc333743bcbb43f29737370077aeb93203b3727fee8cc160d7f3af9ea166bc4c57f1adfefca55aa6aa25bd3a542830eb4bf17b7eb60e9eafdfb3f3fc75a8da92c979762c93df9def3e872cb9ef6cce3bb9c212a26899dc32f9f59e9196e892674bbe3bef9ff3a5f839d6b34c2e5a26bf3a5f6fb6639774deed12fd7ad9f2a5d6a9ea17f5f68997a9bbdb19a8f71ebf14cf8bef2052f6bc75e4a4e4e689a414cf33cfe790b3b75244c17bba7d486a95877cead2715fe4e0b77d22ab65a9ae18b6e14e97d2267ea91377123be78af3982950934dce5397220554923205642528252825a82addd675d7bdebb44be9d9bed4c29e72b9b72ea476a97feb68d7415501bdeba06854e720ed292cf7aeebc08e82e166594ad7bd3d65a8ae84f1d9830eba1429307ca8e694b28f4bf1bc31bd75f7065a96027ee73d8bfc725e03c19d30f41d29938dd7755dd7755234ff422952a44ce134293bcc43c5a7a9b4b99467e7bd30d498fd35abb1465fa9cd071e69143cfa9ec94ea3d44aa3561ab5d228bfb94b200d29556afa1ddaa5cd43ba3d48755a47b3de926f7bf0359a2951aa44a912a56f965ad3b277eddd0dddba5fe336fed9a6719bcb3a5a4fb7a75fd2c9a6f5e5b4fa287dd7745ed340cb5c6caf81efb4bb0d6d73fd3b9ff6214bbefecc858f6bd49d9d52d9c079b76d039bbf53ea9766b3ef21bf6f91307448f143d2dbe179373bceb65cf279de671bcfce33b9a3037ea8037ef6dee77c240c92f6d067435b4e364a6d749ae70b7fee29535571fb793dadfbb9399e29a6dd804793e767e8ee93e51e8630582c31ddc3e17fccfa982c99eaf6c3b0fdf197dc3a1cfef7cc75675de696d96be4120fc77161b807f71a8fc99a87e7b92fc3efcefe6bb74c5d8696a92f57dbfba16a37cf33cf7324e93acc377c26dd96df3fc8715c3f8769f7d2e733ed79da793e746de7598c8f85c1f9fbc0e07ec973b87f67313e160cc330fc782c8b611b5998cbbd0622f17cf790dab3c89ce7c8cc7b1e9e1dbb8921b3c81c5a0ec5708fccc1efef25df05c3efc1f7380c3f8e7b16b3e4a357ac5f45eeb307fa340e1fccf9b230fc1ada72c947590cf76016c3622853b1989ed81755eedfb9260e15d425ba734d11d6dc385b8600e7cdfdaef659d5ddaea82e8e3bd75cc1be48735f77aef962cbfdc2ea7a973f6acb79afebba672e0b9f9b97fb8cb39323c3f73cce9d7ba5ecddfb384ee378bec9108d97bef73eb3655fef756cd9f7d3e1b12553bbcdb277271a9c645c598397f599fa6699c650dc237ba752396d48f5af1c674b8ebaf53bcd32f5d5ec979f65ea9b71597582843f5d477b96b3defbd72ccbb867284ed34ad6d70f7340242dfcd0f96bc9b23c9e69cc93fd92e6992d63e83afe3c8f9cf7fbbe102a7c6e87ec5e8704bfc99ecfc83a43722af52b472483b49f97f33887bd1c29dcc3abb63db7b47df6dcc73d9374fb9c6732c706691f7ecdbe86b607f4ea673d29de77af24857bcca32e4adbb66ddbec46af965996c236aad83b52d039996ad967951d0e907e6559966559f6d5ca247b18b25ff27511877e9ff77ad1c9437bb6dfafd710447ea1d7c8da48a51f885b8b0077b363bfb26f30058f92e6f2d3d0b29f600af5f935ae1c596ed55908fff8c13d7cf4eb47bfb24fc241cc4a1a45d894e2d5d17d66857aa832b50ea20d48eb68f9e8ac326c6b62a494bed6eabeb6ba4ed3344deb28a52dfab54529d5b8ad07868e485ba310a594d21f8878608d676799673268a78ee6367b0d2ecdfc156f3624b62d37a8497343993427809ac20a96860a0c6665850676850d6fb258716171422aa0d694bce50bd455228beb7d6253a0aecf572b18ac460105450e5b669cf04c0e59c2138453447963a8784f84448043c5ea12e10d57a95b5ceeebf626bb409c31306eeeced7f758d0618a0e4f5c12254b17f87cde8b41039fcfb7a454b95f6252a22ef73cc57198cbbd77010c3069c2811828930c1f4f1e337c3c79b87ebee7229b6d00c2819f7cb47384e3c7397c5e0d3a9c8003028ca03841608aeb841d5c70329a9261041678f8825ca30b5b40999a461e88c109025152382020024e6f6c10327a9061841b83130b3e04b946a14f8226064d86119038c1e63c41c8ea10e38bda15c5583f40850950bff20f2060010031278d2a4fcc9e1184132120c1f421115059f94630fb258498e9255c69024b98e943599898fd6a1a6289d92f22949cb0033027c800be70820c3314a1e4842dae7ec8f8720299174eb0d20038013256dca4a505178cfe9da6121b0093b800db00078c68c1694e232f2e6c91c4850e802e6c41c31138a4be1bf5b728b93bb8babab29af3870c2e325e985302e00bf78d13380129dec020808492bbc5d5d555d59c3f642421e3277824812064bc508217ae15db004ea0045673ce9ff3878c1b222023891686388d3feb4522c66893ccf98027609221b027a00b52c0c6a76f24b33b4116b87c41e307b5a080ababab13627c90eb7ffe876c82f1f7436e89f1133c7a800e313e099a24432643015d4033279f10e35d64bd1e47f95c647691c4f81876f68ca9af367571fa24272f6ad4243929d17924bc0c285640426cc0f4bcfe9e249f4108c878193fc10890f0245829649052905f8a00430493258660224b18242dc4e925340186c53cf9048a93d116374016242652fc73ffa40d2aa25d19d987a2013422dfc9c89216ea86d1085c2fc59b399548717547570adb1277b44d72aeae14d527e3eb7b40bcc54be05e0619343ecce34f06192401125ec66741c09b2c329e849f6011edca88fca2e62d6e0012ec10323e68b4494e46ff594e2093850c519613888c6c4b1891f649ce9511d40da3ff094260fe9061a520c1f4a126276ad3134fff4fb427db930d0a3926164b801343f185641ddf13fa186356b8428cf142ae2f6acf6b065988f1317e8248845ec84611baa2f8418a8fcaec1933aa3e50021f4c30062926ce9e41e653fa22ceca656270baae28ea73f55d3628c8bcba3f3f43d95dd73bdd1fd798c5e32a4cc437924db00ec4216224e74de104dff8aef746b2890c4d46b8e3d30083c16e593f08c89c778ea4c7e96f24eb33d8a4fe8f9d61b425df9ff7abab916430014eb73e106fe919dcf396dee1430760739e102385f9c51da3a8fcc31d7fec0c30ae8b8a6f6b1c5a130aa4a420872aa0cee06045942ba0a0794af3048b1b54f0a40dff1e1fe10ea5c87f236c445a1ad82864b202d8fff4a12450cd1792d5e99f7cf227c80027a3ffa226cdb0c049162da081c99a0ec438b081e9434d2e6862a38117cc00031966bf5e5b7c211932cd7ebdaca0c4e00bc9f069368ec6c15cccc6517f360e1930696af364170cb8de9b2f7087255f97fd197c21592f107ea8840616a81fbeabde26180c06bbe1d77769f1f15803276e6a601b30b941057000c3ec576dea8202b35f4d39d0c10b24bc8c09906065d8e925ec40026f944c2f81791081e92594c03d80c0f4124aa8ef0326be31f0adefc5179444e8637c50fdbe7c83aa7541c8c6b04e77de1f3c8081d0c2ec19f567cf080212382ccc9ed13384b0c2101c4004a538478a60e48b24be2a026b800d0cb86101d3877ce8c94764fa50d3d310280a8822040715a052c821015282e800640ad20e5f48868fc2ec576879f88e66bfaa07d80a1ca27db551067882f68c1e68dff081278eee3f307ec88469a43282364a90c880888b1b31b0fac107587cf0032c5e50890281c840b8c240987168603857380854515fc24051c1ac8008c70f6d75b9602e1896846ec2b0cae76a3dff000a71c10044faf901f249a2c4ca1504830044f2aeeb3d6fce39adb65042e25ae3f280e7fa09e4720131100cc4ecd716e0102020170c881449e38afa78f2e05620df7e51d7aa4d6cfd8ba8dc51c120daf509c310a8897647201fb2098f2ed2bbecf3ec22fbf20bc0212e988b8deb19e672b948202ab8ccb85c3504e1bbdee33820927743d2e97a95641b660d8e9ffac5c1d8b8a0e8c7acb2cfcf45a05f48f254119291983578cbacc17d516f7181163b7cecf8022c42beb52409b32469a9803cfe8c50216eff3f860f34a47e45020a6b481211dd200a47528ab42200faf0590d38e487570022b9a07ec81b34a68c23f9a2f1aa568e3421f27539ddf1475bd44a44fac5403f3ec3c6f1d5af3a3ea70187b860684024205085d10a618367435494f7932421fa86faf6c31af2162a5355be7098d0325569134c209f7b86b509d6724c6e38d27e7557be90fc792cd2a0797a7a7a7a82e60a2b9ec22feb037d393ed0f399f05dcf558029b8dee739056090fa3eb60cbf8ea1eb1b8acb07c84abd6572c31f5bc280a571c0214a7be31775e3f0ef72ad70461cffe7cbfab35fe3f84bf581bea1c020f5812ce5eb01b9a4defe9073d618c9b229cbd7a5fef85e4be11c668d59450a5a8a37b90a71c6a0acee8c41a5e15e0077c6a0b25cde32797097731d35fc93cf3fed4c010a5a07b0c83f797581bea849f24918f94129340c765dff24e72a0e0c66144534fa7f92bfdc9fd7e2febcd75f6590a1660dee95a088dbbbbe5c32de9ff77936030e01fa9f67d8eba9f879a09fe71ec8fbf138767f60b0ebb2526fa70f8d4ed7eb215a8de3e7c3e732e010d7573220d228feabe5bdd74458b162a5d622841042082d57ae84a11107c00206692c588ef0417e597f7cce92250ca5740c0106d98618628b0944804128114420a1a30830c8564411ae9f26905f863f3e6b09bf3e6b0183845fb584e348924f32e182c308238c98ba710418841e714497024849498da317026cd9b2651c9518001248d4fa2589246a0553002e6090e6c2651c9720c01418a4a7a6981840972eb586793289cad10b3884f6abbdd4dac4901260904d0925c4e0f80206a15fbe8c60080c1864030386ea9b38cafaaeffa177a9fe587fb4bc041864fc6a4ba9fff13d1739fb95544564d7ffd427a70f3951c924116c4f7c2139126172c3afb684e18665d30d9b9072c140cc0ba2d8b0a11256d7388ee317b58b2c45301f8fad77daaff15b0a449ae57667bfca25adebf341ef22b7cb2e0085fc3cedd768cb25ae672dc021a3653dc740a4f067bf40f0c748aa1044b2d68043c67e39dd16804840545a0a3caacf532ed0778e6aa57e7cd796cf358eb7becf173567010e01fafa1cc50210c94505e622451ae40dd8931792345e2808aebe100d9de3c7723f92b389d580483a6251e05c1114227ed77d3fab25b4237c56bfc446a2866a4021a1dd796e025cd2baddb356000e19994ae708ff28e49e550022751f960c75b9e73ee4beab3589299d637ceec78ffb911cfbc57d5208c4f1f9c7bfd1af1ebd96e2cb7956019882f85d7301913c234e889dd5797fc602145203dded5dbba7707727400d696c18b9bbbb5301b8bbd3f7a7eeeeeeeeee3568943063e8150012a2b290e1e446652114c3923f02005c6310d04f8b61184579a3fadddccccccc50edd4dd6e60347bf271f2eeeeeea69dc1bc7be0bdbbfb13be32ea1244bf7ecf7dead2c409ec528b024f71825a75b3233c889bffebba66c275d2c8d69a3c0e70fb7fa609db77100a535c1fd7a34ebd8ddc7c48f4219f94320d6953bf660dedab66cb2543dcc296b26f82437c8adb96b5adbd7aad5eabd70de6990ddadd9d4b4089dcdd99527fda9957d143d5fd623d50b933b35de2f7f777221648e6d4dda953cf9cc875e0a33e1dc028ca66d485bf7a7bbbb77b7bd7ee2e5846ccccb39d703365be3c46737233659ea23ed7daea1c1c97d59d8ca4b5daa5189cecb77d4981f48bb3cad5aa55ad56ad56ad562eab97ba208a991be34e2da2686962ea10c9279dbae46f59ab5ee589477f0acdda3d757f1d469ee7b1ad39a4f65e05a957eb5679a35bdd3c12f6655fa51ea576726449996edcf7e5e8463da7996f115f95457d72ef479a10e76cb5a28859058da2bcd16c1c253ff58b76fe149220eab25df2d75ceb489847c4a3465e05bd73b7644959d3b6efbb6955805a6ca393b688ed6abcad737447118d9a71308802edd79367d4eee4536614e58d68e3e06f328a68b4350eb6e1a499bf98f4abb556ee312ff7d07e7ec73dfc27f760eee13f33ee9165b624e246a6c47ee6fee95b20b6513772822db651dfc9d108d19fb3ecb7faadfa6365655fb32ccb32cf4aa79b59ef2c08b7e2595276779f4f1ff851888cc2cf71a7392487da9d05282b4f61f4d93907c05fe437fa357d748ee9a35f73fb283f6d46bc751fffe87c10f5ab3f298cf8424c02f730621bfdcdb6886df42731f1549eba3b8bdb716eff0f1f9f2522f248a51b88d4969488d5fada3df7dcf3beafe71df765a455d75c129e7badf51dc8c893c8ef69a05767daea1c1b33f3463e7d4cbd66599671ec7d4e3265a619a5b452a12e81c71e90911bc4ec69307d164b21568b0564e489e8af791bc8d6481471fb6f33928408dbbe8b6f1b78a4912f9a7df9da2865ca9bb731d37206db687eb18d242344feb9652a64c1162d496e5fffb2e9ba5721fcce551a0db6efef7ef28c9eba3089977e9437a219acfb2e2091ce72166e2b296757cbb8bed4961ddbe027d2af198b8273398ab7bbb18d2423c4b6a5538def234f88e50ebaa35f3dd4e5cbe9c6e5c7628d97daef0302a45f45260fa49aa484c86ab59afe6b878f7929a5f4a3dee3752460b7a43b3e165c8e6dd9b1793e99f3fe265b4cbdaa4a982c4cc0ae9753bfaf92b3c756bfeffecb79aa55ef88136206e8ce34d3721d3be4ecf1b18dc9232704d26090f05bb3eab9887e52696e4cca8c83d93b8f288a3c3c2d761eeadff7f5082fae01ee8c1d417577b0720f70a7163ab8b95efd66e5af55c7ced717278fbe546b758ba7d6ea461ad8323225825f8e77032b4fada0906a677daf6bd7be5d4bda3c1fd07295b89c6b2e876a72ccd807ac5c36c0ec21b20da21b3b260feff987660f16dbe0cf441d3bcfff9a3c729ecb183cd7eb9c073b5b64d6f83ad2c90d0a42afcef7d5b1a5935a3f8714678dfa21c9fac8b1234b9d5b5fe41e248b7be84c1bf5b9f2a8afddcc4edaa10dde3c72833863476ce1fbda72fb69c48c80ddfe1b39ef7f270f1ed9a675fc71df879f06a2d0ca21f97edf7cd25f4767038fa6cef745fde9b8fb83fe448d187c1999125b6e8fec20ea7cc9e41928c47372de13c9923275f1fb8a39ae33bfebfe3d8f5f397adf75deede69c95ab5ccdb22ca339eda501c2ca2d5fb715ae0004566e27e1857f1ec76005bd7224f8917c67eb086bf53ccfb6c2d7ed57e7680d3c9aa1ad96d69ffe959cce711bb771e577aecccc1917021fc6f8a0e5f6d3b0baf433f668f6f3c596bb3fb7cd71092485ea97e345aa41baf767d92351886507a45fb3bd90f43cf2a3fc7964077e5ff0eb9608ddee6f83471dad9347b67152c4caf5dd846496f68b553392e66045d4505edceeceda326b3db05764f298f73233336576a64c9b9bde0956f970264acb9d7167cc03702ee52e9d6e0a6466cf1994829fb94062e0df2db69ed8233b88b585b4a5ecee45a8621e7013f3409a17fbe41edc23bb947bd02fe9cfabab9b01fa6d97e8f7276911fbf94814f7c8183103f496db659ed4439ad95209d7e725b73e25cb24939d69486d505f5abb9f52eb449588180f70be180f6e5a0b1ee210b1580b1eda2ccd9f5e8c072a77e7ce180fb05b32b94c0605b9d3964e905c5ee29f973e1581f46b7ed50df4fb492350c4a5a6975f1bfd41a45f73b20a8018a3050f4f776671a7163b4cdd233b88ec939bd2b613c92d9708ddfe48183f91c631d93ae1662204a1e596b30d93ce51f253ac4a955b7f49251285ea4d75254448a57e552447a01085b02da2767e977e52448a44edd76a89946cd9d6536714e58db81ddedc199bd2c575dd199b72e6c2d039e87346945221a1b149a17ed54f7a224e07d2afacb511d1d6511f48eb98464dce3b8b1411d592c6ad42b78e258ba3b41a787636a035faeff0f7b1e3f53476f828b3e3bad08b06d10e1f3b5e698c981167bfbe97bf0f1888e58b5968ccc8fa05c169d47893d7c4be88a305ec8d6b9f55b5b9d9f398eb0f84a79a1b9da39c6588ecf0f701c45f85244430487f9d53ebe7f61f9d8306123ffd1f622f2d31f711366249c3893a073f0d4a72ab5f3e260521d2ef17ea1c995b7f09653dd8fc5f54b4c61691b7bc0bb4c21262f6e5fca0fa538b1faa6eb9fd9742165497faeb67fd9a47acc4f2753d0908b15b2faad5ea9978295d13838abae49d311ca06ed7bd17923e5597ab559b3d754461acb68182ded3bccf67d0eb7cd0ef74546060c70abbeec3173b9d77215df83b3fc390a9fcf6f56c3d5f54d4f8530c9a45cdd5719b3eefbf017db70101f53c6d7dd05772bb192804e869bf7a5c43ba77b968ed868cb674bae3cf061e8d3f564ae4becaeaba770d19bfabaeb1eb44160c1106d073eff9903eef65a1166e9ce772813e3e3961a8532b4fcfc79307773da1d60f50d0e802c0081f4f1ee3d7e4e76518e1d68713f4bd7240fae560678b3807c0a9e2fa5dab6dc7cbcd9b2b3cfa849627ac1c09cd1afe48fa897bfa5f1124382821e9425f6a7377af6457926b7d4ad2d884268f6a51e8dbf6e5002188d9912188e5acba3346c68bebe010d636d508cd1abed1a8a25c3861e6ceeb4415cb89353c7bcc3ba74c9922d2d7a078ca8d1bfd32b234fa7583b6a51b11229502c9284b6afbdeeccb87fce9b29957bffccbd7ab73549e42a507e7f6efbce7f5c7200336f0ee7c3f4f1e52509b118b89c32428b13f64c2f4e3878f1f3945dd8e8e9ef7929ec47e4f090c3b7610edf8b4d7d1f9ad75f4bc8ece7b3a64120ea2ce6f4a3a16090d1a3c3c3c2fc443d2e0798eeaec7cdb595520d22fde21e9d7af9dfff7217f1cc4fe6c7ce7cb23c5fa1ef2460fb196b048253de4cfffe2bbf8c44afae56d93f4cb5f4904e20e066846443e24de1cb2f451ce2ecae9c565a26935dd6cfc1af34c4364048de85f12f5d684379f046edc496075dda96d9a25e1402c7764ddcfb7edab5fd967ccbdff111f1441d23988f4cb9f23897ac89fe8466681a8d02fa771fd29597e3f8c5ce1db05ad7ae051239eb21969618d4234ee342a7d9439c3a60dc3bc8873e7d73aa8113562a3f9bc058a18383726e64d8e77bfce516acf4bdafb7bc9e4d9926ba498d9b2da5bc4945bb6c03cc5be98b93125b6dc525462cdd717026326070a0c55f60c66cdf5a3ee2b3378f4dcc665da338844ff6b507b9647b30cf4ef7bcaf241ccbe9bc1ef12b573a9233f8dc1ec83824c9bca86cc548ccc192aee8c919972ef8c912973678c8c955b7e779281e27277c6c88491400960555e783933c59c5ec65c365e4ca7ec858a0735e9a495bbc0e9c20277af991b2cbaace972a6b984b9fcdb38b94c5d7e3a29fda6224bd59f6011263434d5d0c59f360e3a85c0f1669ccf0b24aa6ee803d695573772ba13e50b78b3dfc4bcc499617e9725ff18dcca30c29d6f834ecd54993973009979fad4f2c58d37f3063abb162b2f31f0c2a6076ff2e46f1e60d6e8f741e35b6e5a30885355254cb9e3fa38c0ec127559fdba71a364cd8fd50576cbd725722e949ec4ba8c897569824b17b12e577ec08229e28c4d85b9e577bbcc9db1292db76cdd3955e5ced814d4fdee8c718973678c4b17b7bb33c6250657e7ce1897344c5ea6625eb4545541c1e5f772388a58efacaa52e6f28b1231a688aa5b8a4350c586f89273a4066239d514f1772aa2f6f396f452f76eaae648c94894c85f4e35ae05669b7e06a288e50bc12f5b3be80e74dbe13a94c48f5f69eb84a472be642c56dcc635ac4d29ab4dae83d5433dde6ae1dc762bce008b98256322fb233460f1c7fce517d1ec0322dffa6ddcf3c3d0ed0eba611ad7c90cd05b7214b51cd5af7ea91ccf6680de1cf185385bb646edd35104830ff5535be50f83eb602a3dd46fc54d6679aae596a368c052dcfe92a3b42f95de8f86ebd926a57dd59875278842298aa278b35aa915a256d50fb19d54f2a1fed9af7e2c44ab27a4236dc456bf9ad5979b68c8517b10f9521f45241014c62be56d3603d47e22dd3eea6eff481bb1a43487261a92284112c4d484f3596851e50b37c1be6fa33c889fc8f4ee48a2a473d02fd2affe56a15fe29de011102356b45ad56b832920e0eaea2ac8dfe9badde805e2462c5b2d373749bf8c5821f2df90548424222415a1bc71bd230c785ed326b6fe456993a65bbf74526de97493a2446627ca2dc52bfb67a077697c1ad767a077a9ea4645e3456c8828979999e7a458c28470be1a6491658a9e3b635966a559181424bbfed499c892a5b344dd9925875816d81b2fbcb9e6967ce76f60b69d32ce51615877c6b008f10dc352e5ce1816a886e2f142c8db8877c6ae6071f937d6e1ca993b6357c6dc9215bb02e6f6dc19bb62e5b250cd6a7665ca2d67ec0ad48573cb2fee3a6de69c7332c78450734b3a634250111322cc6559b9edbaeee79c5b1cb1dcae57f7eebdcbd151249d43ebba2974fb32a1eb5d673d0e737240a1d7776408bedcbf33164498ebf9a7b981dd19ab012c460335b4ab9d974c69f5dcf33ccf067dbfe47dffd791e5d674b7ae7b8e74ba1bc9e44eb4d9e04dde98ebaa53df7c3233735bb9a68d34eefc8d2748d2fbd18ffcfad67a3b92deea75d5eb98ab4c3fcb344d73ea1e531c3cdf4c6c8d7d294967bd1bf9972fe515961069d72c1337762d394776107b6e0398badc6728c872c93b6366e298e9e2beee8c51b1e69ea9add8ad2f565175ebb3b83c5d4eab46a8c452d4de9b60d07cbed3befaa5954c5e5facb5fe6f5ed3e53ea3fdcaa4baa7650d1a38040cc2d92d33d2de9b46ba88224b038d60a0a9b33574c91a07c76596b32cdf48a6d618adfaa494b96e4f191fe1f1cf6d522249a6550b6c5a48926407cfab5cc69dc120daadef4c3302b08dec29f36c02b08d396f30c9df86c1a3264dfc8fb29f1959e419fd8ce426daa55913ce8ef8294991a653c655072a2a2a3161f8cb15a536dca60d17564a5cb4b142454525268c18aa8fa7f09489a5a1286da2dd2ec3f4193c9ada98398629ad95d2ef316366a5aa52019c5b0addae42b3e6ce2a15bcb9fd2f3bdaa2fe5983fc6c2002b10ac4192bc2ea3216e28c1591e6aa0084d5af241b88a5d09c16695efe1ac476dead32397bccdb3acc343cb4294204b1553f5b7edff748beffbe57fabe36ce73fbe6b7f14010046d50f84be0fb87e0fb83ef4ef723cbed7e4df7bbdb7b2049fbf5719f7524935f6e23cb99e66675caabf786b719c0f38e34214e27e60078b3bdd958b0b811228b1051ee5e33216075ea8db309bca41ec486f88199993ab5a26c9899d63365dcddc35899aad533d63e762b312b54a8bca41dc4ac3cc54410e7b2fa1504212045fdfa51a408f5fea0f4c80e44345764f5ab7f10bde378d3cbe9de7e4fe2f789ee7df3bbdfd3ef75c8ef7edf7f761c82588e627fbf88741451ea5ecae77d8814e91cdb774fcf33f88dcf52c1898f3421f27f3f3f3b3b28f0fdb76d7b8e2cbfcbfd17f23c52f83cef743fb2749a3576749072c49fe0f7daeb90e5763f3248b441729e7ece677c190cf28164f7dc17b9d7711be55a60a9a8c47018314c4505859a1fbca042e57a394bbe264b26e7366ca5c45c709b32b5d68a8031da679437ae19b97d5c35aeb5d6cd2e801f8a27342b460afeae819daa674188de74fa755689dbc71bdd6cd6ad27138ca2bc1157cda93b6721e84186c70e276974e4a8c19d666e00a79eb97b1038d2dc308af2ed052033007777777777a79eb9137507a2efa8144d588441eb148d0c000000482315002020140c084563d15816067a186c1f14800e81944e664c9a89a34910c4288a310821630c200610028600ccd010a8036fd63b521ba70b14967a966114d5e9da462d56cd8e3f24cc0b9a32cebb4787e9fcbf25acf0230e30eb511af4a7d11133cfaf463a521bd30351810635143f93ed8f299390e745f033b6e1637194ba8a6c6b009b644bcd5498e6635f7491d20138589e54708a0f6b83ee13dcf9222bf5df7f5126d90c057a409305ca6004ec46f811bc5de190c8bcb60f07183782ca358c7f3608ea2bf868e81cdea64dc196a20575e0d890f28c48205c57600e92e8cb32d9d8fbadb73344383cd9749474d008756c55c73230c79774f4c8ce23adce8d532d9633257e992de36d1af60df2a3f52e1f59ac5919354cd41c36d1f6921886a511040a9b943093766e0c43ceffa661c06c873a1be559276d2c8a3ffd1eab3239b2f90cc4301da0c53003f01f2b693dae196037c2ec6a9b55ae2ec5b842b0fe949e0a878121d018eb2100ad1b213c0eb802f81b6309ab30c7e13023303f2b666e37ace32e1512f4a9ffc5a7e5eb111cc25211fc8e6729d4f02a84cb594d139686c6f16ede7c2472df4733390b8b9156eff26741267a9298ec0a6a0417182019b9481543a973e0988e2e12e36c35bc87a22196785845de6c218694a6f0e7f6f7b6edd945f208b1824add7a3df8d468d319b1f343ec31820de97bb4d376dc4adbd7829f652e655a74532e71310bfdbed0722c46d9851e33096ceb0110755188e883e2518254e3ee92a19dc1a72881331671de5a68c203119e28be63f6547bb367aa8cb978401f8a4fdd2d857516119924373731b64a38b7f18154c95980273f8343be696026ceac1ebdd58406ac2784156bc6dccbe679ea8a39febcb6f1ce6f7b0b7f6b5868785904423d0c6f14d969017fb4950df88bb0e190ec4331394f1fd1e6f5c2011a6818b9c344ab96b4e614713014c3e5a728509da457da2aacdfe091a173534f67c1c2da9e937b9d8a8cea88e2b7b959c818b650884f41acf139f68f9759bfe38db47ed5535998a454ccb9ceb1b9d0eb0f1ef923e6c9e3b5acce87f8e9323d1d6f9e8bb3d5f5502e48f5ca1c34d44d43a305d821b6689163531c841acaabde22c2c21373e52bcf30da319ec032d3c335f06be64b4d96e78fb23b2a15cac80800a53b7ff2521c9411ee41c586383c6d283c3749077f5563626a32bee789cb2b78e4a75d45e12f77c6f1807bbbbaaeeb9a3a6b0923de0cb0bc91e95c562ce3ea8df3e6dd0a1c195812b01040e76800c6991b41771cb99821c0962cefd1125e23e83600cf6b60197a88fb99d7ad9b21487e22a6cf704eb36881d47fc91dc285186816d17b3540877612c815e4ed24b61204d144660e16bcbbf61296a1a66190c1013c0e1c953445cd38bf62a4ccd5c451a559dca0cdba730b8853dbea0c194c952e667d7dc66ca1336681d5f8a0d04879e5869287d8d1ae3850c4789019a7ffba0fe17f28120bc129d4f06b9055e9453d5aa0502b8d40c8a3b0e624b539550ba3fb0d11e061930791598ed7246f4180947c06bc1f4e401bf5f54751165e9336de97dd7996c0db616d2dd5ad87e7f23ed7f82fca4156b2c70dd6076c9d61506f3c3c2b8018fef81e302ca4c26c046947410d2bad2e2990258af359d649eb8025861b9b510f8d7ea58bc1f0e1e49e5bf231833a657188372331423b0a50856979c1d8eb3a92d3430b6650ce1411b582f26152c806f37414bc50540484e5c90bdba44d246c51fb67b1f0f0248661bd6940387b46f9a5caba7a8fbd2d84d47ba3af157595b1d4a4a542369296ae7a116731a2700e605553bd364c785f8014a3102f7d472247ee5434e5517630201375b6258157940989cdc90994c00dad49188c12f94e8ab71e801c8f7e88d5ad4ba491eb12ba9058bc0b0fb192ab573f34d86b01de51e0e460169676a02f8b1cf88c2f5736fe0833a7ee590fa0e80f1d48e293117d7afee61e186ce5b1334e2f9bca5389cbcd295ee2b7aa35cbf4206fd8c8a5d5b0eac4b20cb88465feee8e14cb20adb6c3ea5b632c3f8a7ab44ecc8f2fa80a98097f63bd81ccb44dc6c9e4199121e32d1028019761d1813069fb6f0205e8643a90c4ba497bc314a9dbcdf1b85ef71115e298b760ee83116488eaab29d166d02d9f61ae142fb333c4aac84cade7dbec1e7f4f78d84def1bf51da0d1c60560f9be7e7e193af1aaa13687a12c4306eebdaf57d3015777f5346033ce75f75b2d98fa54e8b5fe3933db50bd89339b46f65207df81b11694678dff7f8fcb8680157473027c1214c8b0c151599a8a401ca14a4812c21a0653082886149437ed63a6dc6ed82e8ff8fe26529b933a628d5b53f96f1f41a4b7106d082604c1f8daa297a0467110ed45ea64b0d8b9c0b6cb57a9e1af9b872eb07a87a83e8cc9bb4f4e5c85de160e37be76c3a45b01c2410c5abf88622e4c5af0e32966577a6dc55c6e12634064fe49d8b91227dc09e58688bd749a093942df384244b0c039772c82707af18118a211eed7422acaa8770f8e896e0f86aeea5aaaff08a4805c8827118d99df73646b884653e4e6b719ce308d55fd4dae171bfae29744c65691e360801bd42b0302c59f0a611cce489e88fb46fbffbe24d33950a6b50337bf18df5b332cd477cd14e842fe278bac14c6ea66464f5d8294031eacadafa3af7fa274060d0ea88ea5c8996024cc3f03481a0dba924e32a30e1da8fc1112f53b6b38d17e7b4641f9a2d672865e7b96d6c751ad9db1e8038686e4d87705f76c0ca5c865eee28d691876a818ec59800d1c499e0dff0cd4edd7bc8abad818474957f3cbbbf7e6758b7801feb1a4805eee0961053e3856339fa620b16b57745a14ed2a758ed3bf5f700720525afb812f69500410f6e0ff3af768efa4014c8974969bf4e31f87f5407a83b31a1a34686c947b0bdabb1971f43ea6e77f7a405c27822fdd268fd80c5982885d65b5ff2f60920d72eb2354e12a459b5cc6580e648343b2ccc7c5220320d7c4ffc65bc1f408f6e0f4b431f737288bb43f98d20c55ee928be5a258b46bf022924d03e89cae2431830800ddceede72f07960a51c80d356ecc565601bc5fc4714c13191254901d0df290b59651d36ee3cbc28b08a632302efa9075cee3b26adb04969b68661e27ee6fa871e6fd86c1cc9aa50647d8f8b03a57bd80b09828e1ba9b13219d1ac1a6745f04c9a8218b722e6ec443c7d2ecdccbeaadcca559b0fc02da8db4281783165fe8390da52566289f7a79c94584e9b3d7f4435db37ec4df1a92cb663bfeaf5f5d526993831ccf83c74e2c88e772f9e329032c22a7565f9c75d1201d91b368abdc6430dcccc21666d7cb75f92245e78f243f2fbed351fa3d3431df70da5e282ce22ca571e78fa89ef6ebf26bcf87c58d6e64e918e5be9cd36673de080e23067774ff3272ea6bdeff3ac6c5c20a2cc496f4b00410aade7345f720dd331d1e137629397a76f92ba8b55d0b4137473c2c1f728c7941fa630bf2ae058ec7021e2f762e6b8e01f88935e2100c8a96f531d54ccef0e93ffbdd382b87fa4083bf31dd6bfc98b10aa25b776ba16fe7b26d270bbdd7854760b97d41022b008f7090ee26b8cea9ea2753dcaba75dfb2748800acbdd94ab189d027bb6be2f87c13df578c2cfe31bbcd353e3d08cbed4ff783c9f4ee98c36182b5cfdc9ee44329c577b3e02a32e77e8e54eb3d1fabd897c36ca079b4609f2bb27827b514fd5951fe5135a06af70d35571bebcf8f491c74465c2025cc9360728224b45cdc6ecd54368dfd251d5873aa5d9b1c2b4ac00e3e8e36cd4cfa3d307baa0d10a75c1fa9295e018210fd1399aec850372984c58c214dc0c3d3e028362d9766605743bd4b2d33dd8f2c188c3bd31d39d753f54653f3f1037b38e812825c7b7214f348e6d94ec2bf811b9da5fd4d5deddc162b1f3552ed58e1c8e2ccf4bc49506741a0cb5af2f4c2b0104cfb485b21768aec2ce6b94a29ea322e23f0b9555c1f74c1678a9fd88e9c0bd84ca79071d90a2e0a473fe3a484f29f2df5e6842f884d1048bb35336d60a48b2268e82004719414e3dc1e7aba11f01df9e6c206ee63500b637796175c5e9f154f304a42293f86884615878bcb8eae8548d434fab16e9bb8b9267017605818ab9932b1d668c9bc6a38503453dcee7762156a3e943f35d726e6ed7f4fac295170c5bff1c33d699c903e4437422d25429a008e6426cebb46a69841a6288ca32758a8055c92eea422a3e90ac951a9f8b80507c9a25f2e1baa61be3c84d82dcd628cb82581cf50c554a61c72fae0c6e48a28482f10860720c500735ba213d7b2a7384133228fb6fb412950812bacc48d1496cacbfa2da49d80df719c842cd77a32e0edaab31c5f9d9830961650660ce63771c8b0d5c81ecd87497f230f72a54cf496d9f48ba0c8e712c530c699572e0a4b60efa37e40a3824da6a1dfbe88e5a01a6f7478ef7a6b44d87acdeceb61fb3f2f9c76d88efa192d3301847e0429b505cc67e93175c012ec2704d008c4e4411b696e1b68e72a9340b9662f69eae9c41badd8c50cc86cfa0bda4e6f96bb315319c7c01ed91b5f2c188c06e50397bb0bae02fc54e9f3d86d416c5379e278351e86fca0d54330eef466bb6d2efcea65a29ae82b5c5f8da354912f728c040a22da8a1f86f5e12641b57868b8ed7d3e81e214bdc2c01586746f4fbc9ae8ef49cf7ea5fbd80bd7658a09bc32b2ec5de8fa8cd53d7d500a913de4f229a868f038d9b518ae25f7e07d19e67bde6353c664cb73c33e848a948ae3b9adfedb597f331803f1c3df63264140be8b2ec096b84bbcb2fec0f8408b780e116f5b00440dff6832f50c9ed62049f4d67b0a2cda29e28fb968897d0dcbf42098321551db15969e4948df4356fc076270eff868f22ac806302ce65b53056d767ae6417d00083adddb77941d1e9ac61778dee86b9eec4ec66c63fb206d8f2a3e8efe8c9acfcd05dd0a826e91fc6313b029754158619d0a7cc5a9cd28e3c35b3b1d647a70765e865ec3af200ff5522b64dc7d66bce41834d790fcd49051dbf17716ce428a6b41102cc21ae9550f4b825e492a0429c47e400e837880cd56482c8db1c88853876ab2856167e136809615a6e13944631f35dca5a89ccf5b6806a624d93aefcc5adf232c9ce2e3110abc42d3445309a5dce8dab072d87a96547fca0269ac50ce28acc3a8c9554c612882087833e76bd7e02bafa8561a738e31ebb30521b1f8859e8810dd124cb9599ecf235dbf1b988bd35cbecffed7c856e74c7c569a6dd6c1c6214270cfdd75f1029c16af8f86e85dbf7c026cd372b5f84450a818cc6436bb69966050b1731654e73074412a3520bee53a16f56f05474cee4368aa295e2c07b37746f4f4699034fcae63e962e45ae3a42761ddecd9bc484e4e0efebc4e9a5bfb317a6620434befc385e81f1f48b57f93e1c3a9d50880a86dce8c222328cdcfab78140b4427ce7af541d1a275dc210504c8ca0d411669c7af8ff58694f4a61f4fea3ca61432e162c0ddd91c9b135613eb4aa2280ca68bb329785651280394ecdce6a940cc110039518fb17525a52b9622cd96da73aa8a3073ece62fc7fbfd8264d1953548f71b8bd5f6c0c424a8f277e1510ed216ee4a1317c295b3b013acab3258f1f6243df40c7abf1f2cc88505e84a7d297f43bb273700a6b5c6cdee69885e088765255340413ba73bc3e912b79d3e74e6c8e1bc125719872ad09c8383fc4f8de1f70098e9cdea2be73429ab1e0d95493924d4b29c35da8786d3b93b1d2ada10321c910db2725df3cd0ab6a1e3a6907590d632a42fa504670c2d9d2044c4df73389b4f9da31eb74ad4109f2ba5b6a4883c37f8c5e73ae66f9c6cc124a69a3bbe1cf46adb66f9b45fa656216c10841a39ee39230a5376ebab58a052e3112a08c753679b8564e15ef68ff5c379b7a3258abbe2af76121b2c34ae1cf053118da896a1c9f1f69730bd08c1467242e589726522f5d0273eecc2456345fad20ddb11ec18545f3c8875ab2c8cbfbf2e1ae4d0d7aa3b06ae9bcee62497ef83e7a57abd78b0513d6cca99aacd65c1039088619eb8c346946a32e1aae97bd2ab78aa80e91748ff5476a3de4e7065dae4c1358b5b0ffc5f57cdbe6959a6f922b3385c5b54ff741d3234ed60cc09258ee091fced33817e8fde5e1c318bbb526318bb752b48fd7e4408dcccb0b18009d803514ab17cb39becf3ae9700591e23245e2249c8dd18dd0132d2e2fed1086bd5acea67746abb853d698f256f1894bb2a806e83bc12f0f202a84ec0aaf4bd39a43505121ab7fabf5bd77b362bedb897bd902056dbf35b35fad289870585606f6098d4dfe813b489998f0bd88e2286f93e3da0c41708b802fd940b9eeed5ebcbea2402689e6af0c99ea601baea9fc9ee2845003d71d20ac053136ef89b63cd21cb26c216010fdbdf41bd1d60fe5607dc8eb019e03d85c62345009c66d93e1128e982c5a987f119beaee2ebb4bd1ff62b2192cb927a766d1d0de46fcf34d003fe1dee40a4b5459251f628c2de53a17e3d2ce53b9e1678b58f1136a2281fb7b1701a71e7b11a7a4966eb64c1f19861052d9ba75c838475aa62df1003f8403dce3f059b872d195ae4bfeca65a91c6c7836d56b5e772f52d79ec08b476c66c8b6969188cdcf595c68436c954b3006ce7e1a8ad07994a724b9904483d86544828962ae2d82dd8824269e3e8884fcbdf9f5799fd4d15866571e56b03199a2b6eb3424f9a655dbb5d402dd4b796451887f7b23764ad7e16297eab3e67ae7cfe429072e25893e96240db8a1df375bb2c2ae533c04cab8101a1fed93fe2aa02f90bf31598c959a91c8fed74648f160ced460e656bb76f591875c3ef50b505183a51a708c7072afa12551344d5c4348376568c65c8c063ad08039aa8d352d2cf495a72563181ae7d9afc86ac6c829e52870c0b76da4615f156490b930f2efbbb58502d3b26c5d3728ccaa7c44f32eeec924fc991c045e6148c2b06acaaa9a69e42d0d38a4968a7698cf8f4666f73274df0f6e989f8f35ab2bd6a406ddb54e261abeb119d6415a6d24f71f5451b227dd9c26dfdda52e655a84ba0e405f96181f44db743d7aff4fab1bcdfe6318f5aa890d01ff8ea1d1f7ec075677d31f7f033dffa5291be1bee1787ac6e1b9fa67638994d03b0719819652e54a006bdc40f715035129f52b52282356366fe913d75de2ffd3ff122dcad9ca78f9cd40eeb8624d3569c8158b62512f959a91c769cfddef5d1579ecb54ec8f7857e335885ff533cc37f0e437248ca6c7e7fd6b28a585373948a091e53d88fb343e151468ac777cf9296aabb96eaa35d0938c886dcd53b9ae5c2989acba417e2c6d9c134dde5e5727432c30f669e89bfd807331a134326079ffa7fdd78bfa54cbf5fb6783c20844bcea6f997e6729410c919ced93510c888f2da3a5ad0c4ad692b3f17f8a044010995270e5e521bef70326414b6312a7fc0e5ad1677e426f6aba1f2a5e405c1b6fcafb7d8bca939b8fb2c114b55fbb019ef10862e0be1932e78a337be4c0e02fcde7a496bc9546986dfe0d8277f42fe22f2a1d942713a25581ecb16ab900657294824a9ff21f5aedadd0aaf07af650dcfa852f7f5606fbb562f82078e641a249c82fdf7ca66fd7cab4dce664b6662ee4627f720b01be871d5a0f6211ea36f620e2bddc7a793b0c292b0416338619d5bf2b7e4d2539eab73aab87ae45409fce11363e2ac57f8061e67192eb7ccaa340e93c445a3dae977b2e8c09f2efa1e6db8cb691381857b3d338e4a4153fc5d9ff7b0b009773deda91abd4bd0e834636a2aac45f6bf6d8a2668800eb5203dedb0d514bbdd38b08fc64b58a0d9c7574b7e9fd400c32f3517225a3418e21cf33d0971648307e7a6c629ef1a4048b2a93ac1bcbe88a561c232ab904dfd972305b6680949df408cce1b6d83def990db35935b888b70cd17107c3cc204649eeb005da0d1462e2888a3db38608332fb98198bff76b7b48759016956c62ac3fdac42da697c400e80b7f83c0d69918e9593c84b604c2f703e900989b30c255688290732614e3f4aeb07d870b06f02e4e9e9d8981920f4b78909b98ce35afd34015f20dce05bc80e77284a920574f2285cc62ed80d6a8d5589bcf5a99b3c084800346c1067395f78f7a903944e1e8fd9913c5d763c6acc7cd520e9346464e69101b49d2f11227f2655220aab54185b40e8470887f24df03c20ddbac29f838d67e381a565d033df9b6d7e20e75a30341d8f1fbe7641b57f5c08470ef00765cb5e6c20e116c5fcff695a04d37ae3694795098b7b6fa9de00180b322f307128caea0219959afe5808b403e78d6171dfa0b38a54b8b3adf9baae1fa03a7f6661c94fc2925c50fc539ba42b581c999722f5aed3a8edf569dec8308e616bf0ed1eb28171ef5e3945621bebc21052a707b799e93d615ecf6e958f585ae402aa815ded6b1489cd927e651e574138ad0bf9441008ebc2ddab8db9b5056213c8f1ab8e2d597dafa7a575cd9f4403d732d734fbe688a364084023719367bbd7d57d9a1112258adc25864cb3fcc66026dfd883955c35b1b284230b809cb8618349eee2621ce94fc3909ead322e5c50d16d4f6050f805df508407a062fc3ca4d243702ea19f8ef5da9ced21cb0ba3161d6fb21b49a1a73dd747bb2329f4c24f685a48eff6eb80df466cc6ecb2f94d88c3f997eed2d7f37faf4f544639d4bb58292fba1f8dfaf1420adbb1db38bc08d717eb28f8ae6395f8753280d5d5319d02bf44df605516d3665b00ca8acc3c0c1e85b2b476f61dfba45ed1a680e1bc52eb8aa6a05604c272e689f54b2e80a8a984ccd73e86872999f92d9e0404da1825e829e98bdd0a24de3c6793d0840268e4ffaf1bd724612481f49553e525b064b29bb16d513ffc54d2e501ece26ed5ff0402516eb46b469fb747d39dbc465e4e4cff2aa8c6f7e1e240d1fed2236a13ca93fda2609f236263cc23875054d72d0d223955549528b06bde969ba4d226b07000c519c163e524ccc33ddac93879e6ee685c594216e92c4d073e7c5c6b1e1392486cbf5d6058b1fd51b583190c0a672de4c8fdf6e27f6a4b5bb53f50e63e5faec2717d6da3f20e2a405a125c7c18c67e420eb5c582b3099eaf5ab483ee70b8f130793df91b400fe2fb4b9fa86557a49e6311af4439c2a6ba5ae34e777542931632cc96d6156c640e8922d482fd837ab8f069af49d894aac4e0c12bf052a7526b9fca7eb88e37676f1e8ac278e30a72187964ba9875a3ea30d06b50b867370fad3ceb4def813e23145e89152e1dd8abf51912fe4b3dc9853a7ae0775c231b6b5e66c99911b484a097ff774769d63862fc148b1588204c7ed577b937aca0dca9a1ed89fb860eeaed15c829854cf1ee852822e604da6e72de03f2630c6f0f729147ef48fbde39cf0dccae49c2f29645c5d36c34b8059bfbf9f1e35da9d29deff5ade4becdce70ca80e28c8896cb80a198ffa66a7a56ed934afe27a9c2e4c37bf93862dbb38f74ee44c264c6b098e9ba48a363ef68f9fea235adb3de0dccfc4237da91cfaf67c98d13fd77b1761a75b50f7b5f854fe5b06ba19bce5b9aca5ea9e84da557aa7b51d58b4a2f54b067eb0a8f1bfce0b5f54e1d36f52979ecf4a4570f1f2bcce86db65eb3f434a3d70cbd66f53043af597acce861965e33f536337d7adba4aebaf7ef36abdffb7ababb25814c1fd5ab83eeeab40052cef5272077eaed0bd5eef96151b5315d2dd19fa1fa544740fc8f97ea084df808e66ea366608b379fe72c779fb0328a266f6d9b0ea864f113625a2785908f9a698e436e79b36d29466c2c8d806bf52a4f2430b63cce970106efd4e81263b284527707b5a68ca11f0213db9642f318abb809cb6ebb369e9f301530e34162a39e28be151f1df7c49ced9dec83a434fd57bbb6895544d43c848f2b1513845476db228d25e63d39b8329e9441ac54b09ed7bb48831d2b2903f8e48cb375b4a3ec52af93ed321510b406e5db761a033afd34929edea6ce1b32c773876a596f4dfa2819961c71009899806c2211449b5f59677d97384dc7b3fecc7db61298c35494846a6b829d6cf8bef9fb6bc627625720b111d5af21dbcc55c731eaeee83f7ccd63bf115359bd9f57c2f98a32d827c68a8c1d1f363dfd41800b88365e712419258609def04f27b680fe371c3f7d534b5a3503558be95fe14c014b2cb9578e41fed60548611254ff053c9df03ef22b19834b9dd491146ec13cf38448deb429960599a791b33448724f0dc96788eaac48deea81c69981c4025429d7c1322a14270ab32315104f9169b7909257c714e1bcb327a63837adc93459785617ae4db0264d508cfce8728657b8bde179cc4301376798f501f79729930ae39f8dc77d50503e4dcb10207cf80ce9a9d19e7f32ce1bfb44cafeb4c44d0fef3d249cfe263f1f775addf5c53ef8db01a55dabc7aa339a1e9042b88298fd66597a9bed4b8d1337d124443e1670fa1e696f6a8106ec722a5d576dda9d8fafdc44bee9d0d2976e0e34504ac200c360723c33b9e4fbf315a02f2afdbe0a2280f9dfadfab9a70103e9619a39408454603459a03b59e0b77f1189bbfac09fb531c508603c4c16ea5048e3304d719c975d600ace0de450a13f3c3bb9c938852d1d9ea6e92b60aba3d22239aeb4e0e04b36e6a4936ad3da39f8446cb7794600470ddc8bafc40539e980386b44229316e357df89489a69c012c187c6d0f0092269e7e698869a1eedf6445b82b68c5ef265e43b4b0595fae407bcb9be469a9796a724341e7cf1c24ffb2017939603fa06871693368822763937df2ba16e5cb652a72fd319dc32a280437580955fabafdd0ad4bff29473da008e765ff9df854c1589cf0a256c5e6fc1142423e79c0a0c48ea86ce9c91799b86e2bb889707e38b0c52a48516a0ff03eb0b7b1448a3745b2299056bcf8eecb1bf76c183f62a91cd21c9b58a7897f17283a5333c354ce37669d163db757f331edab1e8c8428129c32b3213ad6e93b5d234d9543362c2ca2b947ff668dc7e64fe7a7b6e68e6befcf9bb69dfa68648892acd837d137c2c68bb3b182d05514509c7252d0470b010272a8fd99a39486c1da5fd2683165078b1c7000b317d9184aa11011b2585e0d631b6ccf28d9d30134f41a1eaaaa22fbab84eecb51fa3dd3fd855224b85dade234828cc99be5799320437b9a394cc1799ce03cda2d2d1919a42a75b43c73d36dfdbf3070fb1e334105a6f062414379482ad824db3060fc68ac2818cf1f609b0541fd851b6c85d5cb8a98f91312ad73500f2a429d696c34e21c3ec352b667a4d092aa04e687af84cb0a4a11f6b8eb506f10f470853aa9e795627c630e540f0eec16ea823224e1ec3d2f21be49a512819fe75cae326abeac4c0d71712e85c8e9e3cd40b473fe13385e311e09151347ac813b5933a5466f1b9022fcd2cc82f022df1bc24361d892c3ec5bc1d2bf920488f16950f36428caa55849d5df689b04241ac1a09d96e136e9803dfe96de961e49efc2e9dcfe51d551b27155c047ad3684fb67185abed12038ac33b39d1b1575ced0fe92097864d5daa1897f0eae43c90434c5d20edd7682ce5b636fdf199983d0709817ec3e303551846a1e5d40b84aeb77ba7f73a940b469b56ebf61a48fd8623c15fe137add0ec4365039739dd036e16c8281db3ef4e7f89c20dd418f204d2ca48eea30000f0313f5e0e41486a880354a102c33c1b56a93c3d29da4b5396bfd67ed1e6f38abe5a327847237c8570ce8dc15344c587b66310332315ffabd307b39fa5113de4cf0aec4c680fcf43fec96255e097a31f07d93b988d8cb230f18f3ac2fbbb911eed67baa428436e47320df04d357718dab4de42e020d7cf1cd222d070a2d1772b0c831b1567e0bca61980759417fef2cd560f81da0d5ffa74d870d0c147fe8a9a19d69e70a2be84492cd300de69091f7247b0658778359439d34ecfa54585d44389a1d4638976f079ef6c145de7c8aa3da6373a2cf0705e9bada00e0d1389b2eebfc7859a55e77008651d09e9c5f8c3e60ea43be03d4bffef99f04d0397c2b04dcc6d5c231d09e5140f45a970123ae83b2469212175c041262ea3f921015d332bef9f06690c3eea98779667f5024b8d0ab5a2fb2b1f23174d9f54dbfd2c0626e80dde5e6846d3900de521bcfba73e9c1ae69cb62078bd8b7d304d2a007545a8a3462189eaa575def1f476633a947673093d0f2555c3215e24844ab0bce622d89bc34f769c8a5c5469222882b6d465ef9910ce9695dcf83444f5098dff38cb4d06d00c93a5f981a985c63ca6c00ed616ad47e9756633e425038fedab005cc014871bc16bc429f257a9891941e0d0027eea2db3374e053f61e8517ec1cdde07d6c2cd0c6fd98a22b0dac4b5521f6596bad4c9a5dc89b37fe8974c4489aeddfc2118f26321f0cc3d25bb61ac5ab5540086fd68dd15e22f11e95cee905ad4cda258fd62fa3f080952a6827445895d21c4bd6484f7f0f9ffb482c7ddd9fe8266cf5275c5726058f94ec0872b596fb0984145e100b0fe334986c7669c3aa3baf89377ec37906bc91f95fea4fef69c184c6afb4ff04d0c2913e4e4cac8bc2925b39d9b988304ba62f5e911e5ed0b02bf855fd2406285c5b4642e00a5dfcb4cbe6d0f93bcaa5d3735d5a67109806dc46b0a35a09b418d0f8b956e700336e50791ebb564ea42e4a88511e754b3cef4baf4ea0b448930c61999cbb11d4d8819d006b8fc8ccfa637ccb00cf25a2f3627a6323cb385e0347f589fcbaf7c021c219c38748860659be29d91eafe712178678821b00c7d72952f67c4fdce21b49250ab966cd32019bd32c1e3db361a2d557e3e4d5b2836958fa982797cbb02ca4f0582d68be7d86684cbb7fe0b0332b44793b3ea52e68f0e9dc6e7690a71648698edaa1cda744e595973cfa6b5f44e624b79d1a8d198143a25c32fce801d1670f15bd1c05b8be424c311b6430b8800f89ae51769ee73772ee8ae49987e893e7c200012414f7747364b81a6adad4a2fa880edf6e2192b902a21022bc48aa89fa10b20cf7f8094ca63bb3a7a0323faf47cb672c3710d2b9b6c6af9fd87716b8f1b0ff8ec5fb21ec60b239d1f11e7f1c61dea42e4305286182e535e39888fbff94f04ef2dd957e85e0900ac36b47e0cc753306a83f19a884dc88ab57687681e5e41e10415642b87f743899719ec8c63a28d7df8e5f696420891148fe8d67c47346f2cb7f153cbb9a687a8d0fe9062bf9c1de8290918f95b4827b5e9b58f36b168ef24e0579a215f0ee18f6a69c75ce4fb99d961eb4b52944c8f1474aabf285d24a65a40e6b2b5209ded496970e84baf1563c7276841aedceb11690412fd2b4427fdbbcda2c91a1286d6735eb855ddd497196bfa4183dc963dd6f4930dbd02c5ee1d036d1436276bf1451f6c73b88cfc1194368f27ba798f6ecaf7406f8b9320dddff8f6179146119771207e79b41b182718efc08e935380c0ec68c5e027bdc661ef24088bd642cf818e27771e27f29c2cabe6aeba71eb728cf0791d96c0f18f6a456e85afb1341fd7646a2c65851a068f19197ce005a8c7ba4bfe4787aa58663259e1c4c31f572264de4fba7a06ff7a0e937076c1d78563bf470dcf1d61f336566e44cce6f01ec6d004f36b15d3d3da45b0d1a783d3e4edc287e70dd820278fa0a9dbecc0ccf880d8dcdd22a4019cecb49c6a858d9e17731df4d5d2dd4ca720592b5e3531007357ebcb22e8d17935194bc671fe44b48150681ff2c3b829d48deeae6fc3910834535656b1fc0841927bdb990589b1ca65e30d570af31d6fb1fb55334337bdeab07cbb2246bd5725af7a71cf436701c63d3362baa3bd5c861782f36dbb3160574d6b96afe98c208527b386ef1b056c5d22cfabb7b3c52aca6ba9e3b1c45781c865244fa40d7bd09df9eb06e2a5c6846521c5655e9ce702051739b00cc94e6e713bc13bfdc53e842068121fa401cfcd10a2b983d1d261677b72500fca6085384e873b663e118c5ae089ea01fa3196d2002768e7ed720bca2c86760e535f5efc425dce10fa754533efa7a754e8ea963dd960eb7310c735b1270312a85246181b20248ee929755a03c241ea1017071a0a799be3c07191d0b5ed4c99b7f412c91e2c923c4d57b4f56dd01bcbba9e819acdbeafc03140695a0b1c03c7c9222b776f82898bdf1d74895bb131ad4bcd57a2bbeaacb3cdce3893fa11e02ca4db9ee964d5d0ea757a9deba979ec51889860a1ac2370dedc8e598a1257eab116eac539e4e822d6b4e8c202088f846b4e7c7a66169abaea68bcd73fca98405722f8f253c9ef93960fb59876cf75c9ae52636efa74c860f5808e8738df99822c3244276817e1678279b5c58e215af529dbcd119efa5c7b63c8c4b42075d9408dacabc2bb36fdaf439a7bb504dd0e2712dd70eb17686b2f8ad693ccb9f00647c4416b639bd682ec484c7fcfce7eec235e261564365319d5014e28b0ace40fbe10df907b214ab1487041121d744f130d0c1fd0eb4bc93e72e841d45d890db15d28606d462c932f3c67e611f7746c52b804d51c1210c8b829f8724ce3028a056c30a8dfed9c6cec92001b6950f0f2e4cf53613d1d93b1a894989656d59e66e9bc4a92c64f4a23af83e569cff650c12af1c78d9cf5122f027bbf8a833d3e921fa0375b9637a26d8939f318ccc63535607390537219d41bb4f634a344057e5937289150e8cdeb934b2c56e513928c0bc55017748462923bb6c820e8e54f000b745e20c9d0756604aabc42eb9715db72742e216567ab6a125d6e7219ba2e7a2dcf927743b61dc41317b0c536019d3557a85a99534be35ff16eb0dfa0b9e14557e8a05ed1111480b885b9c5e53545a7b8be02e783999ee9882a3f0ce61507128abcac700c2f910df1e77261328d5847f6f7089018806a62c656b7059970eb6ecaa6942d8f808a5387ca1ae410ba35801c49608a7ec4eb5510896c394fc2729d3f64b7cf23570bee0194814fb8d58a675f6592ee9d0ac861c05999aa180e678a9913b316394548009d85797a9c3bd8363d83e30c28da3588ad702e7a771b6945d400506e025e9ea15d07320ea60674b1ffc40b09bc2ba7969b6396747e3d8443e5115718c890fe5267e81cb57843ed497490a8419ecdb56b6a63be090562a6429fcec672453f9a46601c93269c7627fe302a0135714aa7f1ef8a35721ddac2debb8027de93cafbc2b3cde85711c7d78fd51ec9a6fc1d21144e17da59623e091d04471c9887fd3de198ff2feff28088ecdfad8e3e688d858a127acee28097ea555f08bceb032c08546e6a31d5bf11848c494704045dfa4a5e618b263a0eec41b8b14114bcd0b6817a578d6912af7611dcc585320c06c42424f10131a914cb06b129582c06b1b8f92fb402675c4f12914185a4e70a3640837d9eda161b23b30c573ac917d64db408134bbbc16c603212612b4eaeee0a4c034da18a082b088f487ef634d29df1a71b6a645e9a57fa30a9321964350f3ee4e7c8105e7a5a82b8f5a6cb8614eba813234d601448ff737cffaa94b64a5ea95a15fb38e8e520e39680eea11b0bce2f0f99abe1f9d4893acf3156f775a4084e0b36f15b4fc7fa1d07036d5fd6b59646c72f4e2d71e8e549e75f19d3b56044bd794379acccfcbf76af48eaddb76356ba24eb42934c190c40371134f7e6315bb988a0e63cf67c86bee468692e17271c2b66c41c3103c132187e3d2641d05ccc6a1f1cff4815338d63ddeaf87f2eb2a7b743b5e7c3f8087bc01689a44a0a7b6a2c261427be146012d8f33328a26b155bff8edff984178f44d0b5c676149ccbd4de980a0f1a5d991027e65b9ba841507944113238d993c73cf55204599b78241a15ef4e3c9a2584b98053ea2b29edc8f9623b003d26e2eefeda50a3905d7e4a5e36915b55c75d14d403d1493ccf6b127481dd58040634eab27c8b85f14ab636d2fb70be727b56e1ec681787cac9c56f805120b9068b0add076b6781d8c4d06c2e46900cbf1d6455a7592d708e1da8cfa25951f416e20638adf4b8797a0e28990b7d900f887d61d3f72a0ff4ac6b20c281568293a27b9f4a78347d29b4f2609d456a050c99613884f5232e764c21cc0a001642027514981455e1643c3be877f304dcbaddfb85602d167627f888dc2145853651f80d3aad8a41914917d519ed20b220b3fc372997128a12e8cd8faf83f79a42c9828e58294f4dee38e41e8c2444a555f643aa9cfd47771c96ca40d09a16b82d7b0f944d1cb4d519f29337e1d3bdf389638726cb2c6b045b7ecc858a173be5e9e846c514d3f207a76cddae269b2b799b06ed34dc48aa26c65621e251fe0a9b9f53c5f09f82d2f9fadcd32a21b3ba8d292ed12b811a5542f9e555ab2a4eaebe2dc773c6b63c00a9bf80d6b2529e5e85dfa5b04e3033800b3037416cfb1c8c0bdbb8d87019f008fb167bf13ca8aa84b8fb73dd044442a946742ff2c9167a36113e74d14daff9bf4d8f691e1c24f65998532b48c2837e648c7cabeee3402ee96b1e8eef51647a97f2a08371df2ef94911ca36fb8604c257a67cfc99ddee3c6a7a755aee416b2b8290b5fc17083fa347317d449c761241eded0f0edfe0962dd109bc28d4d2048bc5652d7dcbc56c4ee2fbbe8833844304d7084c5741c2332a10413d9018c5ae45a8b89898b0a7ef663b0a5af6d5da9bf893e1382aa1eaf6e9cfee1a96f8595082b1980424d83bf33d675d573a186cc45760a1a5d1cde693d90931592d5836ae242eb6a3eef2f8b50449888fd8b85b49d2cfeab785116e5163228821546d21daa52918e9d2e92ea1c3f40e491f2b895f65b7c6cd71778714a96c59aa845a86a338f58bfd0e4f5181e4e764f1968bcb022b1e7e5a027414b41e88683a51f6ec2c63b526f6b277e40e4d0b5c489c6493a39b1660da9c58a1dc32dd64945f571972dee08157f3b0b4c6057445342c3937b42b93e911f1e6fadd1ba8151d6c0a829b1be5bd01197e6b3a77268a2c542a46763d1a4d9b299af0c765de8d90756608c156797305f1a4adfd0e2d611e42d6a6b9ad1b9743a5a94c1ba00721684c3ad819c50d448f8b944317446b7e99331b5e1c7192158f62fdc7efa1505caa270b5777c58f0498d4a25f9051ed5e25201e8e44fb3b4ec4ad87d0efc0767453b80169b6a8733a1fbecb0b0ba1272a3bfbcca7d6653f98d8e925aea86e8c1875d137d5306227e9b1c85464fbc43f3a408703727fe7194a463dea3d00de8ceb45a6168f452599c997cf9cc4a0dd2c027e5019e0e01c5d127f9da9882bba7fc0a681e1a8b9f0a8d4ab44aef54b04c641aa77c34132d12360497b14fd521c62992f6b8c9444219069a42ed0fcc64523dc6938aad339839fd489a05f1b744a1057db24ad1454e8363dbcfa9b88aa35a0c9525a8d70292f5c3b16941209bc1d21e2662bf3b5974bf9bd0ad0fcbfc5875c9405f875ff5482e64ed62b323d54544ae9295b7ab20494ee8fe9bf749aea3a6ec9ead74f9e960658ad13efcaf1f544635b74aaf21b7a4aa31edcea14f448404cfc01eaab40621e1c2c834ff47eac247cd5dee578c8ec0e7e3ee6a7376e29a539c490cd67a7c7edc719b71974870e00fd64239d2cdc7ed6b8ab151e0360f1f2a8864ff4c39185f4444e8eccb13e963af0b6cf622c80cc154cc6a93a332ed5eed439fb3b57ffebdad9fc00a0fbe84b7dff6aeca1b775baee9523ecc0383d00f828cff72ebb22be5271a54fe9646954a685ad40edc7c798b003123cb013b92bd180c96bc90b17c8076fc2e486e73a835e1dabc42b40e51ab887b9bbc5df2e2e46f59aa2691a9d12e0a353fb82ec673bb446273941e048c6c43cede59f18d32562616babed26ffffcb214ea498bf92d6192501c64318d2c336a77b5fedf2d514632dbb9f1a20b6890be37fa6eaacdbc65784cf2c253094ab107042af588084ce868e03265064d601fd5f349aefd4c58f64363a4de24a360520f5bd3bf326c9e51d202def5d6b567ae7e2f9663a0057fc849b89767c77184e7e2d3ee957d39f94d4d5955c7789de83d0c75b165888ac7e569ecbd2adbd3c5977ee005dd7de0a8530c88d38402540787a96c469e4086297e4188a9d599a591d862da207e346252ff4ad63ca2e5f05a929a3ae62e362971d169d5dde9daac9e8960d1c35e352ba7a2cf6bdaad0871dd42ed544c5d260263edcd7f05121b59a19ed9e6106cb5409484c905fd82b718e526199f03e6b3f2a90f5ac94c8d6f15aeceb28ee4c709b22671337095dda07b4076cc810a3bf7fb10333bb8d16e40eca057b7d1e533452a3e8466772f1354cee6634ab93210b5da549a9519eca3b2a298f604e7927ca5026ecc3e738c4a79f7e12af84610c153e221aa7c2cb168af4aff31bdef5f3ac21cb86407cd7e33888c99f6d4a3f28eba4852ea43b99565847d44f11edc4e7c856a2c23b1f563d6fd29fc026d6ed5d51283e25800e4549699dcbe6d1b6ab5991d3e90dd3a247c0ab81e0fbab02817c490e6404df27725030e01f1e53a2f6b505a61400672931a5a0e86c086195267f13197d2a557f5109dbcffee42b3bf35ad920882640214d9ee226500d4f939544fbd8b7524717c48cdfe36d5c69c3fceee9748377013dd713df4e3aaeb863e20a5c12e7bb7d38d62b0e3889ed44143e13a0fe4a207e4811fedc0238cf0cc4cdd963e81f7f519e40b90d353e8ae68b7b86040725ccf0f1b034c136eed706f1abfc1b4f58a71a71ff97eb8593c54e9c610c9390b19dc2d9d98b3cfa78e78335e46dd01877a099af4936d5bb77b7f02e7585e0f5ed7f4aee2261902179e724b59fe9fb4a42a4bf32d0dd53fc1d1b931d3153dd7631763757624d393f401a25537db63db92b0b85504bd2fce003b3b653e48ad6502ac88edd819ad75f298a2c6fd84e90a31597fa346a211e2e87aa49f221c53b7ae0b17e823e8e755968ab9ac96f75148777774fe0786686148f12000b80c01a0a200a1e99732754a2c7b560c92dda0f0113d783d2284a5b8bd098edac70141c68863672c4ebfc1e726f289b567c42ef8a506998d0f997aabb0e7b8f47a7e95e8c26da467297e0e71d6186f2dcfc27c4c6555b9ce6dd6a9827a9496b3dd7d4b082cc49542815f44ebf4ca439557cec9b53dd14a4b79788094f99ff1e7dfca91ef0e8e7641870db6a7130e0a21161bbd0de8a029fd1da0c67049da8fa5e34ab6b49089670890fb408c3fa04e3fe6cfc21fab8c4a6cba4650123ff1d8ead73287b8e396baa855258c369bddd137a25acd387b574cfc5bf5cd3e425051b39a782527d2b5e2b752877178cd99403e964728164393fa98a95c1ac2f0ba37ea88644a23465936a1fc008198bc4a0ff38c1eaddd9d35c7aa9fc9c8403b423a259e4ab8ab5ad38836b1b11ea7a2e363efbd347b9ba4ea0c39adffa7ec546d5d872297e67a89e9672d7b2c933961a496ae9d9d0af6c466811aa1218c2c7f15ab999019987e4c79effcefa23da984ab2012d30bb68777449bb3d09744e08b39fa2aa152c17cc2d846e1ff9687135f2a3431c0c110c60c6a77c25525001e1318a445c855cea2849bb08865131184ad81dffd86891097cda3873557acc48cfd83fbceb07edb233887d3340bc0e240cdc63fd36dae679385793fe22909d838d2f37f2f82766595eb2574030e557e554230553953f7c325224506f098155c4444825aa98c3b50a8e05549c1e05ff3688205d0aa01f08b7c94dd9b8e5cdff929b00b1dd1d727606c480fc245dc8021bdc873dcc0c92cdfbb9d1445d9160eae63ec36042d6333e49c1e39396089df126ab24640440772b81a424dde3e71ab95e13e5a1d044d1f2124a62197dd79cd9fc5a3a666c2b291c9c79d80298876eebce1f85716dafb0290b378a997b36983a674c1163cc18017a82bb1c85304e67e9704098fcaf1c4a18ee390cdfe717289f407ab12366934ecddaf2e59ff4fba197f1848758d5ecc7f48074901d1f45f4d89c6d04c1924513b450008841adfc2b45a28387cc0b3cfcfef8ab3f08361306279febbe42b076de418dce67353c25d70b5adaab5b92fb3176ce576eaad21c787d1df2a173716ebf950018997e3250f6f5b6bf8e93f0f720b27825d9e28637e03525c3ab17c5871eebe6530095be30184ca13c7bc9998281cb233b82281baf7636ba6e4dd6751e8e84a49593c9dfbb74d640689c1220185725f22b330297122c45511beda31ed0f3453c3b0018a82828baa5eec41040966f260c069879afcf445f5a4fbb3f061928e6f4362083f0785a51a8c587d7932538b51c95299cca4f56d5d0ed4abcc47453c74ccf5cb3046cfdeaa9f763c5a8384848bfecc48ad443cfbe1b2ea277f46a8a3c6618ba58dd9f4a99b843562a2028c0eaaf16e97f9013765249838b47f53fe2162d4431876b51249495ced6a198a8f21807df8e53aa2871c8f5e41ff4fe5a202b751e461b700eab209ebc8518d69389f444bb58455e4fc45109b5339f2a0849a289b112dfd604d84c2736718d491bcf7733044982af4194ac503281ed953cda3baa6f0282819dc2853384657e4098c7c6c11118cbd1601f85968917fb97911f7226cfde377b809f6fe45806f178f5685792fda7efd29929bafe21bfa075d0274e37157082fab2fa729c2255f9e704c370e48de4e12a69a9c3f072d19008fc1e36a250a8d1c289769fbcf88a57cdbe0ba43a2ae87f976f6170e0b2e148a575586d811cf682d91cbe41433cc17c9689db81e0ee16cd167a44f2a52c5deed923a2278cc7ba9a2d413c6553af682ebf973296091d4fbdb3855707fa6f387577ba72809ac9536f11af8950dc1cce587bd669bbb8428a2ad4ea1e25726177aa543f2e1c2170b6a18b37b8e86966527510918ce368d068c6743c4834e35698ae11c6e89c478db947bf01cecc3d4367f001463bb5382318d7e900918ce5688051c6753a40546d4cb6cf270931914da21d2cbc65b6914711562fe1eb7d7da1b81a8782f10501e53403f9491fc0ef7c82af7fabf2964e6daed3afdd625c436313f2f3efb510c78498d85c1382136ce6693e14606e5c809d33db4be70ab264635189177791539f0c1292e343436f25586030e3ad8658bdaeed6b23537bcb78ac2b8e2eacc6b67f2a6262cab3a72d71bfc24d2dc49873d472bcda5300e772fa63747642f1ac7ad214410c00f42cb1e14434362d1f46b9f622933a0a1cf318c3d564bc83e80dc4203d40b437b0a02d524d8e7dc1850f340f505a9e2fcb2d053e206895c1b61cefdee0017aa17a77821a5b5ab12635680713db063e63affa66961580f73245e7ea6b2edca6770e2d16fd3e974fc64cf59ebed068508449c8807d382c493e68a8f433917d7f9607193a44923b81f14eae902071aadd9fa0a4f5670876d73a25e492f0fe668eb4c642af64247765094bbe0270c162f6e33393f27c2fc346c8385c72a1ddf2e2dcbba41e728acb0a37f8f4d088db3a0032a82e02dd9331ba923f99d983d2f9c29430fa0a6f31412cfc12dbeb2eb77ff1b5e2e42095ac4de523485b94463e6aa019ff69218690ef64c5a50792d792887ce409e042cbfa9db8c8dbe245e381545c88668b69f452bfc987808e65196fc62fe6217155cf1fa13b22c325fd205a84287b43ba35d992bb8ab84add476a1a73e19ad009d1d3f41df1f781f814303205f5cd3279a017960d676993dd03bf16b73939329a3c4aab407030c6a1d00312d2c685a86ba311b8053c665fdf3685509ec662f4a7c05546a24090034f87b317da9b1113458fccf9f22c267c1f24d3922407a00cba66036cab69ce2b9ae35790553104d789de1cae02cb2798f5bbe0fc63d1b05aeb7945ee8ebb158b3db8590ef789b9a0a3dd9e04e3819b56506dffe2f34e05c1e9a3c024badbf952e1e58936b5cb0246884cc7d6b2d494bdec75aa914d121769ae27eb6940c91e9fae06cc6b3f29fe686afa553f7e656ab02903a8dee6fed83dd9860e42e2641684d0c57cac4d37d9ee0b2bf66576aabe1742bdd0b95a2aabb008863f4e75ff18955eddbdf3278397ff85d61ff6c75bb66ef2f1a72fb462ee27f4e7b773d667f68bef452e6d79a9a62cf9775b5b5de7bd63e2be211af52a706230143a26599c5862e8960e2ccbcc8f5468d9dc4c6a90ce4a98ed8e6c058a6776c29934f374ef7f4ca0aa60df56aa74ecaf7734c5c8ebe1880ab44d63714c1558dea5c2122320e6635a653fb683622e942d9af4b793e9dc4fdae75f66a062e536998de2fd43ceda4fa4c6ec95f15e5dd1b0587e5fd116e0ab038ceb86434c6fe25d097cedd7f81d8b399b192538f41507f5206e126d000d1106c6d43831887c7b1606b19dee279c567df208b163be7095da1c9b0e403f6db5b626c89cb983b99f5ffc7172672bb74a96dc368ca4c78ea52fab90ee1b1d7f6056664512c3fb70fdfb946c0a439fee065e3f5aaf79b7dbc9bc3c608e96b1cc1cf6548cfbe36ae0658703537901b728bfb3bce10754714b1f596fb7f1edb1d69cf5925d5ac33bdbbc415bbd972c60c5ff460249c3da845037719b741fd94014e2625ed820e43486695d26a4492e41d710ac619dfbf287bede611cfd7e9bc2b53bae4660ee5cd0ebd6f6efd5b0c3790a3dd29fb0fd74bf5de460be6876bde150e9ad5e647e9f439a47216808cb5e8bde5f0b956934a0b36b33575b628469764d6d4ffb95275ab0bbf090f07e533a80fd40801aafab1e72d94006eed947f8f27b49c5412fca763f06b03e75caca68af0063deb0545312b9c0027c6dcecfd8ad852f009010d72515ab63144ec050c1c1485478cea32fb787a240c9c491c050050760f9112f5b024a754e97b0576815a9c64f336df0f77ea0e0cac0d26964eef77c3990607af4f2e22409e20db0c36a0f049e48769557963f0c80f1061573357f20f0b196b9fee5a6a15084ecc8bd3944694530258544e2e11eea2b72a64153dc71eea110782c2e3de435557cf983c21f87c473cf860b94235c0d40f94d5cde4ebcb18c12bf8a462ad03802a6c798a17116958ed3ec46d07f373da9ef077911ef024f1a840c49ccd16b1bfe888d773527741e2ab800942881ea9c75321a45a711328b5b380ef94ba29ea09632f1845696eb743d3f6d499f19a2f0496d7d7e0bb13e32b6e2327dd2279afd2cfe78755018d9ae33744692b1b60e725e61a856dc3b98cc60e065e2ac4933dca512add08b21f5f5de70fee8df4a9ee9d014749b4e9fd5f1be9c0994c0c62f3b8bbc5e503af152938e093d9cd75404bfc9f735f644ced0b023a0ea22272d13109e4ac75119f62a11ae075db2aaa07a8343d74db607613af12071bfdc09d4568a1691e0a225e6fa0c22596b41c2de79449286712d4c4d030ba3c42aaf5ac01b859e3b76ccbfc369c4ef3ff47a154db260613901a0776c5509730821c7951f084ccc171b9d13c2d9756966869498fcd44408ed6424f385dd4802f024d5dda82b04c0506743bb6babb11cd99217050543f411020803da5226a048d12545715b933547620707250df70a5ac3d5eeec916b0f6b6cc765ab894a6eb7057bc823568cdc7427d59825f9a78ec250bb789651e26fa93937b2aa48182784d3e34a3f57f423e03b4485ae5da586c9407f88f9f23fbeb45baa023b559fa1a56fad09fed7545e4b124ca3d3f7ca378d64fc851829e943184dd9110646df0cf03b1d3d9e2b658cce91bc64099fa06c3a683f997e95656c29f93dd8024c632c5e6bf80756723bfa9f12c32dbdf55759d65920b8537fc5527e234360e1c4c74a5d97f8d88f2e21e79f8a1bdf7dc4da37b21efefdd4c1780522159e040c113abffe1ac255b7042b726cac213fc33e0674a1e88a8bc71bde7431e4592518a9c67f0b0cb2a5df81f42e51b6f84763b474e8dbaa9ab8fc630f847e39c3cd130aa4469e8d4bfdb4e389055a611661b3438031cad4044185303ca2eb4f7208e77e063246c8040d408c10976e657d1cbaf95e6d72780c90df73e81410b9a3a0b456f258250d0a142c9ec601ce93cf72c37dcdec63ac5e88d497e40a178682abfc23fb7015a7033b3f35131bb97799e7376959b484be453e0e06919b875eccd0ca6760944229c947863981e435b5a8744c2cfee4ec7c90ba125e53b4bf126ddb5664a84e2597212281a3017512ea4be809880ec36d0e9ea398f8586867526696a7652ece268b887ee75e46b31f0fcf4db6215d98cb0ade861cd8627918f9a9dfdd74c040709bbbe5f9c6aa47086fe3d6bc78f2672c84b40aa5ec879178c0fc40320b93886f4c3030aac45bcf6135419c2b8282bbaeb5489b1b2228184877d73eac3bdfa57a7952621f386b7a54361f29b49e3b93c2bb44bc61f200e0a38883df0bf587e731cdc04fc49daa25a105cd996f5dd72d3ad3bf18356da2729e48bec1367e6b5b63496005d15a4d6de2835388a0589aa8bf54d53aaf4a1290bf479cea1f4c7b2950cce616a1af25918a2b68e0fc105d60018059e9f57d60a31d5b99f6363b365638765d87b48e1eb3eb94269727c78655e0d5c6324ff2f20de7cd1758d969cd84822ad7729740410c49c2c256bfbd6fb0e4708736434f9ab3a3bf621b9f0a35359a82aa08a88edab53b5da60265e3c8a56b5a1db49d2bec5e790bad9dcdd5e7a7328cc818eaef593c51755165bf3a404764970f411002ecd2dc6bcc72d6a1a7dc6881cd31634d37d02437653d8326a6351dbfeac7c56f892e6eca343c3a2d4ae64ac93e028eefd0412850ba56367a59e66a683524c4f43188a38a7c58278bde338d4b1452c35d3bb27275cbacd0fcec6944ce0aeafd7f7237a71413363f545fd7057c29749a542029696faba371ef87212296d38760a6cae579e6afc3d703ca2cd7aea1ca0b522b1856ea0c572cf00bb1867fa70603506193983d38f443b0865a89f133133a209f726feae548249b8c12f7f263f72e53ecd8ef06877173e3b2e33903ac0aae17c588d4f37291ae06512605513aeac9f51d3241be14df76b91f6f85ccee0af62cb068c86c6ca2a691c9e26e6790079e66381a294f53c80f5cb84ffc97176e88742330d8562f74dd5ba8fd333964d3f8f281ae534c5e90aff03c865d120b7f5301d0811d42f9c43fc91c9257159861d699a4014913b2810dc5abf08c48b2af51e1eeae0b2e3a2e82649c7f6b81d65006dd98a6315901b9088808152aa848364dd792344a5b253b9cab61d5145a51bcd926e57f1292562db1f2e369979aaa7e63747d3452d22fc924c8f0a5d2453376fc25b6ecf6cadb7e272b9d4305b2d59ac4892b9e28341ec748bb0681c2f87e73143d89fb76fa564e27967655044010d4543dfd4c602f699be777d2a5302d59ab67009fbbf2c9aa1088a1c3864998e1afdd79e14d5327e417a7812d11ef17f5ab536b1c41f64abca8c7991f3f3ab6b4e2f231c4ecc6080f293898292f7800a9c90df5703069542a7ba6d0e05d7ab76d907e2fcf6ac34524d8d3ba2d400addd9dd1be7b8b1cb3cf86826745df144be6ad2c3d3a2600de4318d7189a2fb048a1583741184d92fe9b7c71867eee8a3bff258a8d0a4005b2580d7c5735eda56d258291bd44a2391282bd43d0426efff2796383537c3a9bfa174321000da8e818ab575e9ec1fdd10fa18b2366285c01c18fbbb3f4b45f4bca142d0ece67ad5b298838920fe5e4d64849255bc7994192fc15833f6a5c369465a69228567bcb997fb6637b1884123f95bcc699edb0b480bf2f2744176040ea4f616f1ca8c6f4698b0f5fd17671989b2f2a8d09d918e78353329d86faa0b302d0dcab55d4ec58094350e855c9ee73edd251060bbfcd38c21635d6c9cf4993000ce5c6100dde90a2229814fcd7e26ff15e6bad9ee530315c6a2fb7f1f6a9f28757fdf4abe2ddff9a8f4ae2b4694348f86454131b4c2ed2f25ce17348a814690642e53a30b06f38788d71aa901726626d3820f6e97458e075946a7d5e863d87c0169db1c55113ab17e46a8ebc731c81996d9678c4f27be545c6e88edea0b70e49add6080b94f90831a66a5007c9b196d154fbb30ff801028889e22e1da4dd57d587c52bccbcc7a41fcef353fbb6d7acba72ad970b51bc98ce56fc6eb95e8566dc003039e00c5d5a7052458b5014110f0e551c310c8ec04885ec313f6d806f4edd644a46d40246d8c3de5d6726b8de02a202f3bb7b7018b14871bd02fb4b801857296f1b685ccb3b577e5f5b4cb8dd269084d4314b6d0d8703aca0d28ab983598f15a4c3bf24135ab17086d72cc4e6ec0eaa43cba074235b901a956434a83aaf8bf4bef06ab6b976b0ac708a044d492b3ff6aafed065c08f73efb60493c04d43a961137882001b7f4092174958ecffd45d53c4ba7b9e17337e0d1ca7ca83e27f7e8735938aa236e697180334cb6aec2a19a3d7fa818f9f94d5dcd5c3d8de1c69301f1ad9e730fb0b9e0105e0682cd7236bf83d36405ab200e6f40ad7fd29bb3ee15667d1c486fdb59606f406028298a083ebd9338fe5fd963ae402e3815a4cc49db5c873256795864085c2fe4c7d6c7ec8e6af6bcb16edf80bb5308570f7e3c7dffe1f6525ed2be0101f728e71e4e1195e28f9f4a2c9759bd34e5f173afa8e361f14fc001dfaa49073860414a1f2349810e1cf0dc5438ab9a7ce44db6faa742626df9aa52cd5ffff980061b0ee0d3f9952cc873bafdf068507a2b64f3b67726227d9899a4ae8cfeb443986f50e0301181f0e621d303f9a36c1cf8a665e074cfe4b6f22f51e02a0f85c79b068c3498520de2968bf6892391b3c5267ea77b65395d39dedcc03b5764faa3c48516cb9d1fd320ac76f83c64be7ace19165a744ca458737edd85359cf3c3baf5cd2c39040d61b10bb6104a478b02f2456e2de4fc88e7fc924c1746d9f8b51028bf9bad7fd9708862706e5b92d0ef57513d35dd10a7e503961853602570427105ac80fc0caf54868d54d33d0acd21032717d46f7e393433707e0506be6069c5e1713838bf04aef27525045f69f2bb7d52cc7de22ac0503d54ca16ec0be727a4e1b0e5bd882ddb3140e1977dab4a52608b392ac2ba6a65e4b4e1a891dd3177207dda2a1c172310d927111f4275465eb0b2f924faf6907834a101221e6073c4d5523fc8a952b0d978e519e636e67df7cfcd15b657f323c2f451ae867d89dc8a5620793ba16cfee69ca9f9c958aaf9a3b441d0d014e0cd519b66f2095dd61e8a53be343f5fbda5f96985a34a751d202e15b534af994bcd08cacdb9a6f98939ffdf6b7d2cf5ca0a09dc63a119035dfba02049155ccafc90a78c01023dc5bab9381044d6a808117f91336b98677e32497a3ff4fecec83aec80df8ca68714bd7ade18ea3b3774d7f2844ce40bd6dc0385138462e885e8954f38a030bfc31893af99edb5a634bd8b0210f32370bb3644c4fc4040df4ac548626841aede3db7417385f4111ee5190cd711ccaf836109c6607eb8b9e9db2d3adec207f262cca1992168f2168a1c4afe86b2ab755e82a671fa4ef7a24e664f174204dbd72f43f01e205cf9c485eee737659127c8794aa37d25a37a53d6050dfab97f433433af12e51a77b5b7e1d957eb38a07f06f0ce1585c18020d9cd019ca51dd6b79d80f0873864a74c5274439b08ec4b5c9bdcca2b1132820c1f0a56c36081d48adf9136e9eb56ab8a4ca760e37c1d2a56156b6d935f7a7ecade55b77348f3ff53b8528eaaaaf2cb414942921a19a860a4714e3e4703a539638f0775d5268979d82c3555a93f4eccf444698a36ce1f41c63c0f83ca7e705f1b978b9a928b7c0a2c2a976cfb99b4a1b2afb51cbc7bed15860351ee0327539def2b9a0ee4ac1cc8cc968165575092a6ae1b2751526d07af49c5e142642d836d3851e8e33d804924f8ef690531cc7647d07faeb26007e73c0d0fd7f694c87f486b5bae1dd0259918197f0fea2c57a61e1a39a907627e6d623b1b69890009d68ca48a594467581a11369277877332462fc2238e91bc23a40aecb6e3a092f3f16b86bcf55e72f2152f7826ac4f2f0bb123ba06ffe3fe63470d23ba0e3f2692436205627fd0133e07c6f3204b5f49b569d5956829da4e3c8cb3e30be5a4a2f7f0554e10979b13fba0f60688959a2385941fc4594669ec0333687a74492b0db91a2ad31512a9b3e37bd85494e50e7365f4d2bd405a2539d89c8188e068a7e98164f2e83649dc4986fb6a0b6778df84bb883474a16b6839cc932e250145e28453f6b0e9de59b92d39cac56d031f47f8945d149302a560e142501cb7c0b96ebd13b0b5cb499f87907768e8eeeda330fbaf0ff2f851f8fa4b674ee4d31d1cdc65c17aafd9af83bc7d56a4b4f35bdaa4df5254669257b2121c4fd745ed933cc79cb227c802ed0ac45509cb59f3926f3521cf8783441102c9a5e7c9a350db3f8f8a8840145b5953b1e80d32ddc547f18be677a30b3a91236d21767a3af89a1b91339f570b62d9087ae63e6cc6cd28fafff6012781f4abe342493c0a1cbf5a75056ba49d931db96720ec7941e76fe63dd41428cfbfdb11250befcdf449ade77a3ce78b1c87a1970d92b04f2786cb18e968cad656466df99ff2d4eab92d45f57b43ec136862be68d7e09a39f5eb08f75376ade40b661061af7e565a0aaf8249b904c8d2dfcaa034f6a95fd7223e22e57f34f5eb88f689ad297aefac56546687d4b71d941eb7989e61222fb5ba4e8b1c20281a2ec6ecfd1b366d401017a9044ef3b0387fcc11ff4afd70c1d6becef48ef98413cc067ba61ef256ba130ed125db88f2c2500647d58e1fad3763dbb33683045844d8d66c5fd082879c2918c65354993e43ae288f0f02db8433ec8af270072021918f36d6a297388bf2d68245321e5f0540e11710b7bb05a389a12b7227eba895cdbd115cf7054ea1126e4caa09731c5809540df860a32100c5c47389e6a81cc5bd5d28e79449b54e7c7e6161048ff1a6c0c495e5ef507362fe5253b714d6438db148f76d5a296fb22b7ea10035fb59ca1b12737a777d5b6c7afb2f75c9c2fc26b40e9396d5ae0162fc7692939fd5e25ab22ed5a430856d9ac206679cf28452c06cbbc84a69085d811116f94aa70d2127eaba2d53109bdff22b72ca2b1f35ecf64dfdb88e06a609fa8b86c92049a283c8bb7687c419a4fcef84d236dd69f7cb4f1e69cc85a35ca37d7e49144f46e0318df6276756bb1a2ec12cc8816b240c1bf07343208523fccdc43ca6004cae58c8dba3586eb7148ce9f404d9ac4e9333ab55ded8b500a3c05277f243145ae561b6a82a680dea2aa93bbe688a689c8765076066fd986f98d511eedf28e955522720fb8d312befe5d4ea4857d1fc5f0fe3b7a9558668c819dfbb1014084bd606104fdb5f9d122d9f4904a05227c759152d3d9d8ee0710e02acc3640172beef67eea43f555843260324a8efb41205b5db6dffdf9a8aee72e990ed9e8412e9b21c6e586955f78354fb31e74f28df113a3cb3a680dd1fee2399f17a293ee3169665da0da71a911c60b5ebe41c1b957690279f01e97499f604396d065522796919700f41a514a2d94f8a5140ba6d8c4b61d6cc85ab731a7df2b491642a618636646e7d31ba33ab5b4c17fd1fec936d68b8ff247a0cc07857132890be5191bb0580872c43d60da062aa149cf3936f89469431a012d27f6f4329ea4c485920fec2663b480d402bb97be3e9cab4533df786c57a13ba83c693fe8e7bcf10e83a96e0a8ccc57541d30c0551315e08d8a50a465020ede620806a4a5c0bac11441326cb58d534281ba59d63f0fb8dda6f877c71c768f93e12fdaec34352bf0be32671b8f6003a0a62c0077d048bd8c11e2d9c59d14059444cf16dc15e718af8a573c62ae2af0c4331d900837e5148e90c4ea0ce0a4843f1ad290feb88f94a56f3f8cc05158f90aad838c7382fad5f5312442b14da8777c907cec27969fafe6fae6700289bf6b247e89c54dde02805206883769aeed2eae4a2d9f044e174050856450215859bc9eec131a5c0fb6243f14ad055c76c7af9485b2ba8e70a9560d373e94ed285be168543de8ba2896709e154b5094583901e92604b17897946a039ff58cc9262c643784dc800d5ede26c454c07e0c58bb8d320d10bef121a36589489373382036bc033fa9bc7295d41342195c92a003ed2502020d231af5be8049966295dde1c0820fedc3421f210d86ef3213ee60c197bb3f076a5b06860586259eabfd66c205d3d8550d3a20cc353225955877c95e44cdf4a7676f46c25c8ae8e18fb73eb0ee097c19de7dd34dbb6b426e351c51ffc3980ea0ec319caf8d605447fd6944d820c62ce8a26c36cfcec25a8727b8168978e4f67b867f25c97de0063c2dd57582dcee74fa6542ef792ae14e4c703ba2047a6531028ed6ada01e8550a9197346991534540b728c0a0bb08271588b3160c849188096ad0e414e9e0881100ba808102500c88109952139bae660edb2c0e4471085a0a19e288f7f683d636b1465b1249a195ddbd039b0a180ada0a1308d8e48a573597a4d4972280008a4d2188200b36595959b228f838b3b2a82deb2578428237a32697cb0571828f3397ab926077afc38d05bf519aae132d5275289639131515d5041f6754949438c1154e4d4d4d384cf07136353d3551a023868f5349696932e950709b46b6699bb6307c9cb679444105564c915255b5041f659594abaa0a2c20f3e4042925a594e0a3943ac102da189dff9f25c1c7b73b46c309eb10bdd62ebd7e054276505fefec2956a51bd69e02141fab9a5eff4ac91fd9eb5f285a64d3eb447d9eea3d938380578cc2b4631a039cf08a2c48ccfc0b40a1294601c3c7ebd4eb75a27308fd1b4e9c1c0c2068d1cf3720948814bace79e79db7d61acb60ea4fd1663bb42ca10aedeca473d2a953ab0ef32ba5945617ade2acb5d65a7beaac624bef1e13e1dfafdf8e9de8d12fe78fe6cff3e813e1eff46b518e10a8e2854bb098ed970e4d975d36387086035bfad5975eabf7dde7fc5a8f586fb0e5e26f5f6fed7371acddbe4b6c89e3edf64171ecbafd2d8eb8dbd7e288bffb07a27ac664fefdaae70dbd49a5d580992ea44baa37c6f4a73e521c67e84f69546ab74cf05bf1df35af0eb99e7b559776fc6e5f268b8c2077a42c2283a8fd1286ecb7d065af9f7fcb2236c87e4cfae49ed0014c81240e600a244a939d72d1f72e594a0bf3b8f794120c59ad946186764e20e69c7b8a29d4c0c79c2e5da0b4069e020f9c8a630c8a149cd62a4a3173217b6e28e5095d3ee992ca905299477dba4069e1a8d3a5b4f2aacf4fc1c6e719a91b11233421395c4371e2f72a47801540358c8062f4e02e68188bcf55c8ae145c8e263992e438626805026c40a27962865b652e048994834d1f65487d7c2e7da485e9630f541f8d9ce9a3bca5e9a38cda80551fa5993e6e7b35ea5e54e95ca23514277250d883cb97584b6ab5c52a8b1c363982a0e0ca38dd01e3cb639388bf5d97efbd17638cbba0afe12ae03bdc85322298e8ae0c9f63b2984c1693c5f8b3e93a4b69928fdd0c2f3d3c37f6175858b25228485cfeec6b38b38fbfdaaf3dffcc624f4f8ccb32e732de73ee645c91e1d4f5eb0b9bcdfa8bc1c048b279ea9b9bcd53c7be88b259e6238ca51f604c01c992857114048c2bcb7194f6ec8bdcdc3967a43ecf4210c6539736cb22f8a24902309878174aaa33555d529ffc948342d4d502b7b7f5e7755ec69d6d75af6b776db5adeed140a1b1753de5cc52719cd9efe9d6ceacc8a4f6c8197df97f432a32a9bd87d2a4fc1d557762324e8dee95d59dbbafec64900dbaf2691792fa7872e2c0bf9f73c63ac0c7d84ecd332765108e3e88826065f7f44ca23305fafb9dd0df18a90bacde850d84f9724aa942fd2a5ada81085f97540f2d2d95166abaa4d2020d95164c6191ed5d14d5164c4a966a8b232a2db0ba696dedf4a9d853dff82265c4d5d2cd5ed92d90244f17266617fa46527da3066bc775a373a1c1ae2cf2ce8027e62b42abf161abd102827bb4ae5c6d7034af9616b04dc54d9818113db6a71b3374c3062078c8e408a206ce1e6396450ef8044198089624d8d2c651f8ed21ea3b269843070e0ad8a8800d342c60a30c5a183b38ea828f0c0652086183091e30197819d209d1a39334c8b2011b461cec41a4cbeaa0b3c3c7aac81b463e343cc864fc642f8e98419223f341ee09849c1321e49400ca19d1735c82723e0020979424a745287783923d44c86384ab25380e12dc60924609dd192678600420aa4957e6842a04e0e4444c0d23f16409852e88146e0f50ba1c868ea2ac51830a7a0c00dfb1c21c048083858e8d0278532d8c6180eecc01b640401917c624e04901502c8009294930e0cbd8852888293d34e0263920cb03d4307a610f2a5930d80101ab220d44a0cbc5808604ae1932484da00b0a98a90099199e2cf0040d61aa2061eb966a10c286eb839534928cd2b065dd90a6eacaed4b63b1a43983c53cc2503864a72c69be2869f172404a83e502b90d06f0c8618e2433683c353ae4343ba071e60a1ea6d822a607237cd8334403881f725042e306203c36417c7608e1c5c1858d21a88810a34be662c90a2f5114b184119f972f4a4778392081bb01cce701263b92f0e250a28d25d00883460c95190cc50414b6093358544a34755f9ca05a7a620b1454494e54465160b5218519355353534c454d41f1a434c5443330a53445a998b2e93baad8333ca30a6a0a8731062c432653610514371ce68a33b850a53249589c71d4e76f337b86f3025c52999165061d7dfe36d2a4a11899314365c6c9034a299d0498520ed192ea1ecab116693378efbd7b76f71a61dc55c9b403fbd75680678c39fe9c31cfc1f33ccff3bc2c3b24b297bd6c2426488242765b3b9dd81dc61877358df77d466272f6bcdbc9feca6807b6f32c7f62d1dd8ecbea8e05bb3bdfd0e08b3f96f9bb17ce20ed7939e7bc33eec2dc39af475982af5d77bad0e85ea37bbbaeeb82649e53f225c157deb13348cf8dc1c8db699911c6624c5665398c6d1a85065f7206698c31c618ef2e94417a4a595ff5b336ea3a6bebd5125ffbaae2a6b49f94c25146d2446a9951c6d1144aa3634cf551565197109d8e21d5e94fc112e34bffe9924aca4a1f634b97546318750ebaa40a43aa4ba13e435ef071be055de2f6e022833a7e6d831003abd397228655a73f855af9929466e7ac1d88d268d7a364f6d9c957f794d689b32b3251623bee7e56dfcea6c8a4761e03022be51f3c1ffaf85076e0ae1efaf8146fb0d5b93cdce1aeeba88f38167d0d5f07e9efdbdab17842b77d7c32bef4c9447d6618eae3dad2a9a422834ba75c3a7d196a91a1ba338fd41ffcf489a6bc508b785f8924cfe7650c76b2756da57337a035c6d0c3292fd49d5a1f06db7de855943274063f21079634b73c6372300654197a50e52cb84c4ff2d0afad335c4071f1d477f6b86842d2332a33a4baa432638d1ebb40cf9f721e656124ca2f545f6c6150998144196e9441c68c21d264b5acccb89901c5e754c617f6874ea10b3edf950595195af2a8513ed09f09ad84f6281ce05bfe6cf94373e4cf2ca3730ea23101e0a0fc53661ca4750d6994466942e80e7d2495e3a02c46b1835b5c75d4e0567c1c243f03a1a97d21bb06b75de2b2a67a7dfb435ff0d9c75a2df5b1350a1b2e82ccf59a6991195467ad5a2a4e0a2e39f247484fa2fbf633a5896f456b7df87a15e51c427fe80c6ea70f143df8687fcc7de7c89f9903862c9355464d992fca34596b6df6ca2c9551eabacefbca1c61f59cf3a7af50437585d4f77d9fdeb72b9e6616e8b98c2b98ae58a2ba22a9c7d2204121392951ddd050dd9e78c844754b9269cffb2f635c6badb5d68ab10da9e08ec5b1ca124abde794264be21fff88baeef1cf233f6ae8524669fbef6b18985871f6c1406509feef75bf9d53daed5bb4fffd6c49f7fbb758a577af5f7b4bbaef449d6b7fc8dde6cc654febc1df75b5bb17e7ae8dbe133eb16b5abf30d79d2fb4b403aaab74eff38e8d6fffca2253eed897f67b714ab3a21525ee63ec662cb7e499ef013251646e5c96b82c297dc1ea49d467cb4efd2120f8c83907f7d0534d7f1a57620c1aeac2c10a0931864bd7915463b6f4faef928f421b6e8bd89f3f9b5068c3eb4efd8c82151f737acd45b2fca9b7230d25d50395357d4aab22d86c9f2783cd066e1fcf505434e5cf94224a9bf63b221409a5552294569f8a3d557cfcce23796a1685481e1c8e32ab0b913cf55390fafb554c434b1d9dd54779cb34a0ab5e3fc9082548914269537f0b52286ddec7579422055452bb144aab2e5ce1a3bc7d1fdb86b522387d4d65dbb0e685d3d7306c1bd696387d0d816dc35a174e5f176d1bd688e0f47504b60d6b4370fa3a866dc31a174e5f4b60dbb02604a7af65d836ac05c1e9eb096c1bd680e0f43505b60d6b15d836acfdc0e9eb19b60d6b3e70fada02db86b51e387d4dc3b661ad0a0fb61d6ad0c186242b39186d1bd630c06d58bb00b7610d89dbb0a685dbb09685dbb08603b761ed88dbb08685dbb07685dbb07603b761cd88dbb06685dbb06603b761ad066ec39a8d87365bf6e8e1033eb0f9c1034a7a00d18120b284c8830b1e43ac2102abcb1d4b7678e140115746d4f1858e23e640c20acc0698e448220e25aa9680238c06c4bcc1849a26dc686ac309369ec841b186931a51a421459a29d078c265808a8aa92ace80da36746206b7a19332b80d9da0e136744206b7a19331b80d9d88c16de8448a338142404369d8d08917dcbe1d4aa345922440212034b4d83674c205b74c40c1da22aa89a86d43275b70fb4d5c98e1840d6b653ce14513509c61c2e90b31518011468a309698422a093198c6004306125594d105aa8c2f63407bc612283487c29864ce28c28a292f545dae002d8e8832a045638834db864eb89801ad1af3e711a0105092357cbe0d9d2871fa7ae6b60d9d6ce1f4b58c12c35d2d70464d2570776794ad748299138979c4fc32d990b34dab7b2512c89f4ebcbb5ef5fca0ed6ffa3d5dec332a92808b22882e714e591d8325e4a7e18861e8be883e1579c118a8e04e445f9620ebd48ae3acbd0ba9c836bdab9d8885fe82ef212a1e8120bd28089d40c619557589b35255714715775e87f1eb0e14c28f339f5fa7e7791e7eef63d51395d427baddbcfd6594625c41a1aed22be69b018d1fe3d7f825c618632c85d2f08f7006638cb1d7bdec7eb44f612816f5196d53c78fdf36bd75a2561d3715f96e666151273c706a35ee9dfb783bd65df796762d412878f071771c559bccacc9a64e2c6a247fbac7f4037208bee944ca46f2e0b7e2f6476ad5892814c1f3df90763d6fd4a72eb9f3466938cc10d4f8d12bc933071f271635a234fc37a4364ac30f543d7a247feae39f59b408bda23bf8f14f2cea83833c526b9043f0e32d7f466ad5c78955c56a933cf8a915a5e18fb2016ec5719ee9f8476ad5f1cf3314a3e9b86235ddfe8c42c10bef3e8fbbdbdba7060e4b531f330e0b9395f8c7ebe99eefbd2e25cf98bb1447fbf98918d1a1c5ec7c2fa432c37d4ca5ce96108df7a508f4bb4ebc9fc614ce0ad3d41d2da2bfef856ea7e45f383bddb176e6bd87c5ee8ad2b65064b980ea8172150667450967c3991bf0f530fd0a5bef857cfecb062efdf5416c40aa814ddf03abd7cfd1e1e24885f718665d3fff0e6c02fb9738be5c3fe6d91649a8d2f58b3fffd76bdc2fdff50a5fafd6c3fe158e2ff4d777a009def3d78c842a7d3f773d7f1804aa7497180109fa1667fa895cbf5f6f51bed0f9bfd0610ffb71bf60e10883892f91087c974814e45f45162616d9d78bf39b9b9b9b9b1bd8bff60dec5f3737fc61fbc67beeddbc5eafd7eb05e50af6b3c39ef39fcf390c67e50867431a0dc3d56095f3b3e72fa9ebf592be5e0f545f21f83c1c8bec86c1603058d89a20095560b09be7e1fe57585d4fc47fbf8bff7efe5b74fdcdeb812a2ca4fd050b699fc11ef67afe2ff0b9087e91d579a14b2ab84d9b3657bda8fae82d2d668ecf9beb65b81b94ba7df944f371371cf591e36eb08963ee326f106794d56319d050e4c0e180cb7294e79cf36f9ece5dc729c2ea4bbe5eaff9b01bd8db778930318b44ba0b5657b50f83515776b95cb0ecb22fc06cf7793718e70982797c016b5a5fafe7541c79878daf075d4f4379030b611f0b616fa98feb467c3d3825d6e9e7f1854e048eb3d396086e1b93e5bc0ea5c91e4aab02a35f141ae78f9ad201aa3b165f9cb30b40b21bc6f8862eb44069f68782e01688d6168cf4f4d068ffb25c143a72f78a76490a2d758a78634ea7d51d7b7b774111ba9edf0b93d01dfbb46af90585ae785f4b2c274e9245202bb61010a5d9a751aeb03c932373638aec9c23796eef39b4fdaf7cd0fedad1eeb5b4725adb9292a7be182dc2303b151a6c5dff0ec574efd5dd85bbefd0484cc7bb1056d60a61ebd6eabaf16de1effefbbcf994964525b7635147f2d89f1f058fee639466c1269b539a958a75afcfa428a9d8487549c5464d8f658053b2cdfad6da71ee9c19474b8b5616322ac99936974c2b8c161877ccd34e98ba64ee98a741259199eebdad2ceebd57e6cdefe50b21d224bf15017fec8b79b956dce9dcab86d55049746badfd6dadcddbe68c53f6d7190ac15f5fe67005bac6034d7d946dee8125fdd65a6b2da5f57f822274cf6335090da5ab98922315668e36e7253a7d4ef35864bb7c698decc1266acb8e42921d40ea234d56ad8c3a8026e6da4007cef44c2128ecc14723af23cb994ef02993489ef9539a40ffefc7e4d34b86bfeddedbeeda31ec11f999df03beeb3128e4e2d3355d138d14e8ea40a1964bb734f81264a2c5283340943673b4c890065f0b6dd0dbde66e289468878fa3da14fe30f7b387f058572ad5807a77ed7d518a7555cb3cb02850ef091d62dcd86944ebae64b1fb94f75c9d1ed1aa4deca03bfbd53cd9d6dba38039f68ff833f73d7ef85a30ce3ee180cb7a7ab742f2caa3d8bb38d39e44a7542d2ca5b1d5a0a68c89ec0e5d4baeb72a767adb6d7d721ae18776d7bce0485f44bfdfa6768b5b5b1df4f41a1bdf7eb307f0945b52f993fca282d94b5feddfdb5b5044d779d9f08a6f523d4222d9108a544464ba40b1f73cfd9536263febe0745229436ff8af7b798a42726e4d689b62727461db95effdad792c6282d47f6319637a5d1caa45edda9a44005af9fa35356554c733cad999a23ea09649ae3888d129b23361f40b2ca92b2881819358792d5192b282b27acbef4d81a3ceb50b2e07444f509baa4a2636a9c92d3ebe39ad3e9635152b0899899d40763e388034b67ccb75e7f4e8d73d413840302ce4b20bd5eef71b6a82ea9da44b5e1d2ab12f5c1555558badadbe1ec7d1f888921f789444c0c32e95324eb20745cd5d3bdb709de79845ae9f23517367cbc49596cb2ae91cd59353b70143ec0476bd5eba3998a3a03756b72fac2a4c40529c9d6ab11565695559a5eab5417aa5150a0e06335d3ebcf1aa63a7da1b45a997a1deb975e2b9739bbba5495a8cf0c237fc4c823980b39a47efd81fe90d447dbc7eb74451c35a7e096d2a88ffcfab88afa8c52c491828f468cc85b1c6afa789da88fcf12f51971559754719ce9b557ac86ead9be2198d9e38447396826ea1c0dc19660f7f260df0d8e651ffac7061244489fff38ef0a758400014324494638e1492c5ca1859b50ca14585824836d1a851329b4eae3bd89d7098a1d7ca453b962511f7ca666511070be3e56a3a48476ac060f3e56a533bdfe88c9e8f525ce8f584daf8fd1c82294a96232e4cff715a7e9f5f1197abb257125fdb3f0c55d2f5be07e29d5642b8e2563338d6813a9676ef9a937f8b2b65c41fc5f2fa78c707194523d2e719451b41747237dd2a99e292d8eb43eebe384f789698a5e83dc9be4a9ef85d789d2ea4771e2234dcaa1519f8fbbafeaf36b8efa8c01457c895ada825bba40972b5c97aa3c96bee4e1e509e7458925ac38966e4b6d2c4dad2922290f2f485e8c969a705eb81461f392d5bd5475e925e7c58cdb2b6e49aa4bdc521957583b587589d321eb4897381daae816c9832e713ad8d0713c70e912b7039b0dbac42549751eaa78c8e1b638e1b684a13f65bfa00960eedb7aaf98ebce7c30f729a802e73588e4913c6be68fee78dcd63851894b7aeaf96915c7fcf50ccfb277f9eb63714fa2fab58ab122dea9ad864e674bbaa72f42f7d4f342dd6d8cd2ecd7e5f7da5df73326b488774f9cd96cbd4a9fdd2fe2fd7e959eeb2fb94f9fca2c1d7ad697f4ef7d49eb65426d36de35a62f657447f62b8b7872a7be7cf5da064b9efaf27b6d4acb45bce35f426d35742cce98d0ae88f7fa4512ed41a987a3be25ab8f19b7450edc965c0f4db81e98f2c06d91c26d3183ab02578511b82a765843ab8004eecb17dc972e3326abb22a49cda424259acb55559bedc84a494dddee768bea3d97abca4d4d4f9e94d4d4b7b4c4a46ff776a39292949a9a9e5ad8663b722d2d31f12b7c85b35e494959292fe5a5cc04fad0b22ec8ceb66ccb47dd3ec5f1663b877336870d3e62292c85a7bafd0b418e8ff8866f38aadbef22c04db8093f75fb5802d7e3249c8495ba7d2f848957571374b92ed75575fb5ba793eaa4baa96e1fa4a0bb75b72eaadb6f5520b3a05bea963aa66e9fd3663b9dadb37547dd3eec82ababac6eff06839bbbb95bd5edc7845ca92b65df074f98c16dba4df6810cd1e9b94937c97e100daeeddaee51b78fb3c1d55556b73fe3c0e66cce5675fb39442ee8c0deeccd4675fb11f8f014b14b76c93275fb6fc426d924abd4ed871e589bb5d9a36e5ffcb9bacaeaf62738c201922a55a5ea54b74fc1073e20eca66eeb53b76f410875a92e55a66e9f06549392eceff40b82900060e77242928420b46fdd66a0640d3ed2a6a6215504bab4d43382d560891009fbea8a03262394b0a5a43a30210d3ecedbcda706200d1f67535391267369c9c8090110c0be610d8d1f27fb86d989d2ec0b00149ab57dc31a0e897c82c60715051c08293c998102a14c01d5a1337a1435f253be0581b989d26c56610f60dfdcd4ede7a8fc447dc61c95cfe4a65cb79f9d3294adb449cb7b4b659b4eb0842cc5b383963a636d0a6b6df09173d9fca7d19e1e23f5061465a54e98bab916645527af5e086b6af8386dd376e4bdc1c799943495beb9b43499f46c6a7ada70f071de6e33aadbda151f676ec2218bdcbcfde986f4b17f23561de4905947b74b52ddf2d046ab6a5eb9e6d5cc72c561e3361b9723e96593945e1b5882d125269855d30d6f4a7aba99e316cb373a7c58a9291cd6eae055079ad33f68aeca8706f848afe8957dfdc30d3e565bb5d52255a956fb633deaf6b50c7741be5bdb83d7d73916828e469025f87e872d29f209603a310a7e54f0010bd8d03cb0a3c7051dc0204b481e3c7864b066480f9606776cc0811dbcea207934918dc31a07f8586b92fca93ac81fbc030ff2c77bfb758bfcd16fbff6507da83fc89fefed57a50a84fc01df7e0d42feb4de7e1542feb8de7ee5227ff8dbaf43c89fd7dbaf44c81fd8dbaf5de40fecc55d2d907e796bafc31288561d248f7ddd810555dc67c716c1c0080ff560c8fcd1401ee10049071f1401c183108e007d507b0852dc060100034984948830c2921c4860528209016872820030e0a4f604850ba4800465288a0a035881002c6829400b063800025c4880026e58801406681989a634c0010f7881ca0d3040a0484b046290800c13a0400566b0000d556c3560b1c18a51961bae6039ba8243161cb4205db900067248d261071eb6f4e0c30f4a58800842882c5c8620a2cb95252f381461c4952f47200186290925960823060b135a9a6872e209289cb04421c514599e3240451557a0c6602163050e372c5794c1c24c165a5cd9024b94162ebaf0e20c962fc0d012869418639081064b19f7491633b29c3145a505a7050d2c69b0a481831a38ac91bbc2c69536b4b8a1450d0e6f1c69008e2a2c716091e3ca06ace6a0a38e2b0ed87107d69a1bf0b8218fac0ee8e101361f987bcc36b61a6cb06274c3152c473864d18274010ce490a4c30e3c60d982c5871fa812103608212897212c115d96b29722eae046187db172c4c6e1131b78c5e1931a78c5e1131baf38acb5e1f53555a26e59030ad524c9637f080efe7dde70766c7f4a4d29343589fa489c96a46ebf6ea95c661cb36ac2313530df986aa61bb38dc9c6cccd35a61a338d9966a23171936a4ecd33a619b38c89669231c798624ca919c604637e31cf4c2f6617938b1935b7985acc2ca61929a594730929a59c454c2f524a29e71629a59c5a661629690e1403f40214896aa159280ef48862a15768d29c78cc35136bde31ed981c9857b38e49c79c635acd0d4c39680f2deff5ed3a5dbf8f84da142484c6f676d9d31b74811eef5e187613f3f103882c08ceeca300df0bea0af4ef7b7f5f80810542429e0832e001856e06a01008864fcac0a1ec78481b6672cf1a770b4f83dccde2db004d4f0618680ec8e09bc81843782e003b4893c168f988c18301cd55440d7edf0341f109197e9f636ca426c5bfbf0f86bbe3ff707e8d01f670d6e2fc1d5009f81dee1ffe0efcee412c7e5a042b009bbc401e2b8383a078c5cf780636e9fe7bedc18f999f23585c1d415206c90757d4f10108371042b0828e1080c8006d6967a0d0ed774cd028d580e29339f8c82d14a5f58d6932cba6db2c56ddda9b96f71f86c1fba2bb5f7717dcf9b30595e0d7b87bf735be5e16a51591d05267ac57bd3a69e2a3cc92c1369de0e33c3a4aa24ff0712a292d5528f83899989aac131fe7d3d3ed46c1c7191525d549c1c7393595c353f0715655cdabfcc4c79935b36c5e06f8488f8e923e2af84895949674157ca44c4c4d1b8a8ff4e9e9068ee1238d8a926a91e1239d9acab9ace023adaaa257fcc6479a45b36caf2bf8588f8e926065f8589594966eb0e06365626a8a99e1637d7abaf9c8828f352aca89167cac23d49caea23ea304bd7ead55dd8afac82f7acd12d56bfd8277c9837366d6051fa1ee40706904784ae0c9d73304a5e8aa13bca8ce4da5c04705402c084269b31d08e6051260104a2113f0503033b060c88eecc1a06ac0433718523590e2b473b06de84409de254fc56559eada6712d9367472049f6f8de0d367dbd0c9121f659a158a22208f44698116494277ead7d96ccb580443920768488c224218d936741204fff901828f468c20f1e0c891233ff0b1a78788061c2041e2031f6934213b18d8d0490f7cfcae437d9284f2489f40fe0040f2d4af3f45a0a1363ed814803cd6010ec2ae00cc3b2b846d01286d1e40db864ec2e0a0eddb864ec0e0f4350068a01090e4a91fc50300d836ac85c1e9eb24db863530387d2db46d58fb82d3d74ab60d6b67387d2dc2b661cd0b4e5f8fb06d58eb82d3d74bb60d6b5c70fa9a846dc35a14a7af996c1bd6b6e0f47509db86352d387d6dc2b6612d0b4e5f0760dbb06686d3d74db60d6b5870fafa846dc35a194e5f0b60dbb07605a7af9d6c1bd66e9cbeae6d1bd6ace0f4f5936dc31a194e5fa3b06d581bc3e9eb14b60d6b509cbe86b26d58ab82d3d743db86352a387d1d65dbb096014e5fabb06d587be2f4f500b60d6b5370fa7a856dc39a149cbe26c0b6612d0a4e5fb3b06d5873e2f47501b60d6b5070faba856dc3da139cbe36c0b661cd094e5f1f60dbb0d6c4e96b046c1bd69ae0f4b50bdb863526387d9d806dc39a184e5f2b60dbb01686d3d70bd836ac2dc1e96b29db863525387dcd806dc3dab86d5863e2f435d1b6610d0ca7afa76c1bd690e0f47503b60d6b4770fada01db86b52f9cbe7ec0b661cd084e5fbf10b8e370d6217f4e0168db59fbed2db995dcdedf2610797fbd2ef460c85f643b6b35f6baeebffc755d57b768999d4e4fbd6eed79bbdb99fa8cf74159ef8761c05fe4556f7b0f4477d60fe28e43fbdac3dd83baa33e32f943bddf5a6feff3ba9bf77b23ee5a6ffd407487520a19bdc79de7fd8c897daf7b7c71b660f0dc25cea9899e6db63b86b6b7f596fa8096fae8973acf3006adbac445d105f7d15d2f6ba8c709f4ef5da191ebaf88a11242c76f45b609e2af2be844067d6f65b609e246782806ac9ff5072aa9df9a40778556649b20d7b7aa95d926480c16a514f235e9feb33fabf503b7bd7fd325ce894b17037e8f430d0378bfafa5c10eec2ad855904b9e10baf7306cfd1ad4bab55baf6da9cf7f10a8b75e6b6dd5ba6bf570b5e2ae9e12cdbf2da55566af7e9ecd1977540a3de4c5ccdaac5fd72df167ae05e78444bffdd65af075673328bec6fdb3b97e5e27e6257ef4292bcdd96c361f82eac7a4e48e9c923bb2880a4fa82177641f5bfd471739d405b7d5da4a9f60b275e6e867f912a4b213f4cc4fe3484f3cf59e79e595cd34f1a5c3f8fbbeefcb5e16379843baef669294328a107cbeb455e8fad5092e435e6869e28273220dc535c57e688d28250fad12898205d7544e5a5bb325348f285b70896b6ac23585b1fd89e9deda048c7e5ae913592f7b15633a9b543153d14a4973ad75680dafdfdd50cc5d15c164af32b9a2ad62ce6fbdff68b7d60e71805b5b43234f144387c8783a68292712393486e29880c2d2236a8d12dd769ee7618c31f6249dd976b826d25cd0040cca4ab3bd4363706769101c8c57c4199c182531475ad4e09cb8c23d81c4b544b1d99c1cf913cbd183db1f63e2bb86bce0f32be812a7c41315c72a76688d7cdb64836e43fb2fbde0afad0c2be8535a19ce3a95568662afd6e23539d7ef6bcdb2aeff0b7738ce51168a207b2b00d67eab258ead56abf55df72d31bfacd2f5f740754e91f52c56d193a601ade653a86f3f7dc2d8a3d8a3547856987ad4faf87cf3a22238e9636fd2c745140c895c4f43a7de7cd07b1007831308adefa2147455a83e1f47744d4a54dff5f46795196837d228221fe0d1d33c421fd39b07faf001a488522ac01f2b85eaddef1f20b8abe8791efd713d1fd8c75397e889f5a738731979d90759e23d7d02c17106d5b1076258ec2915e34cc4c114c411478a449f0814c7df94ce6f051165e298f7b6aa2e57287badd545050545f00124dcff236c3d0dbb07aa5ea8bb98f8637e89209f73829c5241915c2e91c87bfce07e100427a754707196df551ffc91227597a8c2137c8aaccfef7e7f8b22617134822fa5e2f7d3234ac53c22fb7e0b0a6da8cfa354cc219d086402a1aaaa5e55b6f9e256b6fa4a3544baeda09773b65f44fbed72f63ca2a20de611ef6dee7ed4bfb7f8756211edf9472d763f7fda9e79248f44f2bdf97bf2dd8008f5c9f4e65bbbaf32030d3db74ef43d0d7d5ed7ed9947ee77b0cfd4251275ffb9fe3efdfc92faf0fb72892f223dc344dafd776f97c5d9f7dedb7bb338bede7bbd89bcfbe34bd4fa3ed14bdfdf601eb9e20801cf936abaafebba8ff6f49bdf86f379e8bd2bdc7f43bbc13c02e28cfffe2782a038ebde7bbbc13c72df3eceb76db7fafeb7c13c32c5f17befbddf601e91dd23d26797bde38ec5dcbb2b6e308758d7748da1f59d7fa7fef17b7df1e7fdc844ccf6a87f9738304a4c59bda74b1c53540773d431e81277c454aeef0efb2e09a704132e892b5c12375c124ab824a464aedbae5bfb86fcf33ccfbbff8544ba7adefdefbb5e9763611e19b1d7fa96387adffa117feb52b188f6d1fbab7ffef444ba82677be789e3049be815a697d4799d9e22ad3243952b541a12e1a7a1cfae5b611ee99e4e1810fdfa9eebb738d2914e0f268eb0f76aec47d8fbf8b1be0f2f26e21f61e2584516e610ef3b6f056fac7fbfd7a008b09f22d17cfd1a6cb2fbecdfb3503fd68955f4e1a38ab10fb67bf72ccc235d0685be248cef12dd4111f47b7fc3f9afd6ef2b3b0bf308c7cff1cd8ffb613fba1e268e3d9d3f8e0a4af09758443b51feeec7fdf3c7fcf3f9683b1767f8bfbf2ccc23dddfffc4a22dba1e7c570b148b289d2cb0205960610eb9a2acf29aafaa23988eb849e1beb0f9229c3afd5c449a4e7fc7ba133de6d2898010e81cca4f04e59f55baafb5e292fd4b3db8a217fbb32aed139d62790f2025050f60c54bd0002174a20a4d1c481e20042f5d175a61457a56be97ff680630087f95a0d07ec6e2119120f9401427570ce6dfd00a2bf86fa812943fdf9ff8b3973dd18aab4d50168f88046171cc1597ac300aa10e2bf2ad6885fc196a955a6f125a0c147e2af6232041a73f2928a4ebaeb4dba494009854e85b3186daa60d05a9d01c5a019250a5d3c7610f2b58f1121c4008362901904515d2e0401288ae10020f398764a8d0dbfda47fabcd61f79576af7136bd603e0ec950a90f812addfec63febdb6b6300d2ab0885c51dc8c050f368d3a64da742868a60e403510bd42a97da349a061a2c307f3ed62d3d7ffe943ff2e79e9b625d795fb0a6704b36ac21b270435ccd56378bc8ba43eded42fe923c14367728ce187eef8b443c35491ec963bb962c662322abce1dfbfb733aae4b544b0daecbadd3b94a683a6377451399731e917248124a9b6fd4e957a719f5a50eb1a5d3af7f6f9742286db44fe91f11c1ec2dffdc5b6f5fafed835597b81eac3a065d4bd9cb7f427d705eae407d2078e902f5c99155b683b97ed4a1f5f49bcfae37311fff03c8cb087ef639df028572f26cfe129759049ff3117c8e3885d6737ef6103c080a4110813885d639047cf61264c2c51c319c49fcf9e3fc068570f4dc382d9c90bf0499b4c420a1b4a3c49a4c7467b65a0fe435280404c80612b65e824cb6c8e6f58fff40a11f45b37f3fbe1fe1feb0aea67cad2d7eefe33d50c8474b9cb2fbcbc7cb079397b8c5165e5f0685629f586463b1f0f504bf1effcd6350e8e6756f2ebe5267348e0a4fe07f3d16a7c4fa77a0509e12ebdd7d8981e0f8c34ff7dfd6bd4f5ffcf5f44b80bdb8cb480ba47da1ed9de779998a0c7dd4a09269b3bd8560b6b4c042c232fac2e58ea93ba4b06e40584f9d7e9233158a19bcfb242348224828adc784fa32195adaec4013eceb509a156d8ccb644f67aff275a84fade2959c426932071860e89e4addc3d6f1cbfdf2e7f77dfeeff35eeba967f7c2a70961a66f6e032e88a9fdd9baaed9d6d9baee76676d5de3ddd9baf63cdcea1e88d6f0761b66bb6b0edda1b22b7cbe91984b85061b95196cb6cec4fecd52f256f70e7becdee1dfbdc3206d6f6b3fed6076973af4a31d193df9730f10b2973f55cb6bb7fc9d220cb96391766f36213ef0b1a787881124404946903ff7a5cdb8bbb58708929aa94f776d06f37d628e1123dd1ada14bc5a5bfb0c3f5449f951f0696bb553aa1459e7a28cd2680a4a3c8752aaa2e3a804abda2a731a2a34230000000004008316002020100c070402711cca3245927307140013798c4c5e4c1b49a35110e3300c4239650c02c00018003202332323990223b9c7bcb04f65098014aaf2fcfb1e5ec9210f35e211f6bc702506614ed0f805e04b93163f2523d6557c82b578652ce1e1926f4eb1e9550315ec849612cafa5884b3ee8f0987e08a19325c50a6d64c5029f8f8ae2c7e26385c9aa05731d0c210800d0f695b924964a1a44f4733f2b7a1b4337ac44b09f087ed8639580aeb68369dcd2263308f038f8282c91f204060fd46e51d232b6f4e8ae36c51492a600fc1422c6520b6108ef9b21515151c43362f8023f82d3a7b06ace08729c49d1406bbf13527196d40f0b72712deaa5a562a502a1293b0f9ea64955b87a9f7c7dc2253658d6294efbabf635b04d9c2faf2dd4de625cc31bdda1f695db9fb5d2a60f2173574823ad5c4f10a6b61859c41c1310f1e3a0c084f7f33675ebe9b43a74df2791506483a6e82552075afe080f4a19e930f4151abb4d3cd71b66711f364b6691626d272db20ef33c575012046b129521e4356a822d2a3652e2eb770851bdbfc816e0b88e3aaef4a54649236496751d1d0877f946fe816291c80e4d5277a7c479a55826ee75c11e6c59f3c3a7b17e0bc69f09437c6f301b9940660139128392723f3414f2d27628dda8ae31f68601481b77c2675d1f074f07b476633cb1b8c7bb087097b9942f62dee38f33432756106c27fcb8cbe7000659a3261a178f7cb7352d629f611f0eb342ce9601626c7b689ac56c5529170e5f80473b57b3c3d0c2f33d7b8fae8590617a107cb53390eba39f64366298a0f5569390798372875cc261752cd520a17b8c687e0b20965de1b6c36525fba49243b076f2c2812942bbc675a48319ce75c86858d9bf1c4539aaa22172eaad0cd9083a6f3f2cbb54bd8aa7ad8df7ab77ac381fea75db0c8ed4450dfa70c9e8b16deb899401e9a21df4646177171391e81a090ba891bebe4044e5b1b3c74890deba0630911ad544119a1ebf40d16eb251ded225332ab796a5bdfd6a5ccf300d0ffed45187fa03140c2641e100a1c7528c331d75b9c0f75a9c2071dd05952c044081b619af2dbfac861a9de59d3a11ffd6447ca09b7ac984d2a57441a6493547038ed183f6db4e07fb7c362f788bdb747fedaac62de96fbaf4d2a03eeea06185791510ce75e69d1e214c301bec5d8adb02d2763ec9be518b158db9908a04cb286214dc3a9d25843922c7269c274852c5419e8c1601198b02f2d4a2d74e55a9924ef0a387e7151c9a02d672165c5d0c3f60a9d60e173655ab937d6a6367e367484b7adc141c1193d82d327f0dbe39fcebb75048ec68494f12aa5cac37cb60701a3f2e8f02a259f7fab4ccd563f659ff6ab87f13fbc8edc701ba28ba37f700de040d303dace3980b712ffd60102c9d091831bf061585f34c641c1eb2ee62fd38ea70f44706d125286de605ae05bac63e2c2ede1808ee23caa6f7d26b9c8a40aad492fcabcbe22614cf82eeea2e802c0a78009b14a01f11f2ec9fd5491e84011e3b61300c267f637d09189d1d5adf2a6b91748f863f6c8509542be0a5f82532cc7eea1fd676fe597db5f72bc5e577c51bbf23b2d5d6e7c919396f99208d76b78398d5a1c869f11dbc1be7f6965ba684ad026328f1f48015b54867c9ff5e41f4a8831d23343203052e8f031eedfdacf897a15d9d61075685b7e32cd90220417162f87e7ee1d346d81dbce4f2dcc58a26b0479f6accb228c8143b7324acda9aaab0c8ca406a1504de708ba9609820666534e6597057dfeb2017e3db1f75ae282aa3ebd57fc66bfe8b019c51ab7b73c62cfe5aa1147558be6c4f2202a351e5677faa145448d26a13343fd0c92477a09d1423a5ba9413834dbe45742926cfb04451296ae91d83d5fde87d6dc2157c3f31fc0cc69beb45abddbf1f7de3d0cd338340c404bd495cbdff93b5ce42dc53ae495ae5c387b5a3e98d51d18454b585c861116003816edca65e6670aa2612a56342c8c54c4ae0a5a483a4abe45a13e97f71fd8e4e41fd49b83288652f8e3068da1ba8227906c1e0d8634c008f4582e9ba3177f34425388367f59d1a8cb2ac4cd577875eedd08267baf81edeec6901a289fe40099ff45ff2f2a69235d6e7d6f01cd962c85c0e75bf6448815e236bf38a103bd9f6fe1fb6283aa643f2fd958cecb2783bbe93a343cfe1620792049e9b0547a2676756585e845d1791004ed924c75134928037445f6fe08e36f81322fe97701791a5006cf3415d4642cd02b6359262d37c6df5289b48b1b9a047d2994166543d0e5934a6570e9e70cbd343e95c463e2b699e124c2268b2cd5dee8031c5c7072858369432ec550dd2348a3b97aa3717079f596bb816006d659274ec03780b4db4672c1bac898ce6b4fe81acb396f3512f8ff630b42b7057ef3071a2f347a7e5d8858b25c2ade74ab3da7a9de6aad076047e27978b9da8ba10ca396ee76798e2761d2d7e4aca4e242892079569a178ad65deed2d5132c5f80e5bd39512aca8c96a5e189a3b2d69f8c9d20b17302eb29a1e2e466a83f6517ae4ff9d644881a4079901dfe0141cdb3b1b30d4551c22b26759ede46da52ad008881c07c8c57e2ec62ce22dcf9ca4b236591cb8bbc7869658c080cb3a349b9f98d6e89948c0033af8e951e2a28dc2621356679949775c4ddc38f1d1e02a26d229d6ac3da3305de35ecb24057e83400118c507a584a1cdbd7b2e6cd111ba74da1769120ee6ab99464009312f5dc8f2d92038fb5111caa3c2efd1d107827b1898b6ad5dae5ea50d0ccc4c9e53ebfff747579d38cd107233640e6626ed26808d926dc313eec3de9836f95fe74a1b832969bae9a869d435b2178d16b88373e8e6e2b0aa625c05434c01d03e564dd8f72624c2bc6329645b294cc554aa4aee0aed3789da78e34469e2dcdfdd05d7360817cbdf2badc607e4f004579cc3d9d02b5527d3bc2133e534ddb02b381ba618c2a49449c77b8cf8a64d1f132f83a2af26c412699b845882cd6b86b2e7493402f78c816b0a17613b9e99ac67faf339421295956418207ca167044cd86d491fa23921461abfa686ff6564bbbf97fe9a598ddeb9090d2d1d49956cd071018db57e89e67d643882014843bab775c42cb1abae7c16354e94657b2c4f17517d70f451d52b4b3ce13350c061af117dad669b6c3b9a113fa352829cb8c0295dd036a14b5f9ceb08be3101f537be63605423e087294c6402422261084aea681280fb3b33f7420c124b05901b2c11dcdc77a398ae61987e8612bb7438aa4960fe80957c80fe4b8d9a078dccc629dd71933338691e7dd359a76811cf079fd5c762aa80799366684531f82204b5ec7a91e89bf706353d1a36021dde5818d3e55af74d8ccb0bde61143faccaa2eb518416c1d3633cc5be376108dca1976e64fcc3e075a47876d7b957d2ff22168e454d9db7bc05f9479a2e17d783dcb86870d5f08643d96107d1cf50cce2c42bbfe77ed40d77aa2addb3e9827d675a3da60b68b96792dc55a3a9adfae3721f8c276b8aee9ba4f054edcbcf532294e3e0021a95d2b6f89ae9929ab733d8c1177229815fb932f4376346c882cd262c075a586c3ae6fc7a6bd0a3b3639965c19f8b970ecfa561c53ebf3a139772c469f33ccbcada4c1d9f67e5e5f31d89672b0559c115f044ec5162f0c4fdf77f1bd270b02c1d57d83c5a893519ee574f3ccab69d5c1bdbe9e115292adff52be74a31014e93333d02b8711e4f7b991acac346b48f3913d0ccb7c45469ad793c7c4f35734163e0c10c324673583257ae135fec0164fa94ba964f3c8add8ac1e9801c8f1ce0c5cc866c6439f826c032658dc59d9d0a0ae37c320215cd26af97baff3c75dcdcee067321a414f88ecaaed60a0f26cb0e33a3fdc8661860425eb6e9f250896d8fe4b68c20a6d04d35e3b9c9feeb2ba924acb395b84b714880ed670127351406a2a605040b97a9d38e69016d5930f2f36d1810acbc147771e0c82bc84bd40be84156a6022f729605302294968b4b7623cc335f5aa219fc7cba5fd614230fecfc7d63431dbd54aa7eb1d2804e046c875884083a18cfec1ef00f9ac94e924a4cd63bfd0d5db28d61d395430187d0844884838428bfd55a755799d06bd327a0968b700ac635e0b99acfe932f5a096f6ac4c25039284fff80e3a1cb7a4f9a6851d240c86720b8b4b9c8d04105165cc5335fd1bca794982c4238452d80f7c3785d976cbbc9e3c6d1b711716a7c57bddd3007565d42ab6ab4fe7ebb9157adccb5230e69f7daa4fd97c8dc16322f91b12926da322734c463e6e1847de1da09774997cd17a69b1af8ba3a76b190cb76b26ce419065071d08f61088b709104134ec8c02261b88251f1ea2f851dec6587fdca4f72a898c304759ebd4530d4c77e9fe39825876762982e1e449135690699958dba7ebf8906fed11b81a3f2b30aa49dc536db6112766bc7407b4ccc5f5fe7a41d15098561f2aef14c71057bf0fd80fae5238d2f9173cfc58133b7a57fe24655329c3603b297bf2bb5941e228a6dca7b1e90c2a62dc184c113aecd5d6cf0d0c89ce38ffe703034719f8c864a70d0633403f10d868757e1f47844ff1cd895602c59343059209bc53634ca17e7afaa2e75932f2f79f6bf5eadd4d490d17c55de11a380f6fcb46b782b10f52da163c9fb2686c11fca7071f464faf666dfb6abda1b82eaf7157f24c8fb24c894fc7481da8d2c43709950e8b3f3fb40b434db8846104da3c25b283122b64d90eb851676cb09f2c858c1e11d7d14c38ab7dd575998ede95871d5c1990beac14bcc7a6ddb2734a34a98dbf81e19fecd00d01e3e72f38d2a5d2387b5d8caa782ac625c83eedcacc3dfa1e7a12fd3a338939c5055416ef251e24840d4f4e7d370e71adc2c6971e9ee5632c064f1f5a9efdd362de13a24c5855eed3e60a85aaf4044fa3890cca4475229f57865bdb8efd2352e2a81e318526d9f98e7e63a718c768664a2e5c663cbd32a2ed879ae109e9504d2d52a2000406e7949f81ef69443328657388b7ec49e5090fc02a10bf627d649260cb16b07d12fc43d0dc98dfe2566448a24b8bbf6756a479cd6eee812b5e73acbbc5a27d36a6d93a55c482d7ceed60c235aa571b034cf7f25186d40dce618f0ab1750c931badbff552a185ae76855420c06915c0636110dce02f01fa5386ccb4447f191f0de830baa7b102e4809eb96f829eb08d49a26c4585268c55f36867c6f1b7511e7d619e3edd7af648d6927ba52baa900969c192c39c35c1f990b720a431fd1735d289aa0ff1d496c1a54c9b4848cd9e94624f37482ae5ab4112b4677f4bf60cf571cfe516cfeca0d570049a1ab69dd24747776c8795f3268402b7525a9220cd9da8f84fbbd7ae5900cdaf59179837b309941aba8f02e84842ddfb8dd913aa2cea4506181f974f5b15d58da8b0f4adfa2ac7fef26b85360be97cfd264ba05fbd8bd477d28d35260e0ebbdea56f4fc1113f93bd310bd39e4d40163ffd38c0295daea790495c7df10a407c18f20daf2de0f7f99f1e8e53d602fea0085b1e3819976ac25be7e1defca3922cc0b34d228a1063d1e27522ce851acaa267e3d0f248796f45580c6f9590b56bb1949ac71d6a85a8e8648bc614d60652eade239b782316c491c85108794c32f5b6a34702f2c4f93ac387dfffebe4f693569f1de98a8486d8257a5e2b751d67eb5622302bec445a5cb0bf57c85dbe9ca71b1c02aea0f7d10a8311b452046b82c132d13bebb1be793870dbbd98b15f262f1e69a2dba0f2e5681c3788d34e3557380ba9ae0855c41fb0f709d761911352828c58f7da2f11d0214153fb2c7634526e8953ddd5ef3063f5aa589a6ac77f3bbee3cb847de891e5caf99ba9f17de038740b87a4be02bb481f0b81fdfaab2e5a604f195ea3ae66b7c8b79b86f5d5f5e7121d68e20c307985ccd3da884404a4994d351662e5a42ec4f679a8a261f087b39aa9fd843b3ab39856cb1363307922020bb262aafd28c1a94e4657757f9b9dd89c2c719209bee2714c7bc8a87c5a9d0203c2204d6a67ceaf1977781d2c6b6c12eed87106ba5148c7c390da762d2b87663e6b739238819358680eb46377ed7c00f7b58a335693da4f7fa6529c6929f8e3bb48962a614aa2a4aa41019ea29500fd4de1475612b1afd741c164ed909cdc44dc3c4618300845a1b2d4956c05e43986f2206121057c64d431d7438ed54953fe48ea5d1d1f6c46c251c782c3f5534664871634fd4546240f2694ae4aa5c6a8708d6648ab41d5cee3202991a5a2a37c4a5116cf8ebc24270617cdcc2daaeca5a8d13d103233f3b9dfdfcab0dfe9e3bfcf81a3dd831dd42bcda96607fb5c81c0c45312287913a6c6dccf9f4690300aa8754e6538b92abfa8c4715c91a9516507cdf85b8632c741ff4d1c881ea9c6520d08e7f2dacfd956aa85244f7fb1744957382c9361214a975554bbe8179aa10b260ab4c6d03d0001acee4a165957b471af2facfd3a3fcff1cfc46505cc3ab5bcedd7b51fd0c7a839f9e61ea15005bf5d95f8df6c281804a3e8c38e5c65b8805f69cfde6c9a56672048f1b79452badb17aeadbf4283b235ef5351e0352f1e9ffe51d8d9b64c311316dd9f3f6dd3c739785aa556e41a3349a581b44277d50a0fbd444daf16ec74d2372345b2b6cbca38413ed9ecbd184ca59d8220981522e35e8f237ef4c3c8b4964be29f498e5d5d6776e6c497df22e98214997807b94e8dded2adc06ddbc5aaf4159dfc31a43baf78589c3015b83d1d485ccb6440a132392c213897e323a3eb55089c02cf6529e16b73109ac3a51f58964a8cc840f01a2a6e83922132ef0747b8dd1eeb16d291d45c4b4ed81841d59412c9c04ca4678a53da00066435944902f19135179606e875fcbbae1720753203d83deabb1b0681d2d4412549296ee1ebe5c129f11e984cbbfef951c044a41fe07ffcf40f3a809b165bcf287a2a1778f737d524440901fc8161d1256ec11929a4030600f0c7874ed19c89ded7d98247c259f42f363249324de1f76a3ab37be8ff90ff26f111c96d739bbb194d91c1eb790e4dd905119d547dd5906604ab67793a163ea08effed10bd00c73997c6237a0fcfb2cecf5bfd54233aadfee3ff7c5670e9ee450de5124a215ce7bdc3b73843eae0be0a59274d1244231c7208249276d9498a30804f342233582df8eba2167bbea065cb99918edd6912cf399d5a3c4874205338bcba219855db9e0cef92d769b333b0ebc9b11a092d97523a41d4075bfe6f5975de6efbe9d13f091861c8ead4ec05e6cffc53aaf3db1b2d77c2c0f7bc0c75f8b4af983fc1e8cf189761f4e287305992504f08c383c8d307fd282dcdc0656627481147006505e3bebdfcb4cfe7cf072079497987938100c99ac67bb01a6c3dcf59e313979653f758a5645c3eee1abd18be85101a23f281aed864a9e89fa14314dda41a020cfb6c4931cac6e1f42eff967476e65af2ce11055d99a892c3ab7f68142f12f15620d61d759c8b21fdfa581ab9d1d3191c4dcea894f0334e824b1e55e32c10ad2665da383da1f73c15be91a521ffe7cf1718505bf4a73ad15410f4e6002b93ffeba42f4a9e38fa84088ad05d60642cbb019614032444c3358b574e5fb992fadc5fdf2dc44715384816704c4a52b0d30b0a45b59709616dad1810b8afa76ef1e2d0dcd8e61239d145dd9b450f2aaeebc91c93e9d858c1841f6ae7a09fb4488e68a6f64cc091ba324d70517727fcd3c286bad44368dc75b0e764752de6b34cd346d7f961d872fdc35b40f60d194366f167e3525f0c10ddb3c382969928b3d1531b8886ad9277a0f47f45c4f7475cdb601e9a95e6e1d50bc03c4ed40aba49b99da42beebc95b136da496a765733157397015bd5fcf40fc2797844a9fc9d3db0fcdff6c6903fb718ec8a629743ce90c7a9a1c1f4873a895d5fd041c3b389c7f900ea950b3695a6b58b58243298089ca06d840c980d9497ba18220b4e9debe99b21d80f4fcdb6e4c674d4990af0e63660646b4755899cb2b072f75ce33200b2937c14ec7c5eef147de27f8d6ec37fe3d70055074696d69961e0f244b7cc9dc064ea8e8934b50664b0798fa33ca4d6d73a8557b3aefe28868b6c1f80e81668b34b3f8211df9a17ffe13808ce64fd236bf485bdf7067e5bcbac30e76c02b0cb880e126448122652014c272c5e307065af42079df81e91d011a91a103e09beb47c80f32e2bffd5444d1d3f2139b9d98840ad28bf9dd9d01e29b3f9f962bd595e2145fac2594164c8cc2d3cfd6246bbd4560c711393f30602273174d3a9144f56383039ef74c25e4b9d382d2e716038d65034a6d51a7a172eb415b1d92598809b61038e98c40a648de9ad069437721ddbd04529701e9c9d5aa10a032f78b9b7b9aabcc032ea747b33b4975f7fa8c7ad21c141f62857b0bebbf7f3cf7c20e3c3fbe89664b6c00f573be57457fb3ef20ac45b89ea5e8189a0a1b47b9bfdeda61e93a76074bc020af91515a908e802a8730bba4d9eceff903321937fb94b25c9a51444a874d51bf705bf48b04fe30bb76b4798d000e009c25395f359c89c10376e4c24f88c68e8ea17e31118da4d6c9e896f8b515004b3680691b40405881cb2b139e3d758279c64f11538b81f90b9ad169699054557df67ada0679944e8c8fff82ba449c2aa610f0eb06c6d4aa888576d0edfca21ceb3fe6fc8fc1d9a9b47882c0d5c8691673865f44e9ef7ea94b59308d3a14fa29b51d32bca6794f359112c9aa40728be172e3b5d1271cde2d4280aa53ab4654dd13dcdc794069353c338ab6aae6e219434109aee1425ab2a926d75b76141b00f48345d81bd017bde160368987d2b0accca2459724bb366a70a6a9b42dbb7b495790e2a1bc0f3b8f7dac4398066a872880057b5605e55fadce549587f63234faa85fabc4cf8c8573e427e83f017c7af7e8125e546e244d8601458a72350321383a764c63048068d12dfab02d66cd9f7b3d5972e5665e7b31cb4ecf8097a1eb9e84464ba1a54fc134a0ba57a26ff6b02834e9a4944cdfb892ad5f2eccb078368ccaf6ce098e80b6baca00bb493c1cee1db66213d353d241f08298fb69d3e1e5d8a0f217553320d3db38f307bc81a37f6090602a9a3bf9542ffb3c8f56a9f30d60edcab62c8302efedd13e7e1ec6851b44c60574455e5d3f6f7e9f5a2222fee6d3f9cb63c7e2b4329c3fb1d5db7e4fc7b8f3683f4afc63c8e50a0071f6f167cff9ce67fa99ac94c76c2c26a22c5fb3370af3d9b07954665f4c5f28e88130d4215c6fac62f0faec0e391880d3fff6bb25f62a8e47092d7c516b3fafbbd196672fd12c1ccde68673440b0dade7682d0522991d1af7c7621a93a815379ea928cae86944aa148f525b18e77a8343bc28f9fbd8b70ba0cc9bf817007e6aa07a01cf7b3194f884b5500ffe5dd263f66be7630f564252f16fd864bde741e84ab5b96dac16534f5ab94336e102504ea723e95806f2c512f2629dba530eea3ffa85922ec9090c4afa924186f955120efed3eeb44229ddce9f1741696508b5947a7c7d1a957da514771e1aa5e43ec51d2deaf512eca151855a8a6ebe306d851ebf1c0d455fa28177ad460939debc87dceb53140d87c946c42ef102b2c83bfb0c4a134fdd4f20e6866792a1d916df9844cd1d4f413fb32dd611149516c54ea51d9d0e42416851fb149cdc0b3492907f5279205c9398e8fd0633aba7960393a30a38cd16b54acc9cc8ef029b858d205a522a68aeb7f97da681a46bef2858ca08db35c476106bb78a9a445cc52abce8d99576c2d7bd96a0932cb375dc96f82d13b212e98fca8b31cc8191fff86fed1221f62a72c55af4fbf7914b119d7250976627149b453ad06473394501d2ed52c13f0d23d5e29d8bee2ca0105fa66e5f0c1941740915c98205946b6d4522f9f0d01cdb6c6bdb5d965d2d6c6e070905e6855c17a9cdbeeadd4966f358fc5fef49834871db6d7767a34dbe641b1993af18abb9bac6762651907020a84439762e78ed9c841470bde994e83c82045b649a9af136603988c560cf5e99e9b575eca745866aa6e1274811ae143db0d0514e6ffab73ef689afe204cc070462966209f7ad9319d6e35a00c0986e6161ec7c2648a2d1ede8ae54c5f987b41c95b554aa07e08b9e958b5b7126050d42162267e0239ed45faf945660e6a61dd9f7761367320179898c6a6284c15a23d0fdb447308391a4c7f4578495ec8f894bc1aedcae6def2e4fed6d710d8f9bb055cd3130bc2a0a3908d143421d133bfc27f429c5c9292024ba19f2eb15a5bb6fb4020c9cf6190abd08465c363dfb904a7cb8e88a728644a98985d2af60dcdeab9a762a2df23ff8056222c10a1900be4133ace8e3a87dfcdce7d252321f1013a51201957e01040465bfd2851fdbdad8909ff7161975d6f51bf2db2f44569b7bad86e157ce9fdf7a34c44007a2c392f2a1d4ff52bdb8b15d483b334468de676ef668217f0fbec528168203e25c0110f337d0a3ff86fa066b80f26b46225de8b051aa7b8fe0bfc3ea2640577da111605e3915e36135713e2d14cb3a821674c7bf1fe11a615fe7a2171d9f244f8f721d8876e698366a844299a02212369b33c68663b013de1d040c57ab14eb6b91e10cc41aef605befc16dee329c8a425d27ce3067648d9ed5679af6ff9d41a16f10c0c5f4602c84ca7fd00f6dd00ffa413bb4857668066da11fdaa05f879244a1f553ac1ed40ead6b29c174c2ef1d18b1a80e9be2e57f6c24f9715341d7b1b393ca04f6b4886369663aa6448da131be86889455072497eaa5e05a3756477ab94aed2e02076a71b36310b60062bc9aee66c8f675720c601161b6258d2603006c51b3ab643233c9a6e663003611b3a368323748c666c72056312663b08a1522370a2b775b1b199bda4f97e0048c04abdf02e420f9e2284bf2c34360c597c998f8c157b9d267a478092f43e203479eac2f9e44aad7745ff3168cc08a2f8333f0872b62a5c748f012148d3a6f8172720108d542e2ca10014ed2aa6f417288fcaa18059fc203666cba93e52b020ea4d97209e9a73513c7b8c6ccdc61145b9c5e4650e3960bc061823bf9110cd030fbf2048f7cc4883e2fbaa884dff20af2cce15e6ee4ea2517e255dd614d295949f203e406aa744dd21e961998d228554fbaea006ae37615acfdb635955dad82b8b08c37aee8e028174c5764a7be0ba1206ee2742ddfbfa7e0b95c0b21fd46a298af67edfa2b81b47affa3af7f8d1f71f8ddb38df2da3da3fa13f76cca6ecf0622da9e4da184f66cd065cf269849247b366209f56cd0e2e47dc91fd7703ffecf84fcd925b2567ced1030d6ab5a961034c61022982c5380c22402e16fb904cbcbb1b1fc5b05575561f4a1ac3f742017ae876ba2131c31adfefe4cb76aa4c3eed3ad1d45d01f86929c6ae7795aecc0087c6ab9bbe3398306f1d7bc375c7d924efb23e9507e67afd5cc5d649c02ba4ff673820561d171a72300b4254f246839dadf104670308788a9bd8ecb42a01a0b4b5e56b5c56224d03fe0d577ee0fe8d0d70cd4c174b07e9c9022d80f0a0df5e4276e6f49f121413ff18e7840b130034495f213f74709df59c537cf1d1834d4ce4fb9bf25cb879bf1fb50cc2d4340c94c1065bc93bdd01fc5962b68cac54ad6112b8bed36470d046473245de0b6f1207c674784b33be9242470b13d65e82a5c9ce02a8eb4269af213d191761efc3443fa522f80c6783831875987e570c1d28ce9bdd683bfbf951014f8cd416a08e424f2d734ffafca39431803779b7bf2ae12c33082dc3c7be315a582660cb97bf6c43b4a047f8c1fb1927c1feb9f5983c0aa6fe79035c5bc9d1a3d684e19763e5845c7f11a99ab5a49e9d98cd42d5ef86fb30a2c641df2c23ce685e3c28ce2bf21a995251a5277cf84c13dbc9c0eed42c6a2a5fe48dbec4a21cab58928d38ea82c56ebc9fe38aaaecd8aee15143aad5e91fa35dd0ce86cdf6da9992f50a13605019972b27ba39dda03cb3fca3f08cfaefc67c116dd594d595a4fe00d03ebb9ea2f5932ef738c9b24c1b2344724cd5442c7613fde40dbf1d3e9a1a526417b77d27530a026c25d7269f4a0932621bd3969db8135b7d18282990aecd749d7c0c39b0a36c7a4d1c1499a84b5e1a4d3e2c99ace0d4b9529b44f275d07036a22dc2597460f3a6912d29b53d36014601aea6b8b1579b6ef87770294daedbd5f8cc164cef6c8d21469d6a9b994fe553d1d72e5d5bd0a72111f1cf4d39b5ea550ace3df45d4db7c53fdb308f9af601e0be8e31af2ad80fdabd0df0ae6b784fd9d29c8a1d9090a375d33b8d3b345ccaf408e6a4828d4b899608fd3986b02ef7c9321aacf96b0305459f62ae6b6f8099c82338f7a3c0623cd90c8f439976efe817bd87c30cc80256056795ec975b3e8d04838365e9ac2764c6d4f505e68506ba9170dd8e9464c7dbd58fac67842edcafac7c17c913f0e22c806c07506afdd76ef9ebee0aa52372427698c1e790589a43ba7a3bf2b7a8a3ea3b7216d842849470e017acb036443c4213d4df652323f84fa2654bf9b59d99fabba88995d78fea0e232440798704b1d9f05481be5e3978b320ff6ca46fe46e06ce1f825e83ccadfc584f4ad079ffef4118f63be8be5f0d70f447fffdafb8b32f62f67e67fbae10064bf29c02623027e832f605cf58019b912a830b040762c037baf39f0f1e963ffc34c1330e39377450bc4d96e12715c78b7e08038db5622ce0fcf080c0873d304caf8f01ec10070369d440c97de251800cca64b98fa8fcba5a8d80ac08adfba57cc65cb62d6c416d583b9c8dd606c316e3822dfd7adea45ce4d4b562562053148d3b993696a4d3cdd06789ce53c5951d38d4d9067cc92f55b702608c2f968162c24de9fccf32bb4fe4995abfea5d567c28f51aafed79dbf5dd0e5254cebb22e74c50a89122b30ec802811d60ea5570a36a994088e7593ab88803afe464512af4ae174d4f540ac0c2eb4d764d35468066cd1c58599814c913c6f802a639c26516aa9ac28a77f51d8af4aadecfa933c9d4341a5967e9e48918d2835c1f64a7f7f7cdfa0c105ed65fdf1ff469b7560d960e42ac4feec8ba157db3462d69600855f6abc16df6a867e1b7cd5851f0419adc3514118e6951925313ea119e1842a2d5935ce9b9697de194777a0c5b64ec0154d0ff0227c530a54f7abd1d9da68a5bd4fad280aa3d3097941abfefa60f68283e9837cf87662cc28860b573fff8c65d140953dffce97a830c628b2190863a41202878462aa963d685bcee1c28a0a689b8a100ae42d573fe5bc948d7fc6ecd818569529ad4c873bdef0cef2b0af0604be7d0447f8fd323266807529663612bcfa0304df7616ee508df39c2b214853aa6aa4a11ed50163c6f099f1b27cfc831da7cc79330415d4d673660915c1c51074864f53fdd75dcc5fd3e7cd8b15f516610013c8534122da423b532d1a8fd835810c9fb830c172dac0be331368e99ac0837f88a83b5d9dd188eb2158771315e2ec338cf852dc278cfa7ec2b417290dc503abd2f49be808a21a29bb96b386109b392def40d819c0eac4e6fa788d81fab86ac7020e39c0a35899295cceb34d63c28de36d6c68417b0421f780a34dce316486a765e5c7ac59c66be80e1aa842d8d5889951fe8c04aad49cb3c5953e26aa84538b0caafcd4d28c7e08b28f63365e495a59a5c952352e53a8bfc643f78bc1263b1e8345e52cc399f74ecc848009d1cb4cd0620197369ddc93b505e88586d9cb240439f8a2c7630069bc631facd020f4c1d5ca1ddf2ae9760c808d4b1c005d677696e29c0654accf4f9404c3a492059cb3181db99962540ccb76993e3f77f50ba6cf9de8144c0d194c7b8705f72b5dfe74a0ecb6b5429dcbe9bc66b0518da74f752a053105b22de0c370e16b7ccc3ab2af9e04829694a57aa073747f6b0a597546cd5d8e2dc5e0ed3d22977c581615ee8e14118783a6488763a5b43fc0e86eef2bf10d4660914589c87df83ef42703d06759fc8c21e17b7a593cda07c5460ceec67118a69194b9c944393392184e30e099333120940b4ff14013829d96dff62f2eacf0e385d1365616e782b2e75b086c7d8f7e4d9decfd0ea5b35bf3ec973ebc1fa3711df84d7abb3122cb97742e631a67e4c752e54d100e31055bd239f4d1af506679d51c32d258bd02e7e76b5231414448f28f1de0d5172472c193bd7f96ea259f4e1ec9b0ad6b231eaa3524646a84c3aa50edc34fbefa81128c28cc42068e6d0f0367c0eff9eca5e6fac974c25ce365ce6b8a01653f78f296edf49b8b53e9be44872949dedc33c0c885a7a43a28f753ee4af8eadb436c35db96b1dcb0be8e05a6d9e84de0a23ef09983c00a02c617c0cb38339b5246050abf1220f30eca170c43bcbcd403dd62bb241cac211de32f82f67a95ef1580baf4715f84001b04c413acb3d1611801ebdd1abe27817c05542d9cc029d484ef983300e66db13f4030a6c9433d0a9c6dadf0dff697621984f78476d94374ade8c5d3733631e32709f815a869aa18135ed229d7f942ea8b35bf3d4e62ae6342a7441ed00390718a07a1624bd70cf611352f6597caf0d24d79c8b7af736d09e9b4007aa01b39081cd9addfd159d266bc311cd20c0dff387470e5962c6c08d15ff675d22d30fe2e0940d9d029ba3258606beef839b43ac56f3abf7f26bd1268b1691c6e112ee1adc4fd24287491d34e10835eda5ab3a150aa88c9ba46b6f03e7bbab40d0b9837b6039c0299871b1668f7ecb216928d1c8fb58b5157a5abf1e666a5cc0240e58f8440fd721a0fe84fef23ffa198f5bd96df671d1d73d181241a3c737199989fa27d39f44ade63f074af0d0b4001f26e96264f9f644e60357906ef8cb3b3f277de87d1ced45eed37e3cf974dc95c459c4beab140ebe40c0fbed70cf0c74dcd422a9307aad969898e598026a18925dcc8bc50ed76b4b0969b698805906026dbe4dabf8b166d5e0eb6379ddafc3b909b5f1d42ff45e57e07702dbbbd2d698409551786b4f88546165fe35fce15e31401eb042670563d5c98435ca6de4af15649bfa9c5618e8a83b43877e747966616e549a01cd254f6a2644ee9fbec7ff5ddc4ed3b248de5b95ed1b4103a0bf0eceb6eb2a25b261f8a1869d678a499c02a769e93111b28a5952665e8a43e66a3e5ab4fe104c60738a4a82a501a4668de224497e032a3ff215608898188aba207ce2c075221ab19c0ade6eb48d01b66a11d418ce3493fe6e2c9282b55e621d1f63a7718a16932a2e320b0b194ba693f5ad1fc9ba8952a42c20d78c0658e311056ff83716df7113bd0fb7c5b0ba786c66c793609dadf916013f68a254cd37cb6b6deedc5c6d3a37528195e1335810d38ed018bd2347176f89deb081c1678421d692e211959f4c388f8aef8c9157e851040c259b4efc9350f134b6913885540cb2c71dfaa2b108e5b018eeeaf07fc201b9f5f931ca2df3abf3507c84bcf8a46aae8708ee0111499b5c0324f00c296fd04fd018e17b4e53aa509a4b1afc00bdebc3884472d38a47f6fe7a379e104ebec5b4d56995f052e40501da7383c3c5dfe016d299a31e2f3a3d8d3b6858e0cae4db653c80002f92ec9d016bad8693f4eb4ca65b4e934bb3f2af00ddfb131f8d62d2a318d2ee900a19a1b8a9a97e336a1c410f0d84e124b010b73fcdbfc8649026e0321818bcb846e7d149751a0400b64ee6b40f98d08628b589735ac0846f1e98c0ed03b09acb279ae90c8a9f3fbe62e611b0c5319ce0b82dacbea52cc150b2dd30627063be68a6c22b79c2b1f85e818729ab082a0cb282f79134faeff849fcb3fea4c47f73fd187d47de5a841a0b4e4a50070608e3c41f8c2b8574f5623508dc2ddbe69d925a26758839ab8fcc0f70c2cff037df726886f9ec1d55818169e78b85add592b17a04cbec92fe2b502b54de563bbffc0977c9354003fee2a6aff4d61535d89cd2e3af2c56ba34dc3cf4a020c2a9a74811090967ac321b04d2d23ac182cc722826c0e56d1d84016c70b0fc42caa31c4a92ccc73206c422caf199d01939c08e23c3bc718b901ffafa2c16aac490dde1f11e0017082121cc8bea71d89b49b200f9360c409b406429d5c79c3a9633ba6175975d4be31e608dc1c5ea2dc33d11870b9cc02c151976a2f4431e36c6edc610e04bd92454d80287f4b89a0cb5d43144356d1bc953607f8e49bcb3da87f3ecc7c1586424501dad677a7b9829f05db23e0b1c43e9d1ef9661510f0f38e7a2c145fe55320a6be6d83927a8a4dbb555246851925f42d5fbbf96e63d6440e8a04b1f5b08931b5526029799f01c4df4d62b1d73949009e69e4dcbed5c25361cb0efa2b95d94e31c1369941dcd8172e8a3781e3d0d5b0823053405113a5b1856e6a74eb5bd8b750f5c580a3f33370670fa72ba32f825f83941b1bb73400a9f749a2e64ee9b20428deae112bba3e46f27f9c00697da61f72083e4bdb49629944fe9826fdde9220a6704b81f854ace104a6deac5d0fa4892da2b7b4421b6ef570a97797f341bab22b1621cea854cafd3ac2b11bf7365ea4fb73feb7c32706174a537c42de8f24fe4ebfd47d58765d48552126218575da0228a645b04ef7170207ff8645805d3daac59f04966d738c0039c0fdc5ba948d3223b9b5ceb52f8339b3ca8af154d28d442ef08b61541a39433db6852812ef975498928b1fb424ce5bb13b5c97116dd6adcc5fd7c79104a9bf2ade277b2d0661a36ef5c53e3e6425ff797daee12be9e94cd4f574df1801a6df279ae67255424343752fb64efac9912038662f3c420bad866420f74d3ab278639cb4525cfb208b7a41170a0cc4c4276c4d71478bdde0bbe107dba8c572bf254b79082effa731d1f23a8b7331c7f6f88332ee7cd5dce159d6da216293c3b6a6ee685a336b4838f4508361b87526e1389ffb3d097bfae38e2c7da34454e8dd5b9963c41fb173ae54d220c077459699e958fafeaf372740bf799e566fd0767ffa0b1f4ca85005f6025aa0e78426f39e8d7547f737186de4611c3b0618ab5c15c2cb82a90831e3529f2db602caf422491dd354e93378c492428a42f1b1ab013d27beb6dab2c4e8ad6c7dd6c87311d74fbb429a0304ce2603e7b6ee95fa4e8831d609e6baaf0b1d7d54a0aaa1fb4ac058e4742d380d0c11926f59756fc765bb263f6375174143613b7ddf134562967e0f2be7f6cdf87c4f24863eec78a63098bd4b9f7fb78e51947001bb2d2224013c8b1730ab292bd2e6107b2b0f65045e09e5c9f093e57b7c64c02f0d2b6014fc95452ea171283468e660b742d19212b064023fc5a863d6ff70d992589f904ae2f5c26b0ef53e2bef60f006079e9d6fe54bfd8e0cf7cba2808aa56a8a7b1ba90a3d6a15ae94106c4c72577e79b64e0c1f7261f790ecfbbf93c6a7f5f1b7e266bc7892426b6309293df3cd032509c19efda8938ac145f24aea74a308ea46010e04f131cc9e79e90cd1207e2446c5fa9223b5d6a4e3f124210229bc2027f605d2526da257899c7f0028b164bd277936e8a5da47c383c53f58c820c6e370e99f4d94a1fdd5f705ac738225cbe4e1d80cd5ea5cb01ad2a9e34027c88b49b79fd20552f5ebd1578c0c5ce58cccab82220c2cb4800a7952f6d2a607720332b9215d5871e5dafe37e87218e27937367e1957f33d8e5945487cb824a36143e4a610e0d479864b8e14feee1508eacca246a35440f91919c502d1ed66c04581a00f4d090993dea490c6990bc03991112576d3e69ae59a470a684cb515c29f4138ad6e48e60f16ef2e0202ae6b3052c8841e405e7bda377792f480f70b0ab524887596e69d138bb65f560389c1abb8a6daa66bcab169f3995d5da440346f070cb5c86599df77d38f4092b8d913253ac1bff60858124b2330ca7e97ab4d352aa01260dbcd629dce0619a7100963ddd69891ec500c226af86af7970d87755dbb7c945e0980f1c185295d69284b4345f8780f21f32971cc67e95cbde4de7c3345b8b415d6ee688730c9fa5af36df6e4cbbb45bf41a6e39d37e29b45dc5fb4480a211d5051ef8ecac88cbeedd90af8b824e61e5064ff9b119630d02948b1ae0b46d36ebffbf42eb98b0c14fdbfc6cc178dc42dba674282127a3aaa084d9a7aeee4057b3ec21768683721704d3fd9e3233f633ceee57c70fa38a1078fd49135d7a876f81ba21f158dabe8e9876ad4ccaa592e790a3a9c2dd9a53db963bbc8f0ecfe01d4ee4cbb4a04c2a508782394d0cd14308ac51a39c2bbcde26d820cfa4d096342402c609dd47259fa742f22b247ab42090f252a3cd42e3c144b3a94ea87d791708719628ba968ae66d80ce5843f0461d338c0f63453b3214c818e254da0610f838f251f00830151e6103c29901670c2aaba2b42655b8cfab15a84a3d5ae7da1550261aa08b38aef7bcced5bcb613a04ba45108d2f4d1bb456c5d727f8425745bb0fceef84df90dd740bdd97b0dfa0530f912d95e2ed6645c5251f09cd678eb7c5cc78dbb151d493a106d141aaec5ac213251b2134f1dc87a532e0caec971e97fe240c4281fbdb5cef5cd1a6923c9effcb92ae930c027c249c93a1459625d5fcd13769490969dfba9b1e48e847552b401838e7d4395223ce5070011d080177c0e063d61a69d676d7b2e0a875e745c10e8a478a6e9ef5f7ad1734f30ba2b7fc6d7ef5eef4b80bf8d866445722098aad44ff5e3b0ccff37c0d70bd9d0a6e838ec5009fc274427db9c0eca5387fc32db07a89a4d37f04f8f485c383c817d1dbf14892b515d3f75a2deba061663ce53a4b0412ba87fff943c58e9848889c700fc2f620bf073ea7d57b0da719281a7cdaa2035e9a30fc56cbb67d79c903248d575b485763da93ee74e0179bb7fd7abf77da4d0e5b077af65da4d0ffb0136650329ddc81cbee33b435d759d9f7896875bc4bcae42242b3ff1c1649f6ac981eb7b251da1bd9b48f2619ecf8451db49cf30a7a088cff526470fcaf7bc3fc5a09e41bf1bec821ea9bdbd8532b29d4e0f9f125923b6d7e03e5351a15fbea85ed1918dba0dfccdd0e0fa9c7a31ccdf2885d304990a151e46fd202ce1df686591444f349a0c2a37a44b90ca12489c5eb3242d9273f4ee473d4ae964908e64d799029fe02e6168b9a8c83c824cdef6efb2ab413ed2de23da66620d0bccea8df0b77b8e1f41188c047eb00e4ccefe1dd0ac5f19093e7c67506367fd265fad3400bb0c26487b78f018b93e68dd4dd7013b6cb7ee983a89c5b9bd67f1610b0ef8cd7377dd178a630e37d26de82b1754c1667bb2dd4d53cbe23b9cd6bc618d258574f6a07026975996c75d448c58822ce8cac433e53fa04cde175482c6181eff27d9162531eed4f8d38214211404c27ea1b4125c3b2e6d19f29890d2a4e22ef9fb84c1ef4d43d752cd678d8a9fd6def1bd6f899f5222996c1ceaff69b1a114e2a8cc454007e431f027f5110e93da72e37a1ad2b3e0b818a1d067c5414b48db20f31898ddca3ac23967700f988db84529449e89ddd74c8052b1c01e047b24d247326c755bfe046e90eba98d602defce584a06d654f157f8b364b152d7be01f0565ec100633c13338cf0595f00ff8d0dc4a9054a1f0c9ecdd9d7d0cc604bff3d0c3a4a62a925bb3864254f4a6dc86d65b4a42952e40ab4c1a19cd6a7adbd24a10f363444e369bdd7cc905e2eecc0a1bb38f4b919217be2c10f96801094fa5ba8df548cb69ebd17d14118e4bd949f732dc8380949cd8f839534f059cad1970639e53f17dca5e7bab169f7c76c5b8088fd9827f989fb0a07a54f881fef5f7a8b1a50440ae592710ad959a3a18ec860e0a5ad56c01debc2c8b991507e8967c15719a70771ddc904dafa020b1e3a60175e2b6599bfc76a9f81c2809e0d38e7a357d4cec66a70a4089f2fce8d79b8f1c23f623d04f1d08d06afb4624c6eb053ed49a2057f572931846312b05c6f161408d2a14c53eb6d0454e5be522f5699a20f096cb1641a7f943e9e66272f527b2ce3b9a3b0a0bcddf7ecbfbf278b071dc35e60b8bf0bdd10b3a26fb7c0302077e0790dd8da377cbb308763444db27ae4aae2fd93b8a0b7219c9d6ac36e5c3d3be6e2799407cfcfc281dc3bf4c05b69c66dc372b78239fdef6eb3ecb41f463a3979081bc85c6130e13935e8692a0670514f8ee5b882750adc9e1bb265259237c79edaaf38428b90e1fc7c93517745b6ac6378f7ddd9e2681f91d5190bac0b8a4c6cf669ce22a716727561b005083e583d6923feba4260f68a368a6bab46f087bb71d4fe94d091e29927bf41af2993f6481263f00834274979e99263ef3abc850d3e59f5e9262f3facdb5ac65038aaa5178ac2cbed16ace67fc922d5bc645a569a1703fecd05332e69d29d7652b9b9a1808a3568fd41a913121ba7ff6b0db9341fbe2341f24627276920e14a92e732152e2f0204dce735ac9d860045d34c8aef7ea035aa290baa6a5f31ec2c684a4c1839a7d65a28e1dd73d48fc8d4bca593c0a45273b9ce2563936359d753754e575ca0adbf54be84f8ad7e47191f1363f263cbd0354805a174f1b647132ce024fe386b810ca825f7f8bcf11d0df391b8067847c3b2a003ce9f707a1ea4be1bbfd18400c9d97823d5c92d0cd1b6dab7f866a64ab69aeb37e1c1422ca4de6f14a65570c2c55d099eaa98ca944a17bda2b8b8c03efaae1a387f9adbe5052378f50ed4984ab0d376279246bc58bd6566551789a95818537fa51f8f6b4d70056888cb3a28605a8975ca2f441bd1e9e2c91416b282110c8015ae6e279a87f81b0673f3190d1638c1ade80ca56484db20c24084f33f114c40d86d9094b72b55e73235dd146a1009377aa80620dedb054a9240e9e2066b1b769cf4870abbeb1ad0ed2a7e220a0a046dd1fc00bd5afac2412c4f656250aa1e38b8a4a616d6a64176d327521b822309d98436bec26b0d8783dab821956d18989450e55b192955e5962da25ab1c24ad565476a14719ac1b53fc28c6ed264d2c2b6d44ccf5a154ae8af2221188a74c49a572cd44c020a48b8dc31906182ebaf43f03c78685c4240cc54a3569deff10db738ab343ecfb530cbc1706c9c3352dfc5cd932245a751e7b2ebbc7ccd50389097eece34846eebfd5b375e190321d0e031eab9642062a5348cf762234480adde8262cc40d7dac4b8926353b43f20721fd4cc07c6b0c3281cb6ea1ad60df95250145a12a804494a0a59fe6be5c47149b8a120105c5c941c83970308c3a6463923e66ade18ded87d6453c78332ef2e644079d2eea8a2a05d14733748a0a60c62aef19b68e05a3e32075b2b54c28637ad25e8dacd8114011a3260486dfd99cc8ab6a6a20adf343eb52f4291f4e5772264fa006134615465caaed9da3eb3e7c6d3a79cfb0341393cecd2f3864c6ec985d95c41e83b6fd4f1e907d3d405b8e55a8db97e881fcacd9312f1f92b095d556f1783542e01407e562066ae9ac64fb74e6f0e059b74c2a3052d2731c79bad49a1cc3027eb5ab7997f2e75890159f6c39ba4a2d7effeac314f97718bc008591eb8672f0581faf1b95eaa108b334455d91b6840f9a8c82bfa3d958b429c115a8aaa5d6b383b0fb9b777c435875387a35b0ba0fa3de854a59ff19618f166783a9bc1b9c155a0744d876c0d68d0da4db70f86a81865d3422e353a0d31eeed56b8351b91c80fbfa123d4e80de4b4e04aac7e9705546f8c1e9516b2c8fd8cc5c55ae5e358315642e69f49d8107b1ee32507ff6f556c040453dfe1b95b62e9dba3a6e745e77e4ed51a95a32e82b3a3567a6554747d3cc12f0db4c33cbb8a034102033a890a614a326ab62773719404e4280988272241ea99e7a23bae9224900f56eabbd82188e2ce0d4dae4a0eac39e763e7f7bed82a0d8fb698a686771e06c85117ea2eb7b35c47fc403f065bb2de78ec387252fecf1a8577563a8b2f05e805c82f29a8de4df2acbe24e0757162be93bf3aa107bcc3a12b4658aec9cfe7edff5cd7665611a83a43926e3d991cb99a5b862c367abcab16b5dd5ef06c8fe0afd85e3d5531cf3835fc5f7d5010f973af19631fb2df43254a2d11f45a007d3a6502f4b1fbed2883effb5d46f4af4c07b57d4b0b6fb037405452fb7953d2ebf41f5bec02a104ba88b3050ea7f57be1c77e14f7f4c433d3445cf9d09cb1ad687ad60474d03952fc16c8c438c9678ff32b8feb9c51e03c92c5a4be35dca94e48ca46c3ce2411dc00ef8579e175222f7807bd0fdc7f159bb74516497e60886e31ecfe085d42d3ce010c3506b6547fae9d356decb04c0eb6c06f954b1ba57bcdf19b09f0c8077b16721a8c9bf92f63121b8d5d0ffc5d2ef15fc3ab05d414fe6850251c61d60b83998233cfef9b946c95a12f12f2f117f13dfd5b97262b73b6c979ad87a51f45e1c879695ef68c89a4188107e9dc34e49c77ad8e41eec678a7fb301e2f1ae8980a41f3860dcce37745b8a462bb274c1bc5b82d76983e51e69c5db29afe9227fa0efe50a3bee5ab60dd405f3c1b9b3c5d11e7b5fce3e34c1b0fd176ea3b49127e440adde4bd21d0a807e674d91bc57fec2b4f6408ff66932ac55c96e8e8f1aef9f1a0596121b0ba43672012646a6614d0f63f3195638ad1b30180be7bef05a4feabcd4b1ea577c079e2f32c3e9e3bfbf061c44528b36aa6501229426274c8a239d817ced470217663c35b1cf98db45f197fd878c1ac307bcf196bbf64bf9c79761095f9fe31674fcd12d09cfc9d96027e15ee165bd3f3a8d3648305b29b653e2c4809c71a6f33137d101d224ec36884791f5d09fae241a0e66ecbf5f5f71697adfd6d6862e0a6da7c03ed65f2caf0dfd2cac002556f17e4d084a30a63f9b930062bb87ce39c9d8a6de7a32fd29219accd81fc4ec102789f69b3bfb95a480266cef2c117d7e7bc20e3283cd2d324541801ec61ba702a14f0a5687e12b4ef34cb92545d3054be84a5b63d4a3516b57c3244b94b8c055646e2538c78ad3fa0dbe15f16e73aec914424335cd50991c90f0fb36bb76803a2c0ad0102ca68883b64dcd091247fa0545c46ac7d732ca2e1ffd25b61baaa9153bda2ac8bdd675f149d63ccd0fd52db149a7e2b7bb205854622c63d48e9dc2f655e8e2667d0726d6c075f7c8fa4e067603750b4d9343d3b7f56d22e8b93d33576179c7d23baabeb26be0d1321d5d59b29addddec721ec15204922e5081d5c650cbe0f7eec3b35a81996c43eba005469f022f260e3d95950206475580d186034608839be8ac79a52067e42b27d3354f4b954b838bdefaa00881a942f817dd4fdf9c9b8a3907476540e07c4201ec93f2c8b8dc83ca144ea1de97a73193469618881c277b06ff938f71156eb656bdc856845ef97c6883cc97a50a995b3f971c1b48040b559793be7dae4c713edacaf97cf8bf832422ae1a0711164089a397c709809fd77d0868bb26708bf57cac2e7c87d9eb13f8033a7a8fa4158e489fcf2c21c409d84fbabfadacd94220145645b4a7b86f0899dc907e25d0cb05e8289e18cbadd49f1eac9cfa689fd233b01c7091c7c6d42ca7ac8a9878c127d0fc561a533a2176145570dcb5f4d0ae38e48801b922829ed84689020b1699bb764fade413dcc6f82804e1903554fbe8692efaade226116d317d6b05710b2cc557e08b8b0326338721f1c34cc3aa474fe35a7be9755c14aeaf08423262437ba1017c07a692afbce4eb30f528b8ebdc0802a1098485ade4826f84e07c44c38d58924a4287ad9806558f1eeda7b3078e44006063e84977e954bfa7efd5b8cdce4370a738c82b0eb9ba18b488bfeb559ac4e9366d6f93844d36d67b328f44631c628b87a657cdb5e3d670d3be741b570d37fd4b5f3bf4685c152fbdc68dc2b5e4523bf434dcb59f2eeda1a73fe9172e0000b206ea179d865bcfa57ae8d33cfa4deecaa34be3de72dfb815dc742e4b2e8d9b866bc9b5e05670d3bef41b67000079433b578d8bc67dc95539e8685c752f9dc295c2bde4be7029b8e8dcaa12b9ed45120297a82950d9081f4f1a40a74b049de161d8593fa70fa56ec82bdea3f10d4f1b0992412e4f4f0a97110750062ca02f66f114a74f056495906ae048b0b1593cbcd318dfa404c91c726790aba283ed3853d92a9db34ba9841a43c01399e25b84a92ad5e6d8ab2c73d9f366ce65d988986c3bbd65aa95a99a6a63b8269877593d95f3530141056429a2123e053c14f9ea3ec24ecd4ee735f5acfaad9c3b9305bdfa23a4f45d9cce53f8f32344c7520842bc646af86eaeb33212fd780c9bea73056254ce31dc9753571dc2e3d9bd016604935f1eb6b8f330e59a952159ca24566daa0ea98ca0c02662bacde98aaa0d928e3addb6a76a3a01bacee90d32b880cc5fa52537151b86c601fc60130ffff5f1d12f8ebb20dfc7cdbf8203eb500c6bdb571751f691b6a109351f29019bed5e817bd7b9ff77d7ea9c2d6b5c9030da28d9d076003e4bd97eaf5324d2c3c851d05039027ca2133aa26b40a175ef19c378bbc12491d69e9b644c212f61d1640dfc71bb6a88a89c14c1b925498b305b4cb876c9007a92e55e26cc7a43bfd1df88b310b9f682b97991812346ce34aaf75618a234c061b14011a9bb301703e3c765d46a23b55dbf049baa77829a17be1efb3add627265345fae5c69168a3ce896a5600495f5bfab24bba97b830f0f5f4f5c6d81de053316530c7b56409a8debc7be7bbcdd387007d2d8630a724b085ba608d2c9f910827ec815fbd80af927849434093daaad148e5e2e01955d2e6070a8584c37dceaf96fd4794cf633b82cb39200780b12160b511cc04c351d3fa8531c21e64b92e46a3216c8133edc10a1948236fdb3046f0f73123518bb08e0959423dd1fc75eecd066b0a82b609bb60ae1773a1a4797596caa21042ffdd819097705c0f16e8e6c756e121b3d1638935621554fe0cd632b41b5fac1d840b1319589e955adbb698904e6ab2b615ad52758621d18209a24b7727b93f939afe45f5919778437186e340c5da06938a0eb85e8c2a1ea3c8304be98fc15c06d9b54acbf91122e75cba91aa0041932e89cf935eea4e47d1231332bbbdb4922c5448faef0f555883e0b14a46ec819649c98d79ca94d02006ecdedab7a2789c64503c0467806ca3e3ccee3cd8439a3d8fbd308681f3985f579d28ebfd7c27576a51705ec9837439e2ab95ec74a240c94c26cc0b8a498ec92ff24b5a2a322275bcaad608b7ce57202c1dfa70664ead6b64e76fd36adf7b7fb638d92b6015cf3bcbb46d8a6e88a0747a7d7a62fc322d94871eb73856cbc1f281464381c9dc0f5ccb119705f3d46e56a4b01730808c5fe6f354418a257f1b9a051acb720aaea2f8320e3650dc6e32a95df897587977c5dcbb72614a9cdfc590516405a37dce6d0ae9735c1ba8bf019b134607ad9a1309b393af52547559b7b33b55bcb14cac04a1111c37492019ed343335c12311b1ed3a95529780bab5856a0d48882432594d0b4e1221812eded7781b41298a13df45934702005c7041149f5de4acf451dda2d2b793fc008ec1e6d55839f1e02fc560a5b5ec621d01d0df35fbca8295a078e1408f89d7d2786faaeb829987921c8b22da2d88e5a73a90edb77872e3a45539d9de881c7a46b7ccea4393df00f0fff861569de4f020ae043b2252e27fdf50be392e4205d9de132a2003f64a4d8ac791d39ca87d9b536b3c530b479a27c72d1c5b48b985f905b4f1583d70e3d0aae3515451fef4fae9dac19bad1702d45210b13460f052c328c06db2b6cbe2c52e320c232063cbc1711da13ad264e3a154fecf77b8db2bea57cde2dd6cdb1c377d29c7f6243cb001556592f039ac90214f34071d123121c91a4703fdb7366a5773f69e1ef4fa2eea443abaf95f1e000248e2c18d3c5e070ebafe402ca3bdfbd0079afc689d46cf295781f508232c8550ca82197becd371a9792dbf0f4267f6b8fb6f433d439d3ba1dcc27a924d909a0e1ee59b1ca9ed8ba804202dafbaac3425baabe121e1203be7891ed61a5510cdc493694cf599de55cf608830755d45c8c2066c9a666bb34cb333b0c2b497fe868e1ce971efb2bf61d25e81dfa35b7fc9b98308ec81d2b4e96d9451f0227f215aeef1aedb212dbb625d098b9078579073a076bb1b940328cd012671591d8595e5e239e5b6f2f4fc107dd026cbdedfadece4c005a2913001004e7f600f26937825055883e993e8002d25b44f41bd7c7f19b78ac6b341dfc89848770c027d1018849171e2548a6dc2c6b7a8541fbe2f29e418563a51846da611ea81391bcf951fee932b877417470d5b82774225e9c9eccb3708a40f373b679d3e96a46bf5805805d040f15a9285894bc4b53008abf6ed339d94341e17ef71f1905f37c359cbd8cee4872692f849e02fcb426eb2384a89df09c61048158d94d5ea3e738818b15e4fcde2c5189123051ba41a240d22addc510d6777abfd3b212e7d89db14e203cfff6da4b6c850f49086c7b777d6bb81091e40b2012f4b87575ab46c2be6c0960a6e38d17ce3707f7f900a1d7dc4f644d8a563cedea2c434c3ee34c917c4ab8f4298d4f0a226294f25d0cb15a4dd407e99d1bb49744bf3392a20bf1f8a543efd4feff469fbdb1567ddf45ad4eefe4301c2c96cfd8de7126f87996af3f5383d1491406c4c04d135ca7aacf3bb65ec1f2d9e529b23c87dd11fb4bd16dea8a10bafd114d580df3e190761d41fe6cf3bc3e7002edb09041a21d10839c99484f5868f765e1d1a53e104a8714aa9d46ecf4a4376660091bc87b3ca8e670ff2c1d1ce0bcfb609940e0ea960939753654a66d7b4323a55687df8cfeb70117fc8479f8da82302b54ec8c668eca2884d7d8f6f384f1c822e111fab2131fac85f137876d5cfa454bc5ace7e9ceaac7a61238b4348b943f385c056993f4bdf710488923fa13ad00018ee16820ed41bd54c3189aab006dbcc20216b313f2a6362f9dad9c2c5e5a570fbf9bfa7da425f3c578dc368216c10041230759df20f7cb5595f553f4a939aafd5b6721b88b8e0aecbdc4753acbe08a82adb48477ee55b4f92d4a56a1290e67015ce9cd17ad9c6948267ca0fb5fee0e9e7a98f98403ccf2fad522ccac45726fc1e86a991070df5f52a797932df6c34ada50fc2c8c10b9184df3557f6488880524b3ca53761528a52b4f032d5dc6dac1d599bdc2425ee8cd2a5583b3788f88fcf46c681194ac4d69d013c868df3dd912bd2d7b4a4af0e9093f062941f4be094afb96b1a33301afe8f089222c8c833e498b803d8a5dc1c31755d8b20f04463462fb548d1eb49acea762a3372a841be6cdf21cb89cb6b7b6255942faa61b8dee05aaccf18f39bde3394567f04da411873ca257e8770a144aa92a6e66c30706fd6c6a29aa18408f32646580dfebf1312a81300e85df3ca41cc2b71b538df45103555e4cc6698f4e2aed9f54e163491aa9ef105fc5179371475a9a8d8cb5789ee12661f4036e36f57539c4ef27daf6a47059d17a98b3fa824b48a050e804ca43f58dfc51c53c04d01122a4ce748672f49032735dcc71f7378e021d1a46d9e39e1529af1ee5190aed3a7db0e2e2898f3466616222484e9c3eaf5d001bb0b2541a12508c58cfb81eb5dbec02aa2653376a93d4e8b8ef4db9f16de6260e74ba54daa138b5d707b77059ed62827fb2a87e363b25b26466f67b2356e30e002a2215a407a19caa669f902b14134a060c8639f9f59786f80a731bfe8f600100107120f87f1b7e9bd0a10ac3d573a0d18c5e860c452d27100625c7b5424b965ec60ecec8093d6a7e07aa0c3fdb7f6fa057645a34a26bfdd5cabb7379f386f6535c120cbf12efe1f9aa5e1eda7a4590cd88825d9a27676ad0fd82e56f9fafb661ee1e8b61653eb5a666df6ab4ec86b87a02dac0034e2a14213d62b3883c3751ed0543d8e5962cfbb275dd38be6d407bcaaeec75084165a179f30871694f4e89b72e03dacdfbd1d299e8bd3b404e718059c099e845e14053553c8d97fb0e8e40178ee84d37b087f030966ab2036db9fb85c374d2e9e2c4c2b42c4a8867c562f22c8fff8b5a19a035199316db065d4d694f7d15de7b3f740582552480078f7a7fdc4be13c8222baa44f9dda813a762148e26a697f1a65b109fc3a134db7888d7e0cd1c0683b78cf5361f7e94ef2ed634d71694b02ded477b7a95bc33e0c7485a0ad18a20a781ec3d6a9083235bbc36b915c76d888d6bc5cf08c1179906a29656e9be1485cc73a84c3ebe005f38f42f7da5a3875cf7add618bc535e2b02c03cc36ff752c6b0b5ebd2c909145dc50cf12537165118c990ec55b8d093498041a285b81534b531d2a11c86912911be37dc7e24076454bd06b97239bb5d38179347e0ff3532401459f66335971664a201e94843d98f8367904cdf4de3ed8e37a7fc15ab38dc919cc511a5bd1e3cb3bc79377315248817ce8cb5169a714c1eb8826fb4ba5af70732a8f8bab393ec496cfd2bc776f9919c777693e5ffa7c5e55db5f2071e729e1460d4239475ce7f340ba4e46ecb5c11038791e8284588f62b24d5d46dda1a8952a02e372191ffa422f771de7b805e0a0b31f2a7c126f794d68782cc1b3305de885a485f9a0d439a4d9167ccc8a0c353a3a30b97c6fc68c6d21ddb2e5902ed40abb1248aa25c9ee3320b31bfd497a0937f54c75acba0262ec3c23b4a61aeb93f93d6af2ab5f52a1fa3126884854ea034a5c7bad4e10280f291d85920aba78303c0639979b72664cc15bc1bfd671e18eb5f0fc5826b715462827920a21042200c388107011ea3b5be0abde5f6b7b56fdb0259d7a3366c46a37b265227bef2da54c4906fc09280c7a0a2dc026ef036a006ce23e7600f440aae514a5c59d32ea56ae6cbf2e21d27a9a2bad8f11804b515adc09c20d60fdeb69ac58b9e2fd95d6ffba952bdbb34f592556ae6cbf1069bf3445c8268c884e20c16acaec13666007948082893569a270428a27a680622b47217b9060240f7207f9e59bdbd0aed2cb377b8076953a7cf315b4abcce19bb1a05d65976f9ea25d25976fce8276955bbe590bda55e2f0cd5bd0aef2866f7643bb4aa96fe6827695367c7317b4abd4f2cd5ed0aeb2866f7e43bbcaa86ffe82769534bc9c41caf0cd7002f9663100f9e631fc7c33197f7c739c107c73197e7cb3197dbef98c3ebe590e1fdf3c678f6f46438f6f4e238f6fa683c737abc1e79b637bbe790d107c739d3bbe998d0f7c731b7abed98d39bed90e9e6f7e438e6f86e3ce37c711c737df81e39be578e39bf1d8f9e639dcf8e63c6d7c331d6c7c731d74bed98e34be590f1adffc8139df7c07edca727c33086857bef3cd7b68578ee39bf9d0ae0cc737e341bbf21bdf9c07edca76be590f39dfbcc719dfcc8719dfdc4719dfdc27ce37fb41c6378ff1cd627c339c6f0ee39bc1f8e62fbee39befe8c5778c5d7cc7c8c5778c6ebe63dce23b462dbe63cce23bc6a9ef18b1f88e577cc72db46bf4c077e442bbc636dfb10bed1aadf88e39d0aeb18aefa803ed1aa9f88e5e68d7c8e63b7ea15de314df7107da354af11d79a05d6314df110ced1ad77cc71e68d708c577f481768d1df88e3fd0aef189ef1886768d6abe2310b46b4cf311cd47263e2ef15189ef4804ed1acf7c341393f858e623998f767c44221e118df88e6668d738e63b9ea15d6311df5109da3512f17188efc804ed1ac57c142206f11188efe804ed1ac37cfce1a30fdfb103b46bece123988f3cc41dbea314b46bfcd2357af98e6c68d7e8c477a482768d4d7cc72a68d7a8c377b482768d397cc736b46becf21d3d40bbc63abee315b46be4f21db1a05de396ef3845bb461cbe6316b46bbce13b6a41bb463abee316b46bccf31dddd0ae51ea3b7241bb461bbe6317b46bd4f21dbda05d630ddff10ded1aa3be3704b46ba4e17bffa05de30cdfeb87768d327c2f20b46bccf2bd81d0aeb1cef7fea15de31adf9c85768db16f9681768d6a7cf30cb42bfff9661a68570ee49ba3685706e49b6ba05dd9cf376ba15df98f6fb68176e5107cb314edca7e7cf30db41907da35fef9e62db42bf7f9662eb42bf7f1cd5d6857e6e39b73a05d798f6fd68176653dbed90bedca797cf317da95f1f8e61d6857e6f3cd3cd0aebce79bc1d0ae0c826fee8176e53bbaf2079ef574653bba721d5d998e6f168276e53cdf2c8676e539be7908da95f17c3311b42bbbf1cd45d0aedc465766e39b8da05db94e575ee39b91a05d39d695d5f8e632b42bd3e9ca69746534baf29cae2ce79b97a05df98cae6c46572ee39bd3d0ae1ce79b9ba05d998c6f768276e531be590dedca627cf313b42bc3f9e60ed0ae1cc6374341bb3218dfbc8676e52fbe390ada95df7cb314b42b7bf1cd53d0aedcc537b3a15d998b6fa682766537df5c05edca5b7cb315b42b6bf12dbbe4c03a78915f76601ec0c81e7cf8610b03840c826ee7421ec6aa68f3bba773e2f11f068376e52cbe390cda95a7be190eedca587cb318b42b5ff1cd63d0aeec816f5904dddaf9eed139f18f507ee94ae83cf337ab47e7c485eff6687904857196cdb6b9e3a50c6904efcad98a8fd26180d2ee225d45271c7c08e3025b7ef8e2052e61bcb04017207697bb5e01e51044c332e215316558f912e15460083855769071ac1011c7051e2619558a20a3053063c27895951f7ad0c070c1083028e0c3115f7c5701e207ee4d0b48bc994018325e3c75418805a29bee721428d3c5d38e4a6f104970f11d96d842d7755d126ebed9cc16df7c468b6f56228b6f5e8299c0e29bd150a0bd02da01f243c5140c5a715ed7033f25eeae027669f7c1564ad784724da97374b948e9ba84490725f3ae4abe35dab5e935da75db7c6fb4eb5af1cdd1ae5bc5b78a765d2abe9b765d36df9476dd29be3bda75a5f85ed1ae1bc53710edba6bbe3dda75a1f80e42bb6e07be85d0aefbc47710edba6abe59b4eb3af12d44bb6e13df4368d74df34d84765d34df2dda7599f82e42bbee12df4668d755e27b8876dd33df44b4eb9af93e42bb6e12df00a05db7cc7704b4eb92f976da7591f8aeb4eb1ef1fdd1ae6bc4b704b4eb8ef92ea25db788ef0968d725e29b02da7587f8ae80765d31df2eda7585f836a25d37886f0b68d705e2fb02da75c37c1fd1aefbc33712edba3e7c6340bb6e0fdf4868d705f39d44bb2e0fdf19d0aebbc3b706b4eb7ef90e00edba5ebe93d0aeabc3f706b4ebe6f0ad44bb6e97ef25da75b97c33d1aebbe59b03da7571f86ea25df7866f25b4eb4a7d2fa15dd786ef0e68d7d5f2ed01edba357c7f40bb6ed43713da7569f87eda7567f876a25d57866f01d0ae9be51b04da15fef97ea25d6120df4d685708c87708b42bf4f32d02ed0afff87642bbc2107c8f40bb423fbe9fd0aeb0cf3709b42bece3bb04da15f2f13d00da15eef10d8576857a7c47a15d611edf04a05d211edf26d0ae90cf77016857b8e7fb04da1582e0db00b42bbce31b05da157ee0fb00b42bd4f30d45bb423bbe5fb42bace33b05da15d2f18d00da15e6f99642bbc239be1340bb423cdf0aa05da11cdf0ba05de19def29b42b8ce39b01b42b84e3bb01b42b7ce3db01b42bb4f3ad02ed0addf87e00ed0adbf88600ed0ad9f88e00ed0aeb7caf40bbc235be2540bbc2d8378c76856a7cb340bb423adf54685798c6f704685788c63705685738e7bb05da15caf976817685677c57a15da119df56685758c67705685718e7fb0aed0ac9f8b600ed0ac7f87e817685627c5f80768570be61a05d6118df18a05d2118df19a05de117df1aa05de19bef186857e8c5f7066857d8c537076857c8c53716da15baf9de2cb42bdca22bd4a22bcce27b69a05de154d70fbeb706dad583ae1d7c9e9dea9c5c200b2e08da95e96985d005d3d8e8a068e0a3ef54f74488c5a2f358506a283dadd4e315510cedbac1d32b86a05d933cbd82d3143186136368d715e30923685722288ea05d873e0a3890a05d8d9899020e32b46b11335494a15d5b7094a1ad37634512b42b91ef6a1088f4fac35b37d385b0bfe228f555b5b2f22b94d2aee3e89a4407f25f55a0e8ab326068d721dfdb03ed2af4bd3ed0aeac6f9e926309da35488b25e82ab162223a2899afbc239ed5a2af1b39d0d0ae41e2992eb8551adad5fb95121d19de765cad3aae39ce812810e79973dc1b399aa05d81baaebe390c3c6a68576a460c3c4fd0ae6da6abea9be34041bb7266aca15d37964377975bf9eef2721f6ce758ef6214b4abf6f0e33dd341c95ceb3abfe3149d24061562d8acf481cd925924f6082376cc16b16c100d1929d2dadddddd7d62d3b29d322e135c26b2d93f2bce872a74ea0af74f5311de3b3cc0d3552a97ac695da4d4a96441baca55ae6aaeaaceba8ea93389dad093c91965668d325739b7ed9ee0b32f7f709144874ac35b26dc35e15c8bcc3c9923334bfe64c62532cb293d4629abb64d0fdf40bb078a5d70e9043692be4eb7b2f2f0d66174592f2e50e51256a4fa4e602399e4a5d43ed8b67d30ef5f5480e1c52c3f45ceaf94187902bb5e5a7830265692548afe9342658fe4e807533987aac192396b11b184da136554038d7825a6219969f548269ec863f524092d31878924a634ae4ca83d704ac6dae4f9551a400f636dde3c8c59b1a7cdd4c3581b356dce3c7d186b23e6d7690b45d3a594f31b92fe02c48beca5abc4f2bcbb0bc3f2e5270c4b0d3fa58461d9191af60b05670f3df8e8f36dfafcbff0c1b07cf9cc353b34fc7624c03b3efb20148e5c43c32dcbaa1c628e5addd798dba494f1abc20f1ac530bde061ac8a311e46f6189e333bc4d0827deecaf1c6b977e1d9370f4b43d804238422638c9b259b90e76ec6508bbb49c8cda8ca5a63ba6dc7c1956a811a7a3406e984ac380868591e140ab24384402241b1c52a22c44686ec101148d4da234520008cc408869c88eb91fd00002588608b1c4e5023055f0512b0ab688d26801650b01754008f5c11c908030b18c9059b740433405a0d308001401293246d90012b69b04b01804c4996830d60935254b2c44b98b8030ed68326f881b7de12f81d44270f04c0d2cb07414060129fbec99317028b5dde19de3acc13414a39c224b2c4d4a216b5a8452d6a518b5a6cdabdc878b056047069e5d287a0925cb956895105174024e93023aa205e10219b902019c46296902734642312e51022da9c434413003282ccb75855fcd19560058bbc09843005acad600874195970c1111206489232d02000493698153ecc03025aadba8ed26e958ae3b64dd3b26cce4e6e928bb376dc078bdd06dd9308a8aa4e4db5e4ea9e5c4c16480e8e9a30602549bb4483eec9e5ea2089074a1f303169fa254e1e440148109e9a84208293119e9050c200a0442180090538c100281c00ea950202a42440010b98c28006384085074020022b4800c602950950a00517aa58a9c0150bbc7001183090010dc4b08118b3c830030d513568b141ea061cb670e992830e5ebeecc003981e7cf8210c104108216608228a1863c411489029938499334a2cc1049a344d38a1e6890e40b1260a29a66043451556b4f1c015584c65a1c5166eb8e8c28b375f8011061c31c620234e19669c21670e1a69cc0a3f0d3a6ac4d6a8c3461b6ed879038e38eec881678e3c74d461879e0fdc01823d7cf0c8438f3df8e8a38f1f21f863fd2c201bc8fec922c30c3444d5a0c506a91b70d8c2a54b0e3a78f9b2030f607a0803040721841433041351841c63c4111b1264ca1cb9c89449c24cd4229a8dceaaf2e5a373e20f21120fd195a0dadddd65627777777717cceeee2e94334e9520b5cc45c9cd8cd3b86d6a9aaa69b702f282080962090d21d22a624435a4cd79a48f002002ff221c2a028948105b3ba4481261a109e690c8a220eb49c4820a34a119e4daa836e4c8886369422c50759c10061768dd0671dd08587e06e9a01cd139b50e36a5ab0aba11b8093a289973b3727163754da6ab925473aa30a047523a8b06ad38772847620d8be4729433d3364ed5b45b0179418404b18486b45c5f411209ae18b74269e1ad1b41a4e86d64cc8b082f89e848041a3bb7b5e1d7ad0440b028489c208829108a15107115311a620b8e5c10c11e55240920061320a960938c32b8006a801403808493641003d03db936505a62a25b5f623c0e9a942c09e383edc00326723e60e204c97801b804c0a40c0180f0d42404274e4618e1c99326c195a46b11e1d9a0f3587278ec730054a9dbee782ab00b8a114b514c58ea9e5c2614e00403a07000a8570a08909200052c600a031ae000151e008108ac2001180b54264081165ca862a502572cf0c20560c040063410c3063880258b0c33d0105583161ba46ec0610b972e39e8e0e5cb0e3c80e9c1871fc200f15a21c40c414411638c3802093265923073468925b6be8e68c209354f74008a35514831051b2aaab0a28d07aec0622a0b2db670c345175ebcf9028c30e08831061971ca38630a36ce28c28a3a73d8acb1f53584b774d2a0820c3a54744f2e32d488ad5167b71eb171441b47b871841de97b44f7e462979d37e0b823079e39f2e4a9a38c1d65b6424d1da9c02ef6f8813b3689eec925c75b87b97ecff2a12ab02b3686976fa8c6aae1c4a665abc694719560b87f56d26505b0496e540aa3d78329f430c6c6cec30e8a635e93dcece77ffcce9aa31b2b719bb61c393939c8640563f2503c3fd6a59440b089058b64117032a09f3e678c4d1c204f5226e49c5b8c13cbc3e89087313640b06417194ff39e451ec6a440f33d692c417afc60b3764fb22e635ef3b8cd496393d81586e555d32bb7cd28a3dc210f0c1b8c6378962e6c71296a732d1f38a5612f9e2d50e4cfc7251b38d7c2f9169b828e67562d13b765b00159a00d91203b4234b522a14c6617acb4a881d356a3b6984de6c069ab69329e5350e55a54ce398ce25c0b91539a87b1297e78e86d81237fa5c833cbb9719190539a6c42971e2f70e26a14e75a56597cfe46c0a2811357a368809a531ae993a144973670e0a48503a73499c3238da39c9e5636bf42f491b26bb9f858bf5f2ccf9f0588fe4a918f1660bf026352ccf1b126fd6a5228f6afa4e6d9fc869e5421bf552b57b4af02ff1c45f9c948c3b3c322b0129566e5430efd0854421709373d52c488906fee488f540fd6889d5633529e53d4114fb3de552bfb714680bcca9a218a8ad2e209b18610712d494e69ac5cd95e8857d93f1fe452494e473e2deed4d2dc3f804d9eb37b009b820809727625b089e5ec4db049c8d939804d438838fb126c6a39bb126ca2cebe4112d854c4d903009b8c38bb06b08973f60c601350740340240cc52e3807d671c33dac0ffc430c2381984164426862b62138225445f4112b2046e2a1580906d827880703f4e30191c992454896a8205e1929a9202929214192f0e285c55ec004093113268c9017460c2be8cc983143b6316484584a9c3943449e91bcc443b1d2aa6117c3564d10efd606a947a0d0552334868df8a06a462ac9e9880ba966a4989c8e384be8887badfac2f6d489d417bca73ea4bed07afa993902c54adfba98823a40153a5d25cb66d9d43d63e59cf132e761d7128d9946464753638b716ba8ea341bb48dce8d951da0373c3882c421e44e901c2c3c42730cc943848e561d45ec30a267e80344771c010100f644c0c7f1a8797c7a48b047111f13f441419f0afc7085c0e80f0bfc5c00c8512048b4ebfec1200b12199266c880060da2025043122d1bd8a024b57403130e1c6c69e2a2a4cb921c3ad0c1032f1f7c61b2c3f3e044bb3298290c6880035478000422b08204602c509900055a70a10aed7aa42b0022f0fa49d0b568020a2a70195970c1111206489232d02000445d975a8bc36e59098a2810b916b64b0e3a78f9b2030f607af0e18730400421c4726258424388b48a1819a24b7404001178fd24289a80820a5c46165c708484018d483a033a4fc200a29870020a50294851c094060079ab008115605428a0a6eb9af144f54885d108e66474576ef3ede4491a74b4ae1cfcaa9a3972e483d0a837b66b10600daf0ea56db861e700fcc66be140008c23017b6701500e06443c0ee0391e10f344800e09d4c102db31013d2dec07aadc510108020becb9c0f2c1001e1a80796c400f2cbcc7cac0070d35d870c3962e3a7c09649bcd1edfdbc30f4b79866e84edfa05a015505447c4181b68f7ab6a86c88f1419aa34b840f4b1d8889dae12a30b9eddc8e78248ec95e12151c68c12cb44972c07a9c3af2acb4a108884fd4aeb8320127b7074ebb166f79062970f3670fba862b74f1bb87e5c11370453bc7f68b17edcec02d205dc40deecfe59306096851365d83178868d43c39ab1512b07d6b068ac96a5036dd85894da3a7cc3b681c3dad92d0b07e4b277b6cbe281396c9ea8c3d6c15e56cf97bd63f7403c560fc847dc3ebc21e0f5b381c02038cb0ac13340311c1587d0c24448711138ec182ed0881c8ef08204ef4086c194611f38090eb366828067c4ac1244c025c644268e60346438893d03975834b089a886b9039d93cc3b8a2978a3b88a3513ca6ae55328a52ba585ae04b0c3fa1179d83f18cc02127bd83fec830cfb030d304c0d40d8c041dcb0426c815550c1660a29a2580345079e50e3441369d0bc07f3808200ad84acbaa08eb2680bb56a888a2392655cb6b5609b46b54ccb669149a5916ed991a391b212dd93081e683b5775751d7e434f58e83c6326280b9977cec41ba90e8048ec45aa0af50110899d56084024f6568d0044622752578048ec43aa042012bb102ba8528148ec42ea042a05a6402476a0ca0088c41efcd08eeb88e398936d51079a23f8bd76f0e0439719c7296d9a47e1259533131bb127a949ece25861bce6a19f87bed5a1269e820c1e8c2ea9382f824d9bb3bb26ab5f34789a730e6b71759899ebbc5903cd379c9057302cfe92c1d37c83cec2f67979e8cc8585cd3b889a7ad83de9206aea3729ec719e3d497e30efe1f689607079d83dd12356ac8d3a8cc1c3181b7d7c473a2b1b70be612f47b872253d1ec501e7d99362b5a379c15cc01187e1c8f2153c8cbd41e7fd612c0e34df320e326ad4ac9e875139c36afaf0d6617c86d13c745623e5c16406871f27f4f797b778b87a7809f261256762c24b300a142fc1155c80210b2f6d16a931ac043d3570ea4d1c6fedf0127452cae4ee79e3ccc3d81b4dbc1c9a9e3df7c69897ec6229b9e44ed2891c3649b1128cf7b0128cbd11e7a5af1ecc85953c1fd60f47bdfc2af1cf9f0ab0870067f7847f7ecc054482ab64d90ba746bfc8f05e6478b085b386cd1a766d1b0823bb8e560cbb960c84c1cf14769d002184b38bcea3a78e9d382f67df40243c76c8fa28e8bbbbbbbbbb5171b9c081be474f18d05f627876ee4008672a294951a740c6db15b3ee6949f2c88e6715b64261e1ed4a88024452406f41a16f5cc1a4ac009bf6a104205212d1f973a34785259699f9496f6c0c401e2a8ba687b131b6f81dc32ee95246aa06189e7e94446699949f1415988c18a3f4cd6505a10439bf2127587e7ef0e3b772d0c43a28b1c4dd237af53253934199c6d4c785c138dd1b71ae91c5e872f532baeb6130ce9c2c66716606a5fc3e28f12381c9c545be8ca2c4ef545c9072b348499772d1c822105809c6d228b3bd1765c6d46bbeecd127142b49cfcbd635e90cbb8d7ef1244b297a2b7a184323eadd8f1ec6e668f9396a3c7755f64f738782e62868733af05c2b9059b2387115c6e4d079ae183cec5a114a7a942c1a41e858980392374fcb89e221d2c3181a7d1e76251c79189313e67997d77925854870a3e0a32433d468ce5b34d23c32bdc6149722d3515212565ac92e66d3a676e59631bd76e4694ab08d6acea469da5642d6a588972e85958eb2bcf61a9c5db641a4e8e4b043413a6df3cc52f0999087aedaa55634ca1cf29e5146988f2ee548fd3a7bb6d389eb0677092e05429e5f3f78d3393ab1036097e01ac1bc565c52ad5117bf970fdea45b6527ae1022b1679ac3261a5ebcec9ac86ff3585e040f63689c79d8d1de6417b9d965106966d15bd3346db51f8d953ebdbe78dff679bc5372ce9cc43ce968386734dafd52d0e2c15a734aea3ad2e012f5e9d38978694a6b3aaca8124181b0f504764d872d282bbccda7443bdb078208244c4d7355d576dbba27c9cbbcef0cc29c62188d2b86843ab399426867c6eadcf9395993b279075153df7ea0a05ad1684681ca238e9c569ccc65e879cdf9fb3638c1c35819587cf39ddfaaf63b664c9224da7694042e84480c91768a76b9b6dfa8b90b0f4f739817b99ef8ad66cf752842a43bbff9b6f1f1b64d83b132cefc56b95f3264d8054920c10fcfd9358be292abd5df0b0c909ca6eb799eefe685e07ae341b12b73189157a344a38c661e2b719e6d4e219c87b1386ebe258d9de6344ae6197473026523ea33f732dfae840ea2b0f8751058a983a8a9cf626578f9cc4960a5b9b499d28e943643b8cc7305e300cfd9496628e55cc138f09dd30ae4eb8481be2c5b7555e85fe9aac038fecacaf7690502ea9aa828f52ece9a2a19c7c1ba262a5ff956d886b04fab51d88520552bee7cebca3bf82ad52a6a59a6c555e7ab0a6985edd3aec2efae89caa977f704db26edbbed5b69a6aab00da639f76d9f1d159c3f63cd5233fa44d75176469ecf3296ce5b5a7358b451a288c0ae289ac3e01b2d0e13d634cd33781883e3e719ce15df69df2b070f96944402bbe6d37e2088c0aec9845dd35f8178306f6a4e2974e8fc9cb333ba465e5f78bb2daf609a46d935fdf5c5b5cef99266b16b83cfd4ad6b3549f4603ba6097f0a59bca423cdebac35091ec6c448f3db399170a49141ce4e5b0a9138c9044e81a0461c6e738d88b56d0637ae38cee1bcf1db4d88c4ad873138497ce6cc049176aa6c98b1570e1e44825d999acb37f758deff2e08d8cbcf39971c31e139970d2f0939844b2c38717829884e1d5e22e2d0f74e1e5e1ae2d0774f1e3d75ecc461179403dfb00b6a6d88548f8da60fa9446c348da6b32a131b4d0faa20b0d1f431b23c92873131e2fc764f2e40a4e91df777cdf46533f573ca383cd84665ba260c5159a460139c5e053651710136c13a7af434b1c73bb065331d8a4fdc35ac047f0906871df99973fab661a87298d762713e59df8a81c13ebb67ee1d9e3eb75df3d361884b413e7dd904d565c3465048d7aa4dc817e4836d306fe33cf4d5a4f370ed3c9cd039d867f73c74ed8331f5814890bdacb8c9f02ed41fde2ea410695dcc0a86859fdd831d7faf1cbce8147c1787becb20124bff9e3b558c515b4d8f85e86df3bccc5d4919541f2f46ef3904db86aa2c20ef9ee7999c51d3782ed4542b0991d859d165924934635ee8f15909196758e44a1b1a662e8b5cecda16bbe0b6c1242cf3cd654702968765aee29eab573893afe2272b9da3b7ae30941fde7458d16744cc6ab1d2f4326f3367b573c30f56f4dba2de36e464738edbaaf6b9e67647cff49eec943f16bef0f3eb90e9a16fec628f0566811d3a7961b17c8b5dd08568cdc778f922cb1e3b71a6dea801e280a0b62e8af4062a81c2269c4376adbae59e99e7752648af024f1b44821e244867420cf214257321dd095e3462f7a211f4564b48d72404f8452012fb531188045deb4c602714a453f6c16804b49f759b13c8ae208814d499b04e4192b2e4b8b2ba1020bbbecd817cd53d71df0b076feb3ada3d6ddf0b07d674568782749a5a9dce6f667e3170c0497e301a418f1c88ac7de9bdc34aebf943a6a93874601eb8278b5498310f570d9ba93772de0e9c6a2589c05360f0b27960130c63d7336f8f95589933a1f3197f9679d1284be1866c69db3c2f66ceb48495588af0e63367b131f559b670aa73927519f31cc7ac7dd0336827c2e985af389eea8a3dbc2d6f6d13c5f154db123b49220e837b1ec2341f42413ab51ccb9b59b2bf9fd4519e4ad267bbdfd090a02040deb38729345bea7c01e74dd4fbe9f35a16723a89c9993ebf5cdcf9fdaef0b7bc2d584cbd94deaa9097a2d3eb068fddf3ce049969743b02448de9d699c01c29d799b04e5cf7148506a096ab3a14a493e71d84b2b8484fd242eaa527915e0feba5d562796fec62b1d9b66ddb3ccbe85f79cd61a76179ad52a1bffa568a4522b4512c9f1e65178b556144bf10074fb28be5ccfa3676b5dc5b48d334ed4b21ce461786cfbcf3ae30969037eb5b1c1689109d1772b14b7abe55cf812a8ce93da1afe888e5b9a4c2f4ebde27d91514f434e46b1274851dd8057d2f1c3ccecd983dc34a1bbba69b8cb6ea8b8b0725dd774a8e07da7c53dadafd605d67bbbb9b55e1c06fbe9dd7aeb6d825fd05c7e37cddd46139918b305cc28091de9def07f3322749855673d67492aca0562bced75c88902031292e4527c94b9ee71990ec9eb4ef65032ce99d8995a42fd13eca4ed2675782e642be5c32a97df6d1b842f5885dd059558428494cec82eed5255c6bb5b556553e65deda2dfac0f60c18e949ac046359807919024dc1060f267fd1b0d216027fe65d26bba7e95d757641a7597f99abaaf31274e2763f96ab09e208c88881e04d4c8f9dbfbeb52ac2a3ad6bb2d9087386d1aca1ddc86d3263d83463b65315bb26d90e3d91fb7910090bb78c45f4172076bc3f3f5dc8cf3937ce6b5b8cdbf664fb3c0d0bc9c5a9cdee697e54a26f8c93bb27f1f3e8ab8d6cc98ed5227a18c3038dd7f2fc7a54c528b5ae89e6dc56abc03fdb847ac3eb1ec6f0c043c61899579a0796e3d436159d34e3cf6357d460d2271474f6a3598ba80d4f2eb32a9c328e911591aa2937f8b1109d7329a5ec4c4a3dad086306339f9bcc9c638c50b2fd1c043132cc5c66934f9a8fbec5afa8885d92eefa94aeb92486879a9f73fa9c0e88475969bac76a69d16172eb6388102b4806596dba043a2277a7f79b9cb15a897166b20afcb37df1c9f427309a6decd27383e8d0239c958a418531d3aff0923b4ddf2c1b05637bf2fcf428407ee2d2067642d86a4523672523ab24baaf7bab17bc8d7a9259f7248f7c0b224dea30ad879a389fd4b3cc697bf6cac3f435c70bcf4b8ed79d571c1ab7d1171c2e5682c13c76cda2ac8baf3768b79146cd87625c51569274cfd4b728916e8520fab2a311b1128cbae8eabd88f375af89687cecf856d1210f63784cfd729ad337db95903985b0764aa9c623ec73b14289e115a12f37865ab0a97f4e3d2aa81ec6f8b4f91ea2af36bc2342d8f0601bf5d35f75882c5d61a349858dbaa7f8a9b086d7ce8a60c82be6cd87313e67be3d02fa522302faa2d37aa561a4d2171a44aeee493a141c4fe530784709c6f848fdf41558890b095188f858550f637cc27cacd9f704f435a729a02f395f05f47586d75ee4a2ce4ab0f6b89426fa74226de8ce1354420244323d884f6702a10854a20244029ba24f08c70b2111e8bd2f8620eeb5bb2ca05ef75465ffa83cc8c3189f2ebe8f823666938bac569bd34a0491b67d03414e08f2a5c91cc8a366774de807f3acc2b4cf5656daaf64345b65ce8457197f739d930877c2f6480b3611111de99e5458815dd3a1e8f0fa086dc1a6233f3d3eeb618c4f1a1fbba7e8db55796ace96e3c631ae326fc951c655e6b0db3e332cd8043dfbcc00b94c214d74a06f8b46eb2a6e6d01b4ea68abb88d8d8422ee72591c24d47259a2883149b6b061c3468a3552b0b9c30b1b3667d87451fb609db35a7a7685fac64a2a17e22b05a7daba10540ee49dc1dfbaa74c95398bf3ed298bed4c386b2141661b6f769502cd09f4c4df0686b7fad8c095427a565d53d16df6f774aaf26e098384ad94fc29b5522c9275ae7b9a1a19dab67d720a7f8dcad7229696585eab30a979c4f2dafc348832898f1dc8d5a38771ce7d524ae9bfe4c924568a0a8076a66c0f811dcb2fe773e3aef06b9f026211313d7138d88ac4f4c45913bb434d4c4fcc8e330f85342c6208218490f5bc9fdca2c76f0b3b4c6e4eccc47fb670e92c2c2bf2d0b1628c1ff23066051b08c4decc70cead67190ccb6f5073bccdb34d839967db498fadd8c8e25f8715f8bdc02f16ce9bab140a10eab5560991aa7777e977049136ab475eab30a4674ef571de41252d8792973ae79cc2a6d62a21eab8dbb66d9baf12248884bdc964d73e24cf0e23729934d74c3193e6ace8d964339cf65991cfc47dbbbbb31249a83a3c9884677a6adb56728c9f94ce246e19941e6f5ddddb85c03feb50957de90f8b4e9392b88ea2ec42d0b657166f7feb3aee48df584aee488077ecf4a8799e941367cf849b682f5fd8a49cf2734124283b36340d07e025f9b6ad174354671f4c731a369a26f3dd5dee63650e63bd4725abb4a78d883760a969b0c52ed63ed667af3abc29a39f9e227ae6b9e489698e177d3b289f6bca2b9251deeec35ccf2b29d407bced5e5380c079c1d97c8192923e2b7a974ac6cda53f71bece2e9fec1995a4edb77b22b4c49c259e23968d794f0c3206c819defcf09e8fdeaf243c18477d6425184fb11b565a18a3430f83793ab844cef3e65b52a84db151742d0f4f73301be6f983c570e6a56f80cdcb0fc66dfee2e245e6c24b3c158da247874c59cc4726c3683ef29a8fceed513a755d32110ee7e10fb66e3ec6f958d7645fd745f3b10d1b45971f95cf584f519315e645e70395b0d422899e795c3b78f34024e92cb54a960e88447a5c3b5e4ee7580d16ee9eb6dee0610c8c31df1a7d95d936cf6bc1588ac1bc1447a97dadd7160fc6525cc026f9bd6af098cfb06ba59c543218731e764f945d517621ac1fad6e356eadd8e76513560243879fef0879a35c71019be673c17ba811bd79c2ac1f495f5a3c09e300988745e733ec82ace6689754496c147deb51fc5c747853c60e0a6b19e64d1537cf3cf40cc66ba47f994c7273b4d1cd355dcbf3b07ba2e5f9f9c1a66f5a9e3c5c38eedbe6a7413e33d7e51d6d76b83c3b65edc2c8737ca0eba5e061ac8e360f3b3f1a668130cb3e8f087e2f1dbce853db321160de0ac825d0aaa9ac4bf2f41e4fb56d53cba4ec32add3b22e46f81c763af975b0934c4bdccc514736677ccc010736900c03c6e2356cb4418eccb39a97bfddaa79766df3d841f986349facdfb6dd2cdbf931954b7725ecb80ca35cb133613764a573073c77e01c40402825dcdd4d72578b7de3d7162f3a1e3d9e4aca4c11c6b4047e8c523233331e37241e3c6298f1a07929b9c2e666663c3ba8a20d6d673b282c763151ab487e2f2fde3aac23859584c8b0d266da94e92c87bc34c485784b459c1a711574575c1afaf64c3462e7225feb83d1a87311f96034027298ff900f46a3200e733dccf51ce4b0a49753d8c5429f147631647d411f2cc9e502fa600e3fd5eb8e3a9b1633a2a5215e344466f1328f9b9429753429bb8cc133c3b3a6a91eaaa0aca382942979a494e38f67167368c811e70e1c39ec3cec9eacac73dd363a44d339c96d0c2594cccc77b8785904f402e1b6d8d5f023ea5c1dfc5e3d78f0d7671217e21210ccbc8e009a13d017251a01e1adc3923408a1cb25b069e5ec24a8da5949e79b1fad92ee8bb248baa32b9cc3ea02bbd829bb98fb9acc5f7d31402476f628da8b0f8f3a0ceea115b625657bba9f5c96016940da0c5ee69ac3364aa327b87085e19e385997310faf78f623bf6c831b7b14184e70e10afb4962f35eb824ecc0a22e1e74cda34b67e29ca147e1df32df2accf51b402e9e3dca247f3c58d14ba922f24d0b64c926e509ed79db346d6a9bcd22261b13d90c4f0e913e16fc5e61bc9ddf9cb39b0e6b92f92585007207c5733827e7dc06b56c7a06a3ab2889dca4c6429699794dd36606339804c223568a77c8408571a78687ddd49494915618cb236262e2564b7a92ac4cd2bb24f26392dfeb072f3a670191a0731b88041dc624a5944c7109c8d95580923285955ace2dc8b742f43e188db8cc33979c7d046027a08fc98379dbc7bdfa78ab4abbc2d6cf501366654b40de2202e2e49f24a6249a4ba6254c725990ce71dc37b401f21b169fc4a449994d39a1645a22e50a7d3cabb8cc39f530d6e78f871d148f5dec1089fda8888dd88b663d9aaefa5e3e7845db2c62255792a32e72fc8a5e7e78db56b94c6bc9a5f6099ba49c508014cd6f73b315b98a567e43dc57655f043ecf13ce2925cbadc89534e79c53cfb39330798adff608418a9413a4ac6f5052d80527b314815decadddcdb6db6a84ec62d612e7ec45aea324a357140bda5787c5948488d56216342d491ccfbe04cef6452620b05aceb4c66f1a12d284efc58327639665d994b8a472252f9bb3062101342715cc836d1aa7fa92a2117b0a337830d7cb252f622701a335a874cb5ba87ad829232300000000100000e315000020100a070422b16018a6a12e970714800d7e88445e4ca30704498ec32098a618080d2000006208d00800ccd0b60158a7d5496f9265c682062ab5183cd38fb7032b321b97a31e5400842f6686bd865480c56e668c3df314810101815b4646e1f54a0395efe77450fd6d4f44265960feae24d53620091c3047c168c330e6c1168f2649457a507f866a429b0b7560c730d38ed99b58d000cc67ebfe10235a006ca3097d0c167acd583261f743275fd82cf5cb0879500caa854bcaf7b4de10eaccca02b28e139578ba463ceccd168b925431de39f118c07b24edcd20565ad56a7f5a6c80c1a22cd5c5a4e21a2f05216babf810657dc1fc0b954ba0a80f2a3f31bb1ae60a608a8a7cecc3f3afa4420c4889837f05bc68c83b353634b790453122ca11280a1d61784bafe97c385c2aaf559866411dcac3a88536a4e9fe73fac8c7de900c674e3e4ac75e20879c2e59d40f38cc620a18a8b0ee679117a8bb21d83997217c177db02df3c2f18592b7725b2453f785a8ffcf9f4ed909386a9e8c15b3d82c270f31162fc8030f883de3a65115a14d1985cb83bd4b200c5174486c0f0bcd56b4a486ef7d0caf58536dab996cb70a0925715655d61224b3e6f9c1a3b6552e5e75c074326200a89329363f495767e1035a72f7a1908a8592187ab01761683baa6f2e5aa6069469aa874ff4646ab5346b2d017fa636c9fc868ff5d617aef1df0e103668a09b5be82843eecce81ed3f2e8c4607ef2746aa2966f5f44b6f8f100e237e19b16f55ea4f7a2de8b7a2fd6fba2e94d20b93761dd48e036ed3d5587697b960e0f411e969a0d1da2746c0e43aef399cf827f473dadaebebf06bf8c8fc2f57cc078155cd8efb0bd3045376d8e753bc8f49b40669cb9f87a1ca11914e456e46b821efd739e40e50cd109c1dee7a75f000324a0ff1784ebe65b6998ada753be923a28aeb387ae0d022324b8b1187a2f887bf6860a56ac5cebb404e2fe7d64c162e700d860ad2013d3c9ab5f88bc6c0fb1b9e718e9ac12f2a48144bce2da0abd689602aefbebb00bad9ad09323130edff767063903ae835ea529d58f4d4ace7ba64af1ac3248dfae8f11abf6b1c773030fba0783f21423fc4d8201df07f839d41f638eb478c593b9a1105bf68e7de390dc32b1562af5d0c4ba6eb95eadf339333aa485acbeb570c3932337e99b7c4e14fec2cdf59d9410aa3b908b2a56f09b88d58003f08208b8f0ba4cfa09d0b6fe07dc40450c3c15cdbeb89e4cfd93f0ca07ea5ccb2d1883799f0eccd606753a8392e56817fa92ab23c3cf5ea16b002163796407b73ccad8ea2e29662287c27dd1927b80bcb86f02683d04fb3303bb134facb05217b2ec52cdf27d648027ac5706c85b4754fc9b1626c80b62553dc2bedfc2e8658faef9ba7aa6cf477f140e72263765c42a813bd489aa25012e69e6d3225c91e87632fb81d5769cc0d62e8bef628dc15c8290dea2bd16f7b6b8d722bd164d6f0592a7038959ecfb57bf3d4df8b76a3de254f3507d7314d32ac1c15fc0cd05d60940baaadd9b52b364caf9a06f41fd6f8f1f8e5d10818d34b8384a11b7579455b307dce844243f90907287db5e9d696813ce7fdae2f676e77412116e9fdb242087631aac68698efb35d07e0848bd3d5ff4273569a62fedc734be35935cd32f8ca4ec2b7a087fc8b5dfd6eeb0b4022ebe268087233785664f87b5d16923d8c750ad5191e0a350849429e2d8d4fba3eb3ab72339595f34e45445bc6bc922241315e444e060be22ba74bd11084a6b58fd07830c14d90313375bcf8864efa7ef34106ae9004176d7eca361c3ef9a050506731e9b8cc3be0732c3311f15b9da7ca9287432d29a69351020f5c8a296223762cce55a278d6bc7c26ff607b0d2cf0fe774b8b12769c2d036e9ea2eb1a3f6aa921a5d4a79db92c168a83691fe8fc273b1479a7338ab1c4006355b70de0db5c532591f0fcc0d4ea4088de06c984353368befd89e1d3db6f3e6636e78e7004ec5e2a4184ea2a5706d1aea0a29d0048540f65a8f9434e0b9151a6a0cd66c494318d36c120b78c446dd10c235f355d36c308c2528dd7b6a6d80dd630e1d2c85f70ed926b3927c9e1807705bfe968bc3142793060ca7f669b474f5ab80a8bfc0d9ea649e933783e50c2d02b233eb76dd017662faed3cf7f0b6635a262f12e57c86513bacd888eaf097c9972b0520f7c66763017815f4420d076b0a29131edc2808a9fe2bfb302143bcd2de6183b178b71de387ac3634d0cad9be1990e8cd452b5f7c6d0189fe616ef46ea6a6a6587527eba170b482685c3ab87e8afe1297f7599777f8cda17cd5b30917960276d9ee8ca859b7530615e7c87c8e6e65cbe1c7006da555151a8f79f7e0f1429c266814140b11ea4dec16797140fcaa5af0c1b5f7a03b45d540b849e80b85033f59df739d2b20334db38a2a598de0baeb57aa9fb44e0bf37b466cc4d46d70c73605c90eb384cb762be4909b68d6512380dbb275407eecb5b90a4460b9a3bb96204feae5ed9bd73483fb989b873d31d1c44b7067f8731728223a1369b8921e42343ee537d7209931a2e07ab16e6df6a99c41e9dd226326249e741a4b4c9f1a3ab3f1acd9a70f62bd0ca1ddb11f7e499c594b87d68cc2ff0407d8415c28ab321463b6fef841950a2b361f2beec37e5bd3eb4985c1ff1bab5578e84d58a853d8e8af9b88559e418480a8505cf62991b243987b13c4f2d5ba76be6059b590bfe9c5be83c64d9e5730459cd1788d65bdc6fcc09834fbb351c82c665f9647c949230bd401b453323eef834b9dcbdef799c4d130b60b72884c72620a041c90f1cae890c2116128c5eb3b3938bd3665972ee84832a0c764d214b225a7d0962af6ca7f69b94e7a1564673feb9a5e1f88c0fa9f124df1dfa5c42ff21d4ec4289b971a77f7d5cdb65ed68b6d8efe243e988e58da1aebb94f4cb9b4409e8399460f3e9240207022bf91d932917999ca54a6c8da45523be071a26a184fa4d470f8f34a8146c7249d7f6895a2e09f0bffdb2c0ade2ac80eeffcd62a081116162c52b50a014a6d2b686a15b211d32ac0adb0cb22ca589c2f74840d2f2f5a05ce79e4b5a587f5b70de98d6f55972dafa13c3d21386107051215180daace077fff6be08fe541341da459a0a70c522fa427125b49f49b61f514d2091c88de4509662dfcae1a2b2830c2f9fe4598d0fca3eb4038f6497f30f141b80a4cc695f271b12bd1d5713f3ab1f57d4e2896b92604752cd34235d147381f33c35528bde804858de4b475b4f038c873c6b2133bb804bb1424118157a7eb7f83684760c4ce011bd491424348c4b101baa819023558635a83130585d1d1d570d48bd47585781998920015d99e4a6a49a5111664e64cc7383b1d6a18866aed53b2bb10f6d49321d39ee604c89a87b1b0f526042a4d01eb6f1ef8e83cd6f3dec8865e63c490eccec973ff25312d481faac6cb9fcf44293d45af5a4ab8cc8e7713b7cfb7e1c5fe7c44a4071a1f9368288bda0aa005a044862929333df695858384c38bcaa6717cae85f176b031f1de0f09b7dee6351ece734112cd3c8ac460e0dff1f25dc990256fd627831813a242a01bb8988468aeb7139341db060a3406b3b201580ab024f07801a8cd5c12980f92bc225a38de523e92ba22bd119e9110f3ffb8d8db18d82f4aac5472599532ac3833577da56dd8fae19ef39f72fc71ff22f4ec1ca010955efc9fef2c3553ef5505647fb3f356fcc14e60ea862f41166043e8fc92e155db62cce182daebe8c46a595c03217f93e256ca46aabd2cfe92eea4fb67c487e5a20ee07d3f2e1cd101554f8d5e49729ba0715ecc2232f79d8793ccaacbc41402971904ce2aca252ed1502b62749e180f3a5684aa59c01ff5872a573516c57f75df316843be2f7c63b38183476bf6d0d64c00479c998010b054b1a890fca529bfc56b0e1f9c3a77b82ee2eb2310870f559d319cb0a869fb3d6f44445f59d9572074ca24b47b2a57fc99362c6edb0c015719a4b71e332c4fd8122141f598dd8000e4a382d6e3d8157c437e17bc2883eb68b54ad26125edb0a3b4f8d1d5888353e9e172aa630185b70fb6e95b32e65a77b37dd76d6e06a0be00efe97c55299a0b8efc637f2764e74484b280b72aca7ad2afed79d0d5e5b4436607be843131c22579e71bdcdea1a12e7481085ba0234a858d6059af3a0aae24bd8e9f57ec1fb65913a4c0f06c375c412c42880bfdf9aa01b8b892ccbc4f2b9efeab8b98323087bec08027f823ddc30f33700d79989108ab8b39043503a83d82b5bd4433e02df1bde86f45903b86bd376ce7e0c5ac5f67fe845c484de1ccab1d111f9f805a7fcb0bdaade067c3aac93f227f06af2d44ab7c212fa52dac79365a1079e47a514cbc15287b594b2133221378377c059fc1d958324f43f49d2c5312b0866178761eea6787e0fc986b0da5fe1e308fccf99b3dab31194c7b6828b478888cb54c8e7570f3db27be9a99ff979c54fe090a5b9e394f6e53f41aab4d8f73f10754cebaedb74aabe04f2eae8c20440575d1a496ad236b6281348cd8ee6836490750e6f6a8820918f2e3e63e97ebba99b853ce6b8d4c44c7df39c309e8cfe2b5364adb23a89b58ec2d3aec616151f1f09e7dd26113905a76515430b11c1a878c06fe2398a7568da2e494c932d2f01cda1f1e38de0be28baa6aec3281f558179196875db654996f255adf8a58cc914ded3b7422469b17849248a52f93a4b9c560aa839fa2ac55185d33c8500faddbcaf4d3f0742fac1b9f6b1f6ba85e9377ea6d187c2825b50ecac1b54d9e03c790d602a676b224a43eb31ebc26bc5bd3c9d8d185a3f9d2cd0c0cf96d3204329d7fd945cfc2fc07aac1f8b955a1064c2c0d246a8d82dabdbeacf81b6865b5eec53ea19a9805c62b017c21c35678de8329592e48a61f91a9f67e2313be305340d0b500faf9be4642da0a9886e77990025905ea0a62f5be4f3b9b84780bf2f13cd4db9066e81493dc2d2ffe3a5b98e2af587299905c64e5ce359dfdca4a2ced0cf0b8745a95f65ebaaf3bd497bb23d3b7a2ec54d6b7698614343fb242bfe123facef72a10d8d4873d3d89e293c45982200450bfb721464babc7d4785983bb5acc3b0d0d341a0826ffa39a3fe23bcc29ca61ea30bff3ec422631461c500a0bf44e41a040231799f7394f43cd0cd82d1b7d6ffd599a6cefadec97a95c1b91f2dbb364ba8280299058e64d3b3b7f2d0dfe6d005c07e5491d38c2841c0f022b315c1b227348f68e168fc55e16257b2059931df91e74160aa247a077a75f55f33ff12404a8dccfd4cc23e09a82e60c6003ae8b849101aa14bd43f3feac019c82cb25138e45dcde521bd0b74a61de79dfb9b66f30ff2dfcdbe45e9b90563a5de6f49a63b4acb3089bf36791c6882fb0120d87903caed3c6708ded31208bbf07379302f223dff845fc9e22971149f856ebb15a7aa579ce9efac78d8251e9408b203fbb33b3f16de2670f65ee900a29cbf61b042aad82d40dda5020be43052389b5fc381874ee253a6bf29678fd3a5c6ea125536c64f676f50847f68a7ef1c868811ed3bad1c5ae6f53ae6034f1d73324b1422b94a2c74a1036886eb7ae7d739a105ccd6d9ace6ed8478b93dd974b064d46d1cfe521caa0b0aba155cdac97e213bcc2b51b4bc26efa2508c84c25a022b67fe2b8e20c1de23c04d7822df81a44d003d717db028f4cdb88ac5dfb52faf26a4de72059de159ddad11569f95d183d3ee45c9b0d83cdc2605cba6288eecf6cbbd0560a694a3224ffc33caeb6aa2f2ff1b46498cd298fad9c997ff41791e194de828995265954339b47e92fb445e360eb062ac63b7b859615c8d16683332f4898aadda5df2ef023cdffa84eaec253c3c16a37a0f1f3bca39987e9a95cd031fdc0e5ecd88dbec168818de87410a095203062c9c262ba72fbec63a83160b0ee06d89327e2c3190449a3c2db80a505fbd73cf7dc6165d9200775580b500475d74a30eac6db79a14aef686e6d6992f6cd8b873b5fd9f4fb1dfb73db50bcd372d0c8eb6cda0679cbb04058c6f1a044ba60d78bf8557cd4883afe4bf2a760cdfe0b329cb0b6210191b95522a4d8b2ef1202cb74484f15defbaaec28574fe24258f511c39a86c060528450192192388b3ce1f93ba9c4d66c57b1d21bdd50268706dbc522a55e35dceb45fba073349d42ad186e9714fb3142bf04f2de381154bb441d9c95d6016bf1ace841d9a1ee41f2258e82ba44fae31087363377613a3adc4d72b48ddc9035d2b4dae41da8b4cc5178019447bf1bd9f42df184e4ed28014a148d3fe8d3bdc8164272ea2bb827b6e0991d0f7a13b6bd804fcfac13bb92fee90f607589402e9d6399f29c157022255840e1a273afe806ceb89106e72a375fadf5ebc58c7527b3ff61ba79e3e54dae9f711fdd6def9c788790e47921c917126abd3871f1b4da5bded5758113185287f9a09506a56d1102e4bb1faac5ff864f3edbb721e2fcd31db44401a2a07418e3857cc25fd5894918dbc6a086051ae3edef0ea0a4c9b7ea67df496ece33944c509bd8a1688932b518b53e99e8a0a1474f0776e39e09b78f17ed4a510e95ccbdda95f78f6c36a5c60c45ed27ee95a947a71ebcd5f8cf29e29cadacb0980da7220b6d1a86a3e7a950cafb04743d1ba1ff545648b792b2c5fcfa46b67bc4f417a9076ddb056829e4c31f4a0686cd6e6309f3c20c7abc8bcd46d463686c0b017d33d2a7ff7a40171a14227749fe9676061b04da2b555c7ae5964318ee3c25aacc531313947786fac0ee63a3f8bd2e1e3f14a3a15a8aa37dcdab6ad653dd566e2223ae4a0e3b54a3d901342e90077fafe939853ffd19d6c366a85b03fd406ef363858f54071fd185abaef10a7f558511694caf8acf6252c86f83c2aa561f103377109686e4e1addcac7f0833fe6d265bf6ca9e5a702959794b913d1d0ecb93d9b47a344f1d8df4a390a1b6cfabdb5d8f1097a359901acdbeb288bed9aba9f46013afb43335102ce88161eebc14bf834cd8b515f9f09991ee2f0c277a9accac950097380f37cdd4ceccef0a4785eb87da6cab294a68330008e6d62a9f41b531cc342ce28ac183dcfc87ab10b09788afae3bcde6b96eafc36326b67d54f60ade6671d2c82a18c0b4135c985105e6f66802de02d3f3a3cdc68faababb94bfc51aac1bc3348e3661d19621cd7002dcb6d5a115641ee6e0a15f11ff7e67c63ef928a07a785804110c78e22ec704baee1a3445b10fc8013300e8d93c1e54e689b2321e808289c88786a2facbd21ffc70cd0e8d535627ced39d573719536cd5911f0d5bd0dcfceb64a1953ebf5febb38b124bc126cb33e0bf2a41de254fd158a144f26fd8238cb3f6f354573cc28918135f9f044ef309e1a01e21b141c601eb59cfc3e8ccbad2ffdf6b9f7e06ebcf1e1266a733a63d3f77585e3144636f110b38cfc27a6a7abfb423be28680d7300d4a98d3384a885ca8bb844882911773378f492fc6ed64afe4314e06c3f181eb6ae13894ddd98edbdde14fd233c3e2fbacc124fdf14f25e3152e7e63bfbbe9ecdf8aebde7d50662dc366bc13b2297ed1d1678fa324dc54bbff1da442964650778270aeee1e54c474936cea4584c992eb8aafdebee6affd02f1266a48f88b4671e7de894b6ab70800eec0135b4cb2e855596f34cd3fb8e854b3f334b49f8b81a77b1044c3afcdc66e0f7def3abc746c4077a9055a0acb75acb70be28344159605152207cd90f21150547579f5bfadf5957e08f97cd32d00e0fc1da94e68942cc779246aadbcf13f0d77cbc512f73c18f013a78967480f5d84419bdc88e9acacedaa0833bb62b2c6bcd158421d981bbd757318e0b744a8fedaccab40158cb11ec72616b7b1d4aa5298a917fd6dd4401ffa7011dcd448a33f2c58381456411f5ec1ae23fa846a7ece4160485cbc097610194d604244a2318c2cb49bf2243cae2d4f192b30fdd5df550fe0cc81cd0e56319e0adfc23a86cae29c6611cc7711be3ae4de49164088c5f94be9fe96bc612b9e0d78c5f61914df496c2b02a800d07236ae99eb3f905119f3ba32448cdc2a8bf1fbc896d5f0b6d6d470c878df893003ac97f11190fd0b46c83b7b0802a42ecca67128e58dea5fef8202aba2ac86ca279945c7d57ef8886299ae8010b1aec84cf8d13c7d9e855bbaea7da2402143fb87775601507ccfc6c8dc99cb029cf760f0afe8782843f218682f20af2fcc67657f364f461d072707fd8d7da6bcdaa2e018d85ae18e8348aff31df3121c12e5a04db4c0e126ee76cce53c6c22b87e11727f88aa5b554070ec6f259c0e3f5cc3808b2ac052ab350b457e06fa71ce57088c24609f987ec9f57d6299d39a421309d2e219e160e4a006fe7bcb9af44a6cc82583eddaf212bac0e5f9993de4b67fb8f818ab1d0fb4074c2e82cc07182639555b41575b1dbcce0979e73a49b2943e0918d9cde3210fe0864f66a186ab999ff91b1bf9267d375f01166421a18f7d739e3a555dc2f9096a70ba85b93e893bf9d31796579eaa68c66988ccd9e7ce295266db12833efe1924b6a9ad58676b09f9499d6bd59ac1cffaf8f2411919e1ff060969a9b5466baf26745c19ba4171c94b171ec351de7cb2fe387730ec0f8ca01006e5922abab8e6d29431ff20a6a58a1fac2741b17e350a116308b217b2441e3c02f9716a12a5181e83682bf7aeabc075beb0e2a70a262c18f50a8b0bc7b88d6241e52d20b0f8794fb412e74d9fad2f866e11a81e0c11eada11c2eb724898ae66aa8189018270c55d73200d591cb6f7d29dc5cd19f28aea262302c6c3aedf5f02022c1e34acf60447fd72b8b56a1cb92e64af19e92573f1cb9af86253417dc1f7b8ce122c4d1785feb5bb3a36aa09e073b04ba2b76a7cd18f479c5c73cb245e58a1bb6b43eae51204ea8ce8442f1d35462a1e6d2329fa80dd4879913638e32a229e64854145b781c84c810644481b3b775bb979b05167688be11748facbf724e7f32531f41f6c9cc31388a83d20f9142929d08c3a2040c8bd1c49a8c4df61ab7bc5975abcf5920e9d10b64085be6b3f1c25bf382633f2c05af3ed26eec8acfd229f8fcf8043e23eda0a8129cd81bdb46172207512cb161172f22cfc543bff316123d95352865032daa6103fce32af95fc93928f0935958dd67347743ed30873e1e55b2efc084a4bae09c49f32fa25f2a1535add6ad226a56c305176bbb76c0590da8c640de0bd0f20576c20841ab00bdbd72fcebc5f8001930868b8107871cd074e15f5046b94c3eb8924360986fdc3f6c874409121d8a3a796d11f1b898419acf55d6097e5b21c4d78df4939b78fbe4e8784f82243548916617a5a4136de1147f1af37fe5a9a458d425126155a4162bf31b8bd06a2b982e0f51f48b11672fa0094b9f9e2e6ab5f18ec282b759b6cba1847655853b095878238409b683180bf4bfe3239535cd169eb41f24a0f3362f5e839063ae20149453c5bde765569d1fa2a0c9d5dd4100c4a0a8841c1782bbc7b7018d6a20263b2ba4a3a4eab7448fcef0b117ad48bf4a20756466c11108b431ec437a655474f12d26a5cd021509fee1345822ad655aafdfa9dbde39f3deb0ab1cf65a015e1ac3414d82c9d086b2e5cd0c51091e7c1ad33063b990ede7046284eda0772561666fad7de051582e5afd9692dc11a91370957a6e5152a749b6f6831145451836443c47dd1a6b3a4798b2fb1451b4d23eb3fc25c2813e1f0b233ecfab93d321bfbf6bbfd6c1c89cf03a574f4d937ab77062f238c78bda6692f7489d8a08e48ee808cfdc2031d8d9596321aa5eed2b6acedc8281bfe5fa539d97473f9895ba8c7792acdf9d2eb7ee9320cbcd319c02289b83ad125470d661e9134adb39e28563fb6fc96a0095f287019a3ac77989dd07e88ee2d74b033ee611cb94c35ff1909ce18ea57a4549dd72be22d3b8d7c07f4c23227d99bcab2269be611a23b331601ee5e951f3b282fff9360c37a9d6219487cfdd73609c0fbd438a081948be116919813f6b65d30f8f48d2393a7d014181dd953b0e4b745a87cd5e6913b31fb0551864b1fbb0b521e1ace362efd4d1b2304822b03a07394bc54bea40044777c25d130e01163d450d01668f53fa41d12dea78ac56a7643d2091492b7dc0c2940ec8c59c96f834adc169ed2225ad35c79cfbee6f516478cd65d885aa6dab7c468c879a887af9c55f221e6987b311e58749ad50f80aafdb60c075d08b11e66c29d24ab503396989115b111c498857da257ba97b1030130bbb13babe735fcbd62fe4765b91e94c3accbe60971ef69e7b33e5f0f327211f02e853886c4740a560217c414f7daa8c8b5629c1f7dee5cc1b9b7a175a25cc9a2e7c03ec4f8965fbb98121d7ff6c93837cb6f111601e36059a1de5038983ff1df1b159231527d59ff31e9d89ea3d03978aeb5ef386f0d717f51b8eb40f885e791a110599de30ceda928dd833937ffaebb113f20a8eedab70d34bb35dc21afe5969f168c033be6d63e03e76992ba62b6414a2e00f607fad06dcb1c9cf79cfc0832d023487a863934e550aac8419877fa421e1da4953a00417d906a92e5cfef535b12c755ed9a62854a940943c1aedc23b6bca2bbde3dd63ce151bdbd7d4f020e63443b370661f18833c8b5c6e731e304b158c477479ec85c1ae167f72efe00315a1405266ce90004582cb8e229795c0efe6dd0152aeb4c7ab9e30ec39f791cd8abf4a75f8a6d25a7e99ffcdcfe8c9b9471a44f3d282d61943451903cb7f53fd6644e231812c926e1e2cccd55f3a0ae8a423df710297183e07f7415894345eba1c5cf6a270ca9814fbfb0e8d949e563ee9c947db3bd2db6795323d86bfbe089047a3a117dfc4bec4e02d0daf753bf7357f397d6f1ac2bb640e7329634f89ecb7593a74907d37cdcca0f89817643aea80ba9b89ab0a0429aa408db1cbd74bc8910596a3b6467e00e8e1b52c402e7f21ca8fd1327e9a2ad59fc4aa7e2930f79de0769c734e4e5bcbbf6fd28f316719f7e0e4eae2deb45c8267f6141675b4ea3be2528ea770e71e18330e1ed194763e298e1144bc839a1b1aaf56719b4f25265233987e90009e6e3447bf6db96b4340787bd9d193375a6e1ec3bdac922ce56821fe8472e083f9e3bc756c4fc7251ce042f1c3c2a2c9ed5c6538800312dc879b3edd4d14cf05832ee5ec0e778928b84e3196d3e544ea8e911b9f524984962f5045cb573cddf147eb59b75f854ca70be3ad4ed704ac5b450e891a257eb8956c6b1c35cc8db399616c2a59e5ca397bd597274cb77393475eb913ba27085c442ba595d9f5548d238bc7283f8d34b091b9b9db1544e06bb4cda061fd366483d71032f4ab985fcb291fc074a90fec54760ac2c8e0f9da905de89f211239c068921fc0c1e1c873878cbe99dad86e69453df7ee247e5a67ac6ebe51725883f46187818791a53803aa9afe1ba2cd7906718663ff3788f2eae069b2426f6a0f220f4522b09f41453e26a8413d53c3d49cdc9555e62901a3ff336c232e768d01062710adf1bacdc3d06ec3f957eeb8374721c66473b9ee5c44c05de36b580088d4156eff5f86cd1b7c4cb69d08c8143d8e6331089ca11c2b63530c8ad7e4345243446b333ba41f3aa4af8241bf57c4fccf6ed7cbad5dc44e7e6bb906e56226805e866461acb4282b96211d1289c3eceabfa05e2b7ff936426db62faa8e7ba259f6b0a546e84643316ddc224cebcb645ab05a6e1d268b0a391ffcda4b25a5147d7c74dc2695905e4ae78f03214b153f01a6fa6067ceb35ee4e62ba07faa18eebdf63ac1b8445d4dc6875a5dbb246cc0ac7615e0dcc3cd648d4fe4014b0f81eebe4245e231bf022efd8b0397a50274939979a4a8011c76e31358dd49b4e4aaf9863a58ad704b89c3783939151897bdca4a2fa2d03f46c45666dff3ab340add0420f240ba78317414867702d98675a7ecea8ebaea46ae30389e3b4a1cd8a0de8cde37768682fe7ca2a79b0214ae63b2c10c32643c6aa0d5ae29fc6b9f6d58f0b70e286af3e0b0c21da79401cd91e21c5fa92a743230728bc518ef1976a82b34afbd023f9a444120c73551916c96dbcabecff4f2bef10ee45273ed7773ca0bf45cb91803b68c3db66ab885ac56320f43ec62f2ca237e22cd54e9f945144031a80cfc7b24f27bb8587196d41a5b8eaf7f1286bbfe43753f9f6fd8a9ec0bc314b444fa7d45bcc7b7dc047428d6b1f7d4da32cca2eb45b85f8d501b8611be8baa4df047af23ae530d8f79cf86b45354e19a0d115f0dc2090b20cbbbb41a7f00bbf01b765e0592b2d0e1a93090a04c7420e56015d5bf9249e644c5528859e47babf995028c4638b6a7c688ef30eac54be1ee30f4e6d0bb03511a7f216caa637cafff10d8ea59ff4390adb6a0bcc0a07c7050196efb7050874e46c042257e54b7bcab234b3b06dae1888d0f298a3705fb396e0189a1805c9020f74d0a5b64e245c82cc67e3f5661628a1e0d2201fc1256cc6f24b1b20b65c0e2665830b6ad246c3781000cba8fd5023e8f87a372af2e4278af937e1d0651351e482b6634aeeb9a1c84acb75d633aa1a1d9db42ed41f6a0cc995b235deb48bc7e17bdb8ef6d93601b9f0cf4586e029e498bdfaebe55aef32318e7f4dae95cced8dd1dec472b03a5124dfa2333ebb7b06bbeffe2067ef7baba0f7fd544e6faab89487cbd15c38c0c490959b33a342780815ba2086c5304db7eba8e334dcd4b18f6709d95c1bbec16a904735b8ae362090fc6622a61eab9776b8e69e0d2525ecdeaeb37736c984b5dde502e46b5d9b06826748034368a06c8fa5eb399f53686d95b593c1e9c790a06dda6c19bd2befe7eb90befde4eb626ab97e7e20e1fd89f71e64b4e292c873b5816e8201b693ce6a57195aec8713a51c2fc639817a040fdbbb8e58202af3d0f04aadb91033d78c6280b98720b92b59564cdf71a3e04e799b02c4586afecacf721f86239b02f69c18f19261049938c4870e8e3d5544d13093b5c554d490c3ef874ae70aa82cd2f65d8d3fe872aba54f53cf1bc3741acb6ca340b6362a0a4bd07fe6248d4838a3363327670ab5de7a56402d12c624f7d0d9cd920c98d11a23726399c134dd599618b28da584a567c7ef56670b71521b79bb329f21ccde714ceea646ed2e95d6a07ee66c683b5aca7a7c436d6d30fa17859bd90f0df4c60aab02e56f16803b3695ef8ed0de1967409ca659c88659ac58302c2ec613300278281863d726ba8d79802cb16094c688f292e99411409320a8c36f3f4fe8405f7ecca77f9f502e60b7218134a3a3d2ca067d46004878643d75a17d0ca0d4559d7f0c908b59d008b17d5f74f07833f5c30d75874d3f5657f10d50cac3d6b192782a338c7871804fcbb51d68bb3c84c737df5bfed830322f18bd0776a6263484c12e19673ba04f7599232e688749bd6676c63bbbc982b2b6ca659a0708952aff583ddb5773b5156410d6f837f3e0d68ecca1a6a2ef6b3a22fff66cf836644a6c82df5d3263155506fd7c672ec4422172d339cafe1d06000ffaac03295397249d4c5d50f910b5b19d0983e4ff8a9257d3b5e00949b206f80776abda266f35e8e10f8b2cbfc20f0032babb2e2203146cc4991cddb50a4d7820dd2882fdd38ce5451155c793344b49574a8df3c220deb0cab3a00b2048642765f2e7e5fb6381d4e5bac3c84984bd2d552cd90c028ce105265c6e436f9c86675cb3e901933e4eaf5e788a4576eb2ec98308e66b817e979ec5cec4a829830bef8db54e5f6980853b568d47edc59e08c0fe668caa143352a511432e09a2352e8d19d67546a3d932ee4fb1ef0ba28f59b2131d11d9506c31e5562b33dd64d0a2615e27d8ef1adecf685c9c22219aedc2430eaa0d1ed5df57028263ad4bbd2152054263b3077326c597cde5eee0aa2a211b56bea0b354288e41a23356f7f579d8e4b5d3e44673195802c4f45db8eb25ea17c8a1a11f1da7f872c5bc190d661c1e9942ed60f5d0ca9eeef6ddf40779f8ffab1b27d7d60bd4a37c05dbb8ade0cc2a09b9409056b5cac18245f1234057aeec25dfb80054a930a9c5b240f72a0dc359beb5afc3ef9cc6cb6bc203659e65aa5d8c12995cb7a2f4c82b6dc3d2741168dbefc862ef51111aa0f3bed671b3f63c0f336d286957e59b8bd30e96c5ec6b3022f82bbf51a1d57f2f974bd5cfa574829bd24f8da5346db6de1da264c038ad78c161e5464ad90b7860945ab206e93d273a5a364fbf547f473b0426caa27a561dda4369cea902cf7cc184478bdcf9b14cb9afda58ed7ae0a35315a4c4cff764b205aa392c59f757863911b74f5db96301252dd9256ebce1b6379d4ef4dfb40903aa077d29cf0e989378e6ea1f02eb62a3970306870465c2f33b0b5af9541f96567fda40bc6966c5bb9bcd4d2554ff7d4659de882d44f0dadf25da4f32c7d5f9a9771f2db40445495425e725e92a315e4ce5a5c7f24cc2c0fcdc591fcc7c68ad990034d44e13952f6d20135563f2225f2fe208258e6e861ec2561ce8b73a66b6488248a02e84d931457c42ab4eb0bcbc45fcb0f05ebe088a9cbb6d8677dbb02d7e862c3fa988e2248e1ecc2da36142bfa854cc758995094c3041e007e79f6d55a027d72d13279c18c3f27d129f42a336688d7a11f46ef0148f7d8e2689cf80399c9b0055f499658d0accb3d07103d0d84ae85733262cc3db65344bab5501b5d2f9b329c730c80bc9e3fdf93b70ad5890bf29a31b9f311a7b1d04ee7ca5862fc53ab2981ac8b2646c3333c63570c61b4333698dd99c94adcca9a91d2039fec768e77e7ac1e09033aa8546f57a3b282fac78e45e7a0dfee923c7f951851d76d33953a0fbfd3db49b86165bf09349d83cfba7d7a06b3d8aa729304f4704af9e1bc9374ba4d62dd3b6dc2363552a265230721e83447711b5d8f0f7d480752a00d2208d8f471f7e9ae4fd6f3d87521bf72d28a980fa8b57808c9ac7a6e6677e0599c7183aeb4073b1fd4425880fd5e1d61cda3b6edaa43b9c2b6013cff43b0e103e6e72af393c623e5f7ceb6a701ff0ecf84b4f007f581fd6df1fd322adc7161b7899b43c0bdc9c21b070a4e18b09d8c5c751f201656a1676c6aae71887ea78e62732e1373cfe41dfc57528ce4c215eb0d193a6eea821f91b4a41ad69d35dd902bc5ad940ab9668b2e4345de6740e1b659e9257edd6e7cd5d862d2fb702e1c83796dc8c8b6d70702a9b1173c200a2c02e925c8b8fecd31b3e2952cc4384b9578aeb95b9d68a16e98a2ede1a467c21f2beaafa743fd53fbac65b086085685913d34d06bae064d1f96d2973a29ed7dc9cc988d8afa2de7519602838481958f6e7dc3d72372eda53e80dac366d351b62ea59950c90c243259fceefce5c463fe208306e50f9db7adba72a96564e0a2706453ac610a7248cce4bbc515e81190f7735e60da034399e6d3bb45f934783d31e4ce75c271542dd02104db298ee25d781f61c1a4de718c055fa1c19e94cf36280511d9d040385ae2ae357577cdc9750acd036855be008fb67b4c09b55725c5f25759ee014627dddce0f421aeeb5ba11f9c74434f48e0095542e27f34fe726bdc50d126eda690b0ba29e19bbbe6db899c8950a7d11ab0b976748b1160cd4d26d3df3fad69be96de6740268869e57a06e198a5545a4a0ef6fd61fa1f623fc205243661588dd49c67234526f2d2db926f961971f89f9924c0beb000aa1e960e73f28b4e020e42c463d8096cca6b8fecb537992ec42a5fd44430e1d52a1af849dd307ad25ebbb79789399fd11c7e850dd1e87139fbb37ef738e17a4ee5d30a20e6ecd26d2a34486d16c4db22d8b2c8faaa69a2e6d66cefe8ea9f00dca243de5f3d60e6a2c79c5da82796eac34d6ad628f6660c02682e45864fca765da45c3d7c85b6012f6df63adac28d548c68ed119392743e036e035387a0665582fa8562a6f6dc7b433276c391aa39f4d7f842bd4cebbadb7ff47bef990dcf70a6a5dfaba753b7e2e740678bbbcd1b9998904fd828cd1f159220258d9194c42aec92894938ed1bde5b1eef523f58a4ad9ab4d5357811a1b7281b5f8cd0050132eb4657f3d78e80aceed00a08eaf015f0f3ceae6ff6f0cb79309bb0e30c24ca474b0386b9a27b547e045165fcfe94195cc7083eaa57b4e4092dffeed7ca48611badab012c45d12f6b757219d07d01112c0a04768ac05f980d9bd756d12517003ac125476c851e85435000216d9682762a47539524c006673ee15bfc28d3ad8cbc442410e3e9863f4d5adb2b7699116cf8b05b48198c13a672c5078ef3e146c2877f3018b0df69d10d4b93960f9f0e2bf39dd5ac3cd968b5041e80bb29058694a2603ae3c261a57eb1b9b8f3b8c229ecb1d589beeae36633dc65c7a9482cbe14aeab731ec3d790a56ed06175dd53aefd4ca29372658e161a744af9f9d9139262e67929db10bc483969e96ff1f7189eecc03452a9cfb409483fb5d3342e5bc6fd0727b7745544bd93022e91d32531a9208f896fd1dd2e2de5506ed1338d0e7af99caffc8be54742ba689ed427e1b44176aa71b4de8f04f2a643803683eb0f5ffdc77ac56d9145abf6f3929dcc3ced75f93288e892fd00035a803408aa89d9b21d005925fee6adcee3f547f77b94556117a24da2f69cdd83ee2c35216f06d1e13931a6ccdbad274e1a6d550f24d01ad1c9bbae78aeb49da115d2ca3042fbce46f54b477351e737b655b3ce8eb64762a6ac4e1e64e033706f8ad12569c01e7817242e8c73e3f96cafcc3588447c34a61872c555405b9540f1bfd1b241cb1a29a9b1f957216821d694f02672fbf1bea68175b35a9424df5d783eeb9d584d6d25b1bb2789024a901ca0f7260e77c7b695052e53302f4cf808e8239e914d14230c4ca9fe2048b4827f79c1a940b80d3c094a6107cd14069c29b5d6c269a52c40ad1e8ea70fb8ec699144cdbe3bdd9c61c44e31cf854a720702ba30f736575b9f45b50bb1a3dc526743c737f8e14e0344a7896563a7739ca4504a64e6cd9d6079ff9cd529e599335d08b6f63db2578c65596f99b00caa16ea492e55cc98f5cd712c2d41b32c40f8706d433dd296ca6d07007b97186b14e01602c81ee555413aa1b96d48b15e4a6d25627a283c088bc447f30b3c610458043590246a1876325928b881fa9a753dfecd0fda1aec7a857c8a53cd167ab0cb0be43175055260781cc2ab2d97ed54b9d00916fac85dcf42403d1cf1bcc84737aea5384f3df9e6c88d8f51e598f86b05f126fabcb841d3e9389d0b85bce8ff695e4850508c02bb505900a369777e22da13a713e74b037f1b8051f93e8752dc0399874aa58eae2c016b49245a273c5d7b044d75a48f37e294da2e4a66a1ce4ee132b39a22540fc26938bbba3ffae1884695d54909da7e48307260918976ca90e85ec226002cea03e875f2a20db2f0af53dfdfba8163b09b00e17e12ef6861a36491e879b1e998e3a798eab5b4b0f5c8db7227414058fc47c5888bc6446dda4cbc8feefd1dd54bf44bc9887e8d24ddd393a2d9cb11c2290a080f01cf91331a556793871161039f50fea0ab4927ae302fc2ffaf241164905d6914d3b8f8978927833475e8a33c35b73e713694e1bd971abae618e64c14cb2563b9b3033f3a6890dfe320f0b2019ba1c51ae092d94d859bf5cc398b6d8a369bb5809f2146b1523cabac000df9585d99340f11fff13f66c79a80ca4a2d649712927829e29604211c30d4ff4c1b39c85480f25303d7815b352b0d2cc38c610394d9f2aee7fc02c2237b54df400ed18d7a140d76bd7229d684a5fd4d35cf77ba6736292b681a1c30bcedc660d6ac63a6d5c1c1f402b4f1bd7828e548083940c54316d20386a3208c1860d1245740b9d2b89e144d8b67c2e08b986a53d74923495f2e874213c2c5e30ef150cecfe9f6d18073880b6704a1f7629b23afbe02f17541796a2aef87b867d2c1b07510598a4ad22fbaa8c5d25ade0d2465c6d6ebb0438c65d9f2e22006e2b44d15737f32c4e50e821a6fe9bf07d462ceb799a099093aa2c506b5f0cc7091d77c27beebcc0bd2b949c14e5fa826843ce2b5aa76013e2878e97b1d495c54e01f2e91e3a340ff3c597f4e715188ce376abc3c96f7376ec3c08c749b9c015d6327873fd0d736b1b15f1e361f3177fb9cc11a20f58bb8f3a11ad43493a48e100fab0101e4c7cd6fa9832962d233a491bdbf1f9362731b6e3ebde5b0a9ead9f7ff2e02ed619fdfdd64f2ff21ec64764edafc7444b2ea2220c4de2ae5312a2d8fac398fcfbf10bcc26ea961fb15905289aa7d406eda3c5e87487c034ebd84ae1f4e4561089e5a3818b330f7806c8c41db5a7a8881afd0a5adf06d2c2bf2fd5d88db0f8b1a895a2465bb197c9a61d4efee991a2e14ba1a48e7b08c376c409687cb461975e103f6077b03a8f7f336795af920cff4633712f38efb4fa5e60a34dabca11e7aa17acbc20f010527f14fdf430b885a7774ceee6edaa026516bdf744bd806eac0110937f4b0b3f0b63097a13210bdb1800deb839cff623a7b628914e2309cc493644d7ece361a0c1b6debbcae430c763056c09a71d4a5e5088ac86f9af20be462d8b9cff8d222deef4578a9b9029bae0da22251925896bed2bc4df7479d167aef1823810832c5a8a333faa93ce547225749af8cd913b95e0fc121c5c4099881133e27c7a95fee1ca2458008bb9a30e719404aa5384f562dafd56eea2c3c8b6450813635ee29d91eff776808db9cd3c981f4c069a62bee7a6812cf826418347b0983b297dc341d6ba29986dc9f296bc33398bbffd2856d3479e738cb88d5e01508b2da6fa70a2f23a2980295a9d950c7d2781acb17bd2d4f8c0219684790b794859cd9b87d131419a8f04338780a40118f9a23e1cca17f12eac357da7e32ec1aabc01e5ca0b187417b5a0d5b5ed1c5be3c39c3d8ecfda4325ffdcfcf068a2fb311ffa414bbf421ccb808efbbff824248c4cf18948edcde86fa1cd2b16dfeb73c5dcac9804d4d4498938ab598ef083cfe8ac5378083f61dea74a7aed1d83420e0d027b3ef42b0e99c08fb30a053de2f731353cedac5d6bd4baaeb30492adfa9687a2bdb8976ddebf20601c1f336c1c2c5dc49e01c913aeee875daa543088aa788e319a089443b223a1cf58a9067fa7a090930ca41f03313238db7046ca08981569244bd0929f4ace6d4e1354ae6f4986c8b5e1dd038c9306bf51c19062d212084dd5a5f8bbfd8d5810e472e969f58da736056fae1833ef2f04fcf3452f4cd626cc74543f5e646498394b8e20054d5bc02f973b04e122e620c45de4b402c88ef352e80e0033802e50f8bace2476cb4eef87591153dd8b1e2eb56639d91280011d977b0428141b8be93350e8ccbb03d718f6257e9e98f08c83d8eda44a68543dccf2236858d5ef3cdf69e2d1ce03de59b6dea0087551235edb44c696999925aa4e460562415b5954a9a0f6a390b81aef44cb6055175870809c241bf2dfa85cb972cfbe185871a9474e24ffd74b8fd88de6baedc0f2c0ed5246ae1f5c6a8602cc9ac4bcb215dc227d2921b2115c412f2139b1acfbd2ffcbecf486c8beb00286021f8f8a328606913cb756736a01b4205fb203a48632fa69f2bce512a5fe92af97561a0fab880265ba744b226f630d8b28a17088c71f575deaec39bb050c56807f2db9552baa17d4139078840661046cbbf53561c57d880364e7fc57aa32f44df1b3d47dfe8d98a7604d21d6eed32b4020df4ba9f86d006ff143b240c0f89abf353a6cba5874166dcb622db2b49eb82e3f4e24f07df5e580843bb0b6b920b6f9936c6ad0929f7fed0c267c9a095aeb0723d365b80b84b92c14ca840d3dcc970cb0eadeabe511821892e555d1f512fec4f7e944e8cdc30c248f337a7a53b7d5c9efe33d61ec2736d2792dd072383a04c1b23f72cffb1c3f3bbe13bdb919193dd7207805ed7216541b2e77de1483ca8c1e46867ea8eb3ed2f4811a7852d9e5970580bc661ac4efda99450ac7edaec165d4fb07221de8819e8a5131126feb32d6b933531a5035839f22819a058dc7f0712a36e92ab91c7ab986694fc353a499caef040ecefa204009ae1b5c92ed41f48fdc7d1635b33a10d65cd18e769dd8802155aa288a0ee10ca25ee6560bd3d2f8a43df7205aa8eee0e25aea098412cfb5452a5d1f1c0f21afe6e06fb299bf08cb8df63e6c6714d5e6ff2792a2c2b964c3251ace1233a6ebb99af40c11200bc84bc99a769c83411002f73eec6cc709fd51f697bc8a8020311b8d96621601c03d24a1ef476a985f03dc5f2db85e09ccf77cde081d35e6459b692500e977df243c1bb4924afe4dacaac5d3ec02096b5a5431cf14ceac340259348cc4d08aa426e8512b1baea292cb6cafa488ed82c15bc9ea3941b6526c03876272f52f0f4c1c05105d5ed50f4b557d922498a0624e3dfc13f3159a8e578a3ac2b3025426d8bf70ce1f134a0b94c9eec205fd892adcd4345a9cc558eb0fa9603a954be512aa54a29897f6d2304280c0bc9cc4a1f398a94534a09c12d760106eb27961c6abda1f8d7739226ee55668a8ed55f4897a995893ae3e33e0e45bad3ed2ea5f993e934e86456ae7f66fe522e1dca55b789714f81cc3fc61a8e8312250b50720dadd8c2a1b08b4184e1b11ad2ec643317949d12fabd6551407fb036bab785eba712d5e6e4b2be12bd59dda88b14e0a02ac53080bd8073e30737d8510f0321044dedad7604562417871a00d277ca37bd5445951843c774e55caf58323ac8191da488ada225c670d7b973be9f9ef79e8d008efaf4d3fab82e31b5ad11ab170dd148e213bede87d89c0df604de75a70e0d7a05b1c7ebe832b00ad314a4e47ccf1c074d2b17f7c6b1d4b6cf345634e929f6d64495f6980ebc725628c03bd8e53db0b2ed4aeda81c3e5a7941d068a01628689d1b183ca4c669995e25ef47ec91ff032414828916cc32e1dc5391640f381930c43709aef67fbd9b85d160c6c906cb7107975808c105716b0274ee9d2572d5faf00d5b5711fc5beb80ba80a084fddab247788d7c7cb2b622fff7623059c62d9e3c34cbab3408c2abaabdba82835b4157f08ae839b71814e29573a0a377783a624e90733159c18f27f8a266a28ccc2f309c4b66a3a0c067600f94ac51bcc3da2034b307978872867d7927c7169f5ecb68d98778c93cadc60fffe1d9075ce0611dd9452e3e5c60d29ee9c9cb9af23524b29092f2a7c7f47c1275c8ab57dba9fac60b2f8f6f021e402fd8af1d280a400ef1a1ef8f31392efbf7af3d5e5704d7b5e8117491da810a67e6459eee629560272e116c7a4e52a60abc9855fb86f34918f59e4fa994cc2681da0435b2ef2e7eab0692ef9c19b2bb14125206afda2e5dd05d9033c5afd1d5e1ae599a0c7324c5b5b6d75107fb3b31fb5c2f9cfd0071737c3fc25eaa85bcce2f6db46cd5abf0832b06b057f23c3db2b055d367f1ecca612855c087e31062104219d28cf48929085984f1c25c56020ea7008c21bd050f1c2180591067c9c182a9a8068e9dc180868972369a9317831065908765b35801795a863765b279603425370659cc12064b36d54a38ca2e3846453570760c010c49904d120397920c69b26c95abe08b2b04b057f23c39b3b27d4da9831c8e181a7ce27413a67c64c8efdd0ad574b2da32185a59f280c77155d9771f1f863138685206cbf46a38c61bb145421b6bc346053ee0529e492bb5f35f5976b73bdaba7bf824e228b5a69154dc86bf7280032a68f0b06ce48ddc646d5f34d76065b63e72081f416d557f531d21394c9704d1f1678b4528df9e3298ee1f657ef4cdfcbb4ef5914588c5ae12980bdba9e4d632a0e061119571a30fc9a63c3d907f6aea22308a1d2ddbb6791011ea418c320aae3e09e85a14c457f73880d1fd42eba5631d6637a33cd3987266034a584d94cdb5c64779e56ff98d79a16c73170f01040ef230b1cb7a3f27a65ef9b1eea9432c831c17c24683729f712230923d5a0e8dcd23bb94ce79d95054d334421d73f1030fc916e0e408233c6324842c627861bba20ea38c85cb8025361516044440e0a880d202c111083b82c23644d4854a3e24ceebb01af6f82707bfe4c06f39f92d477fe5c09f1cf991e3fee4dcaf1cfd6372767a321085902781fce7c864e9451af407c719cf662495641051b35caf07d5753da4494229cddb40ac94e3d2a78495e9358ae75699ed1365d4cee6467eb0cba1dc0c6c45bdb202450403c557db045838d2aceca1d6edf0a132b05d8d01ccab8322ada1b1d0e8b49772916064041d0b502c12101981e3428a0b04222170b880f2a26004081c15505e203812a183029416044720d8b190c2824011083b14a6b8282002210785116d60f2c4d8388be2d6c2481a939d46a75d6dda7144da55265d8fa4bf6adac958ba2ba6bb8d4fbf6ea2dbb8b4ebcd3a1f4dbdc6acbbb1d4574c771c4d71c55487d129579b761c91729549c723a9af9a763092ea8ae90ea353af9ae8302ae56a938e4753af30e96824f515d31dc1b89f9778fefa90fa2d660bc93986b227f2f0ea06b636d979867a6f7298da368c66d97976b50742a88a2dbb4cf3068f7a2185abdac668979f67517822845cd9c604cd55f214a394277be3400b0442090b3e68834898c0820311a459a01d384642d920f20365ea07ce8a369319b60e36348b77a072f107e364fdbd61d5e806f340f984047bee660bd839c9f495a51bccc12afe14bdd9bed5bf05094023a4cd62faedf8df55f63a8154544c172f434fe240b7baedddabe107fdb409a92c29d9006a42b4bdd3bf7afceacba44b6279b90d0458074af40b394329184fef007fbf6a61153d37ae70e7348bdc70c3831f4eb8f0c0810b1eb8e1c10d17c0993d6112b27eae46280c79b1baa2a1d005a0cb0c747f4b1b479d7bd8dac5643531f52f4cbddaa6a1f5cfef0e36bb406bfdf37b378c968686fac657b719b4d721ab4b056ecc12c552dff0d1d100cd75c8ea5242375902b1d0377de83c40735d32b554c08d6189fd23d63548fd8969804e8b21ec621e652b8daf0cc2392b970ad9a40ca9c3a2e55d934d9060c6c7c7f7c06f86275ec340b9bf745aa2a2acfbf8415416ca2ab5e02b5cb49e417b9d185299ee1a53ae3095f0cd2e1fb511adaf6c8c7a7754fe6018e813c2d81d1431893a73fd608efec1fd16d8c4c8e95b73549a2b134b51805cea9fe586ad31647b80308d6a8a27622194c6a8e4f87e19bbd61a8e4343b5b87fe45e6f180f0dddeafe50735dd766db693366b1f7549321edeca5d91c82631880c8501c0826a701ca5ca48a0c1ff883d4a6fcd909d04fba881bf163c29039df4d94b4809fbfd4299abb7358a51af8e11ea258842c433d2ddb5755c85c96350e3e392fd8a953f208dfecf4c190b5035fce518c418972e868146c856c200cab45990797a1e1e22e185ccd51465d470958abc64262e22016467a247f61a93a89834d42ee61d3f174aa357cc7385ddd8de461c5233b0bf8eb62fb31f96a7aa4017848bbee6af618b9a07a2f80be7d817be8a5b024a1bcef9f14f32dccbd33a7b2afd2a3534cf64dd8877c355273022007f3b6e6081c62d0c6e27516565194daad52b5161cb80b724e23b1ae53fe850adedf915c4d03b129a817370f5d350c62a2a05edc1e74d5308845817a717be852c3201605e5c5eda1ab06835814d40bb77d385d98143c134257373158e343729241d98338a4f216b341721203952f4e78b42f1c7723e140ec1b3227586a1e44a1ea77989bf27f1e38313058692eea05bfc9cf1829bc1342d76c6337254eb1a93c13c2afefb134e49db1abbc138756ecb0b561b939ad4c862a8f24fae0bb4c96a05da4374860d0f9f4e3dba90ffdff765c01043ee423efdf7a0c2e60feafd9cfc6bb5e7efaccbec9793d7d289b02893d24bc027ce87d38f0a1f3814b9e80927f695b70b287fe953c149be776b1b8500236e9f8d0f6d6751fcbb0cb5fa8b0a8bdf713c94749d9647b61b73e00b13b55f42157fb944fffbf4ef6989008e99f39e6bb1313325f6c75d4d1d82a99ab6db5f33f2c30fe8c12428e2b40017ba9155811fa26102b30fc4f941094789cff44a6174c3a756a197cd81c31cc33a0bf9f832a02d2ec109d428ed0de52f87e1a97c5dc9db3c918629b66146c3d428c5a31a3e2f8b6677dee9674e46679a6805a4cd3267ea08e157b0da455116f33ae5beaa52dfe712610f4df9e4f1c0d35b7420984898219322a26eee485293f19a0e5004d4bf7a3f2b7c12bac13856db50613a54740050261c4f689fa40bc8b57b525e40a5b0d86b5a70c15d35661039fca6e8e9163e3fbe54dd00c6a0cac2ee657270e139792a5480b72c316eda27b8cd5ac5995cafba6a6a577e4fc423b15994695185c3dafd669eabf3c217a49323be04f65ce4b9685f99e713ed61863e33f2858706b6fd1487901c5ae31b9546c895c7e962d8f5d0b82961c7a19c27058519e309e7f39c1278681543a79c7da8473824bd5657d38cb0ca736aec88941c61f369147768af65c060f254dcef1a9a4e079fd8ea6249ab018840ca408bcd859614426f1c0e2581895d36dc81708104fb1c9fe8595b22e96531a7e2b0d7670cbb1bcc6aec0dabf438e7ac06c381a7e2022cbfb42536a9de89245163c3cfdd83a62834facc8028d4e7605fabdbe01a235f3bb036e099fc4a8c4670aa0466fb1018a0b9475f230ae8efb57652446d3982cf26ce7d68a7d6cee7f5f6777dc7e01545c75c4689b56e2c6451320e08a07a4feddff297849a8575aa5a8d4975cfbd3ee3220b8dca4df0ceeff65e7ee7733b73f58837bfb6f271fb20b147907a07056bb1cc5903b273d2a1119ed39c4fc9c159dcb0712a900fe4cd377cd459ecfe010c2b69b31132a8774dade178a8161bf237ed5f39d6c3d98f8848e1280c5b559eeb8a1e01b7d8a7e2d905e939041e7de917cd55ce087e5910970ebf1c630eac9f821edbae58ab10c8c5ff9dfdfbf98b6a0ab60941d793f1fd39fab301989c03edffb44e148466a3d27f9cd61d05d78618922abfdeea311e370943f28d2350ea0230e2c058bd1b720bc24f5bc37a00fca5deb5e773a3389bb71488c84d5774a45cf6a0e31ec88f3a0cd4833ebb286049759efa8836c58603fa9276921ebec08788a64b1c13c7e476c6599725295223fef4f5d4474bad6c1142d2f2434ad586535af89fda85dcf33dd0f79b4b2bb1e40d457bad68baefa7159b0ef2d63bebf8888d9567e8826bdd50968cc43ee55636507da1b473a82a6b5e3c5baf50758858a11a2332f0d09ef0a2f007fb471ff940832c83eeb09ef870d5a31c7154655763a37151fcd35400d3f3917b537cc6e79aad6a7e5977760578f9e3bdeb9b641320dc23fe75a25a31df2cbf3cb1c731a6ed479f77e8a37f1fa8982ff090f57fadb15d2bbc8313a7b6dba46b99e043773fe16562aab6fa49d9c99a17075ec165571482be7f695bf5de56eb7f6db579c76351fb68f81bc3e168f83118f395bb9d44e0b125644f89ee1a89506154ccfd71463aa8342515d7fd00438a36c9cda536f082a7a8b8e0f321bde03b1466f011dff1ecf2ca80f841a9d89ce0d7be13998e1b85a03dd9139e00f3276de07b146db443f37017385e6ca2c0e653528d519043126d4ae4d0619918ce282fa46cdb1ceed74008dd0bcb1a6e37e3ca5763873dc55a51d140819a617cb6db407251615a169d54f8b2045c1eed51e2ef6173020dfa98c24247f71b23f148c011f053974497575027fb3d63b3bc89429b888601b590bafe8419187f65416eceb871b16162e5df3712497077e63c64e9bbc0f436401aa40846bebfb54e569888cffe646d119a40c36c32b21e00638744ed81d621339e28c3b21edcdaf20809c9af6d098796f83b232bd8380a7ea9a2133867d1bb5ddf8020295a9d6864f99176d341bf3073838ab46193631bdb5a6ed265e40a0bc1afde0cc64d38eb037bd0603336a5a4360d8851c0c4ea8e80dcd99d6ed691bd31b1070a25e1f3e6158b5105b8c9f4000892a65f080f10a5a9f3bcd2e509fb090150788272ccec231c4490bb27004014f55ff42a59db2447a4f28c8ef305a80fc2f6206115ec40c62b88839b2b488f9482bed44e15d5a71e1caa522b38a2d45e6150f45662ae289cc2b4e130ff364584b64a6c2255151457944c515b7888a55ec212aaef083a8b8020051f10ae1c3a318655b1f606068aebe2fc2911f980dc68789d374969295a644b07640c4bcb69c2935db9a93ab3975341ec1c35efe4bbb71d9cb796d1f0e669b2e03e95ea8252663617d6f5b60191f3332329a1d0730a63a0c874542b4696bd7a25d535b8b064d5a9a35b4d6045ae9354795629c1d0c913250a6050c95b9a18a4513628228510c0a9b9a2aaa42f95353478a0eca4da2a5a195d5caada6d3e939ac6669123a402b2219715915c159792df3e80024d8b077cc78cb4845f029e49e1e605daef1c39f1f34a3e837de7de3912dbf2f86718ad9c607f9f00d582b3a72ebe57a437c7341a35de0ab785a1b99e48b2636e1096d60821598d8c1eca539038425013023ebc6a83020ab86a861a0d7c62860a016dc88a256185064011b24721bd758f33397975a9accf5336a558becebfb00677a76e7c963fcfb0b706c7cff29c4afdb78984c73e57635d26200d2914d047824174227e609bac0b66a483cf0d8424d0c4d0e6896135fd35494d22d212c67ca2abf256fe274421ab997e59309594c6c779ed5a53c812a8723da544c68be0e64a75f537e7f7bf4c549703f2b16a3542dc563385c65958053f1bcaca5f5f3201839aac777dcc7d2987a80d9c13b943159a7ab11698a3739b759d465443a66e77666ea976f62c198751a13536f1ba1751da105bafb3e46b8350072e63e47697a74b4675f881ff31c961b12b8307c969798a26c3b27e1a381150faec87e73ced22424b5a66fa488e1f38fc6be46ca5aee34e6cf72cf30021ab3764c4f214faef9f8e2886c37e70cbd7f31d88ca39bde56d66c063b9f66a6e365da66a3b20710a8f07bc03126345c078e8cd9f405b89eb570a3c1dd1f5e2f3453dfe2aec1f878f3a47c041542c50f087400519279f8cf1bfb35323acf8ed1d1828e3d7a14d64d1d92bb8e6c8aded0cdf5264e9d28dc1f64a6e9880eb201d0fcb8d5ee16974f84bcb633748ee785f1666cee80f398d2b1fe4314b074ed2e32aa69dc879b05ea1861ec58e2a3c9c8f79351ee9121dd4d40bf4f8e728708716702c654c3b3b5c018eaa82e15ee7402e5ad9ce3ba446ba356b074d8a15200c85060d81093f49b226195f120f0044b8764334e58851af26d0b8c1d58a6b29ce115deb0b467be081079c795c11630058b8bf4ff24bbc6e623a199f41821b85b58df34663fd9132a50dac4d83d883925790435827911541b61153f067ef25f4e1d32536a89f109ec6d3609770edac5f90dc4c4cdb8ecf8a35653f81ce814a65b4e644c654c67984f99272c1b705ee83c58366c25b96b637cff0b455259a157bb77a5cb0c1b3824031a509a4b63b673803d15b1b2606e143e368ebf5bc07fa370aa85386f6f1cb41f5fadc2c1c6f17603f8df14be6a11ef8d8d83d6e3aaad702fa477e23e61e78fda190d8e53d9f46b9a93ba72029dd3eecfbedf27ecd80712ca9612170c876e60dff720a2825568be432065718218a4c7cd5e258b45589cd865061dacb1076ae289b08f90da5faf1032a4450a39cc2efe665b0849e71c9fe90da2049aa2c483915e2a29b18daf92c7e67373a4b49856ddb1c028de1635da584dfff961ffc551f9df1db81f5b9c89b573afb58952aed9fd60539978145b35d78a7ca8bbade0f375c7ca7cacbb56c0873acbca589d4fea6eb742d2c3962d7f4a497b54b9a7ba761f2cd042d07092caa577073505e53f0428d6054b6b7552e107cbb77fd5e0763feb63af8aa36dc9268a75a5808af4f9b95e7b7e22232676fbfcf932b5f7f5628a1edee884c16a9bc862e3382903d08b7ef66b15b9b30958bb5b86ef5c744f541f8aadf8c0ebbf187d0e54fd8d107d5a07632713305917c9ec27d916d803426ddb648eaed5ac03028d4ac8cf867a53d134da979041a0b85d097bff67a53b4e29ac848585ee4f4aee78a5580b0b0bc0fe44c98e538a85b0953f536168e01becab3fbeb996f3819d30d57f52f790c01bef2b3ea8512df7c18b30af7f56cfd0801bfabe5bc0e5e4db0de2e258d365e940edbe65dd0f13b99fd744400bd841c466d0f6f235165cbacf76a4cac38e1cad5030a3432e84d80c91fbb72f4335b190dcf12ab4d0d84ea09fa22184fc8fede1c17be7622011397095dc6f06ac770256809f6004f85d5241267e7e420011c6eda140514664313602c08096bec10e3c007e20240b16ee1918a67773758713d2ee20270424d8dc862e4f6b2c4b543dade72017a109148f1fa6a9a1081f1b82c64acfb27586253234afc0ecd5f270f5202eacb3e77b1c703fd86d427eede55f8cedeee26c4ba6ba8a4935c201f0cd6824d47995f932410e93a224bfe7180d1e6b8ee33eeaed47072df0f4580ab88ec2e12b22db63845058a1dde96e9926a842f16cda08c3b3ce7d1124ebf17d0ea7a8c9008f9c1bc5976f5c7bb129fccd4b10e39b4fb5622925dea7f23be7b81c3d770043aa7790d84d42177620705558e3b957e696c817a06362e7d30f5a10461050544f0b222f6746274cfc4bcc7749387df545749c0196c7fa971ee52a6fe8ff358efd22db090aff3f644207e7a3c3bf85c48a7183719426c69eadd4e680f41ef865108ac000d2619864c25a969acca831edbe86216a409efa5afdf4169a83cfecd200574d7e46f7ecd9a95a89fbe3e014e197303e47dff7ed728cfdab6477597fa2153022cd926226b3a02847d66c194bf9d54a69a187767d58a49dc4c7867f87048e7d8f8be10f1f47878504f932bfc4e325f4be1fd8e7994be5936228b1d295f7030dabfc710237099dcf813663093ffb26f5fe8e277eecc5173b09e3d69fb15fca8186023530a8fa1726626fe6e7e12530993bb86092565f6496c44541d05de92c95a89d2ba60ed77e323275720194430b79832880b82aadba298711b9b5720290be44b8b4fab38711b7e5dc9026acfcc76faa17ebf2b5c6fc07c822763b87811d1cb3d498dfca3a7037bb40eb9eb9d172c3e45285ce129d118d7ffd149c7f0e60e252ff2f26ba085b17d8bca4884f00567afab049fab32bfb68e86269ffdea13a061b0e914204dc6937a1e8145974d70e5abbe0a66744290170aa81bc9317d086feed422e686e831b8cf49779816db60b107b8452e009c3d7f17a056a4b23ec5676adb3c0d6aab8151ac0dc3bd39cbc85ef85554410c4bb96be3fd8b985c8891860a2cfc1d7a4ceb4a56c14248ca0bf0c3e331f8564c9709dc63c0b3c0f060e5aad45f71c1a9b57418e99cbe9304bc5913f80d064f53739dd1c66c44a30bde93196311d4ee7f4c405901bcf11b03b180dcba96007d9d091978ad8d872e0386a1227ec7a8bf725757c9672ebab9b02aa591eae96c73dfe11171824e9b65766beecf99795f335f3ff6aa854abdaa32033155e2bf75c18d79224c305fe16c690154d10108b1575402bcc2badf45bfb433b79be84e21572bdd13549d413fd4044c40a9fa59f48f7d8b2399a1821b284d288e10b7dce9b277a6729788e89ee73e5f463f4666daee2c9c28c90bdf74e01be163816f414b9d8f6cc551cfcffa702664de0ba5427069dfedfc6ff1b5000b9848fa96b75dbb6083ce05671ecc307958f1e3e78f8d8e143878f1c3e70f898f221e5c3071515550f2a1e543ba87450e5a0c24135452545e5a307558f1e3d78f4d8d143478f1c3d70f498ea21d5c3070f2a1e3d78f0e0b183870e1e3978e0e031c5438a878f1d543b7aece0b163c70e1d3b72ecc0b1636a87d40e1f3aa874f4d0c143c70e1d3a74e4d08143c7940e291d3e7250e5e89183478e1d3974e4c89103478ea91c52397ce0a0c2d103070f1c3b70e8c09103070e1c5338a470f898a29aea31c5636ac7948ea91c5338a6a6a6a4a67c485149f590e221b5434a87540e291c52535252523f294d04b1b8467562704c6a06e6ffd9d71df988c535b71ba83b92f1375d8b3b786f5c9f131e392e140e26be9b852b6e6f1ef6bbea9bb57a3b2f126f555f756f4ca7b8edb59df788bb0df61d44b86a55e3f68b035bde5058dcab56df5cc32e5c331115173b10a7b903333ba6d5b55007a1c2319539c6126aacbdbf802d0fd86260cbfb7f02d2fc3faaaba5b62eb6e3ff93539b7550f735a75b1d989ffc8c98f9ff26afb32d119b3ecdc47607554cbc41b68c0089faff1effefe475b5f4812dde81fa40a56ea47adfe87cdd40a62b6c73119ec37026926a1587ad5bed16b2e605d2dcdbcdb245afbeb9784e375770efb62bcd9d2db6edcefaff0104f8ffdceeeed5d7dcb9e6eb06ae5bc6ce12b556237def233d2fc0ff5fc9eb68f97f5aededfee1ffa7f1ff33fe5fc6ff6ffd9fbbd39c8dc508e0ff61fcff8bff16ff2cfe773ad0a91b3c77a3aa62a2d7de5f6d0e068b58244b56f9ff25af3b9bc8e906e6540add814adda0dac17f51c12929a91d53f8f7c38123ed3115e471636b94e78e5b206a6c3bd7c2dc466d618b81a58bb3ebff77af3b63f817db6ab0cd61fb1abb06621603798b0273584f0cb738fec9f5ffd7d7997a7e35729dd2e7a28ac3aeaf6db57c77c577ddd7f7e4c4e2566c2d565575b5c8f311df4db3aa62e0ff27fd3f52bbdb568b2ad89110772be485394f7c4086f9fffdbab2cef316d5952570f94fb3aa71f0f2dc8dbf7b83fb1adb4dcc44dcedff8ffeffb4d9862d5e573a7dd72acbafaf63df8ad7918bfe55cce7c5eb4839ffbff43ad2cc27d066beeaff47fa9fa5f97f28af236ba49b1805cc613ad216c5ffbb78dd03faff35ab17c8cdbf9baac53de4f7e972ed74c772baea9bc33631b73d168bf1f2f7ffc4d77d93ffe72dda8941e056551c656c71fbd36a14b0e5513fad765e6ca37e5a8d2aaec21b63c555ab3756b1bd82adc51b3a78f478508ddd904275f440a7a2f8aaf110a8eedda3d862e7c5168d5af1afcd3c2a13f730eaff6bff4fb6bb6df35df14df3da167b6eefba75c77dcdc4acb2447dbbc66dbfc255f78e89ed0e5efcff33f3ffcfffcffd7f29c3cd20dcd3391e796fca60a10d0eb7e407ddd10af788cc31958f35a5bc64691ecd33973b3aba275395f3e68e3e476b9221a4766960b5a632c6f2d29aca18cdab00d6d1bce42dcb1cd3794ba4ae7302dc25cf5c94e311c77445012cf3de98aa5c5100ebbc668ee9b148262c170b776d4c55a698f776af5c2c5cd3d1bcb7a62a582e16f9e691690a9203e62dcb1b131612eb768f98b090584717c754e58a0258b78b85c4c2dd33976b9a0057c5768f6eae6982096eb7bc8f8563d2315d510345011eed92584b00e99ac0ca18cb5bc678deb3abbc24920c07ce5bdeafaef3de99229c8c264ef8007140b3a68f9f2539e88ed4a8a02b2f0ece921e64c80092f797bcc129c1d0ce6edb5ff0ccfba41656a3dd1953ada9935be5f178c491b99a161803b46b363d89d2c947aadd59ad098c08ed9a1d8c76c95e6bea4777c6248483ac0e665e7236e479b3a67ec42391cc4b632ad2499e170ee490f7919a98612f7865939cbf34d2448202357fd590f78f1e8b2c83e56295f9fb33dc9b3dc8fb3a1c79ffc4fdfd1367337b0440cd9779c91b80f29e03e028b882450d140578b8b2645ac282ae0a47339f9e66b5bba4ce5d72836e891cdd923abaf39a57746e7a6e4d5d4fe7769fbc1edeec1e31f9cca7d992177455b05caca37be5621d35b1e6d36c890dbaa3fbe40b9147f369766d4b68d0c9609bdd5b0c32e868f748061bd3923bba2531e86a77490c3adaad312d9941772e99812ccd3335e896c499b3244e95252ecc89b3c48e6e890bba2757bc25747455e6c4a1c35be282cebc4b60d0958f04e5e9f04810704d4d6f3680fbb32c99545b952952c8f296e757a9807b9224a3303da93541317947e7799eb45b3b3a6bf74ff3da6c97349f982749ded334cb003c21efd125b798dab0b29bd776674d4f02c0b399b600d46cb55bd26a4d4f6a97098cd60436bbb62860b40094b7bce50523efdfab72d606b70485374b1c6e08c9b36d9d6d3fc3ca7b324181c103a3dde7dd9aa0048077744b26283078b4a66e0e219f9cb6262801e06d91b4f3423179607f9f575e19704b7cd0a5d1c968f2f7af0c274b30744c4bfe9417084e694e951953952b3ab0cc1b80311a16da7d24248f655e2a518ec7f2ce98684d36a6aff3a8a48b76674c345ad30427922838a5d90351b06a4d139c77f600ed9ab776cff3ca04b44b629db5daa5d59aaee4b0ceda65aa62a3522b2f4e498603b311feaf4c605e12ab441265764da60044c132b11ec92b87556291485a5de6ad31cd2eade90a89555e12c84b368d306bba42629d4d2f90f7917e0e2895619965d30b7f29a0952719dc921474e5c5e196f0a03bfae30607372ab819c14d06658586f883020f724c40818b0bdeff699368893f6d70682307040178ffa7cd11893f6cf0b069a104365d16ad4942cf9f352d94f9b3c6cb9a297fd43c8144107c72a0e10515d4a82123460d076ab0344a6388092280d8c186185a40e14c1ab22f69b8a4a992084d213449f000039a3368bc6080c60a2343273071421179e29c50c2095d4eb072a60a28ce28b187ce1934673c3863c1992315848e08824f0e75ccb8602605332098b9a0cca13243f02963430c655a202b53411442986083092a988066840fb898504199144904eaa1043b735628414d092594c065d11f3249fc21d3830cc71d0a524a9892fb808ace822a64a458b1557145500501d8c1727bc1823717a0c9328296a30f30c0200312a46ca9828b135d724368600362033d1c1cd9f1629bd3c11a0f7663be74f960042b607089c24421c6b6c4185c2010907808a18603198d06116e2e8cf0860435644c28210413be94e962e6823322503961119a436908a949628d20363520daec80820d6e6248c1d6c21b372ad4d0ac40020b61e06cd042963864545c5024478a176c4cc060c49c5a1074f8c490830c34ccf0421d156850534309766c63ee7460436dcb0d21548043191e2a7278224f123a04d2f3c30e361d78b8d3432d863d2cf051e303093f7cd0670b09040856c83155fc5102101041d820440b81ce08fa60883116105145113a258ce873c4ce0e123a16923061d0ce8b1274c47011b3441843474a30e1a7091c9c50924368cd1364853480224c950bc21c79ff074c2124224a298e803084c3a1a417a6584345082422305caa003325d121458316fd618494a7910cb9158eb63552be4cf9600a95164e5471f1839516325c615381182c5f2cb080c51417ac30220b8b1db4ac9883019b0c74216cf100032e2b1475d92da1c18a3e1becec7000c78bd2990ebe78d041055fa8f80009303e84b923c64b9c315ecc80e0a58310bc5821e3400a11382062040e7a2081833a643870530207642670b0a50c23334d9c09e204a53c6856c84973829a0d3e58b341056c7653b4514a02853e6e74775280f3e68c0a1a7cb0820617b0b0084e12a1168488a3cbe382d21c393a362f2891c1b0c19c2e57e8705114831232fc50cec085863a4870686053c39109764038efcc8ee0d2810d16607003972a478aa2c0c1b6049e236e7f78473ce47027cf96186a71dae8b0c54ca9670b085b382877d8628587297a48624f1f3e36f810e707347d94c400c1c54f0655fee0aa00947322081c1142ec10888e203643ec402002a94b11185031e2d011492091044412b91c06cd51028525486022c94b135a2c70821121289ec81d51a80f1448384431478a140c9539940b33c5ad0b15b82b88b21cab4894c89022428b0631a211d1a8f6a72cbbed70b4418a2d8629b53854de54a1adb18223e1ca980a3cc0d2c5822c175c60250bad4c4b0d110637421920b1c5260497da0f5d76d08086c306753878c1cb0a1dd4d87870e60b8d840f662080a17d09d345cc05632ca002426d51085390151281b6c408474390f0870c8d4f09794cb053868e995a0b67523881a606cdcc4c1ada086ac2ace1800d066d6a5750c072749328059aa137474ca870c40ab4402cf881c3a7053d717070a1063931bc20070616e6b8a1a326063332cc4898614c1d0f68e85243163b1558b95366431537d0a4c081109e991239149127081d7ed0b3c30e38f040430f73f6b4c08796820f6b7e989de943230108317e7224d39f2b1bfcb9a2a504b4c8501046003a85c0532790953769783632a7202b604a73880bfe58d1c0ca162b564a2214157183c288a34147dc8440e2884f12390ca241891796b0a9c0049a264470c20342370c9ea852a5d0912228a088e296841442183ae27328cf1476a8a083e80f9536b433bcda08b62a3e48f4870a06bc23deffa15245d1a245864c464af086301bd5f153668687e3fd9f293e9865343dc7138f941cf9674a9d293639542e58c1fb3f534eb05521b39245f77fa670996285f77e18ed919288772bc4cb19515ef18177f250010d0f162972784f72169c2b5c50bec962a2a02589045e4d0c061e64f0474a06bc99055b4cdeff9172854b8e649232a54bc9fb3f528e1a9c8b480b74ffe7d804ef49eecfb108de8cf77f8e42f0c89b3379ffe7f8e7cf51cfe9e5e4e0dce0d4e0ec727239b79c199c189c5ace2ce705a7052796b382f3ca69e5ac725239a79c52cea35966363219998b4c456622b30a13914985398579c834644a614661426116329f3009994e984d984c984b984a9883cc244c24cc234c23cc224c22cc214c416620530833081390f9c7f4630261f6317f307d30f9987bcc1e4c1ecc1d4c3da60e661e3307138f89837983698379c7b463d660d260d631673065306330e998734c18cc174c39a60b661cb305138ec982b982a982f9c64cc17463a260b631d9986b4c35661a138d798279c6346396314d304b30c9982498239822986466082608e618538c19c604637e607e313d303b30bd981c981b981a985d4c2ee61633031303538b99c5bcc0b4c0c46256605e31ad98554c2ae614538a792ccbca4625a37251a9a84c545651222aa928a7280f95864a29ca284a28ca42e51325a1d289b2899289728952897250994489447944694459444944394429a80c540a510651022aff947e4a20ca3ee50fa50f259f724fd943c943b943a9a7d4a1cc53e650e22971286f286d28ef9476ca1a4a1aca3ae50ca50c650c259d724e0943f94229a774a18c53b650c229592857285528df9429946e4a14ca36259b724da9a64c53a2294f28cf9466ca32a5096509259992847284528492ac0ca104a11c538a29c39460ca0fca2fa5076507a597928372835283b24bc9a5b4525629a994534a29e5912c231b918cc845a422321159058988a4a283a427a3fe926508d94cd334df34ffcd37ffdfd402419e3c3a08e2e8bee9c9d2921274afcb03010e10e4609a6513211e94c89fd2b3431205ebbc13ccae955953050a609df76c2a95f881ce4ef7371a69e13db135aa52c630c47b52835732715eb28441f7a4460ddb2567342626466f04a33d8c74d0ed18dde12d9d68704bbc40b0839fb23d75cac894c9f9c2fb3f472cbc9782c4fb3244bcf75336c84f19113c1aeffd94016aea744e397eca40f8734cf3e748e624cf7b1edd93e9e82ec1a27b72697fbbb5db2da75b8231a3e491bb6579a486a5d4f4e6d3ed26312d71a33b713624ada4f39217e9e672349297c444f2909894e0d15ddbfb29d362f2cc5bc3bc67d3d39acea617449664bb9d0de9f2ee6c0add6c76afee85a37ba27b421ecd1e2797e36cd6f464e99c9de79d915848f3766930764c3aa77beaee8ea98685bb668fdd3d6f8dd249970483373b6b77456d56bb3ba659974ea98b8531c3726f36da0d0e0e774f242d9cd205539a313dc9f1661789e949e721255da524a47b5546e12131a9395eee76bbcd6ead46962b6f644a3a48352c5bc9a3bc52524d4f5443baf22e504a75c1d0d59a9e48f170378e6e76a54cb2cd6d4aa2e29d30be862565f640ba3626295e796b944ee45582a1247544963789e94d282a9eed7ed9641b623171e7d1493b9d78b341408ed2d86c36dbd3ecda6c5a36dc9de996ce7be27a204931e9a002c27415a4743a9d4e3217744fa47827598e697671474d399eee89d4d12ca7836a36b39d4765ce4cee9e3c9c143a1c0ed7646b41575ef23c71f7c49d278ec4692107f17217771ff7a5d3db9a7e46a39db6d9adcdfe3cf485f7d786abc1b3dd9f2119618485f75b7f6d351ceea8e989caa46491eeef55d904238e8e242f9569b3954ee48c12494b89250ef983e4c9e195336094248dfca627d7bc33d3c4dd12772379b6262726dd52c92511204569fc2812e327511f455e784b85708ab4d428674049e958c2d5cc1e97ca249b8e9a489b12f352993d9a944fe57d236e4d5d8f64332f96596bea2a9dcaaf59d3499a66a1b247ed3ec99de63dcf6b32e54aa7b3c9863b69e552e904e389ad3c67e6496b3a79509c381965692bcbb2b4d9aeaee481ab9536da0c5a79d4a42b79d06c4d2569369538d2bcf1feeefe878d8c2aefd7ca9c8efc919b5ddaad31914cbad289c60b2907e095e4693e692ad328c101d11d9e0edefb41c4018f9c91244992a4499a349acdbca5d3bf8dfcf3fcfb2579951cd2914fe79319e63dcfa625a7d2a9bc3a26ce59538dd269c69d6142f082eebe139412effd2002c4ab0de2d970c83d491a0102773301d94c9376be8de9a4d16c6603e691ed344d130ea2d2346bb45a0e9743328f7248b51357bb276e4633713512e988c684bba669de7034dacddd72387376cdda2579729e673373648d055c0061240fb7e2ee74f7b17025cecc5d5c79e6cc232e3cacbfb6dcd1ccac3130c391640e69c75465c7e2e2662c5830a9c921e576bb24a4154c24d62e776d66ce08ede62e1292d62da763aaa29bed6abbd9bd2a77b9a39991a76352324d9d8dcccd6a48b7ab635293bb38dccf942eceacd59466b3d9cccccd68b8262827efa84c2a6f64705ff5a43cf1e89ee40ed14ab34cfabf713ecf8fa21678f769b54722f284b6a8c0d166b32b8346b3e56ef769349a69b3e1ee510d87bb4848b85bbb385a99fbaa190c9e92ee4a297dd5ed965787c42b8f6833e828c2a36850db9eb7db1e29e9d2b0cc8b3b69e4994b6272a0c4ca41804847de5a6e8645b399cf3b4d2c24a6b224af0c929ce5984a2c1b53988d47bb27cdc674bbe779e2ce1357bbd1988ecedc69c3494ac79f52369c906e33db69ce9268342568b3374b9a9c7b9a48341aad44a2e2489ae4bd99b756bbb78b339170e6ad0676bbe4ad927495eedf1948972987b4753b79d07d0fbcf76348051ea906ec766b5789e976734f6ee6d6edd6cca6f34b24a4dc8d863bc2dd8e900e61e1e190c8f234cda4a3abc4f45849bc9bcd2c73656d843bbb47e6cc344fd336fb990bdefb311442ed4f7236bb67799ab34bba60c2e0bd1f43159c47e7cdb499b32ea459d66ef78441be49630184f77ea4f04243ba3824f3969433cd9a6922ed72a62e57d351f2f89b8d4592d2eeab56dcbfb8153a320909698b45ae26a35643226b25ee2a210931afadc654e3994c2489a4c582e909d296a9f437ca1d92101f744f9478e55dc1649ae6ce5cca99b7db8357def20e81519a378541bcf202c1216d9946685098663ca5af0a2b79661394338989e4ed989e20ddb32987a4c40486746ff786d400ade92c9d90b690eeadc9f602c96c5ad29151e555f203120e8774942392a3dd5bd20da0bc5d2976e0e102c899b9f2e8263141298dd8784737774b6aa4fb2a3f524c7173a469e24e1e034f88673619697a727e80fb92078d469264499234da8d46abd1be6a8684bb0578736306bbebd69c679ef9c537f79be6cc27606201a97fa62f2e2446b27a41b8901839d213d26b809795a5d5c05df1b0df36f7d2b5b8dbcbd3814ea15237c0301098c18e36f2789472bc1dff8fc72f8f6f1edf82e367c9f27ffba3ffc7f27fc1f18f8e4729c76396e3fff178c11fa7fcffbfd620edf48f5fa775c5708b03cd31854add58c576fb1b723cd4055974ef90e321ba20857a2ccf44bc762066893babaa0a98d30d0cc391a368d56b333b868960c0adfe5a15f7dd7b6398388689b99739fe59e1c851043286899bf8b56665f93677f1aa2a30e056b1de2acd2cabdbceab881c8b0121dfe8b086ff1d98db76036fdf2bbf37a8efe5fae6e1d7fde1ebb5bbe74b33166f51de3551abc3ff2785ff3bb86ee514b74216c991ce3111ddf5ba158156f1aa8500355f75dbc7b48c2acbf288b97323c7c3ae3677fd7fa55b3dab2aee4a73589b793e92732b04c835b1aa8aaf196cf762c7dd2b0357ac622cdea22ad65d457914456df4ac42759c5be1ed9beba2fcaa18ab45a08a81c255a76bf1e616dffc40959ac3b2dac37cc56daffa7f24af5340ced5d50f391e5eedbeb77bc8efde7dc8f1f05665dee6b0dc5edea2438e8757d7c9ba356f7312afff3fe09fa482839c4ae09f4c22673aab3c38b79dab99df0480dc5413a3a2a27e451e0596f21b7da7184cdd6c148fca40acb260ed168bc21da758a7991895e621c7c3b558559585b8dd9d575565a2ee6bb11d93b23a1328f4b7cae7bb1ddfdc71e7d709d5fd4155646205841b7157cec11e37629673ac021f70f3ffbed725a083b768aaeaa2d4148ae3c60eaefa46563130cdab50733eecb82b55b386a00f853a8bb539cc489a572442528cc58955551c739e8b709e81bbed7c77ede0ba656c77c7e98a8ba8b8cdac111513dbcdc53956b3820c811db35ca75555bc9789b80d7223eeda5c3c438033f243500110bcee4793fff30121ee57f316edabde6c0eb4072a75630a98f9ffa8ba933bcf6bafcd5df78099e551c01c5695e63f8c01065ca99b00d3ed9907837bd6c300030cb80958dd744df27fba70aa392b38b34eac93f7a70e1fba76f3281d95a1dfca377c5f8b1b7813b0ba6b567b3d98d55eaaeeda8cced39b4002c0969764ff7f7c5d8f3b107c6d65f1ba785917c81d4bf58f60a77c21f55f42c06388ef58a8c3f01a9573db7f51ea06f236afab7ec0b8e2227b7ffdff9136a73a6cb75dd801be6edd8159d5e29be5ea59d8e28ea639cd1938962f6f73df6137b745be6af1a0f1f85b3526e524c45f80fe9fc9d5fae225d93ad2b5a3cd3f939bb525642b4babcbebc69712ad2f2e23593bbcecd092e60e2cb6394c774dd42dabe38b6ec7ba03ffbfd375c2e47219d9fae2656d11e9eae27515c1d25c27c944fd95e608b48adbbce60532517f657d21d9c1dbda39d549c672cf6afeea02ea36138b5c5f5a5e5a595c5a481cd0f212aebaed5e5442be9004d1fae21dd12a82844b8b084febc811ad2d215b5f5c5a41b6ee579616035846881041c2a5f595656401aead235f5ef76b0beb88d6025a5f5c5b5c3c2d22468c603dfd7fd6ff0769808124ffbf4515ec4884ab5e3526e636c51d0fc9ddf85bc0fc1589107fe51fb1c825c45f39dd4584f8abcd29ce47da1c66c48870d56d4e5b233d7be58e815a658b417af6fa7fad536f24a9365224d546540cd4eb5e3170dd5cff1fe485b8e7ae571dcce9baf5ff59ff8f95d55eceeb96904cd45fb9e320ffcf5360ddba6bbed9ffbffafff315f8ff74d560ed6e5b2d1c644190a9c18c028e0eb28594244a0ad22fe4a11d1895308451bdef8f0ca5076c7820199959414a80ca20f30839986c8232fc90a730a5f6e0cc87e162c264c0e844e663213387013bc824277479278adcbff16e28b32060f531a4c051222114e8d94046bc1b5a15b286275094222c3242966cfe5e0c61e410a4144a22562823f340f96292017181340efaf2249da77f724b325bac2f7c0f6d1513823112c821dcd4f82689ca480eb0fa9009dc297bb2cf55d9e528f9383ce0ca077af0f10a3c217b27574b9491656565665959135c6408491a8865a49822a6cc2ba3d84bb183d49bc723bf6789467940101190261c7154ba8102025d111a52bca04523891d1dfc0630789871a80727d6e434f873110d7288accb23111048453f94f91772bedfa1a3fc161863c82b36f0502691b59192d249cda20afdffaa3bcfe9cd3bbd4f4e19d81637aff3e6ff56e9a2348892200aec6fd5ed56f56056efbdf9fa50a8db7b7b30abbe3c04764c4c80298104fe1fc88f28285d54eeff723dec5ce761bf557c2ca7553eb888e8d08cb71aec19751a452cae523701ab8bbb9ad3fc93a0d8e475dc4881c5409ebfd0d1f73562edcf3f1320bf4646a6b31d597b2572e6824c226d38ce1e6f72700a502b6db6d96992e4bf28d12f9f74e05480fcda8fd92bd1c827497236d351e2ca2749d22c8790648d2c49d2a445509225592b5d1c21491a59fb924442cd924673ba5df22ccb930b79926479230f95e4d1cfc8b33433493e2949b2b42129659464493b4b928992246925e900f98224cdd236c3ccac25912e4892244b1f650b9b498e214b9256926469f6c8f2bc1de92873a4958d9cd53013206b65794e99b7b2249f947890129c5338216657f9e7972590a7e974ce4ad2fc99179208f2cbd7e9744f3e7992254988b495079064392b4b9324739051a48dcc956559d2b2481b657996a49489e202b0194022ad88517a40ceca00c89334c92fbbca7b23cf2f35edaf8fc4c07ca619c8bfaaa134491a79d64824d2fc5296b62a93a432c9b23c6f993b7222672459933aa7069022cb1bcd56d648b28a2ccb3f268d3c2a4f338c6c2a8b2469de208f702569ab91e5552940294049c37cf3492592569624d2a933cf3280b22c491a7906c9a31a246e56923332a9878c72ab863b2ac99f2d572b4907481b499a25799243481aa58f7246892b6be58c34c9922cc92a9246892b6b2769ce4c92ec419aa4137944e64892fc410a50decc1a693bc99224ab4892e6a25c22cf929c9da48f12479aa500a46996e5599ea48fb224639437f288b49d25499255248df25633c9d3769224d9e392300eb001311198912679449e30c8a3a32a1c13190290049c6459d2ca5a26752da4704348b2244b92246f7cedd95f12852c0401a1bf108830480f044c4634f10026620d922104fd17939ff7126187ec8575f82322c8197384691b7140842785bab08e2b22220820c5103c43ca870830a27ce024343d8640aad183e946f2188264c4c35706028fdbe8519f22016ef8cc9450824cd85057ea0004c8a09e18c0777303dc172b9e8c8593f7cdbafc3da9fc9bdfa44bf76406779cf632717be57573f1207bbafa57b1c677d8b5d890eb5533a07342f46fcc6097777d73bb83f977f1356f3a27b6cda9aa8bbfa84e0c0a799d13d3e7755f5edc3a2cb7eccdc3acb2c40dbcbdb8875d8b5d63dbd77c594cbc6279bdf8ee7ed3ece4ff7b9c4c24b83d41dd9c9c26b813dca06e12dc0b7525b8f7de6b43d0adb2d14767e38dfac3bd48b4f1e5ff56a5f91a539c5b1517c16a77db6ae558855ac53902cd7b711b3191ffc7d1dbbdc7167bff1f35f5a7593e5940140500fa74cdb7177ff7767c790172d235eb0ab8a080b1abdee0beb9ddc11677dee4ffab0ac8d21500a400204f7818f82f9fe0fa2f8b28d5924799438820484069d45c9148bbcd115ce3efe65487e9f4ee7e3b4bccbde3ff7ff2c6e6698ac70502e44e395d20f722b006cd096726f87f2aaf63a2f3bc458b5cb74222a712131dcc59e3041203228879088400fe68f0a608196780987ef6e47831468c16383c1d269d0c8462a20010a46c0b9459c21c2623aecc3441dca8616639066900001194d1c1ca0c934de37481f8fd30f4b4642249421746910862726372e68f303a324728d165eae9ea19e0099d090f54815a64d2b2a0c9e08915aec4c4305432e14218112265c804d13551ea5114260040902913048811e50a6680d8c1ab4911297400a80c4304990a803c1840aa6a4f29e58b8b255248c0e415084f19c473f384e9a1c95809754a22581649f1228a261e1172ca291600cdf1fa5202863c6f4a1753d400a625e14b084dd2908b4a0823838e3f3eb41440861c42082121bcf00159af0831a41d2f07bc6992c803b2143820d3dcd9e145c39d0e9c24a085d4e00a932b1a300943830c5548b1375f4688600c02865800c826511c8d49f06602302b9dc41a8148c207609e106340256df82109a531580c964849240d8a6828136424a1e43f8a3a4e68548105850698afef43c58e2d831868f21f22ff421b213295963b6acc8ce0047084a93d7514d9f8c71282111b06bc00d3a4a5e3897c78a022834689e3f0df6b0b0538f248b04413f6a9e8789047021b6a2d52f817408a023ec610717054e5df5433c6040d697e658306ed2941579647ccd5a2b2147660e185122202c85086ca3ed02207cfd1eec282a789320ae41c614b35d8c560c2883220a30a548882cadf9004a86ceb841a353ed05c831ef694a14634d1d53900811f343c654b1f2840440d7a248892a64ea32a72685300923c35b5829c46812eb015423447a905d89b46755a08c26eb0c54c181dd2343a83e84c4f072c7d020ec834da6242a017428073049c2d621af5405588d5609f28788183464b3ae0b2a2a54b1c03906869a4800d72ca7c3a6290f2aad2a8800a7ebd991a0006b204a0d14d0515d49839a1ec08a7337a420a22106d20c40c5018a032e243029aa012a49e9f29524671fea4516b4cf02ba14a1346641b808590c785026ce8e08b91151a82086223460f39c421c208acca9d3d8178a841811f411875b9a1122a3a60879b0c8030daf1848edb971707a43942072319645774c8c183391e188262f43f742b381430a5ca4e8d454870e960894d35e48b91198b709041c7018f228a92f4585a84c214202b8c4e56c8f3406e51076bf06c75b91af322969d8b2458424c93180184b2e0b068111e0325cd163526d8a082a145427a70a089d3141230549a580485819e01d47089b20888118b763024e9f2040fcc871c2045539489a1b0080639808cec5104080ddbe8851d3035dcf0ffdf088fa2189088a18399400cad40ff5f4659b33a86892513a9e0aab93017f984d408dc40a5501874f0de62f6051b4da46c34f95dabeb448a49b0f893a38b51e8ff9f9c8c9d25e61ed768b0f8634252326598301c4f0c8e2711da0197ac1d92a233e1389be56a06f891728a3075bec8914143bbe078123972719b0183caf1088273892900aed3723621362adacdfc01e336c3e16883735c6a22e5a88739268a5ca0e3acec38cbc5f0e198eb4d301c8f602495b51fb3a81907585ae002f060caa9e5a8c4a4c464ded845d960eccaa6cc10b051d580984a26101b99a359642a8a76a3a5399a385a8c130a37659267ee84ba099921508380168376a33dc92de5968e601cb9a84160329a428b61b69932bb732ce0c949bcbd02689c553925daee24cd1b66d6d9957b412b6b0fd464d4b8662d92481ace9c9d39d3344bb366dacca3db8cd3ac21a9ad50eabaed6ab41a69d64e1d67d449da02306548391a6086e6989446ca8e76cab0059972069ad2d4bb5fd6280920faeca0c7863b45a157172e5a580a24d063af4f108ab2a153b2d5982c31c25596670f0f036c91fae2c11598403fe860670e0b6cca44a1067450ec5b787b088a4280f8eca14185281400a0c9122546b816103280002f5cc871210a9b35144cd0a33163af03240512020af158d6888a299a3079e162f7839d1a6298c3c20a286cc9c0821e002078c008d7960e796ac8e1852f43fef8d1c10e0d736030814c162b54a028f4039f3930c87153e598d32dad1d52a1238c0864030d2ec47973a60b0639ed01a0099307b6b47e543ded9074c863c398305daae414000c6c09d1faf14718a1439e1b6a7021ce1b14ce68904115270c6c25f0a3aa878ea9a715bbf3cb8e3042881b6ca8810617e2a07046832e19605085889e93260a44a18b14116940292988195cb46451f280d4081864318ea9392a331b958c668aca443634e709e599b20c89a39c32a5481477c344c0bc2e06286790326a31cc004818e70bd2c5118b152b4cdda9944bd221c5c805809b71db1dd56cb45a49a3cd6626f9b42ab7027038d68e6a4767928d47edc8a491fb92c2d56473a2dd6c54674e893c73b4de29662299bbb30f1530475a52593b3aa1906850ad39de92e4d2132a494aa943c60cc949d280c8704c8048901d95f2bc9d449ea8382231e5003d52c859d56e802b29e519c3bcc1924c563304f81c69b401baaab450c2b2622e20a5826300470fe496724b110869c1daf86d8a23907eb4804f035dedc8449a819d166891623b93683448a51c529218e1e8001faad810799054e26657bb9a8fb381cca4cd141633a79b909b01b426e701351f535a10618129276c71a193aa82042472419d23ae180c4305098712996486f9a316000f29b79a0fdacd9664f6d85ac0a4711332c5f156db42f2b20d91a125e4763424e7950269e1f8e284e271a355b140a2dd705a4d0030e178b30d11e097e53833753392e600ed36fb413bc00a0b573cb2611b42bbd502400a7254e3e43a7ab134c380182e0eb021d0c01103a4dc6c682d07528e1e5b5db5dc598b31ab32791ce54e1bf7aa7654bb9d51b3064eaa2b7226c3649ab9903ab2014d1f5a3f60d86e2e8e7a48c9e2c2e9b0399d35ce1ab4138e07249d416608cc0438aa71ce509a32694c39a251a419346f9ce64c8226006c00c35ed9acd143a70d9b13c85c106582310e16cc401f009a2c5192048957171106865451e57032a00002ee59030d654f34918402560534c508a04696039e322638a0a540158d16391cad8e9c386acc942143820864639038d98842c380f9f22a5b64e8b7e40942737a7ba7c1161db4fa71ab99e9c2a5c711107dce98a9f2c1e3c512ee66abcd90c1c20a4d726a848b812d215a553aa69e56ec92904e1032b0a082158276bcc066cd09511e48d283078ca573073d5224b14a80c7518d86c295386e46e860832c12840002085b8c7059fdb091231599894a4467a14ba81c7426510e311344fa297f287d38e293db53ee50ea50ca295130d99460e713b20639808dc66c065200e58bb205b9b463315b51ee48dd9954e266b7f2c8662b6bb55979922649d2feff11f8ffdbc7d02dfdf0ea0ff755b76c544e3750af45a424b201325379e09f0cabf14f42c9e1c8db98539a62e39353266edee31a7d72fa15792fcd60c03c04a23cfe49f213c51081d7d7d6025b417a0b6c79f594f08adc04acee93d39a553458fc89a96cd83f2fae9a88a65ffcff2aaf5bf152d7eaf61513d194b7e8ba85b84da38cc2dc71db791430a738ba1a9c7951d103f4441e43ab13808e80ec5081448e5314b98a275ee041c2e900cbbe928060f5b084460b1e35d4d4106c63801b282b1f2f7d9474606065c184e8aa61458ba80afa0011420b430f1530f98206802cb99418c000d3841c51029093431b3f754e40b61e7438d40401dd8828a516548ccc401f1ca15eac4818464c2514a8c2909f321e38b1523991ce79320049e80691c7c44a9a27a41070258a1dc3bfd80e0e1ec7840c4f4eddf817a0caf14da4ab7faefb5fd3f3ff77ca1f606ef8d9a121febf74707c25acab27af90fddbd0fd9b83fe3ffdffdba337beaf5bc4dd0a31b65fff0ff54f9a3a2a9d8d07f7edc57db9be3aa53e3a253d3aa513744a21fcfb6e70dfa7eb746f4e355ff5e5fa767d7f185b9caec5fdbb2d1e022fbe7daf97ebdb8dbfbc6e2edf5db7eeac11252f9d52964e49019dd294cf7785ab066a95df350fc5eed34d00c875bae99a6f0240eeaa85f9e7044551267f9a2990b6c36986f5fffd754843dea26b9b7bc76c54dbf9adea767cd30c06d42b66a5aed56df3b06f291d17c8e55d0b752ab6db76fff6fa641a5dae8a50ffa288c5b57c5d4eecff51f4c9e9c8e98fa2fe3fff97eb2110e7f6ae39ffaedabb181ef620afc3a04d5f31500757a1e6c3de6eb156ece6e1970e032c8f66ae2fd5eb3008f2db987f9763a0d369a1f38fa6fa7785ab5e3156d9dc8a6df5eedd55b578b98d54fff2f04bcb97ff4737974ecb914f33b148d4ab26de3cec9ce7dfcdc32f2b1c398aa9d51790a0914239027de7ffdf18d4ba2c642a5e8b44e2068ee58ec374cbf6c4f0b067e9fa7f1aafcbe2d435500773da4bd762308b135faa7fbddc5a3d5d282763abd9b19c66313ceca9ba87bd75f778abaabaafba08a5cd5d6916dbbd75ef964db76e33dbeb1cab63395db73aab33301fd94331726ac68380a7a9d99496d5fff3764c953cccd4e20b3862226f52a6789d94265e27e58719482cd425cf42b57a162afa2c54a667a1baf8ff1c52d20a023c8b15623c8b15909ec50aff2c5488e259a8308845ad4555956ff143826fe123cfb7f061e75bfce8dfe287fe7f1b2f5af840f22d7c00f9163e0af8163e5efcff8e665bc1b6f815eced57b0e7afd8897ec58ee2576c422b744a2b9e70f9154f28f8154fd45ff1a4c9af78c2f52b9e28f02b9e44cd02103e8b1d966711c08f465b4ae4f44b8966fc522217bf9428e99712d97e29d1f94b89feff8f724b3eca5fa2aae297a89af8252a41bf44b5e797a86cf8252a3aff8f3b62b1e69f851a299e859a259e851a41ff7f64e296aad0bf5485ef97aa70f24b5524f9a52a1af8a52a1258c1824d9e67c146ceb36093e659b019f32cd870d14949f33a2922bc4e0a97ff5fcad15af830bf05d5a16f41a5c4b7a0faf32da8f87c0baa1c5e4969a903047ea98319bfd441ed97bc20fa252f847ec9cb12af9372c1eba454799d140afe3f87809da515b9251060fc529838bf0402ed97c64cf14b6396f8250fdaff575a210cfe0a2103bf42d8e375ffb9a4a5302c7e298cf94b600cfd129841bff4c18a5ffaa0805f02b3e73fa9858e1edf42c7d3b7d051c0b7d041e35be8803163890bcf2f2180e69710f8824362b1c6cfb358a3c3b35853e759ac71e159ac59f32cd69c998184c604c1a0ff7f17313ee0c2c2125dffdfd71c96ea9da4cdaa8ab38ca82ace0a6b92aaf2a4ab12a3ca8a2a67143a2a8388f8b32707175298f2024db18cca972d138451210675614e3d2a45a86851b12a1641858a772c0ce3bae70e4c730439b742d6cd713e92aa7bc814417f7ded6edbdceb45d6a79b62e5f3bab9ee57172f94902941745364a42aee3878d7bd42dd4cdc5e3b2df2b5987911b3ecde6b5f7358ee754dccea4e8bbdce71b097c3345f7330a7bd360b85baedaaaa833cf7224bdcc05ecf3ce78e53b6e865ec5ad51d49fe612c96883bcf44fdc5dbe23d733ef6d5128b047126d2128b1881b8056e620ea26ae05adc5999b8b3583de44586c0fc656c8b1ce7233d73bed3a29711e216cfc03507834686b05a15c2795e893b5df1116337f6ac81db2b49ebb5eede8bea025988893ab75d42cd75578b4538abbfd4bdbb8c6dee7d13e19a8be72214bd22e13dc8d50ae9412e638b55ecc5ea2117dbaa9a85e4766775ae89b4b9ef24ebd645b26ebf78c64a553dccc2e99adb1ccc47c05a4ccc47845f7def23c255f79d4473ade6ae870fac5bf75d240357ac5595abeaeeca615969065bf1911549e75848d8eecabc88bbc6be72ba8be420f66a33d86eb1b43818c75f5908abc1bcb8fc935b32f82731f827b55cf04f5a80e59fac80bc62e59fac4252292b2b2b2b2b2b2b2b2484520c3a0cb04f8408330a31e123f57c7e90f5c06007aabf430668021c5e50f272eaf880c3921bf428881112854da0ff32333478b165a6fb313f5ef8a24494ff0d0aa57b52b061c8679942a185b425fb29547835810d51bd043ec688e052b5e779a13a6c0407bc79a28b2d1c6602e0f9200955a2a8fdeefb34f8a2200a112dbf049014792a00227a24131cb26002f27e176b25d6a4a7ce37c0e6c9fcb0e2f90576acb0076b83349ff5378aa906d42b70030224c60158ffa36b015d9d2e517c8f3c2abca0000a855ec7141c4e5001f4f353c230747a85a01e9560911d13ae547904e46cb13a6a90fe93012b0077d3d21bc0c2a245524071c2d75859984c4a10e29b84e040346282abbf5731980e6812e70550b25b24e805383f434b11b5b7a3f53100f571a3e64f131f801025bc1b5642fc0b3b817e0413d0bd0b5f598a7d20e85b203d093b0bf17916797c582305b08a5f41c28b1c7c4c5cf89d05ba3e6cd239af8ba2429b314ffcbcd2955bd20373749f14e67240868b008f04430084a8f4103f4788802ad2467b8eb9038ccf35058d23ae05c0a2447c06fd8d060306b10e8c70bc35412d7d611dff084b0f1928d932f3364459b4307186cfdbd81b8c108148ed58834267c5ce0139e8d4c68a2053a881049d5a4dcf8b2e3185ae686354215294583a341f47f4a04de56af6878024755804e06753ac4c616fa8d19945d550c3c08a41c753100a1a74d1f2e6787630c4981550dad0391d58c97c5030f5a7ce8517273fd0b8327908d34411952482cc2f325021e1062c47f387e40676a4ec9a5103e010e109d02d1b152232e68564e50e602c28021185ac34210a1d8a0504a25352a0a7cb8c248ef8120224133e508291afdc71e569025fd1572ec13812c65876451a2203012135ea48fe9053d2eb5357a40b3a10806077a80d2902b9a416c6c391c4b264d18d16a64891509e461023a28123c9e481ab1c446ce848213ab8500215e442e69820043d4706f948a62e0a06fdc6f4903a1e6040009a818cfc016a3819ee387e21454d76a0d03b3e1172d690d97103fb7c90708953c302aabfd34290b1232eeecbf983c70d7904d5a380c2106548078e5f460a090612e0a1ebc770097100197ce739288186dc0871fa2c586454da8069f3546a5811ccb880ec2518120681d51ba7e78d02e9882bde3c91800c1619e145cc07db905e1a6840f53e105810ba0091ee970c22c7841482f348b03079e2bea0e7bb22a849c027cb9e6f00ce8e0e6a08a1e317b0f2b54f4cd0e6b36c42589800052cafc02e09a20f0d24fd8f0728e051040924be079f286ed82432e27560e9c006989b989f2282d0b587083d8f4a2193cdf030e111886108068e7430e59f106081894424b87803e4b8a9d3019d295fa3955265cd72c237313085108c5848fd0d4233ce10bbf3023091610a2a0910f033b834a9d10293f36308a2c1b3d364c007b005d62451aafe8b1b66d0d38306d2bbf8c5d1e34340c6b7504ac4228212b23c8b1d14c8828528c7af28a1098e467ac5efb2e078221362e275525888f2456ce9952a708282154a207d9298245817a0f879a439342421638a239f7b6285120ed5c87c0e012902f5f2d8e3f80c61301cf1f85b0d6146728022fd1b0142330814bbfc91058b225803c886b755314213b806e0bc0dca0e740868a2ec6b51d47ed88002385f33e2f066892a2abe6643737423c8e36920542d70c09b129e56b59400d58e153ffb03c49bb22c537e46650a4615670a3f8baa61802b8ee7cf21b68ced1030fce9016bc19040547f3a702880126e00e24f9d17197dc0e8deec61c5300f9b336f7e80c30a239c92377f3010ed90297b336a0a131c3044f8b2acc8973249a4f97287281c5053a58a2fcb6809b96ae8f9328a000bcc3002cc971024a93342979a2f77dc706827467fb90401120138219e3434c4951430703cf98356097666103ee9c29316210020c79322e85822aa00c293582e5881508f204f424972811433724f32912245068bb127854cf1431f2be3933948a8bdb140f824136f436784b027750f5820e308229e7c2b2255c8e4f88702469a219a14f827a24f969b1056fcf3d955d20b20f8bfb3039b274930f02f278a1a081073e81f053b5136eae3bf8c1690294af37fcc8fd4d9c6fe3958ca5a3558fc67f1eae2c488f94fe5050e2a1899f02fc103c511e69cf9ef3945423009fc13a5f8e0a99df90fca89e2430a10fe7d67f6e0619ffc2f914217018fa975eb5e54b717df2c57b947c76750ee8f34df8b678786785dd815498197e10f30373c49c118aa1fc7354392823f70aad0f870c9284f7d7cecf064868c52c117aa2a5418925116dda19ac10316f28841570fab2638a4940460f0f0c9d0879cf2a2cf8e287de0905498c67490312a4456d15f72d04942455a5154084720182e59c1a03b5546828dbc80d766eade2124063604492980e38ae4b2822d0a000fd021bd2875a11420dd21c1048f37c610059164510c8192e3041569669120040025e921ddf4e93a40911717120628101d1083a884cce1063a4f3ec48e64a046839c94900d22a74062c686981b41e5ee8521067450a74f9963099d0254f003a76ce285adb107d1b0dc728019020c250d2973f0e12380c5bd320380c04c130e1c5466d81c3d4c0e00f1994a78f5b9ac102c67d108aa01b674b599357dd11160cd923eb3434390138c5df5f2aad575f7883a98f36f1dd3449d16f1ba893afff06fc5ad30fff04fb86ab0b5cd617b813607d7cd655c7960abe66b1e02bb06cbacf1cb38b6dbaeb22be90be87a960f4f2cf0430b623428fa7f320b13033cb5332068fe9fc48001f4da98e187fdffa5121d78680323109f2eff6fb6c95df02583cd125bff4f76455105865c01602cf87f1302f6081a3e4b6552fc3fd984d894aa1216385ef0ffa79911ce74b170e14e8fff2fcb2860439308602b88f9786ac2a9e055e5ff4905346062848b0563e4fc3f298319a50706f64430fcffb20202964228a2801b70f87f922d23c10a24287902c6ff9329acf93d921c135efcbf79c80900b84943c3074efc7f49444b8123b2d8c842c5ff933a0839c6b0a14d0830fcbfd9628b1e421e7c91c3c3ffd3c0784144eea96a74f5ffa51187ba0460910745f4f8ff338caff6c110872781fe3fa77bbd91d3bd6a96c739c7c38b7de996afbc2951fa7f1a39e4ff01e686a89cee356ad53fcdf28aa03df3625ec7341135aab913f5f55da8bed7fbc3f7e4e4f3f5ae896d66d33c44776fd9ddb22cbe2b0e6edd1bb70a4ab8ea6137aef8eef4f6bdf25de4a2694e2fd750ebd661fb871fb8680a5c7717cbc18b7dbdfc336262aa7718cec5b6fb2e549ab9bef806b7eec5b7cd9d6ba1b1fdea85e5964533bf39ddeb9826728e876c9122a8cfb76260c7bd7bd35507efeed7898f575505d5ece5637233477251281b2bd7d7e7c33d1373bbb350af7c3b1efa72bbb334bef9a25aa8aae22cf466e2f6e52c647ff9d85ecc39a8aa1888fa541567f97210ea5e7c835bb3bcbe66a21177e51ceceddeebe51cdcc155f7d6acf6b1a266795cddbb8b0be53c0381bddd7bc19e585e7bbbf750756fd6e7bbc1ad629eea9eba37db43db1dfc1133316db1586ef31e8a69969781ebe6427ba82fdde2f9d6bd6a96e7958598edf13683e1ce7b1cb719c56d6e8bc17db310b3b8cd3db4ddf872e25e7f41ae1e71775e04e65efce9b6774ccc5d6b96b7eeac9e39e7a19cc562fc42b97b67f67231cdf25663f61abb4e75118a5673047ad5c45e2feede139a859865b5caafbadbddaf6f0c137babeef96ee6489c2e9ae65e04e631a2ee19a85bf66627be0ec463b9d7ee60cfc724f75d847271d7cd39d8cb695f8b9b88714cf5cc39d62c2f8891d7fa6e44f5356b15e8d32cd66cd806729d5e23cf1aed99a72b6eb30e1ac3b26e17408d6a30b8d3150f579db67b03d50ddc7db76ce63b88b5cab218a83b26ee5ec47785e260c01bdcb88af7cc6f705f35a79b7885ab56f12ad49c17519ef90da3ee5b9857dd62a26e599d6a9ee65f16a658788d1db742bed5c5bba9be3df36bcc0b187b984d57dc0ad1a91b5cdfa09a79d7170b45d10b850301ac0b35850096535f71ba6620cfe96dbbbe50586b1e3e70d134733ebc46ace6f40a575d4cf310c8d90c1c1b6a5e57102ede91057a5ee0a2b9988b50826deec15ccc4507bed22c14e2af36a7edbe7cb3abce3fe2e599a8fbcd2aabbb5a24b298c8c531d7dce7e33caffb66304c2cee1fbe5cd5b8e7f4ae2dceeaddfdaa7bb3176c87f5c6ba17ba6e7d7b616892db716f339a66bed70bc553356b7c7f5bfddd14af37739cd5ae8ba6b9cd7d2df276b76ddeea9a89c40dccedd6bdfab63bed45f6a62b56d56230a79d1b577cd7cd9ff47a19e5b96573ebf35ddcb7569edbdc81c5b6f3df567f97cb881703175f8e6fd7beac057cb7ab451ccc69d6d52ccf18cc190b4df5ed39d5bd9e79cfbcd733bfedee384c7720e69ae7350b7bc660cebf3447adbcc8d7ccd70dbc1008d1d2c2bab9cd43b1db128ba0bb739ed5dee5fa460e73c264ddc05eb0dd1d98c3aecfd7f7efaefade4cc43c0375baea1bc459bde98ad7cdf221b0c82fbff907957931e7303c0476fceb7cd558888d41dde62457cd5cd5baa86ff5dd3e14ea23458a40f99ed69b808f07db76078f1429d2eb759e7fbc17c459edb544220feebbf65a2211ed7bb7f748912257b3bcfcc358c3aec5b6ba78bd5e0fed63b9af1ba81683793572d1a7b52df6b4c5c3cbb593fac35ca79707f5458568be505cd538985b600bd66eb19ed79b879d63608a77fbbbf9b757271503b79ae6ce662010dffcbb4675dde98af3efc9e74bf3aa71ff6da78b6fbae276f7b578577cb9d7edf58c192cab3fac6a1cb6af70d5502b6e873dcdbcc8735bec4521175df7cd615abd5ce761eff85ee38a2f9a517da18657b8eafcbbe91ef64cdc9767ade6f6a638778e75bb57a1be3c13718bd9cbf1f5f5ad721f18ee77ab8b272cee61bf6b0ecbb74aebcb08d745796f379bdb305d849235f157e4b7dd9c67605e6f6e31bf685b4cafb1eb2b5c3518ee5cf7cbf3ee2a06ea7677ae872a5bdcc0cbf5cd6a31ddc4cbf5b00b312fdeacb2443c96efcabbac1ef236af623bb86f70ef96bdf872dd3376ddee612fe2be553e9657f429cdc0b5b8d7155fa37a391673ba63794d5b2c5c75af870e819bcd69de2aaa85c5c32a0a75103576ade2b518bc696e75114a6ed9ab597c7dbe9b875f3d3cec170c9887591cddfd1a5b1c7655558b5ddc71caf370d53988f635b76d1178f3b00bb946956531daf77adbcd759ad3a20ae443a01e8add4cdcc05edc4515b8eabbe2ab591ecf42799bfbaa6fb1bd616c535ebc5b5dbc9b875fbd9e8528d779d873181eb6fb42197f5b17ed36d6aef3bab9d215e761e79debb17c83fafa9e9eaca88a4080398953266e2f273023be551bdb5c74e01a3318e7b94d538c3af1e574037b458daf70d5394df156592497c8f5aa896dee39457d4e34139f585e755f71e7ebd6ed2ae6b86355c540d4894f5531b0975bfcabaaaaaaf231b9397b5db40371dbd70dc4777720be69d6410dcc2cbff812771bbcaa8a81175f62bb836deebabdc8ae3aa7bd1ec7c2ce73ba6aa16eb766790f1841358b6f9bc1da2dd60b06377ac138eef74630b86f1e76af3be4c6dc00aa59ec75d1cc1afb3566b08bc015c32dd76a905e2f77210ad4eaafc8de345f2d22bc2caf9be68ed7dc3170dd407ee4a2fcfaa882bde8bbf8f234e7f5519e75d72a5edbdcc732d66137cd7cb363f91a3358bb3b47d39cf95d739816f2e235aa6a691e0279af275c759b59aa1aacc636568f63aae3f794fc0fbb16a392c254ba1e837ad0c9698fe31e5ffe7b0cf977ea6113b4e3c1e398813b1e4a78ecd0f3ffdfee1d6d761c7738fdff4e47591b1dc7dfe970e05fb8ea9cdb602fee5eaa319b66e1aa81ed1692d34dc46deee1360773049ae720e650f2e4747338096f6eb10ddeee70f4d9e1207b15b779735d74876387e3ea1fe59a8703c627992234f5e5519f6f6a087a39eefc723cdc490592d222a5e45163fe4119d51fee9beb621de6a40914932617e549b588a2f398c8f5fd71e347cfbccd511cb4516b148c8bdb0c95c17466a176bf43a740dba42d06729de236af3c14cb7f04fa0bedfa7f9487deff477737343e4236e458f5bac10ad7b1cd7563c80d122acdff0eaa08028d760898f947a338bedc465ef7f569fec4b5ea22be74dd583973a72bccda2170d498dd21e0f48f66b13dccc4cdd7addd018350dfaa8bf88a5c34ebff8dfcee002e8f722dd68bbb0358f4802168f1a62b7e1ac4dbcc5ee34f0f79b1b87bd28306796a83c5709b9f9eb2764e41cc2fbf6cce6077f714ef9ce8a01c6c2d0e81f7f6e25e71961396616773ba73ba42af9adecc8b4eb6bb6543d03fca6dd041bb970d322e1b47a20dad4755550f796f0c13dbdd8138c883b9ed4ac283b965adfa9a816dee4ad7fd5b35315df76fd5442b1c39ac820c811d63ad5b0759b7b258232b66794fb86a6271cd42cc16302c40aad76655ddc0dcb2392dc0d663716e6bec6ac0a981a597e6b6cdc19cf686ff35aefebfc6d560041412ae1a6c47809efdcb2d0166f0ba7f3b02c608e8fa6f736f13e0f44d85fe3f73dc74e75127bea62f8f3af1197f4d63ff7a086cea6ada3121eaf5cc774c77b0988a7bb8cd3db1bc7e59d562d8cae4236e608f49ea3f5df76f2df6c4709b0ebb1663b2a95750efc2f0a8135fb6eaabde5d47585c24e7f60b4be3365b7124606b71988544b8ea21c79d5b0d3b9b83187b46201666d5ca6a0c17b950b8d55a752f65d922b702e62446ab9483adf808d88adbdc7758aa7b7d87093048003a021cdf4913cea4c94e809e00b6ffbf3406fd3f8d3bff34b8a6e1fb479d34015b71cba48993264c9ad0a0fa7f1abaffdd8c3effcf9b81e5533d83b79b81dbc978f38fa6ad1ef6b6d579d8d315df205b97dbf8dd54ff6458d9c9905a3730f355771b43600f6ee1e5c528b48b618698f750ec06f735fe9c621c63f8d03406d5ff7f008854dcf9dd51bb00c8fec1720fe0f8ff9b2b00253b2c808bf2fecbe90d06572de4ff1bf81d8c3bffbf833106a30b86d3ffff0b44ff2fcc84ed76f7c277897df782ea51a37a5fc078b4efd50522addfb930b3813b17c3473370e5dac515ba6b81685df1efb645762dfafcffb768f38fee5a1cff512066efaa7d2dae3e4df5efe21636ae715856f3d2a07f942359a293877db734bcb8b85b1a52dced023cabc596d53d876961bb836398d8e6602fb310f42d8b368f3af1b1bcc87b5998169fb0c082d9dcf67298c6622c7c3d1652ffbf6655c54316badd8a414576051cb1dd79feadf8b21657b0af6ece75ba5b71f5c3dd8abb1611810135989e1d9911585c715681bbdd316cb7f3fd6e47f5a813df0ef7ff3bacd7e6144cb79df7c6303183614cd4e98a81c09c847771b01e50773683f174d50da41a2b5d35985155f1975155714fd7e23e92ea9f4e893183ddf41ed1dd946ba77b74ef94dafca3dc98c16e27eacd8db901a50004d9da5c4a43fe95aeaae2aca43b99935d5ed2d8ff9af91e02c52e2fa98b29cd4952ff7c873488d540dd5b5cdc10ec90dafc231d39cfad70b7ec5db546eafa5ff30ee96655b8eaaf459707cc49726dd4de2e87050ca87bcf58fced723e15ef723f70663bef38b3b9c5217af4692d3a5db678d39c717a7041b63a0fa76487bbbb1ba2dfdd540c4cd7ddadf85169ce6d508fe574bd5ddd667cce6d707734c4ee88ec1f7d4a73985677474dfed1dd518d9d4d10fa948945ee94665ec4eced36d65be4b9e5d94ae0585df7e677f3ab5a59d9a254b5ef950b48e79a48d65c1df776b5345f5b45b688f4821ce10de969651d4162c44beb08c762b55e0d08d79835fe32717bf9eeeed7e7bb3d7ba1a9585e75f04092e6312d64471bd48b2c71037734385b55555646dc7539261a715755d51710ab2f2041233b1afbbc1ded6ab746cc35edfea37c372bc49bd1c9612ad0b89b1d1fb8debc9bf9b27633a7b0bd3b0bb558c5fceece3b689a772719b7b13bd97677523dba3b1f5d8b426e236b67d2f94733be3b93cba33bb32bb8f110988945cea51e75e2db993a60315d75a155efca3bbb92acb72bc77e573e402cfed2ad9e8569f1c735d0084c35667b695e8b3d1568ccc256e9d6850242d458cde2b103c790aa2a9693fda3ab0eee1d3976793b922aa797b72361ecce8ffcff8bdffd9d477d5555d96b2ca76b9174abcdb92bd5bd366776ac81de18184f8be75ed9117ff3b097ad2963f55599ae519f471b7d69e4e33fcd4695d19fff7f4647d4b7e6a198efb63bc8e88a118c471735f18bf02c3aa2b72b02cd7b8b863c9a2ebaa8a2428aee28e2a2afa221ffdf6ea06fd5424548688bd5a230119dff44c547c170d789a83ed17f1532a8b8ef2ab454618508d13ffa94b5da628e11d1c9ea8fc8002afa3ca1eac6eacdab1134774c05d9ff3f15bea7428a0a1b9ae62904fda3536049a7d0d1e2cc0f5571c8cc5e579dbd2e6a542f94aa668ec56e3ee4fb6ff37a88eadfd0a017cbebe5da100de857aa6e434754357485f656a751aaaac50cc1f8475be296c2cc3f2ab65729d897824a0ffa7f340a3a51b0eae6370fbfa258fa47b92eaebaf731abb1bc4271070a3228d847a180215cb5d3edba440a1d9165f52425c5a3c78ea011de5bdc75a178b9dd597dcdc4425c0ae9ff478fa4ea2ef4449f27b03cea5bf7cdedfe4ad5fd849227ee2554a8dd40422c10625f8c9054546e3117215b76c287ffae9f2e9413ef89e5d589a313514d04f1ff6826f2756b61bb75cb5eb1bc129be07263dd6b134a50308e9bd0fdeb98b8235c3513ecff3341f5cf84ed1f5d8b42e01270d0258ebc25ee7fd72d568bc2dcde36738ef3e5c255b32c56db1cb6ef16eb7777a01283c0d422d60d6e25e8f094187b75ef2e25ba949042d335dfdd95b0fd7f5e7983f4fc0f1293db410d24812887e5f58ae5614f824e8bd52230092c8f931882d9a7551b9d9028c422d1e67731bd3c246e448171dcdbbd7b03af3b02d1a7f8c8116dfed1bee6551389fa729dae78b7474439c2290377cb723decbc38ec4f3d1b9d6edf6b56b197ce883eb9dd4670415723ba8c7875efaecb8b3baff8a645c0f9018b2842ea57e4b7038940f46f6c35ff222210115830ef6379d54e445cfd13a1dbeb1083865f43e88b87f065551d826a085d5631173468af82e03c2a08cb7f2b68c83faa0b54682db64e81e0bc301097ffbf7b0d24f568e636d69d895708447773e98410b335502704054220f08f02b570abf8f2745571da6e603e928762dcd88129de2a58bbc5d22d308ebfc038eee9d69154f7fa0ed36c105daf62de0b422a887f6350f7bd02ea53ec0182c3a5d7330734bcea2d6601c1f8b5f867502e42c9ed1f3aa8135fefcf97ff3fecff9fab3f776fd60f22eca7cfa34e7c7edaf4d8dda67e30788e87c0b6c8e6b4a8b6b9af9a25167f3d158be535b746ace62319a8fb5e7b19b8e2b0145bf55455ffdadc05a6167fbdb83351f7de2e6e55cdbca7e29ceadc6e60aff356077bab629edb9d95aa9bf7786e3770d529ce6abae6debab530b7e99a538dd9aeb1c0382e92db9dc57fba978d98cd40ad66ad5b8be5b59766de67f87dae7e7d743f0cfae1cd0f5a7eb842d36cfc5d9fefeede73abfb9a2fefbaf5adbc1f60f830c8072e4f2a4e539e930f3e1fa8f814faffe77387cff1515fbb7d97b85bdf1e8af9f828e10303c8db33e8d13d64e89e239aeee9fafff7e9f6d8fe7bd0d30397ff07d36adf6b0f3e784082072e7c0c13c57230affb4650cdfcc6bad7add78bae4878f0e1bb3b0f543b08fa7ff41a71e73dac2df236ffcff558de61dd6040fc53559cb583921d7e7afafca37adabc9e313d4af45caef514d1410337e7f8ae37746873508700f2cc800a57dd7d97e321b0c82fd7c45ce4482e2a5c35be9c1b5bbce6dfda167fbd0c6c8bfbab2bddaaaafa4a751e258f3af1e571fa5e9e1cfae4d02687e37f0e4a5027be1ca4fe7bbdc53d877f3c7d7a78e0acc5606ef17cc1c38e87c57385e70e81c5dd712884c31d1cbee0300cd32aeeb13983f570a0c281c58502021cd3c26d1fd3e2ab26f6b8ce44bcae3982dd067b5c5315b98a891a985375ff88469e57adae5b43d6aca65b555542725b647bb9dd36b44183190c13815865892b4f67437f28a39adaa0800db6477151a87f44cc753aec5a2caf6d91bdbc3b83fe0eef0e19e6ddf101730ba5aaf8761cd4178a77878ae39ba6386b10ca6d64d6d8b3fad31db3443b5f50ded74c4cf3e5c4bb77b7a3e47fdbb109b3aac374cbe68e550ce439ab06417daf6398e53ca68a56bdaaaaafb13ce47888aae2ac1a86ff350ca9014607e627b9a5a110eac497d270a72db2bd4cc317220dec7f0edb340ca1e17e1d468f3af1f5d2141bc776cb0e391e0e559c5b2b282ba8aa2aab2e96e5e11b10a8748bafba57a7c7a34e7c6279ddc1756b07573de8cecf6086c5b99d618c378392ff2adf0c5233d89ec5c3bb1a91010f9ae6fc53719bbbaa835786b1e0be32483d9abbe6fbc69a6aa02e7ae962e821861e743124c9edced25a6359d558480ce90363b8a2530815cb6b9bb358cfbf16988bbc8ece17615b645b16d8dedde608f0171dfe11dccd6565cc0da41ba8834791672166b93183fd8adc981bb032e6068c198c8e6d8ea09fd3a63787cba34e7c602d26ce19b2380f7b3df33952e91c1b0c826028f6720430b0a8131feff5720a83d68fe9606ed99eaa6ab021c743ab2f76f7ccf190d5e22def6bd6401d0c1639ee38485f8b3b2b988ff036138b7cdd40dc6a55557db1acee2f7079a1eb1f15ae9a6b750f796e87fd85bb6676cb2924870ecf426191cbf9f2282fee36af5978f7663503af9373c5dbccb2bacbd1b9006715db69e797dbe83a8d5a31d0852facee2e0c85fa77f9ba39d6b9c082d59dd51d88db3be4784855d5d790e3618fd5fd4e1cb23863c4cdb318eec5e9faef0d3956791ca9ef716e6279edb1baf3ccb70a04e62439077b5c07871c0f69c3a04f3df3544dd5ddc253503b89e516a678f1eeb488896a91c3297407ed6b5e31b1cd2c1cb2ff9d16391c1fd82e3eb94f4e4e985c1e1c1cbfd3a2d7cf4b2caf56aa8ab3ac2ec7f70b0890b18da5aa18c8421f38a8131fc7bd9d1659f8823af1193358af671686695e8bbd9d16390b5b3b2db69bf735f336ab6ae656a95e41c9ff0ab7880a86805a853d2a60f97fd4f8bb3a15a8d0540518588cbf29f446cf7f1f0a8bfbc77bf3a64bf7c6f628570a7ad095e3a19114c852184b61c8a37d0b2f57d51460103130ffdca478e806cebfcecdd8ffa36ebe8838f72bc42b26ba41e0ffbd5e87421fd427965714c8fe1f45c197a6981b833addc4bb3b0f05aaff47e1bfdd6ddac06943411b2ad4e7bbbc6b75779fefaebc3630d034b329c46231ce86acdd6c94a0696e81abf6a55b69be6cae1e6575bf3c36babf9181586c4d218ec5d6c0f97f148b652edd1ad69781ed16e2ebda77796bae561f3177edbb2b6f8d4e8d2054b8aa215393deddf3f04ba706c60755bcb9d2144aa3e7d13458d250f534b6bda2e9d3b39a53346dd06041a304e55d13734703e3ff4f28f4e89ac170a7f3a8aa62609bd99e79d609ecff134f1872028c47cf08fa4757ac3bf3050fc5569d16f73d33e467a8cedc6bfc99b9f38ffe6eb7b162e04d579c875f66ccb058ccccf1df0631f72d333ecc6f2b65e6776f1e7ee9cad0f98eb7ca7ce9d978fbaa8b9419fee536cae87c41c670111f2e42c9b73501ce3f9adb4d34ae78f30b95e6140faf094754b86a62ee5b2648fda3ac1ef2dbf79a66225e6f1e7e99605b3551557925080ab255429b7ff429ab3f7c63ddabd34d33187013732f61ec0ad7dd8af112ba70567956774b460a3c348e61e24d73aac388b9eb54ff3250af995bf1ce734acc7dab0d1273d7418217aaafba885755d5576e8bdd2addb2eaab2e0264cc8ab3fa6b0c17a9aafaba50acfe22e6bed58346bc72dbd56663f1d74bb358c7c2ace674d5c4145b591539d70f6469312babad0b65cc606c116c6f22bdaaeaabadaafa0a6e3a6b91ec0bd9f09fec8a4cf7305e174221d489cfb8dbce731ac29d10c842187bd4892f84aedc86e0d4330f01843e2090f572cbf64018aa2a06e1ea1f04db8f1934a6cd98636f4c17eac437a6672e0691983ba8139f18b2e7acee3d2366c75027be166715286608cfbab799dd2d2bc6e9bf2dfec43ceac4a70ba3e73febc290a14e7c618eab268651f299ebc2383deac49781ed0e8241a4e7df58fcc9781d18332c16e33da2c62a10cc918873eff5ccc1f0bec7d50c5c31505b0dbb7ea097e656f39cf68ceabaad2e1410604ec2cb401c24af5a4d714ead70e4281ad5317ca12e545f75913062eeda2a0375db6595aed90a48668d5f7dd545326bec5ec4dcb778e69c98bbe63d62ee9af3b88ac3ac8258754dd4442e549ad3b5b8b170c769bab56eabbe6aa255ba45cc7d8b98bbeea57915dbbc2019a85b9d7aa084e7819397ae0395d74194ff57316e796d5ec58c18730355555fedeeac6e813c07e96399cbca0a881690b18df5ff355ee745d07b31e3c5d85bb1ca5ab547da9cb6395d7330b8b31077ad62dbca0a88968a8beb565f738bd9209d67a14e8d54550d391e923beebccd29ce43ac800073121e5cb77aba3ac191c389148e0d72f87fe26e831b1cff3fcd2d700325ba0d02f8b7fa02d26e213a0decfc3f9adb2ca681190d741a3890f6e096baf7afaaea6b775d1741afeb82a5eb5f36fe8a9ceb9b83c1aceb42a5eabe166f9adb9b7f464cd4757934cd4f46b5739cd5dbb1d3cae3d2a7cd418e795cbe3cfae474531d175f8a895d03358f0bd53f9a5ea3aa168345bea5cfffa3502ad67dc537b79b78a1567c8318987f37cd2cbbdbf4722cc6db4296d7bd650cd56d91fa7f94e7e1976e8bad78b93ea2cb40cfffbab5fee932f882738bbf32603b4e6f36a6ebc6d2657055dcd78859350f6f6ef1cdb76f2e5d0601a87da844ae2ff6991ce51442cec8c0880000000043130030282c188e874442a9ac0a1a9a071400086ba658944c9e0893244d71140462581102430000000000008020004f35b2d55c2067be45ffa273a9cce182395d85390d3756c25542fad3f1a922a59b0d82dc16c490994c63cd58f3abea61833b69f6b816e0361d60645c88ed907784a668378b98c2b086296856215b8bb5e6c8bb8a2558251683b96b13f3128f105474e422174963d3b611269d34d03d00477c871b148c48d08b06b580fce2672cb4f428a63b2a10f6e52fc4897e776b0e07f89c979c8c737b2fdbc2ac0f48d7e154d02b0bb31b31da63d8b6191e538788ecf6a574911d109169f0ffb82308663be4c84f4be2009fa036bf607be8b1d35f3c0061878933736788754f7bbaf04348005fdc573c8682fa29db99be6b10f650ac7dc75e8cf11a373078efa71a1400ac0b8ea44e20a27082ae91ec98e392f72e402a9c10c26b6aa096441db57a94b14ac1f80527e3cb7ffa3d235a9df20ac1872970bb06d0466651c3ee83a159440e1bffd0ffeb9fd8cda10193852021bae4d8b882ff7ca73f1d182d7ac07e5a19da4ae11cd7d9f611d479dd2df56c8870510cf618a256eb0c4492b9bee3cbdbf870703d03ce5d50b985f0063329ed15a4ffa90a031e008d932babfc950641838ee5e68890f84b0a6334568cd759e7142f03ee441dc29dc0a1154838da13e17dae7f2feec3308a2fe093c66c57b3970ccf740d7b95ac3f049810851809fbcee6a156840269401f8694d5d00851e3641c1d48ccefcf2c27961bb770c23c38a195ab8d43d74c10598d6a7807c1f2a9cba4cb7d9b0e0a96c46565c033a0647ec759f00b8992ca314f46fefee8eea3d3d12b1a88d1561349a8289013bc05e57e533897a1095b1398eca28d1f27b537e4a597d6a1234d37ffc5c42f4193e50425f7b9299a8bc235ad05dccebceae87d47daebbbfae837b7856f04423b38c169c713e25f0a61615571fbe4b38b20fd31fa9d173a0d33ad18bdc41f6fd1443814f8812fd630ac5f96e45b2fca89fd00ca94e74db0dd389c9b66359b59506519a8292ccddcf0e61664f1debe6e694582f8457d95714d12b3c9e7af9474116b21d1034b9d1b122ce93d3e1162ddb645e577902cf57b5e1d211ebff2f99549be7b52a30a8cb7ff24904b22a7e105b08cb1331123997da3d092fa2f40a201e9641e2ff24d214bb35b64da132853c8ed8cec746f5a581d91ab059a5eb1b34fcd4e3e87d57a917b2093df7680e55d27c5d53c0c5afa9bfe77f9d4bf047097be19126d708775c4723c9293f7cc40e206b84b7854c92b88fc4ce9a91ede50157ad50421241aeea3e40414f8623bb81661c9f874b5fb00c1a09090a8dd338c334c0ce79d481e989d7f3ebffe779b5365d19afb89ddc2d1cc314b36fb45fa328217833270ac31b14d09a392005ef90b38da91905fb7fa0ce904b732fd0ec7b771545b421d4712d931727715abc1934989a107301f35aea24ea6e9beea5f530d05af7cf46e1c9755e159a0e6c454e9d84be3c5dbe08b82559fa66e494104502f2c6cf1766690ca9461ced4d884de16fed65804b6739f01d3ffd90f5cfdc2a56e335a19ac42985c681af3643af36af9b584032103f268081ffabf3b8bf9cafc070a7c4f4db458fd8b30fb1dbc7473d386c69557e222362ee0902b52118adc0a39bba5a1d064ece39fa0f72a743bc4927ff6b5873fe42925af4143576ee3fc06c51d9d96ff490d344dee430893423ed8a50dd68dcf393063bcdb4255e3da43e76c1d42963c6f9231dba3d91f99357e1a1b2b61d108c6728484a5be35b4a6e47cf3eefa8be80b61a3876ba8e0ccc4292689da2277fe63036cd8f30acb0d229dbfd8d5a14b0a6e7f3e6c3386990600555232c872a6b569da6b4b43d5b3ccd2b9e06a425184ac84849ea36b839d07c6767534b010e2e396188024f9b59ac71703a1ccf990320a2a2bd75a75195a2764c266536a2c45d694cf6e10b9b0d7848c4a187fd7f6427710409f4a85ba2ec499d51ce96dc863a707ef1b888e882b6084c0696c96e8bcdc467c3f94c8f653ec61113d55307691e813807cb2fe6f66caa68076919481c0347e5ac1fad6118973228a79c8b8987dc02e2bc3d3d0d8bfea76b16e5caec2c8352a2c59a7f3e03ac1c212423a6136ad1c803a74257d00718ddec662a030cbd879c8a114c0a46ebe331c1ee0392e72ddb53c2319c939023c661de3df5f0056969efd23bc66f19afb80b9f680787fbcaf6d9c37e31b3a280c25deb3c959a24cd15a6189ad8fb86465442bf645a2826e957b6071971de862960810f9817d11f0bfa7041512b2a91f71f1548fa575a65522d437bce79fc5e5c3d4f6f99ab8e4e03d330e67a0dc4f0ad202e13be5822d47073bfae19a6befba9cadaee76e843f596b5539b83f16fbb389dc94c014360a8c6cca2ac94161bd4efe060dda43237047cd44b224ce7d3979f61c7b36d177eb05d07a14cfae90a2834a9324f07e7f0a0e092ee64ad9f9268387dcf9fb860118f50c47bc9f644df0a539f1cc0787587fdb929be0f4fe605fb1cca23927831023e6378a27cb7369a1c0d2e0770fed5be53b56942c111386c52544bfd2e814a5551c226ee266a8c58a188765cc6def18273c620f31d5f36b37a20e9953423340c6f7b315047d5045684e5b770ca33525a6c3808c5db1d392c6aa854c0e8d374fea2cd7126d3e96cb3b9944e4d81f77fac7a2adb65ef36d126cf6e33b70890fd0da15a6c79ba5380f44c93c25e6e20885a1eb8c1b7dcab5a329dc276986734047bf5ca1eb2bb307bb2c3eb3af2cd8003886f4c3e20de173cb54e1d1687cacd5e87705e02b2486b6ea949104b923707f2bb1ef86c852047b11a45b335b3b2cb8b108c5e24121d18d8846f9ae5d060e4720dd5a505708975c1f6a56146c8513d87187fbde62ca30a580c2e5c326d8883a64b622def1edf8529e39893e2fa4bb169023b737bbd968aa7d1dd74763dfea31e43378daf0630ad99d6e32e28fd7860478313d5f573f9b35fd6a79d2b2d3f6c5200205f715d0ea46980536a8d250280566c87962458822ba4fce3c525eb40b0357ccbe8331df86ade0039417a1f3fc49d0ef1303327c0b68c963dd59c6a4e47d2abcd2d0e6263cad2b5badfa983b8e98a25fb21ad79e245a9e9d3b1b708eecb60a69a6ef22976e865d1eee56077b7f1f68b8fe7b16605222f9e7a3da4261a180c88e0762dd204cfcb37117c88fab08190ad709018dbc24c3777f7bdefe6c22a15f9a5cd4b493a2d647e11ce419b96f1b7ddb2c7cbba57e0a31be2641bc9c5af9d6a286d960e29b2183c6c48f2714271a21eb552448b25017828ccb02dac4fc5e409e5355092c7b614772c05a3a365c30b1178f15409981f4cfc375dfdc7777386cece4ad722fe494c0a30f623e6286cc1d395b7334d9850ca63974006bec2d87af8e78cef03af173778b67fca19ce956c8240fb19bb2e06673dcc5db9881b172fa9cd6957ce77e424521dfcb20faad18bb493349b2f3cd4e32f05bba1e8c790c280382241a5b4f2d1fe402df8349d04ba46b9197281e2fb442d46e686bc428b44216b61f0b8cd48c2dd3cea046607de62a8a4e1d8d95d3a3537c5f07aa0f9a593201ef3c18861a9a44d6e6d1fdffe713912c42f04471603606e8e4d9e446b77bf891fd6bd7b4acb43e67f75af03ae435184098774d93a8745856c3a1ad6e18225d2401253aaf0b8c635de182085ec70ab8c2992b969661af87e158179d9ba6a06873b636149d3b3dec8404975f9b19c1ea8a84c807de20b85e979aa54f960361b7a2e7c226e8ee01ecb68d744532f791c79f90e3b46d4d73bb3818d481fcc782e7f592964006b93d45dd773d6b09c3e3e77a76b8aa65f76f17b812bcded9f155db7e6a480bbf503cc74226a7f941b50b9fa96326369101e86f47e32e83b8405989972666afedacde74e064944f39f1402738aa430d967925fd448674faa170f91218f3062570f95a7d9861164a5a0fccceb05e2e2ce0e3010a98c4c62444dff94a6919f3262b2ab3623f903f4e200a829d576c7b93e975da6bd4b6e84e48a0a4eac3b6026d55056a23cb89a09a4e10673c25a1f5cee8b7c77acbb1c5c9ab932d1b2a429449b59beaa33b85aef04019cd74f1b0708c0a91218874bf4e50b6628593c32f0de87d7d8654a786b9a94d29f1132ab8bbc4337a220e90f1785dce9cc77c21c6b5614038d80c14ee0458036cb4f55b1830ec4b25964cf5e6ccc5d699dd68e9b642e55d78ccd0364116dd7d657b85fa328c8a6bfcafcccfdb180cbc2733f9f5080bcb8ca9b5c200761a391683cefeb7a3b725c171c1bfe1228fb4da4a6d9ef6535f69d0bb2f726f02e7690d784b913c0e00b45ad6366e24633716ba6ea678272fac01316323f18c350303e7711945d008b10629b235bbe50bb0d6a5d85b054def2a812d30c2e572cbc049a910d6c7c638e2e8f077c6cac818241cca145523f2bf9c1e5b7c74b52b02fe8c37352c17dca2dacb3703ab660f28c5c6bdda772073253c42d57365ddcf114caae21a6969c1a22296530e7401079cc057060468c21d9bec534bca5b658d4cecc32cd762a5407386e9aece9519e85b7d85ced3675926e1466525f6b561c08b6425891feb9fe5885d4c4fbd223051ce20ac7d70f15720e25f480b69fe55a0e74d730c450e409a830bce64a932a4d491d8d1137039bcaec675678202bf430b873c133b720a0a6810ce2d19ec03524a314c581eed6d171ba01797e6c02fe8d892148593c3f982933991e8e11e2b16c3df0310d8104d190fbaecb49050ed62cf2d35c3d553dacaee1b47ba26f948780dfb5325412310112ad2b8c641ade0c13b423edc996d9d582a57fcc3c767fd9336260d00ac30280e8c9795bf9e53178e1d11171692fbf00e926f6b372e9810c771847f9bdd363d2f9bf48c1942d6d670442e4cc83d515416c48174bc4980fab13aeeb2807f7bd6e5f9adea1f2a337230ef87243f307f6bc55b7c1da39ceee3831d8c7bce1097db79b494b52a42d864453b3d0858d0b1d81627f5ff5b90fa9e82b5220d862a4d08ad27ca8c07f98783c2631b58e9b2c54ea46b82991ae3d7b773a5ac0bb6a06d98eb39460d5f6ed484be71f0c06d05177cee4b8430985a3d61ab177cfc18bc737c3b7b2c5be85733e07f2afd30b24e12f1104e771e04f01718e2b9827135edd67535d9c14d608d9310686725ceac3d6da1f7c1836baf00d272e9d849d195cfdbb43af0bce63256dc8b550745627e795d6a65867f968e20dc4a6c55e48fe6ade2775a8073342c37f17bf475b4f3cc9fe05ea08194647e813b471909f79f31534492221c85c3407c0006948591b142982f2c6363c3f4792d55744b7727556e37275c416fb0b79f3dfa6e4c5f548a85c2f2d6c7296d6e222e0499086c2d36c3a0a9e5c15269ea98c1a71255595c9ddda565f227127d2006a2633ffb3cc3ff3cfa8c1eb6639930d6032224bb7267db447d8c20395bb0a24672c4147e34bf6358ef2e63d2ddbf05206ce989b8ffe98f7c36a1cd19a9f2fe680ae3f19eb943e53b0e57be2d0a520eb7a26184a5c35916cd863f29ffd15fc5a47fb719e3912eab48ceca7053d02d6d75e2e77bacbb8ab563c2e8acb05b6abef959adc0f6a560beb54c94b8b0183d41a201534084b9e8592546d126e6009806e01cdc7a6c24d78ce8c879d9e23efe0f9b9e4117c2c73a955c11f869ae69bfb8116e26153f7124c4ead0a9f145f816ec6fda4866233c212d24d293edecc95cf1889b25d76abc04a8e07de34e09e980c72dc376f2142d29d7278291eae35a61590c08df6dc45045facdc4ed70dc9c0e60e3dfc72dc1542030e162a57b008f0da4b0d2a938d3803d59e14e43a9f599d66091e7eafa3d213a8f203808ed6d72d825335e359be2c8f380c16e6925867efba3104baf1cf01e8326b700043fe226b65ced3d1439be8052014bcc808480148ac0d8dace5caebbb14768c648fb6f94e5499d106e10c110b343b93cbbe002673ad911b66f925fd16b81771f1d8eaaaec855ee0485f28123de96d670db22586b2af53fed3891abf94eb2ce20e953056fbc6ad36186e82cc01042a49c57dd0fe22bcceb789ea9641abf66ce538b0fc8c7ad8d5a423afb20bc00eeb21e4769e8012a6c4a9b86d9755b03d632358b557003dfff4ef43645dd39039d3aa1227c85896a5b69d8cd0baefcf6c82028601bd514c3d42a80bdcea40bc229065ffe128f926469894197ff4fa129ef6c293040ffce3c5c3423535ffc3a190f1fe2d16fd355f09745f08fa3cb34ef90a03b5bd74828761dfbb6582e460b0101872a33b8b7d73e0f5a14903b706952aa9311ca1dacc80a9a1dabd39fe0d8f250d477aaee9baac01e69f7fa22229a0c6dcc5d050c63d2a8ad3a6b187cccae8dc1f94746e03606f6cb9c92773939f25246c00bd05fb41da0be764757d34d16eecc821ff098aea453553008abeb98c9804507c05e26337a15c2f6c438ff7ac7b9da646b887be80bc77c1895f7b64167dc631d09eb8ef139a4a0ad5929f279dcb5426d2203c1ca36c5a863cfdca02653de4d03f8fcf9c46520599843d18028cde3aa26dc2006026c389a42f5120b8977645ee6cf72b39ed98fe39d4643f507c60669ccea84288d25b18957a96d7a96ed9bf7c08e1ae066d7e2172f182341f5cdeb9990b40766d5ba0c5c542bcb3aa2123e19280f3911cc7f52f9d20409933cbfd64d6d6b8f02d6854d81fdf05b260eb04d3476b8e08db6cb6ee55353c4171e7dfcf5d0498c1f68312d9097a0343f738a319861d71ec2ae17385ad066758e5e1c3ac22eb08836040c668beeb82d59b6562d20d872d257f05371457ae8665106e02756c55d6012dfb362d8b2e3edf6c92502a23c384dffd54349edf9663dbc4679b8da608bda59cf637efb97f6095bedaf6d736284245ee392f36e29ea5565b37c30e7219d2fbce3911fa81e768c0eea02d71e71478b64111a04871160df900ecbf32b176f0cab1b9a5758402e8aa357a0d4ce40c6898196572cd8bf5be00a210ae710bd8110f0956654d343581e84b9077c0bfa27015913f3658d2b00c83df5195b4625dbbd6535f0931ff1415fb008537a653cd35d3434ec1c01ba84253060cef8377b78eaceb135c6d6163b97158da1be1a0c020be2dce4961cc77a564862d803651784ea11bbcec3e8acfc8a09cc123ca22d4a1e926ccbf8b6ad4602cd0311f530aecdddb1df16c6226c40050a2883fa7daedd0b5c04aa3bdf8800736e7b87c19151980338b4c33098b55a84b54ba392dc91abe2c2f57dc40a4234024e80022557a6f8274e50d373652e61563a4c0e0023b173af8c539db13397c5b8c9538de452d9673a7ad64ff7252f1bbcab2e13d4f83254bdee082b0e988ff9ad450ed08546516dc55fa3d7060ccffb0bc1e4db64a03bf14a94fa345d9e6814cf91d28621cdc7c2ce68e095586456705469735575fe2d99a7443fa8d430f6c2575a681d53145acc94b18b47b2e0c5b228303ebb33564b2ae0854996aebd375d9ce14d2f418bd5ee1d53ec71818bd64b13b07d21cbd941543db01f692f420e5cc4167af9df81cadc9a9261200e7ba8f3a6f010469b83b0d3b6a053c5a368d677e4d55e71d17ad87a272d8c88bbeec60c233a841eb3b5ceac8b24e6ee901969f8be478f48a479bc711850d963d11c59f7777936740529314012ab75183945cb50a796001a01470532772579d7a1472f4f736f1fba36ad068c01dbb46768d7429c1eb5739f38ce6f42dbe4c8ae085d3023e7a375fa1a5998c66c52aff346de1bf40f0e849cb77d08e90d998475ef839ddcab51b2b22a76c401899fc5ffd5a8cdff5681b742511967d1ff96cce4824795184374d41845ede40bbc0dbb12d5c4913f48e1068e6df069199d1dbe693183bacdb13043238ec04cbfb835f65fd12285d99646342f83122d172552ad1d60c6304138d4aab6f5eba6b5a4fbfae05eec3e1b73fe394af8d34b5ba36cb3a073547450593880d77f3329e93beeef4e973d526c588da9d605abe9aea7b18df1d5fffd786217dd4abb87cf8b558c37c210e606c010a493a130c059ed9b630810bed7a5dc3f374941d2a49d7ec5c120ebf8132141d6378fd1cbcfe103f8c1cc4d1713bb7f3562325373ff95cab9e6a46c95d453af840ca5d7375022f874adf1340000e1bf1205a0bf44d5c713647e80f6f0005bf5107631dd5b1d387d534dcfb7a62e5a0bb5b983279d5283939371813c05203d102fc1a2d62e27c235307cf1d8e85d0469b1c9a43711cc245632d9cc1dfa5e124cd50c04ed7f4f0da07e3f2865e94636bf62211ecc74d5dd7d7933f7ff7671e417061c4aa65d7b8a908ead644bcc21847f4c3abf4079d86718f5b80efb37e0ef53e28285d0e9dfb3e6690b72079bfcfc135a214744a60226226625fdbb29f0957d65aa527bbeb622b9ab801a703cefd4579da4ab07c56d5a00e5c95e050f2fe1b5ad851ca3ebf2dfb93402e109b657d5d2c3b6b9751613578d57de15f166b7ca0e8f2ac709562288e3b8c2434893fe74b18fbdcc9ce2a9f59c3726ac62ccb8f7f7766251921b26135fcc44aa522a766348d73d4d7008c6b553a79c4cb8cb6eab9810ecadb261b2b8cce037f18c52b34040a55d6846c60d1954eab0061d1a716ef5a71f56107a7e040ebd09fec79143344f53f140cbdef9676b384f1742ea0a727007ed0a8e52029b0ed6ecdfc5ea333666491269de9a2f7090139b11cf8a35869ab1ac30b1e186ec5c01f03f1196f08d2e9b4e4b769a703aa31f8ac740291a30a2705707838d69c49cde8e8a62bbf4425a3f8be05b2b43d5a159fa0ea37fb05c31ceeb06e85d578020a3dd047789feaf3a75fb6e1a8d0d97bc06c2b19b6bc1058a39c8489b975f06423ab5df3a910a49ec7aee581e78267809f22d6a63d87cea3a25ba48cded0904ad5cc31736c15538f85eaa091ba6f49311016e17e062fb88c62d16a53724cdaaaf21619dfe9c0b21a2be6176334e541fd281041bac1f92cd6652691816123ad1a2bd6f373cae9fb4b029bcf35d7294076b8e1050dec0b920af5f0cf1b10c53566255f897e1186f03aeda4c4c376eae6d066b1ce247c32a9519e73c9bbb2e2fba0fbf5a9502d5f4db3a9d65b99e41c1476847787a908cc3894751066a81017a046efe2a7b49a9c7209f591886499b45ef2aa7c382a6c5c2cb81817c67b7506c23e39f2c147336084b6e4c4d2569486e03424bdb06073aa79d930c98bd924498053ad4dc502fbb6c591d30b30d20f076ad1fcad76b9a999c22a2ef3c1a5eac2fbe044c326322fb8621b34a876491475dd05dd9a0490d74e0d7b1932c65ad3934ed651adf09964ae516a7ab52cc8d741b3c7a4b616766294f79958540f6cc567265f9735b9eede5159ee2858514f515ec571c6cdb999fd979c009538b4c1c10aa9334a3a0198731a314c94fc0618311b80be6ce6d2cae5dde382a2db518083b91a6fcb20d843dd4ee4694095b68d00e31317f5c069fcb7b8ff82158f149607f04419eaabe3b5c8921080469a2b50e8f1827df5c792cafb76fc7ccc9b7f98bd2bc198b150c06afc29e7c3ea0e34d67292e67ea8872920e67c97a67e78529c461755cdf29dd60cdd145fd6a8d20309fb66d6cc3defb9d37e23c586ca1f8790825a844af6a866fc913a2763640ee064c4f042cd19f8126993f296b03f75d1c95fd6ac4683cef13600ac16af3e591095c52e1f2badd3b1ef81360e4afcec6eca782c88e89faf9a10d7eb665011b2588c9a0d271e058bf81a02dcefad20a71e0aed63b45dd1174e29be2b059ead9896743abb051e6c0f6bac11c5f7703e88c03c5502d3c9d63da1d2f74042040ac74f057fcfbb4922f102887185cec1246073dc12049f998f5ffc5b617d0e783c515f962e568eca97d75533ee145ec4787b5b0b478745a58e54b3a58d867e7d8090e14d0e62e909ecb26cc576b3cc1a34f1be76972d4b65ec89fe452e75789358a09acb08b56289206bf39894fb1de47165cefd08fb8c33d7066271668844b1a54a9585b2cb364c60dc627dbeb4a6ae2ca660d6b82b338540b13e3a0c004e0da2ead5aa92021b8c09a2ae87614aa39305c5a195cc8cb7d4d1dd5461e79bf9d856a369cb8b8c44ca5bb5960e63d45a1175b79c6e53f765780e7be3ea214651956393ea1e9fae7d5ec40546b5d7bd2475ddf547cfb2712751a37f35933b4c3b802726693b5d43d04ab0e901fdb83c8fd434246cc2d2ca1b825e22daf44096d834a17969f2128a0c5525e6198b23d92af1934b565085195f9505fd64f62bd1919e247e6a7805084b96593b679df9a727dcf6b5c7af5f6801e639af357c10bceb5adcab0e7483c8ae29522ca6e019295b0377a644ee1abce872c718917dc94a1b246809fc7a77632d810ebc3e9dfb49f378d8cb2925840386a373563c55ceb7d3ebc7fbeca4be0c365786bbb56bd9ffd5cabcd9e8cd26edf065da0fd57677041d9c6e871a37c01e90a26f0ec71b1a71302a85006be1c553dee9eb16c6bd8b04631fd4ea8863141042eef2759a398e357ddfe2eca598a9ead6306725aed973eaff314ae48526069df7749590f3de5744e2be48edfd6bed4fcfa3919d4924da8e94216b53d8b73f1b93777c99bec97c8a9a004691081b91722fcb52e499efbebb5661035615f8559e7320b358dbd01379b47c1449524e9074d51e640db2aa66b1e5ed45eef98baf3efd295670ff1d4de9500ae8984bda4a527178cc6bbee47cfa2701e23124382ab057a56cb56afcab15ac093901b23a567271c61f5a64c3a52d5453c8107853bd66434d5d09355070777b83f6f103528d757d93a0546a63640702facd0975a64b4b0d28a4e4850178c01d94931df7eef1178fdd9f992f225a758667602c72febc7f601eeeab5f80dd404a3b0857836e43fdacdf17a8ed5df32a0013e670de7b14e5a2220cb7701ce8bc7fe364846ec2766cf29d38bd9d755e7555625e86fba836b951fd3bff8670e073420279f96f8fd151f15d69a2e3422d926f47302cac79cafc57af544fc1e79b09ae99b5e36189b0166db0605ceea898b4670533ca0adeeb79ef1307a6d48bb080176dab1de6040694fc7f36cbb3f7c9608d035e9b5772c3e0bd8506d495fcc7184b2008442b14b358c378782407cc4e928f09c9b49ca076e861ac5df988fa93db7f2e6b4f477ca014de53d91db06a04dba1797800d4c2aa8092682e13d77263503b449183fa23818d57deb23faf9eef5f146ad52bd8f4d005321af1ac89bd6d1aee9bd921101f844ddb80890714cc06af0abf308ea410a4e5a5d493191df466e9a6119b8f3f8311a7fd773562c7a8c20caa8abda409a69e5d9bc18e5175e147228c0f107ed75b26a24b0d598c16f5e8741677fb53b122235f8c1d43f5af83adb374d01d0f41627ba2e056f4901afeb8d5fa77cfff577761b15746759371d0560100b89f7f4063bf630248b8b0ade8dcf5f381403d24f633063dcded3741756251761b1b7c3549efb9ea4cb6e1e854d3ba182cf5bc160e7e546848fd7586150b7e9569cb8a98f8d938ce51dd97c1cb5d0ab552961e9d78bd92d1322b1d4376e4e9cdda9db00d2591784a099fe295f1fffbccb639f9a1a32545864ddb6cae6bec931237035542ffd28a5f6401d189d1d046d87d5c7a8359db287ff291605a763999997294c1215c93eb42cf2221c704fa5ce65b689765fd50fded6d7d592e8c3aa8105e7dc4a5537b2f98105ba25cd4d7e1ae2ab49281bdb03c4db55c0d93aa25d88c7597205561ea2b539f34a9cac10fe16328f33ae3b00f582c7206a2a7e96ec8c95c9b70d8386e7e815ce95dba7f428c882375548d6e0c612906b653d191f5569eec347ec9a0c9f69d077f66452980c4bea05ed2bf4a35201cb61dd1ca80f8494d691dd390d282186d6c00d9ada7cc9c40fa9a26ded81e1a9498935f92bd423bd9937559c501ef9c51a2383ac5d53c1419972f5c2feb17c3d23269141a12e50988c2ca87c46ed58afa7a7c6d5bcc9204e27cb5fba851259dfa1d4178781ea9de0b5f4020388341e900308fd76d2b1cbbaaea09caf0fe3721f4302575308bb06261e3d46c086ae9541dda0b95d33b231118fb5fc2e5ff5b7f5886a8b974ddd6ed2e77c4def0174f2d0d4e1b10106378436204dbf3e0c257c060fc520dbe72cc758a069bfe1c9adb4d97dcb12a15056dd2ae9e3fb2ef55902adc354f3ee1a0322cb3c765fb9317bd60a1bd64054e585296ee03c1e180d246611446961a46f704b772e8c7910d814a8ee189d0ac03d248fe0e28a31f05481983632d046fa61c2bea69a419301bb9b29769d6086a4741364f1d5a4ce8ad96f2665966d5ee5164f91fe6ddeedba34b5c7b7b5c66d30b4070494f23b8ee884b05a8636ad9580da60d48e4e2397f94156e0065263e9be40138606d8be3e54106c680a803255e3b15b616a85d75fdeb53601bbd16b37cd9af3f2a14090c997776ea7a980c4d8489af16f400b642f885a525cc83ede9fcda6208adde2c1ae45a30772c386c6fc8ebb586e3b8c72d9b9f95f6e3cedacf256aa1556930e5e5e33020184bd24954c731370acfdd6a6733f31f0b498f1f91b79c28c42131ee1166c1e39129b2b90262b817317bda3c32bf2413d6475cd419b0a88fa413b17106a5bb238718b16ed9aebae7045f362e0093996148b5ed07c9c8ca64b8ac89fd4d3d94b6a140d27ebb7bb9ea4002f8b4746f09ed49be9cb54a737fbff29485e29d9f735f6b6928472dec01b9a2162c324629327b6e0efb8f4ff24b9dc268d3be867308912afd92601501a1ac770ed9c2423816384b48bfc0702ba70536e69f819d38c57e26dd72489bbb8bd240872df714c026cb86944ec26aa1988da4ad0a102ee74e96689b04094fb1749fe072390a6ce1b3a50e30040ddc338f27f76cbb48619ddd3938408e0ca8bb360ddbde8636d5bc64e2eb67ad48f3d145960a7e65836c1a016e37b6a4ac3dab402c33bce7d21c69a36dd4c39e73e521266fe9c9b70d4ca624ea5861108226a90b03820bf51aa2174fdaec2bc83cd76e7bd4e3a8868a860e14f0be6a6cf99c2a5dbd4f3c41b420d6013fad5df55235eb74b17400ec0346b8d3740ca0f1dabbe022c03d5dd15f1c26a64f4329b730354262892f75fbe9afa1ddce9f688a46bf394cdd9eb691d46d1e318d79479ab04a046a166bef5374c404d6cdc06800a6223e45751b5f55706f45adfb52450372011e5a3a7f41891af5650d35259a0a2f28a2d727fb619b580b7ef18b4d67a79bc87cca4f78e4e7033f1f705c127da5ad794173710a9a5d15560ebefe21fe6df85d1903afdf389ad9042c220e7960ac57ddc9910923fdaaaafa6f9d01dd2d6507a2fadd6a3a373fdc696c9c8f07bf6765c9d352c4d35ec2adf7d78f0a55700865a0320c2c194af160af1fbbc95d9d4321fe01cf40d3687819fe4f6727f395eceed2100cad83d38afa010d4a5d052ee26440adec1221b3cc99ed28f82e1666a9a00f876b2d0f5ac39d0e7c27bb1e499e9d67721f0402bfda0bb1d42e9b74a6bd865c5ad3285c46cc2271908687951b1f1afd528f3619d4651704a39891c2f9617c09ee00850e9a3fba5b86fd7eef9b681997ae2a2cfd1d2d3c4730a55ba6e09befdd0e1f1224a37442243f1b9797fa7eb3058b51f2af0a3ce2462ba3e81c5197fce09698e19a4f498d60b612c5349bac487b698227decf65a6731f8ab5eca0e0039a84d04f318feb34947fa1b649f9a05d69c2afae260ec5d8ec430631f50fd3a69f24cf94fd2f283bb84f2754d825debc65277f5887f530881f7aaf79a424c89ca47760bc6359ad30ff949f543c83cb38c597fe80fb4ac1e7dcffac33cc32430169a4f27f1db03092516c9329b9b192946346a83ec70a9b7d821785a73151a30f551ad70f6bfe26d1aae7284822571f94d61826b3256b811a42603472eaa8153c33c3ac1d1d5a00a7254b9e24fe0208b0b295c0ba1a910f2cd4a5ccd8ab09036dbae2761b1b0dfc8f27ed027b66aa7998f63e750dcf05c9a6b4e8a03520a025b6bb0ba6dac7fa551ae762406f0e73b18520025e999b713d57d98f39ba9197fa418a331d7986489d65a1e2d5dd698a2272df4b56a4df010339e85863ac1a93f079d247fc5acb2016a785d60e0269b76351fb69e0d4cbcdffb858e0ad7590a9e91175ad8f64018cb12244cbcb13da0a58111c03f9f69d3eda9911e4c721803cf359880109d7cc657613383c988e7dfe226283882b649c42032f92cc3eb1ab2a49d639bc3717f42121244d99fb0c9ef244ddac88ba181b1f02deca951fb8a806feb0d2d994bd1fdcba1655383b1bc02c1089fd39aa2aec45834656f738c087a293dbe77cc4d83ac27762fd897f4779b6a94ad0400866515cb22ff21790b1d3fcbf61fc957f6b98792e9bd7e2c4f42bda80c105a4d294752b82980939347a0b1cc6089cc6aff522c5b730149265a07ab5c752de21b265229c8912752a9f9874f79e11eb81693b301641f2e021042b89440358fcc207a488e1df84732bc0da3993a18ceada1cc431c3060515e39b3dde98db3212ece4780daad2f8d8cc6e4946a018cb32e6746ba19a693a3706e08266e61e5d637351884ff7dcc5334a70f6a1f0d55494e8862fe4f8cb92d70bf950bde9aae91cc8f72322c0f973b9796cbde306278db393ede9d81ce743e04c700a62d38282c5d92204318ae1d52d09d5286d36e249c7bd84c120ee4d2774f75f8025da4a518a1c4366733a2d6886f778da3eda2e65cc8e31f4c352bfd03b3c53a9b2f20a6317da5c479c7f8912aebb9d61676c722beea256e77ca90f5289e70467ffb95186066f3635236a7be35e421fffd15cf863dba24810a8fb2b08158bb8cafde721972f3c3f16a846ef0ded8cf3410025e52cfbb5bb5142b0ff35a00d3a4532bd97a238df2a521f5f242da442d9aae3d5acdd2ee042807596cf3c46ece994558dee2d9bf33cdb0fa2b9a72d3d84c0c9e603c5bc5da398f12b13069d8d81f5d3879097b2440a33ba6fc71b2e7ebb59396d140e9c6b39512a2775a2935e2e081b9e98080b158928cd6b27ca947d0b9fe8ed39202a7f069ec33bd36b35414ebc4ccfdc29182220ee5e4e4750b0217698a85209425e0ac7c9503899ed8a13ecb30a7a5ef4102d9c8fdec34b23a3cd521aee974dbf0dc9653f6968997db3f0f360df44798ea2a39b69199170cdd226a3983525d8bf8d4a811b6556619428a04602721db07d6c5caa291dfaf4e1241ee1fbe42f84e6ac626c26c9744bc5b38c2b7cb8d2d5ee67afa6d9f3ca97348ea4b445802fc3bf281e16c00943235f0699b9fcd19e9d376730df96a60c00d451aa2c29c97d4f7318e9ec528cfeca3ebe7df0dc71f4c3954a90678af97c0fc1a137c9b50849e2a664b29a3eb3f3f6e67f4e8317e19f352cd560018fa18e418b8ac05e20031de4ace958ea9b3c2fe39e9fceb4b837c379e795d7d02614a614dced2d06ec4ed81d0b8fce59768e79cda34fd87cdfc6101fae3d8e193970d4d0b2d7cf600eb06aa9220d24b5af5b6504e5400072721c3c62d0eade17b702e816d3e668bfbe36c68c84e5da38f59fbdac52621641141051b3e9bde059f406b2c9499b169fb49cf3d4a27b25bad40016ddfc0e7e1df27e45614ffde750bd4aacafe0203a4dda21b2b317ff6380165873318e87289a5f49a7704aac53005f9da2923fd6bcd9506ba3cdd1f95eaa4a2c580be587a78a78ff06ac5f0dd6ee09daa03768646a8ed7531fce6fe54f6c57b2431aaace1a2c89e9a707e48de498b81f3a1d27c78d65210b7975931947ae4161816bf887688e89d19c7ca4496c9a3650277c4a7ad055126434e543b3a6e0f65019aaccea0be9654b92e18d5b1a4c386e4d14d85af12381bcdbd17ae6ccc8e062ea5be48f7fa2f45b1de9aad9520f666cdc0fe6606a21ec1a9908752cd3f3c5ddd0e37f1089097ed83cbf9ccebbfce835368bec34e732f7fe673fb78ba7f88ca1ba997e0db0af6cece23df82a8f3ea4c3e1cae1a3c3a2399a7717dcffad1fadd7c9bd9415883bde490bf512420fe1af415607ef022e57968a5500cfd80421efb77340c1c6bbc6cd6f37eace1c581d30191da1f271a174a36955179c0145e400feedaf4f7d4cb416be82fe4e37ee17872c73546c20bfe9b1e04f18f7da8b17d930489f5991937e2c3a59e680dabb677e5a0bfe77e0b133d44790d70f579bd09f41dfeffb14b1e969f8aaf31ce1c227fb1dfab817e0d63ff5f4243d7aa5ad449269034cf9e4482b9bbb45d6d49afc722657003547f57b32edb8afd72c753a0ba4dda7b27b7fe73f6a457706c594ebfee77ac6e661396dc48fc10abb49567d40c26b69d2c8d6cc7c95a6ef14ba7b0311aaa7f2ff6b30d9e716cc2cb352dccae74774b3cf147e2787306fe282862ab0e9d85721be8f1b98746cf58723d5f4bdf679a1823da5bb0179098aabf8c6df369ead412f8a780cf295b2ff8c32980163f325b4527db4fb6a288d44a89db4e4b38f8f93e2c062d34f0069e77ee30684340377687c93465573c5fc7746163874f97b25b0a4b832c689d5df597e9dd030882ffe376694a7fa3fb1b9f137fa04bd8851b08c7069a70f451994615adb4520b5932e12da00155c695397690fadd8a740ca5e188fca1290b0439daf3a5c16e10a700dfbf3b859a6b3c12bfdd170f644029fcf8049e4ee142d0d51023812e2b94ae1de8474c252597c6e1ddd4b4f4106ef6901ae53b9fa553c5297b15a9dacf5c008a8e8ebd71ab0a72d477deb57f3a97ce6be203bb6f3c01642d767e8f26fe1706c0bd9f192df7ca0e896c5bd9f9fc3d0f5552f8b3ed9d29eed8945194e0f370d01e80a3dccfec97a2c9fbf109082b7d03303532770e1d81d928fd6fb962fd2f7ef7e12fb6002911f6bfee2ff6bf744db0b07fc305f2c3fea3c7d69c8ae518ccad318cbbef9c2b6a576c7fb9b0886a4408d73b738db8f698dc99ddb6393b2c9711b8561e3bdba9dd9f7ee4c3e9008847b69f46edf316123473b8d8cdbb705fe8045d4dcc085f4c515fedeee8bc4a04fca049997177ae051e870b48f415b3f61af029d67914b18a42a9e464781dac6e15334f7387e25f68f2542bf687e227b2358de5b46e77304b4be28686f56289b078ab14500801817028d916fba1b79a3d1030e3dd456370d6df667ac0640617fe9944555c6513ee98587865d2a3b68bfa1b8ced831dc49e278284d6b16c7be1f678fa6ea8049d1bb7dea74e16a10fe2299ad616de09302b6763bb5b7e7998dfd26bac3753dea40bd03ff8ca297737afdc54f4a8148b20d4f4b9e8c69943d5abbd4d150096763d73a18f4066465cd038d9c007b77494777fe7398f2357301970e4f4879910c93c8478411efc901156747d67ec98d3e069f1bbcddbc50ec2caa3e9520101159be62e01b15bfd6e9c5b620ee0090494342f327ad7b029b8f70fe92b2ff7a7919a0bca6dc995391e39ee4e982400512f4d6119c562849c471cfcd6dc8148e34969fd3f3eb43efb4af3b30b5888b5fda709d3c348c64a606f2369f3fe08d0b1128cd5422da8790e927dd5725cbf77444ac2378153695e57c4b3b24560074cca6a01b2331b5e0b1cc4e700ebf43205d9c5dc1874be86ebbbab17f171c9d088765687170dce5c8125c2a14ea4330c2b9934e35d538b86944fec6a2a1b746ba15285335a26bffc3eddaac835e17f8080f1fd8946f8a67bf18458833f7a04199e491f6c83a0d4ceced02b967f377fa3c420065ddd0b99ffc0d82909c8f7e459b73e7c525c692355c57def13c0448c6d72c42a75f804842bbf3ea90228fdf9b2f8e2ba129f23dac427d4b46f0d5a6eb6abc0e14ca86ca1c889ce8057ab43c4b9964e942c02aa7f491ee4dc1fd88cbdda4e6d69f91391cb2bca3fb7d28e8cb875b8459ec7e88d9ab62418a9fb408ac210fa7206687205af627c5140b85410652008b0b6ab0bb7c98aa568de540e9562b3cd6cff4535f0376ccc79c2b0d3930d56d3da0c64a41e7f7d370f90fb080867602602e02b765b4d41db3756411c07051316e584e6eaf4ed070368a7e5b4c1dbb6201d1d0cc79a665b316253a4f1f4d6610a9aad04905a288cf058b0185346f4564ed881ab3e70f43470bfbc16209bd4c2745485c27751cec3da9f6b9a6d89e3932472218477a286d0c9eba52a7003451e0ff186774286c2d4fce6e5fb4502cf8cda6b8aad826e05a5ce4fb534d8d2058c840930132d4a6301753ea9468758d949c989f694e04d4d22a7f898e8631c5e703e2ccd4d36617c4ca5fd5064de1f4f0e3915c1fdaeeccbe10c1a3b88266a8d01ff28ef8730c3d498e95151741a1fa7ad4560aa07868f2692b7b3514c06c9084e69109ea4c3913a5b294757cb672bd4fd05645502a37164a096b7290b5e490111b80851a8c3133dd41af1efc473885ed6133f79cd60d50520d9cfe49aa320347feb8c845746c36ef807ebd7b5fc90bffb3a4417413a43ad6765ac4443dac5387d3d6b048ef04c0370540d43d6c07197f0038dcd8da8f0ba01c83ef7d786458840ceae519ba44bfdf140a207a4340053b0a9b43963439b8f926047bef71347375a7f2ae77e96362230309af7659331a50579c6e1734e661baae097a0bdef486b80d7e3d5cd5350b24c0eb02448368fbd10e4b8413b5c1d4b3804ebc9fb5512e24d10a739686ac2020fa0504edfc71c8b15ed6cc98743feb5b4255d8f2234f3967ed128a149e14542993478191b22bb2eee7b4f033fce69290695d1eb044b6b9982e98922a58dbe7a18cbc56cbadea456ac81d58f62c16768b517760b6e24addd4c7d39df2e152a6874e85415c25af8246bd062f4033c9b07170163d35a8c50b21246799a858a87699a566d4c9551b03ac64cb7e01193fcd4452006ed304b4f7e67c148abdd3a69dec0908da291909de56bb72d5153abca8ba55497625a6d05851935c624793799a49f86ee811062ed1ac1a6c2033867cd8bad6614e5944b5a9210eaf3c47a627fb4e4c466ae5585ee02c230e37943981201440aff36780458c45085eb1eaa26ce4c51587fa26a92d0791abb3cdedf11d21d90daac2d88424fec547db368f3fd8d2e2e370e54458b9c87673cfe569ad85c476989567e9711a28491de7759db16ed334556ee0342696881fcaf21b6ef393f1fc81fc99ad1622d9746b34a2e95d18ac76ed93008400ea21b02cab812956cea70128a7fb6952a5f61fb94f094da3ad53cb17185039f7c00c5a702820064edfb2f488b9ef19c809f596737989027b023661c47b06484c2073ad00356860007ddec5cc3543f56efcc0915282fde188a005943ea2bd6f39382d66774f656f54a8fc396661f5e6f800ca46782dbafe9a8f05d679b4d764edc314b6bd58cea3cb709449b81b0b680e0814412cb64e51ec1ef44e4ab6a42ca19adb0b7ad1e8debd47626a0814497b920d4086635e6f9427151fb85973c2734a68b36328bec71cbec32fe13ddfd106bbc87912d89280c017d8e99f5031f05fb1e15d24f53a05b8b5285d51a8e2a46f830b874df6230079399a238e319270c76355852f5c817921c3e0b561f88aee8559b9ffe662c4d8d4d098ca2187a2e9070d9d1a18a7a34584014f2c3dad9e856e418cdf9a351c80d443082ad9e595dde9871124457aa62d87db714ac2c151252fa25f40c1bddff09b9aac40cb6f0b6994a39c9c9880f09e5f0e566ea4c80364ee212a95bdac5592c28d341152fbab9b67665fcf676e6a44599321a5f49736d42dbf5f4c4257b4159be2584427dd28fb625638ccb673b47535de3b487947fd1b2256f6bb969bec8eb46079e4a10d94e4959b74fdd3fa7decbda290ea692e394eabc8c6a57ee44cc0230a4d3de12231c134d20746bc60a4f2146995e86c875217bac467c1da12d563e47bf63eb7cad8c9db10a4170156981f46ab98e8f36bbdf17e6f6954e885c10cdbea3fa57dfa57032e67b822be526c54e5942d013dab1407b8c4207b621733240e820a98a6e27ee7f8b6302eddd6b56dd5caaff03de811b8ff93c98e3a0039da522d0f98fea9d1d6533407532a115be411548fc872b1ef397567a3c6c924c019f025cb48ee2df3deb5aed2e49ba0f078b720696906bc547c7b4a8558c6d99b55938e14f66ad7b3721e8cf81b112f384ea1fc497187a12a51d27ffb29e433cac0506c3b2911d1d467379666fdf52e2e414d84fef211703d24cd56cf88932b70008ad9add28072896089b606b42331a10f25a822355394fef59985d5fd1f1fdc8c3da7d888a65551ab616051acf07e1ca0239522c0c6a996c900eeca0470192a741f9e38909263332d338e1345552689f5a81bb99b082cf78df4735c00c6e86db59e4c64c2c73b24e74798335dbcda04772878bb78b8ea6d797e28bbc3ec7bb00128b5bfc7a9508946c6f21966656fa70591887717954a3aadc5698c98814a91878032a418f4127292bf447ab969f316097009161f3addb8e14556f0de9aa07515ba295cf39dcde8a0da43b6d0fc515eb5a05515a2dc9d3abe3b9e9c2e9f08b9dee842ee2748a2c4859af3861b6964f0fe727e2b8d21da2ad52e0ee709e31c61ab8689fd38615ab0f0ee0853a70437c3ceff40b103d8281a5a3a76f25f15fd635427c880fb3eadafd39b8a5b2232a150fbf6b23de796afa95e4174c53e5e93c4aec7f3be2aa6441045ec1edd313b71ec7170b1f284e9fb010cb2d64727bf3506b43f09cdc913010dc96f9e75a9fa1594309868b821f8b9fe132b8de95218bcd0b10001da49d47d1db31a1f21bec43906f0d01dbf33e7c108a79287f3fd3c545a05e42f1dd77d353454b9e5cd4ba19b6b650cc882459fac25f5400d5b3680fcdee6c7793923d48008fb9089ee996c937b75fc31ba6c7f9f1968cec306e07db5b060d4dcba84f2876e9353e60d5793253c8422703981ef5dda485c44042af4906a313d00c27570d933b1866ca133f08f8b22d3b4f1b10a69bba7ae61580c09809710be34b34eaac8cd6cb6f35ccc421ccb118765eaa5470c5a077711f4a71a53ca68744f8dc7417a618b550074b98ee75c4d3823d05f866591a434159ad98e59a740713049ccc736d70e02d6fa404a997ea9f4e3b0360670aa6e8853a8e255db36ae32a7089fd5e2ca77ade085c72552c1659ddfcc2faba7c56405ffaf3ed46346fcba5103571f1ed88738067698aba526159c244c4f2830be7af24048a23bd7a4efc93ef7fcad24d4d1d740425e90d67bd9ddb9fdb27e69ed2527bb07e6972b6df5c19f5806338b5f59be29bc95cd83e64ee6b7abb71ceaf9228e7afdc54c79c1ee0ce58ac229b996f9c5aac08d2d1ff31569e2afdfad85f2dce1b40e39eb6b787889785fafe365bbdc5ef0f41227356c85cdccc35a9c78c9acccdb10122190e6cd2eb6e1c5e6411bad7a401c3808133c29622cf742aca8a2bf0e0fd83e0bf29105b3a4825511122797ba08bf7b4c120fa67ec3f8148c4108f6d9bc5d524862c4dc30f963b0adf23cbdcaae057d910f3c4575dc2cdcc1c2eebc9ba54eecfe3c23c96457e1fb9e15d3684f32b6ab83bbc5052222ff7d42b1914cc41b0dafc9fa959fa36967bbec6bde80a833d3a7de96dd3fe5bd8d98d320bae0a8816d666283488dcd5fbcfb36dfffc589ec8c656e57e9914809c2f81b1e445af970943274c563bda592f073d6d14fb33f1e522f9ec46ea428dcd654e5ad450ff7681cd2cd9540e762d7845310f05492ff06f94fe45297f9e037b64bc57a26991e6584fa110887cd3b8be33b6b1227383e5f5ff56a4206d77be2703bdb87b2d05c625644f76f4613d57ee5a6980bbc5f23fc1cb2ed93504d787fdb93db95a1e85dd94c83d8d8528c1f482a5411d6654444064972b2ffd81c87959b0994bb45ff968e8eaffc26c3f37e64fec26597f1eaf3fe4c07ceeb1e70b83f75a9b9f569feedb0abb0133d8445ece0f03cab60429bdb4ea7774816ab9f576c783179f69b9fae506e4e938e16f4ba91331b1a2cebd7a5fa7cf35e0d1cc6b9544f784545d2d3ff64354ccfa5913ef67b50462ea27773d0becf12bdc50538e9af57caac260e1c20fc56f84615ca50c35aae2c381ab371f2de21ae147bd5e6195e0af35963f81d26bdd00dc8721c8df11f8778ceefe3029c95f44b2e93cf6a58c7faa216d5c22355d93f1587f3d5e5c35b9bf48d145f305eb6a67d6b608256ca1bf55c67ff5bb23d1d05afcc4564726f79f041bffa19935dacb1a9478809c4468716986ded2ac487a6ed9f9737449c93d918d7616bcf83900e63b54c872a133edcc345cce730e00997356d5caef5832e69dca3c147eb22d4dfd7d42e6bfd6880fe7dba751e176f58183e27627bc39ec1a656b964a96e34273eb2917f4392e5f650caa4c0b8d13acb2a21a091e9ed5727ba2f54b7652a6f6c9ca47b91d003eaa9ee6cbf7543196c0946cf0b8ddb6df8391e27c53dfd039e97b95921cbc06bb4610fb9af00ca4fcdaef7e0b3acdc0c8f50fb9b6286cf0ba27c184aa0d265f76d2734e0ce0d5c5a87b5b36a13143c2d25f3adfb232c96674a74f343837ceb334fd3078d7318837ae347cc2d19bf65ee6e60c5b36996fe6e03353b27429379e50a58cc7e16ae6ac998ccf729eb9564ede77dcceb8e527e74bee32d79a9e38df4adac1e19f1b54c6fc41d6207b4a6cea4ab2e34dc9167141fa2fc9b6c7535b56297ca78e33a9f8be91938c596792bfe72e332c3df1ef7191d9d64fd6279cce7cab26f36d6e67cc92c9fd357799b1664d085aad3b89df71f7991d011e4ac96f9290e279988d376c6222f61f8be0033980b53c2623aea315fdfae2df113ff8b8fb9e8e3f2c2acf83083ce71f1c4edbff2b6f415364fd7417e24d0ea0e50e51be5776020dc841f3e1cc0782c98434fa9cfed436afad9dba068987f8260d503094fe8d45cc2e4477b45d36b318766f33e54e95930de837851e19df9fc1f5c7ef4e6bfbc3b9dccd1d9c0b09ba982efa4e57bbdccb15d87f417fd10b741d8e06b91f74fceff4b820a103d7efef22bebd4eeb7709e99a02a64b001f03589e69a866ad8f7fd181ff75382e17cffea7bf493ae4e59894b21416d4f4af0d2b1078393ede4cabe5e74a2ce04eb5e5f5b2b80680bfaef708bce8efbd8481cecaf4fd37cc4488c238384198403475642610b5fa1f896dcf0f6881b50ba1fb5e536872a34a802a04bc9b89af81edf90dbda6f98e14919ed28748b592ccaee4348b3c46d08dcc8574ce61a13ff0e17dc5233a19ccc498fe0e1f0e1f88597ba189e6c438bcd1d7f03ddaea836a1e4ca8791038596f50c06f11bbf693099cdde5af1c21260d6e1d32bcc1ffd3bf2db3cfb08bcb5efc21d0f3e00ee36a5221e1124f21e46ff6f3a6e9b207e0db23081c792f14ef0632f797d098e7761f49fc5ba4ed5ef044f570044dbdf7477f8197ae76ced06e9a871740e6b8f743e87c342158ba4e1e0d3fb2cf7495d3988636b98be7b057a84e13b15991e44b70f2e72da9fdf37885833f79b82388bb06f7a1d29c04767f6104e54719147229e262cc9351137ff72fdfab3597707853fb3e7bc49eb3bfa049aaff56dc95ce527900ce1f7f8f48e58b71e5723e273cd0b43cdcb3f7cf05275962ecd97c8271967a96ec7f8661b49efe1afb7a5efc7778896bf363b00bfef07331f6384f55e663a0acdd297eeb27eb449814713c47099fa47ba8461509523319c417f0e7a045da0fe3b97605878442611f8f6392da47b093f4d17c81f776473d76e5fcc5a34f52301173bc5a71ac2f8b80d530499b65904c3fc1da558422712fe5d1896764cd96f38e7d7348b5e4e63192d08db4fd457a61cf2ada8f24bd430540aa017482998425fcf300ea39764ba917ce86f59177387ae8a9ee797cf2fb690a9780d95da9bfa4d4907723da6347f03ecb8d3747b9ac826814763c7059428fa193680a669d120356dfbd6b3c3543e16068e20fb4ff6f65384ad665fbbdebe551c71c5406fec4fc39a6c2afadfda298a8817732bf24d1844750456916c16c45588745fe63c2e36dc75406e90b341c8fcc69484e02e5284fcc407342f48ec7a1d70ea2e75524c2cc04f528aa10c79b921f578d94f07af66a7b19e1caa8d2f220560d4877422d5997a14dff13e4dff38d3bfa97e4bd01e1a6020293c59519680ecb4f4323d86f9da889b04c08bbac6ef5b54f283f711ee8d7a27831201e90d013f7f8e399c8eb03112f3cf671719dbd6f503bf6bdb4f18c0770fd9cf848d03730ba763783780076119592dc3163508dac108b4d333f8a3e7d4455c24116a8e118d922776c64c0e37b12969a3eea60a28911e7d18b189c44562412f67d42350a280e4b40fc3d12f1f8d1883ab7c2b99570bf91a3645501c9bb5d8224f51e9b634b72d0e1b47f6cd1dac1c35efc49257b065fa260453c3f6220afec92c2a229eb46cb66685ccde21922b144d9524656093cddf7689f6891548a66c4ab6d2116f31b2148c8104525a083116b204931eead915aa97328461fcea9d3477a56347897b1d84ae4cde35104c3312761dc66eaee7d81019322f5fda80d4aea14ef6585e7fee7318fc1651c41179ee2bf73810f994bbd0986ebaeddc3351b28e143057fda44878fee6002fff15cf823ba9a6514e94ec84b45c1600a12fff1d0e3cf6491fa146e269e1ef1adfb1962cde6b5b84c2fc0a887bbf0a22af2018ee38755d939e797cfc3aa674a49373055d7b64415eef4e41219306ccc993e12f9e48c431cfaf91440cd8aae143e393a1032c567c21545b41a036dbc68d9de7c92be539a1ca8eee051e158b7a9805d0c9746ed8a47982415aca24f32553c1bb02a0884ec6b1c76e8e8c730a9bb0c3fddbc27d1aedfc881b736bc6e0b1fbd2d0c6fa40f05a9a8fe0d67e2004dcb19d0a8f3598c550b4e5ba2f38aa3e927714bc8cf7ad2af0244c420c83ce17a6e4497713596623861f150518e9ea5a51daee644ec828480b4941d20936bb3520779d7959f8cc4d2a2223a400277709240b677b762401dc1b1ccd49ea3d1982beded9e7dd7afb2cf1d902e8a58e15c3a42e8e8f149899076cad161383f1e0391644509c48bd55b9a8a215c35bc58c39c549cce95c4636b617c543b3e60a68457241f9c3ca1d95a738b06ae6d151d02bb93486af3cabd330aa0b01817a49e80d080b799f7ebbca0960ca8af3d9079a45af49dd616150c70a3a9f9187d618e0da99838fa67dae06cadb56c35a1e6ca19850605137a0dd425a7454559ef445dbc9f5b7a879582434bdf60ea73c94f6dec5c7674a8428598f9a12a12fdb2296f131a905b92093579df34652f5064a89e4da22db392d85e527240ee8773dc512d82399b65c17b8d9d954350d4cd9e0dfac9eb9101a23d817077b6b6a35a4e3e78f482b98278bb0a3a91484cb9ce32478330d93635198ab6c435284a5a0cd69282623839c29b5fa11ba6702fca1b10186388c82f27c48d384f28f0ff1fdc81411917c81bd6a90b417822615f01d1f92d15ef400d6dd318627d911f8b8c1292243ef88397a9d1848a623c87363fa52bf454348e17ec2af385b2415f5b81441b29d263734552122553142ac516f32e89132a0a8c3182c94aa50eaaaed88b4d6a4924456d7382784145d4aa25090caa05109fb99ac1102fac08026f89f4b18564cac26c0a01bc58f49491243ef82347b454c7108f9ed0868d7c6b4e4a638584c061aa00e467e488837a8e98eb890db1fdd54f06fff02b6cc084dae479ded34708b0ab0c44f6e4bd8cd4f702d48500216566e2a32394614f9dd6e4801fff418e8c2c999247cb0b49d022a2f2b157215160512180f8f06b185bb8b426cebd09668c21e22ff94dc03aed43964220301d053053c811864e73244e150b6805c55a49e25d151c598d285ca4c27216920287a902103f2b416e6aa1145107b8f2a10ac5680bdffc08dd186814350fe4c68fd8212b70bf063e605bd8805d2d8527821dff88fc19ee275a5e5e144022382c27c0f65febf1e4e927272489ae428a9fe56178b6e6d47c05b5be176f6275fea374defeafe4b2f2f9c66bc3a64d518e19bf709a429bfe53182f58c9c132e98bbdadef5599757f2de8f2f489d8e4b9a9eee97d73838adeea4e7978402523a842c2040b93d314daf4bfa0d9edd9a925ee3ddb7e65e8b4296cfd567c5f59728b72ace8e5f31434b14e2b375e6f26a6fc058515b6614a2dbf22f66eb8678daccfaacf3cb7eef8efcdeee5c76a266edcc29c5f7e487de558d1cb578dba15ff49ad9f0b5b56cddf4ec69aad6856e116d6fc9229a4ee0f7a76f3bbe20de67dfbddccd8b266fe4632e67c25aaa4df867f726b8f05d7abe5b79761c97c7118b3cc80e90d2903dbdb68266f281bf77552d597c96919e7cbd2a62bd3741fa8ae4bbfb4aa8f7bbbd48ad77f30916a1c70bd30c078240043b0ccc651524cb0f02097c489f78e3759652f58579a37e5e8d8f46d0650974aff4d18dd9b74da6d5af76c3c09303cfeb0ee02aac5d1919b166f79c78bc8e2eb3df675a92b5bf1b1df8414985efec23b3d3e2283ad625d01f97d52d493d9a9195fb0da06aa7b39f5f13a095471c00bd5e631e82b48af8b1b60f2ce58e53fc64c8725ab7fb4fb52d61b537509f4fc18aef4cf30eab2f87a8f17acb641eacafc9f70eb76a701932bf32bf419b3ae95acfaf882d41eb4fe98f8117b74c37580294ce92a50a20b381d11d18bc9d106505d10bac8a4c2e002c8c471f0710de4c53b183a0fc4e21fccce01b1f10ee68e80f2981bac0f5d02fde5a491a50b93a23c289d97afec8102d53e28dd615a17ee960d544d8fe9208b56ff20c16a0f3a3401ea7ab1ea8f7f99d23af48c09b9072864e23b483d99fe2fecbad719133fe2aeabe2f51f4ca49a835fa8328f42df91dc7515919e81bd63d935a20a1d1a03b91b69cafaf6588de4205d8ad4f7082e4b59c9aa7f14fa75163712ea80d514e3c665d2e63d85f6a60bba8e65d9bc01f10dc7c6590b4891e063d377634c6a93592681bd831cd57bc2bd0e4e1048e18e8a4414a08ca386e4485bfc4735b45a48fd4b18930b4b2aa9c78e5c3a4db10dcf298e37acc0609dfc93da732bc7dd31f7d5faf3cfac6cc7abca3e5f1f44652a4fa22dd7def8cfe67f054fef9b9854bc863db96c2a12777d89f45c3de0339bff959e572fe372eddbffc68c0dabcc7eb63e64b55436fd2f583ce7b11f8daccfaae737ace5b3f0f38a6b3e59e1c4704535bf176f6273f698e21bbf153ab77c5a5e611ba6d4f2438a9a4f3595d4fd675aaf0e9f30553f9678db6b37b7387b92825bdf95dd569eda5ac73e8eceda772a679e5b17a27aca9aff0b5bd618be6964aa95e36e447fcccff474dd1955676dc73fb186c7d267d5f31b33b1c9bdaff25a757987ab87274e7573d7b2e3b59237b66195af7fcde239dffedaf6bca8d9f5f90215d8f8abf8bcbee09676ccf885d31475314e2b1f569a8a297fa1b42237f62cba5f2fbcb50d536ec9e3f4b6318f59aafaa4cde0676b792d7f543bbd3d1143fa7261a57598720b4f2972e3b7a2dbea67628dd608050d45aa01c12197e78f64a41db0053204b530b9a95ba4dc130051976279fd6d7d637582861736a188dba3f4e05ea0e05f2829d844286ff52225f62d469f6d4c97ca0681b83aeda81a5170b50db874758f15abf24195aefef82e4a53efcca36c64e1d41da0de9946ddf82f936689953fb698075d5cdd47bc5d6ae56b3fbabb522cbdd6a3df97623a329176d3eee17feec889e8baf10943d221e084f475263338dd8d2fcfb64be782dee2c588ac361861d92a0d054def8b9b4c7bb873c6b0d7fa06cd9129e4ea6e6374b1b466bb9dafdb7f9002250fc6c78ccc65695ccae326d6f610d7adab33a7154b86b53f8e3346c5796c76fa7245bcd94915a03fc311749dd0652b3f1a17fc951a25ae59efc1127e07b9c241bbb6a88641ca553688a0ac3eee430887548a9c727fb070aae1106ca20c6163ba96b986f4a40c78e63e1d4a546588436bb683eacce0a69605ac6f8ccc6c822d99d0ff11c3b4f48d6c9ffd5f0e800b7cb9425bf5c2800e39eb436fd00b8dd0130720a87577187dcbf35da3a47368b7ef4f271ffbf85e1601eff71b3feb4f97e13355751395d9802ee58e2a9968417c5a3ec24af4080727acf3e74d97e7ceb98bccfe67b887fb8c46efd32eedc803a6acd7cda6f3b94c22135045e1062129607636db09e70cde9479a6e11e4019fece655c3be635dc14e8b81ea629e03e16b8aff55ba05b23ee3351d215e862d6106dd0fd4fb265706da724a5466e5f5e489b8cd2586d298a0016523e7d536c4c260657798d0f1005e44f27cd2e528332ae023a7e200a6e4c714269033ae18a350104dd70c8ec129069a2c1b5ab14792043620dcf47bb80768f960bf446c07a19da565108bd8b838ef359589b32b8da3f9add3d6d1d1e239687162747690f5510ac7b5d7be8668ee275374bc3a8e96cfc7da4aa815c33da83f75c4e357862e7ce8b587ca5a49ada8026ffe61e64fa4fa043b8141f2208394a7f8c7b52082f0d45a4d7708703e0cc05c225cbdf705a092e3d28218acb6e9bd32f4cec742c22984353ad1c382c3769bd785dbfbf71f7d913e722f1552d6ed8b9da418ab31760e6aaf9a79028c3b37eabbae1e16a4571a8b00772027c7692cc8a5e746a677091323f607d54bd06f767cbf0dbc6027594f81b5d6e14f3ce2eaa016afd56ac88df0e9612a1f2dc5520d32a0cdd95b4bafbb81ab6f52ee3e8507deeb97402d09fbb377cc9ff9f703f4e396bf3e12563ff20cf27d8cc45280ae076fb4e8f1945949c1a38bc843d9349d1123b902cc66e57a691fc150495a32072b19857b224a2497422a6ca8d2da6342d0913ec9f1405c22f682a94bff95a153824daede1e60ca68586522834ce318d4855c48de7cd14044271350114bd8f34c8c1998de06d4101d5ec90073562da3fcf8aef6338754544ac25aadc7e81534c28e56a1411e5204e587fa72a78f0f134429c658f24028f426a67a972f270a49028602b81e82f44d8606cb7cb4fd635c9f402556241d06ca08b32c06f97a1a3d73e60342711eb804942eb5a7c1b16bdb00d67ea290aa5628626083c8ee7d45fdec351038b08feea4b6520f4b397aa3c303baf28850da6acc4ff9688b545fad25060da624e700c3fb16dfd2afadfd179808d32d80f1d70f2aa33afc0b1e481c81310e632a69ab2a37c7cd0ac43e602b451684deb873aeeb9cf46ac5e96140683145ffb9840ac0c8ecb3d932f7ee0f52abe225c2f163d878db78918eb98c7ca495400fe7523cc68de1787dba1c361cbf49671930db1675b85599e04e0a8ec622a79e1300a2b031cfc3ba7548eeb22c23e7bf4b6b935baabb6a6eb5a9fb2cbf6e273baf4910e26d830103ebf67179858c584c7e342c7971c7a76fc9243a30dfb93424a750a216a05b2c66f942a48c1fb964736dd7ba94f2bbb220949778150dbe6ec950e50bac6e09f3627c9bf9f368a4f9929c0255ac7cb553a31da442d5bf2792eb2d0cbddf113cde8440b3d8a8778660f40932911c09e73d7d724b72494874aa9ea3d4d649a38b7418cf3a56569ce152dc22c37f44931bf526b50102a89d8e051103f910893d2153c25e7821e6b87e528df9421621ddf58ec0915b24fd3891ba5657cd85ed0a77366906f72322b75bd99250b986ff498ae80c4bb242b9e2f564b74bcd5608afd45d92593ec2408851035f8946e112b03ad2aa5ea885c866b0e2176eacb2b0a39c5695ca3e90b5190527228484253f31fcca18749f0b945295139e9f3d44b21c200366c45d4e3a41b8c9279b819848c03c23a9ad125bade30d6d50180b81a1fd4d80e00604141687c4b16ed4b9d9eb157564d45d32c3b00742200da0e3da2bc986131cb4e7108409efa6922e711588bc6b6330eea13ea3618caba3ff51a6eeb074b9365244ba83f4450d631308c297653ca7959a9276372c3957eb0bcff83de6530a86287a5a6c3c82497f80dbf886f5455e3bfa0f01995787fbac327985e6aa08d05e9ffa70876c8bc07d1b13a881e7b0cd67d13691ec5964c5b52b32e713e17c48016e647200906dd72f29d3da974feed5c8a8261d81b53735e29330a69f2b1483087a34fa10249f21a7e74083bc929dfa54164e2b44a91e28315b84525550ad8921bb45475749568c3b7152118265dace7b9dfe307538ba26d3a6e9ac41595e7e7a650a288347645a8fcc4d0ca3cadc02ab2948f239d21e79c79315cbd6b27b29b76395bcc4c8c8caa9685a186205a73f0e0514a82b20a5d4e2eb0509ca64da27fbe79035900d38203ec22bbb60f217ddfc5d0fe9799bf0062e5051185ae68b4416d39c8cf9e3fa003da846d87e682ecfd2df7c8c24bf7a665a12d5a49d2102956910a0407eb408b7883b1a4e9fa7694544ff7ebe47b06c59f00cf9b3136ae3bad99b0455a59b1aa7a119e7a3e956683a922c8c3b1a6b3d4b2b003f46ca735b3f7141fda716ae4c1cfa5d2944add084397b6bcaa084465080ce04cc55fd3d9bdeb54b3b08e7cb7eba19bf6e01148c67a512ed6b317e559bf6f5704900b9fab9926f8a60cadb25290635b542704906210cc0970527c2278ead7ab14e01b33392f362cc28c640b391222b9cd34ff89e0e4d41df2c55d3509cb46af24f70217c3530819f5e6cc8ae10e0d4449423653751a12e8b373bd00f3e85852777fbe5733fedb9941effb65861c33b9b714aa0be48c4ee8ba3a88b7a02e9d8ce85a9aeff1ec6c84ec9c73668da74f4412c116c4306703644141bd84e8dfdfeb3984c22ea588aeafb1febfcd347015513cb23a317bfaf8a9c028ac909f3184738d91bbeb9ce95bf36357f04ee5bcf2bf756b067900ae75a232b0811af3b324882e2c412cac03adbecd6e6013c415264c7fd7cee4e10180786d78317cd3ec5255f4bc437c652db490845942ae5644213ee25c732476c920d00f2f93174b19f94aa76f7c74bfd0622b93cb2193931f0c4c4e6f8a2928274a833857de3a4ad0c9953ab5c48601381289afe9d0fd25519d7b70f3c879e6b55504fd5ee775ea4300316102462c5b441badd614a4d87a599b9884b069c9f7c95143f9e0ee2337916c8a5dec3514d1589f332276917f23d17f5e0cf7245ed8782338cf8368d4e9b91e8af90512bebd1a458ab2c7faf41945d244631bee9524e66f45effd6d2d1f30ab41d21f76b88b9d46d137b3b37019232fd5c490f4e805d15567becdb53618cd8def3f01dc7535de8eac5de16ae74089e299add47e87246b1b82b642885519b9aee84f91e90324e27f34a2a3df99923679421dcdb43911b4602845dbcf5176a24bc3ccc556c62c7917444e4d14562d807dd8381a13428cddf707a2ecd5b2e99e5bbc7e84d1fd84cae9050db8232c39a417e0da3319885e571654cac6a9f9efe9f0f4837ab80afbf7c33fd39b366d9b1a37db3d2c4fa06d0c077a3f93738731b6a43229699c7cac27c3137ce466bd79c717c530529d2909b4ea5f567ee79d57d41203ba05af5e940d8ca18ca231effe2c7a327a8aded326f91779a95ee4294557ee3dcd2934de33c9447cbd1e339a4431086f4ff519d88b80bf42950e907591da825334c48664c07f2e406be55e4b238b104b5c2caa98a1146610b8c39983c49e4d9a505a6409407bc524a2bb6aa6d7f3944251ef89d1e7811948073e6e7b7f636f92b685657d3a24db278d64636000fcde0b41e1dcdf166156aa26d00604d4a8f8333fbb5b0451ef7f48398c9850dd67ea23c2d1dc3319a45bb44015a197d0267dd7e2187929eca1a461e78ec2067bd9b29582053f21f014d9f00eab170297a05403717c4817bb8da183387003ad602e4945b0cede16410a4fdbfe6cd739072d8d90dd796a8f45d1571a2bee24858bc28e0ea65f5690fa8e2f2dfd9df5b6b2b504350a3cd2712c659c6fdd9b20b04a52aed70e12e41a7c8ec379f85b328c2392e00c72848b6debf22ed010de93f483c901683d52a00d7567cc424fbccaa4302d849201b631443bc0f27bdcd3953d2896abb914d4d7eb2f12f63f30324b64eba4be6c9cb5f83c456bdbb545b973a71b3788b3ce27bc80ec394b8819d59f2c20f1dc326493455e9e94f19d7b4a7734a3d460f39ba70df6981a4e79e17cdffde197eb305209c19cfbce938e0e77628b1ba58290812a4bde288b9073c126fff05c849cfb5430bc1e15ab2cb40408582ad40c25dc1acb9ff6ee2ad7b1a72d42eb2dabd4071abd4ba535d655deae22f47b736a5e1121eaacd1b3638b2e22832474b7edb9a0b046b8df0c7cde987a3932a9811a82837acf22492c0a8eb62778d6d87d4745fbeb285c03daef3ea5fd1dd80546a4e8c8971a0b341549894cfe32b7b172635314f303140a424022adb6cb9e94fef57a0c588abf8fcf1620f3ff693aa599b0639ff4f3636c0f8f2bf403950685cb7355c737d291705e8acfc88f0d087fc039549f871d3044f538873b5eda12af90806d90c6f124728468ad67e94a2f99dc150d7eeb365abc4f1df3d01cb99edf15a7bb85759eb3d080054164f2b3234e0d404b4e8298102587d8808361c40eb3c0a3f3d0a0cae1a22a2732d1380a5d64eb12012cc5661c4966afd3a1ba2fa7e408191cc5a924e79c59447ac7e97b527c2955685c8190557d7e0a09c820d4dfc74eea17c656f3e7a5830fdb2410e3e7933f2ce51cb0c5c7c462a64e213cee6e0f52dea1f4c00a6cc057886892f1f918533ac8d39528d51e519c5cc8a3f57e0aa095958aaa931b43aeb29fe9f32e823898a0aaf4d385250227aa1a2d49b88a07f92661e31609b5467b305138892cd61beb102eea3ddae9c0595fbdfb3d7fbfc02ba08218c2a1ea522181c3221a06ac88850b80980536d1f873d891997858871708b9d7fa0dad8d228f35008de284034fa2cd9adc6867950fb3d8a2ea423515042e26ba556289dae340e09c6909391d7370e49949c68ae00b4d8996a05288628945f69486f737945a97e0d3a7fcf1282888e18f0015b8284404e7dd2ec90ca09a5bcba87d6381091151d4da370dc2c10e80c9fb454f87c83716becac27ef95f17ac25920dd2a6915fbc20a25dcdd3cd7e472c81388a42e8d40b9e7c12e13a9ee3f4b443783f13eb10a6e0eb6d11ad8acb39c19412ea947ea52d65c51f33d8de40830cb2bb3ea85d615f6a052f1d43ad80e0010226fa20e67dd18d917e233426254d27c03e0a204ae4781978d8440fba80de8f8c6c8dce1cdb2c86a488c0abb789aa75219723bcc585282d1cec4d5cb31bbb2cd2a317047c24cd284e5b86851781226d2915d0a36f8bfc5177159c8d96f13ca59dd09d9a17027a659263165b1969e8a521a43faacf9966df7d4661c2691c263461ab2b214bcce1bc90cff726dc273689759540f8ada11aa23c18205173c3612faf2716c83642a08f52ac741a73a0fdf67a7b6853b5f0d3f6faa8f34ebfdf040e74229b3a298fbb28c50e1c061b94f9e3c06b1a0349b6c9bb4db3860e7602f22f4e1775f7231349e784734cfb23797f95c91a43c37a6e1411af4430032b0f0f0783a9583b845fa1f111d3d1388a9f8fb8902902c23881ee618adfcde61c0cd7b740ace041238d6d2aa1630b1e1c86e404f1e3acaa4b906f3f8ff7715d6a88bf5abfa71999d3324efc6e5db87b3a11b7bde2ed36024eafd2b5b9909b160a5f97234adc5d8806f7ef0878e875ac5aeb32e386a82b0292adfde3b34bd5209a6ff9d48e11c52526d7b2078f79a61580ee5c018f1cf0793b9f545550f2e1bc25f60f3aa70b7f8eac1ebdcd87a382fe338a600d97f724cfa4e78f850a0d4c2ab9705870d48b60b139eeb3e611869622f63ce6884cf11665b0e407d000827eaa9dcd9edf7e98cdf924b9e0077364cef5598ff1203ee45983ec0a9aa0a6dd017c68845215acf567490ff68004bc11d4ccb260b3265a64756a69f673c38a40d8783078e52606a886d6b548e2291a966c874d25531829098e9c4e67c384d034ae44ff7c4f5da64b8d4825f134669310dcc96c4eeb8010a728c3770da8564912eb7a4b9e0297dc7e23f3a1303a7718bc885eaa055ca51958717b505a9133854c0261fcfe7ef4673c1c5a0b5d3b793eff25499cfdce66838fc672ddb9070b90c088cb44dd4cbb0dc575ff53b001f7a11c4e4d85fdc2801a21dbaf2244a4bd7c99660152706d759eee98599bede9c9b253829a0a7cb390ab11a769863d713e735ac5f087521f82dc817537a17ccab65a1635bd43f9aa2fa7000a2f742e774a255e0f3a528647f178df1eaa52acfdaafab69dc1f63beef2b55a2f0cd6952c1e6942b046b584bfda755f3f64108fc0df6da26294df679d59fb71fedbbba8a2e19f929ffff3ef77218f85b90a5abf2de2442df99ff33a45fc4f9e93bf68de67f0cfadd98e11308bfea7758f9f47a6d958f1b32df422d60799878e1e98c555295c0e11a39da2310e02fddb68e7515c16a60b24837ada1fd4bd0d5d36c5ab3fb8c995729ec5d13a58d06e3033f714454884b890b2f08a1034daa1341fcff2e2989b59c643756e98a44547a2987b61f7c4e4d3996ae52b83fe4ba26adad13f6a64907ec86c4efa880230e75885bb5ece56a2a6db8ea86044c1d7b2995c503da644fd438c0696007bec4c0520067fc6a49fe4692fdec0d697c9d9427f2a1335d9d99e5a158208f57302927b2350c961b22f931b80f6511b6230168d3b9180cd2c831820dfaf6937729d76c59e3910ba5bd53b2ee27f8619d51593b07fd63aca8e30f80131ba6ea415f698fe9710e7ee3eb620c6636d85fa1215e32d8c44cb700b25080fc17b1f08465e6171fb50239b2342e03488b287c09484195b4d45902b0671db6bb7f8d2870fd7905442a5dcf9866d3a3259b4c8d0c37086ed33e16478867f8746e888a6e90cd917b5fa55606dcd63ed17ee720d8102ee54ddc0868737a86170909db99c00f19a1493f13050db1f0947194afb7f3ae577b04f3c42b9d11759ca071861d68b01c9c90637bfac942e1487ebb451e6c23bb0669e45e43f49856cb9a1e4329faed06d17b19200c3025432b620f85ff1fde311bf4cc5732aef0dce74ccbc9061c5673085b936d007d33f4c9b5ef01918588cc3f9aa780613043c2911b5e2fe8b0ec4b31539a6f259fc17e6d2003c88b1be92b2da505ebd0de30fe09746becc35986582fb5413e345144b2b271cdab75fa0c21a18d5ae634254ea6bd3f0efa57437bf29b9f197ce4333c2d7067cc698d6cde6730cdd36dc8062fee7b07f3cd9b4328eb0dff2d20c453f16a09ca4dd7e5f329f621bb8da4ddca46800c15c1f0c6d476b170c943436704baae8c58dba603ab23c7beba8f9ac8bd0480f408308396b58ee8836837b6f8bc2cb73dc024795cb10d447bd4dff7448ecca28fac00684e861dd5636a9ccce3f32b6e5576f91e819aab95aa784d416c6b38ebc831ca661535c3e79b3114a31c0a116758f2fde3f076e3470930af40f056a405fa9551060aa381d2866e168e01e509c7e4608b0c5c82f29615b91142405d185eb572d3cab654679d9ec964ab8a5dc5b4937926437f906e88c486e6af2d5c3fe81a797a7bc2d053e0b69ad1110b7b369b5e1418ae46a590a500acb0a250a3f440299beafe58c8224e02141898252b0600f6f29452e058a6f0c24a5e6ee528a48cd92825923c832022b2e23a0e2ee232072f7f72c6dcb11048d0046dbba457024822a2e22a8f9ac19c360d425821a11fc08411db16b75084a108224f38a9da9ea97edcf6ebc37954852324d652e1b580af639c4b915e21c5ad1c4dd8a20779a37b7358559211d044720a8e21ec5a75007829ae8020210c880c0c7078cdcdd7e338f7eaf0f4cf94013f7d1bbff81200eef1ffa40c90348208282dc48affe916e11df2ceedf18489a3eba6d48bd94fe8d813010289652330f1fc9d8e69697cad117db91fec64023bd5aafb0b52997cdddd91af3e80be3b6c6b2d7f4f5175b223bd0703454a6633664223bd05c6c75ad94862fec472e7f28dbcfe1cd515dbdf76a6866649aca88ec40c3f130b3c30e3459ef2b72978689ec40c3d50fc7b2e62cb73faa6b6866389a9fd1efc5c93495d5cfdccfe8a685dcea6d7655cbbdcd7b7c7129fd3627052e03533c034d7c2803ad0c00a9028d6ed7febe4cd64bf7cbaa90825585cbdd95abb8818a2b73dbcfca9c1478979f8ad0a9a8c90fc509b305e50994201c283fa80b068ae87f19c418d0806320080ca430c5d1f8aa978e943645159f2fa99a82c8dd5553f0f888bff0eb143da48881141700ee22854c0a20b37ea655fcbc6b3ff1b3d482f25a19fecf6cf8c228c888e20151e470012c3ef1961f9675fad4cd3cfada97e67dfff3e9e21b8bd10f36c3431780e23e3dabe98b3663f3a5e90245dc7d6581237c7b96b080100ba05001155460880a481ff477eac69794302bffc3fa624f35f5d3443cc6ae9d34ccae95309c9fe28befaaa5c23ac8133430ecda271178328402695000cacb68f225de1fea6bf3bf5ec919129c964fc6e337f5ce3fe47da5990214f0e14cec4f27af9d00950974175b390102406165e6d1ad3f2ba3b9a07852a1e840da831304850f9aace157bd54ab9ea032e5ae494d699eddfa89da133cee1e86346f9c27dc7dba48000b70d552d197042e20819ce922811522c045048622c0e33e3b3a33de5f552e10b8f8b578bf0ee18a712000c5dd21b021400391956935fea4a8f74771e4bcd8ea6b2d95113599ba12f1f8c42c221fee737720ae976651cb7762c57d6a1a937a5b91ca6aefa496b1c412865f20f69cccb0577a7bf4fba8ee9c60c30928ee334890fbc2b9e5048fd5415c9a3882bbefd1bb5f532e9bfd519dfa7074a150294d79a4a65249fd903411d444a9091f9e0b13519c0990892077266498a81fe6723cd8e7fb5fecda9c4a3d887b70b643572704e94ea5523f3556394d633e5c4c7c7d9569caf315e354eb7d4d87a3fd7dc08f187dc9bfb847093164126d8f28e151982abf1da22f93c5eca7446b0a754ac8c4e8ebb31230cced8b338cbb96db62883d3df439fc8cbd9f3014b9187d7d96ee4a5f16f3234d40251e99a632ae49d8a486866f134fc228891ab8fbf789b0144859493499425d121d97eb6ffab55e6b64087f1fce9c03aaf8ac0e2072a7fd754050165f59c412861d5042c2caf7e1dc83a63224a4583c541f898e56ef2b41425e7b041695cb11ac23a21c51f379841123b2544bc3bd521951455399114f7c06b990fa460071f719b3df1bc183c994b9ef879a5a59ef874c5a9b5a3b63529ae391cb8c4d6391cf6ab90fc722230c57cb52b35293c2558b876a4d826a427c0a755caaae36e53edbd048bd76a6f1c701e12e349a9c47868c7ca8c95011f148ac223e115b224c8d82dbc865b42d65dcbfc30dfba8ec5ff2628d454b7118d69d3fa86b707e496d6dc6e2be47fa6d4b69392f71d758e6173dfd796bfce552d6b4882b454829a2890715215384fbefd08c29d4ede87adf6658f5c227a1ec8645dca70bcee2d3e22af8e2cf54857fb863b9a99123496e389d1c95cf0fad241ccf8f8a870b52f574f25259cf359ab14c2f11ddf8caf7aed5f70660c6e0fc4c5cfaf7f84ac934e591692a038bdcc128f78a20c8c33d688029d48557bcffa57ee6c5b862d7c6aefd645f8dcf5916f707f1acc8dd697f67507cea98cf182cc9f1d259a7edace4b487117105b38888f211114e17224af8cafda334592c16ca688bb84b6d65475206c5292d7fbda04a16e43366b52c878c258dab4641fd36e34d77ec49ac9be1b8584d4c05bb3f11e4347dd0ba5235da732d05614ddc61453ecb7f13f7d975dbcaaf991d96d1ba19c6dfa5154b7de2f5521bd66a588bb88faf0ae35971dfd9c58ba2f286f0602c05f3a6e16753fdd34bd42f2c3ef34cd3d71520bdaf245e252b65789b4a524a15c5428bdc5d2814a761dab93b2d32ce3cbb7fe88f0ecb4bd45d27c5a7d62f517772f6b8743c5dc9835c0e8b0b37057c900b72e764dc7d88a349879092318c86f2d22c7a1e1ee27e16f71043c0081dc95c2e42577e47a8cabc425066ec0a19e133557a895aa78042a5a4a632f6f91fc6d528f81275ca6593448896bbbf44214abe240b8cdbafaf4ca1aed2255296d496b496c82cf1c1edd70d3072df562ca2015468debad2063c79899acb0d903540c663d77eb14b6b1059dc83b0c2edd7414471f720422e081e7af36b910b425ace25e8680a75f583be98421d274d3174d31c69a29be6bc9ef6e58f5d0be3c258b8b1cd23fd7e6f4bdb74d39ccf52f0533a26058434e592c6b0bbc2b06bebf776a7aeb4aa666130f1a7a6448ad4560911ed594a6456898cfbd456890f1720a30d44c5677d202239be8078dcbd878f024920779f49d070f724124812e24d453c4a13762591f5b3324fba8edc6775154d1794dad78c5d5c35eefed6f5c35d07c9ff73e4fe30f91386fb94e3f6b9d856cb11f90edff3e84f97298dd6fcfcf0c1e24385dbb57fe223db3e35dcc3f28f9b72196f9a45efc5cafd43990c089a31f53703649c013f668b8afbeb6b0bcaacad20af4f5b40909c8184281cc558a672ba2009f289c447fe4d3f16159f31fa1f26594d28ab63c1e05d92b5c7c87d7e86b9f450c138bfee71d253833fb945938ea4e1ef5f3d3047accc988ced1095fd4b5b70c6e697c0233553e73ac2e3b29895498cf711185d3fccf36199912b469ebc9196bed87e3622fdf437401ced0041c57d761a08a2efb3332140bc66bdafff3310a55516d9a65fb9959529d4ada2acb08f9e79f8888ed16f47c7e807fbcfb0f1fb28cf149e20771e1abe2e29553f14cd18215ad31f88b6885d7e28e23ec7ef53c94ba5a62e3f8879c768678ac45bb5537357ed94dc3d5b171d2b7a2567fdaa53f38c5d745aeea2b3438e91cffa2f9931dedfd3684e0e514e1177bb63d5d61c189fd205a78a95d76222f68f2e38440e568c6338329fe3f7e1f8e0dc4cb9a9c594eecdcd0f9591fb04ffab0acaecb48b2a68765a05a3778a60f12935b55f11295f4ea2a4fe119f24456aee52fe108d15c1c1e76fab5f4f1be9176a5b751059eaa31a87a9d4ca66fc3edad21fe5c0dfab249f98f5dbefa339d5e22ca066013053a87b8d458bf81343317bfa8a5cad940a8c7bd154aa465fa9a0944ccaeed8956daff561ca47391f88dc33b75ffbd0b9bb0f439cbb1613f1e52436597c2e11425e958d066c7864e98ab11eb2b8f450811e78dc7d5e9b1f943872fec59eee748df6f4e04385bae28292809454e22d69667e50a8946737dd3f52538942b96c30ecae62403c60a932853acd7d2c3fc8c313771e64bef50ff150640a75dc900b0f287c623e7b6c20b2a1b3414a6d455d4396ef25e29c1abc70ffa9e18929d46d35549fff30ee61dcff974afdceea611c285eee8af933285e1a88361a82dc371a4af92b77e9cb2c5c4ce9377d2d65640210a03f1a8a275d3f1c8aa79cb1a4fb0543401408e0719f3f728238c3744c4962d68680176870807b00180c50e453b62dcdf4f9ebc52f1ceb6284845822444925e76b1c6631ac7f2d486b2fff8a9982f9f76680f035bee86ba93280c9dda7017e6c3354995dc6b203f3bb68cfea6678f23343b7cd2065dbca70342483949965a86d3214995b5b8d6f0c597c763e9dfd1c439177fa7cafe81303d1164310b8c50033b707c391fb1c69b831100c45b3c2d0c4a7b6b67e6ec170c4dd7f63a00d8601c05491dd6fdcc9df60f406539a5d9a3b18de600a50e4722b0014df0a1016a0c6bd00490860e41b01a218bf0f87b34b37027438dc0850b3116005efd13fd2014c1940e7424298b08cb644083900779fafed0529ee73fcaca6db0b44b8f54250ce4a6e2f1c20c4612a254d1407b74a966efda27f2d2662dbbed836bde5b06d3d7cce58694ad2496c41fb335d2ce0b2801f6e6c3f54b0fd5062fb21b3fd8871818ccd05275ce87c822f6afda2f2278de94a27bbb950da5ac8d24291bb13790b2d5a7f6b41477aa1c882916a63214a07e31b0b4d36164aee1dcddf4916b615b408b2ad40c50a39f4c39b0a3dd85498626737e6fb68498e99ee2b7e7808c73715ba4e62db6d2a1071779aa382bbbf449dc214cf226c4ba189c794a42a850508206398cc58e22d85ba1c14aa5b22af5509000afd3eaada049045bd09e04777ff488df6a050dd122317856c2f886f3ea67c18c3e09b0f22d7e257ede6a3e53eb558c457baf980f1397e5aff579f265b5b00acf81600a21a05b7001491bbf6370030c22c0010f98c997976963f86ea6c0068798e0e6865f00d001b0a592e96566e28b8604381db504861eb516576160341935f2f7e659c31de5b8f277bebb1b71ea5a9f35b0a7a782319c5ee467a4207f9300e37d26c23c1b8ffc5f8bb5b8b15b9b7966b31111fe2ad25c8e6ada5b4f168826f3cb6d878649f3126bc65cd94e6d17163fc611cd68b5f9c47fbab6b144cd1fed628c87df485bf58aa5e7cb379a946c13bb2b8df5174c7134ee67e078fc544dc21b9276079c213889e507242162758718214271ca1757e14ca954ab5404b3f2eb5a90fcea6994bc594522e9b241fddd8254df9532e9b0fe356129a9fc397bb16dc18e7fcde15f1ebc3b895fab0cf87714bff87b34eb96c52a9d4c73295e12c41044b68cdf165fa8775a1dd9da9fb87719d542dc1053bacb8db11c5c58e203b3ccb9499e595e5874ff9af6a5170172564518214779f56b69520a48403dc6c116f9c5392a9938cb9965395e48c4d9db9459c653b0957dc9340019a24d49c5512a44f2418f944420b6e28c9efb360fe8f224186378dd9ad952001013346136fe9524794adebe0e8effc75c04c106798adab0fe3d6117a107e2894eb0844eeee720419f73142163782157ea4569511848cf023a4b49f2ee39dfb33ecda1eade98494f6d349d9c63772d251c57d7add87718beecf387434713a787c7af2a3a0dd21123a241deeee577554e47e4434943f8c8f64aaa32239473473ac31f51c4ddc5b73d8cc396490a3c87dea2042e490e21363396430ac659b867248f72de2fa38711cf9c401c5e328e2ee41aea5a184c309f3c3385c7d6c454393b2f11e48b669c8d1cc5c0b7278c3e1c3b9378c6aa552dea8b9bbbc81d30a3f37e4f0595fbb21c40d4d7b568ac80cedaf1b45a61b3f669716010cbf62ac082c2842e7ee347c8b208305cbe9730b0b14cf18067b992d1697bbc794b0b840042a3e61b893a6d7d493e3a5e26ba4a04b4e490499cf13de22c5e1d638942622d4b8c7e847849e36a2b8fb64a97cba99934b1bb5366a9cc5061c7f7165e3046c04b9fbe718fd3e3a7edf890d19ef59638d359eac1123236797e6927451430dab44a62d2d6553c3379bea7078ab519b429d1a411987a05543c6ddd5f03185baf7ee573bf4dc108c68a643a83285ba1f02077c0a754bc64c3faab91fb25ad3f06bcd14bf60302cf46384a5f2913d2cb916d4368d22f7349eb8a711ce34785c95869fea67654653dc2889292d572d276324042beeb5522184600a7523c7fdc6432998b66d49535da950a8588a254d3c364120b2030d4f10703c119434cc535f8b5c10602610b200610920ccdc5de7d8e9af85c9f9621134c472dcfb7398652e20a8800615346668c0708612dc7d6a3a5e959c177b6f19d083c3f8fd87350ee3f7a0b6732bd1fa8c2277f733a4703f83c80e34dd19f60c18ff019592ec32ee7a7ef0844f79ed0f727031e3e874b735a30a35e39b977a57e562868f19f5c32fbaf16d5dc1c2e50ad1159a2b3ec6bc3feb1ffa5e83431ffe7d69a6624c6e9927feccff5ef48a3eb0627dd0c47d0ee5d7f2661c82bf7db0f29e89fd41a15c3dc0d2832d722a65c3ca227ec962f62f17a3ad94343d13fb13d2e7b1a1199204efbb92a61a31a42f7b26f6676bfa9581c5bd8c0d586c37cd6584b32b6395d2343f19574c9ae6b76450719f950c21c808c018465e0b453965dea6f5fe2c53509a74f7533b0c937aa4b4319ee8d3d6142663d78ec1e37ea59c2e63fce836be3cb8e23c20a2cf23af3d5d9107353e370f7a8891851850f8a40fd2fc620489511283e4fe4cec4f4cca6513bbb6467b3ee5b2d9ff93029226231b7f3f1b7f32ee7fc69fa5a4a9aea4e937064ad9e0ecfb60aa5529fe461ad6d5fe9f6a5da998219d148cfe918a5936de03ede0ca0ea0ec20c87dd234a6b976e0c3ca68af7560e42610ef4b652d1d4c09a22f121d40a9b9bb4a0741ba56aa03f9390b1856dcbd560a8614f7261c184160d078486957ff988322f71ce4a0357160070ea8484d35beb2de1f4b3476ed10fd4f9a7010e4ee33dc96a671d0c3bd872f86f0c593aea331e3ab24d35456fa424683fea2887f21dd8d8aaa7851135954334d12e3edc5914f3dd4e91aede9240c672f8adcdde6961753406d7bbca8c0bee28336875e044da1ce0b19f782a46dedb98114b986668666994fa1ee06375be3966c5b255d649921921366c91ebaa0d2c513f759bb90756183fb94c5acec652eeefec7552eac7021850b1917331c0ac5450a36d8816b1b34b1410dce3ff4575eead900c6716a50c56b10a5d680c727adf7633570afefb345954ae5c5f2b5b8c5169dbbffb045cd839435d3d455e58afb942a4db82a415564c66d530f529b4aa150dbd67468507377171ad4cc20cb0ca2b8fb0c66e0c3e70f592d032bd2d39101910c7840ec650cc3d1228b1645b31bbd976d172da26811ba68515373c9e24afe7db3d880bb8cc9b824b53d3d8c6651cba2958574cf2206576230250644f76310148398f105832b30900283d01d06451ccb682e30902b2a58dca70b857251a1e24ee5c9a412e4924ac9e70bb0ec1754b1b31784f305352f709f2e98e2db054d602e68b90be494338fd502a3164871c735b7a09b766c410d8e5d8c8511c5220a1635ed8245112c7eb0e00a0b30306b606a254da91560f11550f115aca0e6b315f070dc5fbc82920ab2a8008c9b02ad2b954ac59432fda8e6ae4d9952304993499a4c7535f36876a532be16fca12ce25c0b566c330d3f87796ba98324607bf43e772d18bbd67a5f63d78239e5b2f92f145d36de03a5209c5d5d752980b11f0c86ff62145cd92a14c89a8382282e66ad785050007fed4c5f76ffe3b46c8baa1318e53f4115f729abc24f503b010fde3f7482d2ac7f021f57145d41f45dd1ba02664b2bee2678e2f34dc0834d00e379af5d4a60844b504bd0c4dda72c41113ca42a010c098c26098adc9d0450029f916f5f916f5f0b7cfb46e0dbc701df3e2a7cfb2ae0db0701dfbe9a6f5ff6ed93f9f6d51536155278c185051801f870e95103e72da01c46071ee6d0818c660807472934a0555301921f1088c1a509158cdcdd855c80072cb8bb6f5b38e1ee32f8b6c54c5b5088de96e6ed690b7e9f8842fdc59a08ee6b7e0dc479f8c0ea396204883beeb863002fbc6c2e77fc70a1853b9c07ccdd83f0adca0beeaef3c43b1cb3a75bac00c1073c10c57acbac65031e534ab261acfaf3c32ff07b90b21ea4f787f6ac29759099b38a592df536cd1dd6153f7aa9dcd294b38a5d3bf3c27f23328a0c3a7092f5af887736666d18abae641024d362066520c4a7a707c3ee8afb9d6944ba4c8b6a8d7ce11ae31b992a39afa6b22c76c86206f7d8b53dcc9080807b4b0738e031a59fd12d6b3a3c9bfe4f4e5257add8b5330f1ff98d81e667e9be2f75b66211f935966d697a997ead369e283d7ef9874c587f2a392ff6c451899c5ad38fdeb07c9eb5312b76edc640fb83c02c16928d593455fd5a55faedc6acb125e70914bd1147ce97874513f4f8339f8fd1960e92d6bc14949d46a1b48847b92968b78dfd57efcbfa269b9148d18b81e129d4c190dc3fd22d91e36bfc6a1f055fabe4dcf73f463d1bd262b6a6393e35896b5531eb63b485593e1bb3b6293a64d17bdac76898823adc9d56fa3cffd3a5a0ca27d39f7752f0c4436d313105f501405260927535eeffc1b0bbca99207d90aae4d422cd3af5759e89fdd1fb7fdec85552dfd336a77e48ea5bdaa25947045748d1c415e215b7bba2e70a9d2b6aaeb0e18a013858a32008ea16cd3afb7f428c591c57a3e0fdd978a98e9c3f44bb6ebf27d67ac5d074ba19efc8397e33fab4186d752894abcb0ffb9c79b1dd57c426989532126f691a5f3267660c7b9a75f2b7f48793b64331bf28c7c5aef5c4fab9935b3fb59ea5e16f76b3eb3a693bd90ebf722799925d87a493a6aef6f5a31bbb34ec73cbd4a13a933cc9259dbcd6e21d394739633a1c6ab4a72bc95a4c8743c63b5d498242a4eee4ce74bf16ebfd6b5f1646939b863f933f14bbb6761266657dcf44f39774fe507cc929d4a150b95be2dd51cb6b357d692abfef69525369ba34d472c264317b7127247be062d73eb7a493a88fd1fca7997fd32fd32bce180d8a5eb69e1c33cddd57ef674af3e31eba65567206b934eb3c2ca4e0ecd2f155ebd74bf5be36465b1a7b120bd957943a7797863b59bf2fc9a9b37dc568abf3c42ad42dd1f563b4f5a3afa5a0acb4ebe6a952d387437b3b947f08ff481116a3a18e5dead54a2f0dcb6cf79829088a3f72eadd6158a7c3cc906ca55772f689afdad7f135a372764234eb98785c2d9d1c2e081f24ae9f158f3c499a759674327f8c16ea843a14aa5b32f76b2993d744bfdad7f15239be968c9a1e91333f98310c85eaf20fe1b08b29ed2be2f16728542737b55f089a3e97cc3666fcf1675c37f436672b5fd32cd4d18d4506744ba40ef2bd68c55e48414c93a3e9626bebb5988890a663fe45efa5b4d21b91a327671e3ed22d91e34b6f1c5c3f497a70002bfdfc7d2a89aa41c6d42f75329dc41bb6fa70cea2f75aeaeca87e6aa8e1fb68487be4d4fbefd61f236218ad24d3f4e5e720a3f740924a1d648fdfcb7a2305eb4bbdaf9c30fcd1afb6fef76ccca2e12318bbb4fe3e2bc3a137bad21b7d69f813bbf6eb55c1906017cd3b98f519f76056bdf846b76e36666dccda9c58396173ad964ef468820b29b5d54d64a009279a60a2099b18a96d49be33c1c41198e081a4f9b3a8bf7e8b16ee2ee45b1250b8b734a065033be39082b48d8915dc5b34d09281258a9660c1122158220a69d2198757caba44c99d86afd4a1446201282324aaebe4b5281da0d50f4b674727e701604c19a92dde5267fa6148551215bbf666aaa43e80c8a4f97f94e0c26795236d2991a365deef71db4c432120f6e64b946d1b132204a5c3bd6572d350f6f04356bb7b8b6f4a08d966a859bf08d983b620cefb61327facfee7ee28f8d6c44a0db6265834a9c2e5b52529af95374818a6f9514d8a6c2a9bc024e146ec5a9da7fe42d026c1a3e53c8d79ebf72e6da9c2bd858a19dc5ba0b8b760c0bd658ab779bb7b8b14ee2d51b8b75cc0bdc502ee2d15706f79e2de420177efe12d1370f70f47d798e9472912487077c7a9f446ff477f3e8c5b3828d447559b11479b1168e4f8eca8ae08e3316209236a6e440f28de975dc724cba536d3219cefa3383a35daf3d54b65e3a512664b9f75d7fdc889f7be9ff1a43da6982ea6d495c61b39bbee148444894bce4d735643f5d29f3ddebada18def2ed967853493be96be9d6b1fbbdacbe38d4dbe28003285552cb6af76b898324b432ed3caa1085a862492c80bb8b794bfd56e7b91570ba5688f416bac081c62237fe41ce18ae344322cb40a152afe98dd454a2502e1b29a5bc42f86023634afb632854ca658342b56ca167f089776e237791b97097291fa444c5aea562810e1c49a1252d68b8fb12df6466e42093fc3e47c27d7c235965c45b5b1124709de7f83321fac371d3f0dcc9796c618d44c9bcbdfa0dbbc0dd45dfb00acff894784bdab364089e74e0480b181bee2d50b83b8f27dc3d665fde0f49fdf6b461f7c4cd3c3bcb5cbdf88542c5ae9de91c243234344368d46755fb7a91983739b25e1aa367f4439f3e3d3d155f1e39634ad2a7a747fa6cfd9b1e9133632a737decd27cba969efe9be50733a8df9e6261c88c614d68600827215a87763684399977ffb5b98d31def787f6fda1cf5c6d733443b859a6207d9b37b7b5fd381da32fd8865d9ad0eeb18635aea2be0fc66896859ca6e138fdffa22fb15a0c844271290ca149cdbc274d36ae21dc1a9a650a52fbb361967524b4ae1ace403eb88a3f3fffa237a91f9b8c77be8fe27c1407854a81fbcaddafd5ca381b522ed42894beb862907b18d5dc865d7b51284d646666666666466686871a0510d941872134333636a00d476dfe456f6cfe455fd805446a2a6dfe619aca5a3b1ce12e77a0d141083a4ca1836a481c43aaccbf18c438e34dd3f6d54914cad58d2f99b109c9b4a0a98b29e96ec837e465887bb5546fccda68a464bbd184ee73a3917e678e94cc289981e299fe365373f1a57bffebfbc4191f9b4c51b7c94871779930c8adb6cad4b8635094f1e1ae040789902bae8548b1b49369469ff623243b0dc59f542af5d7f6a0502e1b18121b1af5b1a9e11b8e46b3c6321dd2fb9391a476edef8402e366e79ef715b96d96386ebfde4e4bf01aedd13f3ae6de48d387f1abb4c39f71dc498e9e085399b26c2633f0855d1314f739f3e86b33c998b876589b49c6b5c39278cb9c95caa45d3bac2d07367cba765875b56177c358b09b03510ed4a7509731b775aa460cf1c609f1ae9fc5818a3b8ee140b4458a4311773f691c62aecceebb18538877a98ba132eb676f623a77df1f13e3c3e9cd562a412988924b1031b6205004e98c6c4d8fa05095ce32a6c9ed33c7379241b15e2a85ba6e89fca84c06a999f56bb427e5b29969ea9a69ba3febf167cfc4ea54aa46f41ea815e2cd3d13ab831cef0494b61bb2d4df7f4311c7e12d52ee06ee8622ee7376c30f9f408c804cf10d08910f102045dce706e487bbdb60e49b0d553c17db5dbfb73b75856177955b291bfd4968cfaabfaaf67593ac5e1440866f1cea6a6f6ab4a7467bae2835ced4330fcffaa2dec6405383a2aed8762e392f96f545fbab67685df7bd6be9cca3f9876a6510fd764a5395ffc13a49fb71eb989c95ac97668b3f5a32556ce5c431e92c7aa74cffc39133e65f23ed29c9d449cad449cab96b36e96a6d4c49ce29d389210ee5f8bdbe5fe58c29c9397e9dbe56d3509ab4cc6976695ec9d9e94e7e8ebc38728656f6dec59e985572ca94aa7d491d64fc3e11abe404c22c11b33666d5df18e8aeea6fccaaf4793666e5df9855ed4da5cf737391e0d6cec6ac9ffc2f1085375028827600b88c3b0403c006104dabbdf11e48cfe8be2b1c992762a097930f3dfeecc56434fe2c07d9d5d51be9e4cb7e46b98b3b1d44bfecb167417cb1f762764d961edf08668d6fa4d695ea25060e778fdd181b6811d30277df7fa9beabd975f26a2aebdb1ad6f6699847cef7ecf6280ccb1bdbb30311e983bcb14666240e72b603912017d324284a1d862032233795212812f111619aed4044db1a6a900fd2d327c262d75efab49082736bb9e90d3232339dc4bb9399339d9cdd7fd57217770fdacdc13e77b2fe58e9fbe89c8b6d0ca75ada027fafae18fb9bfa3a385f694ffdbaaadfaaffdfabe5ee08f017203d2f400cf0628317537faed19ef9616de59773a4dfe797d86a4d6598ca60d8f41f7d89fafbded31694302c758cbe96ca70e4fd5d925907b3becfee1ffd9afe111f9c835d37c983d6b54524f5c33f37497d6f0809665dfa85b38c95548b81b01dbf4c757ed32318bb361eb2ad8d5934bc18204bf8bd8ccbcf19810e9f16ef170364c05da240578b732f330cc0bd63c98034c691f7408615667884b1d55e62a8e2345c2b654cf044ca4b0c9dffa5fada0dbc0cc0077727607989e1873bdd3447a66976bdc0f00018b2eb179811bcc0500133811798245e60924c979c78cbdade19f720e14e9a430e521cdee389f7a8c2dd87f097027c3333335366ce9c5e7ff4c5fc7da2cebfbfdad715ab7dbdbc10846debcb5ea2e6f4f81fc621090ed21b27d00ad9ec38e29b1d437cb323c6373b64f0cd0e17dfec6871f715522882816f4556f856f4c4b72207f856747d2b0a72f7ed99587dc7caddb1bab7502175e1ceddb192b870f71e241b7888f78b0b334d8f60570b36f0d8b53b2f2de4c0bcb4e0e385852ca41ad0e0a5859a2ddc4955dc49347027cd4006242ddcbd07290b1e2b80fec2824c0b69e385051fd4bb22ac93a8afd843a1f1b282147f6decfecc902973b2a0a6b418b8936040c59df40217b8935a80853b89052b7027a9608a3b29052870279de00a7792094ae04e22811477d20844e04e0a8115ee24107cc09de48128eea40e70c09db4010db8933250853b890a28ee240c4ce14e92220a77d2052ce04eaac01377120526e04e82e20977920422e04e8200913bc98913eea4269870272df1007792124ddc494938c09d84c411ee242398b893c69a3b8936e44e12b73b4967775211a13b095f7712f8b9936644b893accc9d1483b993beba93bc973b8976ee246e0877929010eea4250d70270511e44e5202e44e4ae27227fdf8b89318d072272161b9937a8eb8938c00415af1b8937ed87127e9e4b893706edc49aa22eea405a4dc493ed8b8937a40b99378a871272980883b69071ddc494368dc493332ee2421d39d7432b99372c0c19d145372270549803be90620ee241b6a7027d120dd490838803bc90033b8936488c19d04038c3ba9000470270de00577d2cbe64e72f9e14e72a10577120b2bb89354488124001feea40000c09d84420f7712a9c59dc483d472c713dc5b9cd004f716262cc1bdc58e2cee2d4a48827b0b12ea706f398211dc5be838726f99430ed75f3fec3d50d7cdd4c81b642773a6fbb5d4db9ba9f9d1ef22a2dff6cc4818beb13d3ac809c3721ed1e991542579e4f0c2c3051e3d5ebc8e49a549cbfae260bc78141cf7e23576edc4f999e817cf797189f51d4d70f779070d240a85ba83c8e7dfd1237d90e3cfb8106fce34fe4c8678e360d74c53577dbc45d51374e0eebeda9ee000899ac28a0e1c49a194102fcc276a874ea753ecda31bf58440c7f2fcbc4e617dd9746657ad268340cbb7687080f3a1091a8211225d49d24ea3d3d69667690da5269872a95dac6ee29ff10fee8fd507ef4b385753cddfea82c45a30391991921361265b7deb1c701a7e52371902fdbb16b4db2a799e66d5f59a80b690feba75b12a35a9417cbfdd91b7fa6d3a3f2d99999b4088a1a5f792f66e9f1a5c79fc9af746316bd89ddf18dd468cfcfff4e9632dc86567d9c31a46015420377bf98deb07896e0d1c4793420092fb82bc1dd2fb6217d994425a14912ae772184440999617cf34ceccfc7680b0954b8bb8b79eb77d51104f73c79d017d76153078cbbfc107b5a5efbe3fd1037a34f43a1f4c533fa4adc5be2706f81c3bde50df716375a8ae019048fa0c31186082dd120c8859af62c23e0c0dd7f8f3735aaebd36c4fa87f8f37f3620bc3726b8c33b5ed9174d8d031c39474f4707a730487577a63e56805ee0ecafbe05111ee1f8eae8db1cfecf66bae9378cb3ceaedfb3932832037470f730c998306771a785c3ae31b91fbcb49e4a0e2ee723471396ae268421c5ab8c7518b43c6e140c3dde1800247eb8d3ab637b4f0378e9879a344e3061a6e58e1c6e70610eea345b0520426648a5004cb91bb63898225c86dc02289b00611a0b8fb0c118a781b68380a35d3069499365ceea5367ab041061b4c381b416cc0b8cbac6134c31a4fccac71c4d56882bbabf1841a47dc678630650836ee691cb9a7518334ac704f0395c6298d1f8e42c91891e1ee4616300aa5293fcc0888bb0b610d17820884d04497845024087504a18abb4b1f644ce98820d4b807a1070d5f20603103841a104aee8ec61534a040230934646800a1a103a7bf7225bcb9cf3367c071869433eacc19407e70c5b912b7efffe0897b098592f9418f19338acc2032a3889be17e25ca1522771f30c10764b80f38e0030bf8a0e6831e1cb97b0faef08bb77e8178a3503232991ecc94b14619454e53065119364e461d4ec60c34c095c8c0641cc93b6f5d22c3ddc7a83246126354f75290316618c3ddc79f49d30c0fb870771e14c18356490c2c6688a185bb3449d497be8f7a62202186cbdd4b62d860a509eeb864e50656acf0520dcd8c95ceddad00f1f16725998fbe766fc1e2de4204f79636d808234a181a78120613398c1a0603c2b89109e30061b88491c20ed470f714a40f32e6fe77ff334994a6316992a8bc43ae8442cd7cf4f57b346f8d426d8d6532145f8f1983df4382c3dd39df7690005053da83f27b71e7743a7d304eebbf17db1c99a63cb5621c1d0c03e38a592bfd3e15184c801174ca0f460d60c0b8bbac51505b29c168c9011bee2e5352a25c433814723a697d0aed4c0b39e1e0862fa67c11c5bf60c2252a4f21ba2807ee12555f2711a24f1be39c41f0d48591bb47600877b7be7171d4854ce3fc4ca8def6256156a6b747640e399d4e1b91007c73f204df9cc8e19b1320f8e6040cdf9c68e19b1316f8e62404be39d9806f4e9cf8e624fbe624e69b93207c73f2836f4e4ebe3991c137272ef8e6a4c5372792e09b136df8e64419be39e1856f4e64e19b1328f0cd090ff8e60415be39f184ab20001f31acb0828b0f1abcc51dc889f040c1a58507cd0824219c2085b4a475248dd3117a30c316c2c8dd673a40c413a270771a993a5050b9bb1739bdc08a6fe01abe81577c036be01b38c537700adf4009f806d67c03b76f2011be81d53710c83750e51b78f20d94be812ef806b6f8f621c1b7ae0da824343603a97868640000002028009310602028281a8d872332995c3e28c7001400015eb05aa2684a186a518c420849441001000010000000044c18d7e0540eae50dc1147c2e9fbdd0258e2c1077292619f00953008671b0601e09431d6a31719a695d9682159ef62fecc0123e24f9c0652fc9a6eabdd3fedc1e838ca712059904057da1457bd9df11d334562441616726c944be80184a8620d59c161c30a68c82a5043102c4e18250dd58f913137ff6d8429561cdaa1623fb22901c5d495182e043e34fffc757422ce998ecbd3613ae9b836668dbf55fc0b1188910078ef3e6cc86f691b661428b88c631b5fdf4f0a1cc253facc3ddd74152a2086c4b099baf941ad81f9a130327d036bb3b17d7a5b4656481c91119658a02daaf8fdad63c7647e950b9b0291ef4505a48e2c5622138ca9477de216b2eb055021bcd8259f5be068c78e297b766cb3ccdf21b1401d831beb19f7d8d2b280232b5aab630ef83a8467f9e69e94423dc8d49e1bfb98c8d82d45c14758073d98db3de10bb9628a98e9b2f4b1ca4c76f8024dff46d0f567e16d1e01fa5305c1d0876b5edba58b1bcd85507c4dea3abae75344f39a8b570024452619b6e6725da7e698417c96b918a94406186e5674a17cd80aaf420e7b0a27c59aec4dc22b3112962593fc8cc0114f73a139159d7f22be55213505fbfcd2923dc5e3c7615b3889bfce54db6f0a4873502d3a35bb982977318a39bbd516e1d093faa0aff4b38b4702139f5e3ecbb3d2cbf8f476cdd59f39c74c8dc2d2acb2af82c6f231cd982bd623ade793a7df7134590799c884d5a8de3bb2981f0cf42099d5bbef8ca061058c048e79b20768f10f820c5ff2c92ec719cf8c4cabe407467014705290a6fa9bc793c01c68bcf5c46042b7c867553a1e575acc007ad1de4afc966992b93add2c09a022aaec4d99a1b649db5068319234bab0ea9a13156bdd2320a63374290b147a7fd9927ce0d68f16e6c189fbd1dad07540634e4e9cf2dd192ca1943f01462ee0ba0e09e73f10759c693997c78694c1a8bf5e76ec7ae94db78ff5099ee822d53b8ca333650a413e28cc1978ddfa6ffa3964677b5e279c6ffd66200f50b2e511f596c4cd760f78e24ec9bb2b7fdb8465a07bbbc4bb4b2bedea16b74815b543264a6bb5f855bda7fe23740fe7474b0b649ad0b7bb2b9361c88bd4aa9eb001cf837f6818434f29259a0acb189071dcc931855d07d9ae1b16ad198576b1e0b06f60f2e71706fb799f21f1f5c69626142ebc2e1c2ceeeda0d43c2d28aa667b8127d56d3da36cfd57794e3a06abee3838af4e1efc772dbc70ff0c01eb1b5679bab05ac1d413ca7970dc42bcc00d296e5b4e9bb6549d10fb3f73491b161d9e15a9fd856822096f7fa6cd39dd8a558f9fd07cefc6a396409124fde12aa4f616b20189a1503b409eb34620cc24db510c45c25f51879fcf95806a7a9ecadf34e49e46885a504a9ac88347a6e27d88cce64bc2ceb7ad419b27fbf11d39b378cae22eb9587ec96a5709bb6d484e9da92e043d018d8e8c2ed9a0ebc19c881f144d004d22f10b478abefd8e0d19c2b91a9ab0285d93934791a1553b71694ba448326c644384de93807acdf44164c21034d6131db225b41f112aacb7006c7b88bde4a762d9c4e8525b526dd17bbe491e03307fc6508de7074d14e84081cdc25899f6b6bec388116d0b6a6244fcb254a78d06ea2a9a5f51d15a2d1525a89bd361978b441639b53d01a9711be49cc7cdee75822ce9113e001f26f0760239743f5098307c4f19218df38c617464c10d1440bfe51471d9a02bcf6195647050409c8a36383ee0d302194e1611c1495631d3bed2e158d6d863a6022a29db1e78f8b6926d322ce567c4eb691915983e87913a944a918107bd591b0a9b0e554f01a864bb13e3ed42096d34e7948c89ebaa5f3e5a483eec4ef6e68eb11818cca3c240223a1420cd22eac1ccf1eb447efd95e70670f74363c7a41381707d1be9b0fc33f46ba7cde4acbd03a598bd8f05a5042505355a8a7a3517911d7d503f06c93283c8b7d012cfdb65a5ab72f4e91ce89039b8d3afe35ae8c48f76be18aa84f3a77f509c1da103ae1b50cff2ce8a8f42a34f0996286797d6b60db7c70004be8ba4f033d4dfcb14b95b149237f317cfd2697e4aab08a7c3351a46c89f2d731a959594dd599e6574637b3a02b8930f42b4c35e04a525327b632b17311b56b1d1faadaf52e08ee5210c58948757c035a389ac22d9797868bd2b4668451575a451cf9c01a61dc3b7607c7f2c6e8c76053dbc84033cfc291f7eef3cc4069b2740872850907a614916f4d8dc25e39b64692169c26bd51e514cba822f3c6616b3041a0752f51a9dc8dda39f94b20d94cb4155a2952977c80c6511a61aa9314862dd37860caa780d66ac6d3f52a377c8689656e274316a1586805d06c44ce3b2322892476ce27a4b52fc897dd156a3d12ee38b38dab6a1f3820a9a56daa09f71b890c180075074a7f37ffe089111d4ae60b822353bb0f3da7ab16cb086b9908dc3a891ca2724e3b17dfeb34ec323e5cda45d5e257d2bdc40aa18f89073c8d6d2a577e3460179a6d22b2ba78e01e2aa9f39d1c1ffa13efec5c082646be82ec2298bf1acb13086039f0664e889618440916e8ad072115a889f47e2bd4975a117203b714c119ce292d9f0947d7e5dc4ea8b445192d0f22f680ff89fa518517b0b11b069e70e9535ba65bcbb30ccd145fc470770947bb10db211daaf4270097cc3cfe401c650a6adea2aed6fadfbc08d6209f38dc671c068bf6da558adabb2cfa63ef2f15dce174b70179662fd71805d3a2cb0c77b66d80704dbc559449aabc9f3ca5481de5a517b87198570e2d92694463ff31a698c1203fa710b3ebe8752d068a45ebeb26bb44cb3699a2ff84af8af59f9acef73aea4079dbd5db0ac107632dbc974579e361b266a81872ce1cc7725bd3cdcc67c3a31d921988164f59445060fb70d804188df47dd6da361e06e753c261da55fa58f06052f0645aa8979ec860cff0684de43a0acf8f5fb15d7605d3b5366a17a7f8fbd86975776721c77077ae1c0aec3858d84c32e1404fa1642cc301c3173f7d06f43aa337f31610baa1f3e68fb99b8c904017b9d865de8f61549786e06bb764645a2ab3d496033e91433bcd3ee6edcacd1fd5b8bc1d2b1a1691667c98ec801337501179b9da1db2dca316ae7dda4de6c7da14602bca6c2a748f143cf49b6b8f2853c68ef0213fcdf138718e0a1920ed44d0f253a27945b322b6efd40e446ea8f9a66c5f01d643d6680fe3f8e4460eea82d45c3962c434473ed7849581e0da085ceb6bad400a0ac400a743e9a80ee0a11e870e206f46ef680eeeec880828e1970c28d00cde600d5c809b8ec47c08fcc1a924ac0872e69260ec00ec97bb29d84660dca13b4611ea220a07293f1f1ecb0f128a286790236d1827d014f339b69c9facfb21f5f162b67c0bd3f9b2c8c6441da9e5507236899c5ac860fddde6cdd0e3675ffeae9b97b4cae7d696817d6ac6b3f0db8ec35872daed80b970977dc0acb6e57c9d56edf3ac8efb62a001a4e81415c85ba74af46b8946f02ef6d5c671d2543d32d72548db7e554963b0e877b71d54dc984e15314923aa08dae09f400b9a217e00a1a45d48be9bb9f2c37841a5d6168f40c49c112aca1ad910d0da1d1866e1237f4cfd7d00c34f06938d50c5a633a4926d470379ec5978930584f589a5458a8068da5d134d69e6187bf517d12d786794d523e7f67f66d247a1e8cd5615a8a139f752c85df3ca88974897194d71722dbda21ca0f874816fc7764a8617678887c20dd0fae9d0d19a3cf4445c909ba0009ce482e72265b68f9b078729527fcb5ecee9b6f8f266c3ace35f30fc5d18c2d6f00cd693932cd54ef65fcc0e1b2a6a1ef473fbe81ef257f24c2ce4846ca371d7f73cacc8fd846fdcd93bfc44a9b01bbcebf9898f39337393ebf53f0d13f51f0ac1b68beda798436ab1064cfb36ad14710e874735f7f775ba724e0890b0b4c4173083d679c39d7dd31e7565fcfacf1a8873dce4f7a22023d47403e3976d8d805888e17008431028a8c6fc0e89803441807c0c8f805908e1b80c258018e8c31a0e8f8022c8c3920c838028c8e1f00c3b80144c62ae0e818012a8c2f6064cc03828e03c0c2f80148c62d4074ac002e8c1150647c0346c71c20c2380046c62f8074dc0014c60a70648c0145c7176061cc0141c6116074fc0018c60d2032560147c70850617c0123631e10741c0016c60f40326e01a2630570618c8022e31b303ae60011c60130327e01a4e306a030568023630c283abe000b630e08328e00a3e3831b5973dfad4363c27106fc192700ceb103888c5700d031025418afcd594817dfdd28c33b474fdee988f4ed8c14de6b04e48d4745dfd768e1cd4741de7164f4fd8c18de6d24f2564747df6854e17d47236f7e14f41d4616de6f44f26e47a26f6574e18da322ef7b34fae64611de3132f27e47a4ef1677bd39d9760170707c0378c60e4073bc0040c6b0dcd0a33ebb26407cac0047c61850747c0116c61c10641c0146c70f8061ac6d4064546e4f14757ca1d8b4ba0b917f1ba345ffc548d900c23ad5ecb58bcbe8def35707349570918dbfdcd4681a5fe88c72f6b7563ab8a28808e61ff2584984dfc694d40aacfacb2af239ff8f232251c1870bb1e3b9ffa804cdab909205a2fafc0cecb312c450aa52c8eb51be15da1eff9ea09a093c2abee62c774967a23f722ff782c7510b20c01a679563ee4d6e6ab4e517469a4bf96dcfcee265fab9da4ccd180fc0502d58bc77450b370140790e7416fd584a0f1d936e295757ee578689d0ee62c787799616a5248dac10798cad3c74cffcf4592585dfee1d2bc81b7d25036a60623da83ed4e231091642fbb6dc5e231b267dba32086cafffd09b486410487dca1e84a4cf8a4e342217cf1a20bd7f66536b2c7ad456228f2445e3d6cddefe0d665ab1c9c214d853427f7334f9c3c7295f4b21a2da83d8adcca26997ce7b03c5b4cf93774123e5eb8c478249ac677a815eab3785b0dd85a65a96c46c7db927264b4f29f96f41d70653ef1ee9477fac74a7425d87a978d8fd7c680c10d413714eec3fc7fc384cd46196506fe1c1f682ff808713c152f0a6e9014054399ea63210d644c41a878306d0d7faae4d88ad63755740b40d39c51945b378dcded6e9f2147f3af041999eed1c035a4984480ee62aea6f9d38945976d23f048d2fc37b034fd25055bbaa8a8c4be48381e91455705ad5a421ba09488c11ea8a59faf31ee45c0c75035e4a0b5109a8f9c0f457a696ac268a5b520594c7272f36999d9043a6638b423dcfd419cc2031e65af97e716389e9f13ff4781f9f9b448509a23088eec4ace0bf27128d604f8b5a9f5d7ef0c42f3b97f1d36f5a26a3778ad0d905b134d3e0f809e3a03d392bdf8df4a2394763d68a1701bbf6ddc0890cd2c6a7dcc85c097fdeab070929af25fea2f1bab5ab327833e7bbd345d2378b4f0063b2e71fa4a3b1964340f1e2a0470f1e679de8919afb0f0e14b8012fc48ff8cb91faf0168d50a72030289a30c2fe33ac790d3609fe0f8ab12c436bf900f2c15c7fc1e3c771ae06d3ce3ac8d94aef9c64b0cc47e4df2b1a0b9f708e7b6b5d9c818b5d59d6c122594eaecb6a18ee49e2af66645ee213fda245d1cb8ac1a8c2e010548c04920a8b380e0d29c9210098b361574db0f503cfb7877b50775f57cd8f72d1cdcba96d913c7ab97f6a44b4286e3444f9c9464d974ea8dcaa9bfb90dafa00b700ddba18c0f59c6144c22fc53080c5277df0b9f8422b62fcf049401c0bf03e5767a061a587131113b5ea34fc68777f30b69e77e1343d1ff443c200f5a8d5a5d8e089a08cf51e7046a0edf7618d5b0bf94c11cffeee6389931db8f899697aa4aba5c12efd79b5c535dfa8c517eb62534471b03d3a4d4f81f01dc7fc022cb5746a3704ab57f02113b417f6314db861bdabe8a18bb1f8c0f99db953799383179b8604b393543a1300480aedf4172227c2774680c948e6c661eafe66a94242856660738c8cbeec73038b8714d3a2c795a9010c011b7eb993409c4bf3231cac1db6000530498d2986a37cd0192c427a689f9ff95ff3987b72e1f74114d56fd51cc442be83d2fe25f4acfc5aaf9ebafe6808537529ec61c4dba106444ab991b315cbcf9b4b64845aa827d5eb30dd5c12c2dd69c167b645391bace88dd98706f5d7bd59ed57ace0fb73dd204130faedf951fd4c94468cd48330b1adbab90fb10226779646810914c1d7f92599423fc8a4ce7557165c6f0b8c360511d87f6bf7e8028eaaf78f83b5d9364468c55ec88f07aef394ab0a8735e3243f1636ad4439488445f10d3cf8c1c9751b70e5da12304a0bc2400267f823fb4d3f1ffe003c8be570c88aae25682c01672eb7ed960b7d79e0b3b3b6294f00505da8a48c954f2e2cc04fad1af2f3d4523b6ac4d16afb6717204e22a60000fd7b596fffb6095cf12e2492c7d4f02d958926403f0dd003895ed68772236abce7498cfe12809bdbb6e8f3473eb7accb69cd3f0afa97434daf18765f035f1e8e5cff6523b57e03cef2f73cf8b8766273b988e62e9432533c347922c70e336878961ac29ffaefe67cd3a9e31b406776c5f54364be9f6605578afa98962dfa9741f98c75c2954cb7e6ff68f1cc4beef22202ed7f0056c5ed66669c2b171286e378e2d1bb7b9c3ceca395e3b0defeeb3bb095158b59a02a95878ca48f1b8794b7e5b8f241cd1f02569fe8df1d8b6383053b91ad8c28e11df80a06f90f83fecd97ad586ac9a8da27b9c22f84f9901147275e39773329c0f7d99aa5025d9b5c55354da8ebc894e1eca246a3260ec26aa220a4cb26032b7858e3f45f00f863eb7df1b2527c379ac5dfb23c4e584c10e15df41a0fdeebc59d43409f34713e67ab7d23c816114efce2e92f0ada3113b740e784a7bebce2f7e387247b160b34ccfccf57e41304e1299cfe79799f4745460eb8c8cdc18732f703a88bd25d9927f499dd31ca57f1fe52c08a89d7f3cb04af12541def1cbb14dad87f3261b8b14dc267237f89def7692f316242276234eb7c1e50bb38e7f2d38cf09c85184b1bfaa7b68d4d4bf78b0d2e992620a983ae5f03356003a10247679c7ff4a47fc00fee254b05aea96dfdb3ffd630dea7401c1b5f8c8cad7ba133bd7811087a41ca1699733876657e724fab327afcf5eb54fb9f45b06163d18e000892f157f6bf82fdaf563b74bfa34bbebec521a2ffb31648df2f269dd90c8abd656dcaaa5f672fba0d6cf76e0fffb6aded23e32043c59506390b185e53babd48b04c8ec32fb2533ff8ce621bfa8af64501c1532b00091e4c237f87d1f231aacf984e3bc1540660f09ea3841d1e927f11e248f71e527e4f94883e1205ba1c1b1c736decbb853ad88873ccb38c13dc46b140e99943d156978346536153d9e688f513c06e96da6fcbcdfab024247b446d1a7c07059ba6adc975f04f2cc80ba6da983dd8b07e5391f363c58df85e344a7b1802b680242354d45073ff50b1dd7098c34675efd5b2a1788efea3c76d77dba3f9f4f247cfd6996d63de8b381c24c91f3ea8c47ef33a789a2aad437dc7184f4212f8532879c13a1cfc0aaf11568da213769e1bdf811e6b2c591c9c18b2437f91c1c6c580ed6bde993c729e29ddbf613bf70f6a59bfe404d15f91b865504f932c333362f3e5896d0bee85c2d7f73688349952506faa1ccadbcce991fb728a12fedff9a2cb358ee9498b673c3714eacd3473093268525a7b2a9672e36cecbfb226c659cf7200e97b913e274e3f753fa03c0ddd17254e9d5dda52a6b4b9d69d1aa8f3b3f4f478e10c25e03ca192d83a4f0d0b9defb17d1d9ecbdbea1da8cf8405bc377c2ca92f48a13360c083008c1e34305c804d28df3ff20a9087049e51742fdf2f7e3ea2db7c65e2e2cd5e7cdd535eb02f1ebee4f07488de8768a18589f3e03b39ae77dd1d685290052673076d4a99a3e6a4746cf0a735e9031ac32d0ab6250b5c5638bd7b3874589349119e6a8498e0fad073413949c10dbc0479d4e07fc8d5a3fb2daccb3137262447a24b9da8cbb7e4ba7fd551cdf98a6ad903fd64d8fe63ec6762f999c3ed5efd2e4c1d0b197c2ee176d4bd7ba25649c67e4c66a1133bc492164422099b06fd7e5803ea707e425def08c6b844ae89d948ae042df01c196f5191d79a4cf775e1bafb41a51ce490ed928c7b55e7978038cd16977dc9e092d719a2ae12dddae9ec72a40f4ea3e8c808c080010ea79ecc484b173a3c5a15e9470720e51bd895069098a209d5d000b6f903f966ec725d5a6ebaf888a63ccdb8b60c2b727851e27ec2836eba83b6b45e620645fb8ab41bde9a3852a1ef8c8847a77c7d74217a83a59092b3835f812d44a5644862fcd50b7b77e944e7d7ab2ba74e97c90d589d8f01bc7843eb027a521f9e972a16d06843028dc4adc082746d0940d503f4a84a85514eebf0d8cc0e33c201a636a11b7f05e16a7ed098c5d323ee97ae1b8ddb1851694697380a080ccd6971ecf4df12e4347db5e32849bb7872eb7481ce3666e70ec501429288213d1339fe0f81aad5975dbe6323d75a6033ec7db97f0b330d454f0b15c51432bb96961ba2a6ef8b1075ad28b37e6d3afc96a651160eda982aecd45a0127e38d2e5d01428b8ce2bfb715a4be6a076e36ead20c27037230873ee34d17e8b84246e78b0ab314681d7d73ceba8859769d1bbd17defed32d2a80c2d31eabf155e1117d25ea7f09d342ff4d7296ace3c4b3c90adab728d8b7e8d91579800b0b9b7700181194307bcd1bfc71cf85c52807e75bd50ad37f8e74007224171f3e5abf867de76bc5358f456bdebcfbc493fabd0e9d891e6a34e8346fa4e79f33ceba72c37922473b841d00efe9b8be71f2c02ee2f88d0e146339504681516225ad792ac8a0958c9848513ea2f1bf427610856614df33f3deb58a80ef1cb1467944ba550fcded0fbaf87647af39c5a3ef4b38bacd7c8e1e18cfd1411b3ecd7f655430c0f000c007001f25660e1ca86218a713ebdf08a4fc263f27a7bd28c4cf201a17a983bb7b8be4eab03ac8abc6fc8f55b24f5fd96124fed0c348fc65568cc4ff1723f1fb3509f528c58645e67ee887917889529b2c43e3ff9ffffaae8b2a8bd41d4a4ca16fafa05dbc218ac78a3810458082d7e09ee4d2b208f983148cb4c028665f4190be08035fecb3ca3a615678fc095994471bd3ad6f62d42fd986e51a8d76e3445f943e7a471026e98f161286e2e0f830907115e9f38284d1ed98a6ae8426e786c5d9249c8a3dfda18753bd862cdde46bb41d2711a678769973b67add06ab9246c3bca3a016204179146781855847e457941ffd14926ea47b1fe73d440ec40291e5d4d7d8c7289218191166f7580267817e9c9df96b49e6b8e8d938987b7640d946f60a729e1bff9561043732ebd7fcb93af9f49302234038a83562b0cf3d5f9338016e3156392b91da0d1e56a125298185ca3298426b9a27a020daa0455e8ddbc97bf3fcd60019ae474c182de0ab7522d6ec7e48d2e9f03884592399c459c9780c916cea55a51c7ef5bebc5112bcc36d682b86108b75e7f0fcdd9146033c447a238db7ce7ee1e726ec7c99e06037824e838bba9b1fee861a4add850b0cdd8e16c26203b7096746a48051f459eb606fdcfb4a681667ac47bfee901355bac57848ad469ad096b3d7168eb96861e5cb335058bb3a68e4606f0c491e7702a5637189dbfa7895652731fa2f426634705d34003b12517b5912c8ac35edb57d300e762a33dce7b1707c7053e13c0c0e96e6f10ee00853fd25c804318ac874ed181998989393bc5e10354ed5316691be7c27410a3a902f80a2e21f8d7962ba5715b8f7b1795696e0b86cfac85a1251ec023e4a8178a28a795b4408e48d0c4af3c0a991548b25d25fb637c168ce983dec05cb2cc7fa6883f6e8def3640850d6951ddc07e132e63e01ac1c9917b442e454a7c73c6ab4b8530e6a461ca2b8a03af5cf7aec053bc1052f648b83c82b099f8ac3a84b7e8014332a62a3ab499ee6aa2c8ae8bc7724b68922c4bbb2a9cbb6b244347eacf2f30753c52e6c03feb918bcd20e1ddc09fa27b0f4aa2b0c8f77f598e6581e7b954c95e44542e9032de180e3fab1585d3f2552b4f802f4371a3f250e6604131572770344dc1073425e13cc8e48754e98d677cd1556a972b0d46d62e572732dd5e90908ac87e6288343c4433d52fbb1dd4f6a0c323511718c69e5de518e8cea50915a912e1cfc07650adf23e95292b12df08aaa18f308587036781ad57588cf92d5abd9dae1b54f7632727111b3220d3977370724b6f7aed19854ecc637484ca08cbda09c92de9621baaa629d703bdcb58c5857d0147430c15606851d327015ddccfb1d27702d52e2b669834cead8a1ab8a3f6f56fd885d50d517d326f4114732fb8582e4cdd6ffa460bbace1648e590f5dbdb949435dd644e8da52681cd63802c6dc4672cc5ca886bf02e52affce3c53c4a7410182dbd06d6f4a4accc663f387ae050a9234384b713ec2c8d1c654b25604f4826c9770932401b904d77fa10d2087ee76303dba903899c70ce325f529a6d691db7c6d031fd8f65a29b1920f0b758d206e7966b571499bc043dd0861dd183a165330e7cd4295243d43aedaedfa8d70d18f7ea79905d1a07e9160a902f4cd132c751f652bca0981452d7364a0cd922063a3c5ca0608100429bd04b6e16aa8dd1654e92befc1a2e5f52703735677fd187d10fab5aee5acd5c8efe31100c4057857b448a93378e79e3beb79cdc8aa50a2c388b8628b38c66c9528c2a2fb0ae88f0877b1cefd801893affe6fb51ded3539a9d51c5d6b37f546b98fa90da8d1d9e3a472a017a6027c15c9e4db34f9a646c2715cd52df2caa279653e2fe10bec29fa1f207a9549d52df0ba7bd676ef402f4edbd850b355d61eb43adb2f8a757bd71f09ba7673fcff146d806da1d2aea2675c7c4000531a2650b96d7dad3bfc33f1b601e9e8d2448711bd4fb787be34de855d104aa72d381b35ff618ec8426cd49948c99ac9730ff2d5f773c574e516b23fb3294fb1f3f5dbb0218bbf4b5965c04beb5ca0a26eabce6f7bc3d62ab91a3d00976b38b535846a7ef18689de96c0767946ce6a033d2ce346c6debb05f1394bbf91fd668e87b8c78f8d67d6ad8779d5ea64ca9381d024aed15e8a6a4f97e3d83b497b1ee00497029c6d47ac42584bc72a0201f9b1c3e5de2b8dfbc564bcc841689178b4e145250f878c3b54568c4aa9c6b173e31f54eb8e9bb81c60bc14d734bae1e7769ba89303487b3d8ab33024e7bfd957cd70a6d00668269d71b9ef9c0043924a0b441793a2d0683cd0658d7d8891c163ab3d8462b5d6b1269df3fc98da2e9cfa3840d3eda7f6950897ab5e359b6cfe244704c6d7583c010a98fb28addb9dcd86f855ae2df28af9b4e8ef34604cc5697cc745bf4431a919dd95b32cf8ab86c7bd0d2abca9c0e7b0e1980c9186311a704330de15babae2c6d3b8ee056ec512fe859aeca0eb81ef8bec09b4fe4a1adeb02b0202b53b5598e2383b361c2c4be1c68dd80ef23c83304161f05b21965181b5f73e78832a8c09b737a04bba24b69df84ff0b4997d6c7452acafd6be65bb3475593cf4112a3e9885420ec769dde73ea34ba3e995c32022586cabd7463c2f540a08e2738041937fbd705d1ffc1d30670fd3e42707c77ef6bc498ac666197238fd704bf64f1e3b211043cd3c69026651ced7fae52d2c967c80082db77874842fe5c029f218bb135529bcd27acc65d2ebef51d5391d07515ba048b3ef4b9022516f405391b8585cc405039d6654195f1e67628161c9bcb6eb79951a720b1c988c4a01841256544a865f5c4a2c358d088c211b4ab50d6becdcea0d02739c795e6071953e6a47f5072c16b8d47f964410a14184a5477be815a71e3738544fdf59f4a00cc5522773dcaac98b3e46caf165685bc0f3818490b08971dd5ab8f61615e382cf56322212f806656fec1c150205046b084dc8b81e61e3510433b9ee9690ef0d38e27715c54fbef458869a65efe815c77553f796a415861196e5151ec8a3591047f3900b0ac28fb25c7bf6d5e8d05746898a13f35d585cbc9f5705e774def374a216ae2c493a3368ed365a2f8c4d2a6e1ae56e9f15b6245810def19314544c3f05c392dc17ec777bfe430edf542999d78b6797f93a55beae7343a7051ecf611912cb9ff5b05191669f5983dfc00444a2bea8aff5a04555d052b0ee8da4f1c048d4bc0f0ec2a2075e6dbe3aa6775ec0da8b53b5ba5814e3e01f87b2fd4bf4ec17adbad8e988e5c8d88d6acc10532cabb8ba5180cc1cd9be4a4050b7bac396b79d55e583511178d7086eb18a427067c2e5d93b1642c752f949beb2b72cf3edfaa12a437c4f87a5c044509dc0256e000613b4017830c189a9fb74437a5789d2e57d39215f4b8251c217a2fd3d5c3647ae6dd731bba9b5a1b4adfad9fdb021bac325119e3e237566c4b3ff48d5aa96d6872a8e8980c47da064cf147322849bd330362fe106777907d3d830792b14f0b5c115b017367543ad1f043c2412d1727459213db38219eda2db399430a6c2bdeced61494e03757fde6fd752aac6795c98fb8b3e6c465db9c09cb8864b82e19971b88ab138a07de9e2090a2a8eb69906b79ee90d72a56f2344e1b400c86a009f12447d5c2e0089039ce9fdf091c715d1f846e72dee131552567af66df435aa11475be50f70d4ca0156afa9e40018543a94878c95540142ba70631f8885390150516339e7e5936f5a39a38ffe544baecdd1f338b0c8c71ac982c142af25f5e2b96e6c49a42883f401b14ffdfed534e53178ad32bf8b1bb8366eece2e1e5e4d27198c7141b2af8001757a212d72b22556336aa9a0a39d8edbe69114788f7ea7883e5a61815bda520405b9e48ec6a5d32ce66bab7fd7c9ee2f5acad6bed1570900de45115f0d1f7075a30303c98d9f68e063fd13f3c0119496d96f1295a47e6490e9c4a6054374ddef400ae8ea4197a56361c9989b2f4450afc31904b1f4208b69f7fe2240ccf6e0302d041c1efb030b1be9f82ce966fbcf67a121166a7fe8b35edd881601f30d36bd51900b84de0314bed26e446e8dc996d24a443a9c1c35abcc7cc29d732f11bc5c6fec2f8c463c9bb72ff095c191def14519ef83c7cbab16a1c2e019f978b6a3e903beded196443c32c77d627982e2fc451d2fdd9fa18878aa7ef4e3642cf612c1bcc842af4c2b0255350ab1295ed1e00c7cf421bc9701fe3f42680085593a5154057c32d156bc1ee865f2d06d49486fb879a10834c666ae2ab336d437596a428a430079bb000046e9a9984ea3745543a98a7109b8ca72dc3c262ecfe145184e1e8f1a5e813d3cbc1c3c865079885e8d162a087d004a3f913fa431332262d6eace2dd724d0beff5ceaa642fbc35e745e8d0245b2fb252011464a3ebfdf6d49ac937146c623960e3face02357ed53f81076416746d9a8c5d8381b2671c81531489692f7094bfda8d1e34c021e86d17dae670b97593509ea7e8bbcd06b83a526d2b775da4b11da5e41dd3b1fbacede9bc2cff97b0a1243e9ad2daf5b641457d30216423814aa8bb44d25a210a3b4656293650d83752642281fa1af019d5abaf132d9dfc2ee9278030b2321c25298b88c016d9f4c05bbf962866e7afaf5844f4bb4f958e1f55030cbc4e86718540e781ac282079e785bcdd651b3b29508fce045ca19fcafcf512ffbd8137c019cde6aff851f05d0b4273a94213b6cedf6bc37f4909c51b00ed153c5c7d66ad7e0f1822cd21cd59902a52ec8acb0761e3e7103ab830bf4a9b6fdc964ea3a7a99af74f67285ff976b21ceac45d93ac2a9e40cf8bc4dee98004f71723b11c2e424ae6532e495737ea103960518942b9f01580174e7a21321c615988a865e74f8acad9ad22cf926fd0aa47b0c151b0967ca5717de000461ed2945a9a5ef59713de98e12f663e0e67bd5231234995ca002a65767633b7debc6c1be0e651e3ca30e84e96e409bd87cd50a3bbec17fbed889905dfb49bea7c103b675950ca06f68c3ec888d192b69fd8f4cc7ced4fb23315849addd0163b5295911cac7eed1b36a0a796db3fa4e91d6b418900809a568ae3b6e301988ae4cef63f149014fd14c1244e1b594bb0dbd64248ba65c24a951a2d511b6fa0142ad3d313e04e101a2f551075c9c64591be872ef7f6097cc3b09b857f1f2787a38a90694ba93c19a891303bdbe3ca12d261481092cc127bda58caea2766a72aabe53a5bb09ef9e36039c546b9ff17dfaceb7d494f288495834be64d8f9f874c73079291f534ce67d57c0d21802a7e7e2f6738aa89eed8c3950e63de39c895235e3f5770b78fa021d6d01b9b5f7a3c715d5fc924622cd44a21e329b0854a55e062a9a0513b94614ac870ebeb1d66ee4a9705978e9e4f16ef74fb49608387f26df8a780bf8019bdd9225776a9bee016264d2d59b0765f4b7826ee9990a7bbaef5277e209ec29451ae1ad2e0543efa1e3d1838b6ade4e4558ea790b0ec7d4990e5784a67d8c4dbb601c1c04988cbb3042c7ddad9d5e40ac2cd613c4093012979614cff867b517b397dcaa1e42dc0a577f7dbf142f27308d488be9153f1b0acb80f6cfe98b97735d8e2759a60b6c82b4a1e2de7b48b3e7005cbaf09e57223e1360ff29256c82ffe3e0b393d88bdb17ded2e2d7dda1a30b237dd746ddd9aa6304533d15f2b439018342a00512acd0a6ef1a6207e559d4d3266942086b6ae3b441797a26cef28118b4d00ed81f77e8726124af50d454f2ece3152e2a12faed95d6b68c662aae886d4a8acadf433583b37084cc9a96ea027b2251bbe46b47d961cd206472cf834abfe15a89cc23670dbcc063fe8833be0c066492c0db7e4beb122ecb7f1d75efe6ef133b9e68601e52c14969c3375864cc7f765903dfaf51eb9c2f22895b25b6b320b275ba1b75e10bc11cb5d5453110f0fffc856a1c07a44e699eb27526aeeb2c945bd29d23e3be149e7b06b7940872fb70a72e99039e23c4cce500a5198cbc030e143ec3af52f84c760bf82dffcaf4d8daa73580d12f64c2aab4d238b13f99a746774cfd266f1e900b6047454825069be3af6ff075ddaccc19c03fe37d7a7d12dd6c43b409c9e510595daaea838302b1d97eebac1f8653a851b4e65537ea1f40cf01c2b84d1095e8a33498f9c4fecb9d3bff9b120ddff77e9241303a37bf8f46e827b0fc69d3cab2dae4bb8026bde7ba5817f96054f86af1e233b11cbcc1ea3d8b705027f084783ab21fc7c12d4579335e00d2f5260e3be6c351183865f7017a712dc36d747544e904f847b4d4d1f44262aa2fe43cc0cd919129b9b2eb0d45e1d42216ecf2dbd0cfdb75eb75091951c92597b73f41cd03416cd080d12e3e5912a8a7eceff9c18a6dd0b95efc5a1706a8c182ff0af967598ca6e180fb854b0503f8790f72e5f48c4618c1d2a0c2c3cae8a187da672d08c9589717576acf7a9cf669b145f2e2042ac7594be6ada70be629abab2f4d2ede4ad95baf103758f5eea87f6f274ef8e092ef6e8378221896a81d1b223c40a45fd668dcd205c00d2b444973b0133b5639419533db3ccdbf0fdc8ef30d27c6105a96c4afd85acedf40923dc6e8a93f1e38faf146414ed9dfa994f486673d92fcd35972dcdaaf7adbf1e42ffe81245a20cd3a0c98a286e725721a40c34c00883ec13df6c5d9a3bd0570d17fae8364647d0705df9742a2c78d7e39340ca613ec2fe55c785f7f603824b3eee7219ad4062881e885f7c6240dc57564389f7fab8b311045f36894cbd9057def7bd12ef3d5c6902f0ca383a1a9de0bfd7ac4010757ce7c5698af3ab450993e44fd262aaa1f8b400722598bfd6a401b76cbe33be62c53913481fbf3c5a1b4a248b8ce17e95ec29e65c3a6a47a8d856929182f381a082d0ea6e6cb3b6e55d71cc09ab8b912b348274a7ae4941b101bdde96d1bc874757b1a15e14b3ddf0c82c1ba6c521a7522ee949fd50220efa78bf4825c29209db74adcbae0c3b91ea36c33209e17684c6c642f5d72c0d69b0cbe39bab235071cf65240d2914ba160fd484482a468823339d2c149c5e3e4de2c04b7aa34a1f64c951c7e1809402f8543aa78600f7c32dd08af903c41dba7434ee86d87c0a288c591f90313b77a8eefeff7a694e436c22e0745897c15e63f8b5f408bf829eabc1034f62b808aaf2ce16edec6c91f272f256855efb28f5d8474709d24db7ce8d8fb4219942245b2de19f63348c4940cfb1b8b9a81638c61271e300879921532067e0be7989cf232c5384beabac808dc0f395993a0b8622d46559899cb91c9cbde6f0301583075faa2067aa8b058a0f3047b8b2d79483c36b1226efebf4976175700063ce7c30cae5cc0005ba0cce619699632a2034abd4ce458dbc332b138dfa09763e5ba1270b3823e7c8ce83a1fc6f921316afbe3a2b451e966fca27a6d26bd83ae8e3ee385dae3d580d45249f30dc58edb312ff11cdbeb26c83f13c1f0b9a70020dfa5d36f8da45f75b54575c7e94834b162e5a76bcef8b103eb567391990d9ae9c1b20fcb2562c8d456273daa24a5123250682f7999897d3de9fd0803ff2e7ebfb17b026a6495948602c507a1133d0d1dbdffd51e4f449b33144469c1a34ebe20f99b7d0eef611f6ba41a94871d3c465ac27c3d7125441ab2393ff9cdfa9833b421098277bd439ac5423d15fd31dddea003c36b2f36eee4ff3d61c1ea80892fd8adace58b372f136485988813c32a8c6264dc775a0f91750dcbaca8007f49e2e5e00d22e75445f9a1e1255623342cc8725fcc8eddec5f9915cd95b536742501dd2804cce4cdc83fa9676d8db1231dfada6fb922feae47137e8427e0e974b11f752a5c9be1a53377e425f00562ff51c9bdfa93635f5afb364bd129e6d628de9e58312941d625aab79bf73f859ccc91d336963be8d4758988739b6bcb0cbdbc3d4fe0f50df5d4c98fb3953ae6b85fd674e915798dd77f55afe02f3223408aaed0eb99ab5b730833da2c39ab63aaa1602d50bfd180a0fc24e6c3d6a7e8fbeeb097a675dc86e4bdf2ae0e09276e0c036466e494229b3a3f161474b2c3f6a39ee71941a0036918d02192e16712193281659f858129257e476248db3c2040f4bc952d197447985445fb301edac92e57045a2bf823ccae9e41356345228b6a5814e954ed24c225357524dd437c2889045984756692ce512680ac968088859b930809710e02da4a6851c369f2d6d5b82ebe9b93518fec41596a3d12f0174ea90a441ef0d9af2b8459134415fab66d3f3a37e589ca06450575799f33a112a222e07bf1e46e1044017099d5cc5775a4881f4810ae0209c4674cbedecfb692cefdc283ffab10979588acc97ce08d06791461df5e3212610e30f60325e7645881574270f1214ca1130180739ae09db1df248ba4168121b04031612760daea8c99cc2e3184572d9623839716ed7822767a26883b443a5a083cac4833489f41a556a5bf140f181581deb27253702068eed0d911602673ba24b55bf623609eedcf87c1d9fd28c9a8d86d096cf3396ba230d1dff2442913f905a4a6b33a4a9d74f82b7e27b7d5f7ca91e6ed849dd98357c02976414bf54e6af2d2cc2e8c9def3b34b027a0203333eff6e4c88f6c0fbcf1a10e609205b67453a360ab4513df21c910812809411a730e908ce1b927a3873388d3d5444c1c0bf43ee51d778c0e3654a100b1d908e6a64920fb00dde0edab2e31def6872344079080a0c6386cd2b84e03eff2df728351a10797a138d4036f1c06102f6ebf160c30bddc3c111f81ebf268d416ecba9acd0b07ede024280b1070518e001179c8cd42718b2a1cc703a86c2800eebd515607c9e101b1003ff60600babf1da73ea5fe0d81c76ab157e6a5823070011be37e04ae017727b707c0349f89161145d1ef423a4f96122c947d8606ec82052b12d09a2c10e8205c5415aa9764c0d1f3ad43eb09f2e650f41255e774c0ffa6ea7b08bc46ce9b3add460074a5103647f479880e14c9f1d6dee2dbf0ae043bdc38db2c464bf08c7dd04353fa6d72b07030b95e94b5dc8ddc39f030b2c50e0cb2a80196b9d45c7c20a79d584861b6c4935f4c731a6e109ed71c5f13cbc54fce157ad7cd3529032e1f6e95e6c01c84dc3a308519146d8f7ea9057445e1c95569d87ef8b065e9df48ebe63fab0c5868937c258a5b2d6da2e997ca506a3eefb7aa298e083b78f5df5175ab415b16ed56c48bb9208db0dab749b91a9b67fa40d2bb61f2e616a48538099cbb5041467e9b53bc0634542c51663f04a4cd4b982bd3ae8c0d4c3e1c836c3d656436e90413b88460d165643cfa8631c885e3d9ead7c60a19bb06fb132508e37d4494ed6d651a318ff243de3eeb481a6309de027ef6945a40ac484dd8fd8e172739f02d212133bbe30f30da5ca44d228556448aaa5074888e99cc4c42b7cbd850b3e3cc975706d7a85fcc4bd295cb06803708cb8a4a4412c82e92f3452e2c11d587f9ea6fd0b7f47995a84292d4c9e63b7e78ad8f36363b82b035017b4187903eb8bf87479096fbc8858bcaabcd0d81832171ee14693a98321e095266a1616efc539e7cb28b1aa1e41e3da4b075731ebea492bbe60979ef9d9cb1880368a252a8c66d2efa14d286e0476d2e27cc93d02d65b65a3029fa335828129625cc173f2097ca92a919fb23e2966ea07ce86eec3855e494c15ba9cf02432d4c98a0d848e1b0fe6342ee2a9e7f29c08ddba2341cb743848d8d1339593ba70a720cac310bc75a1c9466903ab6e868b1679d433aeed46c8b20fc5518321b7e5a63f36dcf8968650e32fbb15b0bb60ec5c84d6bee96e570608ef2530846f5121f15ef910dfbb446cfb04844bbc281abf6b18306bc2cb6310ef3a9664d49351b484832018309e66f10784f66f03061a3f855c45bcb6ffce1801fb77bfe64fbc7888899622fd47eeba8596f731585b11b8083dbd83bd9126debd825e6e29e21f92f7fa80578dc22184448b4a549fc5eb7e9936ea844017af18361d935ebe322be780a736b2dcc59beecb0d7522defbe3b24f0af6f48a77cf81cb2d07dd431ce2c1ae7ae77b1cab3f9236d208b265e28dae139831eb8e6dd3f2ffc31e6b07a0bc3d2c9dcaa23f8153d9c4c82f991619a874e2f1e105f7a910e889940cbd8f9538eda27d111fd531521c985865c057306fa0879e995c249617e925490279a53371b839739ed68c2b379604cf82e2d803711361105f9755da8d596590af5ac5a3556f5f88cd82ec16b6613fe0bb9153d85baf79f57d0fcfc270aa7f81f4abdde6ad067659ee392c5199ccf3da6f0821e7ad968830ef4cac2bd5a0581fbe88d33368b1afc00368b33fa1d81bb2bd91ebc4ce6c247ef43b2ededbc1a1d189318b05363f5a13c2af4d5d4517d61888986ff9e39526ae60c2e7f6d744baaeaddf9b0346eed859921ea91368e78019d578ac2b9adb0289fbbf94ab2134282cdc38cc9510df793ecec9bc2ce1d5304dc80dc04ff4bdff8ab9560bd3d55d0e4e7b4a67a331d7f58d83f3ed3419eb71da065f519e13cfd785c991437b05b387c2e625b5bb1acf03ff28615020f251134e78a3d8715af4fe32c500d485316ac13e1ea2b1a1039b0a6c800c96ebfca207fabf92821943379bd520594eb13759e45cf5878a3ed76bfd5bbda83c8819001817a2755ba1f036d86d16e843664ad1e4ea8e2a0434d6168af698eecdedd9101da8c87b2221138d6dbba766e365bbd2fa2741e7bd6350058ea699976075d2c8c28defb68eda68e4fb87a2dc92206fee2bbffd4066aeb2c55c068e63b21e8ac2b56371a7a11ef1f11037abc4a90831cae31294d5721453d4c48517b0a3722d830b85bf1f5f5d1aec17de6ad99bc888a03e5b70e083b913feca85e48363419fef28d26c0e84a449ce963a4921152320058adb60f85ff70da9130ef2c637a8a8e7e879cc62d233414f97e393f356ef70ae1feacf6e976509e0bf0bf58698623723ac0a10a46ce83aabb2fdd5e70053faa14d6f213a793f474b595c964da2aa7e9a668e5d87b96d62dad86499c9769052b2bbd24d69d345345d77ab0214e9e4eb04f2cbe50e4b844b93aaceab9939ed482375d4d713bdab3eb6ccebe25c62b58651d8eb63e7b7e1c3825e90dda77fa654cd3d9ee92d4c79df6a6c58a0b05d494f926a5e6bbfb2686f5056f8f2d0d15c86374009f22a9d09d3f023de272885843994482a43cd71dbbfef36d7ae14d3e6735909c3eae56f0e8179765e1a69f48423bb93517b7ee2b29f980d5ec53929e06e90ea641812ce545eb56b9196d932c4aec7eb0254696bcf9503f84537456d2a8d6c81387fc142a14e3f978d145a87f0fbf2dfa3cebef586fe904ee8a525bf9f77af474cf921f65a7bce9471c21ddc633965a725b9ba75eafebca97a3601ec004562bff4aae01ccf24489467430e4c03857fe26cd009474d3462bd16e3c5aeb2d68a3b3397bacf93530ac179173bbb2bc610281eb4eeb4393e6ea6ca9c03493954811ce76f9891740ec16cee5e1886aabb6efa3290365cd766f5b357efa1e8edb095879d197febc86b976b3b7c0da3d5f497437f5130e41625977a229b4123fb6459e0362c9b6bc44256e9c126ef42cae497816b95f5da3c486b6dcf56860c2a8ccb69e1c1a06f97725c7e34be90752f1949df0d5baf48a3db23a3b58037f8b8f1230a23c9e01e0647ffcee639492d8aa0578e31b15945d8f41e2320edcc8f333ec4b6395ada67af9d25fdba551fd765445241e2896db1499de54b0bd50bc6634375250eeb1f0b0d688f0586b75cbee7780b90b531442bc3adfb4f8ec9fa1ef05d1620235981fb0489986a0e1b7d7c02e730497de6585f904f9d7653aa975e16283fa8227d24209816b89061af173cf908fed34c82e4724db610d899eed7c3a8d3b271e2843a28105153c9b20264e5230e5f3d330a4f3585b410fae311d50c6fe8c59c98bf88e952824939f213bcf3165c7a50f6dcd804667e5e443ceafabacc2b469f093d1184998fba7d31f480e598769bfe6cf2d723354bd1f9da661110e9802646a46e1a0a0262002900ac4d9831d5191f72dfa5ff462b2f91c609d107947355af7e8bbc6144efa6086e677ee706ccbc860967af4206aa978a675264893a1c17c2b3d19e621097c49398758499764a3c0b6d7b181d2b8b32a4b999713e66bd1d9fc2b65aa871e7216066867722130ca6203509557b26019ec6b83a37486fca4118c5653989771a64bc1535032eb84b8c687606c94d2553c67fae08b4d7a60f79f1af5a3dfa824fc50a80b94cf4c377a21cb813aea936d0aaaec3f31f24e9884e7ca890a8a650bba0af1d3e9f3ca1c190ec0d72afd98988b0336e8caf8e25f3ce95c96b207c5bfe0963312896f0a1fffa0cc7feef4d0872dade8978a30ac642caabd3a06b66dcda7835f80f042104cfeafc4a49007470ecec876ea442870f1fdd9395bc5792ddaddc9572b7a1ed68c4d7812e7de5bef9bb060128619131585b53a63ad5f094c7b4bdde2b292d69ca59549e07087931507169f55d6a567d665feec93032802bf6ffdd367242b91e1e034ce803cde349e28fe6fac17286353b372dd8907b6a1019b326001cd7afbee554ec984116299cacc9e8215494f4b3ce875a314bb19025509756e89540580f364d96238ba776693f60182c5376e8afac694ed06512115bdd02eb4a7d516c94012cc90d38fb1304a9ca0a3776c2b004a8d9ec630927338336627c0fe849fa326314d0130e417bc3e470ceaeda32de951c26b6d3634df2247d2067fe89773a43080f8e32332faae975460dc31bb18970c7cdceade985cec3d53037ee28feac0288c547ff28d7c6c12a66b666383d2c16381b00bcdb78dbffdba13ebbe3ab150951a459e30347eb95f37fe2e6324e44d00a229e2c000bdbc27bfeb3c9a1019515ee6f7ce481c7b1a5e57f075ba882a477e53db35603e1e6340807bae1d75a30f6443b4e0e12e40eebcec05209bd14ab5b1d6292f4689720168d4b392a10bcff262e80d675124deed185943ee2c2796cdb042b7ee3303a4a7bb55aa9183e92217de6cd779be6a3083baa987f58d66b7f13ef731e931ec35046cad6b7724dc3b618108670aff4c05568564372cf840ee7ba94ccac88078d1e4d808c2b4719edfe47066a8e0f014624a6636a745af7cb36480c03674108658702d77e424a79b3e22a96809b765577b5316aef07605a75604cb8c7f9ed208db4b9a2e5c029d7b96026f62ed4e1201d51b56665eaa707fea647af0284dbb3b81fb7f749de055daa7342b6ca6592f4c9138f4e9255cd2f0d7ab0bc7088027ed763ca8824366b1e324295daa251730fe080f725385b95a8dcdbc53540f506b5562c65a3412ed97ca1c12d95f9e35a5acb940945e64b7023ca5819071c25475f7da9b3a6597656e0f3b77c0fa535314301ba27b6144a55f806b86c38bea449d27d0b3916c9cc0cb4638b95659896f3f240c373c884929edc467c9aa1a38a3428bcbe5b3e391dcdc837352b77b1169e8e449d87e2a34da7b364482cce48d03a7dd77e3525f66ce644944348abb51bec2e1c8614b9c97d56abb7d1a10805bc7342041fd269ad7ba026ebac92c9a6af994f0293c948c4a6106ec45ed40b8eff06c34204d5bc414f7adbc8f80c006fb32ffba3608467c840ba5d85bd14d53ff3bc09e739f41f53c7b62110044d69006b3cedb19a4445006453cd3cea0a7e8d655ce268249d633d6921c88b51ac5ef7e1071e360612b7cdc263e687aa0e7231fcd057e6e3b67bcf101aaf555bcec1a462eda3ac8ce034dee3e37ec923725d97726941faa1169a8f4b841a5e7e9ab9dc502d092c2a407c758a2f5709f5ab7416abebf27bcf7ceda877fa1aae6c232c8ecc9e8dc1a6c5afab36f5818a136a4da1219f4461750122befc30181bb83e5c3ef869ff7f0e511e4d721c0dcbf711c49580bcbfded6875a60df19fe03af8100f5dec2456821b0e2bf8a400606fe80a80172b3627375d39d413aef08f75889f0dc58443bd372fc7ee13b754edf6a202c17c7590001f4353ebcdf8b87c9243e9145be5abe2ba3db0528e4873a4d2dd56f9e49f29d01a2fc6be2eaf69bed63670707613833fc89c51bcf66c3c381a5ee6d3222e0deaa65ca23d3340a001352e56a1f8c6397ad341f57bf789149cf2767cf80dbeea818204720500b7a1c362eeddd8995126a428a6390a9fe3dfe8f87965aac07c31fdae5b2b9bb661abeab5a8830fc49942031a5708ff2f8e144b46072bfda804d2147226b5cd8e0c4c5b9106674149813d05e0eadc56633cbf1113ca369460756602b2f2e5802dd5af2bcc8497f00ac6618ebafd7463df96c78f6d413d0f725ec33984a336be1e724dea90a10f40694486fc13c441c5b341c9711ef974b1c179c203d0dae785ffc4817e999a1c49bfcb19c47860ff03c0b2c8772c25f21ba0982b0101e04183a2b53c89d4e4f2c50cd21350a79fb037442ac0f460a77bc52726ea1b3d579cdf417335ebbf95e17537d8d502330b7b4b12e39d205337eacee6a0777b42d04e5b213eb28210dcec2f1a11d706ce360fb6216e1cd41f5c3911410cd4568fa5815107cba154ac2b18fad5ec9098c3e1742d3af9ecb28da390fdd356b25d1bf86d70b1d7566c8c3f2897b8c7cab30e793ec6de50b16dd7015e3eb7822b6f80dcb734832bab331a52ccfd70c73d1db99cc38825813b4f055b623e0cd0963c385d5847a31b979d4bb79078cfd194d3d807c8185f579521ba6fa6996c3ddbd4bbf5314ea668fb0032352fe52c7f74b303ec0ead7704e1533196cf67e3b63f7fc6da0c4edbf59e9007b099e15d8b67edfb0259c1fb7c531a0e715e25f59065b9fe438d04221c764759dc753e4775522a9ef0661fe569b210407974d2097e27c551d1972b556a74a56c2f010671610025b9a9cf07778006fa21728eeb19ead90410fdf61804c9e3e6cc383799e705b8a9f408c48788a8c771910300eb282bd7f787e0ed9e2291f4e8391e5cde025102154b1bae5a8b68092c7bdc6a3e94a3f6afefe21b5e1a8e24eb141b3f83038ec75cf088086f341b2df72c430a53d465787ece677a6ac6c01be84c325863a90b43ccae00afb918b3cf0b7a231b16b1fa0844494b2213f4906fe4e6f1d9f39e464789c0d9ff963bd616e878cf99e8390a3d163bb535500c123f03fb67ef69851c706cc000422d251f24e1a798449d8ca6e94566ebada06ff6e499a326facefcb5bd706645e715e6ffa2230db38e7a274cc71facf12d3b559dca03dc82b614328e4da9065c9336aabc017883675b1a9fdd6fb83b0b4b8cfd344c7a4b6bc7893b5d8558c254a1b802090cf6a6bec5b67ef62f711379ab23a4764ee07f8edbc7113da5f8dac0a23edf69c7a21f90bab6a0378b06dc2d36bb779a2cedab0e9f314bf3265c252c658028f438d488c9dfca9341cd11e5867f000e6c750428231d6f28b21d969c141da71191aaf24af26e23184c233f8ef3bf4f4b11f3905535c554044d6a6356a5148bfad052bc1e4f380ff4b1e8e3868d0031498cea558355dfeaca351da1c0e45aa7be97329b4f6e61076fb7ff67f79b7e47b3bc542d301da4141e770ff45be0a9563682cf46f873fdbf5f207ae0206e3e8abe02651432d6285132fd8f21ed0d1650fe213bdb9b6d38c3f87f66a892022d648bf198ef33e35685aace8dfe68d2a3834dbc6d56ddbf74c6c63707a710fd62dbe31fa3481792ce87d6d8281e72b22a11af90bc3c18838085557b4d7392d4f505d27749c38be51dee901e4b47b91c06c768514a0b7f1ce041758d64085473e2ffb4065d7124bfee8775b7c0f88a5cc0ea44b572583a173a4060b2b093d2dcbce7b6e8b985cc5a4c56d801946e9d689e80b3930d894b2cf662b63348ad4c6132a33d7948caa1d65633528d0487690734bc773b58f31046425118cc1708303aa3a96a152651ecc396241567d367ac0df3b84aaf3997b1902dd8a6356949e6332a96ea32b505ae7abca6baa1de1ac82b5d7ae9cc0129a538ad65a220dcb175e1dfc731b9512d0653a592d310c84cde36d1edf867ff13f30fefa2767443cce447a429751f4314db19ff90ae11a1ecbd6f723d641e4a0652f56aa11e7e8175a8005b45553a55ec26aabf203609dad02c7875626ae5931c87d5dec05074624367746d4ad3b8cc34fe119a7a532e3cc3673165db8e177b451e9f3b22ec7b9151dde7b44234c674365af25419ee75532d893bb8d9e1a72a4ff330eccd9e1fab06390c9c37a10edc4fad52b6263505ed7f1a6dd7948f7cb75125e5b2eac9b1c1d14ad56fb7b63b297297e82ae6a6d6cf43d83421459c5cc1ac39f2ac26748f57f0c65dee3aca08c4423c978c7fa971b93d79eab2792324207fe15960cf13b28fe08d7412107ca75150d7fbf27b407939f4c050e7bd9678843b77ee1b0742c96422e752ef35c3333fd26c720ec3bd5ce3bb97c8a7eaf84821bf808ba76d07053e0f6be334c4dbce09011ceb795c1137a4591bf45a68186fcf96dc61e16ae085f5e9492de641d0ba0c03036eafe03cf0c5a01eb82042f36c91e44640ea68a63f710c7b5034b5d2f7424390cfa69f29c81b75a928adc18a956248badad500eff00eef882471ac105b08086fb7444cb8035f5a0c44baa247b0431a1e992e9cce6815df8d89c82b9de20f56cd7ebb2aaf1ad48ad04bc12a9d24aac2a75b4044827e8d3a065ad5074394d978d05d3a45cf66ef20948563d1e6d79a4fde0890e5953b94581b8d56420edf5794ef1c1497e552141ba82d8f58df87f7808a5fb316621bbb9059cc31a605ffe40f3654d9cc3773ca4377f12563e4a875f581580ca078736b03a144c6bd566437b49e8c44f740f105339beb0cd9d88c3035038e7079accf9e5abcc9be9fa50388f25629bcbe02e786c1f166a3b180fbb0ced5b064f18d978fb06b1022113c7d44bb3460f9a59e44c78c80c8888d4592cada6ac3f6cd8432d27ddb6a3e8c296a2caeeead227f10513642cf99a4da21e6aa619a9e6e05e099b55313fe5ea531d51b950c5f1f87aa7e00063c6302441182d5f720f8769d1406d5aec38e729f2c9b948be6028703e9846cd35606a5e1f74a4c8cd9a55561efcf711ca4dcd722f345d0cd61e6d07c6a043b13fcdb51061458af4fb869c9201d48a44aa476c1d66dd8a01ca25a92231e48badb8efba72192ef01fdc1638643ab16e2b6c1a6d0e76c5962d43038411f18bbf6afb3149b5df3594eb19820da31f36d2c139c3edc42f6c9f848b0977420d9e13c85d30dd575aed724f5e721478a62eab2281230d039993dcb92be89d1de1007bfb975759d0598e0480ed71c4b120e061a84a360442701136a5d5eaa844ec601d006358a594870061fbabeae25f8bd0f9e59afc83764ca843db04ab2386a28d03028fbc7671b36a561e0b81ee48ce69ea0c0f20a119ad67809970c4eb7e3209ec65ee9ddc609cdd349f512e2e70f5f8b886dc142d8a41b48b82e2efe9a489ccf9d345efc7a13e9a1b534ff94023df612bced250631cb58d651b5c26ea44e234dcfb023f0a64e3083005c653cd835375a52f704eab1c2dada45ea7975b5fb2d3e994ee48986f0711d0d39e3e697b17b60c2d630c152592a14214b95b3a394c2f890b5185c7475987e9f2aa61ead691fb1c30920215935851d4298f1a399cf549d5a9551edf70b23cd0e46f147d60f686337b669bc9ed19d6b4078e4dd82a409a0282ee239ce7374d172c2fb197121a99900999af2758a21e3bdd8a2ba35f759173bf5618a0f06083047a8dab023cc0b4a395b2c6a3ca2c663b8a4afbc20b88b404024c626a53a0c015abc37664c88d292adcc14131a9b1a06f9e765ad4d9f543e9c517313b3f9597e00330e05bbe125179481ebf1a30afc21a49cb54d3f8638b6eae2bdb98bb228cd934f09d3632c259dd514696501ccb5849cc88ae4fb9d15ba952419315c700b528423150839fa6d33a558706585f14d75da85d7816d5c791dd64077e5a623d218602f90110a5a52788174428bfe5d37d54502ed1c61e25c1f55c58b9dc3f8285ce7080dd94f9df52de14e5c041b2714a65d42eb7dd0f82f8aca3fe9e0b1ce4381f6849479551d16df4ee66f42ede2965b049aadc9f02257c8425e8961078162880d41959b2b56f0512774cca681fc7233eafa02cd87634cba6f4ec63919923aa41c8ad95bc2346b26237a20059f60c78cd2f52dc084ef422e2d9ee0b7fa1eb4467f6194135d30db77a4d28d2c4da42b83945ac4d982206f03ea2d8b11fcedd80858a0b2219c5a9466e88f2db01004b0f018e4d3d03ea6b2340c21074f45672ebc41103d5a7b5723d05693e0167c3017ee7399bff7c3ff7485170be5daf3b6947c422fbcd1bf1a13870a3f576a5bb2aad29e4336a21bd61bc736d38c16b89123ecbc1a9a49892d4943a4c8cbc6807dbb8ef8a709cd6d98654ecb3b8ffdaad6a97b5457a9322bb75402b73f14684d4f265fa68204399c4f1235fbb97b49a5ca34238d0690674603456542726c91fc6e455967d24eb48da6a43395653283e95a773f8701018b1d2b207369e18c084ae8d567f275430fddf3255c59dc815076a361315e4658de9b08d17c8e3deba4e808e445abe7c74df64300cacaa471b25a837ffd1302937e711377840372696998fd057659b06df16e3a12ced62fe19fe35a5a40fec77a26a4678a8cf1a7d97c34d718d40b19995b1c12fe0c2847e8122de6c65e82f0c655f00525bb45082163e67b14565fcc130db77e4925feb8d278fc63b51062f48727e60552c6b2b1f7c81e3a5577b4bcc8f3a14e46809bca60f78a5e8b5c860acea02478cd523fabbe7050c6464c97ed41edb8f41fd59cf3d3be1beb2447063773707d0b76578e1d802ac2c8e3ae8ac73fea9833d73e028abc3d1c4bf7b3ec306c33c513a07d96dd59f864ddb106b0d4fc31669e46fd9dab2d586d984be9d033e9b5781dc455727574571fb353b3f4294b644d74e426e845be259f6365894bdb1f81cce57b86ce3e87d5c13186d1c85f4b47f3fc018fdc2282439bfdf4c078428bcd3be4fc679ee177204bc1b69e13eb9994a4e92b8a28f4900f4be9964b4540cdd6e806c1cb8e271f81a25836b3ea4639100454bb66d1e26513ced687e24d29f4d75230c3bbff514f82d4095f9d370d8d46068a2db1b76f678fad27744c681b47a800e40ac0a4ecdeb6563f6af8c67d581718d652e931bdc8c339b874e63cfa1331f179c4468302c0c598309039686ca220958cbb74ac80abf9ca76603ce6877b9cc29fec59424eb7cdc3568dd74a87990c4a0323864cf33332543fed83a4346f3f1cf9a967243ae8158d200c496eb9c3184061445c71bd7e117866e6c2134c649c5fb8a6ca81dca2f67dc1f44db0fb8a8a5b9925f22badac5b30fe6a43e6a3afa86ac6b11c0ba083ff8feacf2de4b93872a08a4ae979e6ceeaf23f13e806267cfa49fc824f0f028dc598ada69b61ea5ecded7cafb95e71d5d83736ade0231f90c98b1d678bdc8b5011272f453768a877bc4ecb90a1589964ab6c007eb4ea556a9afaee9fd9504ac738a6408a929ab259fb3cbc198857449fa48a8282f8689d187b467250e3d74d5b40ee1a36ae463a685912558f2e181b9e26c3f03def8969480a4d4300a9095eb4ab820ab3ea1cab2443dee6d7314e8ba458c3173e1a9aa643bb815dc7fda80496da8cd3e198d6fc57a6a332ba56f296585bef9f67f2b0cf733ceee0acb45a723902b16346ea3f4144150963bae8fc6f0b1d7b4540a97223eeb6885b6e44ede72110944804d6d912cba6cfc32aa86d18692b0486dcd53474415d30df93a620023b54f96ad428fb55dc11712562f0fe871f13d940787aa2edd3d85ab6549fd0485d89ae048a22f3c2f7b54c6332473f40d9bee8af49263ad57dc73193a5ab30f6a05055d42364d8421a9cccd866cb64ff7c3689b703a4c40008e38c0454b3b8bb617ec96d0f714c9a60ddae6117bd2c281112db76b27bd1ef34374f13512525705f2a4803b29d791739bc0d76f9330cfbc82e094b01fdeec9b75111402ebcb23e04481460a0f546c56de112e1fe2bbc8da8543d1193db50ef82124ef95f078d6eb8972c4ddc9c67b805553cb6f6030ff3b994a6f7ac7b23a7314c5c930b780b15e6037424618acf801d5795b74d53dc18633c67a9042646ce934c3e1f250712ff87b49e21094a818409ded6090a186d82cac6054441989b79a9c33b069eaba21bc6c3390c219642c5cecb97df5744bd1038a2618256112fe8ae4e15a7e5200abf05012896eda842aac38a8ef021567d4fe3e20eda1803bb7a6d6a607135f4f81a8e130035bfc3e12d71f07d5893f9fe46659e0c95099f1977a4c7dcdf19569a4420eb9f6e8c170b870a16a39e5f212bd303731267723b9ffa866532233a0cebe5af371fa0335ac1e4edaf91fb07c05b92fde858c66a245aa264d91a591e184e9ab311a6a16aa44f8e78930db4ebd5b214cb14fa0ad03fe6b5fcec2a6f25de2ce76fdb70f3551209eaa1f0453bb9e0fb566316f1286b1aa5895d6e916736c57bcd5d2762a054a22f78497e54e96d9a2bcea4b4d7d93214fa46a53b0e23532b17466f4c9f155c79ec16776881004f7c082f547ee0eed8e37c669cee9e5e6dd3d37c089b3d68350c9fce008027bb8023919099378d655dd86dd1025b91fd9f446cacfd1c426e54f2a5117483ff769f4c17f5e57b9a6eb009a8d49c6d7ebab154a29ae8382c054c19e91df4d2f6aaf8665049165237a971ac9b69c210e5ac564d8da1d733c98dcfe9280907e90b6ee5e20143e3872f883c4dd9f1b55ad113a2e0056b6193306803fcc8b93f3e91583a8873bd0bff4b774af124486862fa84ddda3817438b8e3ae0acaae5582d44af49e888d1d5f954c6ea4c28bc22b740aef1598a06a7cf7429a5d23b63d59e0327762dad5cdeab1464c5ef7faa2a10087f7f3e2c67713b28fd0adb5687445645d07011aa1616815506aa5f04b98255897fdcbdc05e56279bc8c1190a66f6f038d62536594474fca0f2e553aec4c3bf5c4a3efe78151ddf1bdb502bb53e1adaa83925f29e68fac3c1b6369d6ed6c82dced295f111536b7b34ddd24c82fa07da056cbb79029947a1531701698abf9d8258afa23a9d6ef4302801e38e76df0431876e83802ec2f94ddd7561ffc1e308446aa48c4b1de52de3a66164f21db53c60aa3b9532e5d67e02b02a2297f32908ee842a84beb5c80787660dab1b00c5723620e6f5fe73f893449dcb9f95bc367a4a70f0263ae8e5dd57529efe357754b1c078ef59ee6db61158ad83f8783f0a97ca5ac1cde1f036157f1970fabc5ef51294161b42643937de8c8674b7438bf378c15470cbf6453e576d3932915c9a95f081b0ed80d2aed32d50ed03861519981b0ab505daa9b5f38264991c1fb2c7d0497f9a1721f45dff67527dda1195e480517876dc5b63669326881107c3a98b1b699ad14c02ab70fb133c5d482369ff73a94910566deb2c5af895513dde8b656f31447b2de9e686f0cfb96780d3ae06dea1223fcdaea2902570b4e64bbe32aa095ec9d77bff31be101498b19266608a53a6df12019dc7be35e3faa17a2d9723e2f4102dd5586dccb35c234e7f5116e441df5622730f7c9ca669af4d5076280e7c70bb621d5d39f0b39dfb8b4ac7be6b9caae64cea4e936c7da760202b770bb84766290870c61ac78a22054d4f8c05c644fde2bae18c853e80e1232c5fb172c8473fc41c5d91c241e9dd2386b52ca856181571cba3b71578c0c94733750312f315098aa14e78a995a64d3b6635178d7e9384e304885c8a55d815991171b2f9dba5cb9a51341e1c36e896e58cc981b383bcc1e5b3504dfd062a971c7519ff11c8517cb7fc2e9b43a9aacea440ec5790034b73d31c7a778eafb51d624a0985d940ba8e7e32a572e2777e53c6864efc46e29394c61f7cd74a7d634c95380f425ea477b469a89d664bb444c18802cc1e30f1a1e30c321d1a612794751ed9b381752f6443d73997d12c1067089d3a3db781dbcb60422d5f28f3f4e9160f5f6b0ca115b27c10247320bf34cdd78dbe4dbf341885a05c27e44b0cbf426a5394521475eacc20fd503ce90264f24ce74fa9abca48e35714885bb02c0c06e0fc8c0b2d72c5c5a12a96f5e0196453e4948bce830b19b6f810e6ffde1fdf8b65c8f0316fb609784be80523c511e3e297f66bdc5b47d5ce8b1567f80e98c917b7e25a92196ee59bab9f0ca4a933b24f06a95929c1f2fb19ecb06e8534adb4254d28072631a0a5d4af9d8a949358367ad85f3bf2c4743aacb3a64e1756a827e5779817db72f4aa9e8f332deaab61b489071e8ddcdfe8ecc645d432676e7c3f1ee087f1448c961d8101c18af10c37490fbd053ffc9344021ca1a5350ed8dd765ea04590fae794b8a726b3a144bf5ff5e4844c464f348772547c3d94547ec1bb1f119032cb506e3020eb68dadb86864e4a3a78ed680a5d96bf955f261db07022c443608b7c544bbb886b3510d65f5d5742ff38a6c052442ef7d1052cba05ab1febcd8c1538ecd99569c626cc22dde15e320060382cf7fa73533d0ec566b591daa3034d016efbabb8914fb81daac526dfa4415cc7e7f35183666cd41130ad271ac6ec5f44e3c06546d19f2bce22cdb2b409aac568ecb3988450d160de27dd7df13af4b3c1618ed02ca6c2f29950aa0b08d11d7763c95be84ebddb82744702f8fdc002c2a7793e39b649f5d6bf28a3c64fd1e0408fdc35aa57386d0374ca0ccffb1217eba4aa03ec86fe955b9a85aa63de71ce19804f00bfbf0ca394c0ed0b1e6f138d752138080f1642357dd04f5b9907c75deb4a342bf530b19925c898edfd11279792c38be2af16c423f3cb5c08d98902006f0a900fafcd655baf6c2c14e1f9671c39076abc4e083cba26aecd553835edc7eeba165b82d1ce9cfa16b459436b630b2b027b11e86deccc7751dd2aa8f81a0a48e5b860a6cd38753516d6dbc7de81f2eecb6e5e7c0e44e25c4a47ff790308439c5ff6186f4a34291d7eb98460ea7453f01b97b0207373e3d20bdd2261478401182e4f81c564984a632ec2ea4a1e43a4a8a81e75df184693747c6a393b9d8d6b079989914e3ce508b41b17c938c807ef74240e543b7af08777e756f14463b30c430f79728c5c725233b29e7398c4cf6cd6f50193058d7fd9d5b1fcf7ed216938bab959c2ee17a612429f3077177644c0ca9310fbc1efb950f30a33b447711158b47172227541c71e4c43b7bb1beeac486ad0791019ffa9d2eb9d2a85b0394feee14f1993afa101f7d35db06e441a765d55e6d2eaaf3052302e3359347b1b9794d87ff07d7dd8fdc1f32db3a25ef258ecf45f442699400f570f1bb493c9983efb681669b887b3b0c53664811e6bd478e2f2db750d585a2b06dccac8ac9ec115b1dd8a5a545213364151fe813935fe208a338677bd6f5661486d24e0bd00f9726f6f3370bbc367c2f5f37a89b21cd8c75f23fed772dec198190837f524aa688ec56290e6080f407e8c2d9733f07792aac1b5a116f2c1986c7dbb6beb0bcb79e1d2c87857ce06be9cdd338556c8e270b61142e805aedc1e6dad81ddfd694259daa874948e6b4c0e8ded3fbac7dc7ab7f8e3c1e05d17569314533c09622c7819444d010fb4ef970c310bb0d39af0c9c8f71bd9734b49f9465c6d13a0df3a415c7447b1ed51db8227f4593cc271ecc1d331a2b43f3ae793bdb3625575081cf446b1690ea4966c3e746f9e1b519d65b9372f19499c74a467934d680cfa9a070228a457306671d378b8355ec5092d9f09acd66ebb11965ca918919bcbeed86f34d324177368d10f0f21d6717628cd83d02a9267e7f5e0f0b3d3680d81c286fe8dab1b245d628b84d8cc78c5b52ab82c94b31830968e72893820f742e8914a06925f6f578de89dace662e91257274637588764a2ce7452e3affcda4823fa2b5fa59ebe9b15cd411085a44e00b44977dbea1485a5fac6b516c7b76b570b6a0eb723193614e3c601f9ee44e7ff690488c01ed8a1fa551728b713e14ed93a720c49465af2315febe9bd1450990b94e49cbfa6988823783e20b071535dbdf691550cd32370b333b0d6f1565b6d5a16d4f7daf1b0262ee87dbcd04ce34d831e6bc4a402bb563f68ee6eeae0350ddafd3527a9e074d4f497ba1c6de21080098e61332fa7242026ba3521ba24585ea944bd26c6ca8264a9d93cd505e2e42e2e84aa6d563cecaa900f56d7be6ef4055132934e9b6abea7d14359ad9f6776e553c1613de517f3700d281713672678d046f0d7f01a4731baae189fec3ea406234662ca6d48256f8ea9e573c995eb00414931e5a9a581cfbc71700489598f4c9be4105743ff37310463ee453f125328d8783fd70673e05a44f5783ad6d930076f961e6ac46983f6b01220b01b54fccc1099f0143fcfad89215c74352ce0e6179edfcb89dacae554710e1ecfa78c1010bd5306993fd68882cce0d1faed98b6796c31cd37d2b5b81a3c23267e6e92e36d404b0de6c4f14af605cb63c0c35349cd772fecc4312b6c4c9ca8421f40776e4eee50269a5d9c4f330c0f6b3eb41ee88e32ec39e95fe25b389174e03c09664d1c37e855810b4fe70961858513904653309ebba3255de8893e4934519f761aae1a96196762b3c3daf3ec22277f134c9ca1ff27f335327d4817ed38ba098a0150f8aff1485b702d62c1901d71a75ca1f558bb7f1eed45ab0da5face80376a8e50aadd81bb1bf77b2c2da76f3361194948888588a0f0331a6899424ed8a5a73e471c726c7c1f7145545a5d83077371b752ecd5a3b0d041c5539f6228ee73cf3c63e4d2758dcae7e74d637f31508dddad3010c8574a3fe52b357a176dd79d4cf8c7abaa35c287fa77f6b1695e0d1342dad3e44b06d1248a3cfa03ee51c2a4da5a940cf2a61c2937ccf92b75a85d5e29f75036ff2d70a12edc51794d9deb84506de1bf000f04e7a489b31e45e8ba87908f2bd5d2fde71ce724d1dec510d9c7317e175f215cba4304461b8b944661bbcc183b88440d3e710ba2a9f346e42acc90d2f43a798dc8b0de496ef8227a0dfbff161ce9d3b393f2c2ba4580da5e44d24c6a9b634054361cec844a2d86424f664a8e739ee49fb54e4ab2a8999834054dff3119912cd5b551844006b7567a59bc3cd65a83127d7e6557597ae621be811df1793e09df180d88c2547dcf952b837b2f69c4bad19aba6d4a7e8d366e78bc836ba74220df7e1cbfa41551f3125fc59b58b2e73bda19c574b7a43693c01c7d94e1d1e9e48f354cf7d33dda67a4341f482e39df1da4dfba56a7ab84f4a7b121bcdfa7cd5178a0f23ad3f52051afbb2a6fef1a0257b9a06fd268961cbb72c647571d339cacd42de2bc91d963d933ce34d445e22e02911ec32d64d160b3b3e0801bd36c6a2e192746b152a181f6b1083b3135f20267aa9012d3f4bb6ac329f80507d81ca3eb4b9d1e708e4aebbf0aea53dac897ca04c797a302336d0274e08946cdfa30c77e76cf779ac5cb23c07317b47aed294918f237caf36081c32ce3dfcbf2a6550be6561fc9f944e7778d33c821e47afaf58e4949c4fa1c8102a7abedfd6244073b010b300c283e4f38aa211083dfbf01a2a8e375b0dd00a4a63cee98a232d35b6ce1448f61350af1451be583a808d507afe58ff197fb2fc5840d661d078f79836fd0106571e29c712016bc5d01969c37948bbb528a270c9716e0f02aff79b7fdb087047f8ee530df10d256cd3b10b02c572838662e90ae1238da60aec56468d445766eafa43332de760eb9eb77ce4bf8c08b1ccf14da9ab1ee5586c644650ff4e800e9079cee7baf40762a62a220281da1232c36e3de57c785d461a76f41f2cddfe50bc086b7ef5eae16f3a294f45e200125c6271b8fa7b7225bb554b68168b881ee941a582baaa5bb304d380985b63b4a044d46dc85ce8b20cbfe98e2369db54b800b3c275dc2149c20b507f7b6d6d10a39446e36799221e50f939657f90a0d9b1d3c0bf38c23620f54675f4693a1e7a9f71001dcae5019e055b5595a77b4ab80845fb95cfdba604e6239e4f5583ffbbe4896e8ef2ccf2105f708ab418dcc776dfc60fffe2ab8bd0dae712f10ecf448d7dc5a2fd876a3282fe68f374d314f887211fdb588d86a7f0aaad0a01814da66d59f4f003d15a509bd4cd9faf5cfc7eec668ae7e7e189e40a738f5c6e991c6449a120a30fcf751b1f8f9d58950a0d6322c4e175680af562620bdfc9b66bbe3f071b01967141c314d2a8ac88f6e219f91d6b71cc6de68531b2e1745a98d85fbedae7a68dfa740e7f444eaeb327a4fe848a01ba92e12160a69479b850ff3c620c38cf9bd693c85431654caa9c992fe5db1112678a8f69836a18cd5bd6598bdca678c0c62c2432a1a85db8d53cc72b92804b451fe185354eaf7a760d6cd04f138f9ba205e9e6ff58a4903de2ea021b24fc1ce19b8d906fd6804d888b4da04d93cc4e430c4948c8c13e5f5c008b08b177296480ed6fb566ea1dee38b648e4ca6131c74835e833f4ca49bd5530f95d826013f5d63890061bb40c73d21f37ba522cfef76ffb819effae6f42203961a49cd6899d3e3745a7f5e3eb41eaa6373068109a85f85cab0012ce211854c7d9329bb32a31409e4d90d175ba79c8fc42c3dfa71f666de995ec2b02bc6f94ea114868845f847591624d82a8b1a9d22acc5a6ae65126143e16b0b376103e5116885c209147e15c7a9e19ba137958b8a34062fa9ce7647e9dd569003cc12fb464e64af719b2b6a73ed5a0de4d4cbf20f30276527746cac59b1dc731fb47a6ff98f82255cd3dce2cb6fb4b008f245de9ba218e64b0a081dba5db1f01a801c2cca75b99e0277b8c238cb46a0d254bc6ce342abf7309ff39ab9784238e1e8f37a58975a21eff408cee6f46fc187b7b3c0ac220723c7c766215fed0a1e8126374dab17011b09b8c3b0c80efba3110e4df826eee1b4b800dd11bce713b9bc0cd6b77e8b6430d86a31f77a1e5ea222cf0dc57bffc2e8bb7fa330a1f896673d0117002397b44885936b0704a3fefe96816458db592f5f876ff0bf92e0c1b829f209c9fe330af78cf411061abbca9f0e580a0a454d68a95d5be8bae341e3187eec29d39429147821f342c2ca67893f014ef309ba47e77c4da97d3fa66b2b412bf5082152499900f714a94d98edb7d86cd3c64ababf30a41883a08a281c2e6b73ede38f9131afa0d7273157a3bd20e601cd2c44298061a167905980affc28745b8d7c133864cab5d5cfbee7ce3cacb80f1a009830449fb71c5a06f2369f906faa0a2405f37b42ba6ec851c143040eab35f52dd711611bddb2e753a392b1f28d9d9633f0e88df79af2fcaa045a652bed715161ba7213ca15c87a862c4862cbc558aaae6cdb23bfb4f24650951011c2f413e03fa4b0151bf6f28c4756d901a539db0fe24e43646bc315524c3832992a95a1f4a828938712564a920dcace5657f4fb1880393d138dbceff73b05d06c5bcc451e85efbb640416e899d080a9decc5ddd71cc67a9910a2b7b21fb9656d6e763107d1c6a3d5c87180f4a0c981ebf4e8d41c99db2c4d829ebeab9e51a494af3cd9d3281e94d37b3a777013353da8d8bffe0fffe7df70ff10fb8c38f5fdeb25b52ebc5bfcc66fff9f82e471ed157b780b69242915e458db4b50d17a8e6944ef71dcf7f78af0caed0e1500ba1c78acf3a13b2307da5fe6f8215f98c13a9520cf5d076813d5471e5dc694cd143905f6abe09aac45966eb58034f3554fcb2c4adf53aef6b319944cd3a5354ebcce66b54cbb6e774bc2dd0ca54af9de83f105d565c976dba1d112110736a1f8fdbc2b26e4e72494d454642156f0b261eca4de46a6fcc934a7f9870c75e418ebc40b776fae4bc72c1ce4cef7fb6c987e93935de52de7a0a01edf7349638762d2f6b9924d988d17f61673cd92c74eda6176bab7bdde2640286471289bc85766ca3a83ebf2615c47fad375405b1064a3a7240554e3ab4aecf4a998d330b52c5d9d93e7ed6f686250674b98281d57df580df26a5f8026a0b5637882c218a2d4c57077431cf715fb1153d2a8b2cc64fcf5013d8bcb13a3f6f338adcd1fb0633cea491129346213c358aa2c26b854379135d603cd612252fa67a101e1787a597a6fc9c5dae52176cf5228285126b79e8d91c1c6c2a3c21fdb9da2c28b89aaabde1b10bb2a8eb587466b4eeca45848ef898d491f65263ab75a1501f19426e892e82f8366cec298ca1b0d776e6e06e5d5f059bf6142808efc17ed278311040cac6a972cf90aced4cf57d747812d85e1fb68a7b80b2dbc2e95d8626500728d7462e15629667ea0e5128fa4383bc76d76508653c2c45c632422a2bd3be6f3f44cdb87ab27a1ebe8259b7f18e40a6a1c5994dd1d367d5b27d09a21a37aff1046535f706c9b85f56df8d4115c4e9a26f6a0f68dac197430ae5b82b12f0dcb4a65b7e5262d28e221f45933db416b0c841c1b854b67a457457591cb9d60d6a50ed6279795a7d33215973acfcbcf196edb84151fd61c77ac0dd311439e79918558d7634578b63d63b0a7507536d64b38c7bdedec8950c64f1b5bb3a3e318259a268e3f4acb1ef5c83e1c009d49063ba162b60f6fee4d493605362587faddc7066a0065b5819032c18688285960793fda720bc6a2ec8dfa626de2e7ed997c6659d73d89c9d79b7dfae8e3529f56c986ad0915c20fe0bce4b99fef86a2bf0535ecfeaac1d3506d3b8a05e1c8ee1dd7dfae1353469dada898fd184b77ab6df6100a87a752f4b5cc39fbedac57db5b3a0cd0a90e4d661830b4ad6607af763f441f96a04014c398c37c22e451dbd95bcffef6e146d724fea9256974a083812928395508fcf085188368dff13852039440af6b4b05d71808c768a073ad7b3749498ed811c6aa9a37961867a40c13075818d3cda0fa0547972f1fdf7aa2958c38a3eda02aed0f2db7a8358d83a75b2adecd81f2859983a5b2c0eb75b1cf6b81e53a4bd0fe9b2e3b40821ea519e43b43f84455dcc08d7df7bb3554028251c5971dce8e38c2495b95d3c11209fb13dcc1e0f518ab2326b78fd3bb7567f24ae4caba71c42466ed9cfd65b8494079caeff491d9c65ead745bbee7e1e28361f9777a9fe81a94571397edb4229815093c1e83c87d6adbfc6eafc1eb6f1d53e71ab571f25112e752c2c030437ef668eef1158b728c18b815bacc35dc8b49dd4970a4d1794555918c15422c3b2f700635f0a4365084fc7b08ee57e31af85349b5406177bb4d2fb58653a58223d6f7609957a5b5faafa9d979897ad2d6f23c39a2f765b736641501199a83c29b6274b31215d5740b7eb0054cd463067fd873af9d152a8f0346144e87cdf97f0e9ab71f1b53395d53fd6067d5814cbab2c9b70180dca4466d7885ea275c2739377fdc1892ad4c9b1bd9b9ac42aa8a585115a9c7e0c3a52d39f8d6e9fb88621b50582dc381c36b3d07533994dd82e92dfb6ad158a8389f7954658b4e20c398372151ca0259184a4b49f23029c5676587ea0f0c30a0165d7816a35271a5c2434d52d7f4366dd86095a314b0c6358d5009d8223d7c3958c57ba843d543fbfe79a863d22e3d3a22ac1ac33af2a6d3d01fc06d2f3ec7bd0f2c26f6361bc857548c74805fb06286d068e9fb5a2c85231bb367eff9a7b9919f18e4001a4b23686bad74497afd7bd2cc70cec4d1465f3b2a8f13bdcdbfb97696d0217580c48f619d3409d1b43a105856fe77ea9644ac7dcfbd894031ab687485a3a072a0e54ba3486f9f31d90f1230fab70b6359423f8872f1ff2bd404cac42a035a36436157ca8a1d124e5d2ae6a31aca68b37200a5c39a8f528acacd00ec5e88d2c10596d439880dba494eea0a42611cacbf11708580eabf9e80e00dde4c920a8a11d468f85c1ce75e531099afd072dad02227b73fbbe1e19ae348d0798650df9a2f5def57a349cb6bad075b6ccf7f8ef2669b0627fe3404663d26dc74932d8c3b4460ede3a804bb9c13aed7490b4ea18befcbcbe721e5f72f8589cc98a9c354e28cd460efd39c8dd71bee22331b0fc1f694fa2616331860f039830ea23d4df28e0281903f142e4c48c4ff2f98cce22bc0b816cfd25c07da36adb2fbee66647b72a16f8ec4386c04944947d90c46ed4e370f0babd56cf20210e6aed309ace582a1e3226a6c5ba472f6bd0dcbb36e6ab48b0156bda8e1819c7383bdcccc00ab8dd8ed214bc153af6b5c39d6d353d9008ecd70e04043480f26dfeb3c062b087ff1c90454fca170fd2576884a3831ddaca9b3969605c809b7dbd7f008b7f42215225e7ad25d7662d4923dd9a2fc9052c436491ef114228e1ab5ac25e2dc95ce808caf96e4d8e2091d4abbbcc365dcc4498fd5e3b8b3c16a7a2aaebd1045fb2b28f152b9814496d083d10c3af099dc5ce2acdc99d32a02c278472afa529a0672d9c4cd240b67b928060c346361afa934ce445d0ccc9bf38e432aa94a67071d57b7758804e791db587b0558539f058d41c35d21eed402ad644b9217f814ddf01f61887d29ceb902015373b044bb9f9b95c9b8c94ce7275dfbd45e1ea6b2db2cfbdf01b7bb5097c45b405938768dc2081b23ceab0d870bc0a5c701949b0ba7ae883d6b34a10cb03ddb3a7b52cff60a40a3c803401cf03beb8dec881b5148669b7ada8ea1d7f48aac3e4cf0b850ad09771798b988570b664577bd5364ad6a889159ead9dbb8e1009e1fe8581d1fc736eb481770774b9619b359af07c526f2d8c9e7229407cdfa097c7ceb5140329bfdccb62b807a17e5f98bb02fc47ce1111f4a3517ee60afeb1b196c9b9e662d0c3531f62e6119ceed1b975195ef2e82bc3e08ea2e22331e2fe7a95c27037787ddde0026abffa0a994cf8d667e1ef4a569c416a6105b1832d079ef588166927665995732379ee4e2e8b9d5a096bc526094e4eabbe0720506ea3cdbf5c605e1d667a964dd126fc5c6b341006b6a4e084b4d2268b2255c29de82c6118a5b53ac80fdf9d730c62930970508a9c770e836f757d83f5ce94fd93f1cf3fe8d46b7e2048534b6b1c38ee54805297b9d3840091829d04619ae3337982adeaa16a4f5b35f6c4980c456dba3d1be2e722900a236c2941c2b81c52b23ef4071b29461a72867f486872e8df2e92931b6995473d1c129028ddcf4dda0b51ad69a3567b01789186e995b3734307cf2866355740f403ecf76d2c91e719e31f38dda83d70337d8320f51bbccc924add1ca542f72b186844624848b82c9e4d9e1e5ce04a574c70ac97904974f0046138b83e25e8a881a7ad3d5a0a1a0ff1425833d880d77aecec124a151083574aefa7adf526a233727f6d5477a3a7575325055c09685711e522c89101c7c93441881d6df6c54b5afbfe8782d666eb30d589dc6a5a7a2e141140f9ad85f698099024a254fec6a8d69c1e3d579cc609c9a4b18385df96c30ab24c537bdcde84c53b4a81fbea0a8d28566cbd713b0d995dd9e02f9a172a8819f6d8f29e5ca5a89d184473a01d89b3ed227318ec4f0b1db7b339800c808dff378e56f472cc6f3d449cc05818351de3adb2d8a61a0ea4953a6aa85b8360cc362e42baf22f19b3865e12bf34173a6e90ff731dc304a5a5077dee45d478c4a1ac71f0b5fd8c2da1b5ff96c4e2a022a48808d2fa299361cba78ab8e4caf82004346eb75202226316e374d09ee8e8198f8fa9924a53470fe8fec6dfb777de6621f525bbf065b92dc563183d2defcb8de8d31318ba22e7db9ee6964911f39dd8d9050d5a84d73954f5a7d09e6b7a0255b41dd08a5329216a9c161303aac57bf4798d5798e5637a0cb628700d324e520f777a762172404d0934d6408492ec64fcc60f8cacda0b990fe110039c3f91d3b932c2be3db0330fcd5cc57f58a85fc154445bc4c31ccd105fa0f9f1e0cbc01c0ee280f016318b48525b3584cb0d72ec2a1e98b59adffb3ea23da9db3aa3e0678cb41fcccb0ec83440cb15a3b2cf8bdc7b115de0e5592afd5164618c906d34d554a6ca838b9ead02f083e352a4236eeb66e7686fe7e808ed8ae49550f0599c1e2c4ce4449536546a3ce06499cb5a2e4177e56606ee5139c9d0cc129feea2782c7cd1cfd0b184654a7dbb1d3193bc3084447ad2c98aeb1ade7af74d11edb835d34aaa91a647d2293cb5c276005e51fba1e1ada9c8575e86963bb8a85cda470678cca3a14a13ab0e243025333bf94a195209126fc8e396fe185fa73cb1de543b42d1f1412e8a04108cfb2187e0034104fe48aa7680a116f83ada520c30b98c0d9e6947aef25d4c7b590ba29b56a4ae3ccddda5dd069020fe02496f9429d2dab48d4d00ea6974213950bad38b0626daadb74fe0c728e534a9f1a46a13c66f6c53b0a640acd643b35adc36a6ca7f20a11a8a50113879c8340ab16bd0b09b47eea5e41778575abd974f156ba89d15f723afa3b0b67061ff9cad252dd59ed653a79368a84f2c01a05a3c90205ff4dc06b39df5322dccd9f721ab2d59c2ccf112e84711600bfb2f8b0c6076722f4f95c29cb9fca7facb4ddf16623982741ab1c89356ce38db799353721b4b77bdc08240bbc7f007d35ac60ea3a13c548a95b1bbfbd05e7e1f607ffef1e7b4c2daea76530839aea4b26db57e28ee29884f5c114e98dc7eeb82944dcc857d4c0f3f41ee2cbd1d491e91bf821a0420c247df2071f5918c340fc5df33b7bec1c4252ed7e93dd64fc6c5a66a421b6b34a25d76e2327f5fed7f02c73418d97497e5d0d290bd75c112826f0d9b8cffdd8cf5a8b3650d1ae1dce723f3954904e2c5b6563902a33e3573be88d2548f6051338cba4f0644cb33cf03f28b66a67ef38194dfabe1ad265e7fe7e452e1081903f46bc0d53f18c9185cb39da0e3047eea1b136ad521a0ebe007d2b563ddfa5143fc7247d04714de6708a77705b608362181e7c211dfdd00892fb92d7279444c6b981c28f3b4004aa3aceb47fc0bd1e21ac51ae1de6f9d93a2e9d62b3e529ab9fe0cdf46668baa6b4c56bf27aee52f451cb5966940b36604db76c1c05a01d11ea915652315543276cbc1a1deb3fe725e9be39add97f761f769f344f150ba40c2203a08b6c85a5615f6c93c0d2f331db8219e5c5fda5a3aad8d604c18acd999adaf35ce8772a2e007ae9ba714697d7493ce054141cda9c4760bd7c9f62b9a8a900f463465156590f10e08095414db5e993504ab279b251dc1e773dce845f6e29ce94bb5dd439bcc9f4485827cdd424a6982a2245fb836348cf83cf4327289006ead8db953e8bfd9ebf659dc8816263d28697fca0597813ee75996d4664d6d8b315a1852a7fa5593305d0b51df2c0bff083d69a354861eb1a7e977b37caa23b9983ced6344600478af5f78c2ad032cbb39607e6edcc9ba1b166eb761c122638d232c484c35be9065ad8c5646a2dd4e9bd3163768286d40535f8c8ebb5227477533dd7ca747abef58f8608eb91b0c97380855e9face3d158e64c4cbbae50e30af60265261631b71c8d77159af13e7d0f4fabbf05f18c4acd8bbf462dc3ba5c2b927d202f051662100ea6b4eb3a79baaa37c59483125ef25690fb069146017b6045b8e56f8dfe03de060c2b12694c25e42ae0a6bd4a9eab53690e3e371d7d00395f41e2e2a0f955dd66f1f3c5a6de648bb18e6c1d96268cf8273c4a74b6d41fa7ac63bec94ef0d5ddc3407276f9a9b1029da9d95cf3cbcda2e25bcc225635bb2c39a7ec5780aebd5f24602f30485cdb6c673b3d662c3a3ed753dc89c5903cdf665f2136cc63ff41800213fdb15557711cbe673a454dd0da9acdf7ba1684183739bfc7fe9b10177bf61e33bd4046a8b99c47335a2817ecb41756f71af86b3a89074f48359840d3f622fd1ca34cad3817a346f740922a12ee254fb50b1eecd0bd86402e7b1c94ac1f286672246ca21f5d770f613152d9644ca869eaa7011e81a6f6cbcd972d1c46624e44227d64dcf5b6681c1fa68b3108ec01f7c7ad66109b5cb3800a2bec089564e9c8b5f3e3ab71c412b7f566f67a12cefa355d7252751d060c79af395c7f6b7e21a3454df2e9df18d0fd65366c9a4a71d4f07dc0f09c182a22d3feb834d219619082fa58f43e0e95f2fd266c3ea79fe6c1ef8ad861940e390dd9c6552871ee41f0ed32e04e34ad25680772dc134cb485e2fb5984e37c1d2ef443c8f469eb3876d1ce931048fa4626204c2878c5d2b6077cf704ba4a33af5710380c398d01da6dbee7c35e28b45668880c54781993279635566a0c64d5390668e68f9703b9bbfd7f6fb7d8b27ba2428dc8b626ebca46603d21780f9cf688c0e926e4417e2c45c1b5718b3d44dd22a0eb9f7cd1f82805db0ae00a100bd96c0a1ab1f809057d49ec1226e068d26ed23e6f3110b4356d1b7318ee7498dc5f887141358d57c81bb43b8b77a7c3e5be3b8c0bb23b9d2aac8918a65fe1f884c5d9dde96432996c478aa1ce8538c451f8b537a6d14e9813b9ff4e2061408c3739090106fb720d777338fbedcc234e42d8fb082e75d9490830980df107343bfaf6ec9a37ac12f4edd50621ace51b88cb5ab64241166ff126d90f5cc2e404c133cadcf706825b8ba335ef0641a12010df704d6fbcb16dc4b65b62282c0e595adeb44cea28770924211625876f664d0f99a7b6daa675ba65bfa1315fd14db531bbc6d27e2afb912068773321a01b64edb7b17992e2dd63b647aef189651bf32d4914af91d1d1a85f264dc75c3ab6438c5f38775f344cc26cc0a14688ff4f98e1b6efed15260902409949dc2462492c2571948492248692509dd456e88320bb12fac05ad50776456aabfac00659d5b65bb2e050d32660c6044860574241a42ecd11cb6e698e7925d3255e4136ea51674a0089286a5243c920025ed2f8ff741a0120ff21800604648040d47fd96ae8b66f155d62146898845dd1c5ca1209c7841413c58c0b474c1e31e497809a07fcbfe1cedc591cdab63b93d106e810d3eca0e9020d16ffd19880260a9a28bf5dfdc7e5b971dee97449caa89c1a31e494c918f0863240c780290c48ed306e0153dcae68a70b085f041a45dc5044ec76558435d382db95192fbf992187808c0825227c1c8b327408f2b7ab219c5c36c48edfae8498e27625c418bba242dc84b0761504167655c6ae82b8d9551044bf5d05f1dbd5147655c6ae2810a45d0171248a9706c48e3258fc7655862c73e3ff0f657e20fa7dd000f58106bb8afd76e5c390dfae28192e7ebb22a3c6aec888324a06c86f5763d07c4c943137ecaac4b85247c9c44c71bb12a38318d0aec404d9d5ee8189ff3d18c0aec2d31e866c1a860bbb0ae3254c951ca6fe76850308055305cc0fffb71e4fb29593cad1610599afa08208fe6f39fdd2e4bf94d32f0af83f9a7ed9d52e3f1a0ef5984bb386172fa8e18254d3ff264cee92eb050f257c09137bcbf2daf176e04190474611f7c8b8e11e193a0d7efc70fdc70f22ffe1bdf90fcf02ffe115f11f9e0cffe18dffe18df01fde8ffff0729200d9113c9d51e7fed420921a6387713223a9a53fa57483a729d401f85356fe5400d0e8d014855f3fe850f1ec8a12340726be47f97340c0d2e2a239001167b33cea4c8143153f064e71b8316af1bb7fcaf5a7aad45d78db211ea3987088b1fc292a7f2a29e986316478e3e635ce7e9c918e8c76e4ecd83002ac04a75a7f8ad5a4c60c36887615ae6ca0355051c39f8aa283e3600a00489012054a6a95aac126f5e44d026ef8d0d09093ff3752236851854a458303681882061d6ead2e5ccd424b83ee76b57358c4393fe4f850c5be95b63bfb67bfa42673aad0196c7f99cb2d199ae168e48d82895a3721a00c5ad3cdbcbabb74497d1bf39239e6a56f97ba2c7516718e456b52c238e963d92de0167093a7893ff234f1ae0de1515b96c538a949e9bb3793a8c86e27fb91376a7f6059f623456dc3dbbca5cee2ec665d1b5d609416712b74dda651bf6ee6256f14acd449bac428e812a3106273cc4be2c523938e8ae54e13e7a39149d4bae966cb55b48e99279359c34a4e3a2a26def1de627b63253c32ed7c9b420c430260c822ea027071e21243618b4b201c85bbdf962c5bc01067b133abda625e6b75cbb64adca463fb9648babba48d6eb36b37d644e0be5bc0d3d6f4988fd46e475ed0e2850eac54d6ea9c179898be40b473d661ab13139ff853227ccc3743797122025ecc985b93f8b6c90584e3a9a1ec8d452f55bcb0565dbce892822e16e872849562552a2bc5ca540bb8b88aa95f210ec733c9d42f6c66dcffdaa900b0b08d59080efe3fc1a70230dae537b43539dad5cdcc5146f2572bea0204feeff2db4b77576a0c04b4b4b138bbe6d62f5d33c2ff91feb3c00521fc4fa59a809162925af2e75d62dc98952cbe9958a0466c026b69b512a1e8b4515ac4356de2c08103078e1caa7d6e2c4e961445e951e6644951941e45f1d2968817ef7daaf4ffa253138cdf051676f9ad56d43cba1b8c9d823d825dc57642bc2bd55578f3a78a5244df62aedd122956aa80962328ad283bf09f85471d855fb631d3ca270ca3a5d2632a2cc05215cccb363906e9261bc0ae76f98d00251b2273500dc617b7356d95aec4acb561025e0c20cc0912e0e50408b0410705547bf9d0d64affa7998c4dec92e6b0a0390d3cc704b95b2442895a5759ad68b9fcca1c6e09ee039c8f5b6bb726edcac4dbcec232971ba229d0f003fd3904f873fb46ad5629a4726e5f9b23009ac13ca524f53d778af8ac596d5a4b9e5040188b8ddeb8387333274b3ea2a15938847369d22523a74b3ea74b39a74a659c2ab1e0542905a74a5bf8e0c1f3414ece8f019cfe50e1f407edf407ecf407d2e98f26a73f3c38fdf1e3f4c78d532f8c53af8b536f04a71e15a75e14a71e054ebd254e3d089c7a0e38f58c38f58af0f1d18347ddc06955e2b416715ac99c56059cd6194eab97d3ca02dda1a3a2705a934eab92d36a4fab8f531a83536a82539ac529fdc0297de29436714a8f38a5654e290fa7d400a7f48553ba4fe9ec94c64ea9d2299d724a99d49e203772f0e0f1a13ff4f427e7d40706a73e704e7db038f5f1c0a94f13a73e479cfaa439f529e2d4c787539f1d4e7d12e0e3e5d4e73cf5114f7d68a73e5a4e7d603f3a6ce0c0816307045bf8687133c54f9c27ee438c383eb29045d0b8610c20378010a18117ae2ffe5f87e7a6a10f444c683845843fb5c3474f8f1e3b78ece0b9c18303870e1c3772f0dcc07183c7c64e2a5523a593ca493d4e1c10cc31b933a3f04865200f19ca850a705b5164e5308334809c727139f9bfb9d4ffa01d630b16e0160794f9bfc5062f20686de316da96d86f557695c343cb9ba8d2c9f7e4231a1a33b96b77ab7689c38b4b2935d0c8b9404e123951e480e01bfc3953d02c41d771fd2f4f5118e266e6f22ad9a4c631e63f798a8207bbdc8947f6fe3564f0d738e3af61468d32d4fc70f35fc9e9092bfcc733d96e5313aea02658e0bf35afb58d1900fa62396272392135c990a8b09c986230594ce989958474b45a91b866b7ad34f5eb9af72846ee6225cef4ca0f57be5cb90127619c84cdddeccaec22e8ee92a87553899b725bd4baa96534e65c4e05df45f4a9fedfe1c6312f4c6249fea21dc6c1d0c01be732975bad5a31200376e47b89d18da649243cbbdbd451ba060c60d0449d7410b3393e857877457c14aa4a24fb9578d47a6f014fab0a311eefb6777f61796f9acc6d0177338b6735bd491157b11fccda6fccd6c427388558bf425c9eb65c43a24a375c14cb73a6a49322855a29835ad9820af162574c38a761a1d6544491f5b45566aee95d63d98f845814b0a62f8eb2aa0f2cb1596361da0547ed64a36c2ddb6b46e94f0cc36c45f1d6a270da6e202a332a58a88c40a92811b241d6aeae75b25bec2a8b92a19d99cb13aaa04951e88480fa38fa6b8c51e38b1c1f82e8fc1f3a450ac1a83314865d095d621c9918b66b0a312e9b420cc34eb31316e2306495f8c94a888dba28af48c361897138345e5daed574482addcbe67477e9dbfb14497be4caa5598a621e756d766e6cee425adeb7659258244f730b686926b62ad5bd343be6d0ccb9d2eec6dc1dcbdc5eb21f797316ac31dd6c41f034c75bda56d0b72813db403b0a89997683ecb5e599dd9518ca9ad8b6559695d35fee8ebb23b3731f1177f072026b85499564bf9d99cdd1d42ffd1a31eec6b67e99fad57454eaa4d90be324fd9a9d305d96486709515a099bf7a8c6649e4ca1d654c6283d5ad1fb629cb4cd11073baee3c102fe1ea7d7128e6a70d0b4c5ff7fe08a4d665387272cc7e8a6c373eb30614a7d9bb5114e7d6db164712ec73ea11948b343b6080469a0dd51192a97e64c6f3c436ab15af73b431c2d9733bdad0e6fa6914a87312d1311156521d06af3d4bba0acdae93e6dc96da37415fb6df25495336d75b946ea9ac6d1b080afa2a1176855a06cd420164a72ba626fa8c5bd2b2f794b4cda5ade4241169ff6db5d9c0d9b631e2f0c04893016fbe151e70b568951792129c9622fa4252a4830d98bc915337a728ac15e4c463227a4a3d71368c343e6aed5f4100e6f69da8bb1bc68374a8fb8a1ac694377efcabb4b0c155e7ba384446c473d6a71d3f28dbca54d9be4aea48df904d6d229d6f61567b96bb3a5aec5985e36067b5a3a6918663bb01f1224443afc06c4a953a2a8a1b31304b4719ee91c208fe7c54d44e0b2c402a0049fce135b640b5adc35415b62282861141faedd5dd29a8870e251436922c239c37fa05729253868ee73efb24a49e1d96d35a1e4fb7740d8b13b5182862a1238504213ef0ac5555755d495133925d40f0c9ee9dae832b5945a462d352d332d5ab41cd192e586911b9f0d1df549148f85f8dcdb15e69653985b616ed52752ea131f619e5527e31f13c56b14e656d4bdc5a0a2aeee2e89367b2d9ee530bb3e6cdbf6de68f7c6b21f0eadd62639e6a50fcf5a635efa70b93694bbe4b6e5197992197f619eeddbfaf2ec5c61eb9276353647aca46b39e903413d3225b992ec0d473b62a5f17e59b5138582769867201138d37adbdd4cb541d08e5987b549da9db86b1a66c3b1693c73396db4cfa38d7177298c8d4f4d616e9964c6b430b76cb9f5eb20e083af90379e95475415900fe94cbceb500b75e83674fbedca839d0efeff3b448e8c2ca020293b96042439fcdf8944e435772e9b79dcb926692324032130aa500bbe9c50682baf8c369e35255548f5ff1585c71d312e8c5a542a292448b142ba30079935acb4722a99cc1a5662c1eac22cc3b610cb72369ee0b07163c78c0d48896293d8118b325928ea1a23488920356606a47e008132638aec909522c5de3e6c0bb10dd5832a6078f5608892f3f4f0bfcb6b0733dc1c1747b6f8be5999cbcd70342dceaa112ebe9d6884082363fe03010101592ba54e229f562b2b827f4550326dca88a0acd3796ea3da01ecf2cba94594283281223d14a9818421db430f3f7cf117b9150945f11209a21229402d025489a4f16d9cad11254550ab552502c2576489c01858db6690d1029a0e6dd3e1e46cd083030f68d9c4b9215eecf2ab438486d83aa46ef085784d1d646ddd6008734bb17503d3aeaa9034aa9013542153bc0a49238401ff83bc0ab9a10ab9e1aba79eaa10a5ff42414282fcd6bc382382c4f007d152831cfd7665cdbbfb4318a383801d1e1eececd8d1f15f8c302a90dab3d3533528c04511f39ca91aa47672e0c8a1dcb88363e7469454103a65767874b8e85cd111c1839e1c5b034b0dd80a743850ab07b5fe3c9854cac26959dc3965d49f2b72d874953a692f15d598742c74ed8d738d098bda69d42e1dd3e1b0c6b4b1ed36d598760e9bae1a538d89bc51b08df30ef12d91b6d186c56aa83ecc176ef89580c20c97da33e67f8e8ddf0c106a8f93ff9f102dc8ce3ecb69c2023917c8b980053edb39b3b99b994b6d13af05f19891945aac2a462c24a7d7531a39719ee82089a30352d1b9e0757055441d5ce5d1f45d7ebf17f13659dd81e6e3016878616f4d8e325287482784eb10551d54e8318bb59a5e7dabd52561d7e1e3394f350711612dc7969ae384975a0c5de6a9876a25d498876a25d4ff24a72bb77dab24395da9382a90f41a3dd46893a6061129353bea8d336e94f15bfb802f3f7c61b774902508209ee429bcdeb8f295192a97240e771837cb71a2f284d5c612d50601aa0da86a038a50d086b242419fad3b64ea8eded1f24f284828c8f29ce875a7e2590e8e9a425353b19f84283a1ae898ff73520ef8ecdcff8ffc35aa8ca93554b586576ba45e75e0549d286e571babecca5a5c438aaa53fb95eccf864ecd4913eec4cfe670e7ec8b6fabcffe8faf177fa8383088e3268e06e25489d3244e9354037498d085591696f7b4219d54727472747874728828c14fc5177fd6fd4d98f88570f9792879aa062b04cf4788d3353a9caeb1610d0ca76b76a76bf6e99af1748dec744dec74cdd1e99a104ed704fdcfd1e34304121051f1d0f19193731e520099c2230d8f0c063d70fc4821f2e2030d0b4cb90280a80a6c9001305e8218c02aa1409706b0f0ff20f06cf0c1912715385523c4a91a1d4ed5c470aa4677aa26855335279caa09c0a91a29a76a8a7af45034484ed168708a26757a068dd333629c9e79737ac6cde919294ecf3c717aa602f4860e1c67ae9c9e11e1f4cc07a767eae9191ca746a4716a4418a74668716a449b53239e38358202ff81dce7860d1a954193ff4b09110410657ef081cc181dce60edf2924a76f9a5c4a4a2f460460a7635bb333386fc2fbfd99d7db852d7be6f6b7393395b7c711448e6ce99d530fbe16d41329b7a8b25ce22b9cf0b82a0852294c4422997304e122f129b24c84ab16436652616a10891d90ca289972693627766c6a212255665eeb30441d07e2a21329b568f760fedc42bde5cb9c7acc99ca65d706710dc5a1f21b35966a823169b2779c1109bfa4a881baf13ce657bb3aaddccbc401b37deb2a669182a0a375e2723273cead7a845ad9bb4a875d3ec84ed8dc571dcb84c02a3003f89441a3062600c3131183cff4dbc4d0c835db142de9c6cb5da38775fa189617ac6723adadf162f54aebc22eb0bf11d4fb1c4a5ae6d6ce6324a097962dc8db2e678cf126c6c7cfaf0debb59b6dd5077973ea1200b82357d67e5b5d92be61a2ca9c9654b6dc9dc19da17132c0016dca0f8e96e6eb502415b0bf1902a778eb7bc35abf7bdb86b55e6cefb1c9f5ea2782685fb56d9c9796ae9640a712ec7746d74399923cee9255d1bcd2c92b0b0bce1784d1836359419fbd266da1c77dbee0c62daa865a053886db63bc34ee6ce4aa11268cd1b8a7a47aa7607454b5444d67667b6c896da12593b6e6162554bacaa280b68b793264bbe221d11d19225194acfca33c4341b62b08908d67667a4edb6c08d453277b7edce86b6c53810142ab2497437f709c990d82d41568a14bba5c826b1b82ca06ae35c9626ce696c33479d6d07f6db893aca1cb56ad47b97744201711e6fcc6e6b8e5787643bb09fedce4a8c496cd6f44a36947378cb425588b31df3060acd1d663bb2ca5cdaee6c3c5de585ba24de768bf99afbb6407b59f6dbb63bb338dacda27dd9cf76672c1be6db14e230eb2bae11934ee6589e2ddb9831ddc2f58518aa966d79b6bef292bbe9cbd952d73e96c53320fb8d17765a6dee8ba14cfd1a31691ae91a16cd218b8d5c5924f9b7bf8bc522b1319bc4d668d7bab4a9f58d16ded9a9332d8b37f77dbb1bb51befa977a616ed55e9ddb25f894b118a4ebb73cefc6c12bb04ccf69adb7ebb72a7d365886fb4b31467577797748951308ac2495ac74cfdd2afdcd23a16ceee986dac860624208187466c0b2dd8105b2924d8165ab042413b7f18973599ecdba2383b77cb497797be9d58e65bdb19674dde3cb35a8fd796e6be4bb56c77a6386abc419ccf306f5c2ed96f03dd6817c97e5bc86eab14643f13e368617963485b146f38eef29391e06449d11965c4246cb5a21e40c1034e6e64cc765fda18a5c3541830463a78501437fcbb142f4d9bf9991a70e8c0174543e2c509c0a1862f7f8a873f4583021440c30e36dcb0030d3adc80030e38e440c30d36e0f0a76a50c09fb22165c39faa21014fd1f01097671307c0530e3871220278dbb70a68559fd02e227766900df54d7797be219c0bab55e8627ae5e878314413bbb26ec44411828bdfd081d92204997fa92a4493ffdf4e2788900b562868f57d56c582bde63db2d6ea5b5490098be9fcecc00a6200df6ddf2a249963232699805803840f7f0e10750065b87898095006cd8f676272c8c87edba82f983216091dc0fc170ac269d9cedf0f47fc10e50715183eb400c8cc63a6a1b1c365cbff95b1030fd587f0df32ddcd8962bed13096659d820b3113c396944e1d534c1aff73b9dc3dcc70a39dda9445dd9b59939963ceed53864d0d8579d0c243151eaafc7625b3991b4365d94091251e48638b7c104394448a1b656ca04106c0e8203fd0fd00c20e643e205f5368f29a0292d714ec6b0a40fedf10addc13a5dc1397dc133db827feb827fe1e0ece3d9c9b7b3828eee11e700f47e61eae867bb8f31e0e857bb829ff8368d0b3019b19fec3c60b1b926229c02916154eb17039c5c2748ae5e8144b93532c41144b90532c384eaf9cf1e7a03e7ae0a4f00ae7845738ae573823bc56e18157381cbcc2e9798553e3f54d18af6f48f0faa68ad7374fbcbe59e2f54d11af6fc4bcbed1e1f58d0170f4d8b1230c2f4ec348c169185a9c8621c5299c1c4ec370e2348c254ec368408f1f247af80f1236fc07092fff4142f71f2470ff410285ff20b1f41f24a2fc0789a1ff2061e43f4804f90f123d558b00bc6a31c2ab16485eb528f2aa058e573764bcbac1e2d50d055edd00f1eae600af6eca5737565eddb45edd0cbdba01f2ea86e71504aed728c2bcbaf96b162c78cd8204af5950f19a45065eb388c06b1643bc6691c36b1630bc6621be66a1e5358b00bc66e1e4350b15112240de0e1f1f3f3278e05486244e6540732a0310a73208e054862ca73294702ac3d1a90c42a732f0388da18bd318a0388da188d31864388da1cb690cfb3406da690caed3188a4e6308721a03cf290c699cc2e082213780e4f06c36eed5d0b85773c1bd9a09bc5a08eed53470af76817b3525fef304d18dafbaa757dd94ff1c91f31f3564fc47cd16ff5113c57fd464e03f6a24f01f3569fea3a688ffa81963c34617214ebb8039ed62c36997174ebb98a75d6c156acd2b14035ea1c6dc0b71f74213ee8548f7c210ee8543f7c20dee853dee85a97b3418dca371f17b3ebc9bc3bddbe5deb5ddbb26dcbb48ff7f00f1b830e01e972ff7b878e142fef8b0d1c509a75d349d7641a50b29a75d8870da4592d32e889c76514fbbf071dac58d533833388533c67f1fa926ee6b134eaf4d58796d22ca6b1343af4d7cf0da447d6d22c72b9b345ed9b4e0958d166cdabcb2d1c02b1b245ed918f1caa6cc2b9b1d5ed914e0958d0aaf6cc0573625bcb269bdb259f1f8783ef69e4fce3d1f2bb8e76303f77c44e09e8f20eef9c8e19e0f19eef988bae763bce7c3e99e0f11eef900e19e8f9e7b3d33b8d7e3c5bd1e12dceba1e25e4f13f77ad4dceb0173af67867b3d2ddceb19eff5d0eef5c0eef550b9d703e55e4f927b3d40eef5e4b8d7838c7b3d5e70afc716f77a7ca008110d80f4d87183ba1173eac6865337053875639ebac9a76eb69cbaa172eaa6c9a91b22a76e7a9cbad139cd4205ff77e8a03e689b304edba8e0b48d16a76da8386de3c4699b244edba8396d63e6b40d98d336319cb6d19db6d1a76df0699ba7d336554edb90d0a3cd0d4a051aa75488714a050b4ea9d8e2940a2a4ea988c2cb72ef6571ba970500f7b214ddcb02421622f7b2e8b8870219f750e0e21e0a6deea170817b283ce01e0a42fce7a183ae6670ba1ae374b582d31516a72b284e57489caece9caebe9cae1070ba324f57584e574ca72bd7e90acae90ac9e98a83d395cfe92ae7f48918a74fb8387de2e6f4c914a74f3270faa489d32712387d32844fe5c0c7cbf1e55e0e027839a0eee510efe500efe570ba97a3e5e510e15e0e2175cd91d7353f5ed7f0bc1e81c6eb1129783d028bd72332f07ac4035e8ff0e1f5881b34f0bc2b4bf7ae34b97765c8bd2b3c9eccb8f7c4827b4f58dc7b7ae2de1303ee3dd170ef89857b4f29dc7b72baf704e5de93eade53907b4f39eec5d0b81783c1bd580beec548702ff6c4bd189a9e1e3d42d248f19a4602af69d2bca601f39aa6061c394ae8a2042e4a70534215f79ace501b3c72f0a04a0a70aa649f2a094f953c9d2a593a556274aa6475aa84c9a9924f8907a74a869c2aa9a74a709c7e3338fd6270fab9e0f443c1e977c5e907c5e9c7e6f493c0e9b7e6f4fbe1f4bbe1f47be1f4dba71feef4939d7e574e3fd7e937c58727078f0fda8344cb29922ba7485ca748969c2201e13f0e0da4d89d4a913b95e28453295ea752b44ea570722a4592ff3dbca625ee35a9b9d774e65e9310f79ac0e800c2658a572e1878e582c42b17343f0f0f06eef120718fc701f7788ab8c743e61ecf977b3c36dce331c03d9e2ef77874f77872f778b8dce379bac743e5868d1e5a8489d3220d382d52e6b4480da74560382dc2c26911db6991d86991a4d3224f4e8b80705a6483d322f4b4888d5322689c1211e394480b4e8998e094c815a744a638256281532210382572e694880fa74414704a048653222e9c122175f054330f783563c4ab1931af666c783513c3ab19175ecd98af666caf6664af669e5ecd04e0d5cc08af66845ecd14793523e4d54c7d35c3e3d54cce2b1165bc12f1821e1d3d9e383a7de2c9e91343a74f7870fa4490d3277c4e9fc071fa84ce8e9fd3cd7f4e27fe73a2f9cfa9c3ff0a44092b4e9570e25489099c2ac18053257838556277aa84ec5489a6ff3b2e244ed36b1c2aaf7148788d83e4358e7d8d535fe3dcf88fc36b6971afb5817bad25eeb582b8d752c0bd1601eeb574f75ab87bad2df75ab17bada47bad11eeb594dc6b05b9d7e2718f15e71e2b8c7b2c14dc637de01e2b03f7584cdc639db9c712738f75c33d160cf758e63d16bec77abac792728f95e41ecbe7de9434ee4d11e3de1438f7a690e0de142aee4d81e2de9407dc9b12c4bd2960ee4da9e1de942ef7a694f7a6dc7b537e82f4e0c1a30ac9f1fbf4b0b8bcb2aabcb2885e59405e898c782512f34a84c32bd1015e895a7825325f896caf445b5e8960af44565e89a4bc1235792502e19508c82bd18dff3d70e4e861e2daa5045d3ef01b110ab2473a3672ca606184daa5eef2c325590550c5b9f344a74c2a4a4a2828950017b6e0bd29505bc0e2bfd142f87f052d14f94d1d3e99465792d3153cbbad9cccc2112c8cb92fb0a022405d81899c0eaca0f43b6027829f47b61baf8b11f9bfe555f7c5ff19e806f0475571578dbafd32808ae3da3c4035798ecb034b51d7290167c5e62d871e9a69bef16495a73ec17efb24af458204b7489cd6377b33b599bbe6ce5952c67fc36d5041288735844e8a8c0285aee20004a8e30affb5781d41106215c26ca1d434864171e930d661129c24c59e6c943ae68cd8e537c3a17eb96cb7956b4acaad7244b9a0d5fd962c768c02769cec88f0ef84203af1df765b168aedce5e809bc1376e888bf9ae769a30595244a4e41bda51fd3b49fe1d24ff8ed0ce915f14af91285ea39a820ab012cedd2324d813abc9c258f60829c642728a59a49655527261b130a425d6cb527931295926a698fdb6285e8cc5d90d9fb62bdc3d7c299323949dd830c5d9dc7254b7ff0c3030d88846a869e0393eb5f063c6c87901dff0037b502ba06324d4b2441964d074f83e7577c9d6b43d62e27d24ef31077da5fe8454e60db2ab516b98d6b1736327afc7757c2439fa6f64c5454b99355aa0fce515af11932c1a7816243ee6a56f567e3b1c917079ceb2f9e1685784e5ced7b7b7268540308bca3c82a35d711f81c26513142e9bca7c33f7ce9d2f2150c74a0ca58dc0a012376dbc428601e17ca1e870189697666228268971169757b597ecb7fb7079a180d686ed6e06956d8cacb19bddb9c6eca1541817ff59b00a7cb4e50aa3e1bf09b355980915e6c39675923855f1dfc4fbc86577393f90d7f1710a51320ca573b8842a2afa8a866818ca1bc1cb4fdea84d7a4da4784cced22baa62470aafa8e96616f2b11e9113d7e5273e393c7e784443a0586a3c25473c33f0be23bc6f87379486378486ddcdac5d000e57e15a0ef01dccac7913ff81f0542294223b0465892dc4267849c6f09280debd34fa5e9ad9bd344df7d248b99706c9bd3441eea5c9710f4d9c7b68c4b8870605f7d058710fcd12f7d0a8b98726887b6876b887a686ff3c3c3b2110f1bf50cf08e2f50c1e5ecf40c0eb1902783d837c3d037c3da384d7338c5ecf08e17fedc1e30a1b3b3d412ce164830b9c31817a54491f289a26a0230756056e34b1a281212be41031e37f977b42f5bbfc7490bca029ce0428c40cffb5dc0baabb1485824c1d363f95505010ceddbd5a21196006d0031ae281f0e635bbb138bba607420702f8bfe5de0706f83fb4530120aaabda99849177698b5a973a69c9c5a254eaa47d45db9877224966a71a538d49c7ccda6bd798304e1a71a95d18ef6ed3dee1f86474cd7bb471d6316c5ea77db433f7ec84d598768da9c6b445bdcd71db6ecbdc5949a7a362ac25118ac8bbb45444dea5cd2a75924eaa31d5983699633526f22e61d91b973a49d746d7ae31e95a8da9c4e409dbe5c5a21136f5955d2b746d73c45022ae128eac10974821fe40a1a0bc73e2d56316c3f19c913bdb39733d3d7d7bcc4890987a4482c4ea23db81fd762e9798d461281c5e9cc3e2d5a2fd2cb8058bb32c1d80765fdc5db29f1d6fb6dd708f59286867e612c469ad643f211ced9a3051bc461d046dc1d1ae99c5e29bb9efcd2cefc634f2c4d1b4d217eabdcfd9c55bc01d4da6435aadc02c1f064afaae91fd6c4d7fb97daaecdd5b97e4b6ac6c6d4db37299ef0eeae2dbcd504879b6cda30e68996602994059e7bcc215ef9dc92ec6a575d98f89fdecb7c47e46f62bb22b6cbbf80a5955986ffbdeb2c5b9349120a1e5519b7ad4392448ecd5b5315b1cb26a228685216bd7a45fa3cb0987da08291ccf3ce2234c2bb50b2f199980a45f3158927992a3cb098bf98625c4650c1fb96c250eb5d1cd24f191289a27699e4cfb52d9b62b26c5584fad31eb6ef98163d6dda553ef7bc3b52fef5bc53cf50e27cdae798f5ca10b47d34aad2f87c5992ec9f2d4341af881f79618cad4afdb649267891b6fcbc42798faf5ad563bf46ce86004009e8dead9c849a3deae5632d98bc9057342ba225be5ece0edc870992da7804b0b85c8920025c4b77d92de4eeafff6524e5c1ca662f06a5cf1ff0c95426c44e618996351f8e5d570c1abb1e4e99cf1ff23b349e6d8b7c91cfbc86c626dcbb1ef46bb98d4b98fcc2616734dd5da371bcb7ed7bce10d68e7ce118342fa166555651018927769933996c365d38849a62453bfc81cdb173be90c29a3057f8da9cc4b396cba742cc4fb29748d3a874d5789c728a6d746c30c340ad0f3940c60208314fcbf624587041920f97728f0ffc64e13ffbf4f14cf3324f01d993b676436c96cd632c6c480861a8329ff7fc60839630e40880904b0d2011871a418a2a78c1172b4a44a9332e26343c748d15ff41791e9c02b9909bc9259c02b991a5ec9b4f04a667c25a3e5954c9557324e5ec930792503f44a660819fa4a46c7eb9832ea9815bc8e01c1eb980ebc8ea1c0eb9808bc8e39e27f11213b367eec1013c6ab1838af6248f02a868a5731508851537b107aed8183d71e7e5e7ba8f11a268dd73065bc8659c16b182a5ec360e035cc035ec300f11a2601af6158780d930b835fc3c05ec3b85ec348790df3e4350c93d7301fe4780d63e3358cce2b98315ec1a0e0154c9b5730197805a3c42b1808ecd8f9f949f5a8604a7805d37a05f3e4154cd02b180e5ec168f00a26e7f54b0c5ebf78f1fa658bd72f2078fd02c5eb1707bc7ee1e1f54b0caf5fa05ebf94af5fc4d72f38874f90d4ceec8af74f1df97f6307fcc7309c8401e4a7dd32c008011851d81d184154300cf07f60845fec3a4bbef0c0c6385ab6b25436ed1297a0ae8daed52a06e2306fd54ec43b8fda8e67693f7b73258e7d182a8f598f56a54bbc8228de4d621c89314ef6e970d42da1208b4d1d8eba45cbe6786dd9662f9eedf66d7d3bda06c2a3b6e46937d090a6913a6c553bd34a5d0ac9cc8d6732f18e9a7cb29f90b983b25d99faca35ef5112f964e6dc2c2c5be63e97c251b776b7294a2bbd626f4cf8f17e73f446f57f5bb258d90a28509ee592114b7614e2272c6af3640af3ad2ad881f461523c7379ebd836c7fc01d1139dcb3b62dab6d77e45ab9ac6db3c453de67b9311151115d9cff6e131d7b4d556058ae2dd191c31a9419dcd5b0e69730828e7109ba43673986db62c51bc4876766ed5dde4a94b2af6ab9d7ac4b48bcb6ce6b40a042d097a379bd144adb5b9c33b3b6b351d628b73d79671fb0859e693040287401004b7801b04cd9315ea977ee5ce5c0ef1b831d4ad62ead7c6fa089bd7d4aff11a8d98642a994a8ca3652ba67ee17676d2adddc8ba994c3ab66da31671ab6251c65daf580cf15f28a862a145cc342c80fc8a295eaf6861b5d2254621a8d4b20fc356abd8154ec650f38fb631d36a08c49fc84a91628540080a81cf7f1c65ad1563acc0c18a17acd859215a719fcb9d473b6cc5c41b47c1c29055859a7f57f0f9d4646a118ba753947e69ed0483edabb461db0869635ad6e1976b63f1746a69f364ed96ec30b7360ef5cbdc59696929dcfb14afa9c32f53875f5ba767a3abd44bf6c62336af1216c95cc6f60e5bc1fbde6ae595bdc356c2dc99cb3b1fe9f06b87ad20ed12376d9c75383475533eba25d236479cc3d1c46b6a53875f7b57c3b875dbb7ca93521395112b6d51648da77632b5083b3275f8b5639bcabe25d2d3de612ba60ebf965aaead934abc84c9938e955729bcb80af9b48f6e89b4b4b47577a93cdafb3685587797be101fcd6a352d6a6df40de97c93a03e3b5edb98ad4a9b78d4e68dc2238e8695be10df68e379c52bb4b159d3364a576942faf42e8be17867d78ed77ea2b5da14c56b66a1a04deab2a909b443b6d416cac51233f75502ed905d9938a7a34c33e3db4e0c37fec278394189919258378348f69b8da71d63b5bb71edc2a0b6bec5ecf764bf2d1444924f78d42f6de2d76ddf2a4bad28adc4a46ba34ba604e3eeccae9c989c9c90ac918b0a93121321302184891bff97e06289253e70956d743269b74a78b5e8520a713866dac64ea193d353e86462584d2b99fb3c0a71940e472425b07c7fbb713482476dcd6cc311ead6ec3db2396d6a33dbf2dcb953ef60fac8963a05f2b42326f50ab77369c7286dcb53ef422c0371cdaa9020a9b9ac1126272414ec8b5525669da858a4d6376252dbdc7dd96fbc2a10b477e3306fd0ee5a4de3f09638679e2d103cc18220685db0960412ae798faccaaaa2e4f20d46de2529d65acb82b516eb1104414b9a793ced03ea7f2baf6b36f07f4040761566996ad77059d720fd676d1c4d2b59bbf7c547b6319be188491d52368f2801c8aa6e668ed2a96a9cb0ba1bc6b4195a5b8997d4c4a08605355acd4ccd51898180acaa086a49910300f0ff8bd2a2889340d06ebcc92b8a3970af9614550780f03f6cc009ae8c79e903ad59eedc2d6f538dc93c99a2b492c932f54bd7c6bc4fa55718625aa993427cb44b3c463185b98b5b67c89cc9fdaf67388881115e1801e79fb96b95b869dc596dda2fc4396cba44f1d22cb875a94bfd95195cad6220cc7edbc8d42f0c95954cfd521acbb3b5f351289e1a4b88a17419de962e310a635ec2fb69748d78055d264569a55b9a3a245d8ab84a898df0a85f4a4a55764dcb469dc733aa9da8a45498d2a0746846040000000000c3100030381c168cc542d17050362bd23b1480015d9460b866441a89491653ca18430800c000000001000081310a004d6731315fbbd7c35f1e801557a1edf330e755f006e3b8b2e0265cca86cd8b3970d8ed12702f4d596d9f96d6df06adc9d0967fbb4662d0b5d4073d73bfdfccf38617935b3bffbdd612fa1bd43911a232955d72b200a850133d9a38a1957793ae1530938e78934953073e4a09840c8132365a594cb4db2ce4348fc91d9b4e8891879a2285932eb798492bc056ce4feb44e43acbc60d8496f4a8d41fd854a9c07889b216c9ab24a9231f1b0f65d24e0b50933626719e3fc8fe9709bdacd3a412eb3c0c619a5c04b0e4a1e2443dd1953848f9e390ed5d46e7a5335887d8143f2040ad7e6e92d33c049efcbd02f6120f0771ecc186f3af1ed0dd863e888a3350ab136d6bd1e3d6d24aa4e1b6c53cff2fc67e9a0ce7992bcc3dd1e08d17691023694987badc26fdc6a59effdbc9642cd726c7334965456e82d81df2e78c69b128a0ff23534af39c30bbb3b0f122200eaeac0cd59b1f19cbe0fce02c3359159c77c09a5306aa05bbeed5da064b5275d039ef058ceb933de9a55ca4ae91fe4263b0c295ee964a1a3fa83d5c666691a5f857849a034f392dcf25215b3a09da31195283e9a04afc19375823a898797af9186ede46fdec683ed6f2f0665c741071c321d6832f30439a70ee7389126708ae5f9857a462728d7163ef492806679d7313f7daa7a86037978fbb907ce9073739b82fe575a605dde76c90e66d0281a0860ab793130f6f26b5e52e55b08fdfa114818f5071985bce65eb0f768ffa9ceb668583fd16c771f7a007d201b9f481a8111f37120a94936e9a61131ee14db369f4929024a83b913c889cc73be1b7cb2a8f3d4093f274b3e01809459543160fef8342c934cd68bd2090bcff2ce27d0831d90729de0f891e69b4229fdaab45b34a08181a7548c250aa431886decef3c3e0e03d25ceb7c7cc39de2f14224ad8cf5f60b4a39e6383a36a63c1f9c089567e6ff657341677cffe53be6c736c704ebc0fd09bd2642273d261a6bcee688f97295ef8c59136b72626d9df55ba075c821cb0342c925a541cffc03007fcabd79060ef03f5c741e497ab38a782087f5f16bcad5b1881b697f94db507ffc1527184b2dbff3bdf2bf30db7aa2082ce717559a239e450e3feadff5c3ac9be846efa7374e89d0ef53a51a717bdd3046c56557cfce261a565d293dd94587646b6308fc46523b7d9758ac97f59c370c2f6b9e2415496ecae77c76aad6b413e9b1df8c1cf9a14fae958da27e83bf6645d48949a89754aae8801246190e85198a35ad551972a5fed9fe2ba48e1f699b54d455ba2930ee7a911b8999cf0a35259f0c2bc19be16542dda5e01cd2b44689e8d80f055395c5580663e124905e9ba05611b714c43f2165efc69efa48e150a1fb1464879c931b65113a6b4ce99ca741b63ff79ac3e3090caa6c3bf1d3a883f402d52226a9e95b25f3f430570f2d6fd9cf2208edc4e729fe77940589791c186a2edcf29af0dd86fea5c61ff6775812cfa830f54fc75a1df112128e874dcd2ab17874819004ba18bbcf343104c4284fadd894f9adca9eada11b56953f2e7700b9cc0cde2a913f0e1f3911f3afceb83a435f7758e96451ea012b4bec6ec8e5b62642bf51eeb0a867b7c681997a49d1e995184bf58a66d74bb85449115970495b08f82adbb94b9f76061bf3aac5e72ff9b6b7c84d6be902aca9c0f540a0a6ac0b2f29804218b7a23416f20d51837191607f271bff80846d4531f23c915fe6032994cbc93b3b6aac74187886514924c8e4c0c85174e4883f5da352e4f0e1f5cf3c90e6ebb5ce50aa9e054dc73c2c943b5cb7ff351f9e064e9666eb023c3b8a73369306a13b7188d56be0ab72d3c6a4d6b5b94eaac168b16d438eabbf92a66d267332089b44a834b17db052bef3158a224154ce90011a08ec1890864d16bef9aa711c7375e9538be643fa24966af13bd2b6234631cb47272f3bb095e7d20a760ef35ddcb44f43e5a6c2a14885f449c2ab9a0f611912b782ab4da8cf18cc25d0aaa76517f86c319a52cf27440471eec72d185a2a81775c4f35f5ddef56797a33bbd278ebbe47f0bdafa1159cc7639ea27d5efc69ae3037feec05968452eb6de133e2b6088c16b027f712362be4c7b616f99fab18625feb91581918a27ed5b86f5ea88433068a495462bbf40b2e3d09b8816417be586c4ef2604067220363388b9e1c2f09edc9dc81101d2bfa0273a38a500855815c8f93b36419ce619d9a1f200c46e59bb2db747148b738b1bb6ba228048ac38b530acf3bd30c84d105b73965afa84d48ff7087d588fc9d8bd46c333eb9a19f366b6109dd0b441bec2f07372131f6fd52bb585e2d1b24e3c3380bcfdc586be0d3670d0674a2b377ef7ef413dd85f16e446ac6a7bb0fae2790c838429ae730326da1750bfd31e61dafef836b46c5c71ed453f8ee51d85b4b7c470c0a237edfecf659e3089d21bf47e67686a802c51ad8f4117bef3dc61ec6b067bb2c7723bdfed3fdbf61732ee7e879e017d4c4493d78d50b8c57f341cfc59db394ec6f5fce10f68431dd7fa50a79213bd921b8b47d1b00edf205ad5440df31b4c96c35984ecafb631656368864eab9a49340812d695dfe33d3136ca3c3806d8f42a2cd35db88506561a635392642261156048aa709ef3a0be06bdd63c1e23a6b177d2918e73cca9d297c8cb5393adde09d97ab4557ab14c693ceadb751c6c03ae63846fca30b0978816984f478d370ca9b0e00b5a08e1f1946e82bd2df443411d3b291703e13be6d3d6c1d4d9063fa8fd73c3b3ea4f7c0627b391cbb21d9c69ec4038dc55d7fa203fe454f6580d8289cf0421e0139d77ba3b911ac5de50d73a4d256129abdb5da8d424354e9bbab349282a20f8a68d33848ca9785886c624065f079cf6868ec86e81e8f1db9f73396087654815c81d592ee77490fb6ea96e0ab505c15de411536dc897679dd87e830a8f172072179c7c4e322d641b2488a2cf7a5e0a3db57dc81eb1367c752961ce7f041d9d6a677bf75d72e6ca0a375810a79b7a685aa8ac688bbcaf9207e5e72229c3f142a988b68776960309a19fc7898c574c05c36aa73030f3413f9b631b442bdae6c686ea755509b8c4a095139be6e378b1cae1db1d9450c88df94c509a5817d7913669dd5e6d0f5a1dfb6f3e40d28849da583b3cdd84b139ed6a16778368e74df656f7e4ef92fcda99a01e44d7494af322a1b4b277af8598cff8c141699cdd937e14c3ee7bee3719223096262aa5d133d2a505def6124cc68228c9164f52597f785da15b8021482218c143b9d796ed1de062c77956968d6070f33ed04473ef89555fe8023470ebdf5df3ab3a06bbc1d81922dd09c178e85739dae80e87a81b3df6acff6fa23c88179c5452648c9817f06e5e40a85a0c0899105b19d267ab1566e579246d409564040cbf76e3a952d11d39262287bf74a21f7aed626a80be773c370a6eb4207cf9bdadc58404749d4022ee3313f7aacb8103500059ba08351775697c20c4d1f00b653f428730bb800a28e0d29d45ba263b30ed8c71e84ef9d1dd0c0c15e564779950bb5dc2d724102804a127f0f0310c1c62fbde52ae8cf861f793abeb0852e6ce6a14548ed45bb533287ff05690594323fb7357359a5bc51343ab1ec07bf08259931a8b21fc13bb83bbcc09ab3498ef9796736501ee9083630f881d8c6065aede852dde62968c30321221c378c8d49af346ce4ecdb2a9ec5125921703babe0531a2148c45bce72acdac29137144626ea1c9d8154fd86501597518bc6971f8119ddcb07f1cf1f815190079caabad31367c313ecd7dbb84135f0a38f50247634eb3b86ecba10a25c4bf8d18c2e951059668dcc41cd85397b0c9d85313eed22fd6784158141206b3335aca4a0109d94779634fb15f28a58c0b5540f6c35dea4bafaae8e5ac9186e0d7b1cc1dc05ccbf8889bcc76458b816ccc8d1a6ee460b42e50e98aab8beec964dd69847fdb6831516776e8acd134286f60923740904eb202ef4cf65cb2633db2d2a8b3a20d1a983cdb3c4747e45b2400a95cfc2f14d5e829415c07bcd2b82af2b2fb25191b16537625eef5a62669d999cce2b7428af7bc3873d654e221553197836d38e334695563f384f07fffb6902bfa04f4148b3990a3ef037d26b15ac4df239d11e8072ac78874ea752046257df957341dd3de05e46d437c5b84e7334c4080a15fc209fbcc3293865ca65c49b150c3acb8991a19d48569d2b1090d99ed1ead98e91f2d9a1f465d57ebcf50fca13703d2fd1f9a7711280ed9dc7ded792346f6b5ec4cff8766b3b37c968c08f0e222c1c366e2614f4776f7eca33f384cea331de8798d075867003c4f81e12aeb26e4eeeb67c6d68f637076b50a82109f95452403179501b8ff33cea330ca473f48e8bddf7112eed1a7ecc42d98368499ccc67171dd61b21cff4032c2e24c433d851500d58ba731ebd63273b166357686c8fd61e935705b769e34b5ccf0460eb1b30d53878ac9fe056383d080fc984f845dc171b3e018be4dff8672b8a98e5fe30ef02beaa87485826382ea204045b6c818760cd46f714a3c0a1cac63e37dd15c12a15c782b80ccb3469f1a1f79f3df3b6dc2cb0d8acb819cec4aeec5240b86193931e2d551b77564115a0f1b2e60ff5d01b1045313c4a15f55abd877bbb4e9efee2a11ae46a79a0b7e89469f75862aa11d807640790013a62600e48e7aaadd180990fe74df3c9c17008aae0e5fc8bc8f51d3a1680b7b5603ccf537fd8c11a2aaade96ee1390351e39637f742d95b8413bcd6e62f2f7ea8baf06f37c256a379aeb85006213eb4d5acae6a5a989cdfb8416742ef29bc21d97922bd3a9c0bc56b6e62bd934a0b7675608051ea4233440ce2bdabafb32f5228b6ec81169cfcca76572a484431b1a5f7bb2e85b80a920c3bf6f7e8a307fcb6d263d46883a169ed8b836b5c9416d90bb818f74a6d39ea8cddb9f3b57f01b6424479bf25594c693b98d1b554320af5d83fb1b437717230fae94170a17a621e28da3e6f71f0bfc9cf2aa64619473070c761be5fd23155a4b2137a710cbbad483e4acb1478a850218cdd2983f3413d1c06bed69cd10da294f25f6e2bdb581fdde15eeca8296850e39f165d8d66d185b17eacc44a615dc7a4ba0fbc1aa59660f9d62ec72769ed83ad48d5c0620baa479b0d163c76d60220a597e736f166cbb9c608401cb5c017058beb6efeeb554a3fba6564812c4a53f8f15f00347ff4ed8a74f571fd8377e39c494f5e5eaa909494b92b5c945f309f24df5c47b44b478d6d2fe7fc2e07e4c7846de4dc49fb2e6095be4ff7a4dce46c5da09e32715a4b09a4dc079070ed505bbdad503509d2df9af98f7ae9bbbf9a745f0a960b588fb50f224692d050e89e3936db22eed7fb66ea9d22bfe8e6fc5f1d9c701dff8075359ce826e75f39bda90bb9c30f7aafd1079a70d00fad10f8605d1f86ca660c8c14159742cfa013e3bf2fb1f68e9ab574086ed9cdbb61d39707219fc3bb0781b5b6435ab493941b3849f97ffeb4c95cc1619b791a39a411e289de00480f8007c0fb006e7838ff6f0e9b33d77f290598a7f11856b06506ee08addac57490fb835b9324ffaf8adbcea8d013fc4f7a12faa5caf4f722bdbff47ca4254ea609272c6cbcb649fa36cdd385eac255b5fd2d1e6f3cb6d1a5d36dd41ed2ff439c0dccb1b94b9bef32e4fdbcb651ed4ff9de793f6cd3f5c7ba5146c12c0760fb4e5d56c9cc46db761446316fe7f73e1d3f9285e558d6d0c2fcd711eb71a34621aff183eefd51dc1fb5fe6f64edbb679a534549f471b4e3abdcb9c10f7179ef83ab6f6f9b4744ec479e2e90bba23ae29581c1f5073485d8f1647bced15fb5251bcc83540bffce47279f6ce12f3eeae78366f3cc971ec5199316e5012a74f4c163bb42e34253c13553928b946123d21b679993352d93f9e1aaaef2a7a0f6abf0e4f3c763a6ed620578062847ae016d866c466eb911634c46dd2fa0bc61545ab44e17a12918efe2226d28eb5a3ea6a823dc532033e9733466f13fead670a5775d33f1b6e3b5505226c5c845b86c10232fb4796cdd65e423325741a02d3541021a5f6086952ac2ec027a6d0ce87f1823c46ea0ca8f93bac9ec76d453d79e01e8c3a6cc83f4bfecd05978b5a8bdb1d020d4ac77188b8fe60b58c7f8f101098a62bac796050ca510e481b8aa0acda21177350be094d2941173925371fbb7e42c85763f279412f95d6d8b496637d06d6511e537ac12fa92c67728a35da9191dab92c657db4e7cdb2655e51e0c1ce34596598b8d06784bf5b5040d883c4ef351577f982d983238fbcf2f71b3f350762880019b5c31e105081c22b23b862ab4e6a3b826c0e63ee329ff7713cb149294142c15c1d73f2435e3230be84a23fca25c13735f0052000fbd0752487f3fa81ebeafc21bd9fba36eb9a1c4fb210a7912eb3684c421371d411b2bbc2d22b6b89133a47847044d610b388da657d74e027a38b0758cccbd245ed7c084d979a0ebc8dca4a0fe0a8644ee4363c585d06264db93ae4b6011f4905677829c832a2b8360515108c3964feac6d8050a0349b4d397a4ad5b489c2e5b19ad34efa1e9a1c910e5afd02269ef342c25fa82a1f605f71a01209c4a74838219c57356e137e7caa1494db980cd237f301a79b5346399acb307c4238120d4980715df20711c42f6dbeeb53b99c414e4db0cd31c8e9c68951a7f3f3337ddf88ec98c32ae21088a7865c9de70b6ad72e2a0590110bdb4cfaaadae2d79b19d0225a82b00828b1fd2c6681e70ac8b232f0e733faa5d944d8541b40a339d86dce95a31271ee9d251c89277e3293c837302c29bcb00b42fd69d0b6a0b52e77378cd90d9de6ff3cbe2f604bfa80d1e63e0a4c963ae99568436944a1c30442ed832c0a3dad35a13fd8a9ca6c5cfbf028c1a72e7ef5539bf6f6d99d6006a7ecb8e91b1a8385b96077b3f36d216e93986539f4d97bd17d2e123e8e20ab6fd2f3ce5a254d743db8ae9ecf721adf04faea8e61479be602561f52a7ee3d894527a1e1d0311cfb94cc391b1a3d75c385d8b47e7593233e7e1dc606ae18423d60cf8f1108bbea5b118782400b8917b085c6bb5af65bc0acdabea92864c001594817e3b746886580f41f943a135837c0b9f629a810b413f3f66498bfa0b1596648adefc27fa69ab33cc7741c555a894ed2a220faab87ac47bc138e10c27449ac28c6d2b6c5c1c67b3c64ba433f6ae6921af7baf4631a894dba544a6637f29cecdf5ceb6549c14c93eff6250dba740d2574b045a939ae2c378e2cc56950fedfe06dbf2c634e841e8fb86d75d00385df89c6cfaa29371546a1b8a403bb43a580bfd42e57f73ee6612bc73ab012b1186c2452458aac0c36a21b0a81d17fa03987c51aff437c3c8f899389265503e5204695659d34cf0a1fe8759b838a52025360ab89255a28e7e2b4f8f2eecf10ed2c93cd678f77cb197580c12489d033c1415a4e15cacb953eeca78d051015cf6d3d9e36ef8c9ffcdda98b48a98d23756743bedd78fd8273c291b10e2c37607917856b7f228c7521265f8a8437e17efdcfbdd540c35c467a571e6d22fb8dffaa8885898995d70246b3b58b90b86b13724719b2a56e102319e347c5b4f07ed79d45dfb684c9e6820762fbcadf0c3bf46a2ee7256d87edd09810febbc0074eb17986c5daef8733d64d95cdd130f03f05abed5a4d255c728546f40fed329748d6aff7427ff6ae63695dcfd8981bb4a13c7c7c76a1dae0f98b04a300d48ff1a6020010cb869b4fd666e4a76e1bf08dd75333e98cade90662bee43f0dced344b7567523d0862da4fc501d8d0c457f874228a843fcafdc1feb263d0bc0c57d615868b0f5707b8756155408857ffcd64372fc5fcd18091d8f030d31327a4dd86afa21f6b54f9020de4f2204b14b25268cd785833fe471539e8f5447bb2e2e159b900188014fbd46bb3ea9eaa967a3fa7dc652abe175f91ef22e51f938d878d1dea09871ac6e934687051218fb803bec68a5c11013f555fd82c7afa49c794663edf82baa1d252aa93183868bc22b00e333bd109cf0cec88543c1bd8c4f6d46f9f141d11c3bb06141cd05b387e636044c7180ef89668d74d7a03675344d682b4c0b2481dd435759e77cbd950094675cb1a1ec3c956880459bdb9836d6c7e4022f15b8871546d2b01988c53e439548b506c0816fcd81c85742d077529e0d158492655c47f36a30988c90c406d8f0d278dc5e4364208843009539c177a0762ec2568234d1bc1e57f5ddb3f780390e27cec8e506e7f4bda502ff9ddaebd3708453fdb484d8448690a10388a7a97882bdfef87ab0a639cb9dc6a5bb94d022d015bf4ac586656a75d7459cd914d17f182a7c33d5e2996d63c8ee864e9c90aa407ca8075fa1ec8cc5d3ed90f51478908045e906d81a11406c1f2a9ae2bcf5ea523c5894d2f6f8e712b1c3878297fdfb9a0b2476145b3837ef0208b65e2f618a2d950b668140b22223f8e0051c3830b02d7e8656e66fb08a8b9f3fd22ac596234da13313bb24bf24156d32ba95bd9d4aff502171e7a5d0f8344b555558adae1dd068e75da8b42cf0c82af482a9a3bc219b6522c06170363467167112b422e8b1680c53735d9fa17519f2a0157e1776c6e8d16b4e583854e9c500f6946839998c0bd29a28f32e609a1ff765a726c57bc28b7ff4fe05fa8bfa46458810125ada02047a2be79fa01cd29f457d525a66557c10f179f58c5df2138837fe2d1b258e42ff2333ee3285ea935087de2337312469ed2542c84c337f4bff106841f0678497cc6ab17ec9ac084db94489bc7e08f52132820e4445c001c0e9133d361574809ef02ea6824127c09b0641feb318fd681abf4cc0945e9ffd5123ad6a5859c699b281c09c123cf01af3e4bf801c412c9e5c2607a9ec005eaf0357c5879fcc4844684b264ce2f3ebe2b4a65c493b8d460d1d53a221f5e482dbd83de84d44cf0f1922c1a5b932d73d4968cc645a41c62cfca723c2ce1f2d107eb6dabd50d3c2366b19c8f107fe7103578c7100b05a1b29db9e5714ff5f9ec7369cc7ba0550565923cdb4844ed944b7ae7df53dce6ec1d432e86568161deaaadec379072b24bcfee8b49c8688f8d23007cce52cce9940f2564173772aeaefd1f57797a3adf5ac7c348ba8858bdcf61f1b8206391f10e504701ee9c11b371e5483bdfd80c0075fd405d7092678664104d112409ccb6fd6d25e24df8605ab36b0c754810c9be1623ee77062d4cc4dae6d2337e507b1a0058a79a33a2eaed8e08f37543cc8d9df468c105ff0912f4859eee93a9412a2360a02b2d136c526da14887867257b686bc5f41446d07d1b17732b8516a0c8014b53dff39694d10710715201780ae9c6f9a1790af7ecd041d05748ea97b828040dcc2ad69beb6991a301c2021be9c98c51bd1bcb4cb8314c13292943f79be4de0e2858926316ece61b5b9f872b068f4e06e007ac7ba4e82278ba1f9e51adf5692a2707ff86a4c6f82bb1cf28798ca4ca73f24133a11e42b06e82b9330bb91b6a05da1aa0085d1376d013222b4f69add9846e55f001d553b06c2d32cf1e888ed22870c486e88f294305945a8902abe6e3f14ceae56811dbd7deb40face9a50ea2d1fa105ae3e3d858eee6b249b79ac1bd52bbc57b181ac748648c5ca681b7359bacb34c6499fa944656a9f928d6ff99a0facb60196901127eaa6d71139187e5eb2e9bff567d260343a56f7fb033e195cce1e887466a983e802e4fe71e194d84d8abe1206600781620d7f74f79d531584519a02dc91539244e2a92f7fee1c5333b0b60d5444421293aa5dc99f2a5ec499d8abaa9b2c6f5858614981e9439af0dd2769837869ecc4067431f9d01c41f0414ba6650181e31ba6cbce5c1688258f71ef8e184424f289117ee447106f21109454963e0b44d518a0d1da2019db91b50c761c1e95c5558c38f3062c66acd0740bafaf5734a875dcfc8a948a9b9cc6609c51465159d1f6e5ff4dce7f844b6a8786a2d20412b5e8f3e03cd002a67ba434b0c91c61859bbd2c6ca6bb08b2380c8f95b6120fd0351d45c3efc110bf46e22d60b7e394411707981e7fdb753ec542acb11682b5ef274ea494f9deb466b346b43499a26891182846e9642503c3c025099a1fafcc596ec7f5fb975328843aab24e84342160b4aa97562ba36399f5c23bad3be7dfea7a252c4d5fa62eec9dbfc59cc9fbe10b168fff67ef52dbe527c7620eeacc5470743badd72508c69c37276e8a3358b62603f3708bc8d11644c5a2fa606dc382453f8e8581690c6d8d95e98a824680c45e0e33b7b2d24704faf72ef74dd236ce3f1f45a1f8edc0a201a6fba0a9843b6f3d93a23a1fbdc810925ec3e86fc3a9a79e0c8a84a6834bdd7261c97e4b5fecc1c17d3950d12eabc2c32743cb5b7b9993aac1139fee99df1e64b91b91c5d3fd26443b9c64b038a62967c87917003877c1efe3cc702d61b642491af8dfa02791bd56eb94d36986fcd14387e59f44b1f9783b643d64a103886e02447b0b63265c999120490b001f48808340fb202e8ac46edc830b97cb94ac345016ee33d74841ac091ea34899c6a15fa61785a461f16390f8b1fd95247662fdd6c5ad1257fe39a1287fa408c800914be951c1a7cd61adf71af0294cc6b9946438a23881eb21fc1558876a413f9b466d7d5e0f08867c743a605c1aa8122549765c44c79d0b0778cbba4068eeae814f81620b3b2329ac3102710f7660c37defac7e99db9180002a72e6e6f548ef19ad05bb9f688617edd8867d26cf4c0cb2cbf07c24c3b70c24590f3cface6814a23f132a3a3088f5030f8a78ec5184bcf14f53ed62bd47b192d503745c6a81fd2381b83bf06b44bd5343dbdc1d5df02b0066ec1d54ee8488c9c8a107a2a0d14cbc3684cb5e986c37b0de8f9af6ae0a511959b9e66642ffe691eccf442b47342787ae55081d6420a496372b55d462e63aec4ec51979692e272a73e8e6618e248375ec590a6518125c4a546222040e3f3b4332590fee17bd9451f6de27393ce1e0f1b87d188b2c915126c504aef7c1c1d9145f32a709b34fca9900cc8cca614fff76b9fa53d9d10881768af6ffac26bace0cae6b9a462d738270d9c74a079ee1d39490cc4484659908db43f45c7d9f33483de3d702458156f47c9a64cd52a9c9c0acfb847114e0d46f2d7a7e0903d97826fc419acaff48ec2344e542e23d112f547fa7c13564f04819ef41fbb0e0dbf75d1b6ea2ba55a1b17450c715c48c3cc8c46440870db0a7643dabb06122163db052d57c467afacc30b062ec1ffe94a2d6603f34a82492aff6b8b5c252b59e1b068e99c523b04f4b0c50d32fb7662b68a41da6e4faa05f05364580902f46e70cadb2b46be3323cdf69619830703bd220c34116fbeb5207f1e9a396f7747e6411c55fb2b36b3723440e68d3353f2016f674bef71286ff0be16c3bc4137ac235e6a47893e71802e0856e3be473f069ab41c53375c5e194fb7fac92a06d352c9a254ab55599beba118788316ca0776618d95e4431980b350d3cd8f649c6e852dd7bfa662eecb966f0fc661e7abb8ebb102356f80dab09001bc04c3034d0094a420c1f0113edee5cfef233c488620e80335192d1e527c434003a9856297ed44e7fede71da2072509d52687928ec0bb2963cb982618d33e751625c69ba25abc4344e9cd64a14330ed9623d47ac3916b8deda40cf46bdfeb3c0e0b30bd8562cde28ed2abf3d97c6e7001a003dbc60273acb07d028e9047171e904bc18a8e60794012a8164850d066f9ce423e0b4cdfcce49cf4ec24b0d3d201416e70056c85a888a18487347f7a325307eb0a089a1ca88de155c611afbc6842beadab0da93832e6d3d167496751a16a2fdb89c11f9d7f99d3a2e53904f51c6ada07ec1716baac568b652714d21dfd0aca09e6c8226687b8fa27be8b90f016d73825de4b5b0912386c313502838bde7af71c394a9f720230a63c2015307e93d8d00e162d8b8b363aed87ae1d796053da7012828a9b4cc70b01b5d9eb39d54213b5481828908fc0ed9ea911546bbb3eb0d68b391da5fb381b1c806f30a2299dd463351b26e4e9f5deb59d799c0a7992a5340e4d76e4dfa778f02b55fc882b77a0a5ba8c7df4714e97c6582872ddfef90aa58d00c1a6e4fad95959511bc287ab3c4dd4ae3940978e372afffbf8f33e3c8c9753cd3929f7674eb8027534b30d4e19a065395b7517d4cc44f59649df2d6219b6591f224b6455a9f4bbdcf236e6d07f846055992f22c849c47103f78ded583e19665acf6abe96b8914cc1cd738ebe2b6b9f399b2417a3c78aef16f3d79571a27407b46b08302747ae3942d9111dee21c2e6296b52edf1fbb48081fd9063f82b09b7010b9411dfd9e93ad632894fc922af52156ae9068711eba306bcea5368eec6b8c1c464a8f4d04c87507ab93cf32362183f99a864d9f47f119b88d0e7a0039000dc0b03714fbba2d1eb96c23ed2aa3ab702b3af7c3fec6bf7c274641a7f3fa480cbfc0d46887bb6a2f15cc351882bf97574a4fdf6c6621029c52ba69c397a8a818eb285940407cc587caacb017324de5fd6100ae6b9b78822d36370ee319ff1ea5cfcf47cb8fd7a4a5ca149f16ab2dcb694de4d5c687c49c0ce0f9e45769b669c732ff919525b965506a2031978fc97083130ec2ca79c34156ee3238f719a330daff720160218b551bedb6eed9150d5f4e4ab6e139d5e709fc424a52232537f8bdd81834eace403e794dee26d45b695702d6f8f7db583fc64cd16fbbb8e18d52ecc6aef49ccf0bb9c010fdd7fc880edb7ac2cf4ba8e1b8eac3bb31ef1910673a9c5c91a4126a0e2baa688f0b67cdba2baeb94742035f9ccac38ca04fab25b12358339f0cf5c1e5e279feac974085f38257399df0e15ff2983e410f433b9abbfd672b8fac0cd7d1dab1abaa683141609ee3004d167a9e8e9ab17c4c7481695984cdec9da65bf46f68963f6f73018905951ba089c734b191733a2f793da7decfac02f3a7180cd8b5b6d53f17737d0f8d140567573da1a7d087363202145bb0a5667d7ded927df27ab52e90e051b4f2fa48a6ca5ee8e070bbcbba09f1771e66700b7a966ac93981ce4991f33094a5df995a216c8e6c0375185e0d20cf2597c6a233a6455915ff7ad6219c0ce415f259734ab8fd1adc339f7bf76de1186932c3090ddba3b4318de9a224c023284d789af8883d4fd5b2b68b78adacbcd9c323f08147344ced7ae19a8edd2c2c23cf6d34de9bb8df69816bbe9eb8a2af71f303c1e8d33b91dc6a5744dc1febbd854787d07cc27e68939a90d1b9d78d024289319468a5df0324b82ca8015ca21d9e550a17dafd7d2613f5d90c05270cea5da4e09f5d87a4b289027871384518bed3c7efac944ae6e70b164026c8f41e6bf0cd515bf123a17b7dd6d7980172f3075135752e295f15ce67e6b8504470b4201dfd2cf16dbd9db970b6a75876e65e5adff711917f0cce68b1354a9670e8f156743b73507aa24df76ead1fb87fc89d08da9b5ceef7dfc8507add58306ebaa74e714444d6a4dd0ba6d90d4985b1e56a23a1e9233b7003113b45b5817ec0fcdc33e1cf668869e526538c4d1a29567a717e257827db6d4c5bdf491af59fa5cf759e5e98a819384ff8517e1f731c7032cd158c2541eaf4aaf45951366f0fba909ef4228730daa00f1a177e78e227e57c97d0a9b235f23acd0236818fdc93e75d0bb41f1882b1838300136b30179ee0bae52331d66789e9ed03717d8535528177b03680b6f1c31801ae52413c5a443ffee337a3783733ab652d8d78d40f74b4961aaf0771c26a3b9cc5f1b24b271ce40134105afb226b88c099220da3df97908ceb72e63233b2b25d78c32ef111facfac1ee84376928f643b0ee3bd6d6c4f5b001865e1a7fa4b3b295a7fa48c28c0c33b6d23aba724dc414550f4a9d82568d310c8df69acb44fa1b61dcf13e12a3dcde46008f61218efe329d57bf28e9d13685d2528462aa109c6c376bd169ae3a01edcc4651ec3ccd27a9cf4960589fef6468195aba23f981eaec3ed4c5b9fdcac05983edc0b17d8f2c672b9d87c43992d957d10fce23da61a213aae749164415464dc64861595399aa8af5b68e12646432d83ffb5b18f33c71cd8606fd75da561a013a7868a190c31e679b433e76e5a84b762319fe96627edf2b2576dc7cce3c531a0cce9d5c89de5561ae940e3392317609ea8667d8aa11356cf2fb4fdcb80e3cf7b49ec9a573d61e602294e1531acbb1163a7766c8497eed3466f179302ee65abe1e3d07aa3bf254398e6ef5893fbbddd4f641175188bc0e3ca1c9394f5bdd4c36cae43b52d50f8be73bdb561dd6a9054cf5e4d7cce0ddcea55c8e6e9a3ad66930b21bdcb1783ecce5b04ffea3abdd61a3c1004e32728aa20a50d87cf3b731947f927103577a4a562c2ef8919c595396c5ca5b8e29af17b5ce3a3e655d6b17043e1d4f7cc6265c909bca5954701d3f7b9558a0f73e8f26f57db896b681dea3054eb10852156df2c4e37331bb49e7de80b579cc471bf2bc48342b711b1bf288f3f35e3fcc9ff31c758fe3db52f83a4fba7653da49205f3853d10b19e49f7af7d8cf01c6d06ef76fdd73da357d98360dd7fac9ba2324b7fd8f317f3192f90f34481c1ffa76396d2ce235d64db594517ff4b558d1afe1272305c99eefbc622fdf20ff1ec6d6f54bdffb761c1f21f54f7ef8fda3df76a4bbbf813f3f0b6db3e8ba34794e485defd858d5ea0284d2059a7f7ffa916f222f27f837c1fb7e404069d2270ed8d0fc1be1dccebe8b9e8ccfaa674b328203680ffb27807f06604d0e64c995362dc9df23fb1deeed8e6dde3323846516d7fd2dccf5177ef3a6f92f3fe5722340b3e14d7a862bd3edae5f408afc89891952d62f63cb6969e4095beb734e0ef238b3ccd88e45cd2ba9ce50848e6d2c85dc62b5e9cc5f8e0ccdae7d9b5631e31edc100f6fc18db3f304075f9788d40f58502687007399deb5ba2fee3ecc7a811cc670174bfaddc04961e2393f539bbd86fa17a9a7c2721bf059e7aaf8dd9dfea9a0ea0f51588473a04abfb0d7fc70ca12e7d6624a25f9315ec3d78ebfe9ab40879921042719d7781991cee1a57fbc15a01191af335006dfebb83f5833f647fa0f16c52f1e35bea537f68a3ce40764f5743d627997a996cf64c827fccc9ab05ee5b02e8ee21fd712ef92b0f1916307628c84d2f39de5fa837a4ef0dc8855b8274e97cfe4e482c2e01fe396b23bd15ebdf1c5a7e7411e62dc9d6b7f480573e6f99de2f77d3a96acbb76e3ab6ba15a61395437a17fdb8d69e30c3b77c232cfa555225d99b48d6b77ed8357810dee25d0b90fcfbdeb9d01f9b3d1bb9993758baf4c1a42fe4ee7a441fc0166c2fb178ec38b73b8d2028996160c65f41744a5fd349f6ae474dded83bb746e17d8ce329d16ef7fb85ecd0f0f9e36d7f4c47b1d8fbff4bdad6bf1ef297d913bfefe37017288fa90d6ed1e4597fc63fce80e16f10e60d58719fa591e8e0fa2ed2b405ee37ac7f1a8c75fc8c218db569600cb81cf1f172fbcaa03d550592178446a764bb5d1324ffb7d779e1e52f7658db5bea7637040cb52fb2c50d62b6d738b7d0cee079fb32ea4b5cc66f8fa9d9fbf7318d14ca1832bff23babfa87ffe6171acec05ad7afdc8bd9cde06b0c861a2435398f66388e9d9389a083f1e3452e9630e0cffb12d9ecc5163050384291e73ab18ecdf1aa0af04518d70f5aa631efcbd9dcfa22687c9e4aad4745ffd07ac31c9ceba9f3169fd98ae62f15094f04c2a37172803eefc8ea7c1e034c36aefbe51643ccca43838f6a0c885b1f035a2aa68714e466798ed3ab414b011255585223f97c72a75febd90073093868c425677f0e185ff66a57abef3c3c9683efab445f34efe685fa7aa87356c790703b9fe571f7a08e904775b1fc408ff8f45ecbe60520b2ca05c6ac707326d6bd235bd3b6b43e87f772c2476bb605ebb78d82676ac5c00b76f335a36ff4f84c1bdbd6f881e19f8514fd94c657face7eaed1c8fcb7afbeec867c0a5f1038775ccd630744ec5f7dc4c1b2fe26b63a4018fcf2082f8b75c821acb5c527dfd73849481cfb376ce591c1a42b6edadf120b7ed0b018ec16b499456e50238656a915308c6d57e0d962fb81423edc6f7ae7d18766589e8612f1c82d6e9beca0706c66a700832e104bfc20177e64a4b45ce807335c9dadee3b9a7958534d7ee4619644bee586447aacfc0c5f148b56d84c456cd349a4f93e47a490c63a9cd570d6d76b6124b9d6fe0e8f072b05a18d07792852e029f268232c123590cf781663101cc651acd44edb93c734dbbcf0bc802166b338beaebfc2f05c4e8eaa802506f47b03a0daff4bf6aa3f3defc933673029518bf0a4096b4a1ba8c408279cabb560b6164ee21eacac6da009bc710b064731e7e8633997c29294d4bb87d801e8c01b75da1d94f9c44254b42a5e1ecd4c6bf74164edd63271d0ab4421eef1c3c8afbf591f29c8ebe7a87ec216b67f2676b8c0ed65962691de4f22ae2d5d843988e29eef14d11f2074a9b89a6f5e85189951b89518d5baa41b1424bcae0eb23a07883c60b03fe0cab18a5e5c099b9a504683a8f23ea6905bfb0ceabe2f82f8c55e75ceca8a867d417657fbbccf346f391dcd5a35f3662180a4ee20af22cd461d0f5848be99a0fa90a2b19880b279b96e42c201bd9508070ed4cb269964b139288e1d9ce05aee2f99ada557383be0ab14e3f9f55b54de5492e32bdcb3b2de1051091f02fc22f730cdd46932fd5345bc6b47d2811d5918b1801942512cb12b2f6d5b1702947ee56ee8493fdc9ab5a383bdd0348fc7c38c21bf862657e3f60fa4d7c7c81fd6c30c18082b0ce526ceabeeda286a9b97bbdbaa387120ac261ea1714cc999100631c34998984b9c58c2b08cafef1f436ef6bd9df32d11d33b5043ec31af2e85241c17d62a06f92ca2a729709efaccb9981fc403e3148e5ea4b8b3299af7a1bd25ced769fd2a3f1a399d651b32c093033663aeccab187cb5c338336d30169602fd2c3afa59747431118e67fb07ebc7bd13a65d841d7d132fac105964fa180803eb420704fc7287d01b31b11895e97677874c8893c1142493eb1280daa10cefd26e2d3366081afb22cb402e25dfba2c55a0ef1bb769061274d2e41edab7ce6cf7785ac1571fbc2d526235d4b32818e19195173cabed4dcdbe61b505cf518625ababaa3a884a582f48e34ba33f69a4d6c6626b287e94b262bd5b1640fa854a4620f611f1f83770ee179ba7eaf42f8ac6acad2d9c8ad032828ced89f43d31f6a04b26a3b6f5698be7550d443f93063b6a49730e9179c41433a33a8fbed94aed6760b7ff646055bff07b5fb249c82447135dde1baae8b6bb79a6a5a45862afb281f11c79bf44329aee7d0e6bfa86194543587b7c5d355df0bd592503fd6eb7321f0a4716c06b77bd7b22721e9d8262cc3b6d62173c8274e6821a9bb628276b4676be15336a6767991f50ce7251c2684c16611b07715d54c56d3bfb690aa6a2701652b5f8c47adf7362811b3051aac8d06655725af89da0fd668e09e663eb1f5151a9b231665807b48e2469c0ae26fc141373af40471994b6b509db33b6cf1dc9a2fcc077896c48a009f891ac0bc0ab974e1a636e0d023192f9db3eaa10296a109f8d16cbabb48196583d6be846830fc9f6bf71e33b2a9801af618719f33603975b7a3eff55664754fff661d0e92ea9d1b07268740ed3420efb50c272136e17cd93e9ede2a9910bc5fd272544ebe716293cbb4433881d82dbc15cf060ecda5b632773bef24484d04f4b2089996f63779a9e8f59c0f04ae5c35d20db4621542d343dafed10f9445b2ffc215ef4304901be1490a9c3c02e20c8b05532acd29d4ca478b3d5bd4154c34dfaa4abedad21ae0aa54c34f56f99b5a51c9657a75b700a8a2777ea3d50db76c7df46325536f14b5b13c325b8147ed0818e0d567407ca7766ef9d268a14be692f20bcf19af0228bb8d75138e698ff95657145a292abfd4111133bdd86853f21771a47189ce1228fb37ee8a442bcb4e8492f53ade60c1c3de2486ea14c25c8724417fd60c92d15dd11602456503a04ca9c99aa85a913475b4bd8ba4d32393729cce241f9b8a7ed96282ad4a539084c25bd6c1b9b54e95c65d51db5fe29f7ab8ad520aa5398b4017d968524d0501e604c2eb89256404ca1f7e74b83cab1b5773232fabf3e06c9504e1ebf161586189b42448151673888853e5dfd24f386cf3a16650a6e809fedca8999f8e428b2c38992e20cbbb0ec25cfb4d2b0a1a4e4b0f18432af7dabcad53c4daa003f7dffc86af940e1f3a2ee1e274e0434a0f7e7ba68e2d3b65c9462d426806b863303d09d4fed4f91eb85e563f3bee761c005553eca4d05ce1e7d5cb38af0a4d3cba72accd1789e25fcbf709aabca89a77853d20d8dbdfa7bb2660201bf9e24a2b427e45b66a334c85b9d26fe0547bfad7369295d552d2b921a776dfad82750f4aed95c74af0cce01f879e6105689f9912888b5b62597708f471f60322a20c61fbce577b048f3922f2a20cd20c8780bb66dea7f9ea07b57235bc4787193ca016cbcc96026eafc3b1734ae61fefe524f077222c37f56a53915f69864d44d29f50e7bb9026a22b4e10a8c5dc71b1c79ad3ed599007485bf522e61f3068de04a8868af2454d9c351baf30e4e25d58ef4cb304285b4e460d2915e3fef046353662603acf6d203a38c5aecaf5c675f3f253e3c52eeb25faa6734c8bdb6df4397ca5d272c90f08a95e61d12a26f48f1019ee01f99769acb822fb0ff59d4894f897bccb2ce636c286549e66a74a9115575b7a248b528e2c9f2bb42f0578f8dd370bc0b9ced98021c6594e994f32d1718456afde863764d3fa1e4fd887938e082f23cd8a33e241791e2b83e1f328283fc1cabac94f134ba0a96a986d7906714cb21ecb670d7ce92b4d54f1a2565282358ad92ec5b3bd176f973c1f5b78eb70e4d416f199a86d6dd3ad409d89eeddaf60ebd8acbc81ed47603c25e2f839a428a782893411dbc695e65da18f6844ec4d462890d8de266f1c4d6cf0b28047db4e80faefcd2440b6880c2c1fa867b9339a61642c5cc7273e8aa8509d83b70953bb2f21e628253094d6b7d38e63be0673d93863f98decfbe44bd2bac0c2a31ae824f972c76bc4852cf37a40260a8992dc19718d1631a8ad77e78d2aa9fc51ddd5fb5916bb03add486906fb70ee7982217ae07524c764ef2aa6ecc74ae940da6ed714a0c440603a63fed2053ee86c213ea689530bc6e2d01986022c0967eb836ff7b42099ca542d7f9472af3770a222144d1d028f640a43b0d726fd95644b3d6f37a1f26cbce8e4f4076624f90f274db768c727554e46052e9cd64108b50af001e6011aea2f8d68ebde7eece0a85dba176eac601c5541b93cc4a7e262d111a312832a66fb821e520454f879631f6df12c590c30bcc305b12ef28429ed79d5887927394d9a457bb0fbe2ae5b2889d173e553186ba591bfb17aabfd91c970311dd0154e8afc3485d4c7ba660ccd49c1426222790270080cf94211814b39daa61e770dcddb6824b83e7393f01f0a981cf17b34dcae7790bbd91274517940c14aa2c21b00971180e46bdd0734c60f150ae7e09780fe3365bf40e5155852b3bf16bf36e2a3600dc57494fc9ab7a970a3faa1fb6dd84f50a86bfa13e1111c584ee7f2af0a4d1ef83dbd7c6a12098be6d9ed2d39630aa649bbb480427d6ba40e140f0590f55e5b422169854c53cad72ec49b71ec0ef344749ebaf01702e0e5c783f4a52bfb9a7be99444df5080740142d9d5dae6d066bf71337fa72186433540f3604deb03e19480001a200ed1b2412c5934e31610e7fd704a4510bfbef0c7a9e1e1b8f2bd47e74f3a2b61b93d64a703853db794d4df6d2a73c1174df382da1f65e41ae6bb00e55f0d2b75aa2026bdabe3fb9623f2ca2ab8983f9c11df4263e91863a4fae0705011baa41bc71d046b650e055ff04d54c5be9dd86d5d606284e3870de3d31a96ae5474ab078fdf2cd5075c22be5f5b51e832d4acce9d91a16c6edbd7a3994d64c9dd31901cf500bf0dbccd8f96f83d830bad3727dea2aacab93f971f87cb3b444d0174637dbd32a687033defff6e6d28fcda9de2bb927c45fcbd31cd6e2ad4ecf8406e036592ddc3e8b3cb7f1ee9c0d3e4d70dc38336e6be047caf40648c8127b5f47696510d0cf4f5a59ac0e8ce68201800ec0f136f59e63d09291cac4d5823fe3ecd6cecfe1733dbfe149f36984668764264c403c8bca39150bedca7d7409113fbe7a3a8630b1eca22827720866176c7f82b1806589a7699f9c07f81bffaf79ebb5755f2f2836e4c157619c0e6852b6810617de801fed44357c6f49544d966891148d78a4b9fa439f046516e5b8242d6c5fb641e175ff983000fcfc81728a091df49cd5d75e7b40b4731749ea6faeca00e577436a38797616c5af357b7267a05831a6098112a3fd698f21a9b35128ec3218833467ee3d54d1a62cb1f0b7b29e04e86fe6ae81ad9e49b37f1c32abc0aa96a8ad89f0294e1e07d94db7114847b405ba08f9d2e775cd79ad1bb618b121d7070d28555df6efcb82a6b403c8a0577300a3e69ab6fb45cf12baf319106fd1ae44a97e474a18266221c214c76814e24dcc9f7835bb3953c3d9d9dcd0ddcd9ea416bb849ebce835a8fea6a2db2d0d6690fbfb1b2d6957e93f6645eaff1115ad3ee3c112a63dacd73d2d9595c22d5d16bf993e5daf0f2dee59dfcaa7b98f7a209e852bf851ffed6c9a7af047331df9fd53d94e5a60286bbbfde0ae160bb139d7a01eca47d886ef60c30291114d9be79d037bdb298825a186a52303e698e333a33f24146792940822e9b24f2f0afce17553465d94bf5d6f7fa90160b136453a2e850b69258f1a05ad46c45359347f78d81e85bf9c4f6c3562de2233e1a3a1300a05069308103f9659f8b8ae07251d4159bb6543e0fba46979b90f9cc0cb209245d80687fb45abebcc3702ebcd8b9f1d19f1f8f13890f8b73154662bba9ea09ea248c8400cabdc3125f89fbff373243cffe10f66be3bcff450f81b95d71b2ef9a20215f943f276b57cad68c05a864f61f210ca4a67ebb228c1bec91ed40f5bb95c9914fbbe4788e79ba92108d61b5a03977974c485b38a6a2a54549c7c82441e91506dc671a729160cbcc551fb51bba9dea7b076dae72b5e2c01f12b74ab45fbe79c5ee58d0443d0c06498d2c1db2d8bb3b6aa782e70a4810a18fe1ab0aa8520b67c450f92833b5685182467708daad74a68c6db01468a15c9caf36dbe96b85fa72c0b6d61d96dde7c703e3578a09ed66ca3539ad056a2d262d0cd1c1d689bf7550bb209ec642e3713d89bdb758705a8c5a6bed6c64bcb4ce88d63c82cc9caf91f18587503570b2532e54653a9ef53d09685b60e118540a0d9a2358f4ace6a63db21be76cc634029b027d0bb457d93957a0310826e848b7a05d61c7b3db179809fae2b91267b6c3cf4c5d0918f8b2cd1047b8f375062738a36e1096704fb781c07f8fc41c0432c2fde97a8f1904b4350344a59df374bc09a316ab7e9ee8882028c450517df32f4d8dba798e2f55a13e31f0afbcdc35e688c25dc2ee0c83391315d536b8ffa8bf4871b605589ff445f3d89b86298ac87bf8391ec5e0d55e6865aedcc8472581e1a9faacd1e54319d102a956b22b8716e4a9eba642c25a247ca06f9c4d9bde7bbed9afd856a3103ba0b46d957536bdbb30340cc9a5db51b0551b65f5d1d18ca41de70332bfe6fc7f7c980465ae152917d027f7a5295e7a943b85f9214bb55f079063934c7e3d4ca7b86b358efdad9e095dbdd5c6912119318f6ddf8f2276dc006563f137dd734e02d58eb576d3b388552f0a2432838c1d2b044ee55a4fc80e84e520ee19b8c8c9a7a267b271525e5feafd3f0ab816524dfdbeab46f70ca39be077cd63d07c2ae52aa0a3993c4d9ba9b8227786d3955f0c18cf25813061ffe46d52f572fcfb77b6035fa908f68f4eefda1f855002bf3aff91932cfce14bc75dd9c1c45d29cdfba7bb50295edaf72f86412f850d79841f1579ed82e97d2cfba42bc96e79d85689f9562e525e94cc6c0fbad218b997077e837de97ed605807db96f77d0cbe97d6dd30f155fd9c4741cc97ff5c9a3ddcd6ef4868135ef9e5ed12b0863d479779f82f5f691dcc8537b6a9c3afd0649bf9dc171ebd9b57e6b91457081d69d617359ef30c01fcb056e30a1605f5300288dd7306426026cf1d0be827f2782abd6d307b7a5500ad01d0594e767f7affbd3de95d05ad9033e37cef5bc37acb0f702f2f2d6a42a6e5940a3b103ef418e781c5dbbf86da7c0d53440d6c927324c815bca16aac299fc8cbf941124bdcbad68cf3b45294f45541bc317eff1822b8b00fe8fe01eb1fefbb0065a14192043784a9e611bd2dcaf48493fc6a678b83099d5e84f203ac3030234872626a1e46f898c57fe23b22368c31e84ffd6fe933e84cb6afbb82014b5e0030e09fc7a6da31c9b59f540bfd8f51b5bb8cfae8d4e507653859a45856301f53f191998f6f12f0b6e30799966341b5a0ef1726c850dc5f9afc9c212025808820a2867272a417fe6a0e9973d59087daeda89659eab3d7f142ebf3490136989f9f30a6618d705c203be962732ff849bb8b8e162e2326a02a1d841e0839a7bc3ce2415f8e0105711d4de2c94722e7cd6c38e82f9e49ea5d5120025edd70498c2c68a7edf7f1053b00a80a6ca56e4d1ce8251e2ab19a1d5242d490e73323f85b89756c7cc511d25d0a524c170616042a47b9017e160616646df383ca04510eec393200f21113fb2fd57775f0cf23e69647a9a96619c8e92bf088537259ed3d4510bf4eb18a909be9d20d6cc03de1b31d2a81b44eb47bbc9f81d93d98da193f6df88689e65dc07e5dc171c9ca12b2209aed493db4f6218570616364b0f26171fb0049bd71b379652140302659ba600ae81077dd5b31e6a2b990e2955d85a8da77c04275ad6bfda9c288ab077bb06f23d2ee1f1f1f28f0c7c9b503258230dbbf9b97793f6ed443769a17be6fe3bb79d48b1fb9663007e1748a8ac8b71c17de425c143b044e3a92146feb862a0e61f76891f7b9fd6f64dd5c3abbadf8f057266e0d6e36f79d1aea7533c5dd1cc5a9c51f00b4030373c2548df60267833afeef827b83f2fbbfd71621ad3c00009eb43c146ae6cf5e0aea44ef96059a16e2ade4cd0e863eec319b6672f5fe18a5792d6e057defb10ea85391ddc3af937608d30bfa063ec3383d8a2b78210a0f9f7c5dbc8fae0373d411b4d0364e84737db91fe73ecfee9d949cebd941f9827db49ff7b21a777bbff1a7a3a0d9c1f35226f2fb79438a795f4627ba15bd67bed49817adeca1fc6d1d4306578536db6746de376c60ea0c1d2c6894e6260044bbdb8bce0428f6296171074de84568d76a154c89d2a870e3a2d3e09d5b5ad99f93a4517116b3047d8a200c3d63a75a3ad8514ce07f34ad5f08875dcd70c63756d57979f2668d42ece483bd11420dba8aa0195a412740926d3d1d40acba5b51559c00decb6c2a1e36e4b2d60dcc60255092ce6c876568d102f86e5afd8be802c4918ff115414fb5deb380180509616c232ae9eb6c9d4588a20b20e212895838ea6a73deff7e8ed33b2624f57e87ef0ed4e7e0b5e2ddf9db83c9c0ee4a9e90f7b327c450a5c11e7fd9ea0ad0167be5bd7e77310de0356d73e428ffb9265ab09819d4386f2b8c0abe0e76e9f28fa0f99b5f20b2454b20bbd700129970db904cd3ef459951ccfe7e433c9bbcfb731225ec404f9cddfbbdb1663c074c86f40c6cba396cc2d8ef70e47520f8fd051c6db219f0e957bcc9ebf401539d60b3261b3c39b73c21994ffa33cacf2013aab2b4b81f31ace68fa42d79ecf34b800f07c3de7d57f5de846efc4cbeeb42218c55cff879ff9f98fba598c64e3fb0846c49e863568d8c36cc1a74e094581a826032250fcc6d57ec86575a2143728a5689d7e8d26b810fc95ad801ca3e361259a755bf308925c868a952a108048d0cd5d1829687c8a02d858d5448be0557063ac6d2f705758df33c048d5d580041fab62e8bdd30f9658d86ebfb4a5623d3fe7c7b9ccef1165ba970522a173532419b423c0aa0cc02677fcd7426f5f79e0794fd39226d9c36f3dcbc3e0bd7f2eacb777f47070ccc5fd630b7c116b27d748ee3b23ce7fafb5b6dd0c62bff6e776a9554ed6e7eed7bfa0aea59b240907d8d2e3f94bfd86df85a9440574fbb953bdb424ad3ef22463dd45ad78f7ced4af1b2ebeb79b7ced00f1e0a6d59f5f1bedefda4ac39f85562ad6f533bc6dca4c8cbbb181f98b2e2523322afd409d79c2c7bf20c23e9eead73f1e5a17571773a7cf0305577270ccbc5593efe1426e00673cd65db7ea76d14355fa093b51c6dda2ef9c3e3c39f762f72f7bbf14baefab48a61a6220795b62a8055fe0ffaef864c4b120c373056e2b1fbff1e5871f8e740eed4fc14b315608dae49fa8eafbbca737c71fbfd4db5eece9e0fd244cd24de29ef4e821f73746039817ecddf8fb04fd09b243cb7a831821db562491562f842077bc0a7e542c0b9fe39d38e0e17276ddcb4fe52319910ab6ba84339ce691122ce73c85b74bb5e51b02a8df9b06d7af63d3be45a6fb999d67035521264ded35585e7cd2bd2f47eb13e7352868d4ff5893c2e22b58edb2a2186c53907d7f4174bdc10cd5d5a189c80b4c3527675f2939e4c7269c798e6748d625e5812b28ad5871c434e95320cf9151ca398e6a1cfb690c14caac1349951a29746968fe9dbc434518b57a8e4a6e5ea3a96e8be9c81e4a26893d35e3c4964a6d9952a708401e0243d1bb8b69ffd5e87d093d06fe3a2f6da27e10ed4bbbe30bb660efc3a47da0f83c93cfaeed2f38582b1d9e0fd385e5f5526912e8833e7602fb02c7c945625a4f59a17188e6735760c3cdc1ef069afa8c46c0f8dc48b04709f857be4177e1f3a51fcb3f5a6fca9b75d793f7eaa25db9505b58adba3222a04f194374e68e3f37d288e28de19b85cb42923674c921674346eb604ea923e88e64f01ea21743f2aab1ba034af5934275fb1f5dd05e326257d70ef9b5151c4cd7ff109aded8c06405fce557d7b613b8f8a4daaccf3cf666e7b261f3ef51dd9e2fc86c6f08b437dcf2a0905fcb2242ba5b7ec96fffa5e573ca3f0a3de03006f7e3ef28a748dc8d694515d1aa669db669d4f9870f3890974cd94f1a45991209db3a58bd41cda3e7f724c5f7a95c70851a485291b48100a4db000756de18999892392cfec08d20b95a8664ce2ffff6c4d955dce73645eac284c01c36d1947db685c0e6b7af112a5bcc22e903815afb4feb295042bab8b42d134b9171ce9c853bb9bbe6b08b460fa5c3caf30441babbe2f6ab6d10350938649cd9e121a690df71314aba47c40a61d43aa7df9ca7e0c858f7cfd8e22826ee2f067673a6fc6f92e28aa473c4443a9254e41e62fb6ee86b6755525bec377be73d0fa9cb3ae0a881bce3fc73177fbd5b8fc4bc21367598830b0caa3c9278a41e012b01c108b756ec55ec4a0dc5d3a91a30d54d2fcf9191bfae0ce68c6a8b62e8c840956a610025758b8538dd6afbdd0e2c7a408ed568feadfa97b0ff65a9b55755f6c32eb2c4aab115806f683d0022e0a0983ca119f994a50cd05ef120f4c81dd4531ac00a26ada6f0e829dc280da52506ca74e33aef2c53613cbbf72e1f3bef2f0ef3970de412294e5c141e18e76993b7c90961399b0738fa72d556e23cb24468d312224c8babc723d42aba1162e0547144b8887bf31910cae14e8f2822cf105b5c50b6b7783e4edd50f0121b5dbedc5a39a3509babdd391608f1f5bcea95b2a0623040131c1126be864c3594fdd04796dc9ccf313c86809d5fa9bc47805cd665889515be153f2297684407e87a2a3e8dac0ca2400a7d51fc32cd462faf9ce6b44f3f7eb92b376e2d3342383f836394632b7e4dec0ccd657c0aae8bad87b0dc7839edcd49378c3cbded3da24ba1dfcfec543f25de8b5fa1d6819772acac5c27fad90e85d74febd04504f6b315bb4088a541a028df47822ef221e36dcd380c27bedf6c0da8afda7d985f234d6afb194bdef5badc5184c74a2041f9dbd7e78bf844e33c65257c32ed69e79c485977c6bb5a2f181bdd85bbfb86acf6f0f906b970371f788e501d9af562e0c2e9f0ba5fa6332f8898082a4dd019bc286c68e4d1cef93d9a574dfb1bf5fb74f91600c2410df7606328d84cfc47b3144471a20b5594c039e9c4d771ca07a785b73aa6c5804fc7ec168f4f883517a59ad1cb18cc3603196b853a8bf170453c7c68c8d6eb411e1e0664b0da737a1c04f724c3f350970bd8c9205b2e7145677ad30d4b486f1c8a3e89141f165eb16c3fd7eb01ea128ca9b3effba26275361167302050891af72b603d7a2bd7251318518211257a5fea85916eeeeee3a3900b566ac74802e4d60861411af7015d7f04bcb01f23248a84d001488a963ae2310175cab1837dbcd5bdee6bdb141f5d56151c8ff27237ddc19e4beed33bc075bb5ef7e9b07afe8ba101efd443f5b3c900e07964deed0b22d96840ff9a835aa6442e775a8bc8a2a025f1079abf471130064d134b29956e394d80072e297116dc98e334b5881594039e4434d4243809066226e7c8a27a9c831184ca8073fee1804583f27965c1c3adb702afd8b4f04fbe8c3e84427de328a78b35f51d4eb6ec019c3da17a933d169d0b3899938a60a8d5816364554de036747afa916312d6f72666afddd3d23361c697eab4bda58586269858825cdb0e9bdf0bd57a4641f68a1674195c3dd0a799c36f192f636bfba5292f71f0a916d5095395d874299450c628ebeb36b5ad14745b949f5e90057140318e4748855f43bd01c9eb545a83b493f6061a6d8c13ef146e7be98cca585cb58f84b93c119c9e1a86a1d7fabbbcdd7d8ba53ab31175fef4e8a7be4dea01a252bd151565b924b5d58a833c508da12c4b11b8205c25d0e2aed98dda6cf7002562f125edbd3b9ccfb9bf5036c7d4130e7a96c6a593bb33b77945489d27f85084f401cbad155e9ed3d873710b72b55d19a38d3ad76196b516b7c98fa7e14ce839b450ce52af0bc10717af6fe48ee8376399bf4e4a9214961b7c7ea4ce98e411b0ba222e518a32a46570927c4014ff3fa8020ccb79ea62e0dde45ea31bd3c62c5ca330f1c9d139cd201f047c30f01cdd1e1a3d1c90b55154efc61bdc94025e5e6a9215ea7f8d3df9f4b40fba0b009ad5e252802b3a9cd2dcc55dab635a52d3ba2d4c30cd8432b474c0f8af0ecd424d36ea99d0614359ce382731e7df67d2210ec3f12b05540dc2c3df8677f826d0294e9f074715a09250ce4430a82a4a45937d1e66faa3d73a0076b899c826c8777bd6979658c46fbd0d8fcddba13099430e4fa759cc45cd1333c6e6517be28a72c78b4ecf2a788e2c8ae6cb1fbe798de847378bd3e8d31e7d7c13e9c5f4e4c62e0b329007979c1de1cac1721bd1f282b60175d31771d233c782008997b46ecaec2a303b2485b8f1c95eae04b74f51e629159da5e122e680703eb14fe31ea87bb7c9b60162c5e2d0e90adb71694f054f508057e350ab3e57032b0dea06002b888e8a8b0abcd83e36a8bcb5db00cbd46ffbb68738e035c3af9e8aa77aed3f40794b98ed8897e6bcdc5038e191b3c1b5e0708f65db2d77579788949790f9c361ea9712be4bd65f5dd9888809e68ffc1b8cde533c359b33106da8c7b4ccec9d91b1ee61f5503f8cb8d06df2ea15c36a18ecd847dee8b359aa27ed634999d040dabb1d6bb49c560fb71c695fe2cd847ee56456191c90b83a49a060ddba1bcf599ed9ac1a3361afdd2fcb7685287090d55dc6660ab1c8bd3190477e49f0add5f9ed0fe11000ac7a74026ec4716ae556c0c7e80f5a85dc581234509253c1337975d5fb7958f15c7c5e60d33506b64580911bc0a688a0c8794a1167b5f799a0c7c101fdc7983e379da9387bd06d82a6f06d9ad987818831693aa6b6fba36b3bdc769b812e32b49b63c4cbf82cbcb761d2b803934b8925392684ca38a5ddbccb2c77cc36879b7965a5df9a4cc364b84ce241cd3ad0727c10ef597605062aaa266601e391684dc8cb823f4963a658ef685dd31fae20a6f48e9fae15a3546652bc4093f8e25ef2006c4a37a86954d1413342608a69ea97be2017a1640d701c11703cc972ef8a502795d56f0aa48dbeb0c1d2eb0e2da518be2e33cb137013c1c481100fabb10309cc3c239f5d33b333576c27ceca458f37c4e6c05ee45e6261ab5dc727e68214f9ff56ac00e28021c59e334133818f62beb61b6b1321f14a24c18b92663ab8b4d73281a383f55d12495a30417960f924405d88e00092709dc852497f5c0eb205410c76845c7634098808558202d0ec71e0422760f9d3bb7c32ab39ea98411dfbaea35f1cb42ade45003f2e1f75ebb7cce9936e1dfda779c4cc961792022c79d5a223790094bdd873db326571d3c27b97aabe639a48a9064b9f0537cc211b9ab8d292b999de2315b477d28f4377a180c95af588e08d59017c4ac1842e24b791cc8c04dd48ed5b1bcca761d7d07a35a446f86e881e3ac8ccaafd0febd616c816cfab2f328c6b38ca5cce8e6eb1c2d6c536ee7e72d46c65c9bd42951a2eaf75ad18f994789bc7408a9a8514aeaf372ede07be315a1a9053655ccbc0d33008470b4860af06b94be8e43b6452620fcf04955cdefd2c0828b2e73a519c80c23b738fd73c2f40d8531b2392e7473bd7c4f80947927aaa7b11aaeeb30e158b11e184c292b8f377613ab34d22a83752d34eeb1885fccdb7484c5e54fdb9151dda1f2ccf8bde08ffc7e4da8a075a03e736d230604df42a1178ad9f5c6cb7b0b4319b2462ed569b48a192fa11e32482e6e72bcf38799a013200c62ddce22e5cdabad0e1b7dc25f6ac402496cec5f2ca6088a22f118c58b0aa42e31013daa68a237f8ba27a0082c7dc5ab23b8492429b882604039a4bdb76236a2d472ca3ba038de67bedeae3603175218910ed106334316e22d7e3506df4bf25d0eb2cbd1a85681293d169ca82f8946116a47fcb0a139cda56c6d1d1a3858169cc5473d29a0f03e2386ad0da25e69a54d6c41a920394c89db31ffd69ad80833019e8997d012d881b3b03919c05a4d100572ba76e7ec12b707f617ba689ce358cebb62684cf7884e193c0d49be431a3ac7bbef9a6396d31c67e0145ea618f438f581fbc323a6c5a53cc43b46fa61271cebf55dec5f45dd14bb1bbf8b2e78ee06f5f9b299dc085ed43d1958e865c9f8c32d89458d35ca95cd68edc02471d58675d16c6d10ad39d0ff6f764aadc54bce618b61f8fb823fa6c71bb433b17480561434e8a8696428c805946ca7433ce2b36de34cecb8ef2f7e9ab280935cdd0ca79d01db1531045938f24e3104eaf29841f2db80d36d0f816d0a14ca103de68b6284915e16bb0a138a8ca081c92fdabe23aec18eaa7106f1a05570f365861c8a83eb654a7882553136f116f14c7325461ff3a679ac19545cf438f59a71d62c243acde451708a335c5d40a3dcb466cb156288316ab17d080b581c5aee3b8c95162823008ec4d961415538e430cd73f971b30841baee5f441ef5760a2f310c4793067e91cfe88b26700dcaa387596492e046818e44588a093e07a94a38715fc78e2c27b22179fc13614286048aafac5eb5fdc42bd1f5d5462d03f0d9b7e8d2574ce602972284d4791d695f21c0d290e5afb04fba956534e273cde6fbab9f198deeec9a8322171b5b126d8dbcb40e248da4fad52831d9aed7b30621ccbc66d92fb718d5526acf12292f8fc5f5703d30ba9961e1838cc8cb72e4299292fb7f369e0ecf8efe50c2fcc7feadb33e92bfdb5d30f40fe79fc83befd477fbf8455eafe3fdd0dba97ddbc17f247de6769a9be7f58c2451064785f89f9e4ea249b266e6df1f47553eb976519babbd3db88a90bc50644d6fd9aa49f5be1fb48a64353faa09285fcd5aa028a06f7b14abd4cbd21a972989078f6e1af262d539c2e85c863a6391375a74bc4e4e9d5a0547d0540126494fcc8a17fe82452597557e86a2b41cab7581a4a56a07c12efed8ed0a2a403f206b11758ccc405fb102d7c2bd3ca00e56e681c8d49a26456ec578e4453666c2f90bbe2e992030baa4fa7cfb416dcb025da0cf1e8ab20be582b23e291ec043e2ed3889dae1b3ec5d07fdc2999c37e5e7c2e11f5430015f256a6e0be964e70954eca1479b7c41015761d32c1f2ef3b6466c693436b7b22afd6e4e026cc79661e79a74f396609cf1388622574e6862570c51cc925be48af6987876c40d1c5a17bac7d0f9e2351f2969402909fa5db201bd87836e6febc0a2a696d5dcf530e05f55edd05b14c39d1e434a762d8424f02cdb0be7dbdc2fcb45599c93829ec1810f4dd7e879c943843e41be67409a5eb80c3f8fbcbe50cc539f76eac165b97d36371604aa1cebe770a8b820bb013f065484b13a37ff69eb823eb9d699d8b93decb3d5e3e89c545f37d106f06abb55ac59677062924da45cc5740322a896f99906e7af12297fdb95da055c6ca2f66372d48e4e20b5e033b742492b2f6a8f63a21c8239f1751ef0e686e6369611473ac32ec8f2070debc93e16903fa7c700b1416c3e1a1e839ca9f894008b5aa81aa973fff28a6713714e9424a6c6a6c737b22db0587ab93cedc941677b1889853a51ff0e8fad99cb120fce3ce08d5249cb5d5e6b43fbef0f1ac2d1d83835b50462768c267cf2cc9679d9193ea003965f5bd8dffee77c502a15f7ec39702842a35d7d4db9bcb7e8bcb36f757524c6e1fb63c4c17477a6a501bba208ea0d23afae509e846ec8489ec78b5b5ff9ecc17d4da984a30ced8bcddd5cac72cffb67ab182f60992ab1a271571e980ab6b1d2d0cf5ba35a40961a17a240e5b7eb8a127f84e00ba3ce7955ef7be712de81cffaedcbef9b72ec9afee64eea0da47d5e68bd16e82d4a78fb89ed16d31d84397150109dd8d356e0bfc8f105655e7a4ac4e5a0abbaf2ac3852adaeeb2f9d3580dffa173388e73c04165ac3344f050712c734783d0c9381fdf18062a6a907c4ea35bb15f7ffac549c0bb5a8a0e2a16f09ad4e4a80758cf30c5cbf3ccb3165131302954f9dbb392bb15f97fd7e22a086a58a8341f43d54c56d008ac39806a66368fdd0507e59d8c9090630c8c869ac39b0c8987f4e1d7733de915cf0feb131f1d59a800aaeac5d56bbdf0ed265050a7dc5397cd95e8bc4dc6804f374ea3c81e608e70f0dd0396c7257f038a1505de92a8e557d10602b15a6d6d4a89eb1478bf75f8811b28c94bbfe4dc68990db205ed7cb578902dc38e1db8773f7f26cb212a77ada695012ab4030360cc10e3a348b6d08e7bc2e4c1e2c9bde772e198e0938a4e78e1881d34ad251425ecde8c9ddcdd3c28b092f4834e8d0308a816d82da9089c894f4e7748c802ed3d547336b87956a2cd000591ad8966809a75ca1ba3c53eff574c8b3687a2079bbbf1163f982e96e8f98ef2189cb9984271ad6859e7a1ebcf7d31dfa24ca80632f22e16d45daf2fc09b4847fa9d61c91d1667f374da3146f37322b2dd217cd589a9faa4111f1eeeb937fe5f9bb8fb5a8be577f96ecaf1090abb63dbafbd0c64cb29caaf3d52cff362d90bfb2fb675151ff9e0d44775eff9677d1f9c8f874ef07fdad7d1029f7bb8fd55893a83b16733547cc1e5b76b3034a40f36722d9cd35775815deeae0ef69d35c367d3e309dcfb0fe374bc72dca6f13f98a92b14dbb5a1cfde5fec7b5892c6fe56500f2f58f35ce27a2bd8662f4a16052dfa408bf7ad2ec0f05d771720c41e4883b9c26a20fa802d7cc465c75e77315f8a81de127de34339e672eece69f90a5939ed92b60a61aff476a409f6d341355d2dfd73c6eba75d433aa53efc338604d9830bd690af5605d7cdaa50f05d4d45cfca55149e8b6d3a428a9ccc457a296bf864a56ef09137dbf8be828a20145b28a232a18c755274911177053dfb0f442404d08c99faec514f1ec5e361e7f69f9e648a0c8650ffa88fbb7564ff6dcccc0510b0ddf1899cfd13190c0900f9c902106e7804c85ab25aa3010c6aff1f70c847472c6a5a363ea2c29c18862ac698740e75ee39226a60ff158f462f196272cc36b30eea7e0eb9a61c792bbcb37584a0104ac0a5223d05357cb7e3d25d5c639d2fe62b65baba0f997b89054af1541240cc440c25a944b6e7b8bba7d4d5de8294f6b9186dd2abcc744ecdfa417eca87e231297bfee5a18faa8861e35878ee23a5ac8f004d7c1490f555bf7352dc3d2123a71412a6bd264e45f920f8c783a089d9039c20ff4ca34be5694e19bab343da2ba083aae1ba3e8c1d78e3766a2a1ff798b99e9364bfacf810a98e4c29ba45c641c49c97fc32dd50ec704269ff426534858a3d42348a59867e882efdf9cd2ce35717ef7c236980c782827f0ad801cad6b3cdcd91fcb5af7e430ec58b39c2d197d3d635130a9d81248d7105c0727357ff90ffc49eb9b25e73da335f20df3548c583a40c76835dc954dc16b09f261c2179d063bf6adf9db5ce662e3b57f575f333d64c30768d8955e50b386735a97516fda0a32176970a1f5cc9ef9728e457b502197268e0b8c67d213a8a1e985b5660c294a6acaa4db559cd72506c6a53a2f4a3faec981e3d264831cf886cf78e2e43cd080863c35a9a9f378847c73cc0c880ce90f4eb424d28e8eefe692f0199ea5e4cc51998d86760c25b36f08f28b7fa79b819eb9434b7a0acdd234728ee3cdd6b06d5fa5ee5229ba9c1ccc4ec3a97c9ad4573a891497ed2eed55cc5856a62c2eeb78600ac15f34ce497af7966c379d10a5363127fe15917cd16db0cb88d5c719eb34be0cdebf20c0e56f0fb9601849537f6fecb9ed3b07b9c15e3bdfde7af1edea9faacd18984da04e7196e3a65ef7dc605a72dd39ce880f582fa0dcf4d202ecb1cceb3e142499be7c6c723f7e8f6309327441aefd867bd49f6c5a19da9f126d9777e6f26db4d029dd4d2db576974f3f94433d718e3f2e0cce311c312816836c5ed71545fc55ab87b72cca197d5f4f897cb614e044c343a1be078cc876fd6d1b53397fb72ceb6406578e710f439886b28ea1705354aa86dca6c3bad5e368b77cfcd6b6c110235a156e5615663ef8a95530f28c3e0f21518e4e5f7cf3a11c83545e8f2d641afd9cb6d3326f34e26792601fd3ee3aca922ea33b109b2aaec03cdb90cf68f908eb3f493f29d392899d34d99610c5d5eae6673906a6e345f99ef5a928977252f2c9ec23aebd5f088fac0a173fad8b0a2943c21dc6ce34aa0a6535bbf10a9cda949a7985ef6ea525ede16bd65a634ed5abc02c639627231ca266394655e3574dc6b1828ac8e8f541613a3f75eaf6f999ace9cf6abfa2ceaa255051eb969fc96d12cbc32f975867b48ea8dcb527d0088ddb27c90eee9bde858ee42b7dee82d460db976c75248c7c176f810ad5ba4d25adfc8c8bb7770454a031fc2b02f94f66dae6baa6430cce54c9b6bf1d29fbab1d9e08d4a1a4bf403fdee2af0da239c5e83936708b5f345e58a19ae687333f7cb8b639bf8832fe41a43010281d543de64c6e8315e74a7e91292c373ad5dd9908d9a2807a6058bf0dde88a96cb43d489ed2cc65d585656bbced4666df8ce0cb856bf8e333752c9f1a78127cd0f114f89bed34e33f55d47bc2395d5b640d3d2eb6d93e177745ef74c38cf973ba441555ea07abaf1565ea6f54b9c373fee9eb9723884861fb5f1c67a4906ebf3e6021e9006932827a3b5da09ed030bbf275cf93e0cdee9c178b0d7653766be01d90b41589001bc0fe054e8e6a7d5756d6a8767b2d536a3ae1f8113ea7985b28f0d151e99b48ee42be76925c53b64054f29dad2a1b449cf12f7725971dd665f40c6f5d3e3e848ddf49696faeaed0c4de23ae17ba983c5a6274fb2385ca2f3b970fa2889ea647232f0973cc616a1416f1e451af38d6c1d1715a8f8f89ca938e6ad10b34c55184fa945e206b0da36e7fb8b9a78876a7bc600a9c2c2400010d4b5090870adaa27eb679c3276c6d3fc57f950eac11bba67dededc0e4620d0cc7e4eb2753edec9f981e3a286072d397b678cebb38c7b39429f403521ef0442df355af434e07efcdc2b60d9dc72a342ea304a9fcd3bcaffd31486d61e9304e02c07cd118b335217fa5b8decbeec3bc12d2fa4185e964a00ab7e0920095f5d0792054c78fa3440f94f5bb43e1583fda61dcf3385cc1ca552eb71ad00b221a57fa27218d3db1737411d9f73bd6f93dfffda3cc05aad52082ee282f61abbf2edb894e2b27ed8c1f73fc7d22f1e087fe158dc00b7a99981dae323329cf46a03e0236cc21c41eb342238d28edcb08fb1323aa50fd91f48efb5a7afeb0de9c6f5cc8094fe33c419b1a55de9bc61f10ebc94d6c18715ba44748acebc2d117bc24d5fe8bb89fa840e1732ed50314ef1555cd6b31ee515295fa2920a7faf72d4dc38f0f8e7841a3b01f83842457fb3f6f4f096300016096f71aa750cf2a7100a9e570cb6f16a9b621cd7c1630310579f1e5d8c6f99914e5571b864d1a4e19284f0ef4a47e85e29e17ec97427500c32373d8f99a3b16ac3d46f41ddc1c431713f487e987f7d54e6865d9c83596e9ce9d41c5876b918b662b8c20638d60a1ceb435e4f6fe2ef55f56352e1b68a196a777b9732decfff6f8843f79fb5e4d08c9179f7ff3abcedb004dde60e304773037b621d58842ae1c76e743c92695159f31b091bfe39592da07dfb0d2c7dd649ed81de6c35a1ad7e2d77098eb1a7ff148197e13330df66473e8d7233bf4b86d22377200c8c9bd9da8f2d275d4ee1e2317bd749ad61719450ea8b51a62b048802670cc1ecbaf545797e4240b4c1d735211d5edeb36b90c22c127e6bed01339f3c8a7e2cef39ac677ed381bd613d31a7f80fa96f750b5f8434bf584eb000178196af01d8c72f00875fd7998bfe82db6dc2ed1826698a3746efcac5415073606783918ab997ea0c66f2d9bc855c1913186445c6ee69d9928cf17420961fcff4376058f42cb96da9a3b0bc9715fafab2491531c676f182eac9d74313a9b7c34a858bf382c4f1acdf77cd1b2f5f32b7326ed1ba6303a74e3a65c8640904e334c64a540aeda1706eb4f8816677a5a26cbefe59bc24f1fa46b8d70209c3494677069097cdacca1d62007aca11e4e821bb184e0dc29428f2aa971ce8b2230b53724a8eaface63adc2f6d9472b1c258fc0b1c9712e87ca63d3cae9c4f320c41f8d4dd5fc7a4909f9c636ec445523e3004d705c0c28ddbbb582d9bd7daa3de8fb363a62e49be4cf621d6221a210776cc9848ec6f8db2586d8010c06783e7d9e64ad233c6eaa3443fb31427cde7efbefadcc423507ad1dd0800dbeb8a6f22ce517e2b8a3bcffab11a94365ee58545e11f61e389c8fe46cd0c5d82e44d5d8ef41be007518ee7aa9b70b176a19bc0cea1d2aeb52748205874a055e5a72c6b1df96696e919977a449e4d154ca277db758f9df7c7dcb243b4eee6892d06030d8f7030316df4f8a7fd2c326b1bbb591ab3f51bbd7d5cc7d64625cd4ee356d0cf7df4ba8f4f5df29ddfa4efb20962fdadb30841bcc69587b35cc9b7a5082134cb54ed23f20b38a96f5d562e19b3261d2729ee7a2f49434303e3bc9ae40c96e95743b08e1ef7456add266caed527e3ace2f909eb6306829e79762bbde53135f0f50738e946dae1204fe8e559e36ea4efe43a8baa724bf6fe35578c13fc40aea0144cb5d3cf679f4e4ac71fad55afb393bdbdf13d11806cf5f674354888af41599a00939fa6cf0e23c5601901a0e318bbc66a446ddbbd7f08ed1fccddf733f11a6a2867c393934bafc2755e94e9bcdc1cef269159be735079f7859b88ae9d100a1f6562820e22e3b61627aacc8b78d35050b8ff11665e521d60ea04c568fe154d688a325fac56105ce85a26c0a0ffd965ccbd7c3189d4972b3ca3a4a7407152fd11f84533e583ff87a455d0e164aa65a6a302a156f7e805cb2b90b6ef947763479d00ef69d0b499d3aba8c6b2d28e62340471de3ef9ff2ab3b530b04bb2468b985fe915790495154582fd45a12ee534f535e889e530008e58a3ae7479d9e187fb0a2b9456d3cd2112c9eba4ca00de6d95c2389f22d48a02b3706f83883670fc0c1cc3bb8cbf33088e439a4e44d6adef2a38d8a1e585450b3741e1d452dd9917525a146bd703e507f0a94a3ecec18dc234edc5dca047c456fed1d23645c6f1920dc52a85d903121bde858c07e2d5dc96e1b0984be128a8e802fa297798734481a0c5cb8a78d67908abc9277563631b50217aee6a36569a89b5e6223e539d75ebd0663d9575d038821f314cf67ab35ce7496e3bac01548adb9a66a3b8084934c437663e0412c64737accc419f5e9525981038aa113540188c1e3a4895c205fe9c4e3896ba6ce6c20267bb049dd10f60220aab132c47867a30b2f824d6138a11a34dacfb3fcabcca44aa841b7b8a5e3f7efd54e013f3390ef3cfa2f0caccae1bbaa8e684698f842d0d8bd5cfc3b02286cc7d5c8c1574031a309662c1a78260663f8cd586ec7521e9b99181814b9fe690ac1d9658074339c4aed59f7eb0d2fc43541927e4282449f322534f62d73b22893a2c72ef9cddcb44713749ef83f801f3201563171a8d08d96f3a3cc584d35f5f6bcf9001a686ea639e25d86f9296a95c6b50994f5a6d383c93bcc150ca54ca464770d87ceff10b30509540f3a12ffbf44541d96ac5ea48de2658dbe6c5f968924a2b5815ab53fd1f7d9d0519ed265c1409af73627ecd80ea7fccff456dc0d5e12ed3baca2c4fd4fa81e1ec468be957d52a143f88cb54c26396a7ce0e7b2374e7f2ed3829c4f3c2cb95c094d47c8921e83d9d2f907b51b50fbfeb28194ffc37afa1b280f6fe34b1aa825342fca69a1c60c7335b13384fc81913d7625ca0f30befa5c518323b5f530047395350e5f031118a94bce420e87471afe57b2832bd01b8498a5cfd75e3e34e7a717c30504e712bd24ed71839056427a14124a3d140fd27ad1811c60ffbf519d7e7021f7677d5f8fab704077ba084336d1df0fe0b134e1d63e6fe6c21ef21970a5fd8375e78fc2bb690db52fad2776aff4b722b5415b12f748c5e3e4ddb17d121d31656306cc23d2543006bed5bfb71d164fc4ff5f0ec9004fc7f2f6095d6846e0146027b5597896146fbba611f9fc9264ed7e474d559111ba9e9c7f8300fa58bdfb66f56c6139a7aeceef572038c8212d080441779ae5b81cb7d51838019bec914c45b65e6ef95aa5a1d37403296f66f5e6c842150fe8b80e36773feeb2bd2da002a43a600f89f45816ef9c5719723400600adf09a50c921ce4a7d85030ffd47b70d256c506fafac97232744e0d0c7987fbbf58cfc1c59dbcc19e19694b586d7c4c8603d49a5c870a9314af28debcf4c1f118e95036256a44672642c5e0cb1e2f03ded91ccbe57e194799ad7b1b84fab87f441643324b616dd7b8e87ee176100addb90910915cb18657b3b5265ef02aea4342fe8903d5e9e0372952414ce3c8093ece5b7a0de475c66ea1f0315e78affc3fd68fe83cb324532d692fdf6ff1989bd607193f403effc4855ef0cd9906af4dbf42fbdf5d68f89b2efad38fd364af70924f8185c298f622d826b93adb16f331d85d573e72d563fd7df1149ce55a4a6cbf00bd071eb6052142e8a4ccc732a2ae71bf45684995df516f3260a8f7cbbb23a72044029a64742ffa1b46c8313063b128670d7468d3a2d825c49238db4212387ba59775e0c67665a6a5437176a38d187e1a8d31f450994e1901942868bfd4cb31a21fbc9abe01db9853aaebc6f25363a77e24577f22deb7393cc7c0758fe0e0b77803bbaf59d48cb74cb2585194f5e34c192dbfec8a57599cc6702259f5a9ed46a1cf2bf2d92456079a420e3907f6c912c3024b9c88a91241a2949b6eb25fccd94bfa9cbf7f807fe6b068a9239f8a368f8d08373a9ff7ffa3ec7228194ec659ec9a01905fff4616a84633a85a39f47f80f4b181b1c3e81f1a7d3f68ea7ea0c7955ee76337ff22bc43dff7fa01087a1223d6f56b4669216f12c58ff0b0d13cce2a8397e66b6511d041ae7fccdfa5da17ce21f6d9370e3a2c9e82fa3cc9e16e0cf249ff335d8d4ce0c0024f419c9e2c1bc115274c6fce470e91ca2221dfa0f2ef320d761c2df492ecd6f6f7ab8fdbab5c901fe3df04325522291e12c3e423cdd595e742556a87459a2c66f1cf6598c8c3a80b3bc0cc1f8341dd7bc3f193a4c460b3ffe8351168d42b8d33715c81fab15c8504589e13cd01aeb7d1a46a18aa1bab73368a10e957a7cc4ae182d6765f13eb56e29d00fe7a7d5ddecddc1d690259981e0e5ea0667ffdb707546a9d6fcb711f8f44c37b1d862d3bc73f6ba888cda94345b131f4174ebae1c46ca72448bce0ca62ffd884dadef7a7e0f5c947fd4319070c35317cc89b1f5eca5aca05a92fcd19959a6e993b8b2ffed3f7f9a31f8f41415f8465dcf12d0408c29df1e5601a85b63bf05e6e4d8bef77caa689671d53c51b4630544945c2a88455bb5cb920ba37828fc1db7bcfb8035b456109a4741830143741a6b4e13e21dfa4dc517d5d0ec65ad599f9f8c38164cdc9eeba0d9d088fcf6b822df28849927782fc77c46cc00f42f11fc00bc9553239b9304303d821c5fa195570335813397eaf095fbf4ebdb8cdfd4273567d451aad9af3588e1834f7f3bda9c5a31a74efc045e511df38faa42fe270ca6823ae49471bf39fd34fa5b645203669187cf57d21e43fa7e155fbf9e9ad777512af5b72dafdb53e00c7031fd2aae6d8422398bae288ef76915e72ec528f2ce241f829953c40843172e1c36b67a7fee19e3e2a58acfd3ca514d794e2a9a47866342bf7350c6969c33eca4153893122663cef739d92b29f3a9b9a9e1c6ceed13225e76f2f1b8d77361c6e0534d355a51e667b9ec8c1834e69cac2794a8f867045b133cccc6116690acea4fa0f45677d12581904ec177ba2ecd2eca6edac3b74b06797cd30d5caded732be1974c29ebf0aef875e188202a2484b3f49496a01610be5cdbe3e64fda76e409fd007731f921c9486deb4025c0fda9cb92090a078a72bd41a8d049cba5724458b92b03ee2dc6eda2f8a524de8591caa050f0e9c7bbd419fba391cf5182e2f4cb4c93b6d12799422509dbf4ef085e096d569dc63979e8ba1dab6462e50eee1f20a28fec9e16f47451efa01baf0248577b80230eb5a7303d392530ef0edf9af3bb01ac0092aa98552258fd9c6e03ffb6f9136cfa4bb3316b50d38998132dea3b44b730484a5fffe01075905c4ceffcdc2bd4dd93251a67d1c1217adad4b7f51432c41029cd1369a20c0f52729e878cf5f3d2ed4d89a368d6de8901dc4352594b970abd10931f792fd6651246ced4558af85d07655c655351493ec7afcacd782451cb4cd4d697947982d963caf5e3e1f1eea9d706c23128b2ead0d04c42291f5e154b1a2ca089766a61c1f6e38106317cbdc8c1c73cd0919698576a1fc833c0b029ac22b238902bd701e14ac48c11c6a3ebc9ff77a2c8b77d5ae7c871d4a1aa2f33bc6731ccf2cf379631292dff776f25297218e47aab7c64a9c70f251538f40140ce7921cd2109d8b588854083159137ff892d26b960836b17f200728b0ffcac5b03cfe00377999be8cc59abb23642fb7d0e2b7163ce5a4a6e5cae9bf7b956745fd6047e24a7692cb6ca83bf127dbcf78ff41a7a0d401f070ad6489d9dc05980208914677f937183e59375ae452b6b39ca261f79281818f8bf4074313a57170c17c2b606eb0d9b085c6070b35060622fc392fa946fb74cba3368d709290e8e1943b962b07a286c434536f1f922a5a63e13e761d1d502308a08d46d7792a2a39d1b6efea2a68711ca1a1afcac808976ef50b5ebf778fc1954b9c78bce5655a426c00434e44520fb99badadbb0dec060d6394ab2bd7da1ae77dc103ee8dc58c0a65f1881d4cfb19cc96d6528eb81d8537f884460e8f6710f19d0a994c5e9c97d4d63b69d44b6d5710b071c78856d6023b74f6a67b193fe6344225b6ef58c16a0e18fbccfc146bc7aba0d3b5cce0cdf8781242754b563155b79a8c585d880e5cdd46359682bdf15a6cdfb8fa60e731ca2cedd826e0a6b0a03722ae61940fc0a527523f4ab2b256a0a8dddbf8d6bb96b51b92a080336775d5208f9fda0afb758460720b843c34cac52ab163fbf42af34ffb92bc5b071f41a8e831667899ff120384a7d8cba77b8d4047e457e486940f728023bdb5ec9108895312a9716b3b54e9835f5ffb4bc3a6fd65534a120aeca887499d8448e696a2a40640e971385227b98026040d1c8f29356b572bdbcfaf95ef338e2a71610967b81e8c755275978d2fa15e6efe347a2edd910b1b1d30fbed62985ed75397593eca37becb572f66c9141f0a94899a80a68e5c166fe04959e28e54f5a64f78f19184305e582ddc748f7d617e91fcf0c8122be1e0e93566567541e6f7e10dcfb5236acb9e3f54570e1196b88c60ece0ac6906c9acb9023facf5594d5f465a9c91d676a861e5a525e66ff7e1c8ac2fff4e932072c9e683a6a280a3b0027d202c34bb02729538255b6c793f286f4316c1dc68e0c5aea417333b30104b96c7106a1be4901ea0fc8c474d6d4bd15d42d6d01aeeb8b8ea4d5c2c37e2022ed532d7bcbfbc5e0569511ed6622a4808a5a1aa72268a940268fdd95c878416467a116861df93d97e83cbb7df91d9c9c3120d76f502a307b9d9f129863efd5474e9bc9ba6498468fc65608c084aefab941dd012b379fb663c53e6bc33814fd0760da56395858c67ad3d9757e1d3a4de2069c18cb4d328e77915cffa53a7e1707c7760bcd9218d3269cf06672aaebd74189c249e3f410815a8971a7d86cec6165ababb31d1c40100e2e7884a3b2a27441ddd2c6d51513486f0da72ea3afe649cd08e5f47a3a825622fd69f5cc27e30c8b03010847a0c29b30388f8bfc93eb6e6bc0266df9a7bb91d80f136162f7dafd203d38f04fd965e34b99b5418557077c681a6c584b0b9c842f696cd8e802afcbd7a6a0105feeeaaa1f13324b781ebd3bdaeb407ca4367d9a669570087156a190d33a7bf467479bfcec96b6392fcd2479c38919b2d509e77460d2c10bdc403b26a9ec11f17f8b6c1c259438e1a5857a2e8f25b774b6dd260dcaa8ef37f6ed2889ce34afecb52c637e9dcab2c717c3c4e07304c1c58cfeb391c87a6d2272664adfee4a1c6066618f2e1b4ab1888f61d7c7d496e7ef3540e2d6c030855d416803d219de6f914c0be433247aeb0844d80c80a4b77d2cfa54caf4e32c8ee0c13c192c7a36b53460440838c28c7ad1de37075f2617d03e61f151d00976786758d6f0b632e2b1ee0b13884eb0da549d94a8b57ab3f6917045bb9b2c9c8d7db0da14a3c4d2acc8348b70de974e20104bd230f1149bdd3a9c2fe1276a97c11c66bb1af512667997154f18a886dfe09b20563c1e8aadaaf4694b8585f7488a0162aca7e61a168129859bc08a83ecd004be9244a30f4e1020b2b839a7d39f6ccafefa84ff63bfa4ba7ff65c55d797d9ffff26c69286191a8db4970c163b1291bdc2efbaae0271f7b4d3db60f9013cb3341192444ad196f51de114c2f2122f8c8818f9b7140a1170101b0f427ce418a21e8474310523a40d2844d2476c051cc82c31ac810502d87880ec008e3916c1c181299d900d12c04585dbee5a54d04f9611407a0b3e2e2c41e48c41baab0e385c42ea049d0914b53a7870e0e110f842913df4039a4be1c316d28b3d88785238c18babe2c67b3c9eb5026398c19740e914712223626cc01e445a76aa40322251c58d7500a33bd270e0e1488a17c41857645ea11f46b431327099f002012409d10d0bc06285a45c100fd0810691f8f17188dd0a3f8270e19b10ed1717c2b8f130ec46d2c0a14815f9816dc68a070a0e5ee6d83aa4e9be2061cc6d7b516550a9d108221b8431e2f80075848c220a74482e6cf9a1a6e88b0eb2ac9a1c2244110c2e342a1842a0a2e89504110d44bc1029ca408e2ca11a594c20f6071e7a1c35103b245605057e14b2aa2284980a351cc1e48b2069cc0a8d85a43ebce81293c0864e15e4831427e8616508f5471632273461e3c46d8b08d63861656028a7c88e394ea8a2a4070748cc132734706666c3c78ee04b1c65b27c575850fb72864493f3258a32bea030650f2b05e863f625430264934750962faf06ed8d2b6a929734f4b02090085e5dbc14808c952e74ec10e365df330560a3c57911c185dc01049800ea9248122f8060919ad2450c3325c0ca88c00f5d6ac8e1d9620400d4d0856806333d4419e1882e1ddc8ce1d1e2080b5c067180c840979c21b86471bac01383a30217166c5618e132b85c806858c20215a4c1c28502230629638233246ce103902f4a272a58634b143a5106808403145b6ef9832416490fd9c2e3251041729a88b145008d4070b3a2d369a9238d03cc38939f6839020e3ebe324ebad0826e5122f23b0ad0026e0e72f8ee488b12202b54fca5902c6e5071628131a8a8214b108f0ca0102100d9230b4f430581820994c9c21561012d24c021892e60c68b2d5aaca61029a004cec78c1e2021d2e1060422de58a20651972a53d668c11501d1076b4032a5ab43004387d0d4e0224840c250177f3c01c74d83348608f02ae48e2226460c996047055055b00019c280070d66d0028c2a14813b989c8c20e24508012d283ee8818c31426376a23002062254423e321aae007f3e108a808b06be9c41d30086472235b18e2a46d8128b7c01040a2f58606a0e0513c832e6011895286a8882021b0ad80d0d4780d1c485f382c30809f42deac8e045c4d1001a70b2e58c57d9413ae3220af0952fb82101aa43ce783dca0135b488619a8086177a3c214617c6841e7ea880283f496342d1ed011090313433e1499712160c0ca510648193011651d223068591c789072dc4054133385288098634120b1afae1033b428842268883300b3e5e0023082c821801861b7244d2050b1617acb1040441a0b0ac20c51c8308600208b0fcfcd020416b8b2bb0a08e30a216470f3ab8f8c0600545f0e059c285e602650d05001f70d9545ccc81c719535c3b34a479a20f22b82b006856d60a082280e8f8c20903d284a900c88847ba1000d8880fd0299601011c1649813e2c492440022316004a929630905b879f3632a825413373c10f107d9c904105a638fd8c12e8a38f312ad0f313e58e224e255accae303206e810218ab25c298353e1d2079004577208b27c044d69e20a970a248042058ee85cc179000c314c80061b2518628569e2715229810b2e7c2628c018ae8417f61b48783c124609265c200005a8c00d50c20527a87093c60a87961f7ed83345a4515b54b8104215569cf1d2126393c42042d88c16eb280b4378bc0cd182a01033b6b431e6c7ca1d08982311266992ac2861815b197b9cd956d22f17f02ca8e00f2b5346278790e125092b26166040c44c0919f8bcc1061c4f504550e13304055af064292ff09145c0481b492908f8e09d9d9e01c4020b12370e10481d6292b0d22801810e58689861f1a0c51557307052c08ad950480c3753e0b09c50d9029ea921901011bbc70522400707611821fc116583085608656800983e2071a126148202912c6e922e4cd1f0044a931a1d7a02b9f1243540082b7aaec8a939e3012524d253c690366c80e4d8a1e78a057dccc14721413d272932b85d5143159e0768e9a3488729cff384183323579ae741ca595ea8e3ccf3e89091e4ed51e6791e38b20008f97f670e2fcad02087ff1d2338337e54f9df9959d083119e152440fe7fa7e64c2cb58005f41fe870618cc00d1d950b651641818c1870a852650b0e0986645dbbb8f6d5f6a0fda7a0ec51f47b54b9f1e3ffbffc498f317807769e7633ff7ab8f07fd2c3d4a2c7cfac76763daa3c6dcf4e7a707a30f9d7438921ffe559cb63cb298f3a3e958717ebb8d32d1bf33053b451932c93f63ccc3cc6ff2f2a4a25ed34dd46e7b9bb89a2626aafe55943575a52caf36fc3c20af65475f8098f263eab6e4e3757b1a696fe6dca90f9f720bd630f15c4fce77087cc8e339f7239d9d1c7a645495ac7d88851d35e926aed95324d9dd5ca0182784b70c0401527073c5087193afef872311d3ababb56e688e3ffff4138cd21e56373cc71e3e6d8a2e4d7aab89c9cb17394078a931c5674fe811c56e4c07244f0a9295252a955519125e28890e278e1ff4d367000f1afe25d070e2b6f2cb2656fa835f10d162eaebdc162c021ea4e415125f11d558777752db3c8c675ef30008d437563009f52774a4a1b563a8b683d7b399e3a96888ddcc394ea0292b0a9d9ac6a0f53aaea1a2bac41ae21f42735e250638dff375154e49d4ad6352932759b277a6e9aba69b03416f0ff2915a3b33c2ad315a69ee8beb866a2a888862c45c79d345a9cd2a0f0aadeb7cc65ebae34f80c25fe798ac58c3dcc3da229ad1cfb8bc37a4fbafbf99f14bb65dde2fd56b252741d3749ebabcacf6e967d4c51d424d950c094ffedea493a6574595113d667a51096b33c2ae34f6454712223f6aa2f5e56d454a1f0b33ceae245a53ac9e16779d4849fbba8889fe551111632aa8c51459279b6fab869b0508cdad96958fabad7d89ba6ce594369339377d215c694ff6ea2af8b6b60786739e33aa989be52211ea1b5dc51677ded48fcecb02fc2ff2f34f8d46a36f3e2f69f5ac5fe6df8f8ff311a6daf56ab551738e8eef69eca84aee8ee6e194c7717b5095d6cdb2f8b6dfbc561db7e81d7b65fdfb5ed97776dfba5af6dbfba6bdbaf7c6dfb85af6dbfeeb5ed17776dfb055adb7e7dd6b65f9eb5ed97b6b6fdeaac6dbfb2b5ed17b6b6fdbad6b65fd6daf60bb4edd767db2fcfb65fdab65f9d6dbfb26dbfb06dbfae6dbfac6dbf38db7ef513757181c16f11c316a6168c68a1c5ab787ad26286aec6b4e0d9b6eee25944920598cf828417cae2e6ffff84c51fffafc2828957712cd2ff9c9e9a289a6231c2ab7877d2d326dd687718cf1576fc5fe1bab8461bb2c2862aa2fca98a10fe54c5067faaa2823f55c1cf1abaa2442b7a71eddf666503229d58d28e64a230354d5120d4d55374455ddfd188fe785ad53987fe6dbafcab15154b627d4591fe57eb4e5d5c4391a498d25f65161bfea370e0a6bb8cefcd229da8abc3c2d9a8852cd34e04db2a1f43f4c786fea0b3d828d660b17ea55f5c53d7525cad4adaaec59e98c0e989d313aa4d1d5765ead66fdbec2f1eced46d4bea57744e4cccf09f5acd24d4a475be858909d454b5041c4b84f19f5a426889d44989335162b4582aaaeac53595cab7d7cd9328ff740420a723b81e9b8db7d86cbcad289a9e842852fddbe440f9b711e1c9bf8d9326ff362180f06ff301cebf8d071dfcdb7090fab7d940837f9b0c30f8b7b9c0827f9b0a98fcdb5080fab7394df06f234104ff36102cf9b719808d008ed43d8b24922375afbcaf6797d98ed43d4bc72f9ccd218f595f5b5dddfd076d9928da32774b4d5a8fd42d64a268d0b8c93236ae563398d0d89162271c52ffcfc1776d6d8f6a09d43beb86daffe9060afe7483037fbaa1f4271b16f9ff0756b534572b344d5d467ba7cf36ec6c95483610e0bfabb57577a4f2a7862bfe2faec9d42d23a242e5d3522e1e5aa17c352959d74e349c619ae8cb1271443275cb685dcd99a13c8619fc98618ddf2699a2a1a91aba4587196a6fb44d322594eab217133b418632feaf8a5359a47007cb4b085654fa121325355575114d579553e19cb334d33eb35162930482930c3a256dc7b8abca2a2ec70835634847e6ce49ea47ff36a54820f91390963f0199f027a012fe04d4fd09c89e92986a8e4cda090b237fc252813f6199e34f58baf8131634179ca8f0f0272a2efc898a983f51a9fd890afa272ab23f5139e14f5484fe4425680036a7950caba33fad86feb42ae14fab9e3fad547f5a75f0a7d5e94fab9b3f8116f81338813f817efc09cce34fe01b0ca024c00262012ef127d0873f813bfc297b4a1af08cfee469f993e7fa93c7f327effb93c7fdc96bf2276f833f790efc4953e04f3a8f3f6905fc4947f1277de64fba873fe9da9ff4097fd258fea4a5fc4947f993bee04f5d247fea0cf953b7c79f3a34fed455f1a7ee893f7541fca99be14f1dd29f3afea7ae4b97e54f1dd09fbad69fba9d3f75fa4f1df7ff153440c106031800038f04412545db6c7c49e7f559f0cf80238b4412c92b59f17e6a0111d53ecb590b61a8ceb2b4b5d0420e9a72c2d1596a6c9212798a64c10516360b53cad90a8ba42899d353da0a72ac300549e54f2b14ed1552aa1594a471d484657828633b9599fd3f3aeb690a5d535054d3dce3890c17359cc8fcac2a991b950a61c856156250e147b6aa703325955271d43c8d7123a7a7b4313da85dc6b44e63382aa9d46a8ce9ff29f8931843c4a021c60cef505224403989b1a282528a612005a0530a19ac48569816ce52b61aa5dd4993d54aa8a8a8684dca497b90ba5a1575499d4ed43d96e7a6adb61e5bd5da2c96aaa1493534a9888a901428aa5aaaa5187413ca7985d065bdebc89d0ed2beae5dec20a5ee59992251554a555494da2a99e27ddd218410c239420e4a9ea91b6a134aa94ed48616a96a6a46a2b38e8e7d2d6b60602955d1591615f5b4c849932228361b6ad236909ad6d6ada6925675d37696948a838225b547d8e897a2a2a22ea93349c5a1a42894a214add6d33e1bcb55454fa35df2d499d3798dec6a2da5ee3434cdcd631bb1c8c61a108a0aed20d3acb18e764f8360bc910b2839e29f014616f9a4dd59ab3024492ce74e57b72ce844021f25202498399556707416aafedffb5309a6d4320585a7fd28456d47236a46c9897292b921eb81949132a293ac0a9414ef2d7e7624340dea3d3c084b9812a6123a4bb4e7e8dcafa373bf5ee36ac5bb8a9a3cbc87a4e057b3b64927621355a66e994e4aa6ae289192d86944731a8f4ee394f1c9bfcd4993b51ba59ea4a6a48a522a23559852894b7605f61fcf7a119de5368392d27dea04999b67455d2a47bbd19eb57a9a64f253511e453945a910d43525c2ac362b3352aaa7d05577376727d5d39d915254725218e948dd6b593bd1540b75adea0e3a5ba8500437d5ba02b375979a761a7692778aaa36f40745cf56da798a05a6a22e9d1e6e9a3a252499a68eadbbccdacbd65da72d3f6cc9e1ff55a6a9a34a6f1b48f5f31a4a89a951ea444fa1d44665369dd44a4b3a736ae91e532a9e2e13425d2e99baada0a84f161dde5775af3bf5398dce3269ed5b56d455b3d3c149c8caffa752169c84262022843fc1e2f89e254e302054bc1493806941d31f4e2f43fe4f2f2c546b506aeda8eb64c2eaffcf1e06ed294b280875e9aca84ba7760ee9cc4a218b14bb00162faa14ef7db4c0e9433a61b1a0c6ccc9b5c7ff730074c6c5442989265c456fea9410a0c843815327a03bfe0484c5ff27f5a37ea23daa0eca6bfd0a2f790d760212ffff515e8325f52394d7545587ad1db6d7b3c368a5d0acaf2dd86bed309869ea94502b216c15f2ffacb407a94c73d34aa1b3abaa6ad6d752a54aea471d7400e5dc2aa3925469db46b352c45b2a9d946aa7655fd5594fda367484f295b4d266e18aba6e1b0836ae67097496403c2bea425d2d8ecad60ed4cd0d4b69db069bf5b5a59e43eaacafaf8404221284a804419bd5c41395ee34258cd39429a63470924288943bfeff24c5cb498a9593142b48bb9b29b5547b47914e343a59b786b26e0d659d75d65967dd0ab3f264dd0a63f264dd4a57d45c51586aca6017b75254cbc5ad14cbc52d7eea5cdc1a82cdfaebe2d6100ca9ecb9b865d6802e6e8935d8c52dce752e6eade74843832e6e8559792e6e8531792e6e759fac59fd276bd6ea93356bfdc99ad55d59b3c08459b3bacfc5acfe73316bf5b998b5fe5ccceaae8b5960c28b5943ddc7a7fff41f1f9fac5b43b0f527eb567765dd0a0326ccba35d47d7cfa4ffff1f1b9b835045b7f2e6e75d7c5ad3060c28b1d40f6d7da803ac6b3c622fb8b86a63d33131d49349407d67d4cb364d9d0d4a78729613434edd9ebeef937cdb196672b8986f29866c9b2a1a94f0f535efc69fbb558acac5b17b7862ebe58db21d837a4adb643b0afc562f18dfe64ddfa37c9c137fa73716bedb0ee03a3a1694f1c70fc1b2606b891ee84e92eb295ee84011392ad36d29dde85d60e33f7c8c6da7dd0b487d6fb957fd302c21bdfebeeb9f1966c1dd19f1b6fdd78ebe2ac59ffa635fe4d6aa4f1080a3f49e603cccf4395a51c94b2d4aa4b50e2a456a6597391fd954a511204131a699ec8ac781b7a3a914da1dd7a14defb5853cff83799a1807f531964fc9bc610e3df140618ffa6047cf16ff2a28b7f13175bfc9bb4c8028b7fd31556fc9baa3083807f13155348f16f8a028a7f139a079e3039f1ff4a4c4d30f16f5ac2848412ffa6249050a4a7e92e7c6a952a21f1ffe5a3facd73377eb54ad17a3ffa371d61328286a67ce79f031d14ffced1b1af49e25a9e654c2d55e21a668ae8a29e3111318410ebbfa98b99559852fd67a00b1efeb6676739ebb4a41b6feda0c3bf2907b2bfcc5e631d8da88945ddf937e140ebfd0a0d4d7bfe4d37d8404b12aae1df44c36f73061e3450b13eaaa062eb6dcf5253a4a4ce72b6424c89c90575c21b27a0494149add42b27147127dcfc9728f86205245f64814000f5e5461de3082f53bc0d8513b608a1ba3812c5842e5374b1d2c74d5357e002c8ff8f4171e1b808f1425b9e505355ccd6cf2294964514c045155a8ad062c6a545cbff3fc9b24716342822391e45c4804711adf1ff35cf80fa6f82a1d39284ba90fd657671fffc9b86fe4d0478c105b24543d19fa3116d819fe5d110d9fa37b1b04257cdbebb8c86a23fffa632643ea642ecdf34e681d94e59266af61a195b63a887d42aed6affff0a50434ad454a5a284eaf84fadce9a101828a12a8472709242d726a954492b692aa084a4bcd9c57d04db23b54a1515a5d66e54bae9819ce8d9656b8c4463fcecbfc5ffdb1ef59ae2d554157b95f97f7efe9b6262523821cc97a49b179b09a98632e10715a4052ac8cc8db7c6b3c6527b99a29d96b4eac8561b9afaa8ffa6144c52bf42fb37a1a673f6c0bfc95cd26949ab58837553dc4728fcbf6c5cf74c151acf1aebdf54cafebfd392844c46ebbf8934f5ff37f1d93eff4da3b88b4cb1d17442528a9abefc9bbcf8fc9bba70f9ff7455cf9688028ae1d5541505a8caffcfd49d25556474963986a07ee2e0503f4dfed398fad3c09535fe53e58a1aa55611884305d4159c553dcb2b4afebfa4a14a20410901c247b5ac28b202d5f2f29f5ad5c45e442b22cb22485a11a05a01405971e3d76dd6669d05949518fe3fb52a1da1ac6491d6fb51910d3549137ca6f0f1c127867fa42d4bd17a3ffa503e44281f1c2829596ae5fd7753dc76a05862b6299ab464f97f0642148bc97f0af5af448827a1191b2a6cf2df7d38aa478b14b5a5924ce98941627a99f0df6b24083c4da468183c4b9ea355ae3c6a0789bf60a7e7ac91259b9d934e1c47a074f87fba8f503aff4db454a90155c5445581925a3969b24a0345450b6aca110d2441fdd0c8a37e40e4513f18f2a81f26f0a81f0279d40f7f3cea873e505398fcffa3a4d4b1ee945ad380143328293918ed558a2845e87f859232c1ff77a374cbd673a7626a3502223d402dd80865e4a04628f3ff49eb468dd0f3ff644fc78d1a9de50813a0568e3c6a7526872c551a8a9a2928ea8a865a4931f7ea81ffbff8c9939b9a226585021101d900b1f8a371a7b61329a3b3ec016ac152a9aa9ae55e8fcc9a98ea016ac1542557509f17748dc2591597c357153d73d299ba6d5fea73505e1fa6593b636a89f2a658792c786b6a9542795efe1fe561f0456b575545a9550d90154a97f1ffba00657e35eb6647e9a2ff476929afa650fa8656c788ea98f837cddaa922fb88ea923ad9af505d95268fea96f43c2a9741a2b20b45a9bdb2a1a96ced292a5bf99d761a2a2f79d5dca9919a5aa1701dff28ccc47f52ba8e282ce68b48d445c38023261e42265072c017252f6c195f760070878d1314070857068a2b634c61f051e1c9c4c03d2a4a19930e4ae5c61331841918acbc60654dcb9d978d70531fa4ce6e9eddec5039e694441081420a1b440e38100591808252c5861094086ffc4b4999aa90d0d732b5f1ddd37f13159314d308170925c205281102807ae28893d4aac99319549afa8d9d482d693a6a49dbb45949539d7c79211bcae3f354504dd488bd50131b274d42e026fca6fbef22d192b663ab953dd2dda58d3d567ae403363ee70b8ca7158445a88bfacd6a27958b79a4f4f3dcb2914a52bfd2d339152959d7be60dce9f4b69e351ca28ff5325d3de091a9db8a0718fc9b3cf83775f06fe2c094fa376df06fd2e0bf2602a60cfeffdf748105ff3bed3b0dbbaeebbaaecb39e79c73ce19638c31c618e37befbdf7de7badb5d65a6bade52e77b9cb5dee7297bbdce52e7741100441100441f0fbbeeffbbeeffb3ccff33ccff33c4f6badb5d65aebaeebbaaeebbaaecb39e79c73ce19638c31c618e37befbdf7de7badb5d65a6b398ee3388ee338ce82200882200882e0f77ddff77ddff7799ee7799ee7799ed65a6badb5d65dd7755dd7755d9773ce39e79c33c618638c31c6f7de7befbdf75a6badb5d65ace829fa7bb8caf059ab5b6a02ab8fdff4e7b145405a84755d0c0a39830f22826843c8a09208f6272c7a398b8f12826653c8a89168f62c2c412deb9895a398792cc130bfafa3755606e26260a5e4561e17bc734804fda3fa8ebdf749ae04d12fc7fc9048129021304ff1faaaebd8364f294ac8929b5f35ef21aefa76dd3d4b4276d3365ee217377584f83745011c01e1541048f828001ff4fc18ff04f3600511070f12808d64741003e0a020b1eb5c490472d49e3514b9e78d4921e1eb564f6a825f9514b26f893226afc491132fea40817ff2f00738fe84f0b75a57cef9c28df3b3c2f3594ad69b9c3f74ed25ac6ca114ad5b9937617b7d9d7b414533b75964e6c335a8b569a0620803e4361fd445d3d58785c61ec85e5f50a63e1cf500f16a098161d201335da3434a5fd205131da42673f4285bedaacaf2d23d4a4f2d55a3c280180a624a69a7f53c9f4bca7bb06468dcd6a01c836f4bcb2aa7d87dcfd677daddd47a6d6826858c632edb39a6bf71f53dcff0e30f2691aaa483d0d9aa1296b1dfb79a2a35af620f534e82c6717d766b51300d8499397e3256002d5c08f1853d54db399438e3ff759ceca74544b9ede2cf26da06ecafc7f8e18a6957f9b30c0f827baa2c68e50958a94bd6e4e53d72d5ffcffdb78d1c57fb8d7ddd3b221e4629ea23655dd41b27597644f836cb0b8e2ffd73d4b51d6d7a97cef7cddde095f415f0783fdf31225da2a1fc91409c5400eff4fa228969e06912951aca7b42f597ff81a12d271f9b4602197162cd6137269fde8b45e212cb625bc12e369fdec0c05652561feb3aefddb3ce1c48a9ab0246ef05ee3088db657638cb7f846cda42054e9261b515ad8c5bd53aa45c2c4ff9832cd6d8b12eee8ecfc97549c74b14999756d454dd549d6b51494ac6b4d4632258a9129d223555822d68b88f52252d56e94946e474e1a6dd3d4bfb8a66dedab7dd7d6b2ae655d6269248752fcae8d3592411e4bc0f0481738fa9a5129fa98a63022e6df34b51d4a7b901e1fa8a94a8da59d76628411d999ac876e6cf87fbe5aa528a9c8228b58f18be4f08b78f937771a2b5331de6f2519a3a93acf25696728912cbe27ad8d237aea9c10b9e38448183605e8e17fada149db4cd39087877f9b1d6c7488a481244a7c0d951a104a727ca98d921a25334a451c62aaa98aef9e7e04862cf26aaa42cb5a4ad6ce55ac2542010994f8c8e354c803841042c81ea6593b53ab4e4b5a09e9819019582044ccff3b49ada0406942c816428204396735131d53a97e96a9ba6733744cd75b97a5ce124dd39ada4fd474429e654e141152299a726d576a458d9aa4526a3ffb911396e5b89a971c8ee3b89a97262913edbc3c6b451dac67e7e5982f508a564546279a3a57b534d574d35858421af2707236494a772cddb231a6962ad2ec90d800401026a74080b0c9c106877f9b1bfe6d6cb0a981cc03d6a8c00b82a43943064d0a1b4841b362324869fc48c3831c9c90d9599970b2d0002ec804e0c9057d28c1210715e8108200066ea40e50c10827b09450a50b1f2accf0b8e2c4f3904405af0f29317ccd8c0a493078040c429129c6b0d1431a2f4e6af8190384cd660a0ea60060ccb8c3511816fc30c298284168c81c0e59440c230120d24245e40c316500e00933c878f289c9e14686a336842e2066cb123b2c2630242206e70536860863134bc1902307a868e4fb49818b1e3d5a10c106560a2f2489408d0c53de4821a80d41bad50f76a4604104420e14d97242183f5e507201141f3261a8f0b4180fcc1e26051a6628faa040c3b01a18a14c4e961ac24070c611720634b4a43bf21900b085014a5222072246d821cd94a434003f5198386393a4f021019915b39064ba60670d2f89946e6f88e968259c607413828718aa70824be266d4c4ca895005b4b8dd09a4e160c9188cd8206955c97f0ce1c5966615041983a830858d077102335f5c106cb12442398db440b335690389862866b82055a001221851c39813121862e8814298dd05920c467e1092c615054908a6819633546a404aeda800c50f2473d40249f2081f13a47148cd8a362071d96ec2a89551a23bb0c3cca856c21171e811248503b513163cc8a86048591ff00015778c48c6f5099f150261001043acb537d8185ac33059756a60f04824cd04ab038560e043162508a0cea105024f24bd94a845ec81450767ac6ea8a601be50920aada06a3e3837ba202d40ad71d9a08a8939902ea0841404b9807d22fde14443861e10912115c13015c193481c690e24e90188380406461148c6405560c31d60c8b8398f30744000cc0d5870f1880e5b8ec068d9218ad59980088c074c7c20c6e30101ad10153d40ee4102b42d9c807022c309219a0b29417accc4c0430bb260c88d31601bb40ac8f0a24c1a2f64d03eccf8b080196a0d748a3121189c08a6a061c49b2b6c5ae8010d2f583d393283842ee1a30742bc1803e5b4430907632eb0f5389330f3c70f8dac40e60453c24b0f478c8238477042039c93e270da7040c518338cf1c08c0156dcd08dc0066d664608d5c50e1088c08c6ce2093476b00832bb1c10ad0ea07a603e52e3410e8b68e1996764095431831133cc1d72e0c200df190c30bf58f1858c1b1e60c10c810c15b40353baa30ad4a87102ca9f1c2500853c1e2163e3c4510c4364ec3deae208660302912644dcd1061f884100250cf9410110414adf0b360000852a0ac9391e12372890f12365658b8d8a42cb850ae0087384030a139451eca4217aa0dc438806d9999e394a27527a046001ab43caf50f2674d0217229ab68b1071a342e294a00886114068a12a890c961f442235fc8c14556c406438890f458911df534bc475601907582dc4049a3073a64a518e0c8726393c0680d016870c812388218f90006015c06c94006a38dc80d527850421c4650b818e307033d04201369e487405008dd4ada6de8cfed4e1013e24cee31e3ceee7db9cb61ce4b0a57739b04719739f97d9e28f3ec776d2db6cec8cf274cd8bbf881a3078a9df3462e82dfb53594c4e16ecda4cd4adcc592becc61d0f340f0cbbae3acd699b3797324f8edae831c6f2feb5a6c9d91ae5b78b7cd99630f7ba4d73f8fb4853c777877bab322c9d94e8a4821487620d865bb37396e2cee5af88de4cdd90333b8bbedfc937936db59ede4d650cc20495ab16b91bbe37735a75d5c625bd4d08a9cb41fa939af7764e6acccb3e9faa963aa93d531dd19747189e534f4f6287ea097b98e2333a7c5296042cb817b5fd1c397e3fab6a34ac54b34b6aa27aa5d5c62315ae638aee32cd61acc5e87b9eefb486f24b9a849ce71a3eeb288861bb420e7dcdb3693d623f91972fdedceee0fec9fc69ce37c6621986de64811db3e762048725da5f25c5c62a5195edce1fc8d199357e422b732cfaa47bbd3626b3702752c16138fc6eebab8c4788ec69c3b11636cbbbdf9dd1d8590e424e8f5ce5deefbc40d92b7e4a077b7edec37f6ec915ab35e38ba94e10ff434ce1cbe5677dd7731a7f1bd1d395ab2e38f142df68a8cc23c62efb362d7e97e33175354dc1e9076b424ffba4876cec16e4be863b73f91670e9322e9dd7e659ec5bcfb3c6cb3f7799de7699dafcd20e8e50d8eddd733f672e7d75e19c38f5bbc47ee76cc895af436e728683f310449de79de088e1aef912347996739bada21e7bde76e7bce62e7f7bb9ca31c5814e2b1d377e4fae8893d630c72602cdc1877a4edaef8e5bd35ef32cf9ab45919fbbc13c271e4c4bdfbed9f983b2c8af78ef025ccb65fd2db3b7fbd73bb5b99ea692fe1edba13b96ed424a87997c9b323757b575dc23c8adfb877cea4476efc7132cfd2d0945b8e4bd83fce79fae2fbed7bedc53274c5774bf88197935b77bd75f789de28f36c3f51738c5ddbb9b8c4ac9610dbb1bb9f05f3ee5cf78959b284987f96cbe4fd46d103b9e52ad5d7a9a2ee5c5c624344a137ee6eef8e4910775cec56e659743dcb98b5faeb547128e43069efc8f5dbd9bb2da9659efd7a8af2a49b48bcd96a17979827148ea4b63a5fdeb7f574be58e659995aa3c55294d4f6076675673f6b3feb59b0c31aeb0e8b9eb616e41cb8c5eeeb39358ad957c88924c7dc829d68f3d8bd4ee6d918caedf56cfb056e3121b43677ac496b3ddb7532e659ef0b0a416ff37b37e63cbdb9bca65f152c61ee344876177f5ce77d19ec32cf7ed6737d1ca7f167edc59f06b3edba4e7b1dd7f1b7b526499b37697f542a950a77e94aa30185195bebdd0e63db41cd2ff813bbf2a584f0d3dfc7919fc7b5d6b8eb9cccb349aa8a9a9dd55a4a6b86a23193a7b15803567e7cf237627cc56eecf88258e67d351cd60be712b1c2117fdda7412d7696cbbcebd619c98521e63a6879278a64e748fe8d38bcabe108e1885d0d27bbb8c4807a42aefbe63077b5d6bc73bcfbf070d8fb3aebd96cafee3a8dadbe5fc7811f87f1d8b1cddf988570582f9c9b5d5c62453b61cf64dfa38841f1d3e2388232cfae3312ab546347eab48b4bec049d90c4dd23adcd7de43e127b9a24d118f85325f4489b37d7f7d69c673f4e42b8bb3b6a0c5e8fe3ba9bc5ad5b5442d0eeef7ee0ed1893d7e3b8ccb3316cad0e0e0f8e108ed00fced889b41d3b12c632a5cba2f75930f34b6ecef3b8ccb3e9968d9c4d92622f7739bd3f6e474f839c9479365dd518d8d732cda26e1ceed6625fe7e212b38d106add79b6e36b3b89bdae7b32cfc6aed5eb8cc49d8b4b4caf3897bbf7757df926b1b69e4aa552dd4c82567f376bcfbb3a5b4fe7ce03b555cd904c53156aad37c9dd2df27c39386e996771847c7054eb8c54e108fde0c4ced2c3e94ac33d45c7ece212db5fda636a2d8dc52cf054da76a46ec66e7bb64167849a31b3828c391cc26d62a170214471a24ae5d8fad9d30fa07c20c2f5e08951a972e024a91fc59a34f920843b43c758aa7a2078f0c107381e78f0a403de63babbbd4cd7271ccc3448c55274dd1bd8d86caf290d9c64d0bb1aeb0003b5c9054d2ce0e78ee50a9e3051cb980714649d014a83d30db5ad1368204104babb29088cce72bdf5d412dbc1003e72ad65208059ed0c808d75596c3dcb94161bd57286c1032138a05600806b410368fae466f7d40293063636d68d2a60c0aa1828b1e56c863649723ba8b9a064633c76eb183c973cb4f84044a9cff6a9448b0f724ce0c0db9145199d37d90b30b28822895800910a50e010430a216402830812880400f923027ef401013e1eb0871e79e071871d0e68401d74c401c71b0c68838d05aca1461a68a439c30c05d894614386cd18ffff64dbdc3fc510c79f6218e404254038f0762000109d277756b407c6b98ed7427bccdaacb326dc763ff7cf9e9dac3d3bf78c35f4b2a13f37166c084d3b97a11b6b08d6baedb3bcb7ac3967b16e59dfb2be0505e5dbc537a4b287c562b158b75bbe5d7cbbdd866e17df5bd646dda58a3af79635da3334946f17df6eb2db50be5d6cd45daaa8333404336b4030b3063454031a1a1a3265b021995169859fdd86fe0c7d376dbf9bb6a95903eaac0946dda58a3a43e50ee25c67283542d21982dd36d059029d259058838935d8d08671aec3b9ce102c95c14c196c086643d374bb8ed43d5bcb1dd334ea2e55d4a9a54249a7ced877502ddfb54429167eea9c3aa8cbe7deeeeddeeeeddeee2ddff22ddff22ddf60fd96f52deb1b98f0de7c8686866e60c27cf3f1e93ffdc7c76708b6fe741798d0c7a7fff41f1f9ff567fde92e30218b756f59e7dbc5eb3669669830a50dc662b158f796f5bd659d6f17b7f2ede2a1efa66deb3504ebe7fe5947b59fdbec2649d664306d6fdffdb2bef847db739bff3776493ff7cf97359a762e17677db1b6eb3669b0efde2ebeb78bf34ddb7cd37608f6dd3ebed19fef5aa28bbf1b6dc673f1a7ad916cd4f219c9462d9fb6a896efe22fc5a26d8ae53bcff33c4f9d8b3f6dc51aecd3d6367b71aef3711ddbecf50d7d17b7fa787656d66bb9b32491e58aba74c6545d555e9ead3e8b8da9aaf2d6c5acb5a7b497da22fb8bcb3acaff8dea2667555bb33e9bf5d90d14a374cffacc88775a929069ea64d0d7249196b4de8840b6d29d74879f61ec65435399d05e65e3ba799252a1ae9a21d9ba7942435d374ebe6b89fe6f9a64dd7b6f5ddc7b6ffddf84700342ec039c374a75661de8c683bf61a244080c19184660f0bcba2a4a6df5a6831b0dfed37ec341eaff6f36d0e0ff26030c92783591c041450294d0f6ecc6cbd8cd0516745a9290d1160abf6b892ae06779b484175da89d96b4a6104b4d919252cf6ed2d045992ef87f173dff465d30e1029157b990e39f9fab2fd5245162831aa53bb5c5075b38f0ff5ad0b2a8e3ffb508d20395451da82c3e2c68b86142c178851b0c94ac60026585991414284a18a0440cbe8bf8d98b52a6b9ad685246f16a92339b934974120e10e0a590578df66ab4d724950a17a828a262c99ba924539c7555d5117b16288e48614e91c5a7565390f9d4de6a0f500b26c52052d0f12a293c293ef87fae6e5b890067a2e8e13f0a130a34a828b4fc3f1474bc1296921b25368ea8925cc08d4fc2069a42d0ec8106016890406343234333050d947f62912726f0c4204ff4914a4149922565b4d71ea6549364ea979f3cb96b29e6649d4a51d2c94ee9939ba4521a779dae31c00d6da09a28e39f4c135f9a083a9bd0a00993d15e1f5069f8579700c33452ad4e49c4f0b1b3a6e24055d554ed485bc6cf3d8849901a461831da6b51ab0b81e88807fe8831ff8f42028d472141c6a390f8e2514868f12824a6f8ff244664610413ab9411618c308d20c1082e4500236efe5145d851c41aab22644520f1bf2a222c22f5cf8b8acef4f1456790f83fc33fc90392e87186091191fcff068f22628fffa2a25411115efe1fe751441c0045449921bcf822124d1515fdff4e124086f8e3ff8bd454c5c0049fb551baf7ff8d043711ac67298bfddf40f07fb3e46600ffadff1b0104e0b5b34afb581aedd9adf36d0ac1c4cc2066d29841c28c0c492bca8c8f9928ff7fe39a7c392ca1218cd5b2fc23ebd4eae25a2cdd486a2f85251c541016303712ff8f3e2a08f2636649e690680e3f7b103a882641347927376edd4d520f1c000824805881a8f2402829c0f7644fbf6b91b2262f26b32e2f2e7fb0e287177e587fe8f941890f77f880850f43f820f4ff2214a00d3555a90538e17b5c616a95aae65e71e0410b1e92ecd0c0a376f847e980c8a374f8e3513a30e0513a8cf1281da078940e0778940e343c4a87308fd28137b084ec2fb2bfc6b3c6ca9a75312bebd60d001a50bbd10ee25d68efa4dda8e6423b477974c8ff29de6949ebba674a9a20fddfdcdc98fefb6cbb5c4a44b8b159cf4e4b124a37d10e370cd4e8319e6769a2b419ed4689171c7248a5284984839520140e37a5d60d65fcab4a4f4a2094384864903dde68c38638421b8a5e4d55ad47d9f0c083a9c10b75e77c50c3a7a6aa1a96fca7562a1acea06810f34fcce0c84d929a2f6e4aff37af76a3fdc805322c92f50632a0791044304502498e0c37a647fe8556aba47387297b98f2e25a2a7571922b604803430d6769058620184080610235a7fbdfea367ba7dd3a47800f6828ad8cfe0210ff5fa42a5af90b41624d4d8de48d7b21ffdfb8d4aa7374a4a129731b75d32c931eb583cfa376a8f2a81da63c6a87d5a376f01eb543aeb920c6859ee7b3527da185305840b5a0e5ff4958752c10f16aaa8a329e35d2d4c805fed527565884115499db5846cb0864eaa891682cb204181499a26f0121aa0007ea8b161ef58598477d717bd417b5477d913eea0bf4515f9866afb180cc5e63dd78ab9b147953971b6fd16abcf7b4811a13468ad60060cc01c6d0565920811a83f33484f028317dd420c64c0b6282fe532b9498085062fe1f804aa187146e2904fda7a6a45250525356df41983b5e4d5551666737c394af44181315460c13f4ffa924b1cff61943180cfe596200a12559f149653eb52a2ac29274f38fbaf5f129313724c61b945753952d7596a98e92b6149a402101f2dc3e7bba63895800910a50e010430a3111629a80294c5acbf50c256002e48f08fc9bfce803027c3ce0dfb4871effa63cf078b3c7d45e8e678d54bb29ee95df78ab8fa76aea72c7ffdf6a02b0a659cd40ad2efcff1795aa8bba32f95897bc9a831da90486868636ece2d6c5ac9e356b68286bd6c5ac2158d643b08b5b43b0ac875a43b0bede60590fc15a59b7683bcd7271ebb681b2669d2550d62c168b9575d659679d35cb481575b2669d46a59a4443792e66dd36d0c5acb304ba98c562b1586b0a0676316b557bba2f66a5286ab22e669965e7b99865a48a3a17b3d215355714969a3258d6ad14d592752bc592758b9f019bf644c8f7fdb677bbef13c9cd618db9226a9c086dd73bce6d87b9dec9eef1ae8910cc9de41cfe3ccbf967edc7591b6a9808aff77160b73f2d620ffcbab1eb960849726f7224bd2c764e835a94793686ae6789d1f56ca9542a8e851a2542cee6db7192d3e0387a1fd9654bf4d9cc539344c8b94b7219043f8fefcf762012616775263f0e92a047f6fe8949e97aaa5439e72342528f9a8fdae6fb79575fb0a4e974dd143546849803399b3bcdfbbeddc3a34a952d924a656dcc668b84a3a82922c464d72d173fabb1c835d7dc0b870787330127e807c73369b3529786a839137adcee9f3872e2bd3683dd7764d6c4140bb9fb0f0f0f8e4a9592fdd539ea5279562752434428eece7659730d726017bb0b823543845ee63ccb79a288b3253f3eb654315a8d778e99a81122ec2049f2db2fa9c59b3bed09fd583364d7811cf975df88f9d7c76c7496499cb3e87ab6ba4bdb33dc595bab39403872bdbb6377ad287e1d7f1f2d492848a50263b69be267a6c600e1cd388fa3beba13c7d1f24ca452759c8d592f69bd4ad404118a98f7ce91d6c3bb5beced4e4b1252a99256958ab3319bb4ded8016a80d0defd70c65da7bf0ed4deed7067418e3bcbf137f27d6dfebe246a7e086fe75c6fdbe9b17fbb773d54a9542a221c1e9c2b38423f382a156dcf542a95cae370a8f121bc5db7b98ff3f0ed78ec382df3ec0c4d49de8354aad566db444d0142918b20c7fddb9fe8911cc8812e2eb1d20b353d8456f32fe7ec7d64ef44cb893c8423893bc789fc7e9deb2cd73b8463277256dcbbe3f8377e5f4743d31e958a86a69cd7e810debe3f507722df1de7dd1e730841327322f9618efbbacf82220ea1d5f9f3b227f6dc6991fcb0ccb3602bed6b6b86a6acb1d3602ad5c7d931564253734368370747511c2dcee4bef9d6d8d0658ed31ef859fd69ec616fdce027821effb6fd465b5343c875faebc831f76d39f26251e6d9b39b31f48c81b68bc53eebe21263d5d0108e62076abe3d901c39de1e57a9fa6ca7a48b4b0c4ccd0c9877a047de4e9222df98f5c2b9d84b8d0c5d7b9db82d377e9af4448b63e06cc75d6cc1cc7558df6bb187bfcf1baffd3a71f70c7676d7c0107eb77f9fd51dd765cc795bec5c5c6226d41020ec62ef447ced784591e4df0b61e73cf25a2d629ebbe7716f0b71352e841db8efc6e3377ee4dd98cb352d8456bca238f2aecba3ee3847e6560d0b61e771b2bb3c7bdc47e64ef715c291233b107f9d77714d9910e37d411193d976b1d31e27144938929df78b6f277ebb1bc74ee6599cae3448429db1d5ba237916c52e8efa91308f60d7799b73b7b39ebed891507be3e698043dd2b39ce3ae52951a0935783ddd392c8a1bd49cf70b84b723af0535e8755dbfd9ee8e91909322e79c8b1eef46de8d9fccdb42aaabd395b68807eaacc1afebbaec7d96b3dc672dfec88bf9b747b123f9595e2929128a1c16f767f3287698cc3d9150e70fb4da1b3befc66c77a752a954469b972c10729a04f3b61783fb23c74c22128a5c6790e4a41d37e6fd5620c41bece488eff891242872a2ccb33646ebabaa2910f27db767c1bbb991bb1db7659e05d363ebd8e108f9e08009fbac145acfad52a954fa9070c49a771dc841eee3188b628a92e559fb6c96922118df7c3d10fcee05b5b6e20541dd8d9cdb1ceea3ccb3298ab44d321633cdaeefad544828e6cd6d907b20893daec3602624ccd6bb5ab41c0477e7b4b73be75e3ca045d7b5a7ab5aa6e004c2afe362c6bbf3bb47deefc8755c5c6267699010674e767cc551c4bc7392937996f38d43954ae5e9b6f1be9e251aa49abd747524340d52a938d7b16aecda474a8274d7b3dcc759fcd98b3fccdd8fb35a7bdf97bbf771eef2ab7520a178b1cd9c783dd07e9993a304c2317f24e69d67f26e0fdcf60b2a0112627eafd7c98b41fb75b2fb649e3d1a370dbc30952a7be936f7a8ea154a7f849d277ae2077efbf33eef1339ce4620bcbccbfa133f2f739d132f9779d6a89f46dd05723494fc0849922439d9c5ac6dc656aca9620dd64788c16f8b5deb6d39e61a9332cf1e5d1b4aebb89420106e0c761777ddf53cabb7c8659e356b332ce463d68054aafccd51e2237fded765afbb9cf77d17f4f067f7de24c771f7d31c73f2da144a0f082f79b52876fabb1eef3a72cb3c5bc65230ea55a954aa8b6b2a954aa5527da51c4a7b84f88ae367c73173204976ce93795655f7d75d7df5c535ac6a7ef6a3718bde513737ef48696dd4568f90e4bd73b82339bedda8c92f7676d3b3b1241a3a761647c807bcbd94479839397a1fb6dcfdb0677507f108f108e62c7ef6b363bf1f67ef08bdde73fec08d33987bc79131d58e10c49cf87577fcbaed3d7b9cccb31d949203c28e4772db2e5bb2e36e49919fa5edaca167ecb3ab520342db755fb65bf4c651731eef8ccef208ac231cb5a83bdb77a73f8f6f8e435d2a558aaa545f98121d21c71ebff86652e351d4d69379f6bbe94aa3529a2314b9e6483d6e10dc1d68353ffbac77f6da124a7284e0fd38d86131f3aeeb20c9c511821dd9b9d1da4efc46bcc9ae0447b835c9756397f1387276ecb6ccb3dd1b21c7e406ef78c571fc44925f996793fa11a66da08f011f97c1ccd9aef33006afee32c7911de9612f7392ecf98e32cf766e847d7fdc37729be37687b328726d849de65df6bc7b3d8c3bbe4199d7c1acfdd619c94628725f26c5acb93d82b82377595a40783b98efed9e15410ef36c57dae63a7c07a954eaa75d5c6246a535426eb77735ef5acca2d8bb87ad1a612639077ee2d891dcfbf025b145751ae1cd98d42048dedb39388a1f87d108c7ef6eb1db0b76e0287e5994793616bbd734fb98d3845bc4facb20d9b9086e8ef4b48b4bcc4be98c90b4fd8a9cf8717083e0784595ca34fba852f5b4644608721cd8b3edf6033baec5b1a48090dc1ca7c58cb5d51d39725e1961c6b7dbfdda6edbdb3d7293118e578324c73b8d35f73a1167ede212fb521a637772ec22378a63c7e1ae234b62586ebb6d41be3d0f243f7b6da530c24e821ca947ab3b8ecc9f8887542a0d46285e4b7656dc5aefbc3f12671c211f9c964aa54afb5aaa47674dc6f391eb904aa552a5abea7d2e2eb15a29016187b578ed386e6d47317fe4ad52fa22d4ba8b3de32b728e9320c7cf9ebd08f7bddde5e388bbee97677b763376bbaea7d445f670e7715f063bfb71b7cb5ddee2b6deed5ec718771fd9c3946aeda62b6da8c4459849ccbbe663f7ddb1639d659e4dca5b4a5b841c1cc92b76fc1345d2e3b0a7b5083bcc39d6b863aefb2ee8d1d01868bb5216e1c7e5fb59bbc9ce3951f71d43d70f8bf0e336b7e4d837d9e1ed65125dbb2bc20fcc1c063bb7b7f3710445cf8e50b222e438ee75bde33ccb89a2f6409967636a796d152216f1076acd81f7ebbba3815e09011fbe385b0e77396b8b3b4fe3cf92d78ee378fbe78d1dfebaccb3a6b947b08f279693a53f95860a95a80839dce97d3991eb9d27e66eac4d11eacee6efbb9a033deecb5c2ea508b96735c9d9ad7b26c151eca208b505fb0872fcf3bcdc7dd68a2528424bee6f7b5ee781dd9731d86d479b957897d0785cd781df053dcff33eef037177418cada831b8bdfb5d11cb3c9bb5479b95f88990b3dddea2487ea348f6af5f2742ae398feb2cce22cedbe6aeb34d845abc9e0792fd76960431f7c93ccb59507fdeac76ee949808fbed5aecd9f3780776cedbb3dac9792e2eb1b1b444883bb0bb23b941b17fdf05b918d8959408b12792e288c19c37477a7ccb3cabed2d25115a12ec2cdfa467c1cc795dcb3c0baa5fbaaa4884e0c522df2087b7983b70e304bd7070827e7070582f1c9cae349ed211a1e7791724b568459d416ceb274e3b2c5d61d67ae9aa1a115e0c6acb3189ef26ad16314a9eadb13c77904a85926719f35c5c6264a98890bbdfe5f9d39cc6fbfbf49579967ba78e4a95746e7c26bc1eb718e7dec1eef3442e6bb2a84444d8791d9317f311dca2dede95793666d6669c95521a22cc22c9476dedd7e54fdcf9ca3c7b6d282d66d6661f976f171b953b9f9ed54eb02444c8819aeb76f4483ef6aeab28cf763d6be8d8a5abaa4b66420ee6dd61af1b394e66bbaa7d4d51997af101c27eade5f087b9711c3ff044cd3d43d718783b0384e238ee6d6dbe1fef7cc4f9c65b46e77ea954dde8dca94aa5d250ebb9b8c478298890777dc1db394e7a9ee63bb74a4084a4983fbcc93b7620c845ef875073ccefd7454d66b073b6fb10f28ee4a4e51fc969d1c35d2e4028728e043bd1d3fc7ea348e2520f21e7ddeebc4c8aa4d7911a671797d8abc443c8897693e4de9abbdfed37ef108edd26b3f86972939e38e2be6556879067ceed0e7f9ec761d1726e55730839298a18cc17ebed8997dc282a5a29e11082fcdacec70ec4e4475ed2bb37847aef6b49ae493bdece59dc85251b422f937bb4366fef82e00579ae2124bbc8bd9c2d37f28e8b3b631ac2fd75787f9b044590b31ec9dd194270fcb8de378ff9729c8c596ef6928cc5f49521f44050c49eb65ceebece2fb757a71443088edef66c2772511cefdea2ccb331ded718df34d092508221bc5ccf1e78bf8bf388f5f8c93ccb370dab4a0408fb285acd3931779ddfaebbccb397557a21ec7ae3ce6d8fe4f6e22fc637eddaafe442887917b3bedee5f9761d591363b49ddabeb4af202eb5107a1bd41b7f19638ec9de4999676d2094580841dde96b3bf64672043b91d389819d8b4b4c4b698550b49db4db8ee2c557143527f3ec7aeb7acbae3af3d22d1b33ac54a6bb377bd6da0ff4be9cbddb7939e3dd5d6f6fec759ed632cf9e491c87f5c20173bad24c3261ee3667cff27d3b3872dfbdb8c4311542adadf77dddb87bf6ecd8b5b6383626d4dc053bfd75fc915773fb16a3dca814126a96490c22640c110098a30d000da3124040582c1e0dc6a2e178449745dd0714800357906ab64c9bcb846998c33008196414210400000880010233343403ddd015f44d078de2e5a1c89040f2e94f2ccc50701369650dccf881369732c9ff84e22d0e57e3cd8fe2f3ef768d4105990ff42456d4ed39a845b28341033c5edd3878e5b218c5b7e665108574c0d13caeeb4c261f482d1478b280a1ed60aedd4c97fc6c64ff2070aa157d9f0028736c0837488ecbbbd81353908ff2050c35570f78522a9abfc060555b3927aeb72c7b889f6a160c89f24fef99a25b13c5ce9120817e8172068c77f259ab864e1dbb5e1f75a1196eba886e9791e1b92639116218dd8160c5270423349feb8686777b90bcc65300046f0382d3a0eb7856d07721e2c194919dc2dfea3e739c5cbd57d90b3369c7c3bbce35004ab3b85d15fa65aae9e3356c34e04e4d50600401df4fd05da37d559d5cf3e9507c078989f666c47000e8dd0646cb0ba0e0ee5b1bd24944463191af7d518b34cb23e58fcd07c8d388e83cb72af9e37a5d8fea513691fdf2292f89e39831d1dae2d253f8965c305547746daa47bd0beeb494a616265de9169b1775912a36137030988e6c3f56a56ed48f52167263fa72b9fe407216e7491ae8b8342ee92c1b1880c3383b43bcf9b89b84e8f6fb2a2f48e1124d49f647753738ca208d4efcf92b413cb0066a52a4fb1c85b603b4f30830d1389d6392c474003bdf72ad60ddc18aa441136d59c9570e9ab612aea98b0b1e10523735dab0aeab51b82c88481db1442a4fa3f83d09b70c51dd2bf31b0b061657df9fd1c67b4421a00a114fc5146065d3ef7f6e667f8b4a756e60cd351561a785d8770fad0a19b4b48b84e7075a05e1fe941374f20436691a8bc8a6103ca68252715b0457ecdbb68c4be6b36d09b6cad85514329189a609418c06aaae573e5129dbe949b30047a5a4250ee71413b1346e20aeff80c6b77c09774b861fc97198b73491c4f0cee14ee899cccd4b22fa8d4ffc9c7a680e5fe8d69447c3ba399fbd1ff2fceddcf926c898eeb80ff565cf10c290a0fe219f2bdbd0a29d451a529fa7f6bfd65f5a00d956e2c0ec94c0536c2d748710317de810fd30559f36caca69889b482d29c31b3fa03c095d3ca629cc9d0544c3b3245d1ecbf3f7445765943848d7b102f374c57fae664bd1d6ed5e0484955a9c8762c4d5647f44e5f7d70de6490199bad5a5e545f444181cde7b34bf26b3a67d1486b48f5eab01bb5df0c873f410e957b355b7526528441ad2576ec05c16de01f94c73c4760efa0b2d7381f204332dda62239711ef3fa0258c59fefcb0eb504435c01f05364d4cf2699db1d6995d81508a0d3990ac39856e469ba1e447c37e4950c38c055de3a5ecf71d67571c065b959a0ec02573d55defff29918b8ecaf8571292347e8aa32a8492a4578616a472067781a8d207fe01ca32b7686d9709e2b6b41b9206dfb4d08d9143517a645359489bb7d869c1f3910dd1acb0099f0fe02634348f6133699c4302aea8e6c3a3aa4e4a22190446e6322893281503882c99f853057b31e314ea2e91b4f139751928af31a28de2a3990eedd5bb5bb056d190885ab75d1fc314175f4aa064cb7703a8788c2351bbe2b572c234269e112a4252ce1d0f0cb238fb6c4ce306badc81c27f143c4338167628067823f089ecb620d2e9854c8cae2aa0018057c58aef2cca21757f066dd41c704351dddf2098fa151d21464668803400c77075245d8e82d01f08583fdc2592d4fd81dd62fbbe918881997a3c1ca2e8dccb777f3fb8c33616784770e4248bbbb6626d258ef4742d520380c86084534fb58979dd99dbd6209ec923fe899050c120774f39f5bd8628af29693228cf2a4145a3ce6e64ff6cd7a8a2db769e0ee65c724cd926acc7d328963e3e9df6d4c8cb46f411c6ecc1f0fa7b2b4e150a8ab1f1d872822b8a3bcf4e2a2c68eb4128c1b012f01464ed66511db4a2ba57659895b4894e51e9bf1e5ce36b39d6ba98a8f55d5014ef743441740430023145c5914cc2c15b9d720b701ce6a4933b0b518fba818b81533b3809540fad7e6fb62ac431f05cfbf62d15052bb96a76c65ec48daa73c9f852c1c289d86c10368273551e8dd2e273dd4b3a10920794c250802d3831624194a6715bd2750fe5ffe8defbf16a841484e61a6a7ea6d86e660a39a4c28abe0320259066481a9222108d2ca11ce4f18e24c5b8fd96a1b6b813b53564d0d43b08f588d0e5c91ae7697bdcf02b71383e97eaebd65d802ea00781d47245271743eb4a4384b18d02a1102f80a3b45f53c1b5eecaa4d46bdd54f15a9b75eda9212d7bbba0e74a404f65ac588238397b25ba7a7db1541c0981d5cc1f2a3fc8142252c20d6d10cc1560c21e2b9c38f72018047c393a16502a201aab3f6855779be7153c8c8f5eb63f0f24758b6e5f7178893fa4b605bbeb162ba4ae08f81a9c3ab9525b81932894ab1e69b397f6cc6e8d82eb3a83b8e9d4845bcbc70a8f0dde2954a1f64b502fc507d941824a11e0ca8e18f4cafe8a655c28d04e3373b37cf1059573804ad3f95b1957f942d69529309d3dbc0182480ee5318627093b1f7261a00451aa39ab7f38919794f90c652ae4f56f09b177343cd5b807b2bf70f352807277572cf2596489dd6389f15571774be1122c7981ff59f51a0504e7ba43e95cf95a898b2f424a6c38f9c8f2caffe3331871ed87f2a34a121e8d8708f3ece488c53223afbe22fad49430122ea8cf0499267a2b9df202ed6d853fe302c29dd16566a44869cc71c1f416a4f7f674c907d777f4c630e2ca1a3510bbe6e0365d8b3f472b8dcc9958b70427c48c298f8d39b76b4385ddda5da8886bc4d607914a261aa71037a92b1ae3782b44cdbc9c58ffedb3e44e6414aca5363391c98619ab556d0e5cce29b2d7814396fff6f5c2cf10ff039f2b80f7602c80fca28cc7c27d33faa914ab6d548ca9717cd3fa8b851c4d723f1d366fcbe2d8c9af506500281ce7b0498c2fd6e949e26d5bafa06d6bd48b8b017e1f781eb336da6274fdb0d32a370b97ae2969f466a6aa9e7d1b6ed8e03156f5f0c5189fc6945bdcf49543e17cae21038fbecc10d5a0619a680a74f1d3f403af254cfb77bd4006f6220d58cac4e1a25b3e993b2aba20df31c73efd38a4fac5b1b44c8fc8cfb58f271c1287396ac82819f4d1707ba1b2b31655f15839ba993d24999b7a0bb1b79b85e8931b67631138cca61d7ea297ef64f0d744605bc8e9262b7a7d2d22144fa64f05dd9538ee436bfb4a2bdd78ecba42128180c799a76450512dc4b348bdda0938fedf29176a68dc3de344f71c4a229c764e5f77f50032c05e53017f4e321ccd90c5e889f0cc20e313df4028d69ff85eedaa61f4b759b9e576a39ddbed5e071614ce067acf6bc80a4222f4124f78ddac0a08fbdc35807e7a93ceece9b19d40e38ffe5ec11c2e1fa1b6743686055246a757805ab0056293bfac401a11bc75997eb5e09b5228b8617d8742070f67da7431fcabcd5c87da58f1a5329f10dc2d4b31ca136003beedd06d122168ea3f9919ee3b8cfa606a29fb131744522f984b435148ea0060f911b73e021ba6db8c473c1ec18e2de0d89eae4ce8c836dde04e28d6712482b201d364062b1c976b17891a3db2df9bb8dc62471c3ed9c0a43e5636d41859eb11a4b0b672d44997b485f6cfdeab15ed961d33869b129c7b0709b9c12fa6b00b58aba6860cda5e53776973b57e162f2b8066f572a80bd790f6f4590db254d1dce97f05348b2e260451720b7b023dffdda6b9e8daa9b334228d486fae9e7c7298cfcda791dc578af3e129bcdf60ba907cbc9bd470a8d971623b5208b26d978525b70dd0012c69e113cb6c72566662bbd8d98a7b1996d58f740ddc9af02732a34136be59fbdb95612bf63ff88421167954245476a66866707c803f7123c2a2341d05c0174b9068f0a73e317a0387ec393311fd6d4b499a03087e9ecd923bc9e9a05c3d14bfcbf814842183fe80bd680df9c04d2ec7b1616e47c21209f08a62002b1c1927082f670e092cbd08d052a451bcf626d34d849274c0c09c8a6022339557dc96567e674c54657ea51b7c2e8be2e8d6d42f1ceb7447618f07e3cc63622ca0fcde0fa1fca8aba6c7e64c9465195470aa7de239f52a2cfa35747b4c1a1d214e23003031e6b03a708c9db873d6d005c8cd4ed3b1de4c32a083a15788c38c8940fd29b0566e71f649596839ba24830a069f2a049a0c8881e865487d97037ad29ef2c2931283982649436944bcb4fd21af453afb8a3ce8c9ff81eadee3f1e1d7599bf955585bba10142a9700804667c7ca66d5125e31d5034c202709bc1e740f6111545b98c46f780e87603f16cd3dc3a2e05dad75c964a752751ed880543796dd1306cf9122455e5c477b76ccca43e3bf3cedd08cd430d627c069b08c31272917941af170ce038092994b1ec42c29856b7ce9092d5bf338ba49b76830b90465b01015d600d0880e7e5439b4bdc9b6267d40956cdd387dcd9231fb9367811628b49c8a833fff970cb7ad111800e015440628c0722028a9ffc1709c3f18abc5085175ce16077eb50b8d1a097a081ba84abae35d9d34da6ec2f29ed3699ac0beaa3d4bfa1291f8ab2d98eb68d001450e0e0d96d5d600c15d2dfd57a8d88d1d4a8391801bdae1072e3889171627861a5931f85469a290d8cb6267b6a48e07b91a67f61edda028db43856e12091ed6396866776ac8b815c3e775a6c509be2d72649433931dd28d0e5e38e0493e75b541a9bb2c6acad119a13bbf8f4d5eb127afeb658f347fb3380664ed2dfc65c2822c752da84dc5fc62f2fe8597fc14895bb08920ed799838ed880e40acaca1ca7ffe26ecb2ee7d4637e5a168469e6b7a2608d2e3314ab53294f579081b0509448ab5accaca7649ca5d62fc2f891f602686f2e04d40e50d40b994c24337516f7ee503a372ef7c8631951e6de0b323e201468ec0b3e3f009c681ba405c3c629e71d7d361b232fb85a42417f385c59cb7573e5e6a9856b6944b286d019fa812fe3d0b5c36495e332d5096ca9db592adab96e845a5bf5bbc5ded33c37ecc0ca0e38052625667474dd08698180b812245e55244aaacc1c1c0001f3348da3d10edbdcd77bef9ecdbd326decc0db6703d0aab8e636a73ee8470979f289ea4de4985b9df29dcc998e13f2cee8facce9327b2768fb41e8bd705079290704c72143c2aa6d1f85312b38ad6eff2b99bd56e8d2482eae898ad2a6ed59cb77df92c56eb102cc5e6a96b83475316b841a0b8117546073eeac0983686cf23c3979d41e3499bd6ab1bf9502616d164a8a414ebd6063fd22436d96002d35ce80cade701f78daa5c77a8e4438b0f64efe8e1b4cb0c66e2c169530655ec400f4da341f724f1bda90407d11f2a81f4d030873962762fdaf12a7955f2634c6896aab7c3330b7d481d3a5e59be4eb220c0b3a73de13145b1701e5878c72bdc9b2baca215628015ba6515a2a00a574b85e8408554a7f0fb9781c99d65187fcd70c533c47385d42f71f20a9536893a2db04261253754612ca9638508099cc2f3a1683842761a2e6c6f3d37aad2084fc115f94c7914b8163e3d27fb2bb9a269d276051715427bad3d9b41035497457862ab3541ef3adc1c367dc29a6b839fab415f35ca545e0b90e81ec9ab438d8a7d60162495f30e4d20690ff919e08e16a1f3467ca62d1855af3475a18a56a27c75add40adf872d71c8f3db86450b5ad45a706cb5d3497330fe4a76df57ac91ced3d5ad2ee4955122e74f4cf834a7c936951c4cdc9c4086b4e01a053b63b0632b85c369e0833b44142f80e327867853936b54a59e94c572a9ba792aa74b363035ea9e38f5011aa5f09ea737969f4d15dcdad5c8edc9798fd0ae6ee7bf511ffe92c61e2b61d3e8169a55dd52304f494c5a04b5a66cbd3f6347097b65158846c79a0d496a6b2c73261f28a415b8b6194da88ba0978a1d42bf738b3a606f8df76742c8750318c0a85bedb1c9d162deb8896558dc560b5cfe6adddefe686f6779c1b4768b9511ce8c6f4ce67e0da2606a561e0d75d2d0dc1e7a18ba4930cf9edc6c9971f3889b94ad33a49eb3142815e317fe0cf99cd1885504c0776b9db9f20f6d8a9bd4661ca6c8ee6abed14b2a814ea4ada99d476bb589bda6697a2da9689d096e442a72467a08614dc80becf49e22357c5cbe4609ebbc0a869eb90f95d6a7ae9323c398f39df2bb369a209dc247d721775340be573b3960385bf655a9d4a5defe4a4df3dd636f16ce0766f8bfd7f55225a6ba8bd3e50c2b3845e5b21b636e2cdb1d555a651278a6edb07a820163a2782c9277d4501d56b6063312558bf0eeb4613fbd7cac04fc88ff9d521e39c4f21e72ae1ae2ea2be8e4520ebe7a81d6a263a8d9e8c8577d61d36fd5c983939da6d8af0d19fd5778876aef20bd54f32cb3797b74675ca0b9ba16c0b5a3e856e17731db476cf3e0043d3e02d16a810ca37a0a795b15b67ffcd2ca433ec5426a6084fc80c60dd53b92bcfb60bd83513eaf7b450e30f924bf89bb3acf341f7d7d3cb7311265e34ef8890455cdca678a9373f959547616f1eae14a666f36120b67bdfb3ff769b72a6a31dd205307a513a5b494056be7be451fef5bd04e10e2ec6d2ed5926a6efd332cdf312580701213c5ab7de483bd6f243ba3843f8e1ea51cfbbbcab76d0c11b8e4e39d4db6455599243c7d5e26153491eb3fdd5f332c5b8e3c455f001d4313a116fba7837b85b9c397a114f35bd1a0b51530e58a3bb4250c558fbb854991b695bee3c026b6376d4e2411b838f61275c3b41a1ce98d0f3420203e052a15bef78b0bbf08088e061ff33aa3dfa42fb12156d26dd67676be9ead54f3af0ceeeea5f9344d93385b1335a79386fb26bd02bb89c3d536ee5bb7fe4196dc785661329f6c2b5d3c7455b0377c7ed91c024607a2c0d9d4f0378b38f96c6ebb9c2fce1be5cca8c2f59692cf5e82dae9f197915e3f49c189e3a2880e3b16d6be52723f6c7be6809427d634b43828ee1353e336e73cc25d6f3d1ef78751fe8b7abeeb6e1c848318df8dcf274af202debff687b1fc991b7ca0c3b97d98063932f25566554ed97ca7d539257991c3dd35ba337aaa00105bca7480c8e61b62f7e62f66c33da98961c4e0bfd52a62b9aae01f5e3d1891dc4e558c9f5f817bf63527645ea8e73e2b236996021e1e673f7f578b45dd72f458f9dd47c678543cc2d498e8da317fddc061e348ad37ee652c0a1f1927adb7e9de1da5c2b4b8bed6aa1da91d93e600cac5ac0a559cf35dfb29f902d58bc288c83c16907c8289952ba57c2b9ef3ed75bed9c1e52dd764822d184a954ff45a4c35a60123b503aff9954fd60edda9b3d4d34f265bd857d45bc8f1931dd3abcb40c24ae9f7b4e540fcace9b9ad06a068cc8e78aef6bc60e3b3f4a0c6d787f17464e7ab486c588d1754511da9f929fda67684a7a7b9690a8639e0fd79a5e709978b766c4be72a2958e39caa78c33412ee09f6bbb71182f5d3f70d2bc0e248382f953df70dc6cb31a2bee69a860523873900f71c19e21d9a1c5fd5267ac2df82b50b334b71bee24aaf2ddc95311fd916e6322cfed5480da124d4e7a229cd569d547f822b23c5a8f4031f3f32c6b1ff352e935943fb0b6e8c5f975d60ce6b6a7fdc3baf67ab77206f182b71876c745febd36f30102768ca1377c52785ff7a917a81ba4e6fcabe4c3fe90206c4b70cfcbcdd91047b6fe874a47a38bebbc4249996b8cc1234dd70d6bf3a37526dcb9a64443b846cbe66975cbef1842b95f818d1bdadd5ab79cf3de10865b91b7797c070f803f3f6e1239634fcd1cb54081dccdd706be342cf9b032e6780eead5654100b305b89084c45a408e382ca74f54a56c2020ce1ccc5297540512f00cd6eb18efad5d6ecde3028e8f86b150eacd71f12ca58fdd44f7ce243799362f6387d68b60beb7ea37d93c00581d26ed4eaaa24dc8a528789383abadeea8614b9fbf04d6e5530fc93ea5f1c6defc9437c59b94faebee9e64edd5759d4beb3199e2c6650e35496bfe9daa5812f9451e29cb54746c503e732fce3658bbb8658424ae523199a14f0101e39f0820d01e58a285d58875b91ac3245633285d74be75909764c0d14652862d06aa2993a683a0b81a9750e1b865bd9afa2b09e45efac5d53778da7e01c76fe57d1ebd856c834471be8b83d84b0361f7b81cdf5fdeb697f2dc95c837b7262ac050d68d1e7b14ec2e5b73367cb044e5f90a77acb7f56c5d309eaafb6475619e9189c04ded331eca02b679f70036d24149e04ad7a5538aa17600a8cb2731753613be16f0c2d0ddd2597d7eccc6f6e560a2c62cac2e3bf102108de23d102972e63c01d3e2ecf7488eb58bab9da2c5ec886714e6ad98cd91c3dfc2d1af89712d363a64f3740ad81f1e9b5987927f7244f2dec94e5ebe12254fdc4c6917330dde0beba5fa7cf9f24d3da361f4777dd7309028ff31eee75d9dbb7e5438112407caee4ef0d09c2ea652816cce4d659a82f4fd67aef29bd98e75bb39013679d4dc8d94843d1c634c3a0a1863fd3efb2aba5c697eb70c82ff38e4e4043712c10f370c0193b021c713ec26bfdc112c93e8ffbafc73af110366a677c6ddd68c5ad4fdad81d121d36ac14e12c2aced52c630a61906c9b747393b510b79935b9a2def7d79946c24eaaae637d00dbd5f56ec3b5b161e55d6a6356a957dc48b9e528f4633b002c50d024b43b3bc683eca05c752f201d4148a6bff35681d49362c90f9e7af1a94fd7ee9f794a084116b57c8faee001d9aa0c2cfc86918a7038a10c3ae5b1cddafeaed65ded55517473af6341850b2aaf8c11b217789c920620bdbc3e54b1fd4e4cae47ff821fadbfafeee88775e5777cf5f7ce8e227a6410e9b7bcd77bb3a6f7082f17f89a52bf1ed40fc90b0a7bef156bc1f0b936dc24a0d00bb5ed8f424f06a8f79028dff9801f61f08642b0d5ae069ee86bfa9142e18cbba584eba61878d50f5c786287d6a63419bbdf5bd768598238f23bd4378f328d2e5ff91a27c42505eb92eb6be16965030192a6ce005b72cffbbb6d0873e5065a77200ec59025cdf1465a9e8b26d18f8b554ea37b769b0400ff9611f852059312d6a71ace3f1bb97dd567912eec2983ec56e8f998be3e6cfa61f0ec07d9cff958819beb0730e42a79f10c739544eebb6d3cea7e8685e146fb41bc55e0ccc6f192e5e016437bfba2f9df01d639f0dea9287092758e7e2884c9c57af64aa88cc2829fcbcedffad7a36777c255794c5dfdf2504a48cb540ed2dacf74f6ea7a84bbf23805c7430db3c3f68258c93f361e108639d2f3b5d698a06399f1133f6ec9fb3ee2c52cfaad8829cc913cd0aef1f7fa67c10da81f94c5ed2af758458563e4d3431c2eec28b6b43344dd005cb65bda0fd053e5d561de3faea45af6dfe4fec00fb73b4da284fdd7a7c3d67f9671a8bbccb125dea0dae7086d39e30c359f1de100ff965d4482462e3e14f6cce9a014baf788d9a05418cbd1d716c4f87047801850ccbe74fdbfd8627ad061ddf0e72329abf5d0d43f96bcbcd73b4c8b9dfb941c9763d64d98723f568c2e5a2e858e9f308a53a2258c6121c3f7e3a831fde1178f288bde678d227b976c87c6bd5665d0f82fe3a98c0153c1dfd1c011e3fd3ff05ab6943461b188f4e5ee4dc7c632462bd0b578b2adf061e08404fdab060fea5841c8dca7cfa8634f721cb2f56655d10c5a4bfb6d20511a9f13778fbc35a7d5b769ddb0f8a42cce09ec3d9dbc698bb978b036128df323cb838e390eddfb8c3dd5959d4339f676249382c26ba64685f49b2cce9c32a5fce7aff7ef22e634f9ed5b02ff2c07bde4556c2d34574b29b70c942e3bbe23ec488df33b86b055d1b899bb6d8ab0b1c53feca4e4027d463df0dd2c7d97c6908680202f38794f76b4882fc4acf0a9dfd26b875729c8c7b7cb9d39e0aa4f06942b0c80c5f346aee7f13b7e390ecf1a92101d3039554bb6115ecff649c6c88624f9b9803f76143cac314233dc4ad7421891b5f005e655131f65be3c0ea7193c6f7864fa5e70f85c3e81c6e2a49956fd1b0de4532de171a39ab0c70a4bf0bbba8a140415b13a61a417c2fac7643db0b41da6b67e7255c84ff7a82b0cde0909629f2717584a2c7eb78b790d945922ba2d203ce0df1bf679e7a57deaa7056727da681f7044792699de2453529d44df0635d8cf1d21fc7e01aebcec83151f6b29c10f2c5fde850baddfb78102d01eb3bcf04122a3edf18db7fcf587f4fd3127c29bcef82b0b6bbd851bc84e8cd4ebafe7aae7c87f6f4e4e5efd4c0af91d8892843dbe28082d6fdf71209ee8387ab2bb779fa36971e287112cf446001ba199a291377c9537f1cf8bcbc3d10718f2abb0a61d507c035f0be06f7079fa29dc1f4ac3afef8c6126f54a3aa3559db14e96b5d7abccf5f878ab1b7cfcd5c35bdc510b4761a492287069c227bff94150e71c1c25f3e83479da1dafd2f37452070aa746f1fc0e6d576fa18e3044b80e3b3ffc9fd76a59cf8de107003b5ff3291c96d7c9b98dfd2471601a686eb1519dba67632339ab7d2eee70b543caeb04c539db1f3b8d26fbb298fc5211aa890f7f878f8530646cf398e22c0fbfe39f77c3eaeceb5f9fccce0bac3654f717ddc79a09c53f5eabe77426fae9d34af58c9351e7deaa97943bee37fddc17c16e3611a04dcce414156326c106c4bcca2f8dbd190e4431bb0c4535a1dee541470509bfdc355702cafea3e5c99779f2acc95e1749bd67a9ee9035f04440a2113c575767f2eff87f7d7420ce88200c12f21525c587fd45327c679abfead77bd64c66e272fc05f59c968ec8fbaabe2885a56abe599fe11c83db3c1219c5d6f006fd3cfaa8251c40cfd9f99f76bd03b60db5ab53c1ea253b5b0fbbf2f7f99e5d8ebaefb91ce13515f6e2a3c0faa9cfb10a2ff7cb4554e25e18d78943f9b69191897a8b6af9aabdd7bcd5752793f141da9b1be0e063322cc00798f4e6a6068602a891183e74a49f49e5cfcaca7bbdb9ba5dcf567a6dbb1217ee546acca05e68f623fa5a2deaba557fe3a4bedde85351c6dd267dd6b589bffb72aa3d9f62114d3a9df0460269a57c4e86fe321a5dc4ce4d22947db570d0c457ffa27c82baa1af29216562dc681899f2d09dd35debdf3c6981fcc1beeafb8f3de5c235c5366dd73de9015beee40e8966f9d71af5c2f3f7997ea3e80f9021bec1896d554df1445b2a8d88cc64dbf752299ef2418bcdf06ed2b4a1f14879d1cfd06f675c1dbfb953eaaa17e3b0fc6ed13ca9b7134d94b63b3b6634aeb57b47315a91a09c9e8390072d7744ba6652c3963a69b3f9de230a160217ddbca1b58e29bb98b7f48ee9a441ff4266308e803f4ffa012cb35fd9cb5301517a5e61a2537429e9eade0f3e7074e4b9101e68d1d82e9dc76fc69364f7244c865d15a4925125701d4c00350e45db0be80316493ddc7a621358ec6de00612ee0cc99256d393660d4a2449533c09ff10e5ee20d11038646f55a80f574d3829dab40a5eb81094910e40104d8eb3b53a8b35619f9501838f493eb25ce76b06139e5484301f010af9fc9a5c53af47d9bfd311c2f99a94214212944d8dec476e2566dc22538d4971c76678670b0ebd41372cfa352e65f14f43161515d102094e2cf74e418fd2a7618402947b2347964e14e64e8c5e42dcad0cc2191e958073cf730e3426e3363a3c94fafae0c0f116ce3bc62fa13f4b91f99c16535fa8be3dbee16940fadf9acc2067a8cf3bc755c4e1a30292c26aa13d70e19dfa7038003742fcce8a298cfe770ba17534f0cee9389ad1e94e758aa692edadb1d25ffd128c704721d9cd50f8242a87fe3d294395f30211fb3e042392a222cd217e4b01fbe056221a5285f4eb2d6ba71e687100e6460ce8a9d8512b68f6b7b5151bc47b394e6bfd6e0f86e3cce2b0190925ff096bf3218be2c6a3a273bf008dc1087202e83abcfe4392f4bcec0ebb9cacc21b7af58e42eac88e41f1c01833f6d20c0310b948533bdd5204a42c7aaa4228339dd9f54f791bc1d28488b7009c3722d0603344f8b9dd66eee34c688687c00501573c92eaa776be6e796cfb30fec2f0ac844e39f43f3ad0514f08ce31ce793c8bde0bda3456c25dd0361c604f036646725462cf308b14998ce2667492a78e3303ef04e86c9a2b83a0d3cdcf82a1dd4276799f57cf64752b6ec383797fcae84719c6f141c74a7271661b23aa333dadae5436945235a577fb99b3befebc4cf83fd37c4f9a623c617af486634d872f98c03cdf73af19f6ba8bc7c3cb8bf697e68bb9079ee26f7eac39ff8eb1c6df2bcdbd42ce2e9ef8e073756b788df340e6931e64096377044b179553553508cdc80dcddaf4f621c49be6494a465072b1a5468201f1397d4ac4dbeb0ad9c5070b2959e20599ad9e521f3bca4c084e52e12ed1fad95f216f9bfb73f42e02ed86143fce27a5d6c53006011ce74e484f7ea3a0e96de692731db1c9254a9acc051d989bf1a9f1ff82ae73177abce7d38d9b9c72ad8aab27539ca88deacef4e5e42e5cbc51d7bcc9060e54afb0d2976584def3bdbb0e3bb55cfbee7ca4c405087625d3cf1bb34edfe07a8ee0ab01ff8313e47f8cdee7c69af15c3e86c60f3a1568add90381fd0e0e5f81a76ff87a88923e9f2f815412c33856d46972589af203c27292dab1ca85541b0bac57c6a639d5fa1b5896bb0aef125b55b2527a0859d3dfbeb4dd1ec94f1cf920f4c0f68f7377663c44ee16ce488580f7ea4efec0d4eb8e695b2d204b69a7608addedff3abfdf62d9e5d16b83b23f84e2dcdf2480768bf7a36bf2a0f2cf2473c9c409cb6292ed86976119b3f985da30a14bb7bd0cc3c57f1a8e291e21b78f9e91b462a01ce05aebc27d0d71180ba6a1dcb235286ba15993b118df2872cb84301cfd2b17d12689b69a5ab6c2d0c8d5eefdbf29c280f60e57bd55497ee73197fc43ce3575f3a48fd006667b194728192c92a81ebce779be013f05724c7fe0e7bc93369cfa1be0de61a7c1e12c870a374ad4ad8d07e32616ced13942b5b55e0e9757cd8f32b08bdd67e14f92be10e3d5af4dc148e944e1985d8673fcf252451fd0efcc9565a6ea7707efb163746ab6dafe5963a31a5fd153eb9c79a2f0f7b786d1e9b2f73fd3288ea02d8de5ff28fd57972ffa2df91da7b184606b8c1ed6b98a9b76064d7fe51677bbc71ffd1041ef6cb648b111e616f9d8f60f876220f9bf76f92ecb6d8e9291608c7a9a16e2bec9ddffd3d0ec6c3d292f34a41912607924745edfd11f93f00fc97800a08b393cf26f760f55dcc7150d88f344d4122912bd16a4c0509199783b3ba06fd3db333267fdf637c2bf1ca0b2c29bd7fa9398aec98d20cd8897e0e87225ad008c75b62d5c1113de56a23967b3ae2b2489dc3f45453f4891fb288fa5614665a9992cac5df8e56e08cca4664753ef9793490d19593271b2bcd79ab941be902b91ea4152a009f7ad98f94bc1d3642f177db891c0d832250e3ae913790ac9d1c095d5f749c82e5e0f166b662bf23e947c3c13beea67411fbf4a136095dd28692840eb1c96a8fa758b80f3d15f00e9cbc7751a81e3de2d115d54bcd6603dbdedb2f5b85461d1e54b05731521a66185f54829f8c7bdd6defc1855f811b065f9ed3c70c88e0a8f87a55264871b56fd94025fc04ab2f5cd66cfb8981dd2fa0de1b107adec6589085bc7ad87758f1e8d117fca8676943eacd33b1e9f5e32d87db6994b1c7aeaf5ee914d9951c96bcaad1ee18610477c4a64c589ff26cd32f5b634fa00a354315acbe78c2df0dc42e2903d31100556dc6ab3156ac6c5ad23e05c70ce10fd79aa992efe54dd101ff658da69b42d46f096aa8e39b9f8fcafcf5d243e3e2c747b3f8910fbf891c97bc9c515cc1b88cad8024b622613e92bb7463bc2c8d3cafbe24f4dda9615a2aa2ac8b386d490cee5878f63e6b0b981ff2ce3c66d4777a3bde757c9036366692d2bc08c6ed3cb8bf91e09cb10951c186785295b4b32d6e1cde4064bf3b3f479898fb146c3173a70f99bc17f5a9bc1192f842fb15b2d6a72709d5b5254f76224a73157e63b70d060bf43e7893c137ae452b72687e41ce1fed1559eddebfdcffd83bba17b86c21f474b514b3aace276f3022ca21d732602976fd21348c79dfa207916eda4450a572f477cb2b630ad24d7f83e82145ac00f229fa7f4e8708c52baa864182ce64b4fbfeb762c9f6ed83937b89d61b5157973c0530367be7ab80efd82408e279ba9e3337ac4903e065c5a5d67c28291be9f8dcf09995b904eef3a2f61a46cf097157ae0a126353750903ac335ec35b387efb498d7f6b28c71f40c9a3c649263c344b4dccc34ff3131d9b5b90d0344cfebde6dcd09dd1fd3ec17c1f958d21aea98006fdf0afcdfb65074cea5c036eedfb5d638fe676e8724e8a7903a35a04cacf9c95f8687d489ecd2095369346cfa427679a7ff7f709c0c3c45c9c7ab7efd4211e2371fe5f728134338f6151b5c4ff637f32cce1202cfb6aab4312ec99d68adb3adbcca21e12dd30542e0b1d101f258bef5b5cb0ac35a361f4aad066ba858ba0114c75e31f016e72dfe0c133c2a4cd1ab5103c77310d6bbe47f7562096d3b7c8113efe46496a59458b813c14eeaca7a7250c618aa173f407a71473597d507564e570916b885ce11631b64d4a85da82ce1d884e602a8070ede28a5691fd5e89fffdf418a0502a5752a947f664363e29565cae02ed701f01438557060cc0013b3b277e7e43191bee22e6e52b46eccf09472d5a4b62a5ac9544a40d54387828bba2a426f2add7bcfc81bb9f266cc1813b5e0ee1cdcbbbd14339646cee2c199bfcae9b31d6daeabfa7626ff3bf7fc838809b4483aa69cec543f30e649b2cc949fd2da54e22323bc7f453575ebfa0ffc806051fdf183fe4c75ec0c6822bd672c7a1bb725b15dcafc90bbefc2f8fdf54c652f64e0028fd5378696fb8afc85f0dc2e6829ad0b82b41406471eddd0d0c970c1a652ed6ff963a72165438360e775d4135fe21bbf1d704fbbb779fabe4e937b33e97f2c52f8506d42ebcbaaeadcd46d76b22e48859e32deda53242551ba46c60303e30ddce2b8d20ead4c42ac23e7bf1c00c609aaf5c0a4e988a8691f2163e5b40fcfe695009fba204d72382f4572a48e83e7f281574d50a1db4fb8ddc80f8925f4757b9f55e94ac7fddb47d33b10d3abfcea7779cea0841a46718f210a55fecd912fc93d199e1e95b643d0f881d9baacda1e8848151d18bdbf697333cb8f66fcb8316ef38117e205f2f52bbe83ae2c1fc9b58c9a95850eb62d6fe90c33b0ee52d77b305ca6a81cf65c02771737ffc5ee15f0ff30667dd7af6ce08552742d734921609d09782f83bbcc6061f4fa7286e4dac83b07ea0df26e79fe8fe27330e133955bf93ac1487f45f50873ce138afa4f73a11baa3038e3f2a996bd2f870e3668ce2e26cf475231f0e1bfc120f91ddd4ebb38c86a69f138ea8ea7332d7a340c4146895c5bb5a18efb9e747a7f3056357220932e4ae9810c170f98dd6c8a96bb397082ccc81e2c13d31a1141149e4f2888125c943b022fdabadd41cc8750a0c42277383b3cf0929e0ff444f18b514ce9d51f87570ef9ab848fd7f90f7536e5afef262b9feecf332417461d9c9bb52909a2a8e89d26c6c50f776ab1e98cc1b5483671f2370b3620867524a4595f2ff835dba3376af169a358c7fd67a0f8fc57bf77e7e84e8c4762af44ac7cf19c7f7f9f8a0168dc17b4df1fb1da794c48b32de912938dd689f9063974d7f91d003576c07c402a05f396a12c9e00f93cccc99fd8a5f64197672c5cc66101f97b9c671b514266437215f2ed717edbe6309c82db77339ec3a1056c100001e28186a4e8484b18a38e83fe4a72aee8371f1012411ae0bbd4cdd59c1a0aa35ba36f66689ad4f9f083723f7172e436d87fd9e55ede7545b8639852135383a439ea19cad63f351530c3b5f45b581497cf6514bb27d62205129f68e4748d9da32e858d6eeb0dbe360a13982f08db5fadd576e2b29bc715bc169f68f2c160db67e37bd1b5f7eb16329294972d42b43d9463a6aebf4e3db5a1ae8cc80d9eebb49d9f1f20ddf9feb7f323f0da624a3fa401f9bcecd5ed4613bf1169650efdd868b1ecd94ecdfcc06fb16eebb838b0f91201bbb58bd87ce910425efe10a4953df716032201f2d1f311359095c20cfa51f69dd8c7119b057ee1ee6ec26af1fc1167a3ee03faf3c01f9797038c5b271fd284aecf4cd0eac9c33e6ebfe15c384d2d7dad50380cff51e53e2f73026e3104e7b6e970fb8497798d7183614c66f3e1fd5d498877aaafb57a317be9cc8c27b121aff60d942e92373a841ab4d75e5fd5461ac46f8069e6bf2cbd1f5c04e70e6e9bb6dfc787bd6d526d93c21b6a918ddd517dc2d73dd6b52ee42081cdd99d43a6589cb4f2ed21f126631f9dd7e74dd8397bd609522308aa08bfda6037f1360fb7cba21c25e6f88c74274aaebb6aeff43b511dbcb3ff159082082a7cdcda569f602b7cd5d917a60061ee3ecf54aedac22d08d9970876741896eb41517de4ce4bd69db7f28e13447108e558c4551b2cfd48dcb834ac1c1cf4bef4e6135808440e6ac5ffe6ae06aebd0062179210684612d748ed4a6c6cd44312eef10cc4ac9e8f4b24f9579f3616d57201e76e3d842a5138bb6e38072587a4d8f07d163e77955147a2e4c90cd765beec50ed1173dac197ee4e533f3939575838273bead26f0371d089d1e26d39b8e4660778b0d11345aedb5a71e4cc3eb3714836e3986bae30f3a39257e3b19d85c8fd9ea3de103e1533943fa42651f437521635daad3ac07a6084e70530be007bdc32fb07fdb3f733977065d04fcc68bd99ba31bf4f7fe3ce99813e3f319cc7f0c8eea798a95b2b34f72940670a4d5ea83918aad985ebcf150ac04c37c6c697e641b7b0fad542c5ac7703093df522963f0ba383191b3c1aeae326154b97c6d2bea08347329719c84f12a29883de19678da1011b6d8dc065fbae9be9f5acc510c94bed42fdf2d7504df0d3a284272ae8ff202ff9770eff578a1f2e850c135d352dbacf590f07ee544d1cf1b7c5c58877ec49f243fcb7f1b2f09f7ae9fcd0ff8dbc2c5cc73e224fe45f239f0defd59fc48bfed7ce991820d71b23601ba4e16294b478a78a1043cc611d261bd9b48f4f0b7adf0666c779ed23f1447d3672d970defda87ce85f4d7e36fc7b4f2a1fd2678b9311f7d693e687fa6be762e2bff5d379a2fe9a3859388fbd349ee8bf561e3baeb33f8d1fdac9c325c6963273ab7d1b82da24cd5615365cd76468ad5a353c535385e1e8588ceda5705fb2d4ffd52d17e47b2ec9a78dc2835df314f9df2535f227ebb2df9d32f19f71adbc585e0af4294bed67dd3251bef3937ced293bee375395ef5542234f322ffb5c2a13fb1b67dd8bf5f2307ff94c9cee95bc452582067ce43981d998c8f85daa3b6c6e150218019d96873dc517f223ff1f3f2f336c5fb005013ca73b0407a96e82ac3c1ebacfe2f905b63647c93d907834f2bbfb7c946fad8ce0c491f2cd59b372d1edc15651480d74d1527d0d615dd33560561f1295c29684350435dd6fd9d9220dc7e4526b09a6ae81c0a4fed55cc258dfe6ce405a9e4df744d218067cb125fec283d3caa929d171884087f16a5fbd4c18089afc6a96ff31b162803714d67ce0bad0a9e2363806fd079281a5ac4f88786d860017246b18f4152aea7eea76f1e4aa870d6ef3a6029c4b22e45e2270503b0a677e1deecd1f45919517ea9604bf13bc7f9244039e3e0f6519d6d2630567ad767933864720ab23de647d2643ada6779d7254a0f1fd5b2af01487f01fbbccf743b542c85ab984d1d766b796271a97a274d22fe27b390dd97ac3b3e1470b072dcb11ce3acc50246626f8dbc1733293c28dd6024b0f2fc91fa2898d1b1e85f618643bf5223d92048201bcbf196ef7129a5f17454800d590aa9d6c07b7f12241886728cc807c1feca1e9402f1fd4c75a54abf5d6f1fdc9f72c54200aaedd19a7ef7fdb6286970ddb95de761af4d5713255139d2a5d93becd39bc3983da43338d027cf587a7915b2057fb921a97a9b1d20339d4ef821c883d11f84143cbc434103c64047f4c8420d950fa9139fb1ce1d96aefc7d4176844038c0f120c958c7251fc29b26d06682eeb487d40ab718439f187658c141788eae057caf7aafe10b8651f4d94dad3ee571c59081d21f2a4c5eecdac17f6d7e589b29e0511f1241214e2922048b634640740e2a99204195b1a883da5d96a9073a774947a455013513188b766a791e5a8ebf5dcb5daaa845ea03a574e0247bfc2d3f7bfe51e0cd7c1a57f42cc820594889aee00b658d3e087493b7ac1c6d6b1511ca59951e78036a23e76161480754c679b2a0144fbee18c2d384f370c25df5b94d10a95639616b11f28b256afe8e5b5d83d99c793a9c4d4b70260e7087ff64214acc5d38c2d58998d990953dd4e62ccaa4b2c12791d77a2898efe2fd320a67ec415ed29abf09d285a5bb1e38824ad41b1c6b4928f071f64e70a34ccc1928a588fb094bb76b2c9681252a4a170e5340fe0735f37692fc64fc382fa964445ae023c91b766834098f7ddd34b1269a2d07de6676c0de5b9ce2fc187be07ae01aa71b2c63207642ef6bf3fc239f6c58609aaeca0aa0fc661f6409233e9f587606d7f95c30ce8b00a150f0f6d03beba3c7d6f6b6ee3b7e3348a8297bcd0f830d6d6cb7439d33e4025b860ded7cf032f674d1af5339565391d164f984e86288ce2b0037ae6c01c869042c025138c8b5b18bfeb6cb1e39348b8e1a157c7870b0852872137762a3a7f6ebc87f57da586124940f7c2ad40160abaccb68490fcae00dc994a1d033490ce43019d20023e0db14e6ddb2f90fa9f0af679bef52d7154f0667ee1c9c6ea584cd390515e5a914cb9aa727d22ee7ceebe3ed3ec392a9cc5329c67b61b15febb7cb8b497ae42afd11637b833758bcde8e8f3f6d838a7d7bb16973872e3af7b0b537bf15e78cbca5784263880963ca0f96ea9a17ffa4c88561e8350125b640242a8f20a77b4459eca0624730d8ea888d141982a1d6588803091fe2b1f343132f0d6f7d1ef96263999113b3a2fd5978474fa1eda115192f9895a1c2cd54ec434d1525013dfa1de0fa57502d52141215db87ccbfc1045c11d768ac44c8181d0acb2a1a6d4fceed41620f2a88e6ffcae79c74f58e7ef4078aa8eb3a51b810fc36018ce9a4bc392f9d0771d03d82839171855419a3b54f7f5f87b0f54012d14eb4881dc056048bda694bbb8371c4aec54dc01d356c35362ebf1acf76d73f3bea5edcd1a0a30487c0faa65ce74ddc21c4227942ee57b9b2e0003dabd44a4ea104880f56e437b8d515001b730a586722fd5d2e40496ad1110bb50e5acb1e6960865a1d52da675642130ae8365171fce4e91ae298bb3876b01b22d1fb22703a5889d2b7d7f9b2869bb787f3057b30ec6ac6dfb5a8e3152e178eae6f373e27bdec08e6210518add5d6376c366dade173b4aa7123c412c154dc433317a61384863a8cb938b4012fbbe9cc27561aa34bc437dc76313eac5e0e93665efb0e31ac00ca89ff4269ca82cfb100bf4837149990793252f11e66cdef3344724c0b5623894a455d739c0cd6287672d5550c6086257239615a28f6a2f28968d404147c8c732098ece8b4cabb85e07e9934f5133191a76ff25a593c8d1d758b444a7e38f5355c7a1363f293b33486906b338400be36184e2f45917506f51a900d3c1a4ed69e06fd945205e85bf15da9c11dc60909448bf5f39680544dffbfc575f5feefb746c84b2b3e95d6efb2d65e32482e3ca0837227388edfc37d10d2f9d7f3418fc19cf20944e63c98404e733ab78f69dfa22b733f8c3a09be3ff137322649de0c498e8f4de5f07cd0baa8fbf3f4d683b73170c7601b59d5dd6744b8f53c138fd2922a16dbdf017651ca85b46d7c0b8d2f3652b91637a3c0d48273aecdee37e881e8b1279d1fb1a2efc22c7fbc399f6d397843410d7e38ac8f96e9bfc5a34dcffd86275195b7532a44d4718ed416012504da4b5c314f985c9e52a8323f0ccd44151be8735efb285f66efee44d5a965361ffacfbe3175e613ff365518c864013b963479f62817d403085b339bfa97440c6b7cf0f63f891015a781cf3268fd79b798dafeafdde9728a7a36fd2a97c12957dd3423fb5ce86a0dac9cec41191239ee980cf779db6b807d007b7b707d9915526f9c09d9fa96d2fc14f9f1871c4fd7f3be64753b6ea737f8b63087fb1432ac1ae035ef96af8d7fc1359ed95baf8d63357a3e48aa9c73d818bdcdf16a7705e5941ea4bbb567bdb79b36a7f0cfd0dfb814f492a5ebc651ec24b6228870a73fe195b5bdc0463f4758d22bf16a080fc03d6558315411df808d5edb12b8ec75d474e87ee0ecd71fe6dc7c699d1fc0febfc9317a4845222dda81a6862fed577f2f597ab5ae77cd2d125ae4e7dafaffd977f8513fc9ff096b54c70c181a6f3d9d9ede00377ebd639e0b1ff4ec66683abde12e05a8c6159457c437f58f90baa140747f894b925458bb46951587d2bc36619f1383f396f5daeff82e7b1420ba7b603eaf91b0e84e67898eb01e3fcffca717935bee8e0be79a2d717c1622cebe51c31904342addd1d3ed6ed3b97801f4fca580b6588a400d1ecd6884cedc82c1b778556bcd4a8d62dede5724a76037ceb277e90a194e3da6e0ae76714c10101a2f7131bd702e0986e4215216283d9b6e8cbf8314a3f428fb9b94f7f7c073eaf84aa53c6ed2bc922c6bbc7286f5b62424b787b8a9686d71b82131c3b3a12979721b18a03dbfb17bed5f53500d73a23b40e3ef22cf8043150b8a81d5f59643a7e574f3679935d1c80e0f45b0f9da4f995c345b4abf06ae09ade36284a5c71542ae44bb514168453107fda01f5e7b36d77168aebd94db1aa1d81b173aafa5404cbe1e9b9c9024387c641a5f80c44f3e0a95292ff01920d65fa8fedee7613c7e12f24ce64ec925415c9fc5b39e2df43ed8eb20eca5551988730cb398ace5bdcdfe2f419fc2a2a009744bd3435779604c752ee4b816bdfe99fef44e411ef6e16b7617ab7c4b94307ce57dc680f1818de017a6b8893981c54994efc3398c812bb2d73e7c89fd994076d0ac67ef2e23d20ac1b30b556c4687eec161e6cbf558f22d4dfbf72ecd985327cbca966935d2d0c13b4ff1407861d0a13051b12e9153e6bc7e51cd97e7bf51d3abe3858bfd05e054efbb086d1c618ce5ddde52bfbfa44bfdb0158d6146715f64e3af3dd9a5ac33b4f3749d752b19bcc04bd5763c4c9759251d07c2729e96dc5a87662b8766a4d0332993a1c192627bef2c8d3b6091a5b7177a15e6e898dffbc8e6f1509c828e21c67fe6be04401f981248d3cf79dddfb7fed96640bab53e2ae2932351ee567db0940833d9b981a6b32bffe8dc8e8da3bdf7b0bc58ff5cf03fe4df9de57af68b445fdaf2020f4f8d5af55916290798ad05ccbd80e8dafedea6720f3f6376b433659d4868e1f02f380538b1f93d2e4fedc26def1d37a4faf30377d33fe54e4119f0f07017c3b72ed43a2c49113a82c6893b43d5ca810e567c6a802159993ec5b1eee13261f47ade8f2eb24362f6c2fead6f3a73c1b007b075456e48fe13a7d32750cadf7dd98b7508495e412f4d5d0a59f02201ef681a57f5dd4eb9ec5c7aa4da337fa8f84f902e78e0f747b176488ba006c55f02ab07f2cd5f2ca061310a3b7994a6ebbbbf9c12da8524a61192d6cc1671461f68417a180b805e0ec96a118fb9d3f6fe6f77c1ca7955415a3fba860e1560371f7c1e6bdd85cc4be222be115818471c31d2e4d8c7958497c13e8b104e3275692e53e43ec700ea2787ed9a212d44bbe8f6a97256dba36ce096c0fa674f8e2bce4a93a09c8810b22fd8f7dd7b98e755bdc5620deff7575837513ccdc9e2b5e3ff38173ba9d45561c156085ac8b7b6b2acfc05c226d4a88226fb7c009d664db484ff96f87bb31c5f75573b9ffb163aec76e77b0e0ce5aebd680e4d4f0c5178443898ce7bc566364b8e688e50bd524fc3d756555773bea6bc9ae8e5092ed6743385ee9d7604b59ba1d699c12ad79470740b6d3f237354b0e1ee456c0d89dfe6088887291baf7ceb605e0805430bd3949821448b778b9a0849c8760dddb93e5d6b32975a5baad417401d7e8885a560a87243132f2540c0cff4af51750b7293f200106028ee4a249d1c8665d0b439a458b466f418a6d992cd3dcaaa780f42becc162e697e9a0f62650347f900a55adeaedc0e1d9bb070e8a1a37c22cb2aceb4d3344a367fe8e4b960f9c252e555f7e2e8c3824e983b03681cd26aedde32f5b45448b963b5f08e931c7f148f6a51c310af127a844d153612125f8d9a7a0d260c9d3b3b5cb1981935609fe63f76f78313e851fcad523d35cffd9ac37129e508db6f13c4e2f7ab0b6944b4a24e4a97ae483a580981035a763dbe9bde4ee6515471cee5e558b59502086910735a79f2dd42fb2200a7a3031c34f9d707bb08aebf55fbaece5c262e8579ce136bc55913903b51de0b62a2340c47ee9ff34fbea2426647a3eb2c59b280e45fd29daae1cfd98a1933b2e784f1e75624310cb12520094195921ed22161b64613332e8b3b4918a8ab057d7a9cae22e16d730e130a9583b8d87f9d935a69512b50518db30a024e1be348de5276d67d95870538d64be02661aece938c4e5b32308f4953c36bd52ebdcb9c4e6423b9232739a7cc49ce33cf44d5abff8a35e3b406086fae4905a89b33617d0a09732cb404ea9b6a006c05d224c17101936818c7734464580464364bf8868ed04f28d9bc18787e294cdcb0b94a0752678b118547dfe2d58574331378997433d8edfb06025e3da31ec2907cd2343ae3964993817a4b8765b7135e6e3407701c69cbd29478714e1495e4dca83587665f67da5a85d9c93fd44d328e474aecae0dafcab1ae1bd9a18154ccfbd1f10debaaf4f6202e74e383cf7d99d29c1ffb23ac1923093cfdf0b9f6ffa779bbf3cbc79a1f58577e5b1c04b785baf919d1c46549dedccd61c511f7be690e4a242e9a830971235adcdc18a4774a0a2527de386c966265214107cbea9cd78ad95d769e964491f69ad15d5936b5b1c2485848ad6922634169659086dc0924bed73c9c3838d044505de71231d6ce1460efbdf0783495f40bbc76f00d1763691dc28e2cbf420bab9479ffaff262e5b731968e3212d976d3b20f44a60f6959c21bfb50466d3cedf33eeb7e01c7195c19049a530731a620f0aab642bc94db7e8f8e0de9ee07cf022ffd66c7d8dc740d9c1122cba9c83604420612b39353f9392a676ea687a00a6718dfa3cba9c5d8bc73c34c7d87a4438de26f502a828cc9a8a08d90ed34ebad1f9b630c66653af7649a4299b30c3401ec8730e55a98022b85e844a9166975198538b30d9c97014957f62b320f241cc0f132bdef1de0dc35f608687010c81d39329b11215b086ab0950411bf21334a5c118b2bc23f3b38c6d3d7a6e2db40bf70ec0ad685c2ffe1b24aee23068fd43fde7411c401e4c32db232122ec715d04143f5ae014bfd42f5807445467beddd409db997fbacbbde06d5acb3c6dd36e7dcc368befca44a4a34f7f0424017f76e946c8cebb95908c3964ff502e4df1b119b42ad0edffc0985cb547043485a14f1577f22737180d92b4d696046e1a989ee17080b0c0b69f9057ae8e64de30c5957eb01399c42d7858cc3dfd4b98e7bdfa181afb0ba8e822d78214abf647899f50b4edfa079c0f2d248190396887de5d74d980512b3641e51f9a9028644fd802ffa60d642b5aaaca3944e43146cca0659cbfa61ad6b3688e60cd25cf1a3dcbd76e4d4341affe448d08d5ba5618ebc02e89efe01204f42f8bd9b300ba709f2a2d1c93c8d6e5af8f3543dd53d59ed22e85cb02c1e3afa1869497f40d02077601ecb0178602a828fb940a52b34de0acc1abeafa9223bb17526974956321f34bb74517174bd160d108ff7c7c463500320bb256103a044911bd4982fd8a01634601770f5053093ec8a77ea3ff1a7802784d4e5749a12e79640b34e73c07cf6805ba436b708c59eee3f2da24fc5676301906003dc23f9cc564b880cd009a1b931cf8e31232da0f122f8d5e89dd30bcb5386f229637958d9b09f104e52ad5047a49ff563fa576187ac9618551f4543c759a072bacf8bcf9a94871d7dab462ca2047837383d99a9083daf7f7a02c4d1197cdb9d4e8f2e8c54befac8f20efdb70da1706f9f6c889edc94ffe18a8f9f8f705aa0f77045a414eb8948768f87148ad070a4f53261697f3700b6fe30632124491a8062cdfc38b0324db23383a5a2518c01d6532f9ae2f58f786baba8aadbedeac97ea42642475a9296ffd404ecf911ce957417cd31b64e638aea933df89bdad5e582735f1399ee33e7e93ba7aaf0baf89bc239a87ffbcc3ed0043248510dec34114ed5074027ef8d62cd604b819efa1a436ad9e714e45fb500f8742b8a37982e440dd35dda01e89780890e35cedb1a38df9d4dc088022d4714f3e6e787a2ee131e8bd9ceb31f7b9ee152df4782b3b23eb5cb6de3b4102310d919eb2cd685665d12ebd4b14ec71a58d6605dcab1d41ed056f69eee7d9b063dccef5b0c6acfdbe0bdc7c7fb407fdf0a424f8737a0f2a3abd15b9dbed3934adaa618f4ea77b7ea8bba645a4da79ee94035d9be212b63dd52596b01d056fa5bdf77f8c694f3a2ee9b9667b2491b8165adb3ecb05688753c835f9966be8463a5e9c9d618f077702f79d76ed05bf75e7e5fea7d3b037aeafb9ede56dec3fcb6dbdbe2bb5bf6b129352fd604a689996ea7e924d37198aca58956de18c93a031ffec1b036bfddd5fa9e69e6736c1ad8a3297d2fd692a9a6f46269a2f1d27efdfd4dfbb2f399d45d8e3878c6b684375924e1c9294fad609d38e48a3668cc6c4b90a0054d6cc173290b1a6ba8874b5fd9b7a9121a1474b5885ba1b4b0f33e4e4d2ca29d677039f81d7bd2080478e1c6be361e4478964bca389c364226d6c4f4209b6d1213a5ae79fa3466d72e838049ed3aba3008cd0d88ed16b416ef8d7260c455961737bbabe830cec50968535c4eec7a8a592517bf57179e17c1ca6fd317eb29e346a6786ca346b8e2f71c1eb1dea7647f63a254b4b283d37e072879a2ce4e3de17f5240fea7bd00a836796ca7cb05609b3513d41f526856f4eeb14a01739b76a07cc6ebf4629b3d41527238adbf0069e138edbb7af185daf0c5647bfa3ea7ee985705553726237bf3560694f5e53503f9745d1c1b90652934ab07eec69d23f1c59d268643f46b7088a68e89f1bd4721ac732060e2fc3950453d8839a10e8148451ec487fbf744b6d77f4fd0f74ed333917aa964bce2c4ec538a01014cf85caf35c9f35d2d77e332d73665e28e9ef8e7eb268717946083354e680ad166c9d7d79fd04dd8b89c40f9e54a69f16ed5f090933552e5eb95e3b820cc90a3833115ec3a6741f281e628d683969b5dc17a469acc897caa853f1cc42bca40560b7718169e5b974916bee4731f7c9950a4e97894445e709508d81eba29892df494749d2fb548088f9d21c7ab6520d7a229a3ec0ffe97a6b18da942a67c410d1e1898f7418a7ada91e2b84f3f9b84861377e25952e2bdba950e063decdfca2f8c6f6d02c367c1fe60ef688b96fd26d28775147d99c8e3c9ad3f370ffd39627f77fd78a3cc1b06c0b380cf57f95abf74832572edbbfe5ed8fee55feae64156031d7690f8d14b23918949f73987bec1574c1d4b79b89fa89d7f78fedd7e87efef3ff0b93d0a1cb4f0fe1e7eba9ee972bd1dd7e5a8af71f1fedea078203f1bea20c68ee6ae4628873dc8af84c9cd7428dbd5e1fe4bd61381f9ecf48cc18e558421f8cf1934bfc91dbbfc043c4f8da78c018f7cffd60c7be140e7b30beb63404c7a766df31d79c1d7555236dc7e9827fde4204b022f93e2efedbfbb74c7280c909b36b7cd4e31e7b29210257ebf11ab8ec66caccb8fba990ebaad73a500ae6199cd972a46302c63df8e5b3d376f6b515afbf9c3ffa3f88bfd3473d7e1299180bdd75a6cf07902f8e0d964b6c7707f06f2e09d1abce751a17f55007262e4f9c3fd17e7d0cf376a3b9560d22fd3820dfb27fdd4afdf33d3a797e6ffb116cb7437ead9611325a67be99395290a164efa02102de0998e09ed8114b6456974eef01d151c8ad3ead0f3bd61fcd7ef5ded98b21b8dc6b07c4d2fd81ce42dd2635322eb95c97731c3107a75c852f0be548cef94ca6aa7f805d5e26b1cfe9e06e969a98c8a7c103717b1f76c89cdc446ac3a3d555ff5144a90ac07beb3ffc0acf9ac40131db2a0fb22fbb226ea9fe9973f6efa1f1df962dd9ea9573e6854057e59db0c636e03647027ee459e5b4c473a44eb21802f0f99db5940f7b11e29c13719aaffb71d56a21c25bede3b3150300a1cb31b75dc74037dfed25b55860a0cf69164c3f81bb3adeed314fd0825cafca485959eeafd861fbaefb5b38d2349991fe1dfdd0d619e76cc891f8055af15a4e7592146b835ae5d55a18c6e1d70fe2d6c5fbec7fdc9f4916e3245de483d404bb31b93885cbc932fda6a7b147960f2db31186b03050216e28620d62342f055fd8318353b941c646020a539f956253d3f5e6618d63cbb1993e0bdd8843e0af625efec1a5518cd4fe46edc0fab087be59ebd1fc6898faaab336bcebf689c6c94ef517ae53ff9e0bb2250aa8e29e40297f74df489efec7fe53dbd5904df8e49820b20a52734cd7dabef659d84a49fa4edcc3e0c0e99da357230f49d8dc86d16ecf3650e2ceef80a6a328aed92057da19f142f3e802e202e85aa59e001c1df8f1b7e71a0faad41984feca967dcbe13fe75c85d9169d867df7fdc3710e39d46e33e5a2a9b5807bcbfafe9da654c7c07ddcd1b2e99d30e87bad3085c660f1679f139fd54a98f16b93f670cfe05a93165f4c33d04b1fd6b6165651226a8de8617e60195f34157f45e02fdc4916e219f3ed486d41d9c685483fcf94ad70e7d15697180e854263274013741999b002e5d3b1b1f38d2029a23b0d1246dcb3205560cdc35dc471ff4bbc91213a9a528d32b85795a7568ea32fb6541910b035f4c03b88dcfe2dbe8d003a90816da2ee94db1b29820a484f13157e37985431f532aeed8cb8132e964c2ad33fcc5af3b0f1d68343471271d6183176ce7e6a074287a7dc8e0a64fd3e4d2935405a883463e535e190280197ff5f01935b34db10c0c423658d85fc97e2a1041d864ca1dbf3e638ffae70873ad72e1e1a48219d93cf4c172927583fb02756c56154b1710110b85cd95be2a030a27285c4b066cb6fb6496dca6955d147e840508872ae3a9d0f467d074270e3b4f12f505e05d77c0ad1104e06e57343c139c15856142fcf9fe31d438ae0d181e58ecd2413a504f43901faefc561175fc3f6e5aa159e5b8a75da720a08166730f102c23853c63084d25824385088cd087af4195333ae481bb8089091a4f54e3b0a1bba8f2026cd0048a6ac42e8a02c20b1f3a70d072ba3242bd4bcf545e960dd80e84615ab746f6fd0c9a0061326f5159ae70fc3fff59a1611611aeee26cc923b9f3b9f31d6f640178f7754207bd80755c9b12d2cfdb503d7d5e9dd20c41db98ba449010220f8fafba768b356b9e3a30ee948dad3dd867828d807e3b4d6ad8707c399027ac9857870dba5c32f12606c326051c3f8e0d30f9480f184ffc0d25027064c114ba86299b42476bc72d369d49a4f93fdb901382708d28e3375490ef53acc041abfff20ea1083e3d43bd5a0966dee3c2c6eb9256bc4d89fe8c532b6a5ca1bf18d8265b4607b470b28678957aae30f69ac3ae46fd7316933d97cba25731eb47da94990a09196e0d42ba2f2cebed25bab112c6a5100f194b08a72c0e8a87980c879f940d32cd2a2256d6b96346de218c4059a0fbda8820c2fe7366060d4d7283db8828bff68428265ff2ee1e0094a65b70badf9f448bd53ee401232932e1c0d180800eac96b4f6bcc955ee15188e421f16ae34d1c90776ffb183a8657965ab0a9374547f08bc8e2ac17f353878b8f7598fe2e415ec66c1c18751f90e43db2409c0ded7b5c7b2fe9ba988e37d53d50a4b97a2c847f203a94226f2be0086a512d5d0ce246c14adbe60ff03f9905778a671bd0dd81db51450d88078a833fdb9a22e7eccb86c2d4e8dbbfe693a251b9713ca4cdbf8b959b7380c6187c20a4ae9c63fde6de94554632b1a8958c1e45e04bcb19e0c2592e5a5a2356dcc8705ee15a1d8b97013020ad595b5014f8848bffa1b739d28d58c096c33fdcf916b199dcc00df54e1eb5efa735f8e143b7956956d683e4319a893eeb914a260a63ab2edc0aa0e7e37f5440c65a45443407dfb96b1fa388b26537b7050cdf90f3553055ac6931117c9b8cbca192a6035025d371eede5fc67fcfbb71c8376e331e69bee0291643cdb1cb3433650c24de9b3c193de0d433d121dea10fa7f682cb2127ab8fd430a52a1633075c7c71072a65183e15d1d042cd110b923303d00a7ea1ef48ea57f074299767044dfeb46876e6e4dd5cd8be05fca800f5ba50845fb1ad8bb81eb8f56717457d851571cb483cf27c5ea398324163dff6e1385d4a4664b5c57a2f7f0b7abd3a8a1d0d6371f2f9e9c46fcc70f3b3702780be05d6bc88d1a482e5b63ffb19541dd0bf7572d41f3eaaa1a560cb0732f01b95644cebeaef781bb09ee06771ca85cfdcbef46167b6fb9a744c4ecda594de7edc75849b4f4ece28182a8ebfe7d1b8eb1f0cbffd63db914b243bb73c2167bcc02d138f455d33b90b3ff82de10dd00138b596dd250c749277888d5f1d4ca1cd6ff7e6f4663268f2bc8220627a427bac71f4f8b58ffa758fafd40eca4f922c16e2ab5bfc68c9431fe529df1f13cc320721d143997e2a3238fcbce841a96ccd8516221700c6bd6c08899f7c1146d4455cfe9b106a50a1beeb5bd58c65c0ccd4849021c84edc1ca45aac687efbb06c921e2cd80c52528b900a1b3848c26dbaec77884848918833daae18f42030d8437dd69dbd7f4f8cc750bacb3135a849130730b281b4d469adf6539508dea9489b0b624c056243f8e8ebe524fb20331bf4c9429804311757c1c3cb1358012ef0e3fca71826039adc89502c125c045d1efbddcff0e1aeb70d58dcb5d36bff483d2ed251789c9148956fac22fd259db1a37f782a21c8e1d3948f538dcb088c6242156d28872592b4b8ed11dee2dde2d91a03ac0570c4ffa2d327d49c25fa87c739d2dc7dda74576337730ce89d7aa48deee2f4048160edf1d3c5f308b5618a0c459a18d7f67c2c6797e5c4c2ab97d432c02a31ee68eb3fa94acd9e3046cf1b35ad3e65aba0260f976a2a99dceb8a7c529e3769b8d800b01b81b0cfa87f26f7df0ca1ffb08c8b0b04284d6fa9ed198091b38799987e85ac842bb4bc8709cba1a56c8eec8086c0fe74880375e6e0f48c52bd2794ad59cc5caf6304e75831c703211f6796e27a53442d835d0c1094ca23c44115362bde67bfeda11dab1b78f06192a89ea1446fbb899267978377c0794833bca7940fb97f2bb0de04ebdf7b57cf099237de80337029a378ea8f53ea498069f05d49b4ae40f2b70ac61eeba7bc28c705718382c281b4d924cf5a49077222f77d2ff79c2ac0c2eaa2df999b718300c98101ea4924f131c21d33f0f8cb2702008de10a3496908973bb380d7c90eeb63f05ea5594145f64a980c0ef270c2ed768f9385c84a3b2b340788cb6f75025f71f8b0d6a9b07386db9f3535b2238a66a72f63c46a53a045ca21190206ddf287b9c9f32c799f0203f58cc5f19f3fc1ce6ebdc246adcdd7118f32d259bc49541f7acfe98487766cc3d4f514e8fd324c3581ef465be5931a1a84811a629fbe2d7d99b4709e533070f8537245f5ec2c9de5088fa954bfbc0966adee293cdc9b803266d2a9a66d162896ca87b49b08c7a2eaae3d03cd49590a84ca88d83d3fca776176d9804b461b2c8b692f052a005edb28abec63a998b7fe9b86b82a9676789844a511fac8cc5948aba2ae8345bd6ba0aa781b3b4cc306be21eaae36b5c0e0055f115a927480122af82bd2888875a2762e2b61430808afa4e29a1cb9e805cb50e859048f4bd90f3e1242618cc063b3df026ae4b195710d79926f3cc928e475c505676fa760364fc155652b0ef9b8f541594156a3cc696e1accc9c161ed06d414aeb1e0d85797179adf37445375a6892f7ba09410ddb1d8f215eddee0ca2e4e60b2b7b09780ddd0b2c48879f54fecd502f088faec78f2fa03498f89e1cd6097dd8783d90f0ad245a0633f2fbb7112fb7ab600327dcec6a39c039069bb6606d9912bef2eb1782c48243f889281bd1ba13b7cddf8eb5cfae12b4917329677a96b3d640ed13413e2d85649fcbf20a706b3ead7dd36405c4b253b0f39b5ea886e379fa6b224077c3a4c86036faa2fddca44d9f78c6d021fab8e901115cf4460417adfc530d0ae67d31616a518c784b0b539a5560723f279dbfa85421d63285075fbfe28dbafd902335c2b3360f7e3404b644cfe98876fa42faa987a156fb697e893762207afe57addcd31237cab4a0feec6e91a250a859e96c38101e59413945e47fb4f0e861d03ba9bbef99e5f982305f188fc49c73275a40fdebd545105f16021a060e579c09402bbc0b98c99ee231d9b244958230d1c2a696446ad2c1423c023a802355574ecdab29bd01e6b825fac60d9d782cd8acb147067dcc2280d360be0b838e65de45e5ae603c0683f55f8666c74ba86190f571541f1f2de0ff1bbdd7afed6de431b34f70e73595042e0bc4c9dd2cf654e006e53d91c4f84b327ca85bfef8bbe87af6c9f75982ad81dacd8449766469139467d8a0ff21daf0a3bc8aed610e7c5b81f0d9d6379f66059fcf7bd995fcead7b722508ba5a48553f04f78f17b214e81c40c16ebcd96e2085c8028ff48a873f127f52b9e036526338f465978b7b2190d861ed631b5597e7e35e038c1b1dcb35d6545dc5c3b5b36babe2ad3e481852304f95c62320a889a326d052377c5e0668da696b8ee11f75344d554524bd3a772c4afd57b78c59315f7f3b2644498eed9634b845385274d7c1b8a3c974f1fe6ba1e56c79c2237d810a2021d13c58c6ccc0b210835a19cd5306d2394fcb1f800c0790be4e5580454abaa698107c0b43989a9b54ded15473e595dd17fd0fbdcc44214e6972c47c86235805c091a60cafbe010f267056cab90e25c0394151a633424f90715d2789c8604e9b97e2b4cc5b2c34497119000f4b8d500cb4e74e9c2ba49e26125db8af50ece0670d5f77f178aa1e25d249bca6dcbe7f1bb875d93dd696ba1f1ed86f453a4b99ac4d11738db32aeb03ec9065dc7ad285a9ceeb4c347ca78f7b825ffed78e70ceaa885ed618a6b3eaea6e398011b3ea7abf54132f292581f4f953413065f0b719bdf3e4d398db51213333a0d7a5cf0e2cbb19258a08e307e0857a20371126d45c609e1c24032c146d61eb8f1951f07025049766c37975f702633179c962c7b6463ae2bc8f14fe7b86e8c10d7c029d0a7e97b88e8c1b9a3c93dae2ec4b416b032c56735fbe5e6e4b6a6a3c37cd633267b7208924a65679e1d2eba7519386b14b2650a8d7efda4ff92411b7c26b869805be9cdd344e5c4d901a652c8da39d2f160f4b9e7e5a33e16a439d36d9a7018e400c48a6bcdbc0d91098ec9c5fc1ebc87279a07fb298fd8ec1d1cb5f7c1f6be1187896fb4808b2da6d8266d5f011d2537605969fea54f322ad407855d9f00efbf0795891ff305487573083c6bd7cc743f73496e92806d608ada1bcd3a70e943c9f0bece9cce3914e91c8e24a9a7391f08c6de198f5de42cd0e2f37fee455bdfeb784462121eccc192b971ac5fca7a170cf2274d5b37c58308ae54fb9807cb973711291848f41840d595e915a585bb5a125171943eaaaa8e2bb4c51b66e03a92b8ebda6043f301d081ff1c709f2cfb7274af7a7d5784cb98e4632ad771ab696bf980798fbf0c1df8d7b8a37022e24772f550f6ae4f1e1020307c90964ee607132bab80e73c3acaf1654c8f110f30776ce2a87ae18c999d814a5e94b9507892d77be258b18a4529c9eb1c6f563a5d53cecd1354f62841b5c6012445e3c40452da2d05fa6fb94d269b02a4e7ddad6494d3984f68bc13c2c802ba238ac54369aae5737b10264ae862049888c8eb76d4d8c1ab80bc3e54e9b0a37da856e8d36311b1ba067eae87ffb3d4e4789dc3d27399798786390379f2bfe14e38fa0c6963dc4509f9420b8a99aefbc2337ba1f715e99b5816fe912d5e6ff13d9567e10085630619ae62b3b548be62c65ea097fd33a1b7bf14b8949c7116209af9e4cca3ab4abd11054ac83ad805fe507858824ea887d59de10242806f4bf3b9e724989fb75401152e99fb50f91001b89ca87af60b0d9ac088acf5270f7be6ca086a0ba4e98de156a8fb2878662a9a40a08ac851b829b0930f848c563a77d5e7ab0ef58aa2abc3d014977a8a2a7a5991c083619032ac8e41358d1ab3a03dc8f3c2b2a575ba4cafcc632cf7eb54f93483234f261370a2ee67a38493c55e7d241ef1571a558307e0659ff42a59f21254484dc3a547c2c5d8f43225080900a1563bdccbdf99c099cbf928622f0f7893bb245674a2c9978d51df792c9c56034ba5fa6d7ccf9cf5ba64ebeb767e2ae84a0ca144b64415b775534d6bc510b1af46b835c0bcd7adc3a7714f28befd5f53ff5938f4e87ebee91300dda1247d1bfd56abea1d79d273ce7d3ea3e9bcf89db5d4c6b8439eb20c1b30db43521a806295b838fdebe20443dbbc9dd9e25dd49f9342f6d34403f187e17b171bd3637b562369c5426c637e0c33c0a814c574d1c071a1b0429b26070ccf6832d059b2cbf46b62907e76dc70243b8ed63bc8fe753c6b4e7e5bfcafe3e00f331aba3301f362fb43f7cd5ff29bc8cf11feff9c75b28284f6fe7143270865fe5f441f39f390c1056790e23f8b40bf7dba5151fdefe4fdfb5d2900795e2a0005ba9a0bb46d2010e4f81f377971baf82b16d931bad40b8a3ad99905298b950e7c3802ded444020c3870b0a490033ccff33ccff33ccff33ccff3075c587fea72d19656ca4a6261faf593fd0e704b9232379548b236c08d8b098d8b09d3972d3310e30ce50b840b56c4ced9905383563acaa916d2d5d0a271581c66d060fb18c222554796979ec1d61973d2995cd6399a1932d822dd6ad2499bb8a88a0e64c462958f9f3aec6853579e58da05444023c61664c062f399b8d2c97453da101a0564bc624f29fee772e6ca18cba20310c8c2b0172a3086012d7807e3046f829ae10519aed8a252ac47913926ed5ab1e59834ed141e48ca415dc860c5a6beb3e33717cac25bc59afe34ddec6aaa5842ef635c1fddf8c871b50019a9d83b880bb5eb95c3778ea062f5b0aa73d8d1539c0f3cc56ae1736d48b5b9d731c5b6295ae5f20f779dfd165f6cb1829245072000c6165f6cf101e7e2b778000d1a1b1bbeb1f10ed8d878a7b1b1610819a558825c4a8cd30f632c470d2d522c1d8731cfe7d15648750d2d16b017641890318ad5fa3376a0392a4dec6a681d550d90218af572f8612e7f55b4bc3860160119a1d8e77cc3c7fff15d0eec810c506c1a340766ddd93b1de78e20e3139b877239ec0e3c323e875d408627b6ff4c2fabf8943cfc111009d08040b9800868bc404627f60fd73ceb2e539c4ebda011060dcba20310c86263a3647062cb54113f67b8c9692b8746090c7ba145072ab0b1f105cad8c4963b8813b3bb336c87161b5b9c1374918516591c2ac8a20315c862636363238b0c54208b136cc160b4a0039607199ad826061529cdf8b8ef4a02bf822dc0e011fc05c2d8d808c36c6c6c6cfc3fa006185b80800b7e07c8a0848c4cec398cb739b00f726efa606249b1efca3a695ef9ff127bffccac7d771cfff896d893cf48494695b0e257628bf1551b3d547e98734aacfb41e4c98971bd2766124bc69c94743a3696c448624b1e3e4f4ce1482c132deb3cc5e4ea0e48ec31c67cdcb5cd51acfd885592a69dad3849634871c46a39a4f50ed629a6b111ab64c79a8c29adc384116b684e6329be26b53a16b1c5bb4b177efea2ea8ad8729a8b148de1819c9a88f567ede3b9e8351511b179ce0b2b89793f4477886d26a6d0933d7fdb1b62d1adf00e62ed37e2855833cf6808d1443fbe106289257a9b42981f0d0e62d1f538c5949b26324404b106e9493a395ed1e20ac41a26ce6388213dc60f886d7388a293497ef2fc873df4735314c937e6e1873dfc3cb9f24a67e58d687c816554e005181c78176cc1011064d1810a64b1b1d1872dbb82a4cc95d24e493eac31f6e7559884b48fdec36a162da64c5ac7987232f4a0cc7cf01bc3e6a8d4d0fa15600a64e461d3b9f9fceb49f9f18987c55388790821bce3e8bbc31e241f0b511e759c18a37132906187358d47294347fe61975d87bdeeee629a909993a7055d346063c3bf055df4a174d8b253cccd2be1c33c129c818c39ece97e35ba3444c9a1c140861cb6ab0f45244db01c3690118745fe329a8547d9a8b6d640061c961c743effa41c94aaf9863d08b9a2a5679711ae7203196ed87238993e081d52c89503e39ca00dfb7994995c1f7d2da66c58d24847313aedec43cb1a968f1c49deeaa4bb7cf902055b80a1862de4fc89b61ea605ef48c3be3165c6e039871e3c1e0d4bfe699ac44c23e7316758546726a495efebf530039e347354ea2857863d4f9218e3c5b0b12c3d821590618fe387e5e139df6ce4bc18c37e579f1a21255a7aa018565f8b5211a29fd6c961582f72d00df6f3bb7277e12af8020cab6e3ebf9598a751f117d6d03c3a967298463cc70b5be690537f8ee8e5bbbab05ede49eff5ee6e76850632b8b0f455460b1b4efa73740b7b4871c9f46ae352b0c338ff5ad82246ce27e7418e7c35a4c4404616568db531b2835029c3ca16c8c0c2329d33c7d7b1f6fc235758c26cc3bae320d6b735b78121c30aebee87e1e5f9562c5678b0404615d60e21764c1fe6cca6ed50810c2a1c233bb1b73d5df11a5a5c70c134364827644c21e9745379a2e54b6a17beb1b1b111460bba3834dc7963630bf6a203462406276448e10b676736fda1ae840bb3b161822ebc381b1b59740002599062424614d60b1f4374e690c1d36c0228283b5615217ed033a9a125e309fbe82611bd8fd34a432bc829c870c29a325d57f254edac14636fc21e6573a8172f752816a1146430610d3a1e77f81f732ed6d2c2ec093296b058844fbaa92745532802194ad8c30a317dc40fc334fa357463638306958c24d89924a50eb1f279f548d83fbe9fd4a92f889a59740002596c6c6c41c6110e46eac2c5bc5539cc6184b6abafeeeee33cdf15e1bda86adff93745d9889087333977f0aab27055411626d8a2c6171b2bc8a2550559d07d216308a4da0df669d3724605260043051638c10350033284701ca8584831b554adb3ba932753bfce1395ce1a5a5c70c1e64ef0009b808c202ce9d294de6e0731853c10f69c93372366a694d1b1f1beb1f1eec57f21e3077b0c977e2bd557529e6b6821f960d54f134bc503bf18ad8a5c4004343820a3074ba58ac182478d925385077b58f16c4643da4b13c204193b582ebb2f876afd397e580d2d521090a1832d43757c3ae239444dd6d0ca0b888046183272b0e56439ea09a21f73fc0bab07c8c0c1fe3b9d1aec428741c237d823ec5ece1dc38e66e7c573c1056ba14a906183ad3ec8fe3c9a832439c401b9326ab065aa84ebdb7c1b7fd7502e588b77008d2a499041833d265907296f53433d70020c58f9095440e3045d902a249031032b570e42ae8a1891a48360f9692c6ce423e65040e3c80b8880060364c860f31075757d1fd86a9f822fee01c68018b138ac1c248dec2caff048b3eb9c7350c173a75815164b57cc5af43ca3513f5d80915d74a05eb16a88b17b27452a48b086969ba00b2f1ee08a354e730e2d0791f2a64c0d2d0e386063638386d9020c146cc10517cf808d8d3fc116e770a927c468c51e86cd3d493c77473ad5d0a3b8680e838bb3b191682560c59612a1fbbd371f42aca1951e88b18a45ffc3f0691b62be531b88a18a3d9e4b394cbe1177d28517ef82a352b1c79186aed4b1f1fc5db04509410c542c9dd6b76ed5427fbc7601c6718afdc3a3cdfd2879ee34d6d032adb41650d1a8a24ab4129c29964a92623cfcfc99289762d1bda06a218deec71c2996f39dbc52efb0a0eb28d60b531be7e436dc8488628f32e27394a2058b7d8762cb31e53049af65c8bc417156881c49c741c79b3af418f61b29b9f9c46ab5a91afd2964520b7a62d3f548c26f4fec40939d582c25f64f5dd08f751321062796906ead3b3e8f241f2d85189b5824c761b14364948a1ea81710018d1a3134b1544a7a381dc7840f63070d000021462696f45b1defcf47569dd66840314c6c962e878dfd610ea22235b48e2facd22ea107212c47392af1e8ce8e6a325afaf3146e6c6c6c145c410c4baca615fc2a52ffe62c2bb187319de7c7a51f771029b1a7b9bfa4162d247e0e1ec498c4922b985a9ce8c172a60da551561710018d3062486229998e1d43ac143cd348ec39d88455f46831a71b1b55880189fd62288bb241a36e66591eb1aa64c855bfb52356ef0e1e4a0e723ac4d888357cc794fc2359cba9691423d6ab8c5979922745fb8d8d0d2a1a65bed8c2049764115b94475c88f49145cf5e7c185c012e58063114b1fa6d34fd7072aea5aa86168dac00031a80810a4020c168c16725620b99a7b21e6ed548bc86d6550b96011c708016bbb1c15fb8f98d0d17c440c4767b9bc92c2f77cb43ac1a62e78831deca67fc5e5c161d80c0c68621ee3c39132baba135822d9a86f37b410a0c15a0a0aa0aa17875d09837ad3f9415831044951c551d88e4c82c7a14c263adcce3e820c7488c41ac99d3c4a01bcb0b34512418c410c41ebe31678e4e739080f123b8f213a8e0d040942a3e4634a7fcf2be8801082dc494d2ca91152b695785e41347c38cc9fd35b45af035ec8b07238c2e61b0175e70fd61ef288efc85af1c56de7ed84a4746720e2965e74e1fd6b9cc91e4ea1021cce3c31225767668a3ab9da93d1c5d9125292a45cb410aa1fcf39d54fc20d54a8a1ef65cb3131f86c89996cec31e54768ca91dada11da840165f68a10362e0618f2fa28d65a87cd2cb917758b6b352559e4a1f9a6e650931ecb0acfdde6d0e1f848ef038428c3aecf721379643ff4d95e30be6428b82841874d84b3bbcb41e6a6e435843ab8b73822fc2e00c6c6c6c6c1c34ea207358632c7d5ef950dee921073c4a3da295657a45a98c58525a6779db9faea165fe0be20518288811873daa491d57b5738e3bb086160db41870583c4c7a986737e3e7680d2d2a30bce8e28b8bf186bd438e1091524373d80a8d32420c37ac97bda59b133bc6dcd5d0ca54408c362c1e635fb0cb88981ca5810236815618c71181186cd8d4364f4e480d793de58b0c030ca3428c356c71b1f1ae329d7c34d16263030cc32830c1f920861ad6a861a3a5aa94922497863d90de0ab7112a31a4c08881863554a74b791d3d6a2f67d843911a0d91dba81ccdb0a79841756312f5545e19f678744e33c4aa910e42863df376a8e8b9eaa873d1c57940165a6421812f780c7b4a9d434c9d2247b58c2117628861353959f5a8316c0c3e6218f678525ecc0de9347c02c3ba75923997979fc38e1a5aef822dbe40c42f6c71b3d2e5791c63b2e07d218617b64bcd93fbaf2b67d2028695e90c61f3f08f267d18afe385b0044f661a7228b709c2e21fa92b6e5cff68202c29c35fb288f0887fb08c7d5f7520399264f1c13265c973e0717cc47bb06deace93543a9de4c11eeee7ad8869d4c21dac3174759c988b613b74b0a4df92281256a6cfc176e93ec9d8eee7701cac71eb2f0409fd39f8067b1c93fe858f3c73da604b5bf3a9c21aacb6e9514a3115000df628720e7c6f7208970a60066bd88f9dc388172da40290c196f9b17969e1ab93b1d8f2d3afe7982c633a61b166771c04b50c4d39f215fb9ec54eda615c1bd3156b12cd290796d3e7a615db7787f319c1f35756ac9e3b48295ad4b2e82af6bc23779f93a61e5115fb8a781cd45a0ebac354aca6739773a6e41c43542c39e64f657d7a39c353ec13bad3fd7c7469a129d6e8514c0ffebbbac2522cf1a173a5c7f1510849b156dabf1c85b417241cc51edf6c74a6f8a9ce89624dc127573507f1ff0bc5e6f11dc7fe0f149b864c12f77996d6fbc49224e23f87fe94c3f3c47e59e9243e3783759d58826ff82ed5b5fa0927160f3c0eb39064c3866c62fbef980a5172770ea289d5642c8ae50f373b928952d02bb1df60620fb72fe494e33877d82eb154f2f111eb78955296d837fb637c107ea95389d5ba46d5d4a3f8a1c47ab73992ef3887cd24d6f2384e3fb1267348624b1de79062cab0dd4762dd90b41b2964ea0c24f689ac4ba3361b1f8fd8a34712d38f52482951001cb146cf0e3b82f9464a148046acf3f9242ac69d98ef67c4aa632145a74c2197862c62d18849836c5dfe146314b1e59ca49f0cb9fa2025117b7fa89cc7bc937c1e446cf7933bfb47f363ed432c1deae41c079e31784a1962ff3c9e16c298ce8e54883d267f1caf14422c95d6235fbdcca12783d8b6243387c7313d4c58106b8e3e9830ba59f7310bc41222e5f906cd3929c98058c29fa69c7f1c570aed0feb454dd5132e7368a97e5825d46e57cc385df3f76159932aafdd54f93df1614b79222e04154949f43d2c55a5b221412452ece861fb520fceef574e7f938735ada7762eb9f1b0d6a7f987e97f7373f20e7bcc39b20efff0a3492176d8ca2a468e87be77dda9c3561f837c10f23fed25e9b058c81d733bf2f0c363e6b06974d821766a318f2487255d944ed3b0cf31b6382c2299ca3ff23b6c32e1b08777fb31c37cbc61915d0f62ea3b86a4d20d5b4eeb133fb95307a9a30d4b8ad6c5c5fc1b7c736c58252c75a5a762d84cad6189d6d921e538898b9f1a16cb91e7fe4df30cb2a661159f9c831c674a2311a361cd599f8ea3becfb0c75ee7e7e667a7d29861cf316c63ff9e4d879561bd90381f7f98e283f29061a9081e794a4ea5fa286358a4ffbfe42215c352a31d276de608c3f63d9f1baa9bd14702c39e32de878dc9a915d22facc93e3aca8e83a8c1e3bcb0dd7da648b25c17961ccb77eee31cbd3d17d698ce8359ec8e5fdcb6b069cc787134a2d33c5ad8d4d46b2b86f2783e3a0b4b46b98f83d03b3db982852d474989f4b9720899414300ae60dc54eb51b2aa12026085553a05ef1c8b1d449aaab0a5598f367e34bb39c454d82ef573500b95c3cd0784004c6151b59c9b3c7d1cc4cf48c189cba147ca618836210051583ce53b86c71bc2a50785253b25dbdc53f2ff619eb0cf78549fc71b75b9e384bdbf6cd2ed87b595af262c97f9f2e59c93c6eb98b04d54909b14e92062be84bd2ac5e50e7732392a95b0669e6a8ee7f4e1264d12f69d88b9ef74425cf848d8e3099f2571f39dc3e6087bd9a5f114997a734a23ec71949cae8ec395c65884cd2c8c7da55413538e26c2661b2e5c49490e34e686b06c8a521f664c9d839c14c21a1ef93b1ff2e5b07410b60c7142a75348588480b06ca9849ab999d5cdfc60390f3aba98dc49c4441f6c61de517fc78f7c3cd7834da272c5f138e5cf31e4c1be29436e5fa5b3b17f074b8c1d2366e4fdb023d3c19223a9e80d71277874e46049d539b4b59895907e1cecfdd174a6e6e5af8cde60e968a9a2d49c767e6c833d074142d53b844c07d660eb8d213e543d35d446832554e794425f77b28bce60c9792175e21f0190c11e5fdc4ce48df10e73b158ee638e3e2763729c2b58ac96d3df56e649e3e17cc51ea7b9cd88f0e3f7f1aed8230f3db7ab726d6fa4159b2435d5be3809b989154bde64951f7c0e9f0f5fc55a29d5677e17edd656c5a6a1bc43cbfcee0a3952b1d44cb48f7296ec4311154b07a633bef3e7d1c729f6fda0246fba52fe20648a3df20dbd1e56588a2dc949469893ba498f148b68cc0e246974146bd45893e2c5d417e3248a25735e9a0e673da8868462ede90cab1ee60b9364502c72e94a3d4ebebd097e62fd49fea1527addb979620df2f1e94a6f98b03ab1450b29e6e7e4380ae939b157f66d273b6b135b4ff9df77af580ca526b6af1fcd191a3ab4af33b16788fcdd292626ab1a13aba97afef0d15ab4b12eb17d4a1371721c079553da128b9aa718c3eb3cb01c5389f5e2a7345568b218274a6c1d876847b2f3782a3389cd2a85df941efb8841492c731eaefc26ab53e448ec39c98fa8e54025d20989c573ac7ca8afc450cb2356c9197e526a7eb236472c9597ebbb237c8ec33462fb703bf7677964ec8f115bcc1cec2fc7d192982e62f11c7afccb941793472a62a9a861e3f1a40993f2895872437d1463bc781b3d22963a9d504da1394bff43acd9e7a1247edc6986583d4f4424d98764632136d5903f9f47c7de3c1162ef1f4fcbd1a9f1e90c62cd1f4e752ac908628dc9d383c58a54f85c20f62872e49dab26445c0c10cb4857fad9e690dba13fece147fbe3dd13e227e2873dcd46c49866ba36d48725d527ed5e58c424930ffb65d9871f9dc4f00dd9c376d96beba1a7111fd5c39a313d48162a23a725f3b08e752069dd49367e1c1ef64b391e46eadc68b9b9c3ba21122cacc3f19b143b2c15f346aaf83854f3e03aaca9a3341e52c4de34193aacf1fe4b93d4e7ef84cc619108b3f97cd2a38da11c56af48392325a5f612873d4c2622e67df64807873de8c50cd5986b2cec6f58cfc2c7c1f64277f0516e58432369f765a8885cdbb049fec872fa34dfd93936ac9f74d367373ceac6d7b045bd281933a4cd9185d5b0f8a6cefd0f213a888e346c796c47a4e36934a9a061498dff53e93ba958ce1936af1c77309e97b19d31c3ba127f2474bc53a9d4322c36b349c3ecf683ff9061eb1026a4f2645ac7e9312ce2b77142cf87313f8718b62415e14aefc62458615834356a74fc2972ce6160d8c394f9e3243950e9f8ce30e30bab5ceed168b515e3491e31c30b5b4869c45276f9a41052438bcce8c2f2613cac558da9a310ac7284195cd8b3fb226f6c6fafaa5284195b583aefa651ef9589dea185254dbcdcbd55bb9b2b539891853d860c7e151eb3ffe2ee30030b8befe855848aa77943801e665c613995b9f014bb397ab5b111012f4c60012f4c60024d44001f665861cdc1e4b02277cdfca6c907b6400103c238ff0dd0dbc18c2a2c1a3991a477f2d98735b4c83631830a6bafe7382254b2cd8cd5d02a59740002f5817302ac0b888006021e31630afb66cafefc6a58f5540dadaf0ac40c29ac3f1faee72f327fed35bee008245a0436366864a1851624017998118555735a9c1837e68c8d6a68e135620614f6f4407673709a7391d750621fd86836686d98f184cdc2e23cb47c2185e85143ab363650b0450938b0b1f1068c8d8d8d8d2fb4d0c2020cf0c0c68616591889c0c6c6c686d9223fe0c57361de378e1c000f339cb059fe18bd22f423a44d58a22358c71def050aec5f3083096b66ec9ccddeb50e15a08006b12fd2011b1b3396b06e8ee8bfd135ff20d6d8d8f8a2045d745143095bf8997016df396b2649d8d2964549d35b412b380309cb74f07c21694e52cb1c61a90ec346288f29acc5cc30c251a3ab83ecf310da8246958a604611968b396276909261340db313786063030a3388b0e5d0315a4127c6a358438f0b8880060b660c61b398eb420ea53aea8eaca1f51020216c5d5f362173ce133fbc86d6175bd0914009ccd7d0a2cc08c29a9283c97e858578110d307e045a603c04c80e660061cff1f27d248f901fecf185ac8a10692a871ee683d524464e2b1dd68c658830a307cb5d0c1bfd634c5f0f2a4bcce00175729f3a27cda87ff63063075b490e3cdd84ba1cb15d1161860e16092a9636efdc848f975d40043400408a193958d4334af3c6910ee7a9a1e559831938d8a6a3fae64826fcc18c1b1c6f871df653157b833620464b03dda68cfb8fb9382c12caa206ed0e0e7b478f32f947999247ee0d8bcdc6786e8585ddce0dcb95da54d04afdd9ae0dabe6302aab434955ecd8b098e5e0ff47a2450fbb352c33b9dd613ef04fedd4b0a64f4ab8bc1032679786353d08b14cc3e5f2ecd0b07d14d62443f64713bb33ec97e3a0bb3633c392cf235f4e41727c591956afd53ecb2d4d19322ce6f15ec79de183f418d6ea947294d5a53ec5b05a8a39e9e6e4dfb2c2b09ad68794ec73c6abc0b085bf532df9c0e72fac93a3945f211d73bc17d6f0793b67ffbafb2e6c1e76e3e7ef8db173610f25c9c432d7847b0bfb570eb51d77aa50d1c2f697fc43a7c741aa59d8a3eda4fd9ce2da840e0b5b4c0f97bfd7a517dd1596af8e76f1c236fd5658e62e5d87b5354f5761f5a94c915342f50715968eaca3d1907f933a85b55349ca1f953e0e8f14d62f338b517312ab4e14d620dae7398c17260c8555534c213787f661e59fb0c7b92274a4aea8f59db07f908ed01b8b96d384d5b6e3c7714eca719e095b081fa7e8355d3b2f61096b9219fb323b0e256c9ffbe3a5eae01f24097b8f460f6963d2b11c09ab877798c478e12a3fc26232992ae41823ec7f7e9f6639ae7f53843507df398ee34458ac8265f8f8687533843d27ed8e2ec7716e5a087bb41b16d2433d7c0461d5206129437e3f0a84ad27536f3d7c8ae40fd6aad01b31a58eff323e585742926c5a47720f168f72e630ce65978707ab6df7e6f938a51cdfc16a9a34a67c932a611d2c215c4839a8e6fc73b0f6c4a8c9837849638d8335c385d30cf61b927c83354589d1cf2f04b0c1127d223cc7217d90a310a006cba490794aa4b3430b0168b0e78ec23f3cfefc91850033d834e6aea7fa386ecc410019ecf1368c6ec8b4913e62b1873bc93b460e028b3d7f32a7d09dcabe83bc6289f7f1420e2c44d30ee28ab53e14bf1b8ffbac83b462bfc9e9f092a5a5d04158b189e58f9127e694e34a56b1c88c7da818913f2a51c5de71d11f529ad0a19254ac7a17e3f31da77a4a50b198744e9bb3935aa7e4146b0e2ee688e668439ac4144b3ad10f0ff551872429c5362379711f39f02b0929b694b2a899534e7a908c621df99dbc1a14c5a65231cde49cf4c3188a4de2dffde4951cc2088a3d1af18a324f1961fcc4a61b3c3f3f90a8287a629f88fa484b6353899dd8e73aa4ed5bdfd98e137b858c10f3e3a70add269618d7e30e3a23530cd1c43623239f7f24664c32b14cc7143b168289bd3e0ea34793f225935c62fdf0e73fc456a49158628d5329573d4f5d8e5462eb1465bc430eb6124289ede3a75ead1dbba04d623549fb51072a539f4962ed8d39f88f57619d91482c157435d47774d11981c496f3ecafcb23a5ccc823d6dceedbd11cd75e461cb1672acb71f76ac466391976db3976ba18b1ae44f24d1e9be1ab45ac9a3e548f924711b252c46aa696e4d7bea39c482296f38d91dc4e712a11442c974262c474967284c821d6c9519b7cf4a24788186295d8d388186127e714628d9c7e4425553ef01062c994ca936a594ae30f620d15f32207e1f3572f88f53bcc0eb7fa40ec914e88481625daf480d8bf3ef438856f8afc1ff60feb224dd547ddfdb09c68fc66de87e53a73673f24df990fdbfced86aefc1e0fdfc3fa61c69ccb81649dae87257cf8d860e151669e873d86d84e31f17150391e168b0ee288e70e7ba55029aee279e8d8611b139bf4e373fdd761cfcd5157aae6a398a6c3ba49e285547b0e9bdf6d4f48795cafe5b08719ead2030f265e1d87d5c7831cd742a6c8311c960bb99be384dfb0999587a9e3559ddc0d7bf09c3b917383c7b461ab389b83f88d982a6c583b442b9856d527d7b007517294e2238b0d15352c313a8ae6283f075149c3e261c79919ffbc3968583c3f728787a4d51f67586acdc3858e10627898612d9bb87511f204bb0cabacef677ae83f16322cf1a26e6fe8c7393986253b8225c91c394b312c2107b5d06318b68a3e65d126550c5130ac2144877744bfb0c7e5554127a4b0dd0b6b4a37d21d26ad0bae450e2e6c97967182e50ea7dbc27a9edd9147e620b3d4c25ad513737252674c16d69090d2363e8a5e62610b751f630c137c42f00afba578394eebe8f36e8565ff2f7e4ad5cc982a6c952233273a8654a9b0959854550e49393985c5728e10772fc84ca4b0654e11226953881685f5523a8a76348dd34161bd9eb49e39eff8e3097b4e113e0cde294cd0097b10621c09196d52429ab05d4c8a1e448efec399b07e78bed2e3c1fc4bd8c63f9e4b7269f14309cb490eb637fce4912c094bf098524cbd97f483843566444e474931f647d83e3ae4a8cc72701a236c651fb53d214e7a1461b130597739791725c292a2277c1c7a841e6b088b7ecea10721a2bf0b61130b51facca3e46182b04ee51cdd664a9218084ba5faccd99fe3f5f8c1b6a6da21a79892237db0fda6f8b9b58a2be9c1fe9d63f0a019951a0ff68b9e525898f0b176b0d95588a111ab3c22d3c11a6d3b22a546b13e07dbe6d08a51274acee160fd98635814cf006eb0df87f13df1e388fe03b0c1621d2245b2ef8bf80fa0066bb8e8e3713657c5fc0068b06cf28fe92c5a5cf90730837d2e99c4205fda971f800cf61c97e4dfe489def1b1582e2a6a475b4fd17c58ac91529e0729bdc9fe154bbeb8e381c7eacdbb2bd69ecaeffed2b0df5bb16ce4683d52d3f0dc59b178b498fc88fa31e3ab584792d655c6209a7155acc9438f628e43d3a4782a961cc7296a99c3891c8e8a55278514ed585da69f6235cb952187e7319e9b62df4c7ae3212fc55ea137a4986c473f86148bc77731d3714766cc2856f528844f1f8c758a11c5d2e3a19dcf4e7535a1d83b6d87ee8a933b31a05862449cbd981d27c97c621bbb9023e253e5547b62ffe0216d9477748e3bb1dd05ddca6993fcc79cd8d3b66c625f7974bc89d5a64b3f768e3a21ac897df2a760a91392f39289257ae84cfc05cb77c1c4265261ba3976bc52b9c42afdd1e22f872536fb345154e3e73a8e4a6c9722e48de341daf0a0c4561da78e8e5a71323a8925d77a9eeef0928655126b58934d625163543412db7cf46e4a2a24d69f9f8aecc8722cf5114bc6f11cf36e6a42d411eba5fd4741529afc69c412b21aae83f9741d46ac92b2e5e5e107cb17b104cb31c41caff84c2a624b9e2bbce3ffcea19988453aca844fad4d692262dfe0133a35c494631e621913931c163204df107b541553f6566cf485d8d3a5b5091d2a6386104b685f86acb01ed783d82496c52b9fd0390a0a62e9f82759ac2013160cc45e651d39fccc8a270262f370b3f737e4a6877fd87ca2c7a4cad571cef961f3a83b768ee3fab0e49049d377774387f061dd590de7e1513e4ff6b0d505dbe99031f986e861eb8ed9e761928735f7e38b33b11829040fab5fd80a35e12a6de40ecb7838937b72d73462874535a79fac8be01fabc396438e56631e9fec181db69f0ebd7422fffc36872d2686ffa80a397793c326a6a665ff914cc6e2b0e4dba0da61ae32dbe0b087709f772bc64f0e7bc366eb610ed6918d75981b56a9342725717bec6ac3b29e59329b2c7264151bf6cf591fe2740e3bb26a0d5bcfc7f91d4aa58655ce830efef9e33455a5618ff973c64afa29c7a142c37e21e634ee26891caa33ac1f0779fd3e66b74365866526e3d385dcd20d5519b68fee53c27f8867529161f1f0f47a6575d3483586357c689fe43c759c73c4b0fec7864b67f93cf884611fcbb9c2050f18563d8feabed37a389d2f2cb11d3c8c1192aa7f2fec15a672b4d019bd7f17f6407e6e628ed99b7e2eacaab3294985394dff16f68c9a230d9552ea7e2dac21848cc59862e8fa5958734a999c390e31bcc7c212f52443af26abc95f61cdd8313a90bc15b69c3ec5ede823ebeaabb0742e3fddc995fb3815b6782935433d3ccbfb1496d8d851fea0f1d37629ec29bd77c5c6e3543c0a9b8c9a76481edd1187c2927f735c31950716f3276c1632476393e4aab413b614b23a904a6192a39bb0e4da55b86495e66c266caa97a92e37c735f512968e2e8cc75e096ba7e9b20b9217e24938aa10a2727f48d8e38c39573af0afc811d61ce4c44a3d7ea611b6187abdbe21e6891561d55c13499fd4343111b68c8fe13e02a7d892d55c74d8fc991c532c1192c7a9328486ffa5583ee48c5c1d438acdb6ea634998d0bd19c5923515373165696944b194c80761f63f321e8afd2cd4e4dc51f8d13428f6c9796b737441a2dc9fd84224636fd4de05db136be80d25fbd1e15edd8965529ae81bd4c66be6c45672b11f65c8a99037b1449e9ca46248a58c35b1498871426cea8e29cec4aab1cae23b0e95830b26564d1b1a3e7d2812964b6cb31325f2154bec217ab8112b3fe74a2cd6f13d9643ad985362cd71c7c14e8a6aa99358430eace3110f49ec71073b15df11897d6be2aefae389210724aefeb05463723c62cbf943959cf8b1d5e1883d7d3d7538f9d07c6dc426f9432c2a27db5d19b185fcf1d58404bf0f5dc41293ef3356fc3ca92a6251dd994bd9dadf34115b4c661776fd430d272296f414a227a73cdef210cb5986341e51345969883deec58fff738a9d8385583e8a09e6b17bbf828458cbac53a27d7e908283d8438ac5cf5b61ce0305b1ec598e2ce6761ca918884dc46b2c861c5588088875454e3cfe8a0efdfd618fda13cb8b1ff6f82b7e8e9c75545e1ff61c829fc9e9757cc787c5c3c72976f24f59b787edc388bcbe1dc7213a3dac79a2fee5ef10f1903cec4126ae6f8ae0618bf971df4f88a688dc61c9316cee78bd263f76583eec2c9b501922a70eebc4d061ff50f109cd956333872554aa7cd8981c969c29f5afb23c668bc3e2715d6790ced11583c3726592638e345cfab037ec719c2935a4841c78981bb6b3349129656dd8c44369fd078faa95b261dda81ac2ebbe542b5dc336637a1de44c5e55aa867d3bdaaff9cdf478d2346cbf1e2c63f018b349d1b05f4ef9831ce50c6bc41cc679f7df4eccb0a7dcbc163a8e31c448cbb0e5782d8f58ac4a0f19f6183c8c2bf63950cd189634d17fcec6a35a0ccb7720e6e1a7e7a8c3b04df75504b90ebf1d30ecb1321ea8e6d3005fd8cac343a64a1126fe348017f6cad3f24d1751d24f0374414d1dcf852de2efe4fb20c7447e0b9b8d871f7d342565bd16d698a1626379e89de359d83a9e0e39a5f81cbb6361f9189b3f474f631abfc216f56b7e172233e2565865c3c377b0cf617915f6f23887d1c427c2e454582a6fa74c0e6357de4c619bd49d5d7b79d11b292c9dfb1799767c37260adbaa27e9badb4bb781c2bea973dcd17ae0416d9eb0eac7990d13530e9671c212f911aff3266c96d74bf3876816c384b5c3b1e459914bef252c3796bb528e97974ad8438f1d553e729cca246c13dd517c20154644c29e317ccc394e4f121e611b8fe13475c73a33c2329b394354ba8caa8bb0a7a78bbe1337c4a989b0ef778d6ea8f4a933844dec734dcab310d6db0ec3a4bc5c6ae120ac9f9de9cb0308eb498e1e8fa40c5ff10f3649d37015ff7423f6c1aa35397d594739fa1eac29977d4cb67972b8f06089080f2d87142e2665078b66caf9fceb60f9a818528a2187183f72b0e7ad12db141cec51ecfbbab03cf1b8c1f21fec873a5511f1b0c19ab97a3c9447fd393558e3e690bea3d50034d8c3b8923d73713e5403cc60ef68e753e554a49f0690c1bef2b1e779729e2563b18738d5b8b1517b252cf61c8a7d3ca97cc592431eed0fbb3a5ed015db49908e0bffeb91d88a2d48848fbdb24c1359b15af0c0f34ffca82b5cc5d6390ea247ffd8a54f15cbf7268f44d2ca725c2ad6fcbf3f1e2679460e154b9f4dee8728cfe84eb15c9ed2ca99b1a127a65872578aade2733ae672dd8614eb7acea674bc3b0d19c5d2c98376695aab9888628ff37ff64146083109c5ea31bbc9ca74e64240b15c4495efd48837924f2c123549ee503ccc81c4138b4998a0b172841c239dd82666d0102966c34538b14485dc517e799adc36b1a44de1731c6e52db98261691ae8c29cbc41a377988f6e72919c3c456d1244c8c2924a4d825f63abbb8f8a1079ac32cb1efe9f7f807192d6595582fdde8c761392a6494d8e3204aacdbf84d9e496c21fe446a472acf4b62914b1beb3d125bf20f248ec96dd40b127bc77f39ee530f3e538f58fd72cd247214c72c47ac9f5e65536762b96ac4715a85d1cb33624f8f321ee6fd9f7e115b86f20d6b915776452ce99f03cb157f7338119bc74a1d850b2522d6142b647df8206d4a7988fd03e90d2ab7fd214a432ce1fba3e4112ec43aebc17ccdc766f0106209b97c39dea5b9c919c41e59a4b4be566a71412cbbbdb183b5ca4e09c452729103f3c81f3f00b1dfaadc4dfaa654fe1f96eebede90f861bff09fabe3e386581fb6d461768548bb903d1fb6baddf0518cf84dbf873dffa6079792c48aeb618febef53593c0f7bfc9eccb41d722e1d0f5b68fa8ff8fc0e5b4cfa7453f551c8b91d96cc693dcff79d495e874543986fda1ca6e5d061cbd929de718e1ee4e7b0450cbf49fc33a78c1cf6b3dcd0b7937fe938ac1bfc927aa70fb786c3163497c7f3cf0a61f386259d4a56c8f943398d1bd6514d9da39c43c9a569c3d69526a5322b2a68d8b04e4c9636be356c6739670e1d04bdcda861f188313efb3a9965d2b0878a902646db0e378d862da4dc09e69779cf3ec3d21fdda68adc460f336c2b9582857cceea28c32a1e26d242326ca92c23c53ca7f2189af138c60288814c553990f4c2b07a74212e25625c088361cb1cce8609fdeff417f6906b3e3969d33f2fecd5e1c6384bd661ebc2aae93e8ad3716496e2c21afa72ed2b9ffe54b6b0cea6bd2cdd93896b612ffbfeb0102a3a59582474acc24f5362b0b085d578aca490b0afb084cc5b192b7cca0f2b2ca1d183ccfe141d5a85e5f7e370fe24738554583eaadb90d1e09d29ec9b2264868ce12e268535fa3ce42b229c754461cfb516c2c3d7ff0385e5c3844f0c2925b93c61fd0b398eb5a51b1e4e58bfa3c89f1d6f33da843de4b36021999e86095bf0209c74b430a95cc2969a72e57179501155c2bab1267f3c2a2a49d8c224c345eca01d07097ba415911cbed36e8eb0757cd5215b163646582d4f52efd69e5c8ab0072571b2f5194525c25a22392a6447ed216c39a95fe4dc692a4258fdea539068972eca206c1fe7e8ac3a46eb81b068a8344d99fbc9f3833d47b952acd434e57db045d209d93dde1ddc83edd24824ad90f4531e2c9339688430b9d23bd8e354376649ab0353074bc5990e6cfc72de30077b47a6215ff75eda71b07ea8b1cc175b92b9c136212ace7658cac506dbfc07fb38af003558359988741ca79e7905a0c11ee9e7304650ef50720598c1d6e9fee2e79d06c91540065b9eb38e294a8e6c178bedc3d84985bcbed7c162ed9388a9f4dc2974af5857fb3af2cc95b426ae58ac42fed1ae9c72495ab185d74a7abcc8d91b2bf678f572fa9e588f6d15fb6a5c38f9e8927f4a15fb868eb3ac32b574a562fd20fec2d5a858d5d35aeef83f04f9147bee87f787a7e729a6583498854830338fa34ab188d6e85e142bb98a144b0e1d31cf71a3eb28f668628e70a239e84e145b4e2d3fdba8f44928b6d959bbeafc1d6584a0f8235a9e142bc24fac1a9f374754c7721c4f54db419ccee3e9c4f661b72bd98731a50e27f6be8e2bfa4c46cd37b176e84ee1730ec65234b1868c9c6673bef58fcfc4fe718aaa913c88798f89add73abca2a7a093bfc412df417eb8589e266e89f5a34c67cce195d8d3a70f63fab8d136945853640ef128ae6326b15d94cf719c4612fbc77992594717156222b14c668e6bfb67aa1948ac36b3b9433e8db1ec476c693fbe0d1fe2775c3b62f59062871d3df8c0ea46ac413d7d702993aad48cd83b47766267a67678116bfa7873f6cf8ad822c6fc77aa0b0d732236ed308f6ceca60f66442c31746029375653e1432c972184ca7195fa071b620f3d0a1e97e355efa5104bcc2035d5e17aec2884d83b30fb48f25f6f4719c422ab3b9e2483a46411c492be1a2b3c59495802b1548a4f71a43cc77105c4def93c2f795ade8dfe61b3959d12bbd461ad7ed83a68c9a8f7ded5da873d6ce6a5edb8f72fca87d52fe77037a7fdc7a17b58674d25845fcbd1a87ad8a3e7786d2a8f5d27f3b0fda4c4eacbfe88493cac391a35ad5051239377d8ba5643c6f598544e3b2c71b91d2564eec7acc3222b7e1f663e4c4b3aac1d3e778e63e620ab9cc3a2e9a1e78cfe38e5510e7b144f8955a864ab24a361c1c060301c0884810070a8533b1bb316080020281a0ac6c23492a45e1a14000238362c3e241a1022101014100e080a0a0e080a0c08080a0602c0603018080087c1c0203c2063f535b193e3ca1f7fe69864c7e7eca5b97bfa9d93370e5c9f79c5f73ebcb89c3da69d5ec43ea918f9ba00c143aa67d2d06f97bb6a45a3dedd67b78e5c3ae8e4d5a5c74f6f5de6fce93d396bcd70e66466bafce88183c1fb48e6714de5ac79684b466211ab3fd1692d7836d06cdb413dc18557a75ce5b4562925069284f6e9210c0192553bee14b746c0148b040649ae320dc6142827538564d6f8c66206e9616d413c97aecf5c7f76d6e96b0f4e1cbe78fa09e0209e7ebc4ec4c58b0c13746890323d6832cec855e17c066ee0d78aecf5664c998f98cae90a7a91489a149b3bca3e846b306ea294d596492a997280d7a95146e42961c9523d49caebfa3967b75d38bb79e215665763e7a803ea86d450c872f0e494c3a7b75f70783c663bfea7c0c9f96e8e3cfcc02ee63134fbcca2354debe6a1836c1fb9d87465c31b0fdc40accb2bf2ef139f2a08d17bf04021772e1b44885a2af1ccea185e36c5cd78c1323623e314b4e7132476b51f16a10a57b7cd468811154a09a72e5ea61bfdc3a50fcd04dd3dbb6c02968b91f055ef2f242d5dc52ed8051fd1e63327df03e5f12432428013aeb4b692561f52d8a86373aaae54d947c7867673d4c8aad37ad16d96aa98871e5b56907d951851e00bfabae9da4087154505baae0c1a75d49124fefcd963276faf3bee1832413f4cea4e71e24db8a261441431418a884256e7728db31d3c574b377f8d3dbadce75f1e453aeca1e1c523eba46d56d172a3ffcaada323b7de3f7155ed72aea5d4ee7971d8d1cb63a7397472edcad373d75c3a73eef2d24367ae5d7076f21ea225232ccc98204e31d189114525b5a4886d6a1c60119795bcb68e2ac26cc778b22a329cb0a2431e2335e491b061907abc85ac270c60638b3e4adecb618bccc1f3da79c3b7f26c4cab1e630e0f2a1614f2d79446d4f80dddeef9df940f974efaa4913ad9e493bedfaa3b6f88d7d08e267d12a84088449a284c483a051494349b73da475fbe3a7df1e189972e8b0771106364f0d235672e5f3cd55a4274c9ebd7551e766d5e1457ef0e633679e2282c3f79c025681fb8cf41ce7fc33cda6ab64a36b32c78b33a74f060c93eb24e13b2c3833157e43e16d97b17b9f2f211b2f2c707256ac10e1f224869ddb594f4b02d6688203f19f1c4f035cdba7b9169c9b6b0094854c07956bf746424433426b0f96d02c6cdc218424a532022c4810949521b582635031c4da434c38f0932babc2c234580833942f438304a8c6c2d95bc905fe1d4a347927212e89cbf71cecd3317675f3c7ee33c7a2c907aa29be9fc9dd70faf3b7b78ed6227c72f5d3fedafb5927e7505ee5d9d71f6de6f4819624b025c79df283284a9571d76601e3b74f429af7974ea0ce83ec4ba8c9017ae3d8f190b710ab1fd0f79ebecc65997276f9cf0fae485265245a36481fdeb04104c483b09289044a1d415c4250b506180be7270e89967d7ae393bd6bdabcf9246d5579e1dbbe7eee8c533371ebeca9b75b5ed106ea867bb31326347baaef94c612dcabaa83232890f7d8ef938d1c04aa202fd19499c844a8a24bce3a94487fc9593571ac34323dbd9db536e3cbf7bcac5d1f3769ceb74101fbc74fac2f59957c09285c89e2081b4735622d5f48a3a4dd4b1182accac1b751c44a54e258f12a9528ed246c99f52a9a8b48be1231cb9a6b84c1fa511253aa5484a3c25a9d2bd526525be12cbbdd4a839e86a574a764a4d25904a142554258e521825d0519a4e49af193353294fc95512575aa194a0c452aac92a95ee917d2a094ac9a525261d25c865a9077c8b1978d3a5753c69a87b4ae84a0d2583104b5f9402b8d42562a6fc120f93a8126b4a3da70cc2f2aaf959261f1fafd8a0a4a2d2d68d2875b80073d58b655c2547617951cfc6c8717840b0857bd56858573c8d995e40a0a623376ae13485489270c8b5f95b2209b018a511c1e0910ce7d51a4929120ed29724a2a402090989893485d41a4989c4479a408a81a442f244aa428a8cc422c1235520454062214122552145466291e0912a9032a124de58a7d1683aea218144a2444a207191cc20d920a921b590ca93709458e590eaf67b110123f5e390962389666548f7480a481c484248942454a5e48d442197cce7490c290e091a9212a98f248124034985e4895485141989458247aa244551e220c120552045426222c1902a4d519578488c0cc929959c7f3c1aa4454879483e2461922a25141217691aa915920a120f69162936928ae48f54498aa2c4418241aa408a84c4448245aa21454562234121d5204543e22241235591a223a981c4437494ab6c951a8cfd1728a01a89d9909c20fd636928a54032966fa454b84703b731b0cb71bf61142586362a0c119d42f168573fb335b10857ef4722e087220ff4c4eabe0820845c55e102ea78e33a24e1194aa9317e91f05a04df60e38a2b61f8422695d538df8b442a2030e1a2875ffcb5161ed8705d3b412597b4f744176c785700e24bd1caddf3a9924690b8af56bf0f85e1301c8531020710a3a4a7136bb834e328278ae0ea048a0536976aa76906929b6910dc13c9199b025d72823ef9aeb1949ee0ff3099e2c2d5b941dff8a0caaec0bf464d15cdc07c019b9496bfbfc7cce2e95cae2ce40328c999a56b26feaec7cf4c164072bd6814c7fdfadb1edfe1446cab20c881ca75cada1ec9acbe3e936c712230e64af68aa725251315e9f52b17f9fb2077d38e1af7a39a1d44bf45917113c161bd6c60284448e288ed7b408819c0b2d3ee1aaa4c76829d412f9f11a8b99fcd9a12b2669c66806facd4c6cd559c5ea26ad5461a8bee3b348a0df9284ffaf17505a2bcb1e2043abc3523a68c02282912ff7982f04b91ffe19eab24d5991e6fbf631908c925bc0f031d2b3e521e251c20f261a2ec7e8104f44c52b84d6e81465058265c51049b8efa765319798988a31a532e346db495ad6ab74326336577ae8d8125840657afb0deddcd51d27b9bfdf4e44b5ee44c0903b34573bddc053ad8fd1077df9ddd9a6f3207a29a6d664af0b74bd4d0d1436c8a3e58d33dffec9ce19ad04cc264d36643e5e97eaee2271ab31cb6944886160d034a3fa32f0bb6ee173621f38da823f22f7c13b8c39c0046b6774ee88f4525c061ea04e6f0471cdb76d6c51bf710151446201a8f1c80a0440d4e090caaeadadbbf7d88bf87ce5f6445a213ecda98c6c3535e2db25814638ddfdf22f64abdae0d59e48fa7c8c5423f5535e815a25fa36864d8cbe19e45c69c1384d65abfe4b50b504178b4f20b2a1ec60081fc84f309142ad1ef9849e6e947ab12cd17843bec67c223b0eb6c92e41ed7b4866e0cb5e609fe291099d8a7b8c3f05bbf7159c547b106ee786b515b2cd445b01467957f802545cd59772ffde376b451cea17ec872a4eb5cbf81bc2f1f3f3a05d51cc1c532971d048d3357c2e879572705faa6154d4c38c05158c1d65f109694f6d35051965141e1af61198d991da19b6f3e9cb069ee1411e5c2135c66640ac2cdb2c3675c4024647c4215577cb233cc86123919f954e31128e2dc3828683b8114ad879ff30907ce82cb478657a036fa92630b28e3610ac8355e48d9418ff15729e400cce89e314b4bf948ea0d538f0885789434b267930f0bd5007732984c83aa0b209bc0eb2608ec57c4cfd2d8877350a2eb178f74853bd1e5dee88977915fcb6d46ce150b6751a50777423aa73d88b0c5aaa927f5b2270b1c5e98f7e4a2debdc831450ea3b939e1a4f94c0b41fbf4902211159ffa8f6932f03788f1caef01cd422da4d8acf158d05b7827ff3a0a8c4a48027ace533dea15f628982a76860c64ad1c4b8242139ffa1990705a032018ad6930413a3670ec0224eb44b7454cf0908b8887898ddfab675b1e8f1117d5091148390b966da064481fd13e3cb3021e30e339f9e39fbd517eb8ff87403740ced23f0ec034494a51bc9e7fe5c328567bb80c1306e788c27d83798f11252f1fe6a3ff289105263b21a1f7e32c8c7e6bb860603498517246f9f813ce3eee8b596efc7926f61574a04c2d46a2d3aadc494ec852c4ab662ecb033fbf7d20db81f5052f6c5b9d1e27b21510ebc2007a5a34c0d38d2629b728067c4382979469d2c52e134efe4be5ab3a889a2a0a173a50030f348c84e1e98cdd9cea9a1a805da638a29f0153f443c3c6de8b5bf3ef226a0802836f4ccdbff0ecb0ec80277807fc195ec930f3bd8a9c58a2dadac1891555a609e049f16023b974436cd0a97fa8cdc73aefe5a2f18cb4ba57055f41c5b51c66b73722daa677d8714bb0d605f1c757897c2d14af6194e74fdbcef57816fcb6c192acea6782b91c844531df4cc82b309681e88fec894a340a508e137c625d5b9b9ae570951858c8c9371b6e56fbf25e61cd07cfd011164a085e32c3a0b596275f32df7fd046e5c860a29aa26be2cb16f9cd780b0534dc0a3e2553678f18f1c1c3074b6251cfeb20cdd6bdb24591149e045e14a3ac2b3b0e819ec277ab39cda9a3df702cbd5d42e4824bee51a2ba1d719422c2331eab935c046a2f8eea94c1cf19492fb6be637cb0a3394fa08bac4c805293200ae554b725a1eacc19affee1cc5119e80a97f9111988b652bf8146c400e1252ef8670ce9ee90c3d7b9e2013daa83cee6b4f3b3334ad631cac74d04055e470a2c2ca1c05c8eeb1318c884041e3149456c62fe919e4e785ccd0158ef68b2f81046d4a3343ba25ba60b9366c71644352dfe8ee1d1feddc51f91227721a40de9f010274afe138d06364c2ceb9666e4f31e93c410a95dda95aac9584885cb3781a5a928dfd70fc12baedf914290d237c6bfb91c4b47f4c69c5eda246c545fe9f75df4673a56d12a0d92bd02d9ee95ffed8d199865dd55c8eaec5d5f3d30cab64728c2350e08c2dd610764edf479422e7ecdd029a5d67c43fb4f85d0ff54031d46ba32011694a9aa77680730f27d3fb08860f2b4b41316ec1be240be2dd152db459a80235d4be3302e66d222bec12f46f41ba92b52cde230bb9e362f3ccf594fbb17860767f4a664aa9926800ab7816179cc7d5a2178e0f9af5610dc6706b8fd0527341f6a86e182cdf5b43e70e1f9303780870125b4552ea3f7cf9319b643c65e48e435cef697a2881d8d57c5622cfbad4c3f901e470f6894a80852ac79776037418347d0c8525ab35a62c58fd4a47806a8674be330e0c61a70308447b54c717cb5f802435b1bb6ff428da3ffe603b80755bd1c458f49766ac9b9f0dff4f32d2cb119482aa42f2c3bf824f5ca4dbbaba32f273008ed261beba58daac73c292b3c209e7440b632d12982462d4a4230ed7a8d9d96566c1a2ef9e4ce64f7130b0ed69b331e4d610c15b0195adb290cfa7d154441bb1e5a37b258dfae2f82bdaf629bae912eb35af4623019efc9ff0a2dfdfacf892b82107ab45b7b62ba539ad148b3f5dedb89ae69ba88a1bbe7d02948c658705cb957c3eb496312cf2c6bf59bbf71dbf42b321b5dcd187f2bf6dde82b86914d4f72635b67ca79ce54df2d59728775fc9c2c1730b191de7727a6b6155efe1fc21250bf3a7a7efdbf3149c778e4be966c5113ef2e4554e3942af152ed7edf37332a95a55163c5fdcc147a970cbcb6c14348f07be9a508efa2dee2dc79b72bbae8bfd64e96ea22026aec882345a89b5f9e49f6270a8e0d8af31c134c951c21c1dcd41740b6589ab756165a50b0305f86ee7e481b27ae95649cb409b50155525b405bf7e93d59472f4489af93a8ee1bf2a9d9895d0c2f4ab4eeff3c7411abbde14f2725a7d77442b783313a2b1092c4dc7fce249f01b01659dd9c0b3cc04e5daa1134235411c1bfd809da506b3d2fce821a05152b0709eaa557e537de029e94e03d00d3160e77170ed08ba0cf83df9184ec7adb4dbf5da45d268770eac7b99ef47c8bf249497a6f55757a4012e403183747e88271da920f8b80adf6a66f89d457950bc60964f15224ec5e59de2118040ae59dc9b6b1909858f0e553d83fa42da6540ffcd084830e6d1f19503d0020f510d59caa3d601022ba5649ed798d0f9fc39f2e40f7eeaf97424cba662aea0b8be4aaffbf45c018cdb7049a7015daec19024b8341512580a379940353a6c59055672169e38379c4e610df703a582a3a88d0bac135dcec53b37da0d306a827be00a1dfe6262f72936353f508d4b61768ca042103b663200e9e8d8c85e9a114a0d7974addb27aa25cc7d168080ca25f019c0b1ea2a80b3cdbcef7373f335aaec384493cc7634b4d7e0d57152bab87a640563116f5754efcd3ca11230a75de7ea1c4aa891ff1e3159f1746e9fcd46a6b2396dd637a21ebc3e8c185d73158700ee56fcddd8341d04781f348ba964ae4435a300ba66b6b55d225f764e9d5b357ef85a1f984b735fde4d0569e6445ccc50362b78f083042dac5cc83e4f0c955e11dbd0fa330733169e504087043a10aaf6b5093fea8f332b8e831dd7f720bd6b60619d332c97ca46126a350dbaa2eb386174d3c22755f949dd49defec28c5b693314066924a93c6fa95019eb022090e2ba4685280312e2ce61bfcd1ec5156c984fe4faa9b66c7870580c00e85684110b65d98a806d089255bffe08bcdac5912dcb5e62b1c3a449092a0c6ec4f9ffc7d1d32209bd161b06bfa3f7c0b72d0482d8a9ce54755848ea33b76bff8221347f3137789964a091a5fda70f75498f072534cc92915eceadd9483e3594cb507f302348e92aa0e72049fc59c1cd545a103531b0b0cd48af9b1643098874801499513e8baaf6d39ad18528204a5867062a977f5d151a8ea8bac215b88c33113f5b24f27bc2e9f1dab8872b05eedaf23935332159a0351090cfdfaf74cc4532d1a25d3ac9ce4093a71dac2c43ddb570471fc4d81363904492780f32b00e0a5ea2938ffc4e28986254f5c98e1f3ba9efd73a5c85b702e276588ee3f2dd55b1fa1cc52384709f5e7160467224762d445cab9641d42546f5d2f90bdc219a6e2b3d8c5ea0530835b9ce275840b75900764096db4dfb5382bd1f55d9da4c905e2d0261073486460c2747b44fe740d7de55cdc0b9c7cfab5a311ed9fd8e30748fb0734e75b78adae058921b7747c4c2fcb6095f51eb704be51e9c7ae59f9023f34606b9844f2afc88f97fa910804c03604320eed04b96efe6a6744bfe1d05086b66dba9cf68ca5d83754b4797be926cda6e0cb8708373eb2597b7d76f1aeaa05668ad7cac57a2f849e2f46d6a42436711ae92ecb2bc28158c75e0850adaf31059850256eddd3dddb29cec153be1d20ac202d3ab385c330582a4b549b456c918b8d006aecf490a4ac90a543f08b06a09338235cb2d6504369443b5dc24a8c06d08c32be2a6c103e3deeb38d50b92b8d4838374ccd179235c69c235696d63f969b4114a40b56c2348f484c0d9e3c3ae017c07427ff360fa1ecdb29a61a0e638236bc03b3ab9f809a9d1eddd6284b6eb8a0a011ecf3ac4bd727bd71211a2ff9cbe22a4f0a72de29cfc3222ba86fc488b6161e1af14e407fc993469011c878e9226fd148d4b4e691e21aa4332079007590fc9a3d75107d449465d472bced7bf992103a5190d92002867dcbadbf8336da270a3706856b4730b4f2eef673f4b814f3633f9080bc8d38bba0f70826942425b86f288db84ee239b4231120595284e24e68f2435ac064c25b39d11e8e162499684e3e8b34e314be9c59e15b736a87e9894d77c07190269ea4b910031650106da29fc6b4d409cf6fd994c43f1c2d60b26dd2c885a70e1d9e5c3450b3d922a5c339a135ddffb435bfc4c0cd8431eb07a4f13283be1ad8a63485725e86bfc8e6e10c336b1b95f240e3f0fa9fc3b9330d1d12432aaa56650040128f814fa3c5a3f7a1433d9885edea52f63a2f0dbbe10fb1cb199bd7ee4d1442fea8da1f9df2e3ded15724ec6daeab3aafb5b9299e185ef52e07283d06521e6cf86f64f24350d252ad32ceadee6a379f6f8d8cd9588bf1a7379a89fb07300ae674798662f47d58c69700ffc35d59b1a32a721884ae5d633582fd2fa2f3d07498b76ad80a4da1369459e84674e150868fc3549c84712c787545f3c216280c3078d173868f434a82718fda8c496e29f6d6bfb37bd9db580ad8147b17158a4ca8c275fe669f80ba6cc239ca0b81b5004e3b00eaa709500c232642021d4cc0eded0010136f94beb2d1ac538866d96dcc4c91d0b3b01203d4ab02de9405ed0d3660b25472ff000000000000000000704e64ad28086cb729333997e8ce66e5955d11292b9295f8745e894f6726ee689a6a052b78cf2a016c0dba0d1a0e5a2062fff04169a8d47bb9a3b538c4b63957989cd358448ed6c210dd8ac4c7901d85582bc4230d153a0c311362c9d1acd2e4d02c471ec41673a8fd14757c3e16c41eb11dddc7116b120ec41aaf34c759a9633e06107b9ecb8156c723ff9b3f6c2b95e63c4f4cf6c60f6b9574e6f0f35466d387cdb3577423040b1ac3873d8e95b42f6988c9a3ec61b32839b408f341caa287253fe25585d59348c9c31e7d8a8939630c7d513cec9174ffeff74826f50efbc7b4f9e822751ca2765863a5a41df53f9c25ebb078d8ef8ff379e8c8a4c33a19f93c7e7ee7cc392c39d4c3c3e0abbba51cf6b076316596715873c50f4a33264a0e1cd699dbc91c849ce36fd82b3f0a295f8c99871b36d930ab3ee2bb9936ac1b55dd61c8ca1cb261f5ec88a9229666766b584a6276deef49b1a386adef83fb8fc913fb346cb1a122e5d819298e862d7f3c39fe66548b336c96fa231313cf4bd25a9861b5e8cf31694c1b43486b51862d4b43ee387d84e5586b4186cd7245a69bb2947c6b2dc6b05a68b2cc297ee6c35a0b31ac5f7279ffc39fce586b11863d90b01bfb17e672d65a806135ed689383587f61af1c4d69b2dc395cd65e582f48472511cb49b2eec2aad1d2e3f433ebf96a2eec936c365a4c59c1afdec2fa113fd887e942c8576b61891f6e0c9ac9c25221449d8af1772916164dedbc936373ce1596afbb08c1c33a2aadb0c63c3f5312530e625558bc4e82947f1c94545458d38ce4e8c3b0d299c21ee5b81eba3b63c8a5b00721c776a68d4f1d857d2ac6d9d151eb38a0b0a7e7b51f4d77d513b6edcc294493e841ec842d4f94b01dfc52589bb06d8821734ae6c9899a09cb8739a6cff17e8cbd842d7a1c6cd4f4dcfba184a5a2ff3bfc1c9d2761d9142ac6fc1d6d9948d823d6f2c3f0405378842d8714f3982b566d84a5430fc2479d226c66217e289127c21acd4227fa8716fd216c412c48dae50a0f7721ac156ac3de78f8dc7810d68f3f1e7ae71c4dc681b0777ca6f61b9b63d47fb0e41c27f4ff264cea3e58428ed3fc47e6997ef7600f2d94c50879bfd3e6c17ea1ac2a668ad371bd83c57b2ea987743521ad83253453f42ecb23ff9183ad3269864dfb68d3070ef610e76cc256a7301f37d82ffd87936c426de5d0c206cb8e5e465a4beff2d0a2067b4c1363e6590cabb31634d87f3523a3d78518642d66b0a65d09afb2b314590b19ec614a47bb396715e158ac932cd7783871d7038bd52ee47f88e6cfd8bc62f94b0bd133c47214e38a7d73582177695ab1c7cc4c492c6f52d1b0628bb8fd388c09e14366157bdc85878de4a87214552cd3414853a12e746449c5229f9924eaa85823d4860db1c30e3e4eb1f9e6d0b1150f3a6c8aed937cd8871ffd31a5d82b56e820f247ac14522c3e2904558d3193ea2896181d5d0e620eaa4345b159ae64b298b6720bc51e3659e4c7a489a904c552621ec59f528f21fcc4d23954c6afebfe389ed8eaea72e8bd3975eec466731f3d48efc882134c79ce1362b8897d82568c69d4730cd1c492421a8fea1d87c9ba4caca11f726e443efb31b154a67958669eb32697d83a7dcc98f05bfab1c436a182de5a941cf595d8223fa7fc60c3859458cd9284853bcd9c4f62b5943ce7af7e574c124b3e4bf11c5de67424f6d8b7aa3375799541620dc103d58a2a1ff623d6d4d17e5cee307418476cddf921a2952649a9466cd122c33385104387115b5f75ce6148c6e42f62b118b911d3cc830f45ac1b7676e6fb11a3895855c2e97ff8993988885522677c984c9a2a3a0eb18ea439ebe87c336f88ad3fa89498dc7ea510aba579da1909b1a4f9207dbcc3590c62bb986e2246e69c2387b310c4221d25f31c11d5fe398b40ec716cccc748cceacf590062b50e7663fa9815e273167fd8b3a3e62087ef873dbe50d5712f84947c1f968a96992b72d849f27cd82253ba917e0f4b774e6971939fc75c0fdb8491d04e0bab97e761df9b20392e87712ac7c3361f6d33731422c5efb044f8affc71d861153d8d7b37faaba9c3ea21dac973e9f77458277e47a6f839bae81c96af1c1e32323adc5a0e4baa4839fae7e02ce2b04ae7f2384bbec3cfc159c061b5da8f1232e5f8a31c9cc51bd6fcde8a9882460d1e9c851bd6a469452266997f0767d1862de69c9f831872ee30cc59b061ebe8ce3a5a84a90873166b586e3d068f9fa63bc770166ad8c37c1572b2f4f862c359a461fbedd58e6a91e2349c051a16f18fe1d2e7bd6419cee20cab690c93b9e3a49c17cec20ceb5ef4e6891875a7c25994610f3f7e875c0b2939ca599061c914eef3c9e7e978e52cc6404a291d2376312c5d663933633fb2c3b0a7697450163e5402863d696e86cf6e4cd91756ad9cc4bee3d14b79618fb1619f927ad421edc21a3f33a4f9ee20855cd8429890bdf5fa28cb2decd1264a988e9c8516fec9310bab7d7e489b03b1b0ef9dc5a78adfb4e215f6505a41367e3f4bb4c21ed672189f2b4fdeabb0e4ff7e2e893173f451619d58f631e886b9f8a6b0a446698ad47c8e3c29ec411cfff09cf24d785158fc53948ff39d7534145649cb216cfc84fdaeec66a368eae9843d4e95212745e9054913f698f3c4942447318484097bd2149facc812d648f9238fc58cce2b61f9f441eab0534b7912168fff4a638d84254482587a8435751cff3c481cf130c25ef3392aefb022ec217e3c631bbbc38c1161d9c9fd81a843d8735016699a1f6f32212c1bc7e3cf61845427087b1c4aa8c78be9fe07c27a1e670409b9c3fc0f96affc8f1c6c4829c6075b58e8ab8e529c450fb6184b1e74942b251667c18332a365cc51573b58d72cd3a56a8a395a07ab7e8c1cf453ad9e3958e3de8c4a04895be260930a5d31cccf9e477c83556248b164f3d63c621b5892f131a46bb0aaa887868d9e3a08310db609f19cea79e3fa3358a673f413d1d7c94206cb8e8599ca5812d2b158577a4672ec90d31c586c1dd50735d9bb89bf62b19c97a276727dccbb6289ac601bfa36fddf8a6537dac65c9a3eac58a7d33fee048b29bd8af5c2e6a38f35faab62cde1a9230d93b5a662994d3b1137e73c31a8d82f54904a36f7719e624dda2525b3a139678a7df5f39e7ad8132d2fc5922a1bd427efc5a4d87ce25eca1dc748cf2896bcd4d8d4c126d4a258a2cf89e7f8250d8762db8ef4f2e31dcb2728364d9f4e37458e37f627f64e1d94976a2edb135bda3c318d473ab168f2c0af6e4e2c1fe29a77078f22c72656bb984f73ee4063aa893d4c66dd29213f4c712696ee74d1c4438f228f897553c54d0fb959f125f6e8f387e5253145d35862bfcd6929d2c6c4b9127b26f9d0e3dc972943896d3fcc0839be4f213589354f36c58fa31d878a2416c9659f347ebcf589c4aa359e43cff5111e90d8420a7d7137a38e8fd8a2c4dc7158ca0f51472c2b511d438c9a5c6a23d6dc394a3d67318c8711dbe597a54ae99bfa45ac41ae23223d0e3e54118b7e454cca71c8736622f6e029444c09312f11117bb81eeaa7b955ed0fb1dfcf8d5c8a359736c4f241aacff51f2cca85d82687b096371e260d21b6cbbc0b77b941ac76937388e509628b1f8446a94454ed02b156556ebe14163a07c4f221c47d1895a30bffb047aebaf8a77bb5f9618dbf1d3be7db8e16e9c33111b1bf16e1c31ec7c94daaf12cf4b6876d3b3db8b550f5b08ef4554c8a9783dc4c1eb652a91c95040b39c80c1ed693ce9bf48e2475cadc61c978bde943dd5a5fc60e9bdfa4d9d2fa38ca95a9c3dee99157caa186d895a1c3661a83449ff2e41f3273d83adccf49623272584c333ac6c560bf9289c3da618f56897f78840c1cf6388ac839081ee6fb9c37acbaa132cc3358edc70d9b4af228c98fee97df8625dcacc5fe38f7873d1b36af70ebf1a3cd1cfa356c9f6eb77389afddae86b53e3d75928e62ac781ad6e8d2bc95f352321d0d6b59ae10f299864efa0c7b94d13e8e91a390adcdb0e768880e3f493fa8cbb05892886796c7ef3fc8b087782793895eb71f635862dc47394e0db3f821863df785e6a02ee6e64718b6e8384cb1dc61cfe300c3d26148217aecf8c296a69f938707c9a4c30bab7c1c049b3f1dfbe02e2cf1242f8246caca3017363d89f21b2d8b2b6f618fecc30836f17f72ac85a5ec537ee243e4df64614f1d4589761fc5f03058d8830fe7e3b0a26b9fb9c21e5b27936cb72c67acb05cf847e7d0f86164aab086896a2a3369438e4285fd53087d391afe53ca14f6a990edea1c98478b14160fe39e746489c2d6b91dc68c95a99302853d66270755319d5ae5094b4a621f25487c0a15276cd2914f880cb3492a4d58334fc566a7ce5a95097b55d4466ac7cc942e614f3f31ef8e94c739a9843daa98a2783069af9349d843873431448f3ae51309cb4af809d1d133ec3cc21e95a6945b9a3aa369845563dd86aad0342d8bb0c58e92528e64e2a748846d3d4ee5617808dbc6ec4edffa84e584b0a6f9c837d23955ee82b0e638b00852e9a34407844dd2774e848bd9f50f96fb0e6abbfb62ecf0c1229da38ca1e12a5f7ab0c41c04f5b8121eec91587698397afc40b28335a22bcc4423868ce860bdf00d29a572b0e8a444ffd41d3e38d8f66b22e9690a0d911b6cb12a374798fcb90db678de791f79d8e6d460ed8fa2111996cea6c1f641d009d1bbef3c66b0e7e9b52c0de2290f4006dbe5fc18cd8f532463b17628b39f9583b80b166b480e311fd56c45f68a2ddec7b394abb862c9f2d079fe2aadd8c2a95aefeac54a5558b147ccaa93f5a87c4365156bc8ea15f928a6c55051c5a2dd39c40e245a7f9c542c592945895d1fdac741c52261e3cf5844881cc7010128e00ac4d8c2b6f9731082c43ea9d8711a0ca0f1c56780c6062640a3468d1a35bcd02ec4d0c2d6713021ea77ce0d2d1b6094200bfb6d6f8e19dff381a699821a352e0616968fbb24c6a5fb86960d2b0d643120c615f6cb31ab3a56ba1042c3430c2becf147a9cac3acbfd0b90a7a7acf6487d9481d6250618b92184483a484f89f296c1e9127b39375fc398e14f6b5ce219944cc31ac270adbfffaa47a0d854d829e84647f9bc3dc79c2a2621fddfe564c1ec73b61af9434079373d8716ade843d6b524ccffee79c61c232e551ccbd8bf92bd64b58224ca22773286113d3cf0e25e692b0763ca29df71d48d83fce393b44644b357c84ad42d2ddee28af0129c430c29a1966296479df4cb8086bac509351936e0ec24458a543cc2e75d8145386b0e44a513d53d4240d1a21ec9d7c7e928709b1834c10b6b859613a9ecffe0e843d828e97cf967f48ff608fea503bf1ec2247293e5882e5f815b3961eeca941a66b4214cf1ce5c11ded479a4727ddc17a9fe3870757dfe5491dac31c4918a69ce1caca973d0a1b1b7b51f1cec1139af78d26fb0874faae7bc6db0c5ab783671c542eaa8c11e73289dd08f224d0a0d160dfe81c958769824cee05c17d37575d4c590c112ba67276a128bcd3adad9e58ba1b18109d0a8b251980283c556173c85ba186e3d26afd8a6628f071f4fe2c771c59229ae7af8397e4c696bc57ab9629ee6fb90ccc38ae3c82cce3ee9b58afd5243f4209eaad8e320dd7b69e929a72a159bf97a8eeae437f5818ae57f3bfce4fb40c4a4532ca1b46eefc4c286cb31c51635721c74c8eab0f35f8aed2a9a9c4dc89362ff1022799e0b4d4f690658d928ab356c318a7525f6c8aca7ebf4e1a2d8728ed26ae80ec682078762499723398d5dd6a16f40b1549e479f611527abf289c53e6886142bf3ee477a629b1c27c61c58798e735c279610ac43ac74381136e3c492d7916453d88d27161a0ca0e111a0c1001a5ffc8102155480c6062640a3460d1b55c6b0c526d634cbb3f1a368628f173eb6635599583ea4dadcc5c9d3f1a44a832d30b1a7904f5725f85ddea9013418600a832d2eb1a488996e8cfa11dbb1c476e6d103cd79aac41abbbba463c26dc984127bd2dd4f3143100f63c824b6edbe927ca52456fbec38cc1fc7a49b48ac7a713f57265a7d680ca0c180e2822d20b14f8798a159136a523e624bfd398a74e933c27d1cb19ea9fedf7ff48dbf1bb1df567698fe3185c5cd883d46cdb937568aa6f158c436235173f20f647b6645ac398e3ce9e4ac48213f5b24628d9b9efae3f8c8910a22d60ecb9d1d47b2f4a31e62990b99536d6ae52c69886d9347712a9258a61f0bb1864f4f16a2d1218d4788fd3fce95957f5b9d6903683080460668308086033630011a356a90b25105105b0c628d889cccc829bc728820f68b50113772de702709c436a1398484b000b1a5e938c610742efcf8872d5de64dd8b5a0398cfcb0a6b891fb18975369fab04ebc8a8f5779eaa2860fcbc7a12f7f9c73f0d1c73d2c9f69aaa92b1fdf5516408301341440e3021338156ca1873dee83cac7ae8ec3b4128c13a400052500638b3cac97c1f6e2f7630b3cec95156955dfddd0ca329518d8e20edb7dd2fb403dc5861761d820c6822decb0468eb2532ca40e6ba80ca7e6a14ade8eee620b3aac721b738ef15d319878802de6b09d26e9d1b8ed9a92dcd0224563030fd800a2600b39ec116b9259a99e495636922a095bc461f5c0ac73e6480ffe73246c01876dff62b8885afd1ce70d8be410d762367e8c1e37ecc9a3203d7a1e2977dab07664cc899a0dcb46f14034bcd463d6b07c0af3733ab31d55c31ee49510b2b9298a9f86bdb44333a6e69defd1b08771b3bb1f35e2f733ac12657218fc34a4d0cdb0c5ff93097119d6f01137414d938792618f99228f9e3d86b5247aa5f20f5e618b6195942153886218d69c3a9273858f43d66058aa272d543a24ea5fd8bf53b326ae2f3f0e2fec2975f0a18fdaf7e4e8c2d6ab61cca38eb3d2c1853572ce8a9ce9f3cf16d68e83aa473f3a19d7c25a5e1ff2deac867016b68accf57f52d93158d8729c8f1f36e2858eafb0470fc3760e612b6c71d252fecc9c8ee22aac79eb42d533e7641bbb37693e9fda4c61cde829a28c460a7b6996c7cf8e743ca2b0fd84e838c3588e3214d695ba9013cd7158ca1356fdc9814e8a87aa1427acb19a9a43998dbb9526ec1f397fc62a4c584352ecd411a93fbe84f5d3775a5f5d0969252c2196baa36dc69593b097e9c6899d22614f899b661322bbd2236caa297724931a61bdb4e154c3d9cea7087bc7289d7d1dfdde4458f5e30389719e2d86b0472af92785ec943179b610c27a329b62ba62489a3c5b04610f7fa6b1c1527a649e2d80b07718c2678a2f9532cf163f583a1e8fc62392cd96670b1fec718c84e4bb88fff16cd18365eab7937804f51ecf163cd8a472e6287c75268e678b1dec6194ffcb31464e693c5be8a00e3556943ce3d922077ba9c5e0314a4388c1b3050e56ef120b3111f314cf1637583f8795541be94287670b1bec41f81462e7206746f06c518325d4724d0e3caeb4f06c4183ed72ef56a8cc60abbf186398b7850cf620498689621b2e8fc51e2c55790af182c5c062a9fef8cafcc3e5ea159be6eb10c9b8d389b862d39b10e3a520a124d28a35799465e3f5391e59b185a9b8081ae95188ad62edf471f0ebe92cc64c157bca1f55ce86aecd53b15de80c371b542c7934d4e5d38e62778a2dcfd54ac5ea10c0148bc779b02995e7caa14380522c9ac28f55968ee4e91080146bf8855cfd6c859d0e0146b169881a9f9cf818a74300512c93ce92e5f8c1470d1d028462ef389cae0deb81a7d021002816b93cf9aaa968393a04f8c49ad2f8e4deab54113a04f00491e284fccb9c4eac933ff2a07a453dcae1c49af2368488ea55f36c62bf1827aa8797dad1d7c4a69d15e268ec9cd7cfc476f1eb73caedb4e363629b601e95f57d78d35f62e98f9511693e66c72db14d4d6d848b949af14aac9e3f3c546efd2c4e89a53a59c47d687b213e896d2b879b728925d95c12abe4eff0a112f1ec8ec45e166e48acfb9bfb2a68461afb11db05cb992399d183da119b860f2a68d575cc69c4ea3df91fa7941ccdc188c583cc819a4748a71e8b5873ec20fdca3f56ee50c41aa3d365d255363912b1e5603a847c50957746c41e16630e7bbbfa473ec4d621e6a832265afcd8107b18eb7f3ecabed84d21f68f3e3d85bef0606308b17a0e520eb3f4ea1433884d3dce74c88d2096f358f9a390c6cb2e81d8faa3ac8e9ed93c0b2016eb0dcfb1cc2985e50fcb94d77e7ec50fcb06b38eb7f6db59e9c31643f2b4e081a67e940f5bee87ad0b1da6c8eb1eb64b392efcc7b4f6a17ad8abd42c55dae72846f3b098789c5a8e31e3543c2c9fc4c3f1cedba1a877582ae9fced785687d40edb05e9943f79b2ffb30ecbf8a68c9e4c3a6c156a4da4c2b2c79cc3be11635f5a0e527629876dfde632a5d08c31c661155fabdc1864ad8270d8e7343c1c4ba13fc4372c292f4bd5bbcce39c1bf6fc29ef76de903abf362c1ea4528c30b239f8d8b0c4fcb9e389f1d26d6e0d4bc784b4a1a3c4839c1a9689a9a25a88a461b1cf4df1f5351a47c31e96244ed8d4d09b33ec9b6b134334aca49819968ef2a40f42f2f865d8bfcbbc524e9bdb21c3923fba3b7f4a67fd1836fb60367f6477246258bb6bc72af2b70cc33e696922f6535e1518f664113d2aff85cd3b87d8997861aff4a1a6f35cf8e82e2cdb817ddcd86953cd856d732ab5ad8f5755fa2d6c331a53e747af85e56ecf3f3d779c9259587b3d3346eeb1b05875a75e7f85254ef08ed29d5c7edc0a9b584ccd1c07dbe3f12a2cf149f3ec73d451dca9b08ae4983a4ca9525c3e8535c2a55de8ed9c2997c27e9ea57621869c954761951c47bfd7d150587a72eee6feb2cdf4131689325ec9d3a793b41316ed9ad30a277ea96ec292c32e624ee93fec3898b04d4c222529246d792c61f520878a1a1e4ad873f2f0fc2c625fec48c212de31473a5aea0709ab770a49520efd53f8084b85059f8b1a3aa94658d5e3ce9579707b16619f9813cb47222cd2f53b9a6f3f7443d8f4632c84cd4a72b0bb710204610b39087b92524a891b270010369b9db88fb734071b27c00fc831e5abf58a0fd65c891fe41c3c42657ab0781cc710af9d68230fd6bc9642dc3ca92cb683552aff644e1d495545074b5a5ad31c5402e460c979c2e2f8efc49c1200079b97560ea9d7c3e04902dc6049b51badc3fa9b3b0960837da3a72627c618e724400d96a4b5c133acfea948001aec7f97cc32eea6a81f0166b0c8e5dcfd14161d1f0164b0fdf84cca1c5ca8d4c5628f62f0e8e3c02b434f60b1858ad156d33e5e98bc62eb403cde10a32b965c7183a5ce1c1e84b462e909b378351f8f84b062cb1da6f6e747578cac62511f4b21c845d05f157b2857d13cc4c3e4a762f9983ff8388ebf8fa362318bd0e955f153b753acb63dd1513674cccd145b7d8a890cb534b795620f39f5b337721ad948b1998e249f14f3512c397746420e97a32e17c512fc64d246e58b1fe5a158629544bbe4716e2b07c516cde3f9133fc90ff927f68d74f91f8727969ec83cbe3d1e5dc83bb1471af761acd81c97e49cd8238920db5188390a926f620f73981feddd7c9e906b621dc9393c8913a152e499583a4948f11779b93f98582b7a86a46ba9927d2eb1594769f92ec49ac7b1c41ad6f579c3ab7e3d955883c48f54b2f49f3c94583fb45bedca24f6baee183d6dcc34bd2496301de879acd2cd89c43e29f5d179a41d3920b17dca271f2d474ef3887d3a94d0716f2d1cb17d983faad9bb24a6b7168d60a7af3ed3e58c58f2d407957355dc2c625fdd8a41a76e2d14b16f5dc7942685cc711cad4522f69508d99982a9ad470776afef6a2e13cb8744c7d5e1a4bef10c269654890c31cd765d4f97583ff5784849b9e93696d8cb3fbe0fa3442cbb904aec297e39bb622d8312abc6f9503aa6744e62df3ca97298262f893d4b538e26c71c78e78f482cb533f3f5618c643a4362ed1c638fa7b2b4abde6941c623b648bd1aa161c5e2e460198e60628e03958a921320a3115bfc2cbb390ffb446e0fc860c4a6ea293d65a739a2c486174ef603198bd8e6e3f032a975483daa22564f315814c98c689ef91578818244ec71a377cc87ea1f1d6f68b9e0b081768858b2af3be70c295fb0f086960d2f5c7920e3105b4acd8ec39254ab1b62ff1ca628d6a13464ee6cc30bcf1dc828c4e2c1c6ca14b743702083104b888db1a4639d762b0bbe0b1b2ef8220c533788a54376e7380ea973914a810c416cfe7b182af0c2048c8240ac39d8a74a59fe686504c49ab7976bcb839ca00426a0aa818c3fac29e3ebc385e98616d90a6cd4a801469fe0042a70c0771744006d90e187ad4389d554e1ddd03a5ed8303390d10793cd871aa1a7bca1658690c1877d737d9c4cc5ba3c8e3cc1c1fa07197b58e2aae4aefc1b39ee7343cb0609ba40d207197ad893680cfdfd0b1764e4610bc9c88a139d29050f0fdb77bc1ce251af557937b4eeb08712cf7176e4e847b22e4a60c31f0c2f52d082b7014609f402678735cce5f58c1cf266a937b4881864d46113ebecaf93bff82a30c8a0c33a5f214ac708ba51d42a1a1b78409e0d64cc210b8f7c5b956f24e6855f85e1851719f830bca8401118c890c3d6193df88f74e4ce7c432b0e7b1436369f4395efbc022fbe48015a40061cb692de907a36c7c8dddfd00d4ce04b502ae30dab664aeb90aee37668b1fa127cb101127441461d90e106374d3c48ea9163dc5c9a1f64b461cbd9371d77da88f1d16cc83b90ff18a22e1f0687a10123c858c39e73d88a5f744e0cd1d8c0046ad470c1177c02c6820c352cb996a3cd394a1da6e3d3b0f8c68f2871a1b7311741061ab694f9df4a1d84be881422c83803e9a43cf2308b171fc830c3ea713d84cb1452da0b4d414619360bfb29e620cedf84b5c8b0a4c74cc92ca86d8e0e29c818c3d291263644ffcc20430c6bfec891c127270c5bee09ed8c29a33606196058a74cafd63ef505d3c9497864ee6e68651464786149e126857a144f4a3cc0781a1b98000d195dd853996e9c0b311e7d9847c028410617d61ecb31e9685c07195b58721ca5d9194f123776b4b0a66da47f1853d4e06b1239c8c84271bd73ca69432b640e21030bfb7ac6cec7916a4711a6c1002368907185cd37a5143ae779f76719061956582e555a4cc6889974c280ea828c2a2c1ee54a119ab192375a640b32a8b06f075a17293a8e73143285edc398939f3cc8f167dcbff0a23f03240b32a4706cbacd936814d6cd1cc6381eaa574285c21ee472aae6d190bfde1336cf93b521d407f113e2843d2f637d7c549a734a37b4de041cc621404613b6ea524d39fc7a6dce8425ca23d14c3167097b7d8e79f61d636eca51c27af22b179fb63aa89c24ec61dd21294cd6537290b0c5dc7a0813d53e45ce1196f81c46e3a324d1b7638465b7e263dcdf64a19d22ac257d6a2173435aea10618dafefea9c7a244a6708db7c103d5b5d088b6e9a4de92bd19107610f7294e91f29967a1a088ba5baed403c43f4cc0fd61ccc5688a1a348aa3e583e87162b2a9563cf1eecdb7956e427af8793074bcee9997cff734a6c075baa93caaaf82b957a1dec679e3ee473ce314d9f83d5830b323147c2843c0e56550f3d9ba36fb0c5a479a462eef8e1761936583ef3e638fe2c22855d460df628951a1a3ba87049974183f5a3ef94d2e48efa97cb98c19e2ac6eb3c5a1a23e53264b077f8bf102d6ea3a463b1d9a99a74de349ad386c5b6f2f9633409f936ed576c122b8d74e82339ce76c576c1833cad32d394752bd6d8a1c2fc5ccd8af57427548e9c77cdb38a6573a57a6912fdb857c59ee1bbe3686d836a9e8abda33bca2b1b2a96a362b34a29e4c33ec59256d5a1d4d5dfe730c5d6a13c57624205df9462cb51a72f88dc248f428ab5238fe8d8d1ae49ca318aad826c4821daf5c77a8862354d795276188a3dc530a92f836c380f144b08b1947279d0a9b34fac316dd45091173b9527160defb56421071ea2a313eb7f5c491f2611b90e27b6d39bf42054881af14d2c1323f75372686299ff94fc4ec9c4a211c343384977918289f5e3bfde940313b5285f82930e557f43b6c43ebee571f471d2091f5762ad8e91b2693296724c89fd6ea382e48fcac2c5935853ccac937c9f37c725b1d74cde76b8476299dabe183d6f72e780c47e1fa4d514d2ca5ad83c62c9515fc48f7a474b318ed8434d96251b65a757d308674fef3eca9361c4da61a89c423de8d9c82c62f5f87c345d2ccdf02b620fa119a33c44a7d827628dd8f17b1f2e67da88d8924f8a61cb3ec4d261a778963cba14db10fb86cfd166ec901d7c14628f4e337e7eeed0df10628931ef18793965963288ed73ce838aaf9e478b209694c33bd950963407298178ec3b0e20b6cd09d5917dfcb0f43f6c1634722a8d943347fb61bb32318fa3dd87a5acc74737a68e1e3e2cdb9d7462a6f3bbf7b079df0761dd8179dca1873daeb24234994ee561bf8ea73b568c183af0b0a9e55063ee3c07cb1d36c971fd6d3acf14613bac9be42c878bb028297558bf32ce58deca3b1db69c597196e61cf6cf797d3f777258a4a3c91f73a771d8c2d56898e4b375210a87ed6b25c5f247cb94d2372cb92986667cd20d48a6499d1cf26dd8f463860b13f572a66cd8238d16267c14f6e45cc39a1f55944e93c373500dfba6ce9da3a40a12b634ec51cedf3f8f162ac4120d7b94d2c34b67f93b86f20c6bf4fc551d076b49a434c39a493e8c3165ca69a22cc32667eac1ba26c3deb1367265a61cd3630c8b84c91c26c761725cc5b05ef292d4fc916f3cc3b06a4e1ea6ef4830ace9911e5e29c58fc72f2c9ba464335a8e69a217f6389e9a4c3e1b36876117564dad9fd3b40fe2845c582e3ef23855c716f6bcec389f897a5aac85e5c22a7f1ce22cecd7f9242274879882854552474e2159e6289757582f5287bef65961dd891f4279aab0c97a54ab9c984bd315800a4b0a1da75c51ba292c1ebc63f438de5cd94b614f3f36d1651ec3ed240a7b54f82849d350583f64e26c0e31875f3f61d1103e8ea72aefa2c3096bd58886142e453b983461e9503c9432d1938f214cd852e57486ad470951b284ad73524a3e5931318912d6b99c7fd359e1139224ac7b96310761e4726411246cd3abf79b74c2e5cf11f69a4c76723946583a62ecb427497ff24558535ca7646af9a38c1361cb1d436dc4699d66089b47aeab10f7424a0e212c1ec68a54fa78371284ed728cb48f2110d608bf153c3ffbc15629e58ea3f3c1de79937628958e93c47ab06aff790e5230df10311eeca1e77c17f42c65f73bd87e3e86b4d475b0848a99d77a3a93e4c8c141887e41e2c3e0608f3942da90266fdc3758737d94c30d2b1291da60b1bbda52df4ffbb1069ba61a5999d2283a0df6d815acfbbc2ac00cb63c314f9fa254a7ae0a20833d2f774892fc51d8a462b1452cf1c03ab08c1452b0d82a644f6fb27ac5be216c5cb2cb77da71c5961b7b2b72bc21436fc51696c3e930a9f768cd8a2d6eea94e59ca61e5ec57a963aae547af87856c51a1be2e4afb421563815eb6c4ce9a5cbf8dda062eddac98ed8d341d49c6233ff1c2da2cfc6a4986209729be14ac4a3afa558c2e75baf9c781fada4d833e5e5a8f721634847b19ce8a9871e14c59a52e221c42e5f1c8a6d24789c3ed1415640b16f47da933a4ccd21f2897d52a7a4f531f643e6892f627462a90e54a337ece483184eecfdbfe9542f54f87536b14d4e1e21954c3c25ae89ad520e5357dc289bd964628d38177b9b3398d85762d5474992450c974b2cb19192e3f8728a99a325f64c152a126782af7595584334354ece15dfa8c24a0dc4a0c49e2ebe63471da51ce73f893d8e4ea322a7ec38e996c47a33151f7448de51e488c456f5d151992e90d8a3be1482a6203791e3114b25098fc34bdf71601d29c4115b9ec4d5a98dca19c346ec7147b510f5a1cff243da1083115be7c833222f6ec5a3166159b4141982d98a3843e78f3697671241f08c143e48f228fd0411eba6cb8c265bc9d2e58738523f9f5c9189baded07216d8b8fae2539002fea20386d83bcfa75edc9029c41a964b2fed6263629886093108b1872629c4b0b1bb73c774083106b185cb5f6bb1790a218620f6b3a4a5d2e3b116244863030fe8c28b1330a0468defc28b13f0204620f65f4d9a3fd44c918e6e6881114617681e8801886d7444ea833041b3408c3f2c1fdadc75d2e839bf0283a020861f16cdb9e338fc99fab0c46456108fd01ffc2e2c50a346175e940000a688c18755fa37247d62081672ec61b10f23fa471e47f46962e8618f03cfdbe9918e69466210230f4bfe0f2b35e579fc7a6ff5821878d83a4dfc4c31cf5cd610e30e7b5c5788ff9c25911e8b6187b4cce328afc25787430d71923627ef63a482187458ce3c5e0fec6331e6b0c7f192a44cf197e33b2a0431e4b076cad89d7772c24331e2b0c58ff3aa93581d668e1a3552d0841870583a8eaaa62184891962bc61896813d4376d45325686186ed8e6e3bd8b392b43254f1b16891d59e5449a0d6c7c6466a959af61091669753bfcbff461d4b046953829f32b7db42f0d7b94ce99737d373c1e0d4b748cb078ffa3926267d8430709b71f21a8de64508861863f85b2f8aed83801775182f30008bc046ad470c19b000d31cab05814f55c49ac43b01430c420c3fe1571b61e5431c6b0873badcb41bc20bfdd0dad0fc38b2eaa683080c6176174f12bd81a358a013468695c600234d40931c4b076e9a49029b34bc3995f881186a5f2fe3b488709be601478210618b60e9f8d310a6cd8380c180aa82f902a532aa64608d19c275c8e53f270991b5a54e882f36f3588e185652b25dfb30fedb7a30b7b382313ef72b663dcf684185c582d858b51caca1b5a2420154f5843f4e0d1770e76c23eb6c92c35fd07f9334d58a27c7498e38ef2e3334cd8aa2e4769924687ee284b582aa5987af01f24068b12d6da0f890d8f61395792b064fa9495ecee227414096bfa5add541f84aebc1e61b550b12433ab11f6fe709342988a5a5f16614d1f2476cabc3e932011d6fb99ab94d941e4794358424ab91f78187310732784c57363ced519bc4fba202cf91d5eaecbcfe1e804084b8e20b71a43e4075b8af5fbfec8725c7cb07c8f4729bac773a6d683f5424382cda7d457f360c990b81ffa7c9e936b076be78e2b524755534507cbc5dc10bf63e8f3e460cfa49ef35f69340607cbc7c58a72661725121806b841d12aa4301629ef6d001bd8719833167bfc3bce6bb0260f8b1c07fa03e00806a0011f3a0eea72d646ae3e6080192c1783872178e707639214a4806bd4f883bd30800c4c31eb715d100ceb772f1850100c0d98d4586cb651f4831c713ab4302cd6c939dd785dcc0e6a7fc51ee37d949acee72333ae5872b8b231a7e9f9f2b2157b64e21f244ea4943c8c157bbacf98723e6b17fb2af69c43c7518e23358741a38afd3e0779c92a537e1ca958cb22ff04bd38251a44c5965243a60ee98f99bb536c194e53b42a72c81ca6d83c0e6bd2c7a1a414fbc79c5bff2122a637c248c17b0b669062c9e51fe5287e8ca79aa358324dce8a29bd19a258eec38fa169a3297d704628f628a8ece72cdfec298da06046216bd11717ac6a80bd1b7e622b8f11e542f49e5872ca8bd11caea9c9de892dce6fec7c65d341554e6cb55731c5142f1a1b7880073641fc4fbe1cdd0dadbc199a38570711ddf5b073c632b15dd2ad5c63f127e577436f80c11060c0021a50a3c6e19a7c98810932724a2be91ce9c446b1a2b18109d00003ef0f332eb19a441bdbd828b1ebbca1d502a680033240a3cc12e5fca7ea0d2de240182af0c2053c811a35bef82f6ad438dcaa8a30a3126bf8b499a386957c277b61bebbb00025d6de4c3947dc968741a3b18107d070800a5040c30119a051a3468d1a60ec60c624d6dd107e153722736649ac1f887dfe8f35126b329fda8f3a6a4e2184c46a217e869ecce73874331ec17f6df8e49563853dc3117bc7699662dd479ea51bb1ed77fe55d9944b3d8cd8ab039dcfd9d4d1fdba88a5efb43c54c494d324672862190b4d1bd7774f4623c48c442c31e38ce66ce7389a1a116b7df81799e29b7188cdb33c9345ecb0aa39cc30c42a7abf751153420c9951883dd8ac7837153ce2771062d35de9da4db151fe044709c0f8e257f0193053cc18c43a316f7d4e7d96563682d89286580c65c940ac390c1e3bae921409be5080045cf0120083216056455ffc0d3038035089198058c452c26e8835e330e30f7b8716c62c674d37ccf0c31e9d761a95f3f3a5ae0f6b8a9223c44d7a76e8f36189e83869086973cc71341c66ec61f5d09cbe52d87ad8673fd5f97455f2a05efc4adedc693cac1b22a6eeec384821c38c3b2c51f52a07ef303aa753ecb0440f3cf7f67f9e9447a9c31e84dc04fde062e7af143ad04105ad78e1786c8860c61cd6ad914eff38f09a1cbba1557a98218745264df607591e3373c387197158fd2ffd8fa408e3b1d18517a422d08505ec30030e6b489d8c9df28268c77143eb4fe025b0d185174a63030ff8e29d1f027f028f40171638c38cc3bc639e76bf1a00f630c30d8be72869d849d98af3571b16f59024e58ea6912f26d9b057ae0c29af3a4230630d5bf02b13fb1c25a81ccc50c3f611cd24ff33e5e077c19bc046661a16bfa8e971b01816e25b00843003db98732687d00f9a61c619b6983ef4ae104b185e70a0460d34c3be6b617ab61b39f0482ccc28c3bae69be6234363e6822fc22856831964d83ecde5ad8ea3ee63c3055f8461a53a98318665cefae31cec3be45fb30d33c4b068d94ddc584a9ef8a71a6684618f1eaa9ac75c7d3861306c29aa6f731c6a8514ff2f6c29ebb42c743a5586d830c30b9b8de9040f8367e6ed5dd853481c9bcefebe1c576998c1853d463e0d3aa7c937675b58c3f73eff271b15bb90d3c2fad97d5162c54fb8f8b2b084e9d4661af5b230030b6b55f02dd51c532dda37665c614db124792fc244ed48ab00086cd89861853d6a0c76c9b2acc2964378b2e94c6655610615d6f260f919af327956900a33a6b0c434192a2b4dea0933a4b0d9e43858f930757ff870c28c282ce73955c8e951cc18664061d5f228cfb3dbdf4fd513f6ad53994b1f871336b3bc1da5e0c1237a601356099e224eca27dbd989610613e8fc1f7d8544bd84453b3d77ce41471f5f4b7d618612b6185da353757653719e91843dfbab238f571e988184a5a3f45517562e2a1784d1850abc386c90e160c611b618334dc14b721ca77343cb051f06ff176d8ac6061e9036c3087bd82761923b2ebb528ab08c678da50aafab10835398418435b29344ebb0a5296e5298318435247fc721a5d334618610f6c87f72d8891e8ec62e089baaa491cef18d850c4b18660061a93dad1f95fc4144a67861c60fd6958db1eaf8a59d333e587283450e3ef07bb077b28ae8a9926098c1032fa27684cc29b383cd3f476d7e9ab01d36edc20c1d2c7271391ed7a1755a47302307dbe7782c871f3c9eaca6033370b0fe65e60e3a6be952888d0f4305fd2d781b5eb85a0f66dc609dc81fc6b5347531c741024e818d1470a1c10c1bac5db936c4c95309f5ddb0910214a8e0d01935d82279dc8e21a41b5adf24c92a00021b309841832d79a68bd224a94bd253cc98c11ec683e6c04cb26182fe1b7db63364508f6f6eec1c875706082e62b167a974e491d6836f0e1637f7bf3ffc8a352207fe65193a6fc871c59e43f2abda1fcb909d566c1512624ea384fb9a157b8dfa6a5dfdabd83e7498fa97ebd3e778552c313ff55da4a95853b8492147e2ea0551b186cee936379c8718fe29f6a82b67bacb7899d59b62ed6817ef36c578b24bb1870d9972dec6fea021c5967ffefe83884c4a7c145b65e8fea8c390731ce6a258e36e1e8aed3366d607e371e05150ec11d5248647c827d6ed28223ae5c7617fed89c5a3c7e18e688af7b1eec45ea57aa7b1c389bd36a5ced146dc47c726b68f949286ccb952746862adcb19834df020ef9989c5f36cea0ba212721e985824565c4ea62eb146ce761c5fded9d16189c537850d6679963eb8127b976ed45c2625b6bbb4e1c6e4d2e5289ec452f123f32aefe0428825b17ad09d8ab92f05f33091d8d23c84f94da729870d2436c9c9bde0339a432a8fd8ee74d7039d89ec5075c412c7d64c73237e68b2115b4e5165c46251453b527f4cdd8bd8734e2b12f3a1883585ca133488ea6c9c89584b4f4534928988b5c39c1feb234941a73cc41a83e45ebb18616d37c4767d1353e62bc4a2b9924d4a8e59f090109b47a60e26759c52ee7010db590a1f6b193aee090a62898fdc193111534c30104bc7be9c103f454d3f20b60a25b172c8f6e7f0fd618b97692307cbd71116177ed803fd8f4f91d563f1f56151c99eb4a95197e7f1618ffc1172dcd071d4e3ed61a9b5501decda75f8133dac1e51495543f2b0e7099551b6be93ad78587b7b2d4255abc279877deec2e4f00f7e63d00eabce6abc8951c53445eab0a6e75056c4373ca3745822e5d88cd123c7c439ec611cd3fd0c1dca7572d862c8b5f5189b732216877da723d56b2ae61c071cf6fe9cbfb7c6c393e50dab888de5386f785099322be0c20dcb7818647c2a4ea850b521cbef7836ac763988e9612eadbfd7b0e6082be94836a41854c3369f22871f72ec145a1a168f1e8378baad8a161ab69f924c75f92c264467d832a61c472a99002eccb0d9ec798a3f291bf229c35a96e2e7c48f43863d0e939f438e53be099d312cc1a642c7711cf89cf562d8cce3d566863d0cfbc64713d31d574cce01067d2fff65559554d0035c7c61f3940f7bf1f7e3147d8d1a360ae7c08517b6f0b0be7c9a27e588766195f455b123c9b91e3d2e6cc97c379ee5f2d1b86d61ddf3ab4f93498b91d2c27ea9a23fc8e871ae0b6561cf281e5caace18a27860618f42f8770e6da4a6e40b48818b2b6c297d3ba70d6921d9b1c26af9a4b783302d09952aec993e8e3ba81863f29ca8b045c8f827bd9621848e292c1952c8b429ce87969114d6cdda8c3e391b226178e1c51736fe0426f8e2bf08a3701185fdd2e78efe4da11589041750d8d265b00e57e93c0adf0d2defe2cbb878c2165b31c5d4556cf2980a70e1843d7798f1c8f2838c8769c21629d7f258a7fe60160a70c184fdca827d702b1db71d13e06209dbe608173b5f3379d337b46c8001c6b7175fa4a01c2e94b077781f74decaddd0b2f18517c70631e62209eb4ab21ce27a45da8cded0325516022e90b07d899e69c5cc8c474c52818b23ec519fae4f941034624b27706184a5d3e7e0c2fc449209a96c54725184adc33c7f6feeb820c29672048dd5141de44f65808b21ec1dfafe88e77734a123842526a956e8b08fe341d8e330773d6d252cf0a20b13d800a304c9062e80b08a55d567ca3015c1f3834d6255881cfa47fa61870fb69c2fe8e475481139f760fffada1c95e491aa70c183cd729ce38cbf9dba2a390bd060000d030303a0062e76b0cae4207f24172f7eda74b0858e73f01d6fc86ed858818b1c6c1e965ee5c5d11c2a9455e0020746f1cc1d7798732014b8b8c1964f2f7d68927e021736d837495d74474f0df6cae990215cf798c70020031734d8a2f444b09cf261e062065b8eb34e3b8fa3dbb890c1f64192ad8769a34cce118bf53b278d9b9a9824232c96d095c9e2989ec47c5eb1d6d64aaaf5d415cb47a92ae57c722bd62c1d8bd29f4f772dac58fbe32066e4bf8a257e267c3c1f7f393d552cea917948f9a1546ca271b996fe1721d4a858d3729c6e2d89ee76f4144bb2b493bf974f242aa6582d74e8d1d84ffdf8a5d86a73943e8f0719627d90628f3b2eab8c39ce41687014fb4824a9c8f7eb277951ecb9520cd50e443f4e7928d690c3c8a991eb227e1e145bfe90aa37c4931c3afa8935a9dae79c8eaa234d3cb16f88389352504dcd9f4e1cb224574db28d137bb4ab1a43ba2b593437b1e7ca53311f598e2f464d6ca31e79851e8b7da8440b4522c241619148280c86036160d85aef0123160800102c280c46a2248ac3acce07140002492424321e1e121818121010120e0c0a0c080808040c0c080484c1603020100a8491085e4944eb019ddd69d34b19814360210c13ba84968230a178117af6a658bc8052f02cdc0864057761111666b340b22bad10d3a83d581061432582669457230f2de0020bcb408bca9a6e7ef2d1e115bf618f164ea2eb898f4b095d07bb6057c9edc19caa1e62481c5c99f9d34540afd159eb221cf158af9472bcc5e03e40ac075c2bf97d01fa855203fca9a7f2a94bb82885e56cd8c40e4567a5bdc622411cf899f6213a98d0caab082edcdf5528dd3e1b9157d3988e83a3478fc6246f604fb2cc00a7e1ab854797922fc3c9e0fe4c159e4d6743a7cf2837158eaf8ca68992383ece1eb6783d1adf9e7be0b7f3389e7fc5b4410895f13e80e07c7612c42627362c7c6a44a6b9daed125b063d012a4f91f116d4c4b7a3a3fa0bca06b87611e7bce910aec498f6f3b7ca30eb6b12adefaa684728bb3d10e4e6dab5f539052f089cbe9de8a89b655adadb84874c251c5f20af6bc87a3193ab4f8788ba8c6f479fa7dbbcbac48c2c0f0133456f612259e2f6b6145688bd5a2b4dd8c02d78019cc250efda0aef4b3f8c405bf5d659981282eb2d06bb0393f30b7a35416c1baeada227a12646df173bf39122dc4b0c139d131188a0e70e3ec7f1a178ba4b1ee2af287319bd52cb0449bd24f4c19a016dfbce77c7eded9f0e03278bdd0dd592503987506318d10e5314d1e99b84179937079ba496b70020ac47ff9e34f44303fad1965030483ffa3811c30151a5e600c89bb67fa10bdd004c2d7f205b0135bc8f7ea02ec5952579f8caa777881a48098071a47aacee597a0f345f1466fd0d4e239100dc9403f7732b4297412a4edddcb28f6b5b371591a7e2537b6777fadec55db9e39bd3d045eda5e869054e51614e629c0d6adb0558f0ab808dbabd2cda78a33f97790c4f76a7d954bd4acb332cef341d5c259e606a2553256e050367092263176c943632a631fe8d9ebd329369e64aa8360341354a0bbb150b584724932a91145663822d799eb38a3e2d8a893cf0819d24dbefa0f051c27a339f96df160aa17a235027ccde6e23bc0ed83e262ed6a026a11c1fb07d186e24fdcdcedfff47ca5b0cc6f628fe93a05999442139b33c1f212a148294668196528b1c8020584c29b555499a9cdbfbe96fc00b7674a329b5f70359b7e1a57528b6fee113c132f0f1d9c7a0327409571a28413fa654d682a8d689af7bb86d5117ecd0dfef7e5158ea8e007d73f5f9363d895e732aa19025c3c7e7ad8247bcaf024ed7c6d58e69d313719f823d22b3afbd53c789d858be2020847fada22bcc8b511a3ebdfc8626e1ec4060fd3854c2ac1c8bc9e518c13c6228c6199a44bcfcd79b473f6eb9b8c089b25e6f5cbc2e3c83dc5c1ec26a3d1a7ac7bbc6176911e7ccc2849bc0bc24f50f6d1ad6fc6e5d04e831a5eec6f21acd7ac0273d4cacf2b02eff73c13b62952b5d9bc02f0c99e6fd3459ce453c91b8b656a5f15d712e7f5ea0c097f5d9e3014cb2c16108656b782ac5a64d37d89995330acd1e9546b94ef8576a489751f7896cc15c5e0d532fe420addb0b896814af865138459c9cc17c968424fc270fde26d6259aeb9b2db75b739c7d9027f1baba16f29b4dfb2caad78f394f0a2e684609842db1c37cfcb8c766efcf33ea5b76318b68e501bd63fa77188bab5018c6caedd8d71171e4d7fc59af801345168e68e6c06d5aaec7cab5e83343bd6fa8e17191f0d263c21aadf53e470b15fd42313d4b493a7e646e2e7d67f125ef1f3cc09bd72e3ec18937db50102efa90d34301c4ce07b2debe745f441aed463b66c57215d64e08f88f341653c4244cfc51a5e8386396ec40df89dbe96b280cc6fd0a21c072bae607cc3d874542ca223e50f06b960e4c79652bc3eee8fff88dc00dc4f194529232028d9d50950350b89bdad642452e98fd2cf7a93261c2d28b2213b3737215f97dfe9ed82dfe7fee3ec4d54cab73b5311bee08c0c1b2a7021ee5f3d8e6a11c8f39caf15ac5c1e36da41788e08d17177b10cf742635b5b5d8164e836abc1d6d756fdb23ab68f5ef501ab5e8490a91c238f7e8193d5b2ac238da864d1f8242485f51fd48942f320066e90eed5c9443d4c08c55b39f4d30e5f33ceedda673f1a4826be78335547d1e870d8020265ffed6e00b9508a4f18960447c6f9b069323a6a275995c196fd9ac504337313609dc34073ead99878dcb0db2d14f2fbb82299955d39b49a4a3ebe5dbc39d69462472184940ef20e991a93482c827b35cb64a40857a69a1136e1910d14a657253d5d1212e25c56a207e9b9ae1fe5ffd7c25f1b753f21dbf8757a7aa9c10d80beaed6192a6922141a5e1d37e65d9dbd7c3388de8c04456578fd40ba82302c3ddb633401212fd570d3d69d1630a93f29082b06131a68279910248b1f9085ab287144b7faa1d2ab8b9c949d3d25a8e471b7eed14ef42705b94df35814311c4c741d1cabc6d9b84b09e2f6754d9f0c57c8581df8e897e7d6ebcbc32f180eef8bc474d238f0ff9900a0e0d5ef2a4ce748bf6675a807a82aa6a8fce57dff310bb634ff2f93d9327192a68ebf1e018736a11fed424a7ad6ef0dcda56d6280396bf66c28cea147d6ac158c710b1a151c2586d44b386becefad7244af7456b49526a354f2a7cda04cac3174cb29f595bbb94c12dc7a92a5952652b92da609b85c7ed4b886d6d6d7937f41ae84f06fa486c7355997e674de464915236d658f88568ac661aae86b2469b730b1aca32823c522be7e57a8ab2532bd42c7794e0241d2314ff7d45ea5aa7b42833a391095ab8c62547f8700f620366a8532d3e0c02289774c8ec3cd942b29d72519aa475e7dd03a4b52a4ca83464c495e59dfa5c2422429d1b27b809705f04a9d85c73bbc6514236d7f85e7fc4dc839207fe4fc8477ac6be0c338696d7ad6b705a5a3b33da98d463ad20d15a652f3bb738029e8a460a197a715f2d6bd2d272cfcb813424449596d9001a2431a21a1f629d56feffc4e992fa479058bb32c6f6a59d7310a9e720f3025cda2d32213fb7c56628b8ae5240e10dbd31d8d1834e035ff744cb4013324d91c271dd9aadc46adbcb9a59699675700ebeffe8660a3befe1a10080f56f6336c49b8ca5e7d484b7002032756c63160e173b250fa1f6c94cea2145b578d216ebb1f3d0a67e4f08dad5bdecca7de1c5e4307fe2addb0e1ff88d91c43d1cd574a71b0a114b864d4940085935a9814935b04144267e122f2df014def1e7f193dcbc1b9e930bc94dd9d3db6dce683c51ee58200eed444da7e426f55425b0844db245a5d197c467e4ace55704cb907d5e09c54a7ff6593ca5471ce47d8fef65d909e71b1271b6794dd5749f11a751c1414fe9064b0376f26e1ab6cc32b0545fda50bdf0d3dc10aa21ed9250e56127015fb86e6414be72aa4aee50196fb432f4f3cd450b2d2a6033fe5ca1ea727cd110f8d5cd21261ca4fa09946822a1b6ee15803632e8dfe07e49ca2eee46c338f9c8b8168c602c899444b110808193b999b86926be55b506de6a940e8708d168fd14a41d2c6684224921baa891b5b3b084adbfd3be611d7248fcee062e100357fd141354b2723c438001e88bf14c99dd387c44396831e48e2cebb399d70f92518281a08deffd76ccb6b3e6010d03bd4749fe90811f894022d12eec566f6efad4057293d7125bc0b70aca847d6e6a1c38c5ab54ab5122e53505dc230cbb2739b9d1396e900006b5cebd0ed3462c66faccd5e787810fa0eefd1959159932d28b5f82a2a2d13f25128a6061aa5f97a2e0a4ea2de53a0d8e34a5e5ac15238ea9bdd3e48b4f865211cad58bd68c9730747bd17c87c8086d52588cf8427d4fb7c2fc921425bbb5b0c64b1f7c419c7dfde6312a4147550a98cf49b0f7da7bb67b9da496e6f58bbf5a2fa8255eb492b178a68c89e112e51888824a5fe415c41b6e526e2fb912243b602ccdb17a5d8ad504bd3b417a3af9593d3f49347a6b143817987e8241d49cc32808fb100301c2c4c54bd73c9f49f58da6b16650d93559df116121cc42e7612adb207ffa3bd3859de2a7412066f6e1e75ce217404a806316e1ba2a789904a2482d1082776cf1db764d62bec6038d2ee299e7385ea33452dab2b943ab2a210f8017ebabed48025c2cb98663b561c6403b2eac7ff9c1d1e2cf15b2524e9413c12695dc8cb1c67503d5466113c7f683c1c33a7dc9b3da570ada0e6645220cc67fed1341167d2de809d280708b4e1f2d9b82b147f118a62ea9edeb6e2a5b8abdabe86e94e1e9876cb263b7df8d0ef54bcf12f1aa58eceaf4931090b57638edacb6f37177091e66d329cdb6762976a3b5e36e678ddd3f7658623727e7c9585ec7ee0fbb16d84d39f35c1b8546ad033f7937bf5d6f5aa583a6a75beabd83c33dcad18e9bd28718c509839880c524be5bf061fc0e504eb7dcbc39d77b4b8a6850e2898b894a747bb7a3c08b53d8acf3e2909d00b646ffd0a51817b1757929fa703b68e61f1dfbd2dbc0ac4343a00e189fba82cae152a61717cfabc30a0341e9e69cf4e3557b6c3a621bad05ca508a612cf4f22b6632f577a5451340e6085cbd091a059172d9e69e7cd98a5a1dfe97aac815a06204e9f4c612a1dcd030d07f022289f1497158afd531483cb7363df31ec639151d4f692fe458b0b180557fb4c3ed6d4c6839cecc6a31d4b8f4e9f4208aa2268218c1be3f2101c82636c2c3622a2b9c90e67a442bd63bae0c9b51414391b784edbbbd6af1a840ac12208b2f3b97504a7fbaf8369995648306c154f3e20947a03add1c645bcc5ce5eefa5eebd3161b8ae046294709bf222cd2502ce8591a8186f57a709047292165ee28b0b0e1711022988ffc6a0a6a9d825f12086b908086294fc480bdaab438d1167a71a7b68da6b53ae50fd985abc09e2c8885ac2dc1c412c81c7c738bb68a800ba59e65a8b209ab68b4b9a97a242a2ccfdad6e0176b49ea50c74f462550adf65697539e0003d16ef6063f5dc526601574c89663d0755839cd78beed0dbe94b77021ba37a5a6b2770bf9b9c0f2e331def1bfbcb3038f1d7d87b7541b1a110c1498689f7b925260389e3749b82f927adee849df571e57e363e5cd4fae870819557a351835313f14be1ee6f4197323f66d9174824349d4f8df2ac59814c30e2eacc1a6d0c664b3ea320534c868c847e9a9bdcc51aaa3465a314c9c56d3ad0e13d37780a1a484e37732f13ca5c48d153361069c2821587e9b30cb376e8ace6f50562c85416ee0761a9e648dc0f4277d674d725dd600ac3501a8fe268ac57d398f4c8722e180faece5452e61a60f32c80765edaf8ab3d0dbe46a0728521bc499ddfb7d782b4bd9b4efedf0f459805a37de144845e35619e78fc3ce8e0767ab6236a9a5e3d2af2949e547aaa796c08223f211a6d20a2f36d25544f9820ed1800f5549a399608e66bacd7955e4afba7a4d45c11e95bba0291e12dae0539f4c36a2921ef29e629da72e5412053b71b19f7f28bd9f2627ad034a93c844b6fc46e5b108117be4f9a08919c04821b9787322ae120522e4326f2dcc18168725dda1eadfdc7cd9d17847a636c8ae7dc52560124bdab927f4e7461b27cf7e448a1740b83b1f2f9585cf906527b9eb25c526c62ac2104abcaec81a166b0b4cc21367f63c728b636a307433a465f46d15d3c73c203a81386ee27533744ca82d8e00f53b4a08dfbc791a25be606923d05f51687cb617d68e23f52aba08963c93ccc5818abb918970ab35dd9deae1485ab0283494ade04e8623c33deece58a8d7e12e648213314caf23ba70bcd5467b72567399a57219b107b7ac3a1be83d473fb4b5f2d5276d2f50605efd0d2cb9441b2b04a367ffe9d119c14f1fcdf33c091a35344f1fbf3d5c5b8b45026bf75a8d6c57df4a0789ae5e93297d0d1756fba25df114041530aaba87a69a1082e95cef1e053cb905da12e8afa2615087d1f969014259251ef5b21d76b3617933b344f47cc57464d9403909d706d20014b4fb4b53729d62134c32e8925246255906a8733a325c30c922b2ae852227302125dd6e52e1eef9ffc6f00c350f9abad76ce9cb8234b4a65c4253b5cac79d7cd39d6d694d7b6ddb62bb4b2ada99abec8f4ab9484afa06328521ce0158f04232a4a72dbd9cdec67385b076811b5e44c33b646187b2d58bc6579f4b4a4d55bb35e82f6b431b56588e2cb13894019b748283ebede90e6e15d04e4a4339725d9583ab8213588957043487c7b352fc379999b22d2b96632cce2ee8fabd6845ba04b136e321b5fa37d9acdaa19a7a457e3dfb62c2923437d99b25178dee1bf264ce19401bab7e7f6583cfd90e68ac493149606dee5f801f838fa9323657ed695b9247e0ea1732e80d6f9d56929a8eba515c3515b570dd6515ed684de94afb636b9b230bdaa342f4e698a6c40b8e9e3a957872adf463e3550c7b13aaf616335334b0f43a7c83ac7168e913065924dbcd421c749d655a38531742197e6f664270b0b996cea7962c4a4fabca1177e52ceff87975e2a5a46be6f5db89ec0e58ad7fcc4131804b9e9ed0b1bd5e9199d64d3392d99bc41fcfeafdaeee32870be730dfc9bf534313311cb07864b586b00f86bcc752fa6a1e518cf5d7ddf08577bcc83daf7bed9b6ffda27ef7bc91c792c9b0f01fde40e2d91238d887990e38a81d050c64378295e873f055ea89f38acb8fd802e9b0131f44554255e2d4109914947ac95d7dab21b5c22a76e1b1cc3a84ae379f2b4521ab202adfd6d351a623335de74cdaf1d9f84e17f2d464e3f6bf6561f492118548dc5e0d52c1d59cea63411892a6e2629d7142ecb0488ab035b9e1e33779dd36a5314bf04a1816776a75e4696d30002414cdb5159219a443201328fd305cd7763ec5bc1f028c438ca069292484fa6d48547b5fe7391f26d3d9442cc9261a3bd1b78bc04933b8e9df6f5c00aa296c8a19ed425904f50bb49272bd3f5aca3eb6d3de3e85e4f1fd44cc314c7fd86213d41799d1d3350c180ba383bbe738e597cfc81757ba180ce554fa6f138d8a2864de09e747a011f1e3e8375de9f184d4982f75ab4fca6c4df7bebf708cc63256ca9a56e6d5e9f054befb954529d0b75516a08c571969748291e87bb01889ab2423255ecd664fa20308e9c65dd967c14967a530c42119586d434609f30e155cdd73ada3d5bb2e78d97e1303764e5abd583a48a7244f3912fe2558d52b29f4dbff1a4a443b7f259bf5ac5578202abe3945865b67ac416565000838d684ffcb873e0668c3c590f76c9c5f1e0b0437a12df2c98e967b17a34883605b90a16372dc2fa9be87b8390a0a342ac96ec4ac1ad11a55de49f76ba3145d115acee21c1995bafd76ee53c9aa1ce3291ab8d0a6e945e02521996824ecf0001e73382d151a1450b299deafb5b50bfdbede2c94e416f59fe14a7807feed2900d70b91619a6b0310faedb4b7e31446501ede4ba3a43f67212668a3e5f4fd00554c0397c6311b6c389c5aa304e87dbae5fff296ebe21368b2dc6cbb6402b80bb3bbfb5573ee1e3791d28337a70f63f4f23bf31b7c7550e9a1b98091da2284d41f58ca9555fe96dceb264aa127a277f84385165d4a4baaebdd825cb8a475b182407a64ecafba2009457f9035b144c63f103227220dfa2fca328542b128bd0cfab0e967eb715e5c8b877e63b09be77837343eae443f47ea31e3b6e37fe0676670a024d5dbe233dff2a2d964c7250db7241bf2dc8c59b79e46738f792beda1e8111b97ac271a575861075fbbc8ef97e6f802fad360fc528b42b5d8a42bd9c1af8ad47e6a9895964f2655f3d477c8cadd35bc403fe3e069c713ffa28d2e9d087956c4c14816ea4cb8e1d142c29870898c514873fa461e8a3f7ce1bd94f80398858612c9de07d0fa45bb81b86fe6728a93aaa878da7233d5631112adf055ff3e180164b3940f7ee67748ba1fa02a194c6a83718b4dc8fd3793ff0599f5a587ef99e189a53d077528f11295517b768e2a074e8a6a2f58128166870c88c5ae816e683fc66ae7fef88543e643217aa752165b6ae016f40bd16d25605a298f3e4cba6a279704fec0a3ea1acc9f0889eb7e85575b176ba4fe9629ade38d57451b0f76e10d6b9d11ad9dbc3fdc5ac7cca4595fcf92d9ea88b540ab51fbee3467b755e3806a88c243eb522bb560441959957acf795019e520732660b42269a9a01d501102face3cc3c4c29c7ca3f11081853321896937beab2092b24db87c47345f6ab886a3eaa1b714e8754975ca69c55c8a52ae172d33ad30e4c3e96354d5a315f8bb8de58ef4262a83d2b605fd91d713a45930d6b10e5efb55dd52c6cd0089a46da6f47bb6ae12e5a2e4726133b0d4bb63c398acf085d267f99cc3f4adcbeb35482ad4f799bf3e6f8a5537e0a10c388fc8f633bc663072424a5a7d4a9554195733c3e26c433d2b942d76aa9a3f1582ca502514963845a269f47aa4e0be216a1c353cfaa0b42cfe7b5f8bacd09463773cf15003b4028398af4407e4b0cd15e0841289924426712962e284894a7ac54b5104106b176e1ac9194279ad480293ae714a1f3c481a006d000c4dd88928d94fcb443ed41e5e2626d4f86c37ad43d3c172ab712c64e382634d7ced06542f20ae74ee74149654e0b4394af5d96feca7b587e855fa65833c2bc1e4184ea3e4aa1aef1b6b518deac67118f4235cbea5880dcdd818718dee1bf31bc3618ce25a8be4957e15abfa137102f943fb161e997b13838c606175c2431a79103f75f808a8646a24e5c75afa342dfd8309519463cf20e40c38851c5721ae819e88b6c309abe756642e23079ee75f44a91e14a5355c8f42ce2fe5db692be50c54234c723a94965b8ecc527c6a5dfb9478d4f8e53ff5950750611a2525f510469405a4ab36d6039d0c7275fcd550d65e38d5012c30a6c9e88dec3b25290a6fb7071a574189c8071d4762e1aa048c8cf43f8afaa7d75ee783c3ff3ba8a7928ecc806710b396194c3a8b1ca900809182ffb18931d59b9097ff957e19c70294f9832a660e925e701875f4c0d2ac259e286476f1d5b7dc45b60af6ba8183ce086f51d68ebb1c44ae0fa5e03433e670f47d0b23c618f10cccb0da0a91753f70da02490acd90ac350976a239c6713df1d94ffcf781578e519c69c871d519795e1d72fafd392cfda747cdac42a1a322cd4d4fee034d3592a3cd3bc4a9e31e83eceb3a7d78e621cc31c53428c854566f904a12faa31e85a088b574171990e1c92637461c23bccb45b242e509a23fdb0cd34e7e3ca3cc339c0989032808896e3ce3b2cb2fbaf18ae72e3be0d273fc952727a859113313f3dad34c4defd8bb2e7be8d6c3ae3deb84c23e60f2edd381c3ddf05ab244da72c14e7ee6cee7af7df9e28b0f358398795437b17ba7bde3f2976fbffcf8db47394b36d71f000c06719598cfa20e374c0cfd969b29f1f9acad80f8b1d32f645cb0c3eeabc85e545455628e549082b8179f8f3e9dc4996b9db9fdd9a73f7cdb596b376e9d84bcffd0850f5c915d2b731e0c38ee598b0ec4315c18093a1694128345a5a61ba0be0b879691293efef2871a6d5c9312fd8a471e93224e473e0533033226852c64928eac14529ac00547590671c0a2109c7ae3e4c6314772eee71f7ecb32b30e51d402a78a18aa115205314bac131a714a85b0f427a5ba7b2f5df4903c336c8715a6e7302f768ca35341293a0f30931614edb281f1e95a55ec3dd7a74c3a7bb4c397982ea58adc77ee3517dc76fb854ebe76dc3be73f7ef9d5a7bf7cf40bd7929dcf3aaf6f976257164f0433b333064cb25079648b0d038f3e89e1661ae07c8dd73e79674288421b4a2835ebb168b3ad39633e8435c5984119d304e9982d8deaf1c790204c91b8a668550a6a951a43a66b5b63610f64cf1416e73cedb11b0fb8fbec23dfbef6e9ab0f4783a4e4d34009a6f33fda9f99f4fa50bff69203b798775539b2f64194f04112dd8959c54882cb0cc640a722fdaab083e17dbb7b28fab9199c8629313f4bcaf17472fb988e584eab41801be278a19f2c2e072a49dd18df4ea9fc81aa256ecec14d3a4b936887f8fc8a93d53393fb7a9b7fbdbb87d942a059d2ee5818cecaacda34d414c99772609adc58e74f75fa39a631de74039a71ec069d5d92c654f58611a5885098c0ea4c8c535e11a8a53f49578e7d150703033041966542dfae77dcc6a95f7cf5d956bef8c160acfe2276594e6b0f7b285a85651a222e2a4fb48d6c01460aaedf1ed7576404112a77bb5706d6ba224b4795a8718c399a5a5a54e2de0aa73039a9317129631e428c204c85d307db533110eaa20b52b74606ad676ef143c8e1125aed2a4515c3ac78967e04624459d2de2254256b5ec42a4cde4811c7b963426a2e96639dbc7de4e34fbd61dc997545731a121fbad35c6931eab823e5a562a29ac0c471ada895fa38de6a1daad832ed459ed3b102ec6ec6ed089f480368263b1d94a31385945c422ac2b93295494e42adc7ddbcd0b95b0f75eb79a75ebbeca94b8fbba858f9239c6086b9fac88b9ebaf298bbcf3ffaf2954fbf82b1f28da45fd01e79debd0b1db8f0f0cbce7ac88deb1dfe8c1e63e7485196a7df66213eb821c42ecd7b98a34feada8e8925dfce9ee0de324b7d043162ec2846499ba7189c3d69c12c415eba9decd3866a84ea74ecfaaae540b9a45b029e0e445a0a3660b4960e330f0f0f0f0f0f0f8fd4c1de5dbdc911a4a694920456340be9c9b89632a594648af09d36c099094e4444480b7f9136181082320a500a5c0a271526e514fe3c63fd03b478f4a454530e9a32e70364b414c77a93450e9ecaa1d50374aea81a59b372e9f379808e1bf29bf7d63b40dfb6477d2f3d8f9fa40344ba958de1643ab73307a8dc297e8a6e591ca06a27671cbf6e80f69d1c2db66c2a0939364055c5ec9ee4d9493fa606a8f0f559356ed854d168800c9abe64c534a5006306688fb739f65ccf226d52b013b0a1850d15fcf0a20bb4a30236b450410fffe20236b4b061430b1b2af008ec04b430c68b82020c19202677f6b6e431a5dce9087a2420c70f1d1c381e801103e489ade43f3f8972e10fc080014ab597ecd2cb3fd1fc2b501d675bbdf9a2a7d5ae4004f74acf0cf13ce6dc0ab47d3293b1b5f1a65656a0f3e4a86ecaeeecee2a1021afe63edd5ba99753052ae60af9fc46beccad1c5a3c4a2133a94067f09cb37aacfad01515c8ab4b3aa60edb29d0ab753978a60cb90ac9c21468aaa47df9adb2145bda4dda2f2445b59e2d260b6e61438b73892c46a1c588eb172c3fc55a14dbe40fc954ee0a29e543c1c79c0e6b8d2639a441a1253159ebfdc4bad7edfd56425e4fb42996521f4c684ed174e2b52c6a9da49c309d9a8e1cd44dd4a1f15ae3b38645521389cf39ea2d6f6acc44b294cca6f56102e5957d276be91c5a69638b0698b2872c2ec164bf78e1b3749638a63c69219c7edfd52a51ccfdbc6b21b7850d2d8a24b2a004724526c6d8caa9b7746512c8945b7c27ad7a96f8b1210b49a03cecdd97a946862c22813c9bdc71dd9a744c1b12c81f7b89aff1cae1631d60430b1b7de306a680470f2fae90c523106a2a67f8e9d3b57f7bf0c05176802c1c814cd97412e382278f6f11b26804c222f75b66b9b439e40d0e1e64c10894a99ccdec14e6559ff30e1e14e8c27ff850c112b258047a66b4ea3ee95f3f8d16369012b25004327779ce72b25db73a894049b10ac954b6d49005223ec96fe397abc13f44327de94997b029fe6e88bf4bd525e985404b5fae8c914bb74d08d2c98a49d0109907614c9f64e41e6daf4c124415733a1decb4d4e903816e531ed45de3ce7f9605204c8b3163d93a98f8fcc1f8123597b67ef0639c57595ba9b60f67b692c1d3eb7df860e74eb2b9a3dae6f5ec211d62bfa86d64d3ad1efcf33a2d0bafd2561ecc514def17d7628a183c147a919348dec1554dbf1555bc847658b3534a12b76f3e7528f4df6218f1281e1d3aa93abacfe1a48387ab790ee79652b6b0a1c569441672c8f694faca8abdfd71e0f394a5c83d1c9aac952de5df60bab40d6ed193d20d98ab7c6af86678af0d29edba6c6da66e3236e0932c2d63cd4d7c0d29ddafb7b51a92de26adc4697093481cf7301a6a9f589bf73cc63f3ec3e979a511e6737cc766d8b4244c48a6329c1633244b06f3269d323c6328e918e29eeacdd511831b2f83cdcda6e47113864be5ead827473be5060c8e9dfce841e367ace60bfeaf68348d17082942b2a891d4a75cbb50962431891c21f687950b291d3bfda614750bcd5f7f95f0530b85f97756cc577f6d6621a1d92eabe9b0a0a5cfa9eb9ae1e115b6f816d3e12f87fbac7068073f918f24ddab82a5764a77b7d347b650c1f0614b72e656b5a44cc1cbeb3d9a14b694f44abaa4d652b428a031f85a9a50383707cf139ff2d6ab27b036afde9e6ed1572768bb751633cdc68cd81636b4384464d1048448dc8da441b34abd2c9880b099ff5c69cf620928b7893116d3ad0444487e6267222909a824d257aef40f09e8303b73973ec13aa71c019df332f1d3443270e306b124646104b45c5fccfe994ffff460c8a2086638d9c9cfd465b19e08a77422fd2795a4fefb10d47c5993eb11e5df238427e64be6ee49eed62090938727131754922c81e0551229a6edd89eff07672b0b319786fcf1411f421adb24f444ec014963a2a4b05fb2f2e3c1deef9ebea7a2a6643b504de7fa460c1f4cad83b4c9187f428a54d7566d710691450e10fa16f337e5d89d7a8303e4dbd98f8c07bd4dd92c6e507eb8cb29c66d40ba3efb3625ad013243f0cdc9b972574ce48517dbe387674183a27ecc29d962a69483011b5a68610109d8d8f1050378fcd8f1001c3c7474e16351c080406431035458ce48eb9fcb42b28e90850cc89562ba594c3d9fe5d032bb41163148cec3ea75638b9f39b4b28001e2ffabe4735245018b571057a054b8b4e6a944d2d23c8756291e3a7cb4ef18818e0c34018b56102e5b38716bd222480c0658b00231e17e6352958da63eaec2ebf46e31010b5520d56d6f26fb59ff55ac48b5018b542036e9f0eff92d536d8e0a848c76274f659f02b57231a9e6889f627ba640c41adbae4b97cff24b818a1352660a1b2105aad4d54a90348e02f99592f418c1230ae42779bd29043d14a8347de2ff91b67d675020d2eddbc855fd8933b6254bbecf1328f3968f93a44d38d37602e597d7fbbbbd4c7c9013e83e711a1af553b6753681cc90b33d9cfa60ed319a405e9ab09d39e599b8f4761413c8d9b7d294bbbdafd22510ff692b4e4f3a0996b404726d62ccdc8d29e34c2a81f2a41716c2257d930b25d0994a56fedd983e3e390974ea6db1ca2739425291042a7e4db6986e5f2c1709444a912ab48604325db5e2b6e6e7b2fc084454cb4a91328f65e90864089aa5c23f86ec636a04623562c4d30d1bfe628c4068ae90dd959dfc29ff022c16814c9b2b77c3e4ec6915168a40a6ebad1cceddc7fc4d042a3ee432885b10814c3a3c957c8ae193f410c868d2ff4b8ee914c2888521503a925249f92e2c0a818e1537fb77472affb063007b8005215071b2ee44bcf47ca51f04d2cc7ba2e9e645371d168240593411debbb2580402ed9fb7fb8429699a5f40a04a8b69c44db1f2fdf207547a9a8f3f33d912426e80851f6c3fd93f49879c3d4e052cfa40ac4c2962a5b42eed482af6d9597369e43cef0958f001a551d64bbcd27b407c4433bd7d625979d2035a3ccddd57a6f57b330f0839ad6731f98cc614c783da671b732476ee80ce79af324b0e93f245ed8052693697c9bf5294641dd0a6e64bde59ce0658d00191ea3b9fc48db9df3e87d68e2f7a7091b6043c4ef06375fcf8c1dbe3071673406ab01093a6efbd473f87d6b971837de8e842e5804ee296d233d7622c4bf2008b38a0e62ac74a05ab904d0d07d44fd4b513c1adac94de805a37f19942536e406cc7d25f66bac2c56d40684c954eb7aa7fa3840658b001397249cddbf6c5a0a90ab058034226fd04f32a4bb27a3520f426c4f895af76a5a701bdd1e38be97e0e73713420f3a5f4e59943c2567d06e4474b2627bdaba6bb664087cdd24d2a689210b365407a588a3cd962b624b2644085b0178325112b4ccc19034a586d4e932f279deb8801fdd9a9f4e9dff49e316140e7a43f44d39c65e94e30a0fcf3c866886a7e2bbf808c273b2e6a422fa07aacfa4b4ec97ce275019d728c613b553dbece0574779a27ef919cb154b680aa6ef9dc3127ef47b58054ffce69af62b75c960564f49224577356b5486101fda9a376aa92b355c809b0b802d23684cd919cec4a7f2b20767db344bad39f4c5f05b465a753c26adddc772aa03d5db8d4a425aae73cada6549bac4f5b0aa8311d5657ca8e023a6de5440a2bf797c350406c5ccd06bbc83929d31390f69566f28e7d9f989c80d47ca69fdad5fea9a423a7f97888f539051a369ccead62ba2990f9beb061b4624af1c69c89a44dca4a0a2cfb6cc9dd594671c6f6ab8f7d0893228abc648aa039cea63214e64a37ed41814d4c2aab9a8c347e02c939d6e9fd553b8c9ec8f3a469f670a6ee849d2869492c1372e2381bdb8307fdd1173771aca64b762551d4c46daaa6efcb847eb39572ccbcf21962a2bc9053ecfaca7eea4b74fa94e764d94955d81225916d4b6a729f2a91f8e74d99d4747b94285f0c61253b896c336be94a14bdb34822952b9120be97f8892577be154824db62d2fd11a506ddfc745ee2e30892aece19e33168b8117f85104346301a734eb75ff2527811c75fb48ac1abaf5d45103b544b699888bf92e58a39f9da8588bfe66248ee1d24a5eb109fce99e931049f33b74a32cdaa10cb6f56ba3c2178d778bf95977efd20941c2dbffa8b6405d15f45ae104decbf1388735776d0cdb00d20aebca7c5db6f937f60ef539a4a4fbd1f4c9bec2f5e5925f6c13f39399fe343ab2e6b7e324e234662ec016dea4cf366977a40dc588d9aa48c39de260fa80ad92325491272c42e061ed0b17ab63b9a121c62dc01d59383c724413e3ba0b3563bceae53e5eec4a8037add4662f5ade5f2cea103ea3d92d04dd17bb63e271031e6808e11e492dc24d31d93726895a0070f0e983cc490033a988ead336a7142a231e280d2ccf339da1b79f79243ebac8b1870406d18b99cee9d99399d43aba4186f40e6d5243ce92595e9cc1c5a5ef0f881c3abccdc808e5efde197d47c98d4c1428c36a0d7dc3ad75930f75ed98076530f9ba359e79ce11a1056d5396ac5edf94dd58092a22947d359d299d24903cad763758a5b79b9936c88810664899b0c92a4a9e79767406698706a73e457f7b41950699792bdd67869885106e4a71cf3e36bcc71c44286186440e8c64a7232a631e7bbc70878f4b0808e01957c3d6ea5ddd50b331a628801d5926f56b6debfae1406749feed4f52dbbf0190cc89b147efd4979b2ffeb0b31be80d212933c5fba735e4f0b31bca05e7a88bd1db39d89d105548924533e19d2070d3d87d60f2e36c75d20061710fb3176ce770f7239358218ffac5f0c975c5f086268013dc1de93ddc6db56b40d31b280febd1c37a73a5dd04e0d31b080d294b9277f9c4590cd1550d529a2c93e469dcf6b1a6258017d2a668e7d6b1ab1b50e31aa80ca9cfdb74a9a6b884105443a09132d6845d3e499eb38438c292092cf263baf7137534b0171e984dec758cc653b0ae8f858897327d54bca5040abcaa96ac75359cb3c016132e4bbe899b193844e40e6e9b9b0ebd76aae35017df14aa59c7326a0e56565d72ba7796909e89439680ef36955ca520242d2fa58e59ce429f71470e346552b622401a9fe6ad66fa6936b7e0d888104bbf2d9f7e684a88f6222887104645c95fc31e594b0e61b0125a29a59faf8f9451d0c318a60e428223e621162ee10830888943fffe6581468428c21207427d557fad926392960430b1b0e10023a8990d253beeb58787268f9e0e1058e1f8bc336461050a2b3feab3766167420a0369cf0bb4fbd21ffc3470f1d8fa304ee5e9052db408c1fa02687d94aeacc89d77621860f502a568e59b13af27c775488d1036486cb68c86b29d7646d6c21011b650a317880cc5737de253d6ee678b1ee001b5ad8f015e8c8c05ae0c60d28c4d801f27366d4cd922be798c4d001dad2c57a3d93c7c801aafe334df9c5a592f59d27c4c00122a758215a90cf9dea3b4e887103945cdb689769378fc585183640996e37bfd3f2d5a9ac016a23a94bf1e3d6d258b2108306c818d7eca9d3999ae46780b20a5f319a9698e6bb0c5035e6276252493bf8270608dd8c5792fa642e49c68001fa7b262999d1fa5d72382a4b0e305e81f664f26bd25abc48760ead1efe43c70f1f3a24d0fea3078f0cf8f0a1811b372601c315c8edd6d4b5e6b602359fac74c4ff58518647d2b03a006315a8936622a6cd1b342f890018aa40b5756c13569d6f729c0af4ddece64fa5733835a1027fd7ed0f2b932925f0b15b188c53a0b5d6eb735abea42f4d81cc3db393a269c9ff622950ee3923c8cf77e3068ec2030c5220235d886d12625c7b056314a8349bc4e6cb2218a240ae07c992923a5d49f5a140c597d27c9de7e2260705da4e45de30e727d6e49f40e6ef24762cf5c7cfb92710fb16bf5a2db64bed4e204c3baf9c068da6ade604fa27468b94bbfbd9e24d20fbd76d3fd6a68b7d3581f85877161bded596cd043ac8efa653613afa8c984084f1d83b0b5f026dfacdd66f3575b3b30432ea9cb2a87297315b09e4a7ac144c3d058d984209c488c949f94652bab9a6006312e8785696e2b33292d24b0215515ebfec23788623814c1dfec45b92496aa421814a21bbe5153ea960e2472052295d29655c373bc911a834baa93605bfda9c46a0ab424a9affd3985619817ed164b2c6a46af87611a84939d5d87c6e53fb2802156424e5e99844207f2dab88407586c64f5cf510e8980d8fd1ffb83e514320352b8dbee96791942c04ea4d4f42343109810adae12bb46f34a53808646afc98923da7fa0d0581cc4c7a4c6dd2e136be40a064d4983ea77de3490f1008fb7072bec5abbb727f40e9d8a8baa5d8cbc90f885871e26ba589a4724a1f5055e25ead66a5392c7c40d8eca94acb39e4b9ca1e5062f246be0d1ef622a607647a9cf2cbd14b59a9f28010ab64259a2d3ca073d6decdad215dc9dc01bd75196bc26bfc2c7640a6e92d4b1a4260d401a1113c5d8ef177ac663a20fddb74c95bed4ded5ec00930e640c81a27a31c52f136a4dccb1db5aab6b0a145008600230e48ddf54ae6f597bdd312e85181fdb10b307040a87d9c6be84b3c33cd0f60bc019564548f298d29997cd204186e4057bcfea8f5c61226c34361b401799b74e4bdf01630d8805232789c64f121fed9a93c60ac61118f78e9abf66f3578faa4256d1d9387ad555bd8d0a2340037809106d429b7306f317eb8202701061a9071d72e87142fc52bfd10609c01154966c93189141c57806106c485651c6bd9acbb2610c028032ae51cb229b5694de066811b37bce80247824106e4c4b639f94d39ce547268d50a608c01915fb38799afb7307145020c31a05fa2f5258996e4df1706d458ba182ced2789e08301914cbc761049f9022ab9b8ddbc87458fb61750b3e15a72d8bb80eeeb199fcd692996c90b156c915c40b5dbe692926eecd406028c2d20b52e78c5b670fae482630730b480cafb1af4624c0ccdcbd902ab0230b2804cedb7c1b434659d093300030b55eafee9d8d416e6151027dbc4bd6557abdf88d9d8a2019e810da0c029b0a302376e68f5e8a20b1c190a1856407efa0afad65b5f371f014615909ac2a7f8a752e9cd9b0a5b76524debd0820830a680d4f68f315726cf4bbf00430a889915ad9214df552c5140589598e55954d37b1917604001912e649389af31dd595cf4d0c08d1b4f48525faec5b41308674ae37e54df73b6b0a1c5c155c068823bee1e572d2cef4ce0925eca8dc97589f3125276ff3eab7ab32aa1b78e73a9114cc4f1cc1636b4b0a15bd8d0e2d014309280d6a4a3cac5e494534a79808184c593568f9d7df3e91ea178c293644d6e61438be3040c23a0420cf922202fb5edcf6e4af9729a08c89c244362ca878032cbfb1634ca685e84804adaea3f9235e6b64c10d0d71773ae7d933aaa40400195ad65302517cc2ecca8c427ffd73473eecbe00c4aa0f2959a9cbf43b6243493982109a45c8e9564263b1228793a2bc45d3319ef101275a3663ca24ff992e92c96bb637268a58d2d1a9002940234821d3abc8be2c20c47a052deee4b9f322783de3a4ef06387f7f01c3b74d412663402d5714ba89b0a6f5a22871128cd49cec36708df6ee72250f1f795462f7098a188dc53f8fb148fe902ed302311e8ec592f392f57e96a7c2002952c043319534ca2dbe90247ef7045330e81b26069755556e2860b6a31c310b57758cc6896b0e18207e3f8c14e82c4a304330a61f493efe348818e37e4c00c421cc55210ab0caaaa313cac3243dc4c49306310c8ef9cf2df77ce141e51c18ecd0acc1004c2f6d37bb5be73c9cb0666046237ef9ca4069d2005660002d9a25d6937ef48aaec0fc856dbf84cb18ff519c10e1e5c980bccf003427d36e694269bced28fc07fecd0d1075494a453720f0e330dcce003f2c3bdc8a5e6ce33ed1e905163bb7d26e9ebeae5df0466e80199a6d9934a7b7268e501912fe74de6f16c19cb71f4e08107f4d5b84b7e9bd17377f80e1e5ea4c08b0466dc013d1652aceacb9b724e7368edc0b163d9871dd06992b22eb51153aecba1e53e7aac170581197540a78f9f2ec24fd6941e650f98410754164fa539202747d40dd38c1e2f92436b878e5238430e282552c8450d0b5f57870f1d27401f3dd60256de6680197140a588c923c7368f9e3221cc80033207cbdf97413fc9f86f40bf67f1d2cfab78d9e40684c95e4f39e9a60dc89cb09faddd49474f4bc961061b103b9a9b530c63fafd1a90db3972d29c613d5bce79c20c35a024fce9fb8ca5ccd2990674fd78ad9a120d2821a275e9fe7126de1990e29534cb24a535333303aa2e8926fd389ba45d0674bef8dc9b53ca8d1b9f6440dc89e95c3946be983106540ca76447bf38c5808e49dfa6cd3b6b274e39b45a6d6cd1001b19c01dcc08032ace6cead5e4bb6aefc0804e573a63aaaad1fb9c195f409a090b97dcc3640833bc8016f7f2da481bf261e283195d40a97964fbabecd74710667001253c692571b14e64ff1c0a7800070b666cc1a4641837d9dd5630430b88fd70e712f763a36b33b2808ab4dbda3af11c5a27e082870fefa1b580195840d6985ca6e6b20b1f8b02ad1e3cae0133ae80fc4d1b93fef9ad80cef9627c8b25e9cdf4552854f37596dcfe0c2aa05478af8ef6c5b2eccf9802f22cefa658a5ce457f86147acd767d1410d77552c55349d51e0aa8b449d62d2d8619f9092839dec924fd85ab2427a0a44ab64ccbe9c27a9a805cbd4b4143126316c304646fce7962c86699185f0232df27cd1957a969ba12d0fb2a29e5e4af902e4f02c22549fe7876329f8d04d48965eb4bdbb9927d0454eedcedfc59eb7136022a2c6ecc0ce7e1c3dc45407afcc865d52e5d9e2602e2f24e66f3d80d31d54340698cfd6e52e95b2d0b0115739f528e1e0e026a342346f897f0963110d0d1634a591935999e7f80aed58b70abfb0065a9976497d0494aa90728770f933d89ec392e0f10af15d593523a89f7ec40cf27f4537e27e9005defdb29c4edf808a61c20dc5be3de55c6885dc201426336e54f4b3740c50e92e368e992364936409bea0d72f3f7e17e0dd067292de6e424a76b1a206388c693a7266aac67808c94d46fb3bd6d9e6480989cb3c718ab2b78cc8c1820634c6713e3b2784967c0009974bc2435e78375ee15a85cab3d6632d575e60a54a5a0319ab666dfac1528a13b31638af0b5a96505baf289f3531b73a7d4ae02b1a5dddeb2b4e9be5581feb092ab36c64b9f5381d049f1d1d73da840cdcf6693f1163c36e714e8983d2b571653a05452963bdae7764b39a54007efd94bf2953bd7210532da7c79c89b61451f052226d56d397f554a2d0ad42619efb62f4f323714e8245ef1763949271514a898434eefd312357f9f40599f581c53319e407dc75432e5bb4c39653a81d2154cca09444a696722e6ab0f8d6e021937e9c938f9e7af544da0b57a2ccca7cffe7d660295bda6c2cfe91c3b4f4ca076d7d532de9740c7fc244bc9536dba6909645dccb94bfa7a48d1ac044a5557979c90c22431298134bd5609416753fc9340bdf7c5eebbc9ea2449a02584cb6b22b7867c22812a9f138b1c8390409ddac9316d649589e1235029974c7fe9baef26e808b45dc4be8a7b23509672ae54f3e1636146a0fb82ac8560ff3e9e4520e289485ecd3999061581f4d4762fef1ddb542e11e84cf314ad2ba6e90c2210927d236577d64cf010e81cb6fb457286404e2e2d3d91520a81ec36eb70d30a215017296da7e52efd933208c48ce448951e36f7a40802a5765ddfe2c99aea81405d76f6caa49b4cdf804067fb910fcfb13fa036c51883790ebaab9a1f90295beccb27f26d8dd60754e94cf93b5cf88052e936c53077195ed903fa4f8428417e2fc494e901152156b0955c12bcb23c203ef869ca1b8398c8e301b55dfed72964f32ddd01d59562eea57d2f492a3b202b756790904f634c551d501566274577239f4f07442e379dd7d54dc6760e680f276cb265e480be9835577dd525c738a04ae37de614d91e28b802c8808355c11c5abce38bb72adfa163043b3c3b20e30d4cd04962438c61299a430b078edeb1a565b80121b6ff573262e1f4a90de82061d3cc84460abbe6d052c10fe31d5ffc1140061b1033d936bffcaa57e26b40bcc93edd1d0baa25ab01253f8388f56d08614f32d27098d267d2b484e4f8b1a3c840433df7a77297fc4d2b87960a120e52460432ce80ca4997d6adf9b2e2c5f6d8227bfcf022c93043f77dca8306f94a0fffa1438b1e3c18d038da0b0df4e0624fc0a30bc7c08e0ad8a500de20a30cc889a96225eda1ffd0d18303376e74e9f1c30b1964405e77ca3649d6e3871745c618109be4c4f91296dfa45e8a0832c460ce3d16b424393070e3c60f2ebef0e13d6edcf01e3cf8f20b1b5adcb8917870a1802e7c2c076e9c6007ba71a30b1f8b0242aac70f2f0670051961385bdc6dadeffa9b1e0c7a976b79e6bfe09b698dd9fc97f1829b42dcce53ace4cbe882e991543a996c922f830b79cbe64f0a9e547e0b8999560bd6db17e35a30d5b3374ede9e0542fc320bbb0c2c9cdd51c7f37d4b57b03ea44f997b5ddeb54299f28caa89346f9e2a202763cef3f88dba0c2a74a5f9c4e693231f74195358829feec9957f9182617cc74c788e291e05b3de49937aa23971281c6bd5529a1862be9f506fa7b069b26d2738794773ba0907dd30c1ba8daf9c2544b39750fe4e1db97238392be149da4efc8548cc7212ca2f294e9cf8926f1909e7dcf0c1d373d6f0110a1e23df899dacb011eed39ab3529e589c8a90b2a4f4fc670827119293e8d6553926fd0da1cf09f94afa5684f069b16c1e3927966404e1cc18d35a090895cedd71f22be3075ab7e844edf2cae7caf0412a897b99b8297365f4e0d4933b24db0b57060ff078d934cbdbc4d656c60ed2ec18c63746bb56074552d2d33c96f61c193960abe49e861c193868ee4c87b89f308f8c1b1c9a21d89e47860daab9322d61afb6df915183d2fb68f0d891410392582e99215f7847c60c90dcb3953b4c4a8e0c19acedf162ea185c7d4abf5fc5326060eef0da2bbf21e61597c792b139abed925c91eacac5ec8a755b71ac14e13f33dde4282b8e565d9a5578ea6d55551c9bc77b4fb26f9a0ad63d939e4b5191f078a6861a806033b85c5cf9f42f8eba438d3f20a27ed60d313dc964a98eff2fb250c30fbe04c9973ba47c151b5b48e0c68d1b370eef089c8bfc438d3ea07f5fd72ca42bcdb7201f90a9d435b9d8c5d3d3e7d04adc0352629aa474d29b1a7a40e53e1f359323ee97efe13ebec081980794eacdcab9846a085e9ea1061ed0513cedd4641cc950e30ec84931e31eaf3c7bdad10ec8f8321e67796154eec23aa0239cf44c5fd9534c313afc4964fb8dbba439a053bad09613f6bb1a126ac8016195f2b6e5f0fa9d741c906795472ecd9352d23c7040c7ecedbf41262495e937203b2df78798e7156ab80195c3982c9d69e71bb3d90674b298da3676c5fb5f6c4058ae92d11841cde25f0322ca56cf468b7c262456a8a10694e56ce66a08ae91ee34205357d013091663ec1844032a66de4865a5369dc737851a67407dd7fba9df8df0dd87a0861930e5976aa04619906bb21bf452840c2869ef2b7239296d7b8f4c418d3120c44be6601ae73d4ceee30b1f77821a624048929615de796483240ca80e8deff4319554f98041cdb99a45bd72387cfca0c6179097cb2e6d55a95f95e4d0621d3fbcf012f8f8a28617f64a121c3b7474019912b573cc59e5a30617901ad2a6d99c7cc241cac6160dc81e35b68048f9cd2ed2ab4e3eb580ca52591f5faa2ceead9105b465e996267595166a60019dc23ec7cc3059439a548d2ba047ef725c9bcd77cd6d68a117851a5640c594f112432659ed9750a85105a4ba6fccb24aa9804b0d2a20dd934efa73824caaf0126a4c013939e60afe9d9502eaf463e6a4bd8d02c2432f7ee55d53b587022a666fecc58dd85dce13d05e4acd92c70f99f19c809009772ab7b63ea8d10464d09cd3a996340d21ce0444d23176775d4b40fc9eae7b872849445709a87fb732c939a996ec3ca1461250498457097bdb7e9a4502327cecbc2605374fe6088a096a1c01dd26366dbba4285eaae251c308e8481abc2b5798d27011d06e3976c4e2c7c64821022a93b24cc9c512458d212072dee8e9279d0c9a342120ac8469eca039ef948154d408024ae32d9cf2d9f6d42427d40002eaf2bac79f3ea596a249a8f103b4a7deec377aa6b63f3e28c52595f378be08357a80b2bb7db70941dec449841a3c40565825a91edc6ce3bd036449cdb121ff49de9ca40364c94b2a17ac465bf40bd4c8015ad2d8fe777c6fdc282ad4c00142537837bdb2bce0f11c5aa546b043478e2d7ab8050c046adc001d4f4becde4e9a1d4e6c03e4c8b6c99bcd947e52a306a8da5326fe4ff9c635736859f9026f508306e8bddc2af7631d34ef376edcb841aa94116acc00652935d5c676430ea30cd0eab21b67efbec66486502306e8b0df193c245a948d0aa1060cd09dc22687132efe1ece1ed078057ac79294311db9422c3ca0e10a94ce9c4e5b4e296612a756a034fd33841871b5921e051aac7052b64ffad27e875751e90c5f9e73d66e5471a7b575324db9f154141744bd52a35e8e8afb4e4908217d8abf743ded3485ab19afb13ba9af4ab1e69abf34aded9831529c4dccbf361b4539d879482ae8bea94f14c594372fc7882735a128529df893a5b3c620284af91824669f28b76692a4e3867862dfa42979ab6e183bb18cfaa5b358da3f4efc31a7dc14e6b3ef4dd47963aa1cb31483a434710a6173a592a4f3c79940dc35e58fefbf7339269871c91e3bc698e24b1cbb64c8d96458737d2da17834e929c52ba1040fad24d37a990a254e7d7ed2620e2229982651c79da0ab1f1a43d09004725bbd52f69c69baac72028d489cec733ef9bd1348a0c44bce53ad828dc71f81bc4e7bebb50c0a341c81ccaaaecfbe614ca5df08a4468f31b53a4fad244da0c1085496a69032fbb40ed05804d23643da3325621229ab17a0a108d487669a8b1569cd2716a09108c404b1104ce53422d0e9abdeaddd3d9af6d8214e4b3be2672ea908d0300422b87bbd7d5e40a31028a99fc24ba490da43635c408310e87055f2f119934913e6d0e282070f2f70f0686d018d41a03c472ef7de2a87160b02112f3fabef64879fc07bf0e8b4018d4020c7737a10af8ffa73b128f01dde0310889c440c17f7a6f125d680c61f905d6df154aa6439a5cec5fa0199eb39cb3e3d70f0e8a3018d3ea04f86a4662a17d2e40b3e20fd83494f6939b786387eb88f3d203e5ffa70225cd8e0ab1eacd51329727c9c434b471e9049a9128d39b6a4b9c36440030f8834e3b9d3677368dd01f9ee67e9a5b7d2e97c6c0eeef18517387874c580861d50f94f24bd67db0f73e5d0aa42a30ec8ac58226933ad405140830ee8d19194deec13d09803ca44f8bffff80b1f3e74e01734e4800a971127cf8fedf8ada3871744c78f2f0a0b68c4614f965452fb21969ceb83478f421f25601d3f48d180033ac3c5f7cc574d199e37a0be42cef249849036e9065430ad88da9e2c3c886d407fbc35b926d36003328ee5c971d6bfbfae0155df415229dfd5607b98244f03f2f34ed848ff99636334a06287dd7ca5d9daf1730694a61cdefd2427b5b231c3a7a9d34a62a934ca80f4ec0b29c30999b369900179e284ae78bc917d2d8716e3f8c1c517fbde651aa0310674e6f3eeb81d2fc9ecd01003b253a64fba2bcba16500a0031a614046cc3bdd612dde2b9543cbca2440030ca84ffd92934afbafff02dad7f2e758f92ffbf35e40ea7fc44a8fb13ef95d40249163ea8d318b478d0be8f83269725bbe0574de28396e9cb816509383b6edbc6a4e7d16504a55f2c997361650faffd73166eda9b1af804c5339a4945b0125263d5cf9bbc495ab804a252ddd3d544049cd216726214fa19223a3f116c2524096125133c44e97d3514045c97193c98edb24430129516b54a2c9247a4a4f407872536721bf4e4089acb729b9699b80c81bd4dc73296d19b34c40a94ded3e53c94d5cbb0454ec9cd8a3221fac3f4a40e7ed24364f56fa4b9f24a03a8e59fb674c52d7830484f97d58a70d359d3c47406ff678296fd61379344640279993ac8974115067193684984c3d452220acd4d56f4d6fe5a74340460d4d36132f8cc95408a8d22ad5ee7a393ed32020df94ce1722b7f97220a0425ed194ab5e73ba7f802ecbdfcbcff101aa6f732644996c3ada0344ca114cbb26fb250b0f703fa5fb71addc01d2ea93ebe5181da0dae4687253c1922573802a8d17f77e441ca0538e97e271833740c78dea37361b7249364066db2cf7b4a72fba3540c9cfa598f327999a06c8c9dda9922be88f773340a94a4e3a5deaf5c6324079cb4790689ec495628038b38d9a4a87060c50692a1ee4645e8194d8596ef2f7d8a5ae40a4be34a2b1335bb3d20a94484c2331fbb888ce0aa4a470b1ef4f3e645781d2f0ef9c7c9715b22a10d964ec47fd244e9952815aef18737e893529c750818e5bef9aac534fca4f8108a399bbb1e925854d81b66469df4c9358b214e81331cbe58a2952a0b3ad89989d51204e3ce39bdaf81c92a2407cd2cb71959eed54c80e1d38767cd1e3ca01334281f02e5566df2e28d0b137be5b4431374b9af1096485d58efd58b1bd09333c81b6e8e596f46ff72f09875e61462790b95e3af8584db4928661062750b9a6a97424fd697c7363c626901fde54860f219dce8b26d0f14475d692aee41a365f98910943def196f42e61434c205fd2585049c932dba25e987109544d1e991c63b6d07b2d81fc4b068c39a864aec80269241207c4c15038180ba2b97b00c31408001034240d8502c128ce54c97d1400034f3026362c28121c1c121416100e1a1686028130304c1296c600402010068402a290249b41fd1c6790c2105e3eff7eefc8eeb800340589602e8a3233c914f3a6ff5f7d0b1d1cbafb76209fa07d3df64ba1cea809067909ee8af795287da61574ced69a1a8b227ab309a272ca69c74a9955fbf312941199cfad97a6f4bc515bc300c6a665fae77ffe307422e233988f2bae23bc2a98e0181f58f223d52bf7074a2932b95ab21ac304199b0f29a11102ac0f292d877cf5811057edf1791084a3e36edd20d29a880b319f5b41bb300464cf73943465fde2d5237343877c2927322c9ab3fe39e722b76202241b630f97283ed2564b036e81b1e76b75933b19083ecb778ff6b9045a46fa9f3e404773783f756672b43cc0522899d03e8433203c0bbc8c6f3280fcbc3f5398cafaa39d647b4f8b9afeb60bea1e7bc40e35ea612625590df5fb56c58c5c9dff6355d4f1cd4230a39e50d1aa27a66b84c40d02abbd48a0d2bf025c0485abf16ff637eaaac27185e5a45a1d0d9c3b0935a6884aeff3b435cfb2ff070a80e7255c4c4b305aa575b5eb46995612c442c65b12d5e16f819cd6fd6aafd622ff1310fdb392cab2ec7f6af598da03f1d4a1d2770328a19b3723b20dd14f79aed7d035b1dda078999084dbd1a2e2e5ecc51fa5131e5fed1216b1fbf162ec05c637e3e7b4fe8a88e52e4ddee12909f8e1b59676c96701bcd81041ce9c6a87b7a2a405fac37e1ce63300c432887795502b127f05605ddc5be39df9af3569876afdd89b94cca682a22864e042e3943be61291a7154560038e614c5ee84a4055cc0c35b484120157c0d55043bdc16f88c55b61b8e8b785a034104547cfe0ba238ff8215c2b668484ec26343aa152ca947d11fc671872803dd1f042a18d1d59e781244eca361bde8e8159446db0956c6944ccf7deca70a6d75fa62217bf7147a14aa753a6430d459bf1dcd09f74e81a00561e0836173dcb33ccf9908733422aef23875f5717150ed1f102ab993894b4acd571a42205e7535b427c59847037e361626dc91173c600a91f9f269b9b8ca435fc5763889fb585409606253ffed4257d8abe5a001a86ce11b97e142823282b72d191568ac39c9a490e38d6b5cf130f8c70135080a1cbc5bf99877b6e77c4d3a739329ad30f941c31967e0b4602d0445248b9a3070ede13378d059e875194c394ef23810adf64b001703aaff965fd5b6c43a455e2284922bd09b38e160e15ae5106d77f0e6315e831619431c636a8e4681283e2c279146c20823ef1a470d69d830618dd7b2b73e6f9d1520b74a472e4ce879d34ea435f4ce9364a3ef0c53c8acc83a851ee3e365e2e75919c6d5dc4db45b4c3d31a2bfce6f8ec825a0006c5e91345835d2116919ad014c8ddb5ea0cfb366b9746d8761245d2afe68ed89f2fc818183ae0edb2814b3c91a24abb8846a41f0a757ce420998e4691874424ce687572762370c61c9e30506a21a891ade9b40e571549e1bd7de6d36ae8ab1e636b56726a239cbdd840330c2917796510bd13946fcfab3aef7f408f5b05c879949ec263107134a278d0d813028db6d3f3b5edd6078a49da6a7fec0d527ca8e4044f2959c6c13c7533ac7899e6662e77b702ece9eb7ee6854f1437b7bfe044e902fd8c2e98453d31fdc6611121d65557200b6023744abac82cebc7823861c190b0b88889667f0b2dfa3fb136a3813421639b1115f3a30c22591e305c120d9ab2b68b0ed6cc9209affcae334e2234073ded009c0194656f9658023c27f00f1150ecb24540f4bc16b55fbabddb26e9c8cac870aefc89481016d757fe93d1325a31966c7dfa0b05eeab1718c937c659e661f13e7b556c2f42bc2a55885652442afe71d75d625e02cb8a6825ac101b652d74a6574f88e68148e54a926fd3029da4f02163905bf9993cac9301ae58982775baee2b2e56dcd4ea590599a9996c855774856865a9545831e47b952c49058a10ac9c63fe6abb3f9c72e665418ebaacfc40dcaa8bd3b59098c37ddf4282a5a0642841a9f1bdf55857bb0aa0af29eb589c18b37642c9890078a9294d4afb28f7a8be4194f138c1d154e2cba520d128bddb4cd494cb314878f51e03e473544ccae9a7b581c97474171caae7e0a4790004c601f83dfa88b17f534018af8e554a2de26a179d2ad7d1f4a8d19c21151852610344a5e56111068997c1e3344e541a5ee2e72a0ce61971093dc88f0ba9b8e247708ebb7912b936e0bb62b068a71eb0b928dbd6cd9fb9c62dc887bf352e50ca538a1b47686cf58031fefa09b96635e2529d8032e2fcb84146ba42edab80abeea362b42966eae80c7a3da1c3fb93ccce545575edb159ac12cb22ac63a7bd55795e73277cb94bd45762fd833f723b8c721508daa2c07cf51fbe48253108cb4792fdd5ea5912e9fbefb5657b7e437694c47f0e4fd57373250e57c44389fc884a1fb4a564f1ac13d10be2c921c49726f10f9a9ed73716cb4f188d2940169e5c2d2f16f79d662f3f7d0f51cb8abad662207f91ddc714789e32a618eed7abccd16c75a8107618a87c53e20adcc680ad2c071f78ab7b9e917c706bb0bfba94127c83d6a1c46cfff8dc6a37e7ade405710b060c8a572b9e56dc126dd9943b0a236a2932e59e5461dec269623d4c82b272793ced195b4778ccaf6cbe8b6c170f8a89c20691017c904dfa80c0033695c222856845402d08bd934bb851dfe795a17664debcb48294c9ab876de04868afdc78bf971939c8050e6c37ef36a3c9763adf4f51c0b74eb549d5b30bf508b613ce465229dc54716d08906a7fffdc4b2e1bc66eae24188304617a34769d1f5b7aa7ec3336d28f70261119586e6c98f299e6ec17f585f5cb9c79849500a4c3c9ef9d56eb51571fdea9bb80b3ebaf5f4cf365cf3432dd09956e4bc28ed56c5fc449bd0511a5653bcbd6182a6c37d794b9b256b8ddd610d08fad89b2afdf17e40470829b406f829ccc6c37b5ad3c851e9bee80f5ed44f5aa33130283060b2ff375676870782b4f6a08f208eaaeb8d7f90be70b83f2367adf89eccead27db6aabed7c5769d2f70f9c177197d96919caff697a229b28af506fc20bce29b917867766f0dc48c915fce88ede02976dc2e8a1c485bc4a4a1beb78f01ecc9f5f803247040013f4ed98e2a9c1dd26cbfab388d220868e8a956659bab4c527223d07f163e401a1bed135a0f50a1e1d44349729d379687a8b3ea38427f2f3cbe00e3aff59d59c55de456a9a2262c559e6356f914fe987918d0d8dab2fe2e3c2ae40601527598aa4b6163f40fe6fa27b183102dfc9379ee5da369f85c7446a6bcb6bf429f13c331aff76e6db7d4b341a136708a79e21c09daf75a4cdba4b5349659eea390886b9bc74c19ac7153331ad70ce4a3289ff6600c1ee94875c00170db08349103d2f20b54f90bec4292f1c4b61bf91c1a1272aa8de2c6d244643407fcd8e054f9583bb79966220242e2d2fc56a9b3f739a03226b4499652d7705f1dad57450ea6be4af8d701b2e632a498259233552c5bd1cade21ac03d942cdcc80c107957056244b3ba90876a6da9ee03e359323d1c7c2bc4f51494076b28d2131827502d8a84991354ea1390431bb081155e8eed407e402fd6690770d0911151f9c9ba51e947102405f37ec9e186ef270e54dd879536480a501441534d137a52727c4ca7bfef92b423f9dbbf4f29bcbc2f9745c889ee13348fa5a631e0c8a9cc91507b67eb8335f0ef45a89604c1f44de0a5716cfa14868d88a9ec5212f88a9f0835d0a2ce049db38fc9a837c3317629e212d3f9ca0c85c0c553aa4119c164c6043baa0395989b19ef1794c9d8070b43cc322d1184942ec8dbfe0a4ceb0e4bb3a5a1289429f5958a76529a507dc3261b87a01e2676f00b267fa23c1dd93e7d8e8895e444209df8c6b14e9679af090755a59b939ee8d88512987acb48146b3d54e2884f94173536f94340b470d9e9e9a4058d1494736c10122d5282e9b485a585883ead72a23efc443331a3cbf58fdee25b6438adcc905a4f16962fc4d941900ae03338e129831a1f2aba0b686c88adb0a7de16bed13321e0480f73c230d5fc011ffca803acf3a75c31139cf76e291b673247616e8a403fe8de49490ac0a7a39d23ea749454937671fe70ecdc783919fbc7f20caa132328fe7d01c8133e0ba2708c3a8620a72e5d9ec952fc06022e7fc435ec4e200738e2d1a71dbce6b776b5ad1fe2aaf07b1fff7a527a71aea60d362a876828966fac4164264c30a49ad17c3ff6cb4a1e6e5f81cd3a8df272ad8c64a195015750c8b35aad8138d5172469c6e621ca08dd194736c19f0cf67c4f6b776ea480b4fc512961370ab68efa72c71f7862915276109a987fb3b7f07466af806a5aa43a31351ba560c1d53f30dee9b552656bb89ccc3940e4a50376c3b314d6bc2913e0327770edc2062a8ba318af72f55e298eacb9bbee5ce93c920e9ad8506bb5a3a7af222ae247a14a487dfaaba99c43e24a2ee611617f3586a95a65dc405369a771b360901383741ab4ac55b04222177528bda7bab9678f1e8aab5f4b904e444764a584aca7dd373648d2013713f2f072cbbcdea48f470491230dc4ea243975b3ec367a08d658175063b52c8dbe1cec4d801ed248c1104b5358e1e97fefaf494742c224239ee5cc48d1a596f58d0c7d6cac169ebe4210ed2eb6690b924770a4a06f0331e58529c1e0398ea81f51c272e3e5fd586e21107640d1911263b0f931854c599b0dbb26651d1df18aa955bc719c61bf3a54b2f340ccda84aaf4f3521df8b03d972821145a75ee3b705639257bfe4670e1b1bc5d078a52b91b7798a340cd7db80474117e2269264e924b570b9bed1579fd27737b290833af5af80248983f4cb94dc015d57a2eec2e009e86b2a4773236b56183c300194a7b20576277fdcbd16d1edd01ede237de41ac1265db5332e112cd0e8140173d1c07d578d9e88ac77a3c77441b26c2f7ebdc3eab1ecbc9681c04bdae16d1f801b26f7e16bd72a399708cf8f6046045262dfb8f16b821b2a1477a493f0099f839314874f38c74c1f5bed559e8b2f64f8172038c7e89fee47ad55a68ab1354976f806fd69a21d249228dc52c64b202c96c8af5ab902c375cc516dd0be381d9701a15799d35af89895e8a20d4b24416b6c1659766eb47258d8c713588e8d577c1a3c9452be45170722f11683ad5de1db044172593e7c8807de52ae75c66ee9326af74a9c6521b0b84f9a4524de317fad942f6857630ba62efb0850bad93ae181d2d8083a0c95d3f083169a001bbe1fc73a8c22a99e5a453ee8a403eab4055734d9133bc376a0e7d4667b180e30491db76fb9650e658bb26e021e14935616e96187a931303be02d4cee11ecbe46705217b575d3c722cb5390c85ba43da26e40c9876467b4713d61b5b86e7cfc1ab528d9d15517f89fb3dfa471f0df9fbcd446fb4b7150dbaabbbd6bfdd7f370495bd657a816de1b346316367050362bca562f1711a23473e8cad4e311875d3ea2059a27ac74e5e5d3559199fca26a119653fce1f542a6eccb20f6462c27a3e1cda2d40c1c743db5492193db38a2c98974ef2195c3f07a82542c1ec803250a18b000265d25262776a4c6ccc647c9a48280e0527e3de3372211021a09271763cf561fccbdaecd54b04e4b3c9d0fde8e8506fa4b1ad66bce2cfe1f82018199b40fa258f49aaa174eeef59cb14ed26e03e4ddc1992a9275d279c089dcd8de130bb8d40a719ef7ea7e2e4608bba01f89d8bff7a8f512e8e28550d30a24f33f12f671268f493532d6eb4fa5adbbde24c9e4641a4deaa5e99511a9bed56a0987c644f3c23015960d16c1e72b2d34809b032056f1446641c8c13043b4a3aa349a92bad6f9c5e4e3d2d1aeaace51cc489631e5f753c1ef553ba73ee6d3d6fb1fe2883a50bc1aa2fd82ba6774c5fe9a187022e9f5b7d532a07755e4a0971945b8ede949c4b8588bfa0fe0b0c7e9a9b207973713f13bae8fbca85f548ab156ba508735674d6c53ff33ff62d71b2720ca04587f28253e54c5fcc05d50a200ff50b179de12eca37a0e973fe56238b5ef479c76628c2491306939611cfde89073165ed32604c7420739798c6c87a200c1808c43d20a59fac530d5a02a2f221f5e3052f50bf120d34e33d189b865b1543f8075a9923217522bc800363d4952b86a02f49fbd2aeb42248c3d3316198a420273547efd6faf41693f89baf70721801ea0eadc8ea1af0b828cb1bbf806812c82929422a4a8deeb255a02bf512752b14b0a9ebdcbc659782446329f25fe299215fdc859288e9a5021c8614dd344d2d3e4806c45086b61cd955438aaf2195c36f8efed1564d34e7e72bc8d667db5e8dba57a9af4794fa9475d7b0f148771e8866853617c6c76caa46d4dbfdb308a3c949fa13284abdb8b6cc092e8cdfc1bebc48548f145efa8933cb38b88295a79afe9b4d53bf3b5b115721d1f22f8cdb5d298469d9520a51b57ffc92fa458ab4a255e8cedaa67e4ad0422df067a29d6af5e1281465705075e24e7053e757a56fb18348e7a4367c5b54cbd1cb555d4bcd486efbef206e3a361c182d5dca09bfc3b310914d421930a2334845b19208d12ce867116c790678d1179d3fa68fae991463c6ce467e47c31caa173a44e59daced4545fc5b8474ce155c004291f772ae4c556e3935a9c8a6f390b999f846b4338bfbade35cfa1b83b8d62681f06d259990845c452eb1603eed6225c5756af409645c3c638e8c80a512c16c714ae13a294bb4b8eb3cff501b35df780f1cb457cf74b548406e8c1be8ce5d0f47a20c7df6b1cda01eca170a6ac01a4d4987e8e519d1cdd83474f8c0397e60492e25bdcc47f2ac866c8b4dbccb2e9be2c914c9307c7b87044f3a8194e9e881399d0f141044cd3c97fa82c0f14276560ba7db2edccb9b351ea88e717a2ef727f584171b61d829738e8f48f26b04be495ec7f3b01cf2d3ab884fa013cd6e742c196d712e61e73d6b82befda387842fe8d61044811b46d316bca633341020f8fc92eaeeb335b17dfc381dba4a3e4b006a3863eb2761191c9bd275186059e719f4983601946f13c0ac0043eb6030e64dc0d8ab138207d2443ea2a1a421906a5f5b61cb6d2c58492661185f90104349a907bf304587580c09ead3e7dd592b4189d701caf3432812a1440c4d0a6e5c6cdcba4791eb545a21deace67d8e8479a07c8a0837c2ed88bb5947e89e911aebcea17e01591382815b71c22241c824dd8791a51dd8ff799b330acd874c1d505c0b9b25ca54810abf4dfdb7715c09a0cf955c3266cac7d04ab66ff1d45127eadecc611548761c0a77ff5a46f0d1b5ac114bcd5517c51d75c61d5b1a6c2eb628d869b153876c832265a14663db913623934d20033d41836b796c8e89582fbb4385dbfb50c1c94158b45e5f92e9001ab01919252db957512635801510efdb2c4889939234a6078472f12cf22f177383405efaa7b6659f1bbb20a3a23ab51b339520225bee8d209501eb249de21b37c5b261695d91cc195002370da6b9779a8d853ee26d960294dccfeaaf31d6381c0539a56ea4cc08634846823f9610a3f77e41c68d34e7d17d4b47f1b5f75fa2a556bb322a24c9b8989e50b8a1390a561b62371c3c44e95c4316eba9a67a754f664ea1583c7b007e007871e3a698ef29b6e1255708c5469305293f151c4700404302f6ef99a8342998a174f9c9547740a6f00086ff1e3b4aab6e39113cb0334a68d56e24d9a292fcb50eef8d729dff5e75930e514c2b8653694867a746fec094dcc0cde7a5936d4256ea0fc39f09368ee8df6b15c4946f207418d655f8234c6b661add6f3f0f03abfd9cdadf39515605d99c0266d65f3c936c4d79b116319062a11196748a73baab6d915ae172f8ced11cc35801964049331720e939b65af7071a46c341d55d5b684a3bd5dbd10131e0800e5eea68b1296cc22abc5ebcb1f0e05c0b2ba079060478bb1cd953acbe66718e3328f73611fc2a6ce5e6641728a4c97681593db471a0fcaff2d65ff29c68a3500b135069320105f3f09afd2801fa7fb85f9c66d262709c30f71b71206d71669356ee2966ba90d9796d9eb2cdf012b83e0a8652bee96af46b72cafbd11aeee3bc9719e62e535f10ba4613a4fb95de3280ce9eaceb299306054d7121de5a0ecc2494495a49cc92c442524be283442d490d24c99de493c0197ffb6b7253c94f930f93a8909244f868b2283e1b5cf6e336c83f8fea1eb47e641f020792a687107b9cdaf85b4181fc71fa12f7e505a76196d11fef346b6480b4876f8f50f563762bd06c4b1ee179acf448ef81e751820f3b90ea3c343dccf7c0f3b0053ddef3d9883e0a3e7084e02d9013251bdba40a1df940d2aa51c2477432e2bfc10de3bfca4dc48f3a2fd5315cd892e0c010ad11d34cc570431eb41f87b5c5e5ab770ee094d9297d0ecaa49c38c4040b6f60b3d359ee16f35077c36d3ee1efaa06965bdfa48cca1909613149b8688bde3340328d50909dc0d2f339c90d79917b5a5fed5e009adcd1d85b2c5c5509435accf689c43da65a009bc9305c15f13c24a28f44e2b567008df7b7c2fceb5c53dbb0c9856f12263961742bee02da30805c519eebb04a3e38c3833b7888fe6709b4286a94f3c1a7c017f3d67480e3e89cebb86b2fac22dfcfd97e77993ce6964cfd9ac0d08ffb462ebf2db5dfdd3f7c285974f437dbd4b7c9cd666b9c59d15f96a58cc78eb182eb6b90a19a1be0723b4152cef8e242c68fa8e11f0b817fb5468866f63db16acded3e7c9fdb655858be62f3112ef1e5fa792994322d4778a514f08dc0f5ca836bc9ebb3c39867fca5265c5a5a0088f1aad6c0f669309399281246831bef604342fe58338fb03191144bc2be16bdcc4586527c05cec744b75f1149e2dab30429cbce06242831c5857079649854d4d65b2650d790a85e5f230be0e5ad566ec128fb83c786c11b263aa0fde0df272804020baa9b737387c303e01b2cd0a9cc37b82c605712a65e38dc5ef921298a19b9ebe6ee921a6b6570e21ec00e543df1ee120126b34e120f171dbbf4d4c00fd2ad0bce9be26714026286d7a8eef33b6660c78e906b048893712731b73a2e2f4447c8b23584730b19771d0ceaa3838d558419a2ffb7ba296890b946c0850c37d06bfe7c25dec2a3aa661a016fc50423a1dcf601e86d66f041b6a0ca86761c5bc1adc6684485ff9c5287c0b6df385021ae3bb791753d8c5a6054027c32318ec40817d4ee0ce2f144fc0ec84aeb084305883ab65ce364c09fba21c5a7f3c8509a6b3922324be847a6859ea696fd93742680ae0f8615af70d2a0e07c80f76789635ecfa5cac8d709978900c4ec6861b39dc5f2e03c12e74e694df1265cb20af109588fc2e8e954a511c0db13e493575fa4b8b11401fd23e78b32dcbc274b8a914c27b278042349a4296f8c782283200a0c84b42652df9b041036113134820e2529be6cc0e19314d9843c12fdc72482892c1379f6465278ec4452bad29158ac70628ff196045a363142a2d7dc2bf289002ea38f2fa96451c5532130d546a26fc58a5934323905564ddb91682a609b57d50d245444fb784a6148968a48995101c1ee50ff906a4150002826389e91809491c15fce7e8650483b2c7b57bb190542dfeb62349ed136b2ecc7e5edc6223b1998b0acb3d62b9eeab9a5c2fc8ea8df38eee7b9a5590d149aeefe1eac60cd03d358f02a725c2554bd392cdc4da6e95e0ebd19c73b71d27bbb34553b619c6f956ae9c609f468e1a78adbf336ebdc0c124a49b84d17136e69e349f26f744b2f0eae27f77d6cbc3a30a6fbe69940a76460d5d0a5d68d6d89d038380b7aef72609adf9bb3c5c50929da0cec0028272e3eb66cfff7f895fd8f891ad965366a0ef95294a238e236b9a76b8453f0c283ae536f2cde0c0ee120e05cac5b52bb62ab2947c9cdc446724b8332a2135760ead1371993aae6a8ddb1b4344a1000f02b1d4da9d2e2404bcbb90d25642d868f668f2ccfbee88c6f14dfeedc20c5e59317f2cceda0e8e4c10bc39b313e0095da2f8e8345e4f097bb701d1d55d73caa61aeb52dda7137b2e4969081be5cfc81da57c3b74c0accfee665cc83cf53a61c51ed37c8d9055ee57eb047ff744923cdf8db688f0dd7a86282df27a9438331a9b3f52189b806b3a0b8328b8c24f66f624d7add0c56280180e6c3b14fef3f0ccf06d3ef1570ddd1486e39c01be658fd49f11df59fb88a919fefe3cb05b54a77852668d8aeac9748be92bd34b0a392309f81a0a82214e70f8b41b79a2dc9f0507fb67aa720e669d02ae3cf88cc4e7b5331589939699929fad514e725231b7d49079f32c147321919e954cb6c08dc32530ca13da1b2571b02f40a9d15e7f5244cde5ea7a8bcec1f143fa1a5bd3234183e772c8d197df9cba45cf1ac02579db9c37032329b9598ef0163e949664a481aa0d9657a024563726bb86371a08c9ceaef40f1c6141e382313c6e828a8df87722ad33dc31dd51ab94e5596a95e41aa655f3e884ca20ae56815f30cf7bd6bc7abbbbad0d1ae2f4eb8ac81a7f5c443546d19de8129285be848a684d735e58469a1e69f12766723626f090d4d4b1652bdf5327cee7e155926e0990f54b9adcd5d499517be0d94b5ea5dd8daee71758f04c4a9b5cd6e829e2db738f8da3216cf5adbc06905c8818ad52b11281221878b16aa18b56c2aa315340e5a25c5d3e2eafc5d7e50b6e8065ead717b2afeebc87cb19ed6365f5ef809d516ffe16c9d5d8eb5ce02ab95558e564aef82803568f8a48a08422dd53167ad4bdbfc20290ecc21d8fa6bb8ba0ab6a46589a7eefa3a42f534e1743241d2bbbc0b03787d749190603fc31439d0cf1aacf2ad120ce6c6c5fb20938771b149f43e026432cf474080e8217e3dc47e0c511f20402f001543c7c0a1379d20b08eb3d318ba2838e82c47049dc022a2b9be3973bee24d27cdda6072dc1605fb578e0200c006b042e51407251089511120224a77e5a10232514ab2ed5db605bc142a9fc8dc0665540770518222190a19ac91d2e248a01e52e89a8642386e7fc0b8cb46ee05db80a92408f2b89529cda8f45cf17401c6591f1361765f5cce8f9b54d027a587c61fe5f71b4cd8351a28a8c3d0c2c204e4115df068a19e8732b8f85d1f862875d60a0386a43b39a8eccf9c30da8c02e9a3ed3aa7960bb53126e72731639b03f77174d957388b3c5ee0733d10b93b7f5ed162011d83c20549d4507eaa72525e509b98cd7555e190222851be1807da7faf66f0c07a92d1ba2343b41c2576de37ced509d48046c42e47b0399181f8b9a0df6bec0c394a37aa4b6664876b6b8f64b55e82261def4d82ed568a46acf1f8176bdd43d45226309518a373521149b37dd170603b771fc059397f43c93f9e55d84255e5b64655172090541a1b582917b6f62e4c8eee873c72768387ec1657482b8829975a362b13eb815413f674963b7c2a7df35a666a6eeceed566e8fafbe0dc34f4292a57333fd7dae0eac8083a601bb8247062b4be82f28ee06e96183bcc0180b8b84503e10c806a45e5923ffd2a2af88038310048d3a59cc5992a3180506a37cbd5a71f2014e1fd3b1840158e20627c5c80f3dbcd1f77b95e0b20cfeebba0f8ff635f56d4b383320c9f633916929378ccdec7b6a5e9bb83048b3442f566cf41846231d301e062a937b0f1537a73b7b6672450809d83ee153f5a3ba8c0a14a0cdc09a8d116025f91c2460253c6aeafa77b7851e53899e4cf958f8881d3f7bad43df94afe5097805c870f280f8fa19638d232ad72654fd4fcccf6c7f8edecc8f5fa5bc349c097ad2cac83cdd1ee532418c57bc6f963c97ada89d593a8c5f2457882840af43c0f41608cf998c0a9d10f702e9907e0fc6b1086a815728337f41a7e2e77680d4d5043c7beac03276a13d429be36c00d32154ef99d77ec4b30fa5077cd0983996eabbf63a2bc4ab4e661d6dd9a32a85755f32f1d9c84475149b57776ee5f0779f43e589cb19364b03d250a276db25f522459cc7ddf8899ed63376be840ba8288838d9287f81a58b0a9d43f52fa7a097e1f5822a660d494d5e7c4e1a5e35cfa742c7431eb88d11c90d0d55643adb51be4c7e5352db87c8bf045ca80388b5889f045cc8834875480f043cc8fb4c912a9182d4b5a7a44c809938a3549be1499889d87f056e48b83999d2d40292028bc8769c6de10790e51505a684609d609230a8b176ec323f69694d2028e6644a60b3c40ec26e9033333333313333319e98c0a9a6c8d86d6ee61fdeeb4f65392a95c38950f662a3823934c32c9947d341d38d56d6d377b9e40828d335ab9015e0ba50b700bfb0a619e05d732c4282120d628a25a8c8c2dcbd5c229841a7fd86e945229a4d2197b07a13b5eccd71b533f6ca2a1cb3f794e1f96cd29a526ad76cb3e860fab90590b1a64be87459489c8e0ab2793e8f4b0cd781ae1a7e5cb52cec32ab3bc526f7eb3944a78583407d3f3a1b3da2eadc61df69c65a9673b55682a155f35ecb0d69d5676e335eab08d964eee87f1324fa2c3a26cd3c7a8393e874dd6c3cae82c6f542f6a82ac847fa0f3400e6ac861971b4fe7bf6e21f282e2b0bf16858aa9c78b9d2513690d38ec820ca5c1746ea849758d372cb6713576e46ed07ab9400d37ec496f3bc773c7ccfdb7612f4d19ec73ec53a92e6c48fa6bb1a3e8fe6bd8bcd4bc107d39c77dbd1ad697b4955a4d5a7eaad3b0efa6552f466850c79c8594b225cfb098beff17bd4c33ec1d648e871add720ef68f32acb52f46f9d82f32ec4a8d74a9639d63d853c8dbd669f3ead42586357a679f8f6a16a44e0ac32eaceb16843297af5f60d825919349279df48575bdd306d5522a66f5c29e4a4b22a3f56adecb98b1a7e9d597e32b65d27117162d2b0fa5d933637be2c22644cec56d9993d039dec27a2e64cb82e9cda494a885fd63fe605a6a9c8535bf1a19792d0b16f69ca6e5174aaaaeb07ff417fcb396594c29b3c22af2f4c30b9955615d1f6fe5b2702dcbf94585ed547be549d5ade32a4d61d1de0d4a61fdb255324b3325b62f6391cda22e39a2e4d869a2b09a1645375c7c16cca550d8e57c9f2772945cd3f0096b904abf9259d809fb9cce5bb59d3a7d744dd85bcb39faffb510428998b0a7ed162ba6c325aca333b732ae68942e252c6aebf2c36e683daa91b1e78fbaa58e7726616dbd9d9b31a78ed023246c5f739e45e55aee588fb00bd3e163325f4658cec51cd31f63144d1661fbfc655a4ea7bd394b22ecc165cbfed3708d21ec21a59222e3948c2f2e845d06999f850b9be6f705618fbab264ce6220ec4a9792a2d6c598c599632c3aeb8c9bca5ed474fac122a432713aad9dec766af8604d29e6e59dcea9d1833d9677eb6f399a949ea5060fb617f7af4f7c6379e7d41063cfdfd26aba13d762d1987446652f4b4afab45863aa7a16cbfa8fdeedd1beff5d16bb30fb0d61aee5fc1dc6e24e5ac6f1fc590b2cb6efd4a1a5eee615db879d6e9abbd3ba855db16dfed2324817f58af15ab19c54a627bb33566cd2d5eaec9c196eeb556c5a4c9973bc6484e6508900a28a7db5f442ca345b2ad60eabc4c7f06a63f874f4f8e10381a062f3cddd725091b15fc64eb1aa5831ad6508bd00c4146b8c1accd3bf18fbd880946297b6a4ce28b3161ec4a4d837e93a5f1347b149311784aadb2032378106769cf8e0a14c46a0a258cb4f6b194c9f7eb18587ef38a3819b404142b18cd692bc1c659ae5d283623917aabc57e7e872584d90a901f9c42a5f8fce1c5fdc9c09174b49f16e0cf4505c244fac2e8997a5336c4c5027969775dc796e7e10082776314a8bea257b4c904dacfe51cb4ca9e46710be26f6ce8278f9f5e89cf641904c68ab630c5eaa4e4c680d402e618230402cb16f290fb9d31f6308214825d2d8161a2aeb64d00e104aec21b33019b3b3e5e92302904998b34e9f518569670f2209cffc7464906527031289a4ebd6f163360681c426e4cf8479f2528ca1f8e8f188d557aefc7aaf925a430071c47227549d8e5a1a213f9046a8ad7e93bea4fc641f0061c4deb9a3feea9885da1f0f64116bbfe031dd4a3d724ac704a598791182bd0351c4fa21d4e9a03c1f3c72989e145e4012b1e7555f1931eab7758f0865c76f16555b6b2d057288550a7d396f387d5ac728432ce7f2884f2dce208558d4658b6963774008b1e7a42d84f03f5fdde53104c820b615175e86501993ea5c1020825884bedbd459bdf800c37928cac916387894a004cb29932d94c916958a326965d2258b8742b11c2081d8e56ea93075c145a545f50c1040ac2fa6799097f3da9e09e40f6b7841787e9ca70b1694c800e48c5d2757a374ace6f401c40f6b9a8aaa954a7392310ba40febfadfac0c993465b6e801840fab9916fdd36cc6552d8fdc00b28745478bc23b3db3856da13680e861d572d03723f79b8589f3b0a8f9922fe39a5ef3550e20785895965f74593a896f00b9c35a42aacfd2cb253bec79f3485d7aa7e4765d873d08d359e5f332e9d9e2004287350ba95ce915ab75dea439ec41cdc4c69349ccb363e4b0d97decc713ba65ad6c3780c46193ab74476f50a5e34f70d8f37f37cacf4b2d395e1940deb04b26b785cc39bcd0b2920c206e58eba5e9dda0bf9aa34c270069c31a464b7fb222bf64fd0210366c9fb4ac654e295a1225b58645796e39675e16c78103c5b9388e03c5771c1080a8614d975acedf9873a4e0092069d865d1f38b9fcfb6e57cf00082864dc447fb98fa84c7d19c618d2a936f78dd39a6bc94d8d501c40c7b92a2453d1ffe5cd271b535809461d9d25267703107d9784271be0321c32ea717c3687e59c240f1b194906c41e2814a257502640cbbf8cebbd9b994e856a582b263870111c3aec3294fb752678add615863b8ef117d7a53081518d6aeff52d964e23e287d61d7b2d87185fcf7e8971776a5b79dc7e7c50220662cba540bf3901b74b4511776496e69c94539b9b0d6e9cfd154abc520835bd8ce955221c7d3a697755ad857ae5c59f3abd4ca41b2b0781c91e2f5b2a405d50282857d955831257467f5420bc815d6cdb296a58fa204628565d6646667be41aab09fe99684549913050815d69746e76e92d1f4f7371e22e842045b781102bd04c814d6cdac459b951e6c5e29854d868e294dd195b14bdbd2f4dd2b0a6b6c416dd8093b8d3986c2bea9ab75c6249367c67409204f58536fd52add63267ce5845d5222424d58b45e7231fcb82ce99809bbbcba34caf0d412d6f9f0bc39c257c276420b3a77142932164fb6e64a8e7768f72049d86332f1c9cf5b96f31d0812167d251e3bf2a2d869408eb0cc69adfbb7946749aa4c90a51e2046d8f7ec5b96317cd9fac7c34b4e969e8014e12e2594526a131c0384088be60655b3594a6c274d90f92a39590906c81036917f390a396a141021acd184542d8e30a95e870224087ba697b2944715086b8918919d73d8d892c93240c6d8449446a97f2245d809e407fbcbb2d255e25f4c00495dcc8cf372da1dbd00d283754e69a958cf185e14720184076b8cf242d98c963403448c4d34f99ae6121af2caacc52e27997923f3764608b980062d1617bfe309b3cf9da54a6316ab74e179b5b6c5ca974b5928733d7b634e523d2628254722028d582cab336ac60629564bb209b212d78183478e14bb1cd080c5a65ce7131eeb92cc82c604d9050008345eb1bf7039a85ff3982c68b862f59c2144fd4ec92c9563470e1dfc238587dbd168c52645a5ccd64ac98da965824ccd478a778179041aacd883baba5df123fc37ebf2063456b18b2eee4c55c97b613a1364c7fe73680069a8621763b2e55833ca490aab5ce7a206aa04e7ce0a68a462318df1f4561fcd6347c59ae5d22c7dee2c52a0718a55282fd33187777ab1638a3dc366991fb33acbf29462fdd9edd997b55073312820f1220424a4d8347cc911fa283629e4a66f314be7bd2d74a0218a552835d562f83bd37a148a35eb97f4d8eb7af1f01c281b0803c5bf38694739030d502cf256e917f2b9a5e7dc27f64ffd179f65f84081862756b517eef58b325bd83e75625b1d5ebf16d5c3c5c755093438e1dcfa8b2183c6264ca9417e4dec514c8c09a5a5bb402313ab6a29c4bd982d0b611b1a98583b85b90cabab372a5f62ef1d2574149e23af6389cdf3cd99b813d7df5d25d6f8d5b19da731374651621d392fc528173dc8989bc47eebb5d14eac24b1cb3b2e3429a5f5292114895d08e162dca94a579f430312bb50532de75f9d47ecadfb935a9994aa5d4f0b683862713965ae54a143b7fcd068c4a6e951be4e898917230d462cf75b76cc78714e8be034696fead2aca3d4083414b169e5b9c454cd4fec250d3412b1c8ecdcce795a94914f0d22f6d3c2b610cfe3ddb99f2fd038c42ee9d90d1542ebd3b2a4e501922d507a04aa1079c32ede07cf8287e9cf683e7ee8383101c9165602005088b8c1dfd14d797932226dd84e0a8d653af5650bba06e00e226c58f4cceb857f1442b7e01c44d660151888a8617f3997fcfdc70dd93913446a1049c3b6faf46e6651e40bddd1b0cd9caeb61c32c9a0e482640b122fb8c014889c614d1efa466efe54c40cbb542764e90bf36452ee3852197639a4d641bf95e731930cbb24725f8e7a3c81c818d6a83c28bbd39fb1b59018d6183da4125a6c41c95e534c504a702836c64509b8e06239941d3b4c0b44c2b09dce314a21a4cc2d99120c6b9249ebb51d5bbd20f285553dcad91929bbe5589119225ed8b40c724a33bf522ff594051133369dcc36cb93cea164162c8874610d72b3df49a5b8b09fa7666173d7733dc606912dac4a4fbbbcd4fe646b591a44b4b00b423c7d7cc193855d542637e727d9592b1b0bab782d3fcf25d11a44aeb04ba31e6bd59656d8741694d9aefa385b17348854615d293cc5ae8d06bd9240840a7baa96b9c5ddce04d9173956898e1f3bd00844a6b099ca98f3bdcef1e56a52d8658ceacfc33fb8acb343a48c5509256594d2b42d2a250aeb49ad17ceb3ae410a722102856d6597a7dedca7c921f284ed5627519ebfaaa4a7e304c56d508272f23d7494b40ed58b311171c21a4e2ba575d4b75f336a91262cdaf2941663b8133bab1ab84084097b6a7c99634ca37441c9029125a439f5e4ceb6ac5b9006224a783766fde7d5d0e728f1c1e3c7c90e657a8890b16ae9cb398ccecc25615762e569a95b0e12feb47a42571039c22ed8ff8d0b324a561031c2a2e5415c6ae7d75acc97215284fd2551da1d7647c61b89b0e65123c46ee8a4317912194486b0e9cc72bc3efecc6651611011c22e78521a55a8e664ff89046197f4b42cf8e9b013951201c2beff398b613c850b3bc12032c69ac363cb79646c952e3d20f2835b5aad5eccd25f22e2834db8f8311ad38eac8e4a2810e9c1ae7366ed0697536af1f360f15fd93adfcb73414f2262ec51fe6e142eac14d3826ac12719a7b3f68421b4d88352aae94ae43f660b99c57aea537616b54c75cb3141e623a52cd6d35f19e733aa5953482c36bf31cf966e87c59a362b427e54c9191984bc62d739e710f63abe7c5ae88a350b263ae3aed78a55ee43ba12ca3f938850509c153d4256b1ace8132e6775aa95392bd4821055ec193de8edc86965c24f1684a4628f2f8eb6a43196821054ec5a526152e94ddfcc33e514cb7e3ea5375566f96b090f941f3e1ca5a41d0cb733c52642caf2a895bc7caa29c572722fac545b9262554a45e3b9fc596fa909b24b18848c6211bea736f3a6ce7296390e3b418828f69873d6291aa50ef3d8045949c9528e92322414fbf8b9145abf92a2307c06a0d84763d4fb9cba3777964f6c5a273ffd19291c258ba517219e58ce3cf95967f1834e8a8f9413d489f5c58d9abb64797819c289b5837c9431689cb19519219b58d4282d8be2aba54593812044138b6e0c3add7c97894dc59c52babaab5e56a964ae104cecddd2f3f45b160b41a582e233e09143075e62d1515c962d66344196729696d83f99ccf87216d4280f9ae54b9d84e00c7520a4128bc9f431598fd137d526c850f3f000c91624cbc1c8b181149501141fbee3c43950a9e4192194583c26339756be188f77a59221934868cca4e479feda4224b17dce7ffed2b3502ab3cc2012cb7a9c5891275acbca931048acbf2a3248f5b432d70677843c62b979d1b518655ddeae4d90a9e120c411ab893013abd9d2960e9a20eb8116d2884d983e712d5b48fdad137694dc400823f8d4ab93c9299d2d310859c42e435fd47342e70d9dbb0d51c4be212357e933552a21895874f4fda43a6d44ac2e085ff9d1f64559e5217641c7adcf9f2423c4108bd43f3727422951235a424821d6cc4d97627a663a7c24841062fb20e534f506a159b08d1032885dcfa68c6c194bca151242882076599d6fc90ff9a2673878e46894930d9458482076fd65a2af95cc100288656396c7cc2c9ed4a11f43c81ff653ca6432b9e61742ced8ebbb54dce9d2820e2e3f2ce3fd2ba6520bd2934c1ff6fe5caf73e891639b7521840fab4bfabe4349792eaea65a08d9c3224209e972b8d362ba171542f4b0bab48fe205b9ffa0326584e461172a6f437f1462bc4b0d94a05209c1c3fa518dbf8ee9a7742185903b6cbf31e7d92ca6cea0941cc970881dd6fb0e2e2a132f9de53ad85c0942eab0e7a9cda7901bf3d053d49120840e7b944a5b79f60a996b2fc7a17a7011328755fbc5c7811039ac9be5cb9fb51c736dd01b86c421040e17f2865d6c167633f5cfb9d6a1388ee53adcb0c997eb44a6129d8f6913643f4a789ca842c1d1e3040805275e240ab8a8a02f2a954ae5a01d42dab0a891d94acb696379cf216c58438695a75435aaed969035ac36cafc94687eddfa74216ad8940bb2a3529f0c49c32ef8664126b142245bcca04f74f0c181ca10828645469d510bda2fcacf9728849c61fb2e53bae9ee5f069961531b7d4f9dda9dc7bf0c8b3cdb4e4a979a0c6b3ecfd4773ff25efcc7b06edad5ea252db4656116c3e6e96549d776470bdaf3a88108108584c12a86661002863d64969ca6cb52948a16f375c2037995780e141fa80b16946020e40bfbafa8ed9ddeb81ca44708f1c21eb4fca09b4fb79c7f9bb1eaa444c9b916a58e8dbbb0e8283f68bcee96b4b4e2c2deb176b621a334c7a42d2c3263929e54455a585cfc79dd197416460ab3b066d972b2d719c5c2befae1514f6c13643b1c8796800b2e5076ecd8e2845c61d3c1638e6273ce4156e7811f2626e81c690563d76e8e2ebd744815d638ab1aa4676008a1c2e27bb27676831ebb7f0aebc6fdddac2a69a384269a2152d8bb6318a934a78b423538d191828281b4e611460a9e2e585052819032d6d2f415ae5f990899f1a85442a2b0c90e1b56e6e516b528cfe105b21d29aa06d8450814d69649ba6c59e8ac2f42c813f6fa151f1374214e58652ee57947e6266cbb7ac5856c31eac287097bfa9879b796c48d0e97b086cca3595225fc5cb67c4918283e7408214ad833357a2bf1c9d846ae8d3a99b4246193abe4c9983747c25e623fbe3fa78fb07cf7e696ce83697135c2fa2f8afaae9adeea14618f5297da2a1922ace72b467e64eb4b0b0f615d2d474f2d6616c2362fb3f8bdb50a422a3275a8067be19472f010028475c3c91caae5f270b234c63ebeaee5782ffdc19a3e9f69592e211fa0738bea626c39cc83d2d8c1a4fca8c94cd3772b45878e1faf50d6437ab0cdaa8a2bd761080ff638361a73169396e2342162ece2887ceaecaf462d76a9636c30a9ec44b35c0d5a6cd2d7f48a1793de16b48c5163168b89d67f5a123a59ec19b5285e7ee1f208ad8ec5aa5cca6d1dbf7414b410d480c5262a66ea53ba24af6c0c906ce1058ae15183131436495126a90b16946c51e3159bdaba7c1ea5f9e713a624d470c5ea23f3baeed759484fd568c51af3a9bf706aabd4ed47a8c18a4d9fefaadcf85ac5be596ef5fa95ba51bf32418603c5b9a8541c078aefd8410d552c2fafa66a4136a9585657b96c212b950b3f2a167331664653b67c42eb14fba9d18da242a6d87347179f1fe54768b214fb49b9c2e5a4e59a900f2936f15b2b1e52bd72f91ac59ee5e9aeb5fbcc51698962cdf27c14eab44347a90ec52ad436bd50a945196318147b90f329d46a8c0e3ae9136b9916d5c90ca927160da7c1ffe5512756d1c9852d1bd9f128e2c4225768da208472137bfc890ca9a7475b1835b1a9ed289356f7d2e916cbc4aa2933bcb8a9733530b18ad0fac5d9142665baecb8c4fa2d970c4fd73acde98051c312bb38df652a5fb61c842a8c1a95d8e514d11dfbf31c752e6b50628d32e7e5f4593bd99b8f1c3c7e9c9178c10163831a93d85ed7c7f474dfd2792789bd648697e5b15a8c9a482c7f9a834b9b7ca3a71812ab48352ff8ff8bfb283f82d78216ff537304327facd6864c526d449f85109e5383119b102bbbb179a77943f1b54e7898a51a8bd8fcbe834bfd61736b7145ac4235eb28b5d3cb0ce244ac75f659ae537d9a1b46c4aaf22dadfabf99935287585b1c9d470b9d8d9a4519621ddb17e364181d54970ab169d1e53cf7b298738e2742ec32bc77444bb4189b0e622f65bbc9739020f618548b23aab334099d40048bd0529be54eb209b2c08d45ecb2f4c134d8aad9542745ace762beb31f9f13e349c4be1f7435e6b42b850811b1acc7d4dc2c4af9bf328758735cc66ee614efd83870c3109bea246495fa723dca2fc49eb4f0d92d434f76ba08b1ce8d689c123a83d83737b6cc963182587e4b8f0ed977c2ff406c5ad42d847841469703626f317390422617bdc37fd8748c1ecdcfb4986175c61a94ee2df32873de931f36e1a9598e51e8fb7007d5ab1f23f26191d3cccac6e5b393d9c31a5c3cade7b30e9eb6d7c3a263aaa8279149ec79d843cb4a881459e19dc7c39a7372ddab5c9ffc77d873ebd1d559fbd1713bacdef28e986ff9c2dd7558939432ebd52b377f8a0ebb20d49d2a759ac31e354b74ae520e6b8eaba4ce3a1787e5f4c7b49cb3381cd64c1357db1b56cdff866d6c4c88cf926ed84b9acbff3afcf9abdbb0078f95da2faa4929366cca3e9c9031c9e9a6d6b0a78e8d1a7396376e8e1a1619564ee8f051be05d3b04b6aca65a575a8cd68d8a5aa9d968bad33ec2f8d4e26f366d8d437be14a1c4835d8645c6acd36a1c4f3ae464585dd4289ab253e4a9c7b0da68123a98ae8a32896157cac519b96a18d67919f3851a3518f65ed1119b321b6396fec2662384549aa588165bda0b9bf8ba559bbb199beab093b2e5ac5f52e22eec590eb16ac5c9f511622eac2363f89847670bcbbc54c23465c7fe9c1676319ef9ffb2e48b31cec21afe41cbea847edd0b63617359095d27beb664fa0a6b99d279b71eb23552565885905da13c55854d9696c5d5123ab816a6c29eb5fa36de39854dceeb4ea5b74cd629855df257e24bd576852695b1ea92e98469b11485e57e5d96a37e945eb64261d334627dc2a66cff46d77c0b375227ec42a4bfccf3392afd3761d5b8ea5153cb3ffa3361f95517bb44c86b69474b58e59ffc502e8e94b0a7ec9ce53467bad5c7642c6a5d12915a49d85b48595a341909ab10afa39636e3c63d1d6117637c4eea65980bd508ab8866dde5afa58d081561d1f993d4c20b22c26aaba51d194353ae3784cd3647cb654149979910d6f51cdfa78517a65e501016974367f7ad1829b480b06be9645e16bd31d664a6724acbc91b3f58638cb7a77554c28452def0c19a95094f5a9a0b72cebcd183e565d430bd9eec05316ff06017b674a9105a92e13479438c4dac9ad4387af3f45f8b4dc7ac4c94a7905aeb69b14bbb1ddf59d2b79f9fc52ea71f99c5bbd5a82f59ece17250c23e885abd4f2cd64fb67bdf72dab4332cf6301ff9e9abf38ab5b5fe8fb3bf2dc5e48a45d4cb20b573ac88b315eb7ea71b1deb5a68b859b1664989d97a394bc6e7ac6213dd1874ac54b16ef806e539ff5b8e9d54ec8292ded20babebb29642c59ebda9254de814ebfca89e2e259a621da554c610e719ca83a558b4e74cb8f4b984cb2029d6db0daec6d5a3d8b44ea9d942f6cbd1a128f67fb571c74fa4d83e14cb8d8e62aaff4cfe058aed5bd4a875d42985b8cd27162f95d39fc527d1da7862bf919bc13cb61853c774625327e4cb3a859c5876cb364f894bfde126b6fba8a7b59823ba1ba38955087d23b305338f9ac9c4f69db4b0ea4c6e6a794cac75f6ad43a81ebffd127b099da3054f61a6b32516ad1783980b556297e9bcc5cdcd0b765262d352880fe1626e12dbca16fc6e7f5e94d94962cd30c275d4ffa7c1e522b1b92865a7694162959ae35a7e6ca53beb119b967c41b570f7333a8ed8575b8d7c31aa8d6a6cc4ea32a3722d646631878c58858ebee1e51ca4679d2d62fd79a9c589ee0df199221625b5e6b4d827d3c48958c6b430eb5144c4a62743c7128d35d31d62332173ebfbd4e2e8d86288556ecb173e752ed3a2100d360ab1e6184a733fa6cca4562827267dd2637d80e15dd8196c106253612ae2758a959f57336c0c62d52545b50e32a75279942f2a954ac5511ee50b83cab02188e5c57b31b3a54b9e751aa854167256680b3602b188baacfec4250d2620565f9d565bb20f62b3f587d5ce47d473f43f46f119cb9f8792ab75941fd617e5aecc4e1f76b5e9a2b49397e3e6281ff6cdd9ea3e57695059ee21affd7c33423e7ad88396c534f2b4924236d68e029481b09187fdb5b8994fabd3c2770eb204021b7858f5c86629345770b071875dbd24b5459d1f6b830d3bec77e276b4b47164ea8b91818d3aec7a56e3cdca9630291f6a9d51c0061df6dc1ce40bb32da45cbbfd8b39ace52da7d216c3a726a543396ca61a5253eb3b0e8b2979e2b749e6ed38c361173b69c1c35efc8645b538575acfc6d3a972c35e33b24a7eee64224726c8fea4c4244599209314d5016cc3aa332bfd4b57bc2c6ab1c1865d079bf94dd1b96b1acf81e2850f1b6b58f733c6284d5a162fc62e5850c2c3861af65a1de92fea204484aee3a4c451d0086ca4c19764dc2c8e47fd4fa518d840c39a5af9cfac0e32b9f0b4f748e191a3440436cec09790f131c9151b36416686bdff63ecacfbf5eb7231131b6550a934a965a941e61c6b1b6458e7ce5c98fcfd1c9e8d61cd8dea739ca22fb021865dfcbcacb47cb2590baf250c9b8907b16dd959581783618ff32d6aa1cfe5a03e881cb0f185d7b4c5ace5bab0e18535260f932e78549b8f076c98b1cba2b8cf49c9aa127deac21e7cb51cf1e286106373614f1f2f877252821db0b1855db69e955189cfa0d3643660430b8b8c9422a4c62cc396de04d91636b2a0504d996261552157084d1d64fc3dcdc0c615d6121f3cab4fbd9e1d5aea44471a1736acb07c8bb1bf461364294af14a60a30aebe9dfd3df2342998e36a8b0c7f77a08f923839c730a6b50726e53e87abf7c4961d7c174c94619fb963cada31aa528ecf2ba2c536ea5f2959a4aa552491c36a0b077c788d98d424f58ed5f6cf8f852e2b93441e6a324d1ceda70c2a63285964e6951ea50376117eaa38d6dcb58e672262cfe63a7feb52d66942d61ef97192f2997c93f26c3502828eaecb0a18445bf4606b17932167da3e1f28792b07db6586ac676347f1c098b69d4a752ac8a11cf11f6d00d2f3e64b7961116a52a3dafe6576a3a2ec25a724d9efc347ad399445843a38c2d57e7e5e23384c5754a9d49ead4dfd498202b0903c58799221b4248bcec749fa222a548b011845b72e9a5539131a78e72d22620194108480cb2018475450b2e737a16b5dacec6185659367e60151f58c5460fac82367860151b625845118a482dac72446861951343641656512088c8c22a680c9158580516564941107985555c6195565885155659855554619554580515563985554c61952f4a611552586514561185554261155058e51356f1845552a41356419cb0ca26ac927820a209aba40d443261154c58e52e6195236209ab546251d9e8591c3112a1c42683e9900effb101c42e4426b1bda03669de11a773965723895d8c59d41db4922db6e526c8d2f8fc20594c17442261154858650b228f60756e4711a1b4734c50a9641c441c61954658e56841841156b945ac71f64edeba2cbd11274558850c9144acfaf3e671a92f4f4d9f800822d674ea73e8f9cdca551f624f11bff61fa30cb1bcda90b1cb5c1abd992d3c078a178558a3ebdf7eb572c5b39c0932e6eba40b24c4a6e546696232993aa90e6239f95cc257658bd72d1d8a078a49abeef1a3640627273ad09178c1011212906c91be105109d9c984c85999482014912ff3775ef3396f200288e525ad75a6d928952e91c81f5657424b3aa39d8e226526c83aa01a1039a3cff9176e5b09f5cf7e7091010d780e142fd47cfcd8c1cb73a0f848227ed85606f918a7f526d2877df64e7db49c840ae189f061d5a9c5bea0715fa9ba8755b8f02fbc72f14bb3d804598240440f6b54973e0893ab09b24629098387cac376aa534ba93a35cb5956183c54498a5a3450a9a4a0947861f0b08787ffd3db624c9081916347890f332e7cb88e1e3950bca854c0c8e101bcc3ea82ce51a80821113bec9f5676d2baa5532b74913aec4a67a7cf479f1767e210a1c3261b95c9a8f7d24751f5304b640eebab5ddffc5a8cd1fdb2504e4a4a78e45028cbae06227238eb339a18adbf364156e2e3c749b23c2488c441fddb5246b39820386c7256fc6567b1c497ca04785e41228b4de80791f1f56782789c1c3467684149511e3467b964529407cdd9594e529407cd192e9814e5417366169314e5417376cb254579d0cc2c29ca73864600a02089c5a6e5d62fc60c1258ec41dd0b323f328befac572c5a46b12bf6fbe44a6f166e4f36a8159b8e328b32f56fdc17b358b1ac86c7a874e6fb24e3552c3a6821ee752e2d4d67a962fb9c6a55ef88118fe254eca2a7cc9743b3d0152a549cce5fa612ae2406c92976dd32a79251a58c8f4aa6d8f4e5d3cdfc493b48af14ab66f9517e872d9da51729b64f519e79956e148b4b5d26579d52ff398744149b906aa71bf6d1efb5c03841e941128a7d73d8d2f9fc40b19a0cea767f6326c81ce5478f4fec3a7cb6f098837192e33db147f50c1e32da98c64e2736a1f25e8c2fce9aae9d136bc717cf578a1315fa6513cb092fd7d9424a139be8672499585d6f2c6df96298d88354e7ad93472163be2fb1c797dd272de366307992416289e5f57e14974f76522e4d04924a6ca274cec9c68468ec4c89655c7ad677ab84f44d27b1bdce9b328cbfd6d25e24b167a613d172cbe14fca904462d721a43a9779a3cc701e1190406239d37ad3ad963eb6e22079c4eabd3a87ea95395969031247ecd2c6e5f22cc52425078f1c8f6090348211cbdac94d1955fd95943141765f902c625ff1982ea71eb1ca65fc074ab72ae1a17a391f248a2049c42af5495959dedda2273c4a14850411bb5026c369393c69bf3c0fffc2510eb1cbe194fc1735c6de9a87ead3416288d54fbd9cc52ea154bada04d962322029c45e1e73a428f92ccd7f42ec3a363b4b4f320b2ae483d843aa6e0e6ad2342d8845f37aff68995487b902b1ace61c334ab901b1bad0d2a7173fff613b6fa1c4ac2b699fa4ced8757231ea878bffca547e585ffaa459fa0c6a34d73eec41cd77e83c2bb32485f8b06da8d4b296c3883813dac3aaa91e469768d1c50cf570d4d2a1a5452d260f7bbd5e7351ccbee3080f8bfffdcb207a3c8e78877d945411999bcfb6c54c90f950283e96e305e00c2476d8d757a3d44e251b85ac8620a9c3a2f2c5981932d46a87e9b06e07352f151ad33c9dc32e2a17a396d05aee13b3102472d84ebf43aa0c7552732889c40b0ea02d90c46179b1343c3ee79c89e908410287bd7463342d7e28176f2d7147f1c179059237acf59f5489062de72c88ddb06f6921c3837439832069c32ec96e5e59f2ea5cca822061c376ca25ff3ab3d7b0f76fe8c7b8dcd3790404891a56eb1d5d144de23f90a4610dfea1515b9631b6a48c02091af69239e874f1659db5283ac39ee1ec4cd7aec9a0f566d86599368b932e2dc32e43e894ebad564b3364583db9a8b6b4d09d41328665f587d1e8ad93507512c32e8dd4a20ab939615834e7db5dd372597dcc0c78281444e20507ac0c124ec699f464da098a01c917f66f1965fee3c8b880c40b9b7c8cdc2da91f439a4c90959c2c1233169de5a05ebaf8f2e5acc50f245dd837969e15539f0bbbceac467e8ebda05a7c0bab543e1ff2f4a8853d6d54d5c95b8b51659a85357e3cbbb9efd1f9ef3e906061514a0b1d3aaf57585d94e5327ff84e25273e90586115db1dbcc3c7ed074915169d7b6966ca9354404bdd24659c93ea5128253e7ef4d871d249328545cc6949293e725081440a6bf2d918639af3995acbd8b473d697302d2961341348a2b0d9cb28572a2deb4c42058565f3c3874f2b755a159fb0e639353a272d87fc487d2894dc0389135665a3dd695f124aca9626acfae3cb2742939ac62813d68f752f6195fa63fa8e678cdc9712d68c9b6e5dd499a48c7af44042c6ea62f3aa068fddf73a49d8bf6549c6399d9ac4a991b09ecc37ca74ce8f1e8447d83fc684f03b9711f69b97fe7368b251255384bdbc4628e9a24b9b5a8c792021c222d49fbc71a5b69be71076e9b3373b2ba1429f8c10684012844daf2ad5ff592697560d84c5a59dd6829659a8996e8c350b2dc93c23275eb0971fec82c6b8a02a6a3c90f860dda42a6c95679499cf9812487ab06ae71c7d4dcb72d251eaaa40c2834d8954b33a6c147fb2e5ee4022c6ba7ef7323669516bbf5a2ca65727151d1dcd7fa6c5a2991a1a6b93c6ca38328b3d85cca323a45a168b6a6155accb555aa36524168bf23c252c762d6999890d9bf7f99157acaeb524fae5e0b5398bf9f8b1234330e28a453eef6569b55aaa17f45e02f5c0482b7619527ba4109b85124256aceb1b64d0a26e3c160e23ab58ee85902f4a59a6e4f7aa5874c64fdf489332ba701b4652b18d4c62c5a8fab0d1258da0e2ee3ead7f767423a76094ebcf78ded2cbaa549693c48829d64eeb1b1b95540931528a739af24e179ae59d31428a4557799efa8fd12fc5f6f6b6388c8c626d59d082cf6f889ad262c7881151ac5adeac83761a8ffd9d0e906c41c2010d6ca1a1d8b7b360aa577eb8f23c28569d0d2a4ce63eb129d11faf952865fa674f6c72ea65544a83f99edc893d46a5794ce378a73f7162d7e2be209fbbb489edb48c3b1f4d9bc7a49ad8b7efe5281f8432b1a9c6122df54498d8fe834cb13129e496ce2556dd6957c4bcb3f0ce128b58e9e7510b5662975ffa4789fd05955aaebc6d12fb6a141f476f163d92d8a5b42fb933562a551889c4aea489c8cc716f6ec42728701f275f542aeee3e40bd4c2082436399e858d234746257fc4ea6290bd2245cd99923ae182648b11472cfac5f4ff1dce8515ad11ab52c265b91b7bfae239c2883d446a8c427783f4a89145acd265a1c5603a8cd01995631851c4b2f9d2ef7d8b2fa6ed8c246291dd3a7ad6fbaf65adcbc123d1610411dbbe2c08bd2eb4d034a743ec7daf465bf4d5ff2d470db1be28d3e3e898c5175f8c0ab1794b215d5efb14f22d422c3a7b7f36458d68ea06b1292d8da64da6a596ad844e1811c49a2e83ad0ce23b6814324d1809c4bea65a94e9c5671dca63c8180104a619a49a90ea2b8cfc6155d39765103a9cfa547971c61e954819c49a5ed9f9f7c3aa84d8b03a8a97839f7808237d3868794cc205d9b183968ed91ae1c33a5b7a52758e7f1e9a09b212745b90784185913daca5a56cb1b9e961f1fb9efb19fd481e1e3082871292913b848cd821250c9f414a180e021b237540711f293970380a1d763860640e0b189143ca0f068cc40164040e081879c39f9ca0f470430246da80b263c70e2e0a30c206088cac2147d4908612058ca081c6c81952c2483143190c3042061e270c1819030a0146c4b08c8441870eb505184246bee085921c3d72c48c2eb87fc9898f92112eac12f78fc0c8164a68502232a2852c6081012357d0a143b50146ace080912a78f338e151023242851c3d30a0011b2353382352201929e300235180c203469e90a307069c55061230e2841b234d503e4e7ed0a02485c60813964032a284921c3d3090a2e3e464043746c888c048127404092b47890f4f69c0c811523c478d1123d420470f0ca0f80c504e526063a40829242344f01ffe8304cb71e0505e48606408294248111909c2034680504263640c078cfc80c6880fb830c0480f1230c283038c8831801bb5d8e40a17ffbc67fff7d4c10d5aace9a26759de71af65a109b214b4831bb3d8e5ed203f4a2df7fda926c86450b24e4e70a8a5e1862c7699e5de8fe97b433766622ec7e7407114e48d58acfea17b5d909a59d053ba018b6d645db27f996aa6a3afd85e781417d488b09767cac10d57ecbdb1c52442cb92cf4b6ac522e57594f26410ff9764c5f22d4b8ee957762eab2409e1c62ab657f2f274da52158bd255cfbc59963b55441fdc48c51e5f6a399fb739b9e841c5fe2f49fda3c73c6bbd3123f1820362dc38c52e37c8062d63d6b7589962cd7b22b3982f3c272d4bb9518a45b4fe78624fba50bdf93ae9222d46811ba4d895588d51e37794d24c3746b1ea584abad40edf775216dc10c5e2c1b412f5595c7fa8e04628f2cf42b4b6c423f87170b8010a8366b7a0b3438890e1a2c67a29f6c600188a8b5ccc0b373eb1cdead81de3233eb4dc139b97c96ffd2a29a57e756297439a06f9c1e6c49e3ed34b526abc8955ae492dade9d5616cd5c4fa234fc89271e31fa34cac4a4f96fc9caa2a9b8389f53bc6cb05f928a78497d8ec650aad539f25f6a093d6e94b0be2d46f9558b64eef6b59d0728312cb0bd5bceae393587cf374bcf8b3ae7c9532704312fb474fc26396b0d7511e89fdc4faaa16b49c2a840812abec98fef2aa0abdf147acbf1a4e4c834a2dd7e988c5574457eb8c69c422c544cd851523028f3ba874300683692812070362184541008fab4b009313000018101c140603b158340e2551fa01140004543826463c2c1a3020148b48e3e0381c0e83c2c050200c0a034161502892c438444399db077ce09eb8a418b6d01997e82720378156416fd6484827b720669c7dd1bebdeec2d6343198671ed7bfb4b9d72a1bc40ac98ebae73eee64812249d94041c42da618c3042ebbd8a2d6da24834819d95df7b85f0b8d561a210a2a96d8c414e3706791165a636b1925d8201bbbcd7d596e9cc90b0564157721bcd3f19b162f113ed20e47eaa28a11b14a0ddebee825403ae800f1354aa31aba467fab93d084ac5110bd77d01c9515d5902ca634225f0007afd99aa02ac7cd9e255f81cf5b89c8f6a83fb1c958c2afc02d9b291fc00297e08c08b193404b2eede91ca00e1d599668a1739cccf560e9a6cda4d57aeb2b117da5f496103a9718be329a2eec4e24c64f46337d3900f33ff6951400da9ad880293cf1dff34636854523b99e963c7eaaa8bef68e9270ee82263045f4fb4decf5afcae5d09382448aa875ff415a4701690a9a4b151be133790aaa7d6dde7594c16c75a54865e6dd27f503625f6311c7a5f129af3970ff54c5bad7771420863dab0d1bdfe3293cb70da916bb242dde4afaf5d30cb00486e9f553fa09ed5c799e44401dea1603014c2c0669d9cf701b62d0c83f3f4c9b0669e5dfdcbd485e8a2b11725aaf3978617171690624e89c90825b8d6ff6570dd97a7d6f27012149c852c9a1248c85819a556fe085db6314675ea8f704236dbca106efa7f71e5e6bd9c71be185dce4f5abf1f9d059ce8328ec5f44f2d114733843e3a725025353868ec0d2d2748ee5282efedc5abe53d17a781335efb4d3b0262d714c32b29afaf01a203d3eeae9dc53b937ef13d9e2d337f36a6a61ae70eb8accdc2a75800ba6b344c3f8977bba4ea4832dbba8419f4bb2fb16206d067866577282b0ee70d0929edd335bb5f22a5fe2dcd14f88165e10ef0a755d9e248b99d66cabfddaae9a78833fade5707085e52e09532880ab95b2cd1694276add023f3595d3a495d37509ee210e6ebf7b115e3e96376df730760fa169f93ee8091feab910bdf11f37da4d04b437dcc71bd219f54f36f7c1defb486f3ebebd0f7bf3a1defba8b77d7c56b3c660bd313fea95418a1e07b9b947af58d0fe2115df33cac6eda06ca0dad2915943ea3502561b6b044177018c44d95ddf215093865c7bdf84e2e7142f8eb725e51c50026c5d8fd475335c647441fd11cfc446f608fc0091d18e3c651525589909a9579c92b49650596755a8000a72a8da709e55080dc3c10dcc0cd2abc245a0a7ca06c4184dda942dd042ff57dfee002ce229799c055f2a704fcd4c5342c149b6af6a11688452c532c4169b7c59919ceddb0230abb133aeafb6f5b3ac9e31c28835f004251610df37e150cb8472923a30be3e6e428d2852a85c566c82581b4602591798636cdda9a452105a99197496e52b8cc4fdb11ff9221154495901b8ba7b44106d2e40d575c38af7a9fb16b71fdbb22b0a38613190dc4350d981042cb0f36142754ee13d4cc63abe83a64126caf2cc0838f2f6bc00c090f8727b52316d075d2c9f53d7eb5e993f7f3fbc51ab82aac0d82528bb2b321096946dce650f8b12c432a604b6b4f2a87da31c69dc871ada2790b99bc619c5df9352225d1e6929c298b89fed02454782df1087bdf677d07f242ca0292ac838a4ba785d43cdfd82ce66b20e07d2f29735b7e5cf0a67ceccee9bdf0600174eda1fa6fe2497c3d5f5c0e222630c5f04e8cc74865ad3210a328e4374c45146988f0dcfcf0db10263124ef5161d81a8f74c6868c225e9d93d4271f1ff5fa6613074659848ebc5e482d0a852aed60c28f96b32dced63797ffbcf75cefb6909a3ef2663635087cffccc89df33802c978109e43d9856c394e57f4a8f64517c5030c1c0b19001b8a5de96e90e75623b0f3831cefba4c5d03bd6d8ea70876e712316b1c50675ef90b62815af3583814ac10e0ad02b8ba5defc1c6a6a51594551214b79223bccb98955af228a14c53d200094c3e202d560b7a96a339aef4a7b417ed29d90ddb3d9127104e4252686c95f968de84adad07255a61f35721439a85ad31480089a5bd5218d351268f782a2a99fe35388c33c06490925c5c91c352525440590c695deb185559a0d2dbe7c019c5d018bb569386e0b81ac3018b5675501c9b2ed9810a272dd959f0481b24e120ae46aad687f880a92cbe584290206be82b63a61016773041273ca51f58d41415bafe5a451cc5c77ae09de4a2c045c76052c8636435d2614c81d5fd13747320f04280111dd118dd0f0b79303628fe01d18637ab04eb8cbf49c326b50c5efa282b4f9e788e290f0d79853a068eeb7e04e99561774239612c1cc8e54385590a8192c937d94c41a236c53c6c4cbf41525bb996a7eced0a5add8ed41005c58874551d17fc1011e8d5b52a21c52b1328d8ad3cbc46d6289fc9e767e52034fb1eb77c68784dea34ac31831a00f855255a690504f5e3d8fc0a79e142383eed054d29fe083b07a31da282bf882402860c83d52a279aa6b4f3a7c69e554eafd7d4bb24436f6a34e494ce2b5e3fbc102adc228a7682abd7c07c40b605232cdb210cab4a498c4e5444c65f12293511fade99cbbd0ef1df16916242f9c5092fb1e843ebb2297e1e93153527d605e4450e2043fb33fec93855ed8ea41a5aedaee98c4dfa77c8f174b744ec227450e481c11121beefc073064a4311d988887d2b1b342d8504a4eb2e8270d31280e42cc0a6ed48d53b9f02da649da8fe97dc6856a4801e952b4b0a149c670618398d9a652c17b20dccac70c2b08375fd44b80b8db44c1742680d9a74967d15ecf3104c83027fd2d612735506a199eb6ea8a6f902ec9ae0cfe06b71fae36c01d9172fc2d0a1c4030644974acf7985815c454f738c1041c3b3533a4a02ecd20710c71d4a614416b2a3e0b30c4a73602d51a43ac0f961822a5888f2e3092228c8c36078942236544ae1eec3d371b5abc9d5081c35d85467848495e80b4d064bd8a54701e1f29e049217b534f21623701278a8d3ac21d46bba72414dfa296d0fc824f5544e5882942400af943f08865b9564bff8f94d7a471cfd6d52c12288e85806c7b2429a7fb1ca9d240b11abb8a84570c83e0108cca6455ce6e31c933d1f324d877706948a813150ba86523810fdf525ffbabf858c554a8cdf5b3de24726d1b6fd00bc0079c7b5e4978ce17be4aecf884a4c6bf200c220627b8422824dd963638418da3c38c67a07b516758cc500de149e2a2b71e10b09838cbc1d74b6c4392820505f6865690c7bf15b6e07de06122e6cacc838c980ba880003d76397009a8a871135588812fb1fe430b1068bd5f96bddbac898c1c5a1dc50ce90660751148594904f4e3503910f3dee30b8c5c1e403f6252946318b20df35a28d7492190ded6d5dc9c77f2ce4b1aab75cb62b5d7d06880acd10b39d5329c86169296cc071c8ba3b318d8ceaebee71d8a172c8516d939c89f9689bc8524d5dc8271d58abe29b9d606b2575e305c36e3747d95af59a2c26aee123fb46bc2723fc7f4d982affd42a41292de56375071a0b958f46cd4be2d2cfa1e4721d09a020da4a7b9a69cbd305d85c4a040574b0cecd249e25cd484d1eea3b3b4509354348fbcfd0be00a2f8f22820d5de69dee8d510cf38a87cf306e232d6b0c5637bab7e26b02f05ee880be70a786d1d7488f6ccbf22bb6e11b82664dbd41ad21b9d18a49f6cf8915c51e8df1456ed340a2dea136154c4b1c77238c138e2939f5ccf0046af32a45e0b4c8ae27fb6209fe190ba575154011f3883b19f6cbd87203d8494191ddfed51e8199da297d39946c434ff275fe589a841ef2f5cd3fd03fd97fa5a65e4174db3161bbebe32846ee9c184ba13f43a8ff26bb236f09519da6f76115d98940acb844ed15943ddeafdc2e78706764da7df7b06ed75d8b524d313d2dc7a3e10f730d5b0495fab3c1cb8a4cf7ec21efe7a882e9285a9040ac93197258b3e308a1428b22509291b308622ae46e60c5e163442f88e9a8ff3141d160398fc4d70a96646e805a938ce42e6a1b25c7f2e260ae6c15e9d23b8baab502b557fe6ecdbab85a500233752a2349587423b0c728e737de639f4d7ac18da6113b66ef15e125e2230275501c51aa90975ffe40d01b08f7f621b14b0ab7a9ba00d559d563d7ec226eeac0376ed27f377108ca7282eec5d31b85275947057e66c7032b78d16b156794062db5282f47a0dbe3da7dce6e86cd5e3a5d03e877f96d7560b037a7cae70b0080e033bda0f5c1f7898b489b942acbe8f2e8d7020676b08090a50940827cf72010b37348a83886d24ee5aa27181d801c6e684a1551e5e842757162e306b61b530e107cbcf22b5c131a850033818b2e2e4ed8fcb44a5d6ba0c847c3d039322b6f6caa452eceb88f9c0680a3050c8969d90c4889b8e27b08cf699a54b870a83df47599c5b7d83b54c816a40adc1e447d2d1d6e9f0fd4e3aa9375dee65ade73b01a28bc291580656d1817f24e035f6d6d2999852d746edb436ba30b56c17796898576452b5f0aa3ecacbd5d77b0f4b50e4027e0a36b33907fa78ee783b0f8468fd1ee65b3f6b6bbb6fdde02e8c76bffa3dae2cb4c979603eb37b070ed82792531d1d9a255c8b2e988cdf4295dcd9763f86d70a74c8a0b1fc0ad522566a27791ed805439e4883d769c4cfe7688d109a7a144d79e1707f1692123da5a77cee384339018bf8642b81825c2c42260656a8048eb843b351967920c918aba9b340af36a86f780e8b4b49e7ad0b1aaa871ad6958e677058f1b0d604c1532d305dd8c0b0b5c54f0cafa3d38d2aeac42a848954c6d167f73e6e3305e7087c96cd625786f87e9eb2cb75807ce611270734d0947dba667bed25c65b18c50013d524da464411db196da891a0b8cbea9526bbcf5b9be5839a8cc9e37138a7365e4bdbcc2e25c26199db6c96125f8841a5385cc0b56c082366ee17673b46d7ae62be75a42cba099f3b9ccc19493703af23c5e3c5fb0a3dfaa5c625c193b86687715d75b71e82616239558647aadbab2332e25133518e6aa363a11ec5998da32662af7577962e5570deaeb8adc967aa939fdba6ab5895403c40aa498a77c0b338d70e9789b5ec334452da36432561b53bb1c56c82440bd5961489159e8920d1ce0f5c480ac39055b966f3ced1411eec05b9f3cb90059715ac624d12c6385224bd750266980b9ba37cc3377069c4a53904dc9b273cb52e94f65a27085eba8a636198a35410b2269482fd59bf67019d7466d45668ca0976365bdcef8f9044548252e99146065dadd31b18d29ff8dadd4b07628ae5380ff1ea936ef22a02ab11b32b676222b3cb572c897cabd7631eba5dc237f690e63a232c4255b44fce1acb6f51b971bf9b6a659e04e523ed8ca0f9607d16dea2973b7b85560704d34c70ed891d5ec753a59a950cbccfde8a5418639456d5b16b516a686712309128fb11fb1463b04a4797c2758394a60072128515f83ab74a94364658d278f6af7e3487c4af4eba87edbd41c6de32ee7bda12b94174217fd7e0620750ec16c3a50cf8ae1f58f6e5ca79366d07a0be1aa0e4ea21f198b078fb87473aa93e62cd8314d1c9d141b20bbd1c5b285556e067ccda85e82359cd5f0ca56e7c9a4c2b94080879cb9c6b243d28750126f775c18857fe6216f43c7f323b1782dfc4707dc5d378bfee0b7137544717b84e7d81c49bbf4e3dafdaaec8b5256419339e95bc7679067841dd37e3220802d28d8691329377cac3012061959c5a199fab2e04cea61cc594348209d48fe1c804a6f89f82e5d95c3629ed4ebe7ae08d50927edc0c0eb6762d08b41c595c70bd719f8d00ea18cbb7de1f856caab7353c228872727a92580588a5a7cd39da524a5525b07daa9c55b4d19276727c08a6eb82719eae694663fd67d4fa5c1e9c988baf8964fe64c856d406a056b6fc309ba16926bbb27c64943cc7ceddfaf6bf0713fe48549062e946b5ffc98c8f01a33d2dd092680ebfa916a6bb8bc80b45276d56b0dc161a1c24db3fbab4edd7141fb898599033aea1ba62db9ce5ec712a05788b98223c28686a6227912d81ecb28ff0922bfe157f6f4397c56d387fe81afe256d00c3e6d4a06f52a8f03221df35e91a9feea5dc3192e833baa098556796af3531e859ede4a491e61f24cd92a516d99a87b2e669bc6c44bd0d6622983901938674f21103e9b15410bd31eea594cfc974e833d822233d0a6c7e384b36b81ce9a5df6d7bbcda96f31fc5913fe14d31954228d141c52896d4cb21d4f0f7d959c99bfa35702897231064281405c677cf5842673f18e17441a385cdb68b036ab31e6df18386f16cd89c3e480beac387fdb4d6cf9388dc1f9c6d7abdde851d806c3c14aa52d449c07cfd6aa55e7ba9ed83faae7ac16e4796deb4061cd43235f9a635a8bdf578ca41db7e4e797e44d9d6e8e46bf500d6d93136de6d447ea3f26790908303a6047ee83682c2c0db3d43e4fdf784cae8013de01e7f8f29f88a83a269938570d671e420cd66180c53e950396473b51d26aa4ba07399c3e6706b5a00e03b2f429e25498b3b9fe1d290a449700cb2317b3f2cce26a3e73abc7f1b68321db07cbe37467dda8ab72b2ccc1a3af3bf8a138c26284a521a7b6bac1e0c5481c9b721fe08371762b2345d454d02078812ece9a101460b66371b6a2e6f16c6de55471b68c39394e2aedc6bcd9519cfd54534c826e13679fdb3f40d54e5725c80b6c9f7d0789b3e53cc45848c35197dd1b9485385bdf1655a33ba05693cd19ce3f9c55df4440ee4d121f840d10997538fb67d4f3ba5e1a6791a8e16c11013c1c7926f4d8a2771bd2f8c57076da9c2e730b6767cc0154ea06fce1e414cef64c9e6dd84a386bf9db8d720867cf1cd0eda2111760c8c1596129d76fc7035a2f73066763cc911b12ed3598525fc1d969b77a9907046777c1ece68406ced6321051ccf2ad1238eb22490fff0d2fdfaa80b3ae2036047173339cc000ce0e31487b72f7e75d61ebdfecc9e7f12ce36ff6ec04a86e155ac0c9afdfec837540b4f09bc591cb04867fdc01930ffb66275a29c2ba9c8b870d21a06f56c7c4a7433615062edf2c42058c776ae8e3ca01d0fa274ff068806fb61c10f1665e60951935415c43d7915aba1e607bb3c5540c6ba95e9e63addee7f188df3a5f6f56db8cb7aae9cd8acda7836c38bf249395a29f370bb5c4e207cb2a33e5cd669b1e7f4300210c2da43a1388eaa28a4687c9feb16fee1bd105e2fb959fe28c8b7dc4f020a8cabd7c33f1a9047a42bfd15a02b85a56f5f654d59b3ef1f615d5fd9a1d8dc6b031d086d1f5cae2b438364a916b142e935484aeefb3df6d158517684fb41e198f07cdb5f21ca5f836f098838066c1fbbf0f9da8c518e5103f1ab9b991d8be8aefe88cea814118af4127d0372e1eb02286a933cd39eba96efbf6ace0728a856d7bf694874d4d4b65ed59876f78ee9671af525cda48aad964439ec841d25fe56b258acbe54ebd6337f8bca1e300653a19477a24d6f89581e7cbe862e7659e556638e3e31800185989a06f80bfe8574825935d6b52d32a727f5aa801764a7dba901f95b5cebcf362d81031e7fcca8327d0e64414a508fe20865f2b300b3327d7f62d836d272ec5a5194702af04c30f25f7225e3584e71678fa1fee9d82cb42250bc523b8fe5707dc3502bdbe2c59a88c0c8eb175f66a1b63a4e9e246c22f4d3a4c3fe20383889cd9854564a2224deefc98dc0a4f97a55877178b3a38acd184c2342928545cb4d932829f5fbc18c367547f249dcad2f23645194f39abea5a52142a7ca84cd57e0bb3c00888c25e16cd550b03d69d35135144759cd589c23fb9dd413691ee7b00c33c5b0f1e6b52ac9f85eb03d037f59513bc08d5e63de30d53aa659bc38a48d9972c705f8a06122fda3f4971ab64e1c8d21d8a5f0883dae18ad278173bfdc0abd4d4a47313220841e050dd534eb604ff3566495b5229c05a8b41d754163b759a00688937acba415114be5fed0c56645f2dde57f53d9112efaf3447dc582579be2532f783505c0313fb92b66a6c002a4e0117abc163756e1d3cb387944d1d06a5797e61b397b18911dc2fac1258e6698023d6a3330fce499031bc4564779c249d231064bdc2f03c00cc6af53753082c7e5abd901e3f902f72852b88493d0074280b52b30ad228e28dabee1d14ece39b09ae9193a97d264fdf9e4bead2958e211338aa76c8d045d5d2d8e98b50c7417bc83f11339bce7699ee789ddb15462b9a7a2189863affa1be3e1c6e725a7e9a5becb168644217ce659ad935912c685d13ec3ac37ebc74443d2ff6163020acd8579ba5f184930467ee27af360d51b49720773d41088af5a4928184f9b6b8c3982152ab7029100fb708661e005730eeb9e21089e13d4a9cfde5bc25dc2618429750baccb36bc7a47201242478ce2e0c86525bae9b2effd5a35d33246af47cad065c2ab5d43f1f77b82761a826209c971b3204fa5ef077c2c650ef7bd4dfe080b51f28c852c1d22b1f2d31b647e1b358d4784cbe17f363f7a14e70e6d2a16fb8d8b6d748ef3c35d023e53c35a3224d9a50bff7e750664358da9201df796593df1bd1efab1c5f04522c777c37a4f714169d640bc150257dcd50b94522fee71939f5fcf3761c728110d595082fe51058eebdb3e093780797510eaeb2f723917a9671cd3cd50da32a8054dc36207e15974a396caad629f2a8dee0de63ea7250582e755df73f2f49bdf35e024d96ba047d1684c6c03031e278c9758f2f1fbbfa148cf9fb2e6f42250554b11992c8442109edd857a52da0d9ca9273492ede6a58656725358e199218c57d3a52702e108406d7c5e529db410d47b15e960ed468a0717116e463d4cc8537e8fd190fccc205754ee38f31fc30a65ade4aee5ee1dbe751ec5de6862b04fb1c8dde6eea5c595bf176dc14cc1a1a375199e878265c207ab6682e3cba44490987eae68ec4534e97835833c651e200d5eab319db942161f0ae4e080a8a94a06a5978b84666ed9f3f8fcc7c5ae9179e0a9a73c5718d0cb88da2f0ce1ac255a9d2b15a9ce51bb71d4132f257d0e9d4877cff31998f8d5fba33e06150522b8088a66bca5b38fa09f04e6f082a83aacb036cef880c54b234ef24ef0f9e5e11fd9d780842dd793c31c9b36af4d3279efab048e4bfcd523249f6bdd60cebf16e0a242bf05801b5853c1cbb45917927c45a07cb7460599e302e3ddabcd69524f90d763ce4f12ae59aaf73250bdf82c577450cf5c643e2234d1142cacdad3e41988fe2d43a51d865ea1b338bbe332ec51debd5f42d0d41ec28f1c08b1249d0edcd946824a114a8beb4c37855f7ea179bc7f211b8475af9fcc86fbf229dd15e9315f205c9c7d132c6be569f5d28e3f54c788c382cdeec516d8e1636526525c24feaeb976bdf36676854ced56b9da630a1ef7fcd0c49911de411537ddb974bbc39d6a5ece48d485098803a7fc4d4f704ecf37269196bee79a196553d9fb590a12ba09caa7d9ced61863c334422bc3335cff85237dd89ddc63b94b06ad83879a6d907e9ef7495865cca8ab621bcbdc2b60864de3f7feff0e7f23d12356aa4f640c00a395666e4287dac5ab334ac3e474c54f6b378ec2a51afb5a331996c21bac8501984544e7b6ea1231c7192b9d290e69d843a185084610f2af1a1614e6b54563e1b3d8298c14722d7da8ad13e04f634ad0bcc7ca7777305f7fb11ae43c890c8e7ad07291cd84017bb5aea50c1395c8d0a751afe197ff9acaffeca924b2b50060758501badb5c4c56ed0ecdfa2b69d38cea31715119600d6c018ce8bf595bb9c9bef8a1cd44798fd4b9281b49a7df0c254ca49ea62903f11b16644aed96a866be08a62a2eedf3066b4a515250e907810fc50e410213ad1018154833cd7012ee266065122de5535884d7c9053f6efe9e5d62d5d765c35ac5777d354b2a77c90b227eebc8ee479bb37c488d9f4565caa7af7314063e568269d48edab18997951d821969ed855cdcc7326c0ccbd00763162691faa920d26a23cd5278bc26b5158fde5754b4978ee76edc48d26c1344f9e9bbd3ddc4625588d67265ed652df321db16e540d8241bd561296803dfd3d0871583a8c13e93b9b7e274aeadc7d3669e0322c406f0a1ae60b5387853253fad4c5af979109f51de520c7325ab22b2784e2f71f22446d8b9431003dccc905a7d247a4d845a11ce84635764c5c6d69128d2be3006cbdb1fc73dba10bd5e1b003d80492d3c9d7d88b74814321de5ffa39eac4a320c6d3e864abf3d90ce3c7da0b29796267e161881b0a8d6fb8a8e25e5ec91b0b836462286ec8e7ad9ec74041452ea7039b6b73d7dc441a57130907d139bef9b4c8427347660c61d2998266d0552ae9e32111c93d4eefc7e40b3c840873448f0e74cbe4938bfd8b7e65448164884fbfa38485885a596be76d0cf1c87b2c7a0125637f4696c37c457d721ebb421b5bd0584e9d3324f6087bc3c3974cfc90ee38c6cf3dc407f422833bcc67ab654ddd1a1e9f9e667d0037591709eb806783ae7a3e0b5369af6dd3622c49b3f6d93c465831719e3af3f2864e4d3686647093957cc9c62191843633548948f445a1b045f137a2460585393b58fd826a83423e822fef047c1e4121eb45421f650e58ece6f129e4abe394f2516db46938364d8d46f1da6aa43a6e1ef2eb8139d84aa8a28cae02efc577a5872c6eb0c4c5bede3ce518095c6dcffb4e7b1fc532ef6d8ffe736b0f76349545d73fb89db0ea616bb0008c3bc9a496c8e01f6a0c69e359ae5db03217feeb3781806cb6e55d2b5431f856e68b01e665b2652e1dfd7bcb5e74fa2b0efaaee87bd765a97f2bb8147730f85df873efb2fb39833e8f04da9d28c3189e928639449e1736a9fd4df029b3773f5d996234d6b673da106e1087733b91789d23864caf1a3c569eb7c1dfe296d5a0cebbf01b5f805ec1bec48c5686788e5c25ca1203a28e84a5741584a291561893c0e05430d5d3a651488924f759666f10190b2b0cd42524d7dabcad9712fdbfdf61468e03cd83f093e93855f4472b082575ecb5dbaf486a8b886f566287e4f2fca34259d5eb5862404a8caecf754c6f5b820eede4bb8611ba8b02937d049c0c293ff5885aa97f638de714a03a3888b0ae287677accbb8cf57021c8a04dc5de97cce703ff0fba4a28e0b1858b809c2103af2eebf0114435355466d9354869f52ed65500648f468e79c53cf2be147bf042923af6a47ad50cd7416c6aa018c9471ca8048c644b553c78ef58cbec098b8cb8599be90290748e4ccf65acb224d8679dcffdea47b602260c152b3a8666129aee83d6524c3d828469232a035711b8b8ad20d323dc2927f04ce0df90e5f6810d1f233f84b7ca6aa9270e9a0bae8164a789aeba4514ccf5ae48cf886938a73202a9d54e06619b93966fd6cb86b8aa4cbb9815792cc245d67672b37fb13c053c96f824d747fa72e4bf9411f73da2005b41528b7950f5032a28f58c1b2126a911945f9b8108702c20954de4b725704eb3e4612ea05862d89abc30783ce17100c1a5b81823deda2e4edabf1cf164f9595f19634eee8fb57866fe8cfc7901454c9cf0e7890832f2b19e4d6bac051614372a1b212ca118494d729493637b60dec8cb78e1420c2d060653314eed4945cd875699b61eb03e9651623590756b0751d6e3fff7002bd525ae4770ae9fc06c57eb3244d7f84e8ff9524a705b115af90566dec00afe52a1b1d17e735a3acd31329e54da5fb2e098659eba8995d647a555457ba767aeef33ebd9202e3d9d38e3bee1077e4d9e2b32b3e236a412b58319924590e98f000a0ed5bdcb4ef21eb8a6104e04685be80c708d5190cf53717d5a040501f4c07d2052aaa21cd76c38182235bfa2c1385a5718e78aa94c657ce433ce58bca5d80caf094c2715f861c64cadda3dcb95e0d4e3f518246e919d62541c9a09b33ca66098247ecd2081e9ade46d320b48deeff565696b4522973bc71a0de81e9aec5cd1b6d8ccaa0b7e3bc017dc5a1b4586ebe98dd404246aad39013a8a87b03d81aba3d4e9da1e8bdf1d69dec85d8d05e1b611317c7fa0bcd3d3ec80608e49a5c806bc0a1d617cc8412fc9d7caacc5d988441e331ff3b9bfb856bc3e1e32830010c02578bf7b702c207ff434f833318ddf98a890e90f1585c6d57da1996812a0b24cb810d6ce0854306c55a0a3914641aff2c03333d1f7017a8433073e99d0945f9e331195e3e5ea43795ac1ef6f9083708841190d0b4a17c72330c77ae103124886da783bfb1cb252796d520846c325130ae2c44ebc40893032f8f9329641c79e0ba3f4ffe0b8d3b436e9a2ec0c63349ad2b152f27cbb16bfd683b296fb70d363f457ec999b10d4dee7168f5ccdca1de29b9dc10939917498eb80d9fbb4f391f213ea1448b207392aa77fe10eeb61188253221777c9dd9ccbcf7287d447e8e045d0dc1cc22d9524effaf8c654a04016cce5d6da59ec92f51a55c9975e080f80c8cbb91379d80f773405ad4db02c59f0ff8362bd03c4d55a96a8865e64512587fb95339d9c98186a4678d0f64f4ca1c7f0ca69d100183dc99293a97f205f86eef55382c511f6ae7325f2661e19b3ddbde36f1143d480151389ee5dbb2fecd00aee3798f08a83bf561cebed986e3bc07571dd5e3706272c1255e185f083d9ab357f9dc00661f4fe325bdf55cb4b7742ab4892bc61ba51acfce0d7b950803dcc137980f665dd403e6d4ed58d18218d3be8b72f59d4aae6561dabb4790f6b902dd1a5c8580410975d0b5215f52e225b68aa46c427804f52dc0db860ffe4e87dee5a4c4cee7da234caeefb468ac768ab34d5048891202adebd4def43ba24ec438a66ee93f79794672248370bdce53150f1a741a9c0ab4e588a7f16af61c07243fa960ed87f920c298bcfe970782f982c054b4e68754997c765656aa2c8880f74a706df3661e8dcf5537859d31d42472ff22c86c9601d543168036404d94a69f20ae5caabd5c7a68c291618d2d9c14244133c3e13c4f0f0fe41fc97c3e4420fe61d06903dafdc1754ec87c07235c8474f06430c462820bdc6afc1b9cfb526f63c0b1ab735dccbadb805743ae7ca480e627a3322b98ecf74ea96bca515d06b9a2b6a83d63f4909e6cc578c655f902b42b65a815aa1048c8c62c592865ddc407eb08d8354a4a5ced60ec16191499fd2a8bf0bedc1e1b5bb462ab1a3f6ea8d8c00e6dd688f5bdc6aca54184ec4b4a5c469c584b27ca1df8a2a91a9d5183f286ceacd5d197dbc5d3f1981022f071c7dd311caae7e73c8d14d6bd355e4b77b35f708fbee48047c553cd5242208c6842f201010008438395504025d86eb168bf22516314b9cae0607fc6da39f548247df76025f6debd65f25404606896e02cdaf4ac2984d476cd4dc7464dd1a5ea4aa1f0b887cce1f79fcd47b55cc495786c73f6abf705007cd895e17ae9a8376491c4ae3e3797af782cd4ab0d3e7b146da8a787e66880ccaf9893917bed51ba741b9f3508e31beaa30e9ec04aa66f98d898cf26caf2738c2d4f39f178ae209eb8fb2b45cafc9963d36907826a4c9dcb2a15246ebdeb36d407d397640e997c8b138707e060bdd23f35e3209b813ea410076a424ba7b7c3b0812d9b295fdf6e02800388f26b3030ea2245f3134c06082000195c046d87fdbeea22f59ddcb085c48a56a7305664022f79c0964fe4aa22e62104e889d449af2127e23216a0c01d3211d8719474b80d2de4296ab20d039a88d73a199852ff33400d8d0bb288f89fe685d0054512cb656f5e6d6709fe31211f13cc7f863d5130fa1b5eeb00ddfe6b15971f079911e9b2369c60926e8fcb2b65874ec5ea8086c56f75e8527099700c58ab61e83328f85f43dd1ad1cbe648e547d1e0ac2b276369a6a03de8b4335c416ac254bd832aaf4047e30eb347f27f1a319df7ce9ea4dba6ae2184b9d360824973e1e55e2c806f6ffe9477a3856ca84716698a2ee7ea9932b4016559d11715983ad07b8c6c72ad49b49f237de93d1d3688924c1a9d225799438e669aaa8558a02f2a5d31d36a1319d7b01d3fc5c254745a6b6f73e64a52cadb089d53308f138a9961f4aba51157903971da2aa630de31cc91b19cd7fada99245f8314877ee53fc10262533e6f6a772339184968b1a74e636b657a5cb766cb43365efde680b77b45e8ab8c3a0db8b6d66aed32378d951d7869a21f15083e219d1654a0a793617c55f136d71f1b1f5c4865163998d7a812c2ae78cdbb2e5bb2b13b485cb664a191598f74ae362c01e815192c7b93eab2253493c8da0672e993fdcd617ea8e662dd2101512d5561aeb2aec3e6404b0b0a668956566aebc3def3fe6b32d9ab61e1076889aac1d5e710f81a0a7fb595d89875c03e5e50c1288b6757343922fb61b4347be031ed3d08c67a16210e8cda3991a0af01d67e3cd4e017e507f53cb6db8e4d054145137c1801a2932d543cd26aa5751e6b006d083816df23b6491be8b5b9fa8f3fdc66d7cfc443b92b30c9d186c9b464b5b0e6204dd2593059c0de9e51dc6805986ac2050f306b72f860307cf1ce011dea79892b6d1e82a2401e983c0e851dce15737779b7bf491d66baae1e54800ae27148892c9e13ba8f224c8b402fcb664a3d4fbf5bf0087e8d406a4ebc4a7d7c13b4ea2aab2ac2b752c3d5348f77561d57136bf7483ab31ce984d76d91368c61eaf176548a967380c23e09060326883f8a31e626818e07e0799e40edf8b86c410df8b4dbf9daa83c2a81a3fcdb72a996bba0d14aa6f68256186522daa0d96f3f12c5560adb5dd1c3b6994a09a681244e3de322c5ec73036297be199b3e83ca991fd4d716e1bccf1bf9bb5fc2b007982691936ae442011918aa66a2b0b779928827810357ba5d5e14da9618b45dbeac9c1e8a77221581943a13b612ae4c79633444c25e6d0ba5be3491a916817a62521ecc24680ad4d5058bedd6064f278947091a704724590189e2994bd196dbc3e7f864c454847ced5fff892d0e25b674b05aac65ecb59f406475c9b4f4d3f4ef7b296cc179410c8c11b0d05b2d1263e228abc939cd9935d6c49713ce4ac8244221768314ff36ac0a058f1b4eff0058ff4b37db350297e3c3c6831f5bb4500b0a2ba00b0fec74e767fe4da2a5ca7141a50d0204c01b1a98a0c685aa113e0a6be4067ec92fec114334fce834367886ec26c76bdae36067c104396f9bf22af6c49ce4ce1b6c3f04f6546a751318d4e49fc0cd98e2e6245f7e070c36d78b4364248d14d511b1673123f60b461e22800b6bc583ef7c89c578a719edc7866f8ffe3a736770c3aae15d0c6e629af239db2d6c5462c254f67dc65ac2c5425bb933b987d25dc80acde3a30b695b294bb0638e2361d1d30789eb0b95b9bd8f2046b0404b4cd1faa2903c50a1e6029752752ba97f5b67a7e8976c79903ce62a161aab394fd71e31448d1ec40a6535a78986e1d6af954ff9b3dc1054e001bb32be5829879941ca32734ffbd9f552865a2151bdfc16ae468ae1040f6d5a4df82b27ba150667e5dd6dd2bea9c2a5bb5971559bd11e1f1247e89a80481d5a545e62d801d10dc14c59ea19a4e446df0e61587fe37349bd4880076b166dabd3c5e90232b0005597ea43be3437fb1211f46974693c7aea21ce294a894c3d0613c901c171f7f55cfed9e542379c6f1ac3c6e0d7a80a5bc7083f656ec47236a0e562a72325ae8498c32ce696086401cc9c3302de2d84900a3660b0a490033033333333333333333353939aff8f9f773eca4db6dca86a2e44814b5292ac8864e9239ab5bf0d7f9136fc45da3cf0c979a00a020b030a7814eb383f8a462a3566f1ac6dd1802d1ab0c511c68ba2b5902b587ee087a2f9ec380a56620145a3fad37f79b275fc273a9d8cf9df2bf2c3973dd15ea466e68fcde8449f3acad9d2c89fdc262732134fbd495581183e066fa293a821f9e154bc88132f62200619288b199ae8c3ddc8da5190c8fe67a20f41421e358d6af98b71bc3817781106195e8821c6f18205ae02ad04ccc0441be2c4f43d0f63be608011060bbcf0ba441b3a9e499d0d3927f596684625334b5cecb8e6bed00a23066080e11ce8a20b30c0080303d58a1995e83c7b857ab8a173073189206650a2d9ce714e4d8f5533a54346182758010ac808c303878719936846c77473bdca22f332cc90445b31a2658f8fe3a8cc128926c64baed9f5cca3cc41a2bd982cee7e4e1231cc784417bcb387e6bea6c084410132cc70449ffc23f7c484f0afd146f49f2753415bc59cc20c46b49a92c7f2c82948bc3ea53063119d8f7e88a3277962d252117db0ecf3d78c6d186624a2d5e928e7ec93e34a8f4444af2b1d398a8588d6da219acd3b613226437ce01ba2892945f552b7afe40b8619856873a899b133c71c8f6408d185576c16dd0b92299b5d983188b6c3e496312dddaf634d304310fd24eb78f11fbf5a553302d1a47f6c0ad2912fb44ee0658c1980682c343ce5a039f2ec51ca1533fed04efe55f59483f8a1315fc968b9cc197d682b6acca9e8fc4161061f3af7603592c59853393e630f9d558fe8f8e7cbe58d1e1af720fa7cbc2a391c8b7e61461eba94c28598e330a387add11978683235735893ce1d7a8f42f0cccd19ae5bb143eff1c34b9dd1721c25e885197568347cac29635091dc910e4d7698d0e06dc9449373e8238f937f4a3f553fdf8b1972e8239aa7ae7cce1dcaec81197168d563bd248c058c197068443224268f2b6fe873a41dd3bc376ee83cab98fa7ac7e3b1df86a624660bf3eadff13bd8d0f7749c16524657a46e0dfd5a9c0b2907be9355a3864e7f2205f135d3d0e489a529a47324517734749a2ca7e60e2254a27986f6245904cb0e1fd97133b4ae1df6e4ecd0196568725a85cd964f3a2ecd2043e341a6c71aab27a470c7d0768ecd5fffbd1803058c2b9821864ea7a3942763644618ba9c6c9e344be89610ce0043175b3ffd2c5ffc852666865315b31c494a6778a1cdb9173ceb476674a1ebcfb1958795a7636ec8853e66b5c715964ae3e7d842ff67de1d5ede9cd4b216da6b0f4457c344ff20a5851959e8936a8cb2fd713c297860a1c9e7dd33123cbc0aeb15665ca14d2e32f9bd2b216e8e1956e8afccbc34e4f03f63e404be025701b11acca842ffa17291327e7f10d7175a0b831954e83de81c0513cd90e31c138319536833a2a25b9e879312961f6648a1cd39efdbe5db0c55620c9b43f25056e0ca8bc238cc80421fb77f8ea3b052b2977fc28c27f4be2ae9f1cc7cc45f9930c309bdccc428394a3992a450139acd9f293dfa32c189b996113f5f7a83194b68dbd77248d271926d5f097d86f238f2a852474c31094d8b85189349eaec954342a3b943f219bd929c838ed07854890eff9c0b9334429bf3172e072972ce71a4084d26ed545616b1271e223453ae51cbc3e8cdb0cc18429b7532485a879b25fa0c21b43e9f3f8c5a1d22cc08421f49ff4e5a0c1673ea0c20b4f1ab1fe282695698f183aec73c5c0bffe18a757cd04bf88fe3d8fc1eeac73d68e383ce659974a97267f0a0b35c290dc1fc1df4719c0b1a725c922accd04153a61f856415c3a49622989183a6e74f2ce7d02f5ce93370d0668dcf9752c5998d0e161c997183fea547db528ec71f1d5f6885418617638001869b2464ccb041abe971dc583d3d9ff531c208e30b43b8a8455f2185183e11bbe282167d9c3c928bfaf959f03fa5b19145d7d9e6baa16131479d58dcfe9383eeb86c0b16bd87ad6d7da9e21231af20278e4c6cfe482357743948d5db7924ad7892e5a091c7424b0e70c18a3687a7b13d90c8e8210305b581034671310e1911582d70b18ac62478942dea872a3aad187323de83cad9a6c2a41a7b66837ca0a2dd6acd414ebd50d1434fd189e678e142bbe23b53b4eedd261a9937a666a5e8afc7c3e8f92245bb39fc0f524fee0e37620217a3e8aa3d7f90f00dd6f1228ace73de0fdbe2a64e1f8ab6cce391e41b2aa75150f43972dc1e79183f84874ae0e2136dee60992d633cd174a82ae193c79731873bd184848875cb7e292d39d14410bf145d3d0831859b682c55ae30bd9765444d746122a477e8f9580849021799e8ad3b3374b828113c0a261a59f5b877d5532e2ed10771437f877e47052e2cd155dc3c1aa39f4a34717fcb3a3e6727724af49e03ebd6931c5d64fb62127dcecfe8fde84c72e51f9b021792683266a5677262f0f944a2891d45178d60d93f82800558e02a5801390147810b48f491629235766ac9b9c4022e1ed16c72f98f4437ce79e70b2da400178e68bc2c868e34bbc558f1e2bc808b4674fdc167cf5c2168cafc0bad149cc30272350673c1883ede73849072eac931c629a3056538032e16d1c6655c4d6db929c3a38826afe67b88bfa9e39a88ce53c89cbbda8188464b4ac3e718a743ac5c1ca2bf8839985e34cffd7061883e53de4cf9aa5cb2322e0ad14ed2fc51a4238f37674c12e082107d1cf35966995f8eea0fa2e91419abf283d26cbe207a1fcb41e5e4d1c32649203a51f7b7306e9d1b4074c15dc348a6ea92f0ffd09579fc14e5f74393bf538c1da2bad4fb3ef4f1a7f0992564578e1f3e741583c528b9827b683485776c191f3df4c1f9c65ec6541d76f2d0844ad14c553ff0d046d5f3bc31f785601e7768cff3643ecff93979871dda354fea2f1d5387762d32a64b4e43873e089e83cbc125855ce7d086b09457dd43dca01639b493a22a8c5f6cfda9c4a18f83a48b47592efbc3a18bf2282656fc0d5d59bccac9858862b91b3a73f9641b9a2dd151890db3a1ff20e9f7862b0db9e535f4612693891ec88574d4d0e710afb3974943e36615eb992b1fe768e877cc3ba367f70cedbac9957c98a18d9e0ab21daf2cdf2d431bfbf358540ed1c527433f216fbe88cb7182670c4df29cc30fc3b649ee1043932f5d37485cc3d04887ab153b83a18bce6e7ea1cbb144ff384c61274fd20b5db986a4e533ae1a6517faff303277cc15eb71c88536e4189bf28ac49cfc2df4fe31245d8fc318179f169aacc134c6e4b3d0c7a81342f61839bb070b7d877f9cb60a1ab3c7157a8faef11f1ec40a8de4f9ed1c8f6a6b0e03834346192a282fb8a8423f3e17227bcc6196850afd44c68f77e42934112d6eced1954293ccc366c4b1dc37a3d0aa88579cb9a0d087040febe7914f6837c34bd6d47142ff1e798820f935a1f3ca31c77a3eb3161f13dac81c5aca216e8e1e6f094d74f8642613e279d8c4f0324ee0c50aca10a38a4bc08512da943ab6c8c1a4d071ee92d08e840d95d94cb2688784b6d3f5e2c7f17860f923b4e3fd695119e3f98711baa8eaf160f265c61c45e8bc5a72e8872142b371245597c7cdd1d9107a0f3bc143b84c08fdac86cccbc90edf0f827e3aedb1860d103ac94a597cf2fa419b62b9c320af0f7af98ad7173a70dd580ffad1ff2875d4722107150ffaee1834447a9c0aed0e9af8397e468482171030dc8441011306180c869fe342079d657fcc1dbc28e02207ad9e87ffd5f37ca135062e70d025937051cb748c01182c60c1021c0c5cdca09739ab98275547b29e73c0850dda0b65ae214e272ffdacc516b5e872c5305142b5790420c216b4682fe6a83a6ff61c8550b9466c318b3644acfecc517e6f965710a7e4fa81a96b66d1e989486c559eefcd64d1a7a079f4c258349aa31c73a8f647210616fd46c7e4cc4af6c9bca28bb1e5e30f5305ff704517f3c58ff34954e568459b2309931e5958d1f6f76ffc30a53c5b56d1b59acf7747aaa2f74b1ade2ab5c92715ad644939749670114645db99a2cee44498a09fa2f74083a84fa7f48f4dd186d0f1873a16f9518a7e25a59c5a56d949d145759afb59a3e8424855ee7245d19e741eb1ea3852138ad62356b2c4a6ea41d187fc93376b97ce9f6827ce8878dcef333dd127d7f8ce51d2896633e48bac29275a8b9b225ecc21ef6713ad7a143c3a42072ea7269a98538e793457854866a2df2ff349329df2949868a2a410a29932f1c34b34219aa26e7ad20ba125fa0dc91c2da776384925faeb748f5f97d79150022bf32c494da26fb59033e530a13a4c129d6547a92ca1392d9168d5a2fca61ce31943a2ff89d4e2e523fa3036c5f4cbb37295233ad3bd2e13b3c0f0ab46f49f52081762b7257a1846741ee7879cfb353af62c176163118df44586a02a9fd91b45201a3449848d4474319a250b7b2d9b3b4344ffe1b576bca9b25267e3104d76e99c32e74add3c0161c3106d589c2097fae9b97e21bab4903b0afb51a5d41921da58f29719f234882e7a96ac9290a742ca11441f7e3c0811296f470d6d209a9749be2eaae1c17c00a2896b96344ff6e060e30f6d8a71a324ff2831ca20c359e0450bc0061b7ee8e320e3fb1b264ece1c7d68a3f3e64d9d2a7ce882c5cb8b7f99d68fff453d7492fb63d20f34e4b12e0f7d55e8350f493bd41e0fedbc76f0ecf6a875af8d3bf4152c7bcb9e07b9fc6cd8a1a960791223e754e46388e12c400c5889a1808d3a349a971ff3e740b35e8c0e7d582db1decb3ad23960b131874e7247152f4707ea71dfec8a0d39f492a73c588ac76b7a1dd8020314d888431f6bf5847494ad39887e31060ac02865c0a1f5c9cceecf1dc548320b1b6f68b7927f0c39ff082eafe01c2870c1f18260608b0670002d20022f0270850d37b4d15304998e35a69ec8171b6d285b453475e4720b36d8601b6bb00d35d8461a6c030db67106db30836d94c136c8601b63b00d31d846186c030cb6f105dbf0826d74c136b8601b5bb00d2dd846166c030bb67105dbb0826d54c136a8601b53b00d29d846146c030ab6f104db70826d34c13698601b4bb00d25d846126c0309b671842e54ae868e1bb0c50334a068870d23d846112c0b1b44b08d21d88610ac0bb38d2018e92b99033f590d1963a08002628451c6185d7431c631629411c618e7045d7471026740175d9031060ac0e8a20b92651c57c6162a386444608b62653c408c4306182820c3c17840175dace090418683f1570320c306106ce3076da75fced31d4f92b31b3e6893e6f21caa07d9e841eba9d477c2fce494d90d1e1cc59f930f9142f90028c4c60e1a8fe24d524aed303545e2b0a1833edc568f7192b4c51eb30d1b39e877c4935996d8235e6ee0a0d1b4b00eb2877fe3067d903295e438a5924e7dc3067da41a274684ca1f45c9031ab56842fc0f7624c45fee4fe2408316fd07a3fbf1478a4eb8a41b68cca2b58c196274744e8e972cfaf7f6e49e5344ca211f8b36a50e9e394349881d08071ab06873ead6d6aaf2154dfecd18cfa41e620869030d5734f33992330baf216bd88a46e3781c5d55a7c18a364f04fffeeef0477f1aab68ce34c7c73b5be6b14443157d384bcf9314fb2ce769a4a2ff1c5422c7f89126021aa86872d84e3a80a881c6293a134d495f42d893ec9aa21ff1de9f8fa93575e896a28d31a7cc5725cfd973608411060696145d46acc8f46cf973cba36877528cf4d82ca2e8b27bf45e3d3d1487a559f3a068537c0ec3741c07115e7ea2f50b1fe6d03af444fff163d10b413c4a6b51a0d18976c3aa55c895cc2b174e3421b69457068fa39c580e3436d17610da633fddc36cb8061a9a686255ea50c2c66864a28fbae7725c298c071a9868a6b73458a678893eaaabe5768958a293ede0b43bfef03dfc2ad14bc7c187b11d1b030d4ab4e13d1dd6726e12ed66d60f2a7645124d048ddcf3143df2cc23d1e8a5c87166faa43a16127ddc1efafd634be5b52fd07844971a19256e7e2fcfab23daedd49b937ceef02336a20fbe6a112f25493e19d1cc7778ac7ed822ba7c39fb879f554467b1395e895de6414822ba4cfd0fa739e7602a44b4da66397e1073b24f955ca071883e4662fee718ba49b52dd03044e7714cb249c746a648a310cde49f10232e4bb6830e21ba8a59ab6287295d7491051a83683fb36a76ce612ba62b88a64cf2850ff1713a2113a011885e5fc5da3bd028393ecd48400310cd79f546d83839bf1431c230e70fed7f7438e9c8e30bad1594a17e685653a44a696ed1e37da1d5873e0e7ad63f8c7ce82d3479ec16b163ec3340630f7d8a57c9ee29e730445169e8a19fcd94bfd0da10d0c843d3a1c98733973c64c87ea10503c743dfe1a3780f3da548ce05608431c6182838d60234eed0a469caa1522a857c190d3b742592437df53898dcf9175a3f021a75e803bf109175ad0e62f9428b0e9d78889b1a4ae5f7255f6895a120a031873e8eb831a9395f689915a0400e5da5479be51c4d1d3a5650c67b110331c8201da01187467b52b40c6b1ee796056178718a176190e1450ac238e6000d38f431524b232bafb9f85f688da1a545e30dcd490edac2e2a34685bd501a6ee8334756b4ecd006c838639071c6d8038d3618af39ab3a74df4e0534d8d056e6a8afa10fa4f2587e0f57431fef9e7f942f5c3e4ad3d05e7aa6c56850ff40030d6db4480fe52a73862e7860f2d5b147dd9ecdd0ae26d3ece9493dd42d435b3134a2b26406c92719bade1095537bc79772d4189acafac132e86268e392c4cc9951181a6d991872881630346331762421e65fe83b25c6c924150d2ff42985fce4952ae26576a1979833198db13cd08d196870a18f434bb3ac7c45c84134b6d09afa44cab187167af1fde99ce396852e4ffd731c58684bb7015bd005b668c01664812d1ab00555608b066c4114d8a2015bd004b6c00005b6a09a030d2cb4398e24c29ac48d96fc155a290932f937c60a5d08ea1d6594a467d2abd0473936b388fcb847672a74f1cb2327cb52be7b2be8048d29b47a9939a46c96e3f57f2d41430a4deab9f674d01c2e780b0a1a5168673fba75381dd27dc2f2a20641030a6d7ebe84c9928d7154e016d8820314d8e2e8a28b3cd078429ffec9a473782157489dd0660859c72548349ad05a58e530156552bd8306137ab99892851cb3843e827436edb0e93f1a1a4a682d4e072158eba624111a49e83bc8510e95ce91d0cf4bf4abb8d0e22d1fa1c971eb4de567b96262845ec272bee5e085814611dac918277b6779f2d02742333958d11c25977f421a43683ff87385d06be511cb81b9416832b3c4ffe5900610fa20ee5e858d0d533969fca0cb5ba123e4e055f3485da0e1832e4f8ed1b81d07fb29a4d18326acb2cd62884c4083074d0e3fbfa4ec96224fca0eba9c94ac3d48cc96943e4043075deaf694bc60c9411f3646a91c15f93ff1175a6739a081833605ed4bc9db12dacf1bf4219305bf9cb8cc9832b606346cd05ece4bb983f2f840fb5ab4d19fbdf37516538ff285160d66d0a2f99ced9f5f314bc43f8be662e88e13bb953a4e70063364d10739ae102531a2d572b168aca4c5e390b72462fa426b052838c12944063360d18f5a46ead8b93d78fb8ace432c97b0931ec654010ac8408139c755ba020b4f95347bd463ad61462bdaae68d11dbf428eb567455bb973609922070b9fb38a26d7b35aeeee55d174f49410b31d62d21c1dcc4845eb1162ad2df274cc1e156d47b13a16e101801bcc3845a7bf1b72b432e9648729fa903ff867b6f85835f78a19a5e883e6f1204b2c8632958c3038b04503b6e00005d4308314fda77994e303bc84c37fb8ee1c744ae8fbcaf364dd90a94f421772c78807b2a51b24b4d2df2fb9c324ef7684de3d8719a4e365e518a1d94d2129a7a3cc5884cec3f4a790a972102a22b49db33f4a502f0f271e42eb6126a75cc5a48e10da9610a2e21384e3f48dd451e881d0450839ea8fcf0fdaf071a5eb757cd0e6d81ea5d4e12c4ba7079dcc568c399726f10e1e341d62d553ead8419323f758c1c57d3d45076d8a9773d08b587f587071d06f569847fd8ed471833ea457941c3f4e8d1ec0067de698d5f2e50791682dfa603f87113ff89853488bf6838f75e5cca2cd1863c712cba2d18e8ec72224164d6ecdf99022b0e85525263afc062fed155d78e5cf39ca1d123157b441b5c37410343ccc5ad17844abdc95fa6753ace8caa2672459fe7f6b57d1ca574f0e7dcb996955d184c8b18ba6b4a9e87537e6b0393c441e155d65cf62316cac8c5f4f71468eb7a6683d27c4e3b314ad868b971cd5b5824f8a762248869cb373981f45ab39f0e8f17644d1c4ff8fd6518e50b4d1fa23849498c60f509ce42a48bf7e7ca2d914b583d99c997ba2fd8e1f33a2c2ed44fb51eeba7ce8b17b4ef4e9517af40c9f11de44933bc8af597c4db41a432af178cf441b99cce2acccbce598e83c34e55248fad5f125bab81ee658f6e43f8eb5445fc13f5a9987e6772bd1879a3a2593c6e8144ab4a9824c7cf024da8fe3632f8ffba34425d15498bdb89ec3143e8d4417193c767e5221d1e5ac1a8367576732f5115d24f1ddd9d2116d6a84fd60167352b011cd4a47e13d295f8e2323bafc286bf5340b1da28be8ba33c78bf06b1e86a8223aab6c25d983afc58926a2974c792466662f9328229af89852d6b314c5227a88266a6be6a037b55b4c0dd17b48613493c7549e69217a39ffb8561572bb4f88d6731c85b0a8b6de1c8368baa492ec764e157308a2b38e1c93c394327847205a5deffeab98911f06104d5e65ec194d261de60fcd55a4a0d31d3376e387aef52cc7ef9b2543a50feda4183add73479c381f7acd09fa52ee3997efa1ef281dcb477942fbac87de3acc71ccd688f3721eda0f43e8670d7943bb78e8b354909cec1dfa6c4ff1540f3153edd046f9eb140f25aa44ebd0e64a64f61c567a48e9d054ccf1ba66eaa82f39874e6236875eea1c93944393c37cc54a0f32a6601cba0e2bc49f180e4d7e5f8ee315b79837f4d9592c2bc6b87142dcd0c5c95179f3dc606943e712726ce893ac75acdbada1cf98613a54efade8d4d0e786c9c4748a316a69e83db61873ec8ecc3243436f12423aa46645b4ced0a6c892e7e46342ab344317d1373aae8ef32429cbd0674a85dc302519bab0168f3af5471ef663e832359b48871e5ec711436f6d99542313067388493c0e470386763b66cc1e593b8ecc17baa0ab16ffa378a1c961f2b034c72af9ef42eb26bee129e642ab1d8a6669b6d0c5c656eaff4f9a6ba14fabd80f57e35cde2cb4d3321ecc7369c763a1bd50112284f50a7dacf6102179acd0bcc7f249a1c9238855e8c328e6951fcc791852a1f9b0214ff3640a4d8ab58a8cfe49c3440a9de438496e0bf1d24814fa38339b43d1904b3d84429ff572b4481a3ea1f5fe4d1d660d39d40a9dd07494f56263f68f96b0097d2e75b5a4dd25314226b4a1e358c227e9e7c72fe1f63c5962db57427b29742ce64a79529f84d63c3b8a6ce5f81f098dc9e4c7389fbf9523f471d01527f473e0ba119a4e0f62f77b8ad05cf60996d43b9b7988d06a5f6b497a9021b4e115b113e2bb873142e82f66e9caad1a2ec404a1df0d2152228721c50b103a977f9dff50ebfffc0ffaf718337cf0cdfe8a0ffaf0bd9efd9eb1ce7bd0a5a03ba1d6295b631ef4fadaa27df10e9a978a10d5f933be0e7acb8d593c74a42d39e823c9495ad53266c7419bb217f38a6b801bf4131322a455e5c7a9016cd0c6320d17d942b29cac4513538af6f33079ea498bfe3cccfdccee3984e42c3aa99c731c64298b36a537a747d59d2a63d159965fcb91c858415834a31972ca19e3c284e415cdc9f46ece39d4bc11e28ace73fc84ee5bd1e68b9e92e45aa27eac68c5fabbc38765f2b18a56e3758a219fdb3522aa68b4af33bae4662b3f15ed5b1257f96b0fb3a8e8d75b7f2c798a5eb3070b39ea98a249213a1e4bd14bb999747450e693a28f3df2f446e9f33846d147b983e897c7418e1ca268425cb8189394cc2614fd7f6499bd9e2dc7a0683ff68e7f259b03c97ca2b9fc261aa35448ef896632ad73e893ba3adc89663de3e4dc8a134d75bb5a8c7613fdc50fe48284cd3146137d30a5d1a26b26faa0e272a38989ce42d218638af1b4bc44a72943fc20decb256a893e88339ba103cf2169257a9ffd9fb0f21c7e9212ed7c658c91e5634b9944972db2246af2ce119444ff617c7c1d851ce4c348f4f9a2f3719c430d1b4834561ddd636c739f1fd1777cea98aac5387144e39b21e2c1871a24a411cd55b98707b1331261449f3aba4534f9fccdd2a2638a9e22da90ed293fe412d1affe9b85658fdf354434b1b37a889dec17ed109d7c8eb5b4bf83ff0dd1448ea374b7fd638f42f4bfbdf9422e42b415777a3a460a9fad413429c8e58f413e41b4415fab5d42f80fab0b449fff2741a35a23870e10cde78af7cfe8af21747fe8345cb967ac983944e78776d583f0aef93e341e1f1d586c510d3e1fdae4bb1e6fd219ab7e0fcd9ec86a97aeb97ff4d0c5e6bf541d678bcdc943973a7b8eaf070f6daaee38a1cf824fe70e5d083147b430d94c3fecd049889fb831216876d4a10b1de5eb98b7ab520c1dda2db7fe0b3d73a5994317b287b93b5655ce51e4d05e077f221f1d3c5ce2d0668649314406b98ec3a1491afb51fcbb84d2dfd07bd60f2749f855d1ddd06739bddcb9728c0eb7a10f725eedbc2c1bda9feba8fcf7a28abb86fe23b66b997ecac8aaa1b5102407572a971f9a863e488c0db12f23258a86d63f4676984e6f4a9ea18b23712aa7b36c25cdd0446e69e994a1ebffb0300d397ec9d06c8e52ced92359e76368428c78b29ba53d12c5d0f9c44e21927c14f2616825f692a788d46fc150fc44cfb746bed0c65c691626e2853692861c3673a4de5f17dad43a5be5a6f95d2eb41a3dcbe4af8a6cb685fe2de4aea585c63fd08ffae37045b22cf4fee3915e0aa75f9261a1092d232af915fa28c4f030cb6f852e7699698c7d159a186e9d4226cd1172a8d0e6205a8788debcd299425be2ee1fbfe243e49042d3f272aef241785ca2d05b968f41234485b240a1ed4e8fe3779dec9727f4a1d539694e71cb7427349519f24ed29bd0879594467847f167422fa7f152c82ca12b0f5dc445266aaa843c0ec43bc5c64968b73fee584b24b41ae342cfa3c31cd923f4293d8abf1e56cfb746e82a4719e32d21c54f11788f53ccd68a12a18b4e29d673d8c9940e6108051042f3817bbe4ac771551984d63c7898a245a27f20109ad4d071e0c14c8c1cfee00405f0411fdb99fb43e246773d686265b5481973c6f0a04d129a731cbd613a3b6873acd93a8eba1f611d349f257bc2c39c1d6555801c74eede3ad9c2c4887f017050801b541705b0416be171706de6c1859f6ad1e428ec8798428bd63d3e49a8c18766dd72d26cb14cd310126aeca1d9ada4f196ff23ac250544a8a1875e2b850ba1520c1d5f0cb750230f650f2c2e3c741e848e2c739872851a7768b7e3522ac7133b34fa5b16b32d1381a5428d3a74922d65f8c7163c3fc70935e8d0e7f0e452ae43cb961032ca60819341866b9151c6058e18187880063cc00ea83187cec3e0494f37a322a38c0bac20020fd08007f6c570c181715220861861ace00b3306d590433b6136c7a849198726a66ab7f82976e4eb8143bf97238665ecbca1f598414d3cf00e0d1d6ee872ca196315a2a286db865e731eefc81f464d196743eb6e79f452d4fdcde16be8637b2c95fd391231a986d603939c3b728eedf03434dd8187e1fde3283f88d0d0ff79f0fa31258bf1cc33b472aed2c1470e97b2c30c9da5543165cd61c814c632b4391d712da4aa6235d42043232d29a48898b274d0d51843172145f09f1810841a62b81a61b81a60b81a5fb81a5eb81a5db81a5cb81a5bb81a5ab81a59b81a58b81a57b81a56b81a55b81a54b81a53b81a52b81a51b81a50b81a4fb81a4eb81a4db81a4cb81a4bb81a4ab81a49b81a48b81a47b81a46b81a45b81a44b81a43b81a42b81a41b81a40b81a3fb81a3eb81a3de86523e62c2e194c53bc060fdad9ed68d9910ad4d8c1d5d0c1d5c8c1d5c0c1d5b8c1d5b0c121a0165dce49e438be6767de38e00521161081171140002dda9074b4fc3c888059a4fb5521c71f6f78bece92c3f4c4a2359dce965b3f74ff80457fa96eae111142fc7845ab9233ceb7846af170859bfc3485ce615ad1f77b488b1d83e4d559d17b1467e5d93a8ee35d453f6dd599b3ab8a2ee59797574e9c5ca6a2c9152c3ec4491e34888a2e4efdc3c2788ad6cb63674d15a71231451b9ec3e9d6edf8d795a24b39564e962cba59478a56e54ff43d5cc99651345d2145decc44d17699c78b791d7965a1388fc6d47144068a56bb831cbe58b6eef8447329279ff8d541e29e58f7730ae9d04eb417b2327c1862522d4e34134b3dfc646da2979c3169d833b3b234d1cf77165f170f21863e13ad66cc1f598c1e134de646d3130db93d2e81a5183bbc90794b3431493baa548a4abf127d24390c4bed58323e253acbf833213f894e328bfeba7b852f89c623660b9d9d733e4724fae083c9c6b4ece13d20d1c8480af9f2116d105399d01aa245c6114df2b192fc28a7117dec66c52d0b239a0b4f53bd2c412c5f44e3f9b1a44a37bd5b45f4eab162ffa7871cb58968fdbc2fe638cca71f4544977c73c62d8ce5981ea2cf9d544b1583c64d1aa2b19472603ee1e3388e85684e724748e92832841c423411fcc3b9e4587ed819449bb2b2bb940799613b82e835a6a09be3e3244f9d40f4f931bce6747e0faf03883e48791566437faa74fed0e4c48aff714c122def873e4cc5982fe94357e14162c3e49c8d0f5d5fbc1c3f8b55867e0f5dd08ed9e95ac963f4d0783e0fddddc3b93c0f9d0749f1a390d5917868ce33c5d7f0dca117e995a01e76e8b542797c165387269b9e24f30c1ddab89ac34bce4d463387367e68b8cce78fe38b1c9a914b59773ae5b79438f47f1a4286c0a12b8bdef99f1ef37c439fa4bb33e79c27e386662ae38c6aee0f571bfa1ce7af1639d12c391b1af594c3798f3d4afe1adaf450c28784feb3a8a1c91f2f4b6b7c20200dbdfe58d490a0a1cd350d1d7b7786fe4274e5c863cdd058f238a1f925536ccbd0fc75a8eab831e247c9d0750ae22fb97292181d431ff3a490e32862e873e68e73e4406328350ccda5bca263963ac26068af53f07832a414d72ff4b1879ab39f494741f4421f8e86c9a9ad569a2e741de590992d3910c0854e93666f7e0c1792e440c016fa4dbe5679117375ee4080167a4fe217a3755968fb739ccf9cc2a56c58e8b263b57816cf2555c715badc20d21b4387157a49adce30af8e0a1d55682e7518a742e7757d2ab413dd3342f44ca13d4b5983c75dd9e391429fdca2cc45ca71e944a1efd451a3db030a7daa187b26e1b724c7139aebe051a7641dc97538a1dd142f674e4c13fa38b179c92ba4c64ce83d567e942d4761c725b4d1cf274e42d7aba28466c3696a4ac1334e2509fd8795e8947524f4217a26b7d0fd297f844e326e0589b211fadeadd2aa18dd342e429f636b6ea54b84267a549a2f1d5a121d421339bca051662174b929b9a51c37cecb2034ad398b677e0ff30681d047fd921e62f0078df885b09c62c84107f1413fb239beccb1ab64490f9af0f350335c748e391e141fb805cf76077deceef3b89454cfd3417f62be3d29272fc9e5a00f1dc7c80e247ff53868e4e3c2c4d092ab1b026ed067c5ac919a5245c81060835e3e3db21c32b5e8aaa32793870c2dfafcf9df83e5386a86cc2cda1cc6747b49168b939145ef719da1d1625e7e2c9a94656d1ee99f4b1e168d780e3e84678589ce2bfa307e0e5f7e2c7373b8a251e9f037e46845bba963b7f495d6a861459773d7632b5626cfaca209279bc7e37a06495145fb2beb174324789454b4e15d2ff84c59b68e8a7eadd5234bc67be7a7e8dc3bf6899e7252e6a6e843902e09616195f252b41511f1c973185a6752b4fa39de498f5553ca8ea2ffd03c3926a516595134db7f1e29e52b6c34147dfc68edcd91983505459f5353a55819d32dfd4433297e4b2df54417a34721c74f9e56b0134dce41881c47a127570827ba8c92f2aa62b2cc64135d9e8a39ec47139d87bfecd6bddec1978926e6603ee7e58e2a3d4cb49e39ded8af71c9bb4bb4fedf31116396e8d5ffb23ab49e5e5689563d6eaafed02d97125dd01c912399441f44725416357ebd924497a3dc3dfe4125127d101fc7e6900a249af79ce5224386f31fd17e2c4bd3b0235ab59c3161c123a98de84c5237a2e348d164442be69ac3a41c44a55f44efee1d65b628a2f3b823cbda9644b4f12f2e3144d4b70a22dacc717b53fe105d78b4fe1cf672c8ba213ab1dc9a1d1d5e422f4433937318e3e5433a27441f9deb31ef5608310fa20bdb66299a58c47905d14bfc2439670e44ab29da25753f4e5340f439f67f2ce2d21aca3ff42199079143f6439374c29a7847392fd887fef374d0502f0f13e4c31f51f44b22b887c63ce746cd2964ac874e32aba3a8512e3af2d069b492ddd0112bf1d00793a259c451ab8edca1737f89217967872ec76391705a1d7addcb7165198f38191dfa40caf33c358726640f3e75ea88bd971cda4e315a4ede631d2b0e4d480fdfa8d1133f70e83c6f0ed25afb8397fc0dfd6b949cd93f948d92bba1cdb1f41045f236749132fe9d398e72e4d9d0e652d70d6135057f0dedbb5c847d0f1f400d6d484cfe93deacebe103a4a1f54063b974a7a7f0f001d0d0748a1fe3a1e40c4d18a94e124d53fecdd06e741c237a3ccb1d65e83b929842c36e47860c8d49f47dbdeafe700c9d594b99c6c685cc88a1d59c750dd987a1cd89182465d914690143d329660ee4ff42335d165ed13df630f742d7fafae143871d324f3e88793c263317fa1c7caefcd9aac163b7d08c4f140f31079977b5d09f649e10e2516a8f66a1c91efa3f122f8654b1d0c7711c1ea5701d227b853e8e0f493ae4e0b26a856634acf944df2c5d56a12f09ea9fa572f62aa9d0a71c7f1cfcc3b686e0143acb29c2e32497538752683f2f44658f28f46be25e295f2a7c40a153ff0e29877942df1e86d054d9d78a38a18f3577547b34e1dd8f2c7d22c784de573bb84e3949885d8a70a8a42de401e3d16024108a44e2402010922a07831508001044280cc5a12087a258937d148002501a18362c1c101c1c141212160e100e080608060686c1605020100604026150381828758da1380232aa8dee6bb5fca4c198d6dcac99d1685d33c807bc535f9afbe63a9aef4c8e05c3529421495ddca23b4a14758954d66f7ea7379a919d8a57bd764f5035d83aea35c5590142e48a2be2ed5342a1512b1f6a0be928d515ecc36e7a83653ecaa782bd1823256a2f829bd2728f4049f60b06fa50bef05428589d68843798e78b98d22d4ca6706945ad195d41c990f028e0530b84608fb158e3cf42d1998c01868527b642bc79d79106463e42cdfa4ee991e172690093065cb24e8aef1d0ceb87ab71052fcd548a0496578f24dae9c8399c1ec36afc63ecbca03801b878066915fb3c63e1142e501853f58577fd360c2819db8df230ee1ad9fcb14d6a88c646b88d5b8c6cf23103dc6f32116cb54d6ac07a9e50273a2fff72445f952a01047b2cecc5f01e9975c4a243c7880f9ca603fa1030b830537427581c71e21acf2ee23847a260bd979c46a8fdecd0c801eeb9eb680614518013a0056f8cdf8a8137799c09aa1a3cfdfe56e864eace4e6a1d7ee673f573a7a50e7873c67ab4135d47b6795d5de7d4b0436eeeacae82c5636be87bbe726f06adc5f38d564ba67beacc3856a5cdf27813ffc7bf3dd484d8674d7985d136ad17fa62b6fa986a0d373d312c86fa1337214e4296030d0abae63b99ea3fd7b1f48e33987b501d6d48e125fa8a01135c3a3a02c2b88aff6e6cc441e5d628867ae9ceb5a95372de9adc2cbf75d839ea3c9a0fec26f5accdca9d0658da67a9cdaeb7c087fee937057acbd2963bfff6d736b0ccf2497f9246e1a8e31f4bce031f1ca4ae73cc7b7b9a9581bc8f42ed79a1535424367b37e1a5db17ff256e6e3fdecff7c9f9c817c32701ae74469ce1f28da69b69d81c9adbe3feb4d596eeedcd5f95d6a1ca6aaf9e3d10bfc3dc7288321f3ec6d595eb8f46a8502bab1891ae02135f1c7ed0d508ae2c4f587b492fe227dce6067a783a48d05b2e65e6ff3103c1ebb9718dbd6a8f1c43e04f3027d55f5fdd9028c39dbd74956a41a5e7e67427fabdb1cd0af053ccf1ffb3ccd957ce2b275e948d299ce97a156c8d6401debc02e7a4150d96eb9dc7d443ec79237a9e9c17bbc8757a6b8272a7b64e3a9ad970fbe71b789f7407784169bcc63f2d42abcbbe81d627b9794e5aee18e73ccc67f2b7a0bfc94b9a349f3f996e77d30371a716042676bfaa01cb9ea5b7ddd34b3969bcce35c85eae66c5d635a596d24dbf9b353b1a789825bcafcb666f815f2f75d1c1defba2a156756861dfd74b5033889c6e6bf3edf77b495367e07a7f68ae81ca79cfb8cb88d8305fd74f98e25004fe6b74c52f84ea53414fd97afe2c368d852fcd0396d3296ff8f26370b5bef7ca74fd293bcb7ba876e27e1f88d31de3ed4ef4d76d8754e7650ba140cde926747e1f2948e87373d29dfa45b5bd7c7e1e309cfe4774e5ca94ee2e924f33e032887acafa3dcac18c43d0d2a6b9d3bb1a53f3be2dfe427c2f4fdc57355de84c98373915f6c7993237b9e48e8fafdd7d02d593501a969d971d9909ce971d3d9ca26285dc5abb3a6931ff6effa24d7d5a69f904f66e011dd4fd2495eb2c948fa1ae4adb38dc3c3f618f25b358bcaf960b2a4e7680654ebf3a43be7a90031a43afac11fadaf8d5b73e702f12ae1c86e605d2ce8fd3fd4b6f2d3ab77cfaa5a1dce9dbf45de9371a30f9e17075def20881ffe3db23706abd76d551cf840af5ea0f2578eef52b70881acf71109fb1a99fdf48937ad333a668c29b3724e05b38daf6915b5553b382d33b0ffc6df37a11c26afb8779f58a0dc0cd3eeb136159cae87e237766a52baceff93406ee8ac0afc0abe6e99d39ec77ba89ee2ace469ad87b4f99b5cf0ffdc827e1b33ac93e790ffc4d01ddf20d7b8efe1850ad6a87fb3549cfbaa85af5ebb2823e5aaa4fbb7b6f7d1fedeaa4cd9db7f67110b96d81bdefb8a63ae872ef7d79bcc444f0dcc05e5fb072405fc10414b3ea25145c711059537406a6198dea53839ca0f1dcbcf0456fec6ca25bc1559a678e893e59502495c935bc3ef9491cae0a2fe6ab4c87224c34f15248bdb38d3dfc0c27f92a70fa10f079e7dd86b0d4ceb5e07bc9dac324f434d1f16c98ed6c1b46e19caadaa9c3d5873bb9c8d2fad0741cfbde8dfe93632e7cff4d059e847de866a1b6489f1a62fd56dbd167e425805908d6cf8fa7fc4eaff0f12211c2b4d6563f9da8b83355bb47d27db3e459fb72dfb5fbaecff07296bab5289fe795aa5a56025b5e31bb6bf074e2724a3c224389a95b7cc24fd7afe5fbf5cc5553947f8afa1488e8555139ceafea92ff86f469b700a9c24bdba98f34ee2d9b3fd3257efc76f4dd7d663ef90ef5d3c232de92ae267702bc1a0da6febbc7d3b5d44ff8f5569ab36325772e638ea053ab66ea58d3ae9dd9a112f7ba917e77def7e7edc2c07e28a0c5cd775287baf4b0f176f4d4567dd00ee2da8948d15a6aa6c7be37d029ddefd93f2ba9959d6ef0f11b8f6efa2bbcf44a6fd8bd940fc4da8e8de6f927edbcc7db0772d9877914ad2ac81a6934f6d53b61a5a2d19e44be0f7fa9d91df7b681ae30f2e7f0e9b51ee809641cfde4b453fac2497da58bc6dac6602fe92b0413fab07ef9983f6107abecb49562454dde939a8c320a15fbefcd5cdb3525646552fb1800b8f5bc82511d1434739f3ff23ad9a668f065dca9bd9bc7e3647fe26414115dd07c10de39eebe0e77aa9df7871496f18f7ef1f0d1fae9be34febe0d8538c831985718f2e3c1de3b136390db852aa0431ca776671489fd58b3e756412f70975fa1b72538eb7e4f7263d9890fff74b173e7edbc743b4d566ed30cee66ef0dff1dec61788537df84bdad169029279c4e7fbaedd33df8afe68a60d1ede880448af97c620bbff17a15d008dbfddfbaf791e25857a36c4dfc80c2e9d03273671a51b3e3203436bf287c5f99836fc7d707b461bcc4b55bbd8aef38d227ae06444c47191281a9193a52f3a3e080503bb79da8cc9d1db1c199299ac6641bddb31c055cb414787d63618087e84af82d61f42a60147520bbaab90ee028f67920406624edb0eabc4d588672ba9e284a3fae034dbe0fd283b0f30ef4746f090945b429c744fe6b521cbcbe25d43e00b5f75c8205ddb2ed205ba618b3798a8b090ee45f2013458ce40b5793ff20f712820411500da5188b29cc29ea34e1dd689a8d80106dcd64024554857d6522395f7700d6aae9a8da9f068e5cd34d78953992e3af9e2582b44e21c07ed52be4558dbdd5b040f96372d1f3b1482dc7104c7a56a49fcbc55108a2a693717230334755db5e8073f48c24652d7b4260aa6aaa9ef6381d76832988ad00d5c30272cb4a157ee5b5de78989943275d9f4eadafe3a8a1e6a112772550d0b7bbdd76f2c7127edec770da02d9116f53bc7e9350ee20e76d7c8accba3ddba98b3cd66cb7be4ebaa87dd9b28d20e85ca7300ba930ca105bdff540bf3b0b0d02f8799591daa9f8ad51101a00eb558cf1b577b227e34771b7a6c682fa1bbd3c06c532779b9960324558c764c79988dde849d0ff6c48bc45ea8d6785be2ba1fce9443108ebe6a32bb8470a2d3a5f9a1a0d6a3e26086d0e2a7d734852e02029d1012e3e589d98f975d09e7d9614ad169e179ad45f983de9d2ef6097498e654f10c572586729a71c2ed6293dc1ce7cbde698b349060bfdc3ef42e34a70a8a22a66f4c33571e02759a61599f16a3c0c9128000837704100c5d715dfa68033fb5404b50e7afb7e29746eea6a276f1d33f373f5bd13a40ebe79c43ad9295f47d95cafdee624d8e16eae56f78265b075e8bb5f096fc6d68af325ab32a745eca15fdb741e1e70dfcc0d2ea2b2bd0d62a5813c7b4094939cbac403e4966625a4a63a43270a5bbb9b7bd05c851cd8d6ae036a9fd87b32a38c6f0f4b0390688356dc4fec642f3aba7478465f09da446fa7383477fa8924e68f5cf632e9bef51430ebf15f29a925eeb4e902af812609fb01b79937ed73fd20a6b61a34e8c50c54f1613e29d73ed17a9213b025a95262f3620fc38f493a5708bec18964bf1941b349940dfefc6174a307e8ec8b273c1bcf1cb1dcf378a9e7d00a354b590dadd7fb82ac589835c09b1c263aac72b42b91a6d2c375082df96696284f8d2c73fca1d61b31e4df0a9bb2d2fd802c65a8a56d63922fb4710fed6850effdc8974d508f15e8d44d144a3555d63712da3416c28ca53fc75f7b2046335fc32e4f68879db901663e06ed32eae9084c58b2f4c507ca19a17813ee98d5525c5989ad41d2246a1b89539d4838824b84773cf716f655cc070379c42bc7439bf610d6c0ab16d22c983d359248461797254b162473060fc62a7ea31ba650deda2ddc189c4c4a9649d587f585f1bf3c958f580cdb32dc743cf6c54dc77199be80635a19766dae54d85508b5d340f05da30ee9940a2a0fbc1a27dd5b1fe7177c6841b715c8e483f48983734ef7362aac2571bd8bb21d000a2323b1bb66f99685a6a5694bbea93059a9251c2bdf9fdd1d27eb05286f779f13cab6bc7c1209ddcc778956086b8b7bc4e2fa0675d296072446571aee54cc55b152fb06023a0455d3944f76c899e1b4cd9d23a9fe84c608fa92cc694e5164e68ca2c8e9722601faee79b43c4741066d2d3a4492b531bb2901c41d51f9a1cb19d1bfe86ce53db79d1605194dcf114bab5ccf974283a7109d351fe21541218afadcc2cc13afa2ce7f1da0dc5b0d5784b5bff80b6d32ece89fac0a4dd0820eb446eaca6fe2588e985cab2450b7339eb662fefb97c749cabc3dd25e9810ae2d6ff7b3f3e9beccedc7f970629aba7e28d1c9a2647135c438345812cdaaa9b3cee27fd359f01bcaab4f6dbf80c1de3781fe2135fc1def6ba8a79a05a0ecb4bf0b2c882c9d26e3d0460018ed6f2f16f5add179b628c269c14db4ec6599cc622357c8a8dd47955e7a80c3f0586051b2d59496f2bf3d2a61bec00c11060663e3cec008a0eec32ab8b00adccaf9d6d2c25d21c805a1128048ae0ac3524b382df563696debfb1a08d32e9bc3f0620f405cd3c1ecec32d96a328880d3ebf54cdff18d8203d173f9a46b365a85ff3dc2a4e32b05ca9f219eabc5ba52f4114070fc36e9054d85bb3753db01253a2e5aa2e5652cb232bf653f050a07794f579757ff286a44d7ea0127e2cc91980b3a3e9176b045e9f1442c42d87daf422509389b8ca26a79c375a4af1dc6dd3e471dbca759c0828a970011c6731abeeaac93b1faeeb960e9771feef40407d757008471ad3b8564f2e2fcedb5ba9d288d5993e4af44275ebfcca487bf4a8e98c5405b751c8898207323dc08115297b750fe025e774d212afe6c24d81f44d71b580586f518f93e13eb17c5b375a29af09478cb2e42777a40f0539b30cafa10b64d0cdc58e2214b41a5378359c5b0543ef55d044d9974ae7a71032a35cbe5d58646e24f54a3472e644ecc99dbd9cbb28317f011a8e1c596412f2fd001bf390d04d31a6d7badcb23eb3d7f0f803a11777ac75a1e7b1b1a63a7f8365086003f8bb264168deeae8ba3706fb741f2f202e3ab1afa68fba25a3e3eac8595091943bf173fa2b0185d1c888bd2843280b794f8f7293aa3b7c398c70581bd76863aba791e5ffd5380121a61a86b6429312aaa0442f051f2a0006c968a19acc7b42a22205ca7923bba48016e897150841714249ffe84c721de3bf5db8f0fa4acc12584f4f4783b6eb20a3df99144b2832c2ba8536b51b86d8545d1deebbc16cfca801b26c86567b4fb8027de663e8cff14b7f5714421b38399ee0e1f5f030639c159c6d979d053babc09675d24c5dbf0770bb293d2ed6cba0cacb473849e4225707dc7434769a2afd838ab1b9864b84c90d992b139fa72f8a0e1b92f81e0910ce92826229f10c3e16a9c021e715662757f1a6a8ef59115c959dd8ffe7f6d5ddf3f0779761f152c3074c282dad2ac79a7c797c2e59c1107069aa2b67a5ebca6420509997a1df12e96cff25d2eae2859a8de78f092b3fef3e475550a5562d7eac98c467b0ea89e0db2f5b51f0d6f92c2f67c42a372731bd3823f4d54f459b7c8e3917c90f0e0791dc3b6706e0491d3b4515e3ea94d67902c8d01b1fbadbff15e508b81b08ad814bbcc6f36046a2e0cc1f40e638cfe3453a32d4205c9c9bef002dccf6f692d5026ca1bc9fd21831c1c61b4427b3507425f235b40c8cacccb833ba8404bdd10e6dde5b595dd367956ac36e5cd79c26e29a31e7dac10f46d0a268d5892e135904f666233976dcb732a6e4b5edc8a91b048b79563e7d6bc6feff3843bc7a239d18982ced33edd1b90bd9501f32655ed43445194103ecb81eaba7ae712770f10149206e098585da522a7878df8eca8425e4d0f2708ace52423c05f2e0da6887a71d1e79e2380e21a8871fae6a7ebe8f4d2105f05aa6929a0c2e35b87c110f758335f5340946d0450f643cc9737d0c23ebf4fa4d68927851fb10e866113521266948cff3f0729cac40bb47b4bba2ee94c90bb2742f68dc5d60ee1be7454ce7fcd1786ffd0cccbf302a3d4bf0c92f942c2cd8e30e0ef7f4df29dd40f4708081afd111b028684e0d21a1478abb81fdbd1263bcc47870678479a153fa72cf18d256d15ced596cec80952a1b3bc29bfb627e5edc507e6514257ceaef041dc7fc260e4553e8de5db0018a2b6f6d55b70dc1ab33fe8630c03c885d747d1ea49d02858d01a2eaf0245cbc817e268232b42e049326481e607819027ea3e7529a478db9cf55a57ecb58568116a4ed1d0d859d0eb5532dd5b85f9c4b6b4a3327f3872957c651e026270b95bd81d7eb517a7e02af03a6e29884e4c91758b0b0d45d81d8b593ebd5e19746c3f18f436a7625a56de67edacd314b12841519bcd43114a48adb074646e9f806856968c49c279628edbf68298ccb85eebddd64b682780f523b9ecc23235c051484b453f39e5236bc0bed2ed63f7b7fed516ed034baba549a460fd48d1e3bf732faf90abc04ec2c3a8010b6df68b6245feba2f1dfa6f38ef336214ddc7265d833d7cf87e1de398b94713b4bd452c467a99ab651eefd91bc4e0b9cedbbb87f0180ea9171bc29847b126cccac7618c2a1d263700dc065c0136d21f6768fa42cff90eabf299463e3cebf670b92a61240bea1addc67001f38f7fe84b035b768f9799a436bb669bd946c1c46483845fd6a1c79e25274526cf8d9a55b63edd6a0684f5d27c5d52916043a92158529bd3346c2c96f9ed07f6e68e723ee7dd4c4c4ba44e91100be9ea5467598ecd63e43e3b7703fc501679f8a4db7c56f0cdd1f013ad9c051e26c642795c01c7c2d30a39a3efd5217ef8ce39cead8c94b02ed1fd0a06e6c2392bcc08224bf0178b1b6aac93e49cc26f087da965936423b68b1b80bc1a592a13ab20414c7875a220abb2b82c4440cb19170b7acb7433db01a224b279c0fc7bbb723a8e08381b4054a07b5b62426e9abf2f06cfaa2213a19b43ad14d318353b4c51f227f3a80566d32ccb4a4bc5e1512eea60448287ca2841ae469f34c39866f579a9ba3a4b8b5e7c03c5b89366befb535c4415aee2de2311dde066128ba253fdc87a3e04fb222c7c1ae27b5eb17e61c10c91689008fe81495022c480c4b3f9e49c9bbfd66068f3aca94c2facbd5d24960635364b26145d78292d70041fd03a0c9880c8e29d161f160b1109d9106aad01f04f180469b9ac2a8025c1b055c7ca0018f2cc06c22c42eef2da711704344aa00204bad6535819cae80f47b25b4975d258c7a1bd09b39ae436657d18d09aa2178be091499c9631253e00a07ab2bd213f81ad851be7866d8a3a4eaf18585168a27471adf8528893c0ccf493b77a02b584f3560531ea0d55d76d0ed039a4306658c72837a5f8423e236434cb860cf3cff72ac24d55c1624f34ad1b3b91eae79f87695a5e818f81c80173989de93507d64a8729f606b96b1fb501d64235919134cd4ad2fdd06d1387a09a74c8b3f5b46a47b467316ab514a458517fd7859efb5789d87c9f043243237f4bfcd84911a49a8b329428e2e7ee86a9a0c06f8fc8215c33bd07a9a45328ec996424547ccb548a95350195e184139a996c99cbb51810d4b84b52e802b7057c6fae60fa51c5c0ee4cb165bf266d4a6b6ebca494eee0cba21584c8a720be592952a8b3dd50b94cb682e3d04c262b0b7f5e608c9c774973ac04820a5d546d06f2aa0227d9a21ea7008c78ad7579abd8ce31ecf2d9bd7dfca75bbff584560755463949497ec646a53cb221532a896821128b2092937222d4e73497d2e8d96e45101321ad279c32758484261f5171b5b92a6c8abc46a47a10e5fb358a098d6a2725c8a4ae46c9119ac7bd3b7cd745b1c1a1cc3d4231afdf3479d10ed97a0155b2071cb7f172dcb5c130b0c419945480359c4587c5c079bd74d24d09a894388996f34e395e040fe6f0329202d808df1e2cad068d0da88a1c8c4c53e31a85c3b33825ae27528a1fb451f5e702ed3e706af381f94d4bfbdb9824cf9537b7a49e520797d9c5e2822a0811a48e039e89a6ecc0b8f1985f0e938c0524ad22c2b5e6534510fd38ed6ec98b6338741b85e1191be3477e899749398d87e0e0058f719cbecdcc2a49ccdad1890fec13fa4aa87ecc3084405ed3199f248e8d4464d2a6afa24b36f521259004b833da03e0080b8a56ea540a955ba14288a4b07ddee9e394cbbbd64962107e1cfb260d0774331ca680998d386b422ca42d0b85a49c766778e72358afe6dc34242c63ac0b5c26054210c61082487071a81bac81867e5c82a82cd7f504758921b04cc16f459211f04e583684d199b0e0c21db56eb9f873a782af78d2733197e48992d5c49648981d129ab344abd29a407a00d26be78eb90405e76d603b8968d603287717d0fc048e1453f111d05e8980ce2a60bc681381b7d7efc8aaca608eab6a501e8b44cd7f08e65bfb707c4bff04ea7e1d1836cd023f9bb54fc7c7ae64a468854eeeb8a1572d5f43279ea4e65ca1ff423a868973a173ee235cdc2f854ef8680106648e83ea101ec660e35670741274b6a7dcf3e2f49be03f024908c60aced74083d7009d63c8ee2b92cabee82931a1e8d4c519f56774b644936c031462284324d3750dcfebad8bde8589dc190cbd649036f29badb82481a9785291eee3e0816068a187662f85082b206184848b79b1646d4d42a0c318f738f228e25f12bd1095a6bfd006c251d6a8f00570a95e091650f2920927b568f264eacc964741c93560d7bfec325c813d4b397ef7cf28a08d36cdcc1defacced3f9d09f39f83f684c9534be54c44c91c0cb924eeaaf07a08340786edaad5ba30705f19e447daa3e2333300694d1f5ee4982074956b2fd32774ce1890c4f81b707505ec5c62bfed7f43da3f47c7bc01cdccba1ceca59877bff64e0e5b261c57b30273834421b8d5a1bafd9e7b0b9f5c086d075ed93f7d819a758de099106764e766a08d4806f76661da48b399eafdb3f300f22b85772e4d8aefe8f675c0035621ef6f56a274fce3e3c8b160008998ccf334b5ab3242d1d3ca3bf785f523cb0f68ed92854b0b3b51e690a09b504205df7ff7caa7c2798804972f176e610241670e19d65b540a810e46cb7924f18662ab2b71ee677031dc9969aacfcff4cefc08beff93bf177474cb4da546f067ea02e46e720d394e5ec7fc7cfb83a12073e3382e270063d0076c7a440234abf71e74f5a5f5bdc0e1047ea51b493ebeabd38ba32fadc8d785b639b63edc1609940e13a4b9a98c30c43f3fe17cf323e3302cee20c76c0d51949fc44c7a7f5fc8ec747c8a0617d0755adf9d8347e89f20e6970f4f8b95b9facef284391741970b8e6b22a134cdcbf10fc19dca48b192c0b3ddd4be9313b9d419e17a0412b4ff4750d50ac46c686e08136777d9005534e54b616355a8523d6e3c061825f7146436269fedcb267bd13b8c295099829e69d32d27f6dcccaf7e4a160fc938dc93f7d5f517f7a88e4c84af24cd414c4e68665cce1cff47c00639b8a26623f30e050b86c869508634b68d3560c3f6adf0a51efcc7779d098b2d0b4257e4e93e92cdf7284d8c60ed7d1cdb0d090697a998efc09dee945a9fc79e5f051d936ad306af72238189c3d028aef7f9d2d70b61a0730c30c33cc30c30cb38820e74b60a5ace45384f61d04bb22222224584c08591b28591b28591b28083ccb09b0091a0a78860d85ced048c719cf32326b28b7e9794e59cff01f6a28350cd9b4b4e43494dd71c6d8634349aa8c86f24bb8f6748ecf50aacaac59cfddc0d1c40ca5de18f7a063b4238394a13099634b58479d6f25642883abc9313a39c650f2c860d2e179950487180a1736bae9e671abd7309433fcff517fd6187505431983bc112374f84923bf50081b336b6ebb39af4601bc8064ddee8e4bb30bc5ac689825e6eae8870b65580e6ed3c483bf8c5b28fa7ccebc9971c8e469a1ac19e8d7b8db9e579785729a34d9c1bd868532908e1055fd0a85cf98e711d29a94a6ac50f808a3dd7f15d1430a5085f3b5c35c002a146a754432dc16035828c0144aef9af79df3df6c79a450ce78d1ce612f33dc2d0a6560f3a7be65baea282814ff6a7c773332138d86150af084f255e64486e51b31a92d80138afb25319e48caaf6e17508026942b1c7f4e5af953f978b1b50e2800130aa6f612cea263844d155080251443bb3a7ad10c9387d4288012d6c9d9a249328e9e017f380529785395860224a16415aee1b051bfe40b16b0e005a80006140009c5e4dfc883685d36800d3cc00c040538423984cd66765039713d502880118aa13be3c8bc0d6d42018a50d09c3663c227fb387d018850c8c093fee36bbff8eec253c0022f60f02ff0e28b2ebe302778c1173038bb0c146008a5d2ba9a8d905d7e18b0e08b2d80108a29dda7dc32c4ee495050802014430a4d75a5694bf7e18f02fe420377820200a19c1a37465dfbc4fdefa2062ff8e230a0803a185499a0003f2843fbac97e6dde8ed5ec0001830000578f1c5090a175ca8a1003e28c495875a9f3ce3e0e941d1634cd619e6fa73fce14149cdba6e364696476407e5d318ee72c62b72d474501ec9531a25428c28400e0a993ac3b1c3920889c350001c94254ffa93b336892872c1055518b8b8059fa166def87ab15db8e0616035960b5b945645aefac3a15e8778010326e3a216e56c1fb33d5c92e4d072418bf2a791ee8953b251d315700b34c0c52c8a71c27477b34e087d7ab1f5821fd5002e64518aa8327172c503ff8b18da09b88845c93578be5209cde8742f36025c70c1052c8a925af36dbbe6e21585d1bfec3e8b8cdb63ae12c0852b8e0e524b956c94080b7c68808b561423e71e7af8681755e3005cb0a27021c124ca6b46e766159869f28cdf30c4ed545150eb79898953618a58e7a81121c750516818f657bb23070de5290c99b53a488fc6a09aa29cafe1b33abab3139662ef900ddf54275c90a258ffb8631aff48761d710317a338e4c6729171feec89a250f131974c8687a210572e0f72cce61d3d288a0e5ce24ce537c3ce3f519c50af12129ec3f8c6138550cb767027e94469ce41abadc4e6ff2827ca12a9f16c4fdd4439ca58875e8d99eba226ca4992a4f628c94421857c520d2f3f79344c141b856c7b86cbc9fb12e50d2fe1d5e293c76989925cc42c1f22548982ae2749db7074fc379428cc67d7b073c724ca39d5840d31e28ef29344e9aef4377395e34c53244a9df6ac57c25b48f490287d638b74b0121f297f44d1d324eacc487c498d23ca69f2683ebe4bd4d18d2883ec2173d136238a41ee24aed17a92c9224a227f320d6a24c78b15519e20129395ab8e7b12512eaff58ff6f9a7338288b245fc8998710f514e69aa5976374421d34dc6d2ec5837430b51360fb3ef8dd37cc65042943be48c41a3ed44ad7310850825f1b17904514631314e4891f5431e88db1dbe0788d258ca7d56fb87d24bf5579ca3096d991fcaf91f3d63881eb4e5ea432177489dfa9b422c420a062ef8509efcebe09fd15ee0620fc5b4f53c21234586ac87a2e49f305925eb7de8f35088f14a4cf341d6f31b0fa54e09d9359c7c8742aeccd61972c40ea57a8c3a7f8659faa70e651893dcc4471b57d37428a5d44c6c60f91827c71c8a2739247c3ee4f3b5722864b5e3fc5112ef35712866f09d6bae4d381464f74177c8bd81b611c9304de98642abdaf577586d28946390d5d3ce063a7cfe9c3fe7a80b5cac81f8b35d931bafd9a78632ca7cdee118890609d3408aead838fab698e95ca0a1b0311f86acd3461bb83843b961bbf8f679cc50ce23eb387bc81c3ffc652867abc3d6139f0cc5f48ced5bae73dc65c6507093a994dcebed768ba1f8203346b3e312c77218ca0f1da30a09316c3fc05076e8fe1e3475f6d3fd42b1af362c3c63870fb3810b2f14ca76773e49dd85f2f44b07cf137abab15c2867d47be4ea6f25ad6ea19c6d1b439230da1f4403175a28637f8f3ab37a160aeb49f23a497dd8d758286574107e8fd72b94af66348b8cd97efa58a1b039d3e5c40caf42316b1c71d09653a11caa79a625d2876fcc144afb8f317e5c1929943f068de1b5a9128f2814e43fe365bf9887a150cc99cca15bf284b2fc6c0ef97338a11cacd6b1a64876d5e219b86842393367eb14e5e0d1cf8462650e19b59b48a6ea975068a98c12cad8d59384b2670e13bb89087e35124a95539d53e94b4a378e503087e9f31a5f2394a4ce36e6b46f11ca21bd4f9a280d1dfb4a8472aa547dc64387500c0d7c6270179354a9104a9b31e6df9ad090c50c42397fb25a895993e65402a1b8a2ad2162f983b254491a95ca2fb7cc07e57ef3bd0c21eb41d1f16b48e7eb6e378a07853ce149e3e93b2885c4b44d1f92913270a103b732f3244fe2f1628b1c818b1c6c97a63e5171fa7381037a2769777f0b434c46761e39f06d716e544c8e196be86b4104f9dba969a187a79467336b7d16e3bdecfcd9782b44230b428468f43b16cfc368354db766c34269f5f0eff02b5af13ec9cd3dbbe294ecb1e6273b88c6adb0d6d1c59746a7fa10565c63f360a395830f59451eb3e888d7b6868da8a2adbcc7e91fa9f07fecd545455163e3acc6577bfd7a0a37d4698ad564b39a22b9a889132d459d819a7fda7016592505711e1bc4589697728e021fc9c6e83b1a24455150effe0d2d97c8487e41805018639a69e7e6699a1214d96e04b34913c14f30c93a8dfde44fd113be64f6fa29cd8c75e218c2616bc609f23789a6883e9f4d0c526876752031cad6c40ed3f49cfb5d9d9809353f48d238e71c2a4c8c6383ca3c77cf25463fd1f9516f09a2a187fe63b0291ad602ae4003b452d03160815355e2b79f18d1a4ff2d2fb68b177cd1022a2500253c7f075f35f1b6f32920c0244a7d65dbfbd0610ed6d5a0bb80817df18287011908208962c8d658c35544ce181f09f3a6693f0cb543a2f41a36bf77c32419c63ca26ceda122fa4ad8d5ed8872286dbfde10c2044d238a297c764fae56a3ca8c28e78c9d83cec78b28cd4eb20ef99b99935544a1fb1e8d486c135136df13f99899c4348828ab36f40da6ad61133d4421e5b4a83ad81cd24e4394b1f8f8e33971742e16a2ac1abb536faec7d91e210a313726bd916d1065513f07d195200a171946e798c951e32081008128a9879c2ac9e563b1e08b159c802a6f030400c428acc2d2545cb2684ba8c7f81a21c40c04f843319a484ad9600755280479e40d36e4fbd8a042f1bdd36486f6103949a6503609313599632be29042e1331bce7d4beef544a1209b5c1cae26efbb110ac5e421e2765aeee6f99e503cf78c2cd537edf84e2887cae30993b6416aac0945398f6112d52166a20130a09a504c2877e64933b9eb5634bc820b5c2007514b288e248936291df6317e0356282594bb416f6d76e3bd0b181052e061708219bcf9136020eb65f08218987c815712caf9ce71483faaf20e224221a1281f5245ab55ef9944ab8e50d290d3cc9fcc871c71744219a17c72113955e698e11932f80c70c1850cfe0538a8229471ded2f2bce520644f84e2fd9f635019a5e4a33584b27c38f2c9d590102384b2836c96f6219ffae55c70f1050cde0427f0234128e3b2cd186eadc96618628302422183e040727ab3b462f28332ce55561e6a620eca07a5ab31f56e106324cdbcd86aef02064c050305dca07a5006df551dbe4183e2413173b4caf3fc3b28754e9333482b925d3a2fb654f03b83d2416982fef5eceb9583d26576a4eef1c953068176074c60000c18000460503828e74d3551d5419ca8132fb65670778bc2c3ec3471ebc83446648b32d2ab6e9398dd38fcb5289a7c3b0edaf0d6364e8b7255ce884c8768a97c16c53d1dad99e079ba37b228b9d747f42c212f1f26168590a09a12348645f1e226233f4290caf815e59ce9cf93d17448d77045294b33f6c3be53c7b715a588b953cb236545a1366bc6c7fe9490b38a724acf929e2ad4b3ae8aa27dbee6902726ba662a0aa237394c4d1b8306a2c2c99dd42958bbc816edb8294aa63a31e95685e3181a8450298a495e622b32e5012245496263dc4fcf21ed3ba3284e0679262363461a7a5114e397fd641c1efbc43c14e520d1e17174b34ee6a028d9e3741dc7359f28f5e718349507132d89270c5b979025a613e55b5de987559f1f3438519820a7d9435fd553ba8952cb9a4d9a9987da6fc6271e61268ad6e2f71e63ae887561a2f45a61d9a827ba44f9264762b4a1a40c210c1840072c10822e34409628c7ab0c5e2bee96dba944b9e3e3e8db6a53a2181d44de9a98f424c724cab8d364eb7e3bb2aa92188390d67a3c4d2fb62e29122509dd3629c383db8c6c01bf17832061d6c4e8c043c6fe18987fc146801e5154d9d3e9d8eb8b73022f60d0851a03c811850fa93933ef3796d534e2cc0c937b92ac5e6c59028811a5de77a8f959c10bfe8b2fb8055da080ff058d458b28e4f8709f903445946f3b3d1631df8898938872dc74fd30ba5a6615228c935a2d91d9738862ea8fa9e741cea58a8628fc7a6a2bef10c7ab17a29cc9a197ba669dd01d4294a5fbb432dbde5ee58328640f9af15a1a4114a55174c65dfd38750251ca570925fe9fa4710810c5d8d5cf1cb176b1ffa19053f11a22eb87d26f5c07df49d38762efbcbff6c487628474991c62d2d4baf7507a2c0d67b36b568df5500cb9bc73f3f135c8761e8a1d131ca6557828e66033559e2e2bbabe43b97ec2edce679918653b9435ddbea6ea4ad495eb50f8da1cd73be783f4251dca13454316d9ec1c4a673611245f4ddd7b7228bda30fb59f5de2891b8732ecbfdbfe281ccaa0a763daf066a736bea11c1bfb1b7e7e2bfbb9a1bc914622ab6eec18b9361433f6681d433a57c4990dc54fc7dbd7f1b38662daf7c63e58cb30aba19c36244a2e6fab6b9286926f39d6d88c27a868288724f9cbec7118cdff0cc58f872d269ee7b73343217349594adecc3d55198aa1a61d42b28c0c450729ab7172348633eed28cf04a0ce58a9c373a70771c2614865284cc6bd66028a76a9c0ebdce135b425f28cd84feae9a89bce0864c7fb10b8801e20241231e390c61425b282e2aa0f5822f5a4008d242693c577c0612735e89290b5602c242c9cafee6531bfb7e49572844cf13e235fc58a1b427a13cfbe7a56ca60aa56b69cf30da4b85723fa87050511b54be2994730ce9443cb749f2c81e405228f5eb497eed249d3e1685b2037b0dc9b35e924a0485e278dcf8e83b26936e54ba809e500c12d9e1f76cd6fa7a0511704221feec793ac612d3a9ca0116bca00110e0820b0ec400063088c0c380ff05e61bc005172fe014c4c004ff023e50130a7faa9361e3329feb2a608119000306a0824f41f1c27cc10bc840052a308c3031a1f8f122ed49088d1c6609859a8efdf0f86a1bf24a285aec4f7808c938837c124a2a197b3e744e16e99150c6f86d43b8eafcdefb114a159e3b96a63ff5103742b1c3cea452cd8b507afc20d439d04f2e31442837cc4063e2d9d6877b0805719788fc330ba178d6500e42195fc43bb1bdc99d0742a1356478eb17f1ec0f4a0ed3e368e612d334c407858eab9963837f47a707e5d09f512ee3387883076570fedea7f325d11d3b28479a4fe3dca8d34775502edf4e9fea41e55e9b83e2d93f564d3de1a01c3b3e8639696e518c9f39e75197b833515b946ed6b474bd7d64a2b528a8d9f6a666d80b092d8a595624667669926ccea2fc613764f918322197b228c66310c92ff31dc8188b92ce7cda12c739ddc3a21cf3759863d02759ae571443c848b373b05c51ea4c511e133468c3b4a28ccd1fb97d9415850c9fcf7a3a111a9259d5e08d508055143fbb86998cd7beae1f2228802aca1134329cc7331505cf68716daf6f080a808ad2cfa4a7286c94d07a8dae175b1e2880294adae936c538ae00a5284f86a9ccc1b7f4cef662cf48510c636fdf48b4a38d6714650793533436501425cb92f45a3d5569e9ac04050845e1d5ecef518c75e60f280aeee5593ab2b5aa9f4f1422fdc6d0b0979a36c713853c59ad4bf24e944bb3279b8893efcbe744d173ae5dcf7a9bf96ea2985535dca7f5b813754d14d63cfa3f9e9889e28a468df87163a2f0fe21a6a3c1a2cfbe44d9a343ae4ffb59a28c721f9e55946b70b9128571f131f1ec5bd5114a94bcc34aa4f0307fc99844291a5d49d28c7ccb1c9228db7488df798fe7ae1189c2d54787b5f1e4f6b39028cc6dfad0a132a5e3ec230afb226954763ed7b98e28f54a1ccd5c6a23ca503ae787f0196ac56444d93594b964a0b536e2228ac936870cd23f45943c32e44cd9892823cf1e22f6e443430e11054ff5b9dbc14d35f6108574dad9ec77bb33d010859e50719dc72f44396e6e7d47981025cd121bf7bc1b723988628c3816d32184e8aa045170e8c193e666a8310f44711bc618731d627c4b05004459a38709f9199dbdfd87624896cfb44dde1fbb1fcaf751ae1a4dd74dd2f4a12c9bfcceca3acfd7cd87a2d66e90e01bb28762c68da3e3860d3d94be61382cc9330f65514fcfc95e1acb26f1500ef32187ce26dea1e821e3d45e5cba667628e728a9f1ddee3727ab43396482ce438d8ceba5432146ed085b71cdcdcde1b2f8fc4f337d5101e45086d79d392726cbaba8007140f75b7b3814c2e361bc9fee88512dc01b4a9a9a11fd2f6daa7a3714b37525664f4f6dabb7a1e0d9762648f458078ee9447f47665829ca1693db93879176e98c1465cf531ebaed3bce3a8a62f02c959933cc3edf1145493f67a47c3cfdf278280af1fd718b86089efb064531b74a4778de93b87ea2dc20496a0ffbe4391b9e287a6a1c6656929d28a6890ca2ec473951889df5f24974b37cdb44314dee791d5b03a6898266ce9ad7d79a7a3f9707cb44214ba28cf666b596041325d774e831af3762065fa29c73cb7a3fe23e46fb18cc12e58d1692b19db1da1d5689b285a8987a4d2d38c1179428dca8d85c279d051e03184ca2100d4a5334fcf292d417471265902b923408f7281d1a89a2bc56f4567c749a0c12c57abc91ab1a394c3601600af6083d3d48fe613f840f20cc11658b4d15f1631a5188a9467737e49cf375c688f238b8cdc1c365b6c942c116514e91de73abb23d31ad750453442932ab6c24e6798f922c2358228aa1fa33e386b30d412c201822ca11af6f0d263c42271eb043946fb422ab49a8436f58c00c510c131322e244f834912a44f96386f9ef26a3c1fb0a4e70160323446134bc87c679ebab3914d8208a731dbffa19995e1816b4e0cb0b134419abec3fd48a9438ef0480030b44c97725937c32bdd85a010b4e40835f41174ff7057fc1820c7c4183b7c07fc12a38c117302817805a1820c89f1fd5ca9a4adc8badca81fda1301236e448c3f2fc5717301830780df80a8aa720062cf04203c3beb92b008b303f944155678edeb14452ea4379a5273d4246a51fb37b03e343f1b2d463358c612d329006b687b269e3b67694afe004a77c052770801e8a8d74f3a698fcb81b7706cb43b9f6256506c34321b271caa47cac1a9232c1ee50f0982891f7f7b2a9363b94f3fdd6736fc4c90db23a38552d211dca209e6cda876a90da25d81c0a36715232c3cf39ba24876270f0381b47481c0ae16d63dfed59372b1ccaf5ebe7d11a9cacf9866268bb93101d63f420baa118f5a4d34fba56906d28ca2345e6fd838c86b101750ffa516f6d9b175de80840246c0d8575b11b8d0ecf418a28c1d450bc6e201383a4b5d8390d8587d37d663d8e1a9f8686b295a85e6dd6dcf7d830d819164d47966e218e3ba3b71b9b37800d3ca09b6066286bcebf99525ab4ebaa321422c7a7cd10d62f7e05343801198a995f1dd6aed648c431141b79768744fb7fcd10198289a1943b133e448242b03094367fd6ec612763ea81a1bc217ba36ca0668e732cd8174a939a5123534a4e83bd50f8f030ad2945bb25ff16b081c18f7ac1c3e00c605d284bddaee8c6dc908271a1e4ea6bb761bb31eee309b68542f43789e6f8738fc6b450cef81d99feb34fab66a1649de3d2d148360767140c0b65ed869d518be60aa55489c61d426e8913cc0a650df1716e4ebb0ac549390f228bdd3b8651a1343e3aef2b2164a47e16c1a650728d995cb2c3ba202298144a1367635c69fdf4efe30716857247e392f039420cbb870f0c0a056ff3eb6c37951ba527943362649c63b09d834a5630271472fe4334663b604d28dda3eb10248c5fb4e0046f3e036e302694a163d39037b1f59ad7e005ac0215c4400362b02594c6aca3f849c6fa5629604a28a7d9f1fd3c5ad731ac15b024943506cf95a5939e273f0918128a31cd8669fcb8dc6bf562cb4f400fb02394f1bb89e56b0e04668472decf210491e81e25f4624b052c78c1c13ac10abaf88215a18c3ae38c4f1f2b38017bc1002eb858c109d80b634428e84cadc7fcb00be2810da11cf1ff23a4d20cb1a32498104a3a0f1fc4eb8c755b10ca1977f3dec96c3a94068482bde6b5af69b497fe07659ce346eddd7c50b6c810d3536733064d0f4a9ac56b3d8c4aeae7dc050cba70d440036a603c287786379f72b27bfa73062c6000175ccc80052f7881eda0bcea38bb3a489bb144bdd81674f1ce02b3821838800a0626780147c074a0c3dc38c7edcdfcc73918a38f713d4c3d72180e7eb85926f256e7e82dc6922448caa8b4f06acd4fe6a279b1350316bcc004a88018b8e01b60be03651f0317bc77615e06e404658b72eca70e53aa6999f3b528a5a7bc9f43ff055f7451350316bce0052c58009617e605fc300040238a1685e4c0a543739fa4db6751b43429c758cb72e79645217bd6d850e79afae0589444628ef820734ad90a8b3248fde67983879c7eaf2864da7f281ea4f16f5c5152ff559198be92db5694cb81fa5b45775c3240c1d049142b0a1a1934dcb1b93fff57518e1cdfbb1f6b5451ce90f8fee4ed8da39d0acaf16acefe2a2aca131c674e6c8cd8884f51c80e82487a0f9ff626a628fce759ab6b4a5128cd7af5e2412ab3e1c5960c50d0c5e1c70e4cc00a51a4284c94eec8669d511071bd4e3f582e8a326c5819f963b40c934351509f46d9204a4051c88d3ee34c4c3efbe7278a1f693378a4121dddf44469db3437b74386e9839df873f6be4f5f9c28841dbb9fe81964f0d84431e3f831ba87e08d5b2a4d9475fbc3c6cf7d268a1692f7b036bc53c298284944d79abfc6d65872894246774c11bdb91a534b945644d76d3a665fc54a142f7368dd0af50d0f51a234713fa7a5fa9328fe8b8649a75c12c52ff72909395f628444a2e861e3e4c977252198902806eb0d598e61ce86f11105db6e10eea79356e388420c3bc99fde737ed004fe2658c10950604cf08257411a0baa11c5782d59d7696744b13663ab6e4504c9f6228a1931b13bbc431145f59cc7f6cab1747413514cc998b5fb8f22b722a210fc7f25434e1ea2b89d5fbd41d20d518a0c223abafeb43fb91045eb7cd1e93a44b47610a27c7d9d51666c0ea2709e225a3f75ccee9d20ca11f3ce7cf0d764190b44198750b9e3e8038842eed8f618a4b40dc7f943412452dabfe67e28a45a2d87495c42b3a60f8508360f4df3d44964f850ea4edf4a97ab0637d94371b29843970c8d2b891e8a2d19debebd87d441928792468e931d5b8287427894aa4975f6223dee50b03547da8f3a6ce66187a2c5eb67c826891e1d75284cc9979e9a040fdbd2a17821121b4c7496673b87428e2dff6ccf7d135a3994b15e9871286a0eb196b511d641e0508c17d6d1a563729c6f38658cebb7c13b1378a1a242b9a18cdc25c60dcda0665aad536d18d7e41bb7b50b16f82041b1a1f8a0edad2cd229e0ff02065da0200531e8ac09fc172b6001034cb082132c80d8d71acac03aabdede43b59eb0e00b18bc590177710e77e12be02e68708253f7450c2a70010042a9a1d08f637ad5dfc871f9030360c0002ac00005fc3bc09f525169288eff45e3ce6b0d9a7c118316ac2002596828e4b8693c9546f1f802062f38c12195a5ce509adcc9a3e66596757630a0cc509eb4d112ec514649a60c65fc18e7fc8c5bc736484586a24fb5f5c96a14c0051747a83114c6373d2609b17ffbb9ab2e317c1e2eb2e46e84a19c2b91bb179927780986c2ff6664981d24d35d5f2856b7c5a58fa602fe177ca18117fc0a4ec06c88174a9ecb4b1aa4c9717f329e0b2eb0505d286ae5bbf8dd450b54604e050ca8410a56708137c1a7e0043238c10b3090028e810b8a1517ca350dd35bb4b3858274874993ca5c3bf25a2859e6cef3f81d099d2c141df84858bd0ff2502c146566dd4c5f1f86adaf50ea9d9aa0e25a0fd36c8572ec74b8bd5a4d170721e802040889b2fdc6dceeda3fa2f4fb3369f5a3f9a6ee88b24f06fda0cca741c68d2878d8943a1b238c289f9a7c70cfc8228a91b437c7f478867428a2648f32f41ab7eefe9a883288b9cd76d7d935aa882859bbe8fbdd6fc58d8728860e8eef1a849fcf31442169f66bcc9e4294cb434629293a7e2784286cdfa48f931b44211ce6fc2166fc39c61344e143e79891842e1045cbbb5bffd8f0690544b173868e75524c7eff40d8dc767d99f9a1f4315db28dee4371ba7e37b9877808f3a1b461366d6886945cd51eca26d941b24374473d1447d2a59b44f2508e6f9a619a170fa5d68ac91fa277285cb59c9b450402b44331498dc54fa4ca8d397528fa784ef720449e48870ec5d8f672399fb7338ecfa118b6d53308ebbe9fb81c0a31d36a8e3937cc1aef387c51991dfab88643f11b368ced747af2923794364ee4c89373ad6a861b4aeb123fc32bb70dc54792e18318ce7d72cb86a239cef42185a7ef1c5d43f141dca899bbf1c7ad6a28685dc46a5d7b54a56928a4e9a453de7fa1198986a207f5d10fc1ebb39b6728af44c7f819e69f18d30cc5cf7f96a29261f03896a11cb321b7cb4e86424486c93739421ec918cafe786ce524a3e4856228ded7c6721cd59a290c4319edffeee84744b6c1500ed30b4de3e2b2c12f943276c9cf865e28694eed345cf5e9edba50463da2d9e13a2e943a984778a8ad93fa16caead31511d4c2e03784cca948168af13fa4777a60a1dc792a3464c8ae5088fb596b7859a19ce3d6a3b9aa0aa5467319fff3113115158a9ba67378fda75008c991399da40d31260aa014ca0ffafeb368c64fd98842513f6cb2d79045264a5e6c552514d2cf1ea6dfc14f7c02f88462d438d9f532a2130a2d31c489b9ff1d0ec22614e2e690b6f35b696c30138ada4024f4df7fe4bb84f2ced8be23f58e0d542514322c390dc9ea1e6526a18cf384f99f4c39bb1101888452cd4ea88fde08c99003f0082d4023e809b0083bc671de8399758c44683b8bfb7eb870180b00157008afa499d98e4b4d79f1e60429800103b8e0c2ff042d6081b94221943bc96f8a17370885461fe6cc3caaa64902a11c3284ac41c7c21f48007d50ce6adcabba698c00f6a0689d9ed3685c7754f3a0607f761d9afc1d14bb2faa315a07e5909ad87a901c94663686abbe8c38284e863fb193ae39587c8b32a87e791ca73d641fb6288d6e77ce28bbb95fabc5f69eb2b4719e168593c9a9f5e01132aa5914426af0390fe4321bb228966c888a34e175165d2ccadded18e39b1c2c0a9bd52f71e221e4e4604de25e519a0c2747ff1caca3875c51dc549326a95c405c2b0a79e7714cdf3e5694c424672449e341dc2aca51af4e24d6436bd80e5594d3fae968a7e9dc34012010978ad2c7a9cc101b8787434569c3c4defd89ee14c5b9967e9c27fdbd1ea30e678ac2ef3f869ba37b8ed737006bb852947e27c47c3851e21be4941465d9dc1931ca34cc9a76917db85194532264ccf57a11b18aa29c37cfdce5945de01f2e14c5fda0112b2fe57b195094df37b935862ffd58f385fb44c9d1762777f839c58fe78942cf6ddaca47a9e138d789b2842c31ac4d4d79384e94643d04cfe81edbc36da2902fd5f341a3ea70471d4e13e590fa0f32e72d5d26ca2077f8d314197f5889124c9427c751fb34bae6681d97284c43c77b52f15982c9a041cfc7b732d757894274ea1dd5d7b431399428acb883b3bbd792ca27516e8906aaa697244a3bc965754e74241e71b84814457ba2dda48c86834449e53a429884ca708f28a45d890e31ed6ae672c5708e28a47f8df971f57b46dd36a2546f338d743c8c289a07e98d6b3aa3915e44a1ac6fc2e386f241471954e114510e214aa49190c54d44513fe3a849bb77a34910510c9f35886d6507b90e517e4717314cf0571f0d510e8fab3e41b3e410192f5c214a6a91fb2b92b66b328428cf64d864d75e5b84750b378882bd69ccf23946a99a477082287f146b10f3790251bef7084bd51b10c5d4f1e05cde264b94ff503669bd9e087a1de4f643a964d2ed6f67633c197d287e8c8e63ebc76747071f0af3e8c61e468917a9eea1183ac40c92db4c37561083178c099c1e0aa5e1b739826e955a1bb83c908d37c9ca87491b3c3021596292aca9df1d4a91753ed1aef37fd678b1956787d2594b92e8209fd6a1d0db7d1be297c7dcca8bad2ebc80410c5a4035ca3c0d1e2d7074285b77c631e95cbc53f4869b4331d56c72a5d1ed6df0e450ca9c1e74fe9c76a17130381817746f28238dbef57174c763c40dc596d0c045ce5bf24f189cc0d0e0db5094f91c4fc9c91fb6b802169ca003c78642edcec30ed138e5d25b43c931f40c738edbac3d3514fd43fa3cce33a56979b1158332ad2f60708214e0a5a1981ed228df4386cd48c4a1a19c232f53c3eadc19ca9942f3c87b4eddfdf062ab8b15b0a04a0178823833141ce7ca6ab37b4d62190a230d7b7e52f823dde4138e0c6510423d49303bfbba88136e0c256fb39ccfecfa90ba4cc289a1982e45eac6ba2d520309178642fd07d978103c30946f43d2cca6eb7dc187592fc1d6ecf342317f523e97baa488f375a120e1ebf2d8af32cd3f2e94bb354f4b87541a22260bb7053fcf7f33ff794e0b653d1f55db94b199bb2c14266d88eb9429b61ada050b7ca8e0b0504a57d91063a5175b7785627e6ac9e78bdd0cb67a18c420146785e2b9a5cd694b6e865e158a31c7acff0c8e5fb5a642a1e1c72d0dfd1373704ca12c5919dfc36352288350db7378d6f7496369b8281452c3e029f7e073e40e0ae5fed9cebd29e663083fa1acb531973c940addccda704e2887e8fac9d7bc2614e267f2748dc3e8b732a19c32b96344b2ccfee925941ae64919231f433b9c12cac9317e9c713446c890355c12ca2775699f6e3dc74b9050587547a9ba35eec973849265a472249e334239661cdd5663a66928a3704528a34c1b2baab32342d1f69183a83b6962cc9970432886e019328cdcacfcb0114e08a5cef1ab416d7ac7565d10ca9b9f51e226d11a680e08c5adce1bec415ac98ed2c2fda09844c36c746307314dce07e539911072eadc13fa5e0f8aeeaf7a8f4d45a53ec783b2c4440cdf99357eb3b783f2de27d528e93349ca4e070511cf293ba3edc596e9222f07a538cf38469e6b918cf7705092d02d9637aad92dca377d56123245e69e700a1806b628a8e770a59f7d5337ad45e9b35d46c93d397e6b468b52c6fb33c79fb65914db1dc6e821a6655146fd75db1d6d2c8a5e1719a35c9149ed182c4aa7a19bd3ccf6f1f9f68a926767d0b6238fd731bcd8c26a81b9a2e0d7e3316aa751b186175b63001b78402b8a66ffc061e7ece3e96145b1c656a3352afd72b38a72ccaae132e484693055581a6ced56ac4f45399c76cc742947fd70541427e3de4f6aac8f91a728e376d3ebc9193345a1be0f8b40a8348f85e258281a8bc4218138140621a5f70063140800203c280cc6e1701c4bd280dc0314000353282642382a1a161e1a221c1609478140280c040642615018000804838150502032ce7530f90150644eae6ce784dc0761423286ce5b71c85ca144ba3ddc0bf79db3f2dd4d714737f0a11422be6ab873319c2abc7361cc5de845d560fb7b380d4596df37384c5485879bdb8b6f681b227bf8ddce16e5f7c7afb0e567f87503270e25fc0e150ad90e7ebb1e0fea39b19206891326062910ad4fa45d7022f62b32590287608d4b99f071619584168943d6a37409265597d652c65edd6abafeeebf1cdd8d1685435da74b1d1702ea9b19c91871554875ec22f24171b7264139dc40534f89f638f0989a2605f978b96a34693ac0015bcd92882efbcbea72a16bf61faad24857490796019c4a99c4f19b30ac05a9d4368bb0d274724e2dcb8f31e95537a49cc549679f4ab08e1be39f6157498e3249fd8bcf3002f1998adb1c2b02948691c383500242296f648cdf4f4d1d4ac7783d69c8aa210ee16d7013fa4bd8a595006ed25b1ad07363b92951c21cf56ada513c0dab26cb662ea14ca17efac7ead88b666523005f04c07b520a80fae4636679935e54675751739debfc011663525da4c60642aee69a983a79b73f5e7cf6848b059153bd052ff76b3ef6d72975f81737c4c01e007a2bc27cfd07e51e21581f24542cab2edaf4ea4b22a206a54640a79b38836fa9fb5eafc9a58e6b6204c28d113c94900ddb08ed75216d6c1b58170898c3c58d6b25072293b0545ccb7ac3649c04317979492b086e26d159cc774770863a38a71e148e9f719db63d477579881744128d3e0d343a2829c39697466d12daad3fcf453f32cb0153cac560adfbb9c824fd992f5b53d051f1ca0332fc62e1303dfafa735b05e8eba89e4fc00fc847428be08d038aadc6aef5014f20fe21c60f9e222c902525085ae44d797aea8a80684d381de373026b2c5a301e2870d2a68d0d03c9292104a62369735625b74eb03f624195bc77108db8da156513804cc4ca5ed29481e6cbd41ea303e790c2081430e1429e440c0e2c2b86114848a9eca87b3c94a04edd94140aa2ac0bfa0da2e3e2d8c7cecf2330971aba59819f709d3a6766d695260d74b88e1eee0a42bcbdf4fd41354c28dd17ccffc02dc0fa3a70cbfacb105b0f84c69f58a90dc80c0b9872ce1da98228524f8e6929a35e715942499665896a9702d8519c32ef9592f8707cf6b35fc469a37940962ceca9f6f89ee9c1a73d7907779c3102670f09ec8be9d2786176530e57da270df9a53f5e5e3c1eb0238ca7f8910083bd064c2320470f5d76101ca90df9613312acc4f9a12498514b6c95e825839e2b9c947a5ede49dd1b45c468e31be98e9009a841a7668a0627c3eaf26a639898dab16ba90e197c6f80a77b49531a1bc78e29e6752b74ca38f81807b38c2180b5ce9d424e6a4f946a2b61e98b359205c2df1409a453a22cd362105e4dd6a1453cac7c24bca6d4de6bb16cf7d759e8e660706768ff7be1185a2221829c594afe03609a9e804a0fc7f033553807f88e72a080fadc85e35751c0c1223b88f712842794d06facb2cad7bc7dc9fe10a85a2d93316734c3d004f74e10357a67d7ce9fbc964919131cc71fde8e2cabe3850ad71084d057686912b2ea2b9688682b3174181dacb5e0dac24d1127df66e547cfd00ad2bbc21f537a681a0362ed659019fdce302285413a8242e12baa94c4ade96cc7b6dd1352430294a5b9e9a8042f0f87d3ce5bcf64c4fc96b7cd500fe1db95d394206cdc57d5ff3b4a881836550978835b191aab09df4bb26091c0ed5d8141deac3c6cb1b41e6760f69dd6f317aec2814954ba3d074b270c474304bc710b08b14ebd9b56943b321230ac6912d4330bfb89e5b190a68cb9670f5c67740af37bb5c66afd16ca18122d6bea4ca7b84785cd68ae1d505960a8c4e46bfb67027ef728391920f34ced44e1e92a2569268b6022371da13ff4bfdd9ca09d3cc2b4076287ccc3ce2032cc92cf89cb9e714a1f7f3911b990598182e98c93651b06ec5faf2d502f9b9e0d4d58a5a760cc613e12446729a818a317f4e8b76aa6c974b9010766e7520f8b08ee98f807972a81b5a7fff1c041075ed64f628945cda4b90ae0037a8662f669d39ad332bc932010c3027eaf2b4e71111e00f92a629d0f3303d1e0c1bd5c30d5399a2ba5d4b23f54e7e8737811a9bfda8441fa9ffab1dfcbd4fc4a56102ed9b85ae3d556bded73751f8d5ac94aeb3f2b09648629e4d8fbb463bd07cbda5774d0da707204c111d462afb2d315396087eef1491f813658b34ee88c1b908f9b43d31deb05449d239c037f73359173dd1eb4dc0e8bb17350126b8eaafff8c1396e4aa6508aca2b36ca887a625b10c230f4648ae752e7014b18e8fecd5e64286ae7480fc8cb23665da2a83818b982f1bd4c0e4b74c4fc06c761584ac2cbc93bf661e438c6e5dac1c263c3fe1afb8bd9ec6c484d94acd6355644813c26f5a20971d9c656e3f4f61d2ac9383d64084fdd7ac039be54a72ede38560d0b0b56cf0f649521c6e86309b4bc975bc45ea101da1f5ae5a8b36252cb009f463997b2b93accc663a88e9415e0c395cf4dcd9855492a9f4451b3bb1a092e76d430fc89025a579aa6ec5243546da579714a4a92b91da77665b1d11113a95b9bf35dd1e67f3aacd50851b1ce2185d5e405fff0e79aab5bd46a7d05f58545be22fbfcfcf9d4d8cfce8919a1f348250ae2d9a56976e720449a4c0d70b0ba5ed2b60df6f9d96b86030f1caf4b182015fa0ebc86e4243a0bad638ebc87c8571dc82666d6c90097047f970aaca662bb4732dff51150774fb987d7846bf4c23aa8174f6036c930a5e600e7b601d2e390201e03abeceb7773f8e55d17fd1715f2a1a700faa5075f536e442f1abca16b735ce24076731a64156eb1b8b21cd346a31105a25b2ebf2b39290396974754474e1c7f503ee119edce8e47ed23654632e7579487e7e923aa743ee7cbd75a106f44d38e133809c2769e29d6c5f308a28807b25a3213ee5d9bd9ea48186abf36df51216b111fe4e6ecd2fa1c232eb64ed5941b0df3e60076e84346c77823174c57636c4bf89b711014f0e735c9eca5da97aafe4d41c25515440722e2b5dad6bb31d86ca49273da30a0546ea26c6ca66acb4377baff22e80aa2e48b690ca3acf3a55d823f83d324cac389d88dc3a66e1dd42760670b53949a3f00f81d59d2df44d84e84cad193bc0da9dc4c727c41f906f56b4a9fb7143ff81691a2ca494189bab385bc33980d1cbe228a7f0edde36f52efb035f9694b9333c2887dac780da0030ff3be295f400a259885008fc419439be97a267e6f745cc8d09a71b1c8bc3d7baf688a85b2a177dc16b7d7c7bd9a85633bd06ff1a11d5d6159068b71712b69ac70823c52020e510cfd28def1cebda5c116dbc0754cd97270fd388118f73148bc8fb3f3805a5a1b84f6434876fda05624687b067e318beed1da796cb9e26e1825dbe5f53f090e6f9aafb53f9140f3f30d2383d95fa023e680d28a7e8226de76002070dda1c19bb61caaeb558ec73b0c9a6d46fc22316f141386c2246c100ea8a8d46c9204e6c9d94e31e56a148bae00bb1fa70ac6d37be2bc0541a823492553cc6209d40451832b308a7cf3e6a07e4713848a82050406b904291a99651318eb13af8701431c25da47238bd5605402f144342e799335a1be6b30c0a06c101e7f59004b8b6aae5c7edbd96e6ccb3fda16ea42e5d2d792db21b562c07f3459b5cd94b0f93099ab53c6c3d71e7bc2b5051d17bbff3f7be4ffc2cc2d5a2e026e0d52b35036a699b33f5f565dbadf566733f9d161ce3daf608c1ffec5b7fec023f3bbd039afb7ce5089b400bf514cd8c5ce1fe37495ce0f673b488872b5854b79105188bae9dc071cc39b6e224f3e06a012a47fd7cc5c034722a719b1741058d99341ea019dca8e88a01fb5e401da393ff592a4f021f5518d77389f29c7ba145703f7c31a1f4cc067bdb227c96db7e806a15e22c40a5745e99594c0af08a2fac17a16028e83ebf6a507e22baa8d2926deff61942c0f628a447a1d4918ae9520526c525176b2a9a182c7a017089e6517cf018bba3025849a0b9c1fecc606c8de7fd4c4738d80a2611b731e8299057bbd508903f33cb143cfec001e6f3a7bdd8eb7f48cdbf70bbfc48340ecac6e8f7964a292488cb3326318566ce561edbc2ccdce744318f44be0cf304daccd87f61dd25bda5a15267575ffc964bdc6c6fd35cb8bcc7faff9c3ae731a781d90cf5e2a40b4a225850fbccd0f0dff52dc69ecb4746572caa34ff7057a633ef69238a1c6f63eb76722892c4578c9ce02fbe36822bfac3c6f14eed1a477ce85a05ae7e5ca901183d8731b89128705b3204fe6e70a1b3f3c89f0f93745d1b2c6cb50f345dbeaadec88ac1fd8288266dca6c5be6500bf739327756cbbb6f908d574c40147acffd49b050af9644fbcf950611b1d669db27be62b0fc61e99786d5d4b43087c9b9f3e224277b86ee516ad1dd26bac94324e6772848b39c605ec1e25cf9c02d0bdcd77ddefd238a496499267009fa9cb24e35ddd78795b4b6abc08281c104070ac0399ba319a896378da516e1b34317b6c4fc103e8eeb593078059b60814942e47fcc1ee2ae563e94d0189b569591e6f9659c10b8578c230ba72c417b282e57edbbebdfc2ddbe1a79406bb044d690c506e681960492f330a666810a72bd669a2ee15e4094c21783b5ffb295aa542eb6712e5ba01b57bb99f80253abc7b67069a4582441eb122ebbc4631dbf00e27fa9d0003599a8a712be58010b9c7e6b3920feab3fcb4856ce86c09f8e63a43566209bef7811bd4d7a7711d066bdff02cbf193846216935641697d425fb4b96f8e7ad8ad27da808c33081977bc2595a043ec2a0dec7a1dcb7e7d8138a9c2ff74c5fd479026f8c20cc13ab00dc87df8e26f39c0e7ff544a27c6eed1c23ae71bd7e31899bfda1e484f638b8714a26ebdd80d28d0bc29e20a6038d52ada1336211b8500d9d0725484f4a3e06f415261a7a8d8bc2059c067cbdccff90b30705e3f5d4f495e3ae65c7c6d55d01df25e2b45eb0ec5c83e75fa9c3c1825e871f2e586ab123675f1b2709cde08a81e5060ddc7510a0eafb6e0ff003d66d911b1df0fdcac3f942a75ebd1ea31b3f8a9e11e89ed260dd02cff7a890dd4f02c75a3f46506132011066f0310c12227f29852d6a3f9a90af7e780ff54549b736eb9534fc550856f07bf5b331abf61b333e37ec24dc5c8a0624ac442983cbaf58b2b176566d5f1381a45a97cbfbe1aae12461a65a92b361553c790eb0b53ec4a10c67884e1247788ba203a17143cb507a3e5d1991f6fa0223af4529a137be8f5afb9fb4e9e6580ff52d768caa55a46bee65c9c8dfdc29b56f15421b9e2614573ac6ad4c304e752ab0c559466d7cca9a0608ad3421daddaf46d6fb1a0fbe5e9237847a6d2761a9e5b45480d946fa8bdbf05d376168c9044b3a78f345779f53903d3143bf28ae4ecbc800fb609c97b70a207590f0b85c524cdc2c874b2ceb2d5dfb2754b5c6637ec4b54a0cd28b4971371a44d0f6ccf5ff73a8db52202b135183246f147894d126366f5b5bc770a5c9d7ae90cb1d34f32caad0367d83b555c372be7bd01816e47e722e44f052864cbc4048a37589046acc580431779b4b9fdedee934d2339e428a5a91777ca8eb34fc329d0e98eaa26d4567c8cfa3853d3e2cc06d8d4c741b1a614ff3fc5b97a88ab37afb1b649fcf4a59d7335147a8e7cc255b1632a514e07447038333b45143ce520a335f681691b746619ffd25d0f4d81af4bbe227a6157978554410add13a857803c0b6173546a4778b175a5cc6f6e69ec6d66faad5d07e39a89076659146a5b3d80246a7d50833206858e95512b9041d22d10f190a7fe260670941a8739f948495007ba209f71a4fac0094704d297d4ac4406917568a069738862c89ade77e580c966a87bfa994f78b0b1d14a268c8c7a19ff74b9e52aebc6a8f0d3cab278ffdfb8708369f9e6fe0891ee3a1b27e0a2f6317bb872af4ed02ce7356fa1c1c399320431bf1c21b44483821fa2459b20c94e0e275caf740b7f65380ca9b65793d5191e1405446a08ca53c30caf73a19ffdd069633c4dccf61e44d98b9408bc755d6bd1dc1beb08660c7bfeac2b8e2095d63e154f7100cfe529044639c6e906e649b0eb1d7b7ac1fa326a293c5482cecc7d156114b4e1e1372099f7c8e50365225e801e88d00b171bfb4a9ae73c483ea8cc65bdf1860cc88674a4f35fc714df303cc1a18514369740672036b59a06eb8302ce060ddfcc4c2f42c1093855c5a48cf0215eb2e8c3f31233e5316766b015a0b63b6800b0bd3b090636061ec3a18143149ad7ac1f082b19ae1dd62186999f91a7e2e38a1db49c730e1c9ac5e7d5e2a969fd3fc568cacdca48ca1873591b3f04297f7bc3533bd03823e75d82e97d1b68eaeeb6eb680ab56472446578d6dca5bd2d4f26502d82c824b348c51fa91a053328c6d3874f71a493b28c6101cd13ceff2afd6614772ebb03aa51c3603e12b95e5fc391a75e3504b57d761cc3f0a7d71483c3c07359eb8d77b496049f78747b84c34d3fac8a6c003de8a072db6128ea5c183e711e2c8f443c3aa7b0324d3ec4c3d464940dc23cc6829037778787325864052e841429f48c8ee07cba930b82e750ea32675c759b48ef02c1ea0e094317fe6dfe1a713d6f1db9cbe7453aaf07080b2d2a5874b7db0e23c59968f80b38041710517dabf0ea0a9857c5218c074853bc61ea6edab17ebd56e9a4787dadec0776f91c2353b93c1a0080f68a265354364b0a12b57d74eb3f81e6c2b2cde0e553e03cfbdab8ca37a8f0237424ee8e40c0f8f1b47ef6dfdfaf0907c14997d7da13e4caee2294e97095d0e2170b80f1428669115f7e89caf4747ee1762612e70127e4ed9ccd03bb52980b9e6bca4f3b5591bbe52644f9534e1e988972285fbf54142e374dc1992aa46b87c82ef0baa15aa10a44888c0c287422904c8130029b043584e00a8706c044e394e6781044ad0194c7bd96822caac1bd318324e324ce737667f398d6676f90edf7992ee1765ee891395c855774ad738908909544ac62a061d359212748e5cdb17a63440b7b607a7c539eede49321ddb0e5e2afb96383cfdf9c17fdadc8eb959000f813cf4520daff20b728b602415cb1b22dbd7756c1f24dc54fa549bb76f0e233ec313cf5dcbe81403f95bb7a5cb25d0494b3d3ef2bb879aeb87a776cd5ed482378269608ef0a67dac0364cb62146b945c223e3563376d7582cdbcf1f136dd2260060e157031034a0afc2836993bafb19bc3fe001bd48b18a5a1daf2572045015add44b7b8005b6d7163d6a00313ffa6c1e32c40166d88762b5bb5ef855b89df423c0a44e1f5a17433081c3e45408ff337abe3d01083ecd5f555a61923df703efcd93a24a472b0fc867c7d06bfa03aab63e4efdacd51238e150ee5b0175ab69798cfd49e073511336a13dd40a8aff7b34daa93dbbdbb0d4e5f705c02dac439201213aff941f862c8557e496d505a6230960fbf9295f1dc2bb12f3291e13e0cce7360c57a83c633d132e1792aa42a6dbc582168ac99e80baa2662d9c8df7af93b464b2313bf22ae6931e9a55b57b47e0923a0f41cf025de0e3b6efa3957ebf81c053532006b80bcf6deedc14bfe3009cb5cdbaad7eb2c581f313dd0066534c1e8145206c4a9729e4a67215d2a54f372531b4ea5ab5df45dbf4bf5977193e2dc5393ee594c2da3ac2c3911faab92135662a21ecc85d8fb71162398ad609f6730af3264bacb82b34a3bcf4776708423ad9c432d2b741c551334c7f91d314ff602f23362f163b7c57339febab8d1ac83cfb3fb560ef5f972b5750bd354b14afd12ae46ee2bb6406e6d42a889c846ca2955192087938030ec3cbddbaa623b8a046305c0343e062eb3695f0235ce599de884361fec0b205602c0a0cf96235dbfa754bc82c001892607f34a93c13b40ab6a50b94842ce6b959bb8a248780954b81c9ccb9c58e40aa0c27b2d212c180380c98385b0d141c03744f6b4f4469b07c52812bfe033efe9844250c46af035e9c78ff8f5f88e77236008f45649d6986a9bac26e6cf7e339d6b96f94c24e32313ad8af39d85e4dbde880bcbec6ef94afa2c11780d118aa8cfc71ff10eccc7bfcf2f7a4b39bb98d303dc99955d16c8f3ef6bf310f0bd8bad1f24d6d61b90fa45ff5ffda88433f8f2298c256b5db93aeb02a145ae17cd87e8b1d0e5d6c692af30e31765d3683a89eca5bda01e0122f3b0db2d27834fc04b0e6cff8b32ed5758a6dce8bcc83b4f01a24d1b4625bb38aee992ae694018e996e7ae32c2bc4c168297be1dc2e3fc98f640bb7deaa6fec3dafe4dd465fd002f7e231b9b974248de320c2698cacec1df41be10745c04d5c955cf5dc60a127f7725e79896df05d8321027b943b7ee828ec10148a07947b90ff95feb2ff479e8cfd0cf86f473ae72a22b84f47df4afe07e0514cd78dfacfdd2c87a5328185ca1b8f715e3e7f55ffd7e75fde4f9a1bdcfc11f29fa159e466ac608ed572839e379c84f525faa7d4efed3faf2fa01d8b7e7afddfb27020fe95a3cdddf037fc5142df125327fc5e13cc81f29a936ec448c2a01747a5794f0c55280e47307025b490b7a9ff16f9629e85ad9521dd2732a43e4a991ff50e17aa7bf60dc680127f097d5dc3a5434febbad843f35cb1a234a77a16d07303355b188a19ae833dd8d856f8cf213d9556b1453c7433e4f296e3b39a1c791c7564c9e9abee509ff72ccd9d93d897547211b2f33a03aa684494ae973c6fe31198e9575ff74e734c30ce85ea1d13a23aa1a8d2bd1cd1ee8217d7b348b44f48f76c4a743fe1ea3b9944b727c65342734da13f8f04cdd28ce4890114ba33b23a146b18d1ca3aacd6845127bb3bd6bf4da68cf47bb846bd469748fc6f1b7c4ff0989faa36193cc54d28eddebe3cba3712d3d499a96a4f648551d310069975844f796070930695030ac2a50dc5d43247485f3ae52478277908022bf92aa25550b7720abdc56373037ee64d85b4c6286deedc25bf59fbc9536c000303d6db20c5fa32266abab6e721cfaa407cda00674ab3605f105d8981241944fef8a073231ebd5e774ac7e63ad6b656d1f44ae06359b2257402b374937f839b6352e5e6b2f58aea545ccf0ba0ded6b5cc05ab1175f0c3362175681db2c82ea396712594dad4d23d8e0911b2928ba4df1e1cb0a4f7b6b08c9143b788fa7e9c10402855ac354a36a8d12cda0561e2ef78b10a13b5666ae8eb20609fd80ac26f8257bf6ed56db820a5daaeead1ed4c0dc398a6960739fd3952474aaf9fcb761d9d3c714253ab2bfee0919cb9960cca6ae57d954ad50b2fb29d0f11134ad18702dcde46ee8be5b52bcee7a4b403071542a35e8b9bafd43efe4d9a0f616d8826d1fb39a0d311baf3eae7cc165faa94ef9cf496489160b455b438f751aedae7bdc78a097f279bbbf9b5a05060718ecbd8e3929fc4204a10a60a71ddcf4c60565d0a983e75d7ea93cbb5e7875a91c9bd026f4fb4ed5357b1d2ac39c9e067dd28c96c1b1f5eb03afd93efde97cbf0be96a4f8699eea8b796a468043bded789b3495b2eca731f14224a29d05472ed9bc1381138385df0164329e92653adb6d0405e47c7004227fb8fdeb685cb9cbb020a7a734cdb16011af43e38c44c4330439837dca20144af5c6186fe237250294e865ef499bdee1614cb50e4ee18be3c057d0d800c6e790540414daa7285c8a6a70500633e851183460e70c3ecf2969b564d78d5739b0efab535b86ee99bb76d8c60a51ac6e2fd422822719be50bb52e8e5ec4c770ae7e55d9385e1564bc838f2a212f1ceaf4dc4955b428a65ae38ca13b2ee99eea39ff65566f494c321b229e84e1887c69973e0a83172d93328998e8ed950a56cf02405d298fe3ab58c636edeefc567415b0a6e39d292b30aa7bfce5b0aa092426cb7c3822e3bd67d1f662bbf5c5d0cb00422b0479299f297a73d6b446ab43b1fd2a7e5c997aac763e6198633100b4a128d35cbe90199ea6f0bb36df7ddafe52dc0363cb8f1db39ed31d455e590a302ab4561ec38d522ee82e6d7da4f16f754dc0a60a1a086d696917847952a109785562e99c17b84bc74651a935084cd116d7ae3291618c0d744a26bc55f1b540c4f60845e7cec362964495b15caeba705d42bdcb96c7aec7d6b8c8bd5eb6705eb370dfe516b9cc5a5cb7a1274c962f628ab1f995b11d5baefa13c9c051503687b4be6c91a09433e872c17b3193e3aba0fe609d1c005cb05c3a5d8e8ecb57b540cea8fb0b1b181f2fa5608e7c79151c6f0fec92cbac9501c9ee6018bb685ce0362f5b119490d015b38b9897f3205b968ab439a0b91cc0504d897b30362e8273799d5471924bb940a53127560cf04bb0b928a17201c547292c8a4cac85cba7e407387b69b79aa2e58a29156b289d53a46c85c5c491f1b84b0a6bf335cec015966986d0c5865161f9a58b7feea6b02c15211eab5d61b99117ac65fb057b17ae509d05e8264d040f25c49d31de1efc89693d46b90a8d6f40f1cf44ccad2cf8fb6b9251d3643405dff740b3d908d348cea8ea477f48a974b4431755023106e30317c08536fbb0f6c9839f1bf27c02226f46daae169254cdb3cda63987a4c18e906b494602c480acbbc7e6ac341704743d69f941d1c1912754f570d83fee2a68b48781cf2502b2b11857357dd8637b29b049e7796cc24ddf77cef8ad13660e8d89582e5bc5a58462e65838d54a44cfcf595f271b8e8cc8a13d0ec619d915a74cf3b0f005709c70ce3174fc62408ea380338b63f073cafc6e952dea0c949cb25c8c5c89461c4a20878680723dc13a341189e22b8b009eb82619b0bc6f51132cc84c3b96ee39548bf3dfdb6ba42e8f83b3c1b6dc78d34e08296d3d058f8a0ac436f41b6e16d3a3ebab723c9005c2b8051fdb10956654f792cc062ec3d8c92761c3afc5b49324cf0af574bd1e9e2e370d7b2b5c99dc8fa2f433d13bc75548fa248fa907ab97b7e749412bd90116b4332651abc1060386b174317823776904bc869503d50790a7b08ae1246d9a87f9901926672fc3e30d9b5a88d5e87082ea6d396ceb31928da7e40696dc95ba8feb3aed3044ba69ec5d6835f6be7eabe09c520ca9876cda0204ddd86c08b71b3d54ee26eb5c6824ad228705480c03962c9c2e67a647914bae5eea64cc3be6ac1a63df8c05e0871c725913c1fbec26a2b7abe29e8c6403c9b938a7ac57a51313af7becfb883c2bd8e17541db71147d679ae44986f87a8130cccf78ede5b4f021a952ad95f4a4e3a483c15254e485613acef9fe3ff8cc68d4ad7a4cb3984f9a1f71ca116bb88a7311630656f2c0286f442438441e3cd576c69ce1400866e990a82d4693c5241f4bda58c389c2a435389c66f4f93fc721cffdbed44feafb9cff1520dbd15f9188805de77c17c67f2f66cc7c57da7f066070bebbbee7fc6eee5ff4012a135cd57f1905dba4bac3fe0bdaf6ed7da60040114b1732ec62c28915a2440ca447390e91e668d1ebd1a943bb9ac54954c67630506bacbb34acc6aa8e5718004dc66c4acfe0e272c47336b0f27a5e413a21e8a780845902aab0b7943670b254720333333333333333333333c64edb466be5b58d5d2993ada2b204429cb396949494a44d92b5012c342e26342e26342e861e043e0920095209583896b514ad66638a492d57380c6e59e357e41c39622b1cc414bc5a3bdf2a1411aaed43c4960ac7dd21dc7f5c884b599dc2f1f897e66949a570d46557c1322e040d66148ea633a242d40e0a873f129db2e8a95afe0947b12c8c058bcb09876f39598790a41f64130e43ce29d3dfbd31fc634a4826d893663b7bb74b389c76cb644193759d4a384889f7c943b266974e128e2b977ac875bd31720c128ea2e4ccc94ff276b73fc2f1e47e8a90736c84c34acd94df245c84839b0f9976d4a24ea844380cdbeaae52b9a6fd211cf6edbb67a6288483ec741e523cf7f0d205e13875b5c64e4533dd6c41029e800b1715002424100ee43242dbf469f40bfde028afc43c396747b70dd307c7c1aa74c26f0c12e5d383c39f999324291aa53686045af4052a7970944677474ddec1a1778b5a57da90a3a91a5207072b52c12f3d35a6ed1c1c87c8dc27f5b57122e3e030936e2e8f3e6f70701e1ed4fbcab4c1914572db98440750c07401598363b994b1e3d5fba89934389cb8d75a3df50c8e3c07cf0e17db39ec1c4369c60d192290c141a8a8d173fe18e5bf21a3988741c3d4a04152903138f08a6d4973e90b120647a1435cdfffd48f793206f205a7eee40b9bb37926215d706439a4dc313ba7d78f1803d80a72162dcd4a938db271645d40561ce6f43d7796b9e227db06afe22833d564d110a44733370954c541b2b52031bb05efc9c750fabd00a6e2b83abdd32eec184a5bb417f101a2e2e042bce67db1aeae4e0ca5b5009ee23873df4236dd36492c861269004d8177640aa990d3c5c450332e60290e47f762e4ac781fe3458693e04d0d25c5d15d9a8a0ef63131606c518304852980a338aa34912fe7737c0ca74a004571dcf937b6c76c59c2e61f80a12844ff943921c76e17430914477e9bf3636e93cdc9dfa2b503f88956fab6537d8e780ca524f5c4d9926753773a61105d013b7198ab33d374b60d3e553a209113e5c4e5ce9832c69237f1ecb4b898cf36f85f8b19315cb8a8007c013541cab32ed326e1b9180a638b1930ae2c403271fca9f219f1313dbf2706888983ce5cf79e4e6c82afc58d1bc6463a002f7190a3b4cc24e698b5622e404b1c6adc70bbd129d5630056e2f02ffd9d74ab493a404a1c44f91c33e62b96af2686120c53022d66ec660670125bfed0db1263621e8695da40491c6466dc089ebd23e5aa193012c759d2e5866c6feef740e2a03fc76839d485cf92828f38a81c3da6d07339471cbaa4f98d5671238eb266db45f5841147d17e4e332bb588e31dfbd016bf6c393b2ae2f8ebf3f28aaf89383449a98897ce43bba50444c491c655b8206ad11d923668c8b84165c0431cd6d9e79d55302fcd8a010d71749fbfba257743880b0d1915d8c2d080800b17366860010b713c7e6def528da545421c4b56d6ca2f25172c8338d8f066331a512fa0208ed5632a76921e8f110cc449d37bc444ca53d100e2f026c675b36e08ffcd1f883125e13aaddc23eaf77747e7752586920c1bec87835051f133041dfb706492735d8ca8aec8c2c61d900f47f52ba531834b7b38cce89f8a9e3061752a40a3807a38ca8875173931d97c8679380a751271342e319442e033f68a0a20a0012e5cf80c2dca280043403c1c4ada3cba33170501ef7098da3245f2ee4ac91cb2c3d1dd95a6903f897538a8b34bef0f8931965360403a1c45fd2bcb1ccee1206ba6675fcfb159c3045c91850d185d40391c57a4bfaa947c235a1c0ea5e2affe468d6764e170988366dbb0d5f8ecda0d63c3860b17bb86c0371cc5d8e09165b27456846e38fcccb093361c4b768a6b196122201b8e7270d9b099f9cf10c348c0351c44c7ff4fabbe1d3a07d570fc9fe37977c5f9967c1a8e927dcc1454e63f2f886838dc7021f1d99dd384d8190efb674bcd43255f75d10c4729cbf84ff850190e42bfbaea949ddc4e08084886c3641d5dc369947469ff00c77010ab2a5a5a55500c9fc4f664cb040c83769b72cef1080806b4b3c6beacaadf08f885d39c6dee90312eabeb04f4c2a1599faec777e4ac3007d885a336c912d29ba5673372e1289fa6d5fda79a14be2d1c5a90bb889062cdc53453805a3890f4d9add223aea7270bc75329d96f46e61c1214181f204131346834db00b1709093c409222929906103c6150ea7937456cb7ace00ad70d8c9632499b6b7085f158e3295685a49ef10ba8aa1448543976cb520e269c26a0ca77054f9e16726fed55aa470143c35cd84b871913351388c126d53e44f4e7020140e73f8ebfaceb18d91dfc0271ca36ea4d7a01358f3ac62a11560138e4abac72a48d5850e2113de2829f24b044d8d0810991a3412804b38ceaca359b5a284e3baf3fe0de151c13e49389e96ff14f18b14729070b8493c37cc2fd7648e70e07bd1bf521ccbfe1be128a85674facc14e1f025c608f19521c251870eb3326249fef34338d41adb69edfdeef40be178736c7bba85ff0e7f109ecc59395fcb4038b2d11d4b3ef9b3ed0f0ecbe736a51052d476ef8383ffd8d7cf21ae363d38dc9463f8a81674e3771e1c9f259dca921f9ff33b388a96d43ea6cd102ad7c161d9bde6b668c9c161c8e8f0e169c1c1f1674c9a516fb1742b37385eaf387326f6c93f6d83e34f963793bc665bba6b7018f13b47de8e14466d1a1cfe58bccff7f873fd0c8e3ce5f8658b0c0e2ff36ccc173c244f637024d98366bc088deb60709835757ca6c5f882c32439c7b5d860d9fe45171cc431ab1c362275ea6dc57154655d8c38cf702e2b8e3b47882996e48d93ec2af448d9b284e851c581758e1f316a4eba938ae3b874dbdd1a9fdba2a83898181a724ecaa554f414c7daf5972e2c6d8a83ad9c93571775fed4521cd94c12ffd524217b92e2e8242f7a3c6b440de6280e35cc7e382fc95e1f7ec189e23067b8af0875e145c5501cd72613db3821e7a6101487b39672f2ce0bcfc94f1c6b986c26df3bffe779e228bd6b4cee0e3b711cda7cf6ad3bc5cc73e2f0c257f5d6dfc481da459de4549536d7c451f61065676dcb8421d5fd2a25cd164604460b03631fb001180040c261e2d8465e2db32d94cd76898358313443db4b2c6b96388e78f791c3e74affab12879daa91f3a73a15bd287190275d563f7f1287e1634deeeefe578a244ad39e294e8c1789438ffe993342c96e2071bc9f1b5adb43d424f488c3f7680f3a41471c88b987d24d413b5a84463ba008708d389290b7737faab7ac19230e6c428e7d2515927cb588a3909d56c4418e9c297a45a654790d0a90179788830a592da8ff8c7c7d1071145f93a68e7bcc6f318738cc6691c2c3de755326fd6cc76890074b8383f092a37e92ecdc5b5514760607fe772213e24ff975e58495c1518c6c1c4f29e39bfe181ccaba56d8467f66766170dc7391ce7dcdec5328ec0b0e4322dcf2ce8eb5e5d70507e715db72c4b109da8a8396abe9ca7c03ca8a83db96c9b12fdf795228015dc5d1ce99efcd843c5341a0aa38988f8f5016a28c843486d29b19bfa9a0425f4c1a029fa145292a8e4675724352cde9ce245be8298e63c84c9e9344fd94e3183a0235c5714e79e253fca8f9c734dd0c2dc5a1c7649e5bad2f8415801e28298e7c2b935bf4f0a0a3388c3d5126bd465db82812c5f1777ebda734dd15dc184a336ec0302dda65d49871c3868c18e435144586cc196aa18282027589e712e2ec87e58a2caec82202ff89232b1d4f31f713837ae240c4335fd6a713c729c6d01d6539270e3d7b44e9488d512abc89c3ce4e69c3827e6f76cb0c2d3e00e386f90002b4e8121c7fe304468b2e8171e1a2068d131c376c6c21630b19a789c3d4efbe8af11921a50d0d085c91c51610b8220b1b978943b18d1917794c1cd74defb7864fa0973848c13b63ba73458bc512c76b1b623fc56a72a8632819412b71f4158247c8d61063f46228c198f16b02a5c4515dd924fdd04fe2e043447c0c71d9ed940c1148e248de6d4dbbecb4ec12898308561f5673880f911a24283066bc96402171e09d15d35b4c1f71e4a16b82f44a4a1d71a821716a5e378d380a123dd75778e7cc8c382a4b0b96baec6edb5dc441b6cc8c32adc198f10c8018a8220e24eec57e69aabc9b24e238e94e643a4995b03c228ea24ce7edd363281de228b7c6cde0b29f74fe365f2a50431c46a98ced97524e2221f25a21c2ccea6502b30529218e62a54de1f289f95b3c888394c2af86b7a550b58c87f15bb40ae248faf24ef0bc09c46187d835d1f244f99404c4e1dc4e4a1541ff70943f92c5d6dedc968e1f8eee34fda366c969ea2322681f0e624e9254b56e92e5ca7ea07c38b094bb226f8fc564d307ba87a3ecaf491eae1e8ec7b4a754bffa72733805cdc371b6c7cc49966ea92f8482e2e13879a6f416357587e3da9e90f39e46a8c5ec701c172de40d3126cca40e07e9d30689b3e1be7bd2e168b23ab66d4773388e4bc96e2d6dbe79c9e158c2f2f2551a87c3ec567dfbf75ffd140e873213c22649f786c3ac28e1a375aaa835b9e14823d65fa5ec8a99c1361c78855c5fa319754463c3514a8de8771b6f2ce43518ee67ae452c440dc7e35617f39fa76b69d270909ae5acff7b341cc7f1a0dd1235b4f47886a37417e3bf86954a489be1583ec2a678912bc35116d3ca73c1aa2c696438fe308d9cc4e2357463389a183ce5df2d8683ba71f78e616624ac6138f6ecca59727121620e0c072d294a78ffa897eebe701063c686a88bbc7018e3da460f532fb1bb0b4756ff992923e697362e1c5d7fcc93f7be46636a0b0799e2525a38525fd759c99d43ca2e0b47f95312f7f935699e60e178b635f658865ce128ca4fca356e9e5f4a2b1c447b56ed92982a1cff4bc69d89eb951352e1282fa6adc3f75338c8e1376227317f4192c2916f92770f226f326f148e7f23537594cd09e34181909fb94b72129f7050691d2ea16b2fad39e1207f550efb4a138e3e74749970549a5ad2675554beb58403cf1ef5e7426d2b489470a0d163629648a7e893241c4bd758588890707cb55eb6ed3a92f93bc2c1ac6baf8adb6d50231caae79dc8da90cc2dbb221c84daf914275cf60425c2b1c7102d316e4274951ed0211cab5e3c8f13f729472684e3fe1c732dbe969f86b8021a84a398c634c6cbf3d99345fa8302e16093745c9c8e2f1df26c04fdc14194d4f57237d1417d70dc5e939993ce5d98440eda8303a99852828ca676c7d5dea03c384c9e4378d49be4848ba94177705ca134e27f995fc55f81065c61c3461954078779dbac3f540cb9a03938feb46249ca5462454f8b2ec18c1a3468684171703c957fc22cdd7a83c3b4b354e3657fe93f31948e4c6d709037e77dc841a3daf21a1c55a59e104286f694431a1c451f798ff72915776c81cee0702cdee324db428ad317540607e7b59655e7fcc32a8dc1a1e5bcf85c626f416170b4c1249b27fb9414f405ce5baedbc59c8378d6a02e3892cd2914856cc58179c5f1303147b1e061c54112b5081ebcba6f5fc5414aa7f539545e47561507a94f3a89a7a93856cbd12e3e8f8ac390ef0ecffa1487af29f559e50fde6153186396367ababc14a7872439290e35854f927156ecdc1ec55145ee49e61679515b14c7195fabbafe0dc5b178cea1133edb670f8aa3cc61c27ecf84cb8b3f71a895c3b625eb89a3fa091eaceec471588909dd29e4c46c3971b8aa511ef29c9bf83e59c40c164d1c675cfba47b04a9393371dc1dd396a984710d31711462d89b1c927bd810bcc4d1f4ed49bad9a8d8598346a2202d7190ba11b3b3ebacbbabc45192928db7d652e228996765f20911cf4de23885cf1de34e2689a3b89a1f257b2412c7eef1cc73676d7fbd20716876a641b355fbfb8f3814f14e1e728e388c1a63d6bec8092151238e23e25c7e47db2d67c4417a2aafccf6e5220ea67268740723868dd6c2c651009c908a3814c91ad2e27cc42093441c8f58120d9b2a8838f68a5039b9cd93b01fc24cbbb4693d2d0d711847bf3556f614e260a72d667c48d3543f210e32c55bd366ca208e62caa9e277f3a49c9f208e73e898d6c2722ea5c9d808c441c8f12f8ec8a8fb7800715c39f3e906eb74159d3f1c952629f990704b713f1ce5e5988366e6f89b9b3e1c757ae47e8cc587434ffbfed153ce5692d9c371a69852b4222ad47e3d1c658e9ce1117f1e8ece432732b63c6ab8e0e13847e9cd31859131b5dce1306d885b9892d9d8dbe1a037f9e48b1626fb5e873bab054bb3ec7bc942d2e178ff7c33addc687e73387ef1b1344d7bd137391ca75e566d974df7c7e138bcbbd7e654c3e120dbcdbf4acd6f38eecb6f1aa9b91b0e23cb3d4dcaa83897361c87a50b53be5997261b8e720c7a7695339c05d7703813f436539a2889ac1a0e5b72c6c5fca0f2694dc3d1278d6d9a753c6a8386e3b394e356ceaeafff190e2d44cc9598607d739ac1ca29677e0ecdd4b30cc7a5f79fe71af3f94c86a3d99054e4dd1bc361f0098b12632786c38fdf17e97254b9c4c270281b1a445e04c351aaa55235afbe706cea2e79e1282aa7dc5d4e170e54e27a085b1dd3ce5c381ccfd3c1566d5345c9168e523b9cc6709ef2b5160e6a67425fd768d6a4c9c2410861ed73aee837f60779ca963674e0411ca46fe4741295124346cbc08238c889c12da359782a096381037160c13aa74f3a413554700a0c88e3cfaa4f217cb2a6e6fe70b89b2d9a22499867ec87a35c3124eb3067317e8c7d38bc9c3657f6f28c0ccc87c3499eef3d1ca6a4964ef64ba411f570d09a72a4b86d8d132133701e8ea3c7d01fc55d3c1c49cb9daee9e9a68d7738ccccc162ce4f7d720bedd07fc86925fad5e1a8fa642d9cab5a603a1cdb490c7f395caf5d6c780e47966da761a7bd23d51d60391c494f4a5ec796bacc81f15b345610380e8751d36bfa1cba21697fc3b720c1310fc3868cc401c3e1404312bbfcf5d10af10dc7a2317fd22786244fda9051846e389ecfd2ab4891184a339ea80d8715324d77cde8664306b3e16853c357a5ec184a6f080350035ec3c17dfc143385cb71154181d570781a62abf53d43328b17380d0711a3d9cc52f6f8b6a3c1d8c966543ae61c704516b7053ec3719beeaaa97d9c5a280536c391e710f2e5eac8973bbd321c57b2bc105f8b25980c87635653a22229e5a8665cc090113c8683b468b38dce22102c86a38c0a79c4e2c68ea192070ec3b1e6a4f15c25e5d8d163301cf6695d8b9ac706fec2e1da85fc1fb6f7c271b68af99d81bb7098f2928f567df898825c38082ba1da629ba5144f15780b8721572ea95e885181b570f81b77ea46a3c24afe099c85a324bd12c1a5af620e3b81b170942dc464d9d1a3a6de5ce1a064f734ac5d484590ad70d46ee9c2594fb80a8731d46454dd9b0a073934c56b497f0a4731a4b81df5aa62c36260291cfe448d991c9764e78fc2715790b19c1742e1b0d43ab53f2ee027900b18b0130e3ed2f55e85d54aa8fa056ec2514a356bde673d611966c2614d4e9725d4bf015ec281e4de182fe75725752c60251c7dd6fa8fb7dfb0410210940e3809d6b8d6d95c38632821e150d2fd32a46039c261ba64902f138f291934da08c753d2329abcba82594c5c84a39ccbbd5afd3f466c2360221ca6c915beeafc24b564084723d5a9e9a9fed966ba010be160e28e65ececb312d68cc71970108e3bf3dc4e7cab4e3b918006108ed2e69c4f1af00f0ee5b43767bdcacaec7e802a07ec83c364132ec6d80df161cce8c1b19975ff4afe6eafc72863c03c38d80d57f1ffcd199b0505b680c009600fbc83a35d8d91d4e32d77575acc9811012d66cc8840b10e8e35d98d56d80ecf66cca0515463c68df6190dd062c68c084880737034defee51529ab75a7148c8383b839df5ecb876e70d4e7297c4a316e05dbe078ae2d863e0dc650225c83e395eb8eda3dfe1e2ea2601a1c2591183725eb6238096e181b3666c8c8e28a2caeb811e303322670451657dc38a60110d862868c2d2c300a9ec1816e8c67e4a49acd647090828e448d3df3559d181cdf4f27fbf00c0c0e6e9297c7bc7c61f2f10b0e54432449a60cbbe0386a5eba4e69d73de50c605b71941b93ea4c8e716d4c561ce6cc901136aae766dab0ab38845ed134219aaa38eabc2fa6e2b82d6ba5d14b3bcf13541cca97797948977456ed29d4ff8bf7764d714ebafa9ea516f952f8f613bb51f3475d521cc709976779f2d26e7c1447f216c765c355445e524571942a47f0a895c3a5a5594371a4111d963a280ee43a69fecc3eadfc7ee2c863160f96bc5c4f1ce54b12fb1bf14e1c6c8a4daee635278eef62b01695fc75b169613771102b334f0c16c4bf4f4d1cc564b1d3c6aa3613c7fd7ba2399d8ee5901413c73904cd295afc86b58d5ee2f8a3fe5b36afbcb38f250e3db54a168f2fd953a7128732399ed4066993eb50e25033aee4b5949bbb339338f09ddc7b377d21b74ba2f0c123bcfe868dc4c1fa4ba5245a1bbc72481cc7f43bd1f63e42dae51147c1feaec2cecfa590e28863fd0b1f9e36dd8863b98c1727438b67be1971fc2b99a61366dd3f5dc4c19e04cd5071e93b061571e8f12a31ad8689383295f2bb31cbfa0a228e4c73feb6548f396f87388e1a327494748638ead175919554218eab32a3d34a2dc412e220a568161b833b884317ab0ab13f0970e142108757717c7372963c3967037114236459ed5fcb16fe02e2a03c4f278db07f38be162d4f3f9a3ca63e08eb87e3b90cd79e52b37d388c5d55fbb4103e1c4cac8babe79d9c452fabb07b38cc13d175f766b59fd7c3c15a6adb946e6adb2b0f8715931df23efa8487f1701c426c6f844caa99eb0e8715baa629550709b7dbe128a6476d9990db3a1c863cb9313f8bd981a5c391e44ff6089b9aa11d05760e47fa312da3725e8f1726d58095c3f155d9a7c8fded61e370d46d312979d724bd1d0f0b8763ff6029c9ffeda5c9ec1b0ed7c55e2378a4e0b06e3898f85e64528bb961db707cf16316550f29589c8b0d072d1672536b58b73cd77030112e59d9b5644b8b8d193466d4a0b133560d47e7979fe3a7d234ab184a30b260b06938fcce9b11275bb013058b86c3a06f61e62b5ab24e63289dc0a009f60c477f9e33568a7873925b331cbf976665b2b9fbd0c4507218317c0b12b41646822dc3c159e9e68e2945ccf66e2c190e36fda79e7408cd11ed188e5270d9dca4ded082047dccaf180e2db6c905cb4b188ed3844969238aa530a60272c17098d29aa31b61743e77e1c2858bdd2f1cb88a98d4c654ebe652582f1c863ecdac8e09dd1fb60b879e2c4d4e62442f9fefb05c38869c4b11d2cd5b388abe29ee8dff07cbd015594c400b4751825cde0d95524c994d396c160e2e4d2d6a8c1353ca546a582c1cdec76d79182bc1b05738cc99c359d7fac488360b172e5cb8b04128bbb05638c8b27bb75ac91e2aa9c2e144e85b78f68749582a1cecdb7aacd338fd741a2261a77094ac62e6cdc3c4202a4ae1288bdfc7fded6c148ea6c3e71862e44a21a740e150472fc4729dec130e223da69373cf99a4ae138e4572eaf031429a70dcf513e442ee5ff014261ca73cb9356630150b212bec128e3b75a6c8a75696752be138c43dc9592b9a4938886e51364c5b241c25ab9338f94c2e134382870163abec110ec278bca6ae748d709411f662c66c0ca5cdc016e1202f7ec5e8b72f118e3684e49d9fb5085f0a8ca971ae023b84a30a15ad9b2bc7dc6819356e340d5383e9a6b04238d28dd31a45625ab549100e37524c69da413fd5273ac202e140525b909fffabc8f607471e13347f35b7e2b6eb83233d4b97c25fd2427e0b1918801f6c0f8eccd333ea7c24ba5f60d4f2e0a83d486fc414c4c2c73dd81d1ccc7984a822d9d3b41a43e9d902ab83a348d112f621276287981aa76cb03938b6d4899343fcfccc84c5c1d15b99ace6847a0ad90d0e34e98f7aa84dd51f5c1b1c695d88aa29668a4bd9adc1e11673e05c26e4e7cc7539747fdea77b1c4abef197e386a9c081641f62acc8a6d937ec31c55f4f6a7fb91b12bd9cf972545348de8663f869c9ab5ae46ce8223dbfa349c665ca1a72f54d2b12316ae025ccfbe6b6fed340b5968494be437a8e067c43a463fe77cb194ec173acba98e1f1931cbb824519f66429841b8995b682051996b7b6900817a93286ce745c47eedeb36f319c337be29e627d6311863ca750f31e63c51b0b3014197e32631a8b2f142a76a41ce6156b2cbcd0866899ec215777a10a2952b7d5c2d45c28def587cd16ba94438f6a7c305d0b7ed46dcf59f163ce426e954565735ec60216a9f46d7ccbe52b90a3c77b90a42b5bc190735c85456d5d55a3ab4c8527fc66c953404fb3e874892c055da562c425538fa350ad6c75750753cd620105f3870931e3aeee8bc513ae1067247ffc282f164eb0bcdffdcc57d6c5a209ea65d6d47befb02d138ed58b389d10c92ee148d3442b75cf2af4aa848375665e97bc6b12ecfee0ad1b9a55c5020974b2dfac8dd3a6627184d563bd771093b6a06261843af945922091f5cf22a0f3b61d31794984d4f3c5c69e9fca108a1b73cc3bb1100271ebf3538a9587138b209c2c3b3d7e4fce40388a087e917a2d24dc8481c50f940c6faa315258d307fe75e9896b68e5983df0ea4352728fe0f1a0ac2c261d2aa54f6d07f87f52b128b1d0c1b12942aaf9644428b1c841121e2d4eac7d2606b1c00112d75177bfc1133ad48ee96e83dbb3a60b625183c43ca694f9d36fc48206974d48d71d36de88c50cc890ae3446cef722163260ec73bb5cdcc82216312063968dd34b7e221630d8d3a7d614d14dc4e205ab87452689412388850bca39f43648d0ec5c2bdcea4cc1534b6758418aaa12df60d1975f456a19e5c77d552065962fc63c1ebf54d493e36f6b45df0f15d85e05eb881ee33bc515fd2c7af9ba670a2de5ccb8977edc2b4513731e537f4bf1c12345111a9286bc457f1484d99b7adc44a144091fd2b650587192048fd9601b2888d19995939c507ea2f5c8f9b2ef8ae8093fbaaa04adac135c69d0491927ce61617365d4e7c93641ac0f9641629ad843578d88ab6f4e26b0ba528b2185643071ccc962f0eb12e69686a94c312b96b0aff422ae04f961796e7b3c45941284b6b89273129e87f50b4a821eb7cd90f5aac248582b255d99cf3d76903894566ef508333b68e5a41cd189947d657a7c1ad16ed6885f1fa286117f0879fbd222d8187d7afadbb72545bcf13cb244f41c514a84af95c7735b270911ce555ed85b0ce910873af3118c1786287ec7896051213aeb6831be37a40d2108d162f6c4904194622efac67faff4441025b5943a2ba5b60361ae9ce13adc46fe1a10ca678a3067de71d93f14f21352c26c84c40fd7e67e96befb481fd0241137c2076f3b23a72e9db853f760fb5b88f1d048f93b3d10358b5e0a3b9b837920798eecea0af1623c1c46565282e5fa0e4fce9239a74245a34560287861878378b3a517bc52084fd1684207785187c31072d7f78c4ccb7db69821c3460d730b784187e3eaaf9ecea942bdf27338ba90a9e79ac3ebc31772386e643d71388cc1dccbb6f2e2260f8783ef4d3141a6630eb7bf01dd896ff1a5d26e38b4e897e262dd6d38d44e795519343ccf2d361c8b6fc80b8dcd1a0ebfc3b65b2595bbae1778a186e397f8e126b336beb2031c05dc7023bc48c3a1f78660edef9af242d070909a52d8850d899c9620bc38c3a16a766aacff0c841766380af55ea16e3dc67a7a072fca70b821eca9f78af4cc47072fc870d49f2d3f82794f78318663fdb574d3b23126bc10c3b1e5c695581586e1e8edcb5eae05c381e879ccb7bd1a4b275f38f08f8bdd2172bc70986772e48af497f0a20b073964ada8dee92eb7c681175c38dad3919ebcd924449fc08b2d1c74d4ccc94d3e5f7d7c86160ee3b768183464dcd862c10b2d68e6bf13771a326ec0b04143c60d2d5e64e168ece46fb44f43bcc0c241cac98b0e19f2468f04f1e20a879fd3de7346fc89926285638951634a4c92db60e31f5e54e1e03d6b75480cfa92a91e5e50e1f873a856846dbddcae0c075c1e5e4ce120c7b4bedaaf2dee922d6468f16d0c606a44a0eaf0420a4731860f9e2c3b74781185a35f4f29477f18871750384af267a1ded30549fb094717179113d3a9c8b7eb86174e683cc56848959c36bc68c29ab366058f2c79c18403d9afd99c6a6ae1c5128e763fca9446fa789c6a78a184430ba9b6b229621ec642c38b241c6ba46ce9fb5b35556791c5195e20e12849baffe61ed5fef3c616321c9084174738ee6fdf9ce36b85e5f48a0a34e00a231c69b0ba972835bd494432bc2802de195187e105119a68af10537b783184c3ad9c52089646438810211ca6f07483e145108e52d8c89ce1962fbc00c251a449cf8ac60feff307db4ed6fabb7778e183e318feb39d2dfd446fdac28b1e1c567d6ce5f79431bce0c18155caa396773c5a972f767028bffdf16f597272648b192a85173a38b2c9beb77c9262a5a808cc8d1c1c5c6e7896c41cfbae330a2f70701cafd12a39a4d29567e3c671c28b1b1ca7fa681f2aeb7db585bdf0c20687a33936e7f0bdb58e5ed4e028925a84b70f2f9fdc173430dd256dfa0edecda0e0a5397219d01f27897496cac7a0cf2db376e97056c3a0ce5015ed1790a2da1251adf11a51169233ab4f26c10b171cac7987bfc6f1c96c2b0e73c5bc98cdf4f34c0e2b0e25a7c97b49559d9d5ec56186fca52a8e42907c9e39554b98744ce0541c8af4c46f57dba97a5171906257ccd127a993a536506018708a43cd6fb6d1faf35f19531ce60893ae5daff6ca538aa36421a7ddcf1be634a4388ef2e8914376f091cc280e5b3d475f44b4b29417c5d1fdc618695a0ec5a14c6848c1ba05c5a1e618c752594e921c7ee2302fa6abd1b4278e2dff66c9711659ee0177e268fe4c745c629c38ca95fc472b769b308ef4c944dbe80b581307b9b38d498ad0671ecf042e55a3bd9bd161e2e867b6728833bbb356087c89e3f4d8b3a9e2d2225b6c89c3f87ff9e95e72258efd35b34f8a4844e698124731745ca8f4bb2da1e1491c55870f7f992eedbd52a3c6e1c2450d96c4c1ce5486fd54acb8319138ec984e119533248ed344dd02a0a0460552c08f38e8b997fd0e9b1a338e5050e3c61647151676c461ee4a111792c28d60461c8877a60bf927319408d6b8418317413901560461033811071772649a10d2b44ac388388e636dd9d7423ec481dda96ae6fa96a9cb1087d2f93dc56c7366cca84183868d2dc46146afbcf6e5965284afc86211c18438b2380db1dd8d2da8b4f0a60269241008c471200682148dc907b313080000242e8f0623e1581c6782ac071400034f20224038381a262418121e100989a2301808080905c240200c068402c16038301ae34b9c1ffec7767fb8287e30f7b2870d858f1f7fc19c01db27f3d194395d1e881f2b07f0bb5b210fe7c2a667deeb7813827e2e2cafcf4a84a5da1b536150e4a7c166518b78f7c5e37f7ffab2762a039bbfe08f856a7fb0fc7b9ae1ec0bbee00d1e7b013caa71c83f1b3c1ee66f914ec7d50dca5de81f3fce4a48bcd33c6110cbac4f5ef7189b4ceee2ba4667bb8f04c48633af0cddfb0c5670ae8db4beebcee2ad0c3a0c995dceee3edb59135d0e5005be084dfd0527aa6d542ab4f7e8a9a8b604297be3a06aa70043da895a56cf9cbcceb87520630b42f836fcbdd923751b02388e316de2a7c62ba2731bfc0227b080d4ef56dc899419f61e0ea2f2865bbf29d7dbe9c4cad84a68a0c8b2bfc901e5a4869f5fb033e39976d551864832074b6bb3a83db12087a07e0d7d53c51acf1bf97d6f653ab103470805bcff0789356ea5c6ffeeb2ef9cc4ba389588a4365cd93e307f46caeb95e2d1ec72e5e085d4e65cb72b37a20f7d3c3a9efba9603946d35fc5eef83444161d5cc4c789f8e0a13fb3e14653308afce15bc4e76920d7bcdfb2a7be3216c1da38319becf041d1b213549299861df6c17674226427a8afeb1499e20b3e113a0e6f9e4aa9f784b63cfa541e556c69ac8f61aae02dbfb7a18479cb88e77f2a580e1aba801ce290fb4aaf9ba0ebf12ca031076c97eb0a05bd5dade4bbb56115f51efa2412e31661ef33f3f5c8ab00e10a52f9d9695c0d6ad0c92cdce8e652fe065ac71dba1a373469d71558174e3819777f00052f80b2e7454d219e6ec6dbd679eb8d1368a323f34150bf284d9c48656a26a557c95646e4dedb387cee5b9741364918e79ed39b203ccedb51f3a09b1950be793f65953facb343caef789b97481fe4ef17989461184008a2fee93ffff9658126fe3846a75ffe49341af579ab70943fbd371b3912ee562999d2f6c355482dd53759dc1d4629bc27ebb9c82bf46589146e8d3b846e0728cc106a5badc572a97178cf70b7529561bf9db05ab5cfb1ad47ae40af7799c01d2be2e560b8850635d0c43eb947172a2334060816da5b3dc10ff73a1ba79cb9e61b2224d568a4be60c54391549cf88cc7d1910bfa83d44d604494740e86fad93baf6eec356523124ff756d1fdeca761b40e3586eac056b7fe11924f743d101aa978896d6a0422991981791f715311be20a1fcb46dfb447c8479ae79ec65cb40458a84364a362adc14746c260193d39a22a671457e06d9159d407ef7c8e67a7cc081b74a7ca0ec7687948d5f1be06f662b0ad64df3eccdec8a5e388bda80d8d4eb24e20e0b1b1d6c93b60bfbf55a568be53ae08bf3727251b5c5e0d0384be27938cc3d3468983008a3bc24720215c64bb1050b365849a0fde06764b0c016cdc4e6e9161d219c79e50a615c1b74df4e060dcb78a6722d568085a125a860ed19508a0543017392d621610039423e690f4dbf784c4a714b7d467dd39c635479b5fddd1e92c62d98463a305332b1b2fdd765b649ed5d80f5683f660090643b85f3fc29260acfd60727a128989b0af6381989463856b9139cb98896aefa161904013acc201183c359384515ada06bccc2d3c0724134370828d9034eaf69d85f2509d71a660b752068971ac21adbf0ab0cd6c70d5f26df08a2da6eaa224d8a32137d9780a036e589a342e94eabeb095a65d84117251d99756bf22883c587b7fa8956a1c1e568a618506f5d6ce23b3f6a4525731b5013a1e611b24980586b9795beeb41f9fa730ce380669ed25c2744d39a51fd7e42254fe635d0382a769de068aa457b9078713b223eb73d9d7062a8f9b957faea8097526f4d254eb181ddced5b6b764d1d3049de537370783f225ada83f93346969a9eff87a3abebf70569c52e27e4772127c22bdd731f85fd89cb3d26917bda5a41813706958707bacef4280615bc5071e8460676366eadaedab6e7c82ef08d7dc0695721e5b54018ae2dfb85b1790be0f24961cf92851ce5c5aeeb3c3028abfb1d64ec93d1b171161ed14d87b29cc6cac4c1c046226279fa571ae9efa99d657b9d2a52e16522383fe643b41c42b2eb8d61c62672f2750352da0e41b559172967a1ffa070a33a67ee441f742a1f7208d39df38866a2b032c57665653c3e2e20f5b24d41d9094eda4269bd1d50d2aa2be48434bb55214bf77c17675c61f8b4bcb4ebc218511261ed878168720ad48bcc332c3ebf5be4ea8f869d17397a08d5091fa91947dd024f517be5de99172d8a23986e1021c8f8182df5ba745923aea7f7fbb70487156c863484428fbd05447c623d50429fb1903db508dffd37c595168afb9d359ce0b845c52fb8ebb2a0fa30ba2d03e03481ef99dc2243caed8a902427874d3f022b4abfbbc5362132a14af3c7cc08164d8e4b0bc101e69d0c667dc9b12b37878baa329eab44aa5b94ab41b1dae6b39d8e9e2cb3f49893f0d3e16e5ebde8c86a9d244d0393c3ea015c1fea8c855e737be341c42020a493edd82c56381654ebd5498194eaac8c5d7b8021a7fbe18747da7c6b5e9227c8b9b85635dca6ffa1f45c7a9a19825114ddab42858ac2d90f96aa38ea592e017ad76cb7d48c514ff12376c8e3dd1d7128f4cf1688da84957d5e5176eef7a540c34f4a19a09c912ade99c0d4c362f9084ff51eed8b0a859dde5966a92dee3aebb46ce3bd9562fbde5e43e84f65848af3077297cd367ef798ac8500eff1a8849a374b23c027f0b4a06d5281114412c1e63a36f28421b75ddf00bb06e5a62368c7bd96e0b8082af7c589f5e08dbfd9afa9bcd5b36727cc9d23cfdf70a8d0b81d5ffce73de628ef725cf03a0dbd23549e4e4544c508dafbae2b02eb5ef2029e6a6206d515096faa659dad0884143435f68825ce057e26eb25af5aab2cf0ca0f986ca7ee57e8873d6a34b39e706c7598fd8ab24c51bd996c543054db29ce3625f1a6b12745a222b95f6812cc4598c43cf9b5221cd01cbf183269dfca19f7d7a30d559c87ed6db21f8a8310d9673e1a906e8e8529dbd9ababa0754abb235304b1227c2f19891ce71c214d0d589233cf25cb62e5a2528e93b0264fc76869052047845974bb5cfd9511b12b88cb81b1455066884bb1e870888ec54d43bd41ebfb0cb69b340f7007c988afb2db84d8c081ec8a87cdfdff2610c7ba4d706e2d6a5b1ad3e0533d946e3c8aa63d6466a29b4009a10bb7d7903690297ff6b02431ee9b0615b55854bb1c2bbaea3b464544dc3ef74f133ff6a7eb2816cf47fb3cafca10e7f26596bdc8389ba9f1ec62e038539bbd081640e6e6656ae80bde4496ef3fab575e8d4a95f23919635393dd2000758f9dadbbec0f601303902cafd67c320e62af37c8d642c8fe781c8f6e64020bf3f1df98d4deeb91ff9e5d913a34f96619e8e94d77051cde23a12ed292da50031ac1efb74066a07b68bc7a6a52b9d5c702b57b232cfc6fdd04b274004f251e2ba67f54a18457a6f042496f12adcc8572631a688125bab1d905be8b375b4cd514752043a13fb19ad8e637e4e97dc01366ea81e07c883bc81f44a5b3cd9557da75db1f773e4921c5daaadaa5aa6d012cfabc67804664ec054d5196bb8ee5d0f070d3eb6bb9a7e4351581b6e3bfdfced89b00d52fb0b9e2c41643915120f42fbeb8087e212999af4e71205ef437e7774b27ec494ad770f233d96b22fdeff008b6eedd3ec6f5875d0e4c3edee3e63638584e9851ede0522f72fd2fe5c0130c2049050c4a752e7a68a3226fe9ed2efea81898d4cacb481fcf95253a60eb2deb07424a9363e8b8d609b89d8cc800469d22d8f58d4b33511f5630d49c84df0cbede9047eca920829edb0a5cbc67c55d03aaeb4af8b94e8f9f604b557e4e4a30987f5dd93eefc9b0d8047751bcafae9cbe79015a29af2ee624fe6f44a18a7af28b5c77421149d381e95617fb79c2f8e09ecf2ed7e93ca0db1c1c7f53fceb75ce23cb549c4f484298cacf4e67541dd5ea074f2cd3cbfd666f0a5241bb84f0ec5a155dadf5b11c6d56a6664b12d074e74619cdb453bd249c69009c550af645b567de4517febe9c2817eb5135520b4fa15e25092a22e8ea5d4918e993647c1f2882d1418816895d11f750dcbc905044cd843a207dc926aa54c77d967b6efe1ec67f248ab2b8f16ce41b1ae06f6c4e41c01fdb89f968203437dc276b2fa838a53a15aa8df39956b99b35a3211322cbccd2419f7707ff30444dc8e9ba5321aab9d7e1d3593d051dbb615e86107eb942706daee8cb8ae1905e491b584a70e93315e9a7841cd9c8d66140595816387739d56fee0c903d571c65a9e211724a8c32eb3150209dfc7c06cf9c92a41435cad15c0afaa0b59019212275d6dcf16d3973a952612b80fa137cadcf449b0b527c69a0d7d4100301792e308b31a2ba5b52d96c169aaf15d5ce1194ac28a8cc2f0d22753f18a81a4157ed38dda063d81c9e591d8e410cc9f73a71b7157437829146bbbcbce985c1a50dca39d3ac42e0036e4765bf72216086745802e1a26cfbfc2367d9cdd52bee3cba4f00f09b38c01dfdb97e016744033ab61852e68dc688185a02b7ba7265ceffdb55da55c57a73161aef7a54c69a37b2fecac5631b3ba299238603b11aa88e6483057f2b48467fc86f72203445c41339dc24bdc9480cedd19e8f6177c92886e06778b821c55a745b7f99b7949482422322ecd001eb171318c4e844d98a863a6c9ed50a72a0052e1240bb46dc0c95c077edea3314b5dc1eb2253a5963062142726345319c450d28cfe130272bd1a235af678c77bdc9e0d7c41dd7e4fe1f76ec79ee030402e085409dec9c7223629b911204fe11fafcfc04199e43e40dd27a250fc6244fccacce8ad4b5c56dc11fbf38aa1b06cfedcf5043db284004580e5a4dc90866e88ba48be1d8db734e46f2571eefc7fa3027aa9e8f69483a79ea35dadaa2675f5bbca45c2dd7f099d63eb6a0789d8719e76527e207b01b7fd09b4c0dff7fed54f0a76708f4d879b0658add766a9fb98d2973050aea9f4abf53a55fe007c41204e2d662e2b453846cfdeb27c93d23267bd684a604370a6a8057e54dda256cb4478245e5d4c3ddaf5b13d2b95b80d21ed171e11b327119f26ffcd528b24c2a9ff9107acecf3cf30ff00934cb3cfe7cc3b7e755fba04afc1deb372257865241815256d1882859d32b42d512082eae1da8b2899118c083edc575f314c2e9d685a0fc11339fd2cbee6a984cfde0341cdecfd423966d4d239eae0b7c5b0ad7cd2f947a574ce4f8bb3088d00a12f48c62f028c69a2cd48097bb6274e4cd684fdc23ba88a07fdf91cc1fddee8b84970fc3e79bc91452524146d5da1e1d5d8ab48c5fc0e0f63385f5e2e25616841789a17a71402c2ac6b00ed728502181625f0d503334406f9edc3b4d928bd0bc64f9dd6c7470b3fecce4c48f895140ff182364ed9642e9b30ba29f9b01aaf630a03c2189f9ddacc4ec00c33d72c9af6fb4793da641e064ed2d82a9d297dd410abe0d03a746195f28d0596323f3776cb867154b89a0b1dfd727c370c7d0130885a66202865081b8f363be39a2298cc418d7b6cce143892f0f8cd36476da9420df794e1f1d1923d63464828ce05eea7a27faabd957ff2562e21532c32aa9244e3f936951d2f3beb7aa57f10f56938b1a29e0aef37ad53c25e998f838d0763859b6f7598a4829d59740b80327c676d43e649445e588c8fd0f6ebfe9bdeeab04324ffdf7424c8c72cfb25d92bd066e61a0dee4392de838924991858b7cca09fc152bf43cd6d15231079a6935bb78e001556ab84588be0645388148f0ad38b3938e56702c4e818321e775c68961775faaa67c724726b1e460a66a4b49ab13e46e831665593d042cd79c908572f39af36f1b5a5af7ca7cda6f5d332893ec80c24c81f1b2df29c650e0b9a7197f1c3cff8369204f5d68fd16ac66fc6878891923409e54b948d767c7cf747af2f4e33d14b327a995642994a317a71d0e189ecb8e24386d6cd737b0e250a1ca83b0299423eb3a575c0443e607a807d2ef725057a4e5e67145ffde164ad70359c91143e49348071de2287a36019d415461390205b243bff731d95e3f4b8b02c94a6eebba46b56b66ab57400960e4ca6f9dba05ad9d84d0e08a2f3b9c882109c5ad82611bb9e556e90199ab44440d6309006636e74a74b38a5a37904ff68abfc3b20c3c1d9466094244ac24c484569ea327218cddaf1ffe14be6c370c305c01f85ebb9aaa05c9df50c29d5ae014089bec7c531061f40d523b9525c804b2ac538ac29db2f411295d696ff9641a19d3cb65ccb5dd3401295a94c1a4cf4e8c6a1b41b87b23b2f70ba6653671ad73d99277e60c8d0d843a16f5897d14872268d1a821ffd665aa4ce72f59e85bf9c474c9a3a5136f53bc2c006a7fb0e5032e1b5cb5f4ca2ad3cf86bec382599b6c55e84a07b032f0ff7d00895a165132f9bb136bfeef277c571b56b8d3c4a5eaa1443aa68e4f335c88f8be944c3c58cd9887f36a82ad4dd3612877684c86b1399765b5cc6c7f85624f2aec313519b822f51a31137da50175bbf510a2b133ea935ef18da95f411c995f5f64241ed42eac36b4a309509d560a2a5dacaea933f03a18fdd45adcf6f7941d13b367b93b4f5fdf8fb04979232a7e96d5514123ccd091c02b2cd6f4a05eb3c2701f0e52d85ffbcc04fee7488196a6ca7f78c54e5d41c019462f3ab0cb8b03dad2491ec48fd5d87c6af89c7a7c1b5476172ab805fce40b3c5b4bf6ff17411d1c6000bf956f61e459ed7682aef4d7cdc521004f977b1b17a735bd61e6caa700d9163905343fe309155f61d83efe50e449dd8365562885c946b6b762a494fecf39f5326246cf35393b1df561e2871644c214319e92dfddc551122bc0f509c4593d745089962335b96f7585176968804937bd0017c474d86795197552ebedc2a4cbdae95d725c49aab69c028d6866f1082e27ace3b2a0255c81e2c392ef331685d94f322ed80c526e9935d71a148016dfd6b4babf60fb6fa60244ee135ddce4c00b00935bb2b7098a60323ccea2f6c4ca5ef1c81bd131ce80474a50a11ac8051f23b5751a6fde39155c043229e3a103f2a7a324fda8ba56a090b998bc5d0305c8985f70015e8498001dc90405d843875576074026fb0a0ccbcc42a2ccac60ba59fdfae2862b719f56852e544c8e64e4498061adf742573a424423c4b4238307a3260857cf7a9076fd0240c85d5c0599756bb6278b0000c3c4b2e6707c6f258a1262da6edf29a89187d4300c2b08d1329292cab517e46b19dfcfbd5ed81508ffbb71c685d71bbb02c2757075d18a9029d591a913ddd8e440e19f4621b28599687efa9244ac901370c64ef2b4fda02e55193018b47404e0f2ef0ed8853ab24d564ae3416a0f2e4a9cd0447393b31814fb634c82deff65049609296f32230e72915e4f0b932ee2123e10ce0fc3e8e6949677e8124c2d9947cb4ea41fad0f8d41edab376a5894f8eb6472aa1e9ccd30ca0fb59b00803cc503a267c2a64c4602b2fe0b3563c9486e0458bd298ea5b5494bdd50c3d8358fc83ccd2fd9003f5ec38640373a7acab27577d2e411f91f2d9ac0d90abb88a21b31d5a6ee185c26a72004a15581d820eb7f92963ac19f71093aade36a5472feebc69f30b731805988c1c31bd8f0ffe3e6638e4fc6894b9d840652ef85cce1de99c2949c780d674bd92ca8354302fdb801629e0b8a69d9eba43263cb5a435449ee73c79786267a4f0090d64a98f4481321f49f5cae011e39fc2d78b4db88669ead840b318a17199dc12cc5cb0d4bc9a8f5a27cadf2abab6904eb9bf7f09d6b256a17d5c011a0460c62070be5d3520bd2125b76d2cc63e96edf22a3d10ce0e154648464a3d060f581aa79106af04910243b875292cec204eb09011657cf7b1a314da940c04283e3e88b9e8e0bb1558df0d424a39f595d821f6074963be370c4170a04ad65c49c8b6104141acef52033ecb2a14204f86f18b38af955a05e989aeb509206a03d45e29dcbbeae631048664d70fa595f9b803de45c10a5c69d0821f544654d06a4442d21c02d3214abd24e4548a4cd399cd3fff4a938b009cc7d39847dd201d89becd8998de6f93ee427ef8a37348f180456df410acb9f61ab865238e2d39b18bf9a4f3a9f444355b99c5452b8ded366ddf7d1b41da64f20b8b5ccd687af7fcbea07b754e8604aa04e88965c9d17a210dde428089f1002e29e62374b94388d35267e77b04ba4b0c11758dbb1b6fea3a4816f991266fde8e1c282367c9a7bd09d0b761bc159fbb578aa29395290fee165fea30992c93af248368764a591c36a01d93d47be969ed82d9a3be1f7ca22e904726d0d2c6ce9d37738a5a2d0c8e0c78643ae201c417c56dea6af9b235726a1b214f66e949056d82d5594853b526fc2bd8043b117cb0bd027cc894076853ceb0c63cc3f8130c795ab3f349aaa062a4ed7a3af392f93d20bda5ab47d5f0fdb9efa8de8f77a12e894f98efd4ba3e2b166c44d1a58e842ffb71fc85929c8416174f042c31172dbea75a9f4c798042c464c88cd40d49bce477f98087e1a548418dfb1104534966e94806cfda37edad0ea93895dcf3a5f2ef08b755d78ecadcb7284952677a2c9cc3af156ce7eedc4a5eee8e58ddcb731e14e0a240c5a400996e343b4f3a9dc388153c3cfdcb17f677a0b83e2a33e64580f140c90e33d032e5f73e4dc520e888a9dc0d20f1fc64d4c1040b2cee0d27eb4a3ca643b73e3cb67d2a74d6784ca9890bb2327189d38de061967df6bebb5462092139602225d586d44718cf78547028ad786ee647af550139fc190b83f014a3dadf73085631a23a53aa1e433563bdb9305b340fb65ad3977c826f02fb0f31959f0c8959463b65f913d369356e3c75a8a627abf246a26fe90ddcf4712a06510acfae44d678d94f97ab24e44a54aab3b4937bd5bd2ee907d297fb70c1c07507d71fae847525a6a669a2fc71599f2e26f43b85b4665cce7261932e266eb4cbc4792e03e93a1daf44ad3973466a2f7fe54a44996b8ee98a87e5441e2d97bd415a6445ae35c9c504ba8ead529142d5212e85b98e4d57e236db4a86082ec7ca9518e582c8bf5cdc8eeba12f9cb16db91c73ddc8751e57e28a720a0802ae2bef32c2feb07623ff7ae8bfa115b725273a726dc1c5870bb15d89a67218a33db948cd65ecaa0a855247960e69cd02055b14c313142078d0deb07ce0321acfac70a8e5f3776319a552375f19c239d9476e034347a97deb9d43820e99896616c6f9a6f7853911d1a04ccda5819fb64228a5b75bcf6fb4601f6d80102363ce0cc45e51966d03e65a3ecb562039d92acbf480d5619476ca5729ff3838a4248a6c6d48c6f4c206db8e503b3519e5a15344731dfc82c4bb1ea668b04ab1043ad9e2cf76e42584033b60928c21ec6090a458b32fe24b9caba04e65f35fc094762cdb42cd3d59e8750bdb8d28cb447e9757d628da10c42b65f113f79809d6c6e77278d39558a8e68de5f6ecb46c388998bc92be12db86fd3c03eec4c589ddef350d2b41280152cce0a545e90d21f56ca7e3f6f0af35f4ee9862910498827ac3dcd5c8126c974533afa2145421d3a601767ee1d90ae7831831b827117a3d7559482b6fee76b30d71a08aeeb0c4dd3a4cffeeaa0e3ba22d90f0889d07340bb940b7cec3085395d73840a407e47d8f0811c5fe057ca6b0e52179ca472a36b111f23ec7a72aab3dc4581962c615a992c242f434741378611e339753e8dcfa36a0a733b44ca80cac725a4c278bc46fe218978568a4b6a3151232b46fdf837b88c9e846e04e2a02b144e5e05909df77c2c65d218df5196c9e85f0fb0c4998b9f0eaa8e83ce1d5840d5e1245d8cc83e58c3e71a86fce1f626b308ac1693d58d6854303921c704300e683cd8809b5ff9f106628a85ed2b842e969b0e9a4c90ecf67b09c13c75ee552709383131136b0cee0226f6ca3af63f1af5b726c1609596a558f8d7f9598b7a55f1b3ee28ee48783f160263aa97b53793089099b4cd78724ed60d9875f85ad81530fbe6fc24c0b598fd90a1de1c1c6942698e89ed06988ae0c3fccaaf288e90f9f9a7738bfb2a9bb2f64e1da1213b9423dd3f708eb3e012da4a4ad3fd8f4a9f0bf94f04066f482acf2f453a08809b6bead07e0b5255e4f5b80d62f06cb07e068ccc0e8ec12669a7f00140b605600a802088f784ce32c80d300b008400b34014ac901f4358030e902b67100aa03714e57f6a08cfe471b805001285a80719acac19103605859584ea2035885cafd6fec006239b0ea01c604a004c056002f07105500732d80be23dadfd816b3ee04281d4fb200462f564d36e680165c9aa19897003603c0e0ff6bfaed0c607234df71fd00c0f828e92a476bbf0b08025aac0acd72fe005d98f6970e4cad065c8f502b2e3007c03d00bf01121d004302c1ccf400b460d9a90046029832408bad0158432f80ff07b438a4d1a79503c67700331d562363110330061a55abdfa80e13c4a5ed3fba4432419d81e78ad7ec38c171092820b081c03b0428f0d55adda710dacdce6bc7200891475cef0408c68120057f2140f408c29730ddec6d0d253f06339da2ffc7222cbbcdcee2d3dd0be3f5d90d869e365365aa7e788451890314018a0c9e1a05b03fd9d7bf3e821a070cffebfb333ba2a9b79c06fda704841ae3764289ce193b4431527234840d3bd11a09cc5a436d55b3e8c567c71afe1ef3c397fef324f77c8282120ab8c5d26c6374d93e766c9425880cdc2d7ef30bb056c1294a8e1e76247692601e0e786c42c6aa8b21eaebe4636195a0ada6ea46c223c908d9b34d9ed6ab6bef76d635d20592d3ca2cbc5d5ddc193719f9912f3b2a9a73af0e1e64a107119eeb0c7f0c551c4192a598b7479f85aa314cf9d92f84e803f6d9eec78d64cd6f62a61c61fafa1e25730820ef2d2e3d26122e360f29d0a140bb29cf4fbbe9a3bb0e47d29625656242914e2f4d2c1d968f7192e9710efc9cf648e5c96fe89568aa5e1b97f50c7778a00e89d9b76962a216f588c88fac0c8c4667550e7cba718d7449bec60844d5a7debcd5c61f50394c688a8295aa5dde317421ecf24e5d26fabf22a45a894ab5420e88473d62afed76d1bc8c7f3437c7474f945db526625ce67ab343b29a4af7a0aa0e6f4c5b194ad47ea6110beaa5f3889520434e5c032cd5d65bcc3f842072b80e9697340797aaab61934a169447bf51147750df3929be94a8922a016b7f35a62960ae599b3658e2ee3c103fd85d71c0b0db06530258fb7ce5d048806e81595ce219f3f0216e1797c432f19069fdb9d2c2b4841106e89b7c38a7ac7b0b07e8d6a9f72b1134259d7971d93abb67211022ba4c38e324c9c2d0f65512d6687498ffb7b44e255e71a226ed7bb24e9d0bd4e275f8b4df0696c1da981ee23174ed2a1d0095e2357d9ec65544245fed8b4a2a645357591ae27b83c861dc9e6698dfbbccc2dc2da85823a689d87f4944331b1cfe9b9536925c62beacc4e8193c1db77d597ef56b48df95098914c50b60145d4c0e4a7a3fe4d4dd776065bbf2626cee54a07a8fda8710f9c44f4a7cb651dab0b4873f812e1f52e66bf15d9ebf675f8a27a6bfd8e974009dbc70ae3f6c7287c7f7c0c1420292595a29f315202a066369ef5b274b3dc4aac7f6d1591ef1245c65a5b256668a70e0ba165270286d0028ec2b2b14a75a33d86c82aa34c497e8d2d4fad4950c8cda55ad8dba16cf233a62a1f05099c528c130228a1a95fbebdc0fad93ada855ce780525b6f382c7845a212661c3327397af1872e344f21d74d0dbfb10add0484781c30b3ef611dba74c70ee6235f10e368a5d17ed4a1668ef4d1f21fb7abd09d5150f9747bc123dcab3cd4a6aebbf14aaaade5d071f15c6c5be22177102dd88897e29b67d48c1d46006ff181167056d6185aa05eae8859ffc070fe6c256a65d59372c513012f433fa2ca4cdc235f10b1b6de48468e305920c53b3318240eec30362427449208189bee0accf51c595925aee42115bb0ed98ec508d08b68cb6c3e0cde367633db14a541758c19db041a108f3516777f0e1c9bbccbd73a51e7d7114cb78ec46dc1c19eca011124dc94ca16a70ccea9617cd06303a4d9a233e39cb202b16d436645fcea40764a0e04c6d3492c1bed877cc466a9000ba51ac3554db152835e64d12921024130923ce7a7309aa548e88761e828341927608fe027ade791724f459151a40a9470f095adad20a711fbf408fd73965a001dd5b4b6b1034c3f676cbbf48d4de32186f705960c08f774add935a2c617c2aa0631a4118123c108a59aac9b616aaf1333565019acc48a9cb40db0a391a07d74190c522cf9bba42795cf90a088b080f7d59144855605ef8a9cdf9c0601fef03e9cf4b3564072e8d2be45e1452f7748b4563197411bca607d57032d601eb8eed5a1aa29a8ec88a980c3ebcaded9ace48b2ce34c78760e90a1ef28aa616839fa6449cfbfe4cd62f6394f7b179b6ab376d44d8140a5414107c27dde4008d3635f517e1371e9bd78cc509e913bba0cd04a5eb280c672d2d8a4b447271a4363f8e6baf802fc8205c14abca8953abb56ad4d352980c3484138c2ae858548780d132aa50b4a5b027a0140375db765b5c969cd74a48ba4d563071b21921c0b22b0665d23caa3334d7355515a1abaf4c7f59a0202617b25909b4a39bbf71611c6649281fad1a933034a3f08938f05c94769d063a9e0d416108e46042e075e4a8da36e74b1c0dc5fca73e1aee003b786abecb628a58dfd00b3cfda79b4aba49384701d2da759d4efb3bc15a329e6a4a46bd5260d1487631542f96eab5663d15ef91c6d657f7e2317be2db89c29f3687e6e0fe1bc6c0d82f2e222ac0f5250de70811fd568aed8077466056d15ee87abc4a67c802662dae884ebe3dd5c08ec0f86d00bd82f3c75b2edd6ca31f3f7e56b081280c09494f341bcc9590a892e125bb1c0bdaee3156c3c0062bebf163c260bb6f44d913c2815c3c2fc1150eec993ef3bb53945e97507e629b3bde98addaa3bf3fb2ac82fe034e423aaf97ab68d489bb83fd4c6dda7117ac64b05fe20d24c43333c96c52779709229dc6f9b1da50177521c47f16ed0ed3378ae82e5bb28f9eea922dc9d6b9561a621c0e7bcd9acd849773f1a37d31a9a00897ba236066ea8777acdcf38be51eae24bd43e1008099e0592507547be58174009ed4abcc6a90e4e1d3e7f14ff74f0d36c22b4dd5fac507464fb4f8292e86b44dcc16db3aeba7f3c5abdcdb211784c1ab2bfd641b1bcec345dbb4ad95077a168439d45e2ecadbe7196b166b26819d73a4c9c4c8f851ae8db1d4f187cfe461c3e0f3f0cefaa04e478ab7380fae9b4b381f3edc78787c298547e6209c43ca57cdf1630a37ab7eb6a15213e3dab7fba8cd0f271ceff5d87cefed61636c7d49a085ad06b6ac1b267cb2253fbadc662b2903f0e6fe397265e4f5dbae036a02ddfc54ca18fde93f8952c26613235c1688db7c877744cf96eade90a104f411525113c039b4f244205c226b691202c01f5b4649e8e3aa014e2c0fa23dd800ce4ea15ada727635fc0fd004de6a00c5ba67a9f0de331a7180a86fd00c60607e1f08a038a11bad3236ee3701ba2371737a1e81ebc0ac3aab3629dc8b019a274f7c3390b442e5303f3f3f3f3f3f3f3f3f3f3fef359670fecc944f00b223ad8007248d7496e4ae94bb805601cc8844000000000000409707a607bd07671c0fd49864a4bfb2f60a30051810800044a0a620c50ef414e437a6d8ca13a1d3819eb542cfdcc2e710b41c98f4420707ea4c4aae99c21b68e7fbc1726ecde82dc406dac9c8234919a406dab87b6cc89c3108f941032966a06758a3313f3e64a0c9844893343c62a0445530f76c7b7ff18081964148a155f7399d365ea0358c9b1f7887760a192ed022c4bbab94b64ae3d5822548c1022555b586097b315e5e815aa62942d987adb3a84047b9fb257eb9586e29d0718523a992ef6c1214a8ed318799d7d059a43a816ef1b84dcae683c7044af28931e60d974079f10d671d2948a0bda6d80c175e6e2ca3d0332fa4cc9dac610e51a89bd1e8d15d483146a150b2a6c930c7a87f4702850ec3e7990eef135af690b367f73757487b420f8bdd1d9bbd297cb8135a861f0796a23a482639a1665dca583e6513eab4f865d0386583026842c98d21f7a6fc4ca88dda34248f6342d17609cf1ce74b28272183949299ccddc7125a446c1072d89c4ae813924bde069ac5baa5843a79732c6fac097eed24b49f7cff603c29093de77091fdb3636b2b23a188feb84e1e1112ea46e7a4889fcdc35d1ea1e43c3bfbbc5c692fe708f53fbb48e34c37429feb6053e271e37718a1c8a70d71f3673439b90835d3e39e91cb8e3c1b8ad03f7e1ea5fc27420f8daf8d112285d079446895d34b080f91a7317f08cd433294eec690e9de10ea444bc6549a27a5b81742bf1015f6c2b6f1059d103aaac8a93d067d105ae8fc6f7ac181c9c505a1f979aa7ce01e32e81d08b5f365f0cbe11fe75803428d6312a7b1df38e8ffa06c926eac57b31fd4699829c624a9da0cf741ed28a91c6d613ee89121759e669154f5d983d21343fb4f037790a307e56dfe42a87698bacb83261edac7b3ff7ab2c583b6e1f3766633fe70e41db4ff9872dc888590f37650f3db613619eba0b523cd99436974d0be3ac48f3b71e44f3307dda4713c7b943b7466e4a03bb6461229f2fb464a1cf4f3b1cd547b139f3f3868b973dc51c6dc1bb474ba17536b8ec9ac7383b679d3d2936b3403ad0d9a83986370d4b3418b0cda412ed1fd90d7a0957d8b67d2939206518312efca338a1cbb279d063d3bcbb59668d0738ee18388e30cbae386b519d48fd921bd7319944795bbb1f3e5a7910c9aa3df10110a3006f56248667bb1e58e6e31e895432cc9265731841c06f5af313a9d684da14330e8b0927c88de8997df2fe8b2f956b12f85fb2015c00bda448a4622f92ee8b85c62445f5bee1c17d44f21854afab88354bf05cd7c437485d0b5a0dc4fd2d9f467418b8c63beac3b16f4dcfbeda1fde173c9575042a7f28b0f772b289fc1e3544171bbcf9435388adb492a68226e972cab365c7e0a4a3ac90f6383b1d8194a410b21ea714f8a738d3351503f46e424733b8ff402055d5c67abfa7b827e3906afb6ed9ca034bcde74df9126681bc473ca3e49338a0613b4881f5248f6684c426a099ab8e6acc89a7e500025e8d5e2b12179579c49d03fc598ca28530e9783044d26c79fbcc12368ee1b1a23098da054c548993931a62f823621e4f464efdbf01141cb3d9642720bf990fd10d4b1f7609d3121e818c9c693fb04418b8ed69c281d085af808127331c727c47fa0a62db11c3fe6876f120e0ae00325897cfcde690619c37ba08e779e5fccf577cf031de60cb2ed610c71f23b50c2d14ed57674a0278f1023dbea2da5e440f18dccf93029c6b91a07b985b0151e0d2bc00d94cc2948545bc839be0db4cb39f36bcfc7ece91a28c17f926e39760a05a081f239f35636f320b132032573c3188d6332d053cc64923f8463a0278b2993b98361a0548aebf7d31cbee32fd0427d56aaf4382e502e4383d0c66981da313d9f3b4496cf2c50ccb3c6c6feed0a14db0c7d2c293f425e05bae6793109dee0f4a302a440cf1c1d9e7ebf1a14000583bf749323c62728eda7cf045a480816a725a6df912550242b6df2f80b4082663a9bed6c1a47a1c6e6a718315b9b2a280a2d27a43014dadd559c5ea578e01b50687153ee6892178d49f309fd2e67070e3ce309e5ec422ef9a8f863994e6815fcfe4f6246b89a133acaf86df537294878134a08a70d83ec07ab184de8ae1b26840e3926cf4a26f498bbeb2264061d2405137a589867d3067ea1512ea169cf4692cb3e95eeb3843e4172a8b8a55542f7dc11f29d668f77314aa81fafc43b9645858b4c42eff89ded5b12ca84b0975158ee14ec1109bd6d3cf6c70f24d4ecfa78c2e78cefcbf10825a4c94f967662bcdd119afd63077d3795cfd30867843a9f62767c5ebec50704022c426f0b93dc692479318a503ae420c163d8ee49a94498b2c33c32a7dd230022f4d4d17e6737fee721b4edc89c1ec790c7fb12c0107a063a591c10a010dafe5b54caf191661c0dec05080108a14f8d443dfcba31fd07c1fb25af5839c9e70551eb9795e67c2098b4c9427e629e0f0863380f1be9e29dff875308791c7c3fe4721e2666be0f8e66997bdc9df4b9e78359a5a1628826917d0f04f79fe0d2154ad78317c37d224cc6d1f350ac94c26f84640d1ea85c595efa472a4e803b18b6f1cc7cc60dcc7302d8010973b1b63a1439ef72391dd8f67e70f91c36891c6e6fb6f996832ede691e8668e9913b0e9d9668bc180e57249387e937f89e99d1fda3066937589bd155c5cfd954751be8afb0bb1439869a0dc4346c98bc1bfdbc86e27535683b9537c2a3d903015bc67e50637f0c331de121c43e281e39dee376ec2157f8a0a7b790beef73c8ec1ef4d9f02fb70cd383f6220e274f237950cfdb2f540eba751f8207fd81c7ecf9b8837a8f7f4386cfca57b183328e41f212079ad275d0f2dcac236443ce830eba8e868f31a7ae07d51cb43011ca72dbc56e88c84189c1eb2cc761fe360e7ae9559eaa1fd36ee1a0841d4be2dbdd41bb37e8d6202ce79c4be19a1b747749a23926a30d8a597bf0145fc306ade3e38d91354b677a0d6a65e414914935e8b0f665e7b2c774c93468a92f260b3105ad91141a9498af7b733e399b8c3ad86865b5e5aacca066a4fc31e6a457922d83d669de252e3f978c64d0cc4693576fc6a0e3beda86bf99345dc4a0e9888ccd79ce382c0c4ac7ccf09d22c309564aa2020c5ab48def0389db072116155f506327890fba69da34e305b5431e5e8c697736562aba60fcc65f1abb632ea869229e79e8855e30b5620b4ad6bbf86f86878c508516dcf39a1c17775464413309db0e66361558d01efdc467778c8fbdbb025aa1cbbea3332aaca0c79d7c765916f4d35e5105cd2632e25eeee7cf3837a8a0829e52b218c27f3639df6c5031051d6df8cb8b4929dd440a5a8e573d7b5e21686796501105457772c25170e0ef12ab808256ada1f7633a9fa0b9e4ced8643b5ec68913f4ce1324c404bf18b251d1041d6748bf2952b68209fa65947263334c296759b1045d5a725fa1042d6e2c77ca9429d84515495032380b9582d7a9810a24a8271b39f4f86947d051669f3cfff822737202a6f61411541841f148f25ae1282fc37902a62a8aa03c1c4d16924664e50802af208296453763097f4ec054c510741462f6afcdbf8a1d5fa14208dae7db642177d7871403858a2018ff95f384740fb20004800c154060e63d421a447e09868a1fa8118e53f65c23f7b152e103fdc37568fe3b9bc9c08a1e68beed1e4f43abe08116f4e2889f260fa13e97838a1de8f0a3ef35f8f979f87150a10345627c06af1bfd39e11c289b528f48c8b13ee4a06942050e748ca42ca69670918c1b2554dc40fb188d71f94a973dc5068a23b710bc320e5fa152031d6938cbb931e7865d31a18206ca6ee8c611f6e1be7f6e06cae7cb1cf7b3a70d6555c84079d058ea2f4ee718ef2250110365334e3b218bf955761a500103c5513cff881b32fe3e26606a041ec0c0074855bc40732b09511dfd96cd06000312e0430b152e50a37175a7f4219c7d680a152dd02b37fe0cf1e341c69f058a7fc8115d1d9398e554ac40b7eb94f5da3de40c272ad073a7963c19aa8a14a80dbf633f8c1a05da3e4c6616af32c80e2a4ea0f7c394c6ebe25c1b487450610265e376de0999373fced4a0a2043af20ab71d232ee47e2e091524d0b33a6d8510e31ec6f78811a418850e2b3232fe9eb174172944a1a5a4a59d7b9550e8f9c6325eac4e79a1210528f4b24bbe319c7708979c80a94c80149f50bf2fe6c903099de3e301527842aff2f9581363c76f448a4e6021362221e7c4ff6f53eeb1b2b89b1864943bc60887b5260a696b8b171db3c98419858bb7f51ea263c2d01933ed2506697e1a69962049594a3b5662f4531d7fcf1d84f4525042699c4a763f464bf49f84760fb4b632ea6ce91d39904212daa6202145eb5767db23a18dc58f5b7779bfba868452923f37b7431bedfc084dde34e6d047315dc58e507b26c4343946c6d09e46a82deff7538dc308bd4dc3c71bd583b02f420f1b1fc435f086795e45e8f932a40c499289d0426436679710114a96cb7329e4addc3e849a3daa4baf3286a8e26b4816424d319c5e381909a1489aba3caff9d2b96410da9ca7f1d78aed1d0f412865e52127c70742d7d98a417423c44c1c10dac464a41d36e30971ff418d90dc30f3cd7ed01be9846caf650d33dc0735c3b025bab9221b79f8a077c8d1da967f0feaefd4574a39de4e5f3d680f24cf85f0e64149536197418ef4598907fd6dfbf16d0ede418b1f2607ffda0e6a68daf2cf39dbcfa60e6a3b8e8831273b97a3d041b309ad5cc1f234bb73d0427f88cdcd991cb40c52eb86e7e2a07964998c7c1c70d0324e9325cf32dea0267d3fcd6119bf1ac30d7afaffec8efdf522ae3628ddff632d9a22565b6cd023a577f38abce19a5a83925b61eb5a4c35a8a11f927bc7b29f4c1a949c22c43470cb91a3412d6f0967fef93652cea0c69d1fcde1353f2f336813a44367249541471e1c65be1c07b33d1974ad9042f28bb8e1263f06653ec7835d2f063576348a0c1e54fbc6c3a0a64a9e26a394f472e56070a6f224c490bfa0c4b17718933288c4da0bfa65c36c7e7517b4ee0fc1275c2e68a621cf06c9d89847de42a63159901ab5a09f66d029937e0aef380b8aa4f4e73a134a23c758d042968cedb8ecd244ce15349194f532ba5841b1a9541d529d68785550fcaf45334819b2514b0525b9c549e9249c82b61353d738f7c3e69482163f04cf3086c80a6646410a5240818a1f9259bcff0463896684a31b9da0795f66344107126f222127a90d2213f4f19a0b935f79bae112d4ad69f819edee1b824ad0de5379a598257eb830094ae64d3b1662f8b46c90a0cc99b688b7e608ca585ccbde6bc6163346d0d1f744ce6d2d6dc92228efe04a927b4ed69108bac9a4abfbc9c82a1c82dae81e576875038b0941b90c22dbf3c4a9ba4a10f4f80ab93d2f6e45ba4b200510940bef9f4ff2b448547ea0a591f87a8db18c3f3e50ec1bc6903af3ed8e3dd0345303c95226638bf87968504bcbe3c3e734d971062d264f93dccfdc5123cda064c66942a5cdf56129838e3bf7e758ba198704c9a0e8a31c37a12bb2f663d0b3fde17696763e590c7a79889547c48ac3a04586cae03a6926fb8041f1ebec4df1772c9c5f50225da7cb19639798315ed06abacf72ba0b85ecf1913cd95c5026341a0999b3133a5b50ea6736f666b5a066f2b8b86c9c2f9e59d0410a9bffebe2ee35050bea545b2ccfbe47a5952b685e6ed172be15d4ce75538ffcbd3d58052dfab73a4b860a3a7c2c59d3dd8cc9e5a6401899784a4117c7d73126cdefd44741c94d8fb1566650503f9df58938ec09ca5ff032f32f8dfc71827ab69dc53312d994429aa058c3dcbed9ae4d13c204459368106be91c3206598212a723bf53cefa120e257c5fb921c63e09ea8d278de8fc7b291a48d074324ef12a8c8bcf47d02407bdbc378da098d557dc182c821ed2e78d577331fc86084a6d4839511e0de266084adc46c91b4e84a0bc87dba48df4fcad0a82f2b03fca51aa80a06cfee4b0b34897ff3fd053278f192bee03bdf536e6ba18be5ff7408731fd38f26b647ff240e9649fb135db81d2286f0cd520d28196b63553ead0deb84e0e34e9fb8fdf30a5745ae1400bd6216c2aff6f96f6069a5b87ac9b1cc506eab554d03bcf923c344830450db4343e13a763fb96723450c7eab24ca8688a3ac77f985dfef89cc11432505269867bd592af93850553c440bb60191a324a9d67711868713c676eb0615358fc054af698c95e5f39e3e72ed0abccadca5d53bdde2dd0f38567bc6ebe6db159a0677978d538eb152836331d62633d5b611528fa922eba6d3cd57452a0c4cf6fa1f2e353bc8b02edb542d6ec1b2f85234fa0578c3165981c07eb0b4da08bc592a07709d4ee6c691c0dff2f62a6208152395690b0d9710fcb28946fbf0cc15c51e8b631137e92178ac24c380e144ade4c0fe378f208b67d421f8fbd3143433ca15d889063d29dd02485dbcb92f1a3c6199cd0ff65bb3a6508368db2d8c45e16650ea7c5b39a38c57c693b4df9723ed081083806326001266991093d47f67d47c88dd9b29850be349367f3e40e26a75c40001697d0b24d64318b2da1e72d8bf8c89eac0d5389d19f9f5f25ef94192574cb0d3bd31ffbba52008b49e8a8b7bced639650fa4942c92efff9c8eea6411cc880062e4001538b4828e2f1526d087a9f1d0d093d6bcc28cb32533b88b9e28057000314b080012c1ea1647b4fd8cdd5de3f618002a66e81b30ca8720b9cf5c09d852314f9ca703144a3edf71aa15f32873142af9d181aa57b11fa6910cdb035b423a41431ea0e216fe3b113a194a6bbcd9a4684eea12fa307b73948fa1c4297de73f1f9ca177b1a4277f4c0a57d2c85d02b1ec55738dec87842e8f0721b847621cfa3011682d0dc43f072e02053304920d4e9b7dca713a6c26600429db1aabcbc9532be1660f10735de6d99b53c2cfc60167d300b3e98c51ecc420f669107b3c08359dcc12cec601675300b3a98c51ccc420e661107b3808359bcc12cdc60166d300b3698c51acc420d669106b34083599cc12ccc601665300b3298c518cc420c661106b30083597cc12cbc60165d300b2e98c516cc420b1680105864410b719de3ce56c4a81d477d200916cce20a666105b3a8825950c12ca6601652502b42b84d686f7dd34441cba4e7189fa393880d0b2868f679156da135e779d3058b27e8383898f4a6e1669ae2828513b4093222c9f24d18a3cb3a13d4cfd3ec0979097adaa9cd70e3e26e2a41ad7c34e6b97936661274d1ddbcd89c1fe7f191a09f6717f3606d9a347f041d55b6a9ad946104dd32fc64904f9f8ffb22683b1ea717d112eef144506a2ee7b021e7db4ffb10d42c6bf852973a5ce742d03223e824993c088ae30f9d2766b7750341df9264fb91cc27b53f50aebf6f32dc4ff192ed031db7e968e96d30edba076a8ef93e8dc94b34a479a045908b294956c810f50e94fc69624adbea40fd14fa7d2644b6fce5408f4f9ade34650917631c682de11d659052089dc137d062eacb196303cd52a698b9b5d33035d06a279439be0c0d34b36ce79fe619a8bd6191b23bc3dc9d2303b53b85d7ebe6479d3c31d0638d4d7c9ef55bc88181d2697b73957b2809392fd0a24b26873c772173d605ca5fe86907a7132e6e0b94eb181c967fcb022da53d910d976061b22b503a5f3a5dc4b457af02fd1ad8587eb3b6d053a0594eae99380ab4d0d8cf9e988e394fa077aec8dc93155b37817a19c568f14aa085e81e4d9d411624d03f550e8d0ef38d61390a2d633c992cc2a2505a1ce7aaea06976330148a8674f919238f1d33080a6d63283149955dc3053fa1b65499757e1c9951d0137aefa6f9d86fdf39c34e685df9e217f29cd042748cf3bea18dd29bd03603bb70257779c39ad02bfce65cf748442713ba6cc36d1c9161ce2726946f098e435ca4eacd25340b17ba71b63ca22996d02bc4bbc98cca4a28121166b64176346228a15c66ef792c131e5766126a7bba4f0d2223097d634f8475aee8d023a176cebbcebf0efd7048a83ba7558dbbf379fd08ed72f8fc9abbdfbe74843236c946e822656219bbfb4c6484dae16363a39978e62234734f2596a9a208257c9e18bd7922b4c888f8bb1491f18d08c51d4ee3985d21457d087532b21c72069f21942c21eb847c71c63c5708ddb2c7bb9b4a2987f608a13e729c2b52089553e506a13ffa18745b82c4909c20d43c99be6a0f84fe9273881ddbe78d7180d062264f1978260d7aff411befd3bd5cc94cd0e7a31cc48457d87496a005bbac2722125c4356096a0c8bf9e774a3f69349d036c4980b0d2e96862412b41429ece938f6581f3c82ee5863a6ad201a41c91da4c3bce8e8ffa608bae5b27c912abfcd2f4450a481076dad6f083a7e39f7ee4e083a4a1af4934870e4a00b821e265f9bc6d4b83f372028e15e274e2be3077a5b7e90391a42eadb077ac69cc19b5bc520293dd083c614fa613e4cc615f240bff4f1586e53887f211fc0800176a0a4fefb8898d23a50b6c41e85a48bba07e740b134fe5e1782037d6c6c73eabf0f3aed0df4d7c80f8d8c724fda06bac7f77c5f9217fdc11aa8e1ea7d26f53bded2d040af14ecacf21f740767a003d906ed18c64b155364a0349a10c2a3dc3c2964315083e9340c0b7a977304064a3ccaf7faf036c00bb419d31cefaf71a8cfbb409ff70af616c3ec5d4e0b34d3dbede43a0bd4fc1e1d1a75c60ad4dda820f9ed1a4e892ab842f9bc46ac4d0af40b411a464ee13a7e05058a83f8ce70f3b5c3c84ea0ef6e8615b24990bd8909b48c4f2bdb4552026dcef483ef47de4e8e0148a06e7b6b5eca9edc2164147a46411fef556890c6210a45c7710a630d5b1f4feec94062f6db40a165079b6f34f6cd83ea13ca654796328c4c9635329ed045f45387cac68f32df096553fde48d780a6b0f27749370294fda9f9d3737a19d668b17376208d1404d2892f94b2fc74a11c1452694fcf899301d3c030d26d4d70fe1c9dfac3be4124ad4f93b3ccd1977e82da17f7a20e317d61fb3ad84fa2d99fde3c4f5a629a18d240f073a9fd1203309e5dafcf7add1d6768a24f40caf294eae1e9b3012eab4e49e0813486831cbd9e7c89ff532e80202178f5062969090817fe9d7e50197000796010108005e07ceb970843ea69b6f84fea06d2605cf1821334213f10c8f722417a17cd6782b42c9ea4ed6a1732274c95a41a762ec929711a16ce966f9385335ee3984f2b5d123133fa1ab6308fded453c4b0e1773b485d04349634f722f3d9d24843a1fb31c841e8d63cec54cfb7550109ad5c805a9080642cd9224bbc4adca5e21201471f063b1d530a3d9fc41cbb59f3f55b6c9668d1f740cda33d2c9f040bed2071de487d7f37023c656f8a06f54e5c73947570c953d2821ed83124bd63e51d1838ead3a36b8609be5b93c28ba911f84781e338a0e0f5a6309da38e3c9586abb83ee192cfcb66b077553cad9fcccc423590725a47f8b13bc7637343ae817fa221a247de495cd419b18153f63fcff1e968316768d734fd246b12171d0bf3ee69c2ab662c4081cd470b96a0c1b7da7fe0dba5e5f4876b3cff8b941d77a47a9c2d70625e6d1b0cc76ad0a196cd02cde3bd234ba0dbcba5883a69bdbe53a4665f474a106355706c9a252fc8b4e50b848839adb236cca0c0d3f58800b342831e7c6c0ee31de74963328a5596d627731370805d60366d0520c8d4d11c2ebff3b808b32683163d258bb54c6194c010b74c020e0820c64cb65ee91225ecbb2818b31a823bebbb33144c8dd88417fb1d1b81fe2fc4d4a18f48fefacbf8f5cb12260503b4e5cbcf8a4d7c9f1052da69ebc9c8ab8152e0c50603de01ca0b2b8f08296b372638638b10ab70b5a57d270f133544c6ab9a04e48f6874e6e413f7dd848c3dd5bb35ad061a411c92c310b5ac330ef871d62418b6c9c335c7cf8f35d41ad6b609d32cf5e7e182ba815962aa85339d3e7eaa9a0b9c6660afa59762c130f517d1529282f1363d9a34714948ed2fadfdc0f0791032ea070174fb80b27dc4513ee820977b184bb50c25d24e12e90701747b80b23dc4511ee8208773184bb10c25d04e12e8070173fb80b1fdc450fee820777b183bbd0c15de4e02e70701737b80b1bdc450dee8206773183bb90c15dc4e02e6070172fb80b17dc450bee820577b1021d74cc385decb1f8200439e0010d5ca8407dd4e131a8c8301a93b848c10500051727b80b13dc4509ee820437842946c1e5ddb3bcca010050554f98421415002453982214370528c8149f20537842dd1cb71ecf86af3d39a7e88462b9279b3eb7537042afb1f918caf39bd0d2a438d5217bc12344135ada9d89393cc810e2536442bbc6565e125ad9330e26d464313f66bca597112fa154b2931043a8f07f394b289d424831070f1a211c95d0d26b4a25215feeab690a4ae8a3110de66342a33223010c50200b30c524f470d8b399119f1df5010c44200222d80ba401484d8031b01c3885015348428d9b1d1d096d524476ce2863590c710e64e0000108009617a6808416af27c588a573fcb947e8bba93da414aafa3ee2083564bc7d3aa1653390a66884627ef32842b67b3d82d5c00546b00a08400046b01a98821186482e89102966143b53cc73954b369ee7b8e409532c4229dd707c219f617b4528e1b7c47349ba193d11fa854cc141cd87751a11eac7cfac8a48b1463e4416b2e75e5ed2108ab9c7dac9bae12b5908fdf14ca414c2a4d02021d4bcf6106c6283d062baf651c651de202f083536f0e81c07420b7dd3e1e18c80d0fff26359168de986ff41ddf2d0168337f8c7703f28f326276531c2c3f23ee871f51d53889c0f7a3ac76836483db258ef410d9633f9ba93b179d6839afcae2fcfc7fc27390fda56d81426574d8c1fe341fb68c718a5cde339bf8356af6759f2bdcec3eda095d76e10bd0ebacdfecd6bee4f1b3a68f143a4f34a3183c7735034db89c589eb94a71c94e8b649fac041d871d0bdbd42b0d210e7423828222d493e439e78df1bd46d10f2161d372829343aa4489d36689f81651c21c56ae4b241ff9ad0ddcfb1f0d9769eacf1a4ec1835b0933cba42d6320d7ad9018685a8b32451581288a2388ea3200842c0ec764316502058501cc86108c4b15053f50313c0c00aa2a040240685c2604020080a02c14020100c068381602010080402c18020148605e2f9038a1b2be328b1355e01b11526a58dcd216e854d1c4ccbb429c28763ab5a34cd0c1d3044b81cc556d7930821ae19824ddc341d25d5f04ca7ce00997ac5ce6bcf1457a6c60cff19edd0a4e984b38bcca4b404565e1e125017192b727f8f82afc1e74bfb2a31a7904e20d44d11fdada184f318880b576399a0532e8c6222922c6413558e18c470066d449607063194d20954c1015ab44fd31472d09c6c23f119c022b834052523b203978354c0eb425355c706b307cabf4fc05da81420705ae641220b00258ab493e2b3f69c7c4c6311c691e9c16c30185307c60fbd03d75d18dffdb3138be0fec8a15062fb77f8c63f181c13221b6df436d7db58c86c56d762f0329ab1499599b097bb268f97180c8bd16d60fa74b35e211ce2d39f903d893999af80c1c249e2ab0885c66881835a10095ad851319c9f073a2bb284932eaadc79df0c33ce6c34f1725d6c66d7892b5213fa5b046d334258dcbeab365e9b6263d89836f4df8c0507c63f5d1324c826ab6c2647e4aa2ab411db441bdea6b1016cd2c66f236d761bb3b999d1ce9407f2e5280eb631bed138bb8deac69b537dce98ad79219b38c43633a146a8614fa876df3d01e718bf2055a514389b0842d24ec62f0ff0a99c778b81c0de7a5ffdfd19fcfe71b8009b82dff376161cfc87e92ada61eda118a05745c88dc304e28da6bc425f157ebd8a7bed40369cef331b173d8c774f235813636fad5f186b2e8ebd12940403c65a28d4a0ef84a9ed235ab2bf2388b2681d08638aacac0ad26cd0aa84cd9e622e7b74f72551294d8e080af4e0b46a21785486e33f381a402da0008eafc5e70422791c811974fabe42664ab27676666aba7e37431d5d3b3c63355d3f9bb98ea61d9eb99aac4f70c19628debf5c852cdcdc58934cd3d1b7290ead702f32ae0cf048be506094c124a2623aa465cf7c1fe7d53aecabbab7fd540b33d2001ee17ef9be1eb4024a08fd328ca738904f58f97d848a6ee1c0ac5244f6bc3779458e72704f3bde08437b9a91d090aec83c37da1e4f0c35202010fc41c5eb3dd2204be48d4db4997f850dc5aff54d6376f7c3223a36d0c7f8c5c8a7d2c620a35f6052b4485110d02e6073443b3c9db4031a3d4c8c29c7c6fb3589b60814abe4a02f113c27d023d626ecffa249671f8258479934dcfcd52fe1fd99cffa23bf2350695e06420d1edb895b23fa46297f830e5aa61014040a2b85c8fd09fc66673bec4ad4399aa1c476933cd4f93f84abf82eceb191406803e79f2f49df52e9fca4c95db3c462c755950a72adfac07fbbe5a5d14d954a92baf277ada66856c3e14bd1e16d419b1e79ac27e198c0a1a5d68d5afd24db3d4dfb69de4261b28ddd5cbf7839ac09fece84a7a9b1021f3fe1fa1d609b93b727a017db2fa6ef8e685cdb54ccb70f1d588b347a9e4ae8440e2c0db16250cf933c7d5d0c0a2eb068794903f919d209cd614de0a32590d551cf101fd2082e58a072101ef0c8dec11691357d69c20979e81445795d1edf739feff3333ff917f6701ede7378069f4458dce167fb3a67a024be8ef1b00a881e4f42110b1e009af15169e83d9ec7f75302df0ffc1f13841d7a203c4c61f107feaaefb51e8ddca2290e45d21f17f47db1428b80d7d2d49007f7ef1dc4a8fcb3cd0d1716b0e1a66468f4e1849cc46a678496e0e1b180b770f4ee12f60b35175cc81850181dd033de02e77c8fadf99953fef1163cb8a31bfc4a781bf9831b9cfd1340f21ee33d3c437d8f1c12d2c099d8fb88050f388c3e03be001fbf6ac1e0f830235c767021d7d92790c0757c0bc717f1ab8d9f9ae06312069485087142b1c3839b817bef1cf0107bf8d87beefd7b06fede9d24c7ae2be649138cffb72ecd795841fc783a15c7ae9cc1521026e51be48e5d6724a3b14cb423455669267728694904dcf1df5adb2bc55213f0b10e12b93e870378776fc736eb4cedb16a28ff1ceba4d9402d96631fa38376f00d92c1021e8684669f2fadc03f088016200eee2e6c40b1db564488deefbf104174a35937181180dc15f645b041b6c4a328cb05e238205781089d6ec3f1163698d76e6b91123583883e7bc566e2393699b3b65d7fbd06d1f4fadf7836709afa83da6fabad5d90f4218bb1fa0d0ae1a9964134a58653bfdf806f958082b9fee8912235ae06d1a18fccaff908c94c20a70f0aa52916c28c9b491fb45dd139d3dc632e39ca37583bef096349e8ac100419887ecb56199151987e95ae95410390af37106cbff35ecc50a52ae13329395dd119c4560cd85f84af1ff5840311f7502e643d793ded288a384f9f0af94871d2ee31c70d340ef1fe9df32b93c31efcaf27491416e56454bbb483279ca4ceb1b8b717d13c11899a318fb8432c5bd65793f9df5eea6b1a8409c21cd9dbb630222aa1d4939d94d191e0d82b2e1e00054800e3aee78102f5bc42380dec7da57034ed598c3d9aca5dc85da2f2ae051f59f32ec73e5d79d3828fae79961124617b14f38fae3b2b33d7c42e03c17fb53afccc98ca426c4769018eb4f3669c27077edb4af8d3822843cf654b560b18264a65ec06c1ccf3e6db21284402e981984ecd8e35b5384b9b959eeec22647200fbeaa9ad893755021d346910685cce4af7516935277f91c338b41865caa023ae448340c598b2406a9a679eb33c54fb1d37947c1d27b7b599a8a32d00befa578bb6e29b4db8befc02526ddd105ea6add15d40d357a787ccd778bde8f57eada75856e13ec2eff73d322a35e9217e87ad03df73e25e39fc010e75b6f6d5b75946ea8883d417dbc92eed1adeb6a5dad5be4bbcbede58b74a1aeb59bf46275de6cade4849db857e025d6b79e7694ec7ac76fbd37837cca7d81bbaf1584e721872ed68deb52dd5f57607643ade3a10b716fb217de4be9b57b437a0dcb9b8d1f8bbc2edda79b7e747b29aa5ccac6aed38bd5ebf4a28a375bfef9c1c5f56031f5fe79bbfed69de177f631e966fb5eb443d4ebf786c9dbcb062a12c1d01574075dd615bebba196e130347d81bbdb5edeebd4abf076ddb70e650975a3bb7b8e0b352b4cd7a2eade45d16c3cb7df9f17faabf79a7805ddceafbb57d25b9bb79ea807e6b483eeb95e6eddd4dddd7997c3ad04c99c7a3fafaf2b76ade18e0ed85da8b751bcd95e97f8b9b117d4aba6b72eaf7fc06030416ff24965c771672aa422b96491c28ec507f7ac690cc22476e893aa2cd2a887b63da2bfa0cdc332eb6c0018fe61c7b2c57710db674870b9c887159904271a9419bc94b26b38947982af12443fb6d8e054a08b87cb5415063681b97aab06ee54dc6d1af60848817e0567322d3bd658ab7b778e89d1b4b978d72cf04edae79d6594f62f044852b8a2b3661746a4930704d16a24d34ae2bf086460c4c3190dea889a6b052268a5053080c16be360e258d978939b192522aab4224160f1637663c04d94680cb1604bc943247bb8763b62444ac78c534edf1a93908c6536acb167c417ad84ef0c757cf119917f5809634b0dd6d82ab982270d6f660dc153b3def78952888c589bd5a3ede86b61ddbba102ada5790a7d9677551b3953908105cb800924d8caa0baeda1f6632c26f38c16d45b0f98227156064e737b28ffae688c1e2b3c3d64900a883863d6f0ea6d814054b261c2f79c9edea531944b91050f0b32c6750d7e3d7554bb3bd2020174b3c63ec6b3dcc509451306e60b343e7df99c87ae331479ea86ed28e473092050107be55c12de8aa0b6dbfdc3ecd4401ac0d8500bf02f2fa635b5e828e25829e332787127646683c5f7e8535430247d0f50433b47f5118547351efc00597c530d53c2a05cfa0f801c2828b9a9dafe5e4da040bb6e1befc36ee181290cd8b89135e55b235cace9e5c8745c5ab9cad4edf74d6ce25074b41e00dfa6905aa4b8bcba2ad288d0e83e1a1a76b22b6b890f72ad74989b938f0f7a60e4b88f63a057914a52284c4b2490e0270a56fb8ef16da64535158e7f1badfc970144331db5eb08d4ee3657fa48da54ee11c11d5952b9440f0044846ff42c87a1e567a2a7a0332d3a922485f02eea02cb98834d91a45215aa094e3430d1a33c21987d9aac16829961b84a53016d80ad435f9e9ec1fc55f941a4564fa28c01afc86da5ad70bfe8d9b58f6a50c100429322afe691442595d2643f2462bb8c46aeee3fdde16c0fc425726628e6e1c490be73ecb4f6890ae20165900c7997daeff208bfb3df0a9ca143bf21bc1cb66bfebeb094bf7b9e42b29426b49f9928b43ace4b5eebe0f1eb0b922b158829083dea1132e270c11e0713e3f36f2d27fead440057828a23997af39555f7878226068ceaf92e1987210508ea9b3204efa13b9f5b1336e8a250cab73bcb15865406bab4f66c7f4feb3843127f52ac865ece02809245d23ab10c6c59170a3b4a81bb501904ccf038d244e214d5b86293f7adb134bfa2855195b90dffa179236230fdcbf7ac6950ec92a63432ac9b39cddebc640d8e48d1528fb411b684d51dd000ed492141d5f0a5afc46ddcb1ee6bfbe1420a81f3d267277880a9b25d61f00c0206daa0ba836573edffc977a010143cd848407de8f31bcc2439f707dac1f2091ba520824cbfc1862abb0f14961669b80733ae14fcd30c34069b3698ce7b24bd5c78179d4e6e200d4a38583e774d052a83dbe0b706339a6374f6060b3998b9e661d52b6d2089c1a62559527ff660cc2399f8fa492004cf8105840d36767d059f1c6c569d709b9cb0b92fd5c31b18eccb3662f36c001b8c06bd01991dec03d60ec31ff020d00b2e09c86e5cb95e66eff96a0e59cb27ed0c3e68b04cbfe71d8206ca80bcc18c795aad4e81a0fb60d3f71066adf784191e25255a08181b8ca1a66e002485da0018d8e06046c2e5285e0903113631765031dd86786c1034080ec8b4548aa122207222c551f564233e6f35276c827070271475003833696996d488c208a2de1900836e5037e0b1c13e16b64a6d3558073c0972c226093324c278035c795530ddc6b80ffe9d306311bc3930c7eff067755a51923cb9d01b83eab227b7a4a0848e4c7a155238adcf05fa1b624564998a62358ad2668641de838d2cf6c511fae7d05d844d0c7be705206c68ece04735c44d05189007c472003e67055332300fd1ef4b433f4a0ff6b5037652b48131200c3c031e0c7c5803752736019be1987e1b25e398f04da8279008a441dd0b1b34c615db1136230f40c8d8604a60276103dee40e3ae80d973d9f09af685b6e103e8087800bf005980399aeac2906342790f98ab5e1fd571a78998b694d1c2c9b0ec0cc5eb67f04012d5b9a1bb0013c1e40f8638568ea002d0053015ae270f9620ac06b8030134c37fd001660e603840dd99f950db007480960f2370030e74cceae400fb407f5f83d020f037cdce4199e12bec7e5c17ae03f96842ce1c78a70e3d15f3ffef0bc484be911ff80878820c4a3e1c3a190938fbb3bb7813f6ea654ada33c8c47e8a13d54f0785f91eb36768ff520438f4916cf2f4b7b4800d17d8c1472827fcf134f12725a09d677c73c4ed7436a7d191a59b53e9690f76a1c4d48f721a72f7f1d8d8d0dcd909a59e025f05a302ca00bac182331ab5893ec251fafe1e22c9251882ee26a12ac29444a17124c9b8b20a5c6198458104f8528724ddb6a297af37a74afb786decd524c159a854261506c4321927f19e65eb71031cbe2f6572bc06b12919d025220ac10617f776889effebf87a98abc4b800ebecf09b3893b905934fe49d42b2a091e4380046ff1b86802d4e75a4f2e3dd1e3ef8c1227081821e43410fc80c9458c88277831d173a6506b61c2a104e83084387a3c1ca9c408d964cc0910b727a608e6ec8e6e46c6aef6975d16290ddbac2259d08e7f215cbafcdad0c4f0b559355ecf42078c26087391a005852a018a950c043601a2b83930ff113d257013068e082f016abcdc0e3f8ee8a9a881846c47749e00f98f2f8ded1e018291f87bc34dc86ecb0d158307cd3e99648d3ef18edb123d0aca30106bb67285441e11207d5968f63402d43427e128203a8bd0666af36af1b63500428508200462fb64c59d09f146744d2013a98487d01045086b23b4c59fac79076221003ca287a249045b4a4811a16d42ff62b0c45ac47902449704f6a64652fa42ec7030a038416c30bf5765b0dbd84602d434826fd92218d44428eccd7014bd5bf3a1909bdda8802bc26b2338939307015152a1c3636d6cc33d4a6c36fbc5fcb355f691f7142266a695f929693a3937bca2f555ed50b40d39bcc087a9add5b47853ebff058d1ea927bf895ce35fe46d3f754422d3d9e795dbb7f79972363b7f7140a15307f65b9e87ec6657520be8414c1dabc92b2bdac357b546d877ff439217b90961be7666e699210dc0b3834e6afea37dcbf85800857e992390b6489cb6e2c18d61dd60cf76b8872f1bc7c88192a6533af9466d65bb47cbabeabffa30cde041730a34fa81ca7853fc989a9ad86c79fd746c4d2fed6c57c5fa5f4f2479d5fe6c6f2d02b48e6f7b95ef6fe6ee503f82d5dc7202ae13c4620a3a70b46439000c30c0000395400209a4b5ab91861b2111736399925442b82fa721217ba71dae5b52a624534aa59061a9911cc9911cc9911cc97ef20f0a5d0ac50a968bc5e4262ad957c451042ec5140d4d9994d21fe1200213cde378bdaa1c43e0bbf6b464132a0e213021a948efe66b10b891c1c5b54d3302071098a031dec7d020734ef2079caa308d3125a5e792f1011f22bdabd7853de045c3575dc57d247b3c60f7cc4ac6d6d12322da0113844e113f29d352e7eb80d32e1543c6b8c901db214ec8f9316f83c571c0e81c3906d9f9b901671db297a5686cc0dfc9fe3aa9df39755803762578fe6578a5107f1a70253345ccb1523b9d9a013bbaabe2d692f74b22033692d63f6b71d35f3a316044949874ce4cda9d2c18f0fab122791ae14186e6057cdf6e55ce693bd6a85dc0670dca24a489b5804fcabf7ad47e55be8d057c25c9da1d417f9fbc57c02991fe634c272d832c55c0f575b609992cb7324c016f9d1eb2a49d6461691470e2d5a232a8eecffe4fc0994aa92bfd88a0de2d0e13b0252226959943d67ec851023e7a59be24cb4409e919051bec830a396239e968a260acb427d3f6b15070972225f5d69c2045040af6736d85e0c962e9d181c1c52778bd4ad5fa277fec543804179ee07582d61ccadc73bfda09fedaf5352551a9b1c309eed724e787644a096116c1c52638ffe45649a94b495646139cd28cef769d94097e3f7f8920166282afcf181eb4cd4bb095e4c5d3617fff124bf0a23df768c852f1b4a912dc295331edb8f8a4b150820fb263ea15111395832681cc103ffa6ea592e0d3b56d4ffb1809ee7ce399acca6dab494870d92c86a9f4ec119cea9493d8a5aaff933982f58a591b336b90343a8d78b3526e0efa9318c19e275d7aca3cf9dfb9084e5d8afc9031f53ba828828f9feae3851037091d13c18bbcf75c9be27eac0c114cc8d992a952fd105cfe480fb24a6308c6cb2c4efa8e3c6abb42e859114d4230e926794e52c9bc64360836a7649236752d08264bd01b647e1e084e8f78baec4954ac900304a727ca4b749220bc227f60d355caae1e945015f2039f2ae41ccc922c25bcd4074e640cfdb994979a8ce1035b5916929886ac4fa53df039f74aa86f4b72e4470f8ce9dc9512a37b0835e5814b95b2c96f0debdc3a1ed8899b777f935668cbdf814d59aeda811da1fa7316f34bf163eac047dbbc9f76d474e0f3d62b689226aa3d9d0377b22bb79e87f49439393049c41c9121ea65c889039b54586529cf539e6f3870dac77c2cb56fe0925227ac63a9d3ab1c37b06fc15232a14a6d6042ce74122fc33344131b180bed3f3aa71ee9a25f03d75ad67d1f53ee4c911ad8b41b742ed3c1347029623211ba35dd860e1af8fc1291547bd016b27d06d67da4676ecc943e6706fe5b3f3b95502903df265dd29e3ec9c0e69cb46feacac5dd1b031744d09818981864be91616a18b8526f6a39094b9a3b0e06465a57149354f902e71b2ae4854a96fcbc0b5cd40e7549af3cb4925ce0831ead6d999408c294b6c0e815111e83660b9d4f5ae0edd3e7dc926d6591cd022f66a7f26fad6409aa2cf895a46fcffaed2bd75860e225edfaa3c64369f10a5c2a0ded3f692bb097b2afa8ee3c4253b00a5c85905ff22f9b6dd6a8a058bc9499026b16db334583078d1529b03f29c9a4b3e5bee0220a6cd86becf829f26dce09c105147c53214a4e53052e9ec08d7864afcb0fd36aba7002273f7f7dfffa95bcc98d44c3451338f93a2908cb7eba427e052e98c004cfb86751552ce962099cc89642d6d310cd7ca33470a104ce74ca62214bc8f6635cd1df652509aca81791dcd7a28fd0cc384de349ba0ec4b041a3068d9d810b247095538e1247c86ddcd90b5c1c8111f93dcaf259683a7d8941a3461555d4406a366e241a2b706104f2764cea3f49d554c14511b8fe5275c975257b8844e0456b295d0c215d0881ffe4aa195375faecac20c14510f87ad1929d23c7bc8e71250b2e80c065b18c7c96b2079d911fb01245648967b247a5d24ec1850f981462f9c8c9c9bd6ea32605173d60477716b9c183ddbec6034ec64c395f53348997bad801236af4f4c51c173a602d866c6e57231739e0fc45b9247b0f0e783bdfd75c318860ddb9019f96476555f67ce39ad2810b1b3016636747c87e994316031735e074776f68c0995b9da8acba7d91152e66c0e88f54df7477195a19f0b7397bfa0ff93ce9520cd80dda4e5ee4b5185a18f0a5728fdd7fa87a12bd808d1bf5d722a51055b60bb89841a5fdf293ed9e690123d7bc4d5facdcce15dc11b860011bab839eba1c3719b402ceccacfd53b2b19b2415f071e3e4ea1a530af809b27bcc354552b98402ce93d2ff0a39792ff52760348e8809f89415f23ce5a8aabc7151023689681b3b87d0394971147cdf08115334794984982838171b61ef41a138424a3934b4a5050af645e50ec134a96c1df309f6565d47f5795e13be2798944672b4be4cd109c63478d68c2a722bb736a6e004af392889b941be09d6c3238624b99aa6d72aa6d00463b936e84af93aaa6d5204536482492ab7a486506a2d8a05a6fe06cc988145478b16f9000cc4b8c01498e0d7753c74dccb499dc3628a4b70de399d99af26c9fa4a009503535882fd4d2105252fff5680808a2baa70406225b83d19255350828f902d7f89b4cdb0988fb5f11de89f61ec8a2aca1493e09236132146cc8bffee14926073ca551b647736126c274f327d10220a093e3cf29788766407533c82f54f26a6f93d298bc711dceda5cc24b49d10d19ba211acd9a9a7957a491654399882115c27b7c813e4d6757ca75804a352c4b86974368522d8dca5c42efd896034d468043d294d7c44f065559e3ea66c6a44e9108c4ef5d8a1521226d56408b663c8e117b554084ee44caf379e3da78410fc8a50ad92eb938ee10f822d1143b44d2d08d633c73dc62f0582370fff13a505049fd395eeca916d53457fe084bad893fdf603f792f2784588313ba40fec0691229e92e7df21e20327936c512babe8c1427b602b657b0dea9d4d4b8e1ef2e42b31074d3b0fbc68afcf1b49c5902f8387da7a4fe50edca8f76f5dac144a54ecc09d0c69336869ebc026bd129abaff72d0593a306e26f4d76e760eac9890a57328fb9c5639b036220549233567861a07fea4ede514c2545f0e07ce72bdc4a046c5caa23770923346570d9de3df6e60ed94dc7fd720a3b66d608285d6183f63d68db281cbf5cef7539235f0a26fd7e3496ae05a53ff9a887978280dbc9e1a0fb2434c95b6440397ee7d679a6dbfff3330d69afbc4abec2b66e032580cba5492de6e97812bd171ed84fcd1d0908193987ab4ee69bed218181db27e08a93c3130a6a259af421f063ee2c8ce8e5f2652c8c0c005cd29994a21be46ccbec079b00f3166fe749ee30546c436959d3b5de0942969ad49bb460de1027719dbf46faea8608a2db09b2f87b49cee8296901618f91562ae661cb7096681d7f1ded6a0ed3f6c476fc5045ab460c11459b02a3243335e4c5f793f58d8d8f2000cc410c01458e0b6737a6d37cd15f8cb171e82b48b89c0032270630a2b9837a79dce96a42a7059d2dd66ab9e0adc58c594a404cd9deb29f07d15524713ba1478cd232587caa328f021668f1eacdd3f931014d891a35364c920cd26e8095c3459523779cce0a6e3044e96e9d8f599f337e4a0a98fe619d250f0f99a1afaa249ee2e8182cb39431a5b1ddf4af1139cea1a799d567a737c3dc1e436dd0e41f829e9419d60349dc9cc971da6957182377d9adb04d712436fe52cd20493e3fa25797f97dfdf4cf0995de36eee1226d8b2a444e609e94b709d2582b27cefb7d3604bb06221476f1d0957828b1033980e99d4664d624a30c127495b93499e04d7f9b55b826649fe254b824d91d287ee86c8193c1c0946c54af11cb2e72a392438cda517e4459e1fc1469ff855296b485b2a3b82df760baa735257c5093782cfb64ea157ebeba1c38ce083cacfdb957decb48417c1b86d8e9d9ce4f1748515c15d52ad925c4585da702298a492e7cc91768412494604bfee1fbd7e620ec148b388165ad5edd6fb586ba7f11ae85443b0953d496ba95bd0066cf48d185c08d647ee25dde9f4b1e6ab84603528db8f9b2799ebfdb156c37910ec9ee67985dc4e6a211f6b2c08de3a5a67e7689020d21f6b2a05151e3666cc68173414d0a2057620afd00024820381ab26bdd91f1810dcda4ed2aaba91fbdea0f155fc8157cf1f54be1c295c48e134e4c07e6043c81b7242aaf7cba3162d86c07de026a8fa6bf98fa744990f5cee14b4a570d1ea9bc47be0a2a8db8fb41cd6032763e420b101e7818b9bd6bc226decf5b2068c07467544ec6350675ac23b707ad7e35aac34da81bdf47891f207b999475807d66c5583b48c0e4c2e39e9621ef11c181bed1e39bec7d550590e5cfdc8489df24f876b380e5ca7f71077ac64aaaa0c07be838d75b028bf814b0fd7201e29f46afe63ed86a1c16e602feb8890dbd2539d478ddbc058b6b65c4a783e13e92bde8a1acb6c607da2894fb4146da34ad6c068d02949475d49ceaa8173db93f7a62ba781cfa6df4da8783ae43a311af8d053b292f9d6c5ecf219f8506263415e6a5585d80cdc6686b68a9393fae029039736650715b6659adf92813d11cf420eb13b83909131304157ea0a5e635aec16031f4766b2bae0da97f630b0976217a486a7ec29d50406036396d6a7f7523c72ff05465e8db5455a11e943ea0536a5d36d397fac4f6ac35de0fb826ed10996ba3f672ef09f5390fd96f3bb549e5480b7c0299db89e454d8514c11a33a4a0c2030bd6021f9a6d62e8ba7cac11ce427522a6282a784a165c881f29633ad990915860420eb57ab74e59bc251ee02b30322b29993e6ff2cb467f1c5b81895ff94a65c96e7015b8492f1693f2ef94ad7dacd53981a9c0458d19a9d5f428ddbe30103c053689f81b3c69586e11a5700ae149e9e63e5dfa58231348044781755b9f6027f48fb58442419fb291a3ae51e323c6cf70197769e027f011444ad2693a9488d0c79a1358d1ee39678aa51a4cfdb1a6046e029b3e67d2f97f64a7ff1f6be8e2e3860c0bd89831430152b890420a1752dcf8c0dfa051c385142ea4b86103049c65df011937b040ff81274ce075cced83fef64b4ab80426e6903d39c5f598f244c2c04ae0d5369bd0519627e3e4039c04eec23b25a53c9d6a9ce40a18096c1c91a234e8e49bda8f808fc0c5a495fff4a8a4de6c3602ff3551d336e57cac15818b39c50dd5a6a9aa6d632230be5f21db72baddca78085ca81c4f8ee7a0ef2dcd426092a48ebd764178749383c0c9fcf694d3fd83293d0381b120314a0eb1bde43aff803b99a9b33e7a787ec93e609306a52942ef861082b807871c56af96924593c03c6073e69cdf45a777c0dbd7a61d21441e99433ae07bf2a914474767310fe7802fadd8256450c2011763cab93b49afcaf26ec0a8dc4899eb3eb601dbe2266f83148bae9da100d7809b1c494f5ccda31d746a601ab0a53f5f5a90396b8e6299016f7944a7531d652a34780696016341df0853419a6e961430700c78afa07573734fb20b0c0326c91492deb445b52c5ae01730d9624c1b62945dc0a6ee87fc5d51b53fd8801610b48786586f86c02ce0d49accf145d34a477c055c24eddacaec181db00ad8f23c96ba398853c0e8f9666fbbcacf7c068c025e4c6dc84d1a31988848e013b01692a476caefe8fd5d16814dc0c632515e6a452e01a7d4e2e44e9536e689190517d4db9376cc3b91ca237088821d2121a87f9bd41b47a1e0aa3fa4ef289a4266cd010a4ef5a5471a939a26097dac1454785881c5066ad468009271a36f4c2079c0f109fe2e9e4a22e905b9d9b161e3af70a7408b1689050e4fb027d3671475b95963be13fcf96927137a370307271861559a46891c4978d05721830a625ce0d804a7318a992765d204173c72f6fb6d32c1079bb82983041d555430c10593d49284d03e65e2258e6e4a4d9fe813e0b004fb4163bbdf8b8c216595603d444db34d2129c9f0187bcd410956548e3749a5cf24f8d156cb96d4a265a948829be023457675028e483056d2fba315c3868d621c90e07b9208323584b6c0f108ceb4f6665d05e119381cd1ff7dd2909448d2a861b7008e46707f52840e22246b07e0600417f37bce3ca9145478480182bee20a0528400a2a1a20c58c195dc50466cce82a6ce0123816c1a420f35dddea2b67b60b1c8ae0eef35edc0b762682b1715125539ca4429b10c16e0af69a2ba787e037de873e95446d82c661087ea4e893262253084e3be94a3fc12604df1eafb34e64b99936082e684ca329e6cf968356107c8df84713177fc01108d6f45f3ed139d6696baec001083e47b3d89147c5fceb5981e30ffcc72f799343a7040e3f701e5e6ad3a9cda76ec928f61d588e3eb0a652547945cc942bc6c1076e53e8e658d96298bef75088784c776abd2070e8c1bd5abf4d1ef89c3a53ab25e1014bba934ca76dbc03231a47a53cdf9478e1b003ff6d7a3267c8e94fe875e0a0039b52e37a66f5e4949032074e635caba4b33ac82b39e4c0c7cef26baf501c78139e5270b70a31c68b030e7c48af9de09ae97793377017d5ee72aae041c9987443559e99d132b6a56ecf641b58ff5121c490bbf43b64035f324cf6a6a70f154c8e35706b9d629bd27faa64fc63ad8663416070a881cdf92aabcb3acdba196d98038e34b0e53124fb242dcdfc7eac193430f1427cebcca24e82e763ad98333042bee994273562dcb0e2116a840187194ee93b76c5cbc0bfe5db533926bd1afe079a0c6c6d85985d96fe58b33106ced37e882793be8881c95979f3885e6bb62f0c7c2e91f9f445f285fa8e030c6c9041b726e8e94ac0f1054ec412aa56eb44d29bfa5803415be1056e3f7a2c7fab6a1d04589c1933de460c106071bac0a590aeeb69276ff6c4b8e3029b553d4ffccd42c0b1057ed3373444260de11fd402a7594c82f01159459e765960eb3ad42799bf8fb50da01a33f2041c59b0b67942cf5a936a507eacd1a89187054e2b6e3a15aa3bbbfc2b70faeae6a9f37b432eadc059a9f068daa22a302982c910424832d885830a7cccd184e8a8a496bdad71450c109c1875336a5c41a6c0de4bca666a55c58c51c3cbdff819ef450adc091954c4d22bdfae7fa3ff8a28f09b365aa7f3c9bdb13ed692030abc6d4ca72fff589a1809389ec0a72525be297b8c4955c868b4a23d6023069251458d1b6d1c4ee0d62797b00b7a2fa67facd5f0441f703481cfa07eabb4e2a59e201b8509bca98fb1d3361f6b36d4061c4b607f928cfb3927a6d418b91a702881efbf942c3f2b9698bf8118351072248149ea49fd62ce3ed668c4b021830309dc56c42ae513f3bce46a2ce03802973e6fde4510d9fc72388cc0011c030d1ea360e4c4b2cf3ad9ac2c46146c0cba2747cf6928f8eae4bbe2ba1dfc6440c15f9ae4962388ce144d0df48c0e62038f4f70e92ca524334b41c4148d1a36fa25e0094e348305f92e2954b5da09b62f84597c8b6642d5a2c50d1b3266787082d1a8f9dd4e090d29a76c821fcf96c4d2c70b93219a38f55765a7144af5c804ef25d287987073522ac49b3c5e82f1bcad1f6983b6584ae761094e85ee7debb3cae6299560574c09afd18d1289ab652b11b1324b2fd5ccaa34b2b31e93e07348217c2cfb9f51430292609390314a366d7561a20d1b4fe3860c0b388d3e366470188f4830419f7afaabde65b828fb020f48b07fea2732d5aa23486e061e8f6092a95e4b93a58f1a7838820f2af5d9e6b47f953b1e8de07a4f59bfbb65b2f06004a7dc4463eb6dd2417d1e8be0bf538ce43105611f93af011a3f63467f20a208ee2ac91d352a62ee9cf2b1e634de0a2b3a2d118cd610ea4745a47c35156537ac9071053203782082b59c4e4f9ad41661f7c79a153562d090a1813fa59c4dc0fca971c50d1b4a43c68c2bbe0a7d000662148f43b05b2aa40ffe5d1194c4c3107c2e259475a712011e8548a97429c44b5a2504a7bb27af829b485acfc7cab0a263c4c0076020460b8f41f07572748a4ec1198908824da34d4fba9849764c3fd6345063067a048235e96e9aee44084aae811a0d688007204859c14a93b5c56029533458ecee951c573d0d68a04603aca8f180162d34506386c71fb8346aa4fda5ad2715f958cb0178f881ab741e2dc7cb9c23e77caca51b5770c006f9b8d155641547c68c7c00066214c0a30ffce77ceb493c7eca2ae203f76e222491a2be562bb307b63c47b0945fd9ab4c3d70964943f39d16393a42038f3cb0f9a2c42564d7030f8ccc917972babcc71d588f29be93c2c4f46a3ed6c83b0d182d5a3c0003316a78d881d35f31045171e4510736e7b49b0e6ce74a9f7347eb3107b62c2daec64ef190c3964b46957cd8e88f8cc3d1d3e53442f557b770508f37a8871bd4a30deac106f558837aa8413dd2a01e68508f33a88719d4a30cea4106f518837a88413dc2a01e60508f2fa88717d4a30beac105f5d8827a68413db2a01e59a80716d4e30aea6105f5a8827a50413da6a01e52508f28a80714d4e309eae104f568827a306151ba1fb23f6852ba82518d193314603c96a04a508f24a80712d4e308ea61043ea94512d7491781db1fb1a0eeaf64348b071118a12588ec9f935512cd6308adf767a97e8d7b08e1a424f89a4ffe83c0567d57f9791e08bc84a4763f3a3597b47fc089247c6b63d54511150f1fb01ad953fc709390f4f2e80197e9e31d219d78c06735ad4e19538817e33be0838bc6bcf6a37578e880adce144b1bd2c83fed9161a33f19c123076c56d07d5d9d95397d76040f1cf0ba99f242575abc147203d6549b7a32d34964c8e51c3c6cc0a9ac549547845e07c9c1c1a3068caa527143fb8348173978d080bd4d23ebf3f4aa3d64064c90a817f20851a63f7b83870cb84f26f49b4cf126e9490cb8a0e6291a226f060f18f016e36ecee5bf25d953068f17b05e32c5b1318f0183870b98e42997eca0be29a8fa000cc490e1d10226c5344f536a7addda173c58c0adc95e91f1fef2536b85c70a7813b2926794a04ea8d743056cde9692174133088f14f0b9365734a9f6b9520e203c50c0c98916eea63d8e57fce07102be246550b12d29a195b2838709b8ca6e975ddb2e95e6201d3c4ac06bec8811f5d273274b0d1da3604b77d6e8a7b3b41a355de81005f72df244052d3a3fa743c18aa424a325d9414a8814547844e00e1da060e2b8eb8bd2bcbe0d910c1b7d4e091d9fd00e4f30d963caa01f7f548c7d123a3ac18edbb8585ed0f118f21d681b48810e4ef0a924e8e6ceee562f89f1346454b19be094ddc798ccc26a1b313c806ac4983143c606d634c1a6124f1acd5c2b746442d512a9334488353e6c58d1346c6082914945bb94279658bc3ed6d48ad0710936e4989bdba3b749cbf58715314c2dc1fb27af105409697c44c0031d95e0ecc4ac4727a1eb2b88f8a183128c57596ad0d6b5f755c724d8936631a79ea8c9afcea243127cef5747f6a4d164b644c2e0ab419d8b0591d001094ea7926e19cf74848e4730ae492675dfd7cdba3882cb3569faec64306d7a368215cf1d61257cb3999e5974308213519fec4d338be037dd074ff9a40856d5420e2951457aa8b4d0910856f4b96d5a5649ac1d116c08730f163a0ec186161d43293d0dc149fcb7cffb4e75136385e0f654862729b9bf7d734708ee7cd3ac443ca4909041f0a5a4a5244b25a9a3fbdba861850d19ae19e81004176b637f894e21063a02c1a624dbabaa3de9698b860e40706a4505e163d695a1e30ffca5892491a3e5d18f91828a0648e1a2458bb22d74f881af90b72d3ded5650a53eb026279fd0e03f1ff8082a47d1d228425ecc1eb84ed1927df32f7dd4e8814bcf96643257f2c09af294ad1372e7ce160f5cec20e3c5ccaa783fb903777253985055a6ef4b3b3031a689e78feccb29ac0393ca44248ba774ac52d1016dd12d690e9c959ee53c619be191039b9248a3fecd3ca9c8c781115613e208d5ee240307ce3644678923d3fdf906469748bfcd904e640fb9811399e935f9ef367041e420498ac5b0818995eedf92828ada7d0dfc0731d9a63da420b9a2066e9355e7ce49023ad2c0059d47d68aa7c94b3134702d5a11745b06f7bd3acec09ae7d17a4ac8904742e4d06106ae6fd42461726332cd94810cfcff67d2a9a2ed34c53ac6c0de9a9aac79922725598718d84afa43f452c85797eb08039ff57d33b625952de68081539b3a6a6b87a857d18f358fe15fe3468c1a326ef415317ad1c6156fc58cffd88e2ff049749d4e8717b83ea565292f8e8e2e70398bbedf1c547bf5f25870a0ad8000de023ab8c0aefee9c61f8f0e3ab6c05ec826edd28532090d3ab4c07a9f54cba09448be7f1678935d25949e9d05bff5412708bb6081affcbe579e9e23c45289d071053eed6fd6c7bc2c1e54acc0a50e19ab02b71754a78ce9eaa0026761963284dfe9838e29703fd2d3424e3a45cdb5071d5260d374b9bf755dd21c14056e3cd79d8998f44579a0c056fcb1ce4192e43cea1398a04bf372d4ca48a1c3095c9792c1ba4f3329a1344fe86802a76ad45c82d0595290097bc691e59b1e5c82db21554751fda2d0a1043c9f1495243041b4d784c40ffe232b486083d269528694cdf67447e062e66021cb4e922a5d7718818db811d33649ef107d11d83cff113a377aca982102779b3145c49caf1fb48e2170ab93d4fffd17424908dd5b3f39d411042e28fbce373a0b04f636057def29d33f457ec0e728d1dd524d280dd58d0e1ff0a7aa1732a29ef214d3034627bd7ac99052c654e1019bb52cff5488d368722ce8d801272a4b67a6c6684a4c3ae05a643adf4e579df79203de72aad5ad78e2804f427fd450398d698ddf80173df1e09795f1f2c706ec78c82faa4bb677694dd0510376a47f1a9d9839f9a4d0808d90ad7befb333607c43d2b59e5647d857820e197029cfd46df48ce79f8e01a73198886315b45985dc02a103067c4ecf41b7560c9d3cdc1f74bc809d68db764aa798126272d0e102cedb73b088fb5933e889133a5ac0c4cc31c572fc8eb13e64091d2ce84a2c4d9ad0b102ceeb4cbbbb5d54c0860ade39bc2c4db051091d29e0b64cf956d0983a74a080d3572652810f1bfda29c155d058c8e1370c25248b9a5fba3ab71e83001d16f6dfd7d733e6cf40b05b468d1a2c5878dfe281d25e0b2da5aad8bea8a1a2986bf5f61e3bd068dc302021f36fa858c2ba868c02178149c526af52c8d8dee8f8982d7949ac1303c71248b95965bb20437b3881e2be6a6bc7c39de097e258852ba62082abaff343c0001c309566f3cbeaf68cfadb56d820dfaae35e4f61f3034c1e978c95310fb4da36e191688018c4c70ad15949d8d88092edd8f249d9426a5b479094e94565015fe1ed7d729c0b004a75289d41021960eaa429560ad42f49cbdef1b4f4b09469e451add3be2f15393c843335a0ab1f2cc79624a9142eacb001892e0fd734ca6fe70ff3c4aa0458b162d6c68a0672422c38ac622c6106044c23561a3ae468504374982b2d31272301ec1d8b59b76fb3882cbcff44f9ae24f521bc19544b151ca433453cf083e5a88141944b4084e3d37a8084688ec7722d8bc69574786e0ef258308d662a8cb7475b70bcd21586ddbd8a3272a648a21d84f216ab6921682bd9c21e6f49ea9d2a41082f5c97917a9b383608392a76d520a1104eb7974aad03003c16d98ccc16450c23d6780602d6d7c1fd3140c187fe062e92cea64ee29d1350c3f706241c9a4d64e73d5dd07ded486cc20db3bb5431dc0e003a33c5fc60ecbd7ddd2071ec61ef888a622a7f5a4bc2e450f7cc54b15461ed89455caac4345fffd55705461a33d90378081073e53148f74a92ca5a95ab440028c3b309642cbb47d3ab949ac26c0b0036ba75f62b994deaa7c877f8061d421154d9aaab5ee827e12aa72b00e061d18cb67152db74d8c03c61c3857b3e0633a88a4410f430e4c4cf51b4c4e3e0e7ca70a5113298ffc09820337497ef4382a7a03ab5e1382aad4be2c1e37b09b4a59909af32cc44e1bd8d39b44a4acfebf31860d5cc4df2ebba45903a73f890e7a49433a550d7cc57f1d79314d0357f7afad6b213f5b8a0626795d10b22c67e06470ddd038763147333042a8aef0175dfa352c03abdaf5263785184b27039342aa1a69254b75ca187833d9a5fa458aed7662e077f25608150f0323c4efd533c8608001116db5f4cc9822ff29dd7c42e644118c2f30224b353445d40bdc64ef91f941a40bbc7f9ed0a85183c105ceb3ebd727a9749e178c2d307a3c56125264b4c05dcce9e258d2bbb6616481ebdc41c8508d142728b32804b74ab1d0ceccca4189a68a2198b20130b0c0668a625592734d6e0dc61578c9256c7374658f5a5b8153324ca7a4136ca3a5556047bf5e884a3229c0a00297647f164bdb6a21531853e0638f7eae6beda0eded008614b81ce952c8a1d539074b1530a2c0e5fccb5a1b9ea947580306147837dde0b14f4fe0f47be5a47becd54e4e60ec3f27fd7a4610494de02dc6f74dabaeb10b13d87a494a4cb24b60bb836add3359566e52029b4abb897e483e699292c08ef4e049a9eda05a2624f0b13fe9a7b70c7daa740446c4e839415da9b72b1981fb370d2a63ff45e053acfca13499787d9e086c081331878ffc7dcd0f81ed5b312d3512edb42f0436bfca2d67caa3af7d10d80a91717c3f0e04ce7bccd74f886ceae33f6027a99447072fdda6761f3031beb9e4155d2a35de034e234a50172d5f6eea3ce0638964074c8aa3da4c669f4a4c076cfcd49da379a4fc96e78033d7a0c9d287ec69c7016fc1b45ff0ce4169d10df8a817f38564a3e2e6d880ef4a723f4f7f672c6bc0fe47d0cecf6551431a709f25a245555dec67c089acf14ba5499e6464c04ffeebe8a5a118f059ad37ef650f0cd816d5b71f94ceb14a2fe0cf723f244f8db9f22ee05784246de66901174c67133a84a4cd640e0bd8ccf40de99f4b257956c0f59f9d27fbe0935447055cd2297e795262a7d449c131c8faaf5f51c098a98974fdd14f594ec047dfab57155d57ad093899734a41bb64d6248151822a63acfc9cb251b06dc98304dda4a5ac1605a7deb2994cbf9a4a1e0a2ee7e98edb2e28f8f45d32c49a904f98e191ee37e3092ec97c52725026938e994ef031c4cee97c7207ab0c27d8abcf8ff5216fe46713acef8fbedbfc609ed504efa5237937d5d7b699602b5f53a9916082d577ff941f29997997e05265ce98a7ea46374b7032a45adcbf12bcc6206f627bce5257a1049f93a7bc49fb493069349374894b8215cb5cbda746c60f4582d76b911d420612bc065361be9f92a5f7116c3675ca44691dc1d989b58f321bc149b175adf696116cb7e65eeb05ef8fed22f891d5bfc97b45f0715272d3d556fae944b09e39ee6d4610c18569dfd44eea21d89844cbb44dc711510dc178329173da4e0bc1ff9836cfb6a3fd9408c1e5dc31b44584a8fa0f820d9d74fa14f25b275f10ece914954c674d42080582092a5e9d9e00c1b749901e638708d1f903a3b4a58929b7e5b4fb819fa469c927574750f681cfb553163c46f8c075c9fbaedcf7c088677faadea90726491c9da3f668da4be681f58f15f2a94fda339678e0a4e8c5645acb3b7065292b85c52a2582ecc0879c826c8fa754077e2479a4495b3e6a3a30597204b3bc21e5cbcc81dd682185d00e4a2372603446b74e428c03eb7ffa467f1ee1c05ebc8cbd11f406eefb82caed3937f0395d7226a13da713b9363076397e323d955524c78674881e3b8beed6c0a5204c839a9cf46fead4c0598a5a4451575b4a69e04b465291cf3d848ed0c0b9a97c7a1f5a3d4467e06a5268a81fd9a763ccc0e79cb3931a1b19644c19d8904924cb718d0cdc570cae2a6a93e5c4c6c0e99c9c752a1a31f0ea7aa3348dc912a530f041d458daf879ee20303031fb4357b28fc9f285f2a398e590e2053f5947bac0a729b7e09a319832aff04012e005174ef14ba86708e149bce286150170c38b2d5c994c34a54a0b8be960be1a938532845c42a464fe66718978a644b0b08814d2fe09c9317285ee765b4b259367412ba4b4348660b997bf2aa082b0ecf142d2392ae0498ace2622522ce7a650e6184bc890a49ab04e0a9f4aa2efb328ecdf95552c9e1c0a44f1b0352137d44fb0947b7c8f139a9473e948922bd904f258b89ef877105e55da78c18492a92acd3c9aad5902a6be9d4348baec6ef04209be7625a526b87bec4512b0d41953c87b2162655448e18228004af002095a8d5dfad078e2c511ccdc39fb428ce0897f2e8f64e2451148ae2946d25e9549f9881744587f424eedf92ee60a122aa4706114f16208bb96be48ab8cc115c26a3a998fa97b770f0bf1220824f9a192fa9c2c450e10ce9a26684c5121850b0388173f38a5aa5655bed41e5ef8c03a6db913547678d183d32da6240f4dd93d963b0671dd98342a3ae8f08207bc45eeb5a483ec8c7fef800d2909cbd62d16bada0bbcd001634ae91853123af4567b9103c6347b70092e32aa5f38d0442d795a8c559a2ab46d92e60a317472edfc8b1bb0a63b56ce51211bb0d10e30366047595675b2bc06ecc53179a34457a90d0df8f224f374da0dc78b19f0bd9bce839e8c8dfe06941bbc90017bfd9592a86f6bc09851a3460462c0e954973d67d0df8d180c58f37a5bf5cbc07801ef924b044b1a43049d333878e1023eb4a48e7153dabc0d5bc058dcb0aa90445e8e1e10dce83018bc6001a3a4a6170b15422da657c0bde4d8d16dddeca3278b172ae03d6db29463997a7f3605ecc58ab7257973aafe5ea080f3bb36adfbda9f1ba4c18b137091bbfa42e4d3dde17961025e821e19399f3682172560eddaf232b4a70a2cfe8affb8c135a8681b8e028ce3a8441005726134140805025124462140365d023314000000102095c6029158124551aa4b1f1480035a241e3e4228161e1e2214140a45e350281806020381a06014048342a15050208ca79110ed030539247289b43e761e1986a374d89bbe22c2655072986eed2b5c88bf25bf9771a9ae9d1924f64b365d39597800048471063664a1864943a43246d1b880a3366b2ae6e6a736d2a50956680b41d543113034d8dc82884681c7d2923d169d62fd157dda511cd1b2ae491a8e706c5ff6180f37c4cf7e1899ac5b761890e4114240193c1b66dc2af0bd32ba2ccee8b810610218568913dbf823d134622a92b47521a131beedf7228d9efea21e345e3a508192e52e0d8399848d602f6b648ee5a349cb8c8bda4a5994e15df05c3158fc7060d47f4d9136b4569e3a41e67659e834535d580f504a7f06e83e821afc0f9164a9b5686a153e0390e471db7002f0bfebdaa3d6eb50b041383ea8a01014c6fdc1d633a689fa4fc2abcc2807f64d9af9ec7c5da8fa07665f9db98fa0a2aaf2a950fbd9bf233a99d819e99ef748499702d4e15b82baafbe91584007e4b56a30828d0f8edbc62e9e5182b1a22bab2c99a7b14b8f5894a020ba807d68a24e26e29c27f3d1f01c3c88478184cc0031f6d96ee7793480b4874b6be0c8001274248affde3d0b271c45c80dd89d0c2aa1e7a6c0215f9afd34e319bc5121afcc9f37f6ab009f64bfb500814369761c56f1e5e498d451830180be21358753f6f084926a5304fa02babe3e5f4756a83fe06cafc56b78b57339b349f899aea942a67ea2458c35db420ee2609e7ccec52bba417114d6784ebd9c1bce746d1adf838f4e97a2532da36065ea525855e1e7e5626c7b8a6fa8956563bbf768f68e079b18073b2a264de28ec2635f5b88a321daf9a0068777249b61a10d17bf7b9cd10d350fdf4bbc21bd5aacf93bfcdaefec9e815e832d553cfda0731db5b2ac01eb7d09432c7d22efbecd4ff104236df7c50ea98dc071484228095ff577cd09d6d39c2b6248625bcef5d2554e280d8752acf36777d38c154291ed030e3ecda1e130ac486e6720e29e4c7b69c502ef09021fdb696a779dada205a216c82987b397acc2591ff1a9579179843dc2a4b565083a0b6978113592a5029cf33db2fa345798cf8e9cb0672341f569f9b0887b9b8b1d21e72b8bc370635f1d9946faa416f113590bd5853bb8bbee9bf7d10677c391ae528874f3b24c3a630d5e020269e429ca4e9871b0a1f53347cc05ccac4c810770ec1b3e653d71d623504be7809df2cf007177c630154d858cb1bb79d6690745e3d0a54ef535bf8679d78bedf0a392c3b689a5ada03b776bbe750fedd2cdec76e2ad96d9be00716307694ca2924b1c49cb7b57039a6509a4580bb95cbbe350581c36944dd31acb0893ac7afbe547266c756e51df28d44ad828d9cf7f40184f92d111f38fba649b0faf3ede615752959170736921f0d34d79abbf012113d38267a486b24b7251c521c4ba4365a52468273774c47f30f7f727930265f7f30888f75b8443b28398cfe55da4f5a8301e3a41206a7b1cd0f30a885cc7d42e76d7c45fc271a7b5fe34701991a9b54f16961d9992cfc79ca890f69f2422d41172e30314df0ea3e95a3085ee3ce021359d329774dc7df3bbcc4f85dd88014bc1f27afc9aa371b265772ff9689b5cfa68f934080d97de223f7138869fb2952899c1702bdffdee8819f8690e7424138b03c08a44eda3fe838641949850b59c46541e9ffa63e105a6f761e4fd64070029b31c172a473710ea55717fa36b1102d969ca8111ba78f7cb317df2b71e0f1e8207c31d5120fbb20f65b2d12db9921eb5b3becb701ea019df70cc7a6008ae78df5bc65387698bfa13507498b496ca06e1df443b6ca074123d874641b9b096c2e298e31182e75f58d5e30e0fbacb916acd2bdd5758f2fe5cbeea6a4a7381d12a7fcdcf08d1daa332be336a94efc24e0ceb756284a83c8a438fc7ea1aa05b9fa193a67da73c1c0b50de341bda1fec1b5dac3a5050fb4bdf573d591c7ffef404733cdd407f403040c3e1f7d38df683a329aa50d47044daacf2fb9fe7e0c04de2acc392297eb9d3c61e6c1a8332dff9b51f021a897fc3d84de9e1438fcb93c65454805bc85aa2496093104865633ae749463f688f0ddc3c889e4869a65b370dc56679e2c9271d2c3bee1bcb608c6335c58941e94184ac231af6044771c7cdde2254ac601bf6e2ad60d02fd73ec894b3df6c727ac48d27674f877ddd5d5fcf385bc10e51d7da8be224c7660120b0904332ad44183416d12294b4167e3589ee3b13848068a4156a541a1ceaa9b1ffba3438c62f16d44049d24bcdac1521beacc04093d0617f61c344037d3172fcfe4220a4f7ac891073e5670e0284846a9632c526c90f722f00d2e82b9ffd84399fd52e5b9b3a57732842a04b2da109cc9227fafb0b1636986ecb1a3d0ba2b5e6d84c33a3aa515a2f74a1050dfe5320a41bd69c2d7506c2d2e4fa3c0141027257b2d63f2022560034ecd935a57dbccec727228a620571c7085ebf94ef5a0b0ad20ab0ac66b9608396a35f4566824383f6262d01d5b7eb7b48795d0626db8df3b386c0f0911aae69371c4cd767e8b84948888c2b20c9cc1641a0d6f4b2743b52e169340b24195169234450273ea5686d12814a196e165bfc7b5e77445ddde7fbbc9203f9dc5f25a6aa9b8ce6d5a6e85ba0a3b0ab505818d316e6484551506139627e255796285da553f35365a59189526fd96902867440902c531814986f3d2bfad79519778dae38d2207dd261f0d94ca039305809a72302b1031bba4451d392ae7aecd106949ef38d2017259e5abba674822cd84663375d00230392a95035f52c02d05b3f8df602248d47560e5134b0b4d650a35311fd04267d043be20131b8fd6a6b79420d68418797c3211d984592d56057f3680394bb7b1acd4b557a69c81d534afca985156e49ec53d69400de5340bcd0ee92769b41e21d44f92ad31fe765745623e9391f6e83095085a17197174cb1468aa1a01f8577ad3b1db12d1abfd479429fbc5036ddd0f3ee9d19cd0f6ac81c0032571bb9d00bc17a8de4ec1923364c205501347f0363a05b9aa03c6c490d8ed4854323dae40753f654fb8751811b4e1be1a50e0b237c587799d2715c287abbc37f7421bb5e04780c2c6e18e0d4a1eb2ac0f3f6332d293cd9e7a035e10e103bd0a2b69f37a0ffcbc13e2b5d213a4c09ee24a6f088cda4e4bd2da9cf9fabe737805a3f573d34a4ce9d6ea10a0a122476c5b2736d2bd5d84b812befb60e8a49d040e5abf5f8eaeea0a77b07c3c19f2025e64fc9f6f698a5a44b7d52620671ab5e9c0d9152b3da69d07a3dfebcdee89e9ae95a426971f45503cc4bb9f15d17dc5066460c45f8fe19568bb035a03b292e3925852952fb04b8d01219eb0dad294ebc5ad720760e4e54358c3e86e3ef051362f672aaec465108bbbbb7af446f51b8d4ee87dceef479e62b3114470ea2241dcd7caaa2aa0c29e17064c4d178cd55ec0c3585a533fe85d410f69994efd41a16861599cc5fac53fe75c3df528d25b46b0b9bf115eeee63e3f27478cae8c718b6f09a2c98589900245f387f024c58472e9a4be920ae1d3500cff6357154cf73a93c8b02a07a408d0062dd845fca02a9f7f620e836d8d447aaa0c45367f67d4b1c73db6dd50d1495f05519debe85c6359ab5d57d6b02304eeca66fb343e01b76141dd5a7f15598d5ff9c87e560e8027476e53a995f6ae1318e37dbb272618423f6ceed1708ff3b98c8989af9209a9a884182d48ba8ca5721c840ad0295541dbd6809864c9f6a759f5a6b28573ca334311b94f04cc2fc767331a7c4636eff5e663f59069b158cb491c5cce1f0e506f44d6da0b638eb4ac6665ed1e7de6ba6e8dde152897ea8e60438083f2396abb7cb2758a796bc7c80d1f3d8c3b380243359dd92c0b479368accbabe977c70faac4b7ba587293b748461321d3d87fa9e97b341ffcbdd30381b40216cd25f1c83914e2a38ce926008d9dcb10475155442126ae950c324592a582a07261914df6f442dec4ba72a3b9bc56f81245344891d52927dc7c320b39161bce048a2f88b162e4501380c2ec136add45837139e9bf60d3663afcd1391a0fa3dad9c0428143744a5208fd5685e395c3fffd69491dd8ff1a8efa687e779bdc0bb2ef96b2de3295b71f75ff524c84e9b70004e59357a3fe07b0d98a1628e6b6bc4ca1e5ec855315fe53b616e7df8488a0d5bab6b7586664eaa29629839f03b1e5da37877d7f4cbea8cdec92272f7780d17ea13e9a45ae57781ce04e3549491d5e74c5689881f8051318570452e601a4d131a44285d75c93bd2e6d81f0a07f4793659c115051cf97692a4f1aeea35c04c8cb76fae29b7b66a0c3be5a245a9b46508530f9b5105a1f0499899ffab25cbea84bd8fb9f8a8ca2ce86ee71e0c655ea0766fdb3c66ec26a4acdc67a52fc8f2ad2f82f35e73c7f9ee64064200839a0212f4cc2684a6d0e05a0c26b027a46ef4815d14708af3dbc70c935b0d1c799311cc94f47ba395569fd3066215cac296968d9df1c40b2e4ed724bc0e7a08fc62c6d7214e08d914dd01665ed08fd7690185b27fd2e5af30b579a0f8cf9f47ca8e58ce22fcfd84e3eccce1e857db4a7b062ebf42cbe84454443a59d13d21d4524b31e1f7f6787e825e219a5caa846561890cd7288cfc1f268d2113b32797209c9b1fd578a8d322b75a7ae9b043c8f338bb1fd6507f4344b93e0bbfe148a9a1c7046552b714d026366d10e39d54f787b5dd93ee42fdfc30a7723064332ec49e29a941dd08c1c118257fadeaa60f28c914c9216d5fa14346d1742d9347a839adde94b44f5b7dd3c03f643b31b049e3fba0ba9ad81913e94c1d49088ae21001cda54b5600f0b9816c3bd283f235088425f498cff422561d838456ea95342a76aa835728c22b9d4887c93eb6601872c87e5149cf337860542da301dc2c60ca989e540070924d87bcdc986cb539a1314f811d52216a895153c2a9d88c18fea5b5e22ecd83ef32ca9b617091663b18257c7a4728e316a4720945ad76459e04f3885f8dcef3f40568c214c5b7e1839a479c0892cf830d4ef1d80f453e43fde5a9d0662165a1da0d0449f67955312c1813838a18faa31e99be156e59cd6d269b42b0510ef530141a707dd027d9d59dfeef10ce4dbdb7c2321b977cef74243b22fed4138035295bfcd00bb540c5a3fe4328988ac95bb1f316cf179348d0ffd45a845b77d5b64fc57c4b9b76811feb4943d3021346df28946bf4ea53c13e06bd19b096928317d009c8da34b4ec00fd2e4c285ed6ffbd0fd18afaaa43cc95e4e4d15cc4630812adc70e8012a5929e902d0d48acac60457438b4f92b12658725f5265c46535e1d528256c57d245a46c8781fc3af9418379b28a428ab741fcba02d4a0ce648fcf1649ef2cb9b7a411e82f0665c2ff5c776505b08aacfaa9b2c47604b4a144004d8304e0c4060a3aec688e7072bcd276a544ab0708345471b8b294804f4df881e1979df2879741e3d103468e1c319f197678bc6c1ca61627d6d8403394cdaa853ca99814dc0f8c64c320fb54c30d4d8fdcb6c17c716f01ba5b7ccc3cdd3df7d06da2839aa1fa0e41bedb0a52d40bcae2901889ca9a210a85c4c95f1cf298e0f2ca508ea0c9a077525896e75c58a09b66f6ee34884438bc9841b2584e6fb36b62a545835c40cd0c15488ed202eb74e07150a3e30614102de9ad34de3c7cc936f1d4ae266c6f0a69fd8daa1ab3052a08b5ad94500c9881828c7a2e35061d1b059d6f53e8e4cba6ef755bfa416804745208d5b5894795c82b02b8eb62f9a48bb43ad07db833d765eab20a7af6a3af28117c99c967972845620f04c89feef28085ad18cbd43beec6b720469bf9d12aa02104d25748d5ce83ae0338207538d26677f6aebd0046f563671326671b9b18801785d6353e07a11cdc55b724626ec0b6aef64d163eab5ef4035414408402f8090aadf551cf0e11d2208a33c90790738b7433db4776d681417fc459216d17655acf5559288b21518ec79a1aee94813b2d62e1f30d10a4101d11122e0780f84d2b0c4b8d526c99354128fb3234fcf42b54fcea884bf8d24c69736bbc20523bde04a72b65a85481469b5d26c8dd459906f0f5b5b40c15c006a7b2d5274c86ce7f5181a5af98e184336c1def774f3fa0d248bdf5578e31a149686f0156ab7bad01330c4bd3aea5476365144bb8a11e9b7c9b6480045a31dc759599d36d84b0848e60026ed77fca3bba203e26f7d20332d12bf3949708e64cb72108eee635dda391a0c2e518f82de1d8fd70b69a5a65cf796e7ca3af949918f00a6e7d24293600891a9985b893ad446aabf100b9c60c3e4d765c020927ef5904395ea05e4fafe054b67f8e397b7a7683d2240a33c36aa799b771f0577c91e43243731058d4d96f2246afdd3184df8e6ae9d6981317fc89f954f95507b0631303810e0c6de752c2732a4e166b73bd56919b67ac3ce4625a0e8c9e9929cbfa31e5cd5e4429cafad6c8508dc00b97db9da045e3cef6e8be1af53434d9bb17b25c1d1cb80fea8cfdac944cbb664c6a7322a2dedd9de74e0db0457cef392f306f51cf4d5a444a5e86b262b0a9e8d8a7784c4524c103edf575ff219a8a6dfed551b236624d7f9bc4fdc2568440c82121378ac4a7ce3d8452c216635de54d889ea3ecbb0ef3ec1c966aba329eb565296a6a7e2e2c3429104036e7b99a29301f10647640b1e90202a5c1e846b4182591b209b9f486e69a75b323fac9afe739b1b39bfa912f592a637707e5795f692a636707e2795f0524636647e2835eba7e637187add18ed0f3636c34932ec9b07bad3760f980b3d1c8620f12db47b8470ee07c7bf4a25114974c6611ed5d927b12303855bc407e238b0490e2a957ff5ae252bd0d75c710e42109677c86858101dd686924ada0819a65db5de63c28af8b310c63dd0e805620a5d0452c8e357b4eda6a5a560d50e092a1c02dda0b2ebbc4a8eb46b0452b399d07564a23324701ea14e8c1cebe12c11d65e63627830d23d56fec1dfdd45b1bc6a2d9d3c4e5e4585a631aaafb233bce48c9e4c277605878e69a6f22a5dd87b151368ba6cb914173d429c4b622c8703ea4231b44cf8cc12a35519054e8621daee1bd0f68c4dff179d4b8b26c51544b6fc9ab802fe46a8f06421a1e2a680d834dfe247c033b23562a5219f74e333de4a8886ba2c3268d2c10d3ed3e46b2a4cce30c600f30b2ac9a7dc2a7b04ffcdb0a3317aae187942caad1ea373a251491f494d9397fbe75d81325b0fccec13f934ab63d57487d05d1a132dfeaac3a9df53916597e5868403f73b4b08d64bcb3f47f59c8ab65af564d72ac9993ee8ed1aa94ae3dbade26c1e151c6639655dd8a6484cc14205be82fff2bb89da7067c0c91f565e056b9ddb7c8d994d51ec35a937ad901f44e5df9d398d853f45e91e9d5d8d8d5e2426cf87b4ca25d214b59968da25c690567ff74d15a50692f8a8a60c71950fb789c7145888bec96e1849ebe7f20f8d745c643d738c8d9810189528a97805d9a428892ac88172c5466d0a993c8bfe21d2150b8b16762e2825fe727c3e4338cc4d5c92d84522d1f26a4c99891383e78d183347358d296a92552489ebacd4b23f55f29ed7a868aea67b0dc671980311c7806525cba15a6f58acc9c463b5a1a5d25a2f36804d83b28ee2830999313c1e962e348d75aa9cd0285820e4f28a2f3f4c1903e8c30f76c64561e12555a813217ac33d6ee64f333dcd030c6259cef7390381f4458d17f39d0d767641c633f9936257e6f6d2ca3707a5317074a29c6fde3d523ed8eede86d224dbc39cbda4057857033c527f3b54fd5d61c32289d6f73a8c399b8b6b183af167ee3991ab05274e7f998ff876ddf2b1afac4136a747c271b454ce07183811da87f0f13aa1f100db3adb71888e9a02a954337d113c792f3388d600ec9760a31586d0c9ad4d6e3da657faa687ee69a9068e45d2b52dc53b43e726804c34f0d61954f48e6e4f8ac78d559fbde6b170113e21eda5d4129ab00a105c66b4b729af618b2c7c99d554d86daf2fb39593fea64b4b31395647f6f972e81600a1f0deea61670cde4b98b479abad5a34c1d566b1e9b1ec90e24ca796a64da050b934e844d49403fe2a2d90b60831a7a7ce92877d55a8ef6628880dd4b254de7aaf961bf582939d264d963e95a6897a918caee1c744015ba93ff47e489790989211c8da878a5e47882bdfa750f10cea0977b6073468befbf2350c9193520b3e88c3568dd58937745e87a7e9728d6991ab86185d16c99095fb4186d901c17d5ebf417239e86f5e68f931e5d2c644daa12744ce781b80c1d7c9bd03f0af4b64427e0ec11cfdc003833f2cb0796ab746cb81c0eac96b103af513d0dd66e1b4d0401a56ae6ff8555c325edef8cc49d2939e6b564fdb95d601bd068d42a7f20d73deb5713e0c251c6ab96bd6db797a2b63305f6ddecbfbce7c0c4482c9545a47d1c27abb55fb52a286ccddfa9b4ea373814854b86c8089281cc8a8d8134b822239f9e22bca16907a54e5a992a9eead4a5ba23b84443082bf4b70e7b9784349151f273a26a6fcb82385373d12099412ee70eee97c1921944a04972491a4d6372c2480d23514a9abe50807cc336b712f7985495408106a60150399ad0714ebafd8571b79c1e6d8f908a398f12b59066c88eaed1890967bf564fb324d6767fe2aba7993913a9b78d846c8f9aa0e9a3b6fcee8f170b05e9fd574b939f37c3c5459a6d54dc29e468f0f42fd84717db163e646c76ff8479c5ccba4baffe06ea6b2b61af8a4a8a3e699375e286b121a3bf34dd648acfc71b62040448d765d17b644967a489f339c215a1867eade90e234a56df34a9a2cc9a57c29ab6ac02f40e6c961a21d16f91c4c7b4df9d08e4c78c6699bb2dc37cced5d4600cccea58e5ce11546e6a0d45509701449190b3dc1854ff3f42c766c0e13b73343ad53c57537c56e6bc7c3f86f6baacd23062143d077172d55da3ece9d1e0e61e8205e238e87e1ba3e6417f5699801658a4c30ecc52efcefcf23cb31d6c11d7a542e56ef0c9b5f634986dc99429c831e43a6998f1a5421c2b133a154e1f963318689da601f698a851a5c7e8e6c3ba24a3f9873f3c65781699ec6bc66ac8a8293e604b301710f21ce91f59fc3fdd7f628c208fe50b0fa95b83354c3119ebc47f647c68643775c62c26e645932188ff8c56564786000a7ff868f5e4ad8edb3aeff1b6f2660b4680dc47b7a2e5d5d87e4f1a2c8ff85f3d16a367bef964ed9265e7bc90e20e3c98ab082e2a7a8e5218228c3fd2fae03defafba0f35cf3663ca68c2a087a8e2c3c5e01248d04f14200c1e1aff2c422fa5e1e58ac808d41162df5494962e6f9eb0a291a427f6d7c71141e95f52b17de0b96f29aa9042845077e839ad616dc08321cd57826885507c5ce946ce4aba2c409d97a01d5810d231e996374ed0b3843c4f962ccf27c952a25e52503c452672b82e78d5db8a74ac7d349ea01987e08a686d1c145a070c7e58d2fcf09a66db41335e3fab501a3dd5537fcfa72776988cc2cb508bce4a837567eb99d12a85e46ae056494081d17ed4d0d01ef0b069476f75188239a3676828893fccb8ae23400c0b39b97024e1d89ed3ad18359399b8a4f62f00f650e92c249a76b60f302e0295bb56471805271f23bc430339b225426798adb97c8ff044fa6550b7b7f6a2050747ad6865bd9d43d5827b9beda01e701b1909c41ad7505490bb87afe68c38381b0093f13016f1f1f4e408f3d0b1feeb17d711ab0b908d1aeb3c0c1346af078903ef9b110e24137fb44bc2853596088700a51afd338a410c871abf635cb2f2c6191aa108dfc61425bfa0e7906f481cb1ee00693e1b4ed004f607a3e5f5206548f2ae99903ba9e5aaa5d489127cf72c283447a6429e2f1d915b0002fe94ba52be8408d132acc065d2aba95cbefe0eaa508c68f9034c88883d4f2c6d6f46dffa099c0decd93e1e3ea8b659bd2fa20d2376784c3378d51d508c49eabfb4c44a70e9ca6b9ac00a3b8da9d0435d28409a56b6e43d436f9931ded9ee69ff92f2dfb01f8cd03d506fcc921073f6d5550079eada9985bce1c40917d6fa3ca41880cd00e4c8743507daca2cd6e8a85cae841bbd95206cc0710c6cee229606672fd016a5d08c6ffb398e5383d05ac04d3502a55e694bda97d41c067b002c6a192df60663dc5eb089a22df85818e244f6558b2d6fabfa8634e8d4a49d8614fe472acb59b5faf9e014f9f37f38e5192fdc183eb4b996712c741b09df6cdb407615bd425311b1407741305bd6f46337b848e34ae053e408e8acdd84767dafb289580e9f483c48b0d202e7885129c4e3c32759f8ece313c1df3d27122e4903fa155211e2520fece6004d3d8e3199b2c4a2d81b01362277dc5cc6c7611855525b6f5073d0bd4ea414354efe64e10ef704df28018eea91887c03151c65c8d8e3f0f8d71611ddb324141ee5cb76e200803f7bdbd797571dd4571b4b0076f2b0f78f34585cda9526bb2c618a7434f9e3f9b29e1dfc8c44a286e8d6eae40c41b522a5d512951ecf9718359647df136bba881f60d5231ac62048790bcebe28f98cff5d68bbfadc3b71e0ecc96843be5aa220b6287ffe747b71faf9bad0f41de861c18334d73215d2e8a9f9a5e73bce9d257b99155a5b5adcf02cba1edb80dee9a0e25a8b131e4b3738b175ee052092fb6856985b9de1a5c89f0919b68e68dcc355019e33d99934dd2483e92001d86ff1cba03aeb35eb63bbbd0e1ead2bad9e8565fbdcb1fb4aff6e4ac5f684814a0574af53553f0f5975b626975120c24ff6dd7e0cd653df756ef366f32e1c61c8ded1aa70c3c75afbf308883814bbf73faccd894cd77f96fe41b91cef19ed424a0646c07b59723a9131ba0919a46d365b5507f35f096eefe465a2d6765d28a935d0d1ef0324a865b89e4d5b0c6a47fbae8ac864d5154e49a56865b79b5ea67d5a195662b6b5697ac3095ab0181cceca81b2befad58ad2a59556825d94aa2d59b2a04abcc5a29d457833daa5916a3d5c6ad86a21cd6f60e0354dd5945d38516bbe918e3c38b611eae56d8270857db7442047c5eb066f8206520a79ee53c9a04740f12c36cc80f95f0f123d48d4825e4354350b34c2adf6c6f63b1195491b3324535042a1e5542f1ac1261cc5105b66c0f1880536da72a20055ff97b5daaefa89c55e53bac60afca4c254b458a2a88547e4e252cae4c58dbab0ab48a9d6750aa6b500536f9132908a5a3e346a5e452097bf3bf3c8056d547b2ab2db5417588ca6754f1b47aa56a262adf975359a4924825816aae5de59114a8f06e5ab513506dac183fac3e6930e3546f53b9ab0a91556550050299873cc25a4dea54ff7e31f53458aa1ca8685215b3ea9f0337150c2eaa5f542e57b51d2b61b7711ec132aac006b421ccdf5448b04a8834392f6e21254095aa02477f4fc33654ed8b4af838850f9cba4ad8b8c54567ea914755aaf6ebfae28d3e981b7d4c95858a7aaa45aa4854d153b9a632b25540308f6e737aa1324945505581708840d81241a92053d5c155c26711ef6d19f369121e61d6b269134de524757401695fa08c093d043a07c726c0cb9715d22ba2f31e58b944da67d34dc16a7b63b60f1d1fa185bb4f78d568817a015df2068262da9b48cec76c963ec42e3c32da09771021f86455d59824496ed0a2fae6238816a5ecdd0eeb833114244834891c8cb43a4a2869ac9728e8acc968aa5b91d2e8b9c59dbcba39d79367e9756e2a70ee6f5204145610587d2c43cba834af67a67c64be1d3d8f1c5d919839b4491e5fadda99d78454818086e1fc1b592561adee206985bc19e534c02dcbb22c1ae1b73aa03a8e905a14c0626be2d9db4f2cf7a8d4374b5883b46f2520b683838ba7f34db10edde12205576e2eeb48ff4c65ecfa5520adba0f92c65ed6666cded2cbeb0c7aaa7aa3b036cf1f542a818551bd64d4117600270e87ba29beae2ac2237fe4dda560bbe0280f012d05ba4051c6603cf77e8b6ee9063a0d0550f5b06f6c1978e8ed5cb3b5b87e96f0caaa446da796d2e54934b7e718002eed0a082402a5b1d854ee1f7a2f9f8609c6e80705dc15e11530222eb56f585aa8ab645de1c74bebc21f909aadfa0d8d183a7ba237f15cb7232c0ecdb245d8b9048e30dfd5862f17cb5fde6e1e99dba4a8d9c914db63b9268c103295657018369309529d2e818f2cc6dd9c36865c9e9d2e44652d024bf7675c3352fa4857c6495386ef50178f40524a6e2878d5e49111a0f5c7da6215851178437366994e43c490e81f42452a12c71aee40dc506e5833a8f298d7bf732af7e048a78d720b2ea3ad6bec8f1446f05bb2a7591c9091d6ce4044212eed6851fbb50ae599df98be21ee8005e2ef56f9349e07e648f3ce4124b5f3546a4d1431821819833dcb18bf188083b25760e1508a395768b2e73c1be080974e904644c7a921a2728d5e0920e058aa3b6b7e4da6074c134ba080c9c2db25a636e4537781cae153aaa66cddff0378eef1eea596820b62d7960695457e1b42bbff4dfb9532d5ce2226924e8a1d5c36e5a45e606e5534f6cb3926fc46beeb2dfbb23e254d164ad26acd94196430fd3745e634597892ed2c36b2dff24a6f67843b431968bc65900b3d97212b0f8bb90bb3c34e24e8f52425f371804b2711027f5e31cec4e52e3a51da8569c4fcc73abc50925b02b8d2afb9d958f850bedcc2574e4e34ce8eb13b423c5e3c9524cbf7201d3156f681f05257cb0a33600bc00c6340eda2380af0ff0bc40cdc9fab012a3fb42d4d3d93afa2e81c4ed1a96e25ca285403a31458198ade1e664ab442d96e7d6844755d505871d6e69fbeb253894237a06d492b823340fedc288f4d2b5280759be7cda8e1281aaa68853d9d92e12754438e2eb13ee0d93138b5a7b23215e05582ebfa56ec594b7e6554447a249423748914e4e203a95a9fa9be4c23aca6b0d5be553aea476f190fb53b4f93393d7116b33c10fd222a979483ac15272b42d33057dd5a65142304f94a2d4b8374ed02e26f2bc70baa9cc7e5ec3568649b49eb2864045aea6dd74cfad673518902fc0f334a1072902ca759c3f75d87b2a2052e824a844236a3260a31cd76724917fa5377d44dd8b8d8c9f08baf1c1f2d7f14ebe387abc1b7caf5ad9453f565df988b96eae7b28628de713f65c0e4a6c5c160ba6b7fdc462633061c2ec61423098739d6d0b4e9e56cfd025e5245770d3870b266390333333333333333333333331bb9d384ac362d939412c5a9b03a7aa91c09c2a494524a299592aca3c6c584c645e16342e3620e043b0dd80d0a0de7d8c9d079dfa4d741a13471845de8776a117ba1075e3ca1a44a49f52edb8ffaea75e085130a6a445c0fd3e8e722820387b1f1a209856cf6115ba4d6e7fcafb0f11f39965f30a164d92645ca21f81b5a0a78b184529e06d1e63e8d1d2e01a4b1c373e0087618be5082da2141dc2b23d7b746ceec3d9273a8799b34b668ec7009b060416387e7b017492844c91d96a7849a987b24149292e971a75182e47a052f8e50361daf9bf272c424a1aa0abc30421e2924978da97b879a56e49ebca534e47e6fc5078e0658f18123edc78e1c2f8a50506bf722b3517cf2890845cddf16a71e6492ecbd1842f1e467dda914ad49622f8450f4bbd0219f8f658c9a2014423c3791bbd469261d104aea3f55d37eec335f3f286e4c3ac7ca64f6f9c33eb0238aaadcabb92431bbfd319d4d6c9ad1bde84141ade7cae6081af97b1e784a88b0fedf7750148d1e636310153a671d9434dfee45de20948bf72207c98b16db2c4938285eef491031465fdca06899e1ee72b741715546f99b4d109aaf173528b9e7134ae79cd2a0ec13846c6cf0b899e78b1994464a7a6550924d264467535627b4173128095553ca27d9e96bf00a2f60901e9321fae205e5244cbee4d4a70bfaf4b46db5ad0976356e32255cc8319dfd450b4ae245d68cf6608b172c287704eb983797e65ef96205a5da4b91ee6a22ef6950f0420585cdf9ef94525acf3dc32e5251481a630ca3c52b529e50518a5111d5e4498b0cc95314e27536ed1cbfc20a34800b53142db63abddf7b6fae2a45414cee24f94f6b72aa677c3c077ec78d1a56a42846cf236344120e2b6680a0065a4da300a68b5114fe3bc4d14fb6e69ea73d6006065c88a2979b9872ea9a9a59b141c5c85a2914c5091b226eb64aabd08c0b5094da2ae46c09399b3b74f189e26cce0adf4d7973cf0e1d9e2897e42836fbc94e94454b8cf91b6b4cdbbc7603023a3eae58808edf310205b40b4e14c48bba483d53b6498c406f02a1aae51bf40f179ac04cad456dc2a95add5a87123a8692af1f32f94c140b73818992865e95798ece78105ca2347799e476962c51ce6fb95b21b4336bbc1205116fe24abef7b5652851fa54fe9f747a8949844ca2b4634aaeefed24152749286ba1db237e3012a52e113db87d08bfba5d40a214e9cde53aacdce4fd11e5dbd378d3fdcd37bb234a9b11f3f629cde592c546147fc6539ef655293933a2f4aea77c5306f9204416518e21498dd6f41551cc22f34ff889c9c9b629b8484439b5e68f11c458a62711518c9fd4c8ec4611e7f221ca9a6b3a7eb75976d21982095fb5f166b5b11e2485289c12a73d83a890d98e0c42144c9cdcb352ef204a9d548359c4b2102e0aa2b0a193674f1d4294f8b8084431e4cd9cf3ee78929cbc2db80044a9cd365fbf8bc43d2173f187a288f768a6b42669bafba13c32f5efc869fb604a96afcc76156b93dc5521a95cd53ece840f254f62d9a6e38edec808e0620f495ce8a110b2476badd38cacb18b3c14b7fa468a7eea020fc593fa9f574c9a29b1b8b84321990eaa3fda9f58373c075f3dc0851d38bdab192374528792249d3f9bd8131d0a22c1fdedb4ec620e25dd49dcc23227ffa09443b172fe2347d0329b938b3894b63b6898bc1d38144d77ac9eb0b29143fc06bd4d6b72b6248fb0ad923ce4cd99ad8c2737145389e7d231a9e6994c1b4aa9a25454769c02176c289cbc5df569f27ce068c0055caca19c359da9eb3c2ac3e8d37f48400dc51439972711095fa1711a4a1ec777846aca051aca49b5c695a7523da9da198a317cac75576f864238b1bee6faeb1a73194a161f49d98e76cb9891e1c86573669ab2695f113cb789d3bb524b5d8ca12c6257cc3e6b176228e56d8ee1217c7b02176128d5d668cc299a7bc4b42ec0508ad9705e3ace89a433175f280659d623233d175e28c7fafe7412a45d28c778685c28264911ef73d021e94cb65052f327e621272eb45096245133e448b3502a4936494e14adfec005164a769549eeca9f32935ca1a03985c9abe99062b742b93a89f4d841a90ac510a36b9fe820748e1115b0311997cdaa0d2be125cb547bffc64ca128f7f1a2730867ab970b29944334af73046ee35116c045148a2aeaa73d848a937fd3d8ea07c1c7150bc803b88042f1a3d58fb8c63ca11ca475bc499a20c2c94e2889a9eb988989aee49a50389126bfba944c28d8a4b5eb24632cedd1c5124a42a2b99c907dd6260304174a2887a83d19449ecd6a8f105c24a1382256a7099ef34b0e22a1941ae653e74a1b91ba23709265c44dd24b18d3f371276c84c284fd3c596a7cd46e8a509a98256aa9e81849224249925edf1ed10da1d4498c4270444e4ade5c5b104a77bf9b49e5436efe00a118c9bef3e80ce757221cb8f881a15dfb3b373e251ce9c207a592db639275de234e5cf4a01845668e96113933532e785052936d374dfc2e765052a5bbcded330ce028b8d041b9b727fc77a5fa59e8092e72500ab7c8de1fde6452f7c0050e0a3fbaa3e6f15c73ce21b8b841398528fd2af36db0da5b679cbd8a6abc77cce6fc7cd2434c590d0a6a4c26752236f3868406a5fa12ed1841ed62068598633f78d870a7d3ee4206059949a7c97c8d0d1c3270b888c17966797b9244f2062e6050d81b253c6bd0a77cb41b2e5e50da5939a546b3df00b4810b172c1a71a265cc7fb9684141e91c63f6899db3e18205a5cd10eee2b143c77e2b7e0704ccc50a4ab721a7b78ce9359a9c04172a28ca7f699cd92a15a54e1a25c78ce46799ae8275d00215a58f7977c34e93cc69748ad27990f1430e5b1b656740b63045418eea4eba9749c4524b51886eb99f6a152956b1af8c2c5b9ad56591e2acb3dedce7eeac4751f44fd2db4a6d5194dd6e3659ed1a8a42ca917256aaff4a2f5094429e86c9ec269e91fd44c9edc76cc74f7a4c7de0d8a1e3c6151f3966e0d831438707fc73a041a085274a37fa652d62e8341b6ad1ec6db805278a6713835d6dbb89f2e811f264248c461146a085264a267e3f45c869748efb165a6402ab5391162fe91955d595691f3ab605264af73aa2843ea1aa4d7c89b223c6a56b7ca66b1e21e391e364df12a58871adcdc5674cc32d2a5170cd1e61f2ebe7ea88eff08f169448c4d343b2d98b56a987d7bf3279a61693289e8e704a7bbe119b9d0bb4904421e9b86a5967aace4f9128890efd2065c207ab1c1295d7bda8d5b5aae74e3ac9e06134c7d4e21185604a6ca9da92234a4a4b6ab809494db7a911c5905262d231ff8c285d97c8f9c8ca9fa05f444185f8b2789313527f459443e9a48ff913510c41be9ac7c874951f11654fff9e76ef84e8141da278326ea6dbd823c643862857ceeba43899d1445388a24fc8aa2263a82821274441b9e8f748e2c63af4411434f867498a24a4592d08db7b843810c5fe3aefb3515d9932204aebaa9a5ba951fbe33f14b499845119abdaa9f5433949b6ce6ddf4d32ae7d284548e266b4d253e6ca87c2965ff7474deea124ef44d2204a37e674eaa13472367979a492399f8742cc27665d24e86c2be2c173fb19394df10ec5b8bd52f3a75ef7433b1493679bc8df9ab3f35787b269c9393a94ab3dc8901d7b3a876e0e25b7ba4ed93143909e9243a9aeb62de58b433966564e566ea611293814c26b47d589b29edb1b0a4949b4b9eeaf851b8a41a9fd39516a43f152f5c3e83ef99fc386d268d131cd89ce1bcd1aca1ebb57e4848d77590dec98f60f2deda7a124738cb4961e922ad9a3a1eca7468f38393a43d97b3d84fd69fd7c2333942c83f02a1d45652828cb91752e2721f764285f851619347a049dc750f8741f64e8f188a120c27799e4241386f2a639d7142230946409b97fa174474ecd178a766b212a3ea48668bc50d21a6da57398b792992e9444a6ebaa470eed7673a16cd226fe857435a5f616caa25fe25a288858dc6e0c2939649c85b27779cca276e33469b1508e5b9baf49ca57286e3425ebce635583d00a85d1a7a74fa70a056daaa4c68999a5712a144ee88d7026358b74a7500e9eaab7f96ee327510a85977cf621c4cca3c728145744f29ca33b286826ab3fe36d9e505291cfc4bd56dd6f7342317ad0496da7f678d09a503ea9beed114397b68a09e5d851dd9223b584c2abe890b943504a8e9450ea18fda36b987042435a24a160e2cefb5a622c137a249437eba61242e585418b23946d4487d5b7c7b7ee5a18a11044d794cc274d9ecc16452878a587d778f956318950f6539173b41019429eda75f375352129491bb34d241d8550cc9a3e76ff294df19e201462c80e23ae4e20947cc3c7ce93643f28c99b374de7d17d2c6483163e286df02e15afad9d9e1e14630e7eae91ee163c28e93432871f31ebaf6a8b1d94a486c8df852884163a286b10f3d8cda73788be450e4a32871b3dcaac163828670df9a3cff324a851c5470450d0e206a5952b9d1636286bafc69e9e9c497a5e91c30a1c0b68518372e45e1fd36b6726fec7dfa8e1c18285185ad0c0bef00dea6c3183163228e708db9f7b3e3d6dcc8285085ac4a06c6f09d72e175663b19d74463f6e9cb2050c4a9e838c25f9268995bbc50b4a9dc7458a86097561bb604db154ab32eff4b8d94e1be5b5fe162d284ed0a6dc64d09e316558509ee0f9626ffaa7b45d4149479430e21ebb4cc5162a28978cb183e9b4412015a5533d49e9d60a02a828cc856786081a42e0142559ab279b5335af6d02015394f5d37abbffff3e994a519674427ce60fa7fe6c28a4519ec4afda3594b294fe9049fc9be6130c351484c6f3dca67ca4ec06230d05ed13f47a1a0f061a4a22789887f0a117c03843a9632ab1113e94a75d30cc50ea24234795c7ccdd2e6094a120624cf87c4a73cfe7000770d82043b13c450eb7214d63cb868d1a1eb0d2008c3114c307a139448bc6df4c8718cae964834c99bc1a941986f29e9ea7094a26c76c5f0006188af77be73d9e574ed35f2847dab31055dbaef929f3021bf45f26d79d246330ba906dd64d3249eb99b6191e185c286f48c2dc77af7a2e94c30a088c40013a74b804ce08cc0c1d3a3c070b164880b18582eefde9dd8768b40c0c2d149326fd9dbe27fb24115616ca6a322328ef122162f71f58282851724acb475b5728e938e1426c2825c27d5628e589249526c7ef4c89c6d60d0ed4d061306054a160a373474770bba990c4e83b32adb65328848d6fafc9291a5b33ca039a96e3bc0e3c04430aa53bdde1f3bbb94d512845d2d934e4b0a595aa0c185028ccb8e4125aac2794c637e4b8914ca2e5849285cefd19273e3dabf1b1039b500c56ca7564f80d1fc61d36aed0f132aab061a3860b162c603001dda811821b570000c612b8af2eb113bbaed141c80cfa741a9b00184a287e4ea53d7a96977b118d2d2b3409c5c9aa79743d95bece7f24fcc0b1c31b0905efbb0d1a23b2738eefd0f102c6114a17ca6794085b572372056018a11c9356b93d9327a25584d269f6204b5cd44184527ac9a0533e696b080515ee32bbe929574f731842286c6b6e4e9fcd5d9e9b61c30f0e1b1d84b2a7870d273ba2b1c612800184428c113fe8ce997a8fd1d8425d08c0f84159e6fe47e9863e28e820dce48cfe694c93c6165bcd10018e10ece8811a444431cdbf3a0d1dcc83a2bfad86e977502ccd994338699a0e4a2ddeb5c9938cf160a2b1458ac67ac0c841f97b4372902f260e8a417548d8342f8dad1d376e5048fe9e33e4e4e565c515376c50bcad8f1c77d2e75c4234b644f03466ecb851e32347d7a098e531eb373f8dadad09c0a04131a6acf4d19e3183653a665090d9e4ccc437c9a038a6319d10a63f7be6d0d8226601183128697f6431dd69000c181443529511ed7f0b182f284e8c9dc93c7eaec0704151752cdbf264d22253182d28c6b8e7dbb172369ba2b1c51480c1824292a196baa68e008c1594738f144fed22e3979ac6563a00860a0a41479492935dfa9dcdd8a103078d19373e70d498914347c2c0c08c0778a4a21c53679b0e32a828e72dd5a2b4798a62c64493f120f33045e1aa66ece7e24c290f21e0518ac2e6d630a725e69821a4208777c99da5451419efabe9843c4651d2e22172226bac095881e3a3014ef01045c93e92774c668d9466e0d871a306d61536bc021068400370ecb801010b4559f48312dbfd8322bb8f5c5b31abaaae11764b8ed07ca238b2d4c6521142687d3c51f0d2fd92ef2e8f4e142de29aca08e3bf1ac2099248c85a62a755e1a6a6b34d8736e926380d171d7a62d8be9a28c4bcab6b91795966ca4425df12bbc43dcd4b354588fd8f793f29d1b70726ca1b3c881064e227b5d2e312057927a2f2df26e9b8918187258a65222232b7dc64a4ac1245cdf3d2e71ae274e8418982eba4d218a94994735975f6f41849144e46e44f1df3150d901100f68844e1c225c6750f0dfd184814b2e8e41eaf498637cd234a7db3b71936cb7dd03bc2f02a97a821e9b4b46c354bacc8b91a511e11939708fd223c35bb020f4614d259c4e431134682b88842129aa931a8fe6baa15514ef61d437db878683011c5917ba2eb26a92afb70ead0c13876e418c1c7d1017820a2a04255c79211162c6670ead0717b8862d84e27f6436f8882eccde9d3df9906b916a2ec934bb4cb374214addb4c495317a6b3ec3108cc2b5bb44462c452ed083aa9fdf38794a51744f1f3ef940a8de3a8805ae1118852a92791e94326041e8028c754a2fdbdd39a028f3f9464c8514ac8fbcca83481871fca62d23442ce1d64c7a43e94e2f364bf92397c28eb64df12af9f9396bd87a27f49509631ab8792e714322378189531cc4349062bcb24573ed64a333abd0c241e78285f79bfe789e50458b0f0b8433942904b5dff98bdb476286bd0eb959d651dca195f82b56f8e0ee5bb5691a67f83d238cfa190e4877653bfe5509059d2e5f984e350f012eb4f2ee75e1902877229d51e31883bd3b171e0f080c71bca9e7c730eea9146ec93237d5480058bf401020f371453790cdf198f08fe012c5820113c0d162c3cda5090ffa51ea6b456949ed95012c9395e95c6d1ef1a4aea347d09a193c48f52b6f050432199d7befcda9f6dea9186920afdf590ac071a8a6adaa3bd2fdba882050b1d3b70d8d0e1028f33944bb7f499a7c9c30c652bf54ea1836ef7507994818d8961b39e7c7616f0208322625b9515926abbb6f675835f98122267663dc650bc8d33d17b3662406ecbcb22b96d5a960c5253d3969e1c86b25a759ffa46f2d03145f0004359f5947eec289d387a7ca1a05ffabf2c7dec460989f5c063cd7154460e226fba5010a79a5e947c7f131d170ada254bc8a0347b62087a6ca1f4db7d2952ccf34d6e3582f4cf4cf0d042d993ac4f902574d69fb2508e3b924b43e26f148d050be4386c8cc073ec08d23f63a1ac71ef448ae8b942e9736d5306a9a9cc3c56289fd03ceae73b3abe5685e26ce733253b4985a2e6f87c4ad8c818f23885a247de4c893aeac3490a250fb66ffd9bf4b86ea250f0cffd3166ea68a22f14aa3519ed9a286f5bae9252b4adccbe2829eb138ab93236395f3e387294167838a198679b7a4f7f75bde3d18442d6bd8e7a4228a164ed030f2694464e04f5d11ea381c7120a42e9310de2ed1c7828a1981eb1543ce39184624dacedf4c831da7c2414d3a64c9bf9c722d7c4e308c5c95afa57fd7438dd8d505019c47e0eb9e7c42214ce646df2ee1c4162ec4184f2c4a04b6765f28fa61e4328a90d8db6551a336b5808c54c4a48081e41285ff68bc870d737317a00a1a474d6aa7f9e1b20a3024ff0f84141c81f1532ff7db87d6fd4701b1218c187a31b38ce57e1e18362189572ca37c582858e4e82470f4aba5da4863291e8a7af37be37f0e04139ad4c3f8f66d159b9c70e4adaf3a7ee0e9736dad641c1eb3c35d4a595663807e5c9a793ce739e83bce78183f2846f97117974835268a619f5693584ef2af0b041e9b4ba8c70d7f61c6e8f1a94773d6210da7c44ccf2a04149df3a64d2087f2f298f19943b99e7647a634273ed218392fe1c6d6fc3a4732d06a41989a535279eaa99359d166150de8aa4b44f753c5e70c5bd5cb94cb6956056dfc95389c85fe2451e2e28fa884febbab91c39fc46f0f120c07174d440334690438799470b0afadcb4233033466023071e063c5850f2fbf50e3d5fb6611f039aadde86b902076a2c181e2b28464c32947646cd740e2bce4540060b1636fc86870a4a2286f4539323c08b5494c5e4268a986b7cecd0614377dca841010ed450c0eeb851e30a0ed4308b8ac28458d5a31af729ca5da5633e426fc49cdc71a3c6151f48d49d9576e7489a5294934c5b27d3be6fa5c8460df3821465d9cd316c925396ed5a318a52e855917f2a05d0072f44511cd3fa1ee48cd031c7f3072f42510e9b4a490ead5d32444151923969958d705aaaba4f946a4d434f6a50fba279a2bc6a7b22af369d289fb5974cdd30278aaf76d649e6603261db444925c9366de36aa26cb24904c9a61b36a83251cb6d684db2ca921cdbe5115d420c260aa934e6d8b1233c84179728e56d34113c9d6ec434075b51c0052f2c51d4dd93b6928414a844296b77849090479dfcd0d85a43a500250af23d9cf2cebde11e61c142082f2651d02912424c217f104385007a11d46800cb78218982e586bb9127fd47bf4824c2bc74f84d11248a21b1267ee9d41bb4f98862decf914f82eb887252f5b20e12b35c725e34a228d1274c6a919990531da4ee0523ca7e5d152a2abe5e748b28ce4af09c4f6ef94211e5d291bd6f916c4ba3893044d8218a85bd3044f125fdb888b8bd28c4bf252972d010244441d5ddac04cf7ca2fb41902295bd7c48c872aba5623a57e7b53d5782287ba4cd41f8681f386e70a00629b28128fdc9ced2f2902a409483c79b9d7c1539f49f2c5efca1341f1659ecdf73f2188d2d113c8d8f177e28a73595b6baae8e0fcfd12ffa50be2e0b093b490ffce7b8baf1820fe5744dff082942638b03300107f8cbf853c346152c5820ff0f1a2ff650b0ffcbb78ea49a2792c38a1a2c58e0a8c182c50d1c3a3a30430fa5d3dcd01f65f47f2af3508813838cab61bee2c6ebb87d8187529c4c2a31ed5c6610a2177728ccc4fa1332e7a061a1b2833222b31d217769c48c7d4283788b3343f0a20e25f149261b8bbca043e9e4b23f68921e94d2793187823eed1ff39d74011b78218772869a4e7be2d974ba696ce1a861f6220e35e3051c2adf50d4904ad5ce985844c90b37944310725cb363da500ed5c8be6043d1f63b89d78a8d31aad51a8c1093c8d5392d027f23026a28e91cd63ce9a464e4bd370de5553151a164d23ce2ff1b14788186c256788c629de6ef326728f5afc912b3c9176628c609c9bb53ce6528e769a5a9abba3a154fe005190a9f74ac9dd0c7a300344046000cc7c0889c2147de550ce598ef74645b86cb596df8a97103c70d3f1f8e801761286ecabc4962b6d7cef40b301452fd9795cba988d1bcf8424953a6c9f211437390178a41cd85d8e9fa068ebed100162cba50bc49262954e903c78cdbfa7886f1820b458f61fd4a34de424178069dc304177559bfd042b94d46cba0a31a49c7151f3374d46003bcc842498e1c253473959e019f63041300c10b2c14e3458cce0ccf505a3a06bcb842a97ccb4bc8b508df207f6105b4490eb5fa74aa4239e2c659ee6e35a850526237ea4c9cdc9f778d2994937cf6b55e2785e2ab89ff8909f7ff79144a17845b432dddcbdcc3ec247d4d8ac40042c1640adbd051d605428c1f942e4be958939c6b267ec5077e865ff181e281f33416407c50eccaf51c443c9c7b4a478c1e943263c4126295d13c28756e514ddac34374bc76505299933cc99327e5270d0b310cbefafebf21ecfe428c1c14366d4e359f301966732304386e78e006057050d07943e8eb0ea34b9920b801812cc4b84141625cd1eb9e7524b8376a182b701c2b8d618392e60c9a42721c1d84c80c316a5074ddfe0bf79c525467878e06c80880c5a041a96f426cf99c183328683f499f7d946450704bef98e4e661fec7a07caef6a66e26d7ba0606a83c0992182f28e8bdfafc6f62b8a0a483f90631d29418a5c7684131260bbdf52fb133dd5788c182624ab8f73c95276f3c2b287ce8fc316d8e9f22d5315450d8520ffad5329a874402a9289e2af7246776b75d2201541492c79f7d97d3bc11738a726e7f129ffc5fedc4a62868b5fe4e88debf252c45693c698b9cd6ff9fac0b488014e559b736992c3dd2a94751b8932951e376e3f62b8a924c5bf223370984229b902da24d90ad2a3bcbf4b622c37383945102a02888a453f4326e7fc87fa274253e3f42c813c5c99d76f4678f38994e1454ca87dbd4d4f1754e74bbe2b9f36813e5a4fa2b72cf7c7659134591ae79cac43c8399288491b94586f4cb8962e275cd399728866a9f6c689628e80eed993fab44b14c754eab19edcfa24431d3462d53d5244a4a29991b619bfd248972367dff9ca3a478498a44b1636ca78b900489529567cebd3031fa8490ed58e2c48e280955123b9cdefcd637a2244e68cf97412f014614d2768618c783688e79092ca2515d53993e8a287f8e793c82d60de244947e63089ae9c64375441492303d2ba21fa2f8eea9647cd4a81d1ba2906373fcb7b010c520a2bd6fbf369708518e7173a467db576e8328d5ab2411a4c78f1d41145494ec6c0cf94014dd3fb8fc0e88828898b14f929a52a53f94ca4fe624dfbe178d1f4aeabd3df7cee938f5a1986254db8afc1c633e1435c7f8e0a3fe3be57b287ab5af6e26f550ccc14ab4bd89f2507637219f2789a493427828a99176df12df3b94e4d664f3ce7cac08b24371f36de8cf4edc985487b29865de24f3a6574f87a2759854feb15e1a348782b8911b4a75e45010398888e1e6bd54260e854f1b31a50e876a739a27f17943514463bf061d7c3eec86e2dba4ee16f5ba95db50d0ce963d1e93af563614548695d44fd7508e2c9e6358cd0f16aaa1a025fcbfe89786f297c618d1d1f4c70d0d25fb4fed3491738643bc9b983cc80ce5585bf54164a9dc94a190fb77a48ecc0f33396428a4d0d718844e598fa1306af5c4ab2486b2558dca97c2501023ea435cfb1c620f8662ece821f18390a1fa2f14d773d64e4f768b8e17ca7fbbd983dc12e264ba50d0a5a6f46d8821680d178aab41a48613e15df7160a49fe9c07c95eb7af16ca693aa94ce29a2c944adbe3e7ded4f9d360a138de9a27df35998fe6a0d76d2368118d154a1f55933e117bae93aa504ce2ed4d5e92642b51a1349eff394ed214caa1474633448d94bc14cae11d35c9a0ae3f88a2501e1d434bb4cf2ff340c1a46712cd44fd8492eb7d848d9a797a7642d97ad2c78f51d3e56c4239e68da6459fd68825138a571a449d894b28781899ac6336d6049550d2f6ff9f5eab5e739e8482560dd9c7faa4bee74828af9ee853f5a61f3d3f4241ab9dbc3019a1a4e6712a69438acf8a50d019c944d6ba4e2222142578ced6c738ca1e4221a86e17599e5974e54228a524214a65f6a4fd2014465ac713bb13150242f174dea036893839fd415183993e28bdd6a737fdf6a0b0a935fbea890dfef3a0103ea7898c51277d7e0785f3fb481923a3bed74131c733e8dce03187a01c14b286e429d98383525b87a0a3a6de93f60d0a5e32af468f51365e1b143e7b0c656245d6646b50aed49b9c79b34b8706e5505a7e3dc4e877720665ddd816bf9b46655206e5743241f98b3128894eded933a5c41f06054d6a3de53f2f288e98ce572e6917145285ddce26b5a01ce14e42d03e0bcafe134b5b8324b082a2e7922172af66c548022a28abfe69524a99e5e9a4a23823c2a9b3d0cc98414559d4e7cfebcefcb29fa274123cb2966e8ad297ee8697d399362f45293fe7fce3a5176793a218f2e56f50117a3f3b8a52a4f914915a16456123c790acd2459f90435192e9a4c778d26b5d6450dc5eca229f0a3f51540939641e79a23432d3257a8e3b51fa90b2fb19c4896209dd982a63d2f9b24d14f632c4d92832a84813c5184389a094e7ca4b3813656fcf2283a6642f0963a218ca4e9dc9d68ad0254a429f8b7fca92ae254b14449f6708b2d5ae4a9538feee9428fb67ef92a24b27f993289ace6dc9299244d955d39fad281205b1c164b6dd352811248a62a363a70665a5d94794478910aed17544e9f4dee5c4fc22f3da88924e9d5b4614cb42fb0775ed220aca26c5cbe7de04254594df6e6288484a443977381909fe41b60811e5fc88295c632504d121cae51b6c53a42691740c51ecf210f2999ec8ec2944312719dd7b13a2948610a56cad9e91e1200aaa3de498ba94113a411483a8a61108443967f9772a19eff7d20800a26c9abb649459ef551a813f94cf54c8bd3dcfb45346c00fc51cda6a2afc3e944de7cc99371f8ab9b14f356a92f1dd4331a8c8f727c2e4d0bd1e0af14a7cb23a13b7e7a1a0babdd52971e7427828c74cf33126d45ee8dca11c35acb48e4ca5f5b794554a3c89d7a1f4359e62eefa37870ec5283ffa42680ec59c9e35a7b5e5501cb5734acc3814a27f7a9f24cb7f6c3814829a6cb59384d489bea15cbd39864ed10d05a9f25b4a6de893cc997545c586a2e724743cc7d750f88ea4a349dfb490a41aca9a758366d360795e1dcb2c1acaa54c6aca0f9a424c6728c986181ba799a19c948cd93b0995a1d81d39769c93937c3214cbde4f7b64c9eb396328281db157d429ffea88a1ac9a19343d4d365318cab721a35463c050deb23c7da35722c67ca1545a93eefcc60b25cf79bdacde744e3976a1a8a7ccdbc73dc810462e944a6e8e6da110f7544feca99b78a2168aa5d37ee964112e1766a17c322126659d33a385582865929f523b8b4cc2c22b9436cbcb9934f90c12b442793c9afc7c59dda35485c27dee3b33a116caa742e1e3f56d187f0ae59278117b74e99a202914733889417f96acb747a1bc41e6f8b6dc0f698742a9ecec634e6e8a9c7e4241879c258d6aacc6ac130ae221cc28732d4f6b138a6f72a4279509050fbf71d46bfea0cc25944792f097a033628f4a28e9c6ccb1db2db49f84b28bc790502e1dfabe74ec8e508ef7a3c488f931599d118a1a497d8e93ba2214e368f4f44169a83011a1942344cd3c8c96f743285caee6dfe485500ef23b21d6468e3f0885bc2169f5fc6924778090d668e87692ffa038badfe774d87c50de17e94996dc83526fcdc8a0bcec3be641415688cdf05d2e66eea02831e7849439a8ac510725ddd6253f6a7ca2673928cb5dcef76aee9112c341c963921faf7426d9dca01c63e733dc64834250111ebb917452a51a145cc43674a741493f684a1aed39d633b83d883199dacba0b0b7316ecea21814c3bd4ca3f84732110c8a716d267d5cfb94e11714b36fbcc6a5aaafec82f22973d3db1d4ff4da82a2c82af131a52c287768cf1d32e9d17e05a5c931e8ee4b4bf5444005c51126e622cb5414e39856d5fcf18b242a4a2e9a3f6b4a34ed788a425c9322a925f96fce1485d70f730f22459cab4a519cb02beadb736c11295214236a96659c46519837fda7232979fb45515691db93bb130aab365566c90d288a49a5bd9c6a3e51ba1232318729a59ef1442184b7f613111ea4de89b257acc8983ccb3fcd8942146dbf22f4777a7913c58fa9f153522499644d947b6452225e46393513250d21e4d390936653315112dfa194e479f9945ec224feb14421bd5cd6a64f22319528a83119ce654a946fb2a6f79993d8f77ded438b92288bdc249164f306d3238c48942f646439139e5346a906302051101b3926ec7c679af988c2e720e2c7382646e28e28464913c5d425301a71c7e7909a733279036430823355531233be4e1a5bf6b123078c45140c4510ccb2423bacc445853e91bf32849cc34844e94e6dfe48251888289ad8493a6fec611ca22493b64be6e0a96dfe0e6018a2786aa497104ac323280b51ccb19336089bfdc92121b0b1afb6b8360d9122b377c2e454a541686577f531afed9142534dd2ec2691333322c01044d944122a2b4c042310c5f5500bcda4f1be3b0c40d4251b62dfa9aada5f42d47c187f28849864be18516a532475103f94cdc33ae907959aab221c374450c3630530fa50cadf247be2da888db8c500061f0a577ff2d5c7af620f85e0c984d4fa4c1f46777a2888184f7c7ae8d8737a3203187928095f91784267cdef3d0c3c94f5f3e4a03529db58298c3b14ce45a7cb0c6297d187618762f20961e6f3840130ea5098b43913e45cd66e1a061d4a162ac478889d1b35dc8aff98e133763c073e7024bbb29e43792e6bdb652c2630e450d2654a7e7d7d8447108e841187d278874e30f5c98443b9f49dfa3851c43574b00d30de50fe1c46bd778c05021910c002c17dd498914307c27043317e89291dc330da502a9d5ce7de6a28a86669c8209731e8340d67acff92b11a0dc508b1546ed4bee3e34170e3a650c5194a169bbae39f213e6ca86628690c3ae9abed65282851d7bb96b71b412643f1e48498097b1f25cf6328f9e6910dda3fe86e62f832cee724c46652a8220c2591f6edd222a4532218ca26d2d4558589fa85929811c264accd3949bd50baee36dd105a1a5b3acaa25045178a49ad8aed8924f144a6b1855a63460eff08c10cbb1a5c2809f9121f5fb4dcdfb50594e5a4590bc549b761164ad91bb39e6c52b2b68385a26cc60831b5126a9b2b94c5fe94b83b0fa36a6285e2e786d1ebb9ab4221e86032e6c90c2a15ca9e2187d91c32d942479d42415ad787754891f311550a6551f30bdb35994482a8512828bd92e479a5a850286ae89d8fc8ed092571719b4b56a84e28bd4f8eb4ab5966be1d410e1c5534a124e2bd097117e16444e04c28bc5c6c1ebdd6a7eab662092525ebffe3a7d658262aa170f72ad1f48518f558128ad993d8cfb55d3a728884728951bf0c321fa16c625e84c8a3e378998ce064fd3e95a553ffe17f63865daaa208a511da7af66db2a344d83ca5c771d84833ecd2108a3d77326f8ed9d3ce355e08a5dfef2444536e9c8350124999179f373ec32e01a1242b31c61ff90f8a727d5d5262b62e0dd2d8b281ea83a2483fa14c7f72b4b307a5fc303236660d0f0a5ff731a4fa2c6a153b284f8e571d6d458d7a8c5a850e8a75b3e75a6ee5af25d41a55e4a02054db9eacb0705048b26475075d7183e227976ca564a855d8a0ec92eb4468f3743ad72a6a500aaf191b95e7e9a9a3564183b2f9c6ad8c99784f3e6a153328a886263149ac778c440625d35432dc830e6a153128c73135b211ad93c718b50a1814ef33fce5947cabfaa855bca0d4eda67ff72232830eb50a1794754686264fb5a01c266fe227a1a1b16563078e0f5442152c68ed2e6c26a9f283868e2a5650ee2447dfe3aaea73f6914ba84205a5ea2422088fa0a26368e8484561626e52932745c7aa44808a920ed5a36c43f6151fc70cbb1aa728c5e6757548328df42437453129ab9aac399e08b1538a72d2483e6e924ccba6adf80f5294359efed2949fac74c5288ae9efaa3d9f59d977405003cdb0ab218ad2c7f2a0b49bd6b59f435132ff18bc353d88b80f14658b1cab3d6c3e518c35a351d3a4f598d1c98123c70c3b4f14b268cd21ffa91d9d285ca90c39b22895a7da3833ec3851d8dd6c1262a4ac5b6f13651199257f2d5478fa68a224d29b28f1f3dee1ba4c104470cded57d1d8c244e14c27af1126aa3edb2512e255ea5937b344c15e3de340254ae2a183769b26d7cb06258a21670f91510e4ca268b2218942d617d5b14fd848d18944497a4694b0294c906054692ce5158f2869f8243aa2e423bda21127edb94a461456528774f9411a5b572ca224737c8b3c2a45fd23ce279998119488d27d1c519daf5f2759a88828477f4f916a321b93ec10059526b2c88e9efe6488924c0e3182141db510c589774a5d7d05214ad772a747e3c0208a1d4d48b5affcd55410e5bc2941bdc46f2310a50cb93921d6e50020ca9ea69485e8a47747c2813f943babe666e80a3f943d0799ba6f47e737f98e3e20ad446ef0a12c269e4a7ef6504837eadecb7c1a5b24f8c0cfb0aba187a27b08b7251b937886f350784ffa3348cbe8a83123fd071e0a3a64f5689cacf3e45e716346fa8f3b14f4894d67ab994b8d24d9a1a43249b699f4a63a14f54e28119212a23a87a87428a9b1f79f192da14f86c6d60ebb1a7328c69c21a9e3288782af6a12bf125633c57128083172a3396f686cd9c1a1dca2a5847e509941866f405d8b3a65f9b9a1287a62e888a79ada511a5bda86823c6926947810097936944b668973a3e7ec2b4d6b288cb01d913927253514b3e41bd9313f34c8136a1a4a75a5e3c758e2a2c6b3ab818692eaa8d72feb19cabe3b79cebb3b98ca766628a676920d523465282691cdf89041321474584c36932ed771348642d2dde313f3bb8da76228089d6a3dbdca34b6ae0843693e8a498fb5c05090e0776156e2b7bbe20b852ddb14ef5f7d538fc6968e19ec85b269fe8923f327712a4e5d289bc6ac9263beb91f99c485827947bed1f5a16ea1e8c1e4eb53b63fb7466367d8d5d042419a48960d2af4ad5d1d59287b9478f229aeeed4a54c9081854250225e5b89aa6ccd765ca1b4db397eb45ccd94691d5628e7dc9874bda4d4527e15ca134f7ecd674d3221459f63043bd80932a8504c6292378698467dcd144a3224919ab657a51afe40522879bc0e23396608c95a828c28946c4fd4e7499ef40385421a4d667bed36aa49352bc87842419a1249a8980c1331ea84825649b669b573e9e9d0d8aa31a39f20a3098510742e797a66425144e5bc2487f5a0571a5b1f8604194bf0b55f54820c2514ce5636e6b01bf43ef46192505af98ea55b5e5eff304828291d8237fe08851c43b0d81f191ec6fe8f4b820c2314a3787f2e6df3078d1d4528a6071dd1369d9417211a5b34ce0e3f442806a5fc83cc7eec6822c81842f184648f8d1742c9363e43632bd5e021c80842e9238a57cce83c99211a5b3970e0b0418c20030865f3cf93255d5e4790f183829df0204a535fa8af98b1a3868e1a2088c08e1a3a6a5480050b1d2c58e8f878e4ff81e3c68c0f2b74780858b060c142860fca59b37a09f3b89f5501e7c6150da8b26a808c1e14cd52abad4e63fb1e0009c820b88006c80840f241060f30f9c8266aea808c1d14ce4db435e9e8fe1665e8e00cabb9ebb4d9d5cbbdaf0a193928ac7e10e6496e28c8c04149477cccf2a7be1b6e43028f70c0e0937183b2e7cf10c5e7337fa464d8601909aa9e292f5a55aa567e40460dcab1548e76d778627d248306a58f0dfaf3e58954256f1d3970cc20326670ac79468c37d10813c4ecff9343860c4aaabf3da33d298b20911183a247356bd1891464c0a064f52246ddfdbfd2a6b135c386dba940c60b4a9abc46336e161174108dad1c3764b8a0e4f124669eefbeccf765b4a0dc41e814e96387bbd275b80d52e741d01d90c18282befa1b1d27fb068db1f315a0828c1594f3b709edbc9bc6d67910e890a18292c7f82772f4d4f8203862a4a224ca459d36d3ff999bfb88818af24f4c9135c696c766649da26c26f3eb94e81082c734b6100e182c58e09f1a3674981a37d414c59f3fb178b555b192c696087098191e386ec3f4dbd861aed0a13030304300314a517853758f53d90c1d355a8f14dd79926f1a6328c628f49af396e8951992226b7fdfe89c54277f7789a26819797c3d94ce5d3714e532a13b9d87ea57a53140519a8d1fa647c682458c4ff87d424753da7498c8b027eeb5bc0e429a9c748c4e902585869c6c84c4e04449439b10cfb21bb3e918066ca2a8398d70793dc95e3a9ab845b3ab22c78b6766c97dda5c6363fa74673351fa93257367beeb9a08268ab5e9ad4cfac610f2ff8318972868989e6836d739295ba29449a73ed99f54a290e446cf9d5a42f7343128519e9dec29ffab4edd3b89b2cccebdff9e8e26d292a8cb4ce535edcb55c362a365abe96a8e473f12c5a8293e13e016c4804469ecb7dbb306d79cdc188f28a71cb351bb9de94289c6d6026238a29067df256cfccaf934a218a3b31d947f4eba26234ae7daeef1e35d92f62c820932b722b3916b4642f4509fae12f37c54155110974d2252e4bc25ed4c44fe219c690ffe224460d9ea166156b279b9a5a59e968c99553a3e271dc2b1137fe76f0c439023bcdc965d452e46214a134628b7cecaf19412a220bbb5b33979e88d4f634b2b4310631045b1d39f5cdd537f835388218892ce1923a44cf0f66fab1023102425ce2d368bb0460e2f29c400441d428695c778fa4321660c71d3c47e2884b095be5a2275bab10fc5dc50e12371db3cc962f0a1f8396bcc41a8bf87d2a777b45273133779f4506ad997dbdb983c94831251a389c978288fafe528f9d166cabd43396dfcbb796b31ec508e31c939fa6ad0b108cf20461d0a1e22a80cc14e3d8a1d830e25c96da725074dcde1d8143b19492bdb1244acdf5dd3c9bf8ca5b4fd16882187425eaffa1a4d2764e9c4a1dcd9c4e4887ac3a16ce5979d3c6332d59237987c677fd773d60de58c51faadedd48652eeea44f70f6243297488ec1d373ec8285a436184d04ef6127bd53d6a28873a99b3863c0de5e4ff67fa6a444c23a3a12c7ae344ea5f4d3b37c6190aa637a812664a47be490c3314bccbaf66c65e64d8cb508c0941ae42c36428ad7cde2cbfa93194c48758233bc78bdd550c85384afde453ca30686f13c3c6cd6cc6ece64487b889df4b996380a12443498f632734377d5210e30b05d7cd4da71f8ae1858227d935ba339fe4126374a110c3e7c689725a72890b2521340775f2247597b885e27ab6c6e811d3698a3f86168a62ae9d6be368f58ec4c8427a94f6fece8d0331b090c9a675969b66cdd7bd68bbf41c84c99c7d1b31ae500ef13eeb3c87b2ccb2c4b042d9c72478ea980c324c6254a19cc4a457fd1dd9f93506154a7d22dc8f4619c6148a575f5d997370717f6348a1b0dfd9d74ea86810230abcbdb98803376ad8a8e11f1310410c2894734d123af565745c11e3092593172afd362686136cf530f9d6729909d679276a6ba44f8c26145fe224f5dca593a4d04761c1c23f3e06130a739d579a23732488b184c2ac691ddb8e3713944e104309e5cafcbb65a6d22414377d25e7e6fae05962c359100309a5159de1267e8eb4a9b17105c28125887184e2acc81191b49c58c9a22086118a5088714ae8f8d74e5afbd891a36310a1e049d4addd3bcc408c211494905d7d9e7c21a02ee744959efba0148dfba8a4cc858302d2702c160b862251280ace0e130013130000000c2295c6a2d1502c8bf438167e1480036b40243638221e1a1614140bc501a120140c0202a1401800048341a16010140c06dfa20cc903083352ab502330736691f1ba95198402db27ec910505025af8c1f1a0b29d210b3de941a01abec86619ac821307728151d8d8019233064a2f18401755cb35798922c2353ada9826362907cd2c74754d68a60ea4c4b585d06acacac2e8870bf7a4caad1257c33f2de3d04ad18aebc286c1744923ac8e6cba839228f0034867efe009fecce1c7322092ea3e9604b37af0689639a450073fa80f22c9b58aa3a780991f74718449346b1eb6c58fb81ff13d250bfee0cfa6d0e2352878e22b0512e3074a59b842bb3d8a62c2f841255a3813c695831cf263cb10a694848a2f0b8f1f66a5e07431231a7838ccf10ea882cd973fb451c264b401040f43988886646a2184c9f0cf3d109270d865439818885a8a2f0ec77a88ef59a8007e1d81495e627fa038b8d1a97c60ed5b7573248d0d6e0281aa0235df76b0142e854dc15909da6b77e12d9a08c323b403e75640cd26c2f474a1737139e86f991070e68317c8f1cf82aa91c549fdc9d08572a19b11c6ca40c107dc3cd48973bf11333f5c033a556f9eb08cd04c70d7895b370737e3d9848ec0268e4687d0e961b0ae6211e55cf499816269d21931244fa8665914c484ea3029c1957025284d9ccb8e3071be8c7bb7014ac8e9f309502433e1a84edc6c42c0b9f34fbff07688b13881553d93cf6670fb99bb38e972a5fe0ff4616f84ee5b140f8ab9a08768d0d4322290644cdb6ef943a80795093d7743e8c4620c802034d824b710280aba92922c0c546ee65257224830a30633374298a06c0742874698eaae11c8a678b3151d82e9aec729cd4f81d6c50a5153bb9487095300bb4f41d41d6a6044c1c7191b5238fffc638823b1a604f8e863f2ad50f5dcac88923b83fdc7cc8ccc48a144882966597d8b9f2246224aeff1ab00da1025e3c74d50f0429b234ab567bd66948769cdf0ba6a204ae7332f1b8892bdd36bc92d6e1d154271f6d6a42bf433d7576571c20f8c32fc2676049ac2ba83386154a5d3d16e96f5664e46f4e2a4045de5dd59696f94c28f12c4e9bacc702cd2e2d4ca2f958b8929e4a478783525de499e829c93a560539880214ae4b57363823b15d004d0c114b7cfa682c2172026ddac77794efcc5e9e26b31946d092611a7045c09a92c4e9df18cfd4926462cad0091dcf7d40341dda5a20e71b2ef826cb97bc250328b9382dc1ece5998487054d96618513bbd8b4db60f5907516adfbbb1778127c59a0c4884f6f4939685e107013350e690b68c209c5c6ce45feeaae48820fe69d097f4223806363f0542d32c28de74b2a68910ee294a2aa01efa4dffa009371d326d9b24f3b2c39785ea0543e6b8b99d18f408aa1c50596ca21aaac7aad4bf0a50dd6e2dc2c8f027b3a6021490f374d8c2ca7a8a14bf97bc839045423c29084da2323a17349a2240a889991550262cfdde2742a8dd5503e6c9898e942ba8337ea262ac722bd56005ded50ca1100a61e81b6d085c2b186b8f8abfc256a13edc0811bea0ff8969743dcc63452b219052be54c751112b02f1508135bb2b0e150e4fb20f02965a241082935e82b5845382533cd8d1cd0aa75606795f1f429c8eba5ba4666e1e3af3d7a3072cbba9220cbf22148db2a54005fafa895dfe6d07044970ff0ad959d54d104a9b376e4370c926ddb67c26b0af0258411ce0a0345704ed95a2169c02a635177e3808e931a8b59a0a4c7b777519fe02f6dd90301de1e1dde3bc040bc5651e13c4ccbefd1ef1ed27a5fe32330d4e029259b33eb54a316f24b7d9226b9f790a81e36609e1e090b685d12e3d81660c82200708bc18e00661001cd33a1328c951ccbb1f3e0343bc63226f9ddaa47e0e0ac7ebf60092542490b8fa091fe3ec421d0e982c31141016d62304e5b968d8f3b9b4d72bc61311803432c9d96dd6de66b53af9c7f5c8f76f1ea92e49a0aad5b5acb9bf4cd478d33c15df1c5697938d2101dd93223a22ac399efce91299c0a3bca36b4b655b7e0b059e49c18bd14045da1aa7cfd6dbdd725dd56dfd2cb5fe38703168179091bbd883792392ee384bbd22140c2a5c0c131e7540b258db8e18fe39ff0d56eb7e5bf548e6d182e9fff57802a9a518587b36fe7e9763ab3f0c9bd58385cce227de47c6c606cc64d65a22cb001a772d325c11db212bad3fa0ae596b9141aeb1fb223dfb5dccc91d6884a22c854ae6d80943083403681e1033db268d470236ce980bb19e34c039082c644871e163c3513d4b95729727cb175d3e1c61b55a2e9a38c7b60a18805fb1ed9e41c22df485daa44b1da6fe3ef8b795f27d38e87959c99362f7fba5a983abecb4ec4e9017407850b4f3314935f3321bd5b285df5e35791f18ec8ce9d342e31f669a6713ae5659a5d8f400827796232dda0e6d64c9ecda67b7fab4164b903818581fafaaf3691128a49d4e6b7d2ed595a53c609e3b885b66a367c28daa062d2617b3d5bb65d24d3d1b5893ea39f1c02178b3bb4ea3a681229a8be97c8bac42a80f9bfc1e58240cef859a5861c8d478688da2159737521758eb91fb737b89053c4783e67fce8c5f15dfd4f156f490feed957517221ca0fe62d64632c975ce4e2be1ea5818099c3db2743e938cc694f9cad0b613528abe55ce0642c2d12ec9518dac77ba386e7bcad52540bbea972d70259a42249d4bc5fd8c4727c6c7a5eac524cf23c46eaaf21d48809b9b1d4db1856cfa4580104a7aa6d326d1d33c72d4b67771610732ae1c94c7d4a24bac98695e1bf640535b94d2b9a23885e611f0eaba663a80f6b3f33671127308569b4cc703c7c61ac1c25978026e6b97ee4f42bca5a6978e4a44d2dc1457e6882d66ae3fb4a5b0584ae973302ac0e8491bbca3216e1e6bcfc506deb4b36f6e1b576c4030450be62853c463085c26c5198b822173af056416ffda1c53f0f2004290e40b934aa60e48a35d4bb65ab1da0f30eafbe3a65a3b676666315859d0bc15270d33b47627885227302a089fd685c12485ea098c8f02f2107448a5a66c383a6a14e2e97ed90b76284bf0d0519ebb5dc322804a495226be8d6d5f4f081d5ccc87efcd1bfe32edb74ef11c28150d597ffe2247eaaa81ed3ed864adc7e7f17ff9064686a93d8fe7059a818c5e93bfd4d9f29449336c9a1f1f742df213eccd8fd1cadd5952ef0eec3f8b392930a08b9d8bc42b64151f159525bc169671d91c36c97600ae658efbc1218791ec6b0cbbf732f46612109844e32355e7d6b9ff7afb8a20b9ea163471325a52bc91bf99cc23317d2b6985d20acdca0ba8d24319dccd94f6a0b6ef386a62d05d46703fc1a5e9ce08d7bc50022346686632f13a0ac36400a2444c638977e3e1e19935349d144982e96b0c6bdced7e404b6284822d20e18675954c6c670b9e726cbb4ec1d4285717ed985c312dea8fdca99320c7d508c4a1746fdd81e610295a7bdc9fc9cae3916d7ff213ef8ce6c4a17577c3ae477068648d13b0cb69117ec4f02b0e8cfd0be5196115531a1109c2a5f95464cbfd401367ad234579983aaefed1be0fb12d2035ed7d33798791f9efc26de7d42a894c08b26425930870893af6fe1084c96f8731f4d3dc15c1034d332860e480027125d33a448d0e609e49d127e08007eef13a6c2f1dca0e009c7a8331c7cb2d00caf81bea3bb58673e7c9791a081aae424c59a03b6e5b4a79a3e5e4206c78933bd78a4e7172cf47dfdc8dfc12f19976c26c2c77843b0669580d924437e06562935294d66c2a25419a432c1bca59d8e718a449ed1e29b66cbaa3265cecd73018c7f2b1d677265f16af3129efb4c33500afc040e6f9e65f3bcf9665665a809de632f087c7758226ac7716680400360d4caa69889069b1d037c6a484f31dae9b1682f46897eb105bfddea2711305ab5e4518fbce1343294a62d864dd98749ba01b509d0ab3ee99377aea1092c36942bd462e9787afc31d2580f4d288841ab88db1076786568a895972cc18e9e3b698bc26454b412a54551dc087f960cfc2b9c5b2d50390c332c1783a0278e1b07f4bda069541f8e9dc955c4dfad7be527ee70c9c5e52ce5b149951111e75ae1cf49fdc0a5b298724308490e90ecc6fba774127ff70e9a3f05d6d0da483397f5513adee5808bc574dc179d0762f8f4905b7744f1e38d4adaecb2b6b6e3079457a36fbe6a7e1ccdde3f1a11b32ace83c24c167e3ef12fcb0624da7168be9a99e6469bcbe5dae052caaacd5004b1996cba61995dcbe92553bb274a5c1b124ff47509755aa70096bf2e1b3a87e3b83421ec30d898847744bcb60e18eef92e51c2d49b34683001a2e7940e97476dfeeb0c384e893b7c18ca5c225d8baa9e70ee7444c7cba6bdbc64ca0cc07b3255299bf5b3bed81307e50d4f8702ea7defa182a7ba429c2364ee9670ff1a50da04d9f5ecf7f538d38dfa98a656217c8bf9da2e83b8635dd0056721f212f1e7ad2fc46d12cce731b87219ae158707a8d9e20251afd574c1d661bab5037cfb81aa86cb99cb4e0bd103f90dd1074a3570507b663a3e01da6ddc968c796c572a1970c989b84cb76f7ad5d97f47b23f0c4cf947422f2bc6cdd8ef8639a7123d97ad814aa50dbd5d1bb59dac78b3713f58b34624666e8a654b2d58b6d8428694c11bdf274362f427c21ae62adcbfd6167af7e8a605491f21419795ca22115bfe3edb58d845ad89ec2476343fd1d2171c3946c01c948f55824d4431acb1c48ee4317851f6af6252bd8d9504142a6f3d9945a87c6f3cc5ac9f8eb6459f18fa41e53ea639e530c5884e5de781f7a1865366f9f8e24b953f65faab79a45d8eb7df55227f1a7109ac9ea26dc07de5e8dad20ab3874a7a21631e9bb911a57a116e14d6fa1776e984ca9bd2cf740ea430067334981b6d0f355cdab646361adc2b663a3a756d3ac53fc093a5f8fc7e9bb9f1ebb871d3759dd22844a898eecc121bcfa7ee0b58ff539abcbefe96d7836df870cc72b6de28c38fd57f76716fb344033bf3246420674e26ac753c33e226416db01a9d1c5540f26c513a6825e89e6a70bc1aafa33ebd70321e3a5bda437c5998ed14b9768a585f3cbd9bdac3646ca7736ba081fc685f26c0896ca3ef053754c51a6a887a9ac945eb359308d53fe9ec797a72cd5487b09b11247e7f08c8e7d206f92dac197e3e2dfaadf8797f19d344bc854aa830fb8fc4e6973b60deb48456eb416d925ed30aa4502f7abc522b0825e9718a5d3bb65115eb9e376f70dd2d5a45198825d04f99519f62700e288efb89e1e5fc4c4ddce44af664d4137cc62a79c342b91228d65bd3d544873ad8109ac0b73c3afa7d7f77adcf95f8447226b17bdd14e29e7f498b04079f8988dd33b2f136a42161e35faad955ef28ca0661efb35299ef67622097d9906a0457e2a85a432e852f9befd4382b96157a3e1689714f55c638a56ad5168db945f17fc13c1a9620df785127d91ec2a12bf995694721dd8d0dc31d20bf22746e7a0985229401295cc0ce7559f4e6a4b32e55d6754c7c8ac62cbcbc74786eda2a23285969ea69a7698123a1916ef4bb8099f4ca398d4461f15fbd3f9a3973d565686cf88d37fdddf4aa7f5cc867d0001ae06b75d9867ce2c1d15acd85dc36322cc7e91d41f719436236c973871b6a1365ede1fd635bdd7644c79ba688a8a7398a74553ba285a1d53d15fd188a5aa63771c3d35734a6048ff3262bfa728b1aeaa17611950ec3c40cca82cad6a2acf7b661049fc7cde5be612dda547c5b0e303ae2c9c7944b73f45ef3be192e63abf46afcdbe12352b32035f7ae823a72948291737ab4f91dfabc34cc004d9b1d4d0829b7455ef15c7ee1cb56f93c5e97e11abfdd40dff63ca78aba96408dbf0d8202a9a67954dcb29fd5edf2c5a192b391a48247379c6260117c0946f80973cbfc21082cb64ce7f01a70ed95c10501a733b15a288998f716a8e1f74feb0a5604f02f11e28ce1d1330b0b22477a14896e36b56960a6de3a4032c2fe633a7b5f12540c0a3d8a930e7bd5758cc2e610d4d899929298d64a0128e996880b179589103d9a7f65007a5c5811946399ec9bfc18455b54ddba39c76f914ed3ad705eba92914cb59ac25c12087273621b05e3d0eb5224906201fad0fef369755b95ca30fc2bb1f0edb360be0d0b1673c2ecc4bbdb1293d1a3ae94ca8c1085a646fab1cd41e0d608359be27e0c902012537a64e2783a26fbe08c4efd16b81c3d81107932b667d5268ef367e1813a46bd05b2e2aad183e3906aeb8dcfb89cf012d0d7940841d8287705767dcb0c057cd575c172b1ac4b3d1e04f540c716a4f69dd04efaea685dcb5f738dd8a9c4502175ae1132471f058a8495e3c323d076f613f436d158d45eb1e9a519d994f02fd4c454954659d24f1fc8f0bfeb47574a767e8b7274a42e3ea2cf0ef099de8e5671971576f9aaef03ce59bfe21b14473942ee781ffb69a7e9eeadbb0bd60399e79df929381a2bf1291120b491518d050eaefa5727aaf72dd0625d573df6cedc50e06328611f0b6082ae41b943dc3dc4a5c17b77c8e575c5642dbcc9ccfdd81d0dacce8d56c4535d53dbd91051e45ada02c5b3e5460e07690bcf1d97bedfc140929fd62ff650c269c7342137177b1defe53286eaf4ea60ec276c40c65a2c0774345422a4187cbdd803bbe3a21ceb17cc16a682478362810062739f0dc5d0e297e6ff2c822682e998954ecbb0be3ebb5f5657bbf431f70c1609759e308431e999df51393cf15539ebc6e9b22131c1aa42dfb1e4f277be7ddaff28ebce06fd7212570c5c10b21ae53859d88a0d38c73c956b67d2e3066d29be514e5a7c82d8cbbdedba3532b628d6af20356350bd6eee09103dcf8aa396f515e9bf17774a081a1ecbaa03c4d66d8a0a948e9938be6a924b4b5d36a3251de33cd36c2ac240b64603c10825ea72192b82b8017df1f0ccdbca2d1e7234dcbccb4ec32432964147dab67ae1d0a769562b0cd1c8d0cafc8a6365ec65d0b304696fbe7197a25e5ccf3318be37ccf9d7fc10aeef5e6b317ea3cee1ffbd37afa6c7faca2ab65c0017ad1f394c66b83ba827dd2fe86c422a0cd9bd1dcd3c943d79dbbc359bf67b5fea6e3487ea5164764e3723c44785804ffee1a2e417a0619aca28abd2f0415497a9f531668675e7fa6a09b83e89ce1244e18a59b2dccda4371fa13dac379adbc9c7e9886c1c461a29e5277706a75fc2b0731125aebb72f3cd230cbfaac998cc47684608e2772300c3b46e9f10f0bd4ceaf4bffd274caa5f40c0fd2412366d703a1d9f9065f32fa4a013c6877cd8e973357ec9d58a47d302b5e1d05dee927c49133317ae7daa30fa686aaebd2ef6c876e6f7918ac3f54b8eeafa69c7345cfcf32e491d70c23e36fc561dcee99ba6838e24ed5714f0a2f62372156557757c3c11982877bcc28118a2a6ccdc5347da1cf5753d613eccd1cf329c3a0037a6d15a5a9cc08495ea30b22a90389bd8dcbf71003ed8ca9009fa4899db25115df0fa16e5ce16bd313f17af84a18e98b9b3e5045e1d96d769583e1464827ee4b2b05aab1eddc74a69047091e490cd4fc1c4688360df9715804098c0b7972b929aebcc85658cee8a1a89c77cecee106b402cb656e4b100426c2d24f1a565275bbf5ab69e6fc5b1972156c5d5a17728af848f8c1e5041104864e55bb52d11c817e1d6a1c1f23ce55538a16ed0ee4bd9e26543fd7ed6e576be90247a64e230186711bdb66f42477ccbdba193cc48f7aec94084dea21afbc60d327da0c7e9554f3f71f23c78927b33e233cc8740599314533e1df9ee96071711799d9e9c6d218268b546a46343ce3bf9df7aca0616247135af294aa0373c8f83fd8602a85b797e6185a63f7d289439021c553ecdd82262a0ad00641b2975283c3709a6380524dbe269c2770e53160d05d71417f2ee4dcefe8cee17538c6454a0618300744eca62e4dfea761b95307501fed5c156f2ab17086d9905e0013131625d89d5049cdd0e4dac34c6dbb475af00dbb5c111b15ec29967ec5b49e860d752403f3b54ce1f33aca7e939ab201ae4d2e116621ccf389959153bc70684323607404d220d3e90b8f29bab3aa9eb5e58915d0e00ced31b240d47e4e427073cee9aa8973b885da8599261a8a2829e90f3559ffd88d8b2632b77f6251b40d774b9a5b32462c752d29490eeae1ce36904e15d86593ee631fc12c1ed779218d04231a5faff8948ebe1040a489dcbfc904f713fa7f94a122f351349abcf6e7d4af0e3e3625a0f00f8db4c874d245a603a6e0be607e3f3af53e0299d94f33353a8ade16d24c7c96e6b3027aa5c95430acca650436ad9d2c0d8c509dd8ddcf54985355596376b4999cf3afd821a97c6a4a4590d870197a261b7e8163c89aeeba3d138da862d208ac138334874dd1f5a709e2e0d044756a6273caa189cf883d9a3871de301e61506e714587f90fe29a130fbe6142dc004756d942e41386ba8efe1eef12f9ee07ba589ede203dd0652a922c9262fce2d1d052e6ed9afac26acc5c79b1542acecb4756164d699b280f0fa37410c80f3515003aa19207076b8583c401cbeb5aaed07c79f2416216fabcd24e0b311887407378b5bb4202e70c77e46f809b8712f7ef66a881e02166eff3e97259996052af57df04f84953dca4f521aac577beb63403256e2de507ec59ca16d213ddfe65e2a2e18c91cf9f7614182281aced4080c87ed1d1acd836748e961a8bc0ffda6e2acd8ec032872629162082b375c4a6d76619b0cc51d6f82b8552e26387efd134f31a19a67019cb9501cd1f26d188ee2262774b8d84c06e1cde7ca3a6c32218e8962cfda3ca1e3c96559317673c298414a8833baecc3b40b8239c943785561731fd536a34867774af0dc6738a11f3d496d8b1d9c662a097471b2862da121519f1c8cc588d3b5eadb322612eb087011aa7377160bda9bf031ea430805eafdb34eeb11268809fa8708deeb3515ebf2ad1a04ec9ba3fca2b7fd9fbbe5eed8ee548a6ac47f5a1e8f1e013aea328b53ee3e85a2d893aa254adbbb8a1430c6a3b06227311320e6ae15c694212428df4df6369193a24a9c03714d63ee64347f566dc86be6ac5f53b13f5cbc83522349b616a131e60e7f62c7987caddd1a4ac38c5ddb88dd24bac5b4d6d1b6f92bf8dbf3fb9cb457c018d919ef56e07b629d9541a0db4d4291faa1ba5dc81bf2f2b96d5ed60251215b758b21a68680dcb886b025e6090c1f21b38278f9264e2ff36194e9f0df11c684d56fda1fb728592964d7a264bd7489e3ef31e83e00d24dbd0353c0f9f7896d40ec727492026ed5a6f538d518b25aea0e5cd879f00f5625ce85fffd1a8b293f2c6293c18bb18bd24c4c9181c1a7bbec912cde4f401b577300d9bee65c8e346a5166cb2d338d10c9bc4c659e1f74a23a8cb9a8020ee8967e74ff56d569387d439b1ec36b0d3219cc64c2db70f2b2c15cd43330a0c1bb56835cf436d15943a144ecdb3fad155b2dc0486cae6ddcea378060a6206bb591440b89e4ee1f54b2ce09eab705648f51a099cedee2c22cb018901e4ad7e43582820106d799bd7da2d65cb40fddfdd06e561320fdf84f9b597ba2f2fdbb591b00525b140de3683f5f6e1b9f42f241e68914216e453e522e30b46eeaa9d38a0f5f106b01861e810fd99310385f44778bacc8ff2c9e4003d9a816f452bc11178eee89f3877024d9da155ccad6e4c7ccc45301b8f1af0cdd9fcd7a51b84303237c7a08e9b03a7b838b4d78c737f6e6d170085fa7d428150009b755fcfd83d82a30cdfaa66902498b829463989cf585e4fac59e924cf4dcdff4f05dd0edc448ce430ba3aa83327b56f9d3b22fd9a4dfed14364d70f173afc0df17e9f901150c67df6b882a939f98bf6dc3bfacf15600a354280e941baa2c302526d602736e974ba16aadf3d352cf08099d038ec5107ce6079a5763de2725ef083fa60b82f07a0fcdeaea0c220abf1abdc9a806794c677b6a1087178b6b0f6e2081ec78159c551ee0c1f89ba109da0f517ec0eb1f3998d9738d3ccb61940af8712bd6f78ffcb1ed0b25f30cd1df87df1eaa4b1ec5ee01dfff1e3cf6c09c21478294bf2aa3e112ecd2e043d22bd7cf85d907c4374f8f217769437e3705ba678b9bf9187d82ecf7aec49678569759d5789e390353c0657e6f7aadfd3999a36373c9a26dc7f7fcdf67cd9e3899aeea97f3a87b92bc93f3d770d0bba4f093a97976fc71245294e304326ed3ee88402ceef816a8a6e649aae23d734ee8da643ab64d01d3ea7f74c3a19b60715088882d6dba562c9aee6a51cb4fb01fe06a55188ef91239e2d3affed934f1fc215b157c982086558c42532e4144e1eaf99135d68f6f6224b297a489edbc463ee48766b8861e9a86468ace5530e3d0207fb00a3709823aca8c9aba179126bc0740065e07bb048fc231359062f2b91add53b9ab2954eded55d027245e833001f85ad71e1b8aa424b9c02241ee3b7c54dcbb315c2c430d175dfd28f1b42ac4e7418de082df717207e9b008161205739fefe9daabe5f7817ea2243e9580d59d60badb8012d3835e850851327945635e7e6480dc2c3d7650c2d16e587559d63789bc28b326dfc768ecdb69f3bbf160ce7603fd50240a1f78420d13ce9ccc57fc2bc3340f1ef0658cf67e2dfe9dceebad320c5f224d256ad2b610ae260345cec8a5286331e31762890f1a4bfb3ffae0817779be6c12b3ee1d9346f6e88780749920d4dc3b42c93779f6acb05478a7e3b5b36d8ca769a55d63da5a3085e8689afa92cca421c17fe999071409fb9de9da557ba38c7b8c2ec3781838bfed682416f7f34b124851e3b5fad46da59072ba8e36c77a62e014450e18fcd03f08d92c3c1d80f1e8d332a269876f38ee46bc6a21c427139212807400edd4cf7372445ae64be1c3e1a83298a365a827196413b2141a035baf3061479b96c1ce2e774db2cb9a7d56a7f042219ec2c4dcde8f17518a3665d3d509ee809749b98a8a3c2feeafe72120668358d604b68b2ac2a850dfd9e99c3b086604714a395c5aeb5607cea2120c04cf2e5ce5c1a1457b05ec83a840afd639ce46d5306193d2b359e9fd3603d864910ad0a396d1c26486d848cf43f101054cfd6e0fe4ada3311d77b720f7ca9452e00e662c74118e3f7d14e13ca891ad483af26cae3ad2002ff4a397f88861fdc75d954243d2d6715275678044ebd238bf8c91611a169f0a1068a8bb05d7cf14e714189f5263afbdc5f5fb77c7aab489ba5241668f819469d67ebbe48d255e736e7f62a2f9620b90b908e5f385c9156ec66cff2084571116518dbd93c25281cf158ad0240992dc7f0817d873f517d595e13dbcc184b1aa245c33cdd09587102a76a002d4bc24d8fed859ea41b0f110e035a1869ffae2066609f427cc843b34a7e4863d703b333a3c542cdb4ea5082fc4581d497b925655046fe14f44540549e443cd871fe5e0f0c2ef8349a06adc2b638355e5101c63cd88704b699c6ff96af4705beac9b70e80b74802a11e0f9d7724ae712798bfb6facfb0820c8776372ad18308b406c56b13a566e9adaf7c8321116bc121fb4235dd55fe82e42ae06651f1e050f8ed979ed2d288b3eb5d93b668dfc98a2e13104a4c6e07a09291e4915eadf66b9ea787a90a1acd257bda98eacbc52d56f10468decf55f857af3382781b459ee4f59d9f479f432c01942fa12c4e769330f8b7128b724e7b841774552ce1fb91ec568ebed21fbc9ec24c68d9ea1b6591478400399cd23f8f8f6356f4f7d5e0b3535900b025ee0a3dfb19504dd814eea5fdb9bc00a343287940e85eaf6b0706f35a8d70ed51500151fd6c69e8bdba4de83e482fc41c60d72b8a2b723a99190e16167c865bd728b72f3240bf3a56b6ecafa09408450cffa016ffa99d30a780d1394d481d9ba7ee6503c86d515529b27a13648627d45077b91bc32c9f553a0da2beef803a346498e0422f8c68c8b6facf3d527a8b235221d62b0c36bede91408a76f4a82499b106d1b6176a05100dfd856e51a41faf16ff54f2ec19cdb69d39f4a7197805a259be0336ef41f8bfcd17fe9a5c022307910132d13945cb09677adde812d090d67826936212ef5779be286f919b1b7eb8bbb325426d83fb560bc8270e3f5e954a29f282975b40fa2b0e9bf411ec3aab3415f1ffd1d91556318533f502804a71ad98a25f7e14e6ef5e920fb165cf7bb3c6ef83894181e0203c001fb70fce56c16c85158ffff2447068914276d822263e2647afe2a97d737a732249db4b1e2492240c499007e482de73fc6856af700d24f5003781074cda69e26c9b99c0a9a58538ade529f7e7e09505360167f4aa2ece8e42a16caac32791c5e08dfca163cc0c9dd092b90d3d4abe54d0c5abefe8e3805b9bb3629ee0c1d982ae4b2de11e9e1ad24ce4eb42aa1b3f649f52b6d98b2b8402de3c113398e7cc88cff0115a1d99d896267d4326befee27580c9546d803cd7195a02ba2e77c81ef4cb8315914c78c3e67cbbaa356b2c3eecff7bef81a42608c66281ad2a446c61a44a159d2cafd2855d8a5b0200ee4f0f94d589ba2e48e5883cee64991eac26c440b48a8afe86a7f85a1f5307e8a20466b88e3ac756ac3fdd9312b3163ea658f6a887b886dbf331e783a0608ac8ae37a61c6036c8fa62f750f090777860b297fbf188922c21c2dc9c99d2e1e6cfcaa46d594627ececd226417c08b24cd9a74e641ad8fb894ad6ca8a5657661920d4611f681aaf214e35866ec06d750a6985a0e45db9967524e2c8cea28e0408782a4c47e0a7b2f46c2399870e5b16c7ad307ef8835548e24b1c3286c2bd5d5de1c1ef13a9fec8ed6403bf278c5319d99c2d9696c02b16480a22421f05a40f559797115508e1c2b16ea8aac9f2b318fb04f98ed0ea13d71be1e9bc4a654ce8d5f8388d4c6318cdebd045056ba098e4a7fc0a3822c4939c088f43925172c4c91e006e2c72479ebffbabf5db70436a219f4c44cc3137d19c20bf35f617a604389351bc87e2ebc0b7e2f44b4754d9e125bf40e89e685d5da2b2dd2213f2645fb70cfd68c941606679d5087c02d43199c86474148a2801282bc01f5cc51323e4e68edc7d648998ed7b98d1939cab060732c49d221114ecc2d352a25f8b7ed0a3ae75850eefa89f5c4caf4ef0d84041e337d77592cfa9119b9534d3be0a335c88a3aab87cac897c346027ad547c9e8102b887c85446b789822bf05eeef3c3e99028bfa109c87ba3e244ede57e24a710689106a2550bd1bc0a81fe0a89b6fe82ea3bdeeeaa44757966af86a0e51e8b1a9b3fec2ac0deacab166b7f067784f744f61cdb72172997f32a32e08bc8d5c2109dab934ff46e6e08d835a500b6a580400f4eeee08aa886f237ff904a04a8d9ee559deb3d1bc3e0417324bd9c81c9d1eaa912e240aa47999fd1948d485fcffd707d823efc625f28eefc65c48871f18c364e5c28b019565c53137ca5a3118f853ce2fccc08045458975da1ffe6c32686955f32181c9dc2a3ed201a6e51074c8853150b25851b3d2779de4da0347d6a03d151f6842987e96be9b804b1fa9a1c5646b1289d24b682640d10288662b69e82a028f0a380254e79c7a4252630b9c162d1fd75b7ce8c652f86733c63fb71ec68f6bd34969c1505ee9a490c02e543827793d76aeee9d8e662fc1e56909f878b98903e097a2a83e74e264169850f2b0a812395f67e7aa29c507d9882d7ac4fc89a32452e6272ad5676b321b722585ff27f766f71594af24d83d98d6fa2b9b8f10a9773617119c108e54e283b57420fbf7f5857044c9b255a4fa51c22e4c45c9b25feece8002f8dd1983553ae7540bfa5e9bd146f187c30440f35219712253c52a822cd814102bf1751eee01391c23e1c438aa74cd687f22ada5860121de274e31ed83e3fbc88b28d75abb50fbf296865ec64330a5db0a79ef8ed1e7ce6b5faf69b71cd2fb2d77b1128500925c0c5647edf4413926f0da9efb888cca937eac34b6399410800e22802fb3402df322a39b0ccf323678cc9d017246d017bbbf2c560668e58e1a6391c8044e1c7e6de317a4c5dcbbb6125b5d32c7516c1bfba5c091449f5b9a4d1fc6b067c441f19a1fb03d9a92c0900a6628057b74888d9909531ad902bff1b1081935561196117607c62d4c50ec881825b18415a2852035c9ecb23a76019629ec5e8c4b4c01c10e04a8d21a248ae191794b3ba0cc1060ab59581c8b03b3fb3143814f83483edfc668582831eb83198a311821d4d5d42333e36f044b2ba268cbf500372d7208409f80f3cdd15c64be5089ab130429323acb6ff308850beb1a7c24ac56ddcb4653b668ef03752f85276b43c3fdd54a8e7e6814ade3844caa7491282dec383fa7584c31623bd9921753913ed74da3f4886446fad886d9f60c7398e6bdaed1147448ace6a6fa189afacab9352300725b453a8969cba5eb25535a9c690e4297c4ddb3ea5f1b5970b21b5d975b0aa2634f36ad2953c5fb40696c6e483150a7c6f2cd39d755e75fa4a73857687cbbf22e2cb1314a227e13dc29aa1013315522995f775c936aa253262149e81bfaef65bf2ee62d316f928c229a59b01627a7c7875433baa4653e0280b42ed48686b8e48849e12409467f8e60d32acd1a84ea158b269d57f54995acd199e5ed7ea2ae56c672bf08b80520e8916267b038e865689ccea14ec57eab6d9809647f4a95817f3963661582320f38784660c3b7695f6ca90475266466064414d4c6f584f74a388ebabfc0c413cd987c81247e83ba2ce995a75c2b3cc901ca21b710a6f5dcae6595fb5aa24cf4d12beb45022e17e1879052eee0858867efa1bc03796afe6aabd45238ca9f22a1820a62ea03d96b17f12094e345a09a0ba1778d17670fc66c347112b32fb5257731d36678cf1c3701cbe26ed94964561cbfdb740f992ff43b6f371374bed20d36ad5d2107e5142da4de83bd4e196c88eeab6e601e654a65fd7b2ceb933d7ca0c7212e8792585cf6376d279ce363077f00cbcf0fd94d5b8c9a0e88a9a0bb1b427cf692853c7749171518a0c45add6a856f021e07447e0a3540b0a6d0013c0c3c0c3c0c3c0c2c7566e6ee1ddd7d446b5f4a995287468c6cd424d04829a524535a3674d909acfe19fdf3d5dd9f26430a700a380aa7bc031964d8d5520a22efc9733eb9cfe981900d7420630ce6a816fb324509c74137aa6020430c26d3cfc9901106a3cfc9f221b439dac61918cc2fc266c5aad6f39a4a252e90f10553ea5c26bd96e4a6d3396478c1a052b85ed1b92e18ceb349cfb7f9dd7f6592c105f365376d078efd42c6164cbac48b194be90d2d1d3f3a07563e782c066468c15457624209fa517447454616ccc9aab25ded332c18bcb6b29a8b979cace4645cc1e0fee122f4870f321a5a880c2b986d542edb7693d62be986168300fd15baf1fda802195530c8ea659d0b61e5966e810c2ae40c644cc13472fa4c50369282f92b9c3c75a5f493340a264f513dbfcc68cf491a0a461d374b5ea327ab093fc19c72f61fb4746cc8c50966d5ea921d94aa385e134c95f6ab1fac3db3e498605056eafd923c29a758233296600acfd6a2f564cbfca404a3896bb29dfd7eca974e82b93adb57534b7a3f2d12cc97e43fa74b8f60d0191b31a1110ce6a6625abe4cca9d229864694f397946229893526b29c7bf219863056529fd13826147450819ef0b355610cc29c9652a6a6d2a8780604e1767e13a8802193f302949c7b5dccb34a99d0c1f60266805d9342998707df76b52d256482f0ca6b694d41d9f4984f0c294d652ae0b79b99e555a84ecc2e49919d285c99214b52b323d4bbe7361d2537bfacc9399b813172813b5ee94240bb9459aa6bb949d70e28e105b982f29cb4a31ab6872d24387d920a4162625a697dcdbe649d2a91ca01dab3512420bf36625b790259e851d4a6faee3de474d0a21b2309fa5d0fc9ca389088985c982c8cf901f9ebc465898e3541cdf2f5141ec492222e41546d1f8dbfce4415b8a2b0ce22648eb5239ad3008bdca25636dfe7c6685f93e8be734d94fac5f3c44c82acc2656e558b65115e66476f79d04b1776e82231506f95cca6e63bff4895061721125db43c8ad4939a7302569948a9e6fe33085d1567b46d3bd529893d44936634f4e533e298c66a66389265a9c6d7f14a6fc582f66398a5eb6446152a1525225e6c44f97540c11120a93e928fdf86725454982c224543229bde4f609c3ba7dfe505fba75d6428478823bb91e3a05a1f7b626847462f330aafb9d4fae3e101b15423861d2266b99dcc8134a12db84c1f45acc944ec29ce86ac294bb6afd2e7eb05c76264ca5ecd2e9a8d89f151a21423061659de51e2bada34d42c8258c2d3e964f9ec7b0131a4488254cad582ac8ac8584904a18d4a5ffe960c24e95921226255dfe12a38ffe1f388e204226613c3fa9649c24e5ac9292304949773f3c94765bc981088944a1a26c5aa96caad62f268440c2d859d747fb73da9fa40544c8234c2549d99fb3925e72c511e6107d3f5dc1d20853c8d0f61b2abd45888c305ed6be2497b86421ba45189496d44912eb0c9d4c4518ccb2bd791061224c65c9ddcbe40f11a6513b725ffab177cf43984411a2e77b5432f92419c22c7e5292a32d8452824921cc39baffe475d9111d214cfa2499ee258cd4eb8b41184bb0941ea4688b77521c4910e6b4d3257f295f34ef04c264aa922991d3a7845072430b1026498e79136d2def78f6e30fe60f1a4a5b12ea5e4fe987bdc40e7229d407a3279513eae795b3491b481f3e18fcc46cca876a0f69efc9568297a0d4c482e8c1a064536f25f44d754aca83298913f2e7c285a932e1c114458f78079424081d6ba3951ab211868fdeb184103b98e22dcbcbcaa730a25207930abfdf6bbef7e3173a98a45c1fd7f1a345e660ca254386771c3f495d6c87103918e4c9ef29d9c9c7c16ce14349b26568f930e1906429c7c7ba59dfb009efd14ebe298a1037947f5c74c74b4d49b24f84b421715315537ebfecc34a086183496a2d956ac47adfd7018e1f6b3025119da3c3675afe10a2069332b922a24e7cf67cfa917e084983e176dea42a657da6321a4ca9a2c793f3fb936efe7106d3fd495209962ee86c96194c32535438bbd392455906530e5fb1cd926430c7559631a5ea44633067bb14fdfd12fb102206a3a9679f1c7987c1bc55eb5752e5dc173b37140c461731e2d5447f43bfb0e74f964bdc4b7afec247eb403abc60ece46731b392e81cb62e183c7fa753b1a75971e3c23e4288ce9fd25cf810b205839b5ef9874913256d5a30b6093a7fae33a5c7abdb4348168c2552448c656b7a08c142977a4bfef15cf12b98bdcacf32fe910379e7a81a8458c1284a666fc9caf9eaaf0a26d325bdb24db242a86052427ef6d35d77b96b168f90299883e5c94e995f12122346c1438814cecfd6f81c47bdbbf123480ffe41481434ad976af601e46df4e0d1637d1002854a9051c1efc3cc846c0c21e409c9b699b899756b95bed0d127d543070a498e71c019e2043e437cba090651efbcbe237f6c1d29840926d16a428a4921a43ffac7d5216409064f49755fe74405b10e02a373a8ad21440946fdd8f3dfed1e948d21493089a273f6944665bb1c8520c1a4dfe3d3577cd3ea241d407078c8114c6277705bab14101c1e6204d368b6e7ba105204c3858e4a517ce4f4d53b8860125365dafd1df44b5dbc103204b3c92565b14bf6e3c993108c277f365126b829082653f26cca9fe9bf0f01c1dc21840c25db08b16df981494d2e1586101f9847d7dabfefddf2b75e9804f17d9252cfeb40073872c00b5309e1a665b4ff9c30d985714776ffde9ecc173de9c228d25372edde743139b9306a77d27aa2e8b5b72ae1c220d5c4ec50a3dec278e28a2c199a8151d216c6107d3ada9beed123ae85c9eda4d45a11ff73e60d2d30ec6861f2a02e7a479113aad7599c52b6ba2c1859b230ea49495e848eddd02a868617c4c234e2c193f0fd3985d8817cfb000206828529e56609be154f29c88d1f36b2c0d85798ecb22941ceb8499692b8c2147c2e3fd8e9ad30a7b09197fb4e55a9b0c2549f4709ca6e94b8b4adc26cd22cabc7932ea8d85561ea344ade775392074b954c8541a84ea6af6e3ef2743b5498662f87b19362259f52d6298c67925639d1a473d85853184fa7e45726d23f5fb414a6eca2fae68266470ae3094a9f6b88f30e13658dc270d2774cb9f0d23837478f1f364461d8d9117ea5dae54d05c686c234ee398e8e7f7cd473ad70000aa39ade92e6b42771fa270cdf25666937f11b5a5fdc78307ae8f865c30b3c6152b279a79126223ead9d30ace5363d91730e74f8e084c1bbe45ad8df1a1dfa264cf2722abdfee95c666ac264612936e54e2533c1dc9e742aa76887031306cfda399f83b6d8cc2e614ef2871cd1d259c2141e5659442dbaea090447e7e0059530db8ddccaca262fa08441adda55c5bdd33a964998ba469a50614d57fb9684d9cd2feb9fe09d645674a01c281206153f95564f526772fd02489853959b8632e9c1e31f6190a1638fee30eea397234c4125d325ebe69f6ab9118631254f3cf35841052546186eb6645befd6af08955c8429988fe56fb8d9b5ac08b39bde5a8a6bebf5393b101030c6f08244184f927c4dde5fbeed141c09112639966cee5baa8e25c3910e61daec4c2b593fdf828630c971264ba6c79991aa0f1b7638d0d2f0824218cb4274ba70929592a453c94408f36f55c9ff191fb5c341984b256131ab09c224b52425d45cf8f52b4820cc6742d6e4f8018451df2fa88a27986c20203c74a09318195ef00773aa934dd0a6af792541025c3a070f1e2cc8c183470f1b49754084096633b92ffadc4e0ca1aeda16882cc1684a050de12674d9e78828c17c2768c7d42b293a9c9260522bf52577899060124fb977db9c7096fa11cc595e43b55d6c04933c29dbfa737f3e2b45309a962e31ec4587fa9808114aa57ef4a9b393b4213204730eb262ee56142b698b08a10cbf70d9e3100982c13c7bdf3f681f53824480600c9354c573b8cb153d14f981e1e4e0bb880f0c972c2895b1d9eb367b617c4be2ae3d999caee385b104aff42054b88f7af0b0e1230768478c18ccbb30fe7836e1e57e94781ab9e0033162e80c5d681546ddb52de532a9c439c1670f03480f1d26468ccc85c174965fb68e3866e0c2b079a1b62f7f8119b730ad49729a502a6e4d8b6c61fafab7f5d7daf9fca98571b47e480b936adfca1dba4d32b19f85c166444f908f2c8ca7fe2f85df159d662c4ca3f745574ae9c12c0b0b93b4f125c9b97c85e99294d9c924a12b4c77fec9abc3d80a730eae1a2679c7b8112b0c5aa48beacea6e26715064faa63393ac9235f518549e794a863f97a4fc9a5c25492a4848e6ff6d949850a93a4f7e3459ba73079fca41ee4a5db7b923903334c51314a61cabfb7587525485121854198b06fe16369b59546618ee5eb7e52eb9f1889c238e24e2e9b94fe4f4e280ca355a408557240610c5d4aca41e8ff0973cecb7f89dd7bc2d865e7f3259e1053274c2528f57222fd12efde84d9c4361dd7a4cff79e3561f81456c6460979523c33612c9933f76db959a9c484a78433d5254c2926887558132f4d96309992740aebda59ab2f95306698a06fede7c5a48e1226755aa35f62e27fd6266150294cda92cafbe4a8246116bbfeec2b95fbc248183c6698685c12489873e50b37173b8c9ffe11c650653e97767684f1554ea550ba4f2ae136c2ecf1fc24932f9c78f28c3049b72e9fa690835e306311262f25ff2cfb198a3098ae67bb248d0cebc488312311e6d10e4a59fc1925fc69c78e12cc4084b1ebb59468b2929c939f7108939493d8f953d2e6eded0c4398ca84332bc98252ea8e203672c0c3c717561b985108b3879ecf1bb272874b99410863e5c7a9c99f9eb5a2ad15cc1884e9c413c49c4076201d2807b21982307b10a3939206e2a33910c6b128a2a349728f6e11204cea6efebb649552ebfc81f9ac37b1615238ce0fa6e49dbd1eaa197d3085dd522f49afca77bf23484a66f0c158928e7b12fd6135630fc6b124e512c2e73b6f2c14ccd08361d4092dfa4ebcf281340f26414cc5754f7f29b6aae347e7402ba91f69836f203f900533f060da4e5d520ee2ff94a8bf2388080eca81a3c71733ee6050ca4debbefc87e7927b740ad0e10102edd13a6ca0c3e3970333ec80c8796525a9e2dd4bdd5cfe2461b23162c48801240c17810b2490a80f203d8030a30ec634110af2821974d839984b6e7d5362a9167d25399845252bb96bd27130fcffbba510177a1dc3c1d4adde61bdc1f4bbb5ed665262c4403970f4d0c1e34f77937b9bd10653bcb61cd35b94b41e1423c60c36b0e6ae222a54e9104be003fd90715c30630d0659cfe322bc44ef356f68d908c30790ab9ca106a3bec8d632e11cc81b053162fc9891067355584bb27d5037df413a82fcd8c1e3b7ac0e0d26d1bcc554698df5669ca1d8dfd1937e5abc366386197446194cda45a512764233c860cec9a458b7923406a399646741869bfcfb11c3c924afd692539fdc0983498a1e378497249a0a3a184ca54efece134c7e6efe858352979643bddeeb055389f8b62487b30b6856b234ed2cb94cb4123be6c73df5a63773c3195c307d301d4556b26cc1a4e4b4dd4e9e32eb3c2d98a49497d34d36230b664b769d438b772c7532030b26e5e76ea1e2c4f22f5de12c4ab2d7731359c1549fa5e4124e923a3b5a0593e5e8126b2e4605835b09a2453b5330b9295df2a76ef70ad60c29984a5a3de97ac9c4ca9f281884d2991f2fa76740c1a454d3d3edef1d98f18462bcc9155a5925b5e59c4b5b38f943c80c339c60fcf39cfe25c91f7644304e096634c1a473bcf4f1aff2baab194c3075122c9bd4ca2667ddc3402798b10483afc973b6f2f1701d61bc40648612cc2988e850236f2dce3e230946d5fb0c59522871eeb0e183870d20e88bab028219483079650d2dc22fe7e8114c71f9263b32e36388cf72986086118c223c294b21bed7bdf403878ead9a5104c3497b6254aa764a0e1424598e194430c7b7ffb93d916fe21d831943305a2a4909216e6b7b541da01d85c70c2198fec268964932901f416a70da860f371bcc088239b6726e75f4e8f6a01d387e30901f3b70988d194030dc58965eead38c1f182b59d893aa2ce7c5cf0c1f98641fcf25c4f35e985db5f546c59417e66427cd466a96f21b77614e2757b1f29cd67f45862e4c62d6d4abbd935ade64e4c2b42d62458b86caf7bf0c5c983a9c10321ebe19326e6156f912f46335f401a4870c5b984ed056e5d9833a5a0525881143462dcc26633fe80b21d4230c2032686192d1e9e7a12b39da79e418418c18326661f6f9a022d504b9d60664c8c2242a7d3b9b248a85c1240d21ee3b0579a197010b93fcdb6525ccaf30a5ebf5fc63fa53bfee0a935c727612cd9326468c183164b4c2682acc8e674b7125cdac30577d50ff91253d6495b10ab3eeb5cc28317bad36556118d926cd73492ac91f45304e0976201f1ee811e4a010a0f50872d0c12a15d4b0710219a930ad9ef822cb73389d1654187bd33b4d7a1c0faa4a9220e31426299f34514bb2c8c6984c61ee1a3525de9adef97029cca33e45b953f18430415218763c283b3b95519873f49777edfe87284cef5f2aa577d40bcadea49a5b9d1dff80c29484998cd1cd93547c3f615611da84bab7b7cec81326fbb7f8549fa12f589da84e558bb6b03f270c1fe3cf4acdc509e76fc21c3a8973d298a07151d78459dfe22d8a7ca7f52f13c6eb0e36e22cbc895f31617e993dd7503b2f1b5dc2246cb5f949b9b7b39358c21c7666d94246d8b6580973a524b7eaab5ffc1351c2e85fbe2323ea4998e48f67423d95e4ed4ac270fb9ea4cf277596db23f1ef9d0c41c21c32ebb2c8051f61ee4ac2d475a87075bf238ce1db6984f972cf2aee3bfbf6831126fb35c1eb73671166bd92b3469460258a1245184ccc77521654eee71361b89c82d2616d2dc80b1161fcbcbf1db49cb07c904398a45272455195b5ee7fe320c310264bcad229a9769ed54298bf2a9b9025c93ea21d4298cc3e499224ba67bffa066150418995ff949dda8c8230abddbccb65d1ce391808f3c8cbad2edfd49b1910e6dcf97a314cf0c71f7add1bf9925b926f90e1074c925390bf2ce983a9f4a74ef7b00be6c91f7c309b60f5559ffb4a7f923d94217f82f460d8cf9196b2836e909107839ba7b7c6e67830e5f01de2646c7730a57ac9a5e4d7e520c30ea6bde05b95744ee1277530fdade9534944991c467990410793246589a83c2174cea61b5a7330453fb730b26a2bd6eba381d8b051c89083498b8aa5ba6bfdb103c76942461c4cf95672d413747905eb865669830c3898733ce5923c479327e96f30ff5e86f43df5e93bed0653900b9d33af397db235c86883592c47858b1c5529259d41464a5c989855857c0d2625a9b6e4d9f43d9bcc20430d0695e3dc07ad8d3d1b9334c8488369435d10deaabbfae152830c3498a49244e66eff3c649cc1f06b963fdcef4232cc805a924babe5247790f140461912d54aea24014a631766534128139f4417c63ae9719e32fd52b87361d2b024db334afeb68a0ba3a7114fa2df8bf7a9b7307aa80a9eb73d8efed016e6befe9395133676ba5a987409a24f3ebd14947bb430ee899b6a27c76661dc3d6dcaee726ebb260b93ce0e27d908c5c270dd494f47ed681e8685c9e4899744136debade41567875632b9dbacdbdcbc836c7ad8c5fa4ea2e10a83781871299ac92153a3d10ac37dc790cb9fc3fd5b345861ea4aab66a3da638ebe0a538b7f9c94f520d050854145b7fa92ae1b5a345261d65149499ed57d543cf9a0810a731cf593c3c77f9dae9cc238bbf5797b4970600a53579253b2ab7647e7288529c59bf51ccf5cc65f1aa43005790df5172549fd791aa33085858fd2954a4913c43444610aeab5675fb93dec2914e6504a05916d1d2b070b1406adce27051dd3274c961e7ce6f5c413e66c5ad59ff3c50e1ca7518ec43a61924b654b9545c7563eddd0e284717d65bc623c3c5c7213065326fe9ef82968b5fc9a260cca83f23bed8c4626cc3a7afa5474363f796e68ddfda08109731e2b0ba72584e31215038725cc17f6df4bbc547656c22cff22d4079d82ce16b3c18f72021a943048cb17bbdb6c66fe0287dbc849548c20342461bafbb84ff24cd49c4154402312063f511e4a0709937452c9bcd1954c88fa86d63dc2dc49ebc62575f52575e5087309c2f4759e36494a2a407ef8c091d4ac11c6b40cb1a1e4e7f7126263010d469817734f52939ebe459834cc838a56214598434f95ec1fbe24e9f3341271aa0ea1a4ec22c274615dac2f6c4939cb340e41c3103d6814c20e2b59352dd9eb691022d54e55a33a7e65bda195d418680c029113c6cbb2c9c6885a6739a02108f349925fe9e929fdfd04c29c04116fe1f5495d2b3ed00084394b9658ae7467881f68fcc19cf3aae545cf152bfe34fc60b213ad6f41ca56c90f8d3e98c35c4bb476d2df0e271a7c307eda131655564b940a8d3d9872f4acdc7225bfc4e7ca060d3d98730c93255586edb6098d3c1894307944aee70f593f1e0c3a573affd4fc0ee63d0d25b2e449920eaa1d4c277dd6cfebd43184b20e26555252264d9ad0a083f9a4e9944be834ff96c61c4c52e858f9a2592007f39daecd9b987130970a9d8309cb6ee1fd1831e060b20af14fd9f406831294ecf69583ba949e2a11d07083397ed049ecd6d906e3defeec9cd48f332736988250d9e4fa5a2ccf97926b3099603376529ff2f35a0de6d3f1f257799706f3a7aecfa935313f995486a90768a0c1a49d64fca8fd923b97f480c6192c2552eb4c12ab04d13043266ad9aa24e1554c9fb036376ac13e1a6530969dce565d7a3d093b0d3298528e5cf997188d31989468fe25e78b68a42ee97c180cef772b1e7282c1bc32161eeea94b984de30b667f0d212de768a32449336878c19c343545966cd7951f61d0e882490c51279d9c4b96edd90082be401a5c30c921cbb7dfcf1b6a954c630ba6ae6d1195a5c46b857834b460507d4b41890e32f7c47f688146164cd2a820eb4aecdc0cfd28030d2c1cb573dbd96c4ee30a66f54bb552bd4ee599156854a162c8a041057327b3f424e70534a6c06b9a962c7292d4dee916940aa6afba7443eb7c00e941430ac6aaaa16791345c1a0f2e5aaa15e2818633cb80891eb130ca66e2628692e27188487d787fe8aa16d82d94af8acf769312da530c194cebb7dd4d6abe92c8131fb3c1d2f5682395e8a8ddcf492604aaac5e4b01f438241e8faf1f7fbfafdd411cc275d56b9ce9682e76930a06104d38cb8ad7c25cbd49a6814c124cc870a6a4bf6060d2218a4a7a4c67e44a53104a3a6c8911bd99dd9ad326908c1bc3b9aba7f2a989ceaa01184832515cedf4ad30284da65352ededce3d4c2f7a99394384a0964470974f0f02182307404d95168fcc0e4a196eff9631a3e307969936334bf2c5ab61746d1f89713265e18b7c4f3492bb7b915dc85f1842f3974d09d2e0c36fab3091d4d72612cb94d55f0d9f4f9282ecc5f4a46bdecb7043da35b98f25a9f64d2f5dddbc9b18559cb3add2e999294fc2730925a984becadfffdd8fb3344686112d5fff39376b09737c82cccc942479dce901636f5d138b0b2ba9285c17296967816ff59db0d2d1b3a78f84858120819018ac4c264c209bae9e94bf3148185b13c9db0f635ba337dac57985aaf2b89ef5b4147c415c690664a3c39ebe7d29513694589b0c22443abe58e7215759718efdd9672a80a535f96b4f9734a8541e6aecbb9752ee1ef08924450717e57cd5113e929cc1fdcadb74a690af3ddcb49aba2a464298c269b692faf93c294a294b4d8f68ec294c52bd8be88ba7f26220ac3d6e5d4217696e4554542610e164a27a9dfe249934c4a0414a61b152a054b4bf2cde7869607443e61d0499d6e680109a2c3069e88278cf96d39b74c551a21ec84c9d4cf9a2c65b23b989213e184d92d65dc536caf0df58656896cc23cae29a6b49a4c57cd443461fe38774ad249d28964c278d9747630f72fad93228209e3ef96ea8d75534970452e61922413a743c97fd2c906970fb4634752680983e95bb56c675fa25d442a61d290dd9225a96e68b9408412a6ca1a6db7e25174746c4b20320993f4a2a43ab14aa8ce318a48c292724a27e7d52f1209c39e8d580f42077533118184a93ca5e811a652f29d92ee3c8975398e30b7a8c686e6a9fef01b618e9715c7e4854bda654698b736edc327719ba24598ae44136ecb5b45982dcceca97c351126b94549134faaee1123c270da520993d5f6469a873097d025279b73922064884d3bedf47ab80a918a25410921cc498cd9af246e3b97203a6cf8c0d13d6c00415f582546029141983accaa573eb988200c6abe04f31f592410a62a93b2c5359f59f14400614a62cbadf876227f30099563fce809172c113f98f574d651417e0da48f481f4c725a6b4bc2f25a5b940f461321e2664ab807c3c9134667f9b0a66ad183796dcb5735bd3c184d962fafb31c4fc4baa18507c386d0a594c938359f490b88dcc158ea5ee6277e7630e57cff88c65f07e3fbc7d8f22c1751613a98522c59fba4f65893bb39983a5f579f9b941c0cfa6453f17c4de260922c449de5a493753c45e0609491f1d81e46226f30a9ea65fc85abb1788c18bf230cfe81881b4ce975b1a453613a89a736605a616a49ca617255980ba6a3cfc927226c30a793f49d92797a4418105983f944dfca37f50d155183b9830e3b932deaa6fe0d05e39460043162c488d13b908fb661a5059134985537948ef16dc2436830c9278e4aefb98b9cc1d4a5e4d557af353b2f620693dcfbafd2927398ed94c1a4c26ac851e9725a223218ffc7b346099ef37b1e8369bbb5e2ce7fc460ba5839a55d66d7e23098c3524982c1a0efaa4a64d44c12f30ba876e7533337bd604aa28c9c6026a7f7bcba608a9e27ca8fc9369f36178cf9d57925f757d2c1da82d93a488d935f2d9872b2d8b61fa72c9874fe9b78568f988b58304949079525744ebcd2154c269f7862e65a2e6205c37efe93470869d7fbbf40a40ac6371d4be892af0d44a8605aff33a5e40ccb3fda0b76884cc154da04596ee2a9dfa844a4a0ba699ba36050d26b9f34aa08148c22abf23840050746e409267f7d3d4157b608224e30a5b4bcf429e23d84be489020d2045379e997349aa72414b8aa405505ce128b007fea042290c4281aa320f0407e04f151800084e11538680101f8e1037d90c3c3478f0468e0078e1ebd00017c010001000000002080002c000000008002d0e1b1a3028b0e8f1d0d604002e0c70f8f41000134903e310a108006d287878f180700c0001e90001b366c3000000170c001d2e1a12315a0c62612504313269d638efea06aed4ef486ae55102b1dc8870d1ce03836cea31e3fb880ecc0719930b8689913e9a5964eb50307261218ad2315a0c625ccb947b3dec4826c2549058cb684e9dfb3ebb6c2c550af12c6d950d6e9259430ba095baf139ffea104464f028cd691085043120695a4576e686124ccda692c9920971a9078440f1def0804d46844da8143472a400d4698e64d29a97f2ccd24ff86d60e1c3a52590410f44311e6d0ab7a6b9228fa049dc3e3f04884e9932c723d9bad96fb381061d0eb3d49558a05ef0f8e439874697c85e7bfef474b91c01026d1aa0435fed9e25dee8c1a85309acea926c52c6d65073a38726083870fa48384044608637a92aba244c6310873d8d29304d11f0e419874f85fb0f496a7e28f231066fb92c296f87f141901c22827668d36c9da5297c6821a7f309764397243baf8e76e83478ea4ce0f46ffd43975e81cebc171a30fe6fb7449579a759c79e4b01004e183a9fdb3c876cf6d7d14070c6aecc1eca583c7b876b474f238f4604ac2f6682d9dcf25fb62078e1e3dda470eac468d3c98922add9335d993e4b9f1c3468e2e203b70c4885132c8480d3c24a0c61d4ce25aabe2b87f43eb6cd8d81c41741c066ad8c11c6a62e7bed341b54a7cdcf891a30e66936b9f4d36cb71e347dbb0c10864078ea383d1c397c84bc209e5969f83b9d3c5896ead11ca4c3998e4747e7f47b3461c0c50030e069554f0912f278792c5d78174a40ea4e3b0c61b0e0f1d890035dc90801a6d3045b1a4dacef7f293c0681d093b50830d86fbff2d532ae5f0d0b106534a8ba644f8c96a7d7243eb7000c1018e13c4860dc6018e13a400d981e33450430d2661e1fc3a899d72f8941b5a87878e5474388e1ce50690d6517eecc001c407ca81230d08073c74e8403a0e50030d3b70e84804a87106b3ffeca72dc9b3a5b26b98c1a0576b5bd2a703a5a046190c174e052566d5748e610d329877acd3f5eb646f7d0cc6b26071dcbe1383b9eec3822529498d3018d4e88a8e5e279b94710d30e4192685b11c7372fb0593f4fc9a5e15ca3ddd35bc60bced93ceb4c735ba7025b9c035b650316450430b06cb725eb1e4501e2eaf9105a3cee79483708f275512168cfbfabea177740563cba5cbfbd7a31f7a2b94c3249525963057c1fc9d75f26e4a05934962bae5eadf0b35a66090d7794fc43e8aae560ae6581d352d651805f328213b57f9ac5e0405c3bd05bddfd16275ce130ce24627515f2f4e309d24edca422d4d3009bb95446d8698303a26983cb5be892d26e8b42ec1b827cf59ba93aaa104935678eeb8ddf62d6b8d246c297549658289dda69d79f27e09a7a5ab8104e387f21879992374ce1fc19483b29bb7b214f9ba114c3ac8998fecb0ac04358a600ab95a1f7c2c29b3cb860f1e49492064045b3d5ac7f5681d60a0b3034739410d2298b7945259621e82f1c392944d524d08868f3d7339e8f21cf36a04c194c469e6b799806090934ce5ae20fe54c97f602cfb51eaf7e92ed4f08149763eedbe7d524e41433f525ac10d203844ac0b23bd30b68e0e778297525ec2115e18af47d8e535fd3c9106f9915d183db452742dc12a584a17e6f027aaec7cd2a25e322319c985b9ce3c9a52aed6173fbe6820850f23b8308957b32569a79017d18f04c4c82d4c49b2f0259d3eed20466c61b4786a77d5e563877e4b0531520b53143dd53f37ad243fb430c83149b762ce943ef12f328dccc29cf424255d67ec65963630220b93cc2b134a5a5f8a796261f48bb9a03be8b40c25d4238c10288cc0c2549efb49095f3f61e415a6b25013d4ed8e7c2861c415c65ccfd17292f05c2902e2430c23ad300525bce47cb54661841526f5bf6e2a2f5bd0e2fec8d1cf0305ab30251f9f139784855c38b111559893a538276ac96b8c18c6e1f1012b74787cf9e1038da4c238db965642b44e7f8a0f0fe0000286115498a46b854a93e4fd74a6d2c1c38708464e6150829624c737c1e33e640ac38c5afe4579cb22ab521854284b49ae84a43027c164ab87ff4661bc3893948c5c14a6f59c249dfbe3973ca25098c436b5e8257762de091426b9644b25e79cf209e3e9b04a23ebf38429a774dfadeff4fee94e18ceaf24f595933861b6b8a2b326afa53f073a7c81914d982d9a30f72de144535313a6a05a9d24c9c4d29b74264cc184ccc5b25b51dfa31c5fecc0f1a30a130613b9e2d94e05f913bc84a943c830293ab58439d8bfa65a4ade36da4a98a4a5d98ba33c4a98947021eabd52123ba24998462f695fd0e99faf4ac22c965ed9e265118f5f772412a61ecfb95fc3ced4c008248c66417e8e6cc58a3a1f610cf9bb120d356fff3bc27041e850426dd344b51bc127259ebeb82423cc1f743e39c5ba08b3fa68bb9e753ba952461461ce637ad20439b942e94612c1769c5cb9e39620ee8305910c2388309d972469cbdd398461cd3ed79af0a8161c318449ee2ad38d917bfec1914218446579fc6f3b3092eae9cbc530395582914198e493632e77fc92246d4118afd48bc9414f747be761740ab8de475f20cc77d57e324d898e00c218262394d0aa281a8efcc13c1f53d7f3e89cba94113f98443fbe78927e1f0c26da29979d4fe3f1f2c1703a166b6c652fe97b30e758d228fd20e7fec5113d1894c7cbd1ebff46a96b240fa69ca2d77dfa77040f2659d153a79253fd6f8fdcc1a4adf345b78ec751da881d8c26c5f5363b478552390f8cd4a1204a924a743027ef5c25c99332079330f7db8abf1ccca3729a0ea14f8fcac93818fed35fa6ef8dc9965d38184cd885cc7c5fba5e70e40d26f1837eaa7c6a3798df66c487bfa8b9e5b7c1643a64e7542a695c8ab3c1a47b92f894f6170da44c30b2069366a81c7fd4e25ef0a8c17462a8b9a02b49addea160240d66958f69a3e7448341c8fc5ade3c953398db3f25d10f2b33184beeaa6893c4351d4d6ea8b2192983692e689dabb9e5682f8e90c1b49da4102f19f711c21b3a320693e8eef1526bb665b7c4c0a73fdd901de53098c396d02f11236030a958624e7d8917458c7cc1542a89ade996e405839c146692d05099dd76c19c6f4d0caf0a2688e570c1bc32f621f2eb3edb8d8b18d982d924ff4f9e6ae6f38c3162d48816cc9957aaa1251ec986912c986a3d898f23ae047f93044246e003f9486e040b06f3eaa4d354bf761243367800b151367205f3a9fd85ce1f4c8fb6818c60c40a9ca7b43cfea3a6b29a63a40a275f33f994a56d840a26299bd24bf9e229184f50164789b25d423e46a4601a51312dc3b2ea9965240a66fd36f949fe4eba3d747a493002054c95bc5b252d9bec8b912798e4d9f9996cf65ed972438b6b8c38c1943b7bea9f42d9042cc42d8796302b27699aa46f94d8e3de790f30d00d469860b492faa6270927552d1859827984272557ea0e1e3b1af50823845330a20453d256524e0962aee4732409a654f92f7ba258368204b39f1493d324f19d4f3c3cc80f1b3f7098a11e61842425839123186b945c73d2b64018318251c5544e65ed69f6d22b868391229864c4598bd9a8341821824176ad5d9f75caa38d731a0b0169202f004129203bd00e1e3d74f0f8198c0cc1b46e75a7cea2a8b74708c6bcd6ad18d2ed939807c16c719228ea740682b9838fb0f9fcc0a43b96e864d11df181f10433f56a49701142bd3069f924a53495273de785e184dc8c53e279de0a8c28a8342e66c3126928188a0402811804d1f0f200e312080018482c0d0563d17054cf44b17714800374523446362a261e0a43c28048240c84c2600018180684c18040180c0cc5611858d218d50f0ad5ace9556cbea5968897637a7b5c21b0b960ba3629b07083c5d4fd11604387731aa4121b5066c3ce297fa3173e531fd6f49563058109a84798101f36f290fdb5774302241e96a40b9575537c53b4ea433d7db1f5b4cf54b091e9a019a7a8ec307db091ed6de193526d0f9ad80460db33c65f8d410c904fcfb15ae2e36749f82b02598d64b71e1a0e0c49ffe25e7ff9272805435713a031cef9caade00a8a290643148ff9934d3f7f3dda3cf93a4281b0bab24e6036e2259c1ba1b6ab7fec0651478416709550dd3dad7d8a79166bca0fa8a86162a74d5660bb9340bf5a410e57cc68980975e9a06b576bb994cf6b7984d240acdc93b5adb56d013ebba1e1ab613d489de0cfadee03ec7a3582058509ecb980f437706c6009c9ca616f5723e62b6941e42ae95243dc4f2a3a8121767509049bd8825228bd0c4608d1695a598a06f1aa9c363d2a23f084d2214582ad9a684c2ab9cf310ca048ca23804fc04019e27a1a38e973b2048dccb04c8419ac4168f22491e977101505c04dbc269bc0500c7fa27dc5fb1bddad7e1b1c0dfb5560fccf2ee48ed55d79f3bf3484220339203879f7ef42864f07f42fcf461912faa1889ab4389fc076a5a49702ee80cc67569e22a8b1d5c319364475f5762a07ffd7a1fcd22371f2b9dc9153fd544f8874802ec4fd46635a423d37c1e0267077d71b0424eb4b34bc386173617f90501b9a3ef55087cb5532e264e583db624e90cb0a0f6423c99a3bf460bdc0acf7eb1bdd579b9ee5bfec77b5d117b745c4e71c67c3025ea9a3301219e1328d2452b88bd4c8a55f4a880165edfdd4c443d8b0b14a489f7afb251d1cdc34186944248c864d75b5485665e6caf36e7ed5455c606eb91fd7fb8a8f34cbc2eabdb1c06539eddeabae89b1235b7f26bb699c77b35db31198e28082ea3f4c463ad31a8770101dafc0126062450a68f76395e877376023ced83cef1feb776c668f314b0422377f5dfb441a97f74f8bbff1fb991bae922d13b6167078aa0e53ef2d00a6fc60eacbe0b0e6bd959bc8e324f6b3a3a76008c4fc0d1d34b4c821c3025a536b4e9783336344429185a031c395776ddca4bd4511d9590f15f4f21efcb53beb1ac2aa3ea86179ebca4599dc90c26581e0c830896393fe2a7b7f4a9a747fd47a79d021c64944097350f51c9d164b7f2efac173a37c6b8682a5fae862f61fe65489510c591ac111ffb433832d36b6b8625050f00134a3ea364651fd80fc6aa571f3f5c46fd88425e176081c8ce5b6f24c991683cebf548088a7e7545a5abbca0185cd63d4df6c6745d86b91d4c0e74dcce1ecca0ac3e181760720630d32d4216207c5cca1557a1693164b18170c632886b9efb7a4260080a0292b2f38d1281366f943b96bc26c62ddba2afaaa5b65dcb447ec8d7a7da51403d9b72866d9136970b0be6a6ca5fb398677d3101a2b629b7572b81c637063e74ddc4b97d6de2e2440f17b68596c85a0d3520caae076e7ceb097a3f94f899856c9e259903dd55537b4c4d017614db71821b303e339f2ecdc363649ebb3617f655892ffeecddc415b2a0a608e8c3bddce700d77e9311b5c2c196596a464729657a1db27487afc21244ab8808eb6093f0cb911e1c2e075fc712046bcc02fb726963e1c843017bc22b0ff46031c7bf6f9925c31d1b0a7da677cc29b078d7a5a36f508e0e58af21dda8a1026fb319a5c5f563f30e02f34f3e0158c2d6e6518dcf1947049bb5e8d62298c534dbe6cd6d0af8ace115a093cf210f1c2e00f0a1e0e44c464dc9c0b2e2212f49990cf15263e30eebfdc9ed15717e63f56ae189aca7490495f30abcbbb2211a4f9fa96da115bd4f8e0a14f1c6e2761993c7eea7ef58516140a735e46d2d7fc3825046f1b4152ae71fa291a218679dcde894d30ecb29b19239de1020af538702f3909185bdfdd5b2e241d46bbd4c024af848eaa4274443ddee2e1a0f8452ad82a43f99f28b859027ad7a99fcc9603563404bf896060398f6ca1f74fc310458f8cd9047af03b66ff84853a1a18c8c0dd1dfe702c568d38978f58c3665ff3ff2d596ea0b4384ba516f20473fbc562c4f17e11414f6417f0c202c5cd9fcec061704691e23206e7198301bb0323a17e9e242b33f60341de7a7caba3a67cd48e978b8426a77b2bf92ac9358c6c0c8dd9a50b749b59a83632778b2f0b7a0320c6f2c4569cf30246b456d15258089f6e215e12692bc254de54c1475e25d285907179bff38b897597f65135045f9631627137cfe91ed212fe706821e0faf9daa6fd6740be27a2d7d333546e50e96f853310b461fb2c3343b60cf73c7d5387eab053e3e729a30fd030b043afccd4cc08c05a91312983917aa12d89dbba1ad8533e4deb2ad0d9c7ed23e95fcc27aac19bb83b2fbd9e18157b0d488cc0a8e93d50d215a36eec62bb6d0d51152ce643386a9628ea5d2a0ad613b705e066545e985353ae51e4ba4db68337674c4710380b8bc82f643124b50d6901c747504f79920e31b81ae161e01f584fb20cba7d503ab796e758c78e9d8946d546884369144e81fceaf52ce6731568d5d3cdd374d45d1965a691a9e1dd5288ad2d941526b0e43e2f70dcb1dff86210aa5e38f6bd6d864eba7967bd65838ccfb1a029e040b1331686448e188df4596fb7ebcf207f606622eb9b70ba4f57c0f7186c709cb7f584ab491f657c93f3d6bf452aba4f9252923370d7649b7e35d647e3039fe965f09f12fd564372def5cff32abd128ac51780a5444475683e8c6f93524276f586dc2c5582407c4dd8e1ccbe7e81fa49fc9841fc8e0313235d9d32bdc85a8a9df20aca93e6a20d3042515122a5a29a06490ed555095f6182f59cca516f8d6697cb9a6fa4c6443e6fe1c85a587240490e600388fb9c527b2568d758f479818727ca37bedb84feae6f02f77c625b045bdf1a89069814776a88a8a0682bcce489b595f9a2703c1bfab40d1e8d07d8ec551e49c03f1404aa0d273f2b47764a927efaef2031cc1fb165c923c0344b5755be4fcce18e9694ddc7d2a54949c4cfb29b6bfd2ccb23c71c84df3cb4cd387bf846184bd326d226e911691174286855e838a6261b5cc4b553481e57ba453e473a4c023db66ee709d276b1e6da870151ec73a0e98faa62887fc76fb082c9b29ecf5d3c05676924db4aa13092a5e259dd6dd5ad9fbf99cb86d3b3a672738e02f92e0f4e4d7883ec3de446a401f19a646d86410444a38c58b4ab1d73f6958dd19550cfa8e1b1a37ce2e6e1f972071f85c9703f5a4f9f11630e60799303015ee767f385e82183ca7fc7ec756706d050c42688558c20b963904bb25e2802f488279b8e0da900c4cbcf0519250f4add5331aaee4b4b5e458251f4fbad98b1cf8bd7e608802360652396c9ef8a753e28e0bf317b911daad1324c62263006d42ec5ec2cf718c09324b963d152ff67a0c67124c9623d41ec12e55209f18512bb6055b3818be57b07025f91c2a266ecb58b77c607414554b6556d69e687a187fc22fcf377a27468f273c6622b6aff6c0db6923c35cfcac873d522460bc9452405cbcacadf74050d61a413569efc9db7be68931b9440f152bfae85d5845e01630db077db492f693b3bc5ad4ab15d5c04631f0b5f9afe25c473a7567b09a3b3579d3eea8ad1b121d18e918b65f024e6b1f396f17f9fe0fbfa8877cc460f624071101c2efa4b9c8a9b5063a8f622d35132a7b7fe1d08dbfbb62d9170741bf0caf49abdb7cebab6e2cee98362ca4192adc8c2b22265ec2d774a2286251cbb218449646828cb0d4d8cd8e9b148905a7cf8911613424f7445f32bcc8a41daed602b6471199ad892a3417ec9549ce102a42feaf7b830a5464c148677c14a0fde4b223f7b56bafbad3512f9a9e3277464b91cf9c178e528b5b0a9e9bc7ed75f97a1a9331a00cf2c1e264d83f4cd62e16381afce4f65c3fd0a8d7256035c0b6735fcc3981db0d20b6365819a821e60817a6641f5da859132a9e336ba4d61f5263da82dc096682c0e2b15983913b26caafa504b339dab773d78aaf2ed6f15cf20af0ef1bd29dac265fddfa2f175ad52913706dd84ce4245cac98c9a71474d0c15426f3b2d5c814a52eb32f75f00292f53875e6f8c2c51c787ad45cb42b420b1f9d427474dc013ef7507e2de3b4c9cd795447090bb689bdf456ab7a95d0488acbb87c030ec4042aee8f154a447ea67c4d5cb6681d0c598b383ea74eff270cd778541d4fbb6150d5a11efd94524d0b4c60be318cb984b8432d1acd54f2596b3245c9a881610d3ce0b79887e5398c1b68e9483bc03dc07cd283aa4ae8f50312961f29d78724778359132faed3cf7c4f4128ce8b14445c9d598ecc134b45d124be8af24286c2e6966c4bb7ab44a3b0f3b8e6d94f80b2fc72014ce163536826065a5510d1892938aa84f7affed0b24cd5dacff7a879e01d3c37d357f7d981e624135e0b17e961a7f443648a3c9b77a969768b48aad857e1a1de8a2c31c2613e668acf6a045c5709494b934adafcb6e958411d5fedc4a1f9a3d0819cfb94bc799dbcc80dd2cdbb67c9615b614eb6c05a127b3f8f52a8e29bcb480ae3e1f952d0eafa67fe5738b1de84331069e8e7ecf2c3b01a6ca7a756f8a1b41b6b9f8deb8816924072278516e42fcbbb315b2c0aa5d78c28cdfaeb2d9be1dfbaaab8d150da46c03e4b38862db86ee87c33680e94adc7b3b8e52ed9a7f7de4267e4afbe89add5069d44ca0fcdb88aa44828a6b5309f5b96cf81906094ca1da41d285956c391adfca4a6219009a5639136a33b6c23c93e38f2966bc69a9b5dfcc7b0508dde011cdf023dccd1ca0a6ce3c619063062ea1ccbbbf4fa9d8f2abc9bfbb64e4c5eef2dc258d600046746cedde612b647314a7f84466878bfe0768e7ef0d759c80469ce8940481bd405739bf96fc8cb4e10ef6e03bbc4d87ffc30dc83276b74cf1fa54e41d7f240123d4a33e427fe3c8d46138fd9ad16529686546b16a033f89e2fd6f38516980052ea1b6ca791f29b0fa1016a9aadd7788bd35a87b2bc46e9d074aec24da13e0fbe15c8450982710827216c150b83210e0e6044a249e38c6b05e727ef96b044ee37c47445864336c8e20c9242e23a6edf75910b5367d390a6cc7923a15ec0969aa7dbc0dce5448c83805c740967b1d592d1946958c11c7b188e55ac2a798887a5436838569676c664b11a17833e07825c0c64e69c3d7df7403d6c08476d4e83a803413e3ac661928c12112e0f619600f43881fda5c481892f6bf857b3e08c50d0fe2c2b6259277ee5a00db63b5f33aaa67ce4f7f63ad7b987170448cd720141b68a4bf548be8ba9fc2997454c8db19f917d4741c71ac35b112f0b98cebd29099af540ddb4ecc16c5b2a8094a768c4e17b494b044f20678de112e1ac8f441ab0330e3220667cb6d5603ecacbc8bf3d497b278d00cfa17ba744df4ac193177c24c8db81ab874f300b57e6faa67dcfa8921c61829ec7683c07525bc7a5b061f4b901f546ad08cfb2b7cf0367d901511f7418ca9c518103e5c0e8e1b0ad8559a934b27dc5be387bab27cca4d1101d0e5645697af7b2d9e5f8998da7fe751d3357e85507f6cebcc63c01aa692a684b0d108372be804a58674a550ae6ba02d0cc77b21dbcda2146304ca6813a4b9e8ecf8025bed06a758a35fcc9d4a04e0b126d2af57b26ca1b69ef001475b3f7d5b56f464bf04c73f095f73227d1e305c7761eb4411373458d1c5e26c6632d049b1cbbd89daf1a809358417a02dfe429016b241d4b97f37f5d8410be335946d1a02d1951dd8eba0faed43a6b79508c748cb760ccb11de40cdbb49cdbb13447df34ef1173414491adb71dc404d524ae4aa43116c28e5333e461b6d8daf3bccee8b4605f8d6969129931920c0c8800767c597810afd1433264209034f39f32b5d22b4056945522910331069ff7d2050c28ebafb1296a7405ae435a8d5e9c7e7a16e6eddc0f0e7724acb5530c68659b28aecfeaabfc7ae32b1aaa57c244b0022a6a4aadad6da0c37a9cd377e5221d714a18c078ddf9888b9b40791896208c8105244d365a58887559a2b293d106ef402e324629fff0ecaadad15f475e8faef0d01f88e48506d33c9bda23a7d26150eb26cc735085ca529dd286e30a0dbef7d79201621cf633733cd62b32fe96a89d7f8c7e40ccf86424a332315dffe266c7bdd34b50d508c499c665a6298541fed32ec84dc3c909340d40934610e14a7a951a0934693fd55719ae81ec401486a87cb2b2bdb5505e024801a605b04a88d9a2ac7658420230a9f1fd5e0272b442d07da1d07025597366d289e8db54f80f96cbf11cff6bcd040dcfd5037df19dd5053ddb6de9a08d5c5305d274bb7779d774c5a3112db2065466e3ad29ad9dc6b0068f4c8ab517bf19ecd8900a097934b90343b2bb48b1994982731f29a3d6932908f64ff1d2254a76472790e5b7b01d26952cc8745c9d769040f623b122a118442355097e7b822e50188359915d5de4060b50092299c03ed8522ff29773d055ba32a062cee66b51ee133b6877219a20b230b23ef6f3abe843578e305f7b6344a5c3d452dcb8ad95a22f22aff7de214184fa6d34e11c53c89f5a444ff70589e0310379b0972d5ff0402ec9f25cd688036c072fd413f4a54cc59b1e9174a5f000179dd23065469ce6f4f177af5ac512bad930df0b71655e9c680558aa079643b10366bda5ef6980a7c27021eea2759a4610e35545e464448179c93dc684ec84e8598b2d0a88c12c584b9e51984a961fc27bb99d74d5cb80b2e7f11a6d38513ffce135f4dc6298fea1ccac9c708dde669536b1f0725b2f263730a4e00cd98d6457c7e1a59437701285a05b6bd09b0400a5e903a4c884d67e81726e246b8c82fe6126a7b738afb63287bdb02488c638f296a4ee892eec53854c9a246f12df68a143b4d22bdee08867c0d85ea2a04892bc89df9358cf15b7dc5da8588f74a6d521f420f427816c13efd2e67bc5d4eb6188711b571aca9cb8cb30a9fa41e7aa643202eea10388407bfe5959377aefd61576c3b34364f751da1a1d5dcb45363115a6a036815fc34b85e8c520d6f30a43ee14ddcd940c36f8205cbedcab78a35ac33455704a5ac35ecba884d300ad1af597f3cf3c876c03c68072a782599656037ada4addd72ad25930406cbed57f7ddc4a0660e7c9cb0f982a51fb11c92d9d899fe22c38cac09a63f559e5a66f74898d5e851a1330550ff8a70b6b0767157e3dc662146ae9812199aeb595a5db7e59c7574606a1f885237cf14260b0e6817bc5bddbdb3b3842e05efacabc06a863872f5b55e92acd0d832aba51bd9855d9f61938d22e13d0c94377d0a53de52b421ad02c34459f8aa0158e57a055816d71bf1205f194199dcc2917a542dadef3de0a5c81a3d0552dc69ef154ce1833ec39ee854cab4f6eccb2b40f438d2e6661bd28b019f05dd90a1aace648213a7adc1a1a427c8caeb69f7b96b25404a69ea48a48ac1a62cc99f7cb89846ea624174880bbaa7e2eedaa41ea62882fba980ca2c037478d569a1d151303ae36fa78f685bed224dedc281d7ee14905efb09603a02d238df697ca795193cc613963be0b61730ae0cb34d24c3d90880e3ef6a3f2ed1c48fd7da0130959b9a53df5701aa17859114ca80c27296db72ef560cc3c9552c57451918f25be1f2416b45e3600ef4bd4024dacbbfac68f2bf6b236a43c8c931752a94c59cd47ec2913169dcac17424836105373c036056e4c04f5f326384bd641b623ec234ae3afaa44af67b79111798ef7da37c8cbfec6935052f30b1e5cfd2309026044f6f3db339a6cd3e8ef20599683d680ee901486d1518510d2c569d080f85163d604ca407d2e0fea6c4a2607cb727c334dfdcdbb97fad255429b6254171d2814a0ae9aa622160b20cb4531b3b341cb6be0c3935653808d5a96ee30a121e0c34fb097a4c35e1db47febcad1355c4da4504e3b676484b862a06581551e867d9b05fcc796baf47911df28adab3bc5fc8f20f160946e434841f6cfbbd7b899d6e2ff96959ffa667268a0725476e2b56878aa474665a9a81ef4042cec7e5ac3e7d8aa4f57b6094ef7fd90012cb0f6a9367109128c935b9a69325f694577505e4c5551c1066568638d4ba820ca3000b77aad54198cf8740323f049d409aecf41af14d3e2d799f36ceb20bf4a7aae1f6f200a195fefe88d83e0d04a2afb0b1425479372567f780699f7a608d53e4a3cd2b52efea21229904e2bc9f3752bdfd5ff8d2d0ca416bd98ca26a4e17d2b05d15cd7580247efbd086a987a2da6c16df162e02304250590863f0a3c33cb8a44225208065c6bf939fba4f6b7de68a325cab76fd6b8d213d528101430300ca190644ae0b5481cf6338b8b76d9c28d6cab464ea90026f678edb270b8d5512521ad231cfdd4f7b2c64272aff9a424351597f7bdcee14a9de2eea18f7345f923a2ed4331d3be48aecc650819cc0b815c4080e9d1bcbd781715283de7433de50cf38c94d6fe21a2be86e013b1ad16860d4f27cf9ce4838e084404e79b3cdf6d142410726b6eabe37d3cbc5b84eb58d55712c0764e1498ff680195179c465c673e2d6bbeb200e12824c6dac7414df9b2656e240e9fc5718adcac0ac1759d5ba1d6d6ae4c6945e7bf173de13bb9aea8a33da99badbc5aaabfc45220ec1055362e649c87368e96e4c10e10a8269063e8f213663e22eb3c312cb980f6978a998d72a54b65672db5590423e44d6b51f53a1486f0035d74f793ff5e26a3989b4a5799346a01c8fc3155610bc06168b683988f69647c865b5573c5378adf519b95a5755cb234de4cc4987384c8f5fe218a6d4e17c706e17a51fe63ae8996bf4a2fba12b5e0c3c358bf75eaf95f5313d70ed5b03c3f2d092557dcbc98a3a35fee6e58def36c95f79209d90fc4e406e48f43814c6e3da6a711cc276c88900c129c620e2d0382014c7a1f6c91ccad8f31d4d964f1ca80ddf43888546570a05a63be0c8ecb21782383a3c9a8108b01e23d31334067a40e125dccc69b444f0446e3304dee522d16204daef33a970f9adca0331ef96972fe2c1930c224376e4371ca220a09dd1b4e0b4a8d358a1815296ed02abd18f88381a680a2f1e9a921614ec3bf895d69bd7616e586d96c49dff0539acb4b1c5b4f6e2b0d3a547419d704ca6d2e412e2d4c8639b87c14cd8d836979812b8c7974a560b6ecf9136802299487a37e230be5d7ad86a2023f4f29e9ddc0d4c9e5a956e081413961cbefcb6c1e9d8df5a2a68828402f95a67ea193034c7202fe990c4df0f7715a00506c4c85564b9bd8f2723a078d626bd9755e62263c9c0d8f64a528d2e06ccdd3b023d404f53e173ceb7f2bddf0b7533ebc32039592b96df6e8eb62a246a04f4c868e68e198a48750c1e46dc890e336cbf1b9952b961434142d6ac3d973faaf2717a056cb32a03c60d43d5143270284a612bcdeb4cd908445154c065b6bd2f545e91c08214fe49e3a17a0bb26a9089b2748455bd0a9ca2172df6d9c887c64c6d495232c99f4ec307ca3cf19dbc4cc84bb5314b3ce7644ff518e71846f3aa1125ec10740411f2de86aabb83896ee8306a5d7850810d6b929d038265e170facf3ecc560ee9110bb64010697a490c6091a1b2f6675aec861df146019817d02050a09d758db403fc071079f40179b426e575d7ce081b81ebbcce6336a0dfcdf133594ba1b8eb08e1d844c03696072404ad590e6f2111190470e30208a78b193b3878b033c65a6e30c00e84fa6da741eefb9041d92f6ac8be63a57db47928396100a96b7b78218f10c0bea85cbf337c2b55c1876855c505581c482b744af92094091b9e4170af776fa0c1210fb58fd2660592f06c460bcf19f9a8695c2a29597e720dc0110a7a155fd1e2f5da3e1279e36155117bcbac9cf7ee286f9386eea3d026caa54e989c8fe11fd86b7c25b2b0cf05a7514900c905fd2648f8c9d0a0ee0e48c0336be2be670fbea022b1ead0602b26ca3cf431918b9e9ca18bf98d2a5032047189be478ff8dd775b853f4a748042151b137cc1a3bf6ca6eb01f415af3814f6e066a38485014ac86857149be53d6118ea52cde8d3dc06515adf9e7b1fe697603f6c77a169c177fe11698b3e9bb1191d2170e3df9fea2457935eb450ae6d169cff9e4cf83101ebaaf8314239648df4c2a45596692a6dee4148d40a144675bc7c7cb76dfa4e81273696e3049cc4dda07f056701e4a23641af4b4a4ef496df783ea11f6710226829d8fc79c50204f6912a03a6584f88c0daa3f129dc2dbfa027aa4e69e74bc1f50c6d0b09621f1ca489d9c49d04afa4796330e08e1f4f60f826a303778542a5309317c4b6f40c642bdb1207b73610452908ef3700bfe139cbfe245ac8354d00d082e6e538cab0559e42b33dc7c0937bbe2424e378355d512a7dcf3aeb66f83d87cc550d44c027b1fce584f99944b1dc1328e155784e4c5dbb749ed6b599a48016c7bd4ea182d6afa29ed1d9a6614ecfcd21814bf6b64c3ec318c49bdf1ef6d04e5e275972f06cd4a1703475d58ce5f64665636d590036b59a2468f212da2e0febfc2684eceb06ea827c3f2f7271333275c58b47993fdce040344b189387bf324a8a75a7b35a5317a7aca928406ead9c46a8a099e2113ec163e63390d990e12a15a9c3796f3a36928aec148f4303665701b1b9896cacb572365a8e980f68ef71d7dd054004ace069a4b06ba465d74d7aa66884f714ecdd46f9951b16af66b32e7b46af2d0c7b415ef95ad2bd210c8e5df6015169ed0c7f3793b5a13f51fbdb85484c7f171459297cd34f545fdb7d2d629b13e595644102bb379daf5d0b72e45cb7998f70ee7e8b1216338cd793397931271e09c9f9452d26d33e1f884337c56e86416b04f0103c43c4d7ea0e64de43e852284fdfcb2b4ac08396cbca1222277a12c85b41abbb348c712351601767db5981a11581a6d6084841cb8db75204b8b22428ed10bb8cf44455018219b7226aa0ea16ce242c64dc5b919164074b431358f3eeac8f21f325550c749b296fe50c7ecd313a65047bb0d261a263de82e625806d71cfcd3efec444cb1431931614986abc80ac5f4771cd0987b50e3644b866578ea2489e145c6016f605f59d35bc7eb02728dde8e926b97cd2442e0710252d16f3b55642a96adbae97a51f1cad87727c772520b5d0dfbbea52a56f70a0255ed244881954273376b5d0a25607dc396dc3d86d5a1ee8b434be07f1b078132ce295e9170bc0e2b55f2e220c8259dc0932679c53d9f6472a2424fbc2f3e54dd465d9da9de983a66303e0b832590679160857c26cb1abee3577c02d5dfccb5eb13a179ffdc6c578f8fd6748dd09ae33ed9f5758ab2d4a80c77d0f55c7d6841d07144c24f29c958ec616c04e7b220904f9b14b6ca99ca94514ef0acb1c0530a198469824e3b2b0b2fc998cf258481886eaac3de5b22b44c210c81cf121ba8193da3f210257e3c56da40c4e3c48730326a9f49038091ca5320e02263d8a463cc2361084746b33ec737b62de524f39129b625034cc621ca191547d1cdec765171d2a7853b46b622d623a765f6cd1d0aa4f8c58221cd9212c940c793653f697fbc9fffb0094b7a7fa35017ac746f911111b81804fe97de0c9ef767455bbd9c79d89472a713e4b2604fcee333f4e14180c3c83a2c2c47c1dff33b125adfeda08d9befa4159afc47c2164b02277b6d9a9f8fcacc73101814b364e9657f0570bed38aeafdcc4018839252713a2713fbff29405c00619f443d238c98bfc4c58840655f0022026c3c00c437de621ff69233dc6c2691b3a53e2997df6c19ec4ef3e84c701846b7c26db684a8c8e4792e9eb2b449329061c081c6e6dae8b5d608c1b58bbec8d182f4a89ad7239d1722efd9758f164bea0da57a02fd57284e07feef4a02a363584908a98f8744788be2f53321409c984d38150d187b92b41b6da66292a59a902051a401883536696a77b05bfe49c99ad2c14c60ebb88fa5497d29084fe998b1e4e06c30e432e5b807a9860ea05a4832a9c946b64e9a8c7427af78a318806588174406c26944519a137bb3cb1f511f81805f4fa253b6e3a80e11f400072a56a80997c5950a2aff5d4d608d6a802a02712b32cc403e7ae417191705850621dbf7e776fba41bb6c0863e3b6984e83808a1b8800b044fb15d8521c42c4062ac2f12c5a452e10b06a10e8a6c09154aedeb3d2a62eaffaabdd9d24021b63a3a53ca42d8af85154b57b36068db9fb910260273938a589c95612d99657fe7d12c5bc74900b6b0c819412efc1d6f314d1407432a85ff9b03b0589ec482a7f15826186d15cc0e98a56a85e280cd0b2de3eb26125d793aeb31561a89c585abd1655f1a6cfbaaba1a003239c99d08c904f913b029107c81e4ae6a2e872461973bfec101c1cead1fedd7e03a59989a170f111ee0c53577ba692518022f2114f0e245f134c2537513480669091c782091c4ccba50833786511c656a5137576d4a22721987020c4281ddc2d69eddc6da3482291cf648eb08859796dbb2429668a6b0803b8adaf55800165c22402d42a0f16b67e0552d84a5d2dc1919fce46ad68406adeb6c20c0a9a96ab3ccc63253eace6e0b9e91f3641033db89577410300abb0747095cdf92084e71d39f96c289f6a2ba644238e99e50205812125d1e90a83ddf50f7f33b172fce4255de39956f9918ab11c405dcc128a4920a00e86759322acc262b14acf04ef3c4b39a8010378bedf0cdab1d6b541680a16f942c02824c357a4a0961ef80f1850439fb1468cb481010ef28f8169b76dc28adfa9d23862e02b0c92b240247ba800678125ac2beccc808391d05f6e4be6593de6cd98ab0c98d82563b3cdb4d1521429d25b27522a9ad14b788291d", "0x3a65787472696e7369635f696e646578": "0x00000000", "0x3db7a24cfdc9de785974746c14a99df94e7b9012096b41c4eb3aaf947f6ea429": "0x0400", "0x3f1467a096bcd71a5b6a0c8155e20810308ce9615de0775a82f8a94dc3d285a1": "0x01", @@ -197,9 +197,9 @@ "0xd5e1a2fa16732ce6906189438c0a82c64e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0xd77451b0cdabc3fb7fe20813c2e9ad4a4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0xd8f314b7f4e6b095f0f8ee4656a448254e7b9012096b41c4eb3aaf947f6ea429": "0x0100", - "0xda7d4185f8093e80caceb64da45219e30c98535b82c72faf3c64974094af4643": "0x0100000000000000020000009394784c9135e2e98a0c095ce594f572650285069b0464ce74c83befcbc17b71", + "0xda7d4185f8093e80caceb64da45219e30c98535b82c72faf3c64974094af4643": "0x010000000000000002000000697ea2a8fe5b03468548a7a413424a6292ab44a82a6f5cc594c3fa7dda7ce402", "0xda7d4185f8093e80caceb64da45219e34e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xda7d4185f8093e80caceb64da45219e3c52aa943bf0908860a3eea0fad707cdc": "0x0000000000000000020000009394784c9135e2e98a0c095ce594f572650285069b0464ce74c83befcbc17b71", + "0xda7d4185f8093e80caceb64da45219e3c52aa943bf0908860a3eea0fad707cdc": "0x000000000000000002000000697ea2a8fe5b03468548a7a413424a6292ab44a82a6f5cc594c3fa7dda7ce402", "0xe601a78caffde57e00752be8864bc48e4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0xe6ff095c8bf38992ef748b1037a308af4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0xe8d49389c2e23e152fdd6364daadd2cc4e7b9012096b41c4eb3aaf947f6ea429": "0x0100", diff --git a/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.zndsl b/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.zndsl index 6e733580d6d..ea0f15e5d8a 100644 --- a/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.zndsl +++ b/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.zndsl @@ -31,6 +31,12 @@ bob: log line matches "Block history download is complete" within 120 seconds alice: reports block height is at least {{DB_BLOCK_HEIGHT}} within 10 seconds bob: reports block height is at least {{DB_BLOCK_HEIGHT}} within 10 seconds +alice: reports substrate_beefy_best_block is at least {{DB_BLOCK_HEIGHT}} within 180 seconds +bob: reports substrate_beefy_best_block is at least {{DB_BLOCK_HEIGHT}} within 180 seconds + +alice: reports substrate_beefy_best_block is greater than {{DB_BLOCK_HEIGHT}} within 60 seconds +bob: reports substrate_beefy_best_block is greater than {{DB_BLOCK_HEIGHT}} within 60 seconds + alice: count of log lines containing "error" is 0 within 10 seconds bob: count of log lines containing "verification failed" is 0 within 10 seconds -- GitLab From 46090ff114a131be4139f0abf619330990194770 Mon Sep 17 00:00:00 2001 From: Liam Aharon Date: Mon, 15 Jan 2024 23:30:51 +1100 Subject: [PATCH 050/392] Unbalanced and Balanced fungible conformance tests, and fungible fixes (#1296) Original PR https://github.com/paritytech/substrate/pull/14655 --- Partial https://github.com/paritytech/polkadot-sdk/issues/225 - [x] Adds conformance tests for Unbalanced - [x] Adds conformance tests for Balanced - Several minor fixes to fungible default implementations and the Balances pallet - [x] `Unbalanced::decrease_balance` can reap account when `Preservation` is `Preserve` - [x] `Balanced::pair` can return pairs of imbalances which do not cancel each other out - [x] Balances pallet `active_issuance` 'underflow' - [x] Refactors the conformance test file structure to match the fungible file structure: tests for traits in regular.rs go into a test file named regular.rs, tests for traits in freezes.rs go into a test file named freezes.rs, etc. - [x] Improve doc comments - [x] Simplify macros ## Fixes ### `Unbalanced::decrease_balance` can reap account when called with `Preservation::Preserve` There is a potential issue in the default implementation of `Unbalanced::decrease_balance`. The implementation can delete an account even when it is called with `preservation: Preservation::Preserve`. This seems to contradict the documentation of `Preservation::Preserve`: ```rust /// The account may not be killed and our provider reference must remain (in the context of /// tokens, this means that the account may not be dusted). Preserve, ``` I updated `Unbalanced::decrease_balance` to return `Err(TokenError::BelowMinimum)` when a withdrawal would cause the account to be reaped and `preservation: Preservation::Preserve`. - [ ] TODO Confirm with @gavofyork that this is correct behavior Test for this behavior: https://github.com/paritytech/polkadot-sdk/blob/e5c876dd6b59e2b7dbacaa4538cb42c802db3730/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular.rs#L912-L937 ### `Balanced::pair` returning non-canceling pairs `Balanced::pair` is supposed to create a pair of imbalances that cancel each other out. However this is not the case when the method is called with an amount greater than the total supply. In the existing default implementation, `Balanced::pair` creates a pair by first rescinding the balance, creating `Debt`, and then issuing the balance, creating `Credit`. When creating `Debt`, if the amount to create exceeds the `total_supply`, `total_supply` units of `Debt` are created *instead* of `amount` units of `Debt`. This can lead to non-canceling amount of `Credit` and `Debt` being created. To address this, I create the credit and debt directly in the method instead of calling `issue` and `rescind`. Test for this behavior: https://github.com/paritytech/polkadot-sdk/blob/e5c876dd6b59e2b7dbacaa4538cb42c802db3730/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular.rs#L1323-L1346 ### `Balances` pallet `active_issuance` 'underflow' This PR resolves an issue in the `Balances` pallet that can lead to odd behavior of `active_issuance`. Currently, the Balances pallet doesn't check if `InactiveIssuance` remains less than or equal to `TotalIssuance` when supply is deactivated. This allows `InactiveIssuance` to be greater than `TotalIssuance`, which can result in unexpected behavior from the perspective of the fungible API. `active_issuance` is derived from `TotalIssuance.saturating_sub(InactiveIssuance)`. If an `amount` is deactivated that causes `InactiveIssuance` to become greater TotalIssuance, `active_issuance` will return 0. However once in that state, reactivating an amount will not increase `active_issuance` by the reactivated `amount` as expected. Consider this test where the last assertion would fail due to this issue: https://github.com/paritytech/polkadot-sdk/blob/e5c876dd6b59e2b7dbacaa4538cb42c802db3730/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular.rs#L1036-L1071 To address this, I've modified the `deactivate` function to ensure `InactiveIssuance` never surpasses `TotalIssuance`. --------- Co-authored-by: Muharem --- prdoc/pr_1296.prdoc | 16 + substrate/frame/assets/src/tests/sets.rs | 2 +- substrate/frame/balances/src/impl_fungible.rs | 5 +- .../src/tests/fungible_conformance_tests.rs | 81 +- .../tokens/fungible/conformance_tests/mod.rs | 1 + .../conformance_tests/regular/balanced.rs | 292 +++++++ .../fungible/conformance_tests/regular/mod.rs | 20 + .../conformance_tests/regular/mutate.rs | 783 ++++++++++++++++++ .../conformance_tests/regular/unbalanced.rs | 281 +++++++ .../src/traits/tokens/fungible/item_of.rs | 8 +- .../src/traits/tokens/fungible/regular.rs | 97 ++- .../src/traits/tokens/fungible/union_of.rs | 15 +- .../src/traits/tokens/fungibles/regular.rs | 24 +- .../src/traits/tokens/fungibles/union_of.rs | 17 +- 14 files changed, 1563 insertions(+), 79 deletions(-) create mode 100644 prdoc/pr_1296.prdoc create mode 100644 substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/balanced.rs create mode 100644 substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/mod.rs create mode 100644 substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/mutate.rs create mode 100644 substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/unbalanced.rs diff --git a/prdoc/pr_1296.prdoc b/prdoc/pr_1296.prdoc new file mode 100644 index 00000000000..b7ef4288a57 --- /dev/null +++ b/prdoc/pr_1296.prdoc @@ -0,0 +1,16 @@ +title: fungible fixes and more conformance tests + +doc: + - audience: Runtime Dev + description: | + Adds conformance tests for the Balanced and Unbalanced fungible traits + Fixes Unbalanced::decrease_balance not respecting preservation + Fixes Balanced::pair possibly returning pairs of imbalances which do not cancel each other out. Method now returns a Result instead (breaking change). + Fixes Balances pallet active_issuance possible 'underflow' + Refactors the conformance test file structure to match the fungible file structure: tests for traits in regular.rs go into a test file named regular.rs, tests for traits in freezes.rs go into a test file named freezes.rs, etc. + Improve doc comments + Simplify macros + +crates: + - name: pallet-balances + - name: frame-support diff --git a/substrate/frame/assets/src/tests/sets.rs b/substrate/frame/assets/src/tests/sets.rs index bdff5175185..f85a736c083 100644 --- a/substrate/frame/assets/src/tests/sets.rs +++ b/substrate/frame/assets/src/tests/sets.rs @@ -153,7 +153,7 @@ fn pair_from_set_types_works() { assert_eq!(First::::total_issuance(()), 100); assert_eq!(First::::total_issuance(()), Assets::total_issuance(asset1)); - let (debt, credit) = First::::pair((), 100); + let (debt, credit) = First::::pair((), 100).unwrap(); assert_eq!(First::::total_issuance(()), 100); assert_eq!(debt.peek(), 100); assert_eq!(credit.peek(), 100); diff --git a/substrate/frame/balances/src/impl_fungible.rs b/substrate/frame/balances/src/impl_fungible.rs index 6737727e0a2..0f4e51f3501 100644 --- a/substrate/frame/balances/src/impl_fungible.rs +++ b/substrate/frame/balances/src/impl_fungible.rs @@ -177,7 +177,10 @@ impl, I: 'static> fungible::Unbalanced for Pallet::mutate(|b| b.saturating_accrue(amount)); + InactiveIssuance::::mutate(|b| { + // InactiveIssuance cannot be greater than TotalIssuance. + *b = b.saturating_add(amount).min(TotalIssuance::::get()); + }); } fn reactivate(amount: Self::Balance) { diff --git a/substrate/frame/balances/src/tests/fungible_conformance_tests.rs b/substrate/frame/balances/src/tests/fungible_conformance_tests.rs index 6262aa04dc0..5c0c19a554a 100644 --- a/substrate/frame/balances/src/tests/fungible_conformance_tests.rs +++ b/substrate/frame/balances/src/tests/fungible_conformance_tests.rs @@ -19,17 +19,19 @@ use super::*; use frame_support::traits::fungible::{conformance_tests, Inspect, Mutate}; use paste::paste; -macro_rules! run_tests { - ($path:path, $ext_deposit:expr, $($name:ident),*) => { +macro_rules! generate_tests { + // Handle a conformance test that requires special testing with and without a dust trap. + (dust_trap_variation, $base_path:path, $scope:expr, $trait:ident, $ext_deposit:expr, $($test_name:ident),*) => { $( paste! { #[test] - fn [< $name _existential_deposit_ $ext_deposit _dust_trap_on >]() { + fn [<$trait _ $scope _ $test_name _existential_deposit_ $ext_deposit _dust_trap_on >]() { + // Some random trap account. let trap_account = ::AccountId::from(65174286u64); let builder = ExtBuilder::default().existential_deposit($ext_deposit).dust_trap(trap_account); builder.build_and_execute_with(|| { Balances::set_balance(&trap_account, Balances::minimum_balance()); - $path::$name::< + $base_path::$scope::$trait::$test_name::< Balances, ::AccountId, >(Some(trap_account)); @@ -37,10 +39,10 @@ macro_rules! run_tests { } #[test] - fn [< $name _existential_deposit_ $ext_deposit _dust_trap_off >]() { + fn [< $trait _ $scope _ $test_name _existential_deposit_ $ext_deposit _dust_trap_off >]() { let builder = ExtBuilder::default().existential_deposit($ext_deposit); builder.build_and_execute_with(|| { - $path::$name::< + $base_path::$scope::$trait::$test_name::< Balances, ::AccountId, >(None); @@ -49,9 +51,37 @@ macro_rules! run_tests { } )* }; - ($path:path, $ext_deposit:expr) => { - run_tests!( - $path, + // Regular conformance test + ($base_path:path, $scope:expr, $trait:ident, $ext_deposit:expr, $($test_name:ident),*) => { + $( + paste! { + #[test] + fn [< $trait _ $scope _ $test_name _existential_deposit_ $ext_deposit>]() { + let builder = ExtBuilder::default().existential_deposit($ext_deposit); + builder.build_and_execute_with(|| { + $base_path::$scope::$trait::$test_name::< + Balances, + ::AccountId, + >(); + }); + } + } + )* + }; + ($base_path:path, $ext_deposit:expr) => { + // regular::mutate + generate_tests!( + dust_trap_variation, + $base_path, + regular, + mutate, + $ext_deposit, + transfer_expendable_dust + ); + generate_tests!( + $base_path, + regular, + mutate, $ext_deposit, mint_into_success, mint_into_overflow, @@ -66,7 +96,6 @@ macro_rules! run_tests { shelve_insufficient_funds, transfer_success, transfer_expendable_all, - transfer_expendable_dust, transfer_protect_preserve, set_balance_mint_success, set_balance_burn_success, @@ -79,10 +108,34 @@ macro_rules! run_tests { reducible_balance_expendable, reducible_balance_protect_preserve ); + // regular::unbalanced + generate_tests!( + $base_path, + regular, + unbalanced, + $ext_deposit, + write_balance, + decrease_balance_expendable, + decrease_balance_preserve, + increase_balance, + set_total_issuance, + deactivate_and_reactivate + ); + // regular::balanced + generate_tests!( + $base_path, + regular, + balanced, + $ext_deposit, + issue_and_resolve_credit, + rescind_and_settle_debt, + deposit, + withdraw, + pair + ); }; } -run_tests!(conformance_tests::inspect_mutate, 1); -run_tests!(conformance_tests::inspect_mutate, 2); -run_tests!(conformance_tests::inspect_mutate, 5); -run_tests!(conformance_tests::inspect_mutate, 1000); +generate_tests!(conformance_tests, 1); +generate_tests!(conformance_tests, 5); +generate_tests!(conformance_tests, 1000); diff --git a/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/mod.rs b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/mod.rs index 56166436003..005674088dd 100644 --- a/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/mod.rs +++ b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/mod.rs @@ -16,3 +16,4 @@ // limitations under the License. pub mod inspect_mutate; +pub mod regular; diff --git a/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/balanced.rs b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/balanced.rs new file mode 100644 index 00000000000..d8d20543e3d --- /dev/null +++ b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/balanced.rs @@ -0,0 +1,292 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use crate::traits::{ + fungible::{Balanced, Inspect}, + tokens::{imbalance::Imbalance as ImbalanceT, Fortitude, Precision, Preservation}, +}; +use core::fmt::Debug; +use frame_support::traits::tokens::fungible::imbalance::{Credit, Debt}; +use sp_arithmetic::{traits::AtLeast8BitUnsigned, ArithmeticError}; +use sp_runtime::{traits::Bounded, TokenError}; + +/// Tests issuing and resolving [`Credit`] imbalances with [`Balanced::issue`] and +/// [`Balanced::resolve`]. +pub fn issue_and_resolve_credit() +where + T: Balanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let account = AccountId::from(0); + assert_eq!(T::total_issuance(), 0.into()); + assert_eq!(T::balance(&account), 0.into()); + + // Account that doesn't exist yet can't be credited below the minimum balance + let credit: Credit = T::issue(T::minimum_balance() - 1.into()); + // issue temporarily increases total issuance + assert_eq!(T::total_issuance(), credit.peek()); + match T::resolve(&account, credit) { + Ok(_) => panic!("Balanced::resolve should have failed"), + Err(c) => assert_eq!(c.peek(), T::minimum_balance() - 1.into()), + }; + // Credit was unused and dropped from total issuance + assert_eq!(T::total_issuance(), 0.into()); + assert_eq!(T::balance(&account), 0.into()); + + // Credit account with minimum balance + let credit: Credit = T::issue(T::minimum_balance()); + match T::resolve(&account, credit) { + Ok(()) => {}, + Err(_) => panic!("resolve failed"), + }; + assert_eq!(T::total_issuance(), T::minimum_balance()); + assert_eq!(T::balance(&account), T::minimum_balance()); + + // Now that account has been created, it can be credited with an amount below the minimum + // balance. + let total_issuance_before = T::total_issuance(); + let balance_before = T::balance(&account); + let amount = T::minimum_balance() - 1.into(); + let credit: Credit = T::issue(amount); + match T::resolve(&account, credit) { + Ok(()) => {}, + Err(_) => panic!("resolve failed"), + }; + assert_eq!(T::total_issuance(), total_issuance_before + amount); + assert_eq!(T::balance(&account), balance_before + amount); + + // Unhandled issuance is dropped from total issuance + // `let _ = ...` immediately drops the issuance, so everything should be unchanged when + // logic gets to the assertions. + let total_issuance_before = T::total_issuance(); + let balance_before = T::balance(&account); + let _ = T::issue(5.into()); + assert_eq!(T::total_issuance(), total_issuance_before); + assert_eq!(T::balance(&account), balance_before); +} + +/// Tests issuing and resolving [`Debt`] imbalances with [`Balanced::rescind`] and +/// [`Balanced::settle`]. +pub fn rescind_and_settle_debt() +where + T: Balanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // Credit account with some balance + let account = AccountId::from(0); + let initial_bal = T::minimum_balance() + 10.into(); + let credit = T::issue(initial_bal); + match T::resolve(&account, credit) { + Ok(()) => {}, + Err(_) => panic!("resolve failed"), + }; + assert_eq!(T::total_issuance(), initial_bal); + assert_eq!(T::balance(&account), initial_bal); + + // Rescind some balance + let rescind_amount = 2.into(); + let debt: Debt = T::rescind(rescind_amount); + assert_eq!(debt.peek(), rescind_amount); + match T::settle(&account, debt, Preservation::Expendable) { + Ok(c) => { + // We settled the full debt and account was not dusted, so there is no left over + // credit. + assert_eq!(c.peek(), 0.into()); + }, + Err(_) => panic!("settle failed"), + }; + assert_eq!(T::total_issuance(), initial_bal - rescind_amount); + assert_eq!(T::balance(&account), initial_bal - rescind_amount); + + // Unhandled debt is added from total issuance + // `let _ = ...` immediately drops the debt, so everything should be unchanged when + // logic gets to the assertions. + let _ = T::rescind(T::minimum_balance()); + assert_eq!(T::total_issuance(), initial_bal - rescind_amount); + assert_eq!(T::balance(&account), initial_bal - rescind_amount); + + // Preservation::Preserve will not allow the account to be dusted on settle + let balance_before = T::balance(&account); + let total_issuance_before = T::total_issuance(); + let rescind_amount = balance_before - T::minimum_balance() + 1.into(); + let debt: Debt = T::rescind(rescind_amount); + assert_eq!(debt.peek(), rescind_amount); + // The new debt is temporarily removed from total_issuance + assert_eq!(T::total_issuance(), total_issuance_before - debt.peek().into()); + match T::settle(&account, debt, Preservation::Preserve) { + Ok(_) => panic!("Balanced::settle should have failed"), + Err(d) => assert_eq!(d.peek(), rescind_amount), + }; + // The debt is added back to total_issuance because it was dropped, leaving the operation a + // noop. + assert_eq!(T::total_issuance(), total_issuance_before); + assert_eq!(T::balance(&account), balance_before); + + // Preservation::Expendable allows the account to be dusted on settle + let debt: Debt = T::rescind(rescind_amount); + match T::settle(&account, debt, Preservation::Expendable) { + Ok(c) => { + // Dusting happens internally, there is no left over credit. + assert_eq!(c.peek(), 0.into()); + }, + Err(_) => panic!("settle failed"), + }; + // The account is dusted and debt dropped from total_issuance + assert_eq!(T::total_issuance(), 0.into()); + assert_eq!(T::balance(&account), 0.into()); +} + +/// Tests [`Balanced::deposit`]. +pub fn deposit() +where + T: Balanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // Cannot deposit < minimum balance into non-existent account + let account = AccountId::from(0); + let amount = T::minimum_balance() - 1.into(); + match T::deposit(&account, amount, Precision::Exact) { + Ok(_) => panic!("Balanced::deposit should have failed"), + Err(e) => assert_eq!(e, TokenError::BelowMinimum.into()), + }; + assert_eq!(T::total_issuance(), 0.into()); + assert_eq!(T::balance(&account), 0.into()); + + // Can deposit minimum balance into non-existent account + let amount = T::minimum_balance(); + match T::deposit(&account, amount, Precision::Exact) { + Ok(d) => assert_eq!(d.peek(), amount), + Err(_) => panic!("Balanced::deposit failed"), + }; + assert_eq!(T::total_issuance(), amount); + assert_eq!(T::balance(&account), amount); + + // Depositing amount that would overflow when Precision::Exact fails and is a noop + let amount = T::Balance::max_value(); + let balance_before = T::balance(&account); + let total_issuance_before = T::total_issuance(); + match T::deposit(&account, amount, Precision::Exact) { + Ok(_) => panic!("Balanced::deposit should have failed"), + Err(e) => assert_eq!(e, ArithmeticError::Overflow.into()), + }; + assert_eq!(T::total_issuance(), total_issuance_before); + assert_eq!(T::balance(&account), balance_before); + + // Depositing amount that would overflow when Precision::BestEffort saturates + match T::deposit(&account, amount, Precision::BestEffort) { + Ok(d) => assert_eq!(d.peek(), T::Balance::max_value() - balance_before), + Err(_) => panic!("Balanced::deposit failed"), + }; + assert_eq!(T::total_issuance(), T::Balance::max_value()); + assert_eq!(T::balance(&account), T::Balance::max_value()); +} + +/// Tests [`Balanced::withdraw`]. +pub fn withdraw() +where + T: Balanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let account = AccountId::from(0); + + // Init an account with some balance + let initial_balance = T::minimum_balance() + 10.into(); + match T::deposit(&account, initial_balance, Precision::Exact) { + Ok(_) => {}, + Err(_) => panic!("Balanced::deposit failed"), + }; + assert_eq!(T::total_issuance(), initial_balance); + assert_eq!(T::balance(&account), initial_balance); + + // Withdrawing an amount smaller than the balance works when Precision::Exact + let amount = 1.into(); + match T::withdraw( + &account, + amount, + Precision::Exact, + Preservation::Expendable, + Fortitude::Polite, + ) { + Ok(c) => assert_eq!(c.peek(), amount), + Err(_) => panic!("withdraw failed"), + }; + assert_eq!(T::total_issuance(), initial_balance - amount); + assert_eq!(T::balance(&account), initial_balance - amount); + + // Withdrawing an amount greater than the balance fails when Precision::Exact + let balance_before = T::balance(&account); + let amount = balance_before + 1.into(); + match T::withdraw( + &account, + amount, + Precision::Exact, + Preservation::Expendable, + Fortitude::Polite, + ) { + Ok(_) => panic!("should have failed"), + Err(e) => assert_eq!(e, TokenError::FundsUnavailable.into()), + }; + assert_eq!(T::total_issuance(), balance_before); + assert_eq!(T::balance(&account), balance_before); + + // Withdrawing an amount greater than the balance works when Precision::BestEffort + let balance_before = T::balance(&account); + let amount = balance_before + 1.into(); + match T::withdraw( + &account, + amount, + Precision::BestEffort, + Preservation::Expendable, + Fortitude::Polite, + ) { + Ok(c) => assert_eq!(c.peek(), balance_before), + Err(_) => panic!("withdraw failed"), + }; + assert_eq!(T::total_issuance(), 0.into()); + assert_eq!(T::balance(&account), 0.into()); +} + +/// Tests [`Balanced::pair`]. +pub fn pair() +where + T: Balanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + T::set_total_issuance(50.into()); + + // Pair zero balance works + let (credit, debt) = T::pair(0.into()).unwrap(); + assert_eq!(debt.peek(), 0.into()); + assert_eq!(credit.peek(), 0.into()); + + // Pair with non-zero balance: the credit and debt cancel each other out + let balance = 10.into(); + let (credit, debt) = T::pair(balance).unwrap(); + assert_eq!(credit.peek(), balance); + assert_eq!(debt.peek(), balance); + + // Creating a pair that could increase total_issuance beyond the max value returns an error + let max_value = T::Balance::max_value(); + let distance_from_max_value = 5.into(); + T::set_total_issuance(max_value - distance_from_max_value); + T::pair(distance_from_max_value + 5.into()).unwrap_err(); +} diff --git a/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/mod.rs b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/mod.rs new file mode 100644 index 00000000000..85acbcf2fcd --- /dev/null +++ b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/mod.rs @@ -0,0 +1,20 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +pub mod balanced; +pub mod mutate; +pub mod unbalanced; diff --git a/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/mutate.rs b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/mutate.rs new file mode 100644 index 00000000000..95b5256bb49 --- /dev/null +++ b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/mutate.rs @@ -0,0 +1,783 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use crate::traits::{ + fungible::{Inspect, Mutate}, + tokens::{ + DepositConsequence, Fortitude, Precision, Preservation, Provenance, WithdrawConsequence, + }, +}; +use core::fmt::Debug; +use sp_arithmetic::traits::AtLeast8BitUnsigned; +use sp_runtime::traits::{Bounded, Zero}; + +/// Test [`Mutate::mint_into`] for successful token minting. +/// +/// It ensures that account balances and total issuance values are updated correctly after +/// minting tokens into two distinct accounts. +pub fn mint_into_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let account_0 = AccountId::from(0); + let account_1 = AccountId::from(1); + + // Test: Mint an amount into each account + let amount_0 = T::minimum_balance(); + let amount_1 = T::minimum_balance() + 5.into(); + T::mint_into(&account_0, amount_0).unwrap(); + T::mint_into(&account_1, amount_1).unwrap(); + + // Verify: Account balances are updated correctly + assert_eq!(T::total_balance(&account_0), amount_0); + assert_eq!(T::total_balance(&account_1), amount_1); + assert_eq!(T::balance(&account_0), amount_0); + assert_eq!(T::balance(&account_1), amount_1); + + // Verify: Total issuance is updated correctly + assert_eq!(T::total_issuance(), initial_total_issuance + amount_0 + amount_1); + assert_eq!(T::active_issuance(), initial_active_issuance + amount_0 + amount_1); +} + +/// Test [`Mutate::mint_into`] for overflow prevention. +/// +/// This test ensures that minting tokens beyond the maximum balance value for an account +/// returns an error and does not change the account balance or total issuance values. +pub fn mint_into_overflow() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let account = AccountId::from(10); + let amount = T::Balance::max_value() - 5.into() - initial_total_issuance; + + // Mint just below the maximum balance + T::mint_into(&account, amount).unwrap(); + + // Verify: Minting beyond the maximum balance value returns an Err + T::mint_into(&account, 10.into()).unwrap_err(); + + // Verify: The balance did not change + assert_eq!(T::total_balance(&account), amount); + assert_eq!(T::balance(&account), amount); + + // Verify: The total issuance did not change + assert_eq!(T::total_issuance(), initial_total_issuance + amount); + assert_eq!(T::active_issuance(), initial_active_issuance + amount); +} + +/// Test [`Mutate::mint_into`] for handling balances below the minimum value. +/// +/// This test verifies that minting tokens below the minimum balance for an account +/// returns an error and has no impact on the account balance or total issuance values. +pub fn mint_into_below_minimum() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // Skip if there is no minimum balance + if T::minimum_balance() == T::Balance::zero() { + return + } + + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let account = AccountId::from(10); + let amount = T::minimum_balance() - 1.into(); + + // Verify: Minting below the minimum balance returns Err + T::mint_into(&account, amount).unwrap_err(); + + // Verify: noop + assert_eq!(T::total_balance(&account), T::Balance::zero()); + assert_eq!(T::balance(&account), T::Balance::zero()); + assert_eq!(T::total_issuance(), initial_total_issuance); + assert_eq!(T::active_issuance(), initial_active_issuance); +} + +/// Test [`Mutate::burn_from`] for successfully burning an exact amount of tokens. +/// +/// This test checks that burning tokens with [`Precision::Exact`] correctly reduces the account +/// balance and total issuance values by the burned amount. +pub fn burn_from_exact_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + + // Setup account + let account = AccountId::from(5); + let initial_balance = T::minimum_balance() + 10.into(); + T::mint_into(&account, initial_balance).unwrap(); + + // Test: Burn an exact amount from the account + let amount_to_burn = T::Balance::from(5); + let precision = Precision::Exact; + let force = Fortitude::Polite; + T::burn_from(&account, amount_to_burn, precision, force).unwrap(); + + // Verify: The balance and total issuance should be reduced by the burned amount + assert_eq!(T::balance(&account), initial_balance - amount_to_burn); + assert_eq!(T::total_balance(&account), initial_balance - amount_to_burn); + assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance - amount_to_burn); + assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance - amount_to_burn); +} + +/// Test [`Mutate::burn_from`] for successfully burning tokens with [`Precision::BestEffort`]. +/// +/// This test verifies that the burning tokens with best-effort precision correctly reduces the +/// account balance and total issuance values by the reducible balance when attempting to burn +/// an amount greater than the reducible balance. +pub fn burn_from_best_effort_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + + // Setup account + let account = AccountId::from(5); + let initial_balance = T::minimum_balance() + 10.into(); + T::mint_into(&account, initial_balance).unwrap(); + + // Get reducible balance + let force = Fortitude::Polite; + let reducible_balance = T::reducible_balance(&account, Preservation::Expendable, force); + + // Test: Burn a best effort amount from the account that is greater than the reducible + // balance + let amount_to_burn = reducible_balance + 5.into(); + let precision = Precision::BestEffort; + assert!(amount_to_burn > reducible_balance); + assert!(amount_to_burn > T::balance(&account)); + T::burn_from(&account, amount_to_burn, precision, force).unwrap(); + + // Verify: The balance and total issuance should be reduced by the reducible_balance + assert_eq!(T::balance(&account), initial_balance - reducible_balance); + assert_eq!(T::total_balance(&account), initial_balance - reducible_balance); + assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance - reducible_balance); + assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance - reducible_balance); +} + +/// Test [`Mutate::burn_from`] handling of insufficient funds when called with +/// [`Precision::Exact`]. +/// +/// This test verifies that burning an amount greater than the account's balance with exact +/// precision returns an error and does not change the account balance or total issuance values. +pub fn burn_from_exact_insufficient_funds() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // Set up the initial conditions and parameters for the test + let account = AccountId::from(5); + let initial_balance = T::minimum_balance() + 10.into(); + T::mint_into(&account, initial_balance).unwrap(); + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + + // Verify: Burn an amount greater than the account's balance with Exact precision returns + // Err + let amount_to_burn = initial_balance + 10.into(); + let precision = Precision::Exact; + let force = Fortitude::Polite; + T::burn_from(&account, amount_to_burn, precision, force).unwrap_err(); + + // Verify: The balance and total issuance should remain unchanged + assert_eq!(T::balance(&account), initial_balance); + assert_eq!(T::total_balance(&account), initial_balance); + assert_eq!(T::total_issuance(), initial_total_issuance); + assert_eq!(T::active_issuance(), initial_active_issuance); +} + +/// Test [`Mutate::restore`] for successful restoration. +/// +/// This test verifies that restoring an amount into each account updates their balances and the +/// total issuance values correctly. +pub fn restore_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let account_0 = AccountId::from(0); + let account_1 = AccountId::from(1); + + // Test: Restore an amount into each account + let amount_0 = T::minimum_balance(); + let amount_1 = T::minimum_balance() + 5.into(); + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + T::restore(&account_0, amount_0).unwrap(); + T::restore(&account_1, amount_1).unwrap(); + + // Verify: Account balances are updated correctly + assert_eq!(T::total_balance(&account_0), amount_0); + assert_eq!(T::total_balance(&account_1), amount_1); + assert_eq!(T::balance(&account_0), amount_0); + assert_eq!(T::balance(&account_1), amount_1); + + // Verify: Total issuance is updated correctly + assert_eq!(T::total_issuance(), initial_total_issuance + amount_0 + amount_1); + assert_eq!(T::active_issuance(), initial_active_issuance + amount_0 + amount_1); +} + +/// Test [`Mutate::restore`] handles balance overflow. +/// +/// This test verifies that restoring an amount beyond the maximum balance returns an error and +/// does not change the account balance or total issuance values. +pub fn restore_overflow() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let account = AccountId::from(10); + let amount = T::Balance::max_value() - 5.into() - initial_total_issuance; + + // Restore just below the maximum balance + T::restore(&account, amount).unwrap(); + + // Verify: Restoring beyond the maximum balance returns an Err + T::restore(&account, 10.into()).unwrap_err(); + + // Verify: The balance and total issuance did not change + assert_eq!(T::total_balance(&account), amount); + assert_eq!(T::balance(&account), amount); + assert_eq!(T::total_issuance(), initial_total_issuance + amount); + assert_eq!(T::active_issuance(), initial_active_issuance + amount); +} + +/// Test [`Mutate::restore`] handles restoration below the minimum balance. +/// +/// This test verifies that restoring an amount below the minimum balance returns an error and +/// does not change the account balance or total issuance values. +pub fn restore_below_minimum() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // Skip if there is no minimum balance + if T::minimum_balance() == T::Balance::zero() { + return + } + + let account = AccountId::from(10); + let amount = T::minimum_balance() - 1.into(); + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + + // Verify: Restoring below the minimum balance returns Err + T::restore(&account, amount).unwrap_err(); + + // Verify: noop + assert_eq!(T::total_balance(&account), T::Balance::zero()); + assert_eq!(T::balance(&account), T::Balance::zero()); + assert_eq!(T::total_issuance(), initial_total_issuance); + assert_eq!(T::active_issuance(), initial_active_issuance); +} + +/// Test [`Mutate::shelve`] for successful shelving. +/// +/// This test verifies that shelving an amount from an account reduces the account balance and +/// total issuance values by the shelved amount. +pub fn shelve_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + + // Setup account + let account = AccountId::from(5); + let initial_balance = T::minimum_balance() + 10.into(); + + T::restore(&account, initial_balance).unwrap(); + + // Test: Shelve an amount from the account + let amount_to_shelve = T::Balance::from(5); + T::shelve(&account, amount_to_shelve).unwrap(); + + // Verify: The balance and total issuance should be reduced by the shelved amount + assert_eq!(T::balance(&account), initial_balance - amount_to_shelve); + assert_eq!(T::total_balance(&account), initial_balance - amount_to_shelve); + assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance - amount_to_shelve); + assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance - amount_to_shelve); +} + +/// Test [`Mutate::shelve`] handles insufficient funds correctly. +/// +/// This test verifies that attempting to shelve an amount greater than the account's balance +/// returns an error and does not change the account balance or total issuance values. +pub fn shelve_insufficient_funds() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + + // Set up the initial conditions and parameters for the test + let account = AccountId::from(5); + let initial_balance = T::minimum_balance() + 10.into(); + T::restore(&account, initial_balance).unwrap(); + + // Verify: Shelving greater than the balance with Exact precision returns Err + let amount_to_shelve = initial_balance + 10.into(); + T::shelve(&account, amount_to_shelve).unwrap_err(); + + // Verify: The balance and total issuance should remain unchanged + assert_eq!(T::balance(&account), initial_balance); + assert_eq!(T::total_balance(&account), initial_balance); + assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance); + assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance); +} + +/// Test [`Mutate::transfer`] for a successful transfer. +/// +/// This test verifies that transferring an amount between two accounts with updates the account +/// balances and maintains correct total issuance and active issuance values. +pub fn transfer_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let account_0 = AccountId::from(0); + let account_1 = AccountId::from(1); + let initial_balance = T::minimum_balance() + 10.into(); + T::set_balance(&account_0, initial_balance); + T::set_balance(&account_1, initial_balance); + + // Test: Transfer an amount from account_0 to account_1 + let transfer_amount = T::Balance::from(3); + T::transfer(&account_0, &account_1, transfer_amount, Preservation::Expendable).unwrap(); + + // Verify: Account balances are updated correctly + assert_eq!(T::total_balance(&account_0), initial_balance - transfer_amount); + assert_eq!(T::total_balance(&account_1), initial_balance + transfer_amount); + assert_eq!(T::balance(&account_0), initial_balance - transfer_amount); + assert_eq!(T::balance(&account_1), initial_balance + transfer_amount); + + // Verify: Total issuance doesn't change + assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance * 2.into()); + assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance * 2.into()); +} + +/// Test calling [`Mutate::transfer`] with [`Preservation::Expendable`] correctly transfers the +/// entire balance. +/// +/// This test verifies that transferring the entire balance from one account to another with +/// when preservation is expendable updates the account balances and maintains the total +/// issuance and active issuance values. +pub fn transfer_expendable_all() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let account_0 = AccountId::from(0); + let account_1 = AccountId::from(1); + let initial_balance = T::minimum_balance() + 10.into(); + T::set_balance(&account_0, initial_balance); + T::set_balance(&account_1, initial_balance); + + // Test: Transfer entire balance from account_0 to account_1 + let preservation = Preservation::Expendable; + let transfer_amount = initial_balance; + T::transfer(&account_0, &account_1, transfer_amount, preservation).unwrap(); + + // Verify: Account balances are updated correctly + assert_eq!(T::total_balance(&account_0), T::Balance::zero()); + assert_eq!(T::total_balance(&account_1), initial_balance * 2.into()); + assert_eq!(T::balance(&account_0), T::Balance::zero()); + assert_eq!(T::balance(&account_1), initial_balance * 2.into()); + + // Verify: Total issuance doesn't change + assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance * 2.into()); + assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance * 2.into()); +} + +/// Test calling [`Mutate::transfer`] function with [`Preservation::Expendable`] and an amount +/// that results in some dust. +/// +/// This test verifies that dust is handled correctly when an account is reaped, with and +/// without a dust trap. +/// +/// # Parameters +/// +/// - dust_trap: An optional account identifier to which dust will be collected. If `None`, dust is +/// expected to be removed from the total and active issuance. +pub fn transfer_expendable_dust(dust_trap: Option) +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + if T::minimum_balance() == T::Balance::zero() { + return + } + + let account_0 = AccountId::from(10); + let account_1 = AccountId::from(20); + let initial_balance = T::minimum_balance() + 10.into(); + T::set_balance(&account_0, initial_balance); + T::set_balance(&account_1, initial_balance); + + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let initial_dust_trap_balance = match dust_trap.clone() { + Some(dust_trap) => T::total_balance(&dust_trap), + None => T::Balance::zero(), + }; + + // Test: Transfer balance + let preservation = Preservation::Expendable; + let transfer_amount = T::Balance::from(11); + T::transfer(&account_0, &account_1, transfer_amount, preservation).unwrap(); + + // Verify: Account balances are updated correctly + assert_eq!(T::total_balance(&account_0), T::Balance::zero()); + assert_eq!(T::total_balance(&account_1), initial_balance + transfer_amount); + assert_eq!(T::balance(&account_0), T::Balance::zero()); + assert_eq!(T::balance(&account_1), initial_balance + transfer_amount); + + match dust_trap { + Some(dust_trap) => { + // Verify: Total issuance and active issuance don't change + assert_eq!(T::total_issuance(), initial_total_issuance); + assert_eq!(T::active_issuance(), initial_active_issuance); + // Verify: Dust is collected into dust trap + assert_eq!( + T::total_balance(&dust_trap), + initial_dust_trap_balance + T::minimum_balance() - 1.into() + ); + assert_eq!( + T::balance(&dust_trap), + initial_dust_trap_balance + T::minimum_balance() - 1.into() + ); + }, + None => { + // Verify: Total issuance and active issuance are reduced by the dust amount + assert_eq!( + T::total_issuance(), + initial_total_issuance - T::minimum_balance() + 1.into() + ); + assert_eq!( + T::active_issuance(), + initial_active_issuance - T::minimum_balance() + 1.into() + ); + }, + } +} + +/// Test [`Mutate::transfer`] with [`Preservation::Protect`] and [`Preservation::Preserve`] +/// transferring the entire balance. +/// +/// This test verifies that attempting to transfer the entire balance with returns an error when +/// preservation should not allow it, and the account balances, total issuance, and active +/// issuance values remain unchanged. +pub fn transfer_protect_preserve() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // This test means nothing if there is no minimum balance + if T::minimum_balance() == T::Balance::zero() { + return + } + + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let account_0 = AccountId::from(0); + let account_1 = AccountId::from(1); + let initial_balance = T::minimum_balance() + 10.into(); + T::set_balance(&account_0, initial_balance); + T::set_balance(&account_1, initial_balance); + + // Verify: Transfer Protect entire balance from account_0 to account_1 should Err + let preservation = Preservation::Protect; + let transfer_amount = initial_balance; + T::transfer(&account_0, &account_1, transfer_amount, preservation).unwrap_err(); + + // Verify: Noop + assert_eq!(T::total_balance(&account_0), initial_balance); + assert_eq!(T::total_balance(&account_1), initial_balance); + assert_eq!(T::balance(&account_0), initial_balance); + assert_eq!(T::balance(&account_1), initial_balance); + assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance * 2.into()); + assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance * 2.into()); + + // Verify: Transfer Preserve entire balance from account_0 to account_1 should Err + let preservation = Preservation::Preserve; + T::transfer(&account_0, &account_1, transfer_amount, preservation).unwrap_err(); + + // Verify: Noop + assert_eq!(T::total_balance(&account_0), initial_balance); + assert_eq!(T::total_balance(&account_1), initial_balance); + assert_eq!(T::balance(&account_0), initial_balance); + assert_eq!(T::balance(&account_1), initial_balance); + assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance * 2.into()); + assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance * 2.into()); +} + +/// Test [`Mutate::set_balance`] mints balances correctly. +/// +/// This test verifies that minting a balance using `set_balance` updates the account balance, +/// total issuance, and active issuance correctly. +pub fn set_balance_mint_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let account = AccountId::from(10); + let initial_balance = T::minimum_balance() + 10.into(); + T::mint_into(&account, initial_balance).unwrap(); + + // Test: Increase the account balance with set_balance + let increase_amount: T::Balance = 5.into(); + let new = T::set_balance(&account, initial_balance + increase_amount); + + // Verify: set_balance returned the new balance + let expected_new = initial_balance + increase_amount; + assert_eq!(new, expected_new); + + // Verify: Balance and issuance is updated correctly + assert_eq!(T::total_balance(&account), expected_new); + assert_eq!(T::balance(&account), expected_new); + assert_eq!(T::total_issuance(), initial_total_issuance + expected_new); + assert_eq!(T::active_issuance(), initial_active_issuance + expected_new); +} + +/// Test [`Mutate::set_balance`] burns balances correctly. +/// +/// This test verifies that burning a balance using `set_balance` updates the account balance, +/// total issuance, and active issuance correctly. +pub fn set_balance_burn_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let account = AccountId::from(10); + let initial_balance = T::minimum_balance() + 10.into(); + T::mint_into(&account, initial_balance).unwrap(); + + // Test: Increase the account balance with set_balance + let burn_amount: T::Balance = 5.into(); + let new = T::set_balance(&account, initial_balance - burn_amount); + + // Verify: set_balance returned the new balance + let expected_new = initial_balance - burn_amount; + assert_eq!(new, expected_new); + + // Verify: Balance and issuance is updated correctly + assert_eq!(T::total_balance(&account), expected_new); + assert_eq!(T::balance(&account), expected_new); + assert_eq!(T::total_issuance(), initial_total_issuance + expected_new); + assert_eq!(T::active_issuance(), initial_active_issuance + expected_new); +} + +/// Test [`Inspect::can_deposit`] works correctly returns [`DepositConsequence::Success`] +/// when depositing an amount that should succeed. +pub fn can_deposit_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let account = AccountId::from(10); + let initial_balance = T::minimum_balance() + 10.into(); + T::mint_into(&account, initial_balance).unwrap(); + + // Test: can_deposit a reasonable amount + let ret = T::can_deposit(&account, 5.into(), Provenance::Minted); + + // Verify: Returns success + assert_eq!(ret, DepositConsequence::Success); +} + +/// Test [`Inspect::can_deposit`] returns [`DepositConsequence::BelowMinimum`] when depositing +/// below the minimum balance. +pub fn can_deposit_below_minimum() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // can_deposit always returns Success for amount 0 + if T::minimum_balance() < 2.into() { + return + } + + let account = AccountId::from(10); + + // Test: can_deposit below the minimum + let ret = T::can_deposit(&account, T::minimum_balance() - 1.into(), Provenance::Minted); + + // Verify: Returns success + assert_eq!(ret, DepositConsequence::BelowMinimum); +} + +/// Test [`Inspect::can_deposit`] returns [`DepositConsequence::Overflow`] when +/// depositing an amount that would overflow. +pub fn can_deposit_overflow() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let account = AccountId::from(10); + + // Test: Try deposit over the max balance + let initial_balance = T::Balance::max_value() - 5.into() - T::total_issuance(); + T::mint_into(&account, initial_balance).unwrap(); + let ret = T::can_deposit(&account, 10.into(), Provenance::Minted); + + // Verify: Returns success + assert_eq!(ret, DepositConsequence::Overflow); +} + +/// Test [`Inspect::can_withdraw`] returns [`WithdrawConsequence::Success`] when withdrawing an +/// amount that should succeed. +pub fn can_withdraw_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let account = AccountId::from(10); + let initial_balance = T::minimum_balance() + 10.into(); + T::mint_into(&account, initial_balance).unwrap(); + + // Test: can_withdraw a reasonable amount + let ret = T::can_withdraw(&account, 5.into()); + + // Verify: Returns success + assert_eq!(ret, WithdrawConsequence::Success); +} + +/// Test [`Inspect::can_withdraw`] returns [`WithdrawConsequence::ReducedToZero`] when +/// withdrawing an amount that would reduce the account balance below the minimum balance. +pub fn can_withdraw_reduced_to_zero() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + if T::minimum_balance() == T::Balance::zero() { + return + } + + let account = AccountId::from(10); + let initial_balance = T::minimum_balance(); + T::mint_into(&account, initial_balance).unwrap(); + + // Verify: can_withdraw below the minimum balance returns ReducedToZero + let ret = T::can_withdraw(&account, 1.into()); + assert_eq!(ret, WithdrawConsequence::ReducedToZero(T::minimum_balance() - 1.into())); +} + +/// Test [`Inspect::can_withdraw`] returns [`WithdrawConsequence::BalanceLow`] when withdrawing +/// an amount that would result in an account balance below the current balance. +pub fn can_withdraw_balance_low() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + if T::minimum_balance() == T::Balance::zero() { + return + } + + let account = AccountId::from(10); + let other_account = AccountId::from(100); + let initial_balance = T::minimum_balance() + 5.into(); + T::mint_into(&account, initial_balance).unwrap(); + T::mint_into(&other_account, initial_balance * 2.into()).unwrap(); + + // Verify: can_withdraw below the account balance returns BalanceLow + let ret = T::can_withdraw(&account, initial_balance + 1.into()); + assert_eq!(ret, WithdrawConsequence::BalanceLow); +} + +/// Test [`Inspect::reducible_balance`] returns the full account balance when called with +/// [`Preservation::Expendable`]. +pub fn reducible_balance_expendable() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let account = AccountId::from(10); + let initial_balance = T::minimum_balance() + 10.into(); + T::mint_into(&account, initial_balance).unwrap(); + + // Verify: reducible_balance returns the full balance + let ret = T::reducible_balance(&account, Preservation::Expendable, Fortitude::Polite); + assert_eq!(ret, initial_balance); +} + +/// Tests [`Inspect::reducible_balance`] returns [`Inspect::balance`] - +/// [`Inspect::minimum_balance`] when called with either [`Preservation::Protect`] or +/// [`Preservation::Preserve`]. +pub fn reducible_balance_protect_preserve() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let account = AccountId::from(10); + let initial_balance = T::minimum_balance() + 10.into(); + T::mint_into(&account, initial_balance).unwrap(); + + // Verify: reducible_balance returns the full balance - min balance + let ret = T::reducible_balance(&account, Preservation::Protect, Fortitude::Polite); + assert_eq!(ret, initial_balance - T::minimum_balance()); + let ret = T::reducible_balance(&account, Preservation::Preserve, Fortitude::Polite); + assert_eq!(ret, initial_balance - T::minimum_balance()); +} diff --git a/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/unbalanced.rs b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/unbalanced.rs new file mode 100644 index 00000000000..e7fcc15472e --- /dev/null +++ b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/unbalanced.rs @@ -0,0 +1,281 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use crate::traits::{ + fungible::{Inspect, Unbalanced}, + tokens::{Fortitude, Precision, Preservation}, +}; +use core::fmt::Debug; +use sp_arithmetic::{traits::AtLeast8BitUnsigned, ArithmeticError}; +use sp_runtime::{traits::Bounded, TokenError}; + +/// Tests [`Unbalanced::write_balance`]. +/// +/// We don't need to test the Error case for this function, because the trait makes no +/// assumptions about the ways it can fail. That is completely an implementation detail. +pub fn write_balance() +where + T: Unbalanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // Setup some accounts to test varying initial balances + let account_0_ed = AccountId::from(0); + let account_1_gt_ed = AccountId::from(1); + let account_2_empty = AccountId::from(2); + T::increase_balance(&account_0_ed, T::minimum_balance(), Precision::Exact).unwrap(); + T::increase_balance(&account_1_gt_ed, T::minimum_balance() + 5.into(), Precision::Exact) + .unwrap(); + + // Test setting the balances of each account by gt the minimum balance succeeds with no + // dust. + let amount = T::minimum_balance() + 10.into(); + assert_eq!(T::write_balance(&account_0_ed, amount), Ok(None)); + assert_eq!(T::write_balance(&account_1_gt_ed, amount), Ok(None)); + assert_eq!(T::write_balance(&account_2_empty, amount), Ok(None)); + assert_eq!(T::balance(&account_0_ed), amount); + assert_eq!(T::balance(&account_1_gt_ed), amount); + assert_eq!(T::balance(&account_2_empty), amount); + + // Test setting the balances of each account to below the minimum balance succeeds with + // the expected dust. + // If the minimum balance is 1, then the dust is 0, represented as None. + // If the minimum balance is >1, then the dust is the remaining balance that will be wiped + // as the account is reaped. + let amount = T::minimum_balance() - 1.into(); + if T::minimum_balance() == 1.into() { + assert_eq!(T::write_balance(&account_0_ed, amount), Ok(None)); + assert_eq!(T::write_balance(&account_1_gt_ed, amount), Ok(None)); + assert_eq!(T::write_balance(&account_2_empty, amount), Ok(None)); + } else if T::minimum_balance() > 1.into() { + assert_eq!(T::write_balance(&account_0_ed, amount), Ok(Some(amount))); + assert_eq!(T::write_balance(&account_1_gt_ed, amount), Ok(Some(amount))); + assert_eq!(T::write_balance(&account_2_empty, amount), Ok(Some(amount))); + } +} + +/// Tests [`Unbalanced::decrease_balance`] called with [`Preservation::Expendable`]. +pub fn decrease_balance_expendable() +where + T: Unbalanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // Setup account with some balance + let account_0 = AccountId::from(0); + let account_0_initial_balance = T::minimum_balance() + 10.into(); + T::increase_balance(&account_0, account_0_initial_balance, Precision::Exact).unwrap(); + + // Decreasing the balance still above the minimum balance should not reap the account. + let amount = 1.into(); + assert_eq!( + T::decrease_balance( + &account_0, + amount, + Precision::Exact, + Preservation::Expendable, + Fortitude::Polite, + ), + Ok(amount), + ); + assert_eq!(T::balance(&account_0), account_0_initial_balance - amount); + + // Decreasing the balance below funds avalibale should fail when Precision::Exact + let balance_before = T::balance(&account_0); + assert_eq!( + T::decrease_balance( + &account_0, + account_0_initial_balance, + Precision::Exact, + Preservation::Expendable, + Fortitude::Polite, + ), + Err(TokenError::FundsUnavailable.into()) + ); + // Balance unchanged + assert_eq!(T::balance(&account_0), balance_before); + + // And reap the account when Precision::BestEffort + assert_eq!( + T::decrease_balance( + &account_0, + account_0_initial_balance, + Precision::BestEffort, + Preservation::Expendable, + Fortitude::Polite, + ), + Ok(balance_before), + ); + // Account reaped + assert_eq!(T::balance(&account_0), 0.into()); +} + +/// Tests [`Unbalanced::decrease_balance`] called with [`Preservation::Preserve`]. +pub fn decrease_balance_preserve() +where + T: Unbalanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // Setup account with some balance + let account_0 = AccountId::from(0); + let account_0_initial_balance = T::minimum_balance() + 10.into(); + T::increase_balance(&account_0, account_0_initial_balance, Precision::Exact).unwrap(); + + // Decreasing the balance below the minimum when Precision::Exact should fail. + let amount = 11.into(); + assert_eq!( + T::decrease_balance( + &account_0, + amount, + Precision::Exact, + Preservation::Preserve, + Fortitude::Polite, + ), + Err(TokenError::FundsUnavailable.into()), + ); + // Balance should not have changed. + assert_eq!(T::balance(&account_0), account_0_initial_balance); + + // Decreasing the balance below the minimum when Precision::BestEffort should reduce to + // minimum balance. + let amount = 11.into(); + assert_eq!( + T::decrease_balance( + &account_0, + amount, + Precision::BestEffort, + Preservation::Preserve, + Fortitude::Polite, + ), + Ok(account_0_initial_balance - T::minimum_balance()), + ); + assert_eq!(T::balance(&account_0), T::minimum_balance()); +} + +/// Tests [`Unbalanced::increase_balance`]. +pub fn increase_balance() +where + T: Unbalanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let account_0 = AccountId::from(0); + assert_eq!(T::balance(&account_0), 0.into()); + + // Increasing the bal below the ED errors when precision is Exact + if T::minimum_balance() > 0.into() { + assert_eq!( + T::increase_balance(&account_0, T::minimum_balance() - 1.into(), Precision::Exact), + Err(TokenError::BelowMinimum.into()), + ); + } + assert_eq!(T::balance(&account_0), 0.into()); + + // Increasing the bal below the ED leaves the balance at zero when precision is BestEffort + if T::minimum_balance() > 0.into() { + assert_eq!( + T::increase_balance(&account_0, T::minimum_balance() - 1.into(), Precision::BestEffort), + Ok(0.into()), + ); + } + assert_eq!(T::balance(&account_0), 0.into()); + + // Can increase if new bal is >= ED + assert_eq!( + T::increase_balance(&account_0, T::minimum_balance(), Precision::Exact), + Ok(T::minimum_balance()), + ); + assert_eq!(T::balance(&account_0), T::minimum_balance()); + assert_eq!(T::increase_balance(&account_0, 5.into(), Precision::Exact), Ok(5.into()),); + assert_eq!(T::balance(&account_0), T::minimum_balance() + 5.into()); + + // Increasing by amount that would overflow fails when precision is Exact + assert_eq!( + T::increase_balance(&account_0, T::Balance::max_value(), Precision::Exact), + Err(ArithmeticError::Overflow.into()), + ); + + // Increasing by amount that would overflow saturates when precision is BestEffort + let balance_before = T::balance(&account_0); + assert_eq!( + T::increase_balance(&account_0, T::Balance::max_value(), Precision::BestEffort), + Ok(T::Balance::max_value() - balance_before), + ); + assert_eq!(T::balance(&account_0), T::Balance::max_value()); +} + +/// Tests [`Unbalanced::set_total_issuance`]. +pub fn set_total_issuance() +where + T: Unbalanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + T::set_total_issuance(1.into()); + assert_eq!(T::total_issuance(), 1.into()); + + T::set_total_issuance(0.into()); + assert_eq!(T::total_issuance(), 0.into()); + + T::set_total_issuance(T::minimum_balance()); + assert_eq!(T::total_issuance(), T::minimum_balance()); + + T::set_total_issuance(T::minimum_balance() + 5.into()); + assert_eq!(T::total_issuance(), T::minimum_balance() + 5.into()); + + if T::minimum_balance() > 0.into() { + T::set_total_issuance(T::minimum_balance() - 1.into()); + assert_eq!(T::total_issuance(), T::minimum_balance() - 1.into()); + } +} + +/// Tests [`Unbalanced::deactivate`] and [`Unbalanced::reactivate`]. +pub fn deactivate_and_reactivate() +where + T: Unbalanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + T::set_total_issuance(10.into()); + assert_eq!(T::total_issuance(), 10.into()); + assert_eq!(T::active_issuance(), 10.into()); + + T::deactivate(2.into()); + assert_eq!(T::total_issuance(), 10.into()); + assert_eq!(T::active_issuance(), 8.into()); + + // Saturates at total_issuance + T::reactivate(4.into()); + assert_eq!(T::total_issuance(), 10.into()); + assert_eq!(T::active_issuance(), 10.into()); + + // Decrements correctly after saturating at total_issuance + T::deactivate(1.into()); + assert_eq!(T::total_issuance(), 10.into()); + assert_eq!(T::active_issuance(), 9.into()); + + // Saturates at zero + T::deactivate(15.into()); + assert_eq!(T::total_issuance(), 10.into()); + assert_eq!(T::active_issuance(), 0.into()); + + // Increments correctly after saturating at zero + T::reactivate(1.into()); + assert_eq!(T::total_issuance(), 10.into()); + assert_eq!(T::active_issuance(), 1.into()); +} diff --git a/substrate/frame/support/src/traits/tokens/fungible/item_of.rs b/substrate/frame/support/src/traits/tokens/fungible/item_of.rs index fe252c6b089..37749d39600 100644 --- a/substrate/frame/support/src/traits/tokens/fungible/item_of.rs +++ b/substrate/frame/support/src/traits/tokens/fungible/item_of.rs @@ -389,9 +389,11 @@ impl< let credit = >::issue(A::get(), amount); imbalance::from_fungibles(credit) } - fn pair(amount: Self::Balance) -> (Debt, Credit) { - let (a, b) = >::pair(A::get(), amount); - (imbalance::from_fungibles(a), imbalance::from_fungibles(b)) + fn pair( + amount: Self::Balance, + ) -> Result<(Debt, Credit), DispatchError> { + let (a, b) = >::pair(A::get(), amount)?; + Ok((imbalance::from_fungibles(a), imbalance::from_fungibles(b))) } fn rescind(amount: Self::Balance) -> Debt { let debt = >::rescind(A::get(), amount); diff --git a/substrate/frame/support/src/traits/tokens/fungible/regular.rs b/substrate/frame/support/src/traits/tokens/fungible/regular.rs index 87c6ef68d77..f15c3418d0a 100644 --- a/substrate/frame/support/src/traits/tokens/fungible/regular.rs +++ b/substrate/frame/support/src/traits/tokens/fungible/regular.rs @@ -64,7 +64,7 @@ pub trait Inspect: Sized { /// indefinitely. /// /// For the amount of the balance which is currently free to be removed from the account without - /// error, use `reducible_balance`. + /// error, use [`Inspect::reducible_balance`]. /// /// For the amount of the balance which may eventually be free to be removed from the account, /// use `balance()`. @@ -74,7 +74,7 @@ pub trait Inspect: Sized { /// subsystems of the chain ("on hold" or "reserved"). /// /// In general this isn't especially useful outside of tests, and for practical purposes, you'll - /// want to use `reducible_balance()`. + /// want to use [`Inspect::reducible_balance`]. fn balance(who: &AccountId) -> Self::Balance; /// Get the maximum amount that `who` can withdraw/transfer successfully based on whether the @@ -82,7 +82,7 @@ pub trait Inspect: Sized { /// reduction and potentially go below user-level restrictions on the minimum amount of the /// account. /// - /// Always less than or equal to `balance()`. + /// Always less than or equal to [`Inspect::balance`]. fn reducible_balance( who: &AccountId, preservation: Preservation, @@ -106,7 +106,7 @@ pub trait Inspect: Sized { fn can_withdraw(who: &AccountId, amount: Self::Balance) -> WithdrawConsequence; } -/// Special dust type which can be type-safely converted into a `Credit`. +/// Special dust type which can be type-safely converted into a [`Credit`]. #[must_use] pub struct Dust>(pub T::Balance); @@ -123,20 +123,20 @@ impl> Dust { /// Do not use this directly unless you want trouble, since it allows you to alter account balances /// without keeping the issuance up to date. It has no safeguards against accidentally creating /// token imbalances in your system leading to accidental inflation or deflation. It's really just -/// for the underlying datatype to implement so the user gets the much safer `Balanced` trait to +/// for the underlying datatype to implement so the user gets the much safer [`Balanced`] trait to /// use. pub trait Unbalanced: Inspect { - /// Create some dust and handle it with `Self::handle_dust`. This is an unbalanced operation - /// and it must only be used when an account is modified in a raw fashion, outside of the entire - /// fungibles API. The `amount` is capped at `Self::minimum_balance() - 1`. + /// Create some dust and handle it with [`Unbalanced::handle_dust`]. This is an unbalanced + /// operation and it must only be used when an account is modified in a raw fashion, outside of + /// the entire fungibles API. The `amount` is capped at [`Inspect::minimum_balance()`] - 1`. /// /// This should not be reimplemented. fn handle_raw_dust(amount: Self::Balance) { Self::handle_dust(Dust(amount.min(Self::minimum_balance().saturating_sub(One::one())))) } - /// Do something with the dust which has been destroyed from the system. `Dust` can be converted - /// into a `Credit` with the `Balanced` trait impl. + /// Do something with the dust which has been destroyed from the system. [`Dust`] can be + /// converted into a [`Credit`] with the [`Balanced`] trait impl. fn handle_dust(dust: Dust); /// Forcefully set the balance of `who` to `amount`. @@ -151,9 +151,10 @@ pub trait Unbalanced: Inspect { /// If this cannot be done for some reason (e.g. because the account cannot be created, deleted /// or would overflow) then an `Err` is returned. /// - /// If `Ok` is returned then its inner, if `Some` is the amount which was discarded as dust due - /// to existential deposit requirements. The default implementation of `decrease_balance` and - /// `increase_balance` converts this into an `Imbalance` and then passes it into `handle_dust`. + /// If `Ok` is returned then its inner, then `Some` is the amount which was discarded as dust + /// due to existential deposit requirements. The default implementation of + /// [`Unbalanced::decrease_balance`] and [`Unbalanced::increase_balance`] converts this into an + /// [`Imbalance`] and then passes it into [`Unbalanced::handle_dust`]. fn write_balance( who: &AccountId, amount: Self::Balance, @@ -164,14 +165,14 @@ pub trait Unbalanced: Inspect { /// Reduce the balance of `who` by `amount`. /// - /// If `precision` is `Exact` and it cannot be reduced by that amount for - /// some reason, return `Err` and don't reduce it at all. If `precision` is `BestEffort`, then + /// If `precision` is [`Exact`] and it cannot be reduced by that amount for + /// some reason, return `Err` and don't reduce it at all. If `precision` is [`BestEffort`], then /// reduce the balance of `who` by the most that is possible, up to `amount`. /// /// In either case, if `Ok` is returned then the inner is the amount by which is was reduced. /// Minimum balance will be respected and thus the returned amount may be up to - /// `Self::minimum_balance() - 1` greater than `amount` in the case that the reduction caused - /// the account to be deleted. + /// [`Inspect::minimum_balance()`] - 1` greater than `amount` in the case that the reduction + /// caused the account to be deleted. fn decrease_balance( who: &AccountId, mut amount: Self::Balance, @@ -180,15 +181,10 @@ pub trait Unbalanced: Inspect { force: Fortitude, ) -> Result { let old_balance = Self::balance(who); - let free = Self::reducible_balance(who, preservation, force); + let reducible = Self::reducible_balance(who, preservation, force); match precision { - BestEffort => { - amount = amount.min(free); - }, - Exact => - if free < amount { - return Err(TokenError::FundsUnavailable.into()) - }, + BestEffort => amount = amount.min(reducible), + Exact => ensure!(reducible >= amount, TokenError::FundsUnavailable), } let new_balance = old_balance.checked_sub(&amount).ok_or(TokenError::FundsUnavailable)?; @@ -203,7 +199,7 @@ pub trait Unbalanced: Inspect { /// If it cannot be increased by that amount for some reason, return `Err` and don't increase /// it at all. If Ok, return the imbalance. /// Minimum balance will be respected and an error will be returned if - /// `amount < Self::minimum_balance()` when the account of `who` is zero. + /// amount < [`Inspect::minimum_balance()`] when the account of `who` is zero. fn increase_balance( who: &AccountId, amount: Self::Balance, @@ -276,8 +272,8 @@ where /// Attempt to decrease the `asset` balance of `who` by `amount`. /// - /// Equivalent to `burn_from`, except with an expectation that within the bounds of some - /// universal issuance, the total assets `suspend`ed and `resume`d will be equivalent. The + /// Equivalent to [`Mutate::burn_from`], except with an expectation that within the bounds of + /// some universal issuance, the total assets `suspend`ed and `resume`d will be equivalent. The /// implementation may be configured such that the total assets suspended may never be less than /// the total assets resumed (which is the invariant for an issuing system), or the reverse /// (which the invariant in a non-issuing system). @@ -296,8 +292,8 @@ where /// Attempt to increase the `asset` balance of `who` by `amount`. /// - /// Equivalent to `mint_into`, except with an expectation that within the bounds of some - /// universal issuance, the total assets `suspend`ed and `resume`d will be equivalent. The + /// Equivalent to [`Mutate::mint_into`], except with an expectation that within the bounds of + /// some universal issuance, the total assets `suspend`ed and `resume`d will be equivalent. The /// implementation may be configured such that the total assets suspended may never be less than /// the total assets resumed (which is the invariant for an issuing system), or the reverse /// (which the invariant in a non-issuing system). @@ -325,7 +321,7 @@ where let _extra = Self::can_withdraw(source, amount).into_result(preservation != Expendable)?; Self::can_deposit(dest, amount, Extant).into_result()?; if source == dest { - return Ok(amount) + return Ok(amount); } Self::decrease_balance(source, amount, BestEffort, preservation, Polite)?; @@ -383,7 +379,7 @@ impl> HandleImbalanceDrop /// A fungible token class where any creation and deletion of tokens is semi-explicit and where the /// total supply is maintained automatically. /// -/// This is auto-implemented when a token class has `Unbalanced` implemented. +/// This is auto-implemented when a token class has [`Unbalanced`] implemented. pub trait Balanced: Inspect + Unbalanced { /// The type for managing what happens when an instance of `Debt` is dropped without being used. type OnDropDebt: HandleImbalanceDrop; @@ -392,7 +388,7 @@ pub trait Balanced: Inspect + Unbalanced { type OnDropCredit: HandleImbalanceDrop; /// Reduce the total issuance by `amount` and return the according imbalance. The imbalance will - /// typically be used to reduce an account by the same amount with e.g. `settle`. + /// typically be used to reduce an account by the same amount with e.g. [`Balanced::settle`]. /// /// This is infallible, but doesn't guarantee that the entire `amount` is burnt, for example /// in the case of underflow. @@ -407,7 +403,7 @@ pub trait Balanced: Inspect + Unbalanced { /// Increase the total issuance by `amount` and return the according imbalance. The imbalance /// will typically be used to increase an account by the same amount with e.g. - /// `resolve_into_existing` or `resolve_creating`. + /// [`Balanced::resolve`]. /// /// This is infallible, but doesn't guarantee that the entire `amount` is issued, for example /// in the case of overflow. @@ -424,18 +420,33 @@ pub trait Balanced: Inspect + Unbalanced { /// /// This is just the same as burning and issuing the same amount and has no effect on the /// total issuance. - fn pair(amount: Self::Balance) -> (Debt, Credit) { - (Self::rescind(amount), Self::issue(amount)) + /// + /// This could fail when we cannot issue and redeem the entire `amount`, for example in the + /// case where the amount would cause overflow or underflow in [`Balanced::issue`] or + /// [`Balanced::rescind`]. + fn pair( + amount: Self::Balance, + ) -> Result<(Debt, Credit), DispatchError> { + let issued = Self::issue(amount); + let rescinded = Self::rescind(amount); + // Need to check amount in case by some edge case both issued and rescinded are below + // `amount` by the exact same value + if issued.peek() != rescinded.peek() || issued.peek() != amount { + // Issued and rescinded will be dropped automatically + Err("Failed to issue and rescind equal amounts".into()) + } else { + Ok((rescinded, issued)) + } } /// Mints `value` into the account of `who`, creating it as needed. /// /// If `precision` is `BestEffort` and `value` in full could not be minted (e.g. due to - /// overflow), then the maximum is minted, up to `value`. If `precision` is `Exact`, then + /// overflow), then the maximum is minted, up to `value`. If `precision` is [`Exact`], then /// exactly `value` must be minted into the account of `who` or the operation will fail with an /// `Err` and nothing will change. /// - /// If the operation is successful, this will return `Ok` with a `Debt` of the total value + /// If the operation is successful, this will return `Ok` with a [`Debt`] of the total value /// added to the account. fn deposit( who: &AccountId, @@ -449,8 +460,8 @@ pub trait Balanced: Inspect + Unbalanced { /// Removes `value` balance from `who` account if possible. /// - /// If `precision` is `BestEffort` and `value` in full could not be removed (e.g. due to - /// underflow), then the maximum is removed, up to `value`. If `precision` is `Exact`, then + /// If `precision` is [`BestEffort`] and `value` in full could not be removed (e.g. due to + /// underflow), then the maximum is removed, up to `value`. If `precision` is [`Exact`], then /// exactly `value` must be removed from the account of `who` or the operation will fail with an /// `Err` and nothing will change. /// @@ -458,7 +469,7 @@ pub trait Balanced: Inspect + Unbalanced { /// If the account needed to be deleted, then slightly more than `value` may be removed from the /// account owning since up to (but not including) minimum balance may also need to be removed. /// - /// If the operation is successful, this will return `Ok` with a `Credit` of the total value + /// If the operation is successful, this will return `Ok` with a [`Credit`] of the total value /// removed from the account. fn withdraw( who: &AccountId, @@ -476,7 +487,7 @@ pub trait Balanced: Inspect + Unbalanced { /// cannot be countered, then nothing is changed and the original `credit` is returned in an /// `Err`. /// - /// Please note: If `credit.peek()` is less than `Self::minimum_balance()`, then `who` must + /// Please note: If `credit.peek()` is less than [`Inspect::minimum_balance()`], then `who` must /// already exist for this to succeed. fn resolve( who: &AccountId, @@ -503,7 +514,7 @@ pub trait Balanced: Inspect + Unbalanced { let amount = debt.peek(); let credit = match Self::withdraw(who, amount, Exact, preservation, Polite) { Err(_) => return Err(debt), - Ok(d) => d, + Ok(c) => c, }; match credit.offset(debt) { diff --git a/substrate/frame/support/src/traits/tokens/fungible/union_of.rs b/substrate/frame/support/src/traits/tokens/fungible/union_of.rs index 86505befc05..33711d7a16c 100644 --- a/substrate/frame/support/src/traits/tokens/fungible/union_of.rs +++ b/substrate/frame/support/src/traits/tokens/fungible/union_of.rs @@ -727,21 +727,22 @@ impl< fn pair( asset: Self::AssetId, amount: Self::Balance, - ) -> (fungibles::Debt, fungibles::Credit) { + ) -> Result<(fungibles::Debt, fungibles::Credit), DispatchError> + { match Criterion::convert(asset.clone()) { Left(()) => { - let (a, b) = >::pair(amount); - ( + let (a, b) = >::pair(amount)?; + Ok(( fungibles::imbalance::from_fungible(a, asset.clone()), fungibles::imbalance::from_fungible(b, asset), - ) + )) }, Right(a) => { - let (a, b) = >::pair(a, amount); - ( + let (a, b) = >::pair(a, amount)?; + Ok(( fungibles::imbalance::from_fungibles(a, asset.clone()), fungibles::imbalance::from_fungibles(b, asset), - ) + )) }, } } diff --git a/substrate/frame/support/src/traits/tokens/fungibles/regular.rs b/substrate/frame/support/src/traits/tokens/fungibles/regular.rs index 41ef4b40c75..8cc97802da6 100644 --- a/substrate/frame/support/src/traits/tokens/fungibles/regular.rs +++ b/substrate/frame/support/src/traits/tokens/fungibles/regular.rs @@ -194,9 +194,10 @@ pub trait Unbalanced: Inspect { force: Fortitude, ) -> Result { let old_balance = Self::balance(asset.clone(), who); - let free = Self::reducible_balance(asset.clone(), who, preservation, force); - if let BestEffort = precision { - amount = amount.min(free); + let reducible = Self::reducible_balance(asset.clone(), who, preservation, force); + match precision { + BestEffort => amount = amount.min(reducible), + Exact => ensure!(reducible >= amount, TokenError::FundsUnavailable), } let new_balance = old_balance.checked_sub(&amount).ok_or(TokenError::FundsUnavailable)?; if let Some(dust) = Self::write_balance(asset.clone(), who, new_balance)? { @@ -478,11 +479,24 @@ pub trait Balanced: Inspect + Unbalanced { /// /// This is just the same as burning and issuing the same amount and has no effect on the /// total issuance. + /// + /// This is infallible, but doesn't guarantee that the entire `amount` is used to create the + /// pair, for example in the case where the amounts would cause overflow or underflow in + /// [`Balanced::issue`] or [`Balanced::rescind`]. fn pair( asset: Self::AssetId, amount: Self::Balance, - ) -> (Debt, Credit) { - (Self::rescind(asset.clone(), amount), Self::issue(asset, amount)) + ) -> Result<(Debt, Credit), DispatchError> { + let issued = Self::issue(asset.clone(), amount); + let rescinded = Self::rescind(asset, amount); + // Need to check amount in case by some edge case both issued and rescinded are below + // `amount` by the exact same value + if issued.peek() != rescinded.peek() || issued.peek() != amount { + // Issued and rescinded will be dropped automatically + Err("Failed to issue and rescind equal amounts".into()) + } else { + Ok((rescinded, issued)) + } } /// Mints `value` into the account of `who`, creating it as needed. diff --git a/substrate/frame/support/src/traits/tokens/fungibles/union_of.rs b/substrate/frame/support/src/traits/tokens/fungibles/union_of.rs index 3619db3a37b..9d2a783df2a 100644 --- a/substrate/frame/support/src/traits/tokens/fungibles/union_of.rs +++ b/substrate/frame/support/src/traits/tokens/fungibles/union_of.rs @@ -706,15 +706,22 @@ impl< fn pair( asset: Self::AssetId, amount: Self::Balance, - ) -> (fungibles::Debt, fungibles::Credit) { + ) -> Result<(fungibles::Debt, fungibles::Credit), DispatchError> + { match Criterion::convert(asset.clone()) { Left(a) => { - let (a, b) = >::pair(a, amount); - (imbalance::from_fungibles(a, asset.clone()), imbalance::from_fungibles(b, asset)) + let (a, b) = >::pair(a, amount)?; + Ok(( + imbalance::from_fungibles(a, asset.clone()), + imbalance::from_fungibles(b, asset), + )) }, Right(a) => { - let (a, b) = >::pair(a, amount); - (imbalance::from_fungibles(a, asset.clone()), imbalance::from_fungibles(b, asset)) + let (a, b) = >::pair(a, amount)?; + Ok(( + imbalance::from_fungibles(a, asset.clone()), + imbalance::from_fungibles(b, asset), + )) }, } } -- GitLab From 53bcbb15f1de62661671ad8099b9dc3f8b623efd Mon Sep 17 00:00:00 2001 From: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> Date: Mon, 15 Jan 2024 16:03:32 +0200 Subject: [PATCH 051/392] archive: Implement archive_unstable_storage (#1846) This PR implements the `archive_unstable_storage` method that offers support for: - fetching values - fetching hashes - iterating over keys and values - iterating over keys and hashes - fetching merkle values from the trie-db A common component dedicated to RPC-V2 storage queries is created to bridge the gap between `chainHead/storage` and `archive/storage`. Query pagination is supported by `paginationStartKey`, similar to the old APIs. Similarly to the `chainHead/storage`, the `archive/storage` method accepts a maximum number of queried items. The design builds upon: https://github.com/paritytech/json-rpc-interface-spec/pull/94. Closes https://github.com/paritytech/polkadot-sdk/issues/1512. cc @paritytech/subxt-team --------- Signed-off-by: Alexandru Vasile Co-authored-by: Niklas Adolfsson --- .../client/rpc-spec-v2/src/archive/api.rs | 18 +- .../client/rpc-spec-v2/src/archive/archive.rs | 70 ++- .../src/archive/archive_storage.rs | 125 ++++ .../client/rpc-spec-v2/src/archive/mod.rs | 2 + .../client/rpc-spec-v2/src/archive/tests.rs | 547 +++++++++++++++++- .../client/rpc-spec-v2/src/chain_head/api.rs | 5 +- .../rpc-spec-v2/src/chain_head/chain_head.rs | 6 +- .../src/chain_head/chain_head_storage.rs | 210 +------ .../rpc-spec-v2/src/chain_head/event.rs | 146 +---- .../client/rpc-spec-v2/src/chain_head/mod.rs | 7 - .../rpc-spec-v2/src/chain_head/tests.rs | 7 +- .../client/rpc-spec-v2/src/common/events.rs | 273 +++++++++ .../client/rpc-spec-v2/src/common/mod.rs | 17 + .../client/rpc-spec-v2/src/common/storage.rs | 198 +++++++ substrate/client/rpc-spec-v2/src/lib.rs | 10 +- 15 files changed, 1278 insertions(+), 363 deletions(-) create mode 100644 substrate/client/rpc-spec-v2/src/archive/archive_storage.rs create mode 100644 substrate/client/rpc-spec-v2/src/common/events.rs create mode 100644 substrate/client/rpc-spec-v2/src/common/mod.rs create mode 100644 substrate/client/rpc-spec-v2/src/common/storage.rs diff --git a/substrate/client/rpc-spec-v2/src/archive/api.rs b/substrate/client/rpc-spec-v2/src/archive/api.rs index 0583111cb48..b1973830400 100644 --- a/substrate/client/rpc-spec-v2/src/archive/api.rs +++ b/substrate/client/rpc-spec-v2/src/archive/api.rs @@ -18,7 +18,10 @@ //! API trait of the archive methods. -use crate::MethodResult; +use crate::{ + common::events::{ArchiveStorageResult, PaginatedStorageQuery}, + MethodResult, +}; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; #[rpc(client, server)] @@ -88,4 +91,17 @@ pub trait ArchiveApi { function: String, call_parameters: String, ) -> RpcResult; + + /// Returns storage entries at a specific block's state. + /// + /// # Unstable + /// + /// This method is unstable and subject to change in the future. + #[method(name = "archive_unstable_storage", blocking)] + fn archive_unstable_storage( + &self, + hash: Hash, + items: Vec>, + child_trie: Option, + ) -> RpcResult; } diff --git a/substrate/client/rpc-spec-v2/src/archive/archive.rs b/substrate/client/rpc-spec-v2/src/archive/archive.rs index 269962cfd74..c01afb5d779 100644 --- a/substrate/client/rpc-spec-v2/src/archive/archive.rs +++ b/substrate/client/rpc-spec-v2/src/archive/archive.rs @@ -20,14 +20,15 @@ use crate::{ archive::{error::Error as ArchiveError, ArchiveApiServer}, - chain_head::hex_string, - MethodResult, + common::events::{ArchiveStorageResult, PaginatedStorageQuery}, + hex_string, MethodResult, }; use codec::Encode; use jsonrpsee::core::{async_trait, RpcResult}; use sc_client_api::{ - Backend, BlockBackend, BlockchainEvents, CallExecutor, ExecutorProvider, StorageProvider, + Backend, BlockBackend, BlockchainEvents, CallExecutor, ChildInfo, ExecutorProvider, StorageKey, + StorageProvider, }; use sp_api::{CallApiAt, CallContext}; use sp_blockchain::{ @@ -40,6 +41,8 @@ use sp_runtime::{ }; use std::{collections::HashSet, marker::PhantomData, sync::Arc}; +use super::archive_storage::ArchiveStorage; + /// An API for archive RPC calls. pub struct Archive, Block: BlockT, Client> { /// Substrate client. @@ -48,8 +51,12 @@ pub struct Archive, Block: BlockT, Client> { backend: Arc, /// The hexadecimal encoded hash of the genesis block. genesis_hash: String, + /// The maximum number of reported items by the `archive_storage` at a time. + storage_max_reported_items: usize, + /// The maximum number of queried items allowed for the `archive_storage` at a time. + storage_max_queried_items: usize, /// Phantom member to pin the block type. - _phantom: PhantomData<(Block, BE)>, + _phantom: PhantomData, } impl, Block: BlockT, Client> Archive { @@ -58,9 +65,18 @@ impl, Block: BlockT, Client> Archive { client: Arc, backend: Arc, genesis_hash: GenesisHash, + storage_max_reported_items: usize, + storage_max_queried_items: usize, ) -> Self { let genesis_hash = hex_string(&genesis_hash.as_ref()); - Self { client, backend, genesis_hash, _phantom: PhantomData } + Self { + client, + backend, + genesis_hash, + storage_max_reported_items, + storage_max_queried_items, + _phantom: PhantomData, + } } } @@ -185,4 +201,48 @@ where Err(error) => MethodResult::err(error.to_string()), }) } + + fn archive_unstable_storage( + &self, + hash: Block::Hash, + items: Vec>, + child_trie: Option, + ) -> RpcResult { + let items = items + .into_iter() + .map(|query| { + let key = StorageKey(parse_hex_param(query.key)?); + let pagination_start_key = query + .pagination_start_key + .map(|key| parse_hex_param(key).map(|key| StorageKey(key))) + .transpose()?; + + // Paginated start key is only supported + if pagination_start_key.is_some() && !query.query_type.is_descendant_query() { + return Err(ArchiveError::InvalidParam( + "Pagination start key is only supported for descendants queries" + .to_string(), + )) + } + + Ok(PaginatedStorageQuery { + key, + query_type: query.query_type, + pagination_start_key, + }) + }) + .collect::, ArchiveError>>()?; + + let child_trie = child_trie + .map(|child_trie| parse_hex_param(child_trie)) + .transpose()? + .map(ChildInfo::new_default_from_vec); + + let storage_client = ArchiveStorage::new( + self.client.clone(), + self.storage_max_reported_items, + self.storage_max_queried_items, + ); + Ok(storage_client.handle_query(hash, items, child_trie)) + } } diff --git a/substrate/client/rpc-spec-v2/src/archive/archive_storage.rs b/substrate/client/rpc-spec-v2/src/archive/archive_storage.rs new file mode 100644 index 00000000000..09415af1ca1 --- /dev/null +++ b/substrate/client/rpc-spec-v2/src/archive/archive_storage.rs @@ -0,0 +1,125 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Implementation of the `archive_storage` method. + +use std::sync::Arc; + +use sc_client_api::{Backend, ChildInfo, StorageKey, StorageProvider}; +use sp_runtime::traits::Block as BlockT; + +use crate::common::{ + events::{ArchiveStorageResult, PaginatedStorageQuery, StorageQueryType}, + storage::{IterQueryType, QueryIter, Storage}, +}; + +/// Generates the events of the `chainHead_storage` method. +pub struct ArchiveStorage { + /// Storage client. + client: Storage, + /// The maximum number of reported items by the `archive_storage` at a time. + storage_max_reported_items: usize, + /// The maximum number of queried items allowed for the `archive_storage` at a time. + storage_max_queried_items: usize, +} + +impl ArchiveStorage { + /// Constructs a new [`ArchiveStorage`]. + pub fn new( + client: Arc, + storage_max_reported_items: usize, + storage_max_queried_items: usize, + ) -> Self { + Self { client: Storage::new(client), storage_max_reported_items, storage_max_queried_items } + } +} + +impl ArchiveStorage +where + Block: BlockT + 'static, + BE: Backend + 'static, + Client: StorageProvider + 'static, +{ + /// Generate the response of the `archive_storage` method. + pub fn handle_query( + &self, + hash: Block::Hash, + mut items: Vec>, + child_key: Option, + ) -> ArchiveStorageResult { + let discarded_items = items.len().saturating_sub(self.storage_max_queried_items); + items.truncate(self.storage_max_queried_items); + + let mut storage_results = Vec::with_capacity(items.len()); + for item in items { + match item.query_type { + StorageQueryType::Value => { + match self.client.query_value(hash, &item.key, child_key.as_ref()) { + Ok(Some(value)) => storage_results.push(value), + Ok(None) => continue, + Err(error) => return ArchiveStorageResult::err(error), + } + }, + StorageQueryType::Hash => + match self.client.query_hash(hash, &item.key, child_key.as_ref()) { + Ok(Some(value)) => storage_results.push(value), + Ok(None) => continue, + Err(error) => return ArchiveStorageResult::err(error), + }, + StorageQueryType::ClosestDescendantMerkleValue => + match self.client.query_merkle_value(hash, &item.key, child_key.as_ref()) { + Ok(Some(value)) => storage_results.push(value), + Ok(None) => continue, + Err(error) => return ArchiveStorageResult::err(error), + }, + StorageQueryType::DescendantsValues => { + match self.client.query_iter_pagination( + QueryIter { + query_key: item.key, + ty: IterQueryType::Value, + pagination_start_key: item.pagination_start_key, + }, + hash, + child_key.as_ref(), + self.storage_max_reported_items, + ) { + Ok((results, _)) => storage_results.extend(results), + Err(error) => return ArchiveStorageResult::err(error), + } + }, + StorageQueryType::DescendantsHashes => { + match self.client.query_iter_pagination( + QueryIter { + query_key: item.key, + ty: IterQueryType::Hash, + pagination_start_key: item.pagination_start_key, + }, + hash, + child_key.as_ref(), + self.storage_max_reported_items, + ) { + Ok((results, _)) => storage_results.extend(results), + Err(error) => return ArchiveStorageResult::err(error), + } + }, + }; + } + + ArchiveStorageResult::ok(storage_results, discarded_items) + } +} diff --git a/substrate/client/rpc-spec-v2/src/archive/mod.rs b/substrate/client/rpc-spec-v2/src/archive/mod.rs index eb7d71d702f..e1f45e19a62 100644 --- a/substrate/client/rpc-spec-v2/src/archive/mod.rs +++ b/substrate/client/rpc-spec-v2/src/archive/mod.rs @@ -25,6 +25,8 @@ #[cfg(test)] mod tests; +mod archive_storage; + pub mod api; pub mod archive; pub mod error; diff --git a/substrate/client/rpc-spec-v2/src/archive/tests.rs b/substrate/client/rpc-spec-v2/src/archive/tests.rs index 6b288c2c954..45da8e588e6 100644 --- a/substrate/client/rpc-spec-v2/src/archive/tests.rs +++ b/substrate/client/rpc-spec-v2/src/archive/tests.rs @@ -16,7 +16,13 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use crate::{chain_head::hex_string, MethodResult}; +use crate::{ + common::events::{ + ArchiveStorageMethodOk, ArchiveStorageResult, PaginatedStorageQuery, StorageQueryType, + StorageResultType, + }, + hex_string, MethodResult, +}; use super::{archive::Archive, *}; @@ -24,17 +30,20 @@ use assert_matches::assert_matches; use codec::{Decode, Encode}; use jsonrpsee::{ core::error::Error, + rpc_params, types::{error::CallError, EmptyServerParams as EmptyParams}, RpcModule, }; use sc_block_builder::BlockBuilderBuilder; +use sc_client_api::ChildInfo; use sp_blockchain::HeaderBackend; use sp_consensus::BlockOrigin; +use sp_core::{Blake2Hasher, Hasher}; use sp_runtime::{ traits::{Block as BlockT, Header as HeaderT}, SaturatedConversion, }; -use std::sync::Arc; +use std::{collections::HashMap, sync::Arc}; use substrate_test_runtime::Transfer; use substrate_test_runtime_client::{ prelude::*, runtime, Backend, BlockBuilderExt, Client, ClientBlockImportExt, @@ -42,23 +51,39 @@ use substrate_test_runtime_client::{ const CHAIN_GENESIS: [u8; 32] = [0; 32]; const INVALID_HASH: [u8; 32] = [1; 32]; +const MAX_PAGINATION_LIMIT: usize = 5; +const MAX_QUERIED_LIMIT: usize = 5; +const KEY: &[u8] = b":mock"; +const VALUE: &[u8] = b"hello world"; +const CHILD_STORAGE_KEY: &[u8] = b"child"; +const CHILD_VALUE: &[u8] = b"child value"; type Header = substrate_test_runtime_client::runtime::Header; type Block = substrate_test_runtime_client::runtime::Block; -fn setup_api() -> (Arc>, RpcModule>>) { - let builder = TestClientBuilder::new(); +fn setup_api( + max_returned_items: usize, + max_queried_items: usize, +) -> (Arc>, RpcModule>>) { + let child_info = ChildInfo::new_default(CHILD_STORAGE_KEY); + let builder = TestClientBuilder::new().add_extra_child_storage( + &child_info, + KEY.to_vec(), + CHILD_VALUE.to_vec(), + ); let backend = builder.backend(); let client = Arc::new(builder.build()); - let api = Archive::new(client.clone(), backend, CHAIN_GENESIS).into_rpc(); + let api = + Archive::new(client.clone(), backend, CHAIN_GENESIS, max_returned_items, max_queried_items) + .into_rpc(); (client, api) } #[tokio::test] async fn archive_genesis() { - let (_client, api) = setup_api(); + let (_client, api) = setup_api(MAX_PAGINATION_LIMIT, MAX_QUERIED_LIMIT); let genesis: String = api.call("archive_unstable_genesisHash", EmptyParams::new()).await.unwrap(); @@ -67,7 +92,7 @@ async fn archive_genesis() { #[tokio::test] async fn archive_body() { - let (mut client, api) = setup_api(); + let (mut client, api) = setup_api(MAX_PAGINATION_LIMIT, MAX_QUERIED_LIMIT); // Invalid block hash. let invalid_hash = hex_string(&INVALID_HASH); @@ -101,7 +126,7 @@ async fn archive_body() { #[tokio::test] async fn archive_header() { - let (mut client, api) = setup_api(); + let (mut client, api) = setup_api(MAX_PAGINATION_LIMIT, MAX_QUERIED_LIMIT); // Invalid block hash. let invalid_hash = hex_string(&INVALID_HASH); @@ -135,7 +160,7 @@ async fn archive_header() { #[tokio::test] async fn archive_finalized_height() { - let (client, api) = setup_api(); + let (client, api) = setup_api(MAX_PAGINATION_LIMIT, MAX_QUERIED_LIMIT); let client_height: u32 = client.info().finalized_number.saturated_into(); @@ -147,7 +172,7 @@ async fn archive_finalized_height() { #[tokio::test] async fn archive_hash_by_height() { - let (mut client, api) = setup_api(); + let (mut client, api) = setup_api(MAX_PAGINATION_LIMIT, MAX_QUERIED_LIMIT); // Genesis height. let hashes: Vec = api.call("archive_unstable_hashByHeight", [0]).await.unwrap(); @@ -253,7 +278,7 @@ async fn archive_hash_by_height() { #[tokio::test] async fn archive_call() { - let (mut client, api) = setup_api(); + let (mut client, api) = setup_api(MAX_PAGINATION_LIMIT, MAX_QUERIED_LIMIT); let invalid_hash = hex_string(&INVALID_HASH); // Invalid parameter (non-hex). @@ -309,3 +334,503 @@ async fn archive_call() { let expected = MethodResult::ok("0x0000000000000000"); assert_eq!(result, expected); } + +#[tokio::test] +async fn archive_storage_hashes_values() { + let (mut client, api) = setup_api(MAX_PAGINATION_LIMIT, MAX_QUERIED_LIMIT); + + let block = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().genesis_hash) + .with_parent_block_number(0) + .build() + .unwrap() + .build() + .unwrap() + .block; + client.import(BlockOrigin::Own, block.clone()).await.unwrap(); + let block_hash = format!("{:?}", block.header.hash()); + let key = hex_string(&KEY); + + let items: Vec> = vec![ + PaginatedStorageQuery { + key: key.clone(), + query_type: StorageQueryType::DescendantsHashes, + pagination_start_key: None, + }, + PaginatedStorageQuery { + key: key.clone(), + query_type: StorageQueryType::DescendantsValues, + pagination_start_key: None, + }, + PaginatedStorageQuery { + key: key.clone(), + query_type: StorageQueryType::Hash, + pagination_start_key: None, + }, + PaginatedStorageQuery { + key: key.clone(), + query_type: StorageQueryType::Value, + pagination_start_key: None, + }, + ]; + + let result: ArchiveStorageResult = api + .call("archive_unstable_storage", rpc_params![&block_hash, items.clone()]) + .await + .unwrap(); + + match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, discarded_items }) => { + // Key has not been imported yet. + assert_eq!(result.len(), 0); + assert_eq!(discarded_items, 0); + }, + _ => panic!("Unexpected result"), + }; + + // Import a block with the given key value pair. + let mut builder = BlockBuilderBuilder::new(&*client) + .on_parent_block(block.hash()) + .with_parent_block_number(1) + .build() + .unwrap(); + builder.push_storage_change(KEY.to_vec(), Some(VALUE.to_vec())).unwrap(); + let block = builder.build().unwrap().block; + client.import(BlockOrigin::Own, block.clone()).await.unwrap(); + + let block_hash = format!("{:?}", block.header.hash()); + let expected_hash = format!("{:?}", Blake2Hasher::hash(&VALUE)); + let expected_value = hex_string(&VALUE); + + let result: ArchiveStorageResult = api + .call("archive_unstable_storage", rpc_params![&block_hash, items]) + .await + .unwrap(); + + match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, discarded_items }) => { + assert_eq!(result.len(), 4); + assert_eq!(discarded_items, 0); + + assert_eq!(result[0].key, key); + assert_eq!(result[0].result, StorageResultType::Hash(expected_hash.clone())); + assert_eq!(result[1].key, key); + assert_eq!(result[1].result, StorageResultType::Value(expected_value.clone())); + assert_eq!(result[2].key, key); + assert_eq!(result[2].result, StorageResultType::Hash(expected_hash)); + assert_eq!(result[3].key, key); + assert_eq!(result[3].result, StorageResultType::Value(expected_value)); + }, + _ => panic!("Unexpected result"), + }; +} + +#[tokio::test] +async fn archive_storage_closest_merkle_value() { + let (mut client, api) = setup_api(MAX_PAGINATION_LIMIT, MAX_QUERIED_LIMIT); + + /// The core of this test. + /// + /// Checks keys that are exact match, keys with descedant and keys that should not return + /// values. + /// + /// Returns (key, merkle value) pairs. + async fn expect_merkle_request( + api: &RpcModule>>, + block_hash: String, + ) -> HashMap { + let result: ArchiveStorageResult = api + .call( + "archive_unstable_storage", + rpc_params![ + &block_hash, + vec![ + PaginatedStorageQuery { + key: hex_string(b":AAAA"), + query_type: StorageQueryType::ClosestDescendantMerkleValue, + pagination_start_key: None, + }, + PaginatedStorageQuery { + key: hex_string(b":AAAB"), + query_type: StorageQueryType::ClosestDescendantMerkleValue, + pagination_start_key: None, + }, + // Key with descedent. + PaginatedStorageQuery { + key: hex_string(b":A"), + query_type: StorageQueryType::ClosestDescendantMerkleValue, + pagination_start_key: None, + }, + PaginatedStorageQuery { + key: hex_string(b":AA"), + query_type: StorageQueryType::ClosestDescendantMerkleValue, + pagination_start_key: None, + }, + // Keys below this comment do not produce a result. + // Key that exceed the keyspace of the trie. + PaginatedStorageQuery { + key: hex_string(b":AAAAX"), + query_type: StorageQueryType::ClosestDescendantMerkleValue, + pagination_start_key: None, + }, + PaginatedStorageQuery { + key: hex_string(b":AAABX"), + query_type: StorageQueryType::ClosestDescendantMerkleValue, + pagination_start_key: None, + }, + // Key that are not part of the trie. + PaginatedStorageQuery { + key: hex_string(b":AAX"), + query_type: StorageQueryType::ClosestDescendantMerkleValue, + pagination_start_key: None, + }, + PaginatedStorageQuery { + key: hex_string(b":AAAX"), + query_type: StorageQueryType::ClosestDescendantMerkleValue, + pagination_start_key: None, + }, + ] + ], + ) + .await + .unwrap(); + + let merkle_values: HashMap<_, _> = match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, .. }) => result + .into_iter() + .map(|res| { + let value = match res.result { + StorageResultType::ClosestDescendantMerkleValue(value) => value, + _ => panic!("Unexpected StorageResultType"), + }; + (res.key, value) + }) + .collect(), + _ => panic!("Unexpected result"), + }; + + // Response for AAAA, AAAB, A and AA. + assert_eq!(merkle_values.len(), 4); + + // While checking for expected merkle values to align, + // the following will check that the returned keys are + // expected. + + // Values for AAAA and AAAB are different. + assert_ne!( + merkle_values.get(&hex_string(b":AAAA")).unwrap(), + merkle_values.get(&hex_string(b":AAAB")).unwrap() + ); + + // Values for A and AA should be on the same branch node. + assert_eq!( + merkle_values.get(&hex_string(b":A")).unwrap(), + merkle_values.get(&hex_string(b":AA")).unwrap() + ); + // The branch node value must be different than the leaf of either + // AAAA and AAAB. + assert_ne!( + merkle_values.get(&hex_string(b":A")).unwrap(), + merkle_values.get(&hex_string(b":AAAA")).unwrap() + ); + assert_ne!( + merkle_values.get(&hex_string(b":A")).unwrap(), + merkle_values.get(&hex_string(b":AAAB")).unwrap() + ); + + merkle_values + } + + // Import a new block with storage changes. + let mut builder = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().genesis_hash) + .with_parent_block_number(0) + .build() + .unwrap(); + builder.push_storage_change(b":AAAA".to_vec(), Some(vec![1; 64])).unwrap(); + builder.push_storage_change(b":AAAB".to_vec(), Some(vec![2; 64])).unwrap(); + let block = builder.build().unwrap().block; + let block_hash = format!("{:?}", block.header.hash()); + client.import(BlockOrigin::Own, block.clone()).await.unwrap(); + + let merkle_values_lhs = expect_merkle_request(&api, block_hash).await; + + // Import a new block with and change AAAB value. + let mut builder = BlockBuilderBuilder::new(&*client) + .on_parent_block(block.hash()) + .with_parent_block_number(1) + .build() + .unwrap(); + builder.push_storage_change(b":AAAA".to_vec(), Some(vec![1; 64])).unwrap(); + builder.push_storage_change(b":AAAB".to_vec(), Some(vec![3; 64])).unwrap(); + let block = builder.build().unwrap().block; + let block_hash = format!("{:?}", block.header.hash()); + client.import(BlockOrigin::Own, block.clone()).await.unwrap(); + + let merkle_values_rhs = expect_merkle_request(&api, block_hash).await; + + // Change propagated to the root. + assert_ne!( + merkle_values_lhs.get(&hex_string(b":A")).unwrap(), + merkle_values_rhs.get(&hex_string(b":A")).unwrap() + ); + assert_ne!( + merkle_values_lhs.get(&hex_string(b":AAAB")).unwrap(), + merkle_values_rhs.get(&hex_string(b":AAAB")).unwrap() + ); + // However the AAAA branch leaf remains unchanged. + assert_eq!( + merkle_values_lhs.get(&hex_string(b":AAAA")).unwrap(), + merkle_values_rhs.get(&hex_string(b":AAAA")).unwrap() + ); +} + +#[tokio::test] +async fn archive_storage_paginate_iterations() { + // 1 iteration allowed before pagination kicks in. + let (mut client, api) = setup_api(1, MAX_QUERIED_LIMIT); + + // Import a new block with storage changes. + let mut builder = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().genesis_hash) + .with_parent_block_number(0) + .build() + .unwrap(); + builder.push_storage_change(b":m".to_vec(), Some(b"a".to_vec())).unwrap(); + builder.push_storage_change(b":mo".to_vec(), Some(b"ab".to_vec())).unwrap(); + builder.push_storage_change(b":moc".to_vec(), Some(b"abc".to_vec())).unwrap(); + builder.push_storage_change(b":moD".to_vec(), Some(b"abcmoD".to_vec())).unwrap(); + builder.push_storage_change(b":mock".to_vec(), Some(b"abcd".to_vec())).unwrap(); + let block = builder.build().unwrap().block; + let block_hash = format!("{:?}", block.header.hash()); + client.import(BlockOrigin::Own, block.clone()).await.unwrap(); + + // Calling with an invalid hash. + let invalid_hash = hex_string(&INVALID_HASH); + let result: ArchiveStorageResult = api + .call( + "archive_unstable_storage", + rpc_params![ + &invalid_hash, + vec![PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::DescendantsValues, + pagination_start_key: None, + }] + ], + ) + .await + .unwrap(); + match result { + ArchiveStorageResult::Err(_) => (), + _ => panic!("Unexpected result"), + }; + + // Valid call with storage at the key. + let result: ArchiveStorageResult = api + .call( + "archive_unstable_storage", + rpc_params![ + &block_hash, + vec![PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::DescendantsValues, + pagination_start_key: None, + }] + ], + ) + .await + .unwrap(); + match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, discarded_items }) => { + assert_eq!(result.len(), 1); + assert_eq!(discarded_items, 0); + + assert_eq!(result[0].key, hex_string(b":m")); + assert_eq!(result[0].result, StorageResultType::Value(hex_string(b"a"))); + }, + _ => panic!("Unexpected result"), + }; + + // Continue with pagination. + let result: ArchiveStorageResult = api + .call( + "archive_unstable_storage", + rpc_params![ + &block_hash, + vec![PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::DescendantsValues, + pagination_start_key: Some(hex_string(b":m")), + }] + ], + ) + .await + .unwrap(); + match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, discarded_items }) => { + assert_eq!(result.len(), 1); + assert_eq!(discarded_items, 0); + + assert_eq!(result[0].key, hex_string(b":mo")); + assert_eq!(result[0].result, StorageResultType::Value(hex_string(b"ab"))); + }, + _ => panic!("Unexpected result"), + }; + + // Continue with pagination. + let result: ArchiveStorageResult = api + .call( + "archive_unstable_storage", + rpc_params![ + &block_hash, + vec![PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::DescendantsValues, + pagination_start_key: Some(hex_string(b":mo")), + }] + ], + ) + .await + .unwrap(); + match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, discarded_items }) => { + assert_eq!(result.len(), 1); + assert_eq!(discarded_items, 0); + + assert_eq!(result[0].key, hex_string(b":moD")); + assert_eq!(result[0].result, StorageResultType::Value(hex_string(b"abcmoD"))); + }, + _ => panic!("Unexpected result"), + }; + + // Continue with pagination. + let result: ArchiveStorageResult = api + .call( + "archive_unstable_storage", + rpc_params![ + &block_hash, + vec![PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::DescendantsValues, + pagination_start_key: Some(hex_string(b":moD")), + }] + ], + ) + .await + .unwrap(); + match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, discarded_items }) => { + assert_eq!(result.len(), 1); + assert_eq!(discarded_items, 0); + + assert_eq!(result[0].key, hex_string(b":moc")); + assert_eq!(result[0].result, StorageResultType::Value(hex_string(b"abc"))); + }, + _ => panic!("Unexpected result"), + }; + + // Continue with pagination. + let result: ArchiveStorageResult = api + .call( + "archive_unstable_storage", + rpc_params![ + &block_hash, + vec![PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::DescendantsValues, + pagination_start_key: Some(hex_string(b":moc")), + }] + ], + ) + .await + .unwrap(); + match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, discarded_items }) => { + assert_eq!(result.len(), 1); + assert_eq!(discarded_items, 0); + + assert_eq!(result[0].key, hex_string(b":mock")); + assert_eq!(result[0].result, StorageResultType::Value(hex_string(b"abcd"))); + }, + _ => panic!("Unexpected result"), + }; + + // Continue with pagination until no keys are returned. + let result: ArchiveStorageResult = api + .call( + "archive_unstable_storage", + rpc_params![ + &block_hash, + vec![PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::DescendantsValues, + pagination_start_key: Some(hex_string(b":mock")), + }] + ], + ) + .await + .unwrap(); + match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, discarded_items }) => { + assert_eq!(result.len(), 0); + assert_eq!(discarded_items, 0); + }, + _ => panic!("Unexpected result"), + }; +} + +#[tokio::test] +async fn archive_storage_discarded_items() { + // One query at a time + let (mut client, api) = setup_api(MAX_PAGINATION_LIMIT, 1); + + // Import a new block with storage changes. + let mut builder = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().genesis_hash) + .with_parent_block_number(0) + .build() + .unwrap(); + builder.push_storage_change(b":m".to_vec(), Some(b"a".to_vec())).unwrap(); + let block = builder.build().unwrap().block; + let block_hash = format!("{:?}", block.header.hash()); + client.import(BlockOrigin::Own, block.clone()).await.unwrap(); + + // Valid call with storage at the key. + let result: ArchiveStorageResult = api + .call( + "archive_unstable_storage", + rpc_params![ + &block_hash, + vec![ + PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::Value, + pagination_start_key: None, + }, + PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::Hash, + pagination_start_key: None, + }, + PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::Hash, + pagination_start_key: None, + } + ] + ], + ) + .await + .unwrap(); + match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, discarded_items }) => { + assert_eq!(result.len(), 1); + assert_eq!(discarded_items, 2); + + assert_eq!(result[0].key, hex_string(b":m")); + assert_eq!(result[0].result, StorageResultType::Value(hex_string(b"a"))); + }, + _ => panic!("Unexpected result"), + }; +} diff --git a/substrate/client/rpc-spec-v2/src/chain_head/api.rs b/substrate/client/rpc-spec-v2/src/chain_head/api.rs index 9ae80137955..3d6091b91bd 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/api.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/api.rs @@ -19,7 +19,10 @@ #![allow(non_snake_case)] //! API trait of the chain head. -use crate::chain_head::event::{FollowEvent, MethodResponse, StorageQuery}; +use crate::{ + chain_head::event::{FollowEvent, MethodResponse}, + common::events::StorageQuery, +}; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; use sp_rpc::list::ListOrValue; diff --git a/substrate/client/rpc-spec-v2/src/chain_head/chain_head.rs b/substrate/client/rpc-spec-v2/src/chain_head/chain_head.rs index 8e04ac7b177..6e4d6ade965 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/chain_head.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/chain_head.rs @@ -27,11 +27,11 @@ use crate::{ api::ChainHeadApiServer, chain_head_follow::ChainHeadFollower, error::Error as ChainHeadRpcError, - event::{FollowEvent, MethodResponse, OperationError, StorageQuery}, - hex_string, + event::{FollowEvent, MethodResponse, OperationError}, subscription::{SubscriptionManagement, SubscriptionManagementError}, }, - SubscriptionTaskExecutor, + common::events::StorageQuery, + hex_string, SubscriptionTaskExecutor, }; use codec::Encode; use futures::future::FutureExt; diff --git a/substrate/client/rpc-spec-v2/src/chain_head/chain_head_storage.rs b/substrate/client/rpc-spec-v2/src/chain_head/chain_head_storage.rs index c23489a050e..ee39ec253a3 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/chain_head_storage.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/chain_head_storage.rs @@ -22,33 +22,24 @@ use std::{collections::VecDeque, marker::PhantomData, sync::Arc}; use sc_client_api::{Backend, ChildInfo, StorageKey, StorageProvider}; use sc_utils::mpsc::TracingUnboundedSender; -use sp_core::storage::well_known_keys; use sp_runtime::traits::Block as BlockT; -use crate::chain_head::event::OperationStorageItems; - -use super::{ - event::{ - OperationError, OperationId, StorageQuery, StorageQueryType, StorageResult, - StorageResultType, +use crate::{ + chain_head::{ + event::{OperationError, OperationId, OperationStorageItems}, + subscription::BlockGuard, + FollowEvent, + }, + common::{ + events::{StorageQuery, StorageQueryType}, + storage::{IterQueryType, QueryIter, QueryIterResult, Storage}, }, - hex_string, - subscription::BlockGuard, - FollowEvent, }; -/// The query type of an interation. -enum IterQueryType { - /// Iterating over (key, value) pairs. - Value, - /// Iterating over (key, hash) pairs. - Hash, -} - /// Generates the events of the `chainHead_storage` method. pub struct ChainHeadStorage { - /// Substrate client. - client: Arc, + /// Storage client. + client: Storage, /// Queue of operations that may require pagination. iter_operations: VecDeque, /// The maximum number of items reported by the `chainHead_storage` before @@ -61,7 +52,7 @@ impl ChainHeadStorage { /// Constructs a new [`ChainHeadStorage`]. pub fn new(client: Arc, operation_max_storage_items: usize) -> Self { Self { - client, + client: Storage::new(client), iter_operations: VecDeque::new(), operation_max_storage_items, _phandom: PhantomData, @@ -69,163 +60,12 @@ impl ChainHeadStorage { } } -/// Query to iterate over storage. -struct QueryIter { - /// The key from which the iteration was started. - query_key: StorageKey, - /// The key after which pagination should resume. - pagination_start_key: Option, - /// The type of the query (either value or hash). - ty: IterQueryType, -} - -/// Checks if the provided key (main or child key) is valid -/// for queries. -/// -/// Keys that are identical to `:child_storage:` or `:child_storage:default:` -/// are not queryable. -fn is_key_queryable(key: &[u8]) -> bool { - !well_known_keys::is_default_child_storage_key(key) && - !well_known_keys::is_child_storage_key(key) -} - -/// The result of making a query call. -type QueryResult = Result, String>; - -/// The result of iterating over keys. -type QueryIterResult = Result<(Vec, Option), String>; - impl ChainHeadStorage where Block: BlockT + 'static, BE: Backend + 'static, Client: StorageProvider + 'static, { - /// Fetch the value from storage. - fn query_storage_value( - &self, - hash: Block::Hash, - key: &StorageKey, - child_key: Option<&ChildInfo>, - ) -> QueryResult { - let result = if let Some(child_key) = child_key { - self.client.child_storage(hash, child_key, key) - } else { - self.client.storage(hash, key) - }; - - result - .map(|opt| { - QueryResult::Ok(opt.map(|storage_data| StorageResult { - key: hex_string(&key.0), - result: StorageResultType::Value(hex_string(&storage_data.0)), - })) - }) - .unwrap_or_else(|error| QueryResult::Err(error.to_string())) - } - - /// Fetch the hash of a value from storage. - fn query_storage_hash( - &self, - hash: Block::Hash, - key: &StorageKey, - child_key: Option<&ChildInfo>, - ) -> QueryResult { - let result = if let Some(child_key) = child_key { - self.client.child_storage_hash(hash, child_key, key) - } else { - self.client.storage_hash(hash, key) - }; - - result - .map(|opt| { - QueryResult::Ok(opt.map(|storage_data| StorageResult { - key: hex_string(&key.0), - result: StorageResultType::Hash(hex_string(&storage_data.as_ref())), - })) - }) - .unwrap_or_else(|error| QueryResult::Err(error.to_string())) - } - - /// Fetch the closest merkle value. - fn query_storage_merkle_value( - &self, - hash: Block::Hash, - key: &StorageKey, - child_key: Option<&ChildInfo>, - ) -> QueryResult { - let result = if let Some(child_key) = child_key { - self.client.child_closest_merkle_value(hash, child_key, key) - } else { - self.client.closest_merkle_value(hash, key) - }; - - result - .map(|opt| { - QueryResult::Ok(opt.map(|storage_data| { - let result = match &storage_data { - sc_client_api::MerkleValue::Node(data) => hex_string(&data.as_slice()), - sc_client_api::MerkleValue::Hash(hash) => hex_string(&hash.as_ref()), - }; - - StorageResult { - key: hex_string(&key.0), - result: StorageResultType::ClosestDescendantMerkleValue(result), - } - })) - }) - .unwrap_or_else(|error| QueryResult::Err(error.to_string())) - } - - /// Iterate over at most `operation_max_storage_items` keys. - /// - /// Returns the storage result with a potential next key to resume iteration. - fn query_storage_iter_pagination( - &self, - query: QueryIter, - hash: Block::Hash, - child_key: Option<&ChildInfo>, - ) -> QueryIterResult { - let QueryIter { ty, query_key, pagination_start_key } = query; - - let mut keys_iter = if let Some(child_key) = child_key { - self.client.child_storage_keys( - hash, - child_key.to_owned(), - Some(&query_key), - pagination_start_key.as_ref(), - ) - } else { - self.client.storage_keys(hash, Some(&query_key), pagination_start_key.as_ref()) - } - .map_err(|err| err.to_string())?; - - let mut ret = Vec::with_capacity(self.operation_max_storage_items); - let mut next_pagination_key = None; - for _ in 0..self.operation_max_storage_items { - let Some(key) = keys_iter.next() else { break }; - - next_pagination_key = Some(key.clone()); - - let result = match ty { - IterQueryType::Value => self.query_storage_value(hash, &key, child_key), - IterQueryType::Hash => self.query_storage_hash(hash, &key, child_key), - }?; - - if let Some(value) = result { - ret.push(value); - } - } - - // Save the next key if any to continue the iteration. - let maybe_next_query = keys_iter.next().map(|_| QueryIter { - ty, - query_key, - pagination_start_key: next_pagination_key, - }); - Ok((ret, maybe_next_query)) - } - /// Iterate over (key, hash) and (key, value) generating the `WaitingForContinue` event if /// necessary. async fn generate_storage_iter_events( @@ -242,7 +82,12 @@ where return } - let result = self.query_storage_iter_pagination(query, hash, child_key.as_ref()); + let result = self.client.query_iter_pagination( + query, + hash, + child_key.as_ref(), + self.operation_max_storage_items, + ); let (events, maybe_next_query) = match result { QueryIterResult::Ok(result) => result, QueryIterResult::Err(error) => { @@ -294,24 +139,11 @@ where let sender = block_guard.response_sender(); let operation = block_guard.operation(); - if let Some(child_key) = child_key.as_ref() { - if !is_key_queryable(child_key.storage_key()) { - let _ = sender.unbounded_send(FollowEvent::::OperationStorageDone( - OperationId { operation_id: operation.operation_id() }, - )); - return - } - } - let mut storage_results = Vec::with_capacity(items.len()); for item in items { - if !is_key_queryable(&item.key.0) { - continue - } - match item.query_type { StorageQueryType::Value => { - match self.query_storage_value(hash, &item.key, child_key.as_ref()) { + match self.client.query_value(hash, &item.key, child_key.as_ref()) { Ok(Some(value)) => storage_results.push(value), Ok(None) => continue, Err(error) => { @@ -321,7 +153,7 @@ where } }, StorageQueryType::Hash => - match self.query_storage_hash(hash, &item.key, child_key.as_ref()) { + match self.client.query_hash(hash, &item.key, child_key.as_ref()) { Ok(Some(value)) => storage_results.push(value), Ok(None) => continue, Err(error) => { @@ -330,7 +162,7 @@ where }, }, StorageQueryType::ClosestDescendantMerkleValue => - match self.query_storage_merkle_value(hash, &item.key, child_key.as_ref()) { + match self.client.query_merkle_value(hash, &item.key, child_key.as_ref()) { Ok(Some(value)) => storage_results.push(value), Ok(None) => continue, Err(error) => { diff --git a/substrate/client/rpc-spec-v2/src/chain_head/event.rs b/substrate/client/rpc-spec-v2/src/chain_head/event.rs index b5f9d6cc2ff..560ab87eab4 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/event.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/event.rs @@ -23,6 +23,8 @@ use sp_api::ApiError; use sp_version::RuntimeVersion; use std::collections::BTreeMap; +use crate::common::events::StorageResult; + /// The operation could not be processed due to an error. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -313,56 +315,6 @@ pub enum FollowEvent { Stop, } -/// The storage item received as paramter. -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct StorageQuery { - /// The provided key. - pub key: Key, - /// The type of the storage query. - #[serde(rename = "type")] - pub query_type: StorageQueryType, -} - -/// The type of the storage query. -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub enum StorageQueryType { - /// Fetch the value of the provided key. - Value, - /// Fetch the hash of the value of the provided key. - Hash, - /// Fetch the closest descendant merkle value. - ClosestDescendantMerkleValue, - /// Fetch the values of all descendants of they provided key. - DescendantsValues, - /// Fetch the hashes of the values of all descendants of they provided key. - DescendantsHashes, -} - -/// The storage result. -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct StorageResult { - /// The hex-encoded key of the result. - pub key: String, - /// The result of the query. - #[serde(flatten)] - pub result: StorageResultType, -} - -/// The type of the storage query. -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub enum StorageResultType { - /// Fetch the value of the provided key. - Value(String), - /// Fetch the hash of the value of the provided key. - Hash(String), - /// Fetch the closest descendant merkle value. - ClosestDescendantMerkleValue(String), -} - /// The method respose of `chainHead_body`, `chainHead_call` and `chainHead_storage`. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -388,6 +340,8 @@ pub struct MethodResponseStarted { #[cfg(test)] mod tests { + use crate::common::events::StorageResultType; + use super::*; #[test] @@ -697,96 +651,4 @@ mod tests { let event_dec: MethodResponse = serde_json::from_str(exp).unwrap(); assert_eq!(event_dec, event); } - - #[test] - fn chain_head_storage_query() { - // Item with Value. - let item = StorageQuery { key: "0x1", query_type: StorageQueryType::Value }; - // Encode - let ser = serde_json::to_string(&item).unwrap(); - let exp = r#"{"key":"0x1","type":"value"}"#; - assert_eq!(ser, exp); - // Decode - let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); - assert_eq!(dec, item); - - // Item with Hash. - let item = StorageQuery { key: "0x1", query_type: StorageQueryType::Hash }; - // Encode - let ser = serde_json::to_string(&item).unwrap(); - let exp = r#"{"key":"0x1","type":"hash"}"#; - assert_eq!(ser, exp); - // Decode - let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); - assert_eq!(dec, item); - - // Item with DescendantsValues. - let item = StorageQuery { key: "0x1", query_type: StorageQueryType::DescendantsValues }; - // Encode - let ser = serde_json::to_string(&item).unwrap(); - let exp = r#"{"key":"0x1","type":"descendantsValues"}"#; - assert_eq!(ser, exp); - // Decode - let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); - assert_eq!(dec, item); - - // Item with DescendantsHashes. - let item = StorageQuery { key: "0x1", query_type: StorageQueryType::DescendantsHashes }; - // Encode - let ser = serde_json::to_string(&item).unwrap(); - let exp = r#"{"key":"0x1","type":"descendantsHashes"}"#; - assert_eq!(ser, exp); - // Decode - let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); - assert_eq!(dec, item); - - // Item with Merkle. - let item = - StorageQuery { key: "0x1", query_type: StorageQueryType::ClosestDescendantMerkleValue }; - // Encode - let ser = serde_json::to_string(&item).unwrap(); - let exp = r#"{"key":"0x1","type":"closestDescendantMerkleValue"}"#; - assert_eq!(ser, exp); - // Decode - let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); - assert_eq!(dec, item); - } - - #[test] - fn chain_head_storage_result() { - // Item with Value. - let item = - StorageResult { key: "0x1".into(), result: StorageResultType::Value("res".into()) }; - // Encode - let ser = serde_json::to_string(&item).unwrap(); - let exp = r#"{"key":"0x1","value":"res"}"#; - assert_eq!(ser, exp); - // Decode - let dec: StorageResult = serde_json::from_str(exp).unwrap(); - assert_eq!(dec, item); - - // Item with Hash. - let item = - StorageResult { key: "0x1".into(), result: StorageResultType::Hash("res".into()) }; - // Encode - let ser = serde_json::to_string(&item).unwrap(); - let exp = r#"{"key":"0x1","hash":"res"}"#; - assert_eq!(ser, exp); - // Decode - let dec: StorageResult = serde_json::from_str(exp).unwrap(); - assert_eq!(dec, item); - - // Item with DescendantsValues. - let item = StorageResult { - key: "0x1".into(), - result: StorageResultType::ClosestDescendantMerkleValue("res".into()), - }; - // Encode - let ser = serde_json::to_string(&item).unwrap(); - let exp = r#"{"key":"0x1","closestDescendantMerkleValue":"res"}"#; - assert_eq!(ser, exp); - // Decode - let dec: StorageResult = serde_json::from_str(exp).unwrap(); - assert_eq!(dec, item); - } } diff --git a/substrate/client/rpc-spec-v2/src/chain_head/mod.rs b/substrate/client/rpc-spec-v2/src/chain_head/mod.rs index 1bd22885780..4cbbd00f64f 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/mod.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/mod.rs @@ -42,10 +42,3 @@ pub use event::{ BestBlockChanged, ErrorEvent, Finalized, FollowEvent, Initialized, NewBlock, RuntimeEvent, RuntimeVersionEvent, }; - -use sp_core::hexdisplay::{AsBytesRef, HexDisplay}; - -/// Util function to print the results of `chianHead` as hex string -pub(crate) fn hex_string(data: &Data) -> String { - format!("0x{:?}", HexDisplay::from(data)) -} diff --git a/substrate/client/rpc-spec-v2/src/chain_head/tests.rs b/substrate/client/rpc-spec-v2/src/chain_head/tests.rs index c8f2362b9eb..4859793a8e2 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/tests.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/tests.rs @@ -16,9 +16,10 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use crate::chain_head::{ - event::{MethodResponse, StorageQuery, StorageQueryType, StorageResultType}, - test_utils::ChainHeadMockClient, +use crate::{ + chain_head::{event::MethodResponse, test_utils::ChainHeadMockClient}, + common::events::{StorageQuery, StorageQueryType, StorageResultType}, + hex_string, }; use super::*; diff --git a/substrate/client/rpc-spec-v2/src/common/events.rs b/substrate/client/rpc-spec-v2/src/common/events.rs new file mode 100644 index 00000000000..b1627d74c84 --- /dev/null +++ b/substrate/client/rpc-spec-v2/src/common/events.rs @@ -0,0 +1,273 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Common events for RPC-V2 spec. + +use serde::{Deserialize, Serialize}; + +/// The storage item to query. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct StorageQuery { + /// The provided key. + pub key: Key, + /// The type of the storage query. + #[serde(rename = "type")] + pub query_type: StorageQueryType, +} + +/// The storage item to query with pagination. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PaginatedStorageQuery { + /// The provided key. + pub key: Key, + /// The type of the storage query. + #[serde(rename = "type")] + pub query_type: StorageQueryType, + /// The pagination key from which the iteration should resume. + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(default)] + pub pagination_start_key: Option, +} + +/// The type of the storage query. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub enum StorageQueryType { + /// Fetch the value of the provided key. + Value, + /// Fetch the hash of the value of the provided key. + Hash, + /// Fetch the closest descendant merkle value. + ClosestDescendantMerkleValue, + /// Fetch the values of all descendants of they provided key. + DescendantsValues, + /// Fetch the hashes of the values of all descendants of they provided key. + DescendantsHashes, +} + +impl StorageQueryType { + /// Returns `true` if the query is a descendant query. + pub fn is_descendant_query(&self) -> bool { + matches!(self, Self::DescendantsValues | Self::DescendantsHashes) + } +} + +/// The storage result. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct StorageResult { + /// The hex-encoded key of the result. + pub key: String, + /// The result of the query. + #[serde(flatten)] + pub result: StorageResultType, +} + +/// The type of the storage query. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub enum StorageResultType { + /// Fetch the value of the provided key. + Value(String), + /// Fetch the hash of the value of the provided key. + Hash(String), + /// Fetch the closest descendant merkle value. + ClosestDescendantMerkleValue(String), +} + +/// The error of a storage call. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct StorageResultErr { + /// The hex-encoded key of the result. + pub key: String, + /// The result of the query. + #[serde(flatten)] + pub error: StorageResultType, +} + +/// The result of a storage call. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ArchiveStorageResult { + /// Query generated a result. + Ok(ArchiveStorageMethodOk), + /// Query encountered an error. + Err(ArchiveStorageMethodErr), +} + +impl ArchiveStorageResult { + /// Create a new `ArchiveStorageResult::Ok` result. + pub fn ok(result: Vec, discarded_items: usize) -> Self { + Self::Ok(ArchiveStorageMethodOk { result, discarded_items }) + } + + /// Create a new `ArchiveStorageResult::Err` result. + pub fn err(error: String) -> Self { + Self::Err(ArchiveStorageMethodErr { error }) + } +} + +/// The result of a storage call. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ArchiveStorageMethodOk { + /// Reported results. + pub result: Vec, + /// Number of discarded items. + pub discarded_items: usize, +} + +/// The error of a storage call. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ArchiveStorageMethodErr { + /// Reported error. + pub error: String, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn storage_result() { + // Item with Value. + let item = + StorageResult { key: "0x1".into(), result: StorageResultType::Value("res".into()) }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","value":"res"}"#; + assert_eq!(ser, exp); + // Decode + let dec: StorageResult = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + + // Item with Hash. + let item = + StorageResult { key: "0x1".into(), result: StorageResultType::Hash("res".into()) }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","hash":"res"}"#; + assert_eq!(ser, exp); + // Decode + let dec: StorageResult = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + + // Item with DescendantsValues. + let item = StorageResult { + key: "0x1".into(), + result: StorageResultType::ClosestDescendantMerkleValue("res".into()), + }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","closestDescendantMerkleValue":"res"}"#; + assert_eq!(ser, exp); + // Decode + let dec: StorageResult = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + } + + #[test] + fn storage_query() { + // Item with Value. + let item = StorageQuery { key: "0x1", query_type: StorageQueryType::Value }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","type":"value"}"#; + assert_eq!(ser, exp); + // Decode + let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + + // Item with Hash. + let item = StorageQuery { key: "0x1", query_type: StorageQueryType::Hash }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","type":"hash"}"#; + assert_eq!(ser, exp); + // Decode + let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + + // Item with DescendantsValues. + let item = StorageQuery { key: "0x1", query_type: StorageQueryType::DescendantsValues }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","type":"descendantsValues"}"#; + assert_eq!(ser, exp); + // Decode + let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + + // Item with DescendantsHashes. + let item = StorageQuery { key: "0x1", query_type: StorageQueryType::DescendantsHashes }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","type":"descendantsHashes"}"#; + assert_eq!(ser, exp); + // Decode + let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + + // Item with Merkle. + let item = + StorageQuery { key: "0x1", query_type: StorageQueryType::ClosestDescendantMerkleValue }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","type":"closestDescendantMerkleValue"}"#; + assert_eq!(ser, exp); + // Decode + let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + } + + #[test] + fn storage_query_paginated() { + let item = PaginatedStorageQuery { + key: "0x1", + query_type: StorageQueryType::Value, + pagination_start_key: None, + }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","type":"value"}"#; + assert_eq!(ser, exp); + // Decode + let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); + assert_eq!(dec.key, item.key); + assert_eq!(dec.query_type, item.query_type); + let dec: PaginatedStorageQuery<&str> = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + + let item = PaginatedStorageQuery { + key: "0x1", + query_type: StorageQueryType::Value, + pagination_start_key: Some("0x2"), + }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","type":"value","paginationStartKey":"0x2"}"#; + assert_eq!(ser, exp); + // Decode + let dec: PaginatedStorageQuery<&str> = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + } +} diff --git a/substrate/client/rpc-spec-v2/src/common/mod.rs b/substrate/client/rpc-spec-v2/src/common/mod.rs new file mode 100644 index 00000000000..ac1af8fce3c --- /dev/null +++ b/substrate/client/rpc-spec-v2/src/common/mod.rs @@ -0,0 +1,17 @@ +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Common types and functionality for the RPC-V2 spec. + +pub mod events; +pub mod storage; diff --git a/substrate/client/rpc-spec-v2/src/common/storage.rs b/substrate/client/rpc-spec-v2/src/common/storage.rs new file mode 100644 index 00000000000..bd249e033f8 --- /dev/null +++ b/substrate/client/rpc-spec-v2/src/common/storage.rs @@ -0,0 +1,198 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Storage queries for the RPC-V2 spec. + +use std::{marker::PhantomData, sync::Arc}; + +use sc_client_api::{Backend, ChildInfo, StorageKey, StorageProvider}; +use sp_runtime::traits::Block as BlockT; + +use super::events::{StorageResult, StorageResultType}; +use crate::hex_string; + +/// Call into the storage of blocks. +pub struct Storage { + /// Substrate client. + client: Arc, + _phandom: PhantomData<(BE, Block)>, +} + +impl Storage { + /// Constructs a new [`Storage`]. + pub fn new(client: Arc) -> Self { + Self { client, _phandom: PhantomData } + } +} + +/// Query to iterate over storage. +pub struct QueryIter { + /// The key from which the iteration was started. + pub query_key: StorageKey, + /// The key after which pagination should resume. + pub pagination_start_key: Option, + /// The type of the query (either value or hash). + pub ty: IterQueryType, +} + +/// The query type of an iteration. +pub enum IterQueryType { + /// Iterating over (key, value) pairs. + Value, + /// Iterating over (key, hash) pairs. + Hash, +} + +/// The result of making a query call. +pub type QueryResult = Result, String>; + +/// The result of iterating over keys. +pub type QueryIterResult = Result<(Vec, Option), String>; + +impl Storage +where + Block: BlockT + 'static, + BE: Backend + 'static, + Client: StorageProvider + 'static, +{ + /// Fetch the value from storage. + pub fn query_value( + &self, + hash: Block::Hash, + key: &StorageKey, + child_key: Option<&ChildInfo>, + ) -> QueryResult { + let result = if let Some(child_key) = child_key { + self.client.child_storage(hash, child_key, key) + } else { + self.client.storage(hash, key) + }; + + result + .map(|opt| { + QueryResult::Ok(opt.map(|storage_data| StorageResult { + key: hex_string(&key.0), + result: StorageResultType::Value(hex_string(&storage_data.0)), + })) + }) + .unwrap_or_else(|error| QueryResult::Err(error.to_string())) + } + + /// Fetch the hash of a value from storage. + pub fn query_hash( + &self, + hash: Block::Hash, + key: &StorageKey, + child_key: Option<&ChildInfo>, + ) -> QueryResult { + let result = if let Some(child_key) = child_key { + self.client.child_storage_hash(hash, child_key, key) + } else { + self.client.storage_hash(hash, key) + }; + + result + .map(|opt| { + QueryResult::Ok(opt.map(|storage_data| StorageResult { + key: hex_string(&key.0), + result: StorageResultType::Hash(hex_string(&storage_data.as_ref())), + })) + }) + .unwrap_or_else(|error| QueryResult::Err(error.to_string())) + } + + /// Fetch the closest merkle value. + pub fn query_merkle_value( + &self, + hash: Block::Hash, + key: &StorageKey, + child_key: Option<&ChildInfo>, + ) -> QueryResult { + let result = if let Some(child_key) = child_key { + self.client.child_closest_merkle_value(hash, child_key, key) + } else { + self.client.closest_merkle_value(hash, key) + }; + + result + .map(|opt| { + QueryResult::Ok(opt.map(|storage_data| { + let result = match &storage_data { + sc_client_api::MerkleValue::Node(data) => hex_string(&data.as_slice()), + sc_client_api::MerkleValue::Hash(hash) => hex_string(&hash.as_ref()), + }; + + StorageResult { + key: hex_string(&key.0), + result: StorageResultType::ClosestDescendantMerkleValue(result), + } + })) + }) + .unwrap_or_else(|error| QueryResult::Err(error.to_string())) + } + + /// Iterate over at most the provided number of keys. + /// + /// Returns the storage result with a potential next key to resume iteration. + pub fn query_iter_pagination( + &self, + query: QueryIter, + hash: Block::Hash, + child_key: Option<&ChildInfo>, + count: usize, + ) -> QueryIterResult { + let QueryIter { ty, query_key, pagination_start_key } = query; + + let mut keys_iter = if let Some(child_key) = child_key { + self.client.child_storage_keys( + hash, + child_key.to_owned(), + Some(&query_key), + pagination_start_key.as_ref(), + ) + } else { + self.client.storage_keys(hash, Some(&query_key), pagination_start_key.as_ref()) + } + .map_err(|err| err.to_string())?; + + let mut ret = Vec::with_capacity(count); + let mut next_pagination_key = None; + for _ in 0..count { + let Some(key) = keys_iter.next() else { break }; + + next_pagination_key = Some(key.clone()); + + let result = match ty { + IterQueryType::Value => self.query_value(hash, &key, child_key), + IterQueryType::Hash => self.query_hash(hash, &key, child_key), + }?; + + if let Some(value) = result { + ret.push(value); + } + } + + // Save the next key if any to continue the iteration. + let maybe_next_query = keys_iter.next().map(|_| QueryIter { + ty, + query_key, + pagination_start_key: next_pagination_key, + }); + Ok((ret, maybe_next_query)) + } +} diff --git a/substrate/client/rpc-spec-v2/src/lib.rs b/substrate/client/rpc-spec-v2/src/lib.rs index d202bfef4a7..23ed422cff1 100644 --- a/substrate/client/rpc-spec-v2/src/lib.rs +++ b/substrate/client/rpc-spec-v2/src/lib.rs @@ -24,6 +24,9 @@ #![deny(unused_crate_dependencies)] use serde::{Deserialize, Serialize}; +use sp_core::hexdisplay::{AsBytesRef, HexDisplay}; + +mod common; pub mod archive; pub mod chain_head; @@ -39,7 +42,7 @@ pub type SubscriptionTaskExecutor = std::sync::Arc(data: &Data) -> String { + format!("0x{:?}", HexDisplay::from(data)) +} + #[cfg(test)] mod tests { use super::*; -- GitLab From ac303406ffc0b1478b53d236a7983c31755717bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 15:56:22 +0100 Subject: [PATCH 052/392] Bump the known_good_semver group with 1 update (#2926) Bumps the known_good_semver group with 1 update: [clap](https://github.com/clap-rs/clap). Updates `clap` from 4.4.14 to 4.4.16
Release notes

Sourced from clap's releases.

v4.4.16

[4.4.16] - 2024-01-12

Fixes

  • Ensure invalid escape sequences in user-defined strings are correctly stripped when terminal doesn't support color

v4.4.15

[4.4.15] - 2024-01-11

Fixes

  • Improve error for args_conflicts_with_subcommands
  • Ensure we error for args_conflicts_with_subcommands when using subcommand short and long flags
Changelog

Sourced from clap's changelog.

[4.4.16] - 2024-01-12

Fixes

  • Ensure invalid escape sequences in user-defined strings are correctly stripped when terminal doesn't support color

[4.4.15] - 2024-01-11

Fixes

  • Improve error for args_conflicts_with_subcommands
  • Ensure we error for args_conflicts_with_subcommands when using subcommand short and long flags
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=clap&package-manager=cargo&previous-version=4.4.14&new-version=4.4.16)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 70 +++++++++---------- cumulus/client/cli/Cargo.toml | 2 +- cumulus/parachain-template/node/Cargo.toml | 2 +- cumulus/polkadot-parachain/Cargo.toml | 2 +- cumulus/test/service/Cargo.toml | 2 +- polkadot/cli/Cargo.toml | 2 +- polkadot/node/malus/Cargo.toml | 2 +- polkadot/node/subsystem-bench/Cargo.toml | 2 +- .../test-parachains/adder/collator/Cargo.toml | 2 +- .../undying/collator/Cargo.toml | 2 +- polkadot/utils/generate-bags/Cargo.toml | 2 +- .../remote-ext-tests/bags-list/Cargo.toml | 2 +- substrate/bin/minimal/node/Cargo.toml | 2 +- substrate/bin/node-template/node/Cargo.toml | 2 +- substrate/bin/node/bench/Cargo.toml | 2 +- substrate/bin/node/cli/Cargo.toml | 4 +- substrate/bin/node/inspect/Cargo.toml | 2 +- .../bin/utils/chain-spec-builder/Cargo.toml | 2 +- substrate/bin/utils/subkey/Cargo.toml | 2 +- substrate/client/cli/Cargo.toml | 2 +- substrate/client/storage-monitor/Cargo.toml | 2 +- .../solution-type/fuzzer/Cargo.toml | 2 +- .../npos-elections/fuzzer/Cargo.toml | 2 +- .../ci/node-template-release/Cargo.toml | 2 +- .../utils/frame/benchmarking-cli/Cargo.toml | 2 +- .../frame/frame-utilities-cli/Cargo.toml | 2 +- .../generate-bags/node-runtime/Cargo.toml | 2 +- .../utils/frame/try-runtime/cli/Cargo.toml | 2 +- 28 files changed, 63 insertions(+), 63 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b20adebf963..aa773aa104a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -270,9 +270,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "4cd2405b3ac1faab2990b74d728624cd9fd115651fcecc7c2d8daf01376275ba" dependencies = [ "anstyle", "anstyle-parse", @@ -2637,9 +2637,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.14" +version = "4.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e92c5c1a78c62968ec57dbc2440366a2d6e5a23faf829970ff1585dc6b18e2" +checksum = "58e54881c004cec7895b0068a0a954cd5d62da01aef83fa35b1e594497bf5445" dependencies = [ "clap_builder", "clap_derive 4.4.7", @@ -2656,9 +2656,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.14" +version = "4.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4323769dc8a61e2c39ad7dc26f6f2800524691a44d74fe3d1071a5c24db6370" +checksum = "59cb82d7f531603d2fd1f507441cdd35184fa81beff7bd489570de7f773460bb" dependencies = [ "anstream", "anstyle", @@ -2673,7 +2673,7 @@ version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "586a385f7ef2f8b4d86bddaa0c094794e7ccbfe5ffef1f434fe928143fc783a5" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", ] [[package]] @@ -3411,7 +3411,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.4.14", + "clap 4.4.16", "criterion-plot", "futures", "is-terminal", @@ -3574,7 +3574,7 @@ dependencies = [ name = "cumulus-client-cli" version = "0.1.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "parity-scale-codec", "sc-chain-spec", "sc-cli", @@ -4313,7 +4313,7 @@ name = "cumulus-test-service" version = "0.1.0" dependencies = [ "async-trait", - "clap 4.4.14", + "clap 4.4.16", "criterion 0.5.1", "cumulus-client-cli", "cumulus-client-consensus-common", @@ -5497,7 +5497,7 @@ dependencies = [ "Inflector", "array-bytes 6.1.0", "chrono", - "clap 4.4.14", + "clap 4.4.16", "comfy-table", "frame-benchmarking", "frame-support", @@ -5589,7 +5589,7 @@ dependencies = [ name = "frame-election-solution-type-fuzzer" version = "2.0.0-alpha.5" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "frame-election-provider-solution-type", "frame-election-provider-support", "frame-support", @@ -8105,7 +8105,7 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" name = "minimal-node" version = "4.0.0-dev" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "frame", "futures", "futures-timer", @@ -8569,7 +8569,7 @@ name = "node-bench" version = "0.9.0-dev" dependencies = [ "array-bytes 6.1.0", - "clap 4.4.14", + "clap 4.4.16", "derive_more", "fs_extra", "futures", @@ -8646,7 +8646,7 @@ dependencies = [ name = "node-runtime-generate-bags" version = "3.0.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "generate-bags", "kitchensink-runtime", ] @@ -8655,7 +8655,7 @@ dependencies = [ name = "node-template" version = "4.0.0-dev" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "frame-benchmarking", "frame-benchmarking-cli", "frame-system", @@ -8699,7 +8699,7 @@ dependencies = [ name = "node-template-release" version = "3.0.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "flate2", "fs_extra", "glob", @@ -11243,7 +11243,7 @@ dependencies = [ name = "parachain-template-node" version = "0.1.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "color-print", "cumulus-client-cli", "cumulus-client-collator", @@ -12201,7 +12201,7 @@ name = "polkadot-cli" version = "1.1.0" dependencies = [ "cfg-if", - "clap 4.4.14", + "clap 4.4.16", "frame-benchmarking-cli", "futures", "log", @@ -13042,7 +13042,7 @@ dependencies = [ "async-trait", "bridge-hub-rococo-runtime", "bridge-hub-westend-runtime", - "clap 4.4.14", + "clap 4.4.16", "collectives-westend-runtime", "color-print", "contracts-rococo-runtime", @@ -13553,7 +13553,7 @@ version = "1.0.0" dependencies = [ "assert_matches", "async-trait", - "clap 4.4.14", + "clap 4.4.16", "clap-num", "color-eyre", "colored", @@ -13630,7 +13630,7 @@ version = "1.0.0" dependencies = [ "assert_matches", "async-trait", - "clap 4.4.14", + "clap 4.4.16", "color-eyre", "futures", "futures-timer", @@ -13777,7 +13777,7 @@ dependencies = [ name = "polkadot-voter-bags" version = "1.0.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "generate-bags", "sp-io", "westend-runtime", @@ -14647,7 +14647,7 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" name = "remote-ext-tests-bags-list" version = "1.0.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "frame-system", "log", "pallet-bags-list-remote-tests", @@ -15437,7 +15437,7 @@ dependencies = [ "array-bytes 6.1.0", "bip39", "chrono", - "clap 4.4.14", + "clap 4.4.16", "fdlimit", "futures", "futures-timer", @@ -16581,7 +16581,7 @@ dependencies = [ name = "sc-storage-monitor" version = "0.1.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "fs4", "log", "sp-core", @@ -18531,7 +18531,7 @@ dependencies = [ name = "sp-npos-elections-fuzzer" version = "2.0.0-alpha.5" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "honggfuzz", "rand 0.8.5", "sp-npos-elections", @@ -19052,7 +19052,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" name = "staging-chain-spec-builder" version = "2.0.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "log", "sc-chain-spec", "serde_json", @@ -19065,7 +19065,7 @@ version = "3.0.0-dev" dependencies = [ "array-bytes 6.1.0", "assert_cmd", - "clap 4.4.14", + "clap 4.4.16", "clap_complete", "criterion 0.4.0", "frame-benchmarking", @@ -19174,7 +19174,7 @@ dependencies = [ name = "staging-node-inspect" version = "0.9.0-dev" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "parity-scale-codec", "sc-cli", "sc-client-api", @@ -19379,7 +19379,7 @@ dependencies = [ name = "subkey" version = "3.0.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "sc-cli", ] @@ -19421,7 +19421,7 @@ dependencies = [ name = "substrate-frame-cli" version = "4.0.0-dev" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "frame-support", "frame-system", "sc-cli", @@ -19899,7 +19899,7 @@ dependencies = [ name = "test-parachain-adder-collator" version = "1.0.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "futures", "futures-timer", "log", @@ -19947,7 +19947,7 @@ dependencies = [ name = "test-parachain-undying-collator" version = "1.0.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "futures", "futures-timer", "log", @@ -20598,7 +20598,7 @@ version = "0.10.0-dev" dependencies = [ "assert_cmd", "async-trait", - "clap 4.4.14", + "clap 4.4.16", "frame-remote-externalities", "frame-try-runtime", "hex", diff --git a/cumulus/client/cli/Cargo.toml b/cumulus/client/cli/Cargo.toml index 736cb02b94b..4048c3eaecb 100644 --- a/cumulus/client/cli/Cargo.toml +++ b/cumulus/client/cli/Cargo.toml @@ -10,7 +10,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0" workspace = true [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0" } url = "2.4.0" diff --git a/cumulus/parachain-template/node/Cargo.toml b/cumulus/parachain-template/node/Cargo.toml index 7edb4b454c0..b34478ab3dd 100644 --- a/cumulus/parachain-template/node/Cargo.toml +++ b/cumulus/parachain-template/node/Cargo.toml @@ -14,7 +14,7 @@ publish = false workspace = true [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } log = "0.4.20" codec = { package = "parity-scale-codec", version = "3.0.0" } serde = { version = "1.0.195", features = ["derive"] } diff --git a/cumulus/polkadot-parachain/Cargo.toml b/cumulus/polkadot-parachain/Cargo.toml index 50fc48b3f2f..9f42a265f39 100644 --- a/cumulus/polkadot-parachain/Cargo.toml +++ b/cumulus/polkadot-parachain/Cargo.toml @@ -16,7 +16,7 @@ path = "src/main.rs" [dependencies] async-trait = "0.1.74" -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0" } futures = "0.3.28" hex-literal = "0.4.1" diff --git a/cumulus/test/service/Cargo.toml b/cumulus/test/service/Cargo.toml index f4dde7d2945..387d65c4931 100644 --- a/cumulus/test/service/Cargo.toml +++ b/cumulus/test/service/Cargo.toml @@ -14,7 +14,7 @@ path = "src/main.rs" [dependencies] async-trait = "0.1.74" -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0" } criterion = { version = "0.5.1", features = ["async_tokio"] } jsonrpsee = { version = "0.16.2", features = ["server"] } diff --git a/polkadot/cli/Cargo.toml b/polkadot/cli/Cargo.toml index 1b331c5ed42..cc96422abbc 100644 --- a/polkadot/cli/Cargo.toml +++ b/polkadot/cli/Cargo.toml @@ -19,7 +19,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] cfg-if = "1.0" -clap = { version = "4.4.14", features = ["derive"], optional = true } +clap = { version = "4.4.16", features = ["derive"], optional = true } log = "0.4.17" thiserror = "1.0.48" futures = "0.3.21" diff --git a/polkadot/node/malus/Cargo.toml b/polkadot/node/malus/Cargo.toml index 56d377648bb..7793abfd69b 100644 --- a/polkadot/node/malus/Cargo.toml +++ b/polkadot/node/malus/Cargo.toml @@ -43,7 +43,7 @@ assert_matches = "1.5" async-trait = "0.1.74" sp-keystore = { path = "../../../substrate/primitives/keystore" } sp-core = { path = "../../../substrate/primitives/core" } -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" gum = { package = "tracing-gum", path = "../gum" } diff --git a/polkadot/node/subsystem-bench/Cargo.toml b/polkadot/node/subsystem-bench/Cargo.toml index dc1179b7762..ab3de33fe2c 100644 --- a/polkadot/node/subsystem-bench/Cargo.toml +++ b/polkadot/node/subsystem-bench/Cargo.toml @@ -31,7 +31,7 @@ async-trait = "0.1.74" sp-keystore = { path = "../../../substrate/primitives/keystore" } sc-keystore = { path = "../../../substrate/client/keystore" } sp-core = { path = "../../../substrate/primitives/core" } -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" gum = { package = "tracing-gum", path = "../gum" } diff --git a/polkadot/parachain/test-parachains/adder/collator/Cargo.toml b/polkadot/parachain/test-parachains/adder/collator/Cargo.toml index c2cea979b97..4ebeb767905 100644 --- a/polkadot/parachain/test-parachains/adder/collator/Cargo.toml +++ b/polkadot/parachain/test-parachains/adder/collator/Cargo.toml @@ -16,7 +16,7 @@ path = "src/main.rs" [dependencies] parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" log = "0.4.17" diff --git a/polkadot/parachain/test-parachains/undying/collator/Cargo.toml b/polkadot/parachain/test-parachains/undying/collator/Cargo.toml index 4d7c7391d82..1d851218bed 100644 --- a/polkadot/parachain/test-parachains/undying/collator/Cargo.toml +++ b/polkadot/parachain/test-parachains/undying/collator/Cargo.toml @@ -16,7 +16,7 @@ path = "src/main.rs" [dependencies] parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" log = "0.4.17" diff --git a/polkadot/utils/generate-bags/Cargo.toml b/polkadot/utils/generate-bags/Cargo.toml index 5435baa6151..a16ee8de496 100644 --- a/polkadot/utils/generate-bags/Cargo.toml +++ b/polkadot/utils/generate-bags/Cargo.toml @@ -10,7 +10,7 @@ description = "CLI to generate voter bags for Polkadot runtimes" workspace = true [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } generate-bags = { path = "../../../substrate/utils/frame/generate-bags" } sp-io = { path = "../../../substrate/primitives/io" } diff --git a/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml b/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml index aeb62e87941..75bfdd9d1a0 100644 --- a/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml +++ b/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml @@ -18,6 +18,6 @@ sp-tracing = { path = "../../../../substrate/primitives/tracing" } frame-system = { path = "../../../../substrate/frame/system" } sp-core = { path = "../../../../substrate/primitives/core" } -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } log = "0.4.17" tokio = { version = "1.24.2", features = ["macros"] } diff --git a/substrate/bin/minimal/node/Cargo.toml b/substrate/bin/minimal/node/Cargo.toml index 07138eb0c55..5a2427fd4d8 100644 --- a/substrate/bin/minimal/node/Cargo.toml +++ b/substrate/bin/minimal/node/Cargo.toml @@ -20,7 +20,7 @@ targets = ["x86_64-unknown-linux-gnu"] name = "minimal-node" [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } futures = { version = "0.3.21", features = ["thread-pool"] } futures-timer = "3.0.1" jsonrpsee = { version = "0.16.2", features = ["server"] } diff --git a/substrate/bin/node-template/node/Cargo.toml b/substrate/bin/node-template/node/Cargo.toml index aac24a83096..f91db97985b 100644 --- a/substrate/bin/node-template/node/Cargo.toml +++ b/substrate/bin/node-template/node/Cargo.toml @@ -20,7 +20,7 @@ targets = ["x86_64-unknown-linux-gnu"] name = "node-template" [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } futures = { version = "0.3.21", features = ["thread-pool"] } serde_json = "1.0.111" diff --git a/substrate/bin/node/bench/Cargo.toml b/substrate/bin/node/bench/Cargo.toml index e2b68b2a0e8..926cdc3bfb0 100644 --- a/substrate/bin/node/bench/Cargo.toml +++ b/substrate/bin/node/bench/Cargo.toml @@ -16,7 +16,7 @@ workspace = true [dependencies] array-bytes = "6.1" -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } log = "0.4.17" node-primitives = { path = "../primitives" } node-testing = { path = "../testing" } diff --git a/substrate/bin/node/cli/Cargo.toml b/substrate/bin/node/cli/Cargo.toml index 4bf5efd7cd1..64b61288391 100644 --- a/substrate/bin/node/cli/Cargo.toml +++ b/substrate/bin/node/cli/Cargo.toml @@ -41,7 +41,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] # third-party dependencies array-bytes = "6.1" -clap = { version = "4.4.14", features = ["derive"], optional = true } +clap = { version = "4.4.16", features = ["derive"], optional = true } codec = { package = "parity-scale-codec", version = "3.6.1" } serde = { version = "1.0.195", features = ["derive"] } jsonrpsee = { version = "0.16.2", features = ["server"] } @@ -164,7 +164,7 @@ sp-trie = { path = "../../../primitives/trie" } sp-state-machine = { path = "../../../primitives/state-machine" } [build-dependencies] -clap = { version = "4.4.14", optional = true } +clap = { version = "4.4.16", optional = true } clap_complete = { version = "4.0.2", optional = true } node-inspect = { package = "staging-node-inspect", path = "../inspect", optional = true } frame-benchmarking-cli = { path = "../../../utils/frame/benchmarking-cli", optional = true } diff --git a/substrate/bin/node/inspect/Cargo.toml b/substrate/bin/node/inspect/Cargo.toml index 29c0917440e..ef82f16be2a 100644 --- a/substrate/bin/node/inspect/Cargo.toml +++ b/substrate/bin/node/inspect/Cargo.toml @@ -15,7 +15,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.6.1" } thiserror = "1.0" sc-cli = { path = "../../../client/cli" } diff --git a/substrate/bin/utils/chain-spec-builder/Cargo.toml b/substrate/bin/utils/chain-spec-builder/Cargo.toml index e9dc4d83b6b..a9ea0ad40b3 100644 --- a/substrate/bin/utils/chain-spec-builder/Cargo.toml +++ b/substrate/bin/utils/chain-spec-builder/Cargo.toml @@ -23,7 +23,7 @@ name = "chain-spec-builder" crate-type = ["rlib"] [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } log = "0.4.17" sc-chain-spec = { path = "../../../client/chain-spec" } serde_json = "1.0.111" diff --git a/substrate/bin/utils/subkey/Cargo.toml b/substrate/bin/utils/subkey/Cargo.toml index 822068f6614..19eba2f1969 100644 --- a/substrate/bin/utils/subkey/Cargo.toml +++ b/substrate/bin/utils/subkey/Cargo.toml @@ -20,5 +20,5 @@ path = "src/main.rs" name = "subkey" [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } sc-cli = { path = "../../../client/cli" } diff --git a/substrate/client/cli/Cargo.toml b/substrate/client/cli/Cargo.toml index caaa96b904c..ce9b1781686 100644 --- a/substrate/client/cli/Cargo.toml +++ b/substrate/client/cli/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] array-bytes = "6.1" chrono = "0.4.31" -clap = { version = "4.4.14", features = ["derive", "string", "wrap_help"] } +clap = { version = "4.4.16", features = ["derive", "string", "wrap_help"] } fdlimit = "0.3.0" futures = "0.3.21" itertools = "0.10.3" diff --git a/substrate/client/storage-monitor/Cargo.toml b/substrate/client/storage-monitor/Cargo.toml index 7185c62e276..17f1c42bccb 100644 --- a/substrate/client/storage-monitor/Cargo.toml +++ b/substrate/client/storage-monitor/Cargo.toml @@ -12,7 +12,7 @@ homepage = "https://substrate.io" workspace = true [dependencies] -clap = { version = "4.4.14", features = ["derive", "string"] } +clap = { version = "4.4.16", features = ["derive", "string"] } log = "0.4.17" fs4 = "0.7.0" sp-core = { path = "../../primitives/core" } diff --git a/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml b/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml index d64498de087..62316b27290 100644 --- a/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml +++ b/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml @@ -16,7 +16,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } honggfuzz = "0.5" rand = { version = "0.8", features = ["small_rng", "std"] } diff --git a/substrate/primitives/npos-elections/fuzzer/Cargo.toml b/substrate/primitives/npos-elections/fuzzer/Cargo.toml index e7cfb75e54b..f98e41ae77a 100644 --- a/substrate/primitives/npos-elections/fuzzer/Cargo.toml +++ b/substrate/primitives/npos-elections/fuzzer/Cargo.toml @@ -17,7 +17,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } honggfuzz = "0.5" rand = { version = "0.8", features = ["small_rng", "std"] } sp-npos-elections = { path = ".." } diff --git a/substrate/scripts/ci/node-template-release/Cargo.toml b/substrate/scripts/ci/node-template-release/Cargo.toml index b02f941811c..40ba629fb05 100644 --- a/substrate/scripts/ci/node-template-release/Cargo.toml +++ b/substrate/scripts/ci/node-template-release/Cargo.toml @@ -14,7 +14,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } flate2 = "1.0" fs_extra = "1.3" glob = "0.3" diff --git a/substrate/utils/frame/benchmarking-cli/Cargo.toml b/substrate/utils/frame/benchmarking-cli/Cargo.toml index 21c5701b518..f7210cf768f 100644 --- a/substrate/utils/frame/benchmarking-cli/Cargo.toml +++ b/substrate/utils/frame/benchmarking-cli/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] array-bytes = "6.1" chrono = "0.4" -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.6.1" } comfy-table = { version = "7.0.1", default-features = false } handlebars = "4.2.2" diff --git a/substrate/utils/frame/frame-utilities-cli/Cargo.toml b/substrate/utils/frame/frame-utilities-cli/Cargo.toml index 886e17280b1..899f86f3cb4 100644 --- a/substrate/utils/frame/frame-utilities-cli/Cargo.toml +++ b/substrate/utils/frame/frame-utilities-cli/Cargo.toml @@ -14,7 +14,7 @@ readme = "README.md" workspace = true [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } frame-support = { path = "../../../frame/support" } frame-system = { path = "../../../frame/system" } sc-cli = { path = "../../../client/cli" } diff --git a/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml b/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml index d2aaaff9a69..ba11fce18f8 100644 --- a/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml +++ b/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml @@ -17,4 +17,4 @@ kitchensink-runtime = { path = "../../../../bin/node/runtime" } generate-bags = { path = ".." } # third-party -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } diff --git a/substrate/utils/frame/try-runtime/cli/Cargo.toml b/substrate/utils/frame/try-runtime/cli/Cargo.toml index b5bce36e3b7..ac515315bbe 100644 --- a/substrate/utils/frame/try-runtime/cli/Cargo.toml +++ b/substrate/utils/frame/try-runtime/cli/Cargo.toml @@ -38,7 +38,7 @@ frame-try-runtime = { path = "../../../../frame/try-runtime", optional = true } substrate-rpc-client = { path = "../../rpc/client" } async-trait = "0.1.74" -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } hex = { version = "0.4.3", default-features = false } log = "0.4.17" parity-scale-codec = "3.6.1" -- GitLab From 36a83186376707e551e43966265fbcc3f1c4afcc Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Mon, 15 Jan 2024 15:53:35 +0100 Subject: [PATCH 053/392] Add missing crates to the workspace (#2932) Changes: - add missing member to the workspace - add CI script after the last attempt to merge it upstream failed https://github.com/paritytech/pipeline-scripts/pull/105 Two crates are excluded from the check since they are templates `substrate/frame/contracts/fixtures/build` and `substrate/frame/contracts/fixtures/contracts/common`. Hopefully this is the last time that some crates need to be added manually. ![meme](https://github.com/paritytech/polkadot-sdk/assets/10380170/984843ee-1c76-4126-a4fc-ff2ba1d47377) --------- Signed-off-by: Oliver Tale-Yazdi --- .github/scripts/check-workspace.py | 162 ++++++++++++++++++++++++++ .github/workflows/check-workspace.yml | 23 ++++ Cargo.toml | 1 + 3 files changed, 186 insertions(+) create mode 100644 .github/scripts/check-workspace.py create mode 100644 .github/workflows/check-workspace.yml diff --git a/.github/scripts/check-workspace.py b/.github/scripts/check-workspace.py new file mode 100644 index 00000000000..fb3b53acb0c --- /dev/null +++ b/.github/scripts/check-workspace.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 + +# Ensures that: +# - all crates are added to the root workspace +# - local dependencies are resolved via `path` +# +# It does not check that the local paths resolve to the correct crate. This is already done by cargo. +# +# Must be called with a folder containing a `Cargo.toml` workspace file. + +import os +import sys +import toml +import argparse + +def parse_args(): + parser = argparse.ArgumentParser(description='Check Rust workspace integrity.') + + parser.add_argument('workspace_dir', help='The directory to check', metavar='workspace_dir', type=str, nargs=1) + parser.add_argument('--exclude', help='Exclude crate paths from the check', metavar='exclude', type=str, nargs='*', default=[]) + + args = parser.parse_args() + return (args.workspace_dir[0], args.exclude) + +def main(root, exclude): + workspace_crates = get_members(root, exclude) + all_crates = get_crates(root, exclude) + print(f'📦 Found {len(all_crates)} crates in total') + + check_missing(workspace_crates, all_crates) + check_links(all_crates) + +# Extract all members from a workspace. +# Return: list of all workspace paths +def get_members(workspace_dir, exclude): + print(f'🔎 Indexing workspace {os.path.abspath(workspace_dir)}') + + root_manifest_path = os.path.join(workspace_dir, "Cargo.toml") + if not os.path.exists(root_manifest_path): + print(f'❌ No root manifest found at {root_manifest}') + sys.exit(1) + + root_manifest = toml.load(root_manifest_path) + if not 'workspace' in root_manifest: + print(f'❌ No workspace found in root {root_manifest_path}') + sys.exit(1) + + if not 'members' in root_manifest['workspace']: + return [] + + members = [] + for member in root_manifest['workspace']['members']: + if member in exclude: + print(f'❌ Excluded member should not appear in the workspace {member}') + sys.exit(1) + members.append(member) + + return members + +# List all members of the workspace. +# Return: Map name -> (path, manifest) +def get_crates(workspace_dir, exclude_crates) -> dict: + crates = {} + + for root, dirs, files in os.walk(workspace_dir): + if "target" in root: + continue + for file in files: + if file != "Cargo.toml": + continue + + path = os.path.join(root, file) + with open(path, "r") as f: + content = f.read() + manifest = toml.loads(content) + + if 'workspace' in manifest: + if root != workspace_dir: + print("⏩ Excluded recursive workspace at %s" % path) + continue + + # Cut off the root path and the trailing /Cargo.toml. + path = path[len(workspace_dir)+1:-11] + name = manifest['package']['name'] + if path in exclude_crates: + print("⏩ Excluded crate %s at %s" % (name, path)) + continue + crates[name] = (path, manifest) + + return crates + +# Check that all crates are in the workspace. +def check_missing(workspace_crates, all_crates): + print(f'🔎 Checking for missing crates') + if len(workspace_crates) == len(all_crates): + print(f'✅ All {len(all_crates)} crates are in the workspace') + return + + missing = [] + # Find out which ones are missing. + for name, (path, manifest) in all_crates.items(): + if not path in workspace_crates: + missing.append([name, path, manifest]) + missing.sort() + + for name, path, _manifest in missing: + print("❌ %s in %s" % (name, path)) + print(f'😱 {len(all_crates) - len(workspace_crates)} crates are missing from the workspace') + sys.exit(1) + +# Check that all local dependencies are good. +def check_links(all_crates): + print(f'🔎 Checking for broken dependency links') + links = [] + broken = [] + + for name, (path, manifest) in all_crates.items(): + def check_deps(deps): + for dep in deps: + # Could be renamed: + dep_name = dep + if 'package' in deps[dep]: + dep_name = deps[dep]['package'] + if dep_name in all_crates: + links.append((name, dep_name)) + + if not 'path' in deps[dep]: + broken.append((name, dep_name, "crate must be linked via `path`")) + return + + def check_crate(deps): + to_checks = ['dependencies', 'dev-dependencies', 'build-dependencies'] + + for to_check in to_checks: + if to_check in deps: + check_deps(deps[to_check]) + + # There could possibly target dependant deps: + if 'target' in manifest: + # Target dependant deps can only have one level of nesting: + for _, target in manifest['target'].items(): + check_crate(target) + + check_crate(manifest) + + + + links.sort() + broken.sort() + + if len(broken) > 0: + for (l, r, reason) in broken: + print(f'❌ {l} -> {r} ({reason})') + + print("💥 %d out of %d links are broken" % (len(broken), len(links))) + sys.exit(1) + else: + print("✅ All %d internal dependency links are correct" % len(links)) + +if __name__ == "__main__": + args = parse_args() + main(args[0], args[1]) diff --git a/.github/workflows/check-workspace.yml b/.github/workflows/check-workspace.yml new file mode 100644 index 00000000000..3dd812d7d9b --- /dev/null +++ b/.github/workflows/check-workspace.yml @@ -0,0 +1,23 @@ +name: Check workspace + +on: + pull_request: + paths: + - "*.toml" + merge_group: + +jobs: + check-workspace: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.0 (22. Sep 2023) + + - name: install python deps + run: pip3 install toml + + - name: check integrity + run: > + python3 .github/scripts/check-workspace.py . + --exclude + "substrate/frame/contracts/fixtures/build" + "substrate/frame/contracts/fixtures/contracts/common" diff --git a/Cargo.toml b/Cargo.toml index 38cae6f640c..3afccc24992 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -105,6 +105,7 @@ members = [ "cumulus/parachains/runtimes/assets/test-utils", "cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo", "cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend", + "cumulus/parachains/runtimes/bridge-hubs/common", "cumulus/parachains/runtimes/bridge-hubs/test-utils", "cumulus/parachains/runtimes/collectives/collectives-westend", "cumulus/parachains/runtimes/contracts/contracts-rococo", -- GitLab From f2fbba3be1d7deaf7cfc731cea00552c212ddfcf Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Mon, 15 Jan 2024 17:21:31 +0100 Subject: [PATCH 054/392] Contracts: stabilize sr25519 (#2920) Integration tests in ink!: https://github.com/paritytech/ink/tree/master/integration-tests/sr25519-verification --- prdoc/pr_2920.prdoc | 11 +++++++++++ substrate/frame/contracts/src/wasm/runtime.rs | 1 - 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 prdoc/pr_2920.prdoc diff --git a/prdoc/pr_2920.prdoc b/prdoc/pr_2920.prdoc new file mode 100644 index 00000000000..7745838ab5c --- /dev/null +++ b/prdoc/pr_2920.prdoc @@ -0,0 +1,11 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Contracts: Stabilize sr25519_verify host function + +doc: + - audience: Runtime Dev + description: | + Removed the `#[unstable]` attrribute on `sr25519_verify` host function. + +crates: ["pallet-contracts"] diff --git a/substrate/frame/contracts/src/wasm/runtime.rs b/substrate/frame/contracts/src/wasm/runtime.rs index 7b1e35ee1ad..a7f329005f9 100644 --- a/substrate/frame/contracts/src/wasm/runtime.rs +++ b/substrate/frame/contracts/src/wasm/runtime.rs @@ -2229,7 +2229,6 @@ pub mod env { /// Verify a sr25519 signature /// See [`pallet_contracts_uapi::HostFn::sr25519_verify`]. - #[unstable] fn sr25519_verify( ctx: _, memory: _, -- GitLab From 0c166ae0194b7337f1c151434483b78b31235549 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 22:07:09 +0100 Subject: [PATCH 055/392] Bump lycheeverse/lychee-action (#2900) Bumps [lycheeverse/lychee-action](https://github.com/lycheeverse/lychee-action) from fdea7032675810093199f485fe075f057cc37b3e to c3089c702fbb949e3f7a8122be0c33c017904f9b.
Commits

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--------- Signed-off-by: dependabot[bot] Signed-off-by: Oliver Tale-Yazdi Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sergejs Kostjucenko <85877331+sergejparity@users.noreply.github.com> Co-authored-by: Oliver Tale-Yazdi --- .config/lychee.toml | 4 ++++ .github/workflows/check-links.yml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.config/lychee.toml b/.config/lychee.toml index 70869465d67..200521ac41e 100644 --- a/.config/lychee.toml +++ b/.config/lychee.toml @@ -47,4 +47,8 @@ exclude = [ "https://w3f.github.io/parachain-implementers-guide/node/index.html", "https://w3f.github.io/parachain-implementers-guide/protocol-chain-selection.html", "https://w3f.github.io/parachain-implementers-guide/runtime/session_info.html", + + # Behind a captcha (code 403): + "https://iohk.io/en/blog/posts/2023/11/03/partner-chains-are-coming-to-cardano/", + "https://www.reddit.com/r/rust/comments/3spfh1/does_collect_allocate_more_than_once_while/", ] diff --git a/.github/workflows/check-links.yml b/.github/workflows/check-links.yml index d3865335c09..903d7a3fcb3 100644 --- a/.github/workflows/check-links.yml +++ b/.github/workflows/check-links.yml @@ -28,7 +28,7 @@ jobs: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.0 (22. Sep 2023) - name: Lychee link checker - uses: lycheeverse/lychee-action@fdea7032675810093199f485fe075f057cc37b3e # for v1.9.0 (5. Jan 2024) + uses: lycheeverse/lychee-action@c3089c702fbb949e3f7a8122be0c33c017904f9b # for v1.9.1 (10. Jan 2024) with: args: >- --config .config/lychee.toml -- GitLab From 1c2db1747e72a0d953a69e88569fa822eb94622a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 16 Jan 2024 01:19:17 +0100 Subject: [PATCH 056/392] Some random fixes (#2936) - Do not disable `std` feature in the integration tests - `contracts-fixtures` test should only check for `riscv` build when the feature is enabled --- .../emulated/common/Cargo.toml | 28 +++++++++---------- substrate/frame/contracts/fixtures/src/lib.rs | 1 + 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/cumulus/parachains/integration-tests/emulated/common/Cargo.toml b/cumulus/parachains/integration-tests/emulated/common/Cargo.toml index 8277b3d734f..2ee91e83585 100644 --- a/cumulus/parachains/integration-tests/emulated/common/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/common/Cargo.toml @@ -16,29 +16,29 @@ serde_json = "1.0.111" # Substrate grandpa = { package = "sc-consensus-grandpa", path = "../../../../../substrate/client/consensus/grandpa" } -sp-authority-discovery = { path = "../../../../../substrate/primitives/authority-discovery", default-features = false } -sp-runtime = { path = "../../../../../substrate/primitives/runtime", default-features = false } -frame-support = { path = "../../../../../substrate/frame/support", default-features = false } -sp-core = { path = "../../../../../substrate/primitives/core", default-features = false } -sp-consensus-babe = { path = "../../../../../substrate/primitives/consensus/babe", default-features = false } -pallet-assets = { path = "../../../../../substrate/frame/assets", default-features = false } -pallet-balances = { path = "../../../../../substrate/frame/balances", default-features = false } -pallet-message-queue = { path = "../../../../../substrate/frame/message-queue", default-features = false } -pallet-im-online = { path = "../../../../../substrate/frame/im-online", default-features = false } +sp-authority-discovery = { path = "../../../../../substrate/primitives/authority-discovery" } +sp-runtime = { path = "../../../../../substrate/primitives/runtime" } +frame-support = { path = "../../../../../substrate/frame/support" } +sp-core = { path = "../../../../../substrate/primitives/core" } +sp-consensus-babe = { path = "../../../../../substrate/primitives/consensus/babe" } +pallet-assets = { path = "../../../../../substrate/frame/assets" } +pallet-balances = { path = "../../../../../substrate/frame/balances" } +pallet-message-queue = { path = "../../../../../substrate/frame/message-queue" } +pallet-im-online = { path = "../../../../../substrate/frame/im-online" } beefy-primitives = { package = "sp-consensus-beefy", path = "../../../../../substrate/primitives/consensus/beefy" } # Polkadot polkadot-service = { path = "../../../../../polkadot/node/service", default-features = false, features = ["full-node"] } -polkadot-primitives = { path = "../../../../../polkadot/primitives", default-features = false } +polkadot-primitives = { path = "../../../../../polkadot/primitives" } polkadot-runtime-parachains = { path = "../../../../../polkadot/runtime/parachains" } -xcm = { package = "staging-xcm", path = "../../../../../polkadot/xcm", default-features = false } -pallet-xcm = { path = "../../../../../polkadot/xcm/pallet-xcm", default-features = false } +xcm = { package = "staging-xcm", path = "../../../../../polkadot/xcm" } +pallet-xcm = { path = "../../../../../polkadot/xcm/pallet-xcm" } # Cumulus parachains-common = { path = "../../../common" } cumulus-primitives-core = { path = "../../../../primitives/core" } -xcm-emulator = { path = "../../../../xcm/xcm-emulator", default-features = false } -cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue", default-features = false } +xcm-emulator = { path = "../../../../xcm/xcm-emulator" } +cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue" } cumulus-pallet-parachain-system = { path = "../../../../pallets/parachain-system" } asset-test-utils = { path = "../../../runtimes/assets/test-utils" } diff --git a/substrate/frame/contracts/fixtures/src/lib.rs b/substrate/frame/contracts/fixtures/src/lib.rs index 4d850d75624..e0d9d4f8bd5 100644 --- a/substrate/frame/contracts/fixtures/src/lib.rs +++ b/substrate/frame/contracts/fixtures/src/lib.rs @@ -70,6 +70,7 @@ mod test { fn out_dir_should_have_compiled_mocks() { let out_dir: std::path::PathBuf = env!("OUT_DIR").into(); assert!(out_dir.join("dummy.wasm").exists()); + #[cfg(feature = "riscv")] assert!(out_dir.join("dummy.polkavm").exists()); } } -- GitLab From 4c4963a1929b59cce2c81d755b440403019e836d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 01:19:37 +0100 Subject: [PATCH 057/392] Bump Swatinem/rust-cache from 2.7.2 to 2.7.3 (#2925) Bumps [Swatinem/rust-cache](https://github.com/swatinem/rust-cache) from 2.7.2 to 2.7.3.
Release notes

Sourced from Swatinem/rust-cache's releases.

v2.7.3

  • Work around upstream problem that causes cache saving to hang for minutes.

Full Changelog: https://github.com/Swatinem/rust-cache/compare/v2.7.2...v2.7.3

Changelog

Sourced from Swatinem/rust-cache's changelog.

Changelog

2.7.3

  • Work around upstream problem that causes cache saving to hang for minutes.

2.7.2

  • Only key by Cargo.toml and Cargo.lock files of workspace members.

2.7.1

  • Update toml parser to fix parsing errors.

2.7.0

  • Properly cache trybuild tests.

2.6.2

  • Fix toml parsing.

2.6.1

  • Fix hash contributions of Cargo.lock/Cargo.toml files.

2.6.0

  • Add "buildjet" as a second cache-provider backend.
  • Clean up sparse registry index.
  • Do not clean up src of -sys crates.
  • Remove .cargo/credentials.toml before saving.

2.5.1

  • Fix hash contribution of Cargo.lock.

2.5.0

  • feat: Rm workspace crates version before caching.
  • feat: Add hash of .cargo/config.toml to key.

2.4.0

  • Fix cache key stability.
  • Use 8 character hash components to reduce the key length, making it more readable.

2.3.0

  • Add cache-all-crates option, which enables caching of crates installed by workflows.

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=Swatinem/rust-cache&package-manager=github_actions&previous-version=2.7.2&new-version=2.7.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/check-publish.yml | 2 +- .github/workflows/claim-crates.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check-publish.yml b/.github/workflows/check-publish.yml index 398cb732585..b16b3d4e5c5 100644 --- a/.github/workflows/check-publish.yml +++ b/.github/workflows/check-publish.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Rust Cache - uses: Swatinem/rust-cache@a22603398250b864f7190077025cf752307154dc # v2.7.2 + uses: Swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2.7.3 with: cache-on-failure: true diff --git a/.github/workflows/claim-crates.yml b/.github/workflows/claim-crates.yml index 038ea213123..f3df0bce72d 100644 --- a/.github/workflows/claim-crates.yml +++ b/.github/workflows/claim-crates.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Rust Cache - uses: Swatinem/rust-cache@a22603398250b864f7190077025cf752307154dc # v2.7.2 + uses: Swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2.7.3 with: cache-on-failure: true -- GitLab From 2cb39f8dc90f3431bd011084862ffa14e618b987 Mon Sep 17 00:00:00 2001 From: Muharem Date: Tue, 16 Jan 2024 15:34:48 +0800 Subject: [PATCH 058/392] XCM WeightTrader: Swap Fee Asset for Native Asset (#1845) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements an XCM executor `WeightTrader`, facilitating fee payments in any asset that can be exchanged for a native asset. A few constraints need to be observed: - `buy_weight` and `refund` operations must be atomic, as another weight trader implementation might be attempted in case of failure. - swap credit must be utilized since there isn’t an account to which an asset of some class can be deposited with a guarantee to meet the existential deposit requirement. Also, operating with credits enhances the efficiency of the weight trader - https://github.com/paritytech/polkadot-sdk/pull/1677 related PRs: - (depends) https://github.com/paritytech/polkadot-sdk/pull/2031 - (depends) https://github.com/paritytech/polkadot-sdk/pull/1677 - (caused) https://github.com/paritytech/polkadot-sdk/pull/1847 - (caused) https://github.com/paritytech/polkadot-sdk/pull/1876 // DONE: impl `OnUnbalanced` for a `fungible/s` credit // DONE: make the trader free from a concept of a native currency and drop few fallible conversions. related issue - https://github.com/paritytech/polkadot-sdk/issues/1842 // DONE: tests --------- Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Co-authored-by: Liam Aharon --- Cargo.lock | 4 + .../assets/asset-hub-rococo/src/tests/send.rs | 75 --- .../assets/asset-hub-rococo/src/tests/swap.rs | 127 ++++ .../asset-hub-westend/src/tests/send.rs | 75 --- .../asset-hub-westend/src/tests/swap.rs | 127 ++++ .../bridges/bridge-hub-rococo/Cargo.toml | 1 + .../bridges/bridge-hub-rococo/src/lib.rs | 3 +- .../src/tests/asset_transfers.rs | 45 +- .../bridges/bridge-hub-westend/Cargo.toml | 1 + .../bridges/bridge-hub-westend/src/lib.rs | 3 +- .../src/tests/asset_transfers.rs | 43 ++ .../assets/asset-hub-rococo/src/lib.rs | 19 +- .../assets/asset-hub-rococo/src/xcm_config.rs | 47 +- .../assets/asset-hub-rococo/tests/tests.rs | 497 +++++++--------- .../assets/asset-hub-westend/src/lib.rs | 19 +- .../asset-hub-westend/src/xcm_config.rs | 47 +- .../assets/asset-hub-westend/tests/tests.rs | 491 +++++++--------- .../runtimes/assets/common/src/lib.rs | 10 + .../runtimes/assets/test-utils/Cargo.toml | 2 + .../test-utils/src/test_cases_over_bridge.rs | 77 ++- cumulus/primitives/utility/Cargo.toml | 3 + cumulus/primitives/utility/src/lib.rs | 270 ++++++++- cumulus/primitives/utility/src/tests/mod.rs | 17 + .../utility/src/tests/swap_first.rs | 551 ++++++++++++++++++ prdoc/pr_1845.prdoc | 16 + 25 files changed, 1739 insertions(+), 831 deletions(-) create mode 100644 cumulus/primitives/utility/src/tests/mod.rs create mode 100644 cumulus/primitives/utility/src/tests/swap_first.rs create mode 100644 prdoc/pr_1845.prdoc diff --git a/Cargo.lock b/Cargo.lock index aa773aa104a..6299bbfe51c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1066,6 +1066,7 @@ dependencies = [ "frame-support", "frame-system", "hex-literal", + "pallet-asset-conversion", "pallet-assets", "pallet-balances", "pallet-collator-selection", @@ -1973,6 +1974,7 @@ dependencies = [ "frame-support", "hex", "hex-literal", + "pallet-asset-conversion", "pallet-assets", "pallet-balances", "pallet-bridge-messages", @@ -2165,6 +2167,7 @@ dependencies = [ "cumulus-pallet-xcmp-queue", "emulated-integration-tests-common", "frame-support", + "pallet-asset-conversion", "pallet-assets", "pallet-balances", "pallet-bridge-messages", @@ -4095,6 +4098,7 @@ dependencies = [ "cumulus-primitives-core", "frame-support", "log", + "pallet-asset-conversion", "pallet-xcm-benchmarks", "parity-scale-codec", "polkadot-runtime-common", diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/send.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/send.rs index 7be0463d2ec..fcf4513859e 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/send.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/send.rs @@ -27,78 +27,3 @@ fn send_transact_as_superuser_from_relay_to_system_para_works() { Some(Weight::from_parts(1_019_445_000, 200_000)), ) } - -/// Parachain should be able to send XCM paying its fee with sufficient asset -/// in the System Parachain -#[test] -fn send_xcm_from_para_to_system_para_paying_fee_with_assets_works() { - let para_sovereign_account = AssetHubRococo::sovereign_account_id_of( - AssetHubRococo::sibling_location_of(PenpalA::para_id()), - ); - - // Force create and mint assets for Parachain's sovereign account - AssetHubRococo::force_create_and_mint_asset( - ASSET_ID, - ASSET_MIN_BALANCE, - true, - para_sovereign_account.clone(), - Some(Weight::from_parts(1_019_445_000, 200_000)), - ASSET_MIN_BALANCE * 1000000000, - ); - - // We just need a call that can pass the `SafeCallFilter` - // Call values are not relevant - let call = AssetHubRococo::force_create_asset_call( - ASSET_ID, - para_sovereign_account.clone(), - true, - ASSET_MIN_BALANCE, - ); - - let origin_kind = OriginKind::SovereignAccount; - let fee_amount = ASSET_MIN_BALANCE * 1000000; - let native_asset = - (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), fee_amount).into(); - - let root_origin = ::RuntimeOrigin::root(); - let system_para_destination = PenpalA::sibling_location_of(AssetHubRococo::para_id()).into(); - let xcm = xcm_transact_paid_execution( - call, - origin_kind, - native_asset, - para_sovereign_account.clone(), - ); - - PenpalA::execute_with(|| { - assert_ok!(::PolkadotXcm::send( - root_origin, - bx!(system_para_destination), - bx!(xcm), - )); - - PenpalA::assert_xcm_pallet_sent(); - }); - - AssetHubRococo::execute_with(|| { - type RuntimeEvent = ::RuntimeEvent; - - AssetHubRococo::assert_xcmp_queue_success(Some(Weight::from_parts( - 15_594_564_000, - 562_893, - ))); - - assert_expected_events!( - AssetHubRococo, - vec![ - RuntimeEvent::Assets(pallet_assets::Event::Burned { asset_id, owner, balance }) => { - asset_id: *asset_id == ASSET_ID, - owner: *owner == para_sovereign_account, - balance: *balance == fee_amount, - }, - RuntimeEvent::Assets(pallet_assets::Event::Issued { asset_id, .. }) => { - asset_id: *asset_id == ASSET_ID, - }, - ] - ); - }); -} diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs index 3dcc51b75cc..b1af69a1cd1 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs @@ -270,3 +270,130 @@ fn cannot_create_pool_from_pool_assets() { ); }); } + +#[test] +fn pay_xcm_fee_with_some_asset_swapped_for_native() { + let asset_native = asset_hub_rococo_runtime::xcm_config::TokenLocation::get(); + let asset_one = MultiLocation { + parents: 0, + interior: X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), + }; + let penpal = AssetHubRococo::sovereign_account_id_of(AssetHubRococo::sibling_location_of( + PenpalA::para_id(), + )); + + AssetHubRococo::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + // set up pool with ASSET_ID <> NATIVE pair + assert_ok!(::Assets::create( + ::RuntimeOrigin::signed(AssetHubRococoSender::get()), + ASSET_ID.into(), + AssetHubRococoSender::get().into(), + ASSET_MIN_BALANCE, + )); + assert!(::Assets::asset_exists(ASSET_ID)); + + assert_ok!(::Assets::mint( + ::RuntimeOrigin::signed(AssetHubRococoSender::get()), + ASSET_ID.into(), + AssetHubRococoSender::get().into(), + 3_000_000_000_000, + )); + + assert_ok!(::AssetConversion::create_pool( + ::RuntimeOrigin::signed(AssetHubRococoSender::get()), + Box::new(asset_native), + Box::new(asset_one), + )); + + assert_expected_events!( + AssetHubRococo, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {}, + ] + ); + + assert_ok!(::AssetConversion::add_liquidity( + ::RuntimeOrigin::signed(AssetHubRococoSender::get()), + Box::new(asset_native), + Box::new(asset_one), + 1_000_000_000_000, + 2_000_000_000_000, + 0, + 0, + AssetHubRococoSender::get().into() + )); + + assert_expected_events!( + AssetHubRococo, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {lp_token_minted, .. }) => { lp_token_minted: *lp_token_minted == 1414213562273, }, + ] + ); + + // ensure `penpal` sovereign account has no native tokens and mint some `ASSET_ID` + assert_eq!( + ::Balances::free_balance(penpal.clone()), + 0 + ); + + assert_ok!(::Assets::touch_other( + ::RuntimeOrigin::signed(AssetHubRococoSender::get()), + ASSET_ID.into(), + penpal.clone().into(), + )); + + assert_ok!(::Assets::mint( + ::RuntimeOrigin::signed(AssetHubRococoSender::get()), + ASSET_ID.into(), + penpal.clone().into(), + 10_000_000_000_000, + )); + }); + + PenpalA::execute_with(|| { + // send xcm transact from `penpal` account which as only `ASSET_ID` tokens on + // `AssetHubRococo` + let call = AssetHubRococo::force_create_asset_call( + ASSET_ID + 1000, + penpal.clone(), + true, + ASSET_MIN_BALANCE, + ); + + let penpal_root = ::RuntimeOrigin::root(); + let fee_amount = 4_000_000_000_000u128; + let asset_one = + (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), fee_amount) + .into(); + let asset_hub_location = PenpalA::sibling_location_of(AssetHubRococo::para_id()).into(); + let xcm = xcm_transact_paid_execution( + call, + OriginKind::SovereignAccount, + asset_one, + penpal.clone(), + ); + + assert_ok!(::PolkadotXcm::send( + penpal_root, + bx!(asset_hub_location), + bx!(xcm), + )); + + PenpalA::assert_xcm_pallet_sent(); + }); + + AssetHubRococo::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + AssetHubRococo::assert_xcmp_queue_success(None); + assert_expected_events!( + AssetHubRococo, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::SwapCreditExecuted { .. },) => {}, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true,.. }) => {}, + ] + ); + }); +} diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/send.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/send.rs index 4b98eeb0ed3..d943bafc379 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/send.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/send.rs @@ -27,78 +27,3 @@ fn send_transact_as_superuser_from_relay_to_system_para_works() { Some(Weight::from_parts(1_019_445_000, 200_000)), ) } - -/// Parachain should be able to send XCM paying its fee with sufficient asset -/// in the System Parachain -#[test] -fn send_xcm_from_para_to_system_para_paying_fee_with_assets_works() { - let para_sovereign_account = AssetHubWestend::sovereign_account_id_of( - AssetHubWestend::sibling_location_of(PenpalB::para_id()), - ); - - // Force create and mint assets for Parachain's sovereign account - AssetHubWestend::force_create_and_mint_asset( - ASSET_ID, - ASSET_MIN_BALANCE, - true, - para_sovereign_account.clone(), - Some(Weight::from_parts(1_019_445_000, 200_000)), - ASSET_MIN_BALANCE * 1000000000, - ); - - // We just need a call that can pass the `SafeCallFilter` - // Call values are not relevant - let call = AssetHubWestend::force_create_asset_call( - ASSET_ID, - para_sovereign_account.clone(), - true, - ASSET_MIN_BALANCE, - ); - - let origin_kind = OriginKind::SovereignAccount; - let fee_amount = ASSET_MIN_BALANCE * 1000000; - let native_asset = - (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), fee_amount).into(); - - let root_origin = ::RuntimeOrigin::root(); - let system_para_destination = PenpalB::sibling_location_of(AssetHubWestend::para_id()).into(); - let xcm = xcm_transact_paid_execution( - call, - origin_kind, - native_asset, - para_sovereign_account.clone(), - ); - - PenpalB::execute_with(|| { - assert_ok!(::PolkadotXcm::send( - root_origin, - bx!(system_para_destination), - bx!(xcm), - )); - - PenpalB::assert_xcm_pallet_sent(); - }); - - AssetHubWestend::execute_with(|| { - type RuntimeEvent = ::RuntimeEvent; - - AssetHubWestend::assert_xcmp_queue_success(Some(Weight::from_parts( - 16_290_336_000, - 562_893, - ))); - - assert_expected_events!( - AssetHubWestend, - vec![ - RuntimeEvent::Assets(pallet_assets::Event::Burned { asset_id, owner, balance }) => { - asset_id: *asset_id == ASSET_ID, - owner: *owner == para_sovereign_account, - balance: *balance == fee_amount, - }, - RuntimeEvent::Assets(pallet_assets::Event::Issued { asset_id, .. }) => { - asset_id: *asset_id == ASSET_ID, - }, - ] - ); - }); -} diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs index 47b6ab01e8f..c768a1366fa 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs @@ -264,3 +264,130 @@ fn cannot_create_pool_from_pool_assets() { ); }); } + +#[test] +fn pay_xcm_fee_with_some_asset_swapped_for_native() { + let asset_native = asset_hub_westend_runtime::xcm_config::WestendLocation::get(); + let asset_one = MultiLocation { + parents: 0, + interior: X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), + }; + let penpal = AssetHubWestend::sovereign_account_id_of(AssetHubWestend::sibling_location_of( + PenpalB::para_id(), + )); + + AssetHubWestend::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + // set up pool with ASSET_ID <> NATIVE pair + assert_ok!(::Assets::create( + ::RuntimeOrigin::signed(AssetHubWestendSender::get()), + ASSET_ID.into(), + AssetHubWestendSender::get().into(), + ASSET_MIN_BALANCE, + )); + assert!(::Assets::asset_exists(ASSET_ID)); + + assert_ok!(::Assets::mint( + ::RuntimeOrigin::signed(AssetHubWestendSender::get()), + ASSET_ID.into(), + AssetHubWestendSender::get().into(), + 3_000_000_000_000, + )); + + assert_ok!(::AssetConversion::create_pool( + ::RuntimeOrigin::signed(AssetHubWestendSender::get()), + Box::new(asset_native), + Box::new(asset_one), + )); + + assert_expected_events!( + AssetHubWestend, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {}, + ] + ); + + assert_ok!(::AssetConversion::add_liquidity( + ::RuntimeOrigin::signed(AssetHubWestendSender::get()), + Box::new(asset_native), + Box::new(asset_one), + 1_000_000_000_000, + 2_000_000_000_000, + 0, + 0, + AssetHubWestendSender::get().into() + )); + + assert_expected_events!( + AssetHubWestend, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {lp_token_minted, .. }) => { lp_token_minted: *lp_token_minted == 1414213562273, }, + ] + ); + + // ensure `penpal` sovereign account has no native tokens and mint some `ASSET_ID` + assert_eq!( + ::Balances::free_balance(penpal.clone()), + 0 + ); + + assert_ok!(::Assets::touch_other( + ::RuntimeOrigin::signed(AssetHubWestendSender::get()), + ASSET_ID.into(), + penpal.clone().into(), + )); + + assert_ok!(::Assets::mint( + ::RuntimeOrigin::signed(AssetHubWestendSender::get()), + ASSET_ID.into(), + penpal.clone().into(), + 10_000_000_000_000, + )); + }); + + PenpalB::execute_with(|| { + // send xcm transact from `penpal` account which as only `ASSET_ID` tokens on + // `AssetHubWestend` + let call = AssetHubWestend::force_create_asset_call( + ASSET_ID + 1000, + penpal.clone(), + true, + ASSET_MIN_BALANCE, + ); + + let penpal_root = ::RuntimeOrigin::root(); + let fee_amount = 4_000_000_000_000u128; + let asset_one = + (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), fee_amount) + .into(); + let asset_hub_location = PenpalB::sibling_location_of(AssetHubWestend::para_id()).into(); + let xcm = xcm_transact_paid_execution( + call, + OriginKind::SovereignAccount, + asset_one, + penpal.clone(), + ); + + assert_ok!(::PolkadotXcm::send( + penpal_root, + bx!(asset_hub_location), + bx!(xcm), + )); + + PenpalB::assert_xcm_pallet_sent(); + }); + + AssetHubWestend::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + AssetHubWestend::assert_xcmp_queue_success(None); + assert_expected_events!( + AssetHubWestend, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::SwapCreditExecuted { .. },) => {}, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true,.. }) => {}, + ] + ); + }); +} diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml index 0904578b156..da09c674a03 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml @@ -20,6 +20,7 @@ hex-literal = "0.4.1" sp-core = { path = "../../../../../../../substrate/primitives/core", default-features = false } frame-support = { path = "../../../../../../../substrate/frame/support", default-features = false } pallet-assets = { path = "../../../../../../../substrate/frame/assets", default-features = false } +pallet-asset-conversion = { path = "../../../../../../../substrate/frame/asset-conversion", default-features = false } pallet-balances = { path = "../../../../../../../substrate/frame/balances", default-features = false } pallet-message-queue = { path = "../../../../../../../substrate/frame/message-queue" } sp-runtime = { path = "../../../../../../../substrate/primitives/runtime", default-features = false } diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs index 5127bd759dc..608aa388ce8 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs @@ -61,7 +61,8 @@ pub use rococo_westend_system_emulated_network::{ rococo_emulated_chain::{genesis::ED as ROCOCO_ED, RococoRelayPallet as RococoPallet}, AssetHubRococoPara as AssetHubRococo, AssetHubRococoParaReceiver as AssetHubRococoReceiver, AssetHubRococoParaSender as AssetHubRococoSender, AssetHubWestendPara as AssetHubWestend, - AssetHubWestendParaReceiver as AssetHubWestendReceiver, BridgeHubRococoPara as BridgeHubRococo, + AssetHubWestendParaReceiver as AssetHubWestendReceiver, + AssetHubWestendParaSender as AssetHubWestendSender, BridgeHubRococoPara as BridgeHubRococo, BridgeHubRococoParaSender as BridgeHubRococoSender, BridgeHubWestendPara as BridgeHubWestend, RococoRelay as Rococo, RococoRelayReceiver as RococoReceiver, RococoRelaySender as RococoSender, diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs index 5a2111a9be9..8b5a72a8e62 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs @@ -49,6 +49,49 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() { AssetHubWestend::para_id(), ); + AssetHubWestend::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + // setup a pool to pay xcm fees with `roc_at_asset_hub_westend` tokens + assert_ok!(::ForeignAssets::mint( + ::RuntimeOrigin::signed(AssetHubWestendSender::get()), + roc_at_asset_hub_westend.into(), + AssetHubWestendSender::get().into(), + 3_000_000_000_000, + )); + + assert_ok!(::AssetConversion::create_pool( + ::RuntimeOrigin::signed(AssetHubWestendSender::get()), + Box::new(Parent.into()), + Box::new(roc_at_asset_hub_westend), + )); + + assert_expected_events!( + AssetHubWestend, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {}, + ] + ); + + assert_ok!(::AssetConversion::add_liquidity( + ::RuntimeOrigin::signed(AssetHubWestendSender::get()), + Box::new(Parent.into()), + Box::new(roc_at_asset_hub_westend), + 1_000_000_000_000, + 2_000_000_000_000, + 1, + 1, + AssetHubWestendSender::get().into() + )); + + assert_expected_events!( + AssetHubWestend, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {..}) => {}, + ] + ); + }); + let rocs_in_reserve_on_ahr_before = ::account_data_of(sov_ahw_on_ahr.clone()).free; let sender_rocs_before = @@ -58,7 +101,7 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() { >::balance(roc_at_asset_hub_westend, &AssetHubWestendReceiver::get()) }); - let amount = ASSET_HUB_ROCOCO_ED * 1_000; + let amount = ASSET_HUB_ROCOCO_ED * 1_000_000; send_asset_from_asset_hub_rococo_to_asset_hub_westend(roc_at_asset_hub_rococo, amount); AssetHubWestend::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/Cargo.toml b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/Cargo.toml index 6dcb57f4161..e9b4f8fb180 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/Cargo.toml @@ -16,6 +16,7 @@ codec = { package = "parity-scale-codec", version = "3.4.0", default-features = # Substrate frame-support = { path = "../../../../../../../substrate/frame/support", default-features = false } pallet-assets = { path = "../../../../../../../substrate/frame/assets", default-features = false } +pallet-asset-conversion = { path = "../../../../../../../substrate/frame/asset-conversion", default-features = false } pallet-balances = { path = "../../../../../../../substrate/frame/balances", default-features = false } pallet-message-queue = { path = "../../../../../../../substrate/frame/message-queue" } sp-runtime = { path = "../../../../../../../substrate/primitives/runtime", default-features = false } diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs index 90a11d38f77..17255320f1d 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs @@ -55,7 +55,8 @@ pub use rococo_westend_system_emulated_network::{ }, westend_emulated_chain::WestendRelayPallet as WestendPallet, AssetHubRococoPara as AssetHubRococo, AssetHubRococoParaReceiver as AssetHubRococoReceiver, - AssetHubWestendPara as AssetHubWestend, AssetHubWestendParaReceiver as AssetHubWestendReceiver, + AssetHubRococoParaSender as AssetHubRococoSender, AssetHubWestendPara as AssetHubWestend, + AssetHubWestendParaReceiver as AssetHubWestendReceiver, AssetHubWestendParaSender as AssetHubWestendSender, BridgeHubRococoPara as BridgeHubRococo, BridgeHubWestendPara as BridgeHubWestend, BridgeHubWestendParaSender as BridgeHubWestendSender, WestendRelay as Westend, diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs index 21f4b4ee235..a4b2719e9fd 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs @@ -48,6 +48,49 @@ fn send_wnds_from_asset_hub_westend_to_asset_hub_rococo() { AssetHubRococo::para_id(), ); + AssetHubRococo::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + // setup a pool to pay xcm fees with `wnd_at_asset_hub_rococo` tokens + assert_ok!(::ForeignAssets::mint( + ::RuntimeOrigin::signed(AssetHubRococoSender::get()), + wnd_at_asset_hub_rococo.into(), + AssetHubRococoSender::get().into(), + 3_000_000_000_000, + )); + + assert_ok!(::AssetConversion::create_pool( + ::RuntimeOrigin::signed(AssetHubRococoSender::get()), + Box::new(Parent.into()), + Box::new(wnd_at_asset_hub_rococo), + )); + + assert_expected_events!( + AssetHubRococo, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {}, + ] + ); + + assert_ok!(::AssetConversion::add_liquidity( + ::RuntimeOrigin::signed(AssetHubRococoSender::get()), + Box::new(Parent.into()), + Box::new(wnd_at_asset_hub_rococo), + 1_000_000_000_000, + 2_000_000_000_000, + 1, + 1, + AssetHubRococoSender::get().into() + )); + + assert_expected_events!( + AssetHubRococo, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {..}) => {}, + ] + ); + }); + let wnds_in_reserve_on_ahw_before = ::account_data_of(sov_ahr_on_ahw.clone()).free; let sender_wnds_before = diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 3010cbc69fa..8cfa4565187 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -312,7 +312,7 @@ impl pallet_assets::Config for Runtime { type BenchmarkHelper = (); } -/// Union fungibles implementation for `Assets`` and `ForeignAssets`. +/// Union fungibles implementation for `Assets` and `ForeignAssets`. pub type LocalAndForeignAssets = fungibles::UnionOf< Assets, ForeignAssets, @@ -324,18 +324,21 @@ pub type LocalAndForeignAssets = fungibles::UnionOf< AccountId, >; +/// Union fungibles implementation for [`LocalAndForeignAssets`] and `Balances`. +pub type NativeAndAssets = fungible::UnionOf< + Balances, + LocalAndForeignAssets, + TargetFromLeft, + MultiLocation, + AccountId, +>; + impl pallet_asset_conversion::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type HigherPrecisionBalance = sp_core::U256; type AssetKind = MultiLocation; - type Assets = fungible::UnionOf< - Balances, - LocalAndForeignAssets, - TargetFromLeft, - Self::AssetKind, - Self::AccountId, - >; + type Assets = NativeAndAssets; type PoolId = (Self::AssetKind, Self::AssetKind); type PoolLocator = pallet_asset_conversion::WithFirstAsset; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs index 121e213b57f..f88d1066488 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs @@ -15,17 +15,21 @@ use super::{ AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, BaseDeliveryFee, - FeeAssetId, ForeignAssets, ForeignAssetsInstance, ParachainInfo, ParachainSystem, PolkadotXcm, - PoolAssets, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, ToWestendXcmRouter, - TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, + CollatorSelection, FeeAssetId, ForeignAssets, ForeignAssetsInstance, ParachainInfo, + ParachainSystem, PolkadotXcm, PoolAssets, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, + ToWestendXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, }; use assets_common::{ local_and_foreign_assets::MatchesLocalAndForeignAssetsMultiLocation, matching::{FromNetwork, FromSiblingParachain, IsForeignConcreteAsset}, + TrustBackedAssetsAsMultiLocation, }; use frame_support::{ match_types, parameter_types, - traits::{ConstU32, Contains, Equals, Everything, Nothing, PalletInfoAccess}, + traits::{ + tokens::imbalance::ResolveAssetTo, ConstU32, Contains, Equals, Everything, Nothing, + PalletInfoAccess, + }, }; use frame_system::EnsureRoot; use pallet_xcm::XcmPassthrough; @@ -73,6 +77,7 @@ parameter_types! { pub PoolAssetsPalletLocation: MultiLocation = PalletInstance(::index() as u8).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); + pub StakingPot: AccountId = CollatorSelection::account_id(); pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); @@ -550,31 +555,17 @@ impl xcm_executor::Config for XcmConfig { >; type Trader = ( UsingComponents>, - // This trader allows to pay with `is_sufficient=true` "Trust Backed" assets from dedicated - // `pallet_assets` instance - `Assets`. - cumulus_primitives_utility::TakeFirstAssetTrader< + cumulus_primitives_utility::SwapFirstAssetTrader< + TokenLocation, + crate::AssetConversion, + WeightToFee, + crate::NativeAndAssets, + ( + TrustBackedAssetsAsMultiLocation, + ForeignAssetsConvertedConcreteId, + ), + ResolveAssetTo, AccountId, - AssetFeeAsExistentialDepositMultiplierFeeCharger, - TrustBackedAssetsConvertedConcreteId, - Assets, - cumulus_primitives_utility::XcmFeesTo32ByteAccount< - FungiblesTransactor, - AccountId, - XcmAssetFeesReceiver, - >, - >, - // This trader allows to pay with `is_sufficient=true` "Foreign" assets from dedicated - // `pallet_assets` instance - `ForeignAssets`. - cumulus_primitives_utility::TakeFirstAssetTrader< - AccountId, - ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, - ForeignAssetsConvertedConcreteId, - ForeignAssets, - cumulus_primitives_utility::XcmFeesTo32ByteAccount< - ForeignFungiblesTransactor, - AccountId, - XcmAssetFeesReceiver, - >, >, ); type ResponseHandler = PolkadotXcm; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs index 42c91cc8ea6..c67374126d3 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs @@ -17,34 +17,38 @@ //! Tests for the Rococo Assets Hub chain. -use asset_hub_rococo_runtime::xcm_config::{ - AssetFeeAsExistentialDepositMultiplierFeeCharger, TokenLocation, - TrustBackedAssetsPalletLocation, +use asset_hub_rococo_runtime::{ + xcm_config, + xcm_config::{bridging, ForeignCreatorsSovereignAccountOf, LocationToAccountId, TokenLocation}, + AllPalletsWithoutSystem, MetadataDepositBase, MetadataDepositPerByte, RuntimeCall, + RuntimeEvent, ToWestendXcmRouterInstance, XcmpQueue, }; pub use asset_hub_rococo_runtime::{ - xcm_config::{ - self, bridging, CheckingAccount, ForeignCreatorsSovereignAccountOf, LocationToAccountId, - XcmConfig, - }, - AllPalletsWithoutSystem, AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets, - ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, Runtime, - RuntimeCall, RuntimeEvent, SessionKeys, System, ToWestendXcmRouterInstance, - TrustBackedAssetsInstance, XcmpQueue, + xcm_config::{CheckingAccount, TrustBackedAssetsPalletLocation, XcmConfig}, + AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, ExistentialDeposit, + ForeignAssets, ForeignAssetsInstance, ParachainSystem, Runtime, SessionKeys, System, + TrustBackedAssetsInstance, }; use asset_test_utils::{ test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, }; use codec::{Decode, Encode}; -use cumulus_primitives_utility::ChargeWeightInFungibles; use frame_support::{ - assert_noop, assert_ok, - traits::fungibles::InspectEnumerable, + assert_ok, + traits::{ + fungible::{Inspect, Mutate}, + fungibles::{ + Create, Inspect as FungiblesInspect, InspectEnumerable, Mutate as FungiblesMutate, + }, + }, weights::{Weight, WeightToFee as WeightToFeeT}, }; use parachains_common::{ - rococo::fee::WeightToFee, AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, + rococo::{currency::UNITS, fee::WeightToFee}, + AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, }; use sp_runtime::traits::MaybeEquivalence; +use std::convert::Into; use xcm::latest::prelude::*; use xcm_executor::traits::{Identity, JustTry, WeightTrader}; @@ -69,7 +73,7 @@ fn collator_session_keys() -> CollatorSessionKeys { } #[test] -fn test_asset_xcm_trader() { +fn test_buy_and_refund_weight_in_native() { ExtBuilder::::default() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( @@ -79,77 +83,55 @@ fn test_asset_xcm_trader() { )]) .build() .execute_with(|| { - // We need root origin to create a sufficient asset - let minimum_asset_balance = 3333333_u128; - let local_asset_id = 1; - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - local_asset_id.into(), - AccountId::from(ALICE).into(), - true, - minimum_asset_balance - )); + let bob: AccountId = SOME_ASSET_ADMIN.into(); + let staking_pot = CollatorSelection::account_id(); + let native_location = TokenLocation::get(); + let initial_balance = 200 * UNITS; - // We first mint enough asset for the account to exist for assets - assert_ok!(Assets::mint( - RuntimeHelper::origin_of(AccountId::from(ALICE)), - local_asset_id.into(), - AccountId::from(ALICE).into(), - minimum_asset_balance - )); - - // get asset id as multilocation - let asset_multilocation = - AssetIdForTrustBackedAssetsConvert::convert_back(&local_asset_id).unwrap(); - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy 4e9 weight - let bought = Weight::from_parts(4_000_000_000u64, 0); + assert_ok!(Balances::mint_into(&bob, initial_balance)); + assert_ok!(Balances::mint_into(&staking_pot, initial_balance)); - // Lets calculate amount needed - let asset_amount_needed = - AssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles( - local_asset_id, - bought, - ) - .expect("failed to compute"); - - // Lets pay with: asset_amount_needed + asset_amount_extra - let asset_amount_extra = 100_u128; - let asset: MultiAsset = - (asset_multilocation, asset_amount_needed + asset_amount_extra).into(); + // keep initial total issuance to assert later. + let total_issuance = Balances::total_issuance(); - let mut trader = ::Trader::new(); + // prepare input to buy weight. + let weight = Weight::from_parts(4_000_000_000, 0); + let fee = WeightToFee::weight_to_fee(&weight); + let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + let payment: MultiAsset = (native_location, fee + extra_amount).into(); - // Lets buy_weight and make sure buy_weight does not return an error - let unused_assets = trader.buy_weight(bought, asset.into(), &ctx).expect("Expected Ok"); - // Check whether a correct amount of unused assets is returned - assert_ok!( - unused_assets.ensure_contains(&(asset_multilocation, asset_amount_extra).into()) - ); - - // Drop trader + // init trader and buy weight. + let mut trader = ::Trader::new(); + let unused_asset = + trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); + + // assert. + let unused_amount = + unused_asset.fungible.get(&native_location.into()).map_or(0, |a| *a); + assert_eq!(unused_amount, extra_amount); + assert_eq!(Balances::total_issuance(), total_issuance); + + // prepare input to refund weight. + let refund_weight = Weight::from_parts(1_000_000_000, 0); + let refund = WeightToFee::weight_to_fee(&refund_weight); + + // refund. + let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); + assert_eq!(actual_refund, (native_location, refund).into()); + + // assert. + assert_eq!(Balances::balance(&staking_pot), initial_balance); + // only after `trader` is dropped we expect the fee to be resolved into the treasury + // account. drop(trader); - - // Make sure author(Alice) has received the amount - assert_eq!( - Assets::balance(local_asset_id, AccountId::from(ALICE)), - minimum_asset_balance + asset_amount_needed - ); - - // We also need to ensure the total supply increased - assert_eq!( - Assets::total_supply(local_asset_id), - minimum_asset_balance + asset_amount_needed - ); - }); + assert_eq!(Balances::balance(&staking_pot), initial_balance + fee - refund); + assert_eq!(Balances::total_issuance(), total_issuance + fee - refund); + }) } #[test] -fn test_asset_xcm_trader_with_refund() { +fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { ExtBuilder::::default() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( @@ -159,77 +141,93 @@ fn test_asset_xcm_trader_with_refund() { )]) .build() .execute_with(|| { - // We need root origin to create a sufficient asset - // We set existential deposit to be identical to the one for Balances first - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - true, - ExistentialDeposit::get() + let bob: AccountId = SOME_ASSET_ADMIN.into(); + let staking_pot = CollatorSelection::account_id(); + let asset_1: u32 = 1; + let native_location = TokenLocation::get(); + let asset_1_location = + AssetIdForTrustBackedAssetsConvert::convert_back(&asset_1).unwrap(); + // bob's initial balance for native and `asset1` assets. + let initial_balance = 200 * UNITS; + // liquidity for both arms of (native, asset1) pool. + let pool_liquidity = 100 * UNITS; + + // init asset, balances and pool. + assert_ok!(>::create(asset_1, bob.clone(), true, 10)); + + assert_ok!(Assets::mint_into(asset_1, &bob, initial_balance)); + assert_ok!(Balances::mint_into(&bob, initial_balance)); + assert_ok!(Balances::mint_into(&staking_pot, initial_balance)); + + assert_ok!(AssetConversion::create_pool( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(asset_1_location) )); - // We first mint enough asset for the account to exist for assets - assert_ok!(Assets::mint( - RuntimeHelper::origin_of(AccountId::from(ALICE)), - 1.into(), - AccountId::from(ALICE).into(), - ExistentialDeposit::get() + assert_ok!(AssetConversion::add_liquidity( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(asset_1_location), + pool_liquidity, + pool_liquidity, + 1, + 1, + bob, )); - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy 4e9 weight - let bought = Weight::from_parts(4_000_000_000u64, 0); - - let asset_multilocation = AssetIdForTrustBackedAssetsConvert::convert_back(&1).unwrap(); - - // lets calculate amount needed - let amount_bought = WeightToFee::weight_to_fee(&bought); - - let asset: MultiAsset = (asset_multilocation, amount_bought).into(); - - // Make sure buy_weight does not return an error - assert_ok!(trader.buy_weight(bought, asset.clone().into(), &ctx)); - - // Make sure again buy_weight does return an error - // This assert relies on the fact, that we use `TakeFirstAssetTrader` in `WeightTrader` - // tuple chain, which cannot be called twice - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // We actually use half of the weight - let weight_used = bought / 2; + // keep initial total issuance to assert later. + let asset_total_issuance = Assets::total_issuance(asset_1); + let native_total_issuance = Balances::total_issuance(); - // Make sure refurnd works. - let amount_refunded = WeightToFee::weight_to_fee(&(bought - weight_used)); - - assert_eq!( - trader.refund_weight(bought - weight_used, &ctx), - Some((asset_multilocation, amount_refunded).into()) - ); + // prepare input to buy weight. + let weight = Weight::from_parts(4_000_000_000, 0); + let fee = WeightToFee::weight_to_fee(&weight); + let asset_fee = + AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); + let extra_amount = 100; + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + let payment: MultiAsset = (asset_1_location, asset_fee + extra_amount).into(); - // Drop trader + // init trader and buy weight. + let mut trader = ::Trader::new(); + let unused_asset = + trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); + + // assert. + let unused_amount = + unused_asset.fungible.get(&asset_1_location.into()).map_or(0, |a| *a); + assert_eq!(unused_amount, extra_amount); + assert_eq!(Assets::total_issuance(asset_1), asset_total_issuance + asset_fee); + + // prepare input to refund weight. + let refund_weight = Weight::from_parts(1_000_000_000, 0); + let refund = WeightToFee::weight_to_fee(&refund_weight); + let (reserve1, reserve2) = + AssetConversion::get_reserves(native_location, asset_1_location).unwrap(); + let asset_refund = + AssetConversion::get_amount_out(&refund, &reserve1, &reserve2).unwrap(); + + // refund. + let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); + assert_eq!(actual_refund, (asset_1_location, asset_refund).into()); + + // assert. + assert_eq!(Balances::balance(&staking_pot), initial_balance); + // only after `trader` is dropped we expect the fee to be resolved into the treasury + // account. drop(trader); - - // We only should have paid for half of the bought weight - let fees_paid = WeightToFee::weight_to_fee(&weight_used); - + assert_eq!(Balances::balance(&staking_pot), initial_balance + fee - refund); assert_eq!( - Assets::balance(1, AccountId::from(ALICE)), - ExistentialDeposit::get() + fees_paid + Assets::total_issuance(asset_1), + asset_total_issuance + asset_fee - asset_refund ); - - // We also need to ensure the total supply increased - assert_eq!(Assets::total_supply(1), ExistentialDeposit::get() + fees_paid); - }); + assert_eq!(Balances::total_issuance(), native_total_issuance); + }) } #[test] -fn test_asset_xcm_trader_refund_not_possible_since_amount_less_than_ed() { +fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { ExtBuilder::::default() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( @@ -239,169 +237,96 @@ fn test_asset_xcm_trader_refund_not_possible_since_amount_less_than_ed() { )]) .build() .execute_with(|| { - // We need root origin to create a sufficient asset - // We set existential deposit to be identical to the one for Balances first - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), + let bob: AccountId = SOME_ASSET_ADMIN.into(); + let staking_pot = CollatorSelection::account_id(); + let native_location = TokenLocation::get(); + let foreign_location = + MultiLocation { parents: 1, interior: X2(Parachain(1234), GeneralIndex(12345)) }; + // bob's initial balance for native and `asset1` assets. + let initial_balance = 200 * UNITS; + // liquidity for both arms of (native, asset1) pool. + let pool_liquidity = 100 * UNITS; + + // init asset, balances and pool. + assert_ok!(>::create( + foreign_location, + bob.clone(), true, - ExistentialDeposit::get() + 10 )); - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy small amount - let bought = Weight::from_parts(500_000_000u64, 0); - - let asset_multilocation = AssetIdForTrustBackedAssetsConvert::convert_back(&1).unwrap(); + assert_ok!(ForeignAssets::mint_into(foreign_location, &bob, initial_balance)); + assert_ok!(Balances::mint_into(&bob, initial_balance)); + assert_ok!(Balances::mint_into(&staking_pot, initial_balance)); - let amount_bought = WeightToFee::weight_to_fee(&bought); - - assert!( - amount_bought < ExistentialDeposit::get(), - "we are testing what happens when the amount does not exceed ED" - ); - - let asset: MultiAsset = (asset_multilocation, amount_bought).into(); - - // Buy weight should return an error - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // not credited since the ED is higher than this value - assert_eq!(Assets::balance(1, AccountId::from(ALICE)), 0); - - // We also need to ensure the total supply did not increase - assert_eq!(Assets::total_supply(1), 0); - }); -} - -#[test] -fn test_that_buying_ed_refund_does_not_refund() { - ExtBuilder::::default() - .with_collators(vec![AccountId::from(ALICE)]) - .with_session_keys(vec![( - AccountId::from(ALICE), - AccountId::from(ALICE), - SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, - )]) - .build() - .execute_with(|| { - // We need root origin to create a sufficient asset - // We set existential deposit to be identical to the one for Balances first - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - true, - ExistentialDeposit::get() + assert_ok!(AssetConversion::create_pool( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(foreign_location) )); - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are gonna buy ED - let bought = Weight::from_parts(ExistentialDeposit::get().try_into().unwrap(), 0); - - let asset_multilocation = AssetIdForTrustBackedAssetsConvert::convert_back(&1).unwrap(); - - let amount_bought = WeightToFee::weight_to_fee(&bought); - - assert!( - amount_bought < ExistentialDeposit::get(), - "we are testing what happens when the amount does not exceed ED" - ); - - // We know we will have to buy at least ED, so lets make sure first it will - // fail with a payment of less than ED - let asset: MultiAsset = (asset_multilocation, amount_bought).into(); - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // Now lets buy ED at least - let asset: MultiAsset = (asset_multilocation, ExistentialDeposit::get()).into(); - - // Buy weight should work - assert_ok!(trader.buy_weight(bought, asset.into(), &ctx)); - - // Should return None. We have a specific check making sure we dont go below ED for - // drop payment - assert_eq!(trader.refund_weight(bought, &ctx), None); - - // Drop trader - drop(trader); - - // Make sure author(Alice) has received the amount - assert_eq!(Assets::balance(1, AccountId::from(ALICE)), ExistentialDeposit::get()); - - // We also need to ensure the total supply increased - assert_eq!(Assets::total_supply(1), ExistentialDeposit::get()); - }); -} - -#[test] -fn test_asset_xcm_trader_not_possible_for_non_sufficient_assets() { - ExtBuilder::::default() - .with_collators(vec![AccountId::from(ALICE)]) - .with_session_keys(vec![( - AccountId::from(ALICE), - AccountId::from(ALICE), - SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, - )]) - .build() - .execute_with(|| { - // Create a non-sufficient asset with specific existential deposit - let minimum_asset_balance = 1_000_000_u128; - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - false, - minimum_asset_balance + assert_ok!(AssetConversion::add_liquidity( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(foreign_location), + pool_liquidity, + pool_liquidity, + 1, + 1, + bob, )); - // We first mint enough asset for the account to exist for assets - assert_ok!(Assets::mint( - RuntimeHelper::origin_of(AccountId::from(ALICE)), - 1.into(), - AccountId::from(ALICE).into(), - minimum_asset_balance - )); + // keep initial total issuance to assert later. + let asset_total_issuance = ForeignAssets::total_issuance(foreign_location); + let native_total_issuance = Balances::total_issuance(); - let mut trader = ::Trader::new(); + // prepare input to buy weight. + let weight = Weight::from_parts(4_000_000_000, 0); + let fee = WeightToFee::weight_to_fee(&weight); + let asset_fee = + AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); + let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + let payment: MultiAsset = (foreign_location, asset_fee + extra_amount).into(); - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy 4e9 weight - let bought = Weight::from_parts(4_000_000_000u64, 0); - - // lets calculate amount needed - let asset_amount_needed = WeightToFee::weight_to_fee(&bought); - - let asset_multilocation = AssetIdForTrustBackedAssetsConvert::convert_back(&1).unwrap(); - - let asset: MultiAsset = (asset_multilocation, asset_amount_needed).into(); + // init trader and buy weight. + let mut trader = ::Trader::new(); + let unused_asset = + trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); - // Make sure again buy_weight does return an error - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + // assert. + let unused_amount = + unused_asset.fungible.get(&foreign_location.into()).map_or(0, |a| *a); + assert_eq!(unused_amount, extra_amount); + assert_eq!( + ForeignAssets::total_issuance(foreign_location), + asset_total_issuance + asset_fee + ); - // Drop trader + // prepare input to refund weight. + let refund_weight = Weight::from_parts(1_000_000_000, 0); + let refund = WeightToFee::weight_to_fee(&refund_weight); + let (reserve1, reserve2) = + AssetConversion::get_reserves(native_location, foreign_location).unwrap(); + let asset_refund = + AssetConversion::get_amount_out(&refund, &reserve1, &reserve2).unwrap(); + + // refund. + let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); + assert_eq!(actual_refund, (foreign_location, asset_refund).into()); + + // assert. + assert_eq!(Balances::balance(&staking_pot), initial_balance); + // only after `trader` is dropped we expect the fee to be resolved into the treasury + // account. drop(trader); - - // Make sure author(Alice) has NOT received the amount - assert_eq!(Assets::balance(1, AccountId::from(ALICE)), minimum_asset_balance); - - // We also need to ensure the total supply NOT increased - assert_eq!(Assets::total_supply(1), minimum_asset_balance); - }); + assert_eq!(Balances::balance(&staking_pot), initial_balance + fee - refund); + assert_eq!( + ForeignAssets::total_issuance(foreign_location), + asset_total_issuance + asset_fee - asset_refund + ); + assert_eq!(Balances::total_issuance(), native_total_issuance); + }) } #[test] diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index e0dff0c4516..8543500fa23 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -295,7 +295,7 @@ impl pallet_assets::Config for Runtime { type BenchmarkHelper = (); } -/// Union fungibles implementation for `Assets`` and `ForeignAssets`. +/// Union fungibles implementation for `Assets` and `ForeignAssets`. pub type LocalAndForeignAssets = fungibles::UnionOf< Assets, ForeignAssets, @@ -307,18 +307,21 @@ pub type LocalAndForeignAssets = fungibles::UnionOf< AccountId, >; +/// Union fungibles implementation for [`LocalAndForeignAssets`] and `Balances`. +pub type NativeAndAssets = fungible::UnionOf< + Balances, + LocalAndForeignAssets, + TargetFromLeft, + MultiLocation, + AccountId, +>; + impl pallet_asset_conversion::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type HigherPrecisionBalance = sp_core::U256; type AssetKind = MultiLocation; - type Assets = fungible::UnionOf< - Balances, - LocalAndForeignAssets, - TargetFromLeft, - Self::AssetKind, - Self::AccountId, - >; + type Assets = NativeAndAssets; type PoolId = (Self::AssetKind, Self::AssetKind); type PoolLocator = pallet_asset_conversion::WithFirstAsset; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs index cb2fedeb146..28876d1d454 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs @@ -15,17 +15,21 @@ use super::{ AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, BaseDeliveryFee, - FeeAssetId, ForeignAssets, ForeignAssetsInstance, ParachainInfo, ParachainSystem, PolkadotXcm, - PoolAssets, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, ToRococoXcmRouter, - TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, + CollatorSelection, FeeAssetId, ForeignAssets, ForeignAssetsInstance, ParachainInfo, + ParachainSystem, PolkadotXcm, PoolAssets, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, + ToRococoXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, }; use assets_common::{ local_and_foreign_assets::MatchesLocalAndForeignAssetsMultiLocation, matching::{FromSiblingParachain, IsForeignConcreteAsset}, + TrustBackedAssetsAsMultiLocation, }; use frame_support::{ match_types, parameter_types, - traits::{ConstU32, Contains, Equals, Everything, Nothing, PalletInfoAccess}, + traits::{ + tokens::imbalance::ResolveAssetTo, ConstU32, Contains, Equals, Everything, Nothing, + PalletInfoAccess, + }, }; use frame_system::EnsureRoot; use pallet_xcm::XcmPassthrough; @@ -70,6 +74,7 @@ parameter_types! { pub PoolAssetsPalletLocation: MultiLocation = PalletInstance(::index() as u8).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); + pub StakingPot: AccountId = CollatorSelection::account_id(); pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); } @@ -567,31 +572,17 @@ impl xcm_executor::Config for XcmConfig { >; type Trader = ( UsingComponents>, - // This trader allows to pay with `is_sufficient=true` "Trust Backed" assets from dedicated - // `pallet_assets` instance - `Assets`. - cumulus_primitives_utility::TakeFirstAssetTrader< + cumulus_primitives_utility::SwapFirstAssetTrader< + WestendLocation, + crate::AssetConversion, + WeightToFee, + crate::NativeAndAssets, + ( + TrustBackedAssetsAsMultiLocation, + ForeignAssetsConvertedConcreteId, + ), + ResolveAssetTo, AccountId, - AssetFeeAsExistentialDepositMultiplierFeeCharger, - TrustBackedAssetsConvertedConcreteId, - Assets, - cumulus_primitives_utility::XcmFeesTo32ByteAccount< - FungiblesTransactor, - AccountId, - XcmAssetFeesReceiver, - >, - >, - // This trader allows to pay with `is_sufficient=true` "Foreign" assets from dedicated - // `pallet_assets` instance - `ForeignAssets`. - cumulus_primitives_utility::TakeFirstAssetTrader< - AccountId, - ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, - ForeignAssetsConvertedConcreteId, - ForeignAssets, - cumulus_primitives_utility::XcmFeesTo32ByteAccount< - ForeignFungiblesTransactor, - AccountId, - XcmAssetFeesReceiver, - >, >, ); type ResponseHandler = PolkadotXcm; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs index 0aaf1d91879..c50a8f3661d 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs @@ -18,28 +18,36 @@ //! Tests for the Westmint (Westend Assets Hub) chain. use asset_hub_westend_runtime::{ + xcm_config, xcm_config::{ - self, bridging, AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, - ForeignCreatorsSovereignAccountOf, LocationToAccountId, TrustBackedAssetsPalletLocation, - WestendLocation, XcmConfig, + bridging, ForeignCreatorsSovereignAccountOf, LocationToAccountId, WestendLocation, }, - AllPalletsWithoutSystem, AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets, - ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, - PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, - ToRococoXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue, + AllPalletsWithoutSystem, MetadataDepositBase, MetadataDepositPerByte, PolkadotXcm, RuntimeCall, + RuntimeEvent, RuntimeOrigin, ToRococoXcmRouterInstance, XcmpQueue, +}; +pub use asset_hub_westend_runtime::{ + xcm_config::{CheckingAccount, TrustBackedAssetsPalletLocation, XcmConfig}, + AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, ExistentialDeposit, + ForeignAssets, ForeignAssetsInstance, ParachainSystem, Runtime, SessionKeys, System, + TrustBackedAssetsInstance, }; use asset_test_utils::{ test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, }; use codec::{Decode, Encode}; -use cumulus_primitives_utility::ChargeWeightInFungibles; use frame_support::{ - assert_noop, assert_ok, - traits::fungibles::InspectEnumerable, + assert_ok, + traits::{ + fungible::{Inspect, Mutate}, + fungibles::{ + Create, Inspect as FungiblesInspect, InspectEnumerable, Mutate as FungiblesMutate, + }, + }, weights::{Weight, WeightToFee as WeightToFeeT}, }; use parachains_common::{ - westend::fee::WeightToFee, AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, + westend::{currency::UNITS, fee::WeightToFee}, + AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, }; use sp_runtime::traits::MaybeEquivalence; use std::convert::Into; @@ -67,7 +75,7 @@ fn collator_session_keys() -> CollatorSessionKeys { } #[test] -fn test_asset_xcm_trader() { +fn test_buy_and_refund_weight_in_native() { ExtBuilder::::default() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( @@ -77,77 +85,55 @@ fn test_asset_xcm_trader() { )]) .build() .execute_with(|| { - // We need root origin to create a sufficient asset - let minimum_asset_balance = 3333333_u128; - let local_asset_id = 1; - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - local_asset_id.into(), - AccountId::from(ALICE).into(), - true, - minimum_asset_balance - )); + let bob: AccountId = SOME_ASSET_ADMIN.into(); + let staking_pot = CollatorSelection::account_id(); + let native_location = WestendLocation::get(); + let initial_balance = 200 * UNITS; - // We first mint enough asset for the account to exist for assets - assert_ok!(Assets::mint( - RuntimeHelper::origin_of(AccountId::from(ALICE)), - local_asset_id.into(), - AccountId::from(ALICE).into(), - minimum_asset_balance - )); - - // get asset id as multilocation - let asset_multilocation = - AssetIdForTrustBackedAssetsConvert::convert_back(&local_asset_id).unwrap(); - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy 4e9 weight - let bought = Weight::from_parts(4_000_000_000u64, 0); - - // Lets calculate amount needed - let asset_amount_needed = - AssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles( - local_asset_id, - bought, - ) - .expect("failed to compute"); + assert_ok!(Balances::mint_into(&bob, initial_balance)); + assert_ok!(Balances::mint_into(&staking_pot, initial_balance)); - // Lets pay with: asset_amount_needed + asset_amount_extra - let asset_amount_extra = 100_u128; - let asset: MultiAsset = - (asset_multilocation, asset_amount_needed + asset_amount_extra).into(); + // keep initial total issuance to assert later. + let total_issuance = Balances::total_issuance(); - let mut trader = ::Trader::new(); + // prepare input to buy weight. + let weight = Weight::from_parts(4_000_000_000, 0); + let fee = WeightToFee::weight_to_fee(&weight); + let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + let payment: MultiAsset = (native_location, fee + extra_amount).into(); - // Lets buy_weight and make sure buy_weight does not return an error - let unused_assets = trader.buy_weight(bought, asset.into(), &ctx).expect("Expected Ok"); - // Check whether a correct amount of unused assets is returned - assert_ok!( - unused_assets.ensure_contains(&(asset_multilocation, asset_amount_extra).into()) - ); - - // Drop trader + // init trader and buy weight. + let mut trader = ::Trader::new(); + let unused_asset = + trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); + + // assert. + let unused_amount = + unused_asset.fungible.get(&native_location.into()).map_or(0, |a| *a); + assert_eq!(unused_amount, extra_amount); + assert_eq!(Balances::total_issuance(), total_issuance); + + // prepare input to refund weight. + let refund_weight = Weight::from_parts(1_000_000_000, 0); + let refund = WeightToFee::weight_to_fee(&refund_weight); + + // refund. + let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); + assert_eq!(actual_refund, (native_location, refund).into()); + + // assert. + assert_eq!(Balances::balance(&staking_pot), initial_balance); + // only after `trader` is dropped we expect the fee to be resolved into the treasury + // account. drop(trader); - - // Make sure author(Alice) has received the amount - assert_eq!( - Assets::balance(local_asset_id, AccountId::from(ALICE)), - minimum_asset_balance + asset_amount_needed - ); - - // We also need to ensure the total supply increased - assert_eq!( - Assets::total_supply(local_asset_id), - minimum_asset_balance + asset_amount_needed - ); - }); + assert_eq!(Balances::balance(&staking_pot), initial_balance + fee - refund); + assert_eq!(Balances::total_issuance(), total_issuance + fee - refund); + }) } #[test] -fn test_asset_xcm_trader_with_refund() { +fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { ExtBuilder::::default() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( @@ -157,76 +143,93 @@ fn test_asset_xcm_trader_with_refund() { )]) .build() .execute_with(|| { - // We need root origin to create a sufficient asset - // We set existential deposit to be identical to the one for Balances first - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - true, - ExistentialDeposit::get() + let bob: AccountId = SOME_ASSET_ADMIN.into(); + let staking_pot = CollatorSelection::account_id(); + let asset_1: u32 = 1; + let native_location = WestendLocation::get(); + let asset_1_location = + AssetIdForTrustBackedAssetsConvert::convert_back(&asset_1).unwrap(); + // bob's initial balance for native and `asset1` assets. + let initial_balance = 200 * UNITS; + // liquidity for both arms of (native, asset1) pool. + let pool_liquidity = 100 * UNITS; + + // init asset, balances and pool. + assert_ok!(>::create(asset_1, bob.clone(), true, 10)); + + assert_ok!(Assets::mint_into(asset_1, &bob, initial_balance)); + assert_ok!(Balances::mint_into(&bob, initial_balance)); + assert_ok!(Balances::mint_into(&staking_pot, initial_balance)); + + assert_ok!(AssetConversion::create_pool( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(asset_1_location) )); - // We first mint enough asset for the account to exist for assets - assert_ok!(Assets::mint( - RuntimeHelper::origin_of(AccountId::from(ALICE)), - 1.into(), - AccountId::from(ALICE).into(), - ExistentialDeposit::get() + assert_ok!(AssetConversion::add_liquidity( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(asset_1_location), + pool_liquidity, + pool_liquidity, + 1, + 1, + bob, )); - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy 4e9 weight - let bought = Weight::from_parts(4_000_000_000u64, 0); - let asset_multilocation = AssetIdForTrustBackedAssetsConvert::convert_back(&1).unwrap(); - - // lets calculate amount needed - let amount_bought = WeightToFee::weight_to_fee(&bought); - - let asset: MultiAsset = (asset_multilocation, amount_bought).into(); + // keep initial total issuance to assert later. + let asset_total_issuance = Assets::total_issuance(asset_1); + let native_total_issuance = Balances::total_issuance(); - // Make sure buy_weight does not return an error - assert_ok!(trader.buy_weight(bought, asset.clone().into(), &ctx)); - - // Make sure again buy_weight does return an error - // This assert relies on the fact, that we use `TakeFirstAssetTrader` in `WeightTrader` - // tuple chain, which cannot be called twice - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // We actually use half of the weight - let weight_used = bought / 2; - - // Make sure refurnd works. - let amount_refunded = WeightToFee::weight_to_fee(&(bought - weight_used)); - - assert_eq!( - trader.refund_weight(bought - weight_used, &ctx), - Some((asset_multilocation, amount_refunded).into()) - ); + // prepare input to buy weight. + let weight = Weight::from_parts(4_000_000_000, 0); + let fee = WeightToFee::weight_to_fee(&weight); + let asset_fee = + AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); + let extra_amount = 100; + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + let payment: MultiAsset = (asset_1_location, asset_fee + extra_amount).into(); - // Drop trader + // init trader and buy weight. + let mut trader = ::Trader::new(); + let unused_asset = + trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); + + // assert. + let unused_amount = + unused_asset.fungible.get(&asset_1_location.into()).map_or(0, |a| *a); + assert_eq!(unused_amount, extra_amount); + assert_eq!(Assets::total_issuance(asset_1), asset_total_issuance + asset_fee); + + // prepare input to refund weight. + let refund_weight = Weight::from_parts(1_000_000_000, 0); + let refund = WeightToFee::weight_to_fee(&refund_weight); + let (reserve1, reserve2) = + AssetConversion::get_reserves(native_location, asset_1_location).unwrap(); + let asset_refund = + AssetConversion::get_amount_out(&refund, &reserve1, &reserve2).unwrap(); + + // refund. + let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); + assert_eq!(actual_refund, (asset_1_location, asset_refund).into()); + + // assert. + assert_eq!(Balances::balance(&staking_pot), initial_balance); + // only after `trader` is dropped we expect the fee to be resolved into the treasury + // account. drop(trader); - - // We only should have paid for half of the bought weight - let fees_paid = WeightToFee::weight_to_fee(&weight_used); - + assert_eq!(Balances::balance(&staking_pot), initial_balance + fee - refund); assert_eq!( - Assets::balance(1, AccountId::from(ALICE)), - ExistentialDeposit::get() + fees_paid + Assets::total_issuance(asset_1), + asset_total_issuance + asset_fee - asset_refund ); - - // We also need to ensure the total supply increased - assert_eq!(Assets::total_supply(1), ExistentialDeposit::get() + fees_paid); - }); + assert_eq!(Balances::total_issuance(), native_total_issuance); + }) } #[test] -fn test_asset_xcm_trader_refund_not_possible_since_amount_less_than_ed() { +fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { ExtBuilder::::default() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( @@ -236,168 +239,96 @@ fn test_asset_xcm_trader_refund_not_possible_since_amount_less_than_ed() { )]) .build() .execute_with(|| { - // We need root origin to create a sufficient asset - // We set existential deposit to be identical to the one for Balances first - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), + let bob: AccountId = SOME_ASSET_ADMIN.into(); + let staking_pot = CollatorSelection::account_id(); + let native_location = WestendLocation::get(); + let foreign_location = + MultiLocation { parents: 1, interior: X2(Parachain(1234), GeneralIndex(12345)) }; + // bob's initial balance for native and `asset1` assets. + let initial_balance = 200 * UNITS; + // liquidity for both arms of (native, asset1) pool. + let pool_liquidity = 100 * UNITS; + + // init asset, balances and pool. + assert_ok!(>::create( + foreign_location, + bob.clone(), true, - ExistentialDeposit::get() + 10 )); - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy small amount - let bought = Weight::from_parts(500_000_000u64, 0); - - let asset_multilocation = AssetIdForTrustBackedAssetsConvert::convert_back(&1).unwrap(); - - let amount_bought = WeightToFee::weight_to_fee(&bought); + assert_ok!(ForeignAssets::mint_into(foreign_location, &bob, initial_balance)); + assert_ok!(Balances::mint_into(&bob, initial_balance)); + assert_ok!(Balances::mint_into(&staking_pot, initial_balance)); - assert!( - amount_bought < ExistentialDeposit::get(), - "we are testing what happens when the amount does not exceed ED" - ); - - let asset: MultiAsset = (asset_multilocation, amount_bought).into(); - - // Buy weight should return an error - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // not credited since the ED is higher than this value - assert_eq!(Assets::balance(1, AccountId::from(ALICE)), 0); - - // We also need to ensure the total supply did not increase - assert_eq!(Assets::total_supply(1), 0); - }); -} - -#[test] -fn test_that_buying_ed_refund_does_not_refund() { - ExtBuilder::::default() - .with_collators(vec![AccountId::from(ALICE)]) - .with_session_keys(vec![( - AccountId::from(ALICE), - AccountId::from(ALICE), - SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, - )]) - .build() - .execute_with(|| { - // We need root origin to create a sufficient asset - // We set existential deposit to be identical to the one for Balances first - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - true, - ExistentialDeposit::get() + assert_ok!(AssetConversion::create_pool( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(foreign_location) )); - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - let bought = Weight::from_parts(500_000_000u64, 0); - - let asset_multilocation = AssetIdForTrustBackedAssetsConvert::convert_back(&1).unwrap(); - - let amount_bought = WeightToFee::weight_to_fee(&bought); - - assert!( - amount_bought < ExistentialDeposit::get(), - "we are testing what happens when the amount does not exceed ED" - ); - - // We know we will have to buy at least ED, so lets make sure first it will - // fail with a payment of less than ED - let asset: MultiAsset = (asset_multilocation, amount_bought).into(); - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // Now lets buy ED at least - let asset: MultiAsset = (asset_multilocation, ExistentialDeposit::get()).into(); - - // Buy weight should work - assert_ok!(trader.buy_weight(bought, asset.into(), &ctx)); - - // Should return None. We have a specific check making sure we dont go below ED for - // drop payment - assert_eq!(trader.refund_weight(bought, &ctx), None); - - // Drop trader - drop(trader); - - // Make sure author(Alice) has received the amount - assert_eq!(Assets::balance(1, AccountId::from(ALICE)), ExistentialDeposit::get()); - - // We also need to ensure the total supply increased - assert_eq!(Assets::total_supply(1), ExistentialDeposit::get()); - }); -} - -#[test] -fn test_asset_xcm_trader_not_possible_for_non_sufficient_assets() { - ExtBuilder::::default() - .with_collators(vec![AccountId::from(ALICE)]) - .with_session_keys(vec![( - AccountId::from(ALICE), - AccountId::from(ALICE), - SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, - )]) - .build() - .execute_with(|| { - // Create a non-sufficient asset with specific existential deposit - let minimum_asset_balance = 1_000_000_u128; - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - false, - minimum_asset_balance + assert_ok!(AssetConversion::add_liquidity( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(foreign_location), + pool_liquidity, + pool_liquidity, + 1, + 1, + bob, )); - // We first mint enough asset for the account to exist for assets - assert_ok!(Assets::mint( - RuntimeHelper::origin_of(AccountId::from(ALICE)), - 1.into(), - AccountId::from(ALICE).into(), - minimum_asset_balance - )); + // keep initial total issuance to assert later. + let asset_total_issuance = ForeignAssets::total_issuance(foreign_location); + let native_total_issuance = Balances::total_issuance(); - let mut trader = ::Trader::new(); + // prepare input to buy weight. + let weight = Weight::from_parts(4_000_000_000, 0); + let fee = WeightToFee::weight_to_fee(&weight); + let asset_fee = + AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); + let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + let payment: MultiAsset = (foreign_location, asset_fee + extra_amount).into(); - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy 4e9 weight - let bought = Weight::from_parts(4_000_000_000u64, 0); - - // lets calculate amount needed - let asset_amount_needed = WeightToFee::weight_to_fee(&bought); - - let asset_multilocation = AssetIdForTrustBackedAssetsConvert::convert_back(&1).unwrap(); - - let asset: MultiAsset = (asset_multilocation, asset_amount_needed).into(); + // init trader and buy weight. + let mut trader = ::Trader::new(); + let unused_asset = + trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); - // Make sure again buy_weight does return an error - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + // assert. + let unused_amount = + unused_asset.fungible.get(&foreign_location.into()).map_or(0, |a| *a); + assert_eq!(unused_amount, extra_amount); + assert_eq!( + ForeignAssets::total_issuance(foreign_location), + asset_total_issuance + asset_fee + ); - // Drop trader + // prepare input to refund weight. + let refund_weight = Weight::from_parts(1_000_000_000, 0); + let refund = WeightToFee::weight_to_fee(&refund_weight); + let (reserve1, reserve2) = + AssetConversion::get_reserves(native_location, foreign_location).unwrap(); + let asset_refund = + AssetConversion::get_amount_out(&refund, &reserve1, &reserve2).unwrap(); + + // refund. + let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); + assert_eq!(actual_refund, (foreign_location, asset_refund).into()); + + // assert. + assert_eq!(Balances::balance(&staking_pot), initial_balance); + // only after `trader` is dropped we expect the fee to be resolved into the treasury + // account. drop(trader); - - // Make sure author(Alice) has NOT received the amount - assert_eq!(Assets::balance(1, AccountId::from(ALICE)), minimum_asset_balance); - - // We also need to ensure the total supply NOT increased - assert_eq!(Assets::total_supply(1), minimum_asset_balance); - }); + assert_eq!(Balances::balance(&staking_pot), initial_balance + fee - refund); + assert_eq!( + ForeignAssets::total_issuance(foreign_location), + asset_total_issuance + asset_fee - asset_refund + ); + assert_eq!(Balances::total_issuance(), native_total_issuance); + }) } #[test] diff --git a/cumulus/parachains/runtimes/assets/common/src/lib.rs b/cumulus/parachains/runtimes/assets/common/src/lib.rs index 15327f51b2a..b0e47143929 100644 --- a/cumulus/parachains/runtimes/assets/common/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/common/src/lib.rs @@ -47,6 +47,16 @@ pub type TrustBackedAssetsConvertedConcreteId = + MatchedConvertedConcreteId< + MultiLocationForAssetId, + Balance, + StartsWith, + Identity, + JustTry, + >; + /// [`MatchedConvertedConcreteId`] converter dedicated for storing `AssetId` as `MultiLocation`. pub type MultiLocationConvertedConcreteId = MatchedConvertedConcreteId< diff --git a/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml b/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml index a3ed3759600..1b863499f04 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml @@ -16,6 +16,7 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = frame-support = { path = "../../../../../substrate/frame/support", default-features = false } frame-system = { path = "../../../../../substrate/frame/system", default-features = false } pallet-assets = { path = "../../../../../substrate/frame/assets", default-features = false } +pallet-asset-conversion = { path = "../../../../../substrate/frame/asset-conversion", default-features = false } pallet-balances = { path = "../../../../../substrate/frame/balances", default-features = false } pallet-session = { path = "../../../../../substrate/frame/session", default-features = false } sp-consensus-aura = { path = "../../../../../substrate/primitives/consensus/aura", default-features = false } @@ -64,6 +65,7 @@ std = [ "cumulus-test-relay-sproof-builder/std", "frame-support/std", "frame-system/std", + "pallet-asset-conversion/std", "pallet-assets/std", "pallet-balances/std", "pallet-collator-selection/std", diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs index 8007b275cb5..d7441880426 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs @@ -30,6 +30,7 @@ use parachains_runtimes_test_utils::{ ValidatorIdOf, XcmReceivedFrom, }; use sp_runtime::{traits::StaticLookup, Saturating}; +use sp_std::ops::Mul; use xcm::{latest::prelude::*, VersionedMultiAssets}; use xcm_builder::{CreateMatcher, MatchXcm}; use xcm_executor::{traits::ConvertLocation, XcmExecutor}; @@ -336,12 +337,13 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< + pallet_collator_selection::Config + cumulus_pallet_parachain_system::Config + cumulus_pallet_xcmp_queue::Config - + pallet_assets::Config, + + pallet_assets::Config + + pallet_asset_conversion::Config, AllPalletsWithoutSystem: OnInitialize> + OnFinalize>, - AccountIdOf: Into<[u8; 32]>, + AccountIdOf: Into<[u8; 32]> + From<[u8; 32]>, ValidatorIdOf: From>, - BalanceOf: From, + BalanceOf: From + Into, XcmConfig: xcm_executor::Config, LocationToAccountId: ConvertLocation>, >::AssetId: @@ -354,6 +356,9 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< + Into, <::Lookup as StaticLookup>::Source: From<::AccountId>, + ::AssetKind: + From + Into, + ::Balance: From, ForeignAssetsPalletInstance: 'static, { ExtBuilder::::default() @@ -400,6 +405,43 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< ) ); + // setup a pool to pay fees with `foreign_asset_id_multilocation` tokens + let pool_owner: AccountIdOf = [1u8; 32].into(); + let native_asset = MultiLocation::parent(); + let pool_liquidity: u128 = + existential_deposit.into().max(foreign_asset_id_minimum_balance).mul(100_000); + + let _ = >::deposit_creating( + &pool_owner, + (existential_deposit.into() + pool_liquidity).mul(2).into(), + ); + + assert_ok!(>::mint( + RuntimeHelper::::origin_of( + sovereign_account_as_owner_of_foreign_asset + ), + foreign_asset_id_multilocation.into(), + pool_owner.clone().into(), + (foreign_asset_id_minimum_balance + pool_liquidity).mul(2).into(), + )); + + assert_ok!(>::create_pool( + RuntimeHelper::::origin_of(pool_owner.clone()), + Box::new(native_asset.into()), + Box::new(foreign_asset_id_multilocation.into()) + )); + + assert_ok!(>::add_liquidity( + RuntimeHelper::::origin_of(pool_owner.clone()), + Box::new(native_asset.into()), + Box::new(foreign_asset_id_multilocation.into()), + pool_liquidity.into(), + pool_liquidity.into(), + 1.into(), + 1.into(), + pool_owner, + )); + // Balances before assert_eq!( >::free_balance(&target_account), @@ -485,14 +527,12 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< ); assert_ok!(outcome.ensure_complete()); - // author actual balance after (received fees from Trader for ForeignAssets) - let author_received_fees = - >::balance( - foreign_asset_id_multilocation.into(), - &block_author_account, - ); - - // Balances after (untouched) + // Balances after + // staking pot receives xcm fees in dot + assert!( + >::free_balance(&staking_pot) != + existential_deposit + ); assert_eq!( >::free_balance(&target_account), existential_deposit.clone() @@ -501,30 +541,25 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< >::free_balance(&block_author_account), 0.into() ); - assert_eq!( - >::free_balance(&staking_pot), - existential_deposit.clone() - ); // ForeignAssets balances after - assert_eq!( + assert!( >::balance( foreign_asset_id_multilocation.into(), &target_account - ), - (transfered_foreign_asset_id_amount - author_received_fees.into()).into() + ) > 0.into() ); assert_eq!( >::balance( foreign_asset_id_multilocation.into(), - &block_author_account + &staking_pot ), - author_received_fees + 0.into() ); assert_eq!( >::balance( foreign_asset_id_multilocation.into(), - &staking_pot + &block_author_account ), 0.into() ); diff --git a/cumulus/primitives/utility/Cargo.toml b/cumulus/primitives/utility/Cargo.toml index 56b6b928417..1558295b936 100644 --- a/cumulus/primitives/utility/Cargo.toml +++ b/cumulus/primitives/utility/Cargo.toml @@ -18,6 +18,7 @@ frame-support = { path = "../../../substrate/frame/support", default-features = sp-io = { path = "../../../substrate/primitives/io", default-features = false } sp-runtime = { path = "../../../substrate/primitives/runtime", default-features = false } sp-std = { path = "../../../substrate/primitives/std", default-features = false } +pallet-asset-conversion = { path = "../../../substrate/frame/asset-conversion", default-features = false } # Polkadot polkadot-runtime-common = { path = "../../../polkadot/runtime/common", default-features = false } @@ -37,6 +38,7 @@ std = [ "cumulus-primitives-core/std", "frame-support/std", "log/std", + "pallet-asset-conversion/std", "pallet-xcm-benchmarks/std", "polkadot-runtime-common/std", "polkadot-runtime-parachains/std", @@ -51,6 +53,7 @@ std = [ runtime-benchmarks = [ "cumulus-primitives-core/runtime-benchmarks", "frame-support/runtime-benchmarks", + "pallet-asset-conversion/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", "polkadot-runtime-parachains/runtime-benchmarks", diff --git a/cumulus/primitives/utility/src/lib.rs b/cumulus/primitives/utility/src/lib.rs index 03f827d7ee2..7216000cb45 100644 --- a/cumulus/primitives/utility/src/lib.rs +++ b/cumulus/primitives/utility/src/lib.rs @@ -22,19 +22,24 @@ use codec::Encode; use cumulus_primitives_core::{MessageSendError, UpwardMessageSender}; use frame_support::{ - traits::{ - tokens::{fungibles, fungibles::Inspect}, - Get, - }, - weights::Weight, + defensive, + traits::{tokens::fungibles, Get, OnUnbalanced as OnUnbalancedT}, + weights::{Weight, WeightToFee as WeightToFeeT}, }; +use pallet_asset_conversion::SwapCredit as SwapCreditT; use polkadot_runtime_common::xcm_sender::PriceForMessageDelivery; -use sp_runtime::{traits::Saturating, SaturatedConversion}; +use sp_runtime::{ + traits::{Saturating, Zero}, + SaturatedConversion, +}; use sp_std::{marker::PhantomData, prelude::*}; use xcm::{latest::prelude::*, WrapVersion}; use xcm_builder::TakeRevenue; use xcm_executor::traits::{MatchesFungibles, TransactAsset, WeightTrader}; +#[cfg(test)] +mod tests; + /// Xcm router which recognises the `Parent` destination and handles it by sending the message into /// the given UMP `UpwardMessageSender` implementation. Thus this essentially adapts an /// `UpwardMessageSender` trait impl into a `SendXcm` trait impl. @@ -286,23 +291,238 @@ impl< /// in such assetId for that amount of weight pub trait ChargeWeightInFungibles> { fn charge_weight_in_fungibles( - asset_id: >::AssetId, + asset_id: >::AssetId, weight: Weight, - ) -> Result<>::Balance, XcmError>; + ) -> Result<>::Balance, XcmError>; +} + +/// Provides an implementation of [`WeightTrader`] to charge for weight using the first asset +/// specified in the `payment` argument. +/// +/// The asset used to pay for the weight must differ from the `Target` asset and be exchangeable for +/// the same `Target` asset through `SwapCredit`. +/// +/// ### Parameters: +/// - `Target`: the asset into which the user's payment will be exchanged using `SwapCredit`. +/// - `SwapCredit`: mechanism used for the exchange of the user's payment asset into the `Target`. +/// - `WeightToFee`: weight to the `Target` asset fee calculator. +/// - `Fungibles`: registry of fungible assets. +/// - `FungiblesAssetMatcher`: utility for mapping [`MultiAsset`] to `Fungibles::AssetId` and +/// `Fungibles::Balance`. +/// - `OnUnbalanced`: handler for the fee payment. +/// - `AccountId`: the account identifier type. +pub struct SwapFirstAssetTrader< + Target: Get, + SwapCredit: SwapCreditT< + AccountId, + Balance = Fungibles::Balance, + AssetKind = Fungibles::AssetId, + Credit = fungibles::Credit, + >, + WeightToFee: WeightToFeeT, + Fungibles: fungibles::Balanced, + FungiblesAssetMatcher: MatchesFungibles, + OnUnbalanced: OnUnbalancedT>, + AccountId, +> where + Fungibles::Balance: Into, +{ + /// Accumulated fee paid for XCM execution. + total_fee: fungibles::Credit, + /// Last asset utilized by a client to settle a fee. + last_fee_asset: Option, + _phantom_data: PhantomData<( + Target, + SwapCredit, + WeightToFee, + Fungibles, + FungiblesAssetMatcher, + OnUnbalanced, + AccountId, + )>, +} + +impl< + Target: Get, + SwapCredit: SwapCreditT< + AccountId, + Balance = Fungibles::Balance, + AssetKind = Fungibles::AssetId, + Credit = fungibles::Credit, + >, + WeightToFee: WeightToFeeT, + Fungibles: fungibles::Balanced, + FungiblesAssetMatcher: MatchesFungibles, + OnUnbalanced: OnUnbalancedT>, + AccountId, + > WeightTrader + for SwapFirstAssetTrader< + Target, + SwapCredit, + WeightToFee, + Fungibles, + FungiblesAssetMatcher, + OnUnbalanced, + AccountId, + > where + Fungibles::Balance: Into, +{ + fn new() -> Self { + Self { + total_fee: fungibles::Credit::::zero(Target::get()), + last_fee_asset: None, + _phantom_data: PhantomData, + } + } + + fn buy_weight( + &mut self, + weight: Weight, + mut payment: xcm_executor::Assets, + _context: &XcmContext, + ) -> Result { + log::trace!( + target: "xcm::weight", + "SwapFirstAssetTrader::buy_weight weight: {:?}, payment: {:?}", + weight, + payment, + ); + let first_asset: MultiAsset = + payment.fungible.pop_first().ok_or(XcmError::AssetNotFound)?.into(); + let (fungibles_asset, balance) = FungiblesAssetMatcher::matches_fungibles(&first_asset) + .map_err(|_| XcmError::AssetNotFound)?; + + let swap_asset = fungibles_asset.clone().into(); + if Target::get().eq(&swap_asset) { + // current trader is not applicable. + return Err(XcmError::FeesNotMet) + } + + let credit_in = Fungibles::issue(fungibles_asset, balance); + let fee = WeightToFee::weight_to_fee(&weight); + + // swap the user's asset for the `Target` asset. + let (credit_out, credit_change) = SwapCredit::swap_tokens_for_exact_tokens( + vec![swap_asset, Target::get()], + credit_in, + fee, + ) + .map_err(|(credit_in, _)| { + drop(credit_in); + XcmError::FeesNotMet + })?; + + match self.total_fee.subsume(credit_out) { + Err(credit_out) => { + // error may occur if `total_fee.asset` differs from `credit_out.asset`, which does + // not apply in this context. + defensive!( + "`total_fee.asset` must be equal to `credit_out.asset`", + (self.total_fee.asset(), credit_out.asset()) + ); + return Err(XcmError::FeesNotMet) + }, + _ => (), + }; + self.last_fee_asset = Some(first_asset.id); + + payment.fungible.insert(first_asset.id, credit_change.peek().into()); + drop(credit_change); + Ok(payment) + } + + fn refund_weight(&mut self, weight: Weight, _context: &XcmContext) -> Option { + log::trace!( + target: "xcm::weight", + "SwapFirstAssetTrader::refund_weight weight: {:?}, self.total_fee: {:?}", + weight, + self.total_fee, + ); + if self.total_fee.peek().is_zero() { + // noting yet paid to refund. + return None + } + let mut refund_asset = if let Some(asset) = &self.last_fee_asset { + // create an initial zero refund in the asset used in the last `buy_weight`. + (*asset, Fungible(0)).into() + } else { + return None + }; + let refund_amount = WeightToFee::weight_to_fee(&weight); + if refund_amount >= self.total_fee.peek() { + // not enough was paid to refund the `weight`. + return None + } + + let refund_swap_asset = FungiblesAssetMatcher::matches_fungibles(&refund_asset) + .map(|(a, _)| a.into()) + .ok()?; + + let refund = self.total_fee.extract(refund_amount); + let refund = match SwapCredit::swap_exact_tokens_for_tokens( + vec![Target::get(), refund_swap_asset], + refund, + None, + ) { + Ok(refund_in_target) => refund_in_target, + Err((refund, _)) => { + // return an attempted refund back to the `total_fee`. + let _ = self.total_fee.subsume(refund).map_err(|refund| { + // error may occur if `total_fee.asset` differs from `refund.asset`, which does + // not apply in this context. + defensive!( + "`total_fee.asset` must be equal to `refund.asset`", + (self.total_fee.asset(), refund.asset()) + ); + }); + return None + }, + }; + + refund_asset.fun = refund.peek().into().into(); + drop(refund); + Some(refund_asset) + } +} + +impl< + Target: Get, + SwapCredit: SwapCreditT< + AccountId, + Balance = Fungibles::Balance, + AssetKind = Fungibles::AssetId, + Credit = fungibles::Credit, + >, + WeightToFee: WeightToFeeT, + Fungibles: fungibles::Balanced, + FungiblesAssetMatcher: MatchesFungibles, + OnUnbalanced: OnUnbalancedT>, + AccountId, + > Drop + for SwapFirstAssetTrader< + Target, + SwapCredit, + WeightToFee, + Fungibles, + FungiblesAssetMatcher, + OnUnbalanced, + AccountId, + > where + Fungibles::Balance: Into, +{ + fn drop(&mut self) { + if self.total_fee.peek().is_zero() { + return + } + let total_fee = self.total_fee.extract(self.total_fee.peek()); + OnUnbalanced::on_unbalanced(total_fee); + } } #[cfg(test)] -mod tests { +mod test_xcm_router { use super::*; use cumulus_primitives_core::UpwardMessage; - use frame_support::{ - assert_ok, - traits::tokens::{ - DepositConsequence, Fortitude, Preservation, Provenance, WithdrawConsequence, - }, - }; - use sp_runtime::DispatchError; - use xcm_executor::{traits::Error, Assets}; /// Validates [`validate`] for required Some(destination) and Some(message) struct OkFixedXcmHashWithAssertingRequiredInputsSender; @@ -398,6 +618,18 @@ mod tests { )>(dest.into(), message) ); } +} +#[cfg(test)] +mod test_trader { + use super::*; + use frame_support::{ + assert_ok, + traits::tokens::{ + DepositConsequence, Fortitude, Preservation, Provenance, WithdrawConsequence, + }, + }; + use sp_runtime::DispatchError; + use xcm_executor::{traits::Error, Assets}; #[test] fn take_first_asset_trader_buy_weight_called_twice_throws_error() { @@ -491,9 +723,9 @@ mod tests { struct FeeChargerAssetsHandleRefund; impl ChargeWeightInFungibles for FeeChargerAssetsHandleRefund { fn charge_weight_in_fungibles( - _: >::AssetId, + _: >::AssetId, _: Weight, - ) -> Result<>::Balance, XcmError> { + ) -> Result<>::Balance, XcmError> { Ok(AMOUNT) } } diff --git a/cumulus/primitives/utility/src/tests/mod.rs b/cumulus/primitives/utility/src/tests/mod.rs new file mode 100644 index 00000000000..e0ad8718b89 --- /dev/null +++ b/cumulus/primitives/utility/src/tests/mod.rs @@ -0,0 +1,17 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +mod swap_first; diff --git a/cumulus/primitives/utility/src/tests/swap_first.rs b/cumulus/primitives/utility/src/tests/swap_first.rs new file mode 100644 index 00000000000..222cd005b12 --- /dev/null +++ b/cumulus/primitives/utility/src/tests/swap_first.rs @@ -0,0 +1,551 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +use crate::*; +use frame_support::{parameter_types, traits::fungibles::Inspect}; +use mock::{setup_pool, AccountId, AssetId, Balance, Fungibles}; +use xcm::latest::AssetId as XcmAssetId; +use xcm_executor::Assets as HoldingAsset; + +fn create_holding_asset(asset_id: AssetId, amount: Balance) -> HoldingAsset { + create_asset(asset_id, amount).into() +} + +fn create_asset(asset_id: AssetId, amount: Balance) -> MultiAsset { + MultiAsset { id: create_asset_id(asset_id), fun: Fungible(amount) } +} + +fn create_asset_id(asset_id: AssetId) -> XcmAssetId { + Concrete(MultiLocation::new(0, X1(GeneralIndex(asset_id.into())))) +} + +fn xcm_context() -> XcmContext { + XcmContext { origin: None, message_id: [0u8; 32], topic: None } +} + +fn weight_worth_of(fee: Balance) -> Weight { + Weight::from_parts(fee.try_into().unwrap(), 0) +} + +const TARGET_ASSET: AssetId = 1; +const CLIENT_ASSET: AssetId = 2; +const CLIENT_ASSET_2: AssetId = 3; + +parameter_types! { + pub const TargetAsset: AssetId = TARGET_ASSET; +} + +pub type Trader = SwapFirstAssetTrader< + TargetAsset, + mock::Swap, + mock::WeightToFee, + mock::Fungibles, + mock::FungiblesMatcher, + (), + AccountId, +>; + +#[test] +fn holding_asset_swap_for_target() { + let client_asset_total = 15; + let fee = 5; + + setup_pool(CLIENT_ASSET, 1000, TARGET_ASSET, 1000); + + let holding_asset = create_holding_asset(CLIENT_ASSET, client_asset_total); + let holding_change = create_holding_asset(CLIENT_ASSET, client_asset_total - fee); + + let target_total = Fungibles::total_issuance(TARGET_ASSET); + let client_total = Fungibles::total_issuance(CLIENT_ASSET); + + let mut trader = Trader::new(); + assert_eq!( + trader.buy_weight(weight_worth_of(fee), holding_asset, &xcm_context()).unwrap(), + holding_change + ); + + assert_eq!(trader.total_fee.peek(), fee); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET))); + + assert_eq!(Fungibles::total_issuance(TARGET_ASSET), target_total); + assert_eq!(Fungibles::total_issuance(CLIENT_ASSET), client_total + fee); +} + +#[test] +fn holding_asset_swap_for_target_twice() { + let client_asset_total = 20; + let fee1 = 5; + let fee2 = 6; + + setup_pool(CLIENT_ASSET, 1000, TARGET_ASSET, 1000); + + let holding_asset = create_holding_asset(CLIENT_ASSET, client_asset_total); + let holding_change1 = create_holding_asset(CLIENT_ASSET, client_asset_total - fee1); + let holding_change2 = create_holding_asset(CLIENT_ASSET, client_asset_total - fee1 - fee2); + + let target_total = Fungibles::total_issuance(TARGET_ASSET); + let client_total = Fungibles::total_issuance(CLIENT_ASSET); + + let mut trader = Trader::new(); + assert_eq!( + trader.buy_weight(weight_worth_of(fee1), holding_asset, &xcm_context()).unwrap(), + holding_change1 + ); + assert_eq!( + trader + .buy_weight(weight_worth_of(fee2), holding_change1, &xcm_context()) + .unwrap(), + holding_change2 + ); + + assert_eq!(trader.total_fee.peek(), fee1 + fee2); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET))); + + assert_eq!(Fungibles::total_issuance(TARGET_ASSET), target_total); + assert_eq!(Fungibles::total_issuance(CLIENT_ASSET), client_total + fee1 + fee2); +} + +#[test] +fn buy_and_refund_twice_for_target() { + let client_asset_total = 15; + let fee = 5; + let refund1 = 4; + let refund2 = 2; + + setup_pool(CLIENT_ASSET, 1000, TARGET_ASSET, 1000); + // create pool for refund swap. + setup_pool(TARGET_ASSET, 1000, CLIENT_ASSET, 1000); + + let holding_asset = create_holding_asset(CLIENT_ASSET, client_asset_total); + let holding_change = create_holding_asset(CLIENT_ASSET, client_asset_total - fee); + let refund_asset = create_asset(CLIENT_ASSET, refund1); + + let target_total = Fungibles::total_issuance(TARGET_ASSET); + let client_total = Fungibles::total_issuance(CLIENT_ASSET); + + let mut trader = Trader::new(); + assert_eq!( + trader.buy_weight(weight_worth_of(fee), holding_asset, &xcm_context()).unwrap(), + holding_change + ); + + assert_eq!(trader.total_fee.peek(), fee); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET))); + + assert_eq!(trader.refund_weight(weight_worth_of(refund1), &xcm_context()), Some(refund_asset)); + + assert_eq!(trader.total_fee.peek(), fee - refund1); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET))); + + assert_eq!(trader.refund_weight(weight_worth_of(refund2), &xcm_context()), None); + + assert_eq!(trader.total_fee.peek(), fee - refund1); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET))); + + assert_eq!(Fungibles::total_issuance(TARGET_ASSET), target_total); + assert_eq!(Fungibles::total_issuance(CLIENT_ASSET), client_total + fee - refund1); +} + +#[test] +fn buy_with_various_assets_and_refund_for_target() { + let client_asset_total = 10; + let client_asset_2_total = 15; + let fee1 = 5; + let fee2 = 6; + let refund1 = 6; + let refund2 = 4; + + setup_pool(CLIENT_ASSET, 1000, TARGET_ASSET, 1000); + setup_pool(CLIENT_ASSET_2, 1000, TARGET_ASSET, 1000); + // create pool for refund swap. + setup_pool(TARGET_ASSET, 1000, CLIENT_ASSET_2, 1000); + + let holding_asset = create_holding_asset(CLIENT_ASSET, client_asset_total); + let holding_asset_2 = create_holding_asset(CLIENT_ASSET_2, client_asset_2_total); + let holding_change = create_holding_asset(CLIENT_ASSET, client_asset_total - fee1); + let holding_change_2 = create_holding_asset(CLIENT_ASSET_2, client_asset_2_total - fee2); + // both refunds in the latest buy asset (`CLIENT_ASSET_2`). + let refund_asset = create_asset(CLIENT_ASSET_2, refund1); + let refund_asset_2 = create_asset(CLIENT_ASSET_2, refund2); + + let target_total = Fungibles::total_issuance(TARGET_ASSET); + let client_total = Fungibles::total_issuance(CLIENT_ASSET); + let client_total_2 = Fungibles::total_issuance(CLIENT_ASSET_2); + + let mut trader = Trader::new(); + // first purchase with `CLIENT_ASSET`. + assert_eq!( + trader.buy_weight(weight_worth_of(fee1), holding_asset, &xcm_context()).unwrap(), + holding_change + ); + + assert_eq!(trader.total_fee.peek(), fee1); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET))); + + // second purchase with `CLIENT_ASSET_2`. + assert_eq!( + trader + .buy_weight(weight_worth_of(fee2), holding_asset_2, &xcm_context()) + .unwrap(), + holding_change_2 + ); + + assert_eq!(trader.total_fee.peek(), fee1 + fee2); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET_2))); + + // first refund in the last asset used with `buy_weight`. + assert_eq!(trader.refund_weight(weight_worth_of(refund1), &xcm_context()), Some(refund_asset)); + + assert_eq!(trader.total_fee.peek(), fee1 + fee2 - refund1); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET_2))); + + // second refund in the last asset used with `buy_weight`. + assert_eq!( + trader.refund_weight(weight_worth_of(refund2), &xcm_context()), + Some(refund_asset_2) + ); + + assert_eq!(trader.total_fee.peek(), fee1 + fee2 - refund1 - refund2); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET_2))); + + assert_eq!(Fungibles::total_issuance(TARGET_ASSET), target_total); + assert_eq!(Fungibles::total_issuance(CLIENT_ASSET), client_total + fee1); + assert_eq!( + Fungibles::total_issuance(CLIENT_ASSET_2), + client_total_2 + fee2 - refund1 - refund2 + ); +} + +#[test] +fn not_enough_to_refund() { + let client_asset_total = 15; + let fee = 5; + let refund = 6; + + setup_pool(CLIENT_ASSET, 1000, TARGET_ASSET, 1000); + + let holding_asset = create_holding_asset(CLIENT_ASSET, client_asset_total); + let holding_change = create_holding_asset(CLIENT_ASSET, client_asset_total - fee); + + let target_total = Fungibles::total_issuance(TARGET_ASSET); + let client_total = Fungibles::total_issuance(CLIENT_ASSET); + + let mut trader = Trader::new(); + assert_eq!( + trader.buy_weight(weight_worth_of(fee), holding_asset, &xcm_context()).unwrap(), + holding_change + ); + + assert_eq!(trader.total_fee.peek(), fee); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET))); + + assert_eq!(trader.refund_weight(weight_worth_of(refund), &xcm_context()), None); + + assert_eq!(Fungibles::total_issuance(TARGET_ASSET), target_total); + assert_eq!(Fungibles::total_issuance(CLIENT_ASSET), client_total + fee); +} + +#[test] +fn not_exchangeable_to_refund() { + let client_asset_total = 15; + let fee = 5; + let refund = 1; + + setup_pool(CLIENT_ASSET, 1000, TARGET_ASSET, 1000); + + let holding_asset = create_holding_asset(CLIENT_ASSET, client_asset_total); + let holding_change = create_holding_asset(CLIENT_ASSET, client_asset_total - fee); + + let target_total = Fungibles::total_issuance(TARGET_ASSET); + let client_total = Fungibles::total_issuance(CLIENT_ASSET); + + let mut trader = Trader::new(); + assert_eq!( + trader.buy_weight(weight_worth_of(fee), holding_asset, &xcm_context()).unwrap(), + holding_change + ); + + assert_eq!(trader.total_fee.peek(), fee); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET))); + + assert_eq!(trader.refund_weight(weight_worth_of(refund), &xcm_context()), None); + + assert_eq!(Fungibles::total_issuance(TARGET_ASSET), target_total); + assert_eq!(Fungibles::total_issuance(CLIENT_ASSET), client_total + fee); +} + +#[test] +fn nothing_to_refund() { + let fee = 5; + + let mut trader = Trader::new(); + assert_eq!(trader.refund_weight(weight_worth_of(fee), &xcm_context()), None); +} + +#[test] +fn holding_asset_not_exchangeable_for_target() { + let holding_asset = create_holding_asset(CLIENT_ASSET, 10); + + let target_total = Fungibles::total_issuance(TARGET_ASSET); + let client_total = Fungibles::total_issuance(CLIENT_ASSET); + + let mut trader = Trader::new(); + assert_eq!( + trader + .buy_weight(Weight::from_all(10), holding_asset, &xcm_context()) + .unwrap_err(), + XcmError::FeesNotMet + ); + + assert_eq!(Fungibles::total_issuance(TARGET_ASSET), target_total); + assert_eq!(Fungibles::total_issuance(CLIENT_ASSET), client_total); +} + +#[test] +fn empty_holding_asset() { + let mut trader = Trader::new(); + assert_eq!( + trader + .buy_weight(Weight::from_all(10), HoldingAsset::new(), &xcm_context()) + .unwrap_err(), + XcmError::AssetNotFound + ); +} + +#[test] +fn fails_to_match_holding_asset() { + let mut trader = Trader::new(); + let holding_asset = + MultiAsset { id: Concrete(MultiLocation::new(1, X1(Parachain(1)))), fun: Fungible(10) }; + assert_eq!( + trader + .buy_weight(Weight::from_all(10), holding_asset.into(), &xcm_context()) + .unwrap_err(), + XcmError::AssetNotFound + ); +} + +#[test] +fn holding_asset_equal_to_target_asset() { + let mut trader = Trader::new(); + let holding_asset = create_holding_asset(TargetAsset::get(), 10); + assert_eq!( + trader + .buy_weight(Weight::from_all(10), holding_asset, &xcm_context()) + .unwrap_err(), + XcmError::FeesNotMet + ); +} + +pub mod mock { + use crate::*; + use core::cell::RefCell; + use frame_support::{ + ensure, + traits::{ + fungibles::{Balanced, DecreaseIssuance, Dust, IncreaseIssuance, Inspect, Unbalanced}, + tokens::{ + DepositConsequence, Fortitude, Fortitude::Polite, Precision::Exact, Preservation, + Preservation::Preserve, Provenance, WithdrawConsequence, + }, + }, + }; + use sp_runtime::{traits::One, DispatchError}; + use std::collections::HashMap; + use xcm::latest::Junction; + + pub type AccountId = u64; + pub type AssetId = u32; + pub type Balance = u128; + pub type Credit = fungibles::Credit; + + thread_local! { + pub static TOTAL_ISSUANCE: RefCell> = RefCell::new(HashMap::new()); + pub static ACCOUNT: RefCell> = RefCell::new(HashMap::new()); + pub static SWAP: RefCell> = RefCell::new(HashMap::new()); + } + + pub struct Swap {} + impl SwapCreditT for Swap { + type Balance = Balance; + type AssetKind = AssetId; + type Credit = Credit; + fn max_path_len() -> u32 { + 2 + } + fn swap_exact_tokens_for_tokens( + path: Vec, + credit_in: Self::Credit, + amount_out_min: Option, + ) -> Result { + ensure!(2 == path.len(), (credit_in, DispatchError::Unavailable)); + ensure!( + credit_in.peek() >= amount_out_min.unwrap_or(Self::Balance::zero()), + (credit_in, DispatchError::Unavailable) + ); + let swap_res = SWAP.with(|b| b.borrow().get(&(path[0], path[1])).map(|v| *v)); + let pool_account = match swap_res { + Some(a) => a, + None => return Err((credit_in, DispatchError::Unavailable)), + }; + let credit_out = match Fungibles::withdraw( + path[1], + &pool_account, + credit_in.peek(), + Exact, + Preserve, + Polite, + ) { + Ok(c) => c, + Err(_) => return Err((credit_in, DispatchError::Unavailable)), + }; + let _ = Fungibles::resolve(&pool_account, credit_in) + .map_err(|c| (c, DispatchError::Unavailable))?; + Ok(credit_out) + } + fn swap_tokens_for_exact_tokens( + path: Vec, + credit_in: Self::Credit, + amount_out: Self::Balance, + ) -> Result<(Self::Credit, Self::Credit), (Self::Credit, DispatchError)> { + ensure!(2 == path.len(), (credit_in, DispatchError::Unavailable)); + ensure!(credit_in.peek() >= amount_out, (credit_in, DispatchError::Unavailable)); + let swap_res = SWAP.with(|b| b.borrow().get(&(path[0], path[1])).map(|v| *v)); + let pool_account = match swap_res { + Some(a) => a, + None => return Err((credit_in, DispatchError::Unavailable)), + }; + let credit_out = match Fungibles::withdraw( + path[1], + &pool_account, + amount_out, + Exact, + Preserve, + Polite, + ) { + Ok(c) => c, + Err(_) => return Err((credit_in, DispatchError::Unavailable)), + }; + let (credit_in, change) = credit_in.split(amount_out); + let _ = Fungibles::resolve(&pool_account, credit_in) + .map_err(|c| (c, DispatchError::Unavailable))?; + Ok((credit_out, change)) + } + } + + pub fn pool_account(asset1: AssetId, asset2: AssetId) -> AccountId { + (1000 + asset1 * 10 + asset2 * 100).into() + } + + pub fn setup_pool(asset1: AssetId, liquidity1: Balance, asset2: AssetId, liquidity2: Balance) { + let account = pool_account(asset1, asset2); + SWAP.with(|b| b.borrow_mut().insert((asset1, asset2), account)); + let debt1 = Fungibles::deposit(asset1, &account, liquidity1, Exact); + let debt2 = Fungibles::deposit(asset2, &account, liquidity2, Exact); + drop(debt1); + drop(debt2); + } + + pub struct WeightToFee; + impl WeightToFeeT for WeightToFee { + type Balance = Balance; + fn weight_to_fee(weight: &Weight) -> Self::Balance { + (weight.ref_time() + weight.proof_size()).into() + } + } + + pub struct Fungibles {} + impl Inspect for Fungibles { + type AssetId = AssetId; + type Balance = Balance; + fn total_issuance(asset: Self::AssetId) -> Self::Balance { + TOTAL_ISSUANCE.with(|b| b.borrow().get(&asset).map_or(Self::Balance::zero(), |b| *b)) + } + fn minimum_balance(_: Self::AssetId) -> Self::Balance { + Self::Balance::one() + } + fn total_balance(asset: Self::AssetId, who: &AccountId) -> Self::Balance { + ACCOUNT.with(|b| b.borrow().get(&(asset, *who)).map_or(Self::Balance::zero(), |b| *b)) + } + fn balance(asset: Self::AssetId, who: &AccountId) -> Self::Balance { + ACCOUNT.with(|b| b.borrow().get(&(asset, *who)).map_or(Self::Balance::zero(), |b| *b)) + } + fn reducible_balance( + asset: Self::AssetId, + who: &AccountId, + _: Preservation, + _: Fortitude, + ) -> Self::Balance { + ACCOUNT.with(|b| b.borrow().get(&(asset, *who)).map_or(Self::Balance::zero(), |b| *b)) + } + fn can_deposit( + _: Self::AssetId, + _: &AccountId, + _: Self::Balance, + _: Provenance, + ) -> DepositConsequence { + unimplemented!() + } + fn can_withdraw( + _: Self::AssetId, + _: &AccountId, + _: Self::Balance, + ) -> WithdrawConsequence { + unimplemented!() + } + fn asset_exists(_: Self::AssetId) -> bool { + unimplemented!() + } + } + + impl Unbalanced for Fungibles { + fn set_total_issuance(asset: Self::AssetId, amount: Self::Balance) { + TOTAL_ISSUANCE.with(|b| b.borrow_mut().insert(asset, amount)); + } + fn handle_dust(_: Dust) { + unimplemented!() + } + fn write_balance( + asset: Self::AssetId, + who: &AccountId, + amount: Self::Balance, + ) -> Result, DispatchError> { + let _ = ACCOUNT.with(|b| b.borrow_mut().insert((asset, *who), amount)); + Ok(None) + } + } + + impl Balanced for Fungibles { + type OnDropCredit = DecreaseIssuance; + type OnDropDebt = IncreaseIssuance; + } + + pub struct FungiblesMatcher; + impl MatchesFungibles for FungiblesMatcher { + fn matches_fungibles( + a: &MultiAsset, + ) -> core::result::Result<(AssetId, Balance), xcm_executor::traits::Error> { + match a { + MultiAsset { + fun: Fungible(amount), + id: + Concrete(MultiLocation { parents: 0, interior: X1(Junction::GeneralIndex(id)) }), + } => Ok(((*id).try_into().unwrap(), *amount)), + _ => Err(xcm_executor::traits::Error::AssetNotHandled), + } + } + } +} diff --git a/prdoc/pr_1845.prdoc b/prdoc/pr_1845.prdoc new file mode 100644 index 00000000000..cf6cd1feadf --- /dev/null +++ b/prdoc/pr_1845.prdoc @@ -0,0 +1,16 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: "XCM WeightTrader: Swap Fee Asset for Native Asset" + +doc: + - audience: Runtime Dev + description: | + Implements an XCM executor `WeightTrader`, facilitating fee payments in any asset that can be exchanged for a native asset. + + A few constraints need to be observed: + - `buy_weight` and `refund` operations must be atomic, as another weight trader implementation might be attempted in case of failure. + - swap credit must be utilized since there isn’t an account to which an asset of some class can be deposited with a guarantee to meet the existential deposit requirement. + +crates: + - name: cumulus-primitives-utility -- GitLab From a42a47f81d91ccf2f885ff01749185cd4c793278 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=B3nal=20Murray?= Date: Tue, 16 Jan 2024 08:24:13 +0000 Subject: [PATCH 059/392] Bump rococo relay and coretime-rococo to 1.6 (#2913) Co-authored-by: command-bot <> --- .../coretime/coretime-rococo/src/lib.rs | 2 +- .../cumulus_pallet_parachain_system.rs | 26 ++- .../src/weights/cumulus_pallet_xcmp_queue.rs | 41 ++-- .../src/weights/frame_system.rs | 110 ++++++---- .../src/weights/pallet_balances.rs | 62 +++--- .../src/weights/pallet_broker.rs | 161 +++++++------- .../src/weights/pallet_collator_selection.rs | 154 +++++++------ .../src/weights/pallet_message_queue.rs | 58 ++--- .../src/weights/pallet_multisig.rs | 89 ++++---- .../src/weights/pallet_session.rs | 33 +-- .../src/weights/pallet_timestamp.rs | 23 +- .../src/weights/pallet_utility.rs | 45 ++-- .../coretime-rococo/src/weights/pallet_xcm.rs | 77 +++---- .../xcm/pallet_xcm_benchmarks_fungible.rs | 117 +++++----- .../xcm/pallet_xcm_benchmarks_generic.rs | 202 ++++++++---------- polkadot/runtime/rococo/src/lib.rs | 2 +- 16 files changed, 640 insertions(+), 562 deletions(-) diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index 0f01c2d7416..c381d78b57f 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -129,7 +129,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("coretime-rococo"), impl_name: create_runtime_str!("coretime-rococo"), authoring_version: 1, - spec_version: 1_005_004, + spec_version: 1_006_001, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 0, diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_parachain_system.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_parachain_system.rs index f7a1486ed58..139e37c5448 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_parachain_system.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_parachain_system.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `cumulus_pallet_parachain_system` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=cumulus_pallet_parachain_system +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -58,14 +61,17 @@ impl cumulus_pallet_parachain_system::WeightInfo for We /// Storage: `MessageQueue::Pages` (r:0 w:1000) /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65585), added: 68060, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. - fn enqueue_inbound_downward_messages(_n: u32, ) -> Weight { + fn enqueue_inbound_downward_messages(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `42` + // Measured: `48` // Estimated: `3517` - // Minimum execution time: 3_000_000 picoseconds. - Weight::from_parts(144_747_000_000, 0) + // Minimum execution time: 2_067_000 picoseconds. + Weight::from_parts(2_151_000, 0) .saturating_add(Weight::from_parts(0, 3517)) + // Standard Error: 32_757 + .saturating_add(Weight::from_parts(204_001_420, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(1004)) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_xcmp_queue.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_xcmp_queue.rs index f5683f747a3..efbe7980de2 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_xcmp_queue.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_xcmp_queue.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `cumulus_pallet_xcmp_queue` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=cumulus_pallet_xcmp_queue +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -53,8 +56,8 @@ impl cumulus_pallet_xcmp_queue::WeightInfo for WeightIn // Proof Size summary in bytes: // Measured: `76` // Estimated: `1561` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(6_000_000, 0) + // Minimum execution time: 3_935_000 picoseconds. + Weight::from_parts(4_188_000, 0) .saturating_add(Weight::from_parts(0, 1561)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -73,8 +76,8 @@ impl cumulus_pallet_xcmp_queue::WeightInfo for WeightIn // Proof Size summary in bytes: // Measured: `82` // Estimated: `3517` - // Minimum execution time: 13_000_000 picoseconds. - Weight::from_parts(13_000_000, 0) + // Minimum execution time: 10_252_000 picoseconds. + Weight::from_parts(10_551_000, 0) .saturating_add(Weight::from_parts(0, 3517)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) @@ -85,8 +88,8 @@ impl cumulus_pallet_xcmp_queue::WeightInfo for WeightIn // Proof Size summary in bytes: // Measured: `76` // Estimated: `1561` - // Minimum execution time: 3_000_000 picoseconds. - Weight::from_parts(3_000_000, 0) + // Minimum execution time: 2_294_000 picoseconds. + Weight::from_parts(2_477_000, 0) .saturating_add(Weight::from_parts(0, 1561)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -97,8 +100,8 @@ impl cumulus_pallet_xcmp_queue::WeightInfo for WeightIn // Proof Size summary in bytes: // Measured: `111` // Estimated: `1596` - // Minimum execution time: 4_000_000 picoseconds. - Weight::from_parts(4_000_000, 0) + // Minimum execution time: 3_068_000 picoseconds. + Weight::from_parts(3_204_000, 0) .saturating_add(Weight::from_parts(0, 1596)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -107,8 +110,8 @@ impl cumulus_pallet_xcmp_queue::WeightInfo for WeightIn // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 42_000_000 picoseconds. - Weight::from_parts(42_000_000, 0) + // Minimum execution time: 68_610_000 picoseconds. + Weight::from_parts(68_800_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// Storage: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6b345d8e88afa015075c945637c07e8f20` (r:1 w:1) @@ -129,8 +132,8 @@ impl cumulus_pallet_xcmp_queue::WeightInfo for WeightIn // Proof Size summary in bytes: // Measured: `65711` // Estimated: `69176` - // Minimum execution time: 86_000_000 picoseconds. - Weight::from_parts(86_000_000, 0) + // Minimum execution time: 125_878_000 picoseconds. + Weight::from_parts(127_632_000, 0) .saturating_add(Weight::from_parts(0, 69176)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(5)) @@ -143,8 +146,8 @@ impl cumulus_pallet_xcmp_queue::WeightInfo for WeightIn // Proof Size summary in bytes: // Measured: `65710` // Estimated: `69175` - // Minimum execution time: 79_000_000 picoseconds. - Weight::from_parts(79_000_000, 0) + // Minimum execution time: 54_918_000 picoseconds. + Weight::from_parts(56_246_000, 0) .saturating_add(Weight::from_parts(0, 69175)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system.rs index 7c41112152f..428976e3e03 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `frame_system` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=frame_system +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -48,22 +51,26 @@ use core::marker::PhantomData; pub struct WeightInfo(PhantomData); impl frame_system::WeightInfo for WeightInfo { /// The range of component `b` is `[0, 3932160]`. - fn remark(_b: u32, ) -> Weight { + fn remark(b: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_000_000 picoseconds. - Weight::from_parts(775_000_000, 0) + // Minimum execution time: 1_760_000 picoseconds. + Weight::from_parts(6_086_623, 0) .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 0 + .saturating_add(Weight::from_parts(430, 0).saturating_mul(b.into())) } /// The range of component `b` is `[0, 3932160]`. - fn remark_with_event(_b: u32, ) -> Weight { + fn remark_with_event(b: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_000_000 picoseconds. - Weight::from_parts(4_700_000_000, 0) + // Minimum execution time: 5_315_000 picoseconds. + Weight::from_parts(20_446_491, 0) .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 2 + .saturating_add(Weight::from_parts(1_725, 0).saturating_mul(b.into())) } /// Storage: `System::Digest` (r:1 w:1) /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -73,8 +80,8 @@ impl frame_system::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `1485` - // Minimum execution time: 5_000_000 picoseconds. - Weight::from_parts(5_000_000, 0) + // Minimum execution time: 3_046_000 picoseconds. + Weight::from_parts(3_249_000, 0) .saturating_add(Weight::from_parts(0, 1485)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -95,8 +102,8 @@ impl frame_system::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `164` // Estimated: `1649` - // Minimum execution time: 79_510_000_000 picoseconds. - Weight::from_parts(79_510_000_000, 0) + // Minimum execution time: 108_366_941_000 picoseconds. + Weight::from_parts(111_101_742_000, 0) .saturating_add(Weight::from_parts(0, 1649)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) @@ -104,39 +111,46 @@ impl frame_system::WeightInfo for WeightInfo { /// Storage: `Skipped::Metadata` (r:0 w:0) /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `i` is `[0, 1000]`. - fn set_storage(_i: u32, ) -> Weight { + fn set_storage(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_000_000 picoseconds. - Weight::from_parts(816_000_000, 0) + // Minimum execution time: 1_877_000 picoseconds. + Weight::from_parts(1_947_000, 0) .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(T::DbWeight::get().writes(1000)) + // Standard Error: 2_035 + .saturating_add(Weight::from_parts(763_800, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) } /// Storage: `Skipped::Metadata` (r:0 w:0) /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `i` is `[0, 1000]`. - fn kill_storage(_i: u32, ) -> Weight { + fn kill_storage(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_000_000 picoseconds. - Weight::from_parts(598_000_000, 0) + // Minimum execution time: 1_847_000 picoseconds. + Weight::from_parts(1_931_000, 0) .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(T::DbWeight::get().writes(1000)) + // Standard Error: 932 + .saturating_add(Weight::from_parts(565_066, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) } /// Storage: `Skipped::Metadata` (r:0 w:0) /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `p` is `[0, 1000]`. - fn kill_prefix(_p: u32, ) -> Weight { + fn kill_prefix(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `55 + p * (69 ±0)` - // Estimated: `69609` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(1_091_000_000, 0) - .saturating_add(Weight::from_parts(0, 69609)) - .saturating_add(T::DbWeight::get().reads(1000)) - .saturating_add(T::DbWeight::get().writes(1000)) + // Measured: `71 + p * (69 ±0)` + // Estimated: `72 + p * (70 ±0)` + // Minimum execution time: 3_587_000 picoseconds. + Weight::from_parts(3_654_000, 0) + .saturating_add(Weight::from_parts(0, 72)) + // Standard Error: 1_468 + .saturating_add(Weight::from_parts(1_170_655, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) + .saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into())) } /// Storage: `System::AuthorizedUpgrade` (r:0 w:1) /// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) @@ -144,25 +158,33 @@ impl frame_system::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 33_027_000 picoseconds. - Weight::from_parts(33_027_000, 0) + // Minimum execution time: 9_701_000 picoseconds. + Weight::from_parts(10_142_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `System::AuthorizedUpgrade` (r:1 w:1) /// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:1) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) - /// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) + /// Storage: `ParachainSystem::ValidationData` (r:1 w:0) + /// Proof: `ParachainSystem::ValidationData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::UpgradeRestrictionSignal` (r:1 w:0) + /// Proof: `ParachainSystem::UpgradeRestrictionSignal` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingValidationCode` (r:1 w:1) + /// Proof: `ParachainSystem::PendingValidationCode` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::NewValidationCode` (r:0 w:1) + /// Proof: `ParachainSystem::NewValidationCode` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::DidSetValidationCode` (r:0 w:1) + /// Proof: `ParachainSystem::DidSetValidationCode` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn apply_authorized_upgrade() -> Weight { // Proof Size summary in bytes: - // Measured: `22` - // Estimated: `1518` - // Minimum execution time: 118_101_992_000 picoseconds. - Weight::from_parts(118_101_992_000, 0) - .saturating_add(Weight::from_parts(0, 1518)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(3)) + // Measured: `186` + // Estimated: `1671` + // Minimum execution time: 113_812_980_000 picoseconds. + Weight::from_parts(115_758_263_000, 0) + .saturating_add(Weight::from_parts(0, 1671)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_balances.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_balances.rs index ee12da7c436..bb9d7b3fe8a 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_balances.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_balances.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `pallet_balances` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=pallet_balances +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -53,8 +56,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 55_000_000 picoseconds. - Weight::from_parts(55_000_000, 0) + // Minimum execution time: 45_258_000 picoseconds. + Weight::from_parts(46_265_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -65,8 +68,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 42_000_000 picoseconds. - Weight::from_parts(42_000_000, 0) + // Minimum execution time: 35_639_000 picoseconds. + Weight::from_parts(36_170_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -77,8 +80,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `3593` - // Minimum execution time: 15_000_000 picoseconds. - Weight::from_parts(15_000_000, 0) + // Minimum execution time: 12_342_000 picoseconds. + Weight::from_parts(12_736_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -89,8 +92,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `3593` - // Minimum execution time: 21_000_000 picoseconds. - Weight::from_parts(21_000_000, 0) + // Minimum execution time: 17_150_000 picoseconds. + Weight::from_parts(17_764_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -101,8 +104,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `6196` - // Minimum execution time: 66_000_000 picoseconds. - Weight::from_parts(66_000_000, 0) + // Minimum execution time: 46_745_000 picoseconds. + Weight::from_parts(47_693_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -113,8 +116,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 53_000_000 picoseconds. - Weight::from_parts(53_000_000, 0) + // Minimum execution time: 44_553_000 picoseconds. + Weight::from_parts(45_113_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -125,23 +128,26 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `3593` - // Minimum execution time: 22_000_000 picoseconds. - Weight::from_parts(22_000_000, 0) + // Minimum execution time: 15_439_000 picoseconds. + Weight::from_parts(15_832_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `System::Account` (r:1000 w:1000) + /// Storage: `System::Account` (r:999 w:999) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `u` is `[1, 1000]`. - fn upgrade_accounts(_u: u32, ) -> Weight { + fn upgrade_accounts(u: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0 + u * (135 ±0)` - // Estimated: `2603990` - // Minimum execution time: 20_000_000 picoseconds. - Weight::from_parts(14_684_000_000, 0) - .saturating_add(Weight::from_parts(0, 2603990)) - .saturating_add(T::DbWeight::get().reads(1000)) - .saturating_add(T::DbWeight::get().writes(1000)) + // Measured: `0 + u * (136 ±0)` + // Estimated: `990 + u * (2603 ±0)` + // Minimum execution time: 15_017_000 picoseconds. + Weight::from_parts(15_286_000, 0) + .saturating_add(Weight::from_parts(0, 990)) + // Standard Error: 11_887 + .saturating_add(Weight::from_parts(13_536_178, 0).saturating_mul(u.into())) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into()))) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into()))) + .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs index 665b84e32cc..2d30ddc612c 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs @@ -17,23 +17,25 @@ //! Autogenerated weights for `pallet_broker` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-q7z7ruxr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/production/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet -// --steps=50 -// --repeat=20 -// --extrinsic=* +// --chain=coretime-rococo-dev // --wasm-execution=compiled -// --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json // --pallet=pallet_broker -// --chain=coretime-rococo-dev +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=50 +// --repeat=20 +// --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -54,8 +56,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_403_000 picoseconds. - Weight::from_parts(2_504_000, 0) + // Minimum execution time: 2_462_000 picoseconds. + Weight::from_parts(2_552_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -65,8 +67,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `10888` // Estimated: `13506` - // Minimum execution time: 22_025_000 picoseconds. - Weight::from_parts(22_799_000, 0) + // Minimum execution time: 25_494_000 picoseconds. + Weight::from_parts(26_063_000, 0) .saturating_add(Weight::from_parts(0, 13506)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -77,8 +79,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `12090` // Estimated: `13506` - // Minimum execution time: 21_012_000 picoseconds. - Weight::from_parts(21_567_000, 0) + // Minimum execution time: 22_299_000 picoseconds. + Weight::from_parts(22_911_000, 0) .saturating_add(Weight::from_parts(0, 13506)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -87,20 +89,24 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Proof: `Broker::Leases` (`max_values`: Some(1), `max_size`: Some(401), added: 896, mode: `MaxEncodedLen`) /// Storage: `ParachainSystem::ValidationData` (r:1 w:0) /// Proof: `ParachainSystem::ValidationData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::LastRelayChainBlockNumber` (r:1 w:0) + /// Proof: `ParachainSystem::LastRelayChainBlockNumber` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn set_lease() -> Weight { // Proof Size summary in bytes: // Measured: `466` // Estimated: `1951` - // Minimum execution time: 10_767_000 picoseconds. - Weight::from_parts(11_364_000, 0) + // Minimum execution time: 11_590_000 picoseconds. + Weight::from_parts(12_007_000, 0) .saturating_add(Weight::from_parts(0, 1951)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Broker::Configuration` (r:1 w:0) /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) /// Storage: `ParachainSystem::ValidationData` (r:1 w:0) /// Proof: `ParachainSystem::ValidationData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::LastRelayChainBlockNumber` (r:1 w:0) + /// Proof: `ParachainSystem::LastRelayChainBlockNumber` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Broker::InstaPoolIo` (r:3 w:3) /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) /// Storage: `Broker::Reservations` (r:1 w:0) @@ -118,12 +124,12 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `12567` // Estimated: `14052` - // Minimum execution time: 112_187_000 picoseconds. - Weight::from_parts(115_233_014, 0) + // Minimum execution time: 120_928_000 picoseconds. + Weight::from_parts(124_947_252, 0) .saturating_add(Weight::from_parts(0, 14052)) - // Standard Error: 162 - .saturating_add(Weight::from_parts(539, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(7)) + // Standard Error: 435 + .saturating_add(Weight::from_parts(1_246, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(66)) } /// Storage: `Broker::Status` (r:1 w:0) @@ -138,8 +144,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `316` // Estimated: `3593` - // Minimum execution time: 32_469_000 picoseconds. - Weight::from_parts(33_443_000, 0) + // Minimum execution time: 32_826_000 picoseconds. + Weight::from_parts(33_889_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -160,8 +166,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `434` // Estimated: `4698` - // Minimum execution time: 59_488_000 picoseconds. - Weight::from_parts(64_711_000, 0) + // Minimum execution time: 57_362_000 picoseconds. + Weight::from_parts(58_994_000, 0) .saturating_add(Weight::from_parts(0, 4698)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) @@ -172,8 +178,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `357` // Estimated: `3550` - // Minimum execution time: 13_370_000 picoseconds. - Weight::from_parts(13_938_000, 0) + // Minimum execution time: 13_982_000 picoseconds. + Weight::from_parts(14_447_000, 0) .saturating_add(Weight::from_parts(0, 3550)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -184,23 +190,23 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `357` // Estimated: `3550` - // Minimum execution time: 14_592_000 picoseconds. - Weight::from_parts(15_235_000, 0) + // Minimum execution time: 15_070_000 picoseconds. + Weight::from_parts(15_735_000, 0) .saturating_add(Weight::from_parts(0, 3550)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Broker::Regions` (r:1 w:2) + /// Storage: `Broker::Regions` (r:1 w:3) /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) fn interlace() -> Weight { // Proof Size summary in bytes: // Measured: `357` // Estimated: `3550` - // Minimum execution time: 14_880_000 picoseconds. - Weight::from_parts(15_274_000, 0) + // Minimum execution time: 16_527_000 picoseconds. + Weight::from_parts(16_894_000, 0) .saturating_add(Weight::from_parts(0, 3550)) .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Broker::Configuration` (r:1 w:0) /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) @@ -214,8 +220,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `936` // Estimated: `4681` - // Minimum execution time: 24_786_000 picoseconds. - Weight::from_parts(26_047_000, 0) + // Minimum execution time: 25_493_000 picoseconds. + Weight::from_parts(26_091_000, 0) .saturating_add(Weight::from_parts(0, 4681)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) @@ -234,8 +240,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `1002` // Estimated: `5996` - // Minimum execution time: 31_159_000 picoseconds. - Weight::from_parts(31_770_000, 0) + // Minimum execution time: 31_498_000 picoseconds. + Weight::from_parts(32_560_000, 0) .saturating_add(Weight::from_parts(0, 5996)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(5)) @@ -251,11 +257,11 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `652` // Estimated: `6196 + m * (2520 ±0)` - // Minimum execution time: 56_524_000 picoseconds. - Weight::from_parts(58_065_019, 0) + // Minimum execution time: 57_183_000 picoseconds. + Weight::from_parts(58_024_898, 0) .saturating_add(Weight::from_parts(0, 6196)) - // Standard Error: 41_840 - .saturating_add(Weight::from_parts(1_322_201, 0).saturating_mul(m.into())) + // Standard Error: 35_831 + .saturating_add(Weight::from_parts(1_384_446, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(m.into()))) .saturating_add(T::DbWeight::get().writes(5)) @@ -277,8 +283,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `215` // Estimated: `3680` - // Minimum execution time: 60_923_000 picoseconds. - Weight::from_parts(62_721_000, 0) + // Minimum execution time: 59_762_000 picoseconds. + Weight::from_parts(61_114_000, 0) .saturating_add(Weight::from_parts(0, 3680)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) @@ -291,8 +297,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `465` // Estimated: `3550` - // Minimum execution time: 39_683_000 picoseconds. - Weight::from_parts(55_799_000, 0) + // Minimum execution time: 41_473_000 picoseconds. + Weight::from_parts(44_155_000, 0) .saturating_add(Weight::from_parts(0, 3550)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -307,8 +313,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `463` // Estimated: `3533` - // Minimum execution time: 90_833_000 picoseconds. - Weight::from_parts(97_249_000, 0) + // Minimum execution time: 56_672_000 picoseconds. + Weight::from_parts(58_086_000, 0) .saturating_add(Weight::from_parts(0, 3533)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -325,8 +331,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `857` // Estimated: `3593` - // Minimum execution time: 93_311_000 picoseconds. - Weight::from_parts(105_496_000, 0) + // Minimum execution time: 64_460_000 picoseconds. + Weight::from_parts(65_894_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(1)) @@ -339,8 +345,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `957` // Estimated: `4698` - // Minimum execution time: 44_597_000 picoseconds. - Weight::from_parts(48_739_000, 0) + // Minimum execution time: 37_447_000 picoseconds. + Weight::from_parts(42_318_000, 0) .saturating_add(Weight::from_parts(0, 4698)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -356,28 +362,28 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `n` is `[0, 1000]`. - fn request_core_count(n: u32, ) -> Weight { + fn request_core_count(_n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 22_114_000 picoseconds. - Weight::from_parts(23_031_633, 0) + // Minimum execution time: 21_219_000 picoseconds. + Weight::from_parts(22_084_648, 0) .saturating_add(Weight::from_parts(0, 3539)) - // Standard Error: 60 - .saturating_add(Weight::from_parts(60, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Broker::CoreCountInbox` (r:1 w:1) /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. - fn process_core_count(_n: u32, ) -> Weight { + fn process_core_count(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `266` // Estimated: `1487` - // Minimum execution time: 6_020_000 picoseconds. - Weight::from_parts(6_540_421, 0) + // Minimum execution time: 5_792_000 picoseconds. + Weight::from_parts(6_358_588, 0) .saturating_add(Weight::from_parts(0, 1487)) + // Standard Error: 20 + .saturating_add(Weight::from_parts(26, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -391,8 +397,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `447` // Estimated: `6196` - // Minimum execution time: 38_744_000 picoseconds. - Weight::from_parts(40_572_000, 0) + // Minimum execution time: 38_690_000 picoseconds. + Weight::from_parts(39_706_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) @@ -408,13 +414,15 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Storage: `Broker::Workplan` (r:0 w:60) /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. - fn rotate_sale(_n: u32, ) -> Weight { + fn rotate_sale(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `12514` // Estimated: `13506` - // Minimum execution time: 94_727_000 picoseconds. - Weight::from_parts(97_766_746, 0) + // Minimum execution time: 93_531_000 picoseconds. + Weight::from_parts(95_836_318, 0) .saturating_add(Weight::from_parts(0, 13506)) + // Standard Error: 113 + .saturating_add(Weight::from_parts(329, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(65)) } @@ -426,8 +434,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `42` // Estimated: `3493` - // Minimum execution time: 6_496_000 picoseconds. - Weight::from_parts(6_757_000, 0) + // Minimum execution time: 6_506_000 picoseconds. + Weight::from_parts(6_783_000, 0) .saturating_add(Weight::from_parts(0, 3493)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -450,8 +458,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `1321` // Estimated: `4786` - // Minimum execution time: 33_164_000 picoseconds. - Weight::from_parts(33_800_000, 0) + // Minimum execution time: 31_927_000 picoseconds. + Weight::from_parts(32_748_000, 0) .saturating_add(Weight::from_parts(0, 4786)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) @@ -470,21 +478,20 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 16_884_000 picoseconds. - Weight::from_parts(17_315_000, 0) + // Minimum execution time: 15_682_000 picoseconds. + Weight::from_parts(16_012_000, 0) .saturating_add(Weight::from_parts(0, 3539)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Broker::CoreCountInbox` (r:0 w:1) /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) - /// The range of component `n` is `[0, 1000]`. fn notify_core_count() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_017_000 picoseconds. - Weight::from_parts(2_210_693, 0) + // Minimum execution time: 2_147_000 picoseconds. + Weight::from_parts(2_281_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -502,8 +509,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `398` // Estimated: `3863` - // Minimum execution time: 12_118_000 picoseconds. - Weight::from_parts(12_541_000, 0) + // Minimum execution time: 12_015_000 picoseconds. + Weight::from_parts(12_619_000, 0) .saturating_add(Weight::from_parts(0, 3863)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_collator_selection.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_collator_selection.rs index ca740bc3550..b62a6c2fce5 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_collator_selection.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_collator_selection.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `pallet_collator_selection` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=pallet_collator_selection +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -52,15 +55,18 @@ impl pallet_collator_selection::WeightInfo for WeightIn /// Storage: `CollatorSelection::Invulnerables` (r:0 w:1) /// Proof: `CollatorSelection::Invulnerables` (`max_values`: Some(1), `max_size`: Some(641), added: 1136, mode: `MaxEncodedLen`) /// The range of component `b` is `[1, 20]`. - fn set_invulnerables(_b: u32, ) -> Weight { + fn set_invulnerables(b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `162 + b * (79 ±0)` - // Estimated: `52242` - // Minimum execution time: 14_000_000 picoseconds. - Weight::from_parts(74_000_000, 0) - .saturating_add(Weight::from_parts(0, 52242)) - .saturating_add(T::DbWeight::get().reads(20)) + // Measured: `164 + b * (79 ±0)` + // Estimated: `1155 + b * (2555 ±0)` + // Minimum execution time: 11_551_000 picoseconds. + Weight::from_parts(8_982_740, 0) + .saturating_add(Weight::from_parts(0, 1155)) + // Standard Error: 6_117 + .saturating_add(Weight::from_parts(3_093_494, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(b.into()))) .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 2555).saturating_mul(b.into())) } /// Storage: `Session::NextKeys` (r:1 w:0) /// Proof: `Session::NextKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -74,18 +80,18 @@ impl pallet_collator_selection::WeightInfo for WeightIn /// The range of component `c` is `[1, 99]`. fn add_invulnerable(b: u32, c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `796 + b * (32 ±0) + c * (52 ±0)` - // Estimated: `6287 + b * (32 ±0) + c * (53 ±0)` - // Minimum execution time: 39_000_000 picoseconds. - Weight::from_parts(37_903_628, 0) + // Measured: `720 + b * (32 ±0) + c * (53 ±0)` + // Estimated: `6287 + b * (37 ±0) + c * (53 ±0)` + // Minimum execution time: 38_580_000 picoseconds. + Weight::from_parts(39_137_598, 0) .saturating_add(Weight::from_parts(0, 6287)) - // Standard Error: 96_225 - .saturating_add(Weight::from_parts(55_555, 0).saturating_mul(b.into())) - // Standard Error: 17_673 - .saturating_add(Weight::from_parts(40_816, 0).saturating_mul(c.into())) + // Standard Error: 6_413 + .saturating_add(Weight::from_parts(119_463, 0).saturating_mul(b.into())) + // Standard Error: 1_215 + .saturating_add(Weight::from_parts(120_116, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) - .saturating_add(Weight::from_parts(0, 32).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 37).saturating_mul(b.into())) .saturating_add(Weight::from_parts(0, 53).saturating_mul(c.into())) } /// Storage: `CollatorSelection::CandidateList` (r:1 w:0) @@ -93,13 +99,15 @@ impl pallet_collator_selection::WeightInfo for WeightIn /// Storage: `CollatorSelection::Invulnerables` (r:1 w:1) /// Proof: `CollatorSelection::Invulnerables` (`max_values`: Some(1), `max_size`: Some(641), added: 1136, mode: `MaxEncodedLen`) /// The range of component `b` is `[5, 20]`. - fn remove_invulnerable(_b: u32, ) -> Weight { + fn remove_invulnerable(b: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `82 + b * (32 ±0)` // Estimated: `6287` - // Minimum execution time: 12_000_000 picoseconds. - Weight::from_parts(12_000_000, 0) + // Minimum execution time: 11_347_000 picoseconds. + Weight::from_parts(11_332_550, 0) .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 2_287 + .saturating_add(Weight::from_parts(134_624, 0).saturating_mul(b.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -109,8 +117,8 @@ impl pallet_collator_selection::WeightInfo for WeightIn // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(6_000_000, 0) + // Minimum execution time: 4_883_000 picoseconds. + Weight::from_parts(5_141_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -126,32 +134,36 @@ impl pallet_collator_selection::WeightInfo for WeightIn /// The range of component `k` is `[0, 100]`. fn set_candidacy_bond(c: u32, k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0 + c * (179 ±0) + k * (130 ±0)` - // Estimated: `261290` - // Minimum execution time: 11_000_000 picoseconds. - Weight::from_parts(11_000_000, 0) - .saturating_add(Weight::from_parts(0, 261290)) - // Standard Error: 5_514_936 - .saturating_add(Weight::from_parts(6_438_000, 0).saturating_mul(c.into())) - // Standard Error: 5_514_936 - .saturating_add(Weight::from_parts(6_368_000, 0).saturating_mul(k.into())) + // Measured: `0 + c * (180 ±0) + k * (112 ±0)` + // Estimated: `6287 + c * (901 ±29) + k * (901 ±29)` + // Minimum execution time: 8_661_000 picoseconds. + Weight::from_parts(8_852_000, 0) + .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 159_154 + .saturating_add(Weight::from_parts(5_352_946, 0).saturating_mul(c.into())) + // Standard Error: 159_154 + .saturating_add(Weight::from_parts(5_075_906, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(k.into()))) + .saturating_add(Weight::from_parts(0, 901).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 901).saturating_mul(k.into())) } /// Storage: `CollatorSelection::CandidacyBond` (r:1 w:0) /// Proof: `CollatorSelection::CandidacyBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `CollatorSelection::CandidateList` (r:1 w:1) /// Proof: `CollatorSelection::CandidateList` (`max_values`: Some(1), `max_size`: Some(4802), added: 5297, mode: `MaxEncodedLen`) /// The range of component `c` is `[4, 100]`. - fn update_bond(_c: u32, ) -> Weight { + fn update_bond(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `243 + c * (50 ±0)` + // Measured: `250 + c * (50 ±0)` // Estimated: `6287` - // Minimum execution time: 26_000_000 picoseconds. - Weight::from_parts(36_000_000, 0) + // Minimum execution time: 23_840_000 picoseconds. + Weight::from_parts(26_343_302, 0) .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 1_743 + .saturating_add(Weight::from_parts(118_295, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -166,15 +178,18 @@ impl pallet_collator_selection::WeightInfo for WeightIn /// Storage: `CollatorSelection::LastAuthoredBlock` (r:0 w:1) /// Proof: `CollatorSelection::LastAuthoredBlock` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// The range of component `c` is `[1, 99]`. - fn register_as_candidate(_c: u32, ) -> Weight { + fn register_as_candidate(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `441 + c * (54 ±0)` - // Estimated: `9299` - // Minimum execution time: 39_000_000 picoseconds. - Weight::from_parts(40_000_000, 0) - .saturating_add(Weight::from_parts(0, 9299)) + // Measured: `687 + c * (52 ±0)` + // Estimated: `6287 + c * (54 ±0)` + // Minimum execution time: 31_637_000 picoseconds. + Weight::from_parts(35_792_418, 0) + .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 2_274 + .saturating_add(Weight::from_parts(146_163, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 54).saturating_mul(c.into())) } /// Storage: `CollatorSelection::Invulnerables` (r:1 w:0) /// Proof: `CollatorSelection::Invulnerables` (`max_values`: Some(1), `max_size`: Some(641), added: 1136, mode: `MaxEncodedLen`) @@ -189,15 +204,18 @@ impl pallet_collator_selection::WeightInfo for WeightIn /// Storage: `CollatorSelection::LastAuthoredBlock` (r:0 w:2) /// Proof: `CollatorSelection::LastAuthoredBlock` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// The range of component `c` is `[4, 100]`. - fn take_candidate_slot(_c: u32, ) -> Weight { + fn take_candidate_slot(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `589 + c * (54 ±0)` - // Estimated: `9521` - // Minimum execution time: 54_000_000 picoseconds. - Weight::from_parts(59_000_000, 0) - .saturating_add(Weight::from_parts(0, 9521)) + // Measured: `855 + c * (52 ±0)` + // Estimated: `6287 + c * (55 ±0)` + // Minimum execution time: 47_931_000 picoseconds. + Weight::from_parts(52_506_905, 0) + .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 2_696 + .saturating_add(Weight::from_parts(149_395, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(Weight::from_parts(0, 55).saturating_mul(c.into())) } /// Storage: `CollatorSelection::CandidateList` (r:1 w:1) /// Proof: `CollatorSelection::CandidateList` (`max_values`: Some(1), `max_size`: Some(4802), added: 5297, mode: `MaxEncodedLen`) @@ -206,13 +224,15 @@ impl pallet_collator_selection::WeightInfo for WeightIn /// Storage: `CollatorSelection::LastAuthoredBlock` (r:0 w:1) /// Proof: `CollatorSelection::LastAuthoredBlock` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// The range of component `c` is `[4, 100]`. - fn leave_intent(_c: u32, ) -> Weight { + fn leave_intent(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `268 + c * (48 ±0)` + // Measured: `277 + c * (48 ±0)` // Estimated: `6287` - // Minimum execution time: 31_000_000 picoseconds. - Weight::from_parts(38_000_000, 0) + // Minimum execution time: 27_658_000 picoseconds. + Weight::from_parts(30_896_953, 0) .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 2_038 + .saturating_add(Weight::from_parts(120_980, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -226,8 +246,8 @@ impl pallet_collator_selection::WeightInfo for WeightIn // Proof Size summary in bytes: // Measured: `103` // Estimated: `6196` - // Minimum execution time: 49_000_000 picoseconds. - Weight::from_parts(49_000_000, 0) + // Minimum execution time: 37_700_000 picoseconds. + Weight::from_parts(38_497_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(4)) @@ -242,24 +262,24 @@ impl pallet_collator_selection::WeightInfo for WeightIn /// Proof: `CollatorSelection::DesiredCandidates` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `System::BlockWeight` (r:1 w:1) /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) + /// Storage: `System::Account` (r:97 w:97) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 100]`. /// The range of component `c` is `[1, 100]`. fn new_session(r: u32, c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `340 + c * (97 ±0)` - // Estimated: `6287 + c * (2519 ±0)` - // Minimum execution time: 19_000_000 picoseconds. - Weight::from_parts(11_136_363, 0) + // Measured: `2143 + c * (97 ±0) + r * (112 ±0)` + // Estimated: `6287 + c * (2519 ±0) + r * (2603 ±0)` + // Minimum execution time: 16_077_000 picoseconds. + Weight::from_parts(16_274_000, 0) .saturating_add(Weight::from_parts(0, 6287)) - // Standard Error: 323_666 - .saturating_add(Weight::from_parts(35_353, 0).saturating_mul(r.into())) - // Standard Error: 323_666 - .saturating_add(Weight::from_parts(4_328_282, 0).saturating_mul(c.into())) + // Standard Error: 283_859 + .saturating_add(Weight::from_parts(12_293_155, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) .saturating_add(Weight::from_parts(0, 2519).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 2603).saturating_mul(r.into())) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_message_queue.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_message_queue.rs index e0e8c79ca17..934ab627bc8 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_message_queue.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_message_queue.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `pallet_message_queue` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=pallet_message_queue +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -55,8 +58,8 @@ impl pallet_message_queue::WeightInfo for WeightInfo // Proof Size summary in bytes: // Measured: `223` // Estimated: `6044` - // Minimum execution time: 13_000_000 picoseconds. - Weight::from_parts(13_000_000, 0) + // Minimum execution time: 11_120_000 picoseconds. + Weight::from_parts(11_605_000, 0) .saturating_add(Weight::from_parts(0, 6044)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -69,8 +72,8 @@ impl pallet_message_queue::WeightInfo for WeightInfo // Proof Size summary in bytes: // Measured: `218` // Estimated: `6044` - // Minimum execution time: 12_000_000 picoseconds. - Weight::from_parts(12_000_000, 0) + // Minimum execution time: 9_795_000 picoseconds. + Weight::from_parts(10_300_000, 0) .saturating_add(Weight::from_parts(0, 6044)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) @@ -81,8 +84,8 @@ impl pallet_message_queue::WeightInfo for WeightInfo // Proof Size summary in bytes: // Measured: `6` // Estimated: `3517` - // Minimum execution time: 4_000_000 picoseconds. - Weight::from_parts(4_000_000, 0) + // Minimum execution time: 3_277_000 picoseconds. + Weight::from_parts(3_426_000, 0) .saturating_add(Weight::from_parts(0, 3517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -93,8 +96,8 @@ impl pallet_message_queue::WeightInfo for WeightInfo // Proof Size summary in bytes: // Measured: `72` // Estimated: `69050` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Minimum execution time: 5_016_000 picoseconds. + Weight::from_parts(5_237_000, 0) .saturating_add(Weight::from_parts(0, 69050)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -105,19 +108,24 @@ impl pallet_message_queue::WeightInfo for WeightInfo // Proof Size summary in bytes: // Measured: `72` // Estimated: `69050` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Minimum execution time: 5_118_000 picoseconds. + Weight::from_parts(5_347_000, 0) .saturating_add(Weight::from_parts(0, 69050)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `MessageQueue::BookStateFor` (r:0 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:0 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65585), added: 68060, mode: `MaxEncodedLen`) fn service_page_item() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 65_000_000 picoseconds. - Weight::from_parts(65_000_000, 0) + // Minimum execution time: 175_756_000 picoseconds. + Weight::from_parts(177_423_000, 0) .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `MessageQueue::ServiceHead` (r:1 w:1) /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) @@ -127,8 +135,8 @@ impl pallet_message_queue::WeightInfo for WeightInfo // Proof Size summary in bytes: // Measured: `171` // Estimated: `3517` - // Minimum execution time: 8_000_000 picoseconds. - Weight::from_parts(8_000_000, 0) + // Minimum execution time: 6_515_000 picoseconds. + Weight::from_parts(6_953_000, 0) .saturating_add(Weight::from_parts(0, 3517)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -141,8 +149,8 @@ impl pallet_message_queue::WeightInfo for WeightInfo // Proof Size summary in bytes: // Measured: `65667` // Estimated: `69050` - // Minimum execution time: 73_000_000 picoseconds. - Weight::from_parts(73_000_000, 0) + // Minimum execution time: 57_649_000 picoseconds. + Weight::from_parts(59_093_000, 0) .saturating_add(Weight::from_parts(0, 69050)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -155,8 +163,8 @@ impl pallet_message_queue::WeightInfo for WeightInfo // Proof Size summary in bytes: // Measured: `65667` // Estimated: `69050` - // Minimum execution time: 74_000_000 picoseconds. - Weight::from_parts(74_000_000, 0) + // Minimum execution time: 73_366_000 picoseconds. + Weight::from_parts(74_402_000, 0) .saturating_add(Weight::from_parts(0, 69050)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -169,8 +177,8 @@ impl pallet_message_queue::WeightInfo for WeightInfo // Proof Size summary in bytes: // Measured: `65667` // Estimated: `69050` - // Minimum execution time: 109_000_000 picoseconds. - Weight::from_parts(109_000_000, 0) + // Minimum execution time: 116_063_000 picoseconds. + Weight::from_parts(117_532_000, 0) .saturating_add(Weight::from_parts(0, 69050)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_multisig.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_multisig.rs index 421fc033e7c..8e010d768f6 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_multisig.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_multisig.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `pallet_multisig` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=pallet_multisig +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -48,27 +51,31 @@ use core::marker::PhantomData; pub struct WeightInfo(PhantomData); impl pallet_multisig::WeightInfo for WeightInfo { /// The range of component `z` is `[0, 10000]`. - fn as_multi_threshold_1(_z: u32, ) -> Weight { + fn as_multi_threshold_1(z: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 13_000_000 picoseconds. - Weight::from_parts(16_000_000, 0) + // Minimum execution time: 12_905_000 picoseconds. + Weight::from_parts(13_544_225, 0) .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 2 + .saturating_add(Weight::from_parts(596, 0).saturating_mul(z.into())) } /// Storage: `Multisig::Multisigs` (r:1 w:1) /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. - fn as_multi_create(_s: u32, z: u32, ) -> Weight { + fn as_multi_create(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `172 + s * (3 ±0)` + // Measured: `262 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 35_000_000 picoseconds. - Weight::from_parts(36_530_612, 0) + // Minimum execution time: 38_729_000 picoseconds. + Weight::from_parts(27_942_442, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 259 - .saturating_add(Weight::from_parts(1_650, 0).saturating_mul(z.into())) + // Standard Error: 648 + .saturating_add(Weight::from_parts(120_340, 0).saturating_mul(s.into())) + // Standard Error: 6 + .saturating_add(Weight::from_parts(1_578, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -80,13 +87,13 @@ impl pallet_multisig::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `282` // Estimated: `6811` - // Minimum execution time: 21_000_000 picoseconds. - Weight::from_parts(18_422_680, 0) + // Minimum execution time: 25_936_000 picoseconds. + Weight::from_parts(16_537_903, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 8_928 - .saturating_add(Weight::from_parts(25_773, 0).saturating_mul(s.into())) - // Standard Error: 86 - .saturating_add(Weight::from_parts(1_250, 0).saturating_mul(z.into())) + // Standard Error: 412 + .saturating_add(Weight::from_parts(105_835, 0).saturating_mul(s.into())) + // Standard Error: 4 + .saturating_add(Weight::from_parts(1_534, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -96,54 +103,62 @@ impl pallet_multisig::WeightInfo for WeightInfo { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. - fn as_multi_complete(_s: u32, z: u32, ) -> Weight { + fn as_multi_complete(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `315 + s * (34 ±0)` + // Measured: `385 + s * (33 ±0)` // Estimated: `6811` - // Minimum execution time: 53_000_000 picoseconds. - Weight::from_parts(56_571_428, 0) + // Minimum execution time: 45_291_000 picoseconds. + Weight::from_parts(31_294_385, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 86 - .saturating_add(Weight::from_parts(150, 0).saturating_mul(z.into())) + // Standard Error: 816 + .saturating_add(Weight::from_parts(152_838, 0).saturating_mul(s.into())) + // Standard Error: 8 + .saturating_add(Weight::from_parts(1_638, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Multisig::Multisigs` (r:1 w:1) /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. - fn approve_as_multi_create(_s: u32, ) -> Weight { + fn approve_as_multi_create(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `172 + s * (3 ±0)` + // Measured: `263 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 32_000_000 picoseconds. - Weight::from_parts(35_000_000, 0) + // Minimum execution time: 26_585_000 picoseconds. + Weight::from_parts(27_424_168, 0) .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 732 + .saturating_add(Weight::from_parts(123_460, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Multisig::Multisigs` (r:1 w:1) /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. - fn approve_as_multi_approve(_s: u32, ) -> Weight { + fn approve_as_multi_approve(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `282` // Estimated: `6811` - // Minimum execution time: 17_000_000 picoseconds. - Weight::from_parts(21_000_000, 0) + // Minimum execution time: 15_228_000 picoseconds. + Weight::from_parts(15_568_631, 0) .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 441 + .saturating_add(Weight::from_parts(107_463, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Multisig::Multisigs` (r:1 w:1) /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. - fn cancel_as_multi(_s: u32, ) -> Weight { + fn cancel_as_multi(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `379 + s * (2 ±0)` + // Measured: `454 + s * (1 ±0)` // Estimated: `6811` - // Minimum execution time: 31_000_000 picoseconds. - Weight::from_parts(40_000_000, 0) + // Minimum execution time: 28_033_000 picoseconds. + Weight::from_parts(29_228_827, 0) .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 748 + .saturating_add(Weight::from_parts(117_495, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_session.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_session.rs index 5151bcaa9e4..409d92be4fc 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_session.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_session.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `pallet_session` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=pallet_session +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -53,11 +56,11 @@ impl pallet_session::WeightInfo for WeightInfo { /// Proof: `Session::KeyOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) fn set_keys() -> Weight { // Proof Size summary in bytes: - // Measured: `270` - // Estimated: `3735` - // Minimum execution time: 19_000_000 picoseconds. - Weight::from_parts(19_000_000, 0) - .saturating_add(Weight::from_parts(0, 3735)) + // Measured: `271` + // Estimated: `3736` + // Minimum execution time: 15_924_000 picoseconds. + Weight::from_parts(16_586_000, 0) + .saturating_add(Weight::from_parts(0, 3736)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -67,11 +70,11 @@ impl pallet_session::WeightInfo for WeightInfo { /// Proof: `Session::KeyOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) fn purge_keys() -> Weight { // Proof Size summary in bytes: - // Measured: `242` - // Estimated: `3707` - // Minimum execution time: 13_000_000 picoseconds. - Weight::from_parts(13_000_000, 0) - .saturating_add(Weight::from_parts(0, 3707)) + // Measured: `243` + // Estimated: `3708` + // Minimum execution time: 11_218_000 picoseconds. + Weight::from_parts(11_587_000, 0) + .saturating_add(Weight::from_parts(0, 3708)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_timestamp.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_timestamp.rs index c2a23bf2a73..c171353404e 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_timestamp.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_timestamp.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `pallet_timestamp` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=pallet_timestamp +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -53,10 +56,10 @@ impl pallet_timestamp::WeightInfo for WeightInfo { /// Proof: `Aura::CurrentSlot` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) fn set() -> Weight { // Proof Size summary in bytes: - // Measured: `49` + // Measured: `86` // Estimated: `1493` - // Minimum execution time: 8_000_000 picoseconds. - Weight::from_parts(8_000_000, 0) + // Minimum execution time: 5_979_000 picoseconds. + Weight::from_parts(6_115_000, 0) .saturating_add(Weight::from_parts(0, 1493)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -65,8 +68,8 @@ impl pallet_timestamp::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `57` // Estimated: `0` - // Minimum execution time: 3_000_000 picoseconds. - Weight::from_parts(3_000_000, 0) + // Minimum execution time: 2_830_000 picoseconds. + Weight::from_parts(2_988_000, 0) .saturating_add(Weight::from_parts(0, 0)) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_utility.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_utility.rs index cf3cc98b593..84eb9783868 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_utility.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_utility.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `pallet_utility` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=pallet_utility +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -48,46 +51,52 @@ use core::marker::PhantomData; pub struct WeightInfo(PhantomData); impl pallet_utility::WeightInfo for WeightInfo { /// The range of component `c` is `[0, 1000]`. - fn batch(_c: u32, ) -> Weight { + fn batch(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(4_117_000_000, 0) + // Minimum execution time: 4_434_000 picoseconds. + Weight::from_parts(2_232_360, 0) .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 3_409 + .saturating_add(Weight::from_parts(3_308_287, 0).saturating_mul(c.into())) } fn as_derivative() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Minimum execution time: 4_455_000 picoseconds. + Weight::from_parts(4_561_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// The range of component `c` is `[0, 1000]`. - fn batch_all(_c: u32, ) -> Weight { + fn batch_all(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(4_519_000_000, 0) + // Minimum execution time: 4_304_000 picoseconds. + Weight::from_parts(4_146_029, 0) .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 3_128 + .saturating_add(Weight::from_parts(3_581_489, 0).saturating_mul(c.into())) } fn dispatch_as() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_000_000 picoseconds. - Weight::from_parts(9_000_000, 0) + // Minimum execution time: 6_531_000 picoseconds. + Weight::from_parts(6_805_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// The range of component `c` is `[0, 1000]`. - fn force_batch(_c: u32, ) -> Weight { + fn force_batch(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(4_114_000_000, 0) + // Minimum execution time: 4_412_000 picoseconds. + Weight::from_parts(4_498_000, 0) .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 1_621 + .saturating_add(Weight::from_parts(3_312_302, 0).saturating_mul(c.into())) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs index 538401ef2c5..0e34cba4aaf 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `pallet_xcm` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=pallet_xcm +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -61,8 +64,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 37_000_000 picoseconds. - Weight::from_parts(37_000_000, 0) + // Minimum execution time: 22_669_000 picoseconds. + Weight::from_parts(23_227_000, 0) .saturating_add(Weight::from_parts(0, 3539)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -83,8 +86,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `3571` - // Minimum execution time: 86_000_000 picoseconds. - Weight::from_parts(86_000_000, 0) + // Minimum execution time: 64_486_000 picoseconds. + Weight::from_parts(65_247_000, 0) .saturating_add(Weight::from_parts(0, 3571)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) @@ -125,8 +128,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 13_000_000 picoseconds. - Weight::from_parts(13_000_000, 0) + // Minimum execution time: 7_020_000 picoseconds. + Weight::from_parts(7_300_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -136,8 +139,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_000_000 picoseconds. - Weight::from_parts(4_000_000, 0) + // Minimum execution time: 2_022_000 picoseconds. + Weight::from_parts(2_141_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -161,8 +164,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 37_000_000 picoseconds. - Weight::from_parts(37_000_000, 0) + // Minimum execution time: 26_893_000 picoseconds. + Weight::from_parts(27_497_000, 0) .saturating_add(Weight::from_parts(0, 3539)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(5)) @@ -185,8 +188,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `292` // Estimated: `3757` - // Minimum execution time: 72_000_000 picoseconds. - Weight::from_parts(72_000_000, 0) + // Minimum execution time: 29_673_000 picoseconds. + Weight::from_parts(30_693_000, 0) .saturating_add(Weight::from_parts(0, 3757)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) @@ -197,8 +200,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_000_000 picoseconds. - Weight::from_parts(4_000_000, 0) + // Minimum execution time: 1_990_000 picoseconds. + Weight::from_parts(2_105_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -208,8 +211,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `95` // Estimated: `10985` - // Minimum execution time: 19_000_000 picoseconds. - Weight::from_parts(19_000_000, 0) + // Minimum execution time: 14_819_000 picoseconds. + Weight::from_parts(15_180_000, 0) .saturating_add(Weight::from_parts(0, 10985)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) @@ -220,8 +223,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `99` // Estimated: `10989` - // Minimum execution time: 19_000_000 picoseconds. - Weight::from_parts(19_000_000, 0) + // Minimum execution time: 14_935_000 picoseconds. + Weight::from_parts(15_335_000, 0) .saturating_add(Weight::from_parts(0, 10989)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) @@ -232,8 +235,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `13471` - // Minimum execution time: 22_000_000 picoseconds. - Weight::from_parts(22_000_000, 0) + // Minimum execution time: 16_278_000 picoseconds. + Weight::from_parts(16_553_000, 0) .saturating_add(Weight::from_parts(0, 13471)) .saturating_add(T::DbWeight::get().reads(5)) } @@ -253,8 +256,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `142` // Estimated: `6082` - // Minimum execution time: 32_000_000 picoseconds. - Weight::from_parts(32_000_000, 0) + // Minimum execution time: 26_360_000 picoseconds. + Weight::from_parts(26_868_000, 0) .saturating_add(Weight::from_parts(0, 6082)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) @@ -265,8 +268,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `136` // Estimated: `8551` - // Minimum execution time: 12_000_000 picoseconds. - Weight::from_parts(12_000_000, 0) + // Minimum execution time: 8_615_000 picoseconds. + Weight::from_parts(8_903_000, 0) .saturating_add(Weight::from_parts(0, 8551)) .saturating_add(T::DbWeight::get().reads(3)) } @@ -276,8 +279,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `10996` - // Minimum execution time: 19_000_000 picoseconds. - Weight::from_parts(19_000_000, 0) + // Minimum execution time: 15_284_000 picoseconds. + Weight::from_parts(15_504_000, 0) .saturating_add(Weight::from_parts(0, 10996)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) @@ -298,8 +301,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `148` // Estimated: `11038` - // Minimum execution time: 39_000_000 picoseconds. - Weight::from_parts(39_000_000, 0) + // Minimum execution time: 32_675_000 picoseconds. + Weight::from_parts(33_816_000, 0) .saturating_add(Weight::from_parts(0, 11038)) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) @@ -312,8 +315,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `32` // Estimated: `1517` - // Minimum execution time: 5_000_000 picoseconds. - Weight::from_parts(5_000_000, 0) + // Minimum execution time: 4_058_000 picoseconds. + Weight::from_parts(4_170_000, 0) .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -324,8 +327,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7669` // Estimated: `11134` - // Minimum execution time: 31_000_000 picoseconds. - Weight::from_parts(31_000_000, 0) + // Minimum execution time: 25_375_000 picoseconds. + Weight::from_parts(26_026_000, 0) .saturating_add(Weight::from_parts(0, 11134)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs index 7fab3584250..ec71a87b5a7 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs @@ -17,26 +17,28 @@ //! Autogenerated weights for `pallet_xcm_benchmarks::fungible` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-11-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: Compiled, CHAIN: Some("asset-hub-rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: Compiled, CHAIN: Some("coretime-rococo-dev"), DB CACHE: 1024 // Executed Command: -// target/production/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet -// --steps=50 -// --repeat=20 -// --extrinsic=* +// --template=./cumulus/templates/xcm-bench-template.hbs +// --chain=coretime-rococo-dev // --wasm-execution=compiled -// --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json // --pallet=pallet_xcm_benchmarks::fungible -// --chain=asset-hub-rococo-dev +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=50 +// --repeat=20 +// --json // --header=./cumulus/file_header.txt -// --template=./cumulus/templates/xcm-bench-template.hbs -// --output=./cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/ +// --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -54,8 +56,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `101` // Estimated: `3593` - // Minimum execution time: 21_643_000 picoseconds. - Weight::from_parts(22_410_000, 3593) + // Minimum execution time: 19_199_000 picoseconds. + Weight::from_parts(19_784_000, 3593) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -65,17 +67,15 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `101` // Estimated: `6196` - // Minimum execution time: 43_758_000 picoseconds. - Weight::from_parts(44_654_000, 6196) + // Minimum execution time: 42_601_000 picoseconds. + Weight::from_parts(43_296_000, 6196) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - // Storage: `System::Account` (r:3 w:3) + // Storage: `System::Account` (r:2 w:2) // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) @@ -88,54 +88,49 @@ impl WeightInfo { // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn transfer_reserve_asset() -> Weight { // Proof Size summary in bytes: - // Measured: `246` - // Estimated: `8799` - // Minimum execution time: 87_978_000 picoseconds. - Weight::from_parts(88_517_000, 8799) - .saturating_add(T::DbWeight::get().reads(10)) - .saturating_add(T::DbWeight::get().writes(5)) + // Measured: `207` + // Estimated: `6196` + // Minimum execution time: 62_463_000 picoseconds. + Weight::from_parts(64_142_000, 6196) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(4)) } - // Storage: `ParachainInfo::ParachainId` (r:1 w:0) - // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `Benchmark::Override` (r:0 w:0) + // Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) pub fn reserve_asset_deposited() -> Weight { // Proof Size summary in bytes: // Measured: `0` - // Estimated: `1489` - // Minimum execution time: 6_883_000 picoseconds. - Weight::from_parts(6_979_000, 1489) - .saturating_add(T::DbWeight::get().reads(1)) + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) // Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) // Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - // Storage: `System::Account` (r:2 w:2) - // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) // Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn initiate_reserve_withdraw() -> Weight { // Proof Size summary in bytes: - // Measured: `246` - // Estimated: `6196` - // Minimum execution time: 198_882_000 picoseconds. - Weight::from_parts(199_930_000, 6196) - .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(4)) + // Measured: `106` + // Estimated: `3571` + // Minimum execution time: 31_417_000 picoseconds. + Weight::from_parts(32_153_000, 3571) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) } pub fn receive_teleported_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_343_000 picoseconds. - Weight::from_parts(3_487_000, 0) + // Minimum execution time: 3_235_000 picoseconds. + Weight::from_parts(3_331_000, 0) } // Storage: `System::Account` (r:1 w:1) // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) @@ -143,17 +138,15 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 19_399_000 picoseconds. - Weight::from_parts(19_659_000, 3593) + // Minimum execution time: 17_701_000 picoseconds. + Weight::from_parts(18_219_000, 3593) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - // Storage: `System::Account` (r:2 w:2) + // Storage: `System::Account` (r:1 w:1) // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) @@ -166,36 +159,32 @@ impl WeightInfo { // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn deposit_reserve_asset() -> Weight { // Proof Size summary in bytes: - // Measured: `145` - // Estimated: `6196` - // Minimum execution time: 59_017_000 picoseconds. - Weight::from_parts(60_543_000, 6196) - .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(4)) + // Measured: `106` + // Estimated: `3593` + // Minimum execution time: 41_748_000 picoseconds. + Weight::from_parts(42_401_000, 3593) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(3)) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) // Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) // Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - // Storage: `System::Account` (r:1 w:1) - // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) // Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn initiate_teleport() -> Weight { // Proof Size summary in bytes: - // Measured: `145` - // Estimated: `3610` - // Minimum execution time: 45_409_000 picoseconds. - Weight::from_parts(47_041_000, 3610) - .saturating_add(T::DbWeight::get().reads(8)) - .saturating_add(T::DbWeight::get().writes(3)) + // Measured: `106` + // Estimated: `3571` + // Minimum execution time: 27_455_000 picoseconds. + Weight::from_parts(27_976_000, 3571) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 4454494badc..a11d049a3fc 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -17,26 +17,28 @@ //! Autogenerated weights for `pallet_xcm_benchmarks::generic` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-11-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: Compiled, CHAIN: Some("asset-hub-rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: Compiled, CHAIN: Some("coretime-rococo-dev"), DB CACHE: 1024 // Executed Command: -// target/production/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet -// --steps=50 -// --repeat=20 -// --extrinsic=* +// --template=./cumulus/templates/xcm-bench-template.hbs +// --chain=coretime-rococo-dev // --wasm-execution=compiled -// --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json // --pallet=pallet_xcm_benchmarks::generic -// --chain=asset-hub-rococo-dev +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=50 +// --repeat=20 +// --json // --header=./cumulus/file_header.txt -// --template=./cumulus/templates/xcm-bench-template.hbs -// --output=./cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/ +// --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,128 +52,120 @@ pub struct WeightInfo(PhantomData); impl WeightInfo { // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) // Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) // Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - // Storage: `System::Account` (r:2 w:2) - // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) // Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn report_holding() -> Weight { // Proof Size summary in bytes: - // Measured: `246` - // Estimated: `6196` - // Minimum execution time: 440_298_000 picoseconds. - Weight::from_parts(446_508_000, 6196) - .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(4)) + // Measured: `106` + // Estimated: `3571` + // Minimum execution time: 35_477_000 picoseconds. + Weight::from_parts(36_129_000, 3571) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) } pub fn buy_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_313_000 picoseconds. - Weight::from_parts(3_422_000, 0) + // Minimum execution time: 2_243_000 picoseconds. + Weight::from_parts(2_329_000, 0) } // Storage: `PolkadotXcm::Queries` (r:1 w:0) // Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) pub fn query_response() -> Weight { // Proof Size summary in bytes: - // Measured: `103` - // Estimated: `3568` - // Minimum execution time: 9_691_000 picoseconds. - Weight::from_parts(9_948_000, 3568) + // Measured: `32` + // Estimated: `3497` + // Minimum execution time: 8_112_000 picoseconds. + Weight::from_parts(8_275_000, 3497) .saturating_add(T::DbWeight::get().reads(1)) } pub fn transact() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 10_384_000 picoseconds. - Weight::from_parts(11_085_000, 0) + // Minimum execution time: 8_960_000 picoseconds. + Weight::from_parts(9_253_000, 0) } pub fn refund_surplus() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_438_000 picoseconds. - Weight::from_parts(3_577_000, 0) + // Minimum execution time: 2_332_000 picoseconds. + Weight::from_parts(2_438_000, 0) } pub fn set_error_handler() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_126_000 picoseconds. - Weight::from_parts(2_243_000, 0) + // Minimum execution time: 2_054_000 picoseconds. + Weight::from_parts(2_119_000, 0) } pub fn set_appendix() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_126_000 picoseconds. - Weight::from_parts(2_207_000, 0) + // Minimum execution time: 2_061_000 picoseconds. + Weight::from_parts(2_133_000, 0) } pub fn clear_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_105_000 picoseconds. - Weight::from_parts(2_193_000, 0) + // Minimum execution time: 2_054_000 picoseconds. + Weight::from_parts(2_128_000, 0) } pub fn descend_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_999_000 picoseconds. - Weight::from_parts(3_056_000, 0) + // Minimum execution time: 2_791_000 picoseconds. + Weight::from_parts(2_903_000, 0) } pub fn clear_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_091_000 picoseconds. - Weight::from_parts(2_176_000, 0) + // Minimum execution time: 2_088_000 picoseconds. + Weight::from_parts(2_153_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) // Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) // Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - // Storage: `System::Account` (r:2 w:2) - // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) // Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn report_error() -> Weight { // Proof Size summary in bytes: - // Measured: `246` - // Estimated: `6196` - // Minimum execution time: 55_728_000 picoseconds. - Weight::from_parts(56_704_000, 6196) - .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(4)) + // Measured: `106` + // Estimated: `3571` + // Minimum execution time: 27_721_000 picoseconds. + Weight::from_parts(28_602_000, 3571) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) } // Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) // Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) pub fn claim_asset() -> Weight { // Proof Size summary in bytes: - // Measured: `160` - // Estimated: `3625` - // Minimum execution time: 12_839_000 picoseconds. - Weight::from_parts(13_457_000, 3625) + // Measured: `90` + // Estimated: `3555` + // Minimum execution time: 11_468_000 picoseconds. + Weight::from_parts(11_866_000, 3555) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -179,13 +173,11 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_116_000 picoseconds. - Weight::from_parts(2_219_000, 0) + // Minimum execution time: 2_125_000 picoseconds. + Weight::from_parts(2_167_000, 0) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:1 w:1) // Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) - // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) @@ -198,11 +190,11 @@ impl WeightInfo { // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn subscribe_version() -> Weight { // Proof Size summary in bytes: - // Measured: `145` - // Estimated: `3610` - // Minimum execution time: 24_891_000 picoseconds. - Weight::from_parts(25_583_000, 3610) - .saturating_add(T::DbWeight::get().reads(7)) + // Measured: `74` + // Estimated: `3539` + // Minimum execution time: 22_422_000 picoseconds. + Weight::from_parts(22_924_000, 3539) + .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:0 w:1) @@ -211,122 +203,114 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_968_000 picoseconds. - Weight::from_parts(4_122_000, 0) + // Minimum execution time: 3_880_000 picoseconds. + Weight::from_parts(4_050_000, 0) .saturating_add(T::DbWeight::get().writes(1)) } pub fn burn_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 136_220_000 picoseconds. - Weight::from_parts(137_194_000, 0) + // Minimum execution time: 3_432_000 picoseconds. + Weight::from_parts(3_536_000, 0) } pub fn expect_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 12_343_000 picoseconds. - Weight::from_parts(12_635_000, 0) + // Minimum execution time: 2_213_000 picoseconds. + Weight::from_parts(2_286_000, 0) } pub fn expect_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_237_000 picoseconds. - Weight::from_parts(2_315_000, 0) + // Minimum execution time: 2_155_000 picoseconds. + Weight::from_parts(2_239_000, 0) } pub fn expect_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_094_000 picoseconds. - Weight::from_parts(2_231_000, 0) + // Minimum execution time: 2_093_000 picoseconds. + Weight::from_parts(2_139_000, 0) } pub fn expect_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_379_000 picoseconds. - Weight::from_parts(2_455_000, 0) + // Minimum execution time: 2_345_000 picoseconds. + Weight::from_parts(2_378_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) // Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) // Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - // Storage: `System::Account` (r:2 w:2) - // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) // Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn query_pallet() -> Weight { // Proof Size summary in bytes: - // Measured: `246` - // Estimated: `6196` - // Minimum execution time: 60_734_000 picoseconds. - Weight::from_parts(61_964_000, 6196) - .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(4)) + // Measured: `106` + // Estimated: `3571` + // Minimum execution time: 31_543_000 picoseconds. + Weight::from_parts(32_075_000, 3571) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) } pub fn expect_pallet() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_500_000 picoseconds. - Weight::from_parts(5_720_000, 0) + // Minimum execution time: 4_416_000 picoseconds. + Weight::from_parts(4_613_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) // Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) // Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - // Storage: `System::Account` (r:2 w:2) - // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) // Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn report_transact_status() -> Weight { // Proof Size summary in bytes: - // Measured: `246` - // Estimated: `6196` - // Minimum execution time: 55_767_000 picoseconds. - Weight::from_parts(56_790_000, 6196) - .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(4)) + // Measured: `106` + // Estimated: `3571` + // Minimum execution time: 28_050_000 picoseconds. + Weight::from_parts(28_755_000, 3571) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) } pub fn clear_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_201_000 picoseconds. - Weight::from_parts(2_291_000, 0) + // Minimum execution time: 2_073_000 picoseconds. + Weight::from_parts(2_181_000, 0) } pub fn set_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_164_000 picoseconds. - Weight::from_parts(2_241_000, 0) + // Minimum execution time: 2_049_000 picoseconds. + Weight::from_parts(2_137_000, 0) } pub fn clear_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_127_000 picoseconds. - Weight::from_parts(2_236_000, 0) + // Minimum execution time: 2_082_000 picoseconds. + Weight::from_parts(2_144_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -342,14 +326,14 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_132_000 picoseconds. - Weight::from_parts(2_216_000, 0) + // Minimum execution time: 2_043_000 picoseconds. + Weight::from_parts(2_151_000, 0) } pub fn unpaid_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_265_000 picoseconds. - Weight::from_parts(2_332_000, 0) + // Minimum execution time: 2_197_000 picoseconds. + Weight::from_parts(2_293_000, 0) } } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 3fd3f2bc635..e492caddc8f 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -153,7 +153,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("rococo"), impl_name: create_runtime_str!("parity-rococo-v2.0"), authoring_version: 0, - spec_version: 1_005_001, + spec_version: 1_006_001, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 24, -- GitLab From 05cfb02bec116349fe6e0428f06837a9290662ac Mon Sep 17 00:00:00 2001 From: Xavier Lau Date: Tue, 16 Jan 2024 20:47:35 +0800 Subject: [PATCH 060/392] CI check features (#1708) To resolve issue #1136. This is a cross verification against zepter. - [cargo-featalign](https://github.com/hack-ink/cargo-featalign): Verifies the proper propagation of all features. - [zepter](https://github.com/ggwpez/zepter): Checks for accidentally enabled features. cc @ggwpez --- Switch to a new branch. Original PR #1537. --------- Signed-off-by: Xavier Lau Signed-off-by: Oliver Tale-Yazdi Co-authored-by: Oliver Tale-Yazdi Co-authored-by: Chevdor --- .github/workflows/check-features.yml | 19 +++++++++++++++++++ substrate/frame/support/procedural/Cargo.toml | 4 ++-- substrate/primitives/api/Cargo.toml | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/check-features.yml diff --git a/.github/workflows/check-features.yml b/.github/workflows/check-features.yml new file mode 100644 index 00000000000..53d6ac6b4db --- /dev/null +++ b/.github/workflows/check-features.yml @@ -0,0 +1,19 @@ +name: Check Features + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + +jobs: + check-features: + runs-on: ubuntu-latest + steps: + - name: Fetch latest code + uses: actions/checkout@v4 + - name: Check + uses: hack-ink/cargo-featalign-action@bea88a864d6ca7d0c53c26f1391ce1d431dc7f34 # v0.1.1 + with: + crate: substrate/bin/node/runtime + features: std,runtime-benchmarks,try-runtime + ignore: sc-executor + default-std: true diff --git a/substrate/frame/support/procedural/Cargo.toml b/substrate/frame/support/procedural/Cargo.toml index 5e47f0dfeb0..25debb7fc2b 100644 --- a/substrate/frame/support/procedural/Cargo.toml +++ b/substrate/frame/support/procedural/Cargo.toml @@ -29,14 +29,14 @@ frame-support-procedural-tools = { path = "tools" } macro_magic = { version = "0.5.0", features = ["proc_support"] } proc-macro-warning = { version = "1.0.0", default-features = false } expander = "2.0.0" -sp-core-hashing = { path = "../../../primitives/core/hashing" } +sp-core-hashing = { path = "../../../primitives/core/hashing", default-features = false } [dev-dependencies] regex = "1" [features] default = ["std"] -std = [] +std = ["sp-core-hashing/std"] no-metadata-docs = [] # Generate impl-trait for tuples with the given number of tuples. Will be needed as the number of # pallets in a runtime grows. Does increase the compile time! diff --git a/substrate/primitives/api/Cargo.toml b/substrate/primitives/api/Cargo.toml index 345647cec25..346b9c35fa8 100644 --- a/substrate/primitives/api/Cargo.toml +++ b/substrate/primitives/api/Cargo.toml @@ -17,7 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false } -sp-api-proc-macro = { path = "proc-macro" } +sp-api-proc-macro = { path = "proc-macro", default-features = false } sp-core = { path = "../core", default-features = false } sp-std = { path = "../std", default-features = false } sp-runtime = { path = "../runtime", default-features = false } -- GitLab From 82c057ee78ca941d86a4455793fc9076f7ab00af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 17:03:54 +0000 Subject: [PATCH 061/392] Bump walkdir from 2.3.3 to 2.4.0 (#2910) Bumps [walkdir](https://github.com/BurntSushi/walkdir) from 2.3.3 to 2.4.0.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=walkdir&package-manager=cargo&previous-version=2.3.3&new-version=2.4.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- substrate/utils/wasm-builder/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6299bbfe51c..31347261151 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20933,9 +20933,9 @@ checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" [[package]] name = "walkdir" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", "winapi-util", diff --git a/substrate/utils/wasm-builder/Cargo.toml b/substrate/utils/wasm-builder/Cargo.toml index ffe95994c65..f882b85e473 100644 --- a/substrate/utils/wasm-builder/Cargo.toml +++ b/substrate/utils/wasm-builder/Cargo.toml @@ -21,7 +21,7 @@ console = "0.15.8" strum = { version = "0.24.1", features = ["derive"] } tempfile = "3.1.0" toml = "0.8.8" -walkdir = "2.3.2" +walkdir = "2.4.0" sp-maybe-compressed-blob = { path = "../../primitives/maybe-compressed-blob" } filetime = "0.2.16" wasm-opt = "0.116" -- GitLab From ec7bfae00a0ec0ce0841274acc707ad9b8d5b1c0 Mon Sep 17 00:00:00 2001 From: Andrei Eres Date: Tue, 16 Jan 2024 18:14:29 +0100 Subject: [PATCH 062/392] subsystem-bench: cache misses profiling (#2893) ## Why we need it To provide another level of understanding to why polkadot's subsystems may perform slower than expected. Cache misses occur when processing large amounts of data, such as during availability recovery. ## Why Cachegrind Cachegrind has many drawbacks: it is slow, it uses its own cache simulation, which is very basic. But unlike `perf`, which is a great tool, Cachegrind can run in a virtual machine. This means we can easily run it in remote installations and even use it in CI/CD to catch possible regressions. Why Cachegrind and not Callgrind, another part of Valgrind? It is simply empirically proven that profiling runs faster with Cachegrind. ## First results First results have been obtained while testing of the approach. Here is an example. ``` $ target/testnet/subsystem-bench --n-cores 10 --cache-misses data-availability-read $ cat cachegrind_report.txt I refs: 64,622,081,485 I1 misses: 3,018,168 LLi misses: 437,654 I1 miss rate: 0.00% LLi miss rate: 0.00% D refs: 12,161,833,115 (9,868,356,364 rd + 2,293,476,751 wr) D1 misses: 167,940,701 ( 71,060,073 rd + 96,880,628 wr) LLd misses: 33,550,018 ( 16,685,853 rd + 16,864,165 wr) D1 miss rate: 1.4% ( 0.7% + 4.2% ) LLd miss rate: 0.3% ( 0.2% + 0.7% ) LL refs: 170,958,869 ( 74,078,241 rd + 96,880,628 wr) LL misses: 33,987,672 ( 17,123,507 rd + 16,864,165 wr) LL miss rate: 0.0% ( 0.0% + 0.7% ) ``` The CLI output shows that 1.4% of the L1 data cache missed, which is not so bad, given that the last-level cache had that data most of the time missing only 0.3%. Instruction data of the L1 has 0.00% misses of the time. Looking at an output file with `cg_annotate` shows that most of the misses occur during reed-solomon, which is expected. --- polkadot/node/subsystem-bench/README.md | 77 +++++++++++++++---- .../subsystem-bench/src/subsystem-bench.rs | 13 +++- polkadot/node/subsystem-bench/src/valgrind.rs | 49 ++++++++++++ 3 files changed, 121 insertions(+), 18 deletions(-) create mode 100644 polkadot/node/subsystem-bench/src/valgrind.rs diff --git a/polkadot/node/subsystem-bench/README.md b/polkadot/node/subsystem-bench/README.md index b1476db2754..1ff5b129e1e 100644 --- a/polkadot/node/subsystem-bench/README.md +++ b/polkadot/node/subsystem-bench/README.md @@ -117,23 +117,24 @@ used to run a suite of tests defined in a `yaml` file like in this [example](exa ``` Options: - --network The type of network to be emulated [default: ideal] [possible values: - ideal, healthy, degraded] - --n-cores Number of cores to fetch availability for [default: 100] - --n-validators Number of validators to fetch chunks from [default: 500] - --min-pov-size The minimum pov size in KiB [default: 5120] - --max-pov-size The maximum pov size bytes [default: 5120] - -n, --num-blocks The number of blocks the test is going to run [default: 1] - -p, --peer-bandwidth The bandwidth of simulated remote peers in KiB - -b, --bandwidth The bandwidth of our simulated node in KiB - --peer-error Simulated conection error ratio [0-100] - --peer-min-latency Minimum remote peer latency in milliseconds [0-5000] - --peer-max-latency Maximum remote peer latency in milliseconds [0-5000] - --profile Enable CPU Profiling with Pyroscope - --pyroscope-url Pyroscope Server URL [default: http://localhost:4040] - --pyroscope-sample-rate Pyroscope Sample Rate [default: 113] - -h, --help Print help - -V, --version Print version + --network The type of network to be emulated [default: ideal] [possible + values: ideal, healthy, degraded] + --n-cores Number of cores to fetch availability for [default: 100] + --n-validators Number of validators to fetch chunks from [default: 500] + --min-pov-size The minimum pov size in KiB [default: 5120] + --max-pov-size The maximum pov size bytes [default: 5120] +-n, --num-blocks The number of blocks the test is going to run [default: 1] +-p, --peer-bandwidth The bandwidth of simulated remote peers in KiB +-b, --bandwidth The bandwidth of our simulated node in KiB + --peer-error Simulated conection error ratio [0-100] + --peer-min-latency Minimum remote peer latency in milliseconds [0-5000] + --peer-max-latency Maximum remote peer latency in milliseconds [0-5000] + --profile Enable CPU Profiling with Pyroscope + --pyroscope-url Pyroscope Server URL [default: http://localhost:4040] + --pyroscope-sample-rate Pyroscope Sample Rate [default: 113] + --cache-misses Enable Cache Misses Profiling with Valgrind. Linux only, Valgrind + must be in the PATH +-h, --help Print help ``` These apply to all test objectives, except `test-sequence` which relies on the values being specified in a file. @@ -221,6 +222,48 @@ view the test progress in real time by accessing [this link](http://localhost:30 Now run `target/testnet/subsystem-bench test-sequence --path polkadot/node/subsystem-bench/examples/availability_read.yaml` and view the metrics in real time and spot differences between different `n_validators` values. + +### Profiling cache misses + +Cache misses are profiled using Cachegrind, part of Valgrind. Cachegrind runs slowly, and its cache simulation is basic +and unlikely to reflect the behavior of a modern machine. However, it still represents the general situation with cache +usage, and more importantly it doesn't require a bare-metal machine to run on, which means it could be run in CI or in +a remote virtual installation. + +To profile cache misses use the `--cache-misses` flag. Cache simulation of current runs tuned for Intel Ice Lake CPU. +Since the execution will be very slow, it's recommended not to run it together with other profiling and not to take +benchmark results into account. A report is saved in a file `cachegrind_report.txt`. + +Example run results: +``` +$ target/testnet/subsystem-bench --n-cores 10 --cache-misses data-availability-read +$ cat cachegrind_report.txt +I refs: 64,622,081,485 +I1 misses: 3,018,168 +LLi misses: 437,654 +I1 miss rate: 0.00% +LLi miss rate: 0.00% + +D refs: 12,161,833,115 (9,868,356,364 rd + 2,293,476,751 wr) +D1 misses: 167,940,701 ( 71,060,073 rd + 96,880,628 wr) +LLd misses: 33,550,018 ( 16,685,853 rd + 16,864,165 wr) +D1 miss rate: 1.4% ( 0.7% + 4.2% ) +LLd miss rate: 0.3% ( 0.2% + 0.7% ) + +LL refs: 170,958,869 ( 74,078,241 rd + 96,880,628 wr) +LL misses: 33,987,672 ( 17,123,507 rd + 16,864,165 wr) +LL miss rate: 0.0% ( 0.0% + 0.7% ) +``` + +The results show that 1.4% of the L1 data cache missed, but the last level cache only missed 0.3% of the time. +Instruction data of the L1 has 0.00%. + +Cachegrind writes line-by-line cache profiling information to a file named `cachegrind.out.`. +This file is best interpreted with `cg_annotate --auto=yes cachegrind.out.`. For more information see the +[cachegrind manual](https://www.cs.cmu.edu/afs/cs.cmu.edu/project/cmt-40/Nice/RuleRefinement/bin/valgrind-3.2.0/docs/html/cg-manual.html). + +For finer profiling of cache misses, better use `perf` on a bare-metal machine. + ## Create new test objectives This tool is intended to make it easy to write new test objectives that focus individual subsystems, diff --git a/polkadot/node/subsystem-bench/src/subsystem-bench.rs b/polkadot/node/subsystem-bench/src/subsystem-bench.rs index 29b62b27855..8669ee4e8b1 100644 --- a/polkadot/node/subsystem-bench/src/subsystem-bench.rs +++ b/polkadot/node/subsystem-bench/src/subsystem-bench.rs @@ -16,6 +16,7 @@ //! A tool for running subsystem benchmark tests designed for development and //! CI regression testing. + use clap::Parser; use color_eyre::eyre; use pyroscope::PyroscopeAgent; @@ -27,6 +28,7 @@ use std::{path::Path, time::Duration}; pub(crate) mod availability; pub(crate) mod cli; pub(crate) mod core; +mod valgrind; use availability::{prepare_test, NetworkEmulation, TestState}; use cli::TestObjective; @@ -90,12 +92,21 @@ struct BenchCli { /// Pyroscope Sample Rate pub pyroscope_sample_rate: u32, + #[clap(long, default_value_t = false)] + /// Enable Cache Misses Profiling with Valgrind. Linux only, Valgrind must be in the PATH + pub cache_misses: bool, + #[command(subcommand)] pub objective: cli::TestObjective, } impl BenchCli { fn launch(self) -> eyre::Result<()> { + let is_valgrind_running = valgrind::is_valgrind_running(); + if !is_valgrind_running && self.cache_misses { + return valgrind::relaunch_in_valgrind_mode() + } + let agent_running = if self.profile { let agent = PyroscopeAgent::builder(self.pyroscope_url.as_str(), "subsystem-bench") .backend(pprof_backend(PprofConfig::new().sample_rate(self.pyroscope_sample_rate))) @@ -185,7 +196,7 @@ impl BenchCli { let mut state = TestState::new(&test_config); let (mut env, _protocol_config) = prepare_test(test_config, &mut state); - // test_config.write_to_disk(); + env.runtime() .block_on(availability::benchmark_availability_read(&mut env, state)); diff --git a/polkadot/node/subsystem-bench/src/valgrind.rs b/polkadot/node/subsystem-bench/src/valgrind.rs new file mode 100644 index 00000000000..3d0c488355b --- /dev/null +++ b/polkadot/node/subsystem-bench/src/valgrind.rs @@ -0,0 +1,49 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use color_eyre::eyre; + +/// Show if the app is running under Valgrind +pub(crate) fn is_valgrind_running() -> bool { + match std::env::var("LD_PRELOAD") { + Ok(v) => v.contains("valgrind"), + Err(_) => false, + } +} + +/// Stop execution and relaunch the app under valgrind +/// Cache configuration used to emulate Intel Ice Lake (size, associativity, line size): +/// L1 instruction: 32,768 B, 8-way, 64 B lines +/// L1 data: 49,152 B, 12-way, 64 B lines +/// Last-level: 2,097,152 B, 16-way, 64 B lines +pub(crate) fn relaunch_in_valgrind_mode() -> eyre::Result<()> { + use std::os::unix::process::CommandExt; + let err = std::process::Command::new("valgrind") + .arg("--tool=cachegrind") + .arg("--cache-sim=yes") + .arg("--log-file=cachegrind_report.txt") + .arg("--I1=32768,8,64") + .arg("--D1=49152,12,64") + .arg("--LL=2097152,16,64") + .arg("--verbose") + .args(std::env::args()) + .exec(); + + Err(eyre::eyre!( + "Сannot run Valgrind, check that it is installed and available in the PATH\n{}", + err + )) +} -- GitLab From 8428f678fe5179399f6854e194f1c8b30a9102f9 Mon Sep 17 00:00:00 2001 From: Francisco Aguirre Date: Tue, 16 Jan 2024 19:18:04 +0100 Subject: [PATCH 063/392] XCMv4 (#1230) # Note for reviewer Most changes are just syntax changes necessary for the new version. Most important files should be the ones under the `xcm` folder. # Description Added XCMv4. ## Removed `Multi` prefix The following types have been renamed: - MultiLocation -> Location - MultiAsset -> Asset - MultiAssets -> Assets - InteriorMultiLocation -> InteriorLocation - MultiAssetFilter -> AssetFilter - VersionedMultiAsset -> VersionedAsset - WildMultiAsset -> WildAsset - VersionedMultiLocation -> VersionedLocation In order to fix a name conflict, the `Assets` in `xcm-executor` were renamed to `HoldingAssets`, as they represent assets in holding. ## Removed `Abstract` asset id It was not being used anywhere and this simplifies the code. Now assets are just constructed as follows: ```rust let asset: Asset = (AssetId(Location::new(1, Here)), 100u128).into(); ``` No need for specifying `Concrete` anymore. ## Outcome is now a named fields struct Instead of ```rust pub enum Outcome { Complete(Weight), Incomplete(Weight, Error), Error(Error), } ``` we now have ```rust pub enum Outcome { Complete { used: Weight }, Incomplete { used: Weight, error: Error }, Error { error: Error }, } ``` ## Added Reanchorable trait Now both locations and assets implement this trait, making it easier to reanchor both. ## New syntax for building locations and junctions Now junctions are built using the following methods: ```rust let location = Location { parents: 1, interior: [Parachain(1000), PalletInstance(50), GeneralIndex(1984)].into() }; ``` or ```rust let location = Location::new(1, [Parachain(1000), PalletInstance(50), GeneralIndex(1984)]); ``` And they are matched like so: ```rust match location.unpack() { (1, [Parachain(id)]) => ... (0, Here) => ..., (1, [_]) => ..., } ``` This syntax is mandatory in v4, and has been also implemented for v2 and v3 for easier migration. This was needed to make all sizes smaller. # TODO - [x] Scaffold v4 - [x] Port github.com/paritytech/polkadot/pull/7236 - [x] Remove `Multi` prefix - [x] Remove `Abstract` asset id --------- Co-authored-by: command-bot <> Co-authored-by: Keith Yeung --- .../src/messages_benchmarking.rs | 12 +- .../src/messages_xcm_extension.rs | 22 +- .../xcm-bridge-hub-router/src/benchmarking.rs | 6 +- .../modules/xcm-bridge-hub-router/src/lib.rs | 33 +- .../modules/xcm-bridge-hub-router/src/mock.rs | 18 +- .../modules/xcm-bridge-hub/src/exporter.rs | 12 +- bridges/modules/xcm-bridge-hub/src/lib.rs | 14 +- bridges/modules/xcm-bridge-hub/src/mock.rs | 17 +- .../pallets/inbound-queue/src/lib.rs | 10 +- .../pallets/inbound-queue/src/mock.rs | 59 +- .../pallets/inbound-queue/src/test.rs | 4 +- .../pallets/system/runtime-api/src/lib.rs | 4 +- .../parachain/pallets/system/src/api.rs | 6 +- .../pallets/system/src/benchmarking.rs | 16 +- .../parachain/pallets/system/src/lib.rs | 44 +- .../parachain/pallets/system/src/mock.rs | 26 +- .../parachain/pallets/system/src/tests.rs | 107 +- .../parachain/primitives/core/src/lib.rs | 22 +- .../parachain/primitives/core/tests/mod.rs | 6 +- .../primitives/router/src/inbound/mod.rs | 60 +- .../primitives/router/src/inbound/tests.rs | 7 +- .../primitives/router/src/outbound/mod.rs | 39 +- .../primitives/router/src/outbound/tests.rs | 283 ++-- .../runtime/runtime-common/src/lib.rs | 47 +- .../parachain/runtime/test-common/src/lib.rs | 69 +- cumulus/pallets/xcmp-queue/src/lib.rs | 8 +- cumulus/pallets/xcmp-queue/src/mock.rs | 19 +- cumulus/pallets/xcmp-queue/src/tests.rs | 54 +- .../runtime/src/xcm_config.rs | 22 +- cumulus/parachains/common/src/impls.rs | 18 +- cumulus/parachains/common/src/xcm_config.rs | 88 +- .../parachains/testing/penpal/src/lib.rs | 4 +- .../emulated/common/src/impls.rs | 57 +- .../emulated/common/src/lib.rs | 1 + .../emulated/common/src/macros.rs | 18 +- .../emulated/common/src/xcm_helpers.rs | 16 +- .../tests/assets/asset-hub-rococo/src/lib.rs | 2 +- .../src/tests/reserve_transfer.rs | 18 +- .../src/tests/set_xcm_versions.rs | 7 +- .../assets/asset-hub-rococo/src/tests/swap.rs | 68 +- .../asset-hub-rococo/src/tests/teleport.rs | 31 +- .../tests/assets/asset-hub-westend/src/lib.rs | 2 +- .../src/tests/fellowship_treasury.rs | 14 +- .../src/tests/reserve_transfer.rs | 18 +- .../src/tests/set_xcm_versions.rs | 7 +- .../asset-hub-westend/src/tests/swap.rs | 67 +- .../asset-hub-westend/src/tests/teleport.rs | 31 +- .../asset-hub-westend/src/tests/treasury.rs | 10 +- .../bridges/bridge-hub-rococo/src/lib.rs | 2 +- .../src/tests/asset_transfers.rs | 23 +- .../bridge-hub-rococo/src/tests/mod.rs | 34 +- .../bridge-hub-rococo/src/tests/send_xcm.rs | 24 +- .../bridge-hub-rococo/src/tests/snowbridge.rs | 63 +- .../bridge-hub-rococo/src/tests/teleport.rs | 2 +- .../bridges/bridge-hub-westend/src/lib.rs | 3 +- .../src/tests/asset_transfers.rs | 20 +- .../bridge-hub-westend/src/tests/mod.rs | 34 +- .../bridge-hub-westend/src/tests/send_xcm.rs | 22 +- .../bridge-hub-westend/src/tests/teleport.rs | 2 +- cumulus/parachains/pallets/ping/src/lib.rs | 4 +- .../assets/asset-hub-rococo/src/lib.rs | 148 +- .../asset-hub-rococo/src/weights/xcm/mod.rs | 96 +- .../assets/asset-hub-rococo/src/xcm_config.rs | 140 +- .../assets/asset-hub-rococo/tests/tests.rs | 103 +- .../assets/asset-hub-westend/src/lib.rs | 146 +- .../asset-hub-westend/src/weights/xcm/mod.rs | 96 +- .../asset-hub-westend/src/xcm_config.rs | 153 +- .../assets/asset-hub-westend/tests/tests.rs | 104 +- .../runtimes/assets/common/src/benchmarks.rs | 21 +- .../assets/common/src/foreign_creators.rs | 25 +- .../assets/common/src/fungible_conversion.rs | 103 +- .../runtimes/assets/common/src/lib.rs | 224 +-- .../common/src/local_and_foreign_assets.rs | 32 +- .../runtimes/assets/common/src/matching.rs | 118 +- .../runtimes/assets/common/src/runtime_api.rs | 12 +- .../runtimes/assets/test-utils/src/lib.rs | 6 +- .../assets/test-utils/src/test_cases.rs | 290 ++-- .../test-utils/src/test_cases_over_bridge.rs | 114 +- .../assets/test-utils/src/xcm_helpers.rs | 28 +- .../src/bridge_to_bulletin_config.rs | 30 +- .../src/bridge_to_westend_config.rs | 40 +- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 78 +- .../bridge-hub-rococo/src/weights/xcm/mod.rs | 96 +- .../bridge-hub-rococo/src/xcm_config.rs | 48 +- .../bridge-hub-rococo/tests/tests.rs | 2 +- .../src/bridge_to_rococo_config.rs | 32 +- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 66 +- .../bridge-hub-westend/src/weights/xcm/mod.rs | 96 +- .../bridge-hub-westend/src/xcm_config.rs | 26 +- .../bridge-hub-westend/tests/tests.rs | 2 +- .../bridge-hubs/common/src/message_queue.rs | 12 +- .../src/test_cases/from_grandpa_chain.rs | 4 +- .../src/test_cases/from_parachain.rs | 4 +- .../test-utils/src/test_cases/helpers.rs | 12 +- .../test-utils/src/test_cases/mod.rs | 63 +- .../test-utils/src/test_data/mod.rs | 12 +- .../collectives-westend/src/ambassador/mod.rs | 2 +- .../collectives-westend/src/fellowship/mod.rs | 12 +- .../collectives-westend/src/lib.rs | 14 +- .../collectives-westend/src/xcm_config.rs | 34 +- .../contracts/contracts-rococo/src/lib.rs | 12 +- .../contracts-rococo/src/xcm_config.rs | 28 +- .../coretime/coretime-rococo/src/coretime.rs | 8 +- .../coretime/coretime-rococo/src/lib.rs | 58 +- .../coretime-rococo/src/weights/xcm/mod.rs | 96 +- .../coretime-rococo/src/xcm_config.rs | 30 +- .../coretime/coretime-westend/src/lib.rs | 58 +- .../coretime-westend/src/weights/xcm/mod.rs | 96 +- .../coretime-westend/src/xcm_config.rs | 40 +- .../glutton/glutton-westend/src/xcm_config.rs | 15 +- .../runtimes/people/people-rococo/src/lib.rs | 56 +- .../people-rococo/src/weights/xcm/mod.rs | 94 +- .../people/people-rococo/src/xcm_config.rs | 55 +- .../runtimes/people/people-westend/src/lib.rs | 56 +- .../people-westend/src/weights/xcm/mod.rs | 94 +- .../people/people-westend/src/xcm_config.rs | 65 +- .../runtimes/starters/shell/src/xcm_config.rs | 15 +- .../parachains/runtimes/test-utils/src/lib.rs | 41 +- .../runtimes/testing/penpal/src/lib.rs | 5 +- .../runtimes/testing/penpal/src/xcm_config.rs | 85 +- .../testing/rococo-parachain/src/lib.rs | 46 +- cumulus/primitives/core/src/lib.rs | 9 +- cumulus/primitives/utility/src/lib.rs | 101 +- .../utility/src/tests/swap_first.rs | 28 +- cumulus/xcm/xcm-emulator/src/lib.rs | 33 +- polkadot/runtime/common/src/impls.rs | 69 +- polkadot/runtime/common/src/xcm_sender.rs | 30 +- .../parachains/src/coretime/migration.rs | 17 +- .../runtime/parachains/src/coretime/mod.rs | 10 +- polkadot/runtime/parachains/src/mock.rs | 9 +- polkadot/runtime/rococo/src/impls.rs | 18 +- polkadot/runtime/rococo/src/lib.rs | 77 +- .../runtime/rococo/src/weights/xcm/mod.rs | 108 +- polkadot/runtime/rococo/src/xcm_config.rs | 85 +- polkadot/runtime/test-runtime/src/lib.rs | 2 +- .../runtime/test-runtime/src/xcm_config.rs | 30 +- polkadot/runtime/westend/src/impls.rs | 18 +- polkadot/runtime/westend/src/lib.rs | 79 +- .../runtime/westend/src/weights/xcm/mod.rs | 108 +- polkadot/runtime/westend/src/xcm_config.rs | 87 +- polkadot/xcm/Cargo.toml | 2 +- .../src/fungible/benchmarking.rs | 24 +- .../src/fungible/mock.rs | 33 +- .../pallet-xcm-benchmarks/src/fungible/mod.rs | 6 +- .../src/generic/benchmarking.rs | 40 +- .../pallet-xcm-benchmarks/src/generic/mock.rs | 68 +- .../pallet-xcm-benchmarks/src/generic/mod.rs | 31 +- polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs | 42 +- .../xcm/pallet-xcm-benchmarks/src/mock.rs | 24 +- polkadot/xcm/pallet-xcm/src/benchmarking.rs | 77 +- polkadot/xcm/pallet-xcm/src/lib.rs | 670 ++++---- polkadot/xcm/pallet-xcm/src/mock.rs | 220 +-- .../pallet-xcm/src/tests/assets_transfer.rs | 835 ++++++---- polkadot/xcm/pallet-xcm/src/tests/mod.rs | 321 ++-- polkadot/xcm/procedural/src/lib.rs | 22 + polkadot/xcm/procedural/src/v2.rs | 49 +- polkadot/xcm/procedural/src/v3.rs | 49 +- polkadot/xcm/procedural/src/v4.rs | 196 +++ .../xcm/procedural/tests/builder_pattern.rs | 16 +- .../procedural/tests/conversion_functions.rs | 24 + polkadot/xcm/src/lib.rs | 256 ++- polkadot/xcm/src/tests.rs | 36 +- polkadot/xcm/src/v2/multilocation.rs | 29 +- polkadot/xcm/src/v2/traits.rs | 5 +- polkadot/xcm/src/v3/junction.rs | 55 +- polkadot/xcm/src/v3/junctions.rs | 21 + polkadot/xcm/src/v3/mod.rs | 234 ++- polkadot/xcm/src/v3/multiasset.rs | 105 +- polkadot/xcm/src/v3/multilocation.rs | 30 +- polkadot/xcm/src/v3/traits.rs | 50 - polkadot/xcm/src/v4/asset.rs | 915 +++++++++++ polkadot/xcm/src/v4/junction.rs | 317 ++++ polkadot/xcm/src/v4/junctions.rs | 723 ++++++++ polkadot/xcm/src/v4/location.rs | 746 +++++++++ polkadot/xcm/src/v4/mod.rs | 1457 +++++++++++++++++ polkadot/xcm/src/v4/traits.rs | 312 ++++ .../xcm/xcm-builder/src/asset_conversion.rs | 168 +- polkadot/xcm/xcm-builder/src/barriers.rs | 64 +- polkadot/xcm/xcm-builder/src/controller.rs | 12 +- .../xcm/xcm-builder/src/currency_adapter.rs | 36 +- polkadot/xcm/xcm-builder/src/fee_handling.rs | 31 +- .../xcm-builder/src/filter_asset_location.rs | 66 +- .../xcm/xcm-builder/src/fungible_adapter.rs | 65 +- .../xcm/xcm-builder/src/fungibles_adapter.rs | 64 +- polkadot/xcm/xcm-builder/src/lib.rs | 8 +- .../xcm-builder/src/location_conversion.rs | 372 ++--- polkadot/xcm/xcm-builder/src/matcher.rs | 6 +- .../xcm/xcm-builder/src/matches_location.rs | 46 +- polkadot/xcm/xcm-builder/src/matches_token.rs | 67 +- .../xcm-builder/src/nonfungibles_adapter.rs | 56 +- .../xcm/xcm-builder/src/origin_aliases.rs | 12 +- .../xcm/xcm-builder/src/origin_conversion.rs | 123 +- polkadot/xcm/xcm-builder/src/pay.rs | 21 +- .../xcm-builder/src/process_xcm_message.rs | 20 +- polkadot/xcm/xcm-builder/src/routing.rs | 4 +- polkadot/xcm/xcm-builder/src/test_utils.rs | 74 +- polkadot/xcm/xcm-builder/src/tests/aliases.rs | 19 +- polkadot/xcm/xcm-builder/src/tests/assets.rs | 358 ++-- polkadot/xcm/xcm-builder/src/tests/basic.rs | 40 +- .../src/tests/bridging/local_para_para.rs | 6 +- .../src/tests/bridging/local_relay_relay.rs | 6 +- .../xcm/xcm-builder/src/tests/bridging/mod.rs | 54 +- .../tests/bridging/paid_remote_relay_relay.rs | 26 +- .../src/tests/bridging/remote_para_para.rs | 20 +- .../bridging/remote_para_para_via_relay.rs | 20 +- .../src/tests/bridging/remote_relay_relay.rs | 18 +- .../xcm/xcm-builder/src/tests/expecting.rs | 130 +- polkadot/xcm/xcm-builder/src/tests/locking.rs | 130 +- polkadot/xcm/xcm-builder/src/tests/mock.rs | 315 ++-- polkadot/xcm/xcm-builder/src/tests/origins.rs | 76 +- .../xcm/xcm-builder/src/tests/pay/mock.rs | 54 +- polkadot/xcm/xcm-builder/src/tests/pay/pay.rs | 28 +- .../xcm/xcm-builder/src/tests/pay/salary.rs | 14 +- .../xcm/xcm-builder/src/tests/querying.rs | 44 +- .../xcm/xcm-builder/src/tests/transacting.rs | 147 +- .../src/tests/version_subscriptions.rs | 110 +- polkadot/xcm/xcm-builder/src/tests/weight.rs | 67 +- .../xcm/xcm-builder/src/universal_exports.rs | 133 +- polkadot/xcm/xcm-builder/src/weight.rs | 38 +- polkadot/xcm/xcm-builder/tests/mock/mod.rs | 22 +- polkadot/xcm/xcm-builder/tests/scenarios.rs | 88 +- .../xcm-executor/integration-tests/src/lib.rs | 12 +- polkadot/xcm/xcm-executor/src/assets.rs | 353 ++-- polkadot/xcm/xcm-executor/src/config.rs | 10 +- polkadot/xcm/xcm-executor/src/lib.rs | 168 +- .../xcm-executor/src/traits/asset_exchange.rs | 18 +- .../xcm/xcm-executor/src/traits/asset_lock.rs | 44 +- .../xcm-executor/src/traits/asset_transfer.rs | 19 +- .../xcm/xcm-executor/src/traits/conversion.rs | 35 +- .../xcm-executor/src/traits/drop_assets.rs | 32 +- .../xcm/xcm-executor/src/traits/export.rs | 20 +- .../xcm-executor/src/traits/fee_manager.rs | 12 +- .../src/traits/filter_asset_location.rs | 10 +- .../xcm-executor/src/traits/on_response.rs | 52 +- .../xcm-executor/src/traits/should_execute.rs | 10 +- .../xcm-executor/src/traits/token_matching.rs | 20 +- .../xcm-executor/src/traits/transact_asset.rs | 172 +- .../xcm/xcm-executor/src/traits/weight.rs | 16 +- polkadot/xcm/xcm-simulator/example/src/lib.rs | 4 +- .../xcm-simulator/example/src/parachain.rs | 65 +- .../xcm-simulator/example/src/relay_chain.rs | 6 +- polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs | 4 +- .../xcm/xcm-simulator/fuzzer/src/parachain.rs | 35 +- .../xcm-simulator/fuzzer/src/relay_chain.rs | 6 +- polkadot/xcm/xcm-simulator/src/lib.rs | 44 +- prdoc/pr_1230.prdoc | 20 + substrate/frame/assets/src/benchmarking.rs | 121 +- substrate/frame/assets/src/lib.rs | 6 +- .../frame/contracts/mock-network/src/lib.rs | 8 +- .../mock-network/src/mocks/msg_queue.rs | 27 +- .../contracts/mock-network/src/parachain.rs | 62 +- .../contracts/mock-network/src/relay_chain.rs | 12 +- .../frame/contracts/mock-network/src/tests.rs | 25 +- substrate/frame/contracts/src/wasm/runtime.rs | 4 +- .../frame/support/src/traits/tokens/pay.rs | 2 +- 255 files changed, 12421 insertions(+), 6722 deletions(-) create mode 100644 polkadot/xcm/procedural/src/v4.rs create mode 100644 polkadot/xcm/procedural/tests/conversion_functions.rs create mode 100644 polkadot/xcm/src/v4/asset.rs create mode 100644 polkadot/xcm/src/v4/junction.rs create mode 100644 polkadot/xcm/src/v4/junctions.rs create mode 100644 polkadot/xcm/src/v4/location.rs create mode 100644 polkadot/xcm/src/v4/mod.rs create mode 100644 polkadot/xcm/src/v4/traits.rs create mode 100644 prdoc/pr_1230.prdoc diff --git a/bridges/bin/runtime-common/src/messages_benchmarking.rs b/bridges/bin/runtime-common/src/messages_benchmarking.rs index e7e7891461b..0c7a9ad1a83 100644 --- a/bridges/bin/runtime-common/src/messages_benchmarking.rs +++ b/bridges/bin/runtime-common/src/messages_benchmarking.rs @@ -38,7 +38,7 @@ use frame_support::weights::Weight; use pallet_bridge_messages::benchmarking::{MessageDeliveryProofParams, MessageProofParams}; use sp_runtime::traits::{Header, Zero}; use sp_std::prelude::*; -use xcm::v3::prelude::*; +use xcm::latest::prelude::*; /// Prepare inbound bridge message according to given message proof parameters. fn prepare_inbound_message( @@ -266,19 +266,19 @@ where /// Returns callback which generates `BridgeMessage` from Polkadot XCM builder based on /// `expected_message_size` for benchmark. pub fn generate_xcm_builder_bridge_message_sample( - destination: InteriorMultiLocation, + destination: InteriorLocation, ) -> impl Fn(usize) -> MessagePayload { move |expected_message_size| -> MessagePayload { // For XCM bridge hubs, it is the message that // will be pushed further to some XCM queue (XCMP/UMP) - let location = xcm::VersionedInteriorMultiLocation::V3(destination); + let location = xcm::VersionedInteriorLocation::V4(destination.clone()); let location_encoded_size = location.encoded_size(); // we don't need to be super-precise with `expected_size` here let xcm_size = expected_message_size.saturating_sub(location_encoded_size); let xcm_data_size = xcm_size.saturating_sub( // minus empty instruction size - xcm::v3::Instruction::<()>::ExpectPallet { + Instruction::<()>::ExpectPallet { index: 0, name: vec![], module_name: vec![], @@ -294,8 +294,8 @@ pub fn generate_xcm_builder_bridge_message_sample( expected_message_size, location_encoded_size, xcm_size, xcm_data_size, ); - let xcm = xcm::VersionedXcm::<()>::V3( - vec![xcm::v3::Instruction::<()>::ExpectPallet { + let xcm = xcm::VersionedXcm::<()>::V4( + vec![Instruction::<()>::ExpectPallet { index: 0, name: vec![42; xcm_data_size], module_name: vec![], diff --git a/bridges/bin/runtime-common/src/messages_xcm_extension.rs b/bridges/bin/runtime-common/src/messages_xcm_extension.rs index 53c0579c4cd..fd2c20af72a 100644 --- a/bridges/bin/runtime-common/src/messages_xcm_extension.rs +++ b/bridges/bin/runtime-common/src/messages_xcm_extension.rs @@ -123,14 +123,14 @@ impl< #[cfg_attr(feature = "std", derive(Debug, Eq, PartialEq))] pub struct SenderAndLane { /// Sending chain relative location. - pub location: MultiLocation, + pub location: Location, /// Message lane, used by the sending chain. pub lane: LaneId, } impl SenderAndLane { /// Create new object using provided location and lane. - pub fn new(location: MultiLocation, lane: LaneId) -> Self { + pub fn new(location: Location, lane: LaneId) -> Self { SenderAndLane { location, lane } } } @@ -168,7 +168,7 @@ pub struct XcmBlobHaulerAdapter( impl< H: XcmBlobHauler, - Lanes: Get>, + Lanes: Get>, > OnMessagesDelivered for XcmBlobHaulerAdapter { fn on_messages_delivered(lane: LaneId, enqueued_messages: MessageNonce) { @@ -288,7 +288,7 @@ impl LocalXcmQueueManager { /// Send congested signal to the `sending_chain_location`. fn send_congested_signal(sender_and_lane: &SenderAndLane) -> Result<(), SendError> { if let Some(msg) = H::CongestedMessage::get() { - send_xcm::(sender_and_lane.location, msg)?; + send_xcm::(sender_and_lane.location.clone(), msg)?; OutboundLanesCongestedSignals::::insert( sender_and_lane.lane, true, @@ -300,7 +300,7 @@ impl LocalXcmQueueManager { /// Send `uncongested` signal to the `sending_chain_location`. fn send_uncongested_signal(sender_and_lane: &SenderAndLane) -> Result<(), SendError> { if let Some(msg) = H::UncongestedMessage::get() { - send_xcm::(sender_and_lane.location, msg)?; + send_xcm::(sender_and_lane.location.clone(), msg)?; OutboundLanesCongestedSignals::::remove( sender_and_lane.lane, ); @@ -315,10 +315,10 @@ impl LocalXcmQueueManager { pub struct XcmVersionOfDestAndRemoteBridge( sp_std::marker::PhantomData<(Version, RemoteBridge)>, ); -impl> GetVersion +impl> GetVersion for XcmVersionOfDestAndRemoteBridge { - fn get_version_for(dest: &MultiLocation) -> Option { + fn get_version_for(dest: &Location) -> Option { let dest_version = Version::get_version_for(dest); let bridge_hub_version = Version::get_version_for(&RemoteBridge::get()); @@ -342,11 +342,11 @@ mod tests { parameter_types! { pub TestSenderAndLane: SenderAndLane = SenderAndLane { - location: MultiLocation::new(1, X1(Parachain(1000))), + location: Location::new(1, [Parachain(1000)]), lane: TEST_LANE_ID, }; - pub TestLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorMultiLocation))> = sp_std::vec![ - (TestSenderAndLane::get(), (NetworkId::ByGenesis([0; 32]), InteriorMultiLocation::Here)) + pub TestLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorLocation))> = sp_std::vec![ + (TestSenderAndLane::get(), (NetworkId::ByGenesis([0; 32]), InteriorLocation::Here)) ]; pub DummyXcmMessage: Xcm<()> = Xcm::new(); } @@ -363,7 +363,7 @@ mod tests { type Ticket = (); fn validate( - _destination: &mut Option, + _destination: &mut Option, _message: &mut Option>, ) -> SendResult { Ok(((), Default::default())) diff --git a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs index 922e4bf94ba..c4f9f534c1a 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs @@ -37,10 +37,10 @@ pub trait Config: crate::Config { /// Returns destination which is valid for this router instance. /// (Needs to pass `T::Bridges`) /// Make sure that `SendXcm` will pass. - fn ensure_bridged_target_destination() -> Result { - Ok(MultiLocation::new( + fn ensure_bridged_target_destination() -> Result { + Ok(Location::new( Self::UniversalLocation::get().len() as u8, - X1(GlobalConsensus(Self::BridgedNetworkId::get().unwrap())), + [GlobalConsensus(Self::BridgedNetworkId::get().unwrap())], )) } } diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index 229628aedcb..f219be78f9e 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -80,7 +80,7 @@ pub mod pallet { type WeightInfo: WeightInfo; /// Universal location of this runtime. - type UniversalLocation: Get; + type UniversalLocation: Get; /// The bridged network that this config is for if specified. /// Also used for filtering `Bridges` by `BridgedNetworkId`. /// If not specified, allows all networks pass through. @@ -235,9 +235,9 @@ type ViaBridgeHubExporter = SovereignPaidRemoteExporter< impl, I: 'static> ExporterFor for Pallet { fn exporter_for( network: &NetworkId, - remote_location: &InteriorMultiLocation, + remote_location: &InteriorLocation, message: &Xcm<()>, - ) -> Option<(MultiLocation, Option)> { + ) -> Option<(Location, Option)> { // ensure that the message is sent to the expected bridged network (if specified). if let Some(bridged_network) = T::BridgedNetworkId::get() { if *network != bridged_network { @@ -268,7 +268,7 @@ impl, I: 'static> ExporterFor for Pallet { // take `base_fee` from `T::Brides`, but it has to be the same `T::FeeAsset` let base_fee = match maybe_payment { Some(payment) => match payment { - MultiAsset { fun: Fungible(amount), id } if id.eq(&T::FeeAsset::get()) => amount, + Asset { fun: Fungible(amount), id } if id.eq(&T::FeeAsset::get()) => amount, invalid_asset => { log::error!( target: LOG_TARGET, @@ -318,7 +318,7 @@ impl, I: 'static> SendXcm for Pallet { type Ticket = (u32, ::Ticket); fn validate( - dest: &mut Option, + dest: &mut Option, xcm: &mut Option>, ) -> SendResult { // `dest` and `xcm` are required here @@ -446,7 +446,7 @@ mod tests { run_test(|| { assert_eq!( send_xcm::( - MultiLocation::new(2, X2(GlobalConsensus(Rococo), Parachain(1000))), + Location::new(2, [GlobalConsensus(Rococo), Parachain(1000)]), vec![].into(), ), Err(SendError::NotApplicable), @@ -459,7 +459,7 @@ mod tests { run_test(|| { assert_eq!( send_xcm::( - MultiLocation::new(2, X2(GlobalConsensus(Rococo), Parachain(1000))), + Location::new(2, [GlobalConsensus(Rococo), Parachain(1000)]), vec![ClearOrigin; HARD_MESSAGE_SIZE_LIMIT as usize].into(), ), Err(SendError::ExceedsMaxMessageSize), @@ -483,14 +483,14 @@ mod tests { #[test] fn returns_proper_delivery_price() { run_test(|| { - let dest = MultiLocation::new(2, X1(GlobalConsensus(BridgedNetworkId::get()))); + let dest = Location::new(2, [GlobalConsensus(BridgedNetworkId::get())]); let xcm: Xcm<()> = vec![ClearOrigin].into(); let msg_size = xcm.encoded_size(); // initially the base fee is used: `BASE_FEE + BYTE_FEE * msg_size + HRMP_FEE` let expected_fee = BASE_FEE + BYTE_FEE * (msg_size as u128) + HRMP_FEE; assert_eq!( - XcmBridgeHubRouter::validate(&mut Some(dest), &mut Some(xcm.clone())) + XcmBridgeHubRouter::validate(&mut Some(dest.clone()), &mut Some(xcm.clone())) .unwrap() .1 .get(0), @@ -518,10 +518,7 @@ mod tests { run_test(|| { let old_bridge = XcmBridgeHubRouter::bridge(); assert_ok!(send_xcm::( - MultiLocation::new( - 2, - X2(GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)) - ), + Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]), vec![ClearOrigin].into(), ) .map(drop)); @@ -538,10 +535,7 @@ mod tests { let old_bridge = XcmBridgeHubRouter::bridge(); assert_ok!(send_xcm::( - MultiLocation::new( - 2, - X2(GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)) - ), + Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]), vec![ClearOrigin].into(), ) .map(drop)); @@ -560,10 +554,7 @@ mod tests { let old_bridge = XcmBridgeHubRouter::bridge(); assert_ok!(send_xcm::( - MultiLocation::new( - 2, - X2(GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)) - ), + Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]), vec![ClearOrigin].into(), ) .map(drop)); diff --git a/bridges/modules/xcm-bridge-hub-router/src/mock.rs b/bridges/modules/xcm-bridge-hub-router/src/mock.rs index 9079f4b9c4c..6dbfba5f6fd 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/mock.rs @@ -49,9 +49,9 @@ construct_runtime! { parameter_types! { pub ThisNetworkId: NetworkId = Polkadot; pub BridgedNetworkId: NetworkId = Kusama; - pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(ThisNetworkId::get()), Parachain(1000)); - pub SiblingBridgeHubLocation: MultiLocation = ParentThen(X1(Parachain(1002))).into(); - pub BridgeFeeAsset: AssetId = MultiLocation::parent().into(); + pub UniversalLocation: InteriorLocation = [GlobalConsensus(ThisNetworkId::get()), Parachain(1000)].into(); + pub SiblingBridgeHubLocation: Location = ParentThen([Parachain(1002)].into()).into(); + pub BridgeFeeAsset: AssetId = Location::parent().into(); pub BridgeTable: Vec = vec![ NetworkExportTableItem::new( @@ -61,7 +61,7 @@ parameter_types! { Some((BridgeFeeAsset::get(), BASE_FEE).into()) ) ]; - pub UnknownXcmVersionLocation: MultiLocation = MultiLocation::new(2, X2(GlobalConsensus(BridgedNetworkId::get()), Parachain(9999))); + pub UnknownXcmVersionLocation: Location = Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(9999)]); } #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] @@ -87,11 +87,11 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { } pub struct LatestOrNoneForLocationVersionChecker(sp_std::marker::PhantomData); -impl> GetVersion - for LatestOrNoneForLocationVersionChecker +impl> GetVersion + for LatestOrNoneForLocationVersionChecker { - fn get_version_for(dest: &MultiLocation) -> Option { - if Location::contains(dest) { + fn get_version_for(dest: &Location) -> Option { + if LocationValue::contains(dest) { return None } Some(XCM_VERSION) @@ -110,7 +110,7 @@ impl SendXcm for TestToBridgeHubSender { type Ticket = (); fn validate( - _destination: &mut Option, + _destination: &mut Option, _message: &mut Option>, ) -> SendResult { Ok(((), (BridgeFeeAsset::get(), HRMP_FEE).into())) diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index 5318b222c54..3dd7459d30f 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -52,10 +52,10 @@ where fn validate( network: NetworkId, channel: u32, - universal_source: &mut Option, - destination: &mut Option, + universal_source: &mut Option, + destination: &mut Option, message: &mut Option>, - ) -> Result<(Self::Ticket, MultiAssets), SendError> { + ) -> Result<(Self::Ticket, Assets), SendError> { // Find supported lane_id. let sender_and_lane = Self::lane_for( universal_source.as_ref().ok_or(SendError::MissingArgument)?, @@ -137,11 +137,11 @@ mod tests { use frame_support::assert_ok; use xcm_executor::traits::export_xcm; - fn universal_source() -> InteriorMultiLocation { - X2(GlobalConsensus(RelayNetwork::get()), Parachain(SIBLING_ASSET_HUB_ID)) + fn universal_source() -> InteriorLocation { + [GlobalConsensus(RelayNetwork::get()), Parachain(SIBLING_ASSET_HUB_ID)].into() } - fn universal_destination() -> InteriorMultiLocation { + fn universal_destination() -> InteriorLocation { BridgedDestination::get() } diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 44f6903b018..60b988497fc 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -45,25 +45,25 @@ pub mod pallet { BridgeMessagesConfig { /// Runtime's universal location. - type UniversalLocation: Get; + type UniversalLocation: Get; // TODO: https://github.com/paritytech/parity-bridges-common/issues/1666 remove `ChainId` and // replace it with the `NetworkId` - then we'll be able to use // `T as pallet_bridge_messages::Config::BridgedChain::NetworkId` /// Bridged network as relative location of bridged `GlobalConsensus`. #[pallet::constant] - type BridgedNetwork: Get; + type BridgedNetwork: Get; /// Associated messages pallet instance that bridges us with the /// `BridgedNetworkId` consensus. type BridgeMessagesPalletInstance: 'static; /// Price of single message export to the bridged consensus (`Self::BridgedNetworkId`). - type MessageExportPrice: Get; + type MessageExportPrice: Get; /// Checks the XCM version for the destination. type DestinationVersion: GetVersion; /// Get point-to-point links with bridged consensus (`Self::BridgedNetworkId`). /// (this will be replaced with dynamic on-chain bridges - `Bridges V2`) - type Lanes: Get>; + type Lanes: Get>; /// Support for point-to-point links /// (this will be replaced with dynamic on-chain bridges - `Bridges V2`) type LanesSupport: XcmBlobHauler; @@ -86,10 +86,10 @@ pub mod pallet { impl, I: 'static> Pallet { /// Returns dedicated/configured lane identifier. pub(crate) fn lane_for( - source: &InteriorMultiLocation, - dest: (&NetworkId, &InteriorMultiLocation), + source: &InteriorLocation, + dest: (&NetworkId, &InteriorLocation), ) -> Option { - let source = source.relative_to(&T::UniversalLocation::get()); + let source = source.clone().relative_to(&T::UniversalLocation::get()); // Check that we have configured a point-to-point lane for 'source' and `dest`. T::Lanes::get() diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 8edd4b1f7aa..6708d4b789a 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -170,16 +170,13 @@ impl pallet_bridge_messages::WeightInfoExt for TestMessagesWeights { parameter_types! { pub const RelayNetwork: NetworkId = NetworkId::Kusama; pub const BridgedRelayNetwork: NetworkId = NetworkId::Polkadot; - pub const BridgedRelayNetworkLocation: MultiLocation = MultiLocation { - parents: 1, - interior: X1(GlobalConsensus(BridgedRelayNetwork::get())) - }; + pub BridgedRelayNetworkLocation: Location = (Parent, GlobalConsensus(BridgedRelayNetwork::get())).into(); pub const NonBridgedRelayNetwork: NetworkId = NetworkId::Rococo; pub const BridgeReserve: Balance = 100_000; - pub UniversalLocation: InteriorMultiLocation = X2( + pub UniversalLocation: InteriorLocation = [ GlobalConsensus(RelayNetwork::get()), Parachain(THIS_BRIDGE_HUB_ID), - ); + ].into(); pub const Penalty: Balance = 1_000; } @@ -197,13 +194,13 @@ impl pallet_xcm_bridge_hub::Config for TestRuntime { parameter_types! { pub TestSenderAndLane: SenderAndLane = SenderAndLane { - location: MultiLocation::new(1, X1(Parachain(SIBLING_ASSET_HUB_ID))), + location: Location::new(1, [Parachain(SIBLING_ASSET_HUB_ID)]), lane: TEST_LANE_ID, }; - pub const BridgedDestination: InteriorMultiLocation = X1( + pub BridgedDestination: InteriorLocation = [ Parachain(BRIDGED_ASSET_HUB_ID) - ); - pub TestLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorMultiLocation))> = sp_std::vec![ + ].into(); + pub TestLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorLocation))> = sp_std::vec![ (TestSenderAndLane::get(), (BridgedRelayNetwork::get(), BridgedDestination::get())) ]; } diff --git a/bridges/snowbridge/parachain/pallets/inbound-queue/src/lib.rs b/bridges/snowbridge/parachain/pallets/inbound-queue/src/lib.rs index f7eea0aadfa..bdc21fcf037 100644 --- a/bridges/snowbridge/parachain/pallets/inbound-queue/src/lib.rs +++ b/bridges/snowbridge/parachain/pallets/inbound-queue/src/lib.rs @@ -54,8 +54,8 @@ use scale_info::TypeInfo; use sp_core::{H160, H256}; use sp_std::{convert::TryFrom, vec}; use xcm::prelude::{ - send_xcm, Instruction::SetTopic, Junction::*, Junctions::*, MultiLocation, - SendError as XcmpSendError, SendXcm, Xcm, XcmContext, XcmHash, + send_xcm, Instruction::SetTopic, Junction::*, Location, SendError as XcmpSendError, SendXcm, + Xcm, XcmContext, XcmHash, }; use xcm_executor::traits::TransactAsset; @@ -324,7 +324,7 @@ pub mod pallet { } pub fn send_xcm(xcm: Xcm<()>, dest: ParaId) -> Result> { - let dest = MultiLocation { parents: 1, interior: X1(Parachain(dest.into())) }; + let dest = Location::new(1, [Parachain(dest.into())]); let (xcm_hash, _) = send_xcm::(dest, xcm).map_err(Error::::from)?; Ok(xcm_hash) } @@ -341,8 +341,8 @@ pub mod pallet { pub fn burn_fees(para_id: ParaId, fee: BalanceOf) -> DispatchResult { let dummy_context = XcmContext { origin: None, message_id: Default::default(), topic: None }; - let dest = MultiLocation { parents: 1, interior: X1(Parachain(para_id.into())) }; - let fees = (MultiLocation::parent(), fee.saturated_into::()).into(); + let dest = Location::new(1, [Parachain(para_id.into())]); + let fees = (Location::parent(), fee.saturated_into::()).into(); T::AssetTransactor::can_check_out(&dest, &fees, &dummy_context).map_err(|error| { log::error!( target: LOG_TARGET, diff --git a/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs b/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs index b031a46e219..39374aa3d71 100644 --- a/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs +++ b/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs @@ -21,8 +21,8 @@ use sp_runtime::{ BuildStorage, FixedU128, MultiSignature, }; use sp_std::convert::From; -use xcm::v3::{prelude::*, MultiAssets, SendXcm}; -use xcm_executor::Assets; +use xcm::v4::{prelude::*, SendXcm}; +use xcm_executor::AssetsInHolding; use crate::{self as inbound_queue}; @@ -155,17 +155,16 @@ impl SendXcm for MockXcmSender { type Ticket = Xcm<()>; fn validate( - dest: &mut Option, - xcm: &mut Option>, + dest: &mut Option, + xcm: &mut Option>, ) -> SendResult { - match dest { - Some(MultiLocation { interior, .. }) => { - if let X1(Parachain(1001)) = interior { - return Err(XcmpSendError::NotApplicable) - } - Ok((xcm.clone().unwrap(), MultiAssets::default())) - }, - _ => Ok((xcm.clone().unwrap(), MultiAssets::default())), + if let Some(location) = dest { + match location.unpack() { + (_, [Parachain(1001)]) => return Err(XcmpSendError::NotApplicable), + _ => Ok((xcm.clone().unwrap(), Assets::default())), + } + } else { + Ok((xcm.clone().unwrap(), Assets::default())) } } @@ -203,45 +202,33 @@ impl StaticLookup for MockChannelLookup { pub struct SuccessfulTransactor; impl TransactAsset for SuccessfulTransactor { - fn can_check_in( - _origin: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Ok(()) } - fn can_check_out( - _dest: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Ok(()) } - fn deposit_asset( - _what: &MultiAsset, - _who: &MultiLocation, - _context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(_what: &Asset, _who: &Location, _context: Option<&XcmContext>) -> XcmResult { Ok(()) } fn withdraw_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, - ) -> Result { - Ok(Assets::default()) + ) -> Result { + Ok(AssetsInHolding::default()) } fn internal_transfer_asset( - _what: &MultiAsset, - _from: &MultiLocation, - _to: &MultiLocation, + _what: &Asset, + _from: &Location, + _to: &Location, _context: &XcmContext, - ) -> Result { - Ok(Assets::default()) + ) -> Result { + Ok(AssetsInHolding::default()) } } diff --git a/bridges/snowbridge/parachain/pallets/inbound-queue/src/test.rs b/bridges/snowbridge/parachain/pallets/inbound-queue/src/test.rs index 17ebeb39446..9a47e475b8c 100644 --- a/bridges/snowbridge/parachain/pallets/inbound-queue/src/test.rs +++ b/bridges/snowbridge/parachain/pallets/inbound-queue/src/test.rs @@ -41,8 +41,8 @@ fn test_submit_happy_path() { .into(), nonce: 1, message_id: [ - 27, 217, 88, 127, 46, 143, 199, 70, 236, 66, 212, 244, 85, 221, 153, 104, 175, 37, - 224, 20, 140, 95, 140, 7, 27, 74, 182, 199, 77, 12, 194, 236, + 57, 61, 232, 3, 66, 61, 25, 190, 234, 188, 193, 174, 13, 186, 1, 64, 237, 94, 73, + 83, 14, 18, 209, 213, 78, 121, 43, 108, 251, 245, 107, 67, ], fee_burned: 110000000000, } diff --git a/bridges/snowbridge/parachain/pallets/system/runtime-api/src/lib.rs b/bridges/snowbridge/parachain/pallets/system/runtime-api/src/lib.rs index d99b456c848..7f119809546 100644 --- a/bridges/snowbridge/parachain/pallets/system/runtime-api/src/lib.rs +++ b/bridges/snowbridge/parachain/pallets/system/runtime-api/src/lib.rs @@ -3,11 +3,11 @@ #![cfg_attr(not(feature = "std"), no_std)] use snowbridge_core::AgentId; -use xcm::VersionedMultiLocation; +use xcm::VersionedLocation; sp_api::decl_runtime_apis! { pub trait ControlApi { - fn agent_id(location: VersionedMultiLocation) -> Option; + fn agent_id(location: VersionedLocation) -> Option; } } diff --git a/bridges/snowbridge/parachain/pallets/system/src/api.rs b/bridges/snowbridge/parachain/pallets/system/src/api.rs index 245e6eea1c1..ef12b03e1d7 100644 --- a/bridges/snowbridge/parachain/pallets/system/src/api.rs +++ b/bridges/snowbridge/parachain/pallets/system/src/api.rs @@ -3,14 +3,14 @@ //! Helpers for implementing runtime api use snowbridge_core::AgentId; -use xcm::{prelude::*, VersionedMultiLocation}; +use xcm::{prelude::*, VersionedLocation}; use crate::{agent_id_of, Config}; -pub fn agent_id(location: VersionedMultiLocation) -> Option +pub fn agent_id(location: VersionedLocation) -> Option where Runtime: Config, { - let location: MultiLocation = location.try_into().ok()?; + let location: Location = location.try_into().ok()?; agent_id_of::(&location).ok() } diff --git a/bridges/snowbridge/parachain/pallets/system/src/benchmarking.rs b/bridges/snowbridge/parachain/pallets/system/src/benchmarking.rs index 8d26408b38e..ef908ad6a3f 100644 --- a/bridges/snowbridge/parachain/pallets/system/src/benchmarking.rs +++ b/bridges/snowbridge/parachain/pallets/system/src/benchmarking.rs @@ -63,7 +63,7 @@ mod benchmarks { #[benchmark] fn create_agent() -> Result<(), BenchmarkError> { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let origin = T::Helper::make_xcm_origin(origin_location); fund_sovereign_account::(origin_para_id.into())?; @@ -76,7 +76,7 @@ mod benchmarks { #[benchmark] fn create_channel() -> Result<(), BenchmarkError> { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let origin = T::Helper::make_xcm_origin(origin_location); fund_sovereign_account::(origin_para_id.into())?; @@ -91,7 +91,7 @@ mod benchmarks { #[benchmark] fn update_channel() -> Result<(), BenchmarkError> { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let origin = T::Helper::make_xcm_origin(origin_location); fund_sovereign_account::(origin_para_id.into())?; SnowbridgeControl::::create_agent(origin.clone())?; @@ -106,7 +106,7 @@ mod benchmarks { #[benchmark] fn force_update_channel() -> Result<(), BenchmarkError> { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let origin = T::Helper::make_xcm_origin(origin_location); let channel_id: ChannelId = ParaId::from(origin_para_id).into(); @@ -123,7 +123,7 @@ mod benchmarks { #[benchmark] fn transfer_native_from_agent() -> Result<(), BenchmarkError> { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let origin = T::Helper::make_xcm_origin(origin_location); fund_sovereign_account::(origin_para_id.into())?; SnowbridgeControl::::create_agent(origin.clone())?; @@ -138,12 +138,12 @@ mod benchmarks { #[benchmark] fn force_transfer_native_from_agent() -> Result<(), BenchmarkError> { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; - let origin = T::Helper::make_xcm_origin(origin_location); + let origin_location = Location::new(1, [Parachain(origin_para_id)]); + let origin = T::Helper::make_xcm_origin(origin_location.clone()); fund_sovereign_account::(origin_para_id.into())?; SnowbridgeControl::::create_agent(origin.clone())?; - let versioned_location: VersionedMultiLocation = origin_location.into(); + let versioned_location: VersionedLocation = origin_location.into(); #[extrinsic_call] _(RawOrigin::Root, Box::new(versioned_location), H160::default(), 1); diff --git a/bridges/snowbridge/parachain/pallets/system/src/lib.rs b/bridges/snowbridge/parachain/pallets/system/src/lib.rs index 0042093ee66..e742bd8e110 100644 --- a/bridges/snowbridge/parachain/pallets/system/src/lib.rs +++ b/bridges/snowbridge/parachain/pallets/system/src/lib.rs @@ -87,12 +87,12 @@ pub type AccountIdOf = ::AccountId; pub type PricingParametersOf = PricingParametersRecord>; /// Ensure origin location is a sibling -fn ensure_sibling(location: &MultiLocation) -> Result<(ParaId, H256), DispatchError> +fn ensure_sibling(location: &Location) -> Result<(ParaId, H256), DispatchError> where T: Config, { - match location { - MultiLocation { parents: 1, interior: X1(Parachain(para_id)) } => { + match location.unpack() { + (1, [Parachain(para_id)]) => { let agent_id = agent_id_of::(location)?; Ok(((*para_id).into(), agent_id)) }, @@ -101,7 +101,7 @@ where } /// Hash the location to produce an agent id -fn agent_id_of(location: &MultiLocation) -> Result { +fn agent_id_of(location: &Location) -> Result { T::AgentIdOf::convert_location(location).ok_or(Error::::LocationConversionFailed.into()) } @@ -110,7 +110,7 @@ pub trait BenchmarkHelper where O: OriginTrait, { - fn make_xcm_origin(location: MultiLocation) -> O; + fn make_xcm_origin(location: Location) -> O; } /// Whether a fee should be withdrawn to an account for sending an outbound message @@ -145,9 +145,9 @@ pub mod pallet { type OutboundQueue: SendMessage>; /// Origin check for XCM locations that can create agents - type SiblingOrigin: EnsureOrigin; + type SiblingOrigin: EnsureOrigin; - /// Converts MultiLocation to AgentId + /// Converts Location to AgentId type AgentIdOf: ConvertLocation; /// Token reserved for control operations @@ -180,7 +180,7 @@ pub mod pallet { }, /// An CreateAgent message was sent to the Gateway CreateAgent { - location: Box, + location: Box, agent_id: AgentId, }, /// An CreateChannel message was sent to the Gateway @@ -299,7 +299,7 @@ pub mod pallet { /// /// Fee required: No /// - /// - `origin`: Must be `MultiLocation` + /// - `origin`: Must be `Location` #[pallet::call_index(1)] #[pallet::weight((T::WeightInfo::set_operating_mode(), DispatchClass::Operational))] pub fn set_operating_mode(origin: OriginFor, mode: OperatingMode) -> DispatchResult { @@ -342,11 +342,11 @@ pub mod pallet { /// /// Fee required: Yes /// - /// - `origin`: Must be `MultiLocation` of a sibling parachain + /// - `origin`: Must be `Location` of a sibling parachain #[pallet::call_index(3)] #[pallet::weight(T::WeightInfo::create_agent())] pub fn create_agent(origin: OriginFor) -> DispatchResult { - let origin_location: MultiLocation = T::SiblingOrigin::ensure_origin(origin)?; + let origin_location: Location = T::SiblingOrigin::ensure_origin(origin)?; // Ensure that origin location is some consensus system on a sibling parachain let (para_id, agent_id) = ensure_sibling::(&origin_location)?; @@ -375,12 +375,12 @@ pub mod pallet { /// /// The message is sent over the bridge on BridgeHub's own channel to the Gateway. /// - /// - `origin`: Must be `MultiLocation` + /// - `origin`: Must be `Location` /// - `mode`: Initial operating mode of the channel #[pallet::call_index(4)] #[pallet::weight(T::WeightInfo::create_channel())] pub fn create_channel(origin: OriginFor, mode: OperatingMode) -> DispatchResult { - let origin_location: MultiLocation = T::SiblingOrigin::ensure_origin(origin)?; + let origin_location: Location = T::SiblingOrigin::ensure_origin(origin)?; // Ensure that origin location is a sibling parachain let (para_id, agent_id) = ensure_sibling::(&origin_location)?; @@ -407,12 +407,12 @@ pub mod pallet { /// /// A partial fee will be charged for local processing only. /// - /// - `origin`: Must be `MultiLocation` + /// - `origin`: Must be `Location` /// - `mode`: Initial operating mode of the channel #[pallet::call_index(5)] #[pallet::weight(T::WeightInfo::update_channel())] pub fn update_channel(origin: OriginFor, mode: OperatingMode) -> DispatchResult { - let origin_location: MultiLocation = T::SiblingOrigin::ensure_origin(origin)?; + let origin_location: Location = T::SiblingOrigin::ensure_origin(origin)?; // Ensure that origin location is a sibling parachain let (para_id, _) = ensure_sibling::(&origin_location)?; @@ -461,7 +461,7 @@ pub mod pallet { /// /// A partial fee will be charged for local processing only. /// - /// - `origin`: Must be `MultiLocation` + /// - `origin`: Must be `Location` #[pallet::call_index(7)] #[pallet::weight(T::WeightInfo::transfer_native_from_agent())] pub fn transfer_native_from_agent( @@ -469,7 +469,7 @@ pub mod pallet { recipient: H160, amount: u128, ) -> DispatchResult { - let origin_location: MultiLocation = T::SiblingOrigin::ensure_origin(origin)?; + let origin_location: Location = T::SiblingOrigin::ensure_origin(origin)?; // Ensure that origin location is some consensus system on a sibling parachain let (para_id, agent_id) = ensure_sibling::(&origin_location)?; @@ -501,14 +501,14 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::force_transfer_native_from_agent())] pub fn force_transfer_native_from_agent( origin: OriginFor, - location: Box, + location: Box, recipient: H160, amount: u128, ) -> DispatchResult { ensure_root(origin)?; // Ensure that location is some consensus system on a sibling parachain - let location: MultiLocation = + let location: Location = (*location).try_into().map_err(|_| Error::::UnsupportedLocationVersion)?; let (_, agent_id) = ensure_sibling::(&location).map_err(|_| Error::::InvalidLocation)?; @@ -621,8 +621,8 @@ pub mod pallet { /// Initializes agents and channels. pub fn initialize(para_id: ParaId, asset_hub_para_id: ParaId) -> Result<(), DispatchError> { // Asset Hub - let asset_hub_location: MultiLocation = - ParentThen(X1(Parachain(asset_hub_para_id.into()))).into(); + let asset_hub_location: Location = + ParentThen(Parachain(asset_hub_para_id.into()).into()).into(); let asset_hub_agent_id = agent_id_of::(&asset_hub_location)?; let asset_hub_channel_id: ChannelId = asset_hub_para_id.into(); Agents::::insert(asset_hub_agent_id, ()); @@ -632,7 +632,7 @@ pub mod pallet { ); // Governance channels - let bridge_hub_agent_id = agent_id_of::(&MultiLocation::here())?; + let bridge_hub_agent_id = agent_id_of::(&Location::here())?; // Agent for BridgeHub Agents::::insert(bridge_hub_agent_id, ()); diff --git a/bridges/snowbridge/parachain/pallets/system/src/mock.rs b/bridges/snowbridge/parachain/pallets/system/src/mock.rs index bb9bae6b56d..bc229578132 100644 --- a/bridges/snowbridge/parachain/pallets/system/src/mock.rs +++ b/bridges/snowbridge/parachain/pallets/system/src/mock.rs @@ -49,22 +49,22 @@ mod pallet_xcm_origin { // Insert this custom Origin into the aggregate RuntimeOrigin #[pallet::origin] #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub struct Origin(pub MultiLocation); + pub struct Origin(pub Location); - impl From for Origin { - fn from(location: MultiLocation) -> Origin { + impl From for Origin { + fn from(location: Location) -> Origin { Origin(location) } } - /// `EnsureOrigin` implementation succeeding with a `MultiLocation` value to recognize and + /// `EnsureOrigin` implementation succeeding with a `Location` value to recognize and /// filter the contained location pub struct EnsureXcm(PhantomData); - impl, F: Contains> EnsureOrigin for EnsureXcm + impl, F: Contains> EnsureOrigin for EnsureXcm where O::PalletsOrigin: From + TryInto, { - type Success = MultiLocation; + type Success = Location; fn try_origin(outer: O) -> Result { outer.try_with_caller(|caller| { @@ -77,7 +77,7 @@ mod pallet_xcm_origin { #[cfg(feature = "runtime-benchmarks")] fn try_successful_origin() -> Result { - Ok(O::from(Origin(MultiLocation { parents: 1, interior: X1(Parachain(2000)) }))) + Ok(O::from(Origin(Location::new(1, [Parachain(2000)])))) } } } @@ -186,9 +186,9 @@ parameter_types! { pub const SS58Prefix: u8 = 42; pub const AnyNetwork: Option = None; pub const RelayNetwork: Option = Some(NetworkId::Kusama); - pub const RelayLocation: MultiLocation = MultiLocation::parent(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(1013)); + pub const RelayLocation: Location = Location::parent(); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(1013)].into(); } pub const DOT: u128 = 10_000_000_000; @@ -211,7 +211,7 @@ parameter_types! { #[cfg(feature = "runtime-benchmarks")] impl BenchmarkHelper for () { - fn make_xcm_origin(location: MultiLocation) -> RuntimeOrigin { + fn make_xcm_origin(location: Location) -> RuntimeOrigin { RuntimeOrigin::from(pallet_xcm_origin::Origin(location)) } } @@ -260,11 +260,11 @@ pub fn new_test_ext(genesis_build: bool) -> sp_io::TestExternalities { // Test helpers -pub fn make_xcm_origin(location: MultiLocation) -> RuntimeOrigin { +pub fn make_xcm_origin(location: Location) -> RuntimeOrigin { pallet_xcm_origin::Origin(location).into() } -pub fn make_agent_id(location: MultiLocation) -> AgentId { +pub fn make_agent_id(location: Location) -> AgentId { ::AgentIdOf::convert_location(&location) .expect("convert location") } diff --git a/bridges/snowbridge/parachain/pallets/system/src/tests.rs b/bridges/snowbridge/parachain/pallets/system/src/tests.rs index e07481c1e33..8b417c258ea 100644 --- a/bridges/snowbridge/parachain/pallets/system/src/tests.rs +++ b/bridges/snowbridge/parachain/pallets/system/src/tests.rs @@ -11,8 +11,8 @@ use sp_runtime::{AccountId32, DispatchError::BadOrigin, TokenError}; fn create_agent() { new_test_ext(true).execute_with(|| { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; - let agent_id = make_agent_id(origin_location); + let origin_location = Location::new(1, [Parachain(origin_para_id)]); + let agent_id = make_agent_id(origin_location.clone()); let sovereign_account = sibling_sovereign_account::(origin_para_id.into()); // fund sovereign account of origin @@ -30,7 +30,7 @@ fn create_agent() { #[test] fn test_agent_for_here() { new_test_ext(true).execute_with(|| { - let origin_location = MultiLocation::here(); + let origin_location = Location::here(); let agent_id = make_agent_id(origin_location); assert_eq!( agent_id, @@ -42,7 +42,7 @@ fn test_agent_for_here() { #[test] fn create_agent_fails_on_funds_unavailable() { new_test_ext(true).execute_with(|| { - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(2000)) }; + let origin_location = Location::new(1, [Parachain(2000)]); let origin = make_xcm_origin(origin_location); // Reset balance of sovereign_account to zero so to trigger the FundsUnavailable error let sovereign_account = sibling_sovereign_account::(2000.into()); @@ -56,19 +56,16 @@ fn create_agent_bad_origin() { new_test_ext(true).execute_with(|| { // relay chain location not allowed assert_noop!( - EthereumSystem::create_agent(make_xcm_origin(MultiLocation { - parents: 1, - interior: Here, - })), + EthereumSystem::create_agent(make_xcm_origin(Location::new(1, [],))), BadOrigin, ); // local account location not allowed assert_noop!( - EthereumSystem::create_agent(make_xcm_origin(MultiLocation { - parents: 0, - interior: X1(Junction::AccountId32 { network: None, id: [67u8; 32] }), - })), + EthereumSystem::create_agent(make_xcm_origin(Location::new( + 0, + [Junction::AccountId32 { network: None, id: [67u8; 32] }], + ))), BadOrigin, ); @@ -243,7 +240,7 @@ fn set_token_transfer_fees_invalid() { fn create_channel() { new_test_ext(true).execute_with(|| { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let sovereign_account = sibling_sovereign_account::(origin_para_id.into()); let origin = make_xcm_origin(origin_location); @@ -259,7 +256,7 @@ fn create_channel() { fn create_channel_fail_already_exists() { new_test_ext(true).execute_with(|| { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let sovereign_account = sibling_sovereign_account::(origin_para_id.into()); let origin = make_xcm_origin(origin_location); @@ -282,7 +279,7 @@ fn create_channel_bad_origin() { // relay chain location not allowed assert_noop!( EthereumSystem::create_channel( - make_xcm_origin(MultiLocation { parents: 1, interior: Here }), + make_xcm_origin(Location::new(1, [])), OperatingMode::Normal, ), BadOrigin, @@ -291,13 +288,10 @@ fn create_channel_bad_origin() { // child of sibling location not allowed assert_noop!( EthereumSystem::create_channel( - make_xcm_origin(MultiLocation { - parents: 1, - interior: X2( - Parachain(2000), - Junction::AccountId32 { network: None, id: [67u8; 32] } - ), - }), + make_xcm_origin(Location::new( + 1, + [Parachain(2000), Junction::AccountId32 { network: None, id: [67u8; 32] }], + )), OperatingMode::Normal, ), BadOrigin, @@ -306,10 +300,10 @@ fn create_channel_bad_origin() { // local account location not allowed assert_noop!( EthereumSystem::create_channel( - make_xcm_origin(MultiLocation { - parents: 0, - interior: X1(Junction::AccountId32 { network: None, id: [67u8; 32] }), - }), + make_xcm_origin(Location::new( + 0, + [Junction::AccountId32 { network: None, id: [67u8; 32] }], + )), OperatingMode::Normal, ), BadOrigin, @@ -333,7 +327,7 @@ fn create_channel_bad_origin() { fn update_channel() { new_test_ext(true).execute_with(|| { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let sovereign_account = sibling_sovereign_account::(origin_para_id.into()); let origin = make_xcm_origin(origin_location); @@ -359,23 +353,17 @@ fn update_channel_bad_origin() { // relay chain location not allowed assert_noop!( - EthereumSystem::update_channel( - make_xcm_origin(MultiLocation { parents: 1, interior: Here }), - mode, - ), + EthereumSystem::update_channel(make_xcm_origin(Location::new(1, [])), mode,), BadOrigin, ); // child of sibling location not allowed assert_noop!( EthereumSystem::update_channel( - make_xcm_origin(MultiLocation { - parents: 1, - interior: X2( - Parachain(2000), - Junction::AccountId32 { network: None, id: [67u8; 32] } - ), - }), + make_xcm_origin(Location::new( + 1, + [Parachain(2000), Junction::AccountId32 { network: None, id: [67u8; 32] }], + )), mode, ), BadOrigin, @@ -384,10 +372,10 @@ fn update_channel_bad_origin() { // local account location not allowed assert_noop!( EthereumSystem::update_channel( - make_xcm_origin(MultiLocation { - parents: 0, - interior: X1(Junction::AccountId32 { network: None, id: [67u8; 32] }), - }), + make_xcm_origin(Location::new( + 0, + [Junction::AccountId32 { network: None, id: [67u8; 32] }], + )), mode, ), BadOrigin, @@ -407,7 +395,7 @@ fn update_channel_bad_origin() { #[test] fn update_channel_fails_not_exist() { new_test_ext(true).execute_with(|| { - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(2000)) }; + let origin_location = Location::new(1, [Parachain(2000)]); let origin = make_xcm_origin(origin_location); // Now try to update it @@ -422,7 +410,7 @@ fn update_channel_fails_not_exist() { fn force_update_channel() { new_test_ext(true).execute_with(|| { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let sovereign_account = sibling_sovereign_account::(origin_para_id.into()); let origin = make_xcm_origin(origin_location); @@ -468,8 +456,8 @@ fn force_update_channel_bad_origin() { #[test] fn transfer_native_from_agent() { new_test_ext(true).execute_with(|| { - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(2000)) }; - let origin = make_xcm_origin(origin_location); + let origin_location = Location::new(1, [Parachain(2000)]); + let origin = make_xcm_origin(origin_location.clone()); let recipient: H160 = [27u8; 20].into(); let amount = 103435; @@ -477,7 +465,7 @@ fn transfer_native_from_agent() { assert_ok!(EthereumSystem::create_agent(origin.clone())); assert_ok!(EthereumSystem::create_channel(origin, OperatingMode::Normal)); - let origin = make_xcm_origin(origin_location); + let origin = make_xcm_origin(origin_location.clone()); assert_ok!(EthereumSystem::transfer_native_from_agent(origin, recipient, amount),); System::assert_last_event(RuntimeEvent::EthereumSystem( @@ -494,13 +482,13 @@ fn transfer_native_from_agent() { fn force_transfer_native_from_agent() { new_test_ext(true).execute_with(|| { let origin = RuntimeOrigin::root(); - let location = MultiLocation { parents: 1, interior: X1(Parachain(2000)) }; - let versioned_location: Box = Box::new(location.into()); + let location = Location::new(1, [Parachain(2000)]); + let versioned_location: Box = Box::new(location.clone().into()); let recipient: H160 = [27u8; 20].into(); let amount = 103435; // First create the agent - Agents::::insert(make_agent_id(location), ()); + Agents::::insert(make_agent_id(location.clone()), ()); assert_ok!(EthereumSystem::force_transfer_native_from_agent( origin, @@ -530,13 +518,10 @@ fn force_transfer_native_from_agent_bad_origin() { EthereumSystem::force_transfer_native_from_agent( RuntimeOrigin::signed([14; 32].into()), Box::new( - MultiLocation { - parents: 1, - interior: X2( - Parachain(2000), - Junction::AccountId32 { network: None, id: [67u8; 32] } - ), - } + Location::new( + 1, + [Parachain(2000), Junction::AccountId32 { network: None, id: [67u8; 32] }], + ) .into() ), recipient, @@ -571,8 +556,8 @@ fn check_sibling_sovereign_account() { fn charge_fee_for_create_agent() { new_test_ext(true).execute_with(|| { let para_id: u32 = TestParaId::get(); - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(para_id)) }; - let origin = make_xcm_origin(origin_location); + let origin_location = Location::new(1, [Parachain(para_id)]); + let origin = make_xcm_origin(origin_location.clone()); let sovereign_account = sibling_sovereign_account::(para_id.into()); let (_, agent_id) = ensure_sibling::(&origin_location).unwrap(); @@ -605,10 +590,10 @@ fn charge_fee_for_create_agent() { fn charge_fee_for_transfer_native_from_agent() { new_test_ext(true).execute_with(|| { let para_id: u32 = TestParaId::get(); - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(para_id)) }; + let origin_location = Location::new(1, [Parachain(para_id)]); let recipient: H160 = [27u8; 20].into(); let amount = 103435; - let origin = make_xcm_origin(origin_location); + let origin = make_xcm_origin(origin_location.clone()); let (_, agent_id) = ensure_sibling::(&origin_location).unwrap(); let sovereign_account = sibling_sovereign_account::(para_id.into()); diff --git a/bridges/snowbridge/parachain/primitives/core/src/lib.rs b/bridges/snowbridge/parachain/primitives/core/src/lib.rs index ecbc3bb365f..a464557a72b 100644 --- a/bridges/snowbridge/parachain/primitives/core/src/lib.rs +++ b/bridges/snowbridge/parachain/primitives/core/src/lib.rs @@ -28,11 +28,7 @@ use sp_core::H256; use sp_io::hashing::keccak_256; use sp_runtime::{traits::AccountIdConversion, RuntimeDebug}; use sp_std::prelude::*; -use xcm::prelude::{ - Junction::Parachain, - Junctions::{Here, X1}, - MultiLocation, -}; +use xcm::prelude::{Junction::Parachain, Location}; use xcm_builder::{DescribeAllTerminal, DescribeFamily, DescribeLocation, HashedDescription}; /// The ID of an agent contract @@ -53,9 +49,9 @@ pub fn sibling_sovereign_account_raw(para_id: ParaId) -> [u8; 32] { } pub struct AllowSiblingsOnly; -impl Contains for AllowSiblingsOnly { - fn contains(location: &MultiLocation) -> bool { - matches!(location, MultiLocation { parents: 1, interior: X1(Parachain(_)) }) +impl Contains for AllowSiblingsOnly { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [Parachain(_)])) } } @@ -161,14 +157,14 @@ pub const SECONDARY_GOVERNANCE_CHANNEL: ChannelId = pub struct DescribeHere; impl DescribeLocation for DescribeHere { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, l.interior) { - (0, Here) => Some(Vec::::new().encode()), + fn describe_location(l: &Location) -> Option> { + match l.unpack() { + (0, []) => Some(Vec::::new().encode()), _ => None, } } } -/// Creates an AgentId from a MultiLocation. An AgentId is a unique mapping to a Agent contract on -/// Ethereum which acts as the sovereign account for the MultiLocation. +/// Creates an AgentId from a Location. An AgentId is a unique mapping to a Agent contract on +/// Ethereum which acts as the sovereign account for the Location. pub type AgentIdOf = HashedDescription)>; diff --git a/bridges/snowbridge/parachain/primitives/core/tests/mod.rs b/bridges/snowbridge/parachain/primitives/core/tests/mod.rs index 2da5d2df182..c91063a8148 100644 --- a/bridges/snowbridge/parachain/primitives/core/tests/mod.rs +++ b/bridges/snowbridge/parachain/primitives/core/tests/mod.rs @@ -2,12 +2,12 @@ mod tests { use frame_support::traits::Contains; use snowbridge_core::AllowSiblingsOnly; - use xcm::prelude::{Junction::Parachain, Junctions::X1, MultiLocation}; + use xcm::prelude::{Junction::Parachain, Location}; #[test] fn allow_siblings_predicate_only_allows_siblings() { - let sibling = MultiLocation::new(1, X1(Parachain(1000))); - let child = MultiLocation::new(0, X1(Parachain(1000))); + let sibling = Location::new(1, [Parachain(1000)]); + let child = Location::new(0, [Parachain(1000)]); assert!(AllowSiblingsOnly::contains(&sibling), "Sibling returns true."); assert!(!AllowSiblingsOnly::contains(&child), "Child returns false."); } diff --git a/bridges/snowbridge/parachain/primitives/router/src/inbound/mod.rs b/bridges/snowbridge/parachain/primitives/router/src/inbound/mod.rs index a07e0eae5d7..c20554c6d18 100644 --- a/bridges/snowbridge/parachain/primitives/router/src/inbound/mod.rs +++ b/bridges/snowbridge/parachain/primitives/router/src/inbound/mod.rs @@ -161,13 +161,13 @@ where { fn convert_register_token(chain_id: u64, token: H160, fee: u128) -> (Xcm<()>, Balance) { let network = Ethereum { chain_id }; - let xcm_fee: MultiAsset = (MultiLocation::parent(), fee).into(); - let deposit: MultiAsset = (MultiLocation::parent(), CreateAssetDeposit::get()).into(); + let xcm_fee: Asset = (Location::parent(), fee).into(); + let deposit: Asset = (Location::parent(), CreateAssetDeposit::get()).into(); let total_amount = fee + CreateAssetDeposit::get(); - let total: MultiAsset = (MultiLocation::parent(), total_amount).into(); + let total: Asset = (Location::parent(), total_amount).into(); - let bridge_location: MultiLocation = (Parent, Parent, GlobalConsensus(network)).into(); + let bridge_location: Location = (Parent, Parent, GlobalConsensus(network)).into(); let owner = GlobalConsensusEthereumConvertsFor::<[u8; 32]>::from_chain_id(&chain_id); let asset_id = Self::convert_token_address(network, token); @@ -182,7 +182,7 @@ where // Fund the snowbridge sovereign with the required deposit for creation. DepositAsset { assets: Definite(deposit.into()), beneficiary: bridge_location }, // Only our inbound-queue pallet is allowed to invoke `UniversalOrigin` - DescendOrigin(X1(PalletInstance(inbound_queue_pallet_index))), + DescendOrigin(PalletInstance(inbound_queue_pallet_index).into()), // Change origin to the bridge. UniversalOrigin(GlobalConsensus(network)), // Call create_asset on foreign assets pallet. @@ -216,40 +216,37 @@ where asset_hub_fee: u128, ) -> (Xcm<()>, Balance) { let network = Ethereum { chain_id }; - let asset_hub_fee_asset: MultiAsset = (MultiLocation::parent(), asset_hub_fee).into(); - let asset: MultiAsset = (Self::convert_token_address(network, token), amount).into(); + let asset_hub_fee_asset: Asset = (Location::parent(), asset_hub_fee).into(); + let asset: Asset = (Self::convert_token_address(network, token), amount).into(); let (dest_para_id, beneficiary, dest_para_fee) = match destination { // Final destination is a 32-byte account on AssetHub - Destination::AccountId32 { id } => ( - None, - MultiLocation { parents: 0, interior: X1(AccountId32 { network: None, id }) }, - 0, - ), + Destination::AccountId32 { id } => + (None, Location::new(0, [AccountId32 { network: None, id }]), 0), // Final destination is a 32-byte account on a sibling of AssetHub Destination::ForeignAccountId32 { para_id, id, fee } => ( Some(para_id), - MultiLocation { parents: 0, interior: X1(AccountId32 { network: None, id }) }, + Location::new(0, [AccountId32 { network: None, id }]), // Total fee needs to cover execution on AssetHub and Sibling fee, ), // Final destination is a 20-byte account on a sibling of AssetHub Destination::ForeignAccountId20 { para_id, id, fee } => ( Some(para_id), - MultiLocation { parents: 0, interior: X1(AccountKey20 { network: None, key: id }) }, + Location::new(0, [AccountKey20 { network: None, key: id }]), // Total fee needs to cover execution on AssetHub and Sibling fee, ), }; let total_fees = asset_hub_fee.saturating_add(dest_para_fee); - let total_fee_asset: MultiAsset = (MultiLocation::parent(), total_fees).into(); + let total_fee_asset: Asset = (Location::parent(), total_fees).into(); let inbound_queue_pallet_index = InboundQueuePalletInstance::get(); let mut instructions = vec![ ReceiveTeleportedAsset(total_fee_asset.into()), BuyExecution { fees: asset_hub_fee_asset, weight_limit: Unlimited }, - DescendOrigin(X1(PalletInstance(inbound_queue_pallet_index))), + DescendOrigin(PalletInstance(inbound_queue_pallet_index).into()), UniversalOrigin(GlobalConsensus(network)), ReserveAssetDeposited(asset.clone().into()), ClearOrigin, @@ -257,14 +254,13 @@ where match dest_para_id { Some(dest_para_id) => { - let dest_para_fee_asset: MultiAsset = - (MultiLocation::parent(), dest_para_fee).into(); + let dest_para_fee_asset: Asset = (Location::parent(), dest_para_fee).into(); instructions.extend(vec![ // Perform a deposit reserve to send to destination chain. DepositReserveAsset { assets: Definite(vec![dest_para_fee_asset.clone(), asset.clone()].into()), - dest: MultiLocation { parents: 1, interior: X1(Parachain(dest_para_id)) }, + dest: Location::new(1, [Parachain(dest_para_id)]), xcm: vec![ // Buy execution on target. BuyExecution { fees: dest_para_fee_asset, weight_limit: Unlimited }, @@ -286,15 +282,12 @@ where (instructions.into(), total_fees.into()) } - // Convert ERC20 token address to a Multilocation that can be understood by Assets Hub. - fn convert_token_address(network: NetworkId, token: H160) -> MultiLocation { - MultiLocation { - parents: 2, - interior: X2( - GlobalConsensus(network), - AccountKey20 { network: None, key: token.into() }, - ), - } + // Convert ERC20 token address to a location that can be understood by Assets Hub. + fn convert_token_address(network: NetworkId, token: H160) -> Location { + Location::new( + 2, + [GlobalConsensus(network), AccountKey20 { network: None, key: token.into() }], + ) } } @@ -303,12 +296,11 @@ impl ConvertLocation for GlobalConsensusEthereumConvertsFo where AccountId: From<[u8; 32]> + Clone, { - fn convert_location(location: &MultiLocation) -> Option { - if let MultiLocation { interior: X1(GlobalConsensus(Ethereum { chain_id })), .. } = location - { - Some(Self::from_chain_id(chain_id).into()) - } else { - None + fn convert_location(location: &Location) -> Option { + match location.unpack() { + (_, [GlobalConsensus(Ethereum { chain_id })]) => + Some(Self::from_chain_id(chain_id).into()), + _ => None, } } } diff --git a/bridges/snowbridge/parachain/primitives/router/src/inbound/tests.rs b/bridges/snowbridge/parachain/primitives/router/src/inbound/tests.rs index 8c96c13cf22..c46b88a84a4 100644 --- a/bridges/snowbridge/parachain/primitives/router/src/inbound/tests.rs +++ b/bridges/snowbridge/parachain/primitives/router/src/inbound/tests.rs @@ -2,7 +2,7 @@ use super::GlobalConsensusEthereumConvertsFor; use crate::inbound::CallIndex; use frame_support::parameter_types; use hex_literal::hex; -use xcm::v3::prelude::*; +use xcm::v4::prelude::*; use xcm_executor::traits::ConvertLocation; const NETWORK: NetworkId = Ethereum { chain_id: 11155111 }; @@ -20,7 +20,7 @@ parameter_types! { fn test_contract_location_with_network_converts_successfully() { let expected_account: [u8; 32] = hex!("ce796ae65569a670d0c1cc1ac12515a3ce21b5fbf729d63d7b289baad070139d"); - let contract_location = MultiLocation { parents: 2, interior: X1(GlobalConsensus(NETWORK)) }; + let contract_location = Location::new(2, [GlobalConsensus(NETWORK)]); let account = GlobalConsensusEthereumConvertsFor::<[u8; 32]>::convert_location(&contract_location) @@ -31,8 +31,7 @@ fn test_contract_location_with_network_converts_successfully() { #[test] fn test_contract_location_with_incorrect_location_fails_convert() { - let contract_location = - MultiLocation { parents: 2, interior: X2(GlobalConsensus(Polkadot), Parachain(1000)) }; + let contract_location = Location::new(2, [GlobalConsensus(Polkadot), Parachain(1000)]); assert_eq!( GlobalConsensusEthereumConvertsFor::<[u8; 32]>::convert_location(&contract_location), diff --git a/bridges/snowbridge/parachain/primitives/router/src/outbound/mod.rs b/bridges/snowbridge/parachain/primitives/router/src/outbound/mod.rs index c7f2f440834..21823992db7 100644 --- a/bridges/snowbridge/parachain/primitives/router/src/outbound/mod.rs +++ b/bridges/snowbridge/parachain/primitives/router/src/outbound/mod.rs @@ -16,7 +16,7 @@ use snowbridge_core::{ }; use sp_core::{H160, H256}; use sp_std::{iter::Peekable, marker::PhantomData, prelude::*}; -use xcm::v3::prelude::*; +use xcm::v4::prelude::*; use xcm_executor::traits::{ConvertLocation, ExportXcm}; pub struct EthereumBlobExporter< @@ -29,7 +29,7 @@ pub struct EthereumBlobExporter< impl ExportXcm for EthereumBlobExporter where - UniversalLocation: Get, + UniversalLocation: Get, EthereumNetwork: Get, OutboundQueue: SendMessage, AgentHashedDescription: ConvertLocation, @@ -39,8 +39,8 @@ where fn validate( network: NetworkId, _channel: u32, - universal_source: &mut Option, - destination: &mut Option, + universal_source: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult { let expected_network = EthereumNetwork::get(); @@ -74,8 +74,8 @@ where return Err(SendError::NotApplicable) } - let para_id = match local_sub { - X1(Parachain(para_id)) => para_id, + let para_id = match local_sub.as_slice() { + [Parachain(para_id)] => *para_id, _ => { log::error!(target: "xcm::ethereum_blob_exporter", "could not get parachain id from universal source '{local_sub:?}'."); return Err(SendError::MissingArgument) @@ -93,7 +93,7 @@ where SendError::Unroutable })?; - let source_location: MultiLocation = MultiLocation { parents: 1, interior: local_sub }; + let source_location = Location::new(1, local_sub.clone()); let agent_id = match AgentHashedDescription::convert_location(&source_location) { Some(id) => id, None => { @@ -116,8 +116,8 @@ where SendError::Unroutable })?; - // convert fee to MultiAsset - let fee = MultiAsset::from((MultiLocation::parent(), fee.total())).into(); + // convert fee to Asset + let fee = Asset::from((Location::parent(), fee.total())).into(); Ok(((ticket.encode(), message_id), fee)) } @@ -216,8 +216,8 @@ impl<'a, Call> XcmConverter<'a, Call> { // assert that the beneficiary is AccountKey20. let recipient = match_expression!( - beneficiary, - MultiLocation { parents: 0, interior: X1(AccountKey20 { network, key }) } + beneficiary.unpack(), + (0, [AccountKey20 { network, key }]) if self.network_matches(network), H160(*key) ) @@ -245,14 +245,15 @@ impl<'a, Call> XcmConverter<'a, Call> { } } - let (token, amount) = match_expression!( - reserve_asset, - MultiAsset { - id: Concrete(MultiLocation { parents: 0, interior: X1(AccountKey20 { network , key })}), - fun: Fungible(amount) - } if self.network_matches(network), - (H160(*key), *amount) - ) + let (token, amount) = match reserve_asset { + Asset { id: AssetId(inner_location), fun: Fungible(amount) } => + match inner_location.unpack() { + (0, [AccountKey20 { network, key }]) if self.network_matches(network) => + Some((H160(*key), *amount)), + _ => None, + }, + _ => None, + } .ok_or(AssetResolutionFailed)?; // transfer amount must be greater than 0. diff --git a/bridges/snowbridge/parachain/primitives/router/src/outbound/tests.rs b/bridges/snowbridge/parachain/primitives/router/src/outbound/tests.rs index 153d934c390..111243bb45a 100644 --- a/bridges/snowbridge/parachain/primitives/router/src/outbound/tests.rs +++ b/bridges/snowbridge/parachain/primitives/router/src/outbound/tests.rs @@ -11,7 +11,7 @@ use super::*; parameter_types! { const MaxMessageSize: u32 = u32::MAX; const RelayNetwork: NetworkId = Polkadot; - const UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(RelayNetwork::get()), Parachain(1013)); + UniversalLocation: InteriorLocation = [GlobalConsensus(RelayNetwork::get()), Parachain(1013)].into(); const BridgedNetwork: NetworkId = Ethereum{ chain_id: 1 }; const NonBridgedNetwork: NetworkId = Ethereum{ chain_id: 2 }; } @@ -61,8 +61,8 @@ impl SendMessageFeeProvider for MockErrOutboundQueue { fn exporter_validate_with_unknown_network_yields_not_applicable() { let network = Ethereum { chain_id: 1337 }; let channel: u32 = 0; - let mut universal_source: Option = None; - let mut destination: Option = None; + let mut universal_source: Option = None; + let mut destination: Option = None; let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -80,8 +80,8 @@ fn exporter_validate_with_unknown_network_yields_not_applicable() { fn exporter_validate_with_invalid_destination_yields_missing_argument() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = None; - let mut destination: Option = None; + let mut universal_source: Option = None; + let mut destination: Option = None; let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -99,10 +99,11 @@ fn exporter_validate_with_invalid_destination_yields_missing_argument() { fn exporter_validate_with_x8_destination_yields_not_applicable() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = None; - let mut destination: Option = Some(X8( - OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, - )); + let mut universal_source: Option = None; + let mut destination: Option = Some( + [OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild] + .into(), + ); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -120,8 +121,8 @@ fn exporter_validate_with_x8_destination_yields_not_applicable() { fn exporter_validate_without_universal_source_yields_missing_argument() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = None; - let mut destination: Option = Here.into(); + let mut universal_source: Option = None; + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -139,8 +140,8 @@ fn exporter_validate_without_universal_source_yields_missing_argument() { fn exporter_validate_without_global_universal_location_yields_unroutable() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = Here.into(); - let mut destination: Option = Here.into(); + let mut universal_source: Option = Here.into(); + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -158,8 +159,8 @@ fn exporter_validate_without_global_universal_location_yields_unroutable() { fn exporter_validate_without_global_bridge_location_yields_not_applicable() { let network = NonBridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = Here.into(); - let mut destination: Option = Here.into(); + let mut universal_source: Option = Here.into(); + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -177,9 +178,9 @@ fn exporter_validate_without_global_bridge_location_yields_not_applicable() { fn exporter_validate_with_remote_universal_source_yields_not_applicable() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = - Some(X2(GlobalConsensus(Kusama), Parachain(1000))); - let mut destination: Option = Here.into(); + let mut universal_source: Option = + Some([GlobalConsensus(Kusama), Parachain(1000)].into()); + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -197,8 +198,8 @@ fn exporter_validate_with_remote_universal_source_yields_not_applicable() { fn exporter_validate_without_para_id_in_source_yields_missing_argument() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = Some(X1(GlobalConsensus(Polkadot))); - let mut destination: Option = Here.into(); + let mut universal_source: Option = Some(GlobalConsensus(Polkadot).into()); + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -216,9 +217,9 @@ fn exporter_validate_without_para_id_in_source_yields_missing_argument() { fn exporter_validate_complex_para_id_in_source_yields_missing_argument() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = - Some(X3(GlobalConsensus(Polkadot), Parachain(1000), PalletInstance(12))); - let mut destination: Option = Here.into(); + let mut universal_source: Option = + Some([GlobalConsensus(Polkadot), Parachain(1000), PalletInstance(12)].into()); + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -236,9 +237,9 @@ fn exporter_validate_complex_para_id_in_source_yields_missing_argument() { fn exporter_validate_without_xcm_message_yields_missing_argument() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = - Some(X2(GlobalConsensus(Polkadot), Parachain(1000))); - let mut destination: Option = Here.into(); + let mut universal_source: Option = + Some([GlobalConsensus(Polkadot), Parachain(1000)].into()); + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -255,23 +256,23 @@ fn exporter_validate_without_xcm_message_yields_missing_argument() { #[test] fn exporter_validate_with_max_target_fee_yields_unroutable() { let network = BridgedNetwork::get(); - let mut destination: Option = Here.into(); + let mut destination: Option = Here.into(); - let mut universal_source: Option = - Some(X2(GlobalConsensus(Polkadot), Parachain(1000))); + let mut universal_source: Option = + Some([GlobalConsensus(Polkadot), Parachain(1000)].into()); let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); let channel: u32 = 0; - let fee = MultiAsset { id: Concrete(Here.into()), fun: Fungible(1000) }; - let fees: MultiAssets = vec![fee.clone()].into(); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let fee = Asset { id: AssetId(Here.into()), fun: Fungible(1000) }; + let fees: Assets = vec![fee.clone()].into(); + let assets: Assets = vec![Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let mut message: Option> = Some( vec![ @@ -280,7 +281,7 @@ fn exporter_validate_with_max_target_fee_yields_unroutable() { WithdrawAsset(assets), DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: Some(network), key: beneficiary_address }) + beneficiary: AccountKey20 { network: Some(network), key: beneficiary_address } .into(), }, SetTopic([0; 32]), @@ -303,14 +304,14 @@ fn exporter_validate_with_max_target_fee_yields_unroutable() { #[test] fn exporter_validate_with_unparsable_xcm_yields_unroutable() { let network = BridgedNetwork::get(); - let mut destination: Option = Here.into(); + let mut destination: Option = Here.into(); - let mut universal_source: Option = - Some(X2(GlobalConsensus(Polkadot), Parachain(1000))); + let mut universal_source: Option = + Some([GlobalConsensus(Polkadot), Parachain(1000)].into()); let channel: u32 = 0; - let fee = MultiAsset { id: Concrete(Here.into()), fun: Fungible(1000) }; - let fees: MultiAssets = vec![fee.clone()].into(); + let fee = Asset { id: AssetId(Here.into()), fun: Fungible(1000) }; + let fees: Assets = vec![fee.clone()].into(); let mut message: Option> = Some(vec![WithdrawAsset(fees), BuyExecution { fees: fee, weight_limit: Unlimited }].into()); @@ -330,22 +331,22 @@ fn exporter_validate_with_unparsable_xcm_yields_unroutable() { #[test] fn exporter_validate_xcm_success_case_1() { let network = BridgedNetwork::get(); - let mut destination: Option = Here.into(); + let mut destination: Option = Here.into(); - let mut universal_source: Option = - Some(X2(GlobalConsensus(Polkadot), Parachain(1000))); + let mut universal_source: Option = + Some([GlobalConsensus(Polkadot), Parachain(1000)].into()); let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); let channel: u32 = 0; - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); let fee = assets.clone().get(0).unwrap().clone(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let mut message: Option> = Some( vec![ @@ -354,7 +355,7 @@ fn exporter_validate_xcm_success_case_1() { BuyExecution { fees: fee, weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -391,12 +392,12 @@ fn xcm_converter_convert_success() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -404,7 +405,7 @@ fn xcm_converter_convert_success() { BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -426,18 +427,18 @@ fn xcm_converter_convert_without_buy_execution_yields_success() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -459,12 +460,12 @@ fn xcm_converter_convert_with_wildcard_all_asset_filter_succeeds() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(All); + let filter: AssetFilter = Wild(All); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -472,7 +473,7 @@ fn xcm_converter_convert_with_wildcard_all_asset_filter_succeeds() { BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -494,13 +495,12 @@ fn xcm_converter_convert_with_fees_less_than_reserve_yields_success() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let asset_location = X1(AccountKey20 { network: None, key: token_address }).into(); - let fee_asset = MultiAsset { id: Concrete(asset_location), fun: Fungible(500) }; + let asset_location: Location = [AccountKey20 { network: None, key: token_address }].into(); + let fee_asset = Asset { id: AssetId(asset_location.clone()), fun: Fungible(500) }; - let assets: MultiAssets = - vec![MultiAsset { id: Concrete(asset_location), fun: Fungible(1000) }].into(); + let assets: Assets = vec![Asset { id: AssetId(asset_location), fun: Fungible(1000) }].into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -508,7 +508,7 @@ fn xcm_converter_convert_with_fees_less_than_reserve_yields_success() { BuyExecution { fees: fee_asset, weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -530,19 +530,19 @@ fn xcm_converter_convert_without_set_topic_yields_set_topic_expected() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, ClearTopic, ] @@ -557,8 +557,8 @@ fn xcm_converter_convert_with_partial_message_yields_unexpected_end_of_xcm() { let network = BridgedNetwork::get(); let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); @@ -576,16 +576,13 @@ fn xcm_converter_with_different_fee_asset_fails() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let asset_location = X1(AccountKey20 { network: None, key: token_address }).into(); - let fee_asset = MultiAsset { - id: Concrete(MultiLocation { parents: 0, interior: Here }), - fun: Fungible(1000), - }; + let asset_location = [AccountKey20 { network: None, key: token_address }].into(); + let fee_asset = + Asset { id: AssetId(Location { parents: 0, interior: Here }), fun: Fungible(1000) }; - let assets: MultiAssets = - vec![MultiAsset { id: Concrete(asset_location), fun: Fungible(1000) }].into(); + let assets: Assets = vec![Asset { id: AssetId(asset_location), fun: Fungible(1000) }].into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -593,7 +590,7 @@ fn xcm_converter_with_different_fee_asset_fails() { BuyExecution { fees: fee_asset, weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -610,13 +607,12 @@ fn xcm_converter_with_fees_greater_than_reserve_fails() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let asset_location = X1(AccountKey20 { network: None, key: token_address }).into(); - let fee_asset = MultiAsset { id: Concrete(asset_location), fun: Fungible(1001) }; + let asset_location: Location = [AccountKey20 { network: None, key: token_address }].into(); + let fee_asset = Asset { id: AssetId(asset_location.clone()), fun: Fungible(1001) }; - let assets: MultiAssets = - vec![MultiAsset { id: Concrete(asset_location), fun: Fungible(1000) }].into(); + let assets: Assets = vec![Asset { id: AssetId(asset_location), fun: Fungible(1000) }].into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -624,7 +620,7 @@ fn xcm_converter_with_fees_greater_than_reserve_fails() { BuyExecution { fees: fee_asset, weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -653,12 +649,12 @@ fn xcm_converter_convert_with_extra_instructions_yields_end_of_xcm_message_expec let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -666,7 +662,7 @@ fn xcm_converter_convert_with_extra_instructions_yields_end_of_xcm_message_expec BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ClearError, @@ -685,19 +681,19 @@ fn xcm_converter_convert_without_withdraw_asset_yields_withdraw_expected() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ ClearOrigin, BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -714,8 +710,8 @@ fn xcm_converter_convert_without_withdraw_asset_yields_deposit_expected() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(1000), }] .into(); @@ -741,11 +737,11 @@ fn xcm_converter_convert_without_assets_yields_no_reserve_assets() { let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![].into(); - let filter: MultiAssetFilter = assets.clone().into(); + let assets: Assets = vec![].into(); + let filter: AssetFilter = assets.clone().into(); - let fee = MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let fee = Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(1000), }; @@ -755,7 +751,7 @@ fn xcm_converter_convert_without_assets_yields_no_reserve_assets() { BuyExecution { fees: fee, weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -774,18 +770,18 @@ fn xcm_converter_convert_with_two_assets_yields_too_many_assets() { let token_address_2: [u8; 20] = hex!("1100000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![ - MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address_1 }).into()), + let assets: Assets = vec![ + Asset { + id: AssetId(AccountKey20 { network: None, key: token_address_1 }.into()), fun: Fungible(1000), }, - MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address_2 }).into()), + Asset { + id: AssetId(AccountKey20 { network: None, key: token_address_2 }.into()), fun: Fungible(500), }, ] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -793,7 +789,7 @@ fn xcm_converter_convert_with_two_assets_yields_too_many_assets() { BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -811,12 +807,12 @@ fn xcm_converter_convert_without_consuming_filter_yields_filter_does_not_consume let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(0)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(0)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -824,7 +820,7 @@ fn xcm_converter_convert_without_consuming_filter_yields_filter_does_not_consume BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -842,12 +838,12 @@ fn xcm_converter_convert_with_zero_amount_asset_yields_zero_asset_transfer() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(0), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(1)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(1)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -855,7 +851,7 @@ fn xcm_converter_convert_with_zero_amount_asset_yields_zero_asset_transfer() { BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -872,12 +868,12 @@ fn xcm_converter_convert_non_ethereum_asset_yields_asset_resolution_failed() { let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X3(GlobalConsensus(Polkadot), Parachain(1000), GeneralIndex(0)).into()), + let assets: Assets = vec![Asset { + id: AssetId([GlobalConsensus(Polkadot), Parachain(1000), GeneralIndex(0)].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(1)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(1)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -885,7 +881,7 @@ fn xcm_converter_convert_non_ethereum_asset_yields_asset_resolution_failed() { BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -903,14 +899,14 @@ fn xcm_converter_convert_non_ethereum_chain_asset_yields_asset_resolution_failed let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete( - X1(AccountKey20 { network: Some(Ethereum { chain_id: 2 }), key: token_address }).into(), + let assets: Assets = vec![Asset { + id: AssetId( + AccountKey20 { network: Some(Ethereum { chain_id: 2 }), key: token_address }.into(), ), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(1)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(1)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -918,7 +914,7 @@ fn xcm_converter_convert_non_ethereum_chain_asset_yields_asset_resolution_failed BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -936,14 +932,14 @@ fn xcm_converter_convert_non_ethereum_chain_yields_asset_resolution_failed() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete( - X1(AccountKey20 { network: Some(NonBridgedNetwork::get()), key: token_address }).into(), + let assets: Assets = vec![Asset { + id: AssetId( + [AccountKey20 { network: Some(NonBridgedNetwork::get()), key: token_address }].into(), ), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(1)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(1)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -951,7 +947,7 @@ fn xcm_converter_convert_non_ethereum_chain_yields_asset_resolution_failed() { BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -971,23 +967,23 @@ fn xcm_converter_convert_with_non_ethereum_beneficiary_yields_beneficiary_resolu let beneficiary_address: [u8; 32] = hex!("2000000000000000000000000000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(1)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(1)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), ClearOrigin, BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X3( + beneficiary: [ GlobalConsensus(Polkadot), Parachain(1000), AccountId32 { network: Some(Polkadot), id: beneficiary_address }, - ) + ] .into(), }, SetTopic([0; 32]), @@ -1007,12 +1003,12 @@ fn xcm_converter_convert_with_non_ethereum_chain_beneficiary_yields_beneficiary_ let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(1)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(1)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -1020,10 +1016,10 @@ fn xcm_converter_convert_with_non_ethereum_chain_beneficiary_yields_beneficiary_ BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { + beneficiary: AccountKey20 { network: Some(Ethereum { chain_id: 2 }), key: beneficiary_address, - }) + } .into(), }, SetTopic([0; 32]), @@ -1037,14 +1033,13 @@ fn xcm_converter_convert_with_non_ethereum_chain_beneficiary_yields_beneficiary_ #[test] fn test_describe_asset_hub() { - let legacy_location: MultiLocation = - MultiLocation { parents: 0, interior: X1(Parachain(1000)) }; + let legacy_location: Location = Location::new(0, [Parachain(1000)]); let legacy_agent_id = AgentIdOf::convert_location(&legacy_location).unwrap(); assert_eq!( legacy_agent_id, hex!("72456f48efed08af20e5b317abf8648ac66e86bb90a411d9b0b713f7364b75b4").into() ); - let location: MultiLocation = MultiLocation { parents: 1, interior: X1(Parachain(1000)) }; + let location: Location = Location::new(1, [Parachain(1000)]); let agent_id = AgentIdOf::convert_location(&location).unwrap(); assert_eq!( agent_id, @@ -1054,7 +1049,7 @@ fn test_describe_asset_hub() { #[test] fn test_describe_here() { - let location: MultiLocation = MultiLocation { parents: 0, interior: Here }; + let location: Location = Location::new(0, []); let agent_id = AgentIdOf::convert_location(&location).unwrap(); assert_eq!( agent_id, diff --git a/bridges/snowbridge/parachain/runtime/runtime-common/src/lib.rs b/bridges/snowbridge/parachain/runtime/runtime-common/src/lib.rs index b7f54d262bb..1a9b704f356 100644 --- a/bridges/snowbridge/parachain/runtime/runtime-common/src/lib.rs +++ b/bridges/snowbridge/parachain/runtime/runtime-common/src/lib.rs @@ -46,43 +46,38 @@ impl where Balance: BaseArithmetic + Unsigned + Copy + From + Into, AccountId: Clone + Into<[u8; 32]> + From<[u8; 32]>, - FeeAssetLocation: Get, + FeeAssetLocation: Get, EthereumNetwork: Get, AssetTransactor: TransactAsset, FeeProvider: SendMessageFeeProvider, { - fn handle_fee( - fees: MultiAssets, - context: Option<&XcmContext>, - reason: FeeReason, - ) -> MultiAssets { + fn handle_fee(fees: Assets, context: Option<&XcmContext>, reason: FeeReason) -> Assets { let token_location = FeeAssetLocation::get(); // Check the reason to see if this export is for snowbridge. if !matches!( reason, - FeeReason::Export { network: bridged_network, destination } - if bridged_network == EthereumNetwork::get() && destination == Here + FeeReason::Export { network: bridged_network, ref destination } + if bridged_network == EthereumNetwork::get() && destination == &Here ) { return fees } // Get the parachain sovereign from the `context`. - let para_sovereign = if let Some(XcmContext { - origin: Some(MultiLocation { parents: 1, interior }), - .. - }) = context - { - if let Some(Parachain(sibling_para_id)) = interior.first() { - let account: AccountId = - sibling_sovereign_account_raw((*sibling_para_id).into()).into(); - account + let para_sovereign = + if let Some(XcmContext { origin: Some(Location { parents: 1, interior }), .. }) = + context + { + if let Some(Parachain(sibling_para_id)) = interior.first() { + let account: AccountId = + sibling_sovereign_account_raw((*sibling_para_id).into()).into(); + account + } else { + return fees + } } else { return fees - } - } else { - return fees - }; + }; // Get the total fee offered by export message. let maybe_total_supplied_fee: Option<(usize, Balance)> = fees @@ -90,8 +85,8 @@ impl (0u128).into() { // Refund remote component of fee to physical origin deposit_or_burn_fee::( - MultiAsset { id: Concrete(token_location), fun: Fungible(remote_fee.into()) } + Asset { id: AssetId(token_location.clone()), fun: Fungible(remote_fee.into()) } .into(), context, para_sovereign, @@ -112,8 +107,8 @@ impl::execute_xcm( + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); + XcmExecutor::::prepare_and_execute( assethub_parachain_location, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ) } @@ -176,7 +175,7 @@ pub fn send_unpaid_transfer_token_message( XcmConfig: xcm_executor::Config, ValidatorIdOf: From>, { - let assethub_parachain_location = MultiLocation::new(1, Parachain(assethub_parachain_id)); + let assethub_parachain_location = Location::new(1, Parachain(assethub_parachain_id)); ExtBuilder::::default() .with_collators(collator_session_key.collators()) @@ -194,28 +193,25 @@ pub fn send_unpaid_transfer_token_message( ) .unwrap(); - let asset = MultiAsset { - id: Concrete(MultiLocation { - parents: 0, - interior: X1(AccountKey20 { network: None, key: weth_contract_address.into() }), - }), + let asset = Asset { + id: AssetId(Location::new( + 0, + [AccountKey20 { network: None, key: weth_contract_address.into() }], + )), fun: Fungible(1000000000), }; let assets = vec![asset.clone()]; let inner_xcm = Xcm(vec![ - WithdrawAsset(MultiAssets::from(assets.clone())), + WithdrawAsset(Assets::from(assets.clone())), ClearOrigin, BuyExecution { fees: asset, weight_limit: Unlimited }, DepositAsset { assets: Wild(AllCounted(1)), - beneficiary: MultiLocation { - parents: 0, - interior: X1(AccountKey20 { - network: None, - key: destination_contract.into(), - }), - }, + beneficiary: Location::new( + 0, + [AccountKey20 { network: None, key: destination_contract.into() }], + ), }, SetTopic([0; 32]), ]); @@ -231,12 +227,13 @@ pub fn send_unpaid_transfer_token_message( ]); // execute XCM - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); - let outcome = XcmExecutor::::execute_xcm( + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let outcome = XcmExecutor::::prepare_and_execute( assethub_parachain_location, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ); // check error is barrier assert_err!(outcome.ensure_complete(), Barrier); diff --git a/cumulus/pallets/xcmp-queue/src/lib.rs b/cumulus/pallets/xcmp-queue/src/lib.rs index 71cd21d45f7..5b900769622 100644 --- a/cumulus/pallets/xcmp-queue/src/lib.rs +++ b/cumulus/pallets/xcmp-queue/src/lib.rs @@ -135,7 +135,7 @@ pub mod pallet { /// The origin that is allowed to resume or suspend the XCMP queue. type ControllerOrigin: EnsureOrigin; - /// The conversion function used to attempt to convert an XCM `MultiLocation` origin to a + /// The conversion function used to attempt to convert an XCM `Location` origin to a /// superuser origin. type ControllerOriginConverter: ConvertOrigin; @@ -903,14 +903,14 @@ impl SendXcm for Pallet { type Ticket = (ParaId, VersionedXcm<()>); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, ) -> SendResult<(ParaId, VersionedXcm<()>)> { let d = dest.take().ok_or(SendError::MissingArgument)?; - match &d { + match d.unpack() { // An HRMP message for a sibling parachain. - MultiLocation { parents: 1, interior: X1(Parachain(id)) } => { + (1, [Parachain(id)]) => { let xcm = msg.take().ok_or(SendError::MissingArgument)?; let id = ParaId::from(*id); let price = T::PriceForSiblingDelivery::price_for_delivery(id, &xcm); diff --git a/cumulus/pallets/xcmp-queue/src/mock.rs b/cumulus/pallets/xcmp-queue/src/mock.rs index a41be6fa9ca..031c0721753 100644 --- a/cumulus/pallets/xcmp-queue/src/mock.rs +++ b/cumulus/pallets/xcmp-queue/src/mock.rs @@ -124,8 +124,8 @@ impl cumulus_pallet_parachain_system::Config for Test { } parameter_types! { - pub const RelayChain: MultiLocation = MultiLocation::parent(); - pub UniversalLocation: InteriorMultiLocation = X1(Parachain(1u32)); + pub const RelayChain: Location = Location::parent(); + pub UniversalLocation: InteriorLocation = [Parachain(1u32)].into(); pub UnitWeightCost: Weight = Weight::from_parts(1_000_000, 1024); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; @@ -138,7 +138,7 @@ pub type LocalAssetTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -187,17 +187,14 @@ impl ConvertOrigin for SystemParachainAsSuperuser { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); if kind == OriginKind::Superuser && matches!( - origin, - MultiLocation { - parents: 1, - interior: X1(Parachain(id)), - } if ParaId::from(id).is_system(), + origin.unpack(), + (1, [Parachain(id)]) if ParaId::from(*id).is_system(), ) { Ok(RuntimeOrigin::root()) } else { @@ -256,7 +253,7 @@ impl> EnqueueMessage for EnqueueToLocalStorage parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(RelayChain::get()); + pub FeeAssetId: AssetId = AssetId(RelayChain::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: Balance = 300_000_000; /// The fee per byte diff --git a/cumulus/pallets/xcmp-queue/src/tests.rs b/cumulus/pallets/xcmp-queue/src/tests.rs index 8e8f6e852e1..0b41095828f 100644 --- a/cumulus/pallets/xcmp-queue/src/tests.rs +++ b/cumulus/pallets/xcmp-queue/src/tests.rs @@ -333,11 +333,11 @@ struct OkFixedXcmHashWithAssertingRequiredInputsSender; impl OkFixedXcmHashWithAssertingRequiredInputsSender { const FIXED_XCM_HASH: [u8; 32] = [9; 32]; - fn fixed_delivery_asset() -> MultiAssets { - MultiAssets::new() + fn fixed_delivery_asset() -> Assets { + Assets::new() } - fn expected_delivery_result() -> Result<(XcmHash, MultiAssets), SendError> { + fn expected_delivery_result() -> Result<(XcmHash, Assets), SendError> { Ok((Self::FIXED_XCM_HASH, Self::fixed_delivery_asset())) } } @@ -345,7 +345,7 @@ impl SendXcm for OkFixedXcmHashWithAssertingRequiredInputsSender { type Ticket = (); fn validate( - destination: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult { assert!(destination.is_some()); @@ -392,8 +392,8 @@ fn xcmp_queue_consumes_dest_and_msg_on_ok_validate() { let message = Xcm(vec![Trap(5)]); // XcmpQueue - check dest/msg is valid - let dest = (Parent, X1(Parachain(5555))); - let mut dest_wrapper = Some(dest.into()); + let dest: Location = (Parent, Parachain(5555)).into(); + let mut dest_wrapper = Some(dest.clone()); let mut msg_wrapper = Some(message.clone()); new_test_ext().execute_with(|| { @@ -416,7 +416,7 @@ fn xcmp_queue_consumes_dest_and_msg_on_ok_validate() { #[test] fn xcmp_queue_validate_nested_xcm_works() { - let dest = (Parent, X1(Parachain(5555))); + let dest = (Parent, Parachain(5555)); // Message that is not too deeply nested: let mut good = Xcm(vec![ClearOrigin]); for _ in 0..MAX_XCM_DECODE_DEPTH - 1 { @@ -441,7 +441,7 @@ fn xcmp_queue_validate_nested_xcm_works() { #[test] fn send_xcm_nested_works() { - let dest = (Parent, X1(Parachain(HRMP_PARA_ID))); + let dest = (Parent, Parachain(HRMP_PARA_ID)); // Message that is not too deeply nested: let mut good = Xcm(vec![ClearOrigin]); for _ in 0..MAX_XCM_DECODE_DEPTH - 1 { @@ -455,7 +455,7 @@ fn send_xcm_nested_works() { XcmpQueue::take_outbound_messages(usize::MAX), vec![( HRMP_PARA_ID.into(), - (XcmpMessageFormat::ConcatenatedVersionedXcm, VersionedXcm::V3(good.clone())) + (XcmpMessageFormat::ConcatenatedVersionedXcm, VersionedXcm::V4(good.clone())) .encode(), )] ); @@ -474,7 +474,7 @@ fn hrmp_signals_are_prioritized() { let message = Xcm(vec![Trap(5)]); let sibling_para_id = ParaId::from(12345); - let dest = (Parent, X1(Parachain(sibling_para_id.into()))); + let dest = (Parent, Parachain(sibling_para_id.into())); let mut dest_wrapper = Some(dest.into()); let mut msg_wrapper = Some(message.clone()); @@ -511,7 +511,7 @@ fn hrmp_signals_are_prioritized() { // Without a signal we get the messages in order: let mut expected_msg = XcmpMessageFormat::ConcatenatedVersionedXcm.encode(); for _ in 0..31 { - expected_msg.extend(VersionedXcm::V3(message.clone()).encode()); + expected_msg.extend(VersionedXcm::V4(message.clone()).encode()); } hypothetically!({ @@ -590,7 +590,7 @@ fn take_first_concatenated_xcm_good_recursion_depth_works() { for _ in 0..MAX_XCM_DECODE_DEPTH - 1 { good = Xcm(vec![SetAppendix(good)]); } - let good = VersionedXcm::V3(good); + let good = VersionedXcm::V4(good); let page = good.encode(); assert_ok!(XcmpQueue::take_first_concatenated_xcm(&mut &page[..], &mut WeightMeter::new())); @@ -603,7 +603,7 @@ fn take_first_concatenated_xcm_good_bad_depth_errors() { for _ in 0..MAX_XCM_DECODE_DEPTH { bad = Xcm(vec![SetAppendix(bad)]); } - let bad = VersionedXcm::V3(bad); + let bad = VersionedXcm::V4(bad); let page = bad.encode(); assert_err!( @@ -699,12 +699,12 @@ fn lazy_migration_noop_when_out_of_weight() { fn xcmp_queue_send_xcm_works() { new_test_ext().execute_with(|| { let sibling_para_id = ParaId::from(12345); - let dest = (Parent, X1(Parachain(sibling_para_id.into()))).into(); + let dest: Location = (Parent, Parachain(sibling_para_id.into())).into(); let msg = Xcm(vec![ClearOrigin]); // try to send without opened HRMP channel to the sibling_para_id assert_eq!( - send_xcm::(dest, msg.clone()), + send_xcm::(dest.clone(), msg.clone()), Err(SendError::Transport("NoChannel")), ); @@ -728,7 +728,7 @@ fn xcmp_queue_send_xcm_works() { fn xcmp_queue_send_too_big_xcm_fails() { new_test_ext().execute_with(|| { let sibling_para_id = ParaId::from(12345); - let dest = (Parent, X1(Parachain(sibling_para_id.into()))).into(); + let dest = (Parent, Parachain(sibling_para_id.into())).into(); let max_message_size = 100_u32; @@ -774,7 +774,7 @@ fn verify_fee_factor_increase_and_decrease() { use sp_runtime::FixedU128; let sibling_para_id = ParaId::from(12345); - let destination = (Parent, Parachain(sibling_para_id.into())).into(); + let destination: Location = (Parent, Parachain(sibling_para_id.into())).into(); let xcm = Xcm(vec![ClearOrigin; 100]); let versioned_xcm = VersionedXcm::from(xcm.clone()); let mut xcmp_message = XcmpMessageFormat::ConcatenatedVersionedXcm.encode(); @@ -799,15 +799,15 @@ fn verify_fee_factor_increase_and_decrease() { // Fee factor is only increased in `send_fragment`, which is called by `send_xcm`. // When queue is not congested, fee factor doesn't change. - assert_ok!(send_xcm::(destination, xcm.clone())); // Size 104 - assert_ok!(send_xcm::(destination, xcm.clone())); // Size 208 - assert_ok!(send_xcm::(destination, xcm.clone())); // Size 312 - assert_ok!(send_xcm::(destination, xcm.clone())); // Size 416 + assert_ok!(send_xcm::(destination.clone(), xcm.clone())); // Size 104 + assert_ok!(send_xcm::(destination.clone(), xcm.clone())); // Size 208 + assert_ok!(send_xcm::(destination.clone(), xcm.clone())); // Size 312 + assert_ok!(send_xcm::(destination.clone(), xcm.clone())); // Size 416 assert_eq!(DeliveryFeeFactor::::get(sibling_para_id), initial); // Sending the message right now is cheap - let (_, delivery_fees) = - validate_send::(destination, xcm.clone()).expect("message can be sent; qed"); + let (_, delivery_fees) = validate_send::(destination.clone(), xcm.clone()) + .expect("message can be sent; qed"); let Fungible(delivery_fee_amount) = delivery_fees.inner()[0].fun else { unreachable!("asset is fungible; qed"); }; @@ -817,18 +817,18 @@ fn verify_fee_factor_increase_and_decrease() { // When we get to half of `max_total_size`, because `THRESHOLD_FACTOR` is 2, // then the fee factor starts to increase. - assert_ok!(send_xcm::(destination, xcm.clone())); // Size 520 + assert_ok!(send_xcm::(destination.clone(), xcm.clone())); // Size 520 assert_eq!(DeliveryFeeFactor::::get(sibling_para_id), FixedU128::from_float(1.05)); for _ in 0..12 { // We finish at size 929 - assert_ok!(send_xcm::(destination, smaller_xcm.clone())); + assert_ok!(send_xcm::(destination.clone(), smaller_xcm.clone())); } assert!(DeliveryFeeFactor::::get(sibling_para_id) > FixedU128::from_float(1.88)); // Sending the message right now is expensive - let (_, delivery_fees) = - validate_send::(destination, xcm.clone()).expect("message can be sent; qed"); + let (_, delivery_fees) = validate_send::(destination.clone(), xcm.clone()) + .expect("message can be sent; qed"); let Fungible(delivery_fee_amount) = delivery_fees.inner()[0].fun else { unreachable!("asset is fungible; qed"); }; diff --git a/cumulus/parachain-template/runtime/src/xcm_config.rs b/cumulus/parachain-template/runtime/src/xcm_config.rs index 7d1a748819c..d407292d0bd 100644 --- a/cumulus/parachain-template/runtime/src/xcm_config.rs +++ b/cumulus/parachain-template/runtime/src/xcm_config.rs @@ -3,8 +3,8 @@ use super::{ Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue, }; use frame_support::{ - match_types, parameter_types, - traits::{ConstU32, Everything, Nothing}, + parameter_types, + traits::{ConstU32, Contains, Everything, Nothing}, weights::Weight, }; use frame_system::EnsureRoot; @@ -25,13 +25,13 @@ use xcm_builder::{ use xcm_executor::XcmExecutor; parameter_types! { - pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = None; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = Parachain(ParachainInfo::parachain_id().into()).into(); + pub UniversalLocation: InteriorLocation = Parachain(ParachainInfo::parachain_id().into()).into(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -50,7 +50,7 @@ pub type LocalAssetTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -86,11 +86,11 @@ parameter_types! { pub const MaxAssetsIntoHolding: u32 = 64; } -match_types! { - pub type ParentOrParentsExecutivePlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Executive, .. }) } - }; +pub struct ParentOrParentsExecutivePlurality; +impl Contains for ParentOrParentsExecutivePlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { id: BodyId::Executive, .. }])) + } } pub type Barrier = TrailingSetTopicAsId< diff --git a/cumulus/parachains/common/src/impls.rs b/cumulus/parachains/common/src/impls.rs index beb655134ad..69da325dd4f 100644 --- a/cumulus/parachains/common/src/impls.rs +++ b/cumulus/parachains/common/src/impls.rs @@ -24,8 +24,8 @@ use pallet_asset_tx_payment::HandleCredit; use sp_runtime::traits::Zero; use sp_std::{marker::PhantomData, prelude::*}; use xcm::latest::{ - AssetId, Fungibility, Fungibility::Fungible, Junction, Junctions::Here, MultiAsset, - MultiLocation, Parent, WeightLimit, + Asset, AssetId, Fungibility, Fungibility::Fungible, Junction, Junctions::Here, Location, + Parent, WeightLimit, }; use xcm_executor::traits::ConvertLocation; @@ -113,11 +113,11 @@ where /// Asset filter that allows all assets from a certain location. pub struct AssetsFrom(PhantomData); -impl> ContainsPair for AssetsFrom { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl> ContainsPair for AssetsFrom { + fn contains(asset: &Asset, origin: &Location) -> bool { let loc = T::get(); &loc == origin && - matches!(asset, MultiAsset { id: AssetId::Concrete(asset_loc), fun: Fungible(_a) } + matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } if asset_loc.match_and_split(&loc).is_some()) } } @@ -148,7 +148,7 @@ where Err(amount) => amount, }; let imbalance = amount.peek(); - let root_location: MultiLocation = Here.into(); + let root_location: Location = Here.into(); let root_account: AccountIdOf = match AccountIdConverter::convert_location(&root_location) { Some(a) => a, @@ -329,13 +329,13 @@ mod tests { #[test] fn assets_from_filters_correctly() { parameter_types! { - pub SomeSiblingParachain: MultiLocation = MultiLocation::new(1, X1(Parachain(1234))); + pub SomeSiblingParachain: Location = (Parent, Parachain(1234)).into(); } let asset_location = SomeSiblingParachain::get() .pushed_with_interior(GeneralIndex(42)) - .expect("multilocation will only have 2 junctions; qed"); - let asset = MultiAsset { id: Concrete(asset_location), fun: 1_000_000u128.into() }; + .expect("location will only have 2 junctions; qed"); + let asset = Asset { id: AssetId(asset_location), fun: 1_000_000u128.into() }; assert!( AssetsFrom::::contains(&asset, &SomeSiblingParachain::get()), "AssetsFrom should allow assets from any of its interior locations" diff --git a/cumulus/parachains/common/src/xcm_config.rs b/cumulus/parachains/common/src/xcm_config.rs index 7a63e720b07..15b090923d5 100644 --- a/cumulus/parachains/common/src/xcm_config.rs +++ b/cumulus/parachains/common/src/xcm_config.rs @@ -66,37 +66,36 @@ where } } -/// Accepts an asset if it is a native asset from a particular `MultiLocation`. -pub struct ConcreteNativeAssetFrom(PhantomData); -impl> ContainsPair - for ConcreteNativeAssetFrom +/// Accepts an asset if it is a native asset from a particular `Location`. +pub struct ConcreteNativeAssetFrom(PhantomData); +impl> ContainsPair + for ConcreteNativeAssetFrom { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + fn contains(asset: &Asset, origin: &Location) -> bool { log::trace!(target: "xcm::filter_asset_location", "ConcreteNativeAsset asset: {:?}, origin: {:?}, location: {:?}", - asset, origin, Location::get()); - matches!(asset.id, Concrete(ref id) if id == origin && origin == &Location::get()) + asset, origin, LocationValue::get()); + asset.id.0 == *origin && origin == &LocationValue::get() } } pub struct RelayOrOtherSystemParachains< - SystemParachainMatcher: Contains, + SystemParachainMatcher: Contains, Runtime: parachain_info::Config, > { _runtime: PhantomData<(SystemParachainMatcher, Runtime)>, } -impl, Runtime: parachain_info::Config> - Contains for RelayOrOtherSystemParachains +impl, Runtime: parachain_info::Config> Contains + for RelayOrOtherSystemParachains { - fn contains(l: &MultiLocation) -> bool { + fn contains(l: &Location) -> bool { let self_para_id: u32 = parachain_info::Pallet::::get().into(); - if let MultiLocation { parents: 0, interior: X1(Parachain(para_id)) } = l { + if let (0, [Parachain(para_id)]) = l.unpack() { if *para_id == self_para_id { return false } } - matches!(l, MultiLocation { parents: 1, interior: Here }) || - SystemParachainMatcher::contains(l) + matches!(l.unpack(), (1, [])) || SystemParachainMatcher::contains(l) } } @@ -105,14 +104,12 @@ impl, Runtime: parachain_info::C /// This structure can only be used at a parachain level. In the Relay Chain, please use /// the `xcm_builder::IsChildSystemParachain` matcher. pub struct AllSiblingSystemParachains; - -impl Contains for AllSiblingSystemParachains { - fn contains(l: &MultiLocation) -> bool { +impl Contains for AllSiblingSystemParachains { + fn contains(l: &Location) -> bool { log::trace!(target: "xcm::contains", "AllSiblingSystemParachains location: {:?}", l); - match *l { + match l.unpack() { // System parachain - MultiLocation { parents: 1, interior: X1(Parachain(id)) } => - ParaId::from(id).is_system(), + (1, [Parachain(id)]) => ParaId::from(*id).is_system(), // Everything else _ => false, } @@ -121,21 +118,20 @@ impl Contains for AllSiblingSystemParachains { /// Accepts an asset if it is a concrete asset from the system (Relay Chain or system parachain). pub struct ConcreteAssetFromSystem(PhantomData); -impl> ContainsPair +impl> ContainsPair for ConcreteAssetFromSystem { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + fn contains(asset: &Asset, origin: &Location) -> bool { log::trace!(target: "xcm::contains", "ConcreteAssetFromSystem asset: {:?}, origin: {:?}", asset, origin); - let is_system = match origin { + let is_system = match origin.unpack() { // The Relay Chain - MultiLocation { parents: 1, interior: Here } => true, + (1, []) => true, // System parachain - MultiLocation { parents: 1, interior: X1(Parachain(id)) } => - ParaId::from(*id).is_system(), + (1, [Parachain(id)]) => ParaId::from(*id).is_system(), // Others _ => false, }; - matches!(asset.id, Concrete(id) if id == AssetLocation::get()) && is_system + asset.id.0 == AssetLocation::get() && is_system } } @@ -144,13 +140,9 @@ impl> ContainsPair /// This type should only be used within the context of a parachain, since it does not verify that /// the parent is indeed a Relay Chain. pub struct ParentRelayOrSiblingParachains; -impl Contains for ParentRelayOrSiblingParachains { - fn contains(location: &MultiLocation) -> bool { - matches!( - location, - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Parachain(_)) } - ) +impl Contains for ParentRelayOrSiblingParachains { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Parachain(_)])) } } @@ -159,20 +151,20 @@ mod tests { use frame_support::{parameter_types, traits::Contains}; use super::{ - AllSiblingSystemParachains, ConcreteAssetFromSystem, ContainsPair, GeneralIndex, Here, - MultiAsset, MultiLocation, PalletInstance, Parachain, Parent, + AllSiblingSystemParachains, Asset, ConcreteAssetFromSystem, ContainsPair, GeneralIndex, + Here, Location, PalletInstance, Parachain, Parent, }; use polkadot_primitives::LOWEST_PUBLIC_ID; use xcm::latest::prelude::*; parameter_types! { - pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RelayLocation: Location = Location::parent(); } #[test] fn concrete_asset_from_relay_works() { - let expected_asset: MultiAsset = (Parent, 1000000).into(); - let expected_origin: MultiLocation = (Parent, Here).into(); + let expected_asset: Asset = (Parent, 1000000).into(); + let expected_origin: Location = (Parent, Here).into(); assert!(>::contains( &expected_asset, @@ -182,12 +174,12 @@ mod tests { #[test] fn concrete_asset_from_sibling_system_para_fails_for_wrong_asset() { - let unexpected_assets: Vec = vec![ + let unexpected_assets: Vec = vec![ (Here, 1000000).into(), ((PalletInstance(50), GeneralIndex(1)), 1000000).into(), ((Parent, Parachain(1000), PalletInstance(50), GeneralIndex(1)), 1000000).into(), ]; - let expected_origin: MultiLocation = (Parent, Parachain(1000)).into(); + let expected_origin: Location = (Parent, Parachain(1000)).into(); unexpected_assets.iter().for_each(|asset| { assert!(!>::contains(asset, &expected_origin)); @@ -206,10 +198,10 @@ mod tests { (2001, false), // Not a System Parachain ]; - let expected_asset: MultiAsset = (Parent, 1000000).into(); + let expected_asset: Asset = (Parent, 1000000).into(); for (para_id, expected_result) in test_data { - let origin: MultiLocation = (Parent, Parachain(para_id)).into(); + let origin: Location = (Parent, Parachain(para_id)).into(); assert_eq!( expected_result, >::contains(&expected_asset, &origin) @@ -220,15 +212,15 @@ mod tests { #[test] fn all_sibling_system_parachains_works() { // system parachain - assert!(AllSiblingSystemParachains::contains(&MultiLocation::new(1, X1(Parachain(1))))); + assert!(AllSiblingSystemParachains::contains(&Location::new(1, [Parachain(1)]))); // non-system parachain - assert!(!AllSiblingSystemParachains::contains(&MultiLocation::new( + assert!(!AllSiblingSystemParachains::contains(&Location::new( 1, - X1(Parachain(LOWEST_PUBLIC_ID.into())) + [Parachain(LOWEST_PUBLIC_ID.into())] ))); // when used at relay chain - assert!(!AllSiblingSystemParachains::contains(&MultiLocation::new(0, X1(Parachain(1))))); + assert!(!AllSiblingSystemParachains::contains(&Location::new(0, [Parachain(1)]))); // when used with non-parachain - assert!(!AllSiblingSystemParachains::contains(&MultiLocation::new(1, X1(OnlyChild)))); + assert!(!AllSiblingSystemParachains::contains(&Location::new(1, [OnlyChild]))); } } diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs index 244a846bbc2..8f586a46a75 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs @@ -15,7 +15,9 @@ mod genesis; pub use genesis::{genesis, ED, PARA_ID_A, PARA_ID_B}; -pub use penpal_runtime::xcm_config::{LocalTeleportableToAssetHub, XcmConfig}; +pub use penpal_runtime::xcm_config::{ + LocalTeleportableToAssetHub, LocalTeleportableToAssetHubV3, XcmConfig, +}; // Substrate use frame_support::traits::OnInitialize; diff --git a/cumulus/parachains/integration-tests/emulated/common/src/impls.rs b/cumulus/parachains/integration-tests/emulated/common/src/impls.rs index aa3ec214f8c..4bbb4701e43 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/impls.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/impls.rs @@ -38,8 +38,9 @@ pub use polkadot_runtime_parachains::{ inclusion::{AggregateMessageOrigin, UmpQueueId}, }; pub use xcm::{ - prelude::{MultiLocation, OriginKind, Outcome, VersionedXcm, XcmVersion}, - v3::Error, + prelude::{Location, OriginKind, Outcome, VersionedXcm, XcmVersion}, + v3, + v4::Error as XcmError, DoubleEncoded, }; @@ -209,7 +210,7 @@ macro_rules! impl_assert_events_helpers_for_relay_chain { Self, vec![ [<$chain RuntimeEvent>]::::XcmPallet( - $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Complete(weight) } + $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Complete { used: weight } } ) => { weight: $crate::impls::weight_within_threshold( ($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD), @@ -224,21 +225,21 @@ macro_rules! impl_assert_events_helpers_for_relay_chain { /// Asserts a dispatchable is incompletely executed and XCM sent pub fn assert_xcm_pallet_attempted_incomplete( expected_weight: Option<$crate::impls::Weight>, - expected_error: Option<$crate::impls::Error>, + expected_error: Option<$crate::impls::XcmError>, ) { $crate::impls::assert_expected_events!( Self, vec![ // Dispatchable is properly executed and XCM message sent [<$chain RuntimeEvent>]::::XcmPallet( - $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Incomplete(weight, error) } + $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Incomplete { used: weight, error } } ) => { weight: $crate::impls::weight_within_threshold( ($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD), expected_weight.unwrap_or(*weight), *weight ), - error: *error == expected_error.unwrap_or(*error), + error: *error == expected_error.unwrap_or((*error).into()).into(), }, ] ); @@ -365,7 +366,7 @@ macro_rules! impl_send_transact_helpers_for_relay_chain { ::execute_with(|| { let root_origin = ::RuntimeOrigin::root(); - let destination: $crate::impls::MultiLocation = ::child_location_of(recipient); + let destination: $crate::impls::Location = ::child_location_of(recipient); let xcm = $crate::impls::xcm_transact_unpaid_execution(call, $crate::impls::OriginKind::Superuser); // Send XCM `Transact` @@ -416,13 +417,13 @@ macro_rules! impl_accounts_helpers_for_parachain { network_id: $crate::impls::NetworkId, para_id: $crate::impls::ParaId, ) -> $crate::impls::AccountId { - let remote_location = $crate::impls::MultiLocation { - parents: 2, - interior: $crate::impls::Junctions::X2( + let remote_location = $crate::impls::Location::new( + 2, + [ $crate::impls::Junction::GlobalConsensus(network_id), $crate::impls::Junction::Parachain(para_id.into()), - ), - }; + ], + ); ::execute_with(|| { Self::sovereign_account_id_of(remote_location) }) @@ -445,7 +446,7 @@ macro_rules! impl_assert_events_helpers_for_parachain { Self, vec![ [<$chain RuntimeEvent>]::::PolkadotXcm( - $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Complete(weight) } + $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Complete { used: weight } } ) => { weight: $crate::impls::weight_within_threshold( ($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD), @@ -460,36 +461,36 @@ macro_rules! impl_assert_events_helpers_for_parachain { /// Asserts a dispatchable is incompletely executed and XCM sent pub fn assert_xcm_pallet_attempted_incomplete( expected_weight: Option<$crate::impls::Weight>, - expected_error: Option<$crate::impls::Error>, + expected_error: Option<$crate::impls::XcmError>, ) { $crate::impls::assert_expected_events!( Self, vec![ // Dispatchable is properly executed and XCM message sent [<$chain RuntimeEvent>]::::PolkadotXcm( - $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Incomplete(weight, error) } + $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Incomplete { used: weight, error } } ) => { weight: $crate::impls::weight_within_threshold( ($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD), expected_weight.unwrap_or(*weight), *weight ), - error: *error == expected_error.unwrap_or(*error), + error: *error == expected_error.unwrap_or((*error).into()).into(), }, ] ); } /// Asserts a dispatchable throws and error when trying to be sent - pub fn assert_xcm_pallet_attempted_error(expected_error: Option<$crate::impls::Error>) { + pub fn assert_xcm_pallet_attempted_error(expected_error: Option<$crate::impls::XcmError>) { $crate::impls::assert_expected_events!( Self, vec![ // Execution fails in the origin with `Barrier` [<$chain RuntimeEvent>]::::PolkadotXcm( - $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Error(error) } + $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Error { error } } ) => { - error: *error == expected_error.unwrap_or(*error), + error: *error == expected_error.unwrap_or((*error).into()).into(), }, ] ); @@ -639,7 +640,7 @@ macro_rules! impl_assets_helpers_for_parachain { ::execute_with(|| { $crate::impls::assert_ok!(]>::Assets::mint( signed_origin, - id.into(), + id.clone().into(), beneficiary.clone().into(), amount_to_mint )); @@ -717,7 +718,7 @@ macro_rules! impl_assets_helpers_for_parachain { ] ); - assert!(]>::Assets::asset_exists(id.into())); + assert!(]>::Assets::asset_exists(id.clone().into())); }); } } @@ -732,7 +733,7 @@ macro_rules! impl_foreign_assets_helpers_for_parachain { impl $chain { /// Create foreign assets using sudo `ForeignAssets::force_create()` pub fn force_create_foreign_asset( - id: $crate::impls::MultiLocation, + id: $crate::impls::v3::Location, owner: $crate::impls::AccountId, is_sufficient: bool, min_balance: u128, @@ -744,13 +745,13 @@ macro_rules! impl_foreign_assets_helpers_for_parachain { $crate::impls::assert_ok!( ]>::ForeignAssets::force_create( sudo_origin, - id, + id.clone(), owner.clone().into(), is_sufficient, min_balance, ) ); - assert!(]>::ForeignAssets::asset_exists(id)); + assert!(]>::ForeignAssets::asset_exists(id.clone())); type RuntimeEvent = <$chain as $crate::impls::Chain>::RuntimeEvent; $crate::impls::assert_expected_events!( Self, @@ -767,21 +768,21 @@ macro_rules! impl_foreign_assets_helpers_for_parachain { for (beneficiary, amount) in prefund_accounts.into_iter() { let signed_origin = <$chain as $crate::impls::Chain>::RuntimeOrigin::signed(owner.clone()); - Self::mint_foreign_asset(signed_origin, id, beneficiary, amount); + Self::mint_foreign_asset(signed_origin, id.clone(), beneficiary, amount); } } /// Mint assets making use of the ForeignAssets pallet-assets instance pub fn mint_foreign_asset( signed_origin: ::RuntimeOrigin, - id: $crate::impls::MultiLocation, + id: $crate::impls::v3::Location, beneficiary: $crate::impls::AccountId, amount_to_mint: u128, ) { ::execute_with(|| { $crate::impls::assert_ok!(]>::ForeignAssets::mint( signed_origin, - id.into(), + id.clone().into(), beneficiary.clone().into(), amount_to_mint )); @@ -813,7 +814,7 @@ macro_rules! impl_xcm_helpers_for_parachain { $crate::impls::paste::paste! { impl $chain { /// Set XCM version for destination. - pub fn force_xcm_version(dest: $crate::impls::MultiLocation, version: $crate::impls::XcmVersion) { + pub fn force_xcm_version(dest: $crate::impls::Location, version: $crate::impls::XcmVersion) { ::execute_with(|| { $crate::impls::assert_ok!(]>::PolkadotXcm::force_xcm_version( ::RuntimeOrigin::root(), diff --git a/cumulus/parachains/integration-tests/emulated/common/src/lib.rs b/cumulus/parachains/integration-tests/emulated/common/src/lib.rs index 48ee1a3b780..ad69d5576aa 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/lib.rs @@ -40,6 +40,7 @@ use polkadot_service::chain_spec::get_authority_keys_from_seed_no_beefy; pub const XCM_V2: u32 = 2; pub const XCM_V3: u32 = 3; +pub const XCM_V4: u32 = 4; pub const REF_TIME_THRESHOLD: u64 = 33; pub const PROOF_SIZE_THRESHOLD: u64 = 33; diff --git a/cumulus/parachains/integration-tests/emulated/common/src/macros.rs b/cumulus/parachains/integration-tests/emulated/common/src/macros.rs index 8718f1e83a0..01a376e4dbf 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/macros.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/macros.rs @@ -48,7 +48,7 @@ macro_rules! test_parachain_is_trusted_teleporter { <$receiver_para as $crate::macros::Chain>::account_data_of(receiver.clone()).free; let para_destination = <$sender_para>::sibling_location_of(<$receiver_para>::para_id()); - let beneficiary: MultiLocation = + let beneficiary: Location = $crate::macros::AccountId32 { network: None, id: receiver.clone().into() }.into(); // Send XCM message from Origin Parachain @@ -57,8 +57,8 @@ macro_rules! test_parachain_is_trusted_teleporter { <$sender_para>::execute_with(|| { assert_ok!(<$sender_para as [<$sender_para Pallet>]>::PolkadotXcm::limited_teleport_assets( origin.clone(), - bx!(para_destination.into()), - bx!(beneficiary.into()), + bx!(para_destination.clone().into()), + bx!(beneficiary.clone().into()), bx!($assets.clone().into()), fee_asset_item, weight_limit.clone(), @@ -127,8 +127,8 @@ macro_rules! include_penpal_create_foreign_asset_on_asset_hub { $crate::impls::paste::paste! { pub fn penpal_create_foreign_asset_on_asset_hub( asset_id_on_penpal: u32, - foreign_asset_at_asset_hub: MultiLocation, - ah_as_seen_by_penpal: MultiLocation, + foreign_asset_at_asset_hub: v3::Location, + ah_as_seen_by_penpal: Location, is_sufficient: bool, asset_owner: AccountId, prefund_amount: u128, @@ -144,14 +144,14 @@ macro_rules! include_penpal_create_foreign_asset_on_asset_hub { // prefund SA of Penpal on AssetHub with enough native tokens to pay for creating // new foreign asset, also prefund CheckingAccount with ED, because teleported asset // itself might not be sufficient and CheckingAccount cannot be created otherwise - let sov_penpal_on_ah = $asset_hub::sovereign_account_id_of(penpal_as_seen_by_ah); + let sov_penpal_on_ah = $asset_hub::sovereign_account_id_of(penpal_as_seen_by_ah.clone()); $asset_hub::fund_accounts(vec![ (sov_penpal_on_ah.clone().into(), $relay_ed * 100_000_000_000), (ah_check_account.clone().into(), $relay_ed * 1000), ]); // prefund SA of AssetHub on Penpal with native asset - let sov_ah_on_penpal = $penpal::sovereign_account_id_of(ah_as_seen_by_penpal); + let sov_ah_on_penpal = $penpal::sovereign_account_id_of(ah_as_seen_by_penpal.clone()); $penpal::fund_accounts(vec![ (sov_ah_on_penpal.into(), $relay_ed * 1_000_000_000), (penpal_check_account.clone().into(), $relay_ed * 1000), @@ -183,8 +183,8 @@ macro_rules! include_penpal_create_foreign_asset_on_asset_hub { let buy_execution_fee_amount = $weight_to_fee::weight_to_fee( &Weight::from_parts(10_100_000_000_000, 300_000), ); - let buy_execution_fee = MultiAsset { - id: Concrete(MultiLocation { parents: 1, interior: Here }), + let buy_execution_fee = Asset { + id: AssetId(Location { parents: 1, interior: Here }), fun: Fungible(buy_execution_fee_amount), }; let xcm = VersionedXcm::from(Xcm(vec![ diff --git a/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs b/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs index 70a9408c309..25e1cffad54 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs @@ -23,12 +23,12 @@ use xcm::{prelude::*, DoubleEncoded}; pub fn xcm_transact_paid_execution( call: DoubleEncoded<()>, origin_kind: OriginKind, - native_asset: MultiAsset, + native_asset: Asset, beneficiary: AccountId, ) -> VersionedXcm<()> { let weight_limit = WeightLimit::Unlimited; let require_weight_at_most = Weight::from_parts(1000000000, 200000); - let native_assets: MultiAssets = native_asset.clone().into(); + let native_assets: Assets = native_asset.clone().into(); VersionedXcm::from(Xcm(vec![ WithdrawAsset(native_assets), @@ -37,9 +37,9 @@ pub fn xcm_transact_paid_execution( RefundSurplus, DepositAsset { assets: All.into(), - beneficiary: MultiLocation { + beneficiary: Location { parents: 0, - interior: X1(AccountId32 { network: None, id: beneficiary.into() }), + interior: [AccountId32 { network: None, id: beneficiary.into() }].into(), }, }, ])) @@ -61,15 +61,11 @@ pub fn xcm_transact_unpaid_execution( } /// Helper method to get the non-fee asset used in multiple assets transfer -pub fn non_fee_asset(assets: &MultiAssets, fee_idx: usize) -> Option<(MultiLocation, u128)> { +pub fn non_fee_asset(assets: &Assets, fee_idx: usize) -> Option<(Location, u128)> { let asset = assets.inner().into_iter().enumerate().find(|a| a.0 != fee_idx)?.1.clone(); - let asset_id = match asset.id { - Concrete(id) => id, - _ => return None, - }; let asset_amount = match asset.fun { Fungible(amount) => amount, _ => return None, }; - Some((asset_id, asset_amount)) + Some((asset.id.0, asset_amount)) } diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/lib.rs index 721f8b511ea..155c952327a 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/lib.rs @@ -26,7 +26,7 @@ pub use frame_support::{ // Polkadot pub use xcm::{ prelude::{AccountId32 as AccountId32Junction, *}, - v3::{Error, NetworkId::Rococo as RococoId}, + v3::{self, Error, NetworkId::Rococo as RococoId}, }; // Cumulus diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs index 24a71d3fb45..dfc0bc6ff39 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs @@ -30,7 +30,7 @@ fn relay_to_para_sender_assertions(t: RelayToParaTest) { ) => { from: *from == t.sender.account_id, to: *to == Rococo::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, @@ -53,7 +53,7 @@ fn system_para_to_para_sender_assertions(t: SystemParaToParaTest) { ) => { from: *from == t.sender.account_id, to: *to == AssetHubRococo::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, @@ -130,7 +130,7 @@ fn system_para_to_para_assets_sender_assertions(t: SystemParaToParaTest) { asset_id: *asset_id == ASSET_ID, from: *from == t.sender.account_id, to: *to == AssetHubRococo::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, @@ -190,10 +190,10 @@ fn para_to_system_para_reserve_transfer_assets(t: ParaToSystemParaTest) -> Dispa fn reserve_transfer_native_asset_from_relay_to_system_para_fails() { let signed_origin = ::RuntimeOrigin::signed(RococoSender::get().into()); let destination = Rococo::child_location_of(AssetHubRococo::para_id()); - let beneficiary: MultiLocation = + let beneficiary: Location = AccountId32Junction { network: None, id: AssetHubRococoReceiver::get().into() }.into(); let amount_to_send: Balance = ROCOCO_ED * 1000; - let assets: MultiAssets = (Here, amount_to_send).into(); + let assets: Assets = (Here, amount_to_send).into(); let fee_asset_item = 0; // this should fail @@ -225,11 +225,11 @@ fn reserve_transfer_native_asset_from_system_para_to_relay_fails() { ::RuntimeOrigin::signed(AssetHubRococoSender::get().into()); let destination = AssetHubRococo::parent_location(); let beneficiary_id = RococoReceiver::get(); - let beneficiary: MultiLocation = + let beneficiary: Location = AccountId32Junction { network: None, id: beneficiary_id.into() }.into(); let amount_to_send: Balance = ASSET_HUB_ROCOCO_ED * 1000; - let assets: MultiAssets = (Parent, amount_to_send).into(); + let assets: Assets = (Parent, amount_to_send).into(); let fee_asset_item = 0; // this should fail @@ -418,9 +418,9 @@ fn reserve_transfer_assets_from_system_para_to_para() { let beneficiary_id = PenpalAReceiver::get(); let fee_amount_to_send = ASSET_HUB_ROCOCO_ED * 1000; let asset_amount_to_send = ASSET_MIN_BALANCE * 1000; - let assets: MultiAssets = vec![ + let assets: Assets = vec![ (Parent, fee_amount_to_send).into(), - (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), asset_amount_to_send) + ([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], asset_amount_to_send) .into(), ] .into(); diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/set_xcm_versions.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/set_xcm_versions.rs index 8faba50fc88..7d630d36805 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/set_xcm_versions.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/set_xcm_versions.rs @@ -19,14 +19,13 @@ use crate::*; fn relay_sets_system_para_xcm_supported_version() { // Init tests variables let sudo_origin = ::RuntimeOrigin::root(); - let system_para_destination: MultiLocation = - Rococo::child_location_of(AssetHubRococo::para_id()); + let system_para_destination: Location = Rococo::child_location_of(AssetHubRococo::para_id()); // Relay Chain sets supported version for Asset Parachain Rococo::execute_with(|| { assert_ok!(::XcmPallet::force_xcm_version( sudo_origin, - bx!(system_para_destination), + bx!(system_para_destination.clone()), XCM_V3 )); @@ -52,7 +51,7 @@ fn system_para_sets_relay_xcm_supported_version() { ::RuntimeCall::PolkadotXcm(pallet_xcm::Call::< ::Runtime, >::force_xcm_version { - location: bx!(parent_location), + location: bx!(parent_location.clone()), version: XCM_V3, }) .encode() diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs index b1af69a1cd1..d6aade68086 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs @@ -15,16 +15,19 @@ use crate::*; use parachains_common::rococo::currency::EXISTENTIAL_DEPOSIT; -use rococo_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHub as PenpalLocalTeleportableToAssetHub; +use rococo_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHubV3 as PenpalLocalTeleportableToAssetHubV3; use sp_runtime::ModuleError; #[test] fn swap_locally_on_chain_using_local_assets() { - let asset_native = asset_hub_rococo_runtime::xcm_config::TokenLocation::get(); - let asset_one = MultiLocation { - parents: 0, - interior: X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), - }; + let asset_native = Box::new(asset_hub_rococo_runtime::xcm_config::TokenLocationV3::get()); + let asset_one = Box::new(v3::Location::new( + 0, + [ + v3::Junction::PalletInstance(ASSETS_PALLET_ID), + v3::Junction::GeneralIndex(ASSET_ID.into()), + ], + )); AssetHubRococo::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; @@ -46,8 +49,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(asset_native), - Box::new(asset_one), + asset_native.clone(), + asset_one.clone(), )); assert_expected_events!( @@ -59,8 +62,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(asset_native), - Box::new(asset_one), + asset_native.clone(), + asset_one.clone(), 1_000_000_000_000, 2_000_000_000_000, 0, @@ -75,7 +78,7 @@ fn swap_locally_on_chain_using_local_assets() { ] ); - let path = vec![Box::new(asset_native), Box::new(asset_one)]; + let path = vec![asset_native.clone(), asset_one.clone()]; assert_ok!( ::AssetConversion::swap_exact_tokens_for_tokens( @@ -100,8 +103,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::remove_liquidity( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(asset_native), - Box::new(asset_one), + asset_native, + asset_one, 1414213562273 - EXISTENTIAL_DEPOSIT * 2, // all but the 2 EDs can't be retrieved. 0, 0, @@ -112,16 +115,16 @@ fn swap_locally_on_chain_using_local_assets() { #[test] fn swap_locally_on_chain_using_foreign_assets() { - let asset_native = asset_hub_rococo_runtime::xcm_config::TokenLocation::get(); + let asset_native = Box::new(asset_hub_rococo_runtime::xcm_config::TokenLocationV3::get()); let ah_as_seen_by_penpal = PenpalA::sibling_location_of(AssetHubRococo::para_id()); - let asset_location_on_penpal = PenpalLocalTeleportableToAssetHub::get(); + let asset_location_on_penpal = PenpalLocalTeleportableToAssetHubV3::get(); let asset_id_on_penpal = match asset_location_on_penpal.last() { - Some(GeneralIndex(id)) => *id as u32, + Some(v3::Junction::GeneralIndex(id)) => *id as u32, _ => unreachable!(), }; let asset_owner_on_penpal = PenpalASender::get(); let foreign_asset_at_asset_hub_rococo = - MultiLocation { parents: 1, interior: X1(Parachain(PenpalA::para_id().into())) } + v3::Location::new(1, [v3::Junction::Parachain(PenpalA::para_id().into())]) .appended_with(asset_location_on_penpal) .unwrap(); @@ -167,7 +170,7 @@ fn swap_locally_on_chain_using_foreign_assets() { // 4. Create pool: assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(asset_native), + asset_native.clone(), Box::new(foreign_asset_at_asset_hub_rococo), )); @@ -181,7 +184,7 @@ fn swap_locally_on_chain_using_foreign_assets() { // 5. Add liquidity: assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(sov_penpal_on_ahr.clone()), - Box::new(asset_native), + asset_native.clone(), Box::new(foreign_asset_at_asset_hub_rococo), 1_000_000_000_000, 2_000_000_000_000, @@ -200,7 +203,7 @@ fn swap_locally_on_chain_using_foreign_assets() { ); // 6. Swap! - let path = vec![Box::new(asset_native), Box::new(foreign_asset_at_asset_hub_rococo)]; + let path = vec![asset_native.clone(), Box::new(foreign_asset_at_asset_hub_rococo)]; assert_ok!( ::AssetConversion::swap_exact_tokens_for_tokens( @@ -226,7 +229,7 @@ fn swap_locally_on_chain_using_foreign_assets() { // 7. Remove liquidity assert_ok!(::AssetConversion::remove_liquidity( ::RuntimeOrigin::signed(sov_penpal_on_ahr.clone()), - Box::new(asset_native), + asset_native.clone(), Box::new(foreign_asset_at_asset_hub_rococo), 1414213562273 - 2_000_000_000, // all but the 2 EDs can't be retrieved. 0, @@ -238,9 +241,11 @@ fn swap_locally_on_chain_using_foreign_assets() { #[test] fn cannot_create_pool_from_pool_assets() { - let asset_native = asset_hub_rococo_runtime::xcm_config::TokenLocation::get(); - let mut asset_one = asset_hub_rococo_runtime::xcm_config::PoolAssetsPalletLocation::get(); - asset_one.append_with(GeneralIndex(ASSET_ID.into())).expect("pool assets"); + let asset_native = Box::new(asset_hub_rococo_runtime::xcm_config::TokenLocationV3::get()); + let mut asset_one = asset_hub_rococo_runtime::xcm_config::PoolAssetsPalletLocationV3::get(); + asset_one + .append_with(v3::Junction::GeneralIndex(ASSET_ID.into())) + .expect("pool assets"); AssetHubRococo::execute_with(|| { let pool_owner_account_id = asset_hub_rococo_runtime::AssetConversionOrigin::get(); @@ -263,7 +268,7 @@ fn cannot_create_pool_from_pool_assets() { assert_matches::assert_matches!( ::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(asset_native), + asset_native, Box::new(asset_one), ), Err(DispatchError::Module(ModuleError{index: _, error: _, message})) => assert_eq!(message, Some("Unknown")) @@ -273,10 +278,14 @@ fn cannot_create_pool_from_pool_assets() { #[test] fn pay_xcm_fee_with_some_asset_swapped_for_native() { - let asset_native = asset_hub_rococo_runtime::xcm_config::TokenLocation::get(); - let asset_one = MultiLocation { + let asset_native = asset_hub_rococo_runtime::xcm_config::TokenLocationV3::get(); + let asset_one = xcm::v3::Location { parents: 0, - interior: X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), + interior: [ + xcm::v3::Junction::PalletInstance(ASSETS_PALLET_ID), + xcm::v3::Junction::GeneralIndex(ASSET_ID.into()), + ] + .into(), }; let penpal = AssetHubRococo::sovereign_account_id_of(AssetHubRococo::sibling_location_of( PenpalA::para_id(), @@ -365,8 +374,7 @@ fn pay_xcm_fee_with_some_asset_swapped_for_native() { let penpal_root = ::RuntimeOrigin::root(); let fee_amount = 4_000_000_000_000u128; let asset_one = - (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), fee_amount) - .into(); + ([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], fee_amount).into(); let asset_hub_location = PenpalA::sibling_location_of(AssetHubRococo::para_id()).into(); let xcm = xcm_transact_paid_execution( call, diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/teleport.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/teleport.rs index a07463cec50..218234cc78e 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/teleport.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/teleport.rs @@ -17,7 +17,7 @@ use crate::*; use asset_hub_rococo_runtime::xcm_config::XcmConfig as AssetHubRococoXcmConfig; use emulated_integration_tests_common::xcm_helpers::non_fee_asset; use rococo_runtime::xcm_config::XcmConfig as RococoXcmConfig; -use rococo_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHub as PenpalLocalTeleportableToAssetHub; +use rococo_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHubV3 as PenpalLocalTeleportableToAssetHubV3; fn relay_origin_assertions(t: RelayToSystemParaTest) { type RuntimeEvent = ::RuntimeEvent; @@ -143,6 +143,7 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) { ); let (expected_foreign_asset_id, expected_foreign_asset_amount) = non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + let expected_foreign_asset_id_v3: v3::Location = expected_foreign_asset_id.try_into().unwrap(); assert_expected_events!( AssetHubRococo, vec![ @@ -157,7 +158,7 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) { who: *who == t.receiver.account_id, }, RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { asset_id, owner, amount }) => { - asset_id: *asset_id == expected_foreign_asset_id, + asset_id: *asset_id == expected_foreign_asset_id_v3, owner: *owner == t.receiver.account_id, amount: *amount == expected_foreign_asset_amount, }, @@ -174,6 +175,7 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) { AssetHubRococo::assert_xcm_pallet_attempted_complete(None); let (expected_foreign_asset_id, expected_foreign_asset_amount) = non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + let expected_foreign_asset_id_v3: v3::Location = expected_foreign_asset_id.try_into().unwrap(); assert_expected_events!( AssetHubRococo, vec![ @@ -183,13 +185,13 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) { ) => { from: *from == t.sender.account_id, to: *to == AssetHubRococo::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, // foreign asset is burned locally as part of teleportation RuntimeEvent::ForeignAssets(pallet_assets::Event::Burned { asset_id, owner, balance }) => { - asset_id: *asset_id == expected_foreign_asset_id, + asset_id: *asset_id == expected_foreign_asset_id_v3, owner: *owner == t.sender.account_id, balance: *balance == expected_foreign_asset_amount, }, @@ -542,7 +544,7 @@ fn teleport_native_assets_from_system_para_to_relay_fails() { #[test] fn teleport_to_other_system_parachains_works() { let amount = ASSET_HUB_ROCOCO_ED * 100; - let native_asset: MultiAssets = (Parent, amount).into(); + let native_asset: Assets = (Parent, amount).into(); test_parachain_is_trusted_teleporter!( AssetHubRococo, // Origin @@ -557,20 +559,20 @@ fn teleport_to_other_system_parachains_works() { #[test] fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() { let ah_as_seen_by_penpal = PenpalA::sibling_location_of(AssetHubRococo::para_id()); - let asset_location_on_penpal = PenpalLocalTeleportableToAssetHub::get(); + let asset_location_on_penpal = PenpalLocalTeleportableToAssetHubV3::get(); let asset_id_on_penpal = match asset_location_on_penpal.last() { - Some(GeneralIndex(id)) => *id as u32, + Some(v3::Junction::GeneralIndex(id)) => *id as u32, _ => unreachable!(), }; let asset_owner_on_penpal = PenpalASender::get(); let foreign_asset_at_asset_hub_rococo = - MultiLocation { parents: 1, interior: X1(Parachain(PenpalA::para_id().into())) } + v3::Location::new(1, [v3::Junction::Parachain(PenpalA::para_id().into())]) .appended_with(asset_location_on_penpal) .unwrap(); super::penpal_create_foreign_asset_on_asset_hub( asset_id_on_penpal, foreign_asset_at_asset_hub_rococo, - ah_as_seen_by_penpal, + ah_as_seen_by_penpal.clone(), false, asset_owner_on_penpal, ASSET_MIN_BALANCE * 1_000_000, @@ -580,9 +582,10 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() { let fee_amount_to_send = ASSET_HUB_ROCOCO_ED * 10_000; let asset_amount_to_send = ASSET_MIN_BALANCE * 1000; - let penpal_assets: MultiAssets = vec![ + let asset_location_on_penpal_latest: Location = asset_location_on_penpal.try_into().unwrap(); + let penpal_assets: Assets = vec![ (Parent, fee_amount_to_send).into(), - (asset_location_on_penpal, asset_amount_to_send).into(), + (asset_location_on_penpal_latest, asset_amount_to_send).into(), ] .into(); let fee_asset_index = penpal_assets @@ -670,11 +673,13 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() { )); }); + let foreign_asset_at_asset_hub_rococo_latest: Location = + foreign_asset_at_asset_hub_rococo.try_into().unwrap(); let ah_to_penpal_beneficiary_id = PenpalAReceiver::get(); let penpal_as_seen_by_ah = AssetHubRococo::sibling_location_of(PenpalA::para_id()); - let ah_assets: MultiAssets = vec![ + let ah_assets: Assets = vec![ (Parent, fee_amount_to_send).into(), - (foreign_asset_at_asset_hub_rococo, asset_amount_to_send).into(), + (foreign_asset_at_asset_hub_rococo_latest, asset_amount_to_send).into(), ] .into(); let fee_asset_index = ah_assets diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs index fbeb08649e7..018e948e5d7 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs @@ -28,7 +28,7 @@ pub use frame_support::{ // Polkadot pub use xcm::{ prelude::{AccountId32 as AccountId32Junction, *}, - v3::{Error, NetworkId::Westend as WestendId}, + v3::{self, Error, NetworkId::Westend as WestendId}, }; // Cumulus diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/fellowship_treasury.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/fellowship_treasury.rs index d7de0a451f2..11e1e1762db 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/fellowship_treasury.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/fellowship_treasury.rs @@ -24,22 +24,20 @@ fn create_and_claim_treasury_spend() { const ASSET_ID: u32 = 1984; const SPEND_AMOUNT: u128 = 1_000_000; // treasury location from a sibling parachain. - let treasury_location: MultiLocation = MultiLocation::new( - 1, - X2(Parachain(CollectivesWestend::para_id().into()), PalletInstance(65)), - ); + let treasury_location: Location = + Location::new(1, [Parachain(CollectivesWestend::para_id().into()), PalletInstance(65)]); // treasury account on a sibling parachain. let treasury_account = asset_hub_westend_runtime::xcm_config::LocationToAccountId::convert_location( &treasury_location, ) .unwrap(); - let asset_hub_location = MultiLocation::new(1, Parachain(AssetHubWestend::para_id().into())); + let asset_hub_location = Location::new(1, [Parachain(AssetHubWestend::para_id().into())]); let root = ::RuntimeOrigin::root(); // asset kind to be spent from the treasury. - let asset_kind = VersionedLocatableAsset::V3 { + let asset_kind = VersionedLocatableAsset::V4 { location: asset_hub_location, - asset_id: AssetId::Concrete((PalletInstance(50), GeneralIndex(ASSET_ID.into())).into()), + asset_id: AssetId((PalletInstance(50), GeneralIndex(ASSET_ID.into())).into()), }; // treasury spend beneficiary. let alice: AccountId = Westend::account_id_of(ALICE); @@ -75,7 +73,7 @@ fn create_and_claim_treasury_spend() { root, Box::new(asset_kind), SPEND_AMOUNT, - Box::new(MultiLocation::new(0, Into::<[u8; 32]>::into(alice.clone())).into()), + Box::new(Location::new(0, Into::<[u8; 32]>::into(alice.clone())).into()), None, )); // claim the spend. diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs index 3cce6c4417e..a2934be9758 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs @@ -32,7 +32,7 @@ fn relay_to_para_sender_assertions(t: RelayToParaTest) { ) => { from: *from == t.sender.account_id, to: *to == Westend::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, @@ -57,7 +57,7 @@ fn system_para_to_para_sender_assertions(t: SystemParaToParaTest) { ) => { from: *from == t.sender.account_id, to: *to == AssetHubWestend::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, @@ -140,7 +140,7 @@ fn system_para_to_para_assets_sender_assertions(t: SystemParaToParaTest) { asset_id: *asset_id == ASSET_ID, from: *from == t.sender.account_id, to: *to == AssetHubWestend::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, @@ -200,10 +200,10 @@ fn para_to_system_para_reserve_transfer_assets(t: ParaToSystemParaTest) -> Dispa fn reserve_transfer_native_asset_from_relay_to_system_para_fails() { let signed_origin = ::RuntimeOrigin::signed(WestendSender::get().into()); let destination = Westend::child_location_of(AssetHubWestend::para_id()); - let beneficiary: MultiLocation = + let beneficiary: Location = AccountId32Junction { network: None, id: AssetHubWestendReceiver::get().into() }.into(); let amount_to_send: Balance = WESTEND_ED * 1000; - let assets: MultiAssets = (Here, amount_to_send).into(); + let assets: Assets = (Here, amount_to_send).into(); let fee_asset_item = 0; // this should fail @@ -235,10 +235,10 @@ fn reserve_transfer_native_asset_from_system_para_to_relay_fails() { ::RuntimeOrigin::signed(AssetHubWestendSender::get().into()); let destination = AssetHubWestend::parent_location(); let beneficiary_id = WestendReceiver::get(); - let beneficiary: MultiLocation = + let beneficiary: Location = AccountId32Junction { network: None, id: beneficiary_id.into() }.into(); let amount_to_send: Balance = ASSET_HUB_WESTEND_ED * 1000; - let assets: MultiAssets = (Parent, amount_to_send).into(); + let assets: Assets = (Parent, amount_to_send).into(); let fee_asset_item = 0; // this should fail @@ -428,9 +428,9 @@ fn reserve_transfer_assets_from_system_para_to_para() { let beneficiary_id = PenpalBReceiver::get(); let fee_amount_to_send = ASSET_HUB_WESTEND_ED * 1000; let asset_amount_to_send = ASSET_MIN_BALANCE * 1000; - let assets: MultiAssets = vec![ + let assets: Assets = vec![ (Parent, fee_amount_to_send).into(), - (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), asset_amount_to_send) + ([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], asset_amount_to_send) .into(), ] .into(); diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/set_xcm_versions.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/set_xcm_versions.rs index 2133d5e5fb7..130454551d2 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/set_xcm_versions.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/set_xcm_versions.rs @@ -19,14 +19,13 @@ use crate::*; fn relay_sets_system_para_xcm_supported_version() { // Init tests variables let sudo_origin = ::RuntimeOrigin::root(); - let system_para_destination: MultiLocation = - Westend::child_location_of(AssetHubWestend::para_id()); + let system_para_destination: Location = Westend::child_location_of(AssetHubWestend::para_id()); // Relay Chain sets supported version for Asset Parachain Westend::execute_with(|| { assert_ok!(::XcmPallet::force_xcm_version( sudo_origin, - bx!(system_para_destination), + bx!(system_para_destination.clone()), XCM_V3 )); @@ -52,7 +51,7 @@ fn system_para_sets_relay_xcm_supported_version() { ::RuntimeCall::PolkadotXcm(pallet_xcm::Call::< ::Runtime, >::force_xcm_version { - location: bx!(parent_location), + location: bx!(parent_location.clone()), version: XCM_V3, }) .encode() diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs index c768a1366fa..b39cc2159de 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs @@ -14,15 +14,19 @@ // limitations under the License. use crate::*; -use westend_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHub as PenpalLocalTeleportableToAssetHub; +use westend_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHubV3 as PenpalLocalTeleportableToAssetHubV3; #[test] fn swap_locally_on_chain_using_local_assets() { - let asset_native = asset_hub_westend_runtime::xcm_config::WestendLocation::get(); - let asset_one = MultiLocation { + let asset_native = Box::new(asset_hub_westend_runtime::xcm_config::WestendLocationV3::get()); + let asset_one = Box::new(v3::Location { parents: 0, - interior: X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), - }; + interior: [ + v3::Junction::PalletInstance(ASSETS_PALLET_ID), + v3::Junction::GeneralIndex(ASSET_ID.into()), + ] + .into(), + }); AssetHubWestend::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; @@ -44,8 +48,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(asset_native), - Box::new(asset_one), + asset_native.clone(), + asset_one.clone(), )); assert_expected_events!( @@ -57,8 +61,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(asset_native), - Box::new(asset_one), + asset_native.clone(), + asset_one.clone(), 1_000_000_000_000, 2_000_000_000_000, 0, @@ -73,7 +77,7 @@ fn swap_locally_on_chain_using_local_assets() { ] ); - let path = vec![Box::new(asset_native), Box::new(asset_one)]; + let path = vec![asset_native.clone(), asset_one.clone()]; assert_ok!(::AssetConversion::swap_exact_tokens_for_tokens( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), @@ -96,8 +100,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::remove_liquidity( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(asset_native), - Box::new(asset_one), + asset_native.clone(), + asset_one.clone(), 1414213562273 - 2_000_000_000, // all but the 2 EDs can't be retrieved. 0, 0, @@ -108,16 +112,16 @@ fn swap_locally_on_chain_using_local_assets() { #[test] fn swap_locally_on_chain_using_foreign_assets() { - let asset_native = asset_hub_westend_runtime::xcm_config::WestendLocation::get(); + let asset_native = Box::new(asset_hub_westend_runtime::xcm_config::WestendLocationV3::get()); let ah_as_seen_by_penpal = PenpalB::sibling_location_of(AssetHubWestend::para_id()); - let asset_location_on_penpal = PenpalLocalTeleportableToAssetHub::get(); + let asset_location_on_penpal = PenpalLocalTeleportableToAssetHubV3::get(); let asset_id_on_penpal = match asset_location_on_penpal.last() { - Some(GeneralIndex(id)) => *id as u32, + Some(v3::Junction::GeneralIndex(id)) => *id as u32, _ => unreachable!(), }; let asset_owner_on_penpal = PenpalBSender::get(); let foreign_asset_at_asset_hub_westend = - MultiLocation { parents: 1, interior: X1(Parachain(PenpalB::para_id().into())) } + v3::Location::new(1, [v3::Junction::Parachain(PenpalB::para_id().into())]) .appended_with(asset_location_on_penpal) .unwrap(); @@ -163,7 +167,7 @@ fn swap_locally_on_chain_using_foreign_assets() { // 4. Create pool: assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(asset_native), + asset_native.clone(), Box::new(foreign_asset_at_asset_hub_westend), )); @@ -177,7 +181,7 @@ fn swap_locally_on_chain_using_foreign_assets() { // 5. Add liquidity: assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(sov_penpal_on_ahw.clone()), - Box::new(asset_native), + asset_native.clone(), Box::new(foreign_asset_at_asset_hub_westend), 1_000_000_000_000, 2_000_000_000_000, @@ -196,7 +200,7 @@ fn swap_locally_on_chain_using_foreign_assets() { ); // 6. Swap! - let path = vec![Box::new(asset_native), Box::new(foreign_asset_at_asset_hub_westend)]; + let path = vec![asset_native.clone(), Box::new(foreign_asset_at_asset_hub_westend)]; assert_ok!(::AssetConversion::swap_exact_tokens_for_tokens( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), @@ -220,7 +224,7 @@ fn swap_locally_on_chain_using_foreign_assets() { // 7. Remove liquidity assert_ok!(::AssetConversion::remove_liquidity( ::RuntimeOrigin::signed(sov_penpal_on_ahw.clone()), - Box::new(asset_native), + asset_native.clone(), Box::new(foreign_asset_at_asset_hub_westend), 1414213562273 - 2_000_000_000, // all but the 2 EDs can't be retrieved. 0, @@ -232,9 +236,11 @@ fn swap_locally_on_chain_using_foreign_assets() { #[test] fn cannot_create_pool_from_pool_assets() { - let asset_native = asset_hub_westend_runtime::xcm_config::WestendLocation::get(); - let mut asset_one = asset_hub_westend_runtime::xcm_config::PoolAssetsPalletLocation::get(); - asset_one.append_with(GeneralIndex(ASSET_ID.into())).expect("pool assets"); + let asset_native = Box::new(asset_hub_westend_runtime::xcm_config::WestendLocationV3::get()); + let mut asset_one = asset_hub_westend_runtime::xcm_config::PoolAssetsPalletLocationV3::get(); + asset_one + .append_with(v3::Junction::GeneralIndex(ASSET_ID.into())) + .expect("pool assets"); AssetHubWestend::execute_with(|| { let pool_owner_account_id = asset_hub_westend_runtime::AssetConversionOrigin::get(); @@ -257,7 +263,7 @@ fn cannot_create_pool_from_pool_assets() { assert_matches::assert_matches!( ::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(asset_native), + asset_native, Box::new(asset_one), ), Err(DispatchError::Module(ModuleError{index: _, error: _, message})) => assert_eq!(message, Some("Unknown")) @@ -267,10 +273,14 @@ fn cannot_create_pool_from_pool_assets() { #[test] fn pay_xcm_fee_with_some_asset_swapped_for_native() { - let asset_native = asset_hub_westend_runtime::xcm_config::WestendLocation::get(); - let asset_one = MultiLocation { + let asset_native = asset_hub_westend_runtime::xcm_config::WestendLocationV3::get(); + let asset_one = xcm::v3::Location { parents: 0, - interior: X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), + interior: [ + xcm::v3::Junction::PalletInstance(ASSETS_PALLET_ID), + xcm::v3::Junction::GeneralIndex(ASSET_ID.into()), + ] + .into(), }; let penpal = AssetHubWestend::sovereign_account_id_of(AssetHubWestend::sibling_location_of( PenpalB::para_id(), @@ -359,8 +369,7 @@ fn pay_xcm_fee_with_some_asset_swapped_for_native() { let penpal_root = ::RuntimeOrigin::root(); let fee_amount = 4_000_000_000_000u128; let asset_one = - (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), fee_amount) - .into(); + ([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], fee_amount).into(); let asset_hub_location = PenpalB::sibling_location_of(AssetHubWestend::para_id()).into(); let xcm = xcm_transact_paid_execution( call, diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/teleport.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/teleport.rs index 27a6e7aaaf4..01498f7bb4e 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/teleport.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/teleport.rs @@ -17,7 +17,7 @@ use crate::*; use asset_hub_westend_runtime::xcm_config::XcmConfig as AssetHubWestendXcmConfig; use emulated_integration_tests_common::xcm_helpers::non_fee_asset; use westend_runtime::xcm_config::XcmConfig as WestendXcmConfig; -use westend_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHub as PenpalLocalTeleportableToAssetHub; +use westend_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHubV3 as PenpalLocalTeleportableToAssetHubV3; fn relay_origin_assertions(t: RelayToSystemParaTest) { type RuntimeEvent = ::RuntimeEvent; @@ -143,6 +143,7 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) { ); let (expected_foreign_asset_id, expected_foreign_asset_amount) = non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + let expected_foreign_asset_id_v3: v3::Location = expected_foreign_asset_id.try_into().unwrap(); assert_expected_events!( AssetHubWestend, vec![ @@ -157,7 +158,7 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) { who: *who == t.receiver.account_id, }, RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { asset_id, owner, amount }) => { - asset_id: *asset_id == expected_foreign_asset_id, + asset_id: *asset_id == expected_foreign_asset_id_v3, owner: *owner == t.receiver.account_id, amount: *amount == expected_foreign_asset_amount, }, @@ -174,6 +175,7 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) { AssetHubWestend::assert_xcm_pallet_attempted_complete(None); let (expected_foreign_asset_id, expected_foreign_asset_amount) = non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + let expected_foreign_asset_id_v3: v3::Location = expected_foreign_asset_id.try_into().unwrap(); assert_expected_events!( AssetHubWestend, vec![ @@ -183,13 +185,13 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) { ) => { from: *from == t.sender.account_id, to: *to == AssetHubWestend::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, // foreign asset is burned locally as part of teleportation RuntimeEvent::ForeignAssets(pallet_assets::Event::Burned { asset_id, owner, balance }) => { - asset_id: *asset_id == expected_foreign_asset_id, + asset_id: *asset_id == expected_foreign_asset_id_v3, owner: *owner == t.sender.account_id, balance: *balance == expected_foreign_asset_amount, }, @@ -542,7 +544,7 @@ fn teleport_native_assets_from_system_para_to_relay_fails() { #[test] fn teleport_to_other_system_parachains_works() { let amount = ASSET_HUB_WESTEND_ED * 100; - let native_asset: MultiAssets = (Parent, amount).into(); + let native_asset: Assets = (Parent, amount).into(); test_parachain_is_trusted_teleporter!( AssetHubWestend, // Origin @@ -557,20 +559,20 @@ fn teleport_to_other_system_parachains_works() { #[test] fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() { let ah_as_seen_by_penpal = PenpalB::sibling_location_of(AssetHubWestend::para_id()); - let asset_location_on_penpal = PenpalLocalTeleportableToAssetHub::get(); + let asset_location_on_penpal = PenpalLocalTeleportableToAssetHubV3::get(); let asset_id_on_penpal = match asset_location_on_penpal.last() { - Some(GeneralIndex(id)) => *id as u32, + Some(v3::Junction::GeneralIndex(id)) => *id as u32, _ => unreachable!(), }; let asset_owner_on_penpal = PenpalBSender::get(); let foreign_asset_at_asset_hub_westend = - MultiLocation { parents: 1, interior: X1(Parachain(PenpalB::para_id().into())) } + v3::Location::new(1, [v3::Junction::Parachain(PenpalB::para_id().into())]) .appended_with(asset_location_on_penpal) .unwrap(); super::penpal_create_foreign_asset_on_asset_hub( asset_id_on_penpal, foreign_asset_at_asset_hub_westend, - ah_as_seen_by_penpal, + ah_as_seen_by_penpal.clone(), false, asset_owner_on_penpal, ASSET_MIN_BALANCE * 1_000_000, @@ -580,9 +582,10 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() { let fee_amount_to_send = ASSET_HUB_WESTEND_ED * 1000; let asset_amount_to_send = ASSET_MIN_BALANCE * 1000; - let penpal_assets: MultiAssets = vec![ + let asset_location_on_penpal_latest: Location = asset_location_on_penpal.try_into().unwrap(); + let penpal_assets: Assets = vec![ (Parent, fee_amount_to_send).into(), - (asset_location_on_penpal, asset_amount_to_send).into(), + (asset_location_on_penpal_latest, asset_amount_to_send).into(), ] .into(); let fee_asset_index = penpal_assets @@ -670,11 +673,13 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() { )); }); + let foreign_asset_at_asset_hub_westend_latest: Location = + foreign_asset_at_asset_hub_westend.try_into().unwrap(); let ah_to_penpal_beneficiary_id = PenpalBReceiver::get(); let penpal_as_seen_by_ah = AssetHubWestend::sibling_location_of(PenpalB::para_id()); - let ah_assets: MultiAssets = vec![ + let ah_assets: Assets = vec![ (Parent, fee_amount_to_send).into(), - (foreign_asset_at_asset_hub_westend, asset_amount_to_send).into(), + (foreign_asset_at_asset_hub_westend_latest, asset_amount_to_send).into(), ] .into(); let fee_asset_index = ah_assets diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/treasury.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/treasury.rs index 32089f7ecec..8e82059a32d 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/treasury.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/treasury.rs @@ -24,19 +24,19 @@ fn create_and_claim_treasury_spend() { const ASSET_ID: u32 = 1984; const SPEND_AMOUNT: u128 = 1_000_000; // treasury location from a sibling parachain. - let treasury_location: MultiLocation = MultiLocation::new(1, PalletInstance(37)); + let treasury_location: Location = Location::new(1, PalletInstance(37)); // treasury account on a sibling parachain. let treasury_account = asset_hub_westend_runtime::xcm_config::LocationToAccountId::convert_location( &treasury_location, ) .unwrap(); - let asset_hub_location = MultiLocation::new(0, Parachain(AssetHubWestend::para_id().into())); + let asset_hub_location = Location::new(0, Parachain(AssetHubWestend::para_id().into())); let root = ::RuntimeOrigin::root(); // asset kind to be spend from the treasury. - let asset_kind = VersionedLocatableAsset::V3 { + let asset_kind = VersionedLocatableAsset::V4 { location: asset_hub_location, - asset_id: AssetId::Concrete((PalletInstance(50), GeneralIndex(ASSET_ID.into())).into()), + asset_id: AssetId([PalletInstance(50), GeneralIndex(ASSET_ID.into())].into()), }; // treasury spend beneficiary. let alice: AccountId = Westend::account_id_of(ALICE); @@ -71,7 +71,7 @@ fn create_and_claim_treasury_spend() { root, Box::new(asset_kind), SPEND_AMOUNT, - Box::new(MultiLocation::new(0, Into::<[u8; 32]>::into(alice.clone())).into()), + Box::new(Location::new(0, Into::<[u8; 32]>::into(alice.clone())).into()), None, )); // claim the spend. diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs index 608aa388ce8..0039eb087fe 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs @@ -22,7 +22,7 @@ pub use xcm::{ latest::ParentThen, prelude::{AccountId32 as AccountId32Junction, *}, v3::{ - Error, + self, Error, NetworkId::{Rococo as RococoId, Westend as WestendId}, }, }; diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs index 8b5a72a8e62..a203de0f8c9 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs @@ -15,14 +15,14 @@ use crate::tests::*; -fn send_asset_from_asset_hub_rococo_to_asset_hub_westend(id: MultiLocation, amount: u128) { +fn send_asset_from_asset_hub_rococo_to_asset_hub_westend(id: Location, amount: u128) { let destination = asset_hub_westend_location(); // fund the AHR's SA on BHR for paying bridge transport fees BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id(), 10_000_000_000_000u128); // set XCM versions - AssetHubRococo::force_xcm_version(destination, XCM_VERSION); + AssetHubRococo::force_xcm_version(destination.clone(), XCM_VERSION); BridgeHubRococo::force_xcm_version(bridge_hub_westend_location(), XCM_VERSION); // send message over bridge @@ -33,9 +33,9 @@ fn send_asset_from_asset_hub_rococo_to_asset_hub_westend(id: MultiLocation, amou #[test] fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() { - let roc_at_asset_hub_rococo: MultiLocation = Parent.into(); + let roc_at_asset_hub_rococo: v3::Location = v3::Parent.into(); let roc_at_asset_hub_westend = - MultiLocation { parents: 2, interior: X1(GlobalConsensus(NetworkId::Rococo)) }; + v3::Location::new(2, [v3::Junction::GlobalConsensus(v3::NetworkId::Rococo)]); let owner: AccountId = AssetHubWestend::account_id_of(ALICE); AssetHubWestend::force_create_foreign_asset( roc_at_asset_hub_westend, @@ -62,7 +62,7 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() { assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(Parent.into()), + Box::new(xcm::v3::Parent.into()), Box::new(roc_at_asset_hub_westend), )); @@ -75,7 +75,7 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() { assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(Parent.into()), + Box::new(xcm::v3::Parent.into()), Box::new(roc_at_asset_hub_westend), 1_000_000_000_000, 2_000_000_000_000, @@ -101,8 +101,9 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() { >::balance(roc_at_asset_hub_westend, &AssetHubWestendReceiver::get()) }); + let roc_at_asset_hub_rococo_latest: Location = roc_at_asset_hub_rococo.try_into().unwrap(); let amount = ASSET_HUB_ROCOCO_ED * 1_000_000; - send_asset_from_asset_hub_rococo_to_asset_hub_westend(roc_at_asset_hub_rococo, amount); + send_asset_from_asset_hub_rococo_to_asset_hub_westend(roc_at_asset_hub_rococo_latest, amount); AssetHubWestend::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; assert_expected_events!( @@ -142,7 +143,7 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() { fn send_wnds_from_asset_hub_rococo_to_asset_hub_westend() { let prefund_amount = 10_000_000_000_000u128; let wnd_at_asset_hub_rococo = - MultiLocation { parents: 2, interior: X1(GlobalConsensus(NetworkId::Westend)) }; + v3::Location::new(2, [v3::Junction::GlobalConsensus(v3::NetworkId::Westend)]); let owner: AccountId = AssetHubWestend::account_id_of(ALICE); AssetHubRococo::force_create_foreign_asset( wnd_at_asset_hub_rococo, @@ -170,8 +171,12 @@ fn send_wnds_from_asset_hub_rococo_to_asset_hub_westend() { let receiver_wnds_before = ::account_data_of(AssetHubWestendReceiver::get()).free; + let wnd_at_asset_hub_rococo_latest: Location = wnd_at_asset_hub_rococo.try_into().unwrap(); let amount_to_send = ASSET_HUB_WESTEND_ED * 1_000; - send_asset_from_asset_hub_rococo_to_asset_hub_westend(wnd_at_asset_hub_rococo, amount_to_send); + send_asset_from_asset_hub_rococo_to_asset_hub_westend( + wnd_at_asset_hub_rococo_latest.clone(), + amount_to_send, + ); AssetHubWestend::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; assert_expected_events!( diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs index e71a022af4c..a33d2fab753 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs @@ -20,37 +20,31 @@ mod send_xcm; mod snowbridge; mod teleport; -pub(crate) fn asset_hub_westend_location() -> MultiLocation { - MultiLocation { - parents: 2, - interior: X2( - GlobalConsensus(NetworkId::Westend), - Parachain(AssetHubWestend::para_id().into()), - ), - } +pub(crate) fn asset_hub_westend_location() -> Location { + Location::new( + 2, + [GlobalConsensus(NetworkId::Westend), Parachain(AssetHubWestend::para_id().into())], + ) } -pub(crate) fn bridge_hub_westend_location() -> MultiLocation { - MultiLocation { - parents: 2, - interior: X2( - GlobalConsensus(NetworkId::Westend), - Parachain(BridgeHubWestend::para_id().into()), - ), - } +pub(crate) fn bridge_hub_westend_location() -> Location { + Location::new( + 2, + [GlobalConsensus(NetworkId::Westend), Parachain(BridgeHubWestend::para_id().into())], + ) } pub(crate) fn send_asset_from_asset_hub_rococo( - destination: MultiLocation, - (id, amount): (MultiLocation, u128), + destination: Location, + (id, amount): (Location, u128), ) -> DispatchResult { let signed_origin = ::RuntimeOrigin::signed(AssetHubRococoSender::get().into()); - let beneficiary: MultiLocation = + let beneficiary: Location = AccountId32Junction { network: None, id: AssetHubWestendReceiver::get().into() }.into(); - let assets: MultiAssets = (id, amount).into(); + let assets: Assets = (id, amount).into(); let fee_asset_item = 0; AssetHubRococo::execute_with(|| { diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs index a3a7d96a14a..a1d871cdb61 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs @@ -29,8 +29,8 @@ fn send_xcm_from_rococo_relay_to_westend_asset_hub_should_fail_on_not_applicable let xcm = VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit, check_origin }, ExportMessage { - network: WestendId, - destination: X1(Parachain(AssetHubWestend::para_id().into())), + network: WestendId.into(), + destination: [Parachain(AssetHubWestend::para_id().into())].into(), xcm: remote_xcm, }, ])); @@ -68,7 +68,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { // prepare data let destination = asset_hub_westend_location(); - let native_token = MultiLocation::parent(); + let native_token = Location::parent(); let amount = ASSET_HUB_ROCOCO_ED * 1_000; // fund the AHR's SA on BHR for paying bridge transport fees @@ -78,7 +78,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { // send XCM from AssetHubRococo - fails - destination version not known assert_err!( - send_asset_from_asset_hub_rococo(destination, (native_token, amount)), + send_asset_from_asset_hub_rococo(destination.clone(), (native_token.clone(), amount)), DispatchError::Module(sp_runtime::ModuleError { index: 31, error: [1, 0, 0, 0], @@ -87,7 +87,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { ); // set destination version - AssetHubRococo::force_xcm_version(destination, xcm::v3::prelude::XCM_VERSION); + AssetHubRococo::force_xcm_version(destination.clone(), xcm::v3::prelude::XCM_VERSION); // TODO: remove this block, when removing `xcm:v2` { @@ -95,7 +95,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { // version, which does not have the `ExportMessage` instruction. If the default `2` is // changed to `3`, then this assert can go away" assert_err!( - send_asset_from_asset_hub_rococo(destination, (native_token, amount)), + send_asset_from_asset_hub_rococo(destination.clone(), (native_token.clone(), amount)), DispatchError::Module(sp_runtime::ModuleError { index: 31, error: [1, 0, 0, 0], @@ -110,7 +110,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { ); // send XCM from AssetHubRococo - fails - `ExportMessage` is not in `2` assert_err!( - send_asset_from_asset_hub_rococo(destination, (native_token, amount)), + send_asset_from_asset_hub_rococo(destination.clone(), (native_token.clone(), amount)), DispatchError::Module(sp_runtime::ModuleError { index: 31, error: [1, 0, 0, 0], @@ -125,7 +125,10 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { xcm::v3::prelude::XCM_VERSION, ); // send XCM from AssetHubRococo - ok - assert_ok!(send_asset_from_asset_hub_rococo(destination, (native_token, amount))); + assert_ok!(send_asset_from_asset_hub_rococo( + destination.clone(), + (native_token.clone(), amount) + )); // `ExportMessage` on local BridgeHub - fails - remote BridgeHub version not known assert_bridge_hub_rococo_message_accepted(false); @@ -142,7 +145,10 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { ); // send XCM from AssetHubRococo - ok - assert_ok!(send_asset_from_asset_hub_rococo(destination, (native_token, amount))); + assert_ok!(send_asset_from_asset_hub_rococo( + destination.clone(), + (native_token.clone(), amount) + )); assert_bridge_hub_rococo_message_accepted(true); assert_bridge_hub_westend_message_received(); // message delivered and processed at destination diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs index 85547f210a7..fe0e479d8e5 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs @@ -61,7 +61,7 @@ fn create_agent() { let remote_xcm = VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - DescendOrigin(X1(Parachain(origin_para))), + DescendOrigin(Parachain(origin_para).into()), Transact { require_weight_at_most: 3000000000.into(), origin_kind: OriginKind::Xcm, @@ -109,14 +109,14 @@ fn create_channel() { BridgeHubRococo::fund_para_sovereign(origin_para.into(), INITIAL_FUND); let sudo_origin = ::RuntimeOrigin::root(); - let destination: VersionedMultiLocation = + let destination: VersionedLocation = Rococo::child_location_of(BridgeHubRococo::para_id()).into(); let create_agent_call = SnowbridgeControl::Control(ControlCall::CreateAgent {}); let create_agent_xcm = VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - DescendOrigin(X1(Parachain(origin_para))), + DescendOrigin(Parachain(origin_para).into()), Transact { require_weight_at_most: 3000000000.into(), origin_kind: OriginKind::Xcm, @@ -129,7 +129,7 @@ fn create_channel() { let create_channel_xcm = VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - DescendOrigin(X1(Parachain(origin_para))), + DescendOrigin(Parachain(origin_para).into()), Transact { require_weight_at_most: 3000000000.into(), origin_kind: OriginKind::Xcm, @@ -218,10 +218,10 @@ fn register_weth_token_from_ethereum_to_asset_hub() { #[test] fn send_token_from_ethereum_to_penpal() { - let asset_hub_sovereign = BridgeHubRococo::sovereign_account_id_of(MultiLocation { - parents: 1, - interior: X1(Parachain(AssetHubRococo::para_id().into())), - }); + let asset_hub_sovereign = BridgeHubRococo::sovereign_account_id_of(Location::new( + 1, + [Parachain(AssetHubRococo::para_id().into())], + )); BridgeHubRococo::fund_accounts(vec![(asset_hub_sovereign.clone(), INITIAL_FUND)]); PenpalA::fund_accounts(vec![ @@ -229,9 +229,9 @@ fn send_token_from_ethereum_to_penpal() { (PenpalASender::get(), INITIAL_FUND), ]); - let weth_asset_location: MultiLocation = + let weth_asset_location: Location = (Parent, Parent, EthereumNetwork::get(), AccountKey20 { network: None, key: WETH }).into(); - let weth_asset_id = weth_asset_location.into(); + let weth_asset_id: v3::Location = weth_asset_location.try_into().unwrap(); let origin_location = (Parent, Parent, EthereumNetwork::get()).into(); @@ -375,18 +375,15 @@ fn send_token_from_ethereum_to_asset_hub() { #[test] fn send_weth_asset_from_asset_hub_to_ethereum() { use asset_hub_rococo_runtime::xcm_config::bridging::to_ethereum::DefaultBridgeHubEthereumBaseFee; - let assethub_sovereign = BridgeHubRococo::sovereign_account_id_of(MultiLocation { - parents: 1, - interior: X1(Parachain(AssetHubRococo::para_id().into())), - }); + let assethub_sovereign = BridgeHubRococo::sovereign_account_id_of(Location::new( + 1, + [Parachain(AssetHubRococo::para_id().into())], + )); AssetHubRococo::force_default_xcm_version(Some(XCM_VERSION)); BridgeHubRococo::force_default_xcm_version(Some(XCM_VERSION)); AssetHubRococo::force_xcm_version( - MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(Ethereum { chain_id: CHAIN_ID })), - }, + Location::new(2, [GlobalConsensus(Ethereum { chain_id: CHAIN_ID })]), XCM_VERSION, ); @@ -437,27 +434,27 @@ fn send_weth_asset_from_asset_hub_to_ethereum() { RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {}, ] ); - let assets = vec![MultiAsset { - id: Concrete(MultiLocation { - parents: 2, - interior: X2( + let assets = vec![Asset { + id: AssetId(Location::new( + 2, + [ GlobalConsensus(Ethereum { chain_id: CHAIN_ID }), AccountKey20 { network: None, key: WETH }, - ), - }), + ], + )), fun: Fungible(WETH_AMOUNT), }]; - let multi_assets = VersionedMultiAssets::V3(MultiAssets::from(assets)); + let multi_assets = VersionedAssets::V4(Assets::from(assets)); - let destination = VersionedMultiLocation::V3(MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(Ethereum { chain_id: CHAIN_ID })), - }); + let destination = VersionedLocation::V4(Location::new( + 2, + [GlobalConsensus(Ethereum { chain_id: CHAIN_ID })], + )); - let beneficiary = VersionedMultiLocation::V3(MultiLocation { - parents: 0, - interior: X1(AccountKey20 { network: None, key: ETHEREUM_DESTINATION_ADDRESS.into() }), - }); + let beneficiary = VersionedLocation::V4(Location::new( + 0, + [AccountKey20 { network: None, key: ETHEREUM_DESTINATION_ADDRESS.into() }], + )); let free_balance_before = ::Balances::free_balance( AssetHubRococoReceiver::get(), diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/teleport.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/teleport.rs index f00288a4d8c..43f8af9244f 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/teleport.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/teleport.rs @@ -19,7 +19,7 @@ use bridge_hub_rococo_runtime::xcm_config::XcmConfig; #[test] fn teleport_to_other_system_parachains_works() { let amount = BRIDGE_HUB_ROCOCO_ED * 100; - let native_asset: MultiAssets = (Parent, amount).into(); + let native_asset: Assets = (Parent, amount).into(); test_parachain_is_trusted_teleporter!( BridgeHubRococo, // Origin diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs index 17255320f1d..223979cc9c9 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs @@ -21,7 +21,8 @@ pub use sp_runtime::DispatchError; pub use xcm::{ latest::ParentThen, prelude::{AccountId32 as AccountId32Junction, *}, - v3::{ + v3, + v4::{ Error, NetworkId::{Rococo as RococoId, Westend as WestendId}, }, diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs index a4b2719e9fd..c2a9c008902 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs @@ -14,14 +14,14 @@ // limitations under the License. use crate::tests::*; -fn send_asset_from_asset_hub_westend_to_asset_hub_rococo(id: MultiLocation, amount: u128) { +fn send_asset_from_asset_hub_westend_to_asset_hub_rococo(id: Location, amount: u128) { let destination = asset_hub_rococo_location(); // fund the AHW's SA on BHW for paying bridge transport fees BridgeHubWestend::fund_para_sovereign(AssetHubWestend::para_id(), 10_000_000_000_000u128); // set XCM versions - AssetHubWestend::force_xcm_version(destination, XCM_VERSION); + AssetHubWestend::force_xcm_version(destination.clone(), XCM_VERSION); BridgeHubWestend::force_xcm_version(bridge_hub_rococo_location(), XCM_VERSION); // send message over bridge @@ -32,9 +32,9 @@ fn send_asset_from_asset_hub_westend_to_asset_hub_rococo(id: MultiLocation, amou #[test] fn send_wnds_from_asset_hub_westend_to_asset_hub_rococo() { - let wnd_at_asset_hub_westend: MultiLocation = Parent.into(); + let wnd_at_asset_hub_westend: Location = Parent.into(); let wnd_at_asset_hub_rococo = - MultiLocation { parents: 2, interior: X1(GlobalConsensus(NetworkId::Westend)) }; + v3::Location::new(2, [v3::Junction::GlobalConsensus(v3::NetworkId::Westend)]); let owner: AccountId = AssetHubRococo::account_id_of(ALICE); AssetHubRococo::force_create_foreign_asset( wnd_at_asset_hub_rococo, @@ -61,7 +61,7 @@ fn send_wnds_from_asset_hub_westend_to_asset_hub_rococo() { assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(Parent.into()), + Box::new(xcm::v3::Parent.into()), Box::new(wnd_at_asset_hub_rococo), )); @@ -74,7 +74,7 @@ fn send_wnds_from_asset_hub_westend_to_asset_hub_rococo() { assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(Parent.into()), + Box::new(xcm::v3::Parent.into()), Box::new(wnd_at_asset_hub_rococo), 1_000_000_000_000, 2_000_000_000_000, @@ -141,7 +141,7 @@ fn send_wnds_from_asset_hub_westend_to_asset_hub_rococo() { fn send_rocs_from_asset_hub_westend_to_asset_hub_rococo() { let prefund_amount = 10_000_000_000_000u128; let roc_at_asset_hub_westend = - MultiLocation { parents: 2, interior: X1(GlobalConsensus(NetworkId::Rococo)) }; + v3::Location::new(2, [v3::Junction::GlobalConsensus(v3::NetworkId::Rococo)]); let owner: AccountId = AssetHubWestend::account_id_of(ALICE); AssetHubWestend::force_create_foreign_asset( roc_at_asset_hub_westend, @@ -169,8 +169,12 @@ fn send_rocs_from_asset_hub_westend_to_asset_hub_rococo() { let receiver_rocs_before = ::account_data_of(AssetHubRococoReceiver::get()).free; + let roc_at_asset_hub_westend_latest: Location = roc_at_asset_hub_westend.try_into().unwrap(); let amount_to_send = ASSET_HUB_ROCOCO_ED * 1_000; - send_asset_from_asset_hub_westend_to_asset_hub_rococo(roc_at_asset_hub_westend, amount_to_send); + send_asset_from_asset_hub_westend_to_asset_hub_rococo( + roc_at_asset_hub_westend_latest.clone(), + amount_to_send, + ); AssetHubRococo::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; assert_expected_events!( diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs index ec2e68fc889..186b96b3976 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs @@ -19,37 +19,31 @@ mod asset_transfers; mod send_xcm; mod teleport; -pub(crate) fn asset_hub_rococo_location() -> MultiLocation { - MultiLocation { - parents: 2, - interior: X2( - GlobalConsensus(NetworkId::Rococo), - Parachain(AssetHubRococo::para_id().into()), - ), - } +pub(crate) fn asset_hub_rococo_location() -> Location { + Location::new( + 2, + [GlobalConsensus(NetworkId::Rococo), Parachain(AssetHubRococo::para_id().into())], + ) } -pub(crate) fn bridge_hub_rococo_location() -> MultiLocation { - MultiLocation { - parents: 2, - interior: X2( - GlobalConsensus(NetworkId::Rococo), - Parachain(BridgeHubRococo::para_id().into()), - ), - } +pub(crate) fn bridge_hub_rococo_location() -> Location { + Location::new( + 2, + [GlobalConsensus(NetworkId::Rococo), Parachain(BridgeHubRococo::para_id().into())], + ) } pub(crate) fn send_asset_from_asset_hub_westend( - destination: MultiLocation, - (id, amount): (MultiLocation, u128), + destination: Location, + (id, amount): (Location, u128), ) -> DispatchResult { let signed_origin = ::RuntimeOrigin::signed(AssetHubWestendSender::get().into()); - let beneficiary: MultiLocation = + let beneficiary: Location = AccountId32Junction { network: None, id: AssetHubRococoReceiver::get().into() }.into(); - let assets: MultiAssets = (id, amount).into(); + let assets: Assets = (id, amount).into(); let fee_asset_item = 0; AssetHubWestend::execute_with(|| { diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs index 0773cbb0599..b01be5e8dc8 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs @@ -30,7 +30,7 @@ fn send_xcm_from_westend_relay_to_rococo_asset_hub_should_fail_on_not_applicable UnpaidExecution { weight_limit, check_origin }, ExportMessage { network: RococoId, - destination: X1(Parachain(AssetHubRococo::para_id().into())), + destination: [Parachain(AssetHubRococo::para_id().into())].into(), xcm: remote_xcm, }, ])); @@ -68,7 +68,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { // prepare data let destination = asset_hub_rococo_location(); - let native_token = MultiLocation::parent(); + let native_token = Location::parent(); let amount = ASSET_HUB_WESTEND_ED * 1_000; // fund the AHR's SA on BHR for paying bridge transport fees @@ -78,7 +78,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { // send XCM from AssetHubWestend - fails - destination version not known assert_err!( - send_asset_from_asset_hub_westend(destination, (native_token, amount)), + send_asset_from_asset_hub_westend(destination.clone(), (native_token.clone(), amount)), DispatchError::Module(sp_runtime::ModuleError { index: 31, error: [1, 0, 0, 0], @@ -87,7 +87,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { ); // set destination version - AssetHubWestend::force_xcm_version(destination, xcm::v3::prelude::XCM_VERSION); + AssetHubWestend::force_xcm_version(destination.clone(), xcm::v3::prelude::XCM_VERSION); // TODO: remove this block, when removing `xcm:v2` { @@ -95,7 +95,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { // version, which does not have the `ExportMessage` instruction. If the default `2` is // changed to `3`, then this assert can go away" assert_err!( - send_asset_from_asset_hub_westend(destination, (native_token, amount)), + send_asset_from_asset_hub_westend(destination.clone(), (native_token.clone(), amount)), DispatchError::Module(sp_runtime::ModuleError { index: 31, error: [1, 0, 0, 0], @@ -110,7 +110,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { ); // send XCM from AssetHubWestend - fails - `ExportMessage` is not in `2` assert_err!( - send_asset_from_asset_hub_westend(destination, (native_token, amount)), + send_asset_from_asset_hub_westend(destination.clone(), (native_token.clone(), amount)), DispatchError::Module(sp_runtime::ModuleError { index: 31, error: [1, 0, 0, 0], @@ -125,7 +125,10 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { xcm::v3::prelude::XCM_VERSION, ); // send XCM from AssetHubWestend - ok - assert_ok!(send_asset_from_asset_hub_westend(destination, (native_token, amount))); + assert_ok!(send_asset_from_asset_hub_westend( + destination.clone(), + (native_token.clone(), amount) + )); // `ExportMessage` on local BridgeHub - fails - remote BridgeHub version not known assert_bridge_hub_westend_message_accepted(false); @@ -142,7 +145,10 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { ); // send XCM from AssetHubWestend - ok - assert_ok!(send_asset_from_asset_hub_westend(destination, (native_token, amount))); + assert_ok!(send_asset_from_asset_hub_westend( + destination.clone(), + (native_token.clone(), amount) + )); assert_bridge_hub_westend_message_accepted(true); assert_bridge_hub_rococo_message_received(); // message delivered and processed at destination diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/teleport.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/teleport.rs index 8dff6c29295..edffaf16596 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/teleport.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/teleport.rs @@ -19,7 +19,7 @@ use bridge_hub_westend_runtime::xcm_config::XcmConfig; #[test] fn teleport_to_other_system_parachains_works() { let amount = BRIDGE_HUB_WESTEND_ED * 100; - let native_asset: MultiAssets = (Parent, amount).into(); + let native_asset: Assets = (Parent, amount).into(); test_parachain_is_trusted_teleporter!( BridgeHubWestend, // Origin diff --git a/cumulus/parachains/pallets/ping/src/lib.rs b/cumulus/parachains/pallets/ping/src/lib.rs index feda3d0b6f9..a738c05e036 100644 --- a/cumulus/parachains/pallets/ping/src/lib.rs +++ b/cumulus/parachains/pallets/ping/src/lib.rs @@ -77,9 +77,9 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { - PingSent(ParaId, u32, Vec, XcmHash, MultiAssets), + PingSent(ParaId, u32, Vec, XcmHash, Assets), Pinged(ParaId, u32, Vec), - PongSent(ParaId, u32, Vec, XcmHash, MultiAssets), + PongSent(ParaId, u32, Vec, XcmHash, Assets), Ponged(ParaId, u32, Vec, BlockNumberFor), ErrorSendingPing(SendError, ParaId, u32, Vec), ErrorSendingPong(SendError, ParaId, u32, Vec), diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 8cfa4565187..53b41892685 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -31,7 +31,7 @@ use assets_common::{ foreign_creators::ForeignCreators, local_and_foreign_assets::{LocalFromLeft, TargetFromLeft}, matching::{FromNetwork, FromSiblingParachain}, - AssetIdForTrustBackedAssetsConvert, MultiLocationForAssetId, + AssetIdForTrustBackedAssetsConvert, }; use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; use cumulus_primitives_core::AggregateMessageOrigin; @@ -80,13 +80,11 @@ use parachains_common::{ Signature, AVERAGE_ON_INITIALIZE_RATIO, DAYS, HOURS, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, }; - use sp_runtime::{Perbill, RuntimeDebug}; -use xcm::opaque::v3::MultiLocation; use xcm_config::{ ForeignAssetsConvertedConcreteId, ForeignCreatorsSovereignAccountOf, GovernanceLocation, - PoolAssetsConvertedConcreteId, TokenLocation, TrustBackedAssetsConvertedConcreteId, - TrustBackedAssetsPalletLocation, + PoolAssetsConvertedConcreteId, TokenLocation, TokenLocationV3, + TrustBackedAssetsConvertedConcreteId, TrustBackedAssetsPalletLocationV3, }; #[cfg(any(feature = "std", test))] @@ -95,7 +93,13 @@ pub use sp_runtime::BuildStorage; // Polkadot imports use pallet_xcm::{EnsureXcm, IsVoiceOfBody}; use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate}; -use xcm::latest::prelude::*; +// We exclude `Assets` since it's the name of a pallet +#[cfg(feature = "runtime-benchmarks")] +use xcm::latest::prelude::{ + Asset, Fungible, Here, InteriorLocation, Junction, Junction::*, Location, NetworkId, + NonFungible, Parent, ParentThen, Response, XCM_VERSION, +}; +use xcm::latest::prelude::{AssetId, BodyId}; use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}; @@ -317,10 +321,11 @@ pub type LocalAndForeignAssets = fungibles::UnionOf< Assets, ForeignAssets, LocalFromLeft< - AssetIdForTrustBackedAssetsConvert, + AssetIdForTrustBackedAssetsConvert, AssetIdForTrustBackedAssets, + xcm::v3::Location, >, - MultiLocation, + xcm::v3::Location, AccountId, >; @@ -328,8 +333,8 @@ pub type LocalAndForeignAssets = fungibles::UnionOf< pub type NativeAndAssets = fungible::UnionOf< Balances, LocalAndForeignAssets, - TargetFromLeft, - MultiLocation, + TargetFromLeft, + xcm::v3::Location, AccountId, >; @@ -337,15 +342,15 @@ impl pallet_asset_conversion::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type HigherPrecisionBalance = sp_core::U256; - type AssetKind = MultiLocation; + type AssetKind = xcm::v3::Location; type Assets = NativeAndAssets; type PoolId = (Self::AssetKind, Self::AssetKind); type PoolLocator = - pallet_asset_conversion::WithFirstAsset; + pallet_asset_conversion::WithFirstAsset; type PoolAssetId = u32; type PoolAssets = PoolAssets; type PoolSetupFee = ConstU128<0>; // Asset class deposit fees are sufficient to prevent spam - type PoolSetupFeeAsset = TokenLocation; + type PoolSetupFeeAsset = TokenLocationV3; type PoolSetupFeeTarget = ResolveAssetTo; type LiquidityWithdrawalFee = LiquidityWithdrawalFee; type LPFee = ConstU32<3>; @@ -355,9 +360,10 @@ impl pallet_asset_conversion::Config for Runtime { type WeightInfo = weights::pallet_asset_conversion::WeightInfo; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = assets_common::benchmarks::AssetPairFactory< - TokenLocation, + TokenLocationV3, parachain_info::Pallet, - xcm_config::AssetsPalletIndex, + xcm_config::TrustBackedAssetsPalletIndex, + xcm::v3::Location, >; } @@ -379,16 +385,17 @@ pub type ForeignAssetsInstance = pallet_assets::Instance2; impl pallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; - type AssetId = MultiLocationForAssetId; - type AssetIdParameter = MultiLocationForAssetId; + type AssetId = xcm::v3::MultiLocation; + type AssetIdParameter = xcm::v3::MultiLocation; type Currency = Balances; type CreateOrigin = ForeignCreators< ( - FromSiblingParachain>, - FromNetwork, + FromSiblingParachain, xcm::v3::Location>, + FromNetwork, ), ForeignCreatorsSovereignAccountOf, AccountId, + xcm::v3::Location, >; type ForceOrigin = AssetsForceOrigin; type AssetDeposit = ForeignAssetsAssetDeposit; @@ -664,7 +671,7 @@ impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(xcm_config::TokenLocation::get()); + pub FeeAssetId: AssetId = AssetId(xcm_config::TokenLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -753,7 +760,7 @@ impl pallet_asset_conversion_tx_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Fungibles = LocalAndForeignAssets; type OnChargeAssetTransaction = - AssetConversionAdapter; + AssetConversionAdapter; } parameter_types! { @@ -1157,18 +1164,16 @@ impl_runtime_apis! { impl pallet_asset_conversion::AssetConversionApi< Block, Balance, - MultiLocation, + xcm::v3::Location, > for Runtime { - fn quote_price_exact_tokens_for_tokens(asset1: MultiLocation, asset2: MultiLocation, amount: Balance, include_fee: bool) -> Option { + fn quote_price_exact_tokens_for_tokens(asset1: xcm::v3::Location, asset2: xcm::v3::Location, amount: Balance, include_fee: bool) -> Option { AssetConversion::quote_price_exact_tokens_for_tokens(asset1, asset2, amount, include_fee) } - - fn quote_price_tokens_for_exact_tokens(asset1: MultiLocation, asset2: MultiLocation, amount: Balance, include_fee: bool) -> Option { + fn quote_price_tokens_for_exact_tokens(asset1: xcm::v3::Location, asset2: xcm::v3::Location, amount: Balance, include_fee: bool) -> Option { AssetConversion::quote_price_tokens_for_exact_tokens(asset1, asset2, amount, include_fee) } - - fn get_reserves(asset1: MultiLocation, asset2: MultiLocation) -> Option<(Balance, Balance)> { + fn get_reserves(asset1: xcm::v3::Location, asset2: xcm::v3::Location) -> Option<(Balance, Balance)> { AssetConversion::get_reserves(asset1, asset2).ok() } } @@ -1222,7 +1227,7 @@ impl_runtime_apis! { AccountId, > for Runtime { - fn query_account_balances(account: AccountId) -> Result { + fn query_account_balances(account: AccountId) -> Result { use assets_common::fungible_conversion::{convert, convert_balance}; Ok([ // collect pallet_balance @@ -1346,45 +1351,45 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between AH and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // AH can reserve transfer native token to some random parachain. let random_para_id = 43211234; ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests( random_para_id.into() ); Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, ParentThen(Parachain(random_para_id).into()).into(), )) } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(xcm::v4::Assets, u32, Location, Box)> { // Transfer to Relay some local AH asset (local-reserve-transfer) while paying // fees using teleported native token. // (We don't care that Relay doesn't accept incoming unknown AH local asset) let dest = Parent.into(); let fee_amount = EXISTENTIAL_DEPOSIT; - let fee_asset: MultiAsset = (MultiLocation::parent(), fee_amount).into(); + let fee_asset: Asset = (Location::parent(), fee_amount).into(); let who = frame_benchmarking::whitelisted_caller(); // Give some multiple of the existential deposit @@ -1402,13 +1407,13 @@ impl_runtime_apis! { Runtime, pallet_assets::Instance1 >(true, initial_asset_amount); - let asset_location = MultiLocation::new( + let asset_location = Location::new( 0, - X2(PalletInstance(50), GeneralIndex(u32::from(asset_id).into())) + [PalletInstance(50), GeneralIndex(u32::from(asset_id).into())] ); - let transfer_asset: MultiAsset = (asset_location, asset_amount).into(); + let transfer_asset: Asset = (asset_location, asset_amount).into(); - let assets: MultiAssets = vec![fee_asset.clone(), transfer_asset].into(); + let assets: xcm::v4::Assets = vec![fee_asset.clone(), transfer_asset].into(); let fee_index = if assets.get(0).unwrap().eq(&fee_asset) { 0 } else { 1 }; // verify transferred successfully @@ -1432,14 +1437,14 @@ impl_runtime_apis! { xcm_config::bridging::SiblingBridgeHubParaId::get().into() ); } - fn ensure_bridged_target_destination() -> Result { + fn ensure_bridged_target_destination() -> Result { ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests( xcm_config::bridging::SiblingBridgeHubParaId::get().into() ); let bridged_asset_hub = xcm_config::bridging::to_westend::AssetHubWestend::get(); let _ = PolkadotXcm::force_xcm_version( RuntimeOrigin::root(), - Box::new(bridged_asset_hub), + Box::new(bridged_asset_hub.clone()), XCM_VERSION, ).map_err(|e| { log::error!( @@ -1455,12 +1460,11 @@ impl_runtime_apis! { } } - use xcm::latest::prelude::*; use xcm_config::{TokenLocation, MaxAssetsIntoHolding}; use pallet_xcm_benchmarks::asset_instance_from; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( TokenLocation::get(), ExistentialDeposit::get() ).into()); @@ -1471,33 +1475,33 @@ impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationToAccountId; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForParentDelivery, >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(TokenLocation::get()) } - fn worst_case_holding(depositable_count: u32) -> MultiAssets { + fn worst_case_holding(depositable_count: u32) -> xcm::v4::Assets { // A mix of fungible, non-fungible, and concrete assets. let holding_non_fungibles = MaxAssetsIntoHolding::get() / 2 - depositable_count; let holding_fungibles = holding_non_fungibles.saturating_sub(1); let fungibles_amount: u128 = 100; let mut assets = (0..holding_fungibles) .map(|i| { - MultiAsset { - id: Concrete(GeneralIndex(i as u128).into()), + Asset { + id: GeneralIndex(i as u128).into(), fun: Fungible(fungibles_amount * i as u128), } }) - .chain(core::iter::once(MultiAsset { id: Concrete(Here.into()), fun: Fungible(u128::MAX) })) - .chain((0..holding_non_fungibles).map(|i| MultiAsset { - id: Concrete(GeneralIndex(i as u128).into()), + .chain(core::iter::once(Asset { id: Here.into(), fun: Fungible(u128::MAX) })) + .chain((0..holding_non_fungibles).map(|i| Asset { + id: GeneralIndex(i as u128).into(), fun: NonFungible(asset_instance_from(i)), })) .collect::>(); - assets.push(MultiAsset { - id: Concrete(TokenLocation::get()), + assets.push(Asset { + id: AssetId(TokenLocation::get()), fun: Fungible(1_000_000 * UNITS), }); assets.into() @@ -1505,16 +1509,16 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( TokenLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(TokenLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(TokenLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; // AssetHubRococo trusts AssetHubWestend as reserve for WNDs - pub TrustedReserve: Option<(MultiLocation, MultiAsset)> = Some( + pub TrustedReserve: Option<(Location, Asset)> = Some( ( xcm_config::bridging::to_westend::AssetHubWestend::get(), - MultiAsset::from((xcm_config::bridging::to_westend::WndLocation::get(), 1000000000000 as u128)) + Asset::from((xcm_config::bridging::to_westend::WndLocation::get(), 1000000000000 as u128)) ) ); } @@ -1526,9 +1530,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(TokenLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(TokenLocation::get()), fun: Fungible(UNITS), } } @@ -1542,42 +1546,42 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(xcm::v4::Assets, xcm::v4::Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { match xcm_config::bridging::BridgingBenchmarksHelper::prepare_universal_alias() { Some(alias) => Ok(alias), None => Err(BenchmarkError::Skip) } } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((TokenLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(TokenLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, xcm::v4::Assets), BenchmarkError> { let origin = TokenLocation::get(); - let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: xcm::v4::Assets = (TokenLocation::get(), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs index 2fbbd61654b..8e675ad0cf8 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs @@ -24,14 +24,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -50,40 +50,36 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct AssetHubRococoXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for AssetHubRococoXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -111,43 +107,35 @@ impl XcmWeightInfo for AssetHubRococoXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -162,7 +150,7 @@ impl XcmWeightInfo for AssetHubRococoXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -174,13 +162,13 @@ impl XcmWeightInfo for AssetHubRococoXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -213,16 +201,16 @@ impl XcmWeightInfo for AssetHubRococoXcmWeight { fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -234,11 +222,11 @@ impl XcmWeightInfo for AssetHubRococoXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs index f88d1066488..98b23efc06e 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs @@ -20,12 +20,12 @@ use super::{ ToWestendXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, }; use assets_common::{ - local_and_foreign_assets::MatchesLocalAndForeignAssetsMultiLocation, + local_and_foreign_assets::MatchesLocalAndForeignAssetsLocation, matching::{FromNetwork, FromSiblingParachain, IsForeignConcreteAsset}, - TrustBackedAssetsAsMultiLocation, + TrustBackedAssetsAsLocation, }; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ tokens::imbalance::ResolveAssetTo, ConstU32, Contains, Equals, Everything, Nothing, PalletInfoAccess, @@ -64,26 +64,32 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const TokenLocation: MultiLocation = MultiLocation::parent(); + pub const TokenLocation: Location = Location::parent(); + pub const TokenLocationV3: xcm::v3::Location = xcm::v3::Location::parent(); pub const RelayNetwork: NetworkId = NetworkId::Rococo; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())].into(); pub UniversalLocationNetworkId: NetworkId = UniversalLocation::get().global_consensus().unwrap(); - pub AssetsPalletIndex: u32 = ::index() as u32; - pub TrustBackedAssetsPalletLocation: MultiLocation = PalletInstance(AssetsPalletIndex::get() as u8).into(); - pub ForeignAssetsPalletLocation: MultiLocation = + pub TrustBackedAssetsPalletLocation: Location = + PalletInstance(TrustBackedAssetsPalletIndex::get()).into(); + pub TrustBackedAssetsPalletIndex: u8 = ::index() as u8; + pub TrustBackedAssetsPalletLocationV3: xcm::v3::Location = + xcm::v3::Junction::PalletInstance(::index() as u8).into(); + pub ForeignAssetsPalletLocation: Location = PalletInstance(::index() as u8).into(); - pub PoolAssetsPalletLocation: MultiLocation = + pub PoolAssetsPalletLocation: Location = PalletInstance(::index() as u8).into(); + pub PoolAssetsPalletLocationV3: xcm::v3::Location = + xcm::v3::Junction::PalletInstance(::index() as u8).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); + pub const GovernanceLocation: Location = Location::parent(); pub StakingPot: AccountId = CollatorSelection::account_id(); - pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -110,7 +116,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -128,7 +134,7 @@ pub type FungiblesTransactor = FungiblesAdapter< Assets, // Use this currency when it is a fungible asset matching the given location or name: TrustBackedAssetsConvertedConcreteId, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -145,8 +151,8 @@ pub type ForeignAssetsConvertedConcreteId = assets_common::ForeignAssetsConverte // Ignore `TrustBackedAssets` explicitly StartsWith, // Ignore assets that start explicitly with our `GlobalConsensus(NetworkId)`, means: - // - foreign assets from our consensus should be: `MultiLocation {parents: 1, - // X*(Parachain(xyz), ..)}` + // - foreign assets from our consensus should be: `Location {parents: 1, X*(Parachain(xyz), + // ..)}` // - foreign assets outside our consensus with the same `GlobalConsensus(NetworkId)` won't // be accepted here StartsWithExplicitGlobalConsensus, @@ -160,7 +166,7 @@ pub type ForeignFungiblesTransactor = FungiblesAdapter< ForeignAssets, // Use this currency when it is a fungible asset matching the given location or name: ForeignAssetsConvertedConcreteId, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -180,7 +186,7 @@ pub type PoolFungiblesTransactor = FungiblesAdapter< PoolAssets, // Use this currency when it is a fungible asset matching the given location or name: PoolAssetsConvertedConcreteId, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -195,20 +201,32 @@ pub type PoolFungiblesTransactor = FungiblesAdapter< pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor, ForeignFungiblesTransactor, PoolFungiblesTransactor); -/// Simple `MultiLocation` matcher for Local and Foreign asset `MultiLocation`. -pub struct LocalAndForeignAssetsMultiLocationMatcher; -impl MatchesLocalAndForeignAssetsMultiLocation for LocalAndForeignAssetsMultiLocationMatcher { - fn is_local(location: &MultiLocation) -> bool { - use assets_common::fungible_conversion::MatchesMultiLocation; - TrustBackedAssetsConvertedConcreteId::contains(location) +/// Simple `Location` matcher for Local and Foreign asset `Location`. +pub struct LocalAndForeignAssetsLocationMatcher; +impl MatchesLocalAndForeignAssetsLocation + for LocalAndForeignAssetsLocationMatcher +{ + fn is_local(location: &xcm::v3::Location) -> bool { + use assets_common::fungible_conversion::MatchesLocation; + let latest_location: Location = if let Ok(location) = (*location).try_into() { + location + } else { + return false; + }; + TrustBackedAssetsConvertedConcreteId::contains(&latest_location) } - fn is_foreign(location: &MultiLocation) -> bool { - use assets_common::fungible_conversion::MatchesMultiLocation; - ForeignAssetsConvertedConcreteId::contains(location) + fn is_foreign(location: &xcm::v3::Location) -> bool { + use assets_common::fungible_conversion::MatchesLocation; + let latest_location: Location = if let Ok(location) = (*location).try_into() { + location + } else { + return false; + }; + ForeignAssetsConvertedConcreteId::contains(&latest_location) } } -impl Contains for LocalAndForeignAssetsMultiLocationMatcher { - fn contains(location: &MultiLocation) -> bool { +impl Contains for LocalAndForeignAssetsLocationMatcher { + fn contains(location: &xcm::v3::Location) -> bool { Self::is_local(location) || Self::is_foreign(location) } } @@ -243,11 +261,11 @@ parameter_types! { pub XcmAssetFeesReceiver: Option = Authorship::author(); } -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -556,12 +574,12 @@ impl xcm_executor::Config for XcmConfig { type Trader = ( UsingComponents>, cumulus_primitives_utility::SwapFirstAssetTrader< - TokenLocation, + TokenLocationV3, crate::AssetConversion, WeightToFee, crate::NativeAndAssets, ( - TrustBackedAssetsAsMultiLocation, + TrustBackedAssetsAsLocation, ForeignAssetsConvertedConcreteId, ), ResolveAssetTo, @@ -588,7 +606,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. +/// Converts a local signed origin into an XCM location. /// Forms the basis for local origins sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; @@ -664,9 +682,9 @@ pub type ForeignCreatorsSovereignAccountOf = ( /// Simple conversion of `u32` into an `AssetId` for use in benchmarking. pub struct XcmBenchmarkHelper; #[cfg(feature = "runtime-benchmarks")] -impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { - fn create_asset_id_parameter(id: u32) -> MultiLocation { - MultiLocation { parents: 1, interior: X1(Parachain(id)) } +impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { + fn create_asset_id_parameter(id: u32) -> xcm::v3::Location { + xcm::v3::Location::new(1, [xcm::v3::Junction::Parachain(id)]) } } @@ -698,7 +716,7 @@ pub mod bridging { pub storage XcmBridgeHubRouterByteFee: Balance = TransactionByteFee::get(); pub SiblingBridgeHubParaId: u32 = bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID; - pub SiblingBridgeHub: MultiLocation = MultiLocation::new(1, X1(Parachain(SiblingBridgeHubParaId::get()))); + pub SiblingBridgeHub: Location = Location::new(1, [Parachain(SiblingBridgeHubParaId::get())]); /// Router expects payment with this `AssetId`. /// (`AssetId` has to be aligned with `BridgeTable`) pub XcmBridgeHubRouterFeeAssetId: AssetId = TokenLocation::get().into(); @@ -722,25 +740,25 @@ pub mod bridging { use super::*; parameter_types! { - pub SiblingBridgeHubWithBridgeHubWestendInstance: MultiLocation = MultiLocation::new( + pub SiblingBridgeHubWithBridgeHubWestendInstance: Location = Location::new( 1, - X2( + [ Parachain(SiblingBridgeHubParaId::get()), PalletInstance(bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_WESTEND_MESSAGES_PALLET_INDEX) - ) + ] ); pub const WestendNetwork: NetworkId = NetworkId::Westend; - pub AssetHubWestend: MultiLocation = MultiLocation::new(2, X2(GlobalConsensus(WestendNetwork::get()), Parachain(bp_asset_hub_westend::ASSET_HUB_WESTEND_PARACHAIN_ID))); - pub WndLocation: MultiLocation = MultiLocation::new(2, X1(GlobalConsensus(WestendNetwork::get()))); + pub AssetHubWestend: Location = Location::new(2, [GlobalConsensus(WestendNetwork::get()), Parachain(bp_asset_hub_westend::ASSET_HUB_WESTEND_PARACHAIN_ID)]); + pub WndLocation: Location = Location::new(2, [GlobalConsensus(WestendNetwork::get())]); - pub WndFromAssetHubWestend: (MultiAssetFilter, MultiLocation) = ( - Wild(AllOf { fun: WildFungible, id: Concrete(WndLocation::get()) }), + pub WndFromAssetHubWestend: (AssetFilter, Location) = ( + Wild(AllOf { fun: WildFungible, id: AssetId(WndLocation::get()) }), AssetHubWestend::get() ); /// Set up exporters configuration. - /// `Option` represents static "base fee" which is used for total delivery fee calculation. + /// `Option` represents static "base fee" which is used for total delivery fee calculation. pub BridgeTable: sp_std::vec::Vec = sp_std::vec![ NetworkExportTableItem::new( WestendNetwork::get(), @@ -757,15 +775,15 @@ pub mod bridging { ]; /// Universal aliases - pub UniversalAliases: BTreeSet<(MultiLocation, Junction)> = BTreeSet::from_iter( + pub UniversalAliases: BTreeSet<(Location, Junction)> = BTreeSet::from_iter( sp_std::vec![ (SiblingBridgeHubWithBridgeHubWestendInstance::get(), GlobalConsensus(WestendNetwork::get())) ] ); } - impl Contains<(MultiLocation, Junction)> for UniversalAliases { - fn contains(alias: &(MultiLocation, Junction)) -> bool { + impl Contains<(Location, Junction)> for UniversalAliases { + fn contains(alias: &(Location, Junction)) -> bool { UniversalAliases::get().contains(alias) } } @@ -804,16 +822,16 @@ pub mod bridging { /// Polkadot uses 10 decimals, Kusama and Rococo 12 decimals. pub const DefaultBridgeHubEthereumBaseFee: Balance = 2_750_872_500_000; pub storage BridgeHubEthereumBaseFee: Balance = DefaultBridgeHubEthereumBaseFee::get(); - pub SiblingBridgeHubWithEthereumInboundQueueInstance: MultiLocation = MultiLocation::new( + pub SiblingBridgeHubWithEthereumInboundQueueInstance: Location = Location::new( 1, - X2( + [ Parachain(SiblingBridgeHubParaId::get()), PalletInstance(parachains_common::rococo::snowbridge::INBOUND_QUEUE_PALLET_INDEX) - ) + ] ); /// Set up exporters configuration. - /// `Option` represents static "base fee" which is used for total delivery fee calculation. + /// `Option` represents static "base fee" which is used for total delivery fee calculation. pub BridgeTable: sp_std::vec::Vec = sp_std::vec![ NetworkExportTableItem::new( EthereumNetwork::get(), @@ -827,7 +845,7 @@ pub mod bridging { ]; /// Universal aliases - pub UniversalAliases: BTreeSet<(MultiLocation, Junction)> = BTreeSet::from_iter( + pub UniversalAliases: BTreeSet<(Location, Junction)> = BTreeSet::from_iter( sp_std::vec![ (SiblingBridgeHubWithEthereumInboundQueueInstance::get(), GlobalConsensus(EthereumNetwork::get())), ] @@ -837,8 +855,8 @@ pub mod bridging { pub type IsTrustedBridgedReserveLocationForForeignAsset = matching::IsForeignConcreteAsset>; - impl Contains<(MultiLocation, Junction)> for UniversalAliases { - fn contains(alias: &(MultiLocation, Junction)) -> bool { + impl Contains<(Location, Junction)> for UniversalAliases { + fn contains(alias: &(Location, Junction)) -> bool { UniversalAliases::get().contains(alias) } } @@ -850,7 +868,7 @@ pub mod bridging { #[cfg(feature = "runtime-benchmarks")] impl BridgingBenchmarksHelper { - pub fn prepare_universal_alias() -> Option<(MultiLocation, Junction)> { + pub fn prepare_universal_alias() -> Option<(Location, Junction)> { let alias = to_westend::UniversalAliases::get() .into_iter() diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs index c67374126d3..3da1a1e66bd 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs @@ -19,12 +19,18 @@ use asset_hub_rococo_runtime::{ xcm_config, - xcm_config::{bridging, ForeignCreatorsSovereignAccountOf, LocationToAccountId, TokenLocation}, + xcm_config::{ + bridging, ForeignCreatorsSovereignAccountOf, LocationToAccountId, TokenLocation, + TokenLocationV3, + }, AllPalletsWithoutSystem, MetadataDepositBase, MetadataDepositPerByte, RuntimeCall, RuntimeEvent, ToWestendXcmRouterInstance, XcmpQueue, }; pub use asset_hub_rococo_runtime::{ - xcm_config::{CheckingAccount, TrustBackedAssetsPalletLocation, XcmConfig}, + xcm_config::{ + CheckingAccount, TrustBackedAssetsPalletLocation, TrustBackedAssetsPalletLocationV3, + XcmConfig, + }, AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, ParachainSystem, Runtime, SessionKeys, System, TrustBackedAssetsInstance, @@ -49,14 +55,18 @@ use parachains_common::{ }; use sp_runtime::traits::MaybeEquivalence; use std::convert::Into; -use xcm::latest::prelude::*; -use xcm_executor::traits::{Identity, JustTry, WeightTrader}; +use xcm::latest::prelude::{Assets as XcmAssets, *}; +use xcm_builder::V4V3LocationConverter; +use xcm_executor::traits::{JustTry, WeightTrader}; const ALICE: [u8; 32] = [1u8; 32]; const SOME_ASSET_ADMIN: [u8; 32] = [5u8; 32]; type AssetIdForTrustBackedAssetsConvert = - assets_common::AssetIdForTrustBackedAssetsConvert; + assets_common::AssetIdForTrustBackedAssetsConvert; + +type AssetIdForTrustBackedAssetsConvertLatest = + assets_common::AssetIdForTrustBackedAssetsConvertLatest; type RuntimeHelper = asset_test_utils::RuntimeHelper; @@ -99,7 +109,7 @@ fn test_buy_and_refund_weight_in_native() { let fee = WeightToFee::weight_to_fee(&weight); let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - let payment: MultiAsset = (native_location, fee + extra_amount).into(); + let payment: Asset = (native_location.clone(), fee + extra_amount).into(); // init trader and buy weight. let mut trader = ::Trader::new(); @@ -108,7 +118,7 @@ fn test_buy_and_refund_weight_in_native() { // assert. let unused_amount = - unused_asset.fungible.get(&native_location.into()).map_or(0, |a| *a); + unused_asset.fungible.get(&native_location.clone().into()).map_or(0, |a| *a); assert_eq!(unused_amount, extra_amount); assert_eq!(Balances::total_issuance(), total_issuance); @@ -144,7 +154,7 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { let bob: AccountId = SOME_ASSET_ADMIN.into(); let staking_pot = CollatorSelection::account_id(); let asset_1: u32 = 1; - let native_location = TokenLocation::get(); + let native_location = TokenLocationV3::get(); let asset_1_location = AssetIdForTrustBackedAssetsConvert::convert_back(&asset_1).unwrap(); // bob's initial balance for native and `asset1` assets. @@ -180,6 +190,8 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { let asset_total_issuance = Assets::total_issuance(asset_1); let native_total_issuance = Balances::total_issuance(); + let asset_1_location_latest: Location = asset_1_location.try_into().unwrap(); + // prepare input to buy weight. let weight = Weight::from_parts(4_000_000_000, 0); let fee = WeightToFee::weight_to_fee(&weight); @@ -187,7 +199,7 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - let payment: MultiAsset = (asset_1_location, asset_fee + extra_amount).into(); + let payment: Asset = (asset_1_location_latest.clone(), asset_fee + extra_amount).into(); // init trader and buy weight. let mut trader = ::Trader::new(); @@ -195,8 +207,10 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); // assert. - let unused_amount = - unused_asset.fungible.get(&asset_1_location.into()).map_or(0, |a| *a); + let unused_amount = unused_asset + .fungible + .get(&asset_1_location_latest.clone().into()) + .map_or(0, |a| *a); assert_eq!(unused_amount, extra_amount); assert_eq!(Assets::total_issuance(asset_1), asset_total_issuance + asset_fee); @@ -210,7 +224,7 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { // refund. let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); - assert_eq!(actual_refund, (asset_1_location, asset_refund).into()); + assert_eq!(actual_refund, (asset_1_location_latest, asset_refund).into()); // assert. assert_eq!(Balances::balance(&staking_pot), initial_balance); @@ -239,9 +253,15 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { .execute_with(|| { let bob: AccountId = SOME_ASSET_ADMIN.into(); let staking_pot = CollatorSelection::account_id(); - let native_location = TokenLocation::get(); - let foreign_location = - MultiLocation { parents: 1, interior: X2(Parachain(1234), GeneralIndex(12345)) }; + let native_location = TokenLocationV3::get(); + let foreign_location = xcm::v3::Location { + parents: 1, + interior: ( + xcm::v3::Junction::Parachain(1234), + xcm::v3::Junction::GeneralIndex(12345), + ) + .into(), + }; // bob's initial balance for native and `asset1` assets. let initial_balance = 200 * UNITS; // liquidity for both arms of (native, asset1) pool. @@ -280,6 +300,8 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { let asset_total_issuance = ForeignAssets::total_issuance(foreign_location); let native_total_issuance = Balances::total_issuance(); + let foreign_location_latest: Location = foreign_location.try_into().unwrap(); + // prepare input to buy weight. let weight = Weight::from_parts(4_000_000_000, 0); let fee = WeightToFee::weight_to_fee(&weight); @@ -287,7 +309,7 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - let payment: MultiAsset = (foreign_location, asset_fee + extra_amount).into(); + let payment: Asset = (foreign_location_latest.clone(), asset_fee + extra_amount).into(); // init trader and buy weight. let mut trader = ::Trader::new(); @@ -295,8 +317,10 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); // assert. - let unused_amount = - unused_asset.fungible.get(&foreign_location.into()).map_or(0, |a| *a); + let unused_amount = unused_asset + .fungible + .get(&foreign_location_latest.clone().into()) + .map_or(0, |a| *a); assert_eq!(unused_amount, extra_amount); assert_eq!( ForeignAssets::total_issuance(foreign_location), @@ -313,7 +337,7 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { // refund. let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); - assert_eq!(actual_refund, (foreign_location, asset_refund).into()); + assert_eq!(actual_refund, (foreign_location_latest, asset_refund).into()); // assert. assert_eq!(Balances::balance(&staking_pot), initial_balance); @@ -343,19 +367,21 @@ fn test_assets_balances_api_works() { .build() .execute_with(|| { let local_asset_id = 1; - let foreign_asset_id_multilocation = - MultiLocation { parents: 1, interior: X2(Parachain(1234), GeneralIndex(12345)) }; + let foreign_asset_id_location = xcm::v3::Location::new( + 1, + [xcm::v3::Junction::Parachain(1234), xcm::v3::Junction::GeneralIndex(12345)], + ); // check before assert_eq!(Assets::balance(local_asset_id, AccountId::from(ALICE)), 0); assert_eq!( - ForeignAssets::balance(foreign_asset_id_multilocation, AccountId::from(ALICE)), + ForeignAssets::balance(foreign_asset_id_location, AccountId::from(ALICE)), 0 ); assert_eq!(Balances::free_balance(AccountId::from(ALICE)), 0); assert!(Runtime::query_account_balances(AccountId::from(ALICE)) .unwrap() - .try_as::() + .try_as::() .unwrap() .is_none()); @@ -386,7 +412,7 @@ fn test_assets_balances_api_works() { let foreign_asset_minimum_asset_balance = 3333333_u128; assert_ok!(ForeignAssets::force_create( RuntimeHelper::root_origin(), - foreign_asset_id_multilocation, + foreign_asset_id_location, AccountId::from(SOME_ASSET_ADMIN).into(), false, foreign_asset_minimum_asset_balance @@ -395,7 +421,7 @@ fn test_assets_balances_api_works() { // We first mint enough asset for the account to exist for assets assert_ok!(ForeignAssets::mint( RuntimeHelper::origin_of(AccountId::from(SOME_ASSET_ADMIN)), - foreign_asset_id_multilocation, + foreign_asset_id_location, AccountId::from(ALICE).into(), 6 * foreign_asset_minimum_asset_balance )); @@ -406,12 +432,12 @@ fn test_assets_balances_api_works() { minimum_asset_balance ); assert_eq!( - ForeignAssets::balance(foreign_asset_id_multilocation, AccountId::from(ALICE)), + ForeignAssets::balance(foreign_asset_id_location, AccountId::from(ALICE)), 6 * minimum_asset_balance ); assert_eq!(Balances::free_balance(AccountId::from(ALICE)), some_currency); - let result: MultiAssets = Runtime::query_account_balances(AccountId::from(ALICE)) + let result: XcmAssets = Runtime::query_account_balances(AccountId::from(ALICE)) .unwrap() .try_into() .unwrap(); @@ -426,13 +452,13 @@ fn test_assets_balances_api_works() { ))); // check trusted asset assert!(result.inner().iter().any(|asset| asset.eq(&( - AssetIdForTrustBackedAssetsConvert::convert_back(&local_asset_id).unwrap(), + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&local_asset_id).unwrap(), minimum_asset_balance ) .into()))); // check foreign asset assert!(result.inner().iter().any(|asset| asset.eq(&( - Identity::convert_back(&foreign_asset_id_multilocation).unwrap(), + V4V3LocationConverter::convert_back(&foreign_asset_id_location).unwrap(), 6 * foreign_asset_minimum_asset_balance ) .into()))); @@ -503,7 +529,7 @@ asset_test_utils::include_asset_transactor_transfer_with_pallet_assets_instance_ XcmConfig, TrustBackedAssetsInstance, AssetIdForTrustBackedAssets, - AssetIdForTrustBackedAssetsConvert, + AssetIdForTrustBackedAssetsConvertLatest, collator_session_keys(), ExistentialDeposit::get(), 12345, @@ -520,11 +546,14 @@ asset_test_utils::include_asset_transactor_transfer_with_pallet_assets_instance_ Runtime, XcmConfig, ForeignAssetsInstance, - MultiLocation, + xcm::v3::Location, JustTry, collator_session_keys(), ExistentialDeposit::get(), - MultiLocation { parents: 1, interior: X2(Parachain(1313), GeneralIndex(12345)) }, + xcm::v3::Location::new( + 1, + [xcm::v3::Junction::Parachain(1313), xcm::v3::Junction::GeneralIndex(12345)] + ), Box::new(|| { assert!(Assets::asset_ids().collect::>().is_empty()); }), @@ -539,8 +568,8 @@ asset_test_utils::include_create_and_manage_foreign_assets_for_local_consensus_p WeightToFee, ForeignCreatorsSovereignAccountOf, ForeignAssetsInstance, - MultiLocation, - JustTry, + xcm::v3::Location, + V4V3LocationConverter, collator_session_keys(), ExistentialDeposit::get(), AssetDeposit::get(), @@ -637,12 +666,12 @@ mod asset_hub_rococo_tests { AccountId::from([73; 32]), AccountId::from(BLOCK_AUTHOR_ACCOUNT), // receiving WNDs - (MultiLocation { parents: 2, interior: X1(GlobalConsensus(Westend)) }, 1000000000000, 1_000_000_000), + (xcm::v3::Location::new(2, [xcm::v3::Junction::GlobalConsensus(xcm::v3::NetworkId::Westend)]), 1000000000000, 1_000_000_000), bridging_to_asset_hub_westend, ( - X1(PalletInstance(bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_WESTEND_MESSAGES_PALLET_INDEX)), + [PalletInstance(bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_WESTEND_MESSAGES_PALLET_INDEX)].into(), GlobalConsensus(Westend), - X1(Parachain(1000)) + [Parachain(1000)].into() ) ) } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 8543500fa23..cf10c0ac052 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -76,21 +76,25 @@ use sp_std::prelude::*; #[cfg(feature = "std")] use sp_version::NativeVersion; use sp_version::RuntimeVersion; -use xcm::opaque::v3::MultiLocation; use xcm_config::{ ForeignAssetsConvertedConcreteId, PoolAssetsConvertedConcreteId, - TrustBackedAssetsConvertedConcreteId, TrustBackedAssetsPalletLocation, WestendLocation, - XcmOriginToTransactDispatchOrigin, + TrustBackedAssetsConvertedConcreteId, TrustBackedAssetsPalletLocationV3, WestendLocation, + WestendLocationV3, XcmOriginToTransactDispatchOrigin, }; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; -use assets_common::{ - foreign_creators::ForeignCreators, matching::FromSiblingParachain, MultiLocationForAssetId, -}; +use assets_common::{foreign_creators::ForeignCreators, matching::FromSiblingParachain}; use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate}; -use xcm::latest::prelude::*; +// We exclude `Assets` since it's the name of a pallet +use xcm::latest::prelude::AssetId; + +#[cfg(feature = "runtime-benchmarks")] +use xcm::latest::prelude::{ + Asset, Fungible, Here, InteriorLocation, Junction, Junction::*, Location, NetworkId, + NonFungible, Parent, ParentThen, Response, XCM_VERSION, +}; use crate::xcm_config::ForeignCreatorsSovereignAccountOf; use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}; @@ -300,10 +304,11 @@ pub type LocalAndForeignAssets = fungibles::UnionOf< Assets, ForeignAssets, LocalFromLeft< - AssetIdForTrustBackedAssetsConvert, + AssetIdForTrustBackedAssetsConvert, AssetIdForTrustBackedAssets, + xcm::v3::Location, >, - MultiLocation, + xcm::v3::Location, AccountId, >; @@ -311,8 +316,8 @@ pub type LocalAndForeignAssets = fungibles::UnionOf< pub type NativeAndAssets = fungible::UnionOf< Balances, LocalAndForeignAssets, - TargetFromLeft, - MultiLocation, + TargetFromLeft, + xcm::v3::Location, AccountId, >; @@ -320,15 +325,15 @@ impl pallet_asset_conversion::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type HigherPrecisionBalance = sp_core::U256; - type AssetKind = MultiLocation; + type AssetKind = xcm::v3::Location; type Assets = NativeAndAssets; type PoolId = (Self::AssetKind, Self::AssetKind); type PoolLocator = - pallet_asset_conversion::WithFirstAsset; + pallet_asset_conversion::WithFirstAsset; type PoolAssetId = u32; type PoolAssets = PoolAssets; type PoolSetupFee = ConstU128<0>; // Asset class deposit fees are sufficient to prevent spam - type PoolSetupFeeAsset = WestendLocation; + type PoolSetupFeeAsset = WestendLocationV3; type PoolSetupFeeTarget = ResolveAssetTo; type LiquidityWithdrawalFee = LiquidityWithdrawalFee; type LPFee = ConstU32<3>; @@ -338,9 +343,10 @@ impl pallet_asset_conversion::Config for Runtime { type WeightInfo = weights::pallet_asset_conversion::WeightInfo; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = assets_common::benchmarks::AssetPairFactory< - WestendLocation, + WestendLocationV3, parachain_info::Pallet, - xcm_config::AssetsPalletIndex, + xcm_config::TrustBackedAssetsPalletIndex, + xcm::v3::Location, >; } @@ -362,13 +368,14 @@ pub type ForeignAssetsInstance = pallet_assets::Instance2; impl pallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; - type AssetId = MultiLocationForAssetId; - type AssetIdParameter = MultiLocationForAssetId; + type AssetId = xcm::v3::Location; + type AssetIdParameter = xcm::v3::Location; type Currency = Balances; type CreateOrigin = ForeignCreators< - (FromSiblingParachain>,), + FromSiblingParachain, xcm::v3::Location>, ForeignCreatorsSovereignAccountOf, AccountId, + xcm::v3::Location, >; type ForceOrigin = AssetsForceOrigin; type AssetDeposit = ForeignAssetsAssetDeposit; @@ -644,7 +651,7 @@ impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(xcm_config::WestendLocation::get()); + pub FeeAssetId: AssetId = AssetId(xcm_config::WestendLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -728,7 +735,7 @@ impl pallet_asset_conversion_tx_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Fungibles = LocalAndForeignAssets; type OnChargeAssetTransaction = - AssetConversionAdapter; + AssetConversionAdapter; } parameter_types! { @@ -1229,18 +1236,18 @@ impl_runtime_apis! { impl pallet_asset_conversion::AssetConversionApi< Block, Balance, - MultiLocation, + xcm::v3::Location, > for Runtime { - fn quote_price_exact_tokens_for_tokens(asset1: MultiLocation, asset2: MultiLocation, amount: Balance, include_fee: bool) -> Option { + fn quote_price_exact_tokens_for_tokens(asset1: xcm::v3::Location, asset2: xcm::v3::Location, amount: Balance, include_fee: bool) -> Option { AssetConversion::quote_price_exact_tokens_for_tokens(asset1, asset2, amount, include_fee) } - fn quote_price_tokens_for_exact_tokens(asset1: MultiLocation, asset2: MultiLocation, amount: Balance, include_fee: bool) -> Option { + fn quote_price_tokens_for_exact_tokens(asset1: xcm::v3::Location, asset2: xcm::v3::Location, amount: Balance, include_fee: bool) -> Option { AssetConversion::quote_price_tokens_for_exact_tokens(asset1, asset2, amount, include_fee) } - fn get_reserves(asset1: MultiLocation, asset2: MultiLocation) -> Option<(Balance, Balance)> { + fn get_reserves(asset1: xcm::v3::Location, asset2: xcm::v3::Location) -> Option<(Balance, Balance)> { AssetConversion::get_reserves(asset1, asset2).ok() } } @@ -1294,7 +1301,7 @@ impl_runtime_apis! { AccountId, > for Runtime { - fn query_account_balances(account: AccountId) -> Result { + fn query_account_balances(account: AccountId) -> Result { use assets_common::fungible_conversion::{convert, convert_balance}; Ok([ // collect pallet_balance @@ -1413,45 +1420,45 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between AH and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // AH can reserve transfer native token to some random parachain. let random_para_id = 43211234; ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests( random_para_id.into() ); Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, ParentThen(Parachain(random_para_id).into()).into(), )) } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(xcm::v4::Assets, u32, Location, Box)> { // Transfer to Relay some local AH asset (local-reserve-transfer) while paying // fees using teleported native token. // (We don't care that Relay doesn't accept incoming unknown AH local asset) let dest = Parent.into(); let fee_amount = EXISTENTIAL_DEPOSIT; - let fee_asset: MultiAsset = (MultiLocation::parent(), fee_amount).into(); + let fee_asset: Asset = (Location::parent(), fee_amount).into(); let who = frame_benchmarking::whitelisted_caller(); // Give some multiple of the existential deposit @@ -1469,13 +1476,13 @@ impl_runtime_apis! { Runtime, pallet_assets::Instance1 >(true, initial_asset_amount); - let asset_location = MultiLocation::new( + let asset_location = Location::new( 0, - X2(PalletInstance(50), GeneralIndex(u32::from(asset_id).into())) + [PalletInstance(50), GeneralIndex(u32::from(asset_id).into())] ); - let transfer_asset: MultiAsset = (asset_location, asset_amount).into(); + let transfer_asset: Asset = (asset_location, asset_amount).into(); - let assets: MultiAssets = vec![fee_asset.clone(), transfer_asset].into(); + let assets: xcm::v4::Assets = vec![fee_asset.clone(), transfer_asset].into(); let fee_index = if assets.get(0).unwrap().eq(&fee_asset) { 0 } else { 1 }; // verify transferred successfully @@ -1504,14 +1511,14 @@ impl_runtime_apis! { xcm_config::bridging::SiblingBridgeHubParaId::get().into() ); } - fn ensure_bridged_target_destination() -> Result { + fn ensure_bridged_target_destination() -> Result { ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests( xcm_config::bridging::SiblingBridgeHubParaId::get().into() ); let bridged_asset_hub = xcm_config::bridging::to_rococo::AssetHubRococo::get(); let _ = PolkadotXcm::force_xcm_version( RuntimeOrigin::root(), - Box::new(bridged_asset_hub), + Box::new(bridged_asset_hub.clone()), XCM_VERSION, ).map_err(|e| { log::error!( @@ -1527,12 +1534,11 @@ impl_runtime_apis! { } } - use xcm::latest::prelude::*; use xcm_config::{MaxAssetsIntoHolding, WestendLocation}; use pallet_xcm_benchmarks::asset_instance_from; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( WestendLocation::get(), ExistentialDeposit::get() ).into()); @@ -1543,33 +1549,33 @@ impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationToAccountId; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForParentDelivery, >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(WestendLocation::get()) } - fn worst_case_holding(depositable_count: u32) -> MultiAssets { + fn worst_case_holding(depositable_count: u32) -> xcm::v4::Assets { // A mix of fungible, non-fungible, and concrete assets. let holding_non_fungibles = MaxAssetsIntoHolding::get() / 2 - depositable_count; let holding_fungibles = holding_non_fungibles - 1; let fungibles_amount: u128 = 100; let mut assets = (0..holding_fungibles) .map(|i| { - MultiAsset { - id: Concrete(GeneralIndex(i as u128).into()), + Asset { + id: AssetId(GeneralIndex(i as u128).into()), fun: Fungible(fungibles_amount * i as u128), } }) - .chain(core::iter::once(MultiAsset { id: Concrete(Here.into()), fun: Fungible(u128::MAX) })) - .chain((0..holding_non_fungibles).map(|i| MultiAsset { - id: Concrete(GeneralIndex(i as u128).into()), + .chain(core::iter::once(Asset { id: AssetId(Here.into()), fun: Fungible(u128::MAX) })) + .chain((0..holding_non_fungibles).map(|i| Asset { + id: AssetId(GeneralIndex(i as u128).into()), fun: NonFungible(asset_instance_from(i)), })) .collect::>(); - assets.push(MultiAsset { - id: Concrete(WestendLocation::get()), + assets.push(Asset { + id: AssetId(WestendLocation::get()), fun: Fungible(1_000_000 * UNITS), }); assets.into() @@ -1577,16 +1583,16 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( WestendLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(WestendLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(WestendLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; // AssetHubWestend trusts AssetHubRococo as reserve for ROCs - pub TrustedReserve: Option<(MultiLocation, MultiAsset)> = Some( + pub TrustedReserve: Option<(Location, Asset)> = Some( ( xcm_config::bridging::to_rococo::AssetHubRococo::get(), - MultiAsset::from((xcm_config::bridging::to_rococo::RocLocation::get(), 1000000000000 as u128)) + Asset::from((xcm_config::bridging::to_rococo::RocLocation::get(), 1000000000000 as u128)) ) ); } @@ -1598,9 +1604,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(WestendLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(WestendLocation::get()), fun: Fungible(UNITS), } } @@ -1614,42 +1620,42 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(xcm::v4::Assets, xcm::v4::Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { match xcm_config::bridging::BridgingBenchmarksHelper::prepare_universal_alias() { Some(alias) => Ok(alias), None => Err(BenchmarkError::Skip) } } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((WestendLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(WestendLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, xcm::v4::Assets), BenchmarkError> { let origin = WestendLocation::get(); - let assets: MultiAssets = (Concrete(WestendLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: xcm::v4::Assets = (AssetId(WestendLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs index bcd51167f97..8c77774da2d 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs @@ -23,14 +23,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -49,40 +49,36 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct AssetHubWestendXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for AssetHubWestendXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -110,44 +106,36 @@ impl XcmWeightInfo for AssetHubWestendXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -162,7 +150,7 @@ impl XcmWeightInfo for AssetHubWestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -174,13 +162,13 @@ impl XcmWeightInfo for AssetHubWestendXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -213,16 +201,16 @@ impl XcmWeightInfo for AssetHubWestendXcmWeight { fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -234,11 +222,11 @@ impl XcmWeightInfo for AssetHubWestendXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs index 28876d1d454..b2498418cc7 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs @@ -20,12 +20,12 @@ use super::{ ToRococoXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, }; use assets_common::{ - local_and_foreign_assets::MatchesLocalAndForeignAssetsMultiLocation, + local_and_foreign_assets::MatchesLocalAndForeignAssetsLocation, matching::{FromSiblingParachain, IsForeignConcreteAsset}, - TrustBackedAssetsAsMultiLocation, + TrustBackedAssetsAsLocation, }; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ tokens::imbalance::ResolveAssetTo, ConstU32, Contains, Equals, Everything, Nothing, PalletInfoAccess, @@ -61,25 +61,31 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const WestendLocation: MultiLocation = MultiLocation::parent(); + pub const WestendLocation: Location = Location::parent(); + pub const WestendLocationV3: xcm::v3::Location = xcm::v3::Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::Westend); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); pub UniversalLocationNetworkId: NetworkId = UniversalLocation::get().global_consensus().unwrap(); - pub AssetsPalletIndex: u32 = ::index() as u32; - pub TrustBackedAssetsPalletLocation: MultiLocation = PalletInstance(AssetsPalletIndex::get() as u8).into(); - pub ForeignAssetsPalletLocation: MultiLocation = + pub TrustBackedAssetsPalletLocation: Location = + PalletInstance(TrustBackedAssetsPalletIndex::get()).into(); + pub TrustBackedAssetsPalletIndex: u8 = ::index() as u8; + pub TrustBackedAssetsPalletLocationV3: xcm::v3::Location = + xcm::v3::Junction::PalletInstance(::index() as u8).into(); + pub ForeignAssetsPalletLocation: Location = PalletInstance(::index() as u8).into(); - pub PoolAssetsPalletLocation: MultiLocation = + pub PoolAssetsPalletLocation: Location = PalletInstance(::index() as u8).into(); + pub PoolAssetsPalletLocationV3: xcm::v3::Location = + xcm::v3::Junction::PalletInstance(::index() as u8).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); pub StakingPot: AccountId = CollatorSelection::account_id(); pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -104,7 +110,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -122,7 +128,7 @@ pub type FungiblesTransactor = FungiblesAdapter< Assets, // Use this currency when it is a fungible asset matching the given location or name: TrustBackedAssetsConvertedConcreteId, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -139,8 +145,8 @@ pub type ForeignAssetsConvertedConcreteId = assets_common::ForeignAssetsConverte // Ignore `TrustBackedAssets` explicitly StartsWith, // Ignore asset which starts explicitly with our `GlobalConsensus(NetworkId)`, means: - // - foreign assets from our consensus should be: `MultiLocation {parents: 1, - // X*(Parachain(xyz), ..)} + // - foreign assets from our consensus should be: `Location {parents: 1, X*(Parachain(xyz), + // ..)} // - foreign assets outside our consensus with the same `GlobalConsensus(NetworkId)` wont // be accepted here StartsWithExplicitGlobalConsensus, @@ -154,7 +160,7 @@ pub type ForeignFungiblesTransactor = FungiblesAdapter< ForeignAssets, // Use this currency when it is a fungible asset matching the given location or name: ForeignAssetsConvertedConcreteId, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -174,7 +180,7 @@ pub type PoolFungiblesTransactor = FungiblesAdapter< PoolAssets, // Use this currency when it is a fungible asset matching the given location or name: PoolAssetsConvertedConcreteId, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -189,21 +195,33 @@ pub type PoolFungiblesTransactor = FungiblesAdapter< pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor, ForeignFungiblesTransactor, PoolFungiblesTransactor); -/// Simple `MultiLocation` matcher for Local and Foreign asset `MultiLocation`. -pub struct LocalAndForeignAssetsMultiLocationMatcher; -impl MatchesLocalAndForeignAssetsMultiLocation for LocalAndForeignAssetsMultiLocationMatcher { - fn is_local(location: &MultiLocation) -> bool { - use assets_common::fungible_conversion::MatchesMultiLocation; - TrustBackedAssetsConvertedConcreteId::contains(location) +/// Simple `Location` matcher for Local and Foreign asset `Location`. +pub struct LocalAndForeignAssetsLocationMatcher; +impl MatchesLocalAndForeignAssetsLocation + for LocalAndForeignAssetsLocationMatcher +{ + fn is_local(location: &xcm::v3::Location) -> bool { + use assets_common::fungible_conversion::MatchesLocation; + let latest_location: Location = if let Ok(location) = (*location).try_into() { + location + } else { + return false; + }; + TrustBackedAssetsConvertedConcreteId::contains(&latest_location) } - fn is_foreign(location: &MultiLocation) -> bool { - use assets_common::fungible_conversion::MatchesMultiLocation; - ForeignAssetsConvertedConcreteId::contains(location) + fn is_foreign(location: &xcm::v3::Location) -> bool { + use assets_common::fungible_conversion::MatchesLocation; + let latest_location: Location = if let Ok(location) = (*location).try_into() { + location + } else { + return false; + }; + ForeignAssetsConvertedConcreteId::contains(&latest_location) } } -impl Contains for LocalAndForeignAssetsMultiLocationMatcher { - fn contains(location: &MultiLocation) -> bool { +impl Contains for LocalAndForeignAssetsLocationMatcher { + fn contains(location: &xcm::v3::Location) -> bool { Self::is_local(location) || Self::is_foreign(location) } } @@ -238,23 +256,30 @@ parameter_types! { pub XcmAssetFeesReceiver: Option = Authorship::author(); } -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; - pub type FellowshipEntities: impl Contains = { - // Fellowship Plurality - MultiLocation { parents: 1, interior: X2(Parachain(1001), Plurality { id: BodyId::Technical, ..}) } | - // Fellowship Salary Pallet - MultiLocation { parents: 1, interior: X2(Parachain(1001), PalletInstance(64)) } | - // Fellowship Treasury Pallet - MultiLocation { parents: 1, interior: X2(Parachain(1001), PalletInstance(65)) } - }; - pub type AmbassadorEntities: impl Contains = { - // Ambassador Salary Pallet - MultiLocation { parents: 1, interior: X2(Parachain(1001), PalletInstance(74)) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } +} + +pub struct FellowshipEntities; +impl Contains for FellowshipEntities { + fn contains(location: &Location) -> bool { + matches!( + location.unpack(), + (1, [Parachain(1001), Plurality { id: BodyId::Technical, .. }]) | + (1, [Parachain(1001), PalletInstance(64)]) | + (1, [Parachain(1001), PalletInstance(65)]) + ) + } +} + +pub struct AmbassadorEntities; +impl Contains for AmbassadorEntities { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [Parachain(1001), PalletInstance(74)])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -573,12 +598,12 @@ impl xcm_executor::Config for XcmConfig { type Trader = ( UsingComponents>, cumulus_primitives_utility::SwapFirstAssetTrader< - WestendLocation, + WestendLocationV3, crate::AssetConversion, WeightToFee, crate::NativeAndAssets, ( - TrustBackedAssetsAsMultiLocation, + TrustBackedAssetsAsLocation, ForeignAssetsConvertedConcreteId, ), ResolveAssetTo, @@ -671,9 +696,9 @@ pub type ForeignCreatorsSovereignAccountOf = ( /// Simple conversion of `u32` into an `AssetId` for use in benchmarking. pub struct XcmBenchmarkHelper; #[cfg(feature = "runtime-benchmarks")] -impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { - fn create_asset_id_parameter(id: u32) -> MultiLocation { - MultiLocation { parents: 1, interior: X1(Parachain(id)) } +impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { + fn create_asset_id_parameter(id: u32) -> xcm::v3::Location { + xcm::v3::Location::new(1, [xcm::v3::Junction::Parachain(id)]) } } @@ -704,7 +729,7 @@ pub mod bridging { pub storage XcmBridgeHubRouterByteFee: Balance = TransactionByteFee::get(); pub SiblingBridgeHubParaId: u32 = bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID; - pub SiblingBridgeHub: MultiLocation = MultiLocation::new(1, X1(Parachain(SiblingBridgeHubParaId::get()))); + pub SiblingBridgeHub: Location = Location::new(1, [Parachain(SiblingBridgeHubParaId::get())]); /// Router expects payment with this `AssetId`. /// (`AssetId` has to be aligned with `BridgeTable`) pub XcmBridgeHubRouterFeeAssetId: AssetId = WestendLocation::get().into(); @@ -721,25 +746,25 @@ pub mod bridging { use super::*; parameter_types! { - pub SiblingBridgeHubWithBridgeHubRococoInstance: MultiLocation = MultiLocation::new( + pub SiblingBridgeHubWithBridgeHubRococoInstance: Location = Location::new( 1, - X2( + [ Parachain(SiblingBridgeHubParaId::get()), PalletInstance(bp_bridge_hub_westend::WITH_BRIDGE_WESTEND_TO_ROCOCO_MESSAGES_PALLET_INDEX) - ) + ] ); pub const RococoNetwork: NetworkId = NetworkId::Rococo; - pub AssetHubRococo: MultiLocation = MultiLocation::new(2, X2(GlobalConsensus(RococoNetwork::get()), Parachain(bp_asset_hub_rococo::ASSET_HUB_ROCOCO_PARACHAIN_ID))); - pub RocLocation: MultiLocation = MultiLocation::new(2, X1(GlobalConsensus(RococoNetwork::get()))); + pub AssetHubRococo: Location = Location::new(2, [GlobalConsensus(RococoNetwork::get()), Parachain(bp_asset_hub_rococo::ASSET_HUB_ROCOCO_PARACHAIN_ID)]); + pub RocLocation: Location = Location::new(2, [GlobalConsensus(RococoNetwork::get())]); - pub RocFromAssetHubRococo: (MultiAssetFilter, MultiLocation) = ( - Wild(AllOf { fun: WildFungible, id: Concrete(RocLocation::get()) }), + pub RocFromAssetHubRococo: (AssetFilter, Location) = ( + Wild(AllOf { fun: WildFungible, id: AssetId(RocLocation::get()) }), AssetHubRococo::get() ); /// Set up exporters configuration. - /// `Option` represents static "base fee" which is used for total delivery fee calculation. + /// `Option` represents static "base fee" which is used for total delivery fee calculation. pub BridgeTable: sp_std::vec::Vec = sp_std::vec![ NetworkExportTableItem::new( RococoNetwork::get(), @@ -756,15 +781,15 @@ pub mod bridging { ]; /// Universal aliases - pub UniversalAliases: BTreeSet<(MultiLocation, Junction)> = BTreeSet::from_iter( + pub UniversalAliases: BTreeSet<(Location, Junction)> = BTreeSet::from_iter( sp_std::vec![ (SiblingBridgeHubWithBridgeHubRococoInstance::get(), GlobalConsensus(RococoNetwork::get())) ] ); } - impl Contains<(MultiLocation, Junction)> for UniversalAliases { - fn contains(alias: &(MultiLocation, Junction)) -> bool { + impl Contains<(Location, Junction)> for UniversalAliases { + fn contains(alias: &(Location, Junction)) -> bool { UniversalAliases::get().contains(alias) } } @@ -799,7 +824,7 @@ pub mod bridging { #[cfg(feature = "runtime-benchmarks")] impl BridgingBenchmarksHelper { - pub fn prepare_universal_alias() -> Option<(MultiLocation, Junction)> { + pub fn prepare_universal_alias() -> Option<(Location, Junction)> { let alias = to_rococo::UniversalAliases::get().into_iter().find_map(|(location, junction)| { match to_rococo::SiblingBridgeHubWithBridgeHubRococoInstance::get() diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs index c50a8f3661d..28fc7ba705a 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs @@ -21,12 +21,16 @@ use asset_hub_westend_runtime::{ xcm_config, xcm_config::{ bridging, ForeignCreatorsSovereignAccountOf, LocationToAccountId, WestendLocation, + WestendLocationV3, }, AllPalletsWithoutSystem, MetadataDepositBase, MetadataDepositPerByte, PolkadotXcm, RuntimeCall, RuntimeEvent, RuntimeOrigin, ToRococoXcmRouterInstance, XcmpQueue, }; pub use asset_hub_westend_runtime::{ - xcm_config::{CheckingAccount, TrustBackedAssetsPalletLocation, XcmConfig}, + xcm_config::{ + CheckingAccount, TrustBackedAssetsPalletLocation, TrustBackedAssetsPalletLocationV3, + XcmConfig, + }, AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, ParachainSystem, Runtime, SessionKeys, System, TrustBackedAssetsInstance, @@ -51,14 +55,18 @@ use parachains_common::{ }; use sp_runtime::traits::MaybeEquivalence; use std::convert::Into; -use xcm::latest::prelude::*; -use xcm_executor::traits::{Identity, JustTry, WeightTrader}; +use xcm::latest::prelude::{Assets as XcmAssets, *}; +use xcm_builder::V4V3LocationConverter; +use xcm_executor::traits::{JustTry, WeightTrader}; const ALICE: [u8; 32] = [1u8; 32]; const SOME_ASSET_ADMIN: [u8; 32] = [5u8; 32]; type AssetIdForTrustBackedAssetsConvert = - assets_common::AssetIdForTrustBackedAssetsConvert; + assets_common::AssetIdForTrustBackedAssetsConvert; + +type AssetIdForTrustBackedAssetsConvertLatest = + assets_common::AssetIdForTrustBackedAssetsConvertLatest; type RuntimeHelper = asset_test_utils::RuntimeHelper; @@ -101,7 +109,7 @@ fn test_buy_and_refund_weight_in_native() { let fee = WeightToFee::weight_to_fee(&weight); let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - let payment: MultiAsset = (native_location, fee + extra_amount).into(); + let payment: Asset = (native_location.clone(), fee + extra_amount).into(); // init trader and buy weight. let mut trader = ::Trader::new(); @@ -110,7 +118,7 @@ fn test_buy_and_refund_weight_in_native() { // assert. let unused_amount = - unused_asset.fungible.get(&native_location.into()).map_or(0, |a| *a); + unused_asset.fungible.get(&native_location.clone().into()).map_or(0, |a| *a); assert_eq!(unused_amount, extra_amount); assert_eq!(Balances::total_issuance(), total_issuance); @@ -146,7 +154,7 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { let bob: AccountId = SOME_ASSET_ADMIN.into(); let staking_pot = CollatorSelection::account_id(); let asset_1: u32 = 1; - let native_location = WestendLocation::get(); + let native_location = WestendLocationV3::get(); let asset_1_location = AssetIdForTrustBackedAssetsConvert::convert_back(&asset_1).unwrap(); // bob's initial balance for native and `asset1` assets. @@ -182,6 +190,8 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { let asset_total_issuance = Assets::total_issuance(asset_1); let native_total_issuance = Balances::total_issuance(); + let asset_1_location_latest: Location = asset_1_location.try_into().unwrap(); + // prepare input to buy weight. let weight = Weight::from_parts(4_000_000_000, 0); let fee = WeightToFee::weight_to_fee(&weight); @@ -189,7 +199,7 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - let payment: MultiAsset = (asset_1_location, asset_fee + extra_amount).into(); + let payment: Asset = (asset_1_location_latest.clone(), asset_fee + extra_amount).into(); // init trader and buy weight. let mut trader = ::Trader::new(); @@ -197,8 +207,10 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); // assert. - let unused_amount = - unused_asset.fungible.get(&asset_1_location.into()).map_or(0, |a| *a); + let unused_amount = unused_asset + .fungible + .get(&asset_1_location_latest.clone().into()) + .map_or(0, |a| *a); assert_eq!(unused_amount, extra_amount); assert_eq!(Assets::total_issuance(asset_1), asset_total_issuance + asset_fee); @@ -212,7 +224,7 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { // refund. let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); - assert_eq!(actual_refund, (asset_1_location, asset_refund).into()); + assert_eq!(actual_refund, (asset_1_location_latest, asset_refund).into()); // assert. assert_eq!(Balances::balance(&staking_pot), initial_balance); @@ -241,9 +253,15 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { .execute_with(|| { let bob: AccountId = SOME_ASSET_ADMIN.into(); let staking_pot = CollatorSelection::account_id(); - let native_location = WestendLocation::get(); - let foreign_location = - MultiLocation { parents: 1, interior: X2(Parachain(1234), GeneralIndex(12345)) }; + let native_location = WestendLocationV3::get(); + let foreign_location = xcm::v3::Location { + parents: 1, + interior: ( + xcm::v3::Junction::Parachain(1234), + xcm::v3::Junction::GeneralIndex(12345), + ) + .into(), + }; // bob's initial balance for native and `asset1` assets. let initial_balance = 200 * UNITS; // liquidity for both arms of (native, asset1) pool. @@ -282,6 +300,8 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { let asset_total_issuance = ForeignAssets::total_issuance(foreign_location); let native_total_issuance = Balances::total_issuance(); + let foreign_location_latest: Location = foreign_location.try_into().unwrap(); + // prepare input to buy weight. let weight = Weight::from_parts(4_000_000_000, 0); let fee = WeightToFee::weight_to_fee(&weight); @@ -289,7 +309,7 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - let payment: MultiAsset = (foreign_location, asset_fee + extra_amount).into(); + let payment: Asset = (foreign_location_latest.clone(), asset_fee + extra_amount).into(); // init trader and buy weight. let mut trader = ::Trader::new(); @@ -297,8 +317,10 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); // assert. - let unused_amount = - unused_asset.fungible.get(&foreign_location.into()).map_or(0, |a| *a); + let unused_amount = unused_asset + .fungible + .get(&foreign_location_latest.clone().into()) + .map_or(0, |a| *a); assert_eq!(unused_amount, extra_amount); assert_eq!( ForeignAssets::total_issuance(foreign_location), @@ -315,7 +337,7 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { // refund. let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); - assert_eq!(actual_refund, (foreign_location, asset_refund).into()); + assert_eq!(actual_refund, (foreign_location_latest, asset_refund).into()); // assert. assert_eq!(Balances::balance(&staking_pot), initial_balance); @@ -345,19 +367,25 @@ fn test_assets_balances_api_works() { .build() .execute_with(|| { let local_asset_id = 1; - let foreign_asset_id_multilocation = - MultiLocation { parents: 1, interior: X2(Parachain(1234), GeneralIndex(12345)) }; + let foreign_asset_id_location = xcm::v3::Location { + parents: 1, + interior: [ + xcm::v3::Junction::Parachain(1234), + xcm::v3::Junction::GeneralIndex(12345), + ] + .into(), + }; // check before assert_eq!(Assets::balance(local_asset_id, AccountId::from(ALICE)), 0); assert_eq!( - ForeignAssets::balance(foreign_asset_id_multilocation, AccountId::from(ALICE)), + ForeignAssets::balance(foreign_asset_id_location, AccountId::from(ALICE)), 0 ); assert_eq!(Balances::free_balance(AccountId::from(ALICE)), 0); assert!(Runtime::query_account_balances(AccountId::from(ALICE)) .unwrap() - .try_as::() + .try_as::() .unwrap() .is_none()); @@ -388,7 +416,7 @@ fn test_assets_balances_api_works() { let foreign_asset_minimum_asset_balance = 3333333_u128; assert_ok!(ForeignAssets::force_create( RuntimeHelper::root_origin(), - foreign_asset_id_multilocation, + foreign_asset_id_location, AccountId::from(SOME_ASSET_ADMIN).into(), false, foreign_asset_minimum_asset_balance @@ -397,7 +425,7 @@ fn test_assets_balances_api_works() { // We first mint enough asset for the account to exist for assets assert_ok!(ForeignAssets::mint( RuntimeHelper::origin_of(AccountId::from(SOME_ASSET_ADMIN)), - foreign_asset_id_multilocation, + foreign_asset_id_location, AccountId::from(ALICE).into(), 6 * foreign_asset_minimum_asset_balance )); @@ -408,12 +436,12 @@ fn test_assets_balances_api_works() { minimum_asset_balance ); assert_eq!( - ForeignAssets::balance(foreign_asset_id_multilocation, AccountId::from(ALICE)), + ForeignAssets::balance(foreign_asset_id_location, AccountId::from(ALICE)), 6 * minimum_asset_balance ); assert_eq!(Balances::free_balance(AccountId::from(ALICE)), some_currency); - let result: MultiAssets = Runtime::query_account_balances(AccountId::from(ALICE)) + let result: XcmAssets = Runtime::query_account_balances(AccountId::from(ALICE)) .unwrap() .try_into() .unwrap(); @@ -428,13 +456,13 @@ fn test_assets_balances_api_works() { ))); // check trusted asset assert!(result.inner().iter().any(|asset| asset.eq(&( - AssetIdForTrustBackedAssetsConvert::convert_back(&local_asset_id).unwrap(), + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&local_asset_id).unwrap(), minimum_asset_balance ) .into()))); // check foreign asset assert!(result.inner().iter().any(|asset| asset.eq(&( - Identity::convert_back(&foreign_asset_id_multilocation).unwrap(), + V4V3LocationConverter::convert_back(&foreign_asset_id_location).unwrap(), 6 * foreign_asset_minimum_asset_balance ) .into()))); @@ -505,7 +533,7 @@ asset_test_utils::include_asset_transactor_transfer_with_pallet_assets_instance_ XcmConfig, TrustBackedAssetsInstance, AssetIdForTrustBackedAssets, - AssetIdForTrustBackedAssetsConvert, + AssetIdForTrustBackedAssetsConvertLatest, collator_session_keys(), ExistentialDeposit::get(), 12345, @@ -522,11 +550,15 @@ asset_test_utils::include_asset_transactor_transfer_with_pallet_assets_instance_ Runtime, XcmConfig, ForeignAssetsInstance, - MultiLocation, + xcm::v3::Location, JustTry, collator_session_keys(), ExistentialDeposit::get(), - MultiLocation { parents: 1, interior: X2(Parachain(1313), GeneralIndex(12345)) }, + xcm::v3::Location { + parents: 1, + interior: [xcm::v3::Junction::Parachain(1313), xcm::v3::Junction::GeneralIndex(12345)] + .into() + }, Box::new(|| { assert!(Assets::asset_ids().collect::>().is_empty()); }), @@ -541,8 +573,8 @@ asset_test_utils::include_create_and_manage_foreign_assets_for_local_consensus_p WeightToFee, ForeignCreatorsSovereignAccountOf, ForeignAssetsInstance, - MultiLocation, - JustTry, + xcm::v3::Location, + V4V3LocationConverter, collator_session_keys(), ExistentialDeposit::get(), AssetDeposit::get(), @@ -626,12 +658,12 @@ fn receive_reserve_asset_deposited_roc_from_asset_hub_rococo_works() { AccountId::from([73; 32]), AccountId::from(BLOCK_AUTHOR_ACCOUNT), // receiving ROCs - (MultiLocation { parents: 2, interior: X1(GlobalConsensus(Rococo)) }, 1000000000000, 1_000_000_000), + (xcm::v3::Location::new(2, [xcm::v3::Junction::GlobalConsensus(xcm::v3::NetworkId::Rococo)]), 1000000000000, 1_000_000_000), bridging_to_asset_hub_rococo, ( - X1(PalletInstance(bp_bridge_hub_westend::WITH_BRIDGE_WESTEND_TO_ROCOCO_MESSAGES_PALLET_INDEX)), + [PalletInstance(bp_bridge_hub_westend::WITH_BRIDGE_WESTEND_TO_ROCOCO_MESSAGES_PALLET_INDEX)].into(), GlobalConsensus(Rococo), - X1(Parachain(1000)) + [Parachain(1000)].into() ) ) } diff --git a/cumulus/parachains/runtimes/assets/common/src/benchmarks.rs b/cumulus/parachains/runtimes/assets/common/src/benchmarks.rs index 344cb5ca336..44bda1eb370 100644 --- a/cumulus/parachains/runtimes/assets/common/src/benchmarks.rs +++ b/cumulus/parachains/runtimes/assets/common/src/benchmarks.rs @@ -19,26 +19,25 @@ use sp_std::marker::PhantomData; use xcm::latest::prelude::*; /// Creates asset pairs for liquidity pools with `Target` always being the first asset. -pub struct AssetPairFactory( - PhantomData<(Target, SelfParaId, PalletId)>, +pub struct AssetPairFactory( + PhantomData<(Target, SelfParaId, PalletId, L)>, ); -impl, SelfParaId: Get, PalletId: Get> - pallet_asset_conversion::BenchmarkHelper - for AssetPairFactory +impl, SelfParaId: Get, PalletId: Get, L: TryFrom> + pallet_asset_conversion::BenchmarkHelper for AssetPairFactory { - fn create_pair(seed1: u32, seed2: u32) -> (MultiLocation, MultiLocation) { - let with_id = MultiLocation::new( + fn create_pair(seed1: u32, seed2: u32) -> (L, L) { + let with_id = Location::new( 1, - X3( + [ Parachain(SelfParaId::get().into()), PalletInstance(PalletId::get() as u8), GeneralIndex(seed2.into()), - ), + ], ); if seed1 % 2 == 0 { - (with_id, Target::get()) + (with_id.try_into().map_err(|_| "Something went wrong").unwrap(), Target::get()) } else { - (Target::get(), with_id) + (Target::get(), with_id.try_into().map_err(|_| "Something went wrong").unwrap()) } } } diff --git a/cumulus/parachains/runtimes/assets/common/src/foreign_creators.rs b/cumulus/parachains/runtimes/assets/common/src/foreign_creators.rs index 1ed7bd0538c..a9fd79bf939 100644 --- a/cumulus/parachains/runtimes/assets/common/src/foreign_creators.rs +++ b/cumulus/parachains/runtimes/assets/common/src/foreign_creators.rs @@ -17,21 +17,21 @@ use frame_support::traits::{ ContainsPair, EnsureOrigin, EnsureOriginWithArg, Everything, OriginTrait, }; use pallet_xcm::{EnsureXcm, Origin as XcmOrigin}; -use xcm::latest::MultiLocation; +use xcm::latest::Location; use xcm_executor::traits::ConvertLocation; /// `EnsureOriginWithArg` impl for `CreateOrigin` that allows only XCM origins that are locations /// containing the class location. -pub struct ForeignCreators( - sp_std::marker::PhantomData<(IsForeign, AccountOf, AccountId)>, +pub struct ForeignCreators( + sp_std::marker::PhantomData<(IsForeign, AccountOf, AccountId, L)>, ); impl< - IsForeign: ContainsPair, + IsForeign: ContainsPair, AccountOf: ConvertLocation, AccountId: Clone, RuntimeOrigin: From + OriginTrait + Clone, - > EnsureOriginWithArg - for ForeignCreators + L: TryFrom + TryInto + Clone, + > EnsureOriginWithArg for ForeignCreators where RuntimeOrigin::PalletsOrigin: From + TryInto, @@ -40,17 +40,20 @@ where fn try_origin( origin: RuntimeOrigin, - asset_location: &MultiLocation, + asset_location: &L, ) -> sp_std::result::Result { - let origin_location = EnsureXcm::::try_origin(origin.clone())?; + let origin_location = EnsureXcm::::try_origin(origin.clone())?; if !IsForeign::contains(asset_location, &origin_location) { return Err(origin) } - AccountOf::convert_location(&origin_location).ok_or(origin) + let latest_location: Location = + origin_location.clone().try_into().map_err(|_| origin.clone())?; + AccountOf::convert_location(&latest_location).ok_or(origin) } #[cfg(feature = "runtime-benchmarks")] - fn try_successful_origin(a: &MultiLocation) -> Result { - Ok(pallet_xcm::Origin::Xcm(*a).into()) + fn try_successful_origin(a: &L) -> Result { + let latest_location: Location = (*a).clone().try_into().map_err(|_| ())?; + Ok(pallet_xcm::Origin::Xcm(latest_location).into()) } } diff --git a/cumulus/parachains/runtimes/assets/common/src/fungible_conversion.rs b/cumulus/parachains/runtimes/assets/common/src/fungible_conversion.rs index 80f8a971d21..e21203485a7 100644 --- a/cumulus/parachains/runtimes/assets/common/src/fungible_conversion.rs +++ b/cumulus/parachains/runtimes/assets/common/src/fungible_conversion.rs @@ -19,52 +19,48 @@ use crate::runtime_api::FungiblesAccessError; use frame_support::traits::Contains; use sp_runtime::traits::MaybeEquivalence; use sp_std::{borrow::Borrow, vec::Vec}; -use xcm::latest::{MultiAsset, MultiLocation}; +use xcm::latest::{Asset, Location}; use xcm_builder::{ConvertedConcreteId, MatchedConvertedConcreteId}; use xcm_executor::traits::MatchesFungibles; -/// Converting any [`(AssetId, Balance)`] to [`MultiAsset`] -pub trait MultiAssetConverter: +/// Converting any [`(AssetId, Balance)`] to [`Asset`] +pub trait AssetConverter: MatchesFungibles where AssetId: Clone, Balance: Clone, - ConvertAssetId: MaybeEquivalence, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, { - fn convert_ref( - value: impl Borrow<(AssetId, Balance)>, - ) -> Result; + fn convert_ref(value: impl Borrow<(AssetId, Balance)>) -> Result; } -/// Checks for `MultiLocation`. -pub trait MatchesMultiLocation: +/// Checks for `Location`. +pub trait MatchesLocation: MatchesFungibles where AssetId: Clone, Balance: Clone, - MatchAssetId: Contains, - ConvertAssetId: MaybeEquivalence, + MatchAssetId: Contains, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, { - fn contains(location: &MultiLocation) -> bool; + fn contains(location: &Location) -> bool; } impl< AssetId: Clone, Balance: Clone, - ConvertAssetId: MaybeEquivalence, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, - > MultiAssetConverter + > AssetConverter for ConvertedConcreteId { - fn convert_ref( - value: impl Borrow<(AssetId, Balance)>, - ) -> Result { + fn convert_ref(value: impl Borrow<(AssetId, Balance)>) -> Result { let (asset_id, balance) = value.borrow(); match ConvertAssetId::convert_back(asset_id) { - Some(asset_id_as_multilocation) => match ConvertBalance::convert_back(balance) { - Some(amount) => Ok((asset_id_as_multilocation, amount).into()), + Some(asset_id_as_location) => match ConvertBalance::convert_back(balance) { + Some(amount) => Ok((asset_id_as_location, amount).into()), None => Err(FungiblesAccessError::AmountToBalanceConversionFailed), }, None => Err(FungiblesAccessError::AssetIdConversionFailed), @@ -75,19 +71,17 @@ impl< impl< AssetId: Clone, Balance: Clone, - MatchAssetId: Contains, - ConvertAssetId: MaybeEquivalence, + MatchAssetId: Contains, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, - > MultiAssetConverter + > AssetConverter for MatchedConvertedConcreteId { - fn convert_ref( - value: impl Borrow<(AssetId, Balance)>, - ) -> Result { + fn convert_ref(value: impl Borrow<(AssetId, Balance)>) -> Result { let (asset_id, balance) = value.borrow(); match ConvertAssetId::convert_back(asset_id) { - Some(asset_id_as_multilocation) => match ConvertBalance::convert_back(balance) { - Some(amount) => Ok((asset_id_as_multilocation, amount).into()), + Some(asset_id_as_location) => match ConvertBalance::convert_back(balance) { + Some(amount) => Ok((asset_id_as_location, amount).into()), None => Err(FungiblesAccessError::AmountToBalanceConversionFailed), }, None => Err(FungiblesAccessError::AssetIdConversionFailed), @@ -98,13 +92,13 @@ impl< impl< AssetId: Clone, Balance: Clone, - MatchAssetId: Contains, - ConvertAssetId: MaybeEquivalence, + MatchAssetId: Contains, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, - > MatchesMultiLocation + > MatchesLocation for MatchedConvertedConcreteId { - fn contains(location: &MultiLocation) -> bool { + fn contains(location: &Location) -> bool { MatchAssetId::contains(location) } } @@ -113,12 +107,12 @@ impl< impl< AssetId: Clone, Balance: Clone, - MatchAssetId: Contains, - ConvertAssetId: MaybeEquivalence, + MatchAssetId: Contains, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, - > MatchesMultiLocation for Tuple + > MatchesLocation for Tuple { - fn contains(location: &MultiLocation) -> bool { + fn contains(location: &Location) -> bool { for_tuples!( #( match Tuple::contains(location) { o @ true => return o, _ => () } )* ); @@ -127,27 +121,24 @@ impl< } } -/// Helper function to convert collections with [`(AssetId, Balance)`] to [`MultiAsset`] +/// Helper function to convert collections with [`(AssetId, Balance)`] to [`Asset`] pub fn convert<'a, AssetId, Balance, ConvertAssetId, ConvertBalance, Converter>( items: impl Iterator, -) -> Result, FungiblesAccessError> +) -> Result, FungiblesAccessError> where AssetId: Clone + 'a, Balance: Clone + 'a, - ConvertAssetId: MaybeEquivalence, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, - Converter: MultiAssetConverter, + Converter: AssetConverter, { items.map(Converter::convert_ref).collect() } -/// Helper function to convert `Balance` with MultiLocation` to `MultiAsset` -pub fn convert_balance< - T: frame_support::pallet_prelude::Get, - Balance: TryInto, ->( +/// Helper function to convert `Balance` with Location` to `Asset` +pub fn convert_balance, Balance: TryInto>( balance: Balance, -) -> Result { +) -> Result { match balance.try_into() { Ok(balance) => Ok((T::get(), balance).into()), Err(_) => Err(FungiblesAccessError::AmountToBalanceConversionFailed), @@ -162,20 +153,20 @@ mod tests { use xcm::latest::prelude::*; use xcm_executor::traits::{Identity, JustTry}; - type Converter = MatchedConvertedConcreteId; + type Converter = MatchedConvertedConcreteId; #[test] fn converted_concrete_id_fungible_multi_asset_conversion_roundtrip_works() { - let location = MultiLocation::new(0, X1(GlobalConsensus(ByGenesis([0; 32])))); + let location = Location::new(0, [GlobalConsensus(ByGenesis([0; 32]))]); let amount = 123456_u64; - let expected_multi_asset = MultiAsset { - id: Concrete(MultiLocation::new(0, X1(GlobalConsensus(ByGenesis([0; 32]))))), + let expected_multi_asset = Asset { + id: AssetId(Location::new(0, [GlobalConsensus(ByGenesis([0; 32]))])), fun: Fungible(123456_u128), }; assert_eq!( Converter::matches_fungibles(&expected_multi_asset).map_err(|_| ()), - Ok((location, amount)) + Ok((location.clone(), amount)) ); assert_eq!(Converter::convert_ref((location, amount)), Ok(expected_multi_asset)); @@ -184,17 +175,17 @@ mod tests { #[test] fn converted_concrete_id_fungible_multi_asset_conversion_collection_works() { let data = vec![ - (MultiLocation::new(0, X1(GlobalConsensus(ByGenesis([0; 32])))), 123456_u64), - (MultiLocation::new(1, X1(GlobalConsensus(ByGenesis([1; 32])))), 654321_u64), + (Location::new(0, [GlobalConsensus(ByGenesis([0; 32]))]), 123456_u64), + (Location::new(1, [GlobalConsensus(ByGenesis([1; 32]))]), 654321_u64), ]; let expected_data = vec![ - MultiAsset { - id: Concrete(MultiLocation::new(0, X1(GlobalConsensus(ByGenesis([0; 32]))))), + Asset { + id: AssetId(Location::new(0, [GlobalConsensus(ByGenesis([0; 32]))])), fun: Fungible(123456_u128), }, - MultiAsset { - id: Concrete(MultiLocation::new(1, X1(GlobalConsensus(ByGenesis([1; 32]))))), + Asset { + id: AssetId(Location::new(1, [GlobalConsensus(ByGenesis([1; 32]))])), fun: Fungible(654321_u128), }, ]; diff --git a/cumulus/parachains/runtimes/assets/common/src/lib.rs b/cumulus/parachains/runtimes/assets/common/src/lib.rs index b0e47143929..f21e1766436 100644 --- a/cumulus/parachains/runtimes/assets/common/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/common/src/lib.rs @@ -23,15 +23,24 @@ pub mod local_and_foreign_assets; pub mod matching; pub mod runtime_api; -use crate::matching::{LocalMultiLocationPattern, ParentLocation}; +use crate::matching::{LocalLocationPattern, ParentLocation}; use frame_support::traits::{Equals, EverythingBut}; use parachains_common::AssetIdForTrustBackedAssets; -use xcm::prelude::MultiLocation; -use xcm_builder::{AsPrefixedGeneralIndex, MatchedConvertedConcreteId, StartsWith}; -use xcm_executor::traits::{Identity, JustTry}; +use xcm_builder::{ + AsPrefixedGeneralIndex, MatchedConvertedConcreteId, StartsWith, V4V3LocationConverter, +}; +use xcm_executor::traits::JustTry; -/// `MultiLocation` vs `AssetIdForTrustBackedAssets` converter for `TrustBackedAssets` +/// `Location` vs `AssetIdForTrustBackedAssets` converter for `TrustBackedAssets` pub type AssetIdForTrustBackedAssetsConvert = + AsPrefixedGeneralIndex< + TrustBackedAssetsPalletLocation, + AssetIdForTrustBackedAssets, + JustTry, + xcm::v3::Location, + >; + +pub type AssetIdForTrustBackedAssetsConvertLatest = AsPrefixedGeneralIndex; /// [`MatchedConvertedConcreteId`] converter dedicated for `TrustBackedAssets` @@ -40,59 +49,55 @@ pub type TrustBackedAssetsConvertedConcreteId, - AssetIdForTrustBackedAssetsConvert, + AssetIdForTrustBackedAssetsConvertLatest, JustTry, >; -/// AssetId used for identifying assets by MultiLocation. -pub type MultiLocationForAssetId = MultiLocation; +/// [`MatchedConvertedConcreteId`] converter dedicated for storing `AssetId` as `Location`. +pub type LocationConvertedConcreteId = MatchedConvertedConcreteId< + xcm::v3::Location, + Balance, + LocationFilter, + V4V3LocationConverter, + JustTry, +>; /// [`MatchedConvertedConcreteId`] converter dedicated for `TrustBackedAssets` -pub type TrustBackedAssetsAsMultiLocation = +pub type TrustBackedAssetsAsLocation = MatchedConvertedConcreteId< - MultiLocationForAssetId, + xcm::v3::Location, Balance, StartsWith, - Identity, - JustTry, - >; - -/// [`MatchedConvertedConcreteId`] converter dedicated for storing `AssetId` as `MultiLocation`. -pub type MultiLocationConvertedConcreteId = - MatchedConvertedConcreteId< - MultiLocationForAssetId, - Balance, - MultiLocationFilter, - Identity, + V4V3LocationConverter, JustTry, >; /// [`MatchedConvertedConcreteId`] converter dedicated for storing `ForeignAssets` with `AssetId` as -/// `MultiLocation`. +/// `Location`. /// /// Excludes by default: /// - parent as relay chain -/// - all local MultiLocations +/// - all local Locations /// -/// `AdditionalMultiLocationExclusionFilter` can customize additional excluded MultiLocations -pub type ForeignAssetsConvertedConcreteId = - MultiLocationConvertedConcreteId< +/// `AdditionalLocationExclusionFilter` can customize additional excluded Locations +pub type ForeignAssetsConvertedConcreteId = + LocationConvertedConcreteId< EverythingBut<( // Excludes relay/parent chain currency Equals, // Here we rely on fact that something like this works: - // assert!(MultiLocation::new(1, - // X1(Parachain(100))).starts_with(&MultiLocation::parent())); - // assert!(X1(Parachain(100)).starts_with(&Here)); - StartsWith, + // assert!(Location::new(1, + // [Parachain(100)]).starts_with(&Location::parent())); + // assert!([Parachain(100)].into().starts_with(&Here)); + StartsWith, // Here we can exclude more stuff or leave it as `()` - AdditionalMultiLocationExclusionFilter, + AdditionalLocationExclusionFilter, )>, Balance, >; type AssetIdForPoolAssets = u32; -/// `MultiLocation` vs `AssetIdForPoolAssets` converter for `PoolAssets`. +/// `Location` vs `AssetIdForPoolAssets` converter for `PoolAssets`. pub type AssetIdForPoolAssetsConvert = AsPrefixedGeneralIndex; /// [`MatchedConvertedConcreteId`] converter dedicated for `PoolAssets` @@ -109,28 +114,28 @@ pub type PoolAssetsConvertedConcreteId = mod tests { use super::*; use sp_runtime::traits::MaybeEquivalence; - use xcm::latest::prelude::*; + use xcm::prelude::*; use xcm_builder::StartsWithExplicitGlobalConsensus; use xcm_executor::traits::{Error as MatchError, MatchesFungibles}; #[test] fn asset_id_for_trust_backed_assets_convert_works() { frame_support::parameter_types! { - pub TrustBackedAssetsPalletLocation: MultiLocation = MultiLocation::new(5, X1(PalletInstance(13))); + pub TrustBackedAssetsPalletLocation: Location = Location::new(5, [PalletInstance(13)]); } let local_asset_id = 123456789 as AssetIdForTrustBackedAssets; let expected_reverse_ref = - MultiLocation::new(5, X2(PalletInstance(13), GeneralIndex(local_asset_id.into()))); + Location::new(5, [PalletInstance(13), GeneralIndex(local_asset_id.into())]); assert_eq!( - AssetIdForTrustBackedAssetsConvert::::convert_back( + AssetIdForTrustBackedAssetsConvertLatest::::convert_back( &local_asset_id ) .unwrap(), expected_reverse_ref ); assert_eq!( - AssetIdForTrustBackedAssetsConvert::::convert( + AssetIdForTrustBackedAssetsConvertLatest::::convert( &expected_reverse_ref ) .unwrap(), @@ -141,7 +146,7 @@ mod tests { #[test] fn trust_backed_assets_match_fungibles_works() { frame_support::parameter_types! { - pub TrustBackedAssetsPalletLocation: MultiLocation = MultiLocation::new(0, X1(PalletInstance(13))); + pub TrustBackedAssetsPalletLocation: Location = Location::new(0, [PalletInstance(13)]); } // setup convert type TrustBackedAssetsConvert = @@ -149,85 +154,86 @@ mod tests { let test_data = vec![ // missing GeneralIndex - (ma_1000(0, X1(PalletInstance(13))), Err(MatchError::AssetIdConversionFailed)), + (ma_1000(0, [PalletInstance(13)].into()), Err(MatchError::AssetIdConversionFailed)), ( - ma_1000(0, X2(PalletInstance(13), GeneralKey { data: [0; 32], length: 32 })), + ma_1000(0, [PalletInstance(13), GeneralKey { data: [0; 32], length: 32 }].into()), Err(MatchError::AssetIdConversionFailed), ), ( - ma_1000(0, X2(PalletInstance(13), Parachain(1000))), + ma_1000(0, [PalletInstance(13), Parachain(1000)].into()), Err(MatchError::AssetIdConversionFailed), ), // OK - (ma_1000(0, X2(PalletInstance(13), GeneralIndex(1234))), Ok((1234, 1000))), + (ma_1000(0, [PalletInstance(13), GeneralIndex(1234)].into()), Ok((1234, 1000))), ( - ma_1000(0, X3(PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222))), + ma_1000(0, [PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222)].into()), Ok((1234, 1000)), ), ( ma_1000( 0, - X4( + [ PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222), GeneralKey { data: [0; 32], length: 32 }, - ), + ] + .into(), ), Ok((1234, 1000)), ), // wrong pallet instance ( - ma_1000(0, X2(PalletInstance(77), GeneralIndex(1234))), + ma_1000(0, [PalletInstance(77), GeneralIndex(1234)].into()), Err(MatchError::AssetNotHandled), ), ( - ma_1000(0, X3(PalletInstance(77), GeneralIndex(1234), GeneralIndex(2222))), + ma_1000(0, [PalletInstance(77), GeneralIndex(1234), GeneralIndex(2222)].into()), Err(MatchError::AssetNotHandled), ), // wrong parent ( - ma_1000(1, X2(PalletInstance(13), GeneralIndex(1234))), + ma_1000(1, [PalletInstance(13), GeneralIndex(1234)].into()), Err(MatchError::AssetNotHandled), ), ( - ma_1000(1, X3(PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222))), + ma_1000(1, [PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222)].into()), Err(MatchError::AssetNotHandled), ), ( - ma_1000(1, X2(PalletInstance(77), GeneralIndex(1234))), + ma_1000(1, [PalletInstance(77), GeneralIndex(1234)].into()), Err(MatchError::AssetNotHandled), ), ( - ma_1000(1, X3(PalletInstance(77), GeneralIndex(1234), GeneralIndex(2222))), + ma_1000(1, [PalletInstance(77), GeneralIndex(1234), GeneralIndex(2222)].into()), Err(MatchError::AssetNotHandled), ), // wrong parent ( - ma_1000(2, X2(PalletInstance(13), GeneralIndex(1234))), + ma_1000(2, [PalletInstance(13), GeneralIndex(1234)].into()), Err(MatchError::AssetNotHandled), ), ( - ma_1000(2, X3(PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222))), + ma_1000(2, [PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222)].into()), Err(MatchError::AssetNotHandled), ), // missing GeneralIndex - (ma_1000(0, X1(PalletInstance(77))), Err(MatchError::AssetNotHandled)), - (ma_1000(1, X1(PalletInstance(13))), Err(MatchError::AssetNotHandled)), - (ma_1000(2, X1(PalletInstance(13))), Err(MatchError::AssetNotHandled)), + (ma_1000(0, [PalletInstance(77)].into()), Err(MatchError::AssetNotHandled)), + (ma_1000(1, [PalletInstance(13)].into()), Err(MatchError::AssetNotHandled)), + (ma_1000(2, [PalletInstance(13)].into()), Err(MatchError::AssetNotHandled)), ]; - for (multi_asset, expected_result) in test_data { + for (asset, expected_result) in test_data { assert_eq!( - >::matches_fungibles(&multi_asset), - expected_result, "multi_asset: {:?}", multi_asset); + >::matches_fungibles(&asset.clone().try_into().unwrap()), + expected_result, "asset: {:?}", asset); } } #[test] - fn multi_location_converted_concrete_id_converter_works() { + fn location_converted_concrete_id_converter_works() { frame_support::parameter_types! { - pub Parachain100Pattern: MultiLocation = MultiLocation::new(1, X1(Parachain(100))); + pub Parachain100Pattern: Location = Location::new(1, [Parachain(100)]); pub UniversalLocationNetworkId: NetworkId = NetworkId::ByGenesis([9; 32]); } @@ -243,95 +249,125 @@ mod tests { let test_data = vec![ // excluded as local (ma_1000(0, Here), Err(MatchError::AssetNotHandled)), - (ma_1000(0, X1(Parachain(100))), Err(MatchError::AssetNotHandled)), + (ma_1000(0, [Parachain(100)].into()), Err(MatchError::AssetNotHandled)), ( - ma_1000(0, X2(PalletInstance(13), GeneralIndex(1234))), + ma_1000(0, [PalletInstance(13), GeneralIndex(1234)].into()), Err(MatchError::AssetNotHandled), ), // excluded as parent (ma_1000(1, Here), Err(MatchError::AssetNotHandled)), // excluded as additional filter - Parachain100Pattern - (ma_1000(1, X1(Parachain(100))), Err(MatchError::AssetNotHandled)), - (ma_1000(1, X2(Parachain(100), GeneralIndex(1234))), Err(MatchError::AssetNotHandled)), + (ma_1000(1, [Parachain(100)].into()), Err(MatchError::AssetNotHandled)), ( - ma_1000(1, X3(Parachain(100), PalletInstance(13), GeneralIndex(1234))), + ma_1000(1, [Parachain(100), GeneralIndex(1234)].into()), + Err(MatchError::AssetNotHandled), + ), + ( + ma_1000(1, [Parachain(100), PalletInstance(13), GeneralIndex(1234)].into()), Err(MatchError::AssetNotHandled), ), // excluded as additional filter - StartsWithExplicitGlobalConsensus ( - ma_1000(1, X1(GlobalConsensus(NetworkId::ByGenesis([9; 32])))), + ma_1000(1, [GlobalConsensus(NetworkId::ByGenesis([9; 32]))].into()), Err(MatchError::AssetNotHandled), ), ( - ma_1000(2, X1(GlobalConsensus(NetworkId::ByGenesis([9; 32])))), + ma_1000(2, [GlobalConsensus(NetworkId::ByGenesis([9; 32]))].into()), Err(MatchError::AssetNotHandled), ), ( ma_1000( 2, - X3( + [ GlobalConsensus(NetworkId::ByGenesis([9; 32])), Parachain(200), GeneralIndex(1234), - ), + ] + .into(), ), Err(MatchError::AssetNotHandled), ), // ok - (ma_1000(1, X1(Parachain(200))), Ok((MultiLocation::new(1, X1(Parachain(200))), 1000))), - (ma_1000(2, X1(Parachain(200))), Ok((MultiLocation::new(2, X1(Parachain(200))), 1000))), ( - ma_1000(1, X2(Parachain(200), GeneralIndex(1234))), - Ok((MultiLocation::new(1, X2(Parachain(200), GeneralIndex(1234))), 1000)), + ma_1000(1, [Parachain(200)].into()), + Ok((xcm::v3::Location::new(1, [xcm::v3::Junction::Parachain(200)]), 1000)), + ), + ( + ma_1000(2, [Parachain(200)].into()), + Ok((xcm::v3::Location::new(2, [xcm::v3::Junction::Parachain(200)]), 1000)), ), ( - ma_1000(2, X2(Parachain(200), GeneralIndex(1234))), - Ok((MultiLocation::new(2, X2(Parachain(200), GeneralIndex(1234))), 1000)), + ma_1000(1, [Parachain(200), GeneralIndex(1234)].into()), + Ok(( + xcm::v3::Location::new( + 1, + [xcm::v3::Junction::Parachain(200), xcm::v3::Junction::GeneralIndex(1234)], + ), + 1000, + )), ), ( - ma_1000(2, X1(GlobalConsensus(NetworkId::ByGenesis([7; 32])))), + ma_1000(2, [Parachain(200), GeneralIndex(1234)].into()), Ok(( - MultiLocation::new(2, X1(GlobalConsensus(NetworkId::ByGenesis([7; 32])))), + xcm::v3::Location::new( + 2, + [xcm::v3::Junction::Parachain(200), xcm::v3::Junction::GeneralIndex(1234)], + ), + 1000, + )), + ), + ( + ma_1000(2, [GlobalConsensus(NetworkId::ByGenesis([7; 32]))].into()), + Ok(( + xcm::v3::Location::new( + 2, + [xcm::v3::Junction::GlobalConsensus(xcm::v3::NetworkId::ByGenesis( + [7; 32], + ))], + ), 1000, )), ), ( ma_1000( 2, - X3( + [ GlobalConsensus(NetworkId::ByGenesis([7; 32])), Parachain(200), GeneralIndex(1234), - ), + ] + .into(), ), Ok(( - MultiLocation::new( + xcm::v3::Location::new( 2, - X3( - GlobalConsensus(NetworkId::ByGenesis([7; 32])), - Parachain(200), - GeneralIndex(1234), - ), + [ + xcm::v3::Junction::GlobalConsensus(xcm::v3::NetworkId::ByGenesis( + [7; 32], + )), + xcm::v3::Junction::Parachain(200), + xcm::v3::Junction::GeneralIndex(1234), + ], ), 1000, )), ), ]; - for (multi_asset, expected_result) in test_data { + for (asset, expected_result) in test_data { assert_eq!( - >::matches_fungibles( - &multi_asset + >::matches_fungibles( + &asset.clone().try_into().unwrap() ), expected_result, - "multi_asset: {:?}", - multi_asset + "asset: {:?}", + asset ); } } - // Create MultiAsset - fn ma_1000(parents: u8, interior: Junctions) -> MultiAsset { - (MultiLocation::new(parents, interior), 1000).into() + // Create Asset + fn ma_1000(parents: u8, interior: Junctions) -> Asset { + (Location::new(parents, interior), 1000).into() } } diff --git a/cumulus/parachains/runtimes/assets/common/src/local_and_foreign_assets.rs b/cumulus/parachains/runtimes/assets/common/src/local_and_foreign_assets.rs index 7dd497797ea..7c237660610 100644 --- a/cumulus/parachains/runtimes/assets/common/src/local_and_foreign_assets.rs +++ b/cumulus/parachains/runtimes/assets/common/src/local_and_foreign_assets.rs @@ -20,32 +20,32 @@ use sp_runtime::{ Either::{Left, Right}, }; use sp_std::marker::PhantomData; -use xcm::latest::MultiLocation; +use xcm::latest::Location; -/// Converts a given [`MultiLocation`] to [`Either::Left`] when equal to `Target`, or +/// Converts a given [`Location`] to [`Either::Left`] when equal to `Target`, or /// [`Either::Right`] otherwise. /// /// Suitable for use as a `Criterion` with [`frame_support::traits::tokens::fungible::UnionOf`]. -pub struct TargetFromLeft(PhantomData); -impl> Convert> - for TargetFromLeft -{ - fn convert(l: MultiLocation) -> Either<(), MultiLocation> { +pub struct TargetFromLeft(PhantomData<(Target, L)>); +impl, L: PartialEq + Eq> Convert> for TargetFromLeft { + fn convert(l: L) -> Either<(), L> { Target::get().eq(&l).then(|| Left(())).map_or(Right(l), |n| n) } } -/// Converts a given [`MultiLocation`] to [`Either::Left`] based on the `Equivalence` criteria. +/// Converts a given [`Location`] to [`Either::Left`] based on the `Equivalence` criteria. /// Returns [`Either::Right`] if not equivalent. /// /// Suitable for use as a `Criterion` with [`frame_support::traits::tokens::fungibles::UnionOf`]. -pub struct LocalFromLeft(PhantomData<(Equivalence, AssetId)>); -impl Convert> - for LocalFromLeft +pub struct LocalFromLeft( + PhantomData<(Equivalence, AssetId, L)>, +); +impl Convert> + for LocalFromLeft where - Equivalence: MaybeEquivalence, + Equivalence: MaybeEquivalence, { - fn convert(l: MultiLocation) -> Either { + fn convert(l: L) -> Either { match Equivalence::convert(&l) { Some(id) => Left(id), None => Right(l), @@ -53,7 +53,7 @@ where } } -pub trait MatchesLocalAndForeignAssetsMultiLocation { - fn is_local(location: &MultiLocation) -> bool; - fn is_foreign(location: &MultiLocation) -> bool; +pub trait MatchesLocalAndForeignAssetsLocation { + fn is_local(location: &L) -> bool; + fn is_foreign(location: &L) -> bool; } diff --git a/cumulus/parachains/runtimes/assets/common/src/matching.rs b/cumulus/parachains/runtimes/assets/common/src/matching.rs index d6ecc3ec99f..478bba4565d 100644 --- a/cumulus/parachains/runtimes/assets/common/src/matching.rs +++ b/cumulus/parachains/runtimes/assets/common/src/matching.rs @@ -15,67 +15,72 @@ use cumulus_primitives_core::ParaId; use frame_support::{pallet_prelude::Get, traits::ContainsPair}; -use xcm::{ - latest::prelude::{MultiAsset, MultiLocation}, - prelude::*, -}; +use xcm::prelude::*; + use xcm_builder::ensure_is_remote; frame_support::parameter_types! { - pub LocalMultiLocationPattern: MultiLocation = MultiLocation::new(0, Here); - pub ParentLocation: MultiLocation = MultiLocation::parent(); + pub LocalLocationPattern: Location = Location::new(0, Here); + pub ParentLocation: Location = Location::parent(); } /// Accepts an asset if it is from the origin. pub struct IsForeignConcreteAsset(sp_std::marker::PhantomData); -impl> ContainsPair +impl> ContainsPair for IsForeignConcreteAsset { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + fn contains(asset: &Asset, origin: &Location) -> bool { log::trace!(target: "xcm::contains", "IsForeignConcreteAsset asset: {:?}, origin: {:?}", asset, origin); - matches!(asset.id, Concrete(ref id) if IsForeign::contains(id, origin)) + matches!(asset.id, AssetId(ref id) if IsForeign::contains(id, origin)) } } -/// Checks if `a` is from sibling location `b`. Checks that `MultiLocation-a` starts with -/// `MultiLocation-b`, and that the `ParaId` of `b` is not equal to `a`. -pub struct FromSiblingParachain(sp_std::marker::PhantomData); -impl> ContainsPair - for FromSiblingParachain +/// Checks if `a` is from sibling location `b`. Checks that `Location-a` starts with +/// `Location-b`, and that the `ParaId` of `b` is not equal to `a`. +pub struct FromSiblingParachain( + sp_std::marker::PhantomData<(SelfParaId, L)>, +); +impl, L: TryFrom + TryInto + Clone> ContainsPair + for FromSiblingParachain { - fn contains(&a: &MultiLocation, b: &MultiLocation) -> bool { - // `a` needs to be from `b` at least - if !a.starts_with(b) { - return false - } + fn contains(a: &L, b: &L) -> bool { + // We convert locations to latest + let a = match ((*a).clone().try_into(), (*b).clone().try_into()) { + (Ok(a), Ok(b)) if a.starts_with(&b) => a, // `a` needs to be from `b` at least + _ => return false, + }; // here we check if sibling - match a { - MultiLocation { parents: 1, interior } => + match a.unpack() { + (1, interior) => matches!(interior.first(), Some(Parachain(sibling_para_id)) if sibling_para_id.ne(&u32::from(SelfParaId::get()))), _ => false, } } } -/// Checks if `a` is from the expected global consensus network. Checks that `MultiLocation-a` -/// starts with `MultiLocation-b`, and that network is a foreign consensus system. -pub struct FromNetwork( - sp_std::marker::PhantomData<(UniversalLocation, ExpectedNetworkId)>, +/// Checks if `a` is from the expected global consensus network. Checks that `Location-a` +/// starts with `Location-b`, and that network is a foreign consensus system. +pub struct FromNetwork( + sp_std::marker::PhantomData<(UniversalLocation, ExpectedNetworkId, L)>, ); -impl, ExpectedNetworkId: Get> - ContainsPair for FromNetwork +impl< + UniversalLocation: Get, + ExpectedNetworkId: Get, + L: TryFrom + TryInto + Clone, + > ContainsPair for FromNetwork { - fn contains(&a: &MultiLocation, b: &MultiLocation) -> bool { - // `a` needs to be from `b` at least - if !a.starts_with(b) { - return false - } + fn contains(a: &L, b: &L) -> bool { + // We convert locations to latest + let a = match ((*a).clone().try_into(), (*b).clone().try_into()) { + (Ok(a), Ok(b)) if a.starts_with(&b) => a, // `a` needs to be from `b` at least + _ => return false, + }; let universal_source = UniversalLocation::get(); - // ensure that `a`` is remote and from the expected network - match ensure_is_remote(universal_source, a) { + // ensure that `a` is remote and from the expected network + match ensure_is_remote(universal_source.clone(), a.clone()) { Ok((network_id, _)) => network_id == ExpectedNetworkId::get(), Err(e) => { log::trace!( @@ -89,19 +94,17 @@ impl, ExpectedNetworkId: Get( sp_std::marker::PhantomData<(UniversalLocation, Reserves)>, ); -impl< - UniversalLocation: Get, - Reserves: ContainsPair, - > ContainsPair +impl, Reserves: ContainsPair> + ContainsPair for IsTrustedBridgedReserveLocationForConcreteAsset { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + fn contains(asset: &Asset, origin: &Location) -> bool { let universal_source = UniversalLocation::get(); log::trace!( target: "xcm::contains", @@ -110,7 +113,7 @@ impl< ); // check remote origin - let _ = match ensure_is_remote(universal_source, *origin) { + let _ = match ensure_is_remote(universal_source.clone(), origin.clone()) { Ok(devolved) => devolved, Err(_) => { log::trace!( @@ -133,14 +136,14 @@ mod tests { use frame_support::parameter_types; parameter_types! { - pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(Rococo), Parachain(1000)); + pub UniversalLocation: InteriorLocation = [GlobalConsensus(Rococo), Parachain(1000)].into(); pub ExpectedNetworkId: NetworkId = Wococo; } #[test] fn from_network_contains_works() { // asset and origin from foreign consensus works - let asset: MultiLocation = ( + let asset: Location = ( Parent, Parent, GlobalConsensus(Wococo), @@ -149,12 +152,11 @@ mod tests { GeneralIndex(1), ) .into(); - let origin: MultiLocation = - (Parent, Parent, GlobalConsensus(Wococo), Parachain(1000)).into(); + let origin: Location = (Parent, Parent, GlobalConsensus(Wococo), Parachain(1000)).into(); assert!(FromNetwork::::contains(&asset, &origin)); // asset and origin from local consensus fails - let asset: MultiLocation = ( + let asset: Location = ( Parent, Parent, GlobalConsensus(Rococo), @@ -163,17 +165,16 @@ mod tests { GeneralIndex(1), ) .into(); - let origin: MultiLocation = - (Parent, Parent, GlobalConsensus(Rococo), Parachain(1000)).into(); + let origin: Location = (Parent, Parent, GlobalConsensus(Rococo), Parachain(1000)).into(); assert!(!FromNetwork::::contains(&asset, &origin)); // asset and origin from here fails - let asset: MultiLocation = (PalletInstance(1), GeneralIndex(1)).into(); - let origin: MultiLocation = Here.into(); + let asset: Location = (PalletInstance(1), GeneralIndex(1)).into(); + let origin: Location = Here.into(); assert!(!FromNetwork::::contains(&asset, &origin)); // asset from different consensus fails - let asset: MultiLocation = ( + let asset: Location = ( Parent, Parent, GlobalConsensus(Polkadot), @@ -182,12 +183,11 @@ mod tests { GeneralIndex(1), ) .into(); - let origin: MultiLocation = - (Parent, Parent, GlobalConsensus(Wococo), Parachain(1000)).into(); + let origin: Location = (Parent, Parent, GlobalConsensus(Wococo), Parachain(1000)).into(); assert!(!FromNetwork::::contains(&asset, &origin)); // origin from different consensus fails - let asset: MultiLocation = ( + let asset: Location = ( Parent, Parent, GlobalConsensus(Wococo), @@ -196,12 +196,11 @@ mod tests { GeneralIndex(1), ) .into(); - let origin: MultiLocation = - (Parent, Parent, GlobalConsensus(Polkadot), Parachain(1000)).into(); + let origin: Location = (Parent, Parent, GlobalConsensus(Polkadot), Parachain(1000)).into(); assert!(!FromNetwork::::contains(&asset, &origin)); // asset and origin from unexpected consensus fails - let asset: MultiLocation = ( + let asset: Location = ( Parent, Parent, GlobalConsensus(Polkadot), @@ -210,8 +209,7 @@ mod tests { GeneralIndex(1), ) .into(); - let origin: MultiLocation = - (Parent, Parent, GlobalConsensus(Polkadot), Parachain(1000)).into(); + let origin: Location = (Parent, Parent, GlobalConsensus(Polkadot), Parachain(1000)).into(); assert!(!FromNetwork::::contains(&asset, &origin)); } } diff --git a/cumulus/parachains/runtimes/assets/common/src/runtime_api.rs b/cumulus/parachains/runtimes/assets/common/src/runtime_api.rs index 0a166a04819..19977cbedab 100644 --- a/cumulus/parachains/runtimes/assets/common/src/runtime_api.rs +++ b/cumulus/parachains/runtimes/assets/common/src/runtime_api.rs @@ -18,12 +18,12 @@ use codec::{Codec, Decode, Encode}; use sp_runtime::RuntimeDebug; #[cfg(feature = "std")] -use {sp_std::vec::Vec, xcm::latest::MultiAsset}; +use {sp_std::vec::Vec, xcm::latest::Asset}; /// The possible errors that can happen querying the storage of assets. #[derive(Eq, PartialEq, Encode, Decode, RuntimeDebug, scale_info::TypeInfo)] pub enum FungiblesAccessError { - /// `MultiLocation` to `AssetId`/`ClassId` conversion failed. + /// `Location` to `AssetId`/`ClassId` conversion failed. AssetIdConversionFailed, /// `u128` amount to currency `Balance` conversion failed. AmountToBalanceConversionFailed, @@ -36,11 +36,11 @@ sp_api::decl_runtime_apis! { where AccountId: Codec, { - /// Returns the list of all [`MultiAsset`] that an `AccountId` has. + /// Returns the list of all [`Asset`] that an `AccountId` has. #[changed_in(2)] - fn query_account_balances(account: AccountId) -> Result, FungiblesAccessError>; + fn query_account_balances(account: AccountId) -> Result, FungiblesAccessError>; - /// Returns the list of all [`MultiAsset`] that an `AccountId` has. - fn query_account_balances(account: AccountId) -> Result; + /// Returns the list of all [`Asset`] that an `AccountId` has. + fn query_account_balances(account: AccountId) -> Result; } } diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/lib.rs b/cumulus/parachains/runtimes/assets/test-utils/src/lib.rs index 872ad06ddd5..877d61780ce 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/lib.rs @@ -28,7 +28,7 @@ use xcm::latest::prelude::*; use xcm_builder::{CreateMatcher, MatchXcm}; /// Given a message, a sender, and a destination, it returns the delivery fees -fn get_fungible_delivery_fees(destination: MultiLocation, message: Xcm<()>) -> u128 { +fn get_fungible_delivery_fees(destination: Location, message: Xcm<()>) -> u128 { let Ok((_, delivery_fees)) = validate_send::(destination, message) else { unreachable!("message can be sent; qed") }; @@ -46,8 +46,8 @@ fn get_fungible_delivery_fees(destination: MultiLocation, message: X /// chain as part of a reserve-asset-transfer. pub(crate) fn assert_matches_reserve_asset_deposited_instructions( xcm: &mut Xcm, - expected_reserve_assets_deposited: &MultiAssets, - expected_beneficiary: &MultiLocation, + expected_reserve_assets_deposited: &Assets, + expected_beneficiary: &Location, ) { let _ = xcm .0 diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs index 915d99470c3..e981fae8015 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs @@ -37,7 +37,7 @@ use sp_runtime::{ traits::{MaybeEquivalence, StaticLookup, Zero}, DispatchError, Saturating, }; -use xcm::{latest::prelude::*, VersionedMultiAssets}; +use xcm::{latest::prelude::*, VersionedAssets}; use xcm_executor::{traits::ConvertLocation, XcmExecutor}; type RuntimeHelper = @@ -110,7 +110,7 @@ pub fn teleports_for_native_asset_works< 0.into() ); - let native_asset_id = MultiLocation::parent(); + let native_asset_id = Location::parent(); let buy_execution_fee_amount_eta = WeightToFee::weight_to_fee(&Weight::from_parts(90_000_000_000, 1024)); let native_asset_amount_unit = existential_deposit; @@ -119,38 +119,40 @@ pub fn teleports_for_native_asset_works< // 1. process received teleported assets from relaychain let xcm = Xcm(vec![ - ReceiveTeleportedAsset(MultiAssets::from(vec![MultiAsset { - id: Concrete(native_asset_id), + ReceiveTeleportedAsset(Assets::from(vec![Asset { + id: AssetId(native_asset_id.clone()), fun: Fungible(native_asset_amount_received.into()), }])), ClearOrigin, BuyExecution { - fees: MultiAsset { - id: Concrete(native_asset_id), + fees: Asset { + id: AssetId(native_asset_id.clone()), fun: Fungible(buy_execution_fee_amount_eta), }, weight_limit: Limited(Weight::from_parts(3035310000, 65536)), }, DepositAsset { assets: Wild(AllCounted(1)), - beneficiary: MultiLocation { + beneficiary: Location { parents: 0, - interior: X1(AccountId32 { + interior: [AccountId32 { network: None, id: target_account.clone().into(), - }), + }] + .into(), }, }, ExpectTransactStatus(MaybeErrorCode::Success), ]); - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); - let outcome = XcmExecutor::::execute_xcm( + let outcome = XcmExecutor::::prepare_and_execute( Parent, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Parent), + Weight::zero(), ); assert_ok!(outcome.ensure_complete()); @@ -163,14 +165,14 @@ pub fn teleports_for_native_asset_works< // 2. try to teleport asset back to the relaychain { - let dest = MultiLocation::parent(); - let mut dest_beneficiary = MultiLocation::parent() + let dest = Location::parent(); + let mut dest_beneficiary = Location::parent() .appended_with(AccountId32 { network: None, id: sp_runtime::AccountId32::new([3; 32]).into(), }) .unwrap(); - dest_beneficiary.reanchor(&dest, XcmConfig::UniversalLocation::get()).unwrap(); + dest_beneficiary.reanchor(&dest, &XcmConfig::UniversalLocation::get()).unwrap(); let target_account_balance_before_teleport = >::free_balance(&target_account); @@ -183,11 +185,11 @@ pub fn teleports_for_native_asset_works< // Mint funds into account to ensure it has enough balance to pay delivery fees let delivery_fees = xcm_helpers::transfer_assets_delivery_fees::( - (native_asset_id, native_asset_to_teleport_away.into()).into(), + (native_asset_id.clone(), native_asset_to_teleport_away.into()).into(), 0, Unlimited, - dest_beneficiary, - dest, + dest_beneficiary.clone(), + dest.clone(), ); >::mint_into( &target_account, @@ -199,7 +201,7 @@ pub fn teleports_for_native_asset_works< RuntimeHelper::::origin_of(target_account.clone()), dest, dest_beneficiary, - (native_asset_id, native_asset_to_teleport_away.into()), + (native_asset_id.clone(), native_asset_to_teleport_away.into()), None, included_head.clone(), &alice, @@ -228,14 +230,14 @@ pub fn teleports_for_native_asset_works< // trust `IsTeleporter` for `(relay-native-asset, para(2345))` pair { let other_para_id = 2345; - let dest = MultiLocation::new(1, X1(Parachain(other_para_id))); - let mut dest_beneficiary = MultiLocation::new(1, X1(Parachain(other_para_id))) + let dest = Location::new(1, [Parachain(other_para_id)]); + let mut dest_beneficiary = Location::new(1, [Parachain(other_para_id)]) .appended_with(AccountId32 { network: None, id: sp_runtime::AccountId32::new([3; 32]).into(), }) .unwrap(); - dest_beneficiary.reanchor(&dest, XcmConfig::UniversalLocation::get()).unwrap(); + dest_beneficiary.reanchor(&dest, &XcmConfig::UniversalLocation::get()).unwrap(); let target_account_balance_before_teleport = >::free_balance(&target_account); @@ -245,6 +247,7 @@ pub fn teleports_for_native_asset_works< native_asset_to_teleport_away < target_account_balance_before_teleport - existential_deposit ); + assert_eq!( RuntimeHelper::::do_teleport_assets::( RuntimeHelper::::origin_of(target_account.clone()), @@ -356,9 +359,9 @@ pub fn teleports_for_foreign_assets_works< ::Balance: From + Into, SovereignAccountOf: ConvertLocation>, >::AssetId: - From + Into, + From + Into, >::AssetIdParameter: - From + Into, + From + Into, >::Balance: From + Into, ::AccountId: @@ -370,23 +373,25 @@ pub fn teleports_for_foreign_assets_works< { // foreign parachain with the same consensus currency as asset let foreign_para_id = 2222; - let foreign_asset_id_multilocation = MultiLocation { + let foreign_asset_id_location = xcm::v3::Location { parents: 1, - interior: X2(Parachain(foreign_para_id), GeneralIndex(1234567)), + interior: [ + xcm::v3::Junction::Parachain(foreign_para_id), + xcm::v3::Junction::GeneralIndex(1234567), + ] + .into(), }; // foreign creator, which can be sibling parachain to match ForeignCreators - let foreign_creator = MultiLocation { parents: 1, interior: X1(Parachain(foreign_para_id)) }; + let foreign_creator = Location { parents: 1, interior: [Parachain(foreign_para_id)].into() }; let foreign_creator_as_account_id = SovereignAccountOf::convert_location(&foreign_creator).expect(""); // we want to buy execution with local relay chain currency let buy_execution_fee_amount = WeightToFee::weight_to_fee(&Weight::from_parts(90_000_000_000, 0)); - let buy_execution_fee = MultiAsset { - id: Concrete(MultiLocation::parent()), - fun: Fungible(buy_execution_fee_amount), - }; + let buy_execution_fee = + Asset { id: AssetId(Location::parent()), fun: Fungible(buy_execution_fee_amount) }; let teleported_foreign_asset_amount = 10_000_000_000_000; let runtime_para_id = 1000; @@ -425,14 +430,14 @@ pub fn teleports_for_foreign_assets_works< ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &target_account ), 0.into() ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &CheckingAccount::get() ), 0.into() @@ -441,14 +446,14 @@ pub fn teleports_for_foreign_assets_works< assert_total::< pallet_assets::Pallet, AccountIdOf, - >(foreign_asset_id_multilocation, 0, 0); + >(foreign_asset_id_location, 0, 0); // create foreign asset (0 total issuance) let asset_minimum_asset_balance = 3333333_u128; assert_ok!( >::force_create( RuntimeHelper::::root_origin(), - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), asset_owner.into(), false, asset_minimum_asset_balance.into() @@ -457,47 +462,52 @@ pub fn teleports_for_foreign_assets_works< assert_total::< pallet_assets::Pallet, AccountIdOf, - >(foreign_asset_id_multilocation, 0, 0); + >(foreign_asset_id_location, 0, 0); assert!(teleported_foreign_asset_amount > asset_minimum_asset_balance); + let foreign_asset_id_location_latest: Location = + foreign_asset_id_location.try_into().unwrap(); + // 1. process received teleported assets from sibling parachain (foreign_para_id) let xcm = Xcm(vec![ // BuyExecution with relaychain native token WithdrawAsset(buy_execution_fee.clone().into()), BuyExecution { - fees: MultiAsset { - id: Concrete(MultiLocation::parent()), + fees: Asset { + id: AssetId(Location::parent()), fun: Fungible(buy_execution_fee_amount), }, weight_limit: Limited(Weight::from_parts(403531000, 65536)), }, // Process teleported asset - ReceiveTeleportedAsset(MultiAssets::from(vec![MultiAsset { - id: Concrete(foreign_asset_id_multilocation), + ReceiveTeleportedAsset(Assets::from(vec![Asset { + id: AssetId(foreign_asset_id_location_latest.clone()), fun: Fungible(teleported_foreign_asset_amount), }])), DepositAsset { assets: Wild(AllOf { - id: Concrete(foreign_asset_id_multilocation), + id: AssetId(foreign_asset_id_location_latest.clone()), fun: WildFungibility::Fungible, }), - beneficiary: MultiLocation { + beneficiary: Location { parents: 0, - interior: X1(AccountId32 { + interior: [AccountId32 { network: None, id: target_account.clone().into(), - }), + }] + .into(), }, }, ExpectTransactStatus(MaybeErrorCode::Success), ]); - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); - let outcome = XcmExecutor::::execute_xcm( + let outcome = XcmExecutor::::prepare_and_execute( foreign_creator, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ); assert_ok!(outcome.ensure_complete()); @@ -508,7 +518,7 @@ pub fn teleports_for_foreign_assets_works< ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &target_account ), teleported_foreign_asset_amount.into() @@ -520,7 +530,7 @@ pub fn teleports_for_foreign_assets_works< ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &CheckingAccount::get() ), 0.into() @@ -530,25 +540,25 @@ pub fn teleports_for_foreign_assets_works< pallet_assets::Pallet, AccountIdOf, >( - foreign_asset_id_multilocation, + foreign_asset_id_location, teleported_foreign_asset_amount, teleported_foreign_asset_amount, ); // 2. try to teleport asset back to source parachain (foreign_para_id) { - let dest = MultiLocation::new(1, X1(Parachain(foreign_para_id))); - let mut dest_beneficiary = MultiLocation::new(1, X1(Parachain(foreign_para_id))) + let dest = Location::new(1, [Parachain(foreign_para_id)]); + let mut dest_beneficiary = Location::new(1, [Parachain(foreign_para_id)]) .appended_with(AccountId32 { network: None, id: sp_runtime::AccountId32::new([3; 32]).into(), }) .unwrap(); - dest_beneficiary.reanchor(&dest, XcmConfig::UniversalLocation::get()).unwrap(); + dest_beneficiary.reanchor(&dest, &XcmConfig::UniversalLocation::get()).unwrap(); let target_account_balance_before_teleport = >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &target_account, ); let asset_to_teleport_away = asset_minimum_asset_balance * 3; @@ -562,11 +572,11 @@ pub fn teleports_for_foreign_assets_works< // Make sure the target account has enough native asset to pay for delivery fees let delivery_fees = xcm_helpers::transfer_assets_delivery_fees::( - (foreign_asset_id_multilocation, asset_to_teleport_away).into(), + (foreign_asset_id_location_latest.clone(), asset_to_teleport_away).into(), 0, Unlimited, - dest_beneficiary, - dest, + dest_beneficiary.clone(), + dest.clone(), ); >::mint_into( &target_account, @@ -578,7 +588,7 @@ pub fn teleports_for_foreign_assets_works< RuntimeHelper::::origin_of(target_account.clone()), dest, dest_beneficiary, - (foreign_asset_id_multilocation, asset_to_teleport_away), + (foreign_asset_id_location_latest.clone(), asset_to_teleport_away), Some((runtime_para_id, foreign_para_id)), included_head, &alice, @@ -587,14 +597,14 @@ pub fn teleports_for_foreign_assets_works< // check balances assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &target_account ), (target_account_balance_before_teleport - asset_to_teleport_away.into()) ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &CheckingAccount::get() ), 0.into() @@ -604,7 +614,7 @@ pub fn teleports_for_foreign_assets_works< pallet_assets::Pallet, AccountIdOf, >( - foreign_asset_id_multilocation, + foreign_asset_id_location, teleported_foreign_asset_amount - asset_to_teleport_away, teleported_foreign_asset_amount - asset_to_teleport_away, ); @@ -717,17 +727,19 @@ pub fn asset_transactor_transfer_with_local_consensus_currency_works BOB let _ = RuntimeHelper::::do_transfer( - MultiLocation { + Location { parents: 0, - interior: X1(AccountId32 { network: None, id: source_account.clone().into() }), + interior: [AccountId32 { network: None, id: source_account.clone().into() }] + .into(), }, - MultiLocation { + Location { parents: 0, - interior: X1(AccountId32 { network: None, id: target_account.clone().into() }), + interior: [AccountId32 { network: None, id: target_account.clone().into() }] + .into(), }, // local_consensus_currency_asset, e.g.: relaychain token (KSM, DOT, ...) ( - MultiLocation { parents: 1, interior: Here }, + Location { parents: 1, interior: Here }, (BalanceOf::::from(1_u128) * unit).into(), ), ) @@ -779,7 +791,7 @@ macro_rules! include_asset_transactor_transfer_with_local_consensus_currency_wor } ); -///Test-case makes sure that `Runtime`'s `xcm::AssetTransactor` can handle native relay chain +/// Test-case makes sure that `Runtime`'s `xcm::AssetTransactor` can handle native relay chain /// currency pub fn asset_transactor_transfer_with_pallet_assets_instance_works< Runtime, @@ -820,8 +832,8 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< <::Lookup as StaticLookup>::Source: From<::AccountId>, AssetsPalletInstance: 'static, - AssetId: Clone + Copy, - AssetIdConverter: MaybeEquivalence, + AssetId: Clone, + AssetIdConverter: MaybeEquivalence, { ExtBuilder::::default() .with_collators(collator_session_keys.collators()) @@ -836,10 +848,10 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< .execute_with(|| { // create some asset class let asset_minimum_asset_balance = 3333333_u128; - let asset_id_as_multilocation = AssetIdConverter::convert_back(&asset_id).unwrap(); + let asset_id_as_location = AssetIdConverter::convert_back(&asset_id).unwrap(); assert_ok!(>::force_create( RuntimeHelper::::root_origin(), - asset_id.into(), + asset_id.clone().into(), asset_owner.clone().into(), false, asset_minimum_asset_balance.into() @@ -848,7 +860,7 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< // We first mint enough asset for the account to exist for assets assert_ok!(>::mint( RuntimeHelper::::origin_of(asset_owner.clone()), - asset_id.into(), + asset_id.clone().into(), alice_account.clone().into(), (6 * asset_minimum_asset_balance).into() )); @@ -856,28 +868,28 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< // check Assets before assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &alice_account ), (6 * asset_minimum_asset_balance).into() ); assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &bob_account ), 0.into() ); assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &charlie_account ), 0.into() ); assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &asset_owner ), 0.into() @@ -904,21 +916,20 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< // ExistentialDeposit) assert_noop!( RuntimeHelper::::do_transfer( - MultiLocation { + Location { parents: 0, - interior: X1(AccountId32 { - network: None, - id: alice_account.clone().into() - }), + interior: [AccountId32 { network: None, id: alice_account.clone().into() }] + .into(), }, - MultiLocation { + Location { parents: 0, - interior: X1(AccountId32 { + interior: [AccountId32 { network: None, id: charlie_account.clone().into() - }), + }] + .into(), }, - (asset_id_as_multilocation, asset_minimum_asset_balance), + (asset_id_as_location.clone(), asset_minimum_asset_balance), ), XcmError::FailedToTransactAsset(Into::<&str>::into( sp_runtime::TokenError::CannotCreate @@ -928,18 +939,17 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< // transfer_asset (deposit/withdraw) ALICE -> BOB (ok - has ExistentialDeposit) assert!(matches!( RuntimeHelper::::do_transfer( - MultiLocation { + Location { parents: 0, - interior: X1(AccountId32 { - network: None, - id: alice_account.clone().into() - }), + interior: [AccountId32 { network: None, id: alice_account.clone().into() }] + .into(), }, - MultiLocation { + Location { parents: 0, - interior: X1(AccountId32 { network: None, id: bob_account.clone().into() }), + interior: [AccountId32 { network: None, id: bob_account.clone().into() }] + .into(), }, - (asset_id_as_multilocation, asset_minimum_asset_balance), + (asset_id_as_location, asset_minimum_asset_balance), ), Ok(_) )); @@ -947,21 +957,21 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< // check Assets after assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &alice_account ), (5 * asset_minimum_asset_balance).into() ); assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &bob_account ), asset_minimum_asset_balance.into() ); assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &charlie_account ), 0.into() @@ -1093,26 +1103,23 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor <::Lookup as StaticLookup>::Source: From<::AccountId>, ForeignAssetsPalletInstance: 'static, - AssetId: Clone + Copy, - AssetIdConverter: MaybeEquivalence, + AssetId: Clone, + AssetIdConverter: MaybeEquivalence, { - // foreign parachain with the same consensus currency as asset - let foreign_asset_id_multilocation = - MultiLocation { parents: 1, interior: X2(Parachain(2222), GeneralIndex(1234567)) }; - let asset_id = AssetIdConverter::convert(&foreign_asset_id_multilocation).unwrap(); + // foreign parachain with the same consenus currency as asset + let foreign_asset_id_location = Location::new(1, [Parachain(2222), GeneralIndex(1234567)]); + let asset_id = AssetIdConverter::convert(&foreign_asset_id_location).unwrap(); // foreign creator, which can be sibling parachain to match ForeignCreators - let foreign_creator = MultiLocation { parents: 1, interior: X1(Parachain(2222)) }; + let foreign_creator = Location { parents: 1, interior: [Parachain(2222)].into() }; let foreign_creator_as_account_id = SovereignAccountOf::convert_location(&foreign_creator).expect(""); // we want to buy execution with local relay chain currency let buy_execution_fee_amount = WeightToFee::weight_to_fee(&Weight::from_parts(90_000_000_000, 0)); - let buy_execution_fee = MultiAsset { - id: Concrete(MultiLocation::parent()), - fun: Fungible(buy_execution_fee_amount), - }; + let buy_execution_fee = + Asset { id: AssetId(Location::parent()), fun: Fungible(buy_execution_fee_amount) }; const ASSET_NAME: &str = "My super coin"; const ASSET_SYMBOL: &str = "MY_S_COIN"; @@ -1152,7 +1159,7 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor Runtime, ForeignAssetsPalletInstance, >::create { - id: asset_id.into(), + id: asset_id.clone().into(), // admin as sovereign_account admin: foreign_creator_as_account_id.clone().into(), min_balance: 1.into(), @@ -1162,7 +1169,7 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor Runtime, ForeignAssetsPalletInstance, >::set_metadata { - id: asset_id.into(), + id: asset_id.clone().into(), name: Vec::from(ASSET_NAME), symbol: Vec::from(ASSET_SYMBOL), decimals: 12, @@ -1172,7 +1179,7 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor Runtime, ForeignAssetsPalletInstance, >::set_team { - id: asset_id.into(), + id: asset_id.clone().into(), issuer: foreign_creator_as_account_id.clone().into(), admin: foreign_creator_as_account_id.clone().into(), freezer: bob_account.clone().into(), @@ -1202,14 +1209,15 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor ]); // messages with different consensus should go through the local bridge-hub - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); // execute xcm as XcmpQueue would do - let outcome = XcmExecutor::::execute_xcm( - foreign_creator, + let outcome = XcmExecutor::::prepare_and_execute( + foreign_creator.clone(), xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ); assert_ok!(outcome.ensure_complete()); @@ -1230,25 +1238,25 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor use frame_support::traits::fungibles::roles::Inspect as InspectRoles; assert_eq!( >::owner( - asset_id.into() + asset_id.clone().into() ), Some(foreign_creator_as_account_id.clone()) ); assert_eq!( >::admin( - asset_id.into() + asset_id.clone().into() ), Some(foreign_creator_as_account_id.clone()) ); assert_eq!( >::issuer( - asset_id.into() + asset_id.clone().into() ), Some(foreign_creator_as_account_id.clone()) ); assert_eq!( >::freezer( - asset_id.into() + asset_id.clone().into() ), Some(bob_account.clone()) ); @@ -1262,13 +1270,13 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor assert_metadata::< pallet_assets::Pallet, AccountIdOf, - >(asset_id, ASSET_NAME, ASSET_SYMBOL, 12); + >(asset_id.clone(), ASSET_NAME, ASSET_SYMBOL, 12); // check if changed freezer, can freeze assert_noop!( >::freeze( RuntimeHelper::::origin_of(bob_account), - asset_id.into(), + asset_id.clone().into(), alice_account.clone().into() ), pallet_assets::Error::::NoAccount @@ -1284,9 +1292,9 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor // lets try create asset for different parachain(3333) (foreign_creator(2222) can create // just his assets) - let foreign_asset_id_multilocation = - MultiLocation { parents: 1, interior: X2(Parachain(3333), GeneralIndex(1234567)) }; - let asset_id = AssetIdConverter::convert(&foreign_asset_id_multilocation).unwrap(); + let foreign_asset_id_location = + Location { parents: 1, interior: [Parachain(3333), GeneralIndex(1234567)].into() }; + let asset_id = AssetIdConverter::convert(&foreign_asset_id_location).unwrap(); // prepare data for xcm::Transact(create) let foreign_asset_create = runtime_call_encode(pallet_assets::Call::< @@ -1310,14 +1318,15 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor ]); // messages with different consensus should go through the local bridge-hub - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); // execute xcm as XcmpQueue would do - let outcome = XcmExecutor::::execute_xcm( + let outcome = XcmExecutor::::prepare_and_execute( foreign_creator, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ); assert_ok!(outcome.ensure_complete()); @@ -1441,15 +1450,15 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works< // reserve-transfer native asset with local reserve to remote parachain (2345) let other_para_id = 2345; - let native_asset = MultiLocation::parent(); - let dest = MultiLocation::new(1, X1(Parachain(other_para_id))); - let mut dest_beneficiary = MultiLocation::new(1, X1(Parachain(other_para_id))) + let native_asset = Location::parent(); + let dest = Location::new(1, [Parachain(other_para_id)]); + let mut dest_beneficiary = Location::new(1, [Parachain(other_para_id)]) .appended_with(AccountId32 { network: None, id: sp_runtime::AccountId32::new([3; 32]).into(), }) .unwrap(); - dest_beneficiary.reanchor(&dest, XcmConfig::UniversalLocation::get()).unwrap(); + dest_beneficiary.reanchor(&dest, &XcmConfig::UniversalLocation::get()).unwrap(); let reserve_account = LocationToAccountId::convert_location(&dest) .expect("Sovereign account for reserves"); @@ -1495,17 +1504,15 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works< ); // local native asset (pallet_balances) - let asset_to_transfer = MultiAsset { - fun: Fungible(balance_to_transfer.into()), - id: Concrete(native_asset), - }; + let asset_to_transfer = + Asset { fun: Fungible(balance_to_transfer.into()), id: AssetId(native_asset) }; // pallet_xcm call reserve transfer assert_ok!(>::limited_reserve_transfer_assets( RuntimeHelper::::origin_of(alice_account.clone()), - Box::new(dest.into_versioned()), - Box::new(dest_beneficiary.into_versioned()), - Box::new(VersionedMultiAssets::from(MultiAssets::from(asset_to_transfer))), + Box::new(dest.clone().into_versioned()), + Box::new(dest_beneficiary.clone().into_versioned()), + Box::new(VersionedAssets::from(Assets::from(asset_to_transfer))), 0, weight_limit, )); @@ -1535,9 +1542,12 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works< ) .unwrap(); + let v4_xcm: Xcm<()> = xcm_sent.clone().try_into().unwrap(); + dbg!(&v4_xcm); + let delivery_fees = get_fungible_delivery_fees::< ::XcmSender, - >(dest, Xcm::try_from(xcm_sent.clone()).unwrap()); + >(dest.clone(), Xcm::try_from(xcm_sent.clone()).unwrap()); assert_eq!( xcm_sent_message_hash, @@ -1547,8 +1557,8 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works< // check sent XCM Program to other parachain println!("reserve_transfer_native_asset_works sent xcm: {:?}", xcm_sent); - let reserve_assets_deposited = MultiAssets::from(vec![MultiAsset { - id: Concrete(MultiLocation { parents: 1, interior: Here }), + let reserve_assets_deposited = Assets::from(vec![Asset { + id: AssetId(Location { parents: 1, interior: Here }), fun: Fungible(1000000000000), }]); diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs index d7441880426..878dddc9137 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs @@ -31,15 +31,15 @@ use parachains_runtimes_test_utils::{ }; use sp_runtime::{traits::StaticLookup, Saturating}; use sp_std::ops::Mul; -use xcm::{latest::prelude::*, VersionedMultiAssets}; +use xcm::{latest::prelude::*, VersionedAssets}; use xcm_builder::{CreateMatcher, MatchXcm}; use xcm_executor::{traits::ConvertLocation, XcmExecutor}; pub struct TestBridgingConfig { pub bridged_network: NetworkId, pub local_bridge_hub_para_id: u32, - pub local_bridge_hub_location: MultiLocation, - pub bridged_target_location: MultiLocation, + pub local_bridge_hub_location: Location, + pub bridged_target_location: Location, } /// Test-case makes sure that `Runtime` can initiate **reserve transfer assets** over bridge. @@ -117,7 +117,7 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works< LocationToAccountId::convert_location(&target_location_from_different_consensus) .expect("Sovereign account for reserves"); let balance_to_transfer = 1_000_000_000_000_u128; - let native_asset = MultiLocation::parent(); + let native_asset = Location::parent(); // open HRMP to bridge hub mock_open_hrmp_channel::( @@ -163,35 +163,33 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works< .unwrap_or(0.into()); // local native asset (pallet_balances) - let asset_to_transfer = MultiAsset { - fun: Fungible(balance_to_transfer.into()), - id: Concrete(native_asset), - }; + let asset_to_transfer = + Asset { fun: Fungible(balance_to_transfer.into()), id: native_asset.into() }; // destination is (some) account relative to the destination different consensus - let target_destination_account = MultiLocation { - parents: 0, - interior: X1(AccountId32 { + let target_destination_account = Location::new( + 0, + [AccountId32 { network: Some(bridged_network), id: sp_runtime::AccountId32::new([3; 32]).into(), - }), - }; + }], + ); - let assets_to_transfer = MultiAssets::from(asset_to_transfer); + let assets_to_transfer = Assets::from(asset_to_transfer); let mut expected_assets = assets_to_transfer.clone(); let context = XcmConfig::UniversalLocation::get(); expected_assets - .reanchor(&target_location_from_different_consensus, context) + .reanchor(&target_location_from_different_consensus, &context) .unwrap(); - let expected_beneficiary = target_destination_account; + let expected_beneficiary = target_destination_account.clone(); // do pallet_xcm call reserve transfer assert_ok!(>::limited_reserve_transfer_assets( RuntimeHelper::::origin_of(alice_account.clone()), - Box::new(target_location_from_different_consensus.into_versioned()), + Box::new(target_location_from_different_consensus.clone().into_versioned()), Box::new(target_destination_account.into_versioned()), - Box::new(VersionedMultiAssets::from(assets_to_transfer)), + Box::new(VersionedAssets::from(assets_to_transfer)), 0, weight_limit, )); @@ -266,13 +264,17 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works< let (_, target_location_junctions_without_global_consensus) = target_location_from_different_consensus .interior + .clone() .split_global() .expect("split works"); assert_eq!(destination, &target_location_junctions_without_global_consensus); // Call `SendXcm::validate` to get delivery fees. delivery_fees = get_fungible_delivery_fees::< ::XcmSender, - >(target_location_from_different_consensus, inner_xcm.clone()); + >( + target_location_from_different_consensus.clone(), + inner_xcm.clone(), + ); assert_matches_reserve_asset_deposited_instructions( inner_xcm, &expected_assets, @@ -322,10 +324,10 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< target_account: AccountIdOf, block_author_account: AccountIdOf, ( - foreign_asset_id_multilocation, + foreign_asset_id_location, transfered_foreign_asset_id_amount, foreign_asset_id_minimum_balance, - ): (MultiLocation, u128, u128), + ): (xcm::v3::Location, u128, u128), prepare_configuration: fn() -> TestBridgingConfig, (bridge_instance, universal_origin, descend_origin): (Junctions, Junction, Junctions), /* bridge adds origin manipulation on the way */ ) where @@ -347,9 +349,9 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< XcmConfig: xcm_executor::Config, LocationToAccountId: ConvertLocation>, >::AssetId: - From + Into, + From + Into, >::AssetIdParameter: - From + Into, + From + Into, >::Balance: From + Into + From, ::AccountId: Into<<::RuntimeOrigin as OriginTrait>::AccountId> @@ -357,7 +359,7 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< <::Lookup as StaticLookup>::Source: From<::AccountId>, ::AssetKind: - From + Into, + From + Into, ::Balance: From, ForeignAssetsPalletInstance: 'static, { @@ -385,7 +387,7 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< // sovereign account as foreign asset owner (can be whoever for this scenario, doesnt // matter) let sovereign_account_as_owner_of_foreign_asset = - LocationToAccountId::convert_location(&MultiLocation::parent()).unwrap(); + LocationToAccountId::convert_location(&Location::parent()).unwrap(); // staking pot account for collecting local native fees from `BuyExecution` let staking_pot = >::account_id(); @@ -398,16 +400,16 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< assert_ok!( >::force_create( RuntimeHelper::::root_origin(), - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), sovereign_account_as_owner_of_foreign_asset.clone().into(), true, // is_sufficient=true foreign_asset_id_minimum_balance.into() ) ); - // setup a pool to pay fees with `foreign_asset_id_multilocation` tokens + // setup a pool to pay fees with `foreign_asset_id_location` tokens let pool_owner: AccountIdOf = [1u8; 32].into(); - let native_asset = MultiLocation::parent(); + let native_asset = xcm::v3::Location::parent(); let pool_liquidity: u128 = existential_deposit.into().max(foreign_asset_id_minimum_balance).mul(100_000); @@ -420,7 +422,7 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< RuntimeHelper::::origin_of( sovereign_account_as_owner_of_foreign_asset ), - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), pool_owner.clone().into(), (foreign_asset_id_minimum_balance + pool_liquidity).mul(2).into(), )); @@ -428,13 +430,13 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< assert_ok!(>::create_pool( RuntimeHelper::::origin_of(pool_owner.clone()), Box::new(native_asset.into()), - Box::new(foreign_asset_id_multilocation.into()) + Box::new(foreign_asset_id_location.into()) )); assert_ok!(>::add_liquidity( RuntimeHelper::::origin_of(pool_owner.clone()), Box::new(native_asset.into()), - Box::new(foreign_asset_id_multilocation.into()), + Box::new(foreign_asset_id_location.into()), pool_liquidity.into(), pool_liquidity.into(), 1.into(), @@ -459,34 +461,37 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< // ForeignAssets balances before assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &target_account ), 0.into() ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &block_author_account ), 0.into() ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &staking_pot ), 0.into() ); - let expected_assets = MultiAssets::from(vec![MultiAsset { - id: Concrete(foreign_asset_id_multilocation), + let foreign_asset_id_location_latest: Location = + foreign_asset_id_location.try_into().unwrap(); + + let expected_assets = Assets::from(vec![Asset { + id: AssetId(foreign_asset_id_location_latest.clone()), fun: Fungible(transfered_foreign_asset_id_amount), }]); - let expected_beneficiary = MultiLocation { - parents: 0, - interior: X1(AccountId32 { network: None, id: target_account.clone().into() }), - }; + let expected_beneficiary = Location::new( + 0, + [AccountId32 { network: None, id: target_account.clone().into() }], + ); // Call received XCM execution let xcm = Xcm(vec![ @@ -496,13 +501,16 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< ReserveAssetDeposited(expected_assets.clone()), ClearOrigin, BuyExecution { - fees: MultiAsset { - id: Concrete(foreign_asset_id_multilocation), + fees: Asset { + id: AssetId(foreign_asset_id_location_latest.clone()), fun: Fungible(transfered_foreign_asset_id_amount), }, weight_limit: Unlimited, }, - DepositAsset { assets: Wild(AllCounted(1)), beneficiary: expected_beneficiary }, + DepositAsset { + assets: Wild(AllCounted(1)), + beneficiary: expected_beneficiary.clone(), + }, SetTopic([ 220, 188, 144, 32, 213, 83, 111, 175, 44, 210, 111, 19, 90, 165, 191, 112, 140, 247, 192, 124, 42, 17, 153, 141, 114, 34, 189, 20, 83, 69, 237, 173, @@ -514,16 +522,17 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< &expected_beneficiary, ); - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); // execute xcm as XcmpQueue would do - let outcome = XcmExecutor::::execute_xcm( + let outcome = XcmExecutor::::prepare_and_execute( local_bridge_hub_location, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight( XcmReceivedFrom::Sibling, ), + Weight::zero(), ); assert_ok!(outcome.ensure_complete()); @@ -545,20 +554,20 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< // ForeignAssets balances after assert!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &target_account ) > 0.into() ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &staking_pot ), 0.into() ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &block_author_account ), 0.into() @@ -614,14 +623,15 @@ pub fn report_bridge_status_from_xcm_bridge_router_works< // Call received XCM execution let xcm = if is_congested { congested_message() } else { uncongested_message() }; - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); // execute xcm as XcmpQueue would do - let outcome = XcmExecutor::::execute_xcm( + let outcome = XcmExecutor::::prepare_and_execute( local_bridge_hub_location, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ); assert_ok!(outcome.ensure_complete()); assert_eq!(is_congested, pallet_xcm_bridge_hub_router::Pallet::::bridge().is_congested); diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/xcm_helpers.rs b/cumulus/parachains/runtimes/assets/test-utils/src/xcm_helpers.rs index 0aebe38fef5..f509a3a8aca 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/xcm_helpers.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/xcm_helpers.rs @@ -23,11 +23,11 @@ use xcm::latest::prelude::*; /// Because it returns only a `u128`, it assumes delivery fees are only paid /// in one asset and that asset is known. pub fn transfer_assets_delivery_fees( - assets: MultiAssets, + assets: Assets, fee_asset_item: u32, weight_limit: WeightLimit, - beneficiary: MultiLocation, - destination: MultiLocation, + beneficiary: Location, + destination: Location, ) -> u128 { let message = teleport_assets_dummy_message(assets, fee_asset_item, weight_limit, beneficiary); get_fungible_delivery_fees::(destination, message) @@ -35,7 +35,7 @@ pub fn transfer_assets_delivery_fees( /// Returns the delivery fees amount for a query response as a result of the execution /// of a `ExpectError` instruction with no error. -pub fn query_response_delivery_fees(querier: MultiLocation) -> u128 { +pub fn query_response_delivery_fees(querier: Location) -> u128 { // Message to calculate delivery fees, it's encoded size is what's important. // This message reports that there was no error, if an error is reported, the encoded size would // be different. @@ -45,7 +45,7 @@ pub fn query_response_delivery_fees(querier: MultiLocation) -> u128 query_id: 0, // Dummy query id response: Response::ExecutionResult(None), max_weight: Weight::zero(), - querier: Some(querier), + querier: Some(querier.clone()), }, SetTopic([0u8; 32]), // Dummy topic ]); @@ -55,9 +55,9 @@ pub fn query_response_delivery_fees(querier: MultiLocation) -> u128 /// Returns the delivery fees amount for the execution of `PayOverXcm` pub fn pay_over_xcm_delivery_fees( interior: Junctions, - destination: MultiLocation, - beneficiary: MultiLocation, - asset: MultiAsset, + destination: Location, + beneficiary: Location, + asset: Asset, ) -> u128 { // This is a dummy message. // The encoded size is all that matters for delivery fees. @@ -66,7 +66,11 @@ pub fn pay_over_xcm_delivery_fees( UnpaidExecution { weight_limit: Unlimited, check_origin: None }, SetAppendix(Xcm(vec![ SetFeesMode { jit_withdraw: true }, - ReportError(QueryResponseInfo { destination, query_id: 0, max_weight: Weight::zero() }), + ReportError(QueryResponseInfo { + destination: destination.clone(), + query_id: 0, + max_weight: Weight::zero(), + }), ])), TransferAsset { beneficiary, assets: vec![asset].into() }, ]); @@ -78,10 +82,10 @@ pub fn pay_over_xcm_delivery_fees( /// However, it should have the same encoded size, which is what matters for delivery fees. /// Also has same encoded size as the one created by the reserve transfer assets extrinsic. fn teleport_assets_dummy_message( - assets: MultiAssets, + assets: Assets, fee_asset_item: u32, weight_limit: WeightLimit, - beneficiary: MultiLocation, + beneficiary: Location, ) -> Xcm<()> { Xcm(vec![ ReceiveTeleportedAsset(assets.clone()), // Same encoded size as `ReserveAssetDeposited` @@ -93,7 +97,7 @@ fn teleport_assets_dummy_message( } /// Given a message, a sender, and a destination, it returns the delivery fees -fn get_fungible_delivery_fees(destination: MultiLocation, message: Xcm<()>) -> u128 { +fn get_fungible_delivery_fees(destination: Location, message: Xcm<()>) -> u128 { let Ok((_, delivery_fees)) = validate_send::(destination, message) else { unreachable!("message can be sent; qed") }; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs index c9d7f60e71a..1c7bdd4cbff 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs @@ -48,7 +48,7 @@ use frame_support::{parameter_types, traits::PalletInfoAccess}; use sp_runtime::RuntimeDebug; use xcm::{ latest::prelude::*, - prelude::{InteriorMultiLocation, NetworkId}, + prelude::{InteriorLocation, NetworkId}, }; use xcm_builder::BridgeBlobDispatcher; @@ -65,16 +65,16 @@ parameter_types! { /// Bridge specific chain (network) identifier of the Rococo Bulletin Chain. pub const RococoBulletinChainId: bp_runtime::ChainId = bp_runtime::POLKADOT_BULLETIN_CHAIN_ID; /// Interior location (relative to this runtime) of the with-RococoBulletin messages pallet. - pub BridgeRococoToRococoBulletinMessagesPalletInstance: InteriorMultiLocation = X1( + pub BridgeRococoToRococoBulletinMessagesPalletInstance: InteriorLocation = [ PalletInstance(::index() as u8) - ); + ].into(); /// Rococo Bulletin Network identifier. pub RococoBulletinGlobalConsensusNetwork: NetworkId = NetworkId::PolkadotBulletin; /// Relative location of the Rococo Bulletin chain. - pub RococoBulletinGlobalConsensusNetworkLocation: MultiLocation = MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(RococoBulletinGlobalConsensusNetwork::get())) - }; + pub RococoBulletinGlobalConsensusNetworkLocation: Location = Location::new( + 2, + [GlobalConsensus(RococoBulletinGlobalConsensusNetwork::get())] + ); /// All active lanes that the current bridge supports. pub ActiveOutboundLanesToRococoBulletin: &'static [bp_messages::LaneId] = &[XCM_LANE_FOR_ROCOCO_PEOPLE_TO_ROCOCO_BULLETIN]; @@ -94,11 +94,11 @@ parameter_types! { /// A route (XCM location and bridge lane) that the Rococo People Chain -> Rococo Bulletin Chain /// message is following. pub FromRococoPeopleToRococoBulletinRoute: SenderAndLane = SenderAndLane::new( - ParentThen(X1(Parachain(RococoPeopleParaId::get().into()))).into(), + ParentThen(Parachain(RococoPeopleParaId::get().into()).into()).into(), XCM_LANE_FOR_ROCOCO_PEOPLE_TO_ROCOCO_BULLETIN, ); /// All active routes and their destinations. - pub ActiveLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorMultiLocation))> = sp_std::vec![ + pub ActiveLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorLocation))> = sp_std::vec![ ( FromRococoPeopleToRococoBulletinRoute::get(), (RococoBulletinGlobalConsensusNetwork::get(), Here) @@ -282,11 +282,11 @@ mod tests { PriorityBoostPerMessage, >(FEE_BOOST_PER_MESSAGE); - assert_eq!( - BridgeRococoToRococoBulletinMessagesPalletInstance::get(), - X1(PalletInstance( - bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_BULLETIN_MESSAGES_PALLET_INDEX - )) - ); + let expected: InteriorLocation = PalletInstance( + bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_BULLETIN_MESSAGES_PALLET_INDEX, + ) + .into(); + + assert_eq!(BridgeRococoToRococoBulletinMessagesPalletInstance::get(), expected,); } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 961b47e1e13..4e8fe6454cc 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -48,7 +48,7 @@ use frame_support::{parameter_types, traits::PalletInfoAccess}; use sp_runtime::RuntimeDebug; use xcm::{ latest::prelude::*, - prelude::{InteriorMultiLocation, NetworkId}, + prelude::{InteriorLocation, NetworkId}, }; use xcm_builder::BridgeBlobDispatcher; @@ -58,12 +58,12 @@ parameter_types! { pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = bp_bridge_hub_rococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; pub const BridgeHubWestendChainId: bp_runtime::ChainId = bp_runtime::BRIDGE_HUB_WESTEND_CHAIN_ID; - pub BridgeRococoToWestendMessagesPalletInstance: InteriorMultiLocation = X1(PalletInstance(::index() as u8)); + pub BridgeRococoToWestendMessagesPalletInstance: InteriorLocation = [PalletInstance(::index() as u8)].into(); pub WestendGlobalConsensusNetwork: NetworkId = NetworkId::Westend; - pub WestendGlobalConsensusNetworkLocation: MultiLocation = MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(WestendGlobalConsensusNetwork::get())) - }; + pub WestendGlobalConsensusNetworkLocation: Location = Location::new( + 2, + [GlobalConsensus(WestendGlobalConsensusNetwork::get())] + ); // see the `FEE_BOOST_PER_MESSAGE` constant to get the meaning of this value pub PriorityBoostPerMessage: u64 = 182_044_444_444_444; @@ -74,26 +74,26 @@ parameter_types! { pub ActiveOutboundLanesToBridgeHubWestend: &'static [bp_messages::LaneId] = &[XCM_LANE_FOR_ASSET_HUB_ROCOCO_TO_ASSET_HUB_WESTEND]; pub const AssetHubRococoToAssetHubWestendMessagesLane: bp_messages::LaneId = XCM_LANE_FOR_ASSET_HUB_ROCOCO_TO_ASSET_HUB_WESTEND; pub FromAssetHubRococoToAssetHubWestendRoute: SenderAndLane = SenderAndLane::new( - ParentThen(X1(Parachain(AssetHubRococoParaId::get().into()))).into(), + ParentThen([Parachain(AssetHubRococoParaId::get().into())].into()).into(), XCM_LANE_FOR_ASSET_HUB_ROCOCO_TO_ASSET_HUB_WESTEND, ); - pub ActiveLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorMultiLocation))> = sp_std::vec![ + pub ActiveLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorLocation))> = sp_std::vec![ ( FromAssetHubRococoToAssetHubWestendRoute::get(), - (WestendGlobalConsensusNetwork::get(), X1(Parachain(AssetHubWestendParaId::get().into()))) + (WestendGlobalConsensusNetwork::get(), [Parachain(AssetHubWestendParaId::get().into())].into()) ) ]; pub CongestedMessage: Xcm<()> = build_congestion_message(true).into(); pub UncongestedMessage: Xcm<()> = build_congestion_message(false).into(); - pub BridgeHubWestendLocation: MultiLocation = MultiLocation { - parents: 2, - interior: X2( + pub BridgeHubWestendLocation: Location = Location::new( + 2, + [ GlobalConsensus(WestendGlobalConsensusNetwork::get()), Parachain(::PARACHAIN_ID) - ) - }; + ] + ); } pub const XCM_LANE_FOR_ASSET_HUB_ROCOCO_TO_ASSET_HUB_WESTEND: LaneId = LaneId([0, 0, 0, 2]); @@ -327,11 +327,11 @@ mod tests { PriorityBoostPerMessage, >(FEE_BOOST_PER_MESSAGE); - assert_eq!( - BridgeRococoToWestendMessagesPalletInstance::get(), - X1(PalletInstance( - bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_WESTEND_MESSAGES_PALLET_INDEX - )) - ); + let expected: InteriorLocation = [PalletInstance( + bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_WESTEND_MESSAGES_PALLET_INDEX, + )] + .into(); + + assert_eq!(BridgeRococoToWestendMessagesPalletInstance::get(), expected,); } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 0052e9dcb38..7e99b039309 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -78,7 +78,7 @@ use bridge_hub_common::{ use pallet_xcm::EnsureXcm; pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; pub use sp_runtime::{MultiAddress, Perbill, Permill}; -use xcm::VersionedMultiLocation; +use xcm::VersionedLocation; use xcm_config::{TreasuryAccount, XcmOriginToTransactDispatchOrigin, XcmRouter}; #[cfg(any(feature = "std", test))] @@ -385,7 +385,7 @@ impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(xcm_config::TokenLocation::get()); + pub FeeAssetId: AssetId = AssetId(xcm_config::TokenLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -517,7 +517,7 @@ pub mod benchmark_helpers { use snowbridge_beacon_primitives::CompactExecutionHeader; use snowbridge_pallet_inbound_queue::BenchmarkHelper; use sp_core::H256; - use xcm::latest::{MultiAssets, MultiLocation, SendError, SendResult, SendXcm, Xcm, XcmHash}; + use xcm::latest::{Assets, Location, SendError, SendResult, SendXcm, Xcm, XcmHash}; impl BenchmarkHelper for Runtime { fn initialize_storage(block_hash: H256, header: CompactExecutionHeader) { @@ -530,10 +530,10 @@ pub mod benchmark_helpers { type Ticket = Xcm<()>; fn validate( - _dest: &mut Option, + _dest: &mut Option, xcm: &mut Option>, ) -> SendResult { - Ok((xcm.clone().unwrap(), MultiAssets::new())) + Ok((xcm.clone().unwrap(), Assets::new())) } fn deliver(xcm: Xcm<()>) -> Result { let hash = xcm.using_encoded(sp_io::hashing::blake2_256); @@ -542,7 +542,7 @@ pub mod benchmark_helpers { } impl snowbridge_pallet_system::BenchmarkHelper for () { - fn make_xcm_origin(location: MultiLocation) -> RuntimeOrigin { + fn make_xcm_origin(location: Location) -> RuntimeOrigin { RuntimeOrigin::from(pallet_xcm::Origin::Xcm(location)) } } @@ -1016,7 +1016,7 @@ impl_runtime_apis! { } impl snowbridge_system_runtime_api::ControlApi for Runtime { - fn agent_id(location: VersionedMultiLocation) -> Option { + fn agent_id(location: VersionedLocation) -> Option { snowbridge_pallet_system::api::agent_id::(location) } } @@ -1095,28 +1095,28 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between BH and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Reserve transfers are disabled on BH. None } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(Assets, u32, Location, Box)> { // BH only supports teleports to system parachain. // Relay/native token can be teleported between BH and Relay. let native_location = Parent.into(); @@ -1132,7 +1132,7 @@ impl_runtime_apis! { use xcm_config::TokenLocation; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( TokenLocation::get(), ExistentialDeposit::get() ).into()); @@ -1143,17 +1143,17 @@ impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationToAccountId; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForParentDelivery, >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(TokenLocation::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // just concrete assets according to relay chain. - let assets: Vec = vec![ - MultiAsset { - id: Concrete(TokenLocation::get()), + let assets: Vec = vec![ + Asset { + id: AssetId(TokenLocation::get()), fun: Fungible(1_000_000 * UNITS), } ]; @@ -1162,12 +1162,12 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( TokenLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(TokenLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(TokenLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -1177,9 +1177,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(TokenLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(TokenLocation::get()), fun: Fungible(UNITS), } } @@ -1193,35 +1193,35 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((TokenLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(TokenLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = TokenLocation::get(); - let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(TokenLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { // save XCM version for remote bridge hub let _ = PolkadotXcm::force_xcm_version( RuntimeOrigin::root(), @@ -1241,12 +1241,12 @@ impl_runtime_apis! { ( bridge_to_westend_config::FromAssetHubRococoToAssetHubWestendRoute::get().location, NetworkId::Westend, - X1(Parachain(bridge_to_westend_config::AssetHubWestendParaId::get().into())) + [Parachain(bridge_to_westend_config::AssetHubWestendParaId::get().into())].into() ) ) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } @@ -1296,7 +1296,7 @@ impl_runtime_apis! { Runtime, bridge_common_config::BridgeGrandpaWestendInstance, bridge_to_westend_config::WithBridgeHubWestendMessageBridge, - >(params, generate_xcm_builder_bridge_message_sample(X2(GlobalConsensus(Rococo), Parachain(42)))) + >(params, generate_xcm_builder_bridge_message_sample([GlobalConsensus(Rococo), Parachain(42)].into())) } fn prepare_message_delivery_proof( @@ -1331,7 +1331,7 @@ impl_runtime_apis! { Runtime, bridge_common_config::BridgeGrandpaRococoBulletinInstance, bridge_to_bulletin_config::WithRococoBulletinMessageBridge, - >(params, generate_xcm_builder_bridge_message_sample(X2(GlobalConsensus(Rococo), Parachain(42)))) + >(params, generate_xcm_builder_bridge_message_sample([GlobalConsensus(Rococo), Parachain(42)].into())) } fn prepare_message_delivery_proof( diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs index 1c2334a89e2..4f5bae0fe59 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs @@ -24,14 +24,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -50,40 +50,36 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct BridgeHubRococoXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for BridgeHubRococoXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -111,44 +107,36 @@ impl XcmWeightInfo for BridgeHubRococoXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -163,7 +151,7 @@ impl XcmWeightInfo for BridgeHubRococoXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -175,13 +163,13 @@ impl XcmWeightInfo for BridgeHubRococoXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -215,16 +203,16 @@ impl XcmWeightInfo for BridgeHubRococoXcmWeight { let inner_encoded_len = inner.encode().len() as u32; XcmGeneric::::export_message(inner_encoded_len) } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -236,11 +224,11 @@ impl XcmWeightInfo for BridgeHubRococoXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs index dc98622cafc..f641b428d4c 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs @@ -32,7 +32,7 @@ use bp_messages::LaneId; use bp_relayers::{PayRewardFromAccount, RewardsAccountOwner, RewardsAccountParams}; use bp_runtime::ChainId; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; @@ -69,19 +69,19 @@ use xcm_executor::{ }; parameter_types! { - pub const TokenLocation: MultiLocation = MultiLocation::parent(); + pub const TokenLocation: Location = Location::parent(); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); pub RelayNetwork: NetworkId = NetworkId::Rococo; - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())].into(); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); - pub SiblingPeople: MultiLocation = (Parent, Parachain(rococo_runtime_constants::system_parachain::PEOPLE_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); + pub SiblingPeople: Location = (Parent, Parachain(rococo_runtime_constants::system_parachain::PEOPLE_ID)).into(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -100,7 +100,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -132,11 +132,11 @@ pub type XcmOriginToTransactDispatchOrigin = ( XcmPassthrough, ); -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -331,7 +331,7 @@ impl xcm_executor::Config for XcmConfig { pub type PriceForParentDelivery = ExponentialPrice; -/// Converts a local signed origin into an XCM multilocation. +/// Converts a local signed origin into an XCM location. /// Forms the basis for local origins sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; @@ -407,14 +407,10 @@ impl< BridgeLaneId, > { - fn handle_fee( - fee: MultiAssets, - maybe_context: Option<&XcmContext>, - reason: FeeReason, - ) -> MultiAssets { + fn handle_fee(fee: Assets, maybe_context: Option<&XcmContext>, reason: FeeReason) -> Assets { if matches!(reason, FeeReason::Export { network: bridged_network, destination } if bridged_network == DestNetwork::get() && - destination == X1(Parachain(DestParaId::get().into()))) + destination == [Parachain(DestParaId::get().into())]) { // We have 2 relayer rewards accounts: // - the SA of the source parachain on this BH: this pays the relayers for delivering @@ -445,14 +441,14 @@ impl< Fungible(total_fee) => { let source_fee = total_fee / 2; deposit_or_burn_fee::( - MultiAsset { id: asset.id, fun: Fungible(source_fee) }.into(), + Asset { id: asset.id.clone(), fun: Fungible(source_fee) }.into(), maybe_context, source_para_account.clone(), ); let dest_fee = total_fee - source_fee; deposit_or_burn_fee::( - MultiAsset { id: asset.id, fun: Fungible(dest_fee) }.into(), + Asset { id: asset.id, fun: Fungible(dest_fee) }.into(), maybe_context, dest_para_account.clone(), ); @@ -467,7 +463,7 @@ impl< } } - return MultiAssets::new() + return Assets::new() } fee @@ -477,10 +473,10 @@ impl< pub struct XcmFeeManagerFromComponentsBridgeHub( PhantomData<(WaivedLocations, HandleFee)>, ); -impl, FeeHandler: HandleFee> FeeManager +impl, FeeHandler: HandleFee> FeeManager for XcmFeeManagerFromComponentsBridgeHub { - fn is_waived(origin: Option<&MultiLocation>, fee_reason: FeeReason) -> bool { + fn is_waived(origin: Option<&Location>, fee_reason: FeeReason) -> bool { let Some(loc) = origin else { return false }; if let Export { network, destination: Here } = fee_reason { return !(network == EthereumNetwork::get()) @@ -488,7 +484,7 @@ impl, FeeHandler: HandleFee> FeeManager WaivedLocations::contains(loc) } - fn handle_fee(fee: MultiAssets, context: Option<&XcmContext>, reason: FeeReason) { + fn handle_fee(fee: Assets, context: Option<&XcmContext>, reason: FeeReason) { FeeHandler::handle_fee(fee, context, reason); } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs index 0fba28c47b4..63e64506ec7 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs @@ -241,7 +241,7 @@ mod bridge_hub_westend_tests { _ => None, } }), - || ExportMessage { network: Westend, destination: X1(Parachain(bridge_to_westend_config::AssetHubWestendParaId::get().into())), xcm: Xcm(vec![]) }, + || ExportMessage { network: Westend, destination: [Parachain(bridge_to_westend_config::AssetHubWestendParaId::get().into())].into(), xcm: Xcm(vec![]) }, XCM_LANE_FOR_ASSET_HUB_ROCOCO_TO_ASSET_HUB_WESTEND, Some((TokenLocation::get(), ExistentialDeposit::get()).into()), // value should be >= than value generated by `can_calculate_weight_for_paid_export_message_with_reserve_transfer` diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index eb5493872b4..716e01b85b4 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -47,7 +47,7 @@ use frame_support::{ use sp_runtime::RuntimeDebug; use xcm::{ latest::prelude::*, - prelude::{InteriorMultiLocation, NetworkId}, + prelude::{InteriorLocation, NetworkId}, }; use xcm_builder::BridgeBlobDispatcher; @@ -63,12 +63,12 @@ parameter_types! { pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = bp_bridge_hub_westend::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; pub const BridgeHubRococoChainId: bp_runtime::ChainId = bp_runtime::BRIDGE_HUB_ROCOCO_CHAIN_ID; - pub BridgeWestendToRococoMessagesPalletInstance: InteriorMultiLocation = X1(PalletInstance(::index() as u8)); + pub BridgeWestendToRococoMessagesPalletInstance: InteriorLocation = [PalletInstance(::index() as u8)].into(); pub RococoGlobalConsensusNetwork: NetworkId = NetworkId::Rococo; - pub RococoGlobalConsensusNetworkLocation: MultiLocation = MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(RococoGlobalConsensusNetwork::get())) - }; + pub RococoGlobalConsensusNetworkLocation: Location = Location::new( + 2, + [GlobalConsensus(RococoGlobalConsensusNetwork::get())] + ); // see the `FEE_BOOST_PER_MESSAGE` constant to get the meaning of this value pub PriorityBoostPerMessage: u64 = 182_044_444_444_444; @@ -79,26 +79,26 @@ parameter_types! { pub ActiveOutboundLanesToBridgeHubRococo: &'static [bp_messages::LaneId] = &[XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO]; pub const AssetHubWestendToAssetHubRococoMessagesLane: bp_messages::LaneId = XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO; pub FromAssetHubWestendToAssetHubRococoRoute: SenderAndLane = SenderAndLane::new( - ParentThen(X1(Parachain(AssetHubWestendParaId::get().into()))).into(), + ParentThen([Parachain(AssetHubWestendParaId::get().into())].into()).into(), XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO, ); - pub ActiveLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorMultiLocation))> = sp_std::vec![ + pub ActiveLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorLocation))> = sp_std::vec![ ( FromAssetHubWestendToAssetHubRococoRoute::get(), - (RococoGlobalConsensusNetwork::get(), X1(Parachain(AssetHubRococoParaId::get().into()))) + (RococoGlobalConsensusNetwork::get(), [Parachain(AssetHubRococoParaId::get().into())].into()) ) ]; pub CongestedMessage: Xcm<()> = build_congestion_message(true).into(); pub UncongestedMessage: Xcm<()> = build_congestion_message(false).into(); - pub BridgeHubRococoLocation: MultiLocation = MultiLocation { - parents: 2, - interior: X2( + pub BridgeHubRococoLocation: Location = Location::new( + 2, + [ GlobalConsensus(RococoGlobalConsensusNetwork::get()), Parachain(::PARACHAIN_ID) - ) - }; + ] + ); } pub const XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO: LaneId = LaneId([0, 0, 0, 2]); @@ -363,9 +363,9 @@ mod tests { assert_eq!( BridgeWestendToRococoMessagesPalletInstance::get(), - X1(PalletInstance( + [PalletInstance( bp_bridge_hub_westend::WITH_BRIDGE_WESTEND_TO_ROCOCO_MESSAGES_PALLET_INDEX - )) + )] ); } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 717cde6280d..d920f5a98cf 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -352,7 +352,7 @@ impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(xcm_config::WestendLocation::get()); + pub FeeAssetId: AssetId = AssetId(xcm_config::WestendLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -797,28 +797,28 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between BH and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Reserve transfers are disabled on BH. None } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(Assets, u32, Location, Box)> { // BH only supports teleports to system parachain. // Relay/native token can be teleported between BH and Relay. let native_location = Parent.into(); @@ -834,7 +834,7 @@ impl_runtime_apis! { use xcm_config::WestendLocation; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( WestendLocation::get(), ExistentialDeposit::get() ).into()); @@ -845,17 +845,17 @@ impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationToAccountId; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForParentDelivery, >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(WestendLocation::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { - // just concrete assets according to relay chain. - let assets: Vec = vec![ - MultiAsset { - id: Concrete(WestendLocation::get()), + fn worst_case_holding(_depositable_count: u32) -> Assets { + // just assets according to relay chain. + let assets: Vec = vec![ + Asset { + id: AssetId(WestendLocation::get()), fun: Fungible(1_000_000 * UNITS), } ]; @@ -864,12 +864,12 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( WestendLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(WestendLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(WestendLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -879,9 +879,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(WestendLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(WestendLocation::get()), fun: Fungible(UNITS), } } @@ -895,35 +895,35 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((WestendLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(WestendLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = WestendLocation::get(); - let assets: MultiAssets = (Concrete(WestendLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(WestendLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { // save XCM version for remote bridge hub let _ = PolkadotXcm::force_xcm_version( RuntimeOrigin::root(), @@ -943,12 +943,12 @@ impl_runtime_apis! { ( bridge_to_rococo_config::FromAssetHubWestendToAssetHubRococoRoute::get().location, NetworkId::Rococo, - X1(Parachain(bridge_to_rococo_config::AssetHubRococoParaId::get().into())) + [Parachain(bridge_to_rococo_config::AssetHubRococoParaId::get().into())].into() ) ) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } @@ -995,7 +995,7 @@ impl_runtime_apis! { Runtime, bridge_to_rococo_config::BridgeGrandpaRococoInstance, bridge_to_rococo_config::WithBridgeHubRococoMessageBridge, - >(params, generate_xcm_builder_bridge_message_sample(X2(GlobalConsensus(Westend), Parachain(42)))) + >(params, generate_xcm_builder_bridge_message_sample([GlobalConsensus(Westend), Parachain(42)].into())) } fn prepare_message_delivery_proof( diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs index 7269fa84f84..e8950678b40 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs @@ -25,14 +25,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -51,40 +51,36 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct BridgeHubWestendXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for BridgeHubWestendXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -112,44 +108,36 @@ impl XcmWeightInfo for BridgeHubWestendXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -164,7 +152,7 @@ impl XcmWeightInfo for BridgeHubWestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -176,13 +164,13 @@ impl XcmWeightInfo for BridgeHubWestendXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -216,16 +204,16 @@ impl XcmWeightInfo for BridgeHubWestendXcmWeight { let inner_encoded_len = inner.encode().len() as u32; XcmGeneric::::export_message(inner_encoded_len) } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -237,11 +225,11 @@ impl XcmWeightInfo for BridgeHubWestendXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs index 397019190f3..085608acf5d 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs @@ -21,7 +21,7 @@ use super::{ }; use crate::bridge_common_config::{DeliveryRewardInBalance, RequiredStakeForStakeAndSlash}; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; @@ -52,18 +52,18 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const WestendLocation: MultiLocation = MultiLocation::parent(); + pub const WestendLocation: Location = Location::parent(); pub const RelayNetwork: NetworkId = NetworkId::Westend; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())].into(); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -82,7 +82,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -114,11 +114,11 @@ pub type XcmOriginToTransactDispatchOrigin = ( XcmPassthrough, ); -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -270,7 +270,7 @@ impl xcm_executor::Config for XcmConfig { pub type PriceForParentDelivery = ExponentialPrice; -/// Converts a local signed origin into an XCM multilocation. +/// Converts a local signed origin into an XCM location. /// Forms the basis for local origins sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs index 0e58b7b408e..1237a231390 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs @@ -207,7 +207,7 @@ fn handle_export_message_from_system_parachain_add_to_outbound_queue_works() { _ => None, } }), - || ExportMessage { network: Rococo, destination: X1(Parachain(bridge_to_rococo_config::AssetHubRococoParaId::get().into())), xcm: Xcm(vec![]) }, + || ExportMessage { network: Rococo, destination: [Parachain(bridge_to_rococo_config::AssetHubRococoParaId::get().into())].into(), xcm: Xcm(vec![]) }, XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO, Some((WestendLocation::get(), ExistentialDeposit::get()).into()), // value should be >= than value generated by `can_calculate_weight_for_paid_export_message_with_reserve_transfer` diff --git a/cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs b/cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs index 3e821d45569..c1bba65b0ab 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs @@ -23,7 +23,7 @@ use pallet_message_queue::OnQueueChanged; use scale_info::TypeInfo; use snowbridge_core::ChannelId; use sp_std::{marker::PhantomData, prelude::*}; -use xcm::v3::{Junction, MultiLocation}; +use xcm::v4::{Junction, Location}; /// The aggregate origin of an inbound message. /// This is specialized for BridgeHub, as the snowbridge-outbound-queue-pallet is also using @@ -46,16 +46,16 @@ pub enum AggregateMessageOrigin { Snowbridge(ChannelId), } -impl From for MultiLocation { +impl From for Location { fn from(origin: AggregateMessageOrigin) -> Self { use AggregateMessageOrigin::*; match origin { - Here => MultiLocation::here(), - Parent => MultiLocation::parent(), - Sibling(id) => MultiLocation::new(1, Junction::Parachain(id.into())), + Here => Location::here(), + Parent => Location::parent(), + Sibling(id) => Location::new(1, Junction::Parachain(id.into())), // NOTE: We don't need this conversion for Snowbridge. However we have to // implement it anyway as xcm_builder::ProcessXcmMessage requires it. - Snowbridge(_) => MultiLocation::default(), + Snowbridge(_) => Location::default(), } } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs index e0e75f093cf..5eca85d3112 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs @@ -336,9 +336,9 @@ where (), >( LaneId::default(), - vec![xcm::v3::Instruction::<()>::ClearOrigin; 1_024].into(), + vec![Instruction::<()>::ClearOrigin; 1_024].into(), 1, - X2(GlobalConsensus(Polkadot), Parachain(1_000)), + [GlobalConsensus(Polkadot), Parachain(1_000)].into(), 1u32.into(), ); diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs index 91bebb36b18..6e638b7b350 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs @@ -418,9 +418,9 @@ where (), >( LaneId::default(), - vec![xcm::v3::Instruction::<()>::ClearOrigin; 1_024].into(), + vec![Instruction::<()>::ClearOrigin; 1_024].into(), 1, - X2(GlobalConsensus(Polkadot), Parachain(1_000)), + [GlobalConsensus(Polkadot), Parachain(1_000)].into(), 1, 5, 1_000, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs index 69aa61db3cc..ba58aeb046e 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs @@ -230,7 +230,7 @@ pub fn relayed_incoming_message_works( prepare_message_proof_import: impl FnOnce( Runtime::AccountId, Runtime::InboundRelayer, - InteriorMultiLocation, + InteriorLocation, MessageNonce, Xcm<()>, ) -> CallsAndVerifiers, @@ -276,21 +276,21 @@ pub fn relayed_incoming_message_works( // set up relayer details and proofs - let message_destination = - X2(GlobalConsensus(local_relay_chain_id), Parachain(sibling_parachain_id)); + let message_destination: InteriorLocation = + [GlobalConsensus(local_relay_chain_id), Parachain(sibling_parachain_id)].into(); // some random numbers (checked by test) let message_nonce = 1; - let xcm = vec![xcm::v3::Instruction::<()>::ClearOrigin; 42]; + let xcm = vec![Instruction::<()>::ClearOrigin; 42]; let expected_dispatch = xcm::latest::Xcm::<()>({ let mut expected_instructions = xcm.clone(); // dispatch prepends bridge pallet instance expected_instructions.insert( 0, - DescendOrigin(X1(PalletInstance( + DescendOrigin([PalletInstance( as PalletInfoAccess>::index() as u8, - ))), + )].into()), ); expected_instructions }); diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs index 64ec8726599..eb7ba132168 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs @@ -319,8 +319,8 @@ pub fn handle_export_message_from_system_parachain_to_outbound_queue_works< >, export_message_instruction: fn() -> Instruction, expected_lane_id: LaneId, - existential_deposit: Option, - maybe_paid_export_message: Option, + existential_deposit: Option, + maybe_paid_export_message: Option, prepare_configuration: impl Fn(), ) where Runtime: BasicParachainRuntime + BridgeMessagesConfig, @@ -328,7 +328,7 @@ pub fn handle_export_message_from_system_parachain_to_outbound_queue_works< MessagesPalletInstance: 'static, { assert_ne!(runtime_para_id, sibling_parachain_id); - let sibling_parachain_location = MultiLocation::new(1, Parachain(sibling_parachain_id)); + let sibling_parachain_location = Location::new(1, [Parachain(sibling_parachain_id)]); run_test::(collator_session_key, runtime_para_id, vec![], || { prepare_configuration(); @@ -361,7 +361,7 @@ pub fn handle_export_message_from_system_parachain_to_outbound_queue_works< .expect("deposited fee"); Xcm(vec![ - WithdrawAsset(MultiAssets::from(vec![fee.clone()])), + WithdrawAsset(Assets::from(vec![fee.clone()])), BuyExecution { fees: fee, weight_limit: Unlimited }, export_message_instruction(), ]) @@ -373,12 +373,13 @@ pub fn handle_export_message_from_system_parachain_to_outbound_queue_works< }; // execute XCM - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); - assert_ok!(XcmExecutor::::execute_xcm( + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); + assert_ok!(XcmExecutor::::prepare_and_execute( sibling_parachain_location, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ) .ensure_complete()); @@ -446,9 +447,9 @@ pub fn message_dispatch_routing_works< NetworkDistanceAsParentCount: Get, { struct NetworkWithParentCount(core::marker::PhantomData<(N, C)>); - impl, C: Get> Get for NetworkWithParentCount { - fn get() -> MultiLocation { - MultiLocation { parents: C::get(), interior: X1(GlobalConsensus(N::get())) } + impl, C: Get> Get for NetworkWithParentCount { + fn get() -> Location { + Location::new(C::get(), [GlobalConsensus(N::get())]) } } @@ -495,7 +496,7 @@ pub fn message_dispatch_routing_works< BridgedNetwork, NetworkWithParentCount, AlwaysLatest, - >((RuntimeNetwork::get(), X1(Parachain(sibling_parachain_id)))); + >((RuntimeNetwork::get(), [Parachain(sibling_parachain_id)].into())); // 2.1. WITHOUT opened hrmp channel -> RoutingError let result = @@ -565,52 +566,43 @@ where { // data here are not relevant for weighing let mut xcm = Xcm(vec![ - WithdrawAsset(MultiAssets::from(vec![MultiAsset { - id: Concrete(MultiLocation { parents: 1, interior: Here }), + WithdrawAsset(Assets::from(vec![Asset { + id: AssetId(Location::new(1, [])), fun: Fungible(34333299), }])), BuyExecution { - fees: MultiAsset { - id: Concrete(MultiLocation { parents: 1, interior: Here }), - fun: Fungible(34333299), - }, + fees: Asset { id: AssetId(Location::new(1, [])), fun: Fungible(34333299) }, weight_limit: Unlimited, }, ExportMessage { network: Polkadot, - destination: X1(Parachain(1000)), + destination: [Parachain(1000)].into(), xcm: Xcm(vec![ - ReserveAssetDeposited(MultiAssets::from(vec![MultiAsset { - id: Concrete(MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(Kusama)), - }), + ReserveAssetDeposited(Assets::from(vec![Asset { + id: AssetId(Location::new(2, [GlobalConsensus(Kusama)])), fun: Fungible(1000000000000), }])), ClearOrigin, BuyExecution { - fees: MultiAsset { - id: Concrete(MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(Kusama)), - }), + fees: Asset { + id: AssetId(Location::new(2, [GlobalConsensus(Kusama)])), fun: Fungible(1000000000000), }, weight_limit: Unlimited, }, DepositAsset { assets: Wild(AllCounted(1)), - beneficiary: MultiLocation { - parents: 0, - interior: X1(xcm::latest::prelude::AccountId32 { + beneficiary: Location::new( + 0, + [xcm::latest::prelude::AccountId32 { network: None, id: [ 212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125, ], - }), - }, + }], + ), }, SetTopic([ 116, 82, 194, 132, 171, 114, 217, 165, 23, 37, 161, 177, 165, 179, 247, 114, @@ -618,10 +610,7 @@ where ]), ]), }, - DepositAsset { - assets: Wild(All), - beneficiary: MultiLocation { parents: 1, interior: X1(Parachain(1000)) }, - }, + DepositAsset { assets: Wild(All), beneficiary: Location::new(1, [Parachain(1000)]) }, SetTopic([ 36, 224, 250, 165, 82, 195, 67, 110, 160, 170, 140, 87, 217, 62, 201, 164, 42, 98, 219, 157, 124, 105, 248, 25, 131, 218, 199, 36, 109, 173, 100, 122, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/mod.rs index f905d21b187..9285a1e7ad4 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/mod.rs @@ -37,10 +37,10 @@ use xcm_executor::traits::{validate_export, ExportXcm}; pub fn prepare_inbound_xcm( xcm_message: Xcm, - destination: InteriorMultiLocation, + destination: InteriorLocation, ) -> Vec { - let location = xcm::VersionedInteriorMultiLocation::V3(destination); - let xcm = xcm::VersionedXcm::::V3(xcm_message); + let location = xcm::VersionedInteriorLocation::V4(destination); + let xcm = xcm::VersionedXcm::::V4(xcm_message); // this is the `BridgeMessage` from polkadot xcm builder, but it has no constructor // or public fields, so just tuple // (double encoding, because `.encode()` is called on original Xcm BLOB when it is pushed @@ -101,7 +101,7 @@ macro_rules! grab_haul_blob ( /// which are transferred over bridge. pub(crate) fn simulate_message_exporter_on_bridged_chain< SourceNetwork: Get, - DestinationNetwork: Get, + DestinationNetwork: Get, DestinationVersion: GetVersion, >( (destination_network, destination_junctions): (NetworkId, Junctions), @@ -109,8 +109,8 @@ pub(crate) fn simulate_message_exporter_on_bridged_chain< grab_haul_blob!(GrabbingHaulBlob, GRABBED_HAUL_BLOB_PAYLOAD); // lets pretend that some parachain on bridged chain exported the message - let universal_source_on_bridged_chain = - X2(GlobalConsensus(SourceNetwork::get()), Parachain(5678)); + let universal_source_on_bridged_chain: Junctions = + [GlobalConsensus(SourceNetwork::get()), Parachain(5678)].into(); let channel = 1_u32; // simulate XCM message export diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/ambassador/mod.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/ambassador/mod.rs index 9f6378de53a..05b3427ef43 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/ambassador/mod.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/ambassador/mod.rs @@ -215,7 +215,7 @@ pub type AmbassadorSalaryInstance = pallet_salary::Instance2; parameter_types! { // The interior location on AssetHub for the paying account. This is the Ambassador Salary // pallet instance (which sits at index 74). This sovereign account will need funding. - pub AmbassadorSalaryLocation: InteriorMultiLocation = PalletInstance(74).into(); + pub AmbassadorSalaryLocation: InteriorLocation = PalletInstance(74).into(); } /// [`PayOverXcm`] setup to pay the Ambassador salary on the AssetHub in WND. diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/fellowship/mod.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/fellowship/mod.rs index f49306bf8e3..273fa6a3415 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/fellowship/mod.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/fellowship/mod.rs @@ -43,7 +43,7 @@ use parachains_common::{ westend::{account, currency::GRAND}, }; use polkadot_runtime_common::impls::{ - LocatableAssetConverter, VersionedLocatableAsset, VersionedMultiLocationConverter, + LocatableAssetConverter, VersionedLocatableAsset, VersionedLocationConverter, }; use sp_arithmetic::Permill; use sp_core::{ConstU128, ConstU32}; @@ -202,7 +202,7 @@ pub type FellowshipSalaryInstance = pallet_salary::Instance1; parameter_types! { // The interior location on AssetHub for the paying account. This is the Fellowship Salary // pallet instance (which sits at index 64). This sovereign account will need funding. - pub Interior: InteriorMultiLocation = PalletInstance(64).into(); + pub Interior: InteriorLocation = PalletInstance(64).into(); } const USDT_UNITS: u128 = 1_000_000; @@ -250,7 +250,7 @@ parameter_types! { pub const MaxBalance: Balance = Balance::max_value(); // The asset's interior location for the paying account. This is the Fellowship Treasury // pallet instance (which sits at index 65). - pub FellowshipTreasuryInteriorLocation: InteriorMultiLocation = PalletInstance(65).into(); + pub FellowshipTreasuryInteriorLocation: InteriorLocation = PalletInstance(65).into(); } #[cfg(feature = "runtime-benchmarks")] @@ -269,10 +269,10 @@ pub type FellowshipTreasuryPaymaster = PayOverXcm< crate::xcm_config::XcmRouter, crate::PolkadotXcm, ConstU32<{ 6 * HOURS }>, - VersionedMultiLocation, + VersionedLocation, VersionedLocatableAsset, LocatableAssetConverter, - VersionedMultiLocationConverter, + VersionedLocationConverter, >; pub type FellowshipTreasuryInstance = pallet_treasury::Instance1; @@ -327,7 +327,7 @@ impl pallet_treasury::Config for Runtime { >, >; type AssetKind = VersionedLocatableAsset; - type Beneficiary = VersionedMultiLocation; + type Beneficiary = VersionedLocation; type BeneficiaryLookup = IdentityLookup; #[cfg(not(feature = "runtime-benchmarks"))] type Paymaster = FellowshipTreasuryPaymaster; diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index 6cb8e096e4b..a527f620137 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -427,7 +427,7 @@ impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(xcm_config::WndLocation::get()); + pub FeeAssetId: AssetId = AssetId(xcm_config::WndLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -974,28 +974,28 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between Collectives and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }.into(), Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Reserve transfers are disabled on Collectives. None } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(Assets, u32, Location, Box)> { // Collectives only supports teleports to system parachain. // Relay/native token can be teleported between Collectives and Relay. let native_location = Parent.into(); diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs index 2e64127d6a1..aa7dbe991e4 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs @@ -19,7 +19,7 @@ use super::{ TransactionByteFee, WeightToFee, WestendTreasuryAccount, XcmpQueue, }; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, weights::Weight, }; @@ -51,17 +51,17 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const WndLocation: MultiLocation = MultiLocation::parent(); + pub const WndLocation: Location = Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::Westend); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); - pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); + pub const GovernanceLocation: Location = Location::parent(); pub const FellowshipAdminBodyId: BodyId = BodyId::Index(xcm_constants::body::FELLOWSHIP_ADMIN_INDEX); + pub AssetHub: Location = (Parent, Parachain(1000)).into(); pub const TreasurerBodyId: BodyId = BodyId::Index(xcm_constants::body::TREASURER_INDEX); - pub AssetHub: MultiLocation = (Parent, Parachain(1000)).into(); pub AssetHubUsdtId: AssetId = (PalletInstance(50), GeneralIndex(1984)).into(); pub UsdtAssetHub: LocatableAssetId = LocatableAssetId { location: AssetHub::get(), @@ -73,7 +73,7 @@ parameter_types! { }; } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -92,7 +92,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -136,11 +136,11 @@ parameter_types! { pub const FellowsBodyId: BodyId = BodyId::Technical; } -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -292,7 +292,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. +/// Converts a local signed origin into an XCM location. /// Forms the basis for local origins sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; @@ -310,10 +310,10 @@ pub type XcmRouter = WithUniqueTopic<( #[cfg(feature = "runtime-benchmarks")] parameter_types! { - pub ReachableDest: Option = Some(Parent.into()); + pub ReachableDest: Option = Some(Parent.into()); } -/// Type to convert the Fellows origin to a Plurality `MultiLocation` value. +/// Type to convert the Fellows origin to a Plurality `Location` value. pub type FellowsToPlurality = OriginToPluralityVoice; impl pallet_xcm::Config for Runtime { diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index 79b6b6be299..bc7d94889a1 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -704,28 +704,28 @@ impl_runtime_apis! { use xcm::latest::prelude::*; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between Contracts-System-Para and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Reserve transfers are disabled on Contracts-System-Para. None } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(Assets, u32, Location, Box)> { // Contracts-System-Para only supports teleports to system parachain. // Relay/native token can be teleported between Contracts-System-Para and Relay. let native_location = Parent.into(); diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/xcm_config.rs index 569ca6e587c..e2cf2c8e51a 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/xcm_config.rs @@ -20,8 +20,8 @@ use super::{ use crate::common::rococo::currency::CENTS; use cumulus_primitives_core::AggregateMessageOrigin; use frame_support::{ - match_types, parameter_types, - traits::{ConstU32, EitherOfDiverse, Equals, Everything, Nothing}, + parameter_types, + traits::{ConstU32, Contains, EitherOfDiverse, Equals, Everything, Nothing}, weights::Weight, }; use frame_system::EnsureRoot; @@ -51,13 +51,13 @@ use xcm_builder::{ use xcm_executor::XcmExecutor; parameter_types! { - pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = None; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = Parachain(ParachainInfo::parachain_id().into()).into(); + pub UniversalLocation: InteriorLocation = Parachain(ParachainInfo::parachain_id().into()).into(); pub const ExecutiveBody: BodyId = BodyId::Executive; pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); } /// We allow root and the Relay Chain council to execute privileged collator selection operations. @@ -66,7 +66,7 @@ pub type CollatorSelectionUpdateOrigin = EitherOfDiverse< EnsureXcm>, >; -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -85,7 +85,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -123,11 +123,11 @@ parameter_types! { pub const MaxInstructions: u32 = 100; } -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } } pub type Barrier = TrailingSetTopicAsId< @@ -200,7 +200,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. +/// Converts a local signed origin into an XCM location. /// Forms the basis for local origins sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; @@ -254,7 +254,7 @@ impl cumulus_pallet_xcm::Config for Runtime { parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(RelayLocation::get()); + pub FeeAssetId: AssetId = AssetId(RelayLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs index f8a5dc6398a..a46051212de 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs @@ -98,7 +98,7 @@ impl CoretimeInterface for CoretimeAllocator { }, ]); - match PolkadotXcm::send_xcm(Here, MultiLocation::parent(), message.clone()) { + match PolkadotXcm::send_xcm(Here, Location::parent(), message.clone()) { Ok(_) => log::info!( target: "runtime::coretime", "Request to update schedulable cores sent successfully." @@ -128,7 +128,7 @@ impl CoretimeInterface for CoretimeAllocator { }, ]); - match PolkadotXcm::send_xcm(Here, MultiLocation::parent(), message.clone()) { + match PolkadotXcm::send_xcm(Here, Location::parent(), message.clone()) { Ok(_) => log::info!( target: "runtime::coretime", "Request for revenue information sent successfully." @@ -157,7 +157,7 @@ impl CoretimeInterface for CoretimeAllocator { }, ]); - match PolkadotXcm::send_xcm(Here, MultiLocation::parent(), message.clone()) { + match PolkadotXcm::send_xcm(Here, Location::parent(), message.clone()) { Ok(_) => log::info!( target: "runtime::coretime", "Instruction to credit account sent successfully." @@ -192,7 +192,7 @@ impl CoretimeInterface for CoretimeAllocator { }, ]); - match PolkadotXcm::send_xcm(Here, MultiLocation::parent(), message.clone()) { + match PolkadotXcm::send_xcm(Here, Location::parent(), message.clone()) { Ok(_) => log::info!( target: "runtime::coretime", "Core assignment sent successfully." diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index c381d78b57f..c5843c1ef29 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -315,7 +315,7 @@ pub type RootOrFellows = EitherOfDiverse< parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(RocRelayLocation::get()); + pub FeeAssetId: AssetId = AssetId(RocRelayLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -698,29 +698,29 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between AH and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Reserve transfers are disabled None } } parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( RocRelayLocation::get(), ExistentialDeposit::get() ).into()); @@ -730,18 +730,18 @@ impl_runtime_apis! { type XcmConfig = xcm_config::XcmConfig; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForParentDelivery, >; type AccountIdConverter = xcm_config::LocationToAccountId; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(RocRelayLocation::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // just concrete assets according to relay chain. - let assets: Vec = vec![ - MultiAsset { - id: Concrete(RocRelayLocation::get()), + let assets: Vec = vec![ + Asset { + id: AssetId(RocRelayLocation::get()), fun: Fungible(1_000_000 * UNITS), } ]; @@ -750,12 +750,12 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( RocRelayLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(RocRelayLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(RocRelayLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -765,9 +765,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(RocRelayLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(RocRelayLocation::get()), fun: Fungible(UNITS), } } @@ -781,39 +781,39 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((RocRelayLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(RocRelayLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = RocRelayLocation::get(); - let assets: MultiAssets = (Concrete(RocRelayLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(RocRelayLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs index 2319c2e3a5b..8815312f304 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs @@ -24,14 +24,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -50,40 +50,36 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct CoretimeRococoXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for CoretimeRococoXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -111,43 +107,35 @@ impl XcmWeightInfo for CoretimeRococoXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -162,7 +150,7 @@ impl XcmWeightInfo for CoretimeRococoXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -174,13 +162,13 @@ impl XcmWeightInfo for CoretimeRococoXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -213,16 +201,16 @@ impl XcmWeightInfo for CoretimeRococoXcmWeight { fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -234,11 +222,11 @@ impl XcmWeightInfo for CoretimeRococoXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs index 00bbe5b5037..927d8f0a78e 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs @@ -20,7 +20,7 @@ use super::{ TransactionByteFee, WeightToFee, XcmpQueue, }; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; @@ -51,18 +51,18 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const RocRelayLocation: MultiLocation = MultiLocation::parent(); + pub const RocRelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::Rococo); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; - pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); - pub const FellowshipLocation: MultiLocation = MultiLocation::parent(); + pub const GovernanceLocation: Location = Location::parent(); + pub const FellowshipLocation: Location = Location::parent(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -81,7 +81,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an `AccountId32` `MultiLocation` into a native chain + // Do a simple punn to convert an `AccountId32` `Location` into a native chain // `AccountId`: LocationToAccountId, // Our chain's `AccountId` type (we can't get away without mentioning it explicitly): @@ -114,11 +114,11 @@ pub type XcmOriginToTransactDispatchOrigin = ( XcmPassthrough, ); -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -191,7 +191,7 @@ pub type Barrier = TrailingSetTopicAsId< parameter_types! { pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); } /// Locations that will not be charged fees in the executor, neither for execution nor delivery. @@ -240,7 +240,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. Forms the basis for local origins +/// Converts a local signed origin into an XCM location. Forms the basis for local origins /// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index 742b3a29275..59ed8d7c603 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -306,7 +306,7 @@ pub type RootOrFellows = EitherOfDiverse< parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(WndRelayLocation::get()); + pub FeeAssetId: AssetId = AssetId(WndRelayLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -689,29 +689,29 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between AH and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Reserve transfers are disabled None } } parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( WndRelayLocation::get(), ExistentialDeposit::get() ).into()); @@ -721,18 +721,18 @@ impl_runtime_apis! { type XcmConfig = xcm_config::XcmConfig; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForParentDelivery, >; type AccountIdConverter = xcm_config::LocationToAccountId; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(WndRelayLocation::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // just concrete assets according to relay chain. - let assets: Vec = vec![ - MultiAsset { - id: Concrete(WndRelayLocation::get()), + let assets: Vec = vec![ + Asset { + id: AssetId(WndRelayLocation::get()), fun: Fungible(1_000_000 * UNITS), } ]; @@ -741,12 +741,12 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( WndRelayLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(WndRelayLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(WndRelayLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -756,9 +756,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(WndRelayLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(WndRelayLocation::get()), fun: Fungible(UNITS), } } @@ -772,39 +772,39 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((WndRelayLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(WndRelayLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = WndRelayLocation::get(); - let assets: MultiAssets = (Concrete(WndRelayLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(WndRelayLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs index 3dc7b82efc2..a14da7c7a38 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs @@ -23,14 +23,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -49,40 +49,36 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct CoretimeWestendXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for CoretimeWestendXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -110,44 +106,36 @@ impl XcmWeightInfo for CoretimeWestendXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -162,7 +150,7 @@ impl XcmWeightInfo for CoretimeWestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -174,13 +162,13 @@ impl XcmWeightInfo for CoretimeWestendXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -213,16 +201,16 @@ impl XcmWeightInfo for CoretimeWestendXcmWeight { fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -234,11 +222,11 @@ impl XcmWeightInfo for CoretimeWestendXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs index 59d76d10d90..f468f29540a 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs @@ -20,7 +20,7 @@ use super::{ TransactionByteFee, WeightToFee, XcmpQueue, }; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; @@ -51,18 +51,18 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const WndRelayLocation: MultiLocation = MultiLocation::parent(); + pub const WndRelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::Westend); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; - pub FellowshipLocation: MultiLocation = MultiLocation::new(1, Parachain(1001)); - pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); + pub FellowshipLocation: Location = Location::new(1, Parachain(1001)); + pub const GovernanceLocation: Location = Location::parent(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -81,7 +81,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an `AccountId32` `MultiLocation` into a native chain + // Do a simple punn to convert an `AccountId32` `Location` into a native chain // `AccountId`: LocationToAccountId, // Our chain's `AccountId` type (we can't get away without mentioning it explicitly): @@ -114,14 +114,18 @@ pub type XcmOriginToTransactDispatchOrigin = ( XcmPassthrough, ); -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; - pub type FellowsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: X2(Parachain(1001), Plurality { id: BodyId::Technical, ..}) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } +} + +pub struct FellowsPlurality; +impl Contains for FellowsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [Parachain(1001), Plurality { id: BodyId::Technical, .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -192,7 +196,7 @@ pub type Barrier = TrailingSetTopicAsId< parameter_types! { pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); } /// Locations that will not be charged fees in the executor, neither for execution nor delivery. @@ -241,7 +245,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. Forms the basis for local origins +/// Converts a local signed origin into an XCM location. Forms the basis for local origins /// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/xcm_config.rs index 5ebb0ade123..1c37241563e 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/glutton/glutton-westend/src/xcm_config.rs @@ -18,8 +18,8 @@ use super::{ RuntimeOrigin, }; use frame_support::{ - match_types, parameter_types, - traits::{Everything, Nothing}, + parameter_types, + traits::{Contains, Everything, Nothing}, weights::Weight, }; use xcm::latest::prelude::*; @@ -29,9 +29,9 @@ use xcm_builder::{ }; parameter_types! { - pub const WestendLocation: MultiLocation = MultiLocation::parent(); + pub const WestendLocation: Location = Location::parent(); pub const WestendNetwork: Option = Some(NetworkId::Westend); - pub UniversalLocation: InteriorMultiLocation = X1(Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = [Parachain(ParachainInfo::parachain_id().into())].into(); } /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, @@ -47,8 +47,11 @@ pub type XcmOriginToTransactDispatchOrigin = ( ParentAsSuperuser, ); -match_types! { - pub type JustTheParent: impl Contains = { MultiLocation { parents:1, interior: Here } }; +pub struct JustTheParent; +impl Contains for JustTheParent { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [])) + } } parameter_types! { diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index 7805e0ad982..f5398829c73 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -682,22 +682,22 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between People and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { None } } @@ -706,7 +706,7 @@ impl_runtime_apis! { use xcm_config::{PriceForParentDelivery, RelayLocation}; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( RelayLocation::get(), ExistentialDeposit::get() ).into()); @@ -717,17 +717,17 @@ impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationToAccountId; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, PriceForParentDelivery, >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(RelayLocation::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // just concrete assets according to relay chain. - let assets: Vec = vec![ - MultiAsset { - id: Concrete(RelayLocation::get()), + let assets: Vec = vec![ + Asset { + id: AssetId(RelayLocation::get()), fun: Fungible(1_000_000 * UNITS), } ]; @@ -736,12 +736,12 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( RelayLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(RelayLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(RelayLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -751,9 +751,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(RelayLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(RelayLocation::get()), fun: Fungible(UNITS), } } @@ -767,39 +767,39 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((RelayLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(RelayLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = RelayLocation::get(); - let assets: MultiAssets = (Concrete(RelayLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(RelayLocation::get()), 1_000 * UNITS).into(); + let ticket = Location::new(0, []); Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs index c90a96c7f82..4afd65bdcfe 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs @@ -23,14 +23,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -49,42 +49,38 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct PeopleRococoXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for PeopleRococoXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } // Currently there is no trusted reserve - fn reserve_asset_deposited(_assets: &MultiAssets) -> Weight { + fn reserve_asset_deposited(_assets: &Assets) -> Weight { // TODO: hardcoded - fix https://github.com/paritytech/cumulus/issues/1974 Weight::from_parts(1_000_000_000_u64, 0) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -112,47 +108,39 @@ impl XcmWeightInfo for PeopleRococoXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { // Hardcoded till the XCM pallet is fixed let hardcoded_weight = Weight::from_parts(1_000_000_000_u64, 0); - let weight = assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()); + let weight = assets.weigh_assets(XcmFungibleWeight::::deposit_asset()); hardcoded_weight.min(weight) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmGeneric::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -167,7 +155,7 @@ impl XcmWeightInfo for PeopleRococoXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -179,13 +167,13 @@ impl XcmWeightInfo for PeopleRococoXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -218,16 +206,16 @@ impl XcmWeightInfo for PeopleRococoXcmWeight { fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -239,11 +227,11 @@ impl XcmWeightInfo for PeopleRococoXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs index 7a2f28aa813..7ef6cb2fac9 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs @@ -19,7 +19,7 @@ use super::{ }; use crate::{TransactionByteFee, CENTS}; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; @@ -49,22 +49,22 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const RootLocation: MultiLocation = MultiLocation::here(); - pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RootLocation: Location = Location::here(); + pub const RelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::Rococo); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; - pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); - pub const FellowshipLocation: MultiLocation = MultiLocation::parent(); + pub const GovernanceLocation: Location = Location::parent(); + pub const FellowshipLocation: Location = Location::parent(); /// The asset ID for the asset that we use to pay for message delivery fees. Just ROC. - pub FeeAssetId: AssetId = Concrete(RelayLocation::get()); + pub FeeAssetId: AssetId = AssetId(RelayLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); } @@ -82,7 +82,7 @@ pub type PriceForSiblingParachainDelivery = polkadot_runtime_common::xcm_sender: XcmpQueue, >; -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -103,7 +103,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an `AccountId32` `MultiLocation` into a native chain + // Do a simple punn to convert an `AccountId32` `Location` into a native chain // `AccountId`: LocationToAccountId, // Our chain's `AccountId` type (we can't get away without mentioning it explicitly): @@ -136,18 +136,25 @@ pub type XcmOriginToTransactDispatchOrigin = ( XcmPassthrough, ); -match_types! { - pub type LocalPlurality: impl Contains = { - MultiLocation { parents: 0, interior: X1(Plurality { .. }) } - }; - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; - pub type ParentOrSiblings: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Parachain(_)) } - }; +pub struct LocalPlurality; +impl Contains for LocalPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (0, [Plurality { .. }])) + } +} + +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } +} + +pub struct ParentOrSiblings; +impl Contains for ParentOrSiblings { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Parachain(_)])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -268,7 +275,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. Forms the basis for local origins +/// Converts a local signed origin into an XCM location. Forms the basis for local origins /// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index 8ea29c8aa21..33f0d511705 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -682,22 +682,22 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between People and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { None } } @@ -706,7 +706,7 @@ impl_runtime_apis! { use xcm_config::{PriceForParentDelivery, RelayLocation}; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( RelayLocation::get(), ExistentialDeposit::get() ).into()); @@ -717,17 +717,17 @@ impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationToAccountId; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, PriceForParentDelivery, >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(RelayLocation::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // just concrete assets according to relay chain. - let assets: Vec = vec![ - MultiAsset { - id: Concrete(RelayLocation::get()), + let assets: Vec = vec![ + Asset { + id: AssetId(RelayLocation::get()), fun: Fungible(1_000_000 * UNITS), } ]; @@ -736,12 +736,12 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( RelayLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(RelayLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(RelayLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -751,9 +751,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(RelayLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(RelayLocation::get()), fun: Fungible(UNITS), } } @@ -767,39 +767,39 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((RelayLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(RelayLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = RelayLocation::get(); - let assets: MultiAssets = (Concrete(RelayLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(RelayLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs index 5d6f90e9f1b..b2579230c9e 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs @@ -23,14 +23,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -49,42 +49,38 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct PeopleWestendXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for PeopleWestendXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } // Currently there is no trusted reserve - fn reserve_asset_deposited(_assets: &MultiAssets) -> Weight { + fn reserve_asset_deposited(_assets: &Assets) -> Weight { // TODO: hardcoded - fix https://github.com/paritytech/cumulus/issues/1974 Weight::from_parts(1_000_000_000_u64, 0) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -112,50 +108,42 @@ impl XcmWeightInfo for PeopleWestendXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { // Hardcoded till the XCM pallet is fixed let hardcoded_weight = Weight::from_parts(1_000_000_000_u64, 0); - let weight = assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()); + let weight = assets.weigh_assets(XcmFungibleWeight::::deposit_asset()); hardcoded_weight.min(weight) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmGeneric::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { // Hardcoded till the XCM pallet is fixed let hardcoded_weight = Weight::from_parts(200_000_000_u64, 0); - let weight = assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()); + let weight = assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()); hardcoded_weight.min(weight) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -170,7 +158,7 @@ impl XcmWeightInfo for PeopleWestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -182,13 +170,13 @@ impl XcmWeightInfo for PeopleWestendXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -221,16 +209,16 @@ impl XcmWeightInfo for PeopleWestendXcmWeight { fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -242,11 +230,11 @@ impl XcmWeightInfo for PeopleWestendXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs index 0a51cf72d5b..59c00dc5ff6 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs @@ -19,7 +19,7 @@ use super::{ }; use crate::{TransactionByteFee, CENTS}; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; @@ -49,22 +49,22 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const RootLocation: MultiLocation = MultiLocation::here(); - pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RootLocation: Location = Location::here(); + pub const RelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::Westend); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; - pub FellowshipLocation: MultiLocation = MultiLocation::new(1, Parachain(1001)); - pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); + pub FellowshipLocation: Location = Location::new(1, Parachain(1001)); + pub const GovernanceLocation: Location = Location::parent(); /// The asset ID for the asset that we use to pay for message delivery fees. Just WND. - pub FeeAssetId: AssetId = Concrete(RelayLocation::get()); + pub FeeAssetId: AssetId = AssetId(RelayLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); } @@ -82,7 +82,7 @@ pub type PriceForSiblingParachainDelivery = polkadot_runtime_common::xcm_sender: XcmpQueue, >; -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -103,7 +103,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an `AccountId32` `MultiLocation` into a native chain + // Do a simple punn to convert an `AccountId32` `Location` into a native chain // `AccountId`: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): @@ -136,21 +136,32 @@ pub type XcmOriginToTransactDispatchOrigin = ( XcmPassthrough, ); -match_types! { - pub type LocalPlurality: impl Contains = { - MultiLocation { parents: 0, interior: X1(Plurality { .. }) } - }; - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; - pub type ParentOrSiblings: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Parachain(_)) } - }; - pub type FellowsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: X2(Parachain(1001), Plurality { id: BodyId::Technical, ..}) } - }; +pub struct LocalPlurality; +impl Contains for LocalPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (0, [Plurality { .. }])) + } +} + +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } +} + +pub struct ParentOrSiblings; +impl Contains for ParentOrSiblings { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Parachain(_)])) + } +} + +pub struct FellowsPlurality; +impl Contains for FellowsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [Parachain(1001), Plurality { id: BodyId::Technical, .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -272,7 +283,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. Forms the basis for local origins +/// Converts a local signed origin into an XCM location. Forms the basis for local origins /// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; diff --git a/cumulus/parachains/runtimes/starters/shell/src/xcm_config.rs b/cumulus/parachains/runtimes/starters/shell/src/xcm_config.rs index ff773ca7816..f5ceabb1eb4 100644 --- a/cumulus/parachains/runtimes/starters/shell/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/starters/shell/src/xcm_config.rs @@ -18,8 +18,8 @@ use super::{ RuntimeOrigin, }; use frame_support::{ - match_types, parameter_types, - traits::{Everything, Nothing}, + parameter_types, + traits::{Contains, Everything, Nothing}, weights::Weight, }; use xcm::latest::prelude::*; @@ -29,9 +29,9 @@ use xcm_builder::{ }; parameter_types! { - pub const RococoLocation: MultiLocation = MultiLocation::parent(); + pub const RococoLocation: Location = Location::parent(); pub const RococoNetwork: Option = Some(NetworkId::Rococo); - pub UniversalLocation: InteriorMultiLocation = X1(Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = [Parachain(ParachainInfo::parachain_id().into())].into(); } /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, @@ -47,8 +47,11 @@ pub type XcmOriginToTransactDispatchOrigin = ( ParentAsSuperuser, ); -match_types! { - pub type JustTheParent: impl Contains = { MultiLocation { parents:1, interior: Here } }; +pub struct JustTheParent; +impl Contains for JustTheParent { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [])) + } } parameter_types! { diff --git a/cumulus/parachains/runtimes/test-utils/src/lib.rs b/cumulus/parachains/runtimes/test-utils/src/lib.rs index 6d43875a886..88e878c73a3 100644 --- a/cumulus/parachains/runtimes/test-utils/src/lib.rs +++ b/cumulus/parachains/runtimes/test-utils/src/lib.rs @@ -37,11 +37,11 @@ use sp_consensus_aura::{SlotDuration, AURA_ENGINE_ID}; use sp_core::Encode; use sp_runtime::{traits::Header, BuildStorage, Digest, DigestItem}; use xcm::{ - latest::{MultiAsset, MultiLocation, XcmContext, XcmHash}, + latest::{Asset, Location, XcmContext, XcmHash}, prelude::*, VersionedXcm, MAX_XCM_DECODE_DEPTH, }; -use xcm_executor::{traits::TransactAsset, Assets}; +use xcm_executor::{traits::TransactAsset, AssetsInHolding}; pub mod test_cases; @@ -307,12 +307,12 @@ impl RuntimeHelper { pub fn do_transfer( - from: MultiLocation, - to: MultiLocation, - (asset, amount): (MultiLocation, u128), - ) -> Result { + from: Location, + to: Location, + (asset, amount): (Location, u128), + ) -> Result { ::transfer_asset( - &MultiAsset { id: Concrete(asset), fun: Fungible(amount) }, + &Asset { id: AssetId(asset), fun: Fungible(amount) }, &from, &to, // We aren't able to track the XCM that initiated the fee deposit, so we create a @@ -329,9 +329,9 @@ impl< { pub fn do_teleport_assets( origin: ::RuntimeOrigin, - dest: MultiLocation, - beneficiary: MultiLocation, - (asset, amount): (MultiLocation, u128), + dest: Location, + beneficiary: Location, + (asset, amount): (Location, u128), open_hrmp_channel: Option<(u32, u32)>, included_head: HeaderFor, slot_digest: &[u8], @@ -356,7 +356,7 @@ impl< origin, Box::new(dest.into()), Box::new(beneficiary.into()), - Box::new((Concrete(asset), amount).into()), + Box::new((AssetId(asset), amount).into()), 0, ) } @@ -379,12 +379,13 @@ impl< ]); // execute xcm as parent origin - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); - <::XcmExecutor>::execute_xcm( - MultiLocation::parent(), + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); + <::XcmExecutor>::prepare_and_execute( + Location::parent(), xcm, - hash, + &mut hash, Self::xcm_max_weight(XcmReceivedFrom::Parent), + Weight::zero(), ) } } @@ -451,7 +452,7 @@ impl< } pub fn assert_metadata( - asset_id: impl Into + Copy, + asset_id: impl Into + Clone, expected_name: &str, expected_symbol: &str, expected_decimals: u8, @@ -459,20 +460,20 @@ pub fn assert_metadata( Fungibles: frame_support::traits::fungibles::metadata::Inspect + frame_support::traits::fungibles::Inspect, { - assert_eq!(Fungibles::name(asset_id.into()), Vec::from(expected_name),); - assert_eq!(Fungibles::symbol(asset_id.into()), Vec::from(expected_symbol),); + assert_eq!(Fungibles::name(asset_id.clone().into()), Vec::from(expected_name),); + assert_eq!(Fungibles::symbol(asset_id.clone().into()), Vec::from(expected_symbol),); assert_eq!(Fungibles::decimals(asset_id.into()), expected_decimals); } pub fn assert_total( - asset_id: impl Into + Copy, + asset_id: impl Into + Clone, expected_total_issuance: impl Into, expected_active_issuance: impl Into, ) where Fungibles: frame_support::traits::fungibles::metadata::Inspect + frame_support::traits::fungibles::Inspect, { - assert_eq!(Fungibles::total_issuance(asset_id.into()), expected_total_issuance.into()); + assert_eq!(Fungibles::total_issuance(asset_id.clone().into()), expected_total_issuance.into()); assert_eq!(Fungibles::active_issuance(asset_id.into()), expected_active_issuance.into()); } diff --git a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs index 541bcd05644..37a8454d62a 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs @@ -32,7 +32,6 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); mod weights; pub mod xcm_config; -use assets_common::MultiLocationForAssetId; use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use frame_support::{ @@ -474,8 +473,8 @@ pub type ForeignAssetsInstance = pallet_assets::Instance2; impl pallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; - type AssetId = MultiLocationForAssetId; - type AssetIdParameter = MultiLocationForAssetId; + type AssetId = xcm::v3::Location; + type AssetIdParameter = xcm::v3::Location; type Currency = Balances; type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = EnsureRoot; diff --git a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs index 9287ac30514..b3f84a4bb9c 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs @@ -29,7 +29,7 @@ use super::{ }; use core::marker::PhantomData; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ fungibles::{self, Balanced, Credit}, ConstU32, Contains, ContainsPair, Everything, Get, Nothing, @@ -59,13 +59,13 @@ use xcm_builder::{ use xcm_executor::{traits::JustTry, XcmExecutor}; parameter_types! { - pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = None; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = X1(Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = [Parachain(ParachainInfo::parachain_id().into())].into(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -84,7 +84,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -115,7 +115,7 @@ pub type FungiblesTransactor = FungiblesAdapter< JustTry, >, ), - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -180,14 +180,18 @@ parameter_types! { pub const MaxAssetsIntoHolding: u32 = 64; } -match_types! { - pub type ParentOrParentsExecutivePlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Executive, .. }) } - }; - pub type CommonGoodAssetsParachain: impl Contains = { - MultiLocation { parents: 1, interior: X1(Parachain(1000)) } - }; +pub struct ParentOrParentsExecutivePlurality; +impl Contains for ParentOrParentsExecutivePlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { id: BodyId::Executive, .. }])) + } +} + +pub struct CommonGoodAssetsParachain; +impl Contains for CommonGoodAssetsParachain { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [Parachain(1000)])) + } } pub type Barrier = TrailingSetTopicAsId< @@ -224,15 +228,15 @@ pub type AccountIdOf = ::AccountId; /// Asset filter that allows all assets from a certain location matching asset id. pub struct AssetPrefixFrom(PhantomData<(Prefix, Origin)>); -impl ContainsPair for AssetPrefixFrom +impl ContainsPair for AssetPrefixFrom where - Prefix: Get, - Origin: Get, + Prefix: Get, + Origin: Get, { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + fn contains(asset: &Asset, origin: &Location) -> bool { let loc = Origin::get(); &loc == origin && - matches!(asset, MultiAsset { id: AssetId::Concrete(asset_loc), fun: Fungible(_a) } + matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } if asset_loc.starts_with(&Prefix::get())) } } @@ -241,12 +245,12 @@ type AssetsFrom = AssetPrefixFrom; /// Asset filter that allows native/relay asset if coming from a certain location. pub struct NativeAssetFrom(PhantomData); -impl> ContainsPair for NativeAssetFrom { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl> ContainsPair for NativeAssetFrom { + fn contains(asset: &Asset, origin: &Location) -> bool { let loc = T::get(); &loc == origin && - matches!(asset, MultiAsset { id: AssetId::Concrete(asset_loc), fun: Fungible(_a) } - if *asset_loc == MultiLocation::from(Parent)) + matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } + if *asset_loc == Location::from(Parent)) } } @@ -282,29 +286,34 @@ where pub const TELEPORTABLE_ASSET_ID: u32 = 2; parameter_types! { /// The location that this chain recognizes as the Relay network's Asset Hub. - pub SystemAssetHubLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(1000))); + pub SystemAssetHubLocation: Location = Location::new(1, [Parachain(1000)]); // ALWAYS ensure that the index in PalletInstance stays up-to-date with // the Relay Chain's Asset Hub's Assets pallet index - pub SystemAssetHubAssetsPalletLocation: MultiLocation = - MultiLocation::new(1, X2(Parachain(1000), PalletInstance(50))); - pub AssetsPalletLocation: MultiLocation = - MultiLocation::new(0, X1(PalletInstance(50))); + pub SystemAssetHubAssetsPalletLocation: Location = + Location::new(1, [Parachain(1000), PalletInstance(50)]); + pub AssetsPalletLocation: Location = + Location::new(0, [PalletInstance(50)]); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); - pub LocalTeleportableToAssetHub: MultiLocation = MultiLocation::new( + pub LocalTeleportableToAssetHub: Location = Location::new( + 0, + [PalletInstance(50), GeneralIndex(TELEPORTABLE_ASSET_ID.into())] + ); + pub LocalTeleportableToAssetHubV3: xcm::v3::Location = xcm::v3::Location::new( 0, - X2(PalletInstance(50), GeneralIndex(TELEPORTABLE_ASSET_ID.into())) + [xcm::v3::Junction::PalletInstance(50), xcm::v3::Junction::GeneralIndex(TELEPORTABLE_ASSET_ID.into())] ); - pub EthereumLocation: MultiLocation = MultiLocation::new(2, X1(GlobalConsensus(EthereumNetwork::get()))); + pub EthereumLocation: Location = Location::new(2, [GlobalConsensus(EthereumNetwork::get())]); } /// Accepts asset with ID `AssetLocation` and is coming from `Origin` chain. pub struct AssetFromChain(PhantomData<(AssetLocation, Origin)>); -impl, Origin: Get> - ContainsPair for AssetFromChain +impl, Origin: Get> ContainsPair + for AssetFromChain { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + fn contains(asset: &Asset, origin: &Location) -> bool { log::trace!(target: "xcm::contains", "AssetFromChain asset: {:?}, origin: {:?}", asset, origin); - *origin == Origin::get() && matches!(asset.id, Concrete(id) if id == AssetLocation::get()) + *origin == Origin::get() && + matches!(asset.id.clone(), AssetId(id) if id == AssetLocation::get()) } } @@ -398,8 +407,8 @@ impl cumulus_pallet_xcm::Config for Runtime { /// Simple conversion of `u32` into an `AssetId` for use in benchmarking. pub struct XcmBenchmarkHelper; #[cfg(feature = "runtime-benchmarks")] -impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { - fn create_asset_id_parameter(id: u32) -> MultiLocation { - MultiLocation { parents: 1, interior: X1(Parachain(id)) } +impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { + fn create_asset_id_parameter(id: u32) -> xcm::v3::Location { + xcm::v3::Location::new(1, [xcm::v3::Junction::Parachain(id)]) } } diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs index 7faee4258f6..102127479d2 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs @@ -42,10 +42,10 @@ pub use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, genesis_builder_helper::{build_config, create_default_config}, - match_types, parameter_types, + parameter_types, traits::{ - AsEnsureOriginWithArg, ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Everything, - IsInVec, Nothing, Randomness, + AsEnsureOriginWithArg, ConstBool, ConstU32, ConstU64, ConstU8, Contains, EitherOfDiverse, + Everything, IsInVec, Nothing, Randomness, }, weights::{ constants::{ @@ -330,14 +330,14 @@ impl pallet_message_queue::Config for Runtime { impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { - pub const RocLocation: MultiLocation = MultiLocation::parent(); + pub const RocLocation: Location = Location::parent(); pub const RococoNetwork: Option = Some(NetworkId::Rococo); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = X1(Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = [Parachain(ParachainInfo::parachain_id().into())].into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -356,7 +356,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -379,7 +379,7 @@ pub type FungiblesTransactor = FungiblesAdapter< >, JustTry, >, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -420,20 +420,22 @@ parameter_types! { // One XCM operation is 1_000_000_000 weight - almost certainly a conservative estimate. pub UnitWeightCost: Weight = Weight::from_parts(1_000_000_000, 64 * 1024); // One ROC buys 1 second of weight. - pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), ROC); + pub const WeightPrice: (Location, u128) = (Location::parent(), ROC); pub const MaxInstructions: u32 = 100; } -match_types! { - // The parent or the parent's unit plurality. - pub type ParentOrParentsUnitPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) } - }; - // The location recognized as the Relay network's Asset Hub. - pub type AssetHub: impl Contains = { - MultiLocation { parents: 1, interior: X1(Parachain(1000)) } - }; +pub struct ParentOrParentsUnitPlurality; +impl Contains for ParentOrParentsUnitPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { id: BodyId::Unit, .. }])) + } +} + +pub struct AssetHub; +impl Contains for AssetHub { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [Parachain(1000)])) + } } pub type Barrier = TrailingSetTopicAsId<( @@ -451,11 +453,11 @@ pub type Barrier = TrailingSetTopicAsId<( parameter_types! { pub MaxAssetsIntoHolding: u32 = 64; - pub SystemAssetHubLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(1000))); + pub SystemAssetHubLocation: Location = Location::new(1, [Parachain(1000)]); // ALWAYS ensure that the index in PalletInstance stays up-to-date with // the Relay Chain's Asset Hub's Assets pallet index - pub SystemAssetHubAssetsPalletLocation: MultiLocation = - MultiLocation::new(1, X2(Parachain(1000), PalletInstance(50))); + pub SystemAssetHubAssetsPalletLocation: Location = + Location::new(1, [Parachain(1000), PalletInstance(50)]); } pub type Reserves = (NativeAsset, AssetsFrom); diff --git a/cumulus/primitives/core/src/lib.rs b/cumulus/primitives/core/src/lib.rs index 835c9de649e..7f735368565 100644 --- a/cumulus/primitives/core/src/lib.rs +++ b/cumulus/primitives/core/src/lib.rs @@ -93,13 +93,12 @@ pub enum AggregateMessageOrigin { Sibling(ParaId), } -impl From for xcm::v3::MultiLocation { +impl From for Location { fn from(origin: AggregateMessageOrigin) -> Self { match origin { - AggregateMessageOrigin::Here => MultiLocation::here(), - AggregateMessageOrigin::Parent => MultiLocation::parent(), - AggregateMessageOrigin::Sibling(id) => - MultiLocation::new(1, Junction::Parachain(id.into())), + AggregateMessageOrigin::Here => Location::here(), + AggregateMessageOrigin::Parent => Location::parent(), + AggregateMessageOrigin::Sibling(id) => Location::new(1, Junction::Parachain(id.into())), } } } diff --git a/cumulus/primitives/utility/src/lib.rs b/cumulus/primitives/utility/src/lib.rs index 7216000cb45..bd13ee1119b 100644 --- a/cumulus/primitives/utility/src/lib.rs +++ b/cumulus/primitives/utility/src/lib.rs @@ -35,7 +35,10 @@ use sp_runtime::{ use sp_std::{marker::PhantomData, prelude::*}; use xcm::{latest::prelude::*, WrapVersion}; use xcm_builder::TakeRevenue; -use xcm_executor::traits::{MatchesFungibles, TransactAsset, WeightTrader}; +use xcm_executor::{ + traits::{MatchesFungibles, TransactAsset, WeightTrader}, + AssetsInHolding, +}; #[cfg(test)] mod tests; @@ -56,10 +59,7 @@ where { type Ticket = Vec; - fn validate( - dest: &mut Option, - msg: &mut Option>, - ) -> SendResult> { + fn validate(dest: &mut Option, msg: &mut Option>) -> SendResult> { let d = dest.take().ok_or(SendError::MissingArgument)?; if d.contains_parents_only(1) { @@ -95,14 +95,14 @@ struct AssetTraderRefunder { // The amount of weight bought minus the weigh already refunded weight_outstanding: Weight, // The concrete asset containing the asset location and outstanding balance - outstanding_concrete_asset: MultiAsset, + outstanding_concrete_asset: Asset, } -/// Charges for execution in the first multiasset of those selected for fee payment +/// Charges for execution in the first asset of those selected for fee payment /// Only succeeds for Concrete Fungible Assets -/// First tries to convert the this MultiAsset into a local assetId +/// First tries to convert the this Asset into a local assetId /// Then charges for this assetId as described by FeeCharger -/// Weight, paid balance, local asset Id and the multilocation is stored for +/// Weight, paid balance, local asset Id and the location is stored for /// later refund purposes /// Important: Errors if the Trader is being called twice by 2 BuyExecution instructions /// Alternatively we could just return payment in the aforementioned case @@ -128,15 +128,15 @@ impl< fn new() -> Self { Self(None, PhantomData) } - // We take first multiasset + // We take first asset // Check whether we can convert fee to asset_fee (is_sufficient, min_deposit) // If everything goes well, we charge. fn buy_weight( &mut self, weight: Weight, - payment: xcm_executor::Assets, + payment: xcm_executor::AssetsInHolding, context: &XcmContext, - ) -> Result { + ) -> Result { log::trace!(target: "xcm::weight", "TakeFirstAssetTrader::buy_weight weight: {:?}, payment: {:?}, context: {:?}", weight, payment, context); // Make sure we dont enter twice @@ -144,12 +144,12 @@ impl< return Err(XcmError::NotWithdrawable) } - // We take the very first multiasset from payment + // We take the very first asset from payment // (assets are sorted by fungibility/amount after this conversion) - let multiassets: MultiAssets = payment.clone().into(); + let assets: Assets = payment.clone().into(); - // Take the first multiasset from the selected MultiAssets - let first = multiassets.get(0).ok_or(XcmError::AssetNotFound)?; + // Take the first asset from the selected Assets + let first = assets.get(0).ok_or(XcmError::AssetNotFound)?; // Get the local asset id in which we can pay for fees let (local_asset_id, _) = @@ -171,13 +171,13 @@ impl< .try_into() .map_err(|_| XcmError::Overflow)?; - // Convert to the same kind of multiasset, with the required fungible balance - let required = first.id.into_multiasset(asset_balance.into()); + // Convert to the same kind of asset, with the required fungible balance + let required = first.id.clone().into_asset(asset_balance.into()); // Substract payment let unused = payment.checked_sub(required.clone()).map_err(|_| XcmError::TooExpensive)?; - // record weight and multiasset + // record weight and asset self.0 = Some(AssetTraderRefunder { weight_outstanding: weight, outstanding_concrete_asset: required, @@ -186,16 +186,16 @@ impl< Ok(unused) } - fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { + fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { log::trace!(target: "xcm::weight", "TakeFirstAssetTrader::refund_weight weight: {:?}, context: {:?}", weight, context); if let Some(AssetTraderRefunder { mut weight_outstanding, - outstanding_concrete_asset: MultiAsset { id, fun }, + outstanding_concrete_asset: Asset { id, fun }, }) = self.0.clone() { // Get the local asset id in which we can refund fees let (local_asset_id, outstanding_balance) = - Matcher::matches_fungibles(&(id, fun).into()).ok()?; + Matcher::matches_fungibles(&(id.clone(), fun).into()).ok()?; let minimum_balance = ConcreteAssets::minimum_balance(local_asset_id.clone()); @@ -225,7 +225,8 @@ impl< // Construct outstanding_concrete_asset with the same location id and substracted // balance - let outstanding_concrete_asset: MultiAsset = (id, outstanding_minus_substracted).into(); + let outstanding_concrete_asset: Asset = + (id.clone(), outstanding_minus_substracted).into(); // Substract from existing weight and balance weight_outstanding = weight_outstanding.saturating_sub(weight); @@ -272,11 +273,11 @@ impl< ReceiverAccount: Get>, > TakeRevenue for XcmFeesTo32ByteAccount { - fn take_revenue(revenue: MultiAsset) { + fn take_revenue(revenue: Asset) { if let Some(receiver) = ReceiverAccount::get() { let ok = FungiblesMutateAdapter::deposit_asset( &revenue, - &(X1(AccountId32 { network: None, id: receiver.into() }).into()), + &([AccountId32 { network: None, id: receiver.into() }].into()), None, ) .is_ok(); @@ -307,7 +308,7 @@ pub trait ChargeWeightInFungibles Result { + ) -> Result { log::trace!( target: "xcm::weight", "SwapFirstAssetTrader::buy_weight weight: {:?}, payment: {:?}", weight, payment, ); - let first_asset: MultiAsset = + let first_asset: Asset = payment.fungible.pop_first().ok_or(XcmError::AssetNotFound)?.into(); let (fungibles_asset, balance) = FungiblesAssetMatcher::matches_fungibles(&first_asset) .map_err(|_| XcmError::AssetNotFound)?; @@ -424,14 +425,14 @@ impl< }, _ => (), }; - self.last_fee_asset = Some(first_asset.id); + self.last_fee_asset = Some(first_asset.id.clone()); payment.fungible.insert(first_asset.id, credit_change.peek().into()); drop(credit_change); Ok(payment) } - fn refund_weight(&mut self, weight: Weight, _context: &XcmContext) -> Option { + fn refund_weight(&mut self, weight: Weight, _context: &XcmContext) -> Option { log::trace!( target: "xcm::weight", "SwapFirstAssetTrader::refund_weight weight: {:?}, self.total_fee: {:?}", @@ -444,7 +445,7 @@ impl< } let mut refund_asset = if let Some(asset) = &self.last_fee_asset { // create an initial zero refund in the asset used in the last `buy_weight`. - (*asset, Fungible(0)).into() + (asset.clone(), Fungible(0)).into() } else { return None }; @@ -529,11 +530,11 @@ mod test_xcm_router { impl OkFixedXcmHashWithAssertingRequiredInputsSender { const FIXED_XCM_HASH: [u8; 32] = [9; 32]; - fn fixed_delivery_asset() -> MultiAssets { - MultiAssets::new() + fn fixed_delivery_asset() -> Assets { + Assets::new() } - fn expected_delivery_result() -> Result<(XcmHash, MultiAssets), SendError> { + fn expected_delivery_result() -> Result<(XcmHash, Assets), SendError> { Ok((Self::FIXED_XCM_HASH, Self::fixed_delivery_asset())) } } @@ -541,7 +542,7 @@ mod test_xcm_router { type Ticket = (); fn validate( - destination: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult { assert!(destination.is_some()); @@ -597,7 +598,7 @@ mod test_xcm_router { // ParentAsUmp - check dest/msg is valid let dest = (Parent, Here); - let mut dest_wrapper = Some(dest.into()); + let mut dest_wrapper = Some(dest.clone().into()); let mut msg_wrapper = Some(message.clone()); assert!( as SendXcm>::validate( &mut dest_wrapper, @@ -629,7 +630,7 @@ mod test_trader { }, }; use sp_runtime::DispatchError; - use xcm_executor::{traits::Error, Assets}; + use xcm_executor::{traits::Error, AssetsInHolding}; #[test] fn take_first_asset_trader_buy_weight_called_twice_throws_error() { @@ -641,9 +642,9 @@ mod test_trader { type TestBalance = u128; struct TestAssets; impl MatchesFungibles for TestAssets { - fn matches_fungibles(a: &MultiAsset) -> Result<(TestAssetId, TestBalance), Error> { + fn matches_fungibles(a: &Asset) -> Result<(TestAssetId, TestBalance), Error> { match a { - MultiAsset { fun: Fungible(amount), id: Concrete(_id) } => Ok((1, *amount)), + Asset { fun: Fungible(amount), id: AssetId(_id) } => Ok((1, *amount)), _ => Err(Error::AssetNotHandled), } } @@ -730,7 +731,7 @@ mod test_trader { } } impl TakeRevenue for FeeChargerAssetsHandleRefund { - fn take_revenue(_: MultiAsset) {} + fn take_revenue(_: Asset) {} } // create new instance @@ -745,8 +746,8 @@ mod test_trader { let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; // prepare test data - let asset: MultiAsset = (Here, AMOUNT).into(); - let payment = Assets::from(asset); + let asset: Asset = (Here, AMOUNT).into(); + let payment = AssetsInHolding::from(asset); let weight_to_buy = Weight::from_parts(1_000, 1_000); // lets do first call (success) @@ -769,17 +770,17 @@ pub struct ToParentDeliveryHelper>, + ExistentialDeposit: Get>, PriceForDelivery: PriceForMessageDelivery, > pallet_xcm_benchmarks::EnsureDelivery for ToParentDeliveryHelper { fn ensure_successful_delivery( - origin_ref: &MultiLocation, - _dest: &MultiLocation, + origin_ref: &Location, + _dest: &Location, fee_reason: xcm_executor::traits::FeeReason, - ) -> (Option, Option) { - use xcm::latest::{MAX_INSTRUCTIONS_TO_DECODE, MAX_ITEMS_IN_MULTIASSETS}; + ) -> (Option, Option) { + use xcm::latest::{MAX_INSTRUCTIONS_TO_DECODE, MAX_ITEMS_IN_ASSETS}; use xcm_executor::{traits::FeeManager, FeesMode}; let mut fees_mode = None; @@ -792,8 +793,8 @@ impl< } // overestimate delivery fee - let mut max_assets: Vec = Vec::new(); - for i in 0..MAX_ITEMS_IN_MULTIASSETS { + let mut max_assets: Vec = Vec::new(); + for i in 0..MAX_ITEMS_IN_ASSETS { max_assets.push((GeneralIndex(i as u128), 100u128).into()); } let overestimated_xcm = diff --git a/cumulus/primitives/utility/src/tests/swap_first.rs b/cumulus/primitives/utility/src/tests/swap_first.rs index 222cd005b12..2e19db49881 100644 --- a/cumulus/primitives/utility/src/tests/swap_first.rs +++ b/cumulus/primitives/utility/src/tests/swap_first.rs @@ -18,18 +18,18 @@ use crate::*; use frame_support::{parameter_types, traits::fungibles::Inspect}; use mock::{setup_pool, AccountId, AssetId, Balance, Fungibles}; use xcm::latest::AssetId as XcmAssetId; -use xcm_executor::Assets as HoldingAsset; +use xcm_executor::AssetsInHolding; -fn create_holding_asset(asset_id: AssetId, amount: Balance) -> HoldingAsset { +fn create_holding_asset(asset_id: AssetId, amount: Balance) -> AssetsInHolding { create_asset(asset_id, amount).into() } -fn create_asset(asset_id: AssetId, amount: Balance) -> MultiAsset { - MultiAsset { id: create_asset_id(asset_id), fun: Fungible(amount) } +fn create_asset(asset_id: AssetId, amount: Balance) -> Asset { + Asset { id: create_asset_id(asset_id), fun: Fungible(amount) } } fn create_asset_id(asset_id: AssetId) -> XcmAssetId { - Concrete(MultiLocation::new(0, X1(GeneralIndex(asset_id.into())))) + AssetId(Location::new(0, [GeneralIndex(asset_id.into())])) } fn xcm_context() -> XcmContext { @@ -319,7 +319,7 @@ fn empty_holding_asset() { let mut trader = Trader::new(); assert_eq!( trader - .buy_weight(Weight::from_all(10), HoldingAsset::new(), &xcm_context()) + .buy_weight(Weight::from_all(10), AssetsInHolding::new(), &xcm_context()) .unwrap_err(), XcmError::AssetNotFound ); @@ -328,8 +328,7 @@ fn empty_holding_asset() { #[test] fn fails_to_match_holding_asset() { let mut trader = Trader::new(); - let holding_asset = - MultiAsset { id: Concrete(MultiLocation::new(1, X1(Parachain(1)))), fun: Fungible(10) }; + let holding_asset = Asset { id: AssetId(Location::new(1, [Parachain(1)])), fun: Fungible(10) }; assert_eq!( trader .buy_weight(Weight::from_all(10), holding_asset.into(), &xcm_context()) @@ -536,14 +535,15 @@ pub mod mock { pub struct FungiblesMatcher; impl MatchesFungibles for FungiblesMatcher { fn matches_fungibles( - a: &MultiAsset, + a: &Asset, ) -> core::result::Result<(AssetId, Balance), xcm_executor::traits::Error> { match a { - MultiAsset { - fun: Fungible(amount), - id: - Concrete(MultiLocation { parents: 0, interior: X1(Junction::GeneralIndex(id)) }), - } => Ok(((*id).try_into().unwrap(), *amount)), + Asset { fun: Fungible(amount), id: AssetId(inner_location) } => + match inner_location.unpack() { + (0, [Junction::GeneralIndex(id)]) => + Ok(((*id).try_into().unwrap(), *amount)), + _ => Err(xcm_executor::traits::Error::AssetNotHandled), + }, _ => Err(xcm_executor::traits::Error::AssetNotHandled), } } diff --git a/cumulus/xcm/xcm-emulator/src/lib.rs b/cumulus/xcm/xcm-emulator/src/lib.rs index c9e4de21d43..c5cc632574b 100644 --- a/cumulus/xcm/xcm-emulator/src/lib.rs +++ b/cumulus/xcm/xcm-emulator/src/lib.rs @@ -60,12 +60,9 @@ pub use polkadot_runtime_parachains::inclusion::{AggregateMessageOrigin, UmpQueu // Polkadot pub use polkadot_parachain_primitives::primitives::RelayChainBlockNumber; use sp_core::crypto::AccountId32; -pub use xcm::{ - prelude::{AccountId32 as AccountId32Junction, Here}, - v3::prelude::{ - Ancestor, MultiAssets, MultiLocation, Parachain as ParachainJunction, Parent, WeightLimit, - XcmHash, X1, - }, +pub use xcm::latest::prelude::{ + AccountId32 as AccountId32Junction, Ancestor, Assets, Here, Location, + Parachain as ParachainJunction, Parent, WeightLimit, XcmHash, }; pub use xcm_executor::traits::ConvertLocation; @@ -231,11 +228,11 @@ pub trait RelayChain: Chain { fn init(); - fn child_location_of(id: ParaId) -> MultiLocation { + fn child_location_of(id: ParaId) -> Location { (Ancestor(0), ParachainJunction(id.into())).into() } - fn sovereign_account_id_of(location: MultiLocation) -> AccountIdOf { + fn sovereign_account_id_of(location: Location) -> AccountIdOf { Self::SovereignAccountOf::convert_location(&location).unwrap() } @@ -263,15 +260,15 @@ pub trait Parachain: Chain { Self::ext_wrapper(|| Self::ParachainInfo::get()) } - fn parent_location() -> MultiLocation { + fn parent_location() -> Location { (Parent).into() } - fn sibling_location_of(para_id: ParaId) -> MultiLocation { - (Parent, X1(ParachainJunction(para_id.into()))).into() + fn sibling_location_of(para_id: ParaId) -> Location { + (Parent, ParachainJunction(para_id.into())).into() } - fn sovereign_account_id_of(location: MultiLocation) -> AccountIdOf { + fn sovereign_account_id_of(location: Location) -> AccountIdOf { Self::LocationToAccountId::convert_location(&location).unwrap() } } @@ -1432,10 +1429,10 @@ pub struct TestAccount { /// Default `Args` provided by xcm-emulator to be stored in a `Test` instance #[derive(Clone)] pub struct TestArgs { - pub dest: MultiLocation, - pub beneficiary: MultiLocation, + pub dest: Location, + pub beneficiary: Location, pub amount: Balance, - pub assets: MultiAssets, + pub assets: Assets, pub asset_id: Option, pub fee_asset_item: u32, pub weight_limit: WeightLimit, @@ -1443,7 +1440,7 @@ pub struct TestArgs { impl TestArgs { /// Returns a [`TestArgs`] instance to be used for the Relay Chain across integration tests. - pub fn new_relay(dest: MultiLocation, beneficiary_id: AccountId32, amount: Balance) -> Self { + pub fn new_relay(dest: Location, beneficiary_id: AccountId32, amount: Balance) -> Self { Self { dest, beneficiary: AccountId32Junction { network: None, id: beneficiary_id.into() }.into(), @@ -1457,10 +1454,10 @@ impl TestArgs { /// Returns a [`TestArgs`] instance to be used for parachains across integration tests. pub fn new_para( - dest: MultiLocation, + dest: Location, beneficiary_id: AccountId32, amount: Balance, - assets: MultiAssets, + assets: Assets, asset_id: Option, fee_asset_item: u32, ) -> Self { diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index d71c626cd98..a9edb196627 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -21,7 +21,7 @@ use frame_support::traits::{Currency, Imbalance, OnUnbalanced}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use primitives::Balance; use sp_runtime::{traits::TryConvert, Perquintill, RuntimeDebug}; -use xcm::VersionedMultiLocation; +use xcm::VersionedLocation; /// Logic for the author to get a portion of fees. pub struct ToAuthor(sp_std::marker::PhantomData); @@ -107,12 +107,9 @@ pub fn era_payout( )] pub enum VersionedLocatableAsset { #[codec(index = 3)] - V3 { - /// The (relative) location in which the asset ID is meaningful. - location: xcm::v3::MultiLocation, - /// The asset's ID. - asset_id: xcm::v3::AssetId, - }, + V3 { location: xcm::v3::MultiLocation, asset_id: xcm::v3::AssetId }, + #[codec(index = 4)] + V4 { location: xcm::v4::Location, asset_id: xcm::v4::AssetId }, } /// Converts the [`VersionedLocatableAsset`] to the [`xcm_builder::LocatableAssetId`]. @@ -125,22 +122,29 @@ impl TryConvert ) -> Result { match asset { VersionedLocatableAsset::V3 { location, asset_id } => - Ok(xcm_builder::LocatableAssetId { asset_id, location }), + Ok(xcm_builder::LocatableAssetId { + location: location.try_into().map_err(|_| asset.clone())?, + asset_id: asset_id.try_into().map_err(|_| asset.clone())?, + }), + VersionedLocatableAsset::V4 { location, asset_id } => + Ok(xcm_builder::LocatableAssetId { location, asset_id }), } } } -/// Converts the [`VersionedMultiLocation`] to the [`xcm::latest::MultiLocation`]. -pub struct VersionedMultiLocationConverter; -impl TryConvert<&VersionedMultiLocation, xcm::latest::MultiLocation> - for VersionedMultiLocationConverter -{ +/// Converts the [`VersionedLocation`] to the [`xcm::latest::Location`]. +pub struct VersionedLocationConverter; +impl TryConvert<&VersionedLocation, xcm::latest::Location> for VersionedLocationConverter { fn try_convert( - location: &VersionedMultiLocation, - ) -> Result { + location: &VersionedLocation, + ) -> Result { let latest = match location.clone() { - VersionedMultiLocation::V2(l) => l.try_into().map_err(|_| location)?, - VersionedMultiLocation::V3(l) => l, + VersionedLocation::V2(l) => { + let v3: xcm::v3::MultiLocation = l.try_into().map_err(|_| location)?; + v3.try_into().map_err(|_| location)? + }, + VersionedLocation::V3(l) => l.try_into().map_err(|_| location)?, + VersionedLocation::V4(l) => l, }; Ok(latest) } @@ -161,11 +165,14 @@ pub mod benchmarks { pub struct AssetRateArguments; impl AssetKindFactory for AssetRateArguments { fn create_asset_kind(seed: u32) -> VersionedLocatableAsset { - VersionedLocatableAsset::V3 { - location: xcm::v3::MultiLocation::new(0, X1(Parachain(seed))), - asset_id: xcm::v3::MultiLocation::new( + VersionedLocatableAsset::V4 { + location: xcm::v4::Location::new(0, [xcm::v4::Junction::Parachain(seed)]), + asset_id: xcm::v4::Location::new( 0, - X2(PalletInstance(seed.try_into().unwrap()), GeneralIndex(seed.into())), + [ + xcm::v4::Junction::PalletInstance(seed.try_into().unwrap()), + xcm::v4::Junction::GeneralIndex(seed.into()), + ], ) .into(), } @@ -173,29 +180,35 @@ pub mod benchmarks { } /// Provide factory methods for the [`VersionedLocatableAsset`] and the `Beneficiary` of the - /// [`VersionedMultiLocation`]. The location of the asset is determined as a Parachain with an + /// [`VersionedLocation`]. The location of the asset is determined as a Parachain with an /// ID equal to the passed seed. pub struct TreasuryArguments, ParaId = ConstU32<0>>( PhantomData<(Parents, ParaId)>, ); impl, ParaId: Get> - TreasuryArgumentsFactory + TreasuryArgumentsFactory for TreasuryArguments { fn create_asset_kind(seed: u32) -> VersionedLocatableAsset { VersionedLocatableAsset::V3 { - location: xcm::v3::MultiLocation::new(Parents::get(), X1(Parachain(ParaId::get()))), + location: xcm::v3::MultiLocation::new( + Parents::get(), + [xcm::v3::Junction::Parachain(ParaId::get())], + ), asset_id: xcm::v3::MultiLocation::new( 0, - X2(PalletInstance(seed.try_into().unwrap()), GeneralIndex(seed.into())), + [ + xcm::v3::Junction::PalletInstance(seed.try_into().unwrap()), + xcm::v3::Junction::GeneralIndex(seed.into()), + ], ) .into(), } } - fn create_beneficiary(seed: [u8; 32]) -> VersionedMultiLocation { - VersionedMultiLocation::V3(xcm::v3::MultiLocation::new( + fn create_beneficiary(seed: [u8; 32]) -> VersionedLocation { + VersionedLocation::V4(xcm::v4::Location::new( 0, - X1(AccountId32 { network: None, id: seed }), + [xcm::v4::Junction::AccountId32 { network: None, id: seed }], )) } } diff --git a/polkadot/runtime/common/src/xcm_sender.rs b/polkadot/runtime/common/src/xcm_sender.rs index 4d31c92cdd3..7f1100a1361 100644 --- a/polkadot/runtime/common/src/xcm_sender.rs +++ b/polkadot/runtime/common/src/xcm_sender.rs @@ -35,13 +35,13 @@ pub trait PriceForMessageDelivery { /// Type used for charging different prices to different destinations type Id; /// Return the assets required to deliver `message` to the given `para` destination. - fn price_for_delivery(id: Self::Id, message: &Xcm<()>) -> MultiAssets; + fn price_for_delivery(id: Self::Id, message: &Xcm<()>) -> Assets; } impl PriceForMessageDelivery for () { type Id = (); - fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> MultiAssets { - MultiAssets::new() + fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> Assets { + Assets::new() } } @@ -49,17 +49,17 @@ pub struct NoPriceForMessageDelivery(PhantomData); impl PriceForMessageDelivery for NoPriceForMessageDelivery { type Id = Id; - fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> MultiAssets { - MultiAssets::new() + fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> Assets { + Assets::new() } } /// Implementation of [`PriceForMessageDelivery`] which returns a fixed price. pub struct ConstantPrice(sp_std::marker::PhantomData); -impl> PriceForMessageDelivery for ConstantPrice { +impl> PriceForMessageDelivery for ConstantPrice { type Id = (); - fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> MultiAssets { + fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> Assets { T::get() } } @@ -84,7 +84,7 @@ impl, B: Get, M: Get, F: FeeTracker> PriceForMessage { type Id = F::Id; - fn price_for_delivery(id: Self::Id, msg: &Xcm<()>) -> MultiAssets { + fn price_for_delivery(id: Self::Id, msg: &Xcm<()>) -> Assets { let msg_fee = (msg.encoded_size() as u128).saturating_mul(M::get()); let fee_sum = B::get().saturating_add(msg_fee); let amount = F::get_fee_factor(id).saturating_mul_int(fee_sum); @@ -103,11 +103,11 @@ where type Ticket = (HostConfiguration>, ParaId, Vec); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, ) -> SendResult<(HostConfiguration>, ParaId, Vec)> { let d = dest.take().ok_or(MissingArgument)?; - let id = if let MultiLocation { parents: 0, interior: X1(Parachain(id)) } = &d { + let id = if let (0, [Parachain(id)]) = d.unpack() { *id } else { *dest = Some(d); @@ -160,7 +160,7 @@ pub struct ToParachainDeliveryHelper< #[cfg(feature = "runtime-benchmarks")] impl< XcmConfig: xcm_executor::Config, - ExistentialDeposit: Get>, + ExistentialDeposit: Get>, PriceForDelivery: PriceForMessageDelivery, Parachain: Get, ToParachainHelper: EnsureForParachain, @@ -174,10 +174,10 @@ impl< > { fn ensure_successful_delivery( - origin_ref: &MultiLocation, - _dest: &MultiLocation, + origin_ref: &Location, + _dest: &Location, fee_reason: xcm_executor::traits::FeeReason, - ) -> (Option, Option) { + ) -> (Option, Option) { use xcm_executor::{ traits::{FeeManager, TransactAsset}, FeesMode, @@ -234,7 +234,7 @@ mod tests { parameter_types! { pub const BaseDeliveryFee: u128 = 300_000_000; pub const TransactionByteFee: u128 = 1_000_000; - pub FeeAssetId: AssetId = Concrete(Here.into()); + pub FeeAssetId: AssetId = AssetId(Here.into()); } struct TestFeeTracker; diff --git a/polkadot/runtime/parachains/src/coretime/migration.rs b/polkadot/runtime/parachains/src/coretime/migration.rs index c720cf0617a..e64d3fbd6a9 100644 --- a/polkadot/runtime/parachains/src/coretime/migration.rs +++ b/polkadot/runtime/parachains/src/coretime/migration.rs @@ -46,9 +46,7 @@ mod v_coretime { #[cfg(feature = "try-runtime")] use sp_std::vec::Vec; use sp_std::{iter, prelude::*, result}; - use xcm::v3::{ - send_xcm, Instruction, Junction, Junctions, MultiLocation, SendError, WeightLimit, Xcm, - }; + use xcm::v4::{send_xcm, Instruction, Junction, Location, SendError, WeightLimit, Xcm}; /// Return information about a legacy lease of a parachain. pub trait GetLegacyLease { @@ -64,7 +62,7 @@ mod v_coretime { sp_std::marker::PhantomData<(T, SendXcm, LegacyLease)>, ); - impl>> + impl>> MigrateToCoretime { fn already_migrated() -> bool { @@ -95,7 +93,7 @@ mod v_coretime { impl< T: Config + crate::dmp::Config, - SendXcm: xcm::v3::SendXcm, + SendXcm: xcm::v4::SendXcm, LegacyLease: GetLegacyLease>, > OnRuntimeUpgrade for MigrateToCoretime { @@ -155,7 +153,7 @@ mod v_coretime { // NOTE: Also migrates coretime_cores config value in configuration::ActiveConfig. fn migrate_to_coretime< T: Config, - SendXcm: xcm::v3::SendXcm, + SendXcm: xcm::v4::SendXcm, LegacyLease: GetLegacyLease>, >() -> Weight { let legacy_paras = paras::Pallet::::parachains(); @@ -209,7 +207,7 @@ mod v_coretime { fn migrate_send_assignments_to_coretime_chain< T: Config, - SendXcm: xcm::v3::SendXcm, + SendXcm: xcm::v4::SendXcm, LegacyLease: GetLegacyLease>, >() -> result::Result<(), SendError> { let legacy_paras = paras::Pallet::::parachains(); @@ -280,10 +278,7 @@ mod v_coretime { for message in messages { send_xcm::( - MultiLocation { - parents: 0, - interior: Junctions::X1(Junction::Parachain(T::BrokerId::get())), - }, + Location::new(0, Junction::Parachain(T::BrokerId::get())), message, )?; } diff --git a/polkadot/runtime/parachains/src/coretime/mod.rs b/polkadot/runtime/parachains/src/coretime/mod.rs index aa074a293c9..531f5c2e4e4 100644 --- a/polkadot/runtime/parachains/src/coretime/mod.rs +++ b/polkadot/runtime/parachains/src/coretime/mod.rs @@ -26,10 +26,7 @@ pub use pallet::*; use pallet_broker::{CoreAssignment, CoreIndex as BrokerCoreIndex}; use primitives::{CoreIndex, Id as ParaId}; use sp_arithmetic::traits::SaturatedConversion; -use xcm::v3::{ - send_xcm, Instruction, Junction, Junctions, MultiLocation, OriginKind, SendXcm, WeightLimit, - Xcm, -}; +use xcm::v4::{send_xcm, Instruction, Junction, Location, OriginKind, SendXcm, WeightLimit, Xcm}; use crate::{ assigner_coretime::{self, PartsOf57600}, @@ -229,10 +226,7 @@ impl Pallet { mk_coretime_call(crate::coretime::CoretimeCalls::NotifyCoreCount(core_count)), ]); if let Err(err) = send_xcm::( - MultiLocation { - parents: 0, - interior: Junctions::X1(Junction::Parachain(T::BrokerId::get())), - }, + Location::new(0, [Junction::Parachain(T::BrokerId::get())]), message, ) { log::error!("Sending `NotifyCoreCount` to coretime chain failed: {:?}", err); diff --git a/polkadot/runtime/parachains/src/mock.rs b/polkadot/runtime/parachains/src/mock.rs index fbaab1d24aa..c08bab0ef0f 100644 --- a/polkadot/runtime/parachains/src/mock.rs +++ b/polkadot/runtime/parachains/src/mock.rs @@ -52,7 +52,7 @@ use sp_runtime::{ }; use sp_std::collections::vec_deque::VecDeque; use std::{cell::RefCell, collections::HashMap}; -use xcm::v3::{MultiAssets, MultiLocation, SendError, SendResult, SendXcm, Xcm, XcmHash}; +use xcm::v4::{Assets, Location, SendError, SendResult, SendXcm, Xcm, XcmHash}; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlockU32; @@ -384,11 +384,8 @@ impl coretime::Config for Test { pub struct DummyXcmSender; impl SendXcm for DummyXcmSender { type Ticket = (); - fn validate( - _: &mut Option, - _: &mut Option>, - ) -> SendResult { - Ok(((), MultiAssets::new())) + fn validate(_: &mut Option, _: &mut Option>) -> SendResult { + Ok(((), Assets::new())) } /// Actually carry out the delivery operation for a previously validated message sending. diff --git a/polkadot/runtime/rococo/src/impls.rs b/polkadot/runtime/rococo/src/impls.rs index eddbfacc3b1..ac7100d7858 100644 --- a/polkadot/runtime/rococo/src/impls.rs +++ b/polkadot/runtime/rococo/src/impls.rs @@ -22,7 +22,7 @@ use primitives::Balance; use rococo_runtime_constants::currency::*; use runtime_common::identity_migrator::{OnReapIdentity, WeightInfo}; use sp_std::{marker::PhantomData, prelude::*}; -use xcm::{latest::prelude::*, VersionedMultiLocation, VersionedXcm}; +use xcm::{latest::prelude::*, VersionedLocation, VersionedXcm}; use xcm_executor::traits::TransactAsset; /// A type containing the encoding of the People Chain pallets in its runtime. Used to construct any @@ -95,9 +95,9 @@ where let total_to_send = Self::calculate_remote_deposit(fields, subs); // define asset / destination from relay perspective - let roc = MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(total_to_send) }; + let roc = Asset { id: AssetId(Here.into_location()), fun: Fungible(total_to_send) }; // People Chain: ParaId 1004 - let destination: MultiLocation = MultiLocation::new(0, Parachain(1004)); + let destination: Location = Location::new(0, Parachain(1004)); // Do `check_out` accounting since the XCM Executor's `InitiateTeleport` doesn't support // unpaid teleports. @@ -138,11 +138,9 @@ where ); // reanchor - let roc_reanchored: MultiAssets = vec![MultiAsset { - id: Concrete(MultiLocation::new(1, Here)), - fun: Fungible(total_to_send), - }] - .into(); + let roc_reanchored: Assets = + vec![Asset { id: AssetId(Location::new(1, Here)), fun: Fungible(total_to_send) }] + .into(); let poke = PeopleRuntimePallets::::IdentityMigrator(PokeDeposit(who.clone())); let remote_weight_limit = MigratorWeights::::poke_deposit().saturating_mul(2); @@ -172,8 +170,8 @@ where // send let _ = >::send( RawOrigin::Root.into(), - Box::new(VersionedMultiLocation::V3(destination)), - Box::new(VersionedXcm::V3(program)), + Box::new(VersionedLocation::V4(destination)), + Box::new(VersionedXcm::V4(program)), )?; Ok(()) } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index e492caddc8f..fec82fc86f9 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -35,7 +35,7 @@ use rococo_runtime_constants::system_parachain::BROKER_ID; use runtime_common::{ assigned_slots, auctions, claims, crowdloan, identity_migrator, impl_runtime_weights, impls::{ - LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, VersionedMultiLocationConverter, + LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, VersionedLocationConverter, }, paras_registrar, paras_sudo_wrapper, prod_or_fast, slots, traits::Leaser, @@ -99,10 +99,7 @@ use sp_staking::SessionIndex; #[cfg(any(feature = "std", test))] use sp_version::NativeVersion; use sp_version::RuntimeVersion; -use xcm::{ - latest::{InteriorMultiLocation, Junction, Junction::PalletInstance}, - VersionedMultiLocation, -}; +use xcm::{latest::prelude::*, VersionedLocation}; use xcm_builder::PayOverXcm; pub use frame_system::Call as SystemCall; @@ -461,7 +458,7 @@ parameter_types! { pub const PayoutSpendPeriod: BlockNumber = 30 * DAYS; // The asset's interior location for the paying account. This is the Treasury // pallet instance (which sits at index 18). - pub TreasuryInteriorLocation: InteriorMultiLocation = PalletInstance(18).into(); + pub TreasuryInteriorLocation: InteriorLocation = PalletInstance(18).into(); pub const TipCountdown: BlockNumber = 1 * DAYS; pub const TipFindersFee: Percent = Percent::from_percent(20); @@ -492,7 +489,7 @@ impl pallet_treasury::Config for Runtime { type SpendFunds = Bounties; type SpendOrigin = TreasurySpender; type AssetKind = VersionedLocatableAsset; - type Beneficiary = VersionedMultiLocation; + type Beneficiary = VersionedLocation; type BeneficiaryLookup = IdentityLookup; type Paymaster = PayOverXcm< TreasuryInteriorLocation, @@ -502,7 +499,7 @@ impl pallet_treasury::Config for Runtime { Self::Beneficiary, Self::AssetKind, LocatableAssetConverter, - VersionedMultiLocationConverter, + VersionedLocationConverter, >; type BalanceConverter = AssetRate; type PayoutPeriod = PayoutSpendPeriod; @@ -538,7 +535,7 @@ impl pallet_bounties::Config for Runtime { parameter_types! { pub const MaxActiveChildBountyCount: u32 = 100; - pub const ChildBountyValueMinimum: Balance = BountyValueMinimum::get() / 10; + pub ChildBountyValueMinimum: Balance = BountyValueMinimum::get() / 10; } impl pallet_child_bounties::Config for Runtime { @@ -1209,7 +1206,7 @@ impl pallet_nis::Config for Runtime { } parameter_types! { - pub const BeefySetIdSessionEntries: u32 = BondingDuration::get() * SessionsPerEra::get(); + pub BeefySetIdSessionEntries: u32 = BondingDuration::get() * SessionsPerEra::get(); } impl pallet_beefy::Config for Runtime { @@ -2270,7 +2267,7 @@ sp_api::impl_runtime_apis! { }; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( TokenLocation::get(), ExistentialDeposit::get() ).into()); @@ -2280,34 +2277,34 @@ sp_api::impl_runtime_apis! { impl frame_system_benchmarking::Config for Runtime {} impl frame_benchmarking::baseline::Config for Runtime {} impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(crate::xcm_config::AssetHub::get()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported to/from AH. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Here.into()) + id: AssetId(Here.into()) }, crate::xcm_config::AssetHub::get(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Relay can reserve transfer native token to some random parachain. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Here.into()) + id: AssetId(Here.into()) }, Parachain(43211234).into(), )) } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(Assets, u32, Location, Box)> { // Relay supports only native token, either reserve transfer it to non-system parachains, // or teleport it to system parachain. Use the teleport case for benchmarking as it's // slightly heavier. @@ -2325,29 +2322,29 @@ sp_api::impl_runtime_apis! { type AccountIdConverter = LocationConverter; type DeliveryHelper = runtime_common::xcm_sender::ToParachainDeliveryHelper< XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForChildParachainDelivery, ToParachain, (), >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(AssetHub::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // Rococo only knows about ROC - vec![MultiAsset{ - id: Concrete(TokenLocation::get()), + vec![Asset{ + id: AssetId(TokenLocation::get()), fun: Fungible(1_000_000 * UNITS), }].into() } } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub TrustedTeleporter: Option<(Location, Asset)> = Some(( AssetHub::get(), - MultiAsset { fun: Fungible(1 * UNITS), id: Concrete(TokenLocation::get()) }, + Asset { fun: Fungible(1 * UNITS), id: AssetId(TokenLocation::get()) }, )); - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -2357,9 +2354,9 @@ sp_api::impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(TokenLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(TokenLocation::get()), fun: Fungible(1 * UNITS), } } @@ -2373,43 +2370,43 @@ sp_api::impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { // Rococo doesn't support asset exchanges Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { // The XCM executor of Rococo doesn't have a configured `UniversalAliases` Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((AssetHub::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(AssetHub::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = AssetHub::get(); - let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(TokenLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { // Rococo doesn't support asset locking Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { // Rococo doesn't support exporting messages Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { // The XCM executor of Rococo doesn't have a configured `Aliasers` Err(BenchmarkError::Skip) } diff --git a/polkadot/runtime/rococo/src/weights/xcm/mod.rs b/polkadot/runtime/rococo/src/weights/xcm/mod.rs index cc485dfbaf7..12f3df897b1 100644 --- a/polkadot/runtime/rococo/src/weights/xcm/mod.rs +++ b/polkadot/runtime/rococo/src/weights/xcm/mod.rs @@ -33,25 +33,25 @@ pub enum AssetTypes { Unknown, } -impl From<&MultiAsset> for AssetTypes { - fn from(asset: &MultiAsset) -> Self { +impl From<&Asset> for AssetTypes { + fn from(asset: &Asset) -> Self { match asset { - MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: Here }), .. } => + Asset { id: AssetId(Location { parents: 0, interior: Here }), .. } => AssetTypes::Balances, _ => AssetTypes::Unknown, } } } -trait WeighMultiAssets { - fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, balances_weight: Weight) -> Weight; } // Rococo only knows about one asset, the balances pallet. const MAX_ASSETS: u64 = 1; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, balances_weight: Weight) -> Weight { match self { Self::Definite(assets) => assets .inner() @@ -72,11 +72,11 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, balances_weight: Weight) -> Weight { self.inner() .into_iter() - .map(|m| >::from(m)) + .map(|m| >::from(m)) .map(|t| match t { AssetTypes::Balances => balances_weight, AssetTypes::Unknown => Weight::MAX, @@ -87,32 +87,28 @@ impl WeighMultiAssets for MultiAssets { pub struct RococoXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for RococoXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::transfer_reserve_asset()) } fn transact( _origin_kind: &OriginKind, @@ -140,45 +136,37 @@ impl XcmWeightInfo for RococoXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { // Rococo does not currently support exchange asset operations Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmBalancesWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -193,7 +181,7 @@ impl XcmWeightInfo for RococoXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -205,13 +193,13 @@ impl XcmWeightInfo for RococoXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -246,19 +234,19 @@ impl XcmWeightInfo for RococoXcmWeight { // Rococo relay should not support export message operations Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { // Rococo does not currently support asset locking operations Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { // Rococo does not currently support asset locking operations Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { // Rococo does not currently support asset locking operations Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { // Rococo does not currently support asset locking operations Weight::MAX } @@ -271,19 +259,19 @@ impl XcmWeightInfo for RococoXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } #[test] fn all_counted_has_a_sane_weight_upper_limit() { - let assets = MultiAssetFilter::Wild(AllCounted(4294967295)); + let assets = AssetFilter::Wild(AllCounted(4294967295)); let weight = Weight::from_parts(1000, 1000); - assert_eq!(assets.weigh_multi_assets(weight), weight * MAX_ASSETS); + assert_eq!(assets.weigh_assets(weight), weight * MAX_ASSETS); } diff --git a/polkadot/runtime/rococo/src/xcm_config.rs b/polkadot/runtime/rococo/src/xcm_config.rs index f3a2ca6f3a6..bfa9beb8209 100644 --- a/polkadot/runtime/rococo/src/xcm_config.rs +++ b/polkadot/runtime/rococo/src/xcm_config.rs @@ -24,8 +24,8 @@ use super::{ use crate::governance::StakingAdmin; use frame_support::{ - match_types, parameter_types, - traits::{Equals, Everything, Nothing}, + parameter_types, + traits::{Contains, Equals, Everything, Nothing}, weights::Weight, }; use frame_system::EnsureRoot; @@ -50,10 +50,10 @@ use xcm_builder::{ use xcm_executor::XcmExecutor; parameter_types! { - pub const RootLocation: MultiLocation = MultiLocation::here(); - pub const TokenLocation: MultiLocation = Here.into_location(); + pub TokenLocation: Location = Here.into_location(); + pub RootLocation: Location = Location::here(); pub const ThisNetwork: NetworkId = NetworkId::Rococo; - pub UniversalLocation: InteriorMultiLocation = ThisNetwork::get().into(); + pub UniversalLocation: InteriorLocation = ThisNetwork::get().into(); pub CheckAccount: AccountId = XcmPallet::check_account(); pub LocalCheckAccount: (AccountId, MintLocation) = (CheckAccount::get(), MintLocation::Local); pub TreasuryAccount: AccountId = Treasury::account_id(); @@ -69,7 +69,7 @@ pub type LocationConverter = ( ); /// Our asset transactor. This is what allows us to interest with the runtime facilities from the -/// point of view of XCM-only concepts like `MultiLocation` and `MultiAsset`. +/// point of view of XCM-only concepts like `Location` and `Asset`. /// /// Ours is only aware of the Balances pallet, which is mapped to `RocLocation`. #[allow(deprecated)] @@ -78,7 +78,7 @@ pub type LocalAssetTransactor = XcmCurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // We can convert the MultiLocations with our converter above: + // We can convert the Locations with our converter above: LocationConverter, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -100,7 +100,7 @@ parameter_types! { /// The amount of weight an XCM operation takes. This is a safe overestimate. pub const BaseXcmWeight: Weight = Weight::from_parts(1_000_000_000, 64 * 1024); /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(TokenLocation::get()); + pub FeeAssetId: AssetId = AssetId(TokenLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -116,25 +116,25 @@ pub type XcmRouter = WithUniqueTopic< >; parameter_types! { - pub const Roc: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(TokenLocation::get()) }); - pub const AssetHub: MultiLocation = Parachain(ASSET_HUB_ID).into_location(); - pub const Contracts: MultiLocation = Parachain(CONTRACTS_ID).into_location(); - pub const Encointer: MultiLocation = Parachain(ENCOINTER_ID).into_location(); - pub const BridgeHub: MultiLocation = Parachain(BRIDGE_HUB_ID).into_location(); - pub const People: MultiLocation = Parachain(PEOPLE_ID).into_location(); - pub const Broker: MultiLocation = Parachain(BROKER_ID).into_location(); - pub const Tick: MultiLocation = Parachain(100).into_location(); - pub const Trick: MultiLocation = Parachain(110).into_location(); - pub const Track: MultiLocation = Parachain(120).into_location(); - pub const RocForTick: (MultiAssetFilter, MultiLocation) = (Roc::get(), Tick::get()); - pub const RocForTrick: (MultiAssetFilter, MultiLocation) = (Roc::get(), Trick::get()); - pub const RocForTrack: (MultiAssetFilter, MultiLocation) = (Roc::get(), Track::get()); - pub const RocForAssetHub: (MultiAssetFilter, MultiLocation) = (Roc::get(), AssetHub::get()); - pub const RocForContracts: (MultiAssetFilter, MultiLocation) = (Roc::get(), Contracts::get()); - pub const RocForEncointer: (MultiAssetFilter, MultiLocation) = (Roc::get(), Encointer::get()); - pub const RocForBridgeHub: (MultiAssetFilter, MultiLocation) = (Roc::get(), BridgeHub::get()); - pub const RocForPeople: (MultiAssetFilter, MultiLocation) = (Roc::get(), People::get()); - pub const RocForBroker: (MultiAssetFilter, MultiLocation) = (Roc::get(), Broker::get()); + pub Roc: AssetFilter = Wild(AllOf { fun: WildFungible, id: AssetId(TokenLocation::get()) }); + pub AssetHub: Location = Parachain(ASSET_HUB_ID).into_location(); + pub Contracts: Location = Parachain(CONTRACTS_ID).into_location(); + pub Encointer: Location = Parachain(ENCOINTER_ID).into_location(); + pub BridgeHub: Location = Parachain(BRIDGE_HUB_ID).into_location(); + pub People: Location = Parachain(PEOPLE_ID).into_location(); + pub Broker: Location = Parachain(BROKER_ID).into_location(); + pub Tick: Location = Parachain(100).into_location(); + pub Trick: Location = Parachain(110).into_location(); + pub Track: Location = Parachain(120).into_location(); + pub RocForTick: (AssetFilter, Location) = (Roc::get(), Tick::get()); + pub RocForTrick: (AssetFilter, Location) = (Roc::get(), Trick::get()); + pub RocForTrack: (AssetFilter, Location) = (Roc::get(), Track::get()); + pub RocForAssetHub: (AssetFilter, Location) = (Roc::get(), AssetHub::get()); + pub RocForContracts: (AssetFilter, Location) = (Roc::get(), Contracts::get()); + pub RocForEncointer: (AssetFilter, Location) = (Roc::get(), Encointer::get()); + pub RocForBridgeHub: (AssetFilter, Location) = (Roc::get(), BridgeHub::get()); + pub RocForPeople: (AssetFilter, Location) = (Roc::get(), People::get()); + pub RocForBroker: (AssetFilter, Location) = (Roc::get(), Broker::get()); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; } @@ -150,13 +150,18 @@ pub type TrustedTeleporters = ( xcm_builder::Case, ); -match_types! { - pub type OnlyParachains: impl Contains = { - MultiLocation { parents: 0, interior: X1(Parachain(_)) } - }; - pub type LocalPlurality: impl Contains = { - MultiLocation { parents: 0, interior: X1(Plurality { .. }) } - }; +pub struct OnlyParachains; +impl Contains for OnlyParachains { + fn contains(loc: &Location) -> bool { + matches!(loc.unpack(), (0, [Parachain(_)])) + } +} + +pub struct LocalPlurality; +impl Contains for LocalPlurality { + fn contains(loc: &Location) -> bool { + matches!(loc.unpack(), (0, [Plurality { .. }])) + } } /// The barriers one of which must be passed for an XCM message to be executed. @@ -227,26 +232,26 @@ parameter_types! { pub const FellowsBodyId: BodyId = BodyId::Technical; } -/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior +/// Type to convert an `Origin` type value into a `Location` value which represents an interior /// location of this chain. pub type LocalOriginToLocation = ( // And a usual Signed origin to be used in XCM as a corresponding AccountId32 SignedToAccountId32, ); -/// Type to convert the `StakingAdmin` origin to a Plurality `MultiLocation` value. +/// Type to convert the `StakingAdmin` origin to a Plurality `Location` value. pub type StakingAdminToPlurality = OriginToPluralityVoice; -/// Type to convert the Fellows origin to a Plurality `MultiLocation` value. +/// Type to convert the Fellows origin to a Plurality `Location` value. pub type FellowsToPlurality = OriginToPluralityVoice; -/// Type to convert a pallet `Origin` type value into a `MultiLocation` value which represents an +/// Type to convert a pallet `Origin` type value into a `Location` value which represents an /// interior location of this chain for a destination chain. pub type LocalPalletOriginToLocation = ( - // StakingAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + // StakingAdmin origin to be used in XCM as a corresponding Plurality `Location` value. StakingAdminToPlurality, - // Fellows origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + // Fellows origin to be used in XCM as a corresponding Plurality `Location` value. FellowsToPlurality, ); diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index f472b619ba7..e80412232d0 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -604,7 +604,7 @@ pub mod pallet_test_notifier { pub enum Event { QueryPrepared(QueryId), NotifyQueryPrepared(QueryId), - ResponseReceived(MultiLocation, QueryId, Response), + ResponseReceived(Location, QueryId, Response), } #[pallet::error] diff --git a/polkadot/runtime/test-runtime/src/xcm_config.rs b/polkadot/runtime/test-runtime/src/xcm_config.rs index ae4faecf700..d9d3d6e0752 100644 --- a/polkadot/runtime/test-runtime/src/xcm_config.rs +++ b/polkadot/runtime/test-runtime/src/xcm_config.rs @@ -27,7 +27,7 @@ use xcm_builder::{ }; use xcm_executor::{ traits::{TransactAsset, WeightTrader}, - Assets, + AssetsInHolding, }; parameter_types! { @@ -35,10 +35,10 @@ parameter_types! { pub const AnyNetwork: Option = None; pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 16; - pub const UniversalLocation: xcm::latest::InteriorMultiLocation = xcm::latest::Junctions::Here; + pub const UniversalLocation: xcm::latest::InteriorLocation = xcm::latest::Junctions::Here; } -/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior +/// Type to convert an `Origin` type value into a `Location` value which represents an interior /// location of this chain. pub type LocalOriginToLocation = ( // And a usual Signed origin to be used in XCM as a corresponding AccountId32 @@ -48,8 +48,8 @@ pub type LocalOriginToLocation = ( pub struct DoNothingRouter; impl SendXcm for DoNothingRouter { type Ticket = (); - fn validate(_dest: &mut Option, _msg: &mut Option>) -> SendResult<()> { - Ok(((), MultiAssets::new())) + fn validate(_dest: &mut Option, _msg: &mut Option>) -> SendResult<()> { + Ok(((), Assets::new())) } fn deliver(_: ()) -> Result { Ok([0; 32]) @@ -60,20 +60,16 @@ pub type Barrier = AllowUnpaidExecutionFrom; pub struct DummyAssetTransactor; impl TransactAsset for DummyAssetTransactor { - fn deposit_asset( - _what: &MultiAsset, - _who: &MultiLocation, - _context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(_what: &Asset, _who: &Location, _context: Option<&XcmContext>) -> XcmResult { Ok(()) } fn withdraw_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _maybe_context: Option<&XcmContext>, - ) -> Result { - let asset: MultiAsset = (Parent, 100_000).into(); + ) -> Result { + let asset: Asset = (Parent, 100_000).into(); Ok(asset.into()) } } @@ -87,10 +83,10 @@ impl WeightTrader for DummyWeightTrader { fn buy_weight( &mut self, _weight: Weight, - _payment: Assets, + _payment: AssetsInHolding, _context: &XcmContext, - ) -> Result { - Ok(Assets::default()) + ) -> Result { + Ok(AssetsInHolding::default()) } } diff --git a/polkadot/runtime/westend/src/impls.rs b/polkadot/runtime/westend/src/impls.rs index 5f23bd373b1..71e6b696a20 100644 --- a/polkadot/runtime/westend/src/impls.rs +++ b/polkadot/runtime/westend/src/impls.rs @@ -22,7 +22,7 @@ use primitives::Balance; use runtime_common::identity_migrator::{OnReapIdentity, WeightInfo}; use sp_std::{marker::PhantomData, prelude::*}; use westend_runtime_constants::currency::*; -use xcm::{latest::prelude::*, VersionedMultiLocation, VersionedXcm}; +use xcm::{latest::prelude::*, VersionedLocation, VersionedXcm}; use xcm_executor::traits::TransactAsset; /// A type containing the encoding of the People Chain pallets in its runtime. Used to construct any @@ -95,9 +95,9 @@ where let total_to_send = Self::calculate_remote_deposit(fields, subs); // define asset / destination from relay perspective - let wnd = MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(total_to_send) }; + let wnd = Asset { id: AssetId(Here.into_location()), fun: Fungible(total_to_send) }; // People Chain: ParaId 1004 - let destination: MultiLocation = MultiLocation::new(0, Parachain(1004)); + let destination: Location = Location::new(0, Parachain(1004)); // Do `check_out` accounting since the XCM Executor's `InitiateTeleport` doesn't support // unpaid teleports. @@ -138,11 +138,9 @@ where ); // reanchor - let wnd_reanchored: MultiAssets = vec![MultiAsset { - id: Concrete(MultiLocation::new(1, Here)), - fun: Fungible(total_to_send), - }] - .into(); + let wnd_reanchored: Assets = + vec![Asset { id: AssetId(Location::new(1, Here)), fun: Fungible(total_to_send) }] + .into(); let poke = PeopleRuntimePallets::::IdentityMigrator(PokeDeposit(who.clone())); let remote_weight_limit = MigratorWeights::::poke_deposit().saturating_mul(2); @@ -172,8 +170,8 @@ where // send let _ = >::send( RawOrigin::Root.into(), - Box::new(VersionedMultiLocation::V3(destination)), - Box::new(VersionedXcm::V3(program)), + Box::new(VersionedLocation::V4(destination)), + Box::new(VersionedXcm::V4(program)), )?; Ok(()) } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index e1416c4b754..92efdf0c0c5 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -59,7 +59,7 @@ use runtime_common::{ elections::OnChainAccuracy, identity_migrator, impl_runtime_weights, impls::{ - LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, VersionedMultiLocationConverter, + LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, VersionedLocationConverter, }, paras_registrar, paras_sudo_wrapper, prod_or_fast, slots, BalanceToU256, BlockHashCount, BlockLength, CurrencyToVote, SlowAdjustingFeeUpdate, U256ToBalance, @@ -98,8 +98,8 @@ use sp_std::{collections::btree_map::BTreeMap, prelude::*}; use sp_version::NativeVersion; use sp_version::RuntimeVersion; use xcm::{ - latest::{InteriorMultiLocation, Junction, Junction::PalletInstance}, - VersionedMultiLocation, + latest::{InteriorLocation, Junction, Junction::PalletInstance}, + VersionedLocation, }; use xcm_builder::PayOverXcm; @@ -714,7 +714,7 @@ parameter_types! { pub const PayoutSpendPeriod: BlockNumber = 30 * DAYS; // The asset's interior location for the paying account. This is the Treasury // pallet instance (which sits at index 37). - pub TreasuryInteriorLocation: InteriorMultiLocation = PalletInstance(37).into(); + pub TreasuryInteriorLocation: InteriorLocation = PalletInstance(37).into(); pub const TipCountdown: BlockNumber = 1 * DAYS; pub const TipFindersFee: Percent = Percent::from_percent(20); @@ -745,7 +745,7 @@ impl pallet_treasury::Config for Runtime { type SpendFunds = (); type SpendOrigin = TreasurySpender; type AssetKind = VersionedLocatableAsset; - type Beneficiary = VersionedMultiLocation; + type Beneficiary = VersionedLocation; type BeneficiaryLookup = IdentityLookup; type Paymaster = PayOverXcm< TreasuryInteriorLocation, @@ -755,7 +755,7 @@ impl pallet_treasury::Config for Runtime { Self::Beneficiary, Self::AssetKind, LocatableAssetConverter, - VersionedMultiLocationConverter, + VersionedLocationConverter, >; type BalanceConverter = AssetRate; type PayoutPeriod = PayoutSpendPeriod; @@ -2286,31 +2286,31 @@ sp_api::impl_runtime_apis! { impl pallet_offences_benchmarking::Config for Runtime {} impl pallet_election_provider_support_benchmarking::Config for Runtime {} impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(crate::xcm_config::AssetHub::get()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported to/from AH. Some(( - MultiAsset { fun: Fungible(EXISTENTIAL_DEPOSIT), id: Concrete(Here.into()) }, + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), id: AssetId(Here.into()) }, crate::xcm_config::AssetHub::get(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Relay can reserve transfer native token to some random parachain. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Here.into()) + id: AssetId(Here.into()) }, crate::Junction::Parachain(43211234).into(), )) } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(Assets, u32, Location, Box)> { // Relay supports only native token, either reserve transfer it to non-system parachains, // or teleport it to system parachain. Use the teleport case for benchmarking as it's // slightly heavier. @@ -2329,13 +2329,13 @@ sp_api::impl_runtime_apis! { impl runtime_parachains::disputes::slashing::benchmarking::Config for Runtime {} use xcm::latest::{ - AssetId::*, Fungibility::*, InteriorMultiLocation, Junction, Junctions::*, - MultiAsset, MultiAssets, MultiLocation, NetworkId, Response, + AssetId, Fungibility::*, InteriorLocation, Junction, Junctions::*, + Asset, Assets, Location, NetworkId, Response, }; use xcm_config::{AssetHub, TokenLocation}; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( TokenLocation::get(), ExistentialDeposit::get() ).into()); @@ -2347,29 +2347,29 @@ sp_api::impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationConverter; type DeliveryHelper = runtime_common::xcm_sender::ToParachainDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForChildParachainDelivery, ToParachain, (), >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(AssetHub::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // Westend only knows about WND. - vec![MultiAsset{ - id: Concrete(TokenLocation::get()), + vec![Asset{ + id: AssetId(TokenLocation::get()), fun: Fungible(1_000_000 * UNITS), }].into() } } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub TrustedTeleporter: Option<(Location, Asset)> = Some(( AssetHub::get(), - MultiAsset { fun: Fungible(1 * UNITS), id: Concrete(TokenLocation::get()) }, + Asset { fun: Fungible(1 * UNITS), id: AssetId(TokenLocation::get()) }, )); - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -2379,9 +2379,9 @@ sp_api::impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(TokenLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(TokenLocation::get()), fun: Fungible(1 * UNITS), } } @@ -2395,43 +2395,43 @@ sp_api::impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { // Westend doesn't support asset exchanges Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { // The XCM executor of Westend doesn't have a configured `UniversalAliases` Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((AssetHub::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(AssetHub::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = AssetHub::get(); - let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(TokenLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { // Westend doesn't support asset locking Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { // Westend doesn't support exporting messages Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { // The XCM executor of Westend doesn't have a configured `Aliasers` Err(BenchmarkError::Skip) } @@ -2503,12 +2503,11 @@ mod remote_tests { mod clean_state_migration { use super::Runtime; + #[cfg(feature = "try-runtime")] + use super::Vec; use frame_support::{pallet_prelude::*, storage_alias, traits::OnRuntimeUpgrade}; use pallet_state_trie_migration::MigrationLimits; - #[cfg(not(feature = "std"))] - use sp_std::prelude::*; - #[storage_alias] type AutoLimits = StorageValue, ValueQuery>; diff --git a/polkadot/runtime/westend/src/weights/xcm/mod.rs b/polkadot/runtime/westend/src/weights/xcm/mod.rs index d5b3d8257ba..0162012825f 100644 --- a/polkadot/runtime/westend/src/weights/xcm/mod.rs +++ b/polkadot/runtime/westend/src/weights/xcm/mod.rs @@ -36,25 +36,25 @@ pub enum AssetTypes { Unknown, } -impl From<&MultiAsset> for AssetTypes { - fn from(asset: &MultiAsset) -> Self { +impl From<&Asset> for AssetTypes { + fn from(asset: &Asset) -> Self { match asset { - MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: Here }), .. } => + Asset { id: AssetId(Location { parents: 0, interior: Here }), .. } => AssetTypes::Balances, _ => AssetTypes::Unknown, } } } -trait WeighMultiAssets { - fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, balances_weight: Weight) -> Weight; } // Westend only knows about one asset, the balances pallet. const MAX_ASSETS: u64 = 1; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, balances_weight: Weight) -> Weight { match self { Self::Definite(assets) => assets .inner() @@ -75,11 +75,11 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, balances_weight: Weight) -> Weight { self.inner() .into_iter() - .map(|m| >::from(m)) + .map(|m| >::from(m)) .map(|t| match t { AssetTypes::Balances => balances_weight, AssetTypes::Unknown => Weight::MAX, @@ -90,32 +90,28 @@ impl WeighMultiAssets for MultiAssets { pub struct WestendXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for WestendXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::transfer_reserve_asset()) } fn transact( _origin_kind: &OriginKind, @@ -143,45 +139,37 @@ impl XcmWeightInfo for WestendXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_repsonse_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { // Westend does not currently support exchange asset operations Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmBalancesWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -196,7 +184,7 @@ impl XcmWeightInfo for WestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -208,13 +196,13 @@ impl XcmWeightInfo for WestendXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -249,19 +237,19 @@ impl XcmWeightInfo for WestendXcmWeight { // Westend relay should not support export message operations Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { // Westend does not currently support asset locking operations Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { // Westend does not currently support asset locking operations Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { // Westend does not currently support asset locking operations Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { // Westend does not currently support asset locking operations Weight::MAX } @@ -274,19 +262,19 @@ impl XcmWeightInfo for WestendXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } #[test] fn all_counted_has_a_sane_weight_upper_limit() { - let assets = MultiAssetFilter::Wild(AllCounted(4294967295)); + let assets = AssetFilter::Wild(AllCounted(4294967295)); let weight = Weight::from_parts(1000, 1000); - assert_eq!(assets.weigh_multi_assets(weight), weight * MAX_ASSETS); + assert_eq!(assets.weigh_assets(weight), weight * MAX_ASSETS); } diff --git a/polkadot/runtime/westend/src/xcm_config.rs b/polkadot/runtime/westend/src/xcm_config.rs index e4b4f50f663..3c052057d90 100644 --- a/polkadot/runtime/westend/src/xcm_config.rs +++ b/polkadot/runtime/westend/src/xcm_config.rs @@ -23,8 +23,8 @@ use super::{ }; use crate::governance::pallet_custom_origins::Treasurer; use frame_support::{ - match_types, parameter_types, - traits::{Equals, Everything, Nothing}, + parameter_types, + traits::{Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; use pallet_xcm::XcmPassthrough; @@ -53,15 +53,15 @@ use xcm_builder::{ use xcm_executor::XcmExecutor; parameter_types! { - pub const RootLocation: MultiLocation = MultiLocation::here(); - pub const TokenLocation: MultiLocation = Here.into_location(); + pub const TokenLocation: Location = Here.into_location(); + pub const RootLocation: Location = Location::here(); pub const ThisNetwork: NetworkId = Westend; - pub const UniversalLocation: InteriorMultiLocation = X1(GlobalConsensus(ThisNetwork::get())); + pub UniversalLocation: InteriorLocation = [GlobalConsensus(ThisNetwork::get())].into(); pub CheckAccount: AccountId = XcmPallet::check_account(); pub LocalCheckAccount: (AccountId, MintLocation) = (CheckAccount::get(), MintLocation::Local); pub TreasuryAccount: AccountId = Treasury::account_id(); /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(TokenLocation::get()); + pub FeeAssetId: AssetId = AssetId(TokenLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -81,7 +81,7 @@ pub type LocalAssetTransactor = XcmCurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // We can convert the MultiLocations with our converter above: + // We can convert the Locations with our converter above: LocationConverter, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -114,17 +114,17 @@ pub type XcmRouter = WithUniqueTopic< >; parameter_types! { - pub const AssetHub: MultiLocation = Parachain(ASSET_HUB_ID).into_location(); - pub const Collectives: MultiLocation = Parachain(COLLECTIVES_ID).into_location(); - pub const BridgeHub: MultiLocation = Parachain(BRIDGE_HUB_ID).into_location(); - pub const People: MultiLocation = Parachain(PEOPLE_ID).into_location(); - pub const Wnd: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(TokenLocation::get()) }); - pub const WndForAssetHub: (MultiAssetFilter, MultiLocation) = (Wnd::get(), AssetHub::get()); - pub const WndForCollectives: (MultiAssetFilter, MultiLocation) = (Wnd::get(), Collectives::get()); - pub const WndForBridgeHub: (MultiAssetFilter, MultiLocation) = (Wnd::get(), BridgeHub::get()); - pub const WndForPeople: (MultiAssetFilter, MultiLocation) = (Wnd::get(), People::get()); - pub const MaxInstructions: u32 = 100; - pub const MaxAssetsIntoHolding: u32 = 64; + pub AssetHub: Location = Parachain(ASSET_HUB_ID).into_location(); + pub Collectives: Location = Parachain(COLLECTIVES_ID).into_location(); + pub BridgeHub: Location = Parachain(BRIDGE_HUB_ID).into_location(); + pub People: Location = Parachain(PEOPLE_ID).into_location(); + pub Wnd: AssetFilter = Wild(AllOf { fun: WildFungible, id: AssetId(TokenLocation::get()) }); + pub WndForAssetHub: (AssetFilter, Location) = (Wnd::get(), AssetHub::get()); + pub WndForCollectives: (AssetFilter, Location) = (Wnd::get(), Collectives::get()); + pub WndForBridgeHub: (AssetFilter, Location) = (Wnd::get(), BridgeHub::get()); + pub WndForPeople: (AssetFilter, Location) = (Wnd::get(), People::get()); + pub MaxInstructions: u32 = 100; + pub MaxAssetsIntoHolding: u32 = 64; } pub type TrustedTeleporters = ( @@ -134,17 +134,29 @@ pub type TrustedTeleporters = ( xcm_builder::Case, ); -match_types! { - pub type OnlyParachains: impl Contains = { - MultiLocation { parents: 0, interior: X1(Parachain(_)) } - }; - pub type CollectivesOrFellows: impl Contains = { - MultiLocation { parents: 0, interior: X1(Parachain(COLLECTIVES_ID)) } | - MultiLocation { parents: 0, interior: X2(Parachain(COLLECTIVES_ID), Plurality { id: BodyId::Technical, .. }) } - }; - pub type LocalPlurality: impl Contains = { - MultiLocation { parents: 0, interior: X1(Plurality { .. }) } - }; +pub struct OnlyParachains; +impl Contains for OnlyParachains { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (0, [Parachain(_)])) + } +} + +pub struct CollectivesOrFellows; +impl Contains for CollectivesOrFellows { + fn contains(location: &Location) -> bool { + matches!( + location.unpack(), + (0, [Parachain(COLLECTIVES_ID)]) | + (0, [Parachain(COLLECTIVES_ID), Plurality { id: BodyId::Technical, .. }]) + ) + } +} + +pub struct LocalPlurality; +impl Contains for LocalPlurality { + fn contains(loc: &Location) -> bool { + matches!(loc.unpack(), (0, [Plurality { .. }])) + } } /// The barriers one of which must be passed for an XCM message to be executed. @@ -218,11 +230,10 @@ parameter_types! { pub const TreasurerBodyId: BodyId = BodyId::Index(TREASURER_INDEX); } -/// Type to convert the `GeneralAdmin` origin to a Plurality `MultiLocation` value. +/// Type to convert the `GeneralAdmin` origin to a Plurality `Location` value. pub type GeneralAdminToPlurality = OriginToPluralityVoice; -/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior /// location of this chain. pub type LocalOriginToLocation = ( GeneralAdminToPlurality, @@ -230,25 +241,25 @@ pub type LocalOriginToLocation = ( SignedToAccountId32, ); -/// Type to convert the `StakingAdmin` origin to a Plurality `MultiLocation` value. +/// Type to convert the `StakingAdmin` origin to a Plurality `Location` value. pub type StakingAdminToPlurality = OriginToPluralityVoice; -/// Type to convert the `FellowshipAdmin` origin to a Plurality `MultiLocation` value. +/// Type to convert the `FellowshipAdmin` origin to a Plurality `Location` value. pub type FellowshipAdminToPlurality = OriginToPluralityVoice; -/// Type to convert the `Treasurer` origin to a Plurality `MultiLocation` value. +/// Type to convert the `Treasurer` origin to a Plurality `Location` value. pub type TreasurerToPlurality = OriginToPluralityVoice; -/// Type to convert a pallet `Origin` type value into a `MultiLocation` value which represents an +/// Type to convert a pallet `Origin` type value into a `Location` value which represents an /// interior location of this chain for a destination chain. pub type LocalPalletOriginToLocation = ( - // GeneralAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + // GeneralAdmin origin to be used in XCM as a corresponding Plurality `Location` value. GeneralAdminToPlurality, - // StakingAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + // StakingAdmin origin to be used in XCM as a corresponding Plurality `Location` value. StakingAdminToPlurality, - // FellowshipAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + // FellowshipAdmin origin to be used in XCM as a corresponding Plurality `Location` value. FellowshipAdminToPlurality, // `Treasurer` origin to be used in XCM as a corresponding Plurality `MultiLocation` value. TreasurerToPlurality, diff --git a/polkadot/xcm/Cargo.toml b/polkadot/xcm/Cargo.toml index 89e3728a361..1103e07adbb 100644 --- a/polkadot/xcm/Cargo.toml +++ b/polkadot/xcm/Cargo.toml @@ -18,7 +18,7 @@ log = { version = "0.4.17", default-features = false } parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive", "max-encoded-len"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive", "serde"] } sp-weights = { path = "../../substrate/primitives/weights", default-features = false, features = ["serde"] } -serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive"] } +serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive", "rc"] } schemars = { version = "0.8.13", default-features = true, optional = true } xcm-procedural = { path = "procedural" } environmental = { version = "1.1.4", default-features = false } diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs index d32eb8d4a52..e96ec48fcba 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs @@ -24,7 +24,7 @@ use frame_support::{ }; use sp_runtime::traits::{Bounded, Zero}; use sp_std::{prelude::*, vec}; -use xcm::latest::{prelude::*, MAX_ITEMS_IN_MULTIASSETS}; +use xcm::latest::{prelude::*, MAX_ITEMS_IN_ASSETS}; use xcm_executor::traits::{ConvertLocation, FeeReason, TransactAsset}; benchmarks_instance_pallet! { @@ -43,7 +43,7 @@ benchmarks_instance_pallet! { withdraw_asset { let (sender_account, sender_location) = account_and_location::(1); let worst_case_holding = T::worst_case_holding(0); - let asset = T::get_multi_asset(); + let asset = T::get_asset(); >::deposit_asset(&asset, &sender_location, None).unwrap(); // check the assets of origin. @@ -63,8 +63,8 @@ benchmarks_instance_pallet! { transfer_asset { let (sender_account, sender_location) = account_and_location::(1); - let asset = T::get_multi_asset(); - let assets: MultiAssets = vec![ asset.clone() ].into(); + let asset = T::get_asset(); + let assets: Assets = vec![ asset.clone() ].into(); // this xcm doesn't use holding let dest_location = T::valid_destination()?; @@ -95,10 +95,10 @@ benchmarks_instance_pallet! { ); let sender_account_balance_before = T::TransactAsset::balance(&sender_account); - let asset = T::get_multi_asset(); + let asset = T::get_asset(); >::deposit_asset(&asset, &sender_location, None).unwrap(); assert!(T::TransactAsset::balance(&sender_account) > sender_account_balance_before); - let assets: MultiAssets = vec![ asset ].into(); + let assets: Assets = vec![asset].into(); assert!(T::TransactAsset::balance(&dest_account).is_zero()); let mut executor = new_executor::(sender_location); @@ -129,7 +129,7 @@ benchmarks_instance_pallet! { BenchmarkResult::from_weight(Weight::MAX) ))?; - let assets: MultiAssets = vec![ transferable_reserve_asset ].into(); + let assets: Assets = vec![ transferable_reserve_asset ].into(); let mut executor = new_executor::(trusted_reserve); let instruction = Instruction::ReserveAssetDeposited(assets.clone()); @@ -143,7 +143,7 @@ benchmarks_instance_pallet! { initiate_reserve_withdraw { let (sender_account, sender_location) = account_and_location::(1); let holding = T::worst_case_holding(1); - let assets_filter = MultiAssetFilter::Definite(holding.clone().into_inner().into_iter().take(MAX_ITEMS_IN_MULTIASSETS).collect::>().into()); + let assets_filter = AssetFilter::Definite(holding.clone().into_inner().into_iter().take(MAX_ITEMS_IN_ASSETS).collect::>().into()); let reserve = T::valid_destination().map_err(|_| BenchmarkError::Skip)?; let (expected_fees_mode, expected_assets_in_holding) = T::DeliveryHelper::ensure_successful_delivery( @@ -188,7 +188,7 @@ benchmarks_instance_pallet! { )?; } - let assets: MultiAssets = vec![ teleportable_asset ].into(); + let assets: Assets = vec![ teleportable_asset ].into(); let mut executor = new_executor::(trusted_teleporter); let instruction = Instruction::ReceiveTeleportedAsset(assets.clone()); @@ -204,7 +204,7 @@ benchmarks_instance_pallet! { } deposit_asset { - let asset = T::get_multi_asset(); + let asset = T::get_asset(); let mut holding = T::worst_case_holding(1); // Add our asset to the holding. @@ -230,7 +230,7 @@ benchmarks_instance_pallet! { } deposit_reserve_asset { - let asset = T::get_multi_asset(); + let asset = T::get_asset(); let mut holding = T::worst_case_holding(1); // Add our asset to the holding. @@ -257,7 +257,7 @@ benchmarks_instance_pallet! { } initiate_teleport { - let asset = T::get_multi_asset(); + let asset = T::get_asset(); let mut holding = T::worst_case_holding(0); // Add our asset to the holding. diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs index 43892c31c7c..bb4b7ff6276 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs @@ -93,10 +93,10 @@ parameter_types! { pub struct MatchAnyFungible; impl xcm_executor::traits::MatchesFungible for MatchAnyFungible { - fn matches_fungible(m: &MultiAsset) -> Option { + fn matches_fungible(m: &Asset) -> Option { use sp_runtime::traits::SaturatedConversion; match m { - MultiAsset { fun: Fungible(amount), .. } => Some((*amount).saturated_into::()), + Asset { fun: Fungible(amount), .. } => Some((*amount).saturated_into::()), _ => None, } } @@ -151,13 +151,12 @@ impl crate::Config for Test { type XcmConfig = XcmConfig; type AccountIdConverter = AccountIdConverter; type DeliveryHelper = (); - fn valid_destination() -> Result { - let valid_destination: MultiLocation = - X1(AccountId32 { network: None, id: [0u8; 32] }).into(); + fn valid_destination() -> Result { + let valid_destination: Location = [AccountId32 { network: None, id: [0u8; 32] }].into(); Ok(valid_destination) } - fn worst_case_holding(depositable_count: u32) -> MultiAssets { + fn worst_case_holding(depositable_count: u32) -> Assets { crate::mock_worst_case_holding( depositable_count, ::MaxAssetsIntoHolding::get(), @@ -170,19 +169,19 @@ pub type TrustedReserves = xcm_builder::Case; parameter_types! { pub const CheckingAccount: Option<(u64, MintLocation)> = Some((100, MintLocation::Local)); - pub const ChildTeleporter: MultiLocation = Parachain(1000).into_location(); - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub ChildTeleporter: Location = Parachain(1000).into_location(); + pub TrustedTeleporter: Option<(Location, Asset)> = Some(( ChildTeleporter::get(), - MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(100) }, + Asset { id: AssetId(Here.into_location()), fun: Fungible(100) }, )); - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = Some(( + pub TrustedReserve: Option<(Location, Asset)> = Some(( ChildTeleporter::get(), - MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(100) }, + Asset { id: AssetId(Here.into_location()), fun: Fungible(100) }, )); - pub const TeleportConcreteFungible: (MultiAssetFilter, MultiLocation) = - (Wild(AllOf { fun: WildFungible, id: Concrete(Here.into_location()) }), ChildTeleporter::get()); - pub const ReserveConcreteFungible: (MultiAssetFilter, MultiLocation) = - (Wild(AllOf { fun: WildFungible, id: Concrete(Here.into_location()) }), ChildTeleporter::get()); + pub TeleportConcreteFungible: (AssetFilter, Location) = + (Wild(AllOf { fun: WildFungible, id: AssetId(Here.into_location()) }), ChildTeleporter::get()); + pub ReserveConcreteFungible: (AssetFilter, Location) = + (Wild(AllOf { fun: WildFungible, id: AssetId(Here.into_location()) }), ChildTeleporter::get()); } impl xcm_balances_benchmark::Config for Test { @@ -191,10 +190,10 @@ impl xcm_balances_benchmark::Config for Test { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { + fn get_asset() -> Asset { let amount = >::minimum_balance() as u128; - MultiAsset { id: Concrete(Here.into()), fun: Fungible(amount) } + Asset { id: AssetId(Here.into()), fun: Fungible(amount) } } } diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mod.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mod.rs index 292921eb595..e84355f4092 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mod.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mod.rs @@ -37,14 +37,14 @@ pub mod pallet { type CheckedAccount: Get>; /// A trusted location which we allow teleports from, and the asset we allow to teleport. - type TrustedTeleporter: Get>; + type TrustedTeleporter: Get>; /// A trusted location where reserve assets are stored, and the asset we allow to be /// reserves. - type TrustedReserve: Get>; + type TrustedReserve: Get>; /// Give me a fungible asset that your asset transactor is going to accept. - fn get_multi_asset() -> xcm::latest::MultiAsset; + fn get_asset() -> xcm::latest::Asset; } #[pallet::pallet] diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs index 50a7fe45e23..14d53c4ebf5 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs @@ -77,7 +77,7 @@ benchmarks! { let mut executor = new_executor::(Default::default()); executor.set_holding(holding); - let fee_asset = Concrete(Here.into()); + let fee_asset = AssetId(Here.into()); let instruction = Instruction::>::BuyExecution { fees: (fee_asset, 100_000_000u128).into(), // should be something inside of holding @@ -95,7 +95,7 @@ benchmarks! { let mut executor = new_executor::(Default::default()); let (query_id, response) = T::worst_case_response(); let max_weight = Weight::MAX; - let querier: Option = Some(Here.into()); + let querier: Option = Some(Here.into()); let instruction = Instruction::QueryResponse { query_id, response, max_weight, querier }; let xcm = Xcm(vec![instruction]); }: { @@ -174,15 +174,15 @@ benchmarks! { descend_origin { let mut executor = new_executor::(Default::default()); - let who = X2(OnlyChild, OnlyChild); - let instruction = Instruction::DescendOrigin(who); + let who = Junctions::from([OnlyChild, OnlyChild]); + let instruction = Instruction::DescendOrigin(who.clone()); let xcm = Xcm(vec![instruction]); } : { executor.bench_process(xcm)?; } verify { assert_eq!( executor.origin(), - &Some(MultiLocation { + &Some(Location { parents: 0, interior: who, }), @@ -242,7 +242,7 @@ benchmarks! { &origin, assets.clone().into(), &XcmContext { - origin: Some(origin), + origin: Some(origin.clone()), message_id: [0; 32], topic: None, }, @@ -279,7 +279,7 @@ benchmarks! { let origin = T::subscribe_origin()?; let query_id = Default::default(); let max_response_weight = Default::default(); - let mut executor = new_executor::(origin); + let mut executor = new_executor::(origin.clone()); let instruction = Instruction::SubscribeVersion { query_id, max_response_weight }; let xcm = Xcm(vec![instruction]); } : { @@ -299,14 +299,14 @@ benchmarks! { query_id, max_response_weight, &XcmContext { - origin: Some(origin), + origin: Some(origin.clone()), message_id: [0; 32], topic: None, }, ).map_err(|_| "Could not start subscription")?; assert!(::SubscriptionService::is_subscribed(&origin)); - let mut executor = new_executor::(origin); + let mut executor = new_executor::(origin.clone()); let instruction = Instruction::UnsubscribeVersion; let xcm = Xcm(vec![instruction]); } : { @@ -545,7 +545,7 @@ benchmarks! { } verify { use frame_support::traits::Get; let universal_location = ::UniversalLocation::get(); - assert_eq!(executor.origin(), &Some(X1(alias).relative_to(&universal_location))); + assert_eq!(executor.origin(), &Some(Junctions::from([alias]).relative_to(&universal_location))); } export_message { @@ -561,8 +561,8 @@ benchmarks! { let (expected_fees_mode, expected_assets_in_holding) = T::DeliveryHelper::ensure_successful_delivery( &origin, - &destination.into(), - FeeReason::Export { network, destination }, + &destination.clone().into(), + FeeReason::Export { network, destination: destination.clone() }, ); let sender_account = T::AccountIdConverter::convert_location(&origin).unwrap(); let sender_account_balance_before = T::TransactAsset::balance(&sender_account); @@ -575,7 +575,7 @@ benchmarks! { executor.set_holding(expected_assets_in_holding.into()); } let xcm = Xcm(vec![ExportMessage { - network, destination, xcm: inner_xcm, + network, destination: destination.clone(), xcm: inner_xcm, }]); }: { executor.bench_process(xcm)?; @@ -632,13 +632,13 @@ benchmarks! { let (unlocker, owner, asset) = T::unlockable_asset()?; - let mut executor = new_executor::(unlocker); + let mut executor = new_executor::(unlocker.clone()); // We first place the asset in lock first... ::AssetLocker::prepare_lock( unlocker, asset.clone(), - owner, + owner.clone(), ) .map_err(|_| BenchmarkError::Skip)? .enact() @@ -658,13 +658,13 @@ benchmarks! { let (unlocker, owner, asset) = T::unlockable_asset()?; - let mut executor = new_executor::(unlocker); + let mut executor = new_executor::(unlocker.clone()); // We first place the asset in lock first... ::AssetLocker::prepare_lock( unlocker, asset.clone(), - owner, + owner.clone(), ) .map_err(|_| BenchmarkError::Skip)? .enact() @@ -686,9 +686,9 @@ benchmarks! { // We first place the asset in lock first... ::AssetLocker::prepare_lock( - locker, + locker.clone(), asset.clone(), - owner, + owner.clone(), ) .map_err(|_| BenchmarkError::Skip)? .enact() @@ -739,7 +739,7 @@ benchmarks! { let mut executor = new_executor::(origin); - let instruction = Instruction::AliasOrigin(target); + let instruction = Instruction::AliasOrigin(target.clone()); let xcm = Xcm(vec![instruction]); }: { executor.bench_process(xcm)?; diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs index 6efd2304e28..4dd677217fc 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs @@ -19,16 +19,16 @@ use crate::{generic, mock::*, *}; use codec::Decode; use frame_support::{ - derive_impl, match_types, parameter_types, - traits::{Everything, OriginTrait}, + derive_impl, parameter_types, + traits::{Contains, Everything, OriginTrait}, weights::Weight, }; use sp_core::H256; use sp_runtime::traits::{BlakeTwo256, IdentityLookup, TrailingZeroInput}; use xcm_builder::{ test_utils::{ - Assets, TestAssetExchanger, TestAssetLocker, TestAssetTrap, TestSubscriptionService, - TestUniversalAliases, + AssetsInHolding, TestAssetExchanger, TestAssetLocker, TestAssetTrap, + TestSubscriptionService, TestUniversalAliases, }, AliasForeignAccountId32, AllowUnpaidExecutionFrom, }; @@ -81,19 +81,15 @@ impl frame_system::Config for Test { /// The benchmarks in this pallet should never need an asset transactor to begin with. pub struct NoAssetTransactor; impl xcm_executor::traits::TransactAsset for NoAssetTransactor { - fn deposit_asset( - _: &MultiAsset, - _: &MultiLocation, - _: Option<&XcmContext>, - ) -> Result<(), XcmError> { + fn deposit_asset(_: &Asset, _: &Location, _: Option<&XcmContext>) -> Result<(), XcmError> { unreachable!(); } fn withdraw_asset( - _: &MultiAsset, - _: &MultiLocation, + _: &Asset, + _: &Location, _: Option<&XcmContext>, - ) -> Result { + ) -> Result { unreachable!(); } } @@ -103,10 +99,11 @@ parameter_types! { pub const MaxAssetsIntoHolding: u32 = 64; } -match_types! { - pub type OnlyParachains: impl Contains = { - MultiLocation { parents: 0, interior: X1(Parachain(_)) } - }; +pub struct OnlyParachains; +impl Contains for OnlyParachains { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (0, [Parachain(_)])) + } } type Aliasers = AliasForeignAccountId32; @@ -153,13 +150,13 @@ impl crate::Config for Test { type XcmConfig = XcmConfig; type AccountIdConverter = AccountIdConverter; type DeliveryHelper = (); - fn valid_destination() -> Result { - let valid_destination: MultiLocation = + fn valid_destination() -> Result { + let valid_destination: Location = Junction::AccountId32 { network: None, id: [0u8; 32] }.into(); Ok(valid_destination) } - fn worst_case_holding(depositable_count: u32) -> MultiAssets { + fn worst_case_holding(depositable_count: u32) -> Assets { crate::mock_worst_case_holding( depositable_count, ::MaxAssetsIntoHolding::get(), @@ -172,48 +169,47 @@ impl generic::Config for Test { type RuntimeCall = RuntimeCall; fn worst_case_response() -> (u64, Response) { - let assets: MultiAssets = (Concrete(Here.into()), 100).into(); + let assets: Assets = (AssetId(Here.into()), 100).into(); (0, Response::Assets(assets)) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Ok(Default::default()) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Ok((Here.into(), GlobalConsensus(ByGenesis([0; 32])))) } fn transact_origin_and_runtime_call( - ) -> Result<(MultiLocation, ::RuntimeCall), BenchmarkError> { + ) -> Result<(Location, ::RuntimeCall), BenchmarkError> { Ok((Default::default(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(Default::default()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { - let assets: MultiAssets = (Concrete(Here.into()), 100).into(); - let ticket = MultiLocation { parents: 0, interior: X1(GeneralIndex(0)) }; + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { + let assets: Assets = (AssetId(Here.into()), 100).into(); + let ticket = Location { parents: 0, interior: [GeneralIndex(0)].into() }; Ok((Default::default(), ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { - let assets: MultiAsset = (Concrete(Here.into()), 100).into(); + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { + let assets: Asset = (AssetId(Here.into()), 100).into(); Ok((Default::default(), account_id_junction::(1).into(), assets)) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { // No MessageExporter in tests Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { - let origin: MultiLocation = - (Parachain(1), AccountId32 { network: None, id: [0; 32] }).into(); - let target: MultiLocation = AccountId32 { network: None, id: [0; 32] }.into(); + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { + let origin: Location = (Parachain(1), AccountId32 { network: None, id: [0; 32] }).into(); + let target: Location = AccountId32 { network: None, id: [0; 32] }.into(); Ok((origin, target)) } } @@ -233,9 +229,9 @@ where ::AccountId: Decode, { fn convert_origin( - _origin: impl Into, + _origin: impl Into, _kind: OriginKind, - ) -> Result { + ) -> Result { Ok(RuntimeOrigin::signed( ::AccountId::decode(&mut TrailingZeroInput::zeroes()) .expect("infinite length input; no invalid inputs for type; qed"), diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mod.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mod.rs index 11f7bba19a9..3728baea983 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mod.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mod.rs @@ -26,10 +26,7 @@ pub mod pallet { use frame_benchmarking::BenchmarkError; use frame_support::{dispatch::GetDispatchInfo, pallet_prelude::Encode}; use sp_runtime::traits::Dispatchable; - use xcm::latest::{ - InteriorMultiLocation, Junction, MultiAsset, MultiAssets, MultiLocation, NetworkId, - Response, - }; + use xcm::latest::{Asset, Assets, InteriorLocation, Junction, Location, NetworkId, Response}; #[pallet::config] pub trait Config: frame_system::Config + crate::Config { @@ -53,44 +50,44 @@ pub mod pallet { /// from, whereas the second element represents the assets that are being exchanged to. /// /// If set to `Err`, benchmarks which rely on an `exchange_asset` will be skipped. - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError>; + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError>; - /// A `(MultiLocation, Junction)` that is one of the `UniversalAliases` configured by the + /// A `(Location, Junction)` that is one of the `UniversalAliases` configured by the /// XCM executor. /// /// If set to `Err`, benchmarks which rely on a universal alias will be skipped. - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError>; + fn universal_alias() -> Result<(Location, Junction), BenchmarkError>; - /// The `MultiLocation` and `RuntimeCall` used for successful transaction XCMs. + /// The `Location` and `RuntimeCall` used for successful transaction XCMs. /// /// If set to `Err`, benchmarks which rely on a `transact_origin_and_runtime_call` will be /// skipped. fn transact_origin_and_runtime_call( - ) -> Result<(MultiLocation, >::RuntimeCall), BenchmarkError>; + ) -> Result<(Location, >::RuntimeCall), BenchmarkError>; - /// A valid `MultiLocation` we can successfully subscribe to. + /// A valid `Location` we can successfully subscribe to. /// /// If set to `Err`, benchmarks which rely on a `subscribe_origin` will be skipped. - fn subscribe_origin() -> Result; + fn subscribe_origin() -> Result; /// Return an origin, ticket, and assets that can be trapped and claimed. - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError>; + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError>; /// Return an unlocker, owner and assets that can be locked and unlocked. - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError>; + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError>; - /// A `(MultiLocation, NetworkId, InteriorMultiLocation)` we can successfully export message + /// A `(Location, NetworkId, InteriorLocation)` we can successfully export message /// to. /// /// If set to `Err`, benchmarks which rely on `export_message` will be skipped. fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError>; + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError>; - /// A `(MultiLocation, MultiLocation)` that is one of the `Aliasers` configured by the XCM + /// A `(Location, Location)` that is one of the `Aliasers` configured by the XCM /// executor. /// /// If set to `Err`, benchmarks which rely on a universal alias will be skipped. - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError>; + fn alias_origin() -> Result<(Location, Location), BenchmarkError>; /// Returns a valid pallet info for `ExpectPallet` or `QueryPallet` benchmark. /// diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs index 3bf4aea1b25..6ce8d3e99e8 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs @@ -41,18 +41,18 @@ pub trait Config: frame_system::Config { /// `TransactAsset` is implemented. type XcmConfig: XcmConfig; - /// A converter between a multi-location to a sovereign account. + /// A converter between a location to a sovereign account. type AccountIdConverter: ConvertLocation; /// Helper that ensures successful delivery for XCM instructions which need `SendXcm`. type DeliveryHelper: EnsureDelivery; /// Does any necessary setup to create a valid destination for XCM messages. - /// Returns that destination's multi-location to be used in benchmarks. - fn valid_destination() -> Result; + /// Returns that destination's location to be used in benchmarks. + fn valid_destination() -> Result; /// Worst case scenario for a holding account in this runtime. - fn worst_case_holding(depositable_count: u32) -> MultiAssets; + fn worst_case_holding(depositable_count: u32) -> Assets; } const SEED: u32 = 0; @@ -66,21 +66,21 @@ pub type AssetTransactorOf = <::XcmConfig as XcmConfig>::AssetTr /// The call type of executor's config. Should eventually resolve to the same overarching call type. pub type XcmCallOf = <::XcmConfig as XcmConfig>::RuntimeCall; -pub fn mock_worst_case_holding(depositable_count: u32, max_assets: u32) -> MultiAssets { +pub fn mock_worst_case_holding(depositable_count: u32, max_assets: u32) -> Assets { let fungibles_amount: u128 = 100; let holding_fungibles = max_assets / 2 - depositable_count; let holding_non_fungibles = holding_fungibles; (0..holding_fungibles) .map(|i| { - MultiAsset { - id: Concrete(GeneralIndex(i as u128).into()), + Asset { + id: AssetId(GeneralIndex(i as u128).into()), fun: Fungible(fungibles_amount * i as u128), } .into() }) - .chain(core::iter::once(MultiAsset { id: Concrete(Here.into()), fun: Fungible(u128::MAX) })) - .chain((0..holding_non_fungibles).map(|i| MultiAsset { - id: Concrete(GeneralIndex(i as u128).into()), + .chain(core::iter::once(Asset { id: AssetId(Here.into()), fun: Fungible(u128::MAX) })) + .chain((0..holding_non_fungibles).map(|i| Asset { + id: AssetId(GeneralIndex(i as u128).into()), fun: NonFungible(asset_instance_from(i)), })) .collect::>() @@ -94,11 +94,11 @@ pub fn asset_instance_from(x: u32) -> AssetInstance { AssetInstance::Array4(instance) } -pub fn new_executor(origin: MultiLocation) -> ExecutorOf { +pub fn new_executor(origin: Location) -> ExecutorOf { ExecutorOf::::new(origin, [0; 32]) } -/// Build a multi-location from an account id. +/// Build a location from an account id. fn account_id_junction(index: u32) -> Junction { let account: T::AccountId = account("account", index, SEED); let mut encoded = account.encode(); @@ -108,8 +108,8 @@ fn account_id_junction(index: u32) -> Junction { Junction::AccountId32 { network: None, id } } -pub fn account_and_location(index: u32) -> (T::AccountId, MultiLocation) { - let location: MultiLocation = account_id_junction::(index).into(); +pub fn account_and_location(index: u32) -> (T::AccountId, Location) { + let location: Location = account_id_junction::(index).into(); let account = T::AccountIdConverter::convert_location(&location).unwrap(); (account, location) @@ -121,21 +121,21 @@ pub trait EnsureDelivery { /// Prepare all requirements for successful `XcmSender: SendXcm` passing (accounts, balances, /// channels ...). Returns: /// - possible `FeesMode` which is expected to be set to executor - /// - possible `MultiAssets` which are expected to be subsume to the Holding Register + /// - possible `Assets` which are expected to be subsume to the Holding Register fn ensure_successful_delivery( - origin_ref: &MultiLocation, - dest: &MultiLocation, + origin_ref: &Location, + dest: &Location, fee_reason: FeeReason, - ) -> (Option, Option); + ) -> (Option, Option); } /// `()` implementation does nothing which means no special requirements for environment. impl EnsureDelivery for () { fn ensure_successful_delivery( - _origin_ref: &MultiLocation, - _dest: &MultiLocation, + _origin_ref: &Location, + _dest: &Location, _fee_reason: FeeReason, - ) -> (Option, Option) { + ) -> (Option, Option) { // doing nothing (None, None) } diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/mock.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/mock.rs index e02c5bf0861..78a9e5f8a01 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/mock.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/mock.rs @@ -22,8 +22,8 @@ use xcm::latest::Weight; pub struct DevNull; impl xcm::opaque::latest::SendXcm for DevNull { type Ticket = (); - fn validate(_: &mut Option, _: &mut Option>) -> SendResult<()> { - Ok(((), MultiAssets::new())) + fn validate(_: &mut Option, _: &mut Option>) -> SendResult<()> { + Ok(((), Assets::new())) } fn deliver(_: ()) -> Result { Ok([0; 32]) @@ -31,13 +31,13 @@ impl xcm::opaque::latest::SendXcm for DevNull { } impl xcm_executor::traits::OnResponse for DevNull { - fn expecting_response(_: &MultiLocation, _: u64, _: Option<&MultiLocation>) -> bool { + fn expecting_response(_: &Location, _: u64, _: Option<&Location>) -> bool { false } fn on_response( - _: &MultiLocation, + _: &Location, _: u64, - _: Option<&MultiLocation>, + _: Option<&Location>, _: Response, _: Weight, _: &XcmContext, @@ -48,9 +48,9 @@ impl xcm_executor::traits::OnResponse for DevNull { pub struct AccountIdConverter; impl xcm_executor::traits::ConvertLocation for AccountIdConverter { - fn convert_location(ml: &MultiLocation) -> Option { - match ml { - MultiLocation { parents: 0, interior: X1(Junction::AccountId32 { id, .. }) } => + fn convert_location(ml: &Location) -> Option { + match ml.unpack() { + (0, [Junction::AccountId32 { id, .. }]) => Some(::decode(&mut &*id.to_vec()).unwrap()), _ => None, } @@ -58,14 +58,14 @@ impl xcm_executor::traits::ConvertLocation for AccountIdConverter { } parameter_types! { - pub UniversalLocation: InteriorMultiLocation = Junction::Parachain(101).into(); + pub UniversalLocation: InteriorLocation = Junction::Parachain(101).into(); pub UnitWeightCost: Weight = Weight::from_parts(10, 10); - pub WeightPrice: (AssetId, u128, u128) = (Concrete(Here.into()), 1_000_000, 1024); + pub WeightPrice: (AssetId, u128, u128) = (AssetId(Here.into()), 1_000_000, 1024); } pub struct AllAssetLocationsPass; -impl ContainsPair for AllAssetLocationsPass { - fn contains(_: &MultiAsset, _: &MultiLocation) -> bool { +impl ContainsPair for AllAssetLocationsPass { + fn contains(_: &Asset, _: &Location) -> bool { true } } diff --git a/polkadot/xcm/pallet-xcm/src/benchmarking.rs b/polkadot/xcm/pallet-xcm/src/benchmarking.rs index 28a198f40a0..c7d8fb24e9d 100644 --- a/polkadot/xcm/pallet-xcm/src/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm/src/benchmarking.rs @@ -32,36 +32,36 @@ pub struct Pallet(crate::Pallet); /// Trait that must be implemented by runtime to be able to benchmark pallet properly. pub trait Config: crate::Config { - /// A `MultiLocation` that can be reached via `XcmRouter`. Used only in benchmarks. + /// A `Location` that can be reached via `XcmRouter`. Used only in benchmarks. /// /// If `None`, the benchmarks that depend on a reachable destination will be skipped. - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { None } - /// A `(MultiAsset, MultiLocation)` pair representing asset and the destination it can be + /// A `(Asset, Location)` pair representing asset and the destination it can be /// teleported to. Used only in benchmarks. /// /// Implementation should also make sure `dest` is reachable/connected. /// /// If `None`, the benchmarks that depend on this will default to `Weight::MAX`. - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { None } - /// A `(MultiAsset, MultiLocation)` pair representing asset and the destination it can be + /// A `(Asset, Location)` pair representing asset and the destination it can be /// reserve-transferred to. Used only in benchmarks. /// /// Implementation should also make sure `dest` is reachable/connected. /// /// If `None`, the benchmarks that depend on this will default to `Weight::MAX`. - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { None } /// Sets up a complex transfer (usually consisting of a teleport and reserve-based transfer), so /// that runtime can properly benchmark `transfer_assets()` extrinsic. Should return a tuple - /// `(MultiAsset, u32, MultiLocation, dyn FnOnce())` representing the assets to transfer, the + /// `(Asset, u32, Location, dyn FnOnce())` representing the assets to transfer, the /// `u32` index of the asset to be used for fees, the destination chain for the transfer, and a /// `verify()` closure to verify the intended transfer side-effects. /// @@ -71,8 +71,7 @@ pub trait Config: crate::Config { /// Used only in benchmarks. /// /// If `None`, the benchmarks that depend on this will default to `Weight::MAX`. - fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + fn set_up_complex_asset_transfer() -> Option<(Assets, u32, Location, Box)> { None } } @@ -90,7 +89,7 @@ benchmarks! { return Err(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX))) } let msg = Xcm(vec![ClearOrigin]); - let versioned_dest: VersionedMultiLocation = T::reachable_dest().ok_or( + let versioned_dest: VersionedLocation = T::reachable_dest().ok_or( BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)), )? .into(); @@ -106,7 +105,7 @@ benchmarks! { Fungible(amount) => *amount, _ => return Err(BenchmarkError::Stop("Benchmark asset not fungible")), }.into(); - let assets: MultiAssets = asset.into(); + let assets: Assets = asset.into(); let existential_deposit = T::ExistentialDeposit::get(); let caller = whitelisted_caller(); @@ -126,10 +125,10 @@ benchmarks! { } let recipient = [0u8; 32]; - let versioned_dest: VersionedMultiLocation = destination.into(); - let versioned_beneficiary: VersionedMultiLocation = + let versioned_dest: VersionedLocation = destination.into(); + let versioned_beneficiary: VersionedLocation = AccountId32 { network: None, id: recipient.into() }.into(); - let versioned_assets: VersionedMultiAssets = assets.into(); + let versioned_assets: VersionedAssets = assets.into(); }: _>(send_origin.into(), Box::new(versioned_dest), Box::new(versioned_beneficiary), Box::new(versioned_assets), 0) verify { // verify balance after transfer, decreased by transferred amount (+ maybe XCM delivery fees) @@ -145,7 +144,7 @@ benchmarks! { Fungible(amount) => *amount, _ => return Err(BenchmarkError::Stop("Benchmark asset not fungible")), }.into(); - let assets: MultiAssets = asset.into(); + let assets: Assets = asset.into(); let existential_deposit = T::ExistentialDeposit::get(); let caller = whitelisted_caller(); @@ -165,10 +164,10 @@ benchmarks! { } let recipient = [0u8; 32]; - let versioned_dest: VersionedMultiLocation = destination.into(); - let versioned_beneficiary: VersionedMultiLocation = + let versioned_dest: VersionedLocation = destination.into(); + let versioned_beneficiary: VersionedLocation = AccountId32 { network: None, id: recipient.into() }.into(); - let versioned_assets: VersionedMultiAssets = assets.into(); + let versioned_assets: VersionedAssets = assets.into(); }: _>(send_origin.into(), Box::new(versioned_dest), Box::new(versioned_beneficiary), Box::new(versioned_assets), 0) verify { // verify balance after transfer, decreased by transferred amount (+ maybe XCM delivery fees) @@ -182,10 +181,10 @@ benchmarks! { let caller: T::AccountId = whitelisted_caller(); let send_origin = RawOrigin::Signed(caller.clone()); let recipient = [0u8; 32]; - let versioned_dest: VersionedMultiLocation = destination.into(); - let versioned_beneficiary: VersionedMultiLocation = + let versioned_dest: VersionedLocation = destination.into(); + let versioned_beneficiary: VersionedLocation = AccountId32 { network: None, id: recipient.into() }.into(); - let versioned_assets: VersionedMultiAssets = assets.into(); + let versioned_assets: VersionedAssets = assets.into(); }: _>(send_origin.into(), Box::new(versioned_dest), Box::new(versioned_beneficiary), Box::new(versioned_assets), 0, WeightLimit::Unlimited) verify { // run provided verification function @@ -214,7 +213,7 @@ benchmarks! { force_default_xcm_version {}: _(RawOrigin::Root, Some(2)) force_subscribe_version_notify { - let versioned_loc: VersionedMultiLocation = T::reachable_dest().ok_or( + let versioned_loc: VersionedLocation = T::reachable_dest().ok_or( BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)), )? .into(); @@ -224,7 +223,7 @@ benchmarks! { let loc = T::reachable_dest().ok_or( BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)), )?; - let versioned_loc: VersionedMultiLocation = loc.into(); + let versioned_loc: VersionedLocation = loc.clone().into(); let _ = crate::Pallet::::request_version_notify(loc); }: _(RawOrigin::Root, Box::new(versioned_loc)) @@ -232,7 +231,7 @@ benchmarks! { migrate_supported_version { let old_version = XCM_VERSION - 1; - let loc = VersionedMultiLocation::from(MultiLocation::from(Parent)); + let loc = VersionedLocation::from(Location::from(Parent)); SupportedVersion::::insert(old_version, loc, old_version); }: { crate::Pallet::::check_xcm_version_change(VersionMigrationStage::MigrateSupportedVersion, Weight::zero()); @@ -240,7 +239,7 @@ benchmarks! { migrate_version_notifiers { let old_version = XCM_VERSION - 1; - let loc = VersionedMultiLocation::from(MultiLocation::from(Parent)); + let loc = VersionedLocation::from(Location::from(Parent)); VersionNotifiers::::insert(old_version, loc, 0); }: { crate::Pallet::::check_xcm_version_change(VersionMigrationStage::MigrateVersionNotifiers, Weight::zero()); @@ -250,7 +249,7 @@ benchmarks! { let loc = T::reachable_dest().ok_or( BenchmarkError::Override(BenchmarkResult::from_weight(T::DbWeight::get().reads(1))), )?; - let loc = VersionedMultiLocation::from(loc); + let loc = VersionedLocation::from(loc); let current_version = T::AdvertisedXcmVersion::get(); VersionNotifyTargets::::insert(current_version, loc, (0, Weight::zero(), current_version)); }: { @@ -261,7 +260,7 @@ benchmarks! { let loc = T::reachable_dest().ok_or( BenchmarkError::Override(BenchmarkResult::from_weight(T::DbWeight::get().reads_writes(1, 3))), )?; - let loc = VersionedMultiLocation::from(loc); + let loc = VersionedLocation::from(loc); let current_version = T::AdvertisedXcmVersion::get(); let old_version = current_version - 1; VersionNotifyTargets::::insert(current_version, loc, (0, Weight::zero(), old_version)); @@ -276,7 +275,7 @@ benchmarks! { part: v2::BodyPart::Voice, } .into(); - let bad_loc = VersionedMultiLocation::from(bad_loc); + let bad_loc = VersionedLocation::from(bad_loc); let current_version = T::AdvertisedXcmVersion::get(); VersionNotifyTargets::::insert(current_version, bad_loc, (0, Weight::zero(), current_version)); }: { @@ -286,7 +285,7 @@ benchmarks! { migrate_version_notify_targets { let current_version = T::AdvertisedXcmVersion::get(); let old_version = current_version - 1; - let loc = VersionedMultiLocation::from(MultiLocation::from(Parent)); + let loc = VersionedLocation::from(Location::from(Parent)); VersionNotifyTargets::::insert(old_version, loc, (0, Weight::zero(), current_version)); }: { crate::Pallet::::check_xcm_version_change(VersionMigrationStage::MigrateAndNotifyOldTargets, Weight::zero()); @@ -296,7 +295,7 @@ benchmarks! { let loc = T::reachable_dest().ok_or( BenchmarkError::Override(BenchmarkResult::from_weight(T::DbWeight::get().reads_writes(1, 3))), )?; - let loc = VersionedMultiLocation::from(loc); + let loc = VersionedLocation::from(loc); let old_version = T::AdvertisedXcmVersion::get() - 1; VersionNotifyTargets::::insert(old_version, loc, (0, Weight::zero(), old_version)); }: { @@ -304,17 +303,17 @@ benchmarks! { } new_query { - let responder = MultiLocation::from(Parent); + let responder = Location::from(Parent); let timeout = 1u32.into(); - let match_querier = MultiLocation::from(Here); + let match_querier = Location::from(Here); }: { crate::Pallet::::new_query(responder, timeout, match_querier); } take_response { - let responder = MultiLocation::from(Parent); + let responder = Location::from(Parent); let timeout = 1u32.into(); - let match_querier = MultiLocation::from(Here); + let match_querier = Location::from(Here); let query_id = crate::Pallet::::new_query(responder, timeout, match_querier); let infos = (0 .. xcm::v3::MaxPalletsInfo::get()).map(|_| PalletInfo::new( u32::MAX, @@ -340,17 +339,17 @@ benchmarks! { pub mod helpers { use super::*; pub fn native_teleport_as_asset_transfer( - native_asset_location: MultiLocation, - destination: MultiLocation, - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> + native_asset_location: Location, + destination: Location, + ) -> Option<(Assets, u32, Location, Box)> where T: Config + pallet_balances::Config, u128: From<::Balance>, { // Relay/native token can be teleported to/from AH. let amount = T::ExistentialDeposit::get() * 100u32.into(); - let assets: MultiAssets = - MultiAsset { fun: Fungible(amount.into()), id: Concrete(native_asset_location) }.into(); + let assets: Assets = + Asset { fun: Fungible(amount.into()), id: AssetId(native_asset_location) }.into(); let fee_index = 0u32; // Give some multiple of transferred amount diff --git a/polkadot/xcm/pallet-xcm/src/lib.rs b/polkadot/xcm/pallet-xcm/src/lib.rs index 2848527f150..55154198a9b 100644 --- a/polkadot/xcm/pallet-xcm/src/lib.rs +++ b/polkadot/xcm/pallet-xcm/src/lib.rs @@ -59,7 +59,7 @@ use xcm_executor::{ DropAssets, MatchesFungible, OnResponse, Properties, QueryHandler, QueryResponseStatus, TransactAsset, TransferType, VersionChangeNotifier, WeightBounds, XcmAssetTransfers, }, - Assets, + AssetsInHolding, }; pub trait WeightInfo { @@ -202,45 +202,39 @@ pub mod pallet { // TODO: We should really use a trait which can handle multiple currencies. type Currency: LockableCurrency>; - /// The `MultiAsset` matcher for `Currency`. + /// The `Asset` matcher for `Currency`. type CurrencyMatcher: MatchesFungible>; - /// Required origin for sending XCM messages. If successful, it resolves to `MultiLocation` + /// Required origin for sending XCM messages. If successful, it resolves to `Location` /// which exists as an interior location within this chain's XCM context. - type SendXcmOrigin: EnsureOrigin< - ::RuntimeOrigin, - Success = MultiLocation, - >; + type SendXcmOrigin: EnsureOrigin<::RuntimeOrigin, Success = Location>; /// The type used to actually dispatch an XCM to its destination. type XcmRouter: SendXcm; /// Required origin for executing XCM messages, including the teleport functionality. If - /// successful, then it resolves to `MultiLocation` which exists as an interior location + /// successful, then it resolves to `Location` which exists as an interior location /// within this chain's XCM context. - type ExecuteXcmOrigin: EnsureOrigin< - ::RuntimeOrigin, - Success = MultiLocation, - >; + type ExecuteXcmOrigin: EnsureOrigin<::RuntimeOrigin, Success = Location>; /// Our XCM filter which messages to be executed using `XcmExecutor` must pass. - type XcmExecuteFilter: Contains<(MultiLocation, Xcm<::RuntimeCall>)>; + type XcmExecuteFilter: Contains<(Location, Xcm<::RuntimeCall>)>; /// Something to execute an XCM message. type XcmExecutor: ExecuteXcm<::RuntimeCall> + XcmAssetTransfers; /// Our XCM filter which messages to be teleported using the dedicated extrinsic must pass. - type XcmTeleportFilter: Contains<(MultiLocation, Vec)>; + type XcmTeleportFilter: Contains<(Location, Vec)>; /// Our XCM filter which messages to be reserve-transferred using the dedicated extrinsic /// must pass. - type XcmReserveTransferFilter: Contains<(MultiLocation, Vec)>; + type XcmReserveTransferFilter: Contains<(Location, Vec)>; /// Means of measuring the weight consumed by an XCM message locally. type Weigher: WeightBounds<::RuntimeCall>; /// This chain's Universal Location. - type UniversalLocation: Get; + type UniversalLocation: Get; /// The runtime `Origin` type. type RuntimeOrigin: From + From<::RuntimeOrigin>; @@ -264,9 +258,9 @@ pub mod pallet { /// The assets which we consider a given origin is trusted if they claim to have placed a /// lock. - type TrustedLockers: ContainsPair; + type TrustedLockers: ContainsPair; - /// How to get an `AccountId` value from a `MultiLocation`, useful for handling asset locks. + /// How to get an `AccountId` value from a `Location`, useful for handling asset locks. type SovereignAccountOf: ConvertLocation; /// The maximum number of local XCM locks that a single account may have. @@ -296,15 +290,15 @@ pub mod pallet { max_weight: Weight, ) -> Result { let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; - let hash = message.using_encoded(sp_io::hashing::blake2_256); + let mut hash = message.using_encoded(sp_io::hashing::blake2_256); let message = (*message).try_into().map_err(|()| Error::::BadVersion)?; let value = (origin_location, message); ensure!(T::XcmExecuteFilter::contains(&value), Error::::Filtered); let (origin_location, message) = value; - let outcome = T::XcmExecutor::execute_xcm_in_credit( + let outcome = T::XcmExecutor::prepare_and_execute( origin_location, message, - hash, + &mut hash, max_weight, max_weight, ); @@ -323,17 +317,17 @@ pub mod pallet { type WeightInfo = Self; fn send( origin: OriginFor, - dest: Box, + dest: Box, message: Box>, ) -> Result { let origin_location = T::SendXcmOrigin::ensure_origin(origin)?; let interior: Junctions = - origin_location.try_into().map_err(|_| Error::::InvalidOrigin)?; - let dest = MultiLocation::try_from(*dest).map_err(|()| Error::::BadVersion)?; + origin_location.clone().try_into().map_err(|_| Error::::InvalidOrigin)?; + let dest = Location::try_from(*dest).map_err(|()| Error::::BadVersion)?; let message: Xcm<()> = (*message).try_into().map_err(|()| Error::::BadVersion)?; - let message_id = - Self::send_xcm(interior, dest, message.clone()).map_err(Error::::from)?; + let message_id = Self::send_xcm(interior, dest.clone(), message.clone()) + .map_err(Error::::from)?; let e = Event::Sent { origin: origin_location, destination: dest, message, message_id }; Self::deposit_event(e); Ok(message_id) @@ -355,13 +349,13 @@ pub mod pallet { fn query( origin: OriginFor, timeout: BlockNumberFor, - match_querier: VersionedMultiLocation, + match_querier: VersionedLocation, ) -> Result { let responder = ::ExecuteXcmOrigin::ensure_origin(origin)?; let query_id = ::new_query( responder, timeout, - MultiLocation::try_from(match_querier) + Location::try_from(match_querier) .map_err(|_| Into::::into(Error::::BadVersion))?, ); @@ -375,16 +369,11 @@ pub mod pallet { /// Execution of an XCM message was attempted. Attempted { outcome: xcm::latest::Outcome }, /// A XCM message was sent. - Sent { - origin: MultiLocation, - destination: MultiLocation, - message: Xcm<()>, - message_id: XcmHash, - }, + Sent { origin: Location, destination: Location, message: Xcm<()>, message_id: XcmHash }, /// Query response received which does not match a registered query. This may be because a /// matching query was never registered, it may be because it is a duplicate response, or /// because the query timed out. - UnexpectedResponse { origin: MultiLocation, query_id: QueryId }, + UnexpectedResponse { origin: Location, query_id: QueryId }, /// Query response has been received and is ready for taking with `take_response`. There is /// no registered notification call. ResponseReady { query_id: QueryId, response: Response }, @@ -412,9 +401,9 @@ pub mod pallet { /// not match that expected. The query remains registered for a later, valid, response to /// be received and acted upon. InvalidResponder { - origin: MultiLocation, + origin: Location, query_id: QueryId, - expected_location: Option, + expected_location: Option, }, /// Expected query response has been received but the expected origin location placed in /// storage by this runtime previously cannot be decoded. The query remains registered. @@ -423,29 +412,29 @@ pub mod pallet { /// runtime should be readable prior to query timeout) and dangerous since the possibly /// valid response will be dropped. Manual governance intervention is probably going to be /// needed. - InvalidResponderVersion { origin: MultiLocation, query_id: QueryId }, + InvalidResponderVersion { origin: Location, query_id: QueryId }, /// Received query response has been read and removed. ResponseTaken { query_id: QueryId }, /// Some assets have been placed in an asset trap. - AssetsTrapped { hash: H256, origin: MultiLocation, assets: VersionedMultiAssets }, + AssetsTrapped { hash: H256, origin: Location, assets: VersionedAssets }, /// An XCM version change notification message has been attempted to be sent. /// /// The cost of sending it (borne by the chain) is included. VersionChangeNotified { - destination: MultiLocation, + destination: Location, result: XcmVersion, - cost: MultiAssets, + cost: Assets, message_id: XcmHash, }, /// The supported version of a location has been changed. This might be through an /// automatic notification or a manual intervention. - SupportedVersionChanged { location: MultiLocation, version: XcmVersion }, + SupportedVersionChanged { location: Location, version: XcmVersion }, /// A given location which had a version change subscription was dropped owing to an error /// sending the notification to it. - NotifyTargetSendFail { location: MultiLocation, query_id: QueryId, error: XcmError }, + NotifyTargetSendFail { location: Location, query_id: QueryId, error: XcmError }, /// A given location which had a version change subscription was dropped owing to an error /// migrating the location to our new XCM format. - NotifyTargetMigrationFail { location: VersionedMultiLocation, query_id: QueryId }, + NotifyTargetMigrationFail { location: VersionedLocation, query_id: QueryId }, /// Expected query response has been received but the expected querier location placed in /// storage by this runtime previously cannot be decoded. The query remains registered. /// @@ -453,48 +442,40 @@ pub mod pallet { /// runtime should be readable prior to query timeout) and dangerous since the possibly /// valid response will be dropped. Manual governance intervention is probably going to be /// needed. - InvalidQuerierVersion { origin: MultiLocation, query_id: QueryId }, + InvalidQuerierVersion { origin: Location, query_id: QueryId }, /// Expected query response has been received but the querier location of the response does /// not match the expected. The query remains registered for a later, valid, response to /// be received and acted upon. InvalidQuerier { - origin: MultiLocation, + origin: Location, query_id: QueryId, - expected_querier: MultiLocation, - maybe_actual_querier: Option, + expected_querier: Location, + maybe_actual_querier: Option, }, /// A remote has requested XCM version change notification from us and we have honored it. /// A version information message is sent to them and its cost is included. - VersionNotifyStarted { destination: MultiLocation, cost: MultiAssets, message_id: XcmHash }, + VersionNotifyStarted { destination: Location, cost: Assets, message_id: XcmHash }, /// We have requested that a remote chain send us XCM version change notifications. - VersionNotifyRequested { - destination: MultiLocation, - cost: MultiAssets, - message_id: XcmHash, - }, + VersionNotifyRequested { destination: Location, cost: Assets, message_id: XcmHash }, /// We have requested that a remote chain stops sending us XCM version change /// notifications. - VersionNotifyUnrequested { - destination: MultiLocation, - cost: MultiAssets, - message_id: XcmHash, - }, + VersionNotifyUnrequested { destination: Location, cost: Assets, message_id: XcmHash }, /// Fees were paid from a location for an operation (often for using `SendXcm`). - FeesPaid { paying: MultiLocation, fees: MultiAssets }, + FeesPaid { paying: Location, fees: Assets }, /// Some assets have been claimed from an asset trap - AssetsClaimed { hash: H256, origin: MultiLocation, assets: VersionedMultiAssets }, + AssetsClaimed { hash: H256, origin: Location, assets: VersionedAssets }, } #[pallet::origin] #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub enum Origin { /// It comes from somewhere in the XCM space wanting to transact. - Xcm(MultiLocation), + Xcm(Location), /// It comes as an expected response from an XCM location. - Response(MultiLocation), + Response(Location), } - impl From for Origin { - fn from(location: MultiLocation) -> Origin { + impl From for Origin { + fn from(location: Location) -> Origin { Origin::Xcm(location) } } @@ -511,7 +492,7 @@ pub mod pallet { Filtered, /// The message's weight could not be determined. UnweighableMessage, - /// The destination `MultiLocation` provided cannot be inverted. + /// The destination `Location` provided cannot be inverted. DestinationNotInvertible, /// The assets to be sent are empty. Empty, @@ -582,25 +563,25 @@ pub mod pallet { Pending { /// The `QueryResponse` XCM must have this origin to be considered a reply for this /// query. - responder: VersionedMultiLocation, + responder: VersionedLocation, /// The `QueryResponse` XCM must have this value as the `querier` field to be /// considered a reply for this query. If `None` then the querier is ignored. - maybe_match_querier: Option, + maybe_match_querier: Option, maybe_notify: Option<(u8, u8)>, timeout: BlockNumber, }, /// The query is for an ongoing version notification subscription. - VersionNotifier { origin: VersionedMultiLocation, is_active: bool }, + VersionNotifier { origin: VersionedLocation, is_active: bool }, /// A response has been received. Ready { response: VersionedResponse, at: BlockNumber }, } #[derive(Copy, Clone)] - pub(crate) struct LatestVersionedMultiLocation<'a>(pub(crate) &'a MultiLocation); - impl<'a> EncodeLike for LatestVersionedMultiLocation<'a> {} - impl<'a> Encode for LatestVersionedMultiLocation<'a> { + pub(crate) struct LatestVersionedLocation<'a>(pub(crate) &'a Location); + impl<'a> EncodeLike for LatestVersionedLocation<'a> {} + impl<'a> Encode for LatestVersionedLocation<'a> { fn encode(&self) -> Vec { - let mut r = VersionedMultiLocation::from(MultiLocation::default()).encode(); + let mut r = VersionedLocation::from(Location::default()).encode(); r.truncate(1); self.0.using_encoded(|d| r.extend_from_slice(d)); r @@ -633,7 +614,7 @@ pub mod pallet { /// The existing asset traps. /// - /// Key is the blake2 256 hash of (origin, versioned `MultiAssets`) pair. Value is the number of + /// Key is the blake2 256 hash of (origin, versioned `Assets`) pair. Value is the number of /// times this pair has been trapped (usually just 1 if it exists at all). #[pallet::storage] #[pallet::getter(fn asset_trap)] @@ -652,7 +633,7 @@ pub mod pallet { Twox64Concat, XcmVersion, Blake2_128Concat, - VersionedMultiLocation, + VersionedLocation, XcmVersion, OptionQuery, >; @@ -664,7 +645,7 @@ pub mod pallet { Twox64Concat, XcmVersion, Blake2_128Concat, - VersionedMultiLocation, + VersionedLocation, QueryId, OptionQuery, >; @@ -677,7 +658,7 @@ pub mod pallet { Twox64Concat, XcmVersion, Blake2_128Concat, - VersionedMultiLocation, + VersionedLocation, (QueryId, Weight, XcmVersion), OptionQuery, >; @@ -696,7 +677,7 @@ pub mod pallet { #[pallet::whitelist_storage] pub(super) type VersionDiscoveryQueue = StorageValue< _, - BoundedVec<(VersionedMultiLocation, u32), VersionDiscoveryQueueSize>, + BoundedVec<(VersionedLocation, u32), VersionDiscoveryQueueSize>, ValueQuery, >; @@ -711,9 +692,9 @@ pub mod pallet { /// Total amount of the asset held by the remote lock. pub amount: u128, /// The owner of the locked asset. - pub owner: VersionedMultiLocation, + pub owner: VersionedLocation, /// The location which holds the original lock. - pub locker: VersionedMultiLocation, + pub locker: VersionedLocation, /// Local consumers of the remote lock with a consumer identifier and the amount /// of fungible asset every consumer holds. /// Every consumer can hold up to total amount of the remote lock. @@ -747,7 +728,7 @@ pub mod pallet { _, Blake2_128Concat, T::AccountId, - BoundedVec<(BalanceOf, VersionedMultiLocation), T::MaxLockers>, + BoundedVec<(BalanceOf, VersionedLocation), T::MaxLockers>, OptionQuery, >; @@ -795,7 +776,7 @@ pub mod pallet { weight_used.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); q.sort_by_key(|i| i.1); while let Some((versioned_dest, _)) = q.pop() { - if let Ok(dest) = MultiLocation::try_from(versioned_dest) { + if let Ok(dest) = Location::try_from(versioned_dest) { if Self::request_version_notify(dest).is_ok() { // TODO: correct weights. weight_used.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); @@ -819,12 +800,12 @@ pub mod pallet { #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] enum QueryStatusV0 { Pending { - responder: VersionedMultiLocation, + responder: VersionedLocation, maybe_notify: Option<(u8, u8)>, timeout: BlockNumber, }, VersionNotifier { - origin: VersionedMultiLocation, + origin: VersionedLocation, is_active: bool, }, Ready { @@ -840,7 +821,7 @@ pub mod pallet { responder, maybe_notify, timeout, - maybe_match_querier: Some(MultiLocation::here().into()), + maybe_match_querier: Some(Location::here().into()), }, VersionNotifier { origin, is_active } => QueryStatus::VersionNotifier { origin, is_active }, @@ -889,7 +870,7 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::send())] pub fn send( origin: OriginFor, - dest: Box, + dest: Box, message: Box>, ) -> DispatchResult { >::send(origin, dest, message)?; @@ -905,9 +886,9 @@ pub mod pallet { /// with all fees taken as needed from the asset. /// /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. - /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, - /// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send - /// from relay to parachain. + /// - `dest`: Destination context for the assets. Will typically be `[Parent, + /// Parachain(..)]` to send from parachain to parachain, or `[Parachain(..)]` to send from + /// relay to parachain. /// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will /// generally be an `AccountId32` value. /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the @@ -916,8 +897,8 @@ pub mod pallet { /// fees. #[pallet::call_index(1)] #[pallet::weight({ - let maybe_assets: Result = (*assets.clone()).try_into(); - let maybe_dest: Result = (*dest.clone()).try_into(); + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); match (maybe_assets, maybe_dest) { (Ok(assets), Ok(dest)) => { use sp_std::vec; @@ -934,9 +915,9 @@ pub mod pallet { })] pub fn teleport_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, ) -> DispatchResult { Self::do_teleport_assets(origin, dest, beneficiary, assets, fee_asset_item, Unlimited) @@ -963,9 +944,9 @@ pub mod pallet { /// with all fees taken as needed from the asset. /// /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. - /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, - /// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send - /// from relay to parachain. + /// - `dest`: Destination context for the assets. Will typically be `[Parent, + /// Parachain(..)]` to send from parachain to parachain, or `[Parachain(..)]` to send from + /// relay to parachain. /// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will /// generally be an `AccountId32` value. /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the @@ -974,8 +955,8 @@ pub mod pallet { /// fees. #[pallet::call_index(2)] #[pallet::weight({ - let maybe_assets: Result = (*assets.clone()).try_into(); - let maybe_dest: Result = (*dest.clone()).try_into(); + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); match (maybe_assets, maybe_dest) { (Ok(assets), Ok(dest)) => { use sp_std::vec; @@ -992,9 +973,9 @@ pub mod pallet { })] pub fn reserve_transfer_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, ) -> DispatchResult { Self::do_reserve_transfer_assets( @@ -1045,16 +1026,12 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::force_xcm_version())] pub fn force_xcm_version( origin: OriginFor, - location: Box, + location: Box, version: XcmVersion, ) -> DispatchResult { T::AdminOrigin::ensure_origin(origin)?; let location = *location; - SupportedVersion::::insert( - XCM_VERSION, - LatestVersionedMultiLocation(&location), - version, - ); + SupportedVersion::::insert(XCM_VERSION, LatestVersionedLocation(&location), version); Self::deposit_event(Event::SupportedVersionChanged { location, version }); Ok(()) } @@ -1083,10 +1060,10 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::force_subscribe_version_notify())] pub fn force_subscribe_version_notify( origin: OriginFor, - location: Box, + location: Box, ) -> DispatchResult { T::AdminOrigin::ensure_origin(origin)?; - let location: MultiLocation = + let location: Location = (*location).try_into().map_err(|()| Error::::BadLocation)?; Self::request_version_notify(location).map_err(|e| { match e { @@ -1107,10 +1084,10 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::force_unsubscribe_version_notify())] pub fn force_unsubscribe_version_notify( origin: OriginFor, - location: Box, + location: Box, ) -> DispatchResult { T::AdminOrigin::ensure_origin(origin)?; - let location: MultiLocation = + let location: Location = (*location).try_into().map_err(|()| Error::::BadLocation)?; Self::unrequest_version_notify(location).map_err(|e| { match e { @@ -1141,9 +1118,9 @@ pub mod pallet { /// at risk. /// /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. - /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, - /// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send - /// from relay to parachain. + /// - `dest`: Destination context for the assets. Will typically be `[Parent, + /// Parachain(..)]` to send from parachain to parachain, or `[Parachain(..)]` to send from + /// relay to parachain. /// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will /// generally be an `AccountId32` value. /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the @@ -1153,8 +1130,8 @@ pub mod pallet { /// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase. #[pallet::call_index(8)] #[pallet::weight({ - let maybe_assets: Result = (*assets.clone()).try_into(); - let maybe_dest: Result = (*dest.clone()).try_into(); + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); match (maybe_assets, maybe_dest) { (Ok(assets), Ok(dest)) => { use sp_std::vec; @@ -1171,9 +1148,9 @@ pub mod pallet { })] pub fn limited_reserve_transfer_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, weight_limit: WeightLimit, ) -> DispatchResult { @@ -1195,9 +1172,9 @@ pub mod pallet { /// at risk. /// /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. - /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, - /// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send - /// from relay to parachain. + /// - `dest`: Destination context for the assets. Will typically be `[Parent, + /// Parachain(..)]` to send from parachain to parachain, or `[Parachain(..)]` to send from + /// relay to parachain. /// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will /// generally be an `AccountId32` value. /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the @@ -1207,8 +1184,8 @@ pub mod pallet { /// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase. #[pallet::call_index(9)] #[pallet::weight({ - let maybe_assets: Result = (*assets.clone()).try_into(); - let maybe_dest: Result = (*dest.clone()).try_into(); + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); match (maybe_assets, maybe_dest) { (Ok(assets), Ok(dest)) => { use sp_std::vec; @@ -1225,9 +1202,9 @@ pub mod pallet { })] pub fn limited_teleport_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, weight_limit: WeightLimit, ) -> DispatchResult { @@ -1288,8 +1265,8 @@ pub mod pallet { /// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase. #[pallet::call_index(11)] #[pallet::weight({ - let maybe_assets: Result = (*assets.clone()).try_into(); - let maybe_dest: Result = (*dest.clone()).try_into(); + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); match (maybe_assets, maybe_dest) { (Ok(assets), Ok(dest)) => { use sp_std::vec; @@ -1309,17 +1286,17 @@ pub mod pallet { })] pub fn transfer_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, weight_limit: WeightLimit, ) -> DispatchResult { let origin = T::ExecuteXcmOrigin::ensure_origin(origin)?; let dest = (*dest).try_into().map_err(|()| Error::::BadVersion)?; - let beneficiary: MultiLocation = + let beneficiary: Location = (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; - let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; + let assets: Assets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; log::debug!( target: "xcm::pallet_xcm::transfer_assets", "origin {:?}, dest {:?}, beneficiary {:?}, assets {:?}, fee-idx {:?}, weight_limit {:?}", @@ -1353,17 +1330,25 @@ pub mod pallet { // added to assets transfers XCM programs let fees = assets.remove(fee_asset_item); let (local_xcm, remote_xcm) = match fees_transfer_type { - TransferType::LocalReserve => - Self::local_reserve_fees_instructions(origin, dest, fees, weight_limit)?, + TransferType::LocalReserve => Self::local_reserve_fees_instructions( + origin.clone(), + dest.clone(), + fees, + weight_limit, + )?, TransferType::DestinationReserve => Self::destination_reserve_fees_instructions( - origin, - dest, + origin.clone(), + dest.clone(), fees, weight_limit, )?, - TransferType::Teleport => - Self::teleport_fees_instructions(origin, dest, fees, weight_limit)?, + TransferType::Teleport => Self::teleport_fees_instructions( + origin.clone(), + dest.clone(), + fees, + weight_limit, + )?, TransferType::RemoteReserve(_) => return Err(Error::::InvalidAssetUnsupportedReserve.into()), }; @@ -1390,7 +1375,7 @@ const MAX_ASSETS_FOR_TRANSFER: usize = 2; #[derive(Clone, PartialEq)] enum FeesHandling { /// `fees` asset can be batch-transferred with rest of assets using same XCM instructions. - Batched { fees: MultiAsset }, + Batched { fees: Asset }, /// fees cannot be batched, they are handled separately using XCM programs here. Separate { local_xcm: Xcm<::RuntimeCall>, remote_xcm: Xcm<()> }, } @@ -1416,9 +1401,9 @@ impl QueryHandler for Pallet { /// Attempt to create a new query ID and register it as a query that is yet to respond. fn new_query( - responder: impl Into, + responder: impl Into, timeout: BlockNumberFor, - match_querier: impl Into, + match_querier: impl Into, ) -> Self::QueryId { Self::do_new_query(responder, None, timeout, match_querier) } @@ -1427,7 +1412,7 @@ impl QueryHandler for Pallet { /// value. fn report_outcome( message: &mut Xcm<()>, - responder: impl Into, + responder: impl Into, timeout: Self::BlockNumber, ) -> Result { let responder = responder.into(); @@ -1474,9 +1459,9 @@ impl Pallet { /// /// Validate `assets` to all have same `TransferType`. fn find_fee_and_assets_transfer_types( - assets: &[MultiAsset], + assets: &[Asset], fee_asset_item: usize, - dest: &MultiLocation, + dest: &Location, ) -> Result<(TransferType, TransferType), Error> { let mut fees_transfer_type = None; let mut assets_transfer_type = None; @@ -1502,7 +1487,7 @@ impl Pallet { } // single asset also marked as fee item if assets.len() == 1 { - assets_transfer_type = fees_transfer_type + assets_transfer_type = fees_transfer_type.clone() } Ok(( fees_transfer_type.ok_or(Error::::Empty)?, @@ -1512,17 +1497,17 @@ impl Pallet { fn do_reserve_transfer_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, weight_limit: WeightLimit, ) -> DispatchResult { let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; let dest = (*dest).try_into().map_err(|()| Error::::BadVersion)?; - let beneficiary: MultiLocation = + let beneficiary: Location = (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; - let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; + let assets: Assets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; log::debug!( target: "xcm::pallet_xcm::do_reserve_transfer_assets", "origin {:?}, dest {:?}, beneficiary {:?}, assets {:?}, fee-idx {:?}", @@ -1558,17 +1543,17 @@ impl Pallet { fn do_teleport_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, weight_limit: WeightLimit, ) -> DispatchResult { let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; let dest = (*dest).try_into().map_err(|()| Error::::BadVersion)?; - let beneficiary: MultiLocation = + let beneficiary: Location = (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; - let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; + let assets: Assets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; log::debug!( target: "xcm::pallet_xcm::do_teleport_assets", "origin {:?}, dest {:?}, beneficiary {:?}, assets {:?}, fee-idx {:?}, weight_limit {:?}", @@ -1598,10 +1583,10 @@ impl Pallet { } fn build_and_execute_xcm_transfer_type( - origin: MultiLocation, - dest: MultiLocation, - beneficiary: MultiLocation, - assets: Vec, + origin: Location, + dest: Location, + beneficiary: Location, + assets: Vec, transfer_type: TransferType, fees: FeesHandling, weight_limit: WeightLimit, @@ -1615,8 +1600,8 @@ impl Pallet { let (mut local_xcm, remote_xcm) = match transfer_type { TransferType::LocalReserve => { let (local, remote) = Self::local_reserve_transfer_programs( - origin, - dest, + origin.clone(), + dest.clone(), beneficiary, assets, fees, @@ -1626,8 +1611,8 @@ impl Pallet { }, TransferType::DestinationReserve => { let (local, remote) = Self::destination_reserve_transfer_programs( - origin, - dest, + origin.clone(), + dest.clone(), beneficiary, assets, fees, @@ -1641,9 +1626,9 @@ impl Pallet { _ => return Err(Error::::InvalidAssetUnsupportedReserve.into()), }; let local = Self::remote_reserve_transfer_program( - origin, + origin.clone(), reserve, - dest, + dest.clone(), beneficiary, assets, fees, @@ -1653,8 +1638,8 @@ impl Pallet { }, TransferType::Teleport => { let (local, remote) = Self::teleport_assets_program( - origin, - dest, + origin.clone(), + dest.clone(), beneficiary, assets, fees, @@ -1665,9 +1650,14 @@ impl Pallet { }; let weight = T::Weigher::weight(&mut local_xcm).map_err(|()| Error::::UnweighableMessage)?; - let hash = local_xcm.using_encoded(sp_io::hashing::blake2_256); - let outcome = - T::XcmExecutor::execute_xcm_in_credit(origin, local_xcm, hash, weight, weight); + let mut hash = local_xcm.using_encoded(sp_io::hashing::blake2_256); + let outcome = T::XcmExecutor::prepare_and_execute( + origin.clone(), + local_xcm, + &mut hash, + weight, + weight, + ); Self::deposit_event(Event::Attempted { outcome: outcome.clone() }); outcome.ensure_complete().map_err(|error| { log::error!( @@ -1678,10 +1668,10 @@ impl Pallet { })?; if let Some(remote_xcm) = remote_xcm { - let (ticket, price) = validate_send::(dest, remote_xcm.clone()) + let (ticket, price) = validate_send::(dest.clone(), remote_xcm.clone()) .map_err(Error::::from)?; if origin != Here.into_location() { - Self::charge_fees(origin, price).map_err(|error| { + Self::charge_fees(origin.clone(), price).map_err(|error| { log::error!( target: "xcm::pallet_xcm::build_and_execute_xcm_transfer_type", "Unable to charge fee with error {:?}", error @@ -1698,7 +1688,7 @@ impl Pallet { } fn add_fees_to_xcm( - dest: MultiLocation, + dest: Location, fees: FeesHandling, weight_limit: WeightLimit, local: &mut Xcm<::RuntimeCall>, @@ -1710,7 +1700,7 @@ impl Pallet { // no custom fees instructions, they are batched together with `assets` transfer; // BuyExecution happens after receiving all `assets` let reanchored_fees = - fees.reanchored(&dest, context).map_err(|_| Error::::CannotReanchor)?; + fees.reanchored(&dest, &context).map_err(|_| Error::::CannotReanchor)?; // buy execution using `fees` batched together with above `reanchored_assets` remote.inner_mut().push(BuyExecution { fees: reanchored_fees, weight_limit }); }, @@ -1728,9 +1718,9 @@ impl Pallet { } fn local_reserve_fees_instructions( - origin: MultiLocation, - dest: MultiLocation, - fees: MultiAsset, + origin: Location, + dest: Location, + fees: Asset, weight_limit: WeightLimit, ) -> Result<(Xcm<::RuntimeCall>, Xcm<()>), Error> { let value = (origin, vec![fees.clone()]); @@ -1739,7 +1729,7 @@ impl Pallet { let context = T::UniversalLocation::get(); let reanchored_fees = fees .clone() - .reanchored(&dest, context) + .reanchored(&dest, &context) .map_err(|_| Error::::CannotReanchor)?; let local_execute_xcm = Xcm(vec![ @@ -1756,10 +1746,10 @@ impl Pallet { } fn local_reserve_transfer_programs( - origin: MultiLocation, - dest: MultiLocation, - beneficiary: MultiLocation, - assets: Vec, + origin: Location, + dest: Location, + beneficiary: Location, + assets: Vec, fees: FeesHandling, weight_limit: WeightLimit, ) -> Result<(Xcm<::RuntimeCall>, Xcm<()>), Error> { @@ -1770,17 +1760,17 @@ impl Pallet { // max assets is `assets` (+ potentially separately handled fee) let max_assets = assets.len() as u32 + if matches!(&fees, FeesHandling::Batched { .. }) { 0 } else { 1 }; - let assets: MultiAssets = assets.into(); + let assets: Assets = assets.into(); let context = T::UniversalLocation::get(); let mut reanchored_assets = assets.clone(); reanchored_assets - .reanchor(&dest, context) + .reanchor(&dest, &context) .map_err(|_| Error::::CannotReanchor)?; // XCM instructions to be executed on local chain let mut local_execute_xcm = Xcm(vec![ // locally move `assets` to `dest`s local sovereign account - TransferAsset { assets, beneficiary: dest }, + TransferAsset { assets, beneficiary: dest.clone() }, ]); // XCM instructions to be executed on destination chain let mut xcm_on_dest = Xcm(vec![ @@ -1800,9 +1790,9 @@ impl Pallet { } fn destination_reserve_fees_instructions( - origin: MultiLocation, - dest: MultiLocation, - fees: MultiAsset, + origin: Location, + dest: Location, + fees: Asset, weight_limit: WeightLimit, ) -> Result<(Xcm<::RuntimeCall>, Xcm<()>), Error> { let value = (origin, vec![fees.clone()]); @@ -1811,9 +1801,9 @@ impl Pallet { let context = T::UniversalLocation::get(); let reanchored_fees = fees .clone() - .reanchored(&dest, context) + .reanchored(&dest, &context) .map_err(|_| Error::::CannotReanchor)?; - let fees: MultiAssets = fees.into(); + let fees: Assets = fees.into(); let local_execute_xcm = Xcm(vec![ // withdraw reserve-based fees (derivatives) @@ -1831,10 +1821,10 @@ impl Pallet { } fn destination_reserve_transfer_programs( - origin: MultiLocation, - dest: MultiLocation, - beneficiary: MultiLocation, - assets: Vec, + origin: Location, + dest: Location, + beneficiary: Location, + assets: Vec, fees: FeesHandling, weight_limit: WeightLimit, ) -> Result<(Xcm<::RuntimeCall>, Xcm<()>), Error> { @@ -1845,11 +1835,11 @@ impl Pallet { // max assets is `assets` (+ potentially separately handled fee) let max_assets = assets.len() as u32 + if matches!(&fees, FeesHandling::Batched { .. }) { 0 } else { 1 }; - let assets: MultiAssets = assets.into(); + let assets: Assets = assets.into(); let context = T::UniversalLocation::get(); let mut reanchored_assets = assets.clone(); reanchored_assets - .reanchor(&dest, context) + .reanchor(&dest, &context) .map_err(|_| Error::::CannotReanchor)?; // XCM instructions to be executed on local chain @@ -1878,12 +1868,12 @@ impl Pallet { // function assumes fees and assets have the same remote reserve fn remote_reserve_transfer_program( - origin: MultiLocation, - reserve: MultiLocation, - dest: MultiLocation, - beneficiary: MultiLocation, - assets: Vec, - fees: MultiAsset, + origin: Location, + reserve: Location, + dest: Location, + beneficiary: Location, + assets: Vec, + fees: Asset, weight_limit: WeightLimit, ) -> Result::RuntimeCall>, Error> { let value = (origin, assets); @@ -1897,13 +1887,14 @@ impl Pallet { let (fees_half_1, fees_half_2) = Self::halve_fees(fees)?; // identifies fee item as seen by `reserve` - to be used at reserve chain let reserve_fees = fees_half_1 - .reanchored(&reserve, context) + .reanchored(&reserve, &context) .map_err(|_| Error::::CannotReanchor)?; // identifies fee item as seen by `dest` - to be used at destination chain - let dest_fees = - fees_half_2.reanchored(&dest, context).map_err(|_| Error::::CannotReanchor)?; + let dest_fees = fees_half_2 + .reanchored(&dest, &context) + .map_err(|_| Error::::CannotReanchor)?; // identifies `dest` as seen by `reserve` - let dest = dest.reanchored(&reserve, context).map_err(|_| Error::::CannotReanchor)?; + let dest = dest.reanchored(&reserve, &context).map_err(|_| Error::::CannotReanchor)?; // xcm to be executed at dest let xcm_on_dest = Xcm(vec![ BuyExecution { fees: dest_fees, weight_limit: weight_limit.clone() }, @@ -1925,9 +1916,9 @@ impl Pallet { } fn teleport_fees_instructions( - origin: MultiLocation, - dest: MultiLocation, - fees: MultiAsset, + origin: Location, + dest: Location, + fees: Asset, weight_limit: WeightLimit, ) -> Result<(Xcm<::RuntimeCall>, Xcm<()>), Error> { let value = (origin, vec![fees.clone()]); @@ -1936,7 +1927,7 @@ impl Pallet { let context = T::UniversalLocation::get(); let reanchored_fees = fees .clone() - .reanchored(&dest, context) + .reanchored(&dest, &context) .map_err(|_| Error::::CannotReanchor)?; // XcmContext irrelevant in teleports checks @@ -1960,7 +1951,7 @@ impl Pallet { &dummy_context, ); - let fees: MultiAssets = fees.into(); + let fees: Assets = fees.into(); let local_execute_xcm = Xcm(vec![ // withdraw fees WithdrawAsset(fees.clone()), @@ -1977,10 +1968,10 @@ impl Pallet { } fn teleport_assets_program( - origin: MultiLocation, - dest: MultiLocation, - beneficiary: MultiLocation, - assets: Vec, + origin: Location, + dest: Location, + beneficiary: Location, + assets: Vec, fees: FeesHandling, weight_limit: WeightLimit, ) -> Result<(Xcm<::RuntimeCall>, Xcm<()>), Error> { @@ -1992,10 +1983,10 @@ impl Pallet { let max_assets = assets.len() as u32 + if matches!(&fees, FeesHandling::Batched { .. }) { 0 } else { 1 }; let context = T::UniversalLocation::get(); - let assets: MultiAssets = assets.into(); + let assets: Assets = assets.into(); let mut reanchored_assets = assets.clone(); reanchored_assets - .reanchor(&dest, context) + .reanchor(&dest, &context) .map_err(|_| Error::::CannotReanchor)?; // XcmContext irrelevant in teleports checks @@ -2048,14 +2039,14 @@ impl Pallet { } /// Halve `fees` fungible amount. - pub(crate) fn halve_fees(fees: MultiAsset) -> Result<(MultiAsset, MultiAsset), Error> { + pub(crate) fn halve_fees(fees: Asset) -> Result<(Asset, Asset), Error> { match fees.fun { Fungible(amount) => { let fee1 = amount.saturating_div(2); let fee2 = amount.saturating_sub(fee1); ensure!(fee1 > 0, Error::::FeesNotMet); ensure!(fee2 > 0, Error::::FeesNotMet); - Ok((MultiAsset::from((fees.id, fee1)), MultiAsset::from((fees.id, fee2)))) + Ok((Asset::from((fees.id.clone(), fee1)), Asset::from((fees.id.clone(), fee2)))) }, NonFungible(_) => Err(Error::::FeesNotMet), } @@ -2119,7 +2110,7 @@ impl Pallet { }; while let Some((key, value)) = iter.next() { let (query_id, max_weight, target_xcm_version) = value; - let new_key: MultiLocation = match key.clone().try_into() { + let new_key: Location = match key.clone().try_into() { Ok(k) if target_xcm_version != xcm_version => k, _ => { // We don't early return here since we need to be certain that we @@ -2131,7 +2122,7 @@ impl Pallet { let response = Response::Version(xcm_version); let message = Xcm(vec![QueryResponse { query_id, response, max_weight, querier: None }]); - let event = match send_xcm::(new_key, message) { + let event = match send_xcm::(new_key.clone(), message) { Ok((message_id, cost)) => { let value = (query_id, max_weight, xcm_version); VersionNotifyTargets::::insert(XCM_VERSION, key, value); @@ -2160,7 +2151,7 @@ impl Pallet { for v in 0..XCM_VERSION { for (old_key, value) in VersionNotifyTargets::::drain_prefix(v) { let (query_id, max_weight, target_xcm_version) = value; - let new_key = match MultiLocation::try_from(old_key.clone()) { + let new_key = match Location::try_from(old_key.clone()) { Ok(k) => k, Err(()) => { Self::deposit_event(Event::NotifyTargetMigrationFail { @@ -2175,7 +2166,7 @@ impl Pallet { }, }; - let versioned_key = LatestVersionedMultiLocation(&new_key); + let versioned_key = LatestVersionedLocation(&new_key); if target_xcm_version == xcm_version { VersionNotifyTargets::::insert(XCM_VERSION, versioned_key, value); weight_used.saturating_accrue(vnt_migrate_weight); @@ -2188,7 +2179,7 @@ impl Pallet { max_weight, querier: None, }]); - let event = match send_xcm::(new_key, message) { + let event = match send_xcm::(new_key.clone(), message) { Ok((message_id, cost)) => { VersionNotifyTargets::::insert( XCM_VERSION, @@ -2221,9 +2212,9 @@ impl Pallet { } /// Request that `dest` informs us of its version. - pub fn request_version_notify(dest: impl Into) -> XcmResult { + pub fn request_version_notify(dest: impl Into) -> XcmResult { let dest = dest.into(); - let versioned_dest = VersionedMultiLocation::from(dest); + let versioned_dest = VersionedLocation::from(dest.clone()); let already = VersionNotifiers::::contains_key(XCM_VERSION, &versioned_dest); ensure!(!already, XcmError::InvalidLocation); let query_id = QueryCounter::::mutate(|q| { @@ -2233,7 +2224,7 @@ impl Pallet { }); // TODO #3735: Correct weight. let instruction = SubscribeVersion { query_id, max_response_weight: Weight::zero() }; - let (message_id, cost) = send_xcm::(dest, Xcm(vec![instruction]))?; + let (message_id, cost) = send_xcm::(dest.clone(), Xcm(vec![instruction]))?; Self::deposit_event(Event::VersionNotifyRequested { destination: dest, cost, message_id }); VersionNotifiers::::insert(XCM_VERSION, &versioned_dest, query_id); let query_status = @@ -2243,12 +2234,13 @@ impl Pallet { } /// Request that `dest` ceases informing us of its version. - pub fn unrequest_version_notify(dest: impl Into) -> XcmResult { + pub fn unrequest_version_notify(dest: impl Into) -> XcmResult { let dest = dest.into(); - let versioned_dest = LatestVersionedMultiLocation(&dest); + let versioned_dest = LatestVersionedLocation(&dest); let query_id = VersionNotifiers::::take(XCM_VERSION, versioned_dest) .ok_or(XcmError::InvalidLocation)?; - let (message_id, cost) = send_xcm::(dest, Xcm(vec![UnsubscribeVersion]))?; + let (message_id, cost) = + send_xcm::(dest.clone(), Xcm(vec![UnsubscribeVersion]))?; Self::deposit_event(Event::VersionNotifyUnrequested { destination: dest, cost, @@ -2263,13 +2255,13 @@ impl Pallet { /// are not charged (and instead borne by the chain). pub fn send_xcm( interior: impl Into, - dest: impl Into, + dest: impl Into, mut message: Xcm<()>, ) -> Result { let interior = interior.into(); let dest = dest.into(); let maybe_fee_payer = if interior != Junctions::Here { - message.0.insert(0, DescendOrigin(interior)); + message.0.insert(0, DescendOrigin(interior.clone())); Some(interior.into()) } else { None @@ -2289,10 +2281,10 @@ impl Pallet { /// Create a new expectation of a query response with the querier being here. fn do_new_query( - responder: impl Into, + responder: impl Into, maybe_notify: Option<(u8, u8)>, timeout: BlockNumberFor, - match_querier: impl Into, + match_querier: impl Into, ) -> u64 { QueryCounter::::mutate(|q| { let r = *q; @@ -2334,7 +2326,7 @@ impl Pallet { /// may be put in the overweight queue and need to be manually executed. pub fn report_outcome_notify( message: &mut Xcm<()>, - responder: impl Into, + responder: impl Into, notify: impl Into<::RuntimeCall>, timeout: BlockNumberFor, ) -> Result<(), XcmError> { @@ -2354,10 +2346,10 @@ impl Pallet { /// Attempt to create a new query ID and register it as a query that is yet to respond, and /// which will call a dispatchable when a response happens. pub fn new_notify_query( - responder: impl Into, + responder: impl Into, notify: impl Into<::RuntimeCall>, timeout: BlockNumberFor, - match_querier: impl Into, + match_querier: impl Into, ) -> u64 { let notify = notify.into().using_encoded(|mut bytes| Decode::decode(&mut bytes)).expect( "decode input is output of Call encode; Call guaranteed to have two enums; qed", @@ -2367,13 +2359,13 @@ impl Pallet { /// Note that a particular destination to whom we would like to send a message is unknown /// and queue it for version discovery. - fn note_unknown_version(dest: &MultiLocation) { + fn note_unknown_version(dest: &Location) { log::trace!( target: "xcm::pallet_xcm::note_unknown_version", "XCM version is unknown for destination: {:?}", dest, ); - let versioned_dest = VersionedMultiLocation::from(*dest); + let versioned_dest = VersionedLocation::from(dest.clone()); VersionDiscoveryQueue::::mutate(|q| { if let Some(index) = q.iter().position(|i| &i.0 == &versioned_dest) { // exists - just bump the count. @@ -2389,8 +2381,8 @@ impl Pallet { /// Fails if: /// - the `assets` are not known on this chain; /// - the `assets` cannot be withdrawn with that location as the Origin. - fn charge_fees(location: MultiLocation, assets: MultiAssets) -> DispatchResult { - T::XcmExecutor::charge_fees(location, assets.clone()) + fn charge_fees(location: Location, assets: Assets) -> DispatchResult { + T::XcmExecutor::charge_fees(location.clone(), assets.clone()) .map_err(|_| Error::::FeesNotMet)?; Self::deposit_event(Event::FeesPaid { paying: location, fees: assets }); Ok(()) @@ -2400,7 +2392,7 @@ impl Pallet { pub struct LockTicket { sovereign_account: T::AccountId, amount: BalanceOf, - unlocker: MultiLocation, + unlocker: Location, item_index: Option, } @@ -2434,7 +2426,7 @@ impl xcm_executor::traits::Enact for LockTicket { pub struct UnlockTicket { sovereign_account: T::AccountId, amount: BalanceOf, - unlocker: MultiLocation, + unlocker: Location, } impl xcm_executor::traits::Enact for UnlockTicket { @@ -2471,8 +2463,8 @@ impl xcm_executor::traits::Enact for UnlockTicket { pub struct ReduceTicket { key: (u32, T::AccountId, VersionedAssetId), amount: u128, - locker: VersionedMultiLocation, - owner: VersionedMultiLocation, + locker: VersionedLocation, + owner: VersionedLocation, } impl xcm_executor::traits::Enact for ReduceTicket { @@ -2498,9 +2490,9 @@ impl xcm_executor::traits::AssetLock for Pallet { type ReduceTicket = ReduceTicket; fn prepare_lock( - unlocker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + unlocker: Location, + asset: Asset, + owner: Location, ) -> Result, xcm_executor::traits::LockError> { use xcm_executor::traits::LockError::*; let sovereign_account = T::SovereignAccountOf::convert_location(&owner).ok_or(BadOwner)?; @@ -2513,9 +2505,9 @@ impl xcm_executor::traits::AssetLock for Pallet { } fn prepare_unlock( - unlocker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + unlocker: Location, + asset: Asset, + owner: Location, ) -> Result, xcm_executor::traits::LockError> { use xcm_executor::traits::LockError::*; let sovereign_account = T::SovereignAccountOf::convert_location(&owner).ok_or(BadOwner)?; @@ -2529,9 +2521,9 @@ impl xcm_executor::traits::AssetLock for Pallet { } fn note_unlockable( - locker: MultiLocation, - asset: MultiAsset, - mut owner: MultiLocation, + locker: Location, + asset: Asset, + mut owner: Location, ) -> Result<(), xcm_executor::traits::LockError> { use xcm_executor::traits::LockError::*; ensure!(T::TrustedLockers::contains(&locker, &asset), NotTrusted); @@ -2558,9 +2550,9 @@ impl xcm_executor::traits::AssetLock for Pallet { } fn prepare_reduce_unlockable( - locker: MultiLocation, - asset: MultiAsset, - mut owner: MultiLocation, + locker: Location, + asset: Asset, + mut owner: Location, ) -> Result { use xcm_executor::traits::LockError::*; let amount = match asset.fun { @@ -2588,7 +2580,7 @@ impl xcm_executor::traits::AssetLock for Pallet { impl WrapVersion for Pallet { fn wrap_version( - dest: &MultiLocation, + dest: &Location, xcm: impl Into>, ) -> Result, ()> { Self::get_version_for(dest) @@ -2609,8 +2601,8 @@ impl WrapVersion for Pallet { } impl GetVersion for Pallet { - fn get_version_for(dest: &MultiLocation) -> Option { - SupportedVersion::::get(XCM_VERSION, LatestVersionedMultiLocation(dest)) + fn get_version_for(dest: &Location) -> Option { + SupportedVersion::::get(XCM_VERSION, LatestVersionedLocation(dest)) } } @@ -2624,21 +2616,21 @@ impl VersionChangeNotifier for Pallet { /// If the `location` has an ongoing notification and when this function is called, then an /// error should be returned. fn start( - dest: &MultiLocation, + dest: &Location, query_id: QueryId, max_weight: Weight, _context: &XcmContext, ) -> XcmResult { - let versioned_dest = LatestVersionedMultiLocation(dest); + let versioned_dest = LatestVersionedLocation(dest); let already = VersionNotifyTargets::::contains_key(XCM_VERSION, versioned_dest); ensure!(!already, XcmError::InvalidLocation); let xcm_version = T::AdvertisedXcmVersion::get(); let response = Response::Version(xcm_version); let instruction = QueryResponse { query_id, response, max_weight, querier: None }; - let (message_id, cost) = send_xcm::(*dest, Xcm(vec![instruction]))?; + let (message_id, cost) = send_xcm::(dest.clone(), Xcm(vec![instruction]))?; Self::deposit_event(Event::::VersionNotifyStarted { - destination: *dest, + destination: dest.clone(), cost, message_id, }); @@ -2650,27 +2642,31 @@ impl VersionChangeNotifier for Pallet { /// Stop notifying `location` should the XCM change. This is a no-op if there was never a /// subscription. - fn stop(dest: &MultiLocation, _context: &XcmContext) -> XcmResult { - VersionNotifyTargets::::remove(XCM_VERSION, LatestVersionedMultiLocation(dest)); + fn stop(dest: &Location, _context: &XcmContext) -> XcmResult { + VersionNotifyTargets::::remove(XCM_VERSION, LatestVersionedLocation(dest)); Ok(()) } /// Return true if a location is subscribed to XCM version changes. - fn is_subscribed(dest: &MultiLocation) -> bool { - let versioned_dest = LatestVersionedMultiLocation(dest); + fn is_subscribed(dest: &Location) -> bool { + let versioned_dest = LatestVersionedLocation(dest); VersionNotifyTargets::::contains_key(XCM_VERSION, versioned_dest) } } impl DropAssets for Pallet { - fn drop_assets(origin: &MultiLocation, assets: Assets, _context: &XcmContext) -> Weight { + fn drop_assets(origin: &Location, assets: AssetsInHolding, _context: &XcmContext) -> Weight { if assets.is_empty() { return Weight::zero() } - let versioned = VersionedMultiAssets::from(MultiAssets::from(assets)); + let versioned = VersionedAssets::from(Assets::from(assets)); let hash = BlakeTwo256::hash_of(&(&origin, &versioned)); AssetTraps::::mutate(hash, |n| *n += 1); - Self::deposit_event(Event::AssetsTrapped { hash, origin: *origin, assets: versioned }); + Self::deposit_event(Event::AssetsTrapped { + hash, + origin: origin.clone(), + assets: versioned, + }); // TODO #3735: Put the real weight in there. Weight::zero() } @@ -2678,71 +2674,75 @@ impl DropAssets for Pallet { impl ClaimAssets for Pallet { fn claim_assets( - origin: &MultiLocation, - ticket: &MultiLocation, - assets: &MultiAssets, + origin: &Location, + ticket: &Location, + assets: &Assets, _context: &XcmContext, ) -> bool { - let mut versioned = VersionedMultiAssets::from(assets.clone()); - match (ticket.parents, &ticket.interior) { - (0, X1(GeneralIndex(i))) => + let mut versioned = VersionedAssets::from(assets.clone()); + match ticket.unpack() { + (0, [GeneralIndex(i)]) => versioned = match versioned.into_version(*i as u32) { Ok(v) => v, Err(()) => return false, }, - (0, Here) => (), + (0, []) => (), _ => return false, }; - let hash = BlakeTwo256::hash_of(&(origin, versioned.clone())); + let hash = BlakeTwo256::hash_of(&(origin.clone(), versioned.clone())); match AssetTraps::::get(hash) { 0 => return false, 1 => AssetTraps::::remove(hash), n => AssetTraps::::insert(hash, n - 1), } - Self::deposit_event(Event::AssetsClaimed { hash, origin: *origin, assets: versioned }); + Self::deposit_event(Event::AssetsClaimed { + hash, + origin: origin.clone(), + assets: versioned, + }); return true } } impl OnResponse for Pallet { fn expecting_response( - origin: &MultiLocation, + origin: &Location, query_id: QueryId, - querier: Option<&MultiLocation>, + querier: Option<&Location>, ) -> bool { match Queries::::get(query_id) { Some(QueryStatus::Pending { responder, maybe_match_querier, .. }) => - MultiLocation::try_from(responder).map_or(false, |r| origin == &r) && + Location::try_from(responder).map_or(false, |r| origin == &r) && maybe_match_querier.map_or(true, |match_querier| { - MultiLocation::try_from(match_querier).map_or(false, |match_querier| { + Location::try_from(match_querier).map_or(false, |match_querier| { querier.map_or(false, |q| q == &match_querier) }) }), Some(QueryStatus::VersionNotifier { origin: r, .. }) => - MultiLocation::try_from(r).map_or(false, |r| origin == &r), + Location::try_from(r).map_or(false, |r| origin == &r), _ => false, } } fn on_response( - origin: &MultiLocation, + origin: &Location, query_id: QueryId, - querier: Option<&MultiLocation>, + querier: Option<&Location>, response: Response, max_weight: Weight, _context: &XcmContext, ) -> Weight { - let origin = *origin; + let origin = origin.clone(); match (response, Queries::::get(query_id)) { ( Response::Version(v), Some(QueryStatus::VersionNotifier { origin: expected_origin, is_active }), ) => { - let origin: MultiLocation = match expected_origin.try_into() { + let origin: Location = match expected_origin.try_into() { Ok(o) if o == origin => o, Ok(o) => { Self::deposit_event(Event::InvalidResponder { - origin, + origin: origin.clone(), query_id, expected_location: Some(o), }); @@ -2750,7 +2750,7 @@ impl OnResponse for Pallet { }, _ => { Self::deposit_event(Event::InvalidResponder { - origin, + origin: origin.clone(), query_id, expected_location: None, }); @@ -2762,15 +2762,14 @@ impl OnResponse for Pallet { if !is_active { Queries::::insert( query_id, - QueryStatus::VersionNotifier { origin: origin.into(), is_active: true }, + QueryStatus::VersionNotifier { + origin: origin.clone().into(), + is_active: true, + }, ); } // We're being notified of a version change. - SupportedVersion::::insert( - XCM_VERSION, - LatestVersionedMultiLocation(&origin), - v, - ); + SupportedVersion::::insert(XCM_VERSION, LatestVersionedLocation(&origin), v); Self::deposit_event(Event::SupportedVersionChanged { location: origin, version: v, @@ -2782,16 +2781,19 @@ impl OnResponse for Pallet { Some(QueryStatus::Pending { responder, maybe_notify, maybe_match_querier, .. }), ) => { if let Some(match_querier) = maybe_match_querier { - let match_querier = match MultiLocation::try_from(match_querier) { + let match_querier = match Location::try_from(match_querier) { Ok(mq) => mq, Err(_) => { - Self::deposit_event(Event::InvalidQuerierVersion { origin, query_id }); + Self::deposit_event(Event::InvalidQuerierVersion { + origin: origin.clone(), + query_id, + }); return Weight::zero() }, }; if querier.map_or(true, |q| q != &match_querier) { Self::deposit_event(Event::InvalidQuerier { - origin, + origin: origin.clone(), query_id, expected_querier: match_querier, maybe_actual_querier: querier.cloned(), @@ -2799,16 +2801,19 @@ impl OnResponse for Pallet { return Weight::zero() } } - let responder = match MultiLocation::try_from(responder) { + let responder = match Location::try_from(responder) { Ok(r) => r, Err(_) => { - Self::deposit_event(Event::InvalidResponderVersion { origin, query_id }); + Self::deposit_event(Event::InvalidResponderVersion { + origin: origin.clone(), + query_id, + }); return Weight::zero() }, }; if origin != responder { Self::deposit_event(Event::InvalidResponder { - origin, + origin: origin.clone(), query_id, expected_location: Some(responder), }); @@ -2836,7 +2841,7 @@ impl OnResponse for Pallet { Self::deposit_event(e); return Weight::zero() } - let dispatch_origin = Origin::Response(origin).into(); + let dispatch_origin = Origin::Response(origin.clone()).into(); match call.dispatch(dispatch_origin) { Ok(post_info) => { let e = Event::Notified { query_id, pallet_index, call_index }; @@ -2874,7 +2879,7 @@ impl OnResponse for Pallet { } }, _ => { - let e = Event::UnexpectedResponse { origin, query_id }; + let e = Event::UnexpectedResponse { origin: origin.clone(), query_id }; Self::deposit_event(e); Weight::zero() }, @@ -2884,7 +2889,7 @@ impl OnResponse for Pallet { impl CheckSuspension for Pallet { fn is_suspended( - _origin: &MultiLocation, + _origin: &Location, _instructions: &mut [Instruction], _max_weight: Weight, _properties: &mut Properties, @@ -2896,7 +2901,7 @@ impl CheckSuspension for Pallet { /// Ensure that the origin `o` represents an XCM (`Transact`) origin. /// /// Returns `Ok` with the location of the XCM sender or an `Err` otherwise. -pub fn ensure_xcm(o: OuterOrigin) -> Result +pub fn ensure_xcm(o: OuterOrigin) -> Result where OuterOrigin: Into>, { @@ -2909,7 +2914,7 @@ where /// Ensure that the origin `o` represents an XCM response origin. /// /// Returns `Ok` with the location of the responder or an `Err` otherwise. -pub fn ensure_response(o: OuterOrigin) -> Result +pub fn ensure_response(o: OuterOrigin) -> Result where OuterOrigin: Into>, { @@ -2919,46 +2924,50 @@ where } } -/// Filter for `MultiLocation` to find those which represent a strict majority approval of an +/// Filter for `Location` to find those which represent a strict majority approval of an /// identified plurality. /// /// May reasonably be used with `EnsureXcm`. pub struct IsMajorityOfBody(PhantomData<(Prefix, Body)>); -impl, Body: Get> Contains +impl, Body: Get> Contains for IsMajorityOfBody { - fn contains(l: &MultiLocation) -> bool { + fn contains(l: &Location) -> bool { let maybe_suffix = l.match_and_split(&Prefix::get()); matches!(maybe_suffix, Some(Plurality { id, part }) if id == &Body::get() && part.is_majority()) } } -/// Filter for `MultiLocation` to find those which represent a voice of an identified plurality. +/// Filter for `Location` to find those which represent a voice of an identified plurality. /// /// May reasonably be used with `EnsureXcm`. pub struct IsVoiceOfBody(PhantomData<(Prefix, Body)>); -impl, Body: Get> Contains - for IsVoiceOfBody -{ - fn contains(l: &MultiLocation) -> bool { +impl, Body: Get> Contains for IsVoiceOfBody { + fn contains(l: &Location) -> bool { let maybe_suffix = l.match_and_split(&Prefix::get()); matches!(maybe_suffix, Some(Plurality { id, part }) if id == &Body::get() && part == &BodyPart::Voice) } } -/// `EnsureOrigin` implementation succeeding with a `MultiLocation` value to recognize and filter +/// `EnsureOrigin` implementation succeeding with a `Location` value to recognize and filter /// the `Origin::Xcm` item. -pub struct EnsureXcm(PhantomData); -impl, F: Contains> EnsureOrigin for EnsureXcm +pub struct EnsureXcm(PhantomData<(F, L)>); +impl< + O: OriginTrait + From, + F: Contains, + L: TryFrom + TryInto + Clone, + > EnsureOrigin for EnsureXcm where O::PalletsOrigin: From + TryInto, { - type Success = MultiLocation; + type Success = L; fn try_origin(outer: O) -> Result { outer.try_with_caller(|caller| { caller.try_into().and_then(|o| match o { - Origin::Xcm(location) if F::contains(&location) => Ok(location), + Origin::Xcm(ref location) + if F::contains(&location.clone().try_into().map_err(|_| o.clone().into())?) => + Ok(location.clone().try_into().map_err(|_| o.clone().into())?), Origin::Xcm(location) => Err(Origin::Xcm(location).into()), o => Err(o.into()), }) @@ -2971,15 +2980,14 @@ where } } -/// `EnsureOrigin` implementation succeeding with a `MultiLocation` value to recognize and filter +/// `EnsureOrigin` implementation succeeding with a `Location` value to recognize and filter /// the `Origin::Response` item. pub struct EnsureResponse(PhantomData); -impl, F: Contains> EnsureOrigin - for EnsureResponse +impl, F: Contains> EnsureOrigin for EnsureResponse where O::PalletsOrigin: From + TryInto, { - type Success = MultiLocation; + type Success = Location; fn try_origin(outer: O) -> Result { outer.try_with_caller(|caller| { @@ -2996,16 +3004,16 @@ where } } -/// A simple passthrough where we reuse the `MultiLocation`-typed XCM origin as the inner value of +/// A simple passthrough where we reuse the `Location`-typed XCM origin as the inner value of /// this crate's `Origin::Xcm` value. pub struct XcmPassthrough(PhantomData); impl> ConvertOrigin for XcmPassthrough { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); match kind { OriginKind::Xcm => Ok(crate::Origin::Xcm(origin).into()), diff --git a/polkadot/xcm/pallet-xcm/src/mock.rs b/polkadot/xcm/pallet-xcm/src/mock.rs index 0ac4205ed94..3ce32fa46d3 100644 --- a/polkadot/xcm/pallet-xcm/src/mock.rs +++ b/polkadot/xcm/pallet-xcm/src/mock.rs @@ -16,7 +16,7 @@ use codec::Encode; use frame_support::{ - construct_runtime, derive_impl, match_types, parameter_types, + construct_runtime, derive_impl, parameter_types, traits::{ AsEnsureOriginWithArg, ConstU128, ConstU32, Contains, Equals, Everything, EverythingBut, Nothing, @@ -76,7 +76,7 @@ pub mod pallet_test_notifier { pub enum Event { QueryPrepared(QueryId), NotifyQueryPrepared(QueryId), - ResponseReceived(MultiLocation, QueryId, Response), + ResponseReceived(Location, QueryId, Response), } #[pallet::error] @@ -89,7 +89,7 @@ pub mod pallet_test_notifier { impl Pallet { #[pallet::call_index(0)] #[pallet::weight(Weight::from_parts(1_000_000, 1_000_000))] - pub fn prepare_new_query(origin: OriginFor, querier: MultiLocation) -> DispatchResult { + pub fn prepare_new_query(origin: OriginFor, querier: Location) -> DispatchResult { let who = ensure_signed(origin)?; let id = who .using_encoded(|mut d| <[u8; 32]>::decode(&mut d)) @@ -105,10 +105,7 @@ pub mod pallet_test_notifier { #[pallet::call_index(1)] #[pallet::weight(Weight::from_parts(1_000_000, 1_000_000))] - pub fn prepare_new_notify_query( - origin: OriginFor, - querier: MultiLocation, - ) -> DispatchResult { + pub fn prepare_new_notify_query(origin: OriginFor, querier: Location) -> DispatchResult { let who = ensure_signed(origin)?; let id = who .using_encoded(|mut d| <[u8; 32]>::decode(&mut d)) @@ -144,7 +141,7 @@ construct_runtime!( { System: frame_system::{Pallet, Call, Storage, Config, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Assets: pallet_assets::{Pallet, Call, Storage, Config, Event}, + AssetsPallet: pallet_assets::{Pallet, Call, Storage, Config, Event}, ParasOrigin: origin::{Pallet, Origin}, XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config}, TestNotifier: pallet_test_notifier::{Pallet, Call, Event}, @@ -152,13 +149,13 @@ construct_runtime!( ); thread_local! { - pub static SENT_XCM: RefCell)>> = RefCell::new(Vec::new()); + pub static SENT_XCM: RefCell)>> = RefCell::new(Vec::new()); pub static FAIL_SEND_XCM: RefCell = RefCell::new(false); } -pub(crate) fn sent_xcm() -> Vec<(MultiLocation, Xcm<()>)> { +pub(crate) fn sent_xcm() -> Vec<(Location, Xcm<()>)> { SENT_XCM.with(|q| (*q.borrow()).clone()) } -pub(crate) fn take_sent_xcm() -> Vec<(MultiLocation, Xcm<()>)> { +pub(crate) fn take_sent_xcm() -> Vec<(Location, Xcm<()>)> { SENT_XCM.with(|q| { let mut r = Vec::new(); std::mem::swap(&mut r, &mut *q.borrow_mut()); @@ -171,18 +168,18 @@ pub(crate) fn set_send_xcm_artificial_failure(should_fail: bool) { /// Sender that never returns error. pub struct TestSendXcm; impl SendXcm for TestSendXcm { - type Ticket = (MultiLocation, Xcm<()>); + type Ticket = (Location, Xcm<()>); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, - ) -> SendResult<(MultiLocation, Xcm<()>)> { + ) -> SendResult<(Location, Xcm<()>)> { if FAIL_SEND_XCM.with(|q| *q.borrow()) { return Err(SendError::Transport("Intentional send failure used in tests")) } let pair = (dest.take().unwrap(), msg.take().unwrap()); - Ok((pair, MultiAssets::new())) + Ok((pair, Assets::new())) } - fn deliver(pair: (MultiLocation, Xcm<()>)) -> Result { + fn deliver(pair: (Location, Xcm<()>)) -> Result { let hash = fake_message_hash(&pair.1); SENT_XCM.with(|q| q.borrow_mut().push(pair)); Ok(hash) @@ -191,11 +188,11 @@ impl SendXcm for TestSendXcm { /// Sender that returns error if `X8` junction and stops routing pub struct TestSendXcmErrX8; impl SendXcm for TestSendXcmErrX8 { - type Ticket = (MultiLocation, Xcm<()>); + type Ticket = (Location, Xcm<()>); fn validate( - dest: &mut Option, + dest: &mut Option, _: &mut Option>, - ) -> SendResult<(MultiLocation, Xcm<()>)> { + ) -> SendResult<(Location, Xcm<()>)> { if dest.as_ref().unwrap().len() == 8 { dest.take(); Err(SendError::Transport("Destination location full")) @@ -203,7 +200,7 @@ impl SendXcm for TestSendXcmErrX8 { Err(SendError::NotApplicable) } } - fn deliver(pair: (MultiLocation, Xcm<()>)) -> Result { + fn deliver(pair: (Location, Xcm<()>)) -> Result { let hash = fake_message_hash(&pair.1); SENT_XCM.with(|q| q.borrow_mut().push(pair)); Ok(hash) @@ -212,18 +209,18 @@ impl SendXcm for TestSendXcmErrX8 { parameter_types! { pub Para3000: u32 = 3000; - pub Para3000Location: MultiLocation = Parachain(Para3000::get()).into(); + pub Para3000Location: Location = Parachain(Para3000::get()).into(); pub Para3000PaymentAmount: u128 = 1; - pub Para3000PaymentMultiAssets: MultiAssets = MultiAssets::from(MultiAsset::from((Here, Para3000PaymentAmount::get()))); + pub Para3000PaymentAssets: Assets = Assets::from(Asset::from((Here, Para3000PaymentAmount::get()))); } /// Sender only sends to `Parachain(3000)` destination requiring payment. pub struct TestPaidForPara3000SendXcm; impl SendXcm for TestPaidForPara3000SendXcm { - type Ticket = (MultiLocation, Xcm<()>); + type Ticket = (Location, Xcm<()>); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, - ) -> SendResult<(MultiLocation, Xcm<()>)> { + ) -> SendResult<(Location, Xcm<()>)> { if let Some(dest) = dest.as_ref() { if !dest.eq(&Para3000Location::get()) { return Err(SendError::NotApplicable) @@ -233,9 +230,9 @@ impl SendXcm for TestPaidForPara3000SendXcm { } let pair = (dest.take().unwrap(), msg.take().unwrap()); - Ok((pair, Para3000PaymentMultiAssets::get())) + Ok((pair, Para3000PaymentAssets::get())) } - fn deliver(pair: (MultiLocation, Xcm<()>)) -> Result { + fn deliver(pair: (Location, Xcm<()>)) -> Result { let hash = fake_message_hash(&pair.1); SENT_XCM.with(|q| q.borrow_mut().push(pair)); Ok(hash) @@ -300,17 +297,17 @@ impl pallet_balances::Config for Test { /// Simple conversion of `u32` into an `AssetId` for use in benchmarking. pub struct XcmBenchmarkHelper; #[cfg(feature = "runtime-benchmarks")] -impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { - fn create_asset_id_parameter(id: u32) -> MultiLocation { - MultiLocation { parents: 1, interior: X1(Parachain(id)) } +impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { + fn create_asset_id_parameter(id: u32) -> Location { + Location::new(1, [Parachain(id)]) } } impl pallet_assets::Config for Test { type RuntimeEvent = RuntimeEvent; type Balance = Balance; - type AssetId = MultiLocation; - type AssetIdParameter = MultiLocation; + type AssetId = Location; + type AssetIdParameter = Location; type Currency = Balances; type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = EnsureRoot; @@ -354,61 +351,61 @@ pub const OTHER_PARA_ID: u32 = 2009; pub const FILTERED_PARA_ID: u32 = 2010; parameter_types! { - pub const RelayLocation: MultiLocation = Here.into_location(); - pub const NativeAsset: MultiAsset = MultiAsset { + pub const RelayLocation: Location = Here.into_location(); + pub const NativeAsset: Asset = Asset { fun: Fungible(10), - id: Concrete(Here.into_location()), - }; - pub const SystemParachainLocation: MultiLocation = MultiLocation { - parents: 0, - interior: X1(Parachain(SOME_SYSTEM_PARA)) - }; - pub const ForeignReserveLocation: MultiLocation = MultiLocation { - parents: 0, - interior: X1(Parachain(FOREIGN_ASSET_RESERVE_PARA_ID)) + id: AssetId(Here.into_location()), }; - pub const ForeignAsset: MultiAsset = MultiAsset { + pub SystemParachainLocation: Location = Location::new( + 0, + [Parachain(SOME_SYSTEM_PARA)] + ); + pub ForeignReserveLocation: Location = Location::new( + 0, + [Parachain(FOREIGN_ASSET_RESERVE_PARA_ID)] + ); + pub ForeignAsset: Asset = Asset { fun: Fungible(10), - id: Concrete(MultiLocation { - parents: 0, - interior: X2(Parachain(FOREIGN_ASSET_RESERVE_PARA_ID), FOREIGN_ASSET_INNER_JUNCTION), - }), + id: AssetId(Location::new( + 0, + [Parachain(FOREIGN_ASSET_RESERVE_PARA_ID), FOREIGN_ASSET_INNER_JUNCTION], + )), }; - pub const UsdcReserveLocation: MultiLocation = MultiLocation { - parents: 0, - interior: X1(Parachain(USDC_RESERVE_PARA_ID)) - }; - pub const Usdc: MultiAsset = MultiAsset { + pub UsdcReserveLocation: Location = Location::new( + 0, + [Parachain(USDC_RESERVE_PARA_ID)] + ); + pub Usdc: Asset = Asset { fun: Fungible(10), - id: Concrete(MultiLocation { - parents: 0, - interior: X2(Parachain(USDC_RESERVE_PARA_ID), USDC_INNER_JUNCTION), - }), + id: AssetId(Location::new( + 0, + [Parachain(USDC_RESERVE_PARA_ID), USDC_INNER_JUNCTION], + )), }; - pub const UsdtTeleportLocation: MultiLocation = MultiLocation { - parents: 0, - interior: X1(Parachain(USDT_PARA_ID)) - }; - pub const Usdt: MultiAsset = MultiAsset { + pub UsdtTeleportLocation: Location = Location::new( + 0, + [Parachain(USDT_PARA_ID)] + ); + pub Usdt: Asset = Asset { fun: Fungible(10), - id: Concrete(MultiLocation { - parents: 0, - interior: X1(Parachain(USDT_PARA_ID)), - }), + id: AssetId(Location::new( + 0, + [Parachain(USDT_PARA_ID)], + )), }; - pub const FilteredTeleportLocation: MultiLocation = MultiLocation { - parents: 0, - interior: X1(Parachain(FILTERED_PARA_ID)) - }; - pub const FilteredTeleportAsset: MultiAsset = MultiAsset { + pub FilteredTeleportLocation: Location = Location::new( + 0, + [Parachain(FILTERED_PARA_ID)] + ); + pub FilteredTeleportAsset: Asset = Asset { fun: Fungible(10), - id: Concrete(MultiLocation { - parents: 0, - interior: X1(Parachain(FILTERED_PARA_ID)), - }), + id: AssetId(Location::new( + 0, + [Parachain(FILTERED_PARA_ID)], + )), }; pub const AnyNetwork: Option = None; - pub UniversalLocation: InteriorMultiLocation = Here; + pub UniversalLocation: InteriorLocation = Here; pub UnitWeightCost: u64 = 1_000; pub CheckingAccount: AccountId = XcmPallet::check_account(); } @@ -420,7 +417,7 @@ pub type SovereignAccountOf = ( ); pub type ForeignAssetsConvertedConcreteId = MatchedConvertedConcreteId< - MultiLocation, + Location, Balance, // Excludes relay/parent chain currency EverythingBut<(Equals,)>, @@ -432,7 +429,7 @@ pub type ForeignAssetsConvertedConcreteId = MatchedConvertedConcreteId< pub type AssetTransactors = ( XcmCurrencyAdapter, SovereignAccountOf, AccountId, ()>, FungiblesAdapter< - Assets, + AssetsPallet, ForeignAssetsConvertedConcreteId, SovereignAccountOf, AccountId, @@ -450,24 +447,29 @@ type LocalOriginConverter = ( parameter_types! { pub const BaseXcmWeight: Weight = Weight::from_parts(1_000, 1_000); - pub CurrencyPerSecondPerByte: (AssetId, u128, u128) = (Concrete(RelayLocation::get()), 1, 1); - pub TrustedLocal: (MultiAssetFilter, MultiLocation) = (All.into(), Here.into()); - pub TrustedSystemPara: (MultiAssetFilter, MultiLocation) = (NativeAsset::get().into(), SystemParachainLocation::get()); - pub TrustedUsdt: (MultiAssetFilter, MultiLocation) = (Usdt::get().into(), UsdtTeleportLocation::get()); - pub TrustedFilteredTeleport: (MultiAssetFilter, MultiLocation) = (FilteredTeleportAsset::get().into(), FilteredTeleportLocation::get()); - pub TeleportUsdtToForeign: (MultiAssetFilter, MultiLocation) = (Usdt::get().into(), ForeignReserveLocation::get()); - pub TrustedForeign: (MultiAssetFilter, MultiLocation) = (ForeignAsset::get().into(), ForeignReserveLocation::get()); - pub TrustedUsdc: (MultiAssetFilter, MultiLocation) = (Usdc::get().into(), UsdcReserveLocation::get()); + pub CurrencyPerSecondPerByte: (AssetId, u128, u128) = (AssetId(RelayLocation::get()), 1, 1); + pub TrustedLocal: (AssetFilter, Location) = (All.into(), Here.into()); + pub TrustedSystemPara: (AssetFilter, Location) = (NativeAsset::get().into(), SystemParachainLocation::get()); + pub TrustedUsdt: (AssetFilter, Location) = (Usdt::get().into(), UsdtTeleportLocation::get()); + pub TrustedFilteredTeleport: (AssetFilter, Location) = (FilteredTeleportAsset::get().into(), FilteredTeleportLocation::get()); + pub TeleportUsdtToForeign: (AssetFilter, Location) = (Usdt::get().into(), ForeignReserveLocation::get()); + pub TrustedForeign: (AssetFilter, Location) = (ForeignAsset::get().into(), ForeignReserveLocation::get()); + pub TrustedUsdc: (AssetFilter, Location) = (Usdc::get().into(), UsdcReserveLocation::get()); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; pub XcmFeesTargetAccount: AccountId = AccountId::new([167u8; 32]); } pub const XCM_FEES_NOT_WAIVED_USER_ACCOUNT: [u8; 32] = [37u8; 32]; -match_types! { - pub type XcmFeesNotWaivedLocations: impl Contains = { - MultiLocation { parents: 0, interior: X1(Junction::AccountId32 {network: None, id: XCM_FEES_NOT_WAIVED_USER_ACCOUNT})} - }; + +pub struct XcmFeesNotWaivedLocations; +impl Contains for XcmFeesNotWaivedLocations { + fn contains(location: &Location) -> bool { + matches!( + location.unpack(), + (0, [Junction::AccountId32 { network: None, id: XCM_FEES_NOT_WAIVED_USER_ACCOUNT }]) + ) + } } pub type Barrier = ( @@ -519,12 +521,12 @@ impl xcm_executor::Config for XcmConfig { pub type LocalOriginToLocation = SignedToAccountId32; parameter_types! { - pub static AdvertisedXcmVersion: pallet_xcm::XcmVersion = 3; + pub static AdvertisedXcmVersion: pallet_xcm::XcmVersion = 4; } pub struct XcmTeleportFiltered; -impl Contains<(MultiLocation, Vec)> for XcmTeleportFiltered { - fn contains(t: &(MultiLocation, Vec)) -> bool { +impl Contains<(Location, Vec)> for XcmTeleportFiltered { + fn contains(t: &(Location, Vec)) -> bool { let filtered = FilteredTeleportAsset::get(); t.1.iter().any(|asset| asset == &filtered) } @@ -566,24 +568,23 @@ impl pallet_test_notifier::Config for Test { #[cfg(feature = "runtime-benchmarks")] impl super::benchmarking::Config for Test { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parachain(1000).into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { Some((NativeAsset::get(), SystemParachainLocation::get())) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { Some(( - MultiAsset { fun: Fungible(10), id: Concrete(Here.into_location()) }, + Asset { fun: Fungible(10), id: AssetId(Here.into_location()) }, Parachain(OTHER_PARA_ID).into(), )) } - fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { - use crate::tests::assets_transfer::{into_multiassets_checked, set_up_foreign_asset}; + fn set_up_complex_asset_transfer() -> Option<(Assets, u32, Location, Box)> { + use crate::tests::assets_transfer::{into_assets_checked, set_up_foreign_asset}; // Transfer native asset (local reserve) to `USDT_PARA_ID`. Using teleport-trusted USDT for // fees. @@ -600,7 +601,7 @@ impl super::benchmarking::Config for Test { ); // create sufficient foreign asset USDT let usdt_initial_local_amount = fee_amount * 10; - let (usdt_chain, _, usdt_id_multilocation) = set_up_foreign_asset( + let (usdt_chain, _, usdt_id_location) = set_up_foreign_asset( USDT_PARA_ID, None, caller.clone(), @@ -610,22 +611,25 @@ impl super::benchmarking::Config for Test { // native assets transfer destination is USDT chain (teleport trust only for USDT) let dest = usdt_chain; - let (assets, fee_index, _, _) = into_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // USDT for fees (is sufficient on local chain too) - teleported - (usdt_id_multilocation, fee_amount).into(), + (usdt_id_location.clone(), fee_amount).into(), // native asset to transfer (not used for fees) - local reserve - (MultiLocation::here(), asset_amount).into(), + (Location::here(), asset_amount).into(), ); // verify initial balances assert_eq!(Balances::free_balance(&caller), balance); - assert_eq!(Assets::balance(usdt_id_multilocation, &caller), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), &caller), + usdt_initial_local_amount + ); // verify transferred successfully let verify = Box::new(move || { // verify balances after transfer, decreased by transferred amounts assert_eq!(Balances::free_balance(&caller), balance - asset_amount); assert_eq!( - Assets::balance(usdt_id_multilocation, &caller), + AssetsPallet::balance(usdt_id_location, &caller), usdt_initial_local_amount - fee_amount ); }); @@ -641,13 +645,13 @@ pub(crate) fn last_events(n: usize) -> Vec { System::events().into_iter().map(|e| e.event).rev().take(n).rev().collect() } -pub(crate) fn buy_execution(fees: impl Into) -> Instruction { +pub(crate) fn buy_execution(fees: impl Into) -> Instruction { use xcm::latest::prelude::*; BuyExecution { fees: fees.into(), weight_limit: Unlimited } } pub(crate) fn buy_limited_execution( - fees: impl Into, + fees: impl Into, weight_limit: WeightLimit, ) -> Instruction { use xcm::latest::prelude::*; diff --git a/polkadot/xcm/pallet-xcm/src/tests/assets_transfer.rs b/polkadot/xcm/pallet-xcm/src/tests/assets_transfer.rs index 6893bae2b6c..27be5cce145 100644 --- a/polkadot/xcm/pallet-xcm/src/tests/assets_transfer.rs +++ b/polkadot/xcm/pallet-xcm/src/tests/assets_transfer.rs @@ -33,8 +33,8 @@ use xcm_executor::traits::ConvertLocation; // Helper function to deduplicate testing different teleport types. fn do_test_and_verify_teleport_assets( - origin_location: MultiLocation, - expected_beneficiary: MultiLocation, + origin_location: Location, + expected_beneficiary: Location, call: Call, expected_weight_limit: WeightLimit, ) { @@ -70,13 +70,15 @@ fn do_test_and_verify_teleport_assets( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { paying: origin_location, - fees: MultiAssets::new(), + fees: Assets::new(), }) ); assert!(matches!( @@ -92,11 +94,11 @@ fn do_test_and_verify_teleport_assets( /// local effects. #[test] fn teleport_assets_works() { - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into(); + let origin_location: Location = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = AccountId32 { network: None, id: BOB.into() }.into(); do_test_and_verify_teleport_assets( - origin_location, - beneficiary, + origin_location.clone(), + beneficiary.clone(), || { assert_ok!(XcmPallet::teleport_assets( RuntimeOrigin::signed(ALICE), @@ -116,13 +118,13 @@ fn teleport_assets_works() { /// local effects. #[test] fn limited_teleport_assets_works() { - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into(); + let origin_location: Location = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = AccountId32 { network: None, id: BOB.into() }.into(); let weight_limit = WeightLimit::Limited(Weight::from_parts(5000, 5000)); let expected_weight_limit = weight_limit.clone(); do_test_and_verify_teleport_assets( - origin_location, - beneficiary, + origin_location.clone(), + beneficiary.clone(), || { assert_ok!(XcmPallet::limited_teleport_assets( RuntimeOrigin::signed(ALICE), @@ -140,7 +142,7 @@ fn limited_teleport_assets_works() { /// `limited_teleport_assets` should fail for filtered assets #[test] fn limited_teleport_filtered_assets_disallowed() { - let beneficiary: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into(); + let beneficiary: Location = AccountId32 { network: None, id: BOB.into() }.into(); new_test_ext_with_balances(vec![(ALICE, INITIAL_BALANCE)]).execute_with(|| { let result = XcmPallet::limited_teleport_assets( RuntimeOrigin::signed(ALICE), @@ -165,7 +167,7 @@ fn limited_teleport_filtered_assets_disallowed() { /// /// Asserts that the sender's balance is decreased and the beneficiary's balance /// is increased. Verifies the correct message is sent and event is emitted. -/// Verifies that XCM router fees (`SendXcm::validate` -> `MultiAssets`) are withdrawn from correct +/// Verifies that XCM router fees (`SendXcm::validate` -> `Assets`) are withdrawn from correct /// user account and deposited to a correct target account (`XcmFeesTargetAccount`). #[test] fn reserve_transfer_assets_with_paid_router_works() { @@ -179,13 +181,13 @@ fn reserve_transfer_assets_with_paid_router_works() { new_test_ext_with_balances(balances).execute_with(|| { let xcm_router_fee_amount = Para3000PaymentAmount::get(); let weight = BaseXcmWeight::get(); - let dest: MultiLocation = - AccountId32 { network: None, id: user_account.clone().into() }.into(); + let dest: Location = + Junction::AccountId32 { network: None, id: user_account.clone().into() }.into(); assert_eq!(Balances::total_balance(&user_account), INITIAL_BALANCE); assert_ok!(XcmPallet::reserve_transfer_assets( RuntimeOrigin::signed(user_account.clone()), Box::new(Parachain(paid_para_id).into()), - Box::new(dest.into()), + Box::new(dest.clone().into()), Box::new((Here, SEND_AMOUNT).into()), 0, )); @@ -206,7 +208,7 @@ fn reserve_transfer_assets_with_paid_router_works() { INITIAL_BALANCE + xcm_router_fee_amount ); - let dest_para: MultiLocation = Parachain(paid_para_id).into(); + let dest_para: Location = Parachain(paid_para_id).into(); assert_eq!( sent_xcm(), vec![( @@ -215,14 +217,16 @@ fn reserve_transfer_assets_with_paid_router_works() { ReserveAssetDeposited((Parent, SEND_AMOUNT).into()), ClearOrigin, buy_execution((Parent, SEND_AMOUNT)), - DepositAsset { assets: AllCounted(1).into(), beneficiary: dest }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: dest.clone() }, ]), )] ); let mut last_events = last_events(5).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); // balances events last_events.next().unwrap(); @@ -231,7 +235,7 @@ fn reserve_transfer_assets_with_paid_router_works() { last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { paying: dest, - fees: Para3000PaymentMultiAssets::get(), + fees: Para3000PaymentAssets::get(), }) ); assert!(matches!( @@ -247,45 +251,45 @@ pub(crate) fn set_up_foreign_asset( benficiary: AccountId, initial_amount: u128, is_sufficient: bool, -) -> (MultiLocation, AccountId, MultiLocation) { +) -> (Location, AccountId, Location) { let reserve_location = RelayLocation::get().pushed_with_interior(Parachain(reserve_para_id)).unwrap(); let reserve_sovereign_account = SovereignAccountOf::convert_location(&reserve_location).unwrap(); - let foreign_asset_id_multilocation = if let Some(junction) = inner_junction { - reserve_location.pushed_with_interior(junction).unwrap() + let foreign_asset_id_location = if let Some(junction) = inner_junction { + reserve_location.clone().pushed_with_interior(junction).unwrap() } else { - reserve_location + reserve_location.clone() }; - // create sufficient (to be used as fees as well) foreign asset - assert_ok!(Assets::force_create( + // create sufficient (to be used as fees as well) foreign asset (0 total issuance) + assert_ok!(AssetsPallet::force_create( RuntimeOrigin::root(), - foreign_asset_id_multilocation, + foreign_asset_id_location.clone(), BOB, is_sufficient, 1 )); // this asset should have been teleported/reserve-transferred in, but for this test we just // mint it locally. - assert_ok!(Assets::mint( + assert_ok!(AssetsPallet::mint( RuntimeOrigin::signed(BOB), - foreign_asset_id_multilocation, + foreign_asset_id_location.clone(), benficiary, initial_amount )); - (reserve_location, reserve_sovereign_account, foreign_asset_id_multilocation) + (reserve_location, reserve_sovereign_account, foreign_asset_id_location) } // Helper function that provides correct `fee_index` after `sort()` done by -// `vec![MultiAsset, MultiAsset].into()`. -pub(crate) fn into_multiassets_checked( - fee_asset: MultiAsset, - transfer_asset: MultiAsset, -) -> (MultiAssets, usize, MultiAsset, MultiAsset) { - let assets: MultiAssets = vec![fee_asset.clone(), transfer_asset.clone()].into(); +// `vec![Asset, Asset].into()`. +pub(crate) fn into_assets_checked( + fee_asset: Asset, + transfer_asset: Asset, +) -> (Assets, usize, Asset, Asset) { + let assets: Assets = vec![fee_asset.clone(), transfer_asset.clone()].into(); let fee_index = if assets.get(0).unwrap().eq(&fee_asset) { 0 } else { 1 }; (assets, fee_index, fee_asset, transfer_asset) } @@ -302,9 +306,9 @@ fn local_asset_reserve_and_local_fee_reserve_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, @@ -313,12 +317,14 @@ fn local_asset_reserve_and_local_fee_reserve_call( (ALICE, INITIAL_BALANCE), (ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + + let origin_location: Location = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); let weight_limit = WeightLimit::Limited(Weight::from_parts(5000, 5000)); let expected_weight_limit = weight_limit.clone(); - let expected_beneficiary = beneficiary; - let dest: MultiLocation = Parachain(OTHER_PARA_ID).into(); + let expected_beneficiary = beneficiary.clone(); + let dest: Location = Parachain(OTHER_PARA_ID).into(); new_test_ext_with_balances(balances).execute_with(|| { let weight = BaseXcmWeight::get(); @@ -326,8 +332,8 @@ fn local_asset_reserve_and_local_fee_reserve_call( // call extrinsic let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new((Here, SEND_AMOUNT).into()), 0, weight_limit, @@ -352,7 +358,7 @@ fn local_asset_reserve_and_local_fee_reserve_call( buy_limited_execution((Parent, SEND_AMOUNT), expected_weight_limit), DepositAsset { assets: AllCounted(1).into(), - beneficiary: expected_beneficiary + beneficiary: expected_beneficiary.clone() }, ]), )] @@ -360,13 +366,15 @@ fn local_asset_reserve_and_local_fee_reserve_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { paying: origin_location, - fees: MultiAssets::new(), + fees: Assets::new(), }) ); assert!(matches!( @@ -423,21 +431,22 @@ fn destination_asset_reserve_and_local_fee_reserve_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let weight = BaseXcmWeight::get() * 3; let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create non-sufficient foreign asset BLA let foreign_initial_amount = 142; - let (reserve_location, reserve_sovereign_account, foreign_asset_id_multilocation) = + let (reserve_location, reserve_sovereign_account, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), @@ -449,27 +458,30 @@ fn destination_asset_reserve_and_local_fee_reserve_call( // transfer destination is reserve location (no teleport trust) let dest = reserve_location; - let (assets, fee_index, fee_asset, xfer_asset) = into_multiassets_checked( + let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( // native asset for fee - local reserve - (MultiLocation::here(), FEE_AMOUNT).into(), + (Location::here(), FEE_AMOUNT).into(), // foreign asset to transfer - destination reserve - (foreign_asset_id_multilocation, SEND_AMOUNT).into(), + (foreign_asset_id_location.clone(), SEND_AMOUNT).into(), ); // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, context).unwrap(); - let expected_asset = xfer_asset.reanchored(&dest, context).unwrap(); + let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index as u32, Unlimited, @@ -483,24 +495,32 @@ fn destination_asset_reserve_and_local_fee_reserve_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); // Alice spent (transferred) amount assert_eq!( - Assets::balance(foreign_asset_id_multilocation, ALICE), + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), foreign_initial_amount - SEND_AMOUNT ); // Alice used native asset for fees assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - FEE_AMOUNT); // Destination account (parachain account) added native reserve used as fee to balances assert_eq!(Balances::free_balance(reserve_sovereign_account.clone()), FEE_AMOUNT); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, reserve_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), reserve_sovereign_account), + 0 + ); // Verify total and active issuance of foreign BLA have decreased (burned on // reserve-withdraw) let expected_issuance = foreign_initial_amount - SEND_AMOUNT; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_issuance); // Verify sent XCM program assert_eq!( @@ -514,7 +534,7 @@ fn destination_asset_reserve_and_local_fee_reserve_call( buy_limited_execution(expected_fee, Unlimited), WithdrawAsset(expected_asset.into()), ClearOrigin, - DepositAsset { assets: AllCounted(2).into(), beneficiary }, + DepositAsset { assets: AllCounted(2).into(), beneficiary: beneficiary.clone() }, ]) )] ); @@ -522,7 +542,7 @@ fn destination_asset_reserve_and_local_fee_reserve_call( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { paying: origin_location, - fees: MultiAssets::new(), + fees: Assets::new(), }) ); assert!(matches!( @@ -582,19 +602,19 @@ fn remote_asset_reserve_and_local_fee_reserve_call_disallowed( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create non-sufficient foreign asset BLA let foreign_initial_amount = 142; - let (_, _, foreign_asset_id_multilocation) = set_up_foreign_asset( + let (_, _, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), ALICE, @@ -606,15 +626,18 @@ fn remote_asset_reserve_and_local_fee_reserve_call_disallowed( // chain) let dest = RelayLocation::get().pushed_with_interior(Parachain(OTHER_PARA_ID)).unwrap(); - let (assets, fee_index, _, _) = into_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // native asset for fee - local reserve - (MultiLocation::here(), FEE_AMOUNT).into(), + (Location::here(), FEE_AMOUNT).into(), // foreign asset to transfer - remote reserve - (foreign_asset_id_multilocation, SEND_AMOUNT).into(), + (foreign_asset_id_location.clone(), SEND_AMOUNT).into(), ); // balances checks before - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // try the transfer @@ -629,14 +652,20 @@ fn remote_asset_reserve_and_local_fee_reserve_call_disallowed( assert_eq!(result, expected_result); // Alice transferred nothing - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); // Alice spent native asset for fees assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Verify total and active issuance of foreign BLA asset have decreased (burned on // reserve-withdraw) let expected_issuance = foreign_initial_amount; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_issuance); }); } @@ -698,20 +727,21 @@ fn local_asset_reserve_and_destination_fee_reserve_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDC let usdc_initial_local_amount = 142; - let (usdc_reserve_location, usdc_chain_sovereign_account, usdc_id_multilocation) = + let (usdc_reserve_location, usdc_chain_sovereign_account, usdc_id_location) = set_up_foreign_asset( USDC_RESERVE_PARA_ID, Some(USDC_INNER_JUNCTION), @@ -723,27 +753,30 @@ fn local_asset_reserve_and_destination_fee_reserve_call( // native assets transfer to fee reserve location (no teleport trust) let dest = usdc_reserve_location; - let (assets, fee_index, fee_asset, xfer_asset) = into_multiassets_checked( + let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( // usdc for fees (is sufficient on local chain too) - destination reserve - (usdc_id_multilocation, FEE_AMOUNT).into(), + (usdc_id_location.clone(), FEE_AMOUNT).into(), // native asset to transfer (not used for fees) - local reserve - (MultiLocation::here(), SEND_AMOUNT).into(), + (Location::here(), SEND_AMOUNT).into(), ); // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, context).unwrap(); - let expected_asset = xfer_asset.reanchored(&dest, context).unwrap(); + let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index as u32, Unlimited, @@ -758,13 +791,15 @@ fn local_asset_reserve_and_destination_fee_reserve_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { - paying: origin_location, - fees: MultiAssets::new(), + paying: origin_location.clone(), + fees: Assets::new(), }) ); assert!(matches!( @@ -774,18 +809,21 @@ fn local_asset_reserve_and_destination_fee_reserve_call( // Alice spent (fees) amount assert_eq!( - Assets::balance(usdc_id_multilocation, ALICE), + AssetsPallet::balance(usdc_id_location.clone(), ALICE), usdc_initial_local_amount - FEE_AMOUNT ); // Alice used native asset for transfer assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - SEND_AMOUNT); // Sovereign account of dest parachain holds `SEND_AMOUNT` native asset in local reserve assert_eq!(Balances::free_balance(usdc_chain_sovereign_account.clone()), SEND_AMOUNT); - assert_eq!(Assets::balance(usdc_id_multilocation, usdc_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), usdc_chain_sovereign_account), + 0 + ); // Verify total and active issuance of USDC have decreased (burned on reserve-withdraw) let expected_issuance = usdc_initial_local_amount - FEE_AMOUNT; - assert_eq!(Assets::total_issuance(usdc_id_multilocation), expected_issuance); - assert_eq!(Assets::active_issuance(usdc_id_multilocation), expected_issuance); + assert_eq!(AssetsPallet::total_issuance(usdc_id_location.clone()), expected_issuance); + assert_eq!(AssetsPallet::active_issuance(usdc_id_location), expected_issuance); // Verify sent XCM program assert_eq!( @@ -856,21 +894,22 @@ fn destination_asset_reserve_and_destination_fee_reserve_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // we'll send just this foreign asset back to its reserve location and use it for fees as // well let foreign_initial_amount = 142; - let (reserve_location, reserve_sovereign_account, foreign_asset_id_multilocation) = + let (reserve_location, reserve_sovereign_account, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), @@ -881,22 +920,25 @@ fn destination_asset_reserve_and_destination_fee_reserve_call( // transfer destination is reserve location let dest = reserve_location; - let assets: MultiAssets = vec![(foreign_asset_id_multilocation, SEND_AMOUNT).into()].into(); + let assets: Assets = vec![(foreign_asset_id_location.clone(), SEND_AMOUNT).into()].into(); let fee_index = 0; // reanchor according to test-case let mut expected_assets = assets.clone(); - expected_assets.reanchor(&dest, UniversalLocation::get()).unwrap(); + expected_assets.reanchor(&dest, &UniversalLocation::get()).unwrap(); // balances checks before - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index, Unlimited, @@ -911,13 +953,15 @@ fn destination_asset_reserve_and_destination_fee_reserve_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { - paying: origin_location, - fees: MultiAssets::new(), + paying: origin_location.clone(), + fees: Assets::new(), }) ); assert!(matches!( @@ -927,19 +971,25 @@ fn destination_asset_reserve_and_destination_fee_reserve_call( // Alice spent (transferred) amount assert_eq!( - Assets::balance(foreign_asset_id_multilocation, ALICE), + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), foreign_initial_amount - SEND_AMOUNT ); // Alice's native asset balance is untouched assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Reserve sovereign account has same balances assert_eq!(Balances::free_balance(reserve_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, reserve_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), reserve_sovereign_account), + 0 + ); // Verify total and active issuance of foreign BLA have decreased (burned on // reserve-withdraw) let expected_issuance = foreign_initial_amount - SEND_AMOUNT; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_issuance); // Verify sent XCM program assert_eq!( @@ -950,7 +1000,7 @@ fn destination_asset_reserve_and_destination_fee_reserve_call( WithdrawAsset(expected_assets.clone()), ClearOrigin, buy_limited_execution(expected_assets.get(0).unwrap().clone(), Unlimited), - DepositAsset { assets: AllCounted(1).into(), beneficiary }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: beneficiary.clone() }, ]), )] ); @@ -1003,19 +1053,19 @@ fn remote_asset_reserve_and_destination_fee_reserve_call_disallowed( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDC let usdc_initial_local_amount = 42; - let (usdc_chain, _, usdc_id_multilocation) = set_up_foreign_asset( + let (usdc_chain, _, usdc_id_location) = set_up_foreign_asset( USDC_RESERVE_PARA_ID, Some(USDC_INNER_JUNCTION), ALICE, @@ -1025,7 +1075,7 @@ fn remote_asset_reserve_and_destination_fee_reserve_call_disallowed( // create non-sufficient foreign asset BLA let foreign_initial_amount = 142; - let (_, _, foreign_asset_id_multilocation) = set_up_foreign_asset( + let (_, _, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), ALICE, @@ -1037,16 +1087,22 @@ fn remote_asset_reserve_and_destination_fee_reserve_call_disallowed( // reserve chain) let dest = usdc_chain; - let (assets, fee_index, _, _) = into_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // USDC for fees (is sufficient on local chain too) - destination reserve - (usdc_id_multilocation, FEE_AMOUNT).into(), + (usdc_id_location.clone(), FEE_AMOUNT).into(), // foreign asset to transfer (not used for fees) - remote reserve - (foreign_asset_id_multilocation, SEND_AMOUNT).into(), + (foreign_asset_id_location.clone(), SEND_AMOUNT).into(), ); // balances checks before - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer @@ -1062,14 +1118,23 @@ fn remote_asset_reserve_and_destination_fee_reserve_call_disallowed( // Alice native asset untouched assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); let expected_usdc_issuance = usdc_initial_local_amount; - assert_eq!(Assets::total_issuance(usdc_id_multilocation), expected_usdc_issuance); - assert_eq!(Assets::active_issuance(usdc_id_multilocation), expected_usdc_issuance); + assert_eq!(AssetsPallet::total_issuance(usdc_id_location.clone()), expected_usdc_issuance); + assert_eq!(AssetsPallet::active_issuance(usdc_id_location.clone()), expected_usdc_issuance); let expected_bla_issuance = foreign_initial_amount; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_bla_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_bla_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_bla_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_bla_issuance); }); } @@ -1127,19 +1192,19 @@ fn local_asset_reserve_and_remote_fee_reserve_call_disallowed( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDC let usdc_initial_local_amount = 142; - let (_, usdc_chain_sovereign_account, usdc_id_multilocation) = set_up_foreign_asset( + let (_, usdc_chain_sovereign_account, usdc_id_location) = set_up_foreign_asset( USDC_RESERVE_PARA_ID, Some(USDC_INNER_JUNCTION), ALICE, @@ -1151,15 +1216,18 @@ fn local_asset_reserve_and_remote_fee_reserve_call_disallowed( let dest = RelayLocation::get().pushed_with_interior(Parachain(OTHER_PARA_ID)).unwrap(); let dest_sovereign_account = SovereignAccountOf::convert_location(&dest).unwrap(); - let (assets, fee_index, _, _) = into_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // USDC for fees (is sufficient on local chain too) - remote reserve - (usdc_id_multilocation, FEE_AMOUNT).into(), + (usdc_id_location.clone(), FEE_AMOUNT).into(), // native asset to transfer (not used for fees) - local reserve - (MultiLocation::here(), SEND_AMOUNT).into(), + (Location::here(), SEND_AMOUNT).into(), ); // balances checks before - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer @@ -1172,15 +1240,21 @@ fn local_asset_reserve_and_remote_fee_reserve_call_disallowed( Unlimited, ); assert_eq!(result, expected_result); - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Sovereign account of reserve parachain is unchanged assert_eq!(Balances::free_balance(usdc_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdc_id_multilocation, usdc_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), usdc_chain_sovereign_account), + 0 + ); assert_eq!(Balances::free_balance(dest_sovereign_account), 0); let expected_usdc_issuance = usdc_initial_local_amount; - assert_eq!(Assets::total_issuance(usdc_id_multilocation), expected_usdc_issuance); - assert_eq!(Assets::active_issuance(usdc_id_multilocation), expected_usdc_issuance); + assert_eq!(AssetsPallet::total_issuance(usdc_id_location.clone()), expected_usdc_issuance); + assert_eq!(AssetsPallet::active_issuance(usdc_id_location), expected_usdc_issuance); }); } @@ -1237,19 +1311,19 @@ fn destination_asset_reserve_and_remote_fee_reserve_call_disallowed( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDC let usdc_initial_local_amount = 42; - let (_, usdc_chain_sovereign_account, usdc_id_multilocation) = set_up_foreign_asset( + let (_, usdc_chain_sovereign_account, usdc_id_location) = set_up_foreign_asset( USDC_RESERVE_PARA_ID, Some(USDC_INNER_JUNCTION), ALICE, @@ -1259,7 +1333,7 @@ fn destination_asset_reserve_and_remote_fee_reserve_call_disallowed( // create non-sufficient foreign asset BLA let foreign_initial_amount = 142; - let (reserve_location, foreign_sovereign_account, foreign_asset_id_multilocation) = + let (reserve_location, foreign_sovereign_account, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), @@ -1272,15 +1346,18 @@ fn destination_asset_reserve_and_remote_fee_reserve_call_disallowed( let dest = reserve_location; let dest_sovereign_account = foreign_sovereign_account; - let (assets, fee_index, _, _) = into_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // USDC for fees (is sufficient on local chain too) - remote reserve - (usdc_id_multilocation, FEE_AMOUNT).into(), + (usdc_id_location.clone(), FEE_AMOUNT).into(), // foreign asset to transfer (not used for fees) - destination reserve - (foreign_asset_id_multilocation, SEND_AMOUNT).into(), + (foreign_asset_id_location.clone(), SEND_AMOUNT).into(), ); // balances checks before - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer @@ -1295,18 +1372,33 @@ fn destination_asset_reserve_and_remote_fee_reserve_call_disallowed( assert_eq!(result, expected_result); // Alice native asset untouched assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); assert_eq!(Balances::free_balance(usdc_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdc_id_multilocation, usdc_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), usdc_chain_sovereign_account), + 0 + ); assert_eq!(Balances::free_balance(dest_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, dest_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), dest_sovereign_account), + 0 + ); let expected_usdc_issuance = usdc_initial_local_amount; - assert_eq!(Assets::total_issuance(usdc_id_multilocation), expected_usdc_issuance); - assert_eq!(Assets::active_issuance(usdc_id_multilocation), expected_usdc_issuance); + assert_eq!(AssetsPallet::total_issuance(usdc_id_location.clone()), expected_usdc_issuance); + assert_eq!(AssetsPallet::active_issuance(usdc_id_location.clone()), expected_usdc_issuance); let expected_bla_issuance = foreign_initial_amount; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_bla_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_bla_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_bla_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_bla_issuance); }); } @@ -1377,52 +1469,54 @@ fn remote_asset_reserve_and_remote_fee_reserve_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDC let usdc_initial_local_amount = 142; - let (usdc_chain, usdc_chain_sovereign_account, usdc_id_multilocation) = - set_up_foreign_asset( - USDC_RESERVE_PARA_ID, - Some(USDC_INNER_JUNCTION), - ALICE, - usdc_initial_local_amount, - true, - ); + let (usdc_chain, usdc_chain_sovereign_account, usdc_id_location) = set_up_foreign_asset( + USDC_RESERVE_PARA_ID, + Some(USDC_INNER_JUNCTION), + ALICE, + usdc_initial_local_amount, + true, + ); // transfer destination is some other parachain let dest = RelayLocation::get().pushed_with_interior(Parachain(OTHER_PARA_ID)).unwrap(); - let assets: MultiAssets = vec![(usdc_id_multilocation, SEND_AMOUNT).into()].into(); - let fee_index = 0u32; + let assets: Assets = vec![(usdc_id_location.clone(), SEND_AMOUNT).into()].into(); + let fee_index = 0; // reanchor according to test-case let context = UniversalLocation::get(); - let expected_dest_on_reserve = dest.reanchored(&usdc_chain, context).unwrap(); + let expected_dest_on_reserve = dest.clone().reanchored(&usdc_chain, &context).unwrap(); let fees = assets.get(fee_index as usize).unwrap().clone(); let (fees_half_1, fees_half_2) = XcmPallet::halve_fees(fees).unwrap(); let mut expected_assets_on_reserve = assets.clone(); - expected_assets_on_reserve.reanchor(&usdc_chain, context).unwrap(); - let expected_fee_on_reserve = fees_half_1.reanchored(&usdc_chain, context).unwrap(); - let expected_fee_on_dest = fees_half_2.reanchored(&dest, context).unwrap(); + expected_assets_on_reserve.reanchor(&usdc_chain, &context).unwrap(); + let expected_fee_on_reserve = fees_half_1.reanchored(&usdc_chain, &context).unwrap(); + let expected_fee_on_dest = fees_half_2.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index, Unlimited, @@ -1435,23 +1529,26 @@ fn remote_asset_reserve_and_remote_fee_reserve_call( assert!(matches!( last_event(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(_) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete { .. } }) )); // Alice spent (transferred) amount assert_eq!( - Assets::balance(usdc_id_multilocation, ALICE), + AssetsPallet::balance(usdc_id_location.clone(), ALICE), usdc_initial_local_amount - SEND_AMOUNT ); // Alice's native asset balance is untouched assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Destination account (parachain account) has expected (same) balances assert_eq!(Balances::free_balance(usdc_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdc_id_multilocation, usdc_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), usdc_chain_sovereign_account), + 0 + ); // Verify total and active issuance of USDC have decreased (burned on reserve-withdraw) let expected_usdc_issuance = usdc_initial_local_amount - SEND_AMOUNT; - assert_eq!(Assets::total_issuance(usdc_id_multilocation), expected_usdc_issuance); - assert_eq!(Assets::active_issuance(usdc_id_multilocation), expected_usdc_issuance); + assert_eq!(AssetsPallet::total_issuance(usdc_id_location.clone()), expected_usdc_issuance); + assert_eq!(AssetsPallet::active_issuance(usdc_id_location.clone()), expected_usdc_issuance); // Verify sent XCM program assert_eq!( @@ -1523,46 +1620,50 @@ fn local_asset_reserve_and_teleported_fee_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDT let usdt_initial_local_amount = 42; - let (usdt_chain, usdt_chain_sovereign_account, usdt_id_multilocation) = + let (usdt_chain, usdt_chain_sovereign_account, usdt_id_location) = set_up_foreign_asset(USDT_PARA_ID, None, ALICE, usdt_initial_local_amount, true); // native assets transfer destination is USDT chain (teleport trust only for USDT) let dest = usdt_chain; - let (assets, fee_index, fee_asset, xfer_asset) = into_multiassets_checked( + let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( // USDT for fees (is sufficient on local chain too) - teleported - (usdt_id_multilocation, FEE_AMOUNT).into(), + (usdt_id_location.clone(), FEE_AMOUNT).into(), // native asset to transfer (not used for fees) - local reserve - (MultiLocation::here(), SEND_AMOUNT).into(), + (Location::here(), SEND_AMOUNT).into(), ); // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, context).unwrap(); - let expected_asset = xfer_asset.reanchored(&dest, context).unwrap(); + let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index as u32, Unlimited, @@ -1577,13 +1678,15 @@ fn local_asset_reserve_and_teleported_fee_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { - paying: origin_location, - fees: MultiAssets::new(), + paying: origin_location.clone(), + fees: Assets::new(), }) ); assert!(matches!( @@ -1592,18 +1695,21 @@ fn local_asset_reserve_and_teleported_fee_call( )); // Alice spent (fees) amount assert_eq!( - Assets::balance(usdt_id_multilocation, ALICE), + AssetsPallet::balance(usdt_id_location.clone(), ALICE), usdt_initial_local_amount - FEE_AMOUNT ); // Alice used native asset for transfer assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - SEND_AMOUNT); // Sovereign account of dest parachain holds `SEND_AMOUNT` native asset in local reserve assert_eq!(Balances::free_balance(usdt_chain_sovereign_account.clone()), SEND_AMOUNT); - assert_eq!(Assets::balance(usdt_id_multilocation, usdt_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), usdt_chain_sovereign_account), + 0 + ); // Verify total and active issuance have decreased (teleported) let expected_usdt_issuance = usdt_initial_local_amount - FEE_AMOUNT; - assert_eq!(Assets::total_issuance(usdt_id_multilocation), expected_usdt_issuance); - assert_eq!(Assets::active_issuance(usdt_id_multilocation), expected_usdt_issuance); + assert_eq!(AssetsPallet::total_issuance(usdt_id_location.clone()), expected_usdt_issuance); + assert_eq!(AssetsPallet::active_issuance(usdt_id_location), expected_usdt_issuance); // Verify sent XCM program assert_eq!( @@ -1672,25 +1778,26 @@ fn destination_asset_reserve_and_teleported_fee_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDT let usdt_initial_local_amount = 42; - let (_, usdt_chain_sovereign_account, usdt_id_multilocation) = + let (_, usdt_chain_sovereign_account, usdt_id_location) = set_up_foreign_asset(USDT_PARA_ID, None, ALICE, usdt_initial_local_amount, true); // create non-sufficient foreign asset BLA let foreign_initial_amount = 142; - let (reserve_location, foreign_sovereign_account, foreign_asset_id_multilocation) = + let (reserve_location, foreign_sovereign_account, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), @@ -1703,27 +1810,30 @@ fn destination_asset_reserve_and_teleported_fee_call( let dest = reserve_location; let dest_sovereign_account = foreign_sovereign_account; - let (assets, fee_index, fee_asset, xfer_asset) = into_multiassets_checked( + let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( // USDT for fees (is sufficient on local chain too) - teleported - (usdt_id_multilocation, FEE_AMOUNT).into(), + (usdt_id_location.clone(), FEE_AMOUNT).into(), // foreign asset to transfer (not used for fees) - destination reserve - (foreign_asset_id_multilocation, SEND_AMOUNT).into(), + (foreign_asset_id_location.clone(), SEND_AMOUNT).into(), ); // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, context).unwrap(); - let expected_asset = xfer_asset.reanchored(&dest, context).unwrap(); + let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index as u32, Unlimited, @@ -1738,13 +1848,15 @@ fn destination_asset_reserve_and_teleported_fee_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { - paying: origin_location, - fees: MultiAssets::new(), + paying: origin_location.clone(), + fees: Assets::new(), }) ); assert!(matches!( @@ -1755,29 +1867,38 @@ fn destination_asset_reserve_and_teleported_fee_call( assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Alice spent USDT for fees assert_eq!( - Assets::balance(usdt_id_multilocation, ALICE), + AssetsPallet::balance(usdt_id_location.clone(), ALICE), usdt_initial_local_amount - FEE_AMOUNT ); // Alice transferred BLA assert_eq!( - Assets::balance(foreign_asset_id_multilocation, ALICE), + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), foreign_initial_amount - SEND_AMOUNT ); // Verify balances of USDT reserve parachain assert_eq!(Balances::free_balance(usdt_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdt_id_multilocation, usdt_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), usdt_chain_sovereign_account), + 0 + ); // Verify balances of transferred-asset reserve parachain assert_eq!(Balances::free_balance(dest_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, dest_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), dest_sovereign_account), + 0 + ); // Verify total and active issuance of USDT have decreased (teleported) let expected_usdt_issuance = usdt_initial_local_amount - FEE_AMOUNT; - assert_eq!(Assets::total_issuance(usdt_id_multilocation), expected_usdt_issuance); - assert_eq!(Assets::active_issuance(usdt_id_multilocation), expected_usdt_issuance); + assert_eq!(AssetsPallet::total_issuance(usdt_id_location.clone()), expected_usdt_issuance); + assert_eq!(AssetsPallet::active_issuance(usdt_id_location.clone()), expected_usdt_issuance); // Verify total and active issuance of foreign BLA asset have decreased (burned on // reserve-withdraw) let expected_bla_issuance = foreign_initial_amount - SEND_AMOUNT; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_bla_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_bla_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_bla_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_bla_issuance); // Verify sent XCM program assert_eq!( @@ -1844,24 +1965,24 @@ fn remote_asset_reserve_and_teleported_fee_reserve_call_disallowed( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDT let usdt_initial_local_amount = 42; - let (usdt_chain, usdt_chain_sovereign_account, usdt_id_multilocation) = + let (usdt_chain, usdt_chain_sovereign_account, usdt_id_location) = set_up_foreign_asset(USDT_PARA_ID, None, ALICE, usdt_initial_local_amount, true); // create non-sufficient foreign asset BLA let foreign_initial_amount = 142; - let (_, reserve_sovereign_account, foreign_asset_id_multilocation) = set_up_foreign_asset( + let (_, reserve_sovereign_account, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), ALICE, @@ -1872,15 +1993,18 @@ fn remote_asset_reserve_and_teleported_fee_reserve_call_disallowed( // transfer destination is USDT chain (foreign asset needs to go through its reserve chain) let dest = usdt_chain; - let (assets, fee_index, _, _) = into_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // USDT for fees (is sufficient on local chain too) - teleported - (usdt_id_multilocation, FEE_AMOUNT).into(), + (usdt_id_location.clone(), FEE_AMOUNT).into(), // foreign asset to transfer (not used for fees) - remote reserve - (foreign_asset_id_multilocation, SEND_AMOUNT).into(), + (foreign_asset_id_location.clone(), SEND_AMOUNT).into(), ); // balances checks before - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // try the transfer @@ -1895,18 +2019,33 @@ fn remote_asset_reserve_and_teleported_fee_reserve_call_disallowed( assert_eq!(result, expected_result); // Alice native asset untouched assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); assert_eq!(Balances::free_balance(usdt_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdt_id_multilocation, usdt_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), usdt_chain_sovereign_account), + 0 + ); assert_eq!(Balances::free_balance(reserve_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, reserve_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), reserve_sovereign_account), + 0 + ); let expected_usdt_issuance = usdt_initial_local_amount; - assert_eq!(Assets::total_issuance(usdt_id_multilocation), expected_usdt_issuance); - assert_eq!(Assets::active_issuance(usdt_id_multilocation), expected_usdt_issuance); + assert_eq!(AssetsPallet::total_issuance(usdt_id_location.clone()), expected_usdt_issuance); + assert_eq!(AssetsPallet::active_issuance(usdt_id_location.clone()), expected_usdt_issuance); let expected_bla_issuance = foreign_initial_amount; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_bla_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_bla_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_bla_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_bla_issuance); }); } @@ -1959,21 +2098,24 @@ fn teleport_assets_with_remote_asset_reserve_and_teleported_fee_disallowed() { #[test] fn reserve_transfer_assets_with_teleportable_asset_disallowed() { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDT let usdt_initial_local_amount = 42; - let (usdt_chain, usdt_chain_sovereign_account, usdt_id_multilocation) = + let (usdt_chain, usdt_chain_sovereign_account, usdt_id_location) = set_up_foreign_asset(USDT_PARA_ID, None, ALICE, usdt_initial_local_amount, true); // transfer destination is USDT chain (foreign asset needs to go through its reserve chain) let dest = usdt_chain; - let assets: MultiAssets = vec![(usdt_id_multilocation, FEE_AMOUNT).into()].into(); + let assets: Assets = vec![(usdt_id_location.clone(), FEE_AMOUNT).into()].into(); let fee_index = 0; // balances checks before - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer @@ -1996,25 +2138,34 @@ fn reserve_transfer_assets_with_teleportable_asset_disallowed() { // Alice native asset is still same assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Alice USDT balance is still same - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); // No USDT moved to sovereign account of reserve parachain - assert_eq!(Assets::balance(usdt_id_multilocation, usdt_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), usdt_chain_sovereign_account), + 0 + ); // Verify total and active issuance of USDT are still the same - assert_eq!(Assets::total_issuance(usdt_id_multilocation), usdt_initial_local_amount); - assert_eq!(Assets::active_issuance(usdt_id_multilocation), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::total_issuance(usdt_id_location.clone()), + usdt_initial_local_amount + ); + assert_eq!(AssetsPallet::active_issuance(usdt_id_location), usdt_initial_local_amount); }); } /// Test `transfer_assets` with teleportable fee that is filtered - should fail. #[test] fn transfer_assets_with_filtered_teleported_fee_disallowed() { - let beneficiary: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into(); + let beneficiary: Location = AccountId32 { network: None, id: BOB.into() }.into(); new_test_ext_with_balances(vec![(ALICE, INITIAL_BALANCE)]).execute_with(|| { - let (assets, fee_index, _, _) = into_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // FilteredTeleportAsset for fees - teleportable but filtered FilteredTeleportAsset::get().into(), // native asset to transfer (not used for fees) - local reserve - (MultiLocation::here(), SEND_AMOUNT).into(), + (Location::here(), SEND_AMOUNT).into(), ); let result = XcmPallet::transfer_assets( RuntimeOrigin::signed(ALICE), @@ -2043,11 +2194,11 @@ fn transfer_assets_with_filtered_teleported_fee_disallowed() { #[test] fn intermediary_error_reverts_side_effects() { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDC let usdc_initial_local_amount = 142; - let (_, usdc_chain_sovereign_account, usdc_id_multilocation) = set_up_foreign_asset( + let (_, usdc_chain_sovereign_account, usdc_id_location) = set_up_foreign_asset( USDC_RESERVE_PARA_ID, Some(USDC_INNER_JUNCTION), ALICE, @@ -2058,11 +2209,14 @@ fn intermediary_error_reverts_side_effects() { // transfer destination is some other parachain let dest = RelayLocation::get().pushed_with_interior(Parachain(OTHER_PARA_ID)).unwrap(); - let assets: MultiAssets = vec![(usdc_id_multilocation, SEND_AMOUNT).into()].into(); + let assets: Assets = vec![(usdc_id_location.clone(), SEND_AMOUNT).into()].into(); let fee_index = 0; // balances checks before - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // introduce artificial error in sending outbound XCM @@ -2080,14 +2234,23 @@ fn intermediary_error_reverts_side_effects() { .is_err()); // Alice no changes - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Destination account (parachain account) no changes assert_eq!(Balances::free_balance(usdc_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdc_id_multilocation, usdc_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), usdc_chain_sovereign_account), + 0 + ); // Verify total and active issuance of USDC has not changed - assert_eq!(Assets::total_issuance(usdc_id_multilocation), usdc_initial_local_amount); - assert_eq!(Assets::active_issuance(usdc_id_multilocation), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::total_issuance(usdc_id_location.clone()), + usdc_initial_local_amount + ); + assert_eq!(AssetsPallet::active_issuance(usdc_id_location), usdc_initial_local_amount); // Verify no XCM program sent assert_eq!(sent_xcm(), vec![]); }); @@ -2105,47 +2268,50 @@ fn teleport_asset_using_local_fee_reserve_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let weight = BaseXcmWeight::get() * 3; let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create non-sufficient foreign asset USDT let usdt_initial_local_amount = 42; - let (usdt_chain, usdt_chain_sovereign_account, usdt_id_multilocation) = + let (usdt_chain, usdt_chain_sovereign_account, usdt_id_location) = set_up_foreign_asset(USDT_PARA_ID, None, ALICE, usdt_initial_local_amount, false); // transfer destination is reserve location (no teleport trust) let dest = usdt_chain; - let (assets, fee_index, fee_asset, xfer_asset) = into_multiassets_checked( + let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( // native asset for fee - local reserve - (MultiLocation::here(), FEE_AMOUNT).into(), + (Location::here(), FEE_AMOUNT).into(), // USDT to transfer - destination reserve - (usdt_id_multilocation, SEND_AMOUNT).into(), + (usdt_id_location.clone(), SEND_AMOUNT).into(), ); // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, context).unwrap(); - let expected_asset = xfer_asset.reanchored(&dest, context).unwrap(); + let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index as u32, Unlimited, @@ -2159,24 +2325,29 @@ fn teleport_asset_using_local_fee_reserve_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); // Alice spent (transferred) amount assert_eq!( - Assets::balance(usdt_id_multilocation, ALICE), + AssetsPallet::balance(usdt_id_location.clone(), ALICE), usdt_initial_local_amount - SEND_AMOUNT ); // Alice used native asset for fees assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - FEE_AMOUNT); // Destination account (parachain account) added native reserve to balances assert_eq!(Balances::free_balance(usdt_chain_sovereign_account.clone()), FEE_AMOUNT); - assert_eq!(Assets::balance(usdt_id_multilocation, usdt_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), usdt_chain_sovereign_account), + 0 + ); // Verify total and active issuance of foreign BLA have decreased (burned on // reserve-withdraw) let expected_issuance = usdt_initial_local_amount - SEND_AMOUNT; - assert_eq!(Assets::total_issuance(usdt_id_multilocation), expected_issuance); - assert_eq!(Assets::active_issuance(usdt_id_multilocation), expected_issuance); + assert_eq!(AssetsPallet::total_issuance(usdt_id_location.clone()), expected_issuance); + assert_eq!(AssetsPallet::active_issuance(usdt_id_location), expected_issuance); // Verify sent XCM program assert_eq!( @@ -2198,7 +2369,7 @@ fn teleport_asset_using_local_fee_reserve_call( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { paying: origin_location, - fees: MultiAssets::new(), + fees: Assets::new(), }) ); assert!(matches!( @@ -2255,20 +2426,20 @@ fn teleported_asset_using_destination_reserve_fee_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset BLA to be used for fees let foreign_initial_amount = 142; - let (reserve_location, foreign_sovereign_account, foreign_asset_id_multilocation) = + let (reserve_location, foreign_sovereign_account, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), @@ -2279,34 +2450,37 @@ fn teleported_asset_using_destination_reserve_fee_call( // create non-sufficient foreign asset USDT let usdt_initial_local_amount = 42; - let (_, usdt_chain_sovereign_account, usdt_id_multilocation) = + let (_, usdt_chain_sovereign_account, usdt_id_location) = set_up_foreign_asset(USDT_PARA_ID, None, ALICE, usdt_initial_local_amount, false); // transfer destination is BLA reserve location let dest = reserve_location; let dest_sovereign_account = foreign_sovereign_account; - let (assets, fee_index, fee_asset, xfer_asset) = into_multiassets_checked( + let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( // foreign asset BLA used for fees - destination reserve - (foreign_asset_id_multilocation, FEE_AMOUNT).into(), + (foreign_asset_id_location.clone(), FEE_AMOUNT).into(), // USDT to transfer - teleported - (usdt_id_multilocation, SEND_AMOUNT).into(), + (usdt_id_location.clone(), SEND_AMOUNT).into(), ); // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, context).unwrap(); - let expected_asset = xfer_asset.reanchored(&dest, context).unwrap(); + let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index as u32, Unlimited, @@ -2321,13 +2495,15 @@ fn teleported_asset_using_destination_reserve_fee_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { paying: origin_location, - fees: MultiAssets::new(), + fees: Assets::new(), }) ); assert!(matches!( @@ -2338,29 +2514,38 @@ fn teleported_asset_using_destination_reserve_fee_call( assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Alice spent USDT for fees assert_eq!( - Assets::balance(usdt_id_multilocation, ALICE), + AssetsPallet::balance(usdt_id_location.clone(), ALICE), usdt_initial_local_amount - SEND_AMOUNT ); // Alice transferred BLA assert_eq!( - Assets::balance(foreign_asset_id_multilocation, ALICE), + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), foreign_initial_amount - FEE_AMOUNT ); // Verify balances of USDT reserve parachain assert_eq!(Balances::free_balance(usdt_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdt_id_multilocation, usdt_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), usdt_chain_sovereign_account), + 0 + ); // Verify balances of transferred-asset reserve parachain assert_eq!(Balances::free_balance(dest_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, dest_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), dest_sovereign_account), + 0 + ); // Verify total and active issuance of USDT have decreased (teleported) let expected_usdt_issuance = usdt_initial_local_amount - SEND_AMOUNT; - assert_eq!(Assets::total_issuance(usdt_id_multilocation), expected_usdt_issuance); - assert_eq!(Assets::active_issuance(usdt_id_multilocation), expected_usdt_issuance); + assert_eq!(AssetsPallet::total_issuance(usdt_id_location.clone()), expected_usdt_issuance); + assert_eq!(AssetsPallet::active_issuance(usdt_id_location), expected_usdt_issuance); // Verify total and active issuance of foreign BLA asset have decreased (burned on // reserve-withdraw) let expected_bla_issuance = foreign_initial_amount - FEE_AMOUNT; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_bla_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_bla_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_bla_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_bla_issuance); // Verify sent XCM program assert_eq!( diff --git a/polkadot/xcm/pallet-xcm/src/tests/mod.rs b/polkadot/xcm/pallet-xcm/src/tests/mod.rs index e7a6fdc9dce..5f9c86ed7b3 100644 --- a/polkadot/xcm/pallet-xcm/src/tests/mod.rs +++ b/polkadot/xcm/pallet-xcm/src/tests/mod.rs @@ -19,9 +19,8 @@ pub(crate) mod assets_transfer; use crate::{ - mock::*, AssetTraps, CurrentMigration, Error, LatestVersionedMultiLocation, Queries, - QueryStatus, VersionDiscoveryQueue, VersionMigrationStage, VersionNotifiers, - VersionNotifyTargets, + mock::*, AssetTraps, CurrentMigration, Error, LatestVersionedLocation, Queries, QueryStatus, + VersionDiscoveryQueue, VersionMigrationStage, VersionNotifiers, VersionNotifyTargets, }; use frame_support::{ assert_noop, assert_ok, @@ -49,9 +48,11 @@ fn report_outcome_notify_works() { (ALICE, INITIAL_BALANCE), (ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; - let sender: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let mut message = - Xcm(vec![TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender }]); + let sender: Location = AccountId32 { network: None, id: ALICE.into() }.into(); + let mut message = Xcm(vec![TransferAsset { + assets: (Here, SEND_AMOUNT).into(), + beneficiary: sender.clone(), + }]); let call = pallet_test_notifier::Call::notification_received { query_id: 0, response: Default::default(), @@ -76,12 +77,12 @@ fn report_outcome_notify_works() { TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender }, ]) ); - let querier: MultiLocation = Here.into(); + let querier: Location = Here.into(); let status = QueryStatus::Pending { - responder: MultiLocation::from(Parachain(OTHER_PARA_ID)).into(), + responder: Location::from(Parachain(OTHER_PARA_ID)).into(), maybe_notify: Some((5, 2)), timeout: 100, - maybe_match_querier: Some(querier.into()), + maybe_match_querier: Some(querier.clone().into()), }; assert_eq!(crate::Queries::::iter().collect::>(), vec![(0, status)]); @@ -91,14 +92,15 @@ fn report_outcome_notify_works() { max_weight: Weight::from_parts(1_000_000, 1_000_000), querier: Some(querier), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(OTHER_PARA_ID), message, - hash, + &mut hash, Weight::from_parts(1_000_000_000, 1_000_000_000), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(1_000, 1_000) }); assert_eq!( last_events(2), vec![ @@ -124,9 +126,11 @@ fn report_outcome_works() { (ALICE, INITIAL_BALANCE), (ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; - let sender: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let mut message = - Xcm(vec![TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender }]); + let sender: Location = AccountId32 { network: None, id: ALICE.into() }.into(); + let mut message = Xcm(vec![TransferAsset { + assets: (Here, SEND_AMOUNT).into(), + beneficiary: sender.clone(), + }]); new_test_ext_with_balances(balances).execute_with(|| { XcmPallet::report_outcome(&mut message, Parachain(OTHER_PARA_ID).into_location(), 100) .unwrap(); @@ -141,12 +145,12 @@ fn report_outcome_works() { TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender }, ]) ); - let querier: MultiLocation = Here.into(); + let querier: Location = Here.into(); let status = QueryStatus::Pending { - responder: MultiLocation::from(Parachain(OTHER_PARA_ID)).into(), + responder: Location::from(Parachain(OTHER_PARA_ID)).into(), maybe_notify: None, timeout: 100, - maybe_match_querier: Some(querier.into()), + maybe_match_querier: Some(querier.clone().into()), }; assert_eq!(crate::Queries::::iter().collect::>(), vec![(0, status)]); @@ -156,14 +160,15 @@ fn report_outcome_works() { max_weight: Weight::zero(), querier: Some(querier), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(OTHER_PARA_ID), message, - hash, + &mut hash, Weight::from_parts(1_000_000_000, 1_000_000_000), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(1_000, 1_000) }); assert_eq!( last_event(), RuntimeEvent::XcmPallet(crate::Event::ResponseReady { @@ -185,16 +190,15 @@ fn custom_querier_works() { (ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; new_test_ext_with_balances(balances).execute_with(|| { - let querier: MultiLocation = - (Parent, AccountId32 { network: None, id: ALICE.into() }).into(); + let querier: Location = (Parent, AccountId32 { network: None, id: ALICE.into() }).into(); - let r = TestNotifier::prepare_new_query(RuntimeOrigin::signed(ALICE), querier); + let r = TestNotifier::prepare_new_query(RuntimeOrigin::signed(ALICE), querier.clone()); assert_eq!(r, Ok(())); let status = QueryStatus::Pending { - responder: MultiLocation::from(AccountId32 { network: None, id: ALICE.into() }).into(), + responder: Location::from(AccountId32 { network: None, id: ALICE.into() }).into(), maybe_notify: None, timeout: 100, - maybe_match_querier: Some(querier.into()), + maybe_match_querier: Some(querier.clone().into()), }; assert_eq!(crate::Queries::::iter().collect::>(), vec![(0, status)]); @@ -205,21 +209,21 @@ fn custom_querier_works() { max_weight: Weight::zero(), querier: None, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm_in_credit( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( AccountId32 { network: None, id: ALICE.into() }, message, - hash, + &mut hash, Weight::from_parts(1_000_000_000, 1_000_000_000), Weight::from_parts(1_000, 1_000), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(1_000, 1_000) }); assert_eq!( last_event(), RuntimeEvent::XcmPallet(crate::Event::InvalidQuerier { origin: AccountId32 { network: None, id: ALICE.into() }.into(), query_id: 0, - expected_querier: querier, + expected_querier: querier.clone(), maybe_actual_querier: None, }), ); @@ -229,24 +233,24 @@ fn custom_querier_works() { query_id: 0, response: Response::ExecutionResult(None), max_weight: Weight::zero(), - querier: Some(MultiLocation::here()), + querier: Some(Location::here()), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm_in_credit( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( AccountId32 { network: None, id: ALICE.into() }, message, - hash, + &mut hash, Weight::from_parts(1_000_000_000, 1_000_000_000), Weight::from_parts(1_000, 1_000), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(1_000, 1_000) }); assert_eq!( last_event(), RuntimeEvent::XcmPallet(crate::Event::InvalidQuerier { origin: AccountId32 { network: None, id: ALICE.into() }.into(), query_id: 0, - expected_querier: querier, - maybe_actual_querier: Some(MultiLocation::here()), + expected_querier: querier.clone(), + maybe_actual_querier: Some(Location::here()), }), ); @@ -257,14 +261,15 @@ fn custom_querier_works() { max_weight: Weight::zero(), querier: Some(querier), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( AccountId32 { network: None, id: ALICE.into() }, message, - hash, + &mut hash, Weight::from_parts(1_000_000_000, 1_000_000_000), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(1_000, 1_000) }); assert_eq!( last_event(), RuntimeEvent::XcmPallet(crate::Event::ResponseReady { @@ -289,12 +294,12 @@ fn send_works() { (ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; new_test_ext_with_balances(balances).execute_with(|| { - let sender: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let sender: Location = AccountId32 { network: None, id: ALICE.into() }.into(); let message = Xcm(vec![ ReserveAssetDeposited((Parent, SEND_AMOUNT).into()), ClearOrigin, buy_execution((Parent, SEND_AMOUNT)), - DepositAsset { assets: AllCounted(1).into(), beneficiary: sender }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: sender.clone() }, ]); let versioned_dest = Box::new(RelayLocation::get().into()); @@ -304,7 +309,7 @@ fn send_works() { versioned_dest, versioned_message )); - let sent_message = Xcm(Some(DescendOrigin(sender.try_into().unwrap())) + let sent_message = Xcm(Some(DescendOrigin(sender.clone().try_into().unwrap())) .into_iter() .chain(message.0.clone().into_iter()) .collect()); @@ -333,8 +338,7 @@ fn send_fails_when_xcm_router_blocks() { (ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; new_test_ext_with_balances(balances).execute_with(|| { - let sender: MultiLocation = - Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let sender: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); let message = Xcm(vec![ ReserveAssetDeposited((Parent, SEND_AMOUNT).into()), buy_execution((Parent, SEND_AMOUNT)), @@ -343,7 +347,7 @@ fn send_fails_when_xcm_router_blocks() { assert_noop!( XcmPallet::send( RuntimeOrigin::signed(ALICE), - Box::new(MultiLocation::ancestor(8).into()), + Box::new(Location::ancestor(8).into()), Box::new(VersionedXcm::from(message.clone())), ), crate::Error::::SendFailure @@ -363,7 +367,7 @@ fn execute_withdraw_to_deposit_works() { ]; new_test_ext_with_balances(balances).execute_with(|| { let weight = BaseXcmWeight::get() * 3; - let dest: MultiLocation = Junction::AccountId32 { network: None, id: BOB.into() }.into(); + let dest: Location = Junction::AccountId32 { network: None, id: BOB.into() }.into(); assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); assert_ok!(XcmPallet::execute( RuntimeOrigin::signed(ALICE), @@ -378,7 +382,9 @@ fn execute_withdraw_to_deposit_works() { assert_eq!(Balances::total_balance(&BOB), SEND_AMOUNT); assert_eq!( last_event(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); }); } @@ -389,7 +395,7 @@ fn trapped_assets_can_be_claimed() { let balances = vec![(ALICE, INITIAL_BALANCE), (BOB, INITIAL_BALANCE)]; new_test_ext_with_balances(balances).execute_with(|| { let weight = BaseXcmWeight::get() * 6; - let dest: MultiLocation = Junction::AccountId32 { network: None, id: BOB.into() }.into(); + let dest: Location = Junction::AccountId32 { network: None, id: BOB.into() }.into(); assert_ok!(XcmPallet::execute( RuntimeOrigin::signed(ALICE), @@ -401,15 +407,14 @@ fn trapped_assets_can_be_claimed() { // This will make an error. Trap(0), // This would succeed, but we never get to it. - DepositAsset { assets: AllCounted(1).into(), beneficiary: dest }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: dest.clone() }, ]))), weight )); - let source: MultiLocation = - Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let source: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); let trapped = AssetTraps::::iter().collect::>(); - let vma = VersionedMultiAssets::from(MultiAssets::from((Here, SEND_AMOUNT))); - let hash = BlakeTwo256::hash_of(&(source, vma.clone())); + let vma = VersionedAssets::from(Assets::from((Here, SEND_AMOUNT))); + let hash = BlakeTwo256::hash_of(&(source.clone(), vma.clone())); assert_eq!( last_events(2), vec![ @@ -419,7 +424,7 @@ fn trapped_assets_can_be_claimed() { assets: vma }), RuntimeEvent::XcmPallet(crate::Event::Attempted { - outcome: Outcome::Complete(BaseXcmWeight::get() * 5) + outcome: Outcome::Complete { used: BaseXcmWeight::get() * 5 } }), ] ); @@ -435,7 +440,7 @@ fn trapped_assets_can_be_claimed() { Box::new(VersionedXcm::from(Xcm(vec![ ClaimAsset { assets: (Here, SEND_AMOUNT).into(), ticket: Here.into() }, buy_execution((Here, SEND_AMOUNT)), - DepositAsset { assets: AllCounted(1).into(), beneficiary: dest }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: dest.clone() }, ]))), weight )); @@ -454,7 +459,8 @@ fn trapped_assets_can_be_claimed() { ]))), weight )); - let outcome = Outcome::Incomplete(BaseXcmWeight::get(), XcmError::UnknownClaim); + let outcome = + Outcome::Incomplete { used: BaseXcmWeight::get(), error: XcmError::UnknownClaim }; assert_eq!(last_event(), RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome })); }); } @@ -468,10 +474,10 @@ fn incomplete_execute_reverts_side_effects() { let balances = vec![(ALICE, INITIAL_BALANCE), (BOB, INITIAL_BALANCE)]; new_test_ext_with_balances(balances).execute_with(|| { let weight = BaseXcmWeight::get() * 4; - let dest: MultiLocation = Junction::AccountId32 { network: None, id: BOB.into() }.into(); + let dest: Location = Junction::AccountId32 { network: None, id: BOB.into() }.into(); assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); let amount_to_send = INITIAL_BALANCE - ExistentialDeposit::get(); - let assets: MultiAssets = (Here, amount_to_send).into(); + let assets: Assets = (Here, amount_to_send).into(); let result = XcmPallet::execute( RuntimeOrigin::signed(ALICE), Box::new(VersionedXcm::from(Xcm(vec![ @@ -506,35 +512,38 @@ fn incomplete_execute_reverts_side_effects() { } #[test] -fn fake_latest_versioned_multilocation_works() { +fn fake_latest_versioned_location_works() { use codec::Encode; - let remote: MultiLocation = Parachain(1000).into(); - let versioned_remote = LatestVersionedMultiLocation(&remote); + let remote: Location = Parachain(1000).into(); + let versioned_remote = LatestVersionedLocation(&remote); assert_eq!(versioned_remote.encode(), remote.into_versioned().encode()); } #[test] fn basic_subscription_works() { new_test_ext_with_balances(vec![]).execute_with(|| { - let remote: MultiLocation = Parachain(1000).into(); + let remote: Location = Parachain(1000).into(); assert_ok!(XcmPallet::force_subscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()), + Box::new(remote.clone().into()), )); assert_eq!( Queries::::iter().collect::>(), - vec![(0, QueryStatus::VersionNotifier { origin: remote.into(), is_active: false })] + vec![( + 0, + QueryStatus::VersionNotifier { origin: remote.clone().into(), is_active: false } + )] ); assert_eq!( VersionNotifiers::::iter().collect::>(), - vec![(XCM_VERSION, remote.into(), 0)] + vec![(XCM_VERSION, remote.clone().into(), 0)] ); assert_eq!( take_sent_xcm(), vec![( - remote, + remote.clone(), Xcm(vec![SubscribeVersion { query_id: 0, max_response_weight: Weight::zero() }]), ),] ); @@ -561,16 +570,16 @@ fn basic_subscription_works() { #[test] fn subscriptions_increment_id() { new_test_ext_with_balances(vec![]).execute_with(|| { - let remote: MultiLocation = Parachain(1000).into(); + let remote: Location = Parachain(1000).into(); assert_ok!(XcmPallet::force_subscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()), + Box::new(remote.clone().into()), )); - let remote2: MultiLocation = Parachain(1001).into(); + let remote2: Location = Parachain(1001).into(); assert_ok!(XcmPallet::force_subscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote2.into()), + Box::new(remote2.clone().into()), )); assert_eq!( @@ -598,10 +607,10 @@ fn subscriptions_increment_id() { #[test] fn double_subscription_fails() { new_test_ext_with_balances(vec![]).execute_with(|| { - let remote: MultiLocation = Parachain(1000).into(); + let remote: Location = Parachain(1000).into(); assert_ok!(XcmPallet::force_subscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()), + Box::new(remote.clone().into()), )); assert_noop!( XcmPallet::force_subscribe_version_notify( @@ -616,19 +625,19 @@ fn double_subscription_fails() { #[test] fn unsubscribe_works() { new_test_ext_with_balances(vec![]).execute_with(|| { - let remote: MultiLocation = Parachain(1000).into(); + let remote: Location = Parachain(1000).into(); assert_ok!(XcmPallet::force_subscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()), + Box::new(remote.clone().into()), )); assert_ok!(XcmPallet::force_unsubscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()) + Box::new(remote.clone().into()) )); assert_noop!( XcmPallet::force_unsubscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()) + Box::new(remote.clone().into()) ), Error::::NoSubscription, ); @@ -637,13 +646,13 @@ fn unsubscribe_works() { take_sent_xcm(), vec![ ( - remote, + remote.clone(), Xcm(vec![SubscribeVersion { query_id: 0, max_response_weight: Weight::zero() }]), ), - (remote, Xcm(vec![UnsubscribeVersion]),), + (remote.clone(), Xcm(vec![UnsubscribeVersion]),), ] ); }); @@ -655,13 +664,19 @@ fn subscription_side_works() { new_test_ext_with_balances(vec![]).execute_with(|| { AdvertisedXcmVersion::set(1); - let remote: MultiLocation = Parachain(1000).into(); + let remote: Location = Parachain(1000).into(); let weight = BaseXcmWeight::get(); let message = Xcm(vec![SubscribeVersion { query_id: 0, max_response_weight: Weight::zero() }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(remote, message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + remote.clone(), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); let instr = QueryResponse { query_id: 0, @@ -669,7 +684,7 @@ fn subscription_side_works() { response: Response::Version(1), querier: None, }; - assert_eq!(take_sent_xcm(), vec![(remote, Xcm(vec![instr]))]); + assert_eq!(take_sent_xcm(), vec![(remote.clone(), Xcm(vec![instr]))]); // A runtime upgrade which doesn't alter the version sends no notifications. CurrentMigration::::put(VersionMigrationStage::default()); @@ -698,7 +713,7 @@ fn subscription_side_upgrades_work_with_notify() { AdvertisedXcmVersion::set(1); // An entry from a previous runtime with v2 XCM. - let v2_location = VersionedMultiLocation::V2(xcm::v2::Junction::Parachain(1001).into()); + let v2_location = VersionedLocation::V2(xcm::v2::Junction::Parachain(1001).into()); VersionNotifyTargets::::insert(1, v2_location, (70, Weight::zero(), 2)); let v3_location = Parachain(1003).into_versioned(); VersionNotifyTargets::::insert(3, v3_location, (72, Weight::zero(), 2)); @@ -751,7 +766,7 @@ fn subscription_side_upgrades_work_with_notify() { fn subscription_side_upgrades_work_without_notify() { new_test_ext_with_balances(vec![]).execute_with(|| { // An entry from a previous runtime with v2 XCM. - let v2_location = VersionedMultiLocation::V2(xcm::v2::Junction::Parachain(1001).into()); + let v2_location = VersionedLocation::V2(xcm::v2::Junction::Parachain(1001).into()); VersionNotifyTargets::::insert(1, v2_location, (70, Weight::zero(), 2)); let v3_location = Parachain(1003).into_versioned(); VersionNotifyTargets::::insert(3, v3_location, (72, Weight::zero(), 2)); @@ -765,8 +780,8 @@ fn subscription_side_upgrades_work_without_notify() { assert_eq!( contents, vec![ - (XCM_VERSION, Parachain(1001).into_versioned(), (70, Weight::zero(), 3)), - (XCM_VERSION, Parachain(1003).into_versioned(), (72, Weight::zero(), 3)), + (XCM_VERSION, Parachain(1001).into_versioned(), (70, Weight::zero(), 4)), + (XCM_VERSION, Parachain(1003).into_versioned(), (72, Weight::zero(), 4)), ] ); }); @@ -775,10 +790,10 @@ fn subscription_side_upgrades_work_without_notify() { #[test] fn subscriber_side_subscription_works() { new_test_ext_with_balances_and_xcm_version(vec![], Some(XCM_VERSION)).execute_with(|| { - let remote: MultiLocation = Parachain(1000).into(); + let remote: Location = Parachain(1000).into(); assert_ok!(XcmPallet::force_subscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()), + Box::new(remote.clone().into()), )); assert_eq!(XcmPallet::get_version_for(&remote), None); take_sent_xcm(); @@ -795,9 +810,15 @@ fn subscriber_side_subscription_works() { querier: None, }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(remote, message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + remote.clone(), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); assert_eq!(take_sent_xcm(), vec![]); assert_eq!(XcmPallet::get_version_for(&remote), Some(1)); @@ -814,9 +835,15 @@ fn subscriber_side_subscription_works() { querier: None, }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(remote, message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + remote.clone(), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); assert_eq!(take_sent_xcm(), vec![]); assert_eq!(XcmPallet::get_version_for(&remote), Some(2)); @@ -832,73 +859,79 @@ fn subscriber_side_subscription_works() { #[test] fn auto_subscription_works() { new_test_ext_with_balances_and_xcm_version(vec![], None).execute_with(|| { - let remote_v2: MultiLocation = Parachain(1000).into(); - let remote_v3: MultiLocation = Parachain(1001).into(); + let remote_v2: Location = Parachain(1000).into(); + let remote_v4: Location = Parachain(1001).into(); assert_ok!(XcmPallet::force_default_xcm_version(RuntimeOrigin::root(), Some(2))); // Wrapping a version for a destination we don't know elicits a subscription. let msg_v2 = xcm::v2::Xcm::<()>(vec![xcm::v2::Instruction::Trap(0)]); - let msg_v3 = xcm::v3::Xcm::<()>(vec![xcm::v3::Instruction::ClearTopic]); + let msg_v4 = xcm::v4::Xcm::<()>(vec![xcm::v4::Instruction::ClearTopic]); assert_eq!( XcmPallet::wrap_version(&remote_v2, msg_v2.clone()), Ok(VersionedXcm::from(msg_v2.clone())), ); - assert_eq!(XcmPallet::wrap_version(&remote_v2, msg_v3.clone()), Err(())); + assert_eq!(XcmPallet::wrap_version(&remote_v2, msg_v4.clone()), Err(())); - let expected = vec![(remote_v2.into(), 2)]; + let expected = vec![(remote_v2.clone().into(), 2)]; assert_eq!(VersionDiscoveryQueue::::get().into_inner(), expected); assert_eq!( - XcmPallet::wrap_version(&remote_v3, msg_v2.clone()), + XcmPallet::wrap_version(&remote_v4, msg_v2.clone()), Ok(VersionedXcm::from(msg_v2.clone())), ); - assert_eq!(XcmPallet::wrap_version(&remote_v3, msg_v3.clone()), Err(())); + assert_eq!(XcmPallet::wrap_version(&remote_v4, msg_v4.clone()), Err(())); - let expected = vec![(remote_v2.into(), 2), (remote_v3.into(), 2)]; + let expected = vec![(remote_v2.clone().into(), 2), (remote_v4.clone().into(), 2)]; assert_eq!(VersionDiscoveryQueue::::get().into_inner(), expected); XcmPallet::on_initialize(1); assert_eq!( take_sent_xcm(), vec![( - remote_v3, + remote_v4.clone(), Xcm(vec![SubscribeVersion { query_id: 0, max_response_weight: Weight::zero() }]), )] ); - // Assume remote_v3 is working ok and XCM version 3. + // Assume remote_v4 is working ok and XCM version 4. let weight = BaseXcmWeight::get(); let message = Xcm(vec![ - // Remote supports XCM v3 + // Remote supports XCM v4 QueryResponse { query_id: 0, max_weight: Weight::zero(), - response: Response::Version(3), + response: Response::Version(4), querier: None, }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(remote_v3, message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + remote_v4.clone(), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); - // V2 messages can be sent to remote_v3 under XCM v3. + // V2 messages can be sent to remote_v4 under XCM v4. assert_eq!( - XcmPallet::wrap_version(&remote_v3, msg_v2.clone()), - Ok(VersionedXcm::from(msg_v2.clone()).into_version(3).unwrap()), + XcmPallet::wrap_version(&remote_v4, msg_v2.clone()), + Ok(VersionedXcm::from(msg_v2.clone()).into_version(4).unwrap()), ); - // This message can now be sent to remote_v3 as it's v3. + // This message can now be sent to remote_v4 as it's v4. assert_eq!( - XcmPallet::wrap_version(&remote_v3, msg_v3.clone()), - Ok(VersionedXcm::from(msg_v3.clone())) + XcmPallet::wrap_version(&remote_v4, msg_v4.clone()), + Ok(VersionedXcm::from(msg_v4.clone())) ); XcmPallet::on_initialize(2); assert_eq!( take_sent_xcm(), vec![( - remote_v2, + remote_v2.clone(), Xcm(vec![SubscribeVersion { query_id: 1, max_response_weight: Weight::zero() }]), )] ); @@ -915,16 +948,22 @@ fn auto_subscription_works() { querier: None, }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(remote_v2, message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + remote_v2.clone(), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); - // v3 messages cannot be sent to remote_v2... + // v4 messages cannot be sent to remote_v2... assert_eq!( XcmPallet::wrap_version(&remote_v2, msg_v2.clone()), Ok(VersionedXcm::V2(msg_v2)) ); - assert_eq!(XcmPallet::wrap_version(&remote_v2, msg_v3.clone()), Err(())); + assert_eq!(XcmPallet::wrap_version(&remote_v2, msg_v4.clone()), Err(())); }) } @@ -934,9 +973,9 @@ fn subscription_side_upgrades_work_with_multistage_notify() { AdvertisedXcmVersion::set(1); // An entry from a previous runtime with v0 XCM. - let v2_location = VersionedMultiLocation::V2(xcm::v2::Junction::Parachain(1001).into()); + let v2_location = VersionedLocation::V2(xcm::v2::Junction::Parachain(1001).into()); VersionNotifyTargets::::insert(1, v2_location, (70, Weight::zero(), 1)); - let v2_location = VersionedMultiLocation::V2(xcm::v2::Junction::Parachain(1002).into()); + let v2_location = VersionedLocation::V2(xcm::v2::Junction::Parachain(1002).into()); VersionNotifyTargets::::insert(2, v2_location, (71, Weight::zero(), 1)); let v3_location = Parachain(1003).into_versioned(); VersionNotifyTargets::::insert(3, v3_location, (72, Weight::zero(), 1)); @@ -1003,9 +1042,9 @@ fn subscription_side_upgrades_work_with_multistage_notify() { #[test] fn get_and_wrap_version_works() { new_test_ext_with_balances_and_xcm_version(vec![], None).execute_with(|| { - let remote_a: MultiLocation = Parachain(1000).into(); - let remote_b: MultiLocation = Parachain(1001).into(); - let remote_c: MultiLocation = Parachain(1002).into(); + let remote_a: Location = Parachain(1000).into(); + let remote_b: Location = Parachain(1001).into(); + let remote_c: Location = Parachain(1002).into(); // no `safe_xcm_version` version at `GenesisConfig` assert_eq!(XcmPallet::get_version_for(&remote_a), None); @@ -1023,7 +1062,7 @@ fn get_and_wrap_version_works() { // set XCM version only for `remote_a` assert_ok!(XcmPallet::force_xcm_version( RuntimeOrigin::root(), - Box::new(remote_a), + Box::new(remote_a.clone()), XCM_VERSION )); assert_eq!(XcmPallet::get_version_for(&remote_a), Some(XCM_VERSION)); @@ -1041,7 +1080,10 @@ fn get_and_wrap_version_works() { // does not work because remote_b has unknown version and default is set to 1, and // `XCM_VERSION` cannot be wrapped to the `1` assert_eq!(XcmPallet::wrap_version(&remote_b, xcm.clone()), Err(())); - assert_eq!(VersionDiscoveryQueue::::get().into_inner(), vec![(remote_b.into(), 1)]); + assert_eq!( + VersionDiscoveryQueue::::get().into_inner(), + vec![(remote_b.clone().into(), 1)] + ); // set default to the `XCM_VERSION` assert_ok!(XcmPallet::force_default_xcm_version(RuntimeOrigin::root(), Some(XCM_VERSION))); @@ -1053,10 +1095,17 @@ fn get_and_wrap_version_works() { XcmPallet::wrap_version(&remote_b, xcm.clone()), Ok(VersionedXcm::from(xcm.clone())) ); - assert_eq!(VersionDiscoveryQueue::::get().into_inner(), vec![(remote_b.into(), 2)]); + assert_eq!( + VersionDiscoveryQueue::::get().into_inner(), + vec![(remote_b.clone().into(), 2)] + ); // change remote_c to `1` - assert_ok!(XcmPallet::force_xcm_version(RuntimeOrigin::root(), Box::new(remote_c), 1)); + assert_ok!(XcmPallet::force_xcm_version( + RuntimeOrigin::root(), + Box::new(remote_c.clone()), + 1 + )); // does not work because remote_c has `1` and default is `XCM_VERSION` which cannot be // wrapped to the `1` diff --git a/polkadot/xcm/procedural/src/lib.rs b/polkadot/xcm/procedural/src/lib.rs index 7600e817d0e..4980d84d328 100644 --- a/polkadot/xcm/procedural/src/lib.rs +++ b/polkadot/xcm/procedural/src/lib.rs @@ -22,6 +22,7 @@ use syn::{parse_macro_input, DeriveInput}; mod builder_pattern; mod v2; mod v3; +mod v4; mod weight_info; #[proc_macro] @@ -31,6 +32,13 @@ pub fn impl_conversion_functions_for_multilocation_v2(input: TokenStream) -> Tok .into() } +#[proc_macro] +pub fn impl_conversion_functions_for_junctions_v2(input: TokenStream) -> TokenStream { + v2::junctions::generate_conversion_functions(input) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} + #[proc_macro_derive(XcmWeightInfoTrait)] pub fn derive_xcm_weight_info(item: TokenStream) -> TokenStream { weight_info::derive(item) @@ -50,6 +58,20 @@ pub fn impl_conversion_functions_for_junctions_v3(input: TokenStream) -> TokenSt .into() } +#[proc_macro] +pub fn impl_conversion_functions_for_location_v4(input: TokenStream) -> TokenStream { + v4::location::generate_conversion_functions(input) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} + +#[proc_macro] +pub fn impl_conversion_functions_for_junctions_v4(input: TokenStream) -> TokenStream { + v4::junctions::generate_conversion_functions(input) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} + /// This is called on the `Instruction` enum, not on the `Xcm` struct, /// and allows for the following syntax for building XCMs: /// let message = Xcm::builder() diff --git a/polkadot/xcm/procedural/src/v2.rs b/polkadot/xcm/procedural/src/v2.rs index dc2694a666f..1a2f281a498 100644 --- a/polkadot/xcm/procedural/src/v2.rs +++ b/polkadot/xcm/procedural/src/v2.rs @@ -14,10 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . +use proc_macro2::{Span, TokenStream}; +use quote::{format_ident, quote}; +use syn::{Result, Token}; + pub mod multilocation { - use proc_macro2::{Span, TokenStream}; - use quote::{format_ident, quote}; - use syn::{Result, Token}; + use super::*; pub fn generate_conversion_functions(input: proc_macro::TokenStream) -> Result { if !input.is_empty() { @@ -181,3 +183,44 @@ pub mod multilocation { } } } + +pub mod junctions { + use super::*; + + pub fn generate_conversion_functions(input: proc_macro::TokenStream) -> Result { + if !input.is_empty() { + return Err(syn::Error::new(Span::call_site(), "No arguments expected")); + } + + let from_slice_syntax = generate_conversion_from_slice_syntax(); + + Ok(quote! { + #from_slice_syntax + }) + } + + fn generate_conversion_from_slice_syntax() -> TokenStream { + quote! { + macro_rules! impl_junction { + ($count:expr, $variant:ident, ($($index:literal),+)) => { + /// Additional helper for building junctions + /// Useful for converting to future XCM versions + impl From<[Junction; $count]> for Junctions { + fn from(junctions: [Junction; $count]) -> Self { + Self::$variant($(junctions[$index].clone()),*) + } + } + }; + } + + impl_junction!(1, X1, (0)); + impl_junction!(2, X2, (0, 1)); + impl_junction!(3, X3, (0, 1, 2)); + impl_junction!(4, X4, (0, 1, 2, 3)); + impl_junction!(5, X5, (0, 1, 2, 3, 4)); + impl_junction!(6, X6, (0, 1, 2, 3, 4, 5)); + impl_junction!(7, X7, (0, 1, 2, 3, 4, 5, 6)); + impl_junction!(8, X8, (0, 1, 2, 3, 4, 5, 6, 7)); + } + } +} diff --git a/polkadot/xcm/procedural/src/v3.rs b/polkadot/xcm/procedural/src/v3.rs index 246f90a46a3..f0556d5a8d4 100644 --- a/polkadot/xcm/procedural/src/v3.rs +++ b/polkadot/xcm/procedural/src/v3.rs @@ -45,9 +45,8 @@ pub mod multilocation { let interior = if num_junctions == 0 { quote!(Junctions::Here) } else { - let variant = format_ident!("X{}", num_junctions); quote! { - Junctions::#variant( #(#idents .into()),* ) + [#(#idents .into()),*].into() } }; @@ -110,7 +109,7 @@ pub mod multilocation { impl From for MultiLocation { fn from(x: Junction) -> Self { - MultiLocation { parents: 0, interior: Junctions::X1(x) } + MultiLocation { parents: 0, interior: [x].into() } } } @@ -129,10 +128,12 @@ pub mod junctions { // Support up to 8 Parents in a tuple, assuming that most use cases don't go past 8 parents. let from_v2 = generate_conversion_from_v2(MAX_JUNCTIONS); + let from_v4 = generate_conversion_from_v4(); let from_tuples = generate_conversion_from_tuples(MAX_JUNCTIONS); Ok(quote! { #from_v2 + #from_v4 #from_tuples }) } @@ -143,12 +144,11 @@ pub mod junctions { let idents = (0..num_junctions).map(|i| format_ident!("j{}", i)).collect::>(); let types = (0..num_junctions).map(|i| format_ident!("J{}", i)).collect::>(); - let variant = &format_ident!("X{}", num_junctions); quote! { impl<#(#types : Into,)*> From<( #(#types,)* )> for Junctions { fn from( ( #(#idents,)* ): ( #(#types,)* ) ) -> Self { - Self::#variant( #(#idents .into()),* ) + [#(#idents .into()),*].into() } } } @@ -156,6 +156,45 @@ pub mod junctions { .collect() } + fn generate_conversion_from_v4() -> TokenStream { + let match_variants = (0..8u8) + .map(|current_number| { + let number_ancestors = current_number + 1; + let variant = format_ident!("X{}", number_ancestors); + let idents = + (0..=current_number).map(|i| format_ident!("j{}", i)).collect::>(); + let convert = idents + .iter() + .map(|ident| { + quote! { let #ident = core::convert::TryInto::try_into(#ident.clone())?; } + }) + .collect::>(); + + quote! { + crate::v4::Junctions::#variant( junctions ) => { + let [#(#idents),*] = &*junctions; + #(#convert);* + [#(#idents),*].into() + }, + } + }) + .collect::(); + + quote! { + impl core::convert::TryFrom for Junctions { + type Error = (); + + fn try_from(mut new: crate::v4::Junctions) -> core::result::Result { + use Junctions::*; + Ok(match new { + crate::v4::Junctions::Here => Here, + #match_variants + }) + } + } + } + } + fn generate_conversion_from_v2(max_junctions: usize) -> TokenStream { let match_variants = (0..max_junctions) .map(|cur_num| { diff --git a/polkadot/xcm/procedural/src/v4.rs b/polkadot/xcm/procedural/src/v4.rs new file mode 100644 index 00000000000..5f5e10d3081 --- /dev/null +++ b/polkadot/xcm/procedural/src/v4.rs @@ -0,0 +1,196 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use proc_macro2::{Span, TokenStream}; +use quote::{format_ident, quote}; +use syn::{Result, Token}; + +const MAX_JUNCTIONS: usize = 8; + +pub mod location { + use super::*; + + /// Generates conversion functions from other types to the `Location` type: + /// - [PalletInstance(50), GeneralIndex(1984)].into() + /// - (Parent, Parachain(1000), AccountId32 { .. }).into() + pub fn generate_conversion_functions(input: proc_macro::TokenStream) -> Result { + if !input.is_empty() { + return Err(syn::Error::new(Span::call_site(), "No arguments expected")) + } + + let from_tuples = generate_conversion_from_tuples(8, 8); + + Ok(quote! { + #from_tuples + }) + } + + fn generate_conversion_from_tuples(max_junctions: usize, max_parents: usize) -> TokenStream { + let mut from_tuples = (0..=max_junctions) + .map(|num_junctions| { + let types = (0..num_junctions).map(|i| format_ident!("J{}", i)).collect::>(); + let idents = + (0..num_junctions).map(|i| format_ident!("j{}", i)).collect::>(); + let array_size = num_junctions; + let interior = if num_junctions == 0 { + quote!(Junctions::Here) + } else { + let variant = format_ident!("X{}", num_junctions); + quote! { + Junctions::#variant( alloc::sync::Arc::new( [#(#idents .into()),*] ) ) + } + }; + + let mut from_tuple = quote! { + impl< #(#types : Into,)* > From<( Ancestor, #( #types ),* )> for Location { + fn from( ( Ancestor(parents), #(#idents),* ): ( Ancestor, #( #types ),* ) ) -> Self { + Location { parents, interior: #interior } + } + } + + impl From<[Junction; #array_size]> for Location { + fn from(j: [Junction; #array_size]) -> Self { + let [#(#idents),*] = j; + Location { parents: 0, interior: #interior } + } + } + }; + + let from_parent_tuples = (0..=max_parents).map(|cur_parents| { + let parents = + (0..cur_parents).map(|_| format_ident!("Parent")).collect::>(); + let underscores = + (0..cur_parents).map(|_| Token![_](Span::call_site())).collect::>(); + + quote! { + impl< #(#types : Into,)* > From<( #( #parents , )* #( #types , )* )> for Location { + fn from( ( #(#underscores,)* #(#idents,)* ): ( #(#parents,)* #(#types,)* ) ) -> Self { + Self { parents: #cur_parents as u8, interior: #interior } + } + } + } + }); + + from_tuple.extend(from_parent_tuples); + from_tuple + }) + .collect::(); + + let from_parent_junctions_tuples = (0..=max_parents).map(|cur_parents| { + let parents = (0..cur_parents).map(|_| format_ident!("Parent")).collect::>(); + let underscores = + (0..cur_parents).map(|_| Token![_](Span::call_site())).collect::>(); + + quote! { + impl From<( #(#parents,)* Junctions )> for Location { + fn from( (#(#underscores,)* junctions): ( #(#parents,)* Junctions ) ) -> Self { + Location { parents: #cur_parents as u8, interior: junctions } + } + } + } + }); + from_tuples.extend(from_parent_junctions_tuples); + + quote! { + impl From<(Ancestor, Junctions)> for Location { + fn from((Ancestor(parents), interior): (Ancestor, Junctions)) -> Self { + Location { parents, interior } + } + } + + impl From for Location { + fn from(x: Junction) -> Self { + Location { parents: 0, interior: [x].into() } + } + } + + #from_tuples + } + } +} + +pub mod junctions { + use super::*; + + pub fn generate_conversion_functions(input: proc_macro::TokenStream) -> Result { + if !input.is_empty() { + return Err(syn::Error::new(Span::call_site(), "No arguments expected")) + } + + // Support up to 8 Parents in a tuple, assuming that most use cases don't go past 8 parents. + let from_v3 = generate_conversion_from_v3(MAX_JUNCTIONS); + let from_tuples = generate_conversion_from_tuples(MAX_JUNCTIONS); + + Ok(quote! { + #from_v3 + #from_tuples + }) + } + + fn generate_conversion_from_tuples(max_junctions: usize) -> TokenStream { + (1..=max_junctions) + .map(|num_junctions| { + let idents = + (0..num_junctions).map(|i| format_ident!("j{}", i)).collect::>(); + let types = (0..num_junctions).map(|i| format_ident!("J{}", i)).collect::>(); + + quote! { + impl<#(#types : Into,)*> From<( #(#types,)* )> for Junctions { + fn from( ( #(#idents,)* ): ( #(#types,)* ) ) -> Self { + [#(#idents .into()),*].into() + } + } + } + }) + .collect() + } + + fn generate_conversion_from_v3(max_junctions: usize) -> TokenStream { + let match_variants = (0..max_junctions) + .map(|cur_num| { + let num_ancestors = cur_num + 1; + let variant = format_ident!("X{}", num_ancestors); + let idents = (0..=cur_num).map(|i| format_ident!("j{}", i)).collect::>(); + let convert = idents + .iter() + .map(|ident| { + quote! { let #ident = core::convert::TryInto::try_into(#ident.clone())?; } + }) + .collect::>(); + + quote! { + crate::v3::Junctions::#variant( #(#idents),* ) => { + #(#convert);*; + let junctions: Junctions = [#(#idents),*].into(); + junctions + }, + } + }) + .collect::(); + + quote! { + impl core::convert::TryFrom for Junctions { + type Error = (); + fn try_from(mut old: crate::v3::Junctions) -> core::result::Result { + Ok(match old { + crate::v3::Junctions::Here => Junctions::Here, + #match_variants + }) + } + } + } + } +} diff --git a/polkadot/xcm/procedural/tests/builder_pattern.rs b/polkadot/xcm/procedural/tests/builder_pattern.rs index eab9d67121f..a9a30611dc0 100644 --- a/polkadot/xcm/procedural/tests/builder_pattern.rs +++ b/polkadot/xcm/procedural/tests/builder_pattern.rs @@ -21,12 +21,12 @@ use xcm::latest::prelude::*; #[test] fn builder_pattern_works() { - let asset: MultiAsset = (Here, 100u128).into(); - let beneficiary: MultiLocation = AccountId32 { id: [0u8; 32], network: None }.into(); + let asset: Asset = (Here, 100u128).into(); + let beneficiary: Location = AccountId32 { id: [0u8; 32], network: None }.into(); let message: Xcm<()> = Xcm::builder() .receive_teleported_asset(asset.clone().into()) .buy_execution(asset.clone(), Unlimited) - .deposit_asset(asset.clone().into(), beneficiary) + .deposit_asset(asset.clone().into(), beneficiary.clone()) .build(); assert_eq!( message, @@ -40,8 +40,8 @@ fn builder_pattern_works() { #[test] fn default_builder_requires_buy_execution() { - let asset: MultiAsset = (Here, 100u128).into(); - let beneficiary: MultiLocation = AccountId32 { id: [0u8; 32], network: None }.into(); + let asset: Asset = (Here, 100u128).into(); + let beneficiary: Location = AccountId32 { id: [0u8; 32], network: None }.into(); // This is invalid, since it doesn't pay for fees. // This is enforced by the runtime, because the build() method doesn't exist // on the resulting type. @@ -54,14 +54,14 @@ fn default_builder_requires_buy_execution() { let message: Xcm<()> = Xcm::builder_unpaid() .unpaid_execution(Unlimited, None) .withdraw_asset(asset.clone().into()) - .deposit_asset(asset.clone().into(), beneficiary) + .deposit_asset(asset.clone().into(), beneficiary.clone()) .build(); // This works assert_eq!( message, Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, WithdrawAsset(asset.clone().into()), - DepositAsset { assets: asset.clone().into(), beneficiary }, + DepositAsset { assets: asset.clone().into(), beneficiary: beneficiary.clone() }, ]) ); @@ -69,7 +69,7 @@ fn default_builder_requires_buy_execution() { // only be used when you really know what you're doing. let message: Xcm<()> = Xcm::builder_unsafe() .withdraw_asset(asset.clone().into()) - .deposit_asset(asset.clone().into(), beneficiary) + .deposit_asset(asset.clone().into(), beneficiary.clone()) .build(); assert_eq!( message, diff --git a/polkadot/xcm/procedural/tests/conversion_functions.rs b/polkadot/xcm/procedural/tests/conversion_functions.rs new file mode 100644 index 00000000000..5b6965167fc --- /dev/null +++ b/polkadot/xcm/procedural/tests/conversion_functions.rs @@ -0,0 +1,24 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use xcm::v2::prelude::*; + +#[test] +fn slice_syntax_in_v2_works() { + let old_junctions = Junctions::X2(Parachain(1), PalletInstance(1)); + let new_junctions = Junctions::from([Parachain(1), PalletInstance(1)]); + assert_eq!(old_junctions, new_junctions); +} diff --git a/polkadot/xcm/src/lib.rs b/polkadot/xcm/src/lib.rs index ddad0b5303b..f0cbe985331 100644 --- a/polkadot/xcm/src/lib.rs +++ b/polkadot/xcm/src/lib.rs @@ -30,13 +30,14 @@ use scale_info::TypeInfo; pub mod v2; pub mod v3; +pub mod v4; pub mod lts { - pub use super::v3::*; + pub use super::v4::*; } pub mod latest { - pub use super::v3::*; + pub use super::v4::*; } mod double_encoded; @@ -79,6 +80,8 @@ macro_rules! versioned_type { ($(#[$attr:meta])* pub enum $n:ident { $(#[$index3:meta])+ V3($v3:ty), + $(#[$index4:meta])+ + V4($v4:ty), }) => { #[derive(Derivative, Encode, Decode, TypeInfo)] #[derivative( @@ -94,6 +97,8 @@ macro_rules! versioned_type { pub enum $n { $(#[$index3])* V3($v3), + $(#[$index4])* + V4($v4), } impl $n { pub fn try_as(&self) -> Result<&T, ()> where Self: TryAs { @@ -104,6 +109,15 @@ macro_rules! versioned_type { fn try_as(&self) -> Result<&$v3, ()> { match &self { Self::V3(ref x) => Ok(x), + _ => Err(()), + } + } + } + impl TryAs<$v4> for $n { + fn try_as(&self) -> Result<&$v4, ()> { + match &self { + Self::V4(ref x) => Ok(x), + _ => Err(()), } } } @@ -111,21 +125,38 @@ macro_rules! versioned_type { fn into_version(self, n: Version) -> Result { Ok(match n { 3 => Self::V3(self.try_into()?), + 4 => Self::V4(self.try_into()?), _ => return Err(()), }) } } - impl> From for $n { - fn from(x: T) -> Self { + impl From<$v3> for $n { + fn from(x: $v3) -> Self { $n::V3(x.into()) } } + impl From<$v4> for $n { + fn from(x: $v4) -> Self { + $n::V4(x.into()) + } + } impl TryFrom<$n> for $v3 { type Error = (); fn try_from(x: $n) -> Result { use $n::*; match x { V3(x) => Ok(x), + V4(x) => x.try_into(), + } + } + } + impl TryFrom<$n> for $v4 { + type Error = (); + fn try_from(x: $n) -> Result { + use $n::*; + match x { + V3(x) => x.try_into().map_err(|_| ()), + V4(x) => Ok(x), } } } @@ -141,6 +172,8 @@ macro_rules! versioned_type { V2($v2:ty), $(#[$index3:meta])+ V3($v3:ty), + $(#[$index4:meta])+ + V4($v4:ty), }) => { #[derive(Derivative, Encode, Decode, TypeInfo)] #[derivative( @@ -158,6 +191,8 @@ macro_rules! versioned_type { V2($v2), $(#[$index3])* V3($v3), + $(#[$index4])* + V4($v4), } impl $n { pub fn try_as(&self) -> Result<&T, ()> where Self: TryAs { @@ -180,11 +215,20 @@ macro_rules! versioned_type { } } } + impl TryAs<$v4> for $n { + fn try_as(&self) -> Result<&$v4, ()> { + match &self { + Self::V4(ref x) => Ok(x), + _ => Err(()), + } + } + } impl IntoVersion for $n { fn into_version(self, n: Version) -> Result { Ok(match n { 1 | 2 => Self::V2(self.try_into()?), 3 => Self::V3(self.try_into()?), + 4 => Self::V4(self.try_into()?), _ => return Err(()), }) } @@ -194,9 +238,9 @@ macro_rules! versioned_type { $n::V2(x) } } - impl> From for $n { + impl> From for $n { fn from(x: T) -> Self { - $n::V3(x.into()) + $n::V4(x.into()) } } impl TryFrom<$n> for $v2 { @@ -206,6 +250,10 @@ macro_rules! versioned_type { match x { V2(x) => Ok(x), V3(x) => x.try_into(), + V4(x) => { + let v3: $v3 = x.try_into().map_err(|_| ())?; + v3.try_into() + }, } } } @@ -216,6 +264,21 @@ macro_rules! versioned_type { match x { V2(x) => x.try_into(), V3(x) => Ok(x), + V4(x) => x.try_into().map_err(|_| ()), + } + } + } + impl TryFrom<$n> for $v4 { + type Error = (); + fn try_from(x: $n) -> Result { + use $n::*; + match x { + V2(x) => { + let v3: $v3 = x.try_into().map_err(|_| ())?; + v3.try_into().map_err(|_| ()) + }, + V3(x) => x.try_into().map_err(|_| ()), + V4(x) => Ok(x), } } } @@ -228,10 +291,12 @@ macro_rules! versioned_type { } versioned_type! { - /// A single version's `Response` value, together with its version code. + /// A single version's `AssetId` value, together with its version code. pub enum VersionedAssetId { #[codec(index = 3)] V3(v3::AssetId), + #[codec(index = 4)] + V4(v4::AssetId), } } @@ -242,6 +307,8 @@ versioned_type! { V2(v2::Response), #[codec(index = 3)] V3(v3::Response), + #[codec(index = 4)] + V4(v4::Response), } } @@ -252,6 +319,8 @@ versioned_type! { V2(v2::NetworkId), #[codec(index = 3)] V3(v3::NetworkId), + #[codec(index = 4)] + V4(v4::NetworkId), } } @@ -262,50 +331,72 @@ versioned_type! { V2(v2::Junction), #[codec(index = 3)] V3(v3::Junction), + #[codec(index = 4)] + V4(v4::Junction), } } versioned_type! { - /// A single `MultiLocation` value, together with its version code. + /// A single `Location` value, together with its version code. #[derive(Ord, PartialOrd)] - pub enum VersionedMultiLocation { + pub enum VersionedLocation { #[codec(index = 1)] // v2 is same as v1 and therefore re-using the v1 index V2(v2::MultiLocation), #[codec(index = 3)] V3(v3::MultiLocation), + #[codec(index = 4)] + V4(v4::Location), } } +#[deprecated(note = "Use `VersionedLocation` instead")] +pub type VersionedMultiLocation = VersionedLocation; + versioned_type! { - /// A single `InteriorMultiLocation` value, together with its version code. - pub enum VersionedInteriorMultiLocation { - #[codec(index = 2)] // while this is same as v1::Junctions, VersionedInteriorMultiLocation is introduced in v3 + /// A single `InteriorLocation` value, together with its version code. + pub enum VersionedInteriorLocation { + #[codec(index = 2)] // while this is same as v1::Junctions, VersionedInteriorLocation is introduced in v3 V2(v2::InteriorMultiLocation), #[codec(index = 3)] V3(v3::InteriorMultiLocation), + #[codec(index = 4)] + V4(v4::InteriorLocation), } } +#[deprecated(note = "Use `VersionedInteriorLocation` instead")] +pub type VersionedInteriorMultiLocation = VersionedInteriorLocation; + versioned_type! { - /// A single `MultiAsset` value, together with its version code. - pub enum VersionedMultiAsset { + /// A single `Asset` value, together with its version code. + pub enum VersionedAsset { #[codec(index = 1)] // v2 is same as v1 and therefore re-using the v1 index V2(v2::MultiAsset), #[codec(index = 3)] V3(v3::MultiAsset), + #[codec(index = 4)] + V4(v4::Asset), } } +#[deprecated(note = "Use `VersionedAsset` instead")] +pub type VersionedMultiAsset = VersionedAsset; + versioned_type! { /// A single `MultiAssets` value, together with its version code. - pub enum VersionedMultiAssets { + pub enum VersionedAssets { #[codec(index = 1)] // v2 is same as v1 and therefore re-using the v1 index V2(v2::MultiAssets), #[codec(index = 3)] V3(v3::MultiAssets), + #[codec(index = 4)] + V4(v4::Assets), } } +#[deprecated(note = "Use `VersionedAssets` instead")] +pub type VersionedMultiAssets = VersionedAssets; + /// A single XCM message, together with its version code. #[derive(Derivative, Encode, Decode, TypeInfo)] #[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))] @@ -318,6 +409,8 @@ pub enum VersionedXcm { V2(v2::Xcm), #[codec(index = 3)] V3(v3::Xcm), + #[codec(index = 4)] + V4(v4::Xcm), } impl IntoVersion for VersionedXcm { @@ -325,6 +418,7 @@ impl IntoVersion for VersionedXcm { Ok(match n { 2 => Self::V2(self.try_into()?), 3 => Self::V3(self.try_into()?), + 4 => Self::V4(self.try_into()?), _ => return Err(()), }) } @@ -342,6 +436,12 @@ impl From> for VersionedXcm { } } +impl From> for VersionedXcm { + fn from(x: v4::Xcm) -> Self { + VersionedXcm::V4(x) + } +} + impl TryFrom> for v2::Xcm { type Error = (); fn try_from(x: VersionedXcm) -> Result { @@ -349,6 +449,10 @@ impl TryFrom> for v2::Xcm { match x { V2(x) => Ok(x), V3(x) => x.try_into(), + V4(x) => { + let v3: v3::Xcm = x.try_into()?; + v3.try_into() + }, } } } @@ -360,15 +464,31 @@ impl TryFrom> for v3::Xcm { match x { V2(x) => x.try_into(), V3(x) => Ok(x), + V4(x) => x.try_into(), + } + } +} + +impl TryFrom> for v4::Xcm { + type Error = (); + fn try_from(x: VersionedXcm) -> Result { + use VersionedXcm::*; + match x { + V2(x) => { + let v3: v3::Xcm = x.try_into()?; + v3.try_into() + }, + V3(x) => x.try_into(), + V4(x) => Ok(x), } } } -/// Convert an `Xcm` datum into a `VersionedXcm`, based on a destination `MultiLocation` which will +/// Convert an `Xcm` datum into a `VersionedXcm`, based on a destination `Location` which will /// interpret it. pub trait WrapVersion { fn wrap_version( - dest: &latest::MultiLocation, + dest: &latest::Location, xcm: impl Into>, ) -> Result, ()>; } @@ -376,14 +496,14 @@ pub trait WrapVersion { /// Check and return the `Version` that should be used for the `Xcm` datum for the destination /// `MultiLocation`, which will interpret it. pub trait GetVersion { - fn get_version_for(dest: &latest::MultiLocation) -> Option; + fn get_version_for(dest: &latest::Location) -> Option; } /// `()` implementation does nothing with the XCM, just sending with whatever version it was /// authored as. impl WrapVersion for () { fn wrap_version( - _: &latest::MultiLocation, + _: &latest::Location, xcm: impl Into>, ) -> Result, ()> { Ok(xcm.into()) @@ -395,14 +515,14 @@ impl WrapVersion for () { pub struct AlwaysV2; impl WrapVersion for AlwaysV2 { fn wrap_version( - _: &latest::MultiLocation, + _: &latest::Location, xcm: impl Into>, ) -> Result, ()> { Ok(VersionedXcm::::V2(xcm.into().try_into()?)) } } impl GetVersion for AlwaysV2 { - fn get_version_for(_dest: &latest::MultiLocation) -> Option { + fn get_version_for(_dest: &latest::Location) -> Option { Some(v2::VERSION) } } @@ -412,31 +532,48 @@ impl GetVersion for AlwaysV2 { pub struct AlwaysV3; impl WrapVersion for AlwaysV3 { fn wrap_version( - _: &latest::MultiLocation, + _: &latest::Location, xcm: impl Into>, ) -> Result, ()> { Ok(VersionedXcm::::V3(xcm.into().try_into()?)) } } impl GetVersion for AlwaysV3 { - fn get_version_for(_dest: &latest::MultiLocation) -> Option { + fn get_version_for(_dest: &latest::Location) -> Option { Some(v3::VERSION) } } +/// `WrapVersion` implementation which attempts to always convert the XCM to version 3 before +/// wrapping it. +pub struct AlwaysV4; +impl WrapVersion for AlwaysV4 { + fn wrap_version( + _: &latest::Location, + xcm: impl Into>, + ) -> Result, ()> { + Ok(VersionedXcm::::V4(xcm.into().try_into()?)) + } +} +impl GetVersion for AlwaysV4 { + fn get_version_for(_dest: &latest::Location) -> Option { + Some(v4::VERSION) + } +} + /// `WrapVersion` implementation which attempts to always convert the XCM to the latest version /// before wrapping it. -pub type AlwaysLatest = AlwaysV3; +pub type AlwaysLatest = AlwaysV4; /// `WrapVersion` implementation which attempts to always convert the XCM to the most recent Long- /// Term-Support version before wrapping it. -pub type AlwaysLts = AlwaysV3; +pub type AlwaysLts = AlwaysV4; pub mod prelude { pub use super::{ - latest::prelude::*, AlwaysLatest, AlwaysLts, AlwaysV2, AlwaysV3, GetVersion, IntoVersion, - Unsupported, Version as XcmVersion, VersionedAssetId, VersionedInteriorMultiLocation, - VersionedMultiAsset, VersionedMultiAssets, VersionedMultiLocation, VersionedResponse, + latest::prelude::*, AlwaysLatest, AlwaysLts, AlwaysV2, AlwaysV3, AlwaysV4, GetVersion, + IntoVersion, Unsupported, Version as XcmVersion, VersionedAsset, VersionedAssetId, + VersionedAssets, VersionedInteriorLocation, VersionedLocation, VersionedResponse, VersionedXcm, WrapVersion, }; } @@ -454,13 +591,19 @@ pub mod opaque { // Then override with the opaque types in v3 pub use crate::v3::opaque::{Instruction, Xcm}; } + pub mod v4 { + // Everything from v4 + pub use crate::v4::*; + // Then override with the opaque types in v4 + pub use crate::v4::opaque::{Instruction, Xcm}; + } pub mod latest { - pub use super::v3::*; + pub use super::v4::*; } pub mod lts { - pub use super::v3::*; + pub use super::v4::*; } /// The basic `VersionedXcm` type which just uses the `Vec` as an encoded call. @@ -470,5 +613,56 @@ pub mod opaque { #[test] fn conversion_works() { use latest::prelude::*; - let _: VersionedMultiAssets = (Here, 1u128).into(); + let assets: Assets = (Here, 1u128).into(); + let _: VersionedAssets = assets.into(); +} + +#[test] +fn size_limits() { + extern crate std; + + let mut test_failed = false; + macro_rules! check_sizes { + ($(($kind:ty, $expected:expr),)+) => { + $({ + let s = core::mem::size_of::<$kind>(); + // Since the types often affect the size of other types in which they're included + // it is more convenient to check multiple types at the same time and only fail + // the test at the end. For debugging it's also useful to print out all of the sizes, + // even if they're within the expected range. + if s > $expected { + test_failed = true; + std::eprintln!( + "assertion failed: size of '{}' is {} (which is more than the expected {})", + stringify!($kind), + s, + $expected + ); + } else { + std::println!( + "type '{}' is of size {} which is within the expected {}", + stringify!($kind), + s, + $expected + ); + } + })+ + } + } + + check_sizes! { + (crate::latest::Instruction<()>, 112), + (crate::latest::Asset, 80), + (crate::latest::Location, 24), + (crate::latest::AssetId, 40), + (crate::latest::Junctions, 16), + (crate::latest::Junction, 88), + (crate::latest::Response, 40), + (crate::latest::AssetInstance, 40), + (crate::latest::NetworkId, 48), + (crate::latest::BodyId, 32), + (crate::latest::Assets, 24), + (crate::latest::BodyPart, 12), + } + assert!(!test_failed); } diff --git a/polkadot/xcm/src/tests.rs b/polkadot/xcm/src/tests.rs index a3a60f6477c..1aabbcef281 100644 --- a/polkadot/xcm/src/tests.rs +++ b/polkadot/xcm/src/tests.rs @@ -59,79 +59,79 @@ fn encode_decode_versioned_response_v3() { #[test] fn encode_decode_versioned_multi_location_v2() { - let location = VersionedMultiLocation::V2(v2::MultiLocation::new(0, v2::Junctions::Here)); + let location = VersionedLocation::V2(v2::MultiLocation::new(0, v2::Junctions::Here)); let encoded = location.encode(); assert_eq!(encoded, hex_literal::hex!("010000"), "encode format changed"); assert_eq!(encoded[0], 1, "bad version number"); // this is introduced in v1 - let decoded = VersionedMultiLocation::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedLocation::decode(&mut &encoded[..]).unwrap(); assert_eq!(location, decoded); } #[test] fn encode_decode_versioned_multi_location_v3() { - let location = VersionedMultiLocation::V3(v3::MultiLocation::new(0, v3::Junctions::Here)); + let location = VersionedLocation::V3(v3::MultiLocation::new(0, v3::Junctions::Here)); let encoded = location.encode(); assert_eq!(encoded, hex_literal::hex!("030000"), "encode format changed"); assert_eq!(encoded[0], 3, "bad version number"); - let decoded = VersionedMultiLocation::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedLocation::decode(&mut &encoded[..]).unwrap(); assert_eq!(location, decoded); } #[test] fn encode_decode_versioned_interior_multi_location_v2() { - let location = VersionedInteriorMultiLocation::V2(v2::InteriorMultiLocation::Here); + let location = VersionedInteriorLocation::V2(v2::InteriorMultiLocation::Here); let encoded = location.encode(); assert_eq!(encoded, hex_literal::hex!("0200"), "encode format changed"); assert_eq!(encoded[0], 2, "bad version number"); - let decoded = VersionedInteriorMultiLocation::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedInteriorLocation::decode(&mut &encoded[..]).unwrap(); assert_eq!(location, decoded); } #[test] fn encode_decode_versioned_interior_multi_location_v3() { - let location = VersionedInteriorMultiLocation::V3(v3::InteriorMultiLocation::Here); + let location = VersionedInteriorLocation::V3(v3::InteriorMultiLocation::Here); let encoded = location.encode(); assert_eq!(encoded, hex_literal::hex!("0300"), "encode format changed"); assert_eq!(encoded[0], 3, "bad version number"); - let decoded = VersionedInteriorMultiLocation::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedInteriorLocation::decode(&mut &encoded[..]).unwrap(); assert_eq!(location, decoded); } #[test] fn encode_decode_versioned_multi_asset_v2() { - let asset = VersionedMultiAsset::V2(v2::MultiAsset::from(((0, v2::Junctions::Here), 1))); + let asset = VersionedAsset::V2(v2::MultiAsset::from(((0, v2::Junctions::Here), 1))); let encoded = asset.encode(); assert_eq!(encoded, hex_literal::hex!("010000000004"), "encode format changed"); assert_eq!(encoded[0], 1, "bad version number"); - let decoded = VersionedMultiAsset::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedAsset::decode(&mut &encoded[..]).unwrap(); assert_eq!(asset, decoded); } #[test] fn encode_decode_versioned_multi_asset_v3() { - let asset = VersionedMultiAsset::V3(v3::MultiAsset::from((v3::MultiLocation::default(), 1))); + let asset = VersionedAsset::V3(v3::MultiAsset::from((v3::MultiLocation::default(), 1))); let encoded = asset.encode(); assert_eq!(encoded, hex_literal::hex!("030000000004"), "encode format changed"); assert_eq!(encoded[0], 3, "bad version number"); - let decoded = VersionedMultiAsset::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedAsset::decode(&mut &encoded[..]).unwrap(); assert_eq!(asset, decoded); } #[test] fn encode_decode_versioned_multi_assets_v2() { - let assets = VersionedMultiAssets::V2(v2::MultiAssets::from(vec![v2::MultiAsset::from(( + let assets = VersionedAssets::V2(v2::MultiAssets::from(vec![v2::MultiAsset::from(( (0, v2::Junctions::Here), 1, ))])); @@ -140,13 +140,13 @@ fn encode_decode_versioned_multi_assets_v2() { assert_eq!(encoded, hex_literal::hex!("01040000000004"), "encode format changed"); assert_eq!(encoded[0], 1, "bad version number"); - let decoded = VersionedMultiAssets::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedAssets::decode(&mut &encoded[..]).unwrap(); assert_eq!(assets, decoded); } #[test] fn encode_decode_versioned_multi_assets_v3() { - let assets = VersionedMultiAssets::V3(v3::MultiAssets::from(vec![ + let assets = VersionedAssets::V3(v3::MultiAssets::from(vec![ (v3::MultiAsset::from((v3::MultiLocation::default(), 1))), ])); let encoded = assets.encode(); @@ -154,7 +154,7 @@ fn encode_decode_versioned_multi_assets_v3() { assert_eq!(encoded, hex_literal::hex!("03040000000004"), "encode format changed"); assert_eq!(encoded[0], 3, "bad version number"); - let decoded = VersionedMultiAssets::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedAssets::decode(&mut &encoded[..]).unwrap(); assert_eq!(assets, decoded); } @@ -187,6 +187,8 @@ fn encode_decode_versioned_xcm_v3() { #[test] fn ensure_type_info_is_correct() { let type_info = VersionedXcm::<()>::type_info(); - assert_eq!(type_info.path.segments, vec!["xcm", "VersionedXcm"]); + + let type_info = VersionedAssetId::type_info(); + assert_eq!(type_info.path.segments, vec!["xcm", "VersionedAssetId"]); } diff --git a/polkadot/xcm/src/v2/multilocation.rs b/polkadot/xcm/src/v2/multilocation.rs index 81b67eee974..60aa1f6cead 100644 --- a/polkadot/xcm/src/v2/multilocation.rs +++ b/polkadot/xcm/src/v2/multilocation.rs @@ -75,8 +75,8 @@ impl MultiLocation { MultiLocation { parents, interior: junctions } } - /// Consume `self` and return the equivalent `VersionedMultiLocation` value. - pub fn versioned(self) -> crate::VersionedMultiLocation { + /// Consume `self` and return the equivalent `VersionedLocation` value. + pub fn versioned(self) -> crate::VersionedLocation { self.into() } @@ -240,9 +240,9 @@ impl MultiLocation { /// # Example /// ```rust /// # use staging_xcm::v2::{Junctions::*, Junction::*, MultiLocation}; - /// let mut m = MultiLocation::new(1, X2(PalletInstance(3), OnlyChild)); + /// let mut m = MultiLocation::new(1, [PalletInstance(3), OnlyChild].into()); /// assert_eq!( - /// m.match_and_split(&MultiLocation::new(1, X1(PalletInstance(3)))), + /// m.match_and_split(&MultiLocation::new(1, [PalletInstance(3)].into())), /// Some(&OnlyChild), /// ); /// assert_eq!(m.match_and_split(&MultiLocation::new(1, Here)), None); @@ -260,10 +260,10 @@ impl MultiLocation { /// # Example /// ```rust /// # use staging_xcm::v2::{Junctions::*, Junction::*, MultiLocation}; - /// let m = MultiLocation::new(1, X3(PalletInstance(3), OnlyChild, OnlyChild)); - /// assert!(m.starts_with(&MultiLocation::new(1, X1(PalletInstance(3))))); - /// assert!(!m.starts_with(&MultiLocation::new(1, X1(GeneralIndex(99))))); - /// assert!(!m.starts_with(&MultiLocation::new(0, X1(PalletInstance(3))))); + /// let m = MultiLocation::new(1, [PalletInstance(3), OnlyChild, OnlyChild].into()); + /// assert!(m.starts_with(&MultiLocation::new(1, [PalletInstance(3)].into()))); + /// assert!(!m.starts_with(&MultiLocation::new(1, [GeneralIndex(99)].into()))); + /// assert!(!m.starts_with(&MultiLocation::new(0, [PalletInstance(3)].into()))); /// ``` pub fn starts_with(&self, prefix: &MultiLocation) -> bool { if self.parents != prefix.parents { @@ -279,9 +279,9 @@ impl MultiLocation { /// # Example /// ```rust /// # use staging_xcm::v2::{Junctions::*, Junction::*, MultiLocation}; - /// let mut m = MultiLocation::new(1, X1(Parachain(21))); - /// assert_eq!(m.append_with(X1(PalletInstance(3))), Ok(())); - /// assert_eq!(m, MultiLocation::new(1, X2(Parachain(21), PalletInstance(3)))); + /// let mut m = MultiLocation::new(1, [Parachain(21)].into()); + /// assert_eq!(m.append_with([PalletInstance(3)].into()), Ok(())); + /// assert_eq!(m, MultiLocation::new(1, [Parachain(21), PalletInstance(3)].into())); /// ``` pub fn append_with(&mut self, suffix: Junctions) -> Result<(), Junctions> { if self.interior.len().saturating_add(suffix.len()) > MAX_JUNCTIONS { @@ -300,9 +300,9 @@ impl MultiLocation { /// # Example /// ```rust /// # use staging_xcm::v2::{Junctions::*, Junction::*, MultiLocation}; - /// let mut m = MultiLocation::new(2, X1(PalletInstance(3))); - /// assert_eq!(m.prepend_with(MultiLocation::new(1, X2(Parachain(21), OnlyChild))), Ok(())); - /// assert_eq!(m, MultiLocation::new(1, X1(PalletInstance(3)))); + /// let mut m = MultiLocation::new(2, [PalletInstance(3)].into()); + /// assert_eq!(m.prepend_with(MultiLocation::new(1, [Parachain(21), OnlyChild].into())), Ok(())); + /// assert_eq!(m, MultiLocation::new(1, [PalletInstance(3)].into())); /// ``` pub fn prepend_with(&mut self, mut prefix: MultiLocation) -> Result<(), MultiLocation> { // prefix self (suffix) @@ -455,6 +455,7 @@ impl> From> for MultiLocation { } xcm_procedural::impl_conversion_functions_for_multilocation_v2!(); +xcm_procedural::impl_conversion_functions_for_junctions_v2!(); /// Maximum number of `Junction`s that a `Junctions` can contain. const MAX_JUNCTIONS: usize = 8; diff --git a/polkadot/xcm/src/v2/traits.rs b/polkadot/xcm/src/v2/traits.rs index 6453f91a1f1..9cfb9b051ab 100644 --- a/polkadot/xcm/src/v2/traits.rs +++ b/polkadot/xcm/src/v2/traits.rs @@ -292,11 +292,12 @@ pub type SendResult = result::Result<(), SendError>; /// } /// } /// -/// /// A sender that accepts a message that has an X2 junction, otherwise stops the routing. +/// /// A sender that accepts a message that has two junctions, otherwise stops the routing. /// struct Sender2; /// impl SendXcm for Sender2 { /// fn send_xcm(destination: impl Into, message: Xcm<()>) -> SendResult { -/// if let MultiLocation { parents: 0, interior: X2(j1, j2) } = destination.into() { +/// let destination = destination.into(); +/// if destination.parents == 0 && destination.interior.len() == 2 { /// Ok(()) /// } else { /// Err(SendError::Unroutable) diff --git a/polkadot/xcm/src/v3/junction.rs b/polkadot/xcm/src/v3/junction.rs index 6ae339db2ae..e9e51941b1a 100644 --- a/polkadot/xcm/src/v3/junction.rs +++ b/polkadot/xcm/src/v3/junction.rs @@ -22,7 +22,8 @@ use crate::{ BodyId as OldBodyId, BodyPart as OldBodyPart, Junction as OldJunction, NetworkId as OldNetworkId, }, - VersionedMultiLocation, + v4::{Junction as NewJunction, NetworkId as NewNetworkId}, + VersionedLocation, }; use bounded_collections::{BoundedSlice, BoundedVec, ConstU32}; use core::convert::{TryFrom, TryInto}; @@ -104,6 +105,31 @@ impl TryFrom for NetworkId { } } +impl From for Option { + fn from(new: NewNetworkId) -> Self { + Some(NetworkId::from(new)) + } +} + +impl From for NetworkId { + fn from(new: NewNetworkId) -> Self { + use NewNetworkId::*; + match new { + ByGenesis(hash) => Self::ByGenesis(hash), + ByFork { block_number, block_hash } => Self::ByFork { block_number, block_hash }, + Polkadot => Self::Polkadot, + Kusama => Self::Kusama, + Westend => Self::Westend, + Rococo => Self::Rococo, + Wococo => Self::Wococo, + Ethereum { chain_id } => Self::Ethereum { chain_id }, + BitcoinCore => Self::BitcoinCore, + BitcoinCash => Self::BitcoinCash, + PolkadotBulletin => Self::PolkadotBulletin, + } + } +} + /// An identifier of a pluralistic body. #[derive( Copy, @@ -414,6 +440,29 @@ impl TryFrom for Junction { } } +impl TryFrom for Junction { + type Error = (); + + fn try_from(value: NewJunction) -> Result { + use NewJunction::*; + Ok(match value { + Parachain(id) => Self::Parachain(id), + AccountId32 { network: maybe_network, id } => + Self::AccountId32 { network: maybe_network.map(|network| network.into()), id }, + AccountIndex64 { network: maybe_network, index } => + Self::AccountIndex64 { network: maybe_network.map(|network| network.into()), index }, + AccountKey20 { network: maybe_network, key } => + Self::AccountKey20 { network: maybe_network.map(|network| network.into()), key }, + PalletInstance(index) => Self::PalletInstance(index), + GeneralIndex(id) => Self::GeneralIndex(id), + GeneralKey { length, data } => Self::GeneralKey { length, data }, + OnlyChild => Self::OnlyChild, + Plurality { id, part } => Self::Plurality { id, part }, + GlobalConsensus(network) => Self::GlobalConsensus(network.into()), + }) + } +} + impl Junction { /// Convert `self` into a `MultiLocation` containing 0 parents. /// @@ -430,10 +479,10 @@ impl Junction { MultiLocation { parents: n, interior: Junctions::X1(self) } } - /// Convert `self` into a `VersionedMultiLocation` containing 0 parents. + /// Convert `self` into a `VersionedLocation` containing 0 parents. /// /// Similar to `Into::into`, except that this method can be used in a const evaluation context. - pub const fn into_versioned(self) -> VersionedMultiLocation { + pub const fn into_versioned(self) -> VersionedLocation { self.into_location().into_versioned() } diff --git a/polkadot/xcm/src/v3/junctions.rs b/polkadot/xcm/src/v3/junctions.rs index 88da20cb1a1..9748e81fa55 100644 --- a/polkadot/xcm/src/v3/junctions.rs +++ b/polkadot/xcm/src/v3/junctions.rs @@ -67,6 +67,27 @@ pub enum Junctions { X8(Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction), } +macro_rules! impl_junction { + ($count:expr, $variant:ident, ($($index:literal),+)) => { + /// Additional helper for building junctions + /// Useful for converting to future XCM versions + impl From<[Junction; $count]> for Junctions { + fn from(junctions: [Junction; $count]) -> Self { + Self::$variant($(junctions[$index]),*) + } + } + }; +} + +impl_junction!(1, X1, (0)); +impl_junction!(2, X2, (0, 1)); +impl_junction!(3, X3, (0, 1, 2)); +impl_junction!(4, X4, (0, 1, 2, 3)); +impl_junction!(5, X5, (0, 1, 2, 3, 4)); +impl_junction!(6, X6, (0, 1, 2, 3, 4, 5)); +impl_junction!(7, X7, (0, 1, 2, 3, 4, 5, 6)); +impl_junction!(8, X8, (0, 1, 2, 3, 4, 5, 6, 7)); + pub struct JunctionsIterator(Junctions); impl Iterator for JunctionsIterator { type Item = Junction; diff --git a/polkadot/xcm/src/v3/mod.rs b/polkadot/xcm/src/v3/mod.rs index 50b7a539122..1172cbf43e6 100644 --- a/polkadot/xcm/src/v3/mod.rs +++ b/polkadot/xcm/src/v3/mod.rs @@ -16,9 +16,15 @@ //! Version 3 of the Cross-Consensus Message format data structures. -use super::v2::{ - Instruction as OldInstruction, Response as OldResponse, WeightLimit as OldWeightLimit, - Xcm as OldXcm, +use super::{ + v2::{ + Instruction as OldInstruction, Response as OldResponse, WeightLimit as OldWeightLimit, + Xcm as OldXcm, + }, + v4::{ + Instruction as NewInstruction, PalletInfo as NewPalletInfo, + QueryResponseInfo as NewQueryResponseInfo, Response as NewResponse, Xcm as NewXcm, + }, }; use crate::DoubleEncoded; use alloc::{vec, vec::Vec}; @@ -48,7 +54,7 @@ pub use multiasset::{ WildFungibility, WildMultiAsset, MAX_ITEMS_IN_MULTIASSETS, }; pub use multilocation::{ - Ancestor, AncestorThen, InteriorMultiLocation, MultiLocation, Parent, ParentThen, + Ancestor, AncestorThen, InteriorMultiLocation, Location, MultiLocation, Parent, ParentThen, }; pub use traits::{ send_xcm, validate_send, Error, ExecuteXcm, Outcome, PreparedMessage, Result, SendError, @@ -209,7 +215,7 @@ pub mod prelude { InteriorMultiLocation, Junction::{self, *}, Junctions::{self, *}, - MaybeErrorCode, MultiAsset, + Location, MaybeErrorCode, MultiAsset, MultiAssetFilter::{self, *}, MultiAssets, MultiLocation, NetworkId::{self, *}, @@ -275,6 +281,22 @@ impl PalletInfo { } } +impl TryInto for PalletInfo { + type Error = (); + + fn try_into(self) -> result::Result { + NewPalletInfo::new( + self.index, + self.name.into_inner(), + self.module_name.into_inner(), + self.major, + self.minor, + self.patch, + ) + .map_err(|_| ()) + } +} + #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] #[scale_info(replace_segment("staging_xcm", "xcm"))] #[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))] @@ -324,6 +346,32 @@ impl Default for Response { } } +impl TryFrom for Response { + type Error = (); + + fn try_from(new: NewResponse) -> result::Result { + use NewResponse::*; + Ok(match new { + Null => Self::Null, + Assets(assets) => Self::Assets(assets.try_into()?), + ExecutionResult(result) => + Self::ExecutionResult(result.map(|(num, old_error)| (num, old_error.into()))), + Version(version) => Self::Version(version), + PalletsInfo(pallet_info) => { + let inner = pallet_info + .into_iter() + .map(TryInto::try_into) + .collect::, _>>()?; + Self::PalletsInfo( + BoundedVec::::try_from(inner).map_err(|_| ())?, + ) + }, + DispatchResult(maybe_error) => + Self::DispatchResult(maybe_error.try_into().map_err(|_| ())?), + }) + } +} + /// Information regarding the composition of a query response. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)] #[scale_info(replace_segment("staging_xcm", "xcm"))] @@ -338,6 +386,18 @@ pub struct QueryResponseInfo { pub max_weight: Weight, } +impl TryFrom for QueryResponseInfo { + type Error = (); + + fn try_from(new: NewQueryResponseInfo) -> result::Result { + Ok(Self { + destination: new.destination.try_into()?, + query_id: new.query_id, + max_weight: new.max_weight, + }) + } +} + /// An optional weight limit. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)] #[scale_info(replace_segment("staging_xcm", "xcm"))] @@ -367,13 +427,12 @@ impl From for Option { } } -impl TryFrom for WeightLimit { - type Error = (); - fn try_from(x: OldWeightLimit) -> result::Result { +impl From for WeightLimit { + fn from(x: OldWeightLimit) -> Self { use OldWeightLimit::*; match x { - Limited(w) => Ok(Self::Limited(Weight::from_parts(w, DEFAULT_PROOF_SIZE))), - Unlimited => Ok(Self::Unlimited), + Limited(w) => Self::Limited(Weight::from_parts(w, DEFAULT_PROOF_SIZE)), + Unlimited => Self::Unlimited, } } } @@ -1263,6 +1322,155 @@ impl TryFrom> for Xcm { } } +// Convert from a v4 XCM to a v3 XCM. +impl TryFrom> for Xcm { + type Error = (); + fn try_from(new_xcm: NewXcm) -> result::Result { + Ok(Xcm(new_xcm.0.into_iter().map(TryInto::try_into).collect::>()?)) + } +} + +// Convert from a v4 instruction to a v3 instruction. +impl TryFrom> for Instruction { + type Error = (); + fn try_from(new_instruction: NewInstruction) -> result::Result { + use NewInstruction::*; + Ok(match new_instruction { + WithdrawAsset(assets) => Self::WithdrawAsset(assets.try_into()?), + ReserveAssetDeposited(assets) => Self::ReserveAssetDeposited(assets.try_into()?), + ReceiveTeleportedAsset(assets) => Self::ReceiveTeleportedAsset(assets.try_into()?), + QueryResponse { query_id, response, max_weight, querier: Some(querier) } => + Self::QueryResponse { + query_id, + querier: querier.try_into()?, + response: response.try_into()?, + max_weight, + }, + QueryResponse { query_id, response, max_weight, querier: None } => + Self::QueryResponse { + query_id, + querier: None, + response: response.try_into()?, + max_weight, + }, + TransferAsset { assets, beneficiary } => Self::TransferAsset { + assets: assets.try_into()?, + beneficiary: beneficiary.try_into()?, + }, + TransferReserveAsset { assets, dest, xcm } => Self::TransferReserveAsset { + assets: assets.try_into()?, + dest: dest.try_into()?, + xcm: xcm.try_into()?, + }, + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => + Self::HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity }, + HrmpChannelAccepted { recipient } => Self::HrmpChannelAccepted { recipient }, + HrmpChannelClosing { initiator, sender, recipient } => + Self::HrmpChannelClosing { initiator, sender, recipient }, + Transact { origin_kind, require_weight_at_most, call } => + Self::Transact { origin_kind, require_weight_at_most, call: call.into() }, + ReportError(response_info) => Self::ReportError(QueryResponseInfo { + query_id: response_info.query_id, + destination: response_info.destination.try_into().map_err(|_| ())?, + max_weight: response_info.max_weight, + }), + DepositAsset { assets, beneficiary } => { + let beneficiary = beneficiary.try_into()?; + let assets = assets.try_into()?; + Self::DepositAsset { assets, beneficiary } + }, + DepositReserveAsset { assets, dest, xcm } => { + let dest = dest.try_into()?; + let xcm = xcm.try_into()?; + let assets = assets.try_into()?; + Self::DepositReserveAsset { assets, dest, xcm } + }, + ExchangeAsset { give, want, maximal } => { + let give = give.try_into()?; + let want = want.try_into()?; + Self::ExchangeAsset { give, want, maximal } + }, + InitiateReserveWithdraw { assets, reserve, xcm } => { + // No `max_assets` here, so if there's a connt, then we cannot translate. + let assets = assets.try_into()?; + let reserve = reserve.try_into()?; + let xcm = xcm.try_into()?; + Self::InitiateReserveWithdraw { assets, reserve, xcm } + }, + InitiateTeleport { assets, dest, xcm } => { + // No `max_assets` here, so if there's a connt, then we cannot translate. + let assets = assets.try_into()?; + let dest = dest.try_into()?; + let xcm = xcm.try_into()?; + Self::InitiateTeleport { assets, dest, xcm } + }, + ReportHolding { response_info, assets } => { + let response_info = QueryResponseInfo { + destination: response_info.destination.try_into().map_err(|_| ())?, + query_id: response_info.query_id, + max_weight: response_info.max_weight, + }; + Self::ReportHolding { response_info, assets: assets.try_into()? } + }, + BuyExecution { fees, weight_limit } => { + let fees = fees.try_into()?; + let weight_limit = weight_limit.into(); + Self::BuyExecution { fees, weight_limit } + }, + ClearOrigin => Self::ClearOrigin, + DescendOrigin(who) => Self::DescendOrigin(who.try_into()?), + RefundSurplus => Self::RefundSurplus, + SetErrorHandler(xcm) => Self::SetErrorHandler(xcm.try_into()?), + SetAppendix(xcm) => Self::SetAppendix(xcm.try_into()?), + ClearError => Self::ClearError, + ClaimAsset { assets, ticket } => { + let assets = assets.try_into()?; + let ticket = ticket.try_into()?; + Self::ClaimAsset { assets, ticket } + }, + Trap(code) => Self::Trap(code), + SubscribeVersion { query_id, max_response_weight } => + Self::SubscribeVersion { query_id, max_response_weight }, + UnsubscribeVersion => Self::UnsubscribeVersion, + BurnAsset(assets) => Self::BurnAsset(assets.try_into()?), + ExpectAsset(assets) => Self::ExpectAsset(assets.try_into()?), + ExpectOrigin(maybe_origin) => + Self::ExpectOrigin(maybe_origin.map(|origin| origin.try_into()).transpose()?), + ExpectError(maybe_error) => Self::ExpectError(maybe_error), + ExpectTransactStatus(maybe_error_code) => Self::ExpectTransactStatus(maybe_error_code), + QueryPallet { module_name, response_info } => + Self::QueryPallet { module_name, response_info: response_info.try_into()? }, + ExpectPallet { index, name, module_name, crate_major, min_crate_minor } => + Self::ExpectPallet { index, name, module_name, crate_major, min_crate_minor }, + ReportTransactStatus(response_info) => + Self::ReportTransactStatus(response_info.try_into()?), + ClearTransactStatus => Self::ClearTransactStatus, + UniversalOrigin(junction) => Self::UniversalOrigin(junction.try_into()?), + ExportMessage { network, destination, xcm } => Self::ExportMessage { + network: network.into(), + destination: destination.try_into()?, + xcm: xcm.try_into()?, + }, + LockAsset { asset, unlocker } => + Self::LockAsset { asset: asset.try_into()?, unlocker: unlocker.try_into()? }, + UnlockAsset { asset, target } => + Self::UnlockAsset { asset: asset.try_into()?, target: target.try_into()? }, + NoteUnlockable { asset, owner } => + Self::NoteUnlockable { asset: asset.try_into()?, owner: owner.try_into()? }, + RequestUnlock { asset, locker } => + Self::RequestUnlock { asset: asset.try_into()?, locker: locker.try_into()? }, + SetFeesMode { jit_withdraw } => Self::SetFeesMode { jit_withdraw }, + SetTopic(topic) => Self::SetTopic(topic), + ClearTopic => Self::ClearTopic, + AliasOrigin(location) => Self::AliasOrigin(location.try_into()?), + UnpaidExecution { weight_limit, check_origin } => Self::UnpaidExecution { + weight_limit, + check_origin: check_origin.map(|origin| origin.try_into()).transpose()?, + }, + }) + } +} + /// Default value for the proof size weight component when converting from V2. Set at 64 KB. /// NOTE: Make sure this is removed after we properly account for PoV weights. const DEFAULT_PROOF_SIZE: u64 = 64 * 1024; @@ -1343,10 +1551,8 @@ impl TryFrom> for Instruction { }; Self::ReportHolding { response_info, assets: assets.try_into()? } }, - BuyExecution { fees, weight_limit } => Self::BuyExecution { - fees: fees.try_into()?, - weight_limit: weight_limit.try_into()?, - }, + BuyExecution { fees, weight_limit } => + Self::BuyExecution { fees: fees.try_into()?, weight_limit: weight_limit.into() }, ClearOrigin => Self::ClearOrigin, DescendOrigin(who) => Self::DescendOrigin(who.try_into()?), RefundSurplus => Self::RefundSurplus, diff --git a/polkadot/xcm/src/v3/multiasset.rs b/polkadot/xcm/src/v3/multiasset.rs index c8801f5a461..557ffa568a4 100644 --- a/polkadot/xcm/src/v3/multiasset.rs +++ b/polkadot/xcm/src/v3/multiasset.rs @@ -27,11 +27,18 @@ //! filtering an XCM holding account. use super::{InteriorMultiLocation, MultiLocation}; -use crate::v2::{ - AssetId as OldAssetId, AssetInstance as OldAssetInstance, Fungibility as OldFungibility, - MultiAsset as OldMultiAsset, MultiAssetFilter as OldMultiAssetFilter, - MultiAssets as OldMultiAssets, WildFungibility as OldWildFungibility, - WildMultiAsset as OldWildMultiAsset, +use crate::{ + v2::{ + AssetId as OldAssetId, AssetInstance as OldAssetInstance, Fungibility as OldFungibility, + MultiAsset as OldMultiAsset, MultiAssetFilter as OldMultiAssetFilter, + MultiAssets as OldMultiAssets, WildFungibility as OldWildFungibility, + WildMultiAsset as OldWildMultiAsset, + }, + v4::{ + Asset as NewMultiAsset, AssetFilter as NewMultiAssetFilter, AssetId as NewAssetId, + AssetInstance as NewAssetInstance, Assets as NewMultiAssets, Fungibility as NewFungibility, + WildAsset as NewWildMultiAsset, WildFungibility as NewWildFungibility, + }, }; use alloc::{vec, vec::Vec}; use bounded_collections::{BoundedVec, ConstU32}; @@ -86,6 +93,21 @@ impl TryFrom for AssetInstance { } } +impl TryFrom for AssetInstance { + type Error = (); + fn try_from(value: NewAssetInstance) -> Result { + use NewAssetInstance::*; + Ok(match value { + Undefined => Self::Undefined, + Index(n) => Self::Index(n), + Array4(n) => Self::Array4(n), + Array8(n) => Self::Array8(n), + Array16(n) => Self::Array16(n), + Array32(n) => Self::Array32(n), + }) + } +} + impl From<()> for AssetInstance { fn from(_: ()) -> Self { Self::Undefined @@ -310,6 +332,17 @@ impl TryFrom for Fungibility { } } +impl TryFrom for Fungibility { + type Error = (); + fn try_from(value: NewFungibility) -> Result { + use NewFungibility::*; + Ok(match value { + Fungible(n) => Self::Fungible(n), + NonFungible(i) => Self::NonFungible(i.try_into()?), + }) + } +} + /// Classification of whether an asset is fungible or not. #[derive( Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen, @@ -335,6 +368,17 @@ impl TryFrom for WildFungibility { } } +impl TryFrom for WildFungibility { + type Error = (); + fn try_from(value: NewWildFungibility) -> Result { + use NewWildFungibility::*; + Ok(match value { + Fungible => Self::Fungible, + NonFungible => Self::NonFungible, + }) + } +} + /// Classification of an asset being concrete or abstract. #[derive( Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen, @@ -378,6 +422,13 @@ impl TryFrom for AssetId { } } +impl TryFrom for AssetId { + type Error = (); + fn try_from(new: NewAssetId) -> Result { + Ok(Self::Concrete(new.0.try_into()?)) + } +} + impl AssetId { /// Prepend a `MultiLocation` to a concrete asset, giving it a new root location. pub fn prepend_with(&mut self, prepend: &MultiLocation) -> Result<(), ()> { @@ -506,6 +557,13 @@ impl TryFrom for MultiAsset { } } +impl TryFrom for MultiAsset { + type Error = (); + fn try_from(new: NewMultiAsset) -> Result { + Ok(Self { id: new.id.try_into()?, fun: new.fun.try_into()? }) + } +} + /// A `Vec` of `MultiAsset`s. /// /// There are a number of invariants which the construction and mutation functions must ensure are @@ -549,6 +607,18 @@ impl TryFrom for MultiAssets { } } +impl TryFrom for MultiAssets { + type Error = (); + fn try_from(new: NewMultiAssets) -> Result { + let v = new + .into_inner() + .into_iter() + .map(MultiAsset::try_from) + .collect::, ()>>()?; + Ok(MultiAssets(v)) + } +} + impl From> for MultiAssets { fn from(mut assets: Vec) -> Self { let mut res = Vec::with_capacity(assets.len()); @@ -747,6 +817,20 @@ impl TryFrom for WildMultiAsset { } } +impl TryFrom for WildMultiAsset { + type Error = (); + fn try_from(new: NewWildMultiAsset) -> Result { + use NewWildMultiAsset::*; + Ok(match new { + AllOf { id, fun } => Self::AllOf { id: id.try_into()?, fun: fun.try_into()? }, + AllOfCounted { id, fun, count } => + Self::AllOfCounted { id: id.try_into()?, fun: fun.try_into()?, count }, + All => Self::All, + AllCounted(count) => Self::AllCounted(count), + }) + } +} + impl TryFrom<(OldWildMultiAsset, u32)> for WildMultiAsset { type Error = (); fn try_from(old: (OldWildMultiAsset, u32)) -> Result { @@ -917,6 +1001,17 @@ impl TryFrom for MultiAssetFilter { } } +impl TryFrom for MultiAssetFilter { + type Error = (); + fn try_from(new: NewMultiAssetFilter) -> Result { + use NewMultiAssetFilter::*; + Ok(match new { + Definite(x) => Self::Definite(x.try_into()?), + Wild(x) => Self::Wild(x.try_into()?), + }) + } +} + impl TryFrom<(OldMultiAssetFilter, u32)> for MultiAssetFilter { type Error = (); fn try_from(old: (OldMultiAssetFilter, u32)) -> Result { diff --git a/polkadot/xcm/src/v3/multilocation.rs b/polkadot/xcm/src/v3/multilocation.rs index 9649b1b3207..c588b924ac7 100644 --- a/polkadot/xcm/src/v3/multilocation.rs +++ b/polkadot/xcm/src/v3/multilocation.rs @@ -17,7 +17,9 @@ //! XCM `MultiLocation` datatype. use super::{Junction, Junctions}; -use crate::{v2::MultiLocation as OldMultiLocation, VersionedMultiLocation}; +use crate::{ + v2::MultiLocation as OldMultiLocation, v4::Location as NewMultiLocation, VersionedLocation, +}; use core::{ convert::{TryFrom, TryInto}, result, @@ -74,6 +76,9 @@ pub struct MultiLocation { pub interior: Junctions, } +/// Type alias for a better transition to V4. +pub type Location = MultiLocation; + impl Default for MultiLocation { fn default() -> Self { Self { parents: 0, interior: Junctions::Here } @@ -91,9 +96,9 @@ impl MultiLocation { MultiLocation { parents, interior: interior.into() } } - /// Consume `self` and return the equivalent `VersionedMultiLocation` value. - pub const fn into_versioned(self) -> VersionedMultiLocation { - VersionedMultiLocation::V3(self) + /// Consume `self` and return the equivalent `VersionedLocation` value. + pub const fn into_versioned(self) -> VersionedLocation { + VersionedLocation::V3(self) } /// Creates a new `MultiLocation` with 0 parents and a `Here` interior. @@ -469,6 +474,23 @@ impl TryFrom for MultiLocation { } } +impl TryFrom for Option { + type Error = (); + fn try_from(new: NewMultiLocation) -> result::Result { + Ok(Some(MultiLocation::try_from(new)?)) + } +} + +impl TryFrom for MultiLocation { + type Error = (); + fn try_from(new: NewMultiLocation) -> result::Result { + Ok(MultiLocation { + parents: new.parent_count(), + interior: new.interior().clone().try_into()?, + }) + } +} + /// A unit struct which can be converted into a `MultiLocation` of `parents` value 1. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] pub struct Parent; diff --git a/polkadot/xcm/src/v3/traits.rs b/polkadot/xcm/src/v3/traits.rs index 29bd40a6a2d..9e9b983fdf8 100644 --- a/polkadot/xcm/src/v3/traits.rs +++ b/polkadot/xcm/src/v3/traits.rs @@ -216,52 +216,6 @@ impl From for Error { pub type Result = result::Result<(), Error>; -/* -TODO: XCMv4 -/// Outcome of an XCM execution. -#[derive(Clone, Encode, Decode, Eq, PartialEq, Debug, TypeInfo)] -pub enum Outcome { - /// Execution completed successfully; given weight was used. - Complete { used: Weight }, - /// Execution started, but did not complete successfully due to the given error; given weight - /// was used. - Incomplete { used: Weight, error: Error }, - /// Execution did not start due to the given error. - Error { error: Error }, -} - -impl Outcome { - pub fn ensure_complete(self) -> Result { - match self { - Outcome::Complete { .. } => Ok(()), - Outcome::Incomplete { error, .. } => Err(error), - Outcome::Error { error, .. } => Err(error), - } - } - pub fn ensure_execution(self) -> result::Result { - match self { - Outcome::Complete { used, .. } => Ok(used), - Outcome::Incomplete { used, .. } => Ok(used), - Outcome::Error { error, .. } => Err(error), - } - } - /// How much weight was used by the XCM execution attempt. - pub fn weight_used(&self) -> Weight { - match self { - Outcome::Complete { used, .. } => *used, - Outcome::Incomplete { used, .. } => *used, - Outcome::Error { .. } => Weight::zero(), - } - } -} - -impl From for Outcome { - fn from(error: Error) -> Self { - Self::Error { error, maybe_id: None } - } -} -*/ - /// Outcome of an XCM execution. #[derive(Clone, Encode, Decode, Eq, PartialEq, Debug, TypeInfo)] #[scale_info(replace_segment("staging_xcm", "xcm"))] @@ -337,8 +291,6 @@ pub trait ExecuteXcm { /// /// The weight limit is a basic hard-limit and the implementation may place further /// restrictions or requirements on weight and other aspects. - // TODO: XCMv4 - // #[deprecated = "Use `prepare_and_execute` instead"] fn execute_xcm( origin: impl Into, message: Xcm, @@ -361,8 +313,6 @@ pub trait ExecuteXcm { /// /// Some amount of `weight_credit` may be provided which, depending on the implementation, may /// allow execution without associated payment. - // TODO: XCMv4 - // #[deprecated = "Use `prepare_and_execute` instead"] fn execute_xcm_in_credit( origin: impl Into, message: Xcm, diff --git a/polkadot/xcm/src/v4/asset.rs b/polkadot/xcm/src/v4/asset.rs new file mode 100644 index 00000000000..8aa1cc61437 --- /dev/null +++ b/polkadot/xcm/src/v4/asset.rs @@ -0,0 +1,915 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Cross-Consensus Message format asset data structures. +//! +//! This encompasses four types for representing assets: +//! - `Asset`: A description of a single asset, either an instance of a non-fungible or some amount +//! of a fungible. +//! - `Assets`: A collection of `Asset`s. These are stored in a `Vec` and sorted with fungibles +//! first. +//! - `Wild`: A single asset wildcard, this can either be "all" assets, or all assets of a specific +//! kind. +//! - `AssetFilter`: A combination of `Wild` and `Assets` designed for efficiently filtering an XCM +//! holding account. + +use super::{InteriorLocation, Location, Reanchorable}; +use crate::v3::{ + AssetId as OldAssetId, AssetInstance as OldAssetInstance, Fungibility as OldFungibility, + MultiAsset as OldAsset, MultiAssetFilter as OldAssetFilter, MultiAssets as OldAssets, + WildFungibility as OldWildFungibility, WildMultiAsset as OldWildAsset, +}; +use alloc::{vec, vec::Vec}; +use core::{ + cmp::Ordering, + convert::{TryFrom, TryInto}, +}; +use parity_scale_codec::{self as codec, Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +/// A general identifier for an instance of a non-fungible asset class. +#[derive( + Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, TypeInfo, MaxEncodedLen, +)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum AssetInstance { + /// Undefined - used if the non-fungible asset class has only one instance. + Undefined, + + /// A compact index. Technically this could be greater than `u128`, but this implementation + /// supports only values up to `2**128 - 1`. + Index(#[codec(compact)] u128), + + /// A 4-byte fixed-length datum. + Array4([u8; 4]), + + /// An 8-byte fixed-length datum. + Array8([u8; 8]), + + /// A 16-byte fixed-length datum. + Array16([u8; 16]), + + /// A 32-byte fixed-length datum. + Array32([u8; 32]), +} + +impl TryFrom for AssetInstance { + type Error = (); + fn try_from(value: OldAssetInstance) -> Result { + use OldAssetInstance::*; + Ok(match value { + Undefined => Self::Undefined, + Index(n) => Self::Index(n), + Array4(n) => Self::Array4(n), + Array8(n) => Self::Array8(n), + Array16(n) => Self::Array16(n), + Array32(n) => Self::Array32(n), + }) + } +} + +impl From<()> for AssetInstance { + fn from(_: ()) -> Self { + Self::Undefined + } +} + +impl From<[u8; 4]> for AssetInstance { + fn from(x: [u8; 4]) -> Self { + Self::Array4(x) + } +} + +impl From<[u8; 8]> for AssetInstance { + fn from(x: [u8; 8]) -> Self { + Self::Array8(x) + } +} + +impl From<[u8; 16]> for AssetInstance { + fn from(x: [u8; 16]) -> Self { + Self::Array16(x) + } +} + +impl From<[u8; 32]> for AssetInstance { + fn from(x: [u8; 32]) -> Self { + Self::Array32(x) + } +} + +impl From for AssetInstance { + fn from(x: u8) -> Self { + Self::Index(x as u128) + } +} + +impl From for AssetInstance { + fn from(x: u16) -> Self { + Self::Index(x as u128) + } +} + +impl From for AssetInstance { + fn from(x: u32) -> Self { + Self::Index(x as u128) + } +} + +impl From for AssetInstance { + fn from(x: u64) -> Self { + Self::Index(x as u128) + } +} + +impl TryFrom for () { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Undefined => Ok(()), + _ => Err(()), + } + } +} + +impl TryFrom for [u8; 4] { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Array4(x) => Ok(x), + _ => Err(()), + } + } +} + +impl TryFrom for [u8; 8] { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Array8(x) => Ok(x), + _ => Err(()), + } + } +} + +impl TryFrom for [u8; 16] { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Array16(x) => Ok(x), + _ => Err(()), + } + } +} + +impl TryFrom for [u8; 32] { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Array32(x) => Ok(x), + _ => Err(()), + } + } +} + +impl TryFrom for u8 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => x.try_into().map_err(|_| ()), + _ => Err(()), + } + } +} + +impl TryFrom for u16 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => x.try_into().map_err(|_| ()), + _ => Err(()), + } + } +} + +impl TryFrom for u32 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => x.try_into().map_err(|_| ()), + _ => Err(()), + } + } +} + +impl TryFrom for u64 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => x.try_into().map_err(|_| ()), + _ => Err(()), + } + } +} + +impl TryFrom for u128 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => Ok(x), + _ => Err(()), + } + } +} + +/// Classification of whether an asset is fungible or not, along with a mandatory amount or +/// instance. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum Fungibility { + /// A fungible asset; we record a number of units, as a `u128` in the inner item. + Fungible(#[codec(compact)] u128), + /// A non-fungible asset. We record the instance identifier in the inner item. Only one asset + /// of each instance identifier may ever be in existence at once. + NonFungible(AssetInstance), +} + +#[derive(Decode)] +enum UncheckedFungibility { + Fungible(#[codec(compact)] u128), + NonFungible(AssetInstance), +} + +impl Decode for Fungibility { + fn decode(input: &mut I) -> Result { + match UncheckedFungibility::decode(input)? { + UncheckedFungibility::Fungible(a) if a != 0 => Ok(Self::Fungible(a)), + UncheckedFungibility::NonFungible(i) => Ok(Self::NonFungible(i)), + UncheckedFungibility::Fungible(_) => + Err("Fungible asset of zero amount is not allowed".into()), + } + } +} + +impl Fungibility { + pub fn is_kind(&self, w: WildFungibility) -> bool { + use Fungibility::*; + use WildFungibility::{Fungible as WildFungible, NonFungible as WildNonFungible}; + matches!((self, w), (Fungible(_), WildFungible) | (NonFungible(_), WildNonFungible)) + } +} + +impl From for Fungibility { + fn from(amount: i32) -> Fungibility { + debug_assert_ne!(amount, 0); + Fungibility::Fungible(amount as u128) + } +} + +impl From for Fungibility { + fn from(amount: u128) -> Fungibility { + debug_assert_ne!(amount, 0); + Fungibility::Fungible(amount) + } +} + +impl> From for Fungibility { + fn from(instance: T) -> Fungibility { + Fungibility::NonFungible(instance.into()) + } +} + +impl TryFrom for Fungibility { + type Error = (); + fn try_from(value: OldFungibility) -> Result { + use OldFungibility::*; + Ok(match value { + Fungible(n) => Self::Fungible(n), + NonFungible(i) => Self::NonFungible(i.try_into()?), + }) + } +} + +/// Classification of whether an asset is fungible or not. +#[derive( + Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen, +)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum WildFungibility { + /// The asset is fungible. + Fungible, + /// The asset is not fungible. + NonFungible, +} + +impl TryFrom for WildFungibility { + type Error = (); + fn try_from(value: OldWildFungibility) -> Result { + use OldWildFungibility::*; + Ok(match value { + Fungible => Self::Fungible, + NonFungible => Self::NonFungible, + }) + } +} + +/// Location to identify an asset. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub struct AssetId(pub Location); + +impl> From for AssetId { + fn from(x: T) -> Self { + Self(x.into()) + } +} + +impl TryFrom for AssetId { + type Error = (); + fn try_from(old: OldAssetId) -> Result { + use OldAssetId::*; + Ok(match old { + Concrete(l) => Self(l.try_into()?), + Abstract(_) => return Err(()), + }) + } +} + +impl AssetId { + /// Prepend a `Location` to an asset id, giving it a new root location. + pub fn prepend_with(&mut self, prepend: &Location) -> Result<(), ()> { + self.0.prepend_with(prepend.clone()).map_err(|_| ())?; + Ok(()) + } + + /// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding + /// `Asset` value. + pub fn into_asset(self, fun: Fungibility) -> Asset { + Asset { fun, id: self } + } + + /// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding + /// `WildAsset` wildcard (`AllOf`) value. + pub fn into_wild(self, fun: WildFungibility) -> WildAsset { + WildAsset::AllOf { fun, id: self } + } +} + +impl Reanchorable for AssetId { + type Error = (); + + /// Mutate the asset to represent the same value from the perspective of a new `target` + /// location. The local chain's location is provided in `context`. + fn reanchor(&mut self, target: &Location, context: &InteriorLocation) -> Result<(), ()> { + self.0.reanchor(target, context)?; + Ok(()) + } + + fn reanchored(mut self, target: &Location, context: &InteriorLocation) -> Result { + match self.reanchor(target, context) { + Ok(()) => Ok(self), + Err(()) => Err(()), + } + } +} + +/// Either an amount of a single fungible asset, or a single well-identified non-fungible asset. +#[derive(Clone, Eq, PartialEq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub struct Asset { + /// The overall asset identity (aka *class*, in the case of a non-fungible). + pub id: AssetId, + /// The fungibility of the asset, which contains either the amount (in the case of a fungible + /// asset) or the *instance ID*, the secondary asset identifier. + pub fun: Fungibility, +} + +impl PartialOrd for Asset { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Asset { + fn cmp(&self, other: &Self) -> Ordering { + match (&self.fun, &other.fun) { + (Fungibility::Fungible(..), Fungibility::NonFungible(..)) => Ordering::Less, + (Fungibility::NonFungible(..), Fungibility::Fungible(..)) => Ordering::Greater, + _ => (&self.id, &self.fun).cmp(&(&other.id, &other.fun)), + } + } +} + +impl, B: Into> From<(A, B)> for Asset { + fn from((id, fun): (A, B)) -> Asset { + Asset { fun: fun.into(), id: id.into() } + } +} + +impl Asset { + pub fn is_fungible(&self, maybe_id: Option) -> bool { + use Fungibility::*; + matches!(self.fun, Fungible(..)) && maybe_id.map_or(true, |i| i == self.id) + } + + pub fn is_non_fungible(&self, maybe_id: Option) -> bool { + use Fungibility::*; + matches!(self.fun, NonFungible(..)) && maybe_id.map_or(true, |i| i == self.id) + } + + /// Prepend a `Location` to a concrete asset, giving it a new root location. + pub fn prepend_with(&mut self, prepend: &Location) -> Result<(), ()> { + self.id.prepend_with(prepend) + } + + /// Returns true if `self` is a super-set of the given `inner` asset. + pub fn contains(&self, inner: &Asset) -> bool { + use Fungibility::*; + if self.id == inner.id { + match (&self.fun, &inner.fun) { + (Fungible(a), Fungible(i)) if a >= i => return true, + (NonFungible(a), NonFungible(i)) if a == i => return true, + _ => (), + } + } + false + } +} + +impl Reanchorable for Asset { + type Error = (); + + /// Mutate the location of the asset identifier if concrete, giving it the same location + /// relative to a `target` context. The local context is provided as `context`. + fn reanchor(&mut self, target: &Location, context: &InteriorLocation) -> Result<(), ()> { + self.id.reanchor(target, context) + } + + /// Mutate the location of the asset identifier if concrete, giving it the same location + /// relative to a `target` context. The local context is provided as `context`. + fn reanchored(mut self, target: &Location, context: &InteriorLocation) -> Result { + self.id.reanchor(target, context)?; + Ok(self) + } +} + +impl TryFrom for Asset { + type Error = (); + fn try_from(old: OldAsset) -> Result { + Ok(Self { id: old.id.try_into()?, fun: old.fun.try_into()? }) + } +} + +/// A `Vec` of `Asset`s. +/// +/// There are a number of invariants which the construction and mutation functions must ensure are +/// maintained: +/// - It may contain no items of duplicate asset class; +/// - All items must be ordered; +/// - The number of items should grow no larger than `MAX_ITEMS_IN_ASSETS`. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, TypeInfo, Default)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub struct Assets(Vec); + +/// Maximum number of items we expect in a single `Assets` value. Note this is not (yet) +/// enforced, and just serves to provide a sensible `max_encoded_len` for `Assets`. +pub const MAX_ITEMS_IN_ASSETS: usize = 20; + +impl MaxEncodedLen for Assets { + fn max_encoded_len() -> usize { + Asset::max_encoded_len() * MAX_ITEMS_IN_ASSETS + } +} + +impl Decode for Assets { + fn decode(input: &mut I) -> Result { + Self::from_sorted_and_deduplicated(Vec::::decode(input)?) + .map_err(|()| "Out of order".into()) + } +} + +impl TryFrom for Assets { + type Error = (); + fn try_from(old: OldAssets) -> Result { + let v = old + .into_inner() + .into_iter() + .map(Asset::try_from) + .collect::, ()>>()?; + Ok(Assets(v)) + } +} + +impl From> for Assets { + fn from(mut assets: Vec) -> Self { + let mut res = Vec::with_capacity(assets.len()); + if !assets.is_empty() { + assets.sort(); + let mut iter = assets.into_iter(); + if let Some(first) = iter.next() { + let last = iter.fold(first, |a, b| -> Asset { + match (a, b) { + ( + Asset { fun: Fungibility::Fungible(a_amount), id: a_id }, + Asset { fun: Fungibility::Fungible(b_amount), id: b_id }, + ) if a_id == b_id => Asset { + id: a_id, + fun: Fungibility::Fungible(a_amount.saturating_add(b_amount)), + }, + ( + Asset { fun: Fungibility::NonFungible(a_instance), id: a_id }, + Asset { fun: Fungibility::NonFungible(b_instance), id: b_id }, + ) if a_id == b_id && a_instance == b_instance => + Asset { fun: Fungibility::NonFungible(a_instance), id: a_id }, + (to_push, to_remember) => { + res.push(to_push); + to_remember + }, + } + }); + res.push(last); + } + } + Self(res) + } +} + +impl> From for Assets { + fn from(x: T) -> Self { + Self(vec![x.into()]) + } +} + +impl Assets { + /// A new (empty) value. + pub fn new() -> Self { + Self(Vec::new()) + } + + /// Create a new instance of `Assets` from a `Vec` whose contents are sorted + /// and which contain no duplicates. + /// + /// Returns `Ok` if the operation succeeds and `Err` if `r` is out of order or had duplicates. + /// If you can't guarantee that `r` is sorted and deduplicated, then use + /// `From::>::from` which is infallible. + pub fn from_sorted_and_deduplicated(r: Vec) -> Result { + if r.is_empty() { + return Ok(Self(Vec::new())) + } + r.iter().skip(1).try_fold(&r[0], |a, b| -> Result<&Asset, ()> { + if a.id < b.id || a < b && (a.is_non_fungible(None) || b.is_non_fungible(None)) { + Ok(b) + } else { + Err(()) + } + })?; + Ok(Self(r)) + } + + /// Create a new instance of `Assets` from a `Vec` whose contents are sorted + /// and which contain no duplicates. + /// + /// In release mode, this skips any checks to ensure that `r` is correct, making it a + /// negligible-cost operation. Generally though you should avoid using it unless you have a + /// strict proof that `r` is valid. + #[cfg(test)] + pub fn from_sorted_and_deduplicated_skip_checks(r: Vec) -> Self { + Self::from_sorted_and_deduplicated(r).expect("Invalid input r is not sorted/deduped") + } + /// Create a new instance of `Assets` from a `Vec` whose contents are sorted + /// and which contain no duplicates. + /// + /// In release mode, this skips any checks to ensure that `r` is correct, making it a + /// negligible-cost operation. Generally though you should avoid using it unless you have a + /// strict proof that `r` is valid. + /// + /// In test mode, this checks anyway and panics on fail. + #[cfg(not(test))] + pub fn from_sorted_and_deduplicated_skip_checks(r: Vec) -> Self { + Self(r) + } + + /// Add some asset onto the list, saturating. This is quite a laborious operation since it + /// maintains the ordering. + pub fn push(&mut self, a: Asset) { + for asset in self.0.iter_mut().filter(|x| x.id == a.id) { + match (&a.fun, &mut asset.fun) { + (Fungibility::Fungible(amount), Fungibility::Fungible(balance)) => { + *balance = balance.saturating_add(*amount); + return + }, + (Fungibility::NonFungible(inst1), Fungibility::NonFungible(inst2)) + if inst1 == inst2 => + return, + _ => (), + } + } + self.0.push(a); + self.0.sort(); + } + + /// Returns `true` if this definitely represents no asset. + pub fn is_none(&self) -> bool { + self.0.is_empty() + } + + /// Returns true if `self` is a super-set of the given `inner` asset. + pub fn contains(&self, inner: &Asset) -> bool { + self.0.iter().any(|i| i.contains(inner)) + } + + /// Consume `self` and return the inner vec. + #[deprecated = "Use `into_inner()` instead"] + pub fn drain(self) -> Vec { + self.0 + } + + /// Consume `self` and return the inner vec. + pub fn into_inner(self) -> Vec { + self.0 + } + + /// Return a reference to the inner vec. + pub fn inner(&self) -> &Vec { + &self.0 + } + + /// Return the number of distinct asset instances contained. + pub fn len(&self) -> usize { + self.0.len() + } + + /// Prepend a `Location` to any concrete asset items, giving it a new root location. + pub fn prepend_with(&mut self, prefix: &Location) -> Result<(), ()> { + self.0.iter_mut().try_for_each(|i| i.prepend_with(prefix)) + } + + /// Return a reference to an item at a specific index or `None` if it doesn't exist. + pub fn get(&self, index: usize) -> Option<&Asset> { + self.0.get(index) + } +} + +impl Reanchorable for Assets { + type Error = (); + + fn reanchor(&mut self, target: &Location, context: &InteriorLocation) -> Result<(), ()> { + self.0.iter_mut().try_for_each(|i| i.reanchor(target, context))?; + self.0.sort(); + Ok(()) + } + + fn reanchored(mut self, target: &Location, context: &InteriorLocation) -> Result { + match self.reanchor(target, context) { + Ok(()) => Ok(self), + Err(()) => Err(()), + } + } +} + +/// A wildcard representing a set of assets. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum WildAsset { + /// All assets in Holding. + All, + /// All assets in Holding of a given fungibility and ID. + AllOf { id: AssetId, fun: WildFungibility }, + /// All assets in Holding, up to `u32` individual assets (different instances of non-fungibles + /// are separate assets). + AllCounted(#[codec(compact)] u32), + /// All assets in Holding of a given fungibility and ID up to `count` individual assets + /// (different instances of non-fungibles are separate assets). + AllOfCounted { + id: AssetId, + fun: WildFungibility, + #[codec(compact)] + count: u32, + }, +} + +impl TryFrom for WildAsset { + type Error = (); + fn try_from(old: OldWildAsset) -> Result { + use OldWildAsset::*; + Ok(match old { + AllOf { id, fun } => Self::AllOf { id: id.try_into()?, fun: fun.try_into()? }, + All => Self::All, + AllOfCounted { id, fun, count } => + Self::AllOfCounted { id: id.try_into()?, fun: fun.try_into()?, count }, + AllCounted(count) => Self::AllCounted(count), + }) + } +} + +impl WildAsset { + /// Returns true if `self` is a super-set of the given `inner` asset. + pub fn contains(&self, inner: &Asset) -> bool { + use WildAsset::*; + match self { + AllOfCounted { count: 0, .. } | AllCounted(0) => false, + AllOf { fun, id } | AllOfCounted { id, fun, .. } => + inner.fun.is_kind(*fun) && &inner.id == id, + All | AllCounted(_) => true, + } + } + + /// Returns true if the wild element of `self` matches `inner`. + /// + /// Note that for `Counted` variants of wildcards, then it will disregard the count except for + /// always returning `false` when equal to 0. + #[deprecated = "Use `contains` instead"] + pub fn matches(&self, inner: &Asset) -> bool { + self.contains(inner) + } + + /// Mutate the asset to represent the same value from the perspective of a new `target` + /// location. The local chain's location is provided in `context`. + pub fn reanchor(&mut self, target: &Location, context: &InteriorLocation) -> Result<(), ()> { + use WildAsset::*; + match self { + AllOf { ref mut id, .. } | AllOfCounted { ref mut id, .. } => + id.reanchor(target, context), + All | AllCounted(_) => Ok(()), + } + } + + /// Maximum count of assets allowed to match, if any. + pub fn count(&self) -> Option { + use WildAsset::*; + match self { + AllOfCounted { count, .. } | AllCounted(count) => Some(*count), + All | AllOf { .. } => None, + } + } + + /// Explicit limit on number of assets allowed to match, if any. + pub fn limit(&self) -> Option { + self.count() + } + + /// Consume self and return the equivalent version but counted and with the `count` set to the + /// given parameter. + pub fn counted(self, count: u32) -> Self { + use WildAsset::*; + match self { + AllOfCounted { fun, id, .. } | AllOf { fun, id } => AllOfCounted { fun, id, count }, + All | AllCounted(_) => AllCounted(count), + } + } +} + +impl, B: Into> From<(A, B)> for WildAsset { + fn from((id, fun): (A, B)) -> WildAsset { + WildAsset::AllOf { fun: fun.into(), id: id.into() } + } +} + +/// `Asset` collection, defined either by a number of `Assets` or a single wildcard. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum AssetFilter { + /// Specify the filter as being everything contained by the given `Assets` inner. + Definite(Assets), + /// Specify the filter as the given `WildAsset` wildcard. + Wild(WildAsset), +} + +impl> From for AssetFilter { + fn from(x: T) -> Self { + Self::Wild(x.into()) + } +} + +impl From for AssetFilter { + fn from(x: Asset) -> Self { + Self::Definite(vec![x].into()) + } +} + +impl From> for AssetFilter { + fn from(x: Vec) -> Self { + Self::Definite(x.into()) + } +} + +impl From for AssetFilter { + fn from(x: Assets) -> Self { + Self::Definite(x) + } +} + +impl AssetFilter { + /// Returns true if `inner` would be matched by `self`. + /// + /// Note that for `Counted` variants of wildcards, then it will disregard the count except for + /// always returning `false` when equal to 0. + pub fn matches(&self, inner: &Asset) -> bool { + match self { + AssetFilter::Definite(ref assets) => assets.contains(inner), + AssetFilter::Wild(ref wild) => wild.contains(inner), + } + } + + /// Mutate the location of the asset identifier if concrete, giving it the same location + /// relative to a `target` context. The local context is provided as `context`. + pub fn reanchor(&mut self, target: &Location, context: &InteriorLocation) -> Result<(), ()> { + match self { + AssetFilter::Definite(ref mut assets) => assets.reanchor(target, context), + AssetFilter::Wild(ref mut wild) => wild.reanchor(target, context), + } + } + + /// Maximum count of assets it is possible to match, if known. + pub fn count(&self) -> Option { + use AssetFilter::*; + match self { + Definite(x) => Some(x.len() as u32), + Wild(x) => x.count(), + } + } + + /// Explicit limit placed on the number of items, if any. + pub fn limit(&self) -> Option { + use AssetFilter::*; + match self { + Definite(_) => None, + Wild(x) => x.limit(), + } + } +} + +impl TryFrom for AssetFilter { + type Error = (); + fn try_from(old: OldAssetFilter) -> Result { + Ok(match old { + OldAssetFilter::Definite(x) => Self::Definite(x.try_into()?), + OldAssetFilter::Wild(x) => Self::Wild(x.try_into()?), + }) + } +} + +#[cfg(test)] +mod tests { + use super::super::prelude::*; + + #[test] + fn conversion_works() { + let _: Assets = (Here, 1u128).into(); + } + + #[test] + fn from_sorted_and_deduplicated_works() { + use super::*; + use alloc::vec; + + let empty = vec![]; + let r = Assets::from_sorted_and_deduplicated(empty); + assert_eq!(r, Ok(Assets(vec![]))); + + let dup_fun = vec![(Here, 100).into(), (Here, 10).into()]; + let r = Assets::from_sorted_and_deduplicated(dup_fun); + assert!(r.is_err()); + + let dup_nft = vec![(Here, *b"notgood!").into(), (Here, *b"notgood!").into()]; + let r = Assets::from_sorted_and_deduplicated(dup_nft); + assert!(r.is_err()); + + let good_fun = vec![(Here, 10).into(), (Parent, 10).into()]; + let r = Assets::from_sorted_and_deduplicated(good_fun.clone()); + assert_eq!(r, Ok(Assets(good_fun))); + + let bad_fun = vec![(Parent, 10).into(), (Here, 10).into()]; + let r = Assets::from_sorted_and_deduplicated(bad_fun); + assert!(r.is_err()); + + let good_nft = vec![(Here, ()).into(), (Here, *b"good").into()]; + let r = Assets::from_sorted_and_deduplicated(good_nft.clone()); + assert_eq!(r, Ok(Assets(good_nft))); + + let bad_nft = vec![(Here, *b"bad!").into(), (Here, ()).into()]; + let r = Assets::from_sorted_and_deduplicated(bad_nft); + assert!(r.is_err()); + + let mixed_good = vec![(Here, 10).into(), (Here, *b"good").into()]; + let r = Assets::from_sorted_and_deduplicated(mixed_good.clone()); + assert_eq!(r, Ok(Assets(mixed_good))); + + let mixed_bad = vec![(Here, *b"bad!").into(), (Here, 10).into()]; + let r = Assets::from_sorted_and_deduplicated(mixed_bad); + assert!(r.is_err()); + } +} diff --git a/polkadot/xcm/src/v4/junction.rs b/polkadot/xcm/src/v4/junction.rs new file mode 100644 index 00000000000..b5d10484aa0 --- /dev/null +++ b/polkadot/xcm/src/v4/junction.rs @@ -0,0 +1,317 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Support data structures for `Location`, primarily the `Junction` datatype. + +use super::Location; +pub use crate::v3::{BodyId, BodyPart}; +use crate::{ + v3::{Junction as OldJunction, NetworkId as OldNetworkId}, + VersionedLocation, +}; +use bounded_collections::{BoundedSlice, BoundedVec, ConstU32}; +use core::convert::TryFrom; +use parity_scale_codec::{self, Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; +use serde::{Deserialize, Serialize}; + +/// A single item in a path to describe the relative location of a consensus system. +/// +/// Each item assumes a pre-existing location as its context and is defined in terms of it. +#[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + Debug, + TypeInfo, + MaxEncodedLen, + Serialize, + Deserialize, +)] +pub enum Junction { + /// An indexed parachain belonging to and operated by the context. + /// + /// Generally used when the context is a Polkadot Relay-chain. + Parachain(#[codec(compact)] u32), + /// A 32-byte identifier for an account of a specific network that is respected as a sovereign + /// endpoint within the context. + /// + /// Generally used when the context is a Substrate-based chain. + AccountId32 { network: Option, id: [u8; 32] }, + /// An 8-byte index for an account of a specific network that is respected as a sovereign + /// endpoint within the context. + /// + /// May be used when the context is a Frame-based chain and includes e.g. an indices pallet. + AccountIndex64 { + network: Option, + #[codec(compact)] + index: u64, + }, + /// A 20-byte identifier for an account of a specific network that is respected as a sovereign + /// endpoint within the context. + /// + /// May be used when the context is an Ethereum or Bitcoin chain or smart-contract. + AccountKey20 { network: Option, key: [u8; 20] }, + /// An instanced, indexed pallet that forms a constituent part of the context. + /// + /// Generally used when the context is a Frame-based chain. + // TODO XCMv4 inner should be `Compact`. + PalletInstance(u8), + /// A non-descript index within the context location. + /// + /// Usage will vary widely owing to its generality. + /// + /// NOTE: Try to avoid using this and instead use a more specific item. + GeneralIndex(#[codec(compact)] u128), + /// A nondescript array datum, 32 bytes, acting as a key within the context + /// location. + /// + /// Usage will vary widely owing to its generality. + /// + /// NOTE: Try to avoid using this and instead use a more specific item. + // Note this is implemented as an array with a length rather than using `BoundedVec` owing to + // the bound for `Copy`. + GeneralKey { length: u8, data: [u8; 32] }, + /// The unambiguous child. + /// + /// Not currently used except as a fallback when deriving context. + OnlyChild, + /// A pluralistic body existing within consensus. + /// + /// Typical to be used to represent a governance origin of a chain, but could in principle be + /// used to represent things such as multisigs also. + Plurality { id: BodyId, part: BodyPart }, + /// A global network capable of externalizing its own consensus. This is not generally + /// meaningful outside of the universal level. + GlobalConsensus(NetworkId), +} + +/// A global identifier of a data structure existing within consensus. +/// +/// Maintenance note: Networks with global consensus and which are practically bridgeable within the +/// Polkadot ecosystem are given preference over explicit naming in this enumeration. +#[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + Debug, + TypeInfo, + MaxEncodedLen, + Serialize, + Deserialize, +)] +pub enum NetworkId { + /// Network specified by the first 32 bytes of its genesis block. + ByGenesis([u8; 32]), + /// Network defined by the first 32-bytes of the hash and number of some block it contains. + ByFork { block_number: u64, block_hash: [u8; 32] }, + /// The Polkadot mainnet Relay-chain. + Polkadot, + /// The Kusama canary-net Relay-chain. + Kusama, + /// The Westend testnet Relay-chain. + Westend, + /// The Rococo testnet Relay-chain. + Rococo, + /// The Wococo testnet Relay-chain. + Wococo, + /// An Ethereum network specified by its chain ID. + Ethereum { + /// The EIP-155 chain ID. + #[codec(compact)] + chain_id: u64, + }, + /// The Bitcoin network, including hard-forks supported by Bitcoin Core development team. + BitcoinCore, + /// The Bitcoin network, including hard-forks supported by Bitcoin Cash developers. + BitcoinCash, + /// The Polkadot Bulletin chain. + PolkadotBulletin, +} + +impl From for Option { + fn from(old: OldNetworkId) -> Self { + Some(NetworkId::from(old)) + } +} + +impl From for NetworkId { + fn from(old: OldNetworkId) -> Self { + use OldNetworkId::*; + match old { + ByGenesis(hash) => Self::ByGenesis(hash), + ByFork { block_number, block_hash } => Self::ByFork { block_number, block_hash }, + Polkadot => Self::Polkadot, + Kusama => Self::Kusama, + Westend => Self::Westend, + Rococo => Self::Rococo, + Wococo => Self::Wococo, + Ethereum { chain_id } => Self::Ethereum { chain_id }, + BitcoinCore => Self::BitcoinCore, + BitcoinCash => Self::BitcoinCash, + PolkadotBulletin => Self::PolkadotBulletin, + } + } +} + +impl From for Junction { + fn from(n: NetworkId) -> Self { + Self::GlobalConsensus(n) + } +} + +impl From<[u8; 32]> for Junction { + fn from(id: [u8; 32]) -> Self { + Self::AccountId32 { network: None, id } + } +} + +impl From>> for Junction { + fn from(key: BoundedVec>) -> Self { + key.as_bounded_slice().into() + } +} + +impl<'a> From>> for Junction { + fn from(key: BoundedSlice<'a, u8, ConstU32<32>>) -> Self { + let mut data = [0u8; 32]; + data[..key.len()].copy_from_slice(&key[..]); + Self::GeneralKey { length: key.len() as u8, data } + } +} + +impl<'a> TryFrom<&'a Junction> for BoundedSlice<'a, u8, ConstU32<32>> { + type Error = (); + fn try_from(key: &'a Junction) -> Result { + match key { + Junction::GeneralKey { length, data } => + BoundedSlice::try_from(&data[..data.len().min(*length as usize)]).map_err(|_| ()), + _ => Err(()), + } + } +} + +impl From<[u8; 20]> for Junction { + fn from(key: [u8; 20]) -> Self { + Self::AccountKey20 { network: None, key } + } +} + +impl From for Junction { + fn from(index: u64) -> Self { + Self::AccountIndex64 { network: None, index } + } +} + +impl From for Junction { + fn from(id: u128) -> Self { + Self::GeneralIndex(id) + } +} + +impl TryFrom for Junction { + type Error = (); + fn try_from(value: OldJunction) -> Result { + use OldJunction::*; + Ok(match value { + Parachain(id) => Self::Parachain(id), + AccountId32 { network: maybe_network, id } => + Self::AccountId32 { network: maybe_network.map(|network| network.into()), id }, + AccountIndex64 { network: maybe_network, index } => + Self::AccountIndex64 { network: maybe_network.map(|network| network.into()), index }, + AccountKey20 { network: maybe_network, key } => + Self::AccountKey20 { network: maybe_network.map(|network| network.into()), key }, + PalletInstance(index) => Self::PalletInstance(index), + GeneralIndex(id) => Self::GeneralIndex(id), + GeneralKey { length, data } => Self::GeneralKey { length, data }, + OnlyChild => Self::OnlyChild, + Plurality { id, part } => Self::Plurality { id, part }, + GlobalConsensus(network) => Self::GlobalConsensus(network.into()), + }) + } +} + +impl Junction { + /// Convert `self` into a `Location` containing 0 parents. + /// + /// Similar to `Into::into`, except that this method can be used in a const evaluation context. + pub fn into_location(self) -> Location { + Location::new(0, [self]) + } + + /// Convert `self` into a `Location` containing `n` parents. + /// + /// Similar to `Self::into_location`, with the added ability to specify the number of parent + /// junctions. + pub fn into_exterior(self, n: u8) -> Location { + Location::new(n, [self]) + } + + /// Convert `self` into a `VersionedLocation` containing 0 parents. + /// + /// Similar to `Into::into`, except that this method can be used in a const evaluation context. + pub fn into_versioned(self) -> VersionedLocation { + self.into_location().into_versioned() + } + + /// Remove the `NetworkId` value. + pub fn remove_network_id(&mut self) { + use Junction::*; + match self { + AccountId32 { ref mut network, .. } | + AccountIndex64 { ref mut network, .. } | + AccountKey20 { ref mut network, .. } => *network = None, + _ => {}, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use alloc::vec; + + #[test] + fn junction_round_trip_works() { + let j = Junction::GeneralKey { length: 32, data: [1u8; 32] }; + let k = Junction::try_from(OldJunction::try_from(j).unwrap()).unwrap(); + assert_eq!(j, k); + + let j = OldJunction::GeneralKey { length: 32, data: [1u8; 32] }; + let k = OldJunction::try_from(Junction::try_from(j).unwrap()).unwrap(); + assert_eq!(j, k); + + let j = Junction::from(BoundedVec::try_from(vec![1u8, 2, 3, 4]).unwrap()); + let k = Junction::try_from(OldJunction::try_from(j).unwrap()).unwrap(); + assert_eq!(j, k); + let s: BoundedSlice<_, _> = (&k).try_into().unwrap(); + assert_eq!(s, &[1u8, 2, 3, 4][..]); + + let j = OldJunction::GeneralKey { length: 32, data: [1u8; 32] }; + let k = OldJunction::try_from(Junction::try_from(j).unwrap()).unwrap(); + assert_eq!(j, k); + } +} diff --git a/polkadot/xcm/src/v4/junctions.rs b/polkadot/xcm/src/v4/junctions.rs new file mode 100644 index 00000000000..48712dd74c6 --- /dev/null +++ b/polkadot/xcm/src/v4/junctions.rs @@ -0,0 +1,723 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! XCM `Junctions`/`InteriorLocation` datatype. + +use super::{Junction, Location, NetworkId}; +use alloc::sync::Arc; +use core::{convert::TryFrom, mem, ops::Range, result}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +/// Maximum number of `Junction`s that a `Junctions` can contain. +pub(crate) const MAX_JUNCTIONS: usize = 8; + +/// Non-parent junctions that can be constructed, up to the length of 8. This specific `Junctions` +/// implementation uses a Rust `enum` in order to make pattern matching easier. +/// +/// Parent junctions cannot be constructed with this type. Refer to `Location` for +/// instructions on constructing parent junctions. +#[derive( + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + Debug, + TypeInfo, + MaxEncodedLen, + serde::Serialize, + serde::Deserialize, +)] +pub enum Junctions { + /// The interpreting consensus system. + Here, + /// A relative path comprising 1 junction. + X1(Arc<[Junction; 1]>), + /// A relative path comprising 2 junctions. + X2(Arc<[Junction; 2]>), + /// A relative path comprising 3 junctions. + X3(Arc<[Junction; 3]>), + /// A relative path comprising 4 junctions. + X4(Arc<[Junction; 4]>), + /// A relative path comprising 5 junctions. + X5(Arc<[Junction; 5]>), + /// A relative path comprising 6 junctions. + X6(Arc<[Junction; 6]>), + /// A relative path comprising 7 junctions. + X7(Arc<[Junction; 7]>), + /// A relative path comprising 8 junctions. + X8(Arc<[Junction; 8]>), +} + +macro_rules! impl_junctions { + ($count:expr, $variant:ident) => { + impl From<[Junction; $count]> for Junctions { + fn from(junctions: [Junction; $count]) -> Self { + Self::$variant(Arc::new(junctions)) + } + } + impl PartialEq<[Junction; $count]> for Junctions { + fn eq(&self, rhs: &[Junction; $count]) -> bool { + self.as_slice() == rhs + } + } + }; +} + +impl_junctions!(1, X1); +impl_junctions!(2, X2); +impl_junctions!(3, X3); +impl_junctions!(4, X4); +impl_junctions!(5, X5); +impl_junctions!(6, X6); +impl_junctions!(7, X7); +impl_junctions!(8, X8); + +pub struct JunctionsIterator { + junctions: Junctions, + range: Range, +} + +impl Iterator for JunctionsIterator { + type Item = Junction; + fn next(&mut self) -> Option { + self.junctions.at(self.range.next()?).cloned() + } +} + +impl DoubleEndedIterator for JunctionsIterator { + fn next_back(&mut self) -> Option { + self.junctions.at(self.range.next_back()?).cloned() + } +} + +pub struct JunctionsRefIterator<'a> { + junctions: &'a Junctions, + range: Range, +} + +impl<'a> Iterator for JunctionsRefIterator<'a> { + type Item = &'a Junction; + fn next(&mut self) -> Option<&'a Junction> { + self.junctions.at(self.range.next()?) + } +} + +impl<'a> DoubleEndedIterator for JunctionsRefIterator<'a> { + fn next_back(&mut self) -> Option<&'a Junction> { + self.junctions.at(self.range.next_back()?) + } +} +impl<'a> IntoIterator for &'a Junctions { + type Item = &'a Junction; + type IntoIter = JunctionsRefIterator<'a>; + fn into_iter(self) -> Self::IntoIter { + JunctionsRefIterator { junctions: self, range: 0..self.len() } + } +} + +impl IntoIterator for Junctions { + type Item = Junction; + type IntoIter = JunctionsIterator; + fn into_iter(self) -> Self::IntoIter { + JunctionsIterator { range: 0..self.len(), junctions: self } + } +} + +impl Junctions { + /// Convert `self` into a `Location` containing 0 parents. + /// + /// Similar to `Into::into`, except that this method can be used in a const evaluation context. + pub const fn into_location(self) -> Location { + Location { parents: 0, interior: self } + } + + /// Convert `self` into a `Location` containing `n` parents. + /// + /// Similar to `Self::into_location`, with the added ability to specify the number of parent + /// junctions. + pub const fn into_exterior(self, n: u8) -> Location { + Location { parents: n, interior: self } + } + + /// Casts `self` into a slice containing `Junction`s. + pub fn as_slice(&self) -> &[Junction] { + match self { + Junctions::Here => &[], + Junctions::X1(ref a) => &a[..], + Junctions::X2(ref a) => &a[..], + Junctions::X3(ref a) => &a[..], + Junctions::X4(ref a) => &a[..], + Junctions::X5(ref a) => &a[..], + Junctions::X6(ref a) => &a[..], + Junctions::X7(ref a) => &a[..], + Junctions::X8(ref a) => &a[..], + } + } + + /// Casts `self` into a mutable slice containing `Junction`s. + pub fn as_slice_mut(&mut self) -> &mut [Junction] { + match self { + Junctions::Here => &mut [], + Junctions::X1(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X2(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X3(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X4(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X5(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X6(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X7(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X8(ref mut a) => &mut Arc::make_mut(a)[..], + } + } + + /// Remove the `NetworkId` value in any `Junction`s. + pub fn remove_network_id(&mut self) { + self.for_each_mut(Junction::remove_network_id); + } + + /// Treating `self` as the universal context, return the location of the local consensus system + /// from the point of view of the given `target`. + pub fn invert_target(&self, target: &Location) -> Result { + let mut itself = self.clone(); + let mut junctions = Self::Here; + for _ in 0..target.parent_count() { + junctions = junctions + .pushed_front_with(itself.take_last().unwrap_or(Junction::OnlyChild)) + .map_err(|_| ())?; + } + let parents = target.interior().len() as u8; + Ok(Location::new(parents, junctions)) + } + + /// Execute a function `f` on every junction. We use this since we cannot implement a mutable + /// `Iterator` without unsafe code. + pub fn for_each_mut(&mut self, x: impl FnMut(&mut Junction)) { + self.as_slice_mut().iter_mut().for_each(x) + } + + /// Extract the network ID treating this value as a universal location. + /// + /// This will return an `Err` if the first item is not a `GlobalConsensus`, which would indicate + /// that this value is not a universal location. + pub fn global_consensus(&self) -> Result { + if let Some(Junction::GlobalConsensus(network)) = self.first() { + Ok(*network) + } else { + Err(()) + } + } + + /// Extract the network ID and the interior consensus location, treating this value as a + /// universal location. + /// + /// This will return an `Err` if the first item is not a `GlobalConsensus`, which would indicate + /// that this value is not a universal location. + pub fn split_global(self) -> Result<(NetworkId, Junctions), ()> { + match self.split_first() { + (location, Some(Junction::GlobalConsensus(network))) => Ok((network, location)), + _ => return Err(()), + } + } + + /// Treat `self` as a universal location and the context of `relative`, returning the universal + /// location of relative. + /// + /// This will return an error if `relative` has as many (or more) parents than there are + /// junctions in `self`, implying that relative refers into a different global consensus. + pub fn within_global(mut self, relative: Location) -> Result { + if self.len() <= relative.parent_count() as usize { + return Err(()) + } + for _ in 0..relative.parent_count() { + self.take_last(); + } + for j in relative.interior() { + self.push(*j).map_err(|_| ())?; + } + Ok(self) + } + + /// Consumes `self` and returns how `viewer` would address it locally. + pub fn relative_to(mut self, viewer: &Junctions) -> Location { + let mut i = 0; + while match (self.first(), viewer.at(i)) { + (Some(x), Some(y)) => x == y, + _ => false, + } { + self = self.split_first().0; + // NOTE: Cannot overflow as loop can only iterate at most `MAX_JUNCTIONS` times. + i += 1; + } + // AUDIT NOTES: + // - above loop ensures that `i <= viewer.len()`. + // - `viewer.len()` is at most `MAX_JUNCTIONS`, so won't overflow a `u8`. + Location::new((viewer.len() - i) as u8, self) + } + + /// Returns first junction, or `None` if the location is empty. + pub fn first(&self) -> Option<&Junction> { + self.as_slice().first() + } + + /// Returns last junction, or `None` if the location is empty. + pub fn last(&self) -> Option<&Junction> { + self.as_slice().last() + } + + /// Splits off the first junction, returning the remaining suffix (first item in tuple) and the + /// first element (second item in tuple) or `None` if it was empty. + pub fn split_first(self) -> (Junctions, Option) { + match self { + Junctions::Here => (Junctions::Here, None), + Junctions::X1(xs) => { + let [a] = *xs; + (Junctions::Here, Some(a)) + }, + Junctions::X2(xs) => { + let [a, b] = *xs; + ([b].into(), Some(a)) + }, + Junctions::X3(xs) => { + let [a, b, c] = *xs; + ([b, c].into(), Some(a)) + }, + Junctions::X4(xs) => { + let [a, b, c, d] = *xs; + ([b, c, d].into(), Some(a)) + }, + Junctions::X5(xs) => { + let [a, b, c, d, e] = *xs; + ([b, c, d, e].into(), Some(a)) + }, + Junctions::X6(xs) => { + let [a, b, c, d, e, f] = *xs; + ([b, c, d, e, f].into(), Some(a)) + }, + Junctions::X7(xs) => { + let [a, b, c, d, e, f, g] = *xs; + ([b, c, d, e, f, g].into(), Some(a)) + }, + Junctions::X8(xs) => { + let [a, b, c, d, e, f, g, h] = *xs; + ([b, c, d, e, f, g, h].into(), Some(a)) + }, + } + } + + /// Splits off the last junction, returning the remaining prefix (first item in tuple) and the + /// last element (second item in tuple) or `None` if it was empty. + pub fn split_last(self) -> (Junctions, Option) { + match self { + Junctions::Here => (Junctions::Here, None), + Junctions::X1(xs) => { + let [a] = *xs; + (Junctions::Here, Some(a)) + }, + Junctions::X2(xs) => { + let [a, b] = *xs; + ([a].into(), Some(b)) + }, + Junctions::X3(xs) => { + let [a, b, c] = *xs; + ([a, b].into(), Some(c)) + }, + Junctions::X4(xs) => { + let [a, b, c, d] = *xs; + ([a, b, c].into(), Some(d)) + }, + Junctions::X5(xs) => { + let [a, b, c, d, e] = *xs; + ([a, b, c, d].into(), Some(e)) + }, + Junctions::X6(xs) => { + let [a, b, c, d, e, f] = *xs; + ([a, b, c, d, e].into(), Some(f)) + }, + Junctions::X7(xs) => { + let [a, b, c, d, e, f, g] = *xs; + ([a, b, c, d, e, f].into(), Some(g)) + }, + Junctions::X8(xs) => { + let [a, b, c, d, e, f, g, h] = *xs; + ([a, b, c, d, e, f, g].into(), Some(h)) + }, + } + } + + /// Removes the first element from `self`, returning it (or `None` if it was empty). + pub fn take_first(&mut self) -> Option { + let mut d = Junctions::Here; + mem::swap(&mut *self, &mut d); + let (tail, head) = d.split_first(); + *self = tail; + head + } + + /// Removes the last element from `self`, returning it (or `None` if it was empty). + pub fn take_last(&mut self) -> Option { + let mut d = Junctions::Here; + mem::swap(&mut *self, &mut d); + let (head, tail) = d.split_last(); + *self = head; + tail + } + + /// Mutates `self` to be appended with `new` or returns an `Err` with `new` if would overflow. + pub fn push(&mut self, new: impl Into) -> result::Result<(), Junction> { + let new = new.into(); + let mut dummy = Junctions::Here; + mem::swap(self, &mut dummy); + match dummy.pushed_with(new) { + Ok(s) => { + *self = s; + Ok(()) + }, + Err((s, j)) => { + *self = s; + Err(j) + }, + } + } + + /// Mutates `self` to be prepended with `new` or returns an `Err` with `new` if would overflow. + pub fn push_front(&mut self, new: impl Into) -> result::Result<(), Junction> { + let new = new.into(); + let mut dummy = Junctions::Here; + mem::swap(self, &mut dummy); + match dummy.pushed_front_with(new) { + Ok(s) => { + *self = s; + Ok(()) + }, + Err((s, j)) => { + *self = s; + Err(j) + }, + } + } + + /// Consumes `self` and returns a `Junctions` suffixed with `new`, or an `Err` with the + /// original value of `self` and `new` in case of overflow. + pub fn pushed_with(self, new: impl Into) -> result::Result { + let new = new.into(); + Ok(match self { + Junctions::Here => [new].into(), + Junctions::X1(xs) => { + let [a] = *xs; + [a, new].into() + }, + Junctions::X2(xs) => { + let [a, b] = *xs; + [a, b, new].into() + }, + Junctions::X3(xs) => { + let [a, b, c] = *xs; + [a, b, c, new].into() + }, + Junctions::X4(xs) => { + let [a, b, c, d] = *xs; + [a, b, c, d, new].into() + }, + Junctions::X5(xs) => { + let [a, b, c, d, e] = *xs; + [a, b, c, d, e, new].into() + }, + Junctions::X6(xs) => { + let [a, b, c, d, e, f] = *xs; + [a, b, c, d, e, f, new].into() + }, + Junctions::X7(xs) => { + let [a, b, c, d, e, f, g] = *xs; + [a, b, c, d, e, f, g, new].into() + }, + s => Err((s, new))?, + }) + } + + /// Consumes `self` and returns a `Junctions` prefixed with `new`, or an `Err` with the + /// original value of `self` and `new` in case of overflow. + pub fn pushed_front_with( + self, + new: impl Into, + ) -> result::Result { + let new = new.into(); + Ok(match self { + Junctions::Here => [new].into(), + Junctions::X1(xs) => { + let [a] = *xs; + [new, a].into() + }, + Junctions::X2(xs) => { + let [a, b] = *xs; + [new, a, b].into() + }, + Junctions::X3(xs) => { + let [a, b, c] = *xs; + [new, a, b, c].into() + }, + Junctions::X4(xs) => { + let [a, b, c, d] = *xs; + [new, a, b, c, d].into() + }, + Junctions::X5(xs) => { + let [a, b, c, d, e] = *xs; + [new, a, b, c, d, e].into() + }, + Junctions::X6(xs) => { + let [a, b, c, d, e, f] = *xs; + [new, a, b, c, d, e, f].into() + }, + Junctions::X7(xs) => { + let [a, b, c, d, e, f, g] = *xs; + [new, a, b, c, d, e, f, g].into() + }, + s => Err((s, new))?, + }) + } + + /// Mutate `self` so that it is suffixed with `suffix`. + /// + /// Does not modify `self` and returns `Err` with `suffix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions, Junction::*, Location}; + /// # fn main() { + /// let mut m = Junctions::from([Parachain(21)]); + /// assert_eq!(m.append_with([PalletInstance(3)]), Ok(())); + /// assert_eq!(m, [Parachain(21), PalletInstance(3)]); + /// # } + /// ``` + pub fn append_with(&mut self, suffix: impl Into) -> Result<(), Junctions> { + let suffix = suffix.into(); + if self.len().saturating_add(suffix.len()) > MAX_JUNCTIONS { + return Err(suffix) + } + for j in suffix.into_iter() { + self.push(j).expect("Already checked the sum of the len()s; qed") + } + Ok(()) + } + + /// Returns the number of junctions in `self`. + pub fn len(&self) -> usize { + self.as_slice().len() + } + + /// Returns the junction at index `i`, or `None` if the location doesn't contain that many + /// elements. + pub fn at(&self, i: usize) -> Option<&Junction> { + self.as_slice().get(i) + } + + /// Returns a mutable reference to the junction at index `i`, or `None` if the location doesn't + /// contain that many elements. + pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> { + self.as_slice_mut().get_mut(i) + } + + /// Returns a reference iterator over the junctions. + pub fn iter(&self) -> JunctionsRefIterator { + JunctionsRefIterator { junctions: self, range: 0..self.len() } + } + + /// Ensures that self begins with `prefix` and that it has a single `Junction` item following. + /// If so, returns a reference to this `Junction` item. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions, Junction::*}; + /// # fn main() { + /// let mut m = Junctions::from([Parachain(2), PalletInstance(3), OnlyChild]); + /// assert_eq!(m.match_and_split(&[Parachain(2), PalletInstance(3)].into()), Some(&OnlyChild)); + /// assert_eq!(m.match_and_split(&[Parachain(2)].into()), None); + /// # } + /// ``` + pub fn match_and_split(&self, prefix: &Junctions) -> Option<&Junction> { + if prefix.len() + 1 != self.len() { + return None + } + for i in 0..prefix.len() { + if prefix.at(i) != self.at(i) { + return None + } + } + return self.at(prefix.len()) + } + + pub fn starts_with(&self, prefix: &Junctions) -> bool { + prefix.len() <= self.len() && prefix.iter().zip(self.iter()).all(|(x, y)| x == y) + } +} + +impl TryFrom for Junctions { + type Error = Location; + fn try_from(x: Location) -> result::Result { + if x.parent_count() > 0 { + Err(x) + } else { + Ok(x.interior().clone()) + } + } +} + +impl> From for Junctions { + fn from(x: T) -> Self { + [x.into()].into() + } +} + +impl From<[Junction; 0]> for Junctions { + fn from(_: [Junction; 0]) -> Self { + Self::Here + } +} + +impl From<()> for Junctions { + fn from(_: ()) -> Self { + Self::Here + } +} + +xcm_procedural::impl_conversion_functions_for_junctions_v4!(); + +#[cfg(test)] +mod tests { + use super::{super::prelude::*, *}; + + #[test] + fn inverting_works() { + let context: InteriorLocation = (Parachain(1000), PalletInstance(42)).into(); + let target = (Parent, PalletInstance(69)).into(); + let expected = (Parent, PalletInstance(42)).into(); + let inverted = context.invert_target(&target).unwrap(); + assert_eq!(inverted, expected); + + let context: InteriorLocation = + (Parachain(1000), PalletInstance(42), GeneralIndex(1)).into(); + let target = (Parent, Parent, PalletInstance(69), GeneralIndex(2)).into(); + let expected = (Parent, Parent, PalletInstance(42), GeneralIndex(1)).into(); + let inverted = context.invert_target(&target).unwrap(); + assert_eq!(inverted, expected); + } + + #[test] + fn relative_to_works() { + use NetworkId::*; + assert_eq!( + Junctions::from([Polkadot.into()]).relative_to(&Junctions::from([Kusama.into()])), + (Parent, Polkadot).into() + ); + let base = Junctions::from([Kusama.into(), Parachain(1), PalletInstance(1)]); + + // Ancestors. + assert_eq!(Here.relative_to(&base), (Parent, Parent, Parent).into()); + assert_eq!(Junctions::from([Kusama.into()]).relative_to(&base), (Parent, Parent).into()); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(1)]).relative_to(&base), + (Parent,).into() + ); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(1), PalletInstance(1)]).relative_to(&base), + Here.into() + ); + + // Ancestors with one child. + assert_eq!( + Junctions::from([Polkadot.into()]).relative_to(&base), + (Parent, Parent, Parent, Polkadot).into() + ); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(2)]).relative_to(&base), + (Parent, Parent, Parachain(2)).into() + ); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(1), PalletInstance(2)]).relative_to(&base), + (Parent, PalletInstance(2)).into() + ); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(1), PalletInstance(1), [1u8; 32].into()]) + .relative_to(&base), + ([1u8; 32],).into() + ); + + // Ancestors with grandchildren. + assert_eq!( + Junctions::from([Polkadot.into(), Parachain(1)]).relative_to(&base), + (Parent, Parent, Parent, Polkadot, Parachain(1)).into() + ); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(2), PalletInstance(1)]).relative_to(&base), + (Parent, Parent, Parachain(2), PalletInstance(1)).into() + ); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(1), PalletInstance(2), [1u8; 32].into()]) + .relative_to(&base), + (Parent, PalletInstance(2), [1u8; 32]).into() + ); + assert_eq!( + Junctions::from([ + Kusama.into(), + Parachain(1), + PalletInstance(1), + [1u8; 32].into(), + 1u128.into() + ]) + .relative_to(&base), + ([1u8; 32], 1u128).into() + ); + } + + #[test] + fn global_consensus_works() { + use NetworkId::*; + assert_eq!(Junctions::from([Polkadot.into()]).global_consensus(), Ok(Polkadot)); + assert_eq!(Junctions::from([Kusama.into(), 1u64.into()]).global_consensus(), Ok(Kusama)); + assert_eq!(Here.global_consensus(), Err(())); + assert_eq!(Junctions::from([1u64.into()]).global_consensus(), Err(())); + assert_eq!(Junctions::from([1u64.into(), Kusama.into()]).global_consensus(), Err(())); + } + + #[test] + fn test_conversion() { + use super::{Junction::*, NetworkId::*}; + let x: Junctions = GlobalConsensus(Polkadot).into(); + assert_eq!(x, Junctions::from([GlobalConsensus(Polkadot)])); + let x: Junctions = Polkadot.into(); + assert_eq!(x, Junctions::from([GlobalConsensus(Polkadot)])); + let x: Junctions = (Polkadot, Kusama).into(); + assert_eq!(x, Junctions::from([GlobalConsensus(Polkadot), GlobalConsensus(Kusama)])); + } + + #[test] + fn encode_decode_junctions_works() { + let original = Junctions::from([ + Polkadot.into(), + Kusama.into(), + 1u64.into(), + GlobalConsensus(Polkadot), + Parachain(123), + PalletInstance(45), + ]); + let encoded = original.encode(); + assert_eq!(encoded, &[6, 9, 2, 9, 3, 2, 0, 4, 9, 2, 0, 237, 1, 4, 45]); + let decoded = Junctions::decode(&mut &encoded[..]).unwrap(); + assert_eq!(decoded, original); + } +} diff --git a/polkadot/xcm/src/v4/location.rs b/polkadot/xcm/src/v4/location.rs new file mode 100644 index 00000000000..db55c3d3034 --- /dev/null +++ b/polkadot/xcm/src/v4/location.rs @@ -0,0 +1,746 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! XCM `Location` datatype. + +use super::{traits::Reanchorable, Junction, Junctions}; +use crate::{v3::MultiLocation as OldLocation, VersionedLocation}; +use core::{ + convert::{TryFrom, TryInto}, + result, +}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +/// A relative path between state-bearing consensus systems. +/// +/// A location in a consensus system is defined as an *isolatable state machine* held within global +/// consensus. The location in question need not have a sophisticated consensus algorithm of its +/// own; a single account within Ethereum, for example, could be considered a location. +/// +/// A very-much non-exhaustive list of types of location include: +/// - A (normal, layer-1) block chain, e.g. the Bitcoin mainnet or a parachain. +/// - A layer-0 super-chain, e.g. the Polkadot Relay chain. +/// - A layer-2 smart contract, e.g. an ERC-20 on Ethereum. +/// - A logical functional component of a chain, e.g. a single instance of a pallet on a Frame-based +/// Substrate chain. +/// - An account. +/// +/// A `Location` is a *relative identifier*, meaning that it can only be used to define the +/// relative path between two locations, and cannot generally be used to refer to a location +/// universally. It is comprised of an integer number of parents specifying the number of times to +/// "escape" upwards into the containing consensus system and then a number of *junctions*, each +/// diving down and specifying some interior portion of state (which may be considered a +/// "sub-consensus" system). +/// +/// This specific `Location` implementation uses a `Junctions` datatype which is a Rust `enum` +/// in order to make pattern matching easier. There are occasions where it is important to ensure +/// that a value is strictly an interior location, in those cases, `Junctions` may be used. +/// +/// The `Location` value of `Null` simply refers to the interpreting consensus system. +#[derive( + Clone, + Decode, + Encode, + Eq, + PartialEq, + Ord, + PartialOrd, + Debug, + TypeInfo, + MaxEncodedLen, + serde::Serialize, + serde::Deserialize, +)] +pub struct Location { + /// The number of parent junctions at the beginning of this `Location`. + pub parents: u8, + /// The interior (i.e. non-parent) junctions that this `Location` contains. + pub interior: Junctions, +} + +impl Default for Location { + fn default() -> Self { + Self { parents: 0, interior: Junctions::Here } + } +} + +/// A relative location which is constrained to be an interior location of the context. +/// +/// See also `Location`. +pub type InteriorLocation = Junctions; + +impl Location { + /// Creates a new `Location` with the given number of parents and interior junctions. + pub fn new(parents: u8, interior: impl Into) -> Location { + Location { parents, interior: interior.into() } + } + + /// Consume `self` and return the equivalent `VersionedLocation` value. + pub const fn into_versioned(self) -> VersionedLocation { + VersionedLocation::V4(self) + } + + /// Creates a new `Location` with 0 parents and a `Here` interior. + /// + /// The resulting `Location` can be interpreted as the "current consensus system". + pub const fn here() -> Location { + Location { parents: 0, interior: Junctions::Here } + } + + /// Creates a new `Location` which evaluates to the parent context. + pub const fn parent() -> Location { + Location { parents: 1, interior: Junctions::Here } + } + + /// Creates a new `Location` with `parents` and an empty (`Here`) interior. + pub const fn ancestor(parents: u8) -> Location { + Location { parents, interior: Junctions::Here } + } + + /// Whether the `Location` has no parents and has a `Here` interior. + pub fn is_here(&self) -> bool { + self.parents == 0 && self.interior.len() == 0 + } + + /// Remove the `NetworkId` value in any interior `Junction`s. + pub fn remove_network_id(&mut self) { + self.interior.remove_network_id(); + } + + /// Return a reference to the interior field. + pub fn interior(&self) -> &Junctions { + &self.interior + } + + /// Return a mutable reference to the interior field. + pub fn interior_mut(&mut self) -> &mut Junctions { + &mut self.interior + } + + /// Returns the number of `Parent` junctions at the beginning of `self`. + pub const fn parent_count(&self) -> u8 { + self.parents + } + + /// Returns the parent count and the interior [`Junctions`] as a tuple. + /// + /// To be used when pattern matching, for example: + /// + /// ```rust + /// # use staging_xcm::v4::{Junctions::*, Junction::*, Location}; + /// fn get_parachain_id(loc: &Location) -> Option { + /// match loc.unpack() { + /// (0, [Parachain(id)]) => Some(*id), + /// _ => None + /// } + /// } + /// ``` + pub fn unpack(&self) -> (u8, &[Junction]) { + (self.parents, self.interior.as_slice()) + } + + /// Returns boolean indicating whether `self` contains only the specified amount of + /// parents and no interior junctions. + pub const fn contains_parents_only(&self, count: u8) -> bool { + matches!(self.interior, Junctions::Here) && self.parents == count + } + + /// Returns the number of parents and junctions in `self`. + pub fn len(&self) -> usize { + self.parent_count() as usize + self.interior.len() + } + + /// Returns the first interior junction, or `None` if the location is empty or contains only + /// parents. + pub fn first_interior(&self) -> Option<&Junction> { + self.interior.first() + } + + /// Returns last junction, or `None` if the location is empty or contains only parents. + pub fn last(&self) -> Option<&Junction> { + self.interior.last() + } + + /// Splits off the first interior junction, returning the remaining suffix (first item in tuple) + /// and the first element (second item in tuple) or `None` if it was empty. + pub fn split_first_interior(self) -> (Location, Option) { + let Location { parents, interior: junctions } = self; + let (suffix, first) = junctions.split_first(); + let location = Location { parents, interior: suffix }; + (location, first) + } + + /// Splits off the last interior junction, returning the remaining prefix (first item in tuple) + /// and the last element (second item in tuple) or `None` if it was empty or if `self` only + /// contains parents. + pub fn split_last_interior(self) -> (Location, Option) { + let Location { parents, interior: junctions } = self; + let (prefix, last) = junctions.split_last(); + let location = Location { parents, interior: prefix }; + (location, last) + } + + /// Mutates `self`, suffixing its interior junctions with `new`. Returns `Err` with `new` in + /// case of overflow. + pub fn push_interior(&mut self, new: impl Into) -> result::Result<(), Junction> { + self.interior.push(new) + } + + /// Mutates `self`, prefixing its interior junctions with `new`. Returns `Err` with `new` in + /// case of overflow. + pub fn push_front_interior( + &mut self, + new: impl Into, + ) -> result::Result<(), Junction> { + self.interior.push_front(new) + } + + /// Consumes `self` and returns a `Location` suffixed with `new`, or an `Err` with + /// theoriginal value of `self` in case of overflow. + pub fn pushed_with_interior( + self, + new: impl Into, + ) -> result::Result { + match self.interior.pushed_with(new) { + Ok(i) => Ok(Location { interior: i, parents: self.parents }), + Err((i, j)) => Err((Location { interior: i, parents: self.parents }, j)), + } + } + + /// Consumes `self` and returns a `Location` prefixed with `new`, or an `Err` with the + /// original value of `self` in case of overflow. + pub fn pushed_front_with_interior( + self, + new: impl Into, + ) -> result::Result { + match self.interior.pushed_front_with(new) { + Ok(i) => Ok(Location { interior: i, parents: self.parents }), + Err((i, j)) => Err((Location { interior: i, parents: self.parents }, j)), + } + } + + /// Returns the junction at index `i`, or `None` if the location is a parent or if the location + /// does not contain that many elements. + pub fn at(&self, i: usize) -> Option<&Junction> { + let num_parents = self.parents as usize; + if i < num_parents { + return None + } + self.interior.at(i - num_parents) + } + + /// Returns a mutable reference to the junction at index `i`, or `None` if the location is a + /// parent or if it doesn't contain that many elements. + pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> { + let num_parents = self.parents as usize; + if i < num_parents { + return None + } + self.interior.at_mut(i - num_parents) + } + + /// Decrements the parent count by 1. + pub fn dec_parent(&mut self) { + self.parents = self.parents.saturating_sub(1); + } + + /// Removes the first interior junction from `self`, returning it + /// (or `None` if it was empty or if `self` contains only parents). + pub fn take_first_interior(&mut self) -> Option { + self.interior.take_first() + } + + /// Removes the last element from `interior`, returning it (or `None` if it was empty or if + /// `self` only contains parents). + pub fn take_last(&mut self) -> Option { + self.interior.take_last() + } + + /// Ensures that `self` has the same number of parents as `prefix`, its junctions begins with + /// the junctions of `prefix` and that it has a single `Junction` item following. + /// If so, returns a reference to this `Junction` item. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions::*, Junction::*, Location}; + /// # fn main() { + /// let mut m = Location::new(1, [PalletInstance(3), OnlyChild]); + /// assert_eq!( + /// m.match_and_split(&Location::new(1, [PalletInstance(3)])), + /// Some(&OnlyChild), + /// ); + /// assert_eq!(m.match_and_split(&Location::new(1, Here)), None); + /// # } + /// ``` + pub fn match_and_split(&self, prefix: &Location) -> Option<&Junction> { + if self.parents != prefix.parents { + return None + } + self.interior.match_and_split(&prefix.interior) + } + + pub fn starts_with(&self, prefix: &Location) -> bool { + self.parents == prefix.parents && self.interior.starts_with(&prefix.interior) + } + + /// Mutate `self` so that it is suffixed with `suffix`. + /// + /// Does not modify `self` and returns `Err` with `suffix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions::*, Junction::*, Location, Parent}; + /// # fn main() { + /// let mut m: Location = (Parent, Parachain(21), 69u64).into(); + /// assert_eq!(m.append_with((Parent, PalletInstance(3))), Ok(())); + /// assert_eq!(m, Location::new(1, [Parachain(21), PalletInstance(3)])); + /// # } + /// ``` + pub fn append_with(&mut self, suffix: impl Into) -> Result<(), Self> { + let prefix = core::mem::replace(self, suffix.into()); + match self.prepend_with(prefix) { + Ok(()) => Ok(()), + Err(prefix) => Err(core::mem::replace(self, prefix)), + } + } + + /// Consume `self` and return its value suffixed with `suffix`. + /// + /// Returns `Err` with the original value of `self` and `suffix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions::*, Junction::*, Location, Parent}; + /// # fn main() { + /// let mut m: Location = (Parent, Parachain(21), 69u64).into(); + /// let r = m.appended_with((Parent, PalletInstance(3))).unwrap(); + /// assert_eq!(r, Location::new(1, [Parachain(21), PalletInstance(3)])); + /// # } + /// ``` + pub fn appended_with(mut self, suffix: impl Into) -> Result { + match self.append_with(suffix) { + Ok(()) => Ok(self), + Err(suffix) => Err((self, suffix)), + } + } + + /// Mutate `self` so that it is prefixed with `prefix`. + /// + /// Does not modify `self` and returns `Err` with `prefix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions::*, Junction::*, Location, Parent}; + /// # fn main() { + /// let mut m: Location = (Parent, Parent, PalletInstance(3)).into(); + /// assert_eq!(m.prepend_with((Parent, Parachain(21), OnlyChild)), Ok(())); + /// assert_eq!(m, Location::new(1, [PalletInstance(3)])); + /// # } + /// ``` + pub fn prepend_with(&mut self, prefix: impl Into) -> Result<(), Self> { + // prefix self (suffix) + // P .. P I .. I p .. p i .. i + let mut prefix = prefix.into(); + let prepend_interior = prefix.interior.len().saturating_sub(self.parents as usize); + let final_interior = self.interior.len().saturating_add(prepend_interior); + if final_interior > super::junctions::MAX_JUNCTIONS { + return Err(prefix) + } + let suffix_parents = (self.parents as usize).saturating_sub(prefix.interior.len()); + let final_parents = (prefix.parents as usize).saturating_add(suffix_parents); + if final_parents > 255 { + return Err(prefix) + } + + // cancel out the final item on the prefix interior for one of the suffix's parents. + while self.parents > 0 && prefix.take_last().is_some() { + self.dec_parent(); + } + + // now we have either removed all suffix's parents or prefix interior. + // this means we can combine the prefix's and suffix's remaining parents/interior since + // we know that with at least one empty, the overall order will be respected: + // prefix self (suffix) + // P .. P (I) p .. p i .. i => P + p .. (no I) i + // -- or -- + // P .. P I .. I (p) i .. i => P (no p) .. I + i + + self.parents = self.parents.saturating_add(prefix.parents); + for j in prefix.interior.into_iter().rev() { + self.push_front_interior(j) + .expect("final_interior no greater than MAX_JUNCTIONS; qed"); + } + Ok(()) + } + + /// Consume `self` and return its value prefixed with `prefix`. + /// + /// Returns `Err` with the original value of `self` and `prefix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions::*, Junction::*, Location, Parent}; + /// # fn main() { + /// let m: Location = (Parent, Parent, PalletInstance(3)).into(); + /// let r = m.prepended_with((Parent, Parachain(21), OnlyChild)).unwrap(); + /// assert_eq!(r, Location::new(1, [PalletInstance(3)])); + /// # } + /// ``` + pub fn prepended_with(mut self, prefix: impl Into) -> Result { + match self.prepend_with(prefix) { + Ok(()) => Ok(self), + Err(prefix) => Err((self, prefix)), + } + } + + /// Remove any unneeded parents/junctions in `self` based on the given context it will be + /// interpreted in. + pub fn simplify(&mut self, context: &Junctions) { + if context.len() < self.parents as usize { + // Not enough context + return + } + while self.parents > 0 { + let maybe = context.at(context.len() - (self.parents as usize)); + match (self.interior.first(), maybe) { + (Some(i), Some(j)) if i == j => { + self.interior.take_first(); + self.parents -= 1; + }, + _ => break, + } + } + } + + /// Return the Location subsection identifying the chain that `self` points to. + pub fn chain_location(&self) -> Location { + let mut clone = self.clone(); + // start popping junctions until we reach chain identifier + while let Some(j) = clone.last() { + if matches!(j, Junction::Parachain(_) | Junction::GlobalConsensus(_)) { + // return chain subsection + return clone + } else { + (clone, _) = clone.split_last_interior(); + } + } + Location::new(clone.parents, Junctions::Here) + } +} + +impl Reanchorable for Location { + type Error = Self; + + /// Mutate `self` so that it represents the same location from the point of view of `target`. + /// The context of `self` is provided as `context`. + /// + /// Does not modify `self` in case of overflow. + fn reanchor(&mut self, target: &Location, context: &InteriorLocation) -> Result<(), ()> { + // TODO: https://github.com/paritytech/polkadot/issues/4489 Optimize this. + + // 1. Use our `context` to figure out how the `target` would address us. + let inverted_target = context.invert_target(target)?; + + // 2. Prepend `inverted_target` to `self` to get self's location from the perspective of + // `target`. + self.prepend_with(inverted_target).map_err(|_| ())?; + + // 3. Given that we know some of `target` context, ensure that any parents in `self` are + // strictly needed. + self.simplify(target.interior()); + + Ok(()) + } + + /// Consume `self` and return a new value representing the same location from the point of view + /// of `target`. The context of `self` is provided as `context`. + /// + /// Returns the original `self` in case of overflow. + fn reanchored(mut self, target: &Location, context: &InteriorLocation) -> Result { + match self.reanchor(target, context) { + Ok(()) => Ok(self), + Err(()) => Err(self), + } + } +} + +impl TryFrom for Option { + type Error = (); + fn try_from(value: OldLocation) -> result::Result { + Ok(Some(Location::try_from(value)?)) + } +} + +impl TryFrom for Location { + type Error = (); + fn try_from(x: OldLocation) -> result::Result { + Ok(Location { parents: x.parents, interior: x.interior.try_into()? }) + } +} + +/// A unit struct which can be converted into a `Location` of `parents` value 1. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct Parent; +impl From for Location { + fn from(_: Parent) -> Self { + Location { parents: 1, interior: Junctions::Here } + } +} + +/// A tuple struct which can be converted into a `Location` of `parents` value 1 with the inner +/// interior. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct ParentThen(pub Junctions); +impl From for Location { + fn from(ParentThen(interior): ParentThen) -> Self { + Location { parents: 1, interior } + } +} + +/// A unit struct which can be converted into a `Location` of the inner `parents` value. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct Ancestor(pub u8); +impl From for Location { + fn from(Ancestor(parents): Ancestor) -> Self { + Location { parents, interior: Junctions::Here } + } +} + +/// A unit struct which can be converted into a `Location` of the inner `parents` value and the +/// inner interior. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct AncestorThen(pub u8, pub Interior); +impl> From> for Location { + fn from(AncestorThen(parents, interior): AncestorThen) -> Self { + Location { parents, interior: interior.into() } + } +} + +xcm_procedural::impl_conversion_functions_for_location_v4!(); + +#[cfg(test)] +mod tests { + use crate::v4::prelude::*; + use parity_scale_codec::{Decode, Encode}; + + #[test] + fn conversion_works() { + let x: Location = Parent.into(); + assert_eq!(x, Location { parents: 1, interior: Here }); + // let x: Location = (Parent,).into(); + // assert_eq!(x, Location { parents: 1, interior: Here }); + // let x: Location = (Parent, Parent).into(); + // assert_eq!(x, Location { parents: 2, interior: Here }); + let x: Location = (Parent, Parent, OnlyChild).into(); + assert_eq!(x, Location { parents: 2, interior: OnlyChild.into() }); + let x: Location = OnlyChild.into(); + assert_eq!(x, Location { parents: 0, interior: OnlyChild.into() }); + let x: Location = (OnlyChild,).into(); + assert_eq!(x, Location { parents: 0, interior: OnlyChild.into() }); + } + + #[test] + fn simplify_basic_works() { + let mut location: Location = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = [Parachain(1000), PalletInstance(42)].into(); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: Location = (Parent, PalletInstance(42), GeneralIndex(69)).into(); + let context = [PalletInstance(42)].into(); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: Location = (Parent, PalletInstance(42), GeneralIndex(69)).into(); + let context = [Parachain(1000), PalletInstance(42)].into(); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: Location = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = [OnlyChild, Parachain(1000), PalletInstance(42)].into(); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + } + + #[test] + fn simplify_incompatible_location_fails() { + let mut location: Location = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = [Parachain(1000), PalletInstance(42), GeneralIndex(42)].into(); + let expected = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: Location = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = [Parachain(1000)].into(); + let expected = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + location.simplify(&context); + assert_eq!(location, expected); + } + + #[test] + fn reanchor_works() { + let mut id: Location = (Parent, Parachain(1000), GeneralIndex(42)).into(); + let context = Parachain(2000).into(); + let target = (Parent, Parachain(1000)).into(); + let expected = GeneralIndex(42).into(); + id.reanchor(&target, &context).unwrap(); + assert_eq!(id, expected); + } + + #[test] + fn encode_and_decode_works() { + let m = Location { + parents: 1, + interior: [Parachain(42), AccountIndex64 { network: None, index: 23 }].into(), + }; + let encoded = m.encode(); + assert_eq!(encoded, [1, 2, 0, 168, 2, 0, 92].to_vec()); + let decoded = Location::decode(&mut &encoded[..]); + assert_eq!(decoded, Ok(m)); + } + + #[test] + fn match_and_split_works() { + let m = Location { + parents: 1, + interior: [Parachain(42), AccountIndex64 { network: None, index: 23 }].into(), + }; + assert_eq!(m.match_and_split(&Location { parents: 1, interior: Here }), None); + assert_eq!( + m.match_and_split(&Location { parents: 1, interior: [Parachain(42)].into() }), + Some(&AccountIndex64 { network: None, index: 23 }) + ); + assert_eq!(m.match_and_split(&m), None); + } + + #[test] + fn append_with_works() { + let acc = AccountIndex64 { network: None, index: 23 }; + let mut m = Location { parents: 1, interior: [Parachain(42)].into() }; + assert_eq!(m.append_with([PalletInstance(3), acc]), Ok(())); + assert_eq!( + m, + Location { parents: 1, interior: [Parachain(42), PalletInstance(3), acc].into() } + ); + + // cannot append to create overly long location + let acc = AccountIndex64 { network: None, index: 23 }; + let m = Location { + parents: 254, + interior: [Parachain(42), OnlyChild, OnlyChild, OnlyChild, OnlyChild].into(), + }; + let suffix: Location = (PalletInstance(3), acc, OnlyChild, OnlyChild).into(); + assert_eq!(m.clone().append_with(suffix.clone()), Err(suffix)); + } + + #[test] + fn prepend_with_works() { + let mut m = Location { + parents: 1, + interior: [Parachain(42), AccountIndex64 { network: None, index: 23 }].into(), + }; + assert_eq!(m.prepend_with(Location { parents: 1, interior: [OnlyChild].into() }), Ok(())); + assert_eq!( + m, + Location { + parents: 1, + interior: [Parachain(42), AccountIndex64 { network: None, index: 23 }].into() + } + ); + + // cannot prepend to create overly long location + let mut m = Location { parents: 254, interior: [Parachain(42)].into() }; + let prefix = Location { parents: 2, interior: Here }; + assert_eq!(m.prepend_with(prefix.clone()), Err(prefix)); + + let prefix = Location { parents: 1, interior: Here }; + assert_eq!(m.prepend_with(prefix.clone()), Ok(())); + assert_eq!(m, Location { parents: 255, interior: [Parachain(42)].into() }); + } + + #[test] + fn double_ended_ref_iteration_works() { + let m: Junctions = [Parachain(1000), Parachain(3), PalletInstance(5)].into(); + let mut iter = m.iter(); + + let first = iter.next().unwrap(); + assert_eq!(first, &Parachain(1000)); + let third = iter.next_back().unwrap(); + assert_eq!(third, &PalletInstance(5)); + let second = iter.next_back().unwrap(); + assert_eq!(iter.next(), None); + assert_eq!(iter.next_back(), None); + assert_eq!(second, &Parachain(3)); + + let res = Here + .pushed_with(*first) + .unwrap() + .pushed_with(*second) + .unwrap() + .pushed_with(*third) + .unwrap(); + assert_eq!(m, res); + + // make sure there's no funny business with the 0 indexing + let m = Here; + let mut iter = m.iter(); + + assert_eq!(iter.next(), None); + assert_eq!(iter.next_back(), None); + } + + #[test] + fn conversion_from_other_types_works() { + use crate::v3; + use core::convert::TryInto; + + fn takes_location>(_arg: Arg) {} + + takes_location(Parent); + takes_location(Here); + takes_location([Parachain(42)]); + takes_location((Ancestor(255), PalletInstance(8))); + takes_location((Ancestor(5), Parachain(1), PalletInstance(3))); + takes_location((Ancestor(2), Here)); + takes_location(AncestorThen( + 3, + [Parachain(43), AccountIndex64 { network: None, index: 155 }], + )); + takes_location((Parent, AccountId32 { network: None, id: [0; 32] })); + takes_location((Parent, Here)); + takes_location(ParentThen([Parachain(75)].into())); + takes_location([Parachain(100), PalletInstance(3)]); + + assert_eq!(v3::Location::from(v3::Junctions::Here).try_into(), Ok(Location::here())); + assert_eq!(v3::Location::from(v3::Parent).try_into(), Ok(Location::parent())); + assert_eq!( + v3::Location::from((v3::Parent, v3::Parent, v3::Junction::GeneralIndex(42u128),)) + .try_into(), + Ok(Location { parents: 2, interior: [GeneralIndex(42u128)].into() }), + ); + } +} diff --git a/polkadot/xcm/src/v4/mod.rs b/polkadot/xcm/src/v4/mod.rs new file mode 100644 index 00000000000..3b57ba1b137 --- /dev/null +++ b/polkadot/xcm/src/v4/mod.rs @@ -0,0 +1,1457 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Version 4 of the Cross-Consensus Message format data structures. + +pub use super::v2::GetWeight; +use super::v3::{ + Instruction as OldInstruction, PalletInfo as OldPalletInfo, + QueryResponseInfo as OldQueryResponseInfo, Response as OldResponse, Xcm as OldXcm, +}; +use crate::DoubleEncoded; +use alloc::{vec, vec::Vec}; +use bounded_collections::{parameter_types, BoundedVec}; +use core::{ + convert::{TryFrom, TryInto}, + fmt::Debug, + result, +}; +use derivative::Derivative; +use parity_scale_codec::{self, Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +mod asset; +mod junction; +pub(crate) mod junctions; +mod location; +mod traits; + +pub use asset::{ + Asset, AssetFilter, AssetId, AssetInstance, Assets, Fungibility, WildAsset, WildFungibility, + MAX_ITEMS_IN_ASSETS, +}; +pub use junction::{BodyId, BodyPart, Junction, NetworkId}; +pub use junctions::Junctions; +pub use location::{Ancestor, AncestorThen, InteriorLocation, Location, Parent, ParentThen}; +pub use traits::{ + send_xcm, validate_send, Error, ExecuteXcm, Outcome, PreparedMessage, Reanchorable, Result, + SendError, SendResult, SendXcm, Weight, XcmHash, +}; +// These parts of XCM v3 are unchanged in XCM v4, and are re-imported here. +pub use super::v3::{MaybeErrorCode, OriginKind, WeightLimit}; + +/// This module's XCM version. +pub const VERSION: super::Version = 4; + +/// An identifier for a query. +pub type QueryId = u64; + +#[derive(Derivative, Default, Encode, Decode, TypeInfo)] +#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))] +#[codec(encode_bound())] +#[codec(decode_bound())] +#[scale_info(bounds(), skip_type_params(Call))] +pub struct Xcm(pub Vec>); + +pub const MAX_INSTRUCTIONS_TO_DECODE: u8 = 100; + +impl Xcm { + /// Create an empty instance. + pub fn new() -> Self { + Self(vec![]) + } + + /// Return `true` if no instructions are held in `self`. + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + /// Return the number of instructions held in `self`. + pub fn len(&self) -> usize { + self.0.len() + } + + /// Return a reference to the inner value. + pub fn inner(&self) -> &[Instruction] { + &self.0 + } + + /// Return a mutable reference to the inner value. + pub fn inner_mut(&mut self) -> &mut Vec> { + &mut self.0 + } + + /// Consume and return the inner value. + pub fn into_inner(self) -> Vec> { + self.0 + } + + /// Return an iterator over references to the items. + pub fn iter(&self) -> impl Iterator> { + self.0.iter() + } + + /// Return an iterator over mutable references to the items. + pub fn iter_mut(&mut self) -> impl Iterator> { + self.0.iter_mut() + } + + /// Consume and return an iterator over the items. + pub fn into_iter(self) -> impl Iterator> { + self.0.into_iter() + } + + /// Consume and either return `self` if it contains some instructions, or if it's empty, then + /// instead return the result of `f`. + pub fn or_else(self, f: impl FnOnce() -> Self) -> Self { + if self.0.is_empty() { + f() + } else { + self + } + } + + /// Return the first instruction, if any. + pub fn first(&self) -> Option<&Instruction> { + self.0.first() + } + + /// Return the last instruction, if any. + pub fn last(&self) -> Option<&Instruction> { + self.0.last() + } + + /// Return the only instruction, contained in `Self`, iff only one exists (`None` otherwise). + pub fn only(&self) -> Option<&Instruction> { + if self.0.len() == 1 { + self.0.first() + } else { + None + } + } + + /// Return the only instruction, contained in `Self`, iff only one exists (returns `self` + /// otherwise). + pub fn into_only(mut self) -> core::result::Result, Self> { + if self.0.len() == 1 { + self.0.pop().ok_or(self) + } else { + Err(self) + } + } +} + +impl From>> for Xcm { + fn from(c: Vec>) -> Self { + Self(c) + } +} + +impl From> for Vec> { + fn from(c: Xcm) -> Self { + c.0 + } +} + +/// A prelude for importing all types typically used when interacting with XCM messages. +pub mod prelude { + mod contents { + pub use super::super::{ + send_xcm, validate_send, Ancestor, AncestorThen, Asset, + AssetFilter::{self, *}, + AssetId, + AssetInstance::{self, *}, + Assets, BodyId, BodyPart, Error as XcmError, ExecuteXcm, + Fungibility::{self, *}, + Instruction::*, + InteriorLocation, + Junction::{self, *}, + Junctions::{self, Here}, + Location, MaybeErrorCode, + NetworkId::{self, *}, + OriginKind, Outcome, PalletInfo, Parent, ParentThen, PreparedMessage, QueryId, + QueryResponseInfo, Reanchorable, Response, Result as XcmResult, SendError, SendResult, + SendXcm, Weight, + WeightLimit::{self, *}, + WildAsset::{self, *}, + WildFungibility::{self, Fungible as WildFungible, NonFungible as WildNonFungible}, + XcmContext, XcmHash, XcmWeightInfo, VERSION as XCM_VERSION, + }; + } + pub use super::{Instruction, Xcm}; + pub use contents::*; + pub mod opaque { + pub use super::{ + super::opaque::{Instruction, Xcm}, + contents::*, + }; + } +} + +parameter_types! { + pub MaxPalletNameLen: u32 = 48; + /// Maximum size of the encoded error code coming from a `Dispatch` result, used for + /// `MaybeErrorCode`. This is not (yet) enforced, so it's just an indication of expectation. + pub MaxDispatchErrorLen: u32 = 128; + pub MaxPalletsInfo: u32 = 64; +} + +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] +pub struct PalletInfo { + #[codec(compact)] + index: u32, + name: BoundedVec, + module_name: BoundedVec, + #[codec(compact)] + major: u32, + #[codec(compact)] + minor: u32, + #[codec(compact)] + patch: u32, +} + +impl TryInto for PalletInfo { + type Error = (); + + fn try_into(self) -> result::Result { + OldPalletInfo::new( + self.index, + self.name.into_inner(), + self.module_name.into_inner(), + self.major, + self.minor, + self.patch, + ) + .map_err(|_| ()) + } +} + +impl PalletInfo { + pub fn new( + index: u32, + name: Vec, + module_name: Vec, + major: u32, + minor: u32, + patch: u32, + ) -> result::Result { + let name = BoundedVec::try_from(name).map_err(|_| Error::Overflow)?; + let module_name = BoundedVec::try_from(module_name).map_err(|_| Error::Overflow)?; + + Ok(Self { index, name, module_name, major, minor, patch }) + } +} + +/// Response data to a query. +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] +pub enum Response { + /// No response. Serves as a neutral default. + Null, + /// Some assets. + Assets(Assets), + /// The outcome of an XCM instruction. + ExecutionResult(Option<(u32, Error)>), + /// An XCM version. + Version(super::Version), + /// The index, instance name, pallet name and version of some pallets. + PalletsInfo(BoundedVec), + /// The status of a dispatch attempt using `Transact`. + DispatchResult(MaybeErrorCode), +} + +impl Default for Response { + fn default() -> Self { + Self::Null + } +} + +impl TryFrom for Response { + type Error = (); + + fn try_from(old: OldResponse) -> result::Result { + use OldResponse::*; + Ok(match old { + Null => Self::Null, + Assets(assets) => Self::Assets(assets.try_into()?), + ExecutionResult(result) => + Self::ExecutionResult(result.map(|(num, old_error)| (num, old_error.into()))), + Version(version) => Self::Version(version), + PalletsInfo(pallet_info) => { + let inner = pallet_info + .into_iter() + .map(TryInto::try_into) + .collect::, _>>()?; + Self::PalletsInfo( + BoundedVec::::try_from(inner).map_err(|_| ())?, + ) + }, + DispatchResult(maybe_error) => Self::DispatchResult(maybe_error), + }) + } +} + +/// Information regarding the composition of a query response. +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)] +pub struct QueryResponseInfo { + /// The destination to which the query response message should be send. + pub destination: Location, + /// The `query_id` field of the `QueryResponse` message. + #[codec(compact)] + pub query_id: QueryId, + /// The `max_weight` field of the `QueryResponse` message. + pub max_weight: Weight, +} + +impl TryFrom for QueryResponseInfo { + type Error = (); + + fn try_from(old: OldQueryResponseInfo) -> result::Result { + Ok(Self { + destination: old.destination.try_into()?, + query_id: old.query_id, + max_weight: old.max_weight, + }) + } +} + +/// Contextual data pertaining to a specific list of XCM instructions. +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] +pub struct XcmContext { + /// The current value of the Origin register of the `XCVM`. + pub origin: Option, + /// The identity of the XCM; this may be a hash of its versioned encoding but could also be + /// a high-level identity set by an appropriate barrier. + pub message_id: XcmHash, + /// The current value of the Topic register of the `XCVM`. + pub topic: Option<[u8; 32]>, +} + +impl XcmContext { + /// Constructor which sets the message ID to the supplied parameter and leaves the origin and + /// topic unset. + pub fn with_message_id(message_id: XcmHash) -> XcmContext { + XcmContext { origin: None, message_id, topic: None } + } +} + +/// Cross-Consensus Message: A message from one consensus system to another. +/// +/// Consensus systems that may send and receive messages include blockchains and smart contracts. +/// +/// All messages are delivered from a known *origin*, expressed as a `Location`. +/// +/// This is the inner XCM format and is version-sensitive. Messages are typically passed using the +/// outer XCM format, known as `VersionedXcm`. +#[derive( + Derivative, + Encode, + Decode, + TypeInfo, + xcm_procedural::XcmWeightInfoTrait, + xcm_procedural::Builder, +)] +#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))] +#[codec(encode_bound())] +#[codec(decode_bound())] +#[scale_info(bounds(), skip_type_params(Call))] +pub enum Instruction { + /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place them into the Holding + /// Register. + /// + /// - `assets`: The asset(s) to be withdrawn into holding. + /// + /// Kind: *Command*. + /// + /// Errors: + #[builder(loads_holding)] + WithdrawAsset(Assets), + + /// Asset(s) (`assets`) have been received into the ownership of this system on the `origin` + /// system and equivalent derivatives should be placed into the Holding Register. + /// + /// - `assets`: The asset(s) that are minted into holding. + /// + /// Safety: `origin` must be trusted to have received and be storing `assets` such that they + /// may later be withdrawn should this system send a corresponding message. + /// + /// Kind: *Trusted Indication*. + /// + /// Errors: + #[builder(loads_holding)] + ReserveAssetDeposited(Assets), + + /// Asset(s) (`assets`) have been destroyed on the `origin` system and equivalent assets should + /// be created and placed into the Holding Register. + /// + /// - `assets`: The asset(s) that are minted into the Holding Register. + /// + /// Safety: `origin` must be trusted to have irrevocably destroyed the corresponding `assets` + /// prior as a consequence of sending this message. + /// + /// Kind: *Trusted Indication*. + /// + /// Errors: + #[builder(loads_holding)] + ReceiveTeleportedAsset(Assets), + + /// Respond with information that the local system is expecting. + /// + /// - `query_id`: The identifier of the query that resulted in this message being sent. + /// - `response`: The message content. + /// - `max_weight`: The maximum weight that handling this response should take. + /// - `querier`: The location responsible for the initiation of the response, if there is one. + /// In general this will tend to be the same location as the receiver of this message. NOTE: + /// As usual, this is interpreted from the perspective of the receiving consensus system. + /// + /// Safety: Since this is information only, there are no immediate concerns. However, it should + /// be remembered that even if the Origin behaves reasonably, it can always be asked to make + /// a response to a third-party chain who may or may not be expecting the response. Therefore + /// the `querier` should be checked to match the expected value. + /// + /// Kind: *Information*. + /// + /// Errors: + QueryResponse { + #[codec(compact)] + query_id: QueryId, + response: Response, + max_weight: Weight, + querier: Option, + }, + + /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets + /// under the ownership of `beneficiary`. + /// + /// - `assets`: The asset(s) to be withdrawn. + /// - `beneficiary`: The new owner for the assets. + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + TransferAsset { assets: Assets, beneficiary: Location }, + + /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets + /// under the ownership of `dest` within this consensus system (i.e. its sovereign account). + /// + /// Send an onward XCM message to `dest` of `ReserveAssetDeposited` with the given + /// `xcm`. + /// + /// - `assets`: The asset(s) to be withdrawn. + /// - `dest`: The location whose sovereign account will own the assets and thus the effective + /// beneficiary for the assets and the notification target for the reserve asset deposit + /// message. + /// - `xcm`: The instructions that should follow the `ReserveAssetDeposited` instruction, which + /// is sent onwards to `dest`. + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + TransferReserveAsset { assets: Assets, dest: Location, xcm: Xcm<()> }, + + /// Apply the encoded transaction `call`, whose dispatch-origin should be `origin` as expressed + /// by the kind of origin `origin_kind`. + /// + /// The Transact Status Register is set according to the result of dispatching the call. + /// + /// - `origin_kind`: The means of expressing the message origin as a dispatch origin. + /// - `require_weight_at_most`: The weight of `call`; this should be at least the chain's + /// calculated weight and will be used in the weight determination arithmetic. + /// - `call`: The encoded transaction to be applied. + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + Transact { origin_kind: OriginKind, require_weight_at_most: Weight, call: DoubleEncoded }, + + /// A message to notify about a new incoming HRMP channel. This message is meant to be sent by + /// the relay-chain to a para. + /// + /// - `sender`: The sender in the to-be opened channel. Also, the initiator of the channel + /// opening. + /// - `max_message_size`: The maximum size of a message proposed by the sender. + /// - `max_capacity`: The maximum number of messages that can be queued in the channel. + /// + /// Safety: The message should originate directly from the relay-chain. + /// + /// Kind: *System Notification* + HrmpNewChannelOpenRequest { + #[codec(compact)] + sender: u32, + #[codec(compact)] + max_message_size: u32, + #[codec(compact)] + max_capacity: u32, + }, + + /// A message to notify about that a previously sent open channel request has been accepted by + /// the recipient. That means that the channel will be opened during the next relay-chain + /// session change. This message is meant to be sent by the relay-chain to a para. + /// + /// Safety: The message should originate directly from the relay-chain. + /// + /// Kind: *System Notification* + /// + /// Errors: + HrmpChannelAccepted { + // NOTE: We keep this as a structured item to a) keep it consistent with the other Hrmp + // items; and b) because the field's meaning is not obvious/mentioned from the item name. + #[codec(compact)] + recipient: u32, + }, + + /// A message to notify that the other party in an open channel decided to close it. In + /// particular, `initiator` is going to close the channel opened from `sender` to the + /// `recipient`. The close will be enacted at the next relay-chain session change. This message + /// is meant to be sent by the relay-chain to a para. + /// + /// Safety: The message should originate directly from the relay-chain. + /// + /// Kind: *System Notification* + /// + /// Errors: + HrmpChannelClosing { + #[codec(compact)] + initiator: u32, + #[codec(compact)] + sender: u32, + #[codec(compact)] + recipient: u32, + }, + + /// Clear the origin. + /// + /// This may be used by the XCM author to ensure that later instructions cannot command the + /// authority of the origin (e.g. if they are being relayed from an untrusted source, as often + /// the case with `ReserveAssetDeposited`). + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + ClearOrigin, + + /// Mutate the origin to some interior location. + /// + /// Kind: *Command* + /// + /// Errors: + DescendOrigin(InteriorLocation), + + /// Immediately report the contents of the Error Register to the given destination via XCM. + /// + /// A `QueryResponse` message of type `ExecutionOutcome` is sent to the described destination. + /// + /// - `response_info`: Information for making the response. + /// + /// Kind: *Command* + /// + /// Errors: + ReportError(QueryResponseInfo), + + /// Remove the asset(s) (`assets`) from the Holding Register and place equivalent assets under + /// the ownership of `beneficiary` within this consensus system. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `beneficiary`: The new owner for the assets. + /// + /// Kind: *Command* + /// + /// Errors: + DepositAsset { assets: AssetFilter, beneficiary: Location }, + + /// Remove the asset(s) (`assets`) from the Holding Register and place equivalent assets under + /// the ownership of `dest` within this consensus system (i.e. deposit them into its sovereign + /// account). + /// + /// Send an onward XCM message to `dest` of `ReserveAssetDeposited` with the given `effects`. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `dest`: The location whose sovereign account will own the assets and thus the effective + /// beneficiary for the assets and the notification target for the reserve asset deposit + /// message. + /// - `xcm`: The orders that should follow the `ReserveAssetDeposited` instruction which is + /// sent onwards to `dest`. + /// + /// Kind: *Command* + /// + /// Errors: + DepositReserveAsset { assets: AssetFilter, dest: Location, xcm: Xcm<()> }, + + /// Remove the asset(s) (`want`) from the Holding Register and replace them with alternative + /// assets. + /// + /// The minimum amount of assets to be received into the Holding Register for the order not to + /// fail may be stated. + /// + /// - `give`: The maximum amount of assets to remove from holding. + /// - `want`: The minimum amount of assets which `give` should be exchanged for. + /// - `maximal`: If `true`, then prefer to give as much as possible up to the limit of `give` + /// and receive accordingly more. If `false`, then prefer to give as little as possible in + /// order to receive as little as possible while receiving at least `want`. + /// + /// Kind: *Command* + /// + /// Errors: + ExchangeAsset { give: AssetFilter, want: Assets, maximal: bool }, + + /// Remove the asset(s) (`assets`) from holding and send a `WithdrawAsset` XCM message to a + /// reserve location. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `reserve`: A valid location that acts as a reserve for all asset(s) in `assets`. The + /// sovereign account of this consensus system *on the reserve location* will have + /// appropriate assets withdrawn and `effects` will be executed on them. There will typically + /// be only one valid location on any given asset/chain combination. + /// - `xcm`: The instructions to execute on the assets once withdrawn *on the reserve + /// location*. + /// + /// Kind: *Command* + /// + /// Errors: + InitiateReserveWithdraw { assets: AssetFilter, reserve: Location, xcm: Xcm<()> }, + + /// Remove the asset(s) (`assets`) from holding and send a `ReceiveTeleportedAsset` XCM message + /// to a `dest` location. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `dest`: A valid location that respects teleports coming from this location. + /// - `xcm`: The instructions to execute on the assets once arrived *on the destination + /// location*. + /// + /// NOTE: The `dest` location *MUST* respect this origin as a valid teleportation origin for + /// all `assets`. If it does not, then the assets may be lost. + /// + /// Kind: *Command* + /// + /// Errors: + InitiateTeleport { assets: AssetFilter, dest: Location, xcm: Xcm<()> }, + + /// Report to a given destination the contents of the Holding Register. + /// + /// A `QueryResponse` message of type `Assets` is sent to the described destination. + /// + /// - `response_info`: Information for making the response. + /// - `assets`: A filter for the assets that should be reported back. The assets reported back + /// will be, asset-wise, *the lesser of this value and the holding register*. No wildcards + /// will be used when reporting assets back. + /// + /// Kind: *Command* + /// + /// Errors: + ReportHolding { response_info: QueryResponseInfo, assets: AssetFilter }, + + /// Pay for the execution of some XCM `xcm` and `orders` with up to `weight` + /// picoseconds of execution time, paying for this with up to `fees` from the Holding Register. + /// + /// - `fees`: The asset(s) to remove from the Holding Register to pay for fees. + /// - `weight_limit`: The maximum amount of weight to purchase; this must be at least the + /// expected maximum weight of the total XCM to be executed for the + /// `AllowTopLevelPaidExecutionFrom` barrier to allow the XCM be executed. + /// + /// Kind: *Command* + /// + /// Errors: + BuyExecution { fees: Asset, weight_limit: WeightLimit }, + + /// Refund any surplus weight previously bought with `BuyExecution`. + /// + /// Kind: *Command* + /// + /// Errors: None. + RefundSurplus, + + /// Set the Error Handler Register. This is code that should be called in the case of an error + /// happening. + /// + /// An error occurring within execution of this code will _NOT_ result in the error register + /// being set, nor will an error handler be called due to it. The error handler and appendix + /// may each still be set. + /// + /// The apparent weight of this instruction is inclusive of the inner `Xcm`; the executing + /// weight however includes only the difference between the previous handler and the new + /// handler, which can reasonably be negative, which would result in a surplus. + /// + /// Kind: *Command* + /// + /// Errors: None. + SetErrorHandler(Xcm), + + /// Set the Appendix Register. This is code that should be called after code execution + /// (including the error handler if any) is finished. This will be called regardless of whether + /// an error occurred. + /// + /// Any error occurring due to execution of this code will result in the error register being + /// set, and the error handler (if set) firing. + /// + /// The apparent weight of this instruction is inclusive of the inner `Xcm`; the executing + /// weight however includes only the difference between the previous appendix and the new + /// appendix, which can reasonably be negative, which would result in a surplus. + /// + /// Kind: *Command* + /// + /// Errors: None. + SetAppendix(Xcm), + + /// Clear the Error Register. + /// + /// Kind: *Command* + /// + /// Errors: None. + ClearError, + + /// Create some assets which are being held on behalf of the origin. + /// + /// - `assets`: The assets which are to be claimed. This must match exactly with the assets + /// claimable by the origin of the ticket. + /// - `ticket`: The ticket of the asset; this is an abstract identifier to help locate the + /// asset. + /// + /// Kind: *Command* + /// + /// Errors: + #[builder(loads_holding)] + ClaimAsset { assets: Assets, ticket: Location }, + + /// Always throws an error of type `Trap`. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `Trap`: All circumstances, whose inner value is the same as this item's inner value. + Trap(#[codec(compact)] u64), + + /// Ask the destination system to respond with the most recent version of XCM that they + /// support in a `QueryResponse` instruction. Any changes to this should also elicit similar + /// responses when they happen. + /// + /// - `query_id`: An identifier that will be replicated into the returned XCM message. + /// - `max_response_weight`: The maximum amount of weight that the `QueryResponse` item which + /// is sent as a reply may take to execute. NOTE: If this is unexpectedly large then the + /// response may not execute at all. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible* + SubscribeVersion { + #[codec(compact)] + query_id: QueryId, + max_response_weight: Weight, + }, + + /// Cancel the effect of a previous `SubscribeVersion` instruction. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible* + UnsubscribeVersion, + + /// Reduce Holding by up to the given assets. + /// + /// Holding is reduced by as much as possible up to the assets in the parameter. It is not an + /// error if the Holding does not contain the assets (to make this an error, use `ExpectAsset` + /// prior). + /// + /// Kind: *Command* + /// + /// Errors: *Infallible* + BurnAsset(Assets), + + /// Throw an error if Holding does not contain at least the given assets. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: If Holding Register does not contain the assets in the parameter. + ExpectAsset(Assets), + + /// Ensure that the Origin Register equals some given value and throw an error if not. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: If Origin Register is not equal to the parameter. + ExpectOrigin(Option), + + /// Ensure that the Error Register equals some given value and throw an error if not. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: If the value of the Error Register is not equal to the parameter. + ExpectError(Option<(u32, Error)>), + + /// Ensure that the Transact Status Register equals some given value and throw an error if + /// not. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: If the value of the Transact Status Register is not equal to the + /// parameter. + ExpectTransactStatus(MaybeErrorCode), + + /// Query the existence of a particular pallet type. + /// + /// - `module_name`: The module name of the pallet to query. + /// - `response_info`: Information for making the response. + /// + /// Sends a `QueryResponse` to Origin whose data field `PalletsInfo` containing the information + /// of all pallets on the local chain whose name is equal to `name`. This is empty in the case + /// that the local chain is not based on Substrate Frame. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible*. + QueryPallet { module_name: Vec, response_info: QueryResponseInfo }, + + /// Ensure that a particular pallet with a particular version exists. + /// + /// - `index: Compact`: The index which identifies the pallet. An error if no pallet exists at + /// this index. + /// - `name: Vec`: Name which must be equal to the name of the pallet. + /// - `module_name: Vec`: Module name which must be equal to the name of the module in + /// which the pallet exists. + /// - `crate_major: Compact`: Version number which must be equal to the major version of the + /// crate which implements the pallet. + /// - `min_crate_minor: Compact`: Version number which must be at most the minor version of the + /// crate which implements the pallet. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: In case any of the expectations are broken. + ExpectPallet { + #[codec(compact)] + index: u32, + name: Vec, + module_name: Vec, + #[codec(compact)] + crate_major: u32, + #[codec(compact)] + min_crate_minor: u32, + }, + + /// Send a `QueryResponse` message containing the value of the Transact Status Register to some + /// destination. + /// + /// - `query_response_info`: The information needed for constructing and sending the + /// `QueryResponse` message. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible*. + ReportTransactStatus(QueryResponseInfo), + + /// Set the Transact Status Register to its default, cleared, value. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: *Infallible*. + ClearTransactStatus, + + /// Set the Origin Register to be some child of the Universal Ancestor. + /// + /// Safety: Should only be usable if the Origin is trusted to represent the Universal Ancestor + /// child in general. In general, no Origin should be able to represent the Universal Ancestor + /// child which is the root of the local consensus system since it would by extension + /// allow it to act as any location within the local consensus. + /// + /// The `Junction` parameter should generally be a `GlobalConsensus` variant since it is only + /// these which are children of the Universal Ancestor. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible*. + UniversalOrigin(Junction), + + /// Send a message on to Non-Local Consensus system. + /// + /// This will tend to utilize some extra-consensus mechanism, the obvious one being a bridge. + /// A fee may be charged; this may be determined based on the contents of `xcm`. It will be + /// taken from the Holding register. + /// + /// - `network`: The remote consensus system to which the message should be exported. + /// - `destination`: The location relative to the remote consensus system to which the message + /// should be sent on arrival. + /// - `xcm`: The message to be exported. + /// + /// As an example, to export a message for execution on Statemine (parachain #1000 in the + /// Kusama network), you would call with `network: NetworkId::Kusama` and + /// `destination: [Parachain(1000)].into()`. Alternatively, to export a message for execution + /// on Polkadot, you would call with `network: NetworkId:: Polkadot` and `destination: Here`. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible*. + ExportMessage { network: NetworkId, destination: InteriorLocation, xcm: Xcm<()> }, + + /// Lock the locally held asset and prevent further transfer or withdrawal. + /// + /// This restriction may be removed by the `UnlockAsset` instruction being called with an + /// Origin of `unlocker` and a `target` equal to the current `Origin`. + /// + /// If the locking is successful, then a `NoteUnlockable` instruction is sent to `unlocker`. + /// + /// - `asset`: The asset(s) which should be locked. + /// - `unlocker`: The value which the Origin must be for a corresponding `UnlockAsset` + /// instruction to work. + /// + /// Kind: *Command*. + /// + /// Errors: + LockAsset { asset: Asset, unlocker: Location }, + + /// Remove the lock over `asset` on this chain and (if nothing else is preventing it) allow the + /// asset to be transferred. + /// + /// - `asset`: The asset to be unlocked. + /// - `target`: The owner of the asset on the local chain. + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + UnlockAsset { asset: Asset, target: Location }, + + /// Asset (`asset`) has been locked on the `origin` system and may not be transferred. It may + /// only be unlocked with the receipt of the `UnlockAsset` instruction from this chain. + /// + /// - `asset`: The asset(s) which are now unlockable from this origin. + /// - `owner`: The owner of the asset on the chain in which it was locked. This may be a + /// location specific to the origin network. + /// + /// Safety: `origin` must be trusted to have locked the corresponding `asset` + /// prior as a consequence of sending this message. + /// + /// Kind: *Trusted Indication*. + /// + /// Errors: + NoteUnlockable { asset: Asset, owner: Location }, + + /// Send an `UnlockAsset` instruction to the `locker` for the given `asset`. + /// + /// This may fail if the local system is making use of the fact that the asset is locked or, + /// of course, if there is no record that the asset actually is locked. + /// + /// - `asset`: The asset(s) to be unlocked. + /// - `locker`: The location from which a previous `NoteUnlockable` was sent and to which an + /// `UnlockAsset` should be sent. + /// + /// Kind: *Command*. + /// + /// Errors: + RequestUnlock { asset: Asset, locker: Location }, + + /// Sets the Fees Mode Register. + /// + /// - `jit_withdraw`: The fees mode item; if set to `true` then fees for any instructions are + /// withdrawn as needed using the same mechanism as `WithdrawAssets`. + /// + /// Kind: *Command*. + /// + /// Errors: + SetFeesMode { jit_withdraw: bool }, + + /// Set the Topic Register. + /// + /// The 32-byte array identifier in the parameter is not guaranteed to be + /// unique; if such a property is desired, it is up to the code author to + /// enforce uniqueness. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: + SetTopic([u8; 32]), + + /// Clear the Topic Register. + /// + /// Kind: *Command* + /// + /// Errors: None. + ClearTopic, + + /// Alter the current Origin to another given origin. + /// + /// Kind: *Command* + /// + /// Errors: If the existing state would not allow such a change. + AliasOrigin(Location), + + /// A directive to indicate that the origin expects free execution of the message. + /// + /// At execution time, this instruction just does a check on the Origin register. + /// However, at the barrier stage messages starting with this instruction can be disregarded if + /// the origin is not acceptable for free execution or the `weight_limit` is `Limited` and + /// insufficient. + /// + /// Kind: *Indication* + /// + /// Errors: If the given origin is `Some` and not equal to the current Origin register. + UnpaidExecution { weight_limit: WeightLimit, check_origin: Option }, +} + +impl Xcm { + pub fn into(self) -> Xcm { + Xcm::from(self) + } + pub fn from(xcm: Xcm) -> Self { + Self(xcm.0.into_iter().map(Instruction::::from).collect()) + } +} + +impl Instruction { + pub fn into(self) -> Instruction { + Instruction::from(self) + } + pub fn from(xcm: Instruction) -> Self { + use Instruction::*; + match xcm { + WithdrawAsset(assets) => WithdrawAsset(assets), + ReserveAssetDeposited(assets) => ReserveAssetDeposited(assets), + ReceiveTeleportedAsset(assets) => ReceiveTeleportedAsset(assets), + QueryResponse { query_id, response, max_weight, querier } => + QueryResponse { query_id, response, max_weight, querier }, + TransferAsset { assets, beneficiary } => TransferAsset { assets, beneficiary }, + TransferReserveAsset { assets, dest, xcm } => + TransferReserveAsset { assets, dest, xcm }, + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity }, + HrmpChannelAccepted { recipient } => HrmpChannelAccepted { recipient }, + HrmpChannelClosing { initiator, sender, recipient } => + HrmpChannelClosing { initiator, sender, recipient }, + Transact { origin_kind, require_weight_at_most, call } => + Transact { origin_kind, require_weight_at_most, call: call.into() }, + ReportError(response_info) => ReportError(response_info), + DepositAsset { assets, beneficiary } => DepositAsset { assets, beneficiary }, + DepositReserveAsset { assets, dest, xcm } => DepositReserveAsset { assets, dest, xcm }, + ExchangeAsset { give, want, maximal } => ExchangeAsset { give, want, maximal }, + InitiateReserveWithdraw { assets, reserve, xcm } => + InitiateReserveWithdraw { assets, reserve, xcm }, + InitiateTeleport { assets, dest, xcm } => InitiateTeleport { assets, dest, xcm }, + ReportHolding { response_info, assets } => ReportHolding { response_info, assets }, + BuyExecution { fees, weight_limit } => BuyExecution { fees, weight_limit }, + ClearOrigin => ClearOrigin, + DescendOrigin(who) => DescendOrigin(who), + RefundSurplus => RefundSurplus, + SetErrorHandler(xcm) => SetErrorHandler(xcm.into()), + SetAppendix(xcm) => SetAppendix(xcm.into()), + ClearError => ClearError, + ClaimAsset { assets, ticket } => ClaimAsset { assets, ticket }, + Trap(code) => Trap(code), + SubscribeVersion { query_id, max_response_weight } => + SubscribeVersion { query_id, max_response_weight }, + UnsubscribeVersion => UnsubscribeVersion, + BurnAsset(assets) => BurnAsset(assets), + ExpectAsset(assets) => ExpectAsset(assets), + ExpectOrigin(origin) => ExpectOrigin(origin), + ExpectError(error) => ExpectError(error), + ExpectTransactStatus(transact_status) => ExpectTransactStatus(transact_status), + QueryPallet { module_name, response_info } => + QueryPallet { module_name, response_info }, + ExpectPallet { index, name, module_name, crate_major, min_crate_minor } => + ExpectPallet { index, name, module_name, crate_major, min_crate_minor }, + ReportTransactStatus(response_info) => ReportTransactStatus(response_info), + ClearTransactStatus => ClearTransactStatus, + UniversalOrigin(j) => UniversalOrigin(j), + ExportMessage { network, destination, xcm } => + ExportMessage { network, destination, xcm }, + LockAsset { asset, unlocker } => LockAsset { asset, unlocker }, + UnlockAsset { asset, target } => UnlockAsset { asset, target }, + NoteUnlockable { asset, owner } => NoteUnlockable { asset, owner }, + RequestUnlock { asset, locker } => RequestUnlock { asset, locker }, + SetFeesMode { jit_withdraw } => SetFeesMode { jit_withdraw }, + SetTopic(topic) => SetTopic(topic), + ClearTopic => ClearTopic, + AliasOrigin(location) => AliasOrigin(location), + UnpaidExecution { weight_limit, check_origin } => + UnpaidExecution { weight_limit, check_origin }, + } + } +} + +// TODO: Automate Generation +impl> GetWeight for Instruction { + fn weight(&self) -> Weight { + use Instruction::*; + match self { + WithdrawAsset(assets) => W::withdraw_asset(assets), + ReserveAssetDeposited(assets) => W::reserve_asset_deposited(assets), + ReceiveTeleportedAsset(assets) => W::receive_teleported_asset(assets), + QueryResponse { query_id, response, max_weight, querier } => + W::query_response(query_id, response, max_weight, querier), + TransferAsset { assets, beneficiary } => W::transfer_asset(assets, beneficiary), + TransferReserveAsset { assets, dest, xcm } => + W::transfer_reserve_asset(&assets, dest, xcm), + Transact { origin_kind, require_weight_at_most, call } => + W::transact(origin_kind, require_weight_at_most, call), + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => + W::hrmp_new_channel_open_request(sender, max_message_size, max_capacity), + HrmpChannelAccepted { recipient } => W::hrmp_channel_accepted(recipient), + HrmpChannelClosing { initiator, sender, recipient } => + W::hrmp_channel_closing(initiator, sender, recipient), + ClearOrigin => W::clear_origin(), + DescendOrigin(who) => W::descend_origin(who), + ReportError(response_info) => W::report_error(&response_info), + DepositAsset { assets, beneficiary } => W::deposit_asset(assets, beneficiary), + DepositReserveAsset { assets, dest, xcm } => + W::deposit_reserve_asset(assets, dest, xcm), + ExchangeAsset { give, want, maximal } => W::exchange_asset(give, want, maximal), + InitiateReserveWithdraw { assets, reserve, xcm } => + W::initiate_reserve_withdraw(assets, reserve, xcm), + InitiateTeleport { assets, dest, xcm } => W::initiate_teleport(assets, dest, xcm), + ReportHolding { response_info, assets } => W::report_holding(&response_info, &assets), + BuyExecution { fees, weight_limit } => W::buy_execution(fees, weight_limit), + RefundSurplus => W::refund_surplus(), + SetErrorHandler(xcm) => W::set_error_handler(xcm), + SetAppendix(xcm) => W::set_appendix(xcm), + ClearError => W::clear_error(), + ClaimAsset { assets, ticket } => W::claim_asset(assets, ticket), + Trap(code) => W::trap(code), + SubscribeVersion { query_id, max_response_weight } => + W::subscribe_version(query_id, max_response_weight), + UnsubscribeVersion => W::unsubscribe_version(), + BurnAsset(assets) => W::burn_asset(assets), + ExpectAsset(assets) => W::expect_asset(assets), + ExpectOrigin(origin) => W::expect_origin(origin), + ExpectError(error) => W::expect_error(error), + ExpectTransactStatus(transact_status) => W::expect_transact_status(transact_status), + QueryPallet { module_name, response_info } => + W::query_pallet(module_name, response_info), + ExpectPallet { index, name, module_name, crate_major, min_crate_minor } => + W::expect_pallet(index, name, module_name, crate_major, min_crate_minor), + ReportTransactStatus(response_info) => W::report_transact_status(response_info), + ClearTransactStatus => W::clear_transact_status(), + UniversalOrigin(j) => W::universal_origin(j), + ExportMessage { network, destination, xcm } => + W::export_message(network, destination, xcm), + LockAsset { asset, unlocker } => W::lock_asset(asset, unlocker), + UnlockAsset { asset, target } => W::unlock_asset(asset, target), + NoteUnlockable { asset, owner } => W::note_unlockable(asset, owner), + RequestUnlock { asset, locker } => W::request_unlock(asset, locker), + SetFeesMode { jit_withdraw } => W::set_fees_mode(jit_withdraw), + SetTopic(topic) => W::set_topic(topic), + ClearTopic => W::clear_topic(), + AliasOrigin(location) => W::alias_origin(location), + UnpaidExecution { weight_limit, check_origin } => + W::unpaid_execution(weight_limit, check_origin), + } + } +} + +pub mod opaque { + /// The basic concrete type of `Xcm`, which doesn't make any assumptions about the + /// format of a call other than it is pre-encoded. + pub type Xcm = super::Xcm<()>; + + /// The basic concrete type of `Instruction`, which doesn't make any assumptions about the + /// format of a call other than it is pre-encoded. + pub type Instruction = super::Instruction<()>; +} + +// Convert from a v3 XCM to a v4 XCM +impl TryFrom> for Xcm { + type Error = (); + fn try_from(old_xcm: OldXcm) -> result::Result { + Ok(Xcm(old_xcm.0.into_iter().map(TryInto::try_into).collect::>()?)) + } +} + +// Convert from a v3 instruction to a v4 instruction +impl TryFrom> for Instruction { + type Error = (); + fn try_from(old_instruction: OldInstruction) -> result::Result { + use OldInstruction::*; + Ok(match old_instruction { + WithdrawAsset(assets) => Self::WithdrawAsset(assets.try_into()?), + ReserveAssetDeposited(assets) => Self::ReserveAssetDeposited(assets.try_into()?), + ReceiveTeleportedAsset(assets) => Self::ReceiveTeleportedAsset(assets.try_into()?), + QueryResponse { query_id, response, max_weight, querier: Some(querier) } => + Self::QueryResponse { + query_id, + querier: querier.try_into()?, + response: response.try_into()?, + max_weight, + }, + QueryResponse { query_id, response, max_weight, querier: None } => + Self::QueryResponse { + query_id, + querier: None, + response: response.try_into()?, + max_weight, + }, + TransferAsset { assets, beneficiary } => Self::TransferAsset { + assets: assets.try_into()?, + beneficiary: beneficiary.try_into()?, + }, + TransferReserveAsset { assets, dest, xcm } => Self::TransferReserveAsset { + assets: assets.try_into()?, + dest: dest.try_into()?, + xcm: xcm.try_into()?, + }, + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => + Self::HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity }, + HrmpChannelAccepted { recipient } => Self::HrmpChannelAccepted { recipient }, + HrmpChannelClosing { initiator, sender, recipient } => + Self::HrmpChannelClosing { initiator, sender, recipient }, + Transact { origin_kind, require_weight_at_most, call } => + Self::Transact { origin_kind, require_weight_at_most, call: call.into() }, + ReportError(response_info) => Self::ReportError(QueryResponseInfo { + query_id: response_info.query_id, + destination: response_info.destination.try_into().map_err(|_| ())?, + max_weight: response_info.max_weight, + }), + DepositAsset { assets, beneficiary } => { + let beneficiary = beneficiary.try_into()?; + let assets = assets.try_into()?; + Self::DepositAsset { assets, beneficiary } + }, + DepositReserveAsset { assets, dest, xcm } => { + let dest = dest.try_into()?; + let xcm = xcm.try_into()?; + let assets = assets.try_into()?; + Self::DepositReserveAsset { assets, dest, xcm } + }, + ExchangeAsset { give, want, maximal } => { + let give = give.try_into()?; + let want = want.try_into()?; + Self::ExchangeAsset { give, want, maximal } + }, + InitiateReserveWithdraw { assets, reserve, xcm } => { + let assets = assets.try_into()?; + let reserve = reserve.try_into()?; + let xcm = xcm.try_into()?; + Self::InitiateReserveWithdraw { assets, reserve, xcm } + }, + InitiateTeleport { assets, dest, xcm } => { + let assets = assets.try_into()?; + let dest = dest.try_into()?; + let xcm = xcm.try_into()?; + Self::InitiateTeleport { assets, dest, xcm } + }, + ReportHolding { response_info, assets } => { + let response_info = QueryResponseInfo { + destination: response_info.destination.try_into().map_err(|_| ())?, + query_id: response_info.query_id, + max_weight: response_info.max_weight, + }; + Self::ReportHolding { response_info, assets: assets.try_into()? } + }, + BuyExecution { fees, weight_limit } => { + let fees = fees.try_into()?; + let weight_limit = weight_limit.into(); + Self::BuyExecution { fees, weight_limit } + }, + ClearOrigin => Self::ClearOrigin, + DescendOrigin(who) => Self::DescendOrigin(who.try_into()?), + RefundSurplus => Self::RefundSurplus, + SetErrorHandler(xcm) => Self::SetErrorHandler(xcm.try_into()?), + SetAppendix(xcm) => Self::SetAppendix(xcm.try_into()?), + ClearError => Self::ClearError, + ClaimAsset { assets, ticket } => { + let assets = assets.try_into()?; + let ticket = ticket.try_into()?; + Self::ClaimAsset { assets, ticket } + }, + Trap(code) => Self::Trap(code), + SubscribeVersion { query_id, max_response_weight } => + Self::SubscribeVersion { query_id, max_response_weight }, + UnsubscribeVersion => Self::UnsubscribeVersion, + BurnAsset(assets) => Self::BurnAsset(assets.try_into()?), + ExpectAsset(assets) => Self::ExpectAsset(assets.try_into()?), + ExpectOrigin(maybe_location) => Self::ExpectOrigin( + maybe_location.map(|location| location.try_into()).transpose().map_err(|_| ())?, + ), + ExpectError(maybe_error) => Self::ExpectError( + maybe_error.map(|error| error.try_into()).transpose().map_err(|_| ())?, + ), + ExpectTransactStatus(maybe_error_code) => Self::ExpectTransactStatus(maybe_error_code), + QueryPallet { module_name, response_info } => Self::QueryPallet { + module_name, + response_info: response_info.try_into().map_err(|_| ())?, + }, + ExpectPallet { index, name, module_name, crate_major, min_crate_minor } => + Self::ExpectPallet { index, name, module_name, crate_major, min_crate_minor }, + ReportTransactStatus(response_info) => + Self::ReportTransactStatus(response_info.try_into().map_err(|_| ())?), + ClearTransactStatus => Self::ClearTransactStatus, + UniversalOrigin(junction) => + Self::UniversalOrigin(junction.try_into().map_err(|_| ())?), + ExportMessage { network, destination, xcm } => Self::ExportMessage { + network: network.into(), + destination: destination.try_into().map_err(|_| ())?, + xcm: xcm.try_into().map_err(|_| ())?, + }, + LockAsset { asset, unlocker } => Self::LockAsset { + asset: asset.try_into().map_err(|_| ())?, + unlocker: unlocker.try_into().map_err(|_| ())?, + }, + UnlockAsset { asset, target } => Self::UnlockAsset { + asset: asset.try_into().map_err(|_| ())?, + target: target.try_into().map_err(|_| ())?, + }, + NoteUnlockable { asset, owner } => Self::NoteUnlockable { + asset: asset.try_into().map_err(|_| ())?, + owner: owner.try_into().map_err(|_| ())?, + }, + RequestUnlock { asset, locker } => Self::RequestUnlock { + asset: asset.try_into().map_err(|_| ())?, + locker: locker.try_into().map_err(|_| ())?, + }, + SetFeesMode { jit_withdraw } => Self::SetFeesMode { jit_withdraw }, + SetTopic(topic) => Self::SetTopic(topic), + ClearTopic => Self::ClearTopic, + AliasOrigin(location) => Self::AliasOrigin(location.try_into().map_err(|_| ())?), + UnpaidExecution { weight_limit, check_origin } => Self::UnpaidExecution { + weight_limit, + check_origin: check_origin + .map(|location| location.try_into()) + .transpose() + .map_err(|_| ())?, + }, + }) + } +} + +#[cfg(test)] +mod tests { + use super::{prelude::*, *}; + use crate::v3::{ + Junctions::Here as OldHere, MultiAssetFilter as OldMultiAssetFilter, + WildMultiAsset as OldWildMultiAsset, + }; + + #[test] + fn basic_roundtrip_works() { + let xcm = Xcm::<()>(vec![TransferAsset { + assets: (Here, 1u128).into(), + beneficiary: Here.into(), + }]); + let old_xcm = OldXcm::<()>(vec![OldInstruction::TransferAsset { + assets: (OldHere, 1u128).into(), + beneficiary: OldHere.into(), + }]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } + + #[test] + fn teleport_roundtrip_works() { + let xcm = Xcm::<()>(vec![ + ReceiveTeleportedAsset((Here, 1u128).into()), + ClearOrigin, + DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Here.into() }, + ]); + let old_xcm: OldXcm<()> = OldXcm::<()>(vec![ + OldInstruction::ReceiveTeleportedAsset((OldHere, 1u128).into()), + OldInstruction::ClearOrigin, + OldInstruction::DepositAsset { + assets: crate::v3::MultiAssetFilter::Wild(crate::v3::WildMultiAsset::AllCounted(1)), + beneficiary: OldHere.into(), + }, + ]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } + + #[test] + fn reserve_deposit_roundtrip_works() { + let xcm = Xcm::<()>(vec![ + ReserveAssetDeposited((Here, 1u128).into()), + ClearOrigin, + BuyExecution { + fees: (Here, 1u128).into(), + weight_limit: Some(Weight::from_parts(1, 1)).into(), + }, + DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Here.into() }, + ]); + let old_xcm = OldXcm::<()>(vec![ + OldInstruction::ReserveAssetDeposited((OldHere, 1u128).into()), + OldInstruction::ClearOrigin, + OldInstruction::BuyExecution { + fees: (OldHere, 1u128).into(), + weight_limit: WeightLimit::Limited(Weight::from_parts(1, 1)), + }, + OldInstruction::DepositAsset { + assets: crate::v3::MultiAssetFilter::Wild(crate::v3::WildMultiAsset::AllCounted(1)), + beneficiary: OldHere.into(), + }, + ]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } + + #[test] + fn deposit_asset_roundtrip_works() { + let xcm = Xcm::<()>(vec![ + WithdrawAsset((Here, 1u128).into()), + DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Here.into() }, + ]); + let old_xcm = OldXcm::<()>(vec![ + OldInstruction::WithdrawAsset((OldHere, 1u128).into()), + OldInstruction::DepositAsset { + assets: OldMultiAssetFilter::Wild(OldWildMultiAsset::AllCounted(1)), + beneficiary: OldHere.into(), + }, + ]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } + + #[test] + fn deposit_reserve_asset_roundtrip_works() { + let xcm = Xcm::<()>(vec![ + WithdrawAsset((Here, 1u128).into()), + DepositReserveAsset { + assets: Wild(AllCounted(1)), + dest: Here.into(), + xcm: Xcm::<()>(vec![]), + }, + ]); + let old_xcm = OldXcm::<()>(vec![ + OldInstruction::WithdrawAsset((OldHere, 1u128).into()), + OldInstruction::DepositReserveAsset { + assets: OldMultiAssetFilter::Wild(OldWildMultiAsset::AllCounted(1)), + dest: OldHere.into(), + xcm: OldXcm::<()>(vec![]), + }, + ]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } +} diff --git a/polkadot/xcm/src/v4/traits.rs b/polkadot/xcm/src/v4/traits.rs new file mode 100644 index 00000000000..f6136c76d80 --- /dev/null +++ b/polkadot/xcm/src/v4/traits.rs @@ -0,0 +1,312 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Cross-Consensus Message format data structures. + +pub use crate::v3::{Error, Result, SendError, XcmHash}; +use core::result; +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; + +pub use sp_weights::Weight; + +use super::*; + +/// Outcome of an XCM execution. +#[derive(Clone, Encode, Decode, Eq, PartialEq, Debug, TypeInfo)] +pub enum Outcome { + /// Execution completed successfully; given weight was used. + Complete { used: Weight }, + /// Execution started, but did not complete successfully due to the given error; given weight + /// was used. + Incomplete { used: Weight, error: Error }, + /// Execution did not start due to the given error. + Error { error: Error }, +} + +impl Outcome { + pub fn ensure_complete(self) -> Result { + match self { + Outcome::Complete { .. } => Ok(()), + Outcome::Incomplete { error, .. } => Err(error), + Outcome::Error { error, .. } => Err(error), + } + } + pub fn ensure_execution(self) -> result::Result { + match self { + Outcome::Complete { used, .. } => Ok(used), + Outcome::Incomplete { used, .. } => Ok(used), + Outcome::Error { error, .. } => Err(error), + } + } + /// How much weight was used by the XCM execution attempt. + pub fn weight_used(&self) -> Weight { + match self { + Outcome::Complete { used, .. } => *used, + Outcome::Incomplete { used, .. } => *used, + Outcome::Error { .. } => Weight::zero(), + } + } +} + +impl From for Outcome { + fn from(error: Error) -> Self { + Self::Error { error } + } +} + +pub trait PreparedMessage { + fn weight_of(&self) -> Weight; +} + +/// Type of XCM message executor. +pub trait ExecuteXcm { + type Prepared: PreparedMessage; + fn prepare(message: Xcm) -> result::Result>; + fn execute( + origin: impl Into, + pre: Self::Prepared, + id: &mut XcmHash, + weight_credit: Weight, + ) -> Outcome; + fn prepare_and_execute( + origin: impl Into, + message: Xcm, + id: &mut XcmHash, + weight_limit: Weight, + weight_credit: Weight, + ) -> Outcome { + let pre = match Self::prepare(message) { + Ok(x) => x, + Err(_) => return Outcome::Error { error: Error::WeightNotComputable }, + }; + let xcm_weight = pre.weight_of(); + if xcm_weight.any_gt(weight_limit) { + return Outcome::Error { error: Error::WeightLimitReached(xcm_weight) } + } + Self::execute(origin, pre, id, weight_credit) + } + + /// Deduct some `fees` to the sovereign account of the given `location` and place them as per + /// the convention for fees. + fn charge_fees(location: impl Into, fees: Assets) -> Result; +} + +pub enum Weightless {} +impl PreparedMessage for Weightless { + fn weight_of(&self) -> Weight { + unreachable!() + } +} + +impl ExecuteXcm for () { + type Prepared = Weightless; + fn prepare(message: Xcm) -> result::Result> { + Err(message) + } + fn execute(_: impl Into, _: Self::Prepared, _: &mut XcmHash, _: Weight) -> Outcome { + unreachable!() + } + fn charge_fees(_location: impl Into, _fees: Assets) -> Result { + Err(Error::Unimplemented) + } +} + +pub trait Reanchorable: Sized { + /// Type to return in case of an error. + type Error: Debug; + + /// Mutate `self` so that it represents the same location from the point of view of `target`. + /// The context of `self` is provided as `context`. + /// + /// Does not modify `self` in case of overflow. + fn reanchor( + &mut self, + target: &Location, + context: &InteriorLocation, + ) -> core::result::Result<(), ()>; + + /// Consume `self` and return a new value representing the same location from the point of view + /// of `target`. The context of `self` is provided as `context`. + /// + /// Returns the original `self` in case of overflow. + fn reanchored( + self, + target: &Location, + context: &InteriorLocation, + ) -> core::result::Result; +} + +/// Result value when attempting to send an XCM message. +pub type SendResult = result::Result<(T, Assets), SendError>; + +/// Utility for sending an XCM message to a given location. +/// +/// These can be amalgamated in tuples to form sophisticated routing systems. In tuple format, each +/// router might return `NotApplicable` to pass the execution to the next sender item. Note that +/// each `NotApplicable` might alter the destination and the XCM message for to the next router. +/// +/// # Example +/// ```rust +/// # use parity_scale_codec::Encode; +/// # use staging_xcm::v4::{prelude::*, Weight}; +/// # use staging_xcm::VersionedXcm; +/// # use std::convert::Infallible; +/// +/// /// A sender that only passes the message through and does nothing. +/// struct Sender1; +/// impl SendXcm for Sender1 { +/// type Ticket = Infallible; +/// fn validate(_: &mut Option, _: &mut Option>) -> SendResult { +/// Err(SendError::NotApplicable) +/// } +/// fn deliver(_: Infallible) -> Result { +/// unreachable!() +/// } +/// } +/// +/// /// A sender that accepts a message that has two junctions, otherwise stops the routing. +/// struct Sender2; +/// impl SendXcm for Sender2 { +/// type Ticket = (); +/// fn validate(destination: &mut Option, message: &mut Option>) -> SendResult<()> { +/// match destination.as_ref().ok_or(SendError::MissingArgument)?.unpack() { +/// (0, [j1, j2]) => Ok(((), Assets::new())), +/// _ => Err(SendError::Unroutable), +/// } +/// } +/// fn deliver(_: ()) -> Result { +/// Ok([0; 32]) +/// } +/// } +/// +/// /// A sender that accepts a message from a parent, passing through otherwise. +/// struct Sender3; +/// impl SendXcm for Sender3 { +/// type Ticket = (); +/// fn validate(destination: &mut Option, message: &mut Option>) -> SendResult<()> { +/// match destination.as_ref().ok_or(SendError::MissingArgument)?.unpack() { +/// (1, []) => Ok(((), Assets::new())), +/// _ => Err(SendError::NotApplicable), +/// } +/// } +/// fn deliver(_: ()) -> Result { +/// Ok([0; 32]) +/// } +/// } +/// +/// // A call to send via XCM. We don't really care about this. +/// # fn main() { +/// let call: Vec = ().encode(); +/// let message = Xcm(vec![Instruction::Transact { +/// origin_kind: OriginKind::Superuser, +/// require_weight_at_most: Weight::zero(), +/// call: call.into(), +/// }]); +/// let message_hash = message.using_encoded(sp_io::hashing::blake2_256); +/// +/// // Sender2 will block this. +/// assert!(send_xcm::<(Sender1, Sender2, Sender3)>(Parent.into(), message.clone()).is_err()); +/// +/// // Sender3 will catch this. +/// assert!(send_xcm::<(Sender1, Sender3)>(Parent.into(), message.clone()).is_ok()); +/// # } +/// ``` +pub trait SendXcm { + /// Intermediate value which connects the two phases of the send operation. + type Ticket; + + /// Check whether the given `_message` is deliverable to the given `_destination` and if so + /// determine the cost which will be paid by this chain to do so, returning a `Validated` token + /// which can be used to enact delivery. + /// + /// The `destination` and `message` must be `Some` (or else an error will be returned) and they + /// may only be consumed if the `Err` is not `NotApplicable`. + /// + /// If it is not a destination which can be reached with this type but possibly could by others, + /// then this *MUST* return `NotApplicable`. Any other error will cause the tuple + /// implementation to exit early without trying other type fields. + fn validate( + destination: &mut Option, + message: &mut Option>, + ) -> SendResult; + + /// Actually carry out the delivery operation for a previously validated message sending. + fn deliver(ticket: Self::Ticket) -> result::Result; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl SendXcm for Tuple { + for_tuples! { type Ticket = (#( Option ),* ); } + + fn validate( + destination: &mut Option, + message: &mut Option>, + ) -> SendResult { + let mut maybe_cost: Option = None; + let one_ticket: Self::Ticket = (for_tuples! { #( + if maybe_cost.is_some() { + None + } else { + match Tuple::validate(destination, message) { + Err(SendError::NotApplicable) => None, + Err(e) => { return Err(e) }, + Ok((v, c)) => { + maybe_cost = Some(c); + Some(v) + }, + } + } + ),* }); + if let Some(cost) = maybe_cost { + Ok((one_ticket, cost)) + } else { + Err(SendError::NotApplicable) + } + } + + fn deliver(one_ticket: Self::Ticket) -> result::Result { + for_tuples!( #( + if let Some(validated) = one_ticket.Tuple { + return Tuple::deliver(validated); + } + )* ); + Err(SendError::Unroutable) + } +} + +/// Convenience function for using a `SendXcm` implementation. Just interprets the `dest` and wraps +/// both in `Some` before passing them as as mutable references into `T::send_xcm`. +pub fn validate_send(dest: Location, msg: Xcm<()>) -> SendResult { + T::validate(&mut Some(dest), &mut Some(msg)) +} + +/// Convenience function for using a `SendXcm` implementation. Just interprets the `dest` and wraps +/// both in `Some` before passing them as as mutable references into `T::send_xcm`. +/// +/// Returns either `Ok` with the price of the delivery, or `Err` with the reason why the message +/// could not be sent. +/// +/// Generally you'll want to validate and get the price first to ensure that the sender can pay it +/// before actually doing the delivery. +pub fn send_xcm( + dest: Location, + msg: Xcm<()>, +) -> result::Result<(XcmHash, Assets), SendError> { + let (ticket, price) = T::validate(&mut Some(dest), &mut Some(msg))?; + let hash = T::deliver(ticket)?; + Ok((hash, price)) +} diff --git a/polkadot/xcm/xcm-builder/src/asset_conversion.rs b/polkadot/xcm/xcm-builder/src/asset_conversion.rs index 5b76ed764a8..e38af149be5 100644 --- a/polkadot/xcm/xcm-builder/src/asset_conversion.rs +++ b/polkadot/xcm/xcm-builder/src/asset_conversion.rs @@ -23,39 +23,42 @@ use xcm::latest::prelude::*; use xcm_executor::traits::{Error as MatchError, MatchesFungibles, MatchesNonFungibles}; /// Converter struct implementing `AssetIdConversion` converting a numeric asset ID (must be -/// `TryFrom/TryInto`) into a `GeneralIndex` junction, prefixed by some `MultiLocation` value. -/// The `MultiLocation` value will typically be a `PalletInstance` junction. -pub struct AsPrefixedGeneralIndex( - PhantomData<(Prefix, AssetId, ConvertAssetId)>, +/// `TryFrom/TryInto`) into a `GeneralIndex` junction, prefixed by some `Location` value. +/// The `Location` value will typically be a `PalletInstance` junction. +pub struct AsPrefixedGeneralIndex( + PhantomData<(Prefix, AssetId, ConvertAssetId, L)>, ); impl< - Prefix: Get, + Prefix: Get, AssetId: Clone, ConvertAssetId: MaybeEquivalence, - > MaybeEquivalence - for AsPrefixedGeneralIndex + L: TryInto + TryFrom + Clone, + > MaybeEquivalence for AsPrefixedGeneralIndex { - fn convert(id: &MultiLocation) -> Option { + fn convert(id: &L) -> Option { let prefix = Prefix::get(); - if prefix.parent_count() != id.parent_count() || - prefix + let latest_prefix: Location = prefix.try_into().ok()?; + let latest_id: Location = (*id).clone().try_into().ok()?; + if latest_prefix.parent_count() != latest_id.parent_count() || + latest_prefix .interior() .iter() .enumerate() - .any(|(index, junction)| id.interior().at(index) != Some(junction)) + .any(|(index, junction)| latest_id.interior().at(index) != Some(junction)) { return None } - match id.interior().at(prefix.interior().len()) { - Some(Junction::GeneralIndex(id)) => ConvertAssetId::convert(id), + match latest_id.interior().at(latest_prefix.interior().len()) { + Some(Junction::GeneralIndex(id)) => ConvertAssetId::convert(&id), _ => None, } } - fn convert_back(what: &AssetId) -> Option { - let mut location = Prefix::get(); + fn convert_back(what: &AssetId) -> Option { + let location = Prefix::get(); + let mut latest_location: Location = location.try_into().ok()?; let id = ConvertAssetId::convert_back(what)?; - location.push_interior(Junction::GeneralIndex(id)).ok()?; - Some(location) + latest_location.push_interior(Junction::GeneralIndex(id)).ok()?; + latest_location.try_into().ok() } } @@ -65,14 +68,14 @@ pub struct ConvertedConcreteId( impl< AssetId: Clone, Balance: Clone, - ConvertAssetId: MaybeEquivalence, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, > MatchesFungibles for ConvertedConcreteId { - fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> { + fn matches_fungibles(a: &Asset) -> result::Result<(AssetId, Balance), MatchError> { let (amount, id) = match (&a.fun, &a.id) { - (Fungible(ref amount), Concrete(ref id)) => (amount, id), + (Fungible(ref amount), AssetId(ref id)) => (amount, id), _ => return Err(MatchError::AssetNotHandled), }; let what = ConvertAssetId::convert(id).ok_or(MatchError::AssetIdConversionFailed)?; @@ -84,14 +87,14 @@ impl< impl< ClassId: Clone, InstanceId: Clone, - ConvertClassId: MaybeEquivalence, + ConvertClassId: MaybeEquivalence, ConvertInstanceId: MaybeEquivalence, > MatchesNonFungibles for ConvertedConcreteId { - fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(ClassId, InstanceId), MatchError> { + fn matches_nonfungibles(a: &Asset) -> result::Result<(ClassId, InstanceId), MatchError> { let (instance, class) = match (&a.fun, &a.id) { - (NonFungible(ref instance), Concrete(ref class)) => (instance, class), + (NonFungible(ref instance), AssetId(ref class)) => (instance, class), _ => return Err(MatchError::AssetNotHandled), }; let what = ConvertClassId::convert(class).ok_or(MatchError::AssetIdConversionFailed)?; @@ -101,68 +104,35 @@ impl< } } -pub struct ConvertedAbstractId( - PhantomData<(AssetId, Balance, ConvertAssetId, ConvertOther)>, -); -impl< - AssetId: Clone, - Balance: Clone, - ConvertAssetId: MaybeEquivalence<[u8; 32], AssetId>, - ConvertBalance: MaybeEquivalence, - > MatchesFungibles - for ConvertedAbstractId -{ - fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> { - let (amount, id) = match (&a.fun, &a.id) { - (Fungible(ref amount), Abstract(ref id)) => (amount, id), - _ => return Err(MatchError::AssetNotHandled), - }; - let what = ConvertAssetId::convert(id).ok_or(MatchError::AssetIdConversionFailed)?; - let amount = - ConvertBalance::convert(amount).ok_or(MatchError::AmountToBalanceConversionFailed)?; - Ok((what, amount)) +#[deprecated = "Use `ConvertedConcreteId` instead"] +pub type ConvertedConcreteAssetId = ConvertedConcreteId; + +pub struct V4V3LocationConverter; +impl MaybeEquivalence for V4V3LocationConverter { + fn convert(old: &xcm::v4::Location) -> Option { + (*old).clone().try_into().ok() } -} -impl< - ClassId: Clone, - InstanceId: Clone, - ConvertClassId: MaybeEquivalence<[u8; 32], ClassId>, - ConvertInstanceId: MaybeEquivalence, - > MatchesNonFungibles - for ConvertedAbstractId -{ - fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(ClassId, InstanceId), MatchError> { - let (instance, class) = match (&a.fun, &a.id) { - (NonFungible(ref instance), Abstract(ref class)) => (instance, class), - _ => return Err(MatchError::AssetNotHandled), - }; - let what = ConvertClassId::convert(class).ok_or(MatchError::AssetIdConversionFailed)?; - let instance = - ConvertInstanceId::convert(instance).ok_or(MatchError::InstanceConversionFailed)?; - Ok((what, instance)) + + fn convert_back(new: &xcm::v3::Location) -> Option { + (*new).try_into().ok() } } -#[deprecated = "Use `ConvertedConcreteId` instead"] -pub type ConvertedConcreteAssetId = ConvertedConcreteId; -#[deprecated = "Use `ConvertedAbstractId` instead"] -pub type ConvertedAbstractAssetId = ConvertedAbstractId; - pub struct MatchedConvertedConcreteId( PhantomData<(AssetId, Balance, MatchAssetId, ConvertAssetId, ConvertOther)>, ); impl< AssetId: Clone, Balance: Clone, - MatchAssetId: Contains, - ConvertAssetId: MaybeEquivalence, + MatchAssetId: Contains, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, > MatchesFungibles for MatchedConvertedConcreteId { - fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> { + fn matches_fungibles(a: &Asset) -> result::Result<(AssetId, Balance), MatchError> { let (amount, id) = match (&a.fun, &a.id) { - (Fungible(ref amount), Concrete(ref id)) if MatchAssetId::contains(id) => (amount, id), + (Fungible(ref amount), AssetId(ref id)) if MatchAssetId::contains(id) => (amount, id), _ => return Err(MatchError::AssetNotHandled), }; let what = ConvertAssetId::convert(id).ok_or(MatchError::AssetIdConversionFailed)?; @@ -174,15 +144,15 @@ impl< impl< ClassId: Clone, InstanceId: Clone, - MatchClassId: Contains, - ConvertClassId: MaybeEquivalence, + MatchClassId: Contains, + ConvertClassId: MaybeEquivalence, ConvertInstanceId: MaybeEquivalence, > MatchesNonFungibles for MatchedConvertedConcreteId { - fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(ClassId, InstanceId), MatchError> { + fn matches_nonfungibles(a: &Asset) -> result::Result<(ClassId, InstanceId), MatchError> { let (instance, class) = match (&a.fun, &a.id) { - (NonFungible(ref instance), Concrete(ref class)) if MatchClassId::contains(class) => + (NonFungible(ref instance), AssetId(ref class)) if MatchClassId::contains(class) => (instance, class), _ => return Err(MatchError::AssetNotHandled), }; @@ -200,10 +170,10 @@ mod tests { use xcm_executor::traits::JustTry; struct OnlyParentZero; - impl Contains for OnlyParentZero { - fn contains(a: &MultiLocation) -> bool { + impl Contains for OnlyParentZero { + fn contains(a: &Location) -> bool { match a { - MultiLocation { parents: 0, .. } => true, + Location { parents: 0, .. } => true, _ => false, } } @@ -214,7 +184,7 @@ mod tests { type AssetIdForTrustBackedAssets = u32; type Balance = u128; frame_support::parameter_types! { - pub TrustBackedAssetsPalletLocation: MultiLocation = PalletInstance(50).into(); + pub TrustBackedAssetsPalletLocation: Location = PalletInstance(50).into(); } // ConvertedConcreteId cfg @@ -231,13 +201,13 @@ mod tests { >; assert_eq!( TrustBackedAssetsPalletLocation::get(), - MultiLocation { parents: 0, interior: X1(PalletInstance(50)) } + Location { parents: 0, interior: [PalletInstance(50)].into() } ); // err - does not match assert_eq!( - Converter::matches_fungibles(&MultiAsset { - id: Concrete(MultiLocation::new(1, X2(PalletInstance(50), GeneralIndex(1)))), + Converter::matches_fungibles(&Asset { + id: AssetId(Location::new(1, [PalletInstance(50), GeneralIndex(1)])), fun: Fungible(12345), }), Err(MatchError::AssetNotHandled) @@ -245,10 +215,10 @@ mod tests { // err - matches, but convert fails assert_eq!( - Converter::matches_fungibles(&MultiAsset { - id: Concrete(MultiLocation::new( + Converter::matches_fungibles(&Asset { + id: AssetId(Location::new( 0, - X2(PalletInstance(50), GeneralKey { length: 1, data: [1; 32] }) + [PalletInstance(50), GeneralKey { length: 1, data: [1; 32] }] )), fun: Fungible(12345), }), @@ -257,8 +227,8 @@ mod tests { // err - matches, but NonFungible assert_eq!( - Converter::matches_fungibles(&MultiAsset { - id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))), + Converter::matches_fungibles(&Asset { + id: AssetId(Location::new(0, [PalletInstance(50), GeneralIndex(1)])), fun: NonFungible(Index(54321)), }), Err(MatchError::AssetNotHandled) @@ -266,8 +236,8 @@ mod tests { // ok assert_eq!( - Converter::matches_fungibles(&MultiAsset { - id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))), + Converter::matches_fungibles(&Asset { + id: AssetId(Location::new(0, [PalletInstance(50), GeneralIndex(1)])), fun: Fungible(12345), }), Ok((1, 12345)) @@ -279,7 +249,7 @@ mod tests { type ClassId = u32; type ClassInstanceId = u64; frame_support::parameter_types! { - pub TrustBackedAssetsPalletLocation: MultiLocation = PalletInstance(50).into(); + pub TrustBackedAssetsPalletLocation: Location = PalletInstance(50).into(); } // ConvertedConcreteId cfg @@ -303,13 +273,13 @@ mod tests { >; assert_eq!( TrustBackedAssetsPalletLocation::get(), - MultiLocation { parents: 0, interior: X1(PalletInstance(50)) } + Location { parents: 0, interior: [PalletInstance(50)].into() } ); // err - does not match assert_eq!( - Converter::matches_nonfungibles(&MultiAsset { - id: Concrete(MultiLocation::new(1, X2(PalletInstance(50), GeneralIndex(1)))), + Converter::matches_nonfungibles(&Asset { + id: AssetId(Location::new(1, [PalletInstance(50), GeneralIndex(1)])), fun: NonFungible(Index(54321)), }), Err(MatchError::AssetNotHandled) @@ -317,10 +287,10 @@ mod tests { // err - matches, but convert fails assert_eq!( - Converter::matches_nonfungibles(&MultiAsset { - id: Concrete(MultiLocation::new( + Converter::matches_nonfungibles(&Asset { + id: AssetId(Location::new( 0, - X2(PalletInstance(50), GeneralKey { length: 1, data: [1; 32] }) + [PalletInstance(50), GeneralKey { length: 1, data: [1; 32] }] )), fun: NonFungible(Index(54321)), }), @@ -329,8 +299,8 @@ mod tests { // err - matches, but Fungible vs NonFungible assert_eq!( - Converter::matches_nonfungibles(&MultiAsset { - id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))), + Converter::matches_nonfungibles(&Asset { + id: AssetId(Location::new(0, [PalletInstance(50), GeneralIndex(1)])), fun: Fungible(12345), }), Err(MatchError::AssetNotHandled) @@ -338,8 +308,8 @@ mod tests { // ok assert_eq!( - Converter::matches_nonfungibles(&MultiAsset { - id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))), + Converter::matches_nonfungibles(&Asset { + id: AssetId(Location::new(0, [PalletInstance(50), GeneralIndex(1)])), fun: NonFungible(Index(54321)), }), Ok((1, 54321)) diff --git a/polkadot/xcm/xcm-builder/src/barriers.rs b/polkadot/xcm/xcm-builder/src/barriers.rs index c2b62751c68..80411ab5a22 100644 --- a/polkadot/xcm/xcm-builder/src/barriers.rs +++ b/polkadot/xcm/xcm-builder/src/barriers.rs @@ -34,7 +34,7 @@ use xcm_executor::traits::{CheckSuspension, OnResponse, Properties, ShouldExecut pub struct TakeWeightCredit; impl ShouldExecute for TakeWeightCredit { fn should_execute( - _origin: &MultiLocation, + _origin: &Location, _instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -60,9 +60,9 @@ const MAX_ASSETS_FOR_BUY_EXECUTION: usize = 2; /// Only allows for `TeleportAsset`, `WithdrawAsset`, `ClaimAsset` and `ReserveAssetDeposit` XCMs /// because they are the only ones that place assets in the Holding Register to pay for execution. pub struct AllowTopLevelPaidExecutionFrom(PhantomData); -impl> ShouldExecute for AllowTopLevelPaidExecutionFrom { +impl> ShouldExecute for AllowTopLevelPaidExecutionFrom { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, _properties: &mut Properties, @@ -158,14 +158,11 @@ impl> ShouldExecute for AllowTopLevelPaidExecutionFro pub struct WithComputedOrigin( PhantomData<(InnerBarrier, LocalUniversal, MaxPrefixes)>, ); -impl< - InnerBarrier: ShouldExecute, - LocalUniversal: Get, - MaxPrefixes: Get, - > ShouldExecute for WithComputedOrigin +impl, MaxPrefixes: Get> + ShouldExecute for WithComputedOrigin { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -175,7 +172,7 @@ impl< "WithComputedOrigin origin: {:?}, instructions: {:?}, max_weight: {:?}, properties: {:?}", origin, instructions, max_weight, properties, ); - let mut actual_origin = *origin; + let mut actual_origin = origin.clone(); let skipped = Cell::new(0usize); // NOTE: We do not check the validity of `UniversalOrigin` here, meaning that a malicious // origin could place a `UniversalOrigin` in order to spoof some location which gets free @@ -190,10 +187,11 @@ impl< // Note the origin is *relative to local consensus*! So we need to escape // local consensus with the `parents` before diving in into the // `universal_location`. - actual_origin = X1(*new_global).relative_to(&LocalUniversal::get()); + actual_origin = + Junctions::from([*new_global]).relative_to(&LocalUniversal::get()); }, DescendOrigin(j) => { - let Ok(_) = actual_origin.append_with(*j) else { + let Ok(_) = actual_origin.append_with(j.clone()) else { return Err(ProcessMessageError::Unsupported) }; }, @@ -221,7 +219,7 @@ impl< pub struct TrailingSetTopicAsId(PhantomData); impl ShouldExecute for TrailingSetTopicAsId { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -250,7 +248,7 @@ where SuspensionChecker: CheckSuspension, { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -268,9 +266,9 @@ where /// Use only for executions from completely trusted origins, from which no permissionless messages /// can be sent. pub struct AllowUnpaidExecutionFrom(PhantomData); -impl> ShouldExecute for AllowUnpaidExecutionFrom { +impl> ShouldExecute for AllowUnpaidExecutionFrom { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], _max_weight: Weight, _properties: &mut Properties, @@ -290,9 +288,9 @@ impl> ShouldExecute for AllowUnpaidExecutionFrom { /// /// Use only for executions from trusted origin groups. pub struct AllowExplicitUnpaidExecutionFrom(PhantomData); -impl> ShouldExecute for AllowExplicitUnpaidExecutionFrom { +impl> ShouldExecute for AllowExplicitUnpaidExecutionFrom { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, _properties: &mut Properties, @@ -314,11 +312,11 @@ impl> ShouldExecute for AllowExplicitUnpaidExecutionF /// Allows a message only if it is from a system-level child parachain. pub struct IsChildSystemParachain(PhantomData); -impl> Contains for IsChildSystemParachain { - fn contains(l: &MultiLocation) -> bool { +impl> Contains for IsChildSystemParachain { + fn contains(l: &Location) -> bool { matches!( - l.interior(), - Junctions::X1(Junction::Parachain(id)) + l.interior().as_slice(), + [Junction::Parachain(id)] if ParaId::from(*id).is_system() && l.parent_count() == 0, ) } @@ -328,7 +326,7 @@ impl> Contains for IsChildSystemPara pub struct AllowKnownQueryResponses(PhantomData); impl ShouldExecute for AllowKnownQueryResponses { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], _max_weight: Weight, _properties: &mut Properties, @@ -354,9 +352,9 @@ impl ShouldExecute for AllowKnownQueryResponses(PhantomData); -impl> ShouldExecute for AllowSubscriptionsFrom { +impl> ShouldExecute for AllowSubscriptionsFrom { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], _max_weight: Weight, _properties: &mut Properties, @@ -391,7 +389,7 @@ where Allow: ShouldExecute, { fn should_execute( - origin: &MultiLocation, + origin: &Location, message: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -405,7 +403,7 @@ where pub struct DenyReserveTransferToRelayChain; impl ShouldExecute for DenyReserveTransferToRelayChain { fn should_execute( - origin: &MultiLocation, + origin: &Location, message: &mut [Instruction], _max_weight: Weight, _properties: &mut Properties, @@ -414,22 +412,18 @@ impl ShouldExecute for DenyReserveTransferToRelayChain { |_| true, |inst| match inst { InitiateReserveWithdraw { - reserve: MultiLocation { parents: 1, interior: Here }, + reserve: Location { parents: 1, interior: Here }, .. } | - DepositReserveAsset { - dest: MultiLocation { parents: 1, interior: Here }, .. - } | - TransferReserveAsset { - dest: MultiLocation { parents: 1, interior: Here }, .. - } => { + DepositReserveAsset { dest: Location { parents: 1, interior: Here }, .. } | + TransferReserveAsset { dest: Location { parents: 1, interior: Here }, .. } => { Err(ProcessMessageError::Unsupported) // Deny }, // An unexpected reserve transfer has arrived from the Relay Chain. Generally, // `IsReserve` should not allow this, but we just log it here. ReserveAssetDeposited { .. } - if matches!(origin, MultiLocation { parents: 1, interior: Here }) => + if matches!(origin, Location { parents: 1, interior: Here }) => { log::warn!( target: "xcm::barrier", diff --git a/polkadot/xcm/xcm-builder/src/controller.rs b/polkadot/xcm/xcm-builder/src/controller.rs index 931d812eaaf..8ead18b5bd7 100644 --- a/polkadot/xcm/xcm-builder/src/controller.rs +++ b/polkadot/xcm/xcm-builder/src/controller.rs @@ -45,7 +45,7 @@ pub trait ExecuteControllerWeightInfo { /// Execute an XCM locally, for a given origin. /// /// An implementation of that trait will handle the low-level details of the execution, such as: -/// - Validating and Converting the origin to a MultiLocation. +/// - Validating and Converting the origin to a Location. /// - Handling versioning. /// - Calling the internal executor, which implements [`ExecuteXcm`]. pub trait ExecuteController { @@ -92,7 +92,7 @@ pub trait SendController { /// - `msg`: the XCM to be sent. fn send( origin: Origin, - dest: Box, + dest: Box, message: Box>, ) -> Result; } @@ -127,7 +127,7 @@ pub trait QueryController: QueryHandler { fn query( origin: Origin, timeout: Timeout, - match_querier: VersionedMultiLocation, + match_querier: VersionedLocation, ) -> Result; } @@ -138,7 +138,7 @@ impl ExecuteController for () { _message: Box>, _max_weight: Weight, ) -> Result { - Ok(Outcome::Error(XcmError::Unimplemented)) + Ok(Outcome::Error { error: XcmError::Unimplemented }) } } @@ -152,7 +152,7 @@ impl SendController for () { type WeightInfo = (); fn send( _origin: Origin, - _dest: Box, + _dest: Box, _message: Box>, ) -> Result { Ok(Default::default()) @@ -180,7 +180,7 @@ impl QueryController for () { fn query( _origin: Origin, _timeout: Timeout, - _match_querier: VersionedMultiLocation, + _match_querier: VersionedLocation, ) -> Result { Ok(Default::default()) } diff --git a/polkadot/xcm/xcm-builder/src/currency_adapter.rs b/polkadot/xcm/xcm-builder/src/currency_adapter.rs index 68ca0111174..fe26b7319bb 100644 --- a/polkadot/xcm/xcm-builder/src/currency_adapter.rs +++ b/polkadot/xcm/xcm-builder/src/currency_adapter.rs @@ -22,17 +22,17 @@ use super::MintLocation; use frame_support::traits::{ExistenceRequirement::AllowDeath, Get, WithdrawReasons}; use sp_runtime::traits::CheckedSub; use sp_std::{marker::PhantomData, result}; -use xcm::latest::{Error as XcmError, MultiAsset, MultiLocation, Result, XcmContext}; +use xcm::latest::{Asset, Error as XcmError, Location, Result, XcmContext}; use xcm_executor::{ traits::{ConvertLocation, MatchesFungible, TransactAsset}, - Assets, + AssetsInHolding, }; /// Asset transaction errors. enum Error { /// The given asset is not handled. (According to [`XcmError::AssetNotFound`]) AssetNotHandled, - /// `MultiLocation` to `AccountId` conversion failed. + /// `Location` to `AccountId` conversion failed. AccountIdConversionFailed, } @@ -62,7 +62,7 @@ impl From for XcmError { /// /// /// Our relay chain's location. /// parameter_types! { -/// pub RelayChain: MultiLocation = Parent.into(); +/// pub RelayChain: Location = Parent.into(); /// pub CheckingAccount: AccountId = PalletId(*b"checking").into_account_truncating(); /// } /// @@ -142,7 +142,7 @@ impl< > TransactAsset for CurrencyAdapter { - fn can_check_in(_origin: &MultiLocation, what: &MultiAsset, _context: &XcmContext) -> Result { + fn can_check_in(_origin: &Location, what: &Asset, _context: &XcmContext) -> Result { log::trace!(target: "xcm::currency_adapter", "can_check_in origin: {:?}, what: {:?}", _origin, what); // Check we handle this asset. let amount: Currency::Balance = @@ -156,7 +156,7 @@ impl< } } - fn check_in(_origin: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + fn check_in(_origin: &Location, what: &Asset, _context: &XcmContext) { log::trace!(target: "xcm::currency_adapter", "check_in origin: {:?}, what: {:?}", _origin, what); if let Some(amount) = Matcher::matches_fungible(what) { match CheckedAccount::get() { @@ -169,7 +169,7 @@ impl< } } - fn can_check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) -> Result { + fn can_check_out(_dest: &Location, what: &Asset, _context: &XcmContext) -> Result { log::trace!(target: "xcm::currency_adapter", "check_out dest: {:?}, what: {:?}", _dest, what); let amount = Matcher::matches_fungible(what).ok_or(Error::AssetNotHandled)?; match CheckedAccount::get() { @@ -181,7 +181,7 @@ impl< } } - fn check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + fn check_out(_dest: &Location, what: &Asset, _context: &XcmContext) { log::trace!(target: "xcm::currency_adapter", "check_out dest: {:?}, what: {:?}", _dest, what); if let Some(amount) = Matcher::matches_fungible(what) { match CheckedAccount::get() { @@ -194,11 +194,7 @@ impl< } } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - _context: Option<&XcmContext>, - ) -> Result { + fn deposit_asset(what: &Asset, who: &Location, _context: Option<&XcmContext>) -> Result { log::trace!(target: "xcm::currency_adapter", "deposit_asset what: {:?}, who: {:?}", what, who); // Check we handle this asset. let amount = Matcher::matches_fungible(&what).ok_or(Error::AssetNotHandled)?; @@ -209,10 +205,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, _maybe_context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { log::trace!(target: "xcm::currency_adapter", "withdraw_asset what: {:?}, who: {:?}", what, who); // Check we handle this asset. let amount = Matcher::matches_fungible(what).ok_or(Error::AssetNotHandled)?; @@ -224,11 +220,11 @@ impl< } fn internal_transfer_asset( - asset: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + asset: &Asset, + from: &Location, + to: &Location, _context: &XcmContext, - ) -> result::Result { + ) -> result::Result { log::trace!(target: "xcm::currency_adapter", "internal_transfer_asset asset: {:?}, from: {:?}, to: {:?}", asset, from, to); let amount = Matcher::matches_fungible(asset).ok_or(Error::AssetNotHandled)?; let from = diff --git a/polkadot/xcm/xcm-builder/src/fee_handling.rs b/polkadot/xcm/xcm-builder/src/fee_handling.rs index c158d5d862d..e114b3601c8 100644 --- a/polkadot/xcm/xcm-builder/src/fee_handling.rs +++ b/polkadot/xcm/xcm-builder/src/fee_handling.rs @@ -25,27 +25,22 @@ pub trait HandleFee { /// fees. /// /// Returns any part of the fee that wasn't consumed. - fn handle_fee(fee: MultiAssets, context: Option<&XcmContext>, reason: FeeReason) - -> MultiAssets; + fn handle_fee(fee: Assets, context: Option<&XcmContext>, reason: FeeReason) -> Assets; } // Default `HandleFee` implementation that just burns the fee. impl HandleFee for () { - fn handle_fee(_: MultiAssets, _: Option<&XcmContext>, _: FeeReason) -> MultiAssets { - MultiAssets::new() + fn handle_fee(_: Assets, _: Option<&XcmContext>, _: FeeReason) -> Assets { + Assets::new() } } #[impl_trait_for_tuples::impl_for_tuples(1, 30)] impl HandleFee for Tuple { - fn handle_fee( - fee: MultiAssets, - context: Option<&XcmContext>, - reason: FeeReason, - ) -> MultiAssets { + fn handle_fee(fee: Assets, context: Option<&XcmContext>, reason: FeeReason) -> Assets { let mut unconsumed_fee = fee; for_tuples!( #( - unconsumed_fee = Tuple::handle_fee(unconsumed_fee, context, reason); + unconsumed_fee = Tuple::handle_fee(unconsumed_fee, context, reason.clone()); if unconsumed_fee.is_none() { return unconsumed_fee; } @@ -60,15 +55,15 @@ impl HandleFee for Tuple { pub struct XcmFeeManagerFromComponents( PhantomData<(WaivedLocations, HandleFee)>, ); -impl, FeeHandler: HandleFee> FeeManager +impl, FeeHandler: HandleFee> FeeManager for XcmFeeManagerFromComponents { - fn is_waived(origin: Option<&MultiLocation>, _: FeeReason) -> bool { + fn is_waived(origin: Option<&Location>, _: FeeReason) -> bool { let Some(loc) = origin else { return false }; WaivedLocations::contains(loc) } - fn handle_fee(fee: MultiAssets, context: Option<&XcmContext>, reason: FeeReason) { + fn handle_fee(fee: Assets, context: Option<&XcmContext>, reason: FeeReason) { FeeHandler::handle_fee(fee, context, reason); } } @@ -76,7 +71,7 @@ impl, FeeHandler: HandleFee> FeeManager /// Try to deposit the given fee in the specified account. /// Burns the fee in case of a failure. pub fn deposit_or_burn_fee>( - fee: MultiAssets, + fee: Assets, context: Option<&XcmContext>, receiver: AccountId, ) { @@ -109,13 +104,9 @@ impl< ReceiverAccount: Get, > HandleFee for XcmFeeToAccount { - fn handle_fee( - fee: MultiAssets, - context: Option<&XcmContext>, - _reason: FeeReason, - ) -> MultiAssets { + fn handle_fee(fee: Assets, context: Option<&XcmContext>, _reason: FeeReason) -> Assets { deposit_or_burn_fee::(fee, context, ReceiverAccount::get()); - MultiAssets::new() + Assets::new() } } diff --git a/polkadot/xcm/xcm-builder/src/filter_asset_location.rs b/polkadot/xcm/xcm-builder/src/filter_asset_location.rs index df81f536f7b..d80c5d70dee 100644 --- a/polkadot/xcm/xcm-builder/src/filter_asset_location.rs +++ b/polkadot/xcm/xcm-builder/src/filter_asset_location.rs @@ -14,28 +14,26 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! Various implementations of `ContainsPair` or -//! `Contains<(MultiLocation, Vec)>`. +//! Various implementations of `ContainsPair` or +//! `Contains<(Location, Vec)>`. use frame_support::traits::{Contains, ContainsPair, Get}; use sp_std::{marker::PhantomData, vec::Vec}; -use xcm::latest::{AssetId::Concrete, MultiAsset, MultiAssetFilter, MultiLocation, WildMultiAsset}; +use xcm::latest::{Asset, AssetFilter, AssetId, Location, WildAsset}; /// Accepts an asset iff it is a native asset. pub struct NativeAsset; -impl ContainsPair for NativeAsset { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl ContainsPair for NativeAsset { + fn contains(asset: &Asset, origin: &Location) -> bool { log::trace!(target: "xcm::contains", "NativeAsset asset: {:?}, origin: {:?}", asset, origin); - matches!(asset.id, Concrete(ref id) if id == origin) + matches!(asset.id, AssetId(ref id) if id == origin) } } /// Accepts an asset if it is contained in the given `T`'s `Get` implementation. pub struct Case(PhantomData); -impl> ContainsPair - for Case -{ - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl> ContainsPair for Case { + fn contains(asset: &Asset, origin: &Location) -> bool { log::trace!(target: "xcm::contains", "Case asset: {:?}, origin: {:?}", asset, origin); let (a, o) = T::get(); a.matches(asset) && &o == origin @@ -44,18 +42,18 @@ impl> ContainsPair( - sp_std::marker::PhantomData<(Location, AssetFilters)>, +/// the `AssetFilter` instances provided by the `Get` implementation of `AssetFilters`. +pub struct LocationWithAssetFilters( + sp_std::marker::PhantomData<(LocationFilter, AssetFilters)>, ); -impl, AssetFilters: Get>> - Contains<(MultiLocation, Vec)> for LocationWithAssetFilters +impl, AssetFilters: Get>> + Contains<(Location, Vec)> for LocationWithAssetFilters { - fn contains((location, assets): &(MultiLocation, Vec)) -> bool { + fn contains((location, assets): &(Location, Vec)) -> bool { log::trace!(target: "xcm::contains", "LocationWithAssetFilters location: {:?}, assets: {:?}", location, assets); // `location` must match the `Location` filter. - if !Location::contains(location) { + if !LocationFilter::contains(location) { return false } @@ -72,12 +70,12 @@ impl, AssetFilters: Get> } } -/// Implementation of `Get>` which accepts every asset. +/// Implementation of `Get>` which accepts every asset. /// (For example, it can be used with `LocationWithAssetFilters`). pub struct AllAssets; -impl Get> for AllAssets { - fn get() -> Vec { - sp_std::vec![MultiAssetFilter::Wild(WildMultiAsset::All)] +impl Get> for AllAssets { + fn get() -> Vec { + sp_std::vec![AssetFilter::Wild(WildAsset::All)] } } @@ -90,24 +88,24 @@ mod tests { #[test] fn location_with_asset_filters_works() { frame_support::parameter_types! { - pub ParaA: MultiLocation = MultiLocation::new(1, X1(Parachain(1001))); - pub ParaB: MultiLocation = MultiLocation::new(1, X1(Parachain(1002))); - pub ParaC: MultiLocation = MultiLocation::new(1, X1(Parachain(1003))); + pub ParaA: Location = Location::new(1, [Parachain(1001)]); + pub ParaB: Location = Location::new(1, [Parachain(1002)]); + pub ParaC: Location = Location::new(1, [Parachain(1003)]); - pub AssetXLocation: MultiLocation = MultiLocation::new(1, X1(GeneralIndex(1111))); - pub AssetYLocation: MultiLocation = MultiLocation::new(1, X1(GeneralIndex(2222))); - pub AssetZLocation: MultiLocation = MultiLocation::new(1, X1(GeneralIndex(3333))); + pub AssetXLocation: Location = Location::new(1, [GeneralIndex(1111)]); + pub AssetYLocation: Location = Location::new(1, [GeneralIndex(2222)]); + pub AssetZLocation: Location = Location::new(1, [GeneralIndex(3333)]); - pub OnlyAssetXOrAssetY: sp_std::vec::Vec = sp_std::vec![ - Wild(AllOf { fun: WildFungible, id: Concrete(AssetXLocation::get()) }), - Wild(AllOf { fun: WildFungible, id: Concrete(AssetYLocation::get()) }), + pub OnlyAssetXOrAssetY: sp_std::vec::Vec = sp_std::vec![ + Wild(AllOf { fun: WildFungible, id: AssetId(AssetXLocation::get()) }), + Wild(AllOf { fun: WildFungible, id: AssetId(AssetYLocation::get()) }), ]; - pub OnlyAssetZ: sp_std::vec::Vec = sp_std::vec![ - Wild(AllOf { fun: WildFungible, id: Concrete(AssetZLocation::get()) }) + pub OnlyAssetZ: sp_std::vec::Vec = sp_std::vec![ + Wild(AllOf { fun: WildFungible, id: AssetId(AssetZLocation::get()) }) ]; } - let test_data: Vec<(MultiLocation, Vec, bool)> = vec![ + let test_data: Vec<(Location, Vec, bool)> = vec![ (ParaA::get(), vec![(AssetXLocation::get(), 1).into()], true), (ParaA::get(), vec![(AssetYLocation::get(), 1).into()], true), (ParaA::get(), vec![(AssetZLocation::get(), 1).into()], false), @@ -202,7 +200,7 @@ mod tests { for (location, assets, expected_result) in test_data { assert_eq!( - Filter::contains(&(location, assets.clone())), + Filter::contains(&(location.clone(), assets.clone())), expected_result, "expected_result: {expected_result} not matched for (location, assets): ({:?}, {:?})!", location, assets, ) diff --git a/polkadot/xcm/xcm-builder/src/fungible_adapter.rs b/polkadot/xcm/xcm-builder/src/fungible_adapter.rs index 90608faa447..7bea8cdf957 100644 --- a/polkadot/xcm/xcm-builder/src/fungible_adapter.rs +++ b/polkadot/xcm/xcm-builder/src/fungible_adapter.rs @@ -25,7 +25,10 @@ use frame_support::traits::{ }; use sp_std::{marker::PhantomData, prelude::*, result}; use xcm::latest::prelude::*; -use xcm_executor::traits::{ConvertLocation, Error as MatchError, MatchesFungible, TransactAsset}; +use xcm_executor::{ + traits::{ConvertLocation, Error as MatchError, MatchesFungible, TransactAsset}, + AssetsInHolding, +}; /// [`TransactAsset`] implementation that allows the use of a [`fungible`] implementation for /// handling an asset in the XCM executor. @@ -41,11 +44,11 @@ impl< > TransactAsset for FungibleTransferAdapter { fn internal_transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, _context: &XcmContext, - ) -> result::Result { + ) -> result::Result { log::trace!( target: "xcm::fungible_adapter", "internal_transfer_asset what: {:?}, from: {:?}, to: {:?}", @@ -111,11 +114,7 @@ impl< > TransactAsset for FungibleMutateAdapter { - fn can_check_in( - _origin: &MultiLocation, - what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, what: &Asset, _context: &XcmContext) -> XcmResult { log::trace!( target: "xcm::fungible_adapter", "can_check_in origin: {:?}, what: {:?}", @@ -132,7 +131,7 @@ impl< } } - fn check_in(_origin: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + fn check_in(_origin: &Location, what: &Asset, _context: &XcmContext) { log::trace!( target: "xcm::fungible_adapter", "check_in origin: {:?}, what: {:?}", @@ -149,7 +148,7 @@ impl< } } - fn can_check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) -> XcmResult { + fn can_check_out(_dest: &Location, what: &Asset, _context: &XcmContext) -> XcmResult { log::trace!( target: "xcm::fungible_adapter", "check_out dest: {:?}, what: {:?}", @@ -166,7 +165,7 @@ impl< } } - fn check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + fn check_out(_dest: &Location, what: &Asset, _context: &XcmContext) { log::trace!( target: "xcm::fungible_adapter", "check_out dest: {:?}, what: {:?}", @@ -184,11 +183,7 @@ impl< } } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - _context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, _context: Option<&XcmContext>) -> XcmResult { log::trace!( target: "xcm::fungible_adapter", "deposit_asset what: {:?}, who: {:?}", @@ -203,10 +198,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, _context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { log::trace!( target: "xcm::fungible_adapter", "deposit_asset what: {:?}, who: {:?}", @@ -236,7 +231,7 @@ impl< > TransactAsset for FungibleAdapter { - fn can_check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_in(origin: &Location, what: &Asset, context: &XcmContext) -> XcmResult { FungibleMutateAdapter::< Fungible, Matcher, @@ -246,7 +241,7 @@ impl< >::can_check_in(origin, what, context) } - fn check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_in(origin: &Location, what: &Asset, context: &XcmContext) { FungibleMutateAdapter::< Fungible, Matcher, @@ -256,7 +251,7 @@ impl< >::check_in(origin, what, context) } - fn can_check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_out(dest: &Location, what: &Asset, context: &XcmContext) -> XcmResult { FungibleMutateAdapter::< Fungible, Matcher, @@ -266,7 +261,7 @@ impl< >::can_check_out(dest, what, context) } - fn check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_out(dest: &Location, what: &Asset, context: &XcmContext) { FungibleMutateAdapter::< Fungible, Matcher, @@ -276,11 +271,7 @@ impl< >::check_out(dest, what, context) } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, context: Option<&XcmContext>) -> XcmResult { FungibleMutateAdapter::< Fungible, Matcher, @@ -291,10 +282,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, maybe_context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { FungibleMutateAdapter::< Fungible, Matcher, @@ -305,11 +296,11 @@ impl< } fn internal_transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, context: &XcmContext, - ) -> result::Result { + ) -> result::Result { FungibleTransferAdapter::::internal_transfer_asset( what, from, to, context ) diff --git a/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs b/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs index 63ce608824e..4574d5ed4c6 100644 --- a/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs +++ b/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs @@ -38,11 +38,11 @@ impl< > TransactAsset for FungiblesTransferAdapter { fn internal_transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, _context: &XcmContext, - ) -> result::Result { + ) -> result::Result { log::trace!( target: "xcm::fungibles_adapter", "internal_transfer_asset what: {:?}, from: {:?}, to: {:?}", @@ -198,11 +198,7 @@ impl< CheckingAccount, > { - fn can_check_in( - _origin: &MultiLocation, - what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, what: &Asset, _context: &XcmContext) -> XcmResult { log::trace!( target: "xcm::fungibles_adapter", "can_check_in origin: {:?}, what: {:?}", @@ -219,7 +215,7 @@ impl< } } - fn check_in(_origin: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + fn check_in(_origin: &Location, what: &Asset, _context: &XcmContext) { log::trace!( target: "xcm::fungibles_adapter", "check_in origin: {:?}, what: {:?}", @@ -236,11 +232,7 @@ impl< } } - fn can_check_out( - _origin: &MultiLocation, - what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_out(_origin: &Location, what: &Asset, _context: &XcmContext) -> XcmResult { log::trace!( target: "xcm::fungibles_adapter", "can_check_in origin: {:?}, what: {:?}", @@ -257,7 +249,7 @@ impl< } } - fn check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + fn check_out(_dest: &Location, what: &Asset, _context: &XcmContext) { log::trace!( target: "xcm::fungibles_adapter", "check_out dest: {:?}, what: {:?}", @@ -274,11 +266,7 @@ impl< } } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - _context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, _context: Option<&XcmContext>) -> XcmResult { log::trace!( target: "xcm::fungibles_adapter", "deposit_asset what: {:?}, who: {:?}", @@ -294,10 +282,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, _maybe_context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { log::trace!( target: "xcm::fungibles_adapter", "withdraw_asset what: {:?}, who: {:?}", @@ -331,7 +319,7 @@ impl< > TransactAsset for FungiblesAdapter { - fn can_check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_in(origin: &Location, what: &Asset, context: &XcmContext) -> XcmResult { FungiblesMutateAdapter::< Assets, Matcher, @@ -342,7 +330,7 @@ impl< >::can_check_in(origin, what, context) } - fn check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_in(origin: &Location, what: &Asset, context: &XcmContext) { FungiblesMutateAdapter::< Assets, Matcher, @@ -353,7 +341,7 @@ impl< >::check_in(origin, what, context) } - fn can_check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_out(dest: &Location, what: &Asset, context: &XcmContext) -> XcmResult { FungiblesMutateAdapter::< Assets, Matcher, @@ -364,7 +352,7 @@ impl< >::can_check_out(dest, what, context) } - fn check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_out(dest: &Location, what: &Asset, context: &XcmContext) { FungiblesMutateAdapter::< Assets, Matcher, @@ -375,11 +363,7 @@ impl< >::check_out(dest, what, context) } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, context: Option<&XcmContext>) -> XcmResult { FungiblesMutateAdapter::< Assets, Matcher, @@ -391,10 +375,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, maybe_context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { FungiblesMutateAdapter::< Assets, Matcher, @@ -406,11 +390,11 @@ impl< } fn internal_transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, context: &XcmContext, - ) -> result::Result { + ) -> result::Result { FungiblesTransferAdapter::::internal_transfer_asset( what, from, to, context ) diff --git a/polkadot/xcm/xcm-builder/src/lib.rs b/polkadot/xcm/xcm-builder/src/lib.rs index e7431ae0254..c00cd62e872 100644 --- a/polkadot/xcm/xcm-builder/src/lib.rs +++ b/polkadot/xcm/xcm-builder/src/lib.rs @@ -47,11 +47,11 @@ pub use origin_conversion::{ }; mod asset_conversion; +#[allow(deprecated)] +pub use asset_conversion::ConvertedConcreteAssetId; pub use asset_conversion::{ - AsPrefixedGeneralIndex, ConvertedAbstractId, ConvertedConcreteId, MatchedConvertedConcreteId, + AsPrefixedGeneralIndex, ConvertedConcreteId, MatchedConvertedConcreteId, V4V3LocationConverter, }; -#[allow(deprecated)] -pub use asset_conversion::{ConvertedAbstractAssetId, ConvertedConcreteAssetId}; mod barriers; pub use barriers::{ @@ -96,7 +96,7 @@ mod matches_location; pub use matches_location::{StartsWith, StartsWithExplicitGlobalConsensus}; mod matches_token; -pub use matches_token::{IsAbstract, IsConcrete}; +pub use matches_token::IsConcrete; mod matcher; pub use matcher::{CreateMatcher, MatchXcm, Matcher}; diff --git a/polkadot/xcm/xcm-builder/src/location_conversion.rs b/polkadot/xcm/xcm-builder/src/location_conversion.rs index 25d16f7eb8c..c9553030817 100644 --- a/polkadot/xcm/xcm-builder/src/location_conversion.rs +++ b/polkadot/xcm/xcm-builder/src/location_conversion.rs @@ -27,12 +27,12 @@ use xcm_executor::traits::ConvertLocation; pub trait DescribeLocation { /// Create a description of the given `location` if possible. No two locations should have the /// same descriptor. - fn describe_location(location: &MultiLocation) -> Option>; + fn describe_location(location: &Location) -> Option>; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl DescribeLocation for Tuple { - fn describe_location(l: &MultiLocation) -> Option> { + fn describe_location(l: &Location) -> Option> { for_tuples!( #( match Tuple::describe_location(l) { Some(result) => return Some(result), @@ -45,9 +45,9 @@ impl DescribeLocation for Tuple { pub struct DescribeTerminus; impl DescribeLocation for DescribeTerminus { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, &l.interior) { - (0, Here) => Some(Vec::new()), + fn describe_location(l: &Location) -> Option> { + match l.unpack() { + (0, []) => Some(Vec::new()), _ => return None, } } @@ -55,10 +55,9 @@ impl DescribeLocation for DescribeTerminus { pub struct DescribePalletTerminal; impl DescribeLocation for DescribePalletTerminal { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, &l.interior) { - (0, X1(PalletInstance(i))) => - Some((b"Pallet", Compact::::from(*i as u32)).encode()), + fn describe_location(l: &Location) -> Option> { + match l.unpack() { + (0, [PalletInstance(i)]) => Some((b"Pallet", Compact::::from(*i as u32)).encode()), _ => return None, } } @@ -66,9 +65,9 @@ impl DescribeLocation for DescribePalletTerminal { pub struct DescribeAccountId32Terminal; impl DescribeLocation for DescribeAccountId32Terminal { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, &l.interior) { - (0, X1(AccountId32 { id, .. })) => Some((b"AccountId32", id).encode()), + fn describe_location(l: &Location) -> Option> { + match l.unpack() { + (0, [AccountId32 { id, .. }]) => Some((b"AccountId32", id).encode()), _ => return None, } } @@ -76,9 +75,9 @@ impl DescribeLocation for DescribeAccountId32Terminal { pub struct DescribeAccountKey20Terminal; impl DescribeLocation for DescribeAccountKey20Terminal { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, &l.interior) { - (0, X1(AccountKey20 { key, .. })) => Some((b"AccountKey20", key).encode()), + fn describe_location(l: &Location) -> Option> { + match l.unpack() { + (0, [AccountKey20 { key, .. }]) => Some((b"AccountKey20", key).encode()), _ => return None, } } @@ -89,9 +88,9 @@ impl DescribeLocation for DescribeAccountKey20Terminal { pub struct DescribeTreasuryVoiceTerminal; impl DescribeLocation for DescribeTreasuryVoiceTerminal { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, &l.interior) { - (0, X1(Plurality { id: BodyId::Treasury, part: BodyPart::Voice })) => + fn describe_location(location: &Location) -> Option> { + match location.unpack() { + (0, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]) => Some((b"Treasury", b"Voice").encode()), _ => None, } @@ -102,9 +101,9 @@ pub type DescribeAccountIdTerminal = (DescribeAccountId32Terminal, DescribeAccou pub struct DescribeBodyTerminal; impl DescribeLocation for DescribeBodyTerminal { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, &l.interior) { - (0, X1(Plurality { id, part })) => Some((b"Body", id, part).encode()), + fn describe_location(l: &Location) -> Option> { + match l.unpack() { + (0, [Plurality { id, part }]) => Some((b"Body", id, part).encode()), _ => return None, } } @@ -121,20 +120,21 @@ pub type DescribeAllTerminal = ( pub struct DescribeFamily(PhantomData); impl DescribeLocation for DescribeFamily { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, l.interior.first()) { + fn describe_location(l: &Location) -> Option> { + match (l.parent_count(), l.first_interior()) { (0, Some(Parachain(index))) => { - let tail = l.interior.split_first().0; + let tail = l.clone().split_first_interior().0; let interior = Suffix::describe_location(&tail.into())?; Some((b"ChildChain", Compact::::from(*index), interior).encode()) }, (1, Some(Parachain(index))) => { - let tail = l.interior.split_first().0; - let interior = Suffix::describe_location(&tail.into())?; + let tail_junctions = l.interior().clone().split_first().0; + let tail = Location::new(0, tail_junctions); + let interior = Suffix::describe_location(&tail)?; Some((b"SiblingChain", Compact::::from(*index), interior).encode()) }, (1, _) => { - let tail = l.interior.into(); + let tail = l.interior().clone().into(); let interior = Suffix::describe_location(&tail)?; Some((b"ParentChain", interior).encode()) }, @@ -147,7 +147,7 @@ pub struct HashedDescription(PhantomData<(AccountId, Descri impl + Clone, Describe: DescribeLocation> ConvertLocation for HashedDescription { - fn convert_location(value: &MultiLocation) -> Option { + fn convert_location(value: &Location) -> Option { Some(blake2_256(&Describe::describe_location(value)?).into()) } } @@ -156,34 +156,26 @@ impl + Clone, Describe: DescribeLocation> ConvertLocat /// are recommended to use the more extensible `HashedDescription` type. pub struct LegacyDescribeForeignChainAccount; impl DescribeLocation for LegacyDescribeForeignChainAccount { - fn describe_location(location: &MultiLocation) -> Option> { - Some(match location { + fn describe_location(location: &Location) -> Option> { + Some(match location.unpack() { // Used on the relay chain for sending paras that use 32 byte accounts - MultiLocation { - parents: 0, - interior: X2(Parachain(para_id), AccountId32 { id, .. }), - } => LegacyDescribeForeignChainAccount::from_para_32(para_id, id, 0), + (0, [Parachain(para_id), AccountId32 { id, .. }]) => + LegacyDescribeForeignChainAccount::from_para_32(para_id, id, 0), // Used on the relay chain for sending paras that use 20 byte accounts - MultiLocation { - parents: 0, - interior: X2(Parachain(para_id), AccountKey20 { key, .. }), - } => LegacyDescribeForeignChainAccount::from_para_20(para_id, key, 0), + (0, [Parachain(para_id), AccountKey20 { key, .. }]) => + LegacyDescribeForeignChainAccount::from_para_20(para_id, key, 0), // Used on para-chain for sending paras that use 32 byte accounts - MultiLocation { - parents: 1, - interior: X2(Parachain(para_id), AccountId32 { id, .. }), - } => LegacyDescribeForeignChainAccount::from_para_32(para_id, id, 1), + (1, [Parachain(para_id), AccountId32 { id, .. }]) => + LegacyDescribeForeignChainAccount::from_para_32(para_id, id, 1), // Used on para-chain for sending paras that use 20 byte accounts - MultiLocation { - parents: 1, - interior: X2(Parachain(para_id), AccountKey20 { key, .. }), - } => LegacyDescribeForeignChainAccount::from_para_20(para_id, key, 1), + (1, [Parachain(para_id), AccountKey20 { key, .. }]) => + LegacyDescribeForeignChainAccount::from_para_20(para_id, key, 1), // Used on para-chain for sending from the relay chain - MultiLocation { parents: 1, interior: X1(AccountId32 { id, .. }) } => + (1, [AccountId32 { id, .. }]) => LegacyDescribeForeignChainAccount::from_relay_32(id, 1), // No other conversions provided @@ -278,16 +270,16 @@ pub struct Account32Hash(PhantomData<(Network, AccountId)>); impl>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone> ConvertLocation for Account32Hash { - fn convert_location(location: &MultiLocation) -> Option { + fn convert_location(location: &Location) -> Option { Some(("multiloc", location).using_encoded(blake2_256).into()) } } -/// A [`MultiLocation`] consisting of a single `Parent` [`Junction`] will be converted to the +/// A [`Location`] consisting of a single `Parent` [`Junction`] will be converted to the /// parent `AccountId`. pub struct ParentIsPreset(PhantomData); impl ConvertLocation for ParentIsPreset { - fn convert_location(location: &MultiLocation) -> Option { + fn convert_location(location: &Location) -> Option { if location.contains_parents_only(1) { Some( b"Parent" @@ -304,10 +296,9 @@ pub struct ChildParachainConvertsVia(PhantomData<(ParaId, Acc impl + Into + AccountIdConversion, AccountId: Clone> ConvertLocation for ChildParachainConvertsVia { - fn convert_location(location: &MultiLocation) -> Option { - match location { - MultiLocation { parents: 0, interior: X1(Parachain(id)) } => - Some(ParaId::from(*id).into_account_truncating()), + fn convert_location(location: &Location) -> Option { + match location.unpack() { + (0, [Parachain(id)]) => Some(ParaId::from(*id).into_account_truncating()), _ => None, } } @@ -317,10 +308,9 @@ pub struct SiblingParachainConvertsVia(PhantomData<(ParaId, A impl + Into + AccountIdConversion, AccountId: Clone> ConvertLocation for SiblingParachainConvertsVia { - fn convert_location(location: &MultiLocation) -> Option { - match location { - MultiLocation { parents: 1, interior: X1(Parachain(id)) } => - Some(ParaId::from(*id).into_account_truncating()), + fn convert_location(location: &Location) -> Option { + match location.unpack() { + (1, [Parachain(id)]) => Some(ParaId::from(*id).into_account_truncating()), _ => None, } } @@ -331,15 +321,13 @@ pub struct AccountId32Aliases(PhantomData<(Network, AccountI impl>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone> ConvertLocation for AccountId32Aliases { - fn convert_location(location: &MultiLocation) -> Option { - let id = match *location { - MultiLocation { parents: 0, interior: X1(AccountId32 { id, network: None }) } => id, - MultiLocation { parents: 0, interior: X1(AccountId32 { id, network }) } - if network == Network::get() => - id, + fn convert_location(location: &Location) -> Option { + let id = match location.unpack() { + (0, [AccountId32 { id, network: None }]) => id, + (0, [AccountId32 { id, network }]) if *network == Network::get() => id, _ => return None, }; - Some(id.into()) + Some((*id).into()) } } @@ -351,25 +339,23 @@ pub struct LocalTreasuryVoiceConvertsVia( impl, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone> ConvertLocation for LocalTreasuryVoiceConvertsVia { - fn convert_location(location: &MultiLocation) -> Option { - match *location { - MultiLocation { - parents: 0, - interior: X1(Plurality { id: BodyId::Treasury, part: BodyPart::Voice }), - } => Some((TreasuryAccount::get().into() as [u8; 32]).into()), + fn convert_location(location: &Location) -> Option { + match location.unpack() { + (0, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]) => + Some((TreasuryAccount::get().into() as [u8; 32]).into()), _ => None, } } } /// Conversion implementation which converts from a `[u8; 32]`-based `AccountId` into a -/// `MultiLocation` consisting solely of a `AccountId32` junction with a fixed value for its +/// `Location` consisting solely of a `AccountId32` junction with a fixed value for its /// network (provided by `Network`) and the `AccountId`'s `[u8; 32]` datum for the `id`. pub struct AliasesIntoAccountId32(PhantomData<(Network, AccountId)>); impl<'a, Network: Get>, AccountId: Clone + Into<[u8; 32]> + Clone> - TryConvert<&'a AccountId, MultiLocation> for AliasesIntoAccountId32 + TryConvert<&'a AccountId, Location> for AliasesIntoAccountId32 { - fn try_convert(who: &AccountId) -> Result { + fn try_convert(who: &AccountId) -> Result { Ok(AccountId32 { network: Network::get(), id: who.clone().into() }.into()) } } @@ -378,15 +364,13 @@ pub struct AccountKey20Aliases(PhantomData<(Network, Account impl>, AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone> ConvertLocation for AccountKey20Aliases { - fn convert_location(location: &MultiLocation) -> Option { - let key = match *location { - MultiLocation { parents: 0, interior: X1(AccountKey20 { key, network: None }) } => key, - MultiLocation { parents: 0, interior: X1(AccountKey20 { key, network }) } - if network == Network::get() => - key, + fn convert_location(location: &Location) -> Option { + let key = match location.unpack() { + (0, [AccountKey20 { key, network: None }]) => key, + (0, [AccountKey20 { key, network }]) if *network == Network::get() => key, _ => return None, }; - Some(key.into()) + Some((*key).into()) } } @@ -402,10 +386,10 @@ impl>, AccountId: From<[u8; 20]> + Into<[u8; 20]> pub struct GlobalConsensusConvertsFor( PhantomData<(UniversalLocation, AccountId)>, ); -impl, AccountId: From<[u8; 32]> + Clone> +impl, AccountId: From<[u8; 32]> + Clone> ConvertLocation for GlobalConsensusConvertsFor { - fn convert_location(location: &MultiLocation) -> Option { + fn convert_location(location: &Location) -> Option { let universal_source = UniversalLocation::get(); log::trace!( target: "xcm::location_conversion", @@ -413,7 +397,7 @@ impl, AccountId: From<[u8; 32]> + universal_source, location, ); let (remote_network, remote_location) = - ensure_is_remote(universal_source, *location).ok()?; + ensure_is_remote(universal_source, location.clone()).ok()?; match remote_location { Here => Some(AccountId::from(Self::from_params(&remote_network))), @@ -445,21 +429,21 @@ impl GlobalConsensusConvertsFor( PhantomData<(UniversalLocation, AccountId)>, ); -impl, AccountId: From<[u8; 32]> + Clone> +impl, AccountId: From<[u8; 32]> + Clone> ConvertLocation for GlobalConsensusParachainConvertsFor { - fn convert_location(location: &MultiLocation) -> Option { + fn convert_location(location: &Location) -> Option { let universal_source = UniversalLocation::get(); log::trace!( target: "xcm::location_conversion", "GlobalConsensusParachainConvertsFor universal_source: {:?}, location: {:?}", universal_source, location, ); - let devolved = ensure_is_remote(universal_source, *location).ok()?; + let devolved = ensure_is_remote(universal_source, location.clone()).ok()?; let (remote_network, remote_location) = devolved; - match remote_location { - X1(Parachain(remote_network_para_id)) => + match remote_location.as_slice() { + [Parachain(remote_network_para_id)] => Some(AccountId::from(Self::from_params(&remote_network, &remote_network_para_id))), _ => None, } @@ -509,12 +493,12 @@ mod tests { #[test] fn inverter_works_in_tree() { parameter_types! { - pub UniversalLocation: InteriorMultiLocation = X3(Parachain(1), account20(), account20()); + pub UniversalLocation: InteriorLocation = [Parachain(1), account20(), account20()].into(); } - let input = MultiLocation::new(3, X2(Parachain(2), account32())); + let input = Location::new(3, [Parachain(2), account32()]); let inverted = UniversalLocation::get().invert_target(&input).unwrap(); - assert_eq!(inverted, MultiLocation::new(2, X3(Parachain(1), account20(), account20()))); + assert_eq!(inverted, Location::new(2, [Parachain(1), account20(), account20()])); } // Network Topology @@ -524,12 +508,12 @@ mod tests { #[test] fn inverter_uses_context_as_inverted_location() { parameter_types! { - pub UniversalLocation: InteriorMultiLocation = X2(account20(), account20()); + pub UniversalLocation: InteriorLocation = [account20(), account20()].into(); } - let input = MultiLocation::grandparent(); + let input = Location::new(2, Here); let inverted = UniversalLocation::get().invert_target(&input).unwrap(); - assert_eq!(inverted, X2(account20(), account20()).into()); + assert_eq!(inverted, [account20(), account20()].into()); } // Network Topology @@ -539,10 +523,10 @@ mod tests { #[test] fn inverter_uses_only_child_on_missing_context() { parameter_types! { - pub UniversalLocation: InteriorMultiLocation = PalletInstance(5).into(); + pub UniversalLocation: InteriorLocation = PalletInstance(5).into(); } - let input = MultiLocation::grandparent(); + let input = Location::new(2, Here); let inverted = UniversalLocation::get().invert_target(&input).unwrap(); assert_eq!(inverted, (OnlyChild, PalletInstance(5)).into()); } @@ -550,10 +534,10 @@ mod tests { #[test] fn inverter_errors_when_location_is_too_large() { parameter_types! { - pub UniversalLocation: InteriorMultiLocation = Here; + pub UniversalLocation: InteriorLocation = Here; } - let input = MultiLocation { parents: 99, interior: X1(Parachain(88)) }; + let input = Location { parents: 99, interior: [Parachain(88)].into() }; let inverted = UniversalLocation::get().invert_target(&input); assert_eq!(inverted, Err(())); } @@ -561,8 +545,8 @@ mod tests { #[test] fn global_consensus_converts_for_works() { parameter_types! { - pub UniversalLocationInNetwork1: InteriorMultiLocation = X2(GlobalConsensus(ByGenesis([1; 32])), Parachain(1234)); - pub UniversalLocationInNetwork2: InteriorMultiLocation = X2(GlobalConsensus(ByGenesis([2; 32])), Parachain(1234)); + pub UniversalLocationInNetwork1: InteriorLocation = [GlobalConsensus(ByGenesis([1; 32])), Parachain(1234)].into(); + pub UniversalLocationInNetwork2: InteriorLocation = [GlobalConsensus(ByGenesis([2; 32])), Parachain(1234)].into(); } let network_1 = UniversalLocationInNetwork1::get().global_consensus().expect("NetworkId"); let network_2 = UniversalLocationInNetwork2::get().global_consensus().expect("NetworkId"); @@ -571,17 +555,17 @@ mod tests { let network_5 = ByGenesis([5; 32]); let test_data = vec![ - (MultiLocation::parent(), false), - (MultiLocation::new(0, Here), false), - (MultiLocation::new(0, X1(GlobalConsensus(network_1))), false), - (MultiLocation::new(1, X1(GlobalConsensus(network_1))), false), - (MultiLocation::new(2, X1(GlobalConsensus(network_1))), false), - (MultiLocation::new(0, X1(GlobalConsensus(network_2))), false), - (MultiLocation::new(1, X1(GlobalConsensus(network_2))), false), - (MultiLocation::new(2, X1(GlobalConsensus(network_2))), true), - (MultiLocation::new(0, X2(GlobalConsensus(network_2), Parachain(1000))), false), - (MultiLocation::new(1, X2(GlobalConsensus(network_2), Parachain(1000))), false), - (MultiLocation::new(2, X2(GlobalConsensus(network_2), Parachain(1000))), false), + (Location::parent(), false), + (Location::new(0, Here), false), + (Location::new(0, [GlobalConsensus(network_1)]), false), + (Location::new(1, [GlobalConsensus(network_1)]), false), + (Location::new(2, [GlobalConsensus(network_1)]), false), + (Location::new(0, [GlobalConsensus(network_2)]), false), + (Location::new(1, [GlobalConsensus(network_2)]), false), + (Location::new(2, [GlobalConsensus(network_2)]), true), + (Location::new(0, [GlobalConsensus(network_2), Parachain(1000)]), false), + (Location::new(1, [GlobalConsensus(network_2), Parachain(1000)]), false), + (Location::new(2, [GlobalConsensus(network_2), Parachain(1000)]), false), ]; for (location, expected_result) in test_data { @@ -596,14 +580,14 @@ mod tests { "expected_result: {}, but conversion passed: {:?}, location: {:?}", expected_result, account, location ); - match &location { - MultiLocation { interior: X1(GlobalConsensus(network)), .. } => + match location.unpack() { + (_, [GlobalConsensus(network)]) => assert_eq!( account, GlobalConsensusConvertsFor::::from_params(network), "expected_result: {}, but conversion passed: {:?}, location: {:?}", expected_result, account, location ), - _ => panic!("expected_result: {}, conversion passed: {:?}, but MultiLocation does not match expected pattern, location: {:?}", expected_result, account, location) + _ => panic!("expected_result: {}, conversion passed: {:?}, but Location does not match expected pattern, location: {:?}", expected_result, account, location) } }, None => { @@ -619,32 +603,32 @@ mod tests { // all success let res_1_gc_network_3 = GlobalConsensusConvertsFor::::convert_location( - &MultiLocation::new(2, X1(GlobalConsensus(network_3))), + &Location::new(2, [GlobalConsensus(network_3)]), ) .expect("conversion is ok"); let res_2_gc_network_3 = GlobalConsensusConvertsFor::::convert_location( - &MultiLocation::new(2, X1(GlobalConsensus(network_3))), + &Location::new(2, [GlobalConsensus(network_3)]), ) .expect("conversion is ok"); let res_1_gc_network_4 = GlobalConsensusConvertsFor::::convert_location( - &MultiLocation::new(2, X1(GlobalConsensus(network_4))), + &Location::new(2, [GlobalConsensus(network_4)]), ) .expect("conversion is ok"); let res_2_gc_network_4 = GlobalConsensusConvertsFor::::convert_location( - &MultiLocation::new(2, X1(GlobalConsensus(network_4))), + &Location::new(2, [GlobalConsensus(network_4)]), ) .expect("conversion is ok"); let res_1_gc_network_5 = GlobalConsensusConvertsFor::::convert_location( - &MultiLocation::new(2, X1(GlobalConsensus(network_5))), + &Location::new(2, [GlobalConsensus(network_5)]), ) .expect("conversion is ok"); let res_2_gc_network_5 = GlobalConsensusConvertsFor::::convert_location( - &MultiLocation::new(2, X1(GlobalConsensus(network_5))), + &Location::new(2, [GlobalConsensus(network_5)]), ) .expect("conversion is ok"); @@ -660,42 +644,30 @@ mod tests { #[test] fn global_consensus_parachain_converts_for_works() { parameter_types! { - pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(ByGenesis([9; 32])), Parachain(1234)); + pub UniversalLocation: InteriorLocation = [GlobalConsensus(ByGenesis([9; 32])), Parachain(1234)].into(); } let test_data = vec![ - (MultiLocation::parent(), false), - (MultiLocation::new(0, X1(Parachain(1000))), false), - (MultiLocation::new(1, X1(Parachain(1000))), false), + (Location::parent(), false), + (Location::new(0, [Parachain(1000)]), false), + (Location::new(1, [Parachain(1000)]), false), ( - MultiLocation::new( + Location::new( 2, - X3( + [ GlobalConsensus(ByGenesis([0; 32])), Parachain(1000), AccountId32 { network: None, id: [1; 32].into() }, - ), + ], ), false, ), - (MultiLocation::new(2, X1(GlobalConsensus(ByGenesis([0; 32])))), false), - ( - MultiLocation::new(0, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), - false, - ), - ( - MultiLocation::new(1, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), - false, - ), - (MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), true), - ( - MultiLocation::new(3, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), - false, - ), - ( - MultiLocation::new(9, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), - false, - ), + (Location::new(2, [GlobalConsensus(ByGenesis([0; 32]))]), false), + (Location::new(0, [GlobalConsensus(ByGenesis([0; 32])), Parachain(1000)]), false), + (Location::new(1, [GlobalConsensus(ByGenesis([0; 32])), Parachain(1000)]), false), + (Location::new(2, [GlobalConsensus(ByGenesis([0; 32])), Parachain(1000)]), true), + (Location::new(3, [GlobalConsensus(ByGenesis([0; 32])), Parachain(1000)]), false), + (Location::new(9, [GlobalConsensus(ByGenesis([0; 32])), Parachain(1000)]), false), ]; for (location, expected_result) in test_data { @@ -710,8 +682,8 @@ mod tests { "expected_result: {}, but conversion passed: {:?}, location: {:?}", expected_result, account, location ); - match &location { - MultiLocation { interior: X2(GlobalConsensus(network), Parachain(para_id)), .. } => + match location.unpack() { + (_, [GlobalConsensus(network), Parachain(para_id)]) => assert_eq!( account, GlobalConsensusParachainConvertsFor::::from_params(network, para_id), @@ -720,7 +692,7 @@ mod tests { _ => assert_eq!( true, expected_result, - "expected_result: {}, conversion passed: {:?}, but MultiLocation does not match expected pattern, location: {:?}", expected_result, account, location + "expected_result: {}, conversion passed: {:?}, but Location does not match expected pattern, location: {:?}", expected_result, account, location ) } }, @@ -737,22 +709,22 @@ mod tests { // all success let res_gc_a_p1000 = GlobalConsensusParachainConvertsFor::::convert_location( - &MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([3; 32])), Parachain(1000))), + &Location::new(2, [GlobalConsensus(ByGenesis([3; 32])), Parachain(1000)]), ) .expect("conversion is ok"); let res_gc_a_p1001 = GlobalConsensusParachainConvertsFor::::convert_location( - &MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([3; 32])), Parachain(1001))), + &Location::new(2, [GlobalConsensus(ByGenesis([3; 32])), Parachain(1001)]), ) .expect("conversion is ok"); let res_gc_b_p1000 = GlobalConsensusParachainConvertsFor::::convert_location( - &MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([4; 32])), Parachain(1000))), + &Location::new(2, [GlobalConsensus(ByGenesis([4; 32])), Parachain(1000)]), ) .expect("conversion is ok"); let res_gc_b_p1001 = GlobalConsensusParachainConvertsFor::::convert_location( - &MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([4; 32])), Parachain(1001))), + &Location::new(2, [GlobalConsensus(ByGenesis([4; 32])), Parachain(1001)]), ) .expect("conversion is ok"); assert_ne!(res_gc_a_p1000, res_gc_a_p1001); @@ -765,9 +737,9 @@ mod tests { #[test] fn remote_account_convert_on_para_sending_para_32() { - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X2(Parachain(1), AccountId32 { network: None, id: [0u8; 32] }), + interior: [Parachain(1), AccountId32 { network: None, id: [0u8; 32] }].into(), }; let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -779,19 +751,20 @@ mod tests { rem_1 ); - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X2( + interior: [ Parachain(1), AccountId32 { network: Some(NetworkId::Polkadot), id: [0u8; 32] }, - ), + ] + .into(), }; assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1); - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X2(Parachain(2), AccountId32 { network: None, id: [0u8; 32] }), + interior: [Parachain(2), AccountId32 { network: None, id: [0u8; 32] }].into(), }; let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -808,9 +781,9 @@ mod tests { #[test] fn remote_account_convert_on_para_sending_para_20() { - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X2(Parachain(1), AccountKey20 { network: None, key: [0u8; 20] }), + interior: [Parachain(1), AccountKey20 { network: None, key: [0u8; 20] }].into(), }; let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -822,19 +795,20 @@ mod tests { rem_1 ); - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X2( + interior: [ Parachain(1), AccountKey20 { network: Some(NetworkId::Polkadot), key: [0u8; 20] }, - ), + ] + .into(), }; assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1); - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X2(Parachain(2), AccountKey20 { network: None, key: [0u8; 20] }), + interior: [Parachain(2), AccountKey20 { network: None, key: [0u8; 20] }].into(), }; let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -851,9 +825,9 @@ mod tests { #[test] fn remote_account_convert_on_para_sending_relay() { - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X1(AccountId32 { network: None, id: [0u8; 32] }), + interior: [AccountId32 { network: None, id: [0u8; 32] }].into(), }; let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -865,16 +839,16 @@ mod tests { rem_1 ); - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X1(AccountId32 { network: Some(NetworkId::Polkadot), id: [0u8; 32] }), + interior: [AccountId32 { network: Some(NetworkId::Polkadot), id: [0u8; 32] }].into(), }; assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1); - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X1(AccountId32 { network: None, id: [1u8; 32] }), + interior: [AccountId32 { network: None, id: [1u8; 32] }].into(), }; let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -891,9 +865,9 @@ mod tests { #[test] fn remote_account_convert_on_relay_sending_para_20() { - let mul = MultiLocation { + let mul = Location { parents: 0, - interior: X2(Parachain(1), AccountKey20 { network: None, key: [0u8; 20] }), + interior: [Parachain(1), AccountKey20 { network: None, key: [0u8; 20] }].into(), }; let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -905,9 +879,9 @@ mod tests { rem_1 ); - let mul = MultiLocation { + let mul = Location { parents: 0, - interior: X2(Parachain(2), AccountKey20 { network: None, key: [0u8; 20] }), + interior: [Parachain(2), AccountKey20 { network: None, key: [0u8; 20] }].into(), }; let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -924,9 +898,9 @@ mod tests { #[test] fn remote_account_convert_on_relay_sending_para_32() { - let mul = MultiLocation { + let mul = Location { parents: 0, - interior: X2(Parachain(1), AccountId32 { network: None, id: [0u8; 32] }), + interior: [Parachain(1), AccountId32 { network: None, id: [0u8; 32] }].into(), }; let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -938,19 +912,20 @@ mod tests { rem_1 ); - let mul = MultiLocation { + let mul = Location { parents: 0, - interior: X2( + interior: [ Parachain(1), AccountId32 { network: Some(NetworkId::Polkadot), id: [0u8; 32] }, - ), + ] + .into(), }; assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1); - let mul = MultiLocation { + let mul = Location { parents: 0, - interior: X2(Parachain(2), AccountId32 { network: None, id: [0u8; 32] }), + interior: [Parachain(2), AccountId32 { network: None, id: [0u8; 32] }].into(), }; let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -966,20 +941,18 @@ mod tests { } #[test] - fn remote_account_fails_with_bad_multilocation() { - let mul = MultiLocation { + fn remote_account_fails_with_bad_location() { + let mul = Location { parents: 1, - interior: X1(AccountKey20 { network: None, key: [0u8; 20] }), + interior: [AccountKey20 { network: None, key: [0u8; 20] }].into(), }; assert!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).is_none()); } #[test] fn remote_account_convert_on_para_sending_from_remote_para_treasury() { - let relay_treasury_to_para_location = MultiLocation { - parents: 1, - interior: X1(Plurality { id: BodyId::Treasury, part: BodyPart::Voice }), - }; + let relay_treasury_to_para_location = + Location::new(1, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]); let actual_description = ForeignChainAliasTreasuryAccount::<[u8; 32]>::convert_location( &relay_treasury_to_para_location, ) @@ -993,13 +966,10 @@ mod tests { actual_description ); - let para_to_para_treasury_location = MultiLocation { - parents: 1, - interior: X2( - Parachain(1001), - Plurality { id: BodyId::Treasury, part: BodyPart::Voice }, - ), - }; + let para_to_para_treasury_location = Location::new( + 1, + [Parachain(1001), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }], + ); let actual_description = ForeignChainAliasTreasuryAccount::<[u8; 32]>::convert_location( ¶_to_para_treasury_location, ) @@ -1016,10 +986,8 @@ mod tests { #[test] fn local_account_convert_on_para_from_relay_treasury() { - let location = MultiLocation { - parents: 0, - interior: X1(Plurality { id: BodyId::Treasury, part: BodyPart::Voice }), - }; + let location = + Location::new(0, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]); parameter_types! { pub TreasuryAccountId: AccountId = AccountId::new([42u8; 32]); diff --git a/polkadot/xcm/xcm-builder/src/matcher.rs b/polkadot/xcm/xcm-builder/src/matcher.rs index 9da135dae31..eae43b290fb 100644 --- a/polkadot/xcm/xcm-builder/src/matcher.rs +++ b/polkadot/xcm/xcm-builder/src/matcher.rs @@ -18,7 +18,7 @@ use core::ops::ControlFlow; use frame_support::traits::ProcessMessageError; -use xcm::latest::{Instruction, MultiLocation}; +use xcm::latest::{Instruction, Location}; /// Creates an instruction matcher from an XCM. Since XCM versions differ, we need to make a trait /// here to unify the interfaces among them. @@ -67,7 +67,7 @@ impl<'a, Call> CreateMatcher for &'a mut [Instruction] { pub trait MatchXcm { /// The concrete instruction type. Necessary to specify as it changes between XCM versions. type Inst; - /// The `MultiLocation` type. Necessary to specify as it changes between XCM versions. + /// The `Location` type. Necessary to specify as it changes between XCM versions. type Loc; /// The error type to throw when errors happen during matching. type Error; @@ -125,7 +125,7 @@ pub struct Matcher<'a, Call> { impl<'a, Call> MatchXcm for Matcher<'a, Call> { type Error = ProcessMessageError; type Inst = Instruction; - type Loc = MultiLocation; + type Loc = Location; fn assert_remaining_insts(self, n: usize) -> Result where diff --git a/polkadot/xcm/xcm-builder/src/matches_location.rs b/polkadot/xcm/xcm-builder/src/matches_location.rs index cfc71eafd02..a96df9e92de 100644 --- a/polkadot/xcm/xcm-builder/src/matches_location.rs +++ b/polkadot/xcm/xcm-builder/src/matches_location.rs @@ -14,37 +14,47 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! Various implementations and utilities for matching and filtering `MultiLocation` and -//! `InteriorMultiLocation` types. +//! Various implementations and utilities for matching and filtering `Location` and +//! `InteriorLocation` types. use frame_support::traits::{Contains, Get}; -use xcm::latest::{InteriorMultiLocation, MultiLocation, NetworkId}; +use xcm::latest::{InteriorLocation, Location, NetworkId}; -/// An implementation of `Contains` that checks for `MultiLocation` or -/// `InteriorMultiLocation` if starts with the provided type `T`. -pub struct StartsWith(sp_std::marker::PhantomData); -impl> Contains for StartsWith { - fn contains(t: &MultiLocation) -> bool { - t.starts_with(&T::get()) +/// An implementation of `Contains` that checks for `Location` or +/// `InteriorLocation` if starts with the provided type `T`. +pub struct StartsWith(sp_std::marker::PhantomData<(T, L)>); +impl, L: TryInto + Clone> Contains for StartsWith { + fn contains(location: &L) -> bool { + let latest_location: Location = if let Ok(location) = (*location).clone().try_into() { + location + } else { + return false; + }; + let latest_t = if let Ok(location) = T::get().try_into() { + location + } else { + return false; + }; + latest_location.starts_with(&latest_t) } } -impl> Contains for StartsWith { - fn contains(t: &InteriorMultiLocation) -> bool { +impl> Contains for StartsWith { + fn contains(t: &InteriorLocation) -> bool { t.starts_with(&T::get()) } } -/// An implementation of `Contains` that checks for `MultiLocation` or -/// `InteriorMultiLocation` if starts with expected `GlobalConsensus(NetworkId)` provided as type +/// An implementation of `Contains` that checks for `Location` or +/// `InteriorLocation` if starts with expected `GlobalConsensus(NetworkId)` provided as type /// `T`. pub struct StartsWithExplicitGlobalConsensus(sp_std::marker::PhantomData); -impl> Contains for StartsWithExplicitGlobalConsensus { - fn contains(location: &MultiLocation) -> bool { - matches!(location.interior.global_consensus(), Ok(requested_network) if requested_network.eq(&T::get())) +impl> Contains for StartsWithExplicitGlobalConsensus { + fn contains(location: &Location) -> bool { + matches!(location.interior().global_consensus(), Ok(requested_network) if requested_network.eq(&T::get())) } } -impl> Contains for StartsWithExplicitGlobalConsensus { - fn contains(location: &InteriorMultiLocation) -> bool { +impl> Contains for StartsWithExplicitGlobalConsensus { + fn contains(location: &InteriorLocation) -> bool { matches!(location.global_consensus(), Ok(requested_network) if requested_network.eq(&T::get())) } } diff --git a/polkadot/xcm/xcm-builder/src/matches_token.rs b/polkadot/xcm/xcm-builder/src/matches_token.rs index b6a320d8931..e49fd18f88d 100644 --- a/polkadot/xcm/xcm-builder/src/matches_token.rs +++ b/polkadot/xcm/xcm-builder/src/matches_token.rs @@ -19,25 +19,24 @@ use frame_support::traits::Get; use sp_std::marker::PhantomData; use xcm::latest::{ - AssetId::{Abstract, Concrete}, - AssetInstance, + Asset, AssetId, AssetInstance, Fungibility::{Fungible, NonFungible}, - MultiAsset, MultiLocation, + Location, }; use xcm_executor::traits::{MatchesFungible, MatchesNonFungible}; -/// Converts a `MultiAsset` into balance `B` if it is a concrete fungible with an id equal to that +/// Converts a `Asset` into balance `B` if its id is equal to that /// given by `T`'s `Get`. /// /// # Example /// /// ``` -/// use xcm::latest::{MultiLocation, Parent}; +/// use xcm::latest::{Location, Parent}; /// use staging_xcm_builder::IsConcrete; /// use xcm_executor::traits::MatchesFungible; /// /// frame_support::parameter_types! { -/// pub TargetLocation: MultiLocation = Parent.into(); +/// pub TargetLocation: Location = Parent.into(); /// } /// /// # fn main() { @@ -47,62 +46,18 @@ use xcm_executor::traits::{MatchesFungible, MatchesNonFungible}; /// # } /// ``` pub struct IsConcrete(PhantomData); -impl, B: TryFrom> MatchesFungible for IsConcrete { - fn matches_fungible(a: &MultiAsset) -> Option { +impl, B: TryFrom> MatchesFungible for IsConcrete { + fn matches_fungible(a: &Asset) -> Option { match (&a.id, &a.fun) { - (Concrete(ref id), Fungible(ref amount)) if id == &T::get() => - (*amount).try_into().ok(), + (AssetId(ref id), Fungible(ref amount)) if id == &T::get() => (*amount).try_into().ok(), _ => None, } } } -impl, I: TryFrom> MatchesNonFungible for IsConcrete { - fn matches_nonfungible(a: &MultiAsset) -> Option { +impl, I: TryFrom> MatchesNonFungible for IsConcrete { + fn matches_nonfungible(a: &Asset) -> Option { match (&a.id, &a.fun) { - (Concrete(id), NonFungible(instance)) if id == &T::get() => (*instance).try_into().ok(), - _ => None, - } - } -} - -/// Same as [`IsConcrete`] but for a fungible with abstract location. -/// -/// # Example -/// -/// ``` -/// use xcm::latest::prelude::*; -/// use staging_xcm_builder::IsAbstract; -/// use xcm_executor::traits::{MatchesFungible, MatchesNonFungible}; -/// -/// frame_support::parameter_types! { -/// pub TargetLocation: [u8; 32] = [7u8; 32]; -/// } -/// -/// # fn main() { -/// let asset = ([7u8; 32], 999u128).into(); -/// // match `asset` if it is an abstract asset in `TargetLocation`. -/// assert_eq!( as MatchesFungible>::matches_fungible(&asset), Some(999)); -/// let nft = ([7u8; 32], [42u8; 4]).into(); -/// assert_eq!( -/// as MatchesNonFungible<[u8; 4]>>::matches_nonfungible(&nft), -/// Some([42u8; 4]) -/// ); -/// # } -/// ``` -pub struct IsAbstract(PhantomData); -impl, B: TryFrom> MatchesFungible for IsAbstract { - fn matches_fungible(a: &MultiAsset) -> Option { - match (&a.id, &a.fun) { - (Abstract(ref id), Fungible(ref amount)) if id == &T::get() => - (*amount).try_into().ok(), - _ => None, - } - } -} -impl, B: TryFrom> MatchesNonFungible for IsAbstract { - fn matches_nonfungible(a: &MultiAsset) -> Option { - match (&a.id, &a.fun) { - (Abstract(id), NonFungible(instance)) if id == &T::get() => (*instance).try_into().ok(), + (AssetId(id), NonFungible(instance)) if id == &T::get() => (*instance).try_into().ok(), _ => None, } } diff --git a/polkadot/xcm/xcm-builder/src/nonfungibles_adapter.rs b/polkadot/xcm/xcm-builder/src/nonfungibles_adapter.rs index 357dc534a5f..b4801d3a23a 100644 --- a/polkadot/xcm/xcm-builder/src/nonfungibles_adapter.rs +++ b/polkadot/xcm/xcm-builder/src/nonfungibles_adapter.rs @@ -40,11 +40,11 @@ impl< > TransactAsset for NonFungiblesTransferAdapter { fn transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, context: &XcmContext, - ) -> result::Result { + ) -> result::Result { log::trace!( target: LOG_TARGET, "transfer_asset what: {:?}, from: {:?}, to: {:?}, context: {:?}", @@ -131,7 +131,7 @@ impl< CheckingAccount, > { - fn can_check_in(_origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_in(_origin: &Location, what: &Asset, context: &XcmContext) -> XcmResult { log::trace!( target: LOG_TARGET, "can_check_in origin: {:?}, what: {:?}, context: {:?}", @@ -150,7 +150,7 @@ impl< } } - fn check_in(_origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_in(_origin: &Location, what: &Asset, context: &XcmContext) { log::trace!( target: LOG_TARGET, "check_in origin: {:?}, what: {:?}, context: {:?}", @@ -169,7 +169,7 @@ impl< } } - fn can_check_out(_dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_out(_dest: &Location, what: &Asset, context: &XcmContext) -> XcmResult { log::trace!( target: LOG_TARGET, "can_check_out dest: {:?}, what: {:?}, context: {:?}", @@ -188,7 +188,7 @@ impl< } } - fn check_out(_dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_out(_dest: &Location, what: &Asset, context: &XcmContext) { log::trace!( target: LOG_TARGET, "check_out dest: {:?}, what: {:?}, context: {:?}", @@ -207,11 +207,7 @@ impl< } } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, context: Option<&XcmContext>) -> XcmResult { log::trace!( target: LOG_TARGET, "deposit_asset what: {:?}, who: {:?}, context: {:?}", @@ -228,10 +224,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, maybe_context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { log::trace!( target: LOG_TARGET, "withdraw_asset what: {:?}, who: {:?}, maybe_context: {:?}", @@ -267,7 +263,7 @@ impl< > TransactAsset for NonFungiblesAdapter { - fn can_check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_in(origin: &Location, what: &Asset, context: &XcmContext) -> XcmResult { NonFungiblesMutateAdapter::< Assets, Matcher, @@ -278,7 +274,7 @@ impl< >::can_check_in(origin, what, context) } - fn check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_in(origin: &Location, what: &Asset, context: &XcmContext) { NonFungiblesMutateAdapter::< Assets, Matcher, @@ -289,7 +285,7 @@ impl< >::check_in(origin, what, context) } - fn can_check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_out(dest: &Location, what: &Asset, context: &XcmContext) -> XcmResult { NonFungiblesMutateAdapter::< Assets, Matcher, @@ -300,7 +296,7 @@ impl< >::can_check_out(dest, what, context) } - fn check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_out(dest: &Location, what: &Asset, context: &XcmContext) { NonFungiblesMutateAdapter::< Assets, Matcher, @@ -311,11 +307,7 @@ impl< >::check_out(dest, what, context) } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, context: Option<&XcmContext>) -> XcmResult { NonFungiblesMutateAdapter::< Assets, Matcher, @@ -327,10 +319,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, maybe_context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { NonFungiblesMutateAdapter::< Assets, Matcher, @@ -342,11 +334,11 @@ impl< } fn transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, context: &XcmContext, - ) -> result::Result { + ) -> result::Result { NonFungiblesTransferAdapter::::transfer_asset( what, from, to, context, ) diff --git a/polkadot/xcm/xcm-builder/src/origin_aliases.rs b/polkadot/xcm/xcm-builder/src/origin_aliases.rs index 82c5f71b7a1..bbf810463a7 100644 --- a/polkadot/xcm/xcm-builder/src/origin_aliases.rs +++ b/polkadot/xcm/xcm-builder/src/origin_aliases.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! Implementation for `ContainsPair`. +//! Implementation for `ContainsPair`. use frame_support::traits::{Contains, ContainsPair}; use sp_std::marker::PhantomData; @@ -25,13 +25,15 @@ use xcm::latest::prelude::*; /// /// Requires that the prefixed origin `AccountId32` matches the target `AccountId32`. pub struct AliasForeignAccountId32(PhantomData); -impl> ContainsPair +impl> ContainsPair for AliasForeignAccountId32 { - fn contains(origin: &MultiLocation, target: &MultiLocation) -> bool { - if let (prefix, Some(account_id @ AccountId32 { .. })) = origin.split_last_interior() { + fn contains(origin: &Location, target: &Location) -> bool { + if let (prefix, Some(account_id @ AccountId32 { .. })) = + origin.clone().split_last_interior() + { return Prefix::contains(&prefix) && - *target == MultiLocation { parents: 0, interior: X1(account_id) } + *target == Location { parents: 0, interior: [account_id].into() } } false } diff --git a/polkadot/xcm/xcm-builder/src/origin_conversion.rs b/polkadot/xcm/xcm-builder/src/origin_conversion.rs index cced7dedf62..f64b5660f66 100644 --- a/polkadot/xcm/xcm-builder/src/origin_conversion.rs +++ b/polkadot/xcm/xcm-builder/src/origin_conversion.rs @@ -21,7 +21,7 @@ use frame_system::RawOrigin as SystemRawOrigin; use polkadot_parachain_primitives::primitives::IsSystem; use sp_runtime::traits::TryConvert; use sp_std::marker::PhantomData; -use xcm::latest::{BodyId, BodyPart, Junction, Junctions::*, MultiLocation, NetworkId, OriginKind}; +use xcm::latest::{BodyId, BodyPart, Junction, Junctions::*, Location, NetworkId, OriginKind}; use xcm_executor::traits::{ConvertLocation, ConvertOrigin}; /// Sovereign accounts use the system's `Signed` origin with an account ID derived from the @@ -35,9 +35,9 @@ where RuntimeOrigin::AccountId: Clone, { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!( target: "xcm::origin_conversion", @@ -56,9 +56,9 @@ where pub struct ParentAsSuperuser(PhantomData); impl ConvertOrigin for ParentAsSuperuser { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!(target: "xcm::origin_conversion", "ParentAsSuperuser origin: {:?}, kind: {:?}", origin, kind); if kind == OriginKind::Superuser && origin.contains_parents_only(1) { @@ -76,17 +76,16 @@ impl, RuntimeOrigin: OriginTrait> ConvertOrigin { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!(target: "xcm::origin_conversion", "ChildSystemParachainAsSuperuser origin: {:?}, kind: {:?}", origin, kind); - match (kind, origin) { - ( - OriginKind::Superuser, - MultiLocation { parents: 0, interior: X1(Junction::Parachain(id)) }, - ) if ParaId::from(id).is_system() => Ok(RuntimeOrigin::root()), - (_, origin) => Err(origin), + match (kind, origin.unpack()) { + (OriginKind::Superuser, (0, [Junction::Parachain(id)])) + if ParaId::from(*id).is_system() => + Ok(RuntimeOrigin::root()), + _ => Err(origin), } } } @@ -98,21 +97,20 @@ impl, RuntimeOrigin: OriginTrait> ConvertOrigin { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!( target: "xcm::origin_conversion", "SiblingSystemParachainAsSuperuser origin: {:?}, kind: {:?}", origin, kind, ); - match (kind, origin) { - ( - OriginKind::Superuser, - MultiLocation { parents: 1, interior: X1(Junction::Parachain(id)) }, - ) if ParaId::from(id).is_system() => Ok(RuntimeOrigin::root()), - (_, origin) => Err(origin), + match (kind, origin.unpack()) { + (OriginKind::Superuser, (1, [Junction::Parachain(id)])) + if ParaId::from(*id).is_system() => + Ok(RuntimeOrigin::root()), + _ => Err(origin), } } } @@ -124,17 +122,15 @@ impl, RuntimeOrigin: From> ConvertOr for ChildParachainAsNative { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!(target: "xcm::origin_conversion", "ChildParachainAsNative origin: {:?}, kind: {:?}", origin, kind); - match (kind, origin) { - ( - OriginKind::Native, - MultiLocation { parents: 0, interior: X1(Junction::Parachain(id)) }, - ) => Ok(RuntimeOrigin::from(ParachainOrigin::from(id))), - (_, origin) => Err(origin), + match (kind, origin.unpack()) { + (OriginKind::Native, (0, [Junction::Parachain(id)])) => + Ok(RuntimeOrigin::from(ParachainOrigin::from(*id))), + _ => Err(origin), } } } @@ -146,21 +142,19 @@ impl, RuntimeOrigin: From> ConvertOr for SiblingParachainAsNative { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!( target: "xcm::origin_conversion", "SiblingParachainAsNative origin: {:?}, kind: {:?}", origin, kind, ); - match (kind, origin) { - ( - OriginKind::Native, - MultiLocation { parents: 1, interior: X1(Junction::Parachain(id)) }, - ) => Ok(RuntimeOrigin::from(ParachainOrigin::from(id))), - (_, origin) => Err(origin), + match (kind, origin.unpack()) { + (OriginKind::Native, (1, [Junction::Parachain(id)])) => + Ok(RuntimeOrigin::from(ParachainOrigin::from(*id))), + _ => Err(origin), } } } @@ -173,9 +167,9 @@ impl, RuntimeOrigin> ConvertOrigin { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!(target: "xcm::origin_conversion", "RelayChainAsNative origin: {:?}, kind: {:?}", origin, kind); if kind == OriginKind::Native && origin.contains_parents_only(1) { @@ -193,22 +187,20 @@ where RuntimeOrigin::AccountId: From<[u8; 32]>, { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!( target: "xcm::origin_conversion", "SignedAccountId32AsNative origin: {:?}, kind: {:?}", origin, kind, ); - match (kind, origin) { - ( - OriginKind::Native, - MultiLocation { parents: 0, interior: X1(Junction::AccountId32 { id, network }) }, - ) if matches!(network, None) || network == Network::get() => - Ok(RuntimeOrigin::signed(id.into())), - (_, origin) => Err(origin), + match (kind, origin.unpack()) { + (OriginKind::Native, (0, [Junction::AccountId32 { id, network }])) + if matches!(network, None) || *network == Network::get() => + Ok(RuntimeOrigin::signed((*id).into())), + _ => Err(origin), } } } @@ -222,34 +214,32 @@ where RuntimeOrigin::AccountId: From<[u8; 20]>, { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!( target: "xcm::origin_conversion", "SignedAccountKey20AsNative origin: {:?}, kind: {:?}", origin, kind, ); - match (kind, origin) { - ( - OriginKind::Native, - MultiLocation { parents: 0, interior: X1(Junction::AccountKey20 { key, network }) }, - ) if (matches!(network, None) || network == Network::get()) => - Ok(RuntimeOrigin::signed(key.into())), - (_, origin) => Err(origin), + match (kind, origin.unpack()) { + (OriginKind::Native, (0, [Junction::AccountKey20 { key, network }])) + if (matches!(network, None) || *network == Network::get()) => + Ok(RuntimeOrigin::signed((*key).into())), + _ => Err(origin), } } } /// `EnsureOrigin` barrier to convert from dispatch origin to XCM origin, if one exists. pub struct EnsureXcmOrigin(PhantomData<(RuntimeOrigin, Conversion)>); -impl> +impl> EnsureOrigin for EnsureXcmOrigin where RuntimeOrigin::PalletsOrigin: PartialEq, { - type Success = MultiLocation; + type Success = Location; fn try_origin(o: RuntimeOrigin) -> Result { let o = match Conversion::try_convert(o) { Ok(location) => return Ok(location), @@ -282,13 +272,12 @@ impl< RuntimeOrigin: OriginTrait + Clone, AccountId: Into<[u8; 32]>, Network: Get>, - > TryConvert - for SignedToAccountId32 + > TryConvert for SignedToAccountId32 where RuntimeOrigin::PalletsOrigin: From> + TryInto, Error = RuntimeOrigin::PalletsOrigin>, { - fn try_convert(o: RuntimeOrigin) -> Result { + fn try_convert(o: RuntimeOrigin) -> Result { o.try_with_caller(|caller| match caller.try_into() { Ok(SystemRawOrigin::Signed(who)) => Ok(Junction::AccountId32 { network: Network::get(), id: who.into() }.into()), @@ -299,7 +288,7 @@ where } /// `Convert` implementation to convert from some an origin which implements `Backing` into a -/// corresponding `Plurality` `MultiLocation`. +/// corresponding `Plurality` `Location`. /// /// Typically used when configuring `pallet-xcm` for allowing a collective's Origin to dispatch an /// XCM from a `Plurality` origin. @@ -307,12 +296,12 @@ pub struct BackingToPlurality( PhantomData<(RuntimeOrigin, COrigin, Body)>, ); impl> - TryConvert for BackingToPlurality + TryConvert for BackingToPlurality where RuntimeOrigin::PalletsOrigin: From + TryInto, { - fn try_convert(o: RuntimeOrigin) -> Result { + fn try_convert(o: RuntimeOrigin) -> Result { o.try_with_caller(|caller| match caller.try_into() { Ok(co) => match co.get_backing() { Some(backing) => Ok(Junction::Plurality { @@ -333,10 +322,10 @@ pub struct OriginToPluralityVoice( PhantomData<(RuntimeOrigin, EnsureBodyOrigin, Body)>, ); impl, Body: Get> - TryConvert + TryConvert for OriginToPluralityVoice { - fn try_convert(o: RuntimeOrigin) -> Result { + fn try_convert(o: RuntimeOrigin) -> Result { match EnsureBodyOrigin::try_origin(o) { Ok(_) => Ok(Junction::Plurality { id: Body::get(), part: BodyPart::Voice }.into()), Err(o) => Err(o), diff --git a/polkadot/xcm/xcm-builder/src/pay.rs b/polkadot/xcm/xcm-builder/src/pay.rs index 4c9b9a6088d..6b466483cfa 100644 --- a/polkadot/xcm/xcm-builder/src/pay.rs +++ b/polkadot/xcm/xcm-builder/src/pay.rs @@ -30,7 +30,7 @@ use xcm_executor::traits::{QueryHandler, QueryResponseStatus}; /// ownership of some `Interior` location of the local chain to a particular `Beneficiary`. The /// `AssetKind` value is not itself bounded (to avoid the issue of needing to wrap some preexisting /// datatype), however a converter type `AssetKindToLocatableAsset` must be provided in order to -/// translate it into a `LocatableAsset`, which comprises both an XCM `MultiLocation` describing +/// translate it into a `LocatableAsset`, which comprises both an XCM `Location` describing /// the XCM endpoint on which the asset to be paid resides and an XCM `AssetId` to identify the /// specific asset at that endpoint. /// @@ -65,14 +65,14 @@ pub struct PayOverXcm< )>, ); impl< - Interior: Get, + Interior: Get, Router: SendXcm, Querier: QueryHandler, Timeout: Get, Beneficiary: Clone, AssetKind, AssetKindToLocatableAsset: TryConvert, - BeneficiaryRefToLocation: for<'a> TryConvert<&'a Beneficiary, MultiLocation>, + BeneficiaryRefToLocation: for<'a> TryConvert<&'a Beneficiary, Location>, > Pay for PayOverXcm< Interior, @@ -105,7 +105,7 @@ impl< let beneficiary = BeneficiaryRefToLocation::try_convert(&who) .map_err(|_| xcm::latest::Error::InvalidLocation)?; - let query_id = Querier::new_query(asset_location, Timeout::get(), Interior::get()); + let query_id = Querier::new_query(asset_location.clone(), Timeout::get(), Interior::get()); let message = Xcm(vec![ DescendOrigin(Interior::get()), @@ -120,8 +120,7 @@ impl< ])), TransferAsset { beneficiary, - assets: vec![MultiAsset { id: asset_id, fun: Fungibility::Fungible(amount) }] - .into(), + assets: vec![Asset { id: asset_id, fun: Fungibility::Fungible(amount) }].into(), }, ]); @@ -195,16 +194,16 @@ pub struct LocatableAssetId { /// The asset's ID. pub asset_id: AssetId, /// The (relative) location in which the asset ID is meaningful. - pub location: MultiLocation, + pub location: Location, } /// Adapter `struct` which implements a conversion from any `AssetKind` into a [`LocatableAssetId`] /// value using a fixed `Location` for the `location` field. -pub struct FixedLocation(sp_std::marker::PhantomData); -impl, AssetKind: Into> TryConvert - for FixedLocation +pub struct FixedLocation(sp_std::marker::PhantomData); +impl, AssetKind: Into> + TryConvert for FixedLocation { fn try_convert(value: AssetKind) -> Result { - Ok(LocatableAssetId { asset_id: value.into(), location: Location::get() }) + Ok(LocatableAssetId { asset_id: value.into(), location: FixedLocationValue::get() }) } } diff --git a/polkadot/xcm/xcm-builder/src/process_xcm_message.rs b/polkadot/xcm/xcm-builder/src/process_xcm_message.rs index 7334bcd2010..bcf91d8e68c 100644 --- a/polkadot/xcm/xcm-builder/src/process_xcm_message.rs +++ b/polkadot/xcm/xcm-builder/src/process_xcm_message.rs @@ -30,7 +30,7 @@ pub struct ProcessXcmMessage( PhantomData<(MessageOrigin, XcmExecutor, Call)>, ); impl< - MessageOrigin: Into + FullCodec + MaxEncodedLen + Clone + Eq + PartialEq + TypeInfo + Debug, + MessageOrigin: Into + FullCodec + MaxEncodedLen + Clone + Eq + PartialEq + TypeInfo + Debug, XcmExecutor: ExecuteXcm, Call, > ProcessMessage for ProcessXcmMessage @@ -82,28 +82,26 @@ impl< let (consumed, result) = match XcmExecutor::execute(origin.into(), pre, id, Weight::zero()) { - Outcome::Complete(w) => { + Outcome::Complete { used } => { log::trace!( target: LOG_TARGET, - "XCM message execution complete, used weight: {w}", + "XCM message execution complete, used weight: {used}", ); - (w, Ok(true)) + (used, Ok(true)) }, - Outcome::Incomplete(w, e) => { + Outcome::Incomplete { used, error } => { log::trace!( target: LOG_TARGET, - "XCM message execution incomplete, used weight: {w}, error: {e:?}", + "XCM message execution incomplete, used weight: {used}, error: {error:?}", ); - - (w, Ok(false)) + (used, Ok(false)) }, // In the error-case we assume the worst case and consume all possible weight. - Outcome::Error(e) => { + Outcome::Error { error } => { log::trace!( target: LOG_TARGET, - "XCM message execution error: {e:?}", + "XCM message execution error: {error:?}", ); - (required, Err(ProcessMessageError::Unsupported)) }, }; diff --git a/polkadot/xcm/xcm-builder/src/routing.rs b/polkadot/xcm/xcm-builder/src/routing.rs index f4c18adddb3..9c0302baee0 100644 --- a/polkadot/xcm/xcm-builder/src/routing.rs +++ b/polkadot/xcm/xcm-builder/src/routing.rs @@ -38,7 +38,7 @@ impl SendXcm for WithUniqueTopic { type Ticket = (Inner::Ticket, [u8; 32]); fn validate( - destination: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult { let mut message = message.take().ok_or(SendError::MissingArgument)?; @@ -82,7 +82,7 @@ impl SendXcm for WithTopicSource, + destination: &mut Option, message: &mut Option>, ) -> SendResult { let mut message = message.take().ok_or(SendError::MissingArgument)?; diff --git a/polkadot/xcm/xcm-builder/src/test_utils.rs b/polkadot/xcm/xcm-builder/src/test_utils.rs index d0f867ba62d..3131dece375 100644 --- a/polkadot/xcm/xcm-builder/src/test_utils.rs +++ b/polkadot/xcm/xcm-builder/src/test_utils.rs @@ -27,11 +27,11 @@ pub use xcm_executor::{ traits::{ AssetExchange, AssetLock, ConvertOrigin, Enact, LockError, OnResponse, TransactAsset, }, - Assets, Config, + AssetsInHolding, Config, }; parameter_types! { - pub static SubscriptionRequests: Vec<(MultiLocation, Option<(QueryId, Weight)>)> = vec![]; + pub static SubscriptionRequests: Vec<(Location, Option<(QueryId, Weight)>)> = vec![]; pub static MaxAssetsIntoHolding: u32 = 4; } @@ -39,39 +39,39 @@ pub struct TestSubscriptionService; impl VersionChangeNotifier for TestSubscriptionService { fn start( - location: &MultiLocation, + location: &Location, query_id: QueryId, max_weight: Weight, _context: &XcmContext, ) -> XcmResult { let mut r = SubscriptionRequests::get(); - r.push((*location, Some((query_id, max_weight)))); + r.push((location.clone(), Some((query_id, max_weight)))); SubscriptionRequests::set(r); Ok(()) } - fn stop(location: &MultiLocation, _context: &XcmContext) -> XcmResult { + fn stop(location: &Location, _context: &XcmContext) -> XcmResult { let mut r = SubscriptionRequests::get(); r.retain(|(l, _q)| l != location); - r.push((*location, None)); + r.push((location.clone(), None)); SubscriptionRequests::set(r); Ok(()) } - fn is_subscribed(location: &MultiLocation) -> bool { + fn is_subscribed(location: &Location) -> bool { let r = SubscriptionRequests::get(); r.iter().any(|(l, q)| l == location && q.is_some()) } } parameter_types! { - pub static TrappedAssets: Vec<(MultiLocation, MultiAssets)> = vec![]; + pub static TrappedAssets: Vec<(Location, Assets)> = vec![]; } pub struct TestAssetTrap; impl DropAssets for TestAssetTrap { - fn drop_assets(origin: &MultiLocation, assets: Assets, _context: &XcmContext) -> Weight { - let mut t: Vec<(MultiLocation, MultiAssets)> = TrappedAssets::get(); - t.push((*origin, assets.into())); + fn drop_assets(origin: &Location, assets: AssetsInHolding, _context: &XcmContext) -> Weight { + let mut t: Vec<(Location, Assets)> = TrappedAssets::get(); + t.push((origin.clone(), assets.into())); TrappedAssets::set(t); Weight::from_parts(5, 5) } @@ -79,13 +79,13 @@ impl DropAssets for TestAssetTrap { impl ClaimAssets for TestAssetTrap { fn claim_assets( - origin: &MultiLocation, - ticket: &MultiLocation, - what: &MultiAssets, + origin: &Location, + ticket: &Location, + what: &Assets, _context: &XcmContext, ) -> bool { - let mut t: Vec<(MultiLocation, MultiAssets)> = TrappedAssets::get(); - if let (0, X1(GeneralIndex(i))) = (ticket.parents, &ticket.interior) { + let mut t: Vec<(Location, Assets)> = TrappedAssets::get(); + if let (0, [GeneralIndex(i)]) = ticket.unpack() { if let Some((l, a)) = t.get(*i as usize) { if l == origin && a == what { t.swap_remove(*i as usize); @@ -102,11 +102,11 @@ pub struct TestAssetExchanger; impl AssetExchange for TestAssetExchanger { fn exchange_asset( - _origin: Option<&MultiLocation>, - _give: Assets, - want: &MultiAssets, + _origin: Option<&Location>, + _give: AssetsInHolding, + want: &Assets, _maximal: bool, - ) -> Result { + ) -> Result { Ok(want.clone().into()) } } @@ -135,17 +135,17 @@ impl PalletsInfoAccess for TestPalletsInfo { } pub struct TestUniversalAliases; -impl Contains<(MultiLocation, Junction)> for TestUniversalAliases { - fn contains(aliases: &(MultiLocation, Junction)) -> bool { +impl Contains<(Location, Junction)> for TestUniversalAliases { + fn contains(aliases: &(Location, Junction)) -> bool { &aliases.0 == &Here.into_location() && &aliases.1 == &GlobalConsensus(ByGenesis([0; 32])) } } parameter_types! { - pub static LockedAssets: Vec<(MultiLocation, MultiAsset)> = vec![]; + pub static LockedAssets: Vec<(Location, Asset)> = vec![]; } -pub struct TestLockTicket(MultiLocation, MultiAsset); +pub struct TestLockTicket(Location, Asset); impl Enact for TestLockTicket { fn enact(self) -> Result<(), LockError> { let mut locked_assets = LockedAssets::get(); @@ -154,7 +154,7 @@ impl Enact for TestLockTicket { Ok(()) } } -pub struct TestUnlockTicket(MultiLocation, MultiAsset); +pub struct TestUnlockTicket(Location, Asset); impl Enact for TestUnlockTicket { fn enact(self) -> Result<(), LockError> { let mut locked_assets = LockedAssets::get(); @@ -183,33 +183,33 @@ impl AssetLock for TestAssetLocker { type ReduceTicket = TestReduceTicket; fn prepare_lock( - unlocker: MultiLocation, - asset: MultiAsset, - _owner: MultiLocation, + unlocker: Location, + asset: Asset, + _owner: Location, ) -> Result { Ok(TestLockTicket(unlocker, asset)) } fn prepare_unlock( - unlocker: MultiLocation, - asset: MultiAsset, - _owner: MultiLocation, + unlocker: Location, + asset: Asset, + _owner: Location, ) -> Result { Ok(TestUnlockTicket(unlocker, asset)) } fn note_unlockable( - _locker: MultiLocation, - _asset: MultiAsset, - _owner: MultiLocation, + _locker: Location, + _asset: Asset, + _owner: Location, ) -> Result<(), LockError> { Ok(()) } fn prepare_reduce_unlockable( - _locker: MultiLocation, - _asset: MultiAsset, - _owner: MultiLocation, + _locker: Location, + _asset: Asset, + _owner: Location, ) -> Result { Ok(TestReduceTicket) } diff --git a/polkadot/xcm/xcm-builder/src/tests/aliases.rs b/polkadot/xcm/xcm-builder/src/tests/aliases.rs index f686926a252..89c17b09396 100644 --- a/polkadot/xcm/xcm-builder/src/tests/aliases.rs +++ b/polkadot/xcm/xcm-builder/src/tests/aliases.rs @@ -66,20 +66,25 @@ fn alias_origin_should_work() { ]); let message = Xcm(vec![AliasOrigin((AccountId32 { network: None, id: [0; 32] }).into())]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( (Parachain(1), AccountId32 { network: None, id: [0; 32] }), message.clone(), - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NoPermission } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NoPermission)); - let r = XcmExecutor::::execute_xcm( + let r = XcmExecutor::::prepare_and_execute( (Parent, Parachain(1), AccountId32 { network: None, id: [0; 32] }), message.clone(), - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); } diff --git a/polkadot/xcm/xcm-builder/src/tests/assets.rs b/polkadot/xcm/xcm-builder/src/tests/assets.rs index e1d61a9d1c6..b510eab8df5 100644 --- a/polkadot/xcm/xcm-builder/src/tests/assets.rs +++ b/polkadot/xcm/xcm-builder/src/tests/assets.rs @@ -32,10 +32,15 @@ fn exchange_asset_should_work() { maximal: true, }, ]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm(Parent, message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(40, 40) }); assert_eq!(asset_list(Parent), vec![(Here, 100u128).into(), (Parent, 950u128).into()]); assert_eq!(exchange_assets(), vec![(Parent, 50u128).into()].into()); } @@ -56,10 +61,15 @@ fn exchange_asset_without_maximal_should_work() { maximal: false, }, ]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm(Parent, message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(40, 40) }); assert_eq!(asset_list(Parent), vec![(Here, 50u128).into(), (Parent, 950u128).into()]); assert_eq!(exchange_assets(), vec![(Here, 50u128).into(), (Parent, 50u128).into()].into()); } @@ -80,10 +90,18 @@ fn exchange_asset_should_fail_when_no_deal_possible() { maximal: false, }, ]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm(Parent, message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(40, 40), XcmError::NoDeal)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(40, 40), error: XcmError::NoDeal } + ); assert_eq!(asset_list(Parent), vec![(Parent, 1000u128).into()]); assert_eq!(exchange_assets(), vec![(Here, 100u128).into()].into()); } @@ -100,32 +118,39 @@ fn paying_reserve_deposit_should_work() { BuyExecution { fees, weight_limit: Limited(Weight::from_parts(30, 30)) }, DepositAsset { assets: AllCounted(1).into(), beneficiary: Here.into() }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(50, 50); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(30, 30))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(30, 30) }); assert_eq!(asset_list(Here), vec![(Parent, 40u128).into()]); } #[test] fn transfer_should_work() { // we'll let them have message execution for free. - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // Child parachain #1 owns 1000 tokens held by us in reserve. add_asset(Parachain(1), (Here, 1000)); // They want to transfer 100 of them to their sibling parachain #2 let message = Xcm(vec![TransferAsset { assets: (Here, 100u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); assert_eq!( asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 100u128).into()] @@ -136,27 +161,31 @@ fn transfer_should_work() { #[test] fn reserve_transfer_should_work() { - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // Child parachain #1 owns 1000 tokens held by us in reserve. add_asset(Parachain(1), (Here, 1000)); // The remote account owned by gav. - let three: MultiLocation = X1(AccountIndex64 { index: 3, network: None }).into(); + let three: Location = [AccountIndex64 { index: 3, network: None }].into(); // They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2 // and let them know to hand it to account #3. let message = Xcm(vec![TransferReserveAsset { assets: (Here, 100u128).into(), dest: Parachain(2).into(), - xcm: Xcm::<()>(vec![DepositAsset { assets: AllCounted(1).into(), beneficiary: three }]), + xcm: Xcm::<()>(vec![DepositAsset { + assets: AllCounted(1).into(), + beneficiary: three.clone(), + }]), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); let expected_msg = Xcm::<()>(vec![ ReserveAssetDeposited((Parent, 100u128).into()), @@ -171,7 +200,7 @@ fn reserve_transfer_should_work() { #[test] fn burn_should_work() { // we'll let them have message execution for free. - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // Child parachain #1 owns 1000 tokens held by us in reserve. add_asset(Parachain(1), (Here, 1000)); // They want to burn 100 of them @@ -180,14 +209,15 @@ fn burn_should_work() { BurnAsset((Here, 100u128).into()), DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Parachain(1).into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(30, 30))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(30, 30) }); assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); assert_eq!(sent_xcm(), vec![]); @@ -197,14 +227,15 @@ fn burn_should_work() { BurnAsset((Here, 1000u128).into()), DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Parachain(1).into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(30, 30))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(30, 30) }); assert_eq!(asset_list(Parachain(1)), vec![]); assert_eq!(sent_xcm(), vec![]); } @@ -212,7 +243,7 @@ fn burn_should_work() { #[test] fn basic_asset_trap_should_work() { // we'll let them have message execution for free. - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into(), X1(Parachain(2)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into(), [Parachain(2)].into()]); // Child parachain #1 owns 1000 tokens held by us in reserve. add_asset(Parachain(1), (Here, 1000)); @@ -224,14 +255,15 @@ fn basic_asset_trap_should_work() { beneficiary: AccountIndex64 { index: 3, network: None }.into(), }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(20, 20), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(25, 25))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(25, 25) }); assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![]); @@ -243,15 +275,19 @@ fn basic_asset_trap_should_work() { beneficiary: AccountIndex64 { index: 3, network: None }.into(), }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let old_trapped_assets = TrappedAssets::get(); - let r = XcmExecutor::::execute_xcm( + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(20, 20), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::UnknownClaim } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::UnknownClaim)); assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![]); assert_eq!(old_trapped_assets, TrappedAssets::get()); @@ -264,15 +300,19 @@ fn basic_asset_trap_should_work() { beneficiary: AccountIndex64 { index: 3, network: None }.into(), }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let old_trapped_assets = TrappedAssets::get(); - let r = XcmExecutor::::execute_xcm( + let r = XcmExecutor::::prepare_and_execute( Parachain(2), message, - hash, + &mut hash, Weight::from_parts(20, 20), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::UnknownClaim } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::UnknownClaim)); assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![]); assert_eq!(old_trapped_assets, TrappedAssets::get()); @@ -285,15 +325,19 @@ fn basic_asset_trap_should_work() { beneficiary: AccountIndex64 { index: 3, network: None }.into(), }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let old_trapped_assets = TrappedAssets::get(); - let r = XcmExecutor::::execute_xcm( + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(20, 20), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::UnknownClaim } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::UnknownClaim)); assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![]); assert_eq!(old_trapped_assets, TrappedAssets::get()); @@ -305,14 +349,15 @@ fn basic_asset_trap_should_work() { beneficiary: AccountIndex64 { index: 3, network: None }.into(), }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(20, 20), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(20, 20) }); assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); assert_eq!( asset_list(AccountIndex64 { index: 3, network: None }), @@ -327,141 +372,168 @@ fn basic_asset_trap_should_work() { beneficiary: AccountIndex64 { index: 3, network: None }.into(), }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(20, 20), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::UnknownClaim } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::UnknownClaim)); } #[test] fn max_assets_limit_should_work() { // we'll let them have message execution for free. - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // Child parachain #1 owns 1000 tokens held by us in reserve. - add_asset(Parachain(1), ([1u8; 32], 1000u128)); - add_asset(Parachain(1), ([2u8; 32], 1000u128)); - add_asset(Parachain(1), ([3u8; 32], 1000u128)); - add_asset(Parachain(1), ([4u8; 32], 1000u128)); - add_asset(Parachain(1), ([5u8; 32], 1000u128)); - add_asset(Parachain(1), ([6u8; 32], 1000u128)); - add_asset(Parachain(1), ([7u8; 32], 1000u128)); - add_asset(Parachain(1), ([8u8; 32], 1000u128)); - add_asset(Parachain(1), ([9u8; 32], 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(0)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(1)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(2)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(3)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(4)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(5)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(6)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(7)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(8)]), 1000u128)); // Attempt to withdraw 8 (=2x4)different assets. This will succeed. let message = Xcm(vec![ - WithdrawAsset(([1u8; 32], 100u128).into()), - WithdrawAsset(([2u8; 32], 100u128).into()), - WithdrawAsset(([3u8; 32], 100u128).into()), - WithdrawAsset(([4u8; 32], 100u128).into()), - WithdrawAsset(([5u8; 32], 100u128).into()), - WithdrawAsset(([6u8; 32], 100u128).into()), - WithdrawAsset(([7u8; 32], 100u128).into()), - WithdrawAsset(([8u8; 32], 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(1)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(2)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(3)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(4)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(5)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(6)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(7)]), 100u128).into()), ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(100, 100), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(85, 85))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(85, 85) }); // Attempt to withdraw 9 different assets will fail. let message = Xcm(vec![ - WithdrawAsset(([1u8; 32], 100u128).into()), - WithdrawAsset(([2u8; 32], 100u128).into()), - WithdrawAsset(([3u8; 32], 100u128).into()), - WithdrawAsset(([4u8; 32], 100u128).into()), - WithdrawAsset(([5u8; 32], 100u128).into()), - WithdrawAsset(([6u8; 32], 100u128).into()), - WithdrawAsset(([7u8; 32], 100u128).into()), - WithdrawAsset(([8u8; 32], 100u128).into()), - WithdrawAsset(([9u8; 32], 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(1)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(2)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(3)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(4)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(5)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(6)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(7)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(8)]), 100u128).into()), ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(100, 100), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(95, 95), + error: XcmError::HoldingWouldOverflow + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(95, 95), XcmError::HoldingWouldOverflow)); // Attempt to withdraw 4 different assets and then the same 4 and then a different 4 will // succeed. let message = Xcm(vec![ - WithdrawAsset(([1u8; 32], 100u128).into()), - WithdrawAsset(([2u8; 32], 100u128).into()), - WithdrawAsset(([3u8; 32], 100u128).into()), - WithdrawAsset(([4u8; 32], 100u128).into()), - WithdrawAsset(([1u8; 32], 100u128).into()), - WithdrawAsset(([2u8; 32], 100u128).into()), - WithdrawAsset(([3u8; 32], 100u128).into()), - WithdrawAsset(([4u8; 32], 100u128).into()), - WithdrawAsset(([5u8; 32], 100u128).into()), - WithdrawAsset(([6u8; 32], 100u128).into()), - WithdrawAsset(([7u8; 32], 100u128).into()), - WithdrawAsset(([8u8; 32], 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(1)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(2)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(3)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(1)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(2)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(3)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(4)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(5)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(6)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(7)]), 100u128).into()), ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(200, 200), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(125, 125))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(125, 125) }); // Attempt to withdraw 4 different assets and then a different 4 and then the same 4 will fail. let message = Xcm(vec![ - WithdrawAsset(([1u8; 32], 100u128).into()), - WithdrawAsset(([2u8; 32], 100u128).into()), - WithdrawAsset(([3u8; 32], 100u128).into()), - WithdrawAsset(([4u8; 32], 100u128).into()), - WithdrawAsset(([5u8; 32], 100u128).into()), - WithdrawAsset(([6u8; 32], 100u128).into()), - WithdrawAsset(([7u8; 32], 100u128).into()), - WithdrawAsset(([8u8; 32], 100u128).into()), - WithdrawAsset(([1u8; 32], 100u128).into()), - WithdrawAsset(([2u8; 32], 100u128).into()), - WithdrawAsset(([3u8; 32], 100u128).into()), - WithdrawAsset(([4u8; 32], 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(1)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(2)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(3)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(4)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(5)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(6)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(7)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(1)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(2)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(3)]), 100u128).into()), ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(200, 200), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(95, 95), + error: XcmError::HoldingWouldOverflow + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(95, 95), XcmError::HoldingWouldOverflow)); // Attempt to withdraw 4 different assets and then a different 4 and then the same 4 will fail. let message = Xcm(vec![ - WithdrawAsset(MultiAssets::from(vec![ - ([1u8; 32], 100u128).into(), - ([2u8; 32], 100u128).into(), - ([3u8; 32], 100u128).into(), - ([4u8; 32], 100u128).into(), - ([5u8; 32], 100u128).into(), - ([6u8; 32], 100u128).into(), - ([7u8; 32], 100u128).into(), - ([8u8; 32], 100u128).into(), + WithdrawAsset(Assets::from(vec![ + (Junctions::from([GeneralIndex(0)]), 100u128).into(), + (Junctions::from([GeneralIndex(1)]), 100u128).into(), + (Junctions::from([GeneralIndex(2)]), 100u128).into(), + (Junctions::from([GeneralIndex(3)]), 100u128).into(), + (Junctions::from([GeneralIndex(4)]), 100u128).into(), + (Junctions::from([GeneralIndex(5)]), 100u128).into(), + (Junctions::from([GeneralIndex(6)]), 100u128).into(), + (Junctions::from([GeneralIndex(7)]), 100u128).into(), ])), - WithdrawAsset(([1u8; 32], 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(200, 200), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(25, 25), + error: XcmError::HoldingWouldOverflow + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(25, 25), XcmError::HoldingWouldOverflow)); } diff --git a/polkadot/xcm/xcm-builder/src/tests/basic.rs b/polkadot/xcm/xcm-builder/src/tests/basic.rs index 02fcd8962db..1482e3d700f 100644 --- a/polkadot/xcm/xcm-builder/src/tests/basic.rs +++ b/polkadot/xcm/xcm-builder/src/tests/basic.rs @@ -27,14 +27,8 @@ fn basic_setup_works() { assert_eq!(to_account(Parachain(50)), Ok(1050)); assert_eq!(to_account((Parent, Parachain(1))), Ok(2001)); assert_eq!(to_account((Parent, Parachain(50))), Ok(2050)); - assert_eq!( - to_account(MultiLocation::new(0, X1(AccountIndex64 { index: 1, network: None }))), - Ok(1), - ); - assert_eq!( - to_account(MultiLocation::new(0, X1(AccountIndex64 { index: 42, network: None }))), - Ok(42), - ); + assert_eq!(to_account(Location::new(0, [AccountIndex64 { index: 1, network: None }])), Ok(1),); + assert_eq!(to_account(Location::new(0, [AccountIndex64 { index: 42, network: None }])), Ok(42),); assert_eq!(to_account(Here), Ok(3000)); } @@ -65,7 +59,7 @@ fn code_registers_should_work() { SetErrorHandler(Xcm(vec![ TransferAsset { assets: (Here, 2u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }, // It was handled fine. ClearError, @@ -73,33 +67,45 @@ fn code_registers_should_work() { // Set the appendix - this will always fire. SetAppendix(Xcm(vec![TransferAsset { assets: (Here, 4u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }])), // First xfer always works ok TransferAsset { assets: (Here, 1u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }, // Second xfer results in error on the second message - our error handler will fire. TransferAsset { assets: (Here, 8u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }, ]); // Weight limit of 70 is needed. let limit = ::Weigher::weight(&mut message).unwrap(); assert_eq!(limit, Weight::from_parts(70, 70)); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Here, message.clone(), hash, limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(50, 50))); // We don't pay the 20 weight for the error handler. + let r = XcmExecutor::::prepare_and_execute( + Here, + message.clone(), + &mut hash, + limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(50, 50) }); // We don't pay the 20 weight for the error handler. assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 13u128).into()]); assert_eq!(asset_list(Here), vec![(Here, 8u128).into()]); assert_eq!(sent_xcm(), vec![]); - let r = XcmExecutor::::execute_xcm(Here, message, hash, limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); // We pay the full weight here. + let r = XcmExecutor::::prepare_and_execute( + Here, + message, + &mut hash, + limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(70, 70) }); // We pay the full weight here. assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 20u128).into()]); assert_eq!(asset_list(Here), vec![(Here, 1u128).into()]); assert_eq!(sent_xcm(), vec![]); diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/local_para_para.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/local_para_para.rs index b1361cc8577..ea584bf9d48 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/local_para_para.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/local_para_para.rs @@ -21,9 +21,9 @@ use super::*; parameter_types! { - pub UniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1)); - pub RemoteUniversalLocation: Junctions = X2(GlobalConsensus(Remote::get()), Parachain(1)); - pub RemoteNetwork: MultiLocation = AncestorThen(2, GlobalConsensus(Remote::get())).into(); + pub UniversalLocation: Junctions = [GlobalConsensus(Local::get()), Parachain(1)].into(); + pub RemoteUniversalLocation: Junctions = [GlobalConsensus(Remote::get()), Parachain(1)].into(); + pub RemoteNetwork: Location = AncestorThen(2, GlobalConsensus(Remote::get())).into(); } type TheBridge = TestBridge>; diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/local_relay_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/local_relay_relay.rs index 5371abccf66..38ffe2532d5 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/local_relay_relay.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/local_relay_relay.rs @@ -21,9 +21,9 @@ use super::*; parameter_types! { - pub UniversalLocation: Junctions = X1(GlobalConsensus(Local::get())); - pub RemoteUniversalLocation: Junctions = X1(GlobalConsensus(Remote::get())); - pub RemoteNetwork: MultiLocation = AncestorThen(1, GlobalConsensus(Remote::get())).into(); + pub UniversalLocation: Junctions = [GlobalConsensus(Local::get())].into(); + pub RemoteUniversalLocation: Junctions = [GlobalConsensus(Remote::get())].into(); + pub RemoteNetwork: Location = AncestorThen(1, GlobalConsensus(Remote::get())).into(); } type TheBridge = TestBridge>; diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/mod.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/mod.rs index 0c749b66da6..11f0044fbca 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/mod.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/mod.rs @@ -37,7 +37,7 @@ mod remote_relay_relay; parameter_types! { pub Local: NetworkId = ByGenesis([0; 32]); pub Remote: NetworkId = ByGenesis([1; 32]); - pub Price: MultiAssets = MultiAssets::from((Here, 100u128)); + pub Price: Assets = Assets::from((Here, 100u128)); pub static UsingTopic: bool = false; } @@ -92,7 +92,7 @@ impl SendXcm for TestTopic { } } fn validate( - destination: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult { Ok(if UsingTopic::get() { @@ -120,26 +120,26 @@ impl HaulBlob for TestBridge { } std::thread_local! { - static REMOTE_INCOMING_XCM: RefCell)>> = RefCell::new(Vec::new()); + static REMOTE_INCOMING_XCM: RefCell)>> = RefCell::new(Vec::new()); } struct TestRemoteIncomingRouter; impl SendXcm for TestRemoteIncomingRouter { - type Ticket = (MultiLocation, Xcm<()>); + type Ticket = (Location, Xcm<()>); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, - ) -> SendResult<(MultiLocation, Xcm<()>)> { + ) -> SendResult<(Location, Xcm<()>)> { let pair = (dest.take().unwrap(), msg.take().unwrap()); - Ok((pair, MultiAssets::new())) + Ok((pair, Assets::new())) } - fn deliver(pair: (MultiLocation, Xcm<()>)) -> Result { + fn deliver(pair: (Location, Xcm<()>)) -> Result { let hash = fake_id(); REMOTE_INCOMING_XCM.with(|q| q.borrow_mut().push(pair)); Ok(hash) } } -fn take_received_remote_messages() -> Vec<(MultiLocation, Xcm<()>)> { +fn take_received_remote_messages() -> Vec<(Location, Xcm<()>)> { REMOTE_INCOMING_XCM.with(|r| r.replace(vec![])) } @@ -152,18 +152,18 @@ struct UnpaidExecutingRouter( fn price( n: NetworkId, c: u32, - s: &InteriorMultiLocation, - d: &InteriorMultiLocation, + s: &InteriorLocation, + d: &InteriorLocation, m: &Xcm<()>, -) -> Result { - Ok(validate_export::(n, c, *s, *d, m.clone())?.1) +) -> Result { + Ok(validate_export::(n, c, s.clone(), d.clone(), m.clone())?.1) } fn deliver( n: NetworkId, c: u32, - s: InteriorMultiLocation, - d: InteriorMultiLocation, + s: InteriorLocation, + d: InteriorLocation, m: Xcm<()>, ) -> Result { export_xcm::(n, c, s, d, m).map(|(hash, _)| hash) @@ -189,7 +189,7 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S type Ticket = Xcm<()>; fn validate( - destination: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult> { let expect_dest = Remote::get().relative_to(&Local::get()); @@ -197,7 +197,7 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S return Err(NotApplicable) } let message = message.take().ok_or(MissingArgument)?; - Ok((message, MultiAssets::new())) + Ok((message, Assets::new())) } fn deliver(message: Xcm<()>) -> Result { @@ -206,7 +206,7 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S // though it is `Remote`. ExecutorUniversalLocation::set(Remote::get()); let origin = Local::get().relative_to(&Remote::get()); - AllowUnpaidFrom::set(vec![origin]); + AllowUnpaidFrom::set(vec![origin.clone()]); set_exporter_override(price::, deliver::); // The we execute it: let mut id = fake_id(); @@ -222,9 +222,9 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S let entry = LogEntry { local, remote, id, message, outcome: outcome.clone(), paid: false }; RoutingLog::mutate(|l| l.push(entry)); match outcome { - Outcome::Complete(..) => Ok(id), - Outcome::Incomplete(..) => Err(Transport("Error executing")), - Outcome::Error(..) => Err(Transport("Unable to execute")), + Outcome::Complete { .. } => Ok(id), + Outcome::Incomplete { .. } => Err(Transport("Error executing")), + Outcome::Error { .. } => Err(Transport("Unable to execute")), } } } @@ -239,7 +239,7 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S type Ticket = Xcm<()>; fn validate( - destination: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult> { let expect_dest = Remote::get().relative_to(&Local::get()); @@ -247,7 +247,7 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S return Err(NotApplicable) } let message = message.take().ok_or(MissingArgument)?; - Ok((message, MultiAssets::new())) + Ok((message, Assets::new())) } fn deliver(message: Xcm<()>) -> Result { @@ -256,7 +256,7 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S // though it is `Remote`. ExecutorUniversalLocation::set(Remote::get()); let origin = Local::get().relative_to(&Remote::get()); - AllowPaidFrom::set(vec![origin]); + AllowPaidFrom::set(vec![origin.clone()]); set_exporter_override(price::, deliver::); // Then we execute it: let mut id = fake_id(); @@ -272,9 +272,9 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S let entry = LogEntry { local, remote, id, message, outcome: outcome.clone(), paid: true }; RoutingLog::mutate(|l| l.push(entry)); match outcome { - Outcome::Complete(..) => Ok(id), - Outcome::Incomplete(..) => Err(Transport("Error executing")), - Outcome::Error(..) => Err(Transport("Unable to execute")), + Outcome::Complete { .. } => Ok(id), + Outcome::Incomplete { .. } => Err(Transport("Error executing")), + Outcome::Error { .. } => Err(Transport("Unable to execute")), } } } diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/paid_remote_relay_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/paid_remote_relay_relay.rs index 079eb0175d7..85d6524fb68 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/paid_remote_relay_relay.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/paid_remote_relay_relay.rs @@ -27,15 +27,15 @@ parameter_types! { // 100 to use the bridge (export) and 80 for the remote execution weight (4 instructions x (10 + // 10) weight each). pub SendOverBridgePrice: u128 = 180u128 + if UsingTopic::get() { 20 } else { 0 }; - pub UniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(100)); - pub RelayUniversalLocation: Junctions = X1(GlobalConsensus(Local::get())); - pub RemoteUniversalLocation: Junctions = X1(GlobalConsensus(Remote::get())); - pub RemoteNetwork: MultiLocation = AncestorThen(1, GlobalConsensus(Remote::get())).into(); + pub UniversalLocation: Junctions = [GlobalConsensus(Local::get()), Parachain(100)].into(); + pub RelayUniversalLocation: Junctions = [GlobalConsensus(Local::get())].into(); + pub RemoteUniversalLocation: Junctions = [GlobalConsensus(Remote::get())].into(); + pub RemoteNetwork: Location = AncestorThen(1, GlobalConsensus(Remote::get())).into(); pub BridgeTable: Vec = vec![ NetworkExportTableItem::new( Remote::get(), None, - MultiLocation::parent(), + Location::parent(), Some((Parent, SendOverBridgePrice::get()).into()) ) ]; @@ -64,7 +64,7 @@ type LocalRouter = TestTopic<(LocalInnerRouter, LocalBridgeRouter)>; #[test] fn sending_to_bridged_chain_works() { maybe_with_topic(|| { - let dest: MultiLocation = (Parent, Parent, Remote::get()).into(); + let dest: Location = (Parent, Parent, Remote::get()).into(); // Initialize the local relay so that our parachain has funds to pay for export. clear_assets(Parachain(100)); @@ -99,7 +99,7 @@ fn sending_to_bridged_chain_works() { message: xcm_with_topic( maybe_forward_id_for(&[0; 32]), vec![ - WithdrawAsset(MultiAsset::from((Here, price)).into()), + WithdrawAsset(Asset::from((Here, price)).into()), BuyExecution { fees: (Here, price).into(), weight_limit: Unlimited }, ExportMessage { network: ByGenesis([1; 32]), @@ -109,7 +109,7 @@ fn sending_to_bridged_chain_works() { DepositAsset { assets: Wild(All), beneficiary: Parachain(100).into() }, ], ), - outcome: Outcome::Complete(test_weight(4)), + outcome: Outcome::Complete { used: test_weight(4) }, paid: true, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -117,7 +117,7 @@ fn sending_to_bridged_chain_works() { } #[test] fn sending_to_bridged_chain_without_funds_fails() { - let dest: MultiLocation = (Parent, Parent, Remote::get()).into(); + let dest: Location = (Parent, Parent, Remote::get()).into(); // Routing won't work if we don't have enough funds. assert_eq!( send_xcm::(dest, Xcm(vec![Trap(1)])), @@ -138,7 +138,7 @@ fn sending_to_bridged_chain_without_funds_fails() { #[test] fn sending_to_parachain_of_bridged_chain_works() { maybe_with_topic(|| { - let dest: MultiLocation = (Parent, Parent, Remote::get(), Parachain(100)).into(); + let dest: Location = (Parent, Parent, Remote::get(), Parachain(100)).into(); // Initialize the local relay so that our parachain has funds to pay for export. clear_assets(Parachain(100)); @@ -173,7 +173,7 @@ fn sending_to_parachain_of_bridged_chain_works() { message: xcm_with_topic( maybe_forward_id_for(&[0; 32]), vec![ - WithdrawAsset(MultiAsset::from((Here, price)).into()), + WithdrawAsset(Asset::from((Here, price)).into()), BuyExecution { fees: (Here, price).into(), weight_limit: Unlimited }, ExportMessage { network: ByGenesis([1; 32]), @@ -183,7 +183,7 @@ fn sending_to_parachain_of_bridged_chain_works() { DepositAsset { assets: Wild(All), beneficiary: Parachain(100).into() }, ], ), - outcome: Outcome::Complete(test_weight(4)), + outcome: Outcome::Complete { used: test_weight(4) }, paid: true, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -191,7 +191,7 @@ fn sending_to_parachain_of_bridged_chain_works() { } #[test] fn sending_to_parachain_of_bridged_chain_without_funds_fails() { - let dest: MultiLocation = (Parent, Parent, Remote::get(), Parachain(100)).into(); + let dest: Location = (Parent, Parent, Remote::get(), Parachain(100)).into(); // Routing won't work if we don't have enough funds. assert_eq!( send_xcm::(dest, Xcm(vec![Trap(1)])), diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para.rs index fb6c5da3eb0..b92c59281c6 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para.rs @@ -21,10 +21,10 @@ use super::*; parameter_types! { - pub UniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1000)); - pub ParaBridgeUniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1)); - pub RemoteParaBridgeUniversalLocation: Junctions = X2(GlobalConsensus(Remote::get()), Parachain(1)); - pub RemoteNetwork: MultiLocation = AncestorThen(2, GlobalConsensus(Remote::get())).into(); + pub UniversalLocation: Junctions = [GlobalConsensus(Local::get()), Parachain(1000)].into(); + pub ParaBridgeUniversalLocation: Junctions = [GlobalConsensus(Local::get()), Parachain(1)].into(); + pub RemoteParaBridgeUniversalLocation: Junctions = [GlobalConsensus(Remote::get()), Parachain(1)].into(); + pub RemoteNetwork: Location = AncestorThen(2, GlobalConsensus(Remote::get())).into(); pub BridgeTable: Vec = vec![ NetworkExportTableItem::new( Remote::get(), @@ -62,7 +62,7 @@ fn sending_to_bridged_chain_works() { send_xcm::((Parent, Parent, Remote::get(), Parachain(1)).into(), msg) .unwrap() .1, - MultiAssets::new() + Assets::new() ); assert_eq!(TheBridge::service(), 1); assert_eq!( @@ -94,7 +94,7 @@ fn sending_to_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -116,7 +116,7 @@ fn sending_to_sibling_of_bridged_chain_works() { maybe_with_topic(|| { let msg = Xcm(vec![Trap(1)]); let dest = (Parent, Parent, Remote::get(), Parachain(1000)).into(); - assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(send_xcm::(dest, msg).unwrap().1, Assets::new()); assert_eq!(TheBridge::service(), 1); let expected = vec![( (Parent, Parachain(1000)).into(), @@ -145,7 +145,7 @@ fn sending_to_sibling_of_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -167,7 +167,7 @@ fn sending_to_relay_of_bridged_chain_works() { maybe_with_topic(|| { let msg = Xcm(vec![Trap(1)]); let dest = (Parent, Parent, Remote::get()).into(); - assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(send_xcm::(dest, msg).unwrap().1, Assets::new()); assert_eq!(TheBridge::service(), 1); let expected = vec![( Parent.into(), @@ -196,7 +196,7 @@ fn sending_to_relay_of_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para_via_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para_via_relay.rs index 0b6dc01e2bf..1d433628825 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para_via_relay.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para_via_relay.rs @@ -21,10 +21,10 @@ use super::*; parameter_types! { - pub UniversalLocation: Junctions = X1(GlobalConsensus(Local::get())); - pub ParaBridgeUniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1)); - pub RemoteParaBridgeUniversalLocation: Junctions = X2(GlobalConsensus(Remote::get()), Parachain(1)); - pub RemoteNetwork: MultiLocation = AncestorThen(2, GlobalConsensus(Remote::get())).into(); + pub UniversalLocation: Junctions = [GlobalConsensus(Local::get())].into(); + pub ParaBridgeUniversalLocation: Junctions = [GlobalConsensus(Local::get()), Parachain(1)].into(); + pub RemoteParaBridgeUniversalLocation: Junctions = [GlobalConsensus(Remote::get()), Parachain(1)].into(); + pub RemoteNetwork: Location = AncestorThen(2, GlobalConsensus(Remote::get())).into(); pub BridgeTable: Vec = vec![ NetworkExportTableItem::new( Remote::get(), @@ -62,7 +62,7 @@ fn sending_to_bridged_chain_works() { send_xcm::((Parent, Remote::get(), Parachain(1)).into(), msg) .unwrap() .1, - MultiAssets::new() + Assets::new() ); assert_eq!(TheBridge::service(), 1); let expected = vec![( @@ -85,7 +85,7 @@ fn sending_to_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -107,7 +107,7 @@ fn sending_to_sibling_of_bridged_chain_works() { maybe_with_topic(|| { let msg = Xcm(vec![Trap(1)]); let dest = (Parent, Remote::get(), Parachain(1000)).into(); - assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(send_xcm::(dest, msg).unwrap().1, Assets::new()); assert_eq!(TheBridge::service(), 1); let expected = vec![( (Parent, Parachain(1000)).into(), @@ -129,7 +129,7 @@ fn sending_to_sibling_of_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -151,7 +151,7 @@ fn sending_to_relay_of_bridged_chain_works() { maybe_with_topic(|| { let msg = Xcm(vec![Trap(1)]); let dest = (Parent, Remote::get()).into(); - assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(send_xcm::(dest, msg).unwrap().1, Assets::new()); assert_eq!(TheBridge::service(), 1); let expected = vec![( Parent.into(), @@ -173,7 +173,7 @@ fn sending_to_relay_of_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_relay_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_relay_relay.rs index e33c7b15b0a..d40a941c791 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_relay_relay.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_relay_relay.rs @@ -21,15 +21,15 @@ use super::*; parameter_types! { - pub UniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1000)); - pub RelayUniversalLocation: Junctions = X1(GlobalConsensus(Local::get())); - pub RemoteUniversalLocation: Junctions = X1(GlobalConsensus(Remote::get())); - pub RemoteNetwork: MultiLocation = AncestorThen(1, GlobalConsensus(Remote::get())).into(); + pub UniversalLocation: Junctions = [GlobalConsensus(Local::get()), Parachain(1000)].into(); + pub RelayUniversalLocation: Junctions = [GlobalConsensus(Local::get())].into(); + pub RemoteUniversalLocation: Junctions = [GlobalConsensus(Remote::get())].into(); + pub RemoteNetwork: Location = AncestorThen(1, GlobalConsensus(Remote::get())).into(); pub BridgeTable: Vec = vec![ NetworkExportTableItem::new( Remote::get(), None, - MultiLocation::parent(), + Location::parent(), None ) ]; @@ -59,7 +59,7 @@ fn sending_to_bridged_chain_works() { let msg = Xcm(vec![Trap(1)]); assert_eq!( send_xcm::((Parent, Parent, Remote::get()).into(), msg).unwrap().1, - MultiAssets::new() + Assets::new() ); assert_eq!(TheBridge::service(), 1); assert_eq!( @@ -91,7 +91,7 @@ fn sending_to_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -113,7 +113,7 @@ fn sending_to_parachain_of_bridged_chain_works() { maybe_with_topic(|| { let msg = Xcm(vec![Trap(1)]); let dest = (Parent, Parent, Remote::get(), Parachain(1000)).into(); - assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(send_xcm::(dest, msg).unwrap().1, Assets::new()); assert_eq!(TheBridge::service(), 1); let expected = vec![( Parachain(1000).into(), @@ -142,7 +142,7 @@ fn sending_to_parachain_of_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); diff --git a/polkadot/xcm/xcm-builder/src/tests/expecting.rs b/polkadot/xcm/xcm-builder/src/tests/expecting.rs index 6d5e0ff47b5..1b36ef4517c 100644 --- a/polkadot/xcm/xcm-builder/src/tests/expecting.rs +++ b/polkadot/xcm/xcm-builder/src/tests/expecting.rs @@ -18,7 +18,7 @@ use super::*; #[test] fn expect_pallet_should_work() { - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2 // and let them know to hand it to account #3. let message = Xcm(vec![ExpectPallet { @@ -28,14 +28,15 @@ fn expect_pallet_should_work() { crate_major: 1, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); let message = Xcm(vec![ExpectPallet { index: 1, @@ -44,19 +45,20 @@ fn expect_pallet_should_work() { crate_major: 1, min_crate_minor: 41, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); } #[test] fn expect_pallet_should_fail_correctly() { - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); let message = Xcm(vec![ExpectPallet { index: 1, name: b"Balances".as_ref().into(), @@ -64,14 +66,21 @@ fn expect_pallet_should_fail_correctly() { crate_major: 1, min_crate_minor: 60, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(10, 10), + error: XcmError::VersionIncompatible + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::VersionIncompatible)); let message = Xcm(vec![ExpectPallet { index: 1, @@ -80,14 +89,18 @@ fn expect_pallet_should_fail_correctly() { crate_major: 1, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NameMismatch } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NameMismatch)); let message = Xcm(vec![ExpectPallet { index: 1, @@ -96,14 +109,18 @@ fn expect_pallet_should_fail_correctly() { crate_major: 1, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NameMismatch } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NameMismatch)); let message = Xcm(vec![ExpectPallet { index: 0, @@ -112,14 +129,18 @@ fn expect_pallet_should_fail_correctly() { crate_major: 1, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NameMismatch } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NameMismatch)); let message = Xcm(vec![ExpectPallet { index: 2, @@ -128,14 +149,18 @@ fn expect_pallet_should_fail_correctly() { crate_major: 1, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::PalletNotFound } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::PalletNotFound)); let message = Xcm(vec![ExpectPallet { index: 1, @@ -144,14 +169,21 @@ fn expect_pallet_should_fail_correctly() { crate_major: 2, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(10, 10), + error: XcmError::VersionIncompatible + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::VersionIncompatible)); let message = Xcm(vec![ExpectPallet { index: 1, @@ -160,14 +192,21 @@ fn expect_pallet_should_fail_correctly() { crate_major: 0, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(10, 10), + error: XcmError::VersionIncompatible + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::VersionIncompatible)); let message = Xcm(vec![ExpectPallet { index: 1, @@ -176,12 +215,19 @@ fn expect_pallet_should_fail_correctly() { crate_major: 1, min_crate_minor: 43, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(10, 10), + error: XcmError::VersionIncompatible + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::VersionIncompatible)); } diff --git a/polkadot/xcm/xcm-builder/src/tests/locking.rs b/polkadot/xcm/xcm-builder/src/tests/locking.rs index f4ef618ac0e..75160e31155 100644 --- a/polkadot/xcm/xcm-builder/src/tests/locking.rs +++ b/polkadot/xcm/xcm-builder/src/tests/locking.rs @@ -34,10 +34,15 @@ fn lock_roundtrip_should_work() { ), LockAsset { asset: (Parent, 100u128).into(), unlocker: (Parent, Parachain(1)).into() }, ]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(40, 40) }); assert_eq!(asset_list((3u64,)), vec![(Parent, 990u128).into()]); let expected_msg = Xcm::<()>(vec![NoteUnlockable { @@ -58,14 +63,15 @@ fn lock_roundtrip_should_work() { // Now we'll unlock it. let message = Xcm(vec![UnlockAsset { asset: (Parent, 100u128).into(), target: (3u64,).into() }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( (Parent, Parachain(1)), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); } #[test] @@ -82,10 +88,15 @@ fn auto_fee_paying_should_work() { SetFeesMode { jit_withdraw: true }, LockAsset { asset: (Parent, 100u128).into(), unlocker: (Parent, Parachain(1)).into() }, ]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(20, 20) }); assert_eq!(asset_list((3u64,)), vec![(Parent, 990u128).into()]); } @@ -100,10 +111,18 @@ fn lock_should_fail_correctly() { asset: (Parent, 100u128).into(), unlocker: (Parent, Parachain(1)).into(), }]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::LockError)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::LockError } + ); assert_eq!(sent_xcm(), vec![]); assert_eq!(take_lock_trace(), vec![]); @@ -118,10 +137,18 @@ fn lock_should_fail_correctly() { asset: (Parent, 100u128).into(), unlocker: (Parent, Parachain(1)).into(), }]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NotHoldingFees)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NotHoldingFees } + ); assert_eq!(sent_xcm(), vec![]); assert_eq!(take_lock_trace(), vec![]); } @@ -140,14 +167,15 @@ fn remote_unlock_roundtrip_should_work() { // This caused Parachain #1 to send us the NoteUnlockable instruction. let message = Xcm(vec![NoteUnlockable { asset: (Parent, 100u128).into(), owner: (3u64,).into() }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( (Parent, Parachain(1)), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); assert_eq!( take_lock_trace(), vec![Note { @@ -165,10 +193,15 @@ fn remote_unlock_roundtrip_should_work() { ), RequestUnlock { asset: (Parent, 100u128).into(), locker: (Parent, Parachain(1)).into() }, ]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(40, 40) }); assert_eq!(asset_list((3u64,)), vec![(Parent, 990u128).into()]); let expected_msg = Xcm::<()>(vec![UnlockAsset { @@ -201,24 +234,33 @@ fn remote_unlock_should_fail_correctly() { asset: (Parent, 100u128).into(), locker: (Parent, Parachain(1)).into(), }]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::LockError)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::LockError } + ); assert_eq!(sent_xcm(), vec![]); assert_eq!(take_lock_trace(), vec![]); // We have been told by Parachain #1 that Account #3 has locked funds which we can unlock. let message = Xcm(vec![NoteUnlockable { asset: (Parent, 100u128).into(), owner: (3u64,).into() }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( (Parent, Parachain(1)), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); let _discard = take_lock_trace(); // We want to unlock 100 of the native parent tokens which were locked for us on parachain. @@ -228,10 +270,18 @@ fn remote_unlock_should_fail_correctly() { asset: (Parent, 100u128).into(), locker: (Parent, Parachain(1)).into(), }]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NotHoldingFees)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NotHoldingFees } + ); assert_eq!(sent_xcm(), vec![]); assert_eq!(take_lock_trace(), vec![]); diff --git a/polkadot/xcm/xcm-builder/src/tests/mock.rs b/polkadot/xcm/xcm-builder/src/tests/mock.rs index c1b3f0cf224..f561c7d3bd4 100644 --- a/polkadot/xcm/xcm-builder/src/tests/mock.rs +++ b/polkadot/xcm/xcm-builder/src/tests/mock.rs @@ -28,7 +28,7 @@ pub use crate::{ use frame_support::traits::{ContainsPair, Everything}; pub use frame_support::{ dispatch::{DispatchInfo, DispatchResultWithPostInfo, GetDispatchInfo, PostDispatchInfo}, - ensure, match_types, parameter_types, + ensure, parameter_types, sp_runtime::{traits::Dispatchable, DispatchError, DispatchErrorWithPostInfo}, traits::{Contains, Get, IsInVec}, }; @@ -45,7 +45,7 @@ pub use xcm_executor::{ AssetExchange, AssetLock, CheckSuspension, ConvertOrigin, Enact, ExportXcm, FeeManager, FeeReason, LockError, OnResponse, TransactAsset, }, - Assets, Config, + AssetsInHolding, Config, }; #[derive(Debug)] @@ -110,52 +110,52 @@ impl GetDispatchInfo for TestCall { } thread_local! { - pub static SENT_XCM: RefCell, XcmHash)>> = RefCell::new(Vec::new()); + pub static SENT_XCM: RefCell, XcmHash)>> = RefCell::new(Vec::new()); pub static EXPORTED_XCM: RefCell< - Vec<(NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash)> + Vec<(NetworkId, u32, InteriorLocation, InteriorLocation, Xcm<()>, XcmHash)> > = RefCell::new(Vec::new()); pub static EXPORTER_OVERRIDE: RefCell, - ) -> Result, + ) -> Result, fn( NetworkId, u32, - InteriorMultiLocation, - InteriorMultiLocation, + InteriorLocation, + InteriorLocation, Xcm<()>, ) -> Result, )>> = RefCell::new(None); - pub static SEND_PRICE: RefCell = RefCell::new(MultiAssets::new()); + pub static SEND_PRICE: RefCell = RefCell::new(Assets::new()); pub static SUSPENDED: Cell = Cell::new(false); } -pub fn sent_xcm() -> Vec<(MultiLocation, opaque::Xcm, XcmHash)> { +pub fn sent_xcm() -> Vec<(Location, opaque::Xcm, XcmHash)> { SENT_XCM.with(|q| (*q.borrow()).clone()) } -pub fn set_send_price(p: impl Into) { +pub fn set_send_price(p: impl Into) { SEND_PRICE.with(|l| l.replace(p.into().into())); } pub fn exported_xcm( -) -> Vec<(NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, opaque::Xcm, XcmHash)> { +) -> Vec<(NetworkId, u32, InteriorLocation, InteriorLocation, opaque::Xcm, XcmHash)> { EXPORTED_XCM.with(|q| (*q.borrow()).clone()) } pub fn set_exporter_override( price: fn( NetworkId, u32, - &InteriorMultiLocation, - &InteriorMultiLocation, + &InteriorLocation, + &InteriorLocation, &Xcm<()>, - ) -> Result, + ) -> Result, deliver: fn( NetworkId, u32, - InteriorMultiLocation, - InteriorMultiLocation, + InteriorLocation, + InteriorLocation, Xcm<()>, ) -> Result, ) { @@ -167,17 +167,17 @@ pub fn clear_exporter_override() { } pub struct TestMessageSender; impl SendXcm for TestMessageSender { - type Ticket = (MultiLocation, Xcm<()>, XcmHash); + type Ticket = (Location, Xcm<()>, XcmHash); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, - ) -> SendResult<(MultiLocation, Xcm<()>, XcmHash)> { + ) -> SendResult<(Location, Xcm<()>, XcmHash)> { let msg = msg.take().unwrap(); let hash = fake_message_hash(&msg); let triplet = (dest.take().unwrap(), msg, hash); Ok((triplet, SEND_PRICE.with(|l| l.borrow().clone()))) } - fn deliver(triplet: (MultiLocation, Xcm<()>, XcmHash)) -> Result { + fn deliver(triplet: (Location, Xcm<()>, XcmHash)) -> Result { let hash = triplet.2; SENT_XCM.with(|q| q.borrow_mut().push(triplet)); Ok(hash) @@ -185,21 +185,20 @@ impl SendXcm for TestMessageSender { } pub struct TestMessageExporter; impl ExportXcm for TestMessageExporter { - type Ticket = (NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash); + type Ticket = (NetworkId, u32, InteriorLocation, InteriorLocation, Xcm<()>, XcmHash); fn validate( network: NetworkId, channel: u32, - uni_src: &mut Option, - dest: &mut Option, + uni_src: &mut Option, + dest: &mut Option, msg: &mut Option>, - ) -> SendResult<(NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash)> - { + ) -> SendResult<(NetworkId, u32, InteriorLocation, InteriorLocation, Xcm<()>, XcmHash)> { let (s, d, m) = (uni_src.take().unwrap(), dest.take().unwrap(), msg.take().unwrap()); - let r: Result = EXPORTER_OVERRIDE.with(|e| { + let r: Result = EXPORTER_OVERRIDE.with(|e| { if let Some((ref f, _)) = &*e.borrow() { f(network, channel, &s, &d, &m) } else { - Ok(MultiAssets::new()) + Ok(Assets::new()) } }); let h = fake_message_hash(&m); @@ -214,7 +213,7 @@ impl ExportXcm for TestMessageExporter { } } fn deliver( - tuple: (NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash), + tuple: (NetworkId, u32, InteriorLocation, InteriorLocation, Xcm<()>, XcmHash), ) -> Result { EXPORTER_OVERRIDE.with(|e| { if let Some((_, ref f)) = &*e.borrow() { @@ -230,37 +229,42 @@ impl ExportXcm for TestMessageExporter { } thread_local! { - pub static ASSETS: RefCell> = RefCell::new(BTreeMap::new()); + pub static ASSETS: RefCell> = RefCell::new(BTreeMap::new()); } -pub fn assets(who: impl Into) -> Assets { +pub fn assets(who: impl Into) -> AssetsInHolding { ASSETS.with(|a| a.borrow().get(&who.into()).cloned()).unwrap_or_default() } -pub fn asset_list(who: impl Into) -> Vec { - MultiAssets::from(assets(who)).into_inner() +pub fn asset_list(who: impl Into) -> Vec { + Assets::from(assets(who)).into_inner() } -pub fn add_asset(who: impl Into, what: impl Into) { - ASSETS.with(|a| a.borrow_mut().entry(who.into()).or_insert(Assets::new()).subsume(what.into())); +pub fn add_asset(who: impl Into, what: impl Into) { + ASSETS.with(|a| { + a.borrow_mut() + .entry(who.into()) + .or_insert(AssetsInHolding::new()) + .subsume(what.into()) + }); } -pub fn clear_assets(who: impl Into) { +pub fn clear_assets(who: impl Into) { ASSETS.with(|a| a.borrow_mut().remove(&who.into())); } pub struct TestAssetTransactor; impl TransactAsset for TestAssetTransactor { fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, _context: Option<&XcmContext>, ) -> Result<(), XcmError> { - add_asset(*who, what.clone()); + add_asset(who.clone(), what.clone()); Ok(()) } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, _maybe_context: Option<&XcmContext>, - ) -> Result { + ) -> Result { ASSETS.with(|a| { a.borrow_mut() .get_mut(who) @@ -271,19 +275,20 @@ impl TransactAsset for TestAssetTransactor { } } -pub fn to_account(l: impl Into) -> Result { - Ok(match l.into() { +pub fn to_account(l: impl Into) -> Result { + let l = l.into(); + Ok(match l.unpack() { // Siblings at 2000+id - MultiLocation { parents: 1, interior: X1(Parachain(id)) } => 2000 + id as u64, + (1, [Parachain(id)]) => 2000 + *id as u64, // Accounts are their number - MultiLocation { parents: 0, interior: X1(AccountIndex64 { index, .. }) } => index, + (0, [AccountIndex64 { index, .. }]) => *index, // Children at 1000+id - MultiLocation { parents: 0, interior: X1(Parachain(id)) } => 1000 + id as u64, + (0, [Parachain(id)]) => 1000 + *id as u64, // Self at 3000 - MultiLocation { parents: 0, interior: Here } => 3000, + (0, []) => 3000, // Parent at 3001 - MultiLocation { parents: 1, interior: Here } => 3001, - l => { + (1, []) => 3001, + _ => { // Is it a foreign-consensus? let uni = ExecutorUniversalLocation::get(); if l.parents as usize != uni.len() { @@ -301,36 +306,35 @@ pub fn to_account(l: impl Into) -> Result { pub struct TestOriginConverter; impl ConvertOrigin for TestOriginConverter { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { use OriginKind::*; - match (kind, origin.into()) { + let origin = origin.into(); + match (kind, origin.unpack()) { (Superuser, _) => Ok(TestOrigin::Root), - (SovereignAccount, l) => Ok(TestOrigin::Signed(to_account(l)?)), - (Native, MultiLocation { parents: 0, interior: X1(Parachain(id)) }) => - Ok(TestOrigin::Parachain(id)), - (Native, MultiLocation { parents: 1, interior: Here }) => Ok(TestOrigin::Relay), - (Native, MultiLocation { parents: 0, interior: X1(AccountIndex64 { index, .. }) }) => - Ok(TestOrigin::Signed(index)), - (_, origin) => Err(origin), + (SovereignAccount, _) => Ok(TestOrigin::Signed(to_account(origin)?)), + (Native, (0, [Parachain(id)])) => Ok(TestOrigin::Parachain(*id)), + (Native, (1, [])) => Ok(TestOrigin::Relay), + (Native, (0, [AccountIndex64 { index, .. }])) => Ok(TestOrigin::Signed(*index)), + _ => Err(origin), } } } thread_local! { - pub static IS_RESERVE: RefCell>> = RefCell::new(BTreeMap::new()); - pub static IS_TELEPORTER: RefCell>> = RefCell::new(BTreeMap::new()); - pub static UNIVERSAL_ALIASES: RefCell> = RefCell::new(BTreeSet::new()); + pub static IS_RESERVE: RefCell>> = RefCell::new(BTreeMap::new()); + pub static IS_TELEPORTER: RefCell>> = RefCell::new(BTreeMap::new()); + pub static UNIVERSAL_ALIASES: RefCell> = RefCell::new(BTreeSet::new()); } -pub fn add_reserve(from: MultiLocation, asset: MultiAssetFilter) { +pub fn add_reserve(from: Location, asset: AssetFilter) { IS_RESERVE.with(|r| r.borrow_mut().entry(from).or_default().push(asset)); } #[allow(dead_code)] -pub fn add_teleporter(from: MultiLocation, asset: MultiAssetFilter) { +pub fn add_teleporter(from: Location, asset: AssetFilter) { IS_TELEPORTER.with(|r| r.borrow_mut().entry(from).or_default().push(asset)); } -pub fn add_universal_alias(bridge: impl Into, consensus: impl Into) { +pub fn add_universal_alias(bridge: impl Into, consensus: impl Into) { UNIVERSAL_ALIASES.with(|r| r.borrow_mut().insert((bridge.into(), consensus.into()))); } pub fn clear_universal_aliases() { @@ -338,29 +342,29 @@ pub fn clear_universal_aliases() { } pub struct TestIsReserve; -impl ContainsPair for TestIsReserve { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl ContainsPair for TestIsReserve { + fn contains(asset: &Asset, origin: &Location) -> bool { IS_RESERVE .with(|r| r.borrow().get(origin).map_or(false, |v| v.iter().any(|a| a.matches(asset)))) } } pub struct TestIsTeleporter; -impl ContainsPair for TestIsTeleporter { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl ContainsPair for TestIsTeleporter { + fn contains(asset: &Asset, origin: &Location) -> bool { IS_TELEPORTER .with(|r| r.borrow().get(origin).map_or(false, |v| v.iter().any(|a| a.matches(asset)))) } } pub struct TestUniversalAliases; -impl Contains<(MultiLocation, Junction)> for TestUniversalAliases { - fn contains(t: &(MultiLocation, Junction)) -> bool { +impl Contains<(Location, Junction)> for TestUniversalAliases { + fn contains(t: &(Location, Junction)) -> bool { UNIVERSAL_ALIASES.with(|r| r.borrow().contains(t)) } } pub enum ResponseSlot { - Expecting(MultiLocation), + Expecting(Location), Received(Response), } thread_local! { @@ -368,20 +372,16 @@ thread_local! { } pub struct TestResponseHandler; impl OnResponse for TestResponseHandler { - fn expecting_response( - origin: &MultiLocation, - query_id: u64, - _querier: Option<&MultiLocation>, - ) -> bool { + fn expecting_response(origin: &Location, query_id: u64, _querier: Option<&Location>) -> bool { QUERIES.with(|q| match q.borrow().get(&query_id) { Some(ResponseSlot::Expecting(ref l)) => l == origin, _ => false, }) } fn on_response( - _origin: &MultiLocation, + _origin: &Location, query_id: u64, - _querier: Option<&MultiLocation>, + _querier: Option<&Location>, response: xcm::latest::Response, _max_weight: Weight, _context: &XcmContext, @@ -396,7 +396,7 @@ impl OnResponse for TestResponseHandler { Weight::from_parts(10, 10) } } -pub fn expect_response(query_id: u64, from: MultiLocation) { +pub fn expect_response(query_id: u64, from: Location) { QUERIES.with(|q| q.borrow_mut().insert(query_id, ResponseSlot::Expecting(from))); } pub fn response(query_id: u64) -> Option { @@ -420,9 +420,9 @@ impl QueryHandler type UniversalLocation = T::UniversalLocation; fn new_query( - responder: impl Into, + responder: impl Into, _timeout: Self::BlockNumber, - _match_querier: impl Into, + _match_querier: impl Into, ) -> Self::QueryId { let query_id = 1; expect_response(query_id, responder.into()); @@ -431,7 +431,7 @@ impl QueryHandler fn report_outcome( message: &mut Xcm<()>, - responder: impl Into, + responder: impl Into, timeout: Self::BlockNumber, ) -> Result { let responder = responder.into(); @@ -466,16 +466,16 @@ impl QueryHandler } parameter_types! { - pub static ExecutorUniversalLocation: InteriorMultiLocation + pub static ExecutorUniversalLocation: InteriorLocation = (ByGenesis([0; 32]), Parachain(42)).into(); pub UnitWeightCost: Weight = Weight::from_parts(10, 10); } parameter_types! { // Nothing is allowed to be paid/unpaid by default. - pub static AllowExplicitUnpaidFrom: Vec = vec![]; - pub static AllowUnpaidFrom: Vec = vec![]; - pub static AllowPaidFrom: Vec = vec![]; - pub static AllowSubsFrom: Vec = vec![]; + pub static AllowExplicitUnpaidFrom: Vec = vec![]; + pub static AllowUnpaidFrom: Vec = vec![]; + pub static AllowPaidFrom: Vec = vec![]; + pub static AllowSubsFrom: Vec = vec![]; // 1_000_000_000_000 => 1 unit of asset for 1 unit of ref time weight. // 1024 * 1024 => 1 unit of asset for 1 unit of proof size weight. pub static WeightPrice: (AssetId, u128, u128) = @@ -486,7 +486,7 @@ parameter_types! { pub struct TestSuspender; impl CheckSuspension for TestSuspender { fn is_suspended( - _origin: &MultiLocation, + _origin: &Location, _instructions: &mut [Instruction], _max_weight: Weight, _properties: &mut Properties, @@ -520,34 +520,34 @@ pub fn set_fee_waiver(waived: Vec) { pub struct TestFeeManager; impl FeeManager for TestFeeManager { - fn is_waived(_: Option<&MultiLocation>, r: FeeReason) -> bool { + fn is_waived(_: Option<&Location>, r: FeeReason) -> bool { IS_WAIVED.with(|l| l.borrow().contains(&r)) } - fn handle_fee(_: MultiAssets, _: Option<&XcmContext>, _: FeeReason) {} + fn handle_fee(_: Assets, _: Option<&XcmContext>, _: FeeReason) {} } #[derive(Clone, Eq, PartialEq, Debug)] pub enum LockTraceItem { - Lock { unlocker: MultiLocation, asset: MultiAsset, owner: MultiLocation }, - Unlock { unlocker: MultiLocation, asset: MultiAsset, owner: MultiLocation }, - Note { locker: MultiLocation, asset: MultiAsset, owner: MultiLocation }, - Reduce { locker: MultiLocation, asset: MultiAsset, owner: MultiLocation }, + Lock { unlocker: Location, asset: Asset, owner: Location }, + Unlock { unlocker: Location, asset: Asset, owner: Location }, + Note { locker: Location, asset: Asset, owner: Location }, + Reduce { locker: Location, asset: Asset, owner: Location }, } thread_local! { pub static NEXT_INDEX: RefCell = RefCell::new(0); pub static LOCK_TRACE: RefCell> = RefCell::new(Vec::new()); - pub static ALLOWED_UNLOCKS: RefCell> = RefCell::new(BTreeMap::new()); - pub static ALLOWED_REQUEST_UNLOCKS: RefCell> = RefCell::new(BTreeMap::new()); + pub static ALLOWED_UNLOCKS: RefCell> = RefCell::new(BTreeMap::new()); + pub static ALLOWED_REQUEST_UNLOCKS: RefCell> = RefCell::new(BTreeMap::new()); } pub fn take_lock_trace() -> Vec { LOCK_TRACE.with(|l| l.replace(Vec::new())) } pub fn allow_unlock( - unlocker: impl Into, - asset: impl Into, - owner: impl Into, + unlocker: impl Into, + asset: impl Into, + owner: impl Into, ) { ALLOWED_UNLOCKS.with(|l| { l.borrow_mut() @@ -557,9 +557,9 @@ pub fn allow_unlock( }); } pub fn disallow_unlock( - unlocker: impl Into, - asset: impl Into, - owner: impl Into, + unlocker: impl Into, + asset: impl Into, + owner: impl Into, ) { ALLOWED_UNLOCKS.with(|l| { l.borrow_mut() @@ -568,17 +568,17 @@ pub fn disallow_unlock( .saturating_take(asset.into().into()) }); } -pub fn unlock_allowed(unlocker: &MultiLocation, asset: &MultiAsset, owner: &MultiLocation) -> bool { +pub fn unlock_allowed(unlocker: &Location, asset: &Asset, owner: &Location) -> bool { ALLOWED_UNLOCKS.with(|l| { l.borrow_mut() - .get(&(*owner, *unlocker)) + .get(&(owner.clone(), unlocker.clone())) .map_or(false, |x| x.contains_asset(asset)) }) } pub fn allow_request_unlock( - locker: impl Into, - asset: impl Into, - owner: impl Into, + locker: impl Into, + asset: impl Into, + owner: impl Into, ) { ALLOWED_REQUEST_UNLOCKS.with(|l| { l.borrow_mut() @@ -588,9 +588,9 @@ pub fn allow_request_unlock( }); } pub fn disallow_request_unlock( - locker: impl Into, - asset: impl Into, - owner: impl Into, + locker: impl Into, + asset: impl Into, + owner: impl Into, ) { ALLOWED_REQUEST_UNLOCKS.with(|l| { l.borrow_mut() @@ -599,14 +599,10 @@ pub fn disallow_request_unlock( .saturating_take(asset.into().into()) }); } -pub fn request_unlock_allowed( - locker: &MultiLocation, - asset: &MultiAsset, - owner: &MultiLocation, -) -> bool { +pub fn request_unlock_allowed(locker: &Location, asset: &Asset, owner: &Location) -> bool { ALLOWED_REQUEST_UNLOCKS.with(|l| { l.borrow_mut() - .get(&(*owner, *locker)) + .get(&(owner.clone(), locker.clone())) .map_or(false, |x| x.contains_asset(asset)) }) } @@ -616,11 +612,11 @@ impl Enact for TestTicket { fn enact(self) -> Result<(), LockError> { match &self.0 { LockTraceItem::Lock { unlocker, asset, owner } => - allow_unlock(*unlocker, asset.clone(), *owner), + allow_unlock(unlocker.clone(), asset.clone(), owner.clone()), LockTraceItem::Unlock { unlocker, asset, owner } => - disallow_unlock(*unlocker, asset.clone(), *owner), + disallow_unlock(unlocker.clone(), asset.clone(), owner.clone()), LockTraceItem::Reduce { locker, asset, owner } => - disallow_request_unlock(*locker, asset.clone(), *owner), + disallow_request_unlock(locker.clone(), asset.clone(), owner.clone()), _ => {}, } LOCK_TRACE.with(move |l| l.borrow_mut().push(self.0)); @@ -635,38 +631,34 @@ impl AssetLock for TestAssetLock { type ReduceTicket = TestTicket; fn prepare_lock( - unlocker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + unlocker: Location, + asset: Asset, + owner: Location, ) -> Result { - ensure!(assets(owner).contains_asset(&asset), LockError::AssetNotOwned); + ensure!(assets(owner.clone()).contains_asset(&asset), LockError::AssetNotOwned); Ok(TestTicket(LockTraceItem::Lock { unlocker, asset, owner })) } fn prepare_unlock( - unlocker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + unlocker: Location, + asset: Asset, + owner: Location, ) -> Result { ensure!(unlock_allowed(&unlocker, &asset, &owner), LockError::NotLocked); Ok(TestTicket(LockTraceItem::Unlock { unlocker, asset, owner })) } - fn note_unlockable( - locker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, - ) -> Result<(), LockError> { - allow_request_unlock(locker, asset.clone(), owner); + fn note_unlockable(locker: Location, asset: Asset, owner: Location) -> Result<(), LockError> { + allow_request_unlock(locker.clone(), asset.clone(), owner.clone()); let item = LockTraceItem::Note { locker, asset, owner }; LOCK_TRACE.with(move |l| l.borrow_mut().push(item)); Ok(()) } fn prepare_reduce_unlockable( - locker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + locker: Location, + asset: Asset, + owner: Location, ) -> Result { ensure!(request_unlock_allowed(&locker, &asset, &owner), LockError::NotLocked); Ok(TestTicket(LockTraceItem::Reduce { locker, asset, owner })) @@ -674,26 +666,26 @@ impl AssetLock for TestAssetLock { } thread_local! { - pub static EXCHANGE_ASSETS: RefCell = RefCell::new(Assets::new()); + pub static EXCHANGE_ASSETS: RefCell = RefCell::new(AssetsInHolding::new()); } -pub fn set_exchange_assets(assets: impl Into) { +pub fn set_exchange_assets(assets: impl Into) { EXCHANGE_ASSETS.with(|a| a.replace(assets.into().into())); } -pub fn exchange_assets() -> MultiAssets { +pub fn exchange_assets() -> Assets { EXCHANGE_ASSETS.with(|a| a.borrow().clone().into()) } pub struct TestAssetExchange; impl AssetExchange for TestAssetExchange { fn exchange_asset( - _origin: Option<&MultiLocation>, - give: Assets, - want: &MultiAssets, + _origin: Option<&Location>, + give: AssetsInHolding, + want: &Assets, maximal: bool, - ) -> Result { + ) -> Result { let mut have = EXCHANGE_ASSETS.with(|l| l.borrow().clone()); ensure!(have.contains_assets(want), give); let get = if maximal { - std::mem::replace(&mut have, Assets::new()) + std::mem::replace(&mut have, AssetsInHolding::new()) } else { have.saturating_take(want.clone().into()) }; @@ -703,16 +695,25 @@ impl AssetExchange for TestAssetExchange { } } -match_types! { - pub type SiblingPrefix: impl Contains = { - MultiLocation { parents: 1, interior: X1(Parachain(_)) } - }; - pub type ChildPrefix: impl Contains = { - MultiLocation { parents: 0, interior: X1(Parachain(_)) } - }; - pub type ParentPrefix: impl Contains = { - MultiLocation { parents: 1, interior: Here } - }; +pub struct SiblingPrefix; +impl Contains for SiblingPrefix { + fn contains(loc: &Location) -> bool { + matches!(loc.unpack(), (1, [Parachain(_)])) + } +} + +pub struct ChildPrefix; +impl Contains for ChildPrefix { + fn contains(loc: &Location) -> bool { + matches!(loc.unpack(), (0, [Parachain(_)])) + } +} + +pub struct ParentPrefix; +impl Contains for ParentPrefix { + fn contains(loc: &Location) -> bool { + matches!(loc.unpack(), (1, [])) + } } pub struct TestConfig; @@ -743,7 +744,7 @@ impl Config for TestConfig { type Aliasers = AliasForeignAccountId32; } -pub fn fungible_multi_asset(location: MultiLocation, amount: u128) -> MultiAsset { +pub fn fungible_multi_asset(location: Location, amount: u128) -> Asset { (AssetId::from(location), Fungibility::Fungible(amount)).into() } diff --git a/polkadot/xcm/xcm-builder/src/tests/origins.rs b/polkadot/xcm/xcm-builder/src/tests/origins.rs index d3d6278eff8..c717d1e2af8 100644 --- a/polkadot/xcm/xcm-builder/src/tests/origins.rs +++ b/polkadot/xcm/xcm-builder/src/tests/origins.rs @@ -18,7 +18,7 @@ use super::*; #[test] fn universal_origin_should_work() { - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into(), X1(Parachain(2)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into(), [Parachain(2)].into()]); clear_universal_aliases(); // Parachain 1 may represent Kusama to us add_universal_alias(Parachain(1), Kusama); @@ -29,48 +29,57 @@ fn universal_origin_should_work() { UniversalOrigin(GlobalConsensus(Kusama)), TransferAsset { assets: (Parent, 100u128).into(), beneficiary: Here.into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(2), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::InvalidLocation } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::InvalidLocation)); let message = Xcm(vec![ UniversalOrigin(GlobalConsensus(Kusama)), TransferAsset { assets: (Parent, 100u128).into(), beneficiary: Here.into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(20, 20), error: XcmError::NotWithdrawable } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(20, 20), XcmError::NotWithdrawable)); add_asset((Ancestor(2), GlobalConsensus(Kusama)), (Parent, 100)); let message = Xcm(vec![ UniversalOrigin(GlobalConsensus(Kusama)), TransferAsset { assets: (Parent, 100u128).into(), beneficiary: Here.into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(20, 20) }); assert_eq!(asset_list((Ancestor(2), GlobalConsensus(Kusama))), vec![]); } #[test] fn export_message_should_work() { // Bridge chain (assumed to be Relay) lets Parachain #1 have message execution for free. - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // Local parachain #1 issues a transfer asset on Polkadot Relay-chain, transfering 100 Planck to // Polkadot parachain #2. let expected_message = Xcm(vec![TransferAsset { @@ -83,14 +92,15 @@ fn export_message_should_work() { destination: Here, xcm: expected_message.clone(), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); let uni_src = (ByGenesis([0; 32]), Parachain(42), Parachain(1)).into(); assert_eq!( exported_xcm(), @@ -101,40 +111,46 @@ fn export_message_should_work() { #[test] fn unpaid_execution_should_work() { // Bridge chain (assumed to be Relay) lets Parachain #1 have message execution for free. - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // Bridge chain (assumed to be Relay) lets Parachain #2 have message execution for free if it // asks. - AllowExplicitUnpaidFrom::set(vec![X1(Parachain(2)).into()]); + AllowExplicitUnpaidFrom::set(vec![[Parachain(2)].into()]); // Asking for unpaid execution of up to 9 weight on the assumption it is origin of #2. let message = Xcm(vec![UnpaidExecution { weight_limit: Limited(Weight::from_parts(9, 9)), check_origin: Some(Parachain(2).into()), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message.clone(), - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::BadOrigin } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::BadOrigin)); - let r = XcmExecutor::::execute_xcm( + let r = XcmExecutor::::prepare_and_execute( Parachain(2), message.clone(), - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Error(XcmError::Barrier)); + assert_eq!(r, Outcome::Error { error: XcmError::Barrier }); let message = Xcm(vec![UnpaidExecution { weight_limit: Limited(Weight::from_parts(10, 10)), check_origin: Some(Parachain(2).into()), }]); - let r = XcmExecutor::::execute_xcm( + let r = XcmExecutor::::prepare_and_execute( Parachain(2), message.clone(), - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); } diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs index 78b9284c689..01ff8c29f3d 100644 --- a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs +++ b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs @@ -115,14 +115,14 @@ impl pallet_assets::Config for Test { } parameter_types! { - pub const RelayLocation: MultiLocation = Here.into_location(); + pub const RelayLocation: Location = Here.into_location(); pub const AnyNetwork: Option = None; - pub UniversalLocation: InteriorMultiLocation = (ByGenesis([0; 32]), Parachain(42)).into(); + pub UniversalLocation: InteriorLocation = (ByGenesis([0; 32]), Parachain(42)).into(); pub UnitWeightCost: u64 = 1_000; pub static AdvertisedXcmVersion: u32 = 3; pub const BaseXcmWeight: Weight = Weight::from_parts(1_000, 1_000); - pub CurrencyPerSecondPerByte: (AssetId, u128, u128) = (Concrete(RelayLocation::get()), 1, 1); - pub TrustedAssets: (MultiAssetFilter, MultiLocation) = (All.into(), Here.into()); + pub CurrencyPerSecondPerByte: (AssetId, u128, u128) = (AssetId(RelayLocation::get()), 1, 1); + pub TrustedAssets: (AssetFilter, Location) = (All.into(), Here.into()); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; pub CheckingAccount: AccountId = XcmPallet::check_account(); @@ -130,28 +130,25 @@ parameter_types! { type AssetIdForAssets = u128; -pub struct FromMultiLocationToAsset( - core::marker::PhantomData<(MultiLocation, AssetId)>, -); -impl MaybeEquivalence - for FromMultiLocationToAsset +pub struct FromLocationToAsset(core::marker::PhantomData<(Location, AssetId)>); +impl MaybeEquivalence + for FromLocationToAsset { - fn convert(value: &MultiLocation) -> Option { - match value { - MultiLocation { parents: 0, interior: Here } => Some(0 as AssetIdForAssets), - MultiLocation { parents: 1, interior: Here } => Some(1 as AssetIdForAssets), - MultiLocation { parents: 0, interior: X2(PalletInstance(1), GeneralIndex(index)) } - if ![0, 1].contains(index) => + fn convert(value: &Location) -> Option { + match value.unpack() { + (0, []) => Some(0 as AssetIdForAssets), + (1, []) => Some(1 as AssetIdForAssets), + (0, [PalletInstance(1), GeneralIndex(index)]) if ![0, 1].contains(index) => Some(*index as AssetIdForAssets), _ => None, } } - fn convert_back(value: &AssetIdForAssets) -> Option { + fn convert_back(value: &AssetIdForAssets) -> Option { match value { - 0u128 => Some(MultiLocation { parents: 1, interior: Here }), + 0u128 => Some(Location { parents: 1, interior: Here }), para_id @ 1..=1000 => - Some(MultiLocation { parents: 1, interior: X1(Parachain(*para_id as u32)) }), + Some(Location { parents: 1, interior: [Parachain(*para_id as u32)].into() }), _ => None, } } @@ -163,7 +160,7 @@ pub type LocalAssetsTransactor = FungiblesAdapter< ConvertedConcreteId< AssetIdForAssets, Balance, - FromMultiLocationToAsset, + FromLocationToAsset, JustTry, >, SovereignAccountOf, @@ -187,10 +184,10 @@ impl WeightTrader for DummyWeightTrader { fn buy_weight( &mut self, _weight: Weight, - _payment: xcm_executor::Assets, + _payment: xcm_executor::AssetsInHolding, _context: &XcmContext, - ) -> Result { - Ok(xcm_executor::Assets::default()) + ) -> Result { + Ok(xcm_executor::AssetsInHolding::default()) } } @@ -228,13 +225,10 @@ parameter_types! { pub struct TreasuryToAccount; impl ConvertLocation for TreasuryToAccount { - fn convert_location(location: &MultiLocation) -> Option { - match location { - MultiLocation { - parents: 1, - interior: - X2(Parachain(42), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }), - } => Some(TreasuryAccountId::get()), // Hardcoded test treasury account id + fn convert_location(location: &Location) -> Option { + match location.unpack() { + (1, [Parachain(42), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]) => + Some(TreasuryAccountId::get()), // Hardcoded test treasury account id _ => None, } } @@ -277,7 +271,7 @@ pub const INITIAL_BALANCE: Balance = 100 * UNITS; pub const MINIMUM_BALANCE: Balance = 1 * UNITS; pub fn sibling_chain_account_id(para_id: u32, account: [u8; 32]) -> AccountId { - let location: MultiLocation = + let location: Location = (Parent, Parachain(para_id), Junction::AccountId32 { id: account, network: None }).into(); SovereignAccountOf::convert_location(&location).unwrap() } diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/pay.rs b/polkadot/xcm/xcm-builder/src/tests/pay/pay.rs index 178b9384273..062faee2abd 100644 --- a/polkadot/xcm/xcm-builder/src/tests/pay/pay.rs +++ b/polkadot/xcm/xcm-builder/src/tests/pay/pay.rs @@ -22,9 +22,9 @@ use frame_support::{assert_ok, traits::tokens::Pay}; /// Type representing both a location and an asset that is held at that location. /// The id of the held asset is relative to the location where it is being held. -#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq)] +#[derive(Encode, Decode, Clone, PartialEq, Eq)] pub struct AssetKind { - destination: MultiLocation, + destination: Location, asset_id: AssetId, } @@ -37,8 +37,8 @@ impl sp_runtime::traits::TryConvert for LocatableAs parameter_types! { pub SenderAccount: AccountId = AccountId::new([3u8; 32]); - pub InteriorAccount: InteriorMultiLocation = AccountId32 { id: SenderAccount::get().into(), network: None }.into(); - pub InteriorBody: InteriorMultiLocation = Plurality { id: BodyId::Treasury, part: BodyPart::Voice }.into(); + pub InteriorAccount: InteriorLocation = AccountId32 { id: SenderAccount::get().into(), network: None }.into(); + pub InteriorBody: InteriorLocation = Plurality { id: BodyId::Treasury, part: BodyPart::Voice }.into(); pub Timeout: BlockNumber = 5; // 5 blocks } @@ -91,13 +91,19 @@ fn pay_over_xcm_works() { vec![((Parent, Parachain(2)).into(), expected_message, expected_hash)] ); - let (_, message, hash) = sent_xcm()[0].clone(); + let (_, message, mut hash) = sent_xcm()[0].clone(); let message = Xcm::<::RuntimeCall>::from(message.clone()); // Execute message in parachain 2 with parachain 42's origin let origin = (Parent, Parachain(42)); - XcmExecutor::::execute_xcm(origin, message, hash, Weight::MAX); + XcmExecutor::::prepare_and_execute( + origin, + message, + &mut hash, + Weight::MAX, + Weight::zero(), + ); assert_eq!(mock::Assets::balance(0, &recipient), amount); }); } @@ -152,13 +158,19 @@ fn pay_over_xcm_governance_body() { vec![((Parent, Parachain(2)).into(), expected_message, expected_hash)] ); - let (_, message, hash) = sent_xcm()[0].clone(); + let (_, message, mut hash) = sent_xcm()[0].clone(); let message = Xcm::<::RuntimeCall>::from(message.clone()); // Execute message in parachain 2 with parachain 42's origin let origin = (Parent, Parachain(42)); - XcmExecutor::::execute_xcm(origin, message, hash, Weight::MAX); + XcmExecutor::::prepare_and_execute( + origin, + message, + &mut hash, + Weight::MAX, + Weight::zero(), + ); assert_eq!(mock::Assets::balance(relay_asset_index, &recipient), amount); }); } diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/salary.rs b/polkadot/xcm/xcm-builder/src/tests/pay/salary.rs index e490fe326b3..6a2945c6a9b 100644 --- a/polkadot/xcm/xcm-builder/src/tests/pay/salary.rs +++ b/polkadot/xcm/xcm-builder/src/tests/pay/salary.rs @@ -25,9 +25,9 @@ use frame_support::{ use sp_runtime::{traits::ConvertToValue, DispatchResult}; parameter_types! { - pub Interior: InteriorMultiLocation = Plurality { id: BodyId::Treasury, part: BodyPart::Voice }.into(); + pub Interior: InteriorLocation = Plurality { id: BodyId::Treasury, part: BodyPart::Voice }.into(); pub Timeout: BlockNumber = 5; - pub AssetHub: MultiLocation = (Parent, Parachain(1)).into(); + pub AssetHub: Location = (Parent, Parachain(1)).into(); pub AssetIdGeneralIndex: u128 = 100; pub AssetHubAssetId: AssetId = (PalletInstance(1), GeneralIndex(AssetIdGeneralIndex::get())).into(); pub LocatableAsset: LocatableAssetId = LocatableAssetId { asset_id: AssetHubAssetId::get(), location: AssetHub::get() }; @@ -140,7 +140,7 @@ fn salary_pay_over_xcm_works() { assert_ok!(Salary::payout(RuntimeOrigin::signed(recipient.clone()))); // Get message from mock transport layer - let (_, message, hash) = sent_xcm()[0].clone(); + let (_, message, mut hash) = sent_xcm()[0].clone(); // Change type from `Xcm<()>` to `Xcm` to be able to execute later let message = Xcm::<::RuntimeCall>::from(message.clone()); @@ -164,7 +164,13 @@ fn salary_pay_over_xcm_works() { assert_eq!(message, expected_message); // Execute message as the asset hub - XcmExecutor::::execute_xcm((Parent, Parachain(42)), message, hash, Weight::MAX); + XcmExecutor::::prepare_and_execute( + (Parent, Parachain(42)), + message, + &mut hash, + Weight::MAX, + Weight::zero(), + ); // Recipient receives the payment assert_eq!( diff --git a/polkadot/xcm/xcm-builder/src/tests/querying.rs b/polkadot/xcm/xcm-builder/src/tests/querying.rs index 8fbb55eb254..3b47073d53d 100644 --- a/polkadot/xcm/xcm-builder/src/tests/querying.rs +++ b/polkadot/xcm/xcm-builder/src/tests/querying.rs @@ -18,7 +18,7 @@ use super::*; #[test] fn pallet_query_should_work() { - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2 // and let them know to hand it to account #3. let message = Xcm(vec![QueryPallet { @@ -29,14 +29,15 @@ fn pallet_query_should_work() { max_weight: Weight::from_parts(50, 50), }, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); let expected_msg = Xcm::<()>(vec![QueryResponse { query_id: 1, @@ -50,7 +51,7 @@ fn pallet_query_should_work() { #[test] fn pallet_query_with_results_should_work() { - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2 // and let them know to hand it to account #3. let message = Xcm(vec![QueryPallet { @@ -61,14 +62,15 @@ fn pallet_query_with_results_should_work() { max_weight: Weight::from_parts(50, 50), }, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); let expected_msg = Xcm::<()>(vec![QueryResponse { query_id: 1, @@ -106,15 +108,27 @@ fn prepaid_result_of_query_should_get_free_execution() { max_weight: Weight::from_parts(10, 10), querier: Some(Here.into()), }]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(10, 10); // First time the response gets through since we're expecting it... - let r = XcmExecutor::::execute_xcm(Parent, message.clone(), hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message.clone(), + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); assert_eq!(response(query_id).unwrap(), the_response); // Second time it doesn't, since we're not. - let r = XcmExecutor::::execute_xcm(Parent, message.clone(), hash, weight_limit); - assert_eq!(r, Outcome::Error(XcmError::Barrier)); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message.clone(), + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Error { error: XcmError::Barrier }); } diff --git a/polkadot/xcm/xcm-builder/src/tests/transacting.rs b/polkadot/xcm/xcm-builder/src/tests/transacting.rs index 743ad7039f7..a85c8b9986c 100644 --- a/polkadot/xcm/xcm-builder/src/tests/transacting.rs +++ b/polkadot/xcm/xcm-builder/src/tests/transacting.rs @@ -25,10 +25,16 @@ fn transacting_should_work() { require_weight_at_most: Weight::from_parts(50, 50), call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(), }]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(60, 60); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(60, 60))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(60, 60) }); } #[test] @@ -40,10 +46,19 @@ fn transacting_should_respect_max_weight_requirement() { require_weight_at_most: Weight::from_parts(40, 40), call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(), }]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(60, 60); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(50, 50), XcmError::MaxWeightInvalid)); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(50, 50), error: XcmError::MaxWeightInvalid } + ); } #[test] @@ -57,20 +72,26 @@ fn transacting_should_refund_weight() { .encode() .into(), }]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(60, 60); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(40, 40) }); } #[test] fn paid_transacting_should_refund_payment_for_unused_weight() { - let one: MultiLocation = AccountIndex64 { index: 1, network: None }.into(); - AllowPaidFrom::set(vec![one]); + let one: Location = AccountIndex64 { index: 1, network: None }.into(); + AllowPaidFrom::set(vec![one.clone()]); add_asset(AccountIndex64 { index: 1, network: None }, (Parent, 200u128)); WeightPrice::set((Parent.into(), 1_000_000_000_000, 1024 * 1024)); - let origin = one; + let origin = one.clone(); let fees = (Parent, 200u128).into(); let message = Xcm::(vec![ WithdrawAsset((Parent, 200u128).into()), // enough for 200 units of weight. @@ -86,10 +107,16 @@ fn paid_transacting_should_refund_payment_for_unused_weight() { RefundSurplus, DepositAsset { assets: AllCounted(1).into(), beneficiary: one }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(100, 100); - let r = XcmExecutor::::execute_xcm(origin, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(60, 60))); + let r = XcmExecutor::::prepare_and_execute( + origin, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(60, 60) }); assert_eq!( asset_list(AccountIndex64 { index: 1, network: None }), vec![(Parent, 80u128).into()] @@ -112,10 +139,16 @@ fn report_successful_transact_status_should_work() { max_weight: Weight::from_parts(5000, 5000), }), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(70, 70); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(70, 70) }); let expected_msg = Xcm(vec![QueryResponse { response: Response::DispatchResult(MaybeErrorCode::Success), query_id: 42, @@ -142,10 +175,16 @@ fn report_failed_transact_status_should_work() { max_weight: Weight::from_parts(5000, 5000), }), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(70, 70); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(70, 70) }); let expected_msg = Xcm(vec![QueryResponse { response: Response::DispatchResult(vec![2].into()), query_id: 42, @@ -168,10 +207,16 @@ fn expect_successful_transact_status_should_work() { }, ExpectTransactStatus(MaybeErrorCode::Success), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(70, 70); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(70, 70) }); let message = Xcm::(vec![ Transact { @@ -181,10 +226,19 @@ fn expect_successful_transact_status_should_work() { }, ExpectTransactStatus(MaybeErrorCode::Success), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(70, 70); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(70, 70), XcmError::ExpectationFalse)); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(70, 70), error: XcmError::ExpectationFalse } + ); } #[test] @@ -199,10 +253,16 @@ fn expect_failed_transact_status_should_work() { }, ExpectTransactStatus(vec![2].into()), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(70, 70); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(70, 70) }); let message = Xcm::(vec![ Transact { @@ -212,10 +272,19 @@ fn expect_failed_transact_status_should_work() { }, ExpectTransactStatus(vec![2].into()), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(70, 70); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(70, 70), XcmError::ExpectationFalse)); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(70, 70), error: XcmError::ExpectationFalse } + ); } #[test] @@ -235,10 +304,16 @@ fn clear_transact_status_should_work() { max_weight: Weight::from_parts(5000, 5000), }), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(80, 80); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(80, 80))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(80, 80) }); let expected_msg = Xcm(vec![QueryResponse { response: Response::DispatchResult(MaybeErrorCode::Success), query_id: 42, diff --git a/polkadot/xcm/xcm-builder/src/tests/version_subscriptions.rs b/polkadot/xcm/xcm-builder/src/tests/version_subscriptions.rs index 44ab7d34c51..e29e3a54661 100644 --- a/polkadot/xcm/xcm-builder/src/tests/version_subscriptions.rs +++ b/polkadot/xcm/xcm-builder/src/tests/version_subscriptions.rs @@ -25,23 +25,41 @@ fn simple_version_subscriptions_should_work() { SetAppendix(Xcm(vec![])), SubscribeVersion { query_id: 42, max_response_weight: Weight::from_parts(5000, 5000) }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(20, 20); - let r = XcmExecutor::::execute_xcm(origin, message, hash, weight_limit); - assert_eq!(r, Outcome::Error(XcmError::Barrier)); + let r = XcmExecutor::::prepare_and_execute( + origin, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Error { error: XcmError::Barrier }); let origin = Parachain(1000); let message = Xcm::(vec![SubscribeVersion { query_id: 42, max_response_weight: Weight::from_parts(5000, 5000), }]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(10, 10); - let r = XcmExecutor::::execute_xcm(origin, message.clone(), hash, weight_limit); - assert_eq!(r, Outcome::Error(XcmError::Barrier)); + let r = XcmExecutor::::prepare_and_execute( + origin, + message.clone(), + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Error { error: XcmError::Barrier }); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); assert_eq!( SubscriptionRequests::get(), @@ -53,33 +71,36 @@ fn simple_version_subscriptions_should_work() { fn version_subscription_instruction_should_work() { let origin = Parachain(1000); let message = Xcm::(vec![ - DescendOrigin(X1(AccountIndex64 { index: 1, network: None })), + DescendOrigin([AccountIndex64 { index: 1, network: None }].into()), SubscribeVersion { query_id: 42, max_response_weight: Weight::from_parts(5000, 5000) }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(20, 20); - let r = XcmExecutor::::execute_xcm_in_credit( + let r = XcmExecutor::::prepare_and_execute( origin, message, - hash, + &mut hash, weight_limit, weight_limit, ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(20, 20), XcmError::BadOrigin)); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(20, 20), error: XcmError::BadOrigin } + ); let message = Xcm::(vec![ SetAppendix(Xcm(vec![])), SubscribeVersion { query_id: 42, max_response_weight: Weight::from_parts(5000, 5000) }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm_in_credit( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( origin, message, - hash, + &mut hash, weight_limit, weight_limit, ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(20, 20) }); assert_eq!( SubscriptionRequests::get(), @@ -93,20 +114,38 @@ fn simple_version_unsubscriptions_should_work() { let origin = Parachain(1000); let message = Xcm::(vec![SetAppendix(Xcm(vec![])), UnsubscribeVersion]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(20, 20); - let r = XcmExecutor::::execute_xcm(origin, message, hash, weight_limit); - assert_eq!(r, Outcome::Error(XcmError::Barrier)); + let r = XcmExecutor::::prepare_and_execute( + origin, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Error { error: XcmError::Barrier }); let origin = Parachain(1000); let message = Xcm::(vec![UnsubscribeVersion]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(10, 10); - let r = XcmExecutor::::execute_xcm(origin, message.clone(), hash, weight_limit); - assert_eq!(r, Outcome::Error(XcmError::Barrier)); + let r = XcmExecutor::::prepare_and_execute( + origin, + message.clone(), + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Error { error: XcmError::Barrier }); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); assert_eq!(SubscriptionRequests::get(), vec![(Parent.into(), None)]); assert_eq!(sent_xcm(), vec![]); @@ -118,31 +157,34 @@ fn version_unsubscription_instruction_should_work() { // Not allowed to do it when origin has been changed. let message = Xcm::(vec![ - DescendOrigin(X1(AccountIndex64 { index: 1, network: None })), + DescendOrigin([AccountIndex64 { index: 1, network: None }].into()), UnsubscribeVersion, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(20, 20); - let r = XcmExecutor::::execute_xcm_in_credit( + let r = XcmExecutor::::prepare_and_execute( origin, message, - hash, + &mut hash, weight_limit, weight_limit, ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(20, 20), XcmError::BadOrigin)); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(20, 20), error: XcmError::BadOrigin } + ); // Fine to do it when origin is untouched. let message = Xcm::(vec![SetAppendix(Xcm(vec![])), UnsubscribeVersion]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm_in_credit( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( origin, message, - hash, + &mut hash, weight_limit, weight_limit, ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(20, 20) }); assert_eq!(SubscriptionRequests::get(), vec![(Parachain(1000).into(), None)]); assert_eq!(sent_xcm(), vec![]); diff --git a/polkadot/xcm/xcm-builder/src/tests/weight.rs b/polkadot/xcm/xcm-builder/src/tests/weight.rs index a2fb265413f..637e30cce99 100644 --- a/polkadot/xcm/xcm-builder/src/tests/weight.rs +++ b/polkadot/xcm/xcm-builder/src/tests/weight.rs @@ -74,45 +74,78 @@ fn errors_should_return_unused_weight() { // First xfer results in an error on the last message only TransferAsset { assets: (Here, 1u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }, // Second xfer results in error third message and after TransferAsset { assets: (Here, 2u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }, // Third xfer results in error second message and after TransferAsset { assets: (Here, 4u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }, ]); // Weight limit of 70 is needed. let limit = ::Weigher::weight(&mut message).unwrap(); assert_eq!(limit, Weight::from_parts(30, 30)); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Here, message.clone(), hash, limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(30, 30))); + let r = XcmExecutor::::prepare_and_execute( + Here, + message.clone(), + &mut hash, + limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(30, 30) }); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 7u128).into()]); assert_eq!(asset_list(Here), vec![(Here, 4u128).into()]); assert_eq!(sent_xcm(), vec![]); - let r = XcmExecutor::::execute_xcm(Here, message.clone(), hash, limit); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(30, 30), XcmError::NotWithdrawable)); + let r = XcmExecutor::::prepare_and_execute( + Here, + message.clone(), + &mut hash, + limit, + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(30, 30), error: XcmError::NotWithdrawable } + ); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 10u128).into()]); assert_eq!(asset_list(Here), vec![(Here, 1u128).into()]); assert_eq!(sent_xcm(), vec![]); - let r = XcmExecutor::::execute_xcm(Here, message.clone(), hash, limit); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(20, 20), XcmError::NotWithdrawable)); + let r = XcmExecutor::::prepare_and_execute( + Here, + message.clone(), + &mut hash, + limit, + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(20, 20), error: XcmError::NotWithdrawable } + ); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 11u128).into()]); assert_eq!(asset_list(Here), vec![]); assert_eq!(sent_xcm(), vec![]); - let r = XcmExecutor::::execute_xcm(Here, message, hash, limit); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NotWithdrawable)); + let r = XcmExecutor::::prepare_and_execute( + Here, + message, + &mut hash, + limit, + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NotWithdrawable } + ); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 11u128).into()]); assert_eq!(asset_list(Here), vec![]); assert_eq!(sent_xcm(), vec![]); @@ -148,8 +181,8 @@ fn weight_bounds_should_respect_instructions_limit() { #[test] fn weight_trader_tuple_should_work() { - let para_1: MultiLocation = Parachain(1).into(); - let para_2: MultiLocation = Parachain(2).into(); + let para_1: Location = Parachain(1).into(); + let para_2: Location = Parachain(2).into(); parameter_types! { pub static HereWeightPrice: (AssetId, u128, u128) = @@ -186,7 +219,11 @@ fn weight_trader_tuple_should_work() { let mut traders = Traders::new(); // trader one failed; trader two buys weight assert_eq!( - traders.buy_weight(Weight::from_parts(5, 5), fungible_multi_asset(para_1, 10).into(), &ctx), + traders.buy_weight( + Weight::from_parts(5, 5), + fungible_multi_asset(para_1.clone(), 10).into(), + &ctx + ), Ok(vec![].into()), ); // trader two refunds diff --git a/polkadot/xcm/xcm-builder/src/universal_exports.rs b/polkadot/xcm/xcm-builder/src/universal_exports.rs index 4aa6a0ef7a5..1d084e022c9 100644 --- a/polkadot/xcm/xcm-builder/src/universal_exports.rs +++ b/polkadot/xcm/xcm-builder/src/universal_exports.rs @@ -28,18 +28,18 @@ use SendError::*; /// chain, itself situated at `universal_local` within the consensus universe. If /// `dest` is not a location in remote consensus, then an error is returned. pub fn ensure_is_remote( - universal_local: impl Into, - dest: impl Into, -) -> Result<(NetworkId, InteriorMultiLocation), MultiLocation> { + universal_local: impl Into, + dest: impl Into, +) -> Result<(NetworkId, InteriorLocation), Location> { let dest = dest.into(); let universal_local = universal_local.into(); let local_net = match universal_local.global_consensus() { Ok(x) => x, Err(_) => return Err(dest), }; - let universal_destination: InteriorMultiLocation = universal_local + let universal_destination: InteriorLocation = universal_local .into_location() - .appended_with(dest) + .appended_with(dest.clone()) .map_err(|x| x.1)? .try_into()?; let (remote_dest, remote_net) = match universal_destination.split_first() { @@ -59,18 +59,18 @@ pub fn ensure_is_remote( pub struct UnpaidLocalExporter( PhantomData<(Exporter, UniversalLocation)>, ); -impl> SendXcm +impl> SendXcm for UnpaidLocalExporter { type Ticket = Exporter::Ticket; fn validate( - dest: &mut Option, + dest: &mut Option, xcm: &mut Option>, ) -> SendResult { let d = dest.take().ok_or(MissingArgument)?; let universal_source = UniversalLocation::get(); - let devolved = match ensure_is_remote(universal_source, d) { + let devolved = match ensure_is_remote(universal_source.clone(), d) { Ok(x) => x, Err(d) => { *dest = Some(d); @@ -96,18 +96,18 @@ pub trait ExporterFor { /// the bridge chain as well as payment for the use of the `ExportMessage` instruction. fn exporter_for( network: &NetworkId, - remote_location: &InteriorMultiLocation, + remote_location: &InteriorLocation, message: &Xcm<()>, - ) -> Option<(MultiLocation, Option)>; + ) -> Option<(Location, Option)>; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl ExporterFor for Tuple { fn exporter_for( network: &NetworkId, - remote_location: &InteriorMultiLocation, + remote_location: &InteriorLocation, message: &Xcm<()>, - ) -> Option<(MultiLocation, Option)> { + ) -> Option<(Location, Option)> { for_tuples!( #( if let Some(r) = Tuple::exporter_for(network, remote_location, message) { return Some(r); @@ -125,21 +125,21 @@ pub struct NetworkExportTableItem { /// If `Some`, the requested remote location must be equal to one of the items in the vector. /// These are locations in the remote network. /// If `None`, then the check is skipped. - pub remote_location_filter: Option>, + pub remote_location_filter: Option>, /// Locally-routable bridge with bridging capabilities to the `remote_network` and /// `remote_location`. See [`ExporterFor`] for more details. - pub bridge: MultiLocation, + pub bridge: Location, /// The local payment. /// See [`ExporterFor`] for more details. - pub payment: Option, + pub payment: Option, } impl NetworkExportTableItem { pub fn new( remote_network: NetworkId, - remote_location_filter: Option>, - bridge: MultiLocation, - payment: Option, + remote_location_filter: Option>, + bridge: Location, + payment: Option, ) -> Self { Self { remote_network, remote_location_filter, bridge, payment } } @@ -152,9 +152,9 @@ pub struct NetworkExportTable(sp_std::marker::PhantomData); impl>> ExporterFor for NetworkExportTable { fn exporter_for( network: &NetworkId, - remote_location: &InteriorMultiLocation, + remote_location: &InteriorLocation, _: &Xcm<()>, - ) -> Option<(MultiLocation, Option)> { + ) -> Option<(Location, Option)> { T::get() .into_iter() .find(|item| { @@ -194,16 +194,16 @@ pub fn forward_id_for(original_id: &XcmHash) -> XcmHash { pub struct UnpaidRemoteExporter( PhantomData<(Bridges, Router, UniversalLocation)>, ); -impl> SendXcm +impl> SendXcm for UnpaidRemoteExporter { type Ticket = Router::Ticket; fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, ) -> SendResult { - let d = dest.ok_or(MissingArgument)?; + let d = dest.clone().ok_or(MissingArgument)?; let devolved = ensure_is_remote(UniversalLocation::get(), d).map_err(|_| NotApplicable)?; let (remote_network, remote_location) = devolved; let xcm = msg.take().ok_or(MissingArgument)?; @@ -261,17 +261,18 @@ impl( PhantomData<(Bridges, Router, UniversalLocation)>, ); -impl> SendXcm +impl> SendXcm for SovereignPaidRemoteExporter { type Ticket = Router::Ticket; fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, ) -> SendResult { - let d = *dest.as_ref().ok_or(MissingArgument)?; - let devolved = ensure_is_remote(UniversalLocation::get(), d).map_err(|_| NotApplicable)?; + let d = dest.as_ref().ok_or(MissingArgument)?; + let devolved = + ensure_is_remote(UniversalLocation::get(), d.clone()).map_err(|_| NotApplicable)?; let (remote_network, remote_location) = devolved; let xcm = msg.take().ok_or(MissingArgument)?; @@ -299,7 +300,7 @@ impl, } @@ -386,8 +387,8 @@ pub struct BridgeBlobDispatcher( ); impl< Router: SendXcm, - OurPlace: Get, - OurPlaceBridgeInstance: Get>, + OurPlace: Get, + OurPlaceBridgeInstance: Get>, > DispatchBlob for BridgeBlobDispatcher { fn dispatch_blob(blob: Vec) -> Result<(), DispatchBlobError> { @@ -396,7 +397,7 @@ impl< our_universal.global_consensus().map_err(|()| DispatchBlobError::Unbridgable)?; let BridgeMessage { universal_dest, message } = Decode::decode(&mut &blob[..]).map_err(|_| DispatchBlobError::InvalidEncoding)?; - let universal_dest: InteriorMultiLocation = universal_dest + let universal_dest: InteriorLocation = universal_dest .try_into() .map_err(|_| DispatchBlobError::UnsupportedLocationVersion)?; // `universal_dest` is the desired destination within the universe: first we need to check @@ -437,9 +438,9 @@ pub struct HaulBlobExporter( /// ``` impl< Bridge: HaulBlob, - BridgedNetwork: Get, + BridgedNetwork: Get, DestinationVersion: GetVersion, - Price: Get, + Price: Get, > ExportXcm for HaulBlobExporter { type Ticket = (Vec, XcmHash); @@ -447,12 +448,12 @@ impl< fn validate( network: NetworkId, _channel: u32, - universal_source: &mut Option, - destination: &mut Option, + universal_source: &mut Option, + destination: &mut Option, message: &mut Option>, - ) -> Result<((Vec, XcmHash), MultiAssets), SendError> { + ) -> Result<((Vec, XcmHash), Assets), SendError> { let (bridged_network, bridged_network_location_parents) = { - let MultiLocation { parents, interior: mut junctions } = BridgedNetwork::get(); + let Location { parents, interior: mut junctions } = BridgedNetwork::get(); match junctions.take_first() { Some(GlobalConsensus(network)) => (network, parents), _ => return Err(SendError::NotApplicable), @@ -467,8 +468,8 @@ impl< let (universal_dest, version) = match dest.pushed_front_with(GlobalConsensus(bridged_network)) { Ok(d) => { - let version = DestinationVersion::get_version_for(&MultiLocation::from( - AncestorThen(bridged_network_location_parents, d), + let version = DestinationVersion::get_version_for(&Location::from( + AncestorThen(bridged_network_location_parents, d.clone()), )) .ok_or(SendError::DestinationUnsupported)?; (d, version) @@ -501,7 +502,7 @@ impl< let message = VersionedXcm::from(message) .into_version(version) .map_err(|()| SendError::DestinationUnsupported)?; - let universal_dest = VersionedInteriorMultiLocation::from(universal_dest) + let universal_dest = VersionedInteriorLocation::from(universal_dest) .into_version(version) .map_err(|()| SendError::DestinationUnsupported)?; @@ -548,10 +549,10 @@ mod tests { type Ticket = (); fn validate( - _destination: &mut Option, + _destination: &mut Option, _message: &mut Option>, ) -> SendResult { - Ok(((), MultiAssets::new())) + Ok(((), Assets::new())) } fn deliver(_ticket: Self::Ticket) -> Result { @@ -562,10 +563,10 @@ mod tests { /// Generic test case asserting that dest and msg is not consumed by `validate` implementation /// of `SendXcm` in case of expected result. fn ensure_validate_does_not_consume_dest_or_msg( - dest: MultiLocation, + dest: Location, assert_result: impl Fn(SendResult), ) { - let mut dest_wrapper = Some(dest); + let mut dest_wrapper = Some(dest.clone()); let msg = Xcm::<()>::new(); let mut msg_wrapper = Some(msg.clone()); @@ -580,19 +581,19 @@ mod tests { fn remote_exporters_does_not_consume_dest_or_msg_on_not_applicable() { frame_support::parameter_types! { pub Local: NetworkId = ByGenesis([0; 32]); - pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(Local::get()), Parachain(1234)); + pub UniversalLocation: InteriorLocation = [GlobalConsensus(Local::get()), Parachain(1234)].into(); pub DifferentRemote: NetworkId = ByGenesis([22; 32]); // no routers pub BridgeTable: Vec = vec![]; } // check with local destination (should be remote) - let local_dest = (Parent, Parachain(5678)).into(); - assert!(ensure_is_remote(UniversalLocation::get(), local_dest).is_err()); + let local_dest: Location = (Parent, Parachain(5678)).into(); + assert!(ensure_is_remote(UniversalLocation::get(), local_dest.clone()).is_err()); ensure_validate_does_not_consume_dest_or_msg::< UnpaidRemoteExporter, OkSender, UniversalLocation>, - >(local_dest, |result| assert_eq!(Err(NotApplicable), result)); + >(local_dest.clone(), |result| assert_eq!(Err(NotApplicable), result)); ensure_validate_does_not_consume_dest_or_msg::< SovereignPaidRemoteExporter< @@ -603,12 +604,12 @@ mod tests { >(local_dest, |result| assert_eq!(Err(NotApplicable), result)); // check with not applicable destination - let remote_dest = (Parent, Parent, DifferentRemote::get()).into(); - assert!(ensure_is_remote(UniversalLocation::get(), remote_dest).is_ok()); + let remote_dest: Location = (Parent, Parent, DifferentRemote::get()).into(); + assert!(ensure_is_remote(UniversalLocation::get(), remote_dest.clone()).is_ok()); ensure_validate_does_not_consume_dest_or_msg::< UnpaidRemoteExporter, OkSender, UniversalLocation>, - >(remote_dest, |result| assert_eq!(Err(NotApplicable), result)); + >(remote_dest.clone(), |result| assert_eq!(Err(NotApplicable), result)); ensure_validate_does_not_consume_dest_or_msg::< SovereignPaidRemoteExporter< @@ -623,15 +624,15 @@ mod tests { fn network_export_table_works() { frame_support::parameter_types! { pub NetworkA: NetworkId = ByGenesis([0; 32]); - pub Parachain1000InNetworkA: InteriorMultiLocation = X1(Parachain(1000)); - pub Parachain2000InNetworkA: InteriorMultiLocation = X1(Parachain(2000)); + pub Parachain1000InNetworkA: InteriorLocation = [Parachain(1000)].into(); + pub Parachain2000InNetworkA: InteriorLocation = [Parachain(2000)].into(); pub NetworkB: NetworkId = ByGenesis([1; 32]); - pub BridgeToALocation: MultiLocation = MultiLocation::new(1, X1(Parachain(1234))); - pub BridgeToBLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(4321))); + pub BridgeToALocation: Location = Location::new(1, [Parachain(1234)]); + pub BridgeToBLocation: Location = Location::new(1, [Parachain(4321)]); - pub PaymentForNetworkAAndParachain2000: MultiAsset = (MultiLocation::parent(), 150).into(); + pub PaymentForNetworkAAndParachain2000: Asset = (Location::parent(), 150).into(); pub BridgeTable: sp_std::vec::Vec = sp_std::vec![ // NetworkA allows `Parachain(1000)` as remote location WITHOUT payment. @@ -658,19 +659,19 @@ mod tests { ]; } - let test_data = vec![ - (NetworkA::get(), X1(Parachain(1000)), Some((BridgeToALocation::get(), None))), - (NetworkA::get(), X2(Parachain(1000), GeneralIndex(1)), None), + let test_data: Vec<(NetworkId, InteriorLocation, Option<(Location, Option)>)> = vec![ + (NetworkA::get(), [Parachain(1000)].into(), Some((BridgeToALocation::get(), None))), + (NetworkA::get(), [Parachain(1000), GeneralIndex(1)].into(), None), ( NetworkA::get(), - X1(Parachain(2000)), + [Parachain(2000)].into(), Some((BridgeToALocation::get(), Some(PaymentForNetworkAAndParachain2000::get()))), ), - (NetworkA::get(), X2(Parachain(2000), GeneralIndex(1)), None), - (NetworkA::get(), X1(Parachain(3000)), None), - (NetworkB::get(), X1(Parachain(1000)), Some((BridgeToBLocation::get(), None))), - (NetworkB::get(), X1(Parachain(2000)), Some((BridgeToBLocation::get(), None))), - (NetworkB::get(), X1(Parachain(3000)), Some((BridgeToBLocation::get(), None))), + (NetworkA::get(), [Parachain(2000), GeneralIndex(1)].into(), None), + (NetworkA::get(), [Parachain(3000)].into(), None), + (NetworkB::get(), [Parachain(1000)].into(), Some((BridgeToBLocation::get(), None))), + (NetworkB::get(), [Parachain(2000)].into(), Some((BridgeToBLocation::get(), None))), + (NetworkB::get(), [Parachain(3000)].into(), Some((BridgeToBLocation::get(), None))), ]; for (network, remote_location, expected_result) in test_data { diff --git a/polkadot/xcm/xcm-builder/src/weight.rs b/polkadot/xcm/xcm-builder/src/weight.rs index c16c52939a3..2ae6a043843 100644 --- a/polkadot/xcm/xcm-builder/src/weight.rs +++ b/polkadot/xcm/xcm-builder/src/weight.rs @@ -25,10 +25,10 @@ use frame_support::{ use parity_scale_codec::Decode; use sp_runtime::traits::{SaturatedConversion, Saturating, Zero}; use sp_std::{marker::PhantomData, result::Result}; -use xcm::latest::{prelude::*, Weight}; +use xcm::latest::{prelude::*, GetWeight, Weight}; use xcm_executor::{ traits::{WeightBounds, WeightTrader}, - Assets, + AssetsInHolding, }; pub struct FixedWeightBounds(PhantomData<(T, C, M)>); @@ -114,16 +114,16 @@ where } /// Function trait for handling some revenue. Similar to a negative imbalance (credit) handler, but -/// for a `MultiAsset`. Sensible implementations will deposit the asset in some known treasury or +/// for a `Asset`. Sensible implementations will deposit the asset in some known treasury or /// block-author account. pub trait TakeRevenue { - /// Do something with the given `revenue`, which is a single non-wildcard `MultiAsset`. - fn take_revenue(revenue: MultiAsset); + /// Do something with the given `revenue`, which is a single non-wildcard `Asset`. + fn take_revenue(revenue: Asset); } /// Null implementation just burns the revenue. impl TakeRevenue for () { - fn take_revenue(_revenue: MultiAsset) {} + fn take_revenue(_revenue: Asset) {} } /// Simple fee calculator that requires payment in a single fungible at a fixed rate. @@ -143,9 +143,9 @@ impl, R: TakeRevenue> WeightTrader for FixedRateOf fn buy_weight( &mut self, weight: Weight, - payment: Assets, + payment: AssetsInHolding, context: &XcmContext, - ) -> Result { + ) -> Result { log::trace!( target: "xcm::weight", "FixedRateOfFungible::buy_weight weight: {:?}, payment: {:?}, context: {:?}", @@ -165,7 +165,7 @@ impl, R: TakeRevenue> WeightTrader for FixedRateOf Ok(unused) } - fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { + fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { log::trace!(target: "xcm::weight", "FixedRateOfFungible::refund_weight weight: {:?}, context: {:?}", weight, context); let (id, units_per_second, units_per_mb) = T::get(); let weight = weight.min(self.0); @@ -194,22 +194,22 @@ impl, R: TakeRevenue> Drop for FixedRateOfFungible /// places any weight bought into the right account. pub struct UsingComponents< WeightToFee: WeightToFeeT, - AssetId: Get, + AssetIdValue: Get, AccountId, Currency: CurrencyT, OnUnbalanced: OnUnbalancedT, >( Weight, Currency::Balance, - PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>, + PhantomData<(WeightToFee, AssetIdValue, AccountId, Currency, OnUnbalanced)>, ); impl< WeightToFee: WeightToFeeT, - AssetId: Get, + AssetIdValue: Get, AccountId, Currency: CurrencyT, OnUnbalanced: OnUnbalancedT, - > WeightTrader for UsingComponents + > WeightTrader for UsingComponents { fn new() -> Self { Self(Weight::zero(), Zero::zero(), PhantomData) @@ -218,20 +218,20 @@ impl< fn buy_weight( &mut self, weight: Weight, - payment: Assets, + payment: AssetsInHolding, context: &XcmContext, - ) -> Result { + ) -> Result { log::trace!(target: "xcm::weight", "UsingComponents::buy_weight weight: {:?}, payment: {:?}, context: {:?}", weight, payment, context); let amount = WeightToFee::weight_to_fee(&weight); let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?; - let required = (Concrete(AssetId::get()), u128_amount).into(); + let required = (AssetId(AssetIdValue::get()), u128_amount).into(); let unused = payment.checked_sub(required).map_err(|_| XcmError::TooExpensive)?; self.0 = self.0.saturating_add(weight); self.1 = self.1.saturating_add(amount); Ok(unused) } - fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { + fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { log::trace!(target: "xcm::weight", "UsingComponents::refund_weight weight: {:?}, context: {:?}", weight, context); let weight = weight.min(self.0); let amount = WeightToFee::weight_to_fee(&weight); @@ -239,7 +239,7 @@ impl< self.1 = self.1.saturating_sub(amount); let amount: u128 = amount.saturated_into(); if amount > 0 { - Some((AssetId::get(), amount).into()) + Some((AssetIdValue::get(), amount).into()) } else { None } @@ -247,7 +247,7 @@ impl< } impl< WeightToFee: WeightToFeeT, - AssetId: Get, + AssetId: Get, AccountId, Currency: CurrencyT, OnUnbalanced: OnUnbalancedT, diff --git a/polkadot/xcm/xcm-builder/tests/mock/mod.rs b/polkadot/xcm/xcm-builder/tests/mock/mod.rs index 6b4d893f73c..e08099280ba 100644 --- a/polkadot/xcm/xcm-builder/tests/mock/mod.rs +++ b/polkadot/xcm/xcm-builder/tests/mock/mod.rs @@ -46,24 +46,24 @@ pub type AccountId = AccountId32; pub type Balance = u128; thread_local! { - pub static SENT_XCM: RefCell> = RefCell::new(Vec::new()); + pub static SENT_XCM: RefCell> = RefCell::new(Vec::new()); } -pub fn sent_xcm() -> Vec<(MultiLocation, opaque::Xcm, XcmHash)> { +pub fn sent_xcm() -> Vec<(Location, opaque::Xcm, XcmHash)> { SENT_XCM.with(|q| (*q.borrow()).clone()) } pub struct TestSendXcm; impl SendXcm for TestSendXcm { - type Ticket = (MultiLocation, Xcm<()>, XcmHash); + type Ticket = (Location, Xcm<()>, XcmHash); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, - ) -> SendResult<(MultiLocation, Xcm<()>, XcmHash)> { + ) -> SendResult<(Location, Xcm<()>, XcmHash)> { let msg = msg.take().unwrap(); let hash = fake_message_hash(&msg); let triplet = (dest.take().unwrap(), msg, hash); - Ok((triplet, MultiAssets::new())) + Ok((triplet, Assets::new())) } - fn deliver(triplet: (MultiLocation, Xcm<()>, XcmHash)) -> Result { + fn deliver(triplet: (Location, Xcm<()>, XcmHash)) -> Result { let hash = triplet.2; SENT_XCM.with(|q| q.borrow_mut().push(triplet)); Ok(hash) @@ -136,9 +136,9 @@ impl configuration::Config for Runtime { // aims to closely emulate the Kusama XcmConfig parameter_types! { - pub const KsmLocation: MultiLocation = MultiLocation::here(); + pub const KsmLocation: Location = Location::here(); pub const KusamaNetwork: NetworkId = NetworkId::Kusama; - pub UniversalLocation: InteriorMultiLocation = Here; + pub UniversalLocation: InteriorLocation = Here; pub CheckAccount: (AccountId, MintLocation) = (XcmPallet::check_account(), MintLocation::Local); } @@ -176,8 +176,8 @@ pub type Barrier = ( ); parameter_types! { - pub KusamaForAssetHub: (MultiAssetFilter, MultiLocation) = - (Wild(AllOf { id: Concrete(Here.into()), fun: WildFungible }), Parachain(1000).into()); + pub KusamaForAssetHub: (AssetFilter, Location) = + (Wild(AllOf { id: AssetId(Here.into()), fun: WildFungible }), Parachain(1000).into()); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 4; } diff --git a/polkadot/xcm/xcm-builder/tests/scenarios.rs b/polkadot/xcm/xcm-builder/tests/scenarios.rs index 36780b9f007..db37f85acdb 100644 --- a/polkadot/xcm/xcm-builder/tests/scenarios.rs +++ b/polkadot/xcm/xcm-builder/tests/scenarios.rs @@ -55,9 +55,15 @@ fn withdraw_and_deposit_works() { beneficiary: Parachain(other_para_id).into(), }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parachain(PARA_ID), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); let other_para_acc: AccountId = ParaId::from(other_para_id).into_account_truncating(); assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE - amount); assert_eq!(Balances::free_balance(other_para_acc), amount); @@ -79,19 +85,19 @@ fn transfer_asset_works() { assets: (Here, amount).into(), beneficiary: AccountId32 { network: None, id: bob.clone().into() }.into(), }]); - let hash = fake_message_hash(&message); - // Use `execute_xcm_in_credit` here to pass through the barrier - let r = XcmExecutor::::execute_xcm_in_credit( + let mut hash = fake_message_hash(&message); + // Use `prepare_and_execute` here to pass through the barrier + let r = XcmExecutor::::prepare_and_execute( AccountId32 { network: None, id: ALICE.into() }, message, - hash, + &mut hash, weight, weight, ); System::assert_last_event( pallet_balances::Event::Transfer { from: ALICE, to: bob.clone(), amount }.into(), ); - assert_eq!(r, Outcome::Complete(weight)); + assert_eq!(r, Outcome::Complete { used: weight }); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - amount); assert_eq!(Balances::free_balance(bob), INITIAL_BALANCE + amount); }); @@ -129,14 +135,20 @@ fn report_holding_works() { // is not triggered becasue the deposit fails ReportHolding { response_info: response_info.clone(), assets: All.into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parachain(PARA_ID), + message, + &mut hash, + weight, + Weight::zero(), + ); assert_eq!( r, - Outcome::Incomplete( - weight - BaseXcmWeight::get(), - XcmError::FailedToTransactAsset("AccountIdConversionFailed") - ) + Outcome::Incomplete { + used: weight - BaseXcmWeight::get(), + error: XcmError::FailedToTransactAsset("AccountIdConversionFailed") + } ); // there should be no query response sent for the failed deposit assert_eq!(mock::sent_xcm(), vec![]); @@ -153,9 +165,15 @@ fn report_holding_works() { // used to get a notification in case of success ReportHolding { response_info: response_info.clone(), assets: AllCounted(1).into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parachain(PARA_ID), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); let other_para_acc: AccountId = ParaId::from(other_para_id).into_account_truncating(); assert_eq!(Balances::free_balance(other_para_acc), amount); assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE - 2 * amount); @@ -209,9 +227,15 @@ fn teleport_to_asset_hub_works() { xcm: Xcm(teleport_effects.clone()), }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parachain(PARA_ID), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); let expected_msg = Xcm(vec![ReceiveTeleportedAsset((Parent, amount).into()), ClearOrigin] .into_iter() .chain(teleport_effects.clone().into_iter()) @@ -232,9 +256,15 @@ fn teleport_to_asset_hub_works() { xcm: Xcm(teleport_effects.clone()), }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parachain(PARA_ID), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); // 2 * amount because of the other teleport above assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE - 2 * amount); let expected_msg = Xcm(vec![ReceiveTeleportedAsset((Parent, amount).into()), ClearOrigin] @@ -282,10 +312,16 @@ fn reserve_based_transfer_works() { xcm: Xcm(transfer_effects.clone()), }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight = BaseXcmWeight::get() * 3; - let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let r = XcmExecutor::::prepare_and_execute( + Parachain(PARA_ID), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE - amount); let expected_msg = Xcm(vec![ReserveAssetDeposited((Parent, amount).into()), ClearOrigin] .into_iter() diff --git a/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs b/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs index c02cb218885..79d6cb1c411 100644 --- a/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs +++ b/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs @@ -65,7 +65,7 @@ fn basic_buy_fees_message_executes() { assert!(polkadot_test_runtime::System::events().iter().any(|r| matches!( r.event, polkadot_test_runtime::RuntimeEvent::Xcm(pallet_xcm::Event::Attempted { - outcome: Outcome::Complete(_) + outcome: Outcome::Complete { .. } }), ))); }); @@ -147,7 +147,7 @@ fn transact_recursion_limit_works() { .filter(|r| matches!( r.event, polkadot_test_runtime::RuntimeEvent::Xcm(pallet_xcm::Event::Attempted { - outcome: Outcome::Complete(_) + outcome: Outcome::Complete { .. } }), )) .count(), @@ -242,7 +242,7 @@ fn query_response_fires() { assert_eq!( polkadot_test_runtime::Xcm::query(query_id), Some(QueryStatus::Ready { - response: VersionedResponse::V3(Response::ExecutionResult(None)), + response: VersionedResponse::V4(Response::ExecutionResult(None)), at: 2u32.into() }), ) @@ -314,12 +314,12 @@ fn query_response_elicits_handler() { client.state_at(block_hash).expect("state should exist").inspect_state(|| { assert!(polkadot_test_runtime::System::events().iter().any(|r| matches!( - r.event, + &r.event, TestNotifier(ResponseReceived( - MultiLocation { parents: 0, interior: X1(Junction::AccountId32 { .. }) }, + location, q, Response::ExecutionResult(None), - )) if q == query_id, + )) if *q == query_id && matches!(location.unpack(), (0, [Junction::AccountId32 { .. }])), ))); }); } diff --git a/polkadot/xcm/xcm-executor/src/assets.rs b/polkadot/xcm/xcm-executor/src/assets.rs index 33f2ff218c7..4407752f702 100644 --- a/polkadot/xcm/xcm-executor/src/assets.rs +++ b/polkadot/xcm/xcm-executor/src/assets.rs @@ -21,16 +21,16 @@ use sp_std::{ prelude::*, }; use xcm::latest::{ - AssetId, AssetInstance, + Asset, AssetFilter, AssetId, AssetInstance, Assets, Fungibility::{Fungible, NonFungible}, - InteriorMultiLocation, MultiAsset, MultiAssetFilter, MultiAssets, MultiLocation, + InteriorLocation, Location, Reanchorable, + WildAsset::{All, AllCounted, AllOf, AllOfCounted}, WildFungibility::{Fungible as WildFungible, NonFungible as WildNonFungible}, - WildMultiAsset::{All, AllCounted, AllOf, AllOfCounted}, }; -/// List of non-wildcard fungible and non-fungible assets. +/// Map of non-wildcard fungible and non-fungible assets held in the holding register. #[derive(Default, Clone, RuntimeDebug, Eq, PartialEq)] -pub struct Assets { +pub struct AssetsInHolding { /// The fungible assets. pub fungible: BTreeMap, @@ -40,16 +40,16 @@ pub struct Assets { pub non_fungible: BTreeSet<(AssetId, AssetInstance)>, } -impl From for Assets { - fn from(asset: MultiAsset) -> Assets { +impl From for AssetsInHolding { + fn from(asset: Asset) -> AssetsInHolding { let mut result = Self::default(); result.subsume(asset); result } } -impl From> for Assets { - fn from(assets: Vec) -> Assets { +impl From> for AssetsInHolding { + fn from(assets: Vec) -> AssetsInHolding { let mut result = Self::default(); for asset in assets.into_iter() { result.subsume(asset) @@ -58,21 +58,21 @@ impl From> for Assets { } } -impl From for Assets { - fn from(assets: MultiAssets) -> Assets { +impl From for AssetsInHolding { + fn from(assets: Assets) -> AssetsInHolding { assets.into_inner().into() } } -impl From for Vec { - fn from(a: Assets) -> Self { +impl From for Vec { + fn from(a: AssetsInHolding) -> Self { a.into_assets_iter().collect() } } -impl From for MultiAssets { - fn from(a: Assets) -> Self { - a.into_assets_iter().collect::>().into() +impl From for Assets { + fn from(a: AssetsInHolding) -> Self { + a.into_assets_iter().collect::>().into() } } @@ -80,10 +80,10 @@ impl From for MultiAssets { #[derive(Debug)] pub enum TakeError { /// There was an attempt to take an asset without saturating (enough of) which did not exist. - AssetUnderflow(MultiAsset), + AssetUnderflow(Asset), } -impl Assets { +impl AssetsInHolding { /// New value, containing no assets. pub fn new() -> Self { Self::default() @@ -100,41 +100,41 @@ impl Assets { } /// A borrowing iterator over the fungible assets. - pub fn fungible_assets_iter(&self) -> impl Iterator + '_ { + pub fn fungible_assets_iter(&self) -> impl Iterator + '_ { self.fungible .iter() - .map(|(id, &amount)| MultiAsset { fun: Fungible(amount), id: *id }) + .map(|(id, &amount)| Asset { fun: Fungible(amount), id: id.clone() }) } /// A borrowing iterator over the non-fungible assets. - pub fn non_fungible_assets_iter(&self) -> impl Iterator + '_ { + pub fn non_fungible_assets_iter(&self) -> impl Iterator + '_ { self.non_fungible .iter() - .map(|(id, instance)| MultiAsset { fun: NonFungible(*instance), id: *id }) + .map(|(id, instance)| Asset { fun: NonFungible(*instance), id: id.clone() }) } /// A consuming iterator over all assets. - pub fn into_assets_iter(self) -> impl Iterator { + pub fn into_assets_iter(self) -> impl Iterator { self.fungible .into_iter() - .map(|(id, amount)| MultiAsset { fun: Fungible(amount), id }) + .map(|(id, amount)| Asset { fun: Fungible(amount), id }) .chain( self.non_fungible .into_iter() - .map(|(id, instance)| MultiAsset { fun: NonFungible(instance), id }), + .map(|(id, instance)| Asset { fun: NonFungible(instance), id }), ) } /// A borrowing iterator over all assets. - pub fn assets_iter(&self) -> impl Iterator + '_ { + pub fn assets_iter(&self) -> impl Iterator + '_ { self.fungible_assets_iter().chain(self.non_fungible_assets_iter()) } /// Mutate `self` to contain all given `assets`, saturating if necessary. /// - /// NOTE: [`Assets`] are always sorted, allowing us to optimize this function from `O(n^2)` to - /// `O(n)`. - pub fn subsume_assets(&mut self, mut assets: Assets) { + /// NOTE: [`AssetsInHolding`] are always sorted, allowing us to optimize this function from + /// `O(n^2)` to `O(n)`. + pub fn subsume_assets(&mut self, mut assets: AssetsInHolding) { let mut f_iter = assets.fungible.iter_mut(); let mut g_iter = self.fungible.iter_mut(); if let (Some(mut f), Some(mut g)) = (f_iter.next(), g_iter.next()) { @@ -166,7 +166,7 @@ impl Assets { /// Mutate `self` to contain the given `asset`, saturating if necessary. /// /// Wildcard values of `asset` do nothing. - pub fn subsume(&mut self, asset: MultiAsset) { + pub fn subsume(&mut self, asset: Asset) { match asset.fun { Fungible(amount) => { self.fungible @@ -180,18 +180,18 @@ impl Assets { } } - /// Swaps two mutable Assets, without deinitializing either one. - pub fn swapped(&mut self, mut with: Assets) -> Self { + /// Swaps two mutable AssetsInHolding, without deinitializing either one. + pub fn swapped(&mut self, mut with: AssetsInHolding) -> Self { mem::swap(&mut *self, &mut with); with } - /// Alter any concretely identified assets by prepending the given `MultiLocation`. + /// Alter any concretely identified assets by prepending the given `Location`. /// /// WARNING: For now we consider this infallible and swallow any errors. It is thus the caller's /// responsibility to ensure that any internal asset IDs are able to be prepended without /// overflow. - pub fn prepend_location(&mut self, prepend: &MultiLocation) { + pub fn prepend_location(&mut self, prepend: &Location) { let mut fungible = Default::default(); mem::swap(&mut self.fungible, &mut fungible); self.fungible = fungible @@ -218,8 +218,8 @@ impl Assets { /// Any assets which were unable to be reanchored are introduced into `failed_bin`. pub fn reanchor( &mut self, - target: &MultiLocation, - context: InteriorMultiLocation, + target: &Location, + context: &InteriorLocation, mut maybe_failed_bin: Option<&mut Self>, ) { let mut fungible = Default::default(); @@ -249,22 +249,22 @@ impl Assets { } /// Returns `true` if `asset` is contained within `self`. - pub fn contains_asset(&self, asset: &MultiAsset) -> bool { + pub fn contains_asset(&self, asset: &Asset) -> bool { match asset { - MultiAsset { fun: Fungible(amount), id } => + Asset { fun: Fungible(amount), id } => self.fungible.get(id).map_or(false, |a| a >= amount), - MultiAsset { fun: NonFungible(instance), id } => - self.non_fungible.contains(&(*id, *instance)), + Asset { fun: NonFungible(instance), id } => + self.non_fungible.contains(&(id.clone(), *instance)), } } /// Returns `true` if all `assets` are contained within `self`. - pub fn contains_assets(&self, assets: &MultiAssets) -> bool { + pub fn contains_assets(&self, assets: &Assets) -> bool { assets.inner().iter().all(|a| self.contains_asset(a)) } /// Returns `true` if all `assets` are contained within `self`. - pub fn contains(&self, assets: &Assets) -> bool { + pub fn contains(&self, assets: &AssetsInHolding) -> bool { assets .fungible .iter() @@ -274,16 +274,16 @@ impl Assets { /// Returns an error unless all `assets` are contained in `self`. In the case of an error, the /// first asset in `assets` which is not wholly in `self` is returned. - pub fn ensure_contains(&self, assets: &MultiAssets) -> Result<(), TakeError> { + pub fn ensure_contains(&self, assets: &Assets) -> Result<(), TakeError> { for asset in assets.inner().iter() { match asset { - MultiAsset { fun: Fungible(amount), id } => { + Asset { fun: Fungible(amount), id } => { if self.fungible.get(id).map_or(true, |a| a < amount) { - return Err(TakeError::AssetUnderflow((*id, *amount).into())) + return Err(TakeError::AssetUnderflow((id.clone(), *amount).into())) } }, - MultiAsset { fun: NonFungible(instance), id } => { - let id_instance = (*id, *instance); + Asset { fun: NonFungible(instance), id } => { + let id_instance = (id.clone(), *instance); if !self.non_fungible.contains(&id_instance) { return Err(TakeError::AssetUnderflow(id_instance.into())) } @@ -308,16 +308,16 @@ impl Assets { /// of) a definite asset to be removed. fn general_take( &mut self, - mask: MultiAssetFilter, + mask: AssetFilter, saturate: bool, - ) -> Result { - let mut taken = Assets::new(); + ) -> Result { + let mut taken = AssetsInHolding::new(); let maybe_limit = mask.limit().map(|x| x as usize); match mask { // TODO: Counted variants where we define `limit`. - MultiAssetFilter::Wild(All) | MultiAssetFilter::Wild(AllCounted(_)) => { + AssetFilter::Wild(All) | AssetFilter::Wild(AllCounted(_)) => { if maybe_limit.map_or(true, |l| self.len() <= l) { - return Ok(self.swapped(Assets::new())) + return Ok(self.swapped(AssetsInHolding::new())) } else { let fungible = mem::replace(&mut self.fungible, Default::default()); fungible.into_iter().for_each(|(c, amount)| { @@ -337,15 +337,15 @@ impl Assets { }); } }, - MultiAssetFilter::Wild(AllOfCounted { fun: WildFungible, id, .. }) | - MultiAssetFilter::Wild(AllOf { fun: WildFungible, id }) => + AssetFilter::Wild(AllOfCounted { fun: WildFungible, id, .. }) | + AssetFilter::Wild(AllOf { fun: WildFungible, id }) => if maybe_limit.map_or(true, |l| l >= 1) { if let Some((id, amount)) = self.fungible.remove_entry(&id) { taken.fungible.insert(id, amount); } }, - MultiAssetFilter::Wild(AllOfCounted { fun: WildNonFungible, id, .. }) | - MultiAssetFilter::Wild(AllOf { fun: WildNonFungible, id }) => { + AssetFilter::Wild(AllOfCounted { fun: WildNonFungible, id, .. }) | + AssetFilter::Wild(AllOf { fun: WildNonFungible, id }) => { let non_fungible = mem::replace(&mut self.non_fungible, Default::default()); non_fungible.into_iter().for_each(|(c, instance)| { if c == id && maybe_limit.map_or(true, |l| taken.len() < l) { @@ -355,13 +355,13 @@ impl Assets { } }); }, - MultiAssetFilter::Definite(assets) => { + AssetFilter::Definite(assets) => { if !saturate { self.ensure_contains(&assets)?; } for asset in assets.into_inner().into_iter() { match asset { - MultiAsset { fun: Fungible(amount), id } => { + Asset { fun: Fungible(amount), id } => { let (remove, amount) = match self.fungible.get_mut(&id) { Some(self_amount) => { let amount = amount.min(*self_amount); @@ -374,10 +374,10 @@ impl Assets { self.fungible.remove(&id); } if amount > 0 { - taken.subsume(MultiAsset::from((id, amount)).into()); + taken.subsume(Asset::from((id, amount)).into()); } }, - MultiAsset { fun: NonFungible(instance), id } => { + Asset { fun: NonFungible(instance), id } => { let id_instance = (id, instance); if self.non_fungible.remove(&id_instance) { taken.subsume(id_instance.into()) @@ -395,7 +395,7 @@ impl Assets { /// /// Returns `Ok` with the non-wildcard equivalence of `mask` taken and mutates `self` to its /// value minus `mask` if `self` contains `asset`, and return `Err` otherwise. - pub fn saturating_take(&mut self, asset: MultiAssetFilter) -> Assets { + pub fn saturating_take(&mut self, asset: AssetFilter) -> AssetsInHolding { self.general_take(asset, true) .expect("general_take never results in error when saturating") } @@ -405,13 +405,13 @@ impl Assets { /// /// Returns `Ok` with the non-wildcard equivalence of `asset` taken and mutates `self` to its /// value minus `asset` if `self` contains `asset`, and return `Err` otherwise. - pub fn try_take(&mut self, mask: MultiAssetFilter) -> Result { + pub fn try_take(&mut self, mask: AssetFilter) -> Result { self.general_take(mask, false) } /// Consumes `self` and returns its original value excluding `asset` iff it contains at least /// `asset`. - pub fn checked_sub(mut self, asset: MultiAsset) -> Result { + pub fn checked_sub(mut self, asset: Asset) -> Result { match asset.fun { Fungible(amount) => { let remove = if let Some(balance) = self.fungible.get_mut(&asset.id) { @@ -446,66 +446,66 @@ impl Assets { /// Example: /// /// ``` - /// use staging_xcm_executor::Assets; + /// use staging_xcm_executor::AssetsInHolding; /// use xcm::latest::prelude::*; - /// let assets_i_have: Assets = vec![ (Here, 100).into(), ([0; 32], 100).into() ].into(); - /// let assets_they_want: MultiAssetFilter = vec![ (Here, 200).into(), ([0; 32], 50).into() ].into(); + /// let assets_i_have: AssetsInHolding = vec![ (Here, 100).into(), (Junctions::from([GeneralIndex(0)]), 100).into() ].into(); + /// let assets_they_want: AssetFilter = vec![ (Here, 200).into(), (Junctions::from([GeneralIndex(0)]), 50).into() ].into(); /// - /// let assets_we_can_trade: Assets = assets_i_have.min(&assets_they_want); + /// let assets_we_can_trade: AssetsInHolding = assets_i_have.min(&assets_they_want); /// assert_eq!(assets_we_can_trade.into_assets_iter().collect::>(), vec![ - /// (Here, 100).into(), ([0; 32], 50).into(), + /// (Here, 100).into(), (Junctions::from([GeneralIndex(0)]), 50).into(), /// ]); /// ``` - pub fn min(&self, mask: &MultiAssetFilter) -> Assets { - let mut masked = Assets::new(); + pub fn min(&self, mask: &AssetFilter) -> AssetsInHolding { + let mut masked = AssetsInHolding::new(); let maybe_limit = mask.limit().map(|x| x as usize); if maybe_limit.map_or(false, |l| l == 0) { return masked } match mask { - MultiAssetFilter::Wild(All) | MultiAssetFilter::Wild(AllCounted(_)) => { + AssetFilter::Wild(All) | AssetFilter::Wild(AllCounted(_)) => { if maybe_limit.map_or(true, |l| self.len() <= l) { return self.clone() } else { - for (&c, &amount) in self.fungible.iter() { - masked.fungible.insert(c, amount); + for (c, &amount) in self.fungible.iter() { + masked.fungible.insert(c.clone(), amount); if maybe_limit.map_or(false, |l| masked.len() >= l) { return masked } } for (c, instance) in self.non_fungible.iter() { - masked.non_fungible.insert((*c, *instance)); + masked.non_fungible.insert((c.clone(), *instance)); if maybe_limit.map_or(false, |l| masked.len() >= l) { return masked } } } }, - MultiAssetFilter::Wild(AllOfCounted { fun: WildFungible, id, .. }) | - MultiAssetFilter::Wild(AllOf { fun: WildFungible, id }) => + AssetFilter::Wild(AllOfCounted { fun: WildFungible, id, .. }) | + AssetFilter::Wild(AllOf { fun: WildFungible, id }) => if let Some(&amount) = self.fungible.get(&id) { - masked.fungible.insert(*id, amount); + masked.fungible.insert(id.clone(), amount); }, - MultiAssetFilter::Wild(AllOfCounted { fun: WildNonFungible, id, .. }) | - MultiAssetFilter::Wild(AllOf { fun: WildNonFungible, id }) => + AssetFilter::Wild(AllOfCounted { fun: WildNonFungible, id, .. }) | + AssetFilter::Wild(AllOf { fun: WildNonFungible, id }) => for (c, instance) in self.non_fungible.iter() { if c == id { - masked.non_fungible.insert((*c, *instance)); + masked.non_fungible.insert((c.clone(), *instance)); if maybe_limit.map_or(false, |l| masked.len() >= l) { return masked } } }, - MultiAssetFilter::Definite(assets) => + AssetFilter::Definite(assets) => for asset in assets.inner().iter() { match asset { - MultiAsset { fun: Fungible(amount), id } => { + Asset { fun: Fungible(amount), id } => { if let Some(m) = self.fungible.get(id) { - masked.subsume((*id, Fungible(*amount.min(m))).into()); + masked.subsume((id.clone(), Fungible(*amount.min(m))).into()); } }, - MultiAsset { fun: NonFungible(instance), id } => { - let id_instance = (*id, *instance); + Asset { fun: NonFungible(instance), id } => { + let id_instance = (id.clone(), *instance); if self.non_fungible.contains(&id_instance) { masked.subsume(id_instance.into()); } @@ -522,30 +522,18 @@ mod tests { use super::*; use xcm::latest::prelude::*; #[allow(non_snake_case)] - /// Abstract fungible constructor - fn AF(id: u8, amount: u128) -> MultiAsset { - ([id; 32], amount).into() - } - #[allow(non_snake_case)] - /// Abstract non-fungible constructor - fn ANF(class: u8, instance_id: u8) -> MultiAsset { - ([class; 32], [instance_id; 4]).into() - } - #[allow(non_snake_case)] /// Concrete fungible constructor - fn CF(amount: u128) -> MultiAsset { + fn CF(amount: u128) -> Asset { (Here, amount).into() } #[allow(non_snake_case)] /// Concrete non-fungible constructor - fn CNF(instance_id: u8) -> MultiAsset { + fn CNF(instance_id: u8) -> Asset { (Here, [instance_id; 4]).into() } - fn test_assets() -> Assets { - let mut assets = Assets::new(); - assets.subsume(AF(1, 100)); - assets.subsume(ANF(2, 20)); + fn test_assets() -> AssetsInHolding { + let mut assets = AssetsInHolding::new(); assets.subsume(CF(300)); assets.subsume(CNF(40)); assets @@ -554,9 +542,7 @@ mod tests { #[test] fn subsume_assets_works() { let t1 = test_assets(); - let mut t2 = Assets::new(); - t2.subsume(AF(1, 50)); - t2.subsume(ANF(2, 10)); + let mut t2 = AssetsInHolding::new(); t2.subsume(CF(300)); t2.subsume(CNF(50)); let mut r1 = t1.clone(); @@ -571,63 +557,48 @@ mod tests { #[test] fn checked_sub_works() { let t = test_assets(); - let t = t.checked_sub(AF(1, 50)).unwrap(); - let t = t.checked_sub(AF(1, 51)).unwrap_err(); - let t = t.checked_sub(AF(1, 50)).unwrap(); - let t = t.checked_sub(AF(1, 1)).unwrap_err(); let t = t.checked_sub(CF(150)).unwrap(); let t = t.checked_sub(CF(151)).unwrap_err(); let t = t.checked_sub(CF(150)).unwrap(); let t = t.checked_sub(CF(1)).unwrap_err(); - let t = t.checked_sub(ANF(2, 21)).unwrap_err(); - let t = t.checked_sub(ANF(2, 20)).unwrap(); - let t = t.checked_sub(ANF(2, 20)).unwrap_err(); let t = t.checked_sub(CNF(41)).unwrap_err(); let t = t.checked_sub(CNF(40)).unwrap(); let t = t.checked_sub(CNF(40)).unwrap_err(); - assert_eq!(t, Assets::new()); + assert_eq!(t, AssetsInHolding::new()); } #[test] fn into_assets_iter_works() { let assets = test_assets(); let mut iter = assets.into_assets_iter(); - // Order defined by implementation: CF, AF, CNF, ANF + // Order defined by implementation: CF, CNF assert_eq!(Some(CF(300)), iter.next()); - assert_eq!(Some(AF(1, 100)), iter.next()); assert_eq!(Some(CNF(40)), iter.next()); - assert_eq!(Some(ANF(2, 20)), iter.next()); assert_eq!(None, iter.next()); } #[test] fn assets_into_works() { - let mut assets_vec: Vec = Vec::new(); - assets_vec.push(AF(1, 100)); - assets_vec.push(ANF(2, 20)); + let mut assets_vec: Vec = Vec::new(); assets_vec.push(CF(300)); assets_vec.push(CNF(40)); // Push same group of tokens again - assets_vec.push(AF(1, 100)); - assets_vec.push(ANF(2, 20)); assets_vec.push(CF(300)); assets_vec.push(CNF(40)); - let assets: Assets = assets_vec.into(); + let assets: AssetsInHolding = assets_vec.into(); let mut iter = assets.into_assets_iter(); // Fungibles add assert_eq!(Some(CF(600)), iter.next()); - assert_eq!(Some(AF(1, 200)), iter.next()); // Non-fungibles collapse assert_eq!(Some(CNF(40)), iter.next()); - assert_eq!(Some(ANF(2, 20)), iter.next()); assert_eq!(None, iter.next()); } #[test] fn min_all_and_none_works() { let assets = test_assets(); - let none = MultiAssets::new().into(); + let none = Assets::new().into(); let all = All.into(); let none_min = assets.min(&none); @@ -638,43 +609,15 @@ mod tests { #[test] fn min_counted_works() { - let mut assets = Assets::new(); - assets.subsume(AF(1, 100)); - assets.subsume(ANF(2, 20)); + let mut assets = AssetsInHolding::new(); assets.subsume(CNF(40)); - assets.subsume(AF(10, 50)); - assets.subsume(ANF(2, 40)); - assets.subsume(ANF(2, 30)); assets.subsume(CF(3000)); assets.subsume(CNF(80)); - assets.subsume(ANF(3, 10)); - let fungible = WildMultiAsset::from(([1u8; 32], WildFungible)).counted(2).into(); - let non_fungible = WildMultiAsset::from(([2u8; 32], WildNonFungible)).counted(2).into(); - let all = WildMultiAsset::AllCounted(6).into(); + let all = WildAsset::AllCounted(6).into(); - let fungible = assets.min(&fungible); - let fungible = fungible.assets_iter().collect::>(); - assert_eq!(fungible, vec![AF(1, 100)]); - let non_fungible = assets.min(&non_fungible); - let non_fungible = non_fungible.assets_iter().collect::>(); - assert_eq!(non_fungible, vec![ANF(2, 20), ANF(2, 30)]); let all = assets.min(&all); let all = all.assets_iter().collect::>(); - assert_eq!(all, vec![CF(3000), AF(1, 100), AF(10, 50), CNF(40), CNF(80), ANF(2, 20),]); - } - - #[test] - fn min_all_abstract_works() { - let assets = test_assets(); - let fungible = Wild(([1u8; 32], WildFungible).into()); - let non_fungible = Wild(([2u8; 32], WildNonFungible).into()); - - let fungible = assets.min(&fungible); - let fungible = fungible.assets_iter().collect::>(); - assert_eq!(fungible, vec![AF(1, 100)]); - let non_fungible = assets.min(&non_fungible); - let non_fungible = non_fungible.assets_iter().collect::>(); - assert_eq!(non_fungible, vec![ANF(2, 20)]); + assert_eq!(all, vec![CF(3000), CNF(40), CNF(80)]); } #[test] @@ -695,20 +638,16 @@ mod tests { fn min_basic_works() { let assets1 = test_assets(); - let mut assets2 = Assets::new(); - // This is less than 100, so it will decrease to 50 - assets2.subsume(AF(1, 50)); - // This asset does not exist, so not included - assets2.subsume(ANF(2, 40)); + let mut assets2 = AssetsInHolding::new(); // This is more then 300, so it should stay at 300 assets2.subsume(CF(600)); // This asset should be included assets2.subsume(CNF(40)); - let assets2: MultiAssets = assets2.into(); + let assets2: Assets = assets2.into(); let assets_min = assets1.min(&assets2.into()); let assets_min = assets_min.into_assets_iter().collect::>(); - assert_eq!(assets_min, vec![CF(300), AF(1, 50), CNF(40)]); + assert_eq!(assets_min, vec![CF(300), CNF(40)]); } #[test] @@ -724,23 +663,6 @@ mod tests { assert!(all_iter.eq(test_assets().assets_iter())); } - #[test] - fn saturating_take_all_abstract_works() { - let mut assets = test_assets(); - let fungible = Wild(([1u8; 32], WildFungible).into()); - let non_fungible = Wild(([2u8; 32], WildNonFungible).into()); - - let fungible = assets.saturating_take(fungible); - let fungible = fungible.assets_iter().collect::>(); - assert_eq!(fungible, vec![AF(1, 100)]); - let non_fungible = assets.saturating_take(non_fungible); - let non_fungible = non_fungible.assets_iter().collect::>(); - assert_eq!(non_fungible, vec![ANF(2, 20)]); - // Assets drained of abstract - let final_assets = assets.assets_iter().collect::>(); - assert_eq!(final_assets, vec![CF(300), CNF(40)]); - } - #[test] fn saturating_take_all_concrete_works() { let mut assets = test_assets(); @@ -753,102 +675,49 @@ mod tests { let non_fungible = assets.saturating_take(non_fungible); let non_fungible = non_fungible.assets_iter().collect::>(); assert_eq!(non_fungible, vec![CNF(40)]); - // Assets drained of concrete - let assets = assets.assets_iter().collect::>(); - assert_eq!(assets, vec![AF(1, 100), ANF(2, 20)]); } #[test] fn saturating_take_basic_works() { let mut assets1 = test_assets(); - let mut assets2 = Assets::new(); - // We should take 50 - assets2.subsume(AF(1, 50)); - // This asset should not be taken - assets2.subsume(ANF(2, 40)); + let mut assets2 = AssetsInHolding::new(); // This is more then 300, so it takes everything assets2.subsume(CF(600)); // This asset should be taken assets2.subsume(CNF(40)); - let assets2: MultiAssets = assets2.into(); + let assets2: Assets = assets2.into(); let taken = assets1.saturating_take(assets2.into()); let taken = taken.into_assets_iter().collect::>(); - assert_eq!(taken, vec![CF(300), AF(1, 50), CNF(40)]); - - let assets = assets1.into_assets_iter().collect::>(); - assert_eq!(assets, vec![AF(1, 50), ANF(2, 20)]); + assert_eq!(taken, vec![CF(300), CNF(40)]); } #[test] fn try_take_all_counted_works() { - let mut assets = Assets::new(); - assets.subsume(AF(1, 100)); - assets.subsume(ANF(2, 20)); + let mut assets = AssetsInHolding::new(); assets.subsume(CNF(40)); - assets.subsume(AF(10, 50)); - assets.subsume(ANF(2, 40)); - assets.subsume(ANF(2, 30)); assets.subsume(CF(3000)); assets.subsume(CNF(80)); - assets.subsume(ANF(3, 10)); - let all = assets.try_take(WildMultiAsset::AllCounted(6).into()).unwrap(); - assert_eq!( - MultiAssets::from(all).inner(), - &vec![CF(3000), AF(1, 100), AF(10, 50), CNF(40), CNF(80), ANF(2, 20),] - ); - assert_eq!(MultiAssets::from(assets).inner(), &vec![ANF(2, 30), ANF(2, 40), ANF(3, 10),]); + let all = assets.try_take(WildAsset::AllCounted(6).into()).unwrap(); + assert_eq!(Assets::from(all).inner(), &vec![CF(3000), CNF(40), CNF(80)]); } #[test] fn try_take_fungibles_counted_works() { - let mut assets = Assets::new(); - assets.subsume(AF(1, 100)); - assets.subsume(ANF(2, 20)); + let mut assets = AssetsInHolding::new(); assets.subsume(CNF(40)); - assets.subsume(AF(10, 50)); - assets.subsume(ANF(2, 40)); - assets.subsume(ANF(2, 30)); assets.subsume(CF(3000)); assets.subsume(CNF(80)); - assets.subsume(ANF(3, 10)); - let mask = WildMultiAsset::from(([1u8; 32], WildFungible)).counted(2).into(); - let taken = assets.try_take(mask).unwrap(); - assert_eq!(MultiAssets::from(taken).inner(), &vec![AF(1, 100)]); - assert_eq!( - MultiAssets::from(assets).inner(), - &vec![ - CF(3000), - AF(10, 50), - CNF(40), - CNF(80), - ANF(2, 20), - ANF(2, 30), - ANF(2, 40), - ANF(3, 10), - ] - ); + assert_eq!(Assets::from(assets).inner(), &vec![CF(3000), CNF(40), CNF(80),]); } #[test] fn try_take_non_fungibles_counted_works() { - let mut assets = Assets::new(); - assets.subsume(AF(1, 100)); - assets.subsume(ANF(2, 20)); + let mut assets = AssetsInHolding::new(); assets.subsume(CNF(40)); - assets.subsume(AF(10, 50)); - assets.subsume(ANF(2, 40)); - assets.subsume(ANF(2, 30)); assets.subsume(CF(3000)); assets.subsume(CNF(80)); - assets.subsume(ANF(3, 10)); - let mask = WildMultiAsset::from(([2u8; 32], WildNonFungible)).counted(2).into(); - let taken = assets.try_take(mask).unwrap(); - assert_eq!(MultiAssets::from(taken).inner(), &vec![ANF(2, 20), ANF(2, 30),]); - assert_eq!( - MultiAssets::from(assets).inner(), - &vec![CF(3000), AF(1, 100), AF(10, 50), CNF(40), CNF(80), ANF(2, 40), ANF(3, 10),] - ); + assert_eq!(Assets::from(assets).inner(), &vec![CF(3000), CNF(40), CNF(80)]); } } diff --git a/polkadot/xcm/xcm-executor/src/config.rs b/polkadot/xcm/xcm-executor/src/config.rs index 2ff12cd7a53..3f1ea6d1fb8 100644 --- a/polkadot/xcm/xcm-executor/src/config.rs +++ b/polkadot/xcm/xcm-executor/src/config.rs @@ -41,17 +41,17 @@ pub trait Config { type OriginConverter: ConvertOrigin<::RuntimeOrigin>; /// Combinations of (Asset, Location) pairs which we trust as reserves. - type IsReserve: ContainsPair; + type IsReserve: ContainsPair; /// Combinations of (Asset, Location) pairs which we trust as teleporters. - type IsTeleporter: ContainsPair; + type IsTeleporter: ContainsPair; /// A list of (Origin, Target) pairs allowing a given Origin to be substituted with its /// corresponding Target pair. - type Aliasers: ContainsPair; + type Aliasers: ContainsPair; /// This chain's Universal Location. - type UniversalLocation: Get; + type UniversalLocation: Get; /// Whether we should execute the given XCM at all. type Barrier: ShouldExecute; @@ -98,7 +98,7 @@ pub trait Config { /// The origin locations and specific universal junctions to which they are allowed to elevate /// themselves. - type UniversalAliases: Contains<(MultiLocation, Junction)>; + type UniversalAliases: Contains<(Location, Junction)>; /// The call dispatcher used by XCM. /// diff --git a/polkadot/xcm/xcm-executor/src/lib.rs b/polkadot/xcm/xcm-executor/src/lib.rs index 665b051c130..1f5f2eba5e2 100644 --- a/polkadot/xcm/xcm-executor/src/lib.rs +++ b/polkadot/xcm/xcm-executor/src/lib.rs @@ -36,7 +36,7 @@ use traits::{ }; mod assets; -pub use assets::Assets; +pub use assets::AssetsInHolding; mod config; pub use config::Config; @@ -56,10 +56,10 @@ environmental::environmental!(recursion_count: u8); /// The XCM executor. pub struct XcmExecutor { - holding: Assets, + holding: AssetsInHolding, holding_limit: usize, context: XcmContext, - original_origin: MultiLocation, + original_origin: Location, trader: Config::Trader, /// The most recent error result and instruction index into the fragment in which it occurred, /// if any. @@ -81,10 +81,10 @@ pub struct XcmExecutor { #[cfg(feature = "runtime-benchmarks")] impl XcmExecutor { - pub fn holding(&self) -> &Assets { + pub fn holding(&self) -> &AssetsInHolding { &self.holding } - pub fn set_holding(&mut self, v: Assets) { + pub fn set_holding(&mut self, v: AssetsInHolding) { self.holding = v } pub fn holding_limit(&self) -> &usize { @@ -93,16 +93,16 @@ impl XcmExecutor { pub fn set_holding_limit(&mut self, v: usize) { self.holding_limit = v } - pub fn origin(&self) -> &Option { + pub fn origin(&self) -> &Option { &self.context.origin } - pub fn set_origin(&mut self, v: Option) { + pub fn set_origin(&mut self, v: Option) { self.context.origin = v } - pub fn original_origin(&self) -> &MultiLocation { + pub fn original_origin(&self) -> &Location { &self.original_origin } - pub fn set_original_origin(&mut self, v: MultiLocation) { + pub fn set_original_origin(&mut self, v: Location) { self.original_origin = v } pub fn trader(&self) -> &Config::Trader { @@ -191,14 +191,14 @@ impl ExecuteXcm for XcmExecutor, + origin: impl Into, WeighedMessage(xcm_weight, mut message): WeighedMessage, id: &mut XcmHash, weight_credit: Weight, ) -> Outcome { let origin = origin.into(); log::trace!( - target: "xcm::execute_xcm_in_credit", + target: "xcm::execute", "origin: {origin:?}, message: {message:?}, weight_credit: {weight_credit:?}", ); let mut properties = Properties { weight_credit, message_id: None }; @@ -209,11 +209,11 @@ impl ExecuteXcm for XcmExecutor ExecuteXcm for XcmExecutor ExecuteXcm for XcmExecutor, fees: MultiAssets) -> XcmResult { + fn charge_fees(origin: impl Into, fees: Assets) -> XcmResult { let origin = origin.into(); if !Config::FeeManager::is_waived(Some(&origin), FeeReason::ChargeFees) { for asset in fees.inner() { @@ -275,12 +275,12 @@ impl From for frame_benchmarking::BenchmarkError { } impl XcmExecutor { - pub fn new(origin: impl Into, message_id: XcmHash) -> Self { + pub fn new(origin: impl Into, message_id: XcmHash) -> Self { let origin = origin.into(); Self { - holding: Assets::new(), + holding: AssetsInHolding::new(), holding_limit: Config::MaxAssetsIntoHolding::get() as usize, - context: XcmContext { origin: Some(origin), message_id, topic: None }, + context: XcmContext { origin: Some(origin.clone()), message_id, topic: None }, original_origin: origin, trader: Config::Trader::new(), error: None, @@ -309,7 +309,7 @@ impl XcmExecutor { if !self.holding.is_empty() { log::trace!( - target: "xcm::execute_xcm_in_credit", + target: "xcm::post_process", "Trapping assets in holding register: {:?}, context: {:?} (original_origin: {:?})", self.holding, self.context, self.original_origin, ); @@ -320,28 +320,28 @@ impl XcmExecutor { }; match self.error { - None => Outcome::Complete(weight_used), + None => Outcome::Complete { used: weight_used }, // TODO: #2841 #REALWEIGHT We should deduct the cost of any instructions following // the error which didn't end up being executed. Some((_i, e)) => { - log::trace!(target: "xcm::execute_xcm_in_credit", "Execution errored at {:?}: {:?} (original_origin: {:?})", _i, e, self.original_origin); - Outcome::Incomplete(weight_used, e) + log::trace!(target: "xcm::post_process", "Execution errored at {:?}: {:?} (original_origin: {:?})", _i, e, self.original_origin); + Outcome::Incomplete { used: weight_used, error: e } }, } } - fn origin_ref(&self) -> Option<&MultiLocation> { + fn origin_ref(&self) -> Option<&Location> { self.context.origin.as_ref() } - fn cloned_origin(&self) -> Option { - self.context.origin + fn cloned_origin(&self) -> Option { + self.context.origin.clone() } /// Send an XCM, charging fees from Holding as needed. fn send( &mut self, - dest: MultiLocation, + dest: Location, msg: Xcm<()>, reason: FeeReason, ) -> Result { @@ -373,14 +373,14 @@ impl XcmExecutor { r } - fn subsume_asset(&mut self, asset: MultiAsset) -> Result<(), XcmError> { + fn subsume_asset(&mut self, asset: Asset) -> Result<(), XcmError> { // worst-case, holding.len becomes 2 * holding_limit. ensure!(self.holding.len() < self.holding_limit * 2, XcmError::HoldingWouldOverflow); self.holding.subsume(asset); Ok(()) } - fn subsume_assets(&mut self, assets: Assets) -> Result<(), XcmError> { + fn subsume_assets(&mut self, assets: AssetsInHolding) -> Result<(), XcmError> { // worst-case, holding.len becomes 2 * holding_limit. // this guarantees that if holding.len() == holding_limit and you have holding_limit more // items (which has a best case outcome of holding.len() == holding_limit), then you'll @@ -403,8 +403,8 @@ impl XcmExecutor { Ok(()) } - fn take_fee(&mut self, fee: MultiAssets, reason: FeeReason) -> XcmResult { - if Config::FeeManager::is_waived(self.origin_ref(), reason) { + fn take_fee(&mut self, fee: Assets, reason: FeeReason) -> XcmResult { + if Config::FeeManager::is_waived(self.origin_ref(), reason.clone()) { return Ok(()) } log::trace!( @@ -430,13 +430,13 @@ impl XcmExecutor { /// Calculates what `local_querier` would be from the perspective of `destination`. fn to_querier( - local_querier: Option, - destination: &MultiLocation, - ) -> Result, XcmError> { + local_querier: Option, + destination: &Location, + ) -> Result, XcmError> { Ok(match local_querier { None => None, Some(q) => Some( - q.reanchored(&destination, Config::UniversalLocation::get()) + q.reanchored(&destination, &Config::UniversalLocation::get()) .map_err(|_| XcmError::ReanchorFailed)?, ), }) @@ -447,7 +447,7 @@ impl XcmExecutor { /// The `local_querier` argument is the querier (if any) specified from the *local* perspective. fn respond( &mut self, - local_querier: Option, + local_querier: Option, response: Response, info: QueryResponseInfo, fee_reason: FeeReason, @@ -459,36 +459,27 @@ impl XcmExecutor { self.send(destination, message, fee_reason) } - fn try_reanchor( - asset: MultiAsset, - destination: &MultiLocation, - ) -> Result<(MultiAsset, InteriorMultiLocation), XcmError> { + fn try_reanchor( + reanchorable: T, + destination: &Location, + ) -> Result<(T, InteriorLocation), XcmError> { let reanchor_context = Config::UniversalLocation::get(); - let asset = asset - .reanchored(&destination, reanchor_context) - .map_err(|()| XcmError::ReanchorFailed)?; - Ok((asset, reanchor_context)) - } - - fn try_reanchor_multilocation( - location: MultiLocation, - destination: &MultiLocation, - ) -> Result<(MultiLocation, InteriorMultiLocation), XcmError> { - let reanchor_context = Config::UniversalLocation::get(); - let location = location - .reanchored(&destination, reanchor_context) - .map_err(|_| XcmError::ReanchorFailed)?; - Ok((location, reanchor_context)) + let reanchored = + reanchorable.reanchored(&destination, &reanchor_context).map_err(|error| { + log::error!(target: "xcm::reanchor", "Failed reanchoring with error {error:?}"); + XcmError::ReanchorFailed + })?; + Ok((reanchored, reanchor_context)) } /// NOTE: Any assets which were unable to be reanchored are introduced into `failed_bin`. fn reanchored( - mut assets: Assets, - dest: &MultiLocation, - maybe_failed_bin: Option<&mut Assets>, - ) -> MultiAssets { + mut assets: AssetsInHolding, + dest: &Location, + maybe_failed_bin: Option<&mut AssetsInHolding>, + ) -> Assets { let reanchor_context = Config::UniversalLocation::get(); - assets.reanchor(dest, reanchor_context, maybe_failed_bin); + assets.reanchor(dest, &reanchor_context, maybe_failed_bin); assets.into_assets_iter().collect::>().into() } @@ -563,8 +554,8 @@ impl XcmExecutor { ); match instr { WithdrawAsset(assets) => { + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; // Take `assets` from the origin account (on-chain) and place in holding. - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; for asset in assets.into_inner().into_iter() { Config::AssetTransactor::withdraw_asset(&asset, &origin, Some(&self.context))?; self.subsume_asset(asset)?; @@ -573,8 +564,8 @@ impl XcmExecutor { }, ReserveAssetDeposited(assets) => { // check whether we trust origin to be our reserve location for this asset. - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; for asset in assets.into_inner().into_iter() { + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; // Must ensure that we recognise the asset as being managed by the origin. ensure!( Config::IsReserve::contains(&asset, &origin), @@ -604,14 +595,14 @@ impl XcmExecutor { Config::AssetTransactor::transfer_asset(asset, origin, &dest, &self.context)?; } let reanchor_context = Config::UniversalLocation::get(); - assets.reanchor(&dest, reanchor_context).map_err(|()| XcmError::LocationFull)?; + assets.reanchor(&dest, &reanchor_context).map_err(|()| XcmError::LocationFull)?; let mut message = vec![ReserveAssetDeposited(assets), ClearOrigin]; message.extend(xcm.0.into_iter()); self.send(dest, Xcm(message), FeeReason::TransferReserveAsset)?; Ok(()) }, ReceiveTeleportedAsset(assets) => { - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; // check whether we trust origin to teleport this asset to us via config trait. for asset in assets.inner() { // We only trust the origin to send us assets that they identify as their @@ -627,6 +618,7 @@ impl XcmExecutor { Config::AssetTransactor::can_check_in(&origin, asset, &self.context)?; } for asset in assets.into_inner().into_iter() { + let origin = self.origin_ref().ok_or(XcmError::BadOrigin)?; Config::AssetTransactor::check_in(&origin, &asset, &self.context); self.subsume_asset(asset)?; } @@ -634,7 +626,7 @@ impl XcmExecutor { }, Transact { origin_kind, require_weight_at_most, mut call } => { // We assume that the Relay-chain is allowed to use transact on this parachain. - let origin = *self.origin_ref().ok_or_else(|| { + let origin = self.cloned_origin().ok_or_else(|| { log::trace!( target: "xcm::process_instruction::transact", "No origin provided", @@ -667,15 +659,17 @@ impl XcmExecutor { return Err(XcmError::NoPermission) } - let dispatch_origin = Config::OriginConverter::convert_origin(origin, origin_kind) - .map_err(|_| { - log::trace!( - target: "xcm::process_instruction::transact", - "Failed to convert origin {origin:?} and origin kind {origin_kind:?} to a local origin." - ); + let dispatch_origin = + Config::OriginConverter::convert_origin(origin.clone(), origin_kind).map_err( + |_| { + log::trace!( + target: "xcm::process_instruction::transact", + "Failed to convert origin {origin:?} and origin kind {origin_kind:?} to a local origin." + ); - XcmError::BadOrigin - })?; + XcmError::BadOrigin + }, + )?; log::trace!( target: "xcm::process_instruction::transact", @@ -964,12 +958,12 @@ impl XcmExecutor { UniversalOrigin(new_global) => { let universal_location = Config::UniversalLocation::get(); ensure!(universal_location.first() != Some(&new_global), XcmError::InvalidLocation); - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; let origin_xform = (origin, new_global); let ok = Config::UniversalAliases::contains(&origin_xform); ensure!(ok, XcmError::InvalidLocation); let (_, new_global) = origin_xform; - let new_origin = X1(new_global).relative_to(&universal_location); + let new_origin = Junctions::from([new_global]).relative_to(&universal_location); self.context.origin = Some(new_origin); Ok(()) }, @@ -983,7 +977,7 @@ impl XcmExecutor { // // This only works because the remote chain empowers the bridge // to speak for the local network. - let origin = self.context.origin.ok_or(XcmError::BadOrigin)?; + let origin = self.context.origin.as_ref().ok_or(XcmError::BadOrigin)?.clone(); let universal_source = Config::UniversalLocation::get() .within_global(origin) .map_err(|()| XcmError::Unanchored)?; @@ -996,7 +990,7 @@ impl XcmExecutor { network, channel, universal_source, - destination, + destination.clone(), xcm, )?; self.take_fee(fee, FeeReason::Export { network, destination })?; @@ -1004,11 +998,12 @@ impl XcmExecutor { Ok(()) }, LockAsset { asset, unlocker } => { - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; let (remote_asset, context) = Self::try_reanchor(asset.clone(), &unlocker)?; - let lock_ticket = Config::AssetLocker::prepare_lock(unlocker, asset, origin)?; + let lock_ticket = + Config::AssetLocker::prepare_lock(unlocker.clone(), asset, origin.clone())?; let owner = - origin.reanchored(&unlocker, context).map_err(|_| XcmError::ReanchorFailed)?; + origin.reanchored(&unlocker, &context).map_err(|_| XcmError::ReanchorFailed)?; let msg = Xcm::<()>(vec![NoteUnlockable { asset: remote_asset, owner }]); let (ticket, price) = validate_send::(unlocker, msg)?; self.take_fee(price, FeeReason::LockAsset)?; @@ -1017,21 +1012,24 @@ impl XcmExecutor { Ok(()) }, UnlockAsset { asset, target } => { - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; Config::AssetLocker::prepare_unlock(origin, asset, target)?.enact()?; Ok(()) }, NoteUnlockable { asset, owner } => { - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; Config::AssetLocker::note_unlockable(origin, asset, owner)?; Ok(()) }, RequestUnlock { asset, locker } => { - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; let remote_asset = Self::try_reanchor(asset.clone(), &locker)?.0; - let remote_target = Self::try_reanchor_multilocation(origin, &locker)?.0; - let reduce_ticket = - Config::AssetLocker::prepare_reduce_unlockable(locker, asset, origin)?; + let remote_target = Self::try_reanchor(origin.clone(), &locker)?.0; + let reduce_ticket = Config::AssetLocker::prepare_reduce_unlockable( + locker.clone(), + asset, + origin.clone(), + )?; let msg = Xcm::<()>(vec![UnlockAsset { asset: remote_asset, target: remote_target }]); let (ticket, price) = validate_send::(locker, msg)?; diff --git a/polkadot/xcm/xcm-executor/src/traits/asset_exchange.rs b/polkadot/xcm/xcm-executor/src/traits/asset_exchange.rs index 0cb188d348d..432a7498ed4 100644 --- a/polkadot/xcm/xcm-executor/src/traits/asset_exchange.rs +++ b/polkadot/xcm/xcm-executor/src/traits/asset_exchange.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use crate::Assets; +use crate::AssetsInHolding; use xcm::prelude::*; /// A service for exchanging assets. @@ -32,21 +32,21 @@ pub trait AssetExchange { /// least want must be in the set. Some assets originally in `give` may also be in this set. In /// the case of returning an `Err`, then `give` is returned. fn exchange_asset( - origin: Option<&MultiLocation>, - give: Assets, - want: &MultiAssets, + origin: Option<&Location>, + give: AssetsInHolding, + want: &Assets, maximal: bool, - ) -> Result; + ) -> Result; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl AssetExchange for Tuple { fn exchange_asset( - origin: Option<&MultiLocation>, - give: Assets, - want: &MultiAssets, + origin: Option<&Location>, + give: AssetsInHolding, + want: &Assets, maximal: bool, - ) -> Result { + ) -> Result { for_tuples!( #( let give = match Tuple::exchange_asset(origin, give, want, maximal) { Ok(r) => return Ok(r), diff --git a/polkadot/xcm/xcm-executor/src/traits/asset_lock.rs b/polkadot/xcm/xcm-executor/src/traits/asset_lock.rs index b5a2b22f5fc..b6270c52945 100644 --- a/polkadot/xcm/xcm-executor/src/traits/asset_lock.rs +++ b/polkadot/xcm/xcm-executor/src/traits/asset_lock.rs @@ -79,9 +79,9 @@ pub trait AssetLock { /// WARNING: Don't call this with an undropped instance of `Self::LockTicket` or /// `Self::UnlockTicket`. fn prepare_lock( - unlocker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + unlocker: Location, + asset: Asset, + owner: Location, ) -> Result; /// Prepare to unlock an asset. On success, a `Self::UnlockTicket` it returned, which can be @@ -90,9 +90,9 @@ pub trait AssetLock { /// WARNING: Don't call this with an undropped instance of `Self::LockTicket` or /// `Self::UnlockTicket`. fn prepare_unlock( - locker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + locker: Location, + asset: Asset, + owner: Location, ) -> Result; /// Handler for when a location reports to us that an asset has been locked for us to unlock @@ -102,11 +102,7 @@ pub trait AssetLock { /// sending chain can ensure the lock does not remain. /// /// We should only act upon this message if we believe that the `origin` is honest. - fn note_unlockable( - locker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, - ) -> Result<(), LockError>; + fn note_unlockable(locker: Location, asset: Asset, owner: Location) -> Result<(), LockError>; /// Handler for when an owner wishes to unlock an asset on a remote chain. /// @@ -115,9 +111,9 @@ pub trait AssetLock { /// /// WARNING: Don't call this with an undropped instance of `Self::ReduceTicket`. fn prepare_reduce_unlockable( - locker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + locker: Location, + asset: Asset, + owner: Location, ) -> Result; } @@ -125,27 +121,19 @@ impl AssetLock for () { type LockTicket = Infallible; type UnlockTicket = Infallible; type ReduceTicket = Infallible; - fn prepare_lock( - _: MultiLocation, - _: MultiAsset, - _: MultiLocation, - ) -> Result { + fn prepare_lock(_: Location, _: Asset, _: Location) -> Result { Err(LockError::NotApplicable) } - fn prepare_unlock( - _: MultiLocation, - _: MultiAsset, - _: MultiLocation, - ) -> Result { + fn prepare_unlock(_: Location, _: Asset, _: Location) -> Result { Err(LockError::NotApplicable) } - fn note_unlockable(_: MultiLocation, _: MultiAsset, _: MultiLocation) -> Result<(), LockError> { + fn note_unlockable(_: Location, _: Asset, _: Location) -> Result<(), LockError> { Err(LockError::NotApplicable) } fn prepare_reduce_unlockable( - _: MultiLocation, - _: MultiAsset, - _: MultiLocation, + _: Location, + _: Asset, + _: Location, ) -> Result { Err(LockError::NotApplicable) } diff --git a/polkadot/xcm/xcm-executor/src/traits/asset_transfer.rs b/polkadot/xcm/xcm-executor/src/traits/asset_transfer.rs index 5fdc9b15e01..1fca84f36e2 100644 --- a/polkadot/xcm/xcm-executor/src/traits/asset_transfer.rs +++ b/polkadot/xcm/xcm-executor/src/traits/asset_transfer.rs @@ -30,7 +30,7 @@ pub enum Error { } /// Specify which type of asset transfer is required for a particular `(asset, dest)` combination. -#[derive(Copy, Clone, PartialEq, Debug)] +#[derive(Clone, PartialEq, Debug)] pub enum TransferType { /// should teleport `asset` to `dest` Teleport, @@ -38,8 +38,8 @@ pub enum TransferType { LocalReserve, /// should reserve-transfer `asset` to `dest`, using `dest` as reserve DestinationReserve, - /// should reserve-transfer `asset` to `dest`, using remote chain `MultiLocation` as reserve - RemoteReserve(MultiLocation), + /// should reserve-transfer `asset` to `dest`, using remote chain `Location` as reserve + RemoteReserve(Location), } /// A trait for identifying asset transfer type based on `IsTeleporter` and `IsReserve` @@ -47,17 +47,17 @@ pub enum TransferType { pub trait XcmAssetTransfers { /// Combinations of (Asset, Location) pairs which we trust as reserves. Meaning /// reserve-based-transfers are to be used for assets matching this filter. - type IsReserve: ContainsPair; + type IsReserve: ContainsPair; /// Combinations of (Asset, Location) pairs which we trust as teleporters. Meaning teleports are /// to be used for assets matching this filter. - type IsTeleporter: ContainsPair; + type IsTeleporter: ContainsPair; /// How to withdraw and deposit an asset. type AssetTransactor: TransactAsset; /// Determine transfer type to be used for transferring `asset` from local chain to `dest`. - fn determine_for(asset: &MultiAsset, dest: &MultiLocation) -> Result { + fn determine_for(asset: &Asset, dest: &Location) -> Result { if Self::IsTeleporter::contains(asset, dest) { // we trust destination for teleporting asset return Ok(TransferType::Teleport) @@ -67,11 +67,8 @@ pub trait XcmAssetTransfers { } // try to determine reserve location based on asset id/location - let asset_location = match asset.id { - Concrete(location) => Ok(location.chain_location()), - _ => Err(Error::NotConcrete), - }?; - if asset_location == MultiLocation::here() || + let asset_location = asset.id.0.chain_location(); + if asset_location == Location::here() || Self::IsTeleporter::contains(asset, &asset_location) { // if the asset is local, then it's a local reserve diff --git a/polkadot/xcm/xcm-executor/src/traits/conversion.rs b/polkadot/xcm/xcm-executor/src/traits/conversion.rs index 1fcdf214057..9e2f4c83997 100644 --- a/polkadot/xcm/xcm-executor/src/traits/conversion.rs +++ b/polkadot/xcm/xcm-executor/src/traits/conversion.rs @@ -22,12 +22,12 @@ use xcm::latest::prelude::*; /// Means of converting a location into an account identifier. pub trait ConvertLocation { /// Convert the `location` into `Some` account ID, or `None` if not possible. - fn convert_location(location: &MultiLocation) -> Option; + fn convert_location(location: &Location) -> Option; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl ConvertLocation for Tuple { - fn convert_location(l: &MultiLocation) -> Option { + fn convert_location(l: &Location) -> Option { for_tuples!( #( match Tuple::convert_location(l) { Some(result) => return Some(result), @@ -45,15 +45,15 @@ impl ConvertLocation for Tuple { /// different `origin` of type `Origin` which is passed to the next convert item. /// /// ```rust -/// # use xcm::latest::{MultiLocation, Junctions, Junction, OriginKind}; +/// # use xcm::latest::{Location, Junctions, Junction, OriginKind}; /// # use staging_xcm_executor::traits::ConvertOrigin; /// // A convertor that will bump the para id and pass it to the next one. /// struct BumpParaId; /// impl ConvertOrigin for BumpParaId { -/// fn convert_origin(origin: impl Into, _: OriginKind) -> Result { -/// match origin.into() { -/// MultiLocation { parents: 0, interior: Junctions::X1(Junction::Parachain(id)) } => { -/// Err(Junctions::X1(Junction::Parachain(id + 1)).into()) +/// fn convert_origin(origin: impl Into, _: OriginKind) -> Result { +/// match origin.into().unpack() { +/// (0, [Junction::Parachain(id)]) => { +/// Err([Junction::Parachain(id + 1)].into()) /// } /// _ => unreachable!() /// } @@ -62,17 +62,18 @@ impl ConvertLocation for Tuple { /// /// struct AcceptPara7; /// impl ConvertOrigin for AcceptPara7 { -/// fn convert_origin(origin: impl Into, _: OriginKind) -> Result { -/// match origin.into() { -/// MultiLocation { parents: 0, interior: Junctions::X1(Junction::Parachain(id)) } if id == 7 => { +/// fn convert_origin(origin: impl Into, _: OriginKind) -> Result { +/// let origin = origin.into(); +/// match origin.unpack() { +/// (0, [Junction::Parachain(id)]) if *id == 7 => { /// Ok(7) /// } -/// o => Err(o) +/// _ => Err(origin) /// } /// } /// } /// # fn main() { -/// let origin: MultiLocation = Junctions::X1(Junction::Parachain(6)).into(); +/// let origin: Location = [Junction::Parachain(6)].into(); /// assert!( /// <(BumpParaId, AcceptPara7) as ConvertOrigin>::convert_origin(origin, OriginKind::Native) /// .is_ok() @@ -81,18 +82,12 @@ impl ConvertLocation for Tuple { /// ``` pub trait ConvertOrigin { /// Attempt to convert `origin` to the generic `Origin` whilst consuming it. - fn convert_origin( - origin: impl Into, - kind: OriginKind, - ) -> Result; + fn convert_origin(origin: impl Into, kind: OriginKind) -> Result; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl ConvertOrigin for Tuple { - fn convert_origin( - origin: impl Into, - kind: OriginKind, - ) -> Result { + fn convert_origin(origin: impl Into, kind: OriginKind) -> Result { for_tuples!( #( let origin = match Tuple::convert_origin(origin, kind) { Err(o) => o, diff --git a/polkadot/xcm/xcm-executor/src/traits/drop_assets.rs b/polkadot/xcm/xcm-executor/src/traits/drop_assets.rs index 9753f3a4213..339d485d979 100644 --- a/polkadot/xcm/xcm-executor/src/traits/drop_assets.rs +++ b/polkadot/xcm/xcm-executor/src/traits/drop_assets.rs @@ -14,28 +14,28 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use crate::Assets; +use crate::AssetsInHolding; use core::marker::PhantomData; use frame_support::traits::Contains; -use xcm::latest::{MultiAssets, MultiLocation, Weight, XcmContext}; +use xcm::latest::{Assets, Location, Weight, XcmContext}; -/// Define a handler for when some non-empty `Assets` value should be dropped. +/// Define a handler for when some non-empty `AssetsInHolding` value should be dropped. pub trait DropAssets { /// Handler for receiving dropped assets. Returns the weight consumed by this operation. - fn drop_assets(origin: &MultiLocation, assets: Assets, context: &XcmContext) -> Weight; + fn drop_assets(origin: &Location, assets: AssetsInHolding, context: &XcmContext) -> Weight; } impl DropAssets for () { - fn drop_assets(_origin: &MultiLocation, _assets: Assets, _context: &XcmContext) -> Weight { + fn drop_assets(_origin: &Location, _assets: AssetsInHolding, _context: &XcmContext) -> Weight { Weight::zero() } } /// Morph a given `DropAssets` implementation into one which can filter based on assets. This can -/// be used to ensure that `Assets` values which hold no value are ignored. +/// be used to ensure that `AssetsInHolding` values which hold no value are ignored. pub struct FilterAssets(PhantomData<(D, A)>); -impl> DropAssets for FilterAssets { - fn drop_assets(origin: &MultiLocation, assets: Assets, context: &XcmContext) -> Weight { +impl> DropAssets for FilterAssets { + fn drop_assets(origin: &Location, assets: AssetsInHolding, context: &XcmContext) -> Weight { if A::contains(&assets) { D::drop_assets(origin, assets, context) } else { @@ -49,8 +49,8 @@ impl> DropAssets for FilterAssets { /// asset trap facility don't get to use it. pub struct FilterOrigin(PhantomData<(D, O)>); -impl> DropAssets for FilterOrigin { - fn drop_assets(origin: &MultiLocation, assets: Assets, context: &XcmContext) -> Weight { +impl> DropAssets for FilterOrigin { + fn drop_assets(origin: &Location, assets: AssetsInHolding, context: &XcmContext) -> Weight { if O::contains(origin) { D::drop_assets(origin, assets, context) } else { @@ -64,9 +64,9 @@ pub trait ClaimAssets { /// Claim any assets available to `origin` and return them in a single `Assets` value, together /// with the weight used by this operation. fn claim_assets( - origin: &MultiLocation, - ticket: &MultiLocation, - what: &MultiAssets, + origin: &Location, + ticket: &Location, + what: &Assets, context: &XcmContext, ) -> bool; } @@ -74,9 +74,9 @@ pub trait ClaimAssets { #[impl_trait_for_tuples::impl_for_tuples(30)] impl ClaimAssets for Tuple { fn claim_assets( - origin: &MultiLocation, - ticket: &MultiLocation, - what: &MultiAssets, + origin: &Location, + ticket: &Location, + what: &Assets, context: &XcmContext, ) -> bool { for_tuples!( #( diff --git a/polkadot/xcm/xcm-executor/src/traits/export.rs b/polkadot/xcm/xcm-executor/src/traits/export.rs index 7aeccd44566..78aa68ce264 100644 --- a/polkadot/xcm/xcm-executor/src/traits/export.rs +++ b/polkadot/xcm/xcm-executor/src/traits/export.rs @@ -51,8 +51,8 @@ pub trait ExportXcm { fn validate( network: NetworkId, channel: u32, - universal_source: &mut Option, - destination: &mut Option, + universal_source: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult; @@ -71,11 +71,11 @@ impl ExportXcm for Tuple { fn validate( network: NetworkId, channel: u32, - universal_source: &mut Option, - destination: &mut Option, + universal_source: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult { - let mut maybe_cost: Option = None; + let mut maybe_cost: Option = None; let one_ticket: Self::Ticket = (for_tuples! { #( if maybe_cost.is_some() { None @@ -112,8 +112,8 @@ impl ExportXcm for Tuple { pub fn validate_export( network: NetworkId, channel: u32, - universal_source: InteriorMultiLocation, - dest: InteriorMultiLocation, + universal_source: InteriorLocation, + dest: InteriorLocation, msg: Xcm<()>, ) -> SendResult { T::validate(network, channel, &mut Some(universal_source), &mut Some(dest), &mut Some(msg)) @@ -130,10 +130,10 @@ pub fn validate_export( pub fn export_xcm( network: NetworkId, channel: u32, - universal_source: InteriorMultiLocation, - dest: InteriorMultiLocation, + universal_source: InteriorLocation, + dest: InteriorLocation, msg: Xcm<()>, -) -> Result<(XcmHash, MultiAssets), SendError> { +) -> Result<(XcmHash, Assets), SendError> { let (ticket, price) = T::validate( network, channel, diff --git a/polkadot/xcm/xcm-executor/src/traits/fee_manager.rs b/polkadot/xcm/xcm-executor/src/traits/fee_manager.rs index d7146457f3b..b6e303daaad 100644 --- a/polkadot/xcm/xcm-executor/src/traits/fee_manager.rs +++ b/polkadot/xcm/xcm-executor/src/traits/fee_manager.rs @@ -19,15 +19,15 @@ use xcm::prelude::*; /// Handle stuff to do with taking fees in certain XCM instructions. pub trait FeeManager { /// Determine if a fee should be waived. - fn is_waived(origin: Option<&MultiLocation>, r: FeeReason) -> bool; + fn is_waived(origin: Option<&Location>, r: FeeReason) -> bool; /// Do something with the fee which has been paid. Doing nothing here silently burns the /// fees. - fn handle_fee(fee: MultiAssets, context: Option<&XcmContext>, r: FeeReason); + fn handle_fee(fee: Assets, context: Option<&XcmContext>, r: FeeReason); } /// Context under which a fee is paid. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq)] pub enum FeeReason { /// When a reporting instruction is called. Report, @@ -42,7 +42,7 @@ pub enum FeeReason { /// When the `QueryPallet` instruction is called. QueryPallet, /// When the `ExportMessage` instruction is called (and includes the network ID). - Export { network: NetworkId, destination: InteriorMultiLocation }, + Export { network: NetworkId, destination: InteriorLocation }, /// The `charge_fees` API. ChargeFees, /// When the `LockAsset` instruction is called. @@ -52,9 +52,9 @@ pub enum FeeReason { } impl FeeManager for () { - fn is_waived(_: Option<&MultiLocation>, _: FeeReason) -> bool { + fn is_waived(_: Option<&Location>, _: FeeReason) -> bool { false } - fn handle_fee(_: MultiAssets, _: Option<&XcmContext>, _: FeeReason) {} + fn handle_fee(_: Assets, _: Option<&XcmContext>, _: FeeReason) {} } diff --git a/polkadot/xcm/xcm-executor/src/traits/filter_asset_location.rs b/polkadot/xcm/xcm-executor/src/traits/filter_asset_location.rs index b162a8b0729..5d0c32890be 100644 --- a/polkadot/xcm/xcm-executor/src/traits/filter_asset_location.rs +++ b/polkadot/xcm/xcm-executor/src/traits/filter_asset_location.rs @@ -15,21 +15,21 @@ // along with Polkadot. If not, see . use frame_support::traits::ContainsPair; -use xcm::latest::{MultiAsset, MultiLocation}; +use xcm::latest::{Asset, Location}; /// Filters assets/location pairs. /// /// Can be amalgamated into tuples. If any item returns `true`, it short-circuits, else `false` is /// returned. -#[deprecated = "Use `frame_support::traits::ContainsPair` instead"] +#[deprecated = "Use `frame_support::traits::ContainsPair` instead"] pub trait FilterAssetLocation { /// A filter to distinguish between asset/location pairs. - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool; + fn contains(asset: &Asset, origin: &Location) -> bool; } #[allow(deprecated)] -impl> FilterAssetLocation for T { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl> FilterAssetLocation for T { + fn contains(asset: &Asset, origin: &Location) -> bool { T::contains(asset, origin) } } diff --git a/polkadot/xcm/xcm-executor/src/traits/on_response.rs b/polkadot/xcm/xcm-executor/src/traits/on_response.rs index ea41f242a97..952bd2d0040 100644 --- a/polkadot/xcm/xcm-executor/src/traits/on_response.rs +++ b/polkadot/xcm/xcm-executor/src/traits/on_response.rs @@ -24,42 +24,34 @@ use parity_scale_codec::{Decode, Encode, FullCodec, MaxEncodedLen}; use sp_arithmetic::traits::Zero; use sp_std::fmt::Debug; use xcm::latest::{ - Error as XcmError, InteriorMultiLocation, MultiLocation, QueryId, Response, - Result as XcmResult, Weight, XcmContext, + Error as XcmError, InteriorLocation, Location, QueryId, Response, Result as XcmResult, Weight, + XcmContext, }; /// Define what needs to be done upon receiving a query response. pub trait OnResponse { /// Returns `true` if we are expecting a response from `origin` for query `query_id` that was /// queried by `querier`. - fn expecting_response( - origin: &MultiLocation, - query_id: u64, - querier: Option<&MultiLocation>, - ) -> bool; + fn expecting_response(origin: &Location, query_id: u64, querier: Option<&Location>) -> bool; /// Handler for receiving a `response` from `origin` relating to `query_id` initiated by /// `querier`. fn on_response( - origin: &MultiLocation, + origin: &Location, query_id: u64, - querier: Option<&MultiLocation>, + querier: Option<&Location>, response: Response, max_weight: Weight, context: &XcmContext, ) -> Weight; } impl OnResponse for () { - fn expecting_response( - _origin: &MultiLocation, - _query_id: u64, - _querier: Option<&MultiLocation>, - ) -> bool { + fn expecting_response(_origin: &Location, _query_id: u64, _querier: Option<&Location>) -> bool { false } fn on_response( - _origin: &MultiLocation, + _origin: &Location, _query_id: u64, - _querier: Option<&MultiLocation>, + _querier: Option<&Location>, _response: Response, _max_weight: Weight, _context: &XcmContext, @@ -79,7 +71,7 @@ pub trait VersionChangeNotifier { /// If the `location` has an ongoing notification and when this function is called, then an /// error should be returned. fn start( - location: &MultiLocation, + location: &Location, query_id: QueryId, max_weight: Weight, context: &XcmContext, @@ -87,20 +79,20 @@ pub trait VersionChangeNotifier { /// Stop notifying `location` should the XCM change. Returns an error if there is no existing /// notification set up. - fn stop(location: &MultiLocation, context: &XcmContext) -> XcmResult; + fn stop(location: &Location, context: &XcmContext) -> XcmResult; /// Return true if a location is subscribed to XCM version changes. - fn is_subscribed(location: &MultiLocation) -> bool; + fn is_subscribed(location: &Location) -> bool; } impl VersionChangeNotifier for () { - fn start(_: &MultiLocation, _: QueryId, _: Weight, _: &XcmContext) -> XcmResult { + fn start(_: &Location, _: QueryId, _: Weight, _: &XcmContext) -> XcmResult { Err(XcmError::Unimplemented) } - fn stop(_: &MultiLocation, _: &XcmContext) -> XcmResult { + fn stop(_: &Location, _: &XcmContext) -> XcmResult { Err(XcmError::Unimplemented) } - fn is_subscribed(_: &MultiLocation) -> bool { + fn is_subscribed(_: &Location) -> bool { false } } @@ -134,13 +126,13 @@ pub trait QueryHandler { + Copy; type BlockNumber: Zero + Encode; type Error; - type UniversalLocation: Get; + type UniversalLocation: Get; /// Attempt to create a new query ID and register it as a query that is yet to respond. fn new_query( - responder: impl Into, + responder: impl Into, timeout: Self::BlockNumber, - match_querier: impl Into, + match_querier: impl Into, ) -> QueryId; /// Consume `message` and return another which is equivalent to it except that it reports @@ -157,7 +149,7 @@ pub trait QueryHandler { /// The response can be queried with `take_response`. fn report_outcome( message: &mut Xcm<()>, - responder: impl Into, + responder: impl Into, timeout: Self::BlockNumber, ) -> result::Result; @@ -170,7 +162,7 @@ pub trait QueryHandler { } parameter_types! { - pub UniversalLocation: InteriorMultiLocation = Here; + pub UniversalLocation: InteriorLocation = Here; } impl QueryHandler for () { @@ -183,16 +175,16 @@ impl QueryHandler for () { QueryResponseStatus::NotFound } fn new_query( - _responder: impl Into, + _responder: impl Into, _timeout: Self::BlockNumber, - _match_querier: impl Into, + _match_querier: impl Into, ) -> Self::QueryId { 0u64 } fn report_outcome( _message: &mut Xcm<()>, - _responder: impl Into, + _responder: impl Into, _timeout: Self::BlockNumber, ) -> Result { Err(()) diff --git a/polkadot/xcm/xcm-executor/src/traits/should_execute.rs b/polkadot/xcm/xcm-executor/src/traits/should_execute.rs index d85458b5470..449e82b5a6e 100644 --- a/polkadot/xcm/xcm-executor/src/traits/should_execute.rs +++ b/polkadot/xcm/xcm-executor/src/traits/should_execute.rs @@ -16,7 +16,7 @@ use frame_support::traits::ProcessMessageError; use sp_std::result::Result; -use xcm::latest::{Instruction, MultiLocation, Weight, XcmHash}; +use xcm::latest::{Instruction, Location, Weight, XcmHash}; /// Properyies of an XCM message and its imminent execution. #[derive(Clone, Eq, PartialEq, Debug)] @@ -43,7 +43,7 @@ pub trait ShouldExecute { /// - `properties`: Various pre-established properties of the message which may be mutated by /// this API. fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -53,7 +53,7 @@ pub trait ShouldExecute { #[impl_trait_for_tuples::impl_for_tuples(30)] impl ShouldExecute for Tuple { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -87,7 +87,7 @@ impl ShouldExecute for Tuple { /// if any of the tuple elements returns true. pub trait CheckSuspension { fn is_suspended( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -97,7 +97,7 @@ pub trait CheckSuspension { #[impl_trait_for_tuples::impl_for_tuples(30)] impl CheckSuspension for Tuple { fn is_suspended( - origin: &MultiLocation, + origin: &Location, instruction: &mut [Instruction], max_weight: Weight, properties: &mut Properties, diff --git a/polkadot/xcm/xcm-executor/src/traits/token_matching.rs b/polkadot/xcm/xcm-executor/src/traits/token_matching.rs index ad65a863021..e9a7e3ad845 100644 --- a/polkadot/xcm/xcm-executor/src/traits/token_matching.rs +++ b/polkadot/xcm/xcm-executor/src/traits/token_matching.rs @@ -18,12 +18,12 @@ use sp_std::result; use xcm::latest::prelude::*; pub trait MatchesFungible { - fn matches_fungible(a: &MultiAsset) -> Option; + fn matches_fungible(a: &Asset) -> Option; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl MatchesFungible for Tuple { - fn matches_fungible(a: &MultiAsset) -> Option { + fn matches_fungible(a: &Asset) -> Option { for_tuples!( #( match Tuple::matches_fungible(a) { o @ Some(_) => return o, _ => () } )* ); @@ -33,12 +33,12 @@ impl MatchesFungible for Tuple { } pub trait MatchesNonFungible { - fn matches_nonfungible(a: &MultiAsset) -> Option; + fn matches_nonfungible(a: &Asset) -> Option; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl MatchesNonFungible for Tuple { - fn matches_nonfungible(a: &MultiAsset) -> Option { + fn matches_nonfungible(a: &Asset) -> Option { for_tuples!( #( match Tuple::matches_nonfungible(a) { o @ Some(_) => return o, _ => () } )* ); @@ -52,11 +52,11 @@ impl MatchesNonFungible for Tuple { pub enum Error { /// The given asset is not handled. (According to [`XcmError::AssetNotFound`]) AssetNotHandled, - /// `MultiLocation` to `AccountId` conversion failed. + /// `Location` to `AccountId` conversion failed. AccountIdConversionFailed, /// `u128` amount to currency `Balance` conversion failed. AmountToBalanceConversionFailed, - /// `MultiLocation` to `AssetId`/`ClassId` conversion failed. + /// `Location` to `AssetId`/`ClassId` conversion failed. AssetIdConversionFailed, /// `AssetInstance` to non-fungibles instance ID conversion failed. InstanceConversionFailed, @@ -77,12 +77,12 @@ impl From for XcmError { } pub trait MatchesFungibles { - fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), Error>; + fn matches_fungibles(a: &Asset) -> result::Result<(AssetId, Balance), Error>; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl MatchesFungibles for Tuple { - fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), Error> { + fn matches_fungibles(a: &Asset) -> result::Result<(AssetId, Balance), Error> { for_tuples!( #( match Tuple::matches_fungibles(a) { o @ Ok(_) => return o, _ => () } )* ); @@ -92,12 +92,12 @@ impl MatchesFungibles for Tuple { } pub trait MatchesNonFungibles { - fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(AssetId, Instance), Error>; + fn matches_nonfungibles(a: &Asset) -> result::Result<(AssetId, Instance), Error>; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl MatchesNonFungibles for Tuple { - fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(AssetId, Instance), Error> { + fn matches_nonfungibles(a: &Asset) -> result::Result<(AssetId, Instance), Error> { for_tuples!( #( match Tuple::matches_nonfungibles(a) { o @ Ok(_) => return o, _ => () } )* ); diff --git a/polkadot/xcm/xcm-executor/src/traits/transact_asset.rs b/polkadot/xcm/xcm-executor/src/traits/transact_asset.rs index c51befff88a..e8a52d82568 100644 --- a/polkadot/xcm/xcm-executor/src/traits/transact_asset.rs +++ b/polkadot/xcm/xcm-executor/src/traits/transact_asset.rs @@ -14,14 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use crate::Assets; +use crate::AssetsInHolding; use sp_std::result::Result; -use xcm::latest::{Error as XcmError, MultiAsset, MultiLocation, Result as XcmResult, XcmContext}; +use xcm::latest::{Asset, Error as XcmError, Location, Result as XcmResult, XcmContext}; /// Facility for asset transacting. /// /// This should work with as many asset/location combinations as possible. Locations to support may -/// include non-account locations such as a `MultiLocation::X1(Junction::Parachain)`. Different +/// include non-account locations such as a `[Junction::Parachain]`. Different /// chains may handle them in different ways. /// /// Can be amalgamated as a tuple of items that implement this trait. In such executions, if any of @@ -31,11 +31,7 @@ pub trait TransactAsset { /// Ensure that `check_in` will do as expected. /// /// When composed as a tuple, all type-items are called and at least one must result in `Ok`. - fn can_check_in( - _origin: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Err(XcmError::Unimplemented) } @@ -56,16 +52,12 @@ pub trait TransactAsset { /// When composed as a tuple, all type-items are called. It is up to the implementer that there /// exists no value for `_what` which can cause side-effects for more than one of the /// type-items. - fn check_in(_origin: &MultiLocation, _what: &MultiAsset, _context: &XcmContext) {} + fn check_in(_origin: &Location, _what: &Asset, _context: &XcmContext) {} /// Ensure that `check_out` will do as expected. /// /// When composed as a tuple, all type-items are called and at least one must result in `Ok`. - fn can_check_out( - _dest: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Err(XcmError::Unimplemented) } @@ -82,16 +74,12 @@ pub trait TransactAsset { /// When composed as a tuple, all type-items are called. It is up to the implementer that there /// exists no value for `_what` which can cause side-effects for more than one of the /// type-items. - fn check_out(_dest: &MultiLocation, _what: &MultiAsset, _context: &XcmContext) {} + fn check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) {} /// Deposit the `what` asset into the account of `who`. /// /// Implementations should return `XcmError::FailedToTransactAsset` if deposit failed. - fn deposit_asset( - _what: &MultiAsset, - _who: &MultiLocation, - _context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(_what: &Asset, _who: &Location, _context: Option<&XcmContext>) -> XcmResult { Err(XcmError::Unimplemented) } @@ -104,10 +92,10 @@ pub trait TransactAsset { /// /// Implementations should return `XcmError::FailedToTransactAsset` if withdraw failed. fn withdraw_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _maybe_context: Option<&XcmContext>, - ) -> Result { + ) -> Result { Err(XcmError::Unimplemented) } @@ -121,11 +109,11 @@ pub trait TransactAsset { /// turn has a default implementation that calls `internal_transfer_asset`. As such, **please /// do not call this method directly unless you know what you're doing**. fn internal_transfer_asset( - _asset: &MultiAsset, - _from: &MultiLocation, - _to: &MultiLocation, + _asset: &Asset, + _from: &Location, + _to: &Location, _context: &XcmContext, - ) -> Result { + ) -> Result { Err(XcmError::Unimplemented) } @@ -134,11 +122,11 @@ pub trait TransactAsset { /// Attempts to use `internal_transfer_asset` and if not available then falls back to using a /// two-part withdraw/deposit. fn transfer_asset( - asset: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + asset: &Asset, + from: &Location, + to: &Location, context: &XcmContext, - ) -> Result { + ) -> Result { match Self::internal_transfer_asset(asset, from, to, context) { Err(XcmError::AssetNotFound | XcmError::Unimplemented) => { let assets = Self::withdraw_asset(asset, from, Some(context))?; @@ -153,7 +141,7 @@ pub trait TransactAsset { #[impl_trait_for_tuples::impl_for_tuples(30)] impl TransactAsset for Tuple { - fn can_check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_in(origin: &Location, what: &Asset, context: &XcmContext) -> XcmResult { for_tuples!( #( match Tuple::can_check_in(origin, what, context) { Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), @@ -170,13 +158,13 @@ impl TransactAsset for Tuple { Err(XcmError::AssetNotFound) } - fn check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_in(origin: &Location, what: &Asset, context: &XcmContext) { for_tuples!( #( Tuple::check_in(origin, what, context); )* ); } - fn can_check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_out(dest: &Location, what: &Asset, context: &XcmContext) -> XcmResult { for_tuples!( #( match Tuple::can_check_out(dest, what, context) { Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), @@ -193,17 +181,13 @@ impl TransactAsset for Tuple { Err(XcmError::AssetNotFound) } - fn check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_out(dest: &Location, what: &Asset, context: &XcmContext) { for_tuples!( #( Tuple::check_out(dest, what, context); )* ); } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, context: Option<&XcmContext>) -> XcmResult { for_tuples!( #( match Tuple::deposit_asset(what, who, context) { Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), @@ -221,10 +205,10 @@ impl TransactAsset for Tuple { } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, maybe_context: Option<&XcmContext>, - ) -> Result { + ) -> Result { for_tuples!( #( match Tuple::withdraw_asset(what, who, maybe_context) { Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), @@ -242,11 +226,11 @@ impl TransactAsset for Tuple { } fn internal_transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, context: &XcmContext, - ) -> Result { + ) -> Result { for_tuples!( #( match Tuple::internal_transfer_asset(what, from, to, context) { Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), @@ -275,133 +259,109 @@ mod tests { pub struct NotFoundTransactor; impl TransactAsset for NotFoundTransactor { - fn can_check_in( - _origin: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Err(XcmError::AssetNotFound) } - fn can_check_out( - _dest: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Err(XcmError::AssetNotFound) } fn deposit_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, ) -> XcmResult { Err(XcmError::AssetNotFound) } fn withdraw_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, - ) -> Result { + ) -> Result { Err(XcmError::AssetNotFound) } fn internal_transfer_asset( - _what: &MultiAsset, - _from: &MultiLocation, - _to: &MultiLocation, + _what: &Asset, + _from: &Location, + _to: &Location, _context: &XcmContext, - ) -> Result { + ) -> Result { Err(XcmError::AssetNotFound) } } pub struct OverflowTransactor; impl TransactAsset for OverflowTransactor { - fn can_check_in( - _origin: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Err(XcmError::Overflow) } - fn can_check_out( - _dest: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Err(XcmError::Overflow) } fn deposit_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, ) -> XcmResult { Err(XcmError::Overflow) } fn withdraw_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, - ) -> Result { + ) -> Result { Err(XcmError::Overflow) } fn internal_transfer_asset( - _what: &MultiAsset, - _from: &MultiLocation, - _to: &MultiLocation, + _what: &Asset, + _from: &Location, + _to: &Location, _context: &XcmContext, - ) -> Result { + ) -> Result { Err(XcmError::Overflow) } } pub struct SuccessfulTransactor; impl TransactAsset for SuccessfulTransactor { - fn can_check_in( - _origin: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Ok(()) } - fn can_check_out( - _dest: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Ok(()) } fn deposit_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, ) -> XcmResult { Ok(()) } fn withdraw_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, - ) -> Result { - Ok(Assets::default()) + ) -> Result { + Ok(AssetsInHolding::default()) } fn internal_transfer_asset( - _what: &MultiAsset, - _from: &MultiLocation, - _to: &MultiLocation, + _what: &Asset, + _from: &Location, + _to: &Location, _context: &XcmContext, - ) -> Result { - Ok(Assets::default()) + ) -> Result { + Ok(AssetsInHolding::default()) } } diff --git a/polkadot/xcm/xcm-executor/src/traits/weight.rs b/polkadot/xcm/xcm-executor/src/traits/weight.rs index bc40c10074f..efb9a2dfb6e 100644 --- a/polkadot/xcm/xcm-executor/src/traits/weight.rs +++ b/polkadot/xcm/xcm-executor/src/traits/weight.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use crate::Assets; +use crate::AssetsInHolding; use sp_std::result::Result; use xcm::latest::{prelude::*, Weight}; @@ -33,7 +33,7 @@ pub trait WeightBounds { /// message. pub trait UniversalWeigher { /// Get the upper limit of weight required for `dest` to execute `message`. - fn weigh(dest: impl Into, message: Xcm<()>) -> Result; + fn weigh(dest: impl Into, message: Xcm<()>) -> Result; } /// Charge for weight in order to execute XCM. @@ -52,15 +52,15 @@ pub trait WeightTrader: Sized { fn buy_weight( &mut self, weight: Weight, - payment: Assets, + payment: AssetsInHolding, context: &XcmContext, - ) -> Result; + ) -> Result; /// Attempt a refund of `weight` into some asset. The caller does not guarantee that the weight /// was purchased using `buy_weight`. /// /// Default implementation refunds nothing. - fn refund_weight(&mut self, _weight: Weight, _context: &XcmContext) -> Option { + fn refund_weight(&mut self, _weight: Weight, _context: &XcmContext) -> Option { None } } @@ -74,9 +74,9 @@ impl WeightTrader for Tuple { fn buy_weight( &mut self, weight: Weight, - payment: Assets, + payment: AssetsInHolding, context: &XcmContext, - ) -> Result { + ) -> Result { let mut too_expensive_error_found = false; let mut last_error = None; for_tuples!( #( @@ -102,7 +102,7 @@ impl WeightTrader for Tuple { }) } - fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { + fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { for_tuples!( #( if let Some(asset) = Tuple.refund_weight(weight, context) { return Some(asset); diff --git a/polkadot/xcm/xcm-simulator/example/src/lib.rs b/polkadot/xcm/xcm-simulator/example/src/lib.rs index 85b8ad1c5cb..d134957fbc1 100644 --- a/polkadot/xcm/xcm-simulator/example/src/lib.rs +++ b/polkadot/xcm/xcm-simulator/example/src/lib.rs @@ -148,7 +148,7 @@ mod tests { use xcm_simulator::TestExt; // Helper function for forming buy execution message - fn buy_execution(fees: impl Into) -> Instruction { + fn buy_execution(fees: impl Into) -> Instruction { BuyExecution { fees: fees.into(), weight_limit: Unlimited } } @@ -642,7 +642,7 @@ mod tests { parachain::MsgQueue::received_dmp(), vec![Xcm(vec![QueryResponse { query_id: query_id_set, - response: Response::Assets(MultiAssets::new()), + response: Response::Assets(Assets::new()), max_weight: Weight::from_parts(1_000_000_000, 1024 * 1024), querier: Some(Here.into()), }])], diff --git a/polkadot/xcm/xcm-simulator/example/src/parachain.rs b/polkadot/xcm/xcm-simulator/example/src/parachain.rs index 69db81deff4..0b6c573f464 100644 --- a/polkadot/xcm/xcm-simulator/example/src/parachain.rs +++ b/polkadot/xcm/xcm-simulator/example/src/parachain.rs @@ -115,8 +115,8 @@ impl pallet_balances::Config for Runtime { #[cfg(feature = "runtime-benchmarks")] pub struct UniquesHelper; #[cfg(feature = "runtime-benchmarks")] -impl pallet_uniques::BenchmarkHelper for UniquesHelper { - fn collection(i: u16) -> MultiLocation { +impl pallet_uniques::BenchmarkHelper for UniquesHelper { + fn collection(i: u16) -> Location { GeneralIndex(i as u128).into() } fn item(i: u16) -> AssetInstance { @@ -126,7 +126,7 @@ impl pallet_uniques::BenchmarkHelper for UniquesHe impl pallet_uniques::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type CollectionId = MultiLocation; + type CollectionId = Location; type ItemId = AssetInstance; type Currency = Balances; type CreateOrigin = ForeignCreators; @@ -148,12 +148,12 @@ impl pallet_uniques::Config for Runtime { // `EnsureOriginWithArg` impl for `CreateOrigin` which allows only XCM origins // which are locations containing the class location. pub struct ForeignCreators; -impl EnsureOriginWithArg for ForeignCreators { +impl EnsureOriginWithArg for ForeignCreators { type Success = AccountId; fn try_origin( o: RuntimeOrigin, - a: &MultiLocation, + a: &Location, ) -> sp_std::result::Result { let origin_location = pallet_xcm::EnsureXcm::::try_origin(o.clone())?; if !a.starts_with(&origin_location) { @@ -163,8 +163,8 @@ impl EnsureOriginWithArg for ForeignCreators { } #[cfg(feature = "runtime-benchmarks")] - fn try_successful_origin(a: &MultiLocation) -> Result { - Ok(pallet_xcm::Origin::Xcm(*a).into()) + fn try_successful_origin(a: &Location) -> Result { + Ok(pallet_xcm::Origin::Xcm(a.clone()).into()) } } @@ -174,9 +174,9 @@ parameter_types! { } parameter_types! { - pub const KsmLocation: MultiLocation = MultiLocation::parent(); + pub const KsmLocation: Location = Location::parent(); pub const RelayNetwork: NetworkId = NetworkId::Kusama; - pub UniversalLocation: InteriorMultiLocation = Parachain(MsgQueue::parachain_id().into()).into(); + pub UniversalLocation: InteriorLocation = Parachain(MsgQueue::parachain_id().into()).into(); } pub type LocationToAccountId = ( @@ -194,17 +194,17 @@ pub type XcmOriginToCallOrigin = ( parameter_types! { pub const UnitWeightCost: Weight = Weight::from_parts(1, 1); - pub KsmPerSecondPerByte: (AssetId, u128, u128) = (Concrete(Parent.into()), 1, 1); + pub KsmPerSecondPerByte: (AssetId, u128, u128) = (AssetId(Parent.into()), 1, 1); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; - pub ForeignPrefix: MultiLocation = (Parent,).into(); + pub ForeignPrefix: Location = (Parent,).into(); } pub type LocalAssetTransactor = ( FungibleAdapter, LocationToAccountId, AccountId, ()>, NonFungiblesAdapter< ForeignUniques, - ConvertedConcreteId, + ConvertedConcreteId, SovereignAccountOf, AccountId, NoChecking, @@ -216,9 +216,9 @@ pub type XcmRouter = super::ParachainXcmRouter; pub type Barrier = AllowUnpaidExecutionFrom; parameter_types! { - pub NftCollectionOne: MultiAssetFilter - = Wild(AllOf { fun: WildNonFungible, id: Concrete((Parent, GeneralIndex(1)).into()) }); - pub NftCollectionOneForRelay: (MultiAssetFilter, MultiLocation) + pub NftCollectionOne: AssetFilter + = Wild(AllOf { fun: WildNonFungible, id: AssetId((Parent, GeneralIndex(1)).into()) }); + pub NftCollectionOneForRelay: (AssetFilter, Location) = (NftCollectionOne::get(), (Parent,).into()); } pub type TrustedTeleporters = xcm_builder::Case; @@ -321,16 +321,23 @@ pub mod mock_msg_queue { max_weight: Weight, ) -> Result { let hash = Encode::using_encoded(&xcm, T::Hashing::hash); - let message_hash = Encode::using_encoded(&xcm, sp_io::hashing::blake2_256); + let mut message_hash = Encode::using_encoded(&xcm, sp_io::hashing::blake2_256); let (result, event) = match Xcm::::try_from(xcm) { Ok(xcm) => { let location = (Parent, Parachain(sender.into())); - match T::XcmExecutor::execute_xcm(location, xcm, message_hash, max_weight) { - Outcome::Error(e) => (Err(e), Event::Fail(Some(hash), e)), - Outcome::Complete(w) => (Ok(w), Event::Success(Some(hash))), + match T::XcmExecutor::prepare_and_execute( + location, + xcm, + &mut message_hash, + max_weight, + Weight::zero(), + ) { + Outcome::Error { error } => (Err(error), Event::Fail(Some(hash), error)), + Outcome::Complete { used } => (Ok(used), Event::Success(Some(hash))), // As far as the caller is concerned, this was dispatched without error, so // we just report the weight used. - Outcome::Incomplete(w, e) => (Ok(w), Event::Fail(Some(hash), e)), + Outcome::Incomplete { used, error } => + (Ok(used), Event::Fail(Some(hash), error)), } }, Err(()) => (Err(XcmError::UnhandledXcmVersion), Event::BadVersion(Some(hash))), @@ -371,7 +378,7 @@ pub mod mock_msg_queue { limit: Weight, ) -> Weight { for (_i, (_sent_at, data)) in iter.enumerate() { - let id = sp_io::hashing::blake2_256(&data[..]); + let mut id = sp_io::hashing::blake2_256(&data[..]); let maybe_versioned = VersionedXcm::::decode(&mut &data[..]); match maybe_versioned { Err(_) => { @@ -380,7 +387,13 @@ pub mod mock_msg_queue { Ok(versioned) => match Xcm::try_from(versioned) { Err(()) => Self::deposit_event(Event::UnsupportedVersion(id)), Ok(x) => { - let outcome = T::XcmExecutor::execute_xcm(Parent, x.clone(), id, limit); + let outcome = T::XcmExecutor::prepare_and_execute( + Parent, + x.clone(), + &mut id, + limit, + Weight::zero(), + ); >::append(x); Self::deposit_event(Event::ExecutedDownward(id, outcome)); }, @@ -400,17 +413,15 @@ impl mock_msg_queue::Config for Runtime { pub type LocalOriginToLocation = SignedToAccountId32; pub struct TrustedLockerCase(PhantomData); -impl> ContainsPair - for TrustedLockerCase -{ - fn contains(origin: &MultiLocation, asset: &MultiAsset) -> bool { +impl> ContainsPair for TrustedLockerCase { + fn contains(origin: &Location, asset: &Asset) -> bool { let (o, a) = T::get(); a.matches(asset) && &o == origin } } parameter_types! { - pub RelayTokenForRelay: (MultiLocation, MultiAssetFilter) = (Parent.into(), Wild(AllOf { id: Concrete(Parent.into()), fun: WildFungible })); + pub RelayTokenForRelay: (Location, AssetFilter) = (Parent.into(), Wild(AllOf { id: AssetId(Parent.into()), fun: WildFungible })); } pub type TrustedLockers = TrustedLockerCase; diff --git a/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs index 24fc56eb717..1bcbe6da2cd 100644 --- a/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs +++ b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs @@ -127,10 +127,10 @@ impl configuration::Config for Runtime { } parameter_types! { - pub const TokenLocation: MultiLocation = Here.into_location(); + pub const TokenLocation: Location = Here.into_location(); pub RelayNetwork: NetworkId = ByGenesis([0; 32]); pub const AnyNetwork: Option = None; - pub UniversalLocation: InteriorMultiLocation = Here; + pub UniversalLocation: InteriorLocation = Here; pub UnitWeightCost: u64 = 1_000; } @@ -162,7 +162,7 @@ type LocalOriginConverter = ( parameter_types! { pub const BaseXcmWeight: Weight = Weight::from_parts(1_000, 1_000); pub TokensPerSecondPerByte: (AssetId, u128, u128) = - (Concrete(TokenLocation::get()), 1_000_000_000_000, 1024 * 1024); + (AssetId(TokenLocation::get()), 1_000_000_000_000, 1024 * 1024); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; } diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs index 0893c7c086f..7026d5467c8 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs @@ -158,7 +158,7 @@ fn run_input(xcm_messages: [XcmMessage; 5]) { if xcm_message.source % 4 == 0 { // We get the destination for the message let parachain_id = (xcm_message.destination % 3) + 1; - let destination: MultiLocation = Parachain(parachain_id).into(); + let destination: Location = Parachain(parachain_id).into(); #[cfg(not(fuzzing))] { println!(" source: Relay Chain"); @@ -176,7 +176,7 @@ fn run_input(xcm_messages: [XcmMessage; 5]) { _ => ParaC::execute_with, }; // We get the destination for the message - let destination: MultiLocation = match xcm_message.destination % 4 { + let destination: Location = match xcm_message.destination % 4 { n @ 1..=3 => (Parent, Parachain(n)).into(), _ => Parent.into(), }; diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs index 2262d18e860..41fc5af9708 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs @@ -109,9 +109,9 @@ parameter_types! { } parameter_types! { - pub const KsmLocation: MultiLocation = MultiLocation::parent(); + pub const KsmLocation: Location = Location::parent(); pub const RelayNetwork: NetworkId = NetworkId::Kusama; - pub UniversalLocation: InteriorMultiLocation = Parachain(MsgQueue::parachain_id().into()).into(); + pub UniversalLocation: InteriorLocation = Parachain(MsgQueue::parachain_id().into()).into(); } pub type LocationToAccountId = ( @@ -128,7 +128,7 @@ pub type XcmOriginToCallOrigin = ( parameter_types! { pub const UnitWeightCost: Weight = Weight::from_parts(1, 1); - pub KsmPerSecondPerByte: (AssetId, u128, u128) = (Concrete(Parent.into()), 1, 1); + pub KsmPerSecondPerByte: (AssetId, u128, u128) = (AssetId(Parent.into()), 1, 1); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; } @@ -237,16 +237,23 @@ pub mod mock_msg_queue { max_weight: Weight, ) -> Result { let hash = Encode::using_encoded(&xcm, T::Hashing::hash); - let message_hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut message_hash = xcm.using_encoded(sp_io::hashing::blake2_256); let (result, event) = match Xcm::::try_from(xcm) { Ok(xcm) => { - let location = MultiLocation::new(1, X1(Parachain(sender.into()))); - match T::XcmExecutor::execute_xcm(location, xcm, message_hash, max_weight) { - Outcome::Error(e) => (Err(e), Event::Fail(Some(hash), e)), - Outcome::Complete(w) => (Ok(w), Event::Success(Some(hash))), + let location = Location::new(1, [Parachain(sender.into())]); + match T::XcmExecutor::prepare_and_execute( + location, + xcm, + &mut message_hash, + max_weight, + Weight::zero(), + ) { + Outcome::Error { error } => (Err(error), Event::Fail(Some(hash), error)), + Outcome::Complete { used } => (Ok(used), Event::Success(Some(hash))), // As far as the caller is concerned, this was dispatched without error, so // we just report the weight used. - Outcome::Incomplete(w, e) => (Ok(w), Event::Fail(Some(hash), e)), + Outcome::Incomplete { used, error } => + (Ok(used), Event::Fail(Some(hash), error)), } }, Err(()) => (Err(XcmError::UnhandledXcmVersion), Event::BadVersion(Some(hash))), @@ -287,7 +294,7 @@ pub mod mock_msg_queue { limit: Weight, ) -> Weight { for (_i, (_sent_at, data)) in iter.enumerate() { - let id = sp_io::hashing::blake2_256(&data[..]); + let mut id = sp_io::hashing::blake2_256(&data[..]); let maybe_msg = VersionedXcm::::decode(&mut &data[..]) .map(Xcm::::try_from); match maybe_msg { @@ -298,7 +305,13 @@ pub mod mock_msg_queue { Self::deposit_event(Event::UnsupportedVersion(id)); }, Ok(Ok(x)) => { - let outcome = T::XcmExecutor::execute_xcm(Parent, x.clone(), id, limit); + let outcome = T::XcmExecutor::prepare_and_execute( + Parent, + x.clone(), + &mut id, + limit, + Weight::zero(), + ); >::append(x); Self::deposit_event(Event::ExecutedDownward(id, outcome)); }, diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs index bbf4f1e6cc5..c066cc5e813 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs @@ -107,10 +107,10 @@ impl configuration::Config for Runtime { } parameter_types! { - pub const TokenLocation: MultiLocation = Here.into_location(); + pub const TokenLocation: Location = Here.into_location(); pub const ThisNetwork: NetworkId = NetworkId::ByGenesis([0; 32]); pub const AnyNetwork: Option = None; - pub const UniversalLocation: InteriorMultiLocation = Here; + pub const UniversalLocation: InteriorLocation = Here; } pub type SovereignAccountOf = @@ -129,7 +129,7 @@ type LocalOriginConverter = ( parameter_types! { pub const BaseXcmWeight: Weight = Weight::from_parts(1_000, 1_000); - pub KsmPerSecondPerByte: (AssetId, u128, u128) = (Concrete(TokenLocation::get()), 1, 1); + pub KsmPerSecondPerByte: (AssetId, u128, u128) = (AssetId(TokenLocation::get()), 1, 1); pub const MaxInstructions: u32 = u32::MAX; pub const MaxAssetsIntoHolding: u32 = 64; } diff --git a/polkadot/xcm/xcm-simulator/src/lib.rs b/polkadot/xcm/xcm-simulator/src/lib.rs index b38465b3d4a..7efbc658bbf 100644 --- a/polkadot/xcm/xcm-simulator/src/lib.rs +++ b/polkadot/xcm/xcm-simulator/src/lib.rs @@ -258,9 +258,9 @@ macro_rules! __impl_ext { } thread_local! { - pub static PARA_MESSAGE_BUS: RefCell)>> + pub static PARA_MESSAGE_BUS: RefCell)>> = RefCell::new(VecDeque::new()); - pub static RELAY_MESSAGE_BUS: RefCell)>> + pub static RELAY_MESSAGE_BUS: RefCell)>> = RefCell::new(VecDeque::new()); } @@ -318,8 +318,8 @@ macro_rules! decl_test_network { while let Some((para_id, destination, message)) = $crate::PARA_MESSAGE_BUS.with( |b| b.borrow_mut().pop_front()) { - match destination.interior() { - $crate::Junctions::Here if destination.parent_count() == 1 => { + match destination.unpack() { + (1, []) => { let encoded = $crate::encode_xcm(message, $crate::MessageKind::Ump); let mut _id = [0; 32]; let r = <$relay_chain>::process_message( @@ -336,7 +336,7 @@ macro_rules! decl_test_network { } }, $( - $crate::X1($crate::Parachain(id)) if *id == $para_id && destination.parent_count() == 1 => { + (1, [$crate::Parachain(id)]) if *id == $para_id => { let encoded = $crate::encode_xcm(message, $crate::MessageKind::Xcmp); let messages = vec![(para_id, 1, &encoded[..])]; let _weight = <$parachain>::handle_xcmp_messages( @@ -360,9 +360,9 @@ macro_rules! decl_test_network { while let Some((destination, message)) = $crate::RELAY_MESSAGE_BUS.with( |b| b.borrow_mut().pop_front()) { - match destination.interior() { + match destination.unpack() { $( - $crate::X1($crate::Parachain(id)) if *id == $para_id && destination.parent_count() == 0 => { + (0, [$crate::Parachain(id)]) if *id == $para_id => { let encoded = $crate::encode_xcm(message, $crate::MessageKind::Dmp); // NOTE: RelayChainBlockNumber is hard-coded to 1 let messages = vec![(1, encoded)]; @@ -382,18 +382,18 @@ macro_rules! decl_test_network { pub struct ParachainXcmRouter($crate::PhantomData); impl> $crate::SendXcm for ParachainXcmRouter { - type Ticket = ($crate::ParaId, $crate::MultiLocation, $crate::Xcm<()>); + type Ticket = ($crate::ParaId, $crate::Location, $crate::Xcm<()>); fn validate( - destination: &mut Option<$crate::MultiLocation>, + destination: &mut Option<$crate::Location>, message: &mut Option<$crate::Xcm<()>>, - ) -> $crate::SendResult<($crate::ParaId, $crate::MultiLocation, $crate::Xcm<()>)> { + ) -> $crate::SendResult<($crate::ParaId, $crate::Location, $crate::Xcm<()>)> { use $crate::XcmpMessageHandlerT; let d = destination.take().ok_or($crate::SendError::MissingArgument)?; - match (d.interior(), d.parent_count()) { - ($crate::Junctions::Here, 1) => {}, + match d.unpack() { + (1, []) => {}, $( - ($crate::X1($crate::Parachain(id)), 1) if id == &$para_id => {} + (1, [$crate::Parachain(id)]) if id == &$para_id => {} )* _ => { *destination = Some(d); @@ -401,10 +401,10 @@ macro_rules! decl_test_network { }, } let m = message.take().ok_or($crate::SendError::MissingArgument)?; - Ok(((T::get(), d, m), $crate::MultiAssets::new())) + Ok(((T::get(), d, m), $crate::Assets::new())) } fn deliver( - triple: ($crate::ParaId, $crate::MultiLocation, $crate::Xcm<()>), + triple: ($crate::ParaId, $crate::Location, $crate::Xcm<()>), ) -> Result<$crate::XcmHash, $crate::SendError> { let hash = $crate::fake_message_hash(&triple.2); $crate::PARA_MESSAGE_BUS.with(|b| b.borrow_mut().push_back(triple)); @@ -415,17 +415,17 @@ macro_rules! decl_test_network { /// XCM router for relay chain. pub struct RelayChainXcmRouter; impl $crate::SendXcm for RelayChainXcmRouter { - type Ticket = ($crate::MultiLocation, $crate::Xcm<()>); + type Ticket = ($crate::Location, $crate::Xcm<()>); fn validate( - destination: &mut Option<$crate::MultiLocation>, + destination: &mut Option<$crate::Location>, message: &mut Option<$crate::Xcm<()>>, - ) -> $crate::SendResult<($crate::MultiLocation, $crate::Xcm<()>)> { + ) -> $crate::SendResult<($crate::Location, $crate::Xcm<()>)> { use $crate::DmpMessageHandlerT; let d = destination.take().ok_or($crate::SendError::MissingArgument)?; - match (d.interior(), d.parent_count()) { + match d.unpack() { $( - ($crate::X1($crate::Parachain(id)), 0) if id == &$para_id => {}, + (0, [$crate::Parachain(id)]) if id == &$para_id => {}, )* _ => { *destination = Some(d); @@ -433,10 +433,10 @@ macro_rules! decl_test_network { }, } let m = message.take().ok_or($crate::SendError::MissingArgument)?; - Ok(((d, m), $crate::MultiAssets::new())) + Ok(((d, m), $crate::Assets::new())) } fn deliver( - pair: ($crate::MultiLocation, $crate::Xcm<()>), + pair: ($crate::Location, $crate::Xcm<()>), ) -> Result<$crate::XcmHash, $crate::SendError> { let hash = $crate::fake_message_hash(&pair.1); $crate::RELAY_MESSAGE_BUS.with(|b| b.borrow_mut().push_back(pair)); diff --git a/prdoc/pr_1230.prdoc b/prdoc/pr_1230.prdoc new file mode 100644 index 00000000000..8eea1816cb5 --- /dev/null +++ b/prdoc/pr_1230.prdoc @@ -0,0 +1,20 @@ +title: XCMv4 + +doc: + - audience: Runtime Dev + description: | + A new version of the XCM format. + The main changes are: + - Removed `Multi` prefix from types + - Removed `Abstract` asset id + - `Outcome` is now a named fields struct + - Added `Reanchorable` trait, implemented for both `Location` and `Asset` + - New syntax for building `Location`s and `Junction`s using slices. + You build them like `let location = Location::new(1, [Parachain(1000), PalletInstance(50), GeneralIndex(1984)]);` + and match on them like `match location.unpack() { + (1, [Parachain(id)]) => ... + (0, Here) => ..., + (1, [_]) => ..., + }` + +crates: [] diff --git a/substrate/frame/assets/src/benchmarking.rs b/substrate/frame/assets/src/benchmarking.rs index 8fe5a7e2493..1b65bb953d7 100644 --- a/substrate/frame/assets/src/benchmarking.rs +++ b/substrate/frame/assets/src/benchmarking.rs @@ -45,7 +45,7 @@ fn create_default_asset, I: 'static>( let root = SystemOrigin::Root.into(); assert!(Assets::::force_create( root, - asset_id, + asset_id.clone(), caller_lookup.clone(), is_sufficient, 1u32.into(), @@ -64,7 +64,7 @@ pub fn create_default_minted_asset, I: 'static>( } assert!(Assets::::mint( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), caller_lookup.clone(), amount, ) @@ -91,7 +91,7 @@ fn add_sufficients, I: 'static>(minter: T::AccountId, n: u32) { let target_lookup = T::Lookup::unlookup(target); assert!(Assets::::mint( origin.clone().into(), - asset_id, + asset_id.clone(), target_lookup, 100u32.into() ) @@ -108,8 +108,13 @@ fn add_approvals, I: 'static>(minter: T::AccountId, n: u32) { ); let minter_lookup = T::Lookup::unlookup(minter.clone()); let origin = SystemOrigin::Signed(minter); - Assets::::mint(origin.clone().into(), asset_id, minter_lookup, (100 * (n + 1)).into()) - .unwrap(); + Assets::::mint( + origin.clone().into(), + asset_id.clone(), + minter_lookup, + (100 * (n + 1)).into(), + ) + .unwrap(); let enough = T::Currency::minimum_balance(); for i in 0..n { let target = account("approval", i, SEED); @@ -117,7 +122,7 @@ fn add_approvals, I: 'static>(minter: T::AccountId, n: u32) { let target_lookup = T::Lookup::unlookup(target); Assets::::approve_transfer( origin.clone().into(), - asset_id, + asset_id.clone(), target_lookup, 100u32.into(), ) @@ -136,12 +141,12 @@ fn assert_event, I: 'static>(generic_event: >::Runti benchmarks_instance_pallet! { create { let asset_id = default_asset_id::(); - let origin = T::CreateOrigin::try_successful_origin(&asset_id.into()) + let origin = T::CreateOrigin::try_successful_origin(&asset_id.clone().into()) .map_err(|_| BenchmarkError::Weightless)?; - let caller = T::CreateOrigin::ensure_origin(origin.clone(), &asset_id.into()).unwrap(); + let caller = T::CreateOrigin::ensure_origin(origin.clone(), &asset_id.clone().into()).unwrap(); let caller_lookup = T::Lookup::unlookup(caller.clone()); T::Currency::make_free_balance_be(&caller, DepositBalanceOf::::max_value()); - }: _(origin, asset_id, caller_lookup, 1u32.into()) + }: _(origin, asset_id.clone(), caller_lookup, 1u32.into()) verify { assert_last_event::(Event::Created { asset_id: asset_id.into(), creator: caller.clone(), owner: caller }.into()); } @@ -150,7 +155,7 @@ benchmarks_instance_pallet! { let asset_id = default_asset_id::(); let caller: T::AccountId = whitelisted_caller(); let caller_lookup = T::Lookup::unlookup(caller.clone()); - }: _(SystemOrigin::Root, asset_id, caller_lookup, true, 1u32.into()) + }: _(SystemOrigin::Root, asset_id.clone(), caller_lookup, true, 1u32.into()) verify { assert_last_event::(Event::ForceCreated { asset_id: asset_id.into(), owner: caller }.into()); } @@ -159,9 +164,9 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, 100u32.into()); Assets::::freeze_asset( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), )?; - }:_(SystemOrigin::Signed(caller), asset_id) + }:_(SystemOrigin::Signed(caller), asset_id.clone()) verify { assert_last_event::(Event::DestructionStarted { asset_id: asset_id.into() }.into()); } @@ -172,10 +177,10 @@ benchmarks_instance_pallet! { add_sufficients::(caller.clone(), c); Assets::::freeze_asset( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), )?; - Assets::::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id)?; - }:_(SystemOrigin::Signed(caller), asset_id) + Assets::::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id.clone())?; + }:_(SystemOrigin::Signed(caller), asset_id.clone()) verify { assert_last_event::(Event::AccountsDestroyed { asset_id: asset_id.into(), @@ -190,10 +195,10 @@ benchmarks_instance_pallet! { add_approvals::(caller.clone(), a); Assets::::freeze_asset( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), )?; - Assets::::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id)?; - }:_(SystemOrigin::Signed(caller), asset_id) + Assets::::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id.clone())?; + }:_(SystemOrigin::Signed(caller), asset_id.clone()) verify { assert_last_event::(Event::ApprovalsDestroyed { asset_id: asset_id.into(), @@ -206,10 +211,10 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_asset::(true); Assets::::freeze_asset( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), )?; - Assets::::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id)?; - }:_(SystemOrigin::Signed(caller), asset_id) + Assets::::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id.clone())?; + }:_(SystemOrigin::Signed(caller), asset_id.clone()) verify { assert_last_event::(Event::Destroyed { asset_id: asset_id.into(), @@ -220,7 +225,7 @@ benchmarks_instance_pallet! { mint { let (asset_id, caller, caller_lookup) = create_default_asset::(true); let amount = T::Balance::from(100u32); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, amount) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, amount) verify { assert_last_event::(Event::Issued { asset_id: asset_id.into(), owner: caller, amount }.into()); } @@ -228,7 +233,7 @@ benchmarks_instance_pallet! { burn { let amount = T::Balance::from(100u32); let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, amount); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, amount) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, amount) verify { assert_last_event::(Event::Burned { asset_id: asset_id.into(), owner: caller, balance: amount }.into()); } @@ -238,7 +243,7 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, amount); let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, target_lookup, amount) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), target_lookup, amount) verify { assert_last_event::(Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into()); } @@ -249,7 +254,7 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, mint_amount); let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, target_lookup, amount) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), target_lookup, amount) verify { assert!(frame_system::Pallet::::account_exists(&caller)); assert_last_event::(Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into()); @@ -260,7 +265,7 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, amount); let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, target_lookup, amount) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, target_lookup, amount) verify { assert_last_event::( Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into() @@ -269,7 +274,7 @@ benchmarks_instance_pallet! { freeze { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, 100u32.into()); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup) verify { assert_last_event::(Event::Frozen { asset_id: asset_id.into(), who: caller }.into()); } @@ -278,17 +283,17 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, 100u32.into()); Assets::::freeze( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), caller_lookup.clone(), )?; - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup) verify { assert_last_event::(Event::Thawed { asset_id: asset_id.into(), who: caller }.into()); } freeze_asset { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, 100u32.into()); - }: _(SystemOrigin::Signed(caller.clone()), asset_id) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone()) verify { assert_last_event::(Event::AssetFrozen { asset_id: asset_id.into() }.into()); } @@ -297,9 +302,9 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, 100u32.into()); Assets::::freeze_asset( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), )?; - }: _(SystemOrigin::Signed(caller.clone()), asset_id) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone()) verify { assert_last_event::(Event::AssetThawed { asset_id: asset_id.into() }.into()); } @@ -308,7 +313,7 @@ benchmarks_instance_pallet! { let (asset_id, caller, _) = create_default_asset::(true); let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); - }: _(SystemOrigin::Signed(caller), asset_id, target_lookup) + }: _(SystemOrigin::Signed(caller), asset_id.clone(), target_lookup) verify { assert_last_event::(Event::OwnerChanged { asset_id: asset_id.into(), owner: target }.into()); } @@ -318,7 +323,7 @@ benchmarks_instance_pallet! { let target0 = T::Lookup::unlookup(account("target", 0, SEED)); let target1 = T::Lookup::unlookup(account("target", 1, SEED)); let target2 = T::Lookup::unlookup(account("target", 2, SEED)); - }: _(SystemOrigin::Signed(caller), asset_id, target0, target1, target2) + }: _(SystemOrigin::Signed(caller), asset_id.clone(), target0, target1, target2) verify { assert_last_event::(Event::TeamChanged { asset_id: asset_id.into(), @@ -338,7 +343,7 @@ benchmarks_instance_pallet! { let (asset_id, caller, _) = create_default_asset::(true); T::Currency::make_free_balance_be(&caller, DepositBalanceOf::::max_value()); - }: _(SystemOrigin::Signed(caller), asset_id, name.clone(), symbol.clone(), decimals) + }: _(SystemOrigin::Signed(caller), asset_id.clone(), name.clone(), symbol.clone(), decimals) verify { assert_last_event::(Event::MetadataSet { asset_id: asset_id.into(), name, symbol, decimals, is_frozen: false }.into()); } @@ -348,8 +353,8 @@ benchmarks_instance_pallet! { T::Currency::make_free_balance_be(&caller, DepositBalanceOf::::max_value()); let dummy = vec![0u8; T::StringLimit::get() as usize]; let origin = SystemOrigin::Signed(caller.clone()).into(); - Assets::::set_metadata(origin, asset_id, dummy.clone(), dummy, 12)?; - }: _(SystemOrigin::Signed(caller), asset_id) + Assets::::set_metadata(origin, asset_id.clone(), dummy.clone(), dummy, 12)?; + }: _(SystemOrigin::Signed(caller), asset_id.clone()) verify { assert_last_event::(Event::MetadataCleared { asset_id: asset_id.into() }.into()); } @@ -367,7 +372,7 @@ benchmarks_instance_pallet! { let origin = T::ForceOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; let call = Call::::force_set_metadata { - id: asset_id, + id: asset_id.clone(), name: name.clone(), symbol: symbol.clone(), decimals, @@ -383,11 +388,11 @@ benchmarks_instance_pallet! { T::Currency::make_free_balance_be(&caller, DepositBalanceOf::::max_value()); let dummy = vec![0u8; T::StringLimit::get() as usize]; let origin = SystemOrigin::Signed(caller).into(); - Assets::::set_metadata(origin, asset_id, dummy.clone(), dummy, 12)?; + Assets::::set_metadata(origin, asset_id.clone(), dummy.clone(), dummy, 12)?; let origin = T::ForceOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let call = Call::::force_clear_metadata { id: asset_id }; + let call = Call::::force_clear_metadata { id: asset_id.clone() }; }: { call.dispatch_bypass_filter(origin)? } verify { assert_last_event::(Event::MetadataCleared { asset_id: asset_id.into() }.into()); @@ -399,7 +404,7 @@ benchmarks_instance_pallet! { let origin = T::ForceOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; let call = Call::::force_asset_status { - id: asset_id, + id: asset_id.clone(), owner: caller_lookup.clone(), issuer: caller_lookup.clone(), admin: caller_lookup.clone(), @@ -420,7 +425,7 @@ benchmarks_instance_pallet! { let delegate: T::AccountId = account("delegate", 0, SEED); let delegate_lookup = T::Lookup::unlookup(delegate.clone()); let amount = 100u32.into(); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, delegate_lookup, amount) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), delegate_lookup, amount) verify { assert_last_event::(Event::ApprovedTransfer { asset_id: asset_id.into(), source: caller, delegate, amount }.into()); } @@ -434,11 +439,11 @@ benchmarks_instance_pallet! { let delegate_lookup = T::Lookup::unlookup(delegate.clone()); let amount = 100u32.into(); let origin = SystemOrigin::Signed(owner.clone()).into(); - Assets::::approve_transfer(origin, asset_id, delegate_lookup, amount)?; + Assets::::approve_transfer(origin, asset_id.clone(), delegate_lookup, amount)?; let dest: T::AccountId = account("dest", 0, SEED); let dest_lookup = T::Lookup::unlookup(dest.clone()); - }: _(SystemOrigin::Signed(delegate.clone()), asset_id, owner_lookup, dest_lookup, amount) + }: _(SystemOrigin::Signed(delegate.clone()), asset_id.clone(), owner_lookup, dest_lookup, amount) verify { assert!(T::Currency::reserved_balance(&owner).is_zero()); assert_event::(Event::Transferred { asset_id: asset_id.into(), from: owner, to: dest, amount }.into()); @@ -452,8 +457,8 @@ benchmarks_instance_pallet! { let delegate_lookup = T::Lookup::unlookup(delegate.clone()); let amount = 100u32.into(); let origin = SystemOrigin::Signed(caller.clone()).into(); - Assets::::approve_transfer(origin, asset_id, delegate_lookup.clone(), amount)?; - }: _(SystemOrigin::Signed(caller.clone()), asset_id, delegate_lookup) + Assets::::approve_transfer(origin, asset_id.clone(), delegate_lookup.clone(), amount)?; + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), delegate_lookup) verify { assert_last_event::(Event::ApprovalCancelled { asset_id: asset_id.into(), owner: caller, delegate }.into()); } @@ -466,15 +471,15 @@ benchmarks_instance_pallet! { let delegate_lookup = T::Lookup::unlookup(delegate.clone()); let amount = 100u32.into(); let origin = SystemOrigin::Signed(caller.clone()).into(); - Assets::::approve_transfer(origin, asset_id, delegate_lookup.clone(), amount)?; - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, delegate_lookup) + Assets::::approve_transfer(origin, asset_id.clone(), delegate_lookup.clone(), amount)?; + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, delegate_lookup) verify { assert_last_event::(Event::ApprovalCancelled { asset_id: asset_id.into(), owner: caller, delegate }.into()); } set_min_balance { let (asset_id, caller, caller_lookup) = create_default_asset::(false); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, 50u32.into()) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), 50u32.into()) verify { assert_last_event::(Event::AssetMinBalanceChanged { asset_id: asset_id.into(), new_min_balance: 50u32.into() }.into()); } @@ -484,8 +489,8 @@ benchmarks_instance_pallet! { let new_account: T::AccountId = account("newaccount", 1, SEED); T::Currency::make_free_balance_be(&new_account, DepositBalanceOf::::max_value()); assert_ne!(asset_owner, new_account); - assert!(!Account::::contains_key(asset_id.into(), &new_account)); - }: _(SystemOrigin::Signed(new_account.clone()), asset_id) + assert!(!Account::::contains_key(asset_id.clone().into(), &new_account)); + }: _(SystemOrigin::Signed(new_account.clone()), asset_id.clone()) verify { assert!(Account::::contains_key(asset_id.into(), &new_account)); } @@ -496,8 +501,8 @@ benchmarks_instance_pallet! { let new_account_lookup = T::Lookup::unlookup(new_account.clone()); T::Currency::make_free_balance_be(&asset_owner, DepositBalanceOf::::max_value()); assert_ne!(asset_owner, new_account); - assert!(!Account::::contains_key(asset_id.into(), &new_account)); - }: _(SystemOrigin::Signed(asset_owner.clone()), asset_id, new_account_lookup) + assert!(!Account::::contains_key(asset_id.clone().into(), &new_account)); + }: _(SystemOrigin::Signed(asset_owner.clone()), asset_id.clone(), new_account_lookup) verify { assert!(Account::::contains_key(asset_id.into(), &new_account)); } @@ -509,12 +514,12 @@ benchmarks_instance_pallet! { assert_ne!(asset_owner, new_account); assert!(Assets::::touch( SystemOrigin::Signed(new_account.clone()).into(), - asset_id + asset_id.clone() ).is_ok()); // `touch` should reserve balance of the caller according to the `AssetAccountDeposit` amount... assert_eq!(T::Currency::reserved_balance(&new_account), T::AssetAccountDeposit::get()); // ...and also create an `Account` entry. - assert!(Account::::contains_key(asset_id.into(), &new_account)); + assert!(Account::::contains_key(asset_id.clone().into(), &new_account)); }: _(SystemOrigin::Signed(new_account.clone()), asset_id, true) verify { // `refund`ing should of course repatriate the reserve @@ -529,12 +534,12 @@ benchmarks_instance_pallet! { assert_ne!(asset_owner, new_account); assert!(Assets::::touch_other( SystemOrigin::Signed(asset_owner.clone()).into(), - asset_id, + asset_id.clone(), new_account_lookup.clone() ).is_ok()); // `touch` should reserve balance of the caller according to the `AssetAccountDeposit` amount... assert_eq!(T::Currency::reserved_balance(&asset_owner), T::AssetAccountDeposit::get()); - assert!(Account::::contains_key(asset_id.into(), &new_account)); + assert!(Account::::contains_key(asset_id.clone().into(), &new_account)); }: _(SystemOrigin::Signed(asset_owner.clone()), asset_id, new_account_lookup.clone()) verify { // this should repatriate the reserved balance of the freezer @@ -543,7 +548,7 @@ benchmarks_instance_pallet! { block { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, 100u32.into()); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup) verify { assert_last_event::(Event::Blocked { asset_id: asset_id.into(), who: caller }.into()); } diff --git a/substrate/frame/assets/src/lib.rs b/substrate/frame/assets/src/lib.rs index f3ae03d667b..cafe7bb1a3b 100644 --- a/substrate/frame/assets/src/lib.rs +++ b/substrate/frame/assets/src/lib.rs @@ -259,11 +259,7 @@ pub mod pallet { /// This type includes the `From` bound, since tightly coupled pallets may /// want to convert an `AssetId` into a parameter for calling dispatchable functions /// directly. - type AssetIdParameter: Parameter - + Copy - + From - + Into - + MaxEncodedLen; + type AssetIdParameter: Parameter + From + Into + MaxEncodedLen; /// The currency mechanism. type Currency: ReservableCurrency; diff --git a/substrate/frame/contracts/mock-network/src/lib.rs b/substrate/frame/contracts/mock-network/src/lib.rs index 345c69541b6..eea9dde062c 100644 --- a/substrate/frame/contracts/mock-network/src/lib.rs +++ b/substrate/frame/contracts/mock-network/src/lib.rs @@ -24,7 +24,7 @@ mod tests; use crate::primitives::{AccountId, UNITS}; use sp_runtime::BuildStorage; -use xcm::latest::{prelude::*, MultiLocation}; +use xcm::latest::prelude::*; use xcm_executor::traits::ConvertLocation; use xcm_simulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain, TestExt}; @@ -67,12 +67,12 @@ decl_test_network! { } pub fn relay_sovereign_account_id() -> AccountId { - let location: MultiLocation = (Parent,).into(); + let location: Location = (Parent,).into(); parachain::SovereignAccountOf::convert_location(&location).unwrap() } pub fn parachain_sovereign_account_id(para: u32) -> AccountId { - let location: MultiLocation = (Parachain(para),).into(); + let location: Location = (Parachain(para),).into(); relay_chain::SovereignAccountOf::convert_location(&location).unwrap() } @@ -80,7 +80,7 @@ pub fn parachain_account_sovereign_account_id( para: u32, who: sp_runtime::AccountId32, ) -> AccountId { - let location: MultiLocation = ( + let location: Location = ( Parachain(para), AccountId32 { network: Some(relay_chain::RelayNetwork::get()), id: who.into() }, ) diff --git a/substrate/frame/contracts/mock-network/src/mocks/msg_queue.rs b/substrate/frame/contracts/mock-network/src/mocks/msg_queue.rs index 82fb8590e26..cc81b6bd636 100644 --- a/substrate/frame/contracts/mock-network/src/mocks/msg_queue.rs +++ b/substrate/frame/contracts/mock-network/src/mocks/msg_queue.rs @@ -96,16 +96,23 @@ pub mod pallet { max_weight: Weight, ) -> Result { let hash = Encode::using_encoded(&xcm, T::Hashing::hash); - let message_hash = Encode::using_encoded(&xcm, sp_io::hashing::blake2_256); + let mut message_hash = Encode::using_encoded(&xcm, sp_io::hashing::blake2_256); let (result, event) = match Xcm::::try_from(xcm) { Ok(xcm) => { let location = (Parent, Parachain(sender.into())); - match T::XcmExecutor::execute_xcm(location, xcm, message_hash, max_weight) { - Outcome::Error(e) => (Err(e), Event::Fail(Some(hash), e)), - Outcome::Complete(w) => (Ok(w), Event::Success(Some(hash))), + match T::XcmExecutor::prepare_and_execute( + location, + xcm, + &mut message_hash, + max_weight, + Weight::zero(), + ) { + Outcome::Error { error } => (Err(error), Event::Fail(Some(hash), error)), + Outcome::Complete { used } => (Ok(used), Event::Success(Some(hash))), // As far as the caller is concerned, this was dispatched without error, so // we just report the weight used. - Outcome::Incomplete(w, e) => (Ok(w), Event::Fail(Some(hash), e)), + Outcome::Incomplete { used, error } => + (Ok(used), Event::Fail(Some(hash), error)), } }, Err(()) => (Err(XcmError::UnhandledXcmVersion), Event::BadVersion(Some(hash))), @@ -146,7 +153,7 @@ pub mod pallet { limit: Weight, ) -> Weight { for (_i, (_sent_at, data)) in iter.enumerate() { - let id = sp_io::hashing::blake2_256(&data[..]); + let mut id = sp_io::hashing::blake2_256(&data[..]); let maybe_versioned = VersionedXcm::::decode(&mut &data[..]); match maybe_versioned { Err(_) => { @@ -155,7 +162,13 @@ pub mod pallet { Ok(versioned) => match Xcm::try_from(versioned) { Err(()) => Self::deposit_event(Event::UnsupportedVersion(id)), Ok(x) => { - let outcome = T::XcmExecutor::execute_xcm(Parent, x.clone(), id, limit); + let outcome = T::XcmExecutor::prepare_and_execute( + Parent, + x.clone(), + &mut id, + limit, + Weight::zero(), + ); >::append(x); Self::deposit_event(Event::ExecutedDownward(id, outcome)); }, diff --git a/substrate/frame/contracts/mock-network/src/parachain.rs b/substrate/frame/contracts/mock-network/src/parachain.rs index a79b7e4e2d6..90fc23af48d 100644 --- a/substrate/frame/contracts/mock-network/src/parachain.rs +++ b/substrate/frame/contracts/mock-network/src/parachain.rs @@ -143,10 +143,10 @@ parameter_types! { } parameter_types! { - pub const KsmLocation: MultiLocation = MultiLocation::parent(); - pub const TokenLocation: MultiLocation = Here.into_location(); + pub const KsmLocation: Location = Location::parent(); + pub const TokenLocation: Location = Here.into_location(); pub const RelayNetwork: NetworkId = ByGenesis([0; 32]); - pub UniversalLocation: InteriorMultiLocation = Parachain(MsgQueue::parachain_id().into()).into(); + pub UniversalLocation: InteriorLocation = Parachain(MsgQueue::parachain_id().into()).into(); } pub type XcmOriginToCallOrigin = ( @@ -158,13 +158,13 @@ pub type XcmOriginToCallOrigin = ( parameter_types! { pub const XcmInstructionWeight: Weight = Weight::from_parts(1_000, 1_000); - pub TokensPerSecondPerMegabyte: (AssetId, u128, u128) = (Concrete(Parent.into()), 1_000_000_000_000, 1024 * 1024); + pub TokensPerSecondPerMegabyte: (AssetId, u128, u128) = (AssetId(Parent.into()), 1_000_000_000_000, 1024 * 1024); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; - pub ForeignPrefix: MultiLocation = (Parent,).into(); + pub ForeignPrefix: Location = (Parent,).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); - pub TrustedLockPairs: (MultiLocation, MultiAssetFilter) = - (Parent.into(), Wild(AllOf { id: Concrete(Parent.into()), fun: WildFungible })); + pub TrustedLockPairs: (Location, AssetFilter) = + (Parent.into(), Wild(AllOf { id: AssetId(Parent.into()), fun: WildFungible })); } pub fn estimate_message_fee(number_of_instructions: u64) -> u128 { @@ -188,20 +188,19 @@ pub fn estimate_fee_for_weight(weight: Weight) -> u128 { pub type LocalBalancesTransactor = XcmCurrencyAdapter, SovereignAccountOf, AccountId, ()>; -pub struct FromMultiLocationToAsset(PhantomData<(MultiLocation, AssetId)>); -impl MaybeEquivalence - for FromMultiLocationToAsset +pub struct FromLocationToAsset(PhantomData<(Location, AssetId)>); +impl MaybeEquivalence + for FromLocationToAsset { - fn convert(value: &MultiLocation) -> Option { - match *value { - MultiLocation { parents: 1, interior: Here } => Some(0 as AssetIdForAssets), - MultiLocation { parents: 1, interior: X1(Parachain(para_id)) } => - Some(para_id as AssetIdForAssets), + fn convert(value: &Location) -> Option { + match value.unpack() { + (1, []) => Some(0 as AssetIdForAssets), + (1, [Parachain(para_id)]) => Some(*para_id as AssetIdForAssets), _ => None, } } - fn convert_back(_id: &AssetIdForAssets) -> Option { + fn convert_back(_id: &AssetIdForAssets) -> Option { None } } @@ -211,7 +210,7 @@ pub type ForeignAssetsTransactor = FungiblesAdapter< ConvertedConcreteId< AssetIdForAssets, Balance, - FromMultiLocationToAsset, + FromLocationToAsset, JustTry, >, SovereignAccountOf, @@ -224,18 +223,15 @@ pub type ForeignAssetsTransactor = FungiblesAdapter< pub type AssetTransactors = (LocalBalancesTransactor, ForeignAssetsTransactor); pub struct ParentRelay; -impl Contains for ParentRelay { - fn contains(location: &MultiLocation) -> bool { +impl Contains for ParentRelay { + fn contains(location: &Location) -> bool { location.contains_parents_only(1) } } pub struct ThisParachain; -impl Contains for ThisParachain { - fn contains(location: &MultiLocation) -> bool { - matches!( - location, - MultiLocation { parents: 0, interior: Junctions::X1(Junction::AccountId32 { .. }) } - ) +impl Contains for ThisParachain { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (0, [Junction::AccountId32 { .. }])) } } @@ -251,12 +247,12 @@ pub type Barrier = ( ); parameter_types! { - pub NftCollectionOne: MultiAssetFilter - = Wild(AllOf { fun: WildNonFungible, id: Concrete((Parent, GeneralIndex(1)).into()) }); - pub NftCollectionOneForRelay: (MultiAssetFilter, MultiLocation) + pub NftCollectionOne: AssetFilter + = Wild(AllOf { fun: WildNonFungible, id: AssetId((Parent, GeneralIndex(1)).into()) }); + pub NftCollectionOneForRelay: (AssetFilter, Location) = (NftCollectionOne::get(), Parent.into()); - pub RelayNativeAsset: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete((Parent, Here).into()) }); - pub RelayNativeAssetForRelay: (MultiAssetFilter, MultiLocation) = (RelayNativeAsset::get(), Parent.into()); + pub RelayNativeAsset: AssetFilter = Wild(AllOf { fun: WildFungible, id: AssetId((Parent, Here).into()) }); + pub RelayNativeAssetForRelay: (AssetFilter, Location) = (RelayNativeAsset::get(), Parent.into()); } pub type TrustedTeleporters = (xcm_builder::Case, xcm_builder::Case); @@ -298,10 +294,8 @@ impl mock_msg_queue::Config for Runtime { pub type LocalOriginToLocation = SignedToAccountId32; pub struct TrustedLockerCase(PhantomData); -impl> ContainsPair - for TrustedLockerCase -{ - fn contains(origin: &MultiLocation, asset: &MultiAsset) -> bool { +impl> ContainsPair for TrustedLockerCase { + fn contains(origin: &Location, asset: &Asset) -> bool { let (o, a) = T::get(); a.matches(asset) && &o == origin } diff --git a/substrate/frame/contracts/mock-network/src/relay_chain.rs b/substrate/frame/contracts/mock-network/src/relay_chain.rs index 136cc2e3ed6..4e5523f7442 100644 --- a/substrate/frame/contracts/mock-network/src/relay_chain.rs +++ b/substrate/frame/contracts/mock-network/src/relay_chain.rs @@ -107,8 +107,8 @@ impl configuration::Config for Runtime { parameter_types! { pub RelayNetwork: NetworkId = ByGenesis([0; 32]); - pub const TokenLocation: MultiLocation = Here.into_location(); - pub UniversalLocation: InteriorMultiLocation = Here; + pub const TokenLocation: Location = Here.into_location(); + pub UniversalLocation: InteriorLocation = Here; pub UnitWeightCost: u64 = 1_000; } @@ -134,15 +134,15 @@ type LocalOriginConverter = ( parameter_types! { pub const XcmInstructionWeight: Weight = Weight::from_parts(1_000, 1_000); pub TokensPerSecondPerMegabyte: (AssetId, u128, u128) = - (Concrete(TokenLocation::get()), 1_000_000_000_000, 1024 * 1024); + (AssetId(TokenLocation::get()), 1_000_000_000_000, 1024 * 1024); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; } pub struct ChildrenParachains; -impl Contains for ChildrenParachains { - fn contains(location: &MultiLocation) -> bool { - matches!(location, MultiLocation { parents: 0, interior: X1(Parachain(_)) }) +impl Contains for ChildrenParachains { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (0, [Parachain(_)])) } } diff --git a/substrate/frame/contracts/mock-network/src/tests.rs b/substrate/frame/contracts/mock-network/src/tests.rs index a66b2b08019..c25373bcbe3 100644 --- a/substrate/frame/contracts/mock-network/src/tests.rs +++ b/substrate/frame/contracts/mock-network/src/tests.rs @@ -31,7 +31,7 @@ use frame_support::{ use pallet_balances::{BalanceLock, Reasons}; use pallet_contracts::{Code, CollectEvents, DebugInfo, Determinism}; use pallet_contracts_fixtures::compile_module; -use xcm::{v3::prelude::*, VersionedMultiLocation, VersionedXcm}; +use xcm::{v4::prelude::*, VersionedLocation, VersionedXcm}; use xcm_simulator::TestExt; type ParachainContracts = pallet_contracts::Pallet; @@ -82,7 +82,7 @@ fn test_xcm_execute() { let amount: u128 = 10 * CENTS; // The XCM used to transfer funds to Bob. - let message: xcm_simulator::Xcm<()> = Xcm(vec![ + let message: Xcm<()> = Xcm(vec![ WithdrawAsset(vec![(Here, amount).into()].into()), DepositAsset { assets: All.into(), @@ -96,7 +96,7 @@ fn test_xcm_execute() { 0, Weight::MAX, None, - VersionedXcm::V3(message).encode(), + VersionedXcm::V4(message).encode(), DebugInfo::UnsafeDebug, CollectEvents::UnsafeCollect, Determinism::Enforced, @@ -106,7 +106,7 @@ fn test_xcm_execute() { let mut data = &result.data[..]; let outcome = Outcome::decode(&mut data).expect("Failed to decode xcm_execute Outcome"); - assert_matches!(outcome, Outcome::Complete(_)); + assert_matches!(outcome, Outcome::Complete { .. }); // Check if the funds are subtracted from the account of Alice and added to the account of // Bob. @@ -137,7 +137,7 @@ fn test_xcm_execute_filtered_call() { 0, Weight::MAX, None, - VersionedXcm::V3(message).encode(), + VersionedXcm::V4(message).encode(), DebugInfo::UnsafeDebug, CollectEvents::UnsafeCollect, Determinism::Enforced, @@ -178,7 +178,7 @@ fn test_xcm_execute_reentrant_call() { 0, Weight::MAX, None, - VersionedXcm::V3(message).encode(), + VersionedXcm::V4(message).encode(), DebugInfo::UnsafeDebug, CollectEvents::UnsafeCollect, Determinism::Enforced, @@ -188,7 +188,10 @@ fn test_xcm_execute_reentrant_call() { let mut data = &result.data[..]; let outcome = Outcome::decode(&mut data).expect("Failed to decode xcm_execute Outcome"); - assert_matches!(outcome, Outcome::Incomplete(_, XcmError::ExpectationFalse)); + assert_matches!( + outcome, + Outcome::Incomplete { used: _, error: XcmError::ExpectationFalse } + ); // Funds should not change hands as the XCM transact failed. assert_eq!(ParachainBalances::free_balance(BOB), INITIAL_BALANCE); @@ -203,15 +206,15 @@ fn test_xcm_send() { // Send XCM instructions through the contract, to lock some funds on the relay chain. ParaA::execute_with(|| { - let dest = MultiLocation::from(Parent); - let dest = VersionedMultiLocation::V3(dest); + let dest = Location::from(Parent); + let dest = VersionedLocation::V4(dest); - let message: xcm_simulator::Xcm<()> = Xcm(vec![ + let message: Xcm<()> = Xcm(vec![ WithdrawAsset((Here, fee).into()), BuyExecution { fees: (Here, fee).into(), weight_limit: WeightLimit::Unlimited }, LockAsset { asset: (Here, 5 * CENTS).into(), unlocker: (Parachain(1)).into() }, ]); - let message = VersionedXcm::V3(message); + let message = VersionedXcm::V4(message); let exec = ParachainContracts::bare_call( ALICE, contract_addr.clone(), diff --git a/substrate/frame/contracts/src/wasm/runtime.rs b/substrate/frame/contracts/src/wasm/runtime.rs index a7f329005f9..3e49b68f86b 100644 --- a/substrate/frame/contracts/src/wasm/runtime.rs +++ b/substrate/frame/contracts/src/wasm/runtime.rs @@ -2169,11 +2169,11 @@ pub mod env { msg_len: u32, output_ptr: u32, ) -> Result { - use xcm::{VersionedMultiLocation, VersionedXcm}; + use xcm::{VersionedLocation, VersionedXcm}; use xcm_builder::{SendController, SendControllerWeightInfo}; ctx.charge_gas(RuntimeCosts::CopyFromContract(msg_len))?; - let dest: VersionedMultiLocation = ctx.read_sandbox_memory_as(memory, dest_ptr)?; + let dest: VersionedLocation = ctx.read_sandbox_memory_as(memory, dest_ptr)?; let message: VersionedXcm<()> = ctx.read_sandbox_memory_as_unbounded(memory, msg_ptr, msg_len)?; diff --git a/substrate/frame/support/src/traits/tokens/pay.rs b/substrate/frame/support/src/traits/tokens/pay.rs index 4d1d80b5b50..62d7a056a3f 100644 --- a/substrate/frame/support/src/traits/tokens/pay.rs +++ b/substrate/frame/support/src/traits/tokens/pay.rs @@ -26,7 +26,7 @@ use sp_std::fmt::Debug; use super::{fungible, fungibles, Balance, Preservation::Expendable}; /// Can be implemented by `PayFromAccount` using a `fungible` impl, but can also be implemented with -/// XCM/MultiAsset and made generic over assets. +/// XCM/Asset and made generic over assets. pub trait Pay { /// The type by which we measure units of the currency in which we make payments. type Balance: Balance; -- GitLab From 33d533e1be8210d65bcbfed58fac5b659333fc77 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 09:20:27 +0100 Subject: [PATCH 064/392] Bump futures-util from 0.3.28 to 0.3.30 (#2952) Bumps [futures-util](https://github.com/rust-lang/futures-rs) from 0.3.28 to 0.3.30.
Release notes

Sourced from futures-util's releases.

0.3.30

  • Add {BiLock,SplitStream,SplitSink,ReadHalf,WriteHalf}::is_pair_of (#2797)
  • Fix panic in FuturesUnordered::clear (#2809)
  • Fix panic in AsyncBufReadExt::fill_buf (#2801, #2812)
  • Improve support for targets without atomic CAS (#2811)
  • Remove build scripts (#2811)

0.3.29

  • Add TryStreamExt::try_ready_chunks (#2757)
  • Add TryStreamExt::{try_all,try_any} (#2783)
  • Add UnboundedSender::{len,is_empty} (#2750)
  • Fix Sync impl of FuturesUnordered (#2788)
  • Fix infinite loop caused by invalid UTF-8 bytes (#2785)
  • Fix build error with -Z minimal-versions (#2761)
Changelog

Sourced from futures-util's changelog.

0.3.30 - 2023-12-24

  • Add {BiLock,SplitStream,SplitSink,ReadHalf,WriteHalf}::is_pair_of (#2797)
  • Fix panic in FuturesUnordered::clear (#2809)
  • Fix panic in AsyncBufReadExt::fill_buf (#2801, #2812)
  • Improve support for targets without atomic CAS (#2811)
  • Remove build scripts (#2811)

0.3.29 - 2023-10-26

  • Add TryStreamExt::try_ready_chunks (#2757)
  • Add TryStreamExt::{try_all,try_any} (#2783)
  • Add UnboundedSender::{len,is_empty} (#2750)
  • Fix Sync impl of FuturesUnordered (#2788)
  • Fix infinite loop caused by invalid UTF-8 bytes (#2785)
  • Fix build error with -Z minimal-versions (#2761)
Commits
  • de1a0fd Release 0.3.30
  • 68d2845 Remove a redundant space in example (#2816)
  • fdd2ce7 Fix broken link in CopyBufAbortable docs (#2815)
  • 272a3c7 Use cfg(target_has_atomic) on no-std targets
  • c179201 FillBuf: Do not call poll_fill_buf twice
  • e6735f3 FuturesUnordered: Fix clear implementation
  • 04d01a0 FuturesOrdered: Use 64-bit index
  • e4aa659 remove redundant impl Unpin
  • 17851c1 provide a mechanism to determine if io read/write halves are from the same st...
  • 4910799 provide a non-destructive mechanism to determine if a sink/stream are paired
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=futures-util&package-manager=cargo&previous-version=0.3.28&new-version=0.3.30)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 28 +++++++++---------- .../node/zombienet-backchannel/Cargo.toml | 2 +- substrate/client/rpc-spec-v2/Cargo.toml | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 31347261151..f685fcaa702 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5918,9 +5918,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -5928,9 +5928,9 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" @@ -5946,9 +5946,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-lite" @@ -5967,9 +5967,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", @@ -5989,15 +5989,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-timer" @@ -6007,9 +6007,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", diff --git a/polkadot/node/zombienet-backchannel/Cargo.toml b/polkadot/node/zombienet-backchannel/Cargo.toml index 82c6f2532ca..6af7a8d6e38 100644 --- a/polkadot/node/zombienet-backchannel/Cargo.toml +++ b/polkadot/node/zombienet-backchannel/Cargo.toml @@ -15,7 +15,7 @@ workspace = true tokio = { version = "1.24.2", default-features = false, features = ["macros", "net", "rt-multi-thread", "sync"] } url = "2.3.1" tokio-tungstenite = "0.17" -futures-util = "0.3.23" +futures-util = "0.3.30" lazy_static = "1.4.0" parity-scale-codec = { version = "3.6.1", features = ["derive"] } reqwest = { version = "0.11", features = ["rustls-tls"], default-features = false } diff --git a/substrate/client/rpc-spec-v2/Cargo.toml b/substrate/client/rpc-spec-v2/Cargo.toml index ba32308e678..17412f883ca 100644 --- a/substrate/client/rpc-spec-v2/Cargo.toml +++ b/substrate/client/rpc-spec-v2/Cargo.toml @@ -39,7 +39,7 @@ tokio-stream = { version = "0.1.14", features = ["sync"] } tokio = { version = "1.22.0", features = ["sync"] } array-bytes = "6.1" log = "0.4.17" -futures-util = { version = "0.3.19", default-features = false } +futures-util = { version = "0.3.30", default-features = false } [dev-dependencies] serde_json = "1.0.111" -- GitLab From c01dbebeaa6394691974de46dd2d41a582f6a4c2 Mon Sep 17 00:00:00 2001 From: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Date: Wed, 17 Jan 2024 09:59:00 +0100 Subject: [PATCH 065/392] Revert "pallet-core-fellowship: import an unimported member on approve" (#2956) Reverts paritytech/polkadot-sdk#2883 Code, not docs, was intended. --- prdoc/pr_2883.prdoc | 9 ------ substrate/frame/core-fellowship/src/lib.rs | 29 ++++++-------------- substrate/frame/core-fellowship/src/tests.rs | 8 ------ 3 files changed, 9 insertions(+), 37 deletions(-) delete mode 100644 prdoc/pr_2883.prdoc diff --git a/prdoc/pr_2883.prdoc b/prdoc/pr_2883.prdoc deleted file mode 100644 index e2817d16a03..00000000000 --- a/prdoc/pr_2883.prdoc +++ /dev/null @@ -1,9 +0,0 @@ -title: "pallet-core-fellowship: import an unimported on approve" - -doc: - - audience: Runtime User - description: | - To align with the documentation of the approve call, we import an untracked member on approval. - -crates: - - name: "pallet-core-fellowship" diff --git a/substrate/frame/core-fellowship/src/lib.rs b/substrate/frame/core-fellowship/src/lib.rs index ee16ae07ce6..a0a45c7c594 100644 --- a/substrate/frame/core-fellowship/src/lib.rs +++ b/substrate/frame/core-fellowship/src/lib.rs @@ -362,8 +362,7 @@ pub mod pallet { /// /// This resets `last_proof` to the current block, thereby delaying any automatic demotion. /// - /// If `who` is not already tracked by this pallet, then it will become tracked. - /// `last_promotion` will be set to zero. + /// `who` must already be tracked by this pallet for this to have an effect. /// /// - `origin`: An origin which satisfies `ApproveOrigin` or root. /// - `who`: A member (i.e. of non-zero rank). @@ -382,11 +381,7 @@ pub mod pallet { ensure!(at_rank > 0, Error::::InvalidRank); let rank = T::Members::rank_of(&who).ok_or(Error::::Unranked)?; ensure!(rank == at_rank, Error::::UnexpectedRank); - let mut member = if let Some(m) = Member::::get(&who) { - m - } else { - Self::import_member(who.clone(), rank) - }; + let mut member = Member::::get(&who).ok_or(Error::::NotTracked)?; member.last_proof = frame_system::Pallet::::block_number(); Member::::insert(&who, &member); @@ -522,7 +517,13 @@ pub mod pallet { let who = ensure_signed(origin)?; ensure!(!Member::::contains_key(&who), Error::::AlreadyInducted); let rank = T::Members::rank_of(&who).ok_or(Error::::Unranked)?; - let _ = Self::import_member(who, rank); + + let now = frame_system::Pallet::::block_number(); + Member::::insert( + &who, + MemberStatus { is_active: true, last_promotion: 0u32.into(), last_proof: now }, + ); + Self::deposit_event(Event::::Imported { who, rank }); Ok(Pays::No.into()) } @@ -546,18 +547,6 @@ pub mod pallet { Self::deposit_event(e); } } - - fn import_member(who: T::AccountId, rank: RankOf) -> MemberStatusOf { - let now = frame_system::Pallet::::block_number(); - let status = MemberStatus { - is_active: true, - last_promotion: BlockNumberFor::::zero(), - last_proof: now, - }; - Member::::insert(&who, status.clone()); - Self::deposit_event(Event::::Imported { who, rank }); - status - } } impl, I: 'static> GetSalary, T::AccountId, T::Balance> for Pallet { diff --git a/substrate/frame/core-fellowship/src/tests.rs b/substrate/frame/core-fellowship/src/tests.rs index 6d9cebbf921..c9098f2171f 100644 --- a/substrate/frame/core-fellowship/src/tests.rs +++ b/substrate/frame/core-fellowship/src/tests.rs @@ -378,11 +378,3 @@ fn active_changing_get_salary_works() { } }); } - -#[test] -fn approve_imports_not_tracked_member() { - new_test_ext().execute_with(|| { - set_rank(10, 5); - assert_ok!(CoreFellowship::approve(signed(5), 10, 5)); - }); -} -- GitLab From 8b28031d16e7a9ed059aa90cb4b4488d58a7d9d9 Mon Sep 17 00:00:00 2001 From: Ignacio Palacios Date: Wed, 17 Jan 2024 12:05:44 +0100 Subject: [PATCH 066/392] Add `Storage` to `PolkadotXcm` for People Chains (#2959) After People Rococo deployment, we noticed that `safeXcmVersion` wasn't initialised. I think it is due to `Storage` missing in the pallet's declaration. This PR should fix it. --- cumulus/parachains/runtimes/people/people-rococo/src/lib.rs | 2 +- cumulus/parachains/runtimes/people/people-westend/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index f5398829c73..00dd58e4a50 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -428,7 +428,7 @@ construct_runtime!( // XCM & related XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin, Config} = 31, + PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 34, diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index 33f0d511705..ee67c7419f1 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -428,7 +428,7 @@ construct_runtime!( // XCM helpers. XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin, Config} = 31, + PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 34, -- GitLab From c1c0e62d33f210663c87f3170b60acb2d0cd32b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Wed, 17 Jan 2024 12:39:33 +0100 Subject: [PATCH 067/392] contracts: Update to Polkavm 0.5 (#2945) This will allow us to change to the target supporting atomics and makes the linker file no longer necessary. --- Cargo.lock | 30 +++++++++++++++---- substrate/frame/contracts/fixtures/Cargo.toml | 2 +- substrate/frame/contracts/fixtures/build.rs | 15 +++++----- .../frame/contracts/fixtures/build/Cargo.toml | 2 +- .../fixtures/build/riscv_memory_layout.ld | 4 --- 5 files changed, 35 insertions(+), 18 deletions(-) delete mode 100644 substrate/frame/contracts/fixtures/build/riscv_memory_layout.ld diff --git a/Cargo.lock b/Cargo.lock index f685fcaa702..7f2221240cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3294,7 +3294,7 @@ dependencies = [ "gimli 0.27.3", "hashbrown 0.13.2", "log", - "regalloc2", + "regalloc2 0.6.1", "smallvec", "target-lexicon", ] @@ -13793,6 +13793,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fecd2caacfc4a7ee34243758dd7348859e6dec73f5e5df059890f5742ee46f0e" +[[package]] +name = "polkavm-common" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b4e215c80fe876147f3d58158d5dfeae7dabdd6047e175af77095b78d0035c" + [[package]] name = "polkavm-derive" version = "0.4.0" @@ -13809,7 +13815,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c99f4e7a9ff434ef9c885b874c99d824c3a5693bf5e3e8569bb1d2245a8c1b7f" dependencies = [ - "polkavm-common", + "polkavm-common 0.4.0", "proc-macro2", "quote", "syn 2.0.48", @@ -13817,15 +13823,16 @@ dependencies = [ [[package]] name = "polkavm-linker" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "550738c1b49b9279fa19d8ebed81f551b911b869227a20a190f85f6db45d5d0e" +checksum = "a5a668bb33c7f0b5f4ca91adb1e1e71cf4930fef5e6909f46c2180d65cce37d0" dependencies = [ "gimli 0.28.0", "hashbrown 0.14.3", "log", "object 0.32.2", - "polkavm-common", + "polkavm-common 0.5.0", + "regalloc2 0.9.3", "rustc-demangle", ] @@ -14597,6 +14604,19 @@ dependencies = [ "smallvec", ] +[[package]] +name = "regalloc2" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6" +dependencies = [ + "hashbrown 0.13.2", + "log", + "rustc-hash", + "slice-group-by", + "smallvec", +] + [[package]] name = "regex" version = "1.10.2" diff --git a/substrate/frame/contracts/fixtures/Cargo.toml b/substrate/frame/contracts/fixtures/Cargo.toml index 5ffac43d9de..7fdf56a91fc 100644 --- a/substrate/frame/contracts/fixtures/Cargo.toml +++ b/substrate/frame/contracts/fixtures/Cargo.toml @@ -21,7 +21,7 @@ parity-wasm = "0.45.0" tempfile = "3.8.1" toml = "0.8.2" twox-hash = "1.6.3" -polkavm-linker = { version = "0.4.0", optional = true } +polkavm-linker = { version = "0.5.0", optional = true } anyhow = "1.0.0" [features] diff --git a/substrate/frame/contracts/fixtures/build.rs b/substrate/frame/contracts/fixtures/build.rs index 125ee7f3722..7b814ef77a6 100644 --- a/substrate/frame/contracts/fixtures/build.rs +++ b/substrate/frame/contracts/fixtures/build.rs @@ -234,11 +234,12 @@ fn post_process_wasm(input_path: &Path, output_path: &Path) -> Result<()> { /// Build contracts for RISC-V. #[cfg(feature = "riscv")] fn invoke_riscv_build(current_dir: &Path) -> Result<()> { - let encoded_rustflags = - ["-Crelocation-model=pie", "-Clink-arg=--emit-relocs", "-Clink-arg=-Tmemory.ld"] - .join("\x1f"); - - fs::write(current_dir.join("memory.ld"), include_bytes!("./build/riscv_memory_layout.ld"))?; + let encoded_rustflags = [ + "-Crelocation-model=pie", + "-Clink-arg=--emit-relocs", + "-Clink-arg=--export-dynamic-symbol=__polkavm_symbol_export_hack__*", + ] + .join("\x1f"); let build_res = Command::new(env::var("CARGO")?) .current_dir(current_dir) @@ -247,7 +248,7 @@ fn invoke_riscv_build(current_dir: &Path) -> Result<()> { .env("CARGO_ENCODED_RUSTFLAGS", encoded_rustflags) .env("RUSTUP_TOOLCHAIN", "rve-nightly") .env("RUSTUP_HOME", env::var("RUSTUP_HOME").unwrap_or_default()) - .args(["build", "--release", "--target=riscv32em-unknown-none-elf"]) + .args(["build", "--release", "--target=riscv32ema-unknown-none-elf"]) .output() .expect("failed to execute process"); @@ -288,7 +289,7 @@ fn write_output(build_dir: &Path, out_dir: &Path, entries: Vec) -> Result #[cfg(feature = "riscv")] post_process_riscv( - &build_dir.join("target/riscv32em-unknown-none-elf/release").join(entry.name()), + &build_dir.join("target/riscv32ema-unknown-none-elf/release").join(entry.name()), &out_dir.join(entry.out_riscv_filename()), )?; diff --git a/substrate/frame/contracts/fixtures/build/Cargo.toml b/substrate/frame/contracts/fixtures/build/Cargo.toml index 70bf0ba94fe..1ff6b7ae7f8 100644 --- a/substrate/frame/contracts/fixtures/build/Cargo.toml +++ b/substrate/frame/contracts/fixtures/build/Cargo.toml @@ -10,7 +10,7 @@ edition = "2021" [dependencies] uapi = { package = 'pallet-contracts-uapi', path = "", default-features = false } common = { package = 'pallet-contracts-fixtures-common', path = "" } -polkavm-derive = '0.4.0' +polkavm-derive = '0.5.0' [profile.release] opt-level = 3 diff --git a/substrate/frame/contracts/fixtures/build/riscv_memory_layout.ld b/substrate/frame/contracts/fixtures/build/riscv_memory_layout.ld deleted file mode 100644 index 89084263ada..00000000000 --- a/substrate/frame/contracts/fixtures/build/riscv_memory_layout.ld +++ /dev/null @@ -1,4 +0,0 @@ -SECTIONS { - .text : { KEEP(*(.text.polkavm_export)) } -} - -- GitLab From f80cfc22595bbb39b50d2bd39661ff9eef74cb60 Mon Sep 17 00:00:00 2001 From: Egor_P Date: Wed, 17 Jan 2024 15:40:23 +0100 Subject: [PATCH 068/392] [Backport] Version bumps from 1.6.0 release (#2965) This PR backports version bumps from release branch `release-polkadot-v1.6.0` back to `master` and also moved `prdoc` files related to the release to the appropriate folder --- Cargo.lock | 4 ++-- .../parachains/runtimes/assets/asset-hub-rococo/src/lib.rs | 4 ++-- .../parachains/runtimes/assets/asset-hub-westend/src/lib.rs | 2 +- .../runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs | 2 +- .../runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs | 2 +- .../runtimes/collectives/collectives-westend/src/lib.rs | 2 +- .../parachains/runtimes/contracts/contracts-rococo/src/lib.rs | 2 +- .../parachains/runtimes/coretime/coretime-westend/src/lib.rs | 2 +- .../parachains/runtimes/glutton/glutton-westend/src/lib.rs | 2 +- cumulus/parachains/runtimes/people/people-rococo/src/lib.rs | 2 +- cumulus/parachains/runtimes/people/people-westend/src/lib.rs | 2 +- .../parachains/runtimes/testing/rococo-parachain/src/lib.rs | 2 +- cumulus/polkadot-parachain/Cargo.toml | 2 +- polkadot/Cargo.toml | 2 +- polkadot/node/primitives/src/lib.rs | 2 +- polkadot/runtime/westend/src/lib.rs | 2 +- prdoc/{ => 1.6.0}/pr_1191.prdoc | 0 prdoc/{ => 1.6.0}/pr_1226.prdoc | 0 prdoc/{ => 1.6.0}/pr_1289.prdoc | 0 prdoc/{ => 1.6.0}/pr_1343.prdoc | 0 prdoc/{ => 1.6.0}/pr_1454.prdoc | 0 prdoc/{ => 1.6.0}/pr_1479.prdoc | 0 prdoc/{ => 1.6.0}/pr_1677.prdoc | 0 prdoc/{ => 1.6.0}/pr_1694.prdoc | 0 prdoc/{ => 1.6.0}/pr_1841.prdoc | 0 prdoc/{ => 1.6.0}/pr_2031.prdoc | 0 prdoc/{ => 1.6.0}/pr_2033.prdoc | 0 prdoc/{ => 1.6.0}/pr_2281.prdoc | 0 prdoc/{ => 1.6.0}/pr_2331.prdoc | 0 prdoc/{ => 1.6.0}/pr_2403.prdoc | 0 prdoc/{ => 1.6.0}/pr_2481.prdoc | 0 prdoc/{ => 1.6.0}/pr_2522.prdoc | 0 prdoc/{ => 1.6.0}/pr_2532.prdoc | 0 prdoc/{ => 1.6.0}/pr_2597.prdoc | 0 prdoc/{ => 1.6.0}/pr_2637.prdoc | 0 prdoc/{ => 1.6.0}/pr_2651.prdoc | 0 prdoc/{ => 1.6.0}/pr_2656.prdoc | 0 .../pr_2663-fix-could-not-create-temporary-drectory.prdoc | 0 prdoc/{ => 1.6.0}/pr_2666.prdoc | 0 prdoc/{ => 1.6.0}/pr_2682.prdoc | 0 prdoc/{ => 1.6.0}/pr_2684.prdoc | 0 prdoc/{ => 1.6.0}/pr_2687.prdoc | 0 prdoc/{ => 1.6.0}/pr_2689.prdoc | 0 prdoc/{ => 1.6.0}/pr_2694.prdoc | 0 prdoc/{ => 1.6.0}/pr_2758.prdoc | 0 prdoc/{ => 1.6.0}/pr_2764.prdoc | 0 prdoc/{ => 1.6.0}/pr_2767.prdoc | 0 prdoc/{ => 1.6.0}/pr_2771.prdoc | 0 prdoc/{ => 1.6.0}/pr_2783.prdoc | 0 prdoc/{ => 1.6.0}/pr_2799.prdoc | 0 prdoc/{ => 1.6.0}/pr_2803.prdoc | 0 prdoc/{ => 1.6.0}/pr_2804.prdoc | 0 prdoc/{ => 1.6.0}/pr_2811.prdoc | 0 prdoc/{ => 1.6.0}/pr_2813.prdoc | 0 prdoc/{ => 1.6.0}/pr_2823.prdoc | 0 prdoc/{ => 1.6.0}/pr_2834.prdoc | 0 prdoc/{ => 1.6.0}/pr_2835.prdoc | 0 prdoc/{ => 1.6.0}/pr_2862.prdoc | 0 prdoc/{ => 1.6.0}/pr_2886.prdoc | 0 prdoc/{ => 1.6.0}/pr_2899.prdoc | 0 60 files changed, 18 insertions(+), 18 deletions(-) rename prdoc/{ => 1.6.0}/pr_1191.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_1226.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_1289.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_1343.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_1454.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_1479.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_1677.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_1694.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_1841.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2031.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2033.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2281.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2331.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2403.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2481.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2522.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2532.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2597.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2637.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2651.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2656.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2663-fix-could-not-create-temporary-drectory.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2666.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2682.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2684.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2687.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2689.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2694.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2758.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2764.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2767.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2771.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2783.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2799.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2803.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2804.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2811.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2813.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2823.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2834.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2835.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2862.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2886.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2899.prdoc (100%) diff --git a/Cargo.lock b/Cargo.lock index 7f2221240cc..849bc069d20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12065,7 +12065,7 @@ dependencies = [ [[package]] name = "polkadot" -version = "1.5.0" +version = "1.6.0" dependencies = [ "assert_cmd", "color-eyre", @@ -13038,7 +13038,7 @@ dependencies = [ [[package]] name = "polkadot-parachain-bin" -version = "1.5.0" +version = "1.6.0" dependencies = [ "assert_cmd", "asset-hub-rococo-runtime", diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 53b41892685..494ca3d1240 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -115,7 +115,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("statemine"), impl_name: create_runtime_str!("statemine"), authoring_version: 1, - spec_version: 1_005_001, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 14, @@ -128,7 +128,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("statemine"), impl_name: create_runtime_str!("statemine"), authoring_version: 1, - spec_version: 1_005_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 14, diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index cf10c0ac052..5950173d90e 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -113,7 +113,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("westmint"), impl_name: create_runtime_str!("westmint"), authoring_version: 1, - spec_version: 1_005_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 14, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 7e99b039309..09aeedfc223 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -201,7 +201,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("bridge-hub-rococo"), impl_name: create_runtime_str!("bridge-hub-rococo"), authoring_version: 1, - spec_version: 1_005_002, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 4, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index d920f5a98cf..55a38fc8543 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -175,7 +175,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("bridge-hub-westend"), impl_name: create_runtime_str!("bridge-hub-westend"), authoring_version: 1, - spec_version: 1_005_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 4, diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index a527f620137..3aff4671636 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -116,7 +116,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("collectives-westend"), impl_name: create_runtime_str!("collectives-westend"), authoring_version: 1, - spec_version: 1_005_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 5, diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index bc7d94889a1..707766ca226 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -133,7 +133,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("contracts-rococo"), impl_name: create_runtime_str!("contracts-rococo"), authoring_version: 1, - spec_version: 1_005_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 6, diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index 59ed8d7c603..bc6b6b3caf1 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -120,7 +120,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("coretime-westend"), impl_name: create_runtime_str!("coretime-westend"), authoring_version: 1, - spec_version: 1_005_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 0, diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs index 2c51791c074..15899e49195 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs @@ -99,7 +99,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("glutton-westend"), impl_name: create_runtime_str!("glutton-westend"), authoring_version: 1, - spec_version: 1_005_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index 00dd58e4a50..ba5b727484c 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -124,7 +124,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("people-rococo"), impl_name: create_runtime_str!("people-rococo"), authoring_version: 1, - spec_version: 1_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 0, diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index ee67c7419f1..4015d841b81 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -124,7 +124,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("people-westend"), impl_name: create_runtime_str!("people-westend"), authoring_version: 1, - spec_version: 1_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 0, diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs index 102127479d2..795efa39247 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs @@ -108,7 +108,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("test-parachain"), impl_name: create_runtime_str!("test-parachain"), authoring_version: 1, - spec_version: 1_005_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 6, diff --git a/cumulus/polkadot-parachain/Cargo.toml b/cumulus/polkadot-parachain/Cargo.toml index 9f42a265f39..84ba8a36d51 100644 --- a/cumulus/polkadot-parachain/Cargo.toml +++ b/cumulus/polkadot-parachain/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polkadot-parachain-bin" -version = "1.5.0" +version = "1.6.0" authors.workspace = true build = "build.rs" edition.workspace = true diff --git a/polkadot/Cargo.toml b/polkadot/Cargo.toml index d769957490e..8c8e9cebd41 100644 --- a/polkadot/Cargo.toml +++ b/polkadot/Cargo.toml @@ -18,7 +18,7 @@ rust-version = "1.64.0" readme = "README.md" authors.workspace = true edition.workspace = true -version = "1.5.0" +version = "1.6.0" default-run = "polkadot" [lints] diff --git a/polkadot/node/primitives/src/lib.rs b/polkadot/node/primitives/src/lib.rs index 6ac6b82c223..e7fd2c46381 100644 --- a/polkadot/node/primitives/src/lib.rs +++ b/polkadot/node/primitives/src/lib.rs @@ -58,7 +58,7 @@ pub use disputes::{ /// relatively rare. /// /// The associated worker binaries should use the same version as the node that spawns them. -pub const NODE_VERSION: &'static str = "1.5.0"; +pub const NODE_VERSION: &'static str = "1.6.0"; // For a 16-ary Merkle Prefix Trie, we can expect at most 16 32-byte hashes per node // plus some overhead: diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 92efdf0c0c5..28b82956a47 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -147,7 +147,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("westend"), impl_name: create_runtime_str!("parity-westend"), authoring_version: 2, - spec_version: 1_005_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 24, diff --git a/prdoc/pr_1191.prdoc b/prdoc/1.6.0/pr_1191.prdoc similarity index 100% rename from prdoc/pr_1191.prdoc rename to prdoc/1.6.0/pr_1191.prdoc diff --git a/prdoc/pr_1226.prdoc b/prdoc/1.6.0/pr_1226.prdoc similarity index 100% rename from prdoc/pr_1226.prdoc rename to prdoc/1.6.0/pr_1226.prdoc diff --git a/prdoc/pr_1289.prdoc b/prdoc/1.6.0/pr_1289.prdoc similarity index 100% rename from prdoc/pr_1289.prdoc rename to prdoc/1.6.0/pr_1289.prdoc diff --git a/prdoc/pr_1343.prdoc b/prdoc/1.6.0/pr_1343.prdoc similarity index 100% rename from prdoc/pr_1343.prdoc rename to prdoc/1.6.0/pr_1343.prdoc diff --git a/prdoc/pr_1454.prdoc b/prdoc/1.6.0/pr_1454.prdoc similarity index 100% rename from prdoc/pr_1454.prdoc rename to prdoc/1.6.0/pr_1454.prdoc diff --git a/prdoc/pr_1479.prdoc b/prdoc/1.6.0/pr_1479.prdoc similarity index 100% rename from prdoc/pr_1479.prdoc rename to prdoc/1.6.0/pr_1479.prdoc diff --git a/prdoc/pr_1677.prdoc b/prdoc/1.6.0/pr_1677.prdoc similarity index 100% rename from prdoc/pr_1677.prdoc rename to prdoc/1.6.0/pr_1677.prdoc diff --git a/prdoc/pr_1694.prdoc b/prdoc/1.6.0/pr_1694.prdoc similarity index 100% rename from prdoc/pr_1694.prdoc rename to prdoc/1.6.0/pr_1694.prdoc diff --git a/prdoc/pr_1841.prdoc b/prdoc/1.6.0/pr_1841.prdoc similarity index 100% rename from prdoc/pr_1841.prdoc rename to prdoc/1.6.0/pr_1841.prdoc diff --git a/prdoc/pr_2031.prdoc b/prdoc/1.6.0/pr_2031.prdoc similarity index 100% rename from prdoc/pr_2031.prdoc rename to prdoc/1.6.0/pr_2031.prdoc diff --git a/prdoc/pr_2033.prdoc b/prdoc/1.6.0/pr_2033.prdoc similarity index 100% rename from prdoc/pr_2033.prdoc rename to prdoc/1.6.0/pr_2033.prdoc diff --git a/prdoc/pr_2281.prdoc b/prdoc/1.6.0/pr_2281.prdoc similarity index 100% rename from prdoc/pr_2281.prdoc rename to prdoc/1.6.0/pr_2281.prdoc diff --git a/prdoc/pr_2331.prdoc b/prdoc/1.6.0/pr_2331.prdoc similarity index 100% rename from prdoc/pr_2331.prdoc rename to prdoc/1.6.0/pr_2331.prdoc diff --git a/prdoc/pr_2403.prdoc b/prdoc/1.6.0/pr_2403.prdoc similarity index 100% rename from prdoc/pr_2403.prdoc rename to prdoc/1.6.0/pr_2403.prdoc diff --git a/prdoc/pr_2481.prdoc b/prdoc/1.6.0/pr_2481.prdoc similarity index 100% rename from prdoc/pr_2481.prdoc rename to prdoc/1.6.0/pr_2481.prdoc diff --git a/prdoc/pr_2522.prdoc b/prdoc/1.6.0/pr_2522.prdoc similarity index 100% rename from prdoc/pr_2522.prdoc rename to prdoc/1.6.0/pr_2522.prdoc diff --git a/prdoc/pr_2532.prdoc b/prdoc/1.6.0/pr_2532.prdoc similarity index 100% rename from prdoc/pr_2532.prdoc rename to prdoc/1.6.0/pr_2532.prdoc diff --git a/prdoc/pr_2597.prdoc b/prdoc/1.6.0/pr_2597.prdoc similarity index 100% rename from prdoc/pr_2597.prdoc rename to prdoc/1.6.0/pr_2597.prdoc diff --git a/prdoc/pr_2637.prdoc b/prdoc/1.6.0/pr_2637.prdoc similarity index 100% rename from prdoc/pr_2637.prdoc rename to prdoc/1.6.0/pr_2637.prdoc diff --git a/prdoc/pr_2651.prdoc b/prdoc/1.6.0/pr_2651.prdoc similarity index 100% rename from prdoc/pr_2651.prdoc rename to prdoc/1.6.0/pr_2651.prdoc diff --git a/prdoc/pr_2656.prdoc b/prdoc/1.6.0/pr_2656.prdoc similarity index 100% rename from prdoc/pr_2656.prdoc rename to prdoc/1.6.0/pr_2656.prdoc diff --git a/prdoc/pr_2663-fix-could-not-create-temporary-drectory.prdoc b/prdoc/1.6.0/pr_2663-fix-could-not-create-temporary-drectory.prdoc similarity index 100% rename from prdoc/pr_2663-fix-could-not-create-temporary-drectory.prdoc rename to prdoc/1.6.0/pr_2663-fix-could-not-create-temporary-drectory.prdoc diff --git a/prdoc/pr_2666.prdoc b/prdoc/1.6.0/pr_2666.prdoc similarity index 100% rename from prdoc/pr_2666.prdoc rename to prdoc/1.6.0/pr_2666.prdoc diff --git a/prdoc/pr_2682.prdoc b/prdoc/1.6.0/pr_2682.prdoc similarity index 100% rename from prdoc/pr_2682.prdoc rename to prdoc/1.6.0/pr_2682.prdoc diff --git a/prdoc/pr_2684.prdoc b/prdoc/1.6.0/pr_2684.prdoc similarity index 100% rename from prdoc/pr_2684.prdoc rename to prdoc/1.6.0/pr_2684.prdoc diff --git a/prdoc/pr_2687.prdoc b/prdoc/1.6.0/pr_2687.prdoc similarity index 100% rename from prdoc/pr_2687.prdoc rename to prdoc/1.6.0/pr_2687.prdoc diff --git a/prdoc/pr_2689.prdoc b/prdoc/1.6.0/pr_2689.prdoc similarity index 100% rename from prdoc/pr_2689.prdoc rename to prdoc/1.6.0/pr_2689.prdoc diff --git a/prdoc/pr_2694.prdoc b/prdoc/1.6.0/pr_2694.prdoc similarity index 100% rename from prdoc/pr_2694.prdoc rename to prdoc/1.6.0/pr_2694.prdoc diff --git a/prdoc/pr_2758.prdoc b/prdoc/1.6.0/pr_2758.prdoc similarity index 100% rename from prdoc/pr_2758.prdoc rename to prdoc/1.6.0/pr_2758.prdoc diff --git a/prdoc/pr_2764.prdoc b/prdoc/1.6.0/pr_2764.prdoc similarity index 100% rename from prdoc/pr_2764.prdoc rename to prdoc/1.6.0/pr_2764.prdoc diff --git a/prdoc/pr_2767.prdoc b/prdoc/1.6.0/pr_2767.prdoc similarity index 100% rename from prdoc/pr_2767.prdoc rename to prdoc/1.6.0/pr_2767.prdoc diff --git a/prdoc/pr_2771.prdoc b/prdoc/1.6.0/pr_2771.prdoc similarity index 100% rename from prdoc/pr_2771.prdoc rename to prdoc/1.6.0/pr_2771.prdoc diff --git a/prdoc/pr_2783.prdoc b/prdoc/1.6.0/pr_2783.prdoc similarity index 100% rename from prdoc/pr_2783.prdoc rename to prdoc/1.6.0/pr_2783.prdoc diff --git a/prdoc/pr_2799.prdoc b/prdoc/1.6.0/pr_2799.prdoc similarity index 100% rename from prdoc/pr_2799.prdoc rename to prdoc/1.6.0/pr_2799.prdoc diff --git a/prdoc/pr_2803.prdoc b/prdoc/1.6.0/pr_2803.prdoc similarity index 100% rename from prdoc/pr_2803.prdoc rename to prdoc/1.6.0/pr_2803.prdoc diff --git a/prdoc/pr_2804.prdoc b/prdoc/1.6.0/pr_2804.prdoc similarity index 100% rename from prdoc/pr_2804.prdoc rename to prdoc/1.6.0/pr_2804.prdoc diff --git a/prdoc/pr_2811.prdoc b/prdoc/1.6.0/pr_2811.prdoc similarity index 100% rename from prdoc/pr_2811.prdoc rename to prdoc/1.6.0/pr_2811.prdoc diff --git a/prdoc/pr_2813.prdoc b/prdoc/1.6.0/pr_2813.prdoc similarity index 100% rename from prdoc/pr_2813.prdoc rename to prdoc/1.6.0/pr_2813.prdoc diff --git a/prdoc/pr_2823.prdoc b/prdoc/1.6.0/pr_2823.prdoc similarity index 100% rename from prdoc/pr_2823.prdoc rename to prdoc/1.6.0/pr_2823.prdoc diff --git a/prdoc/pr_2834.prdoc b/prdoc/1.6.0/pr_2834.prdoc similarity index 100% rename from prdoc/pr_2834.prdoc rename to prdoc/1.6.0/pr_2834.prdoc diff --git a/prdoc/pr_2835.prdoc b/prdoc/1.6.0/pr_2835.prdoc similarity index 100% rename from prdoc/pr_2835.prdoc rename to prdoc/1.6.0/pr_2835.prdoc diff --git a/prdoc/pr_2862.prdoc b/prdoc/1.6.0/pr_2862.prdoc similarity index 100% rename from prdoc/pr_2862.prdoc rename to prdoc/1.6.0/pr_2862.prdoc diff --git a/prdoc/pr_2886.prdoc b/prdoc/1.6.0/pr_2886.prdoc similarity index 100% rename from prdoc/pr_2886.prdoc rename to prdoc/1.6.0/pr_2886.prdoc diff --git a/prdoc/pr_2899.prdoc b/prdoc/1.6.0/pr_2899.prdoc similarity index 100% rename from prdoc/pr_2899.prdoc rename to prdoc/1.6.0/pr_2899.prdoc -- GitLab From f574868822d5976219d391de5acd66bb773e4964 Mon Sep 17 00:00:00 2001 From: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Date: Thu, 18 Jan 2024 07:46:08 +0100 Subject: [PATCH 069/392] Rococo Identity Migration Part 2 + Bug Fix (#2946) Order: - [x] Start People Chain - [RPC node](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frococo-people-rpc.polkadot.io#/explorer) - [x] Upgrade Rococo Relay (`EnsureRoot` -> `EnsureSigned`) (v1,006,002) - Done [here](https://rococo.subscan.io/extrinsic/0xef07e0f9dbb2b9e829305f132e6ce45d291239286e409177e20895e6687daa6c) - [x] Migrate all identities - Done, see extrinsics from [this account](https://rococo.subscan.io/account/5FyNYrBwndvBttTkGUqGGCRAXtBH4Mh8xELDaxaFywTsjDKb) - [x] Upgrade Rococo People (remove call filter) (v1,006,002) - Authorized [here](https://rococo.subscan.io/extrinsic/0xedf6a80229bd411b7ed8d3a489a767b0f773bed5c49239987a294c293a35b98b) With added: - [x] Upgrade Rococo People to fix `poke_deposit` bug (v1,006,001) - Authorized [here](https://rococo.subscan.io/extrinsic/0xd1dc3cd6e8274bd0196f8d9f13ed09f6e9c76e6a40f9786a1629f4cb22cf948d) Note: It's also possible to remove the Identity Migrator pallet from both the Relay Chain and the parachain at this time. I will leave them in for now to preserve the test cases until we run them on Kusama/Polkadot. We will also want a follow up to remove all Identity-related state from the Relay Chain. --- .../people-rococo/src/tests/reap_identity.rs | 2 +- .../runtimes/people/people-rococo/src/lib.rs | 14 ++--- .../people/people-rococo/src/xcm_config.rs | 18 ++++--- .../people/people-westend/src/xcm_config.rs | 18 ++++--- polkadot/runtime/rococo/src/lib.rs | 7 ++- substrate/frame/identity/src/lib.rs | 25 +++++---- substrate/frame/identity/src/tests.rs | 51 +++++++++++++++++++ 7 files changed, 95 insertions(+), 40 deletions(-) diff --git a/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/reap_identity.rs b/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/reap_identity.rs index 2902f359dfb..58bb9504dbd 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/reap_identity.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/reap_identity.rs @@ -291,7 +291,7 @@ fn assert_reap_id_relay(total_deposit: Balance, id: &Identity) { assert_eq!(reserved_balance, total_deposit); assert_ok!(RococoIdentityMigrator::reap_identity( - RococoOrigin::root(), + RococoOrigin::signed(RococoRelaySender::get()), RococoRelaySender::get() )); diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index ba5b727484c..21c24086cbe 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -30,8 +30,7 @@ use frame_support::{ genesis_builder_helper::{build_config, create_default_config}, parameter_types, traits::{ - ConstBool, ConstU32, ConstU64, ConstU8, Contains, EitherOfDiverse, EverythingBut, - TransformOrigin, + ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Everything, TransformOrigin, }, weights::{ConstantMultiplier, Weight}, PalletId, @@ -124,7 +123,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("people-rococo"), impl_name: create_runtime_str!("people-rococo"), authoring_version: 1, - spec_version: 1_006_000, + spec_version: 1_006_002, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 0, @@ -162,16 +161,9 @@ parameter_types! { pub const SS58Prefix: u8 = 42; } -pub struct IdentityCalls; -impl Contains for IdentityCalls { - fn contains(c: &RuntimeCall) -> bool { - matches!(c, RuntimeCall::Identity(_)) - } -} - #[derive_impl(frame_system::config_preludes::ParaChainDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Runtime { - type BaseCallFilter = EverythingBut; + type BaseCallFilter = Everything; type BlockWeights = RuntimeBlockWeights; type BlockLength = RuntimeBlockLength; type AccountId = AccountId; diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs index 7ef6cb2fac9..168d7eaa605 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs @@ -176,13 +176,17 @@ impl Contains for SafeCallFilter { matches!( call, - RuntimeCall::PolkadotXcm(pallet_xcm::Call::force_xcm_version { .. }) | - RuntimeCall::System( - frame_system::Call::set_heap_pages { .. } | - frame_system::Call::set_code { .. } | - frame_system::Call::set_code_without_checks { .. } | - frame_system::Call::kill_prefix { .. }, - ) | RuntimeCall::ParachainSystem(..) | + RuntimeCall::PolkadotXcm( + pallet_xcm::Call::force_xcm_version { .. } | + pallet_xcm::Call::force_default_xcm_version { .. } + ) | RuntimeCall::System( + frame_system::Call::set_heap_pages { .. } | + frame_system::Call::set_code { .. } | + frame_system::Call::set_code_without_checks { .. } | + frame_system::Call::authorize_upgrade { .. } | + frame_system::Call::authorize_upgrade_without_checks { .. } | + frame_system::Call::kill_prefix { .. }, + ) | RuntimeCall::ParachainSystem(..) | RuntimeCall::Timestamp(..) | RuntimeCall::Balances(..) | RuntimeCall::CollatorSelection( diff --git a/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs index 59c00dc5ff6..18c03a968ef 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs @@ -183,13 +183,17 @@ impl Contains for SafeCallFilter { matches!( call, - RuntimeCall::PolkadotXcm(pallet_xcm::Call::force_xcm_version { .. }) | - RuntimeCall::System( - frame_system::Call::set_heap_pages { .. } | - frame_system::Call::set_code { .. } | - frame_system::Call::set_code_without_checks { .. } | - frame_system::Call::kill_prefix { .. }, - ) | RuntimeCall::ParachainSystem(..) | + RuntimeCall::PolkadotXcm( + pallet_xcm::Call::force_xcm_version { .. } | + pallet_xcm::Call::force_default_xcm_version { .. } + ) | RuntimeCall::System( + frame_system::Call::set_heap_pages { .. } | + frame_system::Call::set_code { .. } | + frame_system::Call::set_code_without_checks { .. } | + frame_system::Call::authorize_upgrade { .. } | + frame_system::Call::authorize_upgrade_without_checks { .. } | + frame_system::Call::kill_prefix { .. }, + ) | RuntimeCall::ParachainSystem(..) | RuntimeCall::Timestamp(..) | RuntimeCall::Balances(..) | RuntimeCall::CollatorSelection( diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index fec82fc86f9..0e2eaa03567 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -79,7 +79,7 @@ use frame_support::{ weights::{ConstantMultiplier, WeightMeter}, PalletId, }; -use frame_system::EnsureRoot; +use frame_system::{EnsureRoot, EnsureSigned}; use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId}; use pallet_identity::legacy::IdentityInfo; use pallet_session::historical as session_historical; @@ -150,7 +150,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("rococo"), impl_name: create_runtime_str!("parity-rococo-v2.0"), authoring_version: 0, - spec_version: 1_006_001, + spec_version: 1_006_002, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 24, @@ -1142,8 +1142,7 @@ impl auctions::Config for Runtime { impl identity_migrator::Config for Runtime { type RuntimeEvent = RuntimeEvent; - // To be changed to `EnsureSigned` once there is a People Chain to migrate to. - type Reaper = EnsureRoot; + type Reaper = EnsureSigned; type ReapIdentityHandler = ToParachainIdentityReaper; type WeightInfo = weights::runtime_common_identity_migrator::WeightInfo; } diff --git a/substrate/frame/identity/src/lib.rs b/substrate/frame/identity/src/lib.rs index 1df0a619ea4..78d59180b3f 100644 --- a/substrate/frame/identity/src/lib.rs +++ b/substrate/frame/identity/src/lib.rs @@ -1395,16 +1395,21 @@ impl Pallet { }, )?; - // Subs Deposit - let new_subs_deposit = SubsOf::::try_mutate( - &target, - |(current_subs_deposit, subs_of)| -> Result, DispatchError> { - let new_subs_deposit = Self::subs_deposit(subs_of.len() as u32); - Self::rejig_deposit(&target, *current_subs_deposit, new_subs_deposit)?; - *current_subs_deposit = new_subs_deposit; - Ok(new_subs_deposit) - }, - )?; + let new_subs_deposit = if SubsOf::::contains_key(&target) { + SubsOf::::try_mutate( + &target, + |(current_subs_deposit, subs_of)| -> Result, DispatchError> { + let new_subs_deposit = Self::subs_deposit(subs_of.len() as u32); + Self::rejig_deposit(&target, *current_subs_deposit, new_subs_deposit)?; + *current_subs_deposit = new_subs_deposit; + Ok(new_subs_deposit) + }, + )? + } else { + // If the item doesn't exist, there is no "old" deposit, and the new one is zero, so no + // need to call rejig, it'd just be zero -> zero. + Zero::zero() + }; Ok((new_id_deposit, new_subs_deposit)) } diff --git a/substrate/frame/identity/src/tests.rs b/substrate/frame/identity/src/tests.rs index 4da31782261..e6107cda0f0 100644 --- a/substrate/frame/identity/src/tests.rs +++ b/substrate/frame/identity/src/tests.rs @@ -952,6 +952,57 @@ fn poke_deposit_works() { }); } +#[test] +fn poke_deposit_does_not_insert_new_subs_storage() { + new_test_ext().execute_with(|| { + let [_, _, _, _, ten, _, _, _] = accounts(); + let ten_info = infoof_ten(); + // Set a custom registration with 0 deposit + IdentityOf::::insert::< + _, + ( + Registration>, + Option>, + ), + >( + &ten, + ( + Registration { + judgements: Default::default(), + deposit: Zero::zero(), + info: ten_info.clone(), + }, + None::>, + ), + ); + assert!(Identity::identity(ten.clone()).is_some()); + + // Balance is free + assert_eq!(Balances::free_balance(ten.clone()), 1000); + + // poke + assert_ok!(Identity::poke_deposit(&ten)); + + // free balance reduced correctly + let id_deposit = id_deposit(&ten_info); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit); + // new registration deposit is 10 + assert_eq!( + Identity::identity(&ten), + Some(( + Registration { + judgements: Default::default(), + deposit: id_deposit, + info: infoof_ten() + }, + None + )) + ); + // No new subs storage item. + assert!(!SubsOf::::contains_key(&ten)); + }); +} + #[test] fn adding_and_removing_authorities_should_work() { new_test_ext().execute_with(|| { -- GitLab From f8954093b4226512ea63cb59aae1f6890aeffe76 Mon Sep 17 00:00:00 2001 From: Tsvetomir Dimitrov Date: Thu, 18 Jan 2024 09:33:58 +0200 Subject: [PATCH 070/392] Filter votes from disabled validators in `BackedCandidates` in process_inherent_data (#2889) Backport of https://github.com/paritytech/polkadot-sdk/pull/1863 to master Extend candidate sanitation in paras_inherent by removing backing votes from disabled validators. Check https://github.com/paritytech/polkadot-sdk/issues/1592 for more details. This change is related to the disabling strategy implementation (https://github.com/paritytech/polkadot-sdk/pull/2226). --------- Co-authored-by: ordian Co-authored-by: ordian Co-authored-by: Maciej --- .../src/runtime/parainherent.md | 32 +++ .../runtime/common/src/assigned_slots/mod.rs | 4 +- .../runtime/common/src/integration_tests.rs | 4 +- .../runtime/common/src/paras_registrar/mod.rs | 4 +- polkadot/runtime/parachains/src/mock.rs | 27 ++- .../parachains/src/paras_inherent/mod.rs | 181 ++++++++++++++-- .../parachains/src/paras_inherent/tests.rs | 199 ++++++++++++++++-- .../src/runtime_api_impl/vstaging.rs | 19 +- polkadot/runtime/parachains/src/scheduler.rs | 5 + polkadot/runtime/parachains/src/shared.rs | 42 +++- polkadot/runtime/rococo/src/lib.rs | 4 +- polkadot/runtime/test-runtime/src/lib.rs | 4 +- polkadot/runtime/westend/src/lib.rs | 4 +- polkadot/xcm/xcm-builder/tests/mock/mod.rs | 4 +- .../xcm-simulator/example/src/relay_chain.rs | 4 +- .../xcm-simulator/fuzzer/src/relay_chain.rs | 4 +- prdoc/pr_2889.prdoc | 10 + substrate/frame/aura/src/mock.rs | 4 + .../contracts/mock-network/src/relay_chain.rs | 4 +- substrate/frame/session/src/lib.rs | 4 + .../frame/support/src/traits/validation.rs | 7 + 21 files changed, 506 insertions(+), 64 deletions(-) create mode 100644 prdoc/pr_2889.prdoc diff --git a/polkadot/roadmap/implementers-guide/src/runtime/parainherent.md b/polkadot/roadmap/implementers-guide/src/runtime/parainherent.md index 4a771f1df64..5419ddae83d 100644 --- a/polkadot/roadmap/implementers-guide/src/runtime/parainherent.md +++ b/polkadot/roadmap/implementers-guide/src/runtime/parainherent.md @@ -60,3 +60,35 @@ processing it, so the processed inherent data is simply dropped. This also means that the `enter` function keeps data around for no good reason. This seems acceptable though as the size of a block is rather limited. Nevertheless if we ever wanted to optimize this we can easily implement an inherent collector that has two implementations, where one clones and stores the data and the other just passes it on. + +## Sanitization + +`ParasInherent` with the entry point of `create_inherent` sanitizes the input data, while the `enter` entry point +enforces already sanitized input data. If unsanitized data is provided the module generates an error. + +Disputes are included in the block with a priority for a security reasons. It's important to include as many dispute +votes onchain as possible so that disputes conclude faster and the offenders are punished. However if there are too many +disputes to include in a block the dispute set is trimmed so that it respects max block weight. + +Dispute data is first deduplicated and sorted by block number (older first) and dispute location (local then remote). +Concluded and ancient (disputes initiated before the post conclusion acceptance period) disputes are filtered out. +Votes with invalid signatures or from unknown validators (not found in the active set for the current session) are also +filtered out. + +All dispute statements are included in the order described in the previous paragraph until the available block weight is +exhausted. After the dispute data is included all remaining weight is filled in with candidates and availability +bitfields. Bitfields are included with priority, then candidates containing code updates and finally any backed +candidates. If there is not enough weight for all backed candidates they are trimmed by random selection. Disputes are +processed in three separate functions - `deduplicate_and_sort_dispute_data`, `filter_dispute_data` and +`limit_and_sanitize_disputes`. + +Availability bitfields are also sanitized by dropping malformed ones, containing disputed cores or bad signatures. Refer +to `sanitize_bitfields` function for implementation details. + +Backed candidates sanitization removes malformed ones, candidates which have got concluded invalid disputes against them +or candidates produced by unassigned cores. Furthermore any backing votes from disabled validators for a candidate are +dropped. This is part of the validator disabling strategy. After filtering the statements from disabled validators a +backed candidate may end up with votes count less than `minimum_backing_votes` (a parameter from `HostConfiguiration`). +In this case the whole candidate is dropped otherwise it will be rejected by `process_candidates` from pallet inclusion. +All checks related to backed candidates are implemented in `sanitize_backed_candidates` and +`filter_backed_statements_from_disabled_validators`. diff --git a/polkadot/runtime/common/src/assigned_slots/mod.rs b/polkadot/runtime/common/src/assigned_slots/mod.rs index cb56cb8a118..de8c00df9dd 100644 --- a/polkadot/runtime/common/src/assigned_slots/mod.rs +++ b/polkadot/runtime/common/src/assigned_slots/mod.rs @@ -746,7 +746,9 @@ mod tests { type AssignCoretime = (); } - impl parachains_shared::Config for Test {} + impl parachains_shared::Config for Test { + type DisabledValidators = (); + } parameter_types! { pub const LeasePeriod: BlockNumber = 3; diff --git a/polkadot/runtime/common/src/integration_tests.rs b/polkadot/runtime/common/src/integration_tests.rs index cfa8f4c3ad9..b536b80e245 100644 --- a/polkadot/runtime/common/src/integration_tests.rs +++ b/polkadot/runtime/common/src/integration_tests.rs @@ -197,7 +197,9 @@ impl configuration::Config for Test { type WeightInfo = configuration::TestWeightInfo; } -impl shared::Config for Test {} +impl shared::Config for Test { + type DisabledValidators = (); +} impl origin::Config for Test {} diff --git a/polkadot/runtime/common/src/paras_registrar/mod.rs b/polkadot/runtime/common/src/paras_registrar/mod.rs index 9719f02677d..448490b34a7 100644 --- a/polkadot/runtime/common/src/paras_registrar/mod.rs +++ b/polkadot/runtime/common/src/paras_registrar/mod.rs @@ -799,7 +799,9 @@ mod tests { type MaxFreezes = ConstU32<1>; } - impl shared::Config for Test {} + impl shared::Config for Test { + type DisabledValidators = (); + } impl origin::Config for Test {} diff --git a/polkadot/runtime/parachains/src/mock.rs b/polkadot/runtime/parachains/src/mock.rs index c08bab0ef0f..e3fcf7dd603 100644 --- a/polkadot/runtime/parachains/src/mock.rs +++ b/polkadot/runtime/parachains/src/mock.rs @@ -194,7 +194,22 @@ impl crate::configuration::Config for Test { type WeightInfo = crate::configuration::TestWeightInfo; } -impl crate::shared::Config for Test {} +pub struct MockDisabledValidators {} +impl frame_support::traits::DisabledValidators for MockDisabledValidators { + /// Returns true if the given validator is disabled. + fn is_disabled(index: u32) -> bool { + disabled_validators().iter().any(|v| *v == index) + } + + /// Returns a hardcoded list (`DISABLED_VALIDATORS`) of disabled validators + fn disabled_validators() -> Vec { + disabled_validators() + } +} + +impl crate::shared::Config for Test { + type DisabledValidators = MockDisabledValidators; +} impl origin::Config for Test {} @@ -564,6 +579,8 @@ thread_local! { pub static AVAILABILITY_REWARDS: RefCell> = RefCell::new(HashMap::new()); + + pub static DISABLED_VALIDATORS: RefCell> = RefCell::new(vec![]); } pub fn backing_rewards() -> HashMap { @@ -574,6 +591,10 @@ pub fn availability_rewards() -> HashMap { AVAILABILITY_REWARDS.with(|r| r.borrow().clone()) } +pub fn disabled_validators() -> Vec { + DISABLED_VALIDATORS.with(|r| r.borrow().clone()) +} + parameter_types! { pub static Processed: Vec<(ParaId, UpwardMessage)> = vec![]; } @@ -713,3 +734,7 @@ pub(crate) fn deregister_parachain(id: ParaId) { pub(crate) fn try_deregister_parachain(id: ParaId) -> crate::DispatchResult { frame_support::storage::transactional::with_storage_layer(|| Paras::schedule_para_cleanup(id)) } + +pub(crate) fn set_disabled_validators(disabled: Vec) { + DISABLED_VALIDATORS.with(|d| *d.borrow_mut() = disabled) +} diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 8c33199c092..81e092f0a99 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -30,7 +30,8 @@ use crate::{ metrics::METRICS, paras, scheduler::{self, FreedReason}, - shared, ParaId, + shared::{self, AllowedRelayParentsTracker}, + ParaId, }; use bitvec::prelude::BitVec; use frame_support::{ @@ -42,8 +43,8 @@ use frame_support::{ use frame_system::pallet_prelude::*; use pallet_babe::{self, ParentBlockRandomness}; use primitives::{ - BackedCandidate, CandidateHash, CandidateReceipt, CheckedDisputeStatementSet, - CheckedMultiDisputeStatementSet, CoreIndex, DisputeStatementSet, + effective_minimum_backing_votes, BackedCandidate, CandidateHash, CandidateReceipt, + CheckedDisputeStatementSet, CheckedMultiDisputeStatementSet, CoreIndex, DisputeStatementSet, InherentData as ParachainsInherentData, MultiDisputeStatementSet, ScrapedOnChainVotes, SessionIndex, SignedAvailabilityBitfields, SigningContext, UncheckedSignedAvailabilityBitfield, UncheckedSignedAvailabilityBitfields, ValidatorId, ValidatorIndex, ValidityAttestation, @@ -142,6 +143,8 @@ pub mod pallet { DisputeStatementsUnsortedOrDuplicates, /// A dispute statement was invalid. DisputeInvalid, + /// A candidate was backed by a disabled validator + BackedByDisabled, } /// Whether the paras inherent was included within this block. @@ -378,6 +381,7 @@ impl Pallet { let bitfields_weight = signed_bitfields_weight::(&bitfields); let disputes_weight = multi_dispute_statement_sets_weight::(&disputes); + // Weight before filtering/sanitization let all_weight_before = candidates_weight + bitfields_weight + disputes_weight; METRICS.on_before_filter(all_weight_before.ref_time()); @@ -587,17 +591,19 @@ impl Pallet { METRICS.on_candidates_processed_total(backed_candidates.len() as u64); - let backed_candidates = sanitize_backed_candidates::( - backed_candidates, - |candidate_idx: usize, - backed_candidate: &BackedCandidate<::Hash>| - -> bool { - let para_id = backed_candidate.descriptor().para_id; - let prev_context = >::para_most_recent_context(para_id); - let check_ctx = CandidateCheckContext::::new(prev_context); - - // never include a concluded-invalid candidate - current_concluded_invalid_disputes.contains(&backed_candidate.hash()) || + let SanitizedBackedCandidates { backed_candidates, votes_from_disabled_were_dropped } = + sanitize_backed_candidates::( + backed_candidates, + &allowed_relay_parents, + |candidate_idx: usize, + backed_candidate: &BackedCandidate<::Hash>| + -> bool { + let para_id = backed_candidate.descriptor().para_id; + let prev_context = >::para_most_recent_context(para_id); + let check_ctx = CandidateCheckContext::::new(prev_context); + + // never include a concluded-invalid candidate + current_concluded_invalid_disputes.contains(&backed_candidate.hash()) || // Instead of checking the candidates with code upgrades twice // move the checking up here and skip it in the training wheels fallback. // That way we avoid possible duplicate checks while assuring all @@ -607,12 +613,19 @@ impl Pallet { check_ctx .verify_backed_candidate(&allowed_relay_parents, candidate_idx, backed_candidate) .is_err() - }, - &scheduled, - ); + }, + &scheduled, + ); METRICS.on_candidates_sanitized(backed_candidates.len() as u64); + // In `Enter` context (invoked during execution) there should be no backing votes from + // disabled validators because they should have been filtered out during inherent data + // preparation (`ProvideInherent` context). Abort in such cases. + if context == ProcessInherentDataContext::Enter { + ensure!(!votes_from_disabled_were_dropped, Error::::BackedByDisabled); + } + // Process backed candidates according to scheduled cores. let inclusion::ProcessedCandidates::< as HeaderT>::Hash> { core_indices: occupied, @@ -900,7 +913,19 @@ pub(crate) fn sanitize_bitfields( bitfields } -/// Filter out any candidates that have a concluded invalid dispute. +// Result from `sanitize_backed_candidates` +#[derive(Debug, PartialEq)] +struct SanitizedBackedCandidates { + // Sanitized backed candidates. The `Vec` is sorted according to the occupied core index. + backed_candidates: Vec>, + // Set to true if any votes from disabled validators were dropped from the input. + votes_from_disabled_were_dropped: bool, +} + +/// Filter out: +/// 1. any candidates that have a concluded invalid dispute +/// 2. all backing votes from disabled validators +/// 3. any candidates that end up with less than `effective_minimum_backing_votes` backing votes /// /// `scheduled` follows the same naming scheme as provided in the /// guide: Currently `free` but might become `occupied`. @@ -910,15 +935,17 @@ pub(crate) fn sanitize_bitfields( /// `candidate_has_concluded_invalid_dispute` must return `true` if the candidate /// is disputed, false otherwise. The passed `usize` is the candidate index. /// -/// The returned `Vec` is sorted according to the occupied core index. +/// Returns struct `SanitizedBackedCandidates` where `backed_candidates` are sorted according to the +/// occupied core index. fn sanitize_backed_candidates< T: crate::inclusion::Config, F: FnMut(usize, &BackedCandidate) -> bool, >( mut backed_candidates: Vec>, + allowed_relay_parents: &AllowedRelayParentsTracker>, mut candidate_has_concluded_invalid_dispute_or_is_invalid: F, scheduled: &BTreeMap, -) -> Vec> { +) -> SanitizedBackedCandidates { // Remove any candidates that were concluded invalid. // This does not assume sorting. backed_candidates.indexed_retain(move |candidate_idx, backed_candidate| { @@ -936,6 +963,13 @@ fn sanitize_backed_candidates< scheduled.get(&desc.para_id).is_some() }); + // Filter out backing statements from disabled validators + let dropped_disabled = filter_backed_statements_from_disabled_validators::( + &mut backed_candidates, + &allowed_relay_parents, + scheduled, + ); + // Sort the `Vec` last, once there is a guarantee that these // `BackedCandidates` references the expected relay chain parent, // but more importantly are scheduled for a free core. @@ -946,7 +980,10 @@ fn sanitize_backed_candidates< scheduled[&x.descriptor().para_id].cmp(&scheduled[&y.descriptor().para_id]) }); - backed_candidates + SanitizedBackedCandidates { + backed_candidates, + votes_from_disabled_were_dropped: dropped_disabled, + } } /// Derive entropy from babe provided per block randomness. @@ -1029,3 +1066,105 @@ fn limit_and_sanitize_disputes< (checked, checked_disputes_weight) } } + +// Filters statements from disabled validators in `BackedCandidate`, non-scheduled candidates and +// few more sanity checks. Returns `true` if at least one statement is removed and `false` +// otherwise. +fn filter_backed_statements_from_disabled_validators( + backed_candidates: &mut Vec::Hash>>, + allowed_relay_parents: &AllowedRelayParentsTracker>, + scheduled: &BTreeMap, +) -> bool { + let disabled_validators = + BTreeSet::<_>::from_iter(shared::Pallet::::disabled_validators().into_iter()); + + if disabled_validators.is_empty() { + // No disabled validators - nothing to do + return false + } + + let backed_len_before = backed_candidates.len(); + + // Flag which will be returned. Set to `true` if at least one vote is filtered. + let mut filtered = false; + + let minimum_backing_votes = configuration::Pallet::::config().minimum_backing_votes; + + // Process all backed candidates. `validator_indices` in `BackedCandidates` are indices within + // the validator group assigned to the parachain. To obtain this group we need: + // 1. Core index assigned to the parachain which has produced the candidate + // 2. The relay chain block number of the candidate + backed_candidates.retain_mut(|bc| { + // Get `core_idx` assigned to the `para_id` of the candidate + let core_idx = match scheduled.get(&bc.descriptor().para_id) { + Some(core_idx) => *core_idx, + None => { + log::debug!(target: LOG_TARGET, "Can't get core idx of a backed candidate for para id {:?}. Dropping the candidate.", bc.descriptor().para_id); + return false + } + }; + + // Get relay parent block number of the candidate. We need this to get the group index assigned to this core at this block number + let relay_parent_block_number = match allowed_relay_parents + .acquire_info(bc.descriptor().relay_parent, None) { + Some((_, block_num)) => block_num, + None => { + log::debug!(target: LOG_TARGET, "Relay parent {:?} for candidate is not in the allowed relay parents. Dropping the candidate.", bc.descriptor().relay_parent); + return false + } + }; + + // Get the group index for the core + let group_idx = match >::group_assigned_to_core( + core_idx, + relay_parent_block_number + One::one(), + ) { + Some(group_idx) => group_idx, + None => { + log::debug!(target: LOG_TARGET, "Can't get the group index for core idx {:?}. Dropping the candidate.", core_idx); + return false + }, + }; + + // And finally get the validator group for this group index + let validator_group = match >::group_validators(group_idx) { + Some(validator_group) => validator_group, + None => { + log::debug!(target: LOG_TARGET, "Can't get the validators from group {:?}. Dropping the candidate.", group_idx); + return false + } + }; + + // Bitmask with the disabled indices within the validator group + let disabled_indices = BitVec::::from_iter(validator_group.iter().map(|idx| disabled_validators.contains(idx))); + // The indices of statements from disabled validators in `BackedCandidate`. We have to drop these. + let indices_to_drop = disabled_indices.clone() & &bc.validator_indices; + // Apply the bitmask to drop the disabled validator from `validator_indices` + bc.validator_indices &= !disabled_indices; + // Remove the corresponding votes from `validity_votes` + for idx in indices_to_drop.iter_ones().rev() { + bc.validity_votes.remove(idx); + } + + // If at least one statement was dropped we need to return `true` + if indices_to_drop.count_ones() > 0 { + filtered = true; + } + + // By filtering votes we might render the candidate invalid and cause a failure in + // [`process_candidates`]. To avoid this we have to perform a sanity check here. If there + // are not enough backing votes after filtering we will remove the whole candidate. + if bc.validity_votes.len() < effective_minimum_backing_votes( + validator_group.len(), + minimum_backing_votes + + ) { + return false + } + + true + }); + + // Also return `true` if a whole candidate was dropped from the set + filtered || backed_len_before != backed_candidates.len() +} diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index e62d1cb68ff..6f3eac35685 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -1227,6 +1227,12 @@ mod sanitizers { } mod candidates { + use crate::{ + mock::set_disabled_validators, + scheduler::{common::Assignment, ParasEntry}, + }; + use sp_std::collections::vec_deque::VecDeque; + use super::*; // Backed candidates and scheduled parachains used for `sanitize_backed_candidates` testing @@ -1235,10 +1241,20 @@ mod sanitizers { scheduled_paras: BTreeMap, } - // Generate test data for the candidates test + // Generate test data for the candidates and assert that the evnironment is set as expected + // (check the comments for details) fn get_test_data() -> TestData { const RELAY_PARENT_NUM: u32 = 3; + // Add the relay parent to `shared` pallet. Otherwise some code (e.g. filtering backing + // votes) won't behave correctly + shared::Pallet::::add_allowed_relay_parent( + default_header().hash(), + Default::default(), + RELAY_PARENT_NUM, + 1, + ); + let header = default_header(); let relay_parent = header.hash(); let session_index = SessionIndex::from(0_u32); @@ -1252,6 +1268,7 @@ mod sanitizers { keyring::Sr25519Keyring::Bob, keyring::Sr25519Keyring::Charlie, keyring::Sr25519Keyring::Dave, + keyring::Sr25519Keyring::Eve, ]; for validator in validators.iter() { Keystore::sr25519_generate_new( @@ -1262,11 +1279,42 @@ mod sanitizers { .unwrap(); } + // Set active validators in `shared` pallet + let validator_ids = + validators.iter().map(|v| v.public().into()).collect::>(); + shared::Pallet::::set_active_validators_ascending(validator_ids); + + // Two scheduled parachains - ParaId(1) on CoreIndex(0) and ParaId(2) on CoreIndex(1) let scheduled = (0_usize..2) .into_iter() .map(|idx| (ParaId::from(1_u32 + idx as u32), CoreIndex::from(idx as u32))) .collect::>(); + // Set the validator groups in `scheduler` + scheduler::Pallet::::set_validator_groups(vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2), ValidatorIndex(3)], + ]); + + // Update scheduler's claimqueue with the parachains + scheduler::Pallet::::set_claimqueue(BTreeMap::from([ + ( + CoreIndex::from(0), + VecDeque::from([ParasEntry::new( + Assignment::Pool { para_id: 1.into(), core_index: CoreIndex(1) }, + RELAY_PARENT_NUM, + )]), + ), + ( + CoreIndex::from(1), + VecDeque::from([ParasEntry::new( + Assignment::Pool { para_id: 2.into(), core_index: CoreIndex(1) }, + RELAY_PARENT_NUM, + )]), + ), + ])); + + // Callback used for backing candidates let group_validators = |group_index: GroupIndex| { match group_index { group_index if group_index == GroupIndex::from(0) => Some(vec![0, 1]), @@ -1276,6 +1324,7 @@ mod sanitizers { .map(|m| m.into_iter().map(ValidatorIndex).collect::>()) }; + // Two backed candidates from each parachain let backed_candidates = (0_usize..2) .into_iter() .map(|idx0| { @@ -1304,6 +1353,22 @@ mod sanitizers { }) .collect::>(); + // State sanity checks + assert_eq!( + >::scheduled_paras().collect::>(), + vec![(CoreIndex(0), ParaId::from(1)), (CoreIndex(1), ParaId::from(2))] + ); + assert_eq!( + shared::Pallet::::active_validator_indices(), + vec![ + ValidatorIndex(0), + ValidatorIndex(1), + ValidatorIndex(2), + ValidatorIndex(3), + ValidatorIndex(4) + ] + ); + TestData { backed_candidates, scheduled_paras: scheduled } } @@ -1318,10 +1383,14 @@ mod sanitizers { assert_eq!( sanitize_backed_candidates::( backed_candidates.clone(), + &>::allowed_relay_parents(), has_concluded_invalid, &scheduled ), - backed_candidates + SanitizedBackedCandidates { + backed_candidates, + votes_from_disabled_were_dropped: false + } ); {} @@ -1337,12 +1406,18 @@ mod sanitizers { let has_concluded_invalid = |_idx: usize, _backed_candidate: &BackedCandidate| -> bool { false }; - assert!(sanitize_backed_candidates::( + let SanitizedBackedCandidates { + backed_candidates: sanitized_backed_candidates, + votes_from_disabled_were_dropped, + } = sanitize_backed_candidates::( backed_candidates.clone(), + &>::allowed_relay_parents(), has_concluded_invalid, - &scheduled - ) - .is_empty()); + &scheduled, + ); + + assert!(sanitized_backed_candidates.is_empty()); + assert!(!votes_from_disabled_were_dropped); }); } @@ -1364,15 +1439,113 @@ mod sanitizers { }; let has_concluded_invalid = |_idx: usize, candidate: &BackedCandidate| set.contains(&candidate.hash()); + let SanitizedBackedCandidates { + backed_candidates: sanitized_backed_candidates, + votes_from_disabled_were_dropped, + } = sanitize_backed_candidates::( + backed_candidates.clone(), + &>::allowed_relay_parents(), + has_concluded_invalid, + &scheduled, + ); + + assert_eq!(sanitized_backed_candidates.len(), backed_candidates.len() / 2); + assert!(!votes_from_disabled_were_dropped); + }); + } + + #[test] + fn disabled_non_signing_validator_doesnt_get_filtered() { + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + let TestData { mut backed_candidates, scheduled_paras } = get_test_data(); + + // Disable Eve + set_disabled_validators(vec![4]); + + let before = backed_candidates.clone(); + + // Eve is disabled but no backing statement is signed by it so nothing should be + // filtered + assert!(!filter_backed_statements_from_disabled_validators::( + &mut backed_candidates, + &>::allowed_relay_parents(), + &scheduled_paras + )); + assert_eq!(backed_candidates, before); + }); + } + + #[test] + fn drop_statements_from_disabled_without_dropping_candidate() { + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + let TestData { mut backed_candidates, scheduled_paras } = get_test_data(); + + // Disable Alice + set_disabled_validators(vec![0]); + + // Update `minimum_backing_votes` in HostConfig. We want `minimum_backing_votes` set + // to one so that the candidate will have enough backing votes even after dropping + // Alice's one. + let mut hc = configuration::Pallet::::config(); + hc.minimum_backing_votes = 1; + configuration::Pallet::::force_set_active_config(hc); + + // Verify the initial state is as expected + assert_eq!(backed_candidates.get(0).unwrap().validity_votes.len(), 2); assert_eq!( - sanitize_backed_candidates::( - backed_candidates.clone(), - has_concluded_invalid, - &scheduled - ) - .len(), - backed_candidates.len() / 2 + backed_candidates.get(0).unwrap().validator_indices.get(0).unwrap(), + true + ); + assert_eq!( + backed_candidates.get(0).unwrap().validator_indices.get(1).unwrap(), + true + ); + let untouched = backed_candidates.get(1).unwrap().clone(); + + assert!(filter_backed_statements_from_disabled_validators::( + &mut backed_candidates, + &>::allowed_relay_parents(), + &scheduled_paras + )); + + // there should still be two backed candidates + assert_eq!(backed_candidates.len(), 2); + // but the first one should have only one validity vote + assert_eq!(backed_candidates.get(0).unwrap().validity_votes.len(), 1); + // Validator 0 vote should be dropped, validator 1 - retained + assert_eq!( + backed_candidates.get(0).unwrap().validator_indices.get(0).unwrap(), + false ); + assert_eq!( + backed_candidates.get(0).unwrap().validator_indices.get(1).unwrap(), + true + ); + // the second candidate shouldn't be modified + assert_eq!(*backed_candidates.get(1).unwrap(), untouched); + }); + } + + #[test] + fn drop_candidate_if_all_statements_are_from_disabled() { + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + let TestData { mut backed_candidates, scheduled_paras } = get_test_data(); + + // Disable Alice and Bob + set_disabled_validators(vec![0, 1]); + + // Verify the initial state is as expected + assert_eq!(backed_candidates.get(0).unwrap().validity_votes.len(), 2); + let untouched = backed_candidates.get(1).unwrap().clone(); + + assert!(filter_backed_statements_from_disabled_validators::( + &mut backed_candidates, + &>::allowed_relay_parents(), + &scheduled_paras + )); + + assert_eq!(backed_candidates.len(), 1); + assert_eq!(*backed_candidates.get(0).unwrap(), untouched); }); } } diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs b/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs index 0da50f6a537..1fee1a4097d 100644 --- a/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs +++ b/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs @@ -21,29 +21,16 @@ use primitives::{ vstaging::{ApprovalVotingParams, NodeFeatures}, ValidatorIndex, }; -use sp_std::{collections::btree_map::BTreeMap, prelude::Vec}; +use sp_std::prelude::Vec; /// Implementation for `DisabledValidators` // CAVEAT: this should only be called on the node side // as it might produce incorrect results on session boundaries pub fn disabled_validators() -> Vec where - T: pallet_session::Config + shared::Config, + T: shared::Config, { - let shuffled_indices = >::active_validator_indices(); - // mapping from raw validator index to `ValidatorIndex` - // this computation is the same within a session, but should be cheap - let reverse_index = shuffled_indices - .iter() - .enumerate() - .map(|(i, v)| (v.0, ValidatorIndex(i as u32))) - .collect::>(); - - // we might have disabled validators who are not parachain validators - >::disabled_validators() - .iter() - .filter_map(|v| reverse_index.get(v).cloned()) - .collect() + >::disabled_validators() } /// Returns the current state of the node features. diff --git a/polkadot/runtime/parachains/src/scheduler.rs b/polkadot/runtime/parachains/src/scheduler.rs index 08ce656b2b2..a666f568908 100644 --- a/polkadot/runtime/parachains/src/scheduler.rs +++ b/polkadot/runtime/parachains/src/scheduler.rs @@ -691,4 +691,9 @@ impl Pallet { pub(crate) fn set_validator_groups(validator_groups: Vec>) { ValidatorGroups::::set(validator_groups); } + + #[cfg(test)] + pub(crate) fn set_claimqueue(claimqueue: BTreeMap>>) { + ClaimQueue::::set(claimqueue); + } } diff --git a/polkadot/runtime/parachains/src/shared.rs b/polkadot/runtime/parachains/src/shared.rs index ad13c9e4844..bdaffcd505f 100644 --- a/polkadot/runtime/parachains/src/shared.rs +++ b/polkadot/runtime/parachains/src/shared.rs @@ -19,11 +19,14 @@ //! To avoid cyclic dependencies, it is important that this pallet is not //! dependent on any of the other pallets. -use frame_support::pallet_prelude::*; +use frame_support::{pallet_prelude::*, traits::DisabledValidators}; use frame_system::pallet_prelude::BlockNumberFor; use primitives::{SessionIndex, ValidatorId, ValidatorIndex}; use sp_runtime::traits::AtLeast32BitUnsigned; -use sp_std::{collections::vec_deque::VecDeque, vec::Vec}; +use sp_std::{ + collections::{btree_map::BTreeMap, vec_deque::VecDeque}, + vec::Vec, +}; use rand::{seq::SliceRandom, SeedableRng}; use rand_chacha::ChaCha20Rng; @@ -129,7 +132,9 @@ pub mod pallet { pub struct Pallet(_); #[pallet::config] - pub trait Config: frame_system::Config {} + pub trait Config: frame_system::Config { + type DisabledValidators: frame_support::traits::DisabledValidators; + } /// The current session index. #[pallet::storage] @@ -216,6 +221,25 @@ impl Pallet { Self::session_index().saturating_add(SESSION_DELAY) } + /// Fetches disabled validators list from session pallet. + /// CAVEAT: this might produce incorrect results on session boundaries + pub fn disabled_validators() -> Vec { + let shuffled_indices = Pallet::::active_validator_indices(); + // mapping from raw validator index to `ValidatorIndex` + // this computation is the same within a session, but should be cheap + let reverse_index = shuffled_indices + .iter() + .enumerate() + .map(|(i, v)| (v.0, ValidatorIndex(i as u32))) + .collect::>(); + + // we might have disabled validators who are not parachain validators + T::DisabledValidators::disabled_validators() + .iter() + .filter_map(|v| reverse_index.get(v).cloned()) + .collect() + } + /// Test function for setting the current session index. #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))] pub fn set_session_index(index: SessionIndex) { @@ -239,4 +263,16 @@ impl Pallet { ActiveValidatorIndices::::set(indices); ActiveValidatorKeys::::set(keys); } + + #[cfg(test)] + pub(crate) fn add_allowed_relay_parent( + relay_parent: T::Hash, + state_root: T::Hash, + number: BlockNumberFor, + max_ancestry_len: u32, + ) { + AllowedRelayParents::::mutate(|tracker| { + tracker.update(relay_parent, state_root, number, max_ancestry_len) + }) + } } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 0e2eaa03567..51c00336bef 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -909,7 +909,9 @@ impl parachains_configuration::Config for Runtime { type WeightInfo = weights::runtime_parachains_configuration::WeightInfo; } -impl parachains_shared::Config for Runtime {} +impl parachains_shared::Config for Runtime { + type DisabledValidators = Session; +} impl parachains_session_info::Config for Runtime { type ValidatorSet = Historical; diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index e80412232d0..18bcb16834e 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -478,7 +478,9 @@ impl parachains_configuration::Config for Runtime { type WeightInfo = parachains_configuration::TestWeightInfo; } -impl parachains_shared::Config for Runtime {} +impl parachains_shared::Config for Runtime { + type DisabledValidators = Session; +} impl parachains_inclusion::Config for Runtime { type RuntimeEvent = RuntimeEvent; diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 28b82956a47..941193ba941 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -1117,7 +1117,9 @@ impl parachains_configuration::Config for Runtime { type WeightInfo = weights::runtime_parachains_configuration::WeightInfo; } -impl parachains_shared::Config for Runtime {} +impl parachains_shared::Config for Runtime { + type DisabledValidators = Session; +} impl parachains_session_info::Config for Runtime { type ValidatorSet = Historical; diff --git a/polkadot/xcm/xcm-builder/tests/mock/mod.rs b/polkadot/xcm/xcm-builder/tests/mock/mod.rs index e08099280ba..2e89313a68e 100644 --- a/polkadot/xcm/xcm-builder/tests/mock/mod.rs +++ b/polkadot/xcm/xcm-builder/tests/mock/mod.rs @@ -128,7 +128,9 @@ impl pallet_balances::Config for Runtime { type MaxFreezes = ConstU32<0>; } -impl shared::Config for Runtime {} +impl shared::Config for Runtime { + type DisabledValidators = (); +} impl configuration::Config for Runtime { type WeightInfo = configuration::TestWeightInfo; diff --git a/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs index 1bcbe6da2cd..946b932b05e 100644 --- a/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs +++ b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs @@ -120,7 +120,9 @@ impl pallet_uniques::Config for Runtime { type Helper = (); } -impl shared::Config for Runtime {} +impl shared::Config for Runtime { + type DisabledValidators = (); +} impl configuration::Config for Runtime { type WeightInfo = configuration::TestWeightInfo; diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs index c066cc5e813..d3f91b01317 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs @@ -100,7 +100,9 @@ impl pallet_balances::Config for Runtime { type MaxFreezes = ConstU32<0>; } -impl shared::Config for Runtime {} +impl shared::Config for Runtime { + type DisabledValidators = (); +} impl configuration::Config for Runtime { type WeightInfo = configuration::TestWeightInfo; diff --git a/prdoc/pr_2889.prdoc b/prdoc/pr_2889.prdoc new file mode 100644 index 00000000000..cbb8aafa997 --- /dev/null +++ b/prdoc/pr_2889.prdoc @@ -0,0 +1,10 @@ +title: Filter backing votes from disabled validators in paras_inherent + +doc: + - audience: Runtime User + description: | + paras_inherent drops any backing votes from disabled validators on block import and asserts + that no votes from disabled validators are included in a block during execution + +crates: + - name: polkadot-runtime-parachains diff --git a/substrate/frame/aura/src/mock.rs b/substrate/frame/aura/src/mock.rs index 14b87089ce3..d38a8583819 100644 --- a/substrate/frame/aura/src/mock.rs +++ b/substrate/frame/aura/src/mock.rs @@ -96,6 +96,10 @@ impl DisabledValidators for MockDisabledValidators { fn is_disabled(index: AuthorityIndex) -> bool { DisabledValidatorTestValue::get().binary_search(&index).is_ok() } + + fn disabled_validators() -> Vec { + DisabledValidatorTestValue::get() + } } impl pallet_aura::Config for Test { diff --git a/substrate/frame/contracts/mock-network/src/relay_chain.rs b/substrate/frame/contracts/mock-network/src/relay_chain.rs index 4e5523f7442..abe907839d9 100644 --- a/substrate/frame/contracts/mock-network/src/relay_chain.rs +++ b/substrate/frame/contracts/mock-network/src/relay_chain.rs @@ -99,7 +99,9 @@ impl pallet_balances::Config for Runtime { type RuntimeFreezeReason = RuntimeFreezeReason; } -impl shared::Config for Runtime {} +impl shared::Config for Runtime { + type DisabledValidators = (); +} impl configuration::Config for Runtime { type WeightInfo = configuration::TestWeightInfo; diff --git a/substrate/frame/session/src/lib.rs b/substrate/frame/session/src/lib.rs index bf4671a247f..178d43f596b 100644 --- a/substrate/frame/session/src/lib.rs +++ b/substrate/frame/session/src/lib.rs @@ -918,6 +918,10 @@ impl frame_support::traits::DisabledValidators for Pallet { fn is_disabled(index: u32) -> bool { >::disabled_validators().binary_search(&index).is_ok() } + + fn disabled_validators() -> Vec { + >::disabled_validators() + } } /// Wraps the author-scraping logic for consensus engines that can recover diff --git a/substrate/frame/support/src/traits/validation.rs b/substrate/frame/support/src/traits/validation.rs index 617cdb2d3f4..4b099b2c766 100644 --- a/substrate/frame/support/src/traits/validation.rs +++ b/substrate/frame/support/src/traits/validation.rs @@ -251,10 +251,17 @@ pub trait ValidatorRegistration { pub trait DisabledValidators { /// Returns true if the given validator is disabled. fn is_disabled(index: u32) -> bool; + + /// Returns all disabled validators + fn disabled_validators() -> Vec; } impl DisabledValidators for () { fn is_disabled(_index: u32) -> bool { false } + + fn disabled_validators() -> Vec { + vec![] + } } -- GitLab From d6c0f1531de5be0bcfabf8531490ff6e4804a37f Mon Sep 17 00:00:00 2001 From: Samuel Moelius <35515885+smoelius@users.noreply.github.com> Date: Thu, 18 Jan 2024 04:15:00 -0500 Subject: [PATCH 071/392] Fix typo in traits.rs (#2971) Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> --- substrate/primitives/runtime/src/traits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/primitives/runtime/src/traits.rs b/substrate/primitives/runtime/src/traits.rs index ad82419cb8b..4213117334e 100644 --- a/substrate/primitives/runtime/src/traits.rs +++ b/substrate/primitives/runtime/src/traits.rs @@ -1790,7 +1790,7 @@ pub trait ValidateUnsigned { /// this code before the unsigned extrinsic enters the transaction pool and also periodically /// afterwards to ensure the validity. To prevent dos-ing a network with unsigned /// extrinsics, these validity checks should include some checks around uniqueness, for example, - /// like checking that the unsigned extrinsic was send by an authority in the active set. + /// checking that the unsigned extrinsic was sent by an authority in the active set. /// /// Changes made to storage should be discarded by caller. fn validate_unsigned(source: TransactionSource, call: &Self::Call) -> TransactionValidity; -- GitLab From 38205bf13990e3f10916ea9a973dffcf55fef4a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 18 Jan 2024 11:49:13 +0100 Subject: [PATCH 072/392] Downgrade logging to `debug` (#2980) There is no need to spawn operators with this debug log. Closes: https://github.com/paritytech/polkadot-sdk/issues/2974 --- polkadot/node/core/approval-voting/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot/node/core/approval-voting/src/lib.rs b/polkadot/node/core/approval-voting/src/lib.rs index af76b576d7c..9116725c291 100644 --- a/polkadot/node/core/approval-voting/src/lib.rs +++ b/polkadot/node/core/approval-voting/src/lib.rs @@ -3343,7 +3343,7 @@ async fn issue_approval( ); } - gum::info!( + gum::debug!( target: LOG_TARGET, ?candidate_hash, ?block_hash, -- GitLab From 1113fce5fb7be393f688e8d89ca23a0ee1e4bda5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 13:25:24 +0100 Subject: [PATCH 073/392] Bump the known_good_semver group with 1 update (#2953) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the known_good_semver group with 1 update: [clap](https://github.com/clap-rs/clap). Updates `clap` from 4.4.16 to 4.4.18
Release notes

Sourced from clap's releases.

v4.4.18

[4.4.18] - 2024-01-16

Fixes

  • (error) When lacking usage feature, ensure the list of required arguments is unique

v4.4.17

[4.4.17] - 2024-01-15

Fixes

  • Fix panic! when mixing args_conflicts_with_subcommands with ArgGroup (which is implicit with derive) introduced in 4.4.15
Changelog

Sourced from clap's changelog.

[4.4.18] - 2024-01-16

Fixes

  • (error) When lacking usage feature, ensure the list of required arguments is unique

[4.4.17] - 2024-01-15

Fixes

  • Fix panic! when mixing args_conflicts_with_subcommands with ArgGroup (which is implicit with derive) introduced in 4.4.15
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=clap&package-manager=cargo&previous-version=4.4.16&new-version=4.4.18)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Bastian Köcher Co-authored-by: Dónal Murray --- Cargo.lock | 66 +++++++++---------- cumulus/client/cli/Cargo.toml | 2 +- cumulus/parachain-template/node/Cargo.toml | 2 +- cumulus/polkadot-parachain/Cargo.toml | 2 +- cumulus/test/service/Cargo.toml | 2 +- polkadot/cli/Cargo.toml | 2 +- polkadot/node/malus/Cargo.toml | 2 +- polkadot/node/subsystem-bench/Cargo.toml | 2 +- .../test-parachains/adder/collator/Cargo.toml | 2 +- .../undying/collator/Cargo.toml | 2 +- polkadot/utils/generate-bags/Cargo.toml | 2 +- .../remote-ext-tests/bags-list/Cargo.toml | 2 +- substrate/bin/minimal/node/Cargo.toml | 2 +- substrate/bin/node-template/node/Cargo.toml | 2 +- substrate/bin/node/bench/Cargo.toml | 2 +- substrate/bin/node/cli/Cargo.toml | 4 +- substrate/bin/node/inspect/Cargo.toml | 2 +- .../bin/utils/chain-spec-builder/Cargo.toml | 2 +- substrate/bin/utils/subkey/Cargo.toml | 2 +- substrate/client/cli/Cargo.toml | 2 +- substrate/client/storage-monitor/Cargo.toml | 2 +- .../solution-type/fuzzer/Cargo.toml | 2 +- .../npos-elections/fuzzer/Cargo.toml | 2 +- .../ci/node-template-release/Cargo.toml | 2 +- .../utils/frame/benchmarking-cli/Cargo.toml | 2 +- .../frame/frame-utilities-cli/Cargo.toml | 2 +- .../generate-bags/node-runtime/Cargo.toml | 2 +- .../utils/frame/try-runtime/cli/Cargo.toml | 2 +- 28 files changed, 61 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 849bc069d20..b6f69c2daa1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2640,9 +2640,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.16" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58e54881c004cec7895b0068a0a954cd5d62da01aef83fa35b1e594497bf5445" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" dependencies = [ "clap_builder", "clap_derive 4.4.7", @@ -2659,9 +2659,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.16" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59cb82d7f531603d2fd1f507441cdd35184fa81beff7bd489570de7f773460bb" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" dependencies = [ "anstream", "anstyle", @@ -2676,7 +2676,7 @@ version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "586a385f7ef2f8b4d86bddaa0c094794e7ccbfe5ffef1f434fe928143fc783a5" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", ] [[package]] @@ -3414,7 +3414,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.4.16", + "clap 4.4.18", "criterion-plot", "futures", "is-terminal", @@ -3577,7 +3577,7 @@ dependencies = [ name = "cumulus-client-cli" version = "0.1.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "parity-scale-codec", "sc-chain-spec", "sc-cli", @@ -4317,7 +4317,7 @@ name = "cumulus-test-service" version = "0.1.0" dependencies = [ "async-trait", - "clap 4.4.16", + "clap 4.4.18", "criterion 0.5.1", "cumulus-client-cli", "cumulus-client-consensus-common", @@ -5501,7 +5501,7 @@ dependencies = [ "Inflector", "array-bytes 6.1.0", "chrono", - "clap 4.4.16", + "clap 4.4.18", "comfy-table", "frame-benchmarking", "frame-support", @@ -5593,7 +5593,7 @@ dependencies = [ name = "frame-election-solution-type-fuzzer" version = "2.0.0-alpha.5" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "frame-election-provider-solution-type", "frame-election-provider-support", "frame-support", @@ -8109,7 +8109,7 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" name = "minimal-node" version = "4.0.0-dev" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "frame", "futures", "futures-timer", @@ -8573,7 +8573,7 @@ name = "node-bench" version = "0.9.0-dev" dependencies = [ "array-bytes 6.1.0", - "clap 4.4.16", + "clap 4.4.18", "derive_more", "fs_extra", "futures", @@ -8650,7 +8650,7 @@ dependencies = [ name = "node-runtime-generate-bags" version = "3.0.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "generate-bags", "kitchensink-runtime", ] @@ -8659,7 +8659,7 @@ dependencies = [ name = "node-template" version = "4.0.0-dev" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "frame-benchmarking", "frame-benchmarking-cli", "frame-system", @@ -8703,7 +8703,7 @@ dependencies = [ name = "node-template-release" version = "3.0.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "flate2", "fs_extra", "glob", @@ -11247,7 +11247,7 @@ dependencies = [ name = "parachain-template-node" version = "0.1.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "color-print", "cumulus-client-cli", "cumulus-client-collator", @@ -12205,7 +12205,7 @@ name = "polkadot-cli" version = "1.1.0" dependencies = [ "cfg-if", - "clap 4.4.16", + "clap 4.4.18", "frame-benchmarking-cli", "futures", "log", @@ -13046,7 +13046,7 @@ dependencies = [ "async-trait", "bridge-hub-rococo-runtime", "bridge-hub-westend-runtime", - "clap 4.4.16", + "clap 4.4.18", "collectives-westend-runtime", "color-print", "contracts-rococo-runtime", @@ -13557,7 +13557,7 @@ version = "1.0.0" dependencies = [ "assert_matches", "async-trait", - "clap 4.4.16", + "clap 4.4.18", "clap-num", "color-eyre", "colored", @@ -13634,7 +13634,7 @@ version = "1.0.0" dependencies = [ "assert_matches", "async-trait", - "clap 4.4.16", + "clap 4.4.18", "color-eyre", "futures", "futures-timer", @@ -13781,7 +13781,7 @@ dependencies = [ name = "polkadot-voter-bags" version = "1.0.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "generate-bags", "sp-io", "westend-runtime", @@ -14671,7 +14671,7 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" name = "remote-ext-tests-bags-list" version = "1.0.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "frame-system", "log", "pallet-bags-list-remote-tests", @@ -15461,7 +15461,7 @@ dependencies = [ "array-bytes 6.1.0", "bip39", "chrono", - "clap 4.4.16", + "clap 4.4.18", "fdlimit", "futures", "futures-timer", @@ -16605,7 +16605,7 @@ dependencies = [ name = "sc-storage-monitor" version = "0.1.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "fs4", "log", "sp-core", @@ -18555,7 +18555,7 @@ dependencies = [ name = "sp-npos-elections-fuzzer" version = "2.0.0-alpha.5" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "honggfuzz", "rand 0.8.5", "sp-npos-elections", @@ -19076,7 +19076,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" name = "staging-chain-spec-builder" version = "2.0.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "log", "sc-chain-spec", "serde_json", @@ -19089,7 +19089,7 @@ version = "3.0.0-dev" dependencies = [ "array-bytes 6.1.0", "assert_cmd", - "clap 4.4.16", + "clap 4.4.18", "clap_complete", "criterion 0.4.0", "frame-benchmarking", @@ -19198,7 +19198,7 @@ dependencies = [ name = "staging-node-inspect" version = "0.9.0-dev" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "parity-scale-codec", "sc-cli", "sc-client-api", @@ -19403,7 +19403,7 @@ dependencies = [ name = "subkey" version = "3.0.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "sc-cli", ] @@ -19445,7 +19445,7 @@ dependencies = [ name = "substrate-frame-cli" version = "4.0.0-dev" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "frame-support", "frame-system", "sc-cli", @@ -19923,7 +19923,7 @@ dependencies = [ name = "test-parachain-adder-collator" version = "1.0.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "futures", "futures-timer", "log", @@ -19971,7 +19971,7 @@ dependencies = [ name = "test-parachain-undying-collator" version = "1.0.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "futures", "futures-timer", "log", @@ -20622,7 +20622,7 @@ version = "0.10.0-dev" dependencies = [ "assert_cmd", "async-trait", - "clap 4.4.16", + "clap 4.4.18", "frame-remote-externalities", "frame-try-runtime", "hex", diff --git a/cumulus/client/cli/Cargo.toml b/cumulus/client/cli/Cargo.toml index 4048c3eaecb..96016da5c9a 100644 --- a/cumulus/client/cli/Cargo.toml +++ b/cumulus/client/cli/Cargo.toml @@ -10,7 +10,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0" workspace = true [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0" } url = "2.4.0" diff --git a/cumulus/parachain-template/node/Cargo.toml b/cumulus/parachain-template/node/Cargo.toml index b34478ab3dd..c12ee72f5cb 100644 --- a/cumulus/parachain-template/node/Cargo.toml +++ b/cumulus/parachain-template/node/Cargo.toml @@ -14,7 +14,7 @@ publish = false workspace = true [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } log = "0.4.20" codec = { package = "parity-scale-codec", version = "3.0.0" } serde = { version = "1.0.195", features = ["derive"] } diff --git a/cumulus/polkadot-parachain/Cargo.toml b/cumulus/polkadot-parachain/Cargo.toml index 84ba8a36d51..0a40816fc0b 100644 --- a/cumulus/polkadot-parachain/Cargo.toml +++ b/cumulus/polkadot-parachain/Cargo.toml @@ -16,7 +16,7 @@ path = "src/main.rs" [dependencies] async-trait = "0.1.74" -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0" } futures = "0.3.28" hex-literal = "0.4.1" diff --git a/cumulus/test/service/Cargo.toml b/cumulus/test/service/Cargo.toml index 387d65c4931..dcd70ca97e8 100644 --- a/cumulus/test/service/Cargo.toml +++ b/cumulus/test/service/Cargo.toml @@ -14,7 +14,7 @@ path = "src/main.rs" [dependencies] async-trait = "0.1.74" -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0" } criterion = { version = "0.5.1", features = ["async_tokio"] } jsonrpsee = { version = "0.16.2", features = ["server"] } diff --git a/polkadot/cli/Cargo.toml b/polkadot/cli/Cargo.toml index cc96422abbc..2efb057ca28 100644 --- a/polkadot/cli/Cargo.toml +++ b/polkadot/cli/Cargo.toml @@ -19,7 +19,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] cfg-if = "1.0" -clap = { version = "4.4.16", features = ["derive"], optional = true } +clap = { version = "4.4.18", features = ["derive"], optional = true } log = "0.4.17" thiserror = "1.0.48" futures = "0.3.21" diff --git a/polkadot/node/malus/Cargo.toml b/polkadot/node/malus/Cargo.toml index 7793abfd69b..6a3dff726ed 100644 --- a/polkadot/node/malus/Cargo.toml +++ b/polkadot/node/malus/Cargo.toml @@ -43,7 +43,7 @@ assert_matches = "1.5" async-trait = "0.1.74" sp-keystore = { path = "../../../substrate/primitives/keystore" } sp-core = { path = "../../../substrate/primitives/core" } -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" gum = { package = "tracing-gum", path = "../gum" } diff --git a/polkadot/node/subsystem-bench/Cargo.toml b/polkadot/node/subsystem-bench/Cargo.toml index ab3de33fe2c..f09f7fc4897 100644 --- a/polkadot/node/subsystem-bench/Cargo.toml +++ b/polkadot/node/subsystem-bench/Cargo.toml @@ -31,7 +31,7 @@ async-trait = "0.1.74" sp-keystore = { path = "../../../substrate/primitives/keystore" } sc-keystore = { path = "../../../substrate/client/keystore" } sp-core = { path = "../../../substrate/primitives/core" } -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" gum = { package = "tracing-gum", path = "../gum" } diff --git a/polkadot/parachain/test-parachains/adder/collator/Cargo.toml b/polkadot/parachain/test-parachains/adder/collator/Cargo.toml index 4ebeb767905..7dd0d9a563c 100644 --- a/polkadot/parachain/test-parachains/adder/collator/Cargo.toml +++ b/polkadot/parachain/test-parachains/adder/collator/Cargo.toml @@ -16,7 +16,7 @@ path = "src/main.rs" [dependencies] parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" log = "0.4.17" diff --git a/polkadot/parachain/test-parachains/undying/collator/Cargo.toml b/polkadot/parachain/test-parachains/undying/collator/Cargo.toml index 1d851218bed..001c48476b5 100644 --- a/polkadot/parachain/test-parachains/undying/collator/Cargo.toml +++ b/polkadot/parachain/test-parachains/undying/collator/Cargo.toml @@ -16,7 +16,7 @@ path = "src/main.rs" [dependencies] parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" log = "0.4.17" diff --git a/polkadot/utils/generate-bags/Cargo.toml b/polkadot/utils/generate-bags/Cargo.toml index a16ee8de496..0f5ee43d86d 100644 --- a/polkadot/utils/generate-bags/Cargo.toml +++ b/polkadot/utils/generate-bags/Cargo.toml @@ -10,7 +10,7 @@ description = "CLI to generate voter bags for Polkadot runtimes" workspace = true [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } generate-bags = { path = "../../../substrate/utils/frame/generate-bags" } sp-io = { path = "../../../substrate/primitives/io" } diff --git a/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml b/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml index 75bfdd9d1a0..f8190e6aefa 100644 --- a/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml +++ b/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml @@ -18,6 +18,6 @@ sp-tracing = { path = "../../../../substrate/primitives/tracing" } frame-system = { path = "../../../../substrate/frame/system" } sp-core = { path = "../../../../substrate/primitives/core" } -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } log = "0.4.17" tokio = { version = "1.24.2", features = ["macros"] } diff --git a/substrate/bin/minimal/node/Cargo.toml b/substrate/bin/minimal/node/Cargo.toml index 5a2427fd4d8..cc00988dcfe 100644 --- a/substrate/bin/minimal/node/Cargo.toml +++ b/substrate/bin/minimal/node/Cargo.toml @@ -20,7 +20,7 @@ targets = ["x86_64-unknown-linux-gnu"] name = "minimal-node" [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } futures = { version = "0.3.21", features = ["thread-pool"] } futures-timer = "3.0.1" jsonrpsee = { version = "0.16.2", features = ["server"] } diff --git a/substrate/bin/node-template/node/Cargo.toml b/substrate/bin/node-template/node/Cargo.toml index f91db97985b..36c2f9f8b70 100644 --- a/substrate/bin/node-template/node/Cargo.toml +++ b/substrate/bin/node-template/node/Cargo.toml @@ -20,7 +20,7 @@ targets = ["x86_64-unknown-linux-gnu"] name = "node-template" [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } futures = { version = "0.3.21", features = ["thread-pool"] } serde_json = "1.0.111" diff --git a/substrate/bin/node/bench/Cargo.toml b/substrate/bin/node/bench/Cargo.toml index 926cdc3bfb0..42af802d716 100644 --- a/substrate/bin/node/bench/Cargo.toml +++ b/substrate/bin/node/bench/Cargo.toml @@ -16,7 +16,7 @@ workspace = true [dependencies] array-bytes = "6.1" -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } log = "0.4.17" node-primitives = { path = "../primitives" } node-testing = { path = "../testing" } diff --git a/substrate/bin/node/cli/Cargo.toml b/substrate/bin/node/cli/Cargo.toml index 64b61288391..061c9684c22 100644 --- a/substrate/bin/node/cli/Cargo.toml +++ b/substrate/bin/node/cli/Cargo.toml @@ -41,7 +41,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] # third-party dependencies array-bytes = "6.1" -clap = { version = "4.4.16", features = ["derive"], optional = true } +clap = { version = "4.4.18", features = ["derive"], optional = true } codec = { package = "parity-scale-codec", version = "3.6.1" } serde = { version = "1.0.195", features = ["derive"] } jsonrpsee = { version = "0.16.2", features = ["server"] } @@ -164,7 +164,7 @@ sp-trie = { path = "../../../primitives/trie" } sp-state-machine = { path = "../../../primitives/state-machine" } [build-dependencies] -clap = { version = "4.4.16", optional = true } +clap = { version = "4.4.18", optional = true } clap_complete = { version = "4.0.2", optional = true } node-inspect = { package = "staging-node-inspect", path = "../inspect", optional = true } frame-benchmarking-cli = { path = "../../../utils/frame/benchmarking-cli", optional = true } diff --git a/substrate/bin/node/inspect/Cargo.toml b/substrate/bin/node/inspect/Cargo.toml index ef82f16be2a..860295b0553 100644 --- a/substrate/bin/node/inspect/Cargo.toml +++ b/substrate/bin/node/inspect/Cargo.toml @@ -15,7 +15,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.6.1" } thiserror = "1.0" sc-cli = { path = "../../../client/cli" } diff --git a/substrate/bin/utils/chain-spec-builder/Cargo.toml b/substrate/bin/utils/chain-spec-builder/Cargo.toml index a9ea0ad40b3..06a0a3a1a4a 100644 --- a/substrate/bin/utils/chain-spec-builder/Cargo.toml +++ b/substrate/bin/utils/chain-spec-builder/Cargo.toml @@ -23,7 +23,7 @@ name = "chain-spec-builder" crate-type = ["rlib"] [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } log = "0.4.17" sc-chain-spec = { path = "../../../client/chain-spec" } serde_json = "1.0.111" diff --git a/substrate/bin/utils/subkey/Cargo.toml b/substrate/bin/utils/subkey/Cargo.toml index 19eba2f1969..b53bae0b6a1 100644 --- a/substrate/bin/utils/subkey/Cargo.toml +++ b/substrate/bin/utils/subkey/Cargo.toml @@ -20,5 +20,5 @@ path = "src/main.rs" name = "subkey" [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } sc-cli = { path = "../../../client/cli" } diff --git a/substrate/client/cli/Cargo.toml b/substrate/client/cli/Cargo.toml index ce9b1781686..d64973baf83 100644 --- a/substrate/client/cli/Cargo.toml +++ b/substrate/client/cli/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] array-bytes = "6.1" chrono = "0.4.31" -clap = { version = "4.4.16", features = ["derive", "string", "wrap_help"] } +clap = { version = "4.4.18", features = ["derive", "string", "wrap_help"] } fdlimit = "0.3.0" futures = "0.3.21" itertools = "0.10.3" diff --git a/substrate/client/storage-monitor/Cargo.toml b/substrate/client/storage-monitor/Cargo.toml index 17f1c42bccb..6a01ef0fe2b 100644 --- a/substrate/client/storage-monitor/Cargo.toml +++ b/substrate/client/storage-monitor/Cargo.toml @@ -12,7 +12,7 @@ homepage = "https://substrate.io" workspace = true [dependencies] -clap = { version = "4.4.16", features = ["derive", "string"] } +clap = { version = "4.4.18", features = ["derive", "string"] } log = "0.4.17" fs4 = "0.7.0" sp-core = { path = "../../primitives/core" } diff --git a/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml b/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml index 62316b27290..7200d207aec 100644 --- a/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml +++ b/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml @@ -16,7 +16,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } honggfuzz = "0.5" rand = { version = "0.8", features = ["small_rng", "std"] } diff --git a/substrate/primitives/npos-elections/fuzzer/Cargo.toml b/substrate/primitives/npos-elections/fuzzer/Cargo.toml index f98e41ae77a..93177325436 100644 --- a/substrate/primitives/npos-elections/fuzzer/Cargo.toml +++ b/substrate/primitives/npos-elections/fuzzer/Cargo.toml @@ -17,7 +17,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } honggfuzz = "0.5" rand = { version = "0.8", features = ["small_rng", "std"] } sp-npos-elections = { path = ".." } diff --git a/substrate/scripts/ci/node-template-release/Cargo.toml b/substrate/scripts/ci/node-template-release/Cargo.toml index 40ba629fb05..a0b93184546 100644 --- a/substrate/scripts/ci/node-template-release/Cargo.toml +++ b/substrate/scripts/ci/node-template-release/Cargo.toml @@ -14,7 +14,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } flate2 = "1.0" fs_extra = "1.3" glob = "0.3" diff --git a/substrate/utils/frame/benchmarking-cli/Cargo.toml b/substrate/utils/frame/benchmarking-cli/Cargo.toml index f7210cf768f..ba95afeeee9 100644 --- a/substrate/utils/frame/benchmarking-cli/Cargo.toml +++ b/substrate/utils/frame/benchmarking-cli/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] array-bytes = "6.1" chrono = "0.4" -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.6.1" } comfy-table = { version = "7.0.1", default-features = false } handlebars = "4.2.2" diff --git a/substrate/utils/frame/frame-utilities-cli/Cargo.toml b/substrate/utils/frame/frame-utilities-cli/Cargo.toml index 899f86f3cb4..3cfb81e8c10 100644 --- a/substrate/utils/frame/frame-utilities-cli/Cargo.toml +++ b/substrate/utils/frame/frame-utilities-cli/Cargo.toml @@ -14,7 +14,7 @@ readme = "README.md" workspace = true [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } frame-support = { path = "../../../frame/support" } frame-system = { path = "../../../frame/system" } sc-cli = { path = "../../../client/cli" } diff --git a/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml b/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml index ba11fce18f8..b35e06879df 100644 --- a/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml +++ b/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml @@ -17,4 +17,4 @@ kitchensink-runtime = { path = "../../../../bin/node/runtime" } generate-bags = { path = ".." } # third-party -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } diff --git a/substrate/utils/frame/try-runtime/cli/Cargo.toml b/substrate/utils/frame/try-runtime/cli/Cargo.toml index ac515315bbe..20da5c1675e 100644 --- a/substrate/utils/frame/try-runtime/cli/Cargo.toml +++ b/substrate/utils/frame/try-runtime/cli/Cargo.toml @@ -38,7 +38,7 @@ frame-try-runtime = { path = "../../../../frame/try-runtime", optional = true } substrate-rpc-client = { path = "../../rpc/client" } async-trait = "0.1.74" -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } hex = { version = "0.4.3", default-features = false } log = "0.4.17" parity-scale-codec = "3.6.1" -- GitLab From 9a8ef495bef273d23df6ca6c825e8ef145c1489f Mon Sep 17 00:00:00 2001 From: cristiantroy <154241727+cristiantroy@users.noreply.github.com> Date: Thu, 18 Jan 2024 20:30:29 +0800 Subject: [PATCH 074/392] Fix typos (#2983) --- bridges/modules/parachains/src/lib.rs | 2 +- docs/contributor/STYLE_GUIDE.md | 2 +- docs/sdk/src/meta_contributing.rs | 2 +- docs/sdk/src/reference_docs/extrinsic_encoding.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bridges/modules/parachains/src/lib.rs b/bridges/modules/parachains/src/lib.rs index b2ef0bf52bd..cf76e64ff9c 100644 --- a/bridges/modules/parachains/src/lib.rs +++ b/bridges/modules/parachains/src/lib.rs @@ -1470,7 +1470,7 @@ pub(crate) mod tests { ); // then if someone is pretending to provide updated head#10 of parachain#1 at relay - // block#30, and actualy provides it + // block#30, and actually provides it // // => we'll update value proceed(30, state_root_10_at_30); diff --git a/docs/contributor/STYLE_GUIDE.md b/docs/contributor/STYLE_GUIDE.md index 3df65d9699a..400d9f477bc 100644 --- a/docs/contributor/STYLE_GUIDE.md +++ b/docs/contributor/STYLE_GUIDE.md @@ -161,4 +161,4 @@ See the config file for the exact rules. You may find useful - [Taplo VSCode extension](https://marketplace.visualstudio.com/items?itemName=tamasfe.even-better-toml) -- For NeoVim, [taplo is avaliable with Mason](https://github.com/williamboman/mason-lspconfig.nvim#available-lsp-servers) +- For NeoVim, [taplo is available with Mason](https://github.com/williamboman/mason-lspconfig.nvim#available-lsp-servers) diff --git a/docs/sdk/src/meta_contributing.rs b/docs/sdk/src/meta_contributing.rs index bff475f8e6b..7ecf8b0adfd 100644 --- a/docs/sdk/src/meta_contributing.rs +++ b/docs/sdk/src/meta_contributing.rs @@ -43,7 +43,7 @@ //! The following guidelines are meant to be the guiding torch of those who contribute to this //! crate. //! -//! 1. 🔺 Ground Up: Information should be layed out in the most ground-up fashion. The lowest level +//! 1. 🔺 Ground Up: Information should be laid out in the most ground-up fashion. The lowest level //! (i.e. "ground") is Rust-docs. The highest level (i.e. "up") is "outside of this crate". In //! between lies [`reference_docs`] and [`guides`], from low to high. The point of this principle //! is to document as much of the information as possible in the lower level media, as it is diff --git a/docs/sdk/src/reference_docs/extrinsic_encoding.rs b/docs/sdk/src/reference_docs/extrinsic_encoding.rs index 89c7cfe983c..9008f8f835f 100644 --- a/docs/sdk/src/reference_docs/extrinsic_encoding.rs +++ b/docs/sdk/src/reference_docs/extrinsic_encoding.rs @@ -172,7 +172,7 @@ //! } //! ``` //! -//! The bytes representing `call_data` and `signed_extensions_extra` can be obtained as descibed +//! The bytes representing `call_data` and `signed_extensions_extra` can be obtained as described //! above. `signed_extensions_additional` is constructed by SCALE encoding the //! ["additional signed" data][sp_runtime::traits::SignedExtension::AdditionalSigned] for each //! signed extension that the chain is using, in order. -- GitLab From 13f2342edd70d83377d620385610bc8dc859b64b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 11:43:37 +0000 Subject: [PATCH 075/392] Bump prost from 0.11.9 to 0.12.3 (#2976) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [prost](https://github.com/tokio-rs/prost) from 0.11.9 to 0.12.3.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=prost&package-manager=cargo&previous-version=0.11.9&new-version=0.12.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Dónal Murray --- Cargo.lock | 39 +++++++++++++++---- .../client/authority-discovery/Cargo.toml | 2 +- substrate/client/network/bitswap/Cargo.toml | 2 +- substrate/client/network/light/Cargo.toml | 2 +- substrate/client/network/sync/Cargo.toml | 2 +- .../network/sync/src/block_request_handler.rs | 2 +- 6 files changed, 36 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b6f69c2daa1..87a2dad7549 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14213,7 +14213,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ "bytes", - "prost-derive", + "prost-derive 0.11.9", +] + +[[package]] +name = "prost" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +dependencies = [ + "bytes", + "prost-derive 0.12.3", ] [[package]] @@ -14230,7 +14240,7 @@ dependencies = [ "multimap", "petgraph", "prettyplease 0.1.25", - "prost", + "prost 0.11.9", "prost-types", "regex", "syn 1.0.109", @@ -14251,13 +14261,26 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "prost-derive" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +dependencies = [ + "anyhow", + "itertools 0.11.0", + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "prost-types" version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" dependencies = [ - "prost", + "prost 0.11.9", ] [[package]] @@ -14280,7 +14303,7 @@ dependencies = [ "libflate", "log", "names", - "prost", + "prost 0.11.9", "reqwest", "thiserror", "url", @@ -15357,7 +15380,7 @@ dependencies = [ "multihash 0.18.1", "multihash-codetable", "parity-scale-codec", - "prost", + "prost 0.12.3", "prost-build", "quickcheck", "rand 0.8.5", @@ -16116,7 +16139,7 @@ dependencies = [ "futures", "libp2p-identity", "log", - "prost", + "prost 0.12.3", "prost-build", "sc-block-builder", "sc-client-api", @@ -16183,7 +16206,7 @@ dependencies = [ "libp2p-identity", "log", "parity-scale-codec", - "prost", + "prost 0.12.3", "prost-build", "sc-client-api", "sc-network", @@ -16225,7 +16248,7 @@ dependencies = [ "log", "mockall", "parity-scale-codec", - "prost", + "prost 0.12.3", "prost-build", "quickcheck", "sc-block-builder", diff --git a/substrate/client/authority-discovery/Cargo.toml b/substrate/client/authority-discovery/Cargo.toml index a8a28a501ea..e7aead99c02 100644 --- a/substrate/client/authority-discovery/Cargo.toml +++ b/substrate/client/authority-discovery/Cargo.toml @@ -30,7 +30,7 @@ multihash = { version = "0.18.1", default-features = false, features = [ "std", ] } log = "0.4.17" -prost = "0.11" +prost = "0.12" rand = "0.8.5" thiserror = "1.0" prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus" } diff --git a/substrate/client/network/bitswap/Cargo.toml b/substrate/client/network/bitswap/Cargo.toml index cc919d2977e..b004c03e025 100644 --- a/substrate/client/network/bitswap/Cargo.toml +++ b/substrate/client/network/bitswap/Cargo.toml @@ -24,7 +24,7 @@ cid = "0.9.0" futures = "0.3.21" libp2p-identity = { version = "0.1.3", features = ["peerid"] } log = "0.4.17" -prost = "0.11" +prost = "0.12" thiserror = "1.0" unsigned-varint = { version = "0.7.1", features = ["asynchronous_codec", "futures"] } sc-client-api = { path = "../../api" } diff --git a/substrate/client/network/light/Cargo.toml b/substrate/client/network/light/Cargo.toml index c75d14f0deb..d59fde56430 100644 --- a/substrate/client/network/light/Cargo.toml +++ b/substrate/client/network/light/Cargo.toml @@ -27,7 +27,7 @@ codec = { package = "parity-scale-codec", version = "3.6.1", features = [ futures = "0.3.21" libp2p-identity = { version = "0.1.3", features = ["peerid"] } log = "0.4.16" -prost = "0.11" +prost = "0.12" sp-blockchain = { path = "../../../primitives/blockchain" } sc-client-api = { path = "../../api" } sc-network = { path = ".." } diff --git a/substrate/client/network/sync/Cargo.toml b/substrate/client/network/sync/Cargo.toml index dd993e7a3df..abcb4cc8e42 100644 --- a/substrate/client/network/sync/Cargo.toml +++ b/substrate/client/network/sync/Cargo.toml @@ -28,7 +28,7 @@ futures-timer = "3.0.2" libp2p = "0.51.4" log = "0.4.17" mockall = "0.11.3" -prost = "0.11" +prost = "0.12" schnellru = "0.2.1" smallvec = "1.11.0" thiserror = "1.0" diff --git a/substrate/client/network/sync/src/block_request_handler.rs b/substrate/client/network/sync/src/block_request_handler.rs index f2af7d21786..7dfa76278b8 100644 --- a/substrate/client/network/sync/src/block_request_handler.rs +++ b/substrate/client/network/sync/src/block_request_handler.rs @@ -228,7 +228,7 @@ where }; let direction = - Direction::from_i32(request.direction).ok_or(HandleRequestError::ParseDirection)?; + i32::try_into(request.direction).map_err(|_| HandleRequestError::ParseDirection)?; let attributes = BlockAttributes::from_be_u32(request.fields)?; -- GitLab From dcc76525d98a097be152293eee3389f6af5c4404 Mon Sep 17 00:00:00 2001 From: Muharem Date: Thu, 18 Jan 2024 22:04:13 +0800 Subject: [PATCH 076/392] Westend/Rococo Asset Hub: pay xcm fees with sufficient assets (#2978) Set up the `TakeFirstAssetTrader` trader for Westend and Rococo Asset Hubs to cover XCM fees with sufficient assets. This PR reintroduces previously [removed](https://github.com/paritytech/polkadot-sdk/pull/1845) trader setups, as it was decided to keep both traders, `TakeFirstAssetTrader` and `SwapFirstAssetTrader`, during the transition period. --------- Co-authored-by: Svyatoslav Nikolsky --- ...set-transfer-works-rococo-to-westend.zndsl | 4 +- ...set-transfer-works-westend-to-rococo.zndsl | 4 +- .../assets/asset-hub-rococo/src/tests/send.rs | 75 +++ .../asset-hub-westend/src/tests/send.rs | 75 +++ .../assets/asset-hub-rococo/src/xcm_config.rs | 26 + .../assets/asset-hub-rococo/tests/tests.rs | 447 +++++++++++++++++- .../asset-hub-westend/src/xcm_config.rs | 26 + .../assets/asset-hub-westend/tests/tests.rs | 446 ++++++++++++++++- 8 files changed, 1071 insertions(+), 32 deletions(-) diff --git a/bridges/zombienet/tests/0001-asset-transfer-works-rococo-to-westend.zndsl b/bridges/zombienet/tests/0001-asset-transfer-works-rococo-to-westend.zndsl index a61f1e039f4..fe7dc26b001 100644 --- a/bridges/zombienet/tests/0001-asset-transfer-works-rococo-to-westend.zndsl +++ b/bridges/zombienet/tests/0001-asset-transfer-works-rococo-to-westend.zndsl @@ -14,7 +14,7 @@ bridge-hub-westend-collator1: js-script ../helpers/best-finalized-header-at-brid # step 4: send WND to //Alice on Rococo AH # (that's a required part of a sibling 0001-asset-transfer-works-westend-to-rococo.zndsl test) -asset-hub-westend-collator1: run ../scripts/invoke-script.sh with "reserve-transfer-assets-from-asset-hub-westend-local" within 60 seconds +asset-hub-westend-collator1: run ../scripts/invoke-script.sh with "reserve-transfer-assets-from-asset-hub-westend-local" within 120 seconds # step 5: elsewhere Rococo has sent ROC to //Alice - let's wait for it asset-hub-westend-collator1: js-script ../helpers/wrapped-assets-balance.js with "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY,0,Rococo" within 600 seconds @@ -24,7 +24,7 @@ bridge-hub-westend-collator1: js-script ../helpers/relayer-rewards.js with "5FLS bridge-hub-westend-collator1: js-script ../helpers/relayer-rewards.js with "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y,0x00000002,0x6268726F,ThisChain,0" within 300 seconds # step 7: send wROC back to Alice at Rococo AH -asset-hub-westend-collator1: run ../scripts/invoke-script.sh with "withdraw-reserve-assets-from-asset-hub-westend-local" within 60 seconds +asset-hub-westend-collator1: run ../scripts/invoke-script.sh with "withdraw-reserve-assets-from-asset-hub-westend-local" within 120 seconds # step 8: elsewhere Rococo has sent wWND to //Alice - let's wait for it # (we wait until //Alice account increases here - there are no other transactionc that may increase it) diff --git a/bridges/zombienet/tests/0001-asset-transfer-works-westend-to-rococo.zndsl b/bridges/zombienet/tests/0001-asset-transfer-works-westend-to-rococo.zndsl index 2da5b7a772a..610b4ca7acd 100644 --- a/bridges/zombienet/tests/0001-asset-transfer-works-westend-to-rococo.zndsl +++ b/bridges/zombienet/tests/0001-asset-transfer-works-westend-to-rococo.zndsl @@ -14,7 +14,7 @@ bridge-hub-rococo-collator1: js-script ../helpers/best-finalized-header-at-bridg # step 4: send ROC to //Alice on Westend AH # (that's a required part of a sibling 0001-asset-transfer-works-rococo-to-westend.zndsl test) -asset-hub-rococo-collator1: run ../scripts/invoke-script.sh with "reserve-transfer-assets-from-asset-hub-rococo-local" within 60 seconds +asset-hub-rococo-collator1: run ../scripts/invoke-script.sh with "reserve-transfer-assets-from-asset-hub-rococo-local" within 120 seconds # step 5: elsewhere Westend has sent WND to //Alice - let's wait for it asset-hub-rococo-collator1: js-script ../helpers/wrapped-assets-balance.js with "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY,0,Westend" within 600 seconds @@ -24,7 +24,7 @@ bridge-hub-rococo-collator1: js-script ../helpers/relayer-rewards.js with "5FLSi bridge-hub-rococo-collator1: js-script ../helpers/relayer-rewards.js with "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y,0x00000002,0x62687764,ThisChain,0" within 300 seconds # step 7: send wWND back to Alice at Westend AH -asset-hub-rococo-collator1: run ../scripts/invoke-script.sh with "withdraw-reserve-assets-from-asset-hub-rococo-local" within 60 seconds +asset-hub-rococo-collator1: run ../scripts/invoke-script.sh with "withdraw-reserve-assets-from-asset-hub-rococo-local" within 120 seconds # step 8: elsewhere Westend has sent wROC to //Alice - let's wait for it # (we wait until //Alice account increases here - there are no other transactionc that may increase it) diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/send.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/send.rs index fcf4513859e..3c9e76a34e3 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/send.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/send.rs @@ -27,3 +27,78 @@ fn send_transact_as_superuser_from_relay_to_system_para_works() { Some(Weight::from_parts(1_019_445_000, 200_000)), ) } + +/// Parachain should be able to send XCM paying its fee with sufficient asset +/// in the System Parachain +#[test] +fn send_xcm_from_para_to_system_para_paying_fee_with_assets_works() { + let para_sovereign_account = AssetHubRococo::sovereign_account_id_of( + AssetHubRococo::sibling_location_of(PenpalA::para_id()), + ); + + // Force create and mint assets for Parachain's sovereign account + AssetHubRococo::force_create_and_mint_asset( + ASSET_ID, + ASSET_MIN_BALANCE, + true, + para_sovereign_account.clone(), + Some(Weight::from_parts(1_019_445_000, 200_000)), + ASSET_MIN_BALANCE * 1000000000, + ); + + // We just need a call that can pass the `SafeCallFilter` + // Call values are not relevant + let call = AssetHubRococo::force_create_asset_call( + ASSET_ID, + para_sovereign_account.clone(), + true, + ASSET_MIN_BALANCE, + ); + + let origin_kind = OriginKind::SovereignAccount; + let fee_amount = ASSET_MIN_BALANCE * 1000000; + let native_asset = + ([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], fee_amount).into(); + + let root_origin = ::RuntimeOrigin::root(); + let system_para_destination = PenpalA::sibling_location_of(AssetHubRococo::para_id()).into(); + let xcm = xcm_transact_paid_execution( + call, + origin_kind, + native_asset, + para_sovereign_account.clone(), + ); + + PenpalA::execute_with(|| { + assert_ok!(::PolkadotXcm::send( + root_origin, + bx!(system_para_destination), + bx!(xcm), + )); + + PenpalA::assert_xcm_pallet_sent(); + }); + + AssetHubRococo::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + AssetHubRococo::assert_xcmp_queue_success(Some(Weight::from_parts( + 15_594_564_000, + 562_893, + ))); + + assert_expected_events!( + AssetHubRococo, + vec![ + RuntimeEvent::Assets(pallet_assets::Event::Burned { asset_id, owner, balance }) => { + asset_id: *asset_id == ASSET_ID, + owner: *owner == para_sovereign_account, + balance: *balance == fee_amount, + }, + RuntimeEvent::Assets(pallet_assets::Event::Issued { asset_id, .. }) => { + asset_id: *asset_id == ASSET_ID, + }, + ] + ); + }); +} diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/send.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/send.rs index d943bafc379..a3cd5c5803e 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/send.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/send.rs @@ -27,3 +27,78 @@ fn send_transact_as_superuser_from_relay_to_system_para_works() { Some(Weight::from_parts(1_019_445_000, 200_000)), ) } + +/// Parachain should be able to send XCM paying its fee with sufficient asset +/// in the System Parachain +#[test] +fn send_xcm_from_para_to_system_para_paying_fee_with_assets_works() { + let para_sovereign_account = AssetHubWestend::sovereign_account_id_of( + AssetHubWestend::sibling_location_of(PenpalB::para_id()), + ); + + // Force create and mint assets for Parachain's sovereign account + AssetHubWestend::force_create_and_mint_asset( + ASSET_ID, + ASSET_MIN_BALANCE, + true, + para_sovereign_account.clone(), + Some(Weight::from_parts(1_019_445_000, 200_000)), + ASSET_MIN_BALANCE * 1000000000, + ); + + // We just need a call that can pass the `SafeCallFilter` + // Call values are not relevant + let call = AssetHubWestend::force_create_asset_call( + ASSET_ID, + para_sovereign_account.clone(), + true, + ASSET_MIN_BALANCE, + ); + + let origin_kind = OriginKind::SovereignAccount; + let fee_amount = ASSET_MIN_BALANCE * 1000000; + let native_asset = + ([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], fee_amount).into(); + + let root_origin = ::RuntimeOrigin::root(); + let system_para_destination = PenpalB::sibling_location_of(AssetHubWestend::para_id()).into(); + let xcm = xcm_transact_paid_execution( + call, + origin_kind, + native_asset, + para_sovereign_account.clone(), + ); + + PenpalB::execute_with(|| { + assert_ok!(::PolkadotXcm::send( + root_origin, + bx!(system_para_destination), + bx!(xcm), + )); + + PenpalB::assert_xcm_pallet_sent(); + }); + + AssetHubWestend::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + AssetHubWestend::assert_xcmp_queue_success(Some(Weight::from_parts( + 16_290_336_000, + 562_893, + ))); + + assert_expected_events!( + AssetHubWestend, + vec![ + RuntimeEvent::Assets(pallet_assets::Event::Burned { asset_id, owner, balance }) => { + asset_id: *asset_id == ASSET_ID, + owner: *owner == para_sovereign_account, + balance: *balance == fee_amount, + }, + RuntimeEvent::Assets(pallet_assets::Event::Issued { asset_id, .. }) => { + asset_id: *asset_id == ASSET_ID, + }, + ] + ); + }); +} diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs index 98b23efc06e..b9b9025b697 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs @@ -585,6 +585,32 @@ impl xcm_executor::Config for XcmConfig { ResolveAssetTo, AccountId, >, + // This trader allows to pay with `is_sufficient=true` "Trust Backed" assets from dedicated + // `pallet_assets` instance - `Assets`. + cumulus_primitives_utility::TakeFirstAssetTrader< + AccountId, + AssetFeeAsExistentialDepositMultiplierFeeCharger, + TrustBackedAssetsConvertedConcreteId, + Assets, + cumulus_primitives_utility::XcmFeesTo32ByteAccount< + FungiblesTransactor, + AccountId, + XcmAssetFeesReceiver, + >, + >, + // This trader allows to pay with `is_sufficient=true` "Foreign" assets from dedicated + // `pallet_assets` instance - `ForeignAssets`. + cumulus_primitives_utility::TakeFirstAssetTrader< + AccountId, + ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, + ForeignAssetsConvertedConcreteId, + ForeignAssets, + cumulus_primitives_utility::XcmFeesTo32ByteAccount< + ForeignFungiblesTransactor, + AccountId, + XcmAssetFeesReceiver, + >, + >, ); type ResponseHandler = PolkadotXcm; type AssetTrap = PolkadotXcm; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs index 3da1a1e66bd..cb7ea34a057 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs @@ -20,27 +20,23 @@ use asset_hub_rococo_runtime::{ xcm_config, xcm_config::{ - bridging, ForeignCreatorsSovereignAccountOf, LocationToAccountId, TokenLocation, - TokenLocationV3, + bridging, AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, + ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, ForeignCreatorsSovereignAccountOf, + LocationToAccountId, TokenLocation, TokenLocationV3, TrustBackedAssetsPalletLocation, + TrustBackedAssetsPalletLocationV3, XcmConfig, }, - AllPalletsWithoutSystem, MetadataDepositBase, MetadataDepositPerByte, RuntimeCall, - RuntimeEvent, ToWestendXcmRouterInstance, XcmpQueue, -}; -pub use asset_hub_rococo_runtime::{ - xcm_config::{ - CheckingAccount, TrustBackedAssetsPalletLocation, TrustBackedAssetsPalletLocationV3, - XcmConfig, - }, - AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, ExistentialDeposit, - ForeignAssets, ForeignAssetsInstance, ParachainSystem, Runtime, SessionKeys, System, - TrustBackedAssetsInstance, + AllPalletsWithoutSystem, AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, + ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, + MetadataDepositPerByte, ParachainSystem, Runtime, RuntimeCall, RuntimeEvent, SessionKeys, + ToWestendXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue, }; use asset_test_utils::{ test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, }; use codec::{Decode, Encode}; +use cumulus_primitives_utility::ChargeWeightInFungibles; use frame_support::{ - assert_ok, + assert_noop, assert_ok, traits::{ fungible::{Inspect, Mutate}, fungibles::{ @@ -353,6 +349,429 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { }) } +#[test] +fn test_asset_xcm_take_first_trader() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + let minimum_asset_balance = 3333333_u128; + let local_asset_id = 1; + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + local_asset_id.into(), + AccountId::from(ALICE).into(), + true, + minimum_asset_balance + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(Assets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + local_asset_id.into(), + AccountId::from(ALICE).into(), + minimum_asset_balance + )); + + // get asset id as location + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&local_asset_id).unwrap(); + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 4e9 weight + let bought = Weight::from_parts(4_000_000_000u64, 0); + + // Lets calculate amount needed + let asset_amount_needed = + AssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles( + local_asset_id, + bought, + ) + .expect("failed to compute"); + + // Lets pay with: asset_amount_needed + asset_amount_extra + let asset_amount_extra = 100_u128; + let asset: Asset = + (asset_location.clone(), asset_amount_needed + asset_amount_extra).into(); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Lets buy_weight and make sure buy_weight does not return an error + let unused_assets = trader.buy_weight(bought, asset.into(), &ctx).expect("Expected Ok"); + // Check whether a correct amount of unused assets is returned + assert_ok!(unused_assets.ensure_contains(&(asset_location, asset_amount_extra).into())); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has received the amount + assert_eq!( + Assets::balance(local_asset_id, AccountId::from(ALICE)), + minimum_asset_balance + asset_amount_needed + ); + + // We also need to ensure the total supply increased + assert_eq!( + Assets::total_supply(local_asset_id), + minimum_asset_balance + asset_amount_needed + ); + }); +} + +#[test] +fn test_foreign_asset_xcm_take_first_trader() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + let minimum_asset_balance = 3333333_u128; + let foreign_location = xcm::v3::Location { + parents: 1, + interior: ( + xcm::v3::Junction::Parachain(1234), + xcm::v3::Junction::GeneralIndex(12345), + ) + .into(), + }; + assert_ok!(ForeignAssets::force_create( + RuntimeHelper::root_origin(), + foreign_location.into(), + AccountId::from(ALICE).into(), + true, + minimum_asset_balance + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(ForeignAssets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + foreign_location.into(), + AccountId::from(ALICE).into(), + minimum_asset_balance + )); + + let asset_location_v4: Location = foreign_location.try_into().unwrap(); + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 4e9 weight + let bought = Weight::from_parts(4_000_000_000u64, 0); + + // Lets calculate amount needed + let asset_amount_needed = + ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles( + foreign_location, + bought, + ) + .expect("failed to compute"); + + // Lets pay with: asset_amount_needed + asset_amount_extra + let asset_amount_extra = 100_u128; + let asset: Asset = + (asset_location_v4.clone(), asset_amount_needed + asset_amount_extra).into(); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Lets buy_weight and make sure buy_weight does not return an error + let unused_assets = trader.buy_weight(bought, asset.into(), &ctx).expect("Expected Ok"); + // Check whether a correct amount of unused assets is returned + assert_ok!( + unused_assets.ensure_contains(&(asset_location_v4, asset_amount_extra).into()) + ); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has received the amount + assert_eq!( + ForeignAssets::balance(foreign_location, AccountId::from(ALICE)), + minimum_asset_balance + asset_amount_needed + ); + + // We also need to ensure the total supply increased + assert_eq!( + ForeignAssets::total_supply(foreign_location), + minimum_asset_balance + asset_amount_needed + ); + }); +} + +#[test] +fn test_asset_xcm_take_first_trader_with_refund() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + // We set existential deposit to be identical to the one for Balances first + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + true, + ExistentialDeposit::get() + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(Assets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + 1.into(), + AccountId::from(ALICE).into(), + ExistentialDeposit::get() + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 4e9 weight + let bought = Weight::from_parts(4_000_000_000u64, 0); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + // lets calculate amount needed + let amount_bought = WeightToFee::weight_to_fee(&bought); + + let asset: Asset = (asset_location.clone(), amount_bought).into(); + + // Make sure buy_weight does not return an error + assert_ok!(trader.buy_weight(bought, asset.clone().into(), &ctx)); + + // Make sure again buy_weight does return an error + // This assert relies on the fact, that we use `TakeFirstAssetTrader` in `WeightTrader` + // tuple chain, which cannot be called twice + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // We actually use half of the weight + let weight_used = bought / 2; + + // Make sure refurnd works. + let amount_refunded = WeightToFee::weight_to_fee(&(bought - weight_used)); + + assert_eq!( + trader.refund_weight(bought - weight_used, &ctx), + Some((asset_location, amount_refunded).into()) + ); + + // Drop trader + drop(trader); + + // We only should have paid for half of the bought weight + let fees_paid = WeightToFee::weight_to_fee(&weight_used); + + assert_eq!( + Assets::balance(1, AccountId::from(ALICE)), + ExistentialDeposit::get() + fees_paid + ); + + // We also need to ensure the total supply increased + assert_eq!(Assets::total_supply(1), ExistentialDeposit::get() + fees_paid); + }); +} + +#[test] +fn test_asset_xcm_take_first_trader_refund_not_possible_since_amount_less_than_ed() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + // We set existential deposit to be identical to the one for Balances first + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + true, + ExistentialDeposit::get() + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy small amount + let bought = Weight::from_parts(500_000_000u64, 0); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + let amount_bought = WeightToFee::weight_to_fee(&bought); + + assert!( + amount_bought < ExistentialDeposit::get(), + "we are testing what happens when the amount does not exceed ED" + ); + + let asset: Asset = (asset_location, amount_bought).into(); + + // Buy weight should return an error + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // not credited since the ED is higher than this value + assert_eq!(Assets::balance(1, AccountId::from(ALICE)), 0); + + // We also need to ensure the total supply did not increase + assert_eq!(Assets::total_supply(1), 0); + }); +} + +#[test] +fn test_that_buying_ed_refund_does_not_refund_for_take_first_trader() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + // We set existential deposit to be identical to the one for Balances first + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + true, + ExistentialDeposit::get() + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are gonna buy ED + let bought = Weight::from_parts(ExistentialDeposit::get().try_into().unwrap(), 0); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + let amount_bought = WeightToFee::weight_to_fee(&bought); + + assert!( + amount_bought < ExistentialDeposit::get(), + "we are testing what happens when the amount does not exceed ED" + ); + + // We know we will have to buy at least ED, so lets make sure first it will + // fail with a payment of less than ED + let asset: Asset = (asset_location.clone(), amount_bought).into(); + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // Now lets buy ED at least + let asset: Asset = (asset_location, ExistentialDeposit::get()).into(); + + // Buy weight should work + assert_ok!(trader.buy_weight(bought, asset.into(), &ctx)); + + // Should return None. We have a specific check making sure we dont go below ED for + // drop payment + assert_eq!(trader.refund_weight(bought, &ctx), None); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has received the amount + assert_eq!(Assets::balance(1, AccountId::from(ALICE)), ExistentialDeposit::get()); + + // We also need to ensure the total supply increased + assert_eq!(Assets::total_supply(1), ExistentialDeposit::get()); + }); +} + +#[test] +fn test_asset_xcm_trader_not_possible_for_non_sufficient_assets() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // Create a non-sufficient asset with specific existential deposit + let minimum_asset_balance = 1_000_000_u128; + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + false, + minimum_asset_balance + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(Assets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + 1.into(), + AccountId::from(ALICE).into(), + minimum_asset_balance + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 4e9 weight + let bought = Weight::from_parts(4_000_000_000u64, 0); + + // lets calculate amount needed + let asset_amount_needed = WeightToFee::weight_to_fee(&bought); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + let asset: Asset = (asset_location, asset_amount_needed).into(); + + // Make sure again buy_weight does return an error + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has NOT received the amount + assert_eq!(Assets::balance(1, AccountId::from(ALICE)), minimum_asset_balance); + + // We also need to ensure the total supply NOT increased + assert_eq!(Assets::total_supply(1), minimum_asset_balance); + }); +} + #[test] fn test_assets_balances_api_works() { use assets_common::runtime_api::runtime_decl_for_fungibles_api::FungiblesApi; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs index b2498418cc7..70522eda4b7 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs @@ -609,6 +609,32 @@ impl xcm_executor::Config for XcmConfig { ResolveAssetTo, AccountId, >, + // This trader allows to pay with `is_sufficient=true` "Trust Backed" assets from dedicated + // `pallet_assets` instance - `Assets`. + cumulus_primitives_utility::TakeFirstAssetTrader< + AccountId, + AssetFeeAsExistentialDepositMultiplierFeeCharger, + TrustBackedAssetsConvertedConcreteId, + Assets, + cumulus_primitives_utility::XcmFeesTo32ByteAccount< + FungiblesTransactor, + AccountId, + XcmAssetFeesReceiver, + >, + >, + // This trader allows to pay with `is_sufficient=true` "Foreign" assets from dedicated + // `pallet_assets` instance - `ForeignAssets`. + cumulus_primitives_utility::TakeFirstAssetTrader< + AccountId, + ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, + ForeignAssetsConvertedConcreteId, + ForeignAssets, + cumulus_primitives_utility::XcmFeesTo32ByteAccount< + ForeignFungiblesTransactor, + AccountId, + XcmAssetFeesReceiver, + >, + >, ); type ResponseHandler = PolkadotXcm; type AssetTrap = PolkadotXcm; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs index 28fc7ba705a..3fc9f4a9658 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs @@ -20,27 +20,24 @@ use asset_hub_westend_runtime::{ xcm_config, xcm_config::{ - bridging, ForeignCreatorsSovereignAccountOf, LocationToAccountId, WestendLocation, - WestendLocationV3, + bridging, AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, + ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, ForeignCreatorsSovereignAccountOf, + LocationToAccountId, TrustBackedAssetsPalletLocation, TrustBackedAssetsPalletLocationV3, + WestendLocation, WestendLocationV3, XcmConfig, }, - AllPalletsWithoutSystem, MetadataDepositBase, MetadataDepositPerByte, PolkadotXcm, RuntimeCall, - RuntimeEvent, RuntimeOrigin, ToRococoXcmRouterInstance, XcmpQueue, -}; -pub use asset_hub_westend_runtime::{ - xcm_config::{ - CheckingAccount, TrustBackedAssetsPalletLocation, TrustBackedAssetsPalletLocationV3, - XcmConfig, - }, - AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, ExistentialDeposit, - ForeignAssets, ForeignAssetsInstance, ParachainSystem, Runtime, SessionKeys, System, - TrustBackedAssetsInstance, + AllPalletsWithoutSystem, Assets, Balances, ExistentialDeposit, ForeignAssets, + ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, + PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, + ToRococoXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue, }; +pub use asset_hub_westend_runtime::{AssetConversion, AssetDeposit, CollatorSelection, System}; use asset_test_utils::{ test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, }; use codec::{Decode, Encode}; +use cumulus_primitives_utility::ChargeWeightInFungibles; use frame_support::{ - assert_ok, + assert_noop, assert_ok, traits::{ fungible::{Inspect, Mutate}, fungibles::{ @@ -353,6 +350,427 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { }) } +#[test] +fn test_asset_xcm_take_first_trader() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + let minimum_asset_balance = 3333333_u128; + let local_asset_id = 1; + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + local_asset_id.into(), + AccountId::from(ALICE).into(), + true, + minimum_asset_balance + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(Assets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + local_asset_id.into(), + AccountId::from(ALICE).into(), + minimum_asset_balance + )); + + // get asset id as location + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&local_asset_id).unwrap(); + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 4e9 weight + let bought = Weight::from_parts(4_000_000_000u64, 0); + + // Lets calculate amount needed + let asset_amount_needed = + AssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles( + local_asset_id, + bought, + ) + .expect("failed to compute"); + + // Lets pay with: asset_amount_needed + asset_amount_extra + let asset_amount_extra = 100_u128; + let asset: Asset = + (asset_location.clone(), asset_amount_needed + asset_amount_extra).into(); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Lets buy_weight and make sure buy_weight does not return an error + let unused_assets = trader.buy_weight(bought, asset.into(), &ctx).expect("Expected Ok"); + // Check whether a correct amount of unused assets is returned + assert_ok!(unused_assets.ensure_contains(&(asset_location, asset_amount_extra).into())); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has received the amount + assert_eq!( + Assets::balance(local_asset_id, AccountId::from(ALICE)), + minimum_asset_balance + asset_amount_needed + ); + + // We also need to ensure the total supply increased + assert_eq!( + Assets::total_supply(local_asset_id), + minimum_asset_balance + asset_amount_needed + ); + }); +} + +#[test] +fn test_foreign_asset_xcm_take_first_trader() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + let minimum_asset_balance = 3333333_u128; + let foreign_location = xcm::v3::Location { + parents: 1, + interior: ( + xcm::v3::Junction::Parachain(1234), + xcm::v3::Junction::GeneralIndex(12345), + ) + .into(), + }; + assert_ok!(ForeignAssets::force_create( + RuntimeHelper::root_origin(), + foreign_location.into(), + AccountId::from(ALICE).into(), + true, + minimum_asset_balance + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(ForeignAssets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + foreign_location.into(), + AccountId::from(ALICE).into(), + minimum_asset_balance + )); + + let asset_location_v4: Location = foreign_location.try_into().unwrap(); + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 4e9 weight + let bought = Weight::from_parts(4_000_000_000u64, 0); + + // Lets calculate amount needed + let asset_amount_needed = + ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles( + foreign_location, + bought, + ) + .expect("failed to compute"); + + // Lets pay with: asset_amount_needed + asset_amount_extra + let asset_amount_extra = 100_u128; + let asset: Asset = + (asset_location_v4.clone(), asset_amount_needed + asset_amount_extra).into(); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Lets buy_weight and make sure buy_weight does not return an error + let unused_assets = trader.buy_weight(bought, asset.into(), &ctx).expect("Expected Ok"); + // Check whether a correct amount of unused assets is returned + assert_ok!( + unused_assets.ensure_contains(&(asset_location_v4, asset_amount_extra).into()) + ); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has received the amount + assert_eq!( + ForeignAssets::balance(foreign_location, AccountId::from(ALICE)), + minimum_asset_balance + asset_amount_needed + ); + + // We also need to ensure the total supply increased + assert_eq!( + ForeignAssets::total_supply(foreign_location), + minimum_asset_balance + asset_amount_needed + ); + }); +} + +#[test] +fn test_asset_xcm_take_first_trader_with_refund() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + // We set existential deposit to be identical to the one for Balances first + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + true, + ExistentialDeposit::get() + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(Assets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + 1.into(), + AccountId::from(ALICE).into(), + ExistentialDeposit::get() + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 4e9 weight + let bought = Weight::from_parts(4_000_000_000u64, 0); + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + // lets calculate amount needed + let amount_bought = WeightToFee::weight_to_fee(&bought); + + let asset: Asset = (asset_location.clone(), amount_bought).into(); + + // Make sure buy_weight does not return an error + assert_ok!(trader.buy_weight(bought, asset.clone().into(), &ctx)); + + // Make sure again buy_weight does return an error + // This assert relies on the fact, that we use `TakeFirstAssetTrader` in `WeightTrader` + // tuple chain, which cannot be called twice + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // We actually use half of the weight + let weight_used = bought / 2; + + // Make sure refurnd works. + let amount_refunded = WeightToFee::weight_to_fee(&(bought - weight_used)); + + assert_eq!( + trader.refund_weight(bought - weight_used, &ctx), + Some((asset_location, amount_refunded).into()) + ); + + // Drop trader + drop(trader); + + // We only should have paid for half of the bought weight + let fees_paid = WeightToFee::weight_to_fee(&weight_used); + + assert_eq!( + Assets::balance(1, AccountId::from(ALICE)), + ExistentialDeposit::get() + fees_paid + ); + + // We also need to ensure the total supply increased + assert_eq!(Assets::total_supply(1), ExistentialDeposit::get() + fees_paid); + }); +} + +#[test] +fn test_asset_xcm_take_first_trader_refund_not_possible_since_amount_less_than_ed() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + // We set existential deposit to be identical to the one for Balances first + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + true, + ExistentialDeposit::get() + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy small amount + let bought = Weight::from_parts(500_000_000u64, 0); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + let amount_bought = WeightToFee::weight_to_fee(&bought); + + assert!( + amount_bought < ExistentialDeposit::get(), + "we are testing what happens when the amount does not exceed ED" + ); + + let asset: Asset = (asset_location, amount_bought).into(); + + // Buy weight should return an error + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // not credited since the ED is higher than this value + assert_eq!(Assets::balance(1, AccountId::from(ALICE)), 0); + + // We also need to ensure the total supply did not increase + assert_eq!(Assets::total_supply(1), 0); + }); +} + +#[test] +fn test_that_buying_ed_refund_does_not_refund_for_take_first_trader() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + // We set existential deposit to be identical to the one for Balances first + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + true, + ExistentialDeposit::get() + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + let bought = Weight::from_parts(500_000_000u64, 0); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + let amount_bought = WeightToFee::weight_to_fee(&bought); + + assert!( + amount_bought < ExistentialDeposit::get(), + "we are testing what happens when the amount does not exceed ED" + ); + + // We know we will have to buy at least ED, so lets make sure first it will + // fail with a payment of less than ED + let asset: Asset = (asset_location.clone(), amount_bought).into(); + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // Now lets buy ED at least + let asset: Asset = (asset_location.clone(), ExistentialDeposit::get()).into(); + + // Buy weight should work + assert_ok!(trader.buy_weight(bought, asset.into(), &ctx)); + + // Should return None. We have a specific check making sure we dont go below ED for + // drop payment + assert_eq!(trader.refund_weight(bought, &ctx), None); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has received the amount + assert_eq!(Assets::balance(1, AccountId::from(ALICE)), ExistentialDeposit::get()); + + // We also need to ensure the total supply increased + assert_eq!(Assets::total_supply(1), ExistentialDeposit::get()); + }); +} + +#[test] +fn test_asset_xcm_take_first_trader_not_possible_for_non_sufficient_assets() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // Create a non-sufficient asset with specific existential deposit + let minimum_asset_balance = 1_000_000_u128; + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + false, + minimum_asset_balance + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(Assets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + 1.into(), + AccountId::from(ALICE).into(), + minimum_asset_balance + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 4e9 weight + let bought = Weight::from_parts(4_000_000_000u64, 0); + + // lets calculate amount needed + let asset_amount_needed = WeightToFee::weight_to_fee(&bought); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + let asset: Asset = (asset_location, asset_amount_needed).into(); + + // Make sure again buy_weight does return an error + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has NOT received the amount + assert_eq!(Assets::balance(1, AccountId::from(ALICE)), minimum_asset_balance); + + // We also need to ensure the total supply NOT increased + assert_eq!(Assets::total_supply(1), minimum_asset_balance); + }); +} + #[test] fn test_assets_balances_api_works() { use assets_common::runtime_api::runtime_decl_for_fungibles_api::FungiblesApi; -- GitLab From 0e124a05597b5575f79c90aae212fcf48a87e2ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 18 Jan 2024 18:28:19 +0100 Subject: [PATCH 077/392] pallet-contracts: Fix compilation on latest nightly (#2986) Apparently they changed detection for visibility identifiers on traits, which broke more than it should. There is an issue open: https://github.com/rust-lang/rust/issues/119924 The easy solution for us is to move the declaration of the global variable outside of the trait. Closes: https://github.com/paritytech/polkadot-sdk/issues/2960 --- substrate/frame/contracts/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/substrate/frame/contracts/src/lib.rs b/substrate/frame/contracts/src/lib.rs index a15006e6388..533085f2b87 100644 --- a/substrate/frame/contracts/src/lib.rs +++ b/substrate/frame/contracts/src/lib.rs @@ -1228,6 +1228,9 @@ struct InternalOutput { result: Result, } +// Set up a global reference to the boolean flag used for the re-entrancy guard. +environmental!(executing_contract: bool); + /// Helper trait to wrap contract execution entry points into a single function /// [`Invokable::run_guarded`]. trait Invokable: Sized { @@ -1243,9 +1246,6 @@ trait Invokable: Sized { /// We enforce a re-entrancy guard here by initializing and checking a boolean flag through a /// global reference. fn run_guarded(self, common: CommonInput) -> InternalOutput { - // Set up a global reference to the boolean flag used for the re-entrancy guard. - environmental!(executing_contract: bool); - let gas_limit = common.gas_limit; // Check whether the origin is allowed here. The logic of the access rules -- GitLab From b469960461f674995d75cedbeb514afaa7e20676 Mon Sep 17 00:00:00 2001 From: Andrei Sandu <54316454+sandreim@users.noreply.github.com> Date: Thu, 18 Jan 2024 19:28:55 +0200 Subject: [PATCH 078/392] approval-distribution: downgrade errors to debug (#2989) This is not actually an error of the node, but an issue with the incoming assignment. --------- Signed-off-by: Andrei Sandu --- polkadot/node/network/approval-distribution/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/polkadot/node/network/approval-distribution/src/lib.rs b/polkadot/node/network/approval-distribution/src/lib.rs index d520febaef5..184ccb6b042 100644 --- a/polkadot/node/network/approval-distribution/src/lib.rs +++ b/polkadot/node/network/approval-distribution/src/lib.rs @@ -2094,7 +2094,7 @@ impl State { // Punish the peer for the invalid message. modify_reputation(&mut self.reputation, sender, peer_id, COST_OVERSIZED_BITFIELD) .await; - gum::error!(target: LOG_TARGET, block_hash = ?cert.block_hash, ?candidate_index, validator_index = ?cert.validator, kind = ?cert.cert.kind, "Bad assignment v1"); + gum::debug!(target: LOG_TARGET, block_hash = ?cert.block_hash, ?candidate_index, validator_index = ?cert.validator, kind = ?cert.cert.kind, "Bad assignment v1, invalid candidate index"); } else { sanitized_assignments.push((cert.into(), candidate_index.into())) } @@ -2138,7 +2138,7 @@ impl State { modify_reputation(&mut self.reputation, sender, peer_id, COST_OVERSIZED_BITFIELD) .await; for candidate_index in candidate_bitfield.iter_ones() { - gum::error!(target: LOG_TARGET, block_hash = ?cert.block_hash, ?candidate_index, validator_index = ?cert.validator, "Bad assignment v2"); + gum::debug!(target: LOG_TARGET, block_hash = ?cert.block_hash, ?candidate_index, validator_index = ?cert.validator, "Bad assignment v2, oversized bitfield"); } } else { sanitized_assignments.push((cert, candidate_bitfield)) -- GitLab From f9bbe7db972c62e650ef732b36b05a55022671f6 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Thu, 18 Jan 2024 18:30:08 +0100 Subject: [PATCH 079/392] contracts: Update weights (#2969) As demanded by @athei to run benchmarks via CI. Somehow I was not able to push a PR without commits. --------- Co-authored-by: command-bot <> --- substrate/frame/contracts/src/weights.rs | 1348 +++++++++++----------- 1 file changed, 672 insertions(+), 676 deletions(-) diff --git a/substrate/frame/contracts/src/weights.rs b/substrate/frame/contracts/src/weights.rs index 22e4f749313..622d1e8a9b7 100644 --- a/substrate/frame/contracts/src/weights.rs +++ b/substrate/frame/contracts/src/weights.rs @@ -18,9 +18,9 @@ //! Autogenerated weights for `pallet_contracts` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-09-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-17, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-pzhd7p6z-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: @@ -141,8 +141,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 2_548_000 picoseconds. - Weight::from_parts(2_670_000, 1627) + // Minimum execution time: 1_991_000 picoseconds. + Weight::from_parts(2_135_000, 1627) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -150,12 +150,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `k` is `[0, 1024]`. fn on_initialize_per_trie_key(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `451 + k * (69 ±0)` - // Estimated: `441 + k * (70 ±0)` - // Minimum execution time: 13_526_000 picoseconds. - Weight::from_parts(13_902_000, 441) - // Standard Error: 1_058 - .saturating_add(Weight::from_parts(1_274_724, 0).saturating_mul(k.into())) + // Measured: `452 + k * (69 ±0)` + // Estimated: `442 + k * (70 ±0)` + // Minimum execution time: 11_969_000 picoseconds. + Weight::from_parts(7_055_855, 442) + // Standard Error: 2_328 + .saturating_add(Weight::from_parts(1_212_989, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(T::DbWeight::get().writes(2_u64)) @@ -169,10 +169,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `211 + c * (1 ±0)` // Estimated: `6149 + c * (1 ±0)` - // Minimum execution time: 8_426_000 picoseconds. - Weight::from_parts(8_591_621, 6149) + // Minimum execution time: 8_064_000 picoseconds. + Weight::from_parts(8_301_148, 6149) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_203, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(1_180, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -185,8 +185,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `510` // Estimated: `6450` - // Minimum execution time: 17_008_000 picoseconds. - Weight::from_parts(17_742_000, 6450) + // Minimum execution time: 15_789_000 picoseconds. + Weight::from_parts(16_850_000, 6450) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -199,10 +199,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `171 + k * (1 ±0)` // Estimated: `3635 + k * (1 ±0)` - // Minimum execution time: 3_949_000 picoseconds. - Weight::from_parts(4_062_000, 3635) - // Standard Error: 1_983 - .saturating_add(Weight::from_parts(1_173_197, 0).saturating_mul(k.into())) + // Minimum execution time: 3_369_000 picoseconds. + Weight::from_parts(3_516_000, 3635) + // Standard Error: 960 + .saturating_add(Weight::from_parts(1_139_317, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(k.into()))) @@ -221,10 +221,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `325 + c * (1 ±0)` // Estimated: `6263 + c * (1 ±0)` - // Minimum execution time: 17_094_000 picoseconds. - Weight::from_parts(17_338_591, 6263) + // Minimum execution time: 16_320_000 picoseconds. + Weight::from_parts(16_090_036, 6263) // Standard Error: 1 - .saturating_add(Weight::from_parts(436, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(417, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -235,8 +235,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `440` // Estimated: `6380` - // Minimum execution time: 12_704_000 picoseconds. - Weight::from_parts(13_147_000, 6380) + // Minimum execution time: 12_669_000 picoseconds. + Weight::from_parts(13_118_000, 6380) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -245,13 +245,13 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) fn v14_migration_step() -> Weight { // Proof Size summary in bytes: - // Measured: `360` - // Estimated: `6300` - // Minimum execution time: 48_387_000 picoseconds. - Weight::from_parts(50_024_000, 6300) + // Measured: `352` + // Estimated: `6292` + // Minimum execution time: 45_403_000 picoseconds. + Weight::from_parts(46_636_000, 6292) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -263,8 +263,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `594` // Estimated: `6534` - // Minimum execution time: 59_300_000 picoseconds. - Weight::from_parts(61_805_000, 6534) + // Minimum execution time: 53_622_000 picoseconds. + Weight::from_parts(55_444_000, 6534) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -274,8 +274,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 3_327_000 picoseconds. - Weight::from_parts(3_502_000, 1627) + // Minimum execution time: 2_444_000 picoseconds. + Weight::from_parts(2_587_000, 1627) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -287,8 +287,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `166` // Estimated: `3631` - // Minimum execution time: 12_759_000 picoseconds. - Weight::from_parts(13_134_000, 3631) + // Minimum execution time: 11_476_000 picoseconds. + Weight::from_parts(11_944_000, 3631) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -298,8 +298,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 4_775_000 picoseconds. - Weight::from_parts(5_084_000, 3607) + // Minimum execution time: 4_652_000 picoseconds. + Weight::from_parts(4_792_000, 3607) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -310,8 +310,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `167` // Estimated: `3632` - // Minimum execution time: 6_663_000 picoseconds. - Weight::from_parts(6_855_000, 3632) + // Minimum execution time: 6_054_000 picoseconds. + Weight::from_parts(6_278_000, 3632) .saturating_add(T::DbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -322,8 +322,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 7_212_000 picoseconds. - Weight::from_parts(7_426_000, 3607) + // Minimum execution time: 6_056_000 picoseconds. + Weight::from_parts(6_343_000, 3607) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -346,10 +346,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `792` // Estimated: `6743 + c * (1 ±0)` - // Minimum execution time: 289_557_000 picoseconds. - Weight::from_parts(272_895_652, 6743) - // Standard Error: 80 - .saturating_add(Weight::from_parts(39_917, 0).saturating_mul(c.into())) + // Minimum execution time: 303_205_000 picoseconds. + Weight::from_parts(266_154_889, 6743) + // Standard Error: 79 + .saturating_add(Weight::from_parts(35_195, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -359,7 +359,7 @@ impl WeightInfo for SubstrateWeight { /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:2 w:2) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `System::EventTopics` (r:3 w:3) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::Nonce` (r:1 w:1) @@ -379,14 +379,14 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `323` // Estimated: `8747` - // Minimum execution time: 4_671_359_000 picoseconds. - Weight::from_parts(586_523_882, 8747) - // Standard Error: 206 - .saturating_add(Weight::from_parts(115_402, 0).saturating_mul(c.into())) - // Standard Error: 24 - .saturating_add(Weight::from_parts(1_797, 0).saturating_mul(i.into())) - // Standard Error: 24 - .saturating_add(Weight::from_parts(2_046, 0).saturating_mul(s.into())) + // Minimum execution time: 4_311_802_000 picoseconds. + Weight::from_parts(777_467_048, 8747) + // Standard Error: 338 + .saturating_add(Weight::from_parts(105_862, 0).saturating_mul(c.into())) + // Standard Error: 40 + .saturating_add(Weight::from_parts(1_856, 0).saturating_mul(i.into())) + // Standard Error: 40 + .saturating_add(Weight::from_parts(1_443, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(10_u64)) } @@ -407,19 +407,19 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::EventTopics` (r:2 w:2) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// The range of component `i` is `[0, 1048576]`. /// The range of component `s` is `[0, 1048576]`. fn instantiate(i: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `560` // Estimated: `6504` - // Minimum execution time: 2_170_657_000 picoseconds. - Weight::from_parts(369_331_405, 6504) - // Standard Error: 7 - .saturating_add(Weight::from_parts(1_940, 0).saturating_mul(i.into())) - // Standard Error: 7 - .saturating_add(Weight::from_parts(1_858, 0).saturating_mul(s.into())) + // Minimum execution time: 1_958_694_000 picoseconds. + Weight::from_parts(331_222_273, 6504) + // Standard Error: 13 + .saturating_add(Weight::from_parts(1_954, 0).saturating_mul(i.into())) + // Standard Error: 13 + .saturating_add(Weight::from_parts(1_685, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(10_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } @@ -441,8 +441,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `826` // Estimated: `6766` - // Minimum execution time: 204_287_000 picoseconds. - Weight::from_parts(213_239_000, 6766) + // Minimum execution time: 194_513_000 picoseconds. + Weight::from_parts(201_116_000, 6766) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -451,7 +451,7 @@ impl WeightInfo for SubstrateWeight { /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `System::EventTopics` (r:1 w:1) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:0 w:1) @@ -461,10 +461,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 285_434_000 picoseconds. - Weight::from_parts(242_697_648, 3607) - // Standard Error: 128 - .saturating_add(Weight::from_parts(76_087, 0).saturating_mul(c.into())) + // Minimum execution time: 269_777_000 picoseconds. + Weight::from_parts(204_229_027, 3607) + // Standard Error: 152 + .saturating_add(Weight::from_parts(72_184, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -473,7 +473,7 @@ impl WeightInfo for SubstrateWeight { /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `System::EventTopics` (r:1 w:1) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:0 w:1) @@ -482,8 +482,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `315` // Estimated: `3780` - // Minimum execution time: 46_486_000 picoseconds. - Weight::from_parts(48_422_000, 3780) + // Minimum execution time: 43_271_000 picoseconds. + Weight::from_parts(44_884_000, 3780) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -499,8 +499,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `552` // Estimated: `8967` - // Minimum execution time: 37_568_000 picoseconds. - Weight::from_parts(38_589_000, 8967) + // Minimum execution time: 34_635_000 picoseconds. + Weight::from_parts(35_477_000, 8967) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -523,10 +523,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `866 + r * (6 ±0)` // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 274_513_000 picoseconds. - Weight::from_parts(288_793_403, 6806) - // Standard Error: 650 - .saturating_add(Weight::from_parts(339_309, 0).saturating_mul(r.into())) + // Minimum execution time: 266_757_000 picoseconds. + Weight::from_parts(279_787_352, 6806) + // Standard Error: 812 + .saturating_add(Weight::from_parts(329_166, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -550,10 +550,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `922 + r * (209 ±0)` // Estimated: `6826 + r * (2684 ±0)` - // Minimum execution time: 260_096_000 picoseconds. - Weight::from_parts(149_954_322, 6826) - // Standard Error: 5_713 - .saturating_add(Weight::from_parts(3_788_924, 0).saturating_mul(r.into())) + // Minimum execution time: 266_442_000 picoseconds. + Weight::from_parts(86_660_390, 6826) + // Standard Error: 9_194 + .saturating_add(Weight::from_parts(3_744_648, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -578,10 +578,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `921 + r * (213 ±0)` // Estimated: `6830 + r * (2688 ±0)` - // Minimum execution time: 277_496_000 picoseconds. - Weight::from_parts(285_839_000, 6830) - // Standard Error: 10_076 - .saturating_add(Weight::from_parts(4_720_110, 0).saturating_mul(r.into())) + // Minimum execution time: 265_608_000 picoseconds. + Weight::from_parts(273_219_000, 6830) + // Standard Error: 11_085 + .saturating_add(Weight::from_parts(4_542_778, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -606,10 +606,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `873 + r * (6 ±0)` // Estimated: `6815 + r * (6 ±0)` - // Minimum execution time: 275_655_000 picoseconds. - Weight::from_parts(291_386_528, 6815) - // Standard Error: 898 - .saturating_add(Weight::from_parts(428_765, 0).saturating_mul(r.into())) + // Minimum execution time: 270_033_000 picoseconds. + Weight::from_parts(288_700_795, 6815) + // Standard Error: 1_628 + .saturating_add(Weight::from_parts(428_991, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -633,10 +633,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863 + r * (3 ±0)` // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 260_323_000 picoseconds. - Weight::from_parts(286_371_403, 6804) - // Standard Error: 451 - .saturating_add(Weight::from_parts(183_053, 0).saturating_mul(r.into())) + // Minimum execution time: 263_789_000 picoseconds. + Weight::from_parts(275_806_968, 6804) + // Standard Error: 936 + .saturating_add(Weight::from_parts(182_805, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -658,10 +658,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `753 + r * (3 ±0)` // Estimated: `6693 + r * (3 ±0)` - // Minimum execution time: 262_974_000 picoseconds. - Weight::from_parts(276_571_502, 6693) - // Standard Error: 527 - .saturating_add(Weight::from_parts(165_364, 0).saturating_mul(r.into())) + // Minimum execution time: 257_922_000 picoseconds. + Weight::from_parts(270_842_153, 6693) + // Standard Error: 637 + .saturating_add(Weight::from_parts(156_567, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -685,10 +685,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `867 + r * (6 ±0)` // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 272_826_000 picoseconds. - Weight::from_parts(290_963_001, 6807) - // Standard Error: 810 - .saturating_add(Weight::from_parts(343_762, 0).saturating_mul(r.into())) + // Minimum execution time: 267_214_000 picoseconds. + Weight::from_parts(273_446_444, 6807) + // Standard Error: 2_355 + .saturating_add(Weight::from_parts(356_663, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -712,10 +712,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863 + r * (6 ±0)` // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 277_324_000 picoseconds. - Weight::from_parts(290_872_814, 6806) - // Standard Error: 766 - .saturating_add(Weight::from_parts(371_542, 0).saturating_mul(r.into())) + // Minimum execution time: 258_860_000 picoseconds. + Weight::from_parts(286_389_737, 6806) + // Standard Error: 1_707 + .saturating_add(Weight::from_parts(366_148, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -739,10 +739,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1007 + r * (6 ±0)` // Estimated: `6931 + r * (6 ±0)` - // Minimum execution time: 274_460_000 picoseconds. - Weight::from_parts(285_748_025, 6931) - // Standard Error: 1_570 - .saturating_add(Weight::from_parts(1_656_237, 0).saturating_mul(r.into())) + // Minimum execution time: 267_852_000 picoseconds. + Weight::from_parts(279_617_620, 6931) + // Standard Error: 3_382 + .saturating_add(Weight::from_parts(1_586_170, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -766,10 +766,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `877 + r * (6 ±0)` // Estimated: `6823 + r * (6 ±0)` - // Minimum execution time: 278_254_000 picoseconds. - Weight::from_parts(283_893_525, 6823) - // Standard Error: 726 - .saturating_add(Weight::from_parts(347_368, 0).saturating_mul(r.into())) + // Minimum execution time: 266_379_000 picoseconds. + Weight::from_parts(287_280_653, 6823) + // Standard Error: 1_774 + .saturating_add(Weight::from_parts(323_724, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -793,10 +793,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `875 + r * (6 ±0)` // Estimated: `6816 + r * (6 ±0)` - // Minimum execution time: 279_646_000 picoseconds. - Weight::from_parts(292_505_446, 6816) - // Standard Error: 867 - .saturating_add(Weight::from_parts(337_202, 0).saturating_mul(r.into())) + // Minimum execution time: 266_417_000 picoseconds. + Weight::from_parts(291_394_038, 6816) + // Standard Error: 1_474 + .saturating_add(Weight::from_parts(328_306, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -820,10 +820,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `872 + r * (6 ±0)` // Estimated: `6819 + r * (6 ±0)` - // Minimum execution time: 274_522_000 picoseconds. - Weight::from_parts(295_135_659, 6819) - // Standard Error: 1_052 - .saturating_add(Weight::from_parts(330_788, 0).saturating_mul(r.into())) + // Minimum execution time: 269_198_000 picoseconds. + Weight::from_parts(285_025_368, 6819) + // Standard Error: 1_231 + .saturating_add(Weight::from_parts(324_814, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -847,10 +847,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863 + r * (6 ±0)` // Estimated: `6804 + r * (6 ±0)` - // Minimum execution time: 274_228_000 picoseconds. - Weight::from_parts(289_201_593, 6804) - // Standard Error: 752 - .saturating_add(Weight::from_parts(337_860, 0).saturating_mul(r.into())) + // Minimum execution time: 257_514_000 picoseconds. + Weight::from_parts(280_424_571, 6804) + // Standard Error: 723 + .saturating_add(Weight::from_parts(325_607, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -876,10 +876,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `937 + r * (14 ±0)` // Estimated: `6872 + r * (14 ±0)` - // Minimum execution time: 277_142_000 picoseconds. - Weight::from_parts(296_736_114, 6872) - // Standard Error: 1_502 - .saturating_add(Weight::from_parts(1_446_663, 0).saturating_mul(r.into())) + // Minimum execution time: 268_221_000 picoseconds. + Weight::from_parts(282_273_629, 6872) + // Standard Error: 2_398 + .saturating_add(Weight::from_parts(1_117_278, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 14).saturating_mul(r.into())) @@ -903,10 +903,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `865 + r * (6 ±0)` // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 276_087_000 picoseconds. - Weight::from_parts(287_863_377, 6807) - // Standard Error: 495 - .saturating_add(Weight::from_parts(282_718, 0).saturating_mul(r.into())) + // Minimum execution time: 271_541_000 picoseconds. + Weight::from_parts(276_996_569, 6807) + // Standard Error: 1_462 + .saturating_add(Weight::from_parts(282_119, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -930,10 +930,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `869` // Estimated: `6809` - // Minimum execution time: 277_128_000 picoseconds. - Weight::from_parts(234_478_674, 6809) - // Standard Error: 23 - .saturating_add(Weight::from_parts(1_052, 0).saturating_mul(n.into())) + // Minimum execution time: 256_410_000 picoseconds. + Weight::from_parts(206_888_877, 6809) + // Standard Error: 22 + .saturating_add(Weight::from_parts(1_154, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -956,8 +956,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `853 + r * (45 ±0)` // Estimated: `6793 + r * (45 ±0)` - // Minimum execution time: 251_983_000 picoseconds. - Weight::from_parts(277_986_885, 6793) + // Minimum execution time: 248_852_000 picoseconds. + Weight::from_parts(277_852_834, 6793) + // Standard Error: 1_257_219 + .saturating_add(Weight::from_parts(1_394_065, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 45).saturating_mul(r.into())) @@ -981,10 +983,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863` // Estimated: `6810` - // Minimum execution time: 275_108_000 picoseconds. - Weight::from_parts(284_552_708, 6810) - // Standard Error: 0 - .saturating_add(Weight::from_parts(391, 0).saturating_mul(n.into())) + // Minimum execution time: 269_101_000 picoseconds. + Weight::from_parts(273_407_545, 6810) + // Standard Error: 2 + .saturating_add(Weight::from_parts(339, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1005,7 +1007,7 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::EventTopics` (r:4 w:4) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `Contracts::DeletionQueue` (r:0 w:1) /// Proof: `Contracts::DeletionQueue` (`max_values`: None, `max_size`: Some(142), added: 2617, mode: `Measured`) /// The range of component `r` is `[0, 1]`. @@ -1013,10 +1015,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2972 + r * (316 ±0)` // Estimated: `8912 + r * (5266 ±0)` - // Minimum execution time: 281_278_000 picoseconds. - Weight::from_parts(306_800_667, 8912) - // Standard Error: 855_257 - .saturating_add(Weight::from_parts(126_508_132, 0).saturating_mul(r.into())) + // Minimum execution time: 296_318_000 picoseconds. + Weight::from_parts(322_448_344, 8912) + // Standard Error: 2_358_838 + .saturating_add(Weight::from_parts(107_092_455, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((7_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1044,10 +1046,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `944 + r * (10 ±0)` // Estimated: `6885 + r * (10 ±0)` - // Minimum execution time: 260_609_000 picoseconds. - Weight::from_parts(287_385_076, 6885) - // Standard Error: 2_754 - .saturating_add(Weight::from_parts(2_057_388, 0).saturating_mul(r.into())) + // Minimum execution time: 268_264_000 picoseconds. + Weight::from_parts(285_298_853, 6885) + // Standard Error: 3_238 + .saturating_add(Weight::from_parts(1_238_513, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -1071,10 +1073,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863 + r * (10 ±0)` // Estimated: `6805 + r * (10 ±0)` - // Minimum execution time: 254_770_000 picoseconds. - Weight::from_parts(255_105_647, 6805) - // Standard Error: 5_707 - .saturating_add(Weight::from_parts(3_808_788, 0).saturating_mul(r.into())) + // Minimum execution time: 267_417_000 picoseconds. + Weight::from_parts(290_097_452, 6805) + // Standard Error: 2_523 + .saturating_add(Weight::from_parts(2_012_375, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -1099,12 +1101,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `880 + t * (32 ±0)` // Estimated: `6825 + t * (2508 ±0)` - // Minimum execution time: 278_200_000 picoseconds. - Weight::from_parts(288_081_493, 6825) - // Standard Error: 97_535 - .saturating_add(Weight::from_parts(3_683_455, 0).saturating_mul(t.into())) - // Standard Error: 27 - .saturating_add(Weight::from_parts(731, 0).saturating_mul(n.into())) + // Minimum execution time: 269_735_000 picoseconds. + Weight::from_parts(291_680_757, 6825) + // Standard Error: 196_822 + .saturating_add(Weight::from_parts(2_827_797, 0).saturating_mul(t.into())) + // Standard Error: 55 + .saturating_add(Weight::from_parts(262, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1130,10 +1132,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `862 + r * (7 ±0)` // Estimated: `6807 + r * (7 ±0)` - // Minimum execution time: 167_181_000 picoseconds. - Weight::from_parts(178_433_475, 6807) - // Standard Error: 374 - .saturating_add(Weight::from_parts(241_240, 0).saturating_mul(r.into())) + // Minimum execution time: 161_454_000 picoseconds. + Weight::from_parts(181_662_272, 6807) + // Standard Error: 729 + .saturating_add(Weight::from_parts(221_968, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 7).saturating_mul(r.into())) @@ -1157,10 +1159,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `125813` // Estimated: `131755` - // Minimum execution time: 434_456_000 picoseconds. - Weight::from_parts(400_940_450, 131755) - // Standard Error: 13 - .saturating_add(Weight::from_parts(1_102, 0).saturating_mul(i.into())) + // Minimum execution time: 418_479_000 picoseconds. + Weight::from_parts(397_691_558, 131755) + // Standard Error: 12 + .saturating_add(Weight::from_parts(1_099, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1170,11 +1172,11 @@ impl WeightInfo for SubstrateWeight { fn seal_set_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `924 + r * (292 ±0)` - // Estimated: `925 + r * (293 ±0)` - // Minimum execution time: 277_825_000 picoseconds. - Weight::from_parts(159_688_263, 925) - // Standard Error: 13_610 - .saturating_add(Weight::from_parts(7_145_641, 0).saturating_mul(r.into())) + // Estimated: `926 + r * (293 ±0)` + // Minimum execution time: 268_810_000 picoseconds. + Weight::from_parts(129_545_478, 926) + // Standard Error: 21_173 + .saturating_add(Weight::from_parts(7_118_874, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1186,12 +1188,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 16384]`. fn seal_set_storage_per_new_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1446` - // Estimated: `1429` - // Minimum execution time: 284_745_000 picoseconds. - Weight::from_parts(345_928_316, 1429) - // Standard Error: 70 - .saturating_add(Weight::from_parts(547, 0).saturating_mul(n.into())) + // Measured: `1447` + // Estimated: `1430` + // Minimum execution time: 286_965_000 picoseconds. + Weight::from_parts(340_396_510, 1430) + // Standard Error: 90 + .saturating_add(Weight::from_parts(455, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(8_u64)) } @@ -1200,12 +1202,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 16384]`. fn seal_set_storage_per_old_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1252 + n * (1 ±0)` - // Estimated: `1252 + n * (1 ±0)` - // Minimum execution time: 275_328_000 picoseconds. - Weight::from_parts(300_037_010, 1252) - // Standard Error: 32 - .saturating_add(Weight::from_parts(558, 0).saturating_mul(n.into())) + // Measured: `1253 + n * (1 ±0)` + // Estimated: `1253 + n * (1 ±0)` + // Minimum execution time: 272_395_000 picoseconds. + Weight::from_parts(302_307_069, 1253) + // Standard Error: 94 + .saturating_add(Weight::from_parts(156, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1215,12 +1217,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 800]`. fn seal_clear_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `920 + r * (288 ±0)` - // Estimated: `926 + r * (289 ±0)` - // Minimum execution time: 273_742_000 picoseconds. - Weight::from_parts(169_430_806, 926) - // Standard Error: 11_821 - .saturating_add(Weight::from_parts(6_927_074, 0).saturating_mul(r.into())) + // Measured: `921 + r * (288 ±0)` + // Estimated: `927 + r * (289 ±0)` + // Minimum execution time: 269_165_000 picoseconds. + Weight::from_parts(167_174_485, 927) + // Standard Error: 23_564 + .saturating_add(Weight::from_parts(6_921_525, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1232,12 +1234,10 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 16384]`. fn seal_clear_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1248 + n * (1 ±0)` - // Estimated: `1248 + n * (1 ±0)` - // Minimum execution time: 275_167_000 picoseconds. - Weight::from_parts(301_883_655, 1248) - // Standard Error: 35 - .saturating_add(Weight::from_parts(4, 0).saturating_mul(n.into())) + // Measured: `1249 + n * (1 ±0)` + // Estimated: `1249 + n * (1 ±0)` + // Minimum execution time: 270_248_000 picoseconds. + Weight::from_parts(296_573_310, 1249) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1247,12 +1247,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 800]`. fn seal_get_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `920 + r * (296 ±0)` - // Estimated: `922 + r * (297 ±0)` - // Minimum execution time: 274_628_000 picoseconds. - Weight::from_parts(195_255_092, 922) - // Standard Error: 9_109 - .saturating_add(Weight::from_parts(5_707_060, 0).saturating_mul(r.into())) + // Measured: `921 + r * (296 ±0)` + // Estimated: `923 + r * (297 ±0)` + // Minimum execution time: 270_883_000 picoseconds. + Weight::from_parts(189_792_705, 923) + // Standard Error: 11_149 + .saturating_add(Weight::from_parts(5_232_100, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1263,12 +1263,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 16384]`. fn seal_get_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1264 + n * (1 ±0)` - // Estimated: `1264 + n * (1 ±0)` - // Minimum execution time: 274_202_000 picoseconds. - Weight::from_parts(296_440_752, 1264) - // Standard Error: 38 - .saturating_add(Weight::from_parts(1_010, 0).saturating_mul(n.into())) + // Measured: `1265 + n * (1 ±0)` + // Estimated: `1265 + n * (1 ±0)` + // Minimum execution time: 263_833_000 picoseconds. + Weight::from_parts(290_179_222, 1265) + // Standard Error: 44 + .saturating_add(Weight::from_parts(831, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1278,12 +1278,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 800]`. fn seal_contains_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `931 + r * (288 ±0)` - // Estimated: `928 + r * (289 ±0)` - // Minimum execution time: 274_123_000 picoseconds. - Weight::from_parts(193_280_535, 928) - // Standard Error: 9_264 - .saturating_add(Weight::from_parts(5_548_039, 0).saturating_mul(r.into())) + // Measured: `932 + r * (288 ±0)` + // Estimated: `929 + r * (289 ±0)` + // Minimum execution time: 252_637_000 picoseconds. + Weight::from_parts(98_108_825, 929) + // Standard Error: 23_580 + .saturating_add(Weight::from_parts(5_408_076, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1294,12 +1294,10 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 16384]`. fn seal_contains_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1251 + n * (1 ±0)` - // Estimated: `1251 + n * (1 ±0)` - // Minimum execution time: 276_425_000 picoseconds. - Weight::from_parts(300_521_806, 1251) - // Standard Error: 36 - .saturating_add(Weight::from_parts(83, 0).saturating_mul(n.into())) + // Measured: `1252 + n * (1 ±0)` + // Estimated: `1252 + n * (1 ±0)` + // Minimum execution time: 279_133_000 picoseconds. + Weight::from_parts(301_192_115, 1252) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1309,12 +1307,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 800]`. fn seal_take_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `913 + r * (296 ±0)` - // Estimated: `918 + r * (297 ±0)` - // Minimum execution time: 264_860_000 picoseconds. - Weight::from_parts(191_561_777, 918) - // Standard Error: 10_678 - .saturating_add(Weight::from_parts(6_895_457, 0).saturating_mul(r.into())) + // Measured: `914 + r * (296 ±0)` + // Estimated: `919 + r * (297 ±0)` + // Minimum execution time: 268_833_000 picoseconds. + Weight::from_parts(56_229_951, 919) + // Standard Error: 25_800 + .saturating_add(Weight::from_parts(7_607_143, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1326,12 +1324,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 16384]`. fn seal_take_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1265 + n * (1 ±0)` - // Estimated: `1265 + n * (1 ±0)` - // Minimum execution time: 282_501_000 picoseconds. - Weight::from_parts(303_351_919, 1265) - // Standard Error: 37 - .saturating_add(Weight::from_parts(643, 0).saturating_mul(n.into())) + // Measured: `1266 + n * (1 ±0)` + // Estimated: `1266 + n * (1 ±0)` + // Minimum execution time: 288_677_000 picoseconds. + Weight::from_parts(301_986_360, 1266) + // Standard Error: 39 + .saturating_add(Weight::from_parts(867, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1355,10 +1353,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1415 + r * (45 ±0)` // Estimated: `7307 + r * (2520 ±0)` - // Minimum execution time: 273_198_000 picoseconds. - Weight::from_parts(179_673_238, 7307) - // Standard Error: 34_990 - .saturating_add(Weight::from_parts(38_468_091, 0).saturating_mul(r.into())) + // Minimum execution time: 275_956_000 picoseconds. + Weight::from_parts(280_865_651, 7307) + // Standard Error: 28_235 + .saturating_add(Weight::from_parts(32_233_352, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) @@ -1384,10 +1382,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1260 + r * (245 ±0)` // Estimated: `9440 + r * (2721 ±0)` - // Minimum execution time: 283_869_000 picoseconds. - Weight::from_parts(288_374_000, 9440) - // Standard Error: 137_512 - .saturating_add(Weight::from_parts(248_206_665, 0).saturating_mul(r.into())) + // Minimum execution time: 269_188_000 picoseconds. + Weight::from_parts(276_038_000, 9440) + // Standard Error: 262_029 + .saturating_add(Weight::from_parts(250_766_832, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) @@ -1413,10 +1411,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0 + r * (576 ±0)` // Estimated: `6812 + r * (2637 ±3)` - // Minimum execution time: 257_577_000 picoseconds. - Weight::from_parts(277_310_000, 6812) - // Standard Error: 150_204 - .saturating_add(Weight::from_parts(249_943_483, 0).saturating_mul(r.into())) + // Minimum execution time: 267_543_000 picoseconds. + Weight::from_parts(271_365_000, 6812) + // Standard Error: 190_454 + .saturating_add(Weight::from_parts(242_627_807, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1443,12 +1441,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1307 + t * (277 ±0)` // Estimated: `12197 + t * (5227 ±0)` - // Minimum execution time: 471_081_000 picoseconds. - Weight::from_parts(79_081_122, 12197) - // Standard Error: 11_777_790 - .saturating_add(Weight::from_parts(357_425_411, 0).saturating_mul(t.into())) + // Minimum execution time: 453_215_000 picoseconds. + Weight::from_parts(32_029_330, 12197) + // Standard Error: 12_154_174 + .saturating_add(Weight::from_parts(392_862_355, 0).saturating_mul(t.into())) // Standard Error: 17 - .saturating_add(Weight::from_parts(1_111, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(1_059, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(13_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(6_u64)) @@ -1472,16 +1470,16 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::EventTopics` (r:803 w:803) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:800 w:800) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// The range of component `r` is `[1, 800]`. fn seal_instantiate(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `1278 + r * (255 ±0)` // Estimated: `9620 + r * (2731 ±0)` - // Minimum execution time: 672_742_000 picoseconds. - Weight::from_parts(680_025_000, 9620) - // Standard Error: 313_642 - .saturating_add(Weight::from_parts(388_311_259, 0).saturating_mul(r.into())) + // Minimum execution time: 635_304_000 picoseconds. + Weight::from_parts(645_872_000, 9620) + // Standard Error: 356_713 + .saturating_add(Weight::from_parts(371_999_658, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(7_u64)) @@ -1505,7 +1503,7 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::EventTopics` (r:4 w:4) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// The range of component `t` is `[0, 1]`. /// The range of component `i` is `[0, 983040]`. /// The range of component `s` is `[0, 983040]`. @@ -1513,12 +1511,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1303 + t * (104 ±0)` // Estimated: `12211 + t * (2549 ±1)` - // Minimum execution time: 2_733_870_000 picoseconds. - Weight::from_parts(1_001_793_458, 12211) - // Standard Error: 12 - .saturating_add(Weight::from_parts(1_963, 0).saturating_mul(i.into())) - // Standard Error: 12 - .saturating_add(Weight::from_parts(2_060, 0).saturating_mul(s.into())) + // Minimum execution time: 2_225_692_000 picoseconds. + Weight::from_parts(1_292_861_603, 12211) + // Standard Error: 24 + .saturating_add(Weight::from_parts(1_075, 0).saturating_mul(i.into())) + // Standard Error: 24 + .saturating_add(Weight::from_parts(1_278, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(16_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(11_u64)) @@ -1544,10 +1542,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `862 + r * (8 ±0)` // Estimated: `6801 + r * (8 ±0)` - // Minimum execution time: 272_658_000 picoseconds. - Weight::from_parts(282_717_645, 6801) - // Standard Error: 517 - .saturating_add(Weight::from_parts(400_604, 0).saturating_mul(r.into())) + // Minimum execution time: 252_664_000 picoseconds. + Weight::from_parts(277_967_331, 6801) + // Standard Error: 723 + .saturating_add(Weight::from_parts(370_111, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1571,10 +1569,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `870` // Estimated: `6808` - // Minimum execution time: 260_969_000 picoseconds. - Weight::from_parts(265_206_847, 6808) + // Minimum execution time: 252_485_000 picoseconds. + Weight::from_parts(259_271_531, 6808) // Standard Error: 2 - .saturating_add(Weight::from_parts(1_134, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_091, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1597,10 +1595,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6806 + r * (8 ±0)` - // Minimum execution time: 262_351_000 picoseconds. - Weight::from_parts(286_974_296, 6806) - // Standard Error: 514 - .saturating_add(Weight::from_parts(802_363, 0).saturating_mul(r.into())) + // Minimum execution time: 249_270_000 picoseconds. + Weight::from_parts(272_528_711, 6806) + // Standard Error: 903 + .saturating_add(Weight::from_parts(793_299, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1624,10 +1622,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6814` - // Minimum execution time: 276_907_000 picoseconds. - Weight::from_parts(277_928_418, 6814) - // Standard Error: 1 - .saturating_add(Weight::from_parts(3_410, 0).saturating_mul(n.into())) + // Minimum execution time: 249_470_000 picoseconds. + Weight::from_parts(273_317_815, 6814) + // Standard Error: 4 + .saturating_add(Weight::from_parts(3_400, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1650,10 +1648,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6808 + r * (8 ±0)` - // Minimum execution time: 263_660_000 picoseconds. - Weight::from_parts(285_665_916, 6808) - // Standard Error: 527 - .saturating_add(Weight::from_parts(480_457, 0).saturating_mul(r.into())) + // Minimum execution time: 265_503_000 picoseconds. + Weight::from_parts(279_774_666, 6808) + // Standard Error: 1_351 + .saturating_add(Weight::from_parts(439_734, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1677,10 +1675,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6813` - // Minimum execution time: 262_071_000 picoseconds. - Weight::from_parts(270_115_341, 6813) + // Minimum execution time: 265_009_000 picoseconds. + Weight::from_parts(270_467_968, 6813) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_254, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_206, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1703,10 +1701,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6805 + r * (8 ±0)` - // Minimum execution time: 265_568_000 picoseconds. - Weight::from_parts(285_791_811, 6805) - // Standard Error: 559 - .saturating_add(Weight::from_parts(505_330, 0).saturating_mul(r.into())) + // Minimum execution time: 251_771_000 picoseconds. + Weight::from_parts(283_553_523, 6805) + // Standard Error: 1_053 + .saturating_add(Weight::from_parts(445_715, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1730,10 +1728,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6811` - // Minimum execution time: 271_336_000 picoseconds. - Weight::from_parts(272_829_313, 6811) - // Standard Error: 0 - .saturating_add(Weight::from_parts(1_252, 0).saturating_mul(n.into())) + // Minimum execution time: 253_733_000 picoseconds. + Weight::from_parts(264_277_000, 6811) + // Standard Error: 3 + .saturating_add(Weight::from_parts(1_226, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1756,10 +1754,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `997 + n * (1 ±0)` // Estimated: `6934 + n * (1 ±0)` - // Minimum execution time: 351_146_000 picoseconds. - Weight::from_parts(355_368_323, 6934) - // Standard Error: 14 - .saturating_add(Weight::from_parts(6_155, 0).saturating_mul(n.into())) + // Minimum execution time: 337_326_000 picoseconds. + Weight::from_parts(346_340_758, 6934) + // Standard Error: 18 + .saturating_add(Weight::from_parts(6_110, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1781,12 +1779,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 160]`. fn seal_sr25519_verify(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `807 + r * (112 ±0)` + // Measured: `805 + r * (112 ±0)` // Estimated: `6748 + r * (112 ±0)` - // Minimum execution time: 277_250_000 picoseconds. - Weight::from_parts(346_490_114, 6748) - // Standard Error: 14_654 - .saturating_add(Weight::from_parts(56_127_492, 0).saturating_mul(r.into())) + // Minimum execution time: 253_852_000 picoseconds. + Weight::from_parts(335_731_679, 6748) + // Standard Error: 13_615 + .saturating_add(Weight::from_parts(41_557_258, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(r.into())) @@ -1810,10 +1808,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `907 + r * (76 ±0)` // Estimated: `6801 + r * (77 ±0)` - // Minimum execution time: 272_697_000 picoseconds. - Weight::from_parts(345_385_667, 6801) - // Standard Error: 14_226 - .saturating_add(Weight::from_parts(46_037_637, 0).saturating_mul(r.into())) + // Minimum execution time: 256_283_000 picoseconds. + Weight::from_parts(338_634_113, 6801) + // Standard Error: 43_436 + .saturating_add(Weight::from_parts(46_607_112, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 77).saturating_mul(r.into())) @@ -1837,10 +1835,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `877 + r * (42 ±0)` // Estimated: `6816 + r * (42 ±0)` - // Minimum execution time: 271_800_000 picoseconds. - Weight::from_parts(314_891_136, 6816) - // Standard Error: 9_762 - .saturating_add(Weight::from_parts(11_949_979, 0).saturating_mul(r.into())) + // Minimum execution time: 269_144_000 picoseconds. + Weight::from_parts(331_790_138, 6816) + // Standard Error: 23_357 + .saturating_add(Weight::from_parts(12_213_638, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 42).saturating_mul(r.into())) @@ -1864,10 +1862,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0 + r * (965 ±0)` // Estimated: `6807 + r * (3090 ±10)` - // Minimum execution time: 274_238_000 picoseconds. - Weight::from_parts(278_034_000, 6807) - // Standard Error: 77_011 - .saturating_add(Weight::from_parts(27_627_005, 0).saturating_mul(r.into())) + // Minimum execution time: 262_624_000 picoseconds. + Weight::from_parts(275_865_000, 6807) + // Standard Error: 64_162 + .saturating_add(Weight::from_parts(26_205_387, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1893,10 +1891,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `928 + r * (131 ±0)` // Estimated: `6878 + r * (2606 ±0)` - // Minimum execution time: 271_519_000 picoseconds. - Weight::from_parts(292_726_476, 6878) - // Standard Error: 23_870 - .saturating_add(Weight::from_parts(6_695_172, 0).saturating_mul(r.into())) + // Minimum execution time: 265_482_000 picoseconds. + Weight::from_parts(296_491_925, 6878) + // Standard Error: 46_681 + .saturating_add(Weight::from_parts(6_572_162, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1922,10 +1920,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `969 + r * (183 ±0)` // Estimated: `129453 + r * (2568 ±0)` - // Minimum execution time: 274_675_000 picoseconds. - Weight::from_parts(293_727_489, 129453) - // Standard Error: 23_160 - .saturating_add(Weight::from_parts(5_895_043, 0).saturating_mul(r.into())) + // Minimum execution time: 257_532_000 picoseconds. + Weight::from_parts(299_110_930, 129453) + // Standard Error: 55_003 + .saturating_add(Weight::from_parts(6_130_357, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1951,10 +1949,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `858 + r * (3 ±0)` // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 253_330_000 picoseconds. - Weight::from_parts(281_079_564, 6804) - // Standard Error: 378 - .saturating_add(Weight::from_parts(180_655, 0).saturating_mul(r.into())) + // Minimum execution time: 268_894_000 picoseconds. + Weight::from_parts(287_048_741, 6804) + // Standard Error: 1_156 + .saturating_add(Weight::from_parts(172_596, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -1978,10 +1976,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2109 + r * (39 ±0)` // Estimated: `7899 + r * (40 ±0)` - // Minimum execution time: 276_552_000 picoseconds. - Weight::from_parts(368_521_088, 7899) - // Standard Error: 2_310 - .saturating_add(Weight::from_parts(318_129, 0).saturating_mul(r.into())) + // Minimum execution time: 262_736_000 picoseconds. + Weight::from_parts(389_199_672, 7899) + // Standard Error: 2_646 + .saturating_add(Weight::from_parts(290_309, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) @@ -2007,10 +2005,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `861 + r * (3 ±0)` // Estimated: `6801 + r * (3 ±0)` - // Minimum execution time: 258_953_000 picoseconds. - Weight::from_parts(288_222_836, 6801) - // Standard Error: 367 - .saturating_add(Weight::from_parts(152_842, 0).saturating_mul(r.into())) + // Minimum execution time: 253_465_000 picoseconds. + Weight::from_parts(283_153_874, 6801) + // Standard Error: 745 + .saturating_add(Weight::from_parts(148_864, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -2020,10 +2018,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_476_000 picoseconds. - Weight::from_parts(2_119_717, 0) - // Standard Error: 28 - .saturating_add(Weight::from_parts(9_805, 0).saturating_mul(r.into())) + // Minimum execution time: 1_342_000 picoseconds. + Weight::from_parts(1_940_100, 0) + // Standard Error: 21 + .saturating_add(Weight::from_parts(11_117, 0).saturating_mul(r.into())) } } @@ -2035,8 +2033,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 2_548_000 picoseconds. - Weight::from_parts(2_670_000, 1627) + // Minimum execution time: 1_991_000 picoseconds. + Weight::from_parts(2_135_000, 1627) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -2044,12 +2042,12 @@ impl WeightInfo for () { /// The range of component `k` is `[0, 1024]`. fn on_initialize_per_trie_key(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `451 + k * (69 ±0)` - // Estimated: `441 + k * (70 ±0)` - // Minimum execution time: 13_526_000 picoseconds. - Weight::from_parts(13_902_000, 441) - // Standard Error: 1_058 - .saturating_add(Weight::from_parts(1_274_724, 0).saturating_mul(k.into())) + // Measured: `452 + k * (69 ±0)` + // Estimated: `442 + k * (70 ±0)` + // Minimum execution time: 11_969_000 picoseconds. + Weight::from_parts(7_055_855, 442) + // Standard Error: 2_328 + .saturating_add(Weight::from_parts(1_212_989, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(RocksDbWeight::get().writes(2_u64)) @@ -2063,10 +2061,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `211 + c * (1 ±0)` // Estimated: `6149 + c * (1 ±0)` - // Minimum execution time: 8_426_000 picoseconds. - Weight::from_parts(8_591_621, 6149) + // Minimum execution time: 8_064_000 picoseconds. + Weight::from_parts(8_301_148, 6149) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_203, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(1_180, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -2079,8 +2077,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `510` // Estimated: `6450` - // Minimum execution time: 17_008_000 picoseconds. - Weight::from_parts(17_742_000, 6450) + // Minimum execution time: 15_789_000 picoseconds. + Weight::from_parts(16_850_000, 6450) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2093,10 +2091,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `171 + k * (1 ±0)` // Estimated: `3635 + k * (1 ±0)` - // Minimum execution time: 3_949_000 picoseconds. - Weight::from_parts(4_062_000, 3635) - // Standard Error: 1_983 - .saturating_add(Weight::from_parts(1_173_197, 0).saturating_mul(k.into())) + // Minimum execution time: 3_369_000 picoseconds. + Weight::from_parts(3_516_000, 3635) + // Standard Error: 960 + .saturating_add(Weight::from_parts(1_139_317, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(k.into()))) @@ -2115,10 +2113,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `325 + c * (1 ±0)` // Estimated: `6263 + c * (1 ±0)` - // Minimum execution time: 17_094_000 picoseconds. - Weight::from_parts(17_338_591, 6263) + // Minimum execution time: 16_320_000 picoseconds. + Weight::from_parts(16_090_036, 6263) // Standard Error: 1 - .saturating_add(Weight::from_parts(436, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(417, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -2129,8 +2127,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `440` // Estimated: `6380` - // Minimum execution time: 12_704_000 picoseconds. - Weight::from_parts(13_147_000, 6380) + // Minimum execution time: 12_669_000 picoseconds. + Weight::from_parts(13_118_000, 6380) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2139,13 +2137,13 @@ impl WeightInfo for () { /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) fn v14_migration_step() -> Weight { // Proof Size summary in bytes: - // Measured: `360` - // Estimated: `6300` - // Minimum execution time: 48_387_000 picoseconds. - Weight::from_parts(50_024_000, 6300) + // Measured: `352` + // Estimated: `6292` + // Minimum execution time: 45_403_000 picoseconds. + Weight::from_parts(46_636_000, 6292) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2157,8 +2155,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `594` // Estimated: `6534` - // Minimum execution time: 59_300_000 picoseconds. - Weight::from_parts(61_805_000, 6534) + // Minimum execution time: 53_622_000 picoseconds. + Weight::from_parts(55_444_000, 6534) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -2168,8 +2166,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 3_327_000 picoseconds. - Weight::from_parts(3_502_000, 1627) + // Minimum execution time: 2_444_000 picoseconds. + Weight::from_parts(2_587_000, 1627) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2181,8 +2179,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `166` // Estimated: `3631` - // Minimum execution time: 12_759_000 picoseconds. - Weight::from_parts(13_134_000, 3631) + // Minimum execution time: 11_476_000 picoseconds. + Weight::from_parts(11_944_000, 3631) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -2192,8 +2190,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 4_775_000 picoseconds. - Weight::from_parts(5_084_000, 3607) + // Minimum execution time: 4_652_000 picoseconds. + Weight::from_parts(4_792_000, 3607) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -2204,8 +2202,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `167` // Estimated: `3632` - // Minimum execution time: 6_663_000 picoseconds. - Weight::from_parts(6_855_000, 3632) + // Minimum execution time: 6_054_000 picoseconds. + Weight::from_parts(6_278_000, 3632) .saturating_add(RocksDbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -2216,8 +2214,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 7_212_000 picoseconds. - Weight::from_parts(7_426_000, 3607) + // Minimum execution time: 6_056_000 picoseconds. + Weight::from_parts(6_343_000, 3607) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2240,10 +2238,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `792` // Estimated: `6743 + c * (1 ±0)` - // Minimum execution time: 289_557_000 picoseconds. - Weight::from_parts(272_895_652, 6743) - // Standard Error: 80 - .saturating_add(Weight::from_parts(39_917, 0).saturating_mul(c.into())) + // Minimum execution time: 303_205_000 picoseconds. + Weight::from_parts(266_154_889, 6743) + // Standard Error: 79 + .saturating_add(Weight::from_parts(35_195, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -2253,7 +2251,7 @@ impl WeightInfo for () { /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:2 w:2) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `System::EventTopics` (r:3 w:3) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::Nonce` (r:1 w:1) @@ -2273,14 +2271,14 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `323` // Estimated: `8747` - // Minimum execution time: 4_671_359_000 picoseconds. - Weight::from_parts(586_523_882, 8747) - // Standard Error: 206 - .saturating_add(Weight::from_parts(115_402, 0).saturating_mul(c.into())) - // Standard Error: 24 - .saturating_add(Weight::from_parts(1_797, 0).saturating_mul(i.into())) - // Standard Error: 24 - .saturating_add(Weight::from_parts(2_046, 0).saturating_mul(s.into())) + // Minimum execution time: 4_311_802_000 picoseconds. + Weight::from_parts(777_467_048, 8747) + // Standard Error: 338 + .saturating_add(Weight::from_parts(105_862, 0).saturating_mul(c.into())) + // Standard Error: 40 + .saturating_add(Weight::from_parts(1_856, 0).saturating_mul(i.into())) + // Standard Error: 40 + .saturating_add(Weight::from_parts(1_443, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(10_u64)) } @@ -2301,19 +2299,19 @@ impl WeightInfo for () { /// Storage: `System::EventTopics` (r:2 w:2) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// The range of component `i` is `[0, 1048576]`. /// The range of component `s` is `[0, 1048576]`. fn instantiate(i: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `560` // Estimated: `6504` - // Minimum execution time: 2_170_657_000 picoseconds. - Weight::from_parts(369_331_405, 6504) - // Standard Error: 7 - .saturating_add(Weight::from_parts(1_940, 0).saturating_mul(i.into())) - // Standard Error: 7 - .saturating_add(Weight::from_parts(1_858, 0).saturating_mul(s.into())) + // Minimum execution time: 1_958_694_000 picoseconds. + Weight::from_parts(331_222_273, 6504) + // Standard Error: 13 + .saturating_add(Weight::from_parts(1_954, 0).saturating_mul(i.into())) + // Standard Error: 13 + .saturating_add(Weight::from_parts(1_685, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(10_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } @@ -2335,8 +2333,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `826` // Estimated: `6766` - // Minimum execution time: 204_287_000 picoseconds. - Weight::from_parts(213_239_000, 6766) + // Minimum execution time: 194_513_000 picoseconds. + Weight::from_parts(201_116_000, 6766) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -2345,7 +2343,7 @@ impl WeightInfo for () { /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `System::EventTopics` (r:1 w:1) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:0 w:1) @@ -2355,10 +2353,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 285_434_000 picoseconds. - Weight::from_parts(242_697_648, 3607) - // Standard Error: 128 - .saturating_add(Weight::from_parts(76_087, 0).saturating_mul(c.into())) + // Minimum execution time: 269_777_000 picoseconds. + Weight::from_parts(204_229_027, 3607) + // Standard Error: 152 + .saturating_add(Weight::from_parts(72_184, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -2367,7 +2365,7 @@ impl WeightInfo for () { /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `System::EventTopics` (r:1 w:1) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:0 w:1) @@ -2376,8 +2374,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `315` // Estimated: `3780` - // Minimum execution time: 46_486_000 picoseconds. - Weight::from_parts(48_422_000, 3780) + // Minimum execution time: 43_271_000 picoseconds. + Weight::from_parts(44_884_000, 3780) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -2393,8 +2391,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `552` // Estimated: `8967` - // Minimum execution time: 37_568_000 picoseconds. - Weight::from_parts(38_589_000, 8967) + // Minimum execution time: 34_635_000 picoseconds. + Weight::from_parts(35_477_000, 8967) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -2417,10 +2415,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `866 + r * (6 ±0)` // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 274_513_000 picoseconds. - Weight::from_parts(288_793_403, 6806) - // Standard Error: 650 - .saturating_add(Weight::from_parts(339_309, 0).saturating_mul(r.into())) + // Minimum execution time: 266_757_000 picoseconds. + Weight::from_parts(279_787_352, 6806) + // Standard Error: 812 + .saturating_add(Weight::from_parts(329_166, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2444,10 +2442,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `922 + r * (209 ±0)` // Estimated: `6826 + r * (2684 ±0)` - // Minimum execution time: 260_096_000 picoseconds. - Weight::from_parts(149_954_322, 6826) - // Standard Error: 5_713 - .saturating_add(Weight::from_parts(3_788_924, 0).saturating_mul(r.into())) + // Minimum execution time: 266_442_000 picoseconds. + Weight::from_parts(86_660_390, 6826) + // Standard Error: 9_194 + .saturating_add(Weight::from_parts(3_744_648, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2472,10 +2470,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `921 + r * (213 ±0)` // Estimated: `6830 + r * (2688 ±0)` - // Minimum execution time: 277_496_000 picoseconds. - Weight::from_parts(285_839_000, 6830) - // Standard Error: 10_076 - .saturating_add(Weight::from_parts(4_720_110, 0).saturating_mul(r.into())) + // Minimum execution time: 265_608_000 picoseconds. + Weight::from_parts(273_219_000, 6830) + // Standard Error: 11_085 + .saturating_add(Weight::from_parts(4_542_778, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2500,10 +2498,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `873 + r * (6 ±0)` // Estimated: `6815 + r * (6 ±0)` - // Minimum execution time: 275_655_000 picoseconds. - Weight::from_parts(291_386_528, 6815) - // Standard Error: 898 - .saturating_add(Weight::from_parts(428_765, 0).saturating_mul(r.into())) + // Minimum execution time: 270_033_000 picoseconds. + Weight::from_parts(288_700_795, 6815) + // Standard Error: 1_628 + .saturating_add(Weight::from_parts(428_991, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2527,10 +2525,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863 + r * (3 ±0)` // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 260_323_000 picoseconds. - Weight::from_parts(286_371_403, 6804) - // Standard Error: 451 - .saturating_add(Weight::from_parts(183_053, 0).saturating_mul(r.into())) + // Minimum execution time: 263_789_000 picoseconds. + Weight::from_parts(275_806_968, 6804) + // Standard Error: 936 + .saturating_add(Weight::from_parts(182_805, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -2552,10 +2550,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `753 + r * (3 ±0)` // Estimated: `6693 + r * (3 ±0)` - // Minimum execution time: 262_974_000 picoseconds. - Weight::from_parts(276_571_502, 6693) - // Standard Error: 527 - .saturating_add(Weight::from_parts(165_364, 0).saturating_mul(r.into())) + // Minimum execution time: 257_922_000 picoseconds. + Weight::from_parts(270_842_153, 6693) + // Standard Error: 637 + .saturating_add(Weight::from_parts(156_567, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -2579,10 +2577,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `867 + r * (6 ±0)` // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 272_826_000 picoseconds. - Weight::from_parts(290_963_001, 6807) - // Standard Error: 810 - .saturating_add(Weight::from_parts(343_762, 0).saturating_mul(r.into())) + // Minimum execution time: 267_214_000 picoseconds. + Weight::from_parts(273_446_444, 6807) + // Standard Error: 2_355 + .saturating_add(Weight::from_parts(356_663, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2606,10 +2604,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863 + r * (6 ±0)` // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 277_324_000 picoseconds. - Weight::from_parts(290_872_814, 6806) - // Standard Error: 766 - .saturating_add(Weight::from_parts(371_542, 0).saturating_mul(r.into())) + // Minimum execution time: 258_860_000 picoseconds. + Weight::from_parts(286_389_737, 6806) + // Standard Error: 1_707 + .saturating_add(Weight::from_parts(366_148, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2633,10 +2631,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1007 + r * (6 ±0)` // Estimated: `6931 + r * (6 ±0)` - // Minimum execution time: 274_460_000 picoseconds. - Weight::from_parts(285_748_025, 6931) - // Standard Error: 1_570 - .saturating_add(Weight::from_parts(1_656_237, 0).saturating_mul(r.into())) + // Minimum execution time: 267_852_000 picoseconds. + Weight::from_parts(279_617_620, 6931) + // Standard Error: 3_382 + .saturating_add(Weight::from_parts(1_586_170, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2660,10 +2658,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `877 + r * (6 ±0)` // Estimated: `6823 + r * (6 ±0)` - // Minimum execution time: 278_254_000 picoseconds. - Weight::from_parts(283_893_525, 6823) - // Standard Error: 726 - .saturating_add(Weight::from_parts(347_368, 0).saturating_mul(r.into())) + // Minimum execution time: 266_379_000 picoseconds. + Weight::from_parts(287_280_653, 6823) + // Standard Error: 1_774 + .saturating_add(Weight::from_parts(323_724, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2687,10 +2685,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `875 + r * (6 ±0)` // Estimated: `6816 + r * (6 ±0)` - // Minimum execution time: 279_646_000 picoseconds. - Weight::from_parts(292_505_446, 6816) - // Standard Error: 867 - .saturating_add(Weight::from_parts(337_202, 0).saturating_mul(r.into())) + // Minimum execution time: 266_417_000 picoseconds. + Weight::from_parts(291_394_038, 6816) + // Standard Error: 1_474 + .saturating_add(Weight::from_parts(328_306, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2714,10 +2712,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `872 + r * (6 ±0)` // Estimated: `6819 + r * (6 ±0)` - // Minimum execution time: 274_522_000 picoseconds. - Weight::from_parts(295_135_659, 6819) - // Standard Error: 1_052 - .saturating_add(Weight::from_parts(330_788, 0).saturating_mul(r.into())) + // Minimum execution time: 269_198_000 picoseconds. + Weight::from_parts(285_025_368, 6819) + // Standard Error: 1_231 + .saturating_add(Weight::from_parts(324_814, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2741,10 +2739,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863 + r * (6 ±0)` // Estimated: `6804 + r * (6 ±0)` - // Minimum execution time: 274_228_000 picoseconds. - Weight::from_parts(289_201_593, 6804) - // Standard Error: 752 - .saturating_add(Weight::from_parts(337_860, 0).saturating_mul(r.into())) + // Minimum execution time: 257_514_000 picoseconds. + Weight::from_parts(280_424_571, 6804) + // Standard Error: 723 + .saturating_add(Weight::from_parts(325_607, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2770,10 +2768,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `937 + r * (14 ±0)` // Estimated: `6872 + r * (14 ±0)` - // Minimum execution time: 277_142_000 picoseconds. - Weight::from_parts(296_736_114, 6872) - // Standard Error: 1_502 - .saturating_add(Weight::from_parts(1_446_663, 0).saturating_mul(r.into())) + // Minimum execution time: 268_221_000 picoseconds. + Weight::from_parts(282_273_629, 6872) + // Standard Error: 2_398 + .saturating_add(Weight::from_parts(1_117_278, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 14).saturating_mul(r.into())) @@ -2797,10 +2795,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `865 + r * (6 ±0)` // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 276_087_000 picoseconds. - Weight::from_parts(287_863_377, 6807) - // Standard Error: 495 - .saturating_add(Weight::from_parts(282_718, 0).saturating_mul(r.into())) + // Minimum execution time: 271_541_000 picoseconds. + Weight::from_parts(276_996_569, 6807) + // Standard Error: 1_462 + .saturating_add(Weight::from_parts(282_119, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2824,10 +2822,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `869` // Estimated: `6809` - // Minimum execution time: 277_128_000 picoseconds. - Weight::from_parts(234_478_674, 6809) - // Standard Error: 23 - .saturating_add(Weight::from_parts(1_052, 0).saturating_mul(n.into())) + // Minimum execution time: 256_410_000 picoseconds. + Weight::from_parts(206_888_877, 6809) + // Standard Error: 22 + .saturating_add(Weight::from_parts(1_154, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -2850,8 +2848,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `853 + r * (45 ±0)` // Estimated: `6793 + r * (45 ±0)` - // Minimum execution time: 251_983_000 picoseconds. - Weight::from_parts(277_986_885, 6793) + // Minimum execution time: 248_852_000 picoseconds. + Weight::from_parts(277_852_834, 6793) + // Standard Error: 1_257_219 + .saturating_add(Weight::from_parts(1_394_065, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 45).saturating_mul(r.into())) @@ -2875,10 +2875,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863` // Estimated: `6810` - // Minimum execution time: 275_108_000 picoseconds. - Weight::from_parts(284_552_708, 6810) - // Standard Error: 0 - .saturating_add(Weight::from_parts(391, 0).saturating_mul(n.into())) + // Minimum execution time: 269_101_000 picoseconds. + Weight::from_parts(273_407_545, 6810) + // Standard Error: 2 + .saturating_add(Weight::from_parts(339, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -2899,7 +2899,7 @@ impl WeightInfo for () { /// Storage: `System::EventTopics` (r:4 w:4) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `Contracts::DeletionQueue` (r:0 w:1) /// Proof: `Contracts::DeletionQueue` (`max_values`: None, `max_size`: Some(142), added: 2617, mode: `Measured`) /// The range of component `r` is `[0, 1]`. @@ -2907,10 +2907,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2972 + r * (316 ±0)` // Estimated: `8912 + r * (5266 ±0)` - // Minimum execution time: 281_278_000 picoseconds. - Weight::from_parts(306_800_667, 8912) - // Standard Error: 855_257 - .saturating_add(Weight::from_parts(126_508_132, 0).saturating_mul(r.into())) + // Minimum execution time: 296_318_000 picoseconds. + Weight::from_parts(322_448_344, 8912) + // Standard Error: 2_358_838 + .saturating_add(Weight::from_parts(107_092_455, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((7_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2938,10 +2938,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `944 + r * (10 ±0)` // Estimated: `6885 + r * (10 ±0)` - // Minimum execution time: 260_609_000 picoseconds. - Weight::from_parts(287_385_076, 6885) - // Standard Error: 2_754 - .saturating_add(Weight::from_parts(2_057_388, 0).saturating_mul(r.into())) + // Minimum execution time: 268_264_000 picoseconds. + Weight::from_parts(285_298_853, 6885) + // Standard Error: 3_238 + .saturating_add(Weight::from_parts(1_238_513, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -2965,10 +2965,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863 + r * (10 ±0)` // Estimated: `6805 + r * (10 ±0)` - // Minimum execution time: 254_770_000 picoseconds. - Weight::from_parts(255_105_647, 6805) - // Standard Error: 5_707 - .saturating_add(Weight::from_parts(3_808_788, 0).saturating_mul(r.into())) + // Minimum execution time: 267_417_000 picoseconds. + Weight::from_parts(290_097_452, 6805) + // Standard Error: 2_523 + .saturating_add(Weight::from_parts(2_012_375, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -2993,12 +2993,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `880 + t * (32 ±0)` // Estimated: `6825 + t * (2508 ±0)` - // Minimum execution time: 278_200_000 picoseconds. - Weight::from_parts(288_081_493, 6825) - // Standard Error: 97_535 - .saturating_add(Weight::from_parts(3_683_455, 0).saturating_mul(t.into())) - // Standard Error: 27 - .saturating_add(Weight::from_parts(731, 0).saturating_mul(n.into())) + // Minimum execution time: 269_735_000 picoseconds. + Weight::from_parts(291_680_757, 6825) + // Standard Error: 196_822 + .saturating_add(Weight::from_parts(2_827_797, 0).saturating_mul(t.into())) + // Standard Error: 55 + .saturating_add(Weight::from_parts(262, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3024,10 +3024,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `862 + r * (7 ±0)` // Estimated: `6807 + r * (7 ±0)` - // Minimum execution time: 167_181_000 picoseconds. - Weight::from_parts(178_433_475, 6807) - // Standard Error: 374 - .saturating_add(Weight::from_parts(241_240, 0).saturating_mul(r.into())) + // Minimum execution time: 161_454_000 picoseconds. + Weight::from_parts(181_662_272, 6807) + // Standard Error: 729 + .saturating_add(Weight::from_parts(221_968, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 7).saturating_mul(r.into())) @@ -3051,10 +3051,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `125813` // Estimated: `131755` - // Minimum execution time: 434_456_000 picoseconds. - Weight::from_parts(400_940_450, 131755) - // Standard Error: 13 - .saturating_add(Weight::from_parts(1_102, 0).saturating_mul(i.into())) + // Minimum execution time: 418_479_000 picoseconds. + Weight::from_parts(397_691_558, 131755) + // Standard Error: 12 + .saturating_add(Weight::from_parts(1_099, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3064,11 +3064,11 @@ impl WeightInfo for () { fn seal_set_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `924 + r * (292 ±0)` - // Estimated: `925 + r * (293 ±0)` - // Minimum execution time: 277_825_000 picoseconds. - Weight::from_parts(159_688_263, 925) - // Standard Error: 13_610 - .saturating_add(Weight::from_parts(7_145_641, 0).saturating_mul(r.into())) + // Estimated: `926 + r * (293 ±0)` + // Minimum execution time: 268_810_000 picoseconds. + Weight::from_parts(129_545_478, 926) + // Standard Error: 21_173 + .saturating_add(Weight::from_parts(7_118_874, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3080,12 +3080,12 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 16384]`. fn seal_set_storage_per_new_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1446` - // Estimated: `1429` - // Minimum execution time: 284_745_000 picoseconds. - Weight::from_parts(345_928_316, 1429) - // Standard Error: 70 - .saturating_add(Weight::from_parts(547, 0).saturating_mul(n.into())) + // Measured: `1447` + // Estimated: `1430` + // Minimum execution time: 286_965_000 picoseconds. + Weight::from_parts(340_396_510, 1430) + // Standard Error: 90 + .saturating_add(Weight::from_parts(455, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(8_u64)) } @@ -3094,12 +3094,12 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 16384]`. fn seal_set_storage_per_old_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1252 + n * (1 ±0)` - // Estimated: `1252 + n * (1 ±0)` - // Minimum execution time: 275_328_000 picoseconds. - Weight::from_parts(300_037_010, 1252) - // Standard Error: 32 - .saturating_add(Weight::from_parts(558, 0).saturating_mul(n.into())) + // Measured: `1253 + n * (1 ±0)` + // Estimated: `1253 + n * (1 ±0)` + // Minimum execution time: 272_395_000 picoseconds. + Weight::from_parts(302_307_069, 1253) + // Standard Error: 94 + .saturating_add(Weight::from_parts(156, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3109,12 +3109,12 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 800]`. fn seal_clear_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `920 + r * (288 ±0)` - // Estimated: `926 + r * (289 ±0)` - // Minimum execution time: 273_742_000 picoseconds. - Weight::from_parts(169_430_806, 926) - // Standard Error: 11_821 - .saturating_add(Weight::from_parts(6_927_074, 0).saturating_mul(r.into())) + // Measured: `921 + r * (288 ±0)` + // Estimated: `927 + r * (289 ±0)` + // Minimum execution time: 269_165_000 picoseconds. + Weight::from_parts(167_174_485, 927) + // Standard Error: 23_564 + .saturating_add(Weight::from_parts(6_921_525, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3126,12 +3126,10 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 16384]`. fn seal_clear_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1248 + n * (1 ±0)` - // Estimated: `1248 + n * (1 ±0)` - // Minimum execution time: 275_167_000 picoseconds. - Weight::from_parts(301_883_655, 1248) - // Standard Error: 35 - .saturating_add(Weight::from_parts(4, 0).saturating_mul(n.into())) + // Measured: `1249 + n * (1 ±0)` + // Estimated: `1249 + n * (1 ±0)` + // Minimum execution time: 270_248_000 picoseconds. + Weight::from_parts(296_573_310, 1249) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3141,12 +3139,12 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 800]`. fn seal_get_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `920 + r * (296 ±0)` - // Estimated: `922 + r * (297 ±0)` - // Minimum execution time: 274_628_000 picoseconds. - Weight::from_parts(195_255_092, 922) - // Standard Error: 9_109 - .saturating_add(Weight::from_parts(5_707_060, 0).saturating_mul(r.into())) + // Measured: `921 + r * (296 ±0)` + // Estimated: `923 + r * (297 ±0)` + // Minimum execution time: 270_883_000 picoseconds. + Weight::from_parts(189_792_705, 923) + // Standard Error: 11_149 + .saturating_add(Weight::from_parts(5_232_100, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3157,12 +3155,12 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 16384]`. fn seal_get_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1264 + n * (1 ±0)` - // Estimated: `1264 + n * (1 ±0)` - // Minimum execution time: 274_202_000 picoseconds. - Weight::from_parts(296_440_752, 1264) - // Standard Error: 38 - .saturating_add(Weight::from_parts(1_010, 0).saturating_mul(n.into())) + // Measured: `1265 + n * (1 ±0)` + // Estimated: `1265 + n * (1 ±0)` + // Minimum execution time: 263_833_000 picoseconds. + Weight::from_parts(290_179_222, 1265) + // Standard Error: 44 + .saturating_add(Weight::from_parts(831, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3172,12 +3170,12 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 800]`. fn seal_contains_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `931 + r * (288 ±0)` - // Estimated: `928 + r * (289 ±0)` - // Minimum execution time: 274_123_000 picoseconds. - Weight::from_parts(193_280_535, 928) - // Standard Error: 9_264 - .saturating_add(Weight::from_parts(5_548_039, 0).saturating_mul(r.into())) + // Measured: `932 + r * (288 ±0)` + // Estimated: `929 + r * (289 ±0)` + // Minimum execution time: 252_637_000 picoseconds. + Weight::from_parts(98_108_825, 929) + // Standard Error: 23_580 + .saturating_add(Weight::from_parts(5_408_076, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3188,12 +3186,10 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 16384]`. fn seal_contains_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1251 + n * (1 ±0)` - // Estimated: `1251 + n * (1 ±0)` - // Minimum execution time: 276_425_000 picoseconds. - Weight::from_parts(300_521_806, 1251) - // Standard Error: 36 - .saturating_add(Weight::from_parts(83, 0).saturating_mul(n.into())) + // Measured: `1252 + n * (1 ±0)` + // Estimated: `1252 + n * (1 ±0)` + // Minimum execution time: 279_133_000 picoseconds. + Weight::from_parts(301_192_115, 1252) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3203,12 +3199,12 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 800]`. fn seal_take_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `913 + r * (296 ±0)` - // Estimated: `918 + r * (297 ±0)` - // Minimum execution time: 264_860_000 picoseconds. - Weight::from_parts(191_561_777, 918) - // Standard Error: 10_678 - .saturating_add(Weight::from_parts(6_895_457, 0).saturating_mul(r.into())) + // Measured: `914 + r * (296 ±0)` + // Estimated: `919 + r * (297 ±0)` + // Minimum execution time: 268_833_000 picoseconds. + Weight::from_parts(56_229_951, 919) + // Standard Error: 25_800 + .saturating_add(Weight::from_parts(7_607_143, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3220,12 +3216,12 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 16384]`. fn seal_take_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1265 + n * (1 ±0)` - // Estimated: `1265 + n * (1 ±0)` - // Minimum execution time: 282_501_000 picoseconds. - Weight::from_parts(303_351_919, 1265) - // Standard Error: 37 - .saturating_add(Weight::from_parts(643, 0).saturating_mul(n.into())) + // Measured: `1266 + n * (1 ±0)` + // Estimated: `1266 + n * (1 ±0)` + // Minimum execution time: 288_677_000 picoseconds. + Weight::from_parts(301_986_360, 1266) + // Standard Error: 39 + .saturating_add(Weight::from_parts(867, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3249,10 +3245,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1415 + r * (45 ±0)` // Estimated: `7307 + r * (2520 ±0)` - // Minimum execution time: 273_198_000 picoseconds. - Weight::from_parts(179_673_238, 7307) - // Standard Error: 34_990 - .saturating_add(Weight::from_parts(38_468_091, 0).saturating_mul(r.into())) + // Minimum execution time: 275_956_000 picoseconds. + Weight::from_parts(280_865_651, 7307) + // Standard Error: 28_235 + .saturating_add(Weight::from_parts(32_233_352, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) @@ -3278,10 +3274,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1260 + r * (245 ±0)` // Estimated: `9440 + r * (2721 ±0)` - // Minimum execution time: 283_869_000 picoseconds. - Weight::from_parts(288_374_000, 9440) - // Standard Error: 137_512 - .saturating_add(Weight::from_parts(248_206_665, 0).saturating_mul(r.into())) + // Minimum execution time: 269_188_000 picoseconds. + Weight::from_parts(276_038_000, 9440) + // Standard Error: 262_029 + .saturating_add(Weight::from_parts(250_766_832, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) @@ -3307,10 +3303,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0 + r * (576 ±0)` // Estimated: `6812 + r * (2637 ±3)` - // Minimum execution time: 257_577_000 picoseconds. - Weight::from_parts(277_310_000, 6812) - // Standard Error: 150_204 - .saturating_add(Weight::from_parts(249_943_483, 0).saturating_mul(r.into())) + // Minimum execution time: 267_543_000 picoseconds. + Weight::from_parts(271_365_000, 6812) + // Standard Error: 190_454 + .saturating_add(Weight::from_parts(242_627_807, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3337,12 +3333,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1307 + t * (277 ±0)` // Estimated: `12197 + t * (5227 ±0)` - // Minimum execution time: 471_081_000 picoseconds. - Weight::from_parts(79_081_122, 12197) - // Standard Error: 11_777_790 - .saturating_add(Weight::from_parts(357_425_411, 0).saturating_mul(t.into())) + // Minimum execution time: 453_215_000 picoseconds. + Weight::from_parts(32_029_330, 12197) + // Standard Error: 12_154_174 + .saturating_add(Weight::from_parts(392_862_355, 0).saturating_mul(t.into())) // Standard Error: 17 - .saturating_add(Weight::from_parts(1_111, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(1_059, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(13_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(6_u64)) @@ -3366,16 +3362,16 @@ impl WeightInfo for () { /// Storage: `System::EventTopics` (r:803 w:803) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:800 w:800) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// The range of component `r` is `[1, 800]`. fn seal_instantiate(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `1278 + r * (255 ±0)` // Estimated: `9620 + r * (2731 ±0)` - // Minimum execution time: 672_742_000 picoseconds. - Weight::from_parts(680_025_000, 9620) - // Standard Error: 313_642 - .saturating_add(Weight::from_parts(388_311_259, 0).saturating_mul(r.into())) + // Minimum execution time: 635_304_000 picoseconds. + Weight::from_parts(645_872_000, 9620) + // Standard Error: 356_713 + .saturating_add(Weight::from_parts(371_999_658, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((6_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(7_u64)) @@ -3399,7 +3395,7 @@ impl WeightInfo for () { /// Storage: `System::EventTopics` (r:4 w:4) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// The range of component `t` is `[0, 1]`. /// The range of component `i` is `[0, 983040]`. /// The range of component `s` is `[0, 983040]`. @@ -3407,12 +3403,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1303 + t * (104 ±0)` // Estimated: `12211 + t * (2549 ±1)` - // Minimum execution time: 2_733_870_000 picoseconds. - Weight::from_parts(1_001_793_458, 12211) - // Standard Error: 12 - .saturating_add(Weight::from_parts(1_963, 0).saturating_mul(i.into())) - // Standard Error: 12 - .saturating_add(Weight::from_parts(2_060, 0).saturating_mul(s.into())) + // Minimum execution time: 2_225_692_000 picoseconds. + Weight::from_parts(1_292_861_603, 12211) + // Standard Error: 24 + .saturating_add(Weight::from_parts(1_075, 0).saturating_mul(i.into())) + // Standard Error: 24 + .saturating_add(Weight::from_parts(1_278, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(16_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(11_u64)) @@ -3438,10 +3434,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `862 + r * (8 ±0)` // Estimated: `6801 + r * (8 ±0)` - // Minimum execution time: 272_658_000 picoseconds. - Weight::from_parts(282_717_645, 6801) - // Standard Error: 517 - .saturating_add(Weight::from_parts(400_604, 0).saturating_mul(r.into())) + // Minimum execution time: 252_664_000 picoseconds. + Weight::from_parts(277_967_331, 6801) + // Standard Error: 723 + .saturating_add(Weight::from_parts(370_111, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3465,10 +3461,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `870` // Estimated: `6808` - // Minimum execution time: 260_969_000 picoseconds. - Weight::from_parts(265_206_847, 6808) + // Minimum execution time: 252_485_000 picoseconds. + Weight::from_parts(259_271_531, 6808) // Standard Error: 2 - .saturating_add(Weight::from_parts(1_134, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_091, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3491,10 +3487,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6806 + r * (8 ±0)` - // Minimum execution time: 262_351_000 picoseconds. - Weight::from_parts(286_974_296, 6806) - // Standard Error: 514 - .saturating_add(Weight::from_parts(802_363, 0).saturating_mul(r.into())) + // Minimum execution time: 249_270_000 picoseconds. + Weight::from_parts(272_528_711, 6806) + // Standard Error: 903 + .saturating_add(Weight::from_parts(793_299, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3518,10 +3514,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6814` - // Minimum execution time: 276_907_000 picoseconds. - Weight::from_parts(277_928_418, 6814) - // Standard Error: 1 - .saturating_add(Weight::from_parts(3_410, 0).saturating_mul(n.into())) + // Minimum execution time: 249_470_000 picoseconds. + Weight::from_parts(273_317_815, 6814) + // Standard Error: 4 + .saturating_add(Weight::from_parts(3_400, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3544,10 +3540,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6808 + r * (8 ±0)` - // Minimum execution time: 263_660_000 picoseconds. - Weight::from_parts(285_665_916, 6808) - // Standard Error: 527 - .saturating_add(Weight::from_parts(480_457, 0).saturating_mul(r.into())) + // Minimum execution time: 265_503_000 picoseconds. + Weight::from_parts(279_774_666, 6808) + // Standard Error: 1_351 + .saturating_add(Weight::from_parts(439_734, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3571,10 +3567,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6813` - // Minimum execution time: 262_071_000 picoseconds. - Weight::from_parts(270_115_341, 6813) + // Minimum execution time: 265_009_000 picoseconds. + Weight::from_parts(270_467_968, 6813) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_254, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_206, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3597,10 +3593,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6805 + r * (8 ±0)` - // Minimum execution time: 265_568_000 picoseconds. - Weight::from_parts(285_791_811, 6805) - // Standard Error: 559 - .saturating_add(Weight::from_parts(505_330, 0).saturating_mul(r.into())) + // Minimum execution time: 251_771_000 picoseconds. + Weight::from_parts(283_553_523, 6805) + // Standard Error: 1_053 + .saturating_add(Weight::from_parts(445_715, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3624,10 +3620,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6811` - // Minimum execution time: 271_336_000 picoseconds. - Weight::from_parts(272_829_313, 6811) - // Standard Error: 0 - .saturating_add(Weight::from_parts(1_252, 0).saturating_mul(n.into())) + // Minimum execution time: 253_733_000 picoseconds. + Weight::from_parts(264_277_000, 6811) + // Standard Error: 3 + .saturating_add(Weight::from_parts(1_226, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3650,10 +3646,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `997 + n * (1 ±0)` // Estimated: `6934 + n * (1 ±0)` - // Minimum execution time: 351_146_000 picoseconds. - Weight::from_parts(355_368_323, 6934) - // Standard Error: 14 - .saturating_add(Weight::from_parts(6_155, 0).saturating_mul(n.into())) + // Minimum execution time: 337_326_000 picoseconds. + Weight::from_parts(346_340_758, 6934) + // Standard Error: 18 + .saturating_add(Weight::from_parts(6_110, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3675,12 +3671,12 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 160]`. fn seal_sr25519_verify(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `807 + r * (112 ±0)` + // Measured: `805 + r * (112 ±0)` // Estimated: `6748 + r * (112 ±0)` - // Minimum execution time: 277_250_000 picoseconds. - Weight::from_parts(346_490_114, 6748) - // Standard Error: 14_654 - .saturating_add(Weight::from_parts(56_127_492, 0).saturating_mul(r.into())) + // Minimum execution time: 253_852_000 picoseconds. + Weight::from_parts(335_731_679, 6748) + // Standard Error: 13_615 + .saturating_add(Weight::from_parts(41_557_258, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(r.into())) @@ -3704,10 +3700,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `907 + r * (76 ±0)` // Estimated: `6801 + r * (77 ±0)` - // Minimum execution time: 272_697_000 picoseconds. - Weight::from_parts(345_385_667, 6801) - // Standard Error: 14_226 - .saturating_add(Weight::from_parts(46_037_637, 0).saturating_mul(r.into())) + // Minimum execution time: 256_283_000 picoseconds. + Weight::from_parts(338_634_113, 6801) + // Standard Error: 43_436 + .saturating_add(Weight::from_parts(46_607_112, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 77).saturating_mul(r.into())) @@ -3731,10 +3727,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `877 + r * (42 ±0)` // Estimated: `6816 + r * (42 ±0)` - // Minimum execution time: 271_800_000 picoseconds. - Weight::from_parts(314_891_136, 6816) - // Standard Error: 9_762 - .saturating_add(Weight::from_parts(11_949_979, 0).saturating_mul(r.into())) + // Minimum execution time: 269_144_000 picoseconds. + Weight::from_parts(331_790_138, 6816) + // Standard Error: 23_357 + .saturating_add(Weight::from_parts(12_213_638, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 42).saturating_mul(r.into())) @@ -3758,10 +3754,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0 + r * (965 ±0)` // Estimated: `6807 + r * (3090 ±10)` - // Minimum execution time: 274_238_000 picoseconds. - Weight::from_parts(278_034_000, 6807) - // Standard Error: 77_011 - .saturating_add(Weight::from_parts(27_627_005, 0).saturating_mul(r.into())) + // Minimum execution time: 262_624_000 picoseconds. + Weight::from_parts(275_865_000, 6807) + // Standard Error: 64_162 + .saturating_add(Weight::from_parts(26_205_387, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3787,10 +3783,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `928 + r * (131 ±0)` // Estimated: `6878 + r * (2606 ±0)` - // Minimum execution time: 271_519_000 picoseconds. - Weight::from_parts(292_726_476, 6878) - // Standard Error: 23_870 - .saturating_add(Weight::from_parts(6_695_172, 0).saturating_mul(r.into())) + // Minimum execution time: 265_482_000 picoseconds. + Weight::from_parts(296_491_925, 6878) + // Standard Error: 46_681 + .saturating_add(Weight::from_parts(6_572_162, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3816,10 +3812,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `969 + r * (183 ±0)` // Estimated: `129453 + r * (2568 ±0)` - // Minimum execution time: 274_675_000 picoseconds. - Weight::from_parts(293_727_489, 129453) - // Standard Error: 23_160 - .saturating_add(Weight::from_parts(5_895_043, 0).saturating_mul(r.into())) + // Minimum execution time: 257_532_000 picoseconds. + Weight::from_parts(299_110_930, 129453) + // Standard Error: 55_003 + .saturating_add(Weight::from_parts(6_130_357, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3845,10 +3841,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `858 + r * (3 ±0)` // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 253_330_000 picoseconds. - Weight::from_parts(281_079_564, 6804) - // Standard Error: 378 - .saturating_add(Weight::from_parts(180_655, 0).saturating_mul(r.into())) + // Minimum execution time: 268_894_000 picoseconds. + Weight::from_parts(287_048_741, 6804) + // Standard Error: 1_156 + .saturating_add(Weight::from_parts(172_596, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -3872,10 +3868,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2109 + r * (39 ±0)` // Estimated: `7899 + r * (40 ±0)` - // Minimum execution time: 276_552_000 picoseconds. - Weight::from_parts(368_521_088, 7899) - // Standard Error: 2_310 - .saturating_add(Weight::from_parts(318_129, 0).saturating_mul(r.into())) + // Minimum execution time: 262_736_000 picoseconds. + Weight::from_parts(389_199_672, 7899) + // Standard Error: 2_646 + .saturating_add(Weight::from_parts(290_309, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) @@ -3901,10 +3897,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `861 + r * (3 ±0)` // Estimated: `6801 + r * (3 ±0)` - // Minimum execution time: 258_953_000 picoseconds. - Weight::from_parts(288_222_836, 6801) - // Standard Error: 367 - .saturating_add(Weight::from_parts(152_842, 0).saturating_mul(r.into())) + // Minimum execution time: 253_465_000 picoseconds. + Weight::from_parts(283_153_874, 6801) + // Standard Error: 745 + .saturating_add(Weight::from_parts(148_864, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -3914,9 +3910,9 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_476_000 picoseconds. - Weight::from_parts(2_119_717, 0) - // Standard Error: 28 - .saturating_add(Weight::from_parts(9_805, 0).saturating_mul(r.into())) + // Minimum execution time: 1_342_000 picoseconds. + Weight::from_parts(1_940_100, 0) + // Standard Error: 21 + .saturating_add(Weight::from_parts(11_117, 0).saturating_mul(r.into())) } } -- GitLab From b4b523c84c8de954e1ddabd20e3c66a0a494bd5b Mon Sep 17 00:00:00 2001 From: Nazar Mokrynskyi Date: Thu, 18 Jan 2024 23:18:05 +0200 Subject: [PATCH 080/392] Fix contracts compilation with `CARGO_TARGET_DIR` set (#2927) In case `CARGO_TARGET_DIR` is set, build artifacts were in the wrong place and `build.rs` was failing. With `CARGO_TARGET_DIR=/home/nazar-pc/.cache/cargo/target`: ``` error: failed to run custom build command for `pallet-contracts-fixtures v1.0.0 (/web/subspace/polkadot-sdk/substrate/frame/contracts/fixtures)` Caused by: process didn't exit successfully: `/home/nazar-pc/.cache/cargo/target/debug/build/pallet-contracts-fixtures-35d534f7ac3009e0/build-script-build` (exit status: 1) --- stderr Error: Failed to read "/tmp/.tmpiYwXfv/target/wasm32-unknown-unknown/release/dummy.wasm" Caused by: Can't read from the file: Os { code: 2, kind: NotFound, message: "No such file or directory" } ``` The file was actually in `/home/nazar-pc/.cache/cargo/target/wasm32-unknown-unknown/release/dummy.wasm`. --- substrate/frame/contracts/fixtures/build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/substrate/frame/contracts/fixtures/build.rs b/substrate/frame/contracts/fixtures/build.rs index 7b814ef77a6..8e00bbc9d09 100644 --- a/substrate/frame/contracts/fixtures/build.rs +++ b/substrate/frame/contracts/fixtures/build.rs @@ -203,6 +203,7 @@ fn invoke_wasm_build(current_dir: &Path) -> Result<()> { let build_res = Command::new(env::var("CARGO")?) .current_dir(current_dir) + .env("CARGO_TARGET_DIR", current_dir.join("target").display().to_string()) .env("CARGO_ENCODED_RUSTFLAGS", encoded_rustflags) .args(["build", "--release", "--target=wasm32-unknown-unknown"]) .output() -- GitLab From 87927bbd7cf556b2aea68bef4515a223e9989af6 Mon Sep 17 00:00:00 2001 From: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Date: Thu, 18 Jan 2024 21:55:50 +0100 Subject: [PATCH 081/392] `GenesisBuilder`: `arbitrary_precision` feature enabled for `serde_json` (#2987) [`arbitrary_precision`](https://github.com/serde-rs/json/blob/6d44b9fac9269b4decf76acac5d68e8ec9d10c58/Cargo.toml#L69-L75) feature allows to (de-)serialize big numbers w/o error. For some details refer also to https://github.com/paritytech/polkadot-sdk/pull/1256#discussion_r1455564450 fixes: #2963 --- substrate/primitives/genesis-builder/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/primitives/genesis-builder/Cargo.toml b/substrate/primitives/genesis-builder/Cargo.toml index 42d6c8c3d65..263b48c9efe 100644 --- a/substrate/primitives/genesis-builder/Cargo.toml +++ b/substrate/primitives/genesis-builder/Cargo.toml @@ -19,7 +19,7 @@ targets = ["x86_64-unknown-linux-gnu"] sp-api = { path = "../api", default-features = false } sp-runtime = { path = "../runtime", default-features = false } sp-std = { path = "../std", default-features = false } -serde_json = { version = "1.0.111", default-features = false, features = ["alloc"] } +serde_json = { version = "1.0.111", default-features = false, features = ["alloc", "arbitrary_precision"] } [features] default = ["std"] -- GitLab From 9db92115d023689581e8cf49edb9500b0dcced53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7alo=20Pestana?= Date: Thu, 18 Jan 2024 23:05:59 +0100 Subject: [PATCH 082/392] More tests and checks confirming that `ledger.controller` is always correct. (#2599) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A bonded ledger fetched with the `StakingLedger` implementation exposes a method `ledger.controller()` that returns the controller of the ledger. However, that controller is computed and stored under the `ledger.controller` field on the fly - i.e when the ledger is fetched from storage using the `StakingLedger::get` method. The controller field is never stored in storage. This PR add a few more tests checks and improves the ledger try-state checks to make sure these invariants hold true. --------- Co-authored-by: command-bot <> Co-authored-by: Bastian Köcher Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- substrate/frame/staking/src/pallet/impls.rs | 12 +++++++++++- substrate/frame/staking/src/tests.rs | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/substrate/frame/staking/src/pallet/impls.rs b/substrate/frame/staking/src/pallet/impls.rs index 093cdfdb9cb..80b4079dbd6 100644 --- a/substrate/frame/staking/src/pallet/impls.rs +++ b/substrate/frame/staking/src/pallet/impls.rs @@ -1853,7 +1853,17 @@ impl Pallet { fn check_ledgers() -> Result<(), TryRuntimeError> { Bonded::::iter() - .map(|(_, ctrl)| Self::ensure_ledger_consistent(ctrl)) + .map(|(stash, ctrl)| { + // `ledger.controller` is never stored in raw storage. + let raw = Ledger::::get(stash).unwrap_or_else(|| { + Ledger::::get(ctrl.clone()) + .expect("try_check: bonded stash/ctrl does not have an associated ledger") + }); + ensure!(raw.controller.is_none(), "raw storage controller should be None"); + + // ensure ledger consistency. + Self::ensure_ledger_consistent(ctrl) + }) .collect::, _>>()?; Ok(()) } diff --git a/substrate/frame/staking/src/tests.rs b/substrate/frame/staking/src/tests.rs index 0e9be70ee7d..f469ace0bc4 100644 --- a/substrate/frame/staking/src/tests.rs +++ b/substrate/frame/staking/src/tests.rs @@ -255,6 +255,20 @@ fn change_controller_works() { assert_eq!(Staking::bonded(&stash), Some(stash)); mock::start_active_era(1); + // fetch the ledger from storage and check if the controller is correct. + let ledger = Staking::ledger(StakingAccount::Stash(stash)).unwrap(); + assert_eq!(ledger.controller(), Some(stash)); + + // same if we fetch the ledger by controller. + let ledger = Staking::ledger(StakingAccount::Controller(stash)).unwrap(); + assert_eq!(ledger.controller, Some(stash)); + assert_eq!(ledger.controller(), Some(stash)); + + // the raw storage ledger's controller is always `None`. however, we can still fetch the + // correct controller with `ledger.controler()`. + let raw_ledger = >::get(&stash).unwrap(); + assert_eq!(raw_ledger.controller, None); + // `controller` is no longer in control. `stash` is now controller. assert_noop!( Staking::validate(RuntimeOrigin::signed(controller), ValidatorPrefs::default()), -- GitLab From 697c2c392ebed23060ea5864e72c744ad6954821 Mon Sep 17 00:00:00 2001 From: Liam Aharon Date: Fri, 19 Jan 2024 23:27:59 +1100 Subject: [PATCH 083/392] Update `translate` to use `defensive!` (#2985) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #1323 cc @xlc --------- Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Co-authored-by: Bastian Köcher --- .../support/src/storage/generator/map.rs | 88 ++++++++++++++++--- .../frame/support/src/storage/types/map.rs | 3 +- 2 files changed, 79 insertions(+), 12 deletions(-) diff --git a/substrate/frame/support/src/storage/generator/map.rs b/substrate/frame/support/src/storage/generator/map.rs index b2919bff8d1..257aa7e7bcf 100644 --- a/substrate/frame/support/src/storage/generator/map.rs +++ b/substrate/frame/support/src/storage/generator/map.rs @@ -196,7 +196,10 @@ where let value = match unhashed::get::(¤t_key) { Some(value) => value, None => { - log::error!("Invalid translate: fail to decode old value"); + crate::defensive!( + "Invalid translation: failed to decode old value for key", + array_bytes::bytes2hex("0x", ¤t_key) + ); return Some(current_key) }, }; @@ -205,7 +208,10 @@ where let key = match K::decode(&mut key_material) { Ok(key) => key, Err(_) => { - log::error!("Invalid translate: fail to decode key"); + crate::defensive!( + "Invalid translation: failed to decode key", + array_bytes::bytes2hex("0x", ¤t_key) + ); return Some(current_key) }, }; @@ -389,6 +395,75 @@ mod test_iterators { }); } + #[cfg(debug_assertions)] + #[test] + #[should_panic] + fn map_translate_with_bad_key_in_debug_mode() { + sp_io::TestExternalities::default().execute_with(|| { + type Map = self::frame_system::Map; + let prefix = Map::prefix_hash().to_vec(); + + // Wrong key + unhashed::put(&[prefix.clone(), vec![1, 2, 3]].concat(), &3u64.encode()); + + // debug_assert should cause a + Map::translate(|_k1, v: u64| Some(v * 2)); + assert_eq!(Map::iter().collect::>(), vec![(3, 6), (0, 0), (2, 4), (1, 2)]); + }) + } + + #[cfg(debug_assertions)] + #[test] + #[should_panic] + fn map_translate_with_bad_value_in_debug_mode() { + sp_io::TestExternalities::default().execute_with(|| { + type Map = self::frame_system::Map; + let prefix = Map::prefix_hash().to_vec(); + + // Wrong value + unhashed::put( + &[prefix.clone(), crate::Blake2_128Concat::hash(&6u16.encode())].concat(), + &vec![1], + ); + + Map::translate(|_k1, v: u64| Some(v * 2)); + assert_eq!(Map::iter().collect::>(), vec![(3, 6), (0, 0), (2, 4), (1, 2)]); + }) + } + + #[cfg(not(debug_assertions))] + #[test] + fn map_translate_with_bad_key_in_production_mode() { + sp_io::TestExternalities::default().execute_with(|| { + type Map = self::frame_system::Map; + let prefix = Map::prefix_hash().to_vec(); + + // Wrong key + unhashed::put(&[prefix.clone(), vec![1, 2, 3]].concat(), &3u64.encode()); + + Map::translate(|_k1, v: u64| Some(v * 2)); + assert_eq!(Map::iter().collect::>(), vec![]); + }) + } + + #[cfg(not(debug_assertions))] + #[test] + fn map_translate_with_bad_value_in_production_mode() { + sp_io::TestExternalities::default().execute_with(|| { + type Map = self::frame_system::Map; + let prefix = Map::prefix_hash().to_vec(); + + // Wrong value + unhashed::put( + &[prefix.clone(), crate::Blake2_128Concat::hash(&6u16.encode())].concat(), + &vec![1], + ); + + Map::translate(|_k1, v: u64| Some(v * 2)); + assert_eq!(Map::iter().collect::>(), vec![]); + }) + } + #[test] fn map_reversible_reversible_iteration() { sp_io::TestExternalities::default().execute_with(|| { @@ -425,15 +500,6 @@ mod test_iterators { Map::insert(i as u16, i as u64); } - // Wrong key - unhashed::put(&[prefix.clone(), vec![1, 2, 3]].concat(), &3u64.encode()); - - // Wrong value - unhashed::put( - &[prefix.clone(), crate::Blake2_128Concat::hash(&6u16.encode())].concat(), - &vec![1], - ); - Map::translate(|_k1, v: u64| Some(v * 2)); assert_eq!(Map::iter().collect::>(), vec![(3, 6), (0, 0), (2, 4), (1, 2)]); }) diff --git a/substrate/frame/support/src/storage/types/map.rs b/substrate/frame/support/src/storage/types/map.rs index d0149cf3fc8..ee5db74583b 100644 --- a/substrate/frame/support/src/storage/types/map.rs +++ b/substrate/frame/support/src/storage/types/map.rs @@ -471,7 +471,8 @@ where /// /// By returning `None` from `f` for an element, you'll remove it from the map. /// - /// NOTE: If a value fail to decode because storage is corrupted then it is skipped. + /// NOTE: If a value fails to decode because storage is corrupted, then it will log an error and + /// be skipped in production, or panic in development. pub fn translate Option>(f: F) { >::translate(f) } -- GitLab From 47a3faa41e212838349de528194402d2d415b0b8 Mon Sep 17 00:00:00 2001 From: maksimryndin Date: Fri, 19 Jan 2024 15:10:09 +0100 Subject: [PATCH 084/392] Pvf thiserror (#2958) resolve #2157 - [x] fix broken doc links - [x] fix codec macro typo https://github.com/paritytech/polkadot-sdk/blob/master/polkadot/node/core/pvf/common/src/error.rs#L81 (see the comment below) - [x] refactor `ValidationError`, `PrepareError` and related error types to use `thiserror` crate ## `codec` issue `codec` macro was mistakenly applied two times to `Kernel` error (so it was encoded with 10 instead of 11 and the same as `JobDied`). The PR changes it to 11 because - it was an initial goal of the code author - Kernel is less frequent than JobDied so in case of existing error encoding it is more probable to have 10 as JobDied than Kernel See https://github.com/paritytech/parity-scale-codec/issues/555 ---- polkadot address: 13zCyRG2a1W2ih5SioL8byqmQ6mc8vkgFwQgVzJSdRUUmp46 --------- Co-authored-by: s0me0ne-unkn0wn <48632512+s0me0ne-unkn0wn@users.noreply.github.com> --- polkadot/node/core/pvf/common/src/error.rs | 72 ++++++------------- .../node/core/pvf/execute-worker/src/lib.rs | 2 +- polkadot/node/core/pvf/src/error.rs | 27 +++---- polkadot/node/core/pvf/src/execute/queue.rs | 2 +- polkadot/node/core/pvf/src/host.rs | 3 +- polkadot/node/core/pvf/src/prepare/queue.rs | 4 +- .../core/pvf/src/prepare/worker_interface.rs | 2 +- 7 files changed, 43 insertions(+), 69 deletions(-) diff --git a/polkadot/node/core/pvf/common/src/error.rs b/polkadot/node/core/pvf/common/src/error.rs index 7db7f9a5945..f8faefc24e6 100644 --- a/polkadot/node/core/pvf/common/src/error.rs +++ b/polkadot/node/core/pvf/common/src/error.rs @@ -16,7 +16,6 @@ use crate::prepare::{PrepareSuccess, PrepareWorkerSuccess}; use parity_scale_codec::{Decode, Encode}; -use std::fmt; /// Result of PVF preparation from a worker, with checksum of the compiled PVF and stats of the /// preparation if successful. @@ -32,35 +31,43 @@ pub type PrecheckResult = Result<(), PrepareError>; /// An error that occurred during the prepare part of the PVF pipeline. // Codec indexes are intended to stabilize pre-encoded payloads (see `OOM_PAYLOAD`) -#[derive(Debug, Clone, Encode, Decode)] +#[derive(thiserror::Error, Debug, Clone, Encode, Decode)] pub enum PrepareError { /// During the prevalidation stage of preparation an issue was found with the PVF. #[codec(index = 0)] + #[error("prepare: prevalidation error: {0}")] Prevalidation(String), /// Compilation failed for the given PVF. #[codec(index = 1)] + #[error("prepare: preparation error: {0}")] Preparation(String), /// Instantiation of the WASM module instance failed. #[codec(index = 2)] + #[error("prepare: runtime construction: {0}")] RuntimeConstruction(String), /// An unexpected error has occurred in the preparation job. #[codec(index = 3)] + #[error("prepare: job error: {0}")] JobError(String), /// Failed to prepare the PVF due to the time limit. #[codec(index = 4)] + #[error("prepare: timeout")] TimedOut, /// An IO error occurred. This state is reported by either the validation host or by the /// worker. #[codec(index = 5)] + #[error("prepare: io error while receiving response: {0}")] IoErr(String), /// The temporary file for the artifact could not be created at the given cache path. This /// state is reported by the validation host (not by the worker). #[codec(index = 6)] + #[error("prepare: error creating tmp file: {0}")] CreateTmpFile(String), /// The response from the worker is received, but the file cannot be renamed (moved) to the /// final destination location. This state is reported by the validation host (not by the /// worker). #[codec(index = 7)] + #[error("prepare: error renaming tmp file ({src:?} -> {dest:?}): {err}")] RenameTmpFile { err: String, // Unfortunately `PathBuf` doesn't implement `Encode`/`Decode`, so we do a fallible @@ -70,17 +77,21 @@ pub enum PrepareError { }, /// Memory limit reached #[codec(index = 8)] + #[error("prepare: out of memory")] OutOfMemory, /// The response from the worker is received, but the worker cache could not be cleared. The /// worker has to be killed to avoid jobs having access to data from other jobs. This state is /// reported by the validation host (not by the worker). #[codec(index = 9)] + #[error("prepare: error clearing worker cache: {0}")] ClearWorkerDir(String), /// The preparation job process died, due to OOM, a seccomp violation, or some other factor. - JobDied { err: String, job_pid: i32 }, #[codec(index = 10)] + #[error("prepare: prepare job with pid {job_pid} died: {err}")] + JobDied { err: String, job_pid: i32 }, /// Some error occurred when interfacing with the kernel. #[codec(index = 11)] + #[error("prepare: error interfacing with the kernel: {0}")] Kernel(String), } @@ -109,41 +120,23 @@ impl PrepareError { } } -impl fmt::Display for PrepareError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use PrepareError::*; - match self { - Prevalidation(err) => write!(f, "prevalidation: {}", err), - Preparation(err) => write!(f, "preparation: {}", err), - RuntimeConstruction(err) => write!(f, "runtime construction: {}", err), - JobError(err) => write!(f, "panic: {}", err), - TimedOut => write!(f, "prepare: timeout"), - IoErr(err) => write!(f, "prepare: io error while receiving response: {}", err), - JobDied { err, job_pid } => - write!(f, "prepare: prepare job with pid {job_pid} died: {err}"), - CreateTmpFile(err) => write!(f, "prepare: error creating tmp file: {}", err), - RenameTmpFile { err, src, dest } => - write!(f, "prepare: error renaming tmp file ({:?} -> {:?}): {}", src, dest, err), - OutOfMemory => write!(f, "prepare: out of memory"), - ClearWorkerDir(err) => write!(f, "prepare: error clearing worker cache: {}", err), - Kernel(err) => write!(f, "prepare: error interfacing with the kernel: {}", err), - } - } -} - /// Some internal error occurred. /// /// Should only ever be used for validation errors independent of the candidate and PVF, or for /// errors we ruled out during pre-checking (so preparation errors are fine). -#[derive(Debug, Clone, Encode, Decode)] +#[derive(thiserror::Error, Debug, Clone, Encode, Decode)] pub enum InternalValidationError { /// Some communication error occurred with the host. + #[error("validation: some communication error occurred with the host: {0}")] HostCommunication(String), /// Host could not create a hard link to the artifact path. + #[error("validation: host could not create a hard link to the artifact path: {0}")] CouldNotCreateLink(String), /// Could not find or open compiled artifact file. + #[error("validation: could not find or open compiled artifact file: {0}")] CouldNotOpenFile(String), /// Host could not clear the worker cache after a job. + #[error("validation: host could not clear the worker cache ({path:?}) after a job: {err}")] CouldNotClearWorkerDir { err: String, // Unfortunately `PathBuf` doesn't implement `Encode`/`Decode`, so we do a fallible @@ -151,32 +144,9 @@ pub enum InternalValidationError { path: Option, }, /// Some error occurred when interfacing with the kernel. + #[error("validation: error interfacing with the kernel: {0}")] Kernel(String), - /// Some non-deterministic preparation error occurred. + #[error("validation: prepare: {0}")] NonDeterministicPrepareError(PrepareError), } - -impl fmt::Display for InternalValidationError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use InternalValidationError::*; - match self { - HostCommunication(err) => - write!(f, "validation: some communication error occurred with the host: {}", err), - CouldNotCreateLink(err) => write!( - f, - "validation: host could not create a hard link to the artifact path: {}", - err - ), - CouldNotOpenFile(err) => - write!(f, "validation: could not find or open compiled artifact file: {}", err), - CouldNotClearWorkerDir { err, path } => write!( - f, - "validation: host could not clear the worker cache ({:?}) after a job: {}", - path, err - ), - Kernel(err) => write!(f, "validation: error interfacing with the kernel: {}", err), - NonDeterministicPrepareError(err) => write!(f, "validation: prepare: {}", err), - } - } -} diff --git a/polkadot/node/core/pvf/execute-worker/src/lib.rs b/polkadot/node/core/pvf/execute-worker/src/lib.rs index cff6e0ac13a..6980f913d0d 100644 --- a/polkadot/node/core/pvf/execute-worker/src/lib.rs +++ b/polkadot/node/core/pvf/execute-worker/src/lib.rs @@ -485,7 +485,7 @@ fn recv_child_response(received_data: &mut io::BufReader<&[u8]>) -> io::Result for ValidationError { - fn from(error: InternalValidationError) -> Self { - Self::Internal(error) - } -} - impl From for ValidationError { fn from(error: PrepareError) -> Self { // Here we need to classify the errors into two errors: deterministic and non-deterministic. diff --git a/polkadot/node/core/pvf/src/execute/queue.rs b/polkadot/node/core/pvf/src/execute/queue.rs index be607fe1c20..aa91d11781f 100644 --- a/polkadot/node/core/pvf/src/execute/queue.rs +++ b/polkadot/node/core/pvf/src/execute/queue.rs @@ -372,7 +372,7 @@ fn handle_job_finish( ?artifact_id, ?worker, worker_rip = idle_worker.is_none(), - "execution worker concluded, error occurred: {:?}", + "execution worker concluded, error occurred: {}", err ); } else { diff --git a/polkadot/node/core/pvf/src/host.rs b/polkadot/node/core/pvf/src/host.rs index 21e13453edf..2668ce41583 100644 --- a/polkadot/node/core/pvf/src/host.rs +++ b/polkadot/node/core/pvf/src/host.rs @@ -486,7 +486,8 @@ async fn handle_precheck_pvf( /// /// If the prepare job failed previously, we may retry it under certain conditions. /// -/// When preparing for execution, we use a more lenient timeout ([`LENIENT_PREPARATION_TIMEOUT`]) +/// When preparing for execution, we use a more lenient timeout +/// ([`DEFAULT_LENIENT_PREPARATION_TIMEOUT`](polkadot_primitives::executor_params::DEFAULT_LENIENT_PREPARATION_TIMEOUT)) /// than when prechecking. async fn handle_execute_pvf( artifacts: &mut Artifacts, diff --git a/polkadot/node/core/pvf/src/prepare/queue.rs b/polkadot/node/core/pvf/src/prepare/queue.rs index c140a6cafda..c7bfa2f3b21 100644 --- a/polkadot/node/core/pvf/src/prepare/queue.rs +++ b/polkadot/node/core/pvf/src/prepare/queue.rs @@ -45,8 +45,8 @@ pub struct FromQueue { /// Identifier of an artifact. pub(crate) artifact_id: ArtifactId, /// Outcome of the PVF processing. [`Ok`] indicates that compiled artifact - /// is successfully stored on disk. Otherwise, an [error](crate::error::PrepareError) - /// is supplied. + /// is successfully stored on disk. Otherwise, an + /// [error](polkadot_node_core_pvf_common::error::PrepareError) is supplied. pub(crate) result: PrepareResult, } diff --git a/polkadot/node/core/pvf/src/prepare/worker_interface.rs b/polkadot/node/core/pvf/src/prepare/worker_interface.rs index 45e31a5f453..d64ee1510ca 100644 --- a/polkadot/node/core/pvf/src/prepare/worker_interface.rs +++ b/polkadot/node/core/pvf/src/prepare/worker_interface.rs @@ -174,7 +174,7 @@ pub async fn start_work( gum::warn!( target: LOG_TARGET, worker_pid = %pid, - "failed to recv a prepare response: {:?}", + "failed to recv a prepare response: {}", err, ); Outcome::IoErr(err.to_string()) -- GitLab From 66b2fa2e5950950b6800dedea2f333e0ae6bc9f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 15:04:02 +0000 Subject: [PATCH 085/392] Bump libc from 0.2.149 to 0.2.152 (#2994) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [libc](https://github.com/rust-lang/libc) from 0.2.149 to 0.2.152.
Release notes

Sourced from libc's releases.

0.2.152

What's Changed

New Contributors

Full Changelog: https://github.com/rust-lang/libc/compare/0.2.151...0.2.152

0.2.151

What's Changed

... (truncated)

Commits
  • 3d17519 Merge pull request #3522 from JohnTitor/libc-0.2.152
  • 0f5d2c1 Prepare release for v0.2.152
  • ee500ca Merge pull request #3521 from rust-lang/main
  • 72093f3 Auto merge of #3510 - JohnTitor:prepare-libc-0.3, r=JohnTitor
  • e5612b9 Auto merge of #3520 - devnexen:fuchsia_upd, r=JohnTitor
  • 44ba265 fuchsia adding pthread_set/getname_np
  • 2f93bfb Auto merge of #3519 - JohnTitor:tweak-libc-0.2-ci, r=JohnTitor
  • 11f7c7b Auto merge of #3518 - asomers:more-sigsuspend, r=JohnTitor
  • 0b9596b Tweak libc-0.2 CI
  • 5594447 Auto merge of #3517 - shuoer86:main, r=JohnTitor
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=libc&package-manager=cargo&previous-version=0.2.149&new-version=0.2.152)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- polkadot/node/core/pvf/Cargo.toml | 2 +- polkadot/node/core/pvf/common/Cargo.toml | 2 +- polkadot/node/core/pvf/execute-worker/Cargo.toml | 2 +- polkadot/node/core/pvf/prepare-worker/Cargo.toml | 2 +- substrate/client/executor/wasmtime/Cargo.toml | 2 +- substrate/client/tracing/Cargo.toml | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 87a2dad7549..74d87c2afc8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7218,9 +7218,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.149" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libflate" diff --git a/polkadot/node/core/pvf/Cargo.toml b/polkadot/node/core/pvf/Cargo.toml index be35dc47b8a..73facf8475a 100644 --- a/polkadot/node/core/pvf/Cargo.toml +++ b/polkadot/node/core/pvf/Cargo.toml @@ -18,7 +18,7 @@ futures = "0.3.21" futures-timer = "3.0.2" gum = { package = "tracing-gum", path = "../../gum" } is_executable = "1.0.1" -libc = "0.2.139" +libc = "0.2.152" pin-project = "1.0.9" rand = "0.8.5" slotmap = "1.0" diff --git a/polkadot/node/core/pvf/common/Cargo.toml b/polkadot/node/core/pvf/common/Cargo.toml index 974965be593..b4f6ada9dbb 100644 --- a/polkadot/node/core/pvf/common/Cargo.toml +++ b/polkadot/node/core/pvf/common/Cargo.toml @@ -14,7 +14,7 @@ cfg-if = "1.0" cpu-time = "1.0.0" futures = "0.3.21" gum = { package = "tracing-gum", path = "../../../gum" } -libc = "0.2.139" +libc = "0.2.152" thiserror = "1.0.31" parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } diff --git a/polkadot/node/core/pvf/execute-worker/Cargo.toml b/polkadot/node/core/pvf/execute-worker/Cargo.toml index 97dde59ebc2..83118041fdf 100644 --- a/polkadot/node/core/pvf/execute-worker/Cargo.toml +++ b/polkadot/node/core/pvf/execute-worker/Cargo.toml @@ -14,7 +14,7 @@ cpu-time = "1.0.0" gum = { package = "tracing-gum", path = "../../../gum" } os_pipe = "1.1.4" nix = { version = "0.27.1", features = ["process", "resource"] } -libc = "0.2.139" +libc = "0.2.152" parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } diff --git a/polkadot/node/core/pvf/prepare-worker/Cargo.toml b/polkadot/node/core/pvf/prepare-worker/Cargo.toml index 81e887afe4d..2ef3dfc0e74 100644 --- a/polkadot/node/core/pvf/prepare-worker/Cargo.toml +++ b/polkadot/node/core/pvf/prepare-worker/Cargo.toml @@ -13,7 +13,7 @@ workspace = true blake3 = "1.5" cfg-if = "1.0" gum = { package = "tracing-gum", path = "../../../gum" } -libc = "0.2.139" +libc = "0.2.152" rayon = "1.5.1" tracking-allocator = { package = "staging-tracking-allocator", path = "../../../tracking-allocator" } tikv-jemalloc-ctl = { version = "0.5.0", optional = true } diff --git a/substrate/client/executor/wasmtime/Cargo.toml b/substrate/client/executor/wasmtime/Cargo.toml index f8df23a026e..c1e866502fc 100644 --- a/substrate/client/executor/wasmtime/Cargo.toml +++ b/substrate/client/executor/wasmtime/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] log = "0.4.17" cfg-if = "1.0" -libc = "0.2.121" +libc = "0.2.152" parking_lot = "0.12.1" # When bumping wasmtime do not forget to also bump rustix diff --git a/substrate/client/tracing/Cargo.toml b/substrate/client/tracing/Cargo.toml index fe288474ac9..bca6110846a 100644 --- a/substrate/client/tracing/Cargo.toml +++ b/substrate/client/tracing/Cargo.toml @@ -21,7 +21,7 @@ is-terminal = "0.4.9" chrono = "0.4.31" codec = { package = "parity-scale-codec", version = "3.6.1" } lazy_static = "1.4.0" -libc = "0.2.121" +libc = "0.2.152" log = { version = "0.4.17" } parking_lot = "0.12.1" regex = "1.6.0" -- GitLab From 50a2e28b00196453966ac9858640ee1c4356ef8e Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Fri, 19 Jan 2024 16:14:26 +0100 Subject: [PATCH 086/392] Enable cross-chain NFT transfers on asset-hub (#2796) This PR introduces the following changes: - [x] Adds a `UniquesTransactor` to asset-hub-rococo - [x] Adds a `UniquesTransactor` to asset-hub-westend We can't add a transactor for `pallet-nfts` like we do for `pallet-uniques` because `pallet-nfts` uses `nonfungibles_v2::Mutate` instead of `nonfungibles::Mutate`, and making that work would be out of scope of this PR. With these modifications, reserve-based NFT cross-chain transfers can be performed on asset-hub. --------- Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> --- cumulus/parachains/common/src/lib.rs | 6 +++ .../assets/asset-hub-rococo/src/lib.rs | 14 +++--- .../assets/asset-hub-rococo/src/xcm_config.rs | 46 +++++++++++++++---- .../assets/asset-hub-westend/src/lib.rs | 14 +++--- .../asset-hub-westend/src/xcm_config.rs | 45 ++++++++++++++---- .../runtimes/assets/common/src/lib.rs | 17 ++++++- prdoc/pr_2796.prdoc | 12 +++++ 7 files changed, 122 insertions(+), 32 deletions(-) create mode 100644 prdoc/pr_2796.prdoc diff --git a/cumulus/parachains/common/src/lib.rs b/cumulus/parachains/common/src/lib.rs index eab5d7f4577..68ba10094c0 100644 --- a/cumulus/parachains/common/src/lib.rs +++ b/cumulus/parachains/common/src/lib.rs @@ -67,6 +67,12 @@ mod types { // Id used for identifying assets. pub type AssetIdForTrustBackedAssets = u32; + + // Id used for identifying non-fungible collections. + pub type CollectionId = u32; + + // Id used for identifying non-fungible items. + pub type ItemId = u32; } /// Common constants of parachains. diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 494ca3d1240..0f379a6f7bc 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -76,9 +76,9 @@ use parachains_common::{ impls::DealWithFees, message_queue::{NarrowOriginToSibling, ParaIdToSibling}, rococo::{consensus::*, currency::*, fee::WeightToFee}, - AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, BlockNumber, Hash, Header, Nonce, - Signature, AVERAGE_ON_INITIALIZE_RATIO, DAYS, HOURS, MAXIMUM_BLOCK_WEIGHT, - NORMAL_DISPATCH_RATIO, SLOT_DURATION, + AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, BlockNumber, CollectionId, Hash, + Header, ItemId, Nonce, Signature, AVERAGE_ON_INITIALIZE_RATIO, DAYS, HOURS, + MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, }; use sp_runtime::{Perbill, RuntimeDebug}; use xcm_config::{ @@ -773,8 +773,8 @@ parameter_types! { impl pallet_uniques::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type CollectionId = u32; - type ItemId = u32; + type CollectionId = CollectionId; + type ItemId = ItemId; type Currency = Balances; type ForceOrigin = AssetsForceOrigin; type CollectionDeposit = UniquesCollectionDeposit; @@ -831,8 +831,8 @@ parameter_types! { impl pallet_nfts::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type CollectionId = u32; - type ItemId = u32; + type CollectionId = CollectionId; + type ItemId = ItemId; type Currency = Balances; type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = AssetsForceOrigin; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs index b9b9025b697..9e1affb533a 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs @@ -17,7 +17,8 @@ use super::{ AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, BaseDeliveryFee, CollatorSelection, FeeAssetId, ForeignAssets, ForeignAssetsInstance, ParachainInfo, ParachainSystem, PolkadotXcm, PoolAssets, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, - ToWestendXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, + ToWestendXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, Uniques, WeightToFee, + XcmpQueue, }; use assets_common::{ local_and_foreign_assets::MatchesLocalAndForeignAssetsLocation, @@ -54,12 +55,12 @@ use xcm_builder::{ AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, DenyReserveTransferToRelayChain, DenyThenTry, DescribeAllTerminal, DescribeFamily, EnsureXcmOrigin, FungiblesAdapter, GlobalConsensusParachainConvertsFor, HashedDescription, IsConcrete, LocalMint, - NetworkExportTableItem, NoChecking, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, - SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, - SignedToAccountId32, SovereignPaidRemoteExporter, SovereignSignedViaLocation, StartsWith, - StartsWithExplicitGlobalConsensus, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, - WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, XcmFeeManagerFromComponents, - XcmFeeToAccount, + NetworkExportTableItem, NoChecking, NonFungiblesAdapter, ParentAsSuperuser, ParentIsPreset, + RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, + SignedAccountId32AsNative, SignedToAccountId32, SovereignPaidRemoteExporter, + SovereignSignedViaLocation, StartsWith, StartsWithExplicitGlobalConsensus, TakeWeightCredit, + TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, + XcmFeeManagerFromComponents, XcmFeeToAccount, }; use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; @@ -80,6 +81,8 @@ parameter_types! { PalletInstance(::index() as u8).into(); pub PoolAssetsPalletLocation: Location = PalletInstance(::index() as u8).into(); + pub UniquesPalletLocation: Location = + PalletInstance(::index() as u8).into(); pub PoolAssetsPalletLocationV3: xcm::v3::Location = xcm::v3::Junction::PalletInstance(::index() as u8).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); @@ -145,6 +148,26 @@ pub type FungiblesTransactor = FungiblesAdapter< CheckingAccount, >; +/// Matcher for converting `ClassId`/`InstanceId` into a uniques asset. +pub type UniquesConvertedConcreteId = + assets_common::UniquesConvertedConcreteId; + +/// Means for transacting unique assets. +pub type UniquesTransactor = NonFungiblesAdapter< + // Use this non-fungibles implementation: + Uniques, + // This adapter will handle any non-fungible asset from the uniques pallet. + UniquesConvertedConcreteId, + // Convert an XCM Location into a local account id: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // Does not check teleports. + NoChecking, + // The account to use for tracking teleports. + CheckingAccount, +>; + /// `AssetId`/`Balance` converter for `ForeignAssets`. pub type ForeignAssetsConvertedConcreteId = assets_common::ForeignAssetsConvertedConcreteId< ( @@ -198,8 +221,13 @@ pub type PoolFungiblesTransactor = FungiblesAdapter< >; /// Means for transacting assets on this chain. -pub type AssetTransactors = - (CurrencyTransactor, FungiblesTransactor, ForeignFungiblesTransactor, PoolFungiblesTransactor); +pub type AssetTransactors = ( + CurrencyTransactor, + FungiblesTransactor, + ForeignFungiblesTransactor, + PoolFungiblesTransactor, + UniquesTransactor, +); /// Simple `Location` matcher for Local and Foreign asset `Location`. pub struct LocalAndForeignAssetsLocationMatcher; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 5950173d90e..310726349fa 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -60,9 +60,9 @@ use parachains_common::{ impls::DealWithFees, message_queue::*, westend::{consensus::*, currency::*, fee::WeightToFee}, - AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, BlockNumber, Hash, Header, Nonce, - Signature, AVERAGE_ON_INITIALIZE_RATIO, DAYS, HOURS, MAXIMUM_BLOCK_WEIGHT, - NORMAL_DISPATCH_RATIO, SLOT_DURATION, + AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, BlockNumber, CollectionId, Hash, + Header, ItemId, Nonce, Signature, AVERAGE_ON_INITIALIZE_RATIO, DAYS, HOURS, + MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, }; use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; @@ -748,8 +748,8 @@ parameter_types! { impl pallet_uniques::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type CollectionId = u32; - type ItemId = u32; + type CollectionId = CollectionId; + type ItemId = ItemId; type Currency = Balances; type ForceOrigin = AssetsForceOrigin; type CollectionDeposit = UniquesCollectionDeposit; @@ -806,8 +806,8 @@ parameter_types! { impl pallet_nfts::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type CollectionId = u32; - type ItemId = u32; + type CollectionId = CollectionId; + type ItemId = ItemId; type Currency = Balances; type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = AssetsForceOrigin; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs index 70522eda4b7..0f4ce360ee4 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs @@ -17,7 +17,8 @@ use super::{ AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, BaseDeliveryFee, CollatorSelection, FeeAssetId, ForeignAssets, ForeignAssetsInstance, ParachainInfo, ParachainSystem, PolkadotXcm, PoolAssets, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, - ToRococoXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, + ToRococoXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, Uniques, WeightToFee, + XcmpQueue, }; use assets_common::{ local_and_foreign_assets::MatchesLocalAndForeignAssetsLocation, @@ -52,11 +53,12 @@ use xcm_builder::{ AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, DenyReserveTransferToRelayChain, DenyThenTry, DescribeFamily, DescribePalletTerminal, EnsureXcmOrigin, FungiblesAdapter, GlobalConsensusParachainConvertsFor, HashedDescription, IsConcrete, LocalMint, - NetworkExportTableItem, NoChecking, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, - SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, - SignedToAccountId32, SovereignSignedViaLocation, StartsWith, StartsWithExplicitGlobalConsensus, - TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, - WithUniqueTopic, XcmFeeManagerFromComponents, XcmFeeToAccount, + NetworkExportTableItem, NoChecking, NonFungiblesAdapter, ParentAsSuperuser, ParentIsPreset, + RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, + SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, StartsWith, + StartsWithExplicitGlobalConsensus, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, + WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, XcmFeeManagerFromComponents, + XcmFeeToAccount, }; use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; @@ -77,6 +79,8 @@ parameter_types! { PalletInstance(::index() as u8).into(); pub PoolAssetsPalletLocation: Location = PalletInstance(::index() as u8).into(); + pub UniquesPalletLocation: Location = + PalletInstance(::index() as u8).into(); pub PoolAssetsPalletLocationV3: xcm::v3::Location = xcm::v3::Junction::PalletInstance(::index() as u8).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); @@ -139,6 +143,26 @@ pub type FungiblesTransactor = FungiblesAdapter< CheckingAccount, >; +/// Matcher for converting `ClassId`/`InstanceId` into a uniques asset. +pub type UniquesConvertedConcreteId = + assets_common::UniquesConvertedConcreteId; + +/// Means for transacting unique assets. +pub type UniquesTransactor = NonFungiblesAdapter< + // Use this non-fungibles implementation: + Uniques, + // This adapter will handle any non-fungible asset from the uniques pallet. + UniquesConvertedConcreteId, + // Convert an XCM Location into a local account id: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // Does not check teleports. + NoChecking, + // The account to use for tracking teleports. + CheckingAccount, +>; + /// `AssetId`/`Balance` converter for `ForeignAssets`. pub type ForeignAssetsConvertedConcreteId = assets_common::ForeignAssetsConvertedConcreteId< ( @@ -192,8 +216,13 @@ pub type PoolFungiblesTransactor = FungiblesAdapter< >; /// Means for transacting assets on this chain. -pub type AssetTransactors = - (CurrencyTransactor, FungiblesTransactor, ForeignFungiblesTransactor, PoolFungiblesTransactor); +pub type AssetTransactors = ( + CurrencyTransactor, + FungiblesTransactor, + ForeignFungiblesTransactor, + PoolFungiblesTransactor, + UniquesTransactor, +); /// Simple `Location` matcher for Local and Foreign asset `Location`. pub struct LocalAndForeignAssetsLocationMatcher; diff --git a/cumulus/parachains/runtimes/assets/common/src/lib.rs b/cumulus/parachains/runtimes/assets/common/src/lib.rs index f21e1766436..a0c912b6f0f 100644 --- a/cumulus/parachains/runtimes/assets/common/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/common/src/lib.rs @@ -25,7 +25,7 @@ pub mod runtime_api; use crate::matching::{LocalLocationPattern, ParentLocation}; use frame_support::traits::{Equals, EverythingBut}; -use parachains_common::AssetIdForTrustBackedAssets; +use parachains_common::{AssetIdForTrustBackedAssets, CollectionId, ItemId}; use xcm_builder::{ AsPrefixedGeneralIndex, MatchedConvertedConcreteId, StartsWith, V4V3LocationConverter, }; @@ -43,6 +43,10 @@ pub type AssetIdForTrustBackedAssetsConvert = pub type AssetIdForTrustBackedAssetsConvertLatest = AsPrefixedGeneralIndex; +/// `Location` vs `CollectionId` converter for `Uniques` +pub type CollectionIdForUniquesConvert = + AsPrefixedGeneralIndex; + /// [`MatchedConvertedConcreteId`] converter dedicated for `TrustBackedAssets` pub type TrustBackedAssetsConvertedConcreteId = MatchedConvertedConcreteId< @@ -53,6 +57,17 @@ pub type TrustBackedAssetsConvertedConcreteId; +/// [`MatchedConvertedConcreteId`] converter dedicated for `Uniques` +pub type UniquesConvertedConcreteId = MatchedConvertedConcreteId< + CollectionId, + ItemId, + // The asset starts with the uniques pallet. The `CollectionId` of the asset is specified as a + // junction within the pallet itself. + StartsWith, + CollectionIdForUniquesConvert, + JustTry, +>; + /// [`MatchedConvertedConcreteId`] converter dedicated for storing `AssetId` as `Location`. pub type LocationConvertedConcreteId = MatchedConvertedConcreteId< xcm::v3::Location, diff --git a/prdoc/pr_2796.prdoc b/prdoc/pr_2796.prdoc new file mode 100644 index 00000000000..15cb005d286 --- /dev/null +++ b/prdoc/pr_2796.prdoc @@ -0,0 +1,12 @@ +title: Rococo and Westend Asset-Hub: XCM Transfers with Pallet-Uniques + +doc: + - audience: Runtime User + description: | + With the added `UniquesTransactor` Rococo and Westend Asset-Hub are now capable of handling + XCM transfers with pallet-uniques. + +crates: + - name: "asset-hub-rococo-runtime" + - name: "asset-hub-westend-runtime" + - name: "assets-common" -- GitLab From 2e9b4405edb4d285cc51c15da2cc4d0785e7c32d Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Fri, 19 Jan 2024 17:12:30 +0100 Subject: [PATCH 087/392] Contract fixtures tests: fixe nightly version (#3000) Using just `nightly` is too generic and can fail on different systems. Now its fixed to the nightly version of the CI. Another way would be to use a toolchain file, since this already assumes `rustup`. Signed-off-by: Oliver Tale-Yazdi --- substrate/frame/contracts/fixtures/build.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/substrate/frame/contracts/fixtures/build.rs b/substrate/frame/contracts/fixtures/build.rs index 8e00bbc9d09..5f174d200b9 100644 --- a/substrate/frame/contracts/fixtures/build.rs +++ b/substrate/frame/contracts/fixtures/build.rs @@ -159,7 +159,7 @@ fn invoke_cargo_fmt<'a>( ) -> Result<()> { // If rustfmt is not installed, skip the check. if !Command::new("rustup") - .args(["run", "nightly", "rustfmt", "--version"]) + .args(["nightly-2023-11-01", "run", "rustfmt", "--version"]) .output() .map_or(false, |o| o.status.success()) { @@ -167,7 +167,7 @@ fn invoke_cargo_fmt<'a>( } let fmt_res = Command::new("rustup") - .args(["run", "nightly", "rustfmt", "--check", "--config-path"]) + .args(["nightly-2023-11-01", "run", "rustfmt", "--check", "--config-path"]) .arg(config_path) .args(files) .output() @@ -182,7 +182,7 @@ fn invoke_cargo_fmt<'a>( eprintln!("{}\n{}", stdout, stderr); eprintln!( "Fixtures files are not formatted.\n - Please run `rustup run nightly rustfmt --config-path {} {}/*.rs`", + Please run `rustup nightly-2023-11-01 run rustfmt --config-path {} {}/*.rs`", config_path.display(), contract_dir.display() ); -- GitLab From 320b52892e556fe687e85e01df5c425f7eef39cf Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Fri, 19 Jan 2024 17:50:24 +0100 Subject: [PATCH 088/392] Update bridges subtree (#2996) Update bridges subtree --- bridges/bin/runtime-common/src/lib.rs | 1 + bridges/bin/runtime-common/src/messages.rs | 41 +--- .../runtime-common/src/messages_call_ext.rs | 7 +- .../src/messages_xcm_extension.rs | 5 +- bridges/bin/runtime-common/src/mock.rs | 9 +- .../src/parachains_benchmarking.rs | 2 +- .../src/refund_relayer_extension.rs | 6 +- bridges/modules/grandpa/src/lib.rs | 5 +- bridges/modules/grandpa/src/mock.rs | 6 +- bridges/modules/messages/README.md | 26 +- bridges/modules/messages/src/benchmarking.rs | 4 +- bridges/modules/messages/src/lib.rs | 231 +++++++++--------- bridges/modules/messages/src/mock.rs | 36 +-- bridges/modules/messages/src/outbound_lane.rs | 58 ++--- bridges/modules/parachains/src/call_ext.rs | 2 +- bridges/modules/parachains/src/lib.rs | 34 ++- bridges/modules/parachains/src/mock.rs | 14 +- .../modules/xcm-bridge-hub/src/exporter.rs | 71 +++--- bridges/modules/xcm-bridge-hub/src/mock.rs | 22 +- .../chain-bridge-hub-cumulus/src/lib.rs | 5 + .../chain-bridge-hub-kusama/src/lib.rs | 14 +- .../chain-bridge-hub-polkadot/src/lib.rs | 15 +- .../chain-bridge-hub-rococo/src/lib.rs | 15 +- .../chain-bridge-hub-westend/Cargo.toml | 4 +- .../chain-bridge-hub-westend/src/lib.rs | 14 +- bridges/primitives/chain-kusama/src/lib.rs | 29 ++- .../chain-polkadot-bulletin/src/lib.rs | 16 +- bridges/primitives/chain-polkadot/src/lib.rs | 31 ++- bridges/primitives/chain-rococo/src/lib.rs | 35 ++- bridges/primitives/chain-westend/src/lib.rs | 35 ++- bridges/primitives/header-chain/src/lib.rs | 14 +- bridges/primitives/messages/src/lib.rs | 47 +++- .../primitives/messages/src/source_chain.rs | 58 ++--- bridges/primitives/parachains/src/lib.rs | 4 + bridges/primitives/polkadot-core/src/lib.rs | 48 ++-- .../polkadot-core/src/parachains.rs | 13 +- bridges/primitives/runtime/src/chain.rs | 8 +- bridges/primitives/runtime/src/extensions.rs | 2 + bridges/primitives/runtime/src/lib.rs | 45 +--- bridges/primitives/test-utils/src/keyring.rs | 10 +- bridges/primitives/test-utils/src/lib.rs | 6 +- .../pallets/ethereum-client/Cargo.toml | 2 +- .../pallets/inbound-queue/Cargo.toml | 2 +- .../pallets/outbound-queue/Cargo.toml | 2 +- .../parachain/primitives/beacon/Cargo.toml | 2 +- .../parachain/primitives/core/Cargo.toml | 2 +- .../parachain/primitives/router/Cargo.toml | 2 +- .../parachain/runtime/test-common/Cargo.toml | 2 +- .../src/bridge_to_bulletin_config.rs | 8 +- .../src/bridge_to_westend_config.rs | 10 +- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 4 +- .../src/bridge_to_rococo_config.rs | 10 +- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 4 +- 53 files changed, 565 insertions(+), 533 deletions(-) diff --git a/bridges/bin/runtime-common/src/lib.rs b/bridges/bin/runtime-common/src/lib.rs index d3b3b21061d..2722f6f1c6d 100644 --- a/bridges/bin/runtime-common/src/lib.rs +++ b/bridges/bin/runtime-common/src/lib.rs @@ -16,6 +16,7 @@ //! Common types/functions that may be used by runtimes of all bridged chains. +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] use crate::messages_call_ext::MessagesCallSubType; diff --git a/bridges/bin/runtime-common/src/messages.rs b/bridges/bin/runtime-common/src/messages.rs index ac66adae661..4aca53f3b98 100644 --- a/bridges/bin/runtime-common/src/messages.rs +++ b/bridges/bin/runtime-common/src/messages.rs @@ -24,7 +24,7 @@ pub use bp_runtime::{RangeInclusiveExt, UnderlyingChainOf, UnderlyingChainProvid use bp_header_chain::HeaderChain; use bp_messages::{ - source_chain::{LaneMessageVerifier, TargetHeaderChain}, + source_chain::TargetHeaderChain, target_chain::{ProvedLaneMessages, ProvedMessages, SourceHeaderChain}, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, VerificationError, @@ -120,42 +120,6 @@ pub mod source { pub type ParsedMessagesDeliveryProofFromBridgedChain = (LaneId, InboundLaneData>>); - /// Message verifier that is doing all basic checks. - /// - /// This verifier assumes following: - /// - /// - all message lanes are equivalent, so all checks are the same; - /// - /// Following checks are made: - /// - /// - message is rejected if its lane is currently blocked; - /// - message is rejected if there are too many pending (undelivered) messages at the outbound - /// lane; - /// - check that the sender has rights to dispatch the call on target chain using provided - /// dispatch origin; - /// - check that the sender has paid enough funds for both message delivery and dispatch. - #[derive(RuntimeDebug)] - pub struct FromThisChainMessageVerifier(PhantomData); - - impl LaneMessageVerifier for FromThisChainMessageVerifier - where - B: MessageBridge, - { - fn verify_message( - _lane: &LaneId, - _lane_outbound_data: &OutboundLaneData, - _payload: &FromThisChainMessagePayload, - ) -> Result<(), VerificationError> { - // IMPORTANT: any error that is returned here is fatal for the bridge, because - // this code is executed at the bridge hub and message sender actually lives - // at some sibling parachain. So we are failing **after** the message has been - // sent and we can't report it back to sender (unless error report mechanism is - // embedded into message and its dispatcher). - - Ok(()) - } - } - /// Return maximal message size of This -> Bridged chain message. pub fn maximal_message_size() -> u32 { super::target::maximal_incoming_message_size( @@ -185,8 +149,7 @@ pub mod source { /// Do basic Bridged-chain specific verification of This -> Bridged chain message. /// /// Ok result from this function means that the delivery transaction with this message - /// may be 'mined' by the target chain. But the lane may have its own checks (e.g. fee - /// check) that would reject message (see `FromThisChainMessageVerifier`). + /// may be 'mined' by the target chain. pub fn verify_chain_message( payload: &FromThisChainMessagePayload, ) -> Result<(), VerificationError> { diff --git a/bridges/bin/runtime-common/src/messages_call_ext.rs b/bridges/bin/runtime-common/src/messages_call_ext.rs index 5303fcb7ba0..fb07f7b6dd6 100644 --- a/bridges/bin/runtime-common/src/messages_call_ext.rs +++ b/bridges/bin/runtime-common/src/messages_call_ext.rs @@ -14,6 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +//! Signed extension for the `pallet-bridge-messages` that is able to reject obsolete +//! (and some other invalid) transactions. + use crate::messages::{ source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, }; @@ -116,7 +119,9 @@ impl ReceiveMessagesDeliveryProofInfo { /// which tries to update a single lane. #[derive(PartialEq, RuntimeDebug)] pub enum CallInfo { + /// Messages delivery call info. ReceiveMessagesProof(ReceiveMessagesProofInfo), + /// Messages delivery confirmation call info. ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo), } @@ -132,7 +137,7 @@ impl CallInfo { /// Helper struct that provides methods for working with a call supported by `CallInfo`. pub struct CallHelper, I: 'static> { - pub _phantom_data: sp_std::marker::PhantomData<(T, I)>, + _phantom_data: sp_std::marker::PhantomData<(T, I)>, } impl, I: 'static> CallHelper { diff --git a/bridges/bin/runtime-common/src/messages_xcm_extension.rs b/bridges/bin/runtime-common/src/messages_xcm_extension.rs index fd2c20af72a..e3da6155f08 100644 --- a/bridges/bin/runtime-common/src/messages_xcm_extension.rs +++ b/bridges/bin/runtime-common/src/messages_xcm_extension.rs @@ -40,11 +40,14 @@ use sp_std::{fmt::Debug, marker::PhantomData}; use xcm::prelude::*; use xcm_builder::{DispatchBlob, DispatchBlobError}; -/// Message dispatch result type for single message +/// Message dispatch result type for single message. #[derive(CloneNoBound, EqNoBound, PartialEqNoBound, Encode, Decode, Debug, TypeInfo)] pub enum XcmBlobMessageDispatchResult { + /// We've been unable to decode message payload. InvalidPayload, + /// Message has been dispatched. Dispatched, + /// Message has **NOT** been dispatched because of given error. NotDispatched(#[codec(skip)] Option), } diff --git a/bridges/bin/runtime-common/src/mock.rs b/bridges/bin/runtime-common/src/mock.rs index bd47d37fc07..8877a4fd95c 100644 --- a/bridges/bin/runtime-common/src/mock.rs +++ b/bridges/bin/runtime-common/src/mock.rs @@ -21,7 +21,7 @@ use crate::messages::{ source::{ FromThisChainMaximalOutboundPayloadSize, FromThisChainMessagePayload, - FromThisChainMessageVerifier, TargetHeaderChainAdapter, + TargetHeaderChainAdapter, }, target::{FromBridgedChainMessagePayload, SourceHeaderChainAdapter}, BridgedChainWithMessages, HashOf, MessageBridge, ThisChainWithMessages, @@ -213,7 +213,6 @@ impl pallet_bridge_messages::Config for TestRuntime { type DeliveryPayments = (); type TargetHeaderChain = TargetHeaderChainAdapter; - type LaneMessageVerifier = FromThisChainMessageVerifier; type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< TestRuntime, (), @@ -315,6 +314,8 @@ impl From pub struct ThisUnderlyingChain; impl Chain for ThisUnderlyingChain { + const ID: ChainId = *b"tuch"; + type BlockNumber = ThisChainBlockNumber; type Hash = ThisChainHash; type Hasher = ThisChainHasher; @@ -355,6 +356,8 @@ pub struct BridgedUnderlyingParachain; pub struct BridgedChainCall; impl Chain for BridgedUnderlyingChain { + const ID: ChainId = *b"buch"; + type BlockNumber = BridgedChainBlockNumber; type Hash = BridgedChainHash; type Hasher = BridgedChainHasher; @@ -381,6 +384,8 @@ impl ChainWithGrandpa for BridgedUnderlyingChain { } impl Chain for BridgedUnderlyingParachain { + const ID: ChainId = *b"bupc"; + type BlockNumber = BridgedChainBlockNumber; type Hash = BridgedChainHash; type Hasher = BridgedChainHasher; diff --git a/bridges/bin/runtime-common/src/parachains_benchmarking.rs b/bridges/bin/runtime-common/src/parachains_benchmarking.rs index 63dc78385e4..b3050b9ac0f 100644 --- a/bridges/bin/runtime-common/src/parachains_benchmarking.rs +++ b/bridges/bin/runtime-common/src/parachains_benchmarking.rs @@ -84,5 +84,5 @@ where let (relay_block_number, relay_block_hash) = insert_header_to_grandpa_pallet::(state_root); - (relay_block_number, relay_block_hash, ParaHeadsProof(proof), parachain_heads) + (relay_block_number, relay_block_hash, ParaHeadsProof { storage_proof: proof }, parachain_heads) } diff --git a/bridges/bin/runtime-common/src/refund_relayer_extension.rs b/bridges/bin/runtime-common/src/refund_relayer_extension.rs index 6d8b2114808..27b7ff1a551 100644 --- a/bridges/bin/runtime-common/src/refund_relayer_extension.rs +++ b/bridges/bin/runtime-common/src/refund_relayer_extension.rs @@ -116,7 +116,7 @@ where /// Refund calculator. pub trait RefundCalculator { - // The underlying integer type in which the refund is calculated. + /// The underlying integer type in which the refund is calculated. type Balance; /// Compute refund for given transaction. @@ -986,7 +986,7 @@ mod tests { ParaId(TestParachain::get()), [parachain_head_at_relay_header_number as u8; 32].into(), )], - parachain_heads_proof: ParaHeadsProof(vec![]), + parachain_heads_proof: ParaHeadsProof { storage_proof: vec![] }, }) } @@ -1732,7 +1732,7 @@ mod tests { (ParaId(TestParachain::get()), [1u8; 32].into()), (ParaId(TestParachain::get() + 1), [1u8; 32].into()), ], - parachain_heads_proof: ParaHeadsProof(vec![]), + parachain_heads_proof: ParaHeadsProof { storage_proof: vec![] }, }), message_delivery_call(200), ], diff --git a/bridges/modules/grandpa/src/lib.rs b/bridges/modules/grandpa/src/lib.rs index 22df604bf18..f58db2481ad 100644 --- a/bridges/modules/grandpa/src/lib.rs +++ b/bridges/modules/grandpa/src/lib.rs @@ -32,9 +32,8 @@ //! Shall the fork occur on the bridged chain governance intervention will be required to //! re-initialize the bridge and track the right fork. +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -// Runtime-generated enums -#![allow(clippy::large_enum_variant)] pub use storage_types::StoredAuthoritySet; @@ -408,7 +407,9 @@ pub mod pallet { pub enum Event, I: 'static = ()> { /// Best finalized chain header has been updated to the header with given number and hash. UpdatedBestFinalizedHeader { + /// Number of the new best finalized header. number: BridgedBlockNumber, + /// Hash of the new best finalized header. hash: BridgedBlockHash, /// The Grandpa info associated to the new best finalized header. grandpa_info: StoredHeaderGrandpaInfo>, diff --git a/bridges/modules/grandpa/src/mock.rs b/bridges/modules/grandpa/src/mock.rs index a54f56c4a62..e41e89341b3 100644 --- a/bridges/modules/grandpa/src/mock.rs +++ b/bridges/modules/grandpa/src/mock.rs @@ -18,7 +18,7 @@ #![allow(clippy::from_over_into)] use bp_header_chain::ChainWithGrandpa; -use bp_runtime::Chain; +use bp_runtime::{Chain, ChainId}; use frame_support::{ construct_runtime, derive_impl, parameter_types, traits::Hooks, weights::Weight, }; @@ -64,7 +64,9 @@ impl grandpa::Config for TestRuntime { pub struct TestBridgedChain; impl Chain for TestBridgedChain { - type BlockNumber = TestNumber; + const ID: ChainId = *b"tbch"; + + type BlockNumber = frame_system::pallet_prelude::BlockNumberFor; type Hash = ::Hash; type Hasher = ::Hashing; type Header = TestHeader; diff --git a/bridges/modules/messages/README.md b/bridges/modules/messages/README.md index 457d5f5facf..fe62305748c 100644 --- a/bridges/modules/messages/README.md +++ b/bridges/modules/messages/README.md @@ -116,26 +116,12 @@ maximal possible transaction size of the chain and so on. And when the relayer s implementation must be able to parse and verify the proof of messages delivery. Normally, you would reuse the same (configurable) type on all chains that are sending messages to the same bridged chain. -The `pallet_bridge_messages::Config::LaneMessageVerifier` defines a single callback to verify outbound messages. The -simplest callback may just accept all messages. But in this case you'll need to answer many questions first. Who will -pay for the delivery and confirmation transaction? Are we sure that someone will ever deliver this message to the -bridged chain? Are we sure that we don't bloat our runtime storage by accepting this message? What if the message is -improperly encoded or has some fields set to invalid values? Answering all those (and similar) questions would lead to -correct implementation. - -There's another thing to consider when implementing type for use in -`pallet_bridge_messages::Config::LaneMessageVerifier`. It is whether we treat all message lanes identically, or they'll -have different sets of verification rules? For example, you may reserve lane#1 for messages coming from some -'wrapped-token' pallet - then you may verify in your implementation that the origin is associated with this pallet. -Lane#2 may be reserved for 'system' messages and you may charge zero fee for such messages. You may have some rate -limiting for messages sent over the lane#3. Or you may just verify the same rules set for all outbound messages - it is -all up to the `pallet_bridge_messages::Config::LaneMessageVerifier` implementation. - -The last type is the `pallet_bridge_messages::Config::DeliveryConfirmationPayments`. When confirmation transaction is -received, we call the `pay_reward()` method, passing the range of delivered messages. You may use the -[`pallet-bridge-relayers`](../relayers/) pallet and its -[`DeliveryConfirmationPaymentsAdapter`](../relayers/src/payment_adapter.rs) adapter as a possible implementation. It -allows you to pay fixed reward for relaying the message and some of its portion for confirming delivery. +The last type is the `pallet_bridge_messages::Config::DeliveryConfirmationPayments`. When confirmation +transaction is received, we call the `pay_reward()` method, passing the range of delivered messages. +You may use the [`pallet-bridge-relayers`](../relayers/) pallet and its +[`DeliveryConfirmationPaymentsAdapter`](../relayers/src/payment_adapter.rs) adapter as a possible +implementation. It allows you to pay fixed reward for relaying the message and some of its portion +for confirming delivery. ### I have a Messages Module in my Runtime, but I Want to Reject all Outbound Messages. What shall I do? diff --git a/bridges/modules/messages/src/benchmarking.rs b/bridges/modules/messages/src/benchmarking.rs index 8c4e6fbf00c..4f13c440967 100644 --- a/bridges/modules/messages/src/benchmarking.rs +++ b/bridges/modules/messages/src/benchmarking.rs @@ -31,7 +31,7 @@ use codec::Decode; use frame_benchmarking::{account, benchmarks_instance_pallet}; use frame_support::weights::Weight; use frame_system::RawOrigin; -use sp_runtime::traits::TrailingZeroInput; +use sp_runtime::{traits::TrailingZeroInput, BoundedVec}; use sp_std::{ops::RangeInclusive, prelude::*}; const SEED: u32 = 0; @@ -443,7 +443,7 @@ benchmarks_instance_pallet! { fn send_regular_message, I: 'static>() { let mut outbound_lane = outbound_lane::(T::bench_lane_id()); - outbound_lane.send_message(vec![]).expect("We craft valid messages"); + outbound_lane.send_message(BoundedVec::try_from(vec![]).expect("We craft valid messages")); } fn receive_messages, I: 'static>(nonce: MessageNonce) { diff --git a/bridges/modules/messages/src/lib.rs b/bridges/modules/messages/src/lib.rs index b87c64d1607..a86cb326cf0 100644 --- a/bridges/modules/messages/src/lib.rs +++ b/bridges/modules/messages/src/lib.rs @@ -33,9 +33,8 @@ //! If this test fails with your weights, then either weights are computed incorrectly, //! or some benchmarks assumptions are broken for your runtime. +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -// Generated by `decl_event!` -#![allow(clippy::unused_unit)] pub use inbound_lane::StoredInboundLaneData; pub use outbound_lane::StoredMessagePayload; @@ -53,8 +52,7 @@ use crate::{ use bp_messages::{ source_chain::{ - DeliveryConfirmationPayments, LaneMessageVerifier, OnMessagesDelivered, - SendMessageArtifacts, TargetHeaderChain, + DeliveryConfirmationPayments, OnMessagesDelivered, SendMessageArtifacts, TargetHeaderChain, }, target_chain::{ DeliveryPayments, DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, @@ -155,8 +153,6 @@ pub mod pallet { /// Target header chain. type TargetHeaderChain: TargetHeaderChain; - /// Message payload verifier. - type LaneMessageVerifier: LaneMessageVerifier; /// Delivery confirmation payments. type DeliveryConfirmationPayments: DeliveryConfirmationPayments; /// Delivery confirmation callback. @@ -517,16 +513,28 @@ pub mod pallet { #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event, I: 'static = ()> { /// Message has been accepted and is waiting to be delivered. - MessageAccepted { lane_id: LaneId, nonce: MessageNonce }, + MessageAccepted { + /// Lane, which has accepted the message. + lane_id: LaneId, + /// Nonce of accepted message. + nonce: MessageNonce, + }, /// Messages have been received from the bridged chain. MessagesReceived( + /// Result of received messages dispatch. Vec::DispatchLevelResult>>, ), /// Messages in the inclusive range have been delivered to the bridged chain. - MessagesDelivered { lane_id: LaneId, messages: DeliveredMessages }, + MessagesDelivered { + /// Lane for which the delivery has been confirmed. + lane_id: LaneId, + /// Delivered messages. + messages: DeliveredMessages, + }, } #[pallet::error] + #[derive(PartialEq, Eq)] pub enum Error { /// Pallet is not in Normal operating mode. NotOperatingNormally, @@ -536,8 +544,6 @@ pub mod pallet { MessageDispatchInactive, /// Message has been treated as invalid by chain verifier. MessageRejectedByChainVerifier(VerificationError), - /// Message has been treated as invalid by lane verifier. - MessageRejectedByLaneVerifier(VerificationError), /// Message has been treated as invalid by the pallet logic. MessageRejectedByPallet(VerificationError), /// Submitter has failed to pay fee for delivering and dispatching messages. @@ -683,80 +689,72 @@ pub mod pallet { } } +/// Structure, containing a validated message payload and all the info required +/// to send it on the bridge. +#[derive(Debug, PartialEq, Eq)] +pub struct SendMessageArgs, I: 'static> { + lane_id: LaneId, + payload: StoredMessagePayload, +} + impl bp_messages::source_chain::MessagesBridge for Pallet where T: Config, I: 'static, { - type Error = sp_runtime::DispatchErrorWithPostInfo; + type Error = Error; + type SendMessageArgs = SendMessageArgs; - fn send_message( + fn validate_message( lane: LaneId, - message: T::OutboundPayload, - ) -> Result { - crate::send_message::(lane, message) + message: &T::OutboundPayload, + ) -> Result, Self::Error> { + ensure_normal_operating_mode::()?; + + // let's check if outbound lane is active + ensure!(T::ActiveOutboundLanes::get().contains(&lane), Error::::InactiveOutboundLane); + + // let's first check if message can be delivered to target chain + T::TargetHeaderChain::verify_message(message).map_err(|err| { + log::trace!( + target: LOG_TARGET, + "Message to lane {:?} is rejected by target chain: {:?}", + lane, + err, + ); + + Error::::MessageRejectedByChainVerifier(err) + })?; + + Ok(SendMessageArgs { + lane_id: lane, + payload: StoredMessagePayload::::try_from(message.encode()).map_err(|_| { + Error::::MessageRejectedByPallet(VerificationError::MessageTooLarge) + })?, + }) } -} -/// Function that actually sends message. -fn send_message, I: 'static>( - lane_id: LaneId, - payload: T::OutboundPayload, -) -> sp_std::result::Result< - SendMessageArtifacts, - sp_runtime::DispatchErrorWithPostInfo, -> { - ensure_normal_operating_mode::()?; - - // let's check if outbound lane is active - ensure!(T::ActiveOutboundLanes::get().contains(&lane_id), Error::::InactiveOutboundLane,); - - // let's first check if message can be delivered to target chain - T::TargetHeaderChain::verify_message(&payload).map_err(|err| { - log::trace!( - target: LOG_TARGET, - "Message to lane {:?} is rejected by target chain: {:?}", - lane_id, - err, - ); + fn send_message(args: SendMessageArgs) -> SendMessageArtifacts { + // save message in outbound storage and emit event + let mut lane = outbound_lane::(args.lane_id); + let message_len = args.payload.len(); + let nonce = lane.send_message(args.payload); - Error::::MessageRejectedByChainVerifier(err) - })?; + // return number of messages in the queue to let sender know about its state + let enqueued_messages = lane.data().queued_messages().saturating_len(); - // now let's enforce any additional lane rules - let mut lane = outbound_lane::(lane_id); - T::LaneMessageVerifier::verify_message(&lane_id, &lane.data(), &payload).map_err(|err| { log::trace!( target: LOG_TARGET, - "Message to lane {:?} is rejected by lane verifier: {:?}", - lane_id, - err, + "Accepted message {} to lane {:?}. Message size: {:?}", + nonce, + args.lane_id, + message_len, ); - Error::::MessageRejectedByLaneVerifier(err) - })?; - - // finally, save message in outbound storage and emit event - let encoded_payload = payload.encode(); - let encoded_payload_len = encoded_payload.len(); - let nonce = lane - .send_message(encoded_payload) - .map_err(Error::::MessageRejectedByPallet)?; - - // return number of messages in the queue to let sender know about its state - let enqueued_messages = lane.data().queued_messages().saturating_len(); - - log::trace!( - target: LOG_TARGET, - "Accepted message {} to lane {:?}. Message size: {:?}", - nonce, - lane_id, - encoded_payload_len, - ); + Pallet::::deposit_event(Event::MessageAccepted { lane_id: args.lane_id, nonce }); - Pallet::::deposit_event(Event::MessageAccepted { lane_id, nonce }); - - Ok(SendMessageArtifacts { nonce, enqueued_messages }) + SendMessageArtifacts { nonce, enqueued_messages } + } } /// Ensure that the pallet is in normal operational mode. @@ -857,6 +855,8 @@ struct RuntimeOutboundLaneStorage { } impl, I: 'static> OutboundLaneStorage for RuntimeOutboundLaneStorage { + type StoredMessagePayload = StoredMessagePayload; + fn id(&self) -> LaneId { self.lane_id } @@ -870,22 +870,15 @@ impl, I: 'static> OutboundLaneStorage for RuntimeOutboundLaneStorag } #[cfg(test)] - fn message(&self, nonce: &MessageNonce) -> Option { + fn message(&self, nonce: &MessageNonce) -> Option { OutboundMessages::::get(MessageKey { lane_id: self.lane_id, nonce: *nonce }) - .map(Into::into) } - fn save_message( - &mut self, - nonce: MessageNonce, - message_payload: MessagePayload, - ) -> Result<(), VerificationError> { + fn save_message(&mut self, nonce: MessageNonce, message_payload: Self::StoredMessagePayload) { OutboundMessages::::insert( MessageKey { lane_id: self.lane_id, nonce }, - StoredMessagePayload::::try_from(message_payload) - .map_err(|_| VerificationError::MessageTooLarge)?, + message_payload, ); - Ok(()) } fn remove_message(&mut self, nonce: &MessageNonce) { @@ -932,7 +925,10 @@ mod tests { }, outbound_lane::ReceivalConfirmationError, }; - use bp_messages::{BridgeMessagesCall, UnrewardedRelayer, UnrewardedRelayersState}; + use bp_messages::{ + source_chain::MessagesBridge, BridgeMessagesCall, UnrewardedRelayer, + UnrewardedRelayersState, + }; use bp_test_utils::generate_owned_bridge_module_tests; use frame_support::{ assert_noop, assert_ok, @@ -949,14 +945,15 @@ mod tests { System::::reset_events(); } - fn send_regular_message() { + fn send_regular_message(lane_id: LaneId) { get_ready_for_events(); - let outbound_lane = outbound_lane::(TEST_LANE_ID); + let outbound_lane = outbound_lane::(lane_id); let message_nonce = outbound_lane.data().latest_generated_nonce + 1; let prev_enqueud_messages = outbound_lane.data().queued_messages().saturating_len(); - let artifacts = send_message::(TEST_LANE_ID, REGULAR_PAYLOAD) - .expect("send_message has failed"); + let valid_message = Pallet::::validate_message(lane_id, ®ULAR_PAYLOAD) + .expect("validate_message has failed"); + let artifacts = Pallet::::send_message(valid_message); assert_eq!(artifacts.enqueued_messages, prev_enqueud_messages + 1); // check event with assigned nonce @@ -965,7 +962,7 @@ mod tests { vec![EventRecord { phase: Phase::Initialization, event: TestEvent::Messages(Event::MessageAccepted { - lane_id: TEST_LANE_ID, + lane_id, nonce: message_nonce }), topics: vec![], @@ -1016,14 +1013,14 @@ mod tests { fn pallet_rejects_transactions_if_halted() { run_test(|| { // send message first to be able to check that delivery_proof fails later - send_regular_message(); + send_regular_message(TEST_LANE_ID); PalletOperatingMode::::put(MessagesOperatingMode::Basic( BasicOperatingMode::Halted, )); assert_noop!( - send_message::(TEST_LANE_ID, REGULAR_PAYLOAD,), + Pallet::::validate_message(TEST_LANE_ID, ®ULAR_PAYLOAD), Error::::NotOperatingNormally, ); @@ -1066,14 +1063,14 @@ mod tests { fn pallet_rejects_new_messages_in_rejecting_outbound_messages_operating_mode() { run_test(|| { // send message first to be able to check that delivery_proof fails later - send_regular_message(); + send_regular_message(TEST_LANE_ID); PalletOperatingMode::::put( MessagesOperatingMode::RejectingOutboundMessages, ); assert_noop!( - send_message::(TEST_LANE_ID, REGULAR_PAYLOAD,), + Pallet::::validate_message(TEST_LANE_ID, ®ULAR_PAYLOAD), Error::::NotOperatingNormally, ); @@ -1109,7 +1106,7 @@ mod tests { #[test] fn send_message_works() { run_test(|| { - send_regular_message(); + send_regular_message(TEST_LANE_ID); }); } @@ -1123,7 +1120,7 @@ mod tests { .extra .extend_from_slice(&[0u8; MAX_OUTBOUND_PAYLOAD_SIZE as usize]); assert_noop!( - send_message::(TEST_LANE_ID, message_payload.clone(),), + Pallet::::validate_message(TEST_LANE_ID, &message_payload.clone(),), Error::::MessageRejectedByPallet( VerificationError::MessageTooLarge ), @@ -1134,7 +1131,11 @@ mod tests { message_payload.extra.pop(); } assert_eq!(message_payload.encoded_size() as u32, MAX_OUTBOUND_PAYLOAD_SIZE); - assert_ok!(send_message::(TEST_LANE_ID, message_payload,),); + + let valid_message = + Pallet::::validate_message(TEST_LANE_ID, &message_payload) + .expect("validate_message has failed"); + Pallet::::send_message(valid_message); }) } @@ -1143,7 +1144,10 @@ mod tests { run_test(|| { // messages with this payload are rejected by target chain verifier assert_noop!( - send_message::(TEST_LANE_ID, PAYLOAD_REJECTED_BY_TARGET_CHAIN,), + Pallet::::validate_message( + TEST_LANE_ID, + &PAYLOAD_REJECTED_BY_TARGET_CHAIN, + ), Error::::MessageRejectedByChainVerifier(VerificationError::Other( mock::TEST_ERROR )), @@ -1151,21 +1155,6 @@ mod tests { }); } - #[test] - fn lane_verifier_rejects_invalid_message_in_send_message() { - run_test(|| { - // messages with zero fee are rejected by lane verifier - let mut message = REGULAR_PAYLOAD; - message.reject_by_lane_verifier = true; - assert_noop!( - send_message::(TEST_LANE_ID, message,), - Error::::MessageRejectedByLaneVerifier(VerificationError::Other( - mock::TEST_ERROR - )), - ); - }); - } - #[test] fn receive_messages_proof_works() { run_test(|| { @@ -1318,7 +1307,7 @@ mod tests { #[test] fn receive_messages_delivery_proof_works() { run_test(|| { - send_regular_message(); + send_regular_message(TEST_LANE_ID); receive_messages_delivery_proof(); assert_eq!( @@ -1331,8 +1320,8 @@ mod tests { #[test] fn receive_messages_delivery_proof_rewards_relayers() { run_test(|| { - assert_ok!(send_message::(TEST_LANE_ID, REGULAR_PAYLOAD,)); - assert_ok!(send_message::(TEST_LANE_ID, REGULAR_PAYLOAD,)); + send_regular_message(TEST_LANE_ID); + send_regular_message(TEST_LANE_ID); // this reports delivery of message 1 => reward is paid to TEST_RELAYER_A let single_message_delivery_proof = TestMessagesDeliveryProof(Ok(( @@ -1718,9 +1707,9 @@ mod tests { #[test] fn messages_delivered_callbacks_are_called() { run_test(|| { - send_regular_message(); - send_regular_message(); - send_regular_message(); + send_regular_message(TEST_LANE_ID); + send_regular_message(TEST_LANE_ID); + send_regular_message(TEST_LANE_ID); // messages 1+2 are confirmed in 1 tx, message 3 in a separate tx // dispatch of message 2 has failed @@ -1779,7 +1768,7 @@ mod tests { ) { run_test(|| { // send message first to be able to check that delivery_proof fails later - send_regular_message(); + send_regular_message(TEST_LANE_ID); // 1) InboundLaneData declares that the `last_confirmed_nonce` is 1; // 2) InboundLaneData has no entries => `InboundLaneData::last_delivered_nonce()` @@ -1846,10 +1835,10 @@ mod tests { #[test] fn on_idle_callback_respects_remaining_weight() { run_test(|| { - send_regular_message(); - send_regular_message(); - send_regular_message(); - send_regular_message(); + send_regular_message(TEST_LANE_ID); + send_regular_message(TEST_LANE_ID); + send_regular_message(TEST_LANE_ID); + send_regular_message(TEST_LANE_ID); assert_ok!(Pallet::::receive_messages_delivery_proof( RuntimeOrigin::signed(1), @@ -1928,10 +1917,10 @@ mod tests { fn on_idle_callback_is_rotating_lanes_to_prune() { run_test(|| { // send + receive confirmation for lane 1 - send_regular_message(); + send_regular_message(TEST_LANE_ID); receive_messages_delivery_proof(); // send + receive confirmation for lane 2 - assert_ok!(send_message::(TEST_LANE_ID_2, REGULAR_PAYLOAD,)); + send_regular_message(TEST_LANE_ID_2); assert_ok!(Pallet::::receive_messages_delivery_proof( RuntimeOrigin::signed(1), TestMessagesDeliveryProof(Ok(( @@ -2007,7 +1996,7 @@ mod tests { fn outbound_message_from_unconfigured_lane_is_rejected() { run_test(|| { assert_noop!( - send_message::(TEST_LANE_ID_3, REGULAR_PAYLOAD,), + Pallet::::validate_message(TEST_LANE_ID_3, ®ULAR_PAYLOAD,), Error::::InactiveOutboundLane, ); }); diff --git a/bridges/modules/messages/src/mock.rs b/bridges/modules/messages/src/mock.rs index 648acad772d..af921205398 100644 --- a/bridges/modules/messages/src/mock.rs +++ b/bridges/modules/messages/src/mock.rs @@ -17,19 +17,17 @@ // From construct_runtime macro #![allow(clippy::from_over_into)] -use crate::Config; +use crate::{Config, StoredMessagePayload}; use bp_messages::{ calc_relayers_rewards, - source_chain::{ - DeliveryConfirmationPayments, LaneMessageVerifier, OnMessagesDelivered, TargetHeaderChain, - }, + source_chain::{DeliveryConfirmationPayments, OnMessagesDelivered, TargetHeaderChain}, target_chain::{ DeliveryPayments, DispatchMessage, DispatchMessageData, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain, }, - DeliveredMessages, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, - OutboundLaneData, UnrewardedRelayer, UnrewardedRelayersState, VerificationError, + DeliveredMessages, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, + UnrewardedRelayer, UnrewardedRelayersState, VerificationError, }; use bp_runtime::{messages::MessageDispatchResult, Size}; use codec::{Decode, Encode}; @@ -50,8 +48,6 @@ pub type Balance = u64; pub struct TestPayload { /// Field that may be used to identify messages. pub id: u64, - /// Reject this message by lane verifier? - pub reject_by_lane_verifier: bool, /// Dispatch weight that is declared by the message sender. pub declared_weight: Weight, /// Message dispatch result. @@ -120,7 +116,6 @@ impl Config for TestRuntime { type DeliveryPayments = TestDeliveryPayments; type TargetHeaderChain = TestTargetHeaderChain; - type LaneMessageVerifier = TestLaneMessageVerifier; type DeliveryConfirmationPayments = TestDeliveryConfirmationPayments; type OnMessagesDelivered = TestOnMessagesDelivered; @@ -268,24 +263,6 @@ impl TargetHeaderChain for TestTargetHeaderChain { } } -/// Lane message verifier that is used in tests. -#[derive(Debug, Default)] -pub struct TestLaneMessageVerifier; - -impl LaneMessageVerifier for TestLaneMessageVerifier { - fn verify_message( - _lane: &LaneId, - _lane_outbound_data: &OutboundLaneData, - payload: &TestPayload, - ) -> Result<(), VerificationError> { - if !payload.reject_by_lane_verifier { - Ok(()) - } else { - Err(VerificationError::Other(TEST_ERROR)) - } - } -} - /// Reward payments at the target chain during delivery transaction. #[derive(Debug, Default)] pub struct TestDeliveryPayments; @@ -425,8 +402,8 @@ pub fn message(nonce: MessageNonce, payload: TestPayload) -> Message { } /// Return valid outbound message data, constructed from given payload. -pub fn outbound_message_data(payload: TestPayload) -> MessagePayload { - payload.encode() +pub fn outbound_message_data(payload: TestPayload) -> StoredMessagePayload { + StoredMessagePayload::::try_from(payload.encode()).expect("payload too large") } /// Return valid inbound (dispatch) message data, constructed from given payload. @@ -438,7 +415,6 @@ pub fn inbound_message_data(payload: TestPayload) -> DispatchMessageData TestPayload { TestPayload { id, - reject_by_lane_verifier: false, declared_weight: Weight::from_parts(declared_weight, 0), dispatch_result: dispatch_result(0), extra: Vec::new(), diff --git a/bridges/modules/messages/src/outbound_lane.rs b/bridges/modules/messages/src/outbound_lane.rs index f92e9ccfd95..431c2cfb7ee 100644 --- a/bridges/modules/messages/src/outbound_lane.rs +++ b/bridges/modules/messages/src/outbound_lane.rs @@ -18,10 +18,7 @@ use crate::{Config, LOG_TARGET}; -use bp_messages::{ - DeliveredMessages, LaneId, MessageNonce, MessagePayload, OutboundLaneData, UnrewardedRelayer, - VerificationError, -}; +use bp_messages::{DeliveredMessages, LaneId, MessageNonce, OutboundLaneData, UnrewardedRelayer}; use codec::{Decode, Encode}; use frame_support::{ weights::{RuntimeDbWeight, Weight}, @@ -34,6 +31,8 @@ use sp_std::collections::vec_deque::VecDeque; /// Outbound lane storage. pub trait OutboundLaneStorage { + type StoredMessagePayload; + /// Lane id. fn id(&self) -> LaneId; /// Get lane data from the storage. @@ -42,13 +41,9 @@ pub trait OutboundLaneStorage { fn set_data(&mut self, data: OutboundLaneData); /// Returns saved outbound message payload. #[cfg(test)] - fn message(&self, nonce: &MessageNonce) -> Option; + fn message(&self, nonce: &MessageNonce) -> Option; /// Save outbound message in the storage. - fn save_message( - &mut self, - nonce: MessageNonce, - message_payload: MessagePayload, - ) -> Result<(), VerificationError>; + fn save_message(&mut self, nonce: MessageNonce, message_payload: Self::StoredMessagePayload); /// Remove outbound message from the storage. fn remove_message(&mut self, nonce: &MessageNonce); } @@ -91,18 +86,15 @@ impl OutboundLane { /// Send message over lane. /// /// Returns new message nonce. - pub fn send_message( - &mut self, - message_payload: MessagePayload, - ) -> Result { + pub fn send_message(&mut self, message_payload: S::StoredMessagePayload) -> MessageNonce { let mut data = self.storage.data(); let nonce = data.latest_generated_nonce + 1; data.latest_generated_nonce = nonce; - self.storage.save_message(nonce, message_payload)?; + self.storage.save_message(nonce, message_payload); self.storage.set_data(data); - Ok(nonce) + nonce } /// Confirm messages delivery. @@ -218,7 +210,7 @@ mod tests { }, outbound_lane, }; - use frame_support::{assert_ok, weights::constants::RocksDbWeight}; + use frame_support::weights::constants::RocksDbWeight; use sp_std::ops::RangeInclusive; fn unrewarded_relayers( @@ -239,9 +231,9 @@ mod tests { ) -> Result, ReceivalConfirmationError> { run_test(|| { let mut lane = outbound_lane::(TEST_LANE_ID); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); assert_eq!(lane.storage.data().latest_generated_nonce, 3); assert_eq!(lane.storage.data().latest_received_nonce, 0); let result = lane.confirm_delivery(3, latest_received_nonce, relayers); @@ -256,7 +248,7 @@ mod tests { run_test(|| { let mut lane = outbound_lane::(TEST_LANE_ID); assert_eq!(lane.storage.data().latest_generated_nonce, 0); - assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), Ok(1)); + assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 1); assert!(lane.storage.message(&1).is_some()); assert_eq!(lane.storage.data().latest_generated_nonce, 1); }); @@ -266,9 +258,9 @@ mod tests { fn confirm_delivery_works() { run_test(|| { let mut lane = outbound_lane::(TEST_LANE_ID); - assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), Ok(1)); - assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), Ok(2)); - assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), Ok(3)); + assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 1); + assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 2); + assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 3); assert_eq!(lane.storage.data().latest_generated_nonce, 3); assert_eq!(lane.storage.data().latest_received_nonce, 0); assert_eq!( @@ -284,9 +276,9 @@ mod tests { fn confirm_delivery_rejects_nonce_lesser_than_latest_received() { run_test(|| { let mut lane = outbound_lane::(TEST_LANE_ID); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); assert_eq!(lane.storage.data().latest_generated_nonce, 3); assert_eq!(lane.storage.data().latest_received_nonce, 0); assert_eq!( @@ -368,9 +360,9 @@ mod tests { ); assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); // when nothing is confirmed, nothing is pruned - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); assert!(lane.storage.message(&1).is_some()); assert!(lane.storage.message(&2).is_some()); assert!(lane.storage.message(&3).is_some()); @@ -412,9 +404,9 @@ mod tests { fn confirm_delivery_detects_when_more_than_expected_messages_are_confirmed() { run_test(|| { let mut lane = outbound_lane::(TEST_LANE_ID); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); assert_eq!( lane.confirm_delivery(0, 3, &unrewarded_relayers(1..=3)), Err(ReceivalConfirmationError::TryingToConfirmMoreMessagesThanExpected), diff --git a/bridges/modules/parachains/src/call_ext.rs b/bridges/modules/parachains/src/call_ext.rs index 198ff11be49..da91a40a232 100644 --- a/bridges/modules/parachains/src/call_ext.rs +++ b/bridges/modules/parachains/src/call_ext.rs @@ -178,7 +178,7 @@ mod tests { RuntimeCall::Parachains(crate::Call::::submit_parachain_heads { at_relay_block: (num, Default::default()), parachains, - parachain_heads_proof: ParaHeadsProof(Vec::new()), + parachain_heads_proof: ParaHeadsProof { storage_proof: Vec::new() }, }) .check_obsolete_submit_parachain_heads() .is_ok() diff --git a/bridges/modules/parachains/src/lib.rs b/bridges/modules/parachains/src/lib.rs index cf76e64ff9c..87c57e84622 100644 --- a/bridges/modules/parachains/src/lib.rs +++ b/bridges/modules/parachains/src/lib.rs @@ -21,6 +21,7 @@ //! accepts storage proof of some parachain `Heads` entries from bridged relay chain. //! It requires corresponding relay headers to be already synced. +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] pub use weights::WeightInfo; @@ -98,27 +99,49 @@ pub mod pallet { #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event, I: 'static = ()> { /// The caller has provided head of parachain that the pallet is not configured to track. - UntrackedParachainRejected { parachain: ParaId }, + UntrackedParachainRejected { + /// Identifier of the parachain that is not tracked by the pallet. + parachain: ParaId, + }, /// The caller has declared that he has provided given parachain head, but it is missing /// from the storage proof. - MissingParachainHead { parachain: ParaId }, + MissingParachainHead { + /// Identifier of the parachain with missing head. + parachain: ParaId, + }, /// The caller has provided parachain head hash that is not matching the hash read from the /// storage proof. IncorrectParachainHeadHash { + /// Identifier of the parachain with incorrect head hast. parachain: ParaId, + /// Specified parachain head hash. parachain_head_hash: ParaHash, + /// Actual parachain head hash. actual_parachain_head_hash: ParaHash, }, /// The caller has provided obsolete parachain head, which is already known to the pallet. - RejectedObsoleteParachainHead { parachain: ParaId, parachain_head_hash: ParaHash }, + RejectedObsoleteParachainHead { + /// Identifier of the parachain with obsolete head. + parachain: ParaId, + /// Obsolete parachain head hash. + parachain_head_hash: ParaHash, + }, /// The caller has provided parachain head that exceeds the maximal configured head size. RejectedLargeParachainHead { + /// Identifier of the parachain with rejected head. parachain: ParaId, + /// Parachain head hash. parachain_head_hash: ParaHash, + /// Parachain head size. parachain_head_size: u32, }, /// Parachain head has been updated. - UpdatedParachainHead { parachain: ParaId, parachain_head_hash: ParaHash }, + UpdatedParachainHead { + /// Identifier of the parachain that has been updated. + parachain: ParaId, + /// Parachain head hash. + parachain_head_hash: ParaHash, + }, } #[pallet::error] @@ -137,6 +160,7 @@ pub mod pallet { pub trait BoundedBridgeGrandpaConfig: pallet_bridge_grandpa::Config { + /// Type of the bridged relay chain. type BridgedRelayChain: Chain< BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, @@ -336,7 +360,7 @@ pub mod pallet { let mut storage = GrandpaPalletOf::::storage_proof_checker( relay_block_hash, - parachain_heads_proof.0, + parachain_heads_proof.storage_proof, ) .map_err(Error::::HeaderChainStorageProof)?; diff --git a/bridges/modules/parachains/src/mock.rs b/bridges/modules/parachains/src/mock.rs index 1c7851364d1..143f11d9863 100644 --- a/bridges/modules/parachains/src/mock.rs +++ b/bridges/modules/parachains/src/mock.rs @@ -16,7 +16,7 @@ use bp_header_chain::ChainWithGrandpa; use bp_polkadot_core::parachains::ParaId; -use bp_runtime::{Chain, Parachain}; +use bp_runtime::{Chain, ChainId, Parachain}; use frame_support::{ construct_runtime, derive_impl, parameter_types, traits::ConstU32, weights::Weight, }; @@ -49,6 +49,8 @@ pub type BigParachainHeader = sp_runtime::generic::Header; pub struct Parachain1; impl Chain for Parachain1 { + const ID: ChainId = *b"pch1"; + type BlockNumber = u64; type Hash = H256; type Hasher = RegularParachainHasher; @@ -73,6 +75,8 @@ impl Parachain for Parachain1 { pub struct Parachain2; impl Chain for Parachain2 { + const ID: ChainId = *b"pch2"; + type BlockNumber = u64; type Hash = H256; type Hasher = RegularParachainHasher; @@ -97,6 +101,8 @@ impl Parachain for Parachain2 { pub struct Parachain3; impl Chain for Parachain3 { + const ID: ChainId = *b"pch3"; + type BlockNumber = u64; type Hash = H256; type Hasher = RegularParachainHasher; @@ -122,6 +128,8 @@ impl Parachain for Parachain3 { pub struct BigParachain; impl Chain for BigParachain { + const ID: ChainId = *b"bpch"; + type BlockNumber = u128; type Hash = H256; type Hasher = RegularParachainHasher; @@ -229,6 +237,8 @@ impl pallet_bridge_parachains::benchmarking::Config<()> for TestRuntime { pub struct TestBridgedChain; impl Chain for TestBridgedChain { + const ID: ChainId = *b"tbch"; + type BlockNumber = crate::RelayBlockNumber; type Hash = crate::RelayBlockHash; type Hasher = crate::RelayBlockHasher; @@ -260,6 +270,8 @@ impl ChainWithGrandpa for TestBridgedChain { pub struct OtherBridgedChain; impl Chain for OtherBridgedChain { + const ID: ChainId = *b"obch"; + type BlockNumber = u64; type Hash = crate::RelayBlockHash; type Hasher = crate::RelayBlockHasher; diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index 3dd7459d30f..94ec8b5f106 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -42,12 +42,13 @@ type MessagesPallet = BridgeMessagesPallet>::BridgeMess impl, I: 'static> ExportXcm for Pallet where - T: BridgeMessagesConfig< - >::BridgeMessagesPalletInstance, - OutboundPayload = XcmAsPlainPayload, - >, + T: BridgeMessagesConfig, { - type Ticket = (SenderAndLane, XcmAsPlainPayload, XcmHash); + type Ticket = ( + SenderAndLane, + as MessagesBridge>::SendMessageArgs, + XcmHash, + ); fn validate( network: NetworkId, @@ -74,42 +75,38 @@ where message, )?; - Ok(((sender_and_lane, blob, id), price)) - } - - fn deliver( - (sender_and_lane, blob, id): (SenderAndLane, XcmAsPlainPayload, XcmHash), - ) -> Result { - let lane_id = sender_and_lane.lane; - let send_result = MessagesPallet::::send_message(lane_id, blob); - - match send_result { - Ok(artifacts) => { - log::info!( - target: LOG_TARGET, - "XCM message {:?} has been enqueued at bridge {:?} with nonce {}", - id, - lane_id, - artifacts.nonce, - ); - - // notify XCM queue manager about updated lane state - LocalXcmQueueManager::::on_bridge_message_enqueued( - &sender_and_lane, - artifacts.enqueued_messages, - ); - }, - Err(error) => { + let bridge_message = MessagesPallet::::validate_message(sender_and_lane.lane, &blob) + .map_err(|e| { log::debug!( target: LOG_TARGET, - "XCM message {:?} has been dropped because of bridge error {:?} on bridge {:?}", + "XCM message {:?} cannot be exported because of bridge error {:?} on bridge {:?}", id, - error, - lane_id, + e, + sender_and_lane.lane, ); - return Err(SendError::Transport("BridgeSendError")) - }, - } + SendError::Transport("BridgeValidateError") + })?; + + Ok(((sender_and_lane, bridge_message, id), price)) + } + + fn deliver((sender_and_lane, bridge_message, id): Self::Ticket) -> Result { + let lane_id = sender_and_lane.lane; + let artifacts = MessagesPallet::::send_message(bridge_message); + + log::info!( + target: LOG_TARGET, + "XCM message {:?} has been enqueued at bridge {:?} with nonce {}", + id, + lane_id, + artifacts.nonce, + ); + + // notify XCM queue manager about updated lane state + LocalXcmQueueManager::::on_bridge_message_enqueued( + &sender_and_lane, + artifacts.enqueued_messages, + ); Ok(id) } diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 6708d4b789a..e40e1f9fb65 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -19,11 +19,10 @@ use crate as pallet_xcm_bridge_hub; use bp_messages::{ - source_chain::LaneMessageVerifier, target_chain::{DispatchMessage, MessageDispatch}, - LaneId, OutboundLaneData, VerificationError, + LaneId, }; -use bp_runtime::{messages::MessageDispatchResult, Chain, UnderlyingChainProvider}; +use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, UnderlyingChainProvider}; use bridge_runtime_common::{ messages::{ source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter, @@ -78,20 +77,6 @@ impl pallet_balances::Config for TestRuntime { type AccountStore = System; } -/// Lane message verifier that is used in tests. -#[derive(Debug, Default)] -pub struct TestLaneMessageVerifier; - -impl LaneMessageVerifier> for TestLaneMessageVerifier { - fn verify_message( - _lane: &LaneId, - _lane_outbound_data: &OutboundLaneData, - _payload: &Vec, - ) -> Result<(), VerificationError> { - Ok(()) - } -} - parameter_types! { pub const ActiveOutboundLanes: &'static [LaneId] = &[TEST_LANE_ID]; } @@ -110,7 +95,6 @@ impl pallet_bridge_messages::Config for TestRuntime { type InboundRelayer = (); type DeliveryPayments = (); type TargetHeaderChain = TargetHeaderChainAdapter; - type LaneMessageVerifier = TestLaneMessageVerifier; type DeliveryConfirmationPayments = (); type OnMessagesDelivered = (); type SourceHeaderChain = SourceHeaderChainAdapter; @@ -217,6 +201,7 @@ impl XcmBlobHauler for TestXcmBlobHauler { pub struct ThisChain; impl Chain for ThisChain { + const ID: ChainId = *b"tuch"; type BlockNumber = u64; type Hash = H256; type Hasher = BlakeTwo256; @@ -240,6 +225,7 @@ pub type BridgedHeaderHash = H256; pub type BridgedChainHeader = SubstrateHeader; impl Chain for BridgedChain { + const ID: ChainId = *b"tuch"; type BlockNumber = u64; type Hash = BridgedHeaderHash; type Hasher = BlakeTwo256; diff --git a/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs b/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs index cd281324ee5..285f0020481 100644 --- a/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs +++ b/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs @@ -14,6 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +//! Primitives of all Cumulus-based bridge hubs. + +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] pub use bp_polkadot_core::{ @@ -61,6 +64,7 @@ const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts(constants::WEIGHT_REF_TI pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5); parameter_types! { + /// Size limit of the Cumulus-based bridge hub blocks. pub BlockLength: limits::BlockLength = limits::BlockLength::max_with_normal_ratio( 5 * 1024 * 1024, NORMAL_DISPATCH_RATIO, @@ -73,6 +77,7 @@ parameter_types! { pub const ExtrinsicBaseWeight: Weight = Weight::from_parts(constants::WEIGHT_REF_TIME_PER_NANOS, 0) .saturating_mul(125_000); + /// Weight limit of the Cumulus-based bridge hub blocks. pub BlockWeights: limits::BlockWeights = limits::BlockWeights::builder() .base_block(BlockExecutionWeight::get()) .for_class(DispatchClass::all(), |weights| { diff --git a/bridges/primitives/chain-bridge-hub-kusama/src/lib.rs b/bridges/primitives/chain-bridge-hub-kusama/src/lib.rs index 66e0dad0589..576e3dbee80 100644 --- a/bridges/primitives/chain-bridge-hub-kusama/src/lib.rs +++ b/bridges/primitives/chain-bridge-hub-kusama/src/lib.rs @@ -17,12 +17,13 @@ //! Module with configuration which reflects BridgeHubKusama runtime setup (AccountId, Headers, //! Hashes...) +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] pub use bp_bridge_hub_cumulus::*; use bp_messages::*; use bp_runtime::{ - decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, Parachain, + decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, ChainId, Parachain, }; use frame_support::{ dispatch::DispatchClass, @@ -35,6 +36,8 @@ use sp_runtime::RuntimeDebug; pub struct BridgeHubKusama; impl Chain for BridgeHubKusama { + const ID: ChainId = *b"bhks"; + type BlockNumber = BlockNumber; type Hash = Hash; type Hasher = Hasher; @@ -61,6 +64,15 @@ impl Parachain for BridgeHubKusama { const PARACHAIN_ID: u32 = BRIDGE_HUB_KUSAMA_PARACHAIN_ID; } +impl ChainWithMessages for BridgeHubKusama { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = + WITH_BRIDGE_HUB_KUSAMA_MESSAGES_PALLET_NAME; + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; +} + /// Public key of the chain account that may be used to verify signatures. pub type AccountSigner = MultiSigner; diff --git a/bridges/primitives/chain-bridge-hub-polkadot/src/lib.rs b/bridges/primitives/chain-bridge-hub-polkadot/src/lib.rs index c3661c1adca..6db389c9299 100644 --- a/bridges/primitives/chain-bridge-hub-polkadot/src/lib.rs +++ b/bridges/primitives/chain-bridge-hub-polkadot/src/lib.rs @@ -17,12 +17,13 @@ //! Module with configuration which reflects BridgeHubPolkadot runtime setup //! (AccountId, Headers, Hashes...) +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] pub use bp_bridge_hub_cumulus::*; use bp_messages::*; use bp_runtime::{ - decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, Parachain, + decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, ChainId, Parachain, }; use frame_support::dispatch::DispatchClass; use sp_runtime::RuntimeDebug; @@ -32,6 +33,8 @@ use sp_runtime::RuntimeDebug; pub struct BridgeHubPolkadot; impl Chain for BridgeHubPolkadot { + const ID: ChainId = *b"bhpd"; + type BlockNumber = BlockNumber; type Hash = Hash; type Hasher = Hasher; @@ -58,6 +61,16 @@ impl Parachain for BridgeHubPolkadot { const PARACHAIN_ID: u32 = BRIDGE_HUB_POLKADOT_PARACHAIN_ID; } +impl ChainWithMessages for BridgeHubPolkadot { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = + WITH_BRIDGE_HUB_POLKADOT_MESSAGES_PALLET_NAME; + + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; +} + /// Identifier of BridgeHubPolkadot in the Polkadot relay chain. pub const BRIDGE_HUB_POLKADOT_PARACHAIN_ID: u32 = 1002; diff --git a/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs b/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs index f79b8a8afb3..7b109f30fe0 100644 --- a/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs +++ b/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs @@ -17,12 +17,13 @@ //! Module with configuration which reflects BridgeHubRococo runtime setup (AccountId, Headers, //! Hashes...) +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] pub use bp_bridge_hub_cumulus::*; use bp_messages::*; use bp_runtime::{ - decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, Parachain, + decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, ChainId, Parachain, }; use frame_support::dispatch::DispatchClass; use sp_runtime::{MultiAddress, MultiSigner, RuntimeDebug}; @@ -32,6 +33,8 @@ use sp_runtime::{MultiAddress, MultiSigner, RuntimeDebug}; pub struct BridgeHubRococo; impl Chain for BridgeHubRococo { + const ID: ChainId = *b"bhro"; + type BlockNumber = BlockNumber; type Hash = Hash; type Hasher = Hasher; @@ -58,6 +61,16 @@ impl Parachain for BridgeHubRococo { const PARACHAIN_ID: u32 = BRIDGE_HUB_ROCOCO_PARACHAIN_ID; } +impl ChainWithMessages for BridgeHubRococo { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = + WITH_BRIDGE_HUB_ROCOCO_MESSAGES_PALLET_NAME; + + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; +} + /// Public key of the chain account that may be used to verify signatures. pub type AccountSigner = MultiSigner; diff --git a/bridges/primitives/chain-bridge-hub-westend/Cargo.toml b/bridges/primitives/chain-bridge-hub-westend/Cargo.toml index beebfa8f1a0..cfd0c84eeec 100644 --- a/bridges/primitives/chain-bridge-hub-westend/Cargo.toml +++ b/bridges/primitives/chain-bridge-hub-westend/Cargo.toml @@ -14,8 +14,8 @@ workspace = true # Bridge Dependencies bp-bridge-hub-cumulus = { path = "../chain-bridge-hub-cumulus", default-features = false } -bp-runtime = { path = "../../primitives/runtime", default-features = false } -bp-messages = { path = "../../primitives/messages", default-features = false } +bp-runtime = { path = "../runtime", default-features = false } +bp-messages = { path = "../messages", default-features = false } # Substrate Based Dependencies diff --git a/bridges/primitives/chain-bridge-hub-westend/src/lib.rs b/bridges/primitives/chain-bridge-hub-westend/src/lib.rs index f4524f719f9..83d4d6e33a7 100644 --- a/bridges/primitives/chain-bridge-hub-westend/src/lib.rs +++ b/bridges/primitives/chain-bridge-hub-westend/src/lib.rs @@ -22,7 +22,7 @@ pub use bp_bridge_hub_cumulus::*; use bp_messages::*; use bp_runtime::{ - decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, Parachain, + decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, ChainId, Parachain, }; use frame_support::dispatch::DispatchClass; use sp_runtime::RuntimeDebug; @@ -32,6 +32,8 @@ use sp_runtime::RuntimeDebug; pub struct BridgeHubWestend; impl Chain for BridgeHubWestend { + const ID: ChainId = *b"bhwd"; + type BlockNumber = BlockNumber; type Hash = Hash; type Hasher = Hasher; @@ -58,6 +60,16 @@ impl Parachain for BridgeHubWestend { const PARACHAIN_ID: u32 = BRIDGE_HUB_WESTEND_PARACHAIN_ID; } +impl ChainWithMessages for BridgeHubWestend { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = + WITH_BRIDGE_HUB_WESTEND_MESSAGES_PALLET_NAME; + + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; +} + /// Identifier of BridgeHubWestend in the Westend relay chain. pub const BRIDGE_HUB_WESTEND_PARACHAIN_ID: u32 = 1002; diff --git a/bridges/primitives/chain-kusama/src/lib.rs b/bridges/primitives/chain-kusama/src/lib.rs index 5f089fbc589..e3b4d0520f6 100644 --- a/bridges/primitives/chain-kusama/src/lib.rs +++ b/bridges/primitives/chain-kusama/src/lib.rs @@ -14,36 +14,39 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +//! Primitives of the Kusama chain. + +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -// RuntimeApi generated functions -#![allow(clippy::too_many_arguments)] pub use bp_polkadot_core::*; use bp_header_chain::ChainWithGrandpa; -use bp_runtime::{decl_bridge_finality_runtime_apis, Chain}; +use bp_runtime::{decl_bridge_finality_runtime_apis, Chain, ChainId}; use frame_support::weights::Weight; /// Kusama Chain pub struct Kusama; impl Chain for Kusama { - type BlockNumber = ::BlockNumber; - type Hash = ::Hash; - type Hasher = ::Hasher; - type Header = ::Header; + const ID: ChainId = *b"ksma"; + + type BlockNumber = BlockNumber; + type Hash = Hash; + type Hasher = Hasher; + type Header = Header; - type AccountId = ::AccountId; - type Balance = ::Balance; - type Nonce = ::Nonce; - type Signature = ::Signature; + type AccountId = AccountId; + type Balance = Balance; + type Nonce = Nonce; + type Signature = Signature; fn max_extrinsic_size() -> u32 { - PolkadotLike::max_extrinsic_size() + max_extrinsic_size() } fn max_extrinsic_weight() -> Weight { - PolkadotLike::max_extrinsic_weight() + max_extrinsic_weight() } } diff --git a/bridges/primitives/chain-polkadot-bulletin/src/lib.rs b/bridges/primitives/chain-polkadot-bulletin/src/lib.rs index fe82c9644b6..f2eebf93124 100644 --- a/bridges/primitives/chain-polkadot-bulletin/src/lib.rs +++ b/bridges/primitives/chain-polkadot-bulletin/src/lib.rs @@ -20,14 +20,14 @@ #![cfg_attr(not(feature = "std"), no_std)] use bp_header_chain::ChainWithGrandpa; -use bp_messages::MessageNonce; +use bp_messages::{ChainWithMessages, MessageNonce}; use bp_runtime::{ decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, extensions::{ CheckEra, CheckGenesis, CheckNonZeroSender, CheckNonce, CheckSpecVersion, CheckTxVersion, CheckWeight, GenericSignedExtension, GenericSignedExtensionSchema, }, - Chain, TransactionEra, + Chain, ChainId, TransactionEra, }; use codec::{Decode, Encode}; use frame_support::{ @@ -177,6 +177,8 @@ parameter_types! { pub struct PolkadotBulletin; impl Chain for PolkadotBulletin { + const ID: ChainId = *b"pdbc"; + type BlockNumber = BlockNumber; type Hash = Hash; type Hasher = Hasher; @@ -211,5 +213,15 @@ impl ChainWithGrandpa for PolkadotBulletin { const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE; } +impl ChainWithMessages for PolkadotBulletin { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = + WITH_POLKADOT_BULLETIN_MESSAGES_PALLET_NAME; + + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; +} + decl_bridge_finality_runtime_apis!(polkadot_bulletin, grandpa); decl_bridge_messages_runtime_apis!(polkadot_bulletin); diff --git a/bridges/primitives/chain-polkadot/src/lib.rs b/bridges/primitives/chain-polkadot/src/lib.rs index 9a5b8970acc..fc5e10308a8 100644 --- a/bridges/primitives/chain-polkadot/src/lib.rs +++ b/bridges/primitives/chain-polkadot/src/lib.rs @@ -14,36 +14,41 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +//! Primitives of the Polkadot chain. + +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -// RuntimeApi generated functions -#![allow(clippy::too_many_arguments)] pub use bp_polkadot_core::*; use bp_header_chain::ChainWithGrandpa; -use bp_runtime::{decl_bridge_finality_runtime_apis, extensions::PrevalidateAttests, Chain}; +use bp_runtime::{ + decl_bridge_finality_runtime_apis, extensions::PrevalidateAttests, Chain, ChainId, +}; use frame_support::weights::Weight; /// Polkadot Chain pub struct Polkadot; impl Chain for Polkadot { - type BlockNumber = ::BlockNumber; - type Hash = ::Hash; - type Hasher = ::Hasher; - type Header = ::Header; + const ID: ChainId = *b"pdot"; + + type BlockNumber = BlockNumber; + type Hash = Hash; + type Hasher = Hasher; + type Header = Header; - type AccountId = ::AccountId; - type Balance = ::Balance; - type Nonce = ::Nonce; - type Signature = ::Signature; + type AccountId = AccountId; + type Balance = Balance; + type Nonce = Nonce; + type Signature = Signature; fn max_extrinsic_size() -> u32 { - PolkadotLike::max_extrinsic_size() + max_extrinsic_size() } fn max_extrinsic_weight() -> Weight { - PolkadotLike::max_extrinsic_weight() + max_extrinsic_weight() } } diff --git a/bridges/primitives/chain-rococo/src/lib.rs b/bridges/primitives/chain-rococo/src/lib.rs index 7f3e762715f..f1b256f0f09 100644 --- a/bridges/primitives/chain-rococo/src/lib.rs +++ b/bridges/primitives/chain-rococo/src/lib.rs @@ -14,36 +14,39 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +//! Primitives of the Rococo chain. + +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -// RuntimeApi generated functions -#![allow(clippy::too_many_arguments)] pub use bp_polkadot_core::*; use bp_header_chain::ChainWithGrandpa; -use bp_runtime::{decl_bridge_finality_runtime_apis, Chain}; -use frame_support::{parameter_types, weights::Weight}; +use bp_runtime::{decl_bridge_finality_runtime_apis, Chain, ChainId}; +use frame_support::weights::Weight; /// Rococo Chain pub struct Rococo; impl Chain for Rococo { - type BlockNumber = ::BlockNumber; - type Hash = ::Hash; - type Hasher = ::Hasher; - type Header = ::Header; + const ID: ChainId = *b"roco"; + + type BlockNumber = BlockNumber; + type Hash = Hash; + type Hasher = Hasher; + type Header = Header; - type AccountId = ::AccountId; - type Balance = ::Balance; - type Nonce = ::Nonce; - type Signature = ::Signature; + type AccountId = AccountId; + type Balance = Balance; + type Nonce = Nonce; + type Signature = Signature; fn max_extrinsic_size() -> u32 { - PolkadotLike::max_extrinsic_size() + max_extrinsic_size() } fn max_extrinsic_weight() -> Weight { - PolkadotLike::max_extrinsic_weight() + max_extrinsic_weight() } } @@ -56,10 +59,6 @@ impl ChainWithGrandpa for Rococo { const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE; } -parameter_types! { - pub const SS58Prefix: u8 = 42; -} - // The SignedExtension used by Rococo. pub use bp_polkadot_core::CommonSignedExtension as SignedExtension; diff --git a/bridges/primitives/chain-westend/src/lib.rs b/bridges/primitives/chain-westend/src/lib.rs index 7fa5e140d57..f03fd2160a7 100644 --- a/bridges/primitives/chain-westend/src/lib.rs +++ b/bridges/primitives/chain-westend/src/lib.rs @@ -14,36 +14,39 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +//! Primitives of the Westend chain. + +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -// RuntimeApi generated functions -#![allow(clippy::too_many_arguments)] pub use bp_polkadot_core::*; use bp_header_chain::ChainWithGrandpa; -use bp_runtime::{decl_bridge_finality_runtime_apis, Chain}; -use frame_support::{parameter_types, weights::Weight}; +use bp_runtime::{decl_bridge_finality_runtime_apis, Chain, ChainId}; +use frame_support::weights::Weight; /// Westend Chain pub struct Westend; impl Chain for Westend { - type BlockNumber = ::BlockNumber; - type Hash = ::Hash; - type Hasher = ::Hasher; - type Header = ::Header; + const ID: ChainId = *b"wend"; + + type BlockNumber = BlockNumber; + type Hash = Hash; + type Hasher = Hasher; + type Header = Header; - type AccountId = ::AccountId; - type Balance = ::Balance; - type Nonce = ::Nonce; - type Signature = ::Signature; + type AccountId = AccountId; + type Balance = Balance; + type Nonce = Nonce; + type Signature = Signature; fn max_extrinsic_size() -> u32 { - PolkadotLike::max_extrinsic_size() + max_extrinsic_size() } fn max_extrinsic_weight() -> Weight { - PolkadotLike::max_extrinsic_weight() + max_extrinsic_weight() } } @@ -56,10 +59,6 @@ impl ChainWithGrandpa for Westend { const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE; } -parameter_types! { - pub const SS58Prefix: u8 = 42; -} - // The SignedExtension used by Westend. pub use bp_polkadot_core::CommonSignedExtension as SignedExtension; diff --git a/bridges/primitives/header-chain/src/lib.rs b/bridges/primitives/header-chain/src/lib.rs index 1459b1c1994..f5485aca1ee 100644 --- a/bridges/primitives/header-chain/src/lib.rs +++ b/bridges/primitives/header-chain/src/lib.rs @@ -17,6 +17,7 @@ //! Defines traits which represent a common interface for Substrate pallets which want to //! incorporate bridge functionality. +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] use crate::justification::{ @@ -145,6 +146,7 @@ pub trait ConsensusLogReader { pub struct GrandpaConsensusLogReader(sp_std::marker::PhantomData); impl GrandpaConsensusLogReader { + /// Find and return scheduled (regular) change digest item. pub fn find_scheduled_change( digest: &Digest, ) -> Option> { @@ -158,6 +160,8 @@ impl GrandpaConsensusLogReader { }) } + /// Find and return forced change digest item. Or light client can't do anything + /// with forced changes, so we can't accept header with the forced change digest. pub fn find_forced_change( digest: &Digest, ) -> Option<(Number, sp_consensus_grandpa::ScheduledChange)> { @@ -229,12 +233,17 @@ pub enum BridgeGrandpaCall { /// `pallet-bridge-grandpa::Call::submit_finality_proof` #[codec(index = 0)] submit_finality_proof { + /// The header that we are going to finalize. finality_target: Box
, + /// Finality justification for the `finality_target`. justification: justification::GrandpaJustification
, }, /// `pallet-bridge-grandpa::Call::initialize` #[codec(index = 1)] - initialize { init_data: InitializationData
}, + initialize { + /// All data, required to initialize the pallet. + init_data: InitializationData
, + }, } /// The `BridgeGrandpaCall` used by a chain. @@ -325,12 +334,15 @@ pub fn max_expected_submit_finality_proof_arguments_size( #[cfg(test)] mod tests { use super::*; + use bp_runtime::ChainId; use frame_support::weights::Weight; use sp_runtime::{testing::H256, traits::BlakeTwo256, MultiSignature}; struct TestChain; impl Chain for TestChain { + const ID: ChainId = *b"test"; + type BlockNumber = u32; type Hash = H256; type Hasher = BlakeTwo256; diff --git a/bridges/primitives/messages/src/lib.rs b/bridges/primitives/messages/src/lib.rs index e48914f7591..51b3f25f715 100644 --- a/bridges/primitives/messages/src/lib.rs +++ b/bridges/primitives/messages/src/lib.rs @@ -16,14 +16,13 @@ //! Primitives of messages module. +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -// RuntimeApi generated functions -#![allow(clippy::too_many_arguments)] use bp_header_chain::HeaderChainError; use bp_runtime::{ - messages::MessageDispatchResult, BasicOperatingMode, OperatingMode, RangeInclusiveExt, - StorageProofError, + messages::MessageDispatchResult, BasicOperatingMode, Chain, OperatingMode, RangeInclusiveExt, + StorageProofError, UnderlyingChainOf, UnderlyingChainProvider, }; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::PalletError; @@ -39,6 +38,36 @@ pub mod source_chain; pub mod storage_keys; pub mod target_chain; +/// Substrate-based chain with messaging support. +pub trait ChainWithMessages: Chain { + /// Name of the bridge messages pallet (used in `construct_runtime` macro call) that is + /// deployed at some other chain to bridge with this `ChainWithMessages`. + /// + /// We assume that all chains that are bridging with this `ChainWithMessages` are using + /// the same name. + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str; + + /// Maximal number of unrewarded relayers in a single confirmation transaction at this + /// `ChainWithMessages`. + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce; + /// Maximal number of unconfirmed messages in a single confirmation transaction at this + /// `ChainWithMessages`. + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce; +} + +impl ChainWithMessages for T +where + T: Chain + UnderlyingChainProvider, + UnderlyingChainOf: ChainWithMessages, +{ + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = + UnderlyingChainOf::::WITH_CHAIN_MESSAGES_PALLET_NAME; + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = + UnderlyingChainOf::::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = + UnderlyingChainOf::::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; +} + /// Messages pallet operating mode. #[derive( Encode, @@ -264,6 +293,7 @@ pub struct ReceivedMessages { } impl ReceivedMessages { + /// Creates new `ReceivedMessages` structure from given results. pub fn new( lane: LaneId, receive_results: Vec<(MessageNonce, ReceivalResult)>, @@ -271,6 +301,7 @@ impl ReceivedMessages { ReceivedMessages { lane, receive_results } } + /// Push `result` of the `message` delivery onto `receive_results` vector. pub fn push(&mut self, message: MessageNonce, result: ReceivalResult) { self.receive_results.push((message, result)); } @@ -342,7 +373,7 @@ pub struct UnrewardedRelayersState { } impl UnrewardedRelayersState { - // Verify that the relayers state corresponds with the `InboundLaneData`. + /// Verify that the relayers state corresponds with the `InboundLaneData`. pub fn is_valid(&self, lane_data: &InboundLaneData) -> bool { self == &lane_data.into() } @@ -423,15 +454,21 @@ pub enum BridgeMessagesCall { /// `pallet-bridge-messages::Call::receive_messages_proof` #[codec(index = 2)] receive_messages_proof { + /// Account id of relayer at the **bridged** chain. relayer_id_at_bridged_chain: AccountId, + /// Messages proof. proof: MessagesProof, + /// A number of messages in the proof. messages_count: u32, + /// Total dispatch weight of messages in the proof. dispatch_weight: Weight, }, /// `pallet-bridge-messages::Call::receive_messages_delivery_proof` #[codec(index = 3)] receive_messages_delivery_proof { + /// Messages delivery proof. proof: MessagesDeliveryProof, + /// "Digest" of unrewarded relayers state at the bridged chain. relayers_state: UnrewardedRelayersState, }, } diff --git a/bridges/primitives/messages/src/source_chain.rs b/bridges/primitives/messages/src/source_chain.rs index 73092c3cce0..f4aefd97355 100644 --- a/bridges/primitives/messages/src/source_chain.rs +++ b/bridges/primitives/messages/src/source_chain.rs @@ -16,7 +16,7 @@ //! Primitives of messages module, that are used on the source chain. -use crate::{InboundLaneData, LaneId, MessageNonce, OutboundLaneData, VerificationError}; +use crate::{InboundLaneData, LaneId, MessageNonce, VerificationError}; use crate::UnrewardedRelayer; use bp_runtime::Size; @@ -64,24 +64,6 @@ pub trait TargetHeaderChain { ) -> Result<(LaneId, InboundLaneData), VerificationError>; } -/// Lane message verifier. -/// -/// Runtime developer may implement any additional validation logic over message-lane mechanism. -/// E.g. if lanes should have some security (e.g. you can only accept Lane1 messages from -/// Submitter1, Lane2 messages for those who has submitted first message to this lane, disable -/// Lane3 until some block, ...), then it may be built using this verifier. -/// -/// Any fee requirements should also be enforced here. -pub trait LaneMessageVerifier { - /// Verify message payload and return Ok(()) if message is valid and allowed to be sent over the - /// lane. - fn verify_message( - lane: &LaneId, - outbound_data: &OutboundLaneData, - payload: &Payload, - ) -> Result<(), VerificationError>; -} - /// Manages payments that are happening at the source chain during delivery confirmation /// transaction. pub trait DeliveryConfirmationPayments { @@ -143,25 +125,25 @@ pub trait MessagesBridge { /// Error type. type Error: Debug; - /// Send message over the bridge. + /// Intermediary structure returned by `validate_message()`. /// - /// Returns unique message nonce or error if send has failed. - fn send_message(lane: LaneId, message: Payload) -> Result; -} - -/// Bridge that does nothing when message is being sent. -#[derive(Eq, RuntimeDebug, PartialEq)] -pub struct NoopMessagesBridge; + /// It can than be passed to `send_message()` in order to actually send the message + /// on the bridge. + type SendMessageArgs; -impl MessagesBridge for NoopMessagesBridge { - type Error = &'static str; + /// Check if the message can be sent over the bridge. + fn validate_message( + lane: LaneId, + message: &Payload, + ) -> Result; - fn send_message(_lane: LaneId, _message: Payload) -> Result { - Ok(SendMessageArtifacts { nonce: 0, enqueued_messages: 0 }) - } + /// Send message over the bridge. + /// + /// Returns unique message nonce or error if send has failed. + fn send_message(message: Self::SendMessageArgs) -> SendMessageArtifacts; } -/// Structure that may be used in place of `TargetHeaderChain`, `LaneMessageVerifier` and +/// Structure that may be used in place of `TargetHeaderChain` and /// `MessageDeliveryAndDispatchPayment` on chains, where outbound messages are forbidden. pub struct ForbidOutboundMessages; @@ -183,16 +165,6 @@ impl TargetHeaderChain for ForbidOutboun } } -impl LaneMessageVerifier for ForbidOutboundMessages { - fn verify_message( - _lane: &LaneId, - _outbound_data: &OutboundLaneData, - _payload: &Payload, - ) -> Result<(), VerificationError> { - Err(VerificationError::Other(ALL_OUTBOUND_MESSAGES_REJECTED)) - } -} - impl DeliveryConfirmationPayments for ForbidOutboundMessages { type Error = &'static str; diff --git a/bridges/primitives/parachains/src/lib.rs b/bridges/primitives/parachains/src/lib.rs index 262b9c6f977..692bbd99ece 100644 --- a/bridges/primitives/parachains/src/lib.rs +++ b/bridges/primitives/parachains/src/lib.rs @@ -16,6 +16,7 @@ //! Primitives of parachains module. +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] pub use bp_header_chain::StoredHeaderData; @@ -173,8 +174,11 @@ pub enum BridgeParachainCall { /// `pallet-bridge-parachains::Call::submit_parachain_heads` #[codec(index = 0)] submit_parachain_heads { + /// Relay chain block, for which we have submitted the `parachain_heads_proof`. at_relay_block: (RelayBlockNumber, RelayBlockHash), + /// Parachain identifiers and their head hashes. parachains: Vec<(ParaId, ParaHash)>, + /// Parachain heads proof. parachain_heads_proof: ParaHeadsProof, }, } diff --git a/bridges/primitives/polkadot-core/src/lib.rs b/bridges/primitives/polkadot-core/src/lib.rs index 586cbf8cb9b..df2836495bb 100644 --- a/bridges/primitives/polkadot-core/src/lib.rs +++ b/bridges/primitives/polkadot-core/src/lib.rs @@ -14,6 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +//! Primitives of the Polkadot-like chains. + +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] use bp_messages::MessageNonce; @@ -24,7 +27,7 @@ use bp_runtime::{ CheckSpecVersion, CheckTxVersion, CheckWeight, GenericSignedExtension, SignedExtensionSchema, }, - Chain, EncodedOrDecodedCall, StorageMapKeyProvider, TransactionEra, + EncodedOrDecodedCall, StorageMapKeyProvider, TransactionEra, }; use frame_support::{ dispatch::DispatchClass, @@ -40,7 +43,7 @@ use sp_core::{storage::StorageKey, Hasher as HasherT}; use sp_runtime::{ generic, traits::{BlakeTwo256, IdentifyAccount, Verify}, - MultiAddress, MultiSignature, OpaqueExtrinsic, RuntimeDebug, + MultiAddress, MultiSignature, OpaqueExtrinsic, }; use sp_std::prelude::Vec; @@ -173,11 +176,16 @@ pub use time_units::*; pub mod time_units { use super::BlockNumber; + /// Milliseconds between Polkadot-like chain blocks. pub const MILLISECS_PER_BLOCK: u64 = 6000; + /// Slot duration in Polkadot-like chain consensus algorithms. pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; + /// A minute, expressed in Polkadot-like chain blocks. pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); + /// A hour, expressed in Polkadot-like chain blocks. pub const HOURS: BlockNumber = MINUTES * 60; + /// A day, expressed in Polkadot-like chain blocks. pub const DAYS: BlockNumber = HOURS * 24; } @@ -227,31 +235,17 @@ pub type UncheckedExtrinsic = /// Account address, used by the Polkadot-like chain. pub type Address = MultiAddress; -/// Polkadot-like chain. -#[derive(RuntimeDebug)] -pub struct PolkadotLike; - -impl Chain for PolkadotLike { - type BlockNumber = BlockNumber; - type Hash = Hash; - type Hasher = Hasher; - type Header = Header; - - type AccountId = AccountId; - type Balance = Balance; - type Nonce = Nonce; - type Signature = Signature; - - fn max_extrinsic_size() -> u32 { - *BlockLength::get().max.get(DispatchClass::Normal) - } +/// Returns maximal extrinsic size on all Polkadot-like chains. +pub fn max_extrinsic_size() -> u32 { + *BlockLength::get().max.get(DispatchClass::Normal) +} - fn max_extrinsic_weight() -> Weight { - BlockWeights::get() - .get(DispatchClass::Normal) - .max_extrinsic - .unwrap_or(Weight::MAX) - } +/// Returns maximal extrinsic weight on all Polkadot-like chains. +pub fn max_extrinsic_weight() -> Weight { + BlockWeights::get() + .get(DispatchClass::Normal) + .max_extrinsic + .unwrap_or(Weight::MAX) } /// Provides a storage key for account data. @@ -271,8 +265,10 @@ impl StorageMapKeyProvider for AccountInfoStorageMapKeyProvider { } impl AccountInfoStorageMapKeyProvider { + /// Name of the system pallet. const PALLET_NAME: &'static str = "System"; + /// Return storage key for given account data. pub fn final_key(id: &AccountId) -> StorageKey { ::final_key(Self::PALLET_NAME, id) } diff --git a/bridges/primitives/polkadot-core/src/parachains.rs b/bridges/primitives/polkadot-core/src/parachains.rs index 223956171f8..433cd2845ab 100644 --- a/bridges/primitives/polkadot-core/src/parachains.rs +++ b/bridges/primitives/polkadot-core/src/parachains.rs @@ -89,11 +89,18 @@ pub type ParaHasher = crate::Hasher; /// Raw storage proof of parachain heads, stored in polkadot-like chain runtime. #[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebug, TypeInfo)] -pub struct ParaHeadsProof(pub RawStorageProof); +pub struct ParaHeadsProof { + /// Unverified storage proof of finalized parachain heads. + pub storage_proof: RawStorageProof, +} impl Size for ParaHeadsProof { fn size(&self) -> u32 { - u32::try_from(self.0.iter().fold(0usize, |sum, node| sum.saturating_add(node.len()))) - .unwrap_or(u32::MAX) + u32::try_from( + self.storage_proof + .iter() + .fold(0usize, |sum, node| sum.saturating_add(node.len())), + ) + .unwrap_or(u32::MAX) } } diff --git a/bridges/primitives/runtime/src/chain.rs b/bridges/primitives/runtime/src/chain.rs index 81a2070bece..9ba21a1cddf 100644 --- a/bridges/primitives/runtime/src/chain.rs +++ b/bridges/primitives/runtime/src/chain.rs @@ -14,7 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::HeaderIdProvider; +use crate::{ChainId, HeaderIdProvider}; + use codec::{Codec, Decode, Encode, MaxEncodedLen}; use frame_support::{weights::Weight, Parameter}; use num_traits::{AsPrimitive, Bounded, CheckedSub, Saturating, SaturatingAdd, Zero}; @@ -99,6 +100,9 @@ impl Encode for EncodedOrDecodedCall { /// Minimal Substrate-based chain representation that may be used from no_std environment. pub trait Chain: Send + Sync + 'static { + /// Chain id. + const ID: ChainId; + /// A type that fulfills the abstract idea of what a Substrate block number is. // Constraits come from the associated Number type of `sp_runtime::traits::Header` // See here for more info: @@ -208,6 +212,8 @@ impl Chain for T where T: Send + Sync + 'static + UnderlyingChainProvider, { + const ID: ChainId = ::ID; + type BlockNumber = ::BlockNumber; type Hash = ::Hash; type Hasher = ::Hasher; diff --git a/bridges/primitives/runtime/src/extensions.rs b/bridges/primitives/runtime/src/extensions.rs index 8a618721b23..d896bc92eff 100644 --- a/bridges/primitives/runtime/src/extensions.rs +++ b/bridges/primitives/runtime/src/extensions.rs @@ -102,6 +102,7 @@ impl SignedExtensionSchema for Tuple { /// and signed payloads in the client code. #[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] pub struct GenericSignedExtension { + /// A payload that is included in the transaction. pub payload: S::Payload, #[codec(skip)] // It may be set to `None` if extensions are decoded. We are never reconstructing transactions @@ -112,6 +113,7 @@ pub struct GenericSignedExtension { } impl GenericSignedExtension { + /// Create new `GenericSignedExtension` object. pub fn new(payload: S::Payload, additional_signed: Option) -> Self { Self { payload, additional_signed } } diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs index 0513cfa2a6c..850318923dc 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -16,6 +16,7 @@ //! Primitives that may be used at (bridges) runtime level. +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] use codec::{Decode, Encode, FullCodec, MaxEncodedLen}; @@ -61,36 +62,6 @@ pub use sp_runtime::paste; /// Use this when something must be shared among all instances. pub const NO_INSTANCE_ID: ChainId = [0, 0, 0, 0]; -/// Polkadot chain id. -pub const POLKADOT_CHAIN_ID: ChainId = *b"pdot"; - -/// Polkadot Bulletin chain id. -pub const POLKADOT_BULLETIN_CHAIN_ID: ChainId = *b"pdbc"; - -/// Kusama chain id. -pub const KUSAMA_CHAIN_ID: ChainId = *b"ksma"; - -/// Westend chain id. -pub const WESTEND_CHAIN_ID: ChainId = *b"wend"; - -/// `AssetHubWestmint` chain id. -pub const ASSET_HUB_WESTEND_CHAIN_ID: ChainId = *b"ahwe"; - -/// Rococo chain id. -pub const ROCOCO_CHAIN_ID: ChainId = *b"roco"; - -/// BridgeHubRococo chain id. -pub const BRIDGE_HUB_ROCOCO_CHAIN_ID: ChainId = *b"bhro"; - -/// BridgeHubWestend chain id. -pub const BRIDGE_HUB_WESTEND_CHAIN_ID: ChainId = *b"bhwd"; - -/// BridgeHubKusama chain id. -pub const BRIDGE_HUB_KUSAMA_CHAIN_ID: ChainId = *b"bhks"; - -/// BridgeHubPolkadot chain id. -pub const BRIDGE_HUB_POLKADOT_CHAIN_ID: ChainId = *b"bhpd"; - /// Generic header Id. #[derive( RuntimeDebug, @@ -126,10 +97,10 @@ pub type HeaderIdOf = HeaderId, BlockNumberOf>; /// Generic header id provider. pub trait HeaderIdProvider { - // Get the header id. + /// Get the header id. fn id(&self) -> HeaderId; - // Get the header id for the parent block. + /// Get the header id for the parent block. fn parent_id(&self) -> Option>; } @@ -342,7 +313,7 @@ pub trait StorageDoubleMapKeyProvider { } /// Error generated by the `OwnedBridgeModule` trait. -#[derive(Encode, Decode, TypeInfo, PalletError)] +#[derive(Encode, Decode, PartialEq, Eq, TypeInfo, PalletError)] pub enum OwnedBridgeModuleError { /// All pallet operations are halted. Halted, @@ -350,7 +321,7 @@ pub enum OwnedBridgeModuleError { /// Operating mode for a bridge module. pub trait OperatingMode: Send + Copy + Debug + FullCodec { - // Returns true if the bridge module is halted. + /// Returns true if the bridge module is halted. fn is_halted(&self) -> bool; } @@ -392,8 +363,11 @@ pub trait OwnedBridgeModule { /// The target that will be used when publishing logs related to this module. const LOG_TARGET: &'static str; + /// A storage entry that holds the module `Owner` account. type OwnerStorage: StorageValue>; + /// Operating mode type of the pallet. type OperatingMode: OperatingMode; + /// A storage value that holds the pallet operating mode. type OperatingModeStorage: StorageValue; /// Check if the module is halted. @@ -469,9 +443,11 @@ impl WeightExtraOps for Weight { /// Trait that provides a static `str`. pub trait StaticStrProvider { + /// Static string. const STR: &'static str; } +/// A macro that generates `StaticStrProvider` with the string set to its stringified argument. #[macro_export] macro_rules! generate_static_str_provider { ($str:expr) => { @@ -485,6 +461,7 @@ macro_rules! generate_static_str_provider { }; } +/// Error message that is only dispayable in `std` environment. #[derive(Encode, Decode, Clone, Eq, PartialEq, PalletError, TypeInfo)] #[scale_info(skip_type_params(T))] pub struct StrippableError { diff --git a/bridges/primitives/test-utils/src/keyring.rs b/bridges/primitives/test-utils/src/keyring.rs index eabf9c784eb..22691183acf 100644 --- a/bridges/primitives/test-utils/src/keyring.rs +++ b/bridges/primitives/test-utils/src/keyring.rs @@ -24,12 +24,17 @@ use sp_consensus_grandpa::{AuthorityId, AuthorityList, AuthorityWeight, SetId}; use sp_runtime::RuntimeDebug; use sp_std::prelude::*; -/// Set of test accounts with friendly names. +/// Set of test accounts with friendly names: Alice. pub const ALICE: Account = Account(0); +/// Set of test accounts with friendly names: Bob. pub const BOB: Account = Account(1); +/// Set of test accounts with friendly names: Charlie. pub const CHARLIE: Account = Account(2); +/// Set of test accounts with friendly names: Dave. pub const DAVE: Account = Account(3); +/// Set of test accounts with friendly names: Eve. pub const EVE: Account = Account(4); +/// Set of test accounts with friendly names: Ferdie. pub const FERDIE: Account = Account(5); /// A test account which can be used to sign messages. @@ -37,10 +42,12 @@ pub const FERDIE: Account = Account(5); pub struct Account(pub u16); impl Account { + /// Returns public key of this account. pub fn public(&self) -> VerifyingKey { self.pair().verifying_key() } + /// Returns key pair, used to sign data on behalf of this account. pub fn pair(&self) -> SigningKey { let data = self.0.encode(); let mut bytes = [0_u8; 32]; @@ -48,6 +55,7 @@ impl Account { SigningKey::from_bytes(&bytes) } + /// Generate a signature of given message. pub fn sign(&self, msg: &[u8]) -> Signature { use ed25519_dalek::Signer; self.pair().sign(msg) diff --git a/bridges/primitives/test-utils/src/lib.rs b/bridges/primitives/test-utils/src/lib.rs index 4d3b8475993..f23ddd1a10d 100644 --- a/bridges/primitives/test-utils/src/lib.rs +++ b/bridges/primitives/test-utils/src/lib.rs @@ -16,6 +16,7 @@ //! Utilities for testing runtime code. +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] use bp_header_chain::justification::{required_justification_precommits, GrandpaJustification}; @@ -33,8 +34,11 @@ pub use keyring::*; mod keyring; +/// GRANDPA round number used across tests. pub const TEST_GRANDPA_ROUND: u64 = 1; +/// GRANDPA validators set id used across tests. pub const TEST_GRANDPA_SET_ID: SetId = 1; +/// Name of the `Paras` pallet used across tests. pub const PARAS_PALLET_NAME: &str = "Paras"; /// Configuration parameters when generating test GRANDPA justifications. @@ -190,7 +194,7 @@ pub fn prepare_parachain_heads_proof( .map_err(|_| "record_all_trie_keys has failed") .expect("record_all_trie_keys should not fail in benchmarks"); - (root, ParaHeadsProof(storage_proof), parachains) + (root, ParaHeadsProof { storage_proof }, parachains) } /// Create signed precommit with given target. diff --git a/bridges/snowbridge/parachain/pallets/ethereum-client/Cargo.toml b/bridges/snowbridge/parachain/pallets/ethereum-client/Cargo.toml index 59efcf91fd0..2bf5bfcd12f 100644 --- a/bridges/snowbridge/parachain/pallets/ethereum-client/Cargo.toml +++ b/bridges/snowbridge/parachain/pallets/ethereum-client/Cargo.toml @@ -38,7 +38,7 @@ snowbridge-core = { path = "../../primitives/core", default-features = false } snowbridge-ethereum = { path = "../../primitives/ethereum", default-features = false } primitives = { package = "snowbridge-beacon-primitives", path = "../../primitives/beacon", default-features = false } static_assertions = { version = "1.1.0", default-features = false } -bp-runtime = { path = "../../../../../bridges/primitives/runtime", default-features = false } +bp-runtime = { path = "../../../../primitives/runtime", default-features = false } pallet-timestamp = { path = "../../../../../substrate/frame/timestamp", default-features = false, optional = true } [dev-dependencies] diff --git a/bridges/snowbridge/parachain/pallets/inbound-queue/Cargo.toml b/bridges/snowbridge/parachain/pallets/inbound-queue/Cargo.toml index f645b4224d1..8101ecd5a48 100644 --- a/bridges/snowbridge/parachain/pallets/inbound-queue/Cargo.toml +++ b/bridges/snowbridge/parachain/pallets/inbound-queue/Cargo.toml @@ -47,7 +47,7 @@ snowbridge-beacon-primitives = { path = "../../primitives/beacon", default-featu frame-benchmarking = { path = "../../../../../substrate/frame/benchmarking" } sp-keyring = { path = "../../../../../substrate/primitives/keyring" } snowbridge-beacon-primitives = { path = "../../primitives/beacon" } -snowbridge-pallet-ethereum-client = { path = "../../pallets/ethereum-client" } +snowbridge-pallet-ethereum-client = { path = "../ethereum-client" } hex-literal = { version = "0.4.1" } [features] diff --git a/bridges/snowbridge/parachain/pallets/outbound-queue/Cargo.toml b/bridges/snowbridge/parachain/pallets/outbound-queue/Cargo.toml index de4487553cb..e499ab88729 100644 --- a/bridges/snowbridge/parachain/pallets/outbound-queue/Cargo.toml +++ b/bridges/snowbridge/parachain/pallets/outbound-queue/Cargo.toml @@ -31,7 +31,7 @@ sp-arithmetic = { path = "../../../../../substrate/primitives/arithmetic", defau bridge-hub-common = { path = "../../../../../cumulus/parachains/runtimes/bridge-hubs/common", default-features = false } -snowbridge-core = { path = "../../primitives/core", features = ["serde"], default-features = false } +snowbridge-core = { path = "../../primitives/core", default-features = false, features = ["serde"] } snowbridge-outbound-queue-merkle-tree = { path = "merkle-tree", default-features = false } ethabi = { git = "https://github.com/snowfork/ethabi-decode.git", package = "ethabi-decode", branch = "master", default-features = false } diff --git a/bridges/snowbridge/parachain/primitives/beacon/Cargo.toml b/bridges/snowbridge/parachain/primitives/beacon/Cargo.toml index 8294e903dfb..87f13ad5f6e 100644 --- a/bridges/snowbridge/parachain/primitives/beacon/Cargo.toml +++ b/bridges/snowbridge/parachain/primitives/beacon/Cargo.toml @@ -29,7 +29,7 @@ ssz_rs = { version = "0.9.0", default-features = false } ssz_rs_derive = { version = "0.9.0", default-features = false } byte-slice-cast = { version = "1.2.1", default-features = false } -snowbridge-ethereum = { path = "../../primitives/ethereum", default-features = false } +snowbridge-ethereum = { path = "../ethereum", default-features = false } static_assertions = { version = "1.1.0" } milagro_bls = { git = "https://github.com/snowfork/milagro_bls", default-features = false, rev = "a6d66e4eb89015e352fb1c9f7b661ecdbb5b2176" } diff --git a/bridges/snowbridge/parachain/primitives/core/Cargo.toml b/bridges/snowbridge/parachain/primitives/core/Cargo.toml index 1cb28eb3e50..a4092b4ee6f 100644 --- a/bridges/snowbridge/parachain/primitives/core/Cargo.toml +++ b/bridges/snowbridge/parachain/primitives/core/Cargo.toml @@ -29,7 +29,7 @@ sp-io = { path = "../../../../../substrate/primitives/io", default-features = fa sp-core = { path = "../../../../../substrate/primitives/core", default-features = false } sp-arithmetic = { path = "../../../../../substrate/primitives/arithmetic", default-features = false } -snowbridge-beacon-primitives = { path = "../../primitives/beacon", default-features = false } +snowbridge-beacon-primitives = { path = "../beacon", default-features = false } ethabi = { git = "https://github.com/Snowfork/ethabi-decode.git", package = "ethabi-decode", branch = "master", default-features = false } diff --git a/bridges/snowbridge/parachain/primitives/router/Cargo.toml b/bridges/snowbridge/parachain/primitives/router/Cargo.toml index 65133128ef4..ed8f68d7bc0 100644 --- a/bridges/snowbridge/parachain/primitives/router/Cargo.toml +++ b/bridges/snowbridge/parachain/primitives/router/Cargo.toml @@ -28,7 +28,7 @@ xcm = { package = "staging-xcm", path = "../../../../../polkadot/xcm", default-f xcm-builder = { package = "staging-xcm-builder", path = "../../../../../polkadot/xcm/xcm-builder", default-features = false } xcm-executor = { package = "staging-xcm-executor", path = "../../../../../polkadot/xcm/xcm-executor", default-features = false } -snowbridge-core = { path = "../../primitives/core", default-features = false } +snowbridge-core = { path = "../core", default-features = false } ethabi = { git = "https://github.com/Snowfork/ethabi-decode.git", package = "ethabi-decode", branch = "master", default-features = false } diff --git a/bridges/snowbridge/parachain/runtime/test-common/Cargo.toml b/bridges/snowbridge/parachain/runtime/test-common/Cargo.toml index ae72de406fc..bf7791bbabe 100644 --- a/bridges/snowbridge/parachain/runtime/test-common/Cargo.toml +++ b/bridges/snowbridge/parachain/runtime/test-common/Cargo.toml @@ -90,7 +90,7 @@ snowbridge-system-runtime-api = { path = "../../pallets/system/runtime-api", def [dev-dependencies] static_assertions = "1.1" bridge-hub-test-utils = { path = "../../../../../cumulus/parachains/runtimes/bridge-hubs/test-utils" } -bridge-runtime-common = { path = "../../../../../bridges/bin/runtime-common", features = ["integrity-test"] } +bridge-runtime-common = { path = "../../../../bin/runtime-common", features = ["integrity-test"] } sp-keyring = { path = "../../../../../substrate/primitives/keyring" } [features] diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs index 1c7bdd4cbff..7630c2bf99b 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs @@ -27,6 +27,7 @@ use crate::{ RuntimeEvent, XcmOverRococoBulletin, XcmRouter, }; use bp_messages::LaneId; +use bp_runtime::Chain; use bridge_runtime_common::{ messages, messages::{ @@ -63,7 +64,7 @@ parameter_types! { pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = bp_polkadot_bulletin::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; /// Bridge specific chain (network) identifier of the Rococo Bulletin Chain. - pub const RococoBulletinChainId: bp_runtime::ChainId = bp_runtime::POLKADOT_BULLETIN_CHAIN_ID; + pub const RococoBulletinChainId: bp_runtime::ChainId = bp_polkadot_bulletin::PolkadotBulletin::ID; /// Interior location (relative to this runtime) of the with-RococoBulletin messages pallet. pub BridgeRococoToRococoBulletinMessagesPalletInstance: InteriorLocation = [ PalletInstance(::index() as u8) @@ -151,10 +152,6 @@ impl MessageBridge for WithRococoBulletinMessageBridge { type BridgedHeaderChain = BridgeRococoBulletinGrandpa; } -/// Message verifier for RococoBulletin messages sent from BridgeHubRococo. -pub type ToRococoBulletinMessageVerifier = - messages::source::FromThisChainMessageVerifier; - /// Maximal outbound payload size of BridgeHubRococo -> RococoBulletin messages. pub type ToRococoBulletinMaximalOutboundPayloadSize = messages::source::FromThisChainMaximalOutboundPayloadSize; @@ -205,7 +202,6 @@ impl pallet_bridge_messages::Config for Runt type DeliveryPayments = (); type TargetHeaderChain = TargetHeaderChainAdapter; - type LaneMessageVerifier = ToRococoBulletinMessageVerifier; type DeliveryConfirmationPayments = (); type SourceHeaderChain = SourceHeaderChainAdapter; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 4e8fe6454cc..697386b6a7d 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -26,6 +26,7 @@ use crate::{ XcmRouter, }; use bp_messages::LaneId; +use bp_runtime::Chain; use bridge_runtime_common::{ messages, messages::{ @@ -57,7 +58,7 @@ parameter_types! { bp_bridge_hub_rococo::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = bp_bridge_hub_rococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; - pub const BridgeHubWestendChainId: bp_runtime::ChainId = bp_runtime::BRIDGE_HUB_WESTEND_CHAIN_ID; + pub const BridgeHubWestendChainId: bp_runtime::ChainId = BridgeHubWestend::ID; pub BridgeRococoToWestendMessagesPalletInstance: InteriorLocation = [PalletInstance(::index() as u8)].into(); pub WestendGlobalConsensusNetwork: NetworkId = NetworkId::Westend; pub WestendGlobalConsensusNetworkLocation: Location = Location::new( @@ -157,10 +158,6 @@ impl MessageBridge for WithBridgeHubWestendMessageBridge { >; } -/// Message verifier for BridgeHubWestend messages sent from BridgeHubRococo -pub type ToBridgeHubWestendMessageVerifier = - messages::source::FromThisChainMessageVerifier; - /// Maximal outbound payload size of BridgeHubRococo -> BridgeHubWestend messages. pub type ToBridgeHubWestendMaximalOutboundPayloadSize = messages::source::FromThisChainMaximalOutboundPayloadSize; @@ -212,7 +209,6 @@ impl pallet_bridge_messages::Config for Ru type DeliveryPayments = (); type TargetHeaderChain = TargetHeaderChainAdapter; - type LaneMessageVerifier = ToBridgeHubWestendMessageVerifier; type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime, WithBridgeHubWestendMessagesInstance, @@ -309,7 +305,7 @@ mod tests { bp_bridge_hub_westend::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, max_unconfirmed_messages_in_bridged_confirmation_tx: bp_bridge_hub_westend::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, - bridged_chain_id: bp_runtime::BRIDGE_HUB_WESTEND_CHAIN_ID, + bridged_chain_id: BridgeHubWestend::ID, }, pallet_names: AssertBridgePalletNames { with_this_chain_messages_pallet_name: diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 09aeedfc223..f84ff0799b9 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -70,6 +70,8 @@ use frame_system::{ EnsureRoot, }; +#[cfg(feature = "runtime-benchmarks")] +use bp_runtime::Chain; use bp_runtime::HeaderId; use bridge_hub_common::{ message_queue::{NarrowOriginToSibling, ParaIdToSibling}, @@ -1275,7 +1277,7 @@ impl_runtime_apis! { impl BridgeMessagesConfig for Runtime { fn is_relayer_rewarded(relayer: &Self::AccountId) -> bool { let bench_lane_id = >::bench_lane_id(); - let bridged_chain_id = bp_runtime::BRIDGE_HUB_WESTEND_CHAIN_ID; + let bridged_chain_id = bp_bridge_hub_westend::BridgeHubWestend::ID; pallet_bridge_relayers::Pallet::::relayer_reward( relayer, bp_relayers::RewardsAccountParams::new( diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index 716e01b85b4..c0c0976b52f 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -23,6 +23,7 @@ use crate::{ }; use bp_messages::LaneId; use bp_parachains::SingleParaStoredHeaderDataBuilder; +use bp_runtime::Chain; use bridge_runtime_common::{ messages, messages::{ @@ -62,7 +63,7 @@ parameter_types! { bp_bridge_hub_westend::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = bp_bridge_hub_westend::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; - pub const BridgeHubRococoChainId: bp_runtime::ChainId = bp_runtime::BRIDGE_HUB_ROCOCO_CHAIN_ID; + pub const BridgeHubRococoChainId: bp_runtime::ChainId = BridgeHubRococo::ID; pub BridgeWestendToRococoMessagesPalletInstance: InteriorLocation = [PalletInstance(::index() as u8)].into(); pub RococoGlobalConsensusNetwork: NetworkId = NetworkId::Rococo; pub RococoGlobalConsensusNetworkLocation: Location = Location::new( @@ -162,10 +163,6 @@ impl MessageBridge for WithBridgeHubRococoMessageBridge { >; } -/// Message verifier for BridgeHubRococo messages sent from BridgeHubWestend -type ToBridgeHubRococoMessageVerifier = - messages::source::FromThisChainMessageVerifier; - /// Maximal outbound payload size of BridgeHubWestend -> BridgeHubRococo messages. type ToBridgeHubRococoMaximalOutboundPayloadSize = messages::source::FromThisChainMaximalOutboundPayloadSize; @@ -249,7 +246,6 @@ impl pallet_bridge_messages::Config for Run type DeliveryPayments = (); type TargetHeaderChain = TargetHeaderChainAdapter; - type LaneMessageVerifier = ToBridgeHubRococoMessageVerifier; type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime, WithBridgeHubRococoMessagesInstance, @@ -344,7 +340,7 @@ mod tests { bp_bridge_hub_rococo::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, max_unconfirmed_messages_in_bridged_confirmation_tx: bp_bridge_hub_rococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, - bridged_chain_id: bp_runtime::BRIDGE_HUB_ROCOCO_CHAIN_ID, + bridged_chain_id: BridgeHubRococo::ID, }, pallet_names: AssertBridgePalletNames { with_this_chain_messages_pallet_name: diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 55a38fc8543..e90b5668c03 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -69,6 +69,8 @@ pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; pub use sp_runtime::{MultiAddress, Perbill, Permill}; use xcm_config::{XcmOriginToTransactDispatchOrigin, XcmRouter}; +#[cfg(feature = "runtime-benchmarks")] +use bp_runtime::Chain; use bp_runtime::HeaderId; #[cfg(any(feature = "std", test))] @@ -974,7 +976,7 @@ impl_runtime_apis! { impl BridgeMessagesConfig for Runtime { fn is_relayer_rewarded(relayer: &Self::AccountId) -> bool { let bench_lane_id = >::bench_lane_id(); - let bridged_chain_id = bp_runtime::BRIDGE_HUB_ROCOCO_CHAIN_ID; + let bridged_chain_id = bp_bridge_hub_rococo::BridgeHubRococo::ID; pallet_bridge_relayers::Pallet::::relayer_reward( relayer, bp_relayers::RewardsAccountParams::new( -- GitLab From e02c5204b3c26f0b4423304f027408f73e97d0ef Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Fri, 19 Jan 2024 20:36:16 +0100 Subject: [PATCH 089/392] Update Wasm benchmarks (#2957) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In https://github.com/paritytech/polkadot-sdk/pull/2941 we found out that the new Wasmi (register) is very effective at optimizing away certain benchmark bytecode constructs in a way that created an unfair advantage over Wasmi (stack) which yielded our former benchmarks to be ineffective at properly measuring the performance impact. This PR adjusts both affected benchmarks to fix the stated problems. Affected are - `instr_i64const` -> `instr_i64add`: Renamed since it now measures the performance impact of the Wasm `i64.add` instruction with locals as inputs and outputs. This makes it impossible for Wasmi (register) to aggressively optimize away the entire function body (as it previously did) but still provides a way for Wasmi (register) to shine with its register based execution model. - `call_with_code_per_byte`: Now uses `local.get` instead of `i32.const` for the `if` condition which prevents Wasmi (register) to aggressively optimizing away whole parts of the `if` creating an unfair advantage. cc @athei --------- Co-authored-by: command-bot <> Co-authored-by: Alexander Theißen Co-authored-by: Ignacio Palacios --- .../frame/contracts/src/benchmarking/code.rs | 46 +- .../frame/contracts/src/benchmarking/mod.rs | 46 +- substrate/frame/contracts/src/schedule.rs | 22 +- substrate/frame/contracts/src/weights.rs | 1240 +++++++++-------- 4 files changed, 697 insertions(+), 657 deletions(-) diff --git a/substrate/frame/contracts/src/benchmarking/code.rs b/substrate/frame/contracts/src/benchmarking/code.rs index 2f50611b41c..0b6ab6b3c0e 100644 --- a/substrate/frame/contracts/src/benchmarking/code.rs +++ b/substrate/frame/contracts/src/benchmarking/code.rs @@ -31,8 +31,8 @@ use sp_std::{borrow::ToOwned, prelude::*}; use wasm_instrument::parity_wasm::{ builder, elements::{ - self, BlockType, CustomSection, External, FuncBody, Instruction, Instructions, Module, - Section, ValueType, + self, BlockType, CustomSection, External, FuncBody, Instruction, Instructions, Local, + Module, Section, ValueType, }, }; @@ -281,17 +281,21 @@ impl WasmModule { /// instrumentation runtime by nesting blocks as deeply as possible given the byte budget. /// `code_location`: Whether to place the code into `deploy` or `call`. pub fn sized(target_bytes: u32, code_location: Location) -> Self { - use self::elements::Instruction::{End, I32Const, If, Return}; + use self::elements::Instruction::{End, GetLocal, If, Return}; // Base size of a contract is 63 bytes and each expansion adds 6 bytes. // We do one expansion less to account for the code section and function body // size fields inside the binary wasm module representation which are leb128 encoded // and therefore grow in size when the contract grows. We are not allowed to overshoot // because of the maximum code size that is enforced by `instantiate_with_code`. let expansions = (target_bytes.saturating_sub(63) / 6).saturating_sub(1); - const EXPANSION: [Instruction; 4] = [I32Const(0), If(BlockType::NoResult), Return, End]; + const EXPANSION: [Instruction; 4] = [GetLocal(0), If(BlockType::NoResult), Return, End]; let mut module = ModuleDefinition { memory: Some(ImportedMemory::max::()), ..Default::default() }; - let body = Some(body::repeated(expansions, &EXPANSION)); + let body = Some(body::repeated_with_locals( + &[Local::new(1, ValueType::I32)], + expansions, + &EXPANSION, + )); match code_location { Location::Call => module.call_body = body, Location::Deploy => module.deploy_body = body, @@ -373,8 +377,6 @@ pub mod body { /// Insert a I32Const with incrementing value for each insertion. /// (start_at, increment_by) Counter(u32, u32), - /// Insert the specified amount of I64Const with a random value. - RandomI64Repeated(usize), } pub fn plain(instructions: Vec) -> FuncBody { @@ -382,6 +384,14 @@ pub mod body { } pub fn repeated(repetitions: u32, instructions: &[Instruction]) -> FuncBody { + repeated_with_locals(&[], repetitions, instructions) + } + + pub fn repeated_with_locals( + locals: &[Local], + repetitions: u32, + instructions: &[Instruction], + ) -> FuncBody { let instructions = Instructions::new( instructions .iter() @@ -391,15 +401,23 @@ pub mod body { .chain(sp_std::iter::once(Instruction::End)) .collect(), ); - FuncBody::new(Vec::new(), instructions) + FuncBody::new(locals.to_vec(), instructions) } - pub fn repeated_dyn(repetitions: u32, mut instructions: Vec) -> FuncBody { - use rand::{distributions::Standard, prelude::*}; - - // We do not need to be secure here. - let mut rng = rand_pcg::Pcg32::seed_from_u64(8446744073709551615); + pub fn repeated_with_locals_using( + locals: &[Local], + repetitions: u32, + mut f: impl FnMut() -> [Instruction; N], + ) -> FuncBody { + let mut instructions = Vec::new(); + for _ in 0..repetitions { + instructions.extend(f()); + } + instructions.push(Instruction::End); + FuncBody::new(locals.to_vec(), Instructions::new(instructions)) + } + pub fn repeated_dyn(repetitions: u32, mut instructions: Vec) -> FuncBody { // We need to iterate over indices because we cannot cycle over mutable references let body = (0..instructions.len()) .cycle() @@ -411,8 +429,6 @@ pub mod body { *offset += *increment_by; vec![Instruction::I32Const(current as i32)] }, - DynInstr::RandomI64Repeated(num) => - (&mut rng).sample_iter(Standard).take(*num).map(Instruction::I64Const).collect(), }) .chain(sp_std::iter::once(Instruction::End)) .collect(); diff --git a/substrate/frame/contracts/src/benchmarking/mod.rs b/substrate/frame/contracts/src/benchmarking/mod.rs index 3ab76d6112a..f68f51c2906 100644 --- a/substrate/frame/contracts/src/benchmarking/mod.rs +++ b/substrate/frame/contracts/src/benchmarking/mod.rs @@ -48,7 +48,7 @@ use pallet_balances; use pallet_contracts_uapi::CallFlags; use sp_runtime::traits::{Bounded, Hash}; use sp_std::prelude::*; -use wasm_instrument::parity_wasm::elements::{BlockType, Instruction, ValueType}; +use wasm_instrument::parity_wasm::elements::{BlockType, Instruction, Local, ValueType}; /// How many runs we do per API benchmark. /// @@ -2582,19 +2582,45 @@ benchmarks! { let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::MAX, None, vec![]) - // We make the assumption that pushing a constant and dropping a value takes roughly - // the same amount of time. We call this weight `w_base`. - // The weight that would result from the respective benchmark we call: `w_bench`. + // We load `i64` values from random linear memory locations and store the loaded + // values back into yet another random linear memory location. + // The random addresses are uniformely distributed across the entire span of the linear memory. + // We do this to enforce random memory accesses which are particularly expensive. // - // w_base = w_i{32,64}const = w_drop = w_bench / 2 + // The combination of this computation is our weight base `w_base`. #[pov_mode = Ignored] - instr_i64const { + instr_i64_load_store { let r in 0 .. INSTR_BENCHMARK_RUNS; + + use rand::prelude::*; + + // We do not need to be secure here. Fixed seed allows for determinstic results. + let mut rng = rand_pcg::Pcg32::seed_from_u64(8446744073709551615); + + let memory = ImportedMemory::max::(); + let bytes_per_page = 65536; + let bytes_per_memory = memory.max_pages * bytes_per_page; let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { - call_body: Some(body::repeated_dyn(r, vec![ - RandomI64Repeated(1), - Regular(Instruction::Drop), - ])), + memory: Some(memory), + call_body: Some(body::repeated_with_locals_using( + &[Local::new(1, ValueType::I64)], + r, + || { + // Instruction sequence to load a `i64` from linear memory + // at a random memory location and store it back into another + // location of the linear memory. + let c0: i32 = rng.gen_range(0..bytes_per_memory as i32); + let c1: i32 = rng.gen_range(0..bytes_per_memory as i32); + [ + Instruction::I32Const(c0), // address for `i64.load_8s` + Instruction::I64Load8S(0, 0), + Instruction::SetLocal(0), // temporarily store value loaded in `i64.load_8s` + Instruction::I32Const(c1), // address for `i64.store8` + Instruction::GetLocal(0), // value to be stores in `i64.store8` + Instruction::I64Store8(0, 0), + ] + } + )), .. Default::default() })); }: { diff --git a/substrate/frame/contracts/src/schedule.rs b/substrate/frame/contracts/src/schedule.rs index 5ca18af026a..9fa5217da43 100644 --- a/substrate/frame/contracts/src/schedule.rs +++ b/substrate/frame/contracts/src/schedule.rs @@ -358,25 +358,12 @@ macro_rules! cost_args { } } -macro_rules! cost_instr_no_params { - ($name:ident) => { - cost_args!($name, 1).ref_time() as u32 - }; -} - macro_rules! cost { ($name:ident) => { cost_args!($name, 1) }; } -macro_rules! cost_instr { - ($name:ident, $num_params:expr) => { - cost_instr_no_params!($name) - .saturating_sub((cost_instr_no_params!(instr_i64const) / 2).saturating_mul($num_params)) - }; -} - impl Default for Limits { fn default() -> Self { Self { @@ -396,10 +383,13 @@ impl Default for Limits { } impl Default for InstructionWeights { - /// We price both `i64.const` and `drop` as `instr_i64const / 2`. The reason - /// for that is that we cannot benchmark either of them on its own. + /// We execute 6 different instructions therefore we have to divide the actual + /// computed gas costs by 6 to have a rough estimate as to how expensive each + /// single executed instruction is going to be. fn default() -> Self { - Self { base: cost_instr!(instr_i64const, 1), _phantom: PhantomData } + let instr_cost = cost!(instr_i64_load_store).ref_time() as u32; + let base = instr_cost / 6; + Self { base, _phantom: PhantomData } } } diff --git a/substrate/frame/contracts/src/weights.rs b/substrate/frame/contracts/src/weights.rs index 622d1e8a9b7..fa9df922a7c 100644 --- a/substrate/frame/contracts/src/weights.rs +++ b/substrate/frame/contracts/src/weights.rs @@ -18,7 +18,7 @@ //! Autogenerated weights for `pallet_contracts` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-01-17, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` @@ -129,7 +129,7 @@ pub trait WeightInfo { fn seal_reentrance_count(r: u32, ) -> Weight; fn seal_account_reentrance_count(r: u32, ) -> Weight; fn seal_instantiation_nonce(r: u32, ) -> Weight; - fn instr_i64const(r: u32, ) -> Weight; + fn instr_i64_load_store(r: u32, ) -> Weight; } /// Weights for `pallet_contracts` using the Substrate node and recommended hardware. @@ -141,8 +141,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 1_991_000 picoseconds. - Weight::from_parts(2_135_000, 1627) + // Minimum execution time: 1_997_000 picoseconds. + Weight::from_parts(2_130_000, 1627) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -152,10 +152,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `452 + k * (69 ±0)` // Estimated: `442 + k * (70 ±0)` - // Minimum execution time: 11_969_000 picoseconds. - Weight::from_parts(7_055_855, 442) - // Standard Error: 2_328 - .saturating_add(Weight::from_parts(1_212_989, 0).saturating_mul(k.into())) + // Minimum execution time: 12_276_000 picoseconds. + Weight::from_parts(1_593_881, 442) + // Standard Error: 1_135 + .saturating_add(Weight::from_parts(1_109_302, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(T::DbWeight::get().writes(2_u64)) @@ -169,10 +169,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `211 + c * (1 ±0)` // Estimated: `6149 + c * (1 ±0)` - // Minimum execution time: 8_064_000 picoseconds. - Weight::from_parts(8_301_148, 6149) + // Minimum execution time: 8_176_000 picoseconds. + Weight::from_parts(8_555_388, 6149) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_180, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(1_184, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -185,8 +185,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `510` // Estimated: `6450` - // Minimum execution time: 15_789_000 picoseconds. - Weight::from_parts(16_850_000, 6450) + // Minimum execution time: 16_270_000 picoseconds. + Weight::from_parts(16_779_000, 6450) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -199,10 +199,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `171 + k * (1 ±0)` // Estimated: `3635 + k * (1 ±0)` - // Minimum execution time: 3_369_000 picoseconds. - Weight::from_parts(3_516_000, 3635) - // Standard Error: 960 - .saturating_add(Weight::from_parts(1_139_317, 0).saturating_mul(k.into())) + // Minimum execution time: 3_572_000 picoseconds. + Weight::from_parts(1_950_905, 3635) + // Standard Error: 1_597 + .saturating_add(Weight::from_parts(1_123_190, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(k.into()))) @@ -221,10 +221,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `325 + c * (1 ±0)` // Estimated: `6263 + c * (1 ±0)` - // Minimum execution time: 16_320_000 picoseconds. - Weight::from_parts(16_090_036, 6263) + // Minimum execution time: 16_873_000 picoseconds. + Weight::from_parts(16_790_402, 6263) // Standard Error: 1 - .saturating_add(Weight::from_parts(417, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(396, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -235,8 +235,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `440` // Estimated: `6380` - // Minimum execution time: 12_669_000 picoseconds. - Weight::from_parts(13_118_000, 6380) + // Minimum execution time: 11_904_000 picoseconds. + Weight::from_parts(12_785_000, 6380) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -250,8 +250,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `352` // Estimated: `6292` - // Minimum execution time: 45_403_000 picoseconds. - Weight::from_parts(46_636_000, 6292) + // Minimum execution time: 44_920_000 picoseconds. + Weight::from_parts(46_163_000, 6292) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -263,8 +263,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `594` // Estimated: `6534` - // Minimum execution time: 53_622_000 picoseconds. - Weight::from_parts(55_444_000, 6534) + // Minimum execution time: 53_864_000 picoseconds. + Weight::from_parts(55_139_000, 6534) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -274,8 +274,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 2_444_000 picoseconds. - Weight::from_parts(2_587_000, 1627) + // Minimum execution time: 2_375_000 picoseconds. + Weight::from_parts(2_487_000, 1627) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -287,8 +287,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `166` // Estimated: `3631` - // Minimum execution time: 11_476_000 picoseconds. - Weight::from_parts(11_944_000, 3631) + // Minimum execution time: 11_580_000 picoseconds. + Weight::from_parts(11_980_000, 3631) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -298,8 +298,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 4_652_000 picoseconds. - Weight::from_parts(4_792_000, 3607) + // Minimum execution time: 4_557_000 picoseconds. + Weight::from_parts(4_807_000, 3607) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -310,8 +310,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `167` // Estimated: `3632` - // Minimum execution time: 6_054_000 picoseconds. - Weight::from_parts(6_278_000, 3632) + // Minimum execution time: 6_253_000 picoseconds. + Weight::from_parts(6_479_000, 3632) .saturating_add(T::DbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -322,8 +322,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 6_056_000 picoseconds. - Weight::from_parts(6_343_000, 3607) + // Minimum execution time: 6_166_000 picoseconds. + Weight::from_parts(6_545_000, 3607) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -344,12 +344,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `c` is `[0, 125952]`. fn call_with_code_per_byte(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `792` - // Estimated: `6743 + c * (1 ±0)` - // Minimum execution time: 303_205_000 picoseconds. - Weight::from_parts(266_154_889, 6743) - // Standard Error: 79 - .saturating_add(Weight::from_parts(35_195, 0).saturating_mul(c.into())) + // Measured: `801 + c * (1 ±0)` + // Estimated: `6739 + c * (1 ±0)` + // Minimum execution time: 282_232_000 picoseconds. + Weight::from_parts(266_148_573, 6739) + // Standard Error: 69 + .saturating_add(Weight::from_parts(34_592, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -378,15 +378,15 @@ impl WeightInfo for SubstrateWeight { fn instantiate_with_code(c: u32, i: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `323` - // Estimated: `8747` - // Minimum execution time: 4_311_802_000 picoseconds. - Weight::from_parts(777_467_048, 8747) - // Standard Error: 338 - .saturating_add(Weight::from_parts(105_862, 0).saturating_mul(c.into())) - // Standard Error: 40 - .saturating_add(Weight::from_parts(1_856, 0).saturating_mul(i.into())) - // Standard Error: 40 - .saturating_add(Weight::from_parts(1_443, 0).saturating_mul(s.into())) + // Estimated: `8737` + // Minimum execution time: 3_760_879_000 picoseconds. + Weight::from_parts(794_812_431, 8737) + // Standard Error: 149 + .saturating_add(Weight::from_parts(101_881, 0).saturating_mul(c.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(1_404, 0).saturating_mul(i.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(1_544, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(10_u64)) } @@ -414,12 +414,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `560` // Estimated: `6504` - // Minimum execution time: 1_958_694_000 picoseconds. - Weight::from_parts(331_222_273, 6504) - // Standard Error: 13 - .saturating_add(Weight::from_parts(1_954, 0).saturating_mul(i.into())) - // Standard Error: 13 - .saturating_add(Weight::from_parts(1_685, 0).saturating_mul(s.into())) + // Minimum execution time: 1_953_162_000 picoseconds. + Weight::from_parts(374_252_840, 6504) + // Standard Error: 7 + .saturating_add(Weight::from_parts(1_630, 0).saturating_mul(i.into())) + // Standard Error: 7 + .saturating_add(Weight::from_parts(1_650, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(10_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } @@ -441,8 +441,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `826` // Estimated: `6766` - // Minimum execution time: 194_513_000 picoseconds. - Weight::from_parts(201_116_000, 6766) + // Minimum execution time: 187_899_000 picoseconds. + Weight::from_parts(195_510_000, 6766) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -461,10 +461,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 269_777_000 picoseconds. - Weight::from_parts(204_229_027, 3607) - // Standard Error: 152 - .saturating_add(Weight::from_parts(72_184, 0).saturating_mul(c.into())) + // Minimum execution time: 254_800_000 picoseconds. + Weight::from_parts(285_603_050, 3607) + // Standard Error: 62 + .saturating_add(Weight::from_parts(66_212, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -482,8 +482,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `315` // Estimated: `3780` - // Minimum execution time: 43_271_000 picoseconds. - Weight::from_parts(44_884_000, 3780) + // Minimum execution time: 43_553_000 picoseconds. + Weight::from_parts(45_036_000, 3780) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -499,8 +499,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `552` // Estimated: `8967` - // Minimum execution time: 34_635_000 picoseconds. - Weight::from_parts(35_477_000, 8967) + // Minimum execution time: 33_223_000 picoseconds. + Weight::from_parts(34_385_000, 8967) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -523,10 +523,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `866 + r * (6 ±0)` // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 266_757_000 picoseconds. - Weight::from_parts(279_787_352, 6806) - // Standard Error: 812 - .saturating_add(Weight::from_parts(329_166, 0).saturating_mul(r.into())) + // Minimum execution time: 254_213_000 picoseconds. + Weight::from_parts(273_464_980, 6806) + // Standard Error: 1_362 + .saturating_add(Weight::from_parts(322_619, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -550,10 +550,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `922 + r * (209 ±0)` // Estimated: `6826 + r * (2684 ±0)` - // Minimum execution time: 266_442_000 picoseconds. - Weight::from_parts(86_660_390, 6826) - // Standard Error: 9_194 - .saturating_add(Weight::from_parts(3_744_648, 0).saturating_mul(r.into())) + // Minimum execution time: 250_273_000 picoseconds. + Weight::from_parts(122_072_782, 6826) + // Standard Error: 5_629 + .saturating_add(Weight::from_parts(3_490_256, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -578,10 +578,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `921 + r * (213 ±0)` // Estimated: `6830 + r * (2688 ±0)` - // Minimum execution time: 265_608_000 picoseconds. - Weight::from_parts(273_219_000, 6830) - // Standard Error: 11_085 - .saturating_add(Weight::from_parts(4_542_778, 0).saturating_mul(r.into())) + // Minimum execution time: 255_187_000 picoseconds. + Weight::from_parts(118_082_505, 6830) + // Standard Error: 6_302 + .saturating_add(Weight::from_parts(4_246_968, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -606,10 +606,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `873 + r * (6 ±0)` // Estimated: `6815 + r * (6 ±0)` - // Minimum execution time: 270_033_000 picoseconds. - Weight::from_parts(288_700_795, 6815) - // Standard Error: 1_628 - .saturating_add(Weight::from_parts(428_991, 0).saturating_mul(r.into())) + // Minimum execution time: 256_833_000 picoseconds. + Weight::from_parts(273_330_216, 6815) + // Standard Error: 881 + .saturating_add(Weight::from_parts(400_105, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -633,10 +633,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863 + r * (3 ±0)` // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 263_789_000 picoseconds. - Weight::from_parts(275_806_968, 6804) - // Standard Error: 936 - .saturating_add(Weight::from_parts(182_805, 0).saturating_mul(r.into())) + // Minimum execution time: 244_193_000 picoseconds. + Weight::from_parts(271_221_908, 6804) + // Standard Error: 442 + .saturating_add(Weight::from_parts(176_480, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -658,10 +658,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `753 + r * (3 ±0)` // Estimated: `6693 + r * (3 ±0)` - // Minimum execution time: 257_922_000 picoseconds. - Weight::from_parts(270_842_153, 6693) - // Standard Error: 637 - .saturating_add(Weight::from_parts(156_567, 0).saturating_mul(r.into())) + // Minimum execution time: 232_603_000 picoseconds. + Weight::from_parts(260_577_368, 6693) + // Standard Error: 365 + .saturating_add(Weight::from_parts(158_126, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -685,10 +685,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `867 + r * (6 ±0)` // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 267_214_000 picoseconds. - Weight::from_parts(273_446_444, 6807) - // Standard Error: 2_355 - .saturating_add(Weight::from_parts(356_663, 0).saturating_mul(r.into())) + // Minimum execution time: 247_564_000 picoseconds. + Weight::from_parts(275_108_914, 6807) + // Standard Error: 505 + .saturating_add(Weight::from_parts(315_065, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -712,10 +712,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863 + r * (6 ±0)` // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 258_860_000 picoseconds. - Weight::from_parts(286_389_737, 6806) - // Standard Error: 1_707 - .saturating_add(Weight::from_parts(366_148, 0).saturating_mul(r.into())) + // Minimum execution time: 258_799_000 picoseconds. + Weight::from_parts(274_338_256, 6806) + // Standard Error: 632 + .saturating_add(Weight::from_parts(355_032, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -739,10 +739,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1007 + r * (6 ±0)` // Estimated: `6931 + r * (6 ±0)` - // Minimum execution time: 267_852_000 picoseconds. - Weight::from_parts(279_617_620, 6931) - // Standard Error: 3_382 - .saturating_add(Weight::from_parts(1_586_170, 0).saturating_mul(r.into())) + // Minimum execution time: 253_335_000 picoseconds. + Weight::from_parts(273_013_859, 6931) + // Standard Error: 2_007 + .saturating_add(Weight::from_parts(1_540_735, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -766,10 +766,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `877 + r * (6 ±0)` // Estimated: `6823 + r * (6 ±0)` - // Minimum execution time: 266_379_000 picoseconds. - Weight::from_parts(287_280_653, 6823) - // Standard Error: 1_774 - .saturating_add(Weight::from_parts(323_724, 0).saturating_mul(r.into())) + // Minimum execution time: 252_325_000 picoseconds. + Weight::from_parts(274_733_944, 6823) + // Standard Error: 603 + .saturating_add(Weight::from_parts(314_467, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -793,10 +793,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `875 + r * (6 ±0)` // Estimated: `6816 + r * (6 ±0)` - // Minimum execution time: 266_417_000 picoseconds. - Weight::from_parts(291_394_038, 6816) - // Standard Error: 1_474 - .saturating_add(Weight::from_parts(328_306, 0).saturating_mul(r.into())) + // Minimum execution time: 250_698_000 picoseconds. + Weight::from_parts(271_707_578, 6816) + // Standard Error: 952 + .saturating_add(Weight::from_parts(318_412, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -820,10 +820,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `872 + r * (6 ±0)` // Estimated: `6819 + r * (6 ±0)` - // Minimum execution time: 269_198_000 picoseconds. - Weight::from_parts(285_025_368, 6819) - // Standard Error: 1_231 - .saturating_add(Weight::from_parts(324_814, 0).saturating_mul(r.into())) + // Minimum execution time: 251_854_000 picoseconds. + Weight::from_parts(272_002_212, 6819) + // Standard Error: 622 + .saturating_add(Weight::from_parts(313_353, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -847,10 +847,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863 + r * (6 ±0)` // Estimated: `6804 + r * (6 ±0)` - // Minimum execution time: 257_514_000 picoseconds. - Weight::from_parts(280_424_571, 6804) - // Standard Error: 723 - .saturating_add(Weight::from_parts(325_607, 0).saturating_mul(r.into())) + // Minimum execution time: 252_010_000 picoseconds. + Weight::from_parts(270_387_000, 6804) + // Standard Error: 659 + .saturating_add(Weight::from_parts(325_856, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -876,10 +876,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `937 + r * (14 ±0)` // Estimated: `6872 + r * (14 ±0)` - // Minimum execution time: 268_221_000 picoseconds. - Weight::from_parts(282_273_629, 6872) - // Standard Error: 2_398 - .saturating_add(Weight::from_parts(1_117_278, 0).saturating_mul(r.into())) + // Minimum execution time: 247_933_000 picoseconds. + Weight::from_parts(281_550_162, 6872) + // Standard Error: 660 + .saturating_add(Weight::from_parts(1_090_869, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 14).saturating_mul(r.into())) @@ -903,10 +903,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `865 + r * (6 ±0)` // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 271_541_000 picoseconds. - Weight::from_parts(276_996_569, 6807) - // Standard Error: 1_462 - .saturating_add(Weight::from_parts(282_119, 0).saturating_mul(r.into())) + // Minimum execution time: 251_158_000 picoseconds. + Weight::from_parts(274_623_152, 6807) + // Standard Error: 491 + .saturating_add(Weight::from_parts(263_916, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -930,10 +930,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `869` // Estimated: `6809` - // Minimum execution time: 256_410_000 picoseconds. - Weight::from_parts(206_888_877, 6809) - // Standard Error: 22 - .saturating_add(Weight::from_parts(1_154, 0).saturating_mul(n.into())) + // Minimum execution time: 263_205_000 picoseconds. + Weight::from_parts(216_792_893, 6809) + // Standard Error: 23 + .saturating_add(Weight::from_parts(989, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -956,10 +956,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `853 + r * (45 ±0)` // Estimated: `6793 + r * (45 ±0)` - // Minimum execution time: 248_852_000 picoseconds. - Weight::from_parts(277_852_834, 6793) - // Standard Error: 1_257_219 - .saturating_add(Weight::from_parts(1_394_065, 0).saturating_mul(r.into())) + // Minimum execution time: 239_663_000 picoseconds. + Weight::from_parts(266_124_565, 6793) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 45).saturating_mul(r.into())) @@ -983,10 +981,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863` // Estimated: `6810` - // Minimum execution time: 269_101_000 picoseconds. - Weight::from_parts(273_407_545, 6810) - // Standard Error: 2 - .saturating_add(Weight::from_parts(339, 0).saturating_mul(n.into())) + // Minimum execution time: 241_763_000 picoseconds. + Weight::from_parts(266_535_552, 6810) + // Standard Error: 0 + .saturating_add(Weight::from_parts(320, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1015,10 +1013,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2972 + r * (316 ±0)` // Estimated: `8912 + r * (5266 ±0)` - // Minimum execution time: 296_318_000 picoseconds. - Weight::from_parts(322_448_344, 8912) - // Standard Error: 2_358_838 - .saturating_add(Weight::from_parts(107_092_455, 0).saturating_mul(r.into())) + // Minimum execution time: 265_888_000 picoseconds. + Weight::from_parts(291_232_232, 8912) + // Standard Error: 845_475 + .saturating_add(Weight::from_parts(104_398_867, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((7_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1046,10 +1044,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `944 + r * (10 ±0)` // Estimated: `6885 + r * (10 ±0)` - // Minimum execution time: 268_264_000 picoseconds. - Weight::from_parts(285_298_853, 6885) - // Standard Error: 3_238 - .saturating_add(Weight::from_parts(1_238_513, 0).saturating_mul(r.into())) + // Minimum execution time: 248_500_000 picoseconds. + Weight::from_parts(282_353_053, 6885) + // Standard Error: 1_144 + .saturating_add(Weight::from_parts(1_193_841, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -1073,10 +1071,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863 + r * (10 ±0)` // Estimated: `6805 + r * (10 ±0)` - // Minimum execution time: 267_417_000 picoseconds. - Weight::from_parts(290_097_452, 6805) - // Standard Error: 2_523 - .saturating_add(Weight::from_parts(2_012_375, 0).saturating_mul(r.into())) + // Minimum execution time: 248_130_000 picoseconds. + Weight::from_parts(279_583_178, 6805) + // Standard Error: 971 + .saturating_add(Weight::from_parts(1_987_941, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -1101,12 +1099,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `880 + t * (32 ±0)` // Estimated: `6825 + t * (2508 ±0)` - // Minimum execution time: 269_735_000 picoseconds. - Weight::from_parts(291_680_757, 6825) - // Standard Error: 196_822 - .saturating_add(Weight::from_parts(2_827_797, 0).saturating_mul(t.into())) - // Standard Error: 55 - .saturating_add(Weight::from_parts(262, 0).saturating_mul(n.into())) + // Minimum execution time: 258_594_000 picoseconds. + Weight::from_parts(276_734_422, 6825) + // Standard Error: 102_093 + .saturating_add(Weight::from_parts(2_559_383, 0).saturating_mul(t.into())) + // Standard Error: 28 + .saturating_add(Weight::from_parts(501, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1132,10 +1130,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `862 + r * (7 ±0)` // Estimated: `6807 + r * (7 ±0)` - // Minimum execution time: 161_454_000 picoseconds. - Weight::from_parts(181_662_272, 6807) - // Standard Error: 729 - .saturating_add(Weight::from_parts(221_968, 0).saturating_mul(r.into())) + // Minimum execution time: 154_564_000 picoseconds. + Weight::from_parts(168_931_365, 6807) + // Standard Error: 349 + .saturating_add(Weight::from_parts(226_848, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 7).saturating_mul(r.into())) @@ -1159,10 +1157,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `125813` // Estimated: `131755` - // Minimum execution time: 418_479_000 picoseconds. - Weight::from_parts(397_691_558, 131755) + // Minimum execution time: 394_382_000 picoseconds. + Weight::from_parts(376_780_500, 131755) // Standard Error: 12 - .saturating_add(Weight::from_parts(1_099, 0).saturating_mul(i.into())) + .saturating_add(Weight::from_parts(1_026, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1173,10 +1171,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `924 + r * (292 ±0)` // Estimated: `926 + r * (293 ±0)` - // Minimum execution time: 268_810_000 picoseconds. - Weight::from_parts(129_545_478, 926) - // Standard Error: 21_173 - .saturating_add(Weight::from_parts(7_118_874, 0).saturating_mul(r.into())) + // Minimum execution time: 249_757_000 picoseconds. + Weight::from_parts(177_324_374, 926) + // Standard Error: 9_512 + .saturating_add(Weight::from_parts(6_176_717, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1190,10 +1188,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1447` // Estimated: `1430` - // Minimum execution time: 286_965_000 picoseconds. - Weight::from_parts(340_396_510, 1430) - // Standard Error: 90 - .saturating_add(Weight::from_parts(455, 0).saturating_mul(n.into())) + // Minimum execution time: 267_564_000 picoseconds. + Weight::from_parts(328_701_080, 1430) + // Standard Error: 61 + .saturating_add(Weight::from_parts(576, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(8_u64)) } @@ -1204,10 +1202,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1253 + n * (1 ±0)` // Estimated: `1253 + n * (1 ±0)` - // Minimum execution time: 272_395_000 picoseconds. - Weight::from_parts(302_307_069, 1253) - // Standard Error: 94 - .saturating_add(Weight::from_parts(156, 0).saturating_mul(n.into())) + // Minimum execution time: 266_347_000 picoseconds. + Weight::from_parts(289_824_718, 1253) + // Standard Error: 34 + .saturating_add(Weight::from_parts(184, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1219,10 +1217,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `921 + r * (288 ±0)` // Estimated: `927 + r * (289 ±0)` - // Minimum execution time: 269_165_000 picoseconds. - Weight::from_parts(167_174_485, 927) - // Standard Error: 23_564 - .saturating_add(Weight::from_parts(6_921_525, 0).saturating_mul(r.into())) + // Minimum execution time: 247_207_000 picoseconds. + Weight::from_parts(179_856_075, 927) + // Standard Error: 9_383 + .saturating_add(Weight::from_parts(6_053_198, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1236,8 +1234,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1249 + n * (1 ±0)` // Estimated: `1249 + n * (1 ±0)` - // Minimum execution time: 270_248_000 picoseconds. - Weight::from_parts(296_573_310, 1249) + // Minimum execution time: 262_655_000 picoseconds. + Weight::from_parts(289_482_543, 1249) + // Standard Error: 35 + .saturating_add(Weight::from_parts(92, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1249,10 +1249,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `921 + r * (296 ±0)` // Estimated: `923 + r * (297 ±0)` - // Minimum execution time: 270_883_000 picoseconds. - Weight::from_parts(189_792_705, 923) - // Standard Error: 11_149 - .saturating_add(Weight::from_parts(5_232_100, 0).saturating_mul(r.into())) + // Minimum execution time: 247_414_000 picoseconds. + Weight::from_parts(203_317_182, 923) + // Standard Error: 7_191 + .saturating_add(Weight::from_parts(4_925_154, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1265,10 +1265,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1265 + n * (1 ±0)` // Estimated: `1265 + n * (1 ±0)` - // Minimum execution time: 263_833_000 picoseconds. - Weight::from_parts(290_179_222, 1265) - // Standard Error: 44 - .saturating_add(Weight::from_parts(831, 0).saturating_mul(n.into())) + // Minimum execution time: 258_910_000 picoseconds. + Weight::from_parts(283_086_514, 1265) + // Standard Error: 39 + .saturating_add(Weight::from_parts(980, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1280,10 +1280,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `932 + r * (288 ±0)` // Estimated: `929 + r * (289 ±0)` - // Minimum execution time: 252_637_000 picoseconds. - Weight::from_parts(98_108_825, 929) - // Standard Error: 23_580 - .saturating_add(Weight::from_parts(5_408_076, 0).saturating_mul(r.into())) + // Minimum execution time: 252_410_000 picoseconds. + Weight::from_parts(201_227_879, 929) + // Standard Error: 6_899 + .saturating_add(Weight::from_parts(4_774_983, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1296,8 +1296,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1252 + n * (1 ±0)` // Estimated: `1252 + n * (1 ±0)` - // Minimum execution time: 279_133_000 picoseconds. - Weight::from_parts(301_192_115, 1252) + // Minimum execution time: 259_053_000 picoseconds. + Weight::from_parts(283_392_084, 1252) + // Standard Error: 41 + .saturating_add(Weight::from_parts(213, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1309,10 +1311,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `914 + r * (296 ±0)` // Estimated: `919 + r * (297 ±0)` - // Minimum execution time: 268_833_000 picoseconds. - Weight::from_parts(56_229_951, 919) - // Standard Error: 25_800 - .saturating_add(Weight::from_parts(7_607_143, 0).saturating_mul(r.into())) + // Minimum execution time: 251_371_000 picoseconds. + Weight::from_parts(177_119_717, 919) + // Standard Error: 9_421 + .saturating_add(Weight::from_parts(6_226_005, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1326,10 +1328,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1266 + n * (1 ±0)` // Estimated: `1266 + n * (1 ±0)` - // Minimum execution time: 288_677_000 picoseconds. - Weight::from_parts(301_986_360, 1266) - // Standard Error: 39 - .saturating_add(Weight::from_parts(867, 0).saturating_mul(n.into())) + // Minimum execution time: 263_350_000 picoseconds. + Weight::from_parts(284_323_917, 1266) + // Standard Error: 31 + .saturating_add(Weight::from_parts(921, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1353,10 +1355,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1415 + r * (45 ±0)` // Estimated: `7307 + r * (2520 ±0)` - // Minimum execution time: 275_956_000 picoseconds. - Weight::from_parts(280_865_651, 7307) - // Standard Error: 28_235 - .saturating_add(Weight::from_parts(32_233_352, 0).saturating_mul(r.into())) + // Minimum execution time: 248_701_000 picoseconds. + Weight::from_parts(17_811_969, 7307) + // Standard Error: 35_154 + .saturating_add(Weight::from_parts(31_809_738, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) @@ -1382,10 +1384,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1260 + r * (245 ±0)` // Estimated: `9440 + r * (2721 ±0)` - // Minimum execution time: 269_188_000 picoseconds. - Weight::from_parts(276_038_000, 9440) - // Standard Error: 262_029 - .saturating_add(Weight::from_parts(250_766_832, 0).saturating_mul(r.into())) + // Minimum execution time: 247_335_000 picoseconds. + Weight::from_parts(264_025_000, 9440) + // Standard Error: 121_299 + .saturating_add(Weight::from_parts(234_770_827, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) @@ -1411,10 +1413,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0 + r * (576 ±0)` // Estimated: `6812 + r * (2637 ±3)` - // Minimum execution time: 267_543_000 picoseconds. - Weight::from_parts(271_365_000, 6812) - // Standard Error: 190_454 - .saturating_add(Weight::from_parts(242_627_807, 0).saturating_mul(r.into())) + // Minimum execution time: 261_011_000 picoseconds. + Weight::from_parts(264_554_000, 6812) + // Standard Error: 104_415 + .saturating_add(Weight::from_parts(231_627_084, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1441,12 +1443,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1307 + t * (277 ±0)` // Estimated: `12197 + t * (5227 ±0)` - // Minimum execution time: 453_215_000 picoseconds. - Weight::from_parts(32_029_330, 12197) - // Standard Error: 12_154_174 - .saturating_add(Weight::from_parts(392_862_355, 0).saturating_mul(t.into())) + // Minimum execution time: 445_561_000 picoseconds. + Weight::from_parts(62_287_490, 12197) + // Standard Error: 11_797_697 + .saturating_add(Weight::from_parts(357_530_529, 0).saturating_mul(t.into())) // Standard Error: 17 - .saturating_add(Weight::from_parts(1_059, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(970, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(13_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(6_u64)) @@ -1476,10 +1478,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1278 + r * (255 ±0)` // Estimated: `9620 + r * (2731 ±0)` - // Minimum execution time: 635_304_000 picoseconds. - Weight::from_parts(645_872_000, 9620) - // Standard Error: 356_713 - .saturating_add(Weight::from_parts(371_999_658, 0).saturating_mul(r.into())) + // Minimum execution time: 621_897_000 picoseconds. + Weight::from_parts(631_687_000, 9620) + // Standard Error: 215_241 + .saturating_add(Weight::from_parts(350_527_831, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(7_u64)) @@ -1511,12 +1513,14 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1303 + t * (104 ±0)` // Estimated: `12211 + t * (2549 ±1)` - // Minimum execution time: 2_225_692_000 picoseconds. - Weight::from_parts(1_292_861_603, 12211) - // Standard Error: 24 - .saturating_add(Weight::from_parts(1_075, 0).saturating_mul(i.into())) - // Standard Error: 24 - .saturating_add(Weight::from_parts(1_278, 0).saturating_mul(s.into())) + // Minimum execution time: 2_181_184_000 picoseconds. + Weight::from_parts(1_194_190_111, 12211) + // Standard Error: 11_578_766 + .saturating_add(Weight::from_parts(6_361_884, 0).saturating_mul(t.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(1_025, 0).saturating_mul(i.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(1_158, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(16_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(11_u64)) @@ -1542,10 +1546,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `862 + r * (8 ±0)` // Estimated: `6801 + r * (8 ±0)` - // Minimum execution time: 252_664_000 picoseconds. - Weight::from_parts(277_967_331, 6801) - // Standard Error: 723 - .saturating_add(Weight::from_parts(370_111, 0).saturating_mul(r.into())) + // Minimum execution time: 241_609_000 picoseconds. + Weight::from_parts(268_716_874, 6801) + // Standard Error: 617 + .saturating_add(Weight::from_parts(377_753, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1569,10 +1573,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `870` // Estimated: `6808` - // Minimum execution time: 252_485_000 picoseconds. - Weight::from_parts(259_271_531, 6808) - // Standard Error: 2 - .saturating_add(Weight::from_parts(1_091, 0).saturating_mul(n.into())) + // Minimum execution time: 261_296_000 picoseconds. + Weight::from_parts(255_531_654, 6808) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_081, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1595,10 +1599,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6806 + r * (8 ±0)` - // Minimum execution time: 249_270_000 picoseconds. - Weight::from_parts(272_528_711, 6806) - // Standard Error: 903 - .saturating_add(Weight::from_parts(793_299, 0).saturating_mul(r.into())) + // Minimum execution time: 243_583_000 picoseconds. + Weight::from_parts(270_025_058, 6806) + // Standard Error: 560 + .saturating_add(Weight::from_parts(767_519, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1622,10 +1626,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6814` - // Minimum execution time: 249_470_000 picoseconds. - Weight::from_parts(273_317_815, 6814) - // Standard Error: 4 - .saturating_add(Weight::from_parts(3_400, 0).saturating_mul(n.into())) + // Minimum execution time: 253_798_000 picoseconds. + Weight::from_parts(265_542_351, 6814) + // Standard Error: 0 + .saturating_add(Weight::from_parts(3_343, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1648,10 +1652,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6808 + r * (8 ±0)` - // Minimum execution time: 265_503_000 picoseconds. - Weight::from_parts(279_774_666, 6808) - // Standard Error: 1_351 - .saturating_add(Weight::from_parts(439_734, 0).saturating_mul(r.into())) + // Minimum execution time: 247_332_000 picoseconds. + Weight::from_parts(269_183_656, 6808) + // Standard Error: 665 + .saturating_add(Weight::from_parts(443_386, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1675,10 +1679,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6813` - // Minimum execution time: 265_009_000 picoseconds. - Weight::from_parts(270_467_968, 6813) + // Minimum execution time: 250_855_000 picoseconds. + Weight::from_parts(258_752_975, 6813) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_206, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_202, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1701,10 +1705,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6805 + r * (8 ±0)` - // Minimum execution time: 251_771_000 picoseconds. - Weight::from_parts(283_553_523, 6805) - // Standard Error: 1_053 - .saturating_add(Weight::from_parts(445_715, 0).saturating_mul(r.into())) + // Minimum execution time: 240_733_000 picoseconds. + Weight::from_parts(269_134_358, 6805) + // Standard Error: 512 + .saturating_add(Weight::from_parts(440_043, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1728,10 +1732,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6811` - // Minimum execution time: 253_733_000 picoseconds. - Weight::from_parts(264_277_000, 6811) - // Standard Error: 3 - .saturating_add(Weight::from_parts(1_226, 0).saturating_mul(n.into())) + // Minimum execution time: 247_377_000 picoseconds. + Weight::from_parts(261_077_322, 6811) + // Standard Error: 0 + .saturating_add(Weight::from_parts(1_195, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1754,10 +1758,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `997 + n * (1 ±0)` // Estimated: `6934 + n * (1 ±0)` - // Minimum execution time: 337_326_000 picoseconds. - Weight::from_parts(346_340_758, 6934) - // Standard Error: 18 - .saturating_add(Weight::from_parts(6_110, 0).saturating_mul(n.into())) + // Minimum execution time: 307_337_000 picoseconds. + Weight::from_parts(326_710_473, 6934) + // Standard Error: 9 + .saturating_add(Weight::from_parts(5_765, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1781,10 +1785,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `805 + r * (112 ±0)` // Estimated: `6748 + r * (112 ±0)` - // Minimum execution time: 253_852_000 picoseconds. - Weight::from_parts(335_731_679, 6748) - // Standard Error: 13_615 - .saturating_add(Weight::from_parts(41_557_258, 0).saturating_mul(r.into())) + // Minimum execution time: 245_432_000 picoseconds. + Weight::from_parts(294_206_377, 6748) + // Standard Error: 7_229 + .saturating_add(Weight::from_parts(41_480_485, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(r.into())) @@ -1807,11 +1811,11 @@ impl WeightInfo for SubstrateWeight { fn seal_ecdsa_recover(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `907 + r * (76 ±0)` - // Estimated: `6801 + r * (77 ±0)` - // Minimum execution time: 256_283_000 picoseconds. - Weight::from_parts(338_634_113, 6801) - // Standard Error: 43_436 - .saturating_add(Weight::from_parts(46_607_112, 0).saturating_mul(r.into())) + // Estimated: `6802 + r * (77 ±0)` + // Minimum execution time: 247_788_000 picoseconds. + Weight::from_parts(303_940_062, 6802) + // Standard Error: 10_671 + .saturating_add(Weight::from_parts(45_730_772, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 77).saturating_mul(r.into())) @@ -1835,10 +1839,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `877 + r * (42 ±0)` // Estimated: `6816 + r * (42 ±0)` - // Minimum execution time: 269_144_000 picoseconds. - Weight::from_parts(331_790_138, 6816) - // Standard Error: 23_357 - .saturating_add(Weight::from_parts(12_213_638, 0).saturating_mul(r.into())) + // Minimum execution time: 248_825_000 picoseconds. + Weight::from_parts(286_832_225, 6816) + // Standard Error: 5_274 + .saturating_add(Weight::from_parts(11_889_262, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 42).saturating_mul(r.into())) @@ -1861,11 +1865,11 @@ impl WeightInfo for SubstrateWeight { fn seal_set_code_hash(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + r * (965 ±0)` - // Estimated: `6807 + r * (3090 ±10)` - // Minimum execution time: 262_624_000 picoseconds. - Weight::from_parts(275_865_000, 6807) - // Standard Error: 64_162 - .saturating_add(Weight::from_parts(26_205_387, 0).saturating_mul(r.into())) + // Estimated: `6807 + r * (3090 ±7)` + // Minimum execution time: 244_982_000 picoseconds. + Weight::from_parts(265_297_000, 6807) + // Standard Error: 39_895 + .saturating_add(Weight::from_parts(22_435_888, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1891,10 +1895,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `928 + r * (131 ±0)` // Estimated: `6878 + r * (2606 ±0)` - // Minimum execution time: 265_482_000 picoseconds. - Weight::from_parts(296_491_925, 6878) - // Standard Error: 46_681 - .saturating_add(Weight::from_parts(6_572_162, 0).saturating_mul(r.into())) + // Minimum execution time: 246_455_000 picoseconds. + Weight::from_parts(275_334_919, 6878) + // Standard Error: 20_911 + .saturating_add(Weight::from_parts(6_427_525, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1920,10 +1924,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `969 + r * (183 ±0)` // Estimated: `129453 + r * (2568 ±0)` - // Minimum execution time: 257_532_000 picoseconds. - Weight::from_parts(299_110_930, 129453) - // Standard Error: 55_003 - .saturating_add(Weight::from_parts(6_130_357, 0).saturating_mul(r.into())) + // Minimum execution time: 254_472_000 picoseconds. + Weight::from_parts(280_657_909, 129453) + // Standard Error: 20_131 + .saturating_add(Weight::from_parts(5_644_006, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1949,10 +1953,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `858 + r * (3 ±0)` // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 268_894_000 picoseconds. - Weight::from_parts(287_048_741, 6804) - // Standard Error: 1_156 - .saturating_add(Weight::from_parts(172_596, 0).saturating_mul(r.into())) + // Minimum execution time: 250_535_000 picoseconds. + Weight::from_parts(270_318_376, 6804) + // Standard Error: 386 + .saturating_add(Weight::from_parts(174_627, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -1976,10 +1980,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2109 + r * (39 ±0)` // Estimated: `7899 + r * (40 ±0)` - // Minimum execution time: 262_736_000 picoseconds. - Weight::from_parts(389_199_672, 7899) - // Standard Error: 2_646 - .saturating_add(Weight::from_parts(290_309, 0).saturating_mul(r.into())) + // Minimum execution time: 248_174_000 picoseconds. + Weight::from_parts(301_826_520, 7899) + // Standard Error: 801 + .saturating_add(Weight::from_parts(248_479, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) @@ -2005,23 +2009,23 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `861 + r * (3 ±0)` // Estimated: `6801 + r * (3 ±0)` - // Minimum execution time: 253_465_000 picoseconds. - Weight::from_parts(283_153_874, 6801) - // Standard Error: 745 - .saturating_add(Weight::from_parts(148_864, 0).saturating_mul(r.into())) + // Minimum execution time: 246_540_000 picoseconds. + Weight::from_parts(268_913_509, 6801) + // Standard Error: 378 + .saturating_add(Weight::from_parts(154_950, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. - fn instr_i64const(r: u32, ) -> Weight { + fn instr_i64_load_store(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_342_000 picoseconds. - Weight::from_parts(1_940_100, 0) - // Standard Error: 21 - .saturating_add(Weight::from_parts(11_117, 0).saturating_mul(r.into())) + // Minimum execution time: 1_777_000 picoseconds. + Weight::from_parts(1_707_601, 0) + // Standard Error: 14 + .saturating_add(Weight::from_parts(15_392, 0).saturating_mul(r.into())) } } @@ -2033,8 +2037,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 1_991_000 picoseconds. - Weight::from_parts(2_135_000, 1627) + // Minimum execution time: 1_997_000 picoseconds. + Weight::from_parts(2_130_000, 1627) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -2044,10 +2048,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `452 + k * (69 ±0)` // Estimated: `442 + k * (70 ±0)` - // Minimum execution time: 11_969_000 picoseconds. - Weight::from_parts(7_055_855, 442) - // Standard Error: 2_328 - .saturating_add(Weight::from_parts(1_212_989, 0).saturating_mul(k.into())) + // Minimum execution time: 12_276_000 picoseconds. + Weight::from_parts(1_593_881, 442) + // Standard Error: 1_135 + .saturating_add(Weight::from_parts(1_109_302, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(RocksDbWeight::get().writes(2_u64)) @@ -2061,10 +2065,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `211 + c * (1 ±0)` // Estimated: `6149 + c * (1 ±0)` - // Minimum execution time: 8_064_000 picoseconds. - Weight::from_parts(8_301_148, 6149) + // Minimum execution time: 8_176_000 picoseconds. + Weight::from_parts(8_555_388, 6149) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_180, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(1_184, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -2077,8 +2081,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `510` // Estimated: `6450` - // Minimum execution time: 15_789_000 picoseconds. - Weight::from_parts(16_850_000, 6450) + // Minimum execution time: 16_270_000 picoseconds. + Weight::from_parts(16_779_000, 6450) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2091,10 +2095,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `171 + k * (1 ±0)` // Estimated: `3635 + k * (1 ±0)` - // Minimum execution time: 3_369_000 picoseconds. - Weight::from_parts(3_516_000, 3635) - // Standard Error: 960 - .saturating_add(Weight::from_parts(1_139_317, 0).saturating_mul(k.into())) + // Minimum execution time: 3_572_000 picoseconds. + Weight::from_parts(1_950_905, 3635) + // Standard Error: 1_597 + .saturating_add(Weight::from_parts(1_123_190, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(k.into()))) @@ -2113,10 +2117,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `325 + c * (1 ±0)` // Estimated: `6263 + c * (1 ±0)` - // Minimum execution time: 16_320_000 picoseconds. - Weight::from_parts(16_090_036, 6263) + // Minimum execution time: 16_873_000 picoseconds. + Weight::from_parts(16_790_402, 6263) // Standard Error: 1 - .saturating_add(Weight::from_parts(417, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(396, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -2127,8 +2131,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `440` // Estimated: `6380` - // Minimum execution time: 12_669_000 picoseconds. - Weight::from_parts(13_118_000, 6380) + // Minimum execution time: 11_904_000 picoseconds. + Weight::from_parts(12_785_000, 6380) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2142,8 +2146,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `352` // Estimated: `6292` - // Minimum execution time: 45_403_000 picoseconds. - Weight::from_parts(46_636_000, 6292) + // Minimum execution time: 44_920_000 picoseconds. + Weight::from_parts(46_163_000, 6292) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2155,8 +2159,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `594` // Estimated: `6534` - // Minimum execution time: 53_622_000 picoseconds. - Weight::from_parts(55_444_000, 6534) + // Minimum execution time: 53_864_000 picoseconds. + Weight::from_parts(55_139_000, 6534) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -2166,8 +2170,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 2_444_000 picoseconds. - Weight::from_parts(2_587_000, 1627) + // Minimum execution time: 2_375_000 picoseconds. + Weight::from_parts(2_487_000, 1627) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2179,8 +2183,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `166` // Estimated: `3631` - // Minimum execution time: 11_476_000 picoseconds. - Weight::from_parts(11_944_000, 3631) + // Minimum execution time: 11_580_000 picoseconds. + Weight::from_parts(11_980_000, 3631) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -2190,8 +2194,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 4_652_000 picoseconds. - Weight::from_parts(4_792_000, 3607) + // Minimum execution time: 4_557_000 picoseconds. + Weight::from_parts(4_807_000, 3607) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -2202,8 +2206,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `167` // Estimated: `3632` - // Minimum execution time: 6_054_000 picoseconds. - Weight::from_parts(6_278_000, 3632) + // Minimum execution time: 6_253_000 picoseconds. + Weight::from_parts(6_479_000, 3632) .saturating_add(RocksDbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -2214,8 +2218,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 6_056_000 picoseconds. - Weight::from_parts(6_343_000, 3607) + // Minimum execution time: 6_166_000 picoseconds. + Weight::from_parts(6_545_000, 3607) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2236,12 +2240,12 @@ impl WeightInfo for () { /// The range of component `c` is `[0, 125952]`. fn call_with_code_per_byte(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `792` - // Estimated: `6743 + c * (1 ±0)` - // Minimum execution time: 303_205_000 picoseconds. - Weight::from_parts(266_154_889, 6743) - // Standard Error: 79 - .saturating_add(Weight::from_parts(35_195, 0).saturating_mul(c.into())) + // Measured: `801 + c * (1 ±0)` + // Estimated: `6739 + c * (1 ±0)` + // Minimum execution time: 282_232_000 picoseconds. + Weight::from_parts(266_148_573, 6739) + // Standard Error: 69 + .saturating_add(Weight::from_parts(34_592, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -2270,15 +2274,15 @@ impl WeightInfo for () { fn instantiate_with_code(c: u32, i: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `323` - // Estimated: `8747` - // Minimum execution time: 4_311_802_000 picoseconds. - Weight::from_parts(777_467_048, 8747) - // Standard Error: 338 - .saturating_add(Weight::from_parts(105_862, 0).saturating_mul(c.into())) - // Standard Error: 40 - .saturating_add(Weight::from_parts(1_856, 0).saturating_mul(i.into())) - // Standard Error: 40 - .saturating_add(Weight::from_parts(1_443, 0).saturating_mul(s.into())) + // Estimated: `8737` + // Minimum execution time: 3_760_879_000 picoseconds. + Weight::from_parts(794_812_431, 8737) + // Standard Error: 149 + .saturating_add(Weight::from_parts(101_881, 0).saturating_mul(c.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(1_404, 0).saturating_mul(i.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(1_544, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(10_u64)) } @@ -2306,12 +2310,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `560` // Estimated: `6504` - // Minimum execution time: 1_958_694_000 picoseconds. - Weight::from_parts(331_222_273, 6504) - // Standard Error: 13 - .saturating_add(Weight::from_parts(1_954, 0).saturating_mul(i.into())) - // Standard Error: 13 - .saturating_add(Weight::from_parts(1_685, 0).saturating_mul(s.into())) + // Minimum execution time: 1_953_162_000 picoseconds. + Weight::from_parts(374_252_840, 6504) + // Standard Error: 7 + .saturating_add(Weight::from_parts(1_630, 0).saturating_mul(i.into())) + // Standard Error: 7 + .saturating_add(Weight::from_parts(1_650, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(10_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } @@ -2333,8 +2337,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `826` // Estimated: `6766` - // Minimum execution time: 194_513_000 picoseconds. - Weight::from_parts(201_116_000, 6766) + // Minimum execution time: 187_899_000 picoseconds. + Weight::from_parts(195_510_000, 6766) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -2353,10 +2357,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 269_777_000 picoseconds. - Weight::from_parts(204_229_027, 3607) - // Standard Error: 152 - .saturating_add(Weight::from_parts(72_184, 0).saturating_mul(c.into())) + // Minimum execution time: 254_800_000 picoseconds. + Weight::from_parts(285_603_050, 3607) + // Standard Error: 62 + .saturating_add(Weight::from_parts(66_212, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -2374,8 +2378,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `315` // Estimated: `3780` - // Minimum execution time: 43_271_000 picoseconds. - Weight::from_parts(44_884_000, 3780) + // Minimum execution time: 43_553_000 picoseconds. + Weight::from_parts(45_036_000, 3780) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -2391,8 +2395,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `552` // Estimated: `8967` - // Minimum execution time: 34_635_000 picoseconds. - Weight::from_parts(35_477_000, 8967) + // Minimum execution time: 33_223_000 picoseconds. + Weight::from_parts(34_385_000, 8967) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -2415,10 +2419,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `866 + r * (6 ±0)` // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 266_757_000 picoseconds. - Weight::from_parts(279_787_352, 6806) - // Standard Error: 812 - .saturating_add(Weight::from_parts(329_166, 0).saturating_mul(r.into())) + // Minimum execution time: 254_213_000 picoseconds. + Weight::from_parts(273_464_980, 6806) + // Standard Error: 1_362 + .saturating_add(Weight::from_parts(322_619, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2442,10 +2446,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `922 + r * (209 ±0)` // Estimated: `6826 + r * (2684 ±0)` - // Minimum execution time: 266_442_000 picoseconds. - Weight::from_parts(86_660_390, 6826) - // Standard Error: 9_194 - .saturating_add(Weight::from_parts(3_744_648, 0).saturating_mul(r.into())) + // Minimum execution time: 250_273_000 picoseconds. + Weight::from_parts(122_072_782, 6826) + // Standard Error: 5_629 + .saturating_add(Weight::from_parts(3_490_256, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2470,10 +2474,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `921 + r * (213 ±0)` // Estimated: `6830 + r * (2688 ±0)` - // Minimum execution time: 265_608_000 picoseconds. - Weight::from_parts(273_219_000, 6830) - // Standard Error: 11_085 - .saturating_add(Weight::from_parts(4_542_778, 0).saturating_mul(r.into())) + // Minimum execution time: 255_187_000 picoseconds. + Weight::from_parts(118_082_505, 6830) + // Standard Error: 6_302 + .saturating_add(Weight::from_parts(4_246_968, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2498,10 +2502,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `873 + r * (6 ±0)` // Estimated: `6815 + r * (6 ±0)` - // Minimum execution time: 270_033_000 picoseconds. - Weight::from_parts(288_700_795, 6815) - // Standard Error: 1_628 - .saturating_add(Weight::from_parts(428_991, 0).saturating_mul(r.into())) + // Minimum execution time: 256_833_000 picoseconds. + Weight::from_parts(273_330_216, 6815) + // Standard Error: 881 + .saturating_add(Weight::from_parts(400_105, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2525,10 +2529,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863 + r * (3 ±0)` // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 263_789_000 picoseconds. - Weight::from_parts(275_806_968, 6804) - // Standard Error: 936 - .saturating_add(Weight::from_parts(182_805, 0).saturating_mul(r.into())) + // Minimum execution time: 244_193_000 picoseconds. + Weight::from_parts(271_221_908, 6804) + // Standard Error: 442 + .saturating_add(Weight::from_parts(176_480, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -2550,10 +2554,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `753 + r * (3 ±0)` // Estimated: `6693 + r * (3 ±0)` - // Minimum execution time: 257_922_000 picoseconds. - Weight::from_parts(270_842_153, 6693) - // Standard Error: 637 - .saturating_add(Weight::from_parts(156_567, 0).saturating_mul(r.into())) + // Minimum execution time: 232_603_000 picoseconds. + Weight::from_parts(260_577_368, 6693) + // Standard Error: 365 + .saturating_add(Weight::from_parts(158_126, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -2577,10 +2581,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `867 + r * (6 ±0)` // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 267_214_000 picoseconds. - Weight::from_parts(273_446_444, 6807) - // Standard Error: 2_355 - .saturating_add(Weight::from_parts(356_663, 0).saturating_mul(r.into())) + // Minimum execution time: 247_564_000 picoseconds. + Weight::from_parts(275_108_914, 6807) + // Standard Error: 505 + .saturating_add(Weight::from_parts(315_065, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2604,10 +2608,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863 + r * (6 ±0)` // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 258_860_000 picoseconds. - Weight::from_parts(286_389_737, 6806) - // Standard Error: 1_707 - .saturating_add(Weight::from_parts(366_148, 0).saturating_mul(r.into())) + // Minimum execution time: 258_799_000 picoseconds. + Weight::from_parts(274_338_256, 6806) + // Standard Error: 632 + .saturating_add(Weight::from_parts(355_032, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2631,10 +2635,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1007 + r * (6 ±0)` // Estimated: `6931 + r * (6 ±0)` - // Minimum execution time: 267_852_000 picoseconds. - Weight::from_parts(279_617_620, 6931) - // Standard Error: 3_382 - .saturating_add(Weight::from_parts(1_586_170, 0).saturating_mul(r.into())) + // Minimum execution time: 253_335_000 picoseconds. + Weight::from_parts(273_013_859, 6931) + // Standard Error: 2_007 + .saturating_add(Weight::from_parts(1_540_735, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2658,10 +2662,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `877 + r * (6 ±0)` // Estimated: `6823 + r * (6 ±0)` - // Minimum execution time: 266_379_000 picoseconds. - Weight::from_parts(287_280_653, 6823) - // Standard Error: 1_774 - .saturating_add(Weight::from_parts(323_724, 0).saturating_mul(r.into())) + // Minimum execution time: 252_325_000 picoseconds. + Weight::from_parts(274_733_944, 6823) + // Standard Error: 603 + .saturating_add(Weight::from_parts(314_467, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2685,10 +2689,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `875 + r * (6 ±0)` // Estimated: `6816 + r * (6 ±0)` - // Minimum execution time: 266_417_000 picoseconds. - Weight::from_parts(291_394_038, 6816) - // Standard Error: 1_474 - .saturating_add(Weight::from_parts(328_306, 0).saturating_mul(r.into())) + // Minimum execution time: 250_698_000 picoseconds. + Weight::from_parts(271_707_578, 6816) + // Standard Error: 952 + .saturating_add(Weight::from_parts(318_412, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2712,10 +2716,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `872 + r * (6 ±0)` // Estimated: `6819 + r * (6 ±0)` - // Minimum execution time: 269_198_000 picoseconds. - Weight::from_parts(285_025_368, 6819) - // Standard Error: 1_231 - .saturating_add(Weight::from_parts(324_814, 0).saturating_mul(r.into())) + // Minimum execution time: 251_854_000 picoseconds. + Weight::from_parts(272_002_212, 6819) + // Standard Error: 622 + .saturating_add(Weight::from_parts(313_353, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2739,10 +2743,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863 + r * (6 ±0)` // Estimated: `6804 + r * (6 ±0)` - // Minimum execution time: 257_514_000 picoseconds. - Weight::from_parts(280_424_571, 6804) - // Standard Error: 723 - .saturating_add(Weight::from_parts(325_607, 0).saturating_mul(r.into())) + // Minimum execution time: 252_010_000 picoseconds. + Weight::from_parts(270_387_000, 6804) + // Standard Error: 659 + .saturating_add(Weight::from_parts(325_856, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2768,10 +2772,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `937 + r * (14 ±0)` // Estimated: `6872 + r * (14 ±0)` - // Minimum execution time: 268_221_000 picoseconds. - Weight::from_parts(282_273_629, 6872) - // Standard Error: 2_398 - .saturating_add(Weight::from_parts(1_117_278, 0).saturating_mul(r.into())) + // Minimum execution time: 247_933_000 picoseconds. + Weight::from_parts(281_550_162, 6872) + // Standard Error: 660 + .saturating_add(Weight::from_parts(1_090_869, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 14).saturating_mul(r.into())) @@ -2795,10 +2799,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `865 + r * (6 ±0)` // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 271_541_000 picoseconds. - Weight::from_parts(276_996_569, 6807) - // Standard Error: 1_462 - .saturating_add(Weight::from_parts(282_119, 0).saturating_mul(r.into())) + // Minimum execution time: 251_158_000 picoseconds. + Weight::from_parts(274_623_152, 6807) + // Standard Error: 491 + .saturating_add(Weight::from_parts(263_916, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2822,10 +2826,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `869` // Estimated: `6809` - // Minimum execution time: 256_410_000 picoseconds. - Weight::from_parts(206_888_877, 6809) - // Standard Error: 22 - .saturating_add(Weight::from_parts(1_154, 0).saturating_mul(n.into())) + // Minimum execution time: 263_205_000 picoseconds. + Weight::from_parts(216_792_893, 6809) + // Standard Error: 23 + .saturating_add(Weight::from_parts(989, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -2848,10 +2852,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `853 + r * (45 ±0)` // Estimated: `6793 + r * (45 ±0)` - // Minimum execution time: 248_852_000 picoseconds. - Weight::from_parts(277_852_834, 6793) - // Standard Error: 1_257_219 - .saturating_add(Weight::from_parts(1_394_065, 0).saturating_mul(r.into())) + // Minimum execution time: 239_663_000 picoseconds. + Weight::from_parts(266_124_565, 6793) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 45).saturating_mul(r.into())) @@ -2875,10 +2877,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863` // Estimated: `6810` - // Minimum execution time: 269_101_000 picoseconds. - Weight::from_parts(273_407_545, 6810) - // Standard Error: 2 - .saturating_add(Weight::from_parts(339, 0).saturating_mul(n.into())) + // Minimum execution time: 241_763_000 picoseconds. + Weight::from_parts(266_535_552, 6810) + // Standard Error: 0 + .saturating_add(Weight::from_parts(320, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -2907,10 +2909,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2972 + r * (316 ±0)` // Estimated: `8912 + r * (5266 ±0)` - // Minimum execution time: 296_318_000 picoseconds. - Weight::from_parts(322_448_344, 8912) - // Standard Error: 2_358_838 - .saturating_add(Weight::from_parts(107_092_455, 0).saturating_mul(r.into())) + // Minimum execution time: 265_888_000 picoseconds. + Weight::from_parts(291_232_232, 8912) + // Standard Error: 845_475 + .saturating_add(Weight::from_parts(104_398_867, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((7_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2938,10 +2940,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `944 + r * (10 ±0)` // Estimated: `6885 + r * (10 ±0)` - // Minimum execution time: 268_264_000 picoseconds. - Weight::from_parts(285_298_853, 6885) - // Standard Error: 3_238 - .saturating_add(Weight::from_parts(1_238_513, 0).saturating_mul(r.into())) + // Minimum execution time: 248_500_000 picoseconds. + Weight::from_parts(282_353_053, 6885) + // Standard Error: 1_144 + .saturating_add(Weight::from_parts(1_193_841, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -2965,10 +2967,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863 + r * (10 ±0)` // Estimated: `6805 + r * (10 ±0)` - // Minimum execution time: 267_417_000 picoseconds. - Weight::from_parts(290_097_452, 6805) - // Standard Error: 2_523 - .saturating_add(Weight::from_parts(2_012_375, 0).saturating_mul(r.into())) + // Minimum execution time: 248_130_000 picoseconds. + Weight::from_parts(279_583_178, 6805) + // Standard Error: 971 + .saturating_add(Weight::from_parts(1_987_941, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -2993,12 +2995,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `880 + t * (32 ±0)` // Estimated: `6825 + t * (2508 ±0)` - // Minimum execution time: 269_735_000 picoseconds. - Weight::from_parts(291_680_757, 6825) - // Standard Error: 196_822 - .saturating_add(Weight::from_parts(2_827_797, 0).saturating_mul(t.into())) - // Standard Error: 55 - .saturating_add(Weight::from_parts(262, 0).saturating_mul(n.into())) + // Minimum execution time: 258_594_000 picoseconds. + Weight::from_parts(276_734_422, 6825) + // Standard Error: 102_093 + .saturating_add(Weight::from_parts(2_559_383, 0).saturating_mul(t.into())) + // Standard Error: 28 + .saturating_add(Weight::from_parts(501, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3024,10 +3026,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `862 + r * (7 ±0)` // Estimated: `6807 + r * (7 ±0)` - // Minimum execution time: 161_454_000 picoseconds. - Weight::from_parts(181_662_272, 6807) - // Standard Error: 729 - .saturating_add(Weight::from_parts(221_968, 0).saturating_mul(r.into())) + // Minimum execution time: 154_564_000 picoseconds. + Weight::from_parts(168_931_365, 6807) + // Standard Error: 349 + .saturating_add(Weight::from_parts(226_848, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 7).saturating_mul(r.into())) @@ -3051,10 +3053,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `125813` // Estimated: `131755` - // Minimum execution time: 418_479_000 picoseconds. - Weight::from_parts(397_691_558, 131755) + // Minimum execution time: 394_382_000 picoseconds. + Weight::from_parts(376_780_500, 131755) // Standard Error: 12 - .saturating_add(Weight::from_parts(1_099, 0).saturating_mul(i.into())) + .saturating_add(Weight::from_parts(1_026, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3065,10 +3067,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `924 + r * (292 ±0)` // Estimated: `926 + r * (293 ±0)` - // Minimum execution time: 268_810_000 picoseconds. - Weight::from_parts(129_545_478, 926) - // Standard Error: 21_173 - .saturating_add(Weight::from_parts(7_118_874, 0).saturating_mul(r.into())) + // Minimum execution time: 249_757_000 picoseconds. + Weight::from_parts(177_324_374, 926) + // Standard Error: 9_512 + .saturating_add(Weight::from_parts(6_176_717, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3082,10 +3084,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1447` // Estimated: `1430` - // Minimum execution time: 286_965_000 picoseconds. - Weight::from_parts(340_396_510, 1430) - // Standard Error: 90 - .saturating_add(Weight::from_parts(455, 0).saturating_mul(n.into())) + // Minimum execution time: 267_564_000 picoseconds. + Weight::from_parts(328_701_080, 1430) + // Standard Error: 61 + .saturating_add(Weight::from_parts(576, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(8_u64)) } @@ -3096,10 +3098,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1253 + n * (1 ±0)` // Estimated: `1253 + n * (1 ±0)` - // Minimum execution time: 272_395_000 picoseconds. - Weight::from_parts(302_307_069, 1253) - // Standard Error: 94 - .saturating_add(Weight::from_parts(156, 0).saturating_mul(n.into())) + // Minimum execution time: 266_347_000 picoseconds. + Weight::from_parts(289_824_718, 1253) + // Standard Error: 34 + .saturating_add(Weight::from_parts(184, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3111,10 +3113,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `921 + r * (288 ±0)` // Estimated: `927 + r * (289 ±0)` - // Minimum execution time: 269_165_000 picoseconds. - Weight::from_parts(167_174_485, 927) - // Standard Error: 23_564 - .saturating_add(Weight::from_parts(6_921_525, 0).saturating_mul(r.into())) + // Minimum execution time: 247_207_000 picoseconds. + Weight::from_parts(179_856_075, 927) + // Standard Error: 9_383 + .saturating_add(Weight::from_parts(6_053_198, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3128,8 +3130,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1249 + n * (1 ±0)` // Estimated: `1249 + n * (1 ±0)` - // Minimum execution time: 270_248_000 picoseconds. - Weight::from_parts(296_573_310, 1249) + // Minimum execution time: 262_655_000 picoseconds. + Weight::from_parts(289_482_543, 1249) + // Standard Error: 35 + .saturating_add(Weight::from_parts(92, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3141,10 +3145,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `921 + r * (296 ±0)` // Estimated: `923 + r * (297 ±0)` - // Minimum execution time: 270_883_000 picoseconds. - Weight::from_parts(189_792_705, 923) - // Standard Error: 11_149 - .saturating_add(Weight::from_parts(5_232_100, 0).saturating_mul(r.into())) + // Minimum execution time: 247_414_000 picoseconds. + Weight::from_parts(203_317_182, 923) + // Standard Error: 7_191 + .saturating_add(Weight::from_parts(4_925_154, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3157,10 +3161,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1265 + n * (1 ±0)` // Estimated: `1265 + n * (1 ±0)` - // Minimum execution time: 263_833_000 picoseconds. - Weight::from_parts(290_179_222, 1265) - // Standard Error: 44 - .saturating_add(Weight::from_parts(831, 0).saturating_mul(n.into())) + // Minimum execution time: 258_910_000 picoseconds. + Weight::from_parts(283_086_514, 1265) + // Standard Error: 39 + .saturating_add(Weight::from_parts(980, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3172,10 +3176,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `932 + r * (288 ±0)` // Estimated: `929 + r * (289 ±0)` - // Minimum execution time: 252_637_000 picoseconds. - Weight::from_parts(98_108_825, 929) - // Standard Error: 23_580 - .saturating_add(Weight::from_parts(5_408_076, 0).saturating_mul(r.into())) + // Minimum execution time: 252_410_000 picoseconds. + Weight::from_parts(201_227_879, 929) + // Standard Error: 6_899 + .saturating_add(Weight::from_parts(4_774_983, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3188,8 +3192,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1252 + n * (1 ±0)` // Estimated: `1252 + n * (1 ±0)` - // Minimum execution time: 279_133_000 picoseconds. - Weight::from_parts(301_192_115, 1252) + // Minimum execution time: 259_053_000 picoseconds. + Weight::from_parts(283_392_084, 1252) + // Standard Error: 41 + .saturating_add(Weight::from_parts(213, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3201,10 +3207,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `914 + r * (296 ±0)` // Estimated: `919 + r * (297 ±0)` - // Minimum execution time: 268_833_000 picoseconds. - Weight::from_parts(56_229_951, 919) - // Standard Error: 25_800 - .saturating_add(Weight::from_parts(7_607_143, 0).saturating_mul(r.into())) + // Minimum execution time: 251_371_000 picoseconds. + Weight::from_parts(177_119_717, 919) + // Standard Error: 9_421 + .saturating_add(Weight::from_parts(6_226_005, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3218,10 +3224,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1266 + n * (1 ±0)` // Estimated: `1266 + n * (1 ±0)` - // Minimum execution time: 288_677_000 picoseconds. - Weight::from_parts(301_986_360, 1266) - // Standard Error: 39 - .saturating_add(Weight::from_parts(867, 0).saturating_mul(n.into())) + // Minimum execution time: 263_350_000 picoseconds. + Weight::from_parts(284_323_917, 1266) + // Standard Error: 31 + .saturating_add(Weight::from_parts(921, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3245,10 +3251,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1415 + r * (45 ±0)` // Estimated: `7307 + r * (2520 ±0)` - // Minimum execution time: 275_956_000 picoseconds. - Weight::from_parts(280_865_651, 7307) - // Standard Error: 28_235 - .saturating_add(Weight::from_parts(32_233_352, 0).saturating_mul(r.into())) + // Minimum execution time: 248_701_000 picoseconds. + Weight::from_parts(17_811_969, 7307) + // Standard Error: 35_154 + .saturating_add(Weight::from_parts(31_809_738, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) @@ -3274,10 +3280,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1260 + r * (245 ±0)` // Estimated: `9440 + r * (2721 ±0)` - // Minimum execution time: 269_188_000 picoseconds. - Weight::from_parts(276_038_000, 9440) - // Standard Error: 262_029 - .saturating_add(Weight::from_parts(250_766_832, 0).saturating_mul(r.into())) + // Minimum execution time: 247_335_000 picoseconds. + Weight::from_parts(264_025_000, 9440) + // Standard Error: 121_299 + .saturating_add(Weight::from_parts(234_770_827, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) @@ -3303,10 +3309,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0 + r * (576 ±0)` // Estimated: `6812 + r * (2637 ±3)` - // Minimum execution time: 267_543_000 picoseconds. - Weight::from_parts(271_365_000, 6812) - // Standard Error: 190_454 - .saturating_add(Weight::from_parts(242_627_807, 0).saturating_mul(r.into())) + // Minimum execution time: 261_011_000 picoseconds. + Weight::from_parts(264_554_000, 6812) + // Standard Error: 104_415 + .saturating_add(Weight::from_parts(231_627_084, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3333,12 +3339,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1307 + t * (277 ±0)` // Estimated: `12197 + t * (5227 ±0)` - // Minimum execution time: 453_215_000 picoseconds. - Weight::from_parts(32_029_330, 12197) - // Standard Error: 12_154_174 - .saturating_add(Weight::from_parts(392_862_355, 0).saturating_mul(t.into())) + // Minimum execution time: 445_561_000 picoseconds. + Weight::from_parts(62_287_490, 12197) + // Standard Error: 11_797_697 + .saturating_add(Weight::from_parts(357_530_529, 0).saturating_mul(t.into())) // Standard Error: 17 - .saturating_add(Weight::from_parts(1_059, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(970, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(13_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(6_u64)) @@ -3368,10 +3374,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1278 + r * (255 ±0)` // Estimated: `9620 + r * (2731 ±0)` - // Minimum execution time: 635_304_000 picoseconds. - Weight::from_parts(645_872_000, 9620) - // Standard Error: 356_713 - .saturating_add(Weight::from_parts(371_999_658, 0).saturating_mul(r.into())) + // Minimum execution time: 621_897_000 picoseconds. + Weight::from_parts(631_687_000, 9620) + // Standard Error: 215_241 + .saturating_add(Weight::from_parts(350_527_831, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((6_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(7_u64)) @@ -3403,12 +3409,14 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1303 + t * (104 ±0)` // Estimated: `12211 + t * (2549 ±1)` - // Minimum execution time: 2_225_692_000 picoseconds. - Weight::from_parts(1_292_861_603, 12211) - // Standard Error: 24 - .saturating_add(Weight::from_parts(1_075, 0).saturating_mul(i.into())) - // Standard Error: 24 - .saturating_add(Weight::from_parts(1_278, 0).saturating_mul(s.into())) + // Minimum execution time: 2_181_184_000 picoseconds. + Weight::from_parts(1_194_190_111, 12211) + // Standard Error: 11_578_766 + .saturating_add(Weight::from_parts(6_361_884, 0).saturating_mul(t.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(1_025, 0).saturating_mul(i.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(1_158, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(16_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(11_u64)) @@ -3434,10 +3442,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `862 + r * (8 ±0)` // Estimated: `6801 + r * (8 ±0)` - // Minimum execution time: 252_664_000 picoseconds. - Weight::from_parts(277_967_331, 6801) - // Standard Error: 723 - .saturating_add(Weight::from_parts(370_111, 0).saturating_mul(r.into())) + // Minimum execution time: 241_609_000 picoseconds. + Weight::from_parts(268_716_874, 6801) + // Standard Error: 617 + .saturating_add(Weight::from_parts(377_753, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3461,10 +3469,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `870` // Estimated: `6808` - // Minimum execution time: 252_485_000 picoseconds. - Weight::from_parts(259_271_531, 6808) - // Standard Error: 2 - .saturating_add(Weight::from_parts(1_091, 0).saturating_mul(n.into())) + // Minimum execution time: 261_296_000 picoseconds. + Weight::from_parts(255_531_654, 6808) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_081, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3487,10 +3495,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6806 + r * (8 ±0)` - // Minimum execution time: 249_270_000 picoseconds. - Weight::from_parts(272_528_711, 6806) - // Standard Error: 903 - .saturating_add(Weight::from_parts(793_299, 0).saturating_mul(r.into())) + // Minimum execution time: 243_583_000 picoseconds. + Weight::from_parts(270_025_058, 6806) + // Standard Error: 560 + .saturating_add(Weight::from_parts(767_519, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3514,10 +3522,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6814` - // Minimum execution time: 249_470_000 picoseconds. - Weight::from_parts(273_317_815, 6814) - // Standard Error: 4 - .saturating_add(Weight::from_parts(3_400, 0).saturating_mul(n.into())) + // Minimum execution time: 253_798_000 picoseconds. + Weight::from_parts(265_542_351, 6814) + // Standard Error: 0 + .saturating_add(Weight::from_parts(3_343, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3540,10 +3548,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6808 + r * (8 ±0)` - // Minimum execution time: 265_503_000 picoseconds. - Weight::from_parts(279_774_666, 6808) - // Standard Error: 1_351 - .saturating_add(Weight::from_parts(439_734, 0).saturating_mul(r.into())) + // Minimum execution time: 247_332_000 picoseconds. + Weight::from_parts(269_183_656, 6808) + // Standard Error: 665 + .saturating_add(Weight::from_parts(443_386, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3567,10 +3575,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6813` - // Minimum execution time: 265_009_000 picoseconds. - Weight::from_parts(270_467_968, 6813) + // Minimum execution time: 250_855_000 picoseconds. + Weight::from_parts(258_752_975, 6813) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_206, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_202, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3593,10 +3601,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6805 + r * (8 ±0)` - // Minimum execution time: 251_771_000 picoseconds. - Weight::from_parts(283_553_523, 6805) - // Standard Error: 1_053 - .saturating_add(Weight::from_parts(445_715, 0).saturating_mul(r.into())) + // Minimum execution time: 240_733_000 picoseconds. + Weight::from_parts(269_134_358, 6805) + // Standard Error: 512 + .saturating_add(Weight::from_parts(440_043, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3620,10 +3628,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6811` - // Minimum execution time: 253_733_000 picoseconds. - Weight::from_parts(264_277_000, 6811) - // Standard Error: 3 - .saturating_add(Weight::from_parts(1_226, 0).saturating_mul(n.into())) + // Minimum execution time: 247_377_000 picoseconds. + Weight::from_parts(261_077_322, 6811) + // Standard Error: 0 + .saturating_add(Weight::from_parts(1_195, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3646,10 +3654,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `997 + n * (1 ±0)` // Estimated: `6934 + n * (1 ±0)` - // Minimum execution time: 337_326_000 picoseconds. - Weight::from_parts(346_340_758, 6934) - // Standard Error: 18 - .saturating_add(Weight::from_parts(6_110, 0).saturating_mul(n.into())) + // Minimum execution time: 307_337_000 picoseconds. + Weight::from_parts(326_710_473, 6934) + // Standard Error: 9 + .saturating_add(Weight::from_parts(5_765, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3673,10 +3681,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `805 + r * (112 ±0)` // Estimated: `6748 + r * (112 ±0)` - // Minimum execution time: 253_852_000 picoseconds. - Weight::from_parts(335_731_679, 6748) - // Standard Error: 13_615 - .saturating_add(Weight::from_parts(41_557_258, 0).saturating_mul(r.into())) + // Minimum execution time: 245_432_000 picoseconds. + Weight::from_parts(294_206_377, 6748) + // Standard Error: 7_229 + .saturating_add(Weight::from_parts(41_480_485, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(r.into())) @@ -3699,11 +3707,11 @@ impl WeightInfo for () { fn seal_ecdsa_recover(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `907 + r * (76 ±0)` - // Estimated: `6801 + r * (77 ±0)` - // Minimum execution time: 256_283_000 picoseconds. - Weight::from_parts(338_634_113, 6801) - // Standard Error: 43_436 - .saturating_add(Weight::from_parts(46_607_112, 0).saturating_mul(r.into())) + // Estimated: `6802 + r * (77 ±0)` + // Minimum execution time: 247_788_000 picoseconds. + Weight::from_parts(303_940_062, 6802) + // Standard Error: 10_671 + .saturating_add(Weight::from_parts(45_730_772, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 77).saturating_mul(r.into())) @@ -3727,10 +3735,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `877 + r * (42 ±0)` // Estimated: `6816 + r * (42 ±0)` - // Minimum execution time: 269_144_000 picoseconds. - Weight::from_parts(331_790_138, 6816) - // Standard Error: 23_357 - .saturating_add(Weight::from_parts(12_213_638, 0).saturating_mul(r.into())) + // Minimum execution time: 248_825_000 picoseconds. + Weight::from_parts(286_832_225, 6816) + // Standard Error: 5_274 + .saturating_add(Weight::from_parts(11_889_262, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 42).saturating_mul(r.into())) @@ -3753,11 +3761,11 @@ impl WeightInfo for () { fn seal_set_code_hash(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + r * (965 ±0)` - // Estimated: `6807 + r * (3090 ±10)` - // Minimum execution time: 262_624_000 picoseconds. - Weight::from_parts(275_865_000, 6807) - // Standard Error: 64_162 - .saturating_add(Weight::from_parts(26_205_387, 0).saturating_mul(r.into())) + // Estimated: `6807 + r * (3090 ±7)` + // Minimum execution time: 244_982_000 picoseconds. + Weight::from_parts(265_297_000, 6807) + // Standard Error: 39_895 + .saturating_add(Weight::from_parts(22_435_888, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3783,10 +3791,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `928 + r * (131 ±0)` // Estimated: `6878 + r * (2606 ±0)` - // Minimum execution time: 265_482_000 picoseconds. - Weight::from_parts(296_491_925, 6878) - // Standard Error: 46_681 - .saturating_add(Weight::from_parts(6_572_162, 0).saturating_mul(r.into())) + // Minimum execution time: 246_455_000 picoseconds. + Weight::from_parts(275_334_919, 6878) + // Standard Error: 20_911 + .saturating_add(Weight::from_parts(6_427_525, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3812,10 +3820,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `969 + r * (183 ±0)` // Estimated: `129453 + r * (2568 ±0)` - // Minimum execution time: 257_532_000 picoseconds. - Weight::from_parts(299_110_930, 129453) - // Standard Error: 55_003 - .saturating_add(Weight::from_parts(6_130_357, 0).saturating_mul(r.into())) + // Minimum execution time: 254_472_000 picoseconds. + Weight::from_parts(280_657_909, 129453) + // Standard Error: 20_131 + .saturating_add(Weight::from_parts(5_644_006, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3841,10 +3849,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `858 + r * (3 ±0)` // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 268_894_000 picoseconds. - Weight::from_parts(287_048_741, 6804) - // Standard Error: 1_156 - .saturating_add(Weight::from_parts(172_596, 0).saturating_mul(r.into())) + // Minimum execution time: 250_535_000 picoseconds. + Weight::from_parts(270_318_376, 6804) + // Standard Error: 386 + .saturating_add(Weight::from_parts(174_627, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -3868,10 +3876,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2109 + r * (39 ±0)` // Estimated: `7899 + r * (40 ±0)` - // Minimum execution time: 262_736_000 picoseconds. - Weight::from_parts(389_199_672, 7899) - // Standard Error: 2_646 - .saturating_add(Weight::from_parts(290_309, 0).saturating_mul(r.into())) + // Minimum execution time: 248_174_000 picoseconds. + Weight::from_parts(301_826_520, 7899) + // Standard Error: 801 + .saturating_add(Weight::from_parts(248_479, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) @@ -3897,22 +3905,22 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `861 + r * (3 ±0)` // Estimated: `6801 + r * (3 ±0)` - // Minimum execution time: 253_465_000 picoseconds. - Weight::from_parts(283_153_874, 6801) - // Standard Error: 745 - .saturating_add(Weight::from_parts(148_864, 0).saturating_mul(r.into())) + // Minimum execution time: 246_540_000 picoseconds. + Weight::from_parts(268_913_509, 6801) + // Standard Error: 378 + .saturating_add(Weight::from_parts(154_950, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. - fn instr_i64const(r: u32, ) -> Weight { + fn instr_i64_load_store(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_342_000 picoseconds. - Weight::from_parts(1_940_100, 0) - // Standard Error: 21 - .saturating_add(Weight::from_parts(11_117, 0).saturating_mul(r.into())) + // Minimum execution time: 1_777_000 picoseconds. + Weight::from_parts(1_707_601, 0) + // Standard Error: 14 + .saturating_add(Weight::from_parts(15_392, 0).saturating_mul(r.into())) } } -- GitLab From 4fb2a559046b98be1e1b67464cd90442bbe76063 Mon Sep 17 00:00:00 2001 From: Nazar Mokrynskyi Date: Fri, 19 Jan 2024 23:20:18 +0200 Subject: [PATCH 090/392] Make `Slot` and `SlotDuration` transparent (#2999) I have a use case that for safety requires all contained data structures to be `#[repr(C)]` or `#[repr(transparent)]` and it seemed like non-invasive change. --- substrate/primitives/consensus/slots/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/substrate/primitives/consensus/slots/src/lib.rs b/substrate/primitives/consensus/slots/src/lib.rs index b9a032c1bcf..23cb7f7365a 100644 --- a/substrate/primitives/consensus/slots/src/lib.rs +++ b/substrate/primitives/consensus/slots/src/lib.rs @@ -26,6 +26,7 @@ use sp_timestamp::Timestamp; /// Unit type wrapper that represents a slot. #[derive(Debug, Encode, MaxEncodedLen, Decode, Eq, Clone, Copy, Default, Ord, Hash, TypeInfo)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[repr(transparent)] pub struct Slot(u64); impl core::ops::Deref for Slot { @@ -135,6 +136,7 @@ impl From for u64 { Eq, TypeInfo, )] +#[repr(transparent)] pub struct SlotDuration(u64); impl SlotDuration { -- GitLab From f2336d32f274e815ebd80e671492fa5f4107cdb9 Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Fri, 19 Jan 2024 21:54:39 +0100 Subject: [PATCH 091/392] better debugging for accountid32 in debug build (#2990) --- substrate/primitives/core/src/crypto.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/substrate/primitives/core/src/crypto.rs b/substrate/primitives/core/src/crypto.rs index 2da38d44be4..58d8616368e 100644 --- a/substrate/primitives/core/src/crypto.rs +++ b/substrate/primitives/core/src/crypto.rs @@ -593,14 +593,16 @@ impl std::fmt::Display for AccountId32 { } impl sp_std::fmt::Debug for AccountId32 { - #[cfg(feature = "std")] fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - let s = self.to_ss58check(); - write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) - } + #[cfg(feature = "serde")] + { + let s = self.to_ss58check(); + write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8])?; + } + + #[cfg(not(feature = "serde"))] + write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0))?; - #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { Ok(()) } } -- GitLab From 84ff0a974daece89b3c56adb0a5430351bb3d1f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 23:41:55 +0100 Subject: [PATCH 092/392] Bump h2 from 0.3.21 to 0.3.24 (#3004) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [h2](https://github.com/hyperium/h2) from 0.3.21 to 0.3.24.
Release notes

Sourced from h2's releases.

v0.3.24

Fixed

  • Limit error resets for misbehaving connections.

v0.3.23

What's Changed

v0.3.22

What's Changed

  • Add header_table_size(usize) option to client and server builders.
  • Improve throughput when vectored IO is not available.
  • Update indexmap to 2.

New Contributors

Changelog

Sourced from h2's changelog.

0.3.24 (January 17, 2024)

  • Limit error resets for misbehaving connections.

0.3.23 (January 10, 2024)

  • Backport fix from 0.4.1 for stream capacity assignment.

0.3.22 (November 15, 2023)

  • Add header_table_size(usize) option to client and server builders.
  • Improve throughput when vectored IO is not available.
  • Update indexmap to 2.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=h2&package-manager=cargo&previous-version=0.3.21&new-version=0.3.24)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/paritytech/polkadot-sdk/network/alerts).
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 74d87c2afc8..941f16b68eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6225,9 +6225,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ "bytes", "fnv", @@ -6235,7 +6235,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap 2.0.0", "slab", "tokio", "tokio-util", -- GitLab From 3b7a8c75bbad9be07d655890571b659238a29679 Mon Sep 17 00:00:00 2001 From: Doordashcon Date: Sat, 20 Jan 2024 10:51:25 +0100 Subject: [PATCH 093/392] Adding `try_state` hook for Tips pallet (#1871) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Part of https://github.com/paritytech/polkadot-sdk/issues/239. Invariant 1. The number of entries in `Tips` should be equal to `Reasons`. 2. If `OpenTip.finders_fee` is true, then `OpenTip.deposit` should be greater than zero. 3. Reasons exists for each Tip[`OpenTip.reason`], implying equal length of storage. polkadot address: 12zsKEDVcHpKEWb99iFt3xrTCQQXZMu477nJQsTBBrof5k2h --------- Co-authored-by: Gonçalo Pestana Co-authored-by: Oliver Tale-Yazdi --- prdoc/pr_1871.prdoc | 12 +++ substrate/frame/tips/src/lib.rs | 59 ++++++++++++++- substrate/frame/tips/src/tests.rs | 122 ++++++++++++++++++++++++++---- 3 files changed, 178 insertions(+), 15 deletions(-) create mode 100644 prdoc/pr_1871.prdoc diff --git a/prdoc/pr_1871.prdoc b/prdoc/pr_1871.prdoc new file mode 100644 index 00000000000..d1850509afb --- /dev/null +++ b/prdoc/pr_1871.prdoc @@ -0,0 +1,12 @@ +title: Adding `try-state` hook to tips pallet + +doc: + - audience: Runtime User + description: | + Enforces the following invariants; + 1. The number of entries in Tips should be equal to Reasons. + 2. If OpenTip.finders_fee is true, then OpenTip.deposit should be greater than zero. + 3. Reasons exists for each Tip[OpenTip.reason], implying equal length of storage. + +crates: +- name: pallet-tips diff --git a/substrate/frame/tips/src/lib.rs b/substrate/frame/tips/src/lib.rs index 8764486d5f4..4c7cfc3028a 100644 --- a/substrate/frame/tips/src/lib.rs +++ b/substrate/frame/tips/src/lib.rs @@ -68,6 +68,7 @@ use sp_std::prelude::*; use codec::{Decode, Encode}; use frame_support::{ + ensure, traits::{ ContainsLengthBound, Currency, EnsureOrigin, ExistenceRequirement::KeepAlive, Get, OnUnbalanced, ReservableCurrency, SortedMembers, @@ -76,6 +77,9 @@ use frame_support::{ }; use frame_system::pallet_prelude::BlockNumberFor; +#[cfg(any(feature = "try-runtime", test))] +use sp_runtime::TryRuntimeError; + pub use pallet::*; pub use weights::WeightInfo; @@ -150,7 +154,7 @@ pub mod pallet { #[pallet::constant] type TipFindersFee: Get; - /// The amount held on deposit for placing a tip report. + /// The non-zero amount held on deposit for placing a tip report. #[pallet::constant] type TipReportDepositBase: Get>; @@ -465,6 +469,21 @@ pub mod pallet { Ok(()) } } + + #[pallet::hooks] + impl, I: 'static> Hooks> for Pallet { + fn integrity_test() { + assert!( + !T::TipReportDepositBase::get().is_zero(), + "`TipReportDepositBase` should not be zero", + ); + } + + #[cfg(feature = "try-runtime")] + fn try_state(_n: BlockNumberFor) -> Result<(), TryRuntimeError> { + Self::do_try_state() + } + } } impl, I: 'static> Pallet { @@ -611,4 +630,42 @@ impl, I: 'static> Pallet { Tips::::insert(hash, new_tip) } } + + /// Ensure the correctness of the state of this pallet. + /// + /// This should be valid before and after each state transition of this pallet. + /// + /// ## Invariants: + /// 1. The number of entries in `Tips` should be equal to `Reasons`. + /// 2. Reasons exists for each Tip[`OpenTip.reason`]. + /// 3. If `OpenTip.finders_fee` is true, then OpenTip.deposit should be greater than zero. + #[cfg(any(feature = "try-runtime", test))] + pub fn do_try_state() -> Result<(), TryRuntimeError> { + let reasons = Reasons::::iter_keys().collect::>(); + let tips = Tips::::iter_keys().collect::>(); + + ensure!( + reasons.len() == tips.len(), + TryRuntimeError::Other("Equal length of entries in `Tips` and `Reasons` Storage") + ); + + for tip in Tips::::iter_keys() { + let open_tip = Tips::::get(&tip).expect("All map keys are valid; qed"); + + if open_tip.finders_fee { + ensure!( + !open_tip.deposit.is_zero(), + TryRuntimeError::Other( + "Tips with `finders_fee` should have non-zero `deposit`." + ) + ) + } + + ensure!( + reasons.contains(&open_tip.reason), + TryRuntimeError::Other("no reason for this tip") + ); + } + Ok(()) + } } diff --git a/substrate/frame/tips/src/tests.rs b/substrate/frame/tips/src/tests.rs index d5c8e17a396..63ac8e37cdd 100644 --- a/substrate/frame/tips/src/tests.rs +++ b/substrate/frame/tips/src/tests.rs @@ -31,7 +31,7 @@ use frame_support::{ storage::StoragePrefixedMap, traits::{ tokens::{PayFromAccount, UnityAssetBalanceConversion}, - ConstU32, ConstU64, SortedMembers, StorageVersion, + ConstU32, ConstU64, IntegrityTest, SortedMembers, StorageVersion, }, PalletId, }; @@ -189,13 +189,14 @@ impl pallet_treasury::Config for Test { parameter_types! { pub const TipFindersFee: Percent = Percent::from_percent(20); + pub static TipReportDepositBase: u64 = 1; } impl Config for Test { type MaximumReasonLength = ConstU32<16384>; type Tippers = TenToFourteen; type TipCountdown = ConstU64<1>; type TipFindersFee = TipFindersFee; - type TipReportDepositBase = ConstU64<1>; + type TipReportDepositBase = TipReportDepositBase; type DataDepositPerByte = ConstU64<1>; type MaxTipAmount = ConstU64<10_000_000>; type RuntimeEvent = RuntimeEvent; @@ -207,7 +208,7 @@ impl Config for Test { type Tippers = TenToFourteen; type TipCountdown = ConstU64<1>; type TipFindersFee = TipFindersFee; - type TipReportDepositBase = ConstU64<1>; + type TipReportDepositBase = TipReportDepositBase; type DataDepositPerByte = ConstU64<1>; type MaxTipAmount = ConstU64<10_000_000>; type RuntimeEvent = RuntimeEvent; @@ -228,6 +229,14 @@ pub fn new_test_ext() -> sp_io::TestExternalities { ext } +/// Run the function pointer inside externalities and asserts the try_state hook at the end. +pub fn build_and_execute(test: impl FnOnce() -> ()) { + new_test_ext().execute_with(|| { + test(); + Tips::do_try_state().expect("All invariants must hold after a test"); + }); +} + fn last_event() -> TipEvent { System::events() .into_iter() @@ -239,7 +248,7 @@ fn last_event() -> TipEvent { #[test] fn genesis_config_works() { - new_test_ext().execute_with(|| { + build_and_execute(|| { assert_eq!(Treasury::pot(), 0); assert_eq!(Treasury::proposal_count(), 0); }); @@ -251,7 +260,7 @@ fn tip_hash() -> H256 { #[test] fn tip_new_cannot_be_used_twice() { - new_test_ext().execute_with(|| { + build_and_execute(|| { Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Tips::tip_new(RuntimeOrigin::signed(10), b"awesome.dot".to_vec(), 3, 10)); assert_noop!( @@ -263,7 +272,7 @@ fn tip_new_cannot_be_used_twice() { #[test] fn report_awesome_and_tip_works() { - new_test_ext().execute_with(|| { + build_and_execute(|| { Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Tips::report_awesome(RuntimeOrigin::signed(0), b"awesome.dot".to_vec(), 3)); assert_eq!(Balances::reserved_balance(0), 12); @@ -290,7 +299,7 @@ fn report_awesome_and_tip_works() { #[test] fn report_awesome_from_beneficiary_and_tip_works() { - new_test_ext().execute_with(|| { + build_and_execute(|| { Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Tips::report_awesome(RuntimeOrigin::signed(0), b"awesome.dot".to_vec(), 0)); assert_eq!(Balances::reserved_balance(0), 12); @@ -308,7 +317,7 @@ fn report_awesome_from_beneficiary_and_tip_works() { #[test] fn close_tip_works() { - new_test_ext().execute_with(|| { + build_and_execute(|| { System::set_block_number(1); Balances::make_free_balance_be(&Treasury::account_id(), 101); @@ -346,7 +355,7 @@ fn close_tip_works() { #[test] fn slash_tip_works() { - new_test_ext().execute_with(|| { + build_and_execute(|| { System::set_block_number(1); Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_eq!(Treasury::pot(), 100); @@ -377,7 +386,7 @@ fn slash_tip_works() { #[test] fn retract_tip_works() { - new_test_ext().execute_with(|| { + build_and_execute(|| { // with report awesome Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Tips::report_awesome(RuntimeOrigin::signed(0), b"awesome.dot".to_vec(), 3)); @@ -411,7 +420,7 @@ fn retract_tip_works() { #[test] fn tip_median_calculation_works() { - new_test_ext().execute_with(|| { + build_and_execute(|| { Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Tips::tip_new(RuntimeOrigin::signed(10), b"awesome.dot".to_vec(), 3, 0)); let h = tip_hash(); @@ -425,7 +434,7 @@ fn tip_median_calculation_works() { #[test] fn tip_large_should_fail() { - new_test_ext().execute_with(|| { + build_and_execute(|| { Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Tips::tip_new(RuntimeOrigin::signed(10), b"awesome.dot".to_vec(), 3, 0)); let h = tip_hash(); @@ -442,7 +451,7 @@ fn tip_large_should_fail() { #[test] fn tip_changing_works() { - new_test_ext().execute_with(|| { + build_and_execute(|| { Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Tips::tip_new(RuntimeOrigin::signed(10), b"awesome.dot".to_vec(), 3, 10000)); let h = tip_hash(); @@ -627,7 +636,7 @@ fn genesis_funding_works() { #[test] fn report_awesome_and_tip_works_second_instance() { - new_test_ext().execute_with(|| { + build_and_execute(|| { Balances::make_free_balance_be(&Treasury::account_id(), 101); Balances::make_free_balance_be(&Treasury1::account_id(), 201); assert_eq!(Balances::free_balance(&Treasury::account_id()), 101); @@ -657,3 +666,88 @@ fn report_awesome_and_tip_works_second_instance() { assert_eq!(Balances::free_balance(&Treasury1::account_id()), 191); }); } + +#[test] +fn equal_entries_invariant() { + new_test_ext().execute_with(|| { + use frame_support::pallet_prelude::DispatchError::Other; + + Balances::make_free_balance_be(&Treasury::account_id(), 101); + + assert_ok!(Tips::report_awesome(RuntimeOrigin::signed(0), b"awesome.dot".to_vec(), 3)); + + let reason1 = BlakeTwo256::hash(b"reason1"); + let hash1 = BlakeTwo256::hash_of(&(reason1, 10u64)); + + let tip = OpenTip:: { + reason: reason1, + who: 10, + finder: 20, + deposit: 30, + closes: Some(13), + tips: vec![(40, 50), (60, 70)], + finders_fee: true, + }; + + // Breaks invariant by adding an entry to only `Tips` Storage. + pallet_tips::Tips::::insert(hash1, tip); + + // Invariant violated + assert_eq!( + Tips::do_try_state(), + Err(Other("Equal length of entries in `Tips` and `Reasons` Storage")) + ); + }) +} + +#[test] +fn finders_fee_invariant() { + new_test_ext().execute_with(|| { + use frame_support::pallet_prelude::DispatchError::Other; + + // Breaks invariant by having a zero deposit. + TipReportDepositBase::set(0); + + Balances::make_free_balance_be(&Treasury::account_id(), 101); + + assert_ok!(Tips::report_awesome(RuntimeOrigin::signed(0), b"".to_vec(), 3)); + + // Invariant violated + assert_eq!( + Tips::do_try_state(), + Err(Other("Tips with `finders_fee` should have non-zero `deposit`.")) + ); + }) +} + +#[test] +fn reasons_invariant() { + new_test_ext().execute_with(|| { + use frame_support::pallet_prelude::DispatchError::Other; + + Balances::make_free_balance_be(&Treasury::account_id(), 101); + + assert_ok!(Tips::report_awesome(RuntimeOrigin::signed(0), b"awesome.dot".to_vec(), 0)); + + let hash: Vec<_> = pallet_tips::Tips::::iter_keys().collect(); + + let mut open_tip = pallet_tips::Tips::::take(hash[0]).unwrap(); + + // Breaks invariant by changing value `open_tip.reason` in `Tips` Storage. + open_tip.reason = ::Hashing::hash(&b"".to_vec()); + + pallet_tips::Tips::::insert(hash[0], open_tip); + + // Invariant violated + assert_eq!(Tips::do_try_state(), Err(Other("no reason for this tip"))); + }) +} + +#[test] +#[should_panic = "`TipReportDepositBase` should not be zero"] +fn zero_base_deposit_prohibited() { + new_test_ext().execute_with(|| { + TipReportDepositBase::set(0); + Tips::integrity_test(); + }); +} -- GitLab From a5370fb1877cc9672cb47fea36a27cfed3f4da63 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 20 Jan 2024 23:24:48 +1100 Subject: [PATCH 094/392] Bump comfy-table from 7.0.1 to 7.1.0 (#2993) Bumps [comfy-table](https://github.com/nukesor/comfy-table) from 7.0.1 to 7.1.0.
Release notes

Sourced from comfy-table's releases.

v7.1.0

[7.1.0] - 2023-10-21

Added

  • Add helper methods (col,row)_count and is_empty. The first set of methods return the number of columns and rows respectively. The method is_empty returns if the table is empty (contains no data rows). Implemented by Techassi in #119.

Chore

  • Bump crossterm dependency
Changelog

Sourced from comfy-table's changelog.

[7.1.0] - 2023-10-21

Added

  • Add helper methods (col,row)_count and is_empty. The first set of methods return the number of columns and rows respectively. The method is_empty returns if the table is empty (contains no data rows). Implemented by Techassi in #119.

Chore

  • Bump crossterm dependency
Commits
  • ef14a13 chore: Release comfy-table version 7.1.0
  • 3f0563e docs: Update changelog
  • fb636c9 Merge pull request #125 from Nukesor/dependabot/github_actions/actions/checko...
  • f3c9e1d build(deps): bump actions/checkout from 3 to 4
  • ec99e06 Merge pull request #128 from Nukesor/updates
  • 329f4c9 change: Use 1.70 in CI for criterion
  • 1b6d452 bump: Crossterm
  • af3924c chore: Clippy issues
  • aebf4ef Merge pull request #119 from Techassi/feature/row-col-count
  • 9f45a5e Merge pull request #122 from ip1981/ip1981/cell-hash
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=comfy-table&package-manager=cargo&previous-version=7.0.1&new-version=7.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 45 +++++++++++++------ .../utils/frame/benchmarking-cli/Cargo.toml | 2 +- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 941f16b68eb..0a004b3a736 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2883,12 +2883,12 @@ dependencies = [ [[package]] name = "comfy-table" -version = "7.0.1" +version = "7.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ab77dbd8adecaf3f0db40581631b995f312a8a5ae3aa9993188bb8f23d83a5b" +checksum = "7c64043d6c7b7a4c58e39e7efccfdea7b93d885a795d0c054a69dbbf4dd52686" dependencies = [ - "strum", - "strum_macros", + "strum 0.25.0", + "strum_macros 0.25.3", "unicode-width", ] @@ -9826,7 +9826,7 @@ dependencies = [ "sp-runtime", "sp-std 8.0.0", "sp-tracing 10.0.0", - "strum", + "strum 0.24.1", ] [[package]] @@ -12882,7 +12882,7 @@ dependencies = [ "rand_chacha 0.3.1", "sc-authority-discovery", "sc-network", - "strum", + "strum 0.24.1", "thiserror", "tracing-gum", ] @@ -18215,7 +18215,7 @@ dependencies = [ "sp-mmr-primitives", "sp-runtime", "sp-std 8.0.0", - "strum", + "strum 0.24.1", "w3f-bls", ] @@ -18496,7 +18496,7 @@ version = "24.0.0" dependencies = [ "sp-core", "sp-runtime", - "strum", + "strum 0.24.1", ] [[package]] @@ -19038,7 +19038,7 @@ checksum = "08615eea740067d9899969bc2891c68a19c315cb1f66640af9a9ecb91b13bcab" dependencies = [ "lazy_static", "maplit", - "strum", + "strum 0.24.1", ] [[package]] @@ -19406,9 +19406,15 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" dependencies = [ - "strum_macros", + "strum_macros 0.24.3", ] +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" + [[package]] name = "strum_macros" version = "0.24.3" @@ -19422,6 +19428,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.48", +] + [[package]] name = "subkey" version = "3.0.0" @@ -19685,7 +19704,7 @@ dependencies = [ "filetime", "parity-wasm", "sp-maybe-compressed-blob", - "strum", + "strum 0.24.1", "tempfile", "toml 0.8.8", "walkdir", @@ -21132,8 +21151,8 @@ checksum = "fc942673e7684671f0c5708fc18993569d184265fd5223bb51fc8e5b9b6cfd52" dependencies = [ "anyhow", "libc", - "strum", - "strum_macros", + "strum 0.24.1", + "strum_macros 0.24.3", "tempfile", "thiserror", "wasm-opt-cxx-sys", diff --git a/substrate/utils/frame/benchmarking-cli/Cargo.toml b/substrate/utils/frame/benchmarking-cli/Cargo.toml index ba95afeeee9..d6a96abb23f 100644 --- a/substrate/utils/frame/benchmarking-cli/Cargo.toml +++ b/substrate/utils/frame/benchmarking-cli/Cargo.toml @@ -20,7 +20,7 @@ array-bytes = "6.1" chrono = "0.4" clap = { version = "4.4.18", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.6.1" } -comfy-table = { version = "7.0.1", default-features = false } +comfy-table = { version = "7.1.0", default-features = false } handlebars = "4.2.2" Inflector = "0.11.4" itertools = "0.10.3" -- GitLab From caa987d26d14bbdbfbc9be08a1da4c2b117fcaa3 Mon Sep 17 00:00:00 2001 From: Joshy Orndorff Date: Sun, 21 Jan 2024 06:51:04 +0800 Subject: [PATCH 095/392] Adder Parachain: Accept output file argument to `export-genesis-*` subcommands (#2370) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR makes a small change the the adder parachain's CLI. It allows the user to specify an output file explicitly when generating the genesis wasm and head data. Now we no longer have to rely on redirecting the output to a file at the shell level. This change is nice because if you have any debugging lines enabled, shell redirection does not work. More to the point, this makes the adder parachain's CLI match the cumulus collator's CLI. And that will allow tools like Zombienet (that support both cumulus and the adder) to use the positional argument. cc @pepoviola --------- Co-authored-by: Joshy Orndorff Co-authored-by: Bastian Köcher --- .../test-parachains/adder/collator/src/cli.rs | 13 ++++++++-- .../adder/collator/src/main.rs | 26 ++++++++++++++++--- .../undying/collator/src/main.rs | 4 +-- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/polkadot/parachain/test-parachains/adder/collator/src/cli.rs b/polkadot/parachain/test-parachains/adder/collator/src/cli.rs index f81e4cc0fff..5e9b4f584d4 100644 --- a/polkadot/parachain/test-parachains/adder/collator/src/cli.rs +++ b/polkadot/parachain/test-parachains/adder/collator/src/cli.rs @@ -18,6 +18,7 @@ use clap::Parser; use sc_cli::SubstrateCli; +use std::path::PathBuf; /// Sub-commands supported by the collator. #[derive(Debug, Parser)] @@ -33,11 +34,19 @@ pub enum Subcommand { /// Command for exporting the genesis head data of the parachain #[derive(Debug, Parser)] -pub struct ExportGenesisHeadCommand {} +pub struct ExportGenesisHeadCommand { + /// Output file name or stdout if unspecified. + #[arg()] + pub output: Option, +} /// Command for exporting the genesis wasm file. #[derive(Debug, Parser)] -pub struct ExportGenesisWasmCommand {} +pub struct ExportGenesisWasmCommand { + /// Output file name or stdout if unspecified. + #[arg()] + pub output: Option, +} #[allow(missing_docs)] #[derive(Debug, Parser)] diff --git a/polkadot/parachain/test-parachains/adder/collator/src/main.rs b/polkadot/parachain/test-parachains/adder/collator/src/main.rs index 6ce93ef4ad1..5d9384d4956 100644 --- a/polkadot/parachain/test-parachains/adder/collator/src/main.rs +++ b/polkadot/parachain/test-parachains/adder/collator/src/main.rs @@ -22,6 +22,10 @@ use polkadot_node_subsystem::messages::{CollationGenerationMessage, CollatorProt use polkadot_primitives::Id as ParaId; use sc_cli::{Error as SubstrateCliError, SubstrateCli}; use sp_core::hexdisplay::HexDisplay; +use std::{ + fs, + io::{self, Write}, +}; use test_parachain_adder_collator::Collator; /// The parachain ID to collate for in case it wasn't set explicitly through CLI. @@ -34,15 +38,29 @@ fn main() -> Result<()> { let cli = Cli::from_args(); match cli.subcommand { - Some(cli::Subcommand::ExportGenesisState(_params)) => { + Some(cli::Subcommand::ExportGenesisState(params)) => { let collator = Collator::new(); - println!("0x{:?}", HexDisplay::from(&collator.genesis_head())); + let output_buf = + format!("0x{:?}", HexDisplay::from(&collator.genesis_head())).into_bytes(); + + if let Some(output) = params.output { + std::fs::write(output, output_buf)?; + } else { + std::io::stdout().write_all(&output_buf)?; + } Ok::<_, Error>(()) }, - Some(cli::Subcommand::ExportGenesisWasm(_params)) => { + Some(cli::Subcommand::ExportGenesisWasm(params)) => { let collator = Collator::new(); - println!("0x{:?}", HexDisplay::from(&collator.validation_code())); + let output_buf = + format!("0x{:?}", HexDisplay::from(&collator.validation_code())).into_bytes(); + + if let Some(output) = params.output { + fs::write(output, output_buf)?; + } else { + io::stdout().write_all(&output_buf)?; + } Ok(()) }, diff --git a/polkadot/parachain/test-parachains/undying/collator/src/main.rs b/polkadot/parachain/test-parachains/undying/collator/src/main.rs index 4a15cdd697c..d6fb9a04ab3 100644 --- a/polkadot/parachain/test-parachains/undying/collator/src/main.rs +++ b/polkadot/parachain/test-parachains/undying/collator/src/main.rs @@ -54,9 +54,9 @@ fn main() -> Result<()> { Some(cli::Subcommand::ExportGenesisWasm(params)) => { // We pass some dummy values for `pov_size` and `pvf_complexity` as these don't // matter for `wasm` export. + let collator = Collator::default(); let output_buf = - format!("0x{:?}", HexDisplay::from(&Collator::default().validation_code())) - .into_bytes(); + format!("0x{:?}", HexDisplay::from(&collator.validation_code())).into_bytes(); if let Some(output) = params.output { fs::write(output, output_buf)?; -- GitLab From 21ef949b6e36e6962c88597dae708e550917a619 Mon Sep 17 00:00:00 2001 From: jserrat <35823283+Jpserrat@users.noreply.github.com> Date: Sun, 21 Jan 2024 11:15:36 +0000 Subject: [PATCH 096/392] Use clone instead of fork on pvf (#2477) @mrcnski Done the change on the prepare worker, once the prepare worker part is good I'll do the same for the execute worker. This is based on https://github.com/koute/polkavm/blob/11beebd06276ce9b84f335350138479e714f6caf/crates/polkavm/src/sandbox/linux.rs#L711. ## TODO - [x] Add a check for this capability at startup - [x] Add prdoc mentioning the new Secure Validator Mode (optional) requirement. ## Related Closes #2162 --------- Co-authored-by: Marcin S --- Cargo.lock | 14 +- polkadot/node/core/pvf/common/Cargo.toml | 1 + polkadot/node/core/pvf/common/src/execute.rs | 5 +- .../core/pvf/common/src/executor_interface.rs | 13 +- polkadot/node/core/pvf/common/src/lib.rs | 2 + .../node/core/pvf/common/src/worker/mod.rs | 160 ++++++-- .../common/src/worker/security/change_root.rs | 10 +- .../pvf/common/src/worker/security/clone.rs | 93 +++++ .../common/src/worker/security/landlock.rs | 8 +- .../pvf/common/src/worker/security/mod.rs | 6 +- .../pvf/common/src/worker/security/seccomp.rs | 4 +- .../node/core/pvf/execute-worker/Cargo.toml | 4 +- .../node/core/pvf/execute-worker/src/lib.rs | 376 ++++++++++++------ .../node/core/pvf/prepare-worker/Cargo.toml | 3 +- .../node/core/pvf/prepare-worker/src/lib.rs | 286 ++++++++----- polkadot/node/core/pvf/src/host.rs | 2 +- polkadot/node/core/pvf/src/security.rs | 226 ++++++----- polkadot/node/core/pvf/tests/it/main.rs | 3 + polkadot/node/core/pvf/tests/it/process.rs | 16 +- ...477-use-clone-instead-of-fork-on-pvf.prdoc | 22 + 20 files changed, 860 insertions(+), 394 deletions(-) create mode 100644 polkadot/node/core/pvf/common/src/worker/security/clone.rs create mode 100644 prdoc/pr_2477-use-clone-instead-of-fork-on-pvf.prdoc diff --git a/Cargo.lock b/Cargo.lock index 0a004b3a736..73d5acd6f6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9028,16 +9028,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "os_pipe" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ae859aa07428ca9a929b936690f8b12dc5f11dd8c6992a18ca93919f28bc177" -dependencies = [ - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "os_str_bytes" version = "6.5.1" @@ -12744,6 +12734,7 @@ dependencies = [ "futures", "landlock", "libc", + "nix 0.27.1", "parity-scale-codec", "polkadot-parachain-primitives", "polkadot-primitives", @@ -12764,10 +12755,10 @@ dependencies = [ name = "polkadot-node-core-pvf-execute-worker" version = "1.0.0" dependencies = [ + "cfg-if", "cpu-time", "libc", "nix 0.27.1", - "os_pipe", "parity-scale-codec", "polkadot-node-core-pvf-common", "polkadot-parachain-primitives", @@ -12784,7 +12775,6 @@ dependencies = [ "criterion 0.4.0", "libc", "nix 0.27.1", - "os_pipe", "parity-scale-codec", "polkadot-node-core-pvf-common", "polkadot-primitives", diff --git a/polkadot/node/core/pvf/common/Cargo.toml b/polkadot/node/core/pvf/common/Cargo.toml index b4f6ada9dbb..f2ec505e623 100644 --- a/polkadot/node/core/pvf/common/Cargo.toml +++ b/polkadot/node/core/pvf/common/Cargo.toml @@ -33,6 +33,7 @@ sp-tracing = { path = "../../../../../substrate/primitives/tracing" } [target.'cfg(target_os = "linux")'.dependencies] landlock = "0.3.0" +nix = { version = "0.27.1", features = ["sched"] } seccompiler = "0.4.0" [dev-dependencies] diff --git a/polkadot/node/core/pvf/common/src/execute.rs b/polkadot/node/core/pvf/common/src/execute.rs index 5ba5b443e6a..6b3becf524d 100644 --- a/polkadot/node/core/pvf/common/src/execute.rs +++ b/polkadot/node/core/pvf/common/src/execute.rs @@ -92,10 +92,11 @@ pub enum JobError { TimedOut, #[error("An unexpected panic has occurred in the execution job: {0}")] Panic(String), + /// Some error occurred when interfacing with the kernel. + #[error("Error interfacing with the kernel: {0}")] + Kernel(String), #[error("Could not spawn the requested thread: {0}")] CouldNotSpawnThread(String), #[error("An error occurred in the CPU time monitor thread: {0}")] CpuTimeMonitorThread(String), - #[error("Could not set pdeathsig: {0}")] - CouldNotSetPdeathsig(String), } diff --git a/polkadot/node/core/pvf/common/src/executor_interface.rs b/polkadot/node/core/pvf/common/src/executor_interface.rs index e634940dbe6..4cd2f5c85ee 100644 --- a/polkadot/node/core/pvf/common/src/executor_interface.rs +++ b/polkadot/node/core/pvf/common/src/executor_interface.rs @@ -140,7 +140,7 @@ pub unsafe fn create_runtime_from_artifact_bytes( executor_params: &ExecutorParams, ) -> Result { let mut config = DEFAULT_CONFIG.clone(); - config.semantics = params_to_wasmtime_semantics(executor_params); + config.semantics = params_to_wasmtime_semantics(executor_params).0; sc_executor_wasmtime::create_runtime_from_artifact_bytes::( compiled_artifact_blob, @@ -148,7 +148,10 @@ pub unsafe fn create_runtime_from_artifact_bytes( ) } -pub fn params_to_wasmtime_semantics(par: &ExecutorParams) -> Semantics { +/// Takes the default config and overwrites any settings with existing executor parameters. +/// +/// Returns the semantics as well as the stack limit (since we are guaranteed to have it). +pub fn params_to_wasmtime_semantics(par: &ExecutorParams) -> (Semantics, DeterministicStackLimit) { let mut sem = DEFAULT_CONFIG.semantics.clone(); let mut stack_limit = sem .deterministic_stack_limit @@ -169,8 +172,8 @@ pub fn params_to_wasmtime_semantics(par: &ExecutorParams) -> Semantics { ExecutorParam::PvfExecTimeout(_, _) => (), /* Not used here */ } } - sem.deterministic_stack_limit = Some(stack_limit); - sem + sem.deterministic_stack_limit = Some(stack_limit.clone()); + (sem, stack_limit) } /// Runs the prevalidation on the given code. Returns a [`RuntimeBlob`] if it succeeds. @@ -187,7 +190,7 @@ pub fn prepare( blob: RuntimeBlob, executor_params: &ExecutorParams, ) -> Result, sc_executor_common::error::WasmError> { - let semantics = params_to_wasmtime_semantics(executor_params); + let (semantics, _) = params_to_wasmtime_semantics(executor_params); sc_executor_wasmtime::prepare_runtime_artifact(blob, &semantics) } diff --git a/polkadot/node/core/pvf/common/src/lib.rs b/polkadot/node/core/pvf/common/src/lib.rs index af4a7526e55..d891c06bf2a 100644 --- a/polkadot/node/core/pvf/common/src/lib.rs +++ b/polkadot/node/core/pvf/common/src/lib.rs @@ -57,6 +57,8 @@ pub struct SecurityStatus { pub can_enable_seccomp: bool, /// Whether we are able to unshare the user namespace and change the filesystem root. pub can_unshare_user_namespace_and_change_root: bool, + /// Whether we are able to call `clone` with all sandboxing flags. + pub can_do_secure_clone: bool, } /// A handshake with information for the worker. diff --git a/polkadot/node/core/pvf/common/src/worker/mod.rs b/polkadot/node/core/pvf/common/src/worker/mod.rs index 9dcd535d533..d7c95d9e704 100644 --- a/polkadot/node/core/pvf/common/src/worker/mod.rs +++ b/polkadot/node/core/pvf/common/src/worker/mod.rs @@ -18,14 +18,19 @@ pub mod security; -use crate::{framed_recv_blocking, WorkerHandshake, LOG_TARGET}; +use crate::{framed_recv_blocking, SecurityStatus, WorkerHandshake, LOG_TARGET}; use cpu_time::ProcessTime; use futures::never::Never; use parity_scale_codec::Decode; use std::{ any::Any, - fmt, io, - os::unix::net::UnixStream, + fmt::{self}, + fs::File, + io::{self, Read, Write}, + os::{ + fd::{AsRawFd, FromRawFd, RawFd}, + unix::net::UnixStream, + }, path::PathBuf, sync::mpsc::{Receiver, RecvTimeoutError}, time::Duration, @@ -78,7 +83,7 @@ macro_rules! decl_worker_main { "--check-can-enable-landlock" => { #[cfg(target_os = "linux")] - let status = if let Err(err) = security::landlock::check_is_fully_enabled() { + let status = if let Err(err) = security::landlock::check_can_fully_enable() { // Write the error to stderr, log it on the host-side. eprintln!("{}", err); -1 @@ -91,7 +96,7 @@ macro_rules! decl_worker_main { }, "--check-can-enable-seccomp" => { #[cfg(all(target_os = "linux", target_arch = "x86_64"))] - let status = if let Err(err) = security::seccomp::check_is_fully_enabled() { + let status = if let Err(err) = security::seccomp::check_can_fully_enable() { // Write the error to stderr, log it on the host-side. eprintln!("{}", err); -1 @@ -107,7 +112,7 @@ macro_rules! decl_worker_main { let cache_path_tempdir = std::path::Path::new(&args[2]); #[cfg(target_os = "linux")] let status = if let Err(err) = - security::change_root::check_is_fully_enabled(&cache_path_tempdir) + security::change_root::check_can_fully_enable(&cache_path_tempdir) { // Write the error to stderr, log it on the host-side. eprintln!("{}", err); @@ -119,6 +124,21 @@ macro_rules! decl_worker_main { let status = -1; std::process::exit(status) }, + "--check-can-do-secure-clone" => { + #[cfg(target_os = "linux")] + // SAFETY: new process is spawned within a single threaded process. This + // invariant is enforced by tests. + let status = if let Err(err) = unsafe { security::clone::check_can_fully_clone() } { + // Write the error to stderr, log it on the host-side. + eprintln!("{}", err); + -1 + } else { + 0 + }; + #[cfg(not(target_os = "linux"))] + let status = -1; + std::process::exit(status) + }, "test-sleep" => { std::thread::sleep(std::time::Duration::from_secs(5)); @@ -171,6 +191,84 @@ macro_rules! decl_worker_main { }; } +//taken from the os_pipe crate. Copied here to reduce one dependency and +// because its type-safe abstractions do not play well with nix's clone +#[cfg(not(target_os = "macos"))] +pub fn pipe2_cloexec() -> io::Result<(libc::c_int, libc::c_int)> { + let mut fds: [libc::c_int; 2] = [0; 2]; + let res = unsafe { libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC) }; + if res != 0 { + return Err(io::Error::last_os_error()) + } + Ok((fds[0], fds[1])) +} + +#[cfg(target_os = "macos")] +pub fn pipe2_cloexec() -> io::Result<(libc::c_int, libc::c_int)> { + let mut fds: [libc::c_int; 2] = [0; 2]; + let res = unsafe { libc::pipe(fds.as_mut_ptr()) }; + if res != 0 { + return Err(io::Error::last_os_error()) + } + let res = unsafe { libc::fcntl(fds[0], libc::F_SETFD, libc::FD_CLOEXEC) }; + if res != 0 { + return Err(io::Error::last_os_error()) + } + let res = unsafe { libc::fcntl(fds[1], libc::F_SETFD, libc::FD_CLOEXEC) }; + if res != 0 { + return Err(io::Error::last_os_error()) + } + Ok((fds[0], fds[1])) +} + +/// A wrapper around a file descriptor used to encapsulate and restrict +/// functionality for pipe operations. +pub struct PipeFd { + file: File, +} + +impl AsRawFd for PipeFd { + /// Returns the raw file descriptor associated with this `PipeFd` + fn as_raw_fd(&self) -> RawFd { + self.file.as_raw_fd() + } +} + +impl FromRawFd for PipeFd { + /// Creates a new `PipeFd` instance from a raw file descriptor. + /// + /// # Safety + /// + /// The fd passed in must be an owned file descriptor; in particular, it must be open. + unsafe fn from_raw_fd(fd: RawFd) -> Self { + PipeFd { file: File::from_raw_fd(fd) } + } +} + +impl Read for PipeFd { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + self.file.read(buf) + } + + fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { + self.file.read_to_end(buf) + } +} + +impl Write for PipeFd { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.file.write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + self.file.flush() + } + + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + self.file.write_all(buf) + } +} + /// Some allowed overhead that we account for in the "CPU time monitor" thread's sleeps, on the /// child process. pub const JOB_TIMEOUT_OVERHEAD: Duration = Duration::from_millis(50); @@ -192,14 +290,12 @@ impl fmt::Display for WorkerKind { } } -// Some fields are only used for logging, and dead-code analysis ignores Debug. -#[allow(dead_code)] #[derive(Debug)] pub struct WorkerInfo { - pid: u32, - kind: WorkerKind, - version: Option, - worker_dir_path: PathBuf, + pub pid: u32, + pub kind: WorkerKind, + pub version: Option, + pub worker_dir_path: PathBuf, } // NOTE: The worker version must be passed in so that we accurately get the version of the worker, @@ -218,7 +314,7 @@ pub fn run_worker( worker_version: Option<&str>, mut event_loop: F, ) where - F: FnMut(UnixStream, PathBuf) -> io::Result, + F: FnMut(UnixStream, &WorkerInfo, SecurityStatus) -> io::Result, { #[cfg_attr(not(target_os = "linux"), allow(unused_mut))] let mut worker_info = WorkerInfo { @@ -250,11 +346,8 @@ pub fn run_worker( } // Make sure that we can read the worker dir path, and log its contents. - let entries = || -> Result, io::Error> { - std::fs::read_dir(&worker_info.worker_dir_path)? - .map(|res| res.map(|e| e.file_name())) - .collect() - }(); + let entries: io::Result> = std::fs::read_dir(&worker_info.worker_dir_path) + .and_then(|d| d.map(|res| res.map(|e| e.file_name())).collect()); match entries { Ok(entries) => gum::trace!(target: LOG_TARGET, ?worker_info, "content of worker dir: {:?}", entries), @@ -284,6 +377,22 @@ pub fn run_worker( { gum::trace!(target: LOG_TARGET, ?security_status, "Enabling security features"); + // First, make sure env vars were cleared, to match the environment we perform the checks + // within. (In theory, running checks with different env vars could result in different + // outcomes of the checks.) + if !security::check_env_vars_were_cleared(&worker_info) { + let err = "not all env vars were cleared when spawning the process"; + gum::error!( + target: LOG_TARGET, + ?worker_info, + "{}", + err + ); + if security_status.secure_validator_mode { + worker_shutdown(worker_info, err); + } + } + // Call based on whether we can change root. Error out if it should work but fails. // // NOTE: This should not be called in a multi-threaded context (i.e. inside the tokio @@ -337,23 +446,10 @@ pub fn run_worker( } } } - - if !security::check_env_vars_were_cleared(&worker_info) { - let err = "not all env vars were cleared when spawning the process"; - gum::error!( - target: LOG_TARGET, - ?worker_info, - "{}", - err - ); - if security_status.secure_validator_mode { - worker_shutdown(worker_info, err); - } - } } // Run the main worker loop. - let err = event_loop(stream, worker_info.worker_dir_path.clone()) + let err = event_loop(stream, &worker_info, security_status) // It's never `Ok` because it's `Ok(Never)`. .unwrap_err(); diff --git a/polkadot/node/core/pvf/common/src/worker/security/change_root.rs b/polkadot/node/core/pvf/common/src/worker/security/change_root.rs index 375cc8ff6f2..9ec66906819 100644 --- a/polkadot/node/core/pvf/common/src/worker/security/change_root.rs +++ b/polkadot/node/core/pvf/common/src/worker/security/change_root.rs @@ -54,8 +54,7 @@ pub fn enable_for_worker(worker_info: &WorkerInfo) -> Result<()> { /// /// NOTE: This should not be called in a multi-threaded context. `unshare(2)`: /// "CLONE_NEWUSER requires that the calling process is not threaded." -#[cfg(target_os = "linux")] -pub fn check_is_fully_enabled(tempdir: &Path) -> Result<()> { +pub fn check_can_fully_enable(tempdir: &Path) -> Result<()> { let worker_dir_path = tempdir.to_owned(); try_restrict(&WorkerInfo { pid: std::process::id(), @@ -69,7 +68,6 @@ pub fn check_is_fully_enabled(tempdir: &Path) -> Result<()> { /// /// NOTE: This should not be called in a multi-threaded context. `unshare(2)`: /// "CLONE_NEWUSER requires that the calling process is not threaded." -#[cfg(target_os = "linux")] fn try_restrict(worker_info: &WorkerInfo) -> Result<()> { // TODO: Remove this once this is stable: https://github.com/rust-lang/rust/issues/105723 macro_rules! cstr_ptr { @@ -78,12 +76,6 @@ fn try_restrict(worker_info: &WorkerInfo) -> Result<()> { }; } - gum::trace!( - target: LOG_TARGET, - ?worker_info, - "unsharing the user namespace and calling pivot_root", - ); - let worker_dir_path_c = CString::new(worker_info.worker_dir_path.as_os_str().as_bytes()) .expect("on unix; the path will never contain 0 bytes; qed"); diff --git a/polkadot/node/core/pvf/common/src/worker/security/clone.rs b/polkadot/node/core/pvf/common/src/worker/security/clone.rs new file mode 100644 index 00000000000..707f68d1859 --- /dev/null +++ b/polkadot/node/core/pvf/common/src/worker/security/clone.rs @@ -0,0 +1,93 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Functionality for securing the job processes spawned by the workers using `clone`. If +//! unsupported, falls back to `fork`. + +use crate::{worker::WorkerInfo, LOG_TARGET}; +use nix::{ + errno::Errno, + sched::{CloneCb, CloneFlags}, + unistd::Pid, +}; + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error("could not clone, errno: {0}")] + Clone(Errno), +} + +pub type Result = std::result::Result; + +/// Try to run clone(2) on the current worker. +/// +/// SAFETY: new process should be either spawned within a single threaded process, or use only +/// async-signal-safe functions. +pub unsafe fn clone_on_worker( + worker_info: &WorkerInfo, + have_unshare_newuser: bool, + cb: CloneCb, +) -> Result { + let flags = clone_flags(have_unshare_newuser); + + gum::trace!( + target: LOG_TARGET, + ?worker_info, + "calling clone with flags: {:?}", + flags + ); + + try_clone(cb, flags) +} + +/// Runs a check for clone(2) with all sandboxing flags and returns an error indicating whether it +/// can be fully enabled on the current Linux environment. +/// +/// SAFETY: new process should be either spawned within a single threaded process, or use only +/// async-signal-safe functions. +pub unsafe fn check_can_fully_clone() -> Result<()> { + try_clone(Box::new(|| 0), clone_flags(false)).map(|_pid| ()) +} + +/// Runs clone(2) with all sandboxing flags. +/// +/// SAFETY: new process should be either spawned within a single threaded process, or use only +/// async-signal-safe functions. +unsafe fn try_clone(cb: CloneCb, flags: CloneFlags) -> Result { + let mut stack = [0u8; 2 * 1024 * 1024]; + + nix::sched::clone(cb, stack.as_mut_slice(), flags, None).map_err(|errno| Error::Clone(errno)) +} + +/// Returns flags for `clone(2)`, including all the sandbox-related ones. +fn clone_flags(have_unshare_newuser: bool) -> CloneFlags { + // NOTE: CLONE_NEWUSER does not work in `clone` if we previously called `unshare` with this + // flag. On the other hand, if we did not call `unshare` we need this flag for the CAP_SYS_ADMIN + // capability. + let maybe_clone_newuser = + if have_unshare_newuser { CloneFlags::empty() } else { CloneFlags::CLONE_NEWUSER }; + // SIGCHLD flag is used to inform clone that the parent process is + // expecting a child termination signal, without this flag `waitpid` function + // return `ECHILD` error. + maybe_clone_newuser | + CloneFlags::CLONE_NEWCGROUP | + CloneFlags::CLONE_NEWIPC | + CloneFlags::CLONE_NEWNET | + CloneFlags::CLONE_NEWNS | + CloneFlags::CLONE_NEWPID | + CloneFlags::CLONE_NEWUTS | + CloneFlags::from_bits_retain(libc::SIGCHLD) +} diff --git a/polkadot/node/core/pvf/common/src/worker/security/landlock.rs b/polkadot/node/core/pvf/common/src/worker/security/landlock.rs index 211d12c2e44..10d00a0e2c6 100644 --- a/polkadot/node/core/pvf/common/src/worker/security/landlock.rs +++ b/polkadot/node/core/pvf/common/src/worker/security/landlock.rs @@ -112,7 +112,7 @@ pub fn enable_for_worker(worker_info: &WorkerInfo) -> Result<()> { // TODO: /// Runs a check for landlock in its own thread, and returns an error indicating whether the given /// landlock ABI is fully enabled on the current Linux environment. -pub fn check_is_fully_enabled() -> Result<()> { +pub fn check_can_fully_enable() -> Result<()> { match std::thread::spawn(|| try_restrict(std::iter::empty::<(PathBuf, AccessFs)>())).join() { Ok(Ok(())) => Ok(()), Ok(Err(err)) => Err(err), @@ -165,7 +165,7 @@ mod tests { #[test] fn restricted_thread_cannot_read_file() { // TODO: This would be nice: . - if check_is_fully_enabled().is_err() { + if check_can_fully_enable().is_err() { return } @@ -230,7 +230,7 @@ mod tests { #[test] fn restricted_thread_cannot_write_file() { // TODO: This would be nice: . - if check_is_fully_enabled().is_err() { + if check_can_fully_enable().is_err() { return } @@ -289,7 +289,7 @@ mod tests { #[test] fn restricted_thread_can_truncate_file() { // TODO: This would be nice: . - if check_is_fully_enabled().is_err() { + if check_can_fully_enable().is_err() { return } diff --git a/polkadot/node/core/pvf/common/src/worker/security/mod.rs b/polkadot/node/core/pvf/common/src/worker/security/mod.rs index ff4c712f6bd..72d47235d47 100644 --- a/polkadot/node/core/pvf/common/src/worker/security/mod.rs +++ b/polkadot/node/core/pvf/common/src/worker/security/mod.rs @@ -27,15 +27,17 @@ //! - Restrict networking by blocking socket creation and io_uring. //! - Remove env vars -use crate::{worker::WorkerInfo, LOG_TARGET}; - #[cfg(target_os = "linux")] pub mod change_root; #[cfg(target_os = "linux")] +pub mod clone; +#[cfg(target_os = "linux")] pub mod landlock; #[cfg(all(target_os = "linux", target_arch = "x86_64"))] pub mod seccomp; +use crate::{worker::WorkerInfo, LOG_TARGET}; + /// Require env vars to have been removed when spawning the process, to prevent malicious code from /// accessing them. pub fn check_env_vars_were_cleared(worker_info: &WorkerInfo) -> bool { diff --git a/polkadot/node/core/pvf/common/src/worker/security/seccomp.rs b/polkadot/node/core/pvf/common/src/worker/security/seccomp.rs index 4f270f75b34..f6100d236c8 100644 --- a/polkadot/node/core/pvf/common/src/worker/security/seccomp.rs +++ b/polkadot/node/core/pvf/common/src/worker/security/seccomp.rs @@ -110,7 +110,7 @@ pub fn enable_for_worker(worker_info: &WorkerInfo) -> Result<()> { /// Runs a check for seccomp in its own thread, and returns an error indicating whether seccomp with /// our rules is fully enabled on the current Linux environment. -pub fn check_is_fully_enabled() -> Result<()> { +pub fn check_can_fully_enable() -> Result<()> { match std::thread::spawn(|| try_restrict()).join() { Ok(Ok(())) => Ok(()), Ok(Err(err)) => Err(err), @@ -161,7 +161,7 @@ mod tests { #[test] fn sandboxed_thread_cannot_use_sockets() { // TODO: This would be nice: . - if check_is_fully_enabled().is_err() { + if check_can_fully_enable().is_err() { return } diff --git a/polkadot/node/core/pvf/execute-worker/Cargo.toml b/polkadot/node/core/pvf/execute-worker/Cargo.toml index 83118041fdf..a0a987fb439 100644 --- a/polkadot/node/core/pvf/execute-worker/Cargo.toml +++ b/polkadot/node/core/pvf/execute-worker/Cargo.toml @@ -12,8 +12,8 @@ workspace = true [dependencies] cpu-time = "1.0.0" gum = { package = "tracing-gum", path = "../../../gum" } -os_pipe = "1.1.4" -nix = { version = "0.27.1", features = ["process", "resource"] } +cfg-if = "1.0" +nix = { version = "0.27.1", features = ["process", "resource", "sched"] } libc = "0.2.152" parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } diff --git a/polkadot/node/core/pvf/execute-worker/src/lib.rs b/polkadot/node/core/pvf/execute-worker/src/lib.rs index 6980f913d0d..0cfa5a78694 100644 --- a/polkadot/node/core/pvf/execute-worker/src/lib.rs +++ b/polkadot/node/core/pvf/execute-worker/src/lib.rs @@ -16,7 +16,7 @@ //! Contains the logic for executing PVFs. Used by the polkadot-execute-worker binary. -pub use polkadot_node_core_pvf_common::{executor_interface::execute_artifact, worker_dir}; +pub use polkadot_node_core_pvf_common::executor_interface::execute_artifact; // NOTE: Initializing logging in e.g. tests will not have an effect in the workers, as they are // separate spawned processes. Run with e.g. `RUST_LOG=parachain::pvf-execute-worker=trace`. @@ -31,64 +31,41 @@ use nix::{ }, unistd::{ForkResult, Pid}, }; -use os_pipe::{self, PipeReader, PipeWriter}; use parity_scale_codec::{Decode, Encode}; use polkadot_node_core_pvf_common::{ error::InternalValidationError, execute::{Handshake, JobError, JobResponse, JobResult, WorkerResponse}, + executor_interface::params_to_wasmtime_semantics, framed_recv_blocking, framed_send_blocking, worker::{ - cpu_time_monitor_loop, run_worker, stringify_panic_payload, + cpu_time_monitor_loop, pipe2_cloexec, run_worker, stringify_panic_payload, thread::{self, WaitOutcome}, - WorkerKind, + PipeFd, WorkerInfo, WorkerKind, }, + worker_dir, }; use polkadot_parachain_primitives::primitives::ValidationResult; -use polkadot_primitives::{executor_params::DEFAULT_NATIVE_STACK_MAX, ExecutorParams}; +use polkadot_primitives::ExecutorParams; use std::{ io::{self, Read}, - os::unix::net::UnixStream, + os::{ + fd::{AsRawFd, FromRawFd}, + unix::net::UnixStream, + }, path::PathBuf, process, sync::{mpsc::channel, Arc}, time::Duration, }; -// Wasmtime powers the Substrate Executor. It compiles the wasm bytecode into native code. -// That native code does not create any stacks and just reuses the stack of the thread that -// wasmtime was invoked from. -// -// Also, we configure the executor to provide the deterministic stack and that requires -// supplying the amount of the native stack space that wasm is allowed to use. This is -// realized by supplying the limit into `wasmtime::Config::max_wasm_stack`. -// -// There are quirks to that configuration knob: -// -// 1. It only limits the amount of stack space consumed by wasm but does not ensure nor check that -// the stack space is actually available. -// -// That means, if the calling thread has 1 MiB of stack space left and the wasm code consumes -// more, then the wasmtime limit will **not** trigger. Instead, the wasm code will hit the -// guard page and the Rust stack overflow handler will be triggered. That leads to an -// **abort**. -// -// 2. It cannot and does not limit the stack space consumed by Rust code. -// -// Meaning that if the wasm code leaves no stack space for Rust code, then the Rust code -// will abort and that will abort the process as well. -// -// Typically on Linux the main thread gets the stack size specified by the `ulimit` and -// typically it's configured to 8 MiB. Rust's spawned threads are 2 MiB. OTOH, the -// DEFAULT_NATIVE_STACK_MAX is set to 256 MiB. Not nearly enough. -// -// Hence we need to increase it. The simplest way to fix that is to spawn a thread with the desired -// stack limit. -// -// The reasoning why we pick this particular size is: -// -// The default Rust thread stack limit 2 MiB + 256 MiB wasm stack. -/// The stack size for the execute thread. -pub const EXECUTE_THREAD_STACK_SIZE: usize = 2 * 1024 * 1024 + DEFAULT_NATIVE_STACK_MAX as usize; +/// The number of threads for the child process: +/// 1 - Main thread +/// 2 - Cpu monitor thread +/// 3 - Execute thread +/// +/// NOTE: The correctness of this value is enforced by a test. If the number of threads inside +/// the child process changes in the future, this value must be changed as well. +pub const EXECUTE_WORKER_THREAD_NUMBER: u32 = 3; /// Receives a handshake with information specific to the execute worker. fn recv_execute_handshake(stream: &mut UnixStream) -> io::Result { @@ -145,17 +122,20 @@ pub fn worker_entrypoint( worker_dir_path, node_version, worker_version, - |mut stream, worker_dir_path| { - let worker_pid = process::id(); - let artifact_path = worker_dir::execute_artifact(&worker_dir_path); + |mut stream, worker_info, security_status| { + let artifact_path = worker_dir::execute_artifact(&worker_info.worker_dir_path); let Handshake { executor_params } = recv_execute_handshake(&mut stream)?; + let executor_params: Arc = Arc::new(executor_params); + let execute_thread_stack_size = max_stack_size(&executor_params); + loop { let (params, execution_timeout) = recv_request(&mut stream)?; gum::debug!( target: LOG_TARGET, - %worker_pid, + ?worker_info, + ?security_status, "worker: validating artifact {}", artifact_path.display(), ); @@ -172,7 +152,7 @@ pub fn worker_entrypoint( }, }; - let (pipe_reader, pipe_writer) = os_pipe::pipe()?; + let (pipe_read_fd, pipe_write_fd) = pipe2_cloexec()?; let usage_before = match nix::sys::resource::getrusage(UsageWho::RUSAGE_CHILDREN) { Ok(usage) => usage, @@ -182,44 +162,65 @@ pub fn worker_entrypoint( continue }, }; - - // SAFETY: new process is spawned within a single threaded process. This invariant - // is enforced by tests. - let response = match unsafe { nix::unistd::fork() } { - Err(errno) => internal_error_from_errno("fork", errno), - Ok(ForkResult::Child) => { - // Dropping the stream closes the underlying socket. We want to make sure - // that the sandboxed child can't get any kind of information from the - // outside world. The only IPC it should be able to do is sending its - // response over the pipe. - drop(stream); - // Drop the read end so we don't have too many FDs open. - drop(pipe_reader); - - handle_child_process( - pipe_writer, - compiled_artifact_blob, - executor_params, - params, + let stream_fd = stream.as_raw_fd(); + + let compiled_artifact_blob = Arc::new(compiled_artifact_blob); + let params = Arc::new(params); + + cfg_if::cfg_if! { + if #[cfg(target_os = "linux")] { + let result = if security_status.can_do_secure_clone { + handle_clone( + pipe_write_fd, + pipe_read_fd, + stream_fd, + &compiled_artifact_blob, + &executor_params, + ¶ms, + execution_timeout, + execute_thread_stack_size, + worker_info, + security_status.can_unshare_user_namespace_and_change_root, + usage_before, + )? + } else { + // Fall back to using fork. + handle_fork( + pipe_write_fd, + pipe_read_fd, + stream_fd, + &compiled_artifact_blob, + &executor_params, + ¶ms, + execution_timeout, + execute_thread_stack_size, + worker_info, + usage_before, + )? + }; + } else { + let result = handle_fork( + pipe_write_fd, + pipe_read_fd, + stream_fd, + &compiled_artifact_blob, + &executor_params, + ¶ms, execution_timeout, - ) - }, - Ok(ForkResult::Parent { child }) => { - // the read end will wait until all write ends have been closed, - // this drop is necessary to avoid deadlock - drop(pipe_writer); - - handle_parent_process( - pipe_reader, - child, - worker_pid, + execute_thread_stack_size, + worker_info, usage_before, - execution_timeout, - )? - }, - }; + )?; + } + } - send_response(&mut stream, response)?; + gum::trace!( + target: LOG_TARGET, + ?worker_info, + "worker: sending result to host: {:?}", + result + ); + send_response(&mut stream, result)?; } }, ); @@ -252,39 +253,122 @@ fn validate_using_artifact( JobResponse::Ok { result_descriptor } } +#[cfg(target_os = "linux")] +fn handle_clone( + pipe_write_fd: i32, + pipe_read_fd: i32, + stream_fd: i32, + compiled_artifact_blob: &Arc>, + executor_params: &Arc, + params: &Arc>, + execution_timeout: Duration, + execute_stack_size: usize, + worker_info: &WorkerInfo, + have_unshare_newuser: bool, + usage_before: Usage, +) -> io::Result { + use polkadot_node_core_pvf_common::worker::security; + + // SAFETY: new process is spawned within a single threaded process. This invariant + // is enforced by tests. Stack size being specified to ensure child doesn't overflow + match unsafe { + security::clone::clone_on_worker( + worker_info, + have_unshare_newuser, + Box::new(|| { + handle_child_process( + pipe_write_fd, + pipe_read_fd, + stream_fd, + Arc::clone(compiled_artifact_blob), + Arc::clone(executor_params), + Arc::clone(params), + execution_timeout, + execute_stack_size, + ) + }), + ) + } { + Ok(child) => handle_parent_process( + pipe_read_fd, + pipe_write_fd, + worker_info, + child, + usage_before, + execution_timeout, + ), + Err(security::clone::Error::Clone(errno)) => Ok(internal_error_from_errno("clone", errno)), + } +} + +fn handle_fork( + pipe_write_fd: i32, + pipe_read_fd: i32, + stream_fd: i32, + compiled_artifact_blob: &Arc>, + executor_params: &Arc, + params: &Arc>, + execution_timeout: Duration, + execute_worker_stack_size: usize, + worker_info: &WorkerInfo, + usage_before: Usage, +) -> io::Result { + // SAFETY: new process is spawned within a single threaded process. This invariant + // is enforced by tests. + match unsafe { nix::unistd::fork() } { + Ok(ForkResult::Child) => handle_child_process( + pipe_write_fd, + pipe_read_fd, + stream_fd, + Arc::clone(compiled_artifact_blob), + Arc::clone(executor_params), + Arc::clone(params), + execution_timeout, + execute_worker_stack_size, + ), + Ok(ForkResult::Parent { child }) => handle_parent_process( + pipe_read_fd, + pipe_write_fd, + worker_info, + child, + usage_before, + execution_timeout, + ), + Err(errno) => Ok(internal_error_from_errno("fork", errno)), + } +} + /// This is used to handle child process during pvf execute worker. -/// It execute the artifact and pipes back the response to the parent process -/// -/// # Arguments -/// -/// - `pipe_write`: A `PipeWriter` structure, the writing end of a pipe. -/// -/// - `compiled_artifact_blob`: The artifact bytes from compiled by the prepare worker`. -/// -/// - `executor_params`: Deterministically serialized execution environment semantics. -/// -/// - `params`: Validation parameters. -/// -/// - `execution_timeout`: The timeout in `Duration`. +/// It executes the artifact and pipes back the response to the parent process. /// /// # Returns /// /// - pipe back `JobResponse` to the parent process. fn handle_child_process( - mut pipe_write: PipeWriter, - compiled_artifact_blob: Vec, - executor_params: ExecutorParams, - params: Vec, + pipe_write_fd: i32, + pipe_read_fd: i32, + stream_fd: i32, + compiled_artifact_blob: Arc>, + executor_params: Arc, + params: Arc>, execution_timeout: Duration, + execute_thread_stack_size: usize, ) -> ! { - // Terminate if the parent thread dies. Parent thread == worker process (it is single-threaded). - // - // RACE: the worker may die before we install the death signal. In practice this is unlikely, - // and most of the time the job process should terminate on its own when it completes. - #[cfg(target_os = "linux")] - nix::sys::prctl::set_pdeathsig(nix::sys::signal::Signal::SIGTERM).unwrap_or_else(|err| { - send_child_response(&mut pipe_write, Err(JobError::CouldNotSetPdeathsig(err.to_string()))) - }); + // SAFETY: this is an open and owned file descriptor at this point. + let mut pipe_write = unsafe { PipeFd::from_raw_fd(pipe_write_fd) }; + + // Drop the read end so we don't have too many FDs open. + if let Err(errno) = nix::unistd::close(pipe_read_fd) { + send_child_response(&mut pipe_write, job_error_from_errno("closing pipe", errno)); + } + + // Dropping the stream closes the underlying socket. We want to make sure + // that the sandboxed child can't get any kind of information from the + // outside world. The only IPC it should be able to do is sending its + // response over the pipe. + if let Err(errno) = nix::unistd::close(stream_fd) { + send_child_response(&mut pipe_write, job_error_from_errno("closing stream", errno)); + } gum::debug!( target: LOG_TARGET, @@ -308,13 +392,12 @@ fn handle_child_process( send_child_response(&mut pipe_write, Err(JobError::CouldNotSpawnThread(err.to_string()))) }); - let executor_params_2 = executor_params.clone(); let execute_thread = thread::spawn_worker_thread_with_stack_size( "execute thread", - move || validate_using_artifact(&compiled_artifact_blob, &executor_params_2, ¶ms), + move || validate_using_artifact(&compiled_artifact_blob, &executor_params, ¶ms), Arc::clone(&condvar), WaitOutcome::Finished, - EXECUTE_THREAD_STACK_SIZE, + execute_thread_stack_size, ) .unwrap_or_else(|err| { send_child_response(&mut pipe_write, Err(JobError::CouldNotSpawnThread(err.to_string()))) @@ -343,28 +426,69 @@ fn handle_child_process( send_child_response(&mut pipe_write, response); } -/// Waits for child process to finish and handle child response from pipe. +/// Returns stack size based on the number of threads. +/// The stack size is represented by 2MiB * number_of_threads + native stack; /// -/// # Arguments +/// # Background /// -/// - `pipe_read`: A `PipeReader` used to read data from the child process. +/// Wasmtime powers the Substrate Executor. It compiles the wasm bytecode into native code. +/// That native code does not create any stacks and just reuses the stack of the thread that +/// wasmtime was invoked from. /// -/// - `child`: The child pid. +/// Also, we configure the executor to provide the deterministic stack and that requires +/// supplying the amount of the native stack space that wasm is allowed to use. This is +/// realized by supplying the limit into `wasmtime::Config::max_wasm_stack`. /// -/// - `usage_before`: Resource usage statistics before executing the child process. +/// There are quirks to that configuration knob: /// -/// - `timeout`: The maximum allowed time for the child process to finish, in `Duration`. +/// 1. It only limits the amount of stack space consumed by wasm but does not ensure nor check that +/// the stack space is actually available. +/// +/// That means, if the calling thread has 1 MiB of stack space left and the wasm code consumes +/// more, then the wasmtime limit will **not** trigger. Instead, the wasm code will hit the +/// guard page and the Rust stack overflow handler will be triggered. That leads to an +/// **abort**. +/// +/// 2. It cannot and does not limit the stack space consumed by Rust code. +/// +/// Meaning that if the wasm code leaves no stack space for Rust code, then the Rust code +/// will abort and that will abort the process as well. +/// +/// Typically on Linux the main thread gets the stack size specified by the `ulimit` and +/// typically it's configured to 8 MiB. Rust's spawned threads are 2 MiB. OTOH, the +/// DEFAULT_NATIVE_STACK_MAX is set to 256 MiB. Not nearly enough. +/// +/// Hence we need to increase it. The simplest way to fix that is to spawn an execute thread with +/// the desired stack limit. We must also make sure the job process has enough stack for *all* its +/// threads. This function can be used to get the stack size of either the execute thread or execute +/// job process. +fn max_stack_size(executor_params: &ExecutorParams) -> usize { + let (_sem, deterministic_stack_limit) = params_to_wasmtime_semantics(executor_params); + return (2 * 1024 * 1024 + deterministic_stack_limit.native_stack_max) as usize; +} + +/// Waits for child process to finish and handle child response from pipe. /// /// # Returns /// /// - The response, either `Ok` or some error state. fn handle_parent_process( - mut pipe_read: PipeReader, + pipe_read_fd: i32, + pipe_write_fd: i32, + worker_info: &WorkerInfo, job_pid: Pid, - worker_pid: u32, usage_before: Usage, timeout: Duration, ) -> io::Result { + // the read end will wait until all write ends have been closed, + // this drop is necessary to avoid deadlock + if let Err(errno) = nix::unistd::close(pipe_write_fd) { + return Ok(internal_error_from_errno("closing pipe write fd", errno)); + }; + + // SAFETY: pipe_read_fd is an open and owned file descriptor at this point. + let mut pipe_read = unsafe { PipeFd::from_raw_fd(pipe_read_fd) }; + // Read from the child. Don't decode unless the process exited normally, which we check later. let mut received_data = Vec::new(); pipe_read @@ -376,7 +500,7 @@ fn handle_parent_process( let status = nix::sys::wait::waitpid(job_pid, None); gum::trace!( target: LOG_TARGET, - %worker_pid, + ?worker_info, %job_pid, "execute worker received wait status from job: {:?}", status, @@ -396,7 +520,7 @@ fn handle_parent_process( if cpu_tv >= timeout { gum::warn!( target: LOG_TARGET, - %worker_pid, + ?worker_info, %job_pid, "execute job took {}ms cpu time, exceeded execute timeout {}ms", cpu_tv.as_millis(), @@ -429,7 +553,7 @@ fn handle_parent_process( Err(job_error) => { gum::warn!( target: LOG_TARGET, - %worker_pid, + ?worker_info, %job_pid, "execute job error: {}", job_error, @@ -490,14 +614,14 @@ fn recv_child_response(received_data: &mut io::BufReader<&[u8]>) -> io::Result ! { +/// - `response`: Child process response +fn send_child_response(pipe_write: &mut PipeFd, response: JobResult) -> ! { framed_send_blocking(pipe_write, response.encode().as_slice()) .unwrap_or_else(|_| process::exit(libc::EXIT_FAILURE)); @@ -516,3 +640,7 @@ fn internal_error_from_errno(context: &'static str, errno: Errno) -> WorkerRespo io::Error::last_os_error() ))) } + +fn job_error_from_errno(context: &'static str, errno: Errno) -> JobResult { + Err(JobError::Kernel(format!("{}: {}: {}", context, errno, io::Error::last_os_error()))) +} diff --git a/polkadot/node/core/pvf/prepare-worker/Cargo.toml b/polkadot/node/core/pvf/prepare-worker/Cargo.toml index 2ef3dfc0e74..7ed7d329506 100644 --- a/polkadot/node/core/pvf/prepare-worker/Cargo.toml +++ b/polkadot/node/core/pvf/prepare-worker/Cargo.toml @@ -18,8 +18,7 @@ rayon = "1.5.1" tracking-allocator = { package = "staging-tracking-allocator", path = "../../../tracking-allocator" } tikv-jemalloc-ctl = { version = "0.5.0", optional = true } tikv-jemallocator = { version = "0.5.0", optional = true } -os_pipe = "1.1.4" -nix = { version = "0.27.1", features = ["process", "resource"] } +nix = { version = "0.27.1", features = ["process", "resource", "sched"] } parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } diff --git a/polkadot/node/core/pvf/prepare-worker/src/lib.rs b/polkadot/node/core/pvf/prepare-worker/src/lib.rs index f77eed871ec..82a56107ef5 100644 --- a/polkadot/node/core/pvf/prepare-worker/src/lib.rs +++ b/polkadot/node/core/pvf/prepare-worker/src/lib.rs @@ -18,8 +18,6 @@ mod memory_stats; -use polkadot_node_core_pvf_common::executor_interface::{prepare, prevalidate}; - // NOTE: Initializing logging in e.g. tests will not have an effect in the workers, as they are // separate spawned processes. Run with e.g. `RUST_LOG=parachain::pvf-prepare-worker=trace`. const LOG_TARGET: &str = "parachain::pvf-prepare-worker"; @@ -37,7 +35,11 @@ use nix::{ }, unistd::{ForkResult, Pid}, }; -use os_pipe::{self, PipeReader, PipeWriter}; +use polkadot_node_core_pvf_common::{ + executor_interface::{prepare, prevalidate}, + worker::{pipe2_cloexec, PipeFd, WorkerInfo}, +}; + use parity_scale_codec::{Decode, Encode}; use polkadot_node_core_pvf_common::{ error::{PrepareError, PrepareWorkerResult}, @@ -57,10 +59,10 @@ use std::{ fs, io::{self, Read}, os::{ - fd::{AsRawFd, RawFd}, + fd::{AsRawFd, FromRawFd, RawFd}, unix::net::UnixStream, }, - path::PathBuf, + path::{Path, PathBuf}, process, sync::{mpsc::channel, Arc}, time::Duration, @@ -76,6 +78,16 @@ static ALLOC: TrackingAllocator = #[global_allocator] static ALLOC: TrackingAllocator = TrackingAllocator(std::alloc::System); +/// The number of threads for the child process: +/// 1 - Main thread +/// 2 - Cpu monitor thread +/// 3 - Memory tracker thread +/// 4 - Prepare thread +/// +/// NOTE: The correctness of this value is enforced by a test. If the number of threads inside +/// the child process changes in the future, this value must be changed as well. +pub const PREPARE_WORKER_THREAD_NUMBER: u32 = 4; + /// Contains the bytes for a successfully compiled artifact. #[derive(Encode, Decode)] pub struct CompiledArtifact(Vec); @@ -200,15 +212,15 @@ pub fn worker_entrypoint( worker_dir_path, node_version, worker_version, - |mut stream, worker_dir_path| { - let worker_pid = process::id(); - let temp_artifact_dest = worker_dir::prepare_tmp_artifact(&worker_dir_path); + |mut stream, worker_info, security_status| { + let temp_artifact_dest = worker_dir::prepare_tmp_artifact(&worker_info.worker_dir_path); loop { let pvf = recv_request(&mut stream)?; gum::debug!( target: LOG_TARGET, - %worker_pid, + ?worker_info, + ?security_status, "worker: preparing artifact", ); @@ -216,7 +228,7 @@ pub fn worker_entrypoint( let prepare_job_kind = pvf.prep_kind(); let executor_params = pvf.executor_params(); - let (pipe_reader, pipe_writer) = os_pipe::pipe()?; + let (pipe_read_fd, pipe_write_fd) = pipe2_cloexec()?; let usage_before = match nix::sys::resource::getrusage(UsageWho::RUSAGE_CHILDREN) { Ok(usage) => usage, @@ -227,46 +239,58 @@ pub fn worker_entrypoint( }, }; - // SAFETY: new process is spawned within a single threaded process. This invariant - // is enforced by tests. - let result = match unsafe { nix::unistd::fork() } { - Err(errno) => Err(error_from_errno("fork", errno)), - Ok(ForkResult::Child) => { - // Dropping the stream closes the underlying socket. We want to make sure - // that the sandboxed child can't get any kind of information from the - // outside world. The only IPC it should be able to do is sending its - // response over the pipe. - drop(stream); - // Drop the read end so we don't have too many FDs open. - drop(pipe_reader); - - handle_child_process( - pvf, - pipe_writer, + let stream_fd = stream.as_raw_fd(); + + cfg_if::cfg_if! { + if #[cfg(target_os = "linux")] { + let result = if security_status.can_do_secure_clone { + handle_clone( + &pvf, + pipe_write_fd, + pipe_read_fd, + stream_fd, + preparation_timeout, + prepare_job_kind, + &executor_params, + worker_info, + security_status.can_unshare_user_namespace_and_change_root, + &temp_artifact_dest, + usage_before, + ) + } else { + // Fall back to using fork. + handle_fork( + &pvf, + pipe_write_fd, + pipe_read_fd, + stream_fd, + preparation_timeout, + prepare_job_kind, + &executor_params, + worker_info, + &temp_artifact_dest, + usage_before, + ) + }; + } else { + let result = handle_fork( + &pvf, + pipe_write_fd, + pipe_read_fd, + stream_fd, preparation_timeout, prepare_job_kind, - executor_params, - ) - }, - Ok(ForkResult::Parent { child }) => { - // the read end will wait until all write ends have been closed, - // this drop is necessary to avoid deadlock - drop(pipe_writer); - - handle_parent_process( - pipe_reader, - worker_pid, - child, - temp_artifact_dest.clone(), + &executor_params, + worker_info, + &temp_artifact_dest, usage_before, - preparation_timeout, - ) - }, - }; + ); + } + } gum::trace!( target: LOG_TARGET, - %worker_pid, + ?worker_info, "worker: sending result to host: {:?}", result ); @@ -306,21 +330,94 @@ struct JobResponse { memory_stats: MemoryStats, } +#[cfg(target_os = "linux")] +fn handle_clone( + pvf: &PvfPrepData, + pipe_write_fd: i32, + pipe_read_fd: i32, + stream_fd: i32, + preparation_timeout: Duration, + prepare_job_kind: PrepareJobKind, + executor_params: &Arc, + worker_info: &WorkerInfo, + have_unshare_newuser: bool, + temp_artifact_dest: &Path, + usage_before: Usage, +) -> Result { + use polkadot_node_core_pvf_common::worker::security; + + // SAFETY: new process is spawned within a single threaded process. This invariant + // is enforced by tests. Stack size being specified to ensure child doesn't overflow + match unsafe { + security::clone::clone_on_worker( + worker_info, + have_unshare_newuser, + Box::new(|| { + handle_child_process( + pvf.clone(), + pipe_write_fd, + pipe_read_fd, + stream_fd, + preparation_timeout, + prepare_job_kind, + Arc::clone(&executor_params), + ) + }), + ) + } { + Ok(child) => handle_parent_process( + pipe_read_fd, + pipe_write_fd, + worker_info, + child, + temp_artifact_dest, + usage_before, + preparation_timeout, + ), + Err(security::clone::Error::Clone(errno)) => Err(error_from_errno("clone", errno)), + } +} + +fn handle_fork( + pvf: &PvfPrepData, + pipe_write_fd: i32, + pipe_read_fd: i32, + stream_fd: i32, + preparation_timeout: Duration, + prepare_job_kind: PrepareJobKind, + executor_params: &Arc, + worker_info: &WorkerInfo, + temp_artifact_dest: &Path, + usage_before: Usage, +) -> Result { + // SAFETY: new process is spawned within a single threaded process. This invariant + // is enforced by tests. + match unsafe { nix::unistd::fork() } { + Ok(ForkResult::Child) => handle_child_process( + pvf.clone(), + pipe_write_fd, + pipe_read_fd, + stream_fd, + preparation_timeout, + prepare_job_kind, + Arc::clone(executor_params), + ), + Ok(ForkResult::Parent { child }) => handle_parent_process( + pipe_read_fd, + pipe_write_fd, + worker_info, + child, + temp_artifact_dest, + usage_before, + preparation_timeout, + ), + Err(errno) => Err(error_from_errno("fork", errno)), + } +} + /// This is used to handle child process during pvf prepare worker. /// It prepares the artifact and tracks memory stats during preparation -/// and pipes back the response to the parent process -/// -/// # Arguments -/// -/// - `pvf`: `PvfPrepData` structure, containing data to prepare the artifact -/// -/// - `pipe_write`: A `PipeWriter` structure, the writing end of a pipe. -/// -/// - `preparation_timeout`: The timeout in `Duration`. -/// -/// - `prepare_job_kind`: The kind of prepare job. -/// -/// - `executor_params`: Deterministically serialized execution environment semantics. +/// and pipes back the response to the parent process. /// /// # Returns /// @@ -329,19 +426,34 @@ struct JobResponse { /// - If success, pipe back `JobResponse`. fn handle_child_process( pvf: PvfPrepData, - mut pipe_write: PipeWriter, + pipe_write_fd: i32, + pipe_read_fd: i32, + stream_fd: i32, preparation_timeout: Duration, prepare_job_kind: PrepareJobKind, executor_params: Arc, ) -> ! { - // Terminate if the parent thread dies. Parent thread == worker process (it is single-threaded). - // - // RACE: the worker may die before we install the death signal. In practice this is unlikely, - // and most of the time the job process should terminate on its own when it completes. - #[cfg(target_os = "linux")] - nix::sys::prctl::set_pdeathsig(nix::sys::signal::Signal::SIGTERM).unwrap_or_else(|err| { - send_child_response(&mut pipe_write, Err(PrepareError::IoErr(err.to_string()))) - }); + // SAFETY: pipe_writer is an open and owned file descriptor at this point. + let mut pipe_write = unsafe { PipeFd::from_raw_fd(pipe_write_fd) }; + + // Drop the read end so we don't have too many FDs open. + if let Err(errno) = nix::unistd::close(pipe_read_fd) { + send_child_response( + &mut pipe_write, + JobResult::Err(error_from_errno("closing pipe", errno)), + ); + } + + // Dropping the stream closes the underlying socket. We want to make sure + // that the sandboxed child can't get any kind of information from the + // outside world. The only IPC it should be able to do is sending its + // response over the pipe. + if let Err(errno) = nix::unistd::close(stream_fd) { + send_child_response( + &mut pipe_write, + JobResult::Err(error_from_errno("error closing stream", errno)), + ); + } let worker_job_pid = process::id(); gum::debug!( @@ -489,20 +601,6 @@ fn handle_child_process( /// Waits for child process to finish and handle child response from pipe. /// -/// # Arguments -/// -/// - `pipe_read`: A `PipeReader` used to read data from the child process. -/// -/// - `child`: The child pid. -/// -/// - `temp_artifact_dest`: The destination `PathBuf` to write the temporary artifact file. -/// -/// - `worker_pid`: The PID of the child process. -/// -/// - `usage_before`: Resource usage statistics before executing the child process. -/// -/// - `timeout`: The maximum allowed time for the child process to finish, in `Duration`. -/// /// # Returns /// /// - If the child send response without an error, this function returns `Ok(PrepareStats)` @@ -512,13 +610,23 @@ fn handle_child_process( /// /// - If the child process timeout, it returns `PrepareError::TimedOut`. fn handle_parent_process( - mut pipe_read: PipeReader, - worker_pid: u32, + pipe_read_fd: i32, + pipe_write_fd: i32, + worker_info: &WorkerInfo, job_pid: Pid, - temp_artifact_dest: PathBuf, + temp_artifact_dest: &Path, usage_before: Usage, timeout: Duration, ) -> Result { + // the read end will wait until all write ends have been closed, + // this drop is necessary to avoid deadlock + if let Err(errno) = nix::unistd::close(pipe_write_fd) { + return Err(error_from_errno("closing pipe write fd", errno)); + }; + + // SAFETY: this is an open and owned file descriptor at this point. + let mut pipe_read = unsafe { PipeFd::from_raw_fd(pipe_read_fd) }; + // Read from the child. Don't decode unless the process exited normally, which we check later. let mut received_data = Vec::new(); pipe_read @@ -528,7 +636,7 @@ fn handle_parent_process( let status = nix::sys::wait::waitpid(job_pid, None); gum::trace!( target: LOG_TARGET, - %worker_pid, + ?worker_info, %job_pid, "prepare worker received wait status from job: {:?}", status, @@ -546,7 +654,7 @@ fn handle_parent_process( if cpu_tv >= timeout { gum::warn!( target: LOG_TARGET, - %worker_pid, + ?worker_info, %job_pid, "prepare job took {}ms cpu time, exceeded prepare timeout {}ms", cpu_tv.as_millis(), @@ -581,13 +689,13 @@ fn handle_parent_process( // success. gum::debug!( target: LOG_TARGET, - %worker_pid, + ?worker_info, %job_pid, "worker: writing artifact to {}", temp_artifact_dest.display(), ); // Write to the temp file created by the host. - if let Err(err) = fs::write(&temp_artifact_dest, &artifact) { + if let Err(err) = fs::write(temp_artifact_dest, &artifact) { return Err(PrepareError::IoErr(err.to_string())) }; @@ -651,10 +759,10 @@ fn recv_child_response(received_data: &mut io::BufReader<&[u8]>) -> io::Result ! { +fn send_child_response(pipe_write: &mut PipeFd, response: JobResult) -> ! { framed_send_blocking(pipe_write, response.encode().as_slice()) .unwrap_or_else(|_| process::exit(libc::EXIT_FAILURE)); diff --git a/polkadot/node/core/pvf/src/host.rs b/polkadot/node/core/pvf/src/host.rs index 2668ce41583..b07b3da4c26 100644 --- a/polkadot/node/core/pvf/src/host.rs +++ b/polkadot/node/core/pvf/src/host.rs @@ -906,7 +906,7 @@ pub(crate) mod tests { let _ = pulse.next().await.unwrap(); let el = start.elapsed().as_millis(); - assert!(el > 50 && el < 150, "{}", el); + assert!(el > 50 && el < 150, "pulse duration: {}", el); } } diff --git a/polkadot/node/core/pvf/src/security.rs b/polkadot/node/core/pvf/src/security.rs index 9d0d4cf49af..f62a232abf2 100644 --- a/polkadot/node/core/pvf/src/security.rs +++ b/polkadot/node/core/pvf/src/security.rs @@ -32,14 +32,20 @@ use std::{fmt, path::Path}; pub async fn check_security_status(config: &Config) -> Result { let Config { prepare_worker_program_path, secure_validator_mode, cache_path, .. } = config; - let (landlock, seccomp, change_root) = join!( + let (landlock, seccomp, change_root, secure_clone) = join!( check_landlock(prepare_worker_program_path), check_seccomp(prepare_worker_program_path), - check_can_unshare_user_namespace_and_change_root(prepare_worker_program_path, cache_path) + check_can_unshare_user_namespace_and_change_root(prepare_worker_program_path, cache_path), + check_can_do_secure_clone(prepare_worker_program_path), ); - let full_security_status = - FullSecurityStatus::new(*secure_validator_mode, landlock, seccomp, change_root); + let full_security_status = FullSecurityStatus::new( + *secure_validator_mode, + landlock, + seccomp, + change_root, + secure_clone, + ); let security_status = full_security_status.as_partial(); if full_security_status.err_occurred() { @@ -73,6 +79,7 @@ impl FullSecurityStatus { landlock: SecureModeResult, seccomp: SecureModeResult, change_root: SecureModeResult, + secure_clone: SecureModeResult, ) -> Self { Self { partial: SecurityStatus { @@ -80,8 +87,9 @@ impl FullSecurityStatus { can_enable_landlock: landlock.is_ok(), can_enable_seccomp: seccomp.is_ok(), can_unshare_user_namespace_and_change_root: change_root.is_ok(), + can_do_secure_clone: secure_clone.is_ok(), }, - errs: [landlock, seccomp, change_root] + errs: [landlock, seccomp, change_root, secure_clone] .into_iter() .filter_map(|result| result.err()) .collect(), @@ -120,9 +128,10 @@ type SecureModeResult = std::result::Result<(), SecureModeError>; /// Errors related to enabling Secure Validator Mode. #[derive(Debug)] enum SecureModeError { - CannotEnableLandlock(String), + CannotEnableLandlock { err: String, abi: u8 }, CannotEnableSeccomp(String), CannotUnshareUserNamespaceAndChangeRoot(String), + CannotDoSecureClone(String), } impl SecureModeError { @@ -132,12 +141,16 @@ impl SecureModeError { match self { // Landlock is present on relatively recent Linuxes. This is optional if the unshare // capability is present, providing FS sandboxing a different way. - CannotEnableLandlock(_) => security_status.can_unshare_user_namespace_and_change_root, + CannotEnableLandlock { .. } => + security_status.can_unshare_user_namespace_and_change_root, // seccomp should be present on all modern Linuxes unless it's been disabled. CannotEnableSeccomp(_) => false, // Should always be present on modern Linuxes. If not, Landlock also provides FS // sandboxing, so don't enforce this. CannotUnshareUserNamespaceAndChangeRoot(_) => security_status.can_enable_landlock, + // We have not determined the kernel requirements for this capability, and it's also not + // necessary for FS or networking restrictions. + CannotDoSecureClone(_) => true, } } } @@ -146,9 +159,10 @@ impl fmt::Display for SecureModeError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use SecureModeError::*; match self { - CannotEnableLandlock(err) => write!(f, "Cannot enable landlock, a Linux 5.13+ kernel security feature: {err}"), + CannotEnableLandlock{err, abi} => write!(f, "Cannot enable landlock (ABI {abi}), a Linux 5.13+ kernel security feature: {err}"), CannotEnableSeccomp(err) => write!(f, "Cannot enable seccomp, a Linux-specific kernel security feature: {err}"), CannotUnshareUserNamespaceAndChangeRoot(err) => write!(f, "Cannot unshare user namespace and change root, which are Linux-specific kernel security features: {err}"), + CannotDoSecureClone(err) => write!(f, "Cannot call clone with all sandboxing flags, a Linux-specific kernel security features: {err}"), } } } @@ -208,32 +222,11 @@ async fn check_can_unshare_user_namespace_and_change_root( .map_err(|err| SecureModeError::CannotUnshareUserNamespaceAndChangeRoot( format!("could not create a temporary directory in {:?}: {}", cache_path, err) ))?; - match tokio::process::Command::new(prepare_worker_program_path) - .arg("--check-can-unshare-user-namespace-and-change-root") - .arg(cache_dir_tempdir.path()) - .output() - .await - { - Ok(output) if output.status.success() => Ok(()), - Ok(output) => { - let stderr = std::str::from_utf8(&output.stderr) - .expect("child process writes a UTF-8 string to stderr; qed") - .trim(); - if stderr.is_empty() { - Err(SecureModeError::CannotUnshareUserNamespaceAndChangeRoot( - "not available".into() - )) - } else { - Err(SecureModeError::CannotUnshareUserNamespaceAndChangeRoot( - format!("not available: {}", stderr) - )) - } - }, - Err(err) => - Err(SecureModeError::CannotUnshareUserNamespaceAndChangeRoot( - format!("could not start child process: {}", err) - )), - } + spawn_process_for_security_check( + prepare_worker_program_path, + "--check-can-unshare-user-namespace-and-change-root", + &[cache_dir_tempdir.path()], + ).await.map_err(|err| SecureModeError::CannotUnshareUserNamespaceAndChangeRoot(err)) } else { Err(SecureModeError::CannotUnshareUserNamespaceAndChangeRoot( "only available on Linux".into() @@ -253,37 +246,17 @@ async fn check_landlock( ) -> SecureModeResult { cfg_if::cfg_if! { if #[cfg(target_os = "linux")] { - match tokio::process::Command::new(prepare_worker_program_path) - .arg("--check-can-enable-landlock") - .output() - .await - { - Ok(output) if output.status.success() => Ok(()), - Ok(output) => { - let abi = - polkadot_node_core_pvf_common::worker::security::landlock::LANDLOCK_ABI as u8; - let stderr = std::str::from_utf8(&output.stderr) - .expect("child process writes a UTF-8 string to stderr; qed") - .trim(); - if stderr.is_empty() { - Err(SecureModeError::CannotEnableLandlock( - format!("landlock ABI {} not available", abi) - )) - } else { - Err(SecureModeError::CannotEnableLandlock( - format!("not available: {}", stderr) - )) - } - }, - Err(err) => - Err(SecureModeError::CannotEnableLandlock( - format!("could not start child process: {}", err) - )), - } + let abi = polkadot_node_core_pvf_common::worker::security::landlock::LANDLOCK_ABI as u8; + spawn_process_for_security_check( + prepare_worker_program_path, + "--check-can-enable-landlock", + std::iter::empty::<&str>(), + ).await.map_err(|err| SecureModeError::CannotEnableLandlock { err, abi }) } else { - Err(SecureModeError::CannotEnableLandlock( - "only available on Linux".into() - )) + Err(SecureModeError::CannotEnableLandlock { + err: "only available on Linux".into(), + abi: 0, + }) } } } @@ -301,31 +274,11 @@ async fn check_seccomp( if #[cfg(target_os = "linux")] { cfg_if::cfg_if! { if #[cfg(target_arch = "x86_64")] { - match tokio::process::Command::new(prepare_worker_program_path) - .arg("--check-can-enable-seccomp") - .output() - .await - { - Ok(output) if output.status.success() => Ok(()), - Ok(output) => { - let stderr = std::str::from_utf8(&output.stderr) - .expect("child process writes a UTF-8 string to stderr; qed") - .trim(); - if stderr.is_empty() { - Err(SecureModeError::CannotEnableSeccomp( - "not available".into() - )) - } else { - Err(SecureModeError::CannotEnableSeccomp( - format!("not available: {}", stderr) - )) - } - }, - Err(err) => - Err(SecureModeError::CannotEnableSeccomp( - format!("could not start child process: {}", err) - )), - } + spawn_process_for_security_check( + prepare_worker_program_path, + "--check-can-enable-seccomp", + std::iter::empty::<&str>(), + ).await.map_err(|err| SecureModeError::CannotEnableSeccomp(err)) } else { Err(SecureModeError::CannotEnableSeccomp( "only supported on CPUs from the x86_64 family (usually Intel or AMD)".into() @@ -348,24 +301,85 @@ async fn check_seccomp( } } +/// Check if we can call `clone` with all sandboxing flags, and return an error if not. +/// +/// We do this check by spawning a new process and trying to sandbox it. To get as close as possible +/// to running the check in a worker, we try it... in a worker. The expected return status is 0 on +/// success and -1 on failure. +async fn check_can_do_secure_clone( + #[cfg_attr(not(target_os = "linux"), allow(unused_variables))] + prepare_worker_program_path: &Path, +) -> SecureModeResult { + cfg_if::cfg_if! { + if #[cfg(target_os = "linux")] { + spawn_process_for_security_check( + prepare_worker_program_path, + "--check-can-do-secure-clone", + std::iter::empty::<&str>(), + ).await.map_err(|err| SecureModeError::CannotDoSecureClone(err)) + } else { + Err(SecureModeError::CannotDoSecureClone( + "only available on Linux".into() + )) + } + } +} + +#[cfg(target_os = "linux")] +async fn spawn_process_for_security_check( + prepare_worker_program_path: &Path, + check_arg: &'static str, + extra_args: I, +) -> Result<(), String> +where + I: IntoIterator, + S: AsRef, +{ + let mut command = tokio::process::Command::new(prepare_worker_program_path); + // Clear env vars. (In theory, running checks with different env vars could result in different + // outcomes of the checks.) + command.env_clear(); + // Add back any env vars we want to keep. + if let Ok(value) = std::env::var("RUST_LOG") { + command.env("RUST_LOG", value); + } + + match command.arg(check_arg).args(extra_args).output().await { + Ok(output) if output.status.success() => Ok(()), + Ok(output) => { + let stderr = std::str::from_utf8(&output.stderr) + .expect("child process writes a UTF-8 string to stderr; qed") + .trim(); + if stderr.is_empty() { + Err("not available".into()) + } else { + Err(format!("not available: {}", stderr)) + } + }, + Err(err) => Err(format!("could not start child process: {}", err)), + } +} + #[cfg(test)] mod tests { use super::*; #[test] fn test_secure_mode_error_optionality() { - let err = SecureModeError::CannotEnableLandlock(String::new()); + let err = SecureModeError::CannotEnableLandlock { err: String::new(), abi: 3 }; assert!(err.is_allowed_in_secure_mode(&SecurityStatus { secure_validator_mode: true, can_enable_landlock: false, can_enable_seccomp: false, - can_unshare_user_namespace_and_change_root: true + can_unshare_user_namespace_and_change_root: true, + can_do_secure_clone: true, })); assert!(!err.is_allowed_in_secure_mode(&SecurityStatus { secure_validator_mode: true, can_enable_landlock: false, can_enable_seccomp: true, - can_unshare_user_namespace_and_change_root: false + can_unshare_user_namespace_and_change_root: false, + can_do_secure_clone: false, })); let err = SecureModeError::CannotEnableSeccomp(String::new()); @@ -373,13 +387,15 @@ mod tests { secure_validator_mode: true, can_enable_landlock: false, can_enable_seccomp: false, - can_unshare_user_namespace_and_change_root: true + can_unshare_user_namespace_and_change_root: true, + can_do_secure_clone: true, })); assert!(!err.is_allowed_in_secure_mode(&SecurityStatus { secure_validator_mode: true, can_enable_landlock: false, can_enable_seccomp: true, - can_unshare_user_namespace_and_change_root: false + can_unshare_user_namespace_and_change_root: false, + can_do_secure_clone: false, })); let err = SecureModeError::CannotUnshareUserNamespaceAndChangeRoot(String::new()); @@ -387,13 +403,31 @@ mod tests { secure_validator_mode: true, can_enable_landlock: true, can_enable_seccomp: false, - can_unshare_user_namespace_and_change_root: false + can_unshare_user_namespace_and_change_root: false, + can_do_secure_clone: false, })); assert!(!err.is_allowed_in_secure_mode(&SecurityStatus { secure_validator_mode: true, can_enable_landlock: false, can_enable_seccomp: true, - can_unshare_user_namespace_and_change_root: false + can_unshare_user_namespace_and_change_root: false, + can_do_secure_clone: false, + })); + + let err = SecureModeError::CannotDoSecureClone(String::new()); + assert!(err.is_allowed_in_secure_mode(&SecurityStatus { + secure_validator_mode: true, + can_enable_landlock: true, + can_enable_seccomp: true, + can_unshare_user_namespace_and_change_root: true, + can_do_secure_clone: true, + })); + assert!(err.is_allowed_in_secure_mode(&SecurityStatus { + secure_validator_mode: false, + can_enable_landlock: false, + can_enable_seccomp: false, + can_unshare_user_namespace_and_change_root: false, + can_do_secure_clone: false, })); } } diff --git a/polkadot/node/core/pvf/tests/it/main.rs b/polkadot/node/core/pvf/tests/it/main.rs index 15b341dc094..bcc10749e74 100644 --- a/polkadot/node/core/pvf/tests/it/main.rs +++ b/polkadot/node/core/pvf/tests/it/main.rs @@ -457,10 +457,13 @@ async fn all_security_features_work() { assert_eq!( host.security_status().await, SecurityStatus { + // Disabled in tests to not enforce the presence of security features. This CI-only test + // is the only one that tests them. secure_validator_mode: false, can_enable_landlock, can_enable_seccomp: true, can_unshare_user_namespace_and_change_root: true, + can_do_secure_clone: true, } ); } diff --git a/polkadot/node/core/pvf/tests/it/process.rs b/polkadot/node/core/pvf/tests/it/process.rs index 3ea03339a83..e989eb874ba 100644 --- a/polkadot/node/core/pvf/tests/it/process.rs +++ b/polkadot/node/core/pvf/tests/it/process.rs @@ -94,7 +94,7 @@ fn find_process_by_sid_and_name( found } -/// Sets up the test and makes sure everything gets cleaned up after. +/// Sets up the test. /// /// We run the runtime manually because `#[tokio::test]` doesn't work in `rusty_fork_test!`. fn test_wrapper(f: F) @@ -112,14 +112,6 @@ where // Pass a clone of the host so that it does not get dropped after. f(host.clone(), sid).await; - - // Sleep to give processes a chance to get cleaned up, preventing races in the next step. - tokio::time::sleep(Duration::from_millis(500)).await; - - // Make sure job processes got cleaned up. Pass `is_direct_child: false` to target the - // job processes. - assert!(find_process_by_sid_and_name(sid, PREPARE_PROCESS_NAME, false).is_none()); - assert!(find_process_by_sid_and_name(sid, EXECUTE_PROCESS_NAME, false).is_none()); }); } @@ -127,7 +119,7 @@ where // then finding the child process that matches the session ID and expected process name and doing // something with that child. rusty_fork_test! { - // Everything succeeded. All created subprocesses for jobs should get cleaned up, to avoid memory leaks. + // Everything succeeds. #[test] fn successful_prepare_and_validate() { test_wrapper(|host, _sid| async move { @@ -331,7 +323,7 @@ rusty_fork_test! { // monitor, and memory tracking. assert_eq!( get_num_threads_by_sid_and_name(sid, PREPARE_PROCESS_NAME, false), - 4 + polkadot_node_core_pvf_prepare_worker::PREPARE_WORKER_THREAD_NUMBER as i64, ); // End the test. @@ -374,7 +366,7 @@ rusty_fork_test! { // time monitor. assert_eq!( get_num_threads_by_sid_and_name(sid, EXECUTE_PROCESS_NAME, false), - 3 + polkadot_node_core_pvf_execute_worker::EXECUTE_WORKER_THREAD_NUMBER as i64, ); // End the test. diff --git a/prdoc/pr_2477-use-clone-instead-of-fork-on-pvf.prdoc b/prdoc/pr_2477-use-clone-instead-of-fork-on-pvf.prdoc new file mode 100644 index 00000000000..ac9a0a501b6 --- /dev/null +++ b/prdoc/pr_2477-use-clone-instead-of-fork-on-pvf.prdoc @@ -0,0 +1,22 @@ +title: "Use clone instead of fork on pvf" + +doc: + - audience: Node Operator + description: | + For validators: Adds a new, optional security capability. + Most modern Linux machines should support it, otherwise you will get a warning like: + "- Optional: Cannot call clone with all sandboxing flags, a Linux-specific kernel security features: not available" + If you are already running in a secure environment such as a container, this may conflict with our security features; your only option may be to ignore the warning. + Otherwise, it is recommended to upgrade your Linux version! + +migrations: + db: [] + + runtime: [] + +crates: + - name: polkadot-node-core-pvf + - name: polkadot-node-core-pvf-prepare-worker + - name: polkadot-node-core-pvf-execute-worker + +host_functions: [] -- GitLab From d37a45650e112d3ddcc705ef5f642ba075b14e61 Mon Sep 17 00:00:00 2001 From: s0me0ne-unkn0wn <48632512+s0me0ne-unkn0wn@users.noreply.github.com> Date: Sun, 21 Jan 2024 14:56:44 +0100 Subject: [PATCH 097/392] Make candidate validation bounded again (#2125) This PR aims to channel the backpressure of the PVF host's preparation and execution queues to the candidate validation subsystem consumers. Related: #708 --- Cargo.lock | 12 +- .../Cargo.toml | 2 +- .../node/core/candidate-validation/src/lib.rs | 221 ++++++++++-------- polkadot/node/core/pvf/src/host.rs | 5 +- polkadot/node/core/pvf/src/lib.rs | 5 +- polkadot/node/malus/src/interceptor.rs | 21 +- polkadot/node/metrics/Cargo.toml | 2 +- polkadot/node/overseer/Cargo.toml | 4 +- polkadot/node/subsystem-bench/Cargo.toml | 2 +- .../node/subsystem-test-helpers/src/lib.rs | 24 ++ polkadot/node/subsystem-types/Cargo.toml | 2 +- polkadot/node/subsystem-util/Cargo.toml | 2 +- prdoc/pr_2125.prdoc | 14 ++ 13 files changed, 201 insertions(+), 115 deletions(-) create mode 100644 prdoc/pr_2125.prdoc diff --git a/Cargo.lock b/Cargo.lock index 73d5acd6f6d..1d404a2c231 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8988,9 +8988,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "orchestra" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46d78e1deb2a8d54fc1f063a544130db4da31dfe4d5d3b493186424910222a76" +checksum = "5edee0c1917703f8a28cd229cf6a5c91a7ee34be139ced16509ac5b53b9d0c51" dependencies = [ "async-trait", "dyn-clonable", @@ -9005,9 +9005,9 @@ dependencies = [ [[package]] name = "orchestra-proc-macro" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d035b1f968d91a826f2e34a9d6d02cb2af5aa7ca39ebd27922d850ab4b2dd2c6" +checksum = "4f60e64a3808b5bb2786b9da09fc70714952aabcdd0eeba6f1718e3dbc34ad5b" dependencies = [ "expander 2.0.0", "indexmap 2.0.0", @@ -14018,9 +14018,9 @@ dependencies = [ [[package]] name = "prioritized-metered-channel" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e99f0c89bd88f393aab44a4ab949351f7bc7e7e1179d11ecbfe50cbe4c47e342" +checksum = "a172e6cc603231f2cf004232eabcecccc0da53ba576ab286ef7baa0cfc7927ad" dependencies = [ "coarsetime", "crossbeam-queue", diff --git a/cumulus/client/relay-chain-inprocess-interface/Cargo.toml b/cumulus/client/relay-chain-inprocess-interface/Cargo.toml index 63f4c915474..7c7edc502d4 100644 --- a/cumulus/client/relay-chain-inprocess-interface/Cargo.toml +++ b/cumulus/client/relay-chain-inprocess-interface/Cargo.toml @@ -42,7 +42,7 @@ sp-keyring = { path = "../../../substrate/primitives/keyring" } # Polkadot polkadot-primitives = { path = "../../../polkadot/primitives" } polkadot-test-client = { path = "../../../polkadot/node/test/client" } -metered = { package = "prioritized-metered-channel", version = "0.5.1", default-features = false, features = ["futures_channel"] } +metered = { package = "prioritized-metered-channel", version = "0.6.1", default-features = false, features = ["futures_channel"] } # Cumulus cumulus-test-service = { path = "../../test/service" } diff --git a/polkadot/node/core/candidate-validation/src/lib.rs b/polkadot/node/core/candidate-validation/src/lib.rs index 18c27968915..bf6e09fd1b6 100644 --- a/polkadot/node/core/candidate-validation/src/lib.rs +++ b/polkadot/node/core/candidate-validation/src/lib.rs @@ -55,10 +55,11 @@ use polkadot_primitives::{ use parity_scale_codec::Encode; -use futures::{channel::oneshot, prelude::*}; +use futures::{channel::oneshot, prelude::*, stream::FuturesUnordered}; use std::{ path::PathBuf, + pin::Pin, sync::Arc, time::{Duration, Instant}, }; @@ -81,6 +82,11 @@ const PVF_APPROVAL_EXECUTION_RETRY_DELAY: Duration = Duration::from_secs(3); #[cfg(test)] const PVF_APPROVAL_EXECUTION_RETRY_DELAY: Duration = Duration::from_millis(200); +// The task queue size is chosen to be somewhat bigger than the PVF host incoming queue size +// to allow exhaustive validation messages to fall through in case the tasks are clogged with +// `ValidateFromChainState` messages awaiting data from the runtime +const TASK_LIMIT: usize = 30; + /// Configuration for the candidate validation subsystem #[derive(Clone)] pub struct Config { @@ -130,6 +136,83 @@ impl CandidateValidationSubsystem { } } +fn handle_validation_message( + mut sender: S, + validation_host: ValidationHost, + metrics: Metrics, + msg: CandidateValidationMessage, +) -> Pin + Send>> +where + S: SubsystemSender, +{ + match msg { + CandidateValidationMessage::ValidateFromChainState { + candidate_receipt, + pov, + executor_params, + exec_kind, + response_sender, + .. + } => async move { + let _timer = metrics.time_validate_from_chain_state(); + let res = validate_from_chain_state( + &mut sender, + validation_host, + candidate_receipt, + pov, + executor_params, + exec_kind, + &metrics, + ) + .await; + + metrics.on_validation_event(&res); + let _ = response_sender.send(res); + } + .boxed(), + CandidateValidationMessage::ValidateFromExhaustive { + validation_data, + validation_code, + candidate_receipt, + pov, + executor_params, + exec_kind, + response_sender, + .. + } => async move { + let _timer = metrics.time_validate_from_exhaustive(); + let res = validate_candidate_exhaustive( + validation_host, + validation_data, + validation_code, + candidate_receipt, + pov, + executor_params, + exec_kind, + &metrics, + ) + .await; + + metrics.on_validation_event(&res); + let _ = response_sender.send(res); + } + .boxed(), + CandidateValidationMessage::PreCheck { + relay_parent, + validation_code_hash, + response_sender, + .. + } => async move { + let precheck_result = + precheck_pvf(&mut sender, validation_host, relay_parent, validation_code_hash) + .await; + + let _ = response_sender.send(precheck_result); + } + .boxed(), + } +} + #[overseer::contextbounds(CandidateValidation, prefix = self::overseer)] async fn run( mut ctx: Context, @@ -156,106 +239,48 @@ async fn run( .await?; ctx.spawn_blocking("pvf-validation-host", task.boxed())?; + let mut tasks = FuturesUnordered::new(); + loop { - match ctx.recv().await? { - FromOrchestra::Signal(OverseerSignal::ActiveLeaves(_)) => {}, - FromOrchestra::Signal(OverseerSignal::BlockFinalized(..)) => {}, - FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(()), - FromOrchestra::Communication { msg } => match msg { - CandidateValidationMessage::ValidateFromChainState { - candidate_receipt, - pov, - executor_params, - exec_kind, - response_sender, - .. - } => { - let bg = { - let mut sender = ctx.sender().clone(); - let metrics = metrics.clone(); - let validation_host = validation_host.clone(); - - async move { - let _timer = metrics.time_validate_from_chain_state(); - let res = validate_from_chain_state( - &mut sender, - validation_host, - candidate_receipt, - pov, - executor_params, - exec_kind, - &metrics, - ) - .await; - - metrics.on_validation_event(&res); - let _ = response_sender.send(res); - } - }; - - ctx.spawn("validate-from-chain-state", bg.boxed())?; - }, - CandidateValidationMessage::ValidateFromExhaustive { - validation_data, - validation_code, - candidate_receipt, - pov, - executor_params, - exec_kind, - response_sender, - .. - } => { - let bg = { - let metrics = metrics.clone(); - let validation_host = validation_host.clone(); - - async move { - let _timer = metrics.time_validate_from_exhaustive(); - let res = validate_candidate_exhaustive( - validation_host, - validation_data, - validation_code, - candidate_receipt, - pov, - executor_params, - exec_kind, - &metrics, - ) - .await; - - metrics.on_validation_event(&res); - let _ = response_sender.send(res); - } - }; - - ctx.spawn("validate-from-exhaustive", bg.boxed())?; + loop { + futures::select! { + comm = ctx.recv().fuse() => { + match comm { + Ok(FromOrchestra::Signal(OverseerSignal::ActiveLeaves(_))) => {}, + Ok(FromOrchestra::Signal(OverseerSignal::BlockFinalized(..))) => {}, + Ok(FromOrchestra::Signal(OverseerSignal::Conclude)) => return Ok(()), + Ok(FromOrchestra::Communication { msg }) => { + let task = handle_validation_message(ctx.sender().clone(), validation_host.clone(), metrics.clone(), msg); + tasks.push(task); + if tasks.len() >= TASK_LIMIT { + break + } + }, + Err(e) => return Err(SubsystemError::from(e)), + } }, - CandidateValidationMessage::PreCheck { - relay_parent, - validation_code_hash, - response_sender, - .. - } => { - let bg = { - let mut sender = ctx.sender().clone(); - let validation_host = validation_host.clone(); - - async move { - let precheck_result = precheck_pvf( - &mut sender, - validation_host, - relay_parent, - validation_code_hash, - ) - .await; - - let _ = response_sender.send(precheck_result); - } - }; - - ctx.spawn("candidate-validation-pre-check", bg.boxed())?; + _ = tasks.select_next_some() => () + } + } + + gum::debug!(target: LOG_TARGET, "Validation task limit hit"); + + loop { + futures::select! { + signal = ctx.recv_signal().fuse() => { + match signal { + Ok(OverseerSignal::ActiveLeaves(_)) => {}, + Ok(OverseerSignal::BlockFinalized(..)) => {}, + Ok(OverseerSignal::Conclude) => return Ok(()), + Err(e) => return Err(SubsystemError::from(e)), + } }, - }, + _ = tasks.select_next_some() => { + if tasks.len() < TASK_LIMIT { + break + } + } + } } } } diff --git a/polkadot/node/core/pvf/src/host.rs b/polkadot/node/core/pvf/src/host.rs index b07b3da4c26..e215f11b91d 100644 --- a/polkadot/node/core/pvf/src/host.rs +++ b/polkadot/node/core/pvf/src/host.rs @@ -60,6 +60,9 @@ pub const PREPARE_BINARY_NAME: &str = "polkadot-prepare-worker"; /// The name of binary spawned to execute a PVF pub const EXECUTE_BINARY_NAME: &str = "polkadot-execute-worker"; +/// The size of incoming message queue +pub const HOST_MESSAGE_QUEUE_SIZE: usize = 10; + /// An alias to not spell the type for the oneshot sender for the PVF execution result. pub(crate) type ResultSender = oneshot::Sender>; @@ -227,7 +230,7 @@ pub async fn start( Err(err) => return Err(SubsystemError::Context(err)), }; - let (to_host_tx, to_host_rx) = mpsc::channel(10); + let (to_host_tx, to_host_rx) = mpsc::channel(HOST_MESSAGE_QUEUE_SIZE); let validation_host = ValidationHost { to_host_tx, security_status: security_status.clone() }; diff --git a/polkadot/node/core/pvf/src/lib.rs b/polkadot/node/core/pvf/src/lib.rs index 79391630b2d..92263281eea 100644 --- a/polkadot/node/core/pvf/src/lib.rs +++ b/polkadot/node/core/pvf/src/lib.rs @@ -104,7 +104,10 @@ mod worker_interface; pub mod testing; pub use error::{InvalidCandidate, PossiblyInvalidError, ValidationError}; -pub use host::{start, Config, ValidationHost, EXECUTE_BINARY_NAME, PREPARE_BINARY_NAME}; +pub use host::{ + start, Config, ValidationHost, EXECUTE_BINARY_NAME, HOST_MESSAGE_QUEUE_SIZE, + PREPARE_BINARY_NAME, +}; pub use metrics::Metrics; pub use priority::Priority; pub use worker_interface::{framed_recv, framed_send, JOB_TIMEOUT_WALL_CLOCK_FACTOR}; diff --git a/polkadot/node/malus/src/interceptor.rs b/polkadot/node/malus/src/interceptor.rs index e994319beb9..b44ffc8956b 100644 --- a/polkadot/node/malus/src/interceptor.rs +++ b/polkadot/node/malus/src/interceptor.rs @@ -22,7 +22,7 @@ use polkadot_node_subsystem::*; pub use polkadot_node_subsystem::{messages::*, overseer, FromOrchestra}; -use std::{future::Future, pin::Pin}; +use std::{collections::VecDeque, future::Future, pin::Pin}; /// Filter incoming and outgoing messages. pub trait MessageInterceptor: Send + Sync + Clone + 'static @@ -170,6 +170,7 @@ where inner: Context, message_filter: Fil, sender: InterceptedSender<::Sender, Fil>, + message_buffer: VecDeque::Message>>, } impl InterceptedContext @@ -189,7 +190,7 @@ where inner: inner.sender().clone(), message_filter: message_filter.clone(), }; - Self { inner, message_filter, sender } + Self { inner, message_filter, sender, message_buffer: VecDeque::new() } } } @@ -233,6 +234,9 @@ where } async fn recv(&mut self) -> SubsystemResult> { + if let Some(msg) = self.message_buffer.pop_front() { + return Ok(msg) + } loop { let msg = self.inner.recv().await?; if let Some(msg) = self.message_filter.intercept_incoming(self.inner.sender(), msg) { @@ -241,6 +245,19 @@ where } } + async fn recv_signal(&mut self) -> SubsystemResult { + loop { + let msg = self.inner.recv().await?; + if let Some(msg) = self.message_filter.intercept_incoming(self.inner.sender(), msg) { + if let FromOrchestra::Signal(sig) = msg { + return Ok(sig) + } else { + self.message_buffer.push_back(msg) + } + } + } + } + fn spawn( &mut self, name: &'static str, diff --git a/polkadot/node/metrics/Cargo.toml b/polkadot/node/metrics/Cargo.toml index e9a4d463f4d..90d95a6e50a 100644 --- a/polkadot/node/metrics/Cargo.toml +++ b/polkadot/node/metrics/Cargo.toml @@ -14,7 +14,7 @@ futures = "0.3.21" futures-timer = "3.0.2" gum = { package = "tracing-gum", path = "../gum" } -metered = { package = "prioritized-metered-channel", version = "0.5.1", default-features = false, features = ["futures_channel"] } +metered = { package = "prioritized-metered-channel", version = "0.6.1", default-features = false, features = ["futures_channel"] } # Both `sc-service` and `sc-cli` are required by runtime metrics `logger_hook()`. sc-service = { path = "../../../substrate/client/service" } sc-cli = { path = "../../../substrate/client/cli" } diff --git a/polkadot/node/overseer/Cargo.toml b/polkadot/node/overseer/Cargo.toml index f168bdd0807..f39f0661aa1 100644 --- a/polkadot/node/overseer/Cargo.toml +++ b/polkadot/node/overseer/Cargo.toml @@ -20,14 +20,14 @@ polkadot-node-primitives = { path = "../primitives" } polkadot-node-subsystem-types = { path = "../subsystem-types" } polkadot-node-metrics = { path = "../metrics" } polkadot-primitives = { path = "../../primitives" } -orchestra = { version = "0.3.3", default-features = false, features = ["futures_channel"] } +orchestra = { version = "0.3.4", default-features = false, features = ["futures_channel"] } gum = { package = "tracing-gum", path = "../gum" } sp-core = { path = "../../../substrate/primitives/core" } async-trait = "0.1.74" tikv-jemalloc-ctl = { version = "0.5.0", optional = true } [dev-dependencies] -metered = { package = "prioritized-metered-channel", version = "0.5.1", default-features = false, features = ["futures_channel"] } +metered = { package = "prioritized-metered-channel", version = "0.6.1", default-features = false, features = ["futures_channel"] } sp-core = { path = "../../../substrate/primitives/core" } futures = { version = "0.3.21", features = ["thread-pool"] } femme = "2.2.1" diff --git a/polkadot/node/subsystem-bench/Cargo.toml b/polkadot/node/subsystem-bench/Cargo.toml index f09f7fc4897..750f7a7e2f8 100644 --- a/polkadot/node/subsystem-bench/Cargo.toml +++ b/polkadot/node/subsystem-bench/Cargo.toml @@ -55,7 +55,7 @@ prometheus = { version = "0.13.0", default-features = false } serde = "1.0.195" serde_yaml = "0.9" paste = "1.0.14" -orchestra = { version = "0.3.3", default-features = false, features = ["futures_channel"] } +orchestra = { version = "0.3.4", default-features = false, features = ["futures_channel"] } pyroscope = "0.5.7" pyroscope_pprofrs = "0.2.7" diff --git a/polkadot/node/subsystem-test-helpers/src/lib.rs b/polkadot/node/subsystem-test-helpers/src/lib.rs index dfa78e04b8c..6c1ac86c450 100644 --- a/polkadot/node/subsystem-test-helpers/src/lib.rs +++ b/polkadot/node/subsystem-test-helpers/src/lib.rs @@ -32,6 +32,7 @@ use parking_lot::Mutex; use sp_core::testing::TaskExecutor; use std::{ + collections::VecDeque, convert::Infallible, future::Future, pin::Pin, @@ -190,6 +191,7 @@ pub struct TestSubsystemContext { tx: TestSubsystemSender, rx: mpsc::Receiver>, spawn: S, + message_buffer: VecDeque>, } #[async_trait::async_trait] @@ -207,6 +209,9 @@ where type Error = SubsystemError; async fn try_recv(&mut self) -> Result>, ()> { + if let Some(msg) = self.message_buffer.pop_front() { + return Ok(Some(msg)) + } match poll!(self.rx.next()) { Poll::Ready(Some(msg)) => Ok(Some(msg)), Poll::Ready(None) => Err(()), @@ -215,12 +220,30 @@ where } async fn recv(&mut self) -> SubsystemResult> { + if let Some(msg) = self.message_buffer.pop_front() { + return Ok(msg) + } self.rx .next() .await .ok_or_else(|| SubsystemError::Context("Receiving end closed".to_owned())) } + async fn recv_signal(&mut self) -> SubsystemResult { + loop { + let msg = self + .rx + .next() + .await + .ok_or_else(|| SubsystemError::Context("Receiving end closed".to_owned()))?; + if let FromOrchestra::Signal(sig) = msg { + return Ok(sig) + } else { + self.message_buffer.push_back(msg) + } + } + } + fn spawn( &mut self, name: &'static str, @@ -314,6 +337,7 @@ pub fn make_buffered_subsystem_context( tx: TestSubsystemSender { tx: all_messages_tx }, rx: overseer_rx, spawn: SpawnGlue(spawner), + message_buffer: VecDeque::new(), }, TestSubsystemContextHandle { tx: overseer_tx, rx: all_messages_rx }, ) diff --git a/polkadot/node/subsystem-types/Cargo.toml b/polkadot/node/subsystem-types/Cargo.toml index 6713e903123..181ef54b4c6 100644 --- a/polkadot/node/subsystem-types/Cargo.toml +++ b/polkadot/node/subsystem-types/Cargo.toml @@ -17,7 +17,7 @@ polkadot-node-primitives = { path = "../primitives" } polkadot-node-network-protocol = { path = "../network/protocol" } polkadot-statement-table = { path = "../../statement-table" } polkadot-node-jaeger = { path = "../jaeger" } -orchestra = { version = "0.3.3", default-features = false, features = ["futures_channel"] } +orchestra = { version = "0.3.4", default-features = false, features = ["futures_channel"] } sc-network = { path = "../../../substrate/client/network" } sp-api = { path = "../../../substrate/primitives/api" } sp-blockchain = { path = "../../../substrate/primitives/blockchain" } diff --git a/polkadot/node/subsystem-util/Cargo.toml b/polkadot/node/subsystem-util/Cargo.toml index 3147a4f64f4..68a834d46e3 100644 --- a/polkadot/node/subsystem-util/Cargo.toml +++ b/polkadot/node/subsystem-util/Cargo.toml @@ -32,7 +32,7 @@ polkadot-node-network-protocol = { path = "../network/protocol" } polkadot-primitives = { path = "../../primitives" } polkadot-node-primitives = { path = "../primitives" } polkadot-overseer = { path = "../overseer" } -metered = { package = "prioritized-metered-channel", version = "0.5.1", default-features = false, features = ["futures_channel"] } +metered = { package = "prioritized-metered-channel", version = "0.6.1", default-features = false, features = ["futures_channel"] } sp-core = { path = "../../../substrate/primitives/core" } sp-application-crypto = { path = "../../../substrate/primitives/application-crypto" } diff --git a/prdoc/pr_2125.prdoc b/prdoc/pr_2125.prdoc new file mode 100644 index 00000000000..ee81975d2d0 --- /dev/null +++ b/prdoc/pr_2125.prdoc @@ -0,0 +1,14 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Introduce bounds for the number of candidate validation subsystem simultaneously processed tasks + +doc: + - audience: Node Dev + description: | + Makes it possible for the candidate validation subsystem to create backpressure on subsystems + requesting to validate a candidate through limiting the number of simultaneously processed + validation tasks. + +crates: + - name: polkadot-node-core-candidate-validation -- GitLab From 757ae372f7f07d9a7a4f62f646baa5e388ec5531 Mon Sep 17 00:00:00 2001 From: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Date: Mon, 22 Jan 2024 08:15:53 +0100 Subject: [PATCH 098/392] Switch All `construct_runtime`s to New Syntax (#2979) Clean up all the old syntax. --------- Co-authored-by: command-bot <> Co-authored-by: gupnik Co-authored-by: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Co-authored-by: Maksym H <1177472+mordamax@users.noreply.github.com> --- cumulus/parachain-template/runtime/src/lib.rs | 2 +- .../assets/asset-hub-rococo/src/lib.rs | 57 ++++---- .../assets/asset-hub-westend/src/lib.rs | 58 ++++---- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 72 +++++----- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 46 +++--- .../collectives-westend/src/lib.rs | 72 +++++----- .../contracts/contracts-rococo/src/lib.rs | 42 +++--- .../glutton/glutton-westend/src/lib.rs | 22 ++- .../runtimes/people/people-rococo/src/lib.rs | 40 +++--- .../runtimes/people/people-westend/src/lib.rs | 40 +++--- .../runtimes/starters/seedling/src/lib.rs | 20 ++- .../runtimes/starters/shell/src/lib.rs | 18 ++- .../runtimes/testing/penpal/src/lib.rs | 40 +++--- .../testing/rococo-parachain/src/lib.rs | 32 ++--- docs/sdk/src/guides/your_first_pallet/mod.rs | 6 +- docs/sdk/src/polkadot_sdk/cumulus.rs | 2 +- docs/sdk/src/polkadot_sdk/frame_runtime.rs | 4 +- .../runtime/common/src/assigned_slots/mod.rs | 14 +- polkadot/runtime/common/src/auctions.rs | 6 +- polkadot/runtime/common/src/claims.rs | 8 +- polkadot/runtime/common/src/crowdloan/mod.rs | 6 +- polkadot/runtime/common/src/impls.rs | 8 +- .../runtime/common/src/integration_tests.rs | 26 ++-- .../runtime/common/src/paras_registrar/mod.rs | 14 +- polkadot/runtime/common/src/purchase.rs | 8 +- polkadot/runtime/common/src/slots/mod.rs | 6 +- polkadot/runtime/rococo/src/lib.rs | 132 +++++++++--------- polkadot/runtime/test-runtime/src/lib.rs | 70 +++++----- polkadot/runtime/westend/src/lib.rs | 120 ++++++++-------- .../src/fungible/mock.rs | 6 +- .../pallet-xcm-benchmarks/src/generic/mock.rs | 6 +- polkadot/xcm/pallet-xcm/src/mock.rs | 12 +- .../xcm/xcm-builder/src/tests/pay/mock.rs | 2 +- polkadot/xcm/xcm-builder/tests/mock/mod.rs | 8 +- .../xcm-simulator/example/src/parachain.rs | 10 +- .../xcm-simulator/example/src/relay_chain.rs | 12 +- .../xcm/xcm-simulator/fuzzer/src/parachain.rs | 8 +- .../xcm-simulator/fuzzer/src/relay_chain.rs | 10 +- substrate/bin/minimal/runtime/src/lib.rs | 2 +- .../bin/node-template/runtime/src/lib.rs | 2 +- substrate/bin/node/runtime/src/lib.rs | 11 +- substrate/frame/assets/src/mock.rs | 6 +- substrate/frame/atomic-swap/src/tests.rs | 6 +- substrate/frame/aura/src/mock.rs | 6 +- .../frame/authority-discovery/src/lib.rs | 6 +- substrate/frame/authorship/src/lib.rs | 4 +- substrate/frame/bags-list/src/mock.rs | 7 +- substrate/frame/balances/src/tests/mod.rs | 9 +- substrate/frame/beefy-mmr/src/mock.rs | 10 +- .../benchmarking/pov/src/benchmarking.rs | 4 +- substrate/frame/benchmarking/pov/src/tests.rs | 4 +- substrate/frame/benchmarking/src/baseline.rs | 2 +- substrate/frame/benchmarking/src/tests.rs | 4 +- .../frame/benchmarking/src/tests_instance.rs | 4 +- substrate/frame/bounties/src/tests.rs | 12 +- substrate/frame/child-bounties/src/tests.rs | 10 +- substrate/frame/collective/src/tests.rs | 11 +- .../contracts/mock-network/src/relay_chain.rs | 10 +- substrate/frame/contracts/src/tests.rs | 14 +- .../frame/conviction-voting/src/tests.rs | 6 +- substrate/frame/core-fellowship/src/tests.rs | 4 +- substrate/frame/democracy/src/tests.rs | 8 +- .../election-provider-multi-phase/src/mock.rs | 9 +- .../election-provider-support/src/onchain.rs | 5 +- substrate/frame/elections-phragmen/src/lib.rs | 7 +- substrate/frame/examples/basic/src/tests.rs | 6 +- .../frame/examples/default-config/src/lib.rs | 2 +- .../frame/examples/dev-mode/src/tests.rs | 6 +- .../frame/examples/frame-crate/src/lib.rs | 2 +- .../examples/offchain-worker/src/tests.rs | 4 +- substrate/frame/examples/tasks/src/mock.rs | 2 +- substrate/frame/executive/src/lib.rs | 11 +- substrate/frame/fast-unstake/src/mock.rs | 2 +- substrate/frame/glutton/src/mock.rs | 4 +- substrate/frame/identity/src/tests.rs | 6 +- substrate/frame/im-online/src/mock.rs | 11 +- substrate/frame/indices/src/mock.rs | 6 +- .../src/lib.rs | 4 +- substrate/frame/lottery/src/mock.rs | 6 +- substrate/frame/membership/src/lib.rs | 4 +- .../frame/merkle-mountain-range/src/mock.rs | 4 +- .../message-queue/src/integration_test.rs | 4 +- substrate/frame/message-queue/src/mock.rs | 4 +- substrate/frame/multisig/src/tests.rs | 6 +- substrate/frame/nfts/src/mock.rs | 6 +- .../frame/node-authorization/src/mock.rs | 6 +- .../nomination-pools/benchmarking/src/mock.rs | 15 +- substrate/frame/nomination-pools/src/mock.rs | 9 +- .../nomination-pools/test-staking/src/mock.rs | 15 +- .../frame/offences/benchmarking/src/mock.rs | 6 +- substrate/frame/offences/src/mock.rs | 7 +- substrate/frame/proxy/src/tests.rs | 8 +- .../frame/ranked-collective/src/tests.rs | 4 +- substrate/frame/recovery/src/mock.rs | 6 +- substrate/frame/remark/src/mock.rs | 4 +- substrate/frame/root-offences/src/mock.rs | 14 +- substrate/frame/salary/src/tests.rs | 4 +- substrate/frame/scheduler/src/mock.rs | 8 +- substrate/frame/scored-pool/src/mock.rs | 6 +- .../frame/session/benchmarking/src/mock.rs | 8 +- substrate/frame/session/src/mock.rs | 10 +- substrate/frame/society/src/mock.rs | 6 +- .../frame/state-trie-migration/src/lib.rs | 6 +- substrate/frame/sudo/src/mock.rs | 6 +- .../procedural/src/construct_runtime/mod.rs | 6 +- substrate/frame/support/src/lib.rs | 2 +- substrate/frame/support/src/migrations.rs | 6 +- .../support/test/compile_pass/src/lib.rs | 2 +- .../support/test/stg_frame_crate/src/lib.rs | 4 +- .../missing_system_module.stderr | 2 +- .../pass/composite_enum_instance.rs | 2 +- .../frame/support/test/tests/final_keys.rs | 1 - .../frame/support/test/tests/instance.rs | 27 ++-- .../frame/support/test/tests/issue2219.rs | 2 +- .../pallet_ui/pass/no_std_genesis_config.rs | 4 +- .../support/test/tests/storage_layers.rs | 2 +- .../support/test/tests/versioned_migration.rs | 4 +- substrate/frame/system/benches/bench.rs | 7 +- .../frame/system/benchmarking/src/mock.rs | 2 +- substrate/frame/system/src/mock.rs | 2 +- substrate/frame/timestamp/src/mock.rs | 4 +- substrate/frame/tips/src/tests.rs | 12 +- .../asset-tx-payment/src/mock.rs | 2 +- .../skip-feeless-payment/src/mock.rs | 2 +- .../frame/transaction-payment/src/mock.rs | 4 +- .../frame/transaction-storage/src/mock.rs | 8 +- substrate/frame/treasury/src/tests.rs | 6 +- substrate/frame/uniques/src/mock.rs | 6 +- substrate/frame/utility/src/tests.rs | 14 +- substrate/frame/vesting/src/mock.rs | 6 +- substrate/primitives/api/src/lib.rs | 4 +- .../api/test/tests/decl_and_impl.rs | 2 +- substrate/utils/frame/rpc/support/src/lib.rs | 4 +- 133 files changed, 795 insertions(+), 850 deletions(-) diff --git a/cumulus/parachain-template/runtime/src/lib.rs b/cumulus/parachain-template/runtime/src/lib.rs index 1ef018a8ca3..0ab36eba315 100644 --- a/cumulus/parachain-template/runtime/src/lib.rs +++ b/cumulus/parachain-template/runtime/src/lib.rs @@ -493,7 +493,7 @@ impl pallet_parachain_template::Config for Runtime { // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( - pub struct Runtime { + pub enum Runtime { // System support stuff. System: frame_system = 0, ParachainSystem: cumulus_pallet_parachain_system = 1, diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 0f379a6f7bc..a812e747f00 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -895,48 +895,45 @@ construct_runtime!( pub enum Runtime { // System support stuff. - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 3, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 4, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, + Timestamp: pallet_timestamp = 3, + ParachainInfo: parachain_info = 4, // Monetary stuff. - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 11, - AssetTxPayment: pallet_asset_conversion_tx_payment::{Pallet, Event} = 13, + Balances: pallet_balances = 10, + TransactionPayment: pallet_transaction_payment = 11, + AssetTxPayment: pallet_asset_conversion_tx_payment = 13, // Collator support. the order of these 5 are important and shall not change. - Authorship: pallet_authorship::{Pallet, Storage} = 20, - CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config} = 21, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22, - Aura: pallet_aura::{Pallet, Storage, Config} = 23, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24, + Authorship: pallet_authorship = 20, + CollatorSelection: pallet_collator_selection = 21, + Session: pallet_session = 22, + Aura: pallet_aura = 23, + AuraExt: cumulus_pallet_aura_ext = 24, // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 34, + XcmpQueue: cumulus_pallet_xcmp_queue = 30, + PolkadotXcm: pallet_xcm = 31, + CumulusXcm: cumulus_pallet_xcm = 32, + MessageQueue: pallet_message_queue = 34, // Handy utilities. - Utility: pallet_utility::{Pallet, Call, Event} = 40, - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 41, - Proxy: pallet_proxy::{Pallet, Call, Storage, Event} = 42, + Utility: pallet_utility = 40, + Multisig: pallet_multisig = 41, + Proxy: pallet_proxy = 42, // Bridge utilities. - ToWestendXcmRouter: pallet_xcm_bridge_hub_router::::{Pallet, Storage, Call} = 45, + ToWestendXcmRouter: pallet_xcm_bridge_hub_router:: = 45, // The main stage. - Assets: pallet_assets::::{Pallet, Call, Storage, Event} = 50, - Uniques: pallet_uniques::{Pallet, Call, Storage, Event} = 51, - Nfts: pallet_nfts::{Pallet, Call, Storage, Event} = 52, - ForeignAssets: pallet_assets::::{Pallet, Call, Storage, Event} = 53, - NftFractionalization: pallet_nft_fractionalization::{Pallet, Call, Storage, Event, HoldReason} = 54, - - PoolAssets: pallet_assets::::{Pallet, Call, Storage, Event} = 55, - AssetConversion: pallet_asset_conversion::{Pallet, Call, Storage, Event} = 56, + Assets: pallet_assets:: = 50, + Uniques: pallet_uniques = 51, + Nfts: pallet_nfts = 52, + ForeignAssets: pallet_assets:: = 53, + NftFractionalization: pallet_nft_fractionalization = 54, + PoolAssets: pallet_assets:: = 55, + AssetConversion: pallet_asset_conversion = 56, #[cfg(feature = "state-trie-version-1")] StateTrieMigration: pallet_state_trie_migration = 70, diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 310726349fa..b4bcc716513 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -870,48 +870,46 @@ construct_runtime!( pub enum Runtime { // System support stuff. - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, // RandomnessCollectiveFlip = 2 removed - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 3, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 4, + Timestamp: pallet_timestamp = 3, + ParachainInfo: parachain_info = 4, // Monetary stuff. - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 11, - // AssetTxPayment: pallet_asset_tx_payment::{Pallet, Event} = 12, - AssetTxPayment: pallet_asset_conversion_tx_payment::{Pallet, Event} = 13, + Balances: pallet_balances = 10, + TransactionPayment: pallet_transaction_payment = 11, + // AssetTxPayment: pallet_asset_tx_payment = 12, + AssetTxPayment: pallet_asset_conversion_tx_payment = 13, // Collator support. the order of these 5 are important and shall not change. - Authorship: pallet_authorship::{Pallet, Storage} = 20, - CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config} = 21, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22, - Aura: pallet_aura::{Pallet, Storage, Config} = 23, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24, + Authorship: pallet_authorship = 20, + CollatorSelection: pallet_collator_selection = 21, + Session: pallet_session = 22, + Aura: pallet_aura = 23, + AuraExt: cumulus_pallet_aura_ext = 24, // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, + XcmpQueue: cumulus_pallet_xcmp_queue = 30, + PolkadotXcm: pallet_xcm = 31, + CumulusXcm: cumulus_pallet_xcm = 32, // Bridge utilities. - ToRococoXcmRouter: pallet_xcm_bridge_hub_router::::{Pallet, Storage, Call} = 34, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 35, + ToRococoXcmRouter: pallet_xcm_bridge_hub_router:: = 34, + MessageQueue: pallet_message_queue = 35, // Handy utilities. - Utility: pallet_utility::{Pallet, Call, Event} = 40, - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 41, - Proxy: pallet_proxy::{Pallet, Call, Storage, Event} = 42, + Utility: pallet_utility = 40, + Multisig: pallet_multisig = 41, + Proxy: pallet_proxy = 42, // The main stage. - Assets: pallet_assets::::{Pallet, Call, Storage, Event} = 50, - Uniques: pallet_uniques::{Pallet, Call, Storage, Event} = 51, - Nfts: pallet_nfts::{Pallet, Call, Storage, Event} = 52, - ForeignAssets: pallet_assets::::{Pallet, Call, Storage, Event} = 53, - NftFractionalization: pallet_nft_fractionalization::{Pallet, Call, Storage, Event, HoldReason} = 54, - PoolAssets: pallet_assets::::{Pallet, Call, Storage, Event} = 55, - AssetConversion: pallet_asset_conversion::{Pallet, Call, Storage, Event} = 56, + Assets: pallet_assets:: = 50, + Uniques: pallet_uniques = 51, + Nfts: pallet_nfts = 52, + ForeignAssets: pallet_assets:: = 53, + NftFractionalization: pallet_nft_fractionalization = 54, + PoolAssets: pallet_assets:: = 55, + AssetConversion: pallet_asset_conversion = 56, } ); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index f84ff0799b9..4a3ef8ac4e8 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -666,68 +666,66 @@ construct_runtime!( pub enum Runtime { // System support stuff. - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 3, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, + Timestamp: pallet_timestamp = 2, + ParachainInfo: parachain_info = 3, // Monetary stuff. - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 11, + Balances: pallet_balances = 10, + TransactionPayment: pallet_transaction_payment = 11, // Collator support. The order of these 4 are important and shall not change. - Authorship: pallet_authorship::{Pallet, Storage} = 20, - CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config} = 21, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22, - Aura: pallet_aura::{Pallet, Storage, Config} = 23, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24, + Authorship: pallet_authorship = 20, + CollatorSelection: pallet_collator_selection = 21, + Session: pallet_session = 22, + Aura: pallet_aura = 23, + AuraExt: cumulus_pallet_aura_ext = 24, // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, + XcmpQueue: cumulus_pallet_xcmp_queue = 30, + PolkadotXcm: pallet_xcm = 31, + CumulusXcm: cumulus_pallet_xcm = 32, // Handy utilities. - Utility: pallet_utility::{Pallet, Call, Event} = 40, - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 36, + Utility: pallet_utility = 40, + Multisig: pallet_multisig = 36, // Bridge relayers pallet, used by several bridges here. - BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event} = 47, + BridgeRelayers: pallet_bridge_relayers = 47, // With-Westend GRANDPA bridge module. - BridgeWestendGrandpa: pallet_bridge_grandpa::::{Pallet, Call, Storage, Event, Config} = 48, + BridgeWestendGrandpa: pallet_bridge_grandpa:: = 48, // With-Westend parachain bridge module. - BridgeWestendParachains: pallet_bridge_parachains::::{Pallet, Call, Storage, Event} = 49, + BridgeWestendParachains: pallet_bridge_parachains:: = 49, // With-Westend messaging bridge module. - BridgeWestendMessages: pallet_bridge_messages::::{Pallet, Call, Storage, Event, Config} = 51, + BridgeWestendMessages: pallet_bridge_messages:: = 51, // With-Westend bridge hub pallet. - XcmOverBridgeHubWestend: pallet_xcm_bridge_hub::::{Pallet} = 52, + XcmOverBridgeHubWestend: pallet_xcm_bridge_hub:: = 52, // With-Rococo Bulletin GRANDPA bridge module. // - // we can't use `BridgeRococoBulletinGrandpa` name here, because the same Bulletin runtime will be - // used for both Rococo and Polkadot Bulletin chains AND this name affects runtime storage keys, used - // by the relayer process - BridgePolkadotBulletinGrandpa: pallet_bridge_grandpa::::{Pallet, Call, Storage, Event, Config} = 60, + // we can't use `BridgeRococoBulletinGrandpa` name here, because the same Bulletin runtime + // will be used for both Rococo and Polkadot Bulletin chains AND this name affects runtime + // storage keys, used by the relayer process. + BridgePolkadotBulletinGrandpa: pallet_bridge_grandpa:: = 60, // With-Rococo Bulletin messaging bridge module. // - // we can't use `BridgeRococoBulletinMessages` name here, because the same Bulletin runtime will be - // used for both Rococo and Polkadot Bulletin chains AND this name affects runtime storage keys, used - // by this runtime and the relayer process - BridgePolkadotBulletinMessages: pallet_bridge_messages::::{Pallet, Call, Storage, Event, Config} = 61, + // we can't use `BridgeRococoBulletinMessages` name here, because the same Bulletin runtime + // will be used for both Rococo and Polkadot Bulletin chains AND this name affects runtime + // storage keys, used by this runtime and the relayer process. + BridgePolkadotBulletinMessages: pallet_bridge_messages:: = 61, // With-Rococo Bulletin bridge hub pallet. - XcmOverPolkadotBulletin: pallet_xcm_bridge_hub::::{Pallet} = 62, + XcmOverPolkadotBulletin: pallet_xcm_bridge_hub:: = 62, - EthereumInboundQueue: snowbridge_pallet_inbound_queue::{Pallet, Call, Storage, Event} = 80, - EthereumOutboundQueue: snowbridge_pallet_outbound_queue::{Pallet, Call, Storage, Event} = 81, - EthereumBeaconClient: snowbridge_pallet_ethereum_client::{Pallet, Call, Storage, Event} = 82, - EthereumSystem: snowbridge_pallet_system::{Pallet, Call, Storage, Config, Event} = 83, + EthereumInboundQueue: snowbridge_pallet_inbound_queue = 80, + EthereumOutboundQueue: snowbridge_pallet_outbound_queue = 81, + EthereumBeaconClient: snowbridge_pallet_ethereum_client = 82, + EthereumSystem: snowbridge_pallet_system = 83, // Message Queue. Importantly, is registered last so that messages are processed after // the `on_initialize` hooks of bridging pallets. - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 250, + MessageQueue: pallet_message_queue = 250, } ); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index e90b5668c03..08dd129d84b 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -460,43 +460,41 @@ construct_runtime!( pub enum Runtime { // System support stuff. - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 3, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, + Timestamp: pallet_timestamp = 2, + ParachainInfo: parachain_info = 3, // Monetary stuff. - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 11, + Balances: pallet_balances = 10, + TransactionPayment: pallet_transaction_payment = 11, // Collator support. The order of these 4 are important and shall not change. - Authorship: pallet_authorship::{Pallet, Storage} = 20, - CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config} = 21, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22, - Aura: pallet_aura::{Pallet, Storage, Config} = 23, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24, + Authorship: pallet_authorship = 20, + CollatorSelection: pallet_collator_selection = 21, + Session: pallet_session = 22, + Aura: pallet_aura = 23, + AuraExt: cumulus_pallet_aura_ext = 24, // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, + XcmpQueue: cumulus_pallet_xcmp_queue = 30, + PolkadotXcm: pallet_xcm = 31, + CumulusXcm: cumulus_pallet_xcm = 32, // Handy utilities. - Utility: pallet_utility::{Pallet, Call, Event} = 40, - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 36, + Utility: pallet_utility = 40, + Multisig: pallet_multisig = 36, // Bridging stuff. - BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event} = 41, - BridgeRococoGrandpa: pallet_bridge_grandpa::::{Pallet, Call, Storage, Event, Config} = 42, - BridgeRococoParachains: pallet_bridge_parachains::::{Pallet, Call, Storage, Event} = 43, - BridgeRococoMessages: pallet_bridge_messages::::{Pallet, Call, Storage, Event, Config} = 44, - XcmOverBridgeHubRococo: pallet_xcm_bridge_hub::::{Pallet} = 45, + BridgeRelayers: pallet_bridge_relayers = 41, + BridgeRococoGrandpa: pallet_bridge_grandpa:: = 42, + BridgeRococoParachains: pallet_bridge_parachains:: = 43, + BridgeRococoMessages: pallet_bridge_messages:: = 44, + XcmOverBridgeHubRococo: pallet_xcm_bridge_hub:: = 45, // Message Queue. Importantly, is registered last so that messages are processed after // the `on_initialize` hooks of bridging pallets. - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 250, + MessageQueue: pallet_message_queue = 250, } ); diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index 3aff4671636..be7beafc89a 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -635,64 +635,62 @@ construct_runtime!( pub enum Runtime { // System support stuff. - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 3, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, + Timestamp: pallet_timestamp = 2, + ParachainInfo: parachain_info = 3, // Monetary stuff. - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 11, + Balances: pallet_balances = 10, + TransactionPayment: pallet_transaction_payment = 11, // Collator support. the order of these 5 are important and shall not change. - Authorship: pallet_authorship::{Pallet, Storage} = 20, - CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config} = 21, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22, - Aura: pallet_aura::{Pallet, Storage, Config} = 23, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24, + Authorship: pallet_authorship = 20, + CollatorSelection: pallet_collator_selection = 21, + Session: pallet_session = 22, + Aura: pallet_aura = 23, + AuraExt: cumulus_pallet_aura_ext = 24, // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 34, + XcmpQueue: cumulus_pallet_xcmp_queue = 30, + PolkadotXcm: pallet_xcm = 31, + CumulusXcm: cumulus_pallet_xcm = 32, + MessageQueue: pallet_message_queue = 34, // Handy utilities. - Utility: pallet_utility::{Pallet, Call, Event} = 40, - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 41, - Proxy: pallet_proxy::{Pallet, Call, Storage, Event} = 42, - Preimage: pallet_preimage::{Pallet, Call, Storage, Event, HoldReason} = 43, - Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event} = 44, - AssetRate: pallet_asset_rate::{Pallet, Call, Storage, Event} = 45, + Utility: pallet_utility = 40, + Multisig: pallet_multisig = 41, + Proxy: pallet_proxy = 42, + Preimage: pallet_preimage = 43, + Scheduler: pallet_scheduler = 44, + AssetRate: pallet_asset_rate = 45, // The main stage. // The Alliance. - Alliance: pallet_alliance::{Pallet, Call, Storage, Event, Config} = 50, - AllianceMotion: pallet_collective::::{Pallet, Call, Storage, Origin, Event, Config} = 51, + Alliance: pallet_alliance = 50, + AllianceMotion: pallet_collective:: = 51, // The Fellowship. // pub type FellowshipCollectiveInstance = pallet_ranked_collective::Instance1; - FellowshipCollective: pallet_ranked_collective::::{Pallet, Call, Storage, Event} = 60, + FellowshipCollective: pallet_ranked_collective:: = 60, // pub type FellowshipReferendaInstance = pallet_referenda::Instance1; - FellowshipReferenda: pallet_referenda::::{Pallet, Call, Storage, Event} = 61, - FellowshipOrigins: pallet_fellowship_origins::{Origin} = 62, + FellowshipReferenda: pallet_referenda:: = 61, + FellowshipOrigins: pallet_fellowship_origins = 62, // pub type FellowshipCoreInstance = pallet_core_fellowship::Instance1; - FellowshipCore: pallet_core_fellowship::::{Pallet, Call, Storage, Event} = 63, + FellowshipCore: pallet_core_fellowship:: = 63, // pub type FellowshipSalaryInstance = pallet_salary::Instance1; - FellowshipSalary: pallet_salary::::{Pallet, Call, Storage, Event} = 64, + FellowshipSalary: pallet_salary:: = 64, // pub type FellowshipTreasuryInstance = pallet_treasury::Instance1; - FellowshipTreasury: pallet_treasury::::{Pallet, Call, Storage, Event} = 65, + FellowshipTreasury: pallet_treasury:: = 65, // Ambassador Program. - AmbassadorCollective: pallet_ranked_collective::::{Pallet, Call, Storage, Event} = 70, - AmbassadorReferenda: pallet_referenda::::{Pallet, Call, Storage, Event} = 71, - AmbassadorOrigins: pallet_ambassador_origins::{Origin} = 72, - AmbassadorCore: pallet_core_fellowship::::{Pallet, Call, Storage, Event} = 73, - AmbassadorSalary: pallet_salary::::{Pallet, Call, Storage, Event} = 74, - AmbassadorContent: pallet_collective_content::::{Pallet, Call, Storage, Event} = 75, + AmbassadorCollective: pallet_ranked_collective:: = 70, + AmbassadorReferenda: pallet_referenda:: = 71, + AmbassadorOrigins: pallet_ambassador_origins = 72, + AmbassadorCore: pallet_core_fellowship:: = 73, + AmbassadorSalary: pallet_salary:: = 74, + AmbassadorContent: pallet_collective_content:: = 75, } ); diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index 707766ca226..f1c5acb4952 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -376,40 +376,38 @@ construct_runtime!( pub enum Runtime { // System support stuff. - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, - RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip::{Pallet, Storage} = 2, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 3, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 4, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, + RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip = 2, + Timestamp: pallet_timestamp = 3, + ParachainInfo: parachain_info = 4, // Monetary stuff. - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 11, + Balances: pallet_balances = 10, + TransactionPayment: pallet_transaction_payment = 11, // Collator support. The order of these 5 are important and shall not change. - Authorship: pallet_authorship::{Pallet, Storage} = 20, - CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config} = 21, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22, - Aura: pallet_aura::{Pallet, Storage, Config} = 23, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24, + Authorship: pallet_authorship = 20, + CollatorSelection: pallet_collator_selection = 21, + Session: pallet_session = 22, + Aura: pallet_aura = 23, + AuraExt: cumulus_pallet_aura_ext = 24, // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 34, + XcmpQueue: cumulus_pallet_xcmp_queue = 30, + PolkadotXcm: pallet_xcm = 31, + CumulusXcm: cumulus_pallet_xcm = 32, + MessageQueue: pallet_message_queue = 34, // Smart Contracts. - Contracts: pallet_contracts::{Pallet, Call, Storage, Event, HoldReason} = 40, + Contracts: pallet_contracts = 40, // Handy utilities. - Utility: pallet_utility::{Pallet, Call, Event} = 50, - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 51, + Utility: pallet_utility = 50, + Multisig: pallet_multisig = 51, // Sudo - Sudo: pallet_sudo::{Pallet, Call, Config, Event, Storage} = 100, + Sudo: pallet_sudo = 100, } ); diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs index 15899e49195..9fbbdc61fea 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs @@ -274,26 +274,24 @@ impl pallet_sudo::Config for Runtime { construct_runtime! { pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 2, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 3, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, + ParachainInfo: parachain_info = 2, + Timestamp: pallet_timestamp = 3, // DMP handler. - CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Storage, Event, Origin} = 10, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 11, + CumulusXcm: cumulus_pallet_xcm = 10, + MessageQueue: pallet_message_queue = 11, // The main stage. - Glutton: pallet_glutton::{Pallet, Call, Storage, Event, Config} = 20, + Glutton: pallet_glutton = 20, // Collator support - Aura: pallet_aura::{Pallet, Storage, Config} = 30, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 31, + Aura: pallet_aura = 30, + AuraExt: cumulus_pallet_aura_ext = 31, // Sudo. - Sudo: pallet_sudo::{Pallet, Call, Storage, Event, Config} = 255, + Sudo: pallet_sudo = 255, } } diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index 21c24086cbe..7836208eb62 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -400,39 +400,37 @@ construct_runtime!( pub enum Runtime { // System support stuff. - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 3, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, + Timestamp: pallet_timestamp = 2, + ParachainInfo: parachain_info = 3, // Monetary stuff. - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 11, + Balances: pallet_balances = 10, + TransactionPayment: pallet_transaction_payment = 11, // Collator support. The order of these 5 are important and shall not change. - Authorship: pallet_authorship::{Pallet, Storage} = 20, - CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config} = 21, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22, - Aura: pallet_aura::{Pallet, Storage, Config} = 23, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24, + Authorship: pallet_authorship = 20, + CollatorSelection: pallet_collator_selection = 21, + Session: pallet_session = 22, + Aura: pallet_aura = 23, + AuraExt: cumulus_pallet_aura_ext = 24, // XCM & related - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 34, + XcmpQueue: cumulus_pallet_xcmp_queue = 30, + PolkadotXcm: pallet_xcm = 31, + CumulusXcm: cumulus_pallet_xcm = 32, + MessageQueue: pallet_message_queue = 34, // Handy utilities. - Utility: pallet_utility::{Pallet, Call, Event} = 40, - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 41, + Utility: pallet_utility = 40, + Multisig: pallet_multisig = 41, // The main stage. - Identity: pallet_identity::{Pallet, Call, Storage, Event} = 50, + Identity: pallet_identity = 50, // To migrate deposits - IdentityMigrator: identity_migrator::{Pallet, Call, Event} = 248, + IdentityMigrator: identity_migrator = 248, } ); diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index 4015d841b81..750bf5b2c3e 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -408,39 +408,37 @@ construct_runtime!( pub enum Runtime { // System support stuff. - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 3, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, + Timestamp: pallet_timestamp = 2, + ParachainInfo: parachain_info = 3, // Monetary stuff. - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 11, + Balances: pallet_balances = 10, + TransactionPayment: pallet_transaction_payment = 11, // Collator support. The order of these 5 are important and shall not change. - Authorship: pallet_authorship::{Pallet, Storage} = 20, - CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config} = 21, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22, - Aura: pallet_aura::{Pallet, Storage, Config} = 23, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24, + Authorship: pallet_authorship = 20, + CollatorSelection: pallet_collator_selection = 21, + Session: pallet_session = 22, + Aura: pallet_aura = 23, + AuraExt: cumulus_pallet_aura_ext = 24, // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 34, + XcmpQueue: cumulus_pallet_xcmp_queue = 30, + PolkadotXcm: pallet_xcm = 31, + CumulusXcm: cumulus_pallet_xcm = 32, + MessageQueue: pallet_message_queue = 34, // Handy utilities. - Utility: pallet_utility::{Pallet, Call, Event} = 40, - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 41, + Utility: pallet_utility = 40, + Multisig: pallet_multisig = 41, // The main stage. - Identity: pallet_identity::{Pallet, Call, Storage, Event} = 50, + Identity: pallet_identity = 50, // To migrate deposits - IdentityMigrator: identity_migrator::{Pallet, Call, Event} = 248, + IdentityMigrator: identity_migrator = 248, } ); diff --git a/cumulus/parachains/runtimes/starters/seedling/src/lib.rs b/cumulus/parachains/runtimes/starters/seedling/src/lib.rs index cb868627e79..ba077ef8879 100644 --- a/cumulus/parachains/runtimes/starters/seedling/src/lib.rs +++ b/cumulus/parachains/runtimes/starters/seedling/src/lib.rs @@ -230,17 +230,15 @@ impl pallet_timestamp::Config for Runtime { construct_runtime! { pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Sudo: pallet_sudo::{Pallet, Call, Storage, Config, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - }, - ParachainInfo: parachain_info::{Pallet, Storage, Config}, - SoloToPara: cumulus_pallet_solo_to_para::{Pallet, Call, Storage, Event}, - Aura: pallet_aura::{Pallet, Storage, Config}, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config}, + System: frame_system, + Sudo: pallet_sudo, + Timestamp: pallet_timestamp, + + ParachainSystem: cumulus_pallet_parachain_system, + ParachainInfo: parachain_info, + SoloToPara: cumulus_pallet_solo_to_para, + Aura: pallet_aura, + AuraExt: cumulus_pallet_aura_ext, } } diff --git a/cumulus/parachains/runtimes/starters/shell/src/lib.rs b/cumulus/parachains/runtimes/starters/shell/src/lib.rs index de95969f71d..457394760d9 100644 --- a/cumulus/parachains/runtimes/starters/shell/src/lib.rs +++ b/cumulus/parachains/runtimes/starters/shell/src/lib.rs @@ -258,19 +258,17 @@ impl pallet_timestamp::Config for Runtime { construct_runtime! { pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + System: frame_system, + Timestamp: pallet_timestamp, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - }, - ParachainInfo: parachain_info::{Pallet, Storage, Config}, + ParachainSystem: cumulus_pallet_parachain_system, + ParachainInfo: parachain_info, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Storage, Event, Origin}, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event}, + CumulusXcm: cumulus_pallet_xcm, + MessageQueue: pallet_message_queue, - Aura: pallet_aura::{Pallet, Storage, Config}, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config}, + Aura: pallet_aura, + AuraExt: cumulus_pallet_aura_ext, } } diff --git a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs index 37a8454d62a..d33f51df5a9 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs @@ -634,36 +634,34 @@ construct_runtime!( pub enum Runtime { // System support stuff. - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 3, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, + Timestamp: pallet_timestamp = 2, + ParachainInfo: parachain_info = 3, // Monetary stuff. - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 11, - AssetTxPayment: pallet_asset_tx_payment::{Pallet, Event} = 12, + Balances: pallet_balances = 10, + TransactionPayment: pallet_transaction_payment = 11, + AssetTxPayment: pallet_asset_tx_payment = 12, // Collator support. The order of these 4 are important and shall not change. - Authorship: pallet_authorship::{Pallet, Storage} = 20, - CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config} = 21, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22, - Aura: pallet_aura::{Pallet, Storage, Config} = 23, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24, + Authorship: pallet_authorship = 20, + CollatorSelection: pallet_collator_selection = 21, + Session: pallet_session = 22, + Aura: pallet_aura = 23, + AuraExt: cumulus_pallet_aura_ext = 24, // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin, Config} = 31, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 34, + XcmpQueue: cumulus_pallet_xcmp_queue = 30, + PolkadotXcm: pallet_xcm = 31, + CumulusXcm: cumulus_pallet_xcm = 32, + MessageQueue: pallet_message_queue = 34, // The main stage. - Assets: pallet_assets::::{Pallet, Call, Storage, Event} = 50, - ForeignAssets: pallet_assets::::{Pallet, Call, Storage, Event} = 51, + Assets: pallet_assets:: = 50, + ForeignAssets: pallet_assets:: = 51, - Sudo: pallet_sudo::{Pallet, Call, Storage, Event, Config} = 255, + Sudo: pallet_sudo = 255, } ); diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs index 795efa39247..999cc480ce0 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs @@ -603,30 +603,28 @@ impl pallet_aura::Config for Runtime { construct_runtime! { pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - Sudo: pallet_sudo::{Pallet, Call, Storage, Config, Event}, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, + System: frame_system, + Timestamp: pallet_timestamp, + Sudo: pallet_sudo, + TransactionPayment: pallet_transaction_payment, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 20, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21, + ParachainSystem: cumulus_pallet_parachain_system = 20, + ParachainInfo: parachain_info = 21, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 30, - Assets: pallet_assets::{Pallet, Call, Storage, Event} = 31, + Balances: pallet_balances = 30, + Assets: pallet_assets = 31, - Aura: pallet_aura::{Pallet, Config}, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Config}, + Aura: pallet_aura, + AuraExt: cumulus_pallet_aura_ext, // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 50, - PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin, Config} = 51, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event, Origin} = 52, + XcmpQueue: cumulus_pallet_xcmp_queue = 50, + PolkadotXcm: pallet_xcm = 51, + CumulusXcm: cumulus_pallet_xcm = 52, // RIP DmpQueue 53 - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 54, + MessageQueue: pallet_message_queue = 54, - Spambot: cumulus_ping::{Pallet, Call, Storage, Event} = 99, + Spambot: cumulus_ping = 99, } } diff --git a/docs/sdk/src/guides/your_first_pallet/mod.rs b/docs/sdk/src/guides/your_first_pallet/mod.rs index 24eada44a83..ea23af51ec9 100644 --- a/docs/sdk/src/guides/your_first_pallet/mod.rs +++ b/docs/sdk/src/guides/your_first_pallet/mod.rs @@ -428,8 +428,8 @@ pub mod pallet { use crate::guides::your_first_pallet::pallet as pallet_currency; construct_runtime!( - pub struct Runtime { - // ---^^^^^^ This is where `struct Runtime` is defined. + pub enum Runtime { + // ---^^^^^^ This is where `enum Runtime` is defined. System: frame_system, Currency: pallet_currency, } @@ -708,7 +708,7 @@ pub mod pallet_v2 { use crate::guides::your_first_pallet::pallet_v2 as pallet_currency; construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, Currency: pallet_currency, } diff --git a/docs/sdk/src/polkadot_sdk/cumulus.rs b/docs/sdk/src/polkadot_sdk/cumulus.rs index 07a48c92d80..60c4839f9e2 100644 --- a/docs/sdk/src/polkadot_sdk/cumulus.rs +++ b/docs/sdk/src/polkadot_sdk/cumulus.rs @@ -55,7 +55,7 @@ mod tests { #[docify::export(CR)] construct_runtime!( - pub struct Runtime { + pub enum Runtime { // system-level pallets. System: frame_system, Timestamp: pallet_timestamp, diff --git a/docs/sdk/src/polkadot_sdk/frame_runtime.rs b/docs/sdk/src/polkadot_sdk/frame_runtime.rs index 32dc2045e3a..c9eba7d64bd 100644 --- a/docs/sdk/src/polkadot_sdk/frame_runtime.rs +++ b/docs/sdk/src/polkadot_sdk/frame_runtime.rs @@ -156,9 +156,9 @@ mod tests { use super::pallet as pallet_example; use frame::{prelude::*, testing_prelude::*}; - // The major macro that amalgamates pallets into `struct Runtime` + // The major macro that amalgamates pallets into `enum Runtime` construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, Example: pallet_example, } diff --git a/polkadot/runtime/common/src/assigned_slots/mod.rs b/polkadot/runtime/common/src/assigned_slots/mod.rs index de8c00df9dd..9976a7be548 100644 --- a/polkadot/runtime/common/src/assigned_slots/mod.rs +++ b/polkadot/runtime/common/src/assigned_slots/mod.rs @@ -658,13 +658,13 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Configuration: parachains_configuration::{Pallet, Call, Storage, Config}, - ParasShared: parachains_shared::{Pallet, Call, Storage}, - Parachains: parachains_paras::{Pallet, Call, Storage, Config, Event}, - Slots: slots::{Pallet, Call, Storage, Event}, - AssignedSlots: assigned_slots::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Configuration: parachains_configuration, + ParasShared: parachains_shared, + Parachains: parachains_paras, + Slots: slots, + AssignedSlots: assigned_slots, } ); diff --git a/polkadot/runtime/common/src/auctions.rs b/polkadot/runtime/common/src/auctions.rs index baa66d83a3f..0bd5ed1e733 100644 --- a/polkadot/runtime/common/src/auctions.rs +++ b/polkadot/runtime/common/src/auctions.rs @@ -697,9 +697,9 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Auctions: auctions::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Auctions: auctions, } ); diff --git a/polkadot/runtime/common/src/claims.rs b/polkadot/runtime/common/src/claims.rs index 4cddab969c0..5b87cc9619e 100644 --- a/polkadot/runtime/common/src/claims.rs +++ b/polkadot/runtime/common/src/claims.rs @@ -727,10 +727,10 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Vesting: pallet_vesting::{Pallet, Call, Storage, Config, Event}, - Claims: claims::{Pallet, Call, Storage, Config, Event, ValidateUnsigned}, + System: frame_system, + Balances: pallet_balances, + Vesting: pallet_vesting, + Claims: claims, } ); diff --git a/polkadot/runtime/common/src/crowdloan/mod.rs b/polkadot/runtime/common/src/crowdloan/mod.rs index 77ef406e579..b7dd06aee3a 100644 --- a/polkadot/runtime/common/src/crowdloan/mod.rs +++ b/polkadot/runtime/common/src/crowdloan/mod.rs @@ -888,9 +888,9 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Crowdloan: crowdloan::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Crowdloan: crowdloan, } ); diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index a9edb196627..79ace0972ad 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -242,10 +242,10 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Authorship: pallet_authorship::{Pallet, Storage}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event}, + System: frame_system, + Authorship: pallet_authorship, + Balances: pallet_balances, + Treasury: pallet_treasury, } ); diff --git a/polkadot/runtime/common/src/integration_tests.rs b/polkadot/runtime/common/src/integration_tests.rs index b536b80e245..2bf21bbde95 100644 --- a/polkadot/runtime/common/src/integration_tests.rs +++ b/polkadot/runtime/common/src/integration_tests.rs @@ -74,25 +74,25 @@ frame_support::construct_runtime!( pub enum Test { // System Stuff - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Babe: pallet_babe::{Pallet, Call, Storage, Config, ValidateUnsigned}, + System: frame_system, + Balances: pallet_balances, + Babe: pallet_babe, // Parachains Runtime - Configuration: configuration::{Pallet, Call, Storage, Config}, - Paras: paras::{Pallet, Call, Storage, Event, Config}, - ParasShared: shared::{Pallet, Call, Storage}, - ParachainsOrigin: origin::{Pallet, Origin}, + Configuration: configuration, + Paras: paras, + ParasShared: shared, + ParachainsOrigin: origin, // Para Onboarding Pallets - Registrar: paras_registrar::{Pallet, Call, Storage, Event}, - Auctions: auctions::{Pallet, Call, Storage, Event}, - Crowdloan: crowdloan::{Pallet, Call, Storage, Event}, - Slots: slots::{Pallet, Call, Storage, Event}, + Registrar: paras_registrar, + Auctions: auctions, + Crowdloan: crowdloan, + Slots: slots, // Migrators - Identity: pallet_identity::{Pallet, Call, Storage, Event}, - IdentityMigrator: identity_migrator::{Pallet, Call, Event}, + Identity: pallet_identity, + IdentityMigrator: identity_migrator, } ); diff --git a/polkadot/runtime/common/src/paras_registrar/mod.rs b/polkadot/runtime/common/src/paras_registrar/mod.rs index 448490b34a7..a3bdc1b1b0f 100644 --- a/polkadot/runtime/common/src/paras_registrar/mod.rs +++ b/polkadot/runtime/common/src/paras_registrar/mod.rs @@ -724,13 +724,13 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Configuration: configuration::{Pallet, Call, Storage, Config}, - Parachains: paras::{Pallet, Call, Storage, Config, Event}, - ParasShared: shared::{Pallet, Call, Storage}, - Registrar: paras_registrar::{Pallet, Call, Storage, Event}, - ParachainsOrigin: origin::{Pallet, Origin}, + System: frame_system, + Balances: pallet_balances, + Configuration: configuration, + Parachains: paras, + ParasShared: shared, + Registrar: paras_registrar, + ParachainsOrigin: origin, } ); diff --git a/polkadot/runtime/common/src/purchase.rs b/polkadot/runtime/common/src/purchase.rs index f43f16b838c..146a90fca86 100644 --- a/polkadot/runtime/common/src/purchase.rs +++ b/polkadot/runtime/common/src/purchase.rs @@ -499,10 +499,10 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Vesting: pallet_vesting::{Pallet, Call, Storage, Config, Event}, - Purchase: purchase::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Vesting: pallet_vesting, + Purchase: purchase, } ); diff --git a/polkadot/runtime/common/src/slots/mod.rs b/polkadot/runtime/common/src/slots/mod.rs index 58bd1d53aed..be02aa9961c 100644 --- a/polkadot/runtime/common/src/slots/mod.rs +++ b/polkadot/runtime/common/src/slots/mod.rs @@ -520,9 +520,9 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Slots: slots::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Slots: slots, } ); diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 51c00336bef..2d49f0b99e9 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -1315,135 +1315,131 @@ construct_runtime! { pub enum Runtime { // Basic stuff; balances is uncallable initially. - System: frame_system::{Pallet, Call, Storage, Config, Event} = 0, + System: frame_system = 0, // Babe must be before session. - Babe: pallet_babe::{Pallet, Call, Storage, Config, ValidateUnsigned} = 1, + Babe: pallet_babe = 1, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2, - Indices: pallet_indices::{Pallet, Call, Storage, Config, Event} = 3, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 4, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 33, + Timestamp: pallet_timestamp = 2, + Indices: pallet_indices = 3, + Balances: pallet_balances = 4, + TransactionPayment: pallet_transaction_payment = 33, // Consensus support. // Authorship must be before session in order to note author in the correct session and era. - Authorship: pallet_authorship::{Pallet, Storage} = 5, - Offences: pallet_offences::{Pallet, Storage, Event} = 7, - Historical: session_historical::{Pallet} = 34, + Authorship: pallet_authorship = 5, + Offences: pallet_offences = 7, + Historical: session_historical = 34, // BEEFY Bridges support. - Beefy: pallet_beefy::{Pallet, Call, Storage, Config, ValidateUnsigned} = 240, + Beefy: pallet_beefy = 240, // MMR leaf construction must be before session in order to have leaf contents // refer to block consistently. see substrate issue #11797 for details. - Mmr: pallet_mmr::{Pallet, Storage} = 241, - MmrLeaf: pallet_beefy_mmr::{Pallet, Storage} = 242, + Mmr: pallet_mmr = 241, + MmrLeaf: pallet_beefy_mmr = 242, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 8, - Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event, ValidateUnsigned} = 10, - AuthorityDiscovery: pallet_authority_discovery::{Pallet, Config} = 12, + Session: pallet_session = 8, + Grandpa: pallet_grandpa = 10, + AuthorityDiscovery: pallet_authority_discovery = 12, // Governance stuff; uncallable initially. - Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event} = 18, - ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event} = 20, - Referenda: pallet_referenda::{Pallet, Call, Storage, Event} = 21, + Treasury: pallet_treasury = 18, + ConvictionVoting: pallet_conviction_voting = 20, + Referenda: pallet_referenda = 21, // pub type FellowshipCollectiveInstance = pallet_ranked_collective::Instance1; - FellowshipCollective: pallet_ranked_collective::::{ - Pallet, Call, Storage, Event - } = 22, + FellowshipCollective: pallet_ranked_collective:: = 22, // pub type FellowshipReferendaInstance = pallet_referenda::Instance2; - FellowshipReferenda: pallet_referenda::::{ - Pallet, Call, Storage, Event - } = 23, - Origins: pallet_custom_origins::{Origin} = 43, - Whitelist: pallet_whitelist::{Pallet, Call, Storage, Event} = 44, + FellowshipReferenda: pallet_referenda:: = 23, + Origins: pallet_custom_origins = 43, + Whitelist: pallet_whitelist = 44, // Claims. Usable initially. - Claims: claims::{Pallet, Call, Storage, Event, Config, ValidateUnsigned} = 19, + Claims: claims = 19, // Utility module. - Utility: pallet_utility::{Pallet, Call, Event} = 24, + Utility: pallet_utility = 24, // Less simple identity module. - Identity: pallet_identity::{Pallet, Call, Storage, Event} = 25, + Identity: pallet_identity = 25, // Society module. - Society: pallet_society::{Pallet, Call, Storage, Event} = 26, + Society: pallet_society = 26, // Social recovery module. - Recovery: pallet_recovery::{Pallet, Call, Storage, Event} = 27, + Recovery: pallet_recovery = 27, // Vesting. Usable initially, but removed once all vesting is finished. - Vesting: pallet_vesting::{Pallet, Call, Storage, Event, Config} = 28, + Vesting: pallet_vesting = 28, // System scheduler. - Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event} = 29, + Scheduler: pallet_scheduler = 29, // Proxy module. Late addition. - Proxy: pallet_proxy::{Pallet, Call, Storage, Event} = 30, + Proxy: pallet_proxy = 30, // Multisig module. Late addition. - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 31, + Multisig: pallet_multisig = 31, // Preimage registrar. - Preimage: pallet_preimage::{Pallet, Call, Storage, Event, HoldReason} = 32, + Preimage: pallet_preimage = 32, // Asset rate. - AssetRate: pallet_asset_rate::{Pallet, Call, Storage, Event} = 39, + AssetRate: pallet_asset_rate = 39, // Bounties modules. - Bounties: pallet_bounties::{Pallet, Call, Storage, Event} = 35, + Bounties: pallet_bounties = 35, ChildBounties: pallet_child_bounties = 40, // NIS pallet. - Nis: pallet_nis::{Pallet, Call, Storage, Event, HoldReason} = 38, + Nis: pallet_nis = 38, // pub type NisCounterpartInstance = pallet_balances::Instance2; NisCounterpartBalances: pallet_balances:: = 45, // Parachains pallets. Start indices at 50 to leave room. - ParachainsOrigin: parachains_origin::{Pallet, Origin} = 50, - Configuration: parachains_configuration::{Pallet, Call, Storage, Config} = 51, - ParasShared: parachains_shared::{Pallet, Call, Storage} = 52, - ParaInclusion: parachains_inclusion::{Pallet, Call, Storage, Event} = 53, - ParaInherent: parachains_paras_inherent::{Pallet, Call, Storage, Inherent} = 54, - ParaScheduler: parachains_scheduler::{Pallet, Storage} = 55, - Paras: parachains_paras::{Pallet, Call, Storage, Event, Config, ValidateUnsigned} = 56, - Initializer: parachains_initializer::{Pallet, Call, Storage} = 57, - Dmp: parachains_dmp::{Pallet, Storage} = 58, - Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event, Config} = 60, - ParaSessionInfo: parachains_session_info::{Pallet, Storage} = 61, - ParasDisputes: parachains_disputes::{Pallet, Call, Storage, Event} = 62, - ParasSlashing: parachains_slashing::{Pallet, Call, Storage, ValidateUnsigned} = 63, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 64, - OnDemandAssignmentProvider: parachains_assigner_on_demand::{Pallet, Call, Storage, Event} = 66, - ParachainsAssignmentProvider: parachains_assigner_parachains::{Pallet} = 67, - CoretimeAssignmentProvider: parachains_assigner_coretime::{Pallet, Storage} = 68, + ParachainsOrigin: parachains_origin = 50, + Configuration: parachains_configuration = 51, + ParasShared: parachains_shared = 52, + ParaInclusion: parachains_inclusion = 53, + ParaInherent: parachains_paras_inherent = 54, + ParaScheduler: parachains_scheduler = 55, + Paras: parachains_paras = 56, + Initializer: parachains_initializer = 57, + Dmp: parachains_dmp = 58, + Hrmp: parachains_hrmp = 60, + ParaSessionInfo: parachains_session_info = 61, + ParasDisputes: parachains_disputes = 62, + ParasSlashing: parachains_slashing = 63, + MessageQueue: pallet_message_queue = 64, + OnDemandAssignmentProvider: parachains_assigner_on_demand = 66, + ParachainsAssignmentProvider: parachains_assigner_parachains = 67, + CoretimeAssignmentProvider: parachains_assigner_coretime = 68, // Parachain Onboarding Pallets. Start indices at 70 to leave room. - Registrar: paras_registrar::{Pallet, Call, Storage, Event, Config} = 70, - Slots: slots::{Pallet, Call, Storage, Event} = 71, - Auctions: auctions::{Pallet, Call, Storage, Event} = 72, - Crowdloan: crowdloan::{Pallet, Call, Storage, Event} = 73, - Coretime: coretime::{Pallet, Call, Event} = 74, + Registrar: paras_registrar = 70, + Slots: slots = 71, + Auctions: auctions = 72, + Crowdloan: crowdloan = 73, + Coretime: coretime = 74, // Pallet for sending XCM. - XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 99, + XcmPallet: pallet_xcm = 99, // Pallet for migrating Identity to a parachain. To be removed post-migration. - IdentityMigrator: identity_migrator::{Pallet, Call, Event} = 248, + IdentityMigrator: identity_migrator = 248, - ParasSudoWrapper: paras_sudo_wrapper::{Pallet, Call} = 250, - AssignedSlots: assigned_slots::{Pallet, Call, Storage, Event, Config} = 251, + ParasSudoWrapper: paras_sudo_wrapper = 250, + AssignedSlots: assigned_slots = 251, // Validator Manager pallet. - ValidatorManager: validator_manager::{Pallet, Call, Storage, Event} = 252, + ValidatorManager: validator_manager = 252, // State trie migration pallet, only temporary. StateTrieMigration: pallet_state_trie_migration = 254, // Root testing pallet. - RootTesting: pallet_root_testing::{Pallet, Call, Storage, Event} = 249, + RootTesting: pallet_root_testing = 249, // Sudo. - Sudo: pallet_sudo::{Pallet, Call, Storage, Event, Config} = 255, + Sudo: pallet_sudo = 255, } } diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index 18bcb16834e..51c199b7a05 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -670,52 +670,52 @@ construct_runtime! { pub enum Runtime { // Basic stuff; balances is uncallable initially. - System: frame_system::{Pallet, Call, Storage, Config, Event}, + System: frame_system, // Must be before session. - Babe: pallet_babe::{Pallet, Call, Storage, Config}, + Babe: pallet_babe, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - Indices: pallet_indices::{Pallet, Call, Storage, Config, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, + Timestamp: pallet_timestamp, + Indices: pallet_indices, + Balances: pallet_balances, + TransactionPayment: pallet_transaction_payment, // Consensus support. - Authorship: pallet_authorship::{Pallet, Storage}, - Staking: pallet_staking::{Pallet, Call, Storage, Config, Event}, - Offences: pallet_offences::{Pallet, Storage, Event}, - Historical: session_historical::{Pallet}, - Session: pallet_session::{Pallet, Call, Storage, Event, Config}, - Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event}, - AuthorityDiscovery: pallet_authority_discovery::{Pallet, Config}, + Authorship: pallet_authorship, + Staking: pallet_staking, + Offences: pallet_offences, + Historical: session_historical, + Session: pallet_session, + Grandpa: pallet_grandpa, + AuthorityDiscovery: pallet_authority_discovery, // Claims. Usable initially. - Claims: claims::{Pallet, Call, Storage, Event, Config, ValidateUnsigned}, + Claims: claims, // Vesting. Usable initially, but removed once all vesting is finished. - Vesting: pallet_vesting::{Pallet, Call, Storage, Event, Config}, + Vesting: pallet_vesting, // Parachains runtime modules - Configuration: parachains_configuration::{Pallet, Call, Storage, Config}, - ParaInclusion: parachains_inclusion::{Pallet, Call, Storage, Event}, - ParaInherent: parachains_paras_inherent::{Pallet, Call, Storage, Inherent}, - Initializer: parachains_initializer::{Pallet, Call, Storage}, - Paras: parachains_paras::{Pallet, Call, Storage, Event, ValidateUnsigned}, - ParasShared: parachains_shared::{Pallet, Call, Storage}, - Scheduler: parachains_scheduler::{Pallet, Storage}, - ParasSudoWrapper: paras_sudo_wrapper::{Pallet, Call}, - ParasOrigin: parachains_origin::{Pallet, Origin}, - ParaSessionInfo: parachains_session_info::{Pallet, Storage}, - Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event}, - Dmp: parachains_dmp::{Pallet, Storage}, - Xcm: pallet_xcm::{Pallet, Call, Event, Origin}, - ParasDisputes: parachains_disputes::{Pallet, Storage, Event}, - ParasSlashing: parachains_slashing::{Pallet, Call, Storage, ValidateUnsigned}, - ParaAssignmentProvider: parachains_assigner_parachains::{Pallet}, - - Sudo: pallet_sudo::{Pallet, Call, Storage, Config, Event}, - - TestNotifier: pallet_test_notifier::{Pallet, Call, Event}, + Configuration: parachains_configuration, + ParaInclusion: parachains_inclusion, + ParaInherent: parachains_paras_inherent, + Initializer: parachains_initializer, + Paras: parachains_paras, + ParasShared: parachains_shared, + Scheduler: parachains_scheduler, + ParasSudoWrapper: paras_sudo_wrapper, + ParasOrigin: parachains_origin, + ParaSessionInfo: parachains_session_info, + Hrmp: parachains_hrmp, + Dmp: parachains_dmp, + Xcm: pallet_xcm, + ParasDisputes: parachains_disputes, + ParasSlashing: parachains_slashing, + ParaAssignmentProvider: parachains_assigner_parachains, + + Sudo: pallet_sudo, + + TestNotifier: pallet_test_notifier, } } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 941193ba941..adfb2083254 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -1397,121 +1397,121 @@ construct_runtime! { pub enum Runtime { // Basic stuff; balances is uncallable initially. - System: frame_system::{Pallet, Call, Storage, Config, Event} = 0, + System: frame_system = 0, // Babe must be before session. - Babe: pallet_babe::{Pallet, Call, Storage, Config, ValidateUnsigned} = 1, + Babe: pallet_babe = 1, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2, - Indices: pallet_indices::{Pallet, Call, Storage, Config, Event} = 3, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 4, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 26, + Timestamp: pallet_timestamp = 2, + Indices: pallet_indices = 3, + Balances: pallet_balances = 4, + TransactionPayment: pallet_transaction_payment = 26, // Consensus support. // Authorship must be before session in order to note author in the correct session and era. - Authorship: pallet_authorship::{Pallet, Storage} = 5, - Staking: pallet_staking::{Pallet, Call, Storage, Config, Event} = 6, - Offences: pallet_offences::{Pallet, Storage, Event} = 7, - Historical: session_historical::{Pallet} = 27, + Authorship: pallet_authorship = 5, + Staking: pallet_staking = 6, + Offences: pallet_offences = 7, + Historical: session_historical = 27, // BEEFY Bridges support. - Beefy: pallet_beefy::{Pallet, Call, Storage, Config, ValidateUnsigned} = 200, - // MMR leaf construction must be before session in order to have leaf contents - // refer to block consistently. see substrate issue #11797 for details. - Mmr: pallet_mmr::{Pallet, Storage} = 201, - BeefyMmrLeaf: pallet_beefy_mmr::{Pallet, Storage} = 202, + Beefy: pallet_beefy = 200, + // MMR leaf construction must be before session in order to have leaf contents refer to + // block consistently. see substrate issue #11797 for details. + Mmr: pallet_mmr = 201, + BeefyMmrLeaf: pallet_beefy_mmr = 202, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 8, - Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event, ValidateUnsigned} = 10, - AuthorityDiscovery: pallet_authority_discovery::{Pallet, Config} = 12, + Session: pallet_session = 8, + Grandpa: pallet_grandpa = 10, + AuthorityDiscovery: pallet_authority_discovery = 12, // Utility module. - Utility: pallet_utility::{Pallet, Call, Event} = 16, + Utility: pallet_utility = 16, // Less simple identity module. - Identity: pallet_identity::{Pallet, Call, Storage, Event} = 17, + Identity: pallet_identity = 17, // Social recovery module. - Recovery: pallet_recovery::{Pallet, Call, Storage, Event} = 18, + Recovery: pallet_recovery = 18, // Vesting. Usable initially, but removed once all vesting is finished. - Vesting: pallet_vesting::{Pallet, Call, Storage, Event, Config} = 19, + Vesting: pallet_vesting = 19, // System scheduler. - Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event} = 20, + Scheduler: pallet_scheduler = 20, // Preimage registrar. - Preimage: pallet_preimage::{Pallet, Call, Storage, Event, HoldReason} = 28, + Preimage: pallet_preimage = 28, // Sudo. - Sudo: pallet_sudo::{Pallet, Call, Storage, Event, Config} = 21, + Sudo: pallet_sudo = 21, // Proxy module. Late addition. - Proxy: pallet_proxy::{Pallet, Call, Storage, Event} = 22, + Proxy: pallet_proxy = 22, // Multisig module. Late addition. - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 23, + Multisig: pallet_multisig = 23, // Election pallet. Only works with staking, but placed here to maintain indices. - ElectionProviderMultiPhase: pallet_election_provider_multi_phase::{Pallet, Call, Storage, Event, ValidateUnsigned} = 24, + ElectionProviderMultiPhase: pallet_election_provider_multi_phase = 24, // Provides a semi-sorted list of nominators for staking. - VoterList: pallet_bags_list::::{Pallet, Call, Storage, Event} = 25, + VoterList: pallet_bags_list:: = 25, // Nomination pools for staking. - NominationPools: pallet_nomination_pools::{Pallet, Call, Storage, Event, Config, FreezeReason} = 29, + NominationPools: pallet_nomination_pools = 29, // Fast unstake pallet: extension to staking. FastUnstake: pallet_fast_unstake = 30, // OpenGov - ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event} = 31, - Referenda: pallet_referenda::{Pallet, Call, Storage, Event} = 32, - Origins: pallet_custom_origins::{Origin} = 35, - Whitelist: pallet_whitelist::{Pallet, Call, Storage, Event} = 36, + ConvictionVoting: pallet_conviction_voting = 31, + Referenda: pallet_referenda = 32, + Origins: pallet_custom_origins = 35, + Whitelist: pallet_whitelist = 36, // Treasury - Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event} = 37, + Treasury: pallet_treasury = 37, // Parachains pallets. Start indices at 40 to leave room. - ParachainsOrigin: parachains_origin::{Pallet, Origin} = 41, - Configuration: parachains_configuration::{Pallet, Call, Storage, Config} = 42, - ParasShared: parachains_shared::{Pallet, Call, Storage} = 43, - ParaInclusion: parachains_inclusion::{Pallet, Call, Storage, Event} = 44, - ParaInherent: parachains_paras_inherent::{Pallet, Call, Storage, Inherent} = 45, - ParaScheduler: parachains_scheduler::{Pallet, Storage} = 46, - Paras: parachains_paras::{Pallet, Call, Storage, Event, Config, ValidateUnsigned} = 47, - Initializer: parachains_initializer::{Pallet, Call, Storage} = 48, - Dmp: parachains_dmp::{Pallet, Storage} = 49, + ParachainsOrigin: parachains_origin = 41, + Configuration: parachains_configuration = 42, + ParasShared: parachains_shared = 43, + ParaInclusion: parachains_inclusion = 44, + ParaInherent: parachains_paras_inherent = 45, + ParaScheduler: parachains_scheduler = 46, + Paras: parachains_paras = 47, + Initializer: parachains_initializer = 48, + Dmp: parachains_dmp = 49, // RIP Ump 50 - Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event, Config} = 51, - ParaSessionInfo: parachains_session_info::{Pallet, Storage} = 52, - ParasDisputes: parachains_disputes::{Pallet, Call, Storage, Event} = 53, - ParasSlashing: parachains_slashing::{Pallet, Call, Storage, ValidateUnsigned} = 54, - ParachainsAssignmentProvider: parachains_assigner_parachains::{Pallet} = 55, + Hrmp: parachains_hrmp = 51, + ParaSessionInfo: parachains_session_info = 52, + ParasDisputes: parachains_disputes = 53, + ParasSlashing: parachains_slashing = 54, + ParachainsAssignmentProvider: parachains_assigner_parachains = 55, // Parachain Onboarding Pallets. Start indices at 60 to leave room. - Registrar: paras_registrar::{Pallet, Call, Storage, Event, Config} = 60, - Slots: slots::{Pallet, Call, Storage, Event} = 61, - ParasSudoWrapper: paras_sudo_wrapper::{Pallet, Call} = 62, - Auctions: auctions::{Pallet, Call, Storage, Event} = 63, - Crowdloan: crowdloan::{Pallet, Call, Storage, Event} = 64, - AssignedSlots: assigned_slots::{Pallet, Call, Storage, Event, Config} = 65, + Registrar: paras_registrar = 60, + Slots: slots = 61, + ParasSudoWrapper: paras_sudo_wrapper = 62, + Auctions: auctions = 63, + Crowdloan: crowdloan = 64, + AssignedSlots: assigned_slots = 65, // Pallet for sending XCM. - XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 99, + XcmPallet: pallet_xcm = 99, // Generalized message queue - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 100, + MessageQueue: pallet_message_queue = 100, // Asset rate. - AssetRate: pallet_asset_rate::{Pallet, Call, Storage, Event} = 101, + AssetRate: pallet_asset_rate = 101, // Root testing pallet. - RootTesting: pallet_root_testing::{Pallet, Call, Storage, Event} = 102, + RootTesting: pallet_root_testing = 102, // Pallet for migrating Identity to a parachain. To be removed post-migration. - IdentityMigrator: identity_migrator::{Pallet, Call, Event} = 248, + IdentityMigrator: identity_migrator = 248, } } diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs index bb4b7ff6276..f1d1b2fdef3 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs @@ -34,9 +34,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - XcmBalancesBenchmark: xcm_balances_benchmark::{Pallet}, + System: frame_system, + Balances: pallet_balances, + XcmBalancesBenchmark: xcm_balances_benchmark, } ); diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs index 4dd677217fc..656c675b630 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs @@ -39,9 +39,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - XcmGenericBenchmarks: generic::{Pallet}, + System: frame_system, + Balances: pallet_balances, + XcmGenericBenchmarks: generic, } ); diff --git a/polkadot/xcm/pallet-xcm/src/mock.rs b/polkadot/xcm/pallet-xcm/src/mock.rs index 3ce32fa46d3..1ca30963d59 100644 --- a/polkadot/xcm/pallet-xcm/src/mock.rs +++ b/polkadot/xcm/pallet-xcm/src/mock.rs @@ -139,12 +139,12 @@ pub mod pallet_test_notifier { construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - AssetsPallet: pallet_assets::{Pallet, Call, Storage, Config, Event}, - ParasOrigin: origin::{Pallet, Origin}, - XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config}, - TestNotifier: pallet_test_notifier::{Pallet, Call, Event}, + System: frame_system, + Balances: pallet_balances, + AssetsPallet: pallet_assets, + ParasOrigin: origin, + XcmPallet: pallet_xcm, + TestNotifier: pallet_test_notifier, } ); diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs index 01ff8c29f3d..76198f84ed6 100644 --- a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs +++ b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs @@ -40,7 +40,7 @@ pub type BlockNumber = u32; pub type AccountId = AccountId32; construct_runtime!( - pub struct Test { + pub enum Test { System: frame_system, Balances: pallet_balances, Assets: pallet_assets, diff --git a/polkadot/xcm/xcm-builder/tests/mock/mod.rs b/polkadot/xcm/xcm-builder/tests/mock/mod.rs index 2e89313a68e..73df22561d1 100644 --- a/polkadot/xcm/xcm-builder/tests/mock/mod.rs +++ b/polkadot/xcm/xcm-builder/tests/mock/mod.rs @@ -250,10 +250,10 @@ type Block = frame_system::mocking::MockBlock; construct_runtime!( pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - ParasOrigin: origin::{Pallet, Origin}, - XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin}, + System: frame_system, + Balances: pallet_balances, + ParasOrigin: origin, + XcmPallet: pallet_xcm, } ); diff --git a/polkadot/xcm/xcm-simulator/example/src/parachain.rs b/polkadot/xcm/xcm-simulator/example/src/parachain.rs index 0b6c573f464..3adfa95d2e8 100644 --- a/polkadot/xcm/xcm-simulator/example/src/parachain.rs +++ b/polkadot/xcm/xcm-simulator/example/src/parachain.rs @@ -457,10 +457,10 @@ type Block = frame_system::mocking::MockBlock; construct_runtime!( pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - MsgQueue: mock_msg_queue::{Pallet, Storage, Event}, - PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin}, - ForeignUniques: pallet_uniques::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + MsgQueue: mock_msg_queue, + PolkadotXcm: pallet_xcm, + ForeignUniques: pallet_uniques, } ); diff --git a/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs index 946b932b05e..d9ed6e800aa 100644 --- a/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs +++ b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs @@ -281,11 +281,11 @@ impl pallet_message_queue::Config for Runtime { construct_runtime!( pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - ParasOrigin: origin::{Pallet, Origin}, - XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin}, - Uniques: pallet_uniques::{Pallet, Call, Storage, Event}, - MessageQueue: pallet_message_queue::{Pallet, Event}, + System: frame_system, + Balances: pallet_balances, + ParasOrigin: origin, + XcmPallet: pallet_xcm, + Uniques: pallet_uniques, + MessageQueue: pallet_message_queue, } ); diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs index 41fc5af9708..8a89f8cb0e7 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs @@ -360,9 +360,9 @@ type Block = frame_system::mocking::MockBlock; construct_runtime!( pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - MsgQueue: mock_msg_queue::{Pallet, Storage, Event}, - PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin}, + System: frame_system, + Balances: pallet_balances, + MsgQueue: mock_msg_queue, + PolkadotXcm: pallet_xcm, } ); diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs index d3f91b01317..143f8974f3e 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs @@ -252,10 +252,10 @@ impl pallet_message_queue::Config for Runtime { construct_runtime!( pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - ParasOrigin: origin::{Pallet, Origin}, - XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin}, - MessageQueue: pallet_message_queue::{Pallet, Event}, + System: frame_system, + Balances: pallet_balances, + ParasOrigin: origin, + XcmPallet: pallet_xcm, + MessageQueue: pallet_message_queue, } ); diff --git a/substrate/bin/minimal/runtime/src/lib.rs b/substrate/bin/minimal/runtime/src/lib.rs index efee400c3f5..610289693d9 100644 --- a/substrate/bin/minimal/runtime/src/lib.rs +++ b/substrate/bin/minimal/runtime/src/lib.rs @@ -63,7 +63,7 @@ type SignedExtra = ( ); construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, Timestamp: pallet_timestamp, diff --git a/substrate/bin/node-template/runtime/src/lib.rs b/substrate/bin/node-template/runtime/src/lib.rs index 5f399edda98..e9ccd5697df 100644 --- a/substrate/bin/node-template/runtime/src/lib.rs +++ b/substrate/bin/node-template/runtime/src/lib.rs @@ -258,7 +258,7 @@ impl pallet_template::Config for Runtime { // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, Timestamp: pallet_timestamp, Aura: pallet_aura, diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 1043e5017dc..d7598adb5a2 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -2083,8 +2083,7 @@ impl pallet_mixnet::Config for Runtime { } construct_runtime!( - pub struct Runtime - { + pub enum Runtime { System: frame_system, Utility: pallet_utility, Babe: pallet_babe, @@ -2099,11 +2098,11 @@ construct_runtime!( AssetConversionTxPayment: pallet_asset_conversion_tx_payment, ElectionProviderMultiPhase: pallet_election_provider_multi_phase, Staking: pallet_staking, - Beefy: pallet_beefy::{Pallet, Call, Storage, Config, ValidateUnsigned}, + Beefy: pallet_beefy, // MMR leaf construction must be before session in order to have leaf contents // refer to block consistently. see substrate issue #11797 for details. - Mmr: pallet_mmr::{Pallet, Storage}, - MmrLeaf: pallet_beefy_mmr::{Pallet, Storage}, + Mmr: pallet_mmr, + MmrLeaf: pallet_beefy_mmr, Session: pallet_session, Democracy: pallet_democracy, Council: pallet_collective::, @@ -2118,7 +2117,7 @@ construct_runtime!( ImOnline: pallet_im_online, AuthorityDiscovery: pallet_authority_discovery, Offences: pallet_offences, - Historical: pallet_session_historical::{Pallet}, + Historical: pallet_session_historical, RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip, Identity: pallet_identity, Society: pallet_society, diff --git a/substrate/frame/assets/src/mock.rs b/substrate/frame/assets/src/mock.rs index a4d85b64922..d60f5358336 100644 --- a/substrate/frame/assets/src/mock.rs +++ b/substrate/frame/assets/src/mock.rs @@ -37,9 +37,9 @@ type Block = frame_system::mocking::MockBlock; construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Assets: pallet_assets::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Assets: pallet_assets, } ); diff --git a/substrate/frame/atomic-swap/src/tests.rs b/substrate/frame/atomic-swap/src/tests.rs index 7e2f22b1836..58502aa4f93 100644 --- a/substrate/frame/atomic-swap/src/tests.rs +++ b/substrate/frame/atomic-swap/src/tests.rs @@ -35,9 +35,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - AtomicSwap: pallet_atomic_swap::{Pallet, Call, Event}, + System: frame_system, + Balances: pallet_balances, + AtomicSwap: pallet_atomic_swap, } ); diff --git a/substrate/frame/aura/src/mock.rs b/substrate/frame/aura/src/mock.rs index d38a8583819..d87fea8fc81 100644 --- a/substrate/frame/aura/src/mock.rs +++ b/substrate/frame/aura/src/mock.rs @@ -35,9 +35,9 @@ const SLOT_DURATION: u64 = 2; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - Aura: pallet_aura::{Pallet, Storage, Config}, + System: frame_system, + Timestamp: pallet_timestamp, + Aura: pallet_aura, } ); diff --git a/substrate/frame/authority-discovery/src/lib.rs b/substrate/frame/authority-discovery/src/lib.rs index 3044b41e31d..640c0c8759e 100644 --- a/substrate/frame/authority-discovery/src/lib.rs +++ b/substrate/frame/authority-discovery/src/lib.rs @@ -187,9 +187,9 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Session: pallet_session::{Pallet, Call, Storage, Event, Config}, - AuthorityDiscovery: pallet_authority_discovery::{Pallet, Config}, + System: frame_system, + Session: pallet_session, + AuthorityDiscovery: pallet_authority_discovery, } ); diff --git a/substrate/frame/authorship/src/lib.rs b/substrate/frame/authorship/src/lib.rs index 56a516894de..8b38a58d8e7 100644 --- a/substrate/frame/authorship/src/lib.rs +++ b/substrate/frame/authorship/src/lib.rs @@ -108,8 +108,8 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Authorship: pallet_authorship::{Pallet, Storage}, + System: frame_system, + Authorship: pallet_authorship, } ); diff --git a/substrate/frame/bags-list/src/mock.rs b/substrate/frame/bags-list/src/mock.rs index 9946a2198ac..4282120983b 100644 --- a/substrate/frame/bags-list/src/mock.rs +++ b/substrate/frame/bags-list/src/mock.rs @@ -68,10 +68,9 @@ impl bags_list::Config for Runtime { type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Storage, Event, Config}, - BagsList: bags_list::{Pallet, Call, Storage, Event}, + pub enum Runtime { + System: frame_system, + BagsList: bags_list, } ); diff --git a/substrate/frame/balances/src/tests/mod.rs b/substrate/frame/balances/src/tests/mod.rs index 8e834483cbe..708e081fe0b 100644 --- a/substrate/frame/balances/src/tests/mod.rs +++ b/substrate/frame/balances/src/tests/mod.rs @@ -75,11 +75,10 @@ impl VariantCount for TestId { } frame_support::construct_runtime!( - pub struct Test - { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, + pub enum Test { + System: frame_system, + Balances: pallet_balances, + TransactionPayment: pallet_transaction_payment, } ); diff --git a/substrate/frame/beefy-mmr/src/mock.rs b/substrate/frame/beefy-mmr/src/mock.rs index b85096813de..94149ac6776 100644 --- a/substrate/frame/beefy-mmr/src/mock.rs +++ b/substrate/frame/beefy-mmr/src/mock.rs @@ -49,11 +49,11 @@ type Block = frame_system::mocking::MockBlock; construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Session: pallet_session::{Pallet, Call, Storage, Event, Config}, - Mmr: pallet_mmr::{Pallet, Storage}, - Beefy: pallet_beefy::{Pallet, Config, Storage}, - BeefyMmr: pallet_beefy_mmr::{Pallet, Storage}, + System: frame_system, + Session: pallet_session, + Mmr: pallet_mmr, + Beefy: pallet_beefy, + BeefyMmr: pallet_beefy_mmr, } ); diff --git a/substrate/frame/benchmarking/pov/src/benchmarking.rs b/substrate/frame/benchmarking/pov/src/benchmarking.rs index a24b772ade0..84d81890b17 100644 --- a/substrate/frame/benchmarking/pov/src/benchmarking.rs +++ b/substrate/frame/benchmarking/pov/src/benchmarking.rs @@ -350,8 +350,8 @@ mod mock { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Baseline: crate::{Pallet, Call, Storage, Event}, + System: frame_system, + Baseline: crate, } ); diff --git a/substrate/frame/benchmarking/pov/src/tests.rs b/substrate/frame/benchmarking/pov/src/tests.rs index dda29c071de..7fa2fb97dea 100644 --- a/substrate/frame/benchmarking/pov/src/tests.rs +++ b/substrate/frame/benchmarking/pov/src/tests.rs @@ -170,8 +170,8 @@ mod mock { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Baseline: crate::{Pallet, Call, Storage, Event}, + System: frame_system, + Baseline: crate, } ); diff --git a/substrate/frame/benchmarking/src/baseline.rs b/substrate/frame/benchmarking/src/baseline.rs index 6451284e012..2fd3b634ae7 100644 --- a/substrate/frame/benchmarking/src/baseline.rs +++ b/substrate/frame/benchmarking/src/baseline.rs @@ -121,7 +121,7 @@ pub mod mock { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, + System: frame_system, } ); diff --git a/substrate/frame/benchmarking/src/tests.rs b/substrate/frame/benchmarking/src/tests.rs index 7d6cfaad609..f47a3d9f96a 100644 --- a/substrate/frame/benchmarking/src/tests.rs +++ b/substrate/frame/benchmarking/src/tests.rs @@ -70,8 +70,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - TestPallet: pallet_test::{Pallet, Call, Storage}, + System: frame_system, + TestPallet: pallet_test, } ); diff --git a/substrate/frame/benchmarking/src/tests_instance.rs b/substrate/frame/benchmarking/src/tests_instance.rs index 55010840896..c28aa694a13 100644 --- a/substrate/frame/benchmarking/src/tests_instance.rs +++ b/substrate/frame/benchmarking/src/tests_instance.rs @@ -80,8 +80,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - TestPallet: pallet_test::{Pallet, Call, Storage, Event}, + System: frame_system, + TestPallet: pallet_test, } ); diff --git a/substrate/frame/bounties/src/tests.rs b/substrate/frame/bounties/src/tests.rs index 22e608cce63..a7177393a44 100644 --- a/substrate/frame/bounties/src/tests.rs +++ b/substrate/frame/bounties/src/tests.rs @@ -44,12 +44,12 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Bounties: pallet_bounties::{Pallet, Call, Storage, Event}, - Bounties1: pallet_bounties::::{Pallet, Call, Storage, Event}, - Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event}, - Treasury1: pallet_treasury::::{Pallet, Call, Storage, Config, Event}, + System: frame_system, + Balances: pallet_balances, + Bounties: pallet_bounties, + Bounties1: pallet_bounties::, + Treasury: pallet_treasury, + Treasury1: pallet_treasury::, } ); diff --git a/substrate/frame/child-bounties/src/tests.rs b/substrate/frame/child-bounties/src/tests.rs index 7de45c73127..e57721adad0 100644 --- a/substrate/frame/child-bounties/src/tests.rs +++ b/substrate/frame/child-bounties/src/tests.rs @@ -46,11 +46,11 @@ type BountiesError = pallet_bounties::Error; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Bounties: pallet_bounties::{Pallet, Call, Storage, Event}, - Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event}, - ChildBounties: pallet_child_bounties::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Bounties: pallet_bounties, + Treasury: pallet_treasury, + ChildBounties: pallet_child_bounties, } ); diff --git a/substrate/frame/collective/src/tests.rs b/substrate/frame/collective/src/tests.rs index 06a91cf6fe9..dbc3fbe69b3 100644 --- a/substrate/frame/collective/src/tests.rs +++ b/substrate/frame/collective/src/tests.rs @@ -38,11 +38,11 @@ pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic}, - Collective: pallet_collective::::{Pallet, Call, Event, Origin, Config}, - CollectiveMajority: pallet_collective::::{Pallet, Call, Event, Origin, Config}, - DefaultCollective: pallet_collective::{Pallet, Call, Event, Origin, Config}, - Democracy: mock_democracy::{Pallet, Call, Event}, + System: frame_system, + Collective: pallet_collective::, + CollectiveMajority: pallet_collective::, + DefaultCollective: pallet_collective, + Democracy: mock_democracy, } ); @@ -176,6 +176,7 @@ impl ExtBuilder { pub fn build(self) -> sp_io::TestExternalities { let mut ext: sp_io::TestExternalities = RuntimeGenesisConfig { + system: frame_system::GenesisConfig::default(), collective: pallet_collective::GenesisConfig { members: self.collective_members, phantom: Default::default(), diff --git a/substrate/frame/contracts/mock-network/src/relay_chain.rs b/substrate/frame/contracts/mock-network/src/relay_chain.rs index abe907839d9..9671857fb78 100644 --- a/substrate/frame/contracts/mock-network/src/relay_chain.rs +++ b/substrate/frame/contracts/mock-network/src/relay_chain.rs @@ -233,10 +233,10 @@ impl pallet_message_queue::Config for Runtime { construct_runtime!( pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - ParasOrigin: origin::{Pallet, Origin}, - XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin}, - MessageQueue: pallet_message_queue::{Pallet, Event}, + System: frame_system, + Balances: pallet_balances, + ParasOrigin: origin, + XcmPallet: pallet_xcm, + MessageQueue: pallet_message_queue, } ); diff --git a/substrate/frame/contracts/src/tests.rs b/substrate/frame/contracts/src/tests.rs index 28fe3c2af49..81539591019 100644 --- a/substrate/frame/contracts/src/tests.rs +++ b/substrate/frame/contracts/src/tests.rs @@ -71,13 +71,13 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - Randomness: pallet_insecure_randomness_collective_flip::{Pallet, Storage}, - Utility: pallet_utility::{Pallet, Call, Storage, Event}, - Contracts: pallet_contracts::{Pallet, Call, Storage, Event, HoldReason}, - Proxy: pallet_proxy::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Timestamp: pallet_timestamp, + Randomness: pallet_insecure_randomness_collective_flip, + Utility: pallet_utility, + Contracts: pallet_contracts, + Proxy: pallet_proxy, Dummy: pallet_dummy } ); diff --git a/substrate/frame/conviction-voting/src/tests.rs b/substrate/frame/conviction-voting/src/tests.rs index 371d0364384..d7bac505a54 100644 --- a/substrate/frame/conviction-voting/src/tests.rs +++ b/substrate/frame/conviction-voting/src/tests.rs @@ -37,9 +37,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Voting: pallet_conviction_voting::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Voting: pallet_conviction_voting, } ); diff --git a/substrate/frame/core-fellowship/src/tests.rs b/substrate/frame/core-fellowship/src/tests.rs index c9098f2171f..838bd9bbdc8 100644 --- a/substrate/frame/core-fellowship/src/tests.rs +++ b/substrate/frame/core-fellowship/src/tests.rs @@ -41,8 +41,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - CoreFellowship: pallet_core_fellowship::{Pallet, Call, Storage, Event}, + System: frame_system, + CoreFellowship: pallet_core_fellowship, } ); diff --git a/substrate/frame/democracy/src/tests.rs b/substrate/frame/democracy/src/tests.rs index 00d8fedca0c..888d7e59614 100644 --- a/substrate/frame/democracy/src/tests.rs +++ b/substrate/frame/democracy/src/tests.rs @@ -55,11 +55,11 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + System: frame_system, + Balances: pallet_balances, Preimage: pallet_preimage, - Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event}, - Democracy: pallet_democracy::{Pallet, Call, Storage, Config, Event}, + Scheduler: pallet_scheduler, + Democracy: pallet_democracy, } ); diff --git a/substrate/frame/election-provider-multi-phase/src/mock.rs b/substrate/frame/election-provider-multi-phase/src/mock.rs index e7dd8acf36b..507e8f2c39b 100644 --- a/substrate/frame/election-provider-multi-phase/src/mock.rs +++ b/substrate/frame/election-provider-multi-phase/src/mock.rs @@ -54,11 +54,10 @@ pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Event, Config}, - Balances: pallet_balances::{Pallet, Call, Event, Config}, - MultiPhase: multi_phase::{Pallet, Call, Event}, + pub enum Runtime { + System: frame_system, + Balances: pallet_balances, + MultiPhase: multi_phase, } ); diff --git a/substrate/frame/election-provider-support/src/onchain.rs b/substrate/frame/election-provider-support/src/onchain.rs index 412aac45475..d937f42cb40 100644 --- a/substrate/frame/election-provider-support/src/onchain.rs +++ b/substrate/frame/election-provider-support/src/onchain.rs @@ -194,9 +194,8 @@ mod tests { pub type Block = sp_runtime::generic::Block; frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Event}, + pub enum Runtime { + System: frame_system, } ); diff --git a/substrate/frame/elections-phragmen/src/lib.rs b/substrate/frame/elections-phragmen/src/lib.rs index 5e50027e344..2b599ab5292 100644 --- a/substrate/frame/elections-phragmen/src/lib.rs +++ b/substrate/frame/elections-phragmen/src/lib.rs @@ -1454,9 +1454,9 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Event}, - Balances: pallet_balances::{Pallet, Call, Event, Config}, - Elections: elections_phragmen::{Pallet, Call, Event, Config}, + System: frame_system, + Balances: pallet_balances, + Elections: elections_phragmen, } ); @@ -1507,6 +1507,7 @@ mod tests { *m.borrow_mut() = self.genesis_members.iter().map(|(m, _)| *m).collect::>() }); let mut ext: sp_io::TestExternalities = RuntimeGenesisConfig { + system: frame_system::GenesisConfig::default(), balances: pallet_balances::GenesisConfig:: { balances: vec![ (1, 10 * self.balance_factor), diff --git a/substrate/frame/examples/basic/src/tests.rs b/substrate/frame/examples/basic/src/tests.rs index e00b1ac01b3..2a6fbf0f054 100644 --- a/substrate/frame/examples/basic/src/tests.rs +++ b/substrate/frame/examples/basic/src/tests.rs @@ -39,9 +39,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Example: pallet_example_basic::{Pallet, Call, Storage, Config, Event}, + System: frame_system, + Balances: pallet_balances, + Example: pallet_example_basic, } ); diff --git a/substrate/frame/examples/default-config/src/lib.rs b/substrate/frame/examples/default-config/src/lib.rs index f1611bca2ce..cd1653e6c76 100644 --- a/substrate/frame/examples/default-config/src/lib.rs +++ b/substrate/frame/examples/default-config/src/lib.rs @@ -143,7 +143,7 @@ pub mod tests { type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, DefaultPallet: pallet_default_config_example, } diff --git a/substrate/frame/examples/dev-mode/src/tests.rs b/substrate/frame/examples/dev-mode/src/tests.rs index 3acedcd0fd1..c1501a5b4cf 100644 --- a/substrate/frame/examples/dev-mode/src/tests.rs +++ b/substrate/frame/examples/dev-mode/src/tests.rs @@ -33,9 +33,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Example: pallet_dev_mode::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Example: pallet_dev_mode, } ); diff --git a/substrate/frame/examples/frame-crate/src/lib.rs b/substrate/frame/examples/frame-crate/src/lib.rs index 0fea2c22cf5..7e286df1e32 100644 --- a/substrate/frame/examples/frame-crate/src/lib.rs +++ b/substrate/frame/examples/frame-crate/src/lib.rs @@ -49,7 +49,7 @@ mod tests { use frame::testing_prelude::*; construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, MyPallet: my_pallet, } diff --git a/substrate/frame/examples/offchain-worker/src/tests.rs b/substrate/frame/examples/offchain-worker/src/tests.rs index 48a8d86588c..ea37a2da493 100644 --- a/substrate/frame/examples/offchain-worker/src/tests.rs +++ b/substrate/frame/examples/offchain-worker/src/tests.rs @@ -41,8 +41,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Example: example_offchain_worker::{Pallet, Call, Storage, Event, ValidateUnsigned}, + System: frame_system, + Example: example_offchain_worker, } ); diff --git a/substrate/frame/examples/tasks/src/mock.rs b/substrate/frame/examples/tasks/src/mock.rs index e0fbec3eb76..5ad104b0dfa 100644 --- a/substrate/frame/examples/tasks/src/mock.rs +++ b/substrate/frame/examples/tasks/src/mock.rs @@ -26,7 +26,7 @@ pub type Balance = u32; type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, TasksExample: tasks_example, } diff --git a/substrate/frame/executive/src/lib.rs b/substrate/frame/executive/src/lib.rs index f2cc3b63168..cfeb585b0fd 100644 --- a/substrate/frame/executive/src/lib.rs +++ b/substrate/frame/executive/src/lib.rs @@ -897,12 +897,11 @@ mod tests { } frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, - Custom: custom::{Pallet, Call, ValidateUnsigned, Inherent}, + pub enum Runtime { + System: frame_system, + Balances: pallet_balances, + TransactionPayment: pallet_transaction_payment, + Custom: custom, } ); diff --git a/substrate/frame/fast-unstake/src/mock.rs b/substrate/frame/fast-unstake/src/mock.rs index f9326919fd3..de1772264f1 100644 --- a/substrate/frame/fast-unstake/src/mock.rs +++ b/substrate/frame/fast-unstake/src/mock.rs @@ -181,7 +181,7 @@ impl fast_unstake::Config for Runtime { type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, Timestamp: pallet_timestamp, Balances: pallet_balances, diff --git a/substrate/frame/glutton/src/mock.rs b/substrate/frame/glutton/src/mock.rs index 31b78efc574..26863811e29 100644 --- a/substrate/frame/glutton/src/mock.rs +++ b/substrate/frame/glutton/src/mock.rs @@ -33,8 +33,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Glutton: pallet_glutton::{Pallet, Event}, + System: frame_system, + Glutton: pallet_glutton, } ); diff --git a/substrate/frame/identity/src/tests.rs b/substrate/frame/identity/src/tests.rs index e6107cda0f0..a2b26120254 100644 --- a/substrate/frame/identity/src/tests.rs +++ b/substrate/frame/identity/src/tests.rs @@ -47,9 +47,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Identity: pallet_identity::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Identity: pallet_identity, } ); diff --git a/substrate/frame/im-online/src/mock.rs b/substrate/frame/im-online/src/mock.rs index 2f4e3922026..9dad148b10f 100644 --- a/substrate/frame/im-online/src/mock.rs +++ b/substrate/frame/im-online/src/mock.rs @@ -42,12 +42,11 @@ use crate::Config; type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Session: pallet_session::{Pallet, Call, Storage, Event, Config}, - ImOnline: imonline::{Pallet, Call, Storage, Config, Event}, - Historical: pallet_session_historical::{Pallet}, + pub enum Runtime { + System: frame_system, + Session: pallet_session, + ImOnline: imonline, + Historical: pallet_session_historical, } ); diff --git a/substrate/frame/indices/src/mock.rs b/substrate/frame/indices/src/mock.rs index 913a37fe55b..7ea524a3167 100644 --- a/substrate/frame/indices/src/mock.rs +++ b/substrate/frame/indices/src/mock.rs @@ -32,9 +32,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Indices: pallet_indices::{Pallet, Call, Storage, Config, Event}, + System: frame_system, + Balances: pallet_balances, + Indices: pallet_indices, } ); diff --git a/substrate/frame/insecure-randomness-collective-flip/src/lib.rs b/substrate/frame/insecure-randomness-collective-flip/src/lib.rs index c7ed22d1dd5..00f1055f6f2 100644 --- a/substrate/frame/insecure-randomness-collective-flip/src/lib.rs +++ b/substrate/frame/insecure-randomness-collective-flip/src/lib.rs @@ -179,8 +179,8 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - CollectiveFlip: pallet_insecure_randomness_collective_flip::{Pallet, Storage}, + System: frame_system, + CollectiveFlip: pallet_insecure_randomness_collective_flip, } ); diff --git a/substrate/frame/lottery/src/mock.rs b/substrate/frame/lottery/src/mock.rs index 6e50529619b..884f003aada 100644 --- a/substrate/frame/lottery/src/mock.rs +++ b/substrate/frame/lottery/src/mock.rs @@ -37,9 +37,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Lottery: pallet_lottery::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Lottery: pallet_lottery, } ); diff --git a/substrate/frame/membership/src/lib.rs b/substrate/frame/membership/src/lib.rs index 2f4bf4bc4ff..0e03c097d12 100644 --- a/substrate/frame/membership/src/lib.rs +++ b/substrate/frame/membership/src/lib.rs @@ -541,8 +541,8 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Membership: pallet_membership::{Pallet, Call, Storage, Config, Event}, + System: frame_system, + Membership: pallet_membership, } ); diff --git a/substrate/frame/merkle-mountain-range/src/mock.rs b/substrate/frame/merkle-mountain-range/src/mock.rs index d3cb4e57029..b3b5127db02 100644 --- a/substrate/frame/merkle-mountain-range/src/mock.rs +++ b/substrate/frame/merkle-mountain-range/src/mock.rs @@ -28,8 +28,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - MMR: pallet_mmr::{Pallet, Storage}, + System: frame_system, + MMR: pallet_mmr, } ); diff --git a/substrate/frame/message-queue/src/integration_test.rs b/substrate/frame/message-queue/src/integration_test.rs index fee5d242135..aa6f019d650 100644 --- a/substrate/frame/message-queue/src/integration_test.rs +++ b/substrate/frame/message-queue/src/integration_test.rs @@ -52,8 +52,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event}, + System: frame_system, + MessageQueue: pallet_message_queue, } ); diff --git a/substrate/frame/message-queue/src/mock.rs b/substrate/frame/message-queue/src/mock.rs index 89c6e862510..f1067ed961e 100644 --- a/substrate/frame/message-queue/src/mock.rs +++ b/substrate/frame/message-queue/src/mock.rs @@ -39,8 +39,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event}, + System: frame_system, + MessageQueue: pallet_message_queue, } ); diff --git a/substrate/frame/multisig/src/tests.rs b/substrate/frame/multisig/src/tests.rs index 17982725529..887c7f8bebc 100644 --- a/substrate/frame/multisig/src/tests.rs +++ b/substrate/frame/multisig/src/tests.rs @@ -32,9 +32,9 @@ type Block = frame_system::mocking::MockBlockU32; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Multisig: pallet_multisig::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Multisig: pallet_multisig, } ); diff --git a/substrate/frame/nfts/src/mock.rs b/substrate/frame/nfts/src/mock.rs index 4363eccc7ff..95443cf41c4 100644 --- a/substrate/frame/nfts/src/mock.rs +++ b/substrate/frame/nfts/src/mock.rs @@ -36,9 +36,9 @@ type Block = frame_system::mocking::MockBlock; construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Nfts: pallet_nfts::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Nfts: pallet_nfts, } ); diff --git a/substrate/frame/node-authorization/src/mock.rs b/substrate/frame/node-authorization/src/mock.rs index 3c99d41b89e..bd648de2b24 100644 --- a/substrate/frame/node-authorization/src/mock.rs +++ b/substrate/frame/node-authorization/src/mock.rs @@ -36,10 +36,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - NodeAuthorization: pallet_node_authorization::{ - Pallet, Call, Storage, Config, Event, - }, + System: frame_system, + NodeAuthorization: pallet_node_authorization, } ); diff --git a/substrate/frame/nomination-pools/benchmarking/src/mock.rs b/substrate/frame/nomination-pools/benchmarking/src/mock.rs index c58a66f6163..77124ae3888 100644 --- a/substrate/frame/nomination-pools/benchmarking/src/mock.rs +++ b/substrate/frame/nomination-pools/benchmarking/src/mock.rs @@ -180,14 +180,13 @@ impl crate::Config for Runtime {} type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Staking: pallet_staking::{Pallet, Call, Config, Storage, Event}, - VoterList: pallet_bags_list::::{Pallet, Call, Storage, Event}, - Pools: pallet_nomination_pools::{Pallet, Call, Storage, Event, FreezeReason}, + pub enum Runtime { + System: frame_system, + Timestamp: pallet_timestamp, + Balances: pallet_balances, + Staking: pallet_staking, + VoterList: pallet_bags_list::, + Pools: pallet_nomination_pools, } ); diff --git a/substrate/frame/nomination-pools/src/mock.rs b/substrate/frame/nomination-pools/src/mock.rs index 1bd969230da..cd91fbb33c1 100644 --- a/substrate/frame/nomination-pools/src/mock.rs +++ b/substrate/frame/nomination-pools/src/mock.rs @@ -295,11 +295,10 @@ impl pools::Config for Runtime { type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Storage, Event, Config}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Pools: pools::{Pallet, Call, Storage, Event, FreezeReason}, + pub enum Runtime { + System: frame_system, + Balances: pallet_balances, + Pools: pools, } ); diff --git a/substrate/frame/nomination-pools/test-staking/src/mock.rs b/substrate/frame/nomination-pools/test-staking/src/mock.rs index 491cd619161..cbd7a4d0758 100644 --- a/substrate/frame/nomination-pools/test-staking/src/mock.rs +++ b/substrate/frame/nomination-pools/test-staking/src/mock.rs @@ -192,14 +192,13 @@ impl pallet_nomination_pools::Config for Runtime { type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Staking: pallet_staking::{Pallet, Call, Config, Storage, Event}, - VoterList: pallet_bags_list::::{Pallet, Call, Storage, Event}, - Pools: pallet_nomination_pools::{Pallet, Call, Storage, Event, FreezeReason}, + pub enum Runtime { + System: frame_system, + Timestamp: pallet_timestamp, + Balances: pallet_balances, + Staking: pallet_staking, + VoterList: pallet_bags_list::, + Pools: pallet_nomination_pools, } ); diff --git a/substrate/frame/offences/benchmarking/src/mock.rs b/substrate/frame/offences/benchmarking/src/mock.rs index 1d642b9b498..38c6fb6ea5f 100644 --- a/substrate/frame/offences/benchmarking/src/mock.rs +++ b/substrate/frame/offences/benchmarking/src/mock.rs @@ -227,9 +227,9 @@ frame_support::construct_runtime!( pub enum Test { System: system::{Pallet, Call, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Staking: pallet_staking::{Pallet, Call, Config, Storage, Event}, - Session: pallet_session::{Pallet, Call, Storage, Event, Config}, + Balances: pallet_balances, + Staking: pallet_staking, + Session: pallet_session, ImOnline: pallet_im_online::{Pallet, Call, Storage, Event, ValidateUnsigned, Config}, Offences: pallet_offences::{Pallet, Storage, Event}, Historical: pallet_session_historical::{Pallet}, diff --git a/substrate/frame/offences/src/mock.rs b/substrate/frame/offences/src/mock.rs index 61f680f6db9..d97be99def1 100644 --- a/substrate/frame/offences/src/mock.rs +++ b/substrate/frame/offences/src/mock.rs @@ -68,10 +68,9 @@ pub fn with_on_offence_fractions) -> R>(f: F) -> type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Offences: offences::{Pallet, Storage, Event}, + pub enum Runtime { + System: frame_system, + Offences: offences, } ); diff --git a/substrate/frame/proxy/src/tests.rs b/substrate/frame/proxy/src/tests.rs index 89bd8b68f09..67a662e01b2 100644 --- a/substrate/frame/proxy/src/tests.rs +++ b/substrate/frame/proxy/src/tests.rs @@ -35,10 +35,10 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Proxy: proxy::{Pallet, Call, Storage, Event}, - Utility: pallet_utility::{Pallet, Call, Event}, + System: frame_system, + Balances: pallet_balances, + Proxy: proxy, + Utility: pallet_utility, } ); diff --git a/substrate/frame/ranked-collective/src/tests.rs b/substrate/frame/ranked-collective/src/tests.rs index 60c0da3d7ac..b3605169339 100644 --- a/substrate/frame/ranked-collective/src/tests.rs +++ b/substrate/frame/ranked-collective/src/tests.rs @@ -37,8 +37,8 @@ type Class = Rank; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Club: pallet_ranked_collective::{Pallet, Call, Storage, Event}, + System: frame_system, + Club: pallet_ranked_collective, } ); diff --git a/substrate/frame/recovery/src/mock.rs b/substrate/frame/recovery/src/mock.rs index 44cbeec0986..9adb2b80931 100644 --- a/substrate/frame/recovery/src/mock.rs +++ b/substrate/frame/recovery/src/mock.rs @@ -35,9 +35,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Recovery: recovery::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Recovery: recovery, } ); diff --git a/substrate/frame/remark/src/mock.rs b/substrate/frame/remark/src/mock.rs index 0a385c30eac..5a5e6a3ccdf 100644 --- a/substrate/frame/remark/src/mock.rs +++ b/substrate/frame/remark/src/mock.rs @@ -34,8 +34,8 @@ pub type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Remark: pallet_remark::{ Pallet, Call, Event }, + System: frame_system, + Remark: pallet_remark, } ); diff --git a/substrate/frame/root-offences/src/mock.rs b/substrate/frame/root-offences/src/mock.rs index c0c83dd08d2..583ba5b92fb 100644 --- a/substrate/frame/root-offences/src/mock.rs +++ b/substrate/frame/root-offences/src/mock.rs @@ -48,13 +48,13 @@ pub const BLOCK_TIME: u64 = 1000; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Staking: pallet_staking::{Pallet, Call, Config, Storage, Event}, - Session: pallet_session::{Pallet, Call, Storage, Event, Config}, - RootOffences: root_offences::{Pallet, Call, Storage, Event}, - Historical: pallet_session::historical::{Pallet, Storage}, + System: frame_system, + Timestamp: pallet_timestamp, + Balances: pallet_balances, + Staking: pallet_staking, + Session: pallet_session, + RootOffences: root_offences, + Historical: pallet_session::historical, } ); diff --git a/substrate/frame/salary/src/tests.rs b/substrate/frame/salary/src/tests.rs index fbca1be1188..f25acd93452 100644 --- a/substrate/frame/salary/src/tests.rs +++ b/substrate/frame/salary/src/tests.rs @@ -40,8 +40,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Salary: pallet_salary::{Pallet, Call, Storage, Event}, + System: frame_system, + Salary: pallet_salary, } ); diff --git a/substrate/frame/scheduler/src/mock.rs b/substrate/frame/scheduler/src/mock.rs index 4edcfa0a7bf..d22b9fcf8d9 100644 --- a/substrate/frame/scheduler/src/mock.rs +++ b/substrate/frame/scheduler/src/mock.rs @@ -97,10 +97,10 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Logger: logger::{Pallet, Call, Event}, - Scheduler: scheduler::{Pallet, Call, Storage, Event}, - Preimage: pallet_preimage::{Pallet, Call, Storage, Event, HoldReason}, + System: frame_system, + Logger: logger, + Scheduler: scheduler, + Preimage: pallet_preimage, } ); diff --git a/substrate/frame/scored-pool/src/mock.rs b/substrate/frame/scored-pool/src/mock.rs index 6c032ab808c..00818f4aad0 100644 --- a/substrate/frame/scored-pool/src/mock.rs +++ b/substrate/frame/scored-pool/src/mock.rs @@ -37,9 +37,9 @@ type Block = frame_system::mocking::MockBlock; construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - ScoredPool: pallet_scored_pool::{Pallet, Call, Storage, Config, Event}, + System: frame_system, + Balances: pallet_balances, + ScoredPool: pallet_scored_pool, } ); diff --git a/substrate/frame/session/benchmarking/src/mock.rs b/substrate/frame/session/benchmarking/src/mock.rs index e1744fa43ab..c305641e185 100644 --- a/substrate/frame/session/benchmarking/src/mock.rs +++ b/substrate/frame/session/benchmarking/src/mock.rs @@ -38,10 +38,10 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Staking: pallet_staking::{Pallet, Call, Config, Storage, Event}, - Session: pallet_session::{Pallet, Call, Storage, Event, Config}, + System: frame_system, + Balances: pallet_balances, + Staking: pallet_staking, + Session: pallet_session, } ); diff --git a/substrate/frame/session/src/mock.rs b/substrate/frame/session/src/mock.rs index f3f18fde168..eb9eddfd847 100644 --- a/substrate/frame/session/src/mock.rs +++ b/substrate/frame/session/src/mock.rs @@ -82,9 +82,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Session: pallet_session::{Pallet, Call, Storage, Event, Config}, - Historical: pallet_session_historical::{Pallet}, + System: frame_system, + Session: pallet_session, + Historical: pallet_session_historical, } ); @@ -92,8 +92,8 @@ frame_support::construct_runtime!( frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Session: pallet_session::{Pallet, Call, Storage, Event, Config}, + System: frame_system, + Session: pallet_session, } ); diff --git a/substrate/frame/society/src/mock.rs b/substrate/frame/society/src/mock.rs index 3e29d01ca8e..749d196b6e1 100644 --- a/substrate/frame/society/src/mock.rs +++ b/substrate/frame/society/src/mock.rs @@ -39,9 +39,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Society: pallet_society::{Pallet, Call, Storage, Event, Config}, + System: frame_system, + Balances: pallet_balances, + Society: pallet_society, } ); diff --git a/substrate/frame/state-trie-migration/src/lib.rs b/substrate/frame/state-trie-migration/src/lib.rs index ea28d712605..c71002f420c 100644 --- a/substrate/frame/state-trie-migration/src/lib.rs +++ b/substrate/frame/state-trie-migration/src/lib.rs @@ -1071,9 +1071,9 @@ mod mock { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Config, Storage, Event}, - StateTrieMigration: pallet_state_trie_migration::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + StateTrieMigration: pallet_state_trie_migration, } ); diff --git a/substrate/frame/sudo/src/mock.rs b/substrate/frame/sudo/src/mock.rs index 878e9239080..9ad14804524 100644 --- a/substrate/frame/sudo/src/mock.rs +++ b/substrate/frame/sudo/src/mock.rs @@ -98,9 +98,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Sudo: sudo::{Pallet, Call, Config, Storage, Event}, - Logger: logger::{Pallet, Call, Storage, Event}, + System: frame_system, + Sudo: sudo, + Logger: logger, } ); diff --git a/substrate/frame/support/procedural/src/construct_runtime/mod.rs b/substrate/frame/support/procedural/src/construct_runtime/mod.rs index 7a9c4d89a74..54ed15f7b1d 100644 --- a/substrate/frame/support/procedural/src/construct_runtime/mod.rs +++ b/substrate/frame/support/procedural/src/construct_runtime/mod.rs @@ -21,7 +21,7 @@ //! order to get all the pallet parts for each pallet. //! //! Pallets can define their parts: -//! - Implicitely: `System: frame_system` +//! - Implicitly: `System: frame_system` //! - Explicitly: `System: frame_system::{Pallet, Call}` //! //! The `construct_runtime` transitions from the implicit definition to the explict one. @@ -172,7 +172,7 @@ //! //! This call has no implicit pallet parts, thus it will expand to the runtime construction: //! ```ignore -//! pub struct Runtime { ... } +//! pub enum Runtime { ... } //! pub struct Call { ... } //! impl Call ... //! pub enum Origin { ... } @@ -342,7 +342,7 @@ fn construct_runtime_final_expansion( syn::Error::new( pallets_token.span.join(), "`System` pallet declaration is missing. \ - Please add this line: `System: frame_system::{Pallet, Call, Storage, Config, Event},`", + Please add this line: `System: frame_system,`", ) })?; if !system_pallet.cfg_pattern.is_empty() { diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs index af1f99be103..95478d1a8cc 100644 --- a/substrate/frame/support/src/lib.rs +++ b/substrate/frame/support/src/lib.rs @@ -2291,7 +2291,7 @@ pub mod pallet_macros { /// # type Block = frame_system::mocking::MockBlock; /// # } /// construct_runtime! { - /// pub struct Runtime { + /// pub enum Runtime { /// System: frame_system, /// Custom: custom_pallet /// } diff --git a/substrate/frame/support/src/migrations.rs b/substrate/frame/support/src/migrations.rs index bfd62c8611c..d059a992a86 100644 --- a/substrate/frame/support/src/migrations.rs +++ b/substrate/frame/support/src/migrations.rs @@ -254,10 +254,10 @@ pub fn migrate_from_pallet_version_to_storage_version< /// construct_runtime! { /// pub enum Runtime /// { -/// System: frame_system::{Pallet, Call, Storage, Config, Event} = 0, +/// System: frame_system = 0, /// -/// SomePalletToRemove: pallet_something::{Pallet, Call, Storage, Event} = 1, -/// AnotherPalletToRemove: pallet_something_else::{Pallet, Call, Storage, Event} = 2, +/// SomePalletToRemove: pallet_something = 1, +/// AnotherPalletToRemove: pallet_something_else = 2, /// /// YourOtherPallets... /// } diff --git a/substrate/frame/support/test/compile_pass/src/lib.rs b/substrate/frame/support/test/compile_pass/src/lib.rs index b304dfcb282..575322df760 100644 --- a/substrate/frame/support/test/compile_pass/src/lib.rs +++ b/substrate/frame/support/test/compile_pass/src/lib.rs @@ -83,7 +83,7 @@ pub type Block = generic::Block; pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: renamed_frame_system, } ); diff --git a/substrate/frame/support/test/stg_frame_crate/src/lib.rs b/substrate/frame/support/test/stg_frame_crate/src/lib.rs index 501fcf6a70d..59a66851f23 100644 --- a/substrate/frame/support/test/stg_frame_crate/src/lib.rs +++ b/substrate/frame/support/test/stg_frame_crate/src/lib.rs @@ -68,8 +68,8 @@ mod tests { construct_runtime! { pub struct Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Pallet: pallet::{Pallet, Config}, + System: frame_system, + Pallet: pallet, } } } diff --git a/substrate/frame/support/test/tests/construct_runtime_ui/missing_system_module.stderr b/substrate/frame/support/test/tests/construct_runtime_ui/missing_system_module.stderr index 11ec6f33d20..0f74553f7ec 100644 --- a/substrate/frame/support/test/tests/construct_runtime_ui/missing_system_module.stderr +++ b/substrate/frame/support/test/tests/construct_runtime_ui/missing_system_module.stderr @@ -1,4 +1,4 @@ -error: `System` pallet declaration is missing. Please add this line: `System: frame_system::{Pallet, Call, Storage, Config, Event},` +error: `System` pallet declaration is missing. Please add this line: `System: frame_system,` --> tests/construct_runtime_ui/missing_system_module.rs:22:2 | 22 | / { diff --git a/substrate/frame/support/test/tests/construct_runtime_ui/pass/composite_enum_instance.rs b/substrate/frame/support/test/tests/construct_runtime_ui/pass/composite_enum_instance.rs index ad637087476..5cde4a9beba 100644 --- a/substrate/frame/support/test/tests/construct_runtime_ui/pass/composite_enum_instance.rs +++ b/substrate/frame/support/test/tests/construct_runtime_ui/pass/composite_enum_instance.rs @@ -64,7 +64,7 @@ pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; frame_support::construct_runtime!( - pub struct Runtime + pub enum Runtime { // Exclude part `Storage` in order not to check its metadata in tests. System: frame_system, diff --git a/substrate/frame/support/test/tests/final_keys.rs b/substrate/frame/support/test/tests/final_keys.rs index 765afaf1e66..38240830daa 100644 --- a/substrate/frame/support/test/tests/final_keys.rs +++ b/substrate/frame/support/test/tests/final_keys.rs @@ -201,7 +201,6 @@ pub type Block = generic::Block; frame_support::construct_runtime!( pub enum Runtime - { System: frame_system, FinalKeysNone: no_instance, diff --git a/substrate/frame/support/test/tests/instance.rs b/substrate/frame/support/test/tests/instance.rs index 43a93df9dea..7a888e5685d 100644 --- a/substrate/frame/support/test/tests/instance.rs +++ b/substrate/frame/support/test/tests/instance.rs @@ -278,24 +278,14 @@ pub type Block = generic::Block; frame_support::construct_runtime!( pub enum Runtime { - System: frame_system::{Pallet, Call, Event}, - Module1_1: module1::::{ - Pallet, Call, Storage, Event, Config, Origin, Inherent - }, - Module1_2: module1::::{ - Pallet, Call, Storage, Event, Config, Origin, Inherent - }, - Module2: module2::{Pallet, Call, Storage, Event, Config, Origin, Inherent}, - Module2_1: module2::::{ - Pallet, Call, Storage, Event, Config, Origin, Inherent - }, - Module2_2: module2::::{ - Pallet, Call, Storage, Event, Config, Origin, Inherent - }, - Module2_3: module2::::{ - Pallet, Call, Storage, Event, Config, Origin, Inherent - }, - Module3: module3::{Pallet, Call}, + System: frame_system, + Module1_1: module1::, + Module1_2: module1::, + Module2: module2, + Module2_1: module2::, + Module2_2: module2::, + Module2_3: module2::, + Module3: module3, } ); @@ -350,6 +340,7 @@ impl module3::Config for Runtime { fn new_test_ext() -> sp_io::TestExternalities { RuntimeGenesisConfig { + system: Default::default(), module_1_1: module1::GenesisConfig { value: 3, test: 2 }, module_1_2: module1::GenesisConfig { value: 4, test: 5 }, module_2: module2::GenesisConfig { diff --git a/substrate/frame/support/test/tests/issue2219.rs b/substrate/frame/support/test/tests/issue2219.rs index 4016707b51a..4c384f43276 100644 --- a/substrate/frame/support/test/tests/issue2219.rs +++ b/substrate/frame/support/test/tests/issue2219.rs @@ -176,7 +176,7 @@ impl frame_system::Config for Runtime { impl module::Config for Runtime {} frame_support::construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, Module: module, } diff --git a/substrate/frame/support/test/tests/pallet_ui/pass/no_std_genesis_config.rs b/substrate/frame/support/test/tests/pallet_ui/pass/no_std_genesis_config.rs index de856ddcd3e..7e67193cc76 100644 --- a/substrate/frame/support/test/tests/pallet_ui/pass/no_std_genesis_config.rs +++ b/substrate/frame/support/test/tests/pallet_ui/pass/no_std_genesis_config.rs @@ -57,8 +57,8 @@ impl frame_system::Config for Runtime { construct_runtime! { pub struct Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Pallet: test_pallet::{Pallet, Config}, + System: frame_system, + Pallet: test_pallet, } } diff --git a/substrate/frame/support/test/tests/storage_layers.rs b/substrate/frame/support/test/tests/storage_layers.rs index a6d16e0d66d..88edd7de6ca 100644 --- a/substrate/frame/support/test/tests/storage_layers.rs +++ b/substrate/frame/support/test/tests/storage_layers.rs @@ -94,7 +94,7 @@ impl frame_system::Config for Runtime { impl Config for Runtime {} frame_support::construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, MyPallet: pallet, } diff --git a/substrate/frame/support/test/tests/versioned_migration.rs b/substrate/frame/support/test/tests/versioned_migration.rs index 03dbd948df9..dab5e06dc85 100644 --- a/substrate/frame/support/test/tests/versioned_migration.rs +++ b/substrate/frame/support/test/tests/versioned_migration.rs @@ -66,8 +66,8 @@ impl dummy_pallet::Config for Test {} construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - DummyPallet: dummy_pallet::{Pallet, Config, Storage} = 1, + System: frame_system = 0, + DummyPallet: dummy_pallet = 1, } ); diff --git a/substrate/frame/system/benches/bench.rs b/substrate/frame/system/benches/bench.rs index 79d5a2d8689..a0c567bf852 100644 --- a/substrate/frame/system/benches/bench.rs +++ b/substrate/frame/system/benches/bench.rs @@ -47,10 +47,9 @@ mod module { type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Module: module::{Pallet, Event}, + pub enum Runtime { + System: frame_system, + Module: module, } ); diff --git a/substrate/frame/system/benchmarking/src/mock.rs b/substrate/frame/system/benchmarking/src/mock.rs index 9a81cddca14..edbf74a9a51 100644 --- a/substrate/frame/system/benchmarking/src/mock.rs +++ b/substrate/frame/system/benchmarking/src/mock.rs @@ -31,7 +31,7 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, + System: frame_system, } ); diff --git a/substrate/frame/system/src/mock.rs b/substrate/frame/system/src/mock.rs index e33ac2f56c8..06527a9bb29 100644 --- a/substrate/frame/system/src/mock.rs +++ b/substrate/frame/system/src/mock.rs @@ -31,7 +31,7 @@ type Block = mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, + System: frame_system, } ); diff --git a/substrate/frame/timestamp/src/mock.rs b/substrate/frame/timestamp/src/mock.rs index b75bcaeb0e0..5cbc5211368 100644 --- a/substrate/frame/timestamp/src/mock.rs +++ b/substrate/frame/timestamp/src/mock.rs @@ -37,8 +37,8 @@ type Moment = u64; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + System: frame_system, + Timestamp: pallet_timestamp, } ); diff --git a/substrate/frame/tips/src/tests.rs b/substrate/frame/tips/src/tests.rs index 63ac8e37cdd..b8e528bbe7a 100644 --- a/substrate/frame/tips/src/tests.rs +++ b/substrate/frame/tips/src/tests.rs @@ -44,12 +44,12 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event}, - Treasury1: pallet_treasury::::{Pallet, Call, Storage, Config, Event}, - Tips: pallet_tips::{Pallet, Call, Storage, Event}, - Tips1: pallet_tips::::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Treasury: pallet_treasury, + Treasury1: pallet_treasury::, + Tips: pallet_tips, + Tips1: pallet_tips::, } ); diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs index c9b00be8e2c..03142d6ae37 100644 --- a/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs +++ b/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs @@ -37,7 +37,7 @@ type Balance = u64; type AccountId = u64; frame_support::construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: system, Balances: pallet_balances, TransactionPayment: pallet_transaction_payment, diff --git a/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs b/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs index 5c540c3e459..17c4c773997 100644 --- a/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs +++ b/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs @@ -84,7 +84,7 @@ pub mod pallet_dummy { impl pallet_dummy::Config for Runtime {} frame_support::construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: system, SkipFeeless: pallet_skip_feeless_payment, DummyPallet: pallet_dummy, diff --git a/substrate/frame/transaction-payment/src/mock.rs b/substrate/frame/transaction-payment/src/mock.rs index d6686d44c80..2f025ae81d2 100644 --- a/substrate/frame/transaction-payment/src/mock.rs +++ b/substrate/frame/transaction-payment/src/mock.rs @@ -36,8 +36,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub struct Runtime { - System: system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + System: system, + Balances: pallet_balances, TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, } ); diff --git a/substrate/frame/transaction-storage/src/mock.rs b/substrate/frame/transaction-storage/src/mock.rs index a8da19a382d..4b2fe5a2a8c 100644 --- a/substrate/frame/transaction-storage/src/mock.rs +++ b/substrate/frame/transaction-storage/src/mock.rs @@ -33,11 +33,9 @@ pub type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Config, Storage, Event}, - TransactionStorage: pallet_transaction_storage::{ - Pallet, Call, Storage, Config, Inherent, Event, HoldReason - }, + System: frame_system, + Balances: pallet_balances, + TransactionStorage: pallet_transaction_storage, } ); diff --git a/substrate/frame/treasury/src/tests.rs b/substrate/frame/treasury/src/tests.rs index 093757b2770..602159262e4 100644 --- a/substrate/frame/treasury/src/tests.rs +++ b/substrate/frame/treasury/src/tests.rs @@ -47,9 +47,9 @@ type TreasuryCall = crate::Call; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Treasury: treasury::{Pallet, Call, Storage, Config, Event}, + System: frame_system, + Balances: pallet_balances, + Treasury: treasury, Utility: pallet_utility, } ); diff --git a/substrate/frame/uniques/src/mock.rs b/substrate/frame/uniques/src/mock.rs index 056c19ec559..9120108e0d4 100644 --- a/substrate/frame/uniques/src/mock.rs +++ b/substrate/frame/uniques/src/mock.rs @@ -35,9 +35,9 @@ type Block = frame_system::mocking::MockBlock; construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Uniques: pallet_uniques::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Uniques: pallet_uniques, } ); diff --git a/substrate/frame/utility/src/tests.rs b/substrate/frame/utility/src/tests.rs index 7b42fa511d1..cfdbd6faf0d 100644 --- a/substrate/frame/utility/src/tests.rs +++ b/substrate/frame/utility/src/tests.rs @@ -129,14 +129,14 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Timestamp: pallet_timestamp::{Call, Inherent}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - RootTesting: pallet_root_testing::{Pallet, Call, Storage, Event}, + System: frame_system, + Timestamp: pallet_timestamp, + Balances: pallet_balances, + RootTesting: pallet_root_testing, Council: pallet_collective::, - Utility: utility::{Pallet, Call, Event}, - Example: example::{Pallet, Call}, - Democracy: mock_democracy::{Pallet, Call, Event}, + Utility: utility, + Example: example, + Democracy: mock_democracy, } ); diff --git a/substrate/frame/vesting/src/mock.rs b/substrate/frame/vesting/src/mock.rs index 3af4a9c962d..420edd5e17a 100644 --- a/substrate/frame/vesting/src/mock.rs +++ b/substrate/frame/vesting/src/mock.rs @@ -33,9 +33,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Vesting: pallet_vesting::{Pallet, Call, Storage, Event, Config}, + System: frame_system, + Balances: pallet_balances, + Vesting: pallet_vesting, } ); diff --git a/substrate/primitives/api/src/lib.rs b/substrate/primitives/api/src/lib.rs index 1b8b7c40ae0..0a9b334a96f 100644 --- a/substrate/primitives/api/src/lib.rs +++ b/substrate/primitives/api/src/lib.rs @@ -282,7 +282,7 @@ pub use sp_api_proc_macro::decl_runtime_apis; /// # /// # /// The declaration of the `Runtime` type is done by the `construct_runtime!` macro /// # /// in a real runtime. -/// # pub struct Runtime {} +/// # pub enum Runtime {} /// # /// # sp_api::decl_runtime_apis! { /// # /// Declare the api trait. @@ -361,7 +361,7 @@ pub use sp_api_proc_macro::decl_runtime_apis; /// let's say you want to implement a staging version of the runtime api and put it behind a /// feature flag. You can do it this way: /// ```ignore -/// pub struct Runtime {} +/// pub enum Runtime {} /// sp_api::decl_runtime_apis! { /// pub trait ApiWithStagingMethod { /// fn stable_one(data: u64); diff --git a/substrate/primitives/api/test/tests/decl_and_impl.rs b/substrate/primitives/api/test/tests/decl_and_impl.rs index 6e895680e41..d68470551d2 100644 --- a/substrate/primitives/api/test/tests/decl_and_impl.rs +++ b/substrate/primitives/api/test/tests/decl_and_impl.rs @@ -24,7 +24,7 @@ use substrate_test_runtime_client::runtime::{Block, Hash}; /// The declaration of the `Runtime` type is done by the `construct_runtime!` macro in a real /// runtime. -pub struct Runtime {} +pub enum Runtime {} decl_runtime_apis! { pub trait Api { diff --git a/substrate/utils/frame/rpc/support/src/lib.rs b/substrate/utils/frame/rpc/support/src/lib.rs index bb5098293c2..e3ccbd69658 100644 --- a/substrate/utils/frame/rpc/support/src/lib.rs +++ b/substrate/utils/frame/rpc/support/src/lib.rs @@ -42,8 +42,8 @@ use sp_storage::{StorageData, StorageKey}; /// # construct_runtime!( /// # pub enum TestRuntime /// # { -/// # System: frame_system::{Pallet, Call, Config, Storage, Event}, -/// # Test: pallet_test::{Pallet, Storage}, +/// # System: frame_system, +/// # Test: pallet_test, /// # } /// # ); /// # -- GitLab From e2caa813bfd2973e7a7a74aa5292433397dbc787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 22 Jan 2024 10:12:58 +0100 Subject: [PATCH 099/392] Review: Remove audit rules (#3010) Srlabs review is most of the times just blocking the merge, especially when the changes do not require any audit. This pr removes the requirement of srlabs to approve these prs. --- .github/review-bot.yml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/.github/review-bot.yml b/.github/review-bot.yml index aa4ab8a69e0..ed719cefec8 100644 --- a/.github/review-bot.yml +++ b/.github/review-bot.yml @@ -20,23 +20,6 @@ rules: teams: - core-devs - - name: Audit rules - type: basic - condition: - include: - - ^polkadot/runtime/common/.* - - ^polkadot/primitives/src\/.+\.rs$ - - ^substrate/primitives/.* - - ^substrate/frame/.* - exclude: - - ^substrate\/frame\/.+\.md$ - minApprovals: 1 - allowedToSkipRule: - teams: - - core-devs - teams: - - srlabs - - name: Core developers countAuthor: true condition: -- GitLab From d53534c49e0f649e8b6b8219df5e65893ea9511d Mon Sep 17 00:00:00 2001 From: Marcin S Date: Mon, 22 Jan 2024 11:29:13 +0100 Subject: [PATCH 100/392] Enable async backing on asset-hub-rococo (#2826) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The goal is to move all system chains on Rococo (+ other testnets?) to use async backing. Starting with `asset-hub-rococo` to get feedback, before I do the rest. ## Related Example: https://github.com/paritytech/polkadot-sdk/pull/1619/ Guide: https://github.com/w3f/polkadot-wiki/blob/master/docs/maintain/maintain-guides-async-backing.md --------- Co-authored-by: Branislav Kontur Co-authored-by: Dónal Murray --- Cargo.lock | 1 + cumulus/client/collator/src/lib.rs | 22 +-- .../consensus/aura/src/collators/lookahead.rs | 3 + .../assets/asset-hub-rococo/Cargo.toml | 2 + .../assets/asset-hub-rococo/src/lib.rs | 63 +++++-- .../assets/asset-hub-rococo/tests/tests.rs | 19 ++- .../assets/asset-hub-westend/src/lib.rs | 1 - .../assets/asset-hub-westend/tests/tests.rs | 19 ++- .../assets/test-utils/src/test_cases.rs | 13 +- .../test-utils/src/test_cases_over_bridge.rs | 4 +- .../bridge-hub-rococo/tests/tests.rs | 21 ++- .../bridge-hub-westend/tests/tests.rs | 19 ++- .../src/test_cases/from_grandpa_chain.rs | 6 +- .../src/test_cases/from_parachain.rs | 6 +- .../test-utils/src/test_cases/helpers.rs | 4 +- .../test-utils/src/test_cases/mod.rs | 4 +- .../parachains/runtimes/test-utils/src/lib.rs | 14 +- cumulus/polkadot-parachain/src/command.rs | 13 +- cumulus/polkadot-parachain/src/service.rs | 157 +++++++++++++++++- polkadot/node/collation-generation/src/lib.rs | 10 ++ polkadot/node/subsystem-types/src/messages.rs | 4 +- prdoc/pr_2826.prdoc | 10 ++ 22 files changed, 366 insertions(+), 49 deletions(-) create mode 100644 prdoc/pr_2826.prdoc diff --git a/Cargo.lock b/Cargo.lock index 1d404a2c231..15e3022bfb6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -864,6 +864,7 @@ dependencies = [ "cumulus-pallet-session-benchmarking", "cumulus-pallet-xcm", "cumulus-pallet-xcmp-queue", + "cumulus-primitives-aura", "cumulus-primitives-core", "cumulus-primitives-utility", "frame-benchmarking", diff --git a/cumulus/client/collator/src/lib.rs b/cumulus/client/collator/src/lib.rs index f17ae488310..83249186f62 100644 --- a/cumulus/client/collator/src/lib.rs +++ b/cumulus/client/collator/src/lib.rs @@ -242,17 +242,19 @@ pub async fn initialize_collator_subsystems( overseer_handle: &mut OverseerHandle, key: CollatorPair, para_id: ParaId, + reinitialize: bool, ) { - overseer_handle - .send_msg( - CollationGenerationMessage::Initialize(CollationGenerationConfig { - key, - para_id, - collator: None, - }), - "StartCollator", - ) - .await; + let config = CollationGenerationConfig { key, para_id, collator: None }; + + if reinitialize { + overseer_handle + .send_msg(CollationGenerationMessage::Reinitialize(config), "StartCollator") + .await; + } else { + overseer_handle + .send_msg(CollationGenerationMessage::Initialize(config), "StartCollator") + .await; + } overseer_handle .send_msg(CollatorProtocolMessage::CollateOn(para_id), "StartCollator") diff --git a/cumulus/client/consensus/aura/src/collators/lookahead.rs b/cumulus/client/consensus/aura/src/collators/lookahead.rs index 5d62094e4aa..e24b7f6f1c9 100644 --- a/cumulus/client/consensus/aura/src/collators/lookahead.rs +++ b/cumulus/client/consensus/aura/src/collators/lookahead.rs @@ -105,6 +105,8 @@ pub struct Params { pub collator_service: CS, /// The amount of time to spend authoring each block. pub authoring_duration: Duration, + /// Whether we should reinitialize the collator config (i.e. we are transitioning to aura). + pub reinitialize: bool, } /// Run async-backing-friendly Aura. @@ -149,6 +151,7 @@ where &mut params.overseer_handle, params.collator_key, params.para_id, + params.reinitialize, ) .await; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml index 5d0cb41395f..254aca90078 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml @@ -77,6 +77,7 @@ cumulus-pallet-parachain-system = { path = "../../../../pallets/parachain-system cumulus-pallet-session-benchmarking = { path = "../../../../pallets/session-benchmarking", default-features = false } cumulus-pallet-xcm = { path = "../../../../pallets/xcm", default-features = false } cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue", default-features = false, features = ["bridging"] } +cumulus-primitives-aura = { path = "../../../../primitives/aura", default-features = false } cumulus-primitives-core = { path = "../../../../primitives/core", default-features = false } cumulus-primitives-utility = { path = "../../../../primitives/utility", default-features = false } pallet-collator-selection = { path = "../../../../pallets/collator-selection", default-features = false } @@ -188,6 +189,7 @@ std = [ "cumulus-pallet-session-benchmarking/std", "cumulus-pallet-xcm/std", "cumulus-pallet-xcmp-queue/std", + "cumulus-primitives-aura/std", "cumulus-primitives-core/std", "cumulus-primitives-utility/std", "frame-benchmarking?/std", diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index a812e747f00..983e250d0cc 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -33,7 +33,7 @@ use assets_common::{ matching::{FromNetwork, FromSiblingParachain}, AssetIdForTrustBackedAssetsConvert, }; -use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; +use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; use cumulus_primitives_core::AggregateMessageOrigin; use parachains_common::rococo::snowbridge::EthereumNetwork; use sp_api::impl_runtime_apis; @@ -62,7 +62,7 @@ use frame_support::{ ConstU128, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Equals, InstanceFilter, TransformOrigin, }, - weights::{ConstantMultiplier, Weight}, + weights::{constants::WEIGHT_REF_TIME_PER_SECOND, ConstantMultiplier, Weight}, BoundedVec, PalletId, }; use frame_system::{ @@ -71,14 +71,13 @@ use frame_system::{ }; use pallet_asset_conversion_tx_payment::AssetConversionAdapter; use pallet_nfts::PalletFeatures; -pub use parachains_common as common; use parachains_common::{ impls::DealWithFees, message_queue::{NarrowOriginToSibling, ParaIdToSibling}, rococo::{consensus::*, currency::*, fee::WeightToFee}, AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, BlockNumber, CollectionId, Hash, Header, ItemId, Nonce, Signature, AVERAGE_ON_INITIALIZE_RATIO, DAYS, HOURS, - MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, + NORMAL_DISPATCH_RATIO, }; use sp_runtime::{Perbill, RuntimeDebug}; use xcm_config::{ @@ -141,6 +140,28 @@ pub fn native_version() -> NativeVersion { NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } } +/// We allow for 2 seconds of compute with a 6 second average block. +const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts( + WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), + cumulus_primitives_core::relay_chain::MAX_POV_SIZE as u64, +); + +/// Maximum number of blocks simultaneously accepted by the Runtime, not yet included +/// into the relay chain. +const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3; +/// How many parachain blocks are processed by the relay chain per parent. Limits the +/// number of blocks authored per slot. +const BLOCK_PROCESSING_VELOCITY: u32 = 1; + +/// This determines the average expected block time that we are targeting. +/// Blocks will be produced at a minimum duration defined by `SLOT_DURATION`. +/// `SLOT_DURATION` is picked up by `pallet_timestamp` which is in turn picked +/// up by `pallet_aura` to implement `fn slot_duration()`. +/// +/// Change this to adjust the block time. +pub const MILLISECS_PER_BLOCK: u64 = 6000; +pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; + parameter_types! { pub const Version: RuntimeVersion = VERSION; pub RuntimeBlockLength: BlockLength = @@ -189,6 +210,9 @@ impl pallet_timestamp::Config for Runtime { /// A timestamp: milliseconds since the unix epoch. type Moment = u64; type OnTimestampSet = Aura; + #[cfg(feature = "experimental")] + type MinimumPeriod = ConstU64<0>; + #[cfg(not(feature = "experimental"))] type MinimumPeriod = ConstU64<{ SLOT_DURATION / 2 }>; type WeightInfo = weights::pallet_timestamp::WeightInfo; } @@ -630,15 +654,17 @@ impl cumulus_pallet_parachain_system::Config for Runtime { type OutboundXcmpMessageSource = XcmpQueue; type XcmpMessageHandler = XcmpQueue; type ReservedXcmpWeight = ReservedXcmpWeight; - type CheckAssociatedRelayNumber = RelayNumberStrictlyIncreases; - type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook< - Runtime, - RELAY_CHAIN_SLOT_DURATION_MILLIS, - BLOCK_PROCESSING_VELOCITY, - UNINCLUDED_SEGMENT_CAPACITY, - >; + type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases; + type ConsensusHook = ConsensusHook; } +type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook< + Runtime, + RELAY_CHAIN_SLOT_DURATION_MILLIS, + BLOCK_PROCESSING_VELOCITY, + UNINCLUDED_SEGMENT_CAPACITY, +>; + parameter_types! { pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block; } @@ -722,9 +748,9 @@ impl pallet_aura::Config for Runtime { type AuthorityId = AuraId; type DisabledValidators = (); type MaxAuthorities = ConstU32<100_000>; - type AllowMultipleBlocksPerSlot = ConstBool; + type AllowMultipleBlocksPerSlot = ConstBool; #[cfg(feature = "experimental")] - type SlotDuration = pallet_aura::MinimumPeriodTimesTwo; + type SlotDuration = ConstU64; } parameter_types! { @@ -1067,7 +1093,7 @@ mod benches { impl_runtime_apis! { impl sp_consensus_aura::AuraApi for Runtime { fn slot_duration() -> sp_consensus_aura::SlotDuration { - sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration()) + sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION) } fn authorities() -> Vec { @@ -1075,6 +1101,15 @@ impl_runtime_apis! { } } + impl cumulus_primitives_aura::AuraUnincludedSegmentApi for Runtime { + fn can_build_upon( + included_hash: ::Hash, + slot: cumulus_primitives_aura::Slot, + ) -> bool { + ConsensusHook::can_build_upon(included_hash, slot) + } + } + impl sp_api::Core for Runtime { fn version() -> RuntimeVersion { VERSION diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs index cb7ea34a057..e7ac37b2d5c 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs @@ -28,10 +28,11 @@ use asset_hub_rococo_runtime::{ AllPalletsWithoutSystem, AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, Runtime, RuntimeCall, RuntimeEvent, SessionKeys, - ToWestendXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue, + ToWestendXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue, SLOT_DURATION, }; use asset_test_utils::{ - test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, + test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, + ExtBuilder, SlotDurations, }; use codec::{Decode, Encode}; use cumulus_primitives_utility::ChargeWeightInFungibles; @@ -46,9 +47,10 @@ use frame_support::{ weights::{Weight, WeightToFee as WeightToFeeT}, }; use parachains_common::{ - rococo::{currency::UNITS, fee::WeightToFee}, + rococo::{consensus::RELAY_CHAIN_SLOT_DURATION_MILLIS, currency::UNITS, fee::WeightToFee}, AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, }; +use sp_consensus_aura::SlotDuration; use sp_runtime::traits::MaybeEquivalence; use std::convert::Into; use xcm::latest::prelude::{Assets as XcmAssets, *}; @@ -78,6 +80,13 @@ fn collator_session_keys() -> CollatorSessionKeys { CollatorSessionKeys::default().add(collator_session_key(ALICE)) } +fn slot_durations() -> SlotDurations { + SlotDurations { + relay: SlotDuration::from_millis(RELAY_CHAIN_SLOT_DURATION_MILLIS.into()), + para: SlotDuration::from_millis(SLOT_DURATION), + } +} + #[test] fn test_buy_and_refund_weight_in_native() { ExtBuilder::::default() @@ -892,6 +901,7 @@ asset_test_utils::include_teleports_for_native_asset_works!( WeightToFee, ParachainSystem, collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { @@ -912,6 +922,7 @@ asset_test_utils::include_teleports_for_foreign_assets_works!( ForeignCreatorsSovereignAccountOf, ForeignAssetsInstance, collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { @@ -1023,6 +1034,7 @@ fn limited_reserve_transfer_assets_for_native_asset_over_bridge_works( LocationToAccountId, >( collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), AccountId::from(ALICE), Box::new(|runtime_event_encoded: Vec| { @@ -1194,6 +1206,7 @@ mod asset_hub_rococo_tests { LocationToAccountId, >( collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), AccountId::from(ALICE), Box::new(|runtime_event_encoded: Vec| { diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index b4bcc716513..e642475698e 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -55,7 +55,6 @@ use frame_system::{ use pallet_asset_conversion_tx_payment::AssetConversionAdapter; use pallet_nfts::{DestroyWitness, PalletFeatures}; use pallet_xcm::EnsureXcm; -pub use parachains_common as common; use parachains_common::{ impls::DealWithFees, message_queue::*, diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs index 3fc9f4a9658..381b2867c9c 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs @@ -32,7 +32,8 @@ use asset_hub_westend_runtime::{ }; pub use asset_hub_westend_runtime::{AssetConversion, AssetDeposit, CollatorSelection, System}; use asset_test_utils::{ - test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, + test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, + ExtBuilder, SlotDurations, }; use codec::{Decode, Encode}; use cumulus_primitives_utility::ChargeWeightInFungibles; @@ -47,9 +48,10 @@ use frame_support::{ weights::{Weight, WeightToFee as WeightToFeeT}, }; use parachains_common::{ - westend::{currency::UNITS, fee::WeightToFee}, - AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, + westend::{consensus::RELAY_CHAIN_SLOT_DURATION_MILLIS, currency::UNITS, fee::WeightToFee}, + AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, SLOT_DURATION, }; +use sp_consensus_aura::SlotDuration; use sp_runtime::traits::MaybeEquivalence; use std::convert::Into; use xcm::latest::prelude::{Assets as XcmAssets, *}; @@ -79,6 +81,13 @@ fn collator_session_keys() -> CollatorSessionKeys { CollatorSessionKeys::default().add(collator_session_key(ALICE)) } +fn slot_durations() -> SlotDurations { + SlotDurations { + relay: SlotDuration::from_millis(RELAY_CHAIN_SLOT_DURATION_MILLIS.into()), + para: SlotDuration::from_millis(SLOT_DURATION), + } +} + #[test] fn test_buy_and_refund_weight_in_native() { ExtBuilder::::default() @@ -895,6 +904,7 @@ asset_test_utils::include_teleports_for_native_asset_works!( WeightToFee, ParachainSystem, collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { @@ -915,6 +925,7 @@ asset_test_utils::include_teleports_for_foreign_assets_works!( ForeignCreatorsSovereignAccountOf, ForeignAssetsInstance, collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { @@ -1041,6 +1052,7 @@ fn limited_reserve_transfer_assets_for_native_asset_to_asset_hub_rococo_works() LocationToAccountId, >( collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), AccountId::from(ALICE), Box::new(|runtime_event_encoded: Vec| { @@ -1208,6 +1220,7 @@ fn reserve_transfer_native_asset_to_non_teleport_para_works() { LocationToAccountId, >( collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), AccountId::from(ALICE), Box::new(|runtime_event_encoded: Vec| { diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs index e981fae8015..4007d926983 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs @@ -31,7 +31,7 @@ use frame_system::pallet_prelude::BlockNumberFor; use parachains_common::{AccountId, Balance}; use parachains_runtimes_test_utils::{ assert_metadata, assert_total, mock_open_hrmp_channel, AccountIdOf, BalanceOf, - CollatorSessionKeys, ExtBuilder, ValidatorIdOf, XcmReceivedFrom, + CollatorSessionKeys, ExtBuilder, SlotDurations, ValidatorIdOf, XcmReceivedFrom, }; use sp_runtime::{ traits::{MaybeEquivalence, StaticLookup, Zero}, @@ -57,6 +57,7 @@ pub fn teleports_for_native_asset_works< HrmpChannelOpener, >( collator_session_keys: CollatorSessionKeys, + slot_durations: SlotDurations, existential_deposit: BalanceOf, target_account: AccountIdOf, unwrap_pallet_xcm_event: Box) -> Option>>, @@ -205,6 +206,7 @@ pub fn teleports_for_native_asset_works< None, included_head.clone(), &alice, + &slot_durations, )); // check balances @@ -257,6 +259,7 @@ pub fn teleports_for_native_asset_works< Some((runtime_para_id, other_para_id)), included_head, &alice, + &slot_durations, ), Err(DispatchError::Module(sp_runtime::ModuleError { index: 31, @@ -288,6 +291,7 @@ macro_rules! include_teleports_for_native_asset_works( $weight_to_fee:path, $hrmp_channel_opener:path, $collator_session_key:expr, + $slot_durations:expr, $existential_deposit:expr, $unwrap_pallet_xcm_event:expr, $runtime_para_id:expr @@ -306,6 +310,7 @@ macro_rules! include_teleports_for_native_asset_works( $hrmp_channel_opener >( $collator_session_key, + $slot_durations, $existential_deposit, target_account, $unwrap_pallet_xcm_event, @@ -328,6 +333,7 @@ pub fn teleports_for_foreign_assets_works< ForeignAssetsPalletInstance, >( collator_session_keys: CollatorSessionKeys, + slot_durations: SlotDurations, target_account: AccountIdOf, existential_deposit: BalanceOf, asset_owner: AccountIdOf, @@ -592,6 +598,7 @@ pub fn teleports_for_foreign_assets_works< Some((runtime_para_id, foreign_para_id)), included_head, &alice, + &slot_durations, )); // check balances @@ -644,6 +651,7 @@ macro_rules! include_teleports_for_foreign_assets_works( $sovereign_account_of:path, $assets_pallet_instance:path, $collator_session_key:expr, + $slot_durations:expr, $existential_deposit:expr, $unwrap_pallet_xcm_event:expr, $unwrap_xcmp_queue_event:expr @@ -666,6 +674,7 @@ macro_rules! include_teleports_for_foreign_assets_works( $assets_pallet_instance >( $collator_session_key, + $slot_durations, target_account, $existential_deposit, asset_owner, @@ -1397,6 +1406,7 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works< LocationToAccountId, >( collator_session_keys: CollatorSessionKeys, + slot_durations: SlotDurations, existential_deposit: BalanceOf, alice_account: AccountIdOf, unwrap_pallet_xcm_event: Box) -> Option>>, @@ -1470,6 +1480,7 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works< other_para_id.into(), included_head, &alice, + &slot_durations, ); // we calculate exact delivery fees _after_ sending the message by weighing the sent diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs index 878dddc9137..905703a9d16 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs @@ -27,7 +27,7 @@ use frame_system::pallet_prelude::BlockNumberFor; use parachains_common::{AccountId, Balance}; use parachains_runtimes_test_utils::{ mock_open_hrmp_channel, AccountIdOf, BalanceOf, CollatorSessionKeys, ExtBuilder, RuntimeHelper, - ValidatorIdOf, XcmReceivedFrom, + SlotDurations, ValidatorIdOf, XcmReceivedFrom, }; use sp_runtime::{traits::StaticLookup, Saturating}; use sp_std::ops::Mul; @@ -52,6 +52,7 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works< LocationToAccountId, >( collator_session_keys: CollatorSessionKeys, + slot_durations: SlotDurations, existential_deposit: BalanceOf, alice_account: AccountIdOf, unwrap_pallet_xcm_event: Box) -> Option>>, @@ -125,6 +126,7 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works< local_bridge_hub_para_id.into(), included_head, &alice, + &slot_durations, ); // we calculate exact delivery fees _after_ sending the message by weighing the sent diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs index 63e64506ec7..9e46dc08654 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs @@ -24,9 +24,14 @@ use bridge_hub_rococo_runtime::{ Executive, ExistentialDeposit, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, SignedExtra, TransactionPayment, UncheckedExtrinsic, }; +use bridge_hub_test_utils::SlotDurations; use codec::{Decode, Encode}; use frame_support::{dispatch::GetDispatchInfo, parameter_types, traits::ConstU8}; -use parachains_common::{rococo::fee::WeightToFee, AccountId, AuraId, Balance}; +use parachains_common::{ + rococo::{consensus::RELAY_CHAIN_SLOT_DURATION_MILLIS, fee::WeightToFee}, + AccountId, AuraId, Balance, SLOT_DURATION, +}; +use sp_consensus_aura::SlotDuration; use sp_core::H160; use sp_keyring::AccountKeyring::Alice; use sp_runtime::{ @@ -95,6 +100,13 @@ fn collator_session_keys() -> bridge_hub_test_utils::CollatorSessionKeys SlotDurations { + SlotDurations { + relay: SlotDuration::from_millis(RELAY_CHAIN_SLOT_DURATION_MILLIS.into()), + para: SlotDuration::from_millis(SLOT_DURATION), + } +} + bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!( Runtime, AllPalletsWithoutSystem, @@ -103,6 +115,7 @@ bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!( WeightToFee, ParachainSystem, collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { @@ -264,6 +277,7 @@ mod bridge_hub_westend_tests { ConstU8<2>, >( collator_session_keys(), + slot_durations(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, SIBLING_PARACHAIN_ID, Box::new(|runtime_event_encoded: Vec| { @@ -288,6 +302,7 @@ mod bridge_hub_westend_tests { // from Westend from_parachain::relayed_incoming_message_works::( collator_session_keys(), + slot_durations(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID, BridgeHubWestendChainId::get(), @@ -304,6 +319,7 @@ mod bridge_hub_westend_tests { // for Westend from_parachain::complex_relay_extrinsic_works::( collator_session_keys(), + slot_durations(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID, SIBLING_PARACHAIN_ID, @@ -459,6 +475,7 @@ mod bridge_hub_bulletin_tests { ConstU8<2>, >( collator_session_keys(), + slot_durations(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, SIBLING_PARACHAIN_ID, Box::new(|runtime_event_encoded: Vec| { @@ -483,6 +500,7 @@ mod bridge_hub_bulletin_tests { // from Bulletin from_grandpa_chain::relayed_incoming_message_works::( collator_session_keys(), + slot_durations(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, RococoBulletinChainId::get(), SIBLING_PARACHAIN_ID, @@ -498,6 +516,7 @@ mod bridge_hub_bulletin_tests { // for Bulletin from_grandpa_chain::complex_relay_extrinsic_works::( collator_session_keys(), + slot_durations(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, SIBLING_PARACHAIN_ID, RococoBulletinChainId::get(), diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs index 1237a231390..91d69b80420 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs @@ -18,7 +18,7 @@ use bp_polkadot_core::Signature; use bridge_common_config::{DeliveryRewardInBalance, RequiredStakeForStakeAndSlash}; -use bridge_hub_test_utils::test_cases::from_parachain; +use bridge_hub_test_utils::{test_cases::from_parachain, SlotDurations}; use bridge_hub_westend_runtime::{ bridge_common_config, bridge_to_rococo_config, xcm_config::{RelayNetwork, WestendLocation, XcmConfig}, @@ -33,7 +33,11 @@ use bridge_to_rococo_config::{ }; use codec::{Decode, Encode}; use frame_support::{dispatch::GetDispatchInfo, parameter_types, traits::ConstU8}; -use parachains_common::{westend::fee::WeightToFee, AccountId, AuraId, Balance}; +use parachains_common::{ + westend::{consensus::RELAY_CHAIN_SLOT_DURATION_MILLIS, fee::WeightToFee}, + AccountId, AuraId, Balance, SLOT_DURATION, +}; +use sp_consensus_aura::SlotDuration; use sp_keyring::AccountKeyring::Alice; use sp_runtime::{ generic::{Era, SignedPayload}, @@ -111,6 +115,13 @@ fn collator_session_keys() -> bridge_hub_test_utils::CollatorSessionKeys SlotDurations { + SlotDurations { + relay: SlotDuration::from_millis(RELAY_CHAIN_SLOT_DURATION_MILLIS.into()), + para: SlotDuration::from_millis(SLOT_DURATION), + } +} + bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!( Runtime, AllPalletsWithoutSystem, @@ -119,6 +130,7 @@ bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!( WeightToFee, ParachainSystem, collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { @@ -229,6 +241,7 @@ fn message_dispatch_routing_works() { ConstU8<2>, >( collator_session_keys(), + slot_durations(), bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID, SIBLING_PARACHAIN_ID, Box::new(|runtime_event_encoded: Vec| { @@ -252,6 +265,7 @@ fn message_dispatch_routing_works() { fn relayed_incoming_message_works() { from_parachain::relayed_incoming_message_works::( collator_session_keys(), + slot_durations(), bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID, bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, BridgeHubRococoChainId::get(), @@ -267,6 +281,7 @@ fn relayed_incoming_message_works() { pub fn complex_relay_extrinsic_works() { from_parachain::complex_relay_extrinsic_works::( collator_session_keys(), + slot_durations(), bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID, bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, SIBLING_PARACHAIN_ID, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs index 5eca85d3112..acf0f2c7162 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs @@ -39,7 +39,7 @@ use bridge_runtime_common::{ use frame_support::traits::{Get, OnFinalize, OnInitialize}; use frame_system::pallet_prelude::BlockNumberFor; use parachains_runtimes_test_utils::{ - AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, + AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, SlotDurations, }; use sp_keyring::AccountKeyring::*; use sp_runtime::{traits::Header as HeaderT, AccountId32}; @@ -107,6 +107,7 @@ where /// Also verifies relayer transaction signed extensions work as intended. pub fn relayed_incoming_message_works( collator_session_key: CollatorSessionKeys, + slot_durations: SlotDurations, runtime_para_id: u32, bridged_chain_id: bp_runtime::ChainId, sibling_parachain_id: u32, @@ -136,6 +137,7 @@ pub fn relayed_incoming_message_works( RuntimeHelper::MPI, >( collator_session_key, + slot_durations, runtime_para_id, sibling_parachain_id, local_relay_chain_id, @@ -205,6 +207,7 @@ pub fn relayed_incoming_message_works( /// Also verifies relayer transaction signed extensions work as intended. pub fn complex_relay_extrinsic_works( collator_session_key: CollatorSessionKeys, + slot_durations: SlotDurations, runtime_para_id: u32, sibling_parachain_id: u32, bridged_chain_id: bp_runtime::ChainId, @@ -237,6 +240,7 @@ pub fn complex_relay_extrinsic_works( RuntimeHelper::MPI, >( collator_session_key, + slot_durations, runtime_para_id, sibling_parachain_id, local_relay_chain_id, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs index 6e638b7b350..8a86c5bb72f 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs @@ -40,7 +40,7 @@ use bridge_runtime_common::{ use frame_support::traits::{Get, OnFinalize, OnInitialize}; use frame_system::pallet_prelude::BlockNumberFor; use parachains_runtimes_test_utils::{ - AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, + AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, SlotDurations, }; use sp_keyring::AccountKeyring::*; use sp_runtime::{traits::Header as HeaderT, AccountId32}; @@ -112,6 +112,7 @@ where /// Also verifies relayer transaction signed extensions work as intended. pub fn relayed_incoming_message_works( collator_session_key: CollatorSessionKeys, + slot_durations: SlotDurations, runtime_para_id: u32, bridged_para_id: u32, bridged_chain_id: bp_runtime::ChainId, @@ -146,6 +147,7 @@ pub fn relayed_incoming_message_works( RuntimeHelper::MPI, >( collator_session_key, + slot_durations, runtime_para_id, sibling_parachain_id, local_relay_chain_id, @@ -244,6 +246,7 @@ pub fn relayed_incoming_message_works( /// Also verifies relayer transaction signed extensions work as intended. pub fn complex_relay_extrinsic_works( collator_session_key: CollatorSessionKeys, + slot_durations: SlotDurations, runtime_para_id: u32, bridged_para_id: u32, sibling_parachain_id: u32, @@ -281,6 +284,7 @@ pub fn complex_relay_extrinsic_works( RuntimeHelper::MPI, >( collator_session_key, + slot_durations, runtime_para_id, sibling_parachain_id, local_relay_chain_id, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs index ba58aeb046e..4f634c184aa 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs @@ -31,7 +31,7 @@ use frame_system::pallet_prelude::BlockNumberFor; use pallet_bridge_grandpa::{BridgedBlockHash, BridgedHeader}; use parachains_common::AccountId; use parachains_runtimes_test_utils::{ - mock_open_hrmp_channel, AccountIdOf, CollatorSessionKeys, RuntimeCallOf, + mock_open_hrmp_channel, AccountIdOf, CollatorSessionKeys, RuntimeCallOf, SlotDurations, }; use sp_core::Get; use sp_keyring::AccountKeyring::*; @@ -220,6 +220,7 @@ pub fn relayer_id_at_bridged_chain, /// with proofs (finality, message) independently submitted. pub fn relayed_incoming_message_works( collator_session_key: CollatorSessionKeys, + slot_durations: SlotDurations, runtime_para_id: u32, sibling_parachain_id: u32, local_relay_chain_id: NetworkId, @@ -272,6 +273,7 @@ pub fn relayed_incoming_message_works( sibling_parachain_id.into(), included_head, &alice, + &slot_durations, ); // set up relayer details and proofs diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs index eb7ba132168..ce939692644 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs @@ -45,7 +45,7 @@ use frame_system::pallet_prelude::BlockNumberFor; use parachains_common::AccountId; use parachains_runtimes_test_utils::{ mock_open_hrmp_channel, AccountIdOf, BalanceOf, CollatorSessionKeys, ExtBuilder, RuntimeCallOf, - XcmReceivedFrom, + SlotDurations, XcmReceivedFrom, }; use sp_runtime::{traits::Zero, AccountId32}; use xcm::{latest::prelude::*, AlwaysLatest}; @@ -419,6 +419,7 @@ pub fn message_dispatch_routing_works< NetworkDistanceAsParentCount, >( collator_session_key: CollatorSessionKeys, + slot_durations: SlotDurations, runtime_para_id: u32, sibling_parachain_id: u32, unwrap_cumulus_pallet_parachain_system_event: Box< @@ -529,6 +530,7 @@ pub fn message_dispatch_routing_works< sibling_parachain_id.into(), included_head, &alice, + &slot_durations, ); let result = <>::MessageDispatch>::dispatch( diff --git a/cumulus/parachains/runtimes/test-utils/src/lib.rs b/cumulus/parachains/runtimes/test-utils/src/lib.rs index 88e878c73a3..eb75c2f7ee0 100644 --- a/cumulus/parachains/runtimes/test-utils/src/lib.rs +++ b/cumulus/parachains/runtimes/test-utils/src/lib.rs @@ -29,7 +29,6 @@ use frame_support::{ weights::Weight, }; use frame_system::pallet_prelude::{BlockNumberFor, HeaderFor}; -use parachains_common::SLOT_DURATION; use polkadot_parachain_primitives::primitives::{ HeadData, HrmpChannelId, RelayChainBlockNumber, XcmpMessageFormat, }; @@ -115,6 +114,11 @@ impl, included_head: HeaderFor, slot_digest: &[u8], + slot_durations: &SlotDurations, ) -> DispatchResult where HrmpChannelOpener: frame_support::inherent::ProvideInherent< @@ -348,6 +353,7 @@ impl< target_para_id.into(), included_head, slot_digest, + slot_durations, ); } @@ -493,12 +499,12 @@ pub fn mock_open_hrmp_channel< recipient: ParaId, included_head: HeaderFor, mut slot_digest: &[u8], + slot_durations: &SlotDurations, ) { - const RELAY_CHAIN_SLOT_DURATION: SlotDuration = SlotDuration::from_millis(6000); let slot = Slot::decode(&mut slot_digest).expect("failed to decode digest"); // Convert para slot to relay chain. - let timestamp = slot.saturating_mul(SLOT_DURATION); - let relay_slot = Slot::from_timestamp(timestamp.into(), RELAY_CHAIN_SLOT_DURATION); + let timestamp = slot.saturating_mul(slot_durations.para.as_millis()); + let relay_slot = Slot::from_timestamp(timestamp.into(), slot_durations.relay); let n = 1_u32; let mut sproof_builder = RelayStateSproofBuilder { diff --git a/cumulus/polkadot-parachain/src/command.rs b/cumulus/polkadot-parachain/src/command.rs index 04d618f66c7..a7319b6dfbb 100644 --- a/cumulus/polkadot-parachain/src/command.rs +++ b/cumulus/polkadot-parachain/src/command.rs @@ -695,9 +695,7 @@ pub fn run() -> Result<()> { .map(|r| r.0) .map_err(Into::into), - AssetHubKusama | - AssetHubRococo | - AssetHubWestend => + AssetHubKusama | AssetHubWestend => crate::service::start_asset_hub_node::< RuntimeApi, AuraId, @@ -706,6 +704,15 @@ pub fn run() -> Result<()> { .map(|r| r.0) .map_err(Into::into), + AssetHubRococo => + crate::service::start_asset_hub_lookahead_node::< + RuntimeApi, + AuraId, + >(config, polkadot_config, collator_options, id, hwbench) + .await + .map(|r| r.0) + .map_err(Into::into), + CollectivesPolkadot | CollectivesWestend => crate::service::start_generic_aura_node::< RuntimeApi, diff --git a/cumulus/polkadot-parachain/src/service.rs b/cumulus/polkadot-parachain/src/service.rs index 81d0c9d3980..61b9cbbd80d 100644 --- a/cumulus/polkadot-parachain/src/service.rs +++ b/cumulus/polkadot-parachain/src/service.rs @@ -976,6 +976,7 @@ pub async fn start_rococo_parachain_node( proposer, collator_service, authoring_duration: Duration::from_millis(1500), + reinitialize: false, }; let fut = aura::run::< @@ -1291,7 +1292,7 @@ where Ok(BasicQueue::new(verifier, Box::new(block_import), None, &spawner, registry)) } -/// Start an aura powered parachain node. Asset Hub and Collectives use this. +/// Start an aura powered parachain node. Collectives uses this. pub async fn start_generic_aura_node( parachain_config: Configuration, polkadot_config: Configuration, @@ -1530,6 +1531,159 @@ where .await } +/// Start a shell node which should later transition into an Aura powered parachain node. Asset Hub +/// uses this because at genesis, Asset Hub was on the `shell` runtime which didn't have Aura and +/// needs to sync and upgrade before it can run `AuraApi` functions. +/// +/// Uses the lookahead collator to support async backing. +#[sc_tracing::logging::prefix_logs_with("Parachain")] +pub async fn start_asset_hub_lookahead_node( + parachain_config: Configuration, + polkadot_config: Configuration, + collator_options: CollatorOptions, + para_id: ParaId, + hwbench: Option, +) -> sc_service::error::Result<(TaskManager, Arc>)> +where + RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue + + sp_api::Metadata + + sp_session::SessionKeys + + sp_api::ApiExt + + sp_offchain::OffchainWorkerApi + + sp_block_builder::BlockBuilder + + cumulus_primitives_core::CollectCollationInfo + + sp_consensus_aura::AuraApi::Pair as Pair>::Public> + + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi + + frame_rpc_system::AccountNonceApi + + cumulus_primitives_aura::AuraUnincludedSegmentApi, + <::Pair as Pair>::Signature: + TryFrom> + std::hash::Hash + sp_runtime::traits::Member + Codec, +{ + start_node_impl::( + parachain_config, + polkadot_config, + collator_options, + CollatorSybilResistance::Resistant, // Aura + para_id, + |_| Ok(RpcModule::new(())), + aura_build_import_queue::<_, AuraId>, + |client, + block_import, + prometheus_registry, + telemetry, + task_manager, + relay_chain_interface, + transaction_pool, + sync_oracle, + keystore, + relay_chain_slot_duration, + para_id, + collator_key, + overseer_handle, + announce_block, + backend| { + let relay_chain_interface2 = relay_chain_interface.clone(); + + let collator_service = CollatorService::new( + client.clone(), + Arc::new(task_manager.spawn_handle()), + announce_block, + client.clone(), + ); + + let spawner = task_manager.spawn_handle(); + + let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( + spawner, + client.clone(), + transaction_pool, + prometheus_registry, + telemetry.clone(), + ); + + let collation_future = Box::pin(async move { + // Start collating with the `shell` runtime while waiting for an upgrade to an Aura + // compatible runtime. + let mut request_stream = cumulus_client_collator::relay_chain_driven::init( + collator_key.clone(), + para_id, + overseer_handle.clone(), + ) + .await; + while let Some(request) = request_stream.next().await { + let pvd = request.persisted_validation_data().clone(); + let last_head_hash = + match ::Header::decode(&mut &pvd.parent_head.0[..]) { + Ok(header) => header.hash(), + Err(e) => { + log::error!("Could not decode the head data: {e}"); + request.complete(None); + continue + }, + }; + + // Check if we have upgraded to an Aura compatible runtime and transition if + // necessary. + if client + .runtime_api() + .has_api::>(last_head_hash) + .unwrap_or(false) + { + // Respond to this request before transitioning to Aura. + request.complete(None); + break + } + } + + // Move to Aura consensus. + let slot_duration = match cumulus_client_consensus_aura::slot_duration(&*client) { + Ok(d) => d, + Err(e) => { + log::error!("Could not get Aura slot duration: {e}"); + return + }, + }; + + let proposer = Proposer::new(proposer_factory); + + let params = AuraParams { + create_inherent_data_providers: move |_, ()| async move { Ok(()) }, + block_import, + para_client: client.clone(), + para_backend: backend, + relay_client: relay_chain_interface2, + code_hash_provider: move |block_hash| { + client.code_at(block_hash).ok().map(|c| ValidationCode::from(c).hash()) + }, + sync_oracle, + keystore, + collator_key, + para_id, + overseer_handle, + slot_duration, + relay_chain_slot_duration, + proposer, + collator_service, + authoring_duration: Duration::from_millis(1500), + reinitialize: true, /* we need to always re-initialize for asset-hub moving + * to aura */ + }; + + aura::run::::Pair, _, _, _, _, _, _, _, _, _>(params) + .await + }); + + let spawner = task_manager.spawn_essential_handle(); + spawner.spawn_essential("cumulus-asset-hub-collator", None, collation_future); + + Ok(()) + }, + hwbench, + ) + .await +} + /// Start an aura powered parachain node which uses the lookahead collator to support async backing. /// This node is basic in the sense that its runtime api doesn't include common contents such as /// transaction payment. Used for aura glutton. @@ -1615,6 +1769,7 @@ where proposer, collator_service, authoring_duration: Duration::from_millis(1500), + reinitialize: false, }; let fut = diff --git a/polkadot/node/collation-generation/src/lib.rs b/polkadot/node/collation-generation/src/lib.rs index b8c9c1a36e4..cfa75d7b441 100644 --- a/polkadot/node/collation-generation/src/lib.rs +++ b/polkadot/node/collation-generation/src/lib.rs @@ -143,6 +143,16 @@ impl CollationGenerationSubsystem { } false }, + Ok(FromOrchestra::Communication { + msg: CollationGenerationMessage::Reinitialize(config), + }) => { + if self.config.is_none() { + gum::error!(target: LOG_TARGET, "no initial initialization"); + } else { + self.config = Some(Arc::new(config)); + } + false + }, Ok(FromOrchestra::Communication { msg: CollationGenerationMessage::SubmitCollation(params), }) => { diff --git a/polkadot/node/subsystem-types/src/messages.rs b/polkadot/node/subsystem-types/src/messages.rs index c7675c84b91..1d5d82b57fd 100644 --- a/polkadot/node/subsystem-types/src/messages.rs +++ b/polkadot/node/subsystem-types/src/messages.rs @@ -830,8 +830,10 @@ pub enum ProvisionerMessage { /// Message to the Collation Generation subsystem. #[derive(Debug)] pub enum CollationGenerationMessage { - /// Initialize the collation generation subsystem + /// Initialize the collation generation subsystem. Initialize(CollationGenerationConfig), + /// Reinitialize the collation generation subsystem, overriding the existing config. + Reinitialize(CollationGenerationConfig), /// Submit a collation to the subsystem. This will package it into a signed /// [`CommittedCandidateReceipt`] and distribute along the network to validators. /// diff --git a/prdoc/pr_2826.prdoc b/prdoc/pr_2826.prdoc new file mode 100644 index 00000000000..70de795a100 --- /dev/null +++ b/prdoc/pr_2826.prdoc @@ -0,0 +1,10 @@ +title: Enable async backing on asset-hub-rococo + +doc: + - audience: Runtime User + description: | + Async backing has been enabled on Asset Hub Rococo, which now targets 6s block times. + +crates: + - name: asset-hub-rococo-runtime + - name: polkadot-parachain-bin \ No newline at end of file -- GitLab From deb72f432dd8adf25fb58db7c3a21d747274c5ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 22 Jan 2024 11:31:37 +0100 Subject: [PATCH 101/392] sc-informant: Respect `--disable-log-color` (#3009) Changes `sc-informant` to respect the `--disable-log-color` CLI flag. Closes: https://github.com/paritytech/polkadot-sdk/issues/2795 --------- Co-authored-by: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> --- prdoc/pr_3009.prdoc | 10 ++++ substrate/client/cli/src/config.rs | 6 +-- substrate/client/informant/src/display.rs | 45 ++++++------------ substrate/client/informant/src/lib.rs | 58 ++++++++++++++++++++--- substrate/client/service/src/config.rs | 8 ++-- 5 files changed, 82 insertions(+), 45 deletions(-) create mode 100644 prdoc/pr_3009.prdoc diff --git a/prdoc/pr_3009.prdoc b/prdoc/pr_3009.prdoc new file mode 100644 index 00000000000..2a55f3d7d32 --- /dev/null +++ b/prdoc/pr_3009.prdoc @@ -0,0 +1,10 @@ +title: "sc-informant: Respect `--disable-log-color`" + +doc: + - audience: Node Operator + description: | + Fixes some places that weren't respecting the `--disable-log-color` CLI flag. + +crates: + - name: "sc-informant" + - name: "sc-service" diff --git a/substrate/client/cli/src/config.rs b/substrate/client/cli/src/config.rs index b842df5a690..170173c8c28 100644 --- a/substrate/client/cli/src/config.rs +++ b/substrate/client/cli/src/config.rs @@ -27,8 +27,8 @@ use names::{Generator, Name}; use sc_service::{ config::{ BasePath, Configuration, DatabaseSource, KeystoreConfig, NetworkConfiguration, - NodeKeyConfig, OffchainWorkerConfig, PrometheusConfig, PruningMode, Role, RpcMethods, - TelemetryEndpoints, TransactionPoolOptions, WasmExecutionMethod, + NodeKeyConfig, OffchainWorkerConfig, OutputFormat, PrometheusConfig, PruningMode, Role, + RpcMethods, TelemetryEndpoints, TransactionPoolOptions, WasmExecutionMethod, }, BlocksPruning, ChainSpec, TracingReceiver, }; @@ -516,7 +516,7 @@ pub trait CliConfiguration: Sized { announce_block: self.announce_block()?, role, base_path, - informant_output_format: Default::default(), + informant_output_format: OutputFormat { enable_color: !self.disable_log_color()? }, runtime_cache_size, }) } diff --git a/substrate/client/informant/src/display.rs b/substrate/client/informant/src/display.rs index bcf3794032f..cdbb83b6596 100644 --- a/substrate/client/informant/src/display.rs +++ b/substrate/client/informant/src/display.rs @@ -142,37 +142,20 @@ impl InformantDisplay { ("⚙️ ", format!("Preparing{}", speed), format!(", target=#{target}")), }; - if self.format.enable_color { - info!( - target: "substrate", - "{} {}{} ({} peers), best: #{} ({}), finalized #{} ({}), {} {}", - level, - Colour::White.bold().paint(&status), - target, - Colour::White.bold().paint(format!("{}", num_connected_peers)), - Colour::White.bold().paint(format!("{}", best_number)), - best_hash, - Colour::White.bold().paint(format!("{}", finalized_number)), - info.chain.finalized_hash, - Colour::Green.paint(format!("⬇ {}", TransferRateFormat(avg_bytes_per_sec_inbound))), - Colour::Red.paint(format!("⬆ {}", TransferRateFormat(avg_bytes_per_sec_outbound))), - ) - } else { - info!( - target: "substrate", - "{} {}{} ({} peers), best: #{} ({}), finalized #{} ({}), ⬇ {} ⬆ {}", - level, - status, - target, - num_connected_peers, - best_number, - best_hash, - finalized_number, - info.chain.finalized_hash, - TransferRateFormat(avg_bytes_per_sec_inbound), - TransferRateFormat(avg_bytes_per_sec_outbound), - ) - } + info!( + target: "substrate", + "{} {}{} ({} peers), best: #{} ({}), finalized #{} ({}), {} {}", + level, + self.format.print_with_color(Colour::White.bold(), status), + target, + self.format.print_with_color(Colour::White.bold(), num_connected_peers), + self.format.print_with_color(Colour::White.bold(), best_number), + best_hash, + self.format.print_with_color(Colour::White.bold(), finalized_number), + info.chain.finalized_hash, + self.format.print_with_color(Colour::Green, format!("⬇ {}", TransferRateFormat(avg_bytes_per_sec_inbound))), + self.format.print_with_color(Colour::Red, format!("⬆ {}", TransferRateFormat(avg_bytes_per_sec_outbound))), + ) } } diff --git a/substrate/client/informant/src/lib.rs b/substrate/client/informant/src/lib.rs index b072f8551f9..7db80bb2d97 100644 --- a/substrate/client/informant/src/lib.rs +++ b/substrate/client/informant/src/lib.rs @@ -18,7 +18,7 @@ //! Console informant. Prints sync progress and block events. Runs on the calling thread. -use ansi_term::Colour; +use ansi_term::{Colour, Style}; use futures::prelude::*; use futures_timer::Delay; use log::{debug, info, trace}; @@ -51,6 +51,47 @@ impl Default for OutputFormat { } } +enum ColorOrStyle { + Color(Colour), + Style(Style), +} + +impl From for ColorOrStyle { + fn from(value: Colour) -> Self { + Self::Color(value) + } +} + +impl From diff --git a/docs/sdk/headers/theme.css b/docs/sdk/headers/theme.css new file mode 100644 index 00000000000..bb9254ec4a8 --- /dev/null +++ b/docs/sdk/headers/theme.css @@ -0,0 +1,16 @@ +:root { + --polkadot-pink: #E6007A ; + --polkadot-green: #56F39A ; + --polkadot-lime: #D3FF33 ; + --polkadot-cyan: #00B2FF ; + --polkadot-purple: #552BBF ; + } + +body > nav.sidebar > div.sidebar-crate > a > img { + /* logo width, given that the sidebar width is 200px; */ + width: 190px; +} + +body nav.sidebar { + flex: 0 0 250px; +} diff --git a/docs/sdk/headers/toc.html b/docs/sdk/headers/toc.html deleted file mode 100644 index a4a074cb4f3..00000000000 --- a/docs/sdk/headers/toc.html +++ /dev/null @@ -1,54 +0,0 @@ - - diff --git a/docs/sdk/src/guides/your_first_pallet/mod.rs b/docs/sdk/src/guides/your_first_pallet/mod.rs index 29cdda36ed1..20a8639b270 100644 --- a/docs/sdk/src/guides/your_first_pallet/mod.rs +++ b/docs/sdk/src/guides/your_first_pallet/mod.rs @@ -128,8 +128,8 @@ //! //! Recall that within our pallet, (almost) all blocks of code are generic over ``. And, //! because `trait Config: frame_system::Config`, we can get access to all items in `Config` (or -//! `frame_system::Config`) using `T::NameOfItem`. This is all within the boundaries of how Rust -//! traits and generics work. If unfamiliar with this pattern, read +//! `frame_system::Config`) using `T::NameOfItem`. This is all within the boundaries of how +//! Rust traits and generics work. If unfamiliar with this pattern, read //! [`crate::reference_docs::trait_based_programming`] before going further. //! //! Crucially, a typical FRAME runtime contains a `struct Runtime`. The main role of this `struct` @@ -270,7 +270,7 @@ #![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", config_v2)] //! //! > These `Runtime*` types are better explained in -//! > [`crate::reference_docs::frame_composite_enums`]. +//! > [`crate::reference_docs::frame_runtime_types`]. //! //! Then, we can rewrite the `transfer` dispatchable as such: #![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", transfer_v2)] @@ -285,7 +285,6 @@ //! [`crate::guides::your_first_pallet::pallet_v2::tests::runtime_v2::RuntimeEvent`]. //! //! -//! //! ## What Next? //! //! The following topics where used in this guide, but not covered in depth. It is suggested to @@ -293,7 +292,7 @@ //! //! - [`crate::reference_docs::safe_defensive_programming`]. //! - [`crate::reference_docs::frame_origin`]. -//! - [`crate::reference_docs::frame_composite_enums`]. +//! - [`crate::reference_docs::frame_runtime_types`]. //! - The pallet we wrote in this guide was using `dev_mode`, learn more in //! [`frame::pallet_macros::config`]. //! - Learn more about the individual pallet items/macros, such as event and errors and call, in diff --git a/docs/sdk/src/lib.rs b/docs/sdk/src/lib.rs index 075d9ddaffe..e211476d251 100644 --- a/docs/sdk/src/lib.rs +++ b/docs/sdk/src/lib.rs @@ -15,7 +15,7 @@ //! - Start by learning about the the [`polkadot_sdk`], its structure and context. //! - Then, head over the [`guides`]. This modules contains in-depth guides about the most important //! user-journeys of the Polkadot SDK. -//! - Whilst reading the guides, you might find back-links to [`crate::reference_docs`]. +//! - Whilst reading the guides, you might find back-links to [`reference_docs`]. //! - Finally, is the parent website of this crate that contains the //! list of further tools related to the Polkadot SDK. //! @@ -25,6 +25,11 @@ #![doc = simple_mermaid::mermaid!("../../mermaid/IA.mmd")] #![warn(rustdoc::broken_intra_doc_links)] #![warn(rustdoc::private_intra_doc_links)] +#![doc(html_favicon_url = "https://polkadot.network/favicon-32x32.png")] +#![doc( + html_logo_url = "https://europe1.discourse-cdn.com/standard21/uploads/polkadot2/original/1X/eb57081e2bb7c39e5fcb1a98b443e423fa4448ae.svg" +)] +#![doc(issue_tracker_base_url = "https://github.com/paritytech/polkadot-sdk/issues")] /// Meta information about this crate, how it is built, what principles dictates its evolution and /// how one can contribute to it. diff --git a/docs/sdk/src/meta_contributing.rs b/docs/sdk/src/meta_contributing.rs index 7ecf8b0adfd..fcdcea9934b 100644 --- a/docs/sdk/src/meta_contributing.rs +++ b/docs/sdk/src/meta_contributing.rs @@ -101,7 +101,7 @@ //! * Before even getting started, what is with all of this ``? We link to //! [`crate::reference_docs::trait_based_programming`]. //! * First, the name. Why is this called `pallet::call`? This goes back to `enum Call`, which is -//! explained in [`crate::reference_docs::frame_composite_enums`]. Build on top of this! +//! explained in [`crate::reference_docs::frame_runtime_types`]. Build on top of this! //! * Then, what is `origin`? Just an account id? [`crate::reference_docs::frame_origin`]. //! * Then, what is `DispatchResult`? Why is this called *dispatch*? Probably something that can be //! explained in the documentation of [`frame::prelude::DispatchResult`]. @@ -138,7 +138,9 @@ //! injected, run: //! //! ```sh -//! SKIP_WASM_BUILD=1 RUSTDOCFLAGS="--html-in-header $(pwd)/docs/sdk/headers/toc.html" cargo doc -p polkadot-sdk-docs --no-deps --open +//! SKIP_WASM_BUILD=1 \ +//! RUSTDOCFLAGS="--html-in-header $(pwd)/docs/sdk/headers/header.html --extend-css $(pwd)/docs/sdk/headers/theme.css --default-theme=ayu" \ +//! cargo doc -p polkadot-sdk-docs --no-deps --open //! ``` //! //! If even faster build time for docs is needed, you can temporarily remove most of the diff --git a/docs/sdk/src/reference_docs/extrinsic_encoding.rs b/docs/sdk/src/reference_docs/extrinsic_encoding.rs index 9008f8f835f..8c8568a228f 100644 --- a/docs/sdk/src/reference_docs/extrinsic_encoding.rs +++ b/docs/sdk/src/reference_docs/extrinsic_encoding.rs @@ -127,7 +127,7 @@ //! runtimes, a call is represented as an enum of enums, where the outer enum represents the FRAME //! pallet being called, and the inner enum represents the call being made within that pallet, and //! any arguments to it. Read more about the call enum -//! [here][crate::reference_docs::frame_composite_enums]. +//! [here][crate::reference_docs::frame_runtime_types]. //! //! FRAME `Call` enums are automatically generated, and end up looking something like this: #![doc = docify::embed!("./src/reference_docs/extrinsic_encoding.rs", call_data)] diff --git a/docs/sdk/src/reference_docs/frame_composite_enums.rs b/docs/sdk/src/reference_docs/frame_composite_enums.rs deleted file mode 100644 index 6051cd53446..00000000000 --- a/docs/sdk/src/reference_docs/frame_composite_enums.rs +++ /dev/null @@ -1 +0,0 @@ -//! # FRAME Composite Enums diff --git a/docs/sdk/src/reference_docs/frame_origin.rs b/docs/sdk/src/reference_docs/frame_origin.rs index a4078377cd7..49533157b01 100644 --- a/docs/sdk/src/reference_docs/frame_origin.rs +++ b/docs/sdk/src/reference_docs/frame_origin.rs @@ -1,14 +1,260 @@ //! # FRAME Origin //! -//! Notes: -//! -//! - Def talk about account abstraction and how it is a solved issue in frame. See Gav's talk in -//! Protocol Berg 2023 -//! - system's raw origin, how it is amalgamated with other origins into one type -//! [`frame_composite_enums`] -//! - signed origin -//! - unsigned origin, link to [`fee_less_runtime`] -//! - Root origin, how no one can obtain it. -//! - Abstract origin: how FRAME allows you to express "origin is 2/3 of the this body or 1/2 of -//! that body or half of the token holders". -//! - `type CustomOrigin: EnsureOrigin<_>` in pallets. +//! Let's start by clarifying a common wrong assumption about Origin: +//! +//! **ORIGIN IS NOT AN ACCOUNT ID**. +//! +//! FRAME's origin abstractions allow you to convey meanings far beyond just an account-id being the +//! caller of an extrinsic. Nonetheless, an account-id having signed an extrinsic is one of the +//! meanings that an origin can convey. This is the commonly used [`frame_system::ensure_signed`], +//! where the return value happens to be an account-id. +//! +//! Instead, let's establish the following as the correct definition of an origin: +//! +//! > The origin type represents the privilege level of the caller of an extrinsic. +//! +//! That is, an extrinsic, through checking the origin, can *express what privilege level it wishes +//! to impose on the caller of the extrinsic*. One of those checks can be as simple as "*any account +//! that has signed a statement can pass*". +//! +//! But the origin system can also express more abstract and complicated privilege levels. For +//! example: +//! +//! * If the majority of token holders agreed upon this. This is more or less what the +//! [`pallet_democracy`] does under the hood ([reference](https://github.com/paritytech/polkadot-sdk/blob/edd95b3749754d2ed0c5738588e872c87be91624/substrate/frame/democracy/src/lib.rs#L1603-L1633)). +//! * If a specific ratio of an instance of [`pallet_collective`]/DAO agrees upon this. +//! * If another consensus system, for example a bridged network or a parachain, agrees upon this. +//! * If the majority of validator/authority set agrees upon this[^1]. +//! * If caller holds a particular NFT. +//! +//! and many more. +//! +//! ## Context +//! +//! First, let's look at where the `origin` type is encountered in a typical pallet. The `origin: +//! OriginFor` has to be the first argument of any given callable extrinsic in FRAME: +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", call_simple)] +//! +//! Typically, the code of an extrinsic starts with an origin check, such as +//! [`frame_system::ensure_signed`]. +//! +//! Note that [`OriginFor`](frame_system::pallet_prelude::OriginFor) is merely a shorthand for +//! [`frame_system::Config::RuntimeOrigin`]. Given the name prefix `Runtime`, we can learn that +//! `RuntimeOrigin` is similar to `RuntimeCall` and others, a runtime composite enum that is +//! amalgamated at the runtime level. Read [`crate::reference_docs::frame_runtime_types`] to +//! familiarize yourself with these types. +//! +//! To understand this better, we will next create a pallet with a custom origin, which will add a +//! new variant to `RuntimeOrigin`. +//! +//! ## Adding Custom Pallet Origin to the Runtime +//! +//! For example, given a pallet that defines the following custom origin: +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", custom_origin)] +//! +//! And a runtime with the following pallets: +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", runtime_exp)] +//! +//! The type [`crate::reference_docs::frame_origin::runtime_for_origin::RuntimeOrigin`] is expanded. +//! This `RuntimeOrigin` contains a variant for the [`frame_system::RawOrigin`] and the custom +//! origin of the pallet. +//! +//! > Notice how the [`frame_system::ensure_signed`] is nothing more than a `match` statement. If +//! > you want to know where the actual origin of an extrinsic is set (and the signature +//! > verification happens, if any), see +//! > [`sp_runtime::generic::CheckedExtrinsic#trait-implementations`], specifically +//! > [`sp_runtime::traits::Applyable`]'s implementation. +//! +//! ## Asserting on a Custom Internal Origin +//! +//! In order to assert on a custom origin that is defined within your pallet, we need a way to first +//! convert the `::RuntimeOrigin` into the local `enum Origin` of the +//! current pallet. This is a common process that is explained in +//! [`crate::reference_docs::frame_runtime_types# +//! adding-further-constraints-to-runtime-composite-enums`]. +//! +//! We use the same process here to express that `RuntimeOrigin` has a number of additional bounds, +//! as follows. +//! +//! 1. Defining a custom `RuntimeOrigin` with further bounds in the pallet. +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", custom_origin_bound)] +//! +//! 2. Using it in the pallet. +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", custom_origin_usage)] +//! +//! ## Asserting on a Custom External Origin +//! +//! Very often, a pallet wants to have a parameterized origin that is **NOT** defined within the +//! pallet. In other words, a pallet wants to delegate an origin check to something that is +//! specified later at the runtime level. Like many other parameterizations in FRAME, this implies +//! adding a new associated type to `trait Config`. +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", external_origin_def)] +//! +//! Then, within the pallet, we can simply use this "unknown" origin check type: +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", external_origin_usage)] +//! +//! Finally, at the runtime, any implementation of [`frame::traits::EnsureOrigin`] can be passed. +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", external_origin_provide)] +//! +//! Indeed, some of these implementations of [`frame::traits::EnsureOrigin`] are similar to the ones +//! that we know about: [`frame::runtime::prelude::EnsureSigned`], +//! [`frame::runtime::prelude::EnsureSignedBy`], [`frame::runtime::prelude::EnsureRoot`], +//! [`frame::runtime::prelude::EnsureNone`], etc. But, there are also many more that are not known +//! to us, and are defined in other pallets. +//! +//! For example, [`pallet_collective`] defines [`pallet_collective::EnsureMember`] and +//! [`pallet_collective::EnsureProportionMoreThan`] and many more, which is exactly what we alluded +//! to earlier in this document. +//! +//! Make sure to check the full list of [implementors of +//! `EnsureOrigin`](frame::traits::EnsureOrigin#implementors) for more inspiration. +//! +//! ## Obtaining Abstract Origins +//! +//! So far we have learned that FRAME pallets can assert on custom and abstract origin types, +//! whether they are defined within the pallet or not. But how can we obtain these abstract origins? +//! +//! > All extrinsics that come from the outer world can generally only be obtained as either +//! > `signed` or `none` origin. +//! +//! Generally, these abstract origins are only obtained within the runtime, when a call is +//! dispatched within the runtime. +//! +//! ## Further References +//! +//! - [Gavin Wood's speech about FRAME features at Protocol Berg 2023.](https://youtu.be/j7b8Upipmeg?si=83_XUgYuJxMwWX4g&t=195) +//! - [A related StackExchange question.](https://substrate.stackexchange.com/questions/10992/how-do-you-find-the-public-key-for-the-medium-spender-track-origin) +//! +//! [^1]: Inherents are essentially unsigned extrinsics that need an [`frame_system::ensure_none`] +//! origin check, and through the virtue of being an inherent, are agreed upon by all validators. + +use frame::prelude::*; + +#[frame::pallet(dev_mode)] +pub mod pallet_for_origin { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(_); + + #[docify::export(call_simple)] + #[pallet::call] + impl Pallet { + pub fn do_something(_origin: OriginFor) -> DispatchResult { + // ^^^^^^^^^^^^^^^^^^^^^ + todo!(); + } + } +} + +#[frame::pallet(dev_mode)] +pub mod pallet_with_custom_origin { + use super::*; + + #[docify::export(custom_origin_bound)] + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeOrigin: From<::RuntimeOrigin> + + Into::RuntimeOrigin>>; + } + + #[pallet::pallet] + pub struct Pallet(_); + + #[docify::export(custom_origin)] + /// A dummy custom origin. + #[pallet::origin] + #[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] + pub enum Origin { + /// If all holders of a particular NFT have agreed upon this. + AllNftHolders, + /// If all validators have agreed upon this. + ValidatorSet, + } + + #[docify::export(custom_origin_usage)] + #[pallet::call] + impl Pallet { + pub fn only_validators(origin: OriginFor) -> DispatchResult { + // first, we convert from `::RuntimeOrigin` to `::RuntimeOrigin` + let local_runtime_origin = <::RuntimeOrigin as From< + ::RuntimeOrigin, + >>::from(origin); + // then we convert to `origin`, if possible + let local_origin = + local_runtime_origin.into().map_err(|_| "invalid origin type provided")?; + ensure!(matches!(local_origin, Origin::ValidatorSet), "Not authorized"); + todo!(); + } + } +} + +pub mod runtime_for_origin { + use super::pallet_with_custom_origin; + use frame::{runtime::prelude::*, testing_prelude::*}; + + #[docify::export(runtime_exp)] + construct_runtime!( + pub struct Runtime { + System: frame_system, + PalletWithCustomOrigin: pallet_with_custom_origin, + } + ); + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + impl frame_system::Config for Runtime { + type Block = MockBlock; + } + + impl pallet_with_custom_origin::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + } +} + +#[frame::pallet(dev_mode)] +pub mod pallet_with_external_origin { + use super::*; + #[docify::export(external_origin_def)] + #[pallet::config] + pub trait Config: frame_system::Config { + type ExternalOrigin: EnsureOrigin; + } + + #[pallet::pallet] + pub struct Pallet(_); + + #[docify::export(external_origin_usage)] + #[pallet::call] + impl Pallet { + pub fn externally_checked_ext(origin: OriginFor) -> DispatchResult { + let _ = T::ExternalOrigin::ensure_origin(origin)?; + todo!(); + } + } +} + +pub mod runtime_for_external_origin { + use super::*; + use frame::{runtime::prelude::*, testing_prelude::*}; + + construct_runtime!( + pub struct Runtime { + System: frame_system, + PalletWithExternalOrigin: pallet_with_external_origin, + } + ); + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + impl frame_system::Config for Runtime { + type Block = MockBlock; + } + + #[docify::export(external_origin_provide)] + impl pallet_with_external_origin::Config for Runtime { + type ExternalOrigin = EnsureSigned<::AccountId>; + } +} diff --git a/docs/sdk/src/reference_docs/frame_runtime_types.rs b/docs/sdk/src/reference_docs/frame_runtime_types.rs new file mode 100644 index 00000000000..b5838b79e51 --- /dev/null +++ b/docs/sdk/src/reference_docs/frame_runtime_types.rs @@ -0,0 +1,306 @@ +//! # FRAME Runtime Types +//! +//! This reference document briefly explores the idea around types generated at the runtime level by +//! the FRAME macros. +//! +//! > As of now, many of these important types are generated within the internals of +//! > [`construct_runtime`], and there is no easy way for you to visually know they exist. +//! > [#polkadot-sdk#1378](https://github.com/paritytech/polkadot-sdk/pull/1378) is meant to +//! > significantly improve this. Exploring the rust-docs of a runtime, such as [`runtime`] which is +//! > defined in this module is as of now the best way to learn about these types. +//! +//! ## Composite Enums +//! +//! Many types within a FRAME runtime follow the following structure: +//! +//! * Each individual pallet defines a type, for example `Foo`. +//! * At the runtime level, these types are amalgamated into a single type, for example +//! `RuntimeFoo`. +//! +//! As the names suggest, all composite enums in a FRAME runtime start their name with `Runtime`. +//! For example, `RuntimeCall` is a representation of the most high level `Call`-able type in the +//! runtime. +//! +//! Composite enums are generally convertible to their individual parts as such: +#![doc = simple_mermaid::mermaid!("../../../mermaid/outer_runtime_types.mmd")] +//! +//! In that one can always convert from the inner type into the outer type, but not vice versa. This +//! is usually expressed by implementing `From`, `TryFrom`, `From>` and similar traits. +//! +//! ### Example +//! +//! We provide the following two pallets: [`pallet_foo`] and [`pallet_bar`]. Each define a +//! dispatchable, and `Foo` also defines a custom origin. Lastly, `Bar` defines an additional +//! `GenesisConfig`. +#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", pallet_foo)] +#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", pallet_bar)] +//! +//! Let's explore how each of these affect the [`RuntimeCall`], [`RuntimeOrigin`] and +//! [`RuntimeGenesisConfig`] generated in [`runtime`] by respectively. +//! +//! As observed, [`RuntimeCall`] has 3 variants, one for each pallet and one for `frame_system`. If +//! you explore further, you will soon realize that each variant is merely a pointer to the `Call` +//! type in each pallet, for example [`pallet_foo::Call`]. +//! +//! [`RuntimeOrigin`]'s [`OriginCaller`] has two variants, one for system, and one for `pallet_foo` +//! which utilized [`frame::pallet_macros::origin`]. +//! +//! Finally, [`RuntimeGenesisConfig`] is composed of `frame_system` and a variant for `pallet_bar`'s +//! [`pallet_bar::GenesisConfig`]. +//! +//! You can find other composite enums by scanning [`runtime`] for other types who's name starts +//! with `Runtime`. Some of the more noteworthy ones are: +//! +//! - [`RuntimeEvent`] +//! - [`RuntimeError`] +//! - [`RuntimeHoldReason`] +//! +//! ### Adding Further Constraints to Runtime Composite Enums +//! +//! This section explores a common scenario where a pallet has access to one of these runtime +//! composite enums, but it wishes to further specify it by adding more trait bounds to it. +//! +//! Let's take the example of `RuntimeCall`. This is an associated type in +//! [`frame_system::Config::RuntimeCall`], and all pallets have access to this type, because they +//! have access to [`frame_system::Config`]. Finally, this type is meant to be set to outer call of +//! the entire runtime. +//! +//! But, let's not forget that this is information that *we know*, and the Rust compiler does not. +//! All that the rust compiler knows about this type is *ONLY* what the trait bounds of +//! [`frame_system::Config::RuntimeCall`] are specifying: +#![doc = docify::embed!("../../substrate/frame/system/src/lib.rs", system_runtime_call)] +//! +//! So, when at a given pallet, one accesses `::RuntimeCall`, the type is +//! extremely opaque from the perspective of the Rust compiler. +//! +//! How can a pallet access the `RuntimeCall` type with further constraints? For example, each +//! pallet has its own `enum Call`, and knows that its local `Call` is a part of `RuntimeCall`, +//! therefore there should be a `impl From> for RuntimeCall`. +//! +//! The only way to express this using Rust's associated types is for the pallet to **define its own +//! associated type `RuntimeCall`, and further specify what it thinks `RuntimeCall` should be**. +//! +//! In this case, we will want to assert the existence of [`frame::traits::IsSubType`], which is +//! very similar to [`TryFrom`]. +#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", custom_runtime_call)] +//! +//! And indeed, at the runtime level, this associated type would be the same `RuntimeCall` that is +//! passed to `frame_system`. +#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", pallet_with_specific_runtime_call_impl)] +//! +//! > In other words, the degree of specificity that [`frame_system::Config::RuntimeCall`] has is +//! > not enough for the pallet to work with. Therefore, the pallet has to define its own associated +//! > type representing `RuntimeCall`. +//! +//! Another way to look at this is: +//! +//! `pallet_with_specific_runtime_call::Config::RuntimeCall` and `frame_system::Config::RuntimeCall` +//! are two different representations of the same concrete type that is only known when the runtime +//! is being constructed. +//! +//! Now, within this pallet, this new `RuntimeCall` can be used, and it can use its new trait +//! bounds, such as being [`frame::traits::IsSubType`]: +#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", custom_runtime_call_usages)] +//! +//! ### Asserting Equality of Multiple Runtime Composite Enums +//! +//! Recall that in the above example, `::RuntimeCall` and `::RuntimeCall` are expected to be equal types, but at the compile-time we +//! have to represent them with two different associated types with different bounds. Would it not +//! be cool if we had a test to make sure they actually resolve to the same concrete type once the +//! runtime is constructed? The following snippet exactly does that: +#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", assert_equality)] +//! +//! We leave it to the reader to further explore what [`frame::traits::Hooks::integrity_test`] is, +//! and what [`core::any::TypeId`] is. Another way to assert this is using +//! [`frame::traits::IsType`]. +//! +//! ## Type Aliases +//! +//! A number of type aliases are generated by the `construct_runtime` which are also noteworthy: +//! +//! * [`runtime::PalletFoo`] is an alias to [`pallet_foo::Pallet`]. Same for `PalletBar`, and +//! `System` +//! * [`runtime::AllPalletsWithSystem`] is an alias for a tuple of all of the above. This type is +//! important to FRAME internals such as `executive`, as it implements traits such as +//! [`frame::traits::Hooks`]. +//! +//! ## Further Details +//! +//! * [`crate::reference_docs::frame_origin`] explores further details about the usage of +//! `RuntimeOrigin`. +//! * [`RuntimeCall`] is a particularly interesting composite enum as it dictates the encoding of an +//! extrinsic. See [`crate::reference_docs::signed_extensions`] for more information. +//! * See the documentation of [`construct_runtime`]. +//! * See the corresponding lecture in the [pba-book](https://polkadot-blockchain-academy.github.io/pba-book/frame/outer-enum/page.html). +//! +//! +//! [`construct_runtime`]: frame::runtime::prelude::construct_runtime +//! [`runtime::PalletFoo`]: crate::reference_docs::frame_runtime_types::runtime::PalletFoo +//! [`runtime::AllPalletsWithSystem`]: crate::reference_docs::frame_runtime_types::runtime::AllPalletsWithSystem +//! [`runtime`]: crate::reference_docs::frame_runtime_types::runtime +//! [`pallet_foo`]: crate::reference_docs::frame_runtime_types::pallet_foo +//! [`pallet_foo::Call`]: crate::reference_docs::frame_runtime_types::pallet_foo::Call +//! [`pallet_foo::Pallet`]: crate::reference_docs::frame_runtime_types::pallet_foo::Pallet +//! [`pallet_bar`]: crate::reference_docs::frame_runtime_types::pallet_bar +//! [`pallet_bar::GenesisConfig`]: crate::reference_docs::frame_runtime_types::pallet_bar::GenesisConfig +//! [`RuntimeEvent`]: crate::reference_docs::frame_runtime_types::runtime::RuntimeEvent +//! [`RuntimeGenesisConfig`]: +//! crate::reference_docs::frame_runtime_types::runtime::RuntimeGenesisConfig +//! [`RuntimeOrigin`]: crate::reference_docs::frame_runtime_types::runtime::RuntimeOrigin +//! [`OriginCaller`]: crate::reference_docs::frame_runtime_types::runtime::OriginCaller +//! [`RuntimeError`]: crate::reference_docs::frame_runtime_types::runtime::RuntimeError +//! [`RuntimeCall`]: crate::reference_docs::frame_runtime_types::runtime::RuntimeCall +//! [`RuntimeHoldReason`]: crate::reference_docs::frame_runtime_types::runtime::RuntimeHoldReason + +use frame::prelude::*; + +#[docify::export] +#[frame::pallet(dev_mode)] +pub mod pallet_foo { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::origin] + #[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] + pub enum Origin { + A, + B, + } + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::call] + impl Pallet { + pub fn foo(_origin: OriginFor) -> DispatchResult { + todo!(); + } + + pub fn other(_origin: OriginFor) -> DispatchResult { + todo!(); + } + } +} + +#[docify::export] +#[frame::pallet(dev_mode)] +pub mod pallet_bar { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::genesis_config] + #[derive(DefaultNoBound)] + pub struct GenesisConfig { + pub initial_account: Option, + } + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) {} + } + + #[pallet::call] + impl Pallet { + pub fn bar(_origin: OriginFor) -> DispatchResult { + todo!(); + } + } +} + +pub mod runtime { + use super::{pallet_bar, pallet_foo}; + use frame::{runtime::prelude::*, testing_prelude::*}; + + #[docify::export(runtime_exp)] + construct_runtime!( + pub struct Runtime { + System: frame_system, + PalletFoo: pallet_foo, + PalletBar: pallet_bar, + } + ); + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + impl frame_system::Config for Runtime { + type Block = MockBlock; + } + + impl pallet_foo::Config for Runtime {} + impl pallet_bar::Config for Runtime {} +} + +#[frame::pallet(dev_mode)] +pub mod pallet_with_specific_runtime_call { + use super::*; + use frame::traits::IsSubType; + + #[docify::export(custom_runtime_call)] + /// A pallet that wants to further narrow down what `RuntimeCall` is. + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeCall: IsSubType>; + } + + #[pallet::pallet] + pub struct Pallet(_); + + // note that this pallet needs some `call` to have a `enum Call`. + #[pallet::call] + impl Pallet { + pub fn foo(_origin: OriginFor) -> DispatchResult { + todo!(); + } + } + + #[docify::export(custom_runtime_call_usages)] + impl Pallet { + fn _do_something_useful_with_runtime_call(call: ::RuntimeCall) { + // check if the runtime call given is of this pallet's variant. + let _maybe_my_call: Option<&Call> = call.is_sub_type(); + todo!(); + } + } + + #[docify::export(assert_equality)] + #[pallet::hooks] + impl Hooks> for Pallet { + fn integrity_test() { + use core::any::TypeId; + assert_eq!( + TypeId::of::<::RuntimeCall>(), + TypeId::of::<::RuntimeCall>() + ); + } + } +} + +pub mod runtime_with_specific_runtime_call { + use super::pallet_with_specific_runtime_call; + use frame::{runtime::prelude::*, testing_prelude::*}; + + construct_runtime!( + pub struct Runtime { + System: frame_system, + PalletWithSpecificRuntimeCall: pallet_with_specific_runtime_call, + } + ); + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + impl frame_system::Config for Runtime { + type Block = MockBlock; + } + + #[docify::export(pallet_with_specific_runtime_call_impl)] + impl pallet_with_specific_runtime_call::Config for Runtime { + // an implementation of `IsSubType` is provided by `construct_runtime`. + type RuntimeCall = RuntimeCall; + } +} diff --git a/docs/sdk/src/reference_docs/mod.rs b/docs/sdk/src/reference_docs/mod.rs index c16122ee428..760bb442c16 100644 --- a/docs/sdk/src/reference_docs/mod.rs +++ b/docs/sdk/src/reference_docs/mod.rs @@ -43,16 +43,16 @@ pub mod extrinsic_encoding; // TODO: @jsdw https://github.com/paritytech/polkadot-sdk-docs/issues/42 pub mod signed_extensions; -/// Learn about *"Origin"* A topic in FRAME that enables complex account abstractions to be built. -// TODO: @shawntabrizi https://github.com/paritytech/polkadot-sdk-docs/issues/43 +/// Learn about *Origins*, a topic in FRAME that enables complex account abstractions to be built. pub mod frame_origin; /// Learn about how to write safe and defensive code in your FRAME runtime. // TODO: @CrackTheCode016 https://github.com/paritytech/polkadot-sdk-docs/issues/44 pub mod safe_defensive_programming; -/// Learn about composite enums in FRAME-based runtimes, such as "RuntimeEvent" and "RuntimeCall". -pub mod frame_composite_enums; +/// Learn about composite enums and other runtime level types, such as "RuntimeEvent" and +/// "RuntimeCall". +pub mod frame_runtime_types; /// Learn about how to make a pallet/runtime that is fee-less and instead uses another mechanism to /// control usage and sybil attacks. diff --git a/substrate/frame/src/lib.rs b/substrate/frame/src/lib.rs index a1715ba4900..a2e5d726fdd 100644 --- a/substrate/frame/src/lib.rs +++ b/substrate/frame/src/lib.rs @@ -163,6 +163,12 @@ pub mod runtime { ConstU32, ConstU64, ConstU8, }; + /// Primary types used to parameterize `EnsureOrigin` and `EnsureRootWithArg`. + pub use frame_system::{ + EnsureNever, EnsureNone, EnsureRoot, EnsureRootWithSuccess, EnsureSigned, + EnsureSignedBy, + }; + /// Types to define your runtime version. pub use sp_version::{create_runtime_str, runtime_version, RuntimeVersion}; diff --git a/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs b/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs index b421d2aaffa..83049919d01 100644 --- a/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs +++ b/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs @@ -104,7 +104,7 @@ pub fn expand_outer_origin( #[doc = #doc_string] #[derive(Clone)] pub struct RuntimeOrigin { - caller: OriginCaller, + pub caller: OriginCaller, filter: #scrate::__private::sp_std::rc::Rc::RuntimeCall) -> bool>>, } diff --git a/substrate/frame/support/procedural/src/lib.rs b/substrate/frame/support/procedural/src/lib.rs index 20b8d74310f..441b21e26ff 100644 --- a/substrate/frame/support/procedural/src/lib.rs +++ b/substrate/frame/support/procedural/src/lib.rs @@ -1480,22 +1480,11 @@ pub fn validate_unsigned(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// The `#[pallet::origin]` attribute allows you to define some origin for the pallet. /// -/// Item must be either a type alias, an enum, or a struct. It needs to be public. -/// -/// E.g.: -/// -/// ```ignore -/// #[pallet::origin] -/// pub struct Origin(PhantomData<(T)>); -/// ``` -/// -/// **WARNING**: modifying origin changes the outer runtime origin. This outer runtime origin -/// can be stored on-chain (e.g. in `pallet-scheduler`), thus any change must be done with care -/// as it might require some migration. +/// --- /// -/// NOTE: for instantiable pallets, the origin must be generic over `T` and `I`. +/// **Rust-Analyzer users**: See the documentation of the Rust item in +/// `frame_support::pallet_macros::origin`. #[proc_macro_attribute] pub fn origin(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs index cd12da6de54..26fc1fe42c1 100644 --- a/substrate/frame/support/src/lib.rs +++ b/substrate/frame/support/src/lib.rs @@ -2274,9 +2274,8 @@ pub mod pallet_macros { pub use frame_support_procedural::{ composite_enum, config, disable_frame_system_supertrait_check, error, event, extra_constants, feeless_if, generate_deposit, generate_store, getter, hooks, - import_section, inherent, no_default, no_default_bounds, origin, pallet_section, - storage_prefix, storage_version, type_value, unbounded, validate_unsigned, weight, - whitelist_storage, + import_section, inherent, no_default, no_default_bounds, pallet_section, storage_prefix, + storage_version, type_value, unbounded, validate_unsigned, weight, whitelist_storage, }; /// Allows a pallet to declare a set of functions as a *dispatchable extrinsic*. In @@ -2718,7 +2717,7 @@ pub mod pallet_macros { /// } /// ``` pub use frame_support_procedural::storage; - /// This attribute is attached to a function inside an `impl` block annoated with + /// This attribute is attached to a function inside an `impl` block annotated with /// [`pallet::tasks_experimental`](`tasks_experimental`) to define the conditions for a /// given work item to be valid. /// @@ -2726,21 +2725,21 @@ pub mod pallet_macros { /// should have the same signature as the function it is attached to, except that it should /// return a `bool` instead. pub use frame_support_procedural::task_condition; - /// This attribute is attached to a function inside an `impl` block annoated with + /// This attribute is attached to a function inside an `impl` block annotated with /// [`pallet::tasks_experimental`](`tasks_experimental`) to define the index of a given /// work item. /// /// It takes an integer literal as input, which is then used to define the index. This /// index should be unique for each function in the `impl` block. pub use frame_support_procedural::task_index; - /// This attribute is attached to a function inside an `impl` block annoated with + /// This attribute is attached to a function inside an `impl` block annotated with /// [`pallet::tasks_experimental`](`tasks_experimental`) to define an iterator over the /// available work items for a task. /// /// It takes an iterator as input that yields a tuple with same types as the function /// arguments. pub use frame_support_procedural::task_list; - /// This attribute is attached to a function inside an `impl` block annoated with + /// This attribute is attached to a function inside an `impl` block annotated with /// [`pallet::tasks_experimental`](`tasks_experimental`) define the weight of a given work /// item. /// @@ -2773,6 +2772,61 @@ pub mod pallet_macros { /// Now, this can be executed as follows: #[doc = docify::embed!("src/tests/tasks.rs", tasks_work)] pub use frame_support_procedural::tasks_experimental; + + /// Allows a pallet to declare a type as an origin. + /// + /// If defined as such, this type will be amalgamated at the runtime level into + /// `RuntimeOrigin`, very similar to [`call`], [`error`] and [`event`]. See + /// [`composite_enum`] for similar cases. + /// + /// Origin is a complex FRAME topics and is further explained in `polkadot_sdk_docs`. + /// + /// ## Syntax Variants + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// # #[pallet::pallet] + /// # pub struct Pallet(_); + /// /// On the spot declaration. + /// #[pallet::origin] + /// #[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] + /// pub enum Origin { + /// Foo, + /// Bar, + /// } + /// } + /// ``` + /// + /// Or, more commonly used:/ + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// # #[pallet::pallet] + /// # pub struct Pallet(_); + /// #[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] + /// pub enum RawOrigin { + /// Foo, + /// Bar, + /// } + /// + /// #[pallet::origin] + /// pub type Origin = RawOrigin; + /// } + /// ``` + /// + /// ## Warning + /// + /// Modifying any pallet's origin type will cause the runtime level origin type to also + /// change in encoding. If stored anywhere on-chain, this will require a data migration. + pub use frame_support_procedural::origin; } #[deprecated(note = "Will be removed after July 2023; Use `sp_runtime::traits` directly instead.")] diff --git a/substrate/frame/system/src/lib.rs b/substrate/frame/system/src/lib.rs index 1405c7303f8..aa6841c008a 100644 --- a/substrate/frame/system/src/lib.rs +++ b/substrate/frame/system/src/lib.rs @@ -452,6 +452,7 @@ pub mod pallet { + Clone + OriginTrait; + #[docify::export(system_runtime_call)] /// The aggregated `RuntimeCall` type. #[pallet::no_default_bounds] type RuntimeCall: Parameter -- GitLab From 0cc9b9003c019400a8e26c2e1d5679ab654a63dc Mon Sep 17 00:00:00 2001 From: Petr Mensik Date: Tue, 27 Feb 2024 23:50:07 +0100 Subject: [PATCH 314/392] Add Polkadotters bootnoders per IBP application (#3423) Hey everyone, this PR will replace existing Polkadotters bootnodes for Polkadot, Kusama and Westend and add Paseo bootnode to the relay chain suite. At the same time, it will add new bootnodes for all the system parachains, including People on Westend. This PR is a part of our membership in the IBP, meaning that all the bootnodes are hosted on our hardware housed in the data center in Christchurch, New Zealand. All the bootnodes were tested with an empty chain spec file with the following command yielding 1 peer. The test commands used are as follows: ``` ./polkadot --base-path /tmp/node --reserved-only --chain paseo --reserved-nodes "/dns/paseo.bootnodes.polkadotters.com/tcp/30540/wss/p2p/12D3KooWPbbFy4TefEGTRF5eTYhq8LEzc4VAHdNUVCbY4nAnhqPP" ./polkadot --base-path /tmp/node --reserved-only --chain westend --reserved-nodes "/dns/westend.bootnodes.polkadotters.com/tcp/30310/wss/p2p/12D3KooWHPHb64jXMtSRJDrYFATWeLnvChL8NtWVttY67DCH1eC5" ./polkadot --base-path /tmp/node --reserved-only --chain kusama --reserved-nodes "/dns/kusama.bootnodes.polkadotters.com/tcp/30313/wss/p2p/12D3KooWHB5rTeNkQdXNJ9ynvGz8Lpnmsctt7Tvp7mrYv6bcwbPG" ./polkadot --base-path /tmp/node --no-hardware-benchmarks --reserved-only --chain polkadot --reserved-nodes "/dns/polkadot.bootnodes.polkadotters.com/tcp/30316/wss/p2p/12D3KooWPAVUgBaBk6n8SztLrMk8ESByncbAfRKUdxY1nygb9zG3" ./polkadot-parachain --base-path /tmp/node --reserved-only --chain asset-hub-kusama --reserved-nodes "/dns/asset-hub-kusama.bootnodes.polkadotters.com/tcp/30513/wss/p2p/12D3KooWDpk7wVH7RgjErEvbvAZ2kY5VeaAwRJP5ojmn1e8b8UbU" ./polkadot-parachain --base-path /tmp/node --reserved-only --chain asset-hub-polkadot --reserved-nodes "/dns/asset-hub-polkadot.bootnodes.polkadotters.com/tcp/30510/wss/p2p/12D3KooWKbfY9a9oywxMJKiALmt7yhrdQkjXMtvxhhDDN23vG93R" ./polkadot-parachain --base-path /tmp/node --reserved-only --chain asset-hub-westend --reserved-nodes "/dns/asset-hub-westend.bootnodes.polkadotters.com/tcp/30516/wss/p2p/12D3KooWNFYysCqmojxqjjaTfD2VkWBNngfyUKWjcR4WFixfHNTk" ./polkadot-parachain --base-path /tmp/node --reserved-only --chain bridge-hub-kusama --reserved-nodes "/dns/bridge-hub-kusama.bootnodes.polkadotters.com/tcp/30522/wss/p2p/12D3KooWH3pucezRRS5esoYyzZsUkKWcPSByQxEvmM819QL1HPLV" ./polkadot-parachain --base-path /tmp/node --reserved-only --chain bridge-hub-kusama --reserved-nodes "/dns/bridge-hub-kusama.bootnodes.polkadotters.com/tcp/30522/wss/p2p/12D3KooWH3pucezRRS5esoYyzZsUkKWcPSByQxEvmM819QL1HPLV" ./polkadot-parachain --base-path /tmp/node --reserved-only --chain bridge-hub-westend --reserved-nodes "/dns/bridge-hub-westend.bootnodes.polkadotters.com/tcp/30525/wss/p2p/12D3KooWPkwgJofp4GeeRwNgXqkp2aFwdLkCWv3qodpBJLwK43Jj" ./polkadot-parachain --base-path /tmp/node --reserved-only --chain collectives-polkadot --reserved-nodes "/dns/collectives-polkadot.bootnodes.polkadotters.com/tcp/30528/wss/p2p/12D3KooWNohUjvJtGKUa8Vhy8C1ZBB5N8JATB6e7rdLVCioeb3ff" ./polkadot-parachain --base-path /tmp/node --reserved-only --chain collectives-westend --reserved-nodes "/dns/collectives-westend.bootnodes.polkadotters.com/tcp/30531/wss/p2p/12D3KooWAFkXNSBfyPduZVgfS7pj5NuVpbU8Ee5gHeF8wvos7Yqn" ./polkadot-parachain --base-path /tmp/node --reserved-only --chain people-westend --reserved-nodes "/dns/identity-westend.bootnodes.polkadotters.com/tcp/30534/wss/p2p/12D3KooWKr9San6KTM7REJ95cBaDoiciGcWnW8TTftEJgxGF5Ehb" ``` Best regards, Petr, Polkadotters --- cumulus/parachains/chain-specs/asset-hub-kusama.json | 4 +++- cumulus/parachains/chain-specs/asset-hub-polkadot.json | 4 +++- cumulus/parachains/chain-specs/asset-hub-westend.json | 4 +++- cumulus/parachains/chain-specs/bridge-hub-kusama.json | 4 +++- cumulus/parachains/chain-specs/bridge-hub-polkadot.json | 4 +++- cumulus/parachains/chain-specs/bridge-hub-westend.json | 4 +++- cumulus/parachains/chain-specs/collectives-polkadot.json | 4 +++- cumulus/parachains/chain-specs/collectives-westend.json | 4 +++- cumulus/parachains/chain-specs/people-westend.json | 6 ++++-- polkadot/node/service/chain-specs/kusama.json | 4 ++-- polkadot/node/service/chain-specs/paseo.json | 4 +++- polkadot/node/service/chain-specs/polkadot.json | 4 ++-- polkadot/node/service/chain-specs/westend.json | 4 ++-- 13 files changed, 37 insertions(+), 17 deletions(-) diff --git a/cumulus/parachains/chain-specs/asset-hub-kusama.json b/cumulus/parachains/chain-specs/asset-hub-kusama.json index fba74b17f96..654275eade8 100644 --- a/cumulus/parachains/chain-specs/asset-hub-kusama.json +++ b/cumulus/parachains/chain-specs/asset-hub-kusama.json @@ -25,7 +25,9 @@ "/dns/statemine-bootnode.radiumblock.com/tcp/30336/wss/p2p/12D3KooWCKUrE5uaXQ288ko3Ex3zCyozyJLG47KEYTopinnXNtYL", "/dns/mine14.rotko.net/tcp/33524/p2p/12D3KooWJUFnjR2PNbsJhudwPVaWCoZy1acPGKjM2cSuGj345BBu", "/dns/mine14.rotko.net/tcp/34524/ws/p2p/12D3KooWJUFnjR2PNbsJhudwPVaWCoZy1acPGKjM2cSuGj345BBu", - "/dns/mine14.rotko.net/tcp/35524/wss/p2p/12D3KooWJUFnjR2PNbsJhudwPVaWCoZy1acPGKjM2cSuGj345BBu" + "/dns/mine14.rotko.net/tcp/35524/wss/p2p/12D3KooWJUFnjR2PNbsJhudwPVaWCoZy1acPGKjM2cSuGj345BBu", + "/dns/asset-hub-kusama.bootnodes.polkadotters.com/tcp/30511/p2p/12D3KooWDpk7wVH7RgjErEvbvAZ2kY5VeaAwRJP5ojmn1e8b8UbU", + "/dns/asset-hub-kusama.bootnodes.polkadotters.com/tcp/30513/wss/p2p/12D3KooWDpk7wVH7RgjErEvbvAZ2kY5VeaAwRJP5ojmn1e8b8UbU" ], "telemetryEndpoints": null, "protocolId": null, diff --git a/cumulus/parachains/chain-specs/asset-hub-polkadot.json b/cumulus/parachains/chain-specs/asset-hub-polkadot.json index 685a00ddc71..454060d2a87 100644 --- a/cumulus/parachains/chain-specs/asset-hub-polkadot.json +++ b/cumulus/parachains/chain-specs/asset-hub-polkadot.json @@ -25,7 +25,9 @@ "/dns/statemint-bootnode.radiumblock.com/tcp/30333/p2p/12D3KooWLKxHom7f3XawRJqrF8RwiKK5Sj3qZqz5c7hF6eJeXhTx", "/dns/mint14.rotko.net/tcp/33514/p2p/12D3KooWKkzLjYF6M5eEs7nYiqEtRqY8SGVouoCwo3nCWsRnThDW", "/dns/mint14.rotko.net/tcp/34514/ws/p2p/12D3KooWKkzLjYF6M5eEs7nYiqEtRqY8SGVouoCwo3nCWsRnThDW", - "/dns/mint14.rotko.net/tcp/35514/wss/p2p/12D3KooWKkzLjYF6M5eEs7nYiqEtRqY8SGVouoCwo3nCWsRnThDW" + "/dns/mint14.rotko.net/tcp/35514/wss/p2p/12D3KooWKkzLjYF6M5eEs7nYiqEtRqY8SGVouoCwo3nCWsRnThDW", + "/dns/asset-hub-polkadot.bootnodes.polkadotters.com/tcp/30508/p2p/12D3KooWKbfY9a9oywxMJKiALmt7yhrdQkjXMtvxhhDDN23vG93R", + "/dns/asset-hub-polkadot.bootnodes.polkadotters.com/tcp/30510/wss/p2p/12D3KooWKbfY9a9oywxMJKiALmt7yhrdQkjXMtvxhhDDN23vG93R" ], "telemetryEndpoints": null, "protocolId": null, diff --git a/cumulus/parachains/chain-specs/asset-hub-westend.json b/cumulus/parachains/chain-specs/asset-hub-westend.json index 6f42b5f7d8b..670935c9d24 100644 --- a/cumulus/parachains/chain-specs/asset-hub-westend.json +++ b/cumulus/parachains/chain-specs/asset-hub-westend.json @@ -23,7 +23,9 @@ "/dns/westmint-bootnode.radiumblock.com/tcp/30333/p2p/12D3KooWDoq4PVdWm5nzRSvEz3DSSKjVgRhWVUaKyi5JMKwJKYbk", "/dns/wmint14.rotko.net/tcp/33534/p2p/12D3KooWE4UDXqgtTcMCyUQ8S4uvaT8VMzzTBA6NWmKuYwTacWuN", "/dns/wmint14.rotko.net/tcp/34534/ws/p2p/12D3KooWE4UDXqgtTcMCyUQ8S4uvaT8VMzzTBA6NWmKuYwTacWuN", - "/dns/wmint14.rotko.net/tcp/35534/wss/p2p/12D3KooWE4UDXqgtTcMCyUQ8S4uvaT8VMzzTBA6NWmKuYwTacWuN" + "/dns/wmint14.rotko.net/tcp/35534/wss/p2p/12D3KooWE4UDXqgtTcMCyUQ8S4uvaT8VMzzTBA6NWmKuYwTacWuN", + "/dns/asset-hub-westend.bootnodes.polkadotters.com/tcp/30514/p2p/12D3KooWNFYysCqmojxqjjaTfD2VkWBNngfyUKWjcR4WFixfHNTk", + "/dns/asset-hub-westend.bootnodes.polkadotters.com/tcp/30516/wss/p2p/12D3KooWNFYysCqmojxqjjaTfD2VkWBNngfyUKWjcR4WFixfHNTk" ], "telemetryEndpoints": null, "protocolId": null, diff --git a/cumulus/parachains/chain-specs/bridge-hub-kusama.json b/cumulus/parachains/chain-specs/bridge-hub-kusama.json index 0ef81806cc5..90b70b05016 100644 --- a/cumulus/parachains/chain-specs/bridge-hub-kusama.json +++ b/cumulus/parachains/chain-specs/bridge-hub-kusama.json @@ -25,7 +25,9 @@ "/dns/bridgehub-kusama-bootnode.radiumblock.com/tcp/30336/wss/p2p/12D3KooWQMWofXj8v3RroDNnrhv1iURqm8vnaG98AdGnCn2YoDcW", "/dns/kbr13.rotko.net/tcp/33553/p2p/12D3KooWAmBp54mUEYtvsk2kxNEsDbAvdUMcaghxKXgUQxmPEQ66", "/dns/kbr13.rotko.net/tcp/34553/ws/p2p/12D3KooWAmBp54mUEYtvsk2kxNEsDbAvdUMcaghxKXgUQxmPEQ66", - "/dns/kbr13.rotko.net/tcp/35553/wss/p2p/12D3KooWAmBp54mUEYtvsk2kxNEsDbAvdUMcaghxKXgUQxmPEQ66" + "/dns/kbr13.rotko.net/tcp/35553/wss/p2p/12D3KooWAmBp54mUEYtvsk2kxNEsDbAvdUMcaghxKXgUQxmPEQ66", + "/dns/bridge-hub-kusama.bootnodes.polkadotters.com/tcp/30520/p2p/12D3KooWH3pucezRRS5esoYyzZsUkKWcPSByQxEvmM819QL1HPLV", + "/dns/bridge-hub-kusama.bootnodes.polkadotters.com/tcp/30522/wss/p2p/12D3KooWH3pucezRRS5esoYyzZsUkKWcPSByQxEvmM819QL1HPLV" ], "telemetryEndpoints": null, "protocolId": null, diff --git a/cumulus/parachains/chain-specs/bridge-hub-polkadot.json b/cumulus/parachains/chain-specs/bridge-hub-polkadot.json index 130bdf31ef2..a9444b89e1e 100644 --- a/cumulus/parachains/chain-specs/bridge-hub-polkadot.json +++ b/cumulus/parachains/chain-specs/bridge-hub-polkadot.json @@ -21,7 +21,9 @@ "/dns/bridgehub-polkadot-bootnode.radiumblock.com/tcp/30333/p2p/12D3KooWPNZm78tWUmKbta3SXdkqTPsquRc8ekEbJjZsGGi7YiRi", "/dns/pbr13.rotko.net/tcp/33543/p2p/12D3KooWMxZY7tDc2Rh454VaJJ7RexKAXVS6xSBEvTnXSGCnuGDw", "/dns/pbr13.rotko.net/tcp/34543/ws/p2p/12D3KooWMxZY7tDc2Rh454VaJJ7RexKAXVS6xSBEvTnXSGCnuGDw", - "/dns/pbr13.rotko.net/tcp/35543/wss/p2p/12D3KooWMxZY7tDc2Rh454VaJJ7RexKAXVS6xSBEvTnXSGCnuGDw" + "/dns/pbr13.rotko.net/tcp/35543/wss/p2p/12D3KooWMxZY7tDc2Rh454VaJJ7RexKAXVS6xSBEvTnXSGCnuGDw", + "/dns/bridge-hub-polkadot.bootnodes.polkadotters.com/tcp/30517/p2p/12D3KooWLUNE3LHPDa1WrrZaYT7ArK66CLM1bPv7kKz74UcLnQRB", + "/dns/bridge-hub-polkadot.bootnodes.polkadotters.com/tcp/30519/wss/p2p/12D3KooWLUNE3LHPDa1WrrZaYT7ArK66CLM1bPv7kKz74UcLnQRB" ], "telemetryEndpoints": null, "protocolId": null, diff --git a/cumulus/parachains/chain-specs/bridge-hub-westend.json b/cumulus/parachains/chain-specs/bridge-hub-westend.json index 018ab0ee6fd..447207a5810 100644 --- a/cumulus/parachains/chain-specs/bridge-hub-westend.json +++ b/cumulus/parachains/chain-specs/bridge-hub-westend.json @@ -19,7 +19,9 @@ "/dns/bridgehub-westend-bootnode.radiumblock.com/tcp/30336/wss/p2p/12D3KooWBsBArCMxmQyo3feCEqMWuwyhb2LTRK8hmCCJxgrNeMke", "/dns/wbr13.rotko.net/tcp/33563/p2p/12D3KooWJyeRHpxZZbfBCNEgeUFzmRC5AMSAs2tJhjJS1k5hULkD", "/dns/wbr13.rotko.net/tcp/34563/ws/p2p/12D3KooWJyeRHpxZZbfBCNEgeUFzmRC5AMSAs2tJhjJS1k5hULkD", - "/dns/wbr13.rotko.net/tcp/35563/wss/p2p/12D3KooWJyeRHpxZZbfBCNEgeUFzmRC5AMSAs2tJhjJS1k5hULkD" + "/dns/wbr13.rotko.net/tcp/35563/wss/p2p/12D3KooWJyeRHpxZZbfBCNEgeUFzmRC5AMSAs2tJhjJS1k5hULkD", + "/dns/bridge-hub-westend.bootnodes.polkadotters.com/tcp/30523/p2p/12D3KooWPkwgJofp4GeeRwNgXqkp2aFwdLkCWv3qodpBJLwK43Jj", + "/dns/bridge-hub-westend.bootnodes.polkadotters.com/tcp/30525/wss/p2p/12D3KooWPkwgJofp4GeeRwNgXqkp2aFwdLkCWv3qodpBJLwK43Jj" ], "telemetryEndpoints": null, "protocolId": null, diff --git a/cumulus/parachains/chain-specs/collectives-polkadot.json b/cumulus/parachains/chain-specs/collectives-polkadot.json index e9f690234e4..259669cf37a 100644 --- a/cumulus/parachains/chain-specs/collectives-polkadot.json +++ b/cumulus/parachains/chain-specs/collectives-polkadot.json @@ -25,7 +25,9 @@ "/dns/collectives-polkadot-bootnode.radiumblock.com/tcp/30336/wss/p2p/12D3KooWDumvnNwPbBg5inBEapgjKU7ECdMHHgwfYeGWUkzYUE1c", "/dns/pch13.rotko.net/tcp/33573/p2p/12D3KooWRXudHoazPZ9osMfdY38e8CBxQLD4RhrVeHpRSNNpcDtH", "/dns/pch13.rotko.net/tcp/34573/ws/p2p/12D3KooWRXudHoazPZ9osMfdY38e8CBxQLD4RhrVeHpRSNNpcDtH", - "/dns/pch13.rotko.net/tcp/35573/wss/p2p/12D3KooWRXudHoazPZ9osMfdY38e8CBxQLD4RhrVeHpRSNNpcDtH" + "/dns/pch13.rotko.net/tcp/35573/wss/p2p/12D3KooWRXudHoazPZ9osMfdY38e8CBxQLD4RhrVeHpRSNNpcDtH", + "/dns/collectives-polkadot.bootnodes.polkadotters.com/tcp/30526/p2p/12D3KooWNohUjvJtGKUa8Vhy8C1ZBB5N8JATB6e7rdLVCioeb3ff", + "/dns/collectives-polkadot.bootnodes.polkadotters.com/tcp/30528/wss/p2p/12D3KooWNohUjvJtGKUa8Vhy8C1ZBB5N8JATB6e7rdLVCioeb3ff" ], "telemetryEndpoints": null, "protocolId": null, diff --git a/cumulus/parachains/chain-specs/collectives-westend.json b/cumulus/parachains/chain-specs/collectives-westend.json index ffe73b5a05a..e459c631f8b 100644 --- a/cumulus/parachains/chain-specs/collectives-westend.json +++ b/cumulus/parachains/chain-specs/collectives-westend.json @@ -25,7 +25,9 @@ "/dns/westend-collectives-boot-ng.dwellir.com/tcp/443/wss/p2p/12D3KooWPFM93jgm4pgxx8PM8WJKAJF49qia8jRB95uciUQwYh7m", "/dns/wch13.rotko.net/tcp/33593/p2p/12D3KooWPG85zhuSRoyptjLkFD4iJFistjiBmc15JgQ96B4fdXYr", "/dns/wch13.rotko.net/tcp/34593/ws/p2p/12D3KooWPG85zhuSRoyptjLkFD4iJFistjiBmc15JgQ96B4fdXYr", - "/dns/wch13.rotko.net/tcp/35593/wss/p2p/12D3KooWPG85zhuSRoyptjLkFD4iJFistjiBmc15JgQ96B4fdXYr" + "/dns/wch13.rotko.net/tcp/35593/wss/p2p/12D3KooWPG85zhuSRoyptjLkFD4iJFistjiBmc15JgQ96B4fdXYr", + "/dns/collectives-westend.bootnodes.polkadotters.com/tcp/30529/p2p/12D3KooWAFkXNSBfyPduZVgfS7pj5NuVpbU8Ee5gHeF8wvos7Yqn", + "/dns/collectives-westend.bootnodes.polkadotters.com/tcp/30531/wss/p2p/12D3KooWAFkXNSBfyPduZVgfS7pj5NuVpbU8Ee5gHeF8wvos7Yqn" ], "telemetryEndpoints": null, "protocolId": null, diff --git a/cumulus/parachains/chain-specs/people-westend.json b/cumulus/parachains/chain-specs/people-westend.json index fa29853c70b..29fa0c9cde7 100644 --- a/cumulus/parachains/chain-specs/people-westend.json +++ b/cumulus/parachains/chain-specs/people-westend.json @@ -10,7 +10,9 @@ "/dns/westend-people-collator-node-2.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWGVYTVKW7tYe51JvetvGvVLDPXzqQX1mueJgz14FgkmHG", "/dns/westend-people-collator-node-2.parity-testnet.parity.io/tcp/443/wss/p2p/12D3KooWGVYTVKW7tYe51JvetvGvVLDPXzqQX1mueJgz14FgkmHG", "/dns/westend-people-collator-node-3.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWCF1eA2Gap69zgXD7Df3e9DqDUsGoByocggTGejoHjK23", - "/dns/westend-people-collator-node-3.parity-testnet.parity.io/tcp/443/wss/p2p/12D3KooWCF1eA2Gap69zgXD7Df3e9DqDUsGoByocggTGejoHjK23" + "/dns/westend-people-collator-node-3.parity-testnet.parity.io/tcp/443/wss/p2p/12D3KooWCF1eA2Gap69zgXD7Df3e9DqDUsGoByocggTGejoHjK23", + "/dns/identity-westend.bootnodes.polkadotters.com/tcp/30532/p2p/12D3KooWKr9San6KTM7REJ95cBaDoiciGcWnW8TTftEJgxGF5Ehb", + "/dns/identity-westend.bootnodes.polkadotters.com/tcp/30534/wss/p2p/12D3KooWKr9San6KTM7REJ95cBaDoiciGcWnW8TTftEJgxGF5Ehb" ], "telemetryEndpoints": null, "protocolId": null, @@ -79,4 +81,4 @@ "childrenDefault": {} } } -} \ No newline at end of file +} diff --git a/polkadot/node/service/chain-specs/kusama.json b/polkadot/node/service/chain-specs/kusama.json index 979550c7570..fd60cb8b6c1 100644 --- a/polkadot/node/service/chain-specs/kusama.json +++ b/polkadot/node/service/chain-specs/kusama.json @@ -16,8 +16,8 @@ "/dns/boot-node.helikon.io/tcp/7062/wss/p2p/12D3KooWL4KPqfAsPE2aY1g5Zo1CxsDwcdJ7mmAghK7cg6M2fdbD", "/dns/kusama.bootnode.amforc.com/tcp/30333/p2p/12D3KooWLx6nsj6Fpd8biP1VDyuCUjazvRiGWyBam8PsqRJkbUb9", "/dns/kusama.bootnode.amforc.com/tcp/30334/wss/p2p/12D3KooWLx6nsj6Fpd8biP1VDyuCUjazvRiGWyBam8PsqRJkbUb9", - "/dns/kusama-bootnode.polkadotters.com/tcp/30333/p2p/12D3KooWHB5rTeNkQdXNJ9ynvGz8Lpnmsctt7Tvp7mrYv6bcwbPG", - "/dns/kusama-bootnode.polkadotters.com/tcp/30334/wss/p2p/12D3KooWHB5rTeNkQdXNJ9ynvGz8Lpnmsctt7Tvp7mrYv6bcwbPG", + "/dns/kusama.bootnodes.polkadotters.com/tcp/30311/p2p/12D3KooWHB5rTeNkQdXNJ9ynvGz8Lpnmsctt7Tvp7mrYv6bcwbPG", + "/dns/kusama.bootnodes.polkadotters.com/tcp/30313/wss/p2p/12D3KooWHB5rTeNkQdXNJ9ynvGz8Lpnmsctt7Tvp7mrYv6bcwbPG", "/dns/boot-cr.gatotech.network/tcp/33200/p2p/12D3KooWRNZXf99BfzQDE1C8YhuBbuy7Sj18UEf7FNpD8egbURYD", "/dns/boot-cr.gatotech.network/tcp/35200/wss/p2p/12D3KooWRNZXf99BfzQDE1C8YhuBbuy7Sj18UEf7FNpD8egbURYD", "/dns/boot-kusama.metaspan.io/tcp/23012/p2p/12D3KooWE1tq9ZL9AAxMiUBBqy1ENmh5pwfWabnoBPMo8gFPXhn6", diff --git a/polkadot/node/service/chain-specs/paseo.json b/polkadot/node/service/chain-specs/paseo.json index c8f2b58533c..8db75ff137b 100644 --- a/polkadot/node/service/chain-specs/paseo.json +++ b/polkadot/node/service/chain-specs/paseo.json @@ -12,7 +12,9 @@ "/dns/boot-node.helikon.io/tcp/10020/p2p/12D3KooWBetfzZpf6tGihKrqCo5z854Ub4ZNAUUTRT6eYHNh7FYi", "/dns/boot-node.helikon.io/tcp/10022/wss/p2p/12D3KooWBetfzZpf6tGihKrqCo5z854Ub4ZNAUUTRT6eYHNh7FYi", "/dns/pso16.rotko.net/tcp/33246/p2p/12D3KooWRH8eBMhw8c7bucy6pJfy94q4dKpLkF3pmeGohHmemdRu", - "/dns/pso16.rotko.net/tcp/35246/wss/p2p/12D3KooWRH8eBMhw8c7bucy6pJfy94q4dKpLkF3pmeGohHmemdRu" + "/dns/pso16.rotko.net/tcp/35246/wss/p2p/12D3KooWRH8eBMhw8c7bucy6pJfy94q4dKpLkF3pmeGohHmemdRu", + "/dns/paseo.bootnodes.polkadotters.com/tcp/30538/p2p/12D3KooWPbbFy4TefEGTRF5eTYhq8LEzc4VAHdNUVCbY4nAnhqPP", + "/dns/paseo.bootnodes.polkadotters.com/tcp/30540/wss/p2p/12D3KooWPbbFy4TefEGTRF5eTYhq8LEzc4VAHdNUVCbY4nAnhqPP" ], "telemetryEndpoints": [ [ diff --git a/polkadot/node/service/chain-specs/polkadot.json b/polkadot/node/service/chain-specs/polkadot.json index 71dbb900403..c235cdd09d8 100644 --- a/polkadot/node/service/chain-specs/polkadot.json +++ b/polkadot/node/service/chain-specs/polkadot.json @@ -17,8 +17,8 @@ "/dns/boot-node.helikon.io/tcp/7072/wss/p2p/12D3KooWS9ZcvRxyzrSf6p63QfTCWs12nLoNKhGux865crgxVA4H", "/dns/polkadot.bootnode.amforc.com/tcp/30333/p2p/12D3KooWAsuCEVCzUVUrtib8W82Yne3jgVGhQZN3hizko5FTnDg3", "/dns/polkadot.bootnode.amforc.com/tcp/30334/wss/p2p/12D3KooWAsuCEVCzUVUrtib8W82Yne3jgVGhQZN3hizko5FTnDg3", - "/dns/polkadot-bootnode.polkadotters.com/tcp/30333/p2p/12D3KooWPAVUgBaBk6n8SztLrMk8ESByncbAfRKUdxY1nygb9zG3", - "/dns/polkadot-bootnode.polkadotters.com/tcp/30334/wss/p2p/12D3KooWPAVUgBaBk6n8SztLrMk8ESByncbAfRKUdxY1nygb9zG3", + "/dns/polkadot.bootnodes.polkadotters.com/tcp/30314/p2p/12D3KooWPAVUgBaBk6n8SztLrMk8ESByncbAfRKUdxY1nygb9zG3", + "/dns/polkadot.bootnodes.polkadotters.com/tcp/30316/wss/p2p/12D3KooWPAVUgBaBk6n8SztLrMk8ESByncbAfRKUdxY1nygb9zG3", "/dns/boot-cr.gatotech.network/tcp/33100/p2p/12D3KooWK4E16jKk9nRhvC4RfrDVgcZzExg8Q3Q2G7ABUUitks1w", "/dns/boot-cr.gatotech.network/tcp/35100/wss/p2p/12D3KooWK4E16jKk9nRhvC4RfrDVgcZzExg8Q3Q2G7ABUUitks1w", "/dns/boot-polkadot.metaspan.io/tcp/13012/p2p/12D3KooWRjHFApinuqSBjoaDjQHvxwubQSpEVy5hrgC9Smvh92WF", diff --git a/polkadot/node/service/chain-specs/westend.json b/polkadot/node/service/chain-specs/westend.json index 697675871fc..775f3e72ac7 100644 --- a/polkadot/node/service/chain-specs/westend.json +++ b/polkadot/node/service/chain-specs/westend.json @@ -14,8 +14,8 @@ "/dns/boot-node.helikon.io/tcp/7082/wss/p2p/12D3KooWRFDPyT8vA8mLzh6dJoyujn4QNjeqi6Ch79eSMz9beKXC", "/dns/westend.bootnode.amforc.com/tcp/30333/p2p/12D3KooWJ5y9ZgVepBQNW4aabrxgmnrApdVnscqgKWiUu4BNJbC8", "/dns/westend.bootnode.amforc.com/tcp/30334/wss/p2p/12D3KooWJ5y9ZgVepBQNW4aabrxgmnrApdVnscqgKWiUu4BNJbC8", - "/dns/westend-bootnode.polkadotters.com/tcp/30333/p2p/12D3KooWHPHb64jXMtSRJDrYFATWeLnvChL8NtWVttY67DCH1eC5", - "/dns/westend-bootnode.polkadotters.com/tcp/30334/wss/p2p/12D3KooWHPHb64jXMtSRJDrYFATWeLnvChL8NtWVttY67DCH1eC5", + "/dns/westend.bootnodes.polkadotters.com/tcp/30308/p2p/12D3KooWHPHb64jXMtSRJDrYFATWeLnvChL8NtWVttY67DCH1eC5", + "/dns/westend.bootnodes.polkadotters.com/tcp/30310/wss/p2p/12D3KooWHPHb64jXMtSRJDrYFATWeLnvChL8NtWVttY67DCH1eC5", "/dns/boot-cr.gatotech.network/tcp/33300/p2p/12D3KooWQGR1vUhoy6mvQorFp3bZFn6NNezhQZ6NWnVV7tpFgoPd", "/dns/boot-cr.gatotech.network/tcp/35300/wss/p2p/12D3KooWQGR1vUhoy6mvQorFp3bZFn6NNezhQZ6NWnVV7tpFgoPd", "/dns/boot-westend.metaspan.io/tcp/33012/p2p/12D3KooWNTau7iG4G9cUJSwwt2QJP1W88pUf2SgqsHjRU2RL8pfa", -- GitLab From 95da6583602691fd0c8403e9eda26db1e10dafc4 Mon Sep 17 00:00:00 2001 From: Liam Aharon Date: Wed, 28 Feb 2024 13:13:09 +1100 Subject: [PATCH 315/392] Introduce storage attr macro `#[disable_try_decode_storage]` and set it on `System::Events` and `ParachainSystem::HostConfiguration` (#3454) Closes https://github.com/paritytech/polkadot-sdk/issues/2560 Allows marking storage items with `#[disable_try_decode_storage]`, and uses it with `System::Events`. Question: what's the recommended way to write a test for this? I couldn't find a test for similar existing macro `#[whitelist_storage]`. --- cumulus/pallets/parachain-system/src/lib.rs | 1 + prdoc/pr_3454.prdoc | 19 +++++++++++++++ substrate/frame/support/procedural/src/lib.rs | 19 +++++++++++++++ .../procedural/src/pallet/expand/storage.rs | 5 +++- .../procedural/src/pallet/parse/storage.rs | 24 +++++++++++++++++-- substrate/frame/support/src/lib.rs | 17 +++++++++++-- .../storage_invalid_attribute.stderr | 2 +- substrate/frame/system/src/lib.rs | 1 + 8 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 prdoc/pr_3454.prdoc diff --git a/cumulus/pallets/parachain-system/src/lib.rs b/cumulus/pallets/parachain-system/src/lib.rs index d86a67e58f4..3439227bc5b 100644 --- a/cumulus/pallets/parachain-system/src/lib.rs +++ b/cumulus/pallets/parachain-system/src/lib.rs @@ -840,6 +840,7 @@ pub mod pallet { /// /// This data is also absent from the genesis. #[pallet::storage] + #[pallet::disable_try_decode_storage] #[pallet::getter(fn host_configuration)] pub(super) type HostConfiguration = StorageValue<_, AbridgedHostConfiguration>; diff --git a/prdoc/pr_3454.prdoc b/prdoc/pr_3454.prdoc new file mode 100644 index 00000000000..7f564258f23 --- /dev/null +++ b/prdoc/pr_3454.prdoc @@ -0,0 +1,19 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: "Introduce storage attr macro #[disable_try_decode_storage] and set it on System::Events and ParachainSystem::HostConfiguration" + +doc: + - audience: Runtime Dev + description: | + Allows marking storage items with \#[disable_try_decode_storage], which disables that storage item from being decoded + during try_decode_entire_state calls. + + Applied the attribute to System::Events to close https://github.com/paritytech/polkadot-sdk/issues/2560. + Applied the attribute to ParachainSystem::HostConfiguration to resolve periodic issues with it. + +crates: + - name: frame-support-procedural + - name: frame-system + - name: cumulus-pallet-parachain-system + diff --git a/substrate/frame/support/procedural/src/lib.rs b/substrate/frame/support/procedural/src/lib.rs index 441b21e26ff..78729ee3dc3 100644 --- a/substrate/frame/support/procedural/src/lib.rs +++ b/substrate/frame/support/procedural/src/lib.rs @@ -1371,6 +1371,25 @@ pub fn whitelist_storage(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } +/// The optional attribute `#[pallet::disable_try_decode_storage]` will declare the +/// storage as whitelisted from decoding during try-runtime checks. This should only be +/// attached to transient storage which cannot be migrated during runtime upgrades. +/// +/// ### Example +/// ```ignore +/// #[pallet::storage] +/// #[pallet::disable_try_decode_storage] +/// pub(super) type Events = StorageValue<_, Vec>>, ValueQuery>; +/// ``` +/// +/// NOTE: As with all `pallet::*` attributes, this one _must_ be written as +/// `#[pallet::disable_try_decode_storage]` and can only be placed inside a `pallet` module in order +/// for it to work properly. +#[proc_macro_attribute] +pub fn disable_try_decode_storage(_: TokenStream, _: TokenStream) -> TokenStream { + pallet_macro_stub() +} + /// The `#[pallet::type_value]` attribute lets you define a struct implementing the `Get` trait /// to ease the use of storage types. This attribute is meant to be used alongside /// [`#[pallet::storage]`](`macro@storage`) to define a storage's default value. This attribute diff --git a/substrate/frame/support/procedural/src/pallet/expand/storage.rs b/substrate/frame/support/procedural/src/pallet/expand/storage.rs index 96c2c8e3120..937b068cfab 100644 --- a/substrate/frame/support/procedural/src/pallet/expand/storage.rs +++ b/substrate/frame/support/procedural/src/pallet/expand/storage.rs @@ -834,7 +834,10 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream { .storages .iter() .filter_map(|storage| { - if storage.cfg_attrs.is_empty() { + // A little hacky; don't generate for cfg gated storages to not get compile errors + // when building "frame-feature-testing" gated storages in the "frame-support-test" + // crate. + if storage.try_decode && storage.cfg_attrs.is_empty() { let ident = &storage.ident; let gen = &def.type_use_generics(storage.attr_span); Some(quote::quote_spanned!(storage.attr_span => #ident<#gen> )) diff --git a/substrate/frame/support/procedural/src/pallet/parse/storage.rs b/substrate/frame/support/procedural/src/pallet/parse/storage.rs index d1c7ba2e5e3..9d96a18b569 100644 --- a/substrate/frame/support/procedural/src/pallet/parse/storage.rs +++ b/substrate/frame/support/procedural/src/pallet/parse/storage.rs @@ -29,6 +29,7 @@ mod keyword { syn::custom_keyword!(storage_prefix); syn::custom_keyword!(unbounded); syn::custom_keyword!(whitelist_storage); + syn::custom_keyword!(disable_try_decode_storage); syn::custom_keyword!(OptionQuery); syn::custom_keyword!(ResultQuery); syn::custom_keyword!(ValueQuery); @@ -39,11 +40,13 @@ mod keyword { /// * `#[pallet::storage_prefix = "CustomName"]` /// * `#[pallet::unbounded]` /// * `#[pallet::whitelist_storage] +/// * `#[pallet::disable_try_decode_storage]` pub enum PalletStorageAttr { Getter(syn::Ident, proc_macro2::Span), StorageName(syn::LitStr, proc_macro2::Span), Unbounded(proc_macro2::Span), WhitelistStorage(proc_macro2::Span), + DisableTryDecodeStorage(proc_macro2::Span), } impl PalletStorageAttr { @@ -53,6 +56,7 @@ impl PalletStorageAttr { Self::StorageName(_, span) | Self::Unbounded(span) | Self::WhitelistStorage(span) => *span, + Self::DisableTryDecodeStorage(span) => *span, } } } @@ -93,6 +97,9 @@ impl syn::parse::Parse for PalletStorageAttr { } else if lookahead.peek(keyword::whitelist_storage) { content.parse::()?; Ok(Self::WhitelistStorage(attr_span)) + } else if lookahead.peek(keyword::disable_try_decode_storage) { + content.parse::()?; + Ok(Self::DisableTryDecodeStorage(attr_span)) } else { Err(lookahead.error()) } @@ -104,6 +111,7 @@ struct PalletStorageAttrInfo { rename_as: Option, unbounded: bool, whitelisted: bool, + try_decode: bool, } impl PalletStorageAttrInfo { @@ -112,6 +120,7 @@ impl PalletStorageAttrInfo { let mut rename_as = None; let mut unbounded = false; let mut whitelisted = false; + let mut disable_try_decode_storage = false; for attr in attrs { match attr { PalletStorageAttr::Getter(ident, ..) if getter.is_none() => getter = Some(ident), @@ -119,6 +128,8 @@ impl PalletStorageAttrInfo { rename_as = Some(name), PalletStorageAttr::Unbounded(..) if !unbounded => unbounded = true, PalletStorageAttr::WhitelistStorage(..) if !whitelisted => whitelisted = true, + PalletStorageAttr::DisableTryDecodeStorage(..) if !disable_try_decode_storage => + disable_try_decode_storage = true, attr => return Err(syn::Error::new( attr.attr_span(), @@ -127,7 +138,13 @@ impl PalletStorageAttrInfo { } } - Ok(PalletStorageAttrInfo { getter, rename_as, unbounded, whitelisted }) + Ok(PalletStorageAttrInfo { + getter, + rename_as, + unbounded, + whitelisted, + try_decode: !disable_try_decode_storage, + }) } } @@ -186,6 +203,8 @@ pub struct StorageDef { pub unbounded: bool, /// Whether or not reads to this storage key will be ignored by benchmarking pub whitelisted: bool, + /// Whether or not to try to decode the storage key when running try-runtime checks. + pub try_decode: bool, /// Whether or not a default hasher is allowed to replace `_` pub use_default_hasher: bool, } @@ -775,7 +794,7 @@ impl StorageDef { }; let attrs: Vec = helper::take_item_pallet_attrs(&mut item.attrs)?; - let PalletStorageAttrInfo { getter, rename_as, mut unbounded, whitelisted } = + let PalletStorageAttrInfo { getter, rename_as, mut unbounded, whitelisted, try_decode } = PalletStorageAttrInfo::from_attrs(attrs)?; // set all storages to be unbounded if dev_mode is enabled @@ -921,6 +940,7 @@ impl StorageDef { named_generics, unbounded, whitelisted, + try_decode, use_default_hasher, }) } diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs index 26fc1fe42c1..3e97a384275 100644 --- a/substrate/frame/support/src/lib.rs +++ b/substrate/frame/support/src/lib.rs @@ -982,6 +982,7 @@ pub mod pallet_prelude { /// * [`pallet::storage_prefix = "SomeName"`](#palletstorage_prefix--somename-optional) /// * [`pallet::unbounded`](#palletunbounded-optional) /// * [`pallet::whitelist_storage`](#palletwhitelist_storage-optional) +/// * [`pallet::disable_try_decode_storage`](#palletdisable_try_decode_storage-optional) /// * [`cfg(..)`](#cfg-for-storage) (on storage items) /// * [`pallet::type_value`](#type-value-pallettype_value-optional) /// * [`pallet::genesis_config`](#genesis-config-palletgenesis_config-optional) @@ -1498,6 +1499,15 @@ pub mod pallet_prelude { /// [`pallet::whitelist_storage`](frame_support::pallet_macros::whitelist_storage) /// for more info. /// +/// ## `#[pallet::disable_try_decode_storage]` (optional) +/// +/// The optional attribute `#[pallet::disable_try_decode_storage]` will declare the storage as +/// whitelisted state decoding during try-runtime logic. +/// +/// See +/// [`pallet::disable_try_decode_storage`](frame_support::pallet_macros::disable_try_decode_storage) +/// for more info. +/// /// ## `#[cfg(..)]` (for storage) /// The optional attributes `#[cfg(..)]` allow conditional compilation for the storage. /// @@ -2272,8 +2282,8 @@ pub use frame_support_procedural::pallet; /// Contains macro stubs for all of the pallet:: macros pub mod pallet_macros { pub use frame_support_procedural::{ - composite_enum, config, disable_frame_system_supertrait_check, error, event, - extra_constants, feeless_if, generate_deposit, generate_store, getter, hooks, + composite_enum, config, disable_frame_system_supertrait_check, disable_try_decode_storage, + error, event, extra_constants, feeless_if, generate_deposit, generate_store, getter, hooks, import_section, inherent, no_default, no_default_bounds, pallet_section, storage_prefix, storage_version, type_value, unbounded, validate_unsigned, weight, whitelist_storage, }; @@ -2698,6 +2708,8 @@ pub mod pallet_macros { /// * [`macro@getter`]: Creates a custom getter function. /// * [`macro@storage_prefix`]: Overrides the default prefix of the storage item. /// * [`macro@unbounded`]: Declares the storage item as unbounded. + /// * [`macro@disable_try_decode_storage`]: Declares that try-runtime checks should not + /// attempt to decode the storage item. /// /// #### Example /// ``` @@ -2713,6 +2725,7 @@ pub mod pallet_macros { /// #[pallet::getter(fn foo)] /// #[pallet::storage_prefix = "OtherFoo"] /// #[pallet::unbounded] + /// #[pallet::disable_try_decode_storage] /// pub type Foo = StorageValue<_, u32, ValueQuery>; /// } /// ``` diff --git a/substrate/frame/support/test/tests/pallet_ui/storage_invalid_attribute.stderr b/substrate/frame/support/test/tests/pallet_ui/storage_invalid_attribute.stderr index 7f125526edf..519fadaa604 100644 --- a/substrate/frame/support/test/tests/pallet_ui/storage_invalid_attribute.stderr +++ b/substrate/frame/support/test/tests/pallet_ui/storage_invalid_attribute.stderr @@ -1,4 +1,4 @@ -error: expected one of: `getter`, `storage_prefix`, `unbounded`, `whitelist_storage` +error: expected one of: `getter`, `storage_prefix`, `unbounded`, `whitelist_storage`, `disable_try_decode_storage` --> tests/pallet_ui/storage_invalid_attribute.rs:33:12 | 33 | #[pallet::generate_store(pub trait Store)] diff --git a/substrate/frame/system/src/lib.rs b/substrate/frame/system/src/lib.rs index aa6841c008a..c527a483d88 100644 --- a/substrate/frame/system/src/lib.rs +++ b/substrate/frame/system/src/lib.rs @@ -894,6 +894,7 @@ pub mod pallet { /// just in case someone still reads them from within the runtime. #[pallet::storage] #[pallet::whitelist_storage] + #[pallet::disable_try_decode_storage] #[pallet::unbounded] pub(super) type Events = StorageValue<_, Vec>>, ValueQuery>; -- GitLab From 7ec0b8741b4ead5bc85411b30e53b459a03b1938 Mon Sep 17 00:00:00 2001 From: maksimryndin Date: Wed, 28 Feb 2024 05:05:54 +0100 Subject: [PATCH 316/392] Collator overseer builder unification (#3335) resolve https://github.com/paritytech/polkadot-sdk/issues/3116 a follow-up on https://github.com/paritytech/polkadot-sdk/pull/3061#pullrequestreview-1847530265: - [x] reuse collator overseer builder for polkadot-node and collator - [x] run zombienet test (0001-parachains-smoke-test.toml) - [x] make wasm build errors more user-friendly for an easier problem detection when using different toolchains in Rust --------- Co-authored-by: ordian Co-authored-by: s0me0ne-unkn0wn <48632512+s0me0ne-unkn0wn@users.noreply.github.com> --- Cargo.lock | 1 + .../relay-chain-minimal-node/Cargo.toml | 1 + .../src/collator_overseer.rs | 144 +----------------- .../relay-chain-minimal-node/src/lib.rs | 30 ++-- .../relay-chain-minimal-node/src/network.rs | 8 +- .../src/variants/back_garbage_candidate.rs | 15 +- polkadot/node/malus/src/variants/common.rs | 4 - .../variants/dispute_finalized_candidates.rs | 17 +-- .../src/variants/dispute_valid_candidates.rs | 15 +- .../src/variants/suggest_garbage_candidate.rs | 17 +-- .../malus/src/variants/support_disabled.rs | 15 +- polkadot/node/service/src/lib.rs | 13 +- polkadot/node/service/src/overseer.rs | 76 +++------ .../subsystem-types/src/runtime_client.rs | 64 +++++++- .../utils/wasm-builder/src/prerequisites.rs | 20 ++- 15 files changed, 162 insertions(+), 278 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c52feafe7a7..27ba43780ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4166,6 +4166,7 @@ dependencies = [ "polkadot-node-subsystem-util", "polkadot-overseer", "polkadot-primitives", + "polkadot-service", "sc-authority-discovery", "sc-client-api", "sc-network", diff --git a/cumulus/client/relay-chain-minimal-node/Cargo.toml b/cumulus/client/relay-chain-minimal-node/Cargo.toml index 0b1e001e007..98240c92ada 100644 --- a/cumulus/client/relay-chain-minimal-node/Cargo.toml +++ b/cumulus/client/relay-chain-minimal-node/Cargo.toml @@ -24,6 +24,7 @@ polkadot-node-collation-generation = { path = "../../../polkadot/node/collation- polkadot-node-core-runtime-api = { path = "../../../polkadot/node/core/runtime-api" } polkadot-node-core-chain-api = { path = "../../../polkadot/node/core/chain-api" } polkadot-node-core-prospective-parachains = { path = "../../../polkadot/node/core/prospective-parachains" } +polkadot-service = { path = "../../../polkadot/node/service" } # substrate deps sc-authority-discovery = { path = "../../../substrate/client/authority-discovery" } diff --git a/cumulus/client/relay-chain-minimal-node/src/collator_overseer.rs b/cumulus/client/relay-chain-minimal-node/src/collator_overseer.rs index 5f5bf338ef9..f01ef8b05ec 100644 --- a/cumulus/client/relay-chain-minimal-node/src/collator_overseer.rs +++ b/cumulus/client/relay-chain-minimal-node/src/collator_overseer.rs @@ -15,159 +15,29 @@ // along with Polkadot. If not, see . use futures::{select, StreamExt}; -use parking_lot::Mutex; -use std::{collections::HashMap, sync::Arc}; +use std::sync::Arc; -use polkadot_availability_recovery::AvailabilityRecoverySubsystem; -use polkadot_collator_protocol::{CollatorProtocolSubsystem, ProtocolSide}; -use polkadot_network_bridge::{ - Metrics as NetworkBridgeMetrics, NetworkBridgeRx as NetworkBridgeRxSubsystem, - NetworkBridgeTx as NetworkBridgeTxSubsystem, -}; -use polkadot_node_collation_generation::CollationGenerationSubsystem; -use polkadot_node_core_chain_api::ChainApiSubsystem; -use polkadot_node_core_prospective_parachains::ProspectiveParachainsSubsystem; -use polkadot_node_core_runtime_api::RuntimeApiSubsystem; -use polkadot_node_network_protocol::{ - peer_set::{PeerSet, PeerSetProtocolNames}, - request_response::{ - v1::{self, AvailableDataFetchingRequest}, - v2, IncomingRequestReceiver, ReqProtocolNames, - }, -}; -use polkadot_node_subsystem_util::metrics::{prometheus::Registry, Metrics}; use polkadot_overseer::{ - BlockInfo, DummySubsystem, Handle, Overseer, OverseerConnector, OverseerHandle, SpawnGlue, - UnpinHandle, + BlockInfo, Handle, Overseer, OverseerConnector, OverseerHandle, SpawnGlue, UnpinHandle, }; -use polkadot_primitives::CollatorPair; +use polkadot_service::overseer::{collator_overseer_builder, OverseerGenArgs}; -use sc_authority_discovery::Service as AuthorityDiscoveryService; -use sc_network::{NetworkStateInfo, NotificationService}; use sc_service::TaskManager; use sc_utils::mpsc::tracing_unbounded; -use cumulus_primitives_core::relay_chain::{Block, Hash as PHash}; use cumulus_relay_chain_interface::RelayChainError; use crate::BlockChainRpcClient; -/// Arguments passed for overseer construction. -pub(crate) struct CollatorOverseerGenArgs<'a> { - /// Runtime client generic, providing the `ProvieRuntimeApi` trait besides others. - pub runtime_client: Arc, - /// Underlying network service implementation. - pub network_service: Arc>, - /// Syncing oracle. - pub sync_oracle: Box, - /// Underlying authority discovery service. - pub authority_discovery_service: AuthorityDiscoveryService, - /// Receiver for collation request protocol v1. - pub collation_req_receiver_v1: IncomingRequestReceiver, - /// Receiver for collation request protocol v2. - pub collation_req_receiver_v2: IncomingRequestReceiver, - /// Receiver for availability request protocol - pub available_data_req_receiver: IncomingRequestReceiver, - /// Prometheus registry, commonly used for production systems, less so for test. - pub registry: Option<&'a Registry>, - /// Task spawner to be used throughout the overseer and the APIs it provides. - pub spawner: sc_service::SpawnTaskHandle, - /// Determines the behavior of the collator. - pub collator_pair: CollatorPair, - /// Request response protocols - pub req_protocol_names: ReqProtocolNames, - /// Peerset protocols name mapping - pub peer_set_protocol_names: PeerSetProtocolNames, - /// Notification services for validation/collation protocols. - pub notification_services: HashMap>, -} - fn build_overseer( connector: OverseerConnector, - CollatorOverseerGenArgs { - runtime_client, - network_service, - sync_oracle, - authority_discovery_service, - collation_req_receiver_v1, - collation_req_receiver_v2, - available_data_req_receiver, - registry, - spawner, - collator_pair, - req_protocol_names, - peer_set_protocol_names, - notification_services, - }: CollatorOverseerGenArgs<'_>, + args: OverseerGenArgs, ) -> Result< (Overseer, Arc>, OverseerHandle), RelayChainError, > { - let spawner = SpawnGlue(spawner); - let network_bridge_metrics: NetworkBridgeMetrics = Metrics::register(registry)?; - let notification_sinks = Arc::new(Mutex::new(HashMap::new())); - - let builder = Overseer::builder() - .availability_distribution(DummySubsystem) - .availability_recovery(AvailabilityRecoverySubsystem::for_collator( - available_data_req_receiver, - Metrics::register(registry)?, - )) - .availability_store(DummySubsystem) - .bitfield_distribution(DummySubsystem) - .bitfield_signing(DummySubsystem) - .candidate_backing(DummySubsystem) - .candidate_validation(DummySubsystem) - .pvf_checker(DummySubsystem) - .chain_api(ChainApiSubsystem::new(runtime_client.clone(), Metrics::register(registry)?)) - .collation_generation(CollationGenerationSubsystem::new(Metrics::register(registry)?)) - .collator_protocol({ - let side = ProtocolSide::Collator { - peer_id: network_service.local_peer_id(), - collator_pair, - request_receiver_v1: collation_req_receiver_v1, - request_receiver_v2: collation_req_receiver_v2, - metrics: Metrics::register(registry)?, - }; - CollatorProtocolSubsystem::new(side) - }) - .network_bridge_rx(NetworkBridgeRxSubsystem::new( - network_service.clone(), - authority_discovery_service.clone(), - sync_oracle, - network_bridge_metrics.clone(), - peer_set_protocol_names.clone(), - notification_services, - notification_sinks.clone(), - )) - .network_bridge_tx(NetworkBridgeTxSubsystem::new( - network_service, - authority_discovery_service, - network_bridge_metrics, - req_protocol_names, - peer_set_protocol_names, - notification_sinks, - )) - .provisioner(DummySubsystem) - .runtime_api(RuntimeApiSubsystem::new( - runtime_client.clone(), - Metrics::register(registry)?, - spawner.clone(), - )) - .statement_distribution(DummySubsystem) - .prospective_parachains(ProspectiveParachainsSubsystem::new(Metrics::register(registry)?)) - .approval_distribution(DummySubsystem) - .approval_voting(DummySubsystem) - .gossip_support(DummySubsystem) - .dispute_coordinator(DummySubsystem) - .dispute_distribution(DummySubsystem) - .chain_selection(DummySubsystem) - .activation_external_listeners(Default::default()) - .span_per_active_leaf(Default::default()) - .active_leaves(Default::default()) - .supports_parachains(runtime_client) - .metrics(Metrics::register(registry)?) - .spawner(spawner); + let builder = + collator_overseer_builder(args).map_err(|e| RelayChainError::Application(e.into()))?; builder .build_with_connector(connector) @@ -175,7 +45,7 @@ fn build_overseer( } pub(crate) fn spawn_overseer( - overseer_args: CollatorOverseerGenArgs, + overseer_args: OverseerGenArgs, task_manager: &TaskManager, relay_chain_rpc_client: Arc, ) -> Result { diff --git a/cumulus/client/relay-chain-minimal-node/src/lib.rs b/cumulus/client/relay-chain-minimal-node/src/lib.rs index d121d2d3356..4bccca59fe3 100644 --- a/cumulus/client/relay-chain-minimal-node/src/lib.rs +++ b/cumulus/client/relay-chain-minimal-node/src/lib.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use collator_overseer::{CollatorOverseerGenArgs, NewMinimalNode}; +use collator_overseer::NewMinimalNode; use cumulus_relay_chain_interface::{RelayChainError, RelayChainInterface, RelayChainResult}; use cumulus_relay_chain_rpc_interface::{RelayChainRpcClient, RelayChainRpcInterface, Url}; @@ -29,6 +29,7 @@ use polkadot_node_network_protocol::{ use polkadot_node_subsystem_util::metrics::prometheus::Registry; use polkadot_primitives::CollatorPair; +use polkadot_service::{overseer::OverseerGenArgs, IsParachainNode}; use sc_authority_discovery::Service as AuthorityDiscoveryService; use sc_network::{config::FullNetworkConfiguration, Event, NetworkEventStream, NetworkService}; @@ -172,10 +173,10 @@ async fn new_minimal_relay_chain( } let genesis_hash = relay_chain_rpc_client.block_get_hash(Some(0)).await?.unwrap_or_default(); - let peer_set_protocol_names = + let peerset_protocol_names = PeerSetProtocolNames::new(genesis_hash, config.chain_spec.fork_id()); let is_authority = if role.is_authority() { IsAuthority::Yes } else { IsAuthority::No }; - let notification_services = peer_sets_info(is_authority, &peer_set_protocol_names) + let notification_services = peer_sets_info(is_authority, &peerset_protocol_names) .into_iter() .map(|(config, (peerset, service))| { net_config.add_notification_protocol(config); @@ -184,14 +185,14 @@ async fn new_minimal_relay_chain( .collect::>>(); let request_protocol_names = ReqProtocolNames::new(genesis_hash, config.chain_spec.fork_id()); - let (collation_req_receiver_v1, collation_req_receiver_v2, available_data_req_receiver) = + let (collation_req_v1_receiver, collation_req_v2_receiver, available_data_req_receiver) = build_request_response_protocol_receivers(&request_protocol_names, &mut net_config); let best_header = relay_chain_rpc_client .chain_get_header(None) .await? .ok_or_else(|| RelayChainError::RpcCallError("Unable to fetch best header".to_string()))?; - let (network, network_starter, sync_oracle) = build_collator_network( + let (network, network_starter, sync_service) = build_collator_network( &config, net_config, task_manager.spawn_handle(), @@ -208,19 +209,20 @@ async fn new_minimal_relay_chain( prometheus_registry.cloned(), ); - let overseer_args = CollatorOverseerGenArgs { + let overseer_args = OverseerGenArgs { runtime_client: relay_chain_rpc_client.clone(), network_service: network, - sync_oracle, + sync_service, authority_discovery_service, - collation_req_receiver_v1, - collation_req_receiver_v2, + collation_req_v1_receiver, + collation_req_v2_receiver, available_data_req_receiver, registry: prometheus_registry, spawner: task_manager.spawn_handle(), - collator_pair, + is_parachain_node: IsParachainNode::Collator(collator_pair), + overseer_message_channel_capacity_override: None, req_protocol_names: request_protocol_names, - peer_set_protocol_names, + peerset_protocol_names, notification_services, }; @@ -240,10 +242,10 @@ fn build_request_response_protocol_receivers( IncomingRequestReceiver, IncomingRequestReceiver, ) { - let (collation_req_receiver_v1, cfg) = + let (collation_req_v1_receiver, cfg) = IncomingRequest::get_config_receiver(request_protocol_names); config.add_request_response_protocol(cfg); - let (collation_req_receiver_v2, cfg) = + let (collation_req_v2_receiver, cfg) = IncomingRequest::get_config_receiver(request_protocol_names); config.add_request_response_protocol(cfg); let (available_data_req_receiver, cfg) = @@ -251,5 +253,5 @@ fn build_request_response_protocol_receivers( config.add_request_response_protocol(cfg); let cfg = Protocol::ChunkFetchingV1.get_outbound_only_config(request_protocol_names); config.add_request_response_protocol(cfg); - (collation_req_receiver_v1, collation_req_receiver_v2, available_data_req_receiver) + (collation_req_v1_receiver, collation_req_v2_receiver, available_data_req_receiver) } diff --git a/cumulus/client/relay-chain-minimal-node/src/network.rs b/cumulus/client/relay-chain-minimal-node/src/network.rs index 95785063c1a..7286fab7907 100644 --- a/cumulus/client/relay-chain-minimal-node/src/network.rs +++ b/cumulus/client/relay-chain-minimal-node/src/network.rs @@ -40,7 +40,11 @@ pub(crate) fn build_collator_network( genesis_hash: Hash, best_header: Header, ) -> Result< - (Arc>, NetworkStarter, Box), + ( + Arc>, + NetworkStarter, + Arc, + ), Error, > { let protocol_id = config.protocol_id(); @@ -112,7 +116,7 @@ pub(crate) fn build_collator_network( let network_starter = NetworkStarter::new(network_start_tx); - Ok((network_service, network_starter, Box::new(SyncOracle {}))) + Ok((network_service, network_starter, Arc::new(SyncOracle {}))) } fn adjust_network_config_light_in_peers(config: &mut NetworkConfiguration) { diff --git a/polkadot/node/malus/src/variants/back_garbage_candidate.rs b/polkadot/node/malus/src/variants/back_garbage_candidate.rs index 82475d29142..b939a2151e2 100644 --- a/polkadot/node/malus/src/variants/back_garbage_candidate.rs +++ b/polkadot/node/malus/src/variants/back_garbage_candidate.rs @@ -20,14 +20,13 @@ use polkadot_cli::{ service::{ - AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, ExtendedOverseerGenArgs, - HeaderBackend, Overseer, OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, - ParachainHost, ProvideRuntimeApi, + AuxStore, Error, ExtendedOverseerGenArgs, Overseer, OverseerConnector, OverseerGen, + OverseerGenArgs, OverseerHandle, }, validator_overseer_builder, Cli, }; use polkadot_node_subsystem::SpawnGlue; -use polkadot_node_subsystem_types::DefaultSubsystemClient; +use polkadot_node_subsystem_types::{ChainApiBackend, RuntimeApiSubsystemClient}; use sp_core::traits::SpawnNamed; use crate::{ @@ -63,13 +62,9 @@ impl OverseerGen for BackGarbageCandidates { connector: OverseerConnector, args: OverseerGenArgs<'_, Spawner, RuntimeClient>, ext_args: Option, - ) -> Result< - (Overseer, Arc>>, OverseerHandle), - Error, - > + ) -> Result<(Overseer, Arc>, OverseerHandle), Error> where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, Spawner: 'static + SpawnNamed + Clone + Unpin, { let spawner = args.spawner.clone(); diff --git a/polkadot/node/malus/src/variants/common.rs b/polkadot/node/malus/src/variants/common.rs index 011fcc80e37..eb6988f8181 100644 --- a/polkadot/node/malus/src/variants/common.rs +++ b/polkadot/node/malus/src/variants/common.rs @@ -23,10 +23,6 @@ use crate::{ use polkadot_node_core_candidate_validation::find_validation_data; use polkadot_node_primitives::{InvalidCandidate, ValidationResult}; -use polkadot_node_subsystem::{ - messages::{CandidateValidationMessage, ValidationFailed}, - overseer, -}; use polkadot_primitives::{ CandidateCommitments, CandidateDescriptor, CandidateReceipt, PersistedValidationData, diff --git a/polkadot/node/malus/src/variants/dispute_finalized_candidates.rs b/polkadot/node/malus/src/variants/dispute_finalized_candidates.rs index b3555ba2f5b..7a95bdaead2 100644 --- a/polkadot/node/malus/src/variants/dispute_finalized_candidates.rs +++ b/polkadot/node/malus/src/variants/dispute_finalized_candidates.rs @@ -34,14 +34,13 @@ use futures::channel::oneshot; use polkadot_cli::{ service::{ - AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, ExtendedOverseerGenArgs, - HeaderBackend, Overseer, OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, - ParachainHost, ProvideRuntimeApi, + AuxStore, Error, ExtendedOverseerGenArgs, Overseer, OverseerConnector, OverseerGen, + OverseerGenArgs, OverseerHandle, }, validator_overseer_builder, Cli, }; -use polkadot_node_subsystem::{messages::ApprovalVotingMessage, SpawnGlue}; -use polkadot_node_subsystem_types::{DefaultSubsystemClient, OverseerSignal}; +use polkadot_node_subsystem::SpawnGlue; +use polkadot_node_subsystem_types::{ChainApiBackend, OverseerSignal, RuntimeApiSubsystemClient}; use polkadot_node_subsystem_util::request_candidate_events; use polkadot_primitives::CandidateEvent; use sp_core::traits::SpawnNamed; @@ -237,13 +236,9 @@ impl OverseerGen for DisputeFinalizedCandidates { connector: OverseerConnector, args: OverseerGenArgs<'_, Spawner, RuntimeClient>, ext_args: Option, - ) -> Result< - (Overseer, Arc>>, OverseerHandle), - Error, - > + ) -> Result<(Overseer, Arc>, OverseerHandle), Error> where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, Spawner: 'static + SpawnNamed + Clone + Unpin, { gum::info!( diff --git a/polkadot/node/malus/src/variants/dispute_valid_candidates.rs b/polkadot/node/malus/src/variants/dispute_valid_candidates.rs index b9812cbb501..a50fdce16e4 100644 --- a/polkadot/node/malus/src/variants/dispute_valid_candidates.rs +++ b/polkadot/node/malus/src/variants/dispute_valid_candidates.rs @@ -24,14 +24,13 @@ use polkadot_cli::{ service::{ - AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, ExtendedOverseerGenArgs, - HeaderBackend, Overseer, OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, - ParachainHost, ProvideRuntimeApi, + AuxStore, Error, ExtendedOverseerGenArgs, Overseer, OverseerConnector, OverseerGen, + OverseerGenArgs, OverseerHandle, }, validator_overseer_builder, Cli, }; use polkadot_node_subsystem::SpawnGlue; -use polkadot_node_subsystem_types::DefaultSubsystemClient; +use polkadot_node_subsystem_types::{ChainApiBackend, RuntimeApiSubsystemClient}; use sp_core::traits::SpawnNamed; // Filter wrapping related types. @@ -80,13 +79,9 @@ impl OverseerGen for DisputeValidCandidates { connector: OverseerConnector, args: OverseerGenArgs<'_, Spawner, RuntimeClient>, ext_args: Option, - ) -> Result< - (Overseer, Arc>>, OverseerHandle), - Error, - > + ) -> Result<(Overseer, Arc>, OverseerHandle), Error> where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, Spawner: 'static + SpawnNamed + Clone + Unpin, { let spawner = args.spawner.clone(); diff --git a/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs b/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs index 22b44ddd1dc..739ed40db36 100644 --- a/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs +++ b/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs @@ -25,14 +25,13 @@ use futures::channel::oneshot; use polkadot_cli::{ service::{ - AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, ExtendedOverseerGenArgs, - HeaderBackend, Overseer, OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, - ParachainHost, ProvideRuntimeApi, + AuxStore, Error, ExtendedOverseerGenArgs, Overseer, OverseerConnector, OverseerGen, + OverseerGenArgs, OverseerHandle, }, validator_overseer_builder, Cli, }; use polkadot_node_primitives::{AvailableData, BlockData, PoV}; -use polkadot_node_subsystem_types::DefaultSubsystemClient; +use polkadot_node_subsystem_types::{ChainApiBackend, RuntimeApiSubsystemClient}; use polkadot_primitives::{CandidateDescriptor, CandidateReceipt}; use polkadot_node_subsystem_util::request_validators; @@ -52,7 +51,7 @@ use crate::{ // Import extra types relevant to the particular // subsystem. -use polkadot_node_subsystem::{messages::CandidateBackingMessage, SpawnGlue}; +use polkadot_node_subsystem::SpawnGlue; use std::sync::Arc; @@ -296,13 +295,9 @@ impl OverseerGen for SuggestGarbageCandidates { connector: OverseerConnector, args: OverseerGenArgs<'_, Spawner, RuntimeClient>, ext_args: Option, - ) -> Result< - (Overseer, Arc>>, OverseerHandle), - Error, - > + ) -> Result<(Overseer, Arc>, OverseerHandle), Error> where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, Spawner: 'static + SpawnNamed + Clone + Unpin, { gum::info!( diff --git a/polkadot/node/malus/src/variants/support_disabled.rs b/polkadot/node/malus/src/variants/support_disabled.rs index e25df56fd64..169c442db25 100644 --- a/polkadot/node/malus/src/variants/support_disabled.rs +++ b/polkadot/node/malus/src/variants/support_disabled.rs @@ -19,14 +19,13 @@ use polkadot_cli::{ service::{ - AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, ExtendedOverseerGenArgs, - HeaderBackend, Overseer, OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, - ParachainHost, ProvideRuntimeApi, + AuxStore, Error, ExtendedOverseerGenArgs, Overseer, OverseerConnector, OverseerGen, + OverseerGenArgs, OverseerHandle, }, validator_overseer_builder, Cli, }; use polkadot_node_subsystem::SpawnGlue; -use polkadot_node_subsystem_types::DefaultSubsystemClient; +use polkadot_node_subsystem_types::{ChainApiBackend, RuntimeApiSubsystemClient}; use sp_core::traits::SpawnNamed; use crate::interceptor::*; @@ -50,13 +49,9 @@ impl OverseerGen for SupportDisabled { connector: OverseerConnector, args: OverseerGenArgs<'_, Spawner, RuntimeClient>, ext_args: Option, - ) -> Result< - (Overseer, Arc>>, OverseerHandle), - Error, - > + ) -> Result<(Overseer, Arc>, OverseerHandle), Error> where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, Spawner: 'static + SpawnNamed + Clone + Unpin, { validator_overseer_builder( diff --git a/polkadot/node/service/src/lib.rs b/polkadot/node/service/src/lib.rs index 6dcdec07ca8..83a0afc077e 100644 --- a/polkadot/node/service/src/lib.rs +++ b/polkadot/node/service/src/lib.rs @@ -92,6 +92,7 @@ pub use chain_spec::{GenericChainSpec, RococoChainSpec, WestendChainSpec}; pub use consensus_common::{Proposal, SelectChain}; use frame_benchmarking_cli::SUBSTRATE_REFERENCE_HARDWARE; use mmr_gadget::MmrGadget; +use polkadot_node_subsystem_types::DefaultSubsystemClient; pub use polkadot_primitives::{Block, BlockId, BlockNumber, CollatorPair, Hash, Id as ParaId}; pub use sc_client_api::{Backend, CallExecutor}; pub use sc_consensus::{BlockImport, LongestChain}; @@ -1081,12 +1082,17 @@ pub fn new_full( None }; + let runtime_client = Arc::new(DefaultSubsystemClient::new( + overseer_client.clone(), + OffchainTransactionPoolFactory::new(transaction_pool.clone()), + )); + let overseer_handle = if let Some(authority_discovery_service) = authority_discovery_service { let (overseer, overseer_handle) = overseer_gen - .generate::( + .generate::>( overseer_connector, OverseerGenArgs { - runtime_client: overseer_client.clone(), + runtime_client, network_service: network.clone(), sync_service: sync_service.clone(), authority_discovery_service, @@ -1099,9 +1105,6 @@ pub fn new_full( overseer_message_channel_capacity_override, req_protocol_names, peerset_protocol_names, - offchain_transaction_pool_factory: OffchainTransactionPoolFactory::new( - transaction_pool.clone(), - ), notification_services, }, ext_overseer_args, diff --git a/polkadot/node/service/src/overseer.rs b/polkadot/node/service/src/overseer.rs index b2b0786bfc2..a8167370464 100644 --- a/polkadot/node/service/src/overseer.rs +++ b/polkadot/node/service/src/overseer.rs @@ -14,10 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use super::{AuthorityDiscoveryApi, Block, Error, Hash, IsParachainNode, Registry}; -use polkadot_node_subsystem_types::DefaultSubsystemClient; +use super::{Block, Error, Hash, IsParachainNode, Registry}; +use polkadot_node_subsystem_types::{ChainApiBackend, RuntimeApiSubsystemClient}; use polkadot_overseer::{DummySubsystem, InitializedOverseerBuilder, SubsystemError}; -use sc_transaction_pool_api::OffchainTransactionPoolFactory; use sp_core::traits::SpawnNamed; use polkadot_availability_distribution::IncomingRequestReceivers; @@ -40,14 +39,10 @@ use polkadot_overseer::{ }; use parking_lot::Mutex; -use polkadot_primitives::runtime_api::ParachainHost; use sc_authority_discovery::Service as AuthorityDiscoveryService; use sc_client_api::AuxStore; use sc_keystore::LocalKeystore; use sc_network::{NetworkStateInfo, NotificationService}; -use sp_api::ProvideRuntimeApi; -use sp_blockchain::HeaderBackend; -use sp_consensus_babe::BabeApi; use std::{collections::HashMap, sync::Arc}; pub use polkadot_approval_distribution::ApprovalDistribution as ApprovalDistributionSubsystem; @@ -80,8 +75,6 @@ pub use polkadot_statement_distribution::StatementDistributionSubsystem; /// Arguments passed for overseer construction. pub struct OverseerGenArgs<'a, Spawner, RuntimeClient> where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, Spawner: 'static + SpawnNamed + Clone + Unpin, { /// Runtime client generic, providing the `ProvieRuntimeApi` trait besides others. @@ -89,7 +82,7 @@ where /// Underlying network service implementation. pub network_service: Arc>, /// Underlying syncing service implementation. - pub sync_service: Arc>, + pub sync_service: Arc, /// Underlying authority discovery service. pub authority_discovery_service: AuthorityDiscoveryService, /// Collations request receiver for network protocol v1. @@ -111,8 +104,6 @@ where pub req_protocol_names: ReqProtocolNames, /// `PeerSet` protocol names to protocols mapping. pub peerset_protocol_names: PeerSetProtocolNames, - /// The offchain transaction pool factory. - pub offchain_transaction_pool_factory: OffchainTransactionPoolFactory, /// Notification services for validation/collation protocols. pub notification_services: HashMap>, } @@ -160,7 +151,6 @@ pub fn validator_overseer_builder( overseer_message_channel_capacity_override, req_protocol_names, peerset_protocol_names, - offchain_transaction_pool_factory, notification_services, }: OverseerGenArgs, ExtendedOverseerGenArgs { @@ -180,7 +170,7 @@ pub fn validator_overseer_builder( ) -> Result< InitializedOverseerBuilder< SpawnGlue, - Arc>, + Arc, CandidateValidationSubsystem, PvfCheckerSubsystem, CandidateBackingSubsystem, @@ -190,7 +180,7 @@ pub fn validator_overseer_builder( BitfieldSigningSubsystem, BitfieldDistributionSubsystem, ProvisionerSubsystem, - RuntimeApiSubsystem>, + RuntimeApiSubsystem, AvailabilityStoreSubsystem, NetworkBridgeRxSubsystem< Arc>, @@ -214,8 +204,7 @@ pub fn validator_overseer_builder( Error, > where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, Spawner: 'static + SpawnNamed + Clone + Unpin, { use polkadot_node_subsystem_util::metrics::Metrics; @@ -227,11 +216,6 @@ where let network_bridge_metrics: NetworkBridgeMetrics = Metrics::register(registry)?; - let runtime_api_client = Arc::new(DefaultSubsystemClient::new( - runtime_client.clone(), - offchain_transaction_pool_factory, - )); - let builder = Overseer::builder() .network_bridge_tx(NetworkBridgeTxSubsystem::new( network_service.clone(), @@ -298,7 +282,7 @@ where }) .provisioner(ProvisionerSubsystem::new(Metrics::register(registry)?)) .runtime_api(RuntimeApiSubsystem::new( - runtime_api_client.clone(), + runtime_client.clone(), Metrics::register(registry)?, spawner.clone(), )) @@ -339,7 +323,7 @@ where .activation_external_listeners(Default::default()) .span_per_active_leaf(Default::default()) .active_leaves(Default::default()) - .supports_parachains(runtime_api_client) + .supports_parachains(runtime_client) .metrics(metrics) .spawner(spawner); @@ -367,13 +351,12 @@ pub fn collator_overseer_builder( overseer_message_channel_capacity_override, req_protocol_names, peerset_protocol_names, - offchain_transaction_pool_factory, notification_services, }: OverseerGenArgs, ) -> Result< InitializedOverseerBuilder< SpawnGlue, - Arc>, + Arc, DummySubsystem, DummySubsystem, DummySubsystem, @@ -383,7 +366,7 @@ pub fn collator_overseer_builder( DummySubsystem, DummySubsystem, DummySubsystem, - RuntimeApiSubsystem>, + RuntimeApiSubsystem, DummySubsystem, NetworkBridgeRxSubsystem< Arc>, @@ -407,24 +390,17 @@ pub fn collator_overseer_builder( Error, > where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, Spawner: 'static + SpawnNamed + Clone + Unpin, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, { use polkadot_node_subsystem_util::metrics::Metrics; - let metrics = ::register(registry)?; let notification_sinks = Arc::new(Mutex::new(HashMap::new())); let spawner = SpawnGlue(spawner); let network_bridge_metrics: NetworkBridgeMetrics = Metrics::register(registry)?; - let runtime_api_client = Arc::new(DefaultSubsystemClient::new( - runtime_client.clone(), - offchain_transaction_pool_factory, - )); - let builder = Overseer::builder() .network_bridge_tx(NetworkBridgeTxSubsystem::new( network_service.clone(), @@ -475,7 +451,7 @@ where }) .provisioner(DummySubsystem) .runtime_api(RuntimeApiSubsystem::new( - runtime_api_client.clone(), + runtime_client.clone(), Metrics::register(registry)?, spawner.clone(), )) @@ -490,8 +466,8 @@ where .activation_external_listeners(Default::default()) .span_per_active_leaf(Default::default()) .active_leaves(Default::default()) - .supports_parachains(runtime_api_client) - .metrics(metrics) + .supports_parachains(runtime_client) + .metrics(Metrics::register(registry)?) .spawner(spawner); let builder = if let Some(capacity) = overseer_message_channel_capacity_override { @@ -510,13 +486,9 @@ pub trait OverseerGen { connector: OverseerConnector, args: OverseerGenArgs, ext_args: Option, - ) -> Result< - (Overseer, Arc>>, OverseerHandle), - Error, - > + ) -> Result<(Overseer, Arc>, OverseerHandle), Error> where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, Spawner: 'static + SpawnNamed + Clone + Unpin; // It would be nice to make `create_subsystems` part of this trait, @@ -533,13 +505,9 @@ impl OverseerGen for ValidatorOverseerGen { connector: OverseerConnector, args: OverseerGenArgs, ext_args: Option, - ) -> Result< - (Overseer, Arc>>, OverseerHandle), - Error, - > + ) -> Result<(Overseer, Arc>, OverseerHandle), Error> where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, Spawner: 'static + SpawnNamed + Clone + Unpin, { let ext_args = ext_args.ok_or(Error::Overseer(SubsystemError::Context( @@ -561,13 +529,9 @@ impl OverseerGen for CollatorOverseerGen { connector: OverseerConnector, args: OverseerGenArgs, _ext_args: Option, - ) -> Result< - (Overseer, Arc>>, OverseerHandle), - Error, - > + ) -> Result<(Overseer, Arc>, OverseerHandle), Error> where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, Spawner: 'static + SpawnNamed + Clone + Unpin, { collator_overseer_builder(args)? diff --git a/polkadot/node/subsystem-types/src/runtime_client.rs b/polkadot/node/subsystem-types/src/runtime_client.rs index 7f618307610..4039fc9127d 100644 --- a/polkadot/node/subsystem-types/src/runtime_client.rs +++ b/polkadot/node/subsystem-types/src/runtime_client.rs @@ -26,13 +26,13 @@ use polkadot_primitives::{ PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, }; -use sc_client_api::HeaderBackend; +use sc_client_api::{AuxStore, HeaderBackend}; use sc_transaction_pool_api::OffchainTransactionPoolFactory; use sp_api::{ApiError, ApiExt, ProvideRuntimeApi}; use sp_authority_discovery::AuthorityDiscoveryApi; -use sp_blockchain::Info; +use sp_blockchain::{BlockStatus, Info}; use sp_consensus_babe::{BabeApi, Epoch}; -use sp_runtime::traits::{Header as HeaderT, NumberFor}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; use std::{collections::BTreeMap, sync::Arc}; /// Offers header utilities. @@ -595,3 +595,61 @@ where self.client.runtime_api().approval_voting_params(at) } } + +impl HeaderBackend for DefaultSubsystemClient +where + Client: HeaderBackend, + Block: sp_runtime::traits::Block, +{ + fn header( + &self, + hash: Block::Hash, + ) -> sc_client_api::blockchain::Result> { + self.client.header(hash) + } + + fn info(&self) -> Info { + self.client.info() + } + + fn status(&self, hash: Block::Hash) -> sc_client_api::blockchain::Result { + self.client.status(hash) + } + + fn number( + &self, + hash: Block::Hash, + ) -> sc_client_api::blockchain::Result::Header as HeaderT>::Number>> { + self.client.number(hash) + } + + fn hash( + &self, + number: NumberFor, + ) -> sc_client_api::blockchain::Result> { + self.client.hash(number) + } +} + +impl AuxStore for DefaultSubsystemClient +where + Client: AuxStore, +{ + fn insert_aux< + 'a, + 'b: 'a, + 'c: 'a, + I: IntoIterator, + D: IntoIterator, + >( + &self, + insert: I, + delete: D, + ) -> sp_blockchain::Result<()> { + self.client.insert_aux(insert, delete) + } + + fn get_aux(&self, key: &[u8]) -> sp_blockchain::Result>> { + self.client.get_aux(key) + } +} diff --git a/substrate/utils/wasm-builder/src/prerequisites.rs b/substrate/utils/wasm-builder/src/prerequisites.rs index a601e3210dd..22caf895063 100644 --- a/substrate/utils/wasm-builder/src/prerequisites.rs +++ b/substrate/utils/wasm-builder/src/prerequisites.rs @@ -149,6 +149,14 @@ impl<'a> DummyCrate<'a> { sysroot_cmd.output().ok().and_then(|o| String::from_utf8(o.stdout).ok()) } + fn get_toolchain(&self) -> Option { + let sysroot = self.get_sysroot()?; + Path::new(sysroot.trim()) + .file_name() + .and_then(|s| s.to_str()) + .map(|s| s.to_string()) + } + fn try_build(&self) -> Result<(), Option> { let Ok(result) = self.prepare_command("build").output() else { return Err(None) }; if !result.status.success() { @@ -164,14 +172,15 @@ fn check_wasm_toolchain_installed( let dummy_crate = DummyCrate::new(&cargo_command, RuntimeTarget::Wasm); if let Err(error) = dummy_crate.try_build() { + let toolchain = dummy_crate.get_toolchain().unwrap_or("".to_string()); let basic_error_message = colorize_error_message( - "Rust WASM toolchain is not properly installed; please install it!", + &format!("Rust WASM target for toolchain {toolchain} is not properly installed; please install it!") ); return match error { None => Err(basic_error_message), Some(error) if error.contains("the `wasm32-unknown-unknown` target may not be installed") => { - Err(colorize_error_message("Cannot compile the WASM runtime: the `wasm32-unknown-unknown` target is not installed!\n\ - You can install it with `rustup target add wasm32-unknown-unknown` if you're using `rustup`.")) + Err(colorize_error_message(&format!("Cannot compile the WASM runtime: the `wasm32-unknown-unknown` target is not installed!\n\ + You can install it with `rustup target add wasm32-unknown-unknown --toolchain {toolchain}` if you're using `rustup`."))) }, // Apparently this can happen when we're running on a non Tier 1 platform. Some(ref error) if error.contains("linker `rust-lld` not found") => @@ -193,9 +202,10 @@ fn check_wasm_toolchain_installed( let src_path = Path::new(sysroot.trim()).join("lib").join("rustlib").join("src").join("rust"); if !src_path.exists() { + let toolchain = dummy_crate.get_toolchain().unwrap_or("".to_string()); return Err(colorize_error_message( - "Cannot compile the WASM runtime: no standard library sources found!\n\ - You can install them with `rustup component add rust-src` if you're using `rustup`.", + &format!("Cannot compile the WASM runtime: no standard library sources found at {}!\n\ + You can install them with `rustup component add rust-src --toolchain {toolchain}` if you're using `rustup`.", src_path.display()), )) } } -- GitLab From 12ce4f7d049b70918cadb658de4bbe8eb6ffc670 Mon Sep 17 00:00:00 2001 From: Liam Aharon Date: Wed, 28 Feb 2024 18:32:02 +1100 Subject: [PATCH 317/392] Runtime Upgrade ref docs and Single Block Migration example pallet (#1554) Closes https://github.com/paritytech/polkadot-sdk-docs/issues/55 - Changes 'current storage version' terminology to less ambiguous 'in-code storage version' (suggestion by @ggwpez) - Adds a new example pallet `pallet-example-single-block-migrations` - Adds a new reference doc to replace https://docs.substrate.io/maintain/runtime-upgrades/ (temporarily living in the pallet while we wait for developer hub PR to merge) - Adds documentation for the `storage_alias` macro - Improves `trait Hooks` docs - Improves `trait GetStorageVersion` docs - Update the suggested patterns for using `VersionedMigration`, so that version unchecked migrations are never exported - Prevents accidental usage of version unchecked migrations in runtimes https://github.com/paritytech/substrate/pull/14421#discussion_r1255467895 - Unversioned migration code is kept inside `mod version_unchecked`, versioned code is kept in `pub mod versioned` - It is necessary to use modules to limit visibility because the inner migration must be `pub`. See https://github.com/rust-lang/rust/issues/30905 and https://internals.rust-lang.org/t/lang-team-minutes-private-in-public-rules/4504/40 for more. ### todo - [x] move to reference docs to proper place within sdk-docs (now that https://github.com/paritytech/polkadot-sdk/pull/2102 is merged) - [x] prdoc --------- Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Juan Co-authored-by: Oliver Tale-Yazdi Co-authored-by: command-bot <> Co-authored-by: gupnik --- Cargo.lock | 26 ++ Cargo.toml | 1 + cumulus/pallets/collator-selection/src/lib.rs | 2 +- .../collator-selection/src/migration.rs | 10 +- .../pallets/parachain-system/src/migration.rs | 2 +- cumulus/pallets/xcmp-queue/src/migration.rs | 2 +- .../pallets/collective-content/src/lib.rs | 2 +- .../assets/asset-hub-rococo/src/lib.rs | 14 +- .../assets/asset-hub-westend/src/lib.rs | 6 +- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 4 +- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 4 +- docs/sdk/Cargo.toml | 7 +- .../reference_docs/frame_runtime_migration.rs | 9 - .../frame_runtime_upgrades_and_migrations.rs | 138 +++++++++++ docs/sdk/src/reference_docs/mod.rs | 5 +- .../node/service/src/parachains_db/upgrade.rs | 2 +- .../common/src/assigned_slots/migration.rs | 12 +- .../runtime/common/src/assigned_slots/mod.rs | 2 +- .../runtime/common/src/crowdloan/migration.rs | 4 +- polkadot/runtime/common/src/crowdloan/mod.rs | 2 +- .../runtime/common/src/paras_registrar/mod.rs | 2 +- .../runtime/parachains/src/configuration.rs | 2 +- polkadot/runtime/parachains/src/disputes.rs | 2 +- .../parachains/src/session_info/migration.rs | 2 +- prdoc/pr_1554.prdoc | 14 ++ substrate/client/executor/src/executor.rs | 14 +- substrate/frame/alliance/src/migration.rs | 8 +- substrate/frame/assets/src/lib.rs | 2 +- substrate/frame/assets/src/migration.rs | 20 +- substrate/frame/balances/src/lib.rs | 2 +- substrate/frame/balances/src/migration.rs | 8 +- substrate/frame/collective/src/lib.rs | 2 +- substrate/frame/contracts/src/lib.rs | 2 +- substrate/frame/contracts/src/migration.rs | 20 +- .../frame/contracts/src/migration/v09.rs | 14 +- .../frame/contracts/src/migration/v10.rs | 24 +- .../frame/contracts/src/migration/v11.rs | 12 +- .../frame/contracts/src/migration/v12.rs | 40 ++-- .../frame/contracts/src/migration/v13.rs | 10 +- .../frame/contracts/src/migration/v14.rs | 20 +- .../frame/contracts/src/migration/v15.rs | 16 +- substrate/frame/democracy/src/lib.rs | 2 +- .../election-provider-multi-phase/src/lib.rs | 2 +- .../src/migrations.rs | 4 +- substrate/frame/elections-phragmen/src/lib.rs | 2 +- substrate/frame/examples/Cargo.toml | 3 + .../single-block-migrations/Cargo.toml | 61 +++++ .../single-block-migrations/src/lib.rs | 213 +++++++++++++++++ .../src/migrations/mod.rs | 20 ++ .../src/migrations/v1.rs | 222 ++++++++++++++++++ .../single-block-migrations/src/mock.rs | 69 ++++++ substrate/frame/examples/src/lib.rs | 3 + .../frame/fast-unstake/src/migrations.rs | 4 +- substrate/frame/grandpa/src/lib.rs | 2 +- substrate/frame/im-online/src/lib.rs | 2 +- substrate/frame/im-online/src/migration.rs | 2 +- substrate/frame/membership/src/lib.rs | 2 +- substrate/frame/multisig/src/lib.rs | 2 +- substrate/frame/multisig/src/migrations.rs | 2 +- substrate/frame/nfts/src/lib.rs | 2 +- substrate/frame/nfts/src/migration.rs | 16 +- substrate/frame/nomination-pools/src/lib.rs | 2 +- .../frame/nomination-pools/src/migration.rs | 28 +-- substrate/frame/preimage/src/lib.rs | 2 +- substrate/frame/referenda/src/lib.rs | 2 +- substrate/frame/referenda/src/migration.rs | 16 +- substrate/frame/scheduler/src/lib.rs | 2 +- substrate/frame/session/src/historical/mod.rs | 2 +- substrate/frame/session/src/lib.rs | 2 +- substrate/frame/society/src/migrations.rs | 54 ++--- substrate/frame/society/src/tests.rs | 44 ++-- substrate/frame/staking/src/migrations.rs | 12 +- substrate/frame/staking/src/pallet/mod.rs | 2 +- substrate/frame/support/procedural/src/lib.rs | 38 ++- .../procedural/src/pallet/expand/hooks.rs | 22 +- .../src/pallet/expand/pallet_struct.rs | 6 +- .../src/pallet/parse/pallet_struct.rs | 2 +- substrate/frame/support/src/lib.rs | 4 +- substrate/frame/support/src/migrations.rs | 55 +++-- substrate/frame/support/src/traits/hooks.rs | 70 +++--- .../frame/support/src/traits/metadata.rs | 71 ++++-- .../support/test/tests/construct_runtime.rs | 2 +- substrate/frame/support/test/tests/pallet.rs | 22 +- .../compare_unset_storage_version.rs | 2 +- .../compare_unset_storage_version.stderr | 2 +- substrate/frame/system/src/lib.rs | 2 +- substrate/frame/tips/src/lib.rs | 2 +- 87 files changed, 1223 insertions(+), 370 deletions(-) delete mode 100644 docs/sdk/src/reference_docs/frame_runtime_migration.rs create mode 100644 docs/sdk/src/reference_docs/frame_runtime_upgrades_and_migrations.rs create mode 100644 prdoc/pr_1554.prdoc create mode 100644 substrate/frame/examples/single-block-migrations/Cargo.toml create mode 100644 substrate/frame/examples/single-block-migrations/src/lib.rs create mode 100644 substrate/frame/examples/single-block-migrations/src/migrations/mod.rs create mode 100644 substrate/frame/examples/single-block-migrations/src/migrations/v1.rs create mode 100644 substrate/frame/examples/single-block-migrations/src/mock.rs diff --git a/Cargo.lock b/Cargo.lock index 27ba43780ed..026786378d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9965,6 +9965,26 @@ dependencies = [ "sp-std 14.0.0", ] +[[package]] +name = "pallet-example-single-block-migrations" +version = "0.0.1" +dependencies = [ + "docify", + "frame-executive", + "frame-support", + "frame-system", + "frame-try-runtime", + "log", + "pallet-balances", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std 14.0.0", + "sp-version", +] + [[package]] name = "pallet-example-split" version = "10.0.0" @@ -10006,6 +10026,7 @@ dependencies = [ "pallet-example-frame-crate", "pallet-example-kitchensink", "pallet-example-offchain-worker", + "pallet-example-single-block-migrations", "pallet-example-split", "pallet-example-tasks", ] @@ -13385,6 +13406,8 @@ dependencies = [ "cumulus-pallet-parachain-system", "docify", "frame", + "frame-executive", + "frame-support", "frame-system", "kitchensink-runtime", "pallet-aura", @@ -13393,9 +13416,11 @@ dependencies = [ "pallet-collective", "pallet-default-config-example", "pallet-democracy", + "pallet-example-single-block-migrations", "pallet-examples", "pallet-multisig", "pallet-proxy", + "pallet-scheduler", "pallet-timestamp", "pallet-transaction-payment", "pallet-utility", @@ -13418,6 +13443,7 @@ dependencies = [ "sp-io", "sp-keyring", "sp-runtime", + "sp-version", "staging-chain-spec-builder", "staging-node-cli", "staging-parachain-info", diff --git a/Cargo.toml b/Cargo.toml index 1d27cfe9539..654367cc1e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -337,6 +337,7 @@ members = [ "substrate/frame/examples/frame-crate", "substrate/frame/examples/kitchensink", "substrate/frame/examples/offchain-worker", + "substrate/frame/examples/single-block-migrations", "substrate/frame/examples/split", "substrate/frame/examples/tasks", "substrate/frame/executive", diff --git a/cumulus/pallets/collator-selection/src/lib.rs b/cumulus/pallets/collator-selection/src/lib.rs index 7449f4d68c7..fb4c4a445df 100644 --- a/cumulus/pallets/collator-selection/src/lib.rs +++ b/cumulus/pallets/collator-selection/src/lib.rs @@ -118,7 +118,7 @@ pub mod pallet { use sp_staking::SessionIndex; use sp_std::vec::Vec; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); type BalanceOf = diff --git a/cumulus/pallets/collator-selection/src/migration.rs b/cumulus/pallets/collator-selection/src/migration.rs index 58b4cc5b06a..f384981dbae 100644 --- a/cumulus/pallets/collator-selection/src/migration.rs +++ b/cumulus/pallets/collator-selection/src/migration.rs @@ -31,8 +31,8 @@ pub mod v1 { pub struct MigrateToV1(sp_std::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV1 { fn on_runtime_upgrade() -> Weight { - let onchain_version = Pallet::::on_chain_storage_version(); - if onchain_version == 0 { + let on_chain_version = Pallet::::on_chain_storage_version(); + if on_chain_version == 0 { let invulnerables_len = Invulnerables::::get().to_vec().len(); >::mutate(|invulnerables| { invulnerables.sort(); @@ -45,7 +45,7 @@ pub mod v1 { invulnerables_len, ); // Similar complexity to `set_invulnerables` (put storage value) - // Plus 1 read for length, 1 read for `onchain_version`, 1 write to put version + // Plus 1 read for length, 1 read for `on_chain_version`, 1 write to put version T::WeightInfo::set_invulnerables(invulnerables_len as u32) .saturating_add(T::DbWeight::get().reads_writes(2, 1)) } else { @@ -83,8 +83,8 @@ pub mod v1 { "after migration, there should be the same number of invulnerables" ); - let onchain_version = Pallet::::on_chain_storage_version(); - frame_support::ensure!(onchain_version >= 1, "must_upgrade"); + let on_chain_version = Pallet::::on_chain_storage_version(); + frame_support::ensure!(on_chain_version >= 1, "must_upgrade"); Ok(()) } diff --git a/cumulus/pallets/parachain-system/src/migration.rs b/cumulus/pallets/parachain-system/src/migration.rs index a92f85b9cd4..30106aceab5 100644 --- a/cumulus/pallets/parachain-system/src/migration.rs +++ b/cumulus/pallets/parachain-system/src/migration.rs @@ -21,7 +21,7 @@ use frame_support::{ weights::Weight, }; -/// The current storage version. +/// The in-code storage version. pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(2); /// Migrates the pallet storage to the most recent version. diff --git a/cumulus/pallets/xcmp-queue/src/migration.rs b/cumulus/pallets/xcmp-queue/src/migration.rs index 6c86c3011d2..c7fa61a3e3f 100644 --- a/cumulus/pallets/xcmp-queue/src/migration.rs +++ b/cumulus/pallets/xcmp-queue/src/migration.rs @@ -24,7 +24,7 @@ use frame_support::{ weights::{constants::WEIGHT_REF_TIME_PER_MILLIS, Weight}, }; -/// The current storage version. +/// The in-code storage version. pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(4); pub const LOG: &str = "runtime::xcmp-queue-migration"; diff --git a/cumulus/parachains/pallets/collective-content/src/lib.rs b/cumulus/parachains/pallets/collective-content/src/lib.rs index 7a685858acc..b1c960ad6a0 100644 --- a/cumulus/parachains/pallets/collective-content/src/lib.rs +++ b/cumulus/parachains/pallets/collective-content/src/lib.rs @@ -59,7 +59,7 @@ pub mod pallet { use frame_system::pallet_prelude::*; use sp_runtime::{traits::BadOrigin, Saturating}; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(0); #[pallet::pallet] diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 81bb66a56a2..6791dc4064e 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -986,37 +986,37 @@ impl frame_support::traits::OnRuntimeUpgrade for InitStorageVersions { let mut writes = 0; if PolkadotXcm::on_chain_storage_version() == StorageVersion::new(0) { - PolkadotXcm::current_storage_version().put::(); + PolkadotXcm::in_code_storage_version().put::(); writes.saturating_inc(); } if Multisig::on_chain_storage_version() == StorageVersion::new(0) { - Multisig::current_storage_version().put::(); + Multisig::in_code_storage_version().put::(); writes.saturating_inc(); } if Assets::on_chain_storage_version() == StorageVersion::new(0) { - Assets::current_storage_version().put::(); + Assets::in_code_storage_version().put::(); writes.saturating_inc(); } if Uniques::on_chain_storage_version() == StorageVersion::new(0) { - Uniques::current_storage_version().put::(); + Uniques::in_code_storage_version().put::(); writes.saturating_inc(); } if Nfts::on_chain_storage_version() == StorageVersion::new(0) { - Nfts::current_storage_version().put::(); + Nfts::in_code_storage_version().put::(); writes.saturating_inc(); } if ForeignAssets::on_chain_storage_version() == StorageVersion::new(0) { - ForeignAssets::current_storage_version().put::(); + ForeignAssets::in_code_storage_version().put::(); writes.saturating_inc(); } if PoolAssets::on_chain_storage_version() == StorageVersion::new(0) { - PoolAssets::current_storage_version().put::(); + PoolAssets::in_code_storage_version().put::(); writes.saturating_inc(); } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 3f58c679eee..5352eeb1a1b 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -1037,17 +1037,17 @@ impl frame_support::traits::OnRuntimeUpgrade for InitStorageVersions { let mut writes = 0; if PolkadotXcm::on_chain_storage_version() == StorageVersion::new(0) { - PolkadotXcm::current_storage_version().put::(); + PolkadotXcm::in_code_storage_version().put::(); writes.saturating_inc(); } if ForeignAssets::on_chain_storage_version() == StorageVersion::new(0) { - ForeignAssets::current_storage_version().put::(); + ForeignAssets::in_code_storage_version().put::(); writes.saturating_inc(); } if PoolAssets::on_chain_storage_version() == StorageVersion::new(0) { - PoolAssets::current_storage_version().put::(); + PoolAssets::in_code_storage_version().put::(); writes.saturating_inc(); } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index f576776696c..db1dfbd45d6 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -168,12 +168,12 @@ impl frame_support::traits::OnRuntimeUpgrade for InitStorageVersions { let mut writes = 0; if PolkadotXcm::on_chain_storage_version() == StorageVersion::new(0) { - PolkadotXcm::current_storage_version().put::(); + PolkadotXcm::in_code_storage_version().put::(); writes.saturating_inc(); } if Balances::on_chain_storage_version() == StorageVersion::new(0) { - Balances::current_storage_version().put::(); + Balances::in_code_storage_version().put::(); writes.saturating_inc(); } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index bd42a33370d..1c8c9aa2075 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -142,12 +142,12 @@ impl frame_support::traits::OnRuntimeUpgrade for InitStorageVersions { let mut writes = 0; if PolkadotXcm::on_chain_storage_version() == StorageVersion::new(0) { - PolkadotXcm::current_storage_version().put::(); + PolkadotXcm::in_code_storage_version().put::(); writes.saturating_inc(); } if Balances::on_chain_storage_version() == StorageVersion::new(0) { - Balances::current_storage_version().put::(); + Balances::in_code_storage_version().put::(); writes.saturating_inc(); } diff --git a/docs/sdk/Cargo.toml b/docs/sdk/Cargo.toml index 576a81834f8..b1b60a2d77d 100644 --- a/docs/sdk/Cargo.toml +++ b/docs/sdk/Cargo.toml @@ -33,6 +33,10 @@ node-cli = { package = "staging-node-cli", path = "../../substrate/bin/node/cli" kitchensink-runtime = { path = "../../substrate/bin/node/runtime" } chain-spec-builder = { package = "staging-chain-spec-builder", path = "../../substrate/bin/utils/chain-spec-builder" } subkey = { path = "../../substrate/bin/utils/subkey" } +frame-system = { path = "../../substrate/frame/system", default-features = false } +frame-support = { path = "../../substrate/frame/support", default-features = false } +frame-executive = { path = "../../substrate/frame/executive", default-features = false } +pallet-example-single-block-migrations = { path = "../../substrate/frame/examples/single-block-migrations" } # Substrate sc-network = { path = "../../substrate/client/network" } @@ -66,7 +70,7 @@ pallet-proxy = { path = "../../substrate/frame/proxy" } pallet-authorship = { path = "../../substrate/frame/authorship" } pallet-collective = { path = "../../substrate/frame/collective" } pallet-democracy = { path = "../../substrate/frame/democracy" } -frame-system = { path = "../../substrate/frame/system" } +pallet-scheduler = { path = "../../substrate/frame/scheduler" } # Primitives sp-io = { path = "../../substrate/primitives/io" } @@ -74,6 +78,7 @@ sp-api = { path = "../../substrate/primitives/api" } sp-core = { path = "../../substrate/primitives/core" } sp-keyring = { path = "../../substrate/primitives/keyring" } sp-runtime = { path = "../../substrate/primitives/runtime" } +sp-version = { path = "../../substrate/primitives/version" } # XCM xcm = { package = "staging-xcm", path = "../../polkadot/xcm" } diff --git a/docs/sdk/src/reference_docs/frame_runtime_migration.rs b/docs/sdk/src/reference_docs/frame_runtime_migration.rs deleted file mode 100644 index 0616ccbb6f5..00000000000 --- a/docs/sdk/src/reference_docs/frame_runtime_migration.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! # Runtime Runtime Upgrade and Testing -//! -//! -//! Notes: -//! -//! - Flow of things, when does `on_runtime_upgrade` get called. Link to to `Hooks` and its diagram -//! as source of truth. -//! - Data migration and when it is needed. -//! - Look into the pba-lecture. diff --git a/docs/sdk/src/reference_docs/frame_runtime_upgrades_and_migrations.rs b/docs/sdk/src/reference_docs/frame_runtime_upgrades_and_migrations.rs new file mode 100644 index 00000000000..7d870b43221 --- /dev/null +++ b/docs/sdk/src/reference_docs/frame_runtime_upgrades_and_migrations.rs @@ -0,0 +1,138 @@ +//! # Runtime Upgrades +//! +//! At their core, blockchain logic consists of +//! +//! 1. on-chain state and +//! 2. a state transition function +//! +//! In Substrate-based blockchains, state transition functions are referred to as +//! [runtimes](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/blockchain_state_machines/index.html). +//! +//! Traditionally, before Substrate, upgrading state transition functions required node +//! operators to download new software and restart their nodes in a process called +//! [forking](https://en.wikipedia.org/wiki/Fork_(blockchain)). +//! +//! Substrate-based blockchains do not require forking, and instead upgrade runtimes +//! in a process called "Runtime Upgrades". +//! +//! Forkless runtime upgrades are a defining feature of the Substrate framework. Updating the +//! runtime logic without forking the code base enables your blockchain to seemlessly evolve +//! over time in a deterministic, rules-based manner. It also removes ambiguity for node operators +//! and other participants in the network about what is the canonical runtime. +//! +//! This capability is possible due to the runtime of a blockchain existing in on-chain storage. +//! +//! ## Performing a Runtime Upgrade +//! +//! To upgrade a runtime, an [`Origin`](frame_system::RawOrigin) with the necesarry permissions +//! (usually via governance) changes the `:code` storage. Usually, this is performed via a call to +//! [`set_code`] (or [`set_code_without_checks`]) with the desired new runtime blob, scheduled +//! using [`pallet_scheduler`]. +//! +//! Prior to building the new runtime, don't forget to update the +//! [`RuntimeVersion`](sp_version::RuntimeVersion). +//! +//! # Migrations +//! +//! It is often desirable to define logic to execute immediately after runtime upgrades (see +//! [this diagram](frame::traits::Hooks)). +//! +//! Self-contained pieces of logic that execute after a runtime upgrade are called "Migrations". +//! +//! The typical use case of a migration is to 'migrate' pallet storage from one layout to another, +//! for example when the encoding of a storage item is changed. However, they can also execute +//! arbitary logic such as: +//! +//! - Calling arbitrary pallet methods +//! - Mutating arbitrary on-chain state +//! - Cleaning up some old storage items that are no longer needed +//! +//! ## Single Block Migrations +//! +//! - Execute immediately and entirely at the beginning of the block following +//! a runtime upgrade. +//! - Are suitable for migrations which are guaranteed to not exceed the block weight. +//! - Are simply implementations of [`OnRuntimeUpgrade`]. +//! +//! To learn best practices for writing single block pallet storage migrations, see the +//! [Single Block Migration Example Pallet](pallet_example_single_block_migrations). +//! +//! ### Scheduling the Single Block Migrations to Run Next Runtime Upgrade +//! +//! Schedule migrations to run next runtime upgrade passing them as a generic parameter to your +//! [`Executive`](frame_executive) pallet: +//! +//! ```ignore +//! /// Tuple of migrations (structs that implement `OnRuntimeUpgrade`) +//! type Migrations = ( +//! pallet_example_storage_migration::migrations::v1::versioned::MigrateV0ToV1, +//! MyCustomMigration, +//! // ...more migrations here +//! ); +//! pub type Executive = frame_executive::Executive< +//! Runtime, +//! Block, +//! frame_system::ChainContext, +//! Runtime, +//! AllPalletsWithSystem, +//! Migrations, // <-- pass your migrations to Executive here +//! >; +//! ``` +//! +//! ### Ensuring Single Block Migration Safety +//! +//! "My migration unit tests pass, so it should be safe to deploy right?" +//! +//! No! Unit tests execute the migration in a very simple test environment, and cannot account +//! for the complexities of a real runtime or real on-chain state. +//! +//! Prior to deploying migrations, it is critical to perform additional checks to ensure that when +//! run in our real runtime they will not brick the chain due to: +//! - Panicing +//! - Touching too many storage keys and resulting in an excessively large PoV +//! - Taking too long to execute +//! +//! [`try-runtime-cli`](https://github.com/paritytech/try-runtime-cli) has a sub-command +//! [`on-runtime-upgrade`](https://paritytech.github.io/try-runtime-cli/try_runtime_core/commands/enum.Action.html#variant.OnRuntimeUpgrade) +//! which is designed to help with exactly this. +//! +//! Developers MUST run this command before deploying migrations to ensure they will not +//! inadvertently result in a bricked chain. +//! +//! It is recommended to run as part of your CI pipeline. See the +//! [polkadot-sdk check-runtime-migration job](https://github.com/paritytech/polkadot-sdk/blob/4a293bc5a25be637c06ce950a34490706597615b/.gitlab/pipeline/check.yml#L103-L124) +//! for an example of how to configure this. +//! +//! ### Note on the Manipulability of PoV Size and Execution Time +//! +//! While [`try-runtime-cli`](https://github.com/paritytech/try-runtime-cli) can help ensure with +//! very high certainty that a migration will succeed given **existing** on-chain state, it cannot +//! prevent a malicious actor from manipulating state in a way that will cause the migration to take +//! longer or produce a PoV much larger than previously measured. +//! +//! Therefore, it is important to write migrations in such a way that the execution time or PoV size +//! it adds to the block cannot be easily manipulated. e.g., do not iterate over storage that can +//! quickly or cheaply be bloated. +//! +//! If writing your migration in such a way is not possible, a multi block migration should be used +//! instead. +//! +//! ### Other useful tools +//! +//! [`Chopsticks`](https://github.com/AcalaNetwork/chopsticks) is another tool in the Substrate +//! ecosystem which developers may find useful to use in addition to `try-runtime-cli` when testing +//! their single block migrations. +//! +//! ## Multi Block Migrations +//! +//! Safely and easily execute long-running migrations across multiple blocks. +//! +//! Suitable for migrations which could use arbitrary amounts of block weight. +//! +//! TODO: Link to multi block migration example/s once PR is merged (). +//! +//! [`GetStorageVersion`]: frame_support::traits::GetStorageVersion +//! [`OnRuntimeUpgrade`]: frame_support::traits::OnRuntimeUpgrade +//! [`StorageVersion`]: frame_support::traits::StorageVersion +//! [`set_code`]: frame_system::Call::set_code +//! [`set_code_without_checks`]: frame_system::Call::set_code_without_checks diff --git a/docs/sdk/src/reference_docs/mod.rs b/docs/sdk/src/reference_docs/mod.rs index 760bb442c16..b2c751420ce 100644 --- a/docs/sdk/src/reference_docs/mod.rs +++ b/docs/sdk/src/reference_docs/mod.rs @@ -92,9 +92,8 @@ pub mod cli; // TODO: @JoshOrndorff @kianenigma https://github.com/paritytech/polkadot-sdk-docs/issues/54 pub mod consensus_swapping; -/// Learn about all the advance ways to test your coordinate a rutnime upgrade and data migration. -// TODO: @liamaharon https://github.com/paritytech/polkadot-sdk-docs/issues/55 -pub mod frame_runtime_migration; +/// Learn about Runtime Upgrades and best practices for writing Migrations. +pub mod frame_runtime_upgrades_and_migrations; /// Learn about light nodes, how they function, and how Substrate-based chains come /// light-node-first out of the box. diff --git a/polkadot/node/service/src/parachains_db/upgrade.rs b/polkadot/node/service/src/parachains_db/upgrade.rs index d22eebb5c8d..2eceb391b15 100644 --- a/polkadot/node/service/src/parachains_db/upgrade.rs +++ b/polkadot/node/service/src/parachains_db/upgrade.rs @@ -93,7 +93,7 @@ pub(crate) fn try_upgrade_db( } /// Try upgrading parachain's database to the next version. -/// If successfull, it returns the current version. +/// If successful, it returns the current version. pub(crate) fn try_upgrade_db_to_next_version( db_path: &Path, db_kind: DatabaseKind, diff --git a/polkadot/runtime/common/src/assigned_slots/migration.rs b/polkadot/runtime/common/src/assigned_slots/migration.rs index ba3108c0aa3..def6bad692a 100644 --- a/polkadot/runtime/common/src/assigned_slots/migration.rs +++ b/polkadot/runtime/common/src/assigned_slots/migration.rs @@ -29,14 +29,14 @@ pub mod v1 { impl OnRuntimeUpgrade for VersionUncheckedMigrateToV1 { #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { - let onchain_version = Pallet::::on_chain_storage_version(); - ensure!(onchain_version < 1, "assigned_slots::MigrateToV1 migration can be deleted"); + let on_chain_version = Pallet::::on_chain_storage_version(); + ensure!(on_chain_version < 1, "assigned_slots::MigrateToV1 migration can be deleted"); Ok(Default::default()) } fn on_runtime_upgrade() -> frame_support::weights::Weight { - let onchain_version = Pallet::::on_chain_storage_version(); - if onchain_version < 1 { + let on_chain_version = Pallet::::on_chain_storage_version(); + if on_chain_version < 1 { const MAX_PERMANENT_SLOTS: u32 = 100; const MAX_TEMPORARY_SLOTS: u32 = 100; @@ -52,8 +52,8 @@ pub mod v1 { #[cfg(feature = "try-runtime")] fn post_upgrade(_state: Vec) -> Result<(), sp_runtime::TryRuntimeError> { - let onchain_version = Pallet::::on_chain_storage_version(); - ensure!(onchain_version == 1, "assigned_slots::MigrateToV1 needs to be run"); + let on_chain_version = Pallet::::on_chain_storage_version(); + ensure!(on_chain_version == 1, "assigned_slots::MigrateToV1 needs to be run"); assert_eq!(>::get(), 100); assert_eq!(>::get(), 100); Ok(()) diff --git a/polkadot/runtime/common/src/assigned_slots/mod.rs b/polkadot/runtime/common/src/assigned_slots/mod.rs index 3419e3497f7..4f032f4dfa3 100644 --- a/polkadot/runtime/common/src/assigned_slots/mod.rs +++ b/polkadot/runtime/common/src/assigned_slots/mod.rs @@ -107,7 +107,7 @@ type LeasePeriodOf = <::Leaser as Leaser>>::Le pub mod pallet { use super::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/polkadot/runtime/common/src/crowdloan/migration.rs b/polkadot/runtime/common/src/crowdloan/migration.rs index 5133c14ada9..3afd6b3fbc9 100644 --- a/polkadot/runtime/common/src/crowdloan/migration.rs +++ b/polkadot/runtime/common/src/crowdloan/migration.rs @@ -24,9 +24,9 @@ use frame_support::{ pub struct MigrateToTrackInactiveV2(sp_std::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToTrackInactiveV2 { fn on_runtime_upgrade() -> Weight { - let onchain_version = Pallet::::on_chain_storage_version(); + let on_chain_version = Pallet::::on_chain_storage_version(); - if onchain_version == 1 { + if on_chain_version == 1 { let mut translated = 0u64; for item in Funds::::iter_values() { let b = diff --git a/polkadot/runtime/common/src/crowdloan/mod.rs b/polkadot/runtime/common/src/crowdloan/mod.rs index 7d1b892dfa7..35d075f2ff6 100644 --- a/polkadot/runtime/common/src/crowdloan/mod.rs +++ b/polkadot/runtime/common/src/crowdloan/mod.rs @@ -180,7 +180,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::{ensure_root, ensure_signed, pallet_prelude::*}; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(2); #[pallet::pallet] diff --git a/polkadot/runtime/common/src/paras_registrar/mod.rs b/polkadot/runtime/common/src/paras_registrar/mod.rs index 5450c4309e4..4541b88ec6f 100644 --- a/polkadot/runtime/common/src/paras_registrar/mod.rs +++ b/polkadot/runtime/common/src/paras_registrar/mod.rs @@ -106,7 +106,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/polkadot/runtime/parachains/src/configuration.rs b/polkadot/runtime/parachains/src/configuration.rs index 7cc5b31fc8f..b0e9d03df88 100644 --- a/polkadot/runtime/parachains/src/configuration.rs +++ b/polkadot/runtime/parachains/src/configuration.rs @@ -505,7 +505,7 @@ impl WeightInfo for TestWeightInfo { pub mod pallet { use super::*; - /// The current storage version. + /// The in-code storage version. /// /// v0-v1: /// v1-v2: diff --git a/polkadot/runtime/parachains/src/disputes.rs b/polkadot/runtime/parachains/src/disputes.rs index c2383dad305..da95b060c14 100644 --- a/polkadot/runtime/parachains/src/disputes.rs +++ b/polkadot/runtime/parachains/src/disputes.rs @@ -379,7 +379,7 @@ pub mod pallet { type WeightInfo: WeightInfo; } - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/polkadot/runtime/parachains/src/session_info/migration.rs b/polkadot/runtime/parachains/src/session_info/migration.rs index 228c1e3bb25..ea6f81834b5 100644 --- a/polkadot/runtime/parachains/src/session_info/migration.rs +++ b/polkadot/runtime/parachains/src/session_info/migration.rs @@ -18,5 +18,5 @@ use frame_support::traits::StorageVersion; -/// The current storage version. +/// The in-code storage version. pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); diff --git a/prdoc/pr_1554.prdoc b/prdoc/pr_1554.prdoc new file mode 100644 index 00000000000..bfce7c5edaf --- /dev/null +++ b/prdoc/pr_1554.prdoc @@ -0,0 +1,14 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Runtime Upgrade ref docs and Single Block Migration example pallet + +doc: + - audience: Runtime Dev + description: | + `frame_support::traits::GetStorageVersion::current_storage_version` has been renamed `frame_support::traits::GetStorageVersion::in_code_storage_version`. + A simple find-replace is sufficient to handle this change. + +crates: + - name: "frame-support" + diff --git a/substrate/client/executor/src/executor.rs b/substrate/client/executor/src/executor.rs index 499bb704b16..d56a3b389ef 100644 --- a/substrate/client/executor/src/executor.rs +++ b/substrate/client/executor/src/executor.rs @@ -518,7 +518,7 @@ where runtime_code, ext, heap_alloc_strategy, - |_, mut instance, _onchain_version, mut ext| { + |_, mut instance, _on_chain_version, mut ext| { with_externalities_safe(&mut **ext, move || instance.call_export(method, data)) }, ); @@ -682,18 +682,18 @@ impl CodeExecutor for NativeElseWasmExecut runtime_code, ext, heap_alloc_strategy, - |_, mut instance, onchain_version, mut ext| { - let onchain_version = - onchain_version.ok_or_else(|| Error::ApiError("Unknown version".into()))?; + |_, mut instance, on_chain_version, mut ext| { + let on_chain_version = + on_chain_version.ok_or_else(|| Error::ApiError("Unknown version".into()))?; let can_call_with = - onchain_version.can_call_with(&self.native_version.runtime_version); + on_chain_version.can_call_with(&self.native_version.runtime_version); if use_native && can_call_with { tracing::trace!( target: "executor", native = %self.native_version.runtime_version, - chain = %onchain_version, + chain = %on_chain_version, "Request for native execution succeeded", ); @@ -705,7 +705,7 @@ impl CodeExecutor for NativeElseWasmExecut tracing::trace!( target: "executor", native = %self.native_version.runtime_version, - chain = %onchain_version, + chain = %on_chain_version, "Request for native execution failed", ); } diff --git a/substrate/frame/alliance/src/migration.rs b/substrate/frame/alliance/src/migration.rs index e3a44a7887e..432f09a16f4 100644 --- a/substrate/frame/alliance/src/migration.rs +++ b/substrate/frame/alliance/src/migration.rs @@ -19,19 +19,19 @@ use crate::{Config, Pallet, Weight, LOG_TARGET}; use frame_support::{pallet_prelude::*, storage::migration, traits::OnRuntimeUpgrade}; use log; -/// The current storage version. +/// The in-code storage version. pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(2); /// Wrapper for all migrations of this pallet. pub fn migrate, I: 'static>() -> Weight { - let onchain_version = Pallet::::on_chain_storage_version(); + let on_chain_version = Pallet::::on_chain_storage_version(); let mut weight: Weight = Weight::zero(); - if onchain_version < 1 { + if on_chain_version < 1 { weight = weight.saturating_add(v0_to_v1::migrate::()); } - if onchain_version < 2 { + if on_chain_version < 2 { weight = weight.saturating_add(v1_to_v2::migrate::()); } diff --git a/substrate/frame/assets/src/lib.rs b/substrate/frame/assets/src/lib.rs index cafe7bb1a3b..60316f8cdcf 100644 --- a/substrate/frame/assets/src/lib.rs +++ b/substrate/frame/assets/src/lib.rs @@ -208,7 +208,7 @@ pub mod pallet { }; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/substrate/frame/assets/src/migration.rs b/substrate/frame/assets/src/migration.rs index ff0ffbff0d3..dd7c12293e8 100644 --- a/substrate/frame/assets/src/migration.rs +++ b/substrate/frame/assets/src/migration.rs @@ -67,9 +67,9 @@ pub mod v1 { pub struct MigrateToV1(core::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV1 { fn on_runtime_upgrade() -> Weight { - let current_version = Pallet::::current_storage_version(); - let onchain_version = Pallet::::on_chain_storage_version(); - if onchain_version == 0 && current_version == 1 { + let in_code_version = Pallet::::in_code_storage_version(); + let on_chain_version = Pallet::::on_chain_storage_version(); + if on_chain_version == 0 && in_code_version == 1 { let mut translated = 0u64; Asset::::translate::< OldAssetDetails>, @@ -78,12 +78,12 @@ pub mod v1 { translated.saturating_inc(); Some(old_value.migrate_to_v1()) }); - current_version.put::>(); + in_code_version.put::>(); log::info!( target: LOG_TARGET, "Upgraded {} pools, storage to version {:?}", translated, - current_version + in_code_version ); T::DbWeight::get().reads_writes(translated + 1, translated + 1) } else { @@ -116,13 +116,13 @@ pub mod v1 { "the asset count before and after the migration should be the same" ); - let current_version = Pallet::::current_storage_version(); - let onchain_version = Pallet::::on_chain_storage_version(); + let in_code_version = Pallet::::in_code_storage_version(); + let on_chain_version = Pallet::::on_chain_storage_version(); - frame_support::ensure!(current_version == 1, "must_upgrade"); + frame_support::ensure!(in_code_version == 1, "must_upgrade"); ensure!( - current_version == onchain_version, - "after migration, the current_version and onchain_version should be the same" + in_code_version == on_chain_version, + "after migration, the in_code_version and on_chain_version should be the same" ); Asset::::iter().try_for_each(|(_id, asset)| -> Result<(), TryRuntimeError> { diff --git a/substrate/frame/balances/src/lib.rs b/substrate/frame/balances/src/lib.rs index 7dd087eabd6..e87aa6f9311 100644 --- a/substrate/frame/balances/src/lib.rs +++ b/substrate/frame/balances/src/lib.rs @@ -320,7 +320,7 @@ pub mod pallet { type MaxFreezes: Get; } - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: frame_support::traits::StorageVersion = frame_support::traits::StorageVersion::new(1); diff --git a/substrate/frame/balances/src/migration.rs b/substrate/frame/balances/src/migration.rs index ba6819ec6e8..38d9c07ff7e 100644 --- a/substrate/frame/balances/src/migration.rs +++ b/substrate/frame/balances/src/migration.rs @@ -22,9 +22,9 @@ use frame_support::{ }; fn migrate_v0_to_v1, I: 'static>(accounts: &[T::AccountId]) -> Weight { - let onchain_version = Pallet::::on_chain_storage_version(); + let on_chain_version = Pallet::::on_chain_storage_version(); - if onchain_version == 0 { + if on_chain_version == 0 { let total = accounts .iter() .map(|a| Pallet::::total_balance(a)) @@ -76,9 +76,9 @@ impl, A: Get>, I: 'static> OnRuntimeUpgrade pub struct ResetInactive(PhantomData<(T, I)>); impl, I: 'static> OnRuntimeUpgrade for ResetInactive { fn on_runtime_upgrade() -> Weight { - let onchain_version = Pallet::::on_chain_storage_version(); + let on_chain_version = Pallet::::on_chain_storage_version(); - if onchain_version == 1 { + if on_chain_version == 1 { // Remove the old `StorageVersion` type. frame_support::storage::unhashed::kill(&frame_support::storage::storage_prefix( Pallet::::name().as_bytes(), diff --git a/substrate/frame/collective/src/lib.rs b/substrate/frame/collective/src/lib.rs index c084784e0a9..dd481b53681 100644 --- a/substrate/frame/collective/src/lib.rs +++ b/substrate/frame/collective/src/lib.rs @@ -176,7 +176,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(4); #[pallet::pallet] diff --git a/substrate/frame/contracts/src/lib.rs b/substrate/frame/contracts/src/lib.rs index d8939ee88ba..32d789a458f 100644 --- a/substrate/frame/contracts/src/lib.rs +++ b/substrate/frame/contracts/src/lib.rs @@ -234,7 +234,7 @@ pub mod pallet { use frame_system::pallet_prelude::*; use sp_runtime::Perbill; - /// The current storage version. + /// The in-code storage version. pub(crate) const STORAGE_VERSION: StorageVersion = StorageVersion::new(15); #[pallet::pallet] diff --git a/substrate/frame/contracts/src/migration.rs b/substrate/frame/contracts/src/migration.rs index 6d61cb6b1e1..f30ae1ebfad 100644 --- a/substrate/frame/contracts/src/migration.rs +++ b/substrate/frame/contracts/src/migration.rs @@ -263,10 +263,10 @@ impl Migration { impl OnRuntimeUpgrade for Migration { fn on_runtime_upgrade() -> Weight { let name = >::name(); - let current_version = >::current_storage_version(); + let in_code_version = >::in_code_storage_version(); let on_chain_version = >::on_chain_storage_version(); - if on_chain_version == current_version { + if on_chain_version == in_code_version { log::warn!( target: LOG_TARGET, "{name}: No Migration performed storage_version = latest_version = {:?}", @@ -289,7 +289,7 @@ impl OnRuntimeUpgrade for Migration OnRuntimeUpgrade for Migration>::on_chain_storage_version(); - let current_version = >::current_storage_version(); + let in_code_version = >::in_code_storage_version(); - if on_chain_version == current_version { + if on_chain_version == in_code_version { return Ok(Default::default()) } log::debug!( target: LOG_TARGET, - "Requested migration of {} from {:?}(on-chain storage version) to {:?}(current storage version)", - >::name(), on_chain_version, current_version + "Requested migration of {} from {:?}(on-chain storage version) to {:?}(in-code storage version)", + >::name(), on_chain_version, in_code_version ); ensure!( - T::Migrations::is_upgrade_supported(on_chain_version, current_version), - "Unsupported upgrade: VERSION_RANGE should be (on-chain storage version + 1, current storage version)" + T::Migrations::is_upgrade_supported(on_chain_version, in_code_version), + "Unsupported upgrade: VERSION_RANGE should be (on-chain storage version + 1, in-code storage version)" ); Ok(Default::default()) @@ -421,7 +421,7 @@ impl Migration { }, StepResult::Completed { steps_done } => { in_progress_version.put::>(); - if >::current_storage_version() != in_progress_version { + if >::in_code_storage_version() != in_progress_version { log::info!( target: LOG_TARGET, "{name}: Next migration is {:?},", diff --git a/substrate/frame/contracts/src/migration/v09.rs b/substrate/frame/contracts/src/migration/v09.rs index 98fcccc2c0b..f19bff9d674 100644 --- a/substrate/frame/contracts/src/migration/v09.rs +++ b/substrate/frame/contracts/src/migration/v09.rs @@ -28,7 +28,7 @@ use frame_support::{pallet_prelude::*, storage_alias, DefaultNoBound, Identity}; use sp_runtime::TryRuntimeError; use sp_std::prelude::*; -mod old { +mod v8 { use super::*; #[derive(Encode, Decode)] @@ -50,14 +50,14 @@ mod old { #[cfg(feature = "runtime-benchmarks")] pub fn store_old_dummy_code(len: usize) { use sp_runtime::traits::Hash; - let module = old::PrefabWasmModule { + let module = v8::PrefabWasmModule { instruction_weights_version: 0, initial: 0, maximum: 0, code: vec![42u8; len], }; let hash = T::Hashing::hash(&module.code); - old::CodeStorage::::insert(hash, module); + v8::CodeStorage::::insert(hash, module); } #[derive(Encode, Decode)] @@ -89,9 +89,9 @@ impl MigrationStep for Migration { fn step(&mut self) -> (IsFinished, Weight) { let mut iter = if let Some(last_key) = self.last_code_hash.take() { - old::CodeStorage::::iter_from(old::CodeStorage::::hashed_key_for(last_key)) + v8::CodeStorage::::iter_from(v8::CodeStorage::::hashed_key_for(last_key)) } else { - old::CodeStorage::::iter() + v8::CodeStorage::::iter() }; if let Some((key, old)) = iter.next() { @@ -115,7 +115,7 @@ impl MigrationStep for Migration { #[cfg(feature = "try-runtime")] fn pre_upgrade_step() -> Result, TryRuntimeError> { - let sample: Vec<_> = old::CodeStorage::::iter().take(100).collect(); + let sample: Vec<_> = v8::CodeStorage::::iter().take(100).collect(); log::debug!(target: LOG_TARGET, "Taking sample of {} contract codes", sample.len()); Ok(sample.encode()) @@ -123,7 +123,7 @@ impl MigrationStep for Migration { #[cfg(feature = "try-runtime")] fn post_upgrade_step(state: Vec) -> Result<(), TryRuntimeError> { - let sample = , old::PrefabWasmModule)> as Decode>::decode(&mut &state[..]) + let sample = , v8::PrefabWasmModule)> as Decode>::decode(&mut &state[..]) .expect("pre_upgrade_step provides a valid state; qed"); log::debug!(target: LOG_TARGET, "Validating sample of {} contract codes", sample.len()); diff --git a/substrate/frame/contracts/src/migration/v10.rs b/substrate/frame/contracts/src/migration/v10.rs index d64673aac7d..1bee86e6a77 100644 --- a/substrate/frame/contracts/src/migration/v10.rs +++ b/substrate/frame/contracts/src/migration/v10.rs @@ -47,7 +47,7 @@ use sp_runtime::{ }; use sp_std::prelude::*; -mod old { +mod v9 { use super::*; pub type BalanceOf = ( ) where OldCurrency: ReservableCurrency<::AccountId> + 'static, { - let info = old::ContractInfo { + let info = v9::ContractInfo { trie_id: info.trie_id, code_hash: info.code_hash, storage_bytes: Default::default(), @@ -94,7 +94,7 @@ pub fn store_old_contract_info( storage_item_deposit: Default::default(), storage_base_deposit: Default::default(), }; - old::ContractInfoOf::::insert(account, info); + v9::ContractInfoOf::::insert(account, info); } #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebugNoBound, TypeInfo, MaxEncodedLen)] @@ -120,9 +120,9 @@ where pub code_hash: CodeHash, storage_bytes: u32, storage_items: u32, - pub storage_byte_deposit: old::BalanceOf, - storage_item_deposit: old::BalanceOf, - storage_base_deposit: old::BalanceOf, + pub storage_byte_deposit: v9::BalanceOf, + storage_item_deposit: v9::BalanceOf, + storage_base_deposit: v9::BalanceOf, } #[derive(Encode, Decode, MaxEncodedLen, DefaultNoBound)] @@ -152,7 +152,7 @@ fn deposit_address( impl MigrationStep for Migration where OldCurrency: ReservableCurrency<::AccountId> - + Inspect<::AccountId, Balance = old::BalanceOf>, + + Inspect<::AccountId, Balance = v9::BalanceOf>, { const VERSION: u16 = 10; @@ -162,11 +162,11 @@ where fn step(&mut self) -> (IsFinished, Weight) { let mut iter = if let Some(last_account) = self.last_account.take() { - old::ContractInfoOf::::iter_from( - old::ContractInfoOf::::hashed_key_for(last_account), + v9::ContractInfoOf::::iter_from( + v9::ContractInfoOf::::hashed_key_for(last_account), ) } else { - old::ContractInfoOf::::iter() + v9::ContractInfoOf::::iter() }; if let Some((account, contract)) = iter.next() { @@ -276,7 +276,7 @@ where #[cfg(feature = "try-runtime")] fn pre_upgrade_step() -> Result, TryRuntimeError> { - let sample: Vec<_> = old::ContractInfoOf::::iter().take(10).collect(); + let sample: Vec<_> = v9::ContractInfoOf::::iter().take(10).collect(); log::debug!(target: LOG_TARGET, "Taking sample of {} contracts", sample.len()); Ok(sample.encode()) @@ -284,7 +284,7 @@ where #[cfg(feature = "try-runtime")] fn post_upgrade_step(state: Vec) -> Result<(), TryRuntimeError> { - let sample = )> as Decode>::decode( + let sample = )> as Decode>::decode( &mut &state[..], ) .expect("pre_upgrade_step provides a valid state; qed"); diff --git a/substrate/frame/contracts/src/migration/v11.rs b/substrate/frame/contracts/src/migration/v11.rs index a5b11f6e089..9bfbb25edfb 100644 --- a/substrate/frame/contracts/src/migration/v11.rs +++ b/substrate/frame/contracts/src/migration/v11.rs @@ -29,7 +29,7 @@ use sp_runtime::TryRuntimeError; use codec::{Decode, Encode}; use frame_support::{pallet_prelude::*, storage_alias, DefaultNoBound}; use sp_std::{marker::PhantomData, prelude::*}; -mod old { +mod v10 { use super::*; #[derive(Encode, Decode, TypeInfo, MaxEncodedLen)] @@ -51,11 +51,11 @@ pub struct DeletionQueueManager { #[cfg(any(feature = "runtime-benchmarks", feature = "try-runtime"))] pub fn fill_old_queue(len: usize) { - let queue: Vec = - core::iter::repeat_with(|| old::DeletedContract { trie_id: Default::default() }) + let queue: Vec = + core::iter::repeat_with(|| v10::DeletedContract { trie_id: Default::default() }) .take(len) .collect(); - old::DeletionQueue::::set(Some(queue)); + v10::DeletionQueue::::set(Some(queue)); } #[storage_alias] @@ -80,7 +80,7 @@ impl MigrationStep for Migration { } fn step(&mut self) -> (IsFinished, Weight) { - let Some(old_queue) = old::DeletionQueue::::take() else { + let Some(old_queue) = v10::DeletionQueue::::take() else { return (IsFinished::Yes, Weight::zero()) }; let len = old_queue.len(); @@ -106,7 +106,7 @@ impl MigrationStep for Migration { #[cfg(feature = "try-runtime")] fn pre_upgrade_step() -> Result, TryRuntimeError> { - let old_queue = old::DeletionQueue::::take().unwrap_or_default(); + let old_queue = v10::DeletionQueue::::take().unwrap_or_default(); if old_queue.is_empty() { let len = 10u32; diff --git a/substrate/frame/contracts/src/migration/v12.rs b/substrate/frame/contracts/src/migration/v12.rs index 7dee3150310..d9128286df3 100644 --- a/substrate/frame/contracts/src/migration/v12.rs +++ b/substrate/frame/contracts/src/migration/v12.rs @@ -34,7 +34,7 @@ use sp_runtime::TryRuntimeError; use sp_runtime::{traits::Zero, FixedPointNumber, FixedU128, Saturating}; use sp_std::prelude::*; -mod old { +mod v11 { use super::*; pub type BalanceOf = , #[codec(compact)] - deposit: old::BalanceOf, + deposit: v11::BalanceOf, #[codec(compact)] refcount: u64, determinism: Determinism, @@ -112,17 +112,17 @@ where let hash = T::Hashing::hash(&code); PristineCode::::insert(hash, code.clone()); - let module = old::PrefabWasmModule { + let module = v11::PrefabWasmModule { instruction_weights_version: Default::default(), initial: Default::default(), maximum: Default::default(), code, determinism: Determinism::Enforced, }; - old::CodeStorage::::insert(hash, module); + v11::CodeStorage::::insert(hash, module); - let info = old::OwnerInfo { owner: account, deposit: u32::MAX.into(), refcount: u64::MAX }; - old::OwnerInfoOf::::insert(hash, info); + let info = v11::OwnerInfo { owner: account, deposit: u32::MAX.into(), refcount: u64::MAX }; + v11::OwnerInfoOf::::insert(hash, info); } #[derive(Encode, Decode, MaxEncodedLen, DefaultNoBound)] @@ -148,16 +148,16 @@ where fn step(&mut self) -> (IsFinished, Weight) { let mut iter = if let Some(last_key) = self.last_code_hash.take() { - old::OwnerInfoOf::::iter_from( - old::OwnerInfoOf::::hashed_key_for(last_key), + v11::OwnerInfoOf::::iter_from( + v11::OwnerInfoOf::::hashed_key_for(last_key), ) } else { - old::OwnerInfoOf::::iter() + v11::OwnerInfoOf::::iter() }; if let Some((hash, old_info)) = iter.next() { log::debug!(target: LOG_TARGET, "Migrating OwnerInfo for code_hash {:?}", hash); - let module = old::CodeStorage::::take(hash) + let module = v11::CodeStorage::::take(hash) .expect(format!("No PrefabWasmModule found for code_hash: {:?}", hash).as_str()); let code_len = module.code.len(); @@ -184,7 +184,7 @@ where let bytes_before = module .encoded_size() .saturating_add(code_len) - .saturating_add(old::OwnerInfo::::max_encoded_len()) + .saturating_add(v11::OwnerInfo::::max_encoded_len()) as u32; let items_before = 3u32; let deposit_expected_before = price_per_byte @@ -241,10 +241,10 @@ where fn pre_upgrade_step() -> Result, TryRuntimeError> { let len = 100; log::debug!(target: LOG_TARGET, "Taking sample of {} OwnerInfo(s)", len); - let sample: Vec<_> = old::OwnerInfoOf::::iter() + let sample: Vec<_> = v11::OwnerInfoOf::::iter() .take(len) .map(|(k, v)| { - let module = old::CodeStorage::::get(k) + let module = v11::CodeStorage::::get(k) .expect("No PrefabWasmModule found for code_hash: {:?}"); let info: CodeInfo = CodeInfo { determinism: module.determinism, @@ -258,9 +258,9 @@ where .collect(); let storage: u32 = - old::CodeStorage::::iter().map(|(_k, v)| v.encoded_size() as u32).sum(); - let mut deposit: old::BalanceOf = Default::default(); - old::OwnerInfoOf::::iter().for_each(|(_k, v)| deposit += v.deposit); + v11::CodeStorage::::iter().map(|(_k, v)| v.encoded_size() as u32).sum(); + let mut deposit: v11::BalanceOf = Default::default(); + v11::OwnerInfoOf::::iter().for_each(|(_k, v)| deposit += v.deposit); Ok((sample, deposit, storage).encode()) } @@ -269,7 +269,7 @@ where fn post_upgrade_step(state: Vec) -> Result<(), TryRuntimeError> { let state = <( Vec<(CodeHash, CodeInfo)>, - old::BalanceOf, + v11::BalanceOf, u32, ) as Decode>::decode(&mut &state[..]) .unwrap(); @@ -283,7 +283,7 @@ where ensure!(info.refcount == old.refcount, "invalid refcount"); } - if let Some((k, _)) = old::CodeStorage::::iter().next() { + if let Some((k, _)) = v11::CodeStorage::::iter().next() { log::warn!( target: LOG_TARGET, "CodeStorage is still NOT empty, found code_hash: {:?}", @@ -292,7 +292,7 @@ where } else { log::debug!(target: LOG_TARGET, "CodeStorage is empty."); } - if let Some((k, _)) = old::OwnerInfoOf::::iter().next() { + if let Some((k, _)) = v11::OwnerInfoOf::::iter().next() { log::warn!( target: LOG_TARGET, "OwnerInfoOf is still NOT empty, found code_hash: {:?}", @@ -302,7 +302,7 @@ where log::debug!(target: LOG_TARGET, "OwnerInfoOf is empty."); } - let mut deposit: old::BalanceOf = Default::default(); + let mut deposit: v11::BalanceOf = Default::default(); let mut items = 0u32; let mut storage_info = 0u32; CodeInfoOf::::iter().for_each(|(_k, v)| { diff --git a/substrate/frame/contracts/src/migration/v13.rs b/substrate/frame/contracts/src/migration/v13.rs index dd2eb12eb62..498c44d53ab 100644 --- a/substrate/frame/contracts/src/migration/v13.rs +++ b/substrate/frame/contracts/src/migration/v13.rs @@ -28,7 +28,7 @@ use frame_support::{pallet_prelude::*, storage_alias, DefaultNoBound}; use sp_runtime::BoundedBTreeMap; use sp_std::prelude::*; -mod old { +mod v12 { use super::*; #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] @@ -59,7 +59,7 @@ pub fn store_old_contract_info(account: T::AccountId, info: crate::Co let entropy = (b"contract_depo_v1", account.clone()).using_encoded(T::Hashing::hash); let deposit_account = Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref())) .expect("infinite length input; no invalid inputs for type; qed"); - let info = old::ContractInfo { + let info = v12::ContractInfo { trie_id: info.trie_id.clone(), deposit_account, code_hash: info.code_hash, @@ -69,7 +69,7 @@ pub fn store_old_contract_info(account: T::AccountId, info: crate::Co storage_item_deposit: Default::default(), storage_base_deposit: Default::default(), }; - old::ContractInfoOf::::insert(account, info); + v12::ContractInfoOf::::insert(account, info); } #[storage_alias] @@ -104,11 +104,11 @@ impl MigrationStep for Migration { fn step(&mut self) -> (IsFinished, Weight) { let mut iter = if let Some(last_account) = self.last_account.take() { - old::ContractInfoOf::::iter_from(old::ContractInfoOf::::hashed_key_for( + v12::ContractInfoOf::::iter_from(v12::ContractInfoOf::::hashed_key_for( last_account, )) } else { - old::ContractInfoOf::::iter() + v12::ContractInfoOf::::iter() }; if let Some((key, old)) = iter.next() { diff --git a/substrate/frame/contracts/src/migration/v14.rs b/substrate/frame/contracts/src/migration/v14.rs index 94534d05fdf..09da09e5bcf 100644 --- a/substrate/frame/contracts/src/migration/v14.rs +++ b/substrate/frame/contracts/src/migration/v14.rs @@ -44,7 +44,7 @@ use sp_runtime::{traits::Zero, Saturating}; #[cfg(feature = "try-runtime")] use sp_std::collections::btree_map::BTreeMap; -mod old { +mod v13 { use super::*; pub type BalanceOf = , #[codec(compact)] - pub deposit: old::BalanceOf, + pub deposit: v13::BalanceOf, #[codec(compact)] pub refcount: u64, pub determinism: Determinism, @@ -86,14 +86,14 @@ where let code = vec![42u8; len as usize]; let hash = T::Hashing::hash(&code); - let info = old::CodeInfo { + let info = v13::CodeInfo { owner: account, deposit: 10_000u32.into(), refcount: u64::MAX, determinism: Determinism::Enforced, code_len: len, }; - old::CodeInfoOf::::insert(hash, info); + v13::CodeInfoOf::::insert(hash, info); } #[cfg(feature = "try-runtime")] @@ -105,9 +105,9 @@ where OldCurrency: ReservableCurrency<::AccountId>, { /// Total reserved balance as code upload deposit for the owner. - reserved: old::BalanceOf, + reserved: v13::BalanceOf, /// Total balance of the owner. - total: old::BalanceOf, + total: v13::BalanceOf, } #[derive(Encode, Decode, MaxEncodedLen, DefaultNoBound)] @@ -134,11 +134,11 @@ where fn step(&mut self) -> (IsFinished, Weight) { let mut iter = if let Some(last_hash) = self.last_code_hash.take() { - old::CodeInfoOf::::iter_from( - old::CodeInfoOf::::hashed_key_for(last_hash), + v13::CodeInfoOf::::iter_from( + v13::CodeInfoOf::::hashed_key_for(last_hash), ) } else { - old::CodeInfoOf::::iter() + v13::CodeInfoOf::::iter() }; if let Some((hash, code_info)) = iter.next() { @@ -194,7 +194,7 @@ where #[cfg(feature = "try-runtime")] fn pre_upgrade_step() -> Result, TryRuntimeError> { - let info: Vec<_> = old::CodeInfoOf::::iter().collect(); + let info: Vec<_> = v13::CodeInfoOf::::iter().collect(); let mut owner_balance_allocation = BTreeMap::, BalanceAllocation>::new(); diff --git a/substrate/frame/contracts/src/migration/v15.rs b/substrate/frame/contracts/src/migration/v15.rs index 180fe855ca6..c77198d6fea 100644 --- a/substrate/frame/contracts/src/migration/v15.rs +++ b/substrate/frame/contracts/src/migration/v15.rs @@ -46,7 +46,7 @@ use sp_runtime::{traits::Zero, Saturating}; #[cfg(feature = "try-runtime")] use sp_std::vec::Vec; -mod old { +mod v14 { use super::*; #[derive( @@ -81,7 +81,7 @@ pub fn store_old_contract_info(account: T::AccountId, info: crate::Co let entropy = (b"contract_depo_v1", account.clone()).using_encoded(T::Hashing::hash); let deposit_account = Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref())) .expect("infinite length input; no invalid inputs for type; qed"); - let info = old::ContractInfo { + let info = v14::ContractInfo { trie_id: info.trie_id.clone(), deposit_account, code_hash: info.code_hash, @@ -92,7 +92,7 @@ pub fn store_old_contract_info(account: T::AccountId, info: crate::Co storage_base_deposit: info.storage_base_deposit(), delegate_dependencies: info.delegate_dependencies().clone(), }; - old::ContractInfoOf::::insert(account, info); + v14::ContractInfoOf::::insert(account, info); } #[derive(Encode, Decode, CloneNoBound, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] @@ -127,11 +127,11 @@ impl MigrationStep for Migration { fn step(&mut self) -> (IsFinished, Weight) { let mut iter = if let Some(last_account) = self.last_account.take() { - old::ContractInfoOf::::iter_from(old::ContractInfoOf::::hashed_key_for( + v14::ContractInfoOf::::iter_from(v14::ContractInfoOf::::hashed_key_for( last_account, )) } else { - old::ContractInfoOf::::iter() + v14::ContractInfoOf::::iter() }; if let Some((account, old_contract)) = iter.next() { @@ -243,11 +243,11 @@ impl MigrationStep for Migration { #[cfg(feature = "try-runtime")] fn pre_upgrade_step() -> Result, TryRuntimeError> { - let sample: Vec<_> = old::ContractInfoOf::::iter().take(100).collect(); + let sample: Vec<_> = v14::ContractInfoOf::::iter().take(100).collect(); log::debug!(target: LOG_TARGET, "Taking sample of {} contracts", sample.len()); - let state: Vec<(T::AccountId, old::ContractInfo, BalanceOf, BalanceOf)> = sample + let state: Vec<(T::AccountId, v14::ContractInfo, BalanceOf, BalanceOf)> = sample .iter() .map(|(account, contract)| { ( @@ -265,7 +265,7 @@ impl MigrationStep for Migration { #[cfg(feature = "try-runtime")] fn post_upgrade_step(state: Vec) -> Result<(), TryRuntimeError> { let sample = - , BalanceOf, BalanceOf)> as Decode>::decode( + , BalanceOf, BalanceOf)> as Decode>::decode( &mut &state[..], ) .expect("pre_upgrade_step provides a valid state; qed"); diff --git a/substrate/frame/democracy/src/lib.rs b/substrate/frame/democracy/src/lib.rs index 089556191cd..08e2a7599f5 100644 --- a/substrate/frame/democracy/src/lib.rs +++ b/substrate/frame/democracy/src/lib.rs @@ -211,7 +211,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/substrate/frame/election-provider-multi-phase/src/lib.rs b/substrate/frame/election-provider-multi-phase/src/lib.rs index 4f43f89abed..6bf4dfe4f1e 100644 --- a/substrate/frame/election-provider-multi-phase/src/lib.rs +++ b/substrate/frame/election-provider-multi-phase/src/lib.rs @@ -1343,7 +1343,7 @@ pub mod pallet { #[pallet::getter(fn minimum_untrusted_score)] pub type MinimumUntrustedScore = StorageValue<_, ElectionScore>; - /// The current storage version. + /// The in-code storage version. /// /// v1: https://github.com/paritytech/substrate/pull/12237/ const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); diff --git a/substrate/frame/election-provider-multi-phase/src/migrations.rs b/substrate/frame/election-provider-multi-phase/src/migrations.rs index 50b821e6db6..156f1c02e27 100644 --- a/substrate/frame/election-provider-multi-phase/src/migrations.rs +++ b/substrate/frame/election-provider-multi-phase/src/migrations.rs @@ -27,12 +27,12 @@ pub mod v1 { pub struct MigrateToV1(sp_std::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV1 { fn on_runtime_upgrade() -> Weight { - let current = Pallet::::current_storage_version(); + let current = Pallet::::in_code_storage_version(); let onchain = Pallet::::on_chain_storage_version(); log!( info, - "Running migration with current storage version {:?} / onchain {:?}", + "Running migration with in-code storage version {:?} / onchain {:?}", current, onchain ); diff --git a/substrate/frame/elections-phragmen/src/lib.rs b/substrate/frame/elections-phragmen/src/lib.rs index a078361a5f7..308f2cdc1aa 100644 --- a/substrate/frame/elections-phragmen/src/lib.rs +++ b/substrate/frame/elections-phragmen/src/lib.rs @@ -188,7 +188,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(4); #[pallet::pallet] diff --git a/substrate/frame/examples/Cargo.toml b/substrate/frame/examples/Cargo.toml index eb6355edd31..45c7440eb89 100644 --- a/substrate/frame/examples/Cargo.toml +++ b/substrate/frame/examples/Cargo.toml @@ -23,6 +23,7 @@ pallet-example-frame-crate = { path = "frame-crate", default-features = false } pallet-example-kitchensink = { path = "kitchensink", default-features = false } pallet-example-offchain-worker = { path = "offchain-worker", default-features = false } pallet-example-split = { path = "split", default-features = false } +pallet-example-single-block-migrations = { path = "single-block-migrations", default-features = false } pallet-example-tasks = { path = "tasks", default-features = false } [features] @@ -34,6 +35,7 @@ std = [ "pallet-example-frame-crate/std", "pallet-example-kitchensink/std", "pallet-example-offchain-worker/std", + "pallet-example-single-block-migrations/std", "pallet-example-split/std", "pallet-example-tasks/std", ] @@ -43,6 +45,7 @@ try-runtime = [ "pallet-example-basic/try-runtime", "pallet-example-kitchensink/try-runtime", "pallet-example-offchain-worker/try-runtime", + "pallet-example-single-block-migrations/try-runtime", "pallet-example-split/try-runtime", "pallet-example-tasks/try-runtime", ] diff --git a/substrate/frame/examples/single-block-migrations/Cargo.toml b/substrate/frame/examples/single-block-migrations/Cargo.toml new file mode 100644 index 00000000000..5059b2433c7 --- /dev/null +++ b/substrate/frame/examples/single-block-migrations/Cargo.toml @@ -0,0 +1,61 @@ +[package] +name = "pallet-example-single-block-migrations" +version = "0.0.1" +authors.workspace = true +edition.workspace = true +license = "MIT-0" +homepage = "https://substrate.io" +repository.workspace = true +description = "FRAME example pallet demonstrating best-practices for writing storage migrations." +publish = false + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +docify = { version = "0.2.3", default-features = false } +log = { version = "0.4.20", default-features = false } +codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } +scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } +frame-support = { path = "../../support", default-features = false } +frame-executive = { path = "../../executive", default-features = false } +frame-system = { path = "../../system", default-features = false } +frame-try-runtime = { path = "../../try-runtime", default-features = false, optional = true } +pallet-balances = { path = "../../balances", default-features = false } +sp-std = { path = "../../../primitives/std", default-features = false } +sp-runtime = { path = "../../../primitives/runtime", default-features = false } +sp-core = { path = "../../../primitives/core", default-features = false } +sp-io = { path = "../../../primitives/io", default-features = false } +sp-version = { path = "../../../primitives/version", default-features = false } + +[features] +default = ["std"] +std = [ + "codec/std", + "frame-executive/std", + "frame-support/std", + "frame-system/std", + "frame-try-runtime/std", + "log/std", + "pallet-balances/std", + "scale-info/std", + "sp-core/std", + "sp-io/std", + "sp-runtime/std", + "sp-std/std", + "sp-version/std", +] +runtime-benchmarks = [ + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] +try-runtime = [ + "frame-executive/try-runtime", + "frame-support/try-runtime", + "frame-system/try-runtime", + "frame-try-runtime/try-runtime", + "pallet-balances/try-runtime", + "sp-runtime/try-runtime", +] diff --git a/substrate/frame/examples/single-block-migrations/src/lib.rs b/substrate/frame/examples/single-block-migrations/src/lib.rs new file mode 100644 index 00000000000..86a9e5d6e95 --- /dev/null +++ b/substrate/frame/examples/single-block-migrations/src/lib.rs @@ -0,0 +1,213 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! # Single Block Migration Example Pallet +//! +//! An example pallet demonstrating best-practices for writing single-block migrations in the +//! context of upgrading pallet storage. +//! +//! ## Forwarning +//! +//! Single block migrations **MUST** execute in a single block, therefore when executed on a +//! parachain are only appropriate when guaranteed to not exceed block weight limits. If a +//! parachain submits a block that exceeds the block weight limit it will **brick the chain**! +//! +//! If weight is a concern or you are not sure which type of migration to use, you should probably +//! use a multi-block migration. +//! +//! TODO: Link above to multi-block migration example. +//! +//! ## Pallet Overview +//! +//! This example pallet contains a single storage item [`Value`](pallet::Value), which may be set by +//! any signed origin by calling the [`set_value`](crate::Call::set_value) extrinsic. +//! +//! For the purposes of this exercise, we imagine that in [`StorageVersion`] V0 of this pallet +//! [`Value`](pallet::Value) is a `u32`, and this what is currently stored on-chain. +//! +//! ```ignore +//! // (Old) Storage Version V0 representation of `Value` +//! #[pallet::storage] +//! pub type Value = StorageValue<_, u32>; +//! ``` +//! +//! In [`StorageVersion`] V1 of the pallet a new struct [`CurrentAndPreviousValue`] is introduced: +#![doc = docify::embed!("src/lib.rs", CurrentAndPreviousValue)] +//! and [`Value`](pallet::Value) is updated to store this new struct instead of a `u32`: +#![doc = docify::embed!("src/lib.rs", Value)] +//! +//! In StorageVersion V1 of the pallet when [`set_value`](crate::Call::set_value) is called, the +//! new value is stored in the `current` field of [`CurrentAndPreviousValue`], and the previous +//! value (if it exists) is stored in the `previous` field. +#![doc = docify::embed!("src/lib.rs", pallet_calls)] +//! +//! ## Why a migration is necessary +//! +//! Without a migration, there will be a discrepancy between the on-chain storage for [`Value`] (in +//! V0 it is a `u32`) and the current storage for [`Value`] (in V1 it was changed to a +//! [`CurrentAndPreviousValue`] struct). +//! +//! The on-chain storage for [`Value`] would be a `u32` but the runtime would try to read it as a +//! [`CurrentAndPreviousValue`]. This would result in unacceptable undefined behavior. +//! +//! ## Adding a migration module +//! +//! Writing a pallets migrations in a seperate module is strongly recommended. +//! +//! Here's how the migration module is defined for this pallet: +//! +//! ```text +//! substrate/frame/examples/single-block-migrations/src/ +//! ├── lib.rs <-- pallet definition +//! ├── Cargo.toml <-- pallet manifest +//! └── migrations/ +//! ├── mod.rs <-- migrations module definition +//! └── v1.rs <-- migration logic for the V0 to V1 transition +//! ``` +//! +//! This structure allows keeping migration logic separate from the pallet logic and +//! easily adding new migrations in the future. +//! +//! ## Writing the Migration +//! +//! All code related to the migration can be found under +//! [`v1.rs`](migrations::v1). +//! +//! See the migration source code for detailed comments. +//! +//! To keep the migration logic organised, it is split across additional modules: +//! +//! ### `mod v0` +//! +//! Here we define a [`storage_alias`](frame_support::storage_alias) for the old v0 [`Value`] +//! format. +//! +//! This allows reading the old v0 value from storage during the migration. +//! +//! ### `mod version_unchecked` +//! +//! Here we define our raw migration logic, +//! `version_unchecked::MigrateV0ToV1` which implements the [`OnRuntimeUpgrade`] trait. +//! +//! Importantly, it is kept in a private module so that it cannot be accidentally used in a runtime. +//! +//! Private modules cannot be referenced in docs, so please read the code directly. +//! +//! #### Standalone Struct or Pallet Hook? +//! +//! Note that the storage migration logic is attached to a standalone struct implementing +//! [`OnRuntimeUpgrade`], rather than implementing the +//! [`Hooks::on_runtime_upgrade`](frame_support::traits::Hooks::on_runtime_upgrade) hook directly on +//! the pallet. The pallet hook is better suited for special types of logic that need to execute on +//! every runtime upgrade, but not so much for one-off storage migrations. +//! +//! ### `pub mod versioned` +//! +//! Here, `version_unchecked::MigrateV0ToV1` is wrapped in a +//! [`VersionedMigration`] to define +//! [`versioned::MigrateV0ToV1`](crate::migrations::v1::versioned::MigrateV0ToV1), which may be used +//! in runtimes. +//! +//! Using [`VersionedMigration`] ensures that +//! - The migration only runs once when the on-chain storage version is `0` +//! - The on-chain storage version is updated to `1` after the migration executes +//! - Reads and writes from checking and setting the on-chain storage version are accounted for in +//! the final [`Weight`](frame_support::weights::Weight) +//! +//! This is the only public module exported from `v1`. +//! +//! ### `mod test` +//! +//! Here basic unit tests are defined for the migration. +//! +//! When writing migration tests, don't forget to check: +//! - `on_runtime_upgrade` returns the expected weight +//! - `post_upgrade` succeeds when given the bytes returned by `pre_upgrade` +//! - Pallet storage is in the expected state after the migration +//! +//! [`VersionedMigration`]: frame_support::migrations::VersionedMigration +//! [`GetStorageVersion`]: frame_support::traits::GetStorageVersion +//! [`OnRuntimeUpgrade`]: frame_support::traits::OnRuntimeUpgrade +//! [`MigrateV0ToV1`]: crate::migrations::v1::versioned::MigrationV0ToV1 + +// We make sure this pallet uses `no_std` for compiling to Wasm. +#![cfg_attr(not(feature = "std"), no_std)] +// allow non-camel-case names for storage version V0 value +#![allow(non_camel_case_types)] + +// Re-export pallet items so that they can be accessed from the crate namespace. +pub use pallet::*; + +// Export migrations so they may be used in the runtime. +pub mod migrations; +#[doc(hidden)] +mod mock; +use codec::{Decode, Encode, MaxEncodedLen}; +use frame_support::traits::StorageVersion; +use sp_runtime::RuntimeDebug; + +/// Example struct holding the most recently set [`u32`] and the +/// second most recently set [`u32`] (if one existed). +#[docify::export] +#[derive( + Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, scale_info::TypeInfo, MaxEncodedLen, +)] +pub struct CurrentAndPreviousValue { + /// The most recently set value. + pub current: u32, + /// The previous value, if one existed. + pub previous: Option, +} + +// Pallet for demonstrating storage migrations. +#[frame_support::pallet(dev_mode)] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + /// Define the current [`StorageVersion`] of the pallet. + const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); + + #[pallet::pallet] + #[pallet::storage_version(STORAGE_VERSION)] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config {} + + /// [`StorageVersion`] V1 of [`Value`]. + /// + /// Currently used. + #[docify::export] + #[pallet::storage] + pub type Value = StorageValue<_, CurrentAndPreviousValue>; + + #[docify::export(pallet_calls)] + #[pallet::call] + impl Pallet { + pub fn set_value(origin: OriginFor, value: u32) -> DispatchResult { + ensure_signed(origin)?; + + let previous = Value::::get().map(|v| v.current); + let new_struct = CurrentAndPreviousValue { current: value, previous }; + >::put(new_struct); + + Ok(()) + } + } +} diff --git a/substrate/frame/examples/single-block-migrations/src/migrations/mod.rs b/substrate/frame/examples/single-block-migrations/src/migrations/mod.rs new file mode 100644 index 00000000000..80a33f69941 --- /dev/null +++ b/substrate/frame/examples/single-block-migrations/src/migrations/mod.rs @@ -0,0 +1,20 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +/// Module containing all logic associated with the example migration from +/// [`StorageVersion`](frame_support::traits::StorageVersion) V0 to V1. +pub mod v1; diff --git a/substrate/frame/examples/single-block-migrations/src/migrations/v1.rs b/substrate/frame/examples/single-block-migrations/src/migrations/v1.rs new file mode 100644 index 00000000000..b46640a3202 --- /dev/null +++ b/substrate/frame/examples/single-block-migrations/src/migrations/v1.rs @@ -0,0 +1,222 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use frame_support::{ + storage_alias, + traits::{Get, OnRuntimeUpgrade}, +}; + +#[cfg(feature = "try-runtime")] +use sp_std::vec::Vec; + +/// Collection of storage item formats from the previous storage version. +/// +/// Required so we can read values in the v0 storage format during the migration. +mod v0 { + use super::*; + + /// V0 type for [`crate::Value`]. + #[storage_alias] + pub type Value = StorageValue, u32>; +} + +/// Private module containing *version unchecked* migration logic. +/// +/// Should only be used by the [`VersionedMigration`](frame_support::migrations::VersionedMigration) +/// type in this module to create something to export. +/// +/// The unversioned migration should be kept private so the unversioned migration cannot +/// accidentally be used in any runtimes. +/// +/// For more about this pattern of keeping items private, see +/// - +/// - +mod version_unchecked { + use super::*; + + /// Implements [`OnRuntimeUpgrade`], migrating the state of this pallet from V0 to V1. + /// + /// In V0 of the template [`crate::Value`] is just a `u32`. In V1, it has been upgraded to + /// contain the struct [`crate::CurrentAndPreviousValue`]. + /// + /// In this migration, update the on-chain storage for the pallet to reflect the new storage + /// layout. + pub struct MigrateV0ToV1(sp_std::marker::PhantomData); + + impl OnRuntimeUpgrade for MigrateV0ToV1 { + /// Return the existing [`crate::Value`] so we can check that it was correctly set in + /// `version_unchecked::MigrateV0ToV1::post_upgrade`. + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { + use codec::Encode; + + // Access the old value using the `storage_alias` type + let old_value = v0::Value::::get(); + // Return it as an encoded `Vec` + Ok(old_value.encode()) + } + + /// Migrate the storage from V0 to V1. + /// + /// - If the value doesn't exist, there is nothing to do. + /// - If the value exists, it is read and then written back to storage inside a + /// [`crate::CurrentAndPreviousValue`]. + fn on_runtime_upgrade() -> frame_support::weights::Weight { + // Read the old value from storage + if let Some(old_value) = v0::Value::::take() { + // Write the new value to storage + let new = crate::CurrentAndPreviousValue { current: old_value, previous: None }; + crate::Value::::put(new); + // One read for the old value, one write for the new value + T::DbWeight::get().reads_writes(1, 1) + } else { + // One read for trying to access the old value + T::DbWeight::get().reads(1) + } + } + + /// Verifies the storage was migrated correctly. + /// + /// - If there was no old value, the new value should not be set. + /// - If there was an old value, the new value should be a + /// [`crate::CurrentAndPreviousValue`]. + #[cfg(feature = "try-runtime")] + fn post_upgrade(state: Vec) -> Result<(), sp_runtime::TryRuntimeError> { + use codec::Decode; + use frame_support::ensure; + + let maybe_old_value = Option::::decode(&mut &state[..]).map_err(|_| { + sp_runtime::TryRuntimeError::Other("Failed to decode old value from storage") + })?; + + match maybe_old_value { + Some(old_value) => { + let expected_new_value = + crate::CurrentAndPreviousValue { current: old_value, previous: None }; + let actual_new_value = crate::Value::::get(); + + ensure!(actual_new_value.is_some(), "New value not set"); + ensure!( + actual_new_value == Some(expected_new_value), + "New value not set correctly" + ); + }, + None => { + ensure!(crate::Value::::get().is_none(), "New value unexpectedly set"); + }, + }; + Ok(()) + } + } +} + +/// Public module containing *version checked* migration logic. +/// +/// This is the only module that should be exported from this module. +/// +/// See [`VersionedMigration`](frame_support::migrations::VersionedMigration) docs for more about +/// how it works. +pub mod versioned { + use super::*; + + /// `version_unchecked::MigrateV0ToV1` wrapped in a + /// [`VersionedMigration`](frame_support::migrations::VersionedMigration), which ensures that: + /// - The migration only runs once when the on-chain storage version is 0 + /// - The on-chain storage version is updated to `1` after the migration executes + /// - Reads/Writes from checking/settings the on-chain storage version are accounted for + pub type MigrateV0ToV1 = frame_support::migrations::VersionedMigration< + 0, // The migration will only execute when the on-chain storage version is 0 + 1, // The on-chain storage version will be set to 1 after the migration is complete + version_unchecked::MigrateV0ToV1, + crate::pallet::Pallet, + ::DbWeight, + >; +} + +/// Tests for our migration. +/// +/// When writing migration tests, it is important to check: +/// 1. `on_runtime_upgrade` returns the expected weight +/// 2. `post_upgrade` succeeds when given the bytes returned by `pre_upgrade` +/// 3. The storage is in the expected state after the migration +#[cfg(any(all(feature = "try-runtime", test), doc))] +mod test { + use super::*; + use crate::mock::{new_test_ext, MockRuntime}; + use frame_support::assert_ok; + use version_unchecked::MigrateV0ToV1; + + #[test] + fn handles_no_existing_value() { + new_test_ext().execute_with(|| { + // By default, no value should be set. Verify this assumption. + assert!(crate::Value::::get().is_none()); + assert!(v0::Value::::get().is_none()); + + // Get the pre_upgrade bytes + let bytes = match MigrateV0ToV1::::pre_upgrade() { + Ok(bytes) => bytes, + Err(e) => panic!("pre_upgrade failed: {:?}", e), + }; + + // Execute the migration + let weight = MigrateV0ToV1::::on_runtime_upgrade(); + + // Verify post_upgrade succeeds + assert_ok!(MigrateV0ToV1::::post_upgrade(bytes)); + + // The weight should be just 1 read for trying to access the old value. + assert_eq!(weight, ::DbWeight::get().reads(1)); + + // After the migration, no value should have been set. + assert!(crate::Value::::get().is_none()); + }) + } + + #[test] + fn handles_existing_value() { + new_test_ext().execute_with(|| { + // Set up an initial value + let initial_value = 42; + v0::Value::::put(initial_value); + + // Get the pre_upgrade bytes + let bytes = match MigrateV0ToV1::::pre_upgrade() { + Ok(bytes) => bytes, + Err(e) => panic!("pre_upgrade failed: {:?}", e), + }; + + // Execute the migration + let weight = MigrateV0ToV1::::on_runtime_upgrade(); + + // Verify post_upgrade succeeds + assert_ok!(MigrateV0ToV1::::post_upgrade(bytes)); + + // The weight used should be 1 read for the old value, and 1 write for the new + // value. + assert_eq!( + weight, + ::DbWeight::get().reads_writes(1, 1) + ); + + // After the migration, the new value should be set as the `current` value. + let expected_new_value = + crate::CurrentAndPreviousValue { current: initial_value, previous: None }; + assert_eq!(crate::Value::::get(), Some(expected_new_value)); + }) + } +} diff --git a/substrate/frame/examples/single-block-migrations/src/mock.rs b/substrate/frame/examples/single-block-migrations/src/mock.rs new file mode 100644 index 00000000000..02f72e01836 --- /dev/null +++ b/substrate/frame/examples/single-block-migrations/src/mock.rs @@ -0,0 +1,69 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![cfg(any(all(feature = "try-runtime", test), doc))] + +use crate::*; +use frame_support::{derive_impl, traits::ConstU64, weights::constants::ParityDbWeight}; + +// Re-export crate as its pallet name for construct_runtime. +use crate as pallet_example_storage_migration; + +type Block = frame_system::mocking::MockBlock; + +// For testing the pallet, we construct a mock runtime. +frame_support::construct_runtime!( + pub struct MockRuntime { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Example: pallet_example_storage_migration::{Pallet, Call, Storage}, + } +); + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for MockRuntime { + type Block = Block; + type AccountData = pallet_balances::AccountData; + type DbWeight = ParityDbWeight; +} + +impl pallet_balances::Config for MockRuntime { + type RuntimeHoldReason = RuntimeHoldReason; + type RuntimeFreezeReason = RuntimeFreezeReason; + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type Balance = u64; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ConstU64<1>; + type AccountStore = System; + type WeightInfo = (); + type FreezeIdentifier = (); + type MaxFreezes = (); +} + +impl Config for MockRuntime {} + +pub fn new_test_ext() -> sp_io::TestExternalities { + use sp_runtime::BuildStorage; + + let t = RuntimeGenesisConfig { system: Default::default(), balances: Default::default() } + .build_storage() + .unwrap(); + t.into() +} diff --git a/substrate/frame/examples/src/lib.rs b/substrate/frame/examples/src/lib.rs index f38bbe52dc1..dee23a41379 100644 --- a/substrate/frame/examples/src/lib.rs +++ b/substrate/frame/examples/src/lib.rs @@ -43,6 +43,9 @@ //! - [`pallet_example_frame_crate`]: Example pallet showcasing how one can be //! built using only the `frame` umbrella crate. //! +//! - [`pallet_example_single_block_migrations`]: An example pallet demonstrating best-practices for +//! writing storage migrations. +//! //! - [`pallet_example_tasks`]: This pallet demonstrates the use of `Tasks` to execute service work. //! //! **Tip**: Use `cargo doc --package --open` to view each pallet's documentation. diff --git a/substrate/frame/fast-unstake/src/migrations.rs b/substrate/frame/fast-unstake/src/migrations.rs index 56438840704..97ad86bfff4 100644 --- a/substrate/frame/fast-unstake/src/migrations.rs +++ b/substrate/frame/fast-unstake/src/migrations.rs @@ -33,12 +33,12 @@ pub mod v1 { pub struct MigrateToV1(sp_std::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV1 { fn on_runtime_upgrade() -> Weight { - let current = Pallet::::current_storage_version(); + let current = Pallet::::in_code_storage_version(); let onchain = Pallet::::on_chain_storage_version(); log!( info, - "Running migration with current storage version {:?} / onchain {:?}", + "Running migration with in-code storage version {:?} / onchain {:?}", current, onchain ); diff --git a/substrate/frame/grandpa/src/lib.rs b/substrate/frame/grandpa/src/lib.rs index 0b9f2b35827..90bcd8721df 100644 --- a/substrate/frame/grandpa/src/lib.rs +++ b/substrate/frame/grandpa/src/lib.rs @@ -73,7 +73,7 @@ pub mod pallet { use frame_support::{dispatch::DispatchResult, pallet_prelude::*}; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(5); #[pallet::pallet] diff --git a/substrate/frame/im-online/src/lib.rs b/substrate/frame/im-online/src/lib.rs index 1de89dd00c8..f14093aa09a 100644 --- a/substrate/frame/im-online/src/lib.rs +++ b/substrate/frame/im-online/src/lib.rs @@ -251,7 +251,7 @@ type OffchainResult = Result>>; pub mod pallet { use super::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/substrate/frame/im-online/src/migration.rs b/substrate/frame/im-online/src/migration.rs index 0d2c0a055b6..754a2e672e6 100644 --- a/substrate/frame/im-online/src/migration.rs +++ b/substrate/frame/im-online/src/migration.rs @@ -72,7 +72,7 @@ pub mod v1 { if StorageVersion::get::>() != 0 { log::warn!( target: TARGET, - "Skipping migration because current storage version is not 0" + "Skipping migration because in-code storage version is not 0" ); return weight } diff --git a/substrate/frame/membership/src/lib.rs b/substrate/frame/membership/src/lib.rs index f3226397003..f4ac697130d 100644 --- a/substrate/frame/membership/src/lib.rs +++ b/substrate/frame/membership/src/lib.rs @@ -46,7 +46,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(4); #[pallet::pallet] diff --git a/substrate/frame/multisig/src/lib.rs b/substrate/frame/multisig/src/lib.rs index e4426c64b41..a83b78e316f 100644 --- a/substrate/frame/multisig/src/lib.rs +++ b/substrate/frame/multisig/src/lib.rs @@ -168,7 +168,7 @@ pub mod pallet { type WeightInfo: WeightInfo; } - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/substrate/frame/multisig/src/migrations.rs b/substrate/frame/multisig/src/migrations.rs index d03e42a66a5..e6402600d0d 100644 --- a/substrate/frame/multisig/src/migrations.rs +++ b/substrate/frame/multisig/src/migrations.rs @@ -51,7 +51,7 @@ pub mod v1 { fn on_runtime_upgrade() -> Weight { use sp_runtime::Saturating; - let current = Pallet::::current_storage_version(); + let current = Pallet::::in_code_storage_version(); let onchain = Pallet::::on_chain_storage_version(); if onchain > 0 { diff --git a/substrate/frame/nfts/src/lib.rs b/substrate/frame/nfts/src/lib.rs index a7d505e2e39..7cf7cdc61a7 100644 --- a/substrate/frame/nfts/src/lib.rs +++ b/substrate/frame/nfts/src/lib.rs @@ -76,7 +76,7 @@ pub mod pallet { use frame_support::{pallet_prelude::*, traits::ExistenceRequirement}; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/substrate/frame/nfts/src/migration.rs b/substrate/frame/nfts/src/migration.rs index d4cdf7e820d..8f82e092262 100644 --- a/substrate/frame/nfts/src/migration.rs +++ b/substrate/frame/nfts/src/migration.rs @@ -54,17 +54,17 @@ pub mod v1 { pub struct MigrateToV1(core::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV1 { fn on_runtime_upgrade() -> Weight { - let current_version = Pallet::::current_storage_version(); - let onchain_version = Pallet::::on_chain_storage_version(); + let in_code_version = Pallet::::in_code_storage_version(); + let on_chain_version = Pallet::::on_chain_storage_version(); log::info!( target: LOG_TARGET, - "Running migration with current storage version {:?} / onchain {:?}", - current_version, - onchain_version + "Running migration with in-code storage version {:?} / onchain {:?}", + in_code_version, + on_chain_version ); - if onchain_version == 0 && current_version == 1 { + if on_chain_version == 0 && in_code_version == 1 { let mut translated = 0u64; let mut configs_iterated = 0u64; Collection::::translate::< @@ -77,13 +77,13 @@ pub mod v1 { Some(old_value.migrate_to_v1(item_configs)) }); - current_version.put::>(); + in_code_version.put::>(); log::info!( target: LOG_TARGET, "Upgraded {} records, storage to version {:?}", translated, - current_version + in_code_version ); T::DbWeight::get().reads_writes(translated + configs_iterated + 1, translated + 1) } else { diff --git a/substrate/frame/nomination-pools/src/lib.rs b/substrate/frame/nomination-pools/src/lib.rs index 074d59931ad..c64db9ed692 100644 --- a/substrate/frame/nomination-pools/src/lib.rs +++ b/substrate/frame/nomination-pools/src/lib.rs @@ -1576,7 +1576,7 @@ pub mod pallet { use frame_system::{ensure_signed, pallet_prelude::*}; use sp_runtime::Perbill; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(8); #[pallet::pallet] diff --git a/substrate/frame/nomination-pools/src/migration.rs b/substrate/frame/nomination-pools/src/migration.rs index 6887fcfa7ec..14410339f59 100644 --- a/substrate/frame/nomination-pools/src/migration.rs +++ b/substrate/frame/nomination-pools/src/migration.rs @@ -342,25 +342,25 @@ pub mod v5 { pub struct MigrateToV5(sp_std::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV5 { fn on_runtime_upgrade() -> Weight { - let current = Pallet::::current_storage_version(); + let in_code = Pallet::::in_code_storage_version(); let onchain = Pallet::::on_chain_storage_version(); log!( info, - "Running migration with current storage version {:?} / onchain {:?}", - current, + "Running migration with in-code storage version {:?} / onchain {:?}", + in_code, onchain ); - if current == 5 && onchain == 4 { + if in_code == 5 && onchain == 4 { let mut translated = 0u64; RewardPools::::translate::, _>(|_id, old_value| { translated.saturating_inc(); Some(old_value.migrate_to_v5()) }); - current.put::>(); - log!(info, "Upgraded {} pools, storage to version {:?}", translated, current); + in_code.put::>(); + log!(info, "Upgraded {} pools, storage to version {:?}", translated, in_code); // reads: translated + onchain version. // writes: translated + current.put. @@ -498,12 +498,12 @@ pub mod v4 { #[allow(deprecated)] impl> OnRuntimeUpgrade for MigrateToV4 { fn on_runtime_upgrade() -> Weight { - let current = Pallet::::current_storage_version(); + let current = Pallet::::in_code_storage_version(); let onchain = Pallet::::on_chain_storage_version(); log!( info, - "Running migration with current storage version {:?} / onchain {:?}", + "Running migration with in-code storage version {:?} / onchain {:?}", current, onchain ); @@ -579,13 +579,13 @@ pub mod v3 { pub struct MigrateToV3(sp_std::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV3 { fn on_runtime_upgrade() -> Weight { - let current = Pallet::::current_storage_version(); + let current = Pallet::::in_code_storage_version(); let onchain = Pallet::::on_chain_storage_version(); if onchain == 2 { log!( info, - "Running migration with current storage version {:?} / onchain {:?}", + "Running migration with in-code storage version {:?} / onchain {:?}", current, onchain ); @@ -859,12 +859,12 @@ pub mod v2 { impl OnRuntimeUpgrade for MigrateToV2 { fn on_runtime_upgrade() -> Weight { - let current = Pallet::::current_storage_version(); + let current = Pallet::::in_code_storage_version(); let onchain = Pallet::::on_chain_storage_version(); log!( info, - "Running migration with current storage version {:?} / onchain {:?}", + "Running migration with in-code storage version {:?} / onchain {:?}", current, onchain ); @@ -976,12 +976,12 @@ pub mod v1 { pub struct MigrateToV1(sp_std::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV1 { fn on_runtime_upgrade() -> Weight { - let current = Pallet::::current_storage_version(); + let current = Pallet::::in_code_storage_version(); let onchain = Pallet::::on_chain_storage_version(); log!( info, - "Running migration with current storage version {:?} / onchain {:?}", + "Running migration with in-code storage version {:?} / onchain {:?}", current, onchain ); diff --git a/substrate/frame/preimage/src/lib.rs b/substrate/frame/preimage/src/lib.rs index e344bdfe2d8..4e474685166 100644 --- a/substrate/frame/preimage/src/lib.rs +++ b/substrate/frame/preimage/src/lib.rs @@ -102,7 +102,7 @@ pub const MAX_HASH_UPGRADE_BULK_COUNT: u32 = 1024; pub mod pallet { use super::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::config] diff --git a/substrate/frame/referenda/src/lib.rs b/substrate/frame/referenda/src/lib.rs index c5bf2266e67..e616056c302 100644 --- a/substrate/frame/referenda/src/lib.rs +++ b/substrate/frame/referenda/src/lib.rs @@ -143,7 +143,7 @@ pub mod pallet { use frame_support::{pallet_prelude::*, traits::EnsureOriginWithArg}; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/substrate/frame/referenda/src/migration.rs b/substrate/frame/referenda/src/migration.rs index a80897242ee..631eb7340e5 100644 --- a/substrate/frame/referenda/src/migration.rs +++ b/substrate/frame/referenda/src/migration.rs @@ -109,16 +109,16 @@ pub mod v1 { } fn on_runtime_upgrade() -> Weight { - let current_version = Pallet::::current_storage_version(); - let onchain_version = Pallet::::on_chain_storage_version(); + let in_code_version = Pallet::::in_code_storage_version(); + let on_chain_version = Pallet::::on_chain_storage_version(); let mut weight = T::DbWeight::get().reads(1); log::info!( target: TARGET, - "running migration with current storage version {:?} / onchain {:?}.", - current_version, - onchain_version + "running migration with in-code storage version {:?} / onchain {:?}.", + in_code_version, + on_chain_version ); - if onchain_version != 0 { + if on_chain_version != 0 { log::warn!(target: TARGET, "skipping migration from v0 to v1."); return weight } @@ -149,8 +149,8 @@ pub mod v1 { #[cfg(feature = "try-runtime")] fn post_upgrade(state: Vec) -> Result<(), TryRuntimeError> { - let onchain_version = Pallet::::on_chain_storage_version(); - ensure!(onchain_version == 1, "must upgrade from version 0 to 1."); + let on_chain_version = Pallet::::on_chain_storage_version(); + ensure!(on_chain_version == 1, "must upgrade from version 0 to 1."); let pre_referendum_count: u32 = Decode::decode(&mut &state[..]) .expect("failed to decode the state from pre-upgrade."); let post_referendum_count = ReferendumInfoFor::::iter().count() as u32; diff --git a/substrate/frame/scheduler/src/lib.rs b/substrate/frame/scheduler/src/lib.rs index daebebdee99..af3abd8ac4f 100644 --- a/substrate/frame/scheduler/src/lib.rs +++ b/substrate/frame/scheduler/src/lib.rs @@ -229,7 +229,7 @@ pub mod pallet { use frame_support::{dispatch::PostDispatchInfo, pallet_prelude::*}; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(4); #[pallet::pallet] diff --git a/substrate/frame/session/src/historical/mod.rs b/substrate/frame/session/src/historical/mod.rs index d74e9dd0b7c..b9cecea1a7f 100644 --- a/substrate/frame/session/src/historical/mod.rs +++ b/substrate/frame/session/src/historical/mod.rs @@ -58,7 +58,7 @@ pub mod pallet { use super::*; use frame_support::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/substrate/frame/session/src/lib.rs b/substrate/frame/session/src/lib.rs index fc35cd6ddd8..7d8128dbc1f 100644 --- a/substrate/frame/session/src/lib.rs +++ b/substrate/frame/session/src/lib.rs @@ -368,7 +368,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(0); #[pallet::pallet] diff --git a/substrate/frame/society/src/migrations.rs b/substrate/frame/society/src/migrations.rs index dafb1e0b9e5..6a102911451 100644 --- a/substrate/frame/society/src/migrations.rs +++ b/substrate/frame/society/src/migrations.rs @@ -40,11 +40,11 @@ impl< { #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result, TryRuntimeError> { - let current = Pallet::::current_storage_version(); - let onchain = Pallet::::on_chain_storage_version(); - ensure!(onchain == 0 && current == 2, "pallet_society: invalid version"); + let in_code = Pallet::::in_code_storage_version(); + let on_chain = Pallet::::on_chain_storage_version(); + ensure!(on_chain == 0 && in_code == 2, "pallet_society: invalid version"); - Ok((old::Candidates::::get(), old::Members::::get()).encode()) + Ok((v0::Candidates::::get(), v0::Members::::get()).encode()) } fn on_runtime_upgrade() -> Weight { @@ -103,7 +103,7 @@ pub type MigrateToV2 = frame_support::migrations::VersionedMi ::DbWeight, >; -pub(crate) mod old { +pub(crate) mod v0 { use super::*; use frame_support::storage_alias; @@ -230,37 +230,37 @@ pub fn assert_internal_consistency, I: Instance + 'static>() { } // We don't use these - make sure they don't exist. - assert_eq!(old::SuspendedCandidates::::iter().count(), 0); - assert_eq!(old::Strikes::::iter().count(), 0); - assert_eq!(old::Vouching::::iter().count(), 0); - assert!(!old::Defender::::exists()); - assert!(!old::Members::::exists()); + assert_eq!(v0::SuspendedCandidates::::iter().count(), 0); + assert_eq!(v0::Strikes::::iter().count(), 0); + assert_eq!(v0::Vouching::::iter().count(), 0); + assert!(!v0::Defender::::exists()); + assert!(!v0::Members::::exists()); } pub fn from_original, I: Instance + 'static>( past_payouts: &mut [(::AccountId, BalanceOf)], ) -> Result { // Migrate Bids from old::Bids (just a trunctation). - Bids::::put(BoundedVec::<_, T::MaxBids>::truncate_from(old::Bids::::take())); + Bids::::put(BoundedVec::<_, T::MaxBids>::truncate_from(v0::Bids::::take())); // Initialise round counter. RoundCount::::put(0); // Migrate Candidates from old::Candidates - for Bid { who: candidate, kind, value } in old::Candidates::::take().into_iter() { + for Bid { who: candidate, kind, value } in v0::Candidates::::take().into_iter() { let mut tally = Tally::default(); // Migrate Votes from old::Votes // No need to drain, since we're overwriting values. - for (voter, vote) in old::Votes::::iter_prefix(&candidate) { + for (voter, vote) in v0::Votes::::iter_prefix(&candidate) { Votes::::insert( &candidate, &voter, - Vote { approve: vote == old::Vote::Approve, weight: 1 }, + Vote { approve: vote == v0::Vote::Approve, weight: 1 }, ); match vote { - old::Vote::Approve => tally.approvals.saturating_inc(), - old::Vote::Reject => tally.rejections.saturating_inc(), - old::Vote::Skeptic => Skeptic::::put(&voter), + v0::Vote::Approve => tally.approvals.saturating_inc(), + v0::Vote::Reject => tally.rejections.saturating_inc(), + v0::Vote::Skeptic => Skeptic::::put(&voter), } } Candidates::::insert( @@ -271,9 +271,9 @@ pub fn from_original, I: Instance + 'static>( // Migrate Members from old::Members old::Strikes old::Vouching let mut member_count = 0; - for member in old::Members::::take() { - let strikes = old::Strikes::::take(&member); - let vouching = old::Vouching::::take(&member); + for member in v0::Members::::take() { + let strikes = v0::Strikes::::take(&member); + let vouching = v0::Vouching::::take(&member); let record = MemberRecord { index: member_count, rank: 0, strikes, vouching }; Members::::insert(&member, record); MemberByIndex::::insert(member_count, &member); @@ -314,7 +314,7 @@ pub fn from_original, I: Instance + 'static>( // Migrate Payouts from: old::Payouts and raw info (needed since we can't query old chain // state). past_payouts.sort(); - for (who, mut payouts) in old::Payouts::::iter() { + for (who, mut payouts) in v0::Payouts::::iter() { payouts.truncate(T::MaxPayouts::get() as usize); // ^^ Safe since we already truncated. let paid = past_payouts @@ -329,19 +329,19 @@ pub fn from_original, I: Instance + 'static>( } // Migrate SuspendedMembers from old::SuspendedMembers old::Strikes old::Vouching. - for who in old::SuspendedMembers::::iter_keys() { - let strikes = old::Strikes::::take(&who); - let vouching = old::Vouching::::take(&who); + for who in v0::SuspendedMembers::::iter_keys() { + let strikes = v0::Strikes::::take(&who); + let vouching = v0::Vouching::::take(&who); let record = MemberRecord { index: 0, rank: 0, strikes, vouching }; SuspendedMembers::::insert(&who, record); } // Any suspended candidates remaining are rejected. - let _ = old::SuspendedCandidates::::clear(u32::MAX, None); + let _ = v0::SuspendedCandidates::::clear(u32::MAX, None); // We give the current defender the benefit of the doubt. - old::Defender::::kill(); - let _ = old::DefenderVotes::::clear(u32::MAX, None); + v0::Defender::::kill(); + let _ = v0::DefenderVotes::::clear(u32::MAX, None); Ok(T::BlockWeights::get().max_block) } diff --git a/substrate/frame/society/src/tests.rs b/substrate/frame/society/src/tests.rs index 940643168fb..411567e1ded 100644 --- a/substrate/frame/society/src/tests.rs +++ b/substrate/frame/society/src/tests.rs @@ -18,7 +18,7 @@ //! Tests for the module. use super::*; -use migrations::old; +use migrations::v0; use mock::*; use frame_support::{assert_noop, assert_ok}; @@ -32,41 +32,41 @@ use RuntimeOrigin as Origin; #[test] fn migration_works() { EnvBuilder::new().founded(false).execute(|| { - use old::Vote::*; + use v0::Vote::*; // Initialise the old storage items. Founder::::put(10); Head::::put(30); - old::Members::::put(vec![10, 20, 30]); - old::Vouching::::insert(30, Vouching); - old::Vouching::::insert(40, Banned); - old::Strikes::::insert(20, 1); - old::Strikes::::insert(30, 2); - old::Strikes::::insert(40, 5); - old::Payouts::::insert(20, vec![(1, 1)]); - old::Payouts::::insert( + v0::Members::::put(vec![10, 20, 30]); + v0::Vouching::::insert(30, Vouching); + v0::Vouching::::insert(40, Banned); + v0::Strikes::::insert(20, 1); + v0::Strikes::::insert(30, 2); + v0::Strikes::::insert(40, 5); + v0::Payouts::::insert(20, vec![(1, 1)]); + v0::Payouts::::insert( 30, (0..=::MaxPayouts::get()) .map(|i| (i as u64, i as u64)) .collect::>(), ); - old::SuspendedMembers::::insert(40, true); + v0::SuspendedMembers::::insert(40, true); - old::Defender::::put(20); - old::DefenderVotes::::insert(10, Approve); - old::DefenderVotes::::insert(20, Approve); - old::DefenderVotes::::insert(30, Reject); + v0::Defender::::put(20); + v0::DefenderVotes::::insert(10, Approve); + v0::DefenderVotes::::insert(20, Approve); + v0::DefenderVotes::::insert(30, Reject); - old::SuspendedCandidates::::insert(50, (10, Deposit(100))); + v0::SuspendedCandidates::::insert(50, (10, Deposit(100))); - old::Candidates::::put(vec![ + v0::Candidates::::put(vec![ Bid { who: 60, kind: Deposit(100), value: 200 }, Bid { who: 70, kind: Vouch(30, 30), value: 100 }, ]); - old::Votes::::insert(60, 10, Approve); - old::Votes::::insert(70, 10, Reject); - old::Votes::::insert(70, 20, Approve); - old::Votes::::insert(70, 30, Approve); + v0::Votes::::insert(60, 10, Approve); + v0::Votes::::insert(70, 10, Reject); + v0::Votes::::insert(70, 20, Approve); + v0::Votes::::insert(70, 30, Approve); let bids = (0..=::MaxBids::get()) .map(|i| Bid { @@ -75,7 +75,7 @@ fn migration_works() { value: 10u64 + i as u64, }) .collect::>(); - old::Bids::::put(bids); + v0::Bids::::put(bids); migrations::from_original::(&mut [][..]).expect("migration failed"); migrations::assert_internal_consistency::(); diff --git a/substrate/frame/staking/src/migrations.rs b/substrate/frame/staking/src/migrations.rs index 98984be9920..3e3b1113a81 100644 --- a/substrate/frame/staking/src/migrations.rs +++ b/substrate/frame/staking/src/migrations.rs @@ -67,11 +67,11 @@ pub mod v14 { pub struct MigrateToV14(core::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV14 { fn on_runtime_upgrade() -> Weight { - let current = Pallet::::current_storage_version(); + let in_code = Pallet::::in_code_storage_version(); let on_chain = Pallet::::on_chain_storage_version(); - if current == 14 && on_chain == 13 { - current.put::>(); + if in_code == 14 && on_chain == 13 { + in_code.put::>(); log!(info, "v14 applied successfully."); T::DbWeight::get().reads_writes(1, 1) @@ -108,12 +108,12 @@ pub mod v13 { } fn on_runtime_upgrade() -> Weight { - let current = Pallet::::current_storage_version(); + let in_code = Pallet::::in_code_storage_version(); let onchain = StorageVersion::::get(); - if current == 13 && onchain == ObsoleteReleases::V12_0_0 { + if in_code == 13 && onchain == ObsoleteReleases::V12_0_0 { StorageVersion::::kill(); - current.put::>(); + in_code.put::>(); log!(info, "v13 applied successfully"); T::DbWeight::get().reads_writes(1, 2) diff --git a/substrate/frame/staking/src/pallet/mod.rs b/substrate/frame/staking/src/pallet/mod.rs index e0213efd507..992a7fe2c9c 100644 --- a/substrate/frame/staking/src/pallet/mod.rs +++ b/substrate/frame/staking/src/pallet/mod.rs @@ -66,7 +66,7 @@ pub mod pallet { use super::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(14); #[pallet::pallet] diff --git a/substrate/frame/support/procedural/src/lib.rs b/substrate/frame/support/procedural/src/lib.rs index 78729ee3dc3..5840377d722 100644 --- a/substrate/frame/support/procedural/src/lib.rs +++ b/substrate/frame/support/procedural/src/lib.rs @@ -555,6 +555,42 @@ pub fn __create_tt_macro(input: TokenStream) -> TokenStream { tt_macro::create_tt_return_macro(input) } +/// Allows accessing on-chain pallet storage that is no longer accessible via the pallet. +/// +/// This is especially useful when writing storage migrations, when types of storage items are +/// modified or outright removed, but the previous definition is required to perform the migration. +/// +/// ## Example +/// +/// Imagine a pallet with the following storage definition: +/// ```ignore +/// #[pallet::storage] +/// pub type Value = StorageValue<_, u32>; +/// ``` +/// `Value` can be accessed by calling `Value::::get()`. +/// +/// Now imagine the definition of `Value` is updated to a `(u32, u32)`: +/// ```ignore +/// #[pallet::storage] +/// pub type Value = StorageValue<_, (u32, u32)>; +/// ``` +/// The on-chain value of `Value` is `u32`, but `Value::::get()` expects it to be `(u32, u32)`. +/// +/// In this instance the developer must write a storage migration to reading the old value of +/// `Value` and writing it back to storage in the new format, so that the on-chain storage layout is +/// consistent with what is defined in the pallet. +/// +/// We can read the old v0 value of `Value` in the migration by creating a `storage_alias`: +/// ```ignore +/// pub(crate) mod v0 { +/// use super::*; +/// +/// #[storage_alias] +/// pub type Value = StorageValue, u32>; +/// } +/// ``` +/// +/// The developer can now access the old value of `Value` by calling `v0::Value::::get()`. #[proc_macro_attribute] pub fn storage_alias(attributes: TokenStream, input: TokenStream) -> TokenStream { storage_alias::storage_alias(attributes.into(), input.into()) @@ -1058,7 +1094,7 @@ pub fn generate_store(_: TokenStream, _: TokenStream) -> TokenStream { /// pub struct Pallet(_); /// ``` /// -/// If not present, the current storage version is set to the default value. +/// If not present, the in-code storage version is set to the default value. #[proc_macro_attribute] pub fn storage_version(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() diff --git a/substrate/frame/support/procedural/src/pallet/expand/hooks.rs b/substrate/frame/support/procedural/src/pallet/expand/hooks.rs index 5044d4285bb..6b25ddcba1a 100644 --- a/substrate/frame/support/procedural/src/pallet/expand/hooks.rs +++ b/substrate/frame/support/procedural/src/pallet/expand/hooks.rs @@ -42,7 +42,7 @@ pub fn expand_hooks(def: &mut Def) -> proc_macro2::TokenStream { >::name::().unwrap_or("") }; - let initialize_on_chain_storage_version = if let Some(current_version) = + let initialize_on_chain_storage_version = if let Some(in_code_version) = &def.pallet_struct.storage_version { quote::quote! { @@ -50,9 +50,9 @@ pub fn expand_hooks(def: &mut Def) -> proc_macro2::TokenStream { target: #frame_support::LOG_TARGET, "🐥 New pallet {:?} detected in the runtime. Initializing the on-chain storage version to match the storage version defined in the pallet: {:?}", #pallet_name, - #current_version + #in_code_version ); - #current_version.put::(); + #in_code_version.put::(); } } else { quote::quote! { @@ -73,10 +73,10 @@ pub fn expand_hooks(def: &mut Def) -> proc_macro2::TokenStream { #frame_support::__private::log::info!( target: #frame_support::LOG_TARGET, "⚠️ {} declares internal migrations (which *might* execute). \ - On-chain `{:?}` vs current storage version `{:?}`", + On-chain `{:?}` vs in-code storage version `{:?}`", #pallet_name, ::on_chain_storage_version(), - ::current_storage_version(), + ::in_code_storage_version(), ); } } else { @@ -102,23 +102,23 @@ pub fn expand_hooks(def: &mut Def) -> proc_macro2::TokenStream { }; // If a storage version is set, we should ensure that the storage version on chain matches the - // current storage version. This assumes that `Executive` is running custom migrations before + // in-code storage version. This assumes that `Executive` is running custom migrations before // the pallets are called. let post_storage_version_check = if def.pallet_struct.storage_version.is_some() { quote::quote! { let on_chain_version = ::on_chain_storage_version(); - let current_version = ::current_storage_version(); + let in_code_version = ::in_code_storage_version(); - if on_chain_version != current_version { + if on_chain_version != in_code_version { #frame_support::__private::log::error!( target: #frame_support::LOG_TARGET, - "{}: On chain storage version {:?} doesn't match current storage version {:?}.", + "{}: On chain storage version {:?} doesn't match in-code storage version {:?}.", #pallet_name, on_chain_version, - current_version, + in_code_version, ); - return Err("On chain and current storage version do not match. Missing runtime upgrade?".into()); + return Err("On chain and in-code storage version do not match. Missing runtime upgrade?".into()); } } } else { diff --git a/substrate/frame/support/procedural/src/pallet/expand/pallet_struct.rs b/substrate/frame/support/procedural/src/pallet/expand/pallet_struct.rs index c2102f0284d..7cdf6bde9de 100644 --- a/substrate/frame/support/procedural/src/pallet/expand/pallet_struct.rs +++ b/substrate/frame/support/procedural/src/pallet/expand/pallet_struct.rs @@ -160,7 +160,7 @@ pub fn expand_pallet_struct(def: &mut Def) -> proc_macro2::TokenStream { } ); - let (storage_version, current_storage_version_ty) = + let (storage_version, in_code_storage_version_ty) = if let Some(v) = def.pallet_struct.storage_version.as_ref() { (quote::quote! { #v }, quote::quote! { #frame_support::traits::StorageVersion }) } else { @@ -203,9 +203,9 @@ pub fn expand_pallet_struct(def: &mut Def) -> proc_macro2::TokenStream { for #pallet_ident<#type_use_gen> #config_where_clause { - type CurrentStorageVersion = #current_storage_version_ty; + type InCodeStorageVersion = #in_code_storage_version_ty; - fn current_storage_version() -> Self::CurrentStorageVersion { + fn in_code_storage_version() -> Self::InCodeStorageVersion { #storage_version } diff --git a/substrate/frame/support/procedural/src/pallet/parse/pallet_struct.rs b/substrate/frame/support/procedural/src/pallet/parse/pallet_struct.rs index f4af86aa3e9..c2855ae38ef 100644 --- a/substrate/frame/support/procedural/src/pallet/parse/pallet_struct.rs +++ b/substrate/frame/support/procedural/src/pallet/parse/pallet_struct.rs @@ -44,7 +44,7 @@ pub struct PalletStructDef { /// Whether to specify the storages max encoded len when implementing `StorageInfoTrait`. /// Contains the span of the attribute. pub without_storage_info: Option, - /// The current storage version of the pallet. + /// The in-code storage version of the pallet. pub storage_version: Option, } diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs index 3e97a384275..d2d9a33053f 100644 --- a/substrate/frame/support/src/lib.rs +++ b/substrate/frame/support/src/lib.rs @@ -1178,7 +1178,7 @@ pub mod pallet_prelude { /// # `pallet::storage_version` /// /// Because the [`pallet::pallet`](#pallet-struct-placeholder-palletpallet-mandatory) macro -/// implements [`traits::GetStorageVersion`], the current storage version needs to be +/// implements [`traits::GetStorageVersion`], the in-code storage version needs to be /// communicated to the macro. This can be done by using the `pallet::storage_version` /// attribute: /// @@ -1190,7 +1190,7 @@ pub mod pallet_prelude { /// pub struct Pallet(_); /// ``` /// -/// If not present, the current storage version is set to the default value. +/// If not present, the in-code storage version is set to the default value. /// /// Also see [`pallet::storage_version`](`frame_support::pallet_macros::storage_version`) /// diff --git a/substrate/frame/support/src/migrations.rs b/substrate/frame/support/src/migrations.rs index d059a992a86..f7541059023 100644 --- a/substrate/frame/support/src/migrations.rs +++ b/substrate/frame/support/src/migrations.rs @@ -43,12 +43,30 @@ use sp_std::marker::PhantomData; /// Otherwise, a warning is logged notifying the developer that the upgrade was a noop and should /// probably be removed. /// +/// It is STRONGLY RECOMMENDED to write the unversioned migration logic in a private module and +/// only export the versioned migration logic to prevent accidentally using the unversioned +/// migration in any runtimes. +/// /// ### Examples /// ```ignore /// // In file defining migrations -/// pub struct VersionUncheckedMigrateV5ToV6(sp_std::marker::PhantomData); -/// impl OnRuntimeUpgrade for VersionUncheckedMigrateV5ToV6 { -/// // OnRuntimeUpgrade implementation... +/// +/// /// Private module containing *version unchecked* migration logic. +/// /// +/// /// Should only be used by the [`VersionedMigration`] type in this module to create something to +/// /// export. +/// /// +/// /// We keep this private so the unversioned migration cannot accidentally be used in any runtimes. +/// /// +/// /// For more about this pattern of keeping items private, see +/// /// - https://github.com/rust-lang/rust/issues/30905 +/// /// - https://internals.rust-lang.org/t/lang-team-minutes-private-in-public-rules/4504/40 +/// mod version_unchecked { +/// use super::*; +/// pub struct MigrateV5ToV6(sp_std::marker::PhantomData); +/// impl OnRuntimeUpgrade for VersionUncheckedMigrateV5ToV6 { +/// // OnRuntimeUpgrade implementation... +/// } /// } /// /// pub type MigrateV5ToV6 = @@ -91,7 +109,7 @@ impl< const FROM: u16, const TO: u16, Inner: crate::traits::OnRuntimeUpgrade, - Pallet: GetStorageVersion + PalletInfoAccess, + Pallet: GetStorageVersion + PalletInfoAccess, DbWeight: Get, > crate::traits::OnRuntimeUpgrade for VersionedMigration { @@ -163,25 +181,25 @@ impl< } } -/// Can store the current pallet version in storage. -pub trait StoreCurrentStorageVersion { - /// Write the current storage version to the storage. - fn store_current_storage_version(); +/// Can store the in-code pallet version on-chain. +pub trait StoreInCodeStorageVersion { + /// Write the in-code storage version on-chain. + fn store_in_code_storage_version(); } -impl + PalletInfoAccess> - StoreCurrentStorageVersion for StorageVersion +impl + PalletInfoAccess> + StoreInCodeStorageVersion for StorageVersion { - fn store_current_storage_version() { - let version = ::current_storage_version(); + fn store_in_code_storage_version() { + let version = ::in_code_storage_version(); version.put::(); } } -impl + PalletInfoAccess> - StoreCurrentStorageVersion for NoStorageVersionSet +impl + PalletInfoAccess> + StoreInCodeStorageVersion for NoStorageVersionSet { - fn store_current_storage_version() { + fn store_in_code_storage_version() { StorageVersion::default().put::(); } } @@ -193,7 +211,7 @@ pub trait PalletVersionToStorageVersionHelper { impl PalletVersionToStorageVersionHelper for T where - T::CurrentStorageVersion: StoreCurrentStorageVersion, + T::InCodeStorageVersion: StoreInCodeStorageVersion, { fn migrate(db_weight: &RuntimeDbWeight) -> Weight { const PALLET_VERSION_STORAGE_KEY_POSTFIX: &[u8] = b":__PALLET_VERSION__:"; @@ -204,8 +222,7 @@ where sp_io::storage::clear(&pallet_version_key(::name())); - >::store_current_storage_version( - ); + >::store_in_code_storage_version(); db_weight.writes(2) } @@ -226,7 +243,7 @@ impl PalletVersionToStorageVersionHelper for T { /// Migrate from the `PalletVersion` struct to the new [`StorageVersion`] struct. /// -/// This will remove all `PalletVersion's` from the state and insert the current storage version. +/// This will remove all `PalletVersion's` from the state and insert the in-code storage version. pub fn migrate_from_pallet_version_to_storage_version< Pallets: PalletVersionToStorageVersionHelper, >( diff --git a/substrate/frame/support/src/traits/hooks.rs b/substrate/frame/support/src/traits/hooks.rs index 20788ce932d..72f047c3a73 100644 --- a/substrate/frame/support/src/traits/hooks.rs +++ b/substrate/frame/support/src/traits/hooks.rs @@ -90,7 +90,7 @@ impl OnIdle for Tuple { /// /// Implementing this trait for a pallet let's you express operations that should /// happen at genesis. It will be called in an externalities provided environment and -/// will see the genesis state after all pallets have written their genesis state. +/// will set the genesis state after all pallets have written their genesis state. #[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))] #[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))] #[cfg_attr(feature = "tuples-128", impl_for_tuples(128))] @@ -306,19 +306,23 @@ pub trait IntegrityTest { /// end /// ``` /// -/// * `OnRuntimeUpgrade` is only executed before everything else if a code -/// * `OnRuntimeUpgrade` is mandatorily at the beginning of the block body (extrinsics) being -/// processed. change is detected. -/// * Extrinsics start with inherents, and continue with other signed or unsigned extrinsics. -/// * `OnIdle` optionally comes after extrinsics. -/// `OnFinalize` mandatorily comes after `OnIdle`. +/// * [`OnRuntimeUpgrade`](Hooks::OnRuntimeUpgrade) hooks are only executed when a code change is +/// detected. +/// * [`OnRuntimeUpgrade`](Hooks::OnRuntimeUpgrade) hooks are mandatorily executed at the very +/// beginning of the block body, before any extrinsics are processed. +/// * [`Inherents`](sp_inherents) are always executed before any other other signed or unsigned +/// extrinsics. +/// * [`OnIdle`](Hooks::OnIdle) hooks are executed after extrinsics if there is weight remaining in +/// the block. +/// * [`OnFinalize`](Hooks::OnFinalize) hooks are mandatorily executed after +/// [`OnIdle`](Hooks::OnIdle). /// -/// > `OffchainWorker` is not part of this flow, as it is not really part of the consensus/main -/// > block import path, and is called optionally, and in other circumstances. See -/// > [`crate::traits::misc::OffchainWorker`] for more information. +/// > [`OffchainWorker`](crate::traits::misc::OffchainWorker) hooks are not part of this flow, +/// > because they are not part of the consensus/main block building logic. See +/// > [`OffchainWorker`](crate::traits::misc::OffchainWorker) for more information. /// -/// To learn more about the execution of hooks see `frame-executive` as this component is is charge -/// of dispatching extrinsics and placing the hooks in the correct order. +/// To learn more about the execution of hooks see the FRAME `Executive` pallet which is in charge +/// of dispatching extrinsics and calling hooks in the correct order. pub trait Hooks { /// Block initialization hook. This is called at the very beginning of block execution. /// @@ -370,30 +374,38 @@ pub trait Hooks { Weight::zero() } - /// Hook executed when a code change (aka. a "runtime upgrade") is detected by FRAME. + /// Hook executed when a code change (aka. a "runtime upgrade") is detected by the FRAME + /// `Executive` pallet. /// /// Be aware that this is called before [`Hooks::on_initialize`] of any pallet; therefore, a lot /// of the critical storage items such as `block_number` in system pallet might have not been - /// set. + /// set yet. /// - /// Vert similar to [`Hooks::on_initialize`], any code in this block is mandatory and MUST - /// execute. Use with care. + /// Similar to [`Hooks::on_initialize`], any code in this block is mandatory and MUST execute. + /// It is strongly recommended to dry-run the execution of these hooks using + /// [try-runtime-cli](https://github.com/paritytech/try-runtime-cli) to ensure they will not + /// produce and overweight block which can brick your chain. Use with care! /// - /// ## Implementation Note: Versioning + /// ## Implementation Note: Standalone Migrations /// - /// 1. An implementation of this should typically follow a pattern where the version of the - /// pallet is checked against the onchain version, and a decision is made about what needs to be - /// done. This is helpful to prevent accidental repetitive execution of this hook, which can be - /// catastrophic. + /// Additional migrations can be created by directly implementing [`OnRuntimeUpgrade`] on + /// structs and passing them to `Executive`. /// - /// Alternatively, [`frame_support::migrations::VersionedMigration`] can be used to assist with - /// this. + /// ## Implementation Note: Pallet Versioning /// - /// ## Implementation Note: Runtime Level Migration + /// Implementations of this hook are typically wrapped in + /// [`crate::migrations::VersionedMigration`] to ensure the migration is executed exactly + /// once and only when it is supposed to. /// - /// Additional "upgrade hooks" can be created by pallets by a manual implementation of - /// [`Hooks::on_runtime_upgrade`] which can be passed on to `Executive` at the top level - /// runtime. + /// Alternatively, developers can manually implement version checks. + /// + /// Failure to adequately check storage versions can result in accidental repetitive execution + /// of the hook, which can be catastrophic. + /// + /// ## Implementation Note: Weight + /// + /// Typically, implementations of this method are simple enough that weights can be calculated + /// manually. However, if required, a benchmark can also be used. fn on_runtime_upgrade() -> Weight { Weight::zero() } @@ -403,7 +415,7 @@ pub trait Hooks { /// It should focus on certain checks to ensure that the state is sensible. This is never /// executed in a consensus code-path, therefore it can consume as much weight as it needs. /// - /// This hook should not alter any storage. + /// This hook must not alter any storage. #[cfg(feature = "try-runtime")] fn try_state(_n: BlockNumber) -> Result<(), TryRuntimeError> { Ok(()) @@ -415,7 +427,7 @@ pub trait Hooks { /// which will be passed to `post_upgrade` after upgrading for post-check. An empty vector /// should be returned if there is no such need. /// - /// This hook is never meant to be executed on-chain but is meant to be used by testing tools. + /// This hook is never executed on-chain but instead used by testing tools. #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result, TryRuntimeError> { Ok(Vec::new()) diff --git a/substrate/frame/support/src/traits/metadata.rs b/substrate/frame/support/src/traits/metadata.rs index 586af20511a..8bda4186bc9 100644 --- a/substrate/frame/support/src/traits/metadata.rs +++ b/substrate/frame/support/src/traits/metadata.rs @@ -261,41 +261,64 @@ impl Add for StorageVersion { } } -/// Special marker struct if no storage version is set for a pallet. +/// Special marker struct used when [`storage_version`](crate::pallet_macros::storage_version) is +/// not defined for a pallet. /// /// If you (the reader) end up here, it probably means that you tried to compare /// [`GetStorageVersion::on_chain_storage_version`] against -/// [`GetStorageVersion::current_storage_version`]. This basically means that the -/// [`storage_version`](crate::pallet_macros::storage_version) is missing in the pallet where the -/// mentioned functions are being called. +/// [`GetStorageVersion::in_code_storage_version`]. This basically means that the +/// [`storage_version`](crate::pallet_macros::storage_version) is missing from the pallet where the +/// mentioned functions are being called, and needs to be defined. #[derive(Debug, Default)] pub struct NoStorageVersionSet; -/// Provides information about the storage version of a pallet. +/// Provides information about a pallet's storage versions. /// -/// It differentiates between current and on-chain storage version. Both should be only out of sync -/// when a new runtime upgrade was applied and the runtime migrations did not yet executed. -/// Otherwise it means that the pallet works with an unsupported storage version and unforeseen -/// stuff can happen. +/// Every pallet has two storage versions: +/// 1. An in-code storage version +/// 2. An on-chain storage version /// -/// The current storage version is the version of the pallet as supported at runtime. The active -/// storage version is the version of the pallet in the storage. +/// The in-code storage version is the version of the pallet as defined in the runtime blob, and the +/// on-chain storage version is the version of the pallet stored on-chain. /// -/// It is required to update the on-chain storage version manually when a migration was applied. +/// Storage versions should be only ever be out of sync when a pallet has been updated to a new +/// version and the in-code version is incremented, but the migration has not yet been executed +/// on-chain as part of a runtime upgrade. +/// +/// It is the responsibility of the developer to ensure that the on-chain storage version is set +/// correctly during a migration so that it matches the in-code storage version. pub trait GetStorageVersion { - /// This will be filled out by the [`pallet`](crate::pallet) macro. + /// This type is generated by the [`pallet`](crate::pallet) macro. + /// + /// If the [`storage_version`](crate::pallet_macros::storage_version) attribute isn't specified, + /// this is set to [`NoStorageVersionSet`] to signify that it is missing. + /// + /// If the [`storage_version`](crate::pallet_macros::storage_version) attribute is specified, + /// this is be set to a [`StorageVersion`] corresponding to the attribute. /// - /// If the [`storage_version`](crate::pallet_macros::storage_version) attribute isn't given - /// this is set to [`NoStorageVersionSet`] to inform the user that the attribute is missing. - /// This should prevent that the user forgets to set a storage version when required. However, - /// this will only work when the user actually tries to call [`Self::current_storage_version`] - /// to compare it against the [`Self::on_chain_storage_version`]. If the attribute is given, - /// this will be set to [`StorageVersion`]. - type CurrentStorageVersion; - - /// Returns the current storage version as supported by the pallet. - fn current_storage_version() -> Self::CurrentStorageVersion; - /// Returns the on-chain storage version of the pallet as stored in the storage. + /// The intention of using [`NoStorageVersionSet`] instead of defaulting to a [`StorageVersion`] + /// of zero is to prevent developers from forgetting to set + /// [`storage_version`](crate::pallet_macros::storage_version) when it is required, like in the + /// case that they wish to compare the in-code storage version to the on-chain storage version. + type InCodeStorageVersion; + + #[deprecated( + note = "This method has been renamed to `in_code_storage_version` and will be removed after March 2024." + )] + /// DEPRECATED: Use [`Self::current_storage_version`] instead. + /// + /// Returns the in-code storage version as specified in the + /// [`storage_version`](crate::pallet_macros::storage_version) attribute, or + /// [`NoStorageVersionSet`] if the attribute is missing. + fn current_storage_version() -> Self::InCodeStorageVersion { + Self::in_code_storage_version() + } + + /// Returns the in-code storage version as specified in the + /// [`storage_version`](crate::pallet_macros::storage_version) attribute, or + /// [`NoStorageVersionSet`] if the attribute is missing. + fn in_code_storage_version() -> Self::InCodeStorageVersion; + /// Returns the storage version of the pallet as last set in the actual on-chain storage. fn on_chain_storage_version() -> StorageVersion; } diff --git a/substrate/frame/support/test/tests/construct_runtime.rs b/substrate/frame/support/test/tests/construct_runtime.rs index b8341b25cb0..b7698681886 100644 --- a/substrate/frame/support/test/tests/construct_runtime.rs +++ b/substrate/frame/support/test/tests/construct_runtime.rs @@ -683,7 +683,7 @@ fn test_metadata() { name: "Version", ty: meta_type::(), value: RuntimeVersion::default().encode(), - docs: maybe_docs(vec![ " Get the chain's current version."]), + docs: maybe_docs(vec![ " Get the chain's in-code version."]), }, PalletConstantMetadata { name: "SS58Prefix", diff --git a/substrate/frame/support/test/tests/pallet.rs b/substrate/frame/support/test/tests/pallet.rs index 9b4381c2f82..7bee4b7c820 100644 --- a/substrate/frame/support/test/tests/pallet.rs +++ b/substrate/frame/support/test/tests/pallet.rs @@ -590,7 +590,7 @@ pub mod pallet2 { Self::deposit_event(Event::Something(31)); if UpdateStorageVersion::get() { - Self::current_storage_version().put::(); + Self::in_code_storage_version().put::(); } Weight::zero() @@ -1310,7 +1310,7 @@ fn pallet_on_genesis() { assert_eq!(pallet::Pallet::::on_chain_storage_version(), StorageVersion::new(0)); pallet::Pallet::::on_genesis(); assert_eq!( - pallet::Pallet::::current_storage_version(), + pallet::Pallet::::in_code_storage_version(), pallet::Pallet::::on_chain_storage_version(), ); }) @@ -2257,10 +2257,10 @@ fn pallet_on_chain_storage_version_initializes_correctly() { AllPalletsWithSystem, >; - // Simple example of a pallet with current version 10 being added to the runtime for the first + // Simple example of a pallet with in-code version 10 being added to the runtime for the first // time. TestExternalities::default().execute_with(|| { - let current_version = Example::current_storage_version(); + let in_code_version = Example::in_code_storage_version(); // Check the pallet has no storage items set. let pallet_hashed_prefix = twox_128(Example::name().as_bytes()); @@ -2271,14 +2271,14 @@ fn pallet_on_chain_storage_version_initializes_correctly() { // version. Executive::execute_on_runtime_upgrade(); - // Check that the storage version was initialized to the current version + // Check that the storage version was initialized to the in-code version let on_chain_version_after = StorageVersion::get::(); - assert_eq!(on_chain_version_after, current_version); + assert_eq!(on_chain_version_after, in_code_version); }); - // Pallet with no current storage version should have the on-chain version initialized to 0. + // Pallet with no in-code storage version should have the on-chain version initialized to 0. TestExternalities::default().execute_with(|| { - // Example4 current_storage_version is NoStorageVersionSet. + // Example4 in_code_storage_version is NoStorageVersionSet. // Check the pallet has no storage items set. let pallet_hashed_prefix = twox_128(Example4::name().as_bytes()); @@ -2308,7 +2308,7 @@ fn post_runtime_upgrade_detects_storage_version_issues() { impl OnRuntimeUpgrade for CustomUpgrade { fn on_runtime_upgrade() -> Weight { - Example2::current_storage_version().put::(); + Example2::in_code_storage_version().put::(); Default::default() } @@ -2351,14 +2351,14 @@ fn post_runtime_upgrade_detects_storage_version_issues() { >; TestExternalities::default().execute_with(|| { - // Set the on-chain version to one less than the current version for `Example`, simulating a + // Set the on-chain version to one less than the in-code version for `Example`, simulating a // forgotten migration StorageVersion::new(9).put::(); // The version isn't changed, we should detect it. assert!( Executive::try_runtime_upgrade(UpgradeCheckSelect::PreAndPost).unwrap_err() == - "On chain and current storage version do not match. Missing runtime upgrade?" + "On chain and in-code storage version do not match. Missing runtime upgrade?" .into() ); }); diff --git a/substrate/frame/support/test/tests/pallet_ui/compare_unset_storage_version.rs b/substrate/frame/support/test/tests/pallet_ui/compare_unset_storage_version.rs index 840a6dee20c..d2ca9fc8099 100644 --- a/substrate/frame/support/test/tests/pallet_ui/compare_unset_storage_version.rs +++ b/substrate/frame/support/test/tests/pallet_ui/compare_unset_storage_version.rs @@ -29,7 +29,7 @@ mod pallet { #[pallet::hooks] impl Hooks> for Pallet { fn on_runtime_upgrade() -> Weight { - if Self::current_storage_version() != Self::on_chain_storage_version() { + if Self::in_code_storage_version() != Self::on_chain_storage_version() { } diff --git a/substrate/frame/support/test/tests/pallet_ui/compare_unset_storage_version.stderr b/substrate/frame/support/test/tests/pallet_ui/compare_unset_storage_version.stderr index 1b48197cc9e..3256e69528a 100644 --- a/substrate/frame/support/test/tests/pallet_ui/compare_unset_storage_version.stderr +++ b/substrate/frame/support/test/tests/pallet_ui/compare_unset_storage_version.stderr @@ -1,7 +1,7 @@ error[E0369]: binary operation `!=` cannot be applied to type `NoStorageVersionSet` --> tests/pallet_ui/compare_unset_storage_version.rs:32:39 | -32 | if Self::current_storage_version() != Self::on_chain_storage_version() { +32 | if Self::in_code_storage_version() != Self::on_chain_storage_version() { | ------------------------------- ^^ -------------------------------- StorageVersion | | | NoStorageVersionSet diff --git a/substrate/frame/system/src/lib.rs b/substrate/frame/system/src/lib.rs index c527a483d88..01df09106d9 100644 --- a/substrate/frame/system/src/lib.rs +++ b/substrate/frame/system/src/lib.rs @@ -525,7 +525,7 @@ pub mod pallet { #[pallet::constant] type DbWeight: Get; - /// Get the chain's current version. + /// Get the chain's in-code version. #[pallet::constant] type Version: Get; diff --git a/substrate/frame/tips/src/lib.rs b/substrate/frame/tips/src/lib.rs index 4c7cfc3028a..8c360fb57d7 100644 --- a/substrate/frame/tips/src/lib.rs +++ b/substrate/frame/tips/src/lib.rs @@ -122,7 +122,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(4); #[pallet::pallet] -- GitLab From f1b2189e8312821a9f8a79dc4f0183d314273faa Mon Sep 17 00:00:00 2001 From: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> Date: Wed, 28 Feb 2024 11:43:58 +0200 Subject: [PATCH 318/392] rpc-v2/tx/tests: Add transaction broadcast tests and check propagated tx status (#3193) This PR adds tests for the `transaction_broadcast` method. The testing needs to coordinate the following components: - The `TestApi` marks transactions as invalid and implements `ChainApi::validate_transaction` - this is what dictates if a transaction is valid or not and is called from within the `BasicPool` - The `BasicPool` which maintains the transactions and implements `submit_and_watch` needed by the tx broadcast to submit the transaction - The status of the transaction pool is exposed by mocking the BasicPool - The `ChainHeadMockClient` which mocks the `BlockchainEvents::import_notification_stream` needed by the tx broadcast to know to which blocks the transaction is submitted The following changes have been added to the substrate testing to accommodate this: - `TestApi` gets ` remove_invalid`, counterpart to `add_invalid` to ensure an invalid transaction can become valid again; as well as a priority setter for extrinsics - `BasicPool` test constructor is extended with options for the `PoolRotator` - this mechanism is needed because transactions are banned for 30mins (default) after they are declared invalid - testing bypasses this by providing a `Duration::ZERO` ### Testing Scenarios - Capture the status of the transaction as it is normally broadcasted - `transaction_stop` is valid while the transaction is in progress - A future transaction is handled when the dependencies are completed - Try to resubmit the transaction at a later block (currently invalid) - An invalid transaction status is propagated; the transaction is marked as temporarily banned; then the ban expires and transaction is resubmitted This builds on top of: https://github.com/paritytech/polkadot-sdk/pull/3079 Part of: https://github.com/paritytech/polkadot-sdk/issues/3084 cc @paritytech/subxt-team --------- Signed-off-by: Alexandru Vasile Co-authored-by: James Wilson --- .../rpc-spec-v2/src/chain_head/test_utils.rs | 4 +- .../rpc-spec-v2/src/transaction/tests.rs | 238 -------- .../src/transaction/tests/executor.rs | 100 ++++ .../src/transaction/tests/middleware_pool.rs | 187 +++++++ .../rpc-spec-v2/src/transaction/tests/mod.rs | 24 + .../src/transaction/tests/setup.rs | 120 ++++ .../tests/transaction_broadcast_tests.rs | 523 ++++++++++++++++++ substrate/client/transaction-pool/src/lib.rs | 3 +- .../client/transaction-pool/tests/pool.rs | 3 +- .../runtime/transaction-pool/src/lib.rs | 27 +- 10 files changed, 985 insertions(+), 244 deletions(-) delete mode 100644 substrate/client/rpc-spec-v2/src/transaction/tests.rs create mode 100644 substrate/client/rpc-spec-v2/src/transaction/tests/executor.rs create mode 100644 substrate/client/rpc-spec-v2/src/transaction/tests/middleware_pool.rs create mode 100644 substrate/client/rpc-spec-v2/src/transaction/tests/mod.rs create mode 100644 substrate/client/rpc-spec-v2/src/transaction/tests/setup.rs create mode 100644 substrate/client/rpc-spec-v2/src/transaction/tests/transaction_broadcast_tests.rs diff --git a/substrate/client/rpc-spec-v2/src/chain_head/test_utils.rs b/substrate/client/rpc-spec-v2/src/chain_head/test_utils.rs index d63a98a5cb0..e81bd4bfa0b 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/test_utils.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/test_utils.rs @@ -63,7 +63,7 @@ impl ChainHeadMockClient { BlockImportNotification::new(header.hash(), BlockOrigin::Own, header, true, None, sink); for sink in self.import_sinks.lock().iter_mut() { - sink.unbounded_send(notification.clone()).unwrap(); + let _ = sink.unbounded_send(notification.clone()); } } @@ -83,7 +83,7 @@ impl ChainHeadMockClient { let notification = FinalityNotification::from_summary(summary, sink); for sink in self.finality_sinks.lock().iter_mut() { - sink.unbounded_send(notification.clone()).unwrap(); + let _ = sink.unbounded_send(notification.clone()); } } } diff --git a/substrate/client/rpc-spec-v2/src/transaction/tests.rs b/substrate/client/rpc-spec-v2/src/transaction/tests.rs deleted file mode 100644 index 382f5adeae1..00000000000 --- a/substrate/client/rpc-spec-v2/src/transaction/tests.rs +++ /dev/null @@ -1,238 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use super::*; -use crate::{ - chain_head::test_utils::ChainHeadMockClient, hex_string, - transaction::TransactionBroadcast as RpcTransactionBroadcast, -}; -use assert_matches::assert_matches; -use codec::Encode; -use futures::Future; -use jsonrpsee::{rpc_params, MethodsError as Error, RpcModule}; -use sc_transaction_pool::*; -use sc_transaction_pool_api::{ChainEvent, MaintainedTransactionPool, TransactionPool}; -use sp_core::{testing::TaskExecutor, traits::SpawnNamed}; -use std::{pin::Pin, sync::Arc, time::Duration}; -use substrate_test_runtime_client::{prelude::*, AccountKeyring::*, Client}; -use substrate_test_runtime_transaction_pool::{uxt, TestApi}; -use tokio::sync::mpsc; - -type Block = substrate_test_runtime_client::runtime::Block; - -/// Wrap the `TaskExecutor` to know when the broadcast future is dropped. -#[derive(Clone)] -struct TaskExecutorBroadcast { - executor: TaskExecutor, - sender: mpsc::UnboundedSender<()>, -} - -/// The channel that receives events when the broadcast futures are dropped. -type TaskExecutorRecv = mpsc::UnboundedReceiver<()>; - -impl TaskExecutorBroadcast { - /// Construct a new `TaskExecutorBroadcast` and a receiver to know when the broadcast futures - /// are dropped. - fn new() -> (Self, TaskExecutorRecv) { - let (sender, recv) = mpsc::unbounded_channel(); - - (Self { executor: TaskExecutor::new(), sender }, recv) - } -} - -impl SpawnNamed for TaskExecutorBroadcast { - fn spawn( - &self, - name: &'static str, - group: Option<&'static str>, - future: futures::future::BoxFuture<'static, ()>, - ) { - let sender = self.sender.clone(); - let future = Box::pin(async move { - future.await; - let _ = sender.send(()); - }); - - self.executor.spawn(name, group, future) - } - - fn spawn_blocking( - &self, - name: &'static str, - group: Option<&'static str>, - future: futures::future::BoxFuture<'static, ()>, - ) { - let sender = self.sender.clone(); - let future = Box::pin(async move { - future.await; - let _ = sender.send(()); - }); - - self.executor.spawn_blocking(name, group, future) - } -} - -/// Initial Alice account nonce. -const ALICE_NONCE: u64 = 209; - -fn create_basic_pool_with_genesis( - test_api: Arc, -) -> (BasicPool, Pin + Send>>) { - let genesis_hash = { - test_api - .chain() - .read() - .block_by_number - .get(&0) - .map(|blocks| blocks[0].0.header.hash()) - .expect("there is block 0. qed") - }; - BasicPool::new_test(test_api, genesis_hash, genesis_hash) -} - -fn maintained_pool() -> (BasicPool, Arc, futures::executor::ThreadPool) { - let api = Arc::new(TestApi::with_alice_nonce(ALICE_NONCE)); - let (pool, background_task) = create_basic_pool_with_genesis(api.clone()); - - let thread_pool = futures::executor::ThreadPool::new().unwrap(); - thread_pool.spawn_ok(background_task); - (pool, api, thread_pool) -} - -fn setup_api() -> ( - Arc, - Arc>, - Arc>>, - RpcModule< - TransactionBroadcast, ChainHeadMockClient>>, - >, - TaskExecutorRecv, -) { - let (pool, api, _) = maintained_pool(); - let pool = Arc::new(pool); - - let builder = TestClientBuilder::new(); - let client = Arc::new(builder.build()); - let client_mock = Arc::new(ChainHeadMockClient::new(client.clone())); - - let (task_executor, executor_recv) = TaskExecutorBroadcast::new(); - - let tx_api = - RpcTransactionBroadcast::new(client_mock.clone(), pool.clone(), Arc::new(task_executor)) - .into_rpc(); - - (api, pool, client_mock, tx_api, executor_recv) -} - -#[tokio::test] -async fn tx_broadcast_enters_pool() { - let (api, pool, client_mock, tx_api, _) = setup_api(); - - // Start at block 1. - let block_1_header = api.push_block(1, vec![], true); - - let uxt = uxt(Alice, ALICE_NONCE); - let xt = hex_string(&uxt.encode()); - - let operation_id: String = - tx_api.call("transaction_unstable_broadcast", rpc_params![&xt]).await.unwrap(); - - // Announce block 1 to `transaction_unstable_broadcast`. - client_mock.trigger_import_stream(block_1_header).await; - - // Ensure the tx propagated from `transaction_unstable_broadcast` to the transaction pool. - - // TODO: Improve testability by extending the `transaction_unstable_broadcast` with - // a middleware trait that intercepts the transaction status for testing. - let mut num_retries = 12; - while num_retries > 0 && pool.status().ready != 1 { - tokio::time::sleep(Duration::from_secs(5)).await; - num_retries -= 1; - } - assert_eq!(1, pool.status().ready); - assert_eq!(uxt.encode().len(), pool.status().ready_bytes); - - // Import block 2 with the transaction included. - let block_2_header = api.push_block(2, vec![uxt.clone()], true); - let block_2 = block_2_header.hash(); - - // Announce block 2 to the pool. - let event = ChainEvent::NewBestBlock { hash: block_2, tree_route: None }; - pool.maintain(event).await; - - assert_eq!(0, pool.status().ready); - - // Stop call can still be made. - let _: () = tx_api - .call("transaction_unstable_stop", rpc_params![&operation_id]) - .await - .unwrap(); -} - -#[tokio::test] -async fn tx_broadcast_invalid_tx() { - let (_, pool, _, tx_api, mut exec_recv) = setup_api(); - - // Invalid parameters. - let err = tx_api - .call::<_, serde_json::Value>("transaction_unstable_broadcast", [1u8]) - .await - .unwrap_err(); - assert_matches!(err, - Error::JsonRpc(err) if err.code() == super::error::json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid params" - ); - - assert_eq!(0, pool.status().ready); - - // Invalid transaction that cannot be decoded. The broadcast silently exits. - let xt = "0xdeadbeef"; - let operation_id: String = - tx_api.call("transaction_unstable_broadcast", rpc_params![&xt]).await.unwrap(); - - assert_eq!(0, pool.status().ready); - - // Await the broadcast future to exit. - // Without this we'd be subject to races, where we try to call the stop before the tx is - // dropped. - exec_recv.recv().await.unwrap(); - - // The broadcast future was dropped, and the operation is no longer active. - // When the operation is not active, either from the tx being finalized or a - // terminal error; the stop method should return an error. - let err = tx_api - .call::<_, serde_json::Value>("transaction_unstable_stop", rpc_params![&operation_id]) - .await - .unwrap_err(); - assert_matches!(err, - Error::JsonRpc(err) if err.code() == super::error::json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid operation id" - ); -} - -#[tokio::test] -async fn tx_invalid_stop() { - let (_, _, _, tx_api, _) = setup_api(); - - // Make an invalid stop call. - let err = tx_api - .call::<_, serde_json::Value>("transaction_unstable_stop", ["invalid_operation_id"]) - .await - .unwrap_err(); - assert_matches!(err, - Error::JsonRpc(err) if err.code() == super::error::json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid operation id" - ); -} diff --git a/substrate/client/rpc-spec-v2/src/transaction/tests/executor.rs b/substrate/client/rpc-spec-v2/src/transaction/tests/executor.rs new file mode 100644 index 00000000000..ff9aca79887 --- /dev/null +++ b/substrate/client/rpc-spec-v2/src/transaction/tests/executor.rs @@ -0,0 +1,100 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use sp_core::{testing::TaskExecutor, traits::SpawnNamed}; +use std::sync::{atomic::AtomicUsize, Arc}; +use tokio::sync::mpsc; + +/// Wrap the `TaskExecutor` to know when the broadcast future is dropped. +#[derive(Clone)] +pub struct TaskExecutorBroadcast { + executor: TaskExecutor, + sender: mpsc::UnboundedSender<()>, + num_tasks: Arc, +} + +/// The channel that receives events when the broadcast futures are dropped. +pub type TaskExecutorRecv = mpsc::UnboundedReceiver<()>; + +/// The state of the `TaskExecutorBroadcast`. +pub struct TaskExecutorState { + pub recv: TaskExecutorRecv, + pub num_tasks: Arc, +} + +impl TaskExecutorState { + pub fn num_tasks(&self) -> usize { + self.num_tasks.load(std::sync::atomic::Ordering::Acquire) + } +} + +impl TaskExecutorBroadcast { + /// Construct a new `TaskExecutorBroadcast` and a receiver to know when the broadcast futures + /// are dropped. + pub fn new() -> (Self, TaskExecutorState) { + let (sender, recv) = mpsc::unbounded_channel(); + let num_tasks = Arc::new(AtomicUsize::new(0)); + + ( + Self { executor: TaskExecutor::new(), sender, num_tasks: num_tasks.clone() }, + TaskExecutorState { recv, num_tasks }, + ) + } +} + +impl SpawnNamed for TaskExecutorBroadcast { + fn spawn( + &self, + name: &'static str, + group: Option<&'static str>, + future: futures::future::BoxFuture<'static, ()>, + ) { + let sender = self.sender.clone(); + let num_tasks = self.num_tasks.clone(); + + let future = Box::pin(async move { + num_tasks.fetch_add(1, std::sync::atomic::Ordering::AcqRel); + future.await; + num_tasks.fetch_sub(1, std::sync::atomic::Ordering::AcqRel); + + let _ = sender.send(()); + }); + + self.executor.spawn(name, group, future) + } + + fn spawn_blocking( + &self, + name: &'static str, + group: Option<&'static str>, + future: futures::future::BoxFuture<'static, ()>, + ) { + let sender = self.sender.clone(); + let num_tasks = self.num_tasks.clone(); + + let future = Box::pin(async move { + num_tasks.fetch_add(1, std::sync::atomic::Ordering::AcqRel); + future.await; + num_tasks.fetch_sub(1, std::sync::atomic::Ordering::AcqRel); + + let _ = sender.send(()); + }); + + self.executor.spawn_blocking(name, group, future) + } +} diff --git a/substrate/client/rpc-spec-v2/src/transaction/tests/middleware_pool.rs b/substrate/client/rpc-spec-v2/src/transaction/tests/middleware_pool.rs new file mode 100644 index 00000000000..aa8ac572dec --- /dev/null +++ b/substrate/client/rpc-spec-v2/src/transaction/tests/middleware_pool.rs @@ -0,0 +1,187 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use codec::Encode; +use futures::Future; +use sc_transaction_pool::BasicPool; +use sc_transaction_pool_api::{ + ImportNotificationStream, PoolFuture, PoolStatus, ReadyTransactions, TransactionFor, + TransactionPool, TransactionSource, TransactionStatusStreamFor, TxHash, +}; + +use crate::hex_string; +use futures::{FutureExt, StreamExt}; + +use sp_runtime::traits::{Block as BlockT, NumberFor}; +use std::{collections::HashMap, pin::Pin, sync::Arc}; +use substrate_test_runtime_transaction_pool::TestApi; +use tokio::sync::mpsc; + +pub type Block = substrate_test_runtime_client::runtime::Block; + +pub type TxTestPool = MiddlewarePool; +pub type TxStatusType = sc_transaction_pool_api::TransactionStatus< + sc_transaction_pool_api::TxHash, + sc_transaction_pool_api::BlockHash, +>; +pub type TxStatusTypeTest = TxStatusType; + +/// The type of the event that the middleware captures. +#[derive(Debug, PartialEq)] +pub enum MiddlewarePoolEvent { + TransactionStatus { + transaction: String, + status: sc_transaction_pool_api::TransactionStatus< + ::Hash, + ::Hash, + >, + }, + PoolError { + transaction: String, + err: String, + }, +} + +/// The channel that receives events when the broadcast futures are dropped. +pub type MiddlewarePoolRecv = mpsc::UnboundedReceiver; + +/// Add a middleware to the transaction pool. +/// +/// This wraps the `submit_and_watch` to gain access to the events. +pub struct MiddlewarePool { + pub inner_pool: Arc>, + /// Send the middleware events to the test. + sender: mpsc::UnboundedSender, +} + +impl MiddlewarePool { + /// Construct a new [`MiddlewarePool`]. + pub fn new(pool: Arc>) -> (Self, MiddlewarePoolRecv) { + let (sender, recv) = mpsc::unbounded_channel(); + (MiddlewarePool { inner_pool: pool, sender }, recv) + } +} + +impl TransactionPool for MiddlewarePool { + type Block = as TransactionPool>::Block; + type Hash = as TransactionPool>::Hash; + type InPoolTransaction = as TransactionPool>::InPoolTransaction; + type Error = as TransactionPool>::Error; + + fn submit_at( + &self, + at: ::Hash, + source: TransactionSource, + xts: Vec>, + ) -> PoolFuture, Self::Error>>, Self::Error> { + self.inner_pool.submit_at(at, source, xts) + } + + fn submit_one( + &self, + at: ::Hash, + source: TransactionSource, + xt: TransactionFor, + ) -> PoolFuture, Self::Error> { + self.inner_pool.submit_one(at, source, xt) + } + + fn submit_and_watch( + &self, + at: ::Hash, + source: TransactionSource, + xt: TransactionFor, + ) -> PoolFuture>>, Self::Error> { + let pool = self.inner_pool.clone(); + let sender = self.sender.clone(); + let transaction = hex_string(&xt.encode()); + + async move { + let watcher = match pool.submit_and_watch(at, source, xt).await { + Ok(watcher) => watcher, + Err(err) => { + let _ = sender.send(MiddlewarePoolEvent::PoolError { + transaction: transaction.clone(), + err: err.to_string(), + }); + return Err(err); + }, + }; + + let watcher = watcher.map(move |status| { + let sender = sender.clone(); + let transaction = transaction.clone(); + + let _ = sender.send(MiddlewarePoolEvent::TransactionStatus { + transaction, + status: status.clone(), + }); + + status + }); + + Ok(watcher.boxed()) + } + .boxed() + } + + fn remove_invalid(&self, hashes: &[TxHash]) -> Vec> { + self.inner_pool.remove_invalid(hashes) + } + + fn status(&self) -> PoolStatus { + self.inner_pool.status() + } + + fn import_notification_stream(&self) -> ImportNotificationStream> { + self.inner_pool.import_notification_stream() + } + + fn hash_of(&self, xt: &TransactionFor) -> TxHash { + self.inner_pool.hash_of(xt) + } + + fn on_broadcasted(&self, propagations: HashMap, Vec>) { + self.inner_pool.on_broadcasted(propagations) + } + + fn ready_transaction(&self, hash: &TxHash) -> Option> { + self.inner_pool.ready_transaction(hash) + } + + fn ready_at( + &self, + at: NumberFor, + ) -> Pin< + Box< + dyn Future< + Output = Box> + Send>, + > + Send, + >, + > { + self.inner_pool.ready_at(at) + } + + fn ready(&self) -> Box> + Send> { + self.inner_pool.ready() + } + + fn futures(&self) -> Vec { + self.inner_pool.futures() + } +} diff --git a/substrate/client/rpc-spec-v2/src/transaction/tests/mod.rs b/substrate/client/rpc-spec-v2/src/transaction/tests/mod.rs new file mode 100644 index 00000000000..ab0caaf906f --- /dev/null +++ b/substrate/client/rpc-spec-v2/src/transaction/tests/mod.rs @@ -0,0 +1,24 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +mod executor; +mod middleware_pool; +#[macro_use] +mod setup; + +mod transaction_broadcast_tests; diff --git a/substrate/client/rpc-spec-v2/src/transaction/tests/setup.rs b/substrate/client/rpc-spec-v2/src/transaction/tests/setup.rs new file mode 100644 index 00000000000..04ee7b9b4c9 --- /dev/null +++ b/substrate/client/rpc-spec-v2/src/transaction/tests/setup.rs @@ -0,0 +1,120 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use crate::{ + chain_head::test_utils::ChainHeadMockClient, + transaction::{ + api::TransactionBroadcastApiServer, + tests::executor::{TaskExecutorBroadcast, TaskExecutorState}, + TransactionBroadcast as RpcTransactionBroadcast, + }, +}; +use futures::Future; +use jsonrpsee::RpcModule; +use sc_transaction_pool::*; +use std::{pin::Pin, sync::Arc}; +use substrate_test_runtime_client::{prelude::*, Client}; +use substrate_test_runtime_transaction_pool::TestApi; + +use crate::transaction::tests::middleware_pool::{MiddlewarePool, MiddlewarePoolRecv}; + +pub type Block = substrate_test_runtime_client::runtime::Block; + +/// Initial Alice account nonce. +pub const ALICE_NONCE: u64 = 209; + +fn create_basic_pool_with_genesis( + test_api: Arc, + options: Options, +) -> (BasicPool, Pin + Send>>) { + let genesis_hash = { + test_api + .chain() + .read() + .block_by_number + .get(&0) + .map(|blocks| blocks[0].0.header.hash()) + .expect("there is block 0. qed") + }; + BasicPool::new_test(test_api, genesis_hash, genesis_hash, options) +} + +fn maintained_pool( + options: Options, +) -> (BasicPool, Arc, futures::executor::ThreadPool) { + let api = Arc::new(TestApi::with_alice_nonce(ALICE_NONCE)); + let (pool, background_task) = create_basic_pool_with_genesis(api.clone(), options); + + let thread_pool = futures::executor::ThreadPool::new().unwrap(); + thread_pool.spawn_ok(background_task); + (pool, api, thread_pool) +} + +pub fn setup_api( + options: Options, +) -> ( + Arc, + Arc, + Arc>>, + RpcModule>>>, + TaskExecutorState, + MiddlewarePoolRecv, +) { + let (pool, api, _) = maintained_pool(options); + let (pool, pool_state) = MiddlewarePool::new(Arc::new(pool).clone()); + let pool = Arc::new(pool); + + let builder = TestClientBuilder::new(); + let client = Arc::new(builder.build()); + let client_mock = Arc::new(ChainHeadMockClient::new(client.clone())); + + let (task_executor, executor_recv) = TaskExecutorBroadcast::new(); + + let tx_api = + RpcTransactionBroadcast::new(client_mock.clone(), pool.clone(), Arc::new(task_executor)) + .into_rpc(); + + (api, pool, client_mock, tx_api, executor_recv, pool_state) +} + +/// Get the next event from the provided middleware in at most 5 seconds. +macro_rules! get_next_event { + ($middleware:expr) => { + tokio::time::timeout(std::time::Duration::from_secs(5), $middleware.recv()) + .await + .unwrap() + .unwrap() + }; +} + +/// Collect the next number of transaction events from the provided middleware. +macro_rules! get_next_tx_events { + ($middleware:expr, $num:expr) => {{ + let mut events = std::collections::HashMap::new(); + for _ in 0..$num { + let event = get_next_event!($middleware); + match event { + crate::transaction::tests::middleware_pool::MiddlewarePoolEvent::TransactionStatus { transaction, status } => { + events.entry(transaction).or_insert_with(|| vec![]).push(status); + }, + other => panic!("Expected TransactionStatus, received {:?}", other), + }; + } + events + }}; +} diff --git a/substrate/client/rpc-spec-v2/src/transaction/tests/transaction_broadcast_tests.rs b/substrate/client/rpc-spec-v2/src/transaction/tests/transaction_broadcast_tests.rs new file mode 100644 index 00000000000..690a1a64d74 --- /dev/null +++ b/substrate/client/rpc-spec-v2/src/transaction/tests/transaction_broadcast_tests.rs @@ -0,0 +1,523 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use crate::{hex_string, transaction::error::json_rpc_spec}; +use assert_matches::assert_matches; +use codec::Encode; +use jsonrpsee::{rpc_params, MethodsError as Error}; +use sc_transaction_pool::{Options, PoolLimit}; +use sc_transaction_pool_api::{ChainEvent, MaintainedTransactionPool, TransactionPool}; +use std::sync::Arc; +use substrate_test_runtime_client::AccountKeyring::*; +use substrate_test_runtime_transaction_pool::uxt; + +// Test helpers. +use crate::transaction::tests::{ + middleware_pool::{MiddlewarePoolEvent, TxStatusTypeTest}, + setup::{setup_api, ALICE_NONCE}, +}; + +#[tokio::test] +async fn tx_broadcast_enters_pool() { + let (api, pool, client_mock, tx_api, mut exec_middleware, mut pool_middleware) = + setup_api(Default::default()); + + // Start at block 1. + let block_1_header = api.push_block(1, vec![], true); + + let uxt = uxt(Alice, ALICE_NONCE); + let xt = hex_string(&uxt.encode()); + + let operation_id: String = + tx_api.call("transaction_unstable_broadcast", rpc_params![&xt]).await.unwrap(); + + // Announce block 1 to `transaction_unstable_broadcast`. + client_mock.trigger_import_stream(block_1_header).await; + + // Ensure the tx propagated from `transaction_unstable_broadcast` to the transaction pool. + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::Ready + } + ); + + assert_eq!(1, pool.inner_pool.status().ready); + assert_eq!(uxt.encode().len(), pool.inner_pool.status().ready_bytes); + + // Import block 2 with the transaction included. + let block_2_header = api.push_block(2, vec![uxt.clone()], true); + let block_2 = block_2_header.hash(); + + // Announce block 2 to the pool. + let event = ChainEvent::NewBestBlock { hash: block_2, tree_route: None }; + pool.inner_pool.maintain(event).await; + assert_eq!(0, pool.inner_pool.status().ready); + + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::InBlock((block_2, 0)) + } + ); + + // The future broadcast awaits for the finalized status to be reached. + // Force the future to exit by calling stop. + let _: () = tx_api + .call("transaction_unstable_stop", rpc_params![&operation_id]) + .await + .unwrap(); + + // Ensure the broadcast future finishes. + let _ = get_next_event!(&mut exec_middleware.recv); + assert_eq!(0, exec_middleware.num_tasks()); +} + +#[tokio::test] +async fn tx_broadcast_invalid_tx() { + let (_, pool, _, tx_api, mut exec_middleware, _) = setup_api(Default::default()); + + // Invalid parameters. + let err = tx_api + .call::<_, serde_json::Value>("transaction_unstable_broadcast", [1u8]) + .await + .unwrap_err(); + assert_matches!(err, + Error::JsonRpc(err) if err.code() == json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid params" + ); + + assert_eq!(0, pool.status().ready); + + // Invalid transaction that cannot be decoded. The broadcast silently exits. + let xt = "0xdeadbeef"; + let operation_id: String = + tx_api.call("transaction_unstable_broadcast", rpc_params![&xt]).await.unwrap(); + + assert_eq!(0, pool.status().ready); + + // Await the broadcast future to exit. + // Without this we'd be subject to races, where we try to call the stop before the tx is + // dropped. + let _ = get_next_event!(&mut exec_middleware.recv); + assert_eq!(0, exec_middleware.num_tasks()); + + // The broadcast future was dropped, and the operation is no longer active. + // When the operation is not active, either from the tx being finalized or a + // terminal error; the stop method should return an error. + let err = tx_api + .call::<_, serde_json::Value>("transaction_unstable_stop", rpc_params![&operation_id]) + .await + .unwrap_err(); + assert_matches!(err, + Error::JsonRpc(err) if err.code() == json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid operation id" + ); +} + +#[tokio::test] +async fn tx_stop_with_invalid_operation_id() { + let (_, _, _, tx_api, _, _) = setup_api(Default::default()); + + // Make an invalid stop call. + let err = tx_api + .call::<_, serde_json::Value>("transaction_unstable_stop", ["invalid_operation_id"]) + .await + .unwrap_err(); + assert_matches!(err, + Error::JsonRpc(err) if err.code() == json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid operation id" + ); +} + +#[tokio::test] +async fn tx_broadcast_resubmits_future_nonce_tx() { + let (api, pool, client_mock, tx_api, mut exec_middleware, mut pool_middleware) = + setup_api(Default::default()); + + // Start at block 1. + let block_1_header = api.push_block(1, vec![], true); + let block_1 = block_1_header.hash(); + + let current_uxt = uxt(Alice, ALICE_NONCE); + let current_xt = hex_string(¤t_uxt.encode()); + // This lives in the future. + let future_uxt = uxt(Alice, ALICE_NONCE + 1); + let future_xt = hex_string(&future_uxt.encode()); + + let future_operation_id: String = tx_api + .call("transaction_unstable_broadcast", rpc_params![&future_xt]) + .await + .unwrap(); + + // Announce block 1 to `transaction_unstable_broadcast`. + client_mock.trigger_import_stream(block_1_header).await; + + // Ensure the tx propagated from `transaction_unstable_broadcast` to the transaction pool. + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: future_xt.clone(), + status: TxStatusTypeTest::Future + } + ); + + let event = ChainEvent::NewBestBlock { hash: block_1, tree_route: None }; + pool.inner_pool.maintain(event).await; + assert_eq!(0, pool.inner_pool.status().ready); + // Ensure the tx is in the future. + assert_eq!(1, pool.inner_pool.status().future); + + let block_2_header = api.push_block(2, vec![], true); + let block_2 = block_2_header.hash(); + + let operation_id: String = tx_api + .call("transaction_unstable_broadcast", rpc_params![¤t_xt]) + .await + .unwrap(); + assert_ne!(future_operation_id, operation_id); + + // Announce block 2 to `transaction_unstable_broadcast`. + client_mock.trigger_import_stream(block_2_header).await; + + // Collect the events of both transactions. + let events = get_next_tx_events!(&mut pool_middleware, 2); + // Transactions entered the ready queue. + assert_eq!(events.get(¤t_xt).unwrap(), &vec![TxStatusTypeTest::Ready]); + assert_eq!(events.get(&future_xt).unwrap(), &vec![TxStatusTypeTest::Ready]); + + let event = ChainEvent::NewBestBlock { hash: block_2, tree_route: None }; + pool.inner_pool.maintain(event).await; + assert_eq!(2, pool.inner_pool.status().ready); + assert_eq!(0, pool.inner_pool.status().future); + + // Finalize transactions. + let block_3_header = api.push_block(3, vec![current_uxt, future_uxt], true); + let block_3 = block_3_header.hash(); + client_mock.trigger_import_stream(block_3_header).await; + + let event = ChainEvent::Finalized { hash: block_3, tree_route: Arc::from(vec![]) }; + pool.inner_pool.maintain(event).await; + assert_eq!(0, pool.inner_pool.status().ready); + assert_eq!(0, pool.inner_pool.status().future); + + let events = get_next_tx_events!(&mut pool_middleware, 4); + assert_eq!( + events.get(¤t_xt).unwrap(), + &vec![TxStatusTypeTest::InBlock((block_3, 0)), TxStatusTypeTest::Finalized((block_3, 0))] + ); + assert_eq!( + events.get(&future_xt).unwrap(), + &vec![TxStatusTypeTest::InBlock((block_3, 1)), TxStatusTypeTest::Finalized((block_3, 1))] + ); + + // Both broadcast futures must exit. + let _ = get_next_event!(&mut exec_middleware.recv); + let _ = get_next_event!(&mut exec_middleware.recv); + assert_eq!(0, exec_middleware.num_tasks()); +} + +/// This test is similar to `tx_broadcast_enters_pool` +/// However the last block is announced as finalized to force the +/// broadcast future to exit before the `stop` is called. +#[tokio::test] +async fn tx_broadcast_stop_after_broadcast_finishes() { + let (api, pool, client_mock, tx_api, mut exec_middleware, mut pool_middleware) = + setup_api(Default::default()); + + // Start at block 1. + let block_1_header = api.push_block(1, vec![], true); + + let uxt = uxt(Alice, ALICE_NONCE); + let xt = hex_string(&uxt.encode()); + + let operation_id: String = + tx_api.call("transaction_unstable_broadcast", rpc_params![&xt]).await.unwrap(); + + // Announce block 1 to `transaction_unstable_broadcast`. + client_mock.trigger_import_stream(block_1_header).await; + + // Ensure the tx propagated from `transaction_unstable_broadcast` to the transaction + // pool.inner_pool. + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::Ready + } + ); + + assert_eq!(1, pool.inner_pool.status().ready); + assert_eq!(uxt.encode().len(), pool.inner_pool.status().ready_bytes); + + // Import block 2 with the transaction included. + let block_2_header = api.push_block(2, vec![uxt.clone()], true); + let block_2 = block_2_header.hash(); + + // Announce block 2 to the pool.inner_pool. + let event = ChainEvent::Finalized { hash: block_2, tree_route: Arc::from(vec![]) }; + pool.inner_pool.maintain(event).await; + + assert_eq!(0, pool.inner_pool.status().ready); + + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::InBlock((block_2, 0)) + } + ); + + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::Finalized((block_2, 0)) + } + ); + + // Ensure the broadcast future terminated properly. + let _ = get_next_event!(&mut exec_middleware.recv); + assert_eq!(0, exec_middleware.num_tasks()); + + // The operation ID is no longer valid, check that the broadcast future + // cleared out the inner state of the operation. + let err = tx_api + .call::<_, serde_json::Value>("transaction_unstable_stop", rpc_params![&operation_id]) + .await + .unwrap_err(); + assert_matches!(err, + Error::JsonRpc(err) if err.code() == json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid operation id" + ); +} + +#[tokio::test] +async fn tx_broadcast_resubmits_invalid_tx() { + let limits = PoolLimit { count: 8192, total_bytes: 20 * 1024 * 1024 }; + let options = Options { + ready: limits.clone(), + future: limits, + reject_future_transactions: false, + // This ensures that a transaction is not banned. + ban_time: std::time::Duration::ZERO, + }; + + let (api, pool, client_mock, tx_api, mut exec_middleware, mut pool_middleware) = + setup_api(options); + + let uxt = uxt(Alice, ALICE_NONCE); + let xt = hex_string(&uxt.encode()); + let _operation_id: String = + tx_api.call("transaction_unstable_broadcast", rpc_params![&xt]).await.unwrap(); + + let block_1_header = api.push_block(1, vec![], true); + let block_1 = block_1_header.hash(); + // Announce block 1 to `transaction_unstable_broadcast`. + client_mock.trigger_import_stream(block_1_header).await; + + // Ensure the tx propagated from `transaction_unstable_broadcast` to the transaction pool. + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::Ready, + } + ); + assert_eq!(1, pool.inner_pool.status().ready); + assert_eq!(uxt.encode().len(), pool.inner_pool.status().ready_bytes); + + // Mark the transaction as invalid from the API, causing a temporary ban. + api.add_invalid(&uxt); + + // Push an event to the pool to ensure the transaction is excluded. + let event = ChainEvent::NewBestBlock { hash: block_1, tree_route: None }; + pool.inner_pool.maintain(event).await; + assert_eq!(1, pool.inner_pool.status().ready); + + // Ensure the `transaction_unstable_broadcast` is aware of the invalid transaction. + let event = get_next_event!(&mut pool_middleware); + // Because we have received an `Invalid` status, we try to broadcast the transaction with the + // next announced block. + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::Invalid + } + ); + + // Import block 2. + let block_2_header = api.push_block(2, vec![], true); + client_mock.trigger_import_stream(block_2_header).await; + + // Ensure we propagate the temporary ban error to `submit_and_watch`. + // This ensures we'll loop again with the next annmounced block and try to resubmit the + // transaction. The transaction remains temporarily banned until the pool is maintained. + let event = get_next_event!(&mut pool_middleware); + assert_matches!(event, MiddlewarePoolEvent::PoolError { transaction, err } if transaction == xt && err.contains("Transaction temporarily Banned")); + + // Import block 3. + let block_3_header = api.push_block(3, vec![], true); + let block_3 = block_3_header.hash(); + // Remove the invalid transaction from the pool to allow it to pass through. + api.remove_invalid(&uxt); + let event = ChainEvent::NewBestBlock { hash: block_3, tree_route: None }; + // We have to maintain the pool to ensure the transaction is no longer invalid. + // This clears out the banned transactions. + pool.inner_pool.maintain(event).await; + assert_eq!(0, pool.inner_pool.status().ready); + + // Announce block to `transaction_unstable_broadcast`. + client_mock.trigger_import_stream(block_3_header).await; + + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::Ready, + } + ); + assert_eq!(1, pool.inner_pool.status().ready); + + let block_4_header = api.push_block(4, vec![uxt], true); + let block_4 = block_4_header.hash(); + let event = ChainEvent::Finalized { hash: block_4, tree_route: Arc::from(vec![]) }; + pool.inner_pool.maintain(event).await; + + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::InBlock((block_4, 0)), + } + ); + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::Finalized((block_4, 0)), + } + ); + + // Ensure the broadcast future terminated properly. + let _ = get_next_event!(&mut exec_middleware.recv); + assert_eq!(0, exec_middleware.num_tasks()); +} + +/// This is similar to `tx_broadcast_resubmits_invalid_tx`. +/// However, it forces the tx to be resubmited because of the pool +/// limits. Which is a different code path than the invalid tx. +#[tokio::test] +async fn tx_broadcast_resubmits_dropped_tx() { + let limits = PoolLimit { count: 1, total_bytes: 1000 }; + let options = Options { + ready: limits.clone(), + future: limits, + reject_future_transactions: false, + // This ensures that a transaction is not banned. + ban_time: std::time::Duration::ZERO, + }; + + let (api, pool, client_mock, tx_api, _, mut pool_middleware) = setup_api(options); + + let current_uxt = uxt(Alice, ALICE_NONCE); + let current_xt = hex_string(¤t_uxt.encode()); + // This lives in the future. + let future_uxt = uxt(Alice, ALICE_NONCE + 1); + let future_xt = hex_string(&future_uxt.encode()); + + // By default the `validate_transaction` mock uses priority 1 for + // transactions. Bump the priority to ensure other transactions + // are immediately dropped. + api.set_priority(¤t_uxt, 10); + + let current_operation_id: String = tx_api + .call("transaction_unstable_broadcast", rpc_params![¤t_xt]) + .await + .unwrap(); + + // Announce block 1 to `transaction_unstable_broadcast`. + let block_1_header = api.push_block(1, vec![], true); + let event = + ChainEvent::Finalized { hash: block_1_header.hash(), tree_route: Arc::from(vec![]) }; + pool.inner_pool.maintain(event).await; + client_mock.trigger_import_stream(block_1_header).await; + + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: current_xt.clone(), + status: TxStatusTypeTest::Ready, + } + ); + assert_eq!(1, pool.inner_pool.status().ready); + + // The future tx has priority 2, smaller than the current 10. + api.set_priority(&future_uxt, 2); + let future_operation_id: String = tx_api + .call("transaction_unstable_broadcast", rpc_params![&future_xt]) + .await + .unwrap(); + assert_ne!(current_operation_id, future_operation_id); + + let block_2_header = api.push_block(2, vec![], true); + let event = + ChainEvent::Finalized { hash: block_2_header.hash(), tree_route: Arc::from(vec![]) }; + pool.inner_pool.maintain(event).await; + client_mock.trigger_import_stream(block_2_header).await; + + // We must have at most 1 transaction in the pool, as per limits above. + assert_eq!(1, pool.inner_pool.status().ready); + + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::PoolError { + transaction: future_xt.clone(), + err: "Transaction couldn't enter the pool because of the limit".into() + } + ); + + let block_3_header = api.push_block(3, vec![current_uxt], true); + let event = + ChainEvent::Finalized { hash: block_3_header.hash(), tree_route: Arc::from(vec![]) }; + pool.inner_pool.maintain(event).await; + client_mock.trigger_import_stream(block_3_header.clone()).await; + + // The first tx is in a finalzied block; the future tx must enter the pool. + let events = get_next_tx_events!(&mut pool_middleware, 3); + assert_eq!( + events.get(¤t_xt).unwrap(), + &vec![ + TxStatusTypeTest::InBlock((block_3_header.hash(), 0)), + TxStatusTypeTest::Finalized((block_3_header.hash(), 0)) + ] + ); + // The dropped transaction was resubmitted. + assert_eq!(events.get(&future_xt).unwrap(), &vec![TxStatusTypeTest::Ready]); +} diff --git a/substrate/client/transaction-pool/src/lib.rs b/substrate/client/transaction-pool/src/lib.rs index faa3f455a58..64b301e6bf3 100644 --- a/substrate/client/transaction-pool/src/lib.rs +++ b/substrate/client/transaction-pool/src/lib.rs @@ -164,8 +164,9 @@ where pool_api: Arc, best_block_hash: Block::Hash, finalized_hash: Block::Hash, + options: graph::Options, ) -> (Self, Pin + Send>>) { - let pool = Arc::new(graph::Pool::new(Default::default(), true.into(), pool_api.clone())); + let pool = Arc::new(graph::Pool::new(options, true.into(), pool_api.clone())); let (revalidation_queue, background_task) = revalidation::RevalidationQueue::new_background( pool_api.clone(), pool.clone(), diff --git a/substrate/client/transaction-pool/tests/pool.rs b/substrate/client/transaction-pool/tests/pool.rs index 6b1a197440c..461b9860d41 100644 --- a/substrate/client/transaction-pool/tests/pool.rs +++ b/substrate/client/transaction-pool/tests/pool.rs @@ -73,7 +73,7 @@ fn create_basic_pool_with_genesis( .map(|blocks| blocks[0].0.header.hash()) .expect("there is block 0. qed") }; - BasicPool::new_test(test_api, genesis_hash, genesis_hash) + BasicPool::new_test(test_api, genesis_hash, genesis_hash, Default::default()) } fn create_basic_pool(test_api: TestApi) -> BasicPool { @@ -994,6 +994,7 @@ fn import_notification_to_pool_maintain_works() { )), best_hash, finalized_hash, + Default::default(), ) .0, ); diff --git a/substrate/test-utils/runtime/transaction-pool/src/lib.rs b/substrate/test-utils/runtime/transaction-pool/src/lib.rs index 8c8345b06bd..5202e6e6515 100644 --- a/substrate/test-utils/runtime/transaction-pool/src/lib.rs +++ b/substrate/test-utils/runtime/transaction-pool/src/lib.rs @@ -81,6 +81,7 @@ pub struct ChainState { pub block_by_hash: HashMap, pub nonces: HashMap, pub invalid_hashes: HashSet, + pub priorities: HashMap, } /// Test Api for transaction pool. @@ -214,6 +215,22 @@ impl TestApi { self.chain.write().invalid_hashes.insert(Self::hash_and_length_inner(xts).0); } + /// Remove a transaction that was previously declared as invalid via `[Self::add_invalid]`. + /// + /// Next time transaction pool will try to validate this + /// extrinsic, api will succeed. + pub fn remove_invalid(&self, xts: &Extrinsic) { + self.chain.write().invalid_hashes.remove(&Self::hash_and_length_inner(xts).0); + } + + /// Set a transaction priority. + pub fn set_priority(&self, xts: &Extrinsic, priority: u64) { + self.chain + .write() + .priorities + .insert(Self::hash_and_length_inner(xts).0, priority); + } + /// Query validation requests received. pub fn validation_requests(&self) -> Vec { self.validation_requests.read().clone() @@ -300,8 +317,14 @@ impl ChainApi for TestApi { return ready(Ok(Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(0))))) } - let mut validity = - ValidTransaction { priority: 1, requires, provides, longevity: 64, propagate: true }; + let priority = self.chain.read().priorities.get(&self.hash_and_length(&uxt).0).cloned(); + let mut validity = ValidTransaction { + priority: priority.unwrap_or(1), + requires, + provides, + longevity: 64, + propagate: true, + }; (self.valid_modifier.read())(&mut validity); -- GitLab From f4eedcebafa4d2addb8b71ba31ab1bc579ba3c4a Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Wed, 28 Feb 2024 13:13:27 +0100 Subject: [PATCH 319/392] [prdoc] Optional SemVer bumps and Docs (#3441) Changes: - Add an optional `bump` field to the crates in a prdoc. - Explain the cargo semver interpretation for <1 versions in the release doc. --------- Signed-off-by: Oliver Tale-Yazdi --- docs/RELEASE.md | 12 +++++++++--- prdoc/schema_user.json | 33 +++++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/docs/RELEASE.md b/docs/RELEASE.md index 6d681d78f36..e73be2779a9 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -18,10 +18,16 @@ Rococo. To easily refer to a release, it shall be named by its date in the form ## Crate -We try to follow [SemVer 2.0.0](https://semver.org/) as best as possible for versioning our crates. SemVer requires a -piece of software to first declare a public API. The public API of the Polkadot SDK is hereby declared as the sum of all -crates' public APIs. +We try to follow [SemVer 2.0.0](https://semver.org/) as best as possible for versioning our crates. The definitions of +`major`, `minor` and `patch` version for Rust crates are slightly altered from their standard for pre `1.0.0` versions. +Quoting [rust-lang.org](https://doc.rust-lang.org/cargo/reference/semver.html): +>Initial development releases starting with “0.y.z” can treat changes in “y” as a major release, and “z” as a minor +release. “0.0.z” releases are always major changes. This is because Cargo uses the convention that only changes in the +left-most non-zero component are considered incompatible. + +SemVer requires a piece of software to first declare a public API. The public API of the Polkadot SDK +is hereby declared as the sum of all crates' public APIs. Inductively, the public API of our library crates is declared as all public items that are neither: - Inside a `__private` module diff --git a/prdoc/schema_user.json b/prdoc/schema_user.json index 82215d51866..1bd0b3b93ee 100644 --- a/prdoc/schema_user.json +++ b/prdoc/schema_user.json @@ -3,9 +3,8 @@ "$id": "https://raw.githubusercontent.com/paritytech/prdoc/master/prdoc_schema_user.json", "version": { "major": 1, - "minor": 0, - "patch": 0, - "timestamp": 20230817152351 + "minor": 1, + "patch": 0 }, "title": "Polkadot SDK PRDoc Schema", "description": "JSON Schema definition for the Polkadot SDK PR documentation", @@ -125,10 +124,16 @@ "name": { "type": "string" }, + "bump": { + "$ref": "#/$defs/semver_bump" + }, "note": { "type": "string" } - } + }, + "required": [ + "name" + ] }, "migration_db": { "type": "object", @@ -165,6 +170,26 @@ "description" ] }, + "semver_bump": { + "description": "The type of bump to apply to the crate version according to Cargo SemVer: https://doc.rust-lang.org/cargo/reference/semver.html. Please check docs/RELEASE.md for more information.", + "oneOf": [ + { + "const": "major", + "title": "Major", + "description": "A bump to the leftmost non-zero digit of the version number." + }, + { + "const": "minor", + "title": "Minor", + "description": "A bump to the second leftmost non-zero digit of the version number." + }, + { + "const": "patch", + "title": "Patch", + "description": "A bump to the third leftmost non-zero digit of the version number." + } + ] + }, "doc": { "type": "object", "description": "You have the the option to provide different description of your PR for different audiences.", -- GitLab From 14530269b7a76f50dc939bf57b1e3d38270b662b Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Wed, 28 Feb 2024 13:07:14 +0000 Subject: [PATCH 320/392] Add documentation around FRAME Offchain workers (#3463) - deprecation companion: https://github.com/substrate-developer-hub/substrate-docs/pull/2136 - inspired by https://substrate.stackexchange.com/questions/11058/how-can-i-create-ocw-that-wont-activates-every-block-but-will-activates-only-w/11060#11060 --------- Co-authored-by: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> --- Cargo.lock | 2 + docs/sdk/Cargo.toml | 5 +- .../reference_docs/frame_offchain_workers.rs | 115 ++++++++++++++++++ docs/sdk/src/reference_docs/mod.rs | 4 + substrate/frame/support/src/traits/hooks.rs | 2 +- 5 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 docs/sdk/src/reference_docs/frame_offchain_workers.rs diff --git a/Cargo.lock b/Cargo.lock index 026786378d5..ef510986257 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13416,6 +13416,7 @@ dependencies = [ "pallet-collective", "pallet-default-config-example", "pallet-democracy", + "pallet-example-offchain-worker", "pallet-example-single-block-migrations", "pallet-examples", "pallet-multisig", @@ -13442,6 +13443,7 @@ dependencies = [ "sp-core", "sp-io", "sp-keyring", + "sp-offchain", "sp-runtime", "sp-version", "staging-chain-spec-builder", diff --git a/docs/sdk/Cargo.toml b/docs/sdk/Cargo.toml index b1b60a2d77d..735b3d7df61 100644 --- a/docs/sdk/Cargo.toml +++ b/docs/sdk/Cargo.toml @@ -23,6 +23,7 @@ frame = { path = "../../substrate/frame", features = [ ] } pallet-examples = { path = "../../substrate/frame/examples" } pallet-default-config-example = { path = "../../substrate/frame/examples/default-config" } +pallet-example-offchain-worker = { path = "../../substrate/frame/examples/offchain-worker" } # How we build docs in rust-docs simple-mermaid = "0.1.1" @@ -38,7 +39,7 @@ frame-support = { path = "../../substrate/frame/support", default-features = fal frame-executive = { path = "../../substrate/frame/executive", default-features = false } pallet-example-single-block-migrations = { path = "../../substrate/frame/examples/single-block-migrations" } -# Substrate +# Substrate Client sc-network = { path = "../../substrate/client/network" } sc-rpc-api = { path = "../../substrate/client/rpc-api" } sc-rpc = { path = "../../substrate/client/rpc" } @@ -50,6 +51,7 @@ sc-consensus-grandpa = { path = "../../substrate/client/consensus/grandpa" } sc-consensus-beefy = { path = "../../substrate/client/consensus/beefy" } sc-consensus-manual-seal = { path = "../../substrate/client/consensus/manual-seal" } sc-consensus-pow = { path = "../../substrate/client/consensus/pow" } + substrate-wasm-builder = { path = "../../substrate/utils/wasm-builder" } # Cumulus @@ -78,6 +80,7 @@ sp-api = { path = "../../substrate/primitives/api" } sp-core = { path = "../../substrate/primitives/core" } sp-keyring = { path = "../../substrate/primitives/keyring" } sp-runtime = { path = "../../substrate/primitives/runtime" } +sp-offchain = { path = "../../substrate/primitives/offchain" } sp-version = { path = "../../substrate/primitives/version" } # XCM diff --git a/docs/sdk/src/reference_docs/frame_offchain_workers.rs b/docs/sdk/src/reference_docs/frame_offchain_workers.rs new file mode 100644 index 00000000000..7999707e5ee --- /dev/null +++ b/docs/sdk/src/reference_docs/frame_offchain_workers.rs @@ -0,0 +1,115 @@ +//! # Offchain Workers +//! +//! This reference document explains how offchain workers work in Substrate and FRAME. The main +//! focus is upon FRAME's implementation of this functionality. Nonetheless, offchain workers are a +//! Substrate-provided feature and can be used with possible alternatives to [`frame`] as well. +//! +//! Offchain workers are a commonly misunderstood topic, therefore we explain them bottom-up, +//! starting at the fundamentals and then describing the developer interface. +//! +//! ## Context +//! +//! Recall from [`crate::reference_docs::wasm_meta_protocol`] that the node and the runtime +//! communicate with one another via host functions and runtime APIs. Many of these interactions +//! contribute to the actual state transition of the blockchain. For example [`sp_api::Core`] is the +//! main runtime API that is called to execute new blocks. +//! +//! Offchain workers are in principle not different in any way: It is a runtime API exposed by the +//! wasm blob ([`sp_offchain::OffchainWorkerApi`]), and the node software calls into it when it +//! deems fit. But, crucially, this API call is different in that: +//! +//! 1. It can have no impact on the state ie. it is _OFF (the) CHAIN_. If any state is altered +//! during the execution of this API call, it is discarded. +//! 2. It has access to an extended set of host functions that allow the wasm blob to do more. For +//! example, call into HTTP requests. +//! +//! > The main way through which an offchain worker can interact with the state is by submitting an +//! > extrinsic to the chain. This is the ONLY way to alter the state from an offchain worker. +//! > [`pallet_example_offchain_worker`] provides an example of this. +//! +//! +//! Given the "Off Chain" nature of this API, it is important to remember that calling this API is +//! entirely optional. Some nodes might call into it, some might not, and it would have no impact on +//! the execution of your blockchain because no state is altered no matter the execution of the +//! offchain worker API. +//! +//! Substrate's CLI allows some degree of configuration about this, allowing node operators to +//! specify when they want to run the offchain worker API. See +//! [`sc_cli::RunCmd::offchain_worker_params`]. +//! +//! ## Nondeterministic Execution +//! +//! Needless to say, given the above description, the code in your offchain worker API can be +//! nondeterministic, as it is not part of the blockchain's STF, so it can be executed at unknown +//! times, by unknown nodes, and has no impact on the state. This is why an HTTP +//! ([`sp_runtime::offchain::http`]) API is readily provided to the offchain worker APIs. Because +//! there is no need for determinism in this context. +//! +//! > A common mistake here is for novice developers to see this HTTP API, and imagine that +//! > `polkadot-sdk` somehow magically solved the determinism in blockchains, and now a blockchain +//! > can make HTTP calls and it will all work. This is absolutely NOT the case. An HTTP call made +//! > by the offchain worker is non-deterministic by design. Blockchains can't and always won't be +//! > able to perform non-deterministic operations such as making HTTP calls to a foreign server. +//! +//! ## FRAME's API +//! +//! [`frame`] provides a simple API through which pallets can define offchain worker functions. This +//! is part of [`frame::traits::Hooks`], which is implemented as a part of +//! [`frame::pallet_macros::hooks`]. +//! +//! ``` +//! +//! #[frame::pallet] +//! pub mod pallet { +//! use frame::prelude::*; +//! +//! #[pallet::config] +//! pub trait Config: frame_system::Config {} +//! +//! #[pallet::pallet] +//! pub struct Pallet(_); +//! +//! #[pallet::hooks] +//! impl Hooks> for Pallet { +//! fn offchain_worker(block_number: BlockNumberFor) { +//! // ... +//! } +//! } +//! } +//! ``` +//! +//! Additionally, [`sp_runtime::offchain`] provides a set of utilities that can be used to moderate +//! the execution of offchain workers. +//! +//! ## Think Twice: Why Use Substrate's Offchain Workers? +//! +//! Consider the fact that in principle, an offchain worker code written using the above API is no +//! different than an equivalent written with an _actual offchain interaction library_, such as +//! [Polkadot-JS](https://polkadot.js.org/docs/), or any of the other ones listed [here](https://github.com/substrate-developer-hub/awesome-substrate?tab=readme-ov-file#client-libraries). +//! +//! They can both read from the state, and have no means of updating the state, other than the route +//! of submitting an extrinsic to the chain. Therefore, it is worth thinking twice before embedding +//! a logic as a part of Substrate's offchain worker API. Does it have to be there? can it not be a +//! simple, actual offchain application that lives outside of the chain's WASM blob? +//! +//! Some of the reasons why you might want to do the opposite, and actually embed an offchain worker +//! API into the WASM blob are: +//! +//! * Accessing the state is easier within the `offchain_worker` function, as it is already a part +//! of the runtime, and [`frame::pallet_macros::storage`] provides all the tools needed to read +//! the state. Other client libraries might provide varying degrees of capability here. +//! * It will be updated in synchrony with the runtime. A Substrate's offchain application is part +//! of the same WASM blob, and is therefore guaranteed to be up to date. +//! +//! For example, imagine you have modified a storage item to have a new type. This will possibly +//! require a [`crate::reference_docs::frame_runtime_upgrades_and_migrations`], and any offchain +//! code, such as a Polkadot-JS application, will have to be updated to reflect this change. Whereas +//! the WASM offchain worker code is guaranteed to already be updated, or else the runtime code will +//! not even compile. +//! +//! +//! ## Further References +//! +//! - +//! - +//! - [Offchain worker example](https://github.com/paritytech/polkadot-sdk/tree/master/substrate/frame/examples/offchain-worker) diff --git a/docs/sdk/src/reference_docs/mod.rs b/docs/sdk/src/reference_docs/mod.rs index b2c751420ce..0bd204e4b6a 100644 --- a/docs/sdk/src/reference_docs/mod.rs +++ b/docs/sdk/src/reference_docs/mod.rs @@ -99,3 +99,7 @@ pub mod frame_runtime_upgrades_and_migrations; /// light-node-first out of the box. // TODO: @jsdw @josepot https://github.com/paritytech/polkadot-sdk-docs/issues/68 pub mod light_nodes; + +/// Learn about the offchain workers, how they function, and how to use them, as provided by the +/// [`frame`] APIs. +pub mod frame_offchain_workers; diff --git a/substrate/frame/support/src/traits/hooks.rs b/substrate/frame/support/src/traits/hooks.rs index 72f047c3a73..c37fb0f54bc 100644 --- a/substrate/frame/support/src/traits/hooks.rs +++ b/substrate/frame/support/src/traits/hooks.rs @@ -446,7 +446,7 @@ pub trait Hooks { } /// Implementing this function on a pallet allows you to perform long-running tasks that are - /// dispatched as separate threads, and entirely independent of the main wasm runtime. + /// dispatched as separate threads, and entirely independent of the main blockchain execution. /// /// This function can freely read from the state, but any change it makes to the state is /// meaningless. Writes can be pushed back to the chain by submitting extrinsics from the -- GitLab From 426136671a42ff759127b4a7a71eac6335744675 Mon Sep 17 00:00:00 2001 From: maksimryndin Date: Wed, 28 Feb 2024 17:29:27 +0100 Subject: [PATCH 321/392] PVF: re-preparing artifact on failed runtime construction (#3187) resolve https://github.com/paritytech/polkadot-sdk/issues/3139 - [x] use a distinguishable error for `execute_artifact` - [x] remove artifact in case of a `RuntimeConstruction` error during the execution - [x] augment the `validate_candidate_with_retry` of `ValidationBackend` with the case of retriable `RuntimeConstruction` error during the execution - [x] update the book (https://paritytech.github.io/polkadot-sdk/book/node/utility/pvf-host-and-workers.html#retrying-execution-requests) - [x] add a test - [x] run zombienet tests --------- Co-authored-by: s0me0ne-unkn0wn <48632512+s0me0ne-unkn0wn@users.noreply.github.com> --- .../node/core/candidate-validation/src/lib.rs | 53 +++++++----- polkadot/node/core/pvf/common/src/error.rs | 1 + polkadot/node/core/pvf/common/src/execute.rs | 15 ++++ .../core/pvf/common/src/executor_interface.rs | 4 +- .../node/core/pvf/execute-worker/src/lib.rs | 10 ++- polkadot/node/core/pvf/src/artifacts.rs | 8 ++ polkadot/node/core/pvf/src/error.rs | 4 + polkadot/node/core/pvf/src/execute/mod.rs | 2 +- polkadot/node/core/pvf/src/execute/queue.rs | 68 ++++++++++++--- .../core/pvf/src/execute/worker_interface.rs | 8 ++ polkadot/node/core/pvf/src/host.rs | 53 +++++++++++- polkadot/node/core/pvf/tests/it/main.rs | 83 +++++++++++++++++-- polkadot/primitives/src/v6/executor_params.rs | 10 +-- .../src/node/utility/pvf-host-and-workers.md | 8 ++ prdoc/pr_3187.prdoc | 16 ++++ 15 files changed, 294 insertions(+), 49 deletions(-) create mode 100644 prdoc/pr_3187.prdoc diff --git a/polkadot/node/core/candidate-validation/src/lib.rs b/polkadot/node/core/candidate-validation/src/lib.rs index bf6e09fd1b6..8237137fdca 100644 --- a/polkadot/node/core/candidate-validation/src/lib.rs +++ b/polkadot/node/core/candidate-validation/src/lib.rs @@ -695,6 +695,8 @@ async fn validate_candidate_exhaustive( ))), Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::JobError(err))) => Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(err))), + Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::RuntimeConstruction(err))) => + Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(err))), Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::AmbiguousJobDeath(err))) => Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(format!( @@ -780,40 +782,50 @@ trait ValidationBackend { return validation_result } + macro_rules! break_if_no_retries_left { + ($counter:ident) => { + if $counter > 0 { + $counter -= 1; + } else { + break + } + }; + } + // Allow limited retries for each kind of error. let mut num_death_retries_left = 1; let mut num_job_error_retries_left = 1; let mut num_internal_retries_left = 1; + let mut num_runtime_construction_retries_left = 1; loop { // Stop retrying if we exceeded the timeout. if total_time_start.elapsed() + retry_delay > exec_timeout { break } - + let mut retry_immediately = false; match validation_result { Err(ValidationError::PossiblyInvalid( PossiblyInvalidError::AmbiguousWorkerDeath | PossiblyInvalidError::AmbiguousJobDeath(_), - )) => - if num_death_retries_left > 0 { - num_death_retries_left -= 1; - } else { - break - }, + )) => break_if_no_retries_left!(num_death_retries_left), Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::JobError(_))) => - if num_job_error_retries_left > 0 { - num_job_error_retries_left -= 1; - } else { - break - }, + break_if_no_retries_left!(num_job_error_retries_left), Err(ValidationError::Internal(_)) => - if num_internal_retries_left > 0 { - num_internal_retries_left -= 1; - } else { - break - }, + break_if_no_retries_left!(num_internal_retries_left), + + Err(ValidationError::PossiblyInvalid( + PossiblyInvalidError::RuntimeConstruction(_), + )) => { + break_if_no_retries_left!(num_runtime_construction_retries_left); + self.precheck_pvf(pvf.clone()).await?; + // In this case the error is deterministic + // And a retry forces the ValidationBackend + // to re-prepare the artifact so + // there is no need to wait before the retry + retry_immediately = true; + }, Ok(_) | Err(ValidationError::Invalid(_) | ValidationError::Preparation(_)) => break, } @@ -821,8 +833,11 @@ trait ValidationBackend { // If we got a possibly transient error, retry once after a brief delay, on the // assumption that the conditions that caused this error may have resolved on their own. { - // Wait a brief delay before retrying. - futures_timer::Delay::new(retry_delay).await; + // In case of many transient errors it is necessary to wait a little bit + // for the error to be probably resolved + if !retry_immediately { + futures_timer::Delay::new(retry_delay).await; + } let new_timeout = exec_timeout.saturating_sub(total_time_start.elapsed()); diff --git a/polkadot/node/core/pvf/common/src/error.rs b/polkadot/node/core/pvf/common/src/error.rs index f8faefc24e6..cf274044456 100644 --- a/polkadot/node/core/pvf/common/src/error.rs +++ b/polkadot/node/core/pvf/common/src/error.rs @@ -16,6 +16,7 @@ use crate::prepare::{PrepareSuccess, PrepareWorkerSuccess}; use parity_scale_codec::{Decode, Encode}; +pub use sc_executor_common::error::Error as ExecuteError; /// Result of PVF preparation from a worker, with checksum of the compiled PVF and stats of the /// preparation if successful. diff --git a/polkadot/node/core/pvf/common/src/execute.rs b/polkadot/node/core/pvf/common/src/execute.rs index 6b3becf524d..18c97b03cbc 100644 --- a/polkadot/node/core/pvf/common/src/execute.rs +++ b/polkadot/node/core/pvf/common/src/execute.rs @@ -40,6 +40,9 @@ pub enum WorkerResponse { }, /// The candidate is invalid. InvalidCandidate(String), + /// Instantiation of the WASM module instance failed during an execution. + /// Possibly related to local issues or dirty node update. May be retried with re-preparation. + RuntimeConstruction(String), /// The job timed out. JobTimedOut, /// The job process has died. We must kill the worker just in case. @@ -68,6 +71,9 @@ pub enum JobResponse { /// The result of parachain validation. result_descriptor: ValidationResult, }, + /// A possibly transient runtime instantiation error happened during the execution; may be + /// retried with re-preparation + RuntimeConstruction(String), /// The candidate is invalid. InvalidCandidate(String), } @@ -81,6 +87,15 @@ impl JobResponse { Self::InvalidCandidate(format!("{}: {}", ctx, msg)) } } + + /// Creates a may retry response from a context `ctx` and a message `msg` (which can be empty). + pub fn runtime_construction(ctx: &'static str, msg: &str) -> Self { + if msg.is_empty() { + Self::RuntimeConstruction(ctx.to_string()) + } else { + Self::RuntimeConstruction(format!("{}: {}", ctx, msg)) + } + } } /// An unexpected error occurred in the execution job process. Because this comes from the job, diff --git a/polkadot/node/core/pvf/common/src/executor_interface.rs b/polkadot/node/core/pvf/common/src/executor_interface.rs index 4cd2f5c85ee..b69a87890f6 100644 --- a/polkadot/node/core/pvf/common/src/executor_interface.rs +++ b/polkadot/node/core/pvf/common/src/executor_interface.rs @@ -16,6 +16,7 @@ //! Interface to the Substrate Executor +use crate::error::ExecuteError; use polkadot_primitives::{ executor_params::{DEFAULT_LOGICAL_STACK_MAX, DEFAULT_NATIVE_STACK_MAX}, ExecutorParam, ExecutorParams, @@ -109,7 +110,7 @@ pub unsafe fn execute_artifact( compiled_artifact_blob: &[u8], executor_params: &ExecutorParams, params: &[u8], -) -> Result, String> { +) -> Result, ExecuteError> { let mut extensions = sp_externalities::Extensions::new(); extensions.register(sp_core::traits::ReadRuntimeVersionExt::new(ReadRuntimeVersion)); @@ -123,7 +124,6 @@ pub unsafe fn execute_artifact( Ok(Ok(ok)) => Ok(ok), Ok(Err(err)) | Err(err) => Err(err), } - .map_err(|err| format!("execute error: {:?}", err)) } /// Constructs the runtime for the given PVF, given the artifact bytes. diff --git a/polkadot/node/core/pvf/execute-worker/src/lib.rs b/polkadot/node/core/pvf/execute-worker/src/lib.rs index 0cfa5a78694..bd7e76010a6 100644 --- a/polkadot/node/core/pvf/execute-worker/src/lib.rs +++ b/polkadot/node/core/pvf/execute-worker/src/lib.rs @@ -16,7 +16,9 @@ //! Contains the logic for executing PVFs. Used by the polkadot-execute-worker binary. -pub use polkadot_node_core_pvf_common::executor_interface::execute_artifact; +pub use polkadot_node_core_pvf_common::{ + error::ExecuteError, executor_interface::execute_artifact, +}; // NOTE: Initializing logging in e.g. tests will not have an effect in the workers, as they are // separate spawned processes. Run with e.g. `RUST_LOG=parachain::pvf-execute-worker=trace`. @@ -237,7 +239,9 @@ fn validate_using_artifact( // [`executor_interface::prepare`]. execute_artifact(compiled_artifact_blob, executor_params, params) } { - Err(err) => return JobResponse::format_invalid("execute", &err), + Err(ExecuteError::RuntimeConstruction(wasmerr)) => + return JobResponse::runtime_construction("execute", &wasmerr.to_string()), + Err(err) => return JobResponse::format_invalid("execute", &err.to_string()), Ok(d) => d, }; @@ -550,6 +554,8 @@ fn handle_parent_process( Ok(WorkerResponse::Ok { result_descriptor, duration: cpu_tv }) }, Ok(JobResponse::InvalidCandidate(err)) => Ok(WorkerResponse::InvalidCandidate(err)), + Ok(JobResponse::RuntimeConstruction(err)) => + Ok(WorkerResponse::RuntimeConstruction(err)), Err(job_error) => { gum::warn!( target: LOG_TARGET, diff --git a/polkadot/node/core/pvf/src/artifacts.rs b/polkadot/node/core/pvf/src/artifacts.rs index 78dfe71adad..6288755526d 100644 --- a/polkadot/node/core/pvf/src/artifacts.rs +++ b/polkadot/node/core/pvf/src/artifacts.rs @@ -238,6 +238,14 @@ impl Artifacts { .is_none()); } + /// Remove artifact by its id. + pub fn remove(&mut self, artifact_id: ArtifactId) -> Option<(ArtifactId, PathBuf)> { + self.inner.remove(&artifact_id).and_then(|state| match state { + ArtifactState::Prepared { path, .. } => Some((artifact_id, path)), + _ => None, + }) + } + /// Remove artifacts older than the given TTL and return id and path of the removed ones. pub fn prune(&mut self, artifact_ttl: Duration) -> Vec<(ArtifactId, PathBuf)> { let now = SystemTime::now(); diff --git a/polkadot/node/core/pvf/src/error.rs b/polkadot/node/core/pvf/src/error.rs index 80d41d5c64b..8dc96305ead 100644 --- a/polkadot/node/core/pvf/src/error.rs +++ b/polkadot/node/core/pvf/src/error.rs @@ -86,6 +86,10 @@ pub enum PossiblyInvalidError { /// vote invalid. #[error("possibly invalid: job error: {0}")] JobError(String), + /// Instantiation of the WASM module instance failed during an execution. + /// Possibly related to local issues or dirty node update. May be retried with re-preparation. + #[error("possibly invalid: runtime construction: {0}")] + RuntimeConstruction(String), } impl From for ValidationError { diff --git a/polkadot/node/core/pvf/src/execute/mod.rs b/polkadot/node/core/pvf/src/execute/mod.rs index c6d9cf90fa2..365e98196ca 100644 --- a/polkadot/node/core/pvf/src/execute/mod.rs +++ b/polkadot/node/core/pvf/src/execute/mod.rs @@ -23,4 +23,4 @@ mod queue; mod worker_interface; -pub use queue::{start, PendingExecutionRequest, ToQueue}; +pub use queue::{start, FromQueue, PendingExecutionRequest, ToQueue}; diff --git a/polkadot/node/core/pvf/src/execute/queue.rs b/polkadot/node/core/pvf/src/execute/queue.rs index aa91d11781f..bdc3c7327b0 100644 --- a/polkadot/node/core/pvf/src/execute/queue.rs +++ b/polkadot/node/core/pvf/src/execute/queue.rs @@ -25,7 +25,7 @@ use crate::{ InvalidCandidate, PossiblyInvalidError, ValidationError, LOG_TARGET, }; use futures::{ - channel::mpsc, + channel::{mpsc, oneshot}, future::BoxFuture, stream::{FuturesUnordered, StreamExt as _}, Future, FutureExt, @@ -54,6 +54,12 @@ pub enum ToQueue { Enqueue { artifact: ArtifactPathId, pending_execution_request: PendingExecutionRequest }, } +/// A response from queue. +#[derive(Debug)] +pub enum FromQueue { + RemoveArtifact { artifact: ArtifactId, reply_to: oneshot::Sender<()> }, +} + /// An execution request that should execute the PVF (known in the context) and send the results /// to the given result sender. #[derive(Debug)] @@ -137,6 +143,8 @@ struct Queue { /// The receiver that receives messages to the pool. to_queue_rx: mpsc::Receiver, + /// The sender to send messages back to validation host. + from_queue_tx: mpsc::UnboundedSender, // Some variables related to the current session. program_path: PathBuf, @@ -161,6 +169,7 @@ impl Queue { node_version: Option, security_status: SecurityStatus, to_queue_rx: mpsc::Receiver, + from_queue_tx: mpsc::UnboundedSender, ) -> Self { Self { metrics, @@ -170,6 +179,7 @@ impl Queue { node_version, security_status, to_queue_rx, + from_queue_tx, queue: VecDeque::new(), mux: Mux::new(), workers: Workers { @@ -301,7 +311,7 @@ async fn handle_mux(queue: &mut Queue, event: QueueEvent) { handle_worker_spawned(queue, idle, handle, job); }, QueueEvent::StartWork(worker, outcome, artifact_id, result_tx) => { - handle_job_finish(queue, worker, outcome, artifact_id, result_tx); + handle_job_finish(queue, worker, outcome, artifact_id, result_tx).await; }, } } @@ -327,42 +337,69 @@ fn handle_worker_spawned( /// If there are pending jobs in the queue, schedules the next of them onto the just freed up /// worker. Otherwise, puts back into the available workers list. -fn handle_job_finish( +async fn handle_job_finish( queue: &mut Queue, worker: Worker, outcome: Outcome, artifact_id: ArtifactId, result_tx: ResultSender, ) { - let (idle_worker, result, duration) = match outcome { + let (idle_worker, result, duration, sync_channel) = match outcome { Outcome::Ok { result_descriptor, duration, idle_worker } => { // TODO: propagate the soft timeout - (Some(idle_worker), Ok(result_descriptor), Some(duration)) + (Some(idle_worker), Ok(result_descriptor), Some(duration), None) }, Outcome::InvalidCandidate { err, idle_worker } => ( Some(idle_worker), Err(ValidationError::Invalid(InvalidCandidate::WorkerReportedInvalid(err))), None, + None, ), - Outcome::InternalError { err } => (None, Err(ValidationError::Internal(err)), None), + Outcome::RuntimeConstruction { err, idle_worker } => { + // The task for artifact removal is executed concurrently with + // the message to the host on the execution result. + let (result_tx, result_rx) = oneshot::channel(); + queue + .from_queue_tx + .unbounded_send(FromQueue::RemoveArtifact { + artifact: artifact_id.clone(), + reply_to: result_tx, + }) + .expect("from execute queue receiver is listened by the host; qed"); + ( + Some(idle_worker), + Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::RuntimeConstruction( + err, + ))), + None, + Some(result_rx), + ) + }, + Outcome::InternalError { err } => (None, Err(ValidationError::Internal(err)), None, None), // Either the worker or the job timed out. Kill the worker in either case. Treated as // definitely-invalid, because if we timed out, there's no time left for a retry. Outcome::HardTimeout => - (None, Err(ValidationError::Invalid(InvalidCandidate::HardTimeout)), None), + (None, Err(ValidationError::Invalid(InvalidCandidate::HardTimeout)), None, None), // "Maybe invalid" errors (will retry). Outcome::WorkerIntfErr => ( None, Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::AmbiguousWorkerDeath)), None, + None, ), Outcome::JobDied { err } => ( None, Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::AmbiguousJobDeath(err))), None, + None, + ), + Outcome::JobError { err } => ( + None, + Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::JobError(err))), + None, + None, ), - Outcome::JobError { err } => - (None, Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::JobError(err))), None), }; queue.metrics.execute_finished(); @@ -386,6 +423,12 @@ fn handle_job_finish( ); } + if let Some(sync_channel) = sync_channel { + // err means the sender is dropped (the artifact is already removed from the cache) + // so that's legitimate to ignore the result + let _ = sync_channel.await; + } + // First we send the result. It may fail due to the other end of the channel being dropped, // that's legitimate and we don't treat that as an error. let _ = result_tx.send(result); @@ -521,8 +564,10 @@ pub fn start( spawn_timeout: Duration, node_version: Option, security_status: SecurityStatus, -) -> (mpsc::Sender, impl Future) { +) -> (mpsc::Sender, mpsc::UnboundedReceiver, impl Future) { let (to_queue_tx, to_queue_rx) = mpsc::channel(20); + let (from_queue_tx, from_queue_rx) = mpsc::unbounded(); + let run = Queue::new( metrics, program_path, @@ -532,7 +577,8 @@ pub fn start( node_version, security_status, to_queue_rx, + from_queue_tx, ) .run(); - (to_queue_tx, run) + (to_queue_tx, from_queue_rx, run) } diff --git a/polkadot/node/core/pvf/src/execute/worker_interface.rs b/polkadot/node/core/pvf/src/execute/worker_interface.rs index 9f7738f00e6..db81da118d7 100644 --- a/polkadot/node/core/pvf/src/execute/worker_interface.rs +++ b/polkadot/node/core/pvf/src/execute/worker_interface.rs @@ -87,6 +87,10 @@ pub enum Outcome { /// a trap. Errors related to the preparation process are not expected to be encountered by the /// execution workers. InvalidCandidate { err: String, idle_worker: IdleWorker }, + /// The error is probably transient. It may be for example + /// because the artifact was prepared with a Wasmtime version different from the version + /// in the current execution environment. + RuntimeConstruction { err: String, idle_worker: IdleWorker }, /// The execution time exceeded the hard limit. The worker is terminated. HardTimeout, /// An I/O error happened during communication with the worker. This may mean that the worker @@ -193,6 +197,10 @@ pub async fn start_work( err, idle_worker: IdleWorker { stream, pid, worker_dir }, }, + WorkerResponse::RuntimeConstruction(err) => Outcome::RuntimeConstruction { + err, + idle_worker: IdleWorker { stream, pid, worker_dir }, + }, WorkerResponse::JobTimedOut => Outcome::HardTimeout, WorkerResponse::JobDied { err, job_pid: _ } => Outcome::JobDied { err }, WorkerResponse::JobError(err) => Outcome::JobError { err }, diff --git a/polkadot/node/core/pvf/src/host.rs b/polkadot/node/core/pvf/src/host.rs index ae9fdc7d2de..8ec46f4b08f 100644 --- a/polkadot/node/core/pvf/src/host.rs +++ b/polkadot/node/core/pvf/src/host.rs @@ -274,7 +274,7 @@ pub async fn start( from_prepare_pool, ); - let (to_execute_queue_tx, run_execute_queue) = execute::start( + let (to_execute_queue_tx, from_execute_queue_rx, run_execute_queue) = execute::start( metrics, config.execute_worker_program_path.to_owned(), config.cache_path.clone(), @@ -296,6 +296,7 @@ pub async fn start( to_prepare_queue_tx, from_prepare_queue_rx, to_execute_queue_tx, + from_execute_queue_rx, to_sweeper_tx, awaiting_prepare: AwaitingPrepare::default(), }) @@ -342,6 +343,8 @@ struct Inner { from_prepare_queue_rx: mpsc::UnboundedReceiver, to_execute_queue_tx: mpsc::Sender, + from_execute_queue_rx: mpsc::UnboundedReceiver, + to_sweeper_tx: mpsc::Sender, awaiting_prepare: AwaitingPrepare, @@ -358,6 +361,7 @@ async fn run( to_host_rx, from_prepare_queue_rx, mut to_prepare_queue_tx, + from_execute_queue_rx, mut to_execute_queue_tx, mut to_sweeper_tx, mut awaiting_prepare, @@ -384,10 +388,21 @@ async fn run( let mut to_host_rx = to_host_rx.fuse(); let mut from_prepare_queue_rx = from_prepare_queue_rx.fuse(); + let mut from_execute_queue_rx = from_execute_queue_rx.fuse(); loop { // biased to make it behave deterministically for tests. futures::select_biased! { + from_execute_queue_rx = from_execute_queue_rx.next() => { + let from_queue = break_if_fatal!(from_execute_queue_rx.ok_or(Fatal)); + let execute::FromQueue::RemoveArtifact { artifact, reply_to } = from_queue; + break_if_fatal!(handle_artifact_removal( + &mut to_sweeper_tx, + &mut artifacts, + artifact, + reply_to, + ).await); + }, () = cleanup_pulse.select_next_some() => { // `select_next_some` because we don't expect this to fail, but if it does, we // still don't fail. The trade-off is that the compiled cache will start growing @@ -861,6 +876,37 @@ async fn handle_cleanup_pulse( Ok(()) } +async fn handle_artifact_removal( + sweeper_tx: &mut mpsc::Sender, + artifacts: &mut Artifacts, + artifact_id: ArtifactId, + reply_to: oneshot::Sender<()>, +) -> Result<(), Fatal> { + let (artifact_id, path) = if let Some(artifact) = artifacts.remove(artifact_id) { + artifact + } else { + // if we haven't found the artifact by its id, + // it has been probably removed + // anyway with the randomness of the artifact name + // it is safe to ignore + return Ok(()); + }; + reply_to + .send(()) + .expect("the execute queue waits for the artifact remove confirmation; qed"); + // Thanks to the randomness of the artifact name (see + // `artifacts::generate_artifact_path`) there is no issue with any name conflict on + // future repreparation. + // So we can confirm the artifact removal already + gum::debug!( + target: LOG_TARGET, + validation_code_hash = ?artifact_id.code_hash, + "PVF pruning: pruning artifact by request from the execute queue", + ); + sweeper_tx.send(path).await.map_err(|_| Fatal)?; + Ok(()) +} + /// A simple task which sole purpose is to delete files thrown at it. async fn sweeper_task(mut sweeper_rx: mpsc::Receiver) { loop { @@ -968,6 +1014,8 @@ pub(crate) mod tests { to_prepare_queue_rx: mpsc::Receiver, from_prepare_queue_tx: mpsc::UnboundedSender, to_execute_queue_rx: mpsc::Receiver, + #[allow(unused)] + from_execute_queue_tx: mpsc::UnboundedSender, to_sweeper_rx: mpsc::Receiver, run: BoxFuture<'static, ()>, @@ -979,6 +1027,7 @@ pub(crate) mod tests { let (to_prepare_queue_tx, to_prepare_queue_rx) = mpsc::channel(10); let (from_prepare_queue_tx, from_prepare_queue_rx) = mpsc::unbounded(); let (to_execute_queue_tx, to_execute_queue_rx) = mpsc::channel(10); + let (from_execute_queue_tx, from_execute_queue_rx) = mpsc::unbounded(); let (to_sweeper_tx, to_sweeper_rx) = mpsc::channel(10); let run = run(Inner { @@ -989,6 +1038,7 @@ pub(crate) mod tests { to_prepare_queue_tx, from_prepare_queue_rx, to_execute_queue_tx, + from_execute_queue_rx, to_sweeper_tx, awaiting_prepare: AwaitingPrepare::default(), }) @@ -999,6 +1049,7 @@ pub(crate) mod tests { to_prepare_queue_rx, from_prepare_queue_tx, to_execute_queue_rx, + from_execute_queue_tx, to_sweeper_rx, run, } diff --git a/polkadot/node/core/pvf/tests/it/main.rs b/polkadot/node/core/pvf/tests/it/main.rs index bcc10749e74..cdfbcd8e578 100644 --- a/polkadot/node/core/pvf/tests/it/main.rs +++ b/polkadot/node/core/pvf/tests/it/main.rs @@ -21,13 +21,14 @@ use parity_scale_codec::Encode as _; #[cfg(all(feature = "ci-only-tests", target_os = "linux"))] use polkadot_node_core_pvf::SecurityStatus; use polkadot_node_core_pvf::{ - start, testing::build_workers_and_get_paths, Config, InvalidCandidate, Metrics, PrepareError, - PrepareJobKind, PvfPrepData, ValidationError, ValidationHost, JOB_TIMEOUT_WALL_CLOCK_FACTOR, + start, testing::build_workers_and_get_paths, Config, InvalidCandidate, Metrics, + PossiblyInvalidError, PrepareError, PrepareJobKind, PvfPrepData, ValidationError, + ValidationHost, JOB_TIMEOUT_WALL_CLOCK_FACTOR, }; use polkadot_parachain_primitives::primitives::{BlockData, ValidationParams, ValidationResult}; use polkadot_primitives::{ExecutorParam, ExecutorParams}; -use std::time::Duration; +use std::{io::Write, time::Duration}; use tokio::sync::Mutex; mod adder; @@ -352,10 +353,80 @@ async fn deleting_prepared_artifact_does_not_dispute() { ) .await; - match result { - Err(ValidationError::Invalid(InvalidCandidate::HardTimeout)) => {}, - r => panic!("{:?}", r), + assert_matches!(result, Err(ValidationError::Invalid(InvalidCandidate::HardTimeout))); +} + +// Test that corruption of a prepared artifact does not lead to a dispute when we try to execute it. +#[tokio::test] +async fn corrupted_prepared_artifact_does_not_dispute() { + let host = TestHost::new().await; + let cache_dir = host.cache_dir.path(); + + let _stats = host.precheck_pvf(halt::wasm_binary_unwrap(), Default::default()).await.unwrap(); + + // Manually corrupting the prepared artifact from disk. The in-memory artifacts table won't + // change. + let artifact_path = { + // Get the artifact path (asserting it exists). + let mut cache_dir: Vec<_> = std::fs::read_dir(cache_dir).unwrap().collect(); + // Should contain the artifact and the worker dir. + assert_eq!(cache_dir.len(), 2); + let mut artifact_path = cache_dir.pop().unwrap().unwrap(); + if artifact_path.path().is_dir() { + artifact_path = cache_dir.pop().unwrap().unwrap(); + } + + // Corrupt the artifact. + let mut f = std::fs::OpenOptions::new() + .write(true) + .truncate(true) + .open(artifact_path.path()) + .unwrap(); + f.write_all(b"corrupted wasm").unwrap(); + f.flush().unwrap(); + artifact_path + }; + + assert!(artifact_path.path().exists()); + + // Try to validate, artifact should get removed because of the corruption. + let result = host + .validate_candidate( + halt::wasm_binary_unwrap(), + ValidationParams { + block_data: BlockData(Vec::new()), + parent_head: Default::default(), + relay_parent_number: 1, + relay_parent_storage_root: Default::default(), + }, + Default::default(), + ) + .await; + + assert_matches!( + result, + Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::RuntimeConstruction(_))) + ); + + // because of RuntimeConstruction we may retry + host.precheck_pvf(halt::wasm_binary_unwrap(), Default::default()).await.unwrap(); + + // The actual artifact removal is done concurrently + // with sending of the result of the execution + // it is not a problem for further re-preparation as + // artifact filenames are random + for _ in 1..5 { + if !artifact_path.path().exists() { + break; + } + tokio::time::sleep(Duration::from_secs(1)).await; } + + assert!( + !artifact_path.path().exists(), + "the corrupted artifact ({}) should be deleted by the host", + artifact_path.path().display() + ); } #[tokio::test] diff --git a/polkadot/primitives/src/v6/executor_params.rs b/polkadot/primitives/src/v6/executor_params.rs index 112a529f62b..1e19f3b23fe 100644 --- a/polkadot/primitives/src/v6/executor_params.rs +++ b/polkadot/primitives/src/v6/executor_params.rs @@ -159,7 +159,9 @@ impl sp_std::fmt::LowerHex for ExecutorParamsHash { // into individual fields of the structure. Thus, complex migrations shall be avoided when adding // new entries and removing old ones. At the moment, there's no mandatory parameters defined. If // they show up, they must be clearly documented as mandatory ones. -#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo, Serialize, Deserialize)] +#[derive( + Clone, Debug, Default, Encode, Decode, PartialEq, Eq, TypeInfo, Serialize, Deserialize, +)] pub struct ExecutorParams(Vec); impl ExecutorParams { @@ -334,9 +336,3 @@ impl From<&[ExecutorParam]> for ExecutorParams { ExecutorParams(arr.to_vec()) } } - -impl Default for ExecutorParams { - fn default() -> Self { - ExecutorParams(vec![]) - } -} diff --git a/polkadot/roadmap/implementers-guide/src/node/utility/pvf-host-and-workers.md b/polkadot/roadmap/implementers-guide/src/node/utility/pvf-host-and-workers.md index e0984bd58d1..39a317a07c8 100644 --- a/polkadot/roadmap/implementers-guide/src/node/utility/pvf-host-and-workers.md +++ b/polkadot/roadmap/implementers-guide/src/node/utility/pvf-host-and-workers.md @@ -125,6 +125,14 @@ execution request: reason, which may or may not be independent of the candidate or PVF. 5. **Internal errors:** See "Internal Errors" section. In this case, after the retry we abstain from voting. +6. **RuntimeConstruction** error. The precheck handles a general case of a wrong + artifact but doesn't guarantee its consistency between the preparation and + the execution. If something happened with the artifact between + the preparation of the artifact and its execution (e.g. the artifact was + corrupted on disk or a dirty node upgrade happened when the prepare worker + has a wasmtime version different from the execute worker's wasmtime version). + We treat such an error as possibly transient due to local issues and retry + one time. ### Preparation timeouts diff --git a/prdoc/pr_3187.prdoc b/prdoc/pr_3187.prdoc new file mode 100644 index 00000000000..bda41142d86 --- /dev/null +++ b/prdoc/pr_3187.prdoc @@ -0,0 +1,16 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Retrying an execution on failed runtime construction + +doc: + - audience: Node Dev + description: | + If a runtime construction error happened during the execution request, then the artifact is re-prepared + and the execution request is retried at most once. See also the related issue. + +crates: + - name: polkadot-node-core-candidate-validation + - name: polkadot-node-core-pvf + - name: polkadot-node-core-pvf-execute-worker + - name: polkadot-node-core-pvf-common -- GitLab From 576681b867a234b42aac282940455f9be71d108b Mon Sep 17 00:00:00 2001 From: Clara van Staden Date: Wed, 28 Feb 2024 21:42:35 +0200 Subject: [PATCH 322/392] Snowbridge - Extract Ethereum Chain ID (#3501) While adding runtime tests to https://github.com/polkadot-fellows/runtimes/pull/130, I noticed the Ethereum chain ID was hardcoded. For Kusama + Polkadot, the Ethereum chain ID should 1 (Mainnet), whereas on Rococo it is 11155111 (Sepolia). This PR also updates the Snowbridge crates versions to the current versions on crates.io. --------- Co-authored-by: claravanstaden --- Cargo.lock | 28 +++++++++---------- .../pallets/ethereum-client/Cargo.toml | 2 +- .../pallets/inbound-queue/Cargo.toml | 2 +- .../pallets/inbound-queue/fixtures/Cargo.toml | 2 +- .../pallets/outbound-queue/Cargo.toml | 2 +- .../outbound-queue/merkle-tree/Cargo.toml | 2 +- .../outbound-queue/runtime-api/Cargo.toml | 2 +- bridges/snowbridge/pallets/system/Cargo.toml | 2 +- .../pallets/system/runtime-api/Cargo.toml | 2 +- .../snowbridge/primitives/beacon/Cargo.toml | 2 +- bridges/snowbridge/primitives/core/Cargo.toml | 2 +- .../snowbridge/primitives/ethereum/Cargo.toml | 2 +- .../snowbridge/primitives/router/Cargo.toml | 2 +- .../runtime/runtime-common/Cargo.toml | 2 +- .../snowbridge/runtime/test-common/Cargo.toml | 2 +- .../snowbridge/runtime/test-common/src/lib.rs | 12 ++++++-- .../snowbridge/scripts/contribute-upstream.sh | 2 ++ .../bridge-hub-rococo/tests/snowbridge.rs | 5 ++++ 18 files changed, 45 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ef510986257..197d05e2633 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17856,7 +17856,7 @@ dependencies = [ [[package]] name = "snowbridge-beacon-primitives" -version = "0.0.0" +version = "0.2.0" dependencies = [ "byte-slice-cast", "frame-support", @@ -17880,7 +17880,7 @@ dependencies = [ [[package]] name = "snowbridge-core" -version = "0.0.0" +version = "0.2.0" dependencies = [ "ethabi-decode", "frame-support", @@ -17903,7 +17903,7 @@ dependencies = [ [[package]] name = "snowbridge-ethereum" -version = "0.1.0" +version = "0.3.0" dependencies = [ "ethabi-decode", "ethbloom", @@ -17942,7 +17942,7 @@ dependencies = [ [[package]] name = "snowbridge-outbound-queue-merkle-tree" -version = "0.1.1" +version = "0.3.0" dependencies = [ "array-bytes 4.2.0", "env_logger 0.9.3", @@ -17957,7 +17957,7 @@ dependencies = [ [[package]] name = "snowbridge-outbound-queue-runtime-api" -version = "0.0.0" +version = "0.2.0" dependencies = [ "frame-support", "parity-scale-codec", @@ -17971,7 +17971,7 @@ dependencies = [ [[package]] name = "snowbridge-pallet-ethereum-client" -version = "0.0.0" +version = "0.2.0" dependencies = [ "bp-runtime", "byte-slice-cast", @@ -18017,7 +18017,7 @@ dependencies = [ [[package]] name = "snowbridge-pallet-inbound-queue" -version = "0.0.0" +version = "0.2.0" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -18050,7 +18050,7 @@ dependencies = [ [[package]] name = "snowbridge-pallet-inbound-queue-fixtures" -version = "0.9.0" +version = "0.10.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -18064,7 +18064,7 @@ dependencies = [ [[package]] name = "snowbridge-pallet-outbound-queue" -version = "0.0.0" +version = "0.2.0" dependencies = [ "bridge-hub-common", "ethabi-decode", @@ -18089,7 +18089,7 @@ dependencies = [ [[package]] name = "snowbridge-pallet-system" -version = "0.0.0" +version = "0.2.0" dependencies = [ "ethabi-decode", "frame-benchmarking", @@ -18117,7 +18117,7 @@ dependencies = [ [[package]] name = "snowbridge-router-primitives" -version = "0.0.0" +version = "0.9.0" dependencies = [ "ethabi-decode", "frame-support", @@ -18140,7 +18140,7 @@ dependencies = [ [[package]] name = "snowbridge-runtime-common" -version = "0.0.0" +version = "0.2.0" dependencies = [ "frame-support", "frame-system", @@ -18156,7 +18156,7 @@ dependencies = [ [[package]] name = "snowbridge-runtime-test-common" -version = "0.0.0" +version = "0.2.0" dependencies = [ "assets-common", "bridge-hub-test-utils", @@ -18233,7 +18233,7 @@ dependencies = [ [[package]] name = "snowbridge-system-runtime-api" -version = "0.0.0" +version = "0.2.0" dependencies = [ "parity-scale-codec", "snowbridge-core", diff --git a/bridges/snowbridge/pallets/ethereum-client/Cargo.toml b/bridges/snowbridge/pallets/ethereum-client/Cargo.toml index 99b42905311..c8999633c97 100644 --- a/bridges/snowbridge/pallets/ethereum-client/Cargo.toml +++ b/bridges/snowbridge/pallets/ethereum-client/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-pallet-ethereum-client" description = "Snowbridge Ethereum Client Pallet" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/pallets/inbound-queue/Cargo.toml b/bridges/snowbridge/pallets/inbound-queue/Cargo.toml index c26ef90a22d..b850496cd4e 100644 --- a/bridges/snowbridge/pallets/inbound-queue/Cargo.toml +++ b/bridges/snowbridge/pallets/inbound-queue/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-pallet-inbound-queue" description = "Snowbridge Inbound Queue Pallet" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/pallets/inbound-queue/fixtures/Cargo.toml b/bridges/snowbridge/pallets/inbound-queue/fixtures/Cargo.toml index 61f1421e056..64605a42f0d 100644 --- a/bridges/snowbridge/pallets/inbound-queue/fixtures/Cargo.toml +++ b/bridges/snowbridge/pallets/inbound-queue/fixtures/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-pallet-inbound-queue-fixtures" description = "Snowbridge Inbound Queue Test Fixtures" -version = "0.9.0" +version = "0.10.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/pallets/outbound-queue/Cargo.toml b/bridges/snowbridge/pallets/outbound-queue/Cargo.toml index 40e57db4bbd..f16a28cb1e4 100644 --- a/bridges/snowbridge/pallets/outbound-queue/Cargo.toml +++ b/bridges/snowbridge/pallets/outbound-queue/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-pallet-outbound-queue" description = "Snowbridge Outbound Queue Pallet" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/pallets/outbound-queue/merkle-tree/Cargo.toml b/bridges/snowbridge/pallets/outbound-queue/merkle-tree/Cargo.toml index c185d5af706..0606e9de330 100644 --- a/bridges/snowbridge/pallets/outbound-queue/merkle-tree/Cargo.toml +++ b/bridges/snowbridge/pallets/outbound-queue/merkle-tree/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-outbound-queue-merkle-tree" description = "Snowbridge Outbound Queue Merkle Tree" -version = "0.1.1" +version = "0.3.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/pallets/outbound-queue/runtime-api/Cargo.toml b/bridges/snowbridge/pallets/outbound-queue/runtime-api/Cargo.toml index 347b3bae493..cb68fd0a250 100644 --- a/bridges/snowbridge/pallets/outbound-queue/runtime-api/Cargo.toml +++ b/bridges/snowbridge/pallets/outbound-queue/runtime-api/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-outbound-queue-runtime-api" description = "Snowbridge Outbound Queue Runtime API" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/pallets/system/Cargo.toml b/bridges/snowbridge/pallets/system/Cargo.toml index f6c642e7376..5ad04290de0 100644 --- a/bridges/snowbridge/pallets/system/Cargo.toml +++ b/bridges/snowbridge/pallets/system/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-pallet-system" description = "Snowbridge System Pallet" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/pallets/system/runtime-api/Cargo.toml b/bridges/snowbridge/pallets/system/runtime-api/Cargo.toml index 355d2d29147..eb02ae1db52 100644 --- a/bridges/snowbridge/pallets/system/runtime-api/Cargo.toml +++ b/bridges/snowbridge/pallets/system/runtime-api/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-system-runtime-api" description = "Snowbridge System Runtime API" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/primitives/beacon/Cargo.toml b/bridges/snowbridge/primitives/beacon/Cargo.toml index e021bb01071..d181fa1d394 100644 --- a/bridges/snowbridge/primitives/beacon/Cargo.toml +++ b/bridges/snowbridge/primitives/beacon/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-beacon-primitives" description = "Snowbridge Beacon Primitives" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/primitives/core/Cargo.toml b/bridges/snowbridge/primitives/core/Cargo.toml index 090c48c403f..9a299ad0ae9 100644 --- a/bridges/snowbridge/primitives/core/Cargo.toml +++ b/bridges/snowbridge/primitives/core/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-core" description = "Snowbridge Core" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/primitives/ethereum/Cargo.toml b/bridges/snowbridge/primitives/ethereum/Cargo.toml index 399139cef38..9fa725a6c05 100644 --- a/bridges/snowbridge/primitives/ethereum/Cargo.toml +++ b/bridges/snowbridge/primitives/ethereum/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-ethereum" description = "Snowbridge Ethereum" -version = "0.1.0" +version = "0.3.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/primitives/router/Cargo.toml b/bridges/snowbridge/primitives/router/Cargo.toml index 750a2a73e63..ded773e0d38 100644 --- a/bridges/snowbridge/primitives/router/Cargo.toml +++ b/bridges/snowbridge/primitives/router/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-router-primitives" description = "Snowbridge Router Primitives" -version = "0.0.0" +version = "0.9.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/runtime/runtime-common/Cargo.toml b/bridges/snowbridge/runtime/runtime-common/Cargo.toml index d4c86f8aa75..bf5e9a8832d 100644 --- a/bridges/snowbridge/runtime/runtime-common/Cargo.toml +++ b/bridges/snowbridge/runtime/runtime-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-runtime-common" description = "Snowbridge Runtime Common" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/runtime/test-common/Cargo.toml b/bridges/snowbridge/runtime/test-common/Cargo.toml index ec4466b3426..4e8b311cb97 100644 --- a/bridges/snowbridge/runtime/test-common/Cargo.toml +++ b/bridges/snowbridge/runtime/test-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-runtime-test-common" description = "Snowbridge Runtime Tests" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition = "2021" license = "Apache-2.0" diff --git a/bridges/snowbridge/runtime/test-common/src/lib.rs b/bridges/snowbridge/runtime/test-common/src/lib.rs index 29b0e738c18..7455adf7617 100644 --- a/bridges/snowbridge/runtime/test-common/src/lib.rs +++ b/bridges/snowbridge/runtime/test-common/src/lib.rs @@ -40,6 +40,7 @@ where } pub fn send_transfer_token_message( + ethereum_chain_id: u64, assethub_parachain_id: u32, weth_contract_address: H160, destination_address: H160, @@ -89,7 +90,7 @@ where WithdrawAsset(Assets::from(vec![fee.clone()])), BuyExecution { fees: fee, weight_limit: Unlimited }, ExportMessage { - network: Ethereum { chain_id: 11155111 }, + network: Ethereum { chain_id: ethereum_chain_id }, destination: Here, xcm: inner_xcm, }, @@ -107,6 +108,7 @@ where } pub fn send_transfer_token_message_success( + ethereum_chain_id: u64, collator_session_key: CollatorSessionKeys, runtime_para_id: u32, assethub_parachain_id: u32, @@ -149,6 +151,7 @@ pub fn send_transfer_token_message_success( initial_fund::(assethub_parachain_id, 5_000_000_000_000); let outcome = send_transfer_token_message::( + ethereum_chain_id, assethub_parachain_id, weth_contract_address, destination_address, @@ -205,6 +208,7 @@ pub fn ethereum_outbound_queue_processes_messages_before_message_queue_works< XcmConfig, AllPalletsWithoutSystem, >( + ethereum_chain_id: u64, collator_session_key: CollatorSessionKeys, runtime_para_id: u32, assethub_parachain_id: u32, @@ -249,6 +253,7 @@ pub fn ethereum_outbound_queue_processes_messages_before_message_queue_works< initial_fund::(assethub_parachain_id, 5_000_000_000_000); let outcome = send_transfer_token_message::( + ethereum_chain_id, assethub_parachain_id, weth_contract_address, destination_address, @@ -290,6 +295,7 @@ pub fn ethereum_outbound_queue_processes_messages_before_message_queue_works< } pub fn send_unpaid_transfer_token_message( + ethereum_chain_id: u64, collator_session_key: CollatorSessionKeys, runtime_para_id: u32, assethub_parachain_id: u32, @@ -353,7 +359,7 @@ pub fn send_unpaid_transfer_token_message( let xcm = Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, ExportMessage { - network: Ethereum { chain_id: 11155111 }, + network: Ethereum { chain_id: ethereum_chain_id }, destination: Here, xcm: inner_xcm, }, @@ -375,6 +381,7 @@ pub fn send_unpaid_transfer_token_message( #[allow(clippy::too_many_arguments)] pub fn send_transfer_token_message_failure( + ethereum_chain_id: u64, collator_session_key: CollatorSessionKeys, runtime_para_id: u32, assethub_parachain_id: u32, @@ -414,6 +421,7 @@ pub fn send_transfer_token_message_failure( initial_fund::(assethub_parachain_id, initial_amount); let outcome = send_transfer_token_message::( + ethereum_chain_id, assethub_parachain_id, weth_contract_address, destination_address, diff --git a/bridges/snowbridge/scripts/contribute-upstream.sh b/bridges/snowbridge/scripts/contribute-upstream.sh index 8aa2d2a7035..32005b770ec 100755 --- a/bridges/snowbridge/scripts/contribute-upstream.sh +++ b/bridges/snowbridge/scripts/contribute-upstream.sh @@ -40,10 +40,12 @@ git checkout "$branch_name" # remove everything we think is not required for our needs rm -rf rust-toolchain.toml +rm -rf codecov.yml rm -rf $SNOWBRIDGE_FOLDER/.cargo rm -rf $SNOWBRIDGE_FOLDER/.github rm -rf $SNOWBRIDGE_FOLDER/SECURITY.md rm -rf $SNOWBRIDGE_FOLDER/.gitignore +rm -rf $SNOWBRIDGE_FOLDER/rustfmt.toml rm -rf $SNOWBRIDGE_FOLDER/templates rm -rf $SNOWBRIDGE_FOLDER/pallets/ethereum-client/fuzz diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs index b9f43624b65..239bd946e75 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs @@ -51,6 +51,7 @@ fn collator_session_keys() -> bridge_hub_test_utils::CollatorSessionKeys( + 11155111, collator_session_keys(), 1013, 1000, @@ -69,6 +70,7 @@ pub fn transfer_token_to_ethereum_works() { #[test] pub fn unpaid_transfer_token_to_ethereum_fails_with_barrier() { snowbridge_runtime_test_common::send_unpaid_transfer_token_message::( + 11155111, collator_session_keys(), 1013, 1000, @@ -80,6 +82,7 @@ pub fn unpaid_transfer_token_to_ethereum_fails_with_barrier() { #[test] pub fn transfer_token_to_ethereum_fee_not_enough() { snowbridge_runtime_test_common::send_transfer_token_message_failure::( + 11155111, collator_session_keys(), 1013, 1000, @@ -95,6 +98,7 @@ pub fn transfer_token_to_ethereum_fee_not_enough() { #[test] pub fn transfer_token_to_ethereum_insufficient_fund() { snowbridge_runtime_test_common::send_transfer_token_message_failure::( + 11155111, collator_session_keys(), 1013, 1000, @@ -146,6 +150,7 @@ pub fn ethereum_outbound_queue_processes_messages_before_message_queue_works() { XcmConfig, AllPalletsWithoutSystem, >( + 11155111, collator_session_keys(), 1013, 1000, -- GitLab From eefd5fe4499515da66d088505093f75b5aa22550 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Wed, 28 Feb 2024 20:49:00 +0100 Subject: [PATCH 323/392] Multi-Block-Migrations, `poll` hook and new System callbacks (#1781) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This MR is the merge of https://github.com/paritytech/substrate/pull/14414 and https://github.com/paritytech/substrate/pull/14275. It implements [RFC#13](https://github.com/polkadot-fellows/RFCs/pull/13), closes https://github.com/paritytech/polkadot-sdk/issues/198. ----- This Merge request introduces three major topicals: 1. Multi-Block-Migrations 1. New pallet `poll` hook for periodic service work 1. Replacement hooks for `on_initialize` and `on_finalize` in cases where `poll` cannot be used and some more general changes to FRAME. The changes for each topical span over multiple crates. They are listed in topical order below. # 1.) Multi-Block-Migrations Multi-Block-Migrations are facilitated by creating `pallet_migrations` and configuring `System::Config::MultiBlockMigrator` to point to it. Executive picks this up and triggers one step of the migrations pallet per block. The chain is in lockdown mode for as long as an MBM is ongoing. Executive does this by polling `MultiBlockMigrator::ongoing` and not allowing any transaction in a block, if true. A MBM is defined through trait `SteppedMigration`. A condensed version looks like this: ```rust /// A migration that can proceed in multiple steps. pub trait SteppedMigration { type Cursor: FullCodec + MaxEncodedLen; type Identifier: FullCodec + MaxEncodedLen; fn id() -> Self::Identifier; fn max_steps() -> Option; fn step( cursor: Option, meter: &mut WeightMeter, ) -> Result, SteppedMigrationError>; } ``` `pallet_migrations` can be configured with an aggregated tuple of these migrations. It then starts to migrate them one-by-one on the next runtime upgrade. Two things are important here: - 1. Doing another runtime upgrade while MBMs are ongoing is not a good idea and can lead to messed up state. - 2. **Pallet Migrations MUST BE CONFIGURED IN `System::Config`, otherwise it is not used.** The pallet supports an `UpgradeStatusHandler` that can be used to notify external logic of upgrade start/finish (for example to pause XCM dispatch). Error recovery is very limited in the case that a migration errors or times out (exceeds its `max_steps`). Currently the runtime dev can decide in `FailedMigrationHandler::failed` how to handle this. One follow-up would be to pair this with the `SafeMode` pallet and enact safe mode when an upgrade fails, to allow governance to rescue the chain. This is currently not possible, since governance is not `Mandatory`. ## Runtime API - `Core`: `initialize_block` now returns `ExtrinsicInclusionMode` to inform the Block Author whether they can push transactions. ### Integration Add it to your runtime implementation of `Core` and `BlockBuilder`: ```patch diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs @@ impl_runtime_apis! { impl sp_block_builder::Core for Runtime { - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> RuntimeExecutiveMode { Executive::initialize_block(header) } ... } ``` # 2.) `poll` hook A new pallet hook is introduced: `poll`. `Poll` is intended to replace mostly all usage of `on_initialize`. The reason for this is that any code that can be called from `on_initialize` cannot be migrated through an MBM. Currently there is no way to statically check this; the implication is to use `on_initialize` as rarely as possible. Failing to do so can result in broken storage invariants. The implementation of the poll hook depends on the `Runtime API` changes that are explained above. # 3.) Hard-Deadline callbacks Three new callbacks are introduced and configured on `System::Config`: `PreInherents`, `PostInherents` and `PostTransactions`. These hooks are meant as replacement for `on_initialize` and `on_finalize` in cases where the code that runs cannot be moved to `poll`. The reason for this is to make the usage of HD-code (hard deadline) more explicit - again to prevent broken invariants by MBMs. # 4.) FRAME (general changes) ## `frame_system` pallet A new memorize storage item `InherentsApplied` is added. It is used by executive to track whether inherents have already been applied. Executive and can then execute the MBMs directly between inherents and transactions. The `Config` gets five new items: - `SingleBlockMigrations` this is the new way of configuring migrations that run in a single block. Previously they were defined as last generic argument of `Executive`. This shift is brings all central configuration about migrations closer into view of the developer (migrations that are configured in `Executive` will still work for now but is deprecated). - `MultiBlockMigrator` this can be configured to an engine that drives MBMs. One example would be the `pallet_migrations`. Note that this is only the engine; the exact MBMs are injected into the engine. - `PreInherents` a callback that executes after `on_initialize` but before inherents. - `PostInherents` a callback that executes after all inherents ran (including MBMs and `poll`). - `PostTransactions` in symmetry to `PreInherents`, this one is called before `on_finalize` but after all transactions. A sane default is to set all of these to `()`. Example diff suitable for any chain: ```patch @@ impl frame_system::Config for Test { type MaxConsumers = ConstU32<16>; + type SingleBlockMigrations = (); + type MultiBlockMigrator = (); + type PreInherents = (); + type PostInherents = (); + type PostTransactions = (); } ``` An overview of how the block execution now looks like is here. The same graph is also in the rust doc.
Block Execution Flow

![Screenshot 2023-12-04 at 19 11 29](https://github.com/paritytech/polkadot-sdk/assets/10380170/e88a80c4-ef11-4faa-8df5-8b33a724c054)

## Inherent Order Moved to https://github.com/paritytech/polkadot-sdk/pull/2154 --------------- ## TODO - [ ] Check that `try-runtime` still works - [ ] Ensure backwards compatibility with old Runtime APIs - [x] Consume weight correctly - [x] Cleanup --------- Signed-off-by: Oliver Tale-Yazdi Co-authored-by: Liam Aharon Co-authored-by: Juan Girini Co-authored-by: command-bot <> Co-authored-by: Francisco Aguirre Co-authored-by: Gavin Wood Co-authored-by: Bastian Köcher --- Cargo.lock | 110 +- Cargo.toml | 1 + .../pallets/inbound-queue/src/mock.rs | 13 +- .../pallets/outbound-queue/src/mock.rs | 14 +- bridges/snowbridge/pallets/system/src/mock.rs | 15 +- .../ethereum-beacon-client/src/mock.rs | 259 +++ cumulus/parachain-template/runtime/src/lib.rs | 2 +- .../assets/asset-hub-rococo/src/lib.rs | 2 +- .../assets/asset-hub-westend/src/lib.rs | 2 +- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 2 +- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 2 +- .../collectives-westend/src/lib.rs | 2 +- .../contracts/contracts-rococo/src/lib.rs | 2 +- .../coretime/coretime-rococo/src/lib.rs | 2 +- .../coretime/coretime-westend/src/lib.rs | 2 +- .../glutton/glutton-westend/src/lib.rs | 2 +- .../runtimes/people/people-rococo/src/lib.rs | 2 +- .../runtimes/people/people-westend/src/lib.rs | 2 +- .../runtimes/starters/seedling/src/lib.rs | 2 +- .../runtimes/starters/shell/src/lib.rs | 2 +- .../runtimes/testing/penpal/src/lib.rs | 2 +- .../testing/rococo-parachain/src/lib.rs | 2 +- .../asset_hub_polkadot_aura.rs | 2 +- .../src/fake_runtime_api/aura.rs | 2 +- cumulus/test/runtime/src/lib.rs | 2 +- polkadot/node/service/src/fake_runtime_api.rs | 2 +- polkadot/runtime/common/src/claims.rs | 29 +- polkadot/runtime/rococo/src/lib.rs | 2 +- polkadot/runtime/test-runtime/src/lib.rs | 2 +- polkadot/runtime/westend/src/lib.rs | 2 +- prdoc/pr_1781.prdoc | 45 + substrate/bin/minimal/runtime/src/lib.rs | 5 +- .../bin/node-template/runtime/src/lib.rs | 2 +- substrate/bin/node/runtime/Cargo.toml | 4 + substrate/bin/node/runtime/src/lib.rs | 24 +- .../basic-authorship/src/basic_authorship.rs | 13 +- substrate/client/block-builder/src/lib.rs | 26 +- substrate/client/proposer-metrics/src/lib.rs | 4 + .../rpc-spec-v2/src/chain_head/tests.rs | 6 +- substrate/client/rpc/src/state/tests.rs | 2 +- substrate/frame/executive/Cargo.toml | 2 + substrate/frame/executive/src/lib.rs | 1194 +++----------- substrate/frame/executive/src/tests.rs | 1389 +++++++++++++++++ substrate/frame/migrations/Cargo.toml | 64 + .../frame/migrations/src/benchmarking.rs | 222 +++ substrate/frame/migrations/src/lib.rs | 746 +++++++++ substrate/frame/migrations/src/mock.rs | 163 ++ .../frame/migrations/src/mock_helpers.rs | 142 ++ substrate/frame/migrations/src/tests.rs | 335 ++++ substrate/frame/migrations/src/weights.rs | 358 +++++ substrate/frame/src/lib.rs | 2 +- .../src/construct_runtime/expand/inherent.rs | 63 +- .../procedural/src/pallet/expand/hooks.rs | 16 + substrate/frame/support/src/migrations.rs | 636 +++++++- .../support/src/storage/transactional.rs | 16 + substrate/frame/support/src/traits.rs | 11 +- substrate/frame/support/src/traits/hooks.rs | 70 + substrate/frame/support/src/traits/misc.rs | 17 +- .../undefined_inherent_part.stderr | 23 +- .../test/tests/pallet_outer_enums_explicit.rs | 1 + .../test/tests/pallet_outer_enums_implicit.rs | 1 + .../support/test/tests/runtime_metadata.rs | 6 +- substrate/frame/system/src/lib.rs | 74 +- substrate/frame/system/src/mock.rs | 16 + substrate/frame/system/src/tests.rs | 22 + .../api/proc-macro/src/decl_runtime_apis.rs | 1 + .../proc-macro/src/mock_impl_runtime_apis.rs | 2 +- substrate/primitives/api/src/lib.rs | 18 +- .../api/test/tests/decl_and_impl.rs | 2 +- .../ui/impl_incorrect_method_signature.rs | 2 +- .../api/test/tests/ui/impl_missing_version.rs | 2 +- .../test/tests/ui/missing_versioned_method.rs | 2 +- .../missing_versioned_method_multiple_vers.rs | 2 +- .../ui/positive_cases/custom_where_bound.rs | 2 +- .../tests/ui/positive_cases/default_impls.rs | 2 +- ...ype_reference_in_impl_runtime_apis_call.rs | 2 +- substrate/primitives/runtime/src/lib.rs | 10 + substrate/test-utils/runtime/src/lib.rs | 6 +- 78 files changed, 5072 insertions(+), 1188 deletions(-) create mode 100644 bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/mock.rs create mode 100644 prdoc/pr_1781.prdoc create mode 100644 substrate/frame/executive/src/tests.rs create mode 100644 substrate/frame/migrations/Cargo.toml create mode 100644 substrate/frame/migrations/src/benchmarking.rs create mode 100644 substrate/frame/migrations/src/lib.rs create mode 100644 substrate/frame/migrations/src/mock.rs create mode 100644 substrate/frame/migrations/src/mock_helpers.rs create mode 100644 substrate/frame/migrations/src/tests.rs create mode 100644 substrate/frame/migrations/src/weights.rs diff --git a/Cargo.lock b/Cargo.lock index 197d05e2633..3838ed0e94a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,6 +322,20 @@ dependencies = [ "num-traits", ] +[[package]] +name = "aquamarine" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1da02abba9f9063d786eab1509833ebb2fac0f966862ca59439c76b9c566760" +dependencies = [ + "include_dir", + "itertools 0.10.5", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "aquamarine" version = "0.5.0" @@ -4055,7 +4069,7 @@ dependencies = [ "cumulus-primitives-core", "cumulus-primitives-proof-size-hostfunction", "cumulus-test-runtime", - "docify", + "docify 0.2.7", "frame-support", "frame-system", "log", @@ -4736,13 +4750,39 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +[[package]] +name = "docify" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1b04e6ef3d21119d3eb7b032bca17f99fe041e9c072f30f32cc0e1a2b1f3c4" +dependencies = [ + "docify_macros 0.1.16", +] + [[package]] name = "docify" version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cc4fd38aaa9fb98ac70794c82a00360d1e165a87fbf96a8a91f9dfc602aaee2" dependencies = [ - "docify_macros", + "docify_macros 0.2.7", +] + +[[package]] +name = "docify_macros" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b5610df7f2acf89a1bb5d1a66ae56b1c7fcdcfe3948856fb3ace3f644d70eb7" +dependencies = [ + "common-path", + "derive-syn-parse", + "lazy_static", + "proc-macro2", + "quote", + "regex", + "syn 2.0.50", + "termcolor", + "walkdir", ] [[package]] @@ -5451,7 +5491,7 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" name = "frame" version = "0.0.1-dev" dependencies = [ - "docify", + "docify 0.2.7", "frame-executive", "frame-support", "frame-system", @@ -5619,6 +5659,7 @@ dependencies = [ name = "frame-executive" version = "28.0.0" dependencies = [ + "aquamarine 0.3.3", "array-bytes 6.1.0", "frame-support", "frame-system", @@ -5675,11 +5716,11 @@ dependencies = [ name = "frame-support" version = "28.0.0" dependencies = [ - "aquamarine", + "aquamarine 0.5.0", "array-bytes 6.1.0", "assert_matches", "bitflags 1.3.2", - "docify", + "docify 0.2.7", "environmental", "frame-metadata", "frame-support-procedural", @@ -5822,7 +5863,7 @@ version = "28.0.0" dependencies = [ "cfg-if", "criterion 0.4.0", - "docify", + "docify 0.2.7", "frame-support", "log", "parity-scale-codec", @@ -7081,6 +7122,7 @@ dependencies = [ "pallet-lottery", "pallet-membership", "pallet-message-queue", + "pallet-migrations", "pallet-mixnet", "pallet-mmr", "pallet-multisig", @@ -9301,8 +9343,8 @@ dependencies = [ name = "pallet-bags-list" version = "27.0.0" dependencies = [ - "aquamarine", - "docify", + "aquamarine 0.5.0", + "docify 0.2.7", "frame-benchmarking", "frame-election-provider-support", "frame-support", @@ -9350,7 +9392,7 @@ dependencies = [ name = "pallet-balances" version = "28.0.0" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-support", "frame-system", @@ -9969,7 +10011,7 @@ dependencies = [ name = "pallet-example-single-block-migrations" version = "0.0.1" dependencies = [ - "docify", + "docify 0.2.7", "frame-executive", "frame-support", "frame-system", @@ -10035,7 +10077,7 @@ dependencies = [ name = "pallet-fast-unstake" version = "27.0.0" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-election-provider-support", "frame-support", @@ -10232,6 +10274,30 @@ dependencies = [ "sp-weights", ] +[[package]] +name = "pallet-migrations" +version = "1.0.0" +dependencies = [ + "docify 0.1.16", + "frame-benchmarking", + "frame-executive", + "frame-support", + "frame-system", + "impl-trait-for-tuples", + "log", + "parity-scale-codec", + "pretty_assertions", + "scale-info", + "sp-api", + "sp-block-builder", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std 14.0.0", + "sp-tracing 16.0.0", + "sp-version", +] + [[package]] name = "pallet-mixnet" version = "0.4.0" @@ -10507,7 +10573,7 @@ dependencies = [ name = "pallet-paged-list" version = "0.6.0" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-support", "frame-system", @@ -10550,7 +10616,7 @@ dependencies = [ name = "pallet-parameters" version = "0.0.1" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-support", "frame-system", @@ -10711,7 +10777,7 @@ dependencies = [ name = "pallet-safe-mode" version = "9.0.0" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-support", "frame-system", @@ -10768,7 +10834,7 @@ dependencies = [ name = "pallet-scheduler" version = "29.0.0" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-support", "frame-system", @@ -10981,7 +11047,7 @@ dependencies = [ name = "pallet-sudo" version = "28.0.0" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-support", "frame-system", @@ -11012,7 +11078,7 @@ dependencies = [ name = "pallet-timestamp" version = "27.0.0" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-support", "frame-system", @@ -11116,7 +11182,7 @@ dependencies = [ name = "pallet-treasury" version = "27.0.0" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-support", "frame-system", @@ -11136,7 +11202,7 @@ dependencies = [ name = "pallet-tx-pause" version = "9.0.0" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-support", "frame-system", @@ -13404,7 +13470,7 @@ version = "0.0.1" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", - "docify", + "docify 0.2.7", "frame", "frame-executive", "frame-support", @@ -15665,7 +15731,7 @@ name = "sc-chain-spec" version = "27.0.0" dependencies = [ "array-bytes 6.1.0", - "docify", + "docify 0.2.7", "log", "memmap2 0.9.3", "parity-scale-codec", @@ -18931,7 +18997,7 @@ dependencies = [ name = "sp-runtime" version = "31.0.1" dependencies = [ - "docify", + "docify 0.2.7", "either", "hash256-std-hasher", "impl-trait-for-tuples", diff --git a/Cargo.toml b/Cargo.toml index 654367cc1e2..48aa25f5c5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -352,6 +352,7 @@ members = [ "substrate/frame/membership", "substrate/frame/merkle-mountain-range", "substrate/frame/message-queue", + "substrate/frame/migrations", "substrate/frame/mixnet", "substrate/frame/multisig", "substrate/frame/nft-fractionalization", diff --git a/bridges/snowbridge/pallets/inbound-queue/src/mock.rs b/bridges/snowbridge/pallets/inbound-queue/src/mock.rs index 110f611c676..749fb0367f3 100644 --- a/bridges/snowbridge/pallets/inbound-queue/src/mock.rs +++ b/bridges/snowbridge/pallets/inbound-queue/src/mock.rs @@ -3,7 +3,7 @@ use super::*; use frame_support::{ - parameter_types, + derive_impl, parameter_types, traits::{ConstU128, ConstU32, Everything}, weights::IdentityFee, }; @@ -47,10 +47,9 @@ parameter_types! { type Balance = u128; +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Test { type BaseCallFilter = Everything; - type BlockWeights = (); - type BlockLength = (); type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; type RuntimeTask = RuntimeTask; @@ -60,16 +59,8 @@ impl frame_system::Config for Test { type Lookup = IdentityLookup; type RuntimeEvent = RuntimeEvent; type BlockHashCount = BlockHashCount; - type DbWeight = (); - type Version = (); type PalletInfo = PalletInfo; type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = (); - type OnSetCode = (); - type MaxConsumers = frame_support::traits::ConstU32<16>; type Nonce = u64; type Block = Block; } diff --git a/bridges/snowbridge/pallets/outbound-queue/src/mock.rs b/bridges/snowbridge/pallets/outbound-queue/src/mock.rs index dd8fee4e2ed..6e78fb44672 100644 --- a/bridges/snowbridge/pallets/outbound-queue/src/mock.rs +++ b/bridges/snowbridge/pallets/outbound-queue/src/mock.rs @@ -3,7 +3,7 @@ use super::*; use frame_support::{ - parameter_types, + derive_impl, parameter_types, traits::{Everything, Hooks}, weights::IdentityFee, }; @@ -37,10 +37,9 @@ parameter_types! { pub const BlockHashCount: u64 = 250; } +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Test { type BaseCallFilter = Everything; - type BlockWeights = (); - type BlockLength = (); type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; type RuntimeTask = RuntimeTask; @@ -50,16 +49,7 @@ impl frame_system::Config for Test { type Lookup = IdentityLookup; type RuntimeEvent = RuntimeEvent; type BlockHashCount = BlockHashCount; - type DbWeight = (); - type Version = (); type PalletInfo = PalletInfo; - type AccountData = (); - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = (); - type OnSetCode = (); - type MaxConsumers = frame_support::traits::ConstU32<16>; type Nonce = u64; type Block = Block; } diff --git a/bridges/snowbridge/pallets/system/src/mock.rs b/bridges/snowbridge/pallets/system/src/mock.rs index edc3f141b07..de2970dd550 100644 --- a/bridges/snowbridge/pallets/system/src/mock.rs +++ b/bridges/snowbridge/pallets/system/src/mock.rs @@ -2,8 +2,8 @@ // SPDX-FileCopyrightText: 2023 Snowfork use crate as snowbridge_system; use frame_support::{ - parameter_types, - traits::{tokens::fungible::Mutate, ConstU128, ConstU16, ConstU64, ConstU8}, + derive_impl, parameter_types, + traits::{tokens::fungible::Mutate, ConstU128, ConstU64, ConstU8}, weights::IdentityFee, PalletId, }; @@ -95,11 +95,9 @@ frame_support::construct_runtime!( } ); +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Test { type BaseCallFilter = frame_support::traits::Everything; - type BlockWeights = (); - type BlockLength = (); - type DbWeight = (); type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; type RuntimeTask = RuntimeTask; @@ -109,15 +107,8 @@ impl frame_system::Config for Test { type Lookup = IdentityLookup; type RuntimeEvent = RuntimeEvent; type BlockHashCount = ConstU64<250>; - type Version = (); type PalletInfo = PalletInfo; type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = ConstU16<42>; - type OnSetCode = (); - type MaxConsumers = frame_support::traits::ConstU32<16>; type Nonce = u64; type Block = Block; } diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/mock.rs b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/mock.rs new file mode 100644 index 00000000000..77b5c1aa631 --- /dev/null +++ b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/mock.rs @@ -0,0 +1,259 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork +use crate as ethereum_beacon_client; +use frame_support::parameter_types; +use pallet_timestamp; +use primitives::{Fork, ForkVersions}; +use sp_core::H256; +use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; + +#[cfg(not(feature = "beacon-spec-mainnet"))] +pub mod minimal { + use super::*; + + use crate::config; + use frame_support::derive_impl; + use hex_literal::hex; + use primitives::CompactExecutionHeader; + use snowbridge_core::inbound::{Log, Proof}; + use sp_runtime::BuildStorage; + use std::{fs::File, path::PathBuf}; + + type Block = frame_system::mocking::MockBlock; + + frame_support::construct_runtime!( + pub enum Test { + System: frame_system::{Pallet, Call, Storage, Event}, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + EthereumBeaconClient: ethereum_beacon_client::{Pallet, Call, Storage, Event}, + } + ); + + parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const SS58Prefix: u8 = 42; + } + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type RuntimeTask = RuntimeTask; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type PalletInfo = PalletInfo; + type SS58Prefix = SS58Prefix; + type Nonce = u64; + type Block = Block; + } + + impl pallet_timestamp::Config for Test { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = (); + type WeightInfo = (); + } + + parameter_types! { + pub const ExecutionHeadersPruneThreshold: u32 = 10; + pub const ChainForkVersions: ForkVersions = ForkVersions{ + genesis: Fork { + version: [0, 0, 0, 1], // 0x00000001 + epoch: 0, + }, + altair: Fork { + version: [1, 0, 0, 1], // 0x01000001 + epoch: 0, + }, + bellatrix: Fork { + version: [2, 0, 0, 1], // 0x02000001 + epoch: 0, + }, + capella: Fork { + version: [3, 0, 0, 1], // 0x03000001 + epoch: 0, + }, + }; + } + + impl ethereum_beacon_client::Config for Test { + type RuntimeEvent = RuntimeEvent; + type ForkVersions = ChainForkVersions; + type MaxExecutionHeadersToKeep = ExecutionHeadersPruneThreshold; + type WeightInfo = (); + } + + // Build genesis storage according to the mock runtime. + pub fn new_tester() -> sp_io::TestExternalities { + let t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + let mut ext = sp_io::TestExternalities::new(t); + let _ = ext.execute_with(|| Timestamp::set(RuntimeOrigin::signed(1), 30_000)); + ext + } + + fn load_fixture(basename: &str) -> Result + where + T: for<'de> serde::Deserialize<'de>, + { + let filepath: PathBuf = + [env!("CARGO_MANIFEST_DIR"), "tests", "fixtures", basename].iter().collect(); + serde_json::from_reader(File::open(filepath).unwrap()) + } + + pub fn load_execution_header_update_fixture() -> primitives::ExecutionHeaderUpdate { + load_fixture("execution-header-update.minimal.json").unwrap() + } + + pub fn load_checkpoint_update_fixture( + ) -> primitives::CheckpointUpdate<{ config::SYNC_COMMITTEE_SIZE }> { + load_fixture("initial-checkpoint.minimal.json").unwrap() + } + + pub fn load_sync_committee_update_fixture( + ) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { + load_fixture("sync-committee-update.minimal.json").unwrap() + } + + pub fn load_finalized_header_update_fixture( + ) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { + load_fixture("finalized-header-update.minimal.json").unwrap() + } + + pub fn load_next_sync_committee_update_fixture( + ) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { + load_fixture("next-sync-committee-update.minimal.json").unwrap() + } + + pub fn load_next_finalized_header_update_fixture( + ) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { + load_fixture("next-finalized-header-update.minimal.json").unwrap() + } + + pub fn get_message_verification_payload() -> (Log, Proof) { + ( + Log { + address: hex!("ee9170abfbf9421ad6dd07f6bdec9d89f2b581e0").into(), + topics: vec![ + hex!("1b11dcf133cc240f682dab2d3a8e4cd35c5da8c9cf99adac4336f8512584c5ad").into(), + hex!("00000000000000000000000000000000000000000000000000000000000003e8").into(), + hex!("0000000000000000000000000000000000000000000000000000000000000001").into(), + ], + data: hex!("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004b000f000000000000000100d184c103f7acc340847eee82a0b909e3358bc28d440edffa1352b13227e8ee646f3ea37456dec701345772617070656420457468657210574554481235003511000000000000000000000000000000000000000000").into(), + }, + Proof { + block_hash: hex!("05aaa60b0f27cce9e71909508527264b77ee14da7b5bf915fcc4e32715333213").into(), + tx_index: 0, + data: (vec![ + hex!("cf0d1c1ba57d1e0edfb59786c7e30c2b7e12bd54612b00cd21c4eaeecedf44fb").to_vec(), + hex!("d21fc4f68ab05bc4dcb23c67008e92c4d466437cdd6ed7aad0c008944c185510").to_vec(), + hex!("b9890f91ca0d77aa2a4adfaf9b9e40c94cac9e638b6d9797923865872944b646").to_vec(), + ], vec![ + hex!("f90131a0b601337b3aa10a671caa724eba641e759399979856141d3aea6b6b4ac59b889ba00c7d5dd48be9060221a02fb8fa213860b4c50d47046c8fa65ffaba5737d569e0a094601b62a1086cd9c9cb71a7ebff9e718f3217fd6e837efe4246733c0a196f63a06a4b0dd0aefc37b3c77828c8f07d1b7a2455ceb5dbfd3c77d7d6aeeddc2f7e8ca0d6e8e23142cdd8ec219e1f5d8b56aa18e456702b195deeaa210327284d42ade4a08a313d4c87023005d1ab631bbfe3f5de1e405d0e66d0bef3e033f1e5711b5521a0bf09a5d9a48b10ade82b8d6a5362a15921c8b5228a3487479b467db97411d82fa0f95cccae2a7c572ef3c566503e30bac2b2feb2d2f26eebf6d870dcf7f8cf59cea0d21fc4f68ab05bc4dcb23c67008e92c4d466437cdd6ed7aad0c008944c1855108080808080808080").to_vec(), + hex!("f851a0b9890f91ca0d77aa2a4adfaf9b9e40c94cac9e638b6d9797923865872944b646a060a634b9280e3a23fb63375e7bbdd9ab07fd379ab6a67e2312bbc112195fa358808080808080808080808080808080").to_vec(), + hex!("f9030820b9030402f90300018301d6e2b9010000000000000800000000000020040008000000000000000000000000400000008000000000000000000000000000000000000000000000000000000000042010000000001000000000000000000000000000000000040000000000000000000000000000000000000000000000008000000000000000002000000000000000000000000200000000000000200000000000100000000040000001000200008000000000000200000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000f901f5f87a942ffa5ecdbe006d30397c7636d3e015eee251369ff842a0c965575a00553e094ca7c5d14f02e107c258dda06867cbf9e0e69f80e71bbcc1a000000000000000000000000000000000000000000000000000000000000003e8a000000000000000000000000000000000000000000000000000000000000003e8f9011c94ee9170abfbf9421ad6dd07f6bdec9d89f2b581e0f863a01b11dcf133cc240f682dab2d3a8e4cd35c5da8c9cf99adac4336f8512584c5ada000000000000000000000000000000000000000000000000000000000000003e8a00000000000000000000000000000000000000000000000000000000000000001b8a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004b000f000000000000000100d184c103f7acc340847eee82a0b909e3358bc28d440edffa1352b13227e8ee646f3ea37456dec701345772617070656420457468657210574554481235003511000000000000000000000000000000000000000000f858948cf6147918a5cbb672703f879f385036f8793a24e1a01449abf21e49fd025f33495e77f7b1461caefdd3d4bb646424a3f445c4576a5ba0000000000000000000000000440edffa1352b13227e8ee646f3ea37456dec701").to_vec(), + ]), + } + ) + } + + pub fn get_message_verification_header() -> CompactExecutionHeader { + CompactExecutionHeader { + parent_hash: hex!("04a7f6ab8282203562c62f38b0ab41d32aaebe2c7ea687702b463148a6429e04") + .into(), + block_number: 55, + state_root: hex!("894d968712976d613519f973a317cb0781c7b039c89f27ea2b7ca193f7befdb3") + .into(), + receipts_root: hex!("cf0d1c1ba57d1e0edfb59786c7e30c2b7e12bd54612b00cd21c4eaeecedf44fb") + .into(), + } + } +} + +#[cfg(feature = "beacon-spec-mainnet")] +pub mod mainnet { + use super::*; + use frame_support::derive_impl; + + type Block = frame_system::mocking::MockBlock; + use sp_runtime::BuildStorage; + + frame_support::construct_runtime!( + pub enum Test { + System: frame_system::{Pallet, Call, Storage, Event}, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + EthereumBeaconClient: ethereum_beacon_client::{Pallet, Call, Storage, Event}, + } + ); + + parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const SS58Prefix: u8 = 42; + } + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type RuntimeTask = RuntimeTask; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type PalletInfo = PalletInfo; + type SS58Prefix = SS58Prefix; + type Nonce = u64; + type Block = Block; + } + + impl pallet_timestamp::Config for Test { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = (); + type WeightInfo = (); + } + + parameter_types! { + pub const ChainForkVersions: ForkVersions = ForkVersions{ + genesis: Fork { + version: [0, 0, 16, 32], // 0x00001020 + epoch: 0, + }, + altair: Fork { + version: [1, 0, 16, 32], // 0x01001020 + epoch: 36660, + }, + bellatrix: Fork { + version: [2, 0, 16, 32], // 0x02001020 + epoch: 112260, + }, + capella: Fork { + version: [3, 0, 16, 32], // 0x03001020 + epoch: 162304, + }, + }; + pub const ExecutionHeadersPruneThreshold: u32 = 10; + } + + impl ethereum_beacon_client::Config for Test { + type RuntimeEvent = RuntimeEvent; + type ForkVersions = ChainForkVersions; + type MaxExecutionHeadersToKeep = ExecutionHeadersPruneThreshold; + type WeightInfo = (); + } + + // Build genesis storage according to the mock runtime. + pub fn new_tester() -> sp_io::TestExternalities { + let t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + let mut ext = sp_io::TestExternalities::new(t); + let _ = ext.execute_with(|| Timestamp::set(RuntimeOrigin::signed(1), 30_000)); + ext + } +} diff --git a/cumulus/parachain-template/runtime/src/lib.rs b/cumulus/parachain-template/runtime/src/lib.rs index cee9b33bf37..004a5d70ebc 100644 --- a/cumulus/parachain-template/runtime/src/lib.rs +++ b/cumulus/parachain-template/runtime/src/lib.rs @@ -560,7 +560,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 6791dc4064e..1c4f49fea0e 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -1093,7 +1093,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 5352eeb1a1b..e015c7bfca3 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -1124,7 +1124,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index db1dfbd45d6..0f6af1b51f1 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -816,7 +816,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 1c8c9aa2075..206743ba6ac 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -566,7 +566,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index 36eb0e07f87..3ed9d6e8e16 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -803,7 +803,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index 541978098ca..c4df5b9a565 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -466,7 +466,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index fcd7576b1e1..0cdfebce742 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -521,7 +521,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index 80eb7863803..7797329b526 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -512,7 +512,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs index 10408aaf39a..e09ad42ea9f 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs @@ -332,7 +332,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index 90c39891769..616da5519a5 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -495,7 +495,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index a904f7c3521..9f572330cac 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -495,7 +495,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/starters/seedling/src/lib.rs b/cumulus/parachains/runtimes/starters/seedling/src/lib.rs index ba077ef8879..4cc0a81ef49 100644 --- a/cumulus/parachains/runtimes/starters/seedling/src/lib.rs +++ b/cumulus/parachains/runtimes/starters/seedling/src/lib.rs @@ -300,7 +300,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/starters/shell/src/lib.rs b/cumulus/parachains/runtimes/starters/shell/src/lib.rs index 457394760d9..829754731a4 100644 --- a/cumulus/parachains/runtimes/starters/shell/src/lib.rs +++ b/cumulus/parachains/runtimes/starters/shell/src/lib.rs @@ -357,7 +357,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs index bf8dcbc24c8..0030287edb3 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs @@ -699,7 +699,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs index 57969d9a4f1..b69c2341d6b 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs @@ -689,7 +689,7 @@ impl_runtime_apis! { Executive::execute_block(block); } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/polkadot-parachain/src/fake_runtime_api/asset_hub_polkadot_aura.rs b/cumulus/polkadot-parachain/src/fake_runtime_api/asset_hub_polkadot_aura.rs index 76dd7347ccb..7778d1bf7d2 100644 --- a/cumulus/polkadot-parachain/src/fake_runtime_api/asset_hub_polkadot_aura.rs +++ b/cumulus/polkadot-parachain/src/fake_runtime_api/asset_hub_polkadot_aura.rs @@ -39,7 +39,7 @@ sp_api::impl_runtime_apis! { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/cumulus/polkadot-parachain/src/fake_runtime_api/aura.rs b/cumulus/polkadot-parachain/src/fake_runtime_api/aura.rs index 0f01b85ebcf..880f5d760c7 100644 --- a/cumulus/polkadot-parachain/src/fake_runtime_api/aura.rs +++ b/cumulus/polkadot-parachain/src/fake_runtime_api/aura.rs @@ -39,7 +39,7 @@ sp_api::impl_runtime_apis! { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/cumulus/test/runtime/src/lib.rs b/cumulus/test/runtime/src/lib.rs index 5fb31410984..5ccec8983e9 100644 --- a/cumulus/test/runtime/src/lib.rs +++ b/cumulus/test/runtime/src/lib.rs @@ -377,7 +377,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/polkadot/node/service/src/fake_runtime_api.rs b/polkadot/node/service/src/fake_runtime_api.rs index ccc3da22400..085ea93fdc7 100644 --- a/polkadot/node/service/src/fake_runtime_api.rs +++ b/polkadot/node/service/src/fake_runtime_api.rs @@ -60,7 +60,7 @@ sp_api::impl_runtime_apis! { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/polkadot/runtime/common/src/claims.rs b/polkadot/runtime/common/src/claims.rs index 86550ea8b4e..68f42914e44 100644 --- a/polkadot/runtime/common/src/claims.rs +++ b/polkadot/runtime/common/src/claims.rs @@ -702,7 +702,6 @@ mod tests { use secp_utils::*; use parity_scale_codec::Encode; - use sp_core::H256; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use crate::claims; @@ -715,11 +714,8 @@ mod tests { }; use pallet_balances; use sp_runtime::{ - traits::{BlakeTwo256, Identity, IdentityLookup}, - transaction_validity::TransactionLongevity, - BuildStorage, - DispatchError::BadOrigin, - TokenError, + traits::Identity, transaction_validity::TransactionLongevity, BuildStorage, + DispatchError::BadOrigin, TokenError, }; type Block = frame_system::mocking::MockBlock; @@ -734,34 +730,13 @@ mod tests { } ); - parameter_types! { - pub const BlockHashCount: u32 = 250; - } - #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Test { - type BaseCallFilter = frame_support::traits::Everything; - type BlockWeights = (); - type BlockLength = (); - type DbWeight = (); type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; - type Nonce = u64; - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; type Block = Block; type RuntimeEvent = RuntimeEvent; - type BlockHashCount = BlockHashCount; - type Version = (); - type PalletInfo = PalletInfo; type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = (); - type OnSetCode = (); type MaxConsumers = frame_support::traits::ConstU32<16>; } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index bbc79a13d37..173301e1ad9 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -1768,7 +1768,7 @@ sp_api::impl_runtime_apis! { Executive::execute_block(block); } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index b74def5de8a..6c899c52701 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -767,7 +767,7 @@ sp_api::impl_runtime_apis! { Executive::execute_block(block); } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 574710b3110..91047d953f5 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -1793,7 +1793,7 @@ sp_api::impl_runtime_apis! { Executive::execute_block(block); } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/prdoc/pr_1781.prdoc b/prdoc/pr_1781.prdoc new file mode 100644 index 00000000000..e3560842d15 --- /dev/null +++ b/prdoc/pr_1781.prdoc @@ -0,0 +1,45 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: "Multi-Block-Migrations, `poll` hook and new System Callbacks" + +doc: + - audience: Runtime Dev + description: | + The major things that this MR touches are: + + **Multi-Block-Migrations**: `pallet-migrations` is introduced that can be configured in the + `System` of a runtime to act as multi-block migrator. The `migrations` pallet then in turn + receives the list of MBMs as config parameter. The list of migrations can be an aggregated + tuple of `SteppedMigration` trait implementation. + It is paramount that the `migrations` pallet is configured in `System` once it is deployed. A + test is in place to double check this. + + To integrate this into your runtime, it is only necessary to change the return type of + `initialize_block` to `RuntimeExecutiveMode`. For extended info please see + https://github.com/paritytech/polkadot-sdk/pull/1781. + + **poll**: a new pallet hook named `poll` is added. This can be used for places where the code + that should be executed is not deadline critical. Runtime devs are advised to skim their usage + of `on_initialize` and `on_finalize` to see whether they can be replace with `poll`. `poll` is + not guaranteed to be called each block. In fact it will not be called when MBMs are ongoing. + + **System Callbacks**: The `system` pallet gets five new config items - all of which can be + safely set to `()` as default. They are: + - `SingleBlockMigrations`: replaces the `Executive` now for configuring migrations. + - `MultiBlockMigrator`: the `pallet-migrations` would be set here, if deployed. + - `PreInherents`: a hook that runs before any inherent. + - `PostInherents`: a hook to run between inherents and `poll`/MBM logic. + - `PostTransactions`: a hook to run after all transactions but before `on_idle`. + +crates: + - name: frame-executive + - name: frame-system + - name: frame-support + - name: frame-support-procedural + - name: pallet-migrations + - name: sc-basic-authorship + - name: sc-block-builder + - name: sp-api + - name: sp-api-proc-macro + - name: sp-runtime diff --git a/substrate/bin/minimal/runtime/src/lib.rs b/substrate/bin/minimal/runtime/src/lib.rs index 610289693d9..fb996aef46b 100644 --- a/substrate/bin/minimal/runtime/src/lib.rs +++ b/substrate/bin/minimal/runtime/src/lib.rs @@ -26,7 +26,8 @@ use frame::{ prelude::*, runtime::{ apis::{ - self, impl_runtime_apis, ApplyExtrinsicResult, CheckInherentsResult, OpaqueMetadata, + self, impl_runtime_apis, ApplyExtrinsicResult, CheckInherentsResult, + ExtrinsicInclusionMode, OpaqueMetadata, }, prelude::*, }, @@ -121,7 +122,7 @@ impl_runtime_apis! { RuntimeExecutive::execute_block(block) } - fn initialize_block(header: &Header) { + fn initialize_block(header: &Header) -> ExtrinsicInclusionMode { RuntimeExecutive::initialize_block(header) } } diff --git a/substrate/bin/node-template/runtime/src/lib.rs b/substrate/bin/node-template/runtime/src/lib.rs index 3b6a74be251..159697f427f 100644 --- a/substrate/bin/node-template/runtime/src/lib.rs +++ b/substrate/bin/node-template/runtime/src/lib.rs @@ -331,7 +331,7 @@ impl_runtime_apis! { Executive::execute_block(block); } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/substrate/bin/node/runtime/Cargo.toml b/substrate/bin/node/runtime/Cargo.toml index aa13c3d292b..9607d05daf0 100644 --- a/substrate/bin/node/runtime/Cargo.toml +++ b/substrate/bin/node/runtime/Cargo.toml @@ -88,6 +88,7 @@ pallet-election-provider-support-benchmarking = { path = "../../../frame/electio pallet-elections-phragmen = { path = "../../../frame/elections-phragmen", default-features = false } pallet-example-tasks = { path = "../../../frame/examples/tasks", default-features = false } pallet-fast-unstake = { path = "../../../frame/fast-unstake", default-features = false } +pallet-migrations = { path = "../../../frame/migrations", default-features = false } pallet-nis = { path = "../../../frame/nis", default-features = false } pallet-grandpa = { path = "../../../frame/grandpa", default-features = false } pallet-im-online = { path = "../../../frame/im-online", default-features = false } @@ -198,6 +199,7 @@ std = [ "pallet-lottery/std", "pallet-membership/std", "pallet-message-queue/std", + "pallet-migrations/std", "pallet-mixnet/std", "pallet-mmr/std", "pallet-multisig/std", @@ -302,6 +304,7 @@ runtime-benchmarks = [ "pallet-lottery/runtime-benchmarks", "pallet-membership/runtime-benchmarks", "pallet-message-queue/runtime-benchmarks", + "pallet-migrations/runtime-benchmarks", "pallet-mixnet/runtime-benchmarks", "pallet-mmr/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", @@ -381,6 +384,7 @@ try-runtime = [ "pallet-lottery/try-runtime", "pallet-membership/try-runtime", "pallet-message-queue/try-runtime", + "pallet-migrations/try-runtime", "pallet-mixnet/try-runtime", "pallet-mmr/try-runtime", "pallet-multisig/try-runtime", diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index b34d8c89e56..5431628c747 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -310,6 +310,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = frame_system::weights::SubstrateWeight; type SS58Prefix = ConstU16<42>; type MaxConsumers = ConstU32<16>; + type MultiBlockMigrator = MultiBlockMigrations; } impl pallet_insecure_randomness_collective_flip::Config for Runtime {} @@ -2007,6 +2008,25 @@ impl pallet_statement::Config for Runtime { type MaxAllowedBytes = MaxAllowedBytes; } +parameter_types! { + pub MbmServiceWeight: Weight = Perbill::from_percent(80) * RuntimeBlockWeights::get().max_block; +} + +impl pallet_migrations::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + #[cfg(not(feature = "runtime-benchmarks"))] + type Migrations = (); + // Benchmarks need mocked migrations to guarantee that they succeed. + #[cfg(feature = "runtime-benchmarks")] + type Migrations = pallet_migrations::mock_helpers::MockedMigrations; + type CursorMaxLen = ConstU32<65_536>; + type IdentifierMaxLen = ConstU32<256>; + type MigrationStatusHandler = (); + type FailedMigrationHandler = frame_support::migrations::FreezeChainOnFailedMigration; + type MaxServiceWeight = MbmServiceWeight; + type WeightInfo = pallet_migrations::weights::SubstrateWeight; +} + parameter_types! { pub const BrokerPalletId: PalletId = PalletId(*b"py/broke"); } @@ -2241,6 +2261,7 @@ construct_runtime!( TxPause: pallet_tx_pause, SafeMode: pallet_safe_mode, Statement: pallet_statement, + MultiBlockMigrations: pallet_migrations, Broker: pallet_broker, TasksExample: pallet_example_tasks, Mixnet: pallet_mixnet, @@ -2372,6 +2393,7 @@ mod benches { [pallet_lottery, Lottery] [pallet_membership, TechnicalMembership] [pallet_message_queue, MessageQueue] + [pallet_migrations, MultiBlockMigrations] [pallet_mmr, Mmr] [pallet_multisig, Multisig] [pallet_nomination_pools, NominationPoolsBench::] @@ -2417,7 +2439,7 @@ impl_runtime_apis! { Executive::execute_block(block); } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/substrate/client/basic-authorship/src/basic_authorship.rs b/substrate/client/basic-authorship/src/basic_authorship.rs index fdc3d4918de..932287ac865 100644 --- a/substrate/client/basic-authorship/src/basic_authorship.rs +++ b/substrate/client/basic-authorship/src/basic_authorship.rs @@ -38,7 +38,7 @@ use sp_core::traits::SpawnNamed; use sp_inherents::InherentData; use sp_runtime::{ traits::{BlakeTwo256, Block as BlockT, Hash as HashT, Header as HeaderT}, - Digest, Percent, SaturatedConversion, + Digest, ExtrinsicInclusionMode, Percent, SaturatedConversion, }; use std::{marker::PhantomData, pin::Pin, sync::Arc, time}; @@ -335,11 +335,12 @@ where self.apply_inherents(&mut block_builder, inherent_data)?; - // TODO call `after_inherents` and check if we should apply extrinsincs here - // - - let end_reason = - self.apply_extrinsics(&mut block_builder, deadline, block_size_limit).await?; + let mode = block_builder.extrinsic_inclusion_mode(); + let end_reason = match mode { + ExtrinsicInclusionMode::AllExtrinsics => + self.apply_extrinsics(&mut block_builder, deadline, block_size_limit).await?, + ExtrinsicInclusionMode::OnlyInherents => EndProposingReason::TransactionForbidden, + }; let (block, storage_changes, proof) = block_builder.build()?.into_inner(); let block_took = block_timer.elapsed(); diff --git a/substrate/client/block-builder/src/lib.rs b/substrate/client/block-builder/src/lib.rs index 258e39d962b..2f22cd42591 100644 --- a/substrate/client/block-builder/src/lib.rs +++ b/substrate/client/block-builder/src/lib.rs @@ -37,7 +37,7 @@ use sp_core::traits::CallContext; use sp_runtime::{ legacy, traits::{Block as BlockT, Hash, HashingFor, Header as HeaderT, NumberFor, One}, - Digest, + Digest, ExtrinsicInclusionMode, }; use std::marker::PhantomData; @@ -198,10 +198,12 @@ pub struct BlockBuilder<'a, Block: BlockT, C: ProvideRuntimeApi + 'a> { extrinsics: Vec, api: ApiRef<'a, C::Api>, call_api_at: &'a C, + /// Version of the [`BlockBuilderApi`] runtime API. version: u32, parent_hash: Block::Hash, /// The estimated size of the block header. estimated_header_size: usize, + extrinsic_inclusion_mode: ExtrinsicInclusionMode, } impl<'a, Block, C> BlockBuilder<'a, Block, C> @@ -244,9 +246,19 @@ where api.set_call_context(CallContext::Onchain); - api.initialize_block(parent_hash, &header)?; + let core_version = api + .api_version::>(parent_hash)? + .ok_or_else(|| Error::VersionInvalid("Core".to_string()))?; - let version = api + let extrinsic_inclusion_mode = if core_version >= 5 { + api.initialize_block(parent_hash, &header)? + } else { + #[allow(deprecated)] + api.initialize_block_before_version_5(parent_hash, &header)?; + ExtrinsicInclusionMode::AllExtrinsics + }; + + let bb_version = api .api_version::>(parent_hash)? .ok_or_else(|| Error::VersionInvalid("BlockBuilderApi".to_string()))?; @@ -254,12 +266,18 @@ where parent_hash, extrinsics: Vec::new(), api, - version, + version: bb_version, estimated_header_size, call_api_at, + extrinsic_inclusion_mode, }) } + /// The extrinsic inclusion mode of the runtime for this block. + pub fn extrinsic_inclusion_mode(&self) -> ExtrinsicInclusionMode { + self.extrinsic_inclusion_mode + } + /// Push onto the block's list of extrinsics. /// /// This will ensure the extrinsic can be validly executed (by executing it). diff --git a/substrate/client/proposer-metrics/src/lib.rs b/substrate/client/proposer-metrics/src/lib.rs index 012e8ca769a..2856300cf80 100644 --- a/substrate/client/proposer-metrics/src/lib.rs +++ b/substrate/client/proposer-metrics/src/lib.rs @@ -44,11 +44,14 @@ impl MetricsLink { } /// The reason why proposing a block ended. +#[derive(Clone, Copy, PartialEq, Eq)] pub enum EndProposingReason { NoMoreTransactions, HitDeadline, HitBlockSizeLimit, HitBlockWeightLimit, + /// No transactions are allowed in the block. + TransactionForbidden, } /// Authorship metrics. @@ -112,6 +115,7 @@ impl Metrics { EndProposingReason::NoMoreTransactions => "no_more_transactions", EndProposingReason::HitBlockSizeLimit => "hit_block_size_limit", EndProposingReason::HitBlockWeightLimit => "hit_block_weight_limit", + EndProposingReason::TransactionForbidden => "transactions_forbidden", }; self.end_proposing_reason.with_label_values(&[reason]).inc(); diff --git a/substrate/client/rpc-spec-v2/src/chain_head/tests.rs b/substrate/client/rpc-spec-v2/src/chain_head/tests.rs index 9544736d84c..89d8c4ce271 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/tests.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/tests.rs @@ -242,12 +242,12 @@ async fn follow_with_runtime() { let event: FollowEvent = get_next_event(&mut sub).await; // it is basically json-encoded substrate_test_runtime_client::runtime::VERSION - let runtime_str = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":0,\ - \"specVersion\":2,\"implVersion\":2,\"apis\":[[\"0xdf6acb689907609b\",4],\ + let runtime_str = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":1,\ + \"specVersion\":2,\"implVersion\":2,\"apis\":[[\"0xdf6acb689907609b\",5],\ [\"0x37e397fc7c91f5e4\",2],[\"0xd2bc9897eed08f15\",3],[\"0x40fe3ad401f8959a\",6],\ [\"0xbc9d89904f5b923f\",1],[\"0xc6e9a76309f39b09\",2],[\"0xdd718d5cc53262d4\",1],\ [\"0xcbca25e39f142387\",2],[\"0xf78b278be53f454c\",2],[\"0xab3c0572291feb8b\",1],\ - [\"0xed99c5acb25eedf5\",3],[\"0xfbc577b9d747efd6\",1]],\"transactionVersion\":1,\"stateVersion\":0}"; + [\"0xed99c5acb25eedf5\",3],[\"0xfbc577b9d747efd6\",1]],\"transactionVersion\":1,\"stateVersion\":1}"; let runtime: RuntimeVersion = serde_json::from_str(runtime_str).unwrap(); diff --git a/substrate/client/rpc/src/state/tests.rs b/substrate/client/rpc/src/state/tests.rs index 96f4c1be960..dd866e671c5 100644 --- a/substrate/client/rpc/src/state/tests.rs +++ b/substrate/client/rpc/src/state/tests.rs @@ -475,7 +475,7 @@ async fn should_return_runtime_version() { // it is basically json-encoded substrate_test_runtime_client::runtime::VERSION let result = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":1,\ - \"specVersion\":2,\"implVersion\":2,\"apis\":[[\"0xdf6acb689907609b\",4],\ + \"specVersion\":2,\"implVersion\":2,\"apis\":[[\"0xdf6acb689907609b\",5],\ [\"0x37e397fc7c91f5e4\",2],[\"0xd2bc9897eed08f15\",3],[\"0x40fe3ad401f8959a\",6],\ [\"0xbc9d89904f5b923f\",1],[\"0xc6e9a76309f39b09\",2],[\"0xdd718d5cc53262d4\",1],\ [\"0xcbca25e39f142387\",2],[\"0xf78b278be53f454c\",2],[\"0xab3c0572291feb8b\",1],\ diff --git a/substrate/frame/executive/Cargo.toml b/substrate/frame/executive/Cargo.toml index a4ca265f617..63285e4cb49 100644 --- a/substrate/frame/executive/Cargo.toml +++ b/substrate/frame/executive/Cargo.toml @@ -16,6 +16,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] +aquamarine = "0.3.2" codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = [ "derive", ] } @@ -44,6 +45,7 @@ default = ["std"] with-tracing = ["sp-tracing/with-tracing"] std = [ "codec/std", + "frame-support/experimental", "frame-support/std", "frame-system/std", "frame-try-runtime/std", diff --git a/substrate/frame/executive/src/lib.rs b/substrate/frame/executive/src/lib.rs index 48ff675f808..3028eaf318e 100644 --- a/substrate/frame/executive/src/lib.rs +++ b/substrate/frame/executive/src/lib.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![cfg_attr(not(feature = "std"), no_std)] + //! # Executive Module //! //! The Executive module acts as the orchestration layer for the runtime. It dispatches incoming @@ -35,6 +37,8 @@ //! - Finalize a block. //! - Start an off-chain worker. //! +//! The flow of their application in a block is explained in the [block flowchart](block_flowchart). +//! //! ### Implementations //! //! The Executive module provides the following implementations: @@ -114,17 +118,51 @@ //! pub type Executive = executive::Executive; //! ``` -#![cfg_attr(not(feature = "std"), no_std)] +#[cfg(doc)] +#[cfg_attr(doc, aquamarine::aquamarine)] +/// # Block Execution +/// +/// These are the steps of block execution as done by [`Executive::execute_block`]. A block is +/// invalid if any of them fail. +/// +/// ```mermaid +/// flowchart TD +/// Executive::execute_block --> on_runtime_upgrade +/// on_runtime_upgrade --> System::initialize +/// Executive::initialize_block --> System::initialize +/// System::initialize --> on_initialize +/// on_initialize --> PreInherents[System::PreInherents] +/// PreInherents --> Inherents[Apply Inherents] +/// Inherents --> PostInherents[System::PostInherents] +/// PostInherents --> Check{MBM ongoing?} +/// Check -->|No| poll +/// Check -->|Yes| post_transactions_2[System::PostTransaction] +/// post_transactions_2 --> Step[MBMs::step] +/// Step --> on_finalize +/// poll --> transactions[Apply Transactions] +/// transactions --> post_transactions_1[System::PostTransaction] +/// post_transactions_1 --> CheckIdle{Weight remaining?} +/// CheckIdle -->|Yes| on_idle +/// CheckIdle -->|No| on_finalize +/// on_idle --> on_finalize +/// ``` +pub mod block_flowchart {} + +#[cfg(test)] +mod tests; use codec::{Codec, Encode}; use frame_support::{ + defensive_assert, dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, PostDispatchInfo}, + migrations::MultiStepMigrator, pallet_prelude::InvalidTransaction, traits::{ BeforeAllRuntimeMigrations, EnsureInherentsAreFirst, ExecuteBlock, OffchainWorker, - OnFinalize, OnIdle, OnInitialize, OnRuntimeUpgrade, + OnFinalize, OnIdle, OnInitialize, OnPoll, OnRuntimeUpgrade, PostInherents, + PostTransactions, PreInherents, }, - weights::Weight, + weights::{Weight, WeightMeter}, }; use frame_system::pallet_prelude::BlockNumberFor; use sp_runtime::{ @@ -134,7 +172,7 @@ use sp_runtime::{ ValidateUnsigned, Zero, }, transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, + ApplyExtrinsicResult, ExtrinsicInclusionMode, }; use sp_std::{marker::PhantomData, prelude::*}; @@ -198,7 +236,8 @@ impl< + OnInitialize> + OnIdle> + OnFinalize> - + OffchainWorker>, + + OffchainWorker> + + OnPoll>, COnRuntimeUpgrade: OnRuntimeUpgrade, > ExecuteBlock for Executive @@ -237,6 +276,7 @@ impl< + OnIdle> + OnFinalize> + OffchainWorker> + + OnPoll> + TryState> + TryDecodeEntireStorage, COnRuntimeUpgrade: OnRuntimeUpgrade, @@ -272,36 +312,50 @@ where select, ); - Self::initialize_block(block.header()); - Self::initial_checks(&block); - + let mode = Self::initialize_block(block.header()); + let num_inherents = Self::initial_checks(&block) as usize; let (header, extrinsics) = block.deconstruct(); + // Check if there are any forbidden non-inherents in the block. + if mode == ExtrinsicInclusionMode::OnlyInherents && extrinsics.len() > num_inherents { + return Err("Only inherents allowed".into()) + } + let try_apply_extrinsic = |uxt: Block::Extrinsic| -> ApplyExtrinsicResult { sp_io::init_tracing(); let encoded = uxt.encode(); let encoded_len = encoded.len(); + let is_inherent = System::is_inherent(&uxt); // skip signature verification. let xt = if signature_check { uxt.check(&Default::default()) } else { uxt.unchecked_into_checked_i_know_what_i_am_doing(&Default::default()) }?; - >::note_extrinsic(encoded); let dispatch_info = xt.get_dispatch_info(); + if !is_inherent && !>::inherents_applied() { + Self::inherents_applied(); + } + + >::note_extrinsic(encoded); let r = Applyable::apply::(xt, &dispatch_info, encoded_len)?; + if r.is_err() && dispatch_info.class == DispatchClass::Mandatory { + return Err(InvalidTransaction::BadMandatory.into()) + } + >::note_applied_extrinsic(&r, dispatch_info); Ok(r.map(|_| ()).map_err(|e| e.error)) }; - for e in extrinsics { + // Apply extrinsics: + for e in extrinsics.iter() { if let Err(err) = try_apply_extrinsic(e.clone()) { log::error!( - target: LOG_TARGET, "executing transaction {:?} failed due to {:?}. Aborting the rest of the block execution.", + target: LOG_TARGET, "transaction {:?} failed due to {:?}. Aborting the rest of the block execution.", e, err, ); @@ -309,9 +363,17 @@ where } } + // In this case there were no transactions to trigger this state transition: + if !>::inherents_applied() { + Self::inherents_applied(); + } + // post-extrinsics book-keeping >::note_finished_extrinsics(); - Self::idle_and_finalize_hook(*header.number()); + ::PostTransactions::post_transactions(); + + Self::on_idle_hook(*header.number()); + Self::on_finalize_hook(*header.number()); // run the try-state checks of all pallets, ensuring they don't alter any state. let _guard = frame_support::StorageNoopGuard::default(); @@ -449,7 +511,8 @@ impl< + OnInitialize> + OnIdle> + OnFinalize> - + OffchainWorker>, + + OffchainWorker> + + OnPoll>, COnRuntimeUpgrade: OnRuntimeUpgrade, > Executive where @@ -464,16 +527,36 @@ where pub fn execute_on_runtime_upgrade() -> Weight { let before_all_weight = ::before_all_runtime_migrations(); - <(COnRuntimeUpgrade, AllPalletsWithSystem) as OnRuntimeUpgrade>::on_runtime_upgrade() - .saturating_add(before_all_weight) + + let runtime_upgrade_weight = <( + COnRuntimeUpgrade, + ::SingleBlockMigrations, + // We want to run the migrations before we call into the pallets as they may + // access any state that would then not be migrated. + AllPalletsWithSystem, + ) as OnRuntimeUpgrade>::on_runtime_upgrade(); + + before_all_weight.saturating_add(runtime_upgrade_weight) } /// Start the execution of a particular block. - pub fn initialize_block(header: &frame_system::pallet_prelude::HeaderFor) { + pub fn initialize_block( + header: &frame_system::pallet_prelude::HeaderFor, + ) -> ExtrinsicInclusionMode { sp_io::init_tracing(); sp_tracing::enter_span!(sp_tracing::Level::TRACE, "init_block"); let digests = Self::extract_pre_digest(header); Self::initialize_block_impl(header.number(), header.parent_hash(), &digests); + + Self::extrinsic_mode() + } + + fn extrinsic_mode() -> ExtrinsicInclusionMode { + if ::MultiBlockMigrator::ongoing() { + ExtrinsicInclusionMode::OnlyInherents + } else { + ExtrinsicInclusionMode::AllExtrinsics + } } fn extract_pre_digest(header: &frame_system::pallet_prelude::HeaderFor) -> Digest { @@ -519,6 +602,7 @@ where ); frame_system::Pallet::::note_finished_initialize(); + ::PreInherents::pre_inherents(); } /// Returns if the runtime has been upgraded, based on [`frame_system::LastRuntimeUpgrade`]. @@ -529,7 +613,8 @@ where last.map(|v| v.was_upgraded(¤t)).unwrap_or(true) } - fn initial_checks(block: &Block) { + /// Returns the number of inherents in the block. + fn initial_checks(block: &Block) -> u32 { sp_tracing::enter_span!(sp_tracing::Level::TRACE, "initial_checks"); let header = block.header(); @@ -542,8 +627,9 @@ where "Parent hash should be valid.", ); - if let Err(i) = System::ensure_inherents_are_first(block) { - panic!("Invalid inherent position for extrinsic at index {}", i); + match System::ensure_inherents_are_first(block) { + Ok(num) => num, + Err(i) => panic!("Invalid inherent position for extrinsic at index {}", i), } } @@ -552,53 +638,90 @@ where sp_io::init_tracing(); sp_tracing::within_span! { sp_tracing::info_span!("execute_block", ?block); + // Execute `on_runtime_upgrade` and `on_initialize`. + let mode = Self::initialize_block(block.header()); + let num_inherents = Self::initial_checks(&block) as usize; + let (header, extrinsics) = block.deconstruct(); + let num_extrinsics = extrinsics.len(); - Self::initialize_block(block.header()); + if mode == ExtrinsicInclusionMode::OnlyInherents && num_extrinsics > num_inherents { + // Invalid block + panic!("Only inherents are allowed in this block") + } - // any initial checks - Self::initial_checks(&block); + Self::apply_extrinsics(extrinsics.into_iter()); - // execute extrinsics - let (header, extrinsics) = block.deconstruct(); - Self::execute_extrinsics_with_book_keeping(extrinsics, *header.number()); + // In this case there were no transactions to trigger this state transition: + if !>::inherents_applied() { + defensive_assert!(num_inherents == num_extrinsics); + Self::inherents_applied(); + } - // any final checks + >::note_finished_extrinsics(); + ::PostTransactions::post_transactions(); + + Self::on_idle_hook(*header.number()); + Self::on_finalize_hook(*header.number()); Self::final_checks(&header); } } - /// Execute given extrinsics and take care of post-extrinsics book-keeping. - fn execute_extrinsics_with_book_keeping( - extrinsics: Vec, - block_number: NumberFor, - ) { + /// Logic that runs directly after inherent application. + /// + /// It advances the Multi-Block-Migrations or runs the `on_poll` hook. + pub fn inherents_applied() { + >::note_inherents_applied(); + ::PostInherents::post_inherents(); + + if ::MultiBlockMigrator::ongoing() { + let used_weight = ::MultiBlockMigrator::step(); + >::register_extra_weight_unchecked( + used_weight, + DispatchClass::Mandatory, + ); + } else { + let block_number = >::block_number(); + Self::on_poll_hook(block_number); + } + } + + /// Execute given extrinsics. + fn apply_extrinsics(extrinsics: impl Iterator) { extrinsics.into_iter().for_each(|e| { if let Err(e) = Self::apply_extrinsic(e) { let err: &'static str = e.into(); panic!("{}", err) } }); - - // post-extrinsics book-keeping - >::note_finished_extrinsics(); - - Self::idle_and_finalize_hook(block_number); } /// Finalize the block - it is up the caller to ensure that all header fields are valid /// except state-root. + // Note: Only used by the block builder - not Executive itself. pub fn finalize_block() -> frame_system::pallet_prelude::HeaderFor { sp_io::init_tracing(); sp_tracing::enter_span!(sp_tracing::Level::TRACE, "finalize_block"); - >::note_finished_extrinsics(); - let block_number = >::block_number(); - Self::idle_and_finalize_hook(block_number); + // In this case there were no transactions to trigger this state transition: + if !>::inherents_applied() { + Self::inherents_applied(); + } + >::note_finished_extrinsics(); + ::PostTransactions::post_transactions(); + let block_number = >::block_number(); + Self::on_idle_hook(block_number); + Self::on_finalize_hook(block_number); >::finalize() } - fn idle_and_finalize_hook(block_number: NumberFor) { + /// Run the `on_idle` hook of all pallet, but only if there is weight remaining and there are no + /// ongoing MBMs. + fn on_idle_hook(block_number: NumberFor) { + if ::MultiBlockMigrator::ongoing() { + return + } + let weight = >::block_weight(); let max_weight = >::get().max_block; let remaining_weight = max_weight.saturating_sub(weight.total()); @@ -613,7 +736,33 @@ where DispatchClass::Mandatory, ); } + } + + fn on_poll_hook(block_number: NumberFor) { + defensive_assert!( + !::MultiBlockMigrator::ongoing(), + "on_poll should not be called during migrations" + ); + let weight = >::block_weight(); + let max_weight = >::get().max_block; + let remaining = max_weight.saturating_sub(weight.total()); + + if remaining.all_gt(Weight::zero()) { + let mut meter = WeightMeter::with_limit(remaining); + >>::on_poll( + block_number, + &mut meter, + ); + >::register_extra_weight_unchecked( + meter.consumed(), + DispatchClass::Mandatory, + ); + } + } + + /// Run the `on_finalize` hook of all pallet. + fn on_finalize_hook(block_number: NumberFor) { >>::on_finalize(block_number); } @@ -627,8 +776,18 @@ where let encoded_len = encoded.len(); sp_tracing::enter_span!(sp_tracing::info_span!("apply_extrinsic", ext=?sp_core::hexdisplay::HexDisplay::from(&encoded))); + + // We use the dedicated `is_inherent` check here, since just relying on `Mandatory` dispatch + // class does not capture optional inherents. + let is_inherent = System::is_inherent(&uxt); + // Verify that the signature is good. let xt = uxt.check(&Default::default())?; + let dispatch_info = xt.get_dispatch_info(); + + if !is_inherent && !>::inherents_applied() { + Self::inherents_applied(); + } // We don't need to make sure to `note_extrinsic` only after we know it's going to be // executed to prevent it from leaking in storage since at this point, it will either @@ -637,8 +796,6 @@ where // AUDIT: Under no circumstances may this function panic from here onwards. - // Decode parameters and dispatch - let dispatch_info = xt.get_dispatch_info(); let r = Applyable::apply::(xt, &dispatch_info, encoded_len)?; // Mandatory(inherents) are not allowed to fail. @@ -745,956 +902,3 @@ where ) } } - -#[cfg(test)] -mod tests { - use super::*; - - use sp_core::H256; - use sp_runtime::{ - generic::{DigestItem, Era}, - testing::{Block, Digest, Header}, - traits::{BlakeTwo256, Block as BlockT, Header as HeaderT, IdentityLookup}, - transaction_validity::{ - InvalidTransaction, TransactionValidityError, UnknownTransaction, ValidTransaction, - }, - BuildStorage, DispatchError, - }; - - use frame_support::{ - assert_err, derive_impl, parameter_types, - traits::{fungible, ConstU32, ConstU64, ConstU8, Currency}, - weights::{ConstantMultiplier, IdentityFee, RuntimeDbWeight, Weight, WeightToFee}, - }; - use frame_system::{ChainContext, LastRuntimeUpgrade, LastRuntimeUpgradeInfo}; - use pallet_balances::Call as BalancesCall; - use pallet_transaction_payment::CurrencyAdapter; - - const TEST_KEY: &[u8] = b":test:key:"; - - #[frame_support::pallet(dev_mode)] - mod custom { - use frame_support::pallet_prelude::*; - use frame_system::pallet_prelude::*; - - #[pallet::pallet] - pub struct Pallet(_); - - #[pallet::config] - pub trait Config: frame_system::Config {} - - #[pallet::hooks] - impl Hooks> for Pallet { - // module hooks. - // one with block number arg and one without - fn on_initialize(n: BlockNumberFor) -> Weight { - println!("on_initialize({})", n); - Weight::from_parts(175, 0) - } - - fn on_idle(n: BlockNumberFor, remaining_weight: Weight) -> Weight { - println!("on_idle{}, {})", n, remaining_weight); - Weight::from_parts(175, 0) - } - - fn on_finalize(n: BlockNumberFor) { - println!("on_finalize({})", n); - } - - fn on_runtime_upgrade() -> Weight { - sp_io::storage::set(super::TEST_KEY, "module".as_bytes()); - Weight::from_parts(200, 0) - } - - fn offchain_worker(n: BlockNumberFor) { - assert_eq!(BlockNumberFor::::from(1u32), n); - } - } - - #[pallet::call] - impl Pallet { - pub fn some_function(origin: OriginFor) -> DispatchResult { - // NOTE: does not make any different. - frame_system::ensure_signed(origin)?; - Ok(()) - } - - #[pallet::weight((200, DispatchClass::Operational))] - pub fn some_root_operation(origin: OriginFor) -> DispatchResult { - frame_system::ensure_root(origin)?; - Ok(()) - } - - pub fn some_unsigned_message(origin: OriginFor) -> DispatchResult { - frame_system::ensure_none(origin)?; - Ok(()) - } - - pub fn allowed_unsigned(origin: OriginFor) -> DispatchResult { - frame_system::ensure_root(origin)?; - Ok(()) - } - - pub fn unallowed_unsigned(origin: OriginFor) -> DispatchResult { - frame_system::ensure_root(origin)?; - Ok(()) - } - - #[pallet::weight((0, DispatchClass::Mandatory))] - pub fn inherent_call(origin: OriginFor) -> DispatchResult { - frame_system::ensure_none(origin)?; - Ok(()) - } - - pub fn calculate_storage_root(_origin: OriginFor) -> DispatchResult { - let root = sp_io::storage::root(sp_runtime::StateVersion::V1); - sp_io::storage::set("storage_root".as_bytes(), &root); - Ok(()) - } - } - - #[pallet::inherent] - impl ProvideInherent for Pallet { - type Call = Call; - - type Error = sp_inherents::MakeFatalError<()>; - - const INHERENT_IDENTIFIER: [u8; 8] = *b"test1234"; - - fn create_inherent(_data: &InherentData) -> Option { - None - } - - fn is_inherent(call: &Self::Call) -> bool { - *call == Call::::inherent_call {} - } - } - - #[pallet::validate_unsigned] - impl ValidateUnsigned for Pallet { - type Call = Call; - - // Inherent call is accepted for being dispatched - fn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError> { - match call { - Call::allowed_unsigned { .. } => Ok(()), - Call::inherent_call { .. } => Ok(()), - _ => Err(UnknownTransaction::NoUnsignedValidator.into()), - } - } - - // Inherent call is not validated as unsigned - fn validate_unsigned( - _source: TransactionSource, - call: &Self::Call, - ) -> TransactionValidity { - match call { - Call::allowed_unsigned { .. } => Ok(Default::default()), - _ => UnknownTransaction::NoUnsignedValidator.into(), - } - } - } - } - - frame_support::construct_runtime!( - pub enum Runtime { - System: frame_system, - Balances: pallet_balances, - TransactionPayment: pallet_transaction_payment, - Custom: custom, - } - ); - - parameter_types! { - pub BlockWeights: frame_system::limits::BlockWeights = - frame_system::limits::BlockWeights::builder() - .base_block(Weight::from_parts(10, 0)) - .for_class(DispatchClass::all(), |weights| weights.base_extrinsic = Weight::from_parts(5, 0)) - .for_class(DispatchClass::non_mandatory(), |weights| weights.max_total = Weight::from_parts(1024, u64::MAX).into()) - .build_or_panic(); - pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight { - read: 10, - write: 100, - }; - } - #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] - impl frame_system::Config for Runtime { - type BaseCallFilter = frame_support::traits::Everything; - type BlockWeights = BlockWeights; - type BlockLength = (); - type DbWeight = (); - type RuntimeOrigin = RuntimeOrigin; - type Nonce = u64; - type RuntimeCall = RuntimeCall; - type Hash = sp_core::H256; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; - type Block = TestBlock; - type RuntimeEvent = RuntimeEvent; - type BlockHashCount = ConstU64<250>; - type Version = RuntimeVersion; - type PalletInfo = PalletInfo; - type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = (); - type OnSetCode = (); - type MaxConsumers = ConstU32<16>; - } - - type Balance = u64; - impl pallet_balances::Config for Runtime { - type Balance = Balance; - type RuntimeEvent = RuntimeEvent; - type DustRemoval = (); - type ExistentialDeposit = ConstU64<1>; - type AccountStore = System; - type MaxLocks = (); - type MaxReserves = (); - type ReserveIdentifier = [u8; 8]; - type WeightInfo = (); - type FreezeIdentifier = (); - type MaxFreezes = ConstU32<1>; - type RuntimeHoldReason = (); - type RuntimeFreezeReason = (); - } - - parameter_types! { - pub const TransactionByteFee: Balance = 0; - } - impl pallet_transaction_payment::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type OnChargeTransaction = CurrencyAdapter; - type OperationalFeeMultiplier = ConstU8<5>; - type WeightToFee = IdentityFee; - type LengthToFee = ConstantMultiplier; - type FeeMultiplierUpdate = (); - } - impl custom::Config for Runtime {} - - pub struct RuntimeVersion; - impl frame_support::traits::Get for RuntimeVersion { - fn get() -> sp_version::RuntimeVersion { - RuntimeVersionTestValues::get().clone() - } - } - - parameter_types! { - pub static RuntimeVersionTestValues: sp_version::RuntimeVersion = - Default::default(); - } - - type SignedExtra = ( - frame_system::CheckEra, - frame_system::CheckNonce, - frame_system::CheckWeight, - pallet_transaction_payment::ChargeTransactionPayment, - ); - type TestXt = sp_runtime::testing::TestXt; - type TestBlock = Block; - - // Will contain `true` when the custom runtime logic was called. - const CUSTOM_ON_RUNTIME_KEY: &[u8] = b":custom:on_runtime"; - - struct CustomOnRuntimeUpgrade; - impl OnRuntimeUpgrade for CustomOnRuntimeUpgrade { - fn on_runtime_upgrade() -> Weight { - sp_io::storage::set(TEST_KEY, "custom_upgrade".as_bytes()); - sp_io::storage::set(CUSTOM_ON_RUNTIME_KEY, &true.encode()); - System::deposit_event(frame_system::Event::CodeUpdated); - - assert_eq!(0, System::last_runtime_upgrade_spec_version()); - - Weight::from_parts(100, 0) - } - } - - type Executive = super::Executive< - Runtime, - Block, - ChainContext, - Runtime, - AllPalletsWithSystem, - CustomOnRuntimeUpgrade, - >; - - fn extra(nonce: u64, fee: Balance) -> SignedExtra { - ( - frame_system::CheckEra::from(Era::Immortal), - frame_system::CheckNonce::from(nonce), - frame_system::CheckWeight::new(), - pallet_transaction_payment::ChargeTransactionPayment::from(fee), - ) - } - - fn sign_extra(who: u64, nonce: u64, fee: Balance) -> Option<(u64, SignedExtra)> { - Some((who, extra(nonce, fee))) - } - - fn call_transfer(dest: u64, value: u64) -> RuntimeCall { - RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest, value }) - } - - #[test] - fn balance_transfer_dispatch_works() { - let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(1, 211)] } - .assimilate_storage(&mut t) - .unwrap(); - let xt = TestXt::new(call_transfer(2, 69), sign_extra(1, 0, 0)); - let weight = xt.get_dispatch_info().weight + - ::BlockWeights::get() - .get(DispatchClass::Normal) - .base_extrinsic; - let fee: Balance = - ::WeightToFee::weight_to_fee(&weight); - let mut t = sp_io::TestExternalities::new(t); - t.execute_with(|| { - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - let r = Executive::apply_extrinsic(xt); - assert!(r.is_ok()); - assert_eq!(>::total_balance(&1), 142 - fee); - assert_eq!(>::total_balance(&2), 69); - }); - } - - fn new_test_ext(balance_factor: Balance) -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(1, 111 * balance_factor)] } - .assimilate_storage(&mut t) - .unwrap(); - t.into() - } - - fn new_test_ext_v0(balance_factor: Balance) -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(1, 111 * balance_factor)] } - .assimilate_storage(&mut t) - .unwrap(); - (t, sp_runtime::StateVersion::V0).into() - } - - #[test] - fn block_import_works() { - block_import_works_inner( - new_test_ext_v0(1), - array_bytes::hex_n_into_unchecked( - "65e953676859e7a33245908af7ad3637d6861eb90416d433d485e95e2dd174a1", - ), - ); - block_import_works_inner( - new_test_ext(1), - array_bytes::hex_n_into_unchecked( - "5a19b3d6fdb7241836349fdcbe2d9df4d4f945b949d979e31ad50bff1cbcd1c2", - ), - ); - } - fn block_import_works_inner(mut ext: sp_io::TestExternalities, state_root: H256) { - ext.execute_with(|| { - Executive::execute_block(Block { - header: Header { - parent_hash: [69u8; 32].into(), - number: 1, - state_root, - extrinsics_root: array_bytes::hex_n_into_unchecked( - "03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314", - ), - digest: Digest { logs: vec![] }, - }, - extrinsics: vec![], - }); - }); - } - - #[test] - #[should_panic] - fn block_import_of_bad_state_root_fails() { - new_test_ext(1).execute_with(|| { - Executive::execute_block(Block { - header: Header { - parent_hash: [69u8; 32].into(), - number: 1, - state_root: [0u8; 32].into(), - extrinsics_root: array_bytes::hex_n_into_unchecked( - "03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314", - ), - digest: Digest { logs: vec![] }, - }, - extrinsics: vec![], - }); - }); - } - - #[test] - #[should_panic] - fn block_import_of_bad_extrinsic_root_fails() { - new_test_ext(1).execute_with(|| { - Executive::execute_block(Block { - header: Header { - parent_hash: [69u8; 32].into(), - number: 1, - state_root: array_bytes::hex_n_into_unchecked( - "75e7d8f360d375bbe91bcf8019c01ab6362448b4a89e3b329717eb9d910340e5", - ), - extrinsics_root: [0u8; 32].into(), - digest: Digest { logs: vec![] }, - }, - extrinsics: vec![], - }); - }); - } - - #[test] - fn bad_extrinsic_not_inserted() { - let mut t = new_test_ext(1); - // bad nonce check! - let xt = TestXt::new(call_transfer(33, 69), sign_extra(1, 30, 0)); - t.execute_with(|| { - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - assert_err!( - Executive::apply_extrinsic(xt), - TransactionValidityError::Invalid(InvalidTransaction::Future) - ); - assert_eq!(>::extrinsic_index(), Some(0)); - }); - } - - #[test] - fn block_weight_limit_enforced() { - let mut t = new_test_ext(10000); - // given: TestXt uses the encoded len as fixed Len: - let xt = TestXt::new( - RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - sign_extra(1, 0, 0), - ); - let encoded = xt.encode(); - let encoded_len = encoded.len() as u64; - // on_initialize weight + base block execution weight - let block_weights = ::BlockWeights::get(); - let base_block_weight = Weight::from_parts(175, 0) + block_weights.base_block; - let limit = block_weights.get(DispatchClass::Normal).max_total.unwrap() - base_block_weight; - let num_to_exhaust_block = limit.ref_time() / (encoded_len + 5); - t.execute_with(|| { - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - // Base block execution weight + `on_initialize` weight from the custom module. - assert_eq!(>::block_weight().total(), base_block_weight); - - for nonce in 0..=num_to_exhaust_block { - let xt = TestXt::new( - RuntimeCall::Balances(BalancesCall::transfer_allow_death { - dest: 33, - value: 0, - }), - sign_extra(1, nonce.into(), 0), - ); - let res = Executive::apply_extrinsic(xt); - if nonce != num_to_exhaust_block { - assert!(res.is_ok()); - assert_eq!( - >::block_weight().total(), - //--------------------- on_initialize + block_execution + extrinsic_base weight - Weight::from_parts((encoded_len + 5) * (nonce + 1), 0) + base_block_weight, - ); - assert_eq!( - >::extrinsic_index(), - Some(nonce as u32 + 1) - ); - } else { - assert_eq!(res, Err(InvalidTransaction::ExhaustsResources.into())); - } - } - }); - } - - #[test] - fn block_weight_and_size_is_stored_per_tx() { - let xt = TestXt::new( - RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - sign_extra(1, 0, 0), - ); - let x1 = TestXt::new( - RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - sign_extra(1, 1, 0), - ); - let x2 = TestXt::new( - RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - sign_extra(1, 2, 0), - ); - let len = xt.clone().encode().len() as u32; - let mut t = new_test_ext(1); - t.execute_with(|| { - // Block execution weight + on_initialize weight from custom module - let base_block_weight = Weight::from_parts(175, 0) + - ::BlockWeights::get().base_block; - - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - assert_eq!(>::block_weight().total(), base_block_weight); - assert_eq!(>::all_extrinsics_len(), 0); - - assert!(Executive::apply_extrinsic(xt.clone()).unwrap().is_ok()); - assert!(Executive::apply_extrinsic(x1.clone()).unwrap().is_ok()); - assert!(Executive::apply_extrinsic(x2.clone()).unwrap().is_ok()); - - // default weight for `TestXt` == encoded length. - let extrinsic_weight = Weight::from_parts(len as u64, 0) + - ::BlockWeights::get() - .get(DispatchClass::Normal) - .base_extrinsic; - assert_eq!( - >::block_weight().total(), - base_block_weight + 3u64 * extrinsic_weight, - ); - assert_eq!(>::all_extrinsics_len(), 3 * len); - - let _ = >::finalize(); - // All extrinsics length cleaned on `System::finalize` - assert_eq!(>::all_extrinsics_len(), 0); - - // New Block - Executive::initialize_block(&Header::new( - 2, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - // Block weight cleaned up on `System::initialize` - assert_eq!(>::block_weight().total(), base_block_weight); - }); - } - - #[test] - fn validate_unsigned() { - let valid = TestXt::new(RuntimeCall::Custom(custom::Call::allowed_unsigned {}), None); - let invalid = TestXt::new(RuntimeCall::Custom(custom::Call::unallowed_unsigned {}), None); - let mut t = new_test_ext(1); - - t.execute_with(|| { - assert_eq!( - Executive::validate_transaction( - TransactionSource::InBlock, - valid.clone(), - Default::default(), - ), - Ok(ValidTransaction::default()), - ); - assert_eq!( - Executive::validate_transaction( - TransactionSource::InBlock, - invalid.clone(), - Default::default(), - ), - Err(TransactionValidityError::Unknown(UnknownTransaction::NoUnsignedValidator)), - ); - assert_eq!(Executive::apply_extrinsic(valid), Ok(Err(DispatchError::BadOrigin))); - assert_eq!( - Executive::apply_extrinsic(invalid), - Err(TransactionValidityError::Unknown(UnknownTransaction::NoUnsignedValidator)) - ); - }); - } - - #[test] - fn can_not_pay_for_tx_fee_on_full_lock() { - let mut t = new_test_ext(1); - t.execute_with(|| { - as fungible::MutateFreeze>::set_freeze( - &(), - &1, - 110, - ) - .unwrap(); - let xt = TestXt::new( - RuntimeCall::System(frame_system::Call::remark { remark: vec![1u8] }), - sign_extra(1, 0, 0), - ); - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - assert_eq!(Executive::apply_extrinsic(xt), Err(InvalidTransaction::Payment.into()),); - assert_eq!(>::total_balance(&1), 111); - }); - } - - #[test] - fn block_hooks_weight_is_stored() { - new_test_ext(1).execute_with(|| { - Executive::initialize_block(&Header::new_from_number(1)); - Executive::finalize_block(); - // NOTE: might need updates over time if new weights are introduced. - // For now it only accounts for the base block execution weight and - // the `on_initialize` weight defined in the custom test module. - assert_eq!( - >::block_weight().total(), - Weight::from_parts(175 + 175 + 10, 0) - ); - }) - } - - #[test] - fn runtime_upgraded_should_work() { - new_test_ext(1).execute_with(|| { - RuntimeVersionTestValues::mutate(|v| *v = Default::default()); - // It should be added at genesis - assert!(LastRuntimeUpgrade::::exists()); - assert!(!Executive::runtime_upgraded()); - - RuntimeVersionTestValues::mutate(|v| { - *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } - }); - assert!(Executive::runtime_upgraded()); - - RuntimeVersionTestValues::mutate(|v| { - *v = sp_version::RuntimeVersion { - spec_version: 1, - spec_name: "test".into(), - ..Default::default() - } - }); - assert!(Executive::runtime_upgraded()); - - RuntimeVersionTestValues::mutate(|v| { - *v = sp_version::RuntimeVersion { - spec_version: 0, - impl_version: 2, - ..Default::default() - } - }); - assert!(!Executive::runtime_upgraded()); - - LastRuntimeUpgrade::::take(); - assert!(Executive::runtime_upgraded()); - }) - } - - #[test] - fn last_runtime_upgrade_was_upgraded_works() { - let test_data = vec![ - (0, "", 1, "", true), - (1, "", 1, "", false), - (1, "", 1, "test", true), - (1, "", 0, "", false), - (1, "", 0, "test", true), - ]; - - for (spec_version, spec_name, c_spec_version, c_spec_name, result) in test_data { - let current = sp_version::RuntimeVersion { - spec_version: c_spec_version, - spec_name: c_spec_name.into(), - ..Default::default() - }; - - let last = LastRuntimeUpgradeInfo { - spec_version: spec_version.into(), - spec_name: spec_name.into(), - }; - - assert_eq!(result, last.was_upgraded(¤t)); - } - } - - #[test] - fn custom_runtime_upgrade_is_called_before_modules() { - new_test_ext(1).execute_with(|| { - // Make sure `on_runtime_upgrade` is called. - RuntimeVersionTestValues::mutate(|v| { - *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } - }); - - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - assert_eq!(&sp_io::storage::get(TEST_KEY).unwrap()[..], *b"module"); - assert_eq!(sp_io::storage::get(CUSTOM_ON_RUNTIME_KEY).unwrap(), true.encode()); - assert_eq!( - Some(RuntimeVersionTestValues::get().into()), - LastRuntimeUpgrade::::get(), - ) - }); - } - - #[test] - fn event_from_runtime_upgrade_is_included() { - new_test_ext(1).execute_with(|| { - // Make sure `on_runtime_upgrade` is called. - RuntimeVersionTestValues::mutate(|v| { - *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } - }); - - // set block number to non zero so events are not excluded - System::set_block_number(1); - - Executive::initialize_block(&Header::new( - 2, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - System::assert_last_event(frame_system::Event::::CodeUpdated.into()); - }); - } - - /// Regression test that ensures that the custom on runtime upgrade is called when executive is - /// used through the `ExecuteBlock` trait. - #[test] - fn custom_runtime_upgrade_is_called_when_using_execute_block_trait() { - let xt = TestXt::new( - RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - sign_extra(1, 0, 0), - ); - - let header = new_test_ext(1).execute_with(|| { - // Make sure `on_runtime_upgrade` is called. - RuntimeVersionTestValues::mutate(|v| { - *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } - }); - - // Let's build some fake block. - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - Executive::apply_extrinsic(xt.clone()).unwrap().unwrap(); - - Executive::finalize_block() - }); - - // Reset to get the correct new genesis below. - RuntimeVersionTestValues::mutate(|v| { - *v = sp_version::RuntimeVersion { spec_version: 0, ..Default::default() } - }); - - new_test_ext(1).execute_with(|| { - // Make sure `on_runtime_upgrade` is called. - RuntimeVersionTestValues::mutate(|v| { - *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } - }); - - >>::execute_block(Block::new(header, vec![xt])); - - assert_eq!(&sp_io::storage::get(TEST_KEY).unwrap()[..], *b"module"); - assert_eq!(sp_io::storage::get(CUSTOM_ON_RUNTIME_KEY).unwrap(), true.encode()); - }); - } - - #[test] - fn all_weights_are_recorded_correctly() { - // Reset to get the correct new genesis below. - RuntimeVersionTestValues::take(); - - new_test_ext(1).execute_with(|| { - // Make sure `on_runtime_upgrade` is called for maximum complexity - RuntimeVersionTestValues::mutate(|v| { - *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } - }); - - let block_number = 1; - - Executive::initialize_block(&Header::new( - block_number, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - // Reset the last runtime upgrade info, to make the second call to `on_runtime_upgrade` - // succeed. - LastRuntimeUpgrade::::take(); - - // All weights that show up in the `initialize_block_impl` - let custom_runtime_upgrade_weight = CustomOnRuntimeUpgrade::on_runtime_upgrade(); - let runtime_upgrade_weight = - ::on_runtime_upgrade(); - let on_initialize_weight = - >::on_initialize(block_number); - let base_block_weight = - ::BlockWeights::get().base_block; - - // Weights are recorded correctly - assert_eq!( - frame_system::Pallet::::block_weight().total(), - custom_runtime_upgrade_weight + - runtime_upgrade_weight + - on_initialize_weight + base_block_weight, - ); - }); - } - - #[test] - fn offchain_worker_works_as_expected() { - new_test_ext(1).execute_with(|| { - let parent_hash = sp_core::H256::from([69u8; 32]); - let mut digest = Digest::default(); - digest.push(DigestItem::Seal([1, 2, 3, 4], vec![5, 6, 7, 8])); - - let header = - Header::new(1, H256::default(), H256::default(), parent_hash, digest.clone()); - - Executive::offchain_worker(&header); - - assert_eq!(digest, System::digest()); - assert_eq!(parent_hash, System::block_hash(0)); - assert_eq!(header.hash(), System::block_hash(1)); - }); - } - - #[test] - fn calculating_storage_root_twice_works() { - let call = RuntimeCall::Custom(custom::Call::calculate_storage_root {}); - let xt = TestXt::new(call, sign_extra(1, 0, 0)); - - let header = new_test_ext(1).execute_with(|| { - // Let's build some fake block. - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - Executive::apply_extrinsic(xt.clone()).unwrap().unwrap(); - - Executive::finalize_block() - }); - - new_test_ext(1).execute_with(|| { - Executive::execute_block(Block::new(header, vec![xt])); - }); - } - - #[test] - #[should_panic(expected = "Invalid inherent position for extrinsic at index 1")] - fn invalid_inherent_position_fail() { - let xt1 = TestXt::new( - RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - sign_extra(1, 0, 0), - ); - let xt2 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent_call {}), None); - - let header = new_test_ext(1).execute_with(|| { - // Let's build some fake block. - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); - Executive::apply_extrinsic(xt2.clone()).unwrap().unwrap(); - - Executive::finalize_block() - }); - - new_test_ext(1).execute_with(|| { - Executive::execute_block(Block::new(header, vec![xt1, xt2])); - }); - } - - #[test] - fn valid_inherents_position_works() { - let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent_call {}), None); - let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); - - let header = new_test_ext(1).execute_with(|| { - // Let's build some fake block. - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); - Executive::apply_extrinsic(xt2.clone()).unwrap().unwrap(); - - Executive::finalize_block() - }); - - new_test_ext(1).execute_with(|| { - Executive::execute_block(Block::new(header, vec![xt1, xt2])); - }); - } - - #[test] - #[should_panic(expected = "A call was labelled as mandatory, but resulted in an Error.")] - fn invalid_inherents_fail_block_execution() { - let xt1 = - TestXt::new(RuntimeCall::Custom(custom::Call::inherent_call {}), sign_extra(1, 0, 0)); - - new_test_ext(1).execute_with(|| { - Executive::execute_block(Block::new( - Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - ), - vec![xt1], - )); - }); - } - - // Inherents are created by the runtime and don't need to be validated. - #[test] - fn inherents_fail_validate_block() { - let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent_call {}), None); - - new_test_ext(1).execute_with(|| { - assert_eq!( - Executive::validate_transaction(TransactionSource::External, xt1, H256::random()) - .unwrap_err(), - InvalidTransaction::MandatoryValidation.into() - ); - }) - } -} diff --git a/substrate/frame/executive/src/tests.rs b/substrate/frame/executive/src/tests.rs new file mode 100644 index 00000000000..70b55f6e855 --- /dev/null +++ b/substrate/frame/executive/src/tests.rs @@ -0,0 +1,1389 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Test the `frame-executive` crate. + +use super::*; + +use sp_core::H256; +use sp_runtime::{ + generic::{DigestItem, Era}, + testing::{Block, Digest, Header}, + traits::{Block as BlockT, Header as HeaderT}, + transaction_validity::{ + InvalidTransaction, TransactionValidityError, UnknownTransaction, ValidTransaction, + }, + BuildStorage, DispatchError, +}; + +use frame_support::{ + assert_err, assert_ok, derive_impl, + migrations::MultiStepMigrator, + pallet_prelude::*, + parameter_types, + traits::{fungible, ConstU8, Currency, IsInherent}, + weights::{ConstantMultiplier, IdentityFee, RuntimeDbWeight, Weight, WeightMeter, WeightToFee}, +}; +use frame_system::{pallet_prelude::*, ChainContext, LastRuntimeUpgrade, LastRuntimeUpgradeInfo}; +use pallet_balances::Call as BalancesCall; +use pallet_transaction_payment::CurrencyAdapter; + +const TEST_KEY: &[u8] = b":test:key:"; + +#[frame_support::pallet(dev_mode)] +mod custom { + use super::*; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::hooks] + impl Hooks> for Pallet { + // module hooks. + // one with block number arg and one without + fn on_initialize(_: BlockNumberFor) -> Weight { + Weight::from_parts(175, 0) + } + + fn on_idle(_: BlockNumberFor, _: Weight) -> Weight { + Weight::from_parts(175, 0) + } + + fn on_poll(_: BlockNumberFor, _: &mut WeightMeter) {} + + fn on_finalize(_: BlockNumberFor) {} + + fn on_runtime_upgrade() -> Weight { + sp_io::storage::set(super::TEST_KEY, "module".as_bytes()); + Weight::from_parts(200, 0) + } + + fn offchain_worker(n: BlockNumberFor) { + assert_eq!(BlockNumberFor::::from(1u32), n); + } + } + + #[pallet::call] + impl Pallet { + pub fn some_function(origin: OriginFor) -> DispatchResult { + // NOTE: does not make any difference. + frame_system::ensure_signed(origin)?; + Ok(()) + } + + #[pallet::weight((200, DispatchClass::Operational))] + pub fn some_root_operation(origin: OriginFor) -> DispatchResult { + frame_system::ensure_root(origin)?; + Ok(()) + } + + pub fn some_unsigned_message(origin: OriginFor) -> DispatchResult { + frame_system::ensure_none(origin)?; + Ok(()) + } + + pub fn allowed_unsigned(origin: OriginFor) -> DispatchResult { + frame_system::ensure_root(origin)?; + Ok(()) + } + + pub fn unallowed_unsigned(origin: OriginFor) -> DispatchResult { + frame_system::ensure_root(origin)?; + Ok(()) + } + + #[pallet::weight((0, DispatchClass::Mandatory))] + pub fn inherent(origin: OriginFor) -> DispatchResult { + frame_system::ensure_none(origin)?; + Ok(()) + } + + pub fn calculate_storage_root(_origin: OriginFor) -> DispatchResult { + let root = sp_io::storage::root(sp_runtime::StateVersion::V1); + sp_io::storage::set("storage_root".as_bytes(), &root); + Ok(()) + } + } + + #[pallet::inherent] + impl ProvideInherent for Pallet { + type Call = Call; + + type Error = sp_inherents::MakeFatalError<()>; + + const INHERENT_IDENTIFIER: [u8; 8] = *b"test1234"; + + fn create_inherent(_data: &InherentData) -> Option { + None + } + + fn is_inherent(call: &Self::Call) -> bool { + *call == Call::::inherent {} + } + } + + #[pallet::validate_unsigned] + impl ValidateUnsigned for Pallet { + type Call = Call; + + // Inherent call is accepted for being dispatched + fn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError> { + match call { + Call::allowed_unsigned { .. } => Ok(()), + Call::inherent { .. } => Ok(()), + _ => Err(UnknownTransaction::NoUnsignedValidator.into()), + } + } + + // Inherent call is not validated as unsigned + fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity { + match call { + Call::allowed_unsigned { .. } => Ok(Default::default()), + _ => UnknownTransaction::NoUnsignedValidator.into(), + } + } + } +} + +#[frame_support::pallet(dev_mode)] +mod custom2 { + use super::*; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::hooks] + impl Hooks> for Pallet { + // module hooks. + // one with block number arg and one without + fn on_initialize(_: BlockNumberFor) -> Weight { + assert!( + !MockedSystemCallbacks::pre_inherent_called(), + "Pre inherent hook goes after on_initialize" + ); + + Weight::from_parts(0, 0) + } + + fn on_idle(_: BlockNumberFor, _: Weight) -> Weight { + assert!( + MockedSystemCallbacks::post_transactions_called(), + "Post transactions hook goes before after on_idle" + ); + Weight::from_parts(0, 0) + } + + fn on_finalize(_: BlockNumberFor) { + assert!( + MockedSystemCallbacks::post_transactions_called(), + "Post transactions hook goes before after on_finalize" + ); + } + + fn on_runtime_upgrade() -> Weight { + sp_io::storage::set(super::TEST_KEY, "module".as_bytes()); + Weight::from_parts(0, 0) + } + } + + #[pallet::call] + impl Pallet { + pub fn allowed_unsigned(origin: OriginFor) -> DispatchResult { + frame_system::ensure_root(origin)?; + Ok(()) + } + + pub fn some_call(_: OriginFor) -> DispatchResult { + assert!(MockedSystemCallbacks::post_inherent_called()); + assert!(!MockedSystemCallbacks::post_transactions_called()); + assert!(System::inherents_applied()); + + Ok(()) + } + + #[pallet::weight({0})] + pub fn optional_inherent(origin: OriginFor) -> DispatchResult { + frame_system::ensure_none(origin)?; + + assert!(MockedSystemCallbacks::pre_inherent_called()); + assert!(!MockedSystemCallbacks::post_inherent_called(), "Should not already be called"); + assert!(!System::inherents_applied()); + + Ok(()) + } + + #[pallet::weight((0, DispatchClass::Mandatory))] + pub fn inherent(origin: OriginFor) -> DispatchResult { + frame_system::ensure_none(origin)?; + + assert!(MockedSystemCallbacks::pre_inherent_called()); + assert!(!MockedSystemCallbacks::post_inherent_called(), "Should not already be called"); + assert!(!System::inherents_applied()); + + Ok(()) + } + } + + #[pallet::inherent] + impl ProvideInherent for Pallet { + type Call = Call; + + type Error = sp_inherents::MakeFatalError<()>; + + const INHERENT_IDENTIFIER: [u8; 8] = *b"test1235"; + + fn create_inherent(_data: &InherentData) -> Option { + None + } + + fn is_inherent(call: &Self::Call) -> bool { + matches!(call, Call::::inherent {} | Call::::optional_inherent {}) + } + } + + #[pallet::validate_unsigned] + impl ValidateUnsigned for Pallet { + type Call = Call; + + // Inherent call is accepted for being dispatched + fn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError> { + match call { + Call::allowed_unsigned { .. } | + Call::optional_inherent { .. } | + Call::inherent { .. } => Ok(()), + _ => Err(UnknownTransaction::NoUnsignedValidator.into()), + } + } + + // Inherent call is not validated as unsigned + fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity { + match call { + Call::allowed_unsigned { .. } => Ok(Default::default()), + _ => UnknownTransaction::NoUnsignedValidator.into(), + } + } + } +} + +frame_support::construct_runtime!( + pub struct Runtime + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, + Custom: custom::{Pallet, Call, ValidateUnsigned, Inherent}, + Custom2: custom2::{Pallet, Call, ValidateUnsigned, Inherent}, + } +); + +parameter_types! { + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::builder() + .base_block(Weight::from_parts(10, 0)) + .for_class(DispatchClass::all(), |weights| weights.base_extrinsic = Weight::from_parts(5, 0)) + .for_class(DispatchClass::non_mandatory(), |weights| weights.max_total = Weight::from_parts(1024, u64::MAX).into()) + .build_or_panic(); + pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight { + read: 10, + write: 100, + }; +} + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Runtime { + type BlockWeights = BlockWeights; + type RuntimeOrigin = RuntimeOrigin; + type Nonce = u64; + type RuntimeCall = RuntimeCall; + type Block = TestBlock; + type RuntimeEvent = RuntimeEvent; + type Version = RuntimeVersion; + type AccountData = pallet_balances::AccountData; + type PreInherents = MockedSystemCallbacks; + type PostInherents = MockedSystemCallbacks; + type PostTransactions = MockedSystemCallbacks; + type MultiBlockMigrator = MockedModeGetter; +} + +type Balance = u64; + +#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig as pallet_balances::DefaultConfig)] +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type AccountStore = System; +} + +parameter_types! { + pub const TransactionByteFee: Balance = 0; +} +impl pallet_transaction_payment::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type OnChargeTransaction = CurrencyAdapter; + type OperationalFeeMultiplier = ConstU8<5>; + type WeightToFee = IdentityFee; + type LengthToFee = ConstantMultiplier; + type FeeMultiplierUpdate = (); +} + +impl custom::Config for Runtime {} +impl custom2::Config for Runtime {} + +pub struct RuntimeVersion; +impl frame_support::traits::Get for RuntimeVersion { + fn get() -> sp_version::RuntimeVersion { + RuntimeVersionTestValues::get().clone() + } +} + +parameter_types! { + pub static RuntimeVersionTestValues: sp_version::RuntimeVersion = + Default::default(); +} + +type SignedExtra = ( + frame_system::CheckEra, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_transaction_payment::ChargeTransactionPayment, +); +type TestXt = sp_runtime::testing::TestXt; +type TestBlock = Block; + +// Will contain `true` when the custom runtime logic was called. +const CUSTOM_ON_RUNTIME_KEY: &[u8] = b":custom:on_runtime"; + +struct CustomOnRuntimeUpgrade; +impl OnRuntimeUpgrade for CustomOnRuntimeUpgrade { + fn on_runtime_upgrade() -> Weight { + sp_io::storage::set(TEST_KEY, "custom_upgrade".as_bytes()); + sp_io::storage::set(CUSTOM_ON_RUNTIME_KEY, &true.encode()); + System::deposit_event(frame_system::Event::CodeUpdated); + + assert_eq!(0, System::last_runtime_upgrade_spec_version()); + + Weight::from_parts(100, 0) + } +} + +type Executive = super::Executive< + Runtime, + Block, + ChainContext, + Runtime, + AllPalletsWithSystem, + CustomOnRuntimeUpgrade, +>; + +parameter_types! { + pub static SystemCallbacksCalled: u32 = 0; +} + +pub struct MockedSystemCallbacks; +impl PreInherents for MockedSystemCallbacks { + fn pre_inherents() { + assert_eq!(SystemCallbacksCalled::get(), 0); + SystemCallbacksCalled::set(1); + // Change the storage to modify the root hash: + frame_support::storage::unhashed::put(b":pre_inherent", b"0"); + } +} + +impl PostInherents for MockedSystemCallbacks { + fn post_inherents() { + assert_eq!(SystemCallbacksCalled::get(), 1); + SystemCallbacksCalled::set(2); + // Change the storage to modify the root hash: + frame_support::storage::unhashed::put(b":post_inherent", b"0"); + } +} + +impl PostTransactions for MockedSystemCallbacks { + fn post_transactions() { + assert_eq!(SystemCallbacksCalled::get(), 2); + SystemCallbacksCalled::set(3); + // Change the storage to modify the root hash: + frame_support::storage::unhashed::put(b":post_transaction", b"0"); + } +} + +impl MockedSystemCallbacks { + fn pre_inherent_called() -> bool { + SystemCallbacksCalled::get() >= 1 + } + + fn post_inherent_called() -> bool { + SystemCallbacksCalled::get() >= 2 + } + + fn post_transactions_called() -> bool { + SystemCallbacksCalled::get() >= 3 + } + + fn reset() { + SystemCallbacksCalled::set(0); + frame_support::storage::unhashed::kill(b":pre_inherent"); + frame_support::storage::unhashed::kill(b":post_inherent"); + frame_support::storage::unhashed::kill(b":post_transaction"); + } +} + +parameter_types! { + pub static MbmActive: bool = false; +} + +pub struct MockedModeGetter; +impl MultiStepMigrator for MockedModeGetter { + fn ongoing() -> bool { + MbmActive::get() + } + + fn step() -> Weight { + Weight::zero() + } +} + +fn extra(nonce: u64, fee: Balance) -> SignedExtra { + ( + frame_system::CheckEra::from(Era::Immortal), + frame_system::CheckNonce::from(nonce), + frame_system::CheckWeight::new(), + pallet_transaction_payment::ChargeTransactionPayment::from(fee), + ) +} + +fn sign_extra(who: u64, nonce: u64, fee: Balance) -> Option<(u64, SignedExtra)> { + Some((who, extra(nonce, fee))) +} + +fn call_transfer(dest: u64, value: u64) -> RuntimeCall { + RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest, value }) +} + +#[test] +fn balance_transfer_dispatch_works() { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + pallet_balances::GenesisConfig:: { balances: vec![(1, 211)] } + .assimilate_storage(&mut t) + .unwrap(); + let xt = TestXt::new(call_transfer(2, 69), sign_extra(1, 0, 0)); + let weight = xt.get_dispatch_info().weight + + ::BlockWeights::get() + .get(DispatchClass::Normal) + .base_extrinsic; + let fee: Balance = + ::WeightToFee::weight_to_fee(&weight); + let mut t = sp_io::TestExternalities::new(t); + t.execute_with(|| { + Executive::initialize_block(&Header::new_from_number(1)); + let r = Executive::apply_extrinsic(xt); + assert!(r.is_ok()); + assert_eq!(>::total_balance(&1), 142 - fee); + assert_eq!(>::total_balance(&2), 69); + }); +} + +fn new_test_ext(balance_factor: Balance) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + pallet_balances::GenesisConfig:: { balances: vec![(1, 111 * balance_factor)] } + .assimilate_storage(&mut t) + .unwrap(); + let mut ext: sp_io::TestExternalities = t.into(); + ext.execute_with(|| { + SystemCallbacksCalled::set(0); + }); + ext +} + +fn new_test_ext_v0(balance_factor: Balance) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + pallet_balances::GenesisConfig:: { balances: vec![(1, 111 * balance_factor)] } + .assimilate_storage(&mut t) + .unwrap(); + (t, sp_runtime::StateVersion::V0).into() +} + +#[test] +fn block_import_works() { + block_import_works_inner( + new_test_ext_v0(1), + array_bytes::hex_n_into_unchecked( + "4826d3bdf87dbbc883d2ab274cbe272f58ed94a904619b59953e48294d1142d2", + ), + ); + block_import_works_inner( + new_test_ext(1), + array_bytes::hex_n_into_unchecked( + "d6b465f5a50c9f8d5a6edc0f01d285a6b19030f097d3aaf1649b7be81649f118", + ), + ); +} +fn block_import_works_inner(mut ext: sp_io::TestExternalities, state_root: H256) { + ext.execute_with(|| { + Executive::execute_block(Block { + header: Header { + parent_hash: [69u8; 32].into(), + number: 1, + state_root, + extrinsics_root: array_bytes::hex_n_into_unchecked( + "03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314", + ), + digest: Digest { logs: vec![] }, + }, + extrinsics: vec![], + }); + }); +} + +#[test] +#[should_panic] +fn block_import_of_bad_state_root_fails() { + new_test_ext(1).execute_with(|| { + Executive::execute_block(Block { + header: Header { + parent_hash: [69u8; 32].into(), + number: 1, + state_root: [0u8; 32].into(), + extrinsics_root: array_bytes::hex_n_into_unchecked( + "03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314", + ), + digest: Digest { logs: vec![] }, + }, + extrinsics: vec![], + }); + }); +} + +#[test] +#[should_panic] +fn block_import_of_bad_extrinsic_root_fails() { + new_test_ext(1).execute_with(|| { + Executive::execute_block(Block { + header: Header { + parent_hash: [69u8; 32].into(), + number: 1, + state_root: array_bytes::hex_n_into_unchecked( + "75e7d8f360d375bbe91bcf8019c01ab6362448b4a89e3b329717eb9d910340e5", + ), + extrinsics_root: [0u8; 32].into(), + digest: Digest { logs: vec![] }, + }, + extrinsics: vec![], + }); + }); +} + +#[test] +fn bad_extrinsic_not_inserted() { + let mut t = new_test_ext(1); + // bad nonce check! + let xt = TestXt::new(call_transfer(33, 69), sign_extra(1, 30, 0)); + t.execute_with(|| { + Executive::initialize_block(&Header::new_from_number(1)); + assert_err!( + Executive::apply_extrinsic(xt), + TransactionValidityError::Invalid(InvalidTransaction::Future) + ); + assert_eq!(>::extrinsic_index(), Some(0)); + }); +} + +#[test] +fn block_weight_limit_enforced() { + let mut t = new_test_ext(10000); + // given: TestXt uses the encoded len as fixed Len: + let xt = TestXt::new( + RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), + sign_extra(1, 0, 0), + ); + let encoded = xt.encode(); + let encoded_len = encoded.len() as u64; + // on_initialize weight + base block execution weight + let block_weights = ::BlockWeights::get(); + let base_block_weight = Weight::from_parts(175, 0) + block_weights.base_block; + let limit = block_weights.get(DispatchClass::Normal).max_total.unwrap() - base_block_weight; + let num_to_exhaust_block = limit.ref_time() / (encoded_len + 5); + t.execute_with(|| { + Executive::initialize_block(&Header::new_from_number(1)); + // Base block execution weight + `on_initialize` weight from the custom module. + assert_eq!(>::block_weight().total(), base_block_weight); + + for nonce in 0..=num_to_exhaust_block { + let xt = TestXt::new( + RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), + sign_extra(1, nonce.into(), 0), + ); + let res = Executive::apply_extrinsic(xt); + if nonce != num_to_exhaust_block { + assert!(res.is_ok()); + assert_eq!( + >::block_weight().total(), + //--------------------- on_initialize + block_execution + extrinsic_base weight + Weight::from_parts((encoded_len + 5) * (nonce + 1), 0) + base_block_weight, + ); + assert_eq!( + >::extrinsic_index(), + Some(nonce as u32 + 1) + ); + } else { + assert_eq!(res, Err(InvalidTransaction::ExhaustsResources.into())); + } + } + }); +} + +#[test] +fn block_weight_and_size_is_stored_per_tx() { + let xt = TestXt::new( + RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), + sign_extra(1, 0, 0), + ); + let x1 = TestXt::new( + RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), + sign_extra(1, 1, 0), + ); + let x2 = TestXt::new( + RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), + sign_extra(1, 2, 0), + ); + let len = xt.clone().encode().len() as u32; + let mut t = new_test_ext(1); + t.execute_with(|| { + // Block execution weight + on_initialize weight from custom module + let base_block_weight = Weight::from_parts(175, 0) + + ::BlockWeights::get().base_block; + + Executive::initialize_block(&Header::new_from_number(1)); + + assert_eq!(>::block_weight().total(), base_block_weight); + assert_eq!(>::all_extrinsics_len(), 0); + + assert!(Executive::apply_extrinsic(xt.clone()).unwrap().is_ok()); + assert!(Executive::apply_extrinsic(x1.clone()).unwrap().is_ok()); + assert!(Executive::apply_extrinsic(x2.clone()).unwrap().is_ok()); + + // default weight for `TestXt` == encoded length. + let extrinsic_weight = Weight::from_parts(len as u64, 0) + + ::BlockWeights::get() + .get(DispatchClass::Normal) + .base_extrinsic; + assert_eq!( + >::block_weight().total(), + base_block_weight + 3u64 * extrinsic_weight, + ); + assert_eq!(>::all_extrinsics_len(), 3 * len); + + let _ = >::finalize(); + // All extrinsics length cleaned on `System::finalize` + assert_eq!(>::all_extrinsics_len(), 0); + + // Reset to a new block. + SystemCallbacksCalled::take(); + Executive::initialize_block(&Header::new_from_number(2)); + + // Block weight cleaned up on `System::initialize` + assert_eq!(>::block_weight().total(), base_block_weight); + }); +} + +#[test] +fn validate_unsigned() { + let valid = TestXt::new(RuntimeCall::Custom(custom::Call::allowed_unsigned {}), None); + let invalid = TestXt::new(RuntimeCall::Custom(custom::Call::unallowed_unsigned {}), None); + let mut t = new_test_ext(1); + + t.execute_with(|| { + assert_eq!( + Executive::validate_transaction( + TransactionSource::InBlock, + valid.clone(), + Default::default(), + ), + Ok(ValidTransaction::default()), + ); + assert_eq!( + Executive::validate_transaction( + TransactionSource::InBlock, + invalid.clone(), + Default::default(), + ), + Err(TransactionValidityError::Unknown(UnknownTransaction::NoUnsignedValidator)), + ); + // Need to initialize the block before applying extrinsics for the `MockedSystemCallbacks` + // check. + Executive::initialize_block(&Header::new_from_number(1)); + assert_eq!(Executive::apply_extrinsic(valid), Ok(Err(DispatchError::BadOrigin))); + assert_eq!( + Executive::apply_extrinsic(invalid), + Err(TransactionValidityError::Unknown(UnknownTransaction::NoUnsignedValidator)) + ); + }); +} + +#[test] +fn can_not_pay_for_tx_fee_on_full_lock() { + let mut t = new_test_ext(1); + t.execute_with(|| { + as fungible::MutateFreeze>::set_freeze(&(), &1, 110) + .unwrap(); + let xt = TestXt::new( + RuntimeCall::System(frame_system::Call::remark { remark: vec![1u8] }), + sign_extra(1, 0, 0), + ); + Executive::initialize_block(&Header::new_from_number(1)); + + assert_eq!(Executive::apply_extrinsic(xt), Err(InvalidTransaction::Payment.into()),); + assert_eq!(>::total_balance(&1), 111); + }); +} + +#[test] +fn block_hooks_weight_is_stored() { + new_test_ext(1).execute_with(|| { + Executive::initialize_block(&Header::new_from_number(1)); + Executive::finalize_block(); + // NOTE: might need updates over time if new weights are introduced. + // For now it only accounts for the base block execution weight and + // the `on_initialize` weight defined in the custom test module. + assert_eq!( + >::block_weight().total(), + Weight::from_parts(175 + 175 + 10, 0) + ); + }) +} + +#[test] +fn runtime_upgraded_should_work() { + new_test_ext(1).execute_with(|| { + RuntimeVersionTestValues::mutate(|v| *v = Default::default()); + // It should be added at genesis + assert!(LastRuntimeUpgrade::::exists()); + assert!(!Executive::runtime_upgraded()); + + RuntimeVersionTestValues::mutate(|v| { + *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } + }); + assert!(Executive::runtime_upgraded()); + + RuntimeVersionTestValues::mutate(|v| { + *v = sp_version::RuntimeVersion { + spec_version: 1, + spec_name: "test".into(), + ..Default::default() + } + }); + assert!(Executive::runtime_upgraded()); + + RuntimeVersionTestValues::mutate(|v| { + *v = sp_version::RuntimeVersion { + spec_version: 0, + impl_version: 2, + ..Default::default() + } + }); + assert!(!Executive::runtime_upgraded()); + + LastRuntimeUpgrade::::take(); + assert!(Executive::runtime_upgraded()); + }) +} + +#[test] +fn last_runtime_upgrade_was_upgraded_works() { + let test_data = vec![ + (0, "", 1, "", true), + (1, "", 1, "", false), + (1, "", 1, "test", true), + (1, "", 0, "", false), + (1, "", 0, "test", true), + ]; + + for (spec_version, spec_name, c_spec_version, c_spec_name, result) in test_data { + let current = sp_version::RuntimeVersion { + spec_version: c_spec_version, + spec_name: c_spec_name.into(), + ..Default::default() + }; + + let last = LastRuntimeUpgradeInfo { + spec_version: spec_version.into(), + spec_name: spec_name.into(), + }; + + assert_eq!(result, last.was_upgraded(¤t)); + } +} + +#[test] +fn custom_runtime_upgrade_is_called_before_modules() { + new_test_ext(1).execute_with(|| { + // Make sure `on_runtime_upgrade` is called. + RuntimeVersionTestValues::mutate(|v| { + *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } + }); + + Executive::initialize_block(&Header::new_from_number(1)); + + assert_eq!(&sp_io::storage::get(TEST_KEY).unwrap()[..], *b"module"); + assert_eq!(sp_io::storage::get(CUSTOM_ON_RUNTIME_KEY).unwrap(), true.encode()); + assert_eq!( + Some(RuntimeVersionTestValues::get().into()), + LastRuntimeUpgrade::::get(), + ) + }); +} + +#[test] +fn event_from_runtime_upgrade_is_included() { + new_test_ext(1).execute_with(|| { + // Make sure `on_runtime_upgrade` is called. + RuntimeVersionTestValues::mutate(|v| { + *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } + }); + + // set block number to non zero so events are not excluded + System::set_block_number(1); + + Executive::initialize_block(&Header::new_from_number(2)); + System::assert_last_event(frame_system::Event::::CodeUpdated.into()); + }); +} + +/// Regression test that ensures that the custom on runtime upgrade is called when executive is +/// used through the `ExecuteBlock` trait. +#[test] +fn custom_runtime_upgrade_is_called_when_using_execute_block_trait() { + let xt = TestXt::new( + RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), + sign_extra(1, 0, 0), + ); + + let header = new_test_ext(1).execute_with(|| { + // Make sure `on_runtime_upgrade` is called. + RuntimeVersionTestValues::mutate(|v| { + *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } + }); + + // Let's build some fake block. + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(xt.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + // Reset to get the correct new genesis below. + RuntimeVersionTestValues::mutate(|v| { + *v = sp_version::RuntimeVersion { spec_version: 0, ..Default::default() } + }); + + new_test_ext(1).execute_with(|| { + // Make sure `on_runtime_upgrade` is called. + RuntimeVersionTestValues::mutate(|v| { + *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } + }); + + >>::execute_block(Block::new(header, vec![xt])); + + assert_eq!(&sp_io::storage::get(TEST_KEY).unwrap()[..], *b"module"); + assert_eq!(sp_io::storage::get(CUSTOM_ON_RUNTIME_KEY).unwrap(), true.encode()); + }); +} + +#[test] +fn all_weights_are_recorded_correctly() { + // Reset to get the correct new genesis below. + RuntimeVersionTestValues::take(); + + new_test_ext(1).execute_with(|| { + // Make sure `on_runtime_upgrade` is called for maximum complexity + RuntimeVersionTestValues::mutate(|v| { + *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } + }); + + let block_number = 1; + + Executive::initialize_block(&Header::new_from_number(block_number)); + + // Reset the last runtime upgrade info, to make the second call to `on_runtime_upgrade` + // succeed. + LastRuntimeUpgrade::::take(); + MockedSystemCallbacks::reset(); + + // All weights that show up in the `initialize_block_impl` + let custom_runtime_upgrade_weight = CustomOnRuntimeUpgrade::on_runtime_upgrade(); + let runtime_upgrade_weight = + ::on_runtime_upgrade(); + let on_initialize_weight = + >::on_initialize(block_number); + let base_block_weight = ::BlockWeights::get().base_block; + + // Weights are recorded correctly + assert_eq!( + frame_system::Pallet::::block_weight().total(), + custom_runtime_upgrade_weight + + runtime_upgrade_weight + + on_initialize_weight + + base_block_weight, + ); + }); +} + +#[test] +fn offchain_worker_works_as_expected() { + new_test_ext(1).execute_with(|| { + let parent_hash = sp_core::H256::from([69u8; 32]); + let mut digest = Digest::default(); + digest.push(DigestItem::Seal([1, 2, 3, 4], vec![5, 6, 7, 8])); + + let header = Header::new(1, H256::default(), H256::default(), parent_hash, digest.clone()); + + Executive::offchain_worker(&header); + + assert_eq!(digest, System::digest()); + assert_eq!(parent_hash, System::block_hash(0)); + assert_eq!(header.hash(), System::block_hash(1)); + }); +} + +#[test] +fn calculating_storage_root_twice_works() { + let call = RuntimeCall::Custom(custom::Call::calculate_storage_root {}); + let xt = TestXt::new(call, sign_extra(1, 0, 0)); + + let header = new_test_ext(1).execute_with(|| { + // Let's build some fake block. + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(xt.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + new_test_ext(1).execute_with(|| { + Executive::execute_block(Block::new(header, vec![xt])); + }); +} + +#[test] +#[should_panic(expected = "Invalid inherent position for extrinsic at index 1")] +fn invalid_inherent_position_fail() { + let xt1 = TestXt::new( + RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), + sign_extra(1, 0, 0), + ); + let xt2 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + + let header = new_test_ext(1).execute_with(|| { + // Let's build some fake block. + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); + Executive::apply_extrinsic(xt2.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + new_test_ext(1).execute_with(|| { + Executive::execute_block(Block::new(header, vec![xt1, xt2])); + }); +} + +#[test] +fn valid_inherents_position_works() { + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + + let header = new_test_ext(1).execute_with(|| { + // Let's build some fake block. + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); + Executive::apply_extrinsic(xt2.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + new_test_ext(1).execute_with(|| { + Executive::execute_block(Block::new(header, vec![xt1, xt2])); + }); +} + +#[test] +#[should_panic(expected = "A call was labelled as mandatory, but resulted in an Error.")] +fn invalid_inherents_fail_block_execution() { + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), sign_extra(1, 0, 0)); + + new_test_ext(1).execute_with(|| { + Executive::execute_block(Block::new( + Header::new(1, H256::default(), H256::default(), [69u8; 32].into(), Digest::default()), + vec![xt1], + )); + }); +} + +// Inherents are created by the runtime and don't need to be validated. +#[test] +fn inherents_fail_validate_block() { + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + + new_test_ext(1).execute_with(|| { + assert_eq!( + Executive::validate_transaction(TransactionSource::External, xt1, H256::random()) + .unwrap_err(), + InvalidTransaction::MandatoryValidation.into() + ); + }) +} + +/// Inherents still work while `initialize_block` forbids transactions. +#[test] +fn inherents_ok_while_exts_forbidden_works() { + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + + let header = new_test_ext(1).execute_with(|| { + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); + // This is not applied: + Executive::finalize_block() + }); + + new_test_ext(1).execute_with(|| { + // Tell `initialize_block` to forbid extrinsics: + Executive::execute_block(Block::new(header, vec![xt1])); + }); +} + +/// Refuses to import blocks with transactions during `OnlyInherents` mode. +#[test] +#[should_panic = "Only inherents are allowed in this block"] +fn transactions_in_only_inherents_block_errors() { + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + + let header = new_test_ext(1).execute_with(|| { + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); + Executive::apply_extrinsic(xt2.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + new_test_ext(1).execute_with(|| { + MbmActive::set(true); + Executive::execute_block(Block::new(header, vec![xt1, xt2])); + }); +} + +/// Same as above but no error. +#[test] +fn transactions_in_normal_block_works() { + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + + let header = new_test_ext(1).execute_with(|| { + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); + Executive::apply_extrinsic(xt2.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + new_test_ext(1).execute_with(|| { + // Tell `initialize_block` to forbid extrinsics: + Executive::execute_block(Block::new(header, vec![xt1, xt2])); + }); +} + +#[test] +#[cfg(feature = "try-runtime")] +fn try_execute_block_works() { + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + + let header = new_test_ext(1).execute_with(|| { + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); + Executive::apply_extrinsic(xt2.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + new_test_ext(1).execute_with(|| { + Executive::try_execute_block( + Block::new(header, vec![xt1, xt2]), + true, + true, + frame_try_runtime::TryStateSelect::All, + ) + .unwrap(); + }); +} + +/// Same as `extrinsic_while_exts_forbidden_errors` but using the try-runtime function. +#[test] +#[cfg(feature = "try-runtime")] +#[should_panic = "Only inherents allowed"] +fn try_execute_tx_forbidden_errors() { + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + + let header = new_test_ext(1).execute_with(|| { + // Let's build some fake block. + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); + Executive::apply_extrinsic(xt2.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + new_test_ext(1).execute_with(|| { + MbmActive::set(true); + Executive::try_execute_block( + Block::new(header, vec![xt1, xt2]), + true, + true, + frame_try_runtime::TryStateSelect::All, + ) + .unwrap(); + }); +} + +/// Check that `ensure_inherents_are_first` reports the correct indices. +#[test] +fn ensure_inherents_are_first_works() { + let in1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let in2 = TestXt::new(RuntimeCall::Custom2(custom2::Call::inherent {}), None); + let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + + // Mocked empty header: + let header = new_test_ext(1).execute_with(|| { + Executive::initialize_block(&Header::new_from_number(1)); + Executive::finalize_block() + }); + + new_test_ext(1).execute_with(|| { + assert_ok!(Runtime::ensure_inherents_are_first(&Block::new(header.clone(), vec![]),), 0); + assert_ok!( + Runtime::ensure_inherents_are_first(&Block::new(header.clone(), vec![xt2.clone()]),), + 0 + ); + assert_ok!( + Runtime::ensure_inherents_are_first(&Block::new(header.clone(), vec![in1.clone()])), + 1 + ); + assert_ok!( + Runtime::ensure_inherents_are_first(&Block::new( + header.clone(), + vec![in1.clone(), xt2.clone()] + ),), + 1 + ); + assert_ok!( + Runtime::ensure_inherents_are_first(&Block::new( + header.clone(), + vec![in2.clone(), in1.clone(), xt2.clone()] + ),), + 2 + ); + + assert_eq!( + Runtime::ensure_inherents_are_first(&Block::new( + header.clone(), + vec![xt2.clone(), in1.clone()] + ),), + Err(1) + ); + assert_eq!( + Runtime::ensure_inherents_are_first(&Block::new( + header.clone(), + vec![xt2.clone(), xt2.clone(), in1.clone()] + ),), + Err(2) + ); + assert_eq!( + Runtime::ensure_inherents_are_first(&Block::new( + header.clone(), + vec![xt2.clone(), xt2.clone(), xt2.clone(), in2.clone()] + ),), + Err(3) + ); + }); +} + +/// Check that block execution rejects blocks with transactions in them while MBMs are active and +/// also that all the system callbacks are called correctly. +#[test] +fn callbacks_in_block_execution_works() { + callbacks_in_block_execution_works_inner(false); + callbacks_in_block_execution_works_inner(true); +} + +fn callbacks_in_block_execution_works_inner(mbms_active: bool) { + MbmActive::set(mbms_active); + + for (n_in, n_tx) in (0..10usize).zip(0..10usize) { + let mut extrinsics = Vec::new(); + + let header = new_test_ext(10).execute_with(|| { + MockedSystemCallbacks::reset(); + Executive::initialize_block(&Header::new_from_number(1)); + assert_eq!(SystemCallbacksCalled::get(), 1); + + for i in 0..n_in { + let xt = if i % 2 == 0 { + TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None) + } else { + TestXt::new(RuntimeCall::Custom2(custom2::Call::optional_inherent {}), None) + }; + Executive::apply_extrinsic(xt.clone()).unwrap().unwrap(); + extrinsics.push(xt); + } + + for t in 0..n_tx { + let xt = TestXt::new( + RuntimeCall::Custom2(custom2::Call::some_call {}), + sign_extra(1, t as u64, 0), + ); + // Extrinsics can be applied even when MBMs are active. Only the `execute_block` + // will reject it. + Executive::apply_extrinsic(xt.clone()).unwrap().unwrap(); + extrinsics.push(xt); + } + + Executive::finalize_block() + }); + assert_eq!(SystemCallbacksCalled::get(), 3); + + new_test_ext(10).execute_with(|| { + let header = std::panic::catch_unwind(|| { + Executive::execute_block(Block::new(header, extrinsics)); + }); + + match header { + Err(e) => { + let err = e.downcast::<&str>().unwrap(); + assert_eq!(*err, "Only inherents are allowed in this block"); + assert!( + MbmActive::get() && n_tx > 0, + "Transactions should be rejected when MBMs are active" + ); + }, + Ok(_) => { + assert_eq!(SystemCallbacksCalled::get(), 3); + assert!( + !MbmActive::get() || n_tx == 0, + "MBMs should be deactivated after finalization" + ); + }, + } + }); + } +} + +#[test] +fn post_inherent_called_after_all_inherents() { + let in1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::inherent {}), None); + let xt1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::some_call {}), sign_extra(1, 0, 0)); + + let header = new_test_ext(1).execute_with(|| { + // Let's build some fake block. + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(in1.clone()).unwrap().unwrap(); + Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + #[cfg(feature = "try-runtime")] + new_test_ext(1).execute_with(|| { + Executive::try_execute_block( + Block::new(header.clone(), vec![in1.clone(), xt1.clone()]), + true, + true, + frame_try_runtime::TryStateSelect::All, + ) + .unwrap(); + assert!(MockedSystemCallbacks::post_transactions_called()); + }); + + new_test_ext(1).execute_with(|| { + MockedSystemCallbacks::reset(); + Executive::execute_block(Block::new(header, vec![in1, xt1])); + assert!(MockedSystemCallbacks::post_transactions_called()); + }); +} + +/// Regression test for AppSec finding #40. +#[test] +fn post_inherent_called_after_all_optional_inherents() { + let in1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::optional_inherent {}), None); + let xt1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::some_call {}), sign_extra(1, 0, 0)); + + let header = new_test_ext(1).execute_with(|| { + // Let's build some fake block. + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(in1.clone()).unwrap().unwrap(); + Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + #[cfg(feature = "try-runtime")] + new_test_ext(1).execute_with(|| { + Executive::try_execute_block( + Block::new(header.clone(), vec![in1.clone(), xt1.clone()]), + true, + true, + frame_try_runtime::TryStateSelect::All, + ) + .unwrap(); + assert!(MockedSystemCallbacks::post_transactions_called()); + }); + + new_test_ext(1).execute_with(|| { + MockedSystemCallbacks::reset(); + Executive::execute_block(Block::new(header, vec![in1, xt1])); + assert!(MockedSystemCallbacks::post_transactions_called()); + }); +} + +#[test] +fn is_inherent_works() { + let ext = TestXt::new(RuntimeCall::Custom2(custom2::Call::inherent {}), None); + assert!(Runtime::is_inherent(&ext)); + let ext = TestXt::new(RuntimeCall::Custom2(custom2::Call::optional_inherent {}), None); + assert!(Runtime::is_inherent(&ext)); + + let ext = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + assert!(!Runtime::is_inherent(&ext)); + + let ext = TestXt::new(RuntimeCall::Custom2(custom2::Call::allowed_unsigned {}), None); + assert!(!Runtime::is_inherent(&ext), "Unsigned ext are not automatically inherents"); +} diff --git a/substrate/frame/migrations/Cargo.toml b/substrate/frame/migrations/Cargo.toml new file mode 100644 index 00000000000..2914aa9ea97 --- /dev/null +++ b/substrate/frame/migrations/Cargo.toml @@ -0,0 +1,64 @@ +[package] +name = "pallet-migrations" +version = "1.0.0" +description = "FRAME pallet to execute multi-block migrations." +authors.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } +docify = "0.1.14" +impl-trait-for-tuples = "0.2.2" +log = "0.4.18" +scale-info = { version = "2.0.0", default-features = false, features = ["derive"] } + +frame-benchmarking = { default-features = false, optional = true, path = "../benchmarking" } +frame-support = { default-features = false, path = "../support" } +frame-system = { default-features = false, path = "../system" } +sp-core = { path = "../../primitives/core", default-features = false } +sp-std = { path = "../../primitives/std", default-features = false } +sp-runtime = { path = "../../primitives/runtime", default-features = false } + +[dev-dependencies] +frame-executive = { path = "../executive" } +sp-api = { path = "../../primitives/api", features = ["std"] } +sp-block-builder = { path = "../../primitives/block-builder", features = ["std"] } +sp-io = { path = "../../primitives/io", features = ["std"] } +sp-tracing = { path = "../../primitives/tracing", features = ["std"] } +sp-version = { path = "../../primitives/version", features = ["std"] } + +pretty_assertions = "1.3.0" + +[features] +default = ["std"] + +std = [ + "codec/std", + "frame-benchmarking?/std", + "frame-support/std", + "frame-system/std", + "log/std", + "scale-info/std", + "sp-core/std", + "sp-runtime/std", + "sp-std/std", +] + +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] + +try-runtime = [ + "frame-executive/try-runtime", + "frame-support/try-runtime", + "frame-system/try-runtime", + "sp-runtime/try-runtime", +] diff --git a/substrate/frame/migrations/src/benchmarking.rs b/substrate/frame/migrations/src/benchmarking.rs new file mode 100644 index 00000000000..8ad1fa50d14 --- /dev/null +++ b/substrate/frame/migrations/src/benchmarking.rs @@ -0,0 +1,222 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; + +use frame_benchmarking::{v2::*, BenchmarkError}; +use frame_system::{Pallet as System, RawOrigin}; +use sp_runtime::traits::One; + +fn assert_last_event(generic_event: ::RuntimeEvent) { + frame_system::Pallet::::assert_last_event(generic_event.into()); +} + +#[benchmarks] +mod benches { + use super::*; + use frame_support::traits::Hooks; + + #[benchmark] + fn onboard_new_mbms() { + T::Migrations::set_fail_after(0); // Should not be called anyway. + assert!(!Cursor::::exists()); + + #[block] + { + Pallet::::onboard_new_mbms(); + } + + assert_last_event::(Event::UpgradeStarted { migrations: 1 }.into()); + } + + #[benchmark] + fn progress_mbms_none() { + T::Migrations::set_fail_after(0); // Should not be called anyway. + assert!(!Cursor::::exists()); + + #[block] + { + Pallet::::progress_mbms(One::one()); + } + } + + /// All migrations completed. + #[benchmark] + fn exec_migration_completed() -> Result<(), BenchmarkError> { + T::Migrations::set_fail_after(0); // Should not be called anyway. + assert_eq!(T::Migrations::len(), 1, "Setup failed"); + let c = ActiveCursor { index: 1, inner_cursor: None, started_at: 0u32.into() }; + let mut meter = WeightMeter::with_limit(T::MaxServiceWeight::get()); + System::::set_block_number(1u32.into()); + + #[block] + { + Pallet::::exec_migration(c, false, &mut meter); + } + + assert_last_event::(Event::UpgradeCompleted {}.into()); + + Ok(()) + } + + /// No migration runs since it is skipped as historic. + #[benchmark] + fn exec_migration_skipped_historic() -> Result<(), BenchmarkError> { + T::Migrations::set_fail_after(0); // Should not be called anyway. + assert_eq!(T::Migrations::len(), 1, "Setup failed"); + let c = ActiveCursor { index: 0, inner_cursor: None, started_at: 0u32.into() }; + + let id: IdentifierOf = T::Migrations::nth_id(0).unwrap().try_into().unwrap(); + Historic::::insert(id, ()); + + let mut meter = WeightMeter::with_limit(T::MaxServiceWeight::get()); + System::::set_block_number(1u32.into()); + + #[block] + { + Pallet::::exec_migration(c, false, &mut meter); + } + + assert_last_event::(Event::MigrationSkipped { index: 0 }.into()); + + Ok(()) + } + + /// Advance a migration by one step. + #[benchmark] + fn exec_migration_advance() -> Result<(), BenchmarkError> { + T::Migrations::set_success_after(1); + assert_eq!(T::Migrations::len(), 1, "Setup failed"); + let c = ActiveCursor { index: 0, inner_cursor: None, started_at: 0u32.into() }; + let mut meter = WeightMeter::with_limit(T::MaxServiceWeight::get()); + System::::set_block_number(1u32.into()); + + #[block] + { + Pallet::::exec_migration(c, false, &mut meter); + } + + assert_last_event::(Event::MigrationAdvanced { index: 0, took: One::one() }.into()); + + Ok(()) + } + + /// Successfully complete a migration. + #[benchmark] + fn exec_migration_complete() -> Result<(), BenchmarkError> { + T::Migrations::set_success_after(0); + assert_eq!(T::Migrations::len(), 1, "Setup failed"); + let c = ActiveCursor { index: 0, inner_cursor: None, started_at: 0u32.into() }; + let mut meter = WeightMeter::with_limit(T::MaxServiceWeight::get()); + System::::set_block_number(1u32.into()); + + #[block] + { + Pallet::::exec_migration(c, false, &mut meter); + } + + assert_last_event::(Event::MigrationCompleted { index: 0, took: One::one() }.into()); + + Ok(()) + } + + #[benchmark] + fn exec_migration_fail() -> Result<(), BenchmarkError> { + T::Migrations::set_fail_after(0); + assert_eq!(T::Migrations::len(), 1, "Setup failed"); + let c = ActiveCursor { index: 0, inner_cursor: None, started_at: 0u32.into() }; + let mut meter = WeightMeter::with_limit(T::MaxServiceWeight::get()); + System::::set_block_number(1u32.into()); + + #[block] + { + Pallet::::exec_migration(c, false, &mut meter); + } + + assert_last_event::(Event::UpgradeFailed {}.into()); + + Ok(()) + } + + #[benchmark] + fn on_init_loop() { + T::Migrations::set_fail_after(0); // Should not be called anyway. + System::::set_block_number(1u32.into()); + Pallet::::on_runtime_upgrade(); + + #[block] + { + Pallet::::on_initialize(1u32.into()); + } + } + + #[benchmark] + fn force_set_cursor() { + #[extrinsic_call] + _(RawOrigin::Root, Some(cursor::())); + } + + #[benchmark] + fn force_set_active_cursor() { + #[extrinsic_call] + _(RawOrigin::Root, 0, None, None); + } + + #[benchmark] + fn force_onboard_mbms() { + #[extrinsic_call] + _(RawOrigin::Root); + } + + #[benchmark] + fn clear_historic(n: Linear<0, { DEFAULT_HISTORIC_BATCH_CLEAR_SIZE * 2 }>) { + let id_max_len = ::IdentifierMaxLen::get(); + assert!(id_max_len >= 4, "Precondition violated"); + + for i in 0..DEFAULT_HISTORIC_BATCH_CLEAR_SIZE * 2 { + let id = IdentifierOf::::truncate_from( + i.encode().into_iter().cycle().take(id_max_len as usize).collect::>(), + ); + + Historic::::insert(&id, ()); + } + + #[extrinsic_call] + _( + RawOrigin::Root, + HistoricCleanupSelector::Wildcard { limit: n.into(), previous_cursor: None }, + ); + } + + fn cursor() -> CursorOf { + // Note: The weight of a function can depend on the weight of reading the `inner_cursor`. + // `Cursor` is a user provided type. Now instead of requiring something like `Cursor: + // From`, we instead rely on the fact that it is MEL and the PoV benchmarking will + // therefore already take the MEL bound, even when the cursor in storage is `None`. + MigrationCursor::Active(ActiveCursor { + index: u32::MAX, + inner_cursor: None, + started_at: 0u32.into(), + }) + } + + // Implements a test for each benchmark. Execute with: + // `cargo test -p pallet-migrations --features runtime-benchmarks`. + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); +} diff --git a/substrate/frame/migrations/src/lib.rs b/substrate/frame/migrations/src/lib.rs new file mode 100644 index 00000000000..cd57d89f440 --- /dev/null +++ b/substrate/frame/migrations/src/lib.rs @@ -0,0 +1,746 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![deny(missing_docs)] +#![deny(rustdoc::broken_intra_doc_links)] + +//! # `pallet-migrations` +//! +//! Provides multi block migrations for FRAME runtimes. +//! +//! ## Overview +//! +//! The pallet takes care of executing a batch of multi-step migrations over multiple blocks. The +//! process starts on each runtime upgrade. Normal and operational transactions are paused while +//! migrations are on-going. +//! +//! ### Example +//! +//! This example demonstrates a simple mocked walk through of a basic success scenario. The pallet +//! is configured with two migrations: one succeeding after just one step, and the second one +//! succeeding after two steps. A runtime upgrade is then enacted and the block number is advanced +//! until all migrations finish executing. Afterwards, the recorded historic migrations are +//! checked and events are asserted. +#![doc = docify::embed!("substrate/frame/migrations/src/tests.rs", simple_works)] +//! +//! ## Pallet API +//! +//! See the [`pallet`] module for more information about the interfaces this pallet exposes, +//! including its configuration trait, dispatchables, storage items, events and errors. +//! +//! Otherwise noteworthy API of this pallet include its implementation of the +//! [`MultiStepMigrator`] trait. This must be plugged into +//! [`frame_system::Config::MultiBlockMigrator`] for proper function. +//! +//! The API contains some calls for emergency management. They are all prefixed with `force_` and +//! should normally not be needed. Pay special attention prior to using them. +//! +//! ### Design Goals +//! +//! 1. Must automatically execute migrations over multiple blocks. +//! 2. Must expose information about whether migrations are ongoing. +//! 3. Must respect pessimistic weight bounds of migrations. +//! 4. Must execute migrations in order. Skipping is not allowed; migrations are run on a +//! all-or-nothing basis. +//! 5. Must prevent re-execution of past migrations. +//! 6. Must provide transactional storage semantics for migrations. +//! 7. Must guarantee progress. +//! +//! ### Design +//! +//! Migrations are provided to the pallet through the associated type [`Config::Migrations`] of type +//! [`SteppedMigrations`]. This allows multiple migrations to be aggregated through a tuple. It +//! simplifies the trait bounds since all associated types of the trait must be provided by the +//! pallet. The actual progress of the pallet is stored in the [`Cursor`] storage item. This can +//! either be [`MigrationCursor::Active`] or [`MigrationCursor::Stuck`]. In the active case it +//! points to the currently active migration and stores its inner cursor. The inner cursor can then +//! be used by the migration to store its inner state and advance. Each time when the migration +//! returns `Some(cursor)`, it signals the pallet that it is not done yet. +//! The cursor is reset on each runtime upgrade. This ensures that it starts to execute at the +//! first migration in the vector. The pallets cursor is only ever incremented or set to `Stuck` +//! once it encounters an error (Goal 4). Once in the stuck state, the pallet will stay stuck until +//! it is fixed through manual governance intervention. +//! As soon as the cursor of the pallet becomes `Some(_)`; [`MultiStepMigrator::ongoing`] returns +//! `true` (Goal 2). This can be used by upstream code to possibly pause transactions. +//! In `on_initialize` the pallet will load the current migration and check whether it was already +//! executed in the past by checking for membership of its ID in the [`Historic`] set. Historic +//! migrations are skipped without causing an error. Each successfully executed migration is added +//! to this set (Goal 5). +//! This proceeds until no more migrations remain. At that point, the event `UpgradeCompleted` is +//! emitted (Goal 1). +//! The execution of each migration happens by calling [`SteppedMigration::transactional_step`]. +//! This function wraps the inner `step` function into a transactional layer to allow rollback in +//! the error case (Goal 6). +//! Weight limits must be checked by the migration itself. The pallet provides a [`WeightMeter`] for +//! that purpose. The pallet may return [`SteppedMigrationError::InsufficientWeight`] at any point. +//! In that scenario, one of two things will happen: if that migration was exclusively executed +//! in this block, and therefore required more than the maximum amount of weight possible, the +//! process becomes `Stuck`. Otherwise, one re-attempt is executed with the same logic in the next +//! block (Goal 3). Progress through the migrations is guaranteed by providing a timeout for each +//! migration via [`SteppedMigration::max_steps`]. The pallet **ONLY** guarantees progress if this +//! is set to sensible limits (Goal 7). +//! +//! ### Scenario: Governance cleanup +//! +//! Every now and then, governance can make use of the [`clear_historic`][Pallet::clear_historic] +//! call. This ensures that no old migrations pile up in the [`Historic`] set. This can be done very +//! rarely, since the storage should not grow quickly and the lookup weight does not suffer much. +//! Another possibility would be to have a synchronous single-block migration perpetually deployed +//! that cleans them up before the MBMs start. +//! +//! ### Scenario: Successful upgrade +//! +//! The standard procedure for a successful runtime upgrade can look like this: +//! 1. Migrations are configured in the `Migrations` config item. All migrations expose +//! [`max_steps`][SteppedMigration::max_steps], are error tolerant, check their weight bounds and +//! have a unique identifier. +//! 2. The runtime upgrade is enacted. An `UpgradeStarted` event is +//! followed by lots of `MigrationAdvanced` and `MigrationCompleted` events. Finally +//! `UpgradeCompleted` is emitted. +//! 3. Cleanup as described in the governance scenario be executed at any time after the migrations +//! completed. +//! +//! ### Advice: Failed upgrades +//! +//! Failed upgrades cannot be recovered from automatically and require governance intervention. Set +//! up monitoring for `UpgradeFailed` events to be made aware of any failures. The hook +//! [`FailedMigrationHandler::failed`] should be setup in a way that it allows governance to act, +//! but still prevent other transactions from interacting with the inconsistent storage state. Note +//! that this is paramount, since the inconsistent state might contain a faulty balance amount or +//! similar that could cause great harm if user transactions don't remain suspended. One way to +//! implement this would be to use the `SafeMode` or `TxPause` pallets that can prevent most user +//! interactions but still allow a whitelisted set of governance calls. +//! +//! ### Remark: Failed migrations +//! +//! Failed migrations are not added to the `Historic` set. This means that an erroneous +//! migration must be removed and fixed manually. This already applies, even before considering the +//! historic set. +//! +//! ### Remark: Transactional processing +//! +//! You can see the transactional semantics for migration steps as mostly useless, since in the +//! stuck case the state is already messed up. This just prevents it from becoming even more messed +//! up, but doesn't prevent it in the first place. + +#![cfg_attr(not(feature = "std"), no_std)] + +mod benchmarking; +mod mock; +pub mod mock_helpers; +mod tests; +pub mod weights; + +pub use pallet::*; +pub use weights::WeightInfo; + +use codec::{Decode, Encode, MaxEncodedLen}; +use core::ops::ControlFlow; +use frame_support::{ + defensive, defensive_assert, + migrations::*, + traits::Get, + weights::{Weight, WeightMeter}, + BoundedVec, +}; +use frame_system::{pallet_prelude::BlockNumberFor, Pallet as System}; +use sp_runtime::Saturating; +use sp_std::vec::Vec; + +/// Points to the next migration to execute. +#[derive(Debug, Clone, Eq, PartialEq, Encode, Decode, scale_info::TypeInfo, MaxEncodedLen)] +pub enum MigrationCursor { + /// Points to the currently active migration and its inner cursor. + Active(ActiveCursor), + + /// Migration got stuck and cannot proceed. This is bad. + Stuck, +} + +impl MigrationCursor { + /// Try to return self as an [`ActiveCursor`]. + pub fn as_active(&self) -> Option<&ActiveCursor> { + match self { + MigrationCursor::Active(active) => Some(active), + MigrationCursor::Stuck => None, + } + } +} + +impl From> + for MigrationCursor +{ + fn from(active: ActiveCursor) -> Self { + MigrationCursor::Active(active) + } +} + +/// Points to the currently active migration and its inner cursor. +#[derive(Debug, Clone, Eq, PartialEq, Encode, Decode, scale_info::TypeInfo, MaxEncodedLen)] +pub struct ActiveCursor { + /// The index of the migration in the MBM tuple. + pub index: u32, + /// The cursor of the migration that is referenced by `index`. + pub inner_cursor: Option, + /// The block number that the migration started at. + /// + /// This is used to calculate how many blocks it took. + pub started_at: BlockNumber, +} + +impl ActiveCursor { + /// Advance the overarching cursor to the next migration. + pub(crate) fn goto_next_migration(&mut self, current_block: BlockNumber) { + self.index.saturating_inc(); + self.inner_cursor = None; + self.started_at = current_block; + } +} + +/// How to clear the records of historic migrations. +#[derive(Debug, Clone, Eq, PartialEq, Encode, Decode, scale_info::TypeInfo)] +pub enum HistoricCleanupSelector { + /// Clear exactly these entries. + /// + /// This is the advised way of doing it. + Specific(Vec), + + /// Clear up to this many entries + Wildcard { + /// How many should be cleared in this call at most. + limit: Option, + /// The cursor that was emitted from any previous `HistoricCleared`. + /// + /// Does not need to be passed when clearing the first batch. + previous_cursor: Option>, + }, +} + +/// The default number of entries that should be cleared by a `HistoricCleanupSelector::Wildcard`. +/// +/// The caller can explicitly specify a higher amount. Benchmarks are run with twice this value. +const DEFAULT_HISTORIC_BATCH_CLEAR_SIZE: u32 = 128; + +impl HistoricCleanupSelector { + /// The maximal number of entries that this will remove. + /// + /// Needed for weight calculation. + pub fn limit(&self) -> u32 { + match self { + Self::Specific(ids) => ids.len() as u32, + Self::Wildcard { limit, .. } => limit.unwrap_or(DEFAULT_HISTORIC_BATCH_CLEAR_SIZE), + } + } +} + +/// Convenience alias for [`MigrationCursor`]. +pub type CursorOf = MigrationCursor, BlockNumberFor>; + +/// Convenience alias for the raw inner cursor of a migration. +pub type RawCursorOf = BoundedVec::CursorMaxLen>; + +/// Convenience alias for the identifier of a migration. +pub type IdentifierOf = BoundedVec::IdentifierMaxLen>; + +/// Convenience alias for [`ActiveCursor`]. +pub type ActiveCursorOf = ActiveCursor, BlockNumberFor>; + +/// Trait for a tuple of No-OP migrations with one element. +pub trait MockedMigrations: SteppedMigrations { + /// The migration should fail after `n` steps. + fn set_fail_after(n: u32); + /// The migration should succeed after `n` steps. + fn set_success_after(n: u32); +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config { + /// The overarching event type of the runtime. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// All the multi-block migrations to run. + /// + /// Should only be updated in a runtime-upgrade once all the old migrations have completed. + /// (Check that [`Cursor`] is `None`). + #[cfg(not(feature = "runtime-benchmarks"))] + type Migrations: SteppedMigrations; + + /// Mocked migrations for benchmarking only. + /// + /// Should be configured to [`crate::mock_helpers::MockedMigrations`] in benchmarks. + #[cfg(feature = "runtime-benchmarks")] + type Migrations: MockedMigrations; + + /// The maximal length of an encoded cursor. + /// + /// A good default needs to selected such that no migration will ever have a cursor with MEL + /// above this limit. This is statically checked in `integrity_test`. + #[pallet::constant] + type CursorMaxLen: Get; + + /// The maximal length of an encoded identifier. + /// + /// A good default needs to selected such that no migration will ever have an identifier + /// with MEL above this limit. This is statically checked in `integrity_test`. + #[pallet::constant] + type IdentifierMaxLen: Get; + + /// Notifications for status updates of a runtime upgrade. + /// + /// Could be used to pause XCM etc. + type MigrationStatusHandler: MigrationStatusHandler; + + /// Handler for failed migrations. + type FailedMigrationHandler: FailedMigrationHandler; + + /// The maximum weight to spend each block to execute migrations. + type MaxServiceWeight: Get; + + /// Weight information for the calls and functions of this pallet. + type WeightInfo: WeightInfo; + } + + /// The currently active migration to run and its cursor. + /// + /// `None` indicates that no migration is running. + #[pallet::storage] + pub type Cursor = StorageValue<_, CursorOf, OptionQuery>; + + /// Set of all successfully executed migrations. + /// + /// This is used as blacklist, to not re-execute migrations that have not been removed from the + /// codebase yet. Governance can regularly clear this out via `clear_historic`. + #[pallet::storage] + pub type Historic = StorageMap<_, Twox64Concat, IdentifierOf, (), OptionQuery>; + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// A Runtime upgrade started. + /// + /// Its end is indicated by `UpgradeCompleted` or `UpgradeFailed`. + UpgradeStarted { + /// The number of migrations that this upgrade contains. + /// + /// This can be used to design a progress indicator in combination with counting the + /// `MigrationCompleted` and `MigrationSkipped` events. + migrations: u32, + }, + /// The current runtime upgrade completed. + /// + /// This implies that all of its migrations completed successfully as well. + UpgradeCompleted, + /// Runtime upgrade failed. + /// + /// This is very bad and will require governance intervention. + UpgradeFailed, + /// A migration was skipped since it was already executed in the past. + MigrationSkipped { + /// The index of the skipped migration within the [`Config::Migrations`] list. + index: u32, + }, + /// A migration progressed. + MigrationAdvanced { + /// The index of the migration within the [`Config::Migrations`] list. + index: u32, + /// The number of blocks that this migration took so far. + took: BlockNumberFor, + }, + /// A Migration completed. + MigrationCompleted { + /// The index of the migration within the [`Config::Migrations`] list. + index: u32, + /// The number of blocks that this migration took so far. + took: BlockNumberFor, + }, + /// A Migration failed. + /// + /// This implies that the whole upgrade failed and governance intervention is required. + MigrationFailed { + /// The index of the migration within the [`Config::Migrations`] list. + index: u32, + /// The number of blocks that this migration took so far. + took: BlockNumberFor, + }, + /// The set of historical migrations has been cleared. + HistoricCleared { + /// Should be passed to `clear_historic` in a successive call. + next_cursor: Option>, + }, + } + + #[pallet::error] + pub enum Error { + /// The operation cannot complete since some MBMs are ongoing. + Ongoing, + } + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_runtime_upgrade() -> Weight { + Self::onboard_new_mbms() + } + + #[cfg(feature = "std")] + fn integrity_test() { + // Check that the migrations tuple is legit. + frame_support::assert_ok!(T::Migrations::integrity_test()); + + // Very important! Ensure that the pallet is configured in `System::Config`. + { + assert!(!Cursor::::exists(), "Externalities storage should be clean"); + assert!(!::MultiBlockMigrator::ongoing()); + + Cursor::::put(MigrationCursor::Stuck); + assert!(::MultiBlockMigrator::ongoing()); + + Cursor::::kill(); + } + + // The per-block service weight is sane. + #[cfg(not(test))] + { + let want = T::MaxServiceWeight::get(); + let max = ::BlockWeights::get().max_block; + + assert!(want.all_lte(max), "Service weight is larger than a block: {want} > {max}",); + } + + // Cursor MEL + { + let mel = T::Migrations::cursor_max_encoded_len(); + let max_mel = T::CursorMaxLen::get() as usize; + assert!( + mel <= max_mel, + "A Cursor is not guaranteed to fit into the storage: {mel} > {max_mel}", + ); + } + + // Identifier MEL + { + let mel = T::Migrations::identifier_max_encoded_len(); + let max_mel = T::IdentifierMaxLen::get() as usize; + assert!( + mel <= max_mel, + "An Identifier is not guaranteed to fit into the storage: {mel} > {max_mel}", + ); + } + } + } + + #[pallet::call(weight = T::WeightInfo)] + impl Pallet { + /// Allows root to set a cursor to forcefully start, stop or forward the migration process. + /// + /// Should normally not be needed and is only in place as emergency measure. Note that + /// restarting the migration process in this manner will not call the + /// [`MigrationStatusHandler::started`] hook or emit an `UpgradeStarted` event. + #[pallet::call_index(0)] + pub fn force_set_cursor( + origin: OriginFor, + cursor: Option>, + ) -> DispatchResult { + ensure_root(origin)?; + + Cursor::::set(cursor); + + Ok(()) + } + + /// Allows root to set an active cursor to forcefully start/forward the migration process. + /// + /// This is an edge-case version of [`Self::force_set_cursor`] that allows to set the + /// `started_at` value to the next block number. Otherwise this would not be possible, since + /// `force_set_cursor` takes an absolute block number. Setting `started_at` to `None` + /// indicates that the current block number plus one should be used. + #[pallet::call_index(1)] + pub fn force_set_active_cursor( + origin: OriginFor, + index: u32, + inner_cursor: Option>, + started_at: Option>, + ) -> DispatchResult { + ensure_root(origin)?; + + let started_at = started_at.unwrap_or( + System::::block_number().saturating_add(sp_runtime::traits::One::one()), + ); + Cursor::::put(MigrationCursor::Active(ActiveCursor { + index, + inner_cursor, + started_at, + })); + + Ok(()) + } + + /// Forces the onboarding of the migrations. + /// + /// This process happens automatically on a runtime upgrade. It is in place as an emergency + /// measurement. The cursor needs to be `None` for this to succeed. + #[pallet::call_index(2)] + pub fn force_onboard_mbms(origin: OriginFor) -> DispatchResult { + ensure_root(origin)?; + + ensure!(!Cursor::::exists(), Error::::Ongoing); + Self::onboard_new_mbms(); + + Ok(()) + } + + /// Clears the `Historic` set. + /// + /// `map_cursor` must be set to the last value that was returned by the + /// `HistoricCleared` event. The first time `None` can be used. `limit` must be chosen in a + /// way that will result in a sensible weight. + #[pallet::call_index(3)] + #[pallet::weight(T::WeightInfo::clear_historic(selector.limit()))] + pub fn clear_historic( + origin: OriginFor, + selector: HistoricCleanupSelector>, + ) -> DispatchResult { + ensure_root(origin)?; + + match &selector { + HistoricCleanupSelector::Specific(ids) => { + for id in ids { + Historic::::remove(id); + } + Self::deposit_event(Event::HistoricCleared { next_cursor: None }); + }, + HistoricCleanupSelector::Wildcard { previous_cursor, .. } => { + let next = Historic::::clear(selector.limit(), previous_cursor.as_deref()); + Self::deposit_event(Event::HistoricCleared { next_cursor: next.maybe_cursor }); + }, + } + + Ok(()) + } + } +} + +impl Pallet { + /// Onboard all new Multi-Block-Migrations and start the process of executing them. + /// + /// Should only be called once all previous migrations completed. + fn onboard_new_mbms() -> Weight { + if let Some(cursor) = Cursor::::get() { + log::error!("Ongoing migrations interrupted - chain stuck"); + + let maybe_index = cursor.as_active().map(|c| c.index); + Self::upgrade_failed(maybe_index); + return T::WeightInfo::onboard_new_mbms() + } + + let migrations = T::Migrations::len(); + log::debug!("Onboarding {migrations} new MBM migrations"); + + if migrations > 0 { + // Set the cursor to the first migration: + Cursor::::set(Some( + ActiveCursor { + index: 0, + inner_cursor: None, + started_at: System::::block_number(), + } + .into(), + )); + Self::deposit_event(Event::UpgradeStarted { migrations }); + T::MigrationStatusHandler::started(); + } + + T::WeightInfo::onboard_new_mbms() + } + + /// Tries to make progress on the Multi-Block-Migrations process. + fn progress_mbms(n: BlockNumberFor) -> Weight { + let mut meter = WeightMeter::with_limit(T::MaxServiceWeight::get()); + meter.consume(T::WeightInfo::progress_mbms_none()); + + let mut cursor = match Cursor::::get() { + None => { + log::trace!("[Block {n:?}] Waiting for cursor to become `Some`."); + return meter.consumed() + }, + Some(MigrationCursor::Active(cursor)) => { + log::debug!("Progressing MBM #{}", cursor.index); + cursor + }, + Some(MigrationCursor::Stuck) => { + log::error!("Migration stuck. Governance intervention required."); + return meter.consumed() + }, + }; + debug_assert!(Self::ongoing()); + + // The limit here is a defensive measure to prevent an infinite loop. It expresses that we + // allow no more than 8 MBMs to finish in a single block. This should be harmless, since we + // generally expect *Multi*-Block-Migrations to take *multiple* blocks. + for i in 0..8 { + match Self::exec_migration(cursor, i == 0, &mut meter) { + None => return meter.consumed(), + Some(ControlFlow::Continue(next_cursor)) => { + cursor = next_cursor; + }, + Some(ControlFlow::Break(last_cursor)) => { + cursor = last_cursor; + break + }, + } + } + + Cursor::::set(Some(cursor.into())); + + meter.consumed() + } + + /// Try to make progress on the current migration. + /// + /// Returns whether processing should continue or break for this block. The return value means: + /// - `None`: The migration process is completely finished. + /// - `ControlFlow::Break`: Continue in the *next* block with the given cursor. + /// - `ControlFlow::Continue`: Continue in the *current* block with the given cursor. + fn exec_migration( + mut cursor: ActiveCursorOf, + is_first: bool, + meter: &mut WeightMeter, + ) -> Option, ActiveCursorOf>> { + // The differences between the single branches' weights is not that big. And since we do + // only one step per block, we can just use the maximum instead of more precise accounting. + if meter.try_consume(Self::exec_migration_max_weight()).is_err() { + defensive_assert!(!is_first, "There should be enough weight to do this at least once"); + return Some(ControlFlow::Break(cursor)) + } + + let Some(id) = T::Migrations::nth_id(cursor.index) else { + // No more migrations in the tuple - we are done. + defensive_assert!(cursor.index == T::Migrations::len(), "Inconsistent MBMs tuple"); + Self::deposit_event(Event::UpgradeCompleted); + Cursor::::kill(); + T::MigrationStatusHandler::completed(); + return None; + }; + + let Ok(bounded_id): Result, _> = id.try_into() else { + defensive!("integrity_test ensures that all identifiers' MEL bounds fit into CursorMaxLen; qed."); + Self::upgrade_failed(Some(cursor.index)); + return None + }; + + if Historic::::contains_key(&bounded_id) { + Self::deposit_event(Event::MigrationSkipped { index: cursor.index }); + cursor.goto_next_migration(System::::block_number()); + return Some(ControlFlow::Continue(cursor)) + } + + let max_steps = T::Migrations::nth_max_steps(cursor.index); + let next_cursor = T::Migrations::nth_transactional_step( + cursor.index, + cursor.inner_cursor.clone().map(|c| c.into_inner()), + meter, + ); + let Some((max_steps, next_cursor)) = max_steps.zip(next_cursor) else { + defensive!("integrity_test ensures that the tuple is valid; qed"); + Self::upgrade_failed(Some(cursor.index)); + return None + }; + + let took = System::::block_number().saturating_sub(cursor.started_at); + match next_cursor { + Ok(Some(next_cursor)) => { + let Ok(bound_next_cursor) = next_cursor.try_into() else { + defensive!("The integrity check ensures that all cursors' MEL bound fits into CursorMaxLen; qed"); + Self::upgrade_failed(Some(cursor.index)); + return None + }; + + Self::deposit_event(Event::MigrationAdvanced { index: cursor.index, took }); + cursor.inner_cursor = Some(bound_next_cursor); + + if max_steps.map_or(false, |max| took > max.into()) { + Self::deposit_event(Event::MigrationFailed { index: cursor.index, took }); + Self::upgrade_failed(Some(cursor.index)); + None + } else { + // A migration cannot progress more than one step per block, we therefore break. + Some(ControlFlow::Break(cursor)) + } + }, + Ok(None) => { + // A migration is done when it returns cursor `None`. + Self::deposit_event(Event::MigrationCompleted { index: cursor.index, took }); + Historic::::insert(&bounded_id, ()); + cursor.goto_next_migration(System::::block_number()); + Some(ControlFlow::Continue(cursor)) + }, + Err(SteppedMigrationError::InsufficientWeight { required }) => { + if is_first || required.any_gt(meter.limit()) { + Self::deposit_event(Event::MigrationFailed { index: cursor.index, took }); + Self::upgrade_failed(Some(cursor.index)); + None + } else { + // Retry and hope that there is more weight in the next block. + Some(ControlFlow::Break(cursor)) + } + }, + Err(SteppedMigrationError::InvalidCursor | SteppedMigrationError::Failed) => { + Self::deposit_event(Event::MigrationFailed { index: cursor.index, took }); + Self::upgrade_failed(Some(cursor.index)); + None + }, + } + } + + /// Fail the current runtime upgrade, caused by `migration`. + fn upgrade_failed(migration: Option) { + use FailedMigrationHandling::*; + Self::deposit_event(Event::UpgradeFailed); + + match T::FailedMigrationHandler::failed(migration) { + KeepStuck => Cursor::::set(Some(MigrationCursor::Stuck)), + ForceUnstuck => Cursor::::kill(), + Ignore => {}, + } + } + + fn exec_migration_max_weight() -> Weight { + T::WeightInfo::exec_migration_complete() + .max(T::WeightInfo::exec_migration_completed()) + .max(T::WeightInfo::exec_migration_skipped_historic()) + .max(T::WeightInfo::exec_migration_advance()) + .max(T::WeightInfo::exec_migration_fail()) + } +} + +impl MultiStepMigrator for Pallet { + fn ongoing() -> bool { + Cursor::::exists() + } + + fn step() -> Weight { + Self::progress_mbms(System::::block_number()) + } +} diff --git a/substrate/frame/migrations/src/mock.rs b/substrate/frame/migrations/src/mock.rs new file mode 100644 index 00000000000..37292647554 --- /dev/null +++ b/substrate/frame/migrations/src/mock.rs @@ -0,0 +1,163 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Mocked runtime for testing the migrations pallet. + +#![cfg(test)] + +use crate::{mock_helpers::*, Event, Historic}; + +use frame_support::{ + derive_impl, + migrations::*, + traits::{OnFinalize, OnInitialize}, + weights::Weight, +}; +use frame_system::EventRecord; +use sp_core::{ConstU32, H256}; + +type Block = frame_system::mocking::MockBlock; + +// Configure a mock runtime to test the pallet. +frame_support::construct_runtime!( + pub enum Test { + System: frame_system, + Migrations: crate, + } +); + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Test { + type Block = Block; + type PalletInfo = PalletInfo; + type MultiBlockMigrator = Migrations; +} + +frame_support::parameter_types! { + pub const MaxServiceWeight: Weight = Weight::MAX.div(10); +} + +impl crate::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Migrations = MockedMigrations; + type CursorMaxLen = ConstU32<65_536>; + type IdentifierMaxLen = ConstU32<256>; + type MigrationStatusHandler = MockedMigrationStatusHandler; + type FailedMigrationHandler = MockedFailedMigrationHandler; + type MaxServiceWeight = MaxServiceWeight; + type WeightInfo = (); +} + +frame_support::parameter_types! { + /// The number of started upgrades. + pub static UpgradesStarted: u32 = 0; + /// The number of completed upgrades. + pub static UpgradesCompleted: u32 = 0; + /// The migrations that failed. + pub static UpgradesFailed: Vec> = vec![]; + /// Return value of [`MockedFailedMigrationHandler::failed`]. + pub static FailedUpgradeResponse: FailedMigrationHandling = FailedMigrationHandling::KeepStuck; +} + +/// Records all started and completed upgrades in `UpgradesStarted` and `UpgradesCompleted`. +pub struct MockedMigrationStatusHandler; +impl MigrationStatusHandler for MockedMigrationStatusHandler { + fn started() { + log::info!("MigrationStatusHandler started"); + UpgradesStarted::mutate(|v| *v += 1); + } + + fn completed() { + log::info!("MigrationStatusHandler completed"); + UpgradesCompleted::mutate(|v| *v += 1); + } +} + +/// Records all failed upgrades in `UpgradesFailed`. +pub struct MockedFailedMigrationHandler; +impl FailedMigrationHandler for MockedFailedMigrationHandler { + fn failed(migration: Option) -> FailedMigrationHandling { + UpgradesFailed::mutate(|v| v.push(migration)); + let res = FailedUpgradeResponse::get(); + log::error!("FailedMigrationHandler failed at: {migration:?}, handling as {res:?}"); + res + } +} + +/// Returns the number of `(started, completed, failed)` upgrades and resets their numbers. +pub fn upgrades_started_completed_failed() -> (u32, u32, u32) { + (UpgradesStarted::take(), UpgradesCompleted::take(), UpgradesFailed::take().len() as u32) +} + +/// Build genesis storage according to the mock runtime. +pub fn new_test_ext() -> sp_io::TestExternalities { + sp_io::TestExternalities::new(Default::default()) +} + +/// Run this closure in test externalities. +pub fn test_closure(f: impl FnOnce() -> R) -> R { + let mut ext = new_test_ext(); + ext.execute_with(f) +} + +pub fn run_to_block(n: u32) { + while System::block_number() < n as u64 { + log::debug!("Block {}", System::block_number()); + System::set_block_number(System::block_number() + 1); + System::on_initialize(System::block_number()); + Migrations::on_initialize(System::block_number()); + // Executive calls this: + ::step(); + + Migrations::on_finalize(System::block_number()); + System::on_finalize(System::block_number()); + } +} + +/// Returns the historic migrations, sorted by their identifier. +pub fn historic() -> Vec { + let mut historic = Historic::::iter_keys().collect::>(); + historic.sort(); + historic +} + +// Traits to make using events less insufferable: +pub trait IntoRecord { + fn into_record(self) -> EventRecord<::RuntimeEvent, H256>; +} + +impl IntoRecord for Event { + fn into_record(self) -> EventRecord<::RuntimeEvent, H256> { + let re: ::RuntimeEvent = self.into(); + EventRecord { phase: frame_system::Phase::Initialization, event: re, topics: vec![] } + } +} + +pub trait IntoRecords { + fn into_records(self) -> Vec::RuntimeEvent, H256>>; +} + +impl IntoRecords for Vec { + fn into_records(self) -> Vec::RuntimeEvent, H256>> { + self.into_iter().map(|e| e.into_record()).collect() + } +} + +pub fn assert_events(events: Vec) { + pretty_assertions::assert_eq!(events.into_records(), System::events()); + System::reset_events(); +} diff --git a/substrate/frame/migrations/src/mock_helpers.rs b/substrate/frame/migrations/src/mock_helpers.rs new file mode 100644 index 00000000000..c5e23efb4e3 --- /dev/null +++ b/substrate/frame/migrations/src/mock_helpers.rs @@ -0,0 +1,142 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Test helpers for internal and external usage. + +#![allow(missing_docs)] + +use codec::{Decode, Encode}; +use frame_support::{ + migrations::*, + weights::{Weight, WeightMeter}, +}; +use sp_core::ConstU32; +use sp_runtime::BoundedVec; +use sp_std::{vec, vec::Vec}; + +/// Opaque identifier of a migration. +pub type MockedIdentifier = BoundedVec>; + +/// How a mocked migration should behave. +#[derive(Debug, Clone, Copy, Encode, Decode)] +pub enum MockedMigrationKind { + /// Succeed after its number of steps elapsed. + SucceedAfter, + /// Fail after its number of steps elapsed. + FailAfter, + /// Never terminate. + TimeoutAfter, + /// Cause an [`SteppedMigrationError::InsufficientWeight`] error after its number of steps + /// elapsed. + HighWeightAfter(Weight), +} +use MockedMigrationKind::*; // C style + +/// Creates a migration identifier with a specific `kind` and `steps`. +pub fn mocked_id(kind: MockedMigrationKind, steps: u32) -> MockedIdentifier { + (b"MockedMigration", kind, steps).encode().try_into().unwrap() +} + +frame_support::parameter_types! { + /// The configs for the migrations to run. + storage MIGRATIONS: Vec<(MockedMigrationKind, u32)> = vec![]; +} + +/// Allows to set the migrations to run at runtime instead of compile-time. +/// +/// It achieves this by using the storage to store the migrations to run. +pub struct MockedMigrations; +impl SteppedMigrations for MockedMigrations { + fn len() -> u32 { + MIGRATIONS::get().len() as u32 + } + + fn nth_id(n: u32) -> Option> { + let k = MIGRATIONS::get().get(n as usize).copied(); + k.map(|(kind, steps)| mocked_id(kind, steps).into_inner()) + } + + fn nth_step( + n: u32, + cursor: Option>, + _meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>> { + let (kind, steps) = MIGRATIONS::get()[n as usize]; + + let mut count: u32 = + cursor.as_ref().and_then(|c| Decode::decode(&mut &c[..]).ok()).unwrap_or(0); + log::debug!("MockedMigration: Step {}", count); + if count != steps || matches!(kind, TimeoutAfter) { + count += 1; + return Some(Ok(Some(count.encode()))) + } + + Some(match kind { + SucceedAfter => { + log::debug!("MockedMigration: Succeeded after {} steps", count); + Ok(None) + }, + HighWeightAfter(required) => { + log::debug!("MockedMigration: Not enough weight after {} steps", count); + Err(SteppedMigrationError::InsufficientWeight { required }) + }, + FailAfter => { + log::debug!("MockedMigration: Failed after {} steps", count); + Err(SteppedMigrationError::Failed) + }, + TimeoutAfter => unreachable!(), + }) + } + + fn nth_transactional_step( + n: u32, + cursor: Option>, + meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>> { + // This is a hack but should be fine. We dont need it in testing. + Self::nth_step(n, cursor, meter) + } + + fn nth_max_steps(n: u32) -> Option> { + MIGRATIONS::get().get(n as usize).map(|(_, s)| Some(*s)) + } + + fn cursor_max_encoded_len() -> usize { + 65_536 + } + + fn identifier_max_encoded_len() -> usize { + 256 + } +} + +impl MockedMigrations { + /// Set the migrations to run. + pub fn set(migrations: Vec<(MockedMigrationKind, u32)>) { + MIGRATIONS::set(&migrations); + } +} + +impl crate::MockedMigrations for MockedMigrations { + fn set_fail_after(steps: u32) { + MIGRATIONS::set(&vec![(FailAfter, steps)]); + } + + fn set_success_after(steps: u32) { + MIGRATIONS::set(&vec![(SucceedAfter, steps)]); + } +} diff --git a/substrate/frame/migrations/src/tests.rs b/substrate/frame/migrations/src/tests.rs new file mode 100644 index 00000000000..9c9043d37a6 --- /dev/null +++ b/substrate/frame/migrations/src/tests.rs @@ -0,0 +1,335 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![cfg(test)] + +use crate::{ + mock::{Test as T, *}, + mock_helpers::{MockedMigrationKind::*, *}, + Cursor, Event, FailedMigrationHandling, MigrationCursor, +}; +use frame_support::{pallet_prelude::Weight, traits::OnRuntimeUpgrade}; + +#[docify::export] +#[test] +fn simple_works() { + use Event::*; + test_closure(|| { + // Add three migrations, each taking one block longer than the previous. + MockedMigrations::set(vec![(SucceedAfter, 0), (SucceedAfter, 1), (SucceedAfter, 2)]); + + System::set_block_number(1); + Migrations::on_runtime_upgrade(); + run_to_block(10); + + // Check that the executed migrations are recorded in `Historical`. + assert_eq!( + historic(), + vec![ + mocked_id(SucceedAfter, 0), + mocked_id(SucceedAfter, 1), + mocked_id(SucceedAfter, 2), + ] + ); + + // Check that we got all events. + assert_events(vec![ + UpgradeStarted { migrations: 3 }, + MigrationCompleted { index: 0, took: 1 }, + MigrationAdvanced { index: 1, took: 0 }, + MigrationCompleted { index: 1, took: 1 }, + MigrationAdvanced { index: 2, took: 0 }, + MigrationAdvanced { index: 2, took: 1 }, + MigrationCompleted { index: 2, took: 2 }, + UpgradeCompleted, + ]); + }); +} + +#[test] +fn failing_migration_sets_cursor_to_stuck() { + test_closure(|| { + FailedUpgradeResponse::set(FailedMigrationHandling::KeepStuck); + MockedMigrations::set(vec![(FailAfter, 2)]); + + System::set_block_number(1); + Migrations::on_runtime_upgrade(); + run_to_block(10); + + // Failed migrations are not recorded in `Historical`. + assert!(historic().is_empty()); + // Check that we got all events. + assert_events(vec![ + Event::UpgradeStarted { migrations: 1 }, + Event::MigrationAdvanced { index: 0, took: 1 }, + Event::MigrationAdvanced { index: 0, took: 2 }, + Event::MigrationFailed { index: 0, took: 3 }, + Event::UpgradeFailed, + ]); + + // Check that the handler was called correctly. + assert_eq!(UpgradesStarted::take(), 1); + assert_eq!(UpgradesCompleted::take(), 0); + assert_eq!(UpgradesFailed::take(), vec![Some(0)]); + + assert_eq!(Cursor::::get(), Some(MigrationCursor::Stuck), "Must stuck the chain"); + }); +} + +#[test] +fn failing_migration_force_unstuck_works() { + test_closure(|| { + FailedUpgradeResponse::set(FailedMigrationHandling::ForceUnstuck); + MockedMigrations::set(vec![(FailAfter, 2)]); + + System::set_block_number(1); + Migrations::on_runtime_upgrade(); + run_to_block(10); + + // Failed migrations are not recorded in `Historical`. + assert!(historic().is_empty()); + // Check that we got all events. + assert_events(vec![ + Event::UpgradeStarted { migrations: 1 }, + Event::MigrationAdvanced { index: 0, took: 1 }, + Event::MigrationAdvanced { index: 0, took: 2 }, + Event::MigrationFailed { index: 0, took: 3 }, + Event::UpgradeFailed, + ]); + + // Check that the handler was called correctly. + assert_eq!(UpgradesStarted::take(), 1); + assert_eq!(UpgradesCompleted::take(), 0); + assert_eq!(UpgradesFailed::take(), vec![Some(0)]); + + assert!(Cursor::::get().is_none(), "Must unstuck the chain"); + }); +} + +/// A migration that reports not getting enough weight errors if it is the first one to run in that +/// block. +#[test] +fn high_weight_migration_singular_fails() { + test_closure(|| { + MockedMigrations::set(vec![(HighWeightAfter(Weight::zero()), 2)]); + + System::set_block_number(1); + Migrations::on_runtime_upgrade(); + run_to_block(10); + + // Failed migrations are not recorded in `Historical`. + assert!(historic().is_empty()); + // Check that we got all events. + assert_events(vec![ + Event::UpgradeStarted { migrations: 1 }, + Event::MigrationAdvanced { index: 0, took: 1 }, + Event::MigrationAdvanced { index: 0, took: 2 }, + Event::MigrationFailed { index: 0, took: 3 }, + Event::UpgradeFailed, + ]); + + // Check that the handler was called correctly. + assert_eq!(upgrades_started_completed_failed(), (1, 0, 1)); + assert_eq!(Cursor::::get(), Some(MigrationCursor::Stuck)); + }); +} + +/// A migration that reports of not getting enough weight is retried once, if it is not the first +/// one to run in a block. +#[test] +fn high_weight_migration_retries_once() { + test_closure(|| { + MockedMigrations::set(vec![(SucceedAfter, 0), (HighWeightAfter(Weight::zero()), 0)]); + + System::set_block_number(1); + Migrations::on_runtime_upgrade(); + run_to_block(10); + + assert_eq!(historic(), vec![mocked_id(SucceedAfter, 0)]); + // Check that we got all events. + assert_events::>(vec![ + Event::UpgradeStarted { migrations: 2 }, + Event::MigrationCompleted { index: 0, took: 1 }, + // `took=1` means that it was retried once. + Event::MigrationFailed { index: 1, took: 1 }, + Event::UpgradeFailed, + ]); + + // Check that the handler was called correctly. + assert_eq!(upgrades_started_completed_failed(), (1, 0, 1)); + assert_eq!(Cursor::::get(), Some(MigrationCursor::Stuck)); + }); +} + +/// If a migration uses more weight than the limit, then it will not retry but fail even when it is +/// not the first one in the block. +// Note: Same as `high_weight_migration_retries_once` but with different required weight for the +// migration. +#[test] +fn high_weight_migration_permanently_overweight_fails() { + test_closure(|| { + MockedMigrations::set(vec![(SucceedAfter, 0), (HighWeightAfter(Weight::MAX), 0)]); + + System::set_block_number(1); + Migrations::on_runtime_upgrade(); + run_to_block(10); + + assert_eq!(historic(), vec![mocked_id(SucceedAfter, 0)]); + // Check that we got all events. + assert_events::>(vec![ + Event::UpgradeStarted { migrations: 2 }, + Event::MigrationCompleted { index: 0, took: 1 }, + // `blocks=0` means that it was not retried. + Event::MigrationFailed { index: 1, took: 0 }, + Event::UpgradeFailed, + ]); + + // Check that the handler was called correctly. + assert_eq!(upgrades_started_completed_failed(), (1, 0, 1)); + assert_eq!(Cursor::::get(), Some(MigrationCursor::Stuck)); + }); +} + +#[test] +fn historic_skipping_works() { + test_closure(|| { + MockedMigrations::set(vec![ + (SucceedAfter, 0), + (SucceedAfter, 0), // duplicate + (SucceedAfter, 1), + (SucceedAfter, 2), + (SucceedAfter, 1), // duplicate + ]); + + System::set_block_number(1); + Migrations::on_runtime_upgrade(); + run_to_block(10); + + // Just three historical ones, since two were added twice. + assert_eq!( + historic(), + vec![ + mocked_id(SucceedAfter, 0), + mocked_id(SucceedAfter, 1), + mocked_id(SucceedAfter, 2), + ] + ); + // Events received. + assert_events(vec![ + Event::UpgradeStarted { migrations: 5 }, + Event::MigrationCompleted { index: 0, took: 1 }, + Event::MigrationSkipped { index: 1 }, + Event::MigrationAdvanced { index: 2, took: 0 }, + Event::MigrationCompleted { index: 2, took: 1 }, + Event::MigrationAdvanced { index: 3, took: 0 }, + Event::MigrationAdvanced { index: 3, took: 1 }, + Event::MigrationCompleted { index: 3, took: 2 }, + Event::MigrationSkipped { index: 4 }, + Event::UpgradeCompleted, + ]); + assert_eq!(upgrades_started_completed_failed(), (1, 1, 0)); + + // Now go for another upgrade; just to make sure that it wont execute again. + System::reset_events(); + Migrations::on_runtime_upgrade(); + run_to_block(20); + + // Same historical ones as before. + assert_eq!( + historic(), + vec![ + mocked_id(SucceedAfter, 0), + mocked_id(SucceedAfter, 1), + mocked_id(SucceedAfter, 2), + ] + ); + + // Everything got skipped. + assert_events(vec![ + Event::UpgradeStarted { migrations: 5 }, + Event::MigrationSkipped { index: 0 }, + Event::MigrationSkipped { index: 1 }, + Event::MigrationSkipped { index: 2 }, + Event::MigrationSkipped { index: 3 }, + Event::MigrationSkipped { index: 4 }, + Event::UpgradeCompleted, + ]); + assert_eq!(upgrades_started_completed_failed(), (1, 1, 0)); + }); +} + +/// When another upgrade happens while a migration is still running, it should set the cursor to +/// stuck. +#[test] +fn upgrade_fails_when_migration_active() { + test_closure(|| { + MockedMigrations::set(vec![(SucceedAfter, 10)]); + + System::set_block_number(1); + Migrations::on_runtime_upgrade(); + run_to_block(3); + + // Events received. + assert_events(vec![ + Event::UpgradeStarted { migrations: 1 }, + Event::MigrationAdvanced { index: 0, took: 1 }, + Event::MigrationAdvanced { index: 0, took: 2 }, + ]); + assert_eq!(upgrades_started_completed_failed(), (1, 0, 0)); + + // Upgrade again. + Migrations::on_runtime_upgrade(); + // -- Defensive path -- + assert_eq!(Cursor::::get(), Some(MigrationCursor::Stuck)); + assert_events(vec![Event::UpgradeFailed]); + assert_eq!(upgrades_started_completed_failed(), (0, 0, 1)); + }); +} + +#[test] +fn migration_timeout_errors() { + test_closure(|| { + MockedMigrations::set(vec![(TimeoutAfter, 3)]); + + System::set_block_number(1); + Migrations::on_runtime_upgrade(); + run_to_block(5); + + // Times out after taking more than 3 steps. + assert_events(vec![ + Event::UpgradeStarted { migrations: 1 }, + Event::MigrationAdvanced { index: 0, took: 1 }, + Event::MigrationAdvanced { index: 0, took: 2 }, + Event::MigrationAdvanced { index: 0, took: 3 }, + Event::MigrationAdvanced { index: 0, took: 4 }, + Event::MigrationFailed { index: 0, took: 4 }, + Event::UpgradeFailed, + ]); + assert_eq!(upgrades_started_completed_failed(), (1, 0, 1)); + + // Failed migrations are not black-listed. + assert!(historic().is_empty()); + assert_eq!(Cursor::::get(), Some(MigrationCursor::Stuck)); + + Migrations::on_runtime_upgrade(); + run_to_block(6); + + assert_events(vec![Event::UpgradeFailed]); + assert_eq!(Cursor::::get(), Some(MigrationCursor::Stuck)); + assert_eq!(upgrades_started_completed_failed(), (0, 0, 1)); + }); +} diff --git a/substrate/frame/migrations/src/weights.rs b/substrate/frame/migrations/src/weights.rs new file mode 100644 index 00000000000..c9b63258c44 --- /dev/null +++ b/substrate/frame/migrations/src/weights.rs @@ -0,0 +1,358 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Autogenerated weights for `pallet_migrations` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-04, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `loud1`, CPU: `AMD EPYC 7282 16-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` + +// Executed Command: +// target/release/substrate-node +// benchmark +// pallet +// --chain +// dev +// --pallet +// pallet-migrations +// --extrinsic +// +// --output +// weight.rs +// --template +// ../../polkadot-sdk/substrate/.maintain/frame-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for `pallet_migrations`. +pub trait WeightInfo { + fn onboard_new_mbms() -> Weight; + fn progress_mbms_none() -> Weight; + fn exec_migration_completed() -> Weight; + fn exec_migration_skipped_historic() -> Weight; + fn exec_migration_advance() -> Weight; + fn exec_migration_complete() -> Weight; + fn exec_migration_fail() -> Weight; + fn on_init_loop() -> Weight; + fn force_set_cursor() -> Weight; + fn force_set_active_cursor() -> Weight; + fn force_onboard_mbms() -> Weight; + fn clear_historic(n: u32, ) -> Weight; +} + +/// Weights for `pallet_migrations` using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + fn onboard_new_mbms() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `67035` + // Minimum execution time: 13_980_000 picoseconds. + Weight::from_parts(14_290_000, 67035) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn progress_mbms_none() -> Weight { + // Proof Size summary in bytes: + // Measured: `109` + // Estimated: `67035` + // Minimum execution time: 3_770_000 picoseconds. + Weight::from_parts(4_001_000, 67035) + .saturating_add(T::DbWeight::get().reads(1_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn exec_migration_completed() -> Weight { + // Proof Size summary in bytes: + // Measured: `134` + // Estimated: `3599` + // Minimum execution time: 10_900_000 picoseconds. + Weight::from_parts(11_251_000, 3599) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Historic` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + fn exec_migration_skipped_historic() -> Weight { + // Proof Size summary in bytes: + // Measured: `297` + // Estimated: `3762` + // Minimum execution time: 17_891_000 picoseconds. + Weight::from_parts(18_501_000, 3762) + .saturating_add(T::DbWeight::get().reads(2_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Historic` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + fn exec_migration_advance() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `3731` + // Minimum execution time: 18_271_000 picoseconds. + Weight::from_parts(18_740_000, 3731) + .saturating_add(T::DbWeight::get().reads(2_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Historic` (r:1 w:1) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + fn exec_migration_complete() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `3731` + // Minimum execution time: 21_241_000 picoseconds. + Weight::from_parts(21_911_000, 3731) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Historic` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn exec_migration_fail() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `3731` + // Minimum execution time: 22_740_000 picoseconds. + Weight::from_parts(23_231_000, 3731) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + fn on_init_loop() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 440_000 picoseconds. + Weight::from_parts(500_000, 0) + } + /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn force_set_cursor() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_751_000 picoseconds. + Weight::from_parts(5_950_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn force_set_active_cursor() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_350_000 picoseconds. + Weight::from_parts(6_560_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + fn force_onboard_mbms() -> Weight { + // Proof Size summary in bytes: + // Measured: `218` + // Estimated: `67035` + // Minimum execution time: 11_121_000 picoseconds. + Weight::from_parts(11_530_000, 67035) + .saturating_add(T::DbWeight::get().reads(2_u64)) + } + /// Storage: `MultiBlockMigrations::Historic` (r:256 w:256) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + /// The range of component `n` is `[0, 256]`. + fn clear_historic(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1089 + n * (271 ±0)` + // Estimated: `3834 + n * (2740 ±0)` + // Minimum execution time: 21_891_000 picoseconds. + Weight::from_parts(18_572_306, 3834) + // Standard Error: 3_236 + .saturating_add(Weight::from_parts(1_648_429, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2740).saturating_mul(n.into())) + } +} + +// For backwards compatibility and tests. +impl WeightInfo for () { + /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + fn onboard_new_mbms() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `67035` + // Minimum execution time: 13_980_000 picoseconds. + Weight::from_parts(14_290_000, 67035) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn progress_mbms_none() -> Weight { + // Proof Size summary in bytes: + // Measured: `109` + // Estimated: `67035` + // Minimum execution time: 3_770_000 picoseconds. + Weight::from_parts(4_001_000, 67035) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn exec_migration_completed() -> Weight { + // Proof Size summary in bytes: + // Measured: `134` + // Estimated: `3599` + // Minimum execution time: 10_900_000 picoseconds. + Weight::from_parts(11_251_000, 3599) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Historic` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + fn exec_migration_skipped_historic() -> Weight { + // Proof Size summary in bytes: + // Measured: `297` + // Estimated: `3762` + // Minimum execution time: 17_891_000 picoseconds. + Weight::from_parts(18_501_000, 3762) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Historic` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + fn exec_migration_advance() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `3731` + // Minimum execution time: 18_271_000 picoseconds. + Weight::from_parts(18_740_000, 3731) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Historic` (r:1 w:1) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + fn exec_migration_complete() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `3731` + // Minimum execution time: 21_241_000 picoseconds. + Weight::from_parts(21_911_000, 3731) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Historic` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn exec_migration_fail() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `3731` + // Minimum execution time: 22_740_000 picoseconds. + Weight::from_parts(23_231_000, 3731) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + fn on_init_loop() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 440_000 picoseconds. + Weight::from_parts(500_000, 0) + } + /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn force_set_cursor() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_751_000 picoseconds. + Weight::from_parts(5_950_000, 0) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn force_set_active_cursor() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_350_000 picoseconds. + Weight::from_parts(6_560_000, 0) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + fn force_onboard_mbms() -> Weight { + // Proof Size summary in bytes: + // Measured: `218` + // Estimated: `67035` + // Minimum execution time: 11_121_000 picoseconds. + Weight::from_parts(11_530_000, 67035) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + } + /// Storage: `MultiBlockMigrations::Historic` (r:256 w:256) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + /// The range of component `n` is `[0, 256]`. + fn clear_historic(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1089 + n * (271 ±0)` + // Estimated: `3834 + n * (2740 ±0)` + // Minimum execution time: 21_891_000 picoseconds. + Weight::from_parts(18_572_306, 3834) + // Standard Error: 3_236 + .saturating_add(Weight::from_parts(1_648_429, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) + .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2740).saturating_mul(n.into())) + } +} diff --git a/substrate/frame/src/lib.rs b/substrate/frame/src/lib.rs index a2e5d726fdd..52db7c34bfd 100644 --- a/substrate/frame/src/lib.rs +++ b/substrate/frame/src/lib.rs @@ -197,7 +197,7 @@ pub mod runtime { // Types often used in the runtime APIs. pub use sp_core::OpaqueMetadata; pub use sp_inherents::{CheckInherentsResult, InherentData}; - pub use sp_runtime::ApplyExtrinsicResult; + pub use sp_runtime::{ApplyExtrinsicResult, ExtrinsicInclusionMode}; pub use frame_system_rpc_runtime_api::*; pub use sp_api::{self, *}; diff --git a/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs b/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs index 34b9d21d8ce..da483fa6cf0 100644 --- a/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs +++ b/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs @@ -204,47 +204,50 @@ pub fn expand_outer_inherent( } } + impl #scrate::traits::IsInherent<<#block as #scrate::sp_runtime::traits::Block>::Extrinsic> for #runtime { + fn is_inherent(ext: &<#block as #scrate::sp_runtime::traits::Block>::Extrinsic) -> bool { + use #scrate::inherent::ProvideInherent; + use #scrate::traits::{IsSubType, ExtrinsicCall}; + + if #scrate::sp_runtime::traits::Extrinsic::is_signed(ext).unwrap_or(false) { + // Signed extrinsics are never inherents. + return false + } + + #( + #pallet_attrs + { + let call = <#unchecked_extrinsic as ExtrinsicCall>::call(ext); + if let Some(call) = IsSubType::<_>::is_sub_type(call) { + if <#pallet_names as ProvideInherent>::is_inherent(&call) { + return true; + } + } + } + )* + false + } + } + impl #scrate::traits::EnsureInherentsAreFirst<#block> for #runtime { - fn ensure_inherents_are_first(block: &#block) -> Result<(), u32> { + fn ensure_inherents_are_first(block: &#block) -> Result { use #scrate::inherent::ProvideInherent; use #scrate::traits::{IsSubType, ExtrinsicCall}; use #scrate::sp_runtime::traits::Block as _; - let mut first_signed_observed = false; + let mut num_inherents = 0u32; for (i, xt) in block.extrinsics().iter().enumerate() { - let is_signed = #scrate::sp_runtime::traits::Extrinsic::is_signed(xt) - .unwrap_or(false); - - let is_inherent = if is_signed { - // Signed extrinsics are not inherents. - false - } else { - let mut is_inherent = false; - #( - #pallet_attrs - { - let call = <#unchecked_extrinsic as ExtrinsicCall>::call(xt); - if let Some(call) = IsSubType::<_>::is_sub_type(call) { - if #pallet_names::is_inherent(&call) { - is_inherent = true; - } - } - } - )* - is_inherent - }; - - if !is_inherent { - first_signed_observed = true; - } + if >::is_inherent(xt) { + if num_inherents != i as u32 { + return Err(i as u32); + } - if first_signed_observed && is_inherent { - return Err(i as u32) + num_inherents += 1; // Safe since we are in an `enumerate` loop. } } - Ok(()) + Ok(num_inherents) } } } diff --git a/substrate/frame/support/procedural/src/pallet/expand/hooks.rs b/substrate/frame/support/procedural/src/pallet/expand/hooks.rs index 6b25ddcba1a..3623b595268 100644 --- a/substrate/frame/support/procedural/src/pallet/expand/hooks.rs +++ b/substrate/frame/support/procedural/src/pallet/expand/hooks.rs @@ -175,6 +175,22 @@ pub fn expand_hooks(def: &mut Def) -> proc_macro2::TokenStream { } } + impl<#type_impl_gen> + #frame_support::traits::OnPoll<#frame_system::pallet_prelude::BlockNumberFor::> + for #pallet_ident<#type_use_gen> #where_clause + { + fn on_poll( + n: #frame_system::pallet_prelude::BlockNumberFor::, + weight: &mut #frame_support::weights::WeightMeter + ) { + < + Self as #frame_support::traits::Hooks< + #frame_system::pallet_prelude::BlockNumberFor:: + > + >::on_poll(n, weight); + } + } + impl<#type_impl_gen> #frame_support::traits::OnInitialize<#frame_system::pallet_prelude::BlockNumberFor::> for #pallet_ident<#type_use_gen> #where_clause diff --git a/substrate/frame/support/src/migrations.rs b/substrate/frame/support/src/migrations.rs index f7541059023..2ceab44cb16 100644 --- a/substrate/frame/support/src/migrations.rs +++ b/substrate/frame/support/src/migrations.rs @@ -16,13 +16,21 @@ // limitations under the License. use crate::{ - traits::{GetStorageVersion, NoStorageVersionSet, PalletInfoAccess, StorageVersion}, - weights::{RuntimeDbWeight, Weight}, + defensive, + storage::transactional::with_transaction_opaque_err, + traits::{ + Defensive, GetStorageVersion, NoStorageVersionSet, PalletInfoAccess, SafeMode, + StorageVersion, + }, + weights::{RuntimeDbWeight, Weight, WeightMeter}, }; +use codec::{Decode, Encode, MaxEncodedLen}; use impl_trait_for_tuples::impl_for_tuples; +use sp_arithmetic::traits::Bounded; use sp_core::Get; use sp_io::{hashing::twox_128, storage::clear_prefix, KillStorageResult}; -use sp_std::marker::PhantomData; +use sp_runtime::traits::Zero; +use sp_std::{marker::PhantomData, vec::Vec}; /// Handles storage migration pallet versioning. /// @@ -91,7 +99,7 @@ pub struct VersionedMigration), @@ -118,7 +126,6 @@ impl< /// migration ran or not. #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { - use codec::Encode; let on_chain_version = Pallet::on_chain_storage_version(); if on_chain_version == FROM { Ok(VersionedPostUpgradeData::MigrationExecuted(Inner::pre_upgrade()?).encode()) @@ -361,3 +368,622 @@ impl, DbWeight: Get> frame_support::traits Ok(()) } } + +/// A migration that can proceed in multiple steps. +pub trait SteppedMigration { + /// The cursor type that stores the progress (aka. state) of this migration. + type Cursor: codec::FullCodec + codec::MaxEncodedLen; + + /// The unique identifier type of this migration. + type Identifier: codec::FullCodec + codec::MaxEncodedLen; + + /// The unique identifier of this migration. + /// + /// If two migrations have the same identifier, then they are assumed to be identical. + fn id() -> Self::Identifier; + + /// The maximum number of steps that this migration can take. + /// + /// This can be used to enforce progress and prevent migrations becoming stuck forever. A + /// migration that exceeds its max steps is treated as failed. `None` means that there is no + /// limit. + fn max_steps() -> Option { + None + } + + /// Try to migrate as much as possible with the given weight. + /// + /// **ANY STORAGE CHANGES MUST BE ROLLED-BACK BY THE CALLER UPON ERROR.** This is necessary + /// since the caller cannot return a cursor in the error case. [`Self::transactional_step`] is + /// provided as convenience for a caller. A cursor of `None` implies that the migration is at + /// its end. A migration that once returned `Nonce` is guaranteed to never be called again. + fn step( + cursor: Option, + meter: &mut WeightMeter, + ) -> Result, SteppedMigrationError>; + + /// Same as [`Self::step`], but rolls back pending changes in the error case. + fn transactional_step( + mut cursor: Option, + meter: &mut WeightMeter, + ) -> Result, SteppedMigrationError> { + with_transaction_opaque_err(move || match Self::step(cursor, meter) { + Ok(new_cursor) => { + cursor = new_cursor; + sp_runtime::TransactionOutcome::Commit(Ok(cursor)) + }, + Err(err) => sp_runtime::TransactionOutcome::Rollback(Err(err)), + }) + .map_err(|()| SteppedMigrationError::Failed)? + } +} + +/// Error that can occur during a [`SteppedMigration`]. +#[derive(Debug, Encode, Decode, MaxEncodedLen, scale_info::TypeInfo)] +pub enum SteppedMigrationError { + // Transient errors: + /// The remaining weight is not enough to do anything. + /// + /// Can be resolved by calling with at least `required` weight. Note that calling it with + /// exactly `required` weight could cause it to not make any progress. + InsufficientWeight { + /// Amount of weight required to make progress. + required: Weight, + }, + // Permanent errors: + /// The migration cannot decode its cursor and therefore not proceed. + /// + /// This should not happen unless (1) the migration itself returned an invalid cursor in a + /// previous iteration, (2) the storage got corrupted or (3) there is a bug in the caller's + /// code. + InvalidCursor, + /// The migration encountered a permanent error and cannot continue. + Failed, +} + +/// Notification handler for status updates regarding Multi-Block-Migrations. +#[impl_trait_for_tuples::impl_for_tuples(8)] +pub trait MigrationStatusHandler { + /// Notifies of the start of a runtime migration. + fn started() {} + + /// Notifies of the completion of a runtime migration. + fn completed() {} +} + +/// Handles a failed runtime migration. +/// +/// This should never happen, but is here for completeness. +pub trait FailedMigrationHandler { + /// Infallibly handle a failed runtime migration. + /// + /// Gets passed in the optional index of the migration in the batch that caused the failure. + /// Returning `None` means that no automatic handling should take place and the callee decides + /// in the implementation what to do. + fn failed(migration: Option) -> FailedMigrationHandling; +} + +/// Do now allow any transactions to be processed after a runtime upgrade failed. +/// +/// This is **not a sane default**, since it prevents governance intervention. +pub struct FreezeChainOnFailedMigration; + +impl FailedMigrationHandler for FreezeChainOnFailedMigration { + fn failed(_migration: Option) -> FailedMigrationHandling { + FailedMigrationHandling::KeepStuck + } +} + +/// Enter safe mode on a failed runtime upgrade. +/// +/// This can be very useful to manually intervene and fix the chain state. `Else` is used in case +/// that the safe mode could not be entered. +pub struct EnterSafeModeOnFailedMigration( + PhantomData<(SM, Else)>, +); + +impl FailedMigrationHandler + for EnterSafeModeOnFailedMigration +where + ::BlockNumber: Bounded, +{ + fn failed(migration: Option) -> FailedMigrationHandling { + let entered = if SM::is_entered() { + SM::extend(Bounded::max_value()) + } else { + SM::enter(Bounded::max_value()) + }; + + // If we could not enter or extend safe mode (for whatever reason), then we try the next. + if entered.is_err() { + Else::failed(migration) + } else { + FailedMigrationHandling::KeepStuck + } + } +} + +/// How to proceed after a runtime upgrade failed. +/// +/// There is NO SANE DEFAULT HERE. All options are very dangerous and should be used with care. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum FailedMigrationHandling { + /// Resume extrinsic processing of the chain. This will not resume the upgrade. + /// + /// This should be supplemented with additional measures to ensure that the broken chain state + /// does not get further messed up by user extrinsics. + ForceUnstuck, + /// Set the cursor to `Stuck` and keep blocking extrinsics. + KeepStuck, + /// Don't do anything with the cursor and let the handler decide. + /// + /// This can be useful in cases where the other two options would overwrite any changes that + /// were done by the handler to the cursor. + Ignore, +} + +/// Something that can do multi step migrations. +pub trait MultiStepMigrator { + /// Hint for whether [`Self::step`] should be called. + fn ongoing() -> bool; + + /// Do the next step in the MBM process. + /// + /// Must gracefully handle the case that it is currently not upgrading. + fn step() -> Weight; +} + +impl MultiStepMigrator for () { + fn ongoing() -> bool { + false + } + + fn step() -> Weight { + Weight::zero() + } +} + +/// Multiple [`SteppedMigration`]. +pub trait SteppedMigrations { + /// The number of migrations that `Self` aggregates. + fn len() -> u32; + + /// The `n`th [`SteppedMigration::id`]. + /// + /// Is guaranteed to return `Some` if `n < Self::len()`. + fn nth_id(n: u32) -> Option>; + + /// The [`SteppedMigration::max_steps`] of the `n`th migration. + /// + /// Is guaranteed to return `Some` if `n < Self::len()`. + fn nth_max_steps(n: u32) -> Option>; + + /// Do a [`SteppedMigration::step`] on the `n`th migration. + /// + /// Is guaranteed to return `Some` if `n < Self::len()`. + fn nth_step( + n: u32, + cursor: Option>, + meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>>; + + /// Do a [`SteppedMigration::transactional_step`] on the `n`th migration. + /// + /// Is guaranteed to return `Some` if `n < Self::len()`. + fn nth_transactional_step( + n: u32, + cursor: Option>, + meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>>; + + /// The maximal encoded length across all cursors. + fn cursor_max_encoded_len() -> usize; + + /// The maximal encoded length across all identifiers. + fn identifier_max_encoded_len() -> usize; + + /// Assert the integrity of the migrations. + /// + /// Should be executed as part of a test prior to runtime usage. May or may not need + /// externalities. + #[cfg(feature = "std")] + fn integrity_test() -> Result<(), &'static str> { + use crate::ensure; + let l = Self::len(); + + for n in 0..l { + ensure!(Self::nth_id(n).is_some(), "id is None"); + ensure!(Self::nth_max_steps(n).is_some(), "steps is None"); + + // The cursor that we use does not matter. Hence use empty. + ensure!( + Self::nth_step(n, Some(vec![]), &mut WeightMeter::new()).is_some(), + "steps is None" + ); + ensure!( + Self::nth_transactional_step(n, Some(vec![]), &mut WeightMeter::new()).is_some(), + "steps is None" + ); + } + + Ok(()) + } +} + +impl SteppedMigrations for () { + fn len() -> u32 { + 0 + } + + fn nth_id(_n: u32) -> Option> { + None + } + + fn nth_max_steps(_n: u32) -> Option> { + None + } + + fn nth_step( + _n: u32, + _cursor: Option>, + _meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>> { + None + } + + fn nth_transactional_step( + _n: u32, + _cursor: Option>, + _meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>> { + None + } + + fn cursor_max_encoded_len() -> usize { + 0 + } + + fn identifier_max_encoded_len() -> usize { + 0 + } +} + +// A collection consisting of only a single migration. +impl SteppedMigrations for T { + fn len() -> u32 { + 1 + } + + fn nth_id(_n: u32) -> Option> { + Some(T::id().encode()) + } + + fn nth_max_steps(n: u32) -> Option> { + // It should be generally fine to call with n>0, but the code should not attempt to. + n.is_zero() + .then_some(T::max_steps()) + .defensive_proof("nth_max_steps should only be called with n==0") + } + + fn nth_step( + _n: u32, + cursor: Option>, + meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>> { + if !_n.is_zero() { + defensive!("nth_step should only be called with n==0"); + return None + } + + let cursor = match cursor { + Some(cursor) => match T::Cursor::decode(&mut &cursor[..]) { + Ok(cursor) => Some(cursor), + Err(_) => return Some(Err(SteppedMigrationError::InvalidCursor)), + }, + None => None, + }; + + Some(T::step(cursor, meter).map(|cursor| cursor.map(|cursor| cursor.encode()))) + } + + fn nth_transactional_step( + n: u32, + cursor: Option>, + meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>> { + if n != 0 { + defensive!("nth_transactional_step should only be called with n==0"); + return None + } + + let cursor = match cursor { + Some(cursor) => match T::Cursor::decode(&mut &cursor[..]) { + Ok(cursor) => Some(cursor), + Err(_) => return Some(Err(SteppedMigrationError::InvalidCursor)), + }, + None => None, + }; + + Some( + T::transactional_step(cursor, meter).map(|cursor| cursor.map(|cursor| cursor.encode())), + ) + } + + fn cursor_max_encoded_len() -> usize { + T::Cursor::max_encoded_len() + } + + fn identifier_max_encoded_len() -> usize { + T::Identifier::max_encoded_len() + } +} + +#[impl_trait_for_tuples::impl_for_tuples(1, 30)] +impl SteppedMigrations for Tuple { + fn len() -> u32 { + for_tuples!( #( Tuple::len() )+* ) + } + + fn nth_id(n: u32) -> Option> { + let mut i = 0; + + for_tuples!( #( + if (i + Tuple::len()) > n { + return Tuple::nth_id(n - i) + } + + i += Tuple::len(); + )* ); + + None + } + + fn nth_step( + n: u32, + cursor: Option>, + meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>> { + let mut i = 0; + + for_tuples!( #( + if (i + Tuple::len()) > n { + return Tuple::nth_step(n - i, cursor, meter) + } + + i += Tuple::len(); + )* ); + + None + } + + fn nth_transactional_step( + n: u32, + cursor: Option>, + meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>> { + let mut i = 0; + + for_tuples! ( #( + if (i + Tuple::len()) > n { + return Tuple::nth_transactional_step(n - i, cursor, meter) + } + + i += Tuple::len(); + )* ); + + None + } + + fn nth_max_steps(n: u32) -> Option> { + let mut i = 0; + + for_tuples!( #( + if (i + Tuple::len()) > n { + return Tuple::nth_max_steps(n - i) + } + + i += Tuple::len(); + )* ); + + None + } + + fn cursor_max_encoded_len() -> usize { + let mut max_len = 0; + + for_tuples!( #( + max_len = max_len.max(Tuple::cursor_max_encoded_len()); + )* ); + + max_len + } + + fn identifier_max_encoded_len() -> usize { + let mut max_len = 0; + + for_tuples!( #( + max_len = max_len.max(Tuple::identifier_max_encoded_len()); + )* ); + + max_len + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{assert_ok, storage::unhashed}; + + #[derive(Decode, Encode, MaxEncodedLen, Eq, PartialEq)] + pub enum Either { + Left(L), + Right(R), + } + + pub struct M0; + impl SteppedMigration for M0 { + type Cursor = (); + type Identifier = u8; + + fn id() -> Self::Identifier { + 0 + } + + fn step( + _cursor: Option, + _meter: &mut WeightMeter, + ) -> Result, SteppedMigrationError> { + log::info!("M0"); + unhashed::put(&[0], &()); + Ok(None) + } + } + + pub struct M1; + impl SteppedMigration for M1 { + type Cursor = (); + type Identifier = u8; + + fn id() -> Self::Identifier { + 1 + } + + fn step( + _cursor: Option, + _meter: &mut WeightMeter, + ) -> Result, SteppedMigrationError> { + log::info!("M1"); + unhashed::put(&[1], &()); + Ok(None) + } + + fn max_steps() -> Option { + Some(1) + } + } + + pub struct M2; + impl SteppedMigration for M2 { + type Cursor = (); + type Identifier = u8; + + fn id() -> Self::Identifier { + 2 + } + + fn step( + _cursor: Option, + _meter: &mut WeightMeter, + ) -> Result, SteppedMigrationError> { + log::info!("M2"); + unhashed::put(&[2], &()); + Ok(None) + } + + fn max_steps() -> Option { + Some(2) + } + } + + pub struct F0; + impl SteppedMigration for F0 { + type Cursor = (); + type Identifier = u8; + + fn id() -> Self::Identifier { + 3 + } + + fn step( + _cursor: Option, + _meter: &mut WeightMeter, + ) -> Result, SteppedMigrationError> { + log::info!("F0"); + unhashed::put(&[3], &()); + Err(SteppedMigrationError::Failed) + } + } + + // Three migrations combined to execute in order: + type Triple = (M0, (M1, M2)); + // Six migrations, just concatenating the ones from before: + type Hextuple = (Triple, Triple); + + #[test] + fn singular_migrations_work() { + assert_eq!(M0::max_steps(), None); + assert_eq!(M1::max_steps(), Some(1)); + assert_eq!(M2::max_steps(), Some(2)); + + assert_eq!(<(M0, M1)>::nth_max_steps(0), Some(None)); + assert_eq!(<(M0, M1)>::nth_max_steps(1), Some(Some(1))); + assert_eq!(<(M0, M1, M2)>::nth_max_steps(2), Some(Some(2))); + + assert_eq!(<(M0, M1)>::nth_max_steps(2), None); + } + + #[test] + fn tuple_migrations_work() { + assert_eq!(<() as SteppedMigrations>::len(), 0); + assert_eq!(<((), ((), ())) as SteppedMigrations>::len(), 0); + assert_eq!(::len(), 3); + assert_eq!(::len(), 6); + + // Check the IDs. The index specific functions all return an Option, + // to account for the out-of-range case. + assert_eq!(::nth_id(0), Some(0u8.encode())); + assert_eq!(::nth_id(1), Some(1u8.encode())); + assert_eq!(::nth_id(2), Some(2u8.encode())); + + sp_io::TestExternalities::default().execute_with(|| { + for n in 0..3 { + ::nth_step( + n, + Default::default(), + &mut WeightMeter::new(), + ); + } + }); + } + + #[test] + fn integrity_test_works() { + sp_io::TestExternalities::default().execute_with(|| { + assert_ok!(<() as SteppedMigrations>::integrity_test()); + assert_ok!(::integrity_test()); + assert_ok!(::integrity_test()); + assert_ok!(::integrity_test()); + assert_ok!(::integrity_test()); + assert_ok!(::integrity_test()); + }); + } + + #[test] + fn transactional_rollback_works() { + sp_io::TestExternalities::default().execute_with(|| { + assert_ok!(<(M0, F0) as SteppedMigrations>::nth_transactional_step( + 0, + Default::default(), + &mut WeightMeter::new() + ) + .unwrap()); + assert!(unhashed::exists(&[0])); + + let _g = crate::StorageNoopGuard::new(); + assert!(<(M0, F0) as SteppedMigrations>::nth_transactional_step( + 1, + Default::default(), + &mut WeightMeter::new() + ) + .unwrap() + .is_err()); + assert!(<(F0, M1) as SteppedMigrations>::nth_transactional_step( + 0, + Default::default(), + &mut WeightMeter::new() + ) + .unwrap() + .is_err()); + }); + } +} diff --git a/substrate/frame/support/src/storage/transactional.rs b/substrate/frame/support/src/storage/transactional.rs index d42e1809e91..0671db4a3a8 100644 --- a/substrate/frame/support/src/storage/transactional.rs +++ b/substrate/frame/support/src/storage/transactional.rs @@ -127,6 +127,22 @@ where } } +/// Same as [`with_transaction`] but casts any internal error to `()`. +/// +/// This rids `E` of the `From` bound that is required by `with_transaction`. +pub fn with_transaction_opaque_err(f: F) -> Result, ()> +where + F: FnOnce() -> TransactionOutcome>, +{ + with_transaction(move || -> TransactionOutcome, DispatchError>> { + match f() { + TransactionOutcome::Commit(res) => TransactionOutcome::Commit(Ok(res)), + TransactionOutcome::Rollback(res) => TransactionOutcome::Rollback(Ok(res)), + } + }) + .map_err(|_| ()) +} + /// Same as [`with_transaction`] but without a limit check on nested transactional layers. /// /// This is mostly for backwards compatibility before there was a transactional layer limit. diff --git a/substrate/frame/support/src/traits.rs b/substrate/frame/support/src/traits.rs index 3d0429f71b1..1997d8fc223 100644 --- a/substrate/frame/support/src/traits.rs +++ b/substrate/frame/support/src/traits.rs @@ -59,10 +59,10 @@ pub use misc::{ AccountTouch, Backing, ConstBool, ConstI128, ConstI16, ConstI32, ConstI64, ConstI8, ConstU128, ConstU16, ConstU32, ConstU64, ConstU8, DefensiveMax, DefensiveMin, DefensiveSaturating, DefensiveTruncateFrom, EnsureInherentsAreFirst, EqualPrivilegeOnly, EstimateCallFee, - ExecuteBlock, ExtrinsicCall, Get, GetBacking, GetDefault, HandleLifetime, IsSubType, IsType, - Len, OffchainWorker, OnKilledAccount, OnNewAccount, PrivilegeCmp, SameOrOther, Time, - TryCollect, TryDrop, TypedGet, UnixTime, VariantCount, VariantCountOf, WrapperKeepOpaque, - WrapperOpaque, + ExecuteBlock, ExtrinsicCall, Get, GetBacking, GetDefault, HandleLifetime, IsInherent, + IsSubType, IsType, Len, OffchainWorker, OnKilledAccount, OnNewAccount, PrivilegeCmp, + SameOrOther, Time, TryCollect, TryDrop, TypedGet, UnixTime, VariantCount, VariantCountOf, + WrapperKeepOpaque, WrapperOpaque, }; #[allow(deprecated)] pub use misc::{PreimageProvider, PreimageRecipient}; @@ -86,7 +86,8 @@ mod hooks; pub use hooks::GenesisBuild; pub use hooks::{ BeforeAllRuntimeMigrations, BuildGenesisConfig, Hooks, IntegrityTest, OnFinalize, OnGenesis, - OnIdle, OnInitialize, OnRuntimeUpgrade, OnTimestampSet, + OnIdle, OnInitialize, OnPoll, OnRuntimeUpgrade, OnTimestampSet, PostInherents, + PostTransactions, PreInherents, }; pub mod schedule; diff --git a/substrate/frame/support/src/traits/hooks.rs b/substrate/frame/support/src/traits/hooks.rs index c37fb0f54bc..7d0e5aa1e89 100644 --- a/substrate/frame/support/src/traits/hooks.rs +++ b/substrate/frame/support/src/traits/hooks.rs @@ -25,10 +25,74 @@ use crate::weights::Weight; use impl_trait_for_tuples::impl_for_tuples; use sp_runtime::traits::AtLeast32BitUnsigned; use sp_std::prelude::*; +use sp_weights::WeightMeter; #[cfg(feature = "try-runtime")] use sp_runtime::TryRuntimeError; +/// Provides a callback to execute logic before the all inherents. +pub trait PreInherents { + /// Called before all inherents were applied but after `on_initialize`. + fn pre_inherents() {} +} + +#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))] +#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))] +#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))] +impl PreInherents for Tuple { + fn pre_inherents() { + for_tuples!( #( Tuple::pre_inherents(); )* ); + } +} + +/// Provides a callback to execute logic after the all inherents. +pub trait PostInherents { + /// Called after all inherents were applied. + fn post_inherents() {} +} + +#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))] +#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))] +#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))] +impl PostInherents for Tuple { + fn post_inherents() { + for_tuples!( #( Tuple::post_inherents(); )* ); + } +} + +/// Provides a callback to execute logic before the all transactions. +pub trait PostTransactions { + /// Called after all transactions were applied but before `on_finalize`. + fn post_transactions() {} +} + +#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))] +#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))] +#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))] +impl PostTransactions for Tuple { + fn post_transactions() { + for_tuples!( #( Tuple::post_transactions(); )* ); + } +} + +/// Periodically executes logic. Is not guaranteed to run within a specific timeframe and should +/// only be used on logic that has no deadline. +pub trait OnPoll { + /// Code to execute every now and then at the beginning of the block after inherent application. + /// + /// The remaining weight limit must be respected. + fn on_poll(_n: BlockNumber, _weight: &mut WeightMeter) {} +} + +#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))] +#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))] +#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))] +impl OnPoll for Tuple { + fn on_poll(n: BlockNumber, weight: &mut WeightMeter) { + for_tuples!( #( Tuple::on_poll(n.clone(), weight); )* ); + } +} + /// See [`Hooks::on_initialize`]. pub trait OnInitialize { /// See [`Hooks::on_initialize`]. @@ -374,6 +438,12 @@ pub trait Hooks { Weight::zero() } + /// A hook to run logic after inherent application. + /// + /// Is not guaranteed to execute in a block and should therefore only be used in no-deadline + /// scenarios. + fn on_poll(_n: BlockNumber, _weight: &mut WeightMeter) {} + /// Hook executed when a code change (aka. a "runtime upgrade") is detected by the FRAME /// `Executive` pallet. /// diff --git a/substrate/frame/support/src/traits/misc.rs b/substrate/frame/support/src/traits/misc.rs index eafd9c8abdd..1f634a64282 100644 --- a/substrate/frame/support/src/traits/misc.rs +++ b/substrate/frame/support/src/traits/misc.rs @@ -23,6 +23,7 @@ use impl_trait_for_tuples::impl_for_tuples; use scale_info::{build::Fields, meta_type, Path, Type, TypeInfo, TypeParameter}; use sp_arithmetic::traits::{CheckedAdd, CheckedMul, CheckedSub, One, Saturating}; use sp_core::bounded::bounded_vec::TruncateFrom; + #[doc(hidden)] pub use sp_runtime::traits::{ ConstBool, ConstI128, ConstI16, ConstI32, ConstI64, ConstI8, ConstU128, ConstU16, ConstU32, @@ -895,11 +896,21 @@ pub trait GetBacking { /// A trait to ensure the inherent are before non-inherent in a block. /// /// This is typically implemented on runtime, through `construct_runtime!`. -pub trait EnsureInherentsAreFirst { +pub trait EnsureInherentsAreFirst: + IsInherent<::Extrinsic> +{ /// Ensure the position of inherent is correct, i.e. they are before non-inherents. /// - /// On error return the index of the inherent with invalid position (counting from 0). - fn ensure_inherents_are_first(block: &Block) -> Result<(), u32>; + /// On error return the index of the inherent with invalid position (counting from 0). On + /// success it returns the index of the last inherent. `0` therefore means that there are no + /// inherents. + fn ensure_inherents_are_first(block: &Block) -> Result; +} + +/// A trait to check if an extrinsic is an inherent. +pub trait IsInherent { + /// Whether this extrinsic is an inherent. + fn is_inherent(ext: &Extrinsic) -> bool; } /// An extrinsic on which we can get access to call. diff --git a/substrate/frame/support/test/tests/construct_runtime_ui/undefined_inherent_part.stderr b/substrate/frame/support/test/tests/construct_runtime_ui/undefined_inherent_part.stderr index a4c7ecf7865..30005c07cb6 100644 --- a/substrate/frame/support/test/tests/construct_runtime_ui/undefined_inherent_part.stderr +++ b/substrate/frame/support/test/tests/construct_runtime_ui/undefined_inherent_part.stderr @@ -53,8 +53,9 @@ error[E0599]: no function or associated item named `is_inherent` found for struc | |_^ function or associated item not found in `Pallet` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `is_inherent`, perhaps you need to implement it: + = note: the following traits define an item `is_inherent`, perhaps you need to implement one of them: candidate #1: `ProvideInherent` + candidate #2: `IsInherent` = note: this error originates in the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0599]: no function or associated item named `check_inherent` found for struct `pallet::Pallet` in the current scope @@ -119,3 +120,23 @@ error[E0599]: no function or associated item named `is_inherent_required` found = note: the following trait defines an item `is_inherent_required`, perhaps you need to implement it: candidate #1: `ProvideInherent` = note: this error originates in the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the trait bound `pallet::Pallet: ProvideInherent` is not satisfied + --> tests/construct_runtime_ui/undefined_inherent_part.rs:70:3 + | +70 | Pallet: pallet expanded::{}::{Pallet, Inherent}, + | ^^^^^^ the trait `ProvideInherent` is not implemented for `pallet::Pallet` + +error[E0277]: the trait bound `pallet::Pallet: ProvideInherent` is not satisfied + --> tests/construct_runtime_ui/undefined_inherent_part.rs:66:1 + | +66 | / construct_runtime! { +67 | | pub struct Runtime +68 | | { +69 | | System: frame_system expanded::{}::{Pallet, Call, Storage, Config, Event}, +70 | | Pallet: pallet expanded::{}::{Pallet, Inherent}, +71 | | } +72 | | } + | |_^ the trait `ProvideInherent` is not implemented for `pallet::Pallet` + | + = note: this error originates in the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/substrate/frame/support/test/tests/pallet_outer_enums_explicit.rs b/substrate/frame/support/test/tests/pallet_outer_enums_explicit.rs index 79e9d678671..33b96dea948 100644 --- a/substrate/frame/support/test/tests/pallet_outer_enums_explicit.rs +++ b/substrate/frame/support/test/tests/pallet_outer_enums_explicit.rs @@ -90,6 +90,7 @@ fn module_error_outer_enum_expand_explicit() { frame_system::Error::NonDefaultComposite => (), frame_system::Error::NonZeroRefCount => (), frame_system::Error::CallFiltered => (), + frame_system::Error::MultiBlockMigrationsOngoing => (), #[cfg(feature = "experimental")] frame_system::Error::InvalidTask => (), #[cfg(feature = "experimental")] diff --git a/substrate/frame/support/test/tests/pallet_outer_enums_implicit.rs b/substrate/frame/support/test/tests/pallet_outer_enums_implicit.rs index 4bd8ee0bb39..db006fe7935 100644 --- a/substrate/frame/support/test/tests/pallet_outer_enums_implicit.rs +++ b/substrate/frame/support/test/tests/pallet_outer_enums_implicit.rs @@ -90,6 +90,7 @@ fn module_error_outer_enum_expand_implicit() { frame_system::Error::NonDefaultComposite => (), frame_system::Error::NonZeroRefCount => (), frame_system::Error::CallFiltered => (), + frame_system::Error::MultiBlockMigrationsOngoing => (), #[cfg(feature = "experimental")] frame_system::Error::InvalidTask => (), #[cfg(feature = "experimental")] diff --git a/substrate/frame/support/test/tests/runtime_metadata.rs b/substrate/frame/support/test/tests/runtime_metadata.rs index bb7f7d2822e..40e70b219ba 100644 --- a/substrate/frame/support/test/tests/runtime_metadata.rs +++ b/substrate/frame/support/test/tests/runtime_metadata.rs @@ -101,7 +101,7 @@ sp_api::impl_runtime_apis! { fn execute_block(_: Block) { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } @@ -200,8 +200,8 @@ fn runtime_metadata() { name: "header", ty: meta_type::<&::Header>(), }], - output: meta_type::<()>(), - docs: maybe_docs(vec![" Initialize a block with the given header."]), + output: meta_type::(), + docs: maybe_docs(vec![" Initialize a block with the given header and return the runtime executive mode."]), }, ], docs: maybe_docs(vec![ diff --git a/substrate/frame/system/src/lib.rs b/substrate/frame/system/src/lib.rs index 01df09106d9..3b659916379 100644 --- a/substrate/frame/system/src/lib.rs +++ b/substrate/frame/system/src/lib.rs @@ -130,11 +130,13 @@ use frame_support::{ DispatchResult, DispatchResultWithPostInfo, PerDispatchClass, PostDispatchInfo, }, ensure, impl_ensure_origin_with_arg_ignoring_arg, + migrations::MultiStepMigrator, pallet_prelude::Pays, storage::{self, StorageStreamIter}, traits::{ ConstU32, Contains, EnsureOrigin, EnsureOriginWithArg, Get, HandleLifetime, - OnKilledAccount, OnNewAccount, OriginTrait, PalletInfo, SortedMembers, StoredMap, TypedGet, + OnKilledAccount, OnNewAccount, OnRuntimeUpgrade, OriginTrait, PalletInfo, SortedMembers, + StoredMap, TypedGet, }, Parameter, }; @@ -169,6 +171,7 @@ pub use extensions::{ // Backward compatible re-export. pub use extensions::check_mortality::CheckMortality as CheckEra; pub use frame_support::dispatch::RawOrigin; +use frame_support::traits::{PostInherents, PostTransactions, PreInherents}; pub use weights::WeightInfo; const LOG_TARGET: &str = "runtime::system"; @@ -299,6 +302,11 @@ pub mod pallet { type BaseCallFilter = frame_support::traits::Everything; type BlockHashCount = frame_support::traits::ConstU64<10>; type OnSetCode = (); + type SingleBlockMigrations = (); + type MultiBlockMigrator = (); + type PreInherents = (); + type PostInherents = (); + type PostTransactions = (); } /// Default configurations of this pallet in a solo-chain environment. @@ -393,6 +401,11 @@ pub mod pallet { /// The set code logic, just the default since we're not a parachain. type OnSetCode = (); + type SingleBlockMigrations = (); + type MultiBlockMigrator = (); + type PreInherents = (); + type PostInherents = (); + type PostTransactions = (); } /// Default configurations of this pallet in a relay-chain environment. @@ -572,6 +585,35 @@ pub mod pallet { /// The maximum number of consumers allowed on a single account. type MaxConsumers: ConsumerLimits; + + /// All migrations that should run in the next runtime upgrade. + /// + /// These used to be formerly configured in `Executive`. Parachains need to ensure that + /// running all these migrations in one block will not overflow the weight limit of a block. + /// The migrations are run *before* the pallet `on_runtime_upgrade` hooks, just like the + /// `OnRuntimeUpgrade` migrations. + type SingleBlockMigrations: OnRuntimeUpgrade; + + /// The migrator that is used to run Multi-Block-Migrations. + /// + /// Can be set to [`pallet-migrations`] or an alternative implementation of the interface. + /// The diagram in `frame_executive::block_flowchart` explains when it runs. + type MultiBlockMigrator: MultiStepMigrator; + + /// A callback that executes in *every block* directly before all inherents were applied. + /// + /// See `frame_executive::block_flowchart` for a in-depth explanation when it runs. + type PreInherents: PreInherents; + + /// A callback that executes in *every block* directly after all inherents were applied. + /// + /// See `frame_executive::block_flowchart` for a in-depth explanation when it runs. + type PostInherents: PostInherents; + + /// A callback that executes in *every block* directly after all transactions were applied. + /// + /// See `frame_executive::block_flowchart` for a in-depth explanation when it runs. + type PostTransactions: PostTransactions; } #[pallet::pallet] @@ -619,6 +661,9 @@ pub mod pallet { } /// Set the new runtime code without doing any checks of the given `code`. + /// + /// Note that runtime upgrades will not run if this is called with a not-increasing spec + /// version! #[pallet::call_index(3)] #[pallet::weight((T::SystemWeightInfo::set_code(), DispatchClass::Operational))] pub fn set_code_without_checks( @@ -814,6 +859,8 @@ pub mod pallet { NonZeroRefCount, /// The origin filter prevent the call to be dispatched. CallFiltered, + /// A multi-block migration is ongoing and prevents the current code from being replaced. + MultiBlockMigrationsOngoing, #[cfg(feature = "experimental")] /// The specified [`Task`] is not valid. InvalidTask, @@ -845,6 +892,10 @@ pub mod pallet { #[pallet::storage] pub(super) type ExtrinsicCount = StorageValue<_, u32>; + /// Whether all inherents have been applied. + #[pallet::storage] + pub type InherentsApplied = StorageValue<_, bool, ValueQuery>; + /// The current weight for the block. #[pallet::storage] #[pallet::whitelist_storage] @@ -1373,6 +1424,19 @@ impl Pallet { Self::deposit_event(Event::CodeUpdated); } + /// Whether all inherents have been applied. + pub fn inherents_applied() -> bool { + InherentsApplied::::get() + } + + /// Note that all inherents have been applied. + /// + /// Should be called immediately after all inherents have been applied. Must be called at least + /// once per block. + pub fn note_inherents_applied() { + InherentsApplied::::put(true); + } + /// Increment the reference counter on an account. #[deprecated = "Use `inc_consumers` instead"] pub fn inc_ref(who: &T::AccountId) { @@ -1692,6 +1756,7 @@ impl Pallet { >::put(digest); >::put(parent_hash); >::insert(*number - One::one(), parent_hash); + >::kill(); // Remove previous block data from storage BlockWeight::::kill(); @@ -1738,6 +1803,7 @@ impl Pallet { ExecutionPhase::::kill(); AllExtrinsicsLen::::kill(); storage::unhashed::kill(well_known_keys::INTRABLOCK_ENTROPY); + InherentsApplied::::kill(); // The following fields // @@ -1981,10 +2047,14 @@ impl Pallet { /// Determine whether or not it is possible to update the code. /// - /// Checks the given code if it is a valid runtime wasm blob by instantianting + /// Checks the given code if it is a valid runtime wasm blob by instantiating /// it and extracting the runtime version of it. It checks that the runtime version /// of the old and new runtime has the same spec name and that the spec version is increasing. pub fn can_set_code(code: &[u8]) -> Result<(), sp_runtime::DispatchError> { + if T::MultiBlockMigrator::ongoing() { + return Err(Error::::MultiBlockMigrationsOngoing.into()) + } + let current_version = T::Version::get(); let new_version = sp_io::misc::runtime_version(code) .and_then(|v| RuntimeVersion::decode(&mut &v[..]).ok()) diff --git a/substrate/frame/system/src/mock.rs b/substrate/frame/system/src/mock.rs index c4108099e39..7059845a7df 100644 --- a/substrate/frame/system/src/mock.rs +++ b/substrate/frame/system/src/mock.rs @@ -86,6 +86,22 @@ impl Config for Test { type Version = Version; type AccountData = u32; type OnKilledAccount = RecordKilled; + type MultiBlockMigrator = MockedMigrator; +} + +parameter_types! { + pub static Ongoing: bool = false; +} + +pub struct MockedMigrator; +impl frame_support::migrations::MultiStepMigrator for MockedMigrator { + fn ongoing() -> bool { + Ongoing::get() + } + + fn step() -> Weight { + Weight::zero() + } } pub type SysEvent = frame_system::Event; diff --git a/substrate/frame/system/src/tests.rs b/substrate/frame/system/src/tests.rs index e437e7f9f39..b889b5ca046 100644 --- a/substrate/frame/system/src/tests.rs +++ b/substrate/frame/system/src/tests.rs @@ -675,6 +675,28 @@ fn set_code_with_real_wasm_blob() { }); } +#[test] +fn set_code_rejects_during_mbm() { + Ongoing::set(true); + + let executor = substrate_test_runtime_client::new_native_or_wasm_executor(); + let mut ext = new_test_ext(); + ext.register_extension(sp_core::traits::ReadRuntimeVersionExt::new(executor)); + ext.execute_with(|| { + System::set_block_number(1); + let res = System::set_code( + RawOrigin::Root.into(), + substrate_test_runtime_client::runtime::wasm_binary_unwrap().to_vec(), + ); + assert_eq!( + res, + Err(DispatchErrorWithPostInfo::from(Error::::MultiBlockMigrationsOngoing)) + ); + + assert!(System::events().is_empty()); + }); +} + #[test] fn set_code_via_authorization_works() { let executor = substrate_test_runtime_client::new_native_or_wasm_executor(); diff --git a/substrate/primitives/api/proc-macro/src/decl_runtime_apis.rs b/substrate/primitives/api/proc-macro/src/decl_runtime_apis.rs index 2b1e65ec885..e34e4c0e767 100644 --- a/substrate/primitives/api/proc-macro/src/decl_runtime_apis.rs +++ b/substrate/primitives/api/proc-macro/src/decl_runtime_apis.rs @@ -456,6 +456,7 @@ impl<'a> ToClientSideDecl<'a> { |err| #crate_::ApiError::FailedToDecodeReturnValue { function: #function_name, error: err, + raw: r.clone(), } ) ) diff --git a/substrate/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs b/substrate/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs index c1339ff6621..1761e0ac9db 100644 --- a/substrate/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs +++ b/substrate/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs @@ -158,7 +158,7 @@ fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result::Hash, _: &<#block_type as #crate_::BlockT>::Header, - ) -> std::result::Result<(), #crate_::ApiError> { + ) -> std::result::Result<#crate_::__private::ExtrinsicInclusionMode, #crate_::ApiError> { unimplemented!("`Core::initialize_block` not implemented for runtime api mocks") } } diff --git a/substrate/primitives/api/src/lib.rs b/substrate/primitives/api/src/lib.rs index 190de1ab3fd..a945b9f21f3 100644 --- a/substrate/primitives/api/src/lib.rs +++ b/substrate/primitives/api/src/lib.rs @@ -101,7 +101,7 @@ pub mod __private { generic::BlockId, traits::{Block as BlockT, Hash as HashT, HashingFor, Header as HeaderT, NumberFor}, transaction_validity::TransactionValidity, - RuntimeString, TransactionOutcome, + ExtrinsicInclusionMode, RuntimeString, TransactionOutcome, }; pub use sp_std::{mem, slice, vec}; pub use sp_version::{create_apis_vec, ApiId, ApisVec, RuntimeVersion}; @@ -115,11 +115,11 @@ pub use sp_core::traits::CallContext; use sp_core::OpaqueMetadata; #[cfg(feature = "std")] use sp_externalities::{Extension, Extensions}; -use sp_runtime::traits::Block as BlockT; #[cfg(feature = "std")] use sp_runtime::traits::HashingFor; #[cfg(feature = "std")] pub use sp_runtime::TransactionOutcome; +use sp_runtime::{traits::Block as BlockT, ExtrinsicInclusionMode}; #[cfg(feature = "std")] pub use sp_state_machine::StorageProof; #[cfg(feature = "std")] @@ -280,7 +280,7 @@ pub use sp_api_proc_macro::decl_runtime_apis; /// ```rust /// use sp_version::create_runtime_str; /// # -/// # use sp_runtime::traits::Block as BlockT; +/// # use sp_runtime::{ExtrinsicInclusionMode, traits::Block as BlockT}; /// # use sp_test_primitives::Block; /// # /// # /// The declaration of the `Runtime` type is done by the `construct_runtime!` macro @@ -307,7 +307,9 @@ pub use sp_api_proc_macro::decl_runtime_apis; /// # unimplemented!() /// # } /// # fn execute_block(_block: Block) {} -/// # fn initialize_block(_header: &::Header) {} +/// # fn initialize_block(_header: &::Header) -> ExtrinsicInclusionMode { +/// # unimplemented!() +/// # } /// # } /// /// impl self::Balance for Runtime { @@ -540,11 +542,12 @@ pub fn init_runtime_logger() { #[cfg(feature = "std")] #[derive(Debug, thiserror::Error)] pub enum ApiError { - #[error("Failed to decode return value of {function}")] + #[error("Failed to decode return value of {function}: {error} raw data: {raw:?}")] FailedToDecodeReturnValue { function: &'static str, #[source] error: codec::Error, + raw: Vec, }, #[error("Failed to convert return value from runtime to node of {function}")] FailedToConvertReturnValue { @@ -800,15 +803,18 @@ pub fn deserialize_runtime_api_info(bytes: [u8; RUNTIME_API_INFO_SIZE]) -> ([u8; decl_runtime_apis! { /// The `Core` runtime api that every Substrate runtime needs to implement. #[core_trait] - #[api_version(4)] + #[api_version(5)] pub trait Core { /// Returns the version of the runtime. fn version() -> RuntimeVersion; /// Execute the given block. fn execute_block(block: Block); /// Initialize a block with the given header. + #[changed_in(5)] #[renamed("initialise_block", 2)] fn initialize_block(header: &::Header); + /// Initialize a block with the given header and return the runtime executive mode. + fn initialize_block(header: &::Header) -> ExtrinsicInclusionMode; } /// The `Metadata` api trait that returns metadata for the runtime. diff --git a/substrate/primitives/api/test/tests/decl_and_impl.rs b/substrate/primitives/api/test/tests/decl_and_impl.rs index d68470551d2..211a08561fd 100644 --- a/substrate/primitives/api/test/tests/decl_and_impl.rs +++ b/substrate/primitives/api/test/tests/decl_and_impl.rs @@ -139,7 +139,7 @@ impl_runtime_apis! { fn execute_block(_: Block) { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/substrate/primitives/api/test/tests/ui/impl_incorrect_method_signature.rs b/substrate/primitives/api/test/tests/ui/impl_incorrect_method_signature.rs index 43718e4cd04..262a874213a 100644 --- a/substrate/primitives/api/test/tests/ui/impl_incorrect_method_signature.rs +++ b/substrate/primitives/api/test/tests/ui/impl_incorrect_method_signature.rs @@ -40,7 +40,7 @@ sp_api::impl_runtime_apis! { fn execute_block(_: Block) { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/substrate/primitives/api/test/tests/ui/impl_missing_version.rs b/substrate/primitives/api/test/tests/ui/impl_missing_version.rs index 560257b5168..58850ab343f 100644 --- a/substrate/primitives/api/test/tests/ui/impl_missing_version.rs +++ b/substrate/primitives/api/test/tests/ui/impl_missing_version.rs @@ -45,7 +45,7 @@ sp_api::impl_runtime_apis! { fn execute_block(_: Block) { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/substrate/primitives/api/test/tests/ui/missing_versioned_method.rs b/substrate/primitives/api/test/tests/ui/missing_versioned_method.rs index 6ead545f85a..70f75d06515 100644 --- a/substrate/primitives/api/test/tests/ui/missing_versioned_method.rs +++ b/substrate/primitives/api/test/tests/ui/missing_versioned_method.rs @@ -44,7 +44,7 @@ sp_api::impl_runtime_apis! { fn execute_block(_: Block) { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/substrate/primitives/api/test/tests/ui/missing_versioned_method_multiple_vers.rs b/substrate/primitives/api/test/tests/ui/missing_versioned_method_multiple_vers.rs index 8eebc1d79ba..63032000040 100644 --- a/substrate/primitives/api/test/tests/ui/missing_versioned_method_multiple_vers.rs +++ b/substrate/primitives/api/test/tests/ui/missing_versioned_method_multiple_vers.rs @@ -47,7 +47,7 @@ sp_api::impl_runtime_apis! { fn execute_block(_: Block) { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/substrate/primitives/api/test/tests/ui/positive_cases/custom_where_bound.rs b/substrate/primitives/api/test/tests/ui/positive_cases/custom_where_bound.rs index 594556d57be..0858813bc99 100644 --- a/substrate/primitives/api/test/tests/ui/positive_cases/custom_where_bound.rs +++ b/substrate/primitives/api/test/tests/ui/positive_cases/custom_where_bound.rs @@ -51,7 +51,7 @@ sp_api::impl_runtime_apis! { fn execute_block(_: Block) { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/substrate/primitives/api/test/tests/ui/positive_cases/default_impls.rs b/substrate/primitives/api/test/tests/ui/positive_cases/default_impls.rs index ae573238ffe..3e0cb79156c 100644 --- a/substrate/primitives/api/test/tests/ui/positive_cases/default_impls.rs +++ b/substrate/primitives/api/test/tests/ui/positive_cases/default_impls.rs @@ -46,7 +46,7 @@ sp_api::impl_runtime_apis! { fn execute_block(_: Block) { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/substrate/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.rs b/substrate/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.rs index 921bf0d0435..b2caea7ab7e 100644 --- a/substrate/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.rs +++ b/substrate/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.rs @@ -42,7 +42,7 @@ sp_api::impl_runtime_apis! { fn execute_block(_: Block) { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/substrate/primitives/runtime/src/lib.rs b/substrate/primitives/runtime/src/lib.rs index ddf92554c83..44bf3c969e5 100644 --- a/substrate/primitives/runtime/src/lib.rs +++ b/substrate/primitives/runtime/src/lib.rs @@ -998,6 +998,16 @@ impl TransactionOutcome { } } +/// Confines the kind of extrinsics that can be included in a block. +#[derive(Debug, Default, PartialEq, Eq, Clone, Copy, Encode, Decode, TypeInfo)] +pub enum ExtrinsicInclusionMode { + /// All extrinsics are allowed to be included in this block. + #[default] + AllExtrinsics, + /// Inherents are allowed to be included. + OnlyInherents, +} + #[cfg(test)] mod tests { use crate::traits::BlakeTwo256; diff --git a/substrate/test-utils/runtime/src/lib.rs b/substrate/test-utils/runtime/src/lib.rs index db9ff187b70..63e0aa6e137 100644 --- a/substrate/test-utils/runtime/src/lib.rs +++ b/substrate/test-utils/runtime/src/lib.rs @@ -61,7 +61,7 @@ use sp_runtime::{ create_runtime_str, impl_opaque_keys, traits::{BlakeTwo256, Block as BlockT, DispatchInfoOf, NumberFor, Verify}, transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError}, - ApplyExtrinsicResult, Perbill, + ApplyExtrinsicResult, ExtrinsicInclusionMode, Perbill, }; #[cfg(any(feature = "std", test))] use sp_version::NativeVersion; @@ -480,9 +480,9 @@ impl_runtime_apis! { Executive::execute_block(block); } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> ExtrinsicInclusionMode { log::trace!(target: LOG_TARGET, "initialize_block: {header:#?}"); - Executive::initialize_block(header); + Executive::initialize_block(header) } } -- GitLab From 833bafdbf7b178b639f895e0d43c43eb502de30c Mon Sep 17 00:00:00 2001 From: Alexandru Gheorghe <49718502+alexggh@users.noreply.github.com> Date: Thu, 29 Feb 2024 01:43:53 +0200 Subject: [PATCH 324/392] Fixup multi-collator parachain transition to async backing (#3510) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixing: ``` Verification failed for block 0x07bbf1e04121d70a4bdb21cc055132b53ac2390fa95c4d05497fc91b1e8bf7f5 received from (12D3KooWJzLd8skcAgA24EcJey7aJAhYctfUxWGjSP5Usk9wbpPZ): "Header 0x07bbf1e04121d70a4bdb21cc055132b53ac2390fa95c4d05497fc91b1e8bf7f5 rejected: too far in the future" ``` --------- Signed-off-by: Alexandru Gheorghe Co-authored-by: Dmitry Sinyavin Co-authored-by: s0me0ne-unkn0wn <48632512+s0me0ne-unkn0wn@users.noreply.github.com> Co-authored-by: Bastian Köcher --- cumulus/client/consensus/aura/src/lib.rs | 5 ++- cumulus/polkadot-parachain/src/service.rs | 33 +++++++++++-------- prdoc/pr_3510.prdoc | 13 ++++++++ .../bin/node-template/node/src/service.rs | 26 +++++++++------ 4 files changed, 52 insertions(+), 25 deletions(-) create mode 100644 prdoc/pr_3510.prdoc diff --git a/cumulus/client/consensus/aura/src/lib.rs b/cumulus/client/consensus/aura/src/lib.rs index 8e4bc658e44..ed6f5bdd4d6 100644 --- a/cumulus/client/consensus/aura/src/lib.rs +++ b/cumulus/client/consensus/aura/src/lib.rs @@ -54,7 +54,10 @@ use std::{ mod import_queue; pub use import_queue::{build_verifier, import_queue, BuildVerifierParams, ImportQueueParams}; -pub use sc_consensus_aura::{slot_duration, AuraVerifier, BuildAuraWorkerParams, SlotProportion}; +pub use sc_consensus_aura::{ + slot_duration, standalone::slot_duration_at, AuraVerifier, BuildAuraWorkerParams, + SlotProportion, +}; pub use sc_consensus_slots::InherentDataProviderExt; pub mod collator; diff --git a/cumulus/polkadot-parachain/src/service.rs b/cumulus/polkadot-parachain/src/service.rs index 4e06cd38f1d..386551102e4 100644 --- a/cumulus/polkadot-parachain/src/service.rs +++ b/cumulus/polkadot-parachain/src/service.rs @@ -1251,28 +1251,33 @@ where <::Pair as Pair>::Signature: TryFrom> + std::hash::Hash + sp_runtime::traits::Member + Codec, { - let client2 = client.clone(); + let verifier_client = client.clone(); let aura_verifier = move || { - let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client2).unwrap(); - Box::new(cumulus_client_consensus_aura::build_verifier::< ::Pair, _, _, _, >(cumulus_client_consensus_aura::BuildVerifierParams { - client: client2.clone(), - create_inherent_data_providers: move |_, _| async move { - let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); - - let slot = - sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( - *timestamp, - slot_duration, - ); - - Ok((slot, timestamp)) + client: verifier_client.clone(), + create_inherent_data_providers: move |parent_hash, _| { + let cidp_client = verifier_client.clone(); + async move { + let slot_duration = cumulus_client_consensus_aura::slot_duration_at( + &*cidp_client, + parent_hash, + )?; + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + + let slot = + sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( + *timestamp, + slot_duration, + ); + + Ok((slot, timestamp)) + } }, telemetry: telemetry_handle, })) as Box<_> diff --git a/prdoc/pr_3510.prdoc b/prdoc/pr_3510.prdoc new file mode 100644 index 00000000000..6ee2f9a81f7 --- /dev/null +++ b/prdoc/pr_3510.prdoc @@ -0,0 +1,13 @@ +title: "Fix multi-collator parachain transition to async backing" + +doc: + - audience: Node Operator + description: | + The dynamic Aura slot duration, introduced in PR#3211, didn't take the block import pipeline + into account. The result was the parachain backed by multiple collators not being able to + keep producing blocks after its runtime was upgraded to support async backing, requiring to + restart all the collator nodes. This change fixes the issue, introducing the dynamic Aura + slot duration into the block import pipeline. + +crates: + - name: "polkadot-parachain-bin" diff --git a/substrate/bin/node-template/node/src/service.rs b/substrate/bin/node-template/node/src/service.rs index 25cd6511784..125cca13927 100644 --- a/substrate/bin/node-template/node/src/service.rs +++ b/substrate/bin/node-template/node/src/service.rs @@ -80,23 +80,29 @@ pub fn new_partial(config: &Configuration) -> Result { telemetry.as_ref().map(|x| x.handle()), )?; - let slot_duration = sc_consensus_aura::slot_duration(&*client)?; - + let cidp_client = client.clone(); let import_queue = sc_consensus_aura::import_queue::(ImportQueueParams { block_import: grandpa_block_import.clone(), justification_import: Some(Box::new(grandpa_block_import.clone())), client: client.clone(), - create_inherent_data_providers: move |_, ()| async move { - let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + create_inherent_data_providers: move |parent_hash, _| { + let cidp_client = cidp_client.clone(); + async move { + let slot_duration = sc_consensus_aura::standalone::slot_duration_at( + &*cidp_client, + parent_hash, + )?; + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); - let slot = - sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( - *timestamp, - slot_duration, - ); + let slot = + sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( + *timestamp, + slot_duration, + ); - Ok((slot, timestamp)) + Ok((slot, timestamp)) + } }, spawner: &task_manager.spawn_essential_handle(), registry: config.prometheus_registry(), -- GitLab From a22319cdd5fcdcec3bbedfe41f6d11a6b5446cf9 Mon Sep 17 00:00:00 2001 From: philoniare Date: Thu, 29 Feb 2024 13:17:24 +0800 Subject: [PATCH 325/392] [Deprecation] Remove sp_weights::OldWeight (#3491) # Description *Removes `sp_weights::OldWeight` and its usage* Fixes #144 --------- Co-authored-by: Liam Aharon --- prdoc/pr_3491.prdoc | 12 +++ substrate/frame/contracts/src/wasm/mod.rs | 11 --- substrate/primitives/weights/src/lib.rs | 27 +------ .../primitives/weights/src/weight_meter.rs | 81 ++++++++----------- 4 files changed, 47 insertions(+), 84 deletions(-) create mode 100644 prdoc/pr_3491.prdoc diff --git a/prdoc/pr_3491.prdoc b/prdoc/pr_3491.prdoc new file mode 100644 index 00000000000..e36afb916a6 --- /dev/null +++ b/prdoc/pr_3491.prdoc @@ -0,0 +1,12 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Remove Deprecated OldWeight + +doc: + - audience: Runtime Dev + description: | + Removed deprecated sp_weights::OldWeight type. Use [`weight_v2::Weight`] instead. + +crates: + - name: frame-support diff --git a/substrate/frame/contracts/src/wasm/mod.rs b/substrate/frame/contracts/src/wasm/mod.rs index c96c2856509..34b45cba5d2 100644 --- a/substrate/frame/contracts/src/wasm/mod.rs +++ b/substrate/frame/contracts/src/wasm/mod.rs @@ -1821,17 +1821,6 @@ mod tests { assert!(weight_left.all_gt(actual_left), "gas_left must be greater than final"); } - /// Test that [`frame_support::weights::OldWeight`] en/decodes the same as our - /// [`crate::OldWeight`]. - #[test] - fn old_weight_decode() { - #![allow(deprecated)] - let sp = frame_support::weights::OldWeight(42).encode(); - let our = crate::OldWeight::decode(&mut &*sp).unwrap(); - - assert_eq!(our, 42); - } - const CODE_VALUE_TRANSFERRED: &str = r#" (module (import "seal0" "seal_value_transferred" (func $seal_value_transferred (param i32 i32))) diff --git a/substrate/primitives/weights/src/lib.rs b/substrate/primitives/weights/src/lib.rs index aede9473535..b2c956266e2 100644 --- a/substrate/primitives/weights/src/lib.rs +++ b/substrate/primitives/weights/src/lib.rs @@ -18,9 +18,6 @@ //! # Primitives for transaction weighting. #![cfg_attr(not(feature = "std"), no_std)] -// TODO remove once `OldWeight` is gone. I dont know why this is needed, maybe by one of the macros -// of `OldWeight`. -#![allow(deprecated)] extern crate self as sp_weights; @@ -28,7 +25,7 @@ mod weight_meter; mod weight_v2; use bounded_collections::Get; -use codec::{CompactAs, Decode, Encode, MaxEncodedLen}; +use codec::{Decode, Encode}; use scale_info::TypeInfo; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -52,28 +49,6 @@ pub mod constants { pub const WEIGHT_PROOF_SIZE_PER_KB: u64 = 1024; } -/// The old weight type. -/// -/// NOTE: This type exists purely for compatibility purposes! Use [`weight_v2::Weight`] in all other -/// cases. -#[derive( - Decode, - Encode, - CompactAs, - PartialEq, - Eq, - Clone, - Copy, - RuntimeDebug, - Default, - MaxEncodedLen, - TypeInfo, -)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(transparent))] -#[deprecated(note = "Will be removed soon; use `Weight` instead.")] -pub struct OldWeight(pub u64); - /// The weight of database operations that the runtime can invoke. /// /// NOTE: This is currently only measured in computational time, and will probably diff --git a/substrate/primitives/weights/src/weight_meter.rs b/substrate/primitives/weights/src/weight_meter.rs index 1738948e4c3..cfe8396ae6d 100644 --- a/substrate/primitives/weights/src/weight_meter.rs +++ b/substrate/primitives/weights/src/weight_meter.rs @@ -118,13 +118,6 @@ impl WeightMeter { debug_assert!(self.consumed.all_lte(self.limit), "Weight counter overflow"); } - /// Consume the given weight after checking that it can be consumed and return `true`. Otherwise - /// do nothing and return `false`. - #[deprecated(note = "Use `try_consume` instead. Will be removed after December 2023.")] - pub fn check_accrue(&mut self, w: Weight) -> bool { - self.try_consume(w).is_ok() - } - /// Consume the given weight after checking that it can be consumed. /// /// Returns `Ok` if the weight can be consumed or otherwise an `Err`. @@ -139,12 +132,6 @@ impl WeightMeter { }) } - /// Check if the given weight can be consumed. - #[deprecated(note = "Use `can_consume` instead. Will be removed after December 2023.")] - pub fn can_accrue(&self, w: Weight) -> bool { - self.can_consume(w) - } - /// Check if the given weight can be consumed. pub fn can_consume(&self, w: Weight) -> bool { self.consumed.checked_add(&w).map_or(false, |t| t.all_lte(self.limit)) @@ -165,80 +152,80 @@ mod tests { fn weight_meter_remaining_works() { let mut meter = WeightMeter::with_limit(Weight::from_parts(10, 20)); - assert!(meter.check_accrue(Weight::from_parts(5, 0))); + assert_eq!(meter.try_consume(Weight::from_parts(5, 0)), Ok(())); assert_eq!(meter.consumed, Weight::from_parts(5, 0)); assert_eq!(meter.remaining(), Weight::from_parts(5, 20)); - assert!(meter.check_accrue(Weight::from_parts(2, 10))); + assert_eq!(meter.try_consume(Weight::from_parts(2, 10)), Ok(())); assert_eq!(meter.consumed, Weight::from_parts(7, 10)); assert_eq!(meter.remaining(), Weight::from_parts(3, 10)); - assert!(meter.check_accrue(Weight::from_parts(3, 10))); + assert_eq!(meter.try_consume(Weight::from_parts(3, 10)), Ok(())); assert_eq!(meter.consumed, Weight::from_parts(10, 20)); assert_eq!(meter.remaining(), Weight::from_parts(0, 0)); } #[test] - fn weight_meter_can_accrue_works() { + fn weight_meter_can_consume_works() { let meter = WeightMeter::with_limit(Weight::from_parts(1, 1)); - assert!(meter.can_accrue(Weight::from_parts(0, 0))); - assert!(meter.can_accrue(Weight::from_parts(1, 1))); - assert!(!meter.can_accrue(Weight::from_parts(0, 2))); - assert!(!meter.can_accrue(Weight::from_parts(2, 0))); - assert!(!meter.can_accrue(Weight::from_parts(2, 2))); + assert!(meter.can_consume(Weight::from_parts(0, 0))); + assert!(meter.can_consume(Weight::from_parts(1, 1))); + assert!(!meter.can_consume(Weight::from_parts(0, 2))); + assert!(!meter.can_consume(Weight::from_parts(2, 0))); + assert!(!meter.can_consume(Weight::from_parts(2, 2))); } #[test] - fn weight_meter_check_accrue_works() { + fn weight_meter_try_consume_works() { let mut meter = WeightMeter::with_limit(Weight::from_parts(2, 2)); - assert!(meter.check_accrue(Weight::from_parts(0, 0))); - assert!(meter.check_accrue(Weight::from_parts(1, 1))); - assert!(!meter.check_accrue(Weight::from_parts(0, 2))); - assert!(!meter.check_accrue(Weight::from_parts(2, 0))); - assert!(!meter.check_accrue(Weight::from_parts(2, 2))); - assert!(meter.check_accrue(Weight::from_parts(0, 1))); - assert!(meter.check_accrue(Weight::from_parts(1, 0))); + assert_eq!(meter.try_consume(Weight::from_parts(0, 0)), Ok(())); + assert_eq!(meter.try_consume(Weight::from_parts(1, 1)), Ok(())); + assert_eq!(meter.try_consume(Weight::from_parts(0, 2)), Err(())); + assert_eq!(meter.try_consume(Weight::from_parts(2, 0)), Err(())); + assert_eq!(meter.try_consume(Weight::from_parts(2, 2)), Err(())); + assert_eq!(meter.try_consume(Weight::from_parts(0, 1)), Ok(())); + assert_eq!(meter.try_consume(Weight::from_parts(1, 0)), Ok(())); } #[test] - fn weight_meter_check_and_can_accrue_works() { + fn weight_meter_check_and_can_consume_works() { let mut meter = WeightMeter::new(); - assert!(meter.can_accrue(Weight::from_parts(u64::MAX, 0))); - assert!(meter.check_accrue(Weight::from_parts(u64::MAX, 0))); + assert!(meter.can_consume(Weight::from_parts(u64::MAX, 0))); + assert_eq!(meter.try_consume(Weight::from_parts(u64::MAX, 0)), Ok(())); - assert!(meter.can_accrue(Weight::from_parts(0, u64::MAX))); - assert!(meter.check_accrue(Weight::from_parts(0, u64::MAX))); + assert!(meter.can_consume(Weight::from_parts(0, u64::MAX))); + assert_eq!(meter.try_consume(Weight::from_parts(0, u64::MAX)), Ok(())); - assert!(!meter.can_accrue(Weight::from_parts(0, 1))); - assert!(!meter.check_accrue(Weight::from_parts(0, 1))); + assert!(!meter.can_consume(Weight::from_parts(0, 1))); + assert_eq!(meter.try_consume(Weight::from_parts(0, 1)), Err(())); - assert!(!meter.can_accrue(Weight::from_parts(1, 0))); - assert!(!meter.check_accrue(Weight::from_parts(1, 0))); + assert!(!meter.can_consume(Weight::from_parts(1, 0))); + assert_eq!(meter.try_consume(Weight::from_parts(1, 0)), Err(())); - assert!(meter.can_accrue(Weight::zero())); - assert!(meter.check_accrue(Weight::zero())); + assert!(meter.can_consume(Weight::zero())); + assert_eq!(meter.try_consume(Weight::zero()), Ok(())); } #[test] fn consumed_ratio_works() { let mut meter = WeightMeter::with_limit(Weight::from_parts(10, 20)); - assert!(meter.check_accrue(Weight::from_parts(5, 0))); + assert_eq!(meter.try_consume(Weight::from_parts(5, 0)), Ok(())); assert_eq!(meter.consumed_ratio(), Perbill::from_percent(50)); - assert!(meter.check_accrue(Weight::from_parts(0, 12))); + assert_eq!(meter.try_consume(Weight::from_parts(0, 12)), Ok(())); assert_eq!(meter.consumed_ratio(), Perbill::from_percent(60)); - assert!(meter.check_accrue(Weight::from_parts(2, 0))); + assert_eq!(meter.try_consume(Weight::from_parts(2, 0)), Ok(())); assert_eq!(meter.consumed_ratio(), Perbill::from_percent(70)); - assert!(meter.check_accrue(Weight::from_parts(0, 4))); + assert_eq!(meter.try_consume(Weight::from_parts(0, 4)), Ok(())); assert_eq!(meter.consumed_ratio(), Perbill::from_percent(80)); - assert!(meter.check_accrue(Weight::from_parts(3, 0))); + assert_eq!(meter.try_consume(Weight::from_parts(3, 0)), Ok(())); assert_eq!(meter.consumed_ratio(), Perbill::from_percent(100)); - assert!(meter.check_accrue(Weight::from_parts(0, 4))); + assert_eq!(meter.try_consume(Weight::from_parts(0, 4)), Ok(())); assert_eq!(meter.consumed_ratio(), Perbill::from_percent(100)); } -- GitLab From a035dc9be718c6327420c87fecb7a752954492f4 Mon Sep 17 00:00:00 2001 From: Tsvetomir Dimitrov Date: Thu, 29 Feb 2024 09:12:02 +0200 Subject: [PATCH 326/392] Remove `AssignmentProviderConfig` and use parameters from `HostConfiguration` instead (#3181) This PR removes `AssignmentProviderConfig` and uses the corresponding ondemand parameters from `HostConfiguration` instead. Additionally `scheduling_lookahead` and all coretime/ondemand related parameters are extracted in a separate struct - `SchedulerParams`. The most relevant commit from the PR is [this one](https://github.com/paritytech/polkadot-sdk/pull/3181/commits/830bc0f5e858944474171bbe33382ad96040b535). Fixes https://github.com/paritytech/polkadot-sdk/issues/2268 --------- Co-authored-by: command-bot <> --- .../zombienet/tests/0002-pov_recovery.toml | 2 +- polkadot/node/service/src/chain_spec.rs | 16 +- polkadot/node/test/service/src/chain_spec.rs | 11 +- polkadot/primitives/src/vstaging/mod.rs | 76 ++++ .../implementers-guide/src/types/runtime.md | 118 +----- .../src/assigner_coretime/mock_helpers.rs | 11 +- .../parachains/src/assigner_coretime/mod.rs | 16 +- .../src/assigner_on_demand/benchmarking.rs | 2 +- .../src/assigner_on_demand/mock_helpers.rs | 11 +- .../parachains/src/assigner_on_demand/mod.rs | 18 +- .../parachains/src/assigner_parachains.rs | 12 +- .../src/assigner_parachains/mock_helpers.rs | 11 +- polkadot/runtime/parachains/src/builder.rs | 19 +- .../runtime/parachains/src/configuration.rs | 133 +++---- .../src/configuration/benchmarking.rs | 2 + .../parachains/src/configuration/migration.rs | 1 + .../src/configuration/migration/v11.rs | 113 +++++- .../src/configuration/migration/v12.rs | 349 ++++++++++++++++++ .../parachains/src/configuration/tests.rs | 51 ++- .../parachains/src/coretime/migration.rs | 19 +- .../runtime/parachains/src/coretime/mod.rs | 4 +- .../runtime/parachains/src/inclusion/tests.rs | 10 +- polkadot/runtime/parachains/src/mock.rs | 23 +- .../runtime/parachains/src/paras/tests.rs | 7 +- .../parachains/src/paras_inherent/tests.rs | 11 +- polkadot/runtime/parachains/src/scheduler.rs | 43 +-- .../parachains/src/scheduler/common.rs | 19 +- .../runtime/parachains/src/scheduler/tests.rs | 81 ++-- .../parachains/src/session_info/tests.rs | 4 +- polkadot/runtime/rococo/src/lib.rs | 1 + .../runtime_parachains_configuration.rs | 50 ++- polkadot/runtime/westend/src/lib.rs | 1 + .../runtime_parachains_configuration.rs | 50 ++- .../functional/0002-parachains-disputes.toml | 4 +- .../0004-parachains-garbage-candidate.toml | 4 +- ...0005-parachains-disputes-past-session.toml | 4 +- .../0006-parachains-max-tranche0.toml | 4 +- .../0007-dispute-freshly-finalized.toml | 4 +- .../0008-dispute-old-finalized.toml | 4 +- .../functional/0010-validator-disabling.toml | 4 +- .../0011-async-backing-6-seconds-rate.toml | 7 +- .../functional/0012-elastic-scaling-mvp.toml | 6 +- .../zombienet_tests/misc/0001-paritydb.toml | 4 +- 43 files changed, 901 insertions(+), 439 deletions(-) create mode 100644 polkadot/runtime/parachains/src/configuration/migration/v12.rs diff --git a/cumulus/zombienet/tests/0002-pov_recovery.toml b/cumulus/zombienet/tests/0002-pov_recovery.toml index fe42fd4b2f6..15a61eba2a0 100644 --- a/cumulus/zombienet/tests/0002-pov_recovery.toml +++ b/cumulus/zombienet/tests/0002-pov_recovery.toml @@ -4,7 +4,7 @@ default_command = "polkadot" chain = "rococo-local" -[relaychain.genesis.runtimeGenesis.patch.configuration.config] +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] # set parameters such that collators only connect to 1 validator as a backing group max_validators_per_core = 1 group_rotation_frequency = 100 # 10 mins diff --git a/polkadot/node/service/src/chain_spec.rs b/polkadot/node/service/src/chain_spec.rs index af241d1cbc5..af05af87a46 100644 --- a/polkadot/node/service/src/chain_spec.rs +++ b/polkadot/node/service/src/chain_spec.rs @@ -24,6 +24,8 @@ use polkadot_primitives::{AccountId, AccountPublic, AssignmentId, ValidatorId}; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; use sp_consensus_babe::AuthorityId as BabeId; +#[cfg(any(feature = "rococo-native", feature = "westend-native",))] +use polkadot_primitives::vstaging::SchedulerParams; #[cfg(feature = "rococo-native")] use rococo_runtime as rococo; #[cfg(feature = "rococo-native")] @@ -129,8 +131,6 @@ fn default_parachains_host_configuration( max_code_size: MAX_CODE_SIZE, max_pov_size: MAX_POV_SIZE, max_head_data_size: 32 * 1024, - group_rotation_frequency: 20, - paras_availability_period: 4, max_upward_queue_count: 8, max_upward_queue_size: 1024 * 1024, max_downward_message_size: 1024 * 1024, @@ -151,11 +151,16 @@ fn default_parachains_host_configuration( relay_vrf_modulo_samples: 2, zeroth_delay_tranche_width: 0, minimum_validation_upgrade_delay: 5, - scheduling_lookahead: 2, async_backing_params: AsyncBackingParams { max_candidate_depth: 3, allowed_ancestry_len: 2, }, + scheduler_params: SchedulerParams { + lookahead: 2, + group_rotation_frequency: 20, + paras_availability_period: 4, + ..Default::default() + }, ..Default::default() } } @@ -891,7 +896,10 @@ pub fn rococo_testnet_genesis( "sudo": { "key": Some(root_key.clone()) }, "configuration": { "config": polkadot_runtime_parachains::configuration::HostConfiguration { - max_validators_per_core: Some(1), + scheduler_params: SchedulerParams { + max_validators_per_core: Some(1), + ..default_parachains_host_configuration().scheduler_params + }, ..default_parachains_host_configuration() }, }, diff --git a/polkadot/node/test/service/src/chain_spec.rs b/polkadot/node/test/service/src/chain_spec.rs index 4cc387317c3..f14fa9fde58 100644 --- a/polkadot/node/test/service/src/chain_spec.rs +++ b/polkadot/node/test/service/src/chain_spec.rs @@ -19,7 +19,9 @@ use babe_primitives::AuthorityId as BabeId; use grandpa::AuthorityId as GrandpaId; use pallet_staking::Forcing; -use polkadot_primitives::{AccountId, AssignmentId, ValidatorId, MAX_CODE_SIZE, MAX_POV_SIZE}; +use polkadot_primitives::{ + vstaging::SchedulerParams, AccountId, AssignmentId, ValidatorId, MAX_CODE_SIZE, MAX_POV_SIZE, +}; use polkadot_service::chain_spec::{get_account_id_from_seed, get_from_seed, Extensions}; use polkadot_test_runtime::BABE_GENESIS_EPOCH_CONFIG; use sc_chain_spec::{ChainSpec, ChainType}; @@ -165,11 +167,14 @@ fn polkadot_testnet_genesis( max_code_size: MAX_CODE_SIZE, max_pov_size: MAX_POV_SIZE, max_head_data_size: 32 * 1024, - group_rotation_frequency: 20, - paras_availability_period: 4, no_show_slots: 10, minimum_validation_upgrade_delay: 5, max_downward_message_size: 1024, + scheduler_params: SchedulerParams { + group_rotation_frequency: 20, + paras_availability_period: 4, + ..Default::default() + }, ..Default::default() }, } diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 39d9dfc02c5..bd2a5106c44 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -23,6 +23,7 @@ use sp_std::prelude::*; use parity_scale_codec::{Decode, Encode}; use primitives::RuntimeDebug; use scale_info::TypeInfo; +use sp_arithmetic::Perbill; /// Approval voting configuration parameters #[derive( @@ -50,6 +51,81 @@ impl Default for ApprovalVotingParams { } } +/// Scheduler configuration parameters. All coretime/ondemand parameters are here. +#[derive( + RuntimeDebug, + Copy, + Clone, + PartialEq, + Encode, + Decode, + TypeInfo, + serde::Serialize, + serde::Deserialize, +)] +pub struct SchedulerParams { + /// How often parachain groups should be rotated across parachains. + /// + /// Must be non-zero. + pub group_rotation_frequency: BlockNumber, + /// Availability timeout for a block on a core, measured in blocks. + /// + /// This is the maximum amount of blocks after a core became occupied that validators have time + /// to make the block available. + /// + /// This value only has effect on group rotations. If backers backed something at the end of + /// their rotation, the occupied core affects the backing group that comes afterwards. We limit + /// the effect one backing group can have on the next to `paras_availability_period` blocks. + /// + /// Within a group rotation there is no timeout as backers are only affecting themselves. + /// + /// Must be at least 1. With a value of 1, the previous group will not be able to negatively + /// affect the following group at the expense of a tight availability timeline at group + /// rotation boundaries. + pub paras_availability_period: BlockNumber, + /// The maximum number of validators to have per core. + /// + /// `None` means no maximum. + pub max_validators_per_core: Option, + /// The amount of blocks ahead to schedule paras. + pub lookahead: u32, + /// How many cores are managed by the coretime chain. + pub num_cores: u32, + /// The max number of times a claim can time out in availability. + pub max_availability_timeouts: u32, + /// The maximum queue size of the pay as you go module. + pub on_demand_queue_max_size: u32, + /// The target utilization of the spot price queue in percentages. + pub on_demand_target_queue_utilization: Perbill, + /// How quickly the fee rises in reaction to increased utilization. + /// The lower the number the slower the increase. + pub on_demand_fee_variability: Perbill, + /// The minimum amount needed to claim a slot in the spot pricing queue. + pub on_demand_base_fee: Balance, + /// The number of blocks a claim stays in the scheduler's claimqueue before getting cleared. + /// This number should go reasonably higher than the number of blocks in the async backing + /// lookahead. + pub ttl: BlockNumber, +} + +impl> Default for SchedulerParams { + fn default() -> Self { + Self { + group_rotation_frequency: 1u32.into(), + paras_availability_period: 1u32.into(), + max_validators_per_core: Default::default(), + lookahead: 1, + num_cores: Default::default(), + max_availability_timeouts: Default::default(), + on_demand_queue_max_size: ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, + on_demand_target_queue_utilization: Perbill::from_percent(25), + on_demand_fee_variability: Perbill::from_percent(3), + on_demand_base_fee: 10_000_000u128, + ttl: 5u32.into(), + } + } +} + use bitvec::vec::BitVec; /// Bit indices in the `HostConfiguration.node_features` that correspond to different node features. diff --git a/polkadot/roadmap/implementers-guide/src/types/runtime.md b/polkadot/roadmap/implementers-guide/src/types/runtime.md index 4b97409f8df..1dfabd96db7 100644 --- a/polkadot/roadmap/implementers-guide/src/types/runtime.md +++ b/polkadot/roadmap/implementers-guide/src/types/runtime.md @@ -4,106 +4,24 @@ Types used within the runtime exclusively and pervasively. ## Host Configuration -The internal-to-runtime configuration of the parachain host. This is expected to be altered only by governance procedures. - -```rust -struct HostConfiguration { - /// The minimum period, in blocks, between which parachains can update their validation code. - pub validation_upgrade_cooldown: BlockNumber, - /// The delay, in blocks, before a validation upgrade is applied. - pub validation_upgrade_delay: BlockNumber, - /// How long to keep code on-chain, in blocks. This should be sufficiently long that disputes - /// have concluded. - pub code_retention_period: BlockNumber, - /// The maximum validation code size, in bytes. - pub max_code_size: u32, - /// The maximum head-data size, in bytes. - pub max_head_data_size: u32, - /// The amount of availability cores to dedicate to parathreads (on-demand parachains). - pub parathread_cores: u32, - /// The number of retries that a parathread (on-demand parachain) author has to submit their block. - pub parathread_retries: u32, - /// How often parachain groups should be rotated across parachains. - pub group_rotation_frequency: BlockNumber, - /// The availability period, in blocks, for parachains. This is the amount of blocks - /// after inclusion that validators have to make the block available and signal its availability to - /// the chain. Must be at least 1. - pub chain_availability_period: BlockNumber, - /// The availability period, in blocks, for parathreads (on-demand parachains). Same as the `chain_availability_period`, - /// but a differing timeout due to differing requirements. Must be at least 1. - pub thread_availability_period: BlockNumber, - /// The amount of blocks ahead to schedule on-demand parachains. - pub scheduling_lookahead: u32, - /// The maximum number of validators to have per core. `None` means no maximum. - pub max_validators_per_core: Option, - /// The maximum number of validators to use for parachains, in total. `None` means no maximum. - pub max_validators: Option, - /// The amount of sessions to keep for disputes. - pub dispute_period: SessionIndex, - /// How long after dispute conclusion to accept statements. - pub dispute_post_conclusion_acceptance_period: BlockNumber, - /// The maximum number of dispute spam slots - pub dispute_max_spam_slots: u32, - /// The amount of consensus slots that must pass between submitting an assignment and - /// submitting an approval vote before a validator is considered a no-show. - /// Must be at least 1. - pub no_show_slots: u32, - /// The number of delay tranches in total. - pub n_delay_tranches: u32, - /// The width of the zeroth delay tranche for approval assignments. This many delay tranches - /// beyond 0 are all consolidated to form a wide 0 tranche. - pub zeroth_delay_tranche_width: u32, - /// The number of validators needed to approve a block. - pub needed_approvals: u32, - /// The number of samples to use in `RelayVRFModulo` or `RelayVRFModuloCompact` approval assignment criterions. - pub relay_vrf_modulo_samples: u32, - /// Total number of individual messages allowed in the parachain -> relay-chain message queue. - pub max_upward_queue_count: u32, - /// Total size of messages allowed in the parachain -> relay-chain message queue before which - /// no further messages may be added to it. If it exceeds this then the queue may contain only - /// a single message. - pub max_upward_queue_size: u32, - /// The maximum size of an upward message that can be sent by a candidate. - /// - /// This parameter affects the upper bound of size of `CandidateCommitments`. - pub max_upward_message_size: u32, - /// The maximum number of messages that a candidate can contain. - /// - /// This parameter affects the upper bound of size of `CandidateCommitments`. - pub max_upward_message_num_per_candidate: u32, - /// The maximum size of a message that can be put in a downward message queue. - /// - /// Since we require receiving at least one DMP message the obvious upper bound of the size is - /// the PoV size. Of course, there is a lot of other different things that a parachain may - /// decide to do with its PoV so this value in practice will be picked as a fraction of the PoV - /// size. - pub max_downward_message_size: u32, - /// The deposit that the sender should provide for opening an HRMP channel. - pub hrmp_sender_deposit: u32, - /// The deposit that the recipient should provide for accepting opening an HRMP channel. - pub hrmp_recipient_deposit: u32, - /// The maximum number of messages allowed in an HRMP channel at once. - pub hrmp_channel_max_capacity: u32, - /// The maximum total size of messages in bytes allowed in an HRMP channel at once. - pub hrmp_channel_max_total_size: u32, - /// The maximum number of inbound HRMP channels a parachain is allowed to accept. - pub hrmp_max_parachain_inbound_channels: u32, - /// The maximum number of inbound HRMP channels a parathread (on-demand parachain) is allowed to accept. - pub hrmp_max_parathread_inbound_channels: u32, - /// The maximum size of a message that could ever be put into an HRMP channel. - /// - /// This parameter affects the upper bound of size of `CandidateCommitments`. - pub hrmp_channel_max_message_size: u32, - /// The maximum number of outbound HRMP channels a parachain is allowed to open. - pub hrmp_max_parachain_outbound_channels: u32, - /// The maximum number of outbound HRMP channels a parathread (on-demand parachain) is allowed to open. - pub hrmp_max_parathread_outbound_channels: u32, - /// The maximum number of outbound HRMP messages can be sent by a candidate. - /// - /// This parameter affects the upper bound of size of `CandidateCommitments`. - pub hrmp_max_message_num_per_candidate: u32, -} -``` +The internal-to-runtime configuration of the parachain host is kept in `struct HostConfiguration`. This is expected to +be altered only by governance procedures or via migrations from the Polkadot-SDK codebase. The latest definition of +`HostConfiguration` can be found in the project repo +[here](https://github.com/paritytech/polkadot-sdk/blob/master/polkadot/runtime/parachains/src/configuration.rs). Each +parameter has got a doc comment so for any details please refer to the code. + +Some related parameters in `HostConfiguration` are grouped together so that they can be managed easily. These are: +* `async_backing_params` in `struct AsyncBackingParams` +* `executor_params` in `struct ExecutorParams` +* `approval_voting_params` in `struct ApprovalVotingParams` +* `scheduler_params` in `struct SchedulerParams` + +Check the definitions of these structs for further details. + +### Configuration migrations +Modifying `HostConfiguration` requires a storage migration. These migrations are located in the +[`migrations`](https://github.com/paritytech/polkadot-sdk/blob/master/polkadot/runtime/parachains/src/configuration.rs) +subfolder of Polkadot-SDK repo. ## ParaInherentData diff --git a/polkadot/runtime/parachains/src/assigner_coretime/mock_helpers.rs b/polkadot/runtime/parachains/src/assigner_coretime/mock_helpers.rs index 71c3f1fa39f..e2ba0b4f7ea 100644 --- a/polkadot/runtime/parachains/src/assigner_coretime/mock_helpers.rs +++ b/polkadot/runtime/parachains/src/assigner_coretime/mock_helpers.rs @@ -64,11 +64,12 @@ impl GenesisConfigBuilder { pub(super) fn build(self) -> MockGenesisConfig { let mut genesis = default_genesis_config(); let config = &mut genesis.configuration.config; - config.coretime_cores = self.on_demand_cores; - config.on_demand_base_fee = self.on_demand_base_fee; - config.on_demand_fee_variability = self.on_demand_fee_variability; - config.on_demand_queue_max_size = self.on_demand_max_queue_size; - config.on_demand_target_queue_utilization = self.on_demand_target_queue_utilization; + config.scheduler_params.num_cores = self.on_demand_cores; + config.scheduler_params.on_demand_base_fee = self.on_demand_base_fee; + config.scheduler_params.on_demand_fee_variability = self.on_demand_fee_variability; + config.scheduler_params.on_demand_queue_max_size = self.on_demand_max_queue_size; + config.scheduler_params.on_demand_target_queue_utilization = + self.on_demand_target_queue_utilization; let paras = &mut genesis.paras.paras; for para_id in self.onboarded_on_demand_chains { diff --git a/polkadot/runtime/parachains/src/assigner_coretime/mod.rs b/polkadot/runtime/parachains/src/assigner_coretime/mod.rs index 9da81dc816c..e2da89fadd4 100644 --- a/polkadot/runtime/parachains/src/assigner_coretime/mod.rs +++ b/polkadot/runtime/parachains/src/assigner_coretime/mod.rs @@ -30,7 +30,7 @@ mod tests; use crate::{ assigner_on_demand, configuration, paras::AssignCoretime, - scheduler::common::{Assignment, AssignmentProvider, AssignmentProviderConfig}, + scheduler::common::{Assignment, AssignmentProvider}, ParaId, }; @@ -316,14 +316,6 @@ impl AssignmentProvider> for Pallet { } } - fn get_provider_config(_core_idx: CoreIndex) -> AssignmentProviderConfig> { - let config = >::config(); - AssignmentProviderConfig { - max_availability_timeouts: config.on_demand_retries, - ttl: config.on_demand_ttl, - } - } - #[cfg(any(feature = "runtime-benchmarks", test))] fn get_mock_assignment(_: CoreIndex, para_id: primitives::Id) -> Assignment { // Given that we are not tracking anything in `Bulk` assignments, it is safe to always @@ -333,7 +325,7 @@ impl AssignmentProvider> for Pallet { fn session_core_count() -> u32 { let config = >::config(); - config.coretime_cores + config.scheduler_params.num_cores } } @@ -482,8 +474,8 @@ impl AssignCoretime for Pallet { // Add a new core and assign the para to it. let mut config = >::config(); - let core = config.coretime_cores; - config.coretime_cores.saturating_inc(); + let core = config.scheduler_params.num_cores; + config.scheduler_params.num_cores.saturating_inc(); // `assign_coretime` is only called at genesis or by root, so setting the active // config here is fine. diff --git a/polkadot/runtime/parachains/src/assigner_on_demand/benchmarking.rs b/polkadot/runtime/parachains/src/assigner_on_demand/benchmarking.rs index 5a6060cd2b4..8360e7a78d0 100644 --- a/polkadot/runtime/parachains/src/assigner_on_demand/benchmarking.rs +++ b/polkadot/runtime/parachains/src/assigner_on_demand/benchmarking.rs @@ -43,7 +43,7 @@ where { ParasShared::::set_session_index(SESSION_INDEX); let mut config = HostConfiguration::default(); - config.coretime_cores = 1; + config.scheduler_params.num_cores = 1; ConfigurationPallet::::force_set_active_config(config); let mut parachains = ParachainsCache::new(); ParasPallet::::initialize_para_now( diff --git a/polkadot/runtime/parachains/src/assigner_on_demand/mock_helpers.rs b/polkadot/runtime/parachains/src/assigner_on_demand/mock_helpers.rs index de30330ac84..f8d1a894f0e 100644 --- a/polkadot/runtime/parachains/src/assigner_on_demand/mock_helpers.rs +++ b/polkadot/runtime/parachains/src/assigner_on_demand/mock_helpers.rs @@ -63,11 +63,12 @@ impl GenesisConfigBuilder { pub(super) fn build(self) -> MockGenesisConfig { let mut genesis = default_genesis_config(); let config = &mut genesis.configuration.config; - config.coretime_cores = self.on_demand_cores; - config.on_demand_base_fee = self.on_demand_base_fee; - config.on_demand_fee_variability = self.on_demand_fee_variability; - config.on_demand_queue_max_size = self.on_demand_max_queue_size; - config.on_demand_target_queue_utilization = self.on_demand_target_queue_utilization; + config.scheduler_params.num_cores = self.on_demand_cores; + config.scheduler_params.on_demand_base_fee = self.on_demand_base_fee; + config.scheduler_params.on_demand_fee_variability = self.on_demand_fee_variability; + config.scheduler_params.on_demand_queue_max_size = self.on_demand_max_queue_size; + config.scheduler_params.on_demand_target_queue_utilization = + self.on_demand_target_queue_utilization; let paras = &mut genesis.paras.paras; for para_id in self.onboarded_on_demand_chains { diff --git a/polkadot/runtime/parachains/src/assigner_on_demand/mod.rs b/polkadot/runtime/parachains/src/assigner_on_demand/mod.rs index 1b746e88694..bc450dc7812 100644 --- a/polkadot/runtime/parachains/src/assigner_on_demand/mod.rs +++ b/polkadot/runtime/parachains/src/assigner_on_demand/mod.rs @@ -201,10 +201,10 @@ pub mod pallet { let old_traffic = SpotTraffic::::get(); match Self::calculate_spot_traffic( old_traffic, - config.on_demand_queue_max_size, + config.scheduler_params.on_demand_queue_max_size, Self::queue_size(), - config.on_demand_target_queue_utilization, - config.on_demand_fee_variability, + config.scheduler_params.on_demand_target_queue_utilization, + config.scheduler_params.on_demand_fee_variability, ) { Ok(new_traffic) => { // Only update storage on change @@ -330,8 +330,9 @@ where let traffic = SpotTraffic::::get(); // Calculate spot price - let spot_price: BalanceOf = - traffic.saturating_mul_int(config.on_demand_base_fee.saturated_into::>()); + let spot_price: BalanceOf = traffic.saturating_mul_int( + config.scheduler_params.on_demand_base_fee.saturated_into::>(), + ); // Is the current price higher than `max_amount` ensure!(spot_price.le(&max_amount), Error::::SpotPriceHigherThanMaxAmount); @@ -450,7 +451,10 @@ where OnDemandQueue::::try_mutate(|queue| { // Abort transaction if queue is too large - ensure!(Self::queue_size() < config.on_demand_queue_max_size, Error::::QueueFull); + ensure!( + Self::queue_size() < config.scheduler_params.on_demand_queue_max_size, + Error::::QueueFull + ); match location { QueuePushDirection::Back => queue.push_back(order), QueuePushDirection::Front => queue.push_front(order), @@ -472,7 +476,7 @@ where target: LOG_TARGET, "Failed to fetch the on demand queue size, returning the max size." ); - return config.on_demand_queue_max_size + return config.scheduler_params.on_demand_queue_max_size }, } } diff --git a/polkadot/runtime/parachains/src/assigner_parachains.rs b/polkadot/runtime/parachains/src/assigner_parachains.rs index 34b5d3c1ec5..b5f342563e9 100644 --- a/polkadot/runtime/parachains/src/assigner_parachains.rs +++ b/polkadot/runtime/parachains/src/assigner_parachains.rs @@ -27,7 +27,7 @@ use primitives::CoreIndex; use crate::{ configuration, paras, - scheduler::common::{Assignment, AssignmentProvider, AssignmentProviderConfig}, + scheduler::common::{Assignment, AssignmentProvider}, }; pub use pallet::*; @@ -58,16 +58,6 @@ impl AssignmentProvider> for Pallet { /// this is a no-op in the case of a bulk assignment slot. fn push_back_assignment(_: Assignment) {} - fn get_provider_config(_core_idx: CoreIndex) -> AssignmentProviderConfig> { - AssignmentProviderConfig { - // The next assignment already goes to the same [`ParaId`], no timeout tracking needed. - max_availability_timeouts: 0, - // The next assignment already goes to the same [`ParaId`], this can be any number - // that's high enough to clear the time it takes to clear backing/availability. - ttl: 10u32.into(), - } - } - #[cfg(any(feature = "runtime-benchmarks", test))] fn get_mock_assignment(_: CoreIndex, para_id: primitives::Id) -> Assignment { Assignment::Bulk(para_id) diff --git a/polkadot/runtime/parachains/src/assigner_parachains/mock_helpers.rs b/polkadot/runtime/parachains/src/assigner_parachains/mock_helpers.rs index e6e9fb074aa..a46e114daea 100644 --- a/polkadot/runtime/parachains/src/assigner_parachains/mock_helpers.rs +++ b/polkadot/runtime/parachains/src/assigner_parachains/mock_helpers.rs @@ -60,11 +60,12 @@ impl GenesisConfigBuilder { pub(super) fn build(self) -> MockGenesisConfig { let mut genesis = default_genesis_config(); let config = &mut genesis.configuration.config; - config.coretime_cores = self.on_demand_cores; - config.on_demand_base_fee = self.on_demand_base_fee; - config.on_demand_fee_variability = self.on_demand_fee_variability; - config.on_demand_queue_max_size = self.on_demand_max_queue_size; - config.on_demand_target_queue_utilization = self.on_demand_target_queue_utilization; + config.scheduler_params.num_cores = self.on_demand_cores; + config.scheduler_params.on_demand_base_fee = self.on_demand_base_fee; + config.scheduler_params.on_demand_fee_variability = self.on_demand_fee_variability; + config.scheduler_params.on_demand_queue_max_size = self.on_demand_max_queue_size; + config.scheduler_params.on_demand_target_queue_utilization = + self.on_demand_target_queue_utilization; let paras = &mut genesis.paras.paras; for para_id in self.onboarded_on_demand_chains { diff --git a/polkadot/runtime/parachains/src/builder.rs b/polkadot/runtime/parachains/src/builder.rs index 500bc70cfa7..0e4e659fef2 100644 --- a/polkadot/runtime/parachains/src/builder.rs +++ b/polkadot/runtime/parachains/src/builder.rs @@ -18,11 +18,7 @@ use crate::{ configuration, inclusion, initializer, paras, paras::ParaKind, paras_inherent, - scheduler::{ - self, - common::{AssignmentProvider, AssignmentProviderConfig}, - CoreOccupied, ParasEntry, - }, + scheduler::{self, common::AssignmentProvider, CoreOccupied, ParasEntry}, session_info, shared, }; use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec}; @@ -197,7 +193,10 @@ impl BenchBuilder { /// Maximum number of validators per core (a.k.a. max validators per group). This value is used /// if none is explicitly set on the builder. pub(crate) fn fallback_max_validators_per_core() -> u32 { - configuration::Pallet::::config().max_validators_per_core.unwrap_or(5) + configuration::Pallet::::config() + .scheduler_params + .max_validators_per_core + .unwrap_or(5) } /// Specify a mapping of core index/ para id to the number of dispute statements for the @@ -684,7 +683,7 @@ impl BenchBuilder { // We are currently in Session 0, so these changes will take effect in Session 2. Self::setup_para_ids(used_cores); configuration::ActiveConfig::::mutate(|c| { - c.coretime_cores = used_cores; + c.scheduler_params.num_cores = used_cores; }); let validator_ids = Self::generate_validator_pairs(self.max_validators()); @@ -715,8 +714,7 @@ impl BenchBuilder { let cores = (0..used_cores) .into_iter() .map(|i| { - let AssignmentProviderConfig { ttl, .. } = - scheduler::Pallet::::assignment_provider_config(CoreIndex(i)); + let ttl = configuration::Pallet::::config().scheduler_params.ttl; // Load an assignment into provider so that one is present to pop let assignment = ::AssignmentProvider::get_mock_assignment( CoreIndex(i), @@ -731,8 +729,7 @@ impl BenchBuilder { let cores = (0..used_cores) .into_iter() .map(|i| { - let AssignmentProviderConfig { ttl, .. } = - scheduler::Pallet::::assignment_provider_config(CoreIndex(i)); + let ttl = configuration::Pallet::::config().scheduler_params.ttl; // Load an assignment into provider so that one is present to pop let assignment = ::AssignmentProvider::get_mock_assignment( diff --git a/polkadot/runtime/parachains/src/configuration.rs b/polkadot/runtime/parachains/src/configuration.rs index b0e9d03df88..364a15215d3 100644 --- a/polkadot/runtime/parachains/src/configuration.rs +++ b/polkadot/runtime/parachains/src/configuration.rs @@ -29,7 +29,6 @@ use primitives::{ vstaging::{ApprovalVotingParams, NodeFeatures}, AsyncBackingParams, Balance, ExecutorParamError, ExecutorParams, SessionIndex, LEGACY_MIN_BACKING_VOTES, MAX_CODE_SIZE, MAX_HEAD_DATA_SIZE, MAX_POV_SIZE, - ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, }; use sp_runtime::{traits::Zero, Perbill}; use sp_std::prelude::*; @@ -43,6 +42,7 @@ mod benchmarking; pub mod migration; pub use pallet::*; +use primitives::vstaging::SchedulerParams; const LOG_TARGET: &str = "runtime::configuration"; @@ -118,9 +118,9 @@ pub struct HostConfiguration { /// been completed. /// /// Note, there are situations in which `expected_at` in the past. For example, if - /// [`paras_availability_period`](Self::paras_availability_period) is less than the delay set - /// by this field or if PVF pre-check took more time than the delay. In such cases, the upgrade - /// is further at the earliest possible time determined by + /// [`paras_availability_period`](SchedulerParams::paras_availability_period) is less than the + /// delay set by this field or if PVF pre-check took more time than the delay. In such cases, + /// the upgrade is further at the earliest possible time determined by /// [`minimum_validation_upgrade_delay`](Self::minimum_validation_upgrade_delay). /// /// The rationale for this delay has to do with relay-chain reversions. In case there is an @@ -172,48 +172,7 @@ pub struct HostConfiguration { /// How long to keep code on-chain, in blocks. This should be sufficiently long that disputes /// have concluded. pub code_retention_period: BlockNumber, - /// How many cores are managed by the coretime chain. - pub coretime_cores: u32, - /// The number of retries that a on demand author has to submit their block. - pub on_demand_retries: u32, - /// The maximum queue size of the pay as you go module. - pub on_demand_queue_max_size: u32, - /// The target utilization of the spot price queue in percentages. - pub on_demand_target_queue_utilization: Perbill, - /// How quickly the fee rises in reaction to increased utilization. - /// The lower the number the slower the increase. - pub on_demand_fee_variability: Perbill, - /// The minimum amount needed to claim a slot in the spot pricing queue. - pub on_demand_base_fee: Balance, - /// The number of blocks an on demand claim stays in the scheduler's claimqueue before getting - /// cleared. This number should go reasonably higher than the number of blocks in the async - /// backing lookahead. - pub on_demand_ttl: BlockNumber, - /// How often parachain groups should be rotated across parachains. - /// - /// Must be non-zero. - pub group_rotation_frequency: BlockNumber, - /// The minimum availability period, in blocks. - /// - /// This is the minimum amount of blocks after a core became occupied that validators have time - /// to make the block available. - /// - /// This value only has effect on group rotations. If backers backed something at the end of - /// their rotation, the occupied core affects the backing group that comes afterwards. We limit - /// the effect one backing group can have on the next to `paras_availability_period` blocks. - /// - /// Within a group rotation there is no timeout as backers are only affecting themselves. - /// - /// Must be at least 1. With a value of 1, the previous group will not be able to negatively - /// affect the following group at the expense of a tight availability timeline at group - /// rotation boundaries. - pub paras_availability_period: BlockNumber, - /// The amount of blocks ahead to schedule paras. - pub scheduling_lookahead: u32, - /// The maximum number of validators to have per core. - /// - /// `None` means no maximum. - pub max_validators_per_core: Option, + /// The maximum number of validators to use for parachain consensus, period. /// /// `None` means no maximum. @@ -257,7 +216,7 @@ pub struct HostConfiguration { /// scheduled. This number is controlled by this field. /// /// This value should be greater than - /// [`paras_availability_period`](Self::paras_availability_period). + /// [`paras_availability_period`](SchedulerParams::paras_availability_period). pub minimum_validation_upgrade_delay: BlockNumber, /// The minimum number of valid backing statements required to consider a parachain candidate /// backable. @@ -266,6 +225,8 @@ pub struct HostConfiguration { pub node_features: NodeFeatures, /// Params used by approval-voting pub approval_voting_params: ApprovalVotingParams, + /// Scheduler parameters + pub scheduler_params: SchedulerParams, } impl> Default for HostConfiguration { @@ -275,8 +236,6 @@ impl> Default for HostConfiguration> Default for HostConfiguration> Default for HostConfiguration { ZeroMinimumBackingVotes, /// `executor_params` are inconsistent. InconsistentExecutorParams { inner: ExecutorParamError }, + /// TTL should be bigger than lookahead + LookaheadExceedsTTL, } impl HostConfiguration @@ -373,11 +326,11 @@ where pub fn check_consistency(&self) -> Result<(), InconsistentError> { use InconsistentError::*; - if self.group_rotation_frequency.is_zero() { + if self.scheduler_params.group_rotation_frequency.is_zero() { return Err(ZeroGroupRotationFrequency) } - if self.paras_availability_period.is_zero() { + if self.scheduler_params.paras_availability_period.is_zero() { return Err(ZeroParasAvailabilityPeriod) } @@ -399,10 +352,11 @@ where return Err(MaxPovSizeExceedHardLimit { max_pov_size: self.max_pov_size }) } - if self.minimum_validation_upgrade_delay <= self.paras_availability_period { + if self.minimum_validation_upgrade_delay <= self.scheduler_params.paras_availability_period + { return Err(MinimumValidationUpgradeDelayLessThanChainAvailabilityPeriod { minimum_validation_upgrade_delay: self.minimum_validation_upgrade_delay.clone(), - paras_availability_period: self.paras_availability_period.clone(), + paras_availability_period: self.scheduler_params.paras_availability_period.clone(), }) } @@ -447,6 +401,10 @@ where return Err(InconsistentExecutorParams { inner }) } + if self.scheduler_params.ttl < self.scheduler_params.lookahead.into() { + return Err(LookaheadExceedsTTL) + } + Ok(()) } @@ -471,6 +429,7 @@ pub trait WeightInfo { fn set_config_with_executor_params() -> Weight; fn set_config_with_perbill() -> Weight; fn set_node_feature() -> Weight; + fn set_config_with_scheduler_params() -> Weight; } pub struct TestWeightInfo; @@ -499,6 +458,9 @@ impl WeightInfo for TestWeightInfo { fn set_node_feature() -> Weight { Weight::MAX } + fn set_config_with_scheduler_params() -> Weight { + Weight::MAX + } } #[frame_support::pallet] @@ -520,7 +482,8 @@ pub mod pallet { /// v8-v9: /// v9-v10: /// v10-11: - const STORAGE_VERSION: StorageVersion = StorageVersion::new(11); + /// v11-12: + const STORAGE_VERSION: StorageVersion = StorageVersion::new(12); #[pallet::pallet] #[pallet::storage_version(STORAGE_VERSION)] @@ -679,16 +642,16 @@ pub mod pallet { Self::set_coretime_cores_unchecked(new) } - /// Set the number of retries for a particular on demand. + /// Set the max number of times a claim may timeout on a core before it is abandoned #[pallet::call_index(7)] #[pallet::weight(( T::WeightInfo::set_config_with_u32(), DispatchClass::Operational, ))] - pub fn set_on_demand_retries(origin: OriginFor, new: u32) -> DispatchResult { + pub fn set_max_availability_timeouts(origin: OriginFor, new: u32) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.on_demand_retries = new; + config.scheduler_params.max_availability_timeouts = new; }) } @@ -704,7 +667,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.group_rotation_frequency = new; + config.scheduler_params.group_rotation_frequency = new; }) } @@ -720,7 +683,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.paras_availability_period = new; + config.scheduler_params.paras_availability_period = new; }) } @@ -733,7 +696,7 @@ pub mod pallet { pub fn set_scheduling_lookahead(origin: OriginFor, new: u32) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.scheduling_lookahead = new; + config.scheduler_params.lookahead = new; }) } @@ -749,7 +712,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.max_validators_per_core = new; + config.scheduler_params.max_validators_per_core = new; }) } @@ -1141,7 +1104,7 @@ pub mod pallet { pub fn set_on_demand_base_fee(origin: OriginFor, new: Balance) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.on_demand_base_fee = new; + config.scheduler_params.on_demand_base_fee = new; }) } @@ -1154,7 +1117,7 @@ pub mod pallet { pub fn set_on_demand_fee_variability(origin: OriginFor, new: Perbill) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.on_demand_fee_variability = new; + config.scheduler_params.on_demand_fee_variability = new; }) } @@ -1167,7 +1130,7 @@ pub mod pallet { pub fn set_on_demand_queue_max_size(origin: OriginFor, new: u32) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.on_demand_queue_max_size = new; + config.scheduler_params.on_demand_queue_max_size = new; }) } /// Set the on demand (parathreads) fee variability. @@ -1182,7 +1145,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.on_demand_target_queue_utilization = new; + config.scheduler_params.on_demand_target_queue_utilization = new; }) } /// Set the on demand (parathreads) ttl in the claimqueue. @@ -1194,7 +1157,7 @@ pub mod pallet { pub fn set_on_demand_ttl(origin: OriginFor, new: BlockNumberFor) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.on_demand_ttl = new; + config.scheduler_params.ttl = new; }) } @@ -1244,6 +1207,22 @@ pub mod pallet { config.approval_voting_params = new; }) } + + /// Set scheduler-params. + #[pallet::call_index(55)] + #[pallet::weight(( + T::WeightInfo::set_config_with_scheduler_params(), + DispatchClass::Operational, + ))] + pub fn set_scheduler_params( + origin: OriginFor, + new: SchedulerParams>, + ) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.scheduler_params = new; + }) + } } impl Pallet { @@ -1252,7 +1231,7 @@ pub mod pallet { /// To be used if authorization is checked otherwise. pub fn set_coretime_cores_unchecked(new: u32) -> DispatchResult { Self::schedule_config_update(|config| { - config.coretime_cores = new; + config.scheduler_params.num_cores = new; }) } } @@ -1393,7 +1372,7 @@ impl Pallet { let base_config_consistent = base_config.check_consistency().is_ok(); // Now, we need to decide what the new configuration should be. - // We also move the `base_config` to `new_config` to empahsize that the base config was + // We also move the `base_config` to `new_config` to emphasize that the base config was // destroyed by the `updater`. updater(&mut base_config); let new_config = base_config; diff --git a/polkadot/runtime/parachains/src/configuration/benchmarking.rs b/polkadot/runtime/parachains/src/configuration/benchmarking.rs index 67daf1c4598..882b5aab096 100644 --- a/polkadot/runtime/parachains/src/configuration/benchmarking.rs +++ b/polkadot/runtime/parachains/src/configuration/benchmarking.rs @@ -51,6 +51,8 @@ benchmarks! { set_node_feature{}: set_node_feature(RawOrigin::Root, 255, true) + set_config_with_scheduler_params {} : set_scheduler_params(RawOrigin::Root, SchedulerParams::default()) + impl_benchmark_test_suite!( Pallet, crate::mock::new_test_ext(Default::default()), diff --git a/polkadot/runtime/parachains/src/configuration/migration.rs b/polkadot/runtime/parachains/src/configuration/migration.rs index 2838b73092d..87b30b177e7 100644 --- a/polkadot/runtime/parachains/src/configuration/migration.rs +++ b/polkadot/runtime/parachains/src/configuration/migration.rs @@ -18,6 +18,7 @@ pub mod v10; pub mod v11; +pub mod v12; pub mod v6; pub mod v7; pub mod v8; diff --git a/polkadot/runtime/parachains/src/configuration/migration/v11.rs b/polkadot/runtime/parachains/src/configuration/migration/v11.rs index a69061ac138..f6e0e043164 100644 --- a/polkadot/runtime/parachains/src/configuration/migration/v11.rs +++ b/polkadot/runtime/parachains/src/configuration/migration/v11.rs @@ -21,13 +21,122 @@ use frame_support::{ migrations::VersionedMigration, pallet_prelude::*, traits::Defensive, weights::Weight, }; use frame_system::pallet_prelude::BlockNumberFor; -use primitives::{vstaging::ApprovalVotingParams, SessionIndex}; +use primitives::{ + vstaging::ApprovalVotingParams, AsyncBackingParams, ExecutorParams, SessionIndex, + LEGACY_MIN_BACKING_VOTES, ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, +}; use sp_std::vec::Vec; use frame_support::traits::OnRuntimeUpgrade; +use polkadot_core_primitives::Balance; +use primitives::vstaging::NodeFeatures; +use sp_arithmetic::Perbill; use super::v10::V10HostConfiguration; -type V11HostConfiguration = configuration::HostConfiguration; + +#[derive(Clone, Encode, PartialEq, Decode, Debug)] +pub struct V11HostConfiguration { + pub max_code_size: u32, + pub max_head_data_size: u32, + pub max_upward_queue_count: u32, + pub max_upward_queue_size: u32, + pub max_upward_message_size: u32, + pub max_upward_message_num_per_candidate: u32, + pub hrmp_max_message_num_per_candidate: u32, + pub validation_upgrade_cooldown: BlockNumber, + pub validation_upgrade_delay: BlockNumber, + pub async_backing_params: AsyncBackingParams, + pub max_pov_size: u32, + pub max_downward_message_size: u32, + pub hrmp_max_parachain_outbound_channels: u32, + pub hrmp_sender_deposit: Balance, + pub hrmp_recipient_deposit: Balance, + pub hrmp_channel_max_capacity: u32, + pub hrmp_channel_max_total_size: u32, + pub hrmp_max_parachain_inbound_channels: u32, + pub hrmp_channel_max_message_size: u32, + pub executor_params: ExecutorParams, + pub code_retention_period: BlockNumber, + pub coretime_cores: u32, + pub on_demand_retries: u32, + pub on_demand_queue_max_size: u32, + pub on_demand_target_queue_utilization: Perbill, + pub on_demand_fee_variability: Perbill, + pub on_demand_base_fee: Balance, + pub on_demand_ttl: BlockNumber, + pub group_rotation_frequency: BlockNumber, + pub paras_availability_period: BlockNumber, + pub scheduling_lookahead: u32, + pub max_validators_per_core: Option, + pub max_validators: Option, + pub dispute_period: SessionIndex, + pub dispute_post_conclusion_acceptance_period: BlockNumber, + pub no_show_slots: u32, + pub n_delay_tranches: u32, + pub zeroth_delay_tranche_width: u32, + pub needed_approvals: u32, + pub relay_vrf_modulo_samples: u32, + pub pvf_voting_ttl: SessionIndex, + pub minimum_validation_upgrade_delay: BlockNumber, + pub minimum_backing_votes: u32, + pub node_features: NodeFeatures, + pub approval_voting_params: ApprovalVotingParams, +} + +impl> Default for V11HostConfiguration { + fn default() -> Self { + Self { + async_backing_params: AsyncBackingParams { + max_candidate_depth: 0, + allowed_ancestry_len: 0, + }, + group_rotation_frequency: 1u32.into(), + paras_availability_period: 1u32.into(), + no_show_slots: 1u32.into(), + validation_upgrade_cooldown: Default::default(), + validation_upgrade_delay: 2u32.into(), + code_retention_period: Default::default(), + max_code_size: Default::default(), + max_pov_size: Default::default(), + max_head_data_size: Default::default(), + coretime_cores: Default::default(), + on_demand_retries: Default::default(), + scheduling_lookahead: 1, + max_validators_per_core: Default::default(), + max_validators: None, + dispute_period: 6, + dispute_post_conclusion_acceptance_period: 100.into(), + n_delay_tranches: Default::default(), + zeroth_delay_tranche_width: Default::default(), + needed_approvals: Default::default(), + relay_vrf_modulo_samples: Default::default(), + max_upward_queue_count: Default::default(), + max_upward_queue_size: Default::default(), + max_downward_message_size: Default::default(), + max_upward_message_size: Default::default(), + max_upward_message_num_per_candidate: Default::default(), + hrmp_sender_deposit: Default::default(), + hrmp_recipient_deposit: Default::default(), + hrmp_channel_max_capacity: Default::default(), + hrmp_channel_max_total_size: Default::default(), + hrmp_max_parachain_inbound_channels: Default::default(), + hrmp_channel_max_message_size: Default::default(), + hrmp_max_parachain_outbound_channels: Default::default(), + hrmp_max_message_num_per_candidate: Default::default(), + pvf_voting_ttl: 2u32.into(), + minimum_validation_upgrade_delay: 2.into(), + executor_params: Default::default(), + approval_voting_params: ApprovalVotingParams { max_approval_coalesce_count: 1 }, + on_demand_queue_max_size: ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, + on_demand_base_fee: 10_000_000u128, + on_demand_fee_variability: Perbill::from_percent(3), + on_demand_target_queue_utilization: Perbill::from_percent(25), + on_demand_ttl: 5u32.into(), + minimum_backing_votes: LEGACY_MIN_BACKING_VOTES, + node_features: NodeFeatures::EMPTY, + } + } +} mod v10 { use super::*; diff --git a/polkadot/runtime/parachains/src/configuration/migration/v12.rs b/polkadot/runtime/parachains/src/configuration/migration/v12.rs new file mode 100644 index 00000000000..4295a79893e --- /dev/null +++ b/polkadot/runtime/parachains/src/configuration/migration/v12.rs @@ -0,0 +1,349 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! A module that is responsible for migration of storage. + +use crate::configuration::{self, migration::v11::V11HostConfiguration, Config, Pallet}; +use frame_support::{ + migrations::VersionedMigration, + pallet_prelude::*, + traits::{Defensive, OnRuntimeUpgrade}, +}; +use frame_system::pallet_prelude::BlockNumberFor; +use primitives::vstaging::SchedulerParams; +use sp_core::Get; +use sp_staking::SessionIndex; +use sp_std::vec::Vec; + +type V12HostConfiguration = configuration::HostConfiguration; + +mod v11 { + use super::*; + + #[frame_support::storage_alias] + pub(crate) type ActiveConfig = + StorageValue, V11HostConfiguration>, OptionQuery>; + + #[frame_support::storage_alias] + pub(crate) type PendingConfigs = StorageValue< + Pallet, + Vec<(SessionIndex, V11HostConfiguration>)>, + OptionQuery, + >; +} + +mod v12 { + use super::*; + + #[frame_support::storage_alias] + pub(crate) type ActiveConfig = + StorageValue, V12HostConfiguration>, OptionQuery>; + + #[frame_support::storage_alias] + pub(crate) type PendingConfigs = StorageValue< + Pallet, + Vec<(SessionIndex, V12HostConfiguration>)>, + OptionQuery, + >; +} + +pub type MigrateToV12 = VersionedMigration< + 11, + 12, + UncheckedMigrateToV12, + Pallet, + ::DbWeight, +>; + +pub struct UncheckedMigrateToV12(sp_std::marker::PhantomData); + +impl OnRuntimeUpgrade for UncheckedMigrateToV12 { + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { + log::trace!(target: crate::configuration::LOG_TARGET, "Running pre_upgrade() for HostConfiguration MigrateToV12"); + Ok(Vec::new()) + } + + fn on_runtime_upgrade() -> Weight { + log::info!(target: configuration::LOG_TARGET, "HostConfiguration MigrateToV12 started"); + let weight_consumed = migrate_to_v12::(); + + log::info!(target: configuration::LOG_TARGET, "HostConfiguration MigrateToV12 executed successfully"); + + weight_consumed + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(_state: Vec) -> Result<(), sp_runtime::TryRuntimeError> { + log::trace!(target: crate::configuration::LOG_TARGET, "Running post_upgrade() for HostConfiguration MigrateToV12"); + ensure!( + StorageVersion::get::>() >= 12, + "Storage version should be >= 12 after the migration" + ); + + Ok(()) + } +} + +fn migrate_to_v12() -> Weight { + // Unusual formatting is justified: + // - make it easier to verify that fields assign what they supposed to assign. + // - this code is transient and will be removed after all migrations are done. + // - this code is important enough to optimize for legibility sacrificing consistency. + #[rustfmt::skip] + let translate = + |pre: V11HostConfiguration>| -> + V12HostConfiguration> + { + V12HostConfiguration { + max_code_size : pre.max_code_size, + max_head_data_size : pre.max_head_data_size, + max_upward_queue_count : pre.max_upward_queue_count, + max_upward_queue_size : pre.max_upward_queue_size, + max_upward_message_size : pre.max_upward_message_size, + max_upward_message_num_per_candidate : pre.max_upward_message_num_per_candidate, + hrmp_max_message_num_per_candidate : pre.hrmp_max_message_num_per_candidate, + validation_upgrade_cooldown : pre.validation_upgrade_cooldown, + validation_upgrade_delay : pre.validation_upgrade_delay, + max_pov_size : pre.max_pov_size, + max_downward_message_size : pre.max_downward_message_size, + hrmp_sender_deposit : pre.hrmp_sender_deposit, + hrmp_recipient_deposit : pre.hrmp_recipient_deposit, + hrmp_channel_max_capacity : pre.hrmp_channel_max_capacity, + hrmp_channel_max_total_size : pre.hrmp_channel_max_total_size, + hrmp_max_parachain_inbound_channels : pre.hrmp_max_parachain_inbound_channels, + hrmp_max_parachain_outbound_channels : pre.hrmp_max_parachain_outbound_channels, + hrmp_channel_max_message_size : pre.hrmp_channel_max_message_size, + code_retention_period : pre.code_retention_period, + max_validators : pre.max_validators, + dispute_period : pre.dispute_period, + dispute_post_conclusion_acceptance_period: pre.dispute_post_conclusion_acceptance_period, + no_show_slots : pre.no_show_slots, + n_delay_tranches : pre.n_delay_tranches, + zeroth_delay_tranche_width : pre.zeroth_delay_tranche_width, + needed_approvals : pre.needed_approvals, + relay_vrf_modulo_samples : pre.relay_vrf_modulo_samples, + pvf_voting_ttl : pre.pvf_voting_ttl, + minimum_validation_upgrade_delay : pre.minimum_validation_upgrade_delay, + async_backing_params : pre.async_backing_params, + executor_params : pre.executor_params, + minimum_backing_votes : pre.minimum_backing_votes, + node_features : pre.node_features, + approval_voting_params : pre.approval_voting_params, + scheduler_params: SchedulerParams { + group_rotation_frequency : pre.group_rotation_frequency, + paras_availability_period : pre.paras_availability_period, + max_validators_per_core : pre.max_validators_per_core, + lookahead : pre.scheduling_lookahead, + num_cores : pre.coretime_cores, + max_availability_timeouts : pre.on_demand_retries, + on_demand_queue_max_size : pre.on_demand_queue_max_size, + on_demand_target_queue_utilization : pre.on_demand_target_queue_utilization, + on_demand_fee_variability : pre.on_demand_fee_variability, + on_demand_base_fee : pre.on_demand_base_fee, + ttl : pre.on_demand_ttl, + } + } + }; + + let v11 = v11::ActiveConfig::::get() + .defensive_proof("Could not decode old config") + .unwrap_or_default(); + let v12 = translate(v11); + v12::ActiveConfig::::set(Some(v12)); + + // Allowed to be empty. + let pending_v11 = v11::PendingConfigs::::get().unwrap_or_default(); + let mut pending_v12 = Vec::new(); + + for (session, v11) in pending_v11.into_iter() { + let v12 = translate(v11); + pending_v12.push((session, v12)); + } + v12::PendingConfigs::::set(Some(pending_v12.clone())); + + let num_configs = (pending_v12.len() + 1) as u64; + T::DbWeight::get().reads_writes(num_configs, num_configs) +} + +#[cfg(test)] +mod tests { + use primitives::LEGACY_MIN_BACKING_VOTES; + use sp_arithmetic::Perbill; + + use super::*; + use crate::mock::{new_test_ext, Test}; + + #[test] + fn v12_deserialized_from_actual_data() { + // Example how to get new `raw_config`: + // We'll obtain the raw_config at a specified a block + // Steps: + // 1. Go to Polkadot.js -> Developer -> Chain state -> Storage: https://polkadot.js.org/apps/#/chainstate + // 2. Set these parameters: + // 2.1. selected state query: configuration; activeConfig(): + // PolkadotRuntimeParachainsConfigurationHostConfiguration + // 2.2. blockhash to query at: + // 0xf89d3ab5312c5f70d396dc59612f0aa65806c798346f9db4b35278baed2e0e53 (the hash of + // the block) + // 2.3. Note the value of encoded storage key -> + // 0x06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385 for the + // referenced block. + // 2.4. You'll also need the decoded values to update the test. + // 3. Go to Polkadot.js -> Developer -> Chain state -> Raw storage + // 3.1 Enter the encoded storage key and you get the raw config. + + // This exceeds the maximal line width length, but that's fine, since this is not code and + // doesn't need to be read and also leaving it as one line allows to easily copy it. + let raw_config = + hex_literal::hex![ + "0000300000800000080000000000100000c8000005000000050000000200000002000000000000000000000000005000000010000400000000000000000000000000000000000000000000000000000000000000000000000800000000200000040000000000100000b004000000060000006400000002000000190000000000000002000000020000000200000005000000020000000001000000140000000400000001010000000100000001000000000000001027000080b2e60e80c3c9018096980000000000000000000000000005000000" + ]; + + let v12 = + V12HostConfiguration::::decode(&mut &raw_config[..]).unwrap(); + + // We check only a sample of the values here. If we missed any fields or messed up data + // types that would skew all the fields coming after. + assert_eq!(v12.max_code_size, 3_145_728); + assert_eq!(v12.validation_upgrade_cooldown, 2); + assert_eq!(v12.max_pov_size, 5_242_880); + assert_eq!(v12.hrmp_channel_max_message_size, 1_048_576); + assert_eq!(v12.n_delay_tranches, 25); + assert_eq!(v12.minimum_validation_upgrade_delay, 5); + assert_eq!(v12.minimum_backing_votes, LEGACY_MIN_BACKING_VOTES); + assert_eq!(v12.approval_voting_params.max_approval_coalesce_count, 1); + assert_eq!(v12.scheduler_params.group_rotation_frequency, 20); + assert_eq!(v12.scheduler_params.paras_availability_period, 4); + assert_eq!(v12.scheduler_params.lookahead, 1); + assert_eq!(v12.scheduler_params.num_cores, 1); + assert_eq!(v12.scheduler_params.max_availability_timeouts, 0); + assert_eq!(v12.scheduler_params.on_demand_queue_max_size, 10_000); + assert_eq!( + v12.scheduler_params.on_demand_target_queue_utilization, + Perbill::from_percent(25) + ); + assert_eq!(v12.scheduler_params.on_demand_fee_variability, Perbill::from_percent(3)); + assert_eq!(v12.scheduler_params.on_demand_base_fee, 10_000_000); + assert_eq!(v12.scheduler_params.ttl, 5); + } + + #[test] + fn test_migrate_to_v12() { + // Host configuration has lots of fields. However, in this migration we only add one + // field. The most important part to check are a couple of the last fields. We also pick + // extra fields to check arbitrarily, e.g. depending on their position (i.e. the middle) and + // also their type. + // + // We specify only the picked fields and the rest should be provided by the `Default` + // implementation. That implementation is copied over between the two types and should work + // fine. + let v11 = V11HostConfiguration:: { + needed_approvals: 69, + paras_availability_period: 55, + hrmp_recipient_deposit: 1337, + max_pov_size: 1111, + minimum_validation_upgrade_delay: 20, + on_demand_ttl: 3, + on_demand_retries: 10, + ..Default::default() + }; + + let mut pending_configs = Vec::new(); + pending_configs.push((100, v11.clone())); + pending_configs.push((300, v11.clone())); + + new_test_ext(Default::default()).execute_with(|| { + // Implant the v10 version in the state. + v11::ActiveConfig::::set(Some(v11.clone())); + v11::PendingConfigs::::set(Some(pending_configs)); + + migrate_to_v12::(); + + let v12 = v12::ActiveConfig::::get().unwrap(); + assert_eq!(v12.approval_voting_params.max_approval_coalesce_count, 1); + + let mut configs_to_check = v12::PendingConfigs::::get().unwrap(); + configs_to_check.push((0, v12.clone())); + + for (_, v12) in configs_to_check { + #[rustfmt::skip] + { + assert_eq!(v11.max_code_size , v12.max_code_size); + assert_eq!(v11.max_head_data_size , v12.max_head_data_size); + assert_eq!(v11.max_upward_queue_count , v12.max_upward_queue_count); + assert_eq!(v11.max_upward_queue_size , v12.max_upward_queue_size); + assert_eq!(v11.max_upward_message_size , v12.max_upward_message_size); + assert_eq!(v11.max_upward_message_num_per_candidate , v12.max_upward_message_num_per_candidate); + assert_eq!(v11.hrmp_max_message_num_per_candidate , v12.hrmp_max_message_num_per_candidate); + assert_eq!(v11.validation_upgrade_cooldown , v12.validation_upgrade_cooldown); + assert_eq!(v11.validation_upgrade_delay , v12.validation_upgrade_delay); + assert_eq!(v11.max_pov_size , v12.max_pov_size); + assert_eq!(v11.max_downward_message_size , v12.max_downward_message_size); + assert_eq!(v11.hrmp_max_parachain_outbound_channels , v12.hrmp_max_parachain_outbound_channels); + assert_eq!(v11.hrmp_sender_deposit , v12.hrmp_sender_deposit); + assert_eq!(v11.hrmp_recipient_deposit , v12.hrmp_recipient_deposit); + assert_eq!(v11.hrmp_channel_max_capacity , v12.hrmp_channel_max_capacity); + assert_eq!(v11.hrmp_channel_max_total_size , v12.hrmp_channel_max_total_size); + assert_eq!(v11.hrmp_max_parachain_inbound_channels , v12.hrmp_max_parachain_inbound_channels); + assert_eq!(v11.hrmp_channel_max_message_size , v12.hrmp_channel_max_message_size); + assert_eq!(v11.code_retention_period , v12.code_retention_period); + assert_eq!(v11.max_validators , v12.max_validators); + assert_eq!(v11.dispute_period , v12.dispute_period); + assert_eq!(v11.no_show_slots , v12.no_show_slots); + assert_eq!(v11.n_delay_tranches , v12.n_delay_tranches); + assert_eq!(v11.zeroth_delay_tranche_width , v12.zeroth_delay_tranche_width); + assert_eq!(v11.needed_approvals , v12.needed_approvals); + assert_eq!(v11.relay_vrf_modulo_samples , v12.relay_vrf_modulo_samples); + assert_eq!(v11.pvf_voting_ttl , v12.pvf_voting_ttl); + assert_eq!(v11.minimum_validation_upgrade_delay , v12.minimum_validation_upgrade_delay); + assert_eq!(v11.async_backing_params.allowed_ancestry_len, v12.async_backing_params.allowed_ancestry_len); + assert_eq!(v11.async_backing_params.max_candidate_depth , v12.async_backing_params.max_candidate_depth); + assert_eq!(v11.executor_params , v12.executor_params); + assert_eq!(v11.minimum_backing_votes , v12.minimum_backing_votes); + assert_eq!(v11.group_rotation_frequency , v12.scheduler_params.group_rotation_frequency); + assert_eq!(v11.paras_availability_period , v12.scheduler_params.paras_availability_period); + assert_eq!(v11.max_validators_per_core , v12.scheduler_params.max_validators_per_core); + assert_eq!(v11.scheduling_lookahead , v12.scheduler_params.lookahead); + assert_eq!(v11.coretime_cores , v12.scheduler_params.num_cores); + assert_eq!(v11.on_demand_retries , v12.scheduler_params.max_availability_timeouts); + assert_eq!(v11.on_demand_queue_max_size , v12.scheduler_params.on_demand_queue_max_size); + assert_eq!(v11.on_demand_target_queue_utilization , v12.scheduler_params.on_demand_target_queue_utilization); + assert_eq!(v11.on_demand_fee_variability , v12.scheduler_params.on_demand_fee_variability); + assert_eq!(v11.on_demand_base_fee , v12.scheduler_params.on_demand_base_fee); + assert_eq!(v11.on_demand_ttl , v12.scheduler_params.ttl); + }; // ; makes this a statement. `rustfmt::skip` cannot be put on an expression. + } + }); + } + + // Test that migration doesn't panic in case there are no pending configurations upgrades in + // pallet's storage. + #[test] + fn test_migrate_to_v12_no_pending() { + let v11 = V11HostConfiguration::::default(); + + new_test_ext(Default::default()).execute_with(|| { + // Implant the v10 version in the state. + v11::ActiveConfig::::set(Some(v11)); + // Ensure there are no pending configs. + v12::PendingConfigs::::set(None); + + // Shouldn't fail. + migrate_to_v12::(); + }); + } +} diff --git a/polkadot/runtime/parachains/src/configuration/tests.rs b/polkadot/runtime/parachains/src/configuration/tests.rs index f1570017dd7..254511231ca 100644 --- a/polkadot/runtime/parachains/src/configuration/tests.rs +++ b/polkadot/runtime/parachains/src/configuration/tests.rs @@ -226,8 +226,11 @@ fn invariants() { ); ActiveConfig::::put(HostConfiguration { - paras_availability_period: 10, minimum_validation_upgrade_delay: 11, + scheduler_params: SchedulerParams { + paras_availability_period: 10, + ..Default::default() + }, ..Default::default() }); assert_err!( @@ -283,12 +286,6 @@ fn setting_pending_config_members() { max_code_size: 100_000, max_pov_size: 1024, max_head_data_size: 1_000, - coretime_cores: 2, - on_demand_retries: 5, - group_rotation_frequency: 20, - paras_availability_period: 10, - scheduling_lookahead: 3, - max_validators_per_core: None, max_validators: None, dispute_period: 239, dispute_post_conclusion_acceptance_period: 10, @@ -314,13 +311,21 @@ fn setting_pending_config_members() { minimum_validation_upgrade_delay: 20, executor_params: Default::default(), approval_voting_params: ApprovalVotingParams { max_approval_coalesce_count: 1 }, - on_demand_queue_max_size: 10_000u32, - on_demand_base_fee: 10_000_000u128, - on_demand_fee_variability: Perbill::from_percent(3), - on_demand_target_queue_utilization: Perbill::from_percent(25), - on_demand_ttl: 5u32, minimum_backing_votes: 5, node_features: bitvec![u8, Lsb0; 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], + scheduler_params: SchedulerParams { + group_rotation_frequency: 20, + paras_availability_period: 10, + max_validators_per_core: None, + lookahead: 3, + num_cores: 2, + max_availability_timeouts: 5, + on_demand_queue_max_size: 10_000u32, + on_demand_base_fee: 10_000_000u128, + on_demand_fee_variability: Perbill::from_percent(3), + on_demand_target_queue_utilization: Perbill::from_percent(25), + ttl: 5u32, + }, }; Configuration::set_validation_upgrade_cooldown( @@ -342,13 +347,19 @@ fn setting_pending_config_members() { Configuration::set_max_pov_size(RuntimeOrigin::root(), new_config.max_pov_size).unwrap(); Configuration::set_max_head_data_size(RuntimeOrigin::root(), new_config.max_head_data_size) .unwrap(); - Configuration::set_coretime_cores(RuntimeOrigin::root(), new_config.coretime_cores) - .unwrap(); - Configuration::set_on_demand_retries(RuntimeOrigin::root(), new_config.on_demand_retries) - .unwrap(); + Configuration::set_coretime_cores( + RuntimeOrigin::root(), + new_config.scheduler_params.num_cores, + ) + .unwrap(); + Configuration::set_max_availability_timeouts( + RuntimeOrigin::root(), + new_config.scheduler_params.max_availability_timeouts, + ) + .unwrap(); Configuration::set_group_rotation_frequency( RuntimeOrigin::root(), - new_config.group_rotation_frequency, + new_config.scheduler_params.group_rotation_frequency, ) .unwrap(); // This comes out of order to satisfy the validity criteria for the chain and thread @@ -360,17 +371,17 @@ fn setting_pending_config_members() { .unwrap(); Configuration::set_paras_availability_period( RuntimeOrigin::root(), - new_config.paras_availability_period, + new_config.scheduler_params.paras_availability_period, ) .unwrap(); Configuration::set_scheduling_lookahead( RuntimeOrigin::root(), - new_config.scheduling_lookahead, + new_config.scheduler_params.lookahead, ) .unwrap(); Configuration::set_max_validators_per_core( RuntimeOrigin::root(), - new_config.max_validators_per_core, + new_config.scheduler_params.max_validators_per_core, ) .unwrap(); Configuration::set_max_validators(RuntimeOrigin::root(), new_config.max_validators) diff --git a/polkadot/runtime/parachains/src/coretime/migration.rs b/polkadot/runtime/parachains/src/coretime/migration.rs index 9bc0a20ef5b..03fecc58570 100644 --- a/polkadot/runtime/parachains/src/coretime/migration.rs +++ b/polkadot/runtime/parachains/src/coretime/migration.rs @@ -114,7 +114,7 @@ mod v_coretime { let legacy_paras = paras::Parachains::::get(); let config = >::config(); - let total_core_count = config.coretime_cores + legacy_paras.len() as u32; + let total_core_count = config.scheduler_params.num_cores + legacy_paras.len() as u32; let dmp_queue_size = crate::dmp::Pallet::::dmq_contents(T::BrokerId::get().into()).len() as u32; @@ -150,7 +150,7 @@ mod v_coretime { // Migrate to Coretime. // - // NOTE: Also migrates coretime_cores config value in configuration::ActiveConfig. + // NOTE: Also migrates `num_cores` config value in configuration::ActiveConfig. fn migrate_to_coretime< T: Config, SendXcm: xcm::v4::SendXcm, @@ -176,8 +176,8 @@ mod v_coretime { } let config = >::config(); - // coretime_cores was on_demand_cores until now: - for on_demand in 0..config.coretime_cores { + // num_cores was on_demand_cores until now: + for on_demand in 0..config.scheduler_params.num_cores { let core = CoreIndex(legacy_count.saturating_add(on_demand as _)); let r = assigner_coretime::Pallet::::assign_core( core, @@ -189,9 +189,9 @@ mod v_coretime { log::error!("Creating assignment for existing on-demand core, failed: {:?}", err); } } - let total_cores = config.coretime_cores + legacy_count; + let total_cores = config.scheduler_params.num_cores + legacy_count; configuration::ActiveConfig::::mutate(|c| { - c.coretime_cores = total_cores; + c.scheduler_params.num_cores = total_cores; }); if let Err(err) = migrate_send_assignments_to_coretime_chain::() { @@ -200,7 +200,9 @@ mod v_coretime { let single_weight = ::WeightInfo::assign_core(1); single_weight - .saturating_mul(u64::from(legacy_count.saturating_add(config.coretime_cores))) + .saturating_mul(u64::from( + legacy_count.saturating_add(config.scheduler_params.num_cores), + )) // Second read from sending assignments to the coretime chain. .saturating_add(T::DbWeight::get().reads_writes(2, 1)) } @@ -244,7 +246,8 @@ mod v_coretime { Some(mk_coretime_call(crate::coretime::CoretimeCalls::SetLease(p.into(), time_slice))) }); - let core_count: u16 = configuration::Pallet::::config().coretime_cores.saturated_into(); + let core_count: u16 = + configuration::Pallet::::config().scheduler_params.num_cores.saturated_into(); let set_core_count = iter::once(mk_coretime_call( crate::coretime::CoretimeCalls::NotifyCoreCount(core_count), )); diff --git a/polkadot/runtime/parachains/src/coretime/mod.rs b/polkadot/runtime/parachains/src/coretime/mod.rs index 531f5c2e4e4..eb9646d7e86 100644 --- a/polkadot/runtime/parachains/src/coretime/mod.rs +++ b/polkadot/runtime/parachains/src/coretime/mod.rs @@ -214,8 +214,8 @@ impl Pallet { } pub fn initializer_on_new_session(notification: &SessionChangeNotification>) { - let old_core_count = notification.prev_config.coretime_cores; - let new_core_count = notification.new_config.coretime_cores; + let old_core_count = notification.prev_config.scheduler_params.num_cores; + let new_core_count = notification.new_config.scheduler_params.num_cores; if new_core_count != old_core_count { let core_count: u16 = new_core_count.saturated_into(); let message = Xcm(vec![ diff --git a/polkadot/runtime/parachains/src/inclusion/tests.rs b/polkadot/runtime/parachains/src/inclusion/tests.rs index d2b5a67c3e4..3fe7d7f0c7d 100644 --- a/polkadot/runtime/parachains/src/inclusion/tests.rs +++ b/polkadot/runtime/parachains/src/inclusion/tests.rs @@ -47,10 +47,10 @@ use test_helpers::{dummy_collator, dummy_collator_signature, dummy_validation_co fn default_config() -> HostConfiguration { let mut config = HostConfiguration::default(); - config.coretime_cores = 1; + config.scheduler_params.num_cores = 1; config.max_code_size = 0b100000; config.max_head_data_size = 0b100000; - config.group_rotation_frequency = u32::MAX; + config.scheduler_params.group_rotation_frequency = u32::MAX; config } @@ -224,7 +224,7 @@ pub(crate) fn run_to_block( } pub(crate) fn expected_bits() -> usize { - Paras::parachains().len() + Configuration::config().coretime_cores as usize + Paras::parachains().len() + Configuration::config().scheduler_params.num_cores as usize } fn default_bitfield() -> AvailabilityBitfield { @@ -386,7 +386,7 @@ fn collect_pending_cleans_up_pending() { (thread_a, ParaKind::Parathread), ]; let mut config = genesis_config(paras); - config.configuration.config.group_rotation_frequency = 3; + config.configuration.config.scheduler_params.group_rotation_frequency = 3; new_test_ext(config).execute_with(|| { let default_candidate = TestCandidateBuilder::default().build(); >::insert( @@ -2062,7 +2062,7 @@ fn check_allowed_relay_parents() { } let validator_public = validator_pubkeys(&validators); let mut config = genesis_config(paras); - config.configuration.config.group_rotation_frequency = 1; + config.configuration.config.scheduler_params.group_rotation_frequency = 1; new_test_ext(config).execute_with(|| { shared::Pallet::::set_active_validators_ascending(validator_public.clone()); diff --git a/polkadot/runtime/parachains/src/mock.rs b/polkadot/runtime/parachains/src/mock.rs index 1925ca19501..e18be03bdeb 100644 --- a/polkadot/runtime/parachains/src/mock.rs +++ b/polkadot/runtime/parachains/src/mock.rs @@ -23,7 +23,7 @@ use crate::{ initializer, origin, paras, paras::ParaKind, paras_inherent, scheduler, - scheduler::common::{AssignmentProvider, AssignmentProviderConfig}, + scheduler::common::AssignmentProvider, session_info, shared, ParaId, }; use frame_support::pallet_prelude::*; @@ -463,10 +463,6 @@ pub mod mock_assigner { pub(super) type MockAssignmentQueue = StorageValue<_, VecDeque, ValueQuery>; - #[pallet::storage] - pub(super) type MockProviderConfig = - StorageValue<_, AssignmentProviderConfig, OptionQuery>; - #[pallet::storage] pub(super) type MockCoreCount = StorageValue<_, u32, OptionQuery>; } @@ -478,12 +474,6 @@ pub mod mock_assigner { MockAssignmentQueue::::mutate(|queue| queue.push_back(assignment)); } - // This configuration needs to be customized to service `get_provider_config` in - // scheduler tests. - pub fn set_assignment_provider_config(config: AssignmentProviderConfig) { - MockProviderConfig::::set(Some(config)); - } - // Allows for customized core count in scheduler tests, rather than a core count // derived from on-demand config + parachain count. pub fn set_core_count(count: u32) { @@ -512,17 +502,6 @@ pub mod mock_assigner { // in the mock assigner. fn push_back_assignment(_assignment: Assignment) {} - // Gets the provider config we set earlier using `set_assignment_provider_config`, falling - // back to the on demand parachain configuration if none was set. - fn get_provider_config(_core_idx: CoreIndex) -> AssignmentProviderConfig { - match MockProviderConfig::::get() { - Some(config) => config, - None => AssignmentProviderConfig { - max_availability_timeouts: 1, - ttl: BlockNumber::from(5u32), - }, - } - } #[cfg(any(feature = "runtime-benchmarks", test))] fn get_mock_assignment(_: CoreIndex, para_id: ParaId) -> Assignment { Assignment::Bulk(para_id) diff --git a/polkadot/runtime/parachains/src/paras/tests.rs b/polkadot/runtime/parachains/src/paras/tests.rs index 24ea919ec87..262ec9d3fdb 100644 --- a/polkadot/runtime/parachains/src/paras/tests.rs +++ b/polkadot/runtime/parachains/src/paras/tests.rs @@ -17,7 +17,7 @@ use super::*; use frame_support::{assert_err, assert_ok, assert_storage_noop}; use keyring::Sr25519Keyring; -use primitives::{BlockNumber, PARACHAIN_KEY_TYPE_ID}; +use primitives::{vstaging::SchedulerParams, BlockNumber, PARACHAIN_KEY_TYPE_ID}; use sc_keystore::LocalKeystore; use sp_keystore::{Keystore, KeystorePtr}; use std::sync::Arc; @@ -909,7 +909,10 @@ fn full_parachain_cleanup_storage() { minimum_validation_upgrade_delay: 2, // Those are not relevant to this test. However, HostConfiguration is still a // subject for the consistency check. - paras_availability_period: 1, + scheduler_params: SchedulerParams { + paras_availability_period: 1, + ..Default::default() + }, ..Default::default() }, }, diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index defb2f4404f..b7285ec884a 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -27,13 +27,14 @@ mod enter { builder::{Bench, BenchBuilder}, mock::{mock_assigner, new_test_ext, BlockLength, BlockWeights, MockGenesisConfig, Test}, scheduler::{ - common::{Assignment, AssignmentProvider, AssignmentProviderConfig}, + common::{Assignment, AssignmentProvider}, ParasEntry, }, }; use assert_matches::assert_matches; use frame_support::assert_ok; use frame_system::limits; + use primitives::vstaging::SchedulerParams; use sp_runtime::Perbill; use sp_std::collections::btree_map::BTreeMap; @@ -87,7 +88,7 @@ mod enter { // `create_inherent` and will not cause `enter` to early. fn include_backed_candidates() { let config = MockGenesisConfig::default(); - assert!(config.configuration.config.scheduling_lookahead > 0); + assert!(config.configuration.config.scheduler_params.lookahead > 0); new_test_ext(config).execute_with(|| { let dispute_statements = BTreeMap::new(); @@ -625,7 +626,7 @@ mod enter { #[test] fn limit_candidates_over_weight_1() { let config = MockGenesisConfig::default(); - assert!(config.configuration.config.scheduling_lookahead > 0); + assert!(config.configuration.config.scheduler_params.lookahead > 0); new_test_ext(config).execute_with(|| { // Create the inherent data for this block @@ -706,8 +707,8 @@ mod enter { let cores = (0..used_cores) .into_iter() .map(|i| { - let AssignmentProviderConfig { ttl, .. } = - scheduler::Pallet::::assignment_provider_config(CoreIndex(i)); + let SchedulerParams { ttl, .. } = + >::config().scheduler_params; // Load an assignment into provider so that one is present to pop let assignment = ::AssignmentProvider::get_mock_assignment( diff --git a/polkadot/runtime/parachains/src/scheduler.rs b/polkadot/runtime/parachains/src/scheduler.rs index 3dbb050fb4e..61ab36dbe96 100644 --- a/polkadot/runtime/parachains/src/scheduler.rs +++ b/polkadot/runtime/parachains/src/scheduler.rs @@ -51,7 +51,7 @@ use sp_std::{ pub mod common; -use common::{Assignment, AssignmentProvider, AssignmentProviderConfig}; +use common::{Assignment, AssignmentProvider}; pub use pallet::*; @@ -222,7 +222,7 @@ impl Pallet { let n_cores = core::cmp::max( T::AssignmentProvider::session_core_count(), - match config.max_validators_per_core { + match config.scheduler_params.max_validators_per_core { Some(x) if x != 0 => validators.len() as u32 / x, _ => 0, }, @@ -350,6 +350,7 @@ impl Pallet { fn drop_expired_claims_from_claimqueue() { let now = >::block_number(); let availability_cores = AvailabilityCores::::get(); + let ttl = >::config().scheduler_params.ttl; ClaimQueue::::mutate(|cq| { for (idx, _) in (0u32..).zip(availability_cores) { @@ -382,8 +383,6 @@ impl Pallet { if let Some(assignment) = T::AssignmentProvider::pop_assignment_for_core(core_idx) { - let AssignmentProviderConfig { ttl, .. } = - T::AssignmentProvider::get_provider_config(core_idx); core_claimqueue.push_back(ParasEntry::new(assignment, now + ttl)); } } @@ -428,7 +427,7 @@ impl Pallet { } let rotations_since_session_start: BlockNumberFor = - (at - session_start_block) / config.group_rotation_frequency; + (at - session_start_block) / config.scheduler_params.group_rotation_frequency; let rotations_since_session_start = as TryInto>::try_into(rotations_since_session_start) @@ -460,9 +459,9 @@ impl Pallet { // Note: blocks backed in this rotation will never time out here as backed_in + // config.paras_availability_period will always be > now for these blocks, as // otherwise above condition would not be true. - pending_since + config.paras_availability_period + pending_since + config.scheduler_params.paras_availability_period } else { - next_rotation + config.paras_availability_period + next_rotation + config.scheduler_params.paras_availability_period }; AvailabilityTimeoutStatus { timed_out: time_out_at <= now, live_until: time_out_at } @@ -478,7 +477,8 @@ impl Pallet { let now = >::block_number() + One::one(); let rotation_info = Self::group_rotation_info(now); - let current_window = rotation_info.last_rotation_at() + config.paras_availability_period; + let current_window = + rotation_info.last_rotation_at() + config.scheduler_params.paras_availability_period; now < current_window } @@ -488,7 +488,7 @@ impl Pallet { ) -> GroupRotationInfo> { let session_start_block = Self::session_start_block(); let group_rotation_frequency = - >::config().group_rotation_frequency; + >::config().scheduler_params.group_rotation_frequency; GroupRotationInfo { session_start_block, now, group_rotation_frequency } } @@ -508,6 +508,8 @@ impl Pallet { /// Return the next thing that will be scheduled on this core assuming it is currently /// occupied and the candidate occupying it times out. pub(crate) fn next_up_on_time_out(core: CoreIndex) -> Option { + let max_availability_timeouts = + >::config().scheduler_params.max_availability_timeouts; Self::next_up_on_available(core).or_else(|| { // Or, if none, the claim currently occupying the core, // as it would be put back on the queue after timing out if number of retries is not at @@ -515,16 +517,12 @@ impl Pallet { let cores = AvailabilityCores::::get(); cores.get(core.0 as usize).and_then(|c| match c { CoreOccupied::Free => None, - CoreOccupied::Paras(pe) => { - let AssignmentProviderConfig { max_availability_timeouts, .. } = - T::AssignmentProvider::get_provider_config(core); - + CoreOccupied::Paras(pe) => if pe.availability_timeouts < max_availability_timeouts { Some(Self::paras_entry_to_scheduled_core(pe)) } else { None - } - }, + }, }) }) } @@ -566,7 +564,7 @@ impl Pallet { // ClaimQueue related functions // fn claimqueue_lookahead() -> u32 { - >::config().scheduling_lookahead + >::config().scheduler_params.lookahead } /// Frees cores and fills the free claimqueue spots by popping from the `AssignmentProvider`. @@ -585,15 +583,15 @@ impl Pallet { let n_lookahead = Self::claimqueue_lookahead().max(1); let n_session_cores = T::AssignmentProvider::session_core_count(); let cq = ClaimQueue::::get(); - let ttl = >::config().on_demand_ttl; + let config = >::config(); + let max_availability_timeouts = config.scheduler_params.max_availability_timeouts; + let ttl = config.scheduler_params.ttl; for core_idx in 0..n_session_cores { let core_idx = CoreIndex::from(core_idx); // add previously timedout paras back into the queue if let Some(mut entry) = timedout_paras.remove(&core_idx) { - let AssignmentProviderConfig { max_availability_timeouts, .. } = - T::AssignmentProvider::get_provider_config(core_idx); if entry.availability_timeouts < max_availability_timeouts { // Increment the timeout counter. entry.availability_timeouts += 1; @@ -668,13 +666,6 @@ impl Pallet { .filter_map(|(core_idx, v)| v.front().map(|e| (core_idx, e.assignment.para_id()))) } - #[cfg(any(feature = "runtime-benchmarks", test))] - pub(crate) fn assignment_provider_config( - core_idx: CoreIndex, - ) -> AssignmentProviderConfig> { - T::AssignmentProvider::get_provider_config(core_idx) - } - #[cfg(any(feature = "try-runtime", test))] fn claimqueue_len() -> usize { ClaimQueue::::get().iter().map(|la_vec| la_vec.1.len()).sum() diff --git a/polkadot/runtime/parachains/src/scheduler/common.rs b/polkadot/runtime/parachains/src/scheduler/common.rs index 2eb73385803..66a4e6d30be 100644 --- a/polkadot/runtime/parachains/src/scheduler/common.rs +++ b/polkadot/runtime/parachains/src/scheduler/common.rs @@ -48,22 +48,10 @@ impl Assignment { } } -#[derive(Encode, Decode, TypeInfo)] -/// A set of variables required by the scheduler in order to operate. -pub struct AssignmentProviderConfig { - /// How many times a collation can time out on availability. - /// Zero timeouts still means that a collation can be provided as per the slot auction - /// assignment provider. - pub max_availability_timeouts: u32, - - /// How long the collator has to provide a collation to the backing group before being dropped. - pub ttl: BlockNumber, -} - pub trait AssignmentProvider { /// Pops an [`Assignment`] from the provider for a specified [`CoreIndex`]. /// - /// This is where assignments come into existance. + /// This is where assignments come into existence. fn pop_assignment_for_core(core_idx: CoreIndex) -> Option; /// A previously popped `Assignment` has been fully processed. @@ -77,14 +65,11 @@ pub trait AssignmentProvider { /// Push back a previously popped assignment. /// /// If the assignment could not be processed within the current session, it can be pushed back - /// to the assignment provider in order to be poppped again later. + /// to the assignment provider in order to be popped again later. /// /// This is the second way the life of an assignment can come to an end. fn push_back_assignment(assignment: Assignment); - /// Returns a set of variables needed by the scheduler - fn get_provider_config(core_idx: CoreIndex) -> AssignmentProviderConfig; - /// Push some assignment for mocking/benchmarks purposes. /// /// Useful for benchmarks and testing. The returned assignment is "valid" and can if need be diff --git a/polkadot/runtime/parachains/src/scheduler/tests.rs b/polkadot/runtime/parachains/src/scheduler/tests.rs index 9af23ce64bd..28b3a6b4f5d 100644 --- a/polkadot/runtime/parachains/src/scheduler/tests.rs +++ b/polkadot/runtime/parachains/src/scheduler/tests.rs @@ -18,7 +18,9 @@ use super::*; use frame_support::assert_ok; use keyring::Sr25519Keyring; -use primitives::{BlockNumber, SessionIndex, ValidationCode, ValidatorId}; +use primitives::{ + vstaging::SchedulerParams, BlockNumber, SessionIndex, ValidationCode, ValidatorId, +}; use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet}; use crate::{ @@ -103,15 +105,19 @@ fn run_to_end_of_block( fn default_config() -> HostConfiguration { HostConfiguration { - coretime_cores: 3, - group_rotation_frequency: 10, - paras_availability_period: 3, - scheduling_lookahead: 2, // This field does not affect anything that scheduler does. However, `HostConfiguration` // is still a subject to consistency test. It requires that // `minimum_validation_upgrade_delay` is greater than `chain_availability_period` and // `thread_availability_period`. minimum_validation_upgrade_delay: 6, + scheduler_params: SchedulerParams { + group_rotation_frequency: 10, + paras_availability_period: 3, + lookahead: 2, + num_cores: 3, + max_availability_timeouts: 1, + ..Default::default() + }, ..Default::default() } } @@ -155,7 +161,7 @@ fn scheduled_entries() -> impl Iterator(vec![para_a])); } else { assert!(!claimqueue_contains_para_ids::(vec![para_a])); @@ -822,7 +825,7 @@ fn on_demand_claims_are_pruned_after_timing_out() { assert!(!availability_cores_contains_para_ids::(vec![para_a])); // #25 - now += max_retries + 2; + now += max_timeouts + 2; // Add assignment back to the mix. MockAssigner::add_test_assignment(assignment_a.clone()); @@ -833,7 +836,7 @@ fn on_demand_claims_are_pruned_after_timing_out() { // #26 now += 1; // Run to block #n but this time have group 1 conclude the availabilty. - for n in now..=(now + max_retries + 1) { + for n in now..=(now + max_timeouts + 1) { // #n run_to_block(n, |_| None); // Time out core 0 if group 0 is assigned to it, if group 1 is assigned, conclude. @@ -874,10 +877,8 @@ fn on_demand_claims_are_pruned_after_timing_out() { fn availability_predicate_works() { let genesis_config = genesis_config(&default_config()); - let HostConfiguration { group_rotation_frequency, paras_availability_period, .. } = - default_config(); - - assert!(paras_availability_period < group_rotation_frequency); + let SchedulerParams { group_rotation_frequency, paras_availability_period, .. } = + default_config().scheduler_params; new_test_ext(genesis_config).execute_with(|| { run_to_block(1 + paras_availability_period, |_| None); @@ -1044,7 +1045,7 @@ fn next_up_on_time_out_reuses_claim_if_nothing_queued() { #[test] fn session_change_requires_reschedule_dropping_removed_paras() { let mut config = default_config(); - config.scheduling_lookahead = 1; + config.scheduler_params.lookahead = 1; let genesis_config = genesis_config(&config); let para_a = ParaId::from(1_u32); @@ -1056,7 +1057,7 @@ fn session_change_requires_reschedule_dropping_removed_paras() { new_test_ext(genesis_config).execute_with(|| { // Setting explicit core count MockAssigner::set_core_count(5); - let assignment_provider_ttl = MockAssigner::get_provider_config(CoreIndex::from(0)).ttl; + let coretime_ttl = >::config().scheduler_params.ttl; schedule_blank_para(para_a); schedule_blank_para(para_b); @@ -1120,7 +1121,7 @@ fn session_change_requires_reschedule_dropping_removed_paras() { vec![ParasEntry::new( Assignment::Bulk(para_a), // At end of block 2 - assignment_provider_ttl + 2 + coretime_ttl + 2 )] .into_iter() .collect() @@ -1169,7 +1170,7 @@ fn session_change_requires_reschedule_dropping_removed_paras() { vec![ParasEntry::new( Assignment::Bulk(para_a), // At block 3 - assignment_provider_ttl + 3 + coretime_ttl + 3 )] .into_iter() .collect() @@ -1179,7 +1180,7 @@ fn session_change_requires_reschedule_dropping_removed_paras() { vec![ParasEntry::new( Assignment::Bulk(para_b), // At block 3 - assignment_provider_ttl + 3 + coretime_ttl + 3 )] .into_iter() .collect() diff --git a/polkadot/runtime/parachains/src/session_info/tests.rs b/polkadot/runtime/parachains/src/session_info/tests.rs index 92a50575ded..a5bfeae0745 100644 --- a/polkadot/runtime/parachains/src/session_info/tests.rs +++ b/polkadot/runtime/parachains/src/session_info/tests.rs @@ -25,7 +25,7 @@ use crate::{ util::take_active_subset, }; use keyring::Sr25519Keyring; -use primitives::{BlockNumber, ValidatorId, ValidatorIndex}; +use primitives::{vstaging::SchedulerParams, BlockNumber, ValidatorId, ValidatorIndex}; fn run_to_block( to: BlockNumber, @@ -62,9 +62,9 @@ fn run_to_block( fn default_config() -> HostConfiguration { HostConfiguration { - coretime_cores: 1, dispute_period: 2, needed_approvals: 3, + scheduler_params: SchedulerParams { num_cores: 1, ..Default::default() }, ..Default::default() } } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 173301e1ad9..f3c0c3d6bd8 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -1658,6 +1658,7 @@ pub mod migrations { parachains_configuration::migration::v11::MigrateToV11, // This needs to come after the `parachains_configuration` above as we are reading the configuration. coretime::migration::MigrateToCoretime, + parachains_configuration::migration::v12::MigrateToV12, // permanent pallet_xcm::migration::MigrateToLatestXcmVersion, diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs index 34541b83597..ca0575cb1b6 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `runtime_parachains::configuration` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-11-10, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: @@ -58,8 +58,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_793_000 picoseconds. - Weight::from_parts(8_192_000, 0) + // Minimum execution time: 7_789_000 picoseconds. + Weight::from_parts(8_269_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -74,8 +74,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_819_000 picoseconds. - Weight::from_parts(8_004_000, 0) + // Minimum execution time: 7_851_000 picoseconds. + Weight::from_parts(8_152_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -90,8 +90,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_760_000 picoseconds. - Weight::from_parts(8_174_000, 0) + // Minimum execution time: 7_960_000 picoseconds. + Weight::from_parts(8_276_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -116,8 +116,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_814_000 picoseconds. - Weight::from_parts(8_098_000, 0) + // Minimum execution time: 7_912_000 picoseconds. + Weight::from_parts(8_164_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -132,8 +132,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 10_028_000 picoseconds. - Weight::from_parts(10_386_000, 0) + // Minimum execution time: 9_782_000 picoseconds. + Weight::from_parts(10_373_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -148,8 +148,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_867_000 picoseconds. - Weight::from_parts(8_191_000, 0) + // Minimum execution time: 7_870_000 picoseconds. + Weight::from_parts(8_274_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -164,8 +164,24 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 10_158_000 picoseconds. - Weight::from_parts(10_430_000, 0) + // Minimum execution time: 9_960_000 picoseconds. + Weight::from_parts(10_514_000, 0) + .saturating_add(Weight::from_parts(0, 1636)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_scheduler_params() -> Weight { + // Proof Size summary in bytes: + // Measured: `151` + // Estimated: `1636` + // Minimum execution time: 7_913_000 picoseconds. + Weight::from_parts(8_338_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 91047d953f5..a7772303a95 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -1699,6 +1699,7 @@ pub mod migrations { // Migrate Identity pallet for Usernames pallet_identity::migration::versioned::V0ToV1, parachains_configuration::migration::v11::MigrateToV11, + parachains_configuration::migration::v12::MigrateToV12, // permanent pallet_xcm::migration::MigrateToLatestXcmVersion, // Migrate from legacy lease to coretime. Needs to run after configuration v11 diff --git a/polkadot/runtime/westend/src/weights/runtime_parachains_configuration.rs b/polkadot/runtime/westend/src/weights/runtime_parachains_configuration.rs index 3a4813b667c..8fa3207c644 100644 --- a/polkadot/runtime/westend/src/weights/runtime_parachains_configuration.rs +++ b/polkadot/runtime/westend/src/weights/runtime_parachains_configuration.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `runtime_parachains::configuration` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-11-10, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024 // Executed Command: @@ -58,8 +58,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 8_065_000 picoseconds. - Weight::from_parts(8_389_000, 0) + // Minimum execution time: 7_775_000 picoseconds. + Weight::from_parts(8_036_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -74,8 +74,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 8_038_000 picoseconds. - Weight::from_parts(8_463_000, 0) + // Minimum execution time: 7_708_000 picoseconds. + Weight::from_parts(7_971_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -90,8 +90,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_843_000 picoseconds. - Weight::from_parts(8_216_000, 0) + // Minimum execution time: 7_746_000 picoseconds. + Weight::from_parts(8_028_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -116,8 +116,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_969_000 picoseconds. - Weight::from_parts(8_362_000, 0) + // Minimum execution time: 7_729_000 picoseconds. + Weight::from_parts(7_954_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -132,8 +132,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 10_084_000 picoseconds. - Weight::from_parts(10_451_000, 0) + // Minimum execution time: 9_871_000 picoseconds. + Weight::from_parts(10_075_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -148,8 +148,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_948_000 picoseconds. - Weight::from_parts(8_268_000, 0) + // Minimum execution time: 7_869_000 picoseconds. + Weight::from_parts(8_000_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -164,8 +164,24 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 10_257_000 picoseconds. - Weight::from_parts(10_584_000, 0) + // Minimum execution time: 9_797_000 picoseconds. + Weight::from_parts(10_373_000, 0) + .saturating_add(Weight::from_parts(0, 1636)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_scheduler_params() -> Weight { + // Proof Size summary in bytes: + // Measured: `151` + // Estimated: `1636` + // Minimum execution time: 7_718_000 picoseconds. + Weight::from_parts(7_984_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/polkadot/zombienet_tests/functional/0002-parachains-disputes.toml b/polkadot/zombienet_tests/functional/0002-parachains-disputes.toml index f6bdfeb4877..2561661de1f 100644 --- a/polkadot/zombienet_tests/functional/0002-parachains-disputes.toml +++ b/polkadot/zombienet_tests/functional/0002-parachains-disputes.toml @@ -2,9 +2,11 @@ timeout = 1000 [relaychain.genesis.runtimeGenesis.patch.configuration.config] - max_validators_per_core = 5 needed_approvals = 8 +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] + max_validators_per_core = 5 + [relaychain.genesis.runtimeGenesis.patch.configuration.config.approval_voting_params] max_approval_coalesce_count = 5 diff --git a/polkadot/zombienet_tests/functional/0004-parachains-garbage-candidate.toml b/polkadot/zombienet_tests/functional/0004-parachains-garbage-candidate.toml index 5d6f299d461..a2a2621f842 100644 --- a/polkadot/zombienet_tests/functional/0004-parachains-garbage-candidate.toml +++ b/polkadot/zombienet_tests/functional/0004-parachains-garbage-candidate.toml @@ -2,8 +2,10 @@ timeout = 1000 bootnode = true -[relaychain.genesis.runtimeGenesis.patch.configuration.config] +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] max_validators_per_core = 1 + +[relaychain.genesis.runtimeGenesis.patch.configuration.config] needed_approvals = 2 [relaychain] diff --git a/polkadot/zombienet_tests/functional/0005-parachains-disputes-past-session.toml b/polkadot/zombienet_tests/functional/0005-parachains-disputes-past-session.toml index e2fbec079b1..a3bbc82e74b 100644 --- a/polkadot/zombienet_tests/functional/0005-parachains-disputes-past-session.toml +++ b/polkadot/zombienet_tests/functional/0005-parachains-disputes-past-session.toml @@ -3,8 +3,10 @@ timeout = 1000 bootnode = true [relaychain.genesis.runtimeGenesis.patch.configuration.config] - max_validators_per_core = 1 needed_approvals = 2 + +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] + max_validators_per_core = 1 group_rotation_frequency = 2 [relaychain] diff --git a/polkadot/zombienet_tests/functional/0006-parachains-max-tranche0.toml b/polkadot/zombienet_tests/functional/0006-parachains-max-tranche0.toml index bef54cb8ca4..858f87b9cfe 100644 --- a/polkadot/zombienet_tests/functional/0006-parachains-max-tranche0.toml +++ b/polkadot/zombienet_tests/functional/0006-parachains-max-tranche0.toml @@ -3,10 +3,12 @@ timeout = 1000 bootnode = true [relaychain.genesis.runtimeGenesis.patch.configuration.config] - max_validators_per_core = 1 needed_approvals = 7 relay_vrf_modulo_samples = 5 +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] + max_validators_per_core = 1 + [relaychain] default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" chain = "rococo-local" diff --git a/polkadot/zombienet_tests/functional/0007-dispute-freshly-finalized.toml b/polkadot/zombienet_tests/functional/0007-dispute-freshly-finalized.toml index 69eb0804d8c..573ccf96138 100644 --- a/polkadot/zombienet_tests/functional/0007-dispute-freshly-finalized.toml +++ b/polkadot/zombienet_tests/functional/0007-dispute-freshly-finalized.toml @@ -2,9 +2,11 @@ timeout = 1000 [relaychain.genesis.runtimeGenesis.patch.configuration.config] - max_validators_per_core = 1 needed_approvals = 1 +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] + max_validators_per_core = 1 + [relaychain] default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" chain = "rococo-local" diff --git a/polkadot/zombienet_tests/functional/0008-dispute-old-finalized.toml b/polkadot/zombienet_tests/functional/0008-dispute-old-finalized.toml index 1ea385c3a42..ea1c93a1403 100644 --- a/polkadot/zombienet_tests/functional/0008-dispute-old-finalized.toml +++ b/polkadot/zombienet_tests/functional/0008-dispute-old-finalized.toml @@ -2,9 +2,11 @@ timeout = 1000 [relaychain.genesis.runtimeGenesis.patch.configuration.config] - max_validators_per_core = 1 needed_approvals = 1 +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] + max_validators_per_core = 1 + [relaychain] default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" chain = "rococo-local" diff --git a/polkadot/zombienet_tests/functional/0010-validator-disabling.toml b/polkadot/zombienet_tests/functional/0010-validator-disabling.toml index 6701d60d74d..c9d79c5f8f2 100644 --- a/polkadot/zombienet_tests/functional/0010-validator-disabling.toml +++ b/polkadot/zombienet_tests/functional/0010-validator-disabling.toml @@ -3,8 +3,10 @@ timeout = 1000 bootnode = true [relaychain.genesis.runtimeGenesis.patch.configuration.config] - max_validators_per_core = 1 needed_approvals = 2 + +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] + max_validators_per_core = 1 group_rotation_frequency = 10 [relaychain] diff --git a/polkadot/zombienet_tests/functional/0011-async-backing-6-seconds-rate.toml b/polkadot/zombienet_tests/functional/0011-async-backing-6-seconds-rate.toml index 5a6832b149b..b776622fdce 100644 --- a/polkadot/zombienet_tests/functional/0011-async-backing-6-seconds-rate.toml +++ b/polkadot/zombienet_tests/functional/0011-async-backing-6-seconds-rate.toml @@ -8,13 +8,16 @@ chain = "rococo-local" [relaychain.genesis.runtimeGenesis.patch.configuration.config] needed_approvals = 4 relay_vrf_modulo_samples = 6 - scheduling_lookahead = 2 - group_rotation_frequency = 4 [relaychain.genesis.runtimeGenesis.patch.configuration.config.async_backing_params] max_candidate_depth = 3 allowed_ancestry_len = 2 +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] + lookahead = 2 + group_rotation_frequency = 4 + + [relaychain.default_resources] limits = { memory = "4G", cpu = "2" } requests = { memory = "2G", cpu = "1" } diff --git a/polkadot/zombienet_tests/functional/0012-elastic-scaling-mvp.toml b/polkadot/zombienet_tests/functional/0012-elastic-scaling-mvp.toml index 0dfd814e10a..9b3576eaa3c 100644 --- a/polkadot/zombienet_tests/functional/0012-elastic-scaling-mvp.toml +++ b/polkadot/zombienet_tests/functional/0012-elastic-scaling-mvp.toml @@ -3,9 +3,11 @@ timeout = 1000 bootnode = true [relaychain.genesis.runtimeGenesis.patch.configuration.config] - max_validators_per_core = 2 needed_approvals = 4 - coretime_cores = 2 + +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] + max_validators_per_core = 2 + num_cores = 2 [relaychain] default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" diff --git a/polkadot/zombienet_tests/misc/0001-paritydb.toml b/polkadot/zombienet_tests/misc/0001-paritydb.toml index 399f848d3ac..b3ce2081b11 100644 --- a/polkadot/zombienet_tests/misc/0001-paritydb.toml +++ b/polkadot/zombienet_tests/misc/0001-paritydb.toml @@ -3,9 +3,11 @@ timeout = 1000 bootnode = true [relaychain.genesis.runtimeGenesis.patch.configuration.config] - max_validators_per_core = 1 needed_approvals = 3 +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] + max_validators_per_core = 1 + [relaychain] default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" chain = "rococo-local" -- GitLab From 761937ecdc8f208361ae2a1154e0f1e6ecf57429 Mon Sep 17 00:00:00 2001 From: Alexandru Gheorghe <49718502+alexggh@users.noreply.github.com> Date: Thu, 29 Feb 2024 10:21:00 +0200 Subject: [PATCH 327/392] Fix accidental no-shows on node restart (#3277) If approval was in progress we didn't actually restart it, so we end up in a situation where we distribute our assignment, but we don't distribute any approval. --------- Signed-off-by: Alexandru Gheorghe --- polkadot/node/core/approval-voting/src/lib.rs | 85 +- .../approval-voting/src/persisted_entries.rs | 7 + .../node/core/approval-voting/src/tests.rs | 744 +++++++++++++++++- 3 files changed, 780 insertions(+), 56 deletions(-) diff --git a/polkadot/node/core/approval-voting/src/lib.rs b/polkadot/node/core/approval-voting/src/lib.rs index 456ae319787..8cc16a6e1ec 100644 --- a/polkadot/node/core/approval-voting/src/lib.rs +++ b/polkadot/node/core/approval-voting/src/lib.rs @@ -1253,13 +1253,20 @@ async fn handle_actions( Action::BecomeActive => { *mode = Mode::Active; - let messages = distribution_messages_for_activation( + let (messages, next_actions) = distribution_messages_for_activation( + ctx, overlayed_db, state, delayed_approvals_timers, - )?; + session_info_provider, + ) + .await?; ctx.send_messages(messages.into_iter()).await; + let next_actions: Vec = + next_actions.into_iter().map(|v| v.clone()).chain(actions_iter).collect(); + + actions_iter = next_actions.into_iter(); }, Action::Conclude => { conclude = true; @@ -1313,15 +1320,19 @@ fn get_assignment_core_indices( } } -fn distribution_messages_for_activation( +#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)] +async fn distribution_messages_for_activation( + ctx: &mut Context, db: &OverlayedBackend<'_, impl Backend>, state: &State, delayed_approvals_timers: &mut DelayedApprovalTimer, -) -> SubsystemResult> { + session_info_provider: &mut RuntimeInfo, +) -> SubsystemResult<(Vec, Vec)> { let all_blocks: Vec = db.load_all_blocks()?; let mut approval_meta = Vec::with_capacity(all_blocks.len()); let mut messages = Vec::new(); + let mut actions = Vec::new(); messages.push(ApprovalDistributionMessage::NewBlocks(Vec::new())); // dummy value. @@ -1396,16 +1407,60 @@ fn distribution_messages_for_activation( &claimed_core_indices, &block_entry, ) { - Ok(bitfield) => messages.push( - ApprovalDistributionMessage::DistributeAssignment( - IndirectAssignmentCertV2 { - block_hash, - validator: assignment.validator_index(), - cert: assignment.cert().clone(), - }, - bitfield, - ), - ), + Ok(bitfield) => { + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?candidate_entry.candidate_receipt().hash(), + ?block_hash, + "Discovered, triggered assignment, not approved yet", + ); + + let indirect_cert = IndirectAssignmentCertV2 { + block_hash, + validator: assignment.validator_index(), + cert: assignment.cert().clone(), + }; + messages.push( + ApprovalDistributionMessage::DistributeAssignment( + indirect_cert.clone(), + bitfield.clone(), + ), + ); + + if !block_entry + .candidate_is_pending_signature(*candidate_hash) + { + let ExtendedSessionInfo { ref executor_params, .. } = + match get_extended_session_info( + session_info_provider, + ctx.sender(), + block_entry.block_hash(), + block_entry.session(), + ) + .await + { + Some(i) => i, + None => continue, + }; + + actions.push(Action::LaunchApproval { + claimed_candidate_indices: bitfield, + candidate_hash: candidate_entry + .candidate_receipt() + .hash(), + indirect_cert, + assignment_tranche: assignment.tranche(), + relay_block_hash: block_hash, + session: block_entry.session(), + executor_params: executor_params.clone(), + candidate: candidate_entry + .candidate_receipt() + .clone(), + backing_group: approval_entry.backing_group(), + distribute_assignment: false, + }); + } + }, Err(err) => { // Should never happen. If we fail here it means the // assignment is null (no cores claimed). @@ -1496,7 +1551,7 @@ fn distribution_messages_for_activation( } messages[0] = ApprovalDistributionMessage::NewBlocks(approval_meta); - Ok(messages) + Ok((messages, actions)) } // Handle an incoming signal from the overseer. Returns true if execution should conclude. diff --git a/polkadot/node/core/approval-voting/src/persisted_entries.rs b/polkadot/node/core/approval-voting/src/persisted_entries.rs index ef47bdb2213..b924a1b52cc 100644 --- a/polkadot/node/core/approval-voting/src/persisted_entries.rs +++ b/polkadot/node/core/approval-voting/src/persisted_entries.rs @@ -588,6 +588,13 @@ impl BlockEntry { !self.candidates_pending_signature.is_empty() } + /// Returns true if candidate hash is in the queue for a signature. + pub fn candidate_is_pending_signature(&self, candidate_hash: CandidateHash) -> bool { + self.candidates_pending_signature + .values() + .any(|context| context.candidate_hash == candidate_hash) + } + /// Candidate hashes for candidates pending signatures fn candidate_hashes_pending_signature(&self) -> Vec { self.candidates_pending_signature diff --git a/polkadot/node/core/approval-voting/src/tests.rs b/polkadot/node/core/approval-voting/src/tests.rs index 9220e84a255..c9053232a4c 100644 --- a/polkadot/node/core/approval-voting/src/tests.rs +++ b/polkadot/node/core/approval-voting/src/tests.rs @@ -78,6 +78,7 @@ struct TestSyncOracle { struct TestSyncOracleHandle { done_syncing_receiver: oneshot::Receiver<()>, + is_major_syncing: Arc, } impl TestSyncOracleHandle { @@ -108,8 +109,9 @@ impl SyncOracle for TestSyncOracle { fn make_sync_oracle(val: bool) -> (Box, TestSyncOracleHandle) { let (tx, rx) = oneshot::channel(); let flag = Arc::new(AtomicBool::new(val)); - let oracle = TestSyncOracle { flag, done_syncing_sender: Arc::new(Mutex::new(Some(tx))) }; - let handle = TestSyncOracleHandle { done_syncing_receiver: rx }; + let oracle = + TestSyncOracle { flag: flag.clone(), done_syncing_sender: Arc::new(Mutex::new(Some(tx))) }; + let handle = TestSyncOracleHandle { done_syncing_receiver: rx, is_major_syncing: flag }; (Box::new(oracle), handle) } @@ -465,6 +467,7 @@ struct HarnessConfigBuilder { clock: Option, backend: Option, assignment_criteria: Option>, + major_syncing: bool, } impl HarnessConfigBuilder { @@ -476,9 +479,19 @@ impl HarnessConfigBuilder { self } + pub fn major_syncing(&mut self, value: bool) -> &mut Self { + self.major_syncing = value; + self + } + + pub fn backend(&mut self, store: TestStore) -> &mut Self { + self.backend = Some(store); + self + } + pub fn build(&mut self) -> HarnessConfig { let (sync_oracle, sync_oracle_handle) = - self.sync_oracle.take().unwrap_or_else(|| make_sync_oracle(false)); + self.sync_oracle.take().unwrap_or_else(|| make_sync_oracle(self.major_syncing)); let assignment_criteria = self .assignment_criteria @@ -736,11 +749,13 @@ struct BlockConfig { slot: Slot, candidates: Option>, session_info: Option, + end_syncing: bool, } struct ChainBuilder { blocks_by_hash: HashMap, blocks_at_height: BTreeMap>, + is_major_syncing: Arc, } impl ChainBuilder { @@ -748,16 +763,28 @@ impl ChainBuilder { const GENESIS_PARENT_HASH: Hash = Hash::repeat_byte(0x00); pub fn new() -> Self { - let mut builder = - Self { blocks_by_hash: HashMap::new(), blocks_at_height: BTreeMap::new() }; + let mut builder = Self { + blocks_by_hash: HashMap::new(), + blocks_at_height: BTreeMap::new(), + is_major_syncing: Arc::new(AtomicBool::new(false)), + }; builder.add_block_inner( Self::GENESIS_HASH, Self::GENESIS_PARENT_HASH, 0, - BlockConfig { slot: Slot::from(0), candidates: None, session_info: None }, + BlockConfig { + slot: Slot::from(0), + candidates: None, + session_info: None, + end_syncing: false, + }, ); builder } + pub fn major_syncing(&mut self, major_syncing: Arc) -> &mut Self { + self.is_major_syncing = major_syncing; + self + } pub fn add_block( &mut self, @@ -808,8 +835,16 @@ impl ChainBuilder { } ancestry.reverse(); - import_block(overseer, ancestry.as_ref(), *number, block_config, false, i > 0) - .await; + import_block( + overseer, + ancestry.as_ref(), + *number, + block_config, + false, + i > 0, + self.is_major_syncing.clone(), + ) + .await; let _: Option<()> = future::pending().timeout(Duration::from_millis(100)).await; } } @@ -863,6 +898,7 @@ async fn import_block( config: &BlockConfig, gap: bool, fork: bool, + major_syncing: Arc, ) { let (new_head, new_header) = &hashes[hashes.len() - 1]; let candidates = config.candidates.clone().unwrap_or(vec![( @@ -891,6 +927,12 @@ async fn import_block( h_tx.send(Ok(Some(new_header.clone()))).unwrap(); } ); + + let is_major_syncing = major_syncing.load(Ordering::SeqCst); + if config.end_syncing { + major_syncing.store(false, Ordering::SeqCst); + } + if !fork { let mut _ancestry_step = 0; if gap { @@ -931,7 +973,7 @@ async fn import_block( } } - if number > 0 { + if number > 0 && !is_major_syncing { assert_matches!( overseer_recv(overseer).await, AllMessages::RuntimeApi( @@ -944,7 +986,6 @@ async fn import_block( c_tx.send(Ok(inclusion_events)).unwrap(); } ); - assert_matches!( overseer_recv(overseer).await, AllMessages::RuntimeApi( @@ -984,14 +1025,14 @@ async fn import_block( ); } - if number == 0 { + if number == 0 && !is_major_syncing { assert_matches!( overseer_recv(overseer).await, AllMessages::ApprovalDistribution(ApprovalDistributionMessage::NewBlocks(v)) => { assert_eq!(v.len(), 0usize); } ); - } else { + } else if number > 0 && !is_major_syncing { if !fork { // SessionInfo won't be called for forks - it's already cached assert_matches!( @@ -1031,20 +1072,23 @@ async fn import_block( ); } - assert_matches!( - overseer_recv(overseer).await, - AllMessages::ApprovalDistribution( - ApprovalDistributionMessage::NewBlocks(mut approval_vec) - ) => { - assert_eq!(approval_vec.len(), 1); - let metadata = approval_vec.pop().unwrap(); - let hash = &hashes[number as usize]; - let parent_hash = &hashes[(number - 1) as usize]; - assert_eq!(metadata.hash, hash.0.clone()); - assert_eq!(metadata.parent_hash, parent_hash.0.clone()); - assert_eq!(metadata.slot, config.slot); - } - ); + if !is_major_syncing { + assert_matches!( + overseer_recv(overseer).await, + + AllMessages::ApprovalDistribution( + ApprovalDistributionMessage::NewBlocks(mut approval_vec) + ) => { + assert_eq!(approval_vec.len(), 1); + let metadata = approval_vec.pop().unwrap(); + let hash = &hashes[number as usize]; + let parent_hash = &hashes[(number - 1) as usize]; + assert_eq!(metadata.hash, hash.0.clone()); + assert_eq!(metadata.parent_hash, parent_hash.0.clone()); + assert_eq!(metadata.slot, config.slot); + } + ); + } } } @@ -1072,7 +1116,7 @@ fn subsystem_rejects_bad_assignment_ok_criteria() { block_hash, head, 1, - BlockConfig { slot, candidates: None, session_info: None }, + BlockConfig { slot, candidates: None, session_info: None, end_syncing: false }, ); builder.build(&mut virtual_overseer).await; @@ -1135,7 +1179,7 @@ fn subsystem_rejects_bad_assignment_err_criteria() { block_hash, head, 1, - BlockConfig { slot, candidates: None, session_info: None }, + BlockConfig { slot, candidates: None, session_info: None, end_syncing: false }, ); builder.build(&mut virtual_overseer).await; @@ -1240,6 +1284,7 @@ fn subsystem_rejects_approval_if_no_candidate_entry() { slot, candidates: Some(vec![(candidate_descriptor, CoreIndex(1), GroupIndex(1))]), session_info: None, + end_syncing: false, }, ); builder.build(&mut virtual_overseer).await; @@ -1345,7 +1390,12 @@ fn subsystem_rejects_approval_before_assignment() { block_hash, ChainBuilder::GENESIS_HASH, 1, - BlockConfig { slot: Slot::from(1), candidates: None, session_info: None }, + BlockConfig { + slot: Slot::from(1), + candidates: None, + session_info: None, + end_syncing: false, + }, ) .build(&mut virtual_overseer) .await; @@ -1398,7 +1448,12 @@ fn subsystem_rejects_assignment_in_future() { block_hash, ChainBuilder::GENESIS_HASH, 1, - BlockConfig { slot: Slot::from(0), candidates: None, session_info: None }, + BlockConfig { + slot: Slot::from(0), + candidates: None, + session_info: None, + end_syncing: false, + }, ) .build(&mut virtual_overseer) .await; @@ -1472,6 +1527,7 @@ fn subsystem_accepts_duplicate_assignment() { (candidate_receipt2, CoreIndex(1), GroupIndex(1)), ]), session_info: None, + end_syncing: false, }, ) .build(&mut virtual_overseer) @@ -1537,7 +1593,12 @@ fn subsystem_rejects_assignment_with_unknown_candidate() { block_hash, ChainBuilder::GENESIS_HASH, 1, - BlockConfig { slot: Slot::from(1), candidates: None, session_info: None }, + BlockConfig { + slot: Slot::from(1), + candidates: None, + session_info: None, + end_syncing: false, + }, ) .build(&mut virtual_overseer) .await; @@ -1582,7 +1643,12 @@ fn subsystem_rejects_oversized_bitfields() { block_hash, ChainBuilder::GENESIS_HASH, 1, - BlockConfig { slot: Slot::from(1), candidates: None, session_info: None }, + BlockConfig { + slot: Slot::from(1), + candidates: None, + session_info: None, + end_syncing: false, + }, ) .build(&mut virtual_overseer) .await; @@ -1650,7 +1716,12 @@ fn subsystem_accepts_and_imports_approval_after_assignment() { block_hash, ChainBuilder::GENESIS_HASH, 1, - BlockConfig { slot: Slot::from(1), candidates: None, session_info: None }, + BlockConfig { + slot: Slot::from(1), + candidates: None, + session_info: None, + end_syncing: false, + }, ) .build(&mut virtual_overseer) .await; @@ -1741,6 +1812,7 @@ fn subsystem_second_approval_import_only_schedules_wakeups() { slot: Slot::from(0), candidates: None, session_info: Some(session_info), + end_syncing: false, }, ) .build(&mut virtual_overseer) @@ -1824,7 +1896,12 @@ fn subsystem_assignment_import_updates_candidate_entry_and_schedules_wakeup() { block_hash, ChainBuilder::GENESIS_HASH, 1, - BlockConfig { slot: Slot::from(1), candidates: None, session_info: None }, + BlockConfig { + slot: Slot::from(1), + candidates: None, + session_info: None, + end_syncing: false, + }, ) .build(&mut virtual_overseer) .await; @@ -1873,7 +1950,12 @@ fn subsystem_process_wakeup_schedules_wakeup() { block_hash, ChainBuilder::GENESIS_HASH, 1, - BlockConfig { slot: Slot::from(1), candidates: None, session_info: None }, + BlockConfig { + slot: Slot::from(1), + candidates: None, + session_info: None, + end_syncing: false, + }, ) .build(&mut virtual_overseer) .await; @@ -1925,7 +2007,7 @@ fn linear_import_act_on_leaf() { hash, head, i, - BlockConfig { slot, candidates: None, session_info: None }, + BlockConfig { slot, candidates: None, session_info: None, end_syncing: false }, ); head = hash; } @@ -1983,7 +2065,7 @@ fn forkful_import_at_same_height_act_on_leaf() { hash, head, i, - BlockConfig { slot, candidates: None, session_info: None }, + BlockConfig { slot, candidates: None, session_info: None, end_syncing: false }, ); head = hash; } @@ -1997,7 +2079,7 @@ fn forkful_import_at_same_height_act_on_leaf() { hash, head, session, - BlockConfig { slot, candidates: None, session_info: None }, + BlockConfig { slot, candidates: None, session_info: None, end_syncing: false }, ); } builder.build(&mut virtual_overseer).await; @@ -2168,6 +2250,7 @@ fn import_checked_approval_updates_entries_and_schedules() { slot, candidates: Some(vec![(candidate_descriptor, CoreIndex(0), GroupIndex(0))]), session_info: Some(session_info), + end_syncing: false, }, ); builder.build(&mut virtual_overseer).await; @@ -2323,6 +2406,7 @@ fn subsystem_import_checked_approval_sets_one_block_bit_at_a_time() { (candidate_receipt2, CoreIndex(1), GroupIndex(1)), ]), session_info: Some(session_info), + end_syncing: false, }, ) .build(&mut virtual_overseer) @@ -2445,6 +2529,7 @@ fn approved_ancestor_test( slot: Slot::from(i as u64), candidates: Some(vec![(candidate_receipt, CoreIndex(0), GroupIndex(0))]), session_info: None, + end_syncing: false, }, ); } @@ -2623,13 +2708,19 @@ fn subsystem_validate_approvals_cache() { slot, candidates: candidates.clone(), session_info: Some(session_info.clone()), + end_syncing: false, }, ) .add_block( fork_block_hash, ChainBuilder::GENESIS_HASH, 1, - BlockConfig { slot, candidates, session_info: Some(session_info) }, + BlockConfig { + slot, + candidates, + session_info: Some(session_info), + end_syncing: false, + }, ) .build(&mut virtual_overseer) .await; @@ -2740,6 +2831,7 @@ fn subsystem_doesnt_distribute_duplicate_compact_assignments() { (candidate_receipt2.clone(), CoreIndex(1), GroupIndex(1)), ]), session_info: None, + end_syncing: false, }, ) .build(&mut virtual_overseer) @@ -2997,6 +3089,7 @@ where slot, candidates: Some(vec![(candidate_receipt, CoreIndex(0), GroupIndex(2))]), session_info: Some(session_info), + end_syncing: false, }, ) .build(&mut virtual_overseer) @@ -3314,6 +3407,7 @@ fn pre_covers_dont_stall_approval() { slot, candidates: Some(vec![(candidate_descriptor, CoreIndex(0), GroupIndex(0))]), session_info: Some(session_info), + end_syncing: false, }, ); builder.build(&mut virtual_overseer).await; @@ -3491,6 +3585,7 @@ fn waits_until_approving_assignments_are_old_enough() { slot, candidates: Some(vec![(candidate_descriptor, CoreIndex(0), GroupIndex(0))]), session_info: Some(session_info), + end_syncing: false, }, ); builder.build(&mut virtual_overseer).await; @@ -3705,6 +3800,7 @@ fn test_approval_is_sent_on_max_approval_coalesce_count() { slot, candidates: candidates.clone(), session_info: Some(session_info.clone()), + end_syncing: false, }, ) .build(&mut virtual_overseer) @@ -3943,8 +4039,7 @@ fn test_approval_is_sent_on_max_approval_coalesce_wait() { let store = config.backend(); test_harness(config, |test_harness| async move { - let TestHarness { mut virtual_overseer, clock, sync_oracle_handle: _sync_oracle_handle } = - test_harness; + let TestHarness { mut virtual_overseer, clock, sync_oracle_handle: _ } = test_harness; assert_matches!( overseer_recv(&mut virtual_overseer).await, @@ -4006,6 +4101,7 @@ fn test_approval_is_sent_on_max_approval_coalesce_wait() { slot, candidates: candidates.clone(), session_info: Some(session_info.clone()), + end_syncing: false, }, ) .build(&mut virtual_overseer) @@ -4040,3 +4136,569 @@ fn test_approval_is_sent_on_max_approval_coalesce_wait() { virtual_overseer }); } + +// Builds a chain with a fork where both relay blocks include the same candidate. +async fn build_chain_with_two_blocks_with_one_candidate_each( + block_hash1: Hash, + block_hash2: Hash, + slot: Slot, + sync_oracle_handle: TestSyncOracleHandle, + candidate_receipt: CandidateReceipt, +) -> (ChainBuilder, SessionInfo) { + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Eve, + ]; + let session_info = SessionInfo { + validator_groups: IndexedVec::>::from(vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2)], + vec![ValidatorIndex(3), ValidatorIndex(4)], + ]), + ..session_info(&validators) + }; + + let candidates = Some(vec![(candidate_receipt.clone(), CoreIndex(0), GroupIndex(0))]); + let mut chain_builder = ChainBuilder::new(); + + chain_builder + .major_syncing(sync_oracle_handle.is_major_syncing.clone()) + .add_block( + block_hash1, + ChainBuilder::GENESIS_HASH, + 1, + BlockConfig { + slot, + candidates: candidates.clone(), + session_info: Some(session_info.clone()), + end_syncing: false, + }, + ) + .add_block( + block_hash2, + ChainBuilder::GENESIS_HASH, + 1, + BlockConfig { + slot, + candidates, + session_info: Some(session_info.clone()), + end_syncing: true, + }, + ); + (chain_builder, session_info) +} + +async fn setup_overseer_with_two_blocks_each_with_one_assignment_triggered( + virtual_overseer: &mut VirtualOverseer, + store: TestStore, + clock: &Box, + sync_oracle_handle: TestSyncOracleHandle, +) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + let fork_block_hash = Hash::repeat_byte(0x02); + let candidate_commitments = CandidateCommitments::default(); + let mut candidate_receipt = dummy_candidate_receipt(block_hash); + candidate_receipt.commitments_hash = candidate_commitments.hash(); + let candidate_hash = candidate_receipt.hash(); + let slot = Slot::from(1); + let (chain_builder, _session_info) = build_chain_with_two_blocks_with_one_candidate_each( + block_hash, + fork_block_hash, + slot, + sync_oracle_handle, + candidate_receipt, + ) + .await; + chain_builder.build(virtual_overseer).await; + + assert!(!clock.inner.lock().current_wakeup_is(1)); + clock.inner.lock().wakeup_all(1); + + assert!(clock.inner.lock().current_wakeup_is(slot_to_tick(slot))); + clock.inner.lock().wakeup_all(slot_to_tick(slot)); + + futures_timer::Delay::new(Duration::from_millis(200)).await; + + clock.inner.lock().wakeup_all(slot_to_tick(slot + 2)); + + assert_eq!(clock.inner.lock().wakeups.len(), 0); + + futures_timer::Delay::new(Duration::from_millis(200)).await; + + let candidate_entry = store.load_candidate_entry(&candidate_hash).unwrap().unwrap(); + let our_assignment = + candidate_entry.approval_entry(&block_hash).unwrap().our_assignment().unwrap(); + assert!(our_assignment.triggered()); +} + +// Tests that for candidates that we did not approve yet, for which we triggered the assignment and +// the approval work we restart the work to approve it. +#[test] +fn subsystem_relaunches_approval_work_on_restart() { + let assignment_criteria = Box::new(MockAssignmentCriteria( + || { + let mut assignments = HashMap::new(); + let _ = assignments.insert( + CoreIndex(0), + approval_db::v2::OurAssignment { + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }) + .into(), + tranche: 0, + validator_index: ValidatorIndex(0), + triggered: false, + } + .into(), + ); + + let _ = assignments.insert( + CoreIndex(0), + approval_db::v2::OurAssignment { + cert: garbage_assignment_cert_v2(AssignmentCertKindV2::RelayVRFModuloCompact { + core_bitfield: vec![CoreIndex(0), CoreIndex(1), CoreIndex(2)] + .try_into() + .unwrap(), + }), + tranche: 0, + validator_index: ValidatorIndex(0), + triggered: false, + } + .into(), + ); + assignments + }, + |_| Ok(0), + )); + let config = HarnessConfigBuilder::default().assignment_criteria(assignment_criteria).build(); + let store = config.backend(); + let store_clone = config.backend(); + + test_harness(config, |test_harness| async move { + let TestHarness { mut virtual_overseer, clock, sync_oracle_handle } = test_harness; + + setup_overseer_with_two_blocks_each_with_one_assignment_triggered( + &mut virtual_overseer, + store, + &clock, + sync_oracle_handle, + ) + .await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _, + )) => { + } + ); + + recover_available_data(&mut virtual_overseer).await; + fetch_validation_code(&mut virtual_overseer).await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _ + )) => { + } + ); + + // Bail early after the assignment has been distributed but before we answer with the mocked + // approval from CandidateValidation. + virtual_overseer + }); + + // Restart a new approval voting subsystem with the same database and major syncing true untill + // the last leaf. + let config = HarnessConfigBuilder::default().backend(store_clone).major_syncing(true).build(); + + test_harness(config, |test_harness| async move { + let TestHarness { mut virtual_overseer, clock, sync_oracle_handle } = test_harness; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + let fork_block_hash = Hash::repeat_byte(0x02); + let candidate_commitments = CandidateCommitments::default(); + let mut candidate_receipt = dummy_candidate_receipt(block_hash); + candidate_receipt.commitments_hash = candidate_commitments.hash(); + let slot = Slot::from(1); + clock.inner.lock().set_tick(slot_to_tick(slot + 2)); + let (chain_builder, session_info) = build_chain_with_two_blocks_with_one_candidate_each( + block_hash, + fork_block_hash, + slot, + sync_oracle_handle, + candidate_receipt, + ) + .await; + + chain_builder.build(&mut virtual_overseer).await; + + futures_timer::Delay::new(Duration::from_millis(2000)).await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request( + _, + RuntimeApiRequest::SessionInfo(_, si_tx), + ) + ) => { + si_tx.send(Ok(Some(session_info.clone()))).unwrap(); + } + ); + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request( + _, + RuntimeApiRequest::SessionExecutorParams(_, si_tx), + ) + ) => { + // Make sure all SessionExecutorParams calls are not made for the leaf (but for its relay parent) + si_tx.send(Ok(Some(ExecutorParams::default()))).unwrap(); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), ) + ) => { + si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap(); + } + ); + + // On major syncing ending Approval voting should send all the necessary messages for a + // candidate to be approved. + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::NewBlocks( + _, + )) => { + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _, + )) => { + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _, + )) => { + } + ); + + // Guarantees the approval work has been relaunched. + recover_available_data(&mut virtual_overseer).await; + fetch_validation_code(&mut virtual_overseer).await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::CandidateValidation(CandidateValidationMessage::ValidateFromExhaustive { + exec_kind, + response_sender, + .. + }) if exec_kind == PvfExecKind::Approval => { + response_sender.send(Ok(ValidationResult::Valid(Default::default(), Default::default()))) + .unwrap(); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request(_, RuntimeApiRequest::ApprovalVotingParams(_, sender))) => { + let _ = sender.send(Ok(ApprovalVotingParams { + max_approval_coalesce_count: 1, + })); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeApproval(_)) + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request(_, RuntimeApiRequest::ApprovalVotingParams(_, sender))) => { + let _ = sender.send(Ok(ApprovalVotingParams { + max_approval_coalesce_count: 1, + })); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeApproval(_)) + ); + + // Assert that there are no more messages being sent by the subsystem + assert!(overseer_recv(&mut virtual_overseer).timeout(TIMEOUT / 2).await.is_none()); + + virtual_overseer + }); +} + +// Test that cached approvals, which are candidates that we approved but we didn't issue +// the signature yet because we want to coalesce it with more candidate are sent after restart. +#[test] +fn subsystem_sends_pending_approvals_on_approval_restart() { + let assignment_criteria = Box::new(MockAssignmentCriteria( + || { + let mut assignments = HashMap::new(); + let _ = assignments.insert( + CoreIndex(0), + approval_db::v2::OurAssignment { + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }) + .into(), + tranche: 0, + validator_index: ValidatorIndex(0), + triggered: false, + } + .into(), + ); + + let _ = assignments.insert( + CoreIndex(0), + approval_db::v2::OurAssignment { + cert: garbage_assignment_cert_v2(AssignmentCertKindV2::RelayVRFModuloCompact { + core_bitfield: vec![CoreIndex(0), CoreIndex(1), CoreIndex(2)] + .try_into() + .unwrap(), + }), + tranche: 0, + validator_index: ValidatorIndex(0), + triggered: false, + } + .into(), + ); + assignments + }, + |_| Ok(0), + )); + let config = HarnessConfigBuilder::default().assignment_criteria(assignment_criteria).build(); + let store = config.backend(); + let store_clone = config.backend(); + + test_harness(config, |test_harness| async move { + let TestHarness { mut virtual_overseer, clock, sync_oracle_handle } = test_harness; + + setup_overseer_with_two_blocks_each_with_one_assignment_triggered( + &mut virtual_overseer, + store, + &clock, + sync_oracle_handle, + ) + .await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _, + )) => { + } + ); + + recover_available_data(&mut virtual_overseer).await; + fetch_validation_code(&mut virtual_overseer).await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _ + )) => { + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::CandidateValidation(CandidateValidationMessage::ValidateFromExhaustive { + exec_kind, + response_sender, + .. + }) if exec_kind == PvfExecKind::Approval => { + response_sender.send(Ok(ValidationResult::Valid(Default::default(), Default::default()))) + .unwrap(); + } + ); + + // Configure a big coalesce number, so that the signature is cached instead of being sent to + // approval-distribution. + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request(_, RuntimeApiRequest::ApprovalVotingParams(_, sender))) => { + let _ = sender.send(Ok(ApprovalVotingParams { + max_approval_coalesce_count: 6, + })); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request(_, RuntimeApiRequest::ApprovalVotingParams(_, sender))) => { + let _ = sender.send(Ok(ApprovalVotingParams { + max_approval_coalesce_count: 6, + })); + } + ); + + // Assert that there are no more messages being sent by the subsystem + assert!(overseer_recv(&mut virtual_overseer).timeout(TIMEOUT / 2).await.is_none()); + + virtual_overseer + }); + + let config = HarnessConfigBuilder::default().backend(store_clone).major_syncing(true).build(); + // On restart signatures should be sent to approval-distribution without relaunching the + // approval work. + test_harness(config, |test_harness| async move { + let TestHarness { mut virtual_overseer, clock, sync_oracle_handle } = test_harness; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + let fork_block_hash = Hash::repeat_byte(0x02); + let candidate_commitments = CandidateCommitments::default(); + let mut candidate_receipt = dummy_candidate_receipt(block_hash); + candidate_receipt.commitments_hash = candidate_commitments.hash(); + let slot = Slot::from(1); + + clock.inner.lock().set_tick(slot_to_tick(slot + 2)); + let (chain_builder, session_info) = build_chain_with_two_blocks_with_one_candidate_each( + block_hash, + fork_block_hash, + slot, + sync_oracle_handle, + candidate_receipt, + ) + .await; + chain_builder.build(&mut virtual_overseer).await; + + futures_timer::Delay::new(Duration::from_millis(2000)).await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::NewBlocks( + _, + )) => { + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _, + )) => { + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _, + )) => { + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request(_, RuntimeApiRequest::ApprovalVotingParams(_, sender))) => { + let _ = sender.send(Ok(ApprovalVotingParams { + max_approval_coalesce_count: 1, + })); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request( + _, + RuntimeApiRequest::SessionInfo(_, si_tx), + ) + ) => { + si_tx.send(Ok(Some(session_info.clone()))).unwrap(); + } + ); + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request( + _, + RuntimeApiRequest::SessionExecutorParams(_, si_tx), + ) + ) => { + // Make sure all SessionExecutorParams calls are not made for the leaf (but for its relay parent) + si_tx.send(Ok(Some(ExecutorParams::default()))).unwrap(); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), ) + ) => { + si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap(); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeApproval(_)) + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request(_, RuntimeApiRequest::ApprovalVotingParams(_, sender))) => { + let _ = sender.send(Ok(ApprovalVotingParams { + max_approval_coalesce_count: 1, + })); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeApproval(_)) + ); + + // Assert that there are no more messages being sent by the subsystem + assert!(overseer_recv(&mut virtual_overseer).timeout(TIMEOUT / 2).await.is_none()); + + virtual_overseer + }); +} -- GitLab From c244a94e4a77c0798c5a45d3004ec2389378b394 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Thu, 29 Feb 2024 11:41:11 +0000 Subject: [PATCH 328/392] update development setup in sdk-docs (#3506) Co-authored-by: Liam Aharon --- .../development_environment_advice.rs | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/docs/sdk/src/reference_docs/development_environment_advice.rs b/docs/sdk/src/reference_docs/development_environment_advice.rs index 43176959793..21bbe78836c 100644 --- a/docs/sdk/src/reference_docs/development_environment_advice.rs +++ b/docs/sdk/src/reference_docs/development_environment_advice.rs @@ -111,3 +111,74 @@ //! If you have a powerful remote server available, you may consider using //! [cargo-remote](https://github.com/sgeisler/cargo-remote) to execute cargo commands on it, //! freeing up local resources for other tasks like `rust-analyzer`. +//! +//! When using `cargo-remote`, you can configure your editor to perform the the typical +//! "check-on-save" remotely as well. The configuration for VSCode is as follows: +//! +//! ```json +//! { +//! "rust-analyzer.cargo.buildScripts.overrideCommand": [ +//! "cargo", +//! "remote", +//! "--build-env", +//! "SKIP_WASM_BUILD=1", +//! "--", +//! "check", +//! "--message-format=json", +//! "--all-targets", +//! "--all-features", +//! "--target-dir=target/rust-analyzer" +//! ], +//! "rust-analyzer.check.overrideCommand": [ +//! "cargo", +//! "remote", +//! "--build-env", +//! "SKIP_WASM_BUILD=1", +//! "--", +//! "check", +//! "--workspace", +//! "--message-format=json", +//! "--all-targets", +//! "--all-features", +//! "--target-dir=target/rust-analyzer" +//! ], +//! } +//! ``` +//! +//! //! and the same in Lua for `neovim/nvim-lspconfig`: +//! +//! ```lua +//! ["rust-analyzer"] = { +//! cargo = { +//! buildScripts = { +//! overrideCommand = { +//! "cargo", +//! "remote", +//! "--build-env", +//! "SKIP_WASM_BUILD=1", +//! "--", +//! "check", +//! "--message-format=json", +//! "--all-targets", +//! "--all-features", +//! "--target-dir=target/rust-analyzer" +//! }, +//! }, +//! check = { +//! overrideCommand = { +//! "cargo", +//! "remote", +//! "--build-env", +//! "SKIP_WASM_BUILD=1", +//! "--", +//! "check", +//! "--workspace", +//! "--message-format=json", +//! "--all-targets", +//! "--all-features", +//! "--target-dir=target/rust-analyzer" +//! }, +//! }, +//! }, +//! }, +//! ``` -- GitLab From 7f5d308d2983dcce324a8625edf3f2a838209da8 Mon Sep 17 00:00:00 2001 From: Andrei Sandu <54316454+sandreim@users.noreply.github.com> Date: Thu, 29 Feb 2024 15:32:58 +0200 Subject: [PATCH 329/392] Enable elastic scaling node feature in local testnets genesis (#3509) Signed-off-by: Andrei Sandu --- Cargo.lock | 1 + polkadot/node/service/Cargo.toml | 5 ++- polkadot/node/service/src/chain_spec.rs | 7 +++- polkadot/runtime/parachains/src/builder.rs | 24 ++++++++---- .../functional/0012-elastic-scaling-mvp.zndsl | 11 +----- .../functional/0012-enable-node-feature.js | 37 ------------------- 6 files changed, 27 insertions(+), 58 deletions(-) delete mode 100644 polkadot/zombienet_tests/functional/0012-enable-node-feature.js diff --git a/Cargo.lock b/Cargo.lock index 3838ed0e94a..991541ee84e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13526,6 +13526,7 @@ version = "7.0.0" dependencies = [ "assert_matches", "async-trait", + "bitvec", "env_logger 0.9.3", "frame-benchmarking", "frame-benchmarking-cli", diff --git a/polkadot/node/service/Cargo.toml b/polkadot/node/service/Cargo.toml index 8fd9f20b7bc..734dcbdeb44 100644 --- a/polkadot/node/service/Cargo.toml +++ b/polkadot/node/service/Cargo.toml @@ -93,6 +93,7 @@ kvdb-rocksdb = { version = "0.19.0", optional = true } parity-db = { version = "0.4.12", optional = true } codec = { package = "parity-scale-codec", version = "3.6.1" } parking_lot = "0.12.1" +bitvec = { version = "1.0.1", optional = true } # Polkadot polkadot-core-primitives = { path = "../../core-primitives" } @@ -184,8 +185,8 @@ full-node = [ ] # Configure the native runtimes to use. -westend-native = ["westend-runtime", "westend-runtime-constants"] -rococo-native = ["rococo-runtime", "rococo-runtime-constants"] +westend-native = ["bitvec", "westend-runtime", "westend-runtime-constants"] +rococo-native = ["bitvec", "rococo-runtime", "rococo-runtime-constants"] runtime-benchmarks = [ "frame-benchmarking-cli/runtime-benchmarks", diff --git a/polkadot/node/service/src/chain_spec.rs b/polkadot/node/service/src/chain_spec.rs index af05af87a46..1c44b17b6fd 100644 --- a/polkadot/node/service/src/chain_spec.rs +++ b/polkadot/node/service/src/chain_spec.rs @@ -122,7 +122,9 @@ pub fn wococo_config() -> Result { fn default_parachains_host_configuration( ) -> polkadot_runtime_parachains::configuration::HostConfiguration { - use polkadot_primitives::{AsyncBackingParams, MAX_CODE_SIZE, MAX_POV_SIZE}; + use polkadot_primitives::{ + vstaging::node_features::FeatureIndex, AsyncBackingParams, MAX_CODE_SIZE, MAX_POV_SIZE, + }; polkadot_runtime_parachains::configuration::HostConfiguration { validation_upgrade_cooldown: 2u32, @@ -155,6 +157,9 @@ fn default_parachains_host_configuration( max_candidate_depth: 3, allowed_ancestry_len: 2, }, + node_features: bitvec::vec::BitVec::from_element( + 1u8 << (FeatureIndex::ElasticScalingMVP as usize), + ), scheduler_params: SchedulerParams { lookahead: 2, group_rotation_frequency: 20, diff --git a/polkadot/runtime/parachains/src/builder.rs b/polkadot/runtime/parachains/src/builder.rs index 0e4e659fef2..5b218addb1a 100644 --- a/polkadot/runtime/parachains/src/builder.rs +++ b/polkadot/runtime/parachains/src/builder.rs @@ -25,12 +25,13 @@ use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec}; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; use primitives::{ - collator_signature_payload, AvailabilityBitfield, BackedCandidate, CandidateCommitments, - CandidateDescriptor, CandidateHash, CollatorId, CollatorSignature, CommittedCandidateReceipt, - CompactStatement, CoreIndex, DisputeStatement, DisputeStatementSet, GroupIndex, HeadData, - Id as ParaId, IndexedVec, InherentData as ParachainsInherentData, InvalidDisputeStatementKind, - PersistedValidationData, SessionIndex, SigningContext, UncheckedSigned, - ValidDisputeStatementKind, ValidationCode, ValidatorId, ValidatorIndex, ValidityAttestation, + collator_signature_payload, vstaging::node_features::FeatureIndex, AvailabilityBitfield, + BackedCandidate, CandidateCommitments, CandidateDescriptor, CandidateHash, CollatorId, + CollatorSignature, CommittedCandidateReceipt, CompactStatement, CoreIndex, DisputeStatement, + DisputeStatementSet, GroupIndex, HeadData, Id as ParaId, IndexedVec, + InherentData as ParachainsInherentData, InvalidDisputeStatementKind, PersistedValidationData, + SessionIndex, SigningContext, UncheckedSigned, ValidDisputeStatementKind, ValidationCode, + ValidatorId, ValidatorIndex, ValidityAttestation, }; use sp_core::{sr25519, H256}; use sp_runtime::{ @@ -509,7 +510,7 @@ impl BenchBuilder { .iter() .map(|(seed, num_votes)| { assert!(*num_votes <= validators.len() as u32); - let (para_id, _core_idx, group_idx) = self.create_indexes(*seed); + let (para_id, core_idx, group_idx) = self.create_indexes(*seed); // This generates a pair and adds it to the keystore, returning just the public. let collator_public = CollatorId::generate_pair(None); @@ -586,11 +587,18 @@ impl BenchBuilder { }) .collect(); + // Check if the elastic scaling bit is set, if so we need to supply the core index + // in the generated candidate. + let core_idx = configuration::Pallet::::config() + .node_features + .get(FeatureIndex::ElasticScalingMVP as usize) + .map(|_the_bit| core_idx); + BackedCandidate::::new( candidate, validity_votes, bitvec::bitvec![u8, bitvec::order::Lsb0; 1; group_validators.len()], - None, + core_idx, ) }) .collect() diff --git a/polkadot/zombienet_tests/functional/0012-elastic-scaling-mvp.zndsl b/polkadot/zombienet_tests/functional/0012-elastic-scaling-mvp.zndsl index a7193c9282b..edc87c802a0 100644 --- a/polkadot/zombienet_tests/functional/0012-elastic-scaling-mvp.zndsl +++ b/polkadot/zombienet_tests/functional/0012-elastic-scaling-mvp.zndsl @@ -1,4 +1,4 @@ -Description: Test that a paraid acquiring multiple cores does not brick itself if ElasticScalingMVP feature is enabled +Description: Test that a paraid acquiring multiple cores does not brick itself if ElasticScalingMVP feature is enabled in genesis Network: ./0012-elastic-scaling-mvp.toml Creds: config @@ -15,14 +15,5 @@ alice: js-script ./0012-register-para.js return is 0 within 600 seconds validator: reports substrate_block_height{status="finalized"} is at least 35 within 100 seconds -# Parachain will now be stalled -validator: parachain 2000 block height is lower than 20 within 300 seconds - -# Enable the ElasticScalingMVP node feature. -alice: js-script ./0012-enable-node-feature.js with "1" return is 0 within 600 seconds - -# Wait two sessions for the config to be updated. -sleep 120 seconds - # Ensure parachain is now making progress. validator: parachain 2000 block height is at least 30 within 200 seconds diff --git a/polkadot/zombienet_tests/functional/0012-enable-node-feature.js b/polkadot/zombienet_tests/functional/0012-enable-node-feature.js deleted file mode 100644 index 4822e1f6644..00000000000 --- a/polkadot/zombienet_tests/functional/0012-enable-node-feature.js +++ /dev/null @@ -1,37 +0,0 @@ -async function run(nodeName, networkInfo, index) { - const { wsUri, userDefinedTypes } = networkInfo.nodesByName[nodeName]; - const api = await zombie.connect(wsUri, userDefinedTypes); - - await zombie.util.cryptoWaitReady(); - - // account to submit tx - const keyring = new zombie.Keyring({ type: "sr25519" }); - const alice = keyring.addFromUri("//Alice"); - - await new Promise(async (resolve, reject) => { - const unsub = await api.tx.sudo - .sudo(api.tx.configuration.setNodeFeature(Number(index), true)) - .signAndSend(alice, ({ status, isError }) => { - if (status.isInBlock) { - console.log( - `Transaction included at blockhash ${status.asInBlock}`, - ); - } else if (status.isFinalized) { - console.log( - `Transaction finalized at blockHash ${status.asFinalized}`, - ); - unsub(); - return resolve(); - } else if (isError) { - console.log(`Transaction error`); - reject(`Transaction error`); - } - }); - }); - - - - return 0; -} - -module.exports = { run }; -- GitLab From c0e52a9ed61451152c4e096c58f24fb4e329bd64 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Thu, 29 Feb 2024 19:08:08 +0000 Subject: [PATCH 330/392] Fix call enum's metadata regression (#3513) This fixes an issue introduced in https://github.com/paritytech/substrate/pull/14101, in which I removed the `Call` enum's documentation and replaced it with a link to the `Pallet` struct, but this also removed any docs related to call from the metadata. I tried to add a regression test for this, but it seems to me that this is not possible, given that using `type-info` we only assert in type-ids for `Call`, `Event` and `Error`. I removed some doc comments from a test setup in `frame-support-test` to demonstrate the issue there. @jsdw do you have any comments on this? I also fixed a small issue in the custom html/css of `polkadot-sdk-doc` crate, making sure it does not affect the rust-doc page of all other crates. - [x] Investigate a regression test - [x] prdoc --- docs/sdk/headers/header.html | 111 +++++++++--------- docs/sdk/headers/theme.css | 25 ++-- prdoc/pr_3513.prdoc | 18 +++ substrate/frame/support/Cargo.toml | 21 +++- .../procedural/src/pallet/expand/call.rs | 21 +--- substrate/frame/support/test/tests/pallet.rs | 64 +++++++--- 6 files changed, 157 insertions(+), 103 deletions(-) create mode 100644 prdoc/pr_3513.prdoc diff --git a/docs/sdk/headers/header.html b/docs/sdk/headers/header.html index 68dc5d5509e..e28458c4ccc 100644 --- a/docs/sdk/headers/header.html +++ b/docs/sdk/headers/header.html @@ -54,7 +54,7 @@ sidebarElems.style.display = 'none'; // Add click event listener to the button - expandButton.addEventListener('click', function() { + expandButton.addEventListener('click', function () { // Toggle the display of the '.sidebar-elems' if (sidebarElems.style.display === 'none') { sidebarElems.style.display = 'block'; @@ -72,6 +72,9 @@ if (!crate_name.textContent.startsWith("polkadot_sdk_docs")) { console.log("skipping -- not `polkadot_sdk_docs`"); return; + } else { + // insert class 'sdk-docs' to the body, so it enables the custom css rules. + document.body.classList.add("sdk-docs"); } createToC(); @@ -82,58 +85,60 @@ diff --git a/docs/sdk/headers/theme.css b/docs/sdk/headers/theme.css index bb9254ec4a8..a488e15c36b 100644 --- a/docs/sdk/headers/theme.css +++ b/docs/sdk/headers/theme.css @@ -1,16 +1,17 @@ :root { - --polkadot-pink: #E6007A ; - --polkadot-green: #56F39A ; - --polkadot-lime: #D3FF33 ; - --polkadot-cyan: #00B2FF ; - --polkadot-purple: #552BBF ; - } - -body > nav.sidebar > div.sidebar-crate > a > img { - /* logo width, given that the sidebar width is 200px; */ - width: 190px; + --polkadot-pink: #E6007A; + --polkadot-green: #56F39A; + --polkadot-lime: #D3FF33; + --polkadot-cyan: #00B2FF; + --polkadot-purple: #552BBF; } -body nav.sidebar { - flex: 0 0 250px; +body.sdk-docs { + nav.sidebar>div.sidebar-crate>a>img { + width: 190px; + } + + nav.sidebar { + flex: 0 0 250px; + } } diff --git a/prdoc/pr_3513.prdoc b/prdoc/pr_3513.prdoc new file mode 100644 index 00000000000..e1f2afe280a --- /dev/null +++ b/prdoc/pr_3513.prdoc @@ -0,0 +1,18 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Fix call enum's metadata regression + +doc: + - audience: Runtime Dev + - audience: Runtime User + description: | + This PR fixes an issue where in the metadata of all FRAME-based chains, the documentation for + all extrinsic/call/transactions has been replaced by a single line saying "see Pallet::name". + + Many wallets display the metadata of transactions to the user before signing, and this bug + might have affected this process. + +crates: + - name: frame + - name: frame-support diff --git a/substrate/frame/support/Cargo.toml b/substrate/frame/support/Cargo.toml index 72e2d0bfa56..c19f478c803 100644 --- a/substrate/frame/support/Cargo.toml +++ b/substrate/frame/support/Cargo.toml @@ -18,13 +18,24 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] array-bytes = { version = "6.1", default-features = false } serde = { features = ["alloc", "derive"], workspace = true } -codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive", "max-encoded-len"] } -scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -frame-metadata = { version = "16.0.0", default-features = false, features = ["current"] } -sp-api = { path = "../../primitives/api", default-features = false, features = ["frame-metadata"] } +codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = [ + "derive", + "max-encoded-len", +] } +scale-info = { version = "2.10.0", default-features = false, features = [ + "derive", +] } +frame-metadata = { version = "16.0.0", default-features = false, features = [ + "current", +] } +sp-api = { path = "../../primitives/api", default-features = false, features = [ + "frame-metadata", +] } sp-std = { path = "../../primitives/std", default-features = false } sp-io = { path = "../../primitives/io", default-features = false } -sp-runtime = { path = "../../primitives/runtime", default-features = false, features = ["serde"] } +sp-runtime = { path = "../../primitives/runtime", default-features = false, features = [ + "serde", +] } sp-tracing = { path = "../../primitives/tracing", default-features = false } sp-core = { path = "../../primitives/core", default-features = false } sp-arithmetic = { path = "../../primitives/arithmetic", default-features = false } diff --git a/substrate/frame/support/procedural/src/pallet/expand/call.rs b/substrate/frame/support/procedural/src/pallet/expand/call.rs index f43faba1ee0..f395872c8a8 100644 --- a/substrate/frame/support/procedural/src/pallet/expand/call.rs +++ b/substrate/frame/support/procedural/src/pallet/expand/call.rs @@ -18,7 +18,7 @@ use crate::{ pallet::{ expand::warnings::{weight_constant_warning, weight_witness_warning}, - parse::call::{CallVariantDef, CallWeightDef}, + parse::call::CallWeightDef, Def, }, COUNTER, @@ -112,22 +112,7 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream { } debug_assert_eq!(fn_weight.len(), methods.len()); - let map_fn_docs = if !def.dev_mode { - // Emit the [`Pallet::method`] documentation only for non-dev modes. - |method: &CallVariantDef| { - let reference = format!("See [`Pallet::{}`].", method.name); - quote!(#reference) - } - } else { - // For the dev-mode do not provide a documenation link as it will break the - // `cargo doc` if the pallet is private inside a test. - |method: &CallVariantDef| { - let reference = format!("See `Pallet::{}`.", method.name); - quote!(#reference) - } - }; - - let fn_doc = methods.iter().map(map_fn_docs).collect::>(); + let fn_doc = methods.iter().map(|method| &method.docs).collect::>(); let args_name = methods .iter() @@ -309,7 +294,7 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream { ), #( #cfg_attrs - #[doc = #fn_doc] + #( #[doc = #fn_doc] )* #[codec(index = #call_index)] #fn_name { #( diff --git a/substrate/frame/support/test/tests/pallet.rs b/substrate/frame/support/test/tests/pallet.rs index 7bee4b7c820..607f54ccc13 100644 --- a/substrate/frame/support/test/tests/pallet.rs +++ b/substrate/frame/support/test/tests/pallet.rs @@ -209,7 +209,7 @@ pub mod pallet { where T::AccountId: From + From + SomeAssociation1, { - /// Doc comment put in metadata + /// call foo doc comment put in metadata #[pallet::call_index(0)] #[pallet::weight(Weight::from_parts(*foo as u64, 0))] pub fn foo( @@ -225,7 +225,7 @@ pub mod pallet { Ok(().into()) } - /// Doc comment put in metadata + /// call foo_storage_layer doc comment put in metadata #[pallet::call_index(1)] #[pallet::weight({1})] pub fn foo_storage_layer( @@ -270,7 +270,7 @@ pub mod pallet { #[pallet::error] #[derive(PartialEq, Eq)] pub enum Error { - /// doc comment put into metadata + /// error doc comment put in metadata InsufficientProposersBalance, NonExistentStorageValue, Code(u8), @@ -287,9 +287,8 @@ pub mod pallet { where T::AccountId: SomeAssociation1 + From, { - /// doc comment put in metadata + /// event doc comment put in metadata Proposed(::AccountId), - /// doc Spending(BalanceOf), Something(u32), SomethingElse(::_1), @@ -750,8 +749,7 @@ pub type UncheckedExtrinsic = sp_runtime::testing::TestXt>; frame_support::construct_runtime!( - pub struct Runtime - { + pub struct Runtime { // Exclude part `Storage` in order not to check its metadata in tests. System: frame_system exclude_parts { Pallet, Storage }, Example: pallet, @@ -772,6 +770,14 @@ fn _ensure_call_is_correctly_excluded_and_included(call: RuntimeCall) { } } +fn maybe_docs(doc: Vec<&'static str>) -> Vec<&'static str> { + if cfg!(feature = "no-metadata-docs") { + vec![] + } else { + doc + } +} + #[test] fn transactional_works() { TestExternalities::default().execute_with(|| { @@ -1362,19 +1368,47 @@ fn migrate_from_pallet_version_to_storage_version() { }); } +#[test] +fn pallet_item_docs_in_metadata() { + // call + let call_variants = match meta_type::>().type_info().type_def { + scale_info::TypeDef::Variant(variants) => variants.variants, + _ => unreachable!(), + }; + + assert_eq!(call_variants[0].docs, maybe_docs(vec!["call foo doc comment put in metadata"])); + assert_eq!( + call_variants[1].docs, + maybe_docs(vec!["call foo_storage_layer doc comment put in metadata"]) + ); + assert!(call_variants[2].docs.is_empty()); + + // event + let event_variants = match meta_type::>().type_info().type_def { + scale_info::TypeDef::Variant(variants) => variants.variants, + _ => unreachable!(), + }; + + assert_eq!(event_variants[0].docs, maybe_docs(vec!["event doc comment put in metadata"])); + assert!(event_variants[1].docs.is_empty()); + + // error + let error_variants = match meta_type::>().type_info().type_def { + scale_info::TypeDef::Variant(variants) => variants.variants, + _ => unreachable!(), + }; + + assert_eq!(error_variants[0].docs, maybe_docs(vec!["error doc comment put in metadata"])); + assert!(error_variants[1].docs.is_empty()); + + // storage is already covered in the main `fn metadata` test. +} + #[test] fn metadata() { use codec::Decode; use frame_metadata::{v15::*, *}; - fn maybe_docs(doc: Vec<&'static str>) -> Vec<&'static str> { - if cfg!(feature = "no-metadata-docs") { - vec![] - } else { - doc - } - } - let readme = "Support code for the runtime.\n\nLicense: Apache-2.0\n"; let expected_pallet_doc = vec![" Pallet documentation", readme, readme]; -- GitLab From 650886683d42de45fbcb92645d988248dda6dbba Mon Sep 17 00:00:00 2001 From: Francisco Aguirre Date: Fri, 1 Mar 2024 08:31:48 +0100 Subject: [PATCH 331/392] Add `claim_assets` extrinsic to `pallet-xcm` (#3403) If an XCM execution fails or ends with leftover assets, these will be trapped. In order to claim them, a custom XCM has to be executed, with the `ClaimAsset` instruction. However, arbitrary XCM execution is not allowed everywhere yet and XCM itself is still not easy enough to use for users out there with trapped assets. This new extrinsic in `pallet-xcm` will allow these users to easily claim their assets, without concerning themselves with writing arbitrary XCMs. Part of fixing https://github.com/paritytech/polkadot-sdk/issues/3495 --------- Co-authored-by: command-bot <> Co-authored-by: Adrian Catangiu --- .../assets/asset-hub-rococo/src/lib.rs | 7 + .../src/weights/pallet_xcm.rs | 146 ++++--- .../assets/asset-hub-westend/src/lib.rs | 7 + .../src/weights/pallet_xcm.rs | 150 ++++--- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 7 + .../src/weights/pallet_xcm.rs | 142 +++--- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 7 + .../src/weights/pallet_xcm.rs | 146 ++++--- .../collectives-westend/src/lib.rs | 7 + .../src/weights/pallet_xcm.rs | 142 +++--- .../contracts/contracts-rococo/src/lib.rs | 7 + .../coretime/coretime-rococo/src/lib.rs | 7 + .../coretime-rococo/src/weights/pallet_xcm.rs | 154 ++++--- .../coretime/coretime-westend/src/lib.rs | 7 + .../src/weights/pallet_xcm.rs | 94 ++-- .../runtimes/people/people-rococo/src/lib.rs | 7 + .../people-rococo/src/weights/pallet_xcm.rs | 412 +++++++++--------- .../runtimes/people/people-westend/src/lib.rs | 7 + .../people-westend/src/weights/pallet_xcm.rs | 412 +++++++++--------- polkadot/runtime/rococo/src/lib.rs | 7 + .../runtime/rococo/src/weights/pallet_xcm.rs | 230 ++++++---- polkadot/runtime/westend/src/lib.rs | 7 + .../runtime/westend/src/weights/pallet_xcm.rs | 238 ++++++---- polkadot/xcm/pallet-xcm/src/benchmarking.rs | 21 +- polkadot/xcm/pallet-xcm/src/lib.rs | 63 +++ polkadot/xcm/pallet-xcm/src/mock.rs | 6 +- polkadot/xcm/pallet-xcm/src/tests/mod.rs | 51 +++ polkadot/xcm/src/lib.rs | 31 +- prdoc/pr_3403.prdoc | 22 + 29 files changed, 1501 insertions(+), 1043 deletions(-) create mode 100644 prdoc/pr_3403.prdoc diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 1c4f49fea0e..a64d4bc2365 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -1454,6 +1454,13 @@ impl_runtime_apis! { }); Some((assets, fee_index as u32, dest, verify)) } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(ExistentialDeposit::get()), + } + } } impl XcmBridgeHubRouterConfig for Runtime { diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm.rs index f8820bbb58c..51b6543bae8 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-r43aesjn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-rococo-dev")`, DB CACHE: 1024 // Executed Command: @@ -64,8 +64,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3610` - // Minimum execution time: 25_003_000 picoseconds. - Weight::from_parts(25_800_000, 0) + // Minimum execution time: 22_136_000 picoseconds. + Weight::from_parts(22_518_000, 0) .saturating_add(Weight::from_parts(0, 3610)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) @@ -90,8 +90,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3610` - // Minimum execution time: 88_832_000 picoseconds. - Weight::from_parts(90_491_000, 0) + // Minimum execution time: 92_277_000 picoseconds. + Weight::from_parts(94_843_000, 0) .saturating_add(Weight::from_parts(0, 3610)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) @@ -118,8 +118,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `400` // Estimated: `6196` - // Minimum execution time: 138_911_000 picoseconds. - Weight::from_parts(142_483_000, 0) + // Minimum execution time: 120_110_000 picoseconds. + Weight::from_parts(122_968_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(5)) @@ -148,8 +148,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `496` // Estimated: `6208` - // Minimum execution time: 146_932_000 picoseconds. - Weight::from_parts(153_200_000, 0) + // Minimum execution time: 143_116_000 picoseconds. + Weight::from_parts(147_355_000, 0) .saturating_add(Weight::from_parts(0, 6208)) .saturating_add(T::DbWeight::get().reads(12)) .saturating_add(T::DbWeight::get().writes(7)) @@ -170,8 +170,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_081_000 picoseconds. - Weight::from_parts(7_397_000, 0) + // Minimum execution time: 6_517_000 picoseconds. + Weight::from_parts(6_756_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -181,8 +181,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_007_000 picoseconds. - Weight::from_parts(2_183_000, 0) + // Minimum execution time: 1_894_000 picoseconds. + Weight::from_parts(2_024_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -208,8 +208,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3610` - // Minimum execution time: 28_790_000 picoseconds. - Weight::from_parts(29_767_000, 0) + // Minimum execution time: 27_314_000 picoseconds. + Weight::from_parts(28_787_000, 0) .saturating_add(Weight::from_parts(0, 3610)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(5)) @@ -234,8 +234,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `363` // Estimated: `3828` - // Minimum execution time: 30_951_000 picoseconds. - Weight::from_parts(31_804_000, 0) + // Minimum execution time: 29_840_000 picoseconds. + Weight::from_parts(30_589_000, 0) .saturating_add(Weight::from_parts(0, 3828)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) @@ -246,45 +246,45 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_164_000 picoseconds. - Weight::from_parts(2_311_000, 0) + // Minimum execution time: 1_893_000 picoseconds. + Weight::from_parts(2_017_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `PolkadotXcm::SupportedVersion` (r:4 w:2) + /// Storage: `PolkadotXcm::SupportedVersion` (r:5 w:2) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `162` - // Estimated: `11052` - // Minimum execution time: 16_906_000 picoseconds. - Weight::from_parts(17_612_000, 0) - .saturating_add(Weight::from_parts(0, 11052)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `159` + // Estimated: `13524` + // Minimum execution time: 19_211_000 picoseconds. + Weight::from_parts(19_552_000, 0) + .saturating_add(Weight::from_parts(0, 13524)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifiers` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `166` - // Estimated: `11056` - // Minimum execution time: 17_443_000 picoseconds. - Weight::from_parts(18_032_000, 0) - .saturating_add(Weight::from_parts(0, 11056)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `163` + // Estimated: `13528` + // Minimum execution time: 19_177_000 picoseconds. + Weight::from_parts(19_704_000, 0) + .saturating_add(Weight::from_parts(0, 13528)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:6 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `173` - // Estimated: `13538` - // Minimum execution time: 18_992_000 picoseconds. - Weight::from_parts(19_464_000, 0) - .saturating_add(Weight::from_parts(0, 13538)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `16013` + // Minimum execution time: 20_449_000 picoseconds. + Weight::from_parts(21_075_000, 0) + .saturating_add(Weight::from_parts(0, 16013)) + .saturating_add(T::DbWeight::get().reads(6)) } /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:2 w:1) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -304,36 +304,36 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `212` // Estimated: `6152` - // Minimum execution time: 28_011_000 picoseconds. - Weight::from_parts(28_716_000, 0) + // Minimum execution time: 26_578_000 picoseconds. + Weight::from_parts(27_545_000, 0) .saturating_add(Weight::from_parts(0, 6152)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:3 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `206` - // Estimated: `8621` - // Minimum execution time: 9_533_000 picoseconds. - Weight::from_parts(9_856_000, 0) - .saturating_add(Weight::from_parts(0, 8621)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `11096` + // Minimum execution time: 11_646_000 picoseconds. + Weight::from_parts(11_944_000, 0) + .saturating_add(Weight::from_parts(0, 11096)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `173` - // Estimated: `11063` - // Minimum execution time: 17_628_000 picoseconds. - Weight::from_parts(18_146_000, 0) - .saturating_add(Weight::from_parts(0, 11063)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `170` + // Estimated: `13535` + // Minimum execution time: 19_301_000 picoseconds. + Weight::from_parts(19_664_000, 0) + .saturating_add(Weight::from_parts(0, 13535)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) /// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -349,12 +349,12 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `215` - // Estimated: `11105` - // Minimum execution time: 34_877_000 picoseconds. - Weight::from_parts(35_607_000, 0) - .saturating_add(Weight::from_parts(0, 11105)) - .saturating_add(T::DbWeight::get().reads(10)) + // Measured: `212` + // Estimated: `13577` + // Minimum execution time: 35_715_000 picoseconds. + Weight::from_parts(36_915_000, 0) + .saturating_add(Weight::from_parts(0, 13577)) + .saturating_add(T::DbWeight::get().reads(11)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) @@ -365,8 +365,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `1588` - // Minimum execution time: 5_370_000 picoseconds. - Weight::from_parts(5_616_000, 0) + // Minimum execution time: 4_871_000 picoseconds. + Weight::from_parts(5_066_000, 0) .saturating_add(Weight::from_parts(0, 1588)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -377,10 +377,22 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7740` // Estimated: `11205` - // Minimum execution time: 26_820_000 picoseconds. - Weight::from_parts(27_143_000, 0) + // Minimum execution time: 25_150_000 picoseconds. + Weight::from_parts(26_119_000, 0) .saturating_add(Weight::from_parts(0, 11205)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) + /// Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `160` + // Estimated: `3625` + // Minimum execution time: 38_248_000 picoseconds. + Weight::from_parts(39_122_000, 0) + .saturating_add(Weight::from_parts(0, 3625)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index e015c7bfca3..5778ed362ee 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -1526,6 +1526,13 @@ impl_runtime_apis! { }); Some((assets, fee_index as u32, dest, verify)) } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(ExistentialDeposit::get()), + } + } } use pallet_xcm_bridge_hub_router::benchmarking::{ diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm.rs index 504731f4a9e..71facff87d3 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-r43aesjn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-westend-dev")`, DB CACHE: 1024 // Executed Command: @@ -64,8 +64,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3610` - // Minimum execution time: 25_482_000 picoseconds. - Weight::from_parts(26_622_000, 0) + // Minimum execution time: 21_630_000 picoseconds. + Weight::from_parts(22_306_000, 0) .saturating_add(Weight::from_parts(0, 3610)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) @@ -90,8 +90,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3610` - // Minimum execution time: 87_319_000 picoseconds. - Weight::from_parts(89_764_000, 0) + // Minimum execution time: 91_802_000 picoseconds. + Weight::from_parts(93_672_000, 0) .saturating_add(Weight::from_parts(0, 3610)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) @@ -118,8 +118,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `367` // Estimated: `6196` - // Minimum execution time: 139_133_000 picoseconds. - Weight::from_parts(141_507_000, 0) + // Minimum execution time: 118_930_000 picoseconds. + Weight::from_parts(122_306_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(5)) @@ -148,8 +148,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `496` // Estimated: `6208` - // Minimum execution time: 144_241_000 picoseconds. - Weight::from_parts(149_709_000, 0) + // Minimum execution time: 140_527_000 picoseconds. + Weight::from_parts(144_501_000, 0) .saturating_add(Weight::from_parts(0, 6208)) .saturating_add(T::DbWeight::get().reads(12)) .saturating_add(T::DbWeight::get().writes(7)) @@ -158,8 +158,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 10_392_000 picoseconds. - Weight::from_parts(10_779_000, 0) + // Minimum execution time: 7_556_000 picoseconds. + Weight::from_parts(7_798_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// Storage: `PolkadotXcm::SupportedVersion` (r:0 w:1) @@ -168,8 +168,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_088_000 picoseconds. - Weight::from_parts(7_257_000, 0) + // Minimum execution time: 6_373_000 picoseconds. + Weight::from_parts(6_603_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -179,8 +179,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_095_000 picoseconds. - Weight::from_parts(2_136_000, 0) + // Minimum execution time: 1_941_000 picoseconds. + Weight::from_parts(2_088_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -206,8 +206,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3610` - // Minimum execution time: 28_728_000 picoseconds. - Weight::from_parts(29_349_000, 0) + // Minimum execution time: 27_080_000 picoseconds. + Weight::from_parts(27_820_000, 0) .saturating_add(Weight::from_parts(0, 3610)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(5)) @@ -232,8 +232,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `363` // Estimated: `3828` - // Minimum execution time: 30_605_000 picoseconds. - Weight::from_parts(31_477_000, 0) + // Minimum execution time: 28_850_000 picoseconds. + Weight::from_parts(29_506_000, 0) .saturating_add(Weight::from_parts(0, 3828)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) @@ -244,45 +244,45 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_137_000 picoseconds. - Weight::from_parts(2_303_000, 0) + // Minimum execution time: 2_033_000 picoseconds. + Weight::from_parts(2_201_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `PolkadotXcm::SupportedVersion` (r:4 w:2) + /// Storage: `PolkadotXcm::SupportedVersion` (r:5 w:2) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `162` - // Estimated: `11052` - // Minimum execution time: 16_719_000 picoseconds. - Weight::from_parts(17_329_000, 0) - .saturating_add(Weight::from_parts(0, 11052)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `159` + // Estimated: `13524` + // Minimum execution time: 18_844_000 picoseconds. + Weight::from_parts(19_197_000, 0) + .saturating_add(Weight::from_parts(0, 13524)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifiers` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `166` - // Estimated: `11056` - // Minimum execution time: 16_687_000 picoseconds. - Weight::from_parts(17_405_000, 0) - .saturating_add(Weight::from_parts(0, 11056)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `163` + // Estimated: `13528` + // Minimum execution time: 18_940_000 picoseconds. + Weight::from_parts(19_450_000, 0) + .saturating_add(Weight::from_parts(0, 13528)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:6 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `173` - // Estimated: `13538` - // Minimum execution time: 18_751_000 picoseconds. - Weight::from_parts(19_130_000, 0) - .saturating_add(Weight::from_parts(0, 13538)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `16013` + // Minimum execution time: 20_521_000 picoseconds. + Weight::from_parts(21_076_000, 0) + .saturating_add(Weight::from_parts(0, 16013)) + .saturating_add(T::DbWeight::get().reads(6)) } /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:2 w:1) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -302,36 +302,36 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `212` // Estimated: `6152` - // Minimum execution time: 27_189_000 picoseconds. - Weight::from_parts(27_760_000, 0) + // Minimum execution time: 26_007_000 picoseconds. + Weight::from_parts(26_448_000, 0) .saturating_add(Weight::from_parts(0, 6152)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:3 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `206` - // Estimated: `8621` - // Minimum execution time: 9_307_000 picoseconds. - Weight::from_parts(9_691_000, 0) - .saturating_add(Weight::from_parts(0, 8621)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `11096` + // Minimum execution time: 11_584_000 picoseconds. + Weight::from_parts(12_080_000, 0) + .saturating_add(Weight::from_parts(0, 11096)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `173` - // Estimated: `11063` - // Minimum execution time: 17_607_000 picoseconds. - Weight::from_parts(18_090_000, 0) - .saturating_add(Weight::from_parts(0, 11063)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `170` + // Estimated: `13535` + // Minimum execution time: 19_157_000 picoseconds. + Weight::from_parts(19_513_000, 0) + .saturating_add(Weight::from_parts(0, 13535)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) /// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -347,12 +347,12 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `215` - // Estimated: `11105` - // Minimum execution time: 34_322_000 picoseconds. - Weight::from_parts(35_754_000, 0) - .saturating_add(Weight::from_parts(0, 11105)) - .saturating_add(T::DbWeight::get().reads(10)) + // Measured: `212` + // Estimated: `13577` + // Minimum execution time: 34_878_000 picoseconds. + Weight::from_parts(35_623_000, 0) + .saturating_add(Weight::from_parts(0, 13577)) + .saturating_add(T::DbWeight::get().reads(11)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) @@ -363,8 +363,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `1588` - // Minimum execution time: 4_513_000 picoseconds. - Weight::from_parts(4_754_000, 0) + // Minimum execution time: 3_900_000 picoseconds. + Weight::from_parts(4_161_000, 0) .saturating_add(Weight::from_parts(0, 1588)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -375,10 +375,22 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7740` // Estimated: `11205` - // Minimum execution time: 27_860_000 picoseconds. - Weight::from_parts(28_279_000, 0) + // Minimum execution time: 25_731_000 picoseconds. + Weight::from_parts(26_160_000, 0) .saturating_add(Weight::from_parts(0, 11205)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) + /// Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `160` + // Estimated: `3625` + // Minimum execution time: 37_251_000 picoseconds. + Weight::from_parts(38_075_000, 0) + .saturating_add(Weight::from_parts(0, 3625)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 0f6af1b51f1..ee472f006fa 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -1148,6 +1148,13 @@ impl_runtime_apis! { dest ) } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(ExistentialDeposit::get()), + } + } } use xcm::latest::prelude::*; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm.rs index 5faded42aa8..a732e1a5734 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-r43aesjn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024 // Executed Command: @@ -64,8 +64,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 23_683_000 picoseconds. - Weight::from_parts(24_199_000, 0) + // Minimum execution time: 18_513_000 picoseconds. + Weight::from_parts(19_156_000, 0) .saturating_add(Weight::from_parts(0, 3503)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) @@ -90,8 +90,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `70` // Estimated: `3593` - // Minimum execution time: 89_524_000 picoseconds. - Weight::from_parts(91_401_000, 0) + // Minimum execution time: 88_096_000 picoseconds. + Weight::from_parts(89_732_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) @@ -126,8 +126,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `70` // Estimated: `3593` - // Minimum execution time: 91_890_000 picoseconds. - Weight::from_parts(93_460_000, 0) + // Minimum execution time: 88_239_000 picoseconds. + Weight::from_parts(89_729_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) @@ -148,8 +148,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_152_000 picoseconds. - Weight::from_parts(7_355_000, 0) + // Minimum execution time: 5_955_000 picoseconds. + Weight::from_parts(6_266_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -159,8 +159,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_081_000 picoseconds. - Weight::from_parts(2_258_000, 0) + // Minimum execution time: 1_868_000 picoseconds. + Weight::from_parts(1_961_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -186,8 +186,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 28_067_000 picoseconds. - Weight::from_parts(28_693_000, 0) + // Minimum execution time: 24_388_000 picoseconds. + Weight::from_parts(25_072_000, 0) .saturating_add(Weight::from_parts(0, 3503)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(5)) @@ -212,8 +212,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `255` // Estimated: `3720` - // Minimum execution time: 30_420_000 picoseconds. - Weight::from_parts(31_373_000, 0) + // Minimum execution time: 26_762_000 picoseconds. + Weight::from_parts(27_631_000, 0) .saturating_add(Weight::from_parts(0, 3720)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) @@ -224,45 +224,45 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_087_000 picoseconds. - Weight::from_parts(2_243_000, 0) + // Minimum execution time: 1_856_000 picoseconds. + Weight::from_parts(2_033_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `PolkadotXcm::SupportedVersion` (r:4 w:2) + /// Storage: `PolkadotXcm::SupportedVersion` (r:5 w:2) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `95` - // Estimated: `10985` - // Minimum execution time: 15_142_000 picoseconds. - Weight::from_parts(15_598_000, 0) - .saturating_add(Weight::from_parts(0, 10985)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `89` + // Estimated: `13454` + // Minimum execution time: 17_718_000 picoseconds. + Weight::from_parts(18_208_000, 0) + .saturating_add(Weight::from_parts(0, 13454)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifiers` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `99` - // Estimated: `10989` - // Minimum execution time: 15_041_000 picoseconds. - Weight::from_parts(15_493_000, 0) - .saturating_add(Weight::from_parts(0, 10989)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `93` + // Estimated: `13458` + // Minimum execution time: 17_597_000 picoseconds. + Weight::from_parts(18_090_000, 0) + .saturating_add(Weight::from_parts(0, 13458)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:6 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `106` - // Estimated: `13471` - // Minimum execution time: 16_624_000 picoseconds. - Weight::from_parts(17_031_000, 0) - .saturating_add(Weight::from_parts(0, 13471)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `15946` + // Minimum execution time: 19_533_000 picoseconds. + Weight::from_parts(20_164_000, 0) + .saturating_add(Weight::from_parts(0, 15946)) + .saturating_add(T::DbWeight::get().reads(6)) } /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:2 w:1) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -282,36 +282,36 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `6046` - // Minimum execution time: 26_398_000 picoseconds. - Weight::from_parts(26_847_000, 0) + // Minimum execution time: 24_958_000 picoseconds. + Weight::from_parts(25_628_000, 0) .saturating_add(Weight::from_parts(0, 6046)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:3 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `136` - // Estimated: `8551` - // Minimum execution time: 8_741_000 picoseconds. - Weight::from_parts(8_954_000, 0) - .saturating_add(Weight::from_parts(0, 8551)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `11026` + // Minimum execution time: 12_209_000 picoseconds. + Weight::from_parts(12_612_000, 0) + .saturating_add(Weight::from_parts(0, 11026)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `106` - // Estimated: `10996` - // Minimum execution time: 15_306_000 picoseconds. - Weight::from_parts(15_760_000, 0) - .saturating_add(Weight::from_parts(0, 10996)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `100` + // Estimated: `13465` + // Minimum execution time: 17_844_000 picoseconds. + Weight::from_parts(18_266_000, 0) + .saturating_add(Weight::from_parts(0, 13465)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) /// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -327,12 +327,12 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `112` - // Estimated: `11002` - // Minimum execution time: 33_127_000 picoseconds. - Weight::from_parts(33_938_000, 0) - .saturating_add(Weight::from_parts(0, 11002)) - .saturating_add(T::DbWeight::get().reads(10)) + // Measured: `106` + // Estimated: `13471` + // Minimum execution time: 34_131_000 picoseconds. + Weight::from_parts(34_766_000, 0) + .saturating_add(Weight::from_parts(0, 13471)) + .saturating_add(T::DbWeight::get().reads(11)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) @@ -343,8 +343,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `32` // Estimated: `1517` - // Minimum execution time: 4_290_000 picoseconds. - Weight::from_parts(4_450_000, 0) + // Minimum execution time: 3_525_000 picoseconds. + Weight::from_parts(3_724_000, 0) .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -355,10 +355,22 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7669` // Estimated: `11134` - // Minimum execution time: 26_408_000 picoseconds. - Weight::from_parts(26_900_000, 0) + // Minimum execution time: 24_975_000 picoseconds. + Weight::from_parts(25_517_000, 0) .saturating_add(Weight::from_parts(0, 11134)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) + /// Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `90` + // Estimated: `3555` + // Minimum execution time: 33_761_000 picoseconds. + Weight::from_parts(34_674_000, 0) + .saturating_add(Weight::from_parts(0, 3555)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 206743ba6ac..60d959b4053 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -843,6 +843,13 @@ impl_runtime_apis! { dest ) } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(ExistentialDeposit::get()), + } + } } use xcm::latest::prelude::*; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_xcm.rs index 83e4260e771..a78ff2355ef 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_xcm.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-r43aesjn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-westend-dev")`, DB CACHE: 1024 // Executed Command: @@ -64,8 +64,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 23_219_000 picoseconds. - Weight::from_parts(23_818_000, 0) + // Minimum execution time: 19_527_000 picoseconds. + Weight::from_parts(19_839_000, 0) .saturating_add(Weight::from_parts(0, 3503)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) @@ -88,10 +88,10 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn teleport_assets() -> Weight { // Proof Size summary in bytes: - // Measured: `70` + // Measured: `107` // Estimated: `3593` - // Minimum execution time: 90_120_000 picoseconds. - Weight::from_parts(92_545_000, 0) + // Minimum execution time: 90_938_000 picoseconds. + Weight::from_parts(92_822_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) @@ -124,10 +124,10 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn transfer_assets() -> Weight { // Proof Size summary in bytes: - // Measured: `70` + // Measured: `107` // Estimated: `3593` - // Minimum execution time: 91_339_000 picoseconds. - Weight::from_parts(93_204_000, 0) + // Minimum execution time: 90_133_000 picoseconds. + Weight::from_parts(92_308_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) @@ -148,8 +148,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_976_000 picoseconds. - Weight::from_parts(7_284_000, 0) + // Minimum execution time: 6_205_000 picoseconds. + Weight::from_parts(6_595_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -159,8 +159,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_044_000 picoseconds. - Weight::from_parts(2_223_000, 0) + // Minimum execution time: 1_927_000 picoseconds. + Weight::from_parts(2_062_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -186,8 +186,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 27_778_000 picoseconds. - Weight::from_parts(28_318_000, 0) + // Minimum execution time: 25_078_000 picoseconds. + Weight::from_parts(25_782_000, 0) .saturating_add(Weight::from_parts(0, 3503)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(5)) @@ -212,8 +212,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `255` // Estimated: `3720` - // Minimum execution time: 30_446_000 picoseconds. - Weight::from_parts(31_925_000, 0) + // Minimum execution time: 28_188_000 picoseconds. + Weight::from_parts(28_826_000, 0) .saturating_add(Weight::from_parts(0, 3720)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) @@ -224,45 +224,45 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_037_000 picoseconds. - Weight::from_parts(2_211_000, 0) + // Minimum execution time: 1_886_000 picoseconds. + Weight::from_parts(1_991_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `PolkadotXcm::SupportedVersion` (r:4 w:2) + /// Storage: `PolkadotXcm::SupportedVersion` (r:5 w:2) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `95` - // Estimated: `10985` - // Minimum execution time: 15_620_000 picoseconds. - Weight::from_parts(15_984_000, 0) - .saturating_add(Weight::from_parts(0, 10985)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `89` + // Estimated: `13454` + // Minimum execution time: 17_443_000 picoseconds. + Weight::from_parts(17_964_000, 0) + .saturating_add(Weight::from_parts(0, 13454)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifiers` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `99` - // Estimated: `10989` - // Minimum execution time: 15_689_000 picoseconds. - Weight::from_parts(16_093_000, 0) - .saturating_add(Weight::from_parts(0, 10989)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `93` + // Estimated: `13458` + // Minimum execution time: 17_357_000 picoseconds. + Weight::from_parts(18_006_000, 0) + .saturating_add(Weight::from_parts(0, 13458)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:6 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `106` - // Estimated: `13471` - // Minimum execution time: 16_946_000 picoseconds. - Weight::from_parts(17_192_000, 0) - .saturating_add(Weight::from_parts(0, 13471)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `15946` + // Minimum execution time: 18_838_000 picoseconds. + Weight::from_parts(19_688_000, 0) + .saturating_add(Weight::from_parts(0, 15946)) + .saturating_add(T::DbWeight::get().reads(6)) } /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:2 w:1) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -282,36 +282,36 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `6046` - // Minimum execution time: 27_164_000 picoseconds. - Weight::from_parts(27_760_000, 0) + // Minimum execution time: 25_517_000 picoseconds. + Weight::from_parts(26_131_000, 0) .saturating_add(Weight::from_parts(0, 6046)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:3 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `136` - // Estimated: `8551` - // Minimum execution time: 8_689_000 picoseconds. - Weight::from_parts(8_874_000, 0) - .saturating_add(Weight::from_parts(0, 8551)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `11026` + // Minimum execution time: 11_587_000 picoseconds. + Weight::from_parts(11_963_000, 0) + .saturating_add(Weight::from_parts(0, 11026)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `106` - // Estimated: `10996` - // Minimum execution time: 15_944_000 picoseconds. - Weight::from_parts(16_381_000, 0) - .saturating_add(Weight::from_parts(0, 10996)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `100` + // Estimated: `13465` + // Minimum execution time: 17_490_000 picoseconds. + Weight::from_parts(18_160_000, 0) + .saturating_add(Weight::from_parts(0, 13465)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) /// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -327,12 +327,12 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `112` - // Estimated: `11002` - // Minimum execution time: 33_826_000 picoseconds. - Weight::from_parts(34_784_000, 0) - .saturating_add(Weight::from_parts(0, 11002)) - .saturating_add(T::DbWeight::get().reads(10)) + // Measured: `106` + // Estimated: `13471` + // Minimum execution time: 34_088_000 picoseconds. + Weight::from_parts(34_598_000, 0) + .saturating_add(Weight::from_parts(0, 13471)) + .saturating_add(T::DbWeight::get().reads(11)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) @@ -343,8 +343,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `32` // Estimated: `1517` - // Minimum execution time: 4_257_000 picoseconds. - Weight::from_parts(4_383_000, 0) + // Minimum execution time: 3_566_000 picoseconds. + Weight::from_parts(3_754_000, 0) .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -355,10 +355,22 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7669` // Estimated: `11134` - // Minimum execution time: 26_924_000 picoseconds. - Weight::from_parts(27_455_000, 0) + // Minimum execution time: 25_078_000 picoseconds. + Weight::from_parts(25_477_000, 0) .saturating_add(Weight::from_parts(0, 11134)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) + /// Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `90` + // Estimated: `3555` + // Minimum execution time: 34_661_000 picoseconds. + Weight::from_parts(35_411_000, 0) + .saturating_add(Weight::from_parts(0, 3555)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index 3ed9d6e8e16..9a88ca174df 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -1032,6 +1032,13 @@ impl_runtime_apis! { dest ) } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(ExistentialDeposit::get()), + } + } } let whitelist: Vec = vec![ diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_xcm.rs index 50dfbffde01..5d427d85004 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_xcm.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-r43aesjn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("collectives-westend-dev")`, DB CACHE: 1024 // Executed Command: @@ -64,8 +64,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3610` - // Minimum execution time: 24_540_000 picoseconds. - Weight::from_parts(25_439_000, 0) + // Minimum execution time: 21_813_000 picoseconds. + Weight::from_parts(22_332_000, 0) .saturating_add(Weight::from_parts(0, 3610)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) @@ -90,8 +90,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `214` // Estimated: `3679` - // Minimum execution time: 86_614_000 picoseconds. - Weight::from_parts(88_884_000, 0) + // Minimum execution time: 93_243_000 picoseconds. + Weight::from_parts(95_650_000, 0) .saturating_add(Weight::from_parts(0, 3679)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) @@ -126,8 +126,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `214` // Estimated: `3679` - // Minimum execution time: 87_915_000 picoseconds. - Weight::from_parts(90_219_000, 0) + // Minimum execution time: 96_199_000 picoseconds. + Weight::from_parts(98_620_000, 0) .saturating_add(Weight::from_parts(0, 3679)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) @@ -148,8 +148,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_872_000 picoseconds. - Weight::from_parts(7_110_000, 0) + // Minimum execution time: 6_442_000 picoseconds. + Weight::from_parts(6_682_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -159,8 +159,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_009_000 picoseconds. - Weight::from_parts(2_163_000, 0) + // Minimum execution time: 1_833_000 picoseconds. + Weight::from_parts(1_973_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -186,8 +186,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3610` - // Minimum execution time: 28_858_000 picoseconds. - Weight::from_parts(29_355_000, 0) + // Minimum execution time: 27_318_000 picoseconds. + Weight::from_parts(28_224_000, 0) .saturating_add(Weight::from_parts(0, 3610)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(5)) @@ -212,8 +212,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `363` // Estimated: `3828` - // Minimum execution time: 30_598_000 picoseconds. - Weight::from_parts(31_168_000, 0) + // Minimum execution time: 29_070_000 picoseconds. + Weight::from_parts(30_205_000, 0) .saturating_add(Weight::from_parts(0, 3828)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) @@ -224,45 +224,45 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_090_000 picoseconds. - Weight::from_parts(2_253_000, 0) + // Minimum execution time: 1_904_000 picoseconds. + Weight::from_parts(2_033_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `PolkadotXcm::SupportedVersion` (r:4 w:2) + /// Storage: `PolkadotXcm::SupportedVersion` (r:5 w:2) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `162` - // Estimated: `11052` - // Minimum execution time: 16_133_000 picoseconds. - Weight::from_parts(16_433_000, 0) - .saturating_add(Weight::from_parts(0, 11052)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `159` + // Estimated: `13524` + // Minimum execution time: 18_348_000 picoseconds. + Weight::from_parts(18_853_000, 0) + .saturating_add(Weight::from_parts(0, 13524)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifiers` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `166` - // Estimated: `11056` - // Minimum execution time: 16_012_000 picoseconds. - Weight::from_parts(16_449_000, 0) - .saturating_add(Weight::from_parts(0, 11056)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `163` + // Estimated: `13528` + // Minimum execution time: 17_964_000 picoseconds. + Weight::from_parts(18_548_000, 0) + .saturating_add(Weight::from_parts(0, 13528)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:6 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `173` - // Estimated: `13538` - // Minimum execution time: 17_922_000 picoseconds. - Weight::from_parts(18_426_000, 0) - .saturating_add(Weight::from_parts(0, 13538)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `16013` + // Minimum execution time: 19_708_000 picoseconds. + Weight::from_parts(20_157_000, 0) + .saturating_add(Weight::from_parts(0, 16013)) + .saturating_add(T::DbWeight::get().reads(6)) } /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:2 w:1) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -282,36 +282,36 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `212` // Estimated: `6152` - // Minimum execution time: 27_280_000 picoseconds. - Weight::from_parts(28_026_000, 0) + // Minimum execution time: 26_632_000 picoseconds. + Weight::from_parts(27_314_000, 0) .saturating_add(Weight::from_parts(0, 6152)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:3 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `206` - // Estimated: `8621` - // Minimum execution time: 9_387_000 picoseconds. - Weight::from_parts(9_644_000, 0) - .saturating_add(Weight::from_parts(0, 8621)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `11096` + // Minimum execution time: 11_929_000 picoseconds. + Weight::from_parts(12_304_000, 0) + .saturating_add(Weight::from_parts(0, 11096)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `173` - // Estimated: `11063` - // Minimum execution time: 16_649_000 picoseconds. - Weight::from_parts(17_025_000, 0) - .saturating_add(Weight::from_parts(0, 11063)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `170` + // Estimated: `13535` + // Minimum execution time: 18_599_000 picoseconds. + Weight::from_parts(19_195_000, 0) + .saturating_add(Weight::from_parts(0, 13535)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) /// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -327,12 +327,12 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `215` - // Estimated: `11105` - // Minimum execution time: 34_355_000 picoseconds. - Weight::from_parts(35_295_000, 0) - .saturating_add(Weight::from_parts(0, 11105)) - .saturating_add(T::DbWeight::get().reads(10)) + // Measured: `212` + // Estimated: `13577` + // Minimum execution time: 35_524_000 picoseconds. + Weight::from_parts(36_272_000, 0) + .saturating_add(Weight::from_parts(0, 13577)) + .saturating_add(T::DbWeight::get().reads(11)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) @@ -343,8 +343,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `1588` - // Minimum execution time: 4_527_000 picoseconds. - Weight::from_parts(4_699_000, 0) + // Minimum execution time: 4_044_000 picoseconds. + Weight::from_parts(4_238_000, 0) .saturating_add(Weight::from_parts(0, 1588)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -355,10 +355,22 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7740` // Estimated: `11205` - // Minimum execution time: 27_011_000 picoseconds. - Weight::from_parts(27_398_000, 0) + // Minimum execution time: 25_741_000 picoseconds. + Weight::from_parts(26_301_000, 0) .saturating_add(Weight::from_parts(0, 11205)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) + /// Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `160` + // Estimated: `3625` + // Minimum execution time: 35_925_000 picoseconds. + Weight::from_parts(36_978_000, 0) + .saturating_add(Weight::from_parts(0, 3625)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index c4df5b9a565..c73d2225ebd 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -764,6 +764,13 @@ impl_runtime_apis! { dest ) } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(EXISTENTIAL_DEPOSIT), + } + } } let whitelist: Vec = vec![ diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index 0cdfebce742..d95e68d85c4 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -740,6 +740,13 @@ impl_runtime_apis! { // Reserve transfers are disabled None } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(ExistentialDeposit::get()), + } + } } parameter_types! { diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs index 0e34cba4aaf..c5d315467c1 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs @@ -16,26 +16,24 @@ //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot-parachain +// target/production/polkadot-parachain // benchmark // pallet -// --chain=coretime-rococo-dev -// --wasm-execution=compiled -// --pallet=pallet_xcm -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* // --steps=50 // --repeat=20 -// --json +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_xcm +// --chain=coretime-rococo-dev // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -64,8 +62,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 22_669_000 picoseconds. - Weight::from_parts(23_227_000, 0) + // Minimum execution time: 35_051_000 picoseconds. + Weight::from_parts(35_200_000, 0) .saturating_add(Weight::from_parts(0, 3539)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -86,8 +84,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `3571` - // Minimum execution time: 64_486_000 picoseconds. - Weight::from_parts(65_247_000, 0) + // Minimum execution time: 56_235_000 picoseconds. + Weight::from_parts(58_178_000, 0) .saturating_add(Weight::from_parts(0, 3571)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) @@ -128,8 +126,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_020_000 picoseconds. - Weight::from_parts(7_300_000, 0) + // Minimum execution time: 6_226_000 picoseconds. + Weight::from_parts(6_403_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -139,8 +137,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_022_000 picoseconds. - Weight::from_parts(2_141_000, 0) + // Minimum execution time: 2_020_000 picoseconds. + Weight::from_parts(2_100_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -164,8 +162,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 26_893_000 picoseconds. - Weight::from_parts(27_497_000, 0) + // Minimum execution time: 24_387_000 picoseconds. + Weight::from_parts(24_814_000, 0) .saturating_add(Weight::from_parts(0, 3539)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(5)) @@ -188,8 +186,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `292` // Estimated: `3757` - // Minimum execution time: 29_673_000 picoseconds. - Weight::from_parts(30_693_000, 0) + // Minimum execution time: 27_039_000 picoseconds. + Weight::from_parts(27_693_000, 0) .saturating_add(Weight::from_parts(0, 3757)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) @@ -200,45 +198,45 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_990_000 picoseconds. - Weight::from_parts(2_105_000, 0) + // Minimum execution time: 1_920_000 picoseconds. + Weight::from_parts(2_082_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `PolkadotXcm::SupportedVersion` (r:4 w:2) + /// Storage: `PolkadotXcm::SupportedVersion` (r:5 w:2) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `95` - // Estimated: `10985` - // Minimum execution time: 14_819_000 picoseconds. - Weight::from_parts(15_180_000, 0) - .saturating_add(Weight::from_parts(0, 10985)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `89` + // Estimated: `13454` + // Minimum execution time: 17_141_000 picoseconds. + Weight::from_parts(17_500_000, 0) + .saturating_add(Weight::from_parts(0, 13454)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifiers` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `99` - // Estimated: `10989` - // Minimum execution time: 14_935_000 picoseconds. - Weight::from_parts(15_335_000, 0) - .saturating_add(Weight::from_parts(0, 10989)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `93` + // Estimated: `13458` + // Minimum execution time: 17_074_000 picoseconds. + Weight::from_parts(17_431_000, 0) + .saturating_add(Weight::from_parts(0, 13458)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:6 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `106` - // Estimated: `13471` - // Minimum execution time: 16_278_000 picoseconds. - Weight::from_parts(16_553_000, 0) - .saturating_add(Weight::from_parts(0, 13471)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `15946` + // Minimum execution time: 19_139_000 picoseconds. + Weight::from_parts(19_474_000, 0) + .saturating_add(Weight::from_parts(0, 15946)) + .saturating_add(T::DbWeight::get().reads(6)) } /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:2 w:1) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -256,36 +254,36 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `142` // Estimated: `6082` - // Minimum execution time: 26_360_000 picoseconds. - Weight::from_parts(26_868_000, 0) + // Minimum execution time: 24_346_000 picoseconds. + Weight::from_parts(25_318_000, 0) .saturating_add(Weight::from_parts(0, 6082)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:3 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `136` - // Estimated: `8551` - // Minimum execution time: 8_615_000 picoseconds. - Weight::from_parts(8_903_000, 0) - .saturating_add(Weight::from_parts(0, 8551)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `11026` + // Minimum execution time: 11_777_000 picoseconds. + Weight::from_parts(12_051_000, 0) + .saturating_add(Weight::from_parts(0, 11026)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `106` - // Estimated: `10996` - // Minimum execution time: 15_284_000 picoseconds. - Weight::from_parts(15_504_000, 0) - .saturating_add(Weight::from_parts(0, 10996)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `100` + // Estimated: `13465` + // Minimum execution time: 17_538_000 picoseconds. + Weight::from_parts(17_832_000, 0) + .saturating_add(Weight::from_parts(0, 13465)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -299,12 +297,12 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `148` - // Estimated: `11038` - // Minimum execution time: 32_675_000 picoseconds. - Weight::from_parts(33_816_000, 0) - .saturating_add(Weight::from_parts(0, 11038)) - .saturating_add(T::DbWeight::get().reads(9)) + // Measured: `142` + // Estimated: `13507` + // Minimum execution time: 33_623_000 picoseconds. + Weight::from_parts(34_186_000, 0) + .saturating_add(Weight::from_parts(0, 13507)) + .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) @@ -315,8 +313,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `32` // Estimated: `1517` - // Minimum execution time: 4_058_000 picoseconds. - Weight::from_parts(4_170_000, 0) + // Minimum execution time: 3_363_000 picoseconds. + Weight::from_parts(3_511_000, 0) .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -327,10 +325,22 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7669` // Estimated: `11134` - // Minimum execution time: 25_375_000 picoseconds. - Weight::from_parts(26_026_000, 0) + // Minimum execution time: 23_969_000 picoseconds. + Weight::from_parts(24_347_000, 0) .saturating_add(Weight::from_parts(0, 11134)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) + /// Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `90` + // Estimated: `3555` + // Minimum execution time: 34_071_000 picoseconds. + Weight::from_parts(35_031_000, 0) + .saturating_add(Weight::from_parts(0, 3555)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index 7797329b526..4b9b180321d 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -731,6 +731,13 @@ impl_runtime_apis! { // Reserve transfers are disabled None } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(ExistentialDeposit::get()), + } + } } parameter_types! { diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_xcm.rs index d821a581b0d..0082db3099d 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_xcm.rs @@ -17,25 +17,23 @@ //! Autogenerated weights for `pallet_xcm` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-westend-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot-parachain +// target/production/polkadot-parachain // benchmark // pallet -// --chain=coretime-westend-dev -// --wasm-execution=compiled -// --pallet=pallet_xcm -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* // --steps=50 // --repeat=20 -// --json +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_xcm +// --chain=coretime-westend-dev // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/ @@ -64,8 +62,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 17_946_000 picoseconds. - Weight::from_parts(18_398_000, 0) + // Minimum execution time: 18_410_000 picoseconds. + Weight::from_parts(18_657_000, 0) .saturating_add(Weight::from_parts(0, 3539)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -86,8 +84,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `3571` - // Minimum execution time: 47_982_000 picoseconds. - Weight::from_parts(49_215_000, 0) + // Minimum execution time: 56_616_000 picoseconds. + Weight::from_parts(57_751_000, 0) .saturating_add(Weight::from_parts(0, 3571)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) @@ -128,8 +126,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_042_000 picoseconds. - Weight::from_parts(6_257_000, 0) + // Minimum execution time: 6_014_000 picoseconds. + Weight::from_parts(6_412_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -139,8 +137,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_845_000 picoseconds. - Weight::from_parts(1_993_000, 0) + // Minimum execution time: 1_844_000 picoseconds. + Weight::from_parts(1_957_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -164,8 +162,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 24_062_000 picoseconds. - Weight::from_parts(24_666_000, 0) + // Minimum execution time: 24_067_000 picoseconds. + Weight::from_parts(24_553_000, 0) .saturating_add(Weight::from_parts(0, 3539)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(5)) @@ -188,8 +186,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `292` // Estimated: `3757` - // Minimum execution time: 26_486_000 picoseconds. - Weight::from_parts(27_528_000, 0) + // Minimum execution time: 27_023_000 picoseconds. + Weight::from_parts(27_620_000, 0) .saturating_add(Weight::from_parts(0, 3757)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) @@ -200,8 +198,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_881_000 picoseconds. - Weight::from_parts(2_008_000, 0) + // Minimum execution time: 1_866_000 picoseconds. + Weight::from_parts(1_984_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -211,8 +209,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `89` // Estimated: `13454` - // Minimum execution time: 15_971_000 picoseconds. - Weight::from_parts(16_455_000, 0) + // Minimum execution time: 16_425_000 picoseconds. + Weight::from_parts(16_680_000, 0) .saturating_add(Weight::from_parts(0, 13454)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -223,8 +221,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `93` // Estimated: `13458` - // Minimum execution time: 16_603_000 picoseconds. - Weight::from_parts(17_037_000, 0) + // Minimum execution time: 16_171_000 picoseconds. + Weight::from_parts(16_564_000, 0) .saturating_add(Weight::from_parts(0, 13458)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -235,8 +233,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `15946` - // Minimum execution time: 17_821_000 picoseconds. - Weight::from_parts(18_200_000, 0) + // Minimum execution time: 17_785_000 picoseconds. + Weight::from_parts(18_123_000, 0) .saturating_add(Weight::from_parts(0, 15946)) .saturating_add(T::DbWeight::get().reads(6)) } @@ -256,8 +254,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `142` // Estimated: `6082` - // Minimum execution time: 23_878_000 picoseconds. - Weight::from_parts(24_721_000, 0) + // Minimum execution time: 23_903_000 picoseconds. + Weight::from_parts(24_769_000, 0) .saturating_add(Weight::from_parts(0, 6082)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) @@ -268,8 +266,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `136` // Estimated: `11026` - // Minimum execution time: 10_566_000 picoseconds. - Weight::from_parts(11_053_000, 0) + // Minimum execution time: 10_617_000 picoseconds. + Weight::from_parts(10_843_000, 0) .saturating_add(Weight::from_parts(0, 11026)) .saturating_add(T::DbWeight::get().reads(4)) } @@ -279,8 +277,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `100` // Estimated: `13465` - // Minimum execution time: 16_020_000 picoseconds. - Weight::from_parts(16_619_000, 0) + // Minimum execution time: 16_656_000 picoseconds. + Weight::from_parts(17_106_000, 0) .saturating_add(Weight::from_parts(0, 13465)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -301,8 +299,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `142` // Estimated: `13507` - // Minimum execution time: 32_136_000 picoseconds. - Weight::from_parts(32_610_000, 0) + // Minimum execution time: 31_721_000 picoseconds. + Weight::from_parts(32_547_000, 0) .saturating_add(Weight::from_parts(0, 13507)) .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(4)) @@ -315,8 +313,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `32` // Estimated: `1517` - // Minimum execution time: 3_336_000 picoseconds. - Weight::from_parts(3_434_000, 0) + // Minimum execution time: 3_439_000 picoseconds. + Weight::from_parts(3_619_000, 0) .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -327,10 +325,22 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7669` // Estimated: `11134` - // Minimum execution time: 23_977_000 picoseconds. - Weight::from_parts(24_413_000, 0) + // Minimum execution time: 24_657_000 picoseconds. + Weight::from_parts(24_971_000, 0) .saturating_add(Weight::from_parts(0, 11134)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) + /// Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `90` + // Estimated: `3555` + // Minimum execution time: 34_028_000 picoseconds. + Weight::from_parts(34_697_000, 0) + .saturating_add(Weight::from_parts(0, 3555)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index 616da5519a5..28b8062e0e0 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -710,6 +710,13 @@ impl_runtime_apis! { fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { None } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(ExistentialDeposit::get()), + } + } } use xcm::latest::prelude::*; diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_xcm.rs index 0f793524de9..fabce29b5fd 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_xcm.rs @@ -1,40 +1,41 @@ // Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 +// This file is part of Cumulus. -// 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. +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm4`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("people-kusama-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("people-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./artifacts/polkadot-parachain +// target/production/polkadot-parachain // benchmark // pallet -// --chain=people-kusama-dev -// --execution=wasm -// --wasm-execution=compiled -// --pallet=pallet_xcm -// --extrinsic=* // --steps=50 // --repeat=20 -// --json -// --header=./file_header.txt -// --output=./cumulus/parachains/runtimes/people/people-kusama/src/weights/pallet_xcm.rs +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_xcm +// --chain=people-rococo-dev +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/people/people-rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,57 +48,28 @@ use core::marker::PhantomData; /// Weight functions for `pallet_xcm`. pub struct WeightInfo(PhantomData); impl pallet_xcm::WeightInfo for WeightInfo { - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn send() -> Weight { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 25_931_000 picoseconds. - Weight::from_parts(26_340_000, 0) + // Minimum execution time: 17_830_000 picoseconds. + Weight::from_parts(18_411_000, 0) .saturating_add(Weight::from_parts(0, 3503)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: ParachainInfo ParachainId (r:1 w:0) - /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - fn teleport_assets() -> Weight { - // Proof Size summary in bytes: - // Measured: `32` - // Estimated: `1489` - // Minimum execution time: 25_691_000 picoseconds. - Weight::from_parts(25_971_000, 0) - .saturating_add(Weight::from_parts(0, 1489)) - .saturating_add(T::DbWeight::get().reads(1)) - } - /// Storage: Benchmark Override (r:0 w:0) - /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) - fn reserve_transfer_assets() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. - Weight::from_parts(18_446_744_073_709_551_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:2 w:2) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - /// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) @@ -108,18 +80,38 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn teleport_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `70` + // Estimated: `3535` + // Minimum execution time: 55_456_000 picoseconds. + Weight::from_parts(56_808_000, 0) + .saturating_add(Weight::from_parts(0, 3535)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn reserve_transfer_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) fn transfer_assets() -> Weight { // Proof Size summary in bytes: - // Measured: `496` - // Estimated: `6208` - // Minimum execution time: 146_932_000 picoseconds. - Weight::from_parts(153_200_000, 0) - .saturating_add(Weight::from_parts(0, 6208)) - .saturating_add(T::DbWeight::get().reads(12)) - .saturating_add(T::DbWeight::get().writes(7)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: Benchmark Override (r:0 w:0) - /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) fn execute() -> Weight { // Proof Size summary in bytes: // Measured: `0` @@ -128,189 +120,189 @@ impl pallet_xcm::WeightInfo for WeightInfo { Weight::from_parts(18_446_744_073_709_551_000, 0) .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: PolkadotXcm SupportedVersion (r:0 w:1) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::SupportedVersion` (r:0 w:1) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_xcm_version() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_572_000 picoseconds. - Weight::from_parts(9_924_000, 0) + // Minimum execution time: 5_996_000 picoseconds. + Weight::from_parts(6_154_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: PolkadotXcm SafeXcmVersion (r:0 w:1) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:0 w:1) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn force_default_xcm_version() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_997_000 picoseconds. - Weight::from_parts(3_136_000, 0) + // Minimum execution time: 1_768_000 picoseconds. + Weight::from_parts(1_914_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: PolkadotXcm VersionNotifiers (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionNotifiers (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm QueryCounter (r:1 w:1) - /// Proof Skipped: PolkadotXcm QueryCounter (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm Queries (r:0 w:1) - /// Proof Skipped: PolkadotXcm Queries (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) + /// Proof: `PolkadotXcm::QueryCounter` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::Queries` (r:0 w:1) + /// Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_subscribe_version_notify() -> Weight { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 30_271_000 picoseconds. - Weight::from_parts(30_819_000, 0) + // Minimum execution time: 24_120_000 picoseconds. + Weight::from_parts(24_745_000, 0) .saturating_add(Weight::from_parts(0, 3503)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(5)) } - /// Storage: PolkadotXcm VersionNotifiers (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionNotifiers (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm Queries (r:0 w:1) - /// Proof Skipped: PolkadotXcm Queries (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::Queries` (r:0 w:1) + /// Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_unsubscribe_version_notify() -> Weight { // Proof Size summary in bytes: - // Measured: `220` - // Estimated: `3685` - // Minimum execution time: 32_302_000 picoseconds. - Weight::from_parts(32_807_000, 0) - .saturating_add(Weight::from_parts(0, 3685)) + // Measured: `255` + // Estimated: `3720` + // Minimum execution time: 26_630_000 picoseconds. + Weight::from_parts(27_289_000, 0) + .saturating_add(Weight::from_parts(0, 3720)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: PolkadotXcm XcmExecutionSuspended (r:0 w:1) - /// Proof Skipped: PolkadotXcm XcmExecutionSuspended (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::XcmExecutionSuspended` (r:0 w:1) + /// Proof: `PolkadotXcm::XcmExecutionSuspended` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn force_suspension() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_960_000 picoseconds. - Weight::from_parts(3_094_000, 0) + // Minimum execution time: 1_821_000 picoseconds. + Weight::from_parts(1_946_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: PolkadotXcm SupportedVersion (r:4 w:2) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::SupportedVersion` (r:5 w:2) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `95` - // Estimated: `10985` - // Minimum execution time: 14_877_000 picoseconds. - Weight::from_parts(15_296_000, 0) - .saturating_add(Weight::from_parts(0, 10985)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `89` + // Estimated: `13454` + // Minimum execution time: 16_586_000 picoseconds. + Weight::from_parts(16_977_000, 0) + .saturating_add(Weight::from_parts(0, 13454)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: PolkadotXcm VersionNotifiers (r:4 w:2) - /// Proof Skipped: PolkadotXcm VersionNotifiers (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:5 w:2) + /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `99` - // Estimated: `10989` - // Minimum execution time: 14_835_000 picoseconds. - Weight::from_parts(15_115_000, 0) - .saturating_add(Weight::from_parts(0, 10989)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `93` + // Estimated: `13458` + // Minimum execution time: 16_923_000 picoseconds. + Weight::from_parts(17_415_000, 0) + .saturating_add(Weight::from_parts(0, 13458)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:5 w:0) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:6 w:0) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `106` - // Estimated: `13471` - // Minimum execution time: 15_368_000 picoseconds. - Weight::from_parts(15_596_000, 0) - .saturating_add(Weight::from_parts(0, 13471)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `15946` + // Minimum execution time: 18_596_000 picoseconds. + Weight::from_parts(18_823_000, 0) + .saturating_add(Weight::from_parts(0, 15946)) + .saturating_add(T::DbWeight::get().reads(6)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:2 w:1) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:2 w:1) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn notify_current_targets() -> Weight { // Proof Size summary in bytes: // Measured: `106` // Estimated: `6046` - // Minimum execution time: 28_025_000 picoseconds. - Weight::from_parts(28_524_000, 0) + // Minimum execution time: 23_817_000 picoseconds. + Weight::from_parts(24_520_000, 0) .saturating_add(Weight::from_parts(0, 6046)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:3 w:0) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:0) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `136` - // Estimated: `8551` - // Minimum execution time: 8_166_000 picoseconds. - Weight::from_parts(8_314_000, 0) - .saturating_add(Weight::from_parts(0, 8551)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `11026` + // Minimum execution time: 11_042_000 picoseconds. + Weight::from_parts(11_578_000, 0) + .saturating_add(Weight::from_parts(0, 11026)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:4 w:2) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `106` - // Estimated: `10996` - // Minimum execution time: 14_871_000 picoseconds. - Weight::from_parts(15_374_000, 0) - .saturating_add(Weight::from_parts(0, 10996)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `100` + // Estimated: `13465` + // Minimum execution time: 17_306_000 picoseconds. + Weight::from_parts(17_817_000, 0) + .saturating_add(Weight::from_parts(0, 13465)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:4 w:2) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `112` - // Estimated: `11002` - // Minimum execution time: 33_611_000 picoseconds. - Weight::from_parts(34_008_000, 0) - .saturating_add(Weight::from_parts(0, 11002)) - .saturating_add(T::DbWeight::get().reads(9)) + // Measured: `106` + // Estimated: `13471` + // Minimum execution time: 32_141_000 picoseconds. + Weight::from_parts(32_954_000, 0) + .saturating_add(Weight::from_parts(0, 13471)) + .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) @@ -319,11 +311,11 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn new_query() -> Weight { // Proof Size summary in bytes: - // Measured: `103` - // Estimated: `1588` - // Minimum execution time: 5_496_000 picoseconds. - Weight::from_parts(5_652_000, 0) - .saturating_add(Weight::from_parts(0, 1588)) + // Measured: `32` + // Estimated: `1517` + // Minimum execution time: 3_410_000 picoseconds. + Weight::from_parts(3_556_000, 0) + .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -331,11 +323,23 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn take_response() -> Weight { // Proof Size summary in bytes: - // Measured: `7740` - // Estimated: `11205` - // Minimum execution time: 26_140_000 picoseconds. - Weight::from_parts(26_824_000, 0) - .saturating_add(Weight::from_parts(0, 11205)) + // Measured: `7669` + // Estimated: `11134` + // Minimum execution time: 25_021_000 picoseconds. + Weight::from_parts(25_240_000, 0) + .saturating_add(Weight::from_parts(0, 11134)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) + /// Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `90` + // Estimated: `3555` + // Minimum execution time: 33_801_000 picoseconds. + Weight::from_parts(34_655_000, 0) + .saturating_add(Weight::from_parts(0, 3555)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index 9f572330cac..b2b32445613 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -710,6 +710,13 @@ impl_runtime_apis! { fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { None } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(ExistentialDeposit::get()), + } + } } use xcm::latest::prelude::*; diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_xcm.rs index d3b60471b85..c337289243b 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_xcm.rs @@ -1,40 +1,41 @@ // Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 +// This file is part of Cumulus. -// 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. +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm4`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("people-polkadot-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("people-westend-dev")`, DB CACHE: 1024 // Executed Command: -// ./artifacts/polkadot-parachain +// target/production/polkadot-parachain // benchmark // pallet -// --chain=people-polkadot-dev -// --execution=wasm -// --wasm-execution=compiled -// --pallet=pallet_xcm -// --extrinsic=* // --steps=50 // --repeat=20 -// --json -// --header=./file_header.txt -// --output=./cumulus/parachains/runtimes/people/people-polkadot/src/weights/pallet_xcm.rs +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_xcm +// --chain=people-westend-dev +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/people/people-westend/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,57 +48,28 @@ use core::marker::PhantomData; /// Weight functions for `pallet_xcm`. pub struct WeightInfo(PhantomData); impl pallet_xcm::WeightInfo for WeightInfo { - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn send() -> Weight { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 25_783_000 picoseconds. - Weight::from_parts(26_398_000, 0) + // Minimum execution time: 17_856_000 picoseconds. + Weight::from_parts(18_473_000, 0) .saturating_add(Weight::from_parts(0, 3503)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: ParachainInfo ParachainId (r:1 w:0) - /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - fn teleport_assets() -> Weight { - // Proof Size summary in bytes: - // Measured: `32` - // Estimated: `1489` - // Minimum execution time: 25_511_000 picoseconds. - Weight::from_parts(26_120_000, 0) - .saturating_add(Weight::from_parts(0, 1489)) - .saturating_add(T::DbWeight::get().reads(1)) - } - /// Storage: Benchmark Override (r:0 w:0) - /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) - fn reserve_transfer_assets() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. - Weight::from_parts(18_446_744_073_709_551_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:2 w:2) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - /// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) @@ -108,18 +80,38 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn teleport_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `70` + // Estimated: `3535` + // Minimum execution time: 56_112_000 picoseconds. + Weight::from_parts(57_287_000, 0) + .saturating_add(Weight::from_parts(0, 3535)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn reserve_transfer_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) fn transfer_assets() -> Weight { // Proof Size summary in bytes: - // Measured: `496` - // Estimated: `6208` - // Minimum execution time: 146_932_000 picoseconds. - Weight::from_parts(153_200_000, 0) - .saturating_add(Weight::from_parts(0, 6208)) - .saturating_add(T::DbWeight::get().reads(12)) - .saturating_add(T::DbWeight::get().writes(7)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: Benchmark Override (r:0 w:0) - /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) fn execute() -> Weight { // Proof Size summary in bytes: // Measured: `0` @@ -128,189 +120,189 @@ impl pallet_xcm::WeightInfo for WeightInfo { Weight::from_parts(18_446_744_073_709_551_000, 0) .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: PolkadotXcm SupportedVersion (r:0 w:1) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::SupportedVersion` (r:0 w:1) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_xcm_version() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_707_000 picoseconds. - Weight::from_parts(9_874_000, 0) + // Minimum execution time: 6_186_000 picoseconds. + Weight::from_parts(6_420_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: PolkadotXcm SafeXcmVersion (r:0 w:1) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:0 w:1) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn force_default_xcm_version() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_073_000 picoseconds. - Weight::from_parts(3_183_000, 0) + // Minimum execution time: 1_824_000 picoseconds. + Weight::from_parts(1_999_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: PolkadotXcm VersionNotifiers (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionNotifiers (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm QueryCounter (r:1 w:1) - /// Proof Skipped: PolkadotXcm QueryCounter (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm Queries (r:0 w:1) - /// Proof Skipped: PolkadotXcm Queries (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) + /// Proof: `PolkadotXcm::QueryCounter` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::Queries` (r:0 w:1) + /// Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_subscribe_version_notify() -> Weight { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 30_999_000 picoseconds. - Weight::from_parts(31_641_000, 0) + // Minimum execution time: 23_833_000 picoseconds. + Weight::from_parts(24_636_000, 0) .saturating_add(Weight::from_parts(0, 3503)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(5)) } - /// Storage: PolkadotXcm VersionNotifiers (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionNotifiers (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm Queries (r:0 w:1) - /// Proof Skipped: PolkadotXcm Queries (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::Queries` (r:0 w:1) + /// Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_unsubscribe_version_notify() -> Weight { // Proof Size summary in bytes: - // Measured: `220` - // Estimated: `3685` - // Minimum execution time: 33_036_000 picoseconds. - Weight::from_parts(33_596_000, 0) - .saturating_add(Weight::from_parts(0, 3685)) + // Measured: `255` + // Estimated: `3720` + // Minimum execution time: 26_557_000 picoseconds. + Weight::from_parts(27_275_000, 0) + .saturating_add(Weight::from_parts(0, 3720)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: PolkadotXcm XcmExecutionSuspended (r:0 w:1) - /// Proof Skipped: PolkadotXcm XcmExecutionSuspended (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::XcmExecutionSuspended` (r:0 w:1) + /// Proof: `PolkadotXcm::XcmExecutionSuspended` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn force_suspension() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_035_000 picoseconds. - Weight::from_parts(3_154_000, 0) + // Minimum execution time: 1_921_000 picoseconds. + Weight::from_parts(2_040_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: PolkadotXcm SupportedVersion (r:4 w:2) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::SupportedVersion` (r:5 w:2) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `95` - // Estimated: `10985` - // Minimum execution time: 14_805_000 picoseconds. - Weight::from_parts(15_120_000, 0) - .saturating_add(Weight::from_parts(0, 10985)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `89` + // Estimated: `13454` + // Minimum execution time: 16_832_000 picoseconds. + Weight::from_parts(17_312_000, 0) + .saturating_add(Weight::from_parts(0, 13454)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: PolkadotXcm VersionNotifiers (r:4 w:2) - /// Proof Skipped: PolkadotXcm VersionNotifiers (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:5 w:2) + /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `99` - // Estimated: `10989` - // Minimum execution time: 14_572_000 picoseconds. - Weight::from_parts(14_909_000, 0) - .saturating_add(Weight::from_parts(0, 10989)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `93` + // Estimated: `13458` + // Minimum execution time: 16_687_000 picoseconds. + Weight::from_parts(17_123_000, 0) + .saturating_add(Weight::from_parts(0, 13458)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:5 w:0) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:6 w:0) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `106` - // Estimated: `13471` - // Minimum execution time: 15_341_000 picoseconds. - Weight::from_parts(15_708_000, 0) - .saturating_add(Weight::from_parts(0, 13471)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `15946` + // Minimum execution time: 18_164_000 picoseconds. + Weight::from_parts(18_580_000, 0) + .saturating_add(Weight::from_parts(0, 15946)) + .saturating_add(T::DbWeight::get().reads(6)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:2 w:1) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:2 w:1) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn notify_current_targets() -> Weight { // Proof Size summary in bytes: // Measured: `106` // Estimated: `6046` - // Minimum execution time: 27_840_000 picoseconds. - Weight::from_parts(28_248_000, 0) + // Minimum execution time: 23_577_000 picoseconds. + Weight::from_parts(24_324_000, 0) .saturating_add(Weight::from_parts(0, 6046)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:3 w:0) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:0) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `136` - // Estimated: `8551` - // Minimum execution time: 8_245_000 picoseconds. - Weight::from_parts(8_523_000, 0) - .saturating_add(Weight::from_parts(0, 8551)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `11026` + // Minimum execution time: 11_014_000 picoseconds. + Weight::from_parts(11_223_000, 0) + .saturating_add(Weight::from_parts(0, 11026)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:4 w:2) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `106` - // Estimated: `10996` - // Minimum execution time: 14_780_000 picoseconds. - Weight::from_parts(15_173_000, 0) - .saturating_add(Weight::from_parts(0, 10996)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `100` + // Estimated: `13465` + // Minimum execution time: 16_887_000 picoseconds. + Weight::from_parts(17_361_000, 0) + .saturating_add(Weight::from_parts(0, 13465)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:4 w:2) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `112` - // Estimated: `11002` - // Minimum execution time: 33_422_000 picoseconds. - Weight::from_parts(34_076_000, 0) - .saturating_add(Weight::from_parts(0, 11002)) - .saturating_add(T::DbWeight::get().reads(9)) + // Measured: `106` + // Estimated: `13471` + // Minimum execution time: 31_705_000 picoseconds. + Weight::from_parts(32_166_000, 0) + .saturating_add(Weight::from_parts(0, 13471)) + .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) @@ -319,11 +311,11 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn new_query() -> Weight { // Proof Size summary in bytes: - // Measured: `103` - // Estimated: `1588` - // Minimum execution time: 5_496_000 picoseconds. - Weight::from_parts(5_652_000, 0) - .saturating_add(Weight::from_parts(0, 1588)) + // Measured: `32` + // Estimated: `1517` + // Minimum execution time: 3_568_000 picoseconds. + Weight::from_parts(3_669_000, 0) + .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -331,11 +323,23 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn take_response() -> Weight { // Proof Size summary in bytes: - // Measured: `7740` - // Estimated: `11205` - // Minimum execution time: 26_140_000 picoseconds. - Weight::from_parts(26_824_000, 0) - .saturating_add(Weight::from_parts(0, 11205)) + // Measured: `7669` + // Estimated: `11134` + // Minimum execution time: 24_823_000 picoseconds. + Weight::from_parts(25_344_000, 0) + .saturating_add(Weight::from_parts(0, 11134)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) + /// Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `90` + // Estimated: `3555` + // Minimum execution time: 34_516_000 picoseconds. + Weight::from_parts(35_478_000, 0) + .saturating_add(Weight::from_parts(0, 3555)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index f3c0c3d6bd8..48395f45238 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -2336,6 +2336,13 @@ sp_api::impl_runtime_apis! { dest ) } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::here()), + fun: Fungible(ExistentialDeposit::get()), + } + } } impl pallet_xcm_benchmarks::Config for Runtime { type XcmConfig = XcmConfig; diff --git a/polkadot/runtime/rococo/src/weights/pallet_xcm.rs b/polkadot/runtime/rococo/src/weights/pallet_xcm.rs index 177407ef708..5544ca44658 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_xcm.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_xcm.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: @@ -48,10 +48,6 @@ use core::marker::PhantomData; /// Weight functions for `pallet_xcm`. pub struct WeightInfo(PhantomData); impl pallet_xcm::WeightInfo for WeightInfo { - fn transfer_assets() -> Weight { - // TODO: run benchmarks - Weight::zero() - } /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) @@ -62,36 +58,80 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn send() -> Weight { // Proof Size summary in bytes: - // Measured: `142` - // Estimated: `3607` - // Minimum execution time: 27_328_000 picoseconds. - Weight::from_parts(27_976_000, 0) - .saturating_add(Weight::from_parts(0, 3607)) + // Measured: `180` + // Estimated: `3645` + // Minimum execution time: 25_043_000 picoseconds. + Weight::from_parts(25_682_000, 0) + .saturating_add(Weight::from_parts(0, 3645)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn teleport_assets() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 16_280_000 picoseconds. - Weight::from_parts(16_904_000, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `180` + // Estimated: `3645` + // Minimum execution time: 107_570_000 picoseconds. + Weight::from_parts(109_878_000, 0) + .saturating_add(Weight::from_parts(0, 3645)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn reserve_transfer_assets() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 15_869_000 picoseconds. - Weight::from_parts(16_264_000, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `232` + // Estimated: `3697` + // Minimum execution time: 106_341_000 picoseconds. + Weight::from_parts(109_135_000, 0) + .saturating_add(Weight::from_parts(0, 3697)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn transfer_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `180` + // Estimated: `3645` + // Minimum execution time: 108_372_000 picoseconds. + Weight::from_parts(112_890_000, 0) + .saturating_add(Weight::from_parts(0, 3645)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) } fn execute() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_923_000 picoseconds. - Weight::from_parts(7_432_000, 0) + // Minimum execution time: 6_957_000 picoseconds. + Weight::from_parts(7_417_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// Storage: `XcmPallet::SupportedVersion` (r:0 w:1) @@ -100,8 +140,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_333_000 picoseconds. - Weight::from_parts(7_566_000, 0) + // Minimum execution time: 7_053_000 picoseconds. + Weight::from_parts(7_462_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -109,8 +149,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_219_000 picoseconds. - Weight::from_parts(2_375_000, 0) + // Minimum execution time: 1_918_000 picoseconds. + Weight::from_parts(2_037_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// Storage: `XcmPallet::VersionNotifiers` (r:1 w:1) @@ -129,11 +169,11 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_subscribe_version_notify() -> Weight { // Proof Size summary in bytes: - // Measured: `142` - // Estimated: `3607` - // Minimum execution time: 30_650_000 picoseconds. - Weight::from_parts(31_683_000, 0) - .saturating_add(Weight::from_parts(0, 3607)) + // Measured: `180` + // Estimated: `3645` + // Minimum execution time: 30_417_000 picoseconds. + Weight::from_parts(31_191_000, 0) + .saturating_add(Weight::from_parts(0, 3645)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(5)) } @@ -151,11 +191,11 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_unsubscribe_version_notify() -> Weight { // Proof Size summary in bytes: - // Measured: `322` - // Estimated: `3787` - // Minimum execution time: 37_666_000 picoseconds. - Weight::from_parts(38_920_000, 0) - .saturating_add(Weight::from_parts(0, 3787)) + // Measured: `360` + // Estimated: `3825` + // Minimum execution time: 36_666_000 picoseconds. + Weight::from_parts(37_779_000, 0) + .saturating_add(Weight::from_parts(0, 3825)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -165,45 +205,45 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_244_000 picoseconds. - Weight::from_parts(2_425_000, 0) + // Minimum execution time: 1_869_000 picoseconds. + Weight::from_parts(2_003_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `XcmPallet::SupportedVersion` (r:4 w:2) + /// Storage: `XcmPallet::SupportedVersion` (r:5 w:2) /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `26` - // Estimated: `10916` - // Minimum execution time: 14_710_000 picoseconds. - Weight::from_parts(15_156_000, 0) - .saturating_add(Weight::from_parts(0, 10916)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `22` + // Estimated: `13387` + // Minimum execution time: 16_188_000 picoseconds. + Weight::from_parts(16_435_000, 0) + .saturating_add(Weight::from_parts(0, 13387)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `XcmPallet::VersionNotifiers` (r:4 w:2) + /// Storage: `XcmPallet::VersionNotifiers` (r:5 w:2) /// Proof: `XcmPallet::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `30` - // Estimated: `10920` - // Minimum execution time: 14_630_000 picoseconds. - Weight::from_parts(15_290_000, 0) - .saturating_add(Weight::from_parts(0, 10920)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `26` + // Estimated: `13391` + // Minimum execution time: 16_431_000 picoseconds. + Weight::from_parts(16_935_000, 0) + .saturating_add(Weight::from_parts(0, 13391)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `XcmPallet::VersionNotifyTargets` (r:5 w:0) + /// Storage: `XcmPallet::VersionNotifyTargets` (r:6 w:0) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `40` - // Estimated: `13405` - // Minimum execution time: 16_686_000 picoseconds. - Weight::from_parts(17_332_000, 0) - .saturating_add(Weight::from_parts(0, 13405)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `15880` + // Minimum execution time: 18_460_000 picoseconds. + Weight::from_parts(18_885_000, 0) + .saturating_add(Weight::from_parts(0, 15880)) + .saturating_add(T::DbWeight::get().reads(6)) } /// Storage: `XcmPallet::VersionNotifyTargets` (r:2 w:1) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -217,38 +257,38 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_current_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `178` - // Estimated: `6118` - // Minimum execution time: 30_180_000 picoseconds. - Weight::from_parts(31_351_000, 0) - .saturating_add(Weight::from_parts(0, 6118)) + // Measured: `216` + // Estimated: `6156` + // Minimum execution time: 29_623_000 picoseconds. + Weight::from_parts(30_661_000, 0) + .saturating_add(Weight::from_parts(0, 6156)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `XcmPallet::VersionNotifyTargets` (r:3 w:0) + /// Storage: `XcmPallet::VersionNotifyTargets` (r:4 w:0) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `69` - // Estimated: `8484` - // Minimum execution time: 9_624_000 picoseconds. - Weight::from_parts(10_029_000, 0) - .saturating_add(Weight::from_parts(0, 8484)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `10959` + // Minimum execution time: 12_043_000 picoseconds. + Weight::from_parts(12_360_000, 0) + .saturating_add(Weight::from_parts(0, 10959)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: `XcmPallet::VersionNotifyTargets` (r:4 w:2) + /// Storage: `XcmPallet::VersionNotifyTargets` (r:5 w:2) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `37` - // Estimated: `10927` - // Minimum execution time: 15_139_000 picoseconds. - Weight::from_parts(15_575_000, 0) - .saturating_add(Weight::from_parts(0, 10927)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `33` + // Estimated: `13398` + // Minimum execution time: 16_511_000 picoseconds. + Weight::from_parts(17_011_000, 0) + .saturating_add(Weight::from_parts(0, 13398)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `XcmPallet::VersionNotifyTargets` (r:4 w:2) + /// Storage: `XcmPallet::VersionNotifyTargets` (r:5 w:2) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -260,12 +300,12 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `182` - // Estimated: `11072` - // Minimum execution time: 37_871_000 picoseconds. - Weight::from_parts(38_940_000, 0) - .saturating_add(Weight::from_parts(0, 11072)) - .saturating_add(T::DbWeight::get().reads(8)) + // Measured: `216` + // Estimated: `13581` + // Minimum execution time: 39_041_000 picoseconds. + Weight::from_parts(39_883_000, 0) + .saturating_add(Weight::from_parts(0, 13581)) + .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `XcmPallet::QueryCounter` (r:1 w:1) @@ -276,8 +316,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `1485` - // Minimum execution time: 2_732_000 picoseconds. - Weight::from_parts(2_892_000, 0) + // Minimum execution time: 2_030_000 picoseconds. + Weight::from_parts(2_150_000, 0) .saturating_add(Weight::from_parts(0, 1485)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -288,10 +328,22 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7576` // Estimated: `11041` - // Minimum execution time: 23_813_000 picoseconds. - Weight::from_parts(24_201_000, 0) + // Minimum execution time: 22_615_000 picoseconds. + Weight::from_parts(23_008_000, 0) .saturating_add(Weight::from_parts(0, 11041)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `XcmPallet::AssetTraps` (r:1 w:1) + /// Proof: `XcmPallet::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `23` + // Estimated: `3488` + // Minimum execution time: 34_438_000 picoseconds. + Weight::from_parts(35_514_000, 0) + .saturating_add(Weight::from_parts(0, 3488)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index a7772303a95..4ac2202b8fc 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -2412,6 +2412,13 @@ sp_api::impl_runtime_apis! { dest ) } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::here()), + fun: Fungible(ExistentialDeposit::get()), + } + } } impl frame_system_benchmarking::Config for Runtime {} impl pallet_nomination_pools_benchmarking::Config for Runtime {} diff --git a/polkadot/runtime/westend/src/weights/pallet_xcm.rs b/polkadot/runtime/westend/src/weights/pallet_xcm.rs index 493acd0f9e7..10725cecf24 100644 --- a/polkadot/runtime/westend/src/weights/pallet_xcm.rs +++ b/polkadot/runtime/westend/src/weights/pallet_xcm.rs @@ -16,26 +16,24 @@ //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// target/production/polkadot // benchmark // pallet -// --chain=westend-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=pallet_xcm // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_xcm +// --chain=westend-dev // --header=./polkadot/file_header.txt // --output=./polkadot/runtime/westend/src/weights/ @@ -50,10 +48,6 @@ use core::marker::PhantomData; /// Weight functions for `pallet_xcm`. pub struct WeightInfo(PhantomData); impl pallet_xcm::WeightInfo for WeightInfo { - fn transfer_assets() -> Weight { - // TODO: run benchmarks - Weight::zero() - } /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) @@ -64,29 +58,73 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn send() -> Weight { // Proof Size summary in bytes: - // Measured: `109` - // Estimated: `3574` - // Minimum execution time: 28_098_000 picoseconds. - Weight::from_parts(28_887_000, 0) - .saturating_add(Weight::from_parts(0, 3574)) + // Measured: `147` + // Estimated: `3612` + // Minimum execution time: 25_725_000 picoseconds. + Weight::from_parts(26_174_000, 0) + .saturating_add(Weight::from_parts(0, 3612)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) } + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn teleport_assets() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 17_609_000 picoseconds. - Weight::from_parts(18_000_000, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `250` + // Estimated: `6196` + // Minimum execution time: 113_140_000 picoseconds. + Weight::from_parts(116_204_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) } + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn reserve_transfer_assets() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 17_007_000 picoseconds. - Weight::from_parts(17_471_000, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `302` + // Estimated: `6196` + // Minimum execution time: 108_571_000 picoseconds. + Weight::from_parts(110_650_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn transfer_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `250` + // Estimated: `6196` + // Minimum execution time: 111_836_000 picoseconds. + Weight::from_parts(114_435_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `Benchmark::Override` (r:0 w:0) /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -104,8 +142,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_444_000 picoseconds. - Weight::from_parts(7_671_000, 0) + // Minimum execution time: 7_160_000 picoseconds. + Weight::from_parts(7_477_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -113,8 +151,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_126_000 picoseconds. - Weight::from_parts(2_253_000, 0) + // Minimum execution time: 1_934_000 picoseconds. + Weight::from_parts(2_053_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// Storage: `XcmPallet::VersionNotifiers` (r:1 w:1) @@ -133,11 +171,11 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_subscribe_version_notify() -> Weight { // Proof Size summary in bytes: - // Measured: `109` - // Estimated: `3574` - // Minimum execution time: 31_318_000 picoseconds. - Weight::from_parts(32_413_000, 0) - .saturating_add(Weight::from_parts(0, 3574)) + // Measured: `147` + // Estimated: `3612` + // Minimum execution time: 31_123_000 picoseconds. + Weight::from_parts(31_798_000, 0) + .saturating_add(Weight::from_parts(0, 3612)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(5)) } @@ -155,11 +193,11 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_unsubscribe_version_notify() -> Weight { // Proof Size summary in bytes: - // Measured: `289` - // Estimated: `3754` - // Minimum execution time: 35_282_000 picoseconds. - Weight::from_parts(35_969_000, 0) - .saturating_add(Weight::from_parts(0, 3754)) + // Measured: `327` + // Estimated: `3792` + // Minimum execution time: 35_175_000 picoseconds. + Weight::from_parts(36_098_000, 0) + .saturating_add(Weight::from_parts(0, 3792)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -169,45 +207,45 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_247_000 picoseconds. - Weight::from_parts(2_381_000, 0) + // Minimum execution time: 1_974_000 picoseconds. + Weight::from_parts(2_096_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `XcmPallet::SupportedVersion` (r:4 w:2) + /// Storage: `XcmPallet::SupportedVersion` (r:5 w:2) /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `26` - // Estimated: `10916` - // Minimum execution time: 14_512_000 picoseconds. - Weight::from_parts(15_042_000, 0) - .saturating_add(Weight::from_parts(0, 10916)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `22` + // Estimated: `13387` + // Minimum execution time: 16_626_000 picoseconds. + Weight::from_parts(17_170_000, 0) + .saturating_add(Weight::from_parts(0, 13387)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `XcmPallet::VersionNotifiers` (r:4 w:2) + /// Storage: `XcmPallet::VersionNotifiers` (r:5 w:2) /// Proof: `XcmPallet::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `30` - // Estimated: `10920` - // Minimum execution time: 14_659_000 picoseconds. - Weight::from_parts(15_164_000, 0) - .saturating_add(Weight::from_parts(0, 10920)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `26` + // Estimated: `13391` + // Minimum execution time: 16_937_000 picoseconds. + Weight::from_parts(17_447_000, 0) + .saturating_add(Weight::from_parts(0, 13391)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `XcmPallet::VersionNotifyTargets` (r:5 w:0) + /// Storage: `XcmPallet::VersionNotifyTargets` (r:6 w:0) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `40` - // Estimated: `13405` - // Minimum execution time: 16_261_000 picoseconds. - Weight::from_parts(16_986_000, 0) - .saturating_add(Weight::from_parts(0, 13405)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `15880` + // Minimum execution time: 19_157_000 picoseconds. + Weight::from_parts(19_659_000, 0) + .saturating_add(Weight::from_parts(0, 15880)) + .saturating_add(T::DbWeight::get().reads(6)) } /// Storage: `XcmPallet::VersionNotifyTargets` (r:2 w:1) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -221,38 +259,38 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_current_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `145` - // Estimated: `6085` - // Minimum execution time: 30_539_000 picoseconds. - Weight::from_parts(31_117_000, 0) - .saturating_add(Weight::from_parts(0, 6085)) + // Measured: `183` + // Estimated: `6123` + // Minimum execution time: 30_699_000 picoseconds. + Weight::from_parts(31_537_000, 0) + .saturating_add(Weight::from_parts(0, 6123)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `XcmPallet::VersionNotifyTargets` (r:3 w:0) + /// Storage: `XcmPallet::VersionNotifyTargets` (r:4 w:0) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `69` - // Estimated: `8484` - // Minimum execution time: 9_463_000 picoseconds. - Weight::from_parts(9_728_000, 0) - .saturating_add(Weight::from_parts(0, 8484)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `10959` + // Minimum execution time: 12_303_000 picoseconds. + Weight::from_parts(12_670_000, 0) + .saturating_add(Weight::from_parts(0, 10959)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: `XcmPallet::VersionNotifyTargets` (r:4 w:2) + /// Storage: `XcmPallet::VersionNotifyTargets` (r:5 w:2) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `37` - // Estimated: `10927` - // Minimum execution time: 15_169_000 picoseconds. - Weight::from_parts(15_694_000, 0) - .saturating_add(Weight::from_parts(0, 10927)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `33` + // Estimated: `13398` + // Minimum execution time: 17_129_000 picoseconds. + Weight::from_parts(17_668_000, 0) + .saturating_add(Weight::from_parts(0, 13398)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `XcmPallet::VersionNotifyTargets` (r:4 w:2) + /// Storage: `XcmPallet::VersionNotifyTargets` (r:5 w:2) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -264,12 +302,12 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `149` - // Estimated: `11039` - // Minimum execution time: 37_549_000 picoseconds. - Weight::from_parts(38_203_000, 0) - .saturating_add(Weight::from_parts(0, 11039)) - .saturating_add(T::DbWeight::get().reads(8)) + // Measured: `183` + // Estimated: `13548` + // Minimum execution time: 39_960_000 picoseconds. + Weight::from_parts(41_068_000, 0) + .saturating_add(Weight::from_parts(0, 13548)) + .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `XcmPallet::QueryCounter` (r:1 w:1) @@ -280,8 +318,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `1485` - // Minimum execution time: 2_947_000 picoseconds. - Weight::from_parts(3_117_000, 0) + // Minimum execution time: 2_333_000 picoseconds. + Weight::from_parts(2_504_000, 0) .saturating_add(Weight::from_parts(0, 1485)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -292,10 +330,22 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7576` // Estimated: `11041` - // Minimum execution time: 24_595_000 picoseconds. - Weight::from_parts(24_907_000, 0) + // Minimum execution time: 22_932_000 picoseconds. + Weight::from_parts(23_307_000, 0) .saturating_add(Weight::from_parts(0, 11041)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `XcmPallet::AssetTraps` (r:1 w:1) + /// Proof: `XcmPallet::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `23` + // Estimated: `3488` + // Minimum execution time: 34_558_000 picoseconds. + Weight::from_parts(35_299_000, 0) + .saturating_add(Weight::from_parts(0, 3488)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/polkadot/xcm/pallet-xcm/src/benchmarking.rs b/polkadot/xcm/pallet-xcm/src/benchmarking.rs index e3ea2fb8c06..ed42f93692b 100644 --- a/polkadot/xcm/pallet-xcm/src/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm/src/benchmarking.rs @@ -79,6 +79,13 @@ pub trait Config: crate::Config { fn set_up_complex_asset_transfer() -> Option<(Assets, u32, Location, Box)> { None } + + /// Gets an asset that can be handled by the AssetTransactor. + /// + /// Used only in benchmarks. + /// + /// Used, for example, in the benchmark for `claim_assets`. + fn get_asset() -> Asset; } benchmarks! { @@ -341,11 +348,23 @@ benchmarks! { u32::MAX, ).unwrap()).collect::>(); crate::Pallet::::expect_response(query_id, Response::PalletsInfo(infos.try_into().unwrap())); - }: { as QueryHandler>::take_response(query_id); } + claim_assets { + let claim_origin = RawOrigin::Signed(whitelisted_caller()); + let claim_location = T::ExecuteXcmOrigin::try_origin(claim_origin.clone().into()).map_err(|_| BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?; + let asset: Asset = T::get_asset(); + // Trap assets for claiming later + crate::Pallet::::drop_assets( + &claim_location, + asset.clone().into(), + &XcmContext { origin: None, message_id: [0u8; 32], topic: None } + ); + let versioned_assets = VersionedAssets::V4(asset.into()); + }: _>(claim_origin.into(), Box::new(versioned_assets), Box::new(VersionedLocation::V4(claim_location))) + impl_benchmark_test_suite!( Pallet, crate::mock::new_test_ext_with_balances(Vec::new()), diff --git a/polkadot/xcm/pallet-xcm/src/lib.rs b/polkadot/xcm/pallet-xcm/src/lib.rs index 5e1a3e55f9b..1a1f8b402a3 100644 --- a/polkadot/xcm/pallet-xcm/src/lib.rs +++ b/polkadot/xcm/pallet-xcm/src/lib.rs @@ -85,6 +85,7 @@ pub trait WeightInfo { fn migrate_and_notify_old_targets() -> Weight; fn new_query() -> Weight; fn take_response() -> Weight; + fn claim_assets() -> Weight; } /// fallback implementation @@ -165,6 +166,10 @@ impl WeightInfo for TestWeightInfo { fn take_response() -> Weight { Weight::from_parts(100_000_000, 0) } + + fn claim_assets() -> Weight { + Weight::from_parts(100_000_000, 0) + } } #[frame_support::pallet] @@ -1386,6 +1391,64 @@ pub mod pallet { weight_limit, ) } + + /// Claims assets trapped on this pallet because of leftover assets during XCM execution. + /// + /// - `origin`: Anyone can call this extrinsic. + /// - `assets`: The exact assets that were trapped. Use the version to specify what version + /// was the latest when they were trapped. + /// - `beneficiary`: The location/account where the claimed assets will be deposited. + #[pallet::call_index(12)] + #[pallet::weight({ + let assets_version = assets.identify_version(); + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_beneficiary: Result = (*beneficiary.clone()).try_into(); + match (maybe_assets, maybe_beneficiary) { + (Ok(assets), Ok(beneficiary)) => { + let ticket: Location = GeneralIndex(assets_version as u128).into(); + let mut message = Xcm(vec![ + ClaimAsset { assets: assets.clone(), ticket }, + DepositAsset { assets: AllCounted(assets.len() as u32).into(), beneficiary }, + ]); + T::Weigher::weight(&mut message).map_or(Weight::MAX, |w| T::WeightInfo::claim_assets().saturating_add(w)) + } + _ => Weight::MAX + } + })] + pub fn claim_assets( + origin: OriginFor, + assets: Box, + beneficiary: Box, + ) -> DispatchResult { + let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; + log::debug!(target: "xcm::pallet_xcm::claim_assets", "origin: {:?}, assets: {:?}, beneficiary: {:?}", origin_location, assets, beneficiary); + // Extract version from `assets`. + let assets_version = assets.identify_version(); + let assets: Assets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; + let number_of_assets = assets.len() as u32; + let beneficiary: Location = + (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; + let ticket: Location = GeneralIndex(assets_version as u128).into(); + let mut message = Xcm(vec![ + ClaimAsset { assets, ticket }, + DepositAsset { assets: AllCounted(number_of_assets).into(), beneficiary }, + ]); + let weight = + T::Weigher::weight(&mut message).map_err(|()| Error::::UnweighableMessage)?; + let mut hash = message.using_encoded(sp_io::hashing::blake2_256); + let outcome = T::XcmExecutor::prepare_and_execute( + origin_location, + message, + &mut hash, + weight, + weight, + ); + outcome.ensure_complete().map_err(|error| { + log::error!(target: "xcm::pallet_xcm::claim_assets", "XCM execution failed with error: {:?}", error); + Error::::LocalExecutionIncomplete + })?; + Ok(()) + } } } diff --git a/polkadot/xcm/pallet-xcm/src/mock.rs b/polkadot/xcm/pallet-xcm/src/mock.rs index 17c181387dd..d5ba7312a3a 100644 --- a/polkadot/xcm/pallet-xcm/src/mock.rs +++ b/polkadot/xcm/pallet-xcm/src/mock.rs @@ -172,7 +172,7 @@ impl SendXcm for TestSendXcm { msg: &mut Option>, ) -> SendResult<(Location, Xcm<()>)> { if FAIL_SEND_XCM.with(|q| *q.borrow()) { - return Err(SendError::Transport("Intentional send failure used in tests")) + return Err(SendError::Transport("Intentional send failure used in tests")); } let pair = (dest.take().unwrap(), msg.take().unwrap()); Ok((pair, Assets::new())) @@ -654,6 +654,10 @@ impl super::benchmarking::Config for Test { }); Some((assets, fee_index as u32, dest, verify)) } + + fn get_asset() -> Asset { + Asset { id: AssetId(Location::here()), fun: Fungible(ExistentialDeposit::get()) } + } } pub(crate) fn last_event() -> RuntimeEvent { diff --git a/polkadot/xcm/pallet-xcm/src/tests/mod.rs b/polkadot/xcm/pallet-xcm/src/tests/mod.rs index 28c7d197443..13022d9a8b1 100644 --- a/polkadot/xcm/pallet-xcm/src/tests/mod.rs +++ b/polkadot/xcm/pallet-xcm/src/tests/mod.rs @@ -467,6 +467,57 @@ fn trapped_assets_can_be_claimed() { }); } +// Like `trapped_assets_can_be_claimed` but using the `claim_assets` extrinsic. +#[test] +fn claim_assets_works() { + let balances = vec![(ALICE, INITIAL_BALANCE)]; + new_test_ext_with_balances(balances).execute_with(|| { + // First trap some assets. + let trapping_program = + Xcm::builder_unsafe().withdraw_asset((Here, SEND_AMOUNT).into()).build(); + // Even though assets are trapped, the extrinsic returns success. + assert_ok!(XcmPallet::execute( + RuntimeOrigin::signed(ALICE), + Box::new(VersionedXcm::V4(trapping_program)), + BaseXcmWeight::get() * 2, + )); + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT); + + // Expected `AssetsTrapped` event info. + let source: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let versioned_assets = VersionedAssets::V4(Assets::from((Here, SEND_AMOUNT))); + let hash = BlakeTwo256::hash_of(&(source.clone(), versioned_assets.clone())); + + // Assets were indeed trapped. + assert_eq!( + last_events(2), + vec![ + RuntimeEvent::XcmPallet(crate::Event::AssetsTrapped { + hash, + origin: source, + assets: versioned_assets + }), + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: BaseXcmWeight::get() * 1 } + }) + ], + ); + let trapped = AssetTraps::::iter().collect::>(); + assert_eq!(trapped, vec![(hash, 1)]); + + // Now claim them with the extrinsic. + assert_ok!(XcmPallet::claim_assets( + RuntimeOrigin::signed(ALICE), + Box::new(VersionedAssets::V4((Here, SEND_AMOUNT).into())), + Box::new(VersionedLocation::V4( + AccountId32 { network: None, id: ALICE.clone().into() }.into() + )), + )); + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); + assert_eq!(AssetTraps::::iter().collect::>(), vec![]); + }); +} + /// Test failure to complete execution reverts intermediate side-effects. /// /// XCM program will withdraw and deposit some assets, then fail execution of a further withdraw. diff --git a/polkadot/xcm/src/lib.rs b/polkadot/xcm/src/lib.rs index c90ad25c0d8..ba8d726aecf 100644 --- a/polkadot/xcm/src/lib.rs +++ b/polkadot/xcm/src/lib.rs @@ -165,6 +165,15 @@ macro_rules! versioned_type { <$v3>::max_encoded_len() } } + impl IdentifyVersion for $n { + fn identify_version(&self) -> Version { + use $n::*; + match self { + V3(_) => v3::VERSION, + V4(_) => v4::VERSION, + } + } + } }; ($(#[$attr:meta])* pub enum $n:ident { @@ -287,6 +296,16 @@ macro_rules! versioned_type { <$v3>::max_encoded_len() } } + impl IdentifyVersion for $n { + fn identify_version(&self) -> Version { + use $n::*; + match self { + V2(_) => v2::VERSION, + V3(_) => v3::VERSION, + V4(_) => v4::VERSION, + } + } + } }; } @@ -493,6 +512,12 @@ pub trait WrapVersion { ) -> Result, ()>; } +/// Used to get the version out of a versioned type. +// TODO(XCMv5): This could be `GetVersion` and we change the current one to `GetVersionFor`. +pub trait IdentifyVersion { + fn identify_version(&self) -> Version; +} + /// Check and return the `Version` that should be used for the `Xcm` datum for the destination /// `Location`, which will interpret it. pub trait GetVersion { @@ -572,9 +597,9 @@ pub type AlwaysLts = AlwaysV4; pub mod prelude { pub use super::{ latest::prelude::*, AlwaysLatest, AlwaysLts, AlwaysV2, AlwaysV3, AlwaysV4, GetVersion, - IntoVersion, Unsupported, Version as XcmVersion, VersionedAsset, VersionedAssetId, - VersionedAssets, VersionedInteriorLocation, VersionedLocation, VersionedResponse, - VersionedXcm, WrapVersion, + IdentifyVersion, IntoVersion, Unsupported, Version as XcmVersion, VersionedAsset, + VersionedAssetId, VersionedAssets, VersionedInteriorLocation, VersionedLocation, + VersionedResponse, VersionedXcm, WrapVersion, }; } diff --git a/prdoc/pr_3403.prdoc b/prdoc/pr_3403.prdoc new file mode 100644 index 00000000000..086e769da3c --- /dev/null +++ b/prdoc/pr_3403.prdoc @@ -0,0 +1,22 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: "Add `claim_assets` extrinsic to `pallet-xcm`" + +doc: + - audience: Runtime User + description: | + There's a new extrinsic in `pallet-xcm` for claiming assets. + This means that if your assets ever get trapped while teleporting or doing reserve asset transfers, + you can easily claim them by calling this new extrinsic. + - audience: Runtime Dev + description: | + There's a new extrinsic in `pallet-xcm` that needs a new configuration item for its benchmarks. + It's a simple function in `pallet_xcm::benchmarking::Config`, `get_asset`, that returns a valid asset + handled by the AssetTransactor of the chain. + If you're already using `pallet-xcm-benchmarks`, then you already have this function there and can + just copy and paste it. + +crates: + - name: pallet-xcm + - name: staging-xcm -- GitLab From 59b2661444de2a25f2125a831bd786035a9fac4b Mon Sep 17 00:00:00 2001 From: Egor_P Date: Fri, 1 Mar 2024 15:51:53 +0700 Subject: [PATCH 332/392] [Backport] Node version and spec_version bumps and ordering of the prdoc files from 1.8.0 (#3508) This PR backports Node version and `spec_version` bumps to `1.8.0` from the latest release and orders prdoc files related to it. --- .../runtimes/assets/asset-hub-rococo/src/lib.rs | 4 ++-- .../runtimes/assets/asset-hub-westend/src/lib.rs | 2 +- .../runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs | 2 +- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 2 +- .../collectives/collectives-westend/src/lib.rs | 2 +- .../runtimes/contracts/contracts-rococo/src/lib.rs | 2 +- .../runtimes/coretime/coretime-rococo/src/lib.rs | 2 +- .../runtimes/coretime/coretime-westend/src/lib.rs | 2 +- .../runtimes/glutton/glutton-westend/src/lib.rs | 2 +- .../runtimes/people/people-rococo/src/lib.rs | 2 +- .../runtimes/people/people-westend/src/lib.rs | 2 +- .../runtimes/testing/rococo-parachain/src/lib.rs | 2 +- polkadot/node/primitives/src/lib.rs | 2 +- polkadot/runtime/rococo/src/lib.rs | 2 +- polkadot/runtime/westend/src/lib.rs | 2 +- prdoc/{ => 1.8.0}/pr_1660.prdoc | 0 prdoc/{ => 1.8.0}/pr_2061.prdoc | 0 prdoc/{ => 1.8.0}/pr_2290.prdoc | 0 prdoc/{ => 1.8.0}/pr_2903.prdoc | 0 ...9-async-backing-on-all-testnet-system-chains.prdoc | 0 prdoc/{ => 1.8.0}/pr_3007.prdoc | 0 prdoc/{ => 1.8.0}/pr_3052.prdoc | 0 prdoc/{ => 1.8.0}/pr_3060.prdoc | 0 prdoc/{ => 1.8.0}/pr_3079.prdoc | 0 prdoc/{ => 1.8.0}/pr_3154.prdoc | 0 prdoc/{ => 1.8.0}/pr_3160.prdoc | 0 prdoc/{ => 1.8.0}/pr_3166.prdoc | 0 prdoc/{ => 1.8.0}/pr_3184.prdoc | 0 prdoc/{ => 1.8.0}/pr_3212.prdoc | 0 prdoc/{ => 1.8.0}/pr_3225.prdoc | 0 prdoc/{ => 1.8.0}/pr_3230.prdoc | 0 prdoc/{ => 1.8.0}/pr_3232.prdoc | 0 prdoc/{ => 1.8.0}/pr_3243.prdoc | 0 prdoc/{ => 1.8.0}/pr_3244.prdoc | 0 prdoc/{ => 1.8.0}/pr_3272.prdoc | 0 prdoc/{ => 1.8.0}/pr_3301.prdoc | 0 prdoc/{ => 1.8.0}/pr_3308.prdoc | 0 prdoc/{ => 1.8.0}/pr_3319.prdoc | 0 prdoc/{ => 1.8.0}/pr_3325.prdoc | 0 prdoc/{ => 1.8.0}/pr_3358.prdoc | 0 prdoc/{ => 1.8.0}/pr_3361.prdoc | 0 prdoc/{ => 1.8.0}/pr_3364.prdoc | 0 prdoc/{ => 1.8.0}/pr_3370.prdoc | 0 prdoc/{ => 1.8.0}/pr_3384.prdoc | 0 prdoc/{ => 1.8.0}/pr_3395.prdoc | 0 prdoc/{ => 1.8.0}/pr_3415.prdoc | 0 prdoc/{ => 1.8.0}/pr_3435.prdoc | 0 prdoc/1.8.0/pr_3477.prdoc | 11 +++++++++++ 48 files changed, 27 insertions(+), 16 deletions(-) rename prdoc/{ => 1.8.0}/pr_1660.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_2061.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_2290.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_2903.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_2949-async-backing-on-all-testnet-system-chains.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3007.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3052.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3060.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3079.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3154.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3160.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3166.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3184.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3212.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3225.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3230.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3232.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3243.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3244.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3272.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3301.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3308.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3319.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3325.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3358.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3361.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3364.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3370.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3384.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3395.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3415.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3435.prdoc (100%) create mode 100644 prdoc/1.8.0/pr_3477.prdoc diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index a64d4bc2365..17a12dd2f6f 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -113,7 +113,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("statemine"), impl_name: create_runtime_str!("statemine"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 14, @@ -126,7 +126,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("statemine"), impl_name: create_runtime_str!("statemine"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 14, diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 5778ed362ee..1ead2897855 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -110,7 +110,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("westmint"), impl_name: create_runtime_str!("westmint"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 14, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index ee472f006fa..0b48d1717fa 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -202,7 +202,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("bridge-hub-rococo"), impl_name: create_runtime_str!("bridge-hub-rococo"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 4, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 60d959b4053..e1344fce63d 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -176,7 +176,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("bridge-hub-westend"), impl_name: create_runtime_str!("bridge-hub-westend"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 4, diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index 9a88ca174df..6bcf98c428f 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -117,7 +117,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("collectives-westend"), impl_name: create_runtime_str!("collectives-westend"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 5, diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index c73d2225ebd..0668b9a4c7d 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -133,7 +133,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("contracts-rococo"), impl_name: create_runtime_str!("contracts-rococo"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 6, diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index d95e68d85c4..cdff371c505 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -133,7 +133,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("coretime-rococo"), impl_name: create_runtime_str!("coretime-rococo"), authoring_version: 1, - spec_version: 1_007_001, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 0, diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index 4b9b180321d..7fa70647992 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -133,7 +133,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("coretime-westend"), impl_name: create_runtime_str!("coretime-westend"), authoring_version: 1, - spec_version: 1_007_001, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 0, diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs index e09ad42ea9f..232a82115a8 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs @@ -100,7 +100,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("glutton-westend"), impl_name: create_runtime_str!("glutton-westend"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index 28b8062e0e0..2b8cc32f67c 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -126,7 +126,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("people-rococo"), impl_name: create_runtime_str!("people-rococo"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 0, diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index b2b32445613..2dc2d06a66b 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -126,7 +126,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("people-westend"), impl_name: create_runtime_str!("people-westend"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 0, diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs index b69c2341d6b..2b21a12c3ca 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs @@ -107,7 +107,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("test-parachain"), impl_name: create_runtime_str!("test-parachain"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 6, diff --git a/polkadot/node/primitives/src/lib.rs b/polkadot/node/primitives/src/lib.rs index 6e3eefbcbe8..d295c21cce1 100644 --- a/polkadot/node/primitives/src/lib.rs +++ b/polkadot/node/primitives/src/lib.rs @@ -58,7 +58,7 @@ pub use disputes::{ /// relatively rare. /// /// The associated worker binaries should use the same version as the node that spawns them. -pub const NODE_VERSION: &'static str = "1.7.0"; +pub const NODE_VERSION: &'static str = "1.8.0"; // For a 16-ary Merkle Prefix Trie, we can expect at most 16 32-byte hashes per node // plus some overhead: diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 48395f45238..96e8c4e0979 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -149,7 +149,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("rococo"), impl_name: create_runtime_str!("parity-rococo-v2.0"), authoring_version: 0, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 24, diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 4ac2202b8fc..b55d68ee0f6 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -150,7 +150,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("westend"), impl_name: create_runtime_str!("parity-westend"), authoring_version: 2, - spec_version: 1_007_001, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 24, diff --git a/prdoc/pr_1660.prdoc b/prdoc/1.8.0/pr_1660.prdoc similarity index 100% rename from prdoc/pr_1660.prdoc rename to prdoc/1.8.0/pr_1660.prdoc diff --git a/prdoc/pr_2061.prdoc b/prdoc/1.8.0/pr_2061.prdoc similarity index 100% rename from prdoc/pr_2061.prdoc rename to prdoc/1.8.0/pr_2061.prdoc diff --git a/prdoc/pr_2290.prdoc b/prdoc/1.8.0/pr_2290.prdoc similarity index 100% rename from prdoc/pr_2290.prdoc rename to prdoc/1.8.0/pr_2290.prdoc diff --git a/prdoc/pr_2903.prdoc b/prdoc/1.8.0/pr_2903.prdoc similarity index 100% rename from prdoc/pr_2903.prdoc rename to prdoc/1.8.0/pr_2903.prdoc diff --git a/prdoc/pr_2949-async-backing-on-all-testnet-system-chains.prdoc b/prdoc/1.8.0/pr_2949-async-backing-on-all-testnet-system-chains.prdoc similarity index 100% rename from prdoc/pr_2949-async-backing-on-all-testnet-system-chains.prdoc rename to prdoc/1.8.0/pr_2949-async-backing-on-all-testnet-system-chains.prdoc diff --git a/prdoc/pr_3007.prdoc b/prdoc/1.8.0/pr_3007.prdoc similarity index 100% rename from prdoc/pr_3007.prdoc rename to prdoc/1.8.0/pr_3007.prdoc diff --git a/prdoc/pr_3052.prdoc b/prdoc/1.8.0/pr_3052.prdoc similarity index 100% rename from prdoc/pr_3052.prdoc rename to prdoc/1.8.0/pr_3052.prdoc diff --git a/prdoc/pr_3060.prdoc b/prdoc/1.8.0/pr_3060.prdoc similarity index 100% rename from prdoc/pr_3060.prdoc rename to prdoc/1.8.0/pr_3060.prdoc diff --git a/prdoc/pr_3079.prdoc b/prdoc/1.8.0/pr_3079.prdoc similarity index 100% rename from prdoc/pr_3079.prdoc rename to prdoc/1.8.0/pr_3079.prdoc diff --git a/prdoc/pr_3154.prdoc b/prdoc/1.8.0/pr_3154.prdoc similarity index 100% rename from prdoc/pr_3154.prdoc rename to prdoc/1.8.0/pr_3154.prdoc diff --git a/prdoc/pr_3160.prdoc b/prdoc/1.8.0/pr_3160.prdoc similarity index 100% rename from prdoc/pr_3160.prdoc rename to prdoc/1.8.0/pr_3160.prdoc diff --git a/prdoc/pr_3166.prdoc b/prdoc/1.8.0/pr_3166.prdoc similarity index 100% rename from prdoc/pr_3166.prdoc rename to prdoc/1.8.0/pr_3166.prdoc diff --git a/prdoc/pr_3184.prdoc b/prdoc/1.8.0/pr_3184.prdoc similarity index 100% rename from prdoc/pr_3184.prdoc rename to prdoc/1.8.0/pr_3184.prdoc diff --git a/prdoc/pr_3212.prdoc b/prdoc/1.8.0/pr_3212.prdoc similarity index 100% rename from prdoc/pr_3212.prdoc rename to prdoc/1.8.0/pr_3212.prdoc diff --git a/prdoc/pr_3225.prdoc b/prdoc/1.8.0/pr_3225.prdoc similarity index 100% rename from prdoc/pr_3225.prdoc rename to prdoc/1.8.0/pr_3225.prdoc diff --git a/prdoc/pr_3230.prdoc b/prdoc/1.8.0/pr_3230.prdoc similarity index 100% rename from prdoc/pr_3230.prdoc rename to prdoc/1.8.0/pr_3230.prdoc diff --git a/prdoc/pr_3232.prdoc b/prdoc/1.8.0/pr_3232.prdoc similarity index 100% rename from prdoc/pr_3232.prdoc rename to prdoc/1.8.0/pr_3232.prdoc diff --git a/prdoc/pr_3243.prdoc b/prdoc/1.8.0/pr_3243.prdoc similarity index 100% rename from prdoc/pr_3243.prdoc rename to prdoc/1.8.0/pr_3243.prdoc diff --git a/prdoc/pr_3244.prdoc b/prdoc/1.8.0/pr_3244.prdoc similarity index 100% rename from prdoc/pr_3244.prdoc rename to prdoc/1.8.0/pr_3244.prdoc diff --git a/prdoc/pr_3272.prdoc b/prdoc/1.8.0/pr_3272.prdoc similarity index 100% rename from prdoc/pr_3272.prdoc rename to prdoc/1.8.0/pr_3272.prdoc diff --git a/prdoc/pr_3301.prdoc b/prdoc/1.8.0/pr_3301.prdoc similarity index 100% rename from prdoc/pr_3301.prdoc rename to prdoc/1.8.0/pr_3301.prdoc diff --git a/prdoc/pr_3308.prdoc b/prdoc/1.8.0/pr_3308.prdoc similarity index 100% rename from prdoc/pr_3308.prdoc rename to prdoc/1.8.0/pr_3308.prdoc diff --git a/prdoc/pr_3319.prdoc b/prdoc/1.8.0/pr_3319.prdoc similarity index 100% rename from prdoc/pr_3319.prdoc rename to prdoc/1.8.0/pr_3319.prdoc diff --git a/prdoc/pr_3325.prdoc b/prdoc/1.8.0/pr_3325.prdoc similarity index 100% rename from prdoc/pr_3325.prdoc rename to prdoc/1.8.0/pr_3325.prdoc diff --git a/prdoc/pr_3358.prdoc b/prdoc/1.8.0/pr_3358.prdoc similarity index 100% rename from prdoc/pr_3358.prdoc rename to prdoc/1.8.0/pr_3358.prdoc diff --git a/prdoc/pr_3361.prdoc b/prdoc/1.8.0/pr_3361.prdoc similarity index 100% rename from prdoc/pr_3361.prdoc rename to prdoc/1.8.0/pr_3361.prdoc diff --git a/prdoc/pr_3364.prdoc b/prdoc/1.8.0/pr_3364.prdoc similarity index 100% rename from prdoc/pr_3364.prdoc rename to prdoc/1.8.0/pr_3364.prdoc diff --git a/prdoc/pr_3370.prdoc b/prdoc/1.8.0/pr_3370.prdoc similarity index 100% rename from prdoc/pr_3370.prdoc rename to prdoc/1.8.0/pr_3370.prdoc diff --git a/prdoc/pr_3384.prdoc b/prdoc/1.8.0/pr_3384.prdoc similarity index 100% rename from prdoc/pr_3384.prdoc rename to prdoc/1.8.0/pr_3384.prdoc diff --git a/prdoc/pr_3395.prdoc b/prdoc/1.8.0/pr_3395.prdoc similarity index 100% rename from prdoc/pr_3395.prdoc rename to prdoc/1.8.0/pr_3395.prdoc diff --git a/prdoc/pr_3415.prdoc b/prdoc/1.8.0/pr_3415.prdoc similarity index 100% rename from prdoc/pr_3415.prdoc rename to prdoc/1.8.0/pr_3415.prdoc diff --git a/prdoc/pr_3435.prdoc b/prdoc/1.8.0/pr_3435.prdoc similarity index 100% rename from prdoc/pr_3435.prdoc rename to prdoc/1.8.0/pr_3435.prdoc diff --git a/prdoc/1.8.0/pr_3477.prdoc b/prdoc/1.8.0/pr_3477.prdoc new file mode 100644 index 00000000000..26e96d3635b --- /dev/null +++ b/prdoc/1.8.0/pr_3477.prdoc @@ -0,0 +1,11 @@ +title: Allow parachain which acquires multiple coretime cores to make progress + +doc: + - audience: Node Operator + description: | + Adds the needed changes so that parachains which acquire multiple coretime cores can still make progress. + Only one of the cores will be able to be occupied at a time. + Only works if the ElasticScalingMVP node feature is enabled in the runtime and the block author validator is + updated to include this change. + +crates: [ ] -- GitLab From a1b57a8c181bc39b254ff4d6d774f6ff348e509d Mon Sep 17 00:00:00 2001 From: Dmitry Markin Date: Fri, 1 Mar 2024 13:19:17 +0200 Subject: [PATCH 333/392] Fix crash of synced parachain node run with `--sync=warp` (#3523) Fixes https://github.com/paritytech/polkadot-sdk/issues/3496. --- prdoc/pr_3523.prdoc | 19 ++++ substrate/client/network/sync/src/engine.rs | 2 + substrate/client/network/sync/src/strategy.rs | 88 +++++++++++++++++-- 3 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 prdoc/pr_3523.prdoc diff --git a/prdoc/pr_3523.prdoc b/prdoc/pr_3523.prdoc new file mode 100644 index 00000000000..c31d9d096dc --- /dev/null +++ b/prdoc/pr_3523.prdoc @@ -0,0 +1,19 @@ +title: Fix crash of synced parachain node run with `--sync=warp` + +doc: + - audience: Node Operator + description: | + Fix crash of `SyncingEngine` when an already synced parachain node is run with `--sync=warp` + (issue https://github.com/paritytech/polkadot-sdk/issues/3496). + The issue manifests itself by errors in the logs: + ``` + [Parachain] Cannot set warp sync target block: no warp sync strategy is active. + [Parachain] Failed to set warp sync target block header, terminating `SyncingEngine`. + ``` + Followed by a stream of messages: + ``` + [Parachain] Protocol command streams have been shut down + ``` + +crates: + - name: sc-network-sync diff --git a/substrate/client/network/sync/src/engine.rs b/substrate/client/network/sync/src/engine.rs index c1a7009eeb0..24640fdc455 100644 --- a/substrate/client/network/sync/src/engine.rs +++ b/substrate/client/network/sync/src/engine.rs @@ -656,6 +656,8 @@ where Some(event) => self.process_notification_event(event), None => return, }, + // TODO: setting of warp sync target block should be moved to the initialization of + // `SyncingEngine`, see https://github.com/paritytech/polkadot-sdk/issues/3537. warp_target_block_header = &mut self.warp_sync_target_block_header_rx_fused => { if let Err(_) = self.pass_warp_sync_target_block_header(warp_target_block_header) { error!( diff --git a/substrate/client/network/sync/src/strategy.rs b/substrate/client/network/sync/src/strategy.rs index 7d6e6a8d3b8..dabcf37ae63 100644 --- a/substrate/client/network/sync/src/strategy.rs +++ b/substrate/client/network/sync/src/strategy.rs @@ -30,7 +30,7 @@ use crate::{ }; use chain_sync::{ChainSync, ChainSyncAction, ChainSyncMode}; use libp2p::PeerId; -use log::{debug, error, info}; +use log::{debug, error, info, warn}; use prometheus_endpoint::Registry; use sc_client_api::{BlockBackend, ProofProvider}; use sc_consensus::{BlockImportError, BlockImportStatus, IncomingBlock}; @@ -159,7 +159,7 @@ impl From> for SyncingAction { /// Proxy to specific syncing strategies. pub struct SyncingStrategy { - /// Syncing configuration. + /// Initial syncing configuration. config: SyncingConfig, /// Client used by syncing strategies. client: Arc, @@ -466,15 +466,27 @@ where &mut self, target_header: B::Header, ) -> Result<(), ()> { - match self.warp { - Some(ref mut warp) => { - warp.set_target_block(target_header); - Ok(()) + match self.config.mode { + SyncMode::Warp => match self.warp { + Some(ref mut warp) => { + warp.set_target_block(target_header); + Ok(()) + }, + None => { + // As mode is set to warp sync, but no warp sync strategy is active, this means + // that warp sync has already finished / was skipped. + warn!( + target: LOG_TARGET, + "Discarding warp sync target, as warp sync was seemingly skipped due \ + to node being (partially) synced.", + ); + Ok(()) + }, }, - None => { + _ => { error!( target: LOG_TARGET, - "Cannot set warp sync target block: no warp sync strategy is active." + "Cannot set warp sync target block: not in warp sync mode." ); debug_assert!(false); Err(()) @@ -587,3 +599,63 @@ where } } } + +#[cfg(test)] +mod test { + use super::*; + use futures::executor::block_on; + use sc_block_builder::BlockBuilderBuilder; + use substrate_test_runtime_client::{ + ClientBlockImportExt, ClientExt, DefaultTestClientBuilderExt, TestClientBuilder, + TestClientBuilderExt, + }; + + /// Regression test for crash when starting already synced parachain node with `--sync=warp`. + /// We must remove this after setting of warp sync target block is moved to initialization of + /// `SyncingEngine` (issue https://github.com/paritytech/polkadot-sdk/issues/3537). + #[test] + fn set_target_block_finished_warp_sync() { + // Populate database with finalized state. + let mut client = Arc::new(TestClientBuilder::new().build()); + let block = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().best_hash) + .with_parent_block_number(client.chain_info().best_number) + .build() + .unwrap() + .build() + .unwrap() + .block; + block_on(client.import(BlockOrigin::Own, block.clone())).unwrap(); + let just = (*b"TEST", Vec::new()); + client.finalize_block(block.hash(), Some(just)).unwrap(); + let target_block = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().best_hash) + .with_parent_block_number(client.chain_info().best_number) + .build() + .unwrap() + .build() + .unwrap() + .block; + + // Initialize syncing strategy. + let config = SyncingConfig { + mode: SyncMode::Warp, + max_parallel_downloads: 3, + max_blocks_per_request: 64, + metrics_registry: None, + }; + let mut strategy = + SyncingStrategy::new(config, client, Some(WarpSyncConfig::WaitForTarget)).unwrap(); + + // Warp sync instantly finishes as we have finalized state in DB. + let actions = strategy.actions().unwrap(); + assert_eq!(actions.len(), 1); + assert!(matches!(actions[0], SyncingAction::Finished)); + assert!(strategy.warp.is_none()); + + // Try setting the target block. We mustn't crash. + strategy + .set_warp_sync_target_block_header(target_block.header().clone()) + .unwrap(); + } +} -- GitLab From 6f81a4a09270a5930b8786e2dc765347078b4d4a Mon Sep 17 00:00:00 2001 From: Xiliang Chen Date: Sat, 2 Mar 2024 01:23:21 +1300 Subject: [PATCH 334/392] make SelfParaId a metadata constant (#3517) expose para id via metadata #2116 is blocked by this --- cumulus/pallets/parachain-system/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/cumulus/pallets/parachain-system/src/lib.rs b/cumulus/pallets/parachain-system/src/lib.rs index 3439227bc5b..81965a2a313 100644 --- a/cumulus/pallets/parachain-system/src/lib.rs +++ b/cumulus/pallets/parachain-system/src/lib.rs @@ -205,6 +205,7 @@ pub mod pallet { type OnSystemEvent: OnSystemEvent; /// Returns the parachain ID we are running with. + #[pallet::constant] type SelfParaId: Get; /// The place where outbound XCMP messages come from. This is queried in `finalize_block`. -- GitLab From f0e589d72e5228472c7658c525e0ff80d122d777 Mon Sep 17 00:00:00 2001 From: Andrei Eres Date: Fri, 1 Mar 2024 15:30:43 +0100 Subject: [PATCH 335/392] subsystem-bench: add regression tests for availability read and write (#3311) ### What's been done - `subsystem-bench` has been split into two parts: a cli benchmark runner and a library. - The cli runner is quite simple. It just allows us to run `.yaml` based test sequences. Now it should only be used to run benchmarks during development. - The library is used in the cli runner and in regression tests. Some code is changed to make the library independent of the runner. - Added first regression tests for availability read and write that replicate existing test sequences. ### How we run regression tests - Regression tests are simply rust integration tests without the harnesses. - They should only be compiled under the `subsystem-benchmarks` feature to prevent them from running with other tests. - This doesn't work when running tests with `nextest` in CI, so additional filters have been added to the `nextest` runs. - Each benchmark run takes a different time in the beginning, so we "warm up" the tests until their CPU usage differs by only 1%. - After the warm-up, we run the benchmarks a few more times and compare the average with the exception using a precision. ### What is still wrong? - I haven't managed to set up approval voting tests. The spread of their results is too large and can't be narrowed down in a reasonable amount of time in the warm-up phase. - The tests start an unconfigurable prometheus endpoint inside, which causes errors because they use the same 9999 port. I disable it with a flag, but I think it's better to extract the endpoint launching outside the test, as we already do with `valgrind` and `pyroscope`. But we still use `prometheus` inside the tests. ### Future work * https://github.com/paritytech/polkadot-sdk/issues/3528 * https://github.com/paritytech/polkadot-sdk/issues/3529 * https://github.com/paritytech/polkadot-sdk/issues/3530 * https://github.com/paritytech/polkadot-sdk/issues/3531 --------- Co-authored-by: Alexander Samusev <41779041+alvicsam@users.noreply.github.com> --- .gitlab/pipeline/test.yml | 3 +- Cargo.lock | 2 + .../availability-distribution/Cargo.toml | 11 ++ ...ilability-distribution-regression-bench.rs | 113 +++++++++++++ .../network/availability-recovery/Cargo.toml | 7 + .../availability-recovery-regression-bench.rs | 103 ++++++++++++ polkadot/node/subsystem-bench/Cargo.toml | 6 +- polkadot/node/subsystem-bench/README.md | 146 +++++++++-------- .../examples/approvals_no_shows.yaml | 6 +- .../examples/approvals_throughput.yaml | 3 +- .../approvals_throughput_best_case.yaml | 2 +- ...s_throughput_no_optimisations_enabled.yaml | 2 +- .../subsystem-bench/src/availability/cli.rs | 37 ----- .../src/{ => cli}/subsystem-bench.rs | 149 ++++++++---------- .../subsystem-bench/src/{ => cli}/valgrind.rs | 0 .../src/{ => lib}/approval/helpers.rs | 2 +- .../{ => lib}/approval/message_generator.rs | 19 +-- .../approval/mock_chain_selection.rs | 0 .../src/{ => lib}/approval/mod.rs | 50 +++--- .../src/{ => lib}/approval/test_message.rs | 5 +- .../availability/av_store_helpers.rs | 2 +- .../src/{ => lib}/availability/mod.rs | 70 ++++---- .../src/{core => lib}/configuration.rs | 113 ++++++------- .../src/{core => lib}/display.rs | 28 ++-- .../src/{core => lib}/environment.rs | 78 +++------ .../src/{core => lib}/keyring.rs | 0 .../src/{core/mod.rs => lib/lib.rs} | 7 +- .../src/{core => lib}/mock/av_store.rs | 2 +- .../src/{core => lib}/mock/chain_api.rs | 0 .../src/{core => lib}/mock/dummy.rs | 0 .../src/{core => lib}/mock/mod.rs | 4 +- .../src/{core => lib}/mock/network_bridge.rs | 2 +- .../src/{core => lib}/mock/runtime_api.rs | 2 +- .../src/{core => lib}/network.rs | 2 +- .../node/subsystem-bench/src/lib/usage.rs | 146 +++++++++++++++++ 35 files changed, 711 insertions(+), 411 deletions(-) create mode 100644 polkadot/node/network/availability-distribution/tests/availability-distribution-regression-bench.rs create mode 100644 polkadot/node/network/availability-recovery/tests/availability-recovery-regression-bench.rs delete mode 100644 polkadot/node/subsystem-bench/src/availability/cli.rs rename polkadot/node/subsystem-bench/src/{ => cli}/subsystem-bench.rs (62%) rename polkadot/node/subsystem-bench/src/{ => cli}/valgrind.rs (100%) rename polkadot/node/subsystem-bench/src/{ => lib}/approval/helpers.rs (99%) rename polkadot/node/subsystem-bench/src/{ => lib}/approval/message_generator.rs (97%) rename polkadot/node/subsystem-bench/src/{ => lib}/approval/mock_chain_selection.rs (100%) rename polkadot/node/subsystem-bench/src/{ => lib}/approval/mod.rs (97%) rename polkadot/node/subsystem-bench/src/{ => lib}/approval/test_message.rs (98%) rename polkadot/node/subsystem-bench/src/{ => lib}/availability/av_store_helpers.rs (94%) rename polkadot/node/subsystem-bench/src/{ => lib}/availability/mod.rs (94%) rename polkadot/node/subsystem-bench/src/{core => lib}/configuration.rs (83%) rename polkadot/node/subsystem-bench/src/{core => lib}/display.rs (89%) rename polkadot/node/subsystem-bench/src/{core => lib}/environment.rs (88%) rename polkadot/node/subsystem-bench/src/{core => lib}/keyring.rs (100%) rename polkadot/node/subsystem-bench/src/{core/mod.rs => lib/lib.rs} (88%) rename polkadot/node/subsystem-bench/src/{core => lib}/mock/av_store.rs (99%) rename polkadot/node/subsystem-bench/src/{core => lib}/mock/chain_api.rs (100%) rename polkadot/node/subsystem-bench/src/{core => lib}/mock/dummy.rs (100%) rename polkadot/node/subsystem-bench/src/{core => lib}/mock/mod.rs (97%) rename polkadot/node/subsystem-bench/src/{core => lib}/mock/network_bridge.rs (99%) rename polkadot/node/subsystem-bench/src/{core => lib}/mock/runtime_api.rs (99%) rename polkadot/node/subsystem-bench/src/{core => lib}/network.rs (99%) create mode 100644 polkadot/node/subsystem-bench/src/lib/usage.rs diff --git a/.gitlab/pipeline/test.yml b/.gitlab/pipeline/test.yml index 9f774aab271..5c41a3e6e08 100644 --- a/.gitlab/pipeline/test.yml +++ b/.gitlab/pipeline/test.yml @@ -25,6 +25,7 @@ test-linux-stable: # "upgrade_version_checks_should_work" is currently failing - | time cargo nextest run \ + --filter-expr 'not deps(/polkadot-subsystem-bench/)' \ --workspace \ --locked \ --release \ @@ -69,7 +70,7 @@ test-linux-stable-runtime-benchmarks: # but still want to have debug assertions. RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" script: - - time cargo nextest run --workspace --features runtime-benchmarks benchmark --locked --cargo-profile testnet + - time cargo nextest run --filter-expr 'not deps(/polkadot-subsystem-bench/)' --workspace --features runtime-benchmarks benchmark --locked --cargo-profile testnet # can be used to run all tests # test-linux-stable-all: diff --git a/Cargo.lock b/Cargo.lock index 991541ee84e..b12006bbcf7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12269,6 +12269,7 @@ dependencies = [ "polkadot-node-subsystem-util", "polkadot-primitives", "polkadot-primitives-test-helpers", + "polkadot-subsystem-bench", "rand", "sc-network", "schnellru", @@ -12300,6 +12301,7 @@ dependencies = [ "polkadot-node-subsystem-util", "polkadot-primitives", "polkadot-primitives-test-helpers", + "polkadot-subsystem-bench", "rand", "sc-network", "schnellru", diff --git a/polkadot/node/network/availability-distribution/Cargo.toml b/polkadot/node/network/availability-distribution/Cargo.toml index 432501ed23f..182d92cb163 100644 --- a/polkadot/node/network/availability-distribution/Cargo.toml +++ b/polkadot/node/network/availability-distribution/Cargo.toml @@ -36,3 +36,14 @@ sc-network = { path = "../../../../substrate/client/network" } futures-timer = "3.0.2" assert_matches = "1.4.0" polkadot-primitives-test-helpers = { path = "../../../primitives/test-helpers" } +polkadot-subsystem-bench = { path = "../../subsystem-bench" } + + +[[test]] +name = "availability-distribution-regression-bench" +path = "tests/availability-distribution-regression-bench.rs" +harness = false +required-features = ["subsystem-benchmarks"] + +[features] +subsystem-benchmarks = [] diff --git a/polkadot/node/network/availability-distribution/tests/availability-distribution-regression-bench.rs b/polkadot/node/network/availability-distribution/tests/availability-distribution-regression-bench.rs new file mode 100644 index 00000000000..f2872f3c72b --- /dev/null +++ b/polkadot/node/network/availability-distribution/tests/availability-distribution-regression-bench.rs @@ -0,0 +1,113 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! availability-read regression tests +//! +//! TODO: Explain the test case after configuration adjusted to Kusama +//! +//! Subsystems involved: +//! - availability-distribution +//! - bitfield-distribution +//! - availability-store + +use polkadot_subsystem_bench::{ + availability::{benchmark_availability_write, prepare_test, TestDataAvailability, TestState}, + configuration::{PeerLatency, TestConfiguration}, + usage::BenchmarkUsage, +}; + +const BENCH_COUNT: usize = 3; +const WARM_UP_COUNT: usize = 20; +const WARM_UP_PRECISION: f64 = 0.01; + +fn main() -> Result<(), String> { + let mut messages = vec![]; + + // TODO: Adjust the test configurations to Kusama values + let mut config = TestConfiguration::default(); + config.latency = Some(PeerLatency { mean_latency_ms: 30, std_dev: 2.0 }); + config.n_validators = 1000; + config.n_cores = 200; + config.max_validators_per_core = 5; + config.min_pov_size = 5120; + config.max_pov_size = 5120; + config.peer_bandwidth = 52428800; + config.bandwidth = 52428800; + config.connectivity = 75; + config.num_blocks = 3; + config.generate_pov_sizes(); + + warm_up(config.clone())?; + let usage = benchmark(config.clone()); + + messages.extend(usage.check_network_usage(&[ + ("Received from peers", 4330.0, 0.05), + ("Sent to peers", 15900.0, 0.05), + ])); + messages.extend(usage.check_cpu_usage(&[ + ("availability-distribution", 0.025, 0.05), + ("bitfield-distribution", 0.085, 0.05), + ("availability-store", 0.180, 0.05), + ])); + + if messages.is_empty() { + Ok(()) + } else { + eprintln!("{}", messages.join("\n")); + Err("Regressions found".to_string()) + } +} + +fn warm_up(config: TestConfiguration) -> Result<(), String> { + println!("Warming up..."); + let mut prev_run: Option = None; + for _ in 0..WARM_UP_COUNT { + let curr = run(config.clone()); + if let Some(ref prev) = prev_run { + let av_distr_diff = + curr.cpu_usage_diff(prev, "availability-distribution").expect("Must exist"); + let bitf_distr_diff = + curr.cpu_usage_diff(prev, "bitfield-distribution").expect("Must exist"); + let av_store_diff = + curr.cpu_usage_diff(prev, "availability-store").expect("Must exist"); + if av_distr_diff < WARM_UP_PRECISION && + bitf_distr_diff < WARM_UP_PRECISION && + av_store_diff < WARM_UP_PRECISION + { + return Ok(()) + } + } + prev_run = Some(curr); + } + + Err("Can't warm up".to_string()) +} + +fn benchmark(config: TestConfiguration) -> BenchmarkUsage { + println!("Benchmarking..."); + let usages: Vec = (0..BENCH_COUNT).map(|_| run(config.clone())).collect(); + let usage = BenchmarkUsage::average(&usages); + println!("{}", usage); + usage +} + +fn run(config: TestConfiguration) -> BenchmarkUsage { + let mut state = TestState::new(&config); + let (mut env, _protocol_config) = + prepare_test(config.clone(), &mut state, TestDataAvailability::Write, false); + env.runtime() + .block_on(benchmark_availability_write("data_availability_write", &mut env, state)) +} diff --git a/polkadot/node/network/availability-recovery/Cargo.toml b/polkadot/node/network/availability-recovery/Cargo.toml index 9eddf5c86d2..12b6ce7a057 100644 --- a/polkadot/node/network/availability-recovery/Cargo.toml +++ b/polkadot/node/network/availability-recovery/Cargo.toml @@ -41,6 +41,13 @@ sc-network = { path = "../../../../substrate/client/network" } polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } polkadot-primitives-test-helpers = { path = "../../../primitives/test-helpers" } +polkadot-subsystem-bench = { path = "../../subsystem-bench" } + +[[test]] +name = "availability-recovery-regression-bench" +path = "tests/availability-recovery-regression-bench.rs" +harness = false +required-features = ["subsystem-benchmarks"] [features] subsystem-benchmarks = [] diff --git a/polkadot/node/network/availability-recovery/tests/availability-recovery-regression-bench.rs b/polkadot/node/network/availability-recovery/tests/availability-recovery-regression-bench.rs new file mode 100644 index 00000000000..beb063e7ae0 --- /dev/null +++ b/polkadot/node/network/availability-recovery/tests/availability-recovery-regression-bench.rs @@ -0,0 +1,103 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! availability-write regression tests +//! +//! TODO: Explain the test case after configuration adjusted to Kusama +//! +//! Subsystems involved: +//! - availability-recovery + +use polkadot_subsystem_bench::{ + availability::{ + benchmark_availability_read, prepare_test, DataAvailabilityReadOptions, + TestDataAvailability, TestState, + }, + configuration::{PeerLatency, TestConfiguration}, + usage::BenchmarkUsage, +}; + +const BENCH_COUNT: usize = 3; +const WARM_UP_COUNT: usize = 10; +const WARM_UP_PRECISION: f64 = 0.01; + +fn main() -> Result<(), String> { + let mut messages = vec![]; + + // TODO: Adjust the test configurations to Kusama values + let options = DataAvailabilityReadOptions { fetch_from_backers: true }; + let mut config = TestConfiguration::default(); + config.latency = Some(PeerLatency { mean_latency_ms: 100, std_dev: 1.0 }); + config.n_validators = 300; + config.n_cores = 20; + config.min_pov_size = 5120; + config.max_pov_size = 5120; + config.peer_bandwidth = 52428800; + config.bandwidth = 52428800; + config.num_blocks = 3; + config.connectivity = 90; + config.generate_pov_sizes(); + + warm_up(config.clone(), options.clone())?; + let usage = benchmark(config.clone(), options.clone()); + + messages.extend(usage.check_network_usage(&[ + ("Received from peers", 102400.000, 0.05), + ("Sent to peers", 0.335, 0.05), + ])); + messages.extend(usage.check_cpu_usage(&[("availability-recovery", 3.850, 0.05)])); + + if messages.is_empty() { + Ok(()) + } else { + eprintln!("{}", messages.join("\n")); + Err("Regressions found".to_string()) + } +} + +fn warm_up(config: TestConfiguration, options: DataAvailabilityReadOptions) -> Result<(), String> { + println!("Warming up..."); + let mut prev_run: Option = None; + for _ in 0..WARM_UP_COUNT { + let curr = run(config.clone(), options.clone()); + if let Some(ref prev) = prev_run { + let diff = curr.cpu_usage_diff(prev, "availability-recovery").expect("Must exist"); + if diff < WARM_UP_PRECISION { + return Ok(()) + } + } + prev_run = Some(curr); + } + + Err("Can't warm up".to_string()) +} + +fn benchmark(config: TestConfiguration, options: DataAvailabilityReadOptions) -> BenchmarkUsage { + println!("Benchmarking..."); + let usages: Vec = + (0..BENCH_COUNT).map(|_| run(config.clone(), options.clone())).collect(); + let usage = BenchmarkUsage::average(&usages); + println!("{}", usage); + usage +} + +fn run(config: TestConfiguration, options: DataAvailabilityReadOptions) -> BenchmarkUsage { + let mut state = TestState::new(&config); + let (mut env, _protocol_config) = + prepare_test(config.clone(), &mut state, TestDataAvailability::Read(options), false); + env.runtime() + .block_on(benchmark_availability_read("data_availability_read", &mut env, state)) +} diff --git a/polkadot/node/subsystem-bench/Cargo.toml b/polkadot/node/subsystem-bench/Cargo.toml index 7de91d8cd5d..726e7de4587 100644 --- a/polkadot/node/subsystem-bench/Cargo.toml +++ b/polkadot/node/subsystem-bench/Cargo.toml @@ -8,9 +8,13 @@ license.workspace = true readme = "README.md" publish = false +[lib] +name = "polkadot_subsystem_bench" +path = "src/lib/lib.rs" + [[bin]] name = "subsystem-bench" -path = "src/subsystem-bench.rs" +path = "src/cli/subsystem-bench.rs" # Prevent rustdoc error. Already documented from top-level Cargo.toml. doc = false diff --git a/polkadot/node/subsystem-bench/README.md b/polkadot/node/subsystem-bench/README.md index e090a0392cb..3aac2810ad5 100644 --- a/polkadot/node/subsystem-bench/README.md +++ b/polkadot/node/subsystem-bench/README.md @@ -1,6 +1,6 @@ # Subsystem benchmark client -Run parachain consensus stress and performance tests on your development machine. +Run parachain consensus stress and performance tests on your development machine or in CI. ## Motivation @@ -32,7 +32,8 @@ a local Grafana/Prometheus stack is needed. ### Run Prometheus, Pyroscope and Graphana in Docker -If docker is not usable, then follow the next sections to manually install Prometheus, Pyroscope and Graphana on your machine. +If docker is not usable, then follow the next sections to manually install Prometheus, Pyroscope and Graphana +on your machine. ```bash cd polkadot/node/subsystem-bench/docker @@ -95,39 +96,16 @@ If you are running the servers in Docker, use the following URLs: Follow [this guide](https://grafana.com/docs/grafana/latest/dashboards/manage-dashboards/#export-and-import-dashboards) to import the dashboards from the repository `grafana` folder. -## How to run a test - -To run a test, you need to first choose a test objective. Currently, we support the following: - -``` -target/testnet/subsystem-bench --help -The almighty Subsystem Benchmark Tool™️ - -Usage: subsystem-bench [OPTIONS] - -Commands: - data-availability-read Benchmark availability recovery strategies +### Standard test options ``` +$ subsystem-bench --help +Usage: subsystem-bench [OPTIONS] -Note: `test-sequence` is a special test objective that wraps up an arbitrary number of test objectives. It is tipically - used to run a suite of tests defined in a `yaml` file like in this [example](examples/availability_read.yaml). +Arguments: + Path to the test sequence configuration file -### Standard test options - -``` - --network The type of network to be emulated [default: ideal] [possible values: ideal, healthy, - degraded] - --n-cores Number of cores to fetch availability for [default: 100] - --n-validators Number of validators to fetch chunks from [default: 500] - --min-pov-size The minimum pov size in KiB [default: 5120] - --max-pov-size The maximum pov size bytes [default: 5120] - -n, --num-blocks The number of blocks the test is going to run [default: 1] - -p, --peer-bandwidth The bandwidth of emulated remote peers in KiB - -b, --bandwidth The bandwidth of our node in KiB - --connectivity Emulated peer connection ratio [0-100] - --peer-mean-latency Mean remote peer latency in milliseconds [0-5000] - --peer-latency-std-dev Remote peer latency standard deviation +Options: --profile Enable CPU Profiling with Pyroscope --pyroscope-url Pyroscope Server URL [default: http://localhost:4040] --pyroscope-sample-rate Pyroscope Sample Rate [default: 113] @@ -135,27 +113,17 @@ Note: `test-sequence` is a special test objective that wraps up an arbitrary num -h, --help Print help ``` -These apply to all test objectives, except `test-sequence` which relies on the values being specified in a file. - -### Test objectives - -Each test objective can have it's specific configuration options, in contrast with the standard test options. +## How to run a test -For `data-availability-read` the recovery strategy to be used is configurable. +To run a test, you need to use a path to a test objective: ``` -target/testnet/subsystem-bench data-availability-read --help -Benchmark availability recovery strategies - -Usage: subsystem-bench data-availability-read [OPTIONS] - -Options: - -f, --fetch-from-backers Turbo boost AD Read by fetching the full availability datafrom backers first. Saves CPU - as we don't need to re-construct from chunks. Tipically this is only faster if nodes - have enough bandwidth - -h, --help Print help +target/testnet/subsystem-bench polkadot/node/subsystem-bench/examples/availability_read.yaml ``` +Note: test objectives may be wrapped up into a test sequence. +It is tipically used to run a suite of tests like in this [example](examples/availability_read.yaml). + ### Understanding the test configuration A single test configuration `TestConfiguration` struct applies to a single run of a certain test objective. @@ -175,36 +143,65 @@ the test is started. ### Example run -Let's run an availabilty read test which will recover availability for 10 cores with max PoV size on a 500 +Let's run an availabilty read test which will recover availability for 200 cores with max PoV size on a 1000 node validator network. + + ``` - target/testnet/subsystem-bench --n-cores 10 data-availability-read -[2023-11-28T09:01:59Z INFO subsystem_bench::core::display] n_validators = 500, n_cores = 10, pov_size = 5120 - 5120, - latency = None -[2023-11-28T09:01:59Z INFO subsystem-bench::availability] Generating template candidate index=0 pov_size=5242880 -[2023-11-28T09:01:59Z INFO subsystem-bench::availability] Created test environment. -[2023-11-28T09:01:59Z INFO subsystem-bench::availability] Pre-generating 10 candidates. -[2023-11-28T09:02:01Z INFO subsystem-bench::core] Initializing network emulation for 500 peers. -[2023-11-28T09:02:01Z INFO substrate_prometheus_endpoint] 〽️ Prometheus exporter started at 127.0.0.1:9999 -[2023-11-28T09:02:01Z INFO subsystem-bench::availability] Current block 1/1 -[2023-11-28T09:02:01Z INFO subsystem_bench::availability] 10 recoveries pending -[2023-11-28T09:02:04Z INFO subsystem_bench::availability] Block time 3231ms -[2023-11-28T09:02:04Z INFO subsystem-bench::availability] Sleeping till end of block (2768ms) -[2023-11-28T09:02:07Z INFO subsystem_bench::availability] All blocks processed in 6001ms -[2023-11-28T09:02:07Z INFO subsystem_bench::availability] Throughput: 51200 KiB/block -[2023-11-28T09:02:07Z INFO subsystem_bench::availability] Block time: 6001 ms -[2023-11-28T09:02:07Z INFO subsystem_bench::availability] - - Total received from network: 66 MiB - Total sent to network: 58 KiB - Total subsystem CPU usage 4.16s - CPU usage per block 4.16s - Total test environment CPU usage 0.00s - CPU usage per block 0.00s +target/testnet/subsystem-bench polkadot/node/subsystem-bench/examples/availability_write.yaml +[2024-02-19T14:10:32.981Z INFO subsystem_bench] Sequence contains 1 step(s) +[2024-02-19T14:10:32.981Z INFO subsystem-bench::cli] Step 1/1 +[2024-02-19T14:10:32.981Z INFO subsystem-bench::cli] [objective = DataAvailabilityWrite] n_validators = 1000, n_cores = 200, pov_size = 5120 - 5120, connectivity = 75, latency = Some(PeerLatency { mean_latency_ms: 30, std_dev: 2.0 }) +[2024-02-19T14:10:32.982Z INFO subsystem-bench::availability] Generating template candidate index=0 pov_size=5242880 +[2024-02-19T14:10:33.106Z INFO subsystem-bench::availability] Created test environment. +[2024-02-19T14:10:33.106Z INFO subsystem-bench::availability] Pre-generating 600 candidates. +[2024-02-19T14:10:34.096Z INFO subsystem-bench::network] Initializing emulation for a 1000 peer network. +[2024-02-19T14:10:34.096Z INFO subsystem-bench::network] connectivity 75%, latency Some(PeerLatency { mean_latency_ms: 30, std_dev: 2.0 }) +[2024-02-19T14:10:34.098Z INFO subsystem-bench::network] Network created, connected validator count 749 +[2024-02-19T14:10:34.099Z INFO subsystem-bench::availability] Seeding availability store with candidates ... +[2024-02-19T14:10:34.100Z INFO substrate_prometheus_endpoint] 〽️ Prometheus exporter started at 127.0.0.1:9999 +[2024-02-19T14:10:34.387Z INFO subsystem-bench::availability] Done +[2024-02-19T14:10:34.387Z INFO subsystem-bench::availability] Current block #1 +[2024-02-19T14:10:34.389Z INFO subsystem-bench::availability] Waiting for all emulated peers to receive their chunk from us ... +[2024-02-19T14:10:34.625Z INFO subsystem-bench::availability] All chunks received in 237ms +[2024-02-19T14:10:34.626Z INFO polkadot_subsystem_bench::availability] Waiting for 749 bitfields to be received and processed +[2024-02-19T14:10:35.710Z INFO subsystem-bench::availability] All bitfields processed +[2024-02-19T14:10:35.710Z INFO subsystem-bench::availability] All work for block completed in 1322ms +[2024-02-19T14:10:35.710Z INFO subsystem-bench::availability] Current block #2 +[2024-02-19T14:10:35.712Z INFO subsystem-bench::availability] Waiting for all emulated peers to receive their chunk from us ... +[2024-02-19T14:10:35.947Z INFO subsystem-bench::availability] All chunks received in 236ms +[2024-02-19T14:10:35.947Z INFO polkadot_subsystem_bench::availability] Waiting for 749 bitfields to be received and processed +[2024-02-19T14:10:37.038Z INFO subsystem-bench::availability] All bitfields processed +[2024-02-19T14:10:37.038Z INFO subsystem-bench::availability] All work for block completed in 1328ms +[2024-02-19T14:10:37.039Z INFO subsystem-bench::availability] Current block #3 +[2024-02-19T14:10:37.040Z INFO subsystem-bench::availability] Waiting for all emulated peers to receive their chunk from us ... +[2024-02-19T14:10:37.276Z INFO subsystem-bench::availability] All chunks received in 237ms +[2024-02-19T14:10:37.276Z INFO polkadot_subsystem_bench::availability] Waiting for 749 bitfields to be received and processed +[2024-02-19T14:10:38.362Z INFO subsystem-bench::availability] All bitfields processed +[2024-02-19T14:10:38.362Z INFO subsystem-bench::availability] All work for block completed in 1323ms +[2024-02-19T14:10:38.362Z INFO subsystem-bench::availability] All blocks processed in 3974ms +[2024-02-19T14:10:38.362Z INFO subsystem-bench::availability] Avg block time: 1324 ms +[2024-02-19T14:10:38.362Z INFO parachain::availability-store] received `Conclude` signal, exiting +[2024-02-19T14:10:38.362Z INFO parachain::bitfield-distribution] Conclude +[2024-02-19T14:10:38.362Z INFO subsystem-bench::network] Downlink channel closed, network interface task exiting + +polkadot/node/subsystem-bench/examples/availability_write.yaml #1 DataAvailabilityWrite + +Network usage, KiB total per block +Received from peers 12922.000 4307.333 +Sent to peers 47705.000 15901.667 + +CPU usage, seconds total per block +availability-distribution 0.045 0.015 +bitfield-distribution 0.104 0.035 +availability-store 0.304 0.101 +Test environment 3.213 1.071 ``` -`Block time` in the context of `data-availability-read` has a different meaning. It measures the amount of time it + + +`Block time` in the current context has a different meaning. It measures the amount of time it took the subsystem to finish processing all of the messages sent in the context of the current test block. ### Test logs @@ -233,8 +230,9 @@ Since the execution will be very slow, it's recommended not to run it together w benchmark results into account. A report is saved in a file `cachegrind_report.txt`. Example run results: + ``` -$ target/testnet/subsystem-bench --n-cores 10 --cache-misses data-availability-read +$ target/testnet/subsystem-bench --cache-misses cache-misses-data-availability-read.yaml $ cat cachegrind_report.txt I refs: 64,622,081,485 I1 misses: 3,018,168 @@ -275,7 +273,7 @@ happy and negative scenarios (low bandwidth, network errors and low connectivity To faster write a new test objective you need to use some higher level wrappers and logic: `TestEnvironment`, `TestConfiguration`, `TestAuthorities`, `NetworkEmulator`. To create the `TestEnvironment` you will -need to also build an `Overseer`, but that should be easy using the mockups for subsystems in`core::mock`. +need to also build an `Overseer`, but that should be easy using the mockups for subsystems in `mock`. ### Mocking diff --git a/polkadot/node/subsystem-bench/examples/approvals_no_shows.yaml b/polkadot/node/subsystem-bench/examples/approvals_no_shows.yaml index 758c7fbbf11..146da57d44c 100644 --- a/polkadot/node/subsystem-bench/examples/approvals_no_shows.yaml +++ b/polkadot/node/subsystem-bench/examples/approvals_no_shows.yaml @@ -1,14 +1,14 @@ TestConfiguration: # Test 1 - objective: !ApprovalVoting - last_considered_tranche: 89 coalesce_mean: 3.0 coalesce_std_dev: 1.0 + enable_assignments_v2: true + last_considered_tranche: 89 stop_when_approved: true coalesce_tranche_diff: 12 - workdir_prefix: "/tmp/" - enable_assignments_v2: true num_no_shows_per_candidate: 10 + workdir_prefix: "/tmp/" n_validators: 500 n_cores: 100 min_pov_size: 1120 diff --git a/polkadot/node/subsystem-bench/examples/approvals_throughput.yaml b/polkadot/node/subsystem-bench/examples/approvals_throughput.yaml index 9eeeefc53a4..6b17e62c20a 100644 --- a/polkadot/node/subsystem-bench/examples/approvals_throughput.yaml +++ b/polkadot/node/subsystem-bench/examples/approvals_throughput.yaml @@ -7,11 +7,10 @@ TestConfiguration: last_considered_tranche: 89 stop_when_approved: false coalesce_tranche_diff: 12 - workdir_prefix: "/tmp" num_no_shows_per_candidate: 0 + workdir_prefix: "/tmp" n_validators: 500 n_cores: 100 - n_included_candidates: 100 min_pov_size: 1120 max_pov_size: 5120 peer_bandwidth: 524288000000 diff --git a/polkadot/node/subsystem-bench/examples/approvals_throughput_best_case.yaml b/polkadot/node/subsystem-bench/examples/approvals_throughput_best_case.yaml index 370bb31a5c4..e946c28e8ef 100644 --- a/polkadot/node/subsystem-bench/examples/approvals_throughput_best_case.yaml +++ b/polkadot/node/subsystem-bench/examples/approvals_throughput_best_case.yaml @@ -7,8 +7,8 @@ TestConfiguration: last_considered_tranche: 89 stop_when_approved: true coalesce_tranche_diff: 12 - workdir_prefix: "/tmp/" num_no_shows_per_candidate: 0 + workdir_prefix: "/tmp/" n_validators: 500 n_cores: 100 min_pov_size: 1120 diff --git a/polkadot/node/subsystem-bench/examples/approvals_throughput_no_optimisations_enabled.yaml b/polkadot/node/subsystem-bench/examples/approvals_throughput_no_optimisations_enabled.yaml index 30b9ac8dc50..8f4b050e72f 100644 --- a/polkadot/node/subsystem-bench/examples/approvals_throughput_no_optimisations_enabled.yaml +++ b/polkadot/node/subsystem-bench/examples/approvals_throughput_no_optimisations_enabled.yaml @@ -7,8 +7,8 @@ TestConfiguration: last_considered_tranche: 89 stop_when_approved: false coalesce_tranche_diff: 12 - workdir_prefix: "/tmp/" num_no_shows_per_candidate: 0 + workdir_prefix: "/tmp/" n_validators: 500 n_cores: 100 min_pov_size: 1120 diff --git a/polkadot/node/subsystem-bench/src/availability/cli.rs b/polkadot/node/subsystem-bench/src/availability/cli.rs deleted file mode 100644 index 65df8c1552a..00000000000 --- a/polkadot/node/subsystem-bench/src/availability/cli.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Polkadot. - -// Polkadot is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Polkadot is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Polkadot. If not, see . - -use serde::{Deserialize, Serialize}; - -#[derive(clap::ValueEnum, Clone, Copy, Debug, PartialEq)] -#[value(rename_all = "kebab-case")] -#[non_exhaustive] -pub enum NetworkEmulation { - Ideal, - Healthy, - Degraded, -} - -#[derive(Debug, Clone, Serialize, Deserialize, clap::Parser)] -#[clap(rename_all = "kebab-case")] -#[allow(missing_docs)] -pub struct DataAvailabilityReadOptions { - #[clap(short, long, default_value_t = false)] - /// Turbo boost AD Read by fetching the full availability datafrom backers first. Saves CPU as - /// we don't need to re-construct from chunks. Tipically this is only faster if nodes have - /// enough bandwidth. - pub fetch_from_backers: bool, -} diff --git a/polkadot/node/subsystem-bench/src/subsystem-bench.rs b/polkadot/node/subsystem-bench/src/cli/subsystem-bench.rs similarity index 62% rename from polkadot/node/subsystem-bench/src/subsystem-bench.rs rename to polkadot/node/subsystem-bench/src/cli/subsystem-bench.rs index 0803f175474..deb351360d7 100644 --- a/polkadot/node/subsystem-bench/src/subsystem-bench.rs +++ b/polkadot/node/subsystem-bench/src/cli/subsystem-bench.rs @@ -14,54 +14,32 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! A tool for running subsystem benchmark tests designed for development and -//! CI regression testing. - -use approval::{bench_approvals, ApprovalsOptions}; -use availability::{ - cli::{DataAvailabilityReadOptions, NetworkEmulation}, - prepare_test, TestState, -}; +//! A tool for running subsystem benchmark tests +//! designed for development and CI regression testing. + use clap::Parser; -use clap_num::number_range; use color_eyre::eyre; use colored::Colorize; -use core::{ - configuration::TestConfiguration, - display::display_configuration, - environment::{TestEnvironment, GENESIS_HASH}, -}; +use polkadot_subsystem_bench::{approval, availability, configuration}; use pyroscope::PyroscopeAgent; use pyroscope_pprofrs::{pprof_backend, PprofConfig}; use serde::{Deserialize, Serialize}; use std::path::Path; -mod approval; -mod availability; -mod core; mod valgrind; -const LOG_TARGET: &str = "subsystem-bench"; - -fn le_100(s: &str) -> Result { - number_range(s, 0, 100) -} - -fn le_5000(s: &str) -> Result { - number_range(s, 0, 5000) -} +const LOG_TARGET: &str = "subsystem-bench::cli"; /// Supported test objectives #[derive(Debug, Clone, Parser, Serialize, Deserialize)] #[command(rename_all = "kebab-case")] pub enum TestObjective { /// Benchmark availability recovery strategies. - DataAvailabilityRead(DataAvailabilityReadOptions), + DataAvailabilityRead(availability::DataAvailabilityReadOptions), /// Benchmark availability and bitfield distribution. DataAvailabilityWrite, /// Benchmark the approval-voting and approval-distribution subsystems. - ApprovalVoting(ApprovalsOptions), - Unimplemented, + ApprovalVoting(approval::ApprovalsOptions), } impl std::fmt::Display for TestObjective { @@ -73,39 +51,37 @@ impl std::fmt::Display for TestObjective { Self::DataAvailabilityRead(_) => "DataAvailabilityRead", Self::DataAvailabilityWrite => "DataAvailabilityWrite", Self::ApprovalVoting(_) => "ApprovalVoting", - Self::Unimplemented => "Unimplemented", } ) } } -#[derive(Debug, Parser)] -#[allow(missing_docs)] -struct BenchCli { - #[arg(long, value_enum, ignore_case = true, default_value_t = NetworkEmulation::Ideal)] - /// The type of network to be emulated - pub network: NetworkEmulation, - - #[clap(short, long)] - /// The bandwidth of emulated remote peers in KiB - pub peer_bandwidth: Option, - - #[clap(short, long)] - /// The bandwidth of our node in KiB - pub bandwidth: Option, - - #[clap(long, value_parser=le_100)] - /// Emulated peer connection ratio [0-100]. - pub connectivity: Option, +/// The test input parameters +#[derive(Clone, Debug, Serialize, Deserialize)] +struct CliTestConfiguration { + /// Test Objective + pub objective: TestObjective, + /// Test Configuration + #[serde(flatten)] + pub test_config: configuration::TestConfiguration, +} - #[clap(long, value_parser=le_5000)] - /// Mean remote peer latency in milliseconds [0-5000]. - pub peer_mean_latency: Option, +#[derive(Serialize, Deserialize)] +pub struct TestSequence { + #[serde(rename(serialize = "TestConfiguration", deserialize = "TestConfiguration"))] + test_configurations: Vec, +} - #[clap(long, value_parser=le_5000)] - /// Remote peer latency standard deviation - pub peer_latency_std_dev: Option, +impl TestSequence { + fn new_from_file(path: &Path) -> std::io::Result { + let string = String::from_utf8(std::fs::read(path)?).expect("File is valid UTF8"); + Ok(serde_yaml::from_str(&string).expect("File is valid test sequence YA")) + } +} +#[derive(Debug, Parser)] +#[allow(missing_docs)] +struct BenchCli { #[clap(long, default_value_t = false)] /// Enable CPU Profiling with Pyroscope pub profile: bool, @@ -122,10 +98,6 @@ struct BenchCli { /// Enable Cache Misses Profiling with Valgrind. Linux only, Valgrind must be in the PATH pub cache_misses: bool, - #[clap(long, default_value_t = false)] - /// Shows the output in YAML format - pub yaml_output: bool, - #[arg(required = true)] /// Path to the test sequence configuration file pub path: String, @@ -148,49 +120,60 @@ impl BenchCli { None }; - let test_sequence = core::configuration::TestSequence::new_from_file(Path::new(&self.path)) + let test_sequence = TestSequence::new_from_file(Path::new(&self.path)) .expect("File exists") - .into_vec(); + .test_configurations; let num_steps = test_sequence.len(); gum::info!("{}", format!("Sequence contains {} step(s)", num_steps).bright_purple()); - for (index, test_config) in test_sequence.into_iter().enumerate() { - let benchmark_name = format!("{} #{} {}", &self.path, index + 1, test_config.objective); - gum::info!(target: LOG_TARGET, "{}", format!("Step {}/{}", index + 1, num_steps).bright_purple(),); - display_configuration(&test_config); - let usage = match test_config.objective { - TestObjective::DataAvailabilityRead(ref _opts) => { - let mut state = TestState::new(&test_config); - let (mut env, _protocol_config) = prepare_test(test_config, &mut state); + for (index, CliTestConfiguration { objective, mut test_config }) in + test_sequence.into_iter().enumerate() + { + let benchmark_name = format!("{} #{} {}", &self.path, index + 1, objective); + gum::info!(target: LOG_TARGET, "{}", format!("Step {}/{}", index + 1, num_steps).bright_purple(),); + gum::info!(target: LOG_TARGET, "[{}] {}", format!("objective = {:?}", objective).green(), test_config); + test_config.generate_pov_sizes(); + + let usage = match objective { + TestObjective::DataAvailabilityRead(opts) => { + let mut state = availability::TestState::new(&test_config); + let (mut env, _protocol_config) = availability::prepare_test( + test_config, + &mut state, + availability::TestDataAvailability::Read(opts), + true, + ); env.runtime().block_on(availability::benchmark_availability_read( &benchmark_name, &mut env, state, )) }, - TestObjective::ApprovalVoting(ref options) => { - let (mut env, state) = - approval::prepare_test(test_config.clone(), options.clone()); - env.runtime().block_on(bench_approvals(&benchmark_name, &mut env, state)) - }, TestObjective::DataAvailabilityWrite => { - let mut state = TestState::new(&test_config); - let (mut env, _protocol_config) = prepare_test(test_config, &mut state); + let mut state = availability::TestState::new(&test_config); + let (mut env, _protocol_config) = availability::prepare_test( + test_config, + &mut state, + availability::TestDataAvailability::Write, + true, + ); env.runtime().block_on(availability::benchmark_availability_write( &benchmark_name, &mut env, state, )) }, - TestObjective::Unimplemented => todo!(), - }; - - let output = if self.yaml_output { - serde_yaml::to_string(&vec![usage])? - } else { - usage.to_string() + TestObjective::ApprovalVoting(ref options) => { + let (mut env, state) = + approval::prepare_test(test_config.clone(), options.clone(), true); + env.runtime().block_on(approval::bench_approvals( + &benchmark_name, + &mut env, + state, + )) + }, }; - println!("{}", output); + println!("{}", usage); } if let Some(agent_running) = agent_running { diff --git a/polkadot/node/subsystem-bench/src/valgrind.rs b/polkadot/node/subsystem-bench/src/cli/valgrind.rs similarity index 100% rename from polkadot/node/subsystem-bench/src/valgrind.rs rename to polkadot/node/subsystem-bench/src/cli/valgrind.rs diff --git a/polkadot/node/subsystem-bench/src/approval/helpers.rs b/polkadot/node/subsystem-bench/src/lib/approval/helpers.rs similarity index 99% rename from polkadot/node/subsystem-bench/src/approval/helpers.rs rename to polkadot/node/subsystem-bench/src/lib/approval/helpers.rs index 623d91848f5..af5ff5aa1fa 100644 --- a/polkadot/node/subsystem-bench/src/approval/helpers.rs +++ b/polkadot/node/subsystem-bench/src/lib/approval/helpers.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use crate::core::configuration::TestAuthorities; +use crate::configuration::TestAuthorities; use itertools::Itertools; use polkadot_node_core_approval_voting::time::{Clock, SystemClock, Tick}; use polkadot_node_network_protocol::{ diff --git a/polkadot/node/subsystem-bench/src/approval/message_generator.rs b/polkadot/node/subsystem-bench/src/lib/approval/message_generator.rs similarity index 97% rename from polkadot/node/subsystem-bench/src/approval/message_generator.rs rename to polkadot/node/subsystem-bench/src/lib/approval/message_generator.rs index a7103401324..c1b31a509f6 100644 --- a/polkadot/node/subsystem-bench/src/approval/message_generator.rs +++ b/polkadot/node/subsystem-bench/src/lib/approval/message_generator.rs @@ -18,15 +18,12 @@ use crate::{ approval::{ helpers::{generate_babe_epoch, generate_topology}, test_message::{MessagesBundle, TestMessageInfo}, - ApprovalTestState, BlockTestData, GeneratedState, BUFFER_FOR_GENERATION_MILLIS, LOG_TARGET, - SLOT_DURATION_MILLIS, + ApprovalTestState, ApprovalsOptions, BlockTestData, GeneratedState, + BUFFER_FOR_GENERATION_MILLIS, LOG_TARGET, SLOT_DURATION_MILLIS, }, - core::{ - configuration::{TestAuthorities, TestConfiguration}, - mock::runtime_api::session_info_for_peers, - NODE_UNDER_TEST, - }, - ApprovalsOptions, TestObjective, + configuration::{TestAuthorities, TestConfiguration}, + mock::runtime_api::session_info_for_peers, + NODE_UNDER_TEST, }; use futures::SinkExt; use itertools::Itertools; @@ -132,11 +129,7 @@ impl PeerMessagesGenerator { options: &ApprovalsOptions, ) -> String { let mut fingerprint = options.fingerprint(); - let mut exclude_objective = configuration.clone(); - // The objective contains the full content of `ApprovalOptions`, we don't want to put all of - // that in fingerprint, so execlute it because we add it manually see above. - exclude_objective.objective = TestObjective::Unimplemented; - let configuration_bytes = bincode::serialize(&exclude_objective).unwrap(); + let configuration_bytes = bincode::serialize(&configuration).unwrap(); fingerprint.extend(configuration_bytes); let mut sha1 = sha1::Sha1::new(); sha1.update(fingerprint); diff --git a/polkadot/node/subsystem-bench/src/approval/mock_chain_selection.rs b/polkadot/node/subsystem-bench/src/lib/approval/mock_chain_selection.rs similarity index 100% rename from polkadot/node/subsystem-bench/src/approval/mock_chain_selection.rs rename to polkadot/node/subsystem-bench/src/lib/approval/mock_chain_selection.rs diff --git a/polkadot/node/subsystem-bench/src/approval/mod.rs b/polkadot/node/subsystem-bench/src/lib/approval/mod.rs similarity index 97% rename from polkadot/node/subsystem-bench/src/approval/mod.rs rename to polkadot/node/subsystem-bench/src/lib/approval/mod.rs index f07912de188..450faf06123 100644 --- a/polkadot/node/subsystem-bench/src/approval/mod.rs +++ b/polkadot/node/subsystem-bench/src/lib/approval/mod.rs @@ -24,25 +24,21 @@ use crate::{ mock_chain_selection::MockChainSelection, test_message::{MessagesBundle, TestMessageInfo}, }, - core::{ - configuration::TestAuthorities, - environment::{ - BenchmarkUsage, TestEnvironment, TestEnvironmentDependencies, MAX_TIME_OF_FLIGHT, - }, - mock::{ - chain_api::{ChainApiState, MockChainApi}, - dummy_builder, - network_bridge::{MockNetworkBridgeRx, MockNetworkBridgeTx}, - runtime_api::MockRuntimeApi, - AlwaysSupportsParachains, TestSyncOracle, - }, - network::{ - new_network, HandleNetworkMessage, NetworkEmulatorHandle, NetworkInterface, - NetworkInterfaceReceiver, - }, - NODE_UNDER_TEST, + configuration::{TestAuthorities, TestConfiguration}, + dummy_builder, + environment::{TestEnvironment, TestEnvironmentDependencies, MAX_TIME_OF_FLIGHT}, + mock::{ + chain_api::{ChainApiState, MockChainApi}, + network_bridge::{MockNetworkBridgeRx, MockNetworkBridgeTx}, + runtime_api::MockRuntimeApi, + AlwaysSupportsParachains, TestSyncOracle, }, - TestConfiguration, + network::{ + new_network, HandleNetworkMessage, NetworkEmulatorHandle, NetworkInterface, + NetworkInterfaceReceiver, + }, + usage::BenchmarkUsage, + NODE_UNDER_TEST, }; use colored::Colorize; use futures::channel::oneshot; @@ -472,11 +468,9 @@ impl ApprovalTestState { impl HandleNetworkMessage for ApprovalTestState { fn handle( &self, - _message: crate::core::network::NetworkMessage, - _node_sender: &mut futures::channel::mpsc::UnboundedSender< - crate::core::network::NetworkMessage, - >, - ) -> Option { + _message: crate::network::NetworkMessage, + _node_sender: &mut futures::channel::mpsc::UnboundedSender, + ) -> Option { self.total_sent_messages_from_node .as_ref() .fetch_add(1, std::sync::atomic::Ordering::SeqCst); @@ -841,8 +835,14 @@ fn build_overseer( pub fn prepare_test( config: TestConfiguration, options: ApprovalsOptions, + with_prometheus_endpoint: bool, ) -> (TestEnvironment, ApprovalTestState) { - prepare_test_inner(config, TestEnvironmentDependencies::default(), options) + prepare_test_inner( + config, + TestEnvironmentDependencies::default(), + options, + with_prometheus_endpoint, + ) } /// Build the test environment for an Approval benchmark. @@ -850,6 +850,7 @@ fn prepare_test_inner( config: TestConfiguration, dependencies: TestEnvironmentDependencies, options: ApprovalsOptions, + with_prometheus_endpoint: bool, ) -> (TestEnvironment, ApprovalTestState) { gum::info!("Prepare test state"); let state = ApprovalTestState::new(&config, options, &dependencies); @@ -878,6 +879,7 @@ fn prepare_test_inner( overseer, overseer_handle, state.test_authorities.clone(), + with_prometheus_endpoint, ), state, ) diff --git a/polkadot/node/subsystem-bench/src/approval/test_message.rs b/polkadot/node/subsystem-bench/src/lib/approval/test_message.rs similarity index 98% rename from polkadot/node/subsystem-bench/src/approval/test_message.rs rename to polkadot/node/subsystem-bench/src/lib/approval/test_message.rs index 8aaabc3426c..63e383509be 100644 --- a/polkadot/node/subsystem-bench/src/approval/test_message.rs +++ b/polkadot/node/subsystem-bench/src/lib/approval/test_message.rs @@ -15,9 +15,8 @@ // along with Polkadot. If not, see . use crate::{ - approval::{BlockTestData, CandidateTestData}, - core::configuration::TestAuthorities, - ApprovalsOptions, + approval::{ApprovalsOptions, BlockTestData, CandidateTestData}, + configuration::TestAuthorities, }; use itertools::Itertools; use parity_scale_codec::{Decode, Encode}; diff --git a/polkadot/node/subsystem-bench/src/availability/av_store_helpers.rs b/polkadot/node/subsystem-bench/src/lib/availability/av_store_helpers.rs similarity index 94% rename from polkadot/node/subsystem-bench/src/availability/av_store_helpers.rs rename to polkadot/node/subsystem-bench/src/lib/availability/av_store_helpers.rs index 261dbd0376c..3300def2235 100644 --- a/polkadot/node/subsystem-bench/src/availability/av_store_helpers.rs +++ b/polkadot/node/subsystem-bench/src/lib/availability/av_store_helpers.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use crate::core::{environment::TestEnvironmentDependencies, mock::TestSyncOracle}; +use crate::{environment::TestEnvironmentDependencies, mock::TestSyncOracle}; use polkadot_node_core_av_store::{AvailabilityStoreSubsystem, Config}; use polkadot_node_metrics::metrics::Metrics; use polkadot_node_subsystem_util::database::Database; diff --git a/polkadot/node/subsystem-bench/src/availability/mod.rs b/polkadot/node/subsystem-bench/src/lib/availability/mod.rs similarity index 94% rename from polkadot/node/subsystem-bench/src/availability/mod.rs rename to polkadot/node/subsystem-bench/src/lib/availability/mod.rs index ad9a17ff8f4..f012a5a907e 100644 --- a/polkadot/node/subsystem-bench/src/availability/mod.rs +++ b/polkadot/node/subsystem-bench/src/lib/availability/mod.rs @@ -15,22 +15,18 @@ // along with Polkadot. If not, see . use crate::{ - core::{ - configuration::TestConfiguration, - environment::{BenchmarkUsage, TestEnvironmentDependencies}, - mock::{ - av_store, - av_store::MockAvailabilityStore, - chain_api::{ChainApiState, MockChainApi}, - dummy_builder, - network_bridge::{self, MockNetworkBridgeRx, MockNetworkBridgeTx}, - runtime_api, - runtime_api::MockRuntimeApi, - AlwaysSupportsParachains, - }, - network::new_network, + configuration::TestConfiguration, + dummy_builder, + environment::{TestEnvironment, TestEnvironmentDependencies, GENESIS_HASH}, + mock::{ + av_store::{self, MockAvailabilityStore}, + chain_api::{ChainApiState, MockChainApi}, + network_bridge::{self, MockNetworkBridgeRx, MockNetworkBridgeTx}, + runtime_api::{self, MockRuntimeApi}, + AlwaysSupportsParachains, }, - TestEnvironment, TestObjective, GENESIS_HASH, + network::new_network, + usage::BenchmarkUsage, }; use av_store::NetworkAvailabilityState; use av_store_helpers::new_av_store; @@ -73,14 +69,30 @@ use sc_network::{ PeerId, }; use sc_service::SpawnTaskHandle; +use serde::{Deserialize, Serialize}; use sp_core::H256; use std::{collections::HashMap, iter::Cycle, ops::Sub, sync::Arc, time::Instant}; mod av_store_helpers; -pub(crate) mod cli; const LOG_TARGET: &str = "subsystem-bench::availability"; +#[derive(Debug, Clone, Serialize, Deserialize, clap::Parser)] +#[clap(rename_all = "kebab-case")] +#[allow(missing_docs)] +pub struct DataAvailabilityReadOptions { + #[clap(short, long, default_value_t = false)] + /// Turbo boost AD Read by fetching the full availability datafrom backers first. Saves CPU as + /// we don't need to re-construct from chunks. Tipically this is only faster if nodes have + /// enough bandwidth. + pub fetch_from_backers: bool, +} + +pub enum TestDataAvailability { + Read(DataAvailabilityReadOptions), + Write, +} + fn build_overseer_for_availability_read( spawn_task_handle: SpawnTaskHandle, runtime_api: MockRuntimeApi, @@ -141,14 +153,24 @@ fn build_overseer_for_availability_write( pub fn prepare_test( config: TestConfiguration, state: &mut TestState, + mode: TestDataAvailability, + with_prometheus_endpoint: bool, ) -> (TestEnvironment, Vec) { - prepare_test_inner(config, state, TestEnvironmentDependencies::default()) + prepare_test_inner( + config, + state, + mode, + TestEnvironmentDependencies::default(), + with_prometheus_endpoint, + ) } fn prepare_test_inner( config: TestConfiguration, state: &mut TestState, + mode: TestDataAvailability, dependencies: TestEnvironmentDependencies, + with_prometheus_endpoint: bool, ) -> (TestEnvironment, Vec) { // Generate test authorities. let test_authorities = config.generate_authorities(); @@ -216,8 +238,8 @@ fn prepare_test_inner( let network_bridge_rx = network_bridge::MockNetworkBridgeRx::new(network_receiver, Some(chunk_req_cfg.clone())); - let (overseer, overseer_handle) = match &state.config().objective { - TestObjective::DataAvailabilityRead(options) => { + let (overseer, overseer_handle) = match &mode { + TestDataAvailability::Read(options) => { let use_fast_path = options.fetch_from_backers; let subsystem = if use_fast_path { @@ -247,7 +269,7 @@ fn prepare_test_inner( &dependencies, ) }, - TestObjective::DataAvailabilityWrite => { + TestDataAvailability::Write => { let availability_distribution = AvailabilityDistributionSubsystem::new( test_authorities.keyring.keystore(), IncomingRequestReceivers { pov_req_receiver, chunk_req_receiver }, @@ -284,9 +306,6 @@ fn prepare_test_inner( &dependencies, ) }, - _ => { - unimplemented!("Invalid test objective") - }, }; ( @@ -297,6 +316,7 @@ fn prepare_test_inner( overseer, overseer_handle, test_authorities, + with_prometheus_endpoint, ), req_cfgs, ) @@ -326,10 +346,6 @@ pub struct TestState { } impl TestState { - fn config(&self) -> &TestConfiguration { - &self.config - } - pub fn next_candidate(&mut self) -> Option { let candidate = self.candidates.next(); let candidate_hash = candidate.as_ref().unwrap().hash(); diff --git a/polkadot/node/subsystem-bench/src/core/configuration.rs b/polkadot/node/subsystem-bench/src/lib/configuration.rs similarity index 83% rename from polkadot/node/subsystem-bench/src/core/configuration.rs rename to polkadot/node/subsystem-bench/src/lib/configuration.rs index 00be2a86b17..c7693308527 100644 --- a/polkadot/node/subsystem-bench/src/core/configuration.rs +++ b/polkadot/node/subsystem-bench/src/lib/configuration.rs @@ -16,7 +16,7 @@ //! Test configuration definition and helpers. -use crate::{core::keyring::Keyring, TestObjective}; +use crate::keyring::Keyring; use itertools::Itertools; use polkadot_primitives::{AssignmentId, AuthorityDiscoveryId, ValidatorId}; use rand::thread_rng; @@ -24,17 +24,7 @@ use rand_distr::{Distribution, Normal, Uniform}; use sc_network::PeerId; use serde::{Deserialize, Serialize}; use sp_consensus_babe::AuthorityId; -use std::{collections::HashMap, path::Path}; - -pub fn random_pov_size(min_pov_size: usize, max_pov_size: usize) -> usize { - random_uniform_sample(min_pov_size, max_pov_size) -} - -fn random_uniform_sample + From>(min_value: T, max_value: T) -> T { - Uniform::from(min_value.into()..=max_value.into()) - .sample(&mut thread_rng()) - .into() -} +use std::collections::HashMap; /// Peer networking latency configuration. #[derive(Clone, Debug, Default, Serialize, Deserialize)] @@ -87,8 +77,6 @@ fn default_no_show_slots() -> usize { /// The test input parameters #[derive(Clone, Debug, Serialize, Deserialize)] pub struct TestConfiguration { - /// The test objective - pub objective: TestObjective, /// Number of validators pub n_validators: usize, /// Number of cores @@ -115,7 +103,7 @@ pub struct TestConfiguration { pub max_pov_size: usize, /// Randomly sampled pov_sizes #[serde(skip)] - pov_sizes: Vec, + pub pov_sizes: Vec, /// The amount of bandiwdth remote validators have. #[serde(default = "default_bandwidth")] pub peer_bandwidth: usize, @@ -133,56 +121,32 @@ pub struct TestConfiguration { pub num_blocks: usize, } -fn generate_pov_sizes(count: usize, min_kib: usize, max_kib: usize) -> Vec { - (0..count).map(|_| random_pov_size(min_kib * 1024, max_kib * 1024)).collect() -} - -#[derive(Serialize, Deserialize)] -pub struct TestSequence { - #[serde(rename(serialize = "TestConfiguration", deserialize = "TestConfiguration"))] - test_configurations: Vec, -} - -impl TestSequence { - pub fn into_vec(self) -> Vec { - self.test_configurations - .into_iter() - .map(|mut config| { - config.pov_sizes = - generate_pov_sizes(config.n_cores, config.min_pov_size, config.max_pov_size); - config - }) - .collect() - } -} - -impl TestSequence { - pub fn new_from_file(path: &Path) -> std::io::Result { - let string = String::from_utf8(std::fs::read(path)?).expect("File is valid UTF8"); - Ok(serde_yaml::from_str(&string).expect("File is valid test sequence YA")) +impl Default for TestConfiguration { + fn default() -> Self { + Self { + n_validators: Default::default(), + n_cores: Default::default(), + needed_approvals: default_needed_approvals(), + zeroth_delay_tranche_width: default_zeroth_delay_tranche_width(), + relay_vrf_modulo_samples: default_relay_vrf_modulo_samples(), + n_delay_tranches: default_n_delay_tranches(), + no_show_slots: default_no_show_slots(), + max_validators_per_core: default_backing_group_size(), + min_pov_size: default_pov_size(), + max_pov_size: default_pov_size(), + pov_sizes: Default::default(), + peer_bandwidth: default_bandwidth(), + bandwidth: default_bandwidth(), + latency: Default::default(), + connectivity: default_connectivity(), + num_blocks: Default::default(), + } } } -/// Helper struct for authority related state. -#[derive(Clone)] -pub struct TestAuthorities { - pub keyring: Keyring, - pub validator_public: Vec, - pub validator_authority_id: Vec, - pub validator_babe_id: Vec, - pub validator_assignment_id: Vec, - pub key_seeds: Vec, - pub peer_ids: Vec, - pub peer_id_to_authority: HashMap, -} - impl TestConfiguration { - #[allow(unused)] - pub fn write_to_disk(&self) { - // Serialize a slice of configurations - let yaml = serde_yaml::to_string(&TestSequence { test_configurations: vec![self.clone()] }) - .unwrap(); - std::fs::write("last_test.yaml", yaml).unwrap(); + pub fn generate_pov_sizes(&mut self) { + self.pov_sizes = generate_pov_sizes(self.n_cores, self.min_pov_size, self.max_pov_size); } pub fn pov_sizes(&self) -> &[usize] { @@ -239,6 +203,33 @@ impl TestConfiguration { } } +fn random_uniform_sample + From>(min_value: T, max_value: T) -> T { + Uniform::from(min_value.into()..=max_value.into()) + .sample(&mut thread_rng()) + .into() +} + +fn random_pov_size(min_pov_size: usize, max_pov_size: usize) -> usize { + random_uniform_sample(min_pov_size, max_pov_size) +} + +fn generate_pov_sizes(count: usize, min_kib: usize, max_kib: usize) -> Vec { + (0..count).map(|_| random_pov_size(min_kib * 1024, max_kib * 1024)).collect() +} + +/// Helper struct for authority related state. +#[derive(Clone)] +pub struct TestAuthorities { + pub keyring: Keyring, + pub validator_public: Vec, + pub validator_authority_id: Vec, + pub validator_babe_id: Vec, + pub validator_assignment_id: Vec, + pub key_seeds: Vec, + pub peer_ids: Vec, + pub peer_id_to_authority: HashMap, +} + /// Sample latency (in milliseconds) from a normal distribution with parameters /// specified in `maybe_peer_latency`. pub fn random_latency(maybe_peer_latency: Option<&PeerLatency>) -> usize { diff --git a/polkadot/node/subsystem-bench/src/core/display.rs b/polkadot/node/subsystem-bench/src/lib/display.rs similarity index 89% rename from polkadot/node/subsystem-bench/src/core/display.rs rename to polkadot/node/subsystem-bench/src/lib/display.rs index 13a349382e2..b153d54a7c3 100644 --- a/polkadot/node/subsystem-bench/src/core/display.rs +++ b/polkadot/node/subsystem-bench/src/lib/display.rs @@ -19,7 +19,7 @@ //! //! Currently histogram buckets are skipped. -use crate::{TestConfiguration, LOG_TARGET}; +use crate::configuration::TestConfiguration; use colored::Colorize; use prometheus::{ proto::{MetricFamily, MetricType}, @@ -27,6 +27,8 @@ use prometheus::{ }; use std::fmt::Display; +const LOG_TARGET: &str = "subsystem-bench::display"; + #[derive(Default, Debug)] pub struct MetricCollection(Vec); @@ -85,6 +87,7 @@ impl Display for MetricCollection { Ok(()) } } + #[derive(Debug, Clone)] pub struct TestMetric { name: String, @@ -184,15 +187,16 @@ pub fn parse_metrics(registry: &Registry) -> MetricCollection { test_metrics.into() } -pub fn display_configuration(test_config: &TestConfiguration) { - gum::info!( - "[{}] {}, {}, {}, {}, {}", - format!("objective = {:?}", test_config.objective).green(), - format!("n_validators = {}", test_config.n_validators).blue(), - format!("n_cores = {}", test_config.n_cores).blue(), - format!("pov_size = {} - {}", test_config.min_pov_size, test_config.max_pov_size) - .bright_black(), - format!("connectivity = {}", test_config.connectivity).bright_black(), - format!("latency = {:?}", test_config.latency).bright_black(), - ); +impl Display for TestConfiguration { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}, {}, {}, {}, {}", + format!("n_validators = {}", self.n_validators).blue(), + format!("n_cores = {}", self.n_cores).blue(), + format!("pov_size = {} - {}", self.min_pov_size, self.max_pov_size).bright_black(), + format!("connectivity = {}", self.connectivity).bright_black(), + format!("latency = {:?}", self.latency).bright_black(), + ) + } } diff --git a/polkadot/node/subsystem-bench/src/core/environment.rs b/polkadot/node/subsystem-bench/src/lib/environment.rs similarity index 88% rename from polkadot/node/subsystem-bench/src/core/environment.rs rename to polkadot/node/subsystem-bench/src/lib/environment.rs index ca4c41cf45f..958ed50d089 100644 --- a/polkadot/node/subsystem-bench/src/core/environment.rs +++ b/polkadot/node/subsystem-bench/src/lib/environment.rs @@ -17,13 +17,11 @@ //! Test environment implementation use crate::{ - core::{ - configuration::TestAuthorities, mock::AlwaysSupportsParachains, - network::NetworkEmulatorHandle, - }, - TestConfiguration, + configuration::{TestAuthorities, TestConfiguration}, + mock::AlwaysSupportsParachains, + network::NetworkEmulatorHandle, + usage::{BenchmarkUsage, ResourceUsage}, }; -use colored::Colorize; use core::time::Duration; use futures::{Future, FutureExt}; use polkadot_node_subsystem::{messages::AllMessages, Overseer, SpawnGlue, TimeoutExt}; @@ -33,7 +31,6 @@ use polkadot_node_subsystem_util::metrics::prometheus::{ }; use polkadot_overseer::{BlockInfo, Handle as OverseerHandle}; use sc_service::{SpawnTaskHandle, TaskManager}; -use serde::{Deserialize, Serialize}; use std::net::{Ipv4Addr, SocketAddr}; use tokio::runtime::Handle; @@ -204,6 +201,7 @@ impl TestEnvironment { overseer: Overseer, AlwaysSupportsParachains>, overseer_handle: OverseerHandle, authorities: TestAuthorities, + with_prometheus_endpoint: bool, ) -> Self { let metrics = TestEnvironmentMetrics::new(&dependencies.registry) .expect("Metrics need to be registered"); @@ -211,19 +209,21 @@ impl TestEnvironment { let spawn_handle = dependencies.task_manager.spawn_handle(); spawn_handle.spawn_blocking("overseer", "overseer", overseer.run().boxed()); - let registry_clone = dependencies.registry.clone(); - dependencies.task_manager.spawn_handle().spawn_blocking( - "prometheus", - "test-environment", - async move { - prometheus_endpoint::init_prometheus( - SocketAddr::new(std::net::IpAddr::V4(Ipv4Addr::LOCALHOST), 9999), - registry_clone, - ) - .await - .unwrap(); - }, - ); + if with_prometheus_endpoint { + let registry_clone = dependencies.registry.clone(); + dependencies.task_manager.spawn_handle().spawn_blocking( + "prometheus", + "test-environment", + async move { + prometheus_endpoint::init_prometheus( + SocketAddr::new(std::net::IpAddr::V4(Ipv4Addr::LOCALHOST), 9999), + registry_clone, + ) + .await + .unwrap(); + }, + ); + } TestEnvironment { runtime_handle: dependencies.runtime.handle().clone(), @@ -411,41 +411,3 @@ impl TestEnvironment { usage } } - -#[derive(Debug, Serialize, Deserialize)] -pub struct BenchmarkUsage { - benchmark_name: String, - network_usage: Vec, - cpu_usage: Vec, -} - -impl std::fmt::Display for BenchmarkUsage { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!( - f, - "\n{}\n\n{}\n{}\n\n{}\n{}\n", - self.benchmark_name.purple(), - format!("{:<32}{:>12}{:>12}", "Network usage, KiB", "total", "per block").blue(), - self.network_usage - .iter() - .map(|v| v.to_string()) - .collect::>() - .join("\n"), - format!("{:<32}{:>12}{:>12}", "CPU usage in seconds", "total", "per block").blue(), - self.cpu_usage.iter().map(|v| v.to_string()).collect::>().join("\n") - ) - } -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct ResourceUsage { - resource_name: String, - total: f64, - per_block: f64, -} - -impl std::fmt::Display for ResourceUsage { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "{:<32}{:>12.3}{:>12.3}", self.resource_name.cyan(), self.total, self.per_block) - } -} diff --git a/polkadot/node/subsystem-bench/src/core/keyring.rs b/polkadot/node/subsystem-bench/src/lib/keyring.rs similarity index 100% rename from polkadot/node/subsystem-bench/src/core/keyring.rs rename to polkadot/node/subsystem-bench/src/lib/keyring.rs diff --git a/polkadot/node/subsystem-bench/src/core/mod.rs b/polkadot/node/subsystem-bench/src/lib/lib.rs similarity index 88% rename from polkadot/node/subsystem-bench/src/core/mod.rs rename to polkadot/node/subsystem-bench/src/lib/lib.rs index 764184c5b37..d06f2822a89 100644 --- a/polkadot/node/subsystem-bench/src/core/mod.rs +++ b/polkadot/node/subsystem-bench/src/lib/lib.rs @@ -15,11 +15,14 @@ // along with Polkadot. If not, see . // The validator index that represent the node that is under test. -pub(crate) const NODE_UNDER_TEST: u32 = 0; +pub const NODE_UNDER_TEST: u32 = 0; -pub(crate) mod configuration; +pub mod approval; +pub mod availability; +pub mod configuration; pub(crate) mod display; pub(crate) mod environment; pub(crate) mod keyring; pub(crate) mod mock; pub(crate) mod network; +pub mod usage; diff --git a/polkadot/node/subsystem-bench/src/core/mock/av_store.rs b/polkadot/node/subsystem-bench/src/lib/mock/av_store.rs similarity index 99% rename from polkadot/node/subsystem-bench/src/core/mock/av_store.rs rename to polkadot/node/subsystem-bench/src/lib/mock/av_store.rs index 0a7725c91e0..41c4fe2cbad 100644 --- a/polkadot/node/subsystem-bench/src/core/mock/av_store.rs +++ b/polkadot/node/subsystem-bench/src/lib/mock/av_store.rs @@ -16,7 +16,7 @@ //! A generic av store subsystem mockup suitable to be used in benchmarks. -use crate::core::network::{HandleNetworkMessage, NetworkMessage}; +use crate::network::{HandleNetworkMessage, NetworkMessage}; use futures::{channel::oneshot, FutureExt}; use parity_scale_codec::Encode; use polkadot_node_network_protocol::request_response::{ diff --git a/polkadot/node/subsystem-bench/src/core/mock/chain_api.rs b/polkadot/node/subsystem-bench/src/lib/mock/chain_api.rs similarity index 100% rename from polkadot/node/subsystem-bench/src/core/mock/chain_api.rs rename to polkadot/node/subsystem-bench/src/lib/mock/chain_api.rs diff --git a/polkadot/node/subsystem-bench/src/core/mock/dummy.rs b/polkadot/node/subsystem-bench/src/lib/mock/dummy.rs similarity index 100% rename from polkadot/node/subsystem-bench/src/core/mock/dummy.rs rename to polkadot/node/subsystem-bench/src/lib/mock/dummy.rs diff --git a/polkadot/node/subsystem-bench/src/core/mock/mod.rs b/polkadot/node/subsystem-bench/src/lib/mock/mod.rs similarity index 97% rename from polkadot/node/subsystem-bench/src/core/mock/mod.rs rename to polkadot/node/subsystem-bench/src/lib/mock/mod.rs index 46fdeb196c0..6dda9a47d39 100644 --- a/polkadot/node/subsystem-bench/src/core/mock/mod.rs +++ b/polkadot/node/subsystem-bench/src/lib/mock/mod.rs @@ -34,9 +34,10 @@ impl HeadSupportsParachains for AlwaysSupportsParachains { } // An orchestra with dummy subsystems +#[macro_export] macro_rules! dummy_builder { ($spawn_task_handle: ident, $metrics: ident) => {{ - use $crate::core::mock::dummy::*; + use $crate::mock::dummy::*; // Initialize a mock overseer. // All subsystem except approval_voting and approval_distribution are mock subsystems. @@ -72,7 +73,6 @@ macro_rules! dummy_builder { .spawner(SpawnGlue($spawn_task_handle)) }}; } -pub(crate) use dummy_builder; #[derive(Clone)] pub struct TestSyncOracle {} diff --git a/polkadot/node/subsystem-bench/src/core/mock/network_bridge.rs b/polkadot/node/subsystem-bench/src/lib/mock/network_bridge.rs similarity index 99% rename from polkadot/node/subsystem-bench/src/core/mock/network_bridge.rs rename to polkadot/node/subsystem-bench/src/lib/mock/network_bridge.rs index 4682c7ec79a..d598f6447d3 100644 --- a/polkadot/node/subsystem-bench/src/core/mock/network_bridge.rs +++ b/polkadot/node/subsystem-bench/src/lib/mock/network_bridge.rs @@ -17,7 +17,7 @@ //! Mocked `network-bridge` subsystems that uses a `NetworkInterface` to access //! the emulated network. -use crate::core::{ +use crate::{ configuration::TestAuthorities, network::{NetworkEmulatorHandle, NetworkInterfaceReceiver, NetworkMessage, RequestExt}, }; diff --git a/polkadot/node/subsystem-bench/src/core/mock/runtime_api.rs b/polkadot/node/subsystem-bench/src/lib/mock/runtime_api.rs similarity index 99% rename from polkadot/node/subsystem-bench/src/core/mock/runtime_api.rs rename to polkadot/node/subsystem-bench/src/lib/mock/runtime_api.rs index 0dd76efcbaf..53faf562f03 100644 --- a/polkadot/node/subsystem-bench/src/core/mock/runtime_api.rs +++ b/polkadot/node/subsystem-bench/src/lib/mock/runtime_api.rs @@ -16,7 +16,7 @@ //! A generic runtime api subsystem mockup suitable to be used in benchmarks. -use crate::core::configuration::{TestAuthorities, TestConfiguration}; +use crate::configuration::{TestAuthorities, TestConfiguration}; use bitvec::prelude::BitVec; use futures::FutureExt; use itertools::Itertools; diff --git a/polkadot/node/subsystem-bench/src/core/network.rs b/polkadot/node/subsystem-bench/src/lib/network.rs similarity index 99% rename from polkadot/node/subsystem-bench/src/core/network.rs rename to polkadot/node/subsystem-bench/src/lib/network.rs index e9124726d7c..1e09441792d 100644 --- a/polkadot/node/subsystem-bench/src/core/network.rs +++ b/polkadot/node/subsystem-bench/src/lib/network.rs @@ -33,7 +33,7 @@ // | // Subsystems under test -use crate::core::{ +use crate::{ configuration::{random_latency, TestAuthorities, TestConfiguration}, environment::TestEnvironmentDependencies, NODE_UNDER_TEST, diff --git a/polkadot/node/subsystem-bench/src/lib/usage.rs b/polkadot/node/subsystem-bench/src/lib/usage.rs new file mode 100644 index 00000000000..b83ef7d98d9 --- /dev/null +++ b/polkadot/node/subsystem-bench/src/lib/usage.rs @@ -0,0 +1,146 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Test usage implementation + +use colored::Colorize; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +#[derive(Debug, Serialize, Deserialize)] +pub struct BenchmarkUsage { + pub benchmark_name: String, + pub network_usage: Vec, + pub cpu_usage: Vec, +} + +impl std::fmt::Display for BenchmarkUsage { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!( + f, + "\n{}\n\n{}\n{}\n\n{}\n{}\n", + self.benchmark_name.purple(), + format!("{:<32}{:>12}{:>12}", "Network usage, KiB", "total", "per block").blue(), + self.network_usage + .iter() + .map(|v| v.to_string()) + .collect::>() + .join("\n"), + format!("{:<32}{:>12}{:>12}", "CPU usage, seconds", "total", "per block").blue(), + self.cpu_usage.iter().map(|v| v.to_string()).collect::>().join("\n") + ) + } +} + +impl BenchmarkUsage { + pub fn average(usages: &[Self]) -> Self { + let all_network_usages: Vec<&ResourceUsage> = + usages.iter().flat_map(|v| &v.network_usage).collect(); + let all_cpu_usage: Vec<&ResourceUsage> = usages.iter().flat_map(|v| &v.cpu_usage).collect(); + + Self { + benchmark_name: usages.first().map(|v| v.benchmark_name.clone()).unwrap_or_default(), + network_usage: ResourceUsage::average_by_resource_name(&all_network_usages), + cpu_usage: ResourceUsage::average_by_resource_name(&all_cpu_usage), + } + } + + pub fn check_network_usage(&self, checks: &[ResourceUsageCheck]) -> Vec { + check_usage(&self.benchmark_name, &self.network_usage, checks) + } + + pub fn check_cpu_usage(&self, checks: &[ResourceUsageCheck]) -> Vec { + check_usage(&self.benchmark_name, &self.cpu_usage, checks) + } + + pub fn cpu_usage_diff(&self, other: &Self, resource_name: &str) -> Option { + let self_res = self.cpu_usage.iter().find(|v| v.resource_name == resource_name); + let other_res = other.cpu_usage.iter().find(|v| v.resource_name == resource_name); + + match (self_res, other_res) { + (Some(self_res), Some(other_res)) => Some(self_res.diff(other_res)), + _ => None, + } + } +} + +fn check_usage( + benchmark_name: &str, + usage: &[ResourceUsage], + checks: &[ResourceUsageCheck], +) -> Vec { + checks + .iter() + .filter_map(|check| { + check_resource_usage(usage, check) + .map(|message| format!("{}: {}", benchmark_name, message)) + }) + .collect() +} + +fn check_resource_usage( + usage: &[ResourceUsage], + (resource_name, base, precision): &ResourceUsageCheck, +) -> Option { + if let Some(usage) = usage.iter().find(|v| v.resource_name == *resource_name) { + let diff = (base - usage.per_block).abs() / base; + if diff < *precision { + None + } else { + Some(format!( + "The resource `{}` is expected to be equal to {} with a precision {}, but the current value is {}", + resource_name, base, precision, usage.per_block + )) + } + } else { + Some(format!("The resource `{}` is not found", resource_name)) + } +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct ResourceUsage { + pub resource_name: String, + pub total: f64, + pub per_block: f64, +} + +impl std::fmt::Display for ResourceUsage { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{:<32}{:>12.3}{:>12.3}", self.resource_name.cyan(), self.total, self.per_block) + } +} + +impl ResourceUsage { + fn average_by_resource_name(usages: &[&Self]) -> Vec { + let mut by_name: HashMap> = Default::default(); + for usage in usages { + by_name.entry(usage.resource_name.clone()).or_default().push(usage); + } + let mut average = vec![]; + for (resource_name, values) in by_name { + let total = values.iter().map(|v| v.total).sum::() / values.len() as f64; + let per_block = values.iter().map(|v| v.per_block).sum::() / values.len() as f64; + average.push(Self { resource_name, total, per_block }); + } + average + } + + fn diff(&self, other: &Self) -> f64 { + (self.per_block - other.per_block).abs() / self.per_block + } +} + +type ResourceUsageCheck<'a> = (&'a str, f64, f64); -- GitLab From 62b78a16157134a1c38e0081eb60a1c03ac15df3 Mon Sep 17 00:00:00 2001 From: Alin Dima Date: Fri, 1 Mar 2024 20:25:24 +0200 Subject: [PATCH 336/392] provisioner: allow multiple cores assigned to the same para (#3233) https://github.com/paritytech/polkadot-sdk/issues/3130 builds on top of https://github.com/paritytech/polkadot-sdk/pull/3160 Processes the availability cores and builds a record of how many candidates it should request from prospective-parachains and their predecessors. Tries to supply as many candidates as the runtime can back. Note that the runtime changes to back multiple candidates per para are not yet done, but this paves the way for it. The following backing/inclusion policy is assumed: 1. the runtime will never back candidates of the same para which don't form a chain with the already backed candidates. Even if the others are still pending availability. We're optimistic that they won't time out and we don't want to back parachain forks (as the complexity would be huge). 2. if a candidate is timed out of the core before being included, all of its successors occupying a core will be evicted. 3. only the candidates which are made available and form a chain starting from the on-chain para head may be included/enacted and cleared from the cores. In other words, if para head is at A and the cores are occupied by B->C->D, and B and D are made available, only B will be included and its core cleared. C and D will remain on the cores awaiting for C to be made available or timed out. As point (2) above already says, if C is timed out, D will also be dropped. 4. The runtime will deduplicate candidates which form a cycle. For example if the provisioner supplies candidates A->B->A, the runtime will only back A (as the state output will be the same) Note that if a candidate is timed out, we don't guarantee that in the next relay chain block the block author will be able to fill all of the timed out cores of the para. That increases complexity by a lot. Instead, the provisioner will supply N candidates where N is the number of candidates timed out, but doesn't include their successors which will be also deleted by the runtime. This'll be backfilled in the next relay chain block. Adjacent changes: - Also fixes: https://github.com/paritytech/polkadot-sdk/issues/3141 - For non prospective-parachains, don't supply multiple candidates per para (we can't have elastic scaling without prospective parachains enabled). paras_inherent should already sanitise this input but it's more efficient this way. Note: all of these changes are backwards-compatible with the non-elastic-scaling scenario (one core per para). --- Cargo.lock | 3 + .../core/prospective-parachains/Cargo.toml | 1 + .../src/fragment_tree.rs | 570 ++++++++++++++-- .../core/prospective-parachains/src/lib.rs | 19 +- .../core/prospective-parachains/src/tests.rs | 497 +++++--------- polkadot/node/core/provisioner/Cargo.toml | 2 + polkadot/node/core/provisioner/src/error.rs | 12 +- polkadot/node/core/provisioner/src/lib.rs | 234 ++++--- polkadot/node/core/provisioner/src/tests.rs | 629 +++++++++++++++--- polkadot/node/subsystem-types/src/messages.rs | 14 +- prdoc/pr_3233.prdoc | 12 + 11 files changed, 1412 insertions(+), 581 deletions(-) create mode 100644 prdoc/pr_3233.prdoc diff --git a/Cargo.lock b/Cargo.lock index b12006bbcf7..c42ec612e6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12756,6 +12756,7 @@ dependencies = [ "polkadot-node-subsystem-util", "polkadot-primitives", "polkadot-primitives-test-helpers", + "rstest", "sc-keystore", "sp-application-crypto", "sp-core", @@ -12779,6 +12780,8 @@ dependencies = [ "polkadot-node-subsystem-util", "polkadot-primitives", "polkadot-primitives-test-helpers", + "rstest", + "schnellru", "sp-application-crypto", "sp-keystore", "thiserror", diff --git a/polkadot/node/core/prospective-parachains/Cargo.toml b/polkadot/node/core/prospective-parachains/Cargo.toml index 5b62d90c1d4..f66a66e859e 100644 --- a/polkadot/node/core/prospective-parachains/Cargo.toml +++ b/polkadot/node/core/prospective-parachains/Cargo.toml @@ -23,6 +23,7 @@ polkadot-node-subsystem = { path = "../../subsystem" } polkadot-node-subsystem-util = { path = "../../subsystem-util" } [dev-dependencies] +rstest = "0.18.2" assert_matches = "1" polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } polkadot-node-subsystem-types = { path = "../../subsystem-types" } diff --git a/polkadot/node/core/prospective-parachains/src/fragment_tree.rs b/polkadot/node/core/prospective-parachains/src/fragment_tree.rs index 04ee42a9de0..8061dc82d83 100644 --- a/polkadot/node/core/prospective-parachains/src/fragment_tree.rs +++ b/polkadot/node/core/prospective-parachains/src/fragment_tree.rs @@ -96,6 +96,7 @@ use std::{ use super::LOG_TARGET; use bitvec::prelude::*; +use polkadot_node_subsystem::messages::Ancestors; use polkadot_node_subsystem_util::inclusion_emulator::{ ConstraintModifications, Constraints, Fragment, ProspectiveCandidate, RelayChainBlockInfo, }; @@ -756,45 +757,46 @@ impl FragmentTree { depths.iter_ones().collect() } - /// Select `count` candidates after the given `required_path` which pass + /// Select `count` candidates after the given `ancestors` which pass /// the predicate and have not already been backed on chain. /// - /// Does an exhaustive search into the tree starting after `required_path`. - /// If there are multiple possibilities of size `count`, this will select the first one. - /// If there is no chain of size `count` that matches the criteria, this will return the largest - /// chain it could find with the criteria. - /// If there are no candidates meeting those criteria, returns an empty `Vec`. - /// Cycles are accepted, see module docs for the `Cycles` section. + /// Does an exhaustive search into the tree after traversing the ancestors path. + /// If the ancestors draw out a path that can be traversed in multiple ways, no + /// candidates will be returned. + /// If the ancestors do not draw out a full path (the path contains holes), candidates will be + /// suggested that may fill these holes. + /// If the ancestors don't draw out a valid path, no candidates will be returned. If there are + /// multiple possibilities of the same size, this will select the first one. If there is no + /// chain of size `count` that matches the criteria, this will return the largest chain it could + /// find with the criteria. If there are no candidates meeting those criteria, returns an empty + /// `Vec`. + /// Cycles are accepted, but this code expects that the runtime will deduplicate + /// identical candidates when occupying the cores (when proposing to back A->B->A, only A will + /// be backed on chain). /// - /// The intention of the `required_path` is to allow queries on the basis of + /// The intention of the `ancestors` is to allow queries on the basis of /// one or more candidates which were previously pending availability becoming - /// available and opening up more room on the core. - pub(crate) fn select_children( + /// available or candidates timing out. + pub(crate) fn find_backable_chain( &self, - required_path: &[CandidateHash], + ancestors: Ancestors, count: u32, pred: impl Fn(&CandidateHash) -> bool, ) -> Vec { - let base_node = { - // traverse the required path. - let mut node = NodePointer::Root; - for required_step in required_path { - if let Some(next_node) = self.node_candidate_child(node, &required_step) { - node = next_node; - } else { - return vec![] - }; - } - - node - }; - - // TODO: taking the first best selection might introduce bias - // or become gameable. - // - // For plausibly unique parachains, this shouldn't matter much. - // figure out alternative selection criteria? - self.select_children_inner(base_node, count, count, &pred, &mut vec![]) + if count == 0 { + return vec![] + } + // First, we need to order the ancestors. + // The node returned is the one from which we can start finding new backable candidates. + let Some(base_node) = self.find_ancestor_path(ancestors) else { return vec![] }; + + self.find_backable_chain_inner( + base_node, + count, + count, + &pred, + &mut Vec::with_capacity(count as usize), + ) } // Try finding a candidate chain starting from `base_node` of length `expected_count`. @@ -805,7 +807,7 @@ impl FragmentTree { // Cycles are accepted, but this doesn't allow for infinite execution time, because the maximum // depth we'll reach is `expected_count`. // - // Worst case performance is `O(num_forks ^ expected_count)`. + // Worst case performance is `O(num_forks ^ expected_count)`, the same as populating the tree. // Although an exponential function, this is actually a constant that can only be altered via // sudo/governance, because: // 1. `num_forks` at a given level is at most `max_candidate_depth * max_validators_per_core` @@ -817,7 +819,7 @@ impl FragmentTree { // scaling scenario). For non-elastic-scaling, this is just 1. In practice, this should be a // small number (1-3), capped by the total number of available cores (a constant alterable // only via governance/sudo). - fn select_children_inner( + fn find_backable_chain_inner( &self, base_node: NodePointer, expected_count: u32, @@ -857,7 +859,7 @@ impl FragmentTree { for (child_ptr, child_hash) in children { accumulator.push(child_hash); - let result = self.select_children_inner( + let result = self.find_backable_chain_inner( child_ptr, expected_count, remaining_count - 1, @@ -869,6 +871,9 @@ impl FragmentTree { // Short-circuit the search if we've found the right length. Otherwise, we'll // search for a max. + // Taking the first best selection doesn't introduce bias or become gameable, + // because `find_ancestor_path` uses a `HashSet` to track the ancestors, which + // makes the order in which ancestors are visited non-deterministic. if result.len() == expected_count as usize { return result } else if best_result.len() < result.len() { @@ -879,6 +884,93 @@ impl FragmentTree { best_result } + // Orders the ancestors into a viable path from root to the last one. + // Returns a pointer to the last node in the path. + // We assume that the ancestors form a chain (that the + // av-cores do not back parachain forks), None is returned otherwise. + // If we cannot use all ancestors, stop at the first found hole in the chain. This usually + // translates to a timed out candidate. + fn find_ancestor_path(&self, mut ancestors: Ancestors) -> Option { + // The number of elements in the path we've processed so far. + let mut depth = 0; + let mut last_node = NodePointer::Root; + let mut next_node: Option = Some(NodePointer::Root); + + while let Some(node) = next_node { + if depth > self.scope.max_depth { + return None; + } + + last_node = node; + + next_node = match node { + NodePointer::Root => { + let children = self + .nodes + .iter() + .enumerate() + .take_while(|n| n.1.parent == NodePointer::Root) + .map(|(index, node)| (NodePointer::Storage(index), node.candidate_hash)) + .collect::>(); + + self.find_valid_child(&mut ancestors, children.iter()).ok()? + }, + NodePointer::Storage(ptr) => { + let children = self.nodes.get(ptr).and_then(|n| Some(n.children.iter())); + if let Some(children) = children { + self.find_valid_child(&mut ancestors, children).ok()? + } else { + None + } + }, + }; + + depth += 1; + } + + Some(last_node) + } + + // Find a node from the given iterator which is present in the ancestors + // collection. If there are multiple such nodes, return an error and log a warning. We don't + // accept forks in a parachain to be backed. The supplied ancestors should all form a chain. + // If there is no such node, return None. + fn find_valid_child<'a>( + &self, + ancestors: &'a mut Ancestors, + nodes: impl Iterator + 'a, + ) -> Result, ()> { + let mut possible_children = + nodes.filter_map(|(node_ptr, hash)| match ancestors.remove(&hash) { + true => Some(node_ptr), + false => None, + }); + + // We don't accept forks in a parachain to be backed. The supplied ancestors + // should all form a chain. + let next = possible_children.next(); + if let Some(second_child) = possible_children.next() { + if let (Some(NodePointer::Storage(first_child)), NodePointer::Storage(second_child)) = + (next, second_child) + { + gum::error!( + target: LOG_TARGET, + para_id = ?self.scope.para, + relay_parent = ?self.scope.relay_parent, + "Trying to find new backable candidates for a parachain for which we've backed a fork.\ + This is a bug and the runtime should not have allowed it.\n\ + Backed candidates with the same parent: {}, {}", + self.nodes[*first_child].candidate_hash, + self.nodes[*second_child].candidate_hash, + ); + } + + Err(()) + } else { + Ok(next.copied()) + } + } + fn populate_from_bases(&mut self, storage: &CandidateStorage, initial_bases: Vec) { // Populate the tree breadth-first. let mut last_sweep_start = None; @@ -1061,8 +1153,18 @@ mod tests { use polkadot_node_subsystem_util::inclusion_emulator::InboundHrmpLimitations; use polkadot_primitives::{BlockNumber, CandidateCommitments, CandidateDescriptor, HeadData}; use polkadot_primitives_test_helpers as test_helpers; + use rstest::rstest; use std::iter; + impl NodePointer { + fn unwrap_idx(self) -> usize { + match self { + NodePointer::Root => panic!("Unexpected root"), + NodePointer::Storage(index) => index, + } + } + } + fn make_constraints( min_relay_parent_number: BlockNumber, valid_watermarks: Vec, @@ -1546,6 +1648,373 @@ mod tests { assert_eq!(tree.nodes[1].parent, NodePointer::Storage(0)); } + #[test] + fn test_find_ancestor_path_and_find_backable_chain_empty_tree() { + let para_id = ParaId::from(5u32); + let relay_parent = Hash::repeat_byte(1); + let required_parent: HeadData = vec![0xff].into(); + let max_depth = 10; + + // Empty tree + let storage = CandidateStorage::new(); + let base_constraints = make_constraints(0, vec![0], required_parent.clone()); + + let relay_parent_info = + RelayChainBlockInfo { number: 0, hash: relay_parent, storage_root: Hash::zero() }; + + let scope = Scope::with_ancestors( + para_id, + relay_parent_info, + base_constraints, + vec![], + max_depth, + vec![], + ) + .unwrap(); + let tree = FragmentTree::populate(scope, &storage); + assert_eq!(tree.candidates().collect::>().len(), 0); + assert_eq!(tree.nodes.len(), 0); + + assert_eq!(tree.find_ancestor_path(Ancestors::new()).unwrap(), NodePointer::Root); + assert_eq!(tree.find_backable_chain(Ancestors::new(), 2, |_| true), vec![]); + // Invalid candidate. + let ancestors: Ancestors = [CandidateHash::default()].into_iter().collect(); + assert_eq!(tree.find_ancestor_path(ancestors.clone()), Some(NodePointer::Root)); + assert_eq!(tree.find_backable_chain(ancestors, 2, |_| true), vec![]); + } + + #[rstest] + #[case(true, 13)] + #[case(false, 8)] + // The tree with no cycles looks like: + // Make a tree that looks like this (note that there's no cycle): + // +-(root)-+ + // | | + // +----0---+ 7 + // | | + // 1----+ 5 + // | | + // | | + // 2 6 + // | + // 3 + // | + // 4 + // + // The tree with cycles is the same as the first but has a cycle from 4 back to the state + // produced by 0 (It's bounded by the max_depth + 1). + // +-(root)-+ + // | | + // +----0---+ 7 + // | | + // 1----+ 5 + // | | + // | | + // 2 6 + // | + // 3 + // | + // 4---+ + // | | + // 1 5 + // | + // 2 + // | + // 3 + fn test_find_ancestor_path_and_find_backable_chain( + #[case] has_cycle: bool, + #[case] expected_node_count: usize, + ) { + let para_id = ParaId::from(5u32); + let relay_parent = Hash::repeat_byte(1); + let required_parent: HeadData = vec![0xff].into(); + let max_depth = 7; + let relay_parent_number = 0; + let relay_parent_storage_root = Hash::repeat_byte(69); + + let mut candidates = vec![]; + + // Candidate 0 + candidates.push(make_committed_candidate( + para_id, + relay_parent, + 0, + required_parent.clone(), + vec![0].into(), + 0, + )); + // Candidate 1 + candidates.push(make_committed_candidate( + para_id, + relay_parent, + 0, + vec![0].into(), + vec![1].into(), + 0, + )); + // Candidate 2 + candidates.push(make_committed_candidate( + para_id, + relay_parent, + 0, + vec![1].into(), + vec![2].into(), + 0, + )); + // Candidate 3 + candidates.push(make_committed_candidate( + para_id, + relay_parent, + 0, + vec![2].into(), + vec![3].into(), + 0, + )); + // Candidate 4 + candidates.push(make_committed_candidate( + para_id, + relay_parent, + 0, + vec![3].into(), + vec![4].into(), + 0, + )); + // Candidate 5 + candidates.push(make_committed_candidate( + para_id, + relay_parent, + 0, + vec![0].into(), + vec![5].into(), + 0, + )); + // Candidate 6 + candidates.push(make_committed_candidate( + para_id, + relay_parent, + 0, + vec![1].into(), + vec![6].into(), + 0, + )); + // Candidate 7 + candidates.push(make_committed_candidate( + para_id, + relay_parent, + 0, + required_parent.clone(), + vec![7].into(), + 0, + )); + + if has_cycle { + candidates[4] = make_committed_candidate( + para_id, + relay_parent, + 0, + vec![3].into(), + vec![0].into(), // put the cycle here back to the output state of 0. + 0, + ); + } + + let base_constraints = make_constraints(0, vec![0], required_parent.clone()); + let mut storage = CandidateStorage::new(); + + let relay_parent_info = RelayChainBlockInfo { + number: relay_parent_number, + hash: relay_parent, + storage_root: relay_parent_storage_root, + }; + + for (pvd, candidate) in candidates.iter() { + storage.add_candidate(candidate.clone(), pvd.clone()).unwrap(); + } + let candidates = + candidates.into_iter().map(|(_pvd, candidate)| candidate).collect::>(); + let scope = Scope::with_ancestors( + para_id, + relay_parent_info, + base_constraints, + vec![], + max_depth, + vec![], + ) + .unwrap(); + let tree = FragmentTree::populate(scope, &storage); + + assert_eq!(tree.candidates().collect::>().len(), candidates.len()); + assert_eq!(tree.nodes.len(), expected_node_count); + + // Do some common tests on both trees. + { + // No ancestors supplied. + assert_eq!(tree.find_ancestor_path(Ancestors::new()).unwrap(), NodePointer::Root); + assert_eq!( + tree.find_backable_chain(Ancestors::new(), 4, |_| true), + [0, 1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::>() + ); + // Ancestor which is not part of the tree. Will be ignored. + let ancestors: Ancestors = [CandidateHash::default()].into_iter().collect(); + assert_eq!(tree.find_ancestor_path(ancestors.clone()).unwrap(), NodePointer::Root); + assert_eq!( + tree.find_backable_chain(ancestors, 4, |_| true), + [0, 1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::>() + ); + // A chain fork. + let ancestors: Ancestors = + [(candidates[0].hash()), (candidates[7].hash())].into_iter().collect(); + assert_eq!(tree.find_ancestor_path(ancestors.clone()), None); + assert_eq!(tree.find_backable_chain(ancestors, 1, |_| true), vec![]); + + // Ancestors which are part of the tree but don't form a path. Will be ignored. + let ancestors: Ancestors = + [candidates[1].hash(), candidates[2].hash()].into_iter().collect(); + assert_eq!(tree.find_ancestor_path(ancestors.clone()).unwrap(), NodePointer::Root); + assert_eq!( + tree.find_backable_chain(ancestors, 4, |_| true), + [0, 1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::>() + ); + + // Valid ancestors. + let ancestors: Ancestors = [candidates[7].hash()].into_iter().collect(); + let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); + let candidate = &tree.nodes[res.unwrap_idx()]; + assert_eq!(candidate.candidate_hash, candidates[7].hash()); + assert_eq!(tree.find_backable_chain(ancestors, 1, |_| true), vec![]); + + let ancestors: Ancestors = + [candidates[2].hash(), candidates[0].hash(), candidates[1].hash()] + .into_iter() + .collect(); + let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); + let candidate = &tree.nodes[res.unwrap_idx()]; + assert_eq!(candidate.candidate_hash, candidates[2].hash()); + assert_eq!( + tree.find_backable_chain(ancestors.clone(), 2, |_| true), + [3, 4].into_iter().map(|i| candidates[i].hash()).collect::>() + ); + + // Valid ancestors with candidates which have been omitted due to timeouts + let ancestors: Ancestors = + [candidates[0].hash(), candidates[2].hash()].into_iter().collect(); + let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); + let candidate = &tree.nodes[res.unwrap_idx()]; + assert_eq!(candidate.candidate_hash, candidates[0].hash()); + assert_eq!( + tree.find_backable_chain(ancestors, 3, |_| true), + [1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::>() + ); + + let ancestors: Ancestors = + [candidates[0].hash(), candidates[1].hash(), candidates[3].hash()] + .into_iter() + .collect(); + let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); + let candidate = &tree.nodes[res.unwrap_idx()]; + assert_eq!(candidate.candidate_hash, candidates[1].hash()); + if has_cycle { + assert_eq!( + tree.find_backable_chain(ancestors, 2, |_| true), + [2, 3].into_iter().map(|i| candidates[i].hash()).collect::>() + ); + } else { + assert_eq!( + tree.find_backable_chain(ancestors, 4, |_| true), + [2, 3, 4].into_iter().map(|i| candidates[i].hash()).collect::>() + ); + } + + let ancestors: Ancestors = + [candidates[1].hash(), candidates[2].hash()].into_iter().collect(); + let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); + assert_eq!(res, NodePointer::Root); + assert_eq!( + tree.find_backable_chain(ancestors, 4, |_| true), + [0, 1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::>() + ); + + // Requested count is 0. + assert_eq!(tree.find_backable_chain(Ancestors::new(), 0, |_| true), vec![]); + + let ancestors: Ancestors = + [candidates[2].hash(), candidates[0].hash(), candidates[1].hash()] + .into_iter() + .collect(); + assert_eq!(tree.find_backable_chain(ancestors, 0, |_| true), vec![]); + + let ancestors: Ancestors = + [candidates[2].hash(), candidates[0].hash()].into_iter().collect(); + assert_eq!(tree.find_backable_chain(ancestors, 0, |_| true), vec![]); + } + + // Now do some tests only on the tree with cycles + if has_cycle { + // Exceeds the maximum tree depth. 0-1-2-3-4-1-2-3-4, when the tree stops at + // 0-1-2-3-4-1-2-3. + let ancestors: Ancestors = [ + candidates[0].hash(), + candidates[1].hash(), + candidates[2].hash(), + candidates[3].hash(), + candidates[4].hash(), + ] + .into_iter() + .collect(); + let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); + let candidate = &tree.nodes[res.unwrap_idx()]; + assert_eq!(candidate.candidate_hash, candidates[4].hash()); + assert_eq!( + tree.find_backable_chain(ancestors, 4, |_| true), + [1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::>() + ); + + // 0-1-2. + let ancestors: Ancestors = + [candidates[0].hash(), candidates[1].hash(), candidates[2].hash()] + .into_iter() + .collect(); + let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); + let candidate = &tree.nodes[res.unwrap_idx()]; + assert_eq!(candidate.candidate_hash, candidates[2].hash()); + assert_eq!( + tree.find_backable_chain(ancestors.clone(), 1, |_| true), + [3].into_iter().map(|i| candidates[i].hash()).collect::>() + ); + assert_eq!( + tree.find_backable_chain(ancestors, 5, |_| true), + [3, 4, 1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::>() + ); + + // 0-1 + let ancestors: Ancestors = + [candidates[0].hash(), candidates[1].hash()].into_iter().collect(); + let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); + let candidate = &tree.nodes[res.unwrap_idx()]; + assert_eq!(candidate.candidate_hash, candidates[1].hash()); + assert_eq!( + tree.find_backable_chain(ancestors, 6, |_| true), + [2, 3, 4, 1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::>(), + ); + + // For 0-1-2-3-4-5, there's more than 1 way of finding this path in + // the tree. `None` should be returned. The runtime should not have accepted this. + let ancestors: Ancestors = [ + candidates[0].hash(), + candidates[1].hash(), + candidates[2].hash(), + candidates[3].hash(), + candidates[4].hash(), + candidates[5].hash(), + ] + .into_iter() + .collect(); + let res = tree.find_ancestor_path(ancestors.clone()); + assert_eq!(res, None); + assert_eq!(tree.find_backable_chain(ancestors, 1, |_| true), vec![]); + } + } + #[test] fn graceful_cycle_of_0() { let mut storage = CandidateStorage::new(); @@ -1602,13 +2071,17 @@ mod tests { for count in 1..10 { assert_eq!( - tree.select_children(&[], count, |_| true), + tree.find_backable_chain(Ancestors::new(), count, |_| true), iter::repeat(candidate_a_hash) .take(std::cmp::min(count as usize, max_depth + 1)) .collect::>() ); assert_eq!( - tree.select_children(&[candidate_a_hash], count - 1, |_| true), + tree.find_backable_chain( + [candidate_a_hash].into_iter().collect(), + count - 1, + |_| true + ), iter::repeat(candidate_a_hash) .take(std::cmp::min(count as usize - 1, max_depth)) .collect::>() @@ -1682,22 +2155,22 @@ mod tests { assert_eq!(tree.nodes[3].candidate_hash, candidate_b_hash); assert_eq!(tree.nodes[4].candidate_hash, candidate_a_hash); - assert_eq!(tree.select_children(&[], 1, |_| true), vec![candidate_a_hash],); + assert_eq!(tree.find_backable_chain(Ancestors::new(), 1, |_| true), vec![candidate_a_hash],); assert_eq!( - tree.select_children(&[], 2, |_| true), + tree.find_backable_chain(Ancestors::new(), 2, |_| true), vec![candidate_a_hash, candidate_b_hash], ); assert_eq!( - tree.select_children(&[], 3, |_| true), + tree.find_backable_chain(Ancestors::new(), 3, |_| true), vec![candidate_a_hash, candidate_b_hash, candidate_a_hash], ); assert_eq!( - tree.select_children(&[candidate_a_hash], 2, |_| true), + tree.find_backable_chain([candidate_a_hash].into_iter().collect(), 2, |_| true), vec![candidate_b_hash, candidate_a_hash], ); assert_eq!( - tree.select_children(&[], 6, |_| true), + tree.find_backable_chain(Ancestors::new(), 6, |_| true), vec![ candidate_a_hash, candidate_b_hash, @@ -1706,10 +2179,17 @@ mod tests { candidate_a_hash ], ); - assert_eq!( - tree.select_children(&[candidate_a_hash, candidate_b_hash], 6, |_| true), - vec![candidate_a_hash, candidate_b_hash, candidate_a_hash,], - ); + + for count in 3..7 { + assert_eq!( + tree.find_backable_chain( + [candidate_a_hash, candidate_b_hash].into_iter().collect(), + count, + |_| true + ), + vec![candidate_a_hash, candidate_b_hash, candidate_a_hash], + ); + } } #[test] diff --git a/polkadot/node/core/prospective-parachains/src/lib.rs b/polkadot/node/core/prospective-parachains/src/lib.rs index 5937a1c1fb9..2b14e09b4fb 100644 --- a/polkadot/node/core/prospective-parachains/src/lib.rs +++ b/polkadot/node/core/prospective-parachains/src/lib.rs @@ -35,7 +35,7 @@ use futures::{channel::oneshot, prelude::*}; use polkadot_node_subsystem::{ messages::{ - ChainApiMessage, FragmentTreeMembership, HypotheticalCandidate, + Ancestors, ChainApiMessage, FragmentTreeMembership, HypotheticalCandidate, HypotheticalFrontierRequest, IntroduceCandidateRequest, ProspectiveParachainsMessage, ProspectiveValidationDataRequest, RuntimeApiMessage, RuntimeApiRequest, }, @@ -150,16 +150,9 @@ async fn run_iteration( relay_parent, para, count, - required_path, + ancestors, tx, - ) => answer_get_backable_candidates( - &view, - relay_parent, - para, - count, - required_path, - tx, - ), + ) => answer_get_backable_candidates(&view, relay_parent, para, count, ancestors, tx), ProspectiveParachainsMessage::GetHypotheticalFrontier(request, tx) => answer_hypothetical_frontier_request(&view, request, tx), ProspectiveParachainsMessage::GetTreeMembership(para, candidate, tx) => @@ -565,7 +558,7 @@ fn answer_get_backable_candidates( relay_parent: Hash, para: ParaId, count: u32, - required_path: Vec, + ancestors: Ancestors, tx: oneshot::Sender>, ) { let data = match view.active_leaves.get(&relay_parent) { @@ -614,7 +607,7 @@ fn answer_get_backable_candidates( }; let backable_candidates: Vec<_> = tree - .select_children(&required_path, count, |candidate| storage.is_backed(candidate)) + .find_backable_chain(ancestors.clone(), count, |candidate| storage.is_backed(candidate)) .into_iter() .filter_map(|child_hash| { storage.relay_parent_by_candidate_hash(&child_hash).map_or_else( @@ -635,7 +628,7 @@ fn answer_get_backable_candidates( if backable_candidates.is_empty() { gum::trace!( target: LOG_TARGET, - ?required_path, + ?ancestors, para_id = ?para, %relay_parent, "Could not find any backable candidate", diff --git a/polkadot/node/core/prospective-parachains/src/tests.rs b/polkadot/node/core/prospective-parachains/src/tests.rs index 732736b101d..0beddbf1416 100644 --- a/polkadot/node/core/prospective-parachains/src/tests.rs +++ b/polkadot/node/core/prospective-parachains/src/tests.rs @@ -407,7 +407,7 @@ async fn get_backable_candidates( virtual_overseer: &mut VirtualOverseer, leaf: &TestLeaf, para_id: ParaId, - required_path: Vec, + ancestors: Ancestors, count: u32, expected_result: Vec<(CandidateHash, Hash)>, ) { @@ -415,11 +415,7 @@ async fn get_backable_candidates( virtual_overseer .send(overseer::FromOrchestra::Communication { msg: ProspectiveParachainsMessage::GetBackableCandidates( - leaf.hash, - para_id, - count, - required_path, - tx, + leaf.hash, para_id, count, ancestors, tx, ), }) .await; @@ -903,7 +899,7 @@ fn check_backable_query_single_candidate() { &mut virtual_overseer, &leaf_a, 1.into(), - vec![candidate_hash_a], + vec![candidate_hash_a].into_iter().collect(), 1, vec![], ) @@ -912,12 +908,20 @@ fn check_backable_query_single_candidate() { &mut virtual_overseer, &leaf_a, 1.into(), - vec![candidate_hash_a], + vec![candidate_hash_a].into_iter().collect(), + 0, + vec![], + ) + .await; + get_backable_candidates( + &mut virtual_overseer, + &leaf_a, + 1.into(), + Ancestors::new(), 0, vec![], ) .await; - get_backable_candidates(&mut virtual_overseer, &leaf_a, 1.into(), vec![], 0, vec![]).await; // Second candidates. second_candidate(&mut virtual_overseer, candidate_a.clone()).await; @@ -928,7 +932,7 @@ fn check_backable_query_single_candidate() { &mut virtual_overseer, &leaf_a, 1.into(), - vec![candidate_hash_a], + vec![candidate_hash_a].into_iter().collect(), 1, vec![], ) @@ -939,12 +943,20 @@ fn check_backable_query_single_candidate() { back_candidate(&mut virtual_overseer, &candidate_b, candidate_hash_b).await; // Should not get any backable candidates for the other para. - get_backable_candidates(&mut virtual_overseer, &leaf_a, 2.into(), vec![], 1, vec![]).await; get_backable_candidates( &mut virtual_overseer, &leaf_a, 2.into(), - vec![candidate_hash_a], + Ancestors::new(), + 1, + vec![], + ) + .await; + get_backable_candidates( + &mut virtual_overseer, + &leaf_a, + 2.into(), + vec![candidate_hash_a].into_iter().collect(), 1, vec![], ) @@ -955,7 +967,7 @@ fn check_backable_query_single_candidate() { &mut virtual_overseer, &leaf_a, 1.into(), - vec![], + Ancestors::new(), 1, vec![(candidate_hash_a, leaf_a.hash)], ) @@ -964,20 +976,20 @@ fn check_backable_query_single_candidate() { &mut virtual_overseer, &leaf_a, 1.into(), - vec![candidate_hash_a], + vec![candidate_hash_a].into_iter().collect(), 1, vec![(candidate_hash_b, leaf_a.hash)], ) .await; - // Should not get anything at the wrong path. + // Wrong path get_backable_candidates( &mut virtual_overseer, &leaf_a, 1.into(), - vec![candidate_hash_b], + vec![candidate_hash_b].into_iter().collect(), 1, - vec![], + vec![(candidate_hash_a, leaf_a.hash)], ) .await; @@ -1075,15 +1087,29 @@ fn check_backable_query_multiple_candidates() { make_and_back_candidate!(test_state, virtual_overseer, leaf_a, &candidate_i, 10); // Should not get any backable candidates for the other para. - get_backable_candidates(&mut virtual_overseer, &leaf_a, 2.into(), vec![], 1, vec![]) - .await; - get_backable_candidates(&mut virtual_overseer, &leaf_a, 2.into(), vec![], 5, vec![]) - .await; get_backable_candidates( &mut virtual_overseer, &leaf_a, 2.into(), - vec![candidate_hash_a], + Ancestors::new(), + 1, + vec![], + ) + .await; + get_backable_candidates( + &mut virtual_overseer, + &leaf_a, + 2.into(), + Ancestors::new(), + 5, + vec![], + ) + .await; + get_backable_candidates( + &mut virtual_overseer, + &leaf_a, + 2.into(), + vec![candidate_hash_a].into_iter().collect(), 1, vec![], ) @@ -1097,7 +1123,7 @@ fn check_backable_query_multiple_candidates() { &mut virtual_overseer, &leaf_a, 1.into(), - vec![], + Ancestors::new(), 1, vec![(candidate_hash_a, leaf_a.hash)], ) @@ -1106,7 +1132,7 @@ fn check_backable_query_multiple_candidates() { &mut virtual_overseer, &leaf_a, 1.into(), - vec![], + Ancestors::new(), 4, vec![ (candidate_hash_a, leaf_a.hash), @@ -1124,7 +1150,7 @@ fn check_backable_query_multiple_candidates() { &mut virtual_overseer, &leaf_a, 1.into(), - vec![candidate_hash_a], + vec![candidate_hash_a].into_iter().collect(), 1, vec![(candidate_hash_b, leaf_a.hash)], ) @@ -1133,16 +1159,7 @@ fn check_backable_query_multiple_candidates() { &mut virtual_overseer, &leaf_a, 1.into(), - vec![candidate_hash_a], - 2, - vec![(candidate_hash_b, leaf_a.hash), (candidate_hash_d, leaf_a.hash)], - ) - .await; - get_backable_candidates( - &mut virtual_overseer, - &leaf_a, - 1.into(), - vec![candidate_hash_a], + vec![candidate_hash_a].into_iter().collect(), 3, vec![ (candidate_hash_b, leaf_a.hash), @@ -1159,7 +1176,7 @@ fn check_backable_query_multiple_candidates() { &mut virtual_overseer, &leaf_a, 1.into(), - vec![candidate_hash_a], + vec![candidate_hash_a].into_iter().collect(), count, vec![ (candidate_hash_c, leaf_a.hash), @@ -1172,26 +1189,30 @@ fn check_backable_query_multiple_candidates() { } } - // required path of 2 + // required path of 2 and higher { get_backable_candidates( &mut virtual_overseer, &leaf_a, 1.into(), - vec![candidate_hash_a, candidate_hash_b], + vec![candidate_hash_a, candidate_hash_i, candidate_hash_h, candidate_hash_c] + .into_iter() + .collect(), 1, - vec![(candidate_hash_d, leaf_a.hash)], + vec![(candidate_hash_j, leaf_a.hash)], ) .await; + get_backable_candidates( &mut virtual_overseer, &leaf_a, 1.into(), - vec![candidate_hash_a, candidate_hash_c], + vec![candidate_hash_a, candidate_hash_b].into_iter().collect(), 1, - vec![(candidate_hash_h, leaf_a.hash)], + vec![(candidate_hash_d, leaf_a.hash)], ) .await; + // If the requested count exceeds the largest chain, return the longest // chain we can get. for count in 4..10 { @@ -1199,7 +1220,7 @@ fn check_backable_query_multiple_candidates() { &mut virtual_overseer, &leaf_a, 1.into(), - vec![candidate_hash_a, candidate_hash_c], + vec![candidate_hash_a, candidate_hash_c].into_iter().collect(), count, vec![ (candidate_hash_h, leaf_a.hash), @@ -1213,317 +1234,127 @@ fn check_backable_query_multiple_candidates() { // No more candidates in any chain. { - let required_paths = vec![ - vec![candidate_hash_a, candidate_hash_b, candidate_hash_e], - vec![ - candidate_hash_a, - candidate_hash_c, - candidate_hash_h, - candidate_hash_i, - candidate_hash_j, - ], - ]; - for path in required_paths { - for count in 1..4 { - get_backable_candidates( - &mut virtual_overseer, - &leaf_a, - 1.into(), - path.clone(), - count, - vec![], - ) - .await; - } + for count in 1..4 { + get_backable_candidates( + &mut virtual_overseer, + &leaf_a, + 1.into(), + vec![candidate_hash_a, candidate_hash_b, candidate_hash_e] + .into_iter() + .collect(), + count, + vec![], + ) + .await; + + get_backable_candidates( + &mut virtual_overseer, + &leaf_a, + 1.into(), + vec![ + candidate_hash_a, + candidate_hash_c, + candidate_hash_h, + candidate_hash_i, + candidate_hash_j, + ] + .into_iter() + .collect(), + count, + vec![], + ) + .await; } } - // Should not get anything at the wrong path. + // Wrong paths. get_backable_candidates( &mut virtual_overseer, &leaf_a, 1.into(), - vec![candidate_hash_b], + vec![candidate_hash_b].into_iter().collect(), 1, - vec![], + vec![(candidate_hash_a, leaf_a.hash)], ) .await; get_backable_candidates( &mut virtual_overseer, &leaf_a, 1.into(), - vec![candidate_hash_b, candidate_hash_a], + vec![candidate_hash_b, candidate_hash_f].into_iter().collect(), 3, - vec![], + vec![ + (candidate_hash_a, leaf_a.hash), + (candidate_hash_b, leaf_a.hash), + (candidate_hash_d, leaf_a.hash), + ], ) .await; get_backable_candidates( &mut virtual_overseer, &leaf_a, 1.into(), - vec![candidate_hash_a, candidate_hash_b, candidate_hash_c], - 3, - vec![], + vec![candidate_hash_a, candidate_hash_h].into_iter().collect(), + 4, + vec![ + (candidate_hash_c, leaf_a.hash), + (candidate_hash_h, leaf_a.hash), + (candidate_hash_i, leaf_a.hash), + (candidate_hash_j, leaf_a.hash), + ], ) .await; - - virtual_overseer - }); - - assert_eq!(view.active_leaves.len(), 1); - assert_eq!(view.candidate_storage.len(), 2); - // 10 candidates and 7 parents on para 1. - assert_eq!(view.candidate_storage.get(&1.into()).unwrap().len(), (7, 10)); - assert_eq!(view.candidate_storage.get(&2.into()).unwrap().len(), (0, 0)); - } - - // A tree with multiple roots. - // Parachain 1 looks like this: - // (imaginary root) - // | | - // +----B---+ A - // | | | | - // | | | C - // D E F | - // | H - // G | - // I - // | - // J - { - let test_state = TestState::default(); - let view = test_harness(|mut virtual_overseer| async move { - // Leaf A - let leaf_a = TestLeaf { - number: 100, - hash: Hash::from_low_u64_be(130), - para_data: vec![ - (1.into(), PerParaData::new(97, HeadData(vec![1, 2, 3]))), - (2.into(), PerParaData::new(100, HeadData(vec![2, 3, 4]))), - ], - }; - - // Activate leaves. - activate_leaf(&mut virtual_overseer, &leaf_a, &test_state).await; - - // Candidate B - let (candidate_b, pvd_b) = make_candidate( - leaf_a.hash, - leaf_a.number, + get_backable_candidates( + &mut virtual_overseer, + &leaf_a, 1.into(), - HeadData(vec![1, 2, 3]), - HeadData(vec![2]), - test_state.validation_code_hash, - ); - let candidate_hash_b = candidate_b.hash(); - introduce_candidate(&mut virtual_overseer, candidate_b.clone(), pvd_b).await; - second_candidate(&mut virtual_overseer, candidate_b.clone()).await; - back_candidate(&mut virtual_overseer, &candidate_b, candidate_hash_b).await; + vec![candidate_hash_e, candidate_hash_h].into_iter().collect(), + 2, + vec![(candidate_hash_a, leaf_a.hash), (candidate_hash_b, leaf_a.hash)], + ) + .await; - // Candidate A - let (candidate_a, pvd_a) = make_candidate( - leaf_a.hash, - leaf_a.number, + get_backable_candidates( + &mut virtual_overseer, + &leaf_a, 1.into(), - HeadData(vec![1, 2, 3]), - HeadData(vec![1]), - test_state.validation_code_hash, - ); - let candidate_hash_a = candidate_a.hash(); - introduce_candidate(&mut virtual_overseer, candidate_a.clone(), pvd_a).await; - second_candidate(&mut virtual_overseer, candidate_a.clone()).await; - back_candidate(&mut virtual_overseer, &candidate_a, candidate_hash_a).await; - - let (candidate_c, candidate_hash_c) = - make_and_back_candidate!(test_state, virtual_overseer, leaf_a, &candidate_a, 3); - let (_candidate_d, candidate_hash_d) = - make_and_back_candidate!(test_state, virtual_overseer, leaf_a, &candidate_b, 4); - let (_candidate_e, candidate_hash_e) = - make_and_back_candidate!(test_state, virtual_overseer, leaf_a, &candidate_b, 5); - let (candidate_f, candidate_hash_f) = - make_and_back_candidate!(test_state, virtual_overseer, leaf_a, &candidate_b, 6); - let (_candidate_g, candidate_hash_g) = - make_and_back_candidate!(test_state, virtual_overseer, leaf_a, &candidate_f, 7); - let (candidate_h, candidate_hash_h) = - make_and_back_candidate!(test_state, virtual_overseer, leaf_a, &candidate_c, 8); - let (candidate_i, candidate_hash_i) = - make_and_back_candidate!(test_state, virtual_overseer, leaf_a, &candidate_h, 9); - let (_candidate_j, candidate_hash_j) = - make_and_back_candidate!(test_state, virtual_overseer, leaf_a, &candidate_i, 10); + vec![candidate_hash_a, candidate_hash_c, candidate_hash_d].into_iter().collect(), + 2, + vec![(candidate_hash_h, leaf_a.hash), (candidate_hash_i, leaf_a.hash)], + ) + .await; - // Should not get any backable candidates for the other para. - get_backable_candidates(&mut virtual_overseer, &leaf_a, 2.into(), vec![], 1, vec![]) - .await; - get_backable_candidates(&mut virtual_overseer, &leaf_a, 2.into(), vec![], 5, vec![]) - .await; + // Parachain fork. get_backable_candidates( &mut virtual_overseer, &leaf_a, - 2.into(), - vec![candidate_hash_a], + 1.into(), + vec![candidate_hash_a, candidate_hash_b, candidate_hash_c].into_iter().collect(), 1, vec![], ) .await; - // Test various scenarios with various counts. - - // empty required_path - { - get_backable_candidates( - &mut virtual_overseer, - &leaf_a, - 1.into(), - vec![], - 1, - vec![(candidate_hash_b, leaf_a.hash)], - ) - .await; - get_backable_candidates( - &mut virtual_overseer, - &leaf_a, - 1.into(), - vec![], - 2, - vec![(candidate_hash_b, leaf_a.hash), (candidate_hash_d, leaf_a.hash)], - ) - .await; - get_backable_candidates( - &mut virtual_overseer, - &leaf_a, - 1.into(), - vec![], - 4, - vec![ - (candidate_hash_a, leaf_a.hash), - (candidate_hash_c, leaf_a.hash), - (candidate_hash_h, leaf_a.hash), - (candidate_hash_i, leaf_a.hash), - ], - ) - .await; - } - - // required path of 1 - { - get_backable_candidates( - &mut virtual_overseer, - &leaf_a, - 1.into(), - vec![candidate_hash_a], - 1, - vec![(candidate_hash_c, leaf_a.hash)], - ) - .await; - get_backable_candidates( - &mut virtual_overseer, - &leaf_a, - 1.into(), - vec![candidate_hash_b], - 1, - vec![(candidate_hash_d, leaf_a.hash)], - ) - .await; - get_backable_candidates( - &mut virtual_overseer, - &leaf_a, - 1.into(), - vec![candidate_hash_a], - 2, - vec![(candidate_hash_c, leaf_a.hash), (candidate_hash_h, leaf_a.hash)], - ) - .await; - - // If the requested count exceeds the largest chain, return the longest - // chain we can get. - for count in 2..10 { - get_backable_candidates( - &mut virtual_overseer, - &leaf_a, - 1.into(), - vec![candidate_hash_b], - count, - vec![(candidate_hash_f, leaf_a.hash), (candidate_hash_g, leaf_a.hash)], - ) - .await; - } - } - - // required path of 2 - { - get_backable_candidates( - &mut virtual_overseer, - &leaf_a, - 1.into(), - vec![candidate_hash_b, candidate_hash_f], - 1, - vec![(candidate_hash_g, leaf_a.hash)], - ) - .await; - get_backable_candidates( - &mut virtual_overseer, - &leaf_a, - 1.into(), - vec![candidate_hash_a, candidate_hash_c], - 1, - vec![(candidate_hash_h, leaf_a.hash)], - ) - .await; - // If the requested count exceeds the largest chain, return the longest - // chain we can get. - for count in 4..10 { - get_backable_candidates( - &mut virtual_overseer, - &leaf_a, - 1.into(), - vec![candidate_hash_a, candidate_hash_c], - count, - vec![ - (candidate_hash_h, leaf_a.hash), - (candidate_hash_i, leaf_a.hash), - (candidate_hash_j, leaf_a.hash), - ], - ) - .await; - } - } - - // No more candidates in any chain. - { - let required_paths = vec![ - vec![candidate_hash_b, candidate_hash_f, candidate_hash_g], - vec![candidate_hash_b, candidate_hash_e], - vec![candidate_hash_b, candidate_hash_d], - vec![ - candidate_hash_a, - candidate_hash_c, - candidate_hash_h, - candidate_hash_i, - candidate_hash_j, - ], - ]; - for path in required_paths { - for count in 1..4 { - get_backable_candidates( - &mut virtual_overseer, - &leaf_a, - 1.into(), - path.clone(), - count, - vec![], - ) - .await; - } - } - } + // Non-existent candidate. + get_backable_candidates( + &mut virtual_overseer, + &leaf_a, + 1.into(), + vec![candidate_hash_a, CandidateHash(Hash::from_low_u64_be(100))] + .into_iter() + .collect(), + 2, + vec![(candidate_hash_b, leaf_a.hash), (candidate_hash_d, leaf_a.hash)], + ) + .await; - // Should not get anything at the wrong path. + // Requested count is zero. get_backable_candidates( &mut virtual_overseer, &leaf_a, 1.into(), - vec![candidate_hash_d], - 1, + Ancestors::new(), + 0, vec![], ) .await; @@ -1531,8 +1362,8 @@ fn check_backable_query_multiple_candidates() { &mut virtual_overseer, &leaf_a, 1.into(), - vec![candidate_hash_b, candidate_hash_a], - 3, + vec![candidate_hash_a].into_iter().collect(), + 0, vec![], ) .await; @@ -1540,8 +1371,8 @@ fn check_backable_query_multiple_candidates() { &mut virtual_overseer, &leaf_a, 1.into(), - vec![candidate_hash_a, candidate_hash_c, candidate_hash_d], - 3, + vec![candidate_hash_a, candidate_hash_b].into_iter().collect(), + 0, vec![], ) .await; @@ -1853,8 +1684,8 @@ fn check_pvd_query() { assert_eq!(view.candidate_storage.len(), 2); } -// Test simultaneously activating and deactivating leaves, and simultaneously deactivating multiple -// leaves. +// Test simultaneously activating and deactivating leaves, and simultaneously deactivating +// multiple leaves. #[test] fn correctly_updates_leaves() { let test_state = TestState::default(); @@ -2048,7 +1879,7 @@ fn persists_pending_availability_candidate() { &mut virtual_overseer, &leaf_b, para_id, - vec![candidate_hash_a], + vec![candidate_hash_a].into_iter().collect(), 1, vec![(candidate_hash_b, leaf_b_hash)], ) @@ -2113,7 +1944,7 @@ fn backwards_compatible() { &mut virtual_overseer, &leaf_a, para_id, - vec![], + Ancestors::new(), 1, vec![(candidate_hash_a, candidate_relay_parent)], ) @@ -2135,7 +1966,15 @@ fn backwards_compatible() { ) .await; - get_backable_candidates(&mut virtual_overseer, &leaf_b, para_id, vec![], 1, vec![]).await; + get_backable_candidates( + &mut virtual_overseer, + &leaf_b, + para_id, + Ancestors::new(), + 1, + vec![], + ) + .await; virtual_overseer }); @@ -2162,13 +2001,13 @@ fn uses_ancestry_only_within_session() { .await; assert_matches!( - virtual_overseer.recv().await, - AllMessages::RuntimeApi( - RuntimeApiMessage::Request(parent, RuntimeApiRequest::AsyncBackingParams(tx)) - ) if parent == hash => { - tx.send(Ok(AsyncBackingParams { max_candidate_depth: 0, allowed_ancestry_len: ancestry_len })).unwrap(); - } - ); + virtual_overseer.recv().await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(parent, RuntimeApiRequest::AsyncBackingParams(tx)) + ) if parent == hash => { + tx.send(Ok(AsyncBackingParams { max_candidate_depth: 0, allowed_ancestry_len: ancestry_len + })).unwrap(); } + ); assert_matches!( virtual_overseer.recv().await, diff --git a/polkadot/node/core/provisioner/Cargo.toml b/polkadot/node/core/provisioner/Cargo.toml index 24cdfd6b57b..2a09e2b5b2c 100644 --- a/polkadot/node/core/provisioner/Cargo.toml +++ b/polkadot/node/core/provisioner/Cargo.toml @@ -20,9 +20,11 @@ polkadot-node-subsystem = { path = "../../subsystem" } polkadot-node-subsystem-util = { path = "../../subsystem-util" } futures-timer = "3.0.2" fatality = "0.0.6" +schnellru = "0.2.1" [dev-dependencies] sp-application-crypto = { path = "../../../../substrate/primitives/application-crypto" } sp-keystore = { path = "../../../../substrate/primitives/keystore" } polkadot-node-subsystem-test-helpers = { path = "../../subsystem-test-helpers" } test-helpers = { package = "polkadot-primitives-test-helpers", path = "../../../primitives/test-helpers" } +rstest = "0.18.2" diff --git a/polkadot/node/core/provisioner/src/error.rs b/polkadot/node/core/provisioner/src/error.rs index 376d69f276f..aae3234c3cc 100644 --- a/polkadot/node/core/provisioner/src/error.rs +++ b/polkadot/node/core/provisioner/src/error.rs @@ -44,14 +44,17 @@ pub enum Error { #[error("failed to get block number")] CanceledBlockNumber(#[source] oneshot::Canceled), + #[error("failed to get session index")] + CanceledSessionIndex(#[source] oneshot::Canceled), + #[error("failed to get backed candidates")] CanceledBackedCandidates(#[source] oneshot::Canceled), #[error("failed to get votes on dispute")] CanceledCandidateVotes(#[source] oneshot::Canceled), - #[error("failed to get backable candidate from prospective parachains")] - CanceledBackableCandidate(#[source] oneshot::Canceled), + #[error("failed to get backable candidates from prospective parachains")] + CanceledBackableCandidates(#[source] oneshot::Canceled), #[error(transparent)] ChainApi(#[from] ChainApiError), @@ -71,11 +74,6 @@ pub enum Error { #[error("failed to send return message with Inherents")] InherentDataReturnChannel, - #[error( - "backed candidate does not correspond to selected candidate; check logic in provisioner" - )] - BackedCandidateOrderingProblem, - #[fatal] #[error("Failed to spawn background task")] FailedToSpawnBackgroundTask, diff --git a/polkadot/node/core/provisioner/src/lib.rs b/polkadot/node/core/provisioner/src/lib.rs index a29cf72afb1..c9ed873d3c2 100644 --- a/polkadot/node/core/provisioner/src/lib.rs +++ b/polkadot/node/core/provisioner/src/lib.rs @@ -24,26 +24,29 @@ use futures::{ channel::oneshot, future::BoxFuture, prelude::*, stream::FuturesUnordered, FutureExt, }; use futures_timer::Delay; +use schnellru::{ByLength, LruMap}; use polkadot_node_subsystem::{ jaeger, messages::{ - CandidateBackingMessage, ChainApiMessage, ProspectiveParachainsMessage, ProvisionableData, - ProvisionerInherentData, ProvisionerMessage, RuntimeApiRequest, + Ancestors, CandidateBackingMessage, ChainApiMessage, ProspectiveParachainsMessage, + ProvisionableData, ProvisionerInherentData, ProvisionerMessage, RuntimeApiRequest, }, overseer, ActivatedLeaf, ActiveLeavesUpdate, FromOrchestra, OverseerSignal, PerLeafSpan, SpawnedSubsystem, SubsystemError, }; use polkadot_node_subsystem_util::{ has_required_runtime, request_availability_cores, request_persisted_validation_data, - runtime::{prospective_parachains_mode, ProspectiveParachainsMode}, + request_session_index_for_child, + runtime::{prospective_parachains_mode, request_node_features, ProspectiveParachainsMode}, TimeoutExt, }; use polkadot_primitives::{ - BackedCandidate, BlockNumber, CandidateHash, CandidateReceipt, CoreState, Hash, Id as ParaId, - OccupiedCoreAssumption, SignedAvailabilityBitfield, ValidatorIndex, + vstaging::{node_features::FeatureIndex, NodeFeatures}, + BackedCandidate, BlockNumber, CandidateHash, CandidateReceipt, CoreIndex, CoreState, Hash, + Id as ParaId, OccupiedCoreAssumption, SessionIndex, SignedAvailabilityBitfield, ValidatorIndex, }; -use std::collections::{BTreeMap, HashMap}; +use std::collections::{BTreeMap, HashMap, HashSet}; mod disputes; mod error; @@ -77,11 +80,18 @@ impl ProvisionerSubsystem { } } +/// Per-session info we need for the provisioner subsystem. +pub struct PerSession { + prospective_parachains_mode: ProspectiveParachainsMode, + elastic_scaling_mvp: bool, +} + /// A per-relay-parent state for the provisioning subsystem. pub struct PerRelayParent { leaf: ActivatedLeaf, backed_candidates: Vec, prospective_parachains_mode: ProspectiveParachainsMode, + elastic_scaling_mvp: bool, signed_bitfields: Vec, is_inherent_ready: bool, awaiting_inherent: Vec>, @@ -89,13 +99,14 @@ pub struct PerRelayParent { } impl PerRelayParent { - fn new(leaf: ActivatedLeaf, prospective_parachains_mode: ProspectiveParachainsMode) -> Self { + fn new(leaf: ActivatedLeaf, per_session: &PerSession) -> Self { let span = PerLeafSpan::new(leaf.span.clone(), "provisioner"); Self { leaf, backed_candidates: Vec::new(), - prospective_parachains_mode, + prospective_parachains_mode: per_session.prospective_parachains_mode, + elastic_scaling_mvp: per_session.elastic_scaling_mvp, signed_bitfields: Vec::new(), is_inherent_ready: false, awaiting_inherent: Vec::new(), @@ -124,10 +135,17 @@ impl ProvisionerSubsystem { async fn run(mut ctx: Context, metrics: Metrics) -> FatalResult<()> { let mut inherent_delays = InherentDelays::new(); let mut per_relay_parent = HashMap::new(); + let mut per_session = LruMap::new(ByLength::new(2)); loop { - let result = - run_iteration(&mut ctx, &mut per_relay_parent, &mut inherent_delays, &metrics).await; + let result = run_iteration( + &mut ctx, + &mut per_relay_parent, + &mut per_session, + &mut inherent_delays, + &metrics, + ) + .await; match result { Ok(()) => break, @@ -142,6 +160,7 @@ async fn run(mut ctx: Context, metrics: Metrics) -> FatalResult<()> { async fn run_iteration( ctx: &mut Context, per_relay_parent: &mut HashMap, + per_session: &mut LruMap, inherent_delays: &mut InherentDelays, metrics: &Metrics, ) -> Result<(), Error> { @@ -151,7 +170,7 @@ async fn run_iteration( // Map the error to ensure that the subsystem exits when the overseer is gone. match from_overseer.map_err(Error::OverseerExited)? { FromOrchestra::Signal(OverseerSignal::ActiveLeaves(update)) => - handle_active_leaves_update(ctx.sender(), update, per_relay_parent, inherent_delays).await?, + handle_active_leaves_update(ctx.sender(), update, per_relay_parent, per_session, inherent_delays).await?, FromOrchestra::Signal(OverseerSignal::BlockFinalized(..)) => {}, FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(()), FromOrchestra::Communication { msg } => { @@ -183,6 +202,7 @@ async fn handle_active_leaves_update( sender: &mut impl overseer::ProvisionerSenderTrait, update: ActiveLeavesUpdate, per_relay_parent: &mut HashMap, + per_session: &mut LruMap, inherent_delays: &mut InherentDelays, ) -> Result<(), Error> { gum::trace!(target: LOG_TARGET, "Handle ActiveLeavesUpdate"); @@ -191,10 +211,31 @@ async fn handle_active_leaves_update( } if let Some(leaf) = update.activated { + let session_index = request_session_index_for_child(leaf.hash, sender) + .await + .await + .map_err(Error::CanceledSessionIndex)??; + if per_session.get(&session_index).is_none() { + let prospective_parachains_mode = + prospective_parachains_mode(sender, leaf.hash).await?; + let elastic_scaling_mvp = request_node_features(leaf.hash, session_index, sender) + .await? + .unwrap_or(NodeFeatures::EMPTY) + .get(FeatureIndex::ElasticScalingMVP as usize) + .map(|b| *b) + .unwrap_or(false); + + per_session.insert( + session_index, + PerSession { prospective_parachains_mode, elastic_scaling_mvp }, + ); + } + + let session_info = per_session.get(&session_index).expect("Just inserted"); + gum::trace!(target: LOG_TARGET, leaf_hash=?leaf.hash, "Adding delay"); - let prospective_parachains_mode = prospective_parachains_mode(sender, leaf.hash).await?; let delay_fut = Delay::new(PRE_PROPOSE_TIMEOUT).map(move |_| leaf.hash).boxed(); - per_relay_parent.insert(leaf.hash, PerRelayParent::new(leaf, prospective_parachains_mode)); + per_relay_parent.insert(leaf.hash, PerRelayParent::new(leaf, session_info)); inherent_delays.push(delay_fut); } @@ -253,6 +294,7 @@ async fn send_inherent_data_bg( let signed_bitfields = per_relay_parent.signed_bitfields.clone(); let backed_candidates = per_relay_parent.backed_candidates.clone(); let mode = per_relay_parent.prospective_parachains_mode; + let elastic_scaling_mvp = per_relay_parent.elastic_scaling_mvp; let span = per_relay_parent.span.child("req-inherent-data"); let mut sender = ctx.sender().clone(); @@ -272,6 +314,7 @@ async fn send_inherent_data_bg( &signed_bitfields, &backed_candidates, mode, + elastic_scaling_mvp, return_senders, &mut sender, &metrics, @@ -383,6 +426,7 @@ async fn send_inherent_data( bitfields: &[SignedAvailabilityBitfield], candidates: &[CandidateReceipt], prospective_parachains_mode: ProspectiveParachainsMode, + elastic_scaling_mvp: bool, return_senders: Vec>, from_job: &mut impl overseer::ProvisionerSenderTrait, metrics: &Metrics, @@ -434,6 +478,7 @@ async fn send_inherent_data( &bitfields, candidates, prospective_parachains_mode, + elastic_scaling_mvp, leaf.hash, from_job, ) @@ -558,6 +603,8 @@ async fn select_candidate_hashes_from_tracked( let mut selected_candidates = Vec::with_capacity(candidates.len().min(availability_cores.len())); + let mut selected_parachains = + HashSet::with_capacity(candidates.len().min(availability_cores.len())); gum::debug!( target: LOG_TARGET, @@ -591,6 +638,12 @@ async fn select_candidate_hashes_from_tracked( CoreState::Free => continue, }; + if selected_parachains.contains(&scheduled_core.para_id) { + // We already picked a candidate for this parachain. Elastic scaling only works with + // prospective parachains mode. + continue + } + let validation_data = match request_persisted_validation_data( relay_parent, scheduled_core.para_id, @@ -624,6 +677,7 @@ async fn select_candidate_hashes_from_tracked( "Selected candidate receipt", ); + selected_parachains.insert(candidate.descriptor.para_id); selected_candidates.push((candidate_hash, candidate.descriptor.relay_parent)); } } @@ -637,70 +691,93 @@ async fn select_candidate_hashes_from_tracked( /// Should be called when prospective parachains are enabled. async fn request_backable_candidates( availability_cores: &[CoreState], + elastic_scaling_mvp: bool, bitfields: &[SignedAvailabilityBitfield], relay_parent: Hash, sender: &mut impl overseer::ProvisionerSenderTrait, ) -> Result, Error> { let block_number = get_block_number_under_construction(relay_parent, sender).await?; - let mut selected_candidates = Vec::with_capacity(availability_cores.len()); + // Record how many cores are scheduled for each paraid. Use a BTreeMap because + // we'll need to iterate through them. + let mut scheduled_cores: BTreeMap = BTreeMap::new(); + // The on-chain ancestors of a para present in availability-cores. + let mut ancestors: HashMap = + HashMap::with_capacity(availability_cores.len()); for (core_idx, core) in availability_cores.iter().enumerate() { - let (para_id, required_path) = match core { + let core_idx = CoreIndex(core_idx as u32); + match core { CoreState::Scheduled(scheduled_core) => { - // The core is free, pick the first eligible candidate from - // the fragment tree. - (scheduled_core.para_id, Vec::new()) + *scheduled_cores.entry(scheduled_core.para_id).or_insert(0) += 1; }, CoreState::Occupied(occupied_core) => { - if bitfields_indicate_availability(core_idx, bitfields, &occupied_core.availability) - { + let is_available = bitfields_indicate_availability( + core_idx.0 as usize, + bitfields, + &occupied_core.availability, + ); + + if is_available { + ancestors + .entry(occupied_core.para_id()) + .or_default() + .insert(occupied_core.candidate_hash); + if let Some(ref scheduled_core) = occupied_core.next_up_on_available { - // The candidate occupying the core is available, choose its - // child in the fragment tree. - // - // TODO: doesn't work for on-demand parachains. We lean hard on the - // assumption that cores are fixed to specific parachains within a session. - // https://github.com/paritytech/polkadot/issues/5492 - (scheduled_core.para_id, vec![occupied_core.candidate_hash]) - } else { - continue - } - } else { - if occupied_core.time_out_at != block_number { - continue + // Request a new backable candidate for the newly scheduled para id. + *scheduled_cores.entry(scheduled_core.para_id).or_insert(0) += 1; } + } else if occupied_core.time_out_at <= block_number { + // Timed out before being available. + if let Some(ref scheduled_core) = occupied_core.next_up_on_time_out { // Candidate's availability timed out, practically same as scheduled. - (scheduled_core.para_id, Vec::new()) - } else { - continue + *scheduled_cores.entry(scheduled_core.para_id).or_insert(0) += 1; } + } else { + // Not timed out and not available. + ancestors + .entry(occupied_core.para_id()) + .or_default() + .insert(occupied_core.candidate_hash); } }, CoreState::Free => continue, }; + } - // We should be calling this once per para rather than per core. - // TODO: Will be fixed in https://github.com/paritytech/polkadot-sdk/pull/3233. - // For now, at least make sure we don't supply the same candidate multiple times in case a - // para has multiple cores scheduled. - let response = get_backable_candidate(relay_parent, para_id, required_path, sender).await?; - match response { - Some((hash, relay_parent)) => { - if !selected_candidates.iter().any(|bc| &(hash, relay_parent) == bc) { - selected_candidates.push((hash, relay_parent)) - } - }, - None => { - gum::debug!( - target: LOG_TARGET, - leaf_hash = ?relay_parent, - core = core_idx, - "No backable candidate returned by prospective parachains", - ); - }, + let mut selected_candidates: Vec<(CandidateHash, Hash)> = + Vec::with_capacity(availability_cores.len()); + + for (para_id, core_count) in scheduled_cores { + let para_ancestors = ancestors.remove(¶_id).unwrap_or_default(); + + // If elastic scaling MVP is disabled, only allow one candidate per parachain. + if !elastic_scaling_mvp && core_count > 1 { + continue } + + let response = get_backable_candidates( + relay_parent, + para_id, + para_ancestors, + core_count as u32, + sender, + ) + .await?; + + if response.is_empty() { + gum::debug!( + target: LOG_TARGET, + leaf_hash = ?relay_parent, + ?para_id, + "No backable candidate returned by prospective parachains", + ); + continue + } + + selected_candidates.extend(response.into_iter().take(core_count)); } Ok(selected_candidates) @@ -713,6 +790,7 @@ async fn select_candidates( bitfields: &[SignedAvailabilityBitfield], candidates: &[CandidateReceipt], prospective_parachains_mode: ProspectiveParachainsMode, + elastic_scaling_mvp: bool, relay_parent: Hash, sender: &mut impl overseer::ProvisionerSenderTrait, ) -> Result, Error> { @@ -722,7 +800,14 @@ async fn select_candidates( let selected_candidates = match prospective_parachains_mode { ProspectiveParachainsMode::Enabled { .. } => - request_backable_candidates(availability_cores, bitfields, relay_parent, sender).await?, + request_backable_candidates( + availability_cores, + elastic_scaling_mvp, + bitfields, + relay_parent, + sender, + ) + .await?, ProspectiveParachainsMode::Disabled => select_candidate_hashes_from_tracked( availability_cores, @@ -745,24 +830,6 @@ async fn select_candidates( gum::trace!(target: LOG_TARGET, leaf_hash=?relay_parent, "Got {} backed candidates", candidates.len()); - // `selected_candidates` is generated in ascending order by core index, and - // `GetBackedCandidates` _should_ preserve that property, but let's just make sure. - // - // We can't easily map from `BackedCandidate` to `core_idx`, but we know that every selected - // candidate maps to either 0 or 1 backed candidate, and the hashes correspond. Therefore, by - // checking them in order, we can ensure that the backed candidates are also in order. - let mut backed_idx = 0; - for selected in selected_candidates { - if selected.0 == - candidates.get(backed_idx).ok_or(Error::BackedCandidateOrderingProblem)?.hash() - { - backed_idx += 1; - } - } - if candidates.len() != backed_idx { - Err(Error::BackedCandidateOrderingProblem)?; - } - // keep only one candidate with validation code. let mut with_validation_code = false; candidates.retain(|c| { @@ -804,28 +871,27 @@ async fn get_block_number_under_construction( } } -/// Requests backable candidate from Prospective Parachains based on -/// the given path in the fragment tree. -async fn get_backable_candidate( +/// Requests backable candidates from Prospective Parachains based on +/// the given ancestors in the fragment tree. The ancestors may not be ordered. +async fn get_backable_candidates( relay_parent: Hash, para_id: ParaId, - required_path: Vec, + ancestors: Ancestors, + count: u32, sender: &mut impl overseer::ProvisionerSenderTrait, -) -> Result, Error> { +) -> Result, Error> { let (tx, rx) = oneshot::channel(); sender .send_message(ProspectiveParachainsMessage::GetBackableCandidates( relay_parent, para_id, - 1, // core count hardcoded to 1, until elastic scaling is implemented and enabled. - required_path, + count, + ancestors, tx, )) .await; - rx.await - .map_err(Error::CanceledBackableCandidate) - .map(|res| res.get(0).copied()) + rx.await.map_err(Error::CanceledBackableCandidates) } /// The availability bitfield for a given core is the transpose diff --git a/polkadot/node/core/provisioner/src/tests.rs b/polkadot/node/core/provisioner/src/tests.rs index 87c0e7a65d3..bdb4f85f400 100644 --- a/polkadot/node/core/provisioner/src/tests.rs +++ b/polkadot/node/core/provisioner/src/tests.rs @@ -22,6 +22,9 @@ use polkadot_primitives::{OccupiedCore, ScheduledCore}; const MOCK_GROUP_SIZE: usize = 5; pub fn occupied_core(para_id: u32) -> CoreState { + let mut candidate_descriptor = dummy_candidate_descriptor(dummy_hash()); + candidate_descriptor.para_id = para_id.into(); + CoreState::Occupied(OccupiedCore { group_responsible: para_id.into(), next_up_on_available: None, @@ -29,7 +32,7 @@ pub fn occupied_core(para_id: u32) -> CoreState { time_out_at: 200_u32, next_up_on_time_out: None, availability: bitvec![u8, bitvec::order::Lsb0; 0; 32], - candidate_descriptor: dummy_candidate_descriptor(dummy_hash()), + candidate_descriptor, candidate_hash: Default::default(), }) } @@ -254,10 +257,56 @@ mod select_candidates { use polkadot_primitives::{ BlockNumber, CandidateCommitments, CommittedCandidateReceipt, PersistedValidationData, }; + use rstest::rstest; const BLOCK_UNDER_PRODUCTION: BlockNumber = 128; - // For test purposes, we always return this set of availability cores: + fn dummy_candidate_template() -> CandidateReceipt { + let empty_hash = PersistedValidationData::::default().hash(); + + let mut descriptor_template = dummy_candidate_descriptor(dummy_hash()); + descriptor_template.persisted_validation_data_hash = empty_hash; + CandidateReceipt { + descriptor: descriptor_template, + commitments_hash: CandidateCommitments::default().hash(), + } + } + + fn make_candidates( + core_count: usize, + expected_backed_indices: Vec, + ) -> (Vec, Vec) { + let candidate_template = dummy_candidate_template(); + let candidates: Vec<_> = std::iter::repeat(candidate_template) + .take(core_count) + .enumerate() + .map(|(idx, mut candidate)| { + candidate.descriptor.para_id = idx.into(); + candidate + }) + .collect(); + + let expected_backed = expected_backed_indices + .iter() + .map(|&idx| candidates[idx].clone()) + .map(|c| { + BackedCandidate::new( + CommittedCandidateReceipt { + descriptor: c.descriptor.clone(), + commitments: Default::default(), + }, + Vec::new(), + default_bitvec(MOCK_GROUP_SIZE), + None, + ) + }) + .collect(); + let candidate_hashes = candidates.into_iter().map(|c| c.hash()).collect(); + + (candidate_hashes, expected_backed) + } + + // For testing only one core assigned to a parachain, we return this set of availability cores: // // [ // 0: Free, @@ -273,7 +322,7 @@ mod select_candidates { // 10: Occupied(both next_up set, not available, timeout), // 11: Occupied(next_up_on_available and available, but different successor para_id) // ] - fn mock_availability_cores() -> Vec { + fn mock_availability_cores_one_per_para() -> Vec { use std::ops::Not; use CoreState::{Free, Scheduled}; @@ -292,6 +341,7 @@ mod select_candidates { build_occupied_core(4, |core| { core.next_up_on_available = Some(scheduled_core(4)); core.availability = core.availability.clone().not(); + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(41)); }), // 5: Occupied(next_up_on_time_out set but not timeout), build_occupied_core(5, |core| { @@ -307,12 +357,14 @@ mod select_candidates { build_occupied_core(7, |core| { core.next_up_on_time_out = Some(scheduled_core(7)); core.time_out_at = BLOCK_UNDER_PRODUCTION; + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(71)); }), // 8: Occupied(both next_up set, available), build_occupied_core(8, |core| { core.next_up_on_available = Some(scheduled_core(8)); core.next_up_on_time_out = Some(scheduled_core(8)); core.availability = core.availability.clone().not(); + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(81)); }), // 9: Occupied(both next_up set, not available, no timeout), build_occupied_core(9, |core| { @@ -324,6 +376,7 @@ mod select_candidates { core.next_up_on_available = Some(scheduled_core(10)); core.next_up_on_time_out = Some(scheduled_core(10)); core.time_out_at = BLOCK_UNDER_PRODUCTION; + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(101)); }), // 11: Occupied(next_up_on_available and available, but different successor para_id) build_occupied_core(11, |core| { @@ -333,20 +386,189 @@ mod select_candidates { ] } + // For test purposes with multiple possible cores assigned to a para, we always return this set + // of availability cores: + fn mock_availability_cores_multiple_per_para() -> Vec { + use std::ops::Not; + use CoreState::{Free, Scheduled}; + + vec![ + // 0: Free, + Free, + // 1: Scheduled(default), + Scheduled(scheduled_core(1)), + // 2: Occupied(no next_up set), + occupied_core(2), + // 3: Occupied(next_up_on_available set but not available), + build_occupied_core(3, |core| { + core.next_up_on_available = Some(scheduled_core(3)); + }), + // 4: Occupied(next_up_on_available set and available), + build_occupied_core(4, |core| { + core.next_up_on_available = Some(scheduled_core(4)); + core.availability = core.availability.clone().not(); + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(41)); + }), + // 5: Occupied(next_up_on_time_out set but not timeout), + build_occupied_core(5, |core| { + core.next_up_on_time_out = Some(scheduled_core(5)); + }), + // 6: Occupied(next_up_on_time_out set and timeout but available), + build_occupied_core(6, |core| { + core.next_up_on_time_out = Some(scheduled_core(6)); + core.time_out_at = BLOCK_UNDER_PRODUCTION; + core.availability = core.availability.clone().not(); + }), + // 7: Occupied(next_up_on_time_out set and timeout and not available), + build_occupied_core(7, |core| { + core.next_up_on_time_out = Some(scheduled_core(7)); + core.time_out_at = BLOCK_UNDER_PRODUCTION; + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(71)); + }), + // 8: Occupied(both next_up set, available), + build_occupied_core(8, |core| { + core.next_up_on_available = Some(scheduled_core(8)); + core.next_up_on_time_out = Some(scheduled_core(8)); + core.availability = core.availability.clone().not(); + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(81)); + }), + // 9: Occupied(both next_up set, not available, no timeout), + build_occupied_core(9, |core| { + core.next_up_on_available = Some(scheduled_core(9)); + core.next_up_on_time_out = Some(scheduled_core(9)); + }), + // 10: Occupied(both next_up set, not available, timeout), + build_occupied_core(10, |core| { + core.next_up_on_available = Some(scheduled_core(10)); + core.next_up_on_time_out = Some(scheduled_core(10)); + core.time_out_at = BLOCK_UNDER_PRODUCTION; + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(101)); + }), + // 11: Occupied(next_up_on_available and available, but different successor para_id) + build_occupied_core(11, |core| { + core.next_up_on_available = Some(scheduled_core(12)); + core.availability = core.availability.clone().not(); + }), + // 12-14: Occupied(next_up_on_available and available, same para_id). + build_occupied_core(12, |core| { + core.next_up_on_available = Some(scheduled_core(12)); + core.availability = core.availability.clone().not(); + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(121)); + }), + build_occupied_core(12, |core| { + core.next_up_on_available = Some(scheduled_core(12)); + core.availability = core.availability.clone().not(); + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(122)); + }), + build_occupied_core(12, |core| { + core.next_up_on_available = Some(scheduled_core(12)); + core.availability = core.availability.clone().not(); + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(123)); + }), + // 15: Scheduled on same para_id as 12-14. + Scheduled(scheduled_core(12)), + // 16: Occupied(13, no next_up set, not available) + build_occupied_core(13, |core| { + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(131)); + }), + // 17: Occupied(13, no next_up set, available) + build_occupied_core(13, |core| { + core.availability = core.availability.clone().not(); + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(132)); + }), + // 18: Occupied(13, next_up_on_available set to 13 but not available) + build_occupied_core(13, |core| { + core.next_up_on_available = Some(scheduled_core(13)); + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(133)); + }), + // 19: Occupied(13, next_up_on_available set to 13 and available) + build_occupied_core(13, |core| { + core.next_up_on_available = Some(scheduled_core(13)); + core.availability = core.availability.clone().not(); + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(134)); + }), + // 20: Occupied(13, next_up_on_time_out set to 13 but not timeout) + build_occupied_core(13, |core| { + core.next_up_on_time_out = Some(scheduled_core(13)); + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(135)); + }), + // 21: Occupied(13, next_up_on_available set to 14 and available) + build_occupied_core(13, |core| { + core.next_up_on_available = Some(scheduled_core(14)); + core.availability = core.availability.clone().not(); + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(136)); + }), + // 22: Occupied(13, next_up_on_available set to 14 but not available) + build_occupied_core(13, |core| { + core.next_up_on_available = Some(scheduled_core(14)); + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(137)); + }), + // 23: Occupied(13, both next_up set to 14, available) + build_occupied_core(13, |core| { + core.next_up_on_available = Some(scheduled_core(14)); + core.next_up_on_time_out = Some(scheduled_core(14)); + core.availability = core.availability.clone().not(); + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(138)); + }), + // 24: Occupied(13, both next_up set to 14, not available, timeout) + build_occupied_core(13, |core| { + core.next_up_on_available = Some(scheduled_core(14)); + core.next_up_on_time_out = Some(scheduled_core(14)); + core.time_out_at = BLOCK_UNDER_PRODUCTION; + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(1399)); + }), + // 25: Occupied(13, next_up_on_available and available, but successor para_id 15) + build_occupied_core(13, |core| { + core.next_up_on_available = Some(scheduled_core(15)); + core.availability = core.availability.clone().not(); + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(139)); + }), + // 26: Occupied(15, next_up_on_available and available, but successor para_id 13) + build_occupied_core(15, |core| { + core.next_up_on_available = Some(scheduled_core(13)); + core.availability = core.availability.clone().not(); + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(151)); + }), + // 27: Occupied(15, both next_up, both available and timed out) + build_occupied_core(15, |core| { + core.next_up_on_available = Some(scheduled_core(15)); + core.availability = core.availability.clone().not(); + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(152)); + core.time_out_at = BLOCK_UNDER_PRODUCTION; + }), + // 28: Occupied(13, both next_up set to 13, not available) + build_occupied_core(13, |core| { + core.next_up_on_available = Some(scheduled_core(13)); + core.next_up_on_time_out = Some(scheduled_core(13)); + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(1398)); + }), + // 29: Occupied(13, both next_up set to 13, not available, timeout) + build_occupied_core(13, |core| { + core.next_up_on_available = Some(scheduled_core(13)); + core.next_up_on_time_out = Some(scheduled_core(13)); + core.time_out_at = BLOCK_UNDER_PRODUCTION; + core.candidate_hash = CandidateHash(Hash::from_low_u64_be(1397)); + }), + ] + } + async fn mock_overseer( mut receiver: mpsc::UnboundedReceiver, - expected: Vec, + mock_availability_cores: Vec, + mut expected: Vec, + mut expected_ancestors: HashMap, Ancestors>, prospective_parachains_mode: ProspectiveParachainsMode, ) { use ChainApiMessage::BlockNumber; use RuntimeApiMessage::Request; + let mut backed_iter = expected.clone().into_iter(); + + expected.sort_by_key(|c| c.candidate().descriptor.para_id); let mut candidates_iter = expected .iter() .map(|candidate| (candidate.hash(), candidate.descriptor().relay_parent)); - let mut backed_iter = expected.clone().into_iter(); - while let Some(from_job) = receiver.next().await { match from_job { AllMessages::ChainApi(BlockNumber(_relay_parent, tx)) => @@ -356,7 +578,7 @@ mod select_candidates { PersistedValidationDataReq(_para_id, _assumption, tx), )) => tx.send(Ok(Some(Default::default()))).unwrap(), AllMessages::RuntimeApi(Request(_parent_hash, AvailabilityCores(tx))) => - tx.send(Ok(mock_availability_cores())).unwrap(), + tx.send(Ok(mock_availability_cores.clone())).unwrap(), AllMessages::CandidateBacking(CandidateBackingMessage::GetBackedCandidates( hashes, sender, @@ -373,35 +595,71 @@ mod select_candidates { let _ = sender.send(response); }, AllMessages::ProspectiveParachains( - ProspectiveParachainsMessage::GetBackableCandidates(_, _, count, _, tx), - ) => { - assert_eq!(count, 1); - - match prospective_parachains_mode { - ProspectiveParachainsMode::Enabled { .. } => { - let _ = - tx.send(candidates_iter.next().map_or_else(Vec::new, |c| vec![c])); - }, - ProspectiveParachainsMode::Disabled => - panic!("unexpected prospective parachains request"), - } + ProspectiveParachainsMessage::GetBackableCandidates( + _, + _para_id, + count, + actual_ancestors, + tx, + ), + ) => match prospective_parachains_mode { + ProspectiveParachainsMode::Enabled { .. } => { + assert!(count > 0); + let candidates = + (&mut candidates_iter).take(count as usize).collect::>(); + assert_eq!(candidates.len(), count as usize); + + if !expected_ancestors.is_empty() { + if let Some(expected_required_ancestors) = expected_ancestors.remove( + &(candidates + .clone() + .into_iter() + .take(actual_ancestors.len()) + .map(|(c_hash, _)| c_hash) + .collect::>()), + ) { + assert_eq!(expected_required_ancestors, actual_ancestors); + } else { + assert_eq!(actual_ancestors.len(), 0); + } + } + + let _ = tx.send(candidates); + }, + ProspectiveParachainsMode::Disabled => + panic!("unexpected prospective parachains request"), }, _ => panic!("Unexpected message: {:?}", from_job), } } + + if let ProspectiveParachainsMode::Enabled { .. } = prospective_parachains_mode { + assert_eq!(candidates_iter.next(), None); + } + assert_eq!(expected_ancestors.len(), 0); } - #[test] - fn can_succeed() { + #[rstest] + #[case(ProspectiveParachainsMode::Disabled)] + #[case(ProspectiveParachainsMode::Enabled {max_candidate_depth: 0, allowed_ancestry_len: 0})] + fn can_succeed(#[case] prospective_parachains_mode: ProspectiveParachainsMode) { test_harness( - |r| mock_overseer(r, Vec::new(), ProspectiveParachainsMode::Disabled), + |r| { + mock_overseer( + r, + Vec::new(), + Vec::new(), + HashMap::new(), + prospective_parachains_mode, + ) + }, |mut tx: TestSubsystemSender| async move { - let prospective_parachains_mode = ProspectiveParachainsMode::Disabled; select_candidates( &[], &[], &[], prospective_parachains_mode, + false, Default::default(), &mut tx, ) @@ -411,22 +669,22 @@ mod select_candidates { ) } - // this tests that only the appropriate candidates get selected. - // To accomplish this, we supply a candidate list containing one candidate per possible core; - // the candidate selection algorithm must filter them to the appropriate set - #[test] - fn selects_correct_candidates() { - let mock_cores = mock_availability_cores(); - - let empty_hash = PersistedValidationData::::default().hash(); - - let mut descriptor_template = dummy_candidate_descriptor(dummy_hash()); - descriptor_template.persisted_validation_data_hash = empty_hash; - let candidate_template = CandidateReceipt { - descriptor: descriptor_template, - commitments_hash: CandidateCommitments::default().hash(), - }; - + // Test candidate selection when prospective parachains mode is disabled. + // This tests that only the appropriate candidates get selected when prospective parachains mode + // is disabled. To accomplish this, we supply a candidate list containing one candidate per + // possible core; the candidate selection algorithm must filter them to the appropriate set + #[rstest] + // why those particular indices? see the comments on mock_availability_cores_*() functions. + #[case(mock_availability_cores_one_per_para(), vec![1, 4, 7, 8, 10], true)] + #[case(mock_availability_cores_one_per_para(), vec![1, 4, 7, 8, 10], false)] + #[case(mock_availability_cores_multiple_per_para(), vec![1, 4, 7, 8, 10, 12, 13, 14, 15], true)] + #[case(mock_availability_cores_multiple_per_para(), vec![1, 4, 7, 8, 10, 12, 13, 14, 15], false)] + fn test_in_subsystem_selection( + #[case] mock_cores: Vec, + #[case] expected_candidates: Vec, + #[case] elastic_scaling_mvp: bool, + ) { + let candidate_template = dummy_candidate_template(); let candidates: Vec<_> = std::iter::repeat(candidate_template) .take(mock_cores.len()) .enumerate() @@ -453,9 +711,8 @@ mod select_candidates { }) .collect(); - // why those particular indices? see the comments on mock_availability_cores() let expected_candidates: Vec<_> = - [1, 4, 7, 8, 10].iter().map(|&idx| candidates[idx].clone()).collect(); + expected_candidates.into_iter().map(|idx| candidates[idx].clone()).collect(); let prospective_parachains_mode = ProspectiveParachainsMode::Disabled; let expected_backed = expected_candidates @@ -473,14 +730,24 @@ mod select_candidates { }) .collect(); + let mock_cores_clone = mock_cores.clone(); test_harness( - |r| mock_overseer(r, expected_backed, prospective_parachains_mode), + |r| { + mock_overseer( + r, + mock_cores_clone, + expected_backed, + HashMap::new(), + prospective_parachains_mode, + ) + }, |mut tx: TestSubsystemSender| async move { - let result = select_candidates( + let result: Vec = select_candidates( &mock_cores, &[], &candidates, prospective_parachains_mode, + elastic_scaling_mvp, Default::default(), &mut tx, ) @@ -498,20 +765,24 @@ mod select_candidates { ) } - #[test] - fn selects_max_one_code_upgrade() { - let mock_cores = mock_availability_cores(); + #[rstest] + #[case(ProspectiveParachainsMode::Disabled)] + #[case(ProspectiveParachainsMode::Enabled {max_candidate_depth: 0, allowed_ancestry_len: 0})] + fn selects_max_one_code_upgrade( + #[case] prospective_parachains_mode: ProspectiveParachainsMode, + ) { + let mock_cores = mock_availability_cores_one_per_para(); let empty_hash = PersistedValidationData::::default().hash(); // why those particular indices? see the comments on mock_availability_cores() - // the first candidate with code is included out of [1, 4, 7, 8, 10]. - let cores = [1, 4, 7, 8, 10]; + // the first candidate with code is included out of [1, 4, 7, 8, 10, 12]. + let cores = [1, 4, 7, 8, 10, 12]; let cores_with_code = [1, 4, 8]; - let expected_cores = [1, 7, 10]; + let expected_cores = [1, 7, 10, 12]; - let committed_receipts: Vec<_> = (0..mock_cores.len()) + let committed_receipts: Vec<_> = (0..=mock_cores.len()) .map(|i| { let mut descriptor = dummy_candidate_descriptor(dummy_hash()); descriptor.para_id = i.into(); @@ -552,23 +823,32 @@ mod select_candidates { let expected_backed_filtered: Vec<_> = expected_cores.iter().map(|&idx| candidates[idx].clone()).collect(); - let prospective_parachains_mode = ProspectiveParachainsMode::Disabled; + let mock_cores_clone = mock_cores.clone(); test_harness( - |r| mock_overseer(r, expected_backed, prospective_parachains_mode), + |r| { + mock_overseer( + r, + mock_cores_clone, + expected_backed, + HashMap::new(), + prospective_parachains_mode, + ) + }, |mut tx: TestSubsystemSender| async move { let result = select_candidates( &mock_cores, &[], &candidates, prospective_parachains_mode, + false, Default::default(), &mut tx, ) .await .unwrap(); - assert_eq!(result.len(), 3); + assert_eq!(result.len(), 4); result.into_iter().for_each(|c| { assert!( @@ -581,66 +861,214 @@ mod select_candidates { ) } - #[test] - fn request_from_prospective_parachains() { - let mock_cores = mock_availability_cores(); - let empty_hash = PersistedValidationData::::default().hash(); + #[rstest] + #[case(true)] + #[case(false)] + fn request_from_prospective_parachains_one_core_per_para(#[case] elastic_scaling_mvp: bool) { + let mock_cores = mock_availability_cores_one_per_para(); - let mut descriptor_template = dummy_candidate_descriptor(dummy_hash()); - descriptor_template.persisted_validation_data_hash = empty_hash; - let candidate_template = CandidateReceipt { - descriptor: descriptor_template, - commitments_hash: CandidateCommitments::default().hash(), - }; + // why those particular indices? see the comments on mock_availability_cores() + let expected_candidates: Vec<_> = vec![1, 4, 7, 8, 10, 12]; + let (candidates, expected_candidates) = + make_candidates(mock_cores.len() + 1, expected_candidates); - let candidates: Vec<_> = std::iter::repeat(candidate_template) - .take(mock_cores.len()) - .enumerate() - .map(|(idx, mut candidate)| { - candidate.descriptor.para_id = idx.into(); - candidate - }) - .collect(); + // Expect prospective parachains subsystem requests. + let prospective_parachains_mode = + ProspectiveParachainsMode::Enabled { max_candidate_depth: 0, allowed_ancestry_len: 0 }; + + let mut required_ancestors: HashMap, Ancestors> = HashMap::new(); + required_ancestors.insert( + vec![candidates[4]], + vec![CandidateHash(Hash::from_low_u64_be(41))].into_iter().collect(), + ); + required_ancestors.insert( + vec![candidates[8]], + vec![CandidateHash(Hash::from_low_u64_be(81))].into_iter().collect(), + ); + + let mock_cores_clone = mock_cores.clone(); + let expected_candidates_clone = expected_candidates.clone(); + test_harness( + |r| { + mock_overseer( + r, + mock_cores_clone, + expected_candidates_clone, + required_ancestors, + prospective_parachains_mode, + ) + }, + |mut tx: TestSubsystemSender| async move { + let result = select_candidates( + &mock_cores, + &[], + &[], + prospective_parachains_mode, + elastic_scaling_mvp, + Default::default(), + &mut tx, + ) + .await + .unwrap(); + + assert_eq!(result.len(), expected_candidates.len()); + result.into_iter().for_each(|c| { + assert!( + expected_candidates + .iter() + .any(|c2| c.candidate().corresponds_to(&c2.receipt())), + "Failed to find candidate: {:?}", + c, + ) + }); + }, + ) + } + + #[test] + fn request_from_prospective_parachains_multiple_cores_per_para_elastic_scaling_mvp() { + let mock_cores = mock_availability_cores_multiple_per_para(); // why those particular indices? see the comments on mock_availability_cores() let expected_candidates: Vec<_> = - [1, 4, 7, 8, 10].iter().map(|&idx| candidates[idx].clone()).collect(); + vec![1, 4, 7, 8, 10, 12, 12, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15]; // Expect prospective parachains subsystem requests. let prospective_parachains_mode = ProspectiveParachainsMode::Enabled { max_candidate_depth: 0, allowed_ancestry_len: 0 }; - let expected_backed = expected_candidates - .iter() - .map(|c| { - BackedCandidate::new( - CommittedCandidateReceipt { - descriptor: c.descriptor.clone(), - commitments: Default::default(), - }, - Vec::new(), - default_bitvec(MOCK_GROUP_SIZE), - None, + let (candidates, expected_candidates) = + make_candidates(mock_cores.len(), expected_candidates); + + let mut required_ancestors: HashMap, Ancestors> = HashMap::new(); + required_ancestors.insert( + vec![candidates[4]], + vec![CandidateHash(Hash::from_low_u64_be(41))].into_iter().collect(), + ); + required_ancestors.insert( + vec![candidates[8]], + vec![CandidateHash(Hash::from_low_u64_be(81))].into_iter().collect(), + ); + required_ancestors.insert( + [12, 12, 12].iter().map(|&idx| candidates[idx]).collect::>(), + vec![ + CandidateHash(Hash::from_low_u64_be(121)), + CandidateHash(Hash::from_low_u64_be(122)), + CandidateHash(Hash::from_low_u64_be(123)), + ] + .into_iter() + .collect(), + ); + required_ancestors.insert( + [13, 13, 13].iter().map(|&idx| candidates[idx]).collect::>(), + (131..=139) + .map(|num| CandidateHash(Hash::from_low_u64_be(num))) + .chain(std::iter::once(CandidateHash(Hash::from_low_u64_be(1398)))) + .collect(), + ); + + required_ancestors.insert( + [15, 15].iter().map(|&idx| candidates[idx]).collect::>(), + vec![ + CandidateHash(Hash::from_low_u64_be(151)), + CandidateHash(Hash::from_low_u64_be(152)), + ] + .into_iter() + .collect(), + ); + + let mock_cores_clone = mock_cores.clone(); + let expected_candidates_clone = expected_candidates.clone(); + test_harness( + |r| { + mock_overseer( + r, + mock_cores_clone, + expected_candidates, + required_ancestors, + prospective_parachains_mode, ) - }) - .collect(); + }, + |mut tx: TestSubsystemSender| async move { + let result = select_candidates( + &mock_cores, + &[], + &[], + prospective_parachains_mode, + true, + Default::default(), + &mut tx, + ) + .await + .unwrap(); + assert_eq!(result.len(), expected_candidates_clone.len()); + result.into_iter().for_each(|c| { + assert!( + expected_candidates_clone + .iter() + .any(|c2| c.candidate().corresponds_to(&c2.receipt())), + "Failed to find candidate: {:?}", + c, + ) + }); + }, + ) + } + + #[test] + fn request_from_prospective_parachains_multiple_cores_per_para_elastic_scaling_mvp_disabled() { + let mock_cores = mock_availability_cores_multiple_per_para(); + + // why those particular indices? see the comments on mock_availability_cores() + let expected_candidates: Vec<_> = vec![1, 4, 7, 8, 10]; + // Expect prospective parachains subsystem requests. + let prospective_parachains_mode = + ProspectiveParachainsMode::Enabled { max_candidate_depth: 0, allowed_ancestry_len: 0 }; + + let (candidates, expected_candidates) = + make_candidates(mock_cores.len(), expected_candidates); + + let mut required_ancestors: HashMap, Ancestors> = HashMap::new(); + required_ancestors.insert( + vec![candidates[4]], + vec![CandidateHash(Hash::from_low_u64_be(41))].into_iter().collect(), + ); + required_ancestors.insert( + vec![candidates[8]], + vec![CandidateHash(Hash::from_low_u64_be(81))].into_iter().collect(), + ); + + let mock_cores_clone = mock_cores.clone(); + let expected_candidates_clone = expected_candidates.clone(); test_harness( - |r| mock_overseer(r, expected_backed, prospective_parachains_mode), + |r| { + mock_overseer( + r, + mock_cores_clone, + expected_candidates, + required_ancestors, + prospective_parachains_mode, + ) + }, |mut tx: TestSubsystemSender| async move { let result = select_candidates( &mock_cores, &[], &[], prospective_parachains_mode, + false, Default::default(), &mut tx, ) .await .unwrap(); + assert_eq!(result.len(), expected_candidates_clone.len()); result.into_iter().for_each(|c| { assert!( - expected_candidates.iter().any(|c2| c.candidate().corresponds_to(c2)), + expected_candidates_clone + .iter() + .any(|c2| c.candidate().corresponds_to(&c2.receipt())), "Failed to find candidate: {:?}", c, ) @@ -651,18 +1079,11 @@ mod select_candidates { #[test] fn request_receipts_based_on_relay_parent() { - let mock_cores = mock_availability_cores(); - let empty_hash = PersistedValidationData::::default().hash(); - - let mut descriptor_template = dummy_candidate_descriptor(dummy_hash()); - descriptor_template.persisted_validation_data_hash = empty_hash; - let candidate_template = CandidateReceipt { - descriptor: descriptor_template, - commitments_hash: CandidateCommitments::default().hash(), - }; + let mock_cores = mock_availability_cores_one_per_para(); + let candidate_template = dummy_candidate_template(); let candidates: Vec<_> = std::iter::repeat(candidate_template) - .take(mock_cores.len()) + .take(mock_cores.len() + 1) .enumerate() .map(|(idx, mut candidate)| { candidate.descriptor.para_id = idx.into(); @@ -673,7 +1094,7 @@ mod select_candidates { // why those particular indices? see the comments on mock_availability_cores() let expected_candidates: Vec<_> = - [1, 4, 7, 8, 10].iter().map(|&idx| candidates[idx].clone()).collect(); + [1, 4, 7, 8, 10, 12].iter().map(|&idx| candidates[idx].clone()).collect(); // Expect prospective parachains subsystem requests. let prospective_parachains_mode = ProspectiveParachainsMode::Enabled { max_candidate_depth: 0, allowed_ancestry_len: 0 }; @@ -693,14 +1114,24 @@ mod select_candidates { }) .collect(); + let mock_cores_clone = mock_cores.clone(); test_harness( - |r| mock_overseer(r, expected_backed, prospective_parachains_mode), + |r| { + mock_overseer( + r, + mock_cores_clone, + expected_backed, + HashMap::new(), + prospective_parachains_mode, + ) + }, |mut tx: TestSubsystemSender| async move { let result = select_candidates( &mock_cores, &[], &[], prospective_parachains_mode, + false, Default::default(), &mut tx, ) diff --git a/polkadot/node/subsystem-types/src/messages.rs b/polkadot/node/subsystem-types/src/messages.rs index 549e43a671d..f11291fd0ea 100644 --- a/polkadot/node/subsystem-types/src/messages.rs +++ b/polkadot/node/subsystem-types/src/messages.rs @@ -1112,6 +1112,9 @@ pub struct ProspectiveValidationDataRequest { /// is present in and the depths of that tree the candidate is present in. pub type FragmentTreeMembership = Vec<(Hash, Vec)>; +/// A collection of ancestor candidates of a parachain. +pub type Ancestors = HashSet; + /// Messages sent to the Prospective Parachains subsystem. #[derive(Debug)] pub enum ProspectiveParachainsMessage { @@ -1128,15 +1131,18 @@ pub enum ProspectiveParachainsMessage { /// has been backed. This requires that the candidate was successfully introduced in /// the past. CandidateBacked(ParaId, CandidateHash), - /// Get N backable candidate hashes along with their relay parents for the given parachain, - /// under the given relay-parent hash, which is a descendant of the given candidate hashes. + /// Try getting N backable candidate hashes along with their relay parents for the given + /// parachain, under the given relay-parent hash, which is a descendant of the given ancestors. + /// Timed out ancestors should not be included in the collection. /// N should represent the number of scheduled cores of this ParaId. - /// Returns `None` on the channel if no such candidate exists. + /// A timed out ancestor frees the cores of all of its descendants, so if there's a hole in the + /// supplied ancestor path, we'll get candidates that backfill those timed out slots first. It + /// may also return less/no candidates, if there aren't enough backable candidates recorded. GetBackableCandidates( Hash, ParaId, u32, - Vec, + Ancestors, oneshot::Sender>, ), /// Get the hypothetical frontier membership of candidates with the given properties diff --git a/prdoc/pr_3233.prdoc b/prdoc/pr_3233.prdoc new file mode 100644 index 00000000000..ed4e8cce31f --- /dev/null +++ b/prdoc/pr_3233.prdoc @@ -0,0 +1,12 @@ +title: "provisioner: allow multiple cores assigned to the same para" + +topic: Node + +doc: + - audience: Node Dev + description: | + Enable supplying multiple backable candidates to the paras_inherent pallet for the same paraid. + +crates: + - name: polkadot-node-core-prospective-parachains + - name: polkadot-node-core-provisioner -- GitLab From cdc8d197e6d487ef54f7e16767b5c1ab041c8b10 Mon Sep 17 00:00:00 2001 From: gupnik Date: Sat, 2 Mar 2024 18:19:12 +0530 Subject: [PATCH 337/392] Remove `as frame_system::DefaultConfig` from the required syntax in `derive_impl` (#3505) Step in https://github.com/paritytech/polkadot-sdk/issues/171 This PR removes the need to specify `as [disambiguation_path]` for cases where the trait definition resides within the same scope as default impl path. For example, in the following macro invocation ```rust #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Runtime { ... } ``` the trait `DefaultConfig` lies within the `frame_system` scope and `TestDefaultConfig` impls the `DefaultConfig` trait. Using this information, we can compute the disambiguation path internally, thus removing the need of an explicit specification. In cases where the trait lies outside this scope, we would still need to specify it explicitly, but this should take care of most (if not all) uses of `derive_impl` within FRAME's context. --- prdoc/pr_3505.prdoc | 36 ++++++++++ .../frame/examples/default-config/src/lib.rs | 2 +- .../support/procedural/src/derive_impl.rs | 68 +++++++++++++++---- substrate/frame/support/procedural/src/lib.rs | 5 ++ 4 files changed, 98 insertions(+), 13 deletions(-) create mode 100644 prdoc/pr_3505.prdoc diff --git a/prdoc/pr_3505.prdoc b/prdoc/pr_3505.prdoc new file mode 100644 index 00000000000..08ad909739c --- /dev/null +++ b/prdoc/pr_3505.prdoc @@ -0,0 +1,36 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Removes `as [disambiguation_path]` from the required syntax in `derive_impl` + +doc: + - audience: Runtime Dev + description: | + This PR removes the need to specify `as [disambiguation_path]` for cases where the trait + definition resides within the same scope as default impl path. + + For example, in the following macro invocation + ```rust + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + impl frame_system::Config for Runtime { + ... + } + ``` + the trait `DefaultConfig` lies within the `frame_system` scope and `TestDefaultConfig` impls + the `DefaultConfig` trait. + + Using this information, we can compute the disambiguation path internally, thus removing the + need of an explicit specification: + ```rust + #[derive_impl(frame_system::config_preludes::TestDefaultConfig)] + impl frame_system::Config for Runtime { + ... + } + ``` + + In cases where the trait lies outside this scope, we would still need to specify it explicitly, + but this should take care of most (if not all) uses of `derive_impl` within FRAME's context. + +crates: + - name: frame-support-procedural + - name: pallet-default-config-example diff --git a/substrate/frame/examples/default-config/src/lib.rs b/substrate/frame/examples/default-config/src/lib.rs index cd1653e6c76..69eca055965 100644 --- a/substrate/frame/examples/default-config/src/lib.rs +++ b/substrate/frame/examples/default-config/src/lib.rs @@ -149,7 +149,7 @@ pub mod tests { } ); - #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + #[derive_impl(frame_system::config_preludes::TestDefaultConfig)] impl frame_system::Config for Runtime { // these items are defined by frame-system as `no_default`, so we must specify them here. type Block = Block; diff --git a/substrate/frame/support/procedural/src/derive_impl.rs b/substrate/frame/support/procedural/src/derive_impl.rs index d6d5bf68efd..8740ccd401a 100644 --- a/substrate/frame/support/procedural/src/derive_impl.rs +++ b/substrate/frame/support/procedural/src/derive_impl.rs @@ -172,6 +172,33 @@ fn combine_impls( final_impl } +/// Computes the disambiguation path for the `derive_impl` attribute macro. +/// +/// When specified explicitly using `as [disambiguation_path]` in the macro attr, the +/// disambiguation is used as is. If not, we infer the disambiguation path from the +/// `foreign_impl_path` and the computed scope. +fn compute_disambiguation_path( + disambiguation_path: Option, + foreign_impl: ItemImpl, + default_impl_path: Path, +) -> Result { + match (disambiguation_path, foreign_impl.clone().trait_) { + (Some(disambiguation_path), _) => Ok(disambiguation_path), + (None, Some((_, foreign_impl_path, _))) => + if default_impl_path.segments.len() > 1 { + let scope = default_impl_path.segments.first(); + Ok(parse_quote!(#scope :: #foreign_impl_path)) + } else { + Ok(foreign_impl_path) + }, + _ => Err(syn::Error::new( + default_impl_path.span(), + "Impl statement must have a defined type being implemented \ + for a defined type such as `impl A for B`", + )), + } +} + /// Internal implementation behind [`#[derive_impl(..)]`](`macro@crate::derive_impl`). /// /// `default_impl_path`: the module path of the external `impl` statement whose tokens we are @@ -194,18 +221,11 @@ pub fn derive_impl( let foreign_impl = parse2::(foreign_tokens)?; let default_impl_path = parse2::(default_impl_path)?; - // have disambiguation_path default to the item being impl'd in the foreign impl if we - // don't specify an `as [disambiguation_path]` in the macro attr - let disambiguation_path = match (disambiguation_path, foreign_impl.clone().trait_) { - (Some(disambiguation_path), _) => disambiguation_path, - (None, Some((_, foreign_impl_path, _))) => foreign_impl_path, - _ => - return Err(syn::Error::new( - foreign_impl.span(), - "Impl statement must have a defined type being implemented \ - for a defined type such as `impl A for B`", - )), - }; + let disambiguation_path = compute_disambiguation_path( + disambiguation_path, + foreign_impl.clone(), + default_impl_path.clone(), + )?; // generate the combined impl let combined_impl = combine_impls( @@ -257,3 +277,27 @@ fn test_runtime_type_with_doc() { } } } + +#[test] +fn test_disambugation_path() { + let foreign_impl: ItemImpl = parse_quote!(impl SomeTrait for SomeType {}); + let default_impl_path: Path = parse_quote!(SomeScope::SomeType); + + // disambiguation path is specified + let disambiguation_path = compute_disambiguation_path( + Some(parse_quote!(SomeScope::SomePath)), + foreign_impl.clone(), + default_impl_path.clone(), + ); + assert_eq!(disambiguation_path.unwrap(), parse_quote!(SomeScope::SomePath)); + + // disambiguation path is not specified and the default_impl_path has more than one segment + let disambiguation_path = + compute_disambiguation_path(None, foreign_impl.clone(), default_impl_path.clone()); + assert_eq!(disambiguation_path.unwrap(), parse_quote!(SomeScope::SomeTrait)); + + // disambiguation path is not specified and the default_impl_path has only one segment + let disambiguation_path = + compute_disambiguation_path(None, foreign_impl.clone(), parse_quote!(SomeType)); + assert_eq!(disambiguation_path.unwrap(), parse_quote!(SomeTrait)); +} diff --git a/substrate/frame/support/procedural/src/lib.rs b/substrate/frame/support/procedural/src/lib.rs index 5840377d722..ed920d6a1da 100644 --- a/substrate/frame/support/procedural/src/lib.rs +++ b/substrate/frame/support/procedural/src/lib.rs @@ -639,6 +639,11 @@ pub fn storage_alias(attributes: TokenStream, input: TokenStream) -> TokenStream /// default to `A` from the `impl A for B` part of the default impl. This is useful for scenarios /// where all of the relevant types are already in scope via `use` statements. /// +/// In case the `default_impl_path` is scoped to a different module such as +/// `some::path::TestTraitImpl`, the same scope is assumed for the `disambiguation_path`, i.e. +/// `some::A`. This enables the use of `derive_impl` attribute without having to specify the +/// `disambiguation_path` in most (if not all) uses within FRAME's context. +/// /// Conversely, the `default_impl_path` argument is required and cannot be omitted. /// /// Optionally, `no_aggregated_types` can be specified as follows: -- GitLab From b0741d4f78ebc424c7544e1d2d5db7968132e577 Mon Sep 17 00:00:00 2001 From: Liam Aharon Date: Sun, 3 Mar 2024 19:37:41 +1100 Subject: [PATCH 338/392] Finish documenting `#[pallet::xxx]` macros (#2638) Closes https://github.com/paritytech/polkadot-sdk-docs/issues/35 - Moves pallet proc macro docs to `frame_support` - Adds missing docs - Revise revise existing docs, adding compiling doctests where appropriate --------- Co-authored-by: command-bot <> Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- Cargo.lock | 1 + docs/sdk/src/guides/your_first_pallet/mod.rs | 20 +- substrate/frame/support/Cargo.toml | 2 + substrate/frame/support/procedural/src/lib.rs | 746 +----- substrate/frame/support/src/lib.rs | 2345 +++++++---------- 5 files changed, 1127 insertions(+), 1987 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c42ec612e6c..ad218001b40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5750,6 +5750,7 @@ dependencies = [ "sp-staking", "sp-state-machine", "sp-std 14.0.0", + "sp-timestamp", "sp-tracing 16.0.0", "sp-weights", "static_assertions", diff --git a/docs/sdk/src/guides/your_first_pallet/mod.rs b/docs/sdk/src/guides/your_first_pallet/mod.rs index 20a8639b270..6a262924824 100644 --- a/docs/sdk/src/guides/your_first_pallet/mod.rs +++ b/docs/sdk/src/guides/your_first_pallet/mod.rs @@ -250,14 +250,16 @@ // of event is probably not the best. //! //! With the explanation out of the way, let's see how these components can be added. Both follow a -//! fairly familiar syntax: normal Rust enums, with an extra `#[frame::event/error]` attribute -//! attached. +//! fairly familiar syntax: normal Rust enums, with extra +//! [`#[frame::event]`](frame::pallet_macros::event) and +//! [`#[frame::error]`](frame::pallet_macros::error) attributes attached. #![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", Event)] #![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", Error)] //! -//! One slightly custom part of this is the `#[pallet::generate_deposit(pub(super) fn -//! deposit_event)]` part. Without going into too much detail, in order for a pallet to emit events -//! to the rest of the system, it needs to do two things: +//! One slightly custom part of this is the [`#[pallet::generate_deposit(pub(super) fn +//! deposit_event)]`](frame::pallet_macros::generate_deposit) part. Without going into too +//! much detail, in order for a pallet to emit events to the rest of the system, it needs to do two +//! things: //! //! 1. Declare a type in its `Config` that refers to the overarching event type of the runtime. In //! short, by doing this, the pallet is expressing an important bound: `type RuntimeEvent: @@ -266,7 +268,8 @@ //! store it where needed. //! //! 2. But, doing this conversion and storing is too much to expect each pallet to define. FRAME -//! provides a default way of storing events, and this is what `pallet::generate_deposit` is doing. +//! provides a default way of storing events, and this is what +//! [`pallet::generate_deposit`](frame::pallet_macros::generate_deposit) is doing. #![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", config_v2)] //! //! > These `Runtime*` types are better explained in @@ -280,8 +283,9 @@ #![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", runtime_v2)] //! //! In this snippet, the actual `RuntimeEvent` type (right hand side of `type RuntimeEvent = -//! RuntimeEvent`) is generated by `construct_runtime`. An interesting way to inspect this type is -//! to see its definition in rust-docs: +//! RuntimeEvent`) is generated by +//! [`construct_runtime`](frame::runtime::prelude::construct_runtime). An interesting way to inspect +//! this type is to see its definition in rust-docs: //! [`crate::guides::your_first_pallet::pallet_v2::tests::runtime_v2::RuntimeEvent`]. //! //! diff --git a/substrate/frame/support/Cargo.toml b/substrate/frame/support/Cargo.toml index c19f478c803..fb9cb3d4511 100644 --- a/substrate/frame/support/Cargo.toml +++ b/substrate/frame/support/Cargo.toml @@ -66,6 +66,7 @@ aquamarine = { version = "0.5.0" } [dev-dependencies] assert_matches = "1.3.0" pretty_assertions = "1.2.1" +sp-timestamp = { path = "../../primitives/timestamp", default-features = false } frame-system = { path = "../system" } sp-crypto-hashing = { path = "../../primitives/crypto/hashing" } @@ -96,6 +97,7 @@ std = [ "sp-std/std", "sp-tracing/std", "sp-weights/std", + "sp-timestamp/std" ] runtime-benchmarks = [ "frame-system/runtime-benchmarks", diff --git a/substrate/frame/support/procedural/src/lib.rs b/substrate/frame/support/procedural/src/lib.rs index ed920d6a1da..036da52a7ba 100644 --- a/substrate/frame/support/procedural/src/lib.rs +++ b/substrate/frame/support/procedural/src/lib.rs @@ -188,133 +188,11 @@ pub fn construct_runtime(input: TokenStream) -> TokenStream { construct_runtime::construct_runtime(input) } -/// The pallet struct placeholder `#[pallet::pallet]` is mandatory and allows you to specify -/// pallet information. /// -/// The struct must be defined as follows: -/// ```ignore -/// #[pallet::pallet] -/// pub struct Pallet(_); -/// ``` -/// I.e. a regular struct definition named `Pallet`, with generic T and no where clause. -/// -/// ## Macro expansion: -/// -/// The macro adds this attribute to the struct definition: -/// ```ignore -/// #[derive( -/// frame_support::CloneNoBound, -/// frame_support::EqNoBound, -/// frame_support::PartialEqNoBound, -/// frame_support::RuntimeDebugNoBound, -/// )] -/// ``` -/// and replaces the type `_` with `PhantomData`. It also implements on the pallet: -/// * `GetStorageVersion` -/// * `OnGenesis`: contains some logic to write the pallet version into storage. -/// * `PalletErrorTypeInfo`: provides the type information for the pallet error, if defined. -/// -/// It declares `type Module` type alias for `Pallet`, used by `construct_runtime`. -/// -/// It implements `PalletInfoAccess` on `Pallet` to ease access to pallet information given by -/// `frame_support::traits::PalletInfo`. (The implementation uses the associated type -/// `frame_system::Config::PalletInfo`). -/// -/// It implements `StorageInfoTrait` on `Pallet` which give information about all storages. -/// -/// If the attribute `generate_store` is set then the macro creates the trait `Store` and -/// implements it on `Pallet`. -/// -/// If the attribute `set_storage_max_encoded_len` is set then the macro calls -/// `StorageInfoTrait` for each storage in the implementation of `StorageInfoTrait` for the -/// pallet. Otherwise it implements `StorageInfoTrait` for the pallet using the -/// `PartialStorageInfoTrait` implementation of storages. -/// -/// ## Dev Mode (`#[pallet(dev_mode)]`) -/// -/// Specifying the argument `dev_mode` will allow you to enable dev mode for a pallet. The aim -/// of dev mode is to loosen some of the restrictions and requirements placed on production -/// pallets for easy tinkering and development. Dev mode pallets should not be used in -/// production. Enabling dev mode has the following effects: -/// -/// * Weights no longer need to be specified on every `#[pallet::call]` declaration. By default, dev -/// mode pallets will assume a weight of zero (`0`) if a weight is not specified. This is -/// equivalent to specifying `#[weight(0)]` on all calls that do not specify a weight. -/// * Call indices no longer need to be specified on every `#[pallet::call]` declaration. By -/// default, dev mode pallets will assume a call index based on the order of the call. -/// * All storages are marked as unbounded, meaning you do not need to implement `MaxEncodedLen` on -/// storage types. This is equivalent to specifying `#[pallet::unbounded]` on all storage type -/// definitions. -/// * Storage hashers no longer need to be specified and can be replaced by `_`. In dev mode, these -/// will be replaced by `Blake2_128Concat`. In case of explicit key-binding, `Hasher` can simply -/// be ignored when in `dev_mode`. -/// -/// Note that the `dev_mode` argument can only be supplied to the `#[pallet]` or -/// `#[frame_support::pallet]` attribute macro that encloses your pallet module. This argument -/// cannot be specified anywhere else, including but not limited to the `#[pallet::pallet]` -/// attribute macro. -/// -///
-/// WARNING:
-/// You should not deploy or use dev mode pallets in production. Doing so can break your chain
-/// and therefore should never be done. Once you are done tinkering, you should remove the
-/// 'dev_mode' argument from your #[pallet] declaration and fix any compile errors before
-/// attempting to use your pallet in a production scenario.
-/// 
-/// -/// See `frame_support::pallet` docs for more info. -/// -/// ## Runtime Metadata Documentation -/// -/// The documentation added to this pallet is included in the runtime metadata. -/// -/// The documentation can be defined in the following ways: -/// -/// ```ignore -/// #[pallet::pallet] -/// /// Documentation for pallet 1 -/// #[doc = "Documentation for pallet 2"] -/// #[doc = include_str!("../README.md")] -/// #[pallet_doc("../doc1.md")] -/// #[pallet_doc("../doc2.md")] -/// pub mod pallet {} -/// ``` -/// -/// The runtime metadata for this pallet contains the following -/// - " Documentation for pallet 1" (captured from `///`) -/// - "Documentation for pallet 2" (captured from `#[doc]`) -/// - content of ../README.md (captured from `#[doc]` with `include_str!`) -/// - content of "../doc1.md" (captured from `pallet_doc`) -/// - content of "../doc2.md" (captured from `pallet_doc`) -/// -/// ### `doc` attribute -/// -/// The value of the `doc` attribute is included in the runtime metadata, as well as -/// expanded on the pallet module. The previous example is expanded to: -/// -/// ```ignore -/// /// Documentation for pallet 1 -/// /// Documentation for pallet 2 -/// /// Content of README.md -/// pub mod pallet {} -/// ``` -/// -/// If you want to specify the file from which the documentation is loaded, you can use the -/// `include_str` macro. However, if you only want the documentation to be included in the -/// runtime metadata, use the `pallet_doc` attribute. -/// -/// ### `pallet_doc` attribute -/// -/// Unlike the `doc` attribute, the documentation provided to the `pallet_doc` attribute is -/// not inserted on the module. -/// -/// The `pallet_doc` attribute can only be provided with one argument, -/// which is the file path that holds the documentation to be added to the metadata. +/// --- /// -/// This approach is beneficial when you use the `include_str` macro at the beginning of the file -/// and want that documentation to extend to the runtime metadata, without reiterating the -/// documentation on the pallet module itself. +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet`. #[proc_macro_attribute] pub fn pallet(attr: TokenStream, item: TokenStream) -> TokenStream { pallet::pallet(attr, item) @@ -408,19 +286,28 @@ pub fn transactional(attr: TokenStream, input: TokenStream) -> TokenStream { transactional::transactional(attr, input).unwrap_or_else(|e| e.to_compile_error().into()) } +/// +/// --- +/// +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::require_transactional`. #[proc_macro_attribute] pub fn require_transactional(attr: TokenStream, input: TokenStream) -> TokenStream { transactional::require_transactional(attr, input) .unwrap_or_else(|e| e.to_compile_error().into()) } -/// Derive [`Clone`] but do not bound any generic. Docs are at `frame_support::CloneNoBound`. +/// Derive [`Clone`] but do not bound any generic. +/// +/// Docs at `frame_support::CloneNoBound`. #[proc_macro_derive(CloneNoBound)] pub fn derive_clone_no_bound(input: TokenStream) -> TokenStream { no_bound::clone::derive_clone_no_bound(input) } -/// Derive [`Debug`] but do not bound any generics. Docs are at `frame_support::DebugNoBound`. +/// Derive [`Debug`] but do not bound any generics. +/// +/// Docs at `frame_support::DebugNoBound`. #[proc_macro_derive(DebugNoBound)] pub fn derive_debug_no_bound(input: TokenStream) -> TokenStream { no_bound::debug::derive_debug_no_bound(input) @@ -452,14 +339,17 @@ pub fn derive_runtime_debug_no_bound(input: TokenStream) -> TokenStream { } } -/// Derive [`PartialEq`] but do not bound any generic. Docs are at -/// `frame_support::PartialEqNoBound`. +/// Derive [`PartialEq`] but do not bound any generic. +/// +/// Docs at `frame_support::PartialEqNoBound`. #[proc_macro_derive(PartialEqNoBound)] pub fn derive_partial_eq_no_bound(input: TokenStream) -> TokenStream { no_bound::partial_eq::derive_partial_eq_no_bound(input) } -/// Derive [`Eq`] but do no bound any generic. Docs are at `frame_support::EqNoBound`. +/// DeriveEq but do no bound any generic. +/// +/// Docs at `frame_support::EqNoBound`. #[proc_macro_derive(EqNoBound)] pub fn derive_eq_no_bound(input: TokenStream) -> TokenStream { let input = syn::parse_macro_input!(input as syn::DeriveInput); @@ -494,6 +384,7 @@ pub fn derive_default_no_bound(input: TokenStream) -> TokenStream { no_bound::default::derive_default_no_bound(input) } +/// Macro used internally in FRAME to generate the crate version for a pallet. #[proc_macro] pub fn crate_to_crate_version(input: TokenStream) -> TokenStream { crate_version::crate_to_crate_version(input) @@ -555,42 +446,11 @@ pub fn __create_tt_macro(input: TokenStream) -> TokenStream { tt_macro::create_tt_return_macro(input) } -/// Allows accessing on-chain pallet storage that is no longer accessible via the pallet. -/// -/// This is especially useful when writing storage migrations, when types of storage items are -/// modified or outright removed, but the previous definition is required to perform the migration. /// -/// ## Example -/// -/// Imagine a pallet with the following storage definition: -/// ```ignore -/// #[pallet::storage] -/// pub type Value = StorageValue<_, u32>; -/// ``` -/// `Value` can be accessed by calling `Value::::get()`. -/// -/// Now imagine the definition of `Value` is updated to a `(u32, u32)`: -/// ```ignore -/// #[pallet::storage] -/// pub type Value = StorageValue<_, (u32, u32)>; -/// ``` -/// The on-chain value of `Value` is `u32`, but `Value::::get()` expects it to be `(u32, u32)`. -/// -/// In this instance the developer must write a storage migration to reading the old value of -/// `Value` and writing it back to storage in the new format, so that the on-chain storage layout is -/// consistent with what is defined in the pallet. -/// -/// We can read the old v0 value of `Value` in the migration by creating a `storage_alias`: -/// ```ignore -/// pub(crate) mod v0 { -/// use super::*; -/// -/// #[storage_alias] -/// pub type Value = StorageValue, u32>; -/// } -/// ``` +/// --- /// -/// The developer can now access the old value of `Value` by calling `v0::Value::::get()`. +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::storage_alias`. #[proc_macro_attribute] pub fn storage_alias(attributes: TokenStream, input: TokenStream) -> TokenStream { storage_alias::storage_alias(attributes.into(), input.into()) @@ -826,24 +686,21 @@ pub fn derive_impl(attrs: TokenStream, input: TokenStream) -> TokenStream { .into() } -/// The optional attribute `#[pallet::no_default]` can be attached to trait items within a -/// `Config` trait impl that has [`#[pallet::config(with_default)]`](`macro@config`) attached. /// -/// Attaching this attribute to a trait item ensures that that trait item will not be used as a -/// default with the [`#[derive_impl(..)]`](`macro@derive_impl`) attribute macro. +/// --- +/// +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::no_default`. #[proc_macro_attribute] pub fn no_default(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// The optional attribute `#[pallet::no_default_bounds]` can be attached to trait items within a -/// `Config` trait impl that has [`#[pallet::config(with_default)]`](`macro@config`) attached. /// -/// Attaching this attribute to a trait item ensures that the generated trait `DefaultConfig` -/// will not have any bounds for this trait item. +/// --- /// -/// As an example, if you have a trait item `type AccountId: SomeTrait;` in your `Config` trait, -/// the generated `DefaultConfig` will only have `type AccountId;` with no trait bound. +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::no_default_bounds`. #[proc_macro_attribute] pub fn no_default_bounds(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -923,6 +780,11 @@ pub fn register_default_impl(attrs: TokenStream, tokens: TokenStream) -> TokenSt } } +/// +/// --- +/// +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_prelude::inject_runtime_type`. #[proc_macro_attribute] pub fn inject_runtime_type(_: TokenStream, tokens: TokenStream) -> TokenStream { let item = tokens.clone(); @@ -956,75 +818,11 @@ fn pallet_macro_stub() -> TokenStream { .into() } -/// The mandatory attribute `#[pallet::config]` defines the configurable options for the pallet. -/// -/// Item must be defined as: -/// -/// ```ignore -/// #[pallet::config] -/// pub trait Config: frame_system::Config + $optionally_some_other_supertraits -/// $optional_where_clause -/// { -/// ... -/// } -/// ``` -/// -/// I.e. a regular trait definition named `Config`, with the supertrait -/// `frame_system::pallet::Config`, and optionally other supertraits and a where clause. -/// (Specifying other supertraits here is known as [tight -/// coupling](https://docs.substrate.io/reference/how-to-guides/pallet-design/use-tight-coupling/)) -/// -/// The associated type `RuntimeEvent` is reserved. If defined, it must have the bounds -/// `From` and `IsType<::RuntimeEvent>`. /// -/// [`pallet::event`](`macro@event`) must be present if `RuntimeEvent` exists as a config item -/// in your `#[pallet::config]`. -/// -/// ## Optional: `with_default` -/// -/// An optional `with_default` argument may also be specified. Doing so will automatically -/// generate a `DefaultConfig` trait inside your pallet which is suitable for use with -/// [`[#[derive_impl(..)]`](`macro@derive_impl`) to derive a default testing config: -/// -/// ```ignore -/// #[pallet::config(with_default)] -/// pub trait Config: frame_system::Config { -/// type RuntimeEvent: Parameter -/// + Member -/// + From> -/// + Debug -/// + IsType<::RuntimeEvent>; -/// -/// #[pallet::no_default] -/// type BaseCallFilter: Contains; -/// // ... -/// } -/// ``` -/// -/// As shown above, you may also attach the [`#[pallet::no_default]`](`macro@no_default`) -/// attribute to specify that a particular trait item _cannot_ be used as a default when a test -/// `Config` is derived using the [`#[derive_impl(..)]`](`macro@derive_impl`) attribute macro. -/// This will cause that particular trait item to simply not appear in default testing configs -/// based on this config (the trait item will not be included in `DefaultConfig`). -/// -/// ### `DefaultConfig` Caveats -/// -/// The auto-generated `DefaultConfig` trait: -/// - is always a _subset_ of your pallet's `Config` trait. -/// - can only contain items that don't rely on externalities, such as `frame_system::Config`. -/// -/// Trait items that _do_ rely on externalities should be marked with -/// [`#[pallet::no_default]`](`macro@no_default`) -/// -/// Consequently: -/// - Any items that rely on externalities _must_ be marked with -/// [`#[pallet::no_default]`](`macro@no_default`) or your trait will fail to compile when used -/// with [`derive_impl`](`macro@derive_impl`). -/// - Items marked with [`#[pallet::no_default]`](`macro@no_default`) are entirely excluded from the -/// `DefaultConfig` trait, and therefore any impl of `DefaultConfig` doesn't need to implement -/// such items. +/// --- /// -/// For more information, see [`macro@derive_impl`]. +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::config`. #[proc_macro_attribute] pub fn config(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -1033,7 +831,7 @@ pub fn config(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// **Rust-Analyzer users**: See the documentation of the Rust item in +/// Rust-Analyzer Users: Documentation for this macro can be found at /// `frame_support::pallet_macros::constant`. #[proc_macro_attribute] pub fn constant(_: TokenStream, _: TokenStream) -> TokenStream { @@ -1043,106 +841,58 @@ pub fn constant(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// **Rust-Analyzer users**: See the documentation of the Rust item in +/// Rust-Analyzer Users: Documentation for this macro can be found at /// `frame_support::pallet_macros::constant_name`. #[proc_macro_attribute] pub fn constant_name(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// To bypass the `frame_system::Config` supertrait check, use the attribute -/// `pallet::disable_frame_system_supertrait_check`, e.g.: /// -/// ```ignore -/// #[pallet::config] -/// #[pallet::disable_frame_system_supertrait_check] -/// pub trait Config: pallet_timestamp::Config {} -/// ``` +/// --- /// -/// NOTE: Bypassing the `frame_system::Config` supertrait check is typically desirable when you -/// want to write an alternative to the `frame_system` pallet. +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::disable_frame_system_supertrait_check`. #[proc_macro_attribute] pub fn disable_frame_system_supertrait_check(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// To generate a `Store` trait associating all storages, annotate your `Pallet` struct with -/// the attribute `#[pallet::generate_store($vis trait Store)]`, e.g.: -/// -/// ```ignore -/// #[pallet::pallet] -/// #[pallet::generate_store(pub(super) trait Store)] -/// pub struct Pallet(_); -/// ``` -/// More precisely, the `Store` trait contains an associated type for each storage. It is -/// implemented for `Pallet` allowing access to the storage from pallet struct. /// -/// Thus when defining a storage named `Foo`, it can later be accessed from `Pallet` using -/// `::Foo`. +/// --- /// -/// NOTE: this attribute is only valid when applied _directly_ to your `Pallet` struct -/// definition. +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::generate_store`. #[proc_macro_attribute] pub fn generate_store(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// Because the `pallet::pallet` macro implements `GetStorageVersion`, the current storage -/// version needs to be communicated to the macro. This can be done by using the -/// `pallet::storage_version` attribute: -/// -/// ```ignore -/// const STORAGE_VERSION: StorageVersion = StorageVersion::new(5); /// -/// #[pallet::pallet] -/// #[pallet::storage_version(STORAGE_VERSION)] -/// pub struct Pallet(_); -/// ``` +/// --- /// -/// If not present, the in-code storage version is set to the default value. +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::storage_version`. #[proc_macro_attribute] pub fn storage_version(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// The `#[pallet::hooks]` attribute allows you to specify a `Hooks` implementation for -/// `Pallet` that specifies pallet-specific logic. /// -/// The item the attribute attaches to must be defined as follows: -/// ```ignore -/// #[pallet::hooks] -/// impl Hooks> for Pallet $optional_where_clause { -/// ... -/// } -/// ``` -/// I.e. a regular trait implementation with generic bound: `T: Config`, for the trait -/// `Hooks>` (they are defined in preludes), for the type `Pallet` and -/// with an optional where clause. -/// -/// If no `#[pallet::hooks]` exists, then the following default implementation is -/// automatically generated: -/// ```ignore -/// #[pallet::hooks] -/// impl Hooks> for Pallet {} -/// ``` -/// -/// ## Macro expansion -/// -/// The macro implements the traits `OnInitialize`, `OnIdle`, `OnFinalize`, `OnRuntimeUpgrade`, -/// `OffchainWorker`, and `IntegrityTest` using the provided `Hooks` implementation. -/// -/// NOTE: `OnRuntimeUpgrade` is implemented with `Hooks::on_runtime_upgrade` and some -/// additional logic. E.g. logic to write the pallet version into storage. +/// --- /// -/// NOTE: The macro also adds some tracing logic when implementing the above traits. The -/// following hooks emit traces: `on_initialize`, `on_finalize` and `on_runtime_upgrade`. +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::hooks`. #[proc_macro_attribute] pub fn hooks(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// Each dispatchable needs to define a weight with `#[pallet::weight($expr)]` attribute, the -/// first argument must be `origin: OriginFor`. +/// +/// --- +/// +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::weight`. #[proc_macro_attribute] pub fn weight(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -1151,8 +901,8 @@ pub fn weight(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// **Rust-Analyzer users**: See the documentation of the Rust item in -/// [`frame_support::pallet_macros::call`](../../frame_support/pallet_macros/attr.call.html). +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::compact`. #[proc_macro_attribute] pub fn compact(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -1161,8 +911,8 @@ pub fn compact(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// **Rust-Analyzer users**: See the documentation of the Rust item in -/// [`frame_support::pallet_macros::call`](../../frame_support/pallet_macros/attr.call.html). +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::call`. #[proc_macro_attribute] pub fn call(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -1173,164 +923,60 @@ pub fn call(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// **Rust-Analyzer users**: See the documentation of the Rust item in -/// [`frame_support::pallet_macros::call`](../../frame_support/pallet_macros/attr.call.html). +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::call_index`. #[proc_macro_attribute] pub fn call_index(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// Each dispatchable may be annotated with the `#[pallet::feeless_if($closure)]` attribute, -/// which explicitly defines the condition for the dispatchable to be feeless. -/// -/// The arguments for the closure must be the referenced arguments of the dispatchable function. -/// -/// The closure must return `bool`. -/// -/// ### Example -/// ```ignore -/// #[pallet::feeless_if(|_origin: &OriginFor, something: &u32| -> bool { -/// *something == 0 -/// })] -/// pub fn do_something(origin: OriginFor, something: u32) -> DispatchResult { -/// .... -/// } -/// ``` /// -/// Please note that this only works for signed dispatchables and requires a signed extension -/// such as `SkipCheckIfFeeless` as defined in `pallet-skip-feeless-payment` to wrap the existing -/// payment extension. Else, this is completely ignored and the dispatchable is still charged. +/// --- /// -/// ### Macro expansion +/// Rust-Analyzer Users: Documentation for this macro can be found at /// -/// The macro implements the `CheckIfFeeless` trait on the dispatchable and calls the corresponding -/// closure in the implementation. +/// `frame_support::pallet_macros::feeless_if`. #[proc_macro_attribute] pub fn feeless_if(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// Allows you to define some extra constants to be added into constant metadata. /// -/// Item must be defined as: -/// -/// ```ignore -/// #[pallet::extra_constants] -/// impl Pallet where $optional_where_clause { -/// /// $some_doc -/// $vis fn $fn_name() -> $some_return_type { -/// ... -/// } -/// ... -/// } -/// ``` -/// I.e. a regular rust `impl` block with some optional where clause and functions with 0 args, -/// 0 generics, and some return type. +/// --- /// -/// ## Macro expansion +/// Rust-Analyzer Users: Documentation for this macro can be found at /// -/// The macro add some extra constants to pallet constant metadata. +/// `frame_support::pallet_macros::extra_constants`. #[proc_macro_attribute] pub fn extra_constants(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// The `#[pallet::error]` attribute allows you to define an error enum that will be returned -/// from the dispatchable when an error occurs. The information for this error type is then -/// stored in metadata. -/// -/// Item must be defined as: -/// -/// ```ignore -/// #[pallet::error] -/// pub enum Error { -/// /// $some_optional_doc -/// $SomeFieldLessVariant, -/// /// $some_more_optional_doc -/// $SomeVariantWithOneField(FieldType), -/// ... -/// } -/// ``` -/// I.e. a regular enum named `Error`, with generic `T` and fieldless or multiple-field -/// variants. /// -/// Any field type in the enum variants must implement `TypeInfo` in order to be properly used -/// in the metadata, and its encoded size should be as small as possible, preferably 1 byte in -/// size in order to reduce storage size. The error enum itself has an absolute maximum encoded -/// size specified by `MAX_MODULE_ERROR_ENCODED_SIZE`. -/// -/// (1 byte can still be 256 different errors. The more specific the error, the easier it is to -/// diagnose problems and give a better experience to the user. Don't skimp on having lots of -/// individual error conditions.) -/// -/// Field types in enum variants must also implement `PalletError`, otherwise the pallet will -/// fail to compile. Rust primitive types have already implemented the `PalletError` trait -/// along with some commonly used stdlib types such as [`Option`] and `PhantomData`, and hence -/// in most use cases, a manual implementation is not necessary and is discouraged. -/// -/// The generic `T` must not bound anything and a `where` clause is not allowed. That said, -/// bounds and/or a where clause should not needed for any use-case. -/// -/// ## Macro expansion -/// -/// The macro implements the [`Debug`] trait and functions `as_u8` using variant position, and -/// `as_str` using variant doc. +/// --- /// -/// The macro also implements `From>` for `&'static str` and `From>` for -/// `DispatchError`. +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::error`. #[proc_macro_attribute] pub fn error(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// The `#[pallet::event]` attribute allows you to define pallet events. Pallet events are -/// stored under the `system` / `events` key when the block is applied (and then replaced when -/// the next block writes it's events). /// -/// The Event enum must be defined as follows: -/// -/// ```ignore -/// #[pallet::event] -/// #[pallet::generate_deposit($visibility fn deposit_event)] // Optional -/// pub enum Event<$some_generic> $optional_where_clause { -/// /// Some doc -/// $SomeName($SomeType, $YetanotherType, ...), -/// ... -/// } -/// ``` -/// -/// I.e. an enum (with named or unnamed fields variant), named `Event`, with generic: none or -/// `T` or `T: Config`, and optional w here clause. +/// --- /// -/// Each field must implement [`Clone`], [`Eq`], [`PartialEq`], `Encode`, `Decode`, and -/// [`Debug`] (on std only). For ease of use, bound by the trait `Member`, available in -/// `frame_support::pallet_prelude`. +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::event`. #[proc_macro_attribute] pub fn event(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// The attribute `#[pallet::generate_deposit($visibility fn deposit_event)]` generates a -/// helper function on `Pallet` that handles deposit events. /// -/// NOTE: For instantiable pallets, the event must be generic over `T` and `I`. -/// -/// ## Macro expansion -/// -/// The macro will add on enum `Event` the attributes: -/// * `#[derive(frame_support::CloneNoBound)]` -/// * `#[derive(frame_support::EqNoBound)]` -/// * `#[derive(frame_support::PartialEqNoBound)]` -/// * `#[derive(frame_support::RuntimeDebugNoBound)]` -/// * `#[derive(codec::Encode)]` -/// * `#[derive(codec::Decode)]` -/// -/// The macro implements `From>` for (). -/// -/// The macro implements a metadata function on `Event` returning the `EventMetadata`. +/// --- /// -/// If `#[pallet::generate_deposit]` is present then the macro implements `fn deposit_event` on -/// `Pallet`. +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::generate_deposit`. #[proc_macro_attribute] pub fn generate_deposit(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -1339,124 +985,68 @@ pub fn generate_deposit(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// **Rust-Analyzer users**: See the documentation of the Rust item in +/// Rust-Analyzer Users: Documentation for this macro can be found at /// `frame_support::pallet_macros::storage`. #[proc_macro_attribute] pub fn storage(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// The optional attribute `#[pallet::getter(fn $my_getter_fn_name)]` allows you to define a -/// getter function on `Pallet`. /// -/// Also see [`pallet::storage`](`macro@storage`) +/// --- +/// +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::getter`. #[proc_macro_attribute] pub fn getter(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// The optional attribute `#[pallet::storage_prefix = "SomeName"]` allows you to define the -/// storage prefix to use. This is helpful if you wish to rename the storage field but don't -/// want to perform a migration. -/// -/// E.g: /// -/// ```ignore -/// #[pallet::storage] -/// #[pallet::storage_prefix = "foo"] -/// #[pallet::getter(fn my_storage)] -/// pub(super) type MyStorage = StorageMap; -/// ``` -/// -/// or +/// --- /// -/// ```ignore -/// #[pallet::storage] -/// #[pallet::getter(fn my_storage)] -/// pub(super) type MyStorage = StorageMap<_, Blake2_128Concat, u32, u32>; -/// ``` +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::storage_prefix`. #[proc_macro_attribute] pub fn storage_prefix(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// The optional attribute `#[pallet::unbounded]` declares the storage as unbounded. When -/// implementating the storage info (when `#[pallet::generate_storage_info]` is specified on -/// the pallet struct placeholder), the size of the storage will be declared as unbounded. This -/// can be useful for storage which can never go into PoV (Proof of Validity). +/// +/// --- +/// +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::unbounded`. #[proc_macro_attribute] pub fn unbounded(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// The optional attribute `#[pallet::whitelist_storage]` will declare the -/// storage as whitelisted from benchmarking. Doing so will exclude reads of -/// that value's storage key from counting towards weight calculations during -/// benchmarking. -/// -/// This attribute should only be attached to storages that are known to be -/// read/used in every block. This will result in a more accurate benchmarking weight. /// -/// ### Example -/// ```ignore -/// #[pallet::storage] -/// #[pallet::whitelist_storage] -/// pub(super) type Number = StorageValue<_, frame_system::pallet_prelude::BlockNumberFor::, ValueQuery>; -/// ``` +/// --- /// -/// NOTE: As with all `pallet::*` attributes, this one _must_ be written as -/// `#[pallet::whitelist_storage]` and can only be placed inside a `pallet` module in order for -/// it to work properly. +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::whitelist_storage`. #[proc_macro_attribute] pub fn whitelist_storage(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// The optional attribute `#[pallet::disable_try_decode_storage]` will declare the -/// storage as whitelisted from decoding during try-runtime checks. This should only be -/// attached to transient storage which cannot be migrated during runtime upgrades. /// -/// ### Example -/// ```ignore -/// #[pallet::storage] -/// #[pallet::disable_try_decode_storage] -/// pub(super) type Events = StorageValue<_, Vec>>, ValueQuery>; -/// ``` +/// --- /// -/// NOTE: As with all `pallet::*` attributes, this one _must_ be written as -/// `#[pallet::disable_try_decode_storage]` and can only be placed inside a `pallet` module in order -/// for it to work properly. +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::disable_try_decode_storage`. #[proc_macro_attribute] pub fn disable_try_decode_storage(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// The `#[pallet::type_value]` attribute lets you define a struct implementing the `Get` trait -/// to ease the use of storage types. This attribute is meant to be used alongside -/// [`#[pallet::storage]`](`macro@storage`) to define a storage's default value. This attribute -/// can be used multiple times. -/// -/// Item must be defined as: -/// -/// ```ignore -/// #[pallet::type_value] -/// fn $MyDefaultName<$some_generic>() -> $default_type $optional_where_clause { $expr } -/// ``` -/// -/// I.e.: a function definition with generics none or `T: Config` and a returned type. -/// -/// E.g.: -/// -/// ```ignore -/// #[pallet::type_value] -/// fn MyDefault() -> T::Balance { 3.into() } -/// ``` /// -/// ## Macro expansion +/// --- /// -/// The macro renames the function to some internal name, generates a struct with the original -/// name of the function and its generic, and implements `Get<$ReturnType>` by calling the user -/// defined function. +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::type_value`. #[proc_macro_attribute] pub fn type_value(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -1465,7 +1055,7 @@ pub fn type_value(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// **Rust-Analyzer users**: See the documentation of the Rust item in +/// Rust-Analyzer Users: Documentation for this macro can be found at /// `frame_support::pallet_macros::genesis_config`. #[proc_macro_attribute] pub fn genesis_config(_: TokenStream, _: TokenStream) -> TokenStream { @@ -1475,66 +1065,28 @@ pub fn genesis_config(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// **Rust-Analyzer users**: See the documentation of the Rust item in +/// Rust-Analyzer Users: Documentation for this macro can be found at /// `frame_support::pallet_macros::genesis_build`. #[proc_macro_attribute] pub fn genesis_build(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// The `#[pallet::inherent]` attribute allows the pallet to provide some -/// [inherent](https://docs.substrate.io/fundamentals/transaction-types/#inherent-transactions). -/// An inherent is some piece of data that is inserted by a block authoring node at block -/// creation time and can either be accepted or rejected by validators based on whether the -/// data falls within an acceptable range. -/// -/// The most common inherent is the `timestamp` that is inserted into every block. Since there -/// is no way to validate timestamps, validators simply check that the timestamp reported by -/// the block authoring node falls within an acceptable range. /// -/// Item must be defined as: -/// -/// ```ignore -/// #[pallet::inherent] -/// impl ProvideInherent for Pallet { -/// // ... regular trait implementation -/// } -/// ``` -/// -/// I.e. a trait implementation with bound `T: Config`, of trait `ProvideInherent` for type -/// `Pallet`, and some optional where clause. -/// -/// ## Macro expansion +/// --- /// -/// The macro currently makes no use of this information, but it might use this information in -/// the future to give information directly to `construct_runtime`. +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::inherent`. #[proc_macro_attribute] pub fn inherent(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// The `#[pallet::validate_unsigned]` attribute allows the pallet to validate some unsigned -/// transaction: -/// -/// Item must be defined as: -/// -/// ```ignore -/// #[pallet::validate_unsigned] -/// impl ValidateUnsigned for Pallet { -/// // ... regular trait implementation -/// } -/// ``` -/// -/// I.e. a trait implementation with bound `T: Config`, of trait `ValidateUnsigned` for type -/// `Pallet`, and some optional where clause. /// -/// NOTE: There is also the `sp_runtime::traits::SignedExtension` trait that can be used to add -/// some specific logic for transaction validation. -/// -/// ## Macro expansion +/// --- /// -/// The macro currently makes no use of this information, but it might use this information in -/// the future to give information directly to `construct_runtime`. +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::validate_unsigned`. #[proc_macro_attribute] pub fn validate_unsigned(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -1543,36 +1095,18 @@ pub fn validate_unsigned(_: TokenStream, _: TokenStream) -> TokenStream { /// /// --- /// -/// **Rust-Analyzer users**: See the documentation of the Rust item in +/// Rust-Analyzer Users: Documentation for this macro can be found at /// `frame_support::pallet_macros::origin`. #[proc_macro_attribute] pub fn origin(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// The `#[pallet::composite_enum]` attribute allows you to define an enum that gets composed as an -/// aggregate enum by `construct_runtime`. This is similar in principle with `#[pallet::event]` and -/// `#[pallet::error]`. /// -/// The attribute currently only supports enum definitions, and identifiers that are named -/// `FreezeReason`, `HoldReason`, `LockId` or `SlashReason`. Arbitrary identifiers for the enum are -/// not supported. The aggregate enum generated by `construct_runtime` will have the name of -/// `RuntimeFreezeReason`, `RuntimeHoldReason`, `RuntimeLockId` and `RuntimeSlashReason` -/// respectively. -/// -/// NOTE: The aggregate enum generated by `construct_runtime` generates a conversion function from -/// the pallet enum to the aggregate enum, and automatically derives the following traits: -/// -/// ```ignore -/// Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, MaxEncodedLen, TypeInfo, -/// RuntimeDebug -/// ``` +/// --- /// -/// For ease of usage, when no `#[derive]` attributes are found for the enum under -/// `#[pallet::composite_enum]`, the aforementioned traits are automatically derived for it. The -/// inverse is also true: if there are any `#[derive]` attributes found for the enum, then no traits -/// will automatically be derived for it (this implies that you need to provide the -/// `frame_support::traits::VariantCount` implementation). +/// Rust-Analyzer Users: Documentation for this macro can be found at +/// `frame_support::pallet_macros::composite_enum`. #[proc_macro_attribute] pub fn composite_enum(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() @@ -1628,25 +1162,11 @@ pub fn task_index(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// Can be attached to a module. Doing so will declare that module as importable into a pallet -/// via [`#[import_section]`](`macro@import_section`). -/// -/// Note that sections are imported by their module name/ident, and should be referred to by -/// their _full path_ from the perspective of the target pallet. Do not attempt to make use -/// of `use` statements to bring pallet sections into scope, as this will not work (unless -/// you do so as part of a wildcard import, in which case it will work). -/// -/// ## Naming Logistics /// -/// Also note that because of how `#[pallet_section]` works, pallet section names must be -/// globally unique _within the crate in which they are defined_. For more information on -/// why this must be the case, see macro_magic's -/// [`#[export_tokens]`](https://docs.rs/macro_magic/latest/macro_magic/attr.export_tokens.html) macro. +/// --- /// -/// Optionally, you may provide an argument to `#[pallet_section]` such as -/// `#[pallet_section(some_ident)]`, in the event that there is another pallet section in -/// same crate with the same ident/name. The ident you specify can then be used instead of -/// the module's ident name when you go to import it via `#[import_section]`. +/// **Rust-Analyzer users**: See the documentation of the Rust item in +/// `frame_support::pallet_macros::pallet_section`. #[proc_macro_attribute] pub fn pallet_section(attr: TokenStream, tokens: TokenStream) -> TokenStream { let tokens_clone = tokens.clone(); @@ -1660,39 +1180,11 @@ pub fn pallet_section(attr: TokenStream, tokens: TokenStream) -> TokenStream { } } -/// An attribute macro that can be attached to a module declaration. Doing so will -/// Imports the contents of the specified external pallet section that was defined -/// previously using [`#[pallet_section]`](`macro@pallet_section`). /// -/// ## Example -/// ```ignore -/// #[import_section(some_section)] -/// #[pallet] -/// pub mod pallet { -/// // ... -/// } -/// ``` -/// where `some_section` was defined elsewhere via: -/// ```ignore -/// #[pallet_section] -/// pub mod some_section { -/// // ... -/// } -/// ``` -/// -/// This will result in the contents of `some_section` being _verbatim_ imported into -/// the pallet above. Note that since the tokens for `some_section` are essentially -/// copy-pasted into the target pallet, you cannot refer to imports that don't also -/// exist in the target pallet, but this is easily resolved by including all relevant -/// `use` statements within your pallet section, so they are imported as well, or by -/// otherwise ensuring that you have the same imports on the target pallet. -/// -/// It is perfectly permissible to import multiple pallet sections into the same pallet, -/// which can be done by having multiple `#[import_section(something)]` attributes -/// attached to the pallet. +/// --- /// -/// Note that sections are imported by their module name/ident, and should be referred to by -/// their _full path_ from the perspective of the target pallet. +/// **Rust-Analyzer users**: See the documentation of the Rust item in +/// `frame_support::pallet_macros::import_section`. #[import_tokens_attr { format!( "{}::macro_magic", diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs index d2d9a33053f..caf9457d666 100644 --- a/substrate/frame/support/src/lib.rs +++ b/substrate/frame/support/src/lib.rs @@ -900,18 +900,20 @@ pub mod pallet_prelude { }; pub use codec::{Decode, Encode, MaxEncodedLen}; pub use frame_support::pallet_macros::*; + /// The optional attribute `#[inject_runtime_type]` can be attached to `RuntimeCall`, /// `RuntimeEvent`, `RuntimeOrigin` or `PalletInfo` in an impl statement that has /// `#[register_default_impl]` attached to indicate that this item is generated by /// `construct_runtime`. /// /// Attaching this attribute to such an item ensures that the combined impl generated via - /// [`#[derive_impl(..)]`](`macro@super::derive_impl`) will use the correct type - /// auto-generated by `construct_runtime!`. + /// [`#[derive_impl(..)]`](`frame_support::derive_impl`) will use the correct + /// type auto-generated by + /// `construct_runtime!`. #[doc = docify::embed!("src/tests/inject_runtime_type.rs", derive_impl_works_with_runtime_type_injection)] /// /// However, if `no_aggregated_types` is specified while using - /// `[`#[derive_impl(..)]`](`macro@super::derive_impl`)`, then these items are attached + /// `[`#[derive_impl(..)]`](`frame_support::derive_impl`)`, then these items are attached /// verbatim to the combined impl. #[doc = docify::embed!("src/tests/inject_runtime_type.rs", derive_impl_works_with_no_aggregated_types)] pub use frame_support_procedural::inject_runtime_type; @@ -931,130 +933,26 @@ pub mod pallet_prelude { pub use sp_weights::Weight; } -/// The `pallet` attribute macro defines a pallet that can be used with -/// [`construct_runtime!`]. It must be attached to a module named `pallet` as follows: +/// The pallet struct placeholder `#[pallet::pallet]` is mandatory and allows you to +/// specify pallet information. /// -/// ```ignore -/// #[pallet] -/// pub mod pallet { -/// ... -/// } +/// The struct must be defined as follows: /// ``` +/// #[frame_support::pallet] +/// mod pallet { +/// #[pallet::pallet] // <- the macro +/// pub struct Pallet(_); // <- the struct definition /// -/// Note that various types can be automatically imported using -/// [`frame_support::pallet_prelude`] and `frame_system::pallet_prelude`: -/// -/// ```ignore -/// #[pallet] -/// pub mod pallet { -/// use frame_support::pallet_prelude::*; -/// use frame_system::pallet_prelude::*; -/// ... +/// #[pallet::config] +/// pub trait Config: frame_system::Config {} /// } /// ``` /// -/// # pallet::* Attributes -/// -/// The `pallet` macro will parse any items within your `pallet` module that are annotated with -/// `#[pallet::*]` attributes. Some of these attributes are mandatory and some are optional, -/// and they can attach to different types of items within your pallet depending on the -/// attribute in question. The full list of `#[pallet::*]` attributes is shown below in the -/// order in which they are mentioned in this document: -/// -/// * [`pallet::pallet`](#pallet-struct-placeholder-palletpallet-mandatory) -/// * [`pallet::config`](#config-trait-palletconfig-mandatory) -/// * [`pallet::constant`](#palletconstant) -/// * [`pallet::disable_frame_system_supertrait_check`](#disable_supertrait_check) -/// * [`pallet::generate_store($vis trait Store)`](#palletgenerate_storevis-trait-store) -/// * [`pallet::storage_version`](#palletstorage_version) -/// * [`pallet::hooks`](#hooks-pallethooks-optional) -/// * [`pallet::call`](#call-palletcall-optional) -/// * [`pallet::weight($expr)`](#palletweightexpr) -/// * [`pallet::compact`](#palletcompact-some_arg-some_type) -/// * [`pallet::call_index($idx)`](#palletcall_indexidx) -/// * [`pallet::extra_constants`](#extra-constants-palletextra_constants-optional) -/// * [`pallet::error`](#error-palleterror-optional) -/// * [`pallet::event`](#event-palletevent-optional) -/// * [`pallet::generate_deposit($visibility fn -/// deposit_event)`](#palletgenerate_depositvisibility-fn-deposit_event) -/// * [`pallet::storage`](#storage-palletstorage-optional) -/// * [`pallet::getter(fn $my_getter_fn_name)`](#palletgetterfn-my_getter_fn_name-optional) -/// * [`pallet::storage_prefix = "SomeName"`](#palletstorage_prefix--somename-optional) -/// * [`pallet::unbounded`](#palletunbounded-optional) -/// * [`pallet::whitelist_storage`](#palletwhitelist_storage-optional) -/// * [`pallet::disable_try_decode_storage`](#palletdisable_try_decode_storage-optional) -/// * [`cfg(..)`](#cfg-for-storage) (on storage items) -/// * [`pallet::type_value`](#type-value-pallettype_value-optional) -/// * [`pallet::genesis_config`](#genesis-config-palletgenesis_config-optional) -/// * [`pallet::genesis_build`](#genesis-build-palletgenesis_build-optional) -/// * [`pallet::inherent`](#inherent-palletinherent-optional) -/// * [`pallet::validate_unsigned`](#validate-unsigned-palletvalidate_unsigned-optional) -/// * [`pallet::origin`](#origin-palletorigin-optional) -/// * [`pallet::composite_enum`](#composite-enum-palletcomposite_enum-optional) -/// -/// Note that at compile-time, the `#[pallet]` macro will analyze and expand all of these -/// attributes, ultimately removing their AST nodes before they can be parsed as real -/// attribute macro calls. This means that technically we do not need attribute macro -/// definitions for any of these attributes, however, for consistency and discoverability -/// reasons, we still maintain stub attribute macro definitions for all of these attributes in -/// the [`pallet_macros`] module which is automatically included in all pallets as part of the -/// pallet prelude. The actual "work" for all of these attribute macros can be found in the -/// macro expansion for `#[pallet]`. -/// -/// Also note that in this document, pallet attributes are explained using the syntax of -/// non-instantiable pallets. For an example of an instantiable pallet, see [this -/// example](#example-of-an-instantiable-pallet). -/// -/// # Dev Mode (`#[pallet(dev_mode)]`) -/// -/// Specifying the argument `dev_mode` on the `#[pallet]` or `#[frame_support::pallet]` -/// attribute attached to your pallet module will allow you to enable dev mode for a pallet. -/// The aim of dev mode is to loosen some of the restrictions and requirements placed on -/// production pallets for easy tinkering and development. Dev mode pallets should not be used -/// in production. Enabling dev mode has the following effects: -/// -/// * Weights no longer need to be specified on every `#[pallet::call]` declaration. By -/// default, dev mode pallets will assume a weight of zero (`0`) if a weight is not -/// specified. This is equivalent to specifying `#[weight(0)]` on all calls that do not -/// specify a weight. -/// * Call indices no longer need to be specified on every `#[pallet::call]` declaration. By -/// default, dev mode pallets will assume a call index based on the order of the call. -/// * All storages are marked as unbounded, meaning you do not need to implement -/// `MaxEncodedLen` on storage types. This is equivalent to specifying `#[pallet::unbounded]` -/// on all storage type definitions. -/// * Storage hashers no longer need to be specified and can be replaced by `_`. In dev mode, -/// these will be replaced by `Blake2_128Concat`. In case of explicit key-binding, `Hasher` -/// can simply be ignored when in `dev_mode`. -/// -/// Note that the `dev_mode` argument can only be supplied to the `#[pallet]` or -/// `#[frame_support::pallet]` attribute macro that encloses your pallet module. This argument -/// cannot be specified anywhere else, including but not limited to the `#[pallet::pallet]` -/// attribute macro. -/// -///
-/// WARNING:
-/// You should not deploy or use dev mode pallets in production. Doing so can break your chain
-/// and therefore should never be done. Once you are done tinkering, you should remove the
-/// 'dev_mode' argument from your #[pallet] declaration and fix any compile errors before
-/// attempting to use your pallet in a production scenario.
-/// 
-/// -/// # Pallet struct placeholder: `#[pallet::pallet]` (mandatory) -/// -/// The pallet struct placeholder `#[pallet::pallet]` is mandatory and allows you to specify -/// pallet information. -/// -/// The struct must be defined as follows: -/// ```ignore -/// #[pallet::pallet] -/// pub struct Pallet(_); -/// ``` /// I.e. a regular struct definition named `Pallet`, with generic T and no where clause. /// /// ## Macro expansion: /// -/// The macro adds this attribute to the struct definition: +/// The macro adds this attribute to the Pallet struct definition: /// ```ignore /// #[derive( /// frame_support::CloneNoBound, @@ -1063,1233 +961,947 @@ pub mod pallet_prelude { /// frame_support::RuntimeDebugNoBound, /// )] /// ``` -/// and replaces the type `_` with `PhantomData`. It also implements on the pallet: -/// * [`GetStorageVersion`](`traits::GetStorageVersion`) -/// * [`OnGenesis`](`traits::OnGenesis`): contains some logic to write the pallet version into -/// storage. -/// * `PalletErrorTypeInfo`: provides the type information for the pallet error, if defined. -/// -/// It declares `type Module` type alias for `Pallet`, used by `construct_runtime`. +/// and replaces the type `_` with `PhantomData`. /// -/// It implements [`PalletInfoAccess`](`traits::PalletInfoAccess') on `Pallet` to ease access -/// to pallet information given by [`frame_support::traits::PalletInfo`]. (The implementation -/// uses the associated type `frame_system::Config::PalletInfo`). +/// It also implements on the pallet: /// -/// It implements [`StorageInfoTrait`](`traits::StorageInfoTrait`) on `Pallet` which give -/// information about all storages. -/// -/// If the attribute `generate_store` is set then the macro creates the trait `Store` and -/// implements it on `Pallet`. +/// * [`GetStorageVersion`](frame_support::traits::GetStorageVersion) +/// * [`OnGenesis`](frame_support::traits::OnGenesis): contains some logic to write the pallet +/// version into storage. +/// * [`PalletInfoAccess`](frame_support::traits::PalletInfoAccess) to ease access to pallet +/// information given by [`frame_support::traits::PalletInfo`]. (The implementation uses the +/// associated type [`frame_support::traits::PalletInfo`]). +/// * [`StorageInfoTrait`](frame_support::traits::StorageInfoTrait) to give information about +/// storages. /// /// If the attribute `set_storage_max_encoded_len` is set then the macro calls -/// [`StorageInfoTrait`](`traits::StorageInfoTrait`) for each storage in the implementation of -/// [`StorageInfoTrait`](`traits::StorageInfoTrait`) for the pallet. Otherwise it implements -/// [`StorageInfoTrait`](`traits::StorageInfoTrait`) for the pallet using the -/// [`PartialStorageInfoTrait`](`traits::PartialStorageInfoTrait`) implementation of storages. -/// -/// # Config trait: `#[pallet::config]` (mandatory) -/// -/// The mandatory attribute `#[pallet::config]` defines the configurable options for the -/// pallet. -/// -/// Item must be defined as: -/// -/// ```ignore -/// #[pallet::config] -/// pub trait Config: frame_system::Config + $optionally_some_other_supertraits -/// $optional_where_clause -/// { -/// ... -/// } -/// ``` -/// -/// I.e. a regular trait definition named `Config`, with the supertrait -/// `frame_system::pallet::Config`, and optionally other supertraits and a where clause. -/// (Specifying other supertraits here is known as [tight -/// coupling](https://docs.substrate.io/reference/how-to-guides/pallet-design/use-tight-coupling/)) -/// -/// The associated type `RuntimeEvent` is reserved. If defined, it must have the bounds -/// `From` and `IsType<::RuntimeEvent>`. -/// -/// [`pallet::event`](`frame_support::pallet_macros::event`) must be present if `RuntimeEvent` -/// exists as a config item in your `#[pallet::config]`. -/// -/// Also see [`pallet::config`](`frame_support::pallet_macros::config`) -/// -/// ## `pallet::constant` -/// -/// The `#[pallet::constant]` attribute can be used to add an associated type trait bounded by -/// [`Get`](crate::traits::Get) from [`pallet::config`](#palletconfig) into metadata, e.g.: +/// [`StorageInfoTrait`](frame_support::traits::StorageInfoTrait) for each storage in the +/// implementation of [`StorageInfoTrait`](frame_support::traits::StorageInfoTrait) for the +/// pallet. Otherwise it implements +/// [`StorageInfoTrait`](frame_support::traits::StorageInfoTrait) for the pallet using the +/// [`PartialStorageInfoTrait`](frame_support::traits::PartialStorageInfoTrait) +/// implementation of storages. /// -/// ```ignore -/// #[pallet::config] -/// pub trait Config: frame_system::Config { -/// #[pallet::constant] -/// type Foo: Get; -/// } -/// ``` -/// -/// Also see [`pallet::constant`](`frame_support::pallet_macros::constant`) -/// -/// ## `pallet::disable_frame_system_supertrait_check` -/// -/// -/// To bypass the `frame_system::Config` supertrait check, use the attribute -/// `pallet::disable_frame_system_supertrait_check`, e.g.: -/// -/// ```ignore -/// #[pallet::config] -/// #[pallet::disable_frame_system_supertrait_check] -/// pub trait Config: pallet_timestamp::Config {} -/// ``` -/// -/// NOTE: Bypassing the `frame_system::Config` supertrait check is typically desirable when you -/// want to write an alternative to the `frame_system` pallet. -/// -/// Also see -/// [`pallet::disable_frame_system_supertrait_check`](`frame_support::pallet_macros::disable_frame_system_supertrait_check`) -/// -/// ## Macro expansion: -/// -/// The macro expands pallet constant metadata with the information given by -/// `#[pallet::constant]`. -/// -/// # `pallet::generate_store($vis trait Store)` -/// -/// To generate a `Store` trait associating all storages, annotate your `Pallet` struct with -/// the attribute `#[pallet::generate_store($vis trait Store)]`, e.g.: -/// -/// ```ignore -/// #[pallet::pallet] -/// #[pallet::generate_store(pub(super) trait Store)] -/// pub struct Pallet(_); -/// ``` -/// More precisely, the `Store` trait contains an associated type for each storage. It is -/// implemented for `Pallet` allowing access to the storage from pallet struct. -/// -/// Thus when defining a storage named `Foo`, it can later be accessed from `Pallet` using -/// `::Foo`. -/// -/// NOTE: this attribute is only valid when applied _directly_ to your `Pallet` struct -/// definition. -/// -/// Also see [`pallet::generate_store`](`frame_support::pallet_macros::generate_store`). -/// -/// # `pallet::storage_version` -/// -/// Because the [`pallet::pallet`](#pallet-struct-placeholder-palletpallet-mandatory) macro -/// implements [`traits::GetStorageVersion`], the in-code storage version needs to be -/// communicated to the macro. This can be done by using the `pallet::storage_version` -/// attribute: -/// -/// ```ignore -/// const STORAGE_VERSION: StorageVersion = StorageVersion::new(5); -/// -/// #[pallet::pallet] -/// #[pallet::storage_version(STORAGE_VERSION)] -/// pub struct Pallet(_); -/// ``` -/// -/// If not present, the in-code storage version is set to the default value. -/// -/// Also see [`pallet::storage_version`](`frame_support::pallet_macros::storage_version`) -/// -/// # Hooks: `#[pallet::hooks]` (optional) -/// -/// The `pallet::hooks` attribute allows you to specify a `Hooks` implementation for `Pallet` -/// that specifies pallet-specific logic. -/// -/// The item the attribute attaches to must be defined as follows: -/// ```ignore -/// #[pallet::hooks] -/// impl Hooks> for Pallet $optional_where_clause { -/// ... -/// } -/// ``` -/// I.e. a regular trait implementation with generic bound: `T: Config`, for the trait -/// `Hooks>` (they are defined in preludes), for the type `Pallet` and -/// with an optional where clause. -/// -/// If no `#[pallet::hooks]` exists, then the following default implementation is -/// automatically generated: -/// ```ignore -/// #[pallet::hooks] -/// impl Hooks> for Pallet {} -/// ``` -/// -/// Also see [`pallet::hooks`](`frame_support::pallet_macros::hooks`) -/// -/// # Call: `#[pallet::call]` (optional) -/// -/// Implementation of pallet dispatchables. -/// -/// Item must be defined as: -/// ```ignore -/// #[pallet::call] -/// impl Pallet { -/// /// $some_doc -/// #[pallet::weight($ExpressionResultingInWeight)] -/// pub fn $fn_name( -/// origin: OriginFor, -/// $some_arg: $some_type, -/// // or with compact attribute: #[pallet::compact] $some_arg: $some_type, -/// ... -/// ) -> DispatchResultWithPostInfo { // or `-> DispatchResult` -/// ... -/// } -/// ... -/// } -/// ``` -/// I.e. a regular type implementation, with generic `T: Config`, on type `Pallet`, with -/// an optional where clause. +/// ## Dev Mode (`#[pallet(dev_mode)]`) /// -/// ## `#[pallet::weight($expr)]` +/// Specifying the argument `dev_mode` will allow you to enable dev mode for a pallet. The +/// aim of dev mode is to loosen some of the restrictions and requirements placed on +/// production pallets for easy tinkering and development. Dev mode pallets should not be +/// used in production. Enabling dev mode has the following effects: /// -/// Each dispatchable needs to define a weight with `#[pallet::weight($expr)]` attribute, the -/// first argument must be `origin: OriginFor`. -/// -/// Also see [`pallet::weight`](`frame_support::pallet_macros::weight`) -/// -/// ### `#[pallet::compact] $some_arg: $some_type` -/// -/// Compact encoding for arguments can be achieved via `#[pallet::compact]`. The function must -/// return a `DispatchResultWithPostInfo` or `DispatchResult`. -/// -/// Also see [`pallet::compact`](`frame_support::pallet_macros::compact`) -/// -/// ## `#[pallet::call_index($idx)]` -/// -/// Each dispatchable may also be annotated with the `#[pallet::call_index($idx)]` attribute, -/// which explicitly defines the codec index for the dispatchable function in the `Call` enum. -/// -/// All call indexes start from 0, until it encounters a dispatchable function with a defined -/// call index. The dispatchable function that lexically follows the function with a defined -/// call index will have that call index, but incremented by 1, e.g. if there are 3 -/// dispatchable functions `fn foo`, `fn bar` and `fn qux` in that order, and only `fn bar` -/// has a call index of 10, then `fn qux` will have an index of 11, instead of 1. -/// -/// **WARNING**: modifying dispatchables, changing their order, removing some, etc., must be -/// done with care. Indeed this will change the outer runtime call type (which is an enum with -/// one variant per pallet), this outer runtime call can be stored on-chain (e.g. in -/// `pallet-scheduler`). Thus migration might be needed. To mitigate against some of this, the -/// `#[pallet::call_index($idx)]` attribute can be used to fix the order of the dispatchable so -/// that the `Call` enum encoding does not change after modification. As a general rule of -/// thumb, it is therefore adventageous to always add new calls to the end so you can maintain -/// the existing order of calls. -/// -/// Also see [`pallet::call_index`](`frame_support::pallet_macros::call_index`) -/// -/// # Extra constants: `#[pallet::extra_constants]` (optional) -/// -/// Allows you to define some extra constants to be added into constant metadata. -/// -/// Item must be defined as: -/// -/// ```ignore -/// #[pallet::extra_constants] -/// impl Pallet where $optional_where_clause { -/// /// $some_doc -/// $vis fn $fn_name() -> $some_return_type { -/// ... -/// } -/// ... -/// } -/// ``` -/// I.e. a regular rust `impl` block with some optional where clause and functions with 0 args, -/// 0 generics, and some return type. -/// -/// ## Macro expansion -/// -/// The macro add some extra constants to pallet constant metadata. -/// -/// Also see: [`pallet::extra_constants`](`frame_support::pallet_macros::extra_constants`) -/// -/// # Error: `#[pallet::error]` (optional) -/// -/// The `#[pallet::error]` attribute allows you to define an error enum that will be returned -/// from the dispatchable when an error occurs. The information for this error type is then -/// stored in metadata. -/// -/// Item must be defined as: -/// -/// ```ignore -/// #[pallet::error] -/// pub enum Error { -/// /// $some_optional_doc -/// $SomeFieldLessVariant, -/// /// $some_more_optional_doc -/// $SomeVariantWithOneField(FieldType), -/// ... -/// } -/// ``` -/// I.e. a regular enum named `Error`, with generic `T` and fieldless or multiple-field -/// variants. -/// -/// Any field type in the enum variants must implement [`scale_info::TypeInfo`] in order to be -/// properly used in the metadata, and its encoded size should be as small as possible, -/// preferably 1 byte in size in order to reduce storage size. The error enum itself has an -/// absolute maximum encoded size specified by [`MAX_MODULE_ERROR_ENCODED_SIZE`]. -/// -/// (1 byte can still be 256 different errors. The more specific the error, the easier it is to -/// diagnose problems and give a better experience to the user. Don't skimp on having lots of -/// individual error conditions.) -/// -/// Field types in enum variants must also implement [`PalletError`](traits::PalletError), -/// otherwise the pallet will fail to compile. Rust primitive types have already implemented -/// the [`PalletError`](traits::PalletError) trait along with some commonly used stdlib types -/// such as [`Option`] and -/// [`PhantomData`](`frame_support::__private::sp_std::marker::PhantomData`), and hence in most -/// use cases, a manual implementation is not necessary and is discouraged. -/// -/// The generic `T` must not bound anything and a `where` clause is not allowed. That said, -/// bounds and/or a where clause should not needed for any use-case. -/// -/// Also see: [`pallet::error`](`frame_support::pallet_macros::error`) -/// -/// # Event: `#[pallet::event]` (optional) -/// -/// Allows you to define pallet events. Pallet events are stored under the `system` / `events` -/// key when the block is applied (and then replaced when the next block writes it's events). -/// -/// The Event enum must be defined as follows: -/// -/// ```ignore -/// #[pallet::event] -/// #[pallet::generate_deposit($visibility fn deposit_event)] // Optional -/// pub enum Event<$some_generic> $optional_where_clause { -/// /// Some doc -/// $SomeName($SomeType, $YetanotherType, ...), -/// ... -/// } -/// ``` -/// -/// I.e. an enum (with named or unnamed fields variant), named `Event`, with generic: none or -/// `T` or `T: Config`, and optional w here clause. -/// -/// Each field must implement [`Clone`], [`Eq`], [`PartialEq`], [`Encode`], [`Decode`], and -/// [`Debug`] (on std only). For ease of use, bound by the trait -/// [`Member`](`frame_support::pallet_prelude::Member`), available in -/// frame_support::pallet_prelude. -/// -/// Also see [`pallet::event`](`frame_support::pallet_macros::event`) -/// -/// ## `#[pallet::generate_deposit($visibility fn deposit_event)]` -/// -/// The attribute `#[pallet::generate_deposit($visibility fn deposit_event)]` generates a -/// helper function on `Pallet` that handles deposit events. -/// -/// NOTE: For instantiable pallets, the event must be generic over `T` and `I`. -/// -/// Also see [`pallet::generate_deposit`](`frame_support::pallet_macros::generate_deposit`) -/// -/// # Storage: `#[pallet::storage]` (optional) -/// -/// The `#[pallet::storage]` attribute lets you define some abstract storage inside of runtime -/// storage and also set its metadata. This attribute can be used multiple times. -/// -/// Item should be defined as: -/// -/// ```ignore -/// #[pallet::storage] -/// #[pallet::getter(fn $getter_name)] // optional -/// $vis type $StorageName<$some_generic> $optional_where_clause -/// = $StorageType<$generic_name = $some_generics, $other_name = $some_other, ...>; -/// ``` -/// -/// or with unnamed generic: -/// -/// ```ignore -/// #[pallet::storage] -/// #[pallet::getter(fn $getter_name)] // optional -/// $vis type $StorageName<$some_generic> $optional_where_clause -/// = $StorageType<_, $some_generics, ...>; -/// ``` -/// -/// I.e. it must be a type alias, with generics: `T` or `T: Config`. The aliased type must be -/// one of [`StorageValue`](`pallet_prelude::StorageValue`), -/// [`StorageMap`](`pallet_prelude::StorageMap`) or -/// [`StorageDoubleMap`](`pallet_prelude::StorageDoubleMap`). The generic arguments of the -/// storage type can be given in two manners: named and unnamed. For named generic arguments, -/// the name for each argument should match the name defined for it on the storage struct: -/// * [`StorageValue`](`pallet_prelude::StorageValue`) expects `Value` and optionally -/// `QueryKind` and `OnEmpty`, -/// * [`StorageMap`](`pallet_prelude::StorageMap`) expects `Hasher`, `Key`, `Value` and -/// optionally `QueryKind` and `OnEmpty`, -/// * [`CountedStorageMap`](`pallet_prelude::CountedStorageMap`) expects `Hasher`, `Key`, -/// `Value` and optionally `QueryKind` and `OnEmpty`, -/// * [`StorageDoubleMap`](`pallet_prelude::StorageDoubleMap`) expects `Hasher1`, `Key1`, -/// `Hasher2`, `Key2`, `Value` and optionally `QueryKind` and `OnEmpty`. -/// -/// For unnamed generic arguments: Their first generic must be `_` as it is replaced by the -/// macro and other generic must declared as a normal generic type declaration. -/// -/// The `Prefix` generic written by the macro is generated using -/// `PalletInfo::name::>()` and the name of the storage type. E.g. if runtime names -/// the pallet "MyExample" then the storage `type Foo = ...` should use the prefix: -/// `Twox128(b"MyExample") ++ Twox128(b"Foo")`. -/// -/// For the [`CountedStorageMap`](`pallet_prelude::CountedStorageMap`) variant, the `Prefix` -/// also implements -/// [`CountedStorageMapInstance`](`frame_support::storage::types::CountedStorageMapInstance`). -/// It also associates a [`CounterPrefix`](`pallet_prelude::CounterPrefix'), which is -/// implemented the same as above, but the storage prefix is prepend with `"CounterFor"`. E.g. -/// if runtime names the pallet "MyExample" then the storage `type Foo = -/// CountedStorageaMap<...>` will store its counter at the prefix: `Twox128(b"MyExample") ++ -/// Twox128(b"CounterForFoo")`. -/// -/// E.g: -/// -/// ```ignore -/// #[pallet::storage] -/// pub(super) type MyStorage = StorageMap; -/// ``` -/// -/// In this case the final prefix used by the map is `Twox128(b"MyExample") ++ -/// Twox128(b"OtherName")`. -/// -/// Also see [`pallet::storage`](`frame_support::pallet_macros::storage`) -/// -/// ## `#[pallet::getter(fn $my_getter_fn_name)]` (optional) -/// -/// The optional attribute `#[pallet::getter(fn $my_getter_fn_name)]` allows you to define a -/// getter function on `Pallet`. -/// -/// Also see [`pallet::getter`](`frame_support::pallet_macros::getter`) -/// -/// ## `#[pallet::storage_prefix = "SomeName"]` (optional) -/// -/// The optional attribute `#[pallet::storage_prefix = "SomeName"]` allows you to define the -/// storage prefix to use, see how `Prefix` generic is implemented above. This is helpful if -/// you wish to rename the storage field but don't want to perform a migration. -/// -/// E.g: -/// -/// ```ignore -/// #[pallet::storage] -/// #[pallet::storage_prefix = "foo"] -/// #[pallet::getter(fn my_storage)] -/// pub(super) type MyStorage = StorageMap; -/// ``` -/// -/// or -/// -/// ```ignore -/// #[pallet::storage] -/// #[pallet::getter(fn my_storage)] -/// pub(super) type MyStorage = StorageMap<_, Blake2_128Concat, u32, u32>; -/// ``` -/// -/// Also see [`pallet::storage_prefix`](`frame_support::pallet_macros::storage_prefix`) -/// -/// ## `#[pallet::unbounded]` (optional) -/// -/// The optional attribute `#[pallet::unbounded]` declares the storage as unbounded. When -/// implementating the storage info (when `#[pallet::generate_storage_info]` is specified on -/// the pallet struct placeholder), the size of the storage will be declared as unbounded. This -/// can be useful for storage which can never go into PoV (Proof of Validity). -/// -/// Also see [`pallet::unbounded`](`frame_support::pallet_macros::unbounded`) -/// -/// ## `#[pallet::whitelist_storage]` (optional) -/// -/// The optional attribute `#[pallet::whitelist_storage]` will declare the storage as -/// whitelisted from benchmarking. -/// -/// See -/// [`pallet::whitelist_storage`](frame_support::pallet_macros::whitelist_storage) -/// for more info. -/// -/// ## `#[pallet::disable_try_decode_storage]` (optional) -/// -/// The optional attribute `#[pallet::disable_try_decode_storage]` will declare the storage as -/// whitelisted state decoding during try-runtime logic. -/// -/// See -/// [`pallet::disable_try_decode_storage`](frame_support::pallet_macros::disable_try_decode_storage) -/// for more info. -/// -/// ## `#[cfg(..)]` (for storage) -/// The optional attributes `#[cfg(..)]` allow conditional compilation for the storage. -/// -/// E.g: -/// -/// ```ignore -/// #[cfg(feature = "my-feature")] -/// #[pallet::storage] -/// pub(super) type MyStorage = StorageValue; -/// ``` -/// -/// All the `cfg` attributes are automatically copied to the items generated for the storage, -/// i.e. the getter, storage prefix, and the metadata element etc. -/// -/// Any type placed as the `QueryKind` parameter must implement -/// [`frame_support::storage::types::QueryKindTrait`]. There are 3 implementations of this -/// trait by default: -/// -/// 1. [`OptionQuery`](`frame_support::storage::types::OptionQuery`), the default `QueryKind` -/// used when this type parameter is omitted. Specifying this as the `QueryKind` would cause -/// storage map APIs that return a `QueryKind` to instead return an [`Option`], returning -/// `Some` when a value does exist under a specified storage key, and `None` otherwise. -/// 2. [`ValueQuery`](`frame_support::storage::types::ValueQuery`) causes storage map APIs that -/// return a `QueryKind` to instead return the value type. In cases where a value does not -/// exist under a specified storage key, the `OnEmpty` type parameter on `QueryKindTrait` is -/// used to return an appropriate value. -/// 3. [`ResultQuery`](`frame_support::storage::types::ResultQuery`) causes storage map APIs -/// that return a `QueryKind` to instead return a `Result`, with `T` being the value -/// type and `E` being the pallet error type specified by the `#[pallet::error]` attribute. -/// In cases where a value does not exist under a specified storage key, an `Err` with the -/// specified pallet error variant is returned. -/// -/// NOTE: If the `QueryKind` generic parameter is still generic at this stage or is using some -/// type alias then the generation of the getter might fail. In this case the getter can be -/// implemented manually. -/// -/// NOTE: The generic `Hasher` must implement the [`StorageHasher`] trait (or the type is not -/// usable at all). We use [`StorageHasher::METADATA`] for the metadata of the hasher of the -/// storage item. Thus generic hasher is supported. -/// -/// ## Macro expansion -/// -/// For each storage item the macro generates a struct named -/// `_GeneratedPrefixForStorage$NameOfStorage`, and implements -/// [`StorageInstance`](traits::StorageInstance) on it using the pallet and storage name. It -/// then uses it as the first generic of the aliased type. For -/// [`CountedStorageMap`](`pallet_prelude::CountedStorageMap`), -/// [`CountedStorageMapInstance`](`frame_support::storage::types::CountedStorageMapInstance`) -/// is implemented, and another similar struct is generated. -/// -/// For a named generic, the macro will reorder the generics, and remove the names. -/// -/// The macro implements the function `storage_metadata` on the `Pallet` implementing the -/// metadata for all storage items based on their kind: -/// * for a storage value, the type of the value is copied into the metadata -/// * for a storage map, the type of the values and the key's type is copied into the metadata -/// * for a storage double map, the type of the values, and the types of `key1` and `key2` are -/// copied into the metadata. -/// -/// # Type value: `#[pallet::type_value]` (optional) -/// -/// The `#[pallet::type_value]` attribute lets you define a struct implementing the -/// [`Get`](crate::traits::Get) trait to ease use of storage types. This attribute is meant to -/// be used alongside [`#[pallet::storage]`](#storage-palletstorage-optional) to define a -/// storage's default value. This attribute can be used multiple times. -/// -/// Item must be defined as: -/// -/// ```ignore -/// #[pallet::type_value] -/// fn $MyDefaultName<$some_generic>() -> $default_type $optional_where_clause { $expr } -/// ``` -/// -/// I.e.: a function definition with generics none or `T: Config` and a returned type. -/// -/// E.g.: -/// -/// ```ignore -/// #[pallet::type_value] -/// fn MyDefault() -> T::Balance { 3.into() } -/// ``` -/// -/// Also see [`pallet::type_value`](`frame_support::pallet_macros::type_value`) -/// -/// # Genesis config: `#[pallet::genesis_config]` (optional) -/// -/// The `#[pallet::genesis_config]` attribute allows you to define the genesis configuration -/// for the pallet. -/// -/// Item is defined as either an enum or a struct. It needs to be public and implement the -/// trait [`BuildGenesisConfig`](`traits::BuildGenesisConfig`) with -/// [`#[pallet::genesis_build]`](#genesis-build-palletgenesis_build-optional). The type -/// generics are constrained to be either none, or `T` or `T: Config`. -/// -/// E.g: -/// -/// ```ignore -/// #[pallet::genesis_config] -/// pub struct GenesisConfig { -/// _myfield: BalanceOf, -/// } -/// ``` -/// -/// Also see [`pallet::genesis_config`](`frame_support::pallet_macros::genesis_config`) -/// -/// # Genesis build: `#[pallet::genesis_build]` (optional) -/// -/// The `#[pallet::genesis_build]` attribute allows you to define how `genesis_configuration` -/// is built. This takes as input the `GenesisConfig` type (as `self`) and constructs the -/// pallet's initial state. -/// -/// The impl must be defined as: -/// -/// ```ignore -/// #[pallet::genesis_build] -/// impl GenesisBuild for GenesisConfig<$maybe_generics> { -/// fn build(&self) { $expr } -/// } -/// ``` -/// -/// I.e. a trait implementation with generic `T: Config`, of trait `GenesisBuild` on -/// type `GenesisConfig` with generics none or `T`. -/// -/// E.g.: -/// -/// ```ignore -/// #[pallet::genesis_build] -/// impl GenesisBuild for GenesisConfig { -/// fn build(&self) {} -/// } -/// ``` -/// -/// Also see [`pallet::genesis_build`](`frame_support::pallet_macros::genesis_build`) -/// -/// # Inherent: `#[pallet::inherent]` (optional) -/// -/// The `#[pallet::inherent]` attribute allows the pallet to provide some -/// [inherent](https://docs.substrate.io/fundamentals/transaction-types/#inherent-transactions). -/// An inherent is some piece of data that is inserted by a block authoring node at block -/// creation time and can either be accepted or rejected by validators based on whether the -/// data falls within an acceptable range. -/// -/// The most common inherent is the `timestamp` that is inserted into every block. Since there -/// is no way to validate timestamps, validators simply check that the timestamp reported by -/// the block authoring node falls within an acceptable range. -/// -/// Item must be defined as: -/// -/// ```ignore -/// #[pallet::inherent] -/// impl ProvideInherent for Pallet { -/// // ... regular trait implementation -/// } -/// ``` -/// -/// I.e. a trait implementation with bound `T: Config`, of trait -/// [`ProvideInherent`](`pallet_prelude::ProvideInherent`) for type `Pallet`, and some -/// optional where clause. -/// -/// Also see [`pallet::inherent`](`frame_support::pallet_macros::inherent`) -/// -/// # Validate unsigned: `#[pallet::validate_unsigned]` (optional) -/// -/// The `#[pallet::validate_unsigned]` attribute allows the pallet to validate some unsigned -/// transaction: -/// -/// Item must be defined as: -/// -/// ```ignore -/// #[pallet::validate_unsigned] -/// impl ValidateUnsigned for Pallet { -/// // ... regular trait implementation -/// } -/// ``` -/// -/// I.e. a trait implementation with bound `T: Config`, of trait -/// [`ValidateUnsigned`](`pallet_prelude::ValidateUnsigned`) for type `Pallet`, and some -/// optional where clause. -/// -/// NOTE: There is also the [`sp_runtime::traits::SignedExtension`] trait that can be used to -/// add some specific logic for transaction validation. -/// -/// Also see [`pallet::validate_unsigned`](`frame_support::pallet_macros::validate_unsigned`) -/// -/// # Origin: `#[pallet::origin]` (optional) -/// -/// The `#[pallet::origin]` attribute allows you to define some origin for the pallet. -/// -/// Item must be either a type alias, an enum, or a struct. It needs to be public. -/// -/// E.g.: -/// -/// ```ignore -/// #[pallet::origin] -/// pub struct Origin(PhantomData<(T)>); -/// ``` -/// -/// **WARNING**: modifying origin changes the outer runtime origin. This outer runtime origin -/// can be stored on-chain (e.g. in `pallet-scheduler`), thus any change must be done with care -/// as it might require some migration. -/// -/// NOTE: for instantiable pallets, the origin must be generic over `T` and `I`. -/// -/// Also see [`pallet::origin`](`frame_support::pallet_macros::origin`) -/// -/// # Composite enum `#[pallet::composite_enum]` (optional) -/// -/// The `#[pallet::composite_enum]` attribute allows you to define an enum on the pallet which -/// will then instruct `construct_runtime` to amalgamate all similarly-named enums from other -/// pallets into an aggregate enum. This is similar in principle with how the aggregate enum is -/// generated for `#[pallet::event]` or `#[pallet::error]`. -/// -/// The item tagged with `#[pallet::composite_enum]` MUST be an enum declaration, and can ONLY -/// be the following identifiers: `FreezeReason`, `HoldReason`, `LockId` or `SlashReason`. -/// Custom identifiers are not supported. -/// -/// NOTE: For ease of usage, when no `#[derive]` attributes are detected, the -/// `#[pallet::composite_enum]` attribute will automatically derive the following traits for -/// the enum: -/// -/// ```ignore -/// Copy, Clone, Eq, PartialEq, Encode, Decode, MaxEncodedLen, TypeInfo, RuntimeDebug -/// ``` -/// -/// The inverse is also true: if there are any #[derive] attributes present for the enum, then -/// the attribute will not automatically derive any of the traits described above. -/// -/// # General notes on instantiable pallets -/// -/// An instantiable pallet is one where Config is generic, i.e. `Config`. This allows -/// runtime to implement multiple instances of the pallet, by using different types for the -/// generic. This is the sole purpose of the generic `I`, but because -/// [`PalletInfo`](`traits::PalletInfo`) requires the `Pallet` placeholder to be static, it is -/// important to bound by `'static` whenever [`PalletInfo`](`traits::PalletInfo`) can be used. -/// Additionally, in order to make an instantiable pallet usable as a regular pallet without an -/// instance, it is important to bound by `= ()` on every type. -/// -/// Thus impl bound looks like `impl, I: 'static>`, and types look like -/// `SomeType` or `SomeType, I: 'static = ()>`. -/// -/// # Example of a non-instantiable pallet -/// -/// ``` -/// pub use pallet::*; // reexport in crate namespace for `construct_runtime!` -/// -/// #[frame_support::pallet] -/// // NOTE: The name of the pallet is provided by `construct_runtime` and is used as -/// // the unique identifier for the pallet's storage. It is not defined in the pallet itself. -/// pub mod pallet { -/// use frame_support::pallet_prelude::*; // Import various types used in the pallet definition -/// use frame_system::pallet_prelude::*; // Import some system helper types. -/// -/// type BalanceOf = ::Balance; -/// -/// // Define the generic parameter of the pallet -/// // The macro parses `#[pallet::constant]` attributes and uses them to generate metadata -/// // for the pallet's constants. -/// #[pallet::config] -/// pub trait Config: frame_system::Config { -/// #[pallet::constant] // put the constant in metadata -/// type MyGetParam: Get; -/// type Balance: Parameter + MaxEncodedLen + From; -/// type RuntimeEvent: From> + IsType<::RuntimeEvent>; -/// } -/// -/// // Define some additional constant to put into the constant metadata. -/// #[pallet::extra_constants] -/// impl Pallet { -/// /// Some description -/// fn exra_constant_name() -> u128 { 4u128 } -/// } -/// -/// // Define the pallet struct placeholder, various pallet function are implemented on it. -/// #[pallet::pallet] -/// #[pallet::generate_store(pub(super) trait Store)] -/// pub struct Pallet(_); -/// -/// // Implement the pallet hooks. -/// #[pallet::hooks] -/// impl Hooks> for Pallet { -/// fn on_initialize(_n: BlockNumberFor) -> Weight { -/// unimplemented!(); -/// } -/// -/// // can implement also: on_finalize, on_runtime_upgrade, offchain_worker, ... -/// // see `Hooks` trait -/// } -/// -/// // Declare Call struct and implement dispatchables. -/// // -/// // WARNING: Each parameter used in functions must implement: Clone, Debug, Eq, PartialEq, -/// // Codec. -/// // -/// // The macro parses `#[pallet::compact]` attributes on function arguments and implements -/// // the `Call` encoding/decoding accordingly. -/// #[pallet::call] -/// impl Pallet { -/// /// Doc comment put in metadata -/// #[pallet::weight(0)] // Defines weight for call (function parameters are in scope) -/// pub fn toto( -/// origin: OriginFor, -/// #[pallet::compact] _foo: u32, -/// ) -> DispatchResultWithPostInfo { -/// let _ = origin; -/// unimplemented!(); -/// } -/// } -/// -/// // Declare the pallet `Error` enum (this is optional). -/// // The macro generates error metadata using the doc comment on each variant. -/// #[pallet::error] -/// pub enum Error { -/// /// doc comment put into metadata -/// InsufficientProposersBalance, -/// } -/// -/// // Declare pallet Event enum (this is optional). -/// // -/// // WARNING: Each type used in variants must implement: Clone, Debug, Eq, PartialEq, Codec. -/// // -/// // The macro generates event metadata, and derive Clone, Debug, Eq, PartialEq and Codec -/// #[pallet::event] -/// // Generate a funciton on Pallet to deposit an event. -/// #[pallet::generate_deposit(pub(super) fn deposit_event)] -/// pub enum Event { -/// /// doc comment put in metadata -/// // `::AccountId` is not defined in metadata list, the last -/// // Thus the metadata is `::AccountId`. -/// Proposed(::AccountId), -/// /// doc -/// // here metadata will be `Balance` as define in metadata list -/// Spending(BalanceOf), -/// // here metadata will be `Other` as define in metadata list -/// Something(u32), -/// } -/// -/// // Define a struct which implements `frame_support::traits::Get` (optional). -/// #[pallet::type_value] -/// pub(super) fn MyDefault() -> T::Balance { 3.into() } -/// -/// // Declare a storage item. Any amount of storage items can be declared (optional). -/// // -/// // Is expected either `StorageValue`, `StorageMap` or `StorageDoubleMap`. -/// // The macro generates the prefix type and replaces the first generic `_`. -/// // -/// // The macro expands the metadata for the storage item with the type used: -/// // * for a storage value the type of the value is copied into the metadata -/// // * for a storage map the type of the values and the type of the key is copied into the metadata -/// // * for a storage double map the types of the values and keys are copied into the -/// // metadata. -/// // -/// // NOTE: The generic `Hasher` must implement the `StorageHasher` trait (or the type is not -/// // usable at all). We use [`StorageHasher::METADATA`] for the metadata of the hasher of the -/// // storage item. Thus generic hasher is supported. -/// #[pallet::storage] -/// pub(super) type MyStorageValue = -/// StorageValue>; -/// -/// // Another storage declaration -/// #[pallet::storage] -/// #[pallet::getter(fn my_storage)] -/// #[pallet::storage_prefix = "SomeOtherName"] -/// pub(super) type MyStorage = -/// StorageMap; -/// -/// // Declare the genesis config (optional). -/// // -/// // The macro accepts either a struct or an enum; it checks that generics are consistent. -/// // -/// // Type must implement the `Default` trait. -/// #[pallet::genesis_config] -/// #[derive(frame_support::DefaultNoBound)] -/// pub struct GenesisConfig { -/// _config: sp_std::marker::PhantomData, -/// _myfield: u32, -/// } -/// -/// // Declare genesis builder. (This is need only if GenesisConfig is declared) -/// #[pallet::genesis_build] -/// impl BuildGenesisConfig for GenesisConfig { -/// fn build(&self) {} -/// } -/// -/// // Declare a pallet origin (this is optional). -/// // -/// // The macro accept type alias or struct or enum, it checks generics are consistent. -/// #[pallet::origin] -/// pub struct Origin(PhantomData); -/// -/// // Declare a hold reason (this is optional). -/// // -/// // Creates a hold reason for this pallet that is aggregated by `construct_runtime`. -/// // A similar enum can be defined for `FreezeReason`, `LockId` or `SlashReason`. -/// #[pallet::composite_enum] -/// pub enum HoldReason { -/// SomeHoldReason -/// } -/// -/// // Declare validate_unsigned implementation (this is optional). -/// #[pallet::validate_unsigned] -/// impl ValidateUnsigned for Pallet { -/// type Call = Call; -/// fn validate_unsigned( -/// source: TransactionSource, -/// call: &Self::Call -/// ) -> TransactionValidity { -/// Err(TransactionValidityError::Invalid(InvalidTransaction::Call)) -/// } -/// } -/// -/// // Declare inherent provider for pallet (this is optional). -/// #[pallet::inherent] -/// impl ProvideInherent for Pallet { -/// type Call = Call; -/// type Error = InherentError; -/// -/// const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; -/// -/// fn create_inherent(_data: &InherentData) -> Option { -/// unimplemented!(); -/// } -/// -/// fn is_inherent(_call: &Self::Call) -> bool { -/// unimplemented!(); -/// } -/// } -/// -/// // Regular rust code needed for implementing ProvideInherent trait -/// -/// #[derive(codec::Encode, sp_runtime::RuntimeDebug)] -/// #[cfg_attr(feature = "std", derive(codec::Decode))] -/// pub enum InherentError { -/// } -/// -/// impl sp_inherents::IsFatalError for InherentError { -/// fn is_fatal_error(&self) -> bool { -/// unimplemented!(); -/// } -/// } -/// -/// pub const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"testpall"; -/// } -/// ``` -/// -/// # Example of an instantiable pallet -/// -/// ``` -/// pub use pallet::*; -/// -/// #[frame_support::pallet] -/// pub mod pallet { -/// use frame_support::pallet_prelude::*; -/// use frame_system::pallet_prelude::*; -/// -/// type BalanceOf = >::Balance; +/// * Weights no longer need to be specified on every `#[pallet::call]` declaration. By +/// default, dev mode pallets will assume a weight of zero (`0`) if a weight is not +/// specified. This is equivalent to specifying `#[weight(0)]` on all calls that do not +/// specify a weight. +/// * Call indices no longer need to be specified on every `#[pallet::call]` declaration. By +/// default, dev mode pallets will assume a call index based on the order of the call. +/// * All storages are marked as unbounded, meaning you do not need to implement +/// [`MaxEncodedLen`](frame_support::pallet_prelude::MaxEncodedLen) on storage types. This is +/// equivalent to specifying `#[pallet::unbounded]` on all storage type definitions. +/// * Storage hashers no longer need to be specified and can be replaced by `_`. In dev mode, +/// these will be replaced by `Blake2_128Concat`. In case of explicit key-binding, `Hasher` +/// can simply be ignored when in `dev_mode`. /// -/// #[pallet::config] -/// pub trait Config: frame_system::Config { -/// #[pallet::constant] -/// type MyGetParam: Get; -/// type Balance: Parameter + MaxEncodedLen + From; -/// type RuntimeEvent: From> + IsType<::RuntimeEvent>; -/// } -/// -/// #[pallet::extra_constants] -/// impl, I: 'static> Pallet { -/// /// Some description -/// fn extra_constant_name() -> u128 { 4u128 } -/// } -/// -/// #[pallet::pallet] -/// #[pallet::generate_store(pub(super) trait Store)] -/// pub struct Pallet(PhantomData<(T, I)>); -/// -/// #[pallet::hooks] -/// impl, I: 'static> Hooks> for Pallet { -/// } -/// -/// #[pallet::call] -/// impl, I: 'static> Pallet { -/// /// Doc comment put in metadata -/// #[pallet::weight(0)] -/// pub fn toto(origin: OriginFor, #[pallet::compact] _foo: u32) -> DispatchResultWithPostInfo { -/// let _ = origin; -/// unimplemented!(); -/// } -/// } -/// -/// #[pallet::error] -/// pub enum Error { -/// /// doc comment put into metadata -/// InsufficientProposersBalance, -/// } -/// -/// #[pallet::event] -/// #[pallet::generate_deposit(pub(super) fn deposit_event)] -/// pub enum Event, I: 'static = ()> { -/// /// doc comment put in metadata -/// Proposed(::AccountId), -/// /// doc -/// Spending(BalanceOf), -/// Something(u32), -/// } -/// -/// #[pallet::type_value] -/// pub(super) fn MyDefault, I: 'static>() -> T::Balance { 3.into() } -/// -/// #[pallet::storage] -/// pub(super) type MyStorageValue, I: 'static = ()> = -/// StorageValue>; -/// -/// #[pallet::storage] -/// #[pallet::getter(fn my_storage)] -/// #[pallet::storage_prefix = "SomeOtherName"] -/// pub(super) type MyStorage = -/// StorageMap; -/// -/// #[pallet::genesis_config] -/// #[derive(frame_support::DefaultNoBound)] -/// pub struct GenesisConfig, I: 'static = ()> { -/// _config: sp_std::marker::PhantomData<(T,I)>, -/// _myfield: u32, -/// } -/// -/// #[pallet::genesis_build] -/// impl, I: 'static> BuildGenesisConfig for GenesisConfig { -/// fn build(&self) {} -/// } -/// -/// #[pallet::origin] -/// pub struct Origin(PhantomData<(T, I)>); -/// -/// #[pallet::composite_enum] -/// pub enum HoldReason { -/// SomeHoldReason -/// } -/// -/// #[pallet::validate_unsigned] -/// impl, I: 'static> ValidateUnsigned for Pallet { -/// type Call = Call; -/// fn validate_unsigned( -/// source: TransactionSource, -/// call: &Self::Call -/// ) -> TransactionValidity { -/// Err(TransactionValidityError::Invalid(InvalidTransaction::Call)) -/// } -/// } -/// -/// #[pallet::inherent] -/// impl, I: 'static> ProvideInherent for Pallet { -/// type Call = Call; -/// type Error = InherentError; -/// -/// const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; -/// -/// fn create_inherent(_data: &InherentData) -> Option { -/// unimplemented!(); -/// } -/// -/// fn is_inherent(_call: &Self::Call) -> bool { -/// unimplemented!(); -/// } -/// } -/// -/// // Regular rust code needed for implementing ProvideInherent trait -/// -/// #[derive(codec::Encode, sp_runtime::RuntimeDebug)] -/// #[cfg_attr(feature = "std", derive(codec::Decode))] -/// pub enum InherentError { -/// } -/// -/// impl sp_inherents::IsFatalError for InherentError { -/// fn is_fatal_error(&self) -> bool { -/// unimplemented!(); -/// } -/// } -/// -/// pub const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"testpall"; -/// } -/// ``` +/// Note that the `dev_mode` argument can only be supplied to the `#[pallet]` or +/// `#[frame_support::pallet]` attribute macro that encloses your pallet module. This +/// argument cannot be specified anywhere else, including but not limited to the +/// `#[pallet::pallet]` attribute macro. /// -/// # Upgrade guidelines -/// -/// 1. Export the metadata of the pallet for later checks -/// - run your node with the pallet active -/// - query the metadata using the `state_getMetadata` RPC and curl, or use `subsee -p -/// > meta.json` -/// 2. Generate the template upgrade for the pallet provided by `decl_storage` with the -/// environment variable `PRINT_PALLET_UPGRADE`: `PRINT_PALLET_UPGRADE=1 cargo check -p -/// my_pallet`. This template can be used as it contains all information for storages, -/// genesis config and genesis build. -/// 3. Reorganize the pallet to have the trait `Config`, `decl_*` macros, -/// [`ValidateUnsigned`](`pallet_prelude::ValidateUnsigned`), -/// [`ProvideInherent`](`pallet_prelude::ProvideInherent`), and Origin` all together in one -/// file. Suggested order: -/// * `Config`, -/// * `decl_module`, -/// * `decl_event`, -/// * `decl_error`, -/// * `decl_storage`, -/// * `origin`, -/// * `validate_unsigned`, -/// * `provide_inherent`, so far it should compile and all be correct. -/// 4. start writing the new pallet module -/// ```ignore -/// pub use pallet::*; -/// -/// #[frame_support::pallet] -/// pub mod pallet { -/// use frame_support::pallet_prelude::*; -/// use frame_system::pallet_prelude::*; -/// use super::*; -/// -/// #[pallet::pallet] -/// #[pallet::generate_store($visibility_of_trait_store trait Store)] -/// // NOTE: if the visibility of trait store is private but you want to make it available -/// // in super, then use `pub(super)` or `pub(crate)` to make it available in crate. -/// pub struct Pallet(_); -/// // pub struct Pallet(PhantomData); // for instantiable pallet -/// } -/// ``` -/// 5. **migrate Config**: move trait into the module with -/// * all const in `decl_module` to [`#[pallet::constant]`](#palletconstant) -/// * add the bound `IsType<::RuntimeEvent>` to `type -/// RuntimeEvent` -/// 7. **migrate decl_module**: write: -/// ```ignore -/// #[pallet::hooks] -/// impl Hooks for Pallet { -/// } -/// ``` -/// and write inside `on_initialize`, `on_finalize`, `on_runtime_upgrade`, -/// `offchain_worker`, and `integrity_test`. -/// -/// then write: -/// ```ignore -/// #[pallet::call] -/// impl Pallet { -/// } -/// ``` -/// and write inside all the calls in `decl_module` with a few changes in the signature: -/// - origin must now be written completely, e.g. `origin: OriginFor` -/// - result type must be `DispatchResultWithPostInfo`, you need to write it and also you -/// might need to put `Ok(().into())` at the end or the function. -/// - `#[compact]` must now be written -/// [`#[pallet::compact]`](#palletcompact-some_arg-some_type) -/// - `#[weight = ..]` must now be written [`#[pallet::weight(..)]`](#palletweightexpr) -/// -/// 7. **migrate event**: rewrite as a simple enum with the attribute -/// [`#[pallet::event]`](#event-palletevent-optional), use [`#[pallet::generate_deposit($vis -/// fn deposit_event)]`](#event-palletevent-optional) to generate `deposit_event`, -/// 8. **migrate error**: rewrite it with attribute -/// [`#[pallet::error]`](#error-palleterror-optional). -/// 9. **migrate storage**: `decl_storage` provide an upgrade template (see 3.). All storages, -/// genesis config, genesis build and default implementation of genesis config can be taken -/// from it directly. -/// -/// Otherwise here is the manual process: -/// -/// first migrate the genesis logic. write: -/// ```ignore -/// #[pallet::genesis_config] -/// struct GenesisConfig { -/// // fields of add_extra_genesis -/// } -/// impl Default for GenesisConfig { -/// // type default or default provided for fields -/// } -/// #[pallet::genesis_build] -/// impl GenesisBuild for GenesisConfig { -/// // for instantiable pallet: -/// // `impl GenesisBuild for GenesisConfig { -/// fn build() { -/// // The add_extra_genesis build logic -/// } -/// } -/// ``` -/// for each storage, if it contains `config(..)` then add fields, and make it default to -/// the value in `= ..;` or the type default if none, if it contains no build then also add -/// the logic to build the value. for each storage if it contains `build(..)` then add the -/// logic to `genesis_build`. -/// -/// NOTE: within `decl_storage`: the individual config is executed first, followed by the -/// build and finally the `add_extra_genesis` build. -/// -/// Once this is done you can migrate storages individually, a few notes: -/// - for private storage use `pub(crate) type ` or `pub(super) type` or nothing, -/// - for storages with `get(fn ..)` use [`#[pallet::getter(fn -/// ...)]`](#palletgetterfn-my_getter_fn_name-optional) -/// - for storages with value being `Option<$something>` make generic `Value` being -/// `$something` and generic `QueryKind` being `OptionQuery` (note: this is default). -/// Otherwise make `Value` the complete value type and `QueryKind` being `ValueQuery`. -/// - for storages with default value: `= $expr;` provide some specific `OnEmpty` generic. -/// To do so use of `#[pallet::type_value]` to generate the wanted struct to put. -/// example: `MyStorage: u32 = 3u32` would be written: -/// -/// ```ignore -/// #[pallet::type_value] fn MyStorageOnEmpty() -> u32 { 3u32 } -/// #[pallet::storage] -/// pub(super) type MyStorage = StorageValue<_, u32, ValueQuery, MyStorageOnEmpty>; -/// ``` -/// -/// NOTE: `decl_storage` also generates the functions `assimilate_storage` and -/// `build_storage` directly on `GenesisConfig`, and these are sometimes used in tests. -/// In order not to break they can be implemented manually, one can implement those -/// functions by calling the `GenesisBuild` implementation. -/// 10. **migrate origin**: move the origin to the pallet module to be under a -/// [`#[pallet::origin]`](#origin-palletorigin-optional) attribute -/// 11. **migrate validate_unsigned**: move the -/// [`ValidateUnsigned`](`pallet_prelude::ValidateUnsigned`) implementation to the pallet -/// module under a -/// [`#[pallet::validate_unsigned]`](#validate-unsigned-palletvalidate_unsigned-optional) -/// attribute -/// 12. **migrate provide_inherent**: move the -/// [`ProvideInherent`](`pallet_prelude::ProvideInherent`) implementation to the pallet -/// module under a [`#[pallet::inherent]`](#inherent-palletinherent-optional) attribute -/// 13. rename the usage of `Module` to `Pallet` inside the crate. -/// 14. migration is done, now double check the migration with the checking migration -/// guidelines shown below. -/// -/// # Checking upgrade guidelines: -/// -/// * compare metadata. Use [subsee](https://github.com/ascjones/subsee) to fetch the metadata -/// and do a diff of the resulting json before and after migration. This checks for: -/// * call, names, signature, docs -/// * event names, docs -/// * error names, docs -/// * storage names, hasher, prefixes, default value -/// * error, error, constant -/// * manually check that: -/// * `Origin` was moved inside the macro under -/// [`#[pallet::origin]`](#origin-palletorigin-optional) if it exists -/// * [`ValidateUnsigned`](`pallet_prelude::ValidateUnsigned`) was moved inside the macro -/// under -/// [`#[pallet::validate_unsigned)]`](#validate-unsigned-palletvalidate_unsigned-optional) -/// if it exists -/// * [`ProvideInherent`](`pallet_prelude::ProvideInherent`) was moved inside the macro -/// under [`#[pallet::inherent)]`](#inherent-palletinherent-optional) if it exists -/// * `on_initialize` / `on_finalize` / `on_runtime_upgrade` / `offchain_worker` were moved -/// to the `Hooks` implementation -/// * storages with `config(..)` were converted to `GenesisConfig` field, and their default -/// is `= $expr;` if the storage has a default value -/// * storages with `build($expr)` or `config(..)` were built in `GenesisBuild::build` -/// * `add_extra_genesis` fields were converted to `GenesisConfig` field with their correct -/// default if specified -/// * `add_extra_genesis` build was written into `GenesisBuild::build` -/// * storage items defined with [`pallet`] use the name of the pallet provided by -/// [`traits::PalletInfo::name`] as `pallet_prefix` (in `decl_storage`, storage items used -/// the `pallet_prefix` given as input of `decl_storage` with the syntax `as Example`). Thus -/// a runtime using the pallet must be careful with this change. To handle this change: -/// * either ensure that the name of the pallet given to `construct_runtime!` is the same -/// as the name the pallet was giving to `decl_storage`, -/// * or do a storage migration from the old prefix used to the new prefix used. -/// -/// NOTE: The prefixes used by storage items are in metadata. Thus, ensuring the metadata -/// hasn't changed ensures that the `pallet_prefix`s used by the storage items haven't changed. -/// -/// # Notes when macro fails to show proper error message spans: -/// -/// Rustc loses span for some macro input. Some tips to fix it: -/// * do not use inner attribute: -/// ```ignore -/// #[pallet] -/// pub mod pallet { -/// //! This inner attribute will make span fail -/// .. -/// } -/// ``` -/// * use the newest nightly possible. +///
+/// WARNING:
+/// You should not deploy or use dev mode pallets in production. Doing so can break your
+/// chain and therefore should never be done. Once you are done tinkering, you should
+/// remove the 'dev_mode' argument from your #[pallet] declaration and fix any compile
+/// errors before attempting to use your pallet in a production scenario.
+/// 
pub use frame_support_procedural::pallet; -/// Contains macro stubs for all of the pallet:: macros -pub mod pallet_macros { - pub use frame_support_procedural::{ - composite_enum, config, disable_frame_system_supertrait_check, disable_try_decode_storage, - error, event, extra_constants, feeless_if, generate_deposit, generate_store, getter, hooks, - import_section, inherent, no_default, no_default_bounds, pallet_section, storage_prefix, - storage_version, type_value, unbounded, validate_unsigned, weight, whitelist_storage, - }; +/// Contains macro stubs for all of the `pallet::` macros +pub mod pallet_macros { + /// Declare the storage as whitelisted from benchmarking. + /// + /// Doing so will exclude reads of that value's storage key from counting towards weight + /// calculations during benchmarking. + /// + /// This attribute should only be attached to storages that are known to be + /// read/used in every block. This will result in a more accurate benchmarking weight. + /// + /// ### Example + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// + /// #[pallet::storage] + /// #[pallet::whitelist_storage] + /// pub type MyStorage = StorageValue<_, u32>; + /// # + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// } + /// ``` + pub use frame_support_procedural::whitelist_storage; + + /// Allows specifying the weight of a call. + /// + /// Each dispatchable needs to define a weight with the `#[pallet::weight($expr)]` + /// attribute. The first argument must be `origin: OriginFor`. + /// + /// ## Example + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # use frame_system::pallet_prelude::*; + /// # + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// + /// #[pallet::call] + /// impl Pallet { + /// #[pallet::weight({0})] // <- set actual weight here + /// #[pallet::call_index(0)] + /// pub fn something( + /// _: OriginFor, + /// foo: u32, + /// ) -> DispatchResult { + /// unimplemented!() + /// } + /// } + /// # + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// } + /// ``` + pub use frame_support_procedural::weight; + + /// Allows whitelisting a storage item from decoding during try-runtime checks. + /// + /// The optional attribute `#[pallet::disable_try_decode_storage]` will declare the + /// storage as whitelisted from decoding during try-runtime checks. This should only be + /// attached to transient storage which cannot be migrated during runtime upgrades. + /// + /// ### Example + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// + /// #[pallet::storage] + /// #[pallet::disable_try_decode_storage] + /// pub type MyStorage = StorageValue<_, u32>; + /// # + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// } + /// ``` + pub use frame_support_procedural::disable_try_decode_storage; + + /// Declares a storage as unbounded in potential size. + /// + /// When implementating the storage info (when `#[pallet::generate_storage_info]` is + /// specified on the pallet struct placeholder), the size of the storage will be declared + /// as unbounded. This can be useful for storage which can never go into PoV (Proof of + /// Validity). + /// + /// ## Example + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// + /// #[pallet::storage] + /// #[pallet::unbounded] + /// pub type MyStorage = StorageValue<_, u32>; + /// # + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// } + /// ``` + pub use frame_support_procedural::unbounded; + + /// Defines what storage prefix to use for a storage item when building the trie. + /// + /// This is helpful if you wish to rename the storage field but don't want to perform a + /// migration. + /// + /// ## Example + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// + /// #[pallet::storage] + /// #[pallet::storage_prefix = "foo"] + /// pub type MyStorage = StorageValue<_, u32>; + /// # + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// } + /// ``` + pub use frame_support_procedural::storage_prefix; + + /// Ensures the generated `DefaultConfig` will not have any bounds for + /// that trait item. + /// + /// Attaching this attribute to a trait item ensures that the generated trait + /// `DefaultConfig` will not have any bounds for this trait item. + /// + /// As an example, if you have a trait item `type AccountId: SomeTrait;` in your `Config` + /// trait, the generated `DefaultConfig` will only have `type AccountId;` with no trait + /// bound. + pub use frame_support_procedural::no_default_bounds; + + /// Ensures the trait item will not be used as a default with the + /// `#[derive_impl(..)]` attribute macro. + /// + /// The optional attribute `#[pallet::no_default]` can be attached to trait items within a + /// `Config` trait impl that has [`#[pallet::config(with_default)]`](`config`) + /// attached. + pub use frame_support_procedural::no_default; + + /// Declares a module as importable into a pallet via + /// [`#[import_section]`](`import_section`). + /// + /// Note that sections are imported by their module name/ident, and should be referred to + /// by their _full path_ from the perspective of the target pallet. Do not attempt to make + /// use of `use` statements to bring pallet sections into scope, as this will not work + /// (unless you do so as part of a wildcard import, in which case it will work). + /// + /// ## Naming Logistics + /// + /// Also note that because of how `#[pallet_section]` works, pallet section names must be + /// globally unique _within the crate in which they are defined_. For more information on + /// why this must be the case, see macro_magic's + /// [`#[export_tokens]`](https://docs.rs/macro_magic/latest/macro_magic/attr.export_tokens.html) macro. + /// + /// Optionally, you may provide an argument to `#[pallet_section]` such as + /// `#[pallet_section(some_ident)]`, in the event that there is another pallet section in + /// same crate with the same ident/name. The ident you specify can then be used instead of + /// the module's ident name when you go to import it via + /// [`#[import_section]`](`import_section`). + pub use frame_support_procedural::pallet_section; + + /// The `#[pallet::inherent]` attribute allows the pallet to provide + /// [inherents](https://docs.substrate.io/fundamentals/transaction-types/#inherent-transactions). + /// + /// An inherent is some piece of data that is inserted by a block authoring node at block + /// creation time and can either be accepted or rejected by validators based on whether the + /// data falls within an acceptable range. + /// + /// The most common inherent is the `timestamp` that is inserted into every block. Since + /// there is no way to validate timestamps, validators simply check that the timestamp + /// reported by the block authoring node falls within an acceptable range. + /// + /// Example usage: + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # use frame_support::inherent::IsFatalError; + /// # use sp_timestamp::InherentError; + /// # use sp_std::result; + /// # + /// // Example inherent identifier + /// pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"timstap0"; + /// + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// + /// #[pallet::inherent] + /// impl ProvideInherent for Pallet { + /// type Call = Call; + /// type Error = InherentError; + /// const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; + /// + /// fn create_inherent(data: &InherentData) -> Option { + /// unimplemented!() + /// } + /// + /// fn check_inherent( + /// call: &Self::Call, + /// data: &InherentData, + /// ) -> result::Result<(), Self::Error> { + /// unimplemented!() + /// } + /// + /// fn is_inherent(call: &Self::Call) -> bool { + /// unimplemented!() + /// } + /// } + /// # + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// } + /// ``` + /// + /// I.e. a trait implementation with bound `T: Config`, of trait `ProvideInherent` for type + /// `Pallet`, and some optional where clause. + /// + /// ## Macro expansion + /// + /// The macro currently makes no use of this information, but it might use this information + /// in the future to give information directly to `construct_runtime`. + pub use frame_support_procedural::inherent; + + /// Splits a pallet declaration into multiple parts. + /// + /// An attribute macro that can be attached to a module declaration. Doing so will + /// import the contents of the specified external pallet section that is defined + /// elsewhere using [`#[pallet_section]`](`pallet_section`). + /// + /// ## Example + /// ``` + /// # use frame_support::pallet_macros::pallet_section; + /// # use frame_support::pallet_macros::import_section; + /// # + /// /// A [`pallet_section`] that defines the events for a pallet. + /// /// This can later be imported into the pallet using [`import_section`]. + /// #[pallet_section] + /// mod events { + /// #[pallet::event] + /// #[pallet::generate_deposit(pub(super) fn deposit_event)] + /// pub enum Event { + /// /// Event documentation should end with an array that provides descriptive names for event + /// /// parameters. [something, who] + /// SomethingStored { something: u32, who: T::AccountId }, + /// } + /// } + /// + /// #[import_section(events)] + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// # + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config { + /// # type RuntimeEvent: From> + IsType<::RuntimeEvent>; + /// # } + /// } + /// ``` + /// + /// This will result in the contents of `some_section` being _verbatim_ imported into + /// the pallet above. Note that since the tokens for `some_section` are essentially + /// copy-pasted into the target pallet, you cannot refer to imports that don't also + /// exist in the target pallet, but this is easily resolved by including all relevant + /// `use` statements within your pallet section, so they are imported as well, or by + /// otherwise ensuring that you have the same imports on the target pallet. + /// + /// It is perfectly permissible to import multiple pallet sections into the same pallet, + /// which can be done by having multiple `#[import_section(something)]` attributes + /// attached to the pallet. + /// + /// Note that sections are imported by their module name/ident, and should be referred to + /// by their _full path_ from the perspective of the target pallet. + pub use frame_support_procedural::import_section; + + /// Allows defining getter functions on `Pallet` storage. + /// + /// ## Example + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// + /// #[pallet::storage] + /// #[pallet::getter(fn my_getter_fn_name)] + /// pub type MyStorage = StorageValue<_, u32>; + /// # + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// } + /// ``` + /// + /// See [`pallet::storage`](`frame_support::pallet_macros::storage`) for more info. + pub use frame_support_procedural::getter; + + /// Allows generating the `Store` trait for all storages. + /// + /// DEPRECATED: Will be removed, do not use. + /// See for more details. + /// + /// To generate a `Store` trait associating all storages, annotate your `Pallet` struct + /// with the attribute `#[pallet::generate_store($vis trait Store)]`, e.g.: + /// + /// ```ignore + /// #[pallet::pallet] + /// #[pallet::generate_store(pub(super) trait Store)] + /// pub struct Pallet(_); + /// ``` + /// More precisely, the `Store` trait contains an associated type for each storage. It is + /// implemented for `Pallet` allowing access to the storage from pallet struct. + /// + /// Thus when defining a storage named `Foo`, it can later be accessed from `Pallet` using + /// `::Foo`. + pub use frame_support_procedural::generate_store; + + /// Defines constants that are added to the constant field of + /// [`PalletMetadata`](frame_metadata::v15::PalletMetadata) struct for this pallet. + /// + /// Must be defined like: + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// # + /// #[pallet::extra_constants] + /// impl Pallet // $optional_where_clause + /// { + /// #[pallet::constant_name(SomeU32ConstantName)] + /// /// Some doc + /// fn some_u32_constant() -> u32 { + /// 100u32 + /// } + /// } + /// } + /// ``` + /// + /// I.e. a regular rust `impl` block with some optional where clause and functions with 0 + /// args, 0 generics, and some return type. + pub use frame_support_procedural::extra_constants; + + #[rustfmt::skip] + /// Allows bypassing the `frame_system::Config` supertrait check. + /// + /// To bypass the syntactic `frame_system::Config` supertrait check, use the attribute + /// `pallet::disable_frame_system_supertrait_check`. + /// + /// Note this bypass is purely syntactic, and does not actually remove the requirement that your + /// pallet implements `frame_system::Config`. When using this check, your config is still required to implement + /// `frame_system::Config` either via + /// - Implementing a trait that itself implements `frame_system::Config` + /// - Tightly coupling it with another pallet which itself implements `frame_system::Config` + /// + /// e.g. + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # use frame_system::pallet_prelude::*; + /// trait OtherTrait: frame_system::Config {} + /// + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// + /// #[pallet::config] + /// #[pallet::disable_frame_system_supertrait_check] + /// pub trait Config: OtherTrait {} + /// } + /// ``` + /// + /// To learn more about supertraits, see the + /// [trait_based_programming](../../polkadot_sdk_docs/reference_docs/trait_based_programming/index.html) + /// reference doc. + pub use frame_support_procedural::disable_frame_system_supertrait_check; + + /// The mandatory attribute allowing definition of configurable types for the pallet. + /// + /// Item must be defined as: + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// + /// #[pallet::config] + /// pub trait Config: frame_system::Config // + $optionally_some_other_supertraits + /// // $optional_where_clause + /// { + /// // config items here + /// } + /// } + /// ``` + /// + /// I.e. a regular trait definition named `Config`, with the supertrait + /// [`frame_system::pallet::Config`](../../frame_system/pallet/trait.Config.html), and + /// optionally other supertraits and a where clause. (Specifying other supertraits here is + /// known as [tight coupling](https://docs.substrate.io/reference/how-to-guides/pallet-design/use-tight-coupling/)) + /// + /// The associated type `RuntimeEvent` is reserved. If defined, it must have the bounds + /// `From` and `IsType<::RuntimeEvent>`. + /// + /// [`#[pallet::event]`](`event`) must be present if `RuntimeEvent` + /// exists as a config item in your `#[pallet::config]`. + /// + /// ## Optional: `with_default` + /// + /// An optional `with_default` argument may also be specified. Doing so will automatically + /// generate a `DefaultConfig` trait inside your pallet which is suitable for use with + /// [`#[derive_impl(..)`](`frame_support::derive_impl`) to derive a default testing + /// config: + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # use frame_system::pallet_prelude::*; + /// # use core::fmt::Debug; + /// # use frame_support::traits::Contains; + /// # + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// + /// #[pallet::config(with_default)] // <- with_default is optional + /// pub trait Config: frame_system::Config { + /// /// The overarching event type. + /// #[pallet::no_default_bounds] // Default is not supported for RuntimeEvent + /// type RuntimeEvent: From> + IsType<::RuntimeEvent>; + /// + /// // ...other config items get default + /// } + /// + /// #[pallet::event] + /// pub enum Event { + /// SomeEvent(u16, u32), + /// } + /// } + /// ``` + /// + /// As shown above, you may also attach the [`#[pallet::no_default]`](`no_default`) + /// attribute to specify that a particular trait item _cannot_ be used as a default when a + /// test `Config` is derived using the [`#[derive_impl(..)]`](`frame_support::derive_impl`) + /// attribute macro. This will cause that particular trait item to simply not appear in + /// default testing configs based on this config (the trait item will not be included in + /// `DefaultConfig`). + /// + /// ### `DefaultConfig` Caveats + /// + /// The auto-generated `DefaultConfig` trait: + /// - is always a _subset_ of your pallet's `Config` trait. + /// - can only contain items that don't rely on externalities, such as + /// `frame_system::Config`. + /// + /// Trait items that _do_ rely on externalities should be marked with + /// [`#[pallet::no_default]`](`no_default`) + /// + /// Consequently: + /// - Any items that rely on externalities _must_ be marked with + /// [`#[pallet::no_default]`](`no_default`) or your trait will fail to compile when used + /// with [`derive_impl`](`frame_support::derive_impl`). + /// - Items marked with [`#[pallet::no_default]`](`no_default`) are entirely excluded from + /// the `DefaultConfig` trait, and therefore any impl of `DefaultConfig` doesn't need to + /// implement such items. + /// + /// For more information, see [`frame_support::derive_impl`]. + pub use frame_support_procedural::config; + + /// Allows defining an enum that gets composed as an aggregate enum by `construct_runtime`. + /// + /// The `#[pallet::composite_enum]` attribute allows you to define an enum that gets + /// composed as an aggregate enum by `construct_runtime`. This is similar in principle with + /// [frame_support_procedural::event] and [frame_support_procedural::error]. + /// + /// The attribute currently only supports enum definitions, and identifiers that are named + /// `FreezeReason`, `HoldReason`, `LockId` or `SlashReason`. Arbitrary identifiers for the + /// enum are not supported. The aggregate enum generated by + /// [`frame_support::construct_runtime`](frame_support::construct_runtime) will have the + /// name of `RuntimeFreezeReason`, `RuntimeHoldReason`, `RuntimeLockId` and + /// `RuntimeSlashReason` respectively. + /// + /// NOTE: The aggregate enum generated by `construct_runtime` generates a conversion + /// function from the pallet enum to the aggregate enum, and automatically derives the + /// following traits: + /// + /// ```ignore + /// Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, MaxEncodedLen, TypeInfo, + /// RuntimeDebug + /// ``` + /// + /// For ease of usage, when no `#[derive]` attributes are found for the enum under + /// [`#[pallet::composite_enum]`](composite_enum), the aforementioned traits are + /// automatically derived for it. The inverse is also true: if there are any `#[derive]` + /// attributes found for the enum, then no traits will automatically be derived for it. + /// + /// e.g, defining `HoldReason` in a pallet + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// + /// #[pallet::composite_enum] + /// pub enum HoldReason { + /// /// The NIS Pallet has reserved it for a non-fungible receipt. + /// #[codec(index = 0)] + /// SomeHoldReason, + /// #[codec(index = 1)] + /// SomeOtherHoldReason, + /// } + /// # + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// } + pub use frame_support_procedural::composite_enum; + + /// Allows the pallet to validate unsigned transactions. + /// + /// Item must be defined as: + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// + /// #[pallet::validate_unsigned] + /// impl sp_runtime::traits::ValidateUnsigned for Pallet { + /// type Call = Call; + /// + /// fn validate_unsigned(_source: TransactionSource, _call: &Self::Call) -> TransactionValidity { + /// // Your implementation details here + /// unimplemented!() + /// } + /// } + /// # + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// } + /// ``` + /// + /// I.e. a trait implementation with bound `T: Config`, of trait + /// [`ValidateUnsigned`](frame_support::pallet_prelude::ValidateUnsigned) for + /// type `Pallet`, and some optional where clause. + /// + /// NOTE: There is also the [`sp_runtime::traits::SignedExtension`] trait that can be used + /// to add some specific logic for transaction validation. + /// + /// ## Macro expansion + /// + /// The macro currently makes no use of this information, but it might use this information + /// in the future to give information directly to [`frame_support::construct_runtime`]. + pub use frame_support_procedural::validate_unsigned; + + /// Allows defining a struct implementing the [`Get`](frame_support::traits::Get) trait to + /// ease the use of storage types. + /// + /// This attribute is meant to be used alongside [`#[pallet::storage]`](`storage`) to + /// define a storage's default value. This attribute can be used multiple times. + /// + /// Item must be defined as: + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use sp_runtime::FixedU128; + /// # use frame_support::pallet_prelude::*; + /// # + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// + /// #[pallet::storage] + /// pub(super) type SomeStorage = + /// StorageValue<_, FixedU128, ValueQuery, DefaultForSomeValue>; + /// + /// // Define default for ParachainId + /// #[pallet::type_value] + /// pub fn DefaultForSomeValue() -> FixedU128 { + /// FixedU128::from_u32(1) + /// } + /// # + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// } + /// ``` + /// + /// ## Macro expansion + /// + /// The macro renames the function to some internal name, generates a struct with the + /// original name of the function and its generic, and implements `Get<$ReturnType>` by + /// calling the user defined function. + pub use frame_support_procedural::type_value; + + /// Allows defining a storage version for the pallet. + /// + /// Because the `pallet::pallet` macro implements + /// [`GetStorageVersion`](frame_support::traits::GetStorageVersion), the current storage + /// version needs to be communicated to the macro. This can be done by using the + /// `pallet::storage_version` attribute: + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::StorageVersion; + /// # use frame_support::traits::GetStorageVersion; + /// # + /// const STORAGE_VERSION: StorageVersion = StorageVersion::new(5); + /// + /// #[pallet::pallet] + /// #[pallet::storage_version(STORAGE_VERSION)] + /// pub struct Pallet(_); + /// # + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// } + /// ``` + /// + /// If not present, the current storage version is set to the default value. + pub use frame_support_procedural::storage_version; + + /// The `#[pallet::hooks]` attribute allows you to specify a + /// [`frame_support::traits::Hooks`] implementation for `Pallet` that specifies + /// pallet-specific logic. + /// + /// The item the attribute attaches to must be defined as follows: + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # use frame_system::pallet_prelude::*; + /// # + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// + /// #[pallet::hooks] + /// impl Hooks> for Pallet { + /// // Implement hooks here + /// } + /// # + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// } + /// ``` + /// I.e. a regular trait implementation with generic bound: `T: Config`, for the trait + /// `Hooks>` (they are defined in preludes), for the type `Pallet`. + /// + /// Optionally, you could add a where clause. + /// + /// ## Macro expansion + /// + /// The macro implements the traits + /// [`OnInitialize`](frame_support::traits::OnInitialize), + /// [`OnIdle`](frame_support::traits::OnIdle), + /// [`OnFinalize`](frame_support::traits::OnFinalize), + /// [`OnRuntimeUpgrade`](frame_support::traits::OnRuntimeUpgrade), + /// [`OffchainWorker`](frame_support::traits::OffchainWorker), and + /// [`IntegrityTest`](frame_support::traits::IntegrityTest) using + /// the provided [`Hooks`](frame_support::traits::Hooks) implementation. + /// + /// NOTE: `OnRuntimeUpgrade` is implemented with `Hooks::on_runtime_upgrade` and some + /// additional logic. E.g. logic to write the pallet version into storage. + /// + /// NOTE: The macro also adds some tracing logic when implementing the above traits. The + /// following hooks emit traces: `on_initialize`, `on_finalize` and `on_runtime_upgrade`. + pub use frame_support_procedural::hooks; + + /// Generates a helper function on `Pallet` that handles deposit events. + /// + /// NOTE: For instantiable pallets, the event must be generic over `T` and `I`. + /// + /// ## Macro expansion + /// + /// The macro will add on enum `Event` the attributes: + /// * `#[derive(`[`frame_support::CloneNoBound`]`)]` + /// * `#[derive(`[`frame_support::EqNoBound`]`)]` + /// * `#[derive(`[`frame_support::PartialEqNoBound`]`)]` + /// * `#[derive(`[`frame_support::RuntimeDebugNoBound`]`)]` + /// * `#[derive(`[`codec::Encode`]`)]` + /// * `#[derive(`[`codec::Decode`]`)]` + /// + /// The macro implements `From>` for (). + /// + /// The macro implements a metadata function on `Event` returning the `EventMetadata`. + /// + /// If `#[pallet::generate_deposit]` is present then the macro implements `fn + /// deposit_event` on `Pallet`. + pub use frame_support_procedural::generate_deposit; + + /// Allows defining logic to make an extrinsic call feeless. + /// + /// Each dispatchable may be annotated with the `#[pallet::feeless_if($closure)]` + /// attribute, which explicitly defines the condition for the dispatchable to be feeless. + /// + /// The arguments for the closure must be the referenced arguments of the dispatchable + /// function. + /// + /// The closure must return `bool`. + /// + /// ### Example + /// + /// ``` + /// #[frame_support::pallet(dev_mode)] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # use frame_system::pallet_prelude::*; + /// # + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// + /// #[pallet::call] + /// impl Pallet { + /// #[pallet::call_index(0)] + /// /// Marks this call as feeless if `foo` is zero. + /// #[pallet::feeless_if(|_origin: &OriginFor, foo: &u32| -> bool { + /// *foo == 0 + /// })] + /// pub fn something( + /// _: OriginFor, + /// foo: u32, + /// ) -> DispatchResult { + /// unimplemented!() + /// } + /// } + /// # + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// } + /// ``` + /// + /// Please note that this only works for signed dispatchables and requires a signed + /// extension such as [`pallet_skip_feeless_payment::SkipCheckIfFeeless`] to wrap the + /// existing payment extension. Else, this is completely ignored and the dispatchable is + /// still charged. + /// + /// ### Macro expansion + /// + /// The macro implements the [`pallet_skip_feeless_payment::CheckIfFeeless`] trait on the + /// dispatchable and calls the corresponding closure in the implementation. + /// + /// [`pallet_skip_feeless_payment::SkipCheckIfFeeless`]: ../../pallet_skip_feeless_payment/struct.SkipCheckIfFeeless.html + /// [`pallet_skip_feeless_payment::CheckIfFeeless`]: ../../pallet_skip_feeless_payment/struct.SkipCheckIfFeeless.html + pub use frame_support_procedural::feeless_if; + + /// Allows defining an error enum that will be returned from the dispatchable when an error + /// occurs. + /// + /// The information for this error type is then stored in runtime metadata. + /// + /// Item must be defined as so: + /// + /// ``` + /// #[frame_support::pallet(dev_mode)] + /// mod pallet { + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// + /// #[pallet::error] + /// pub enum Error { + /// /// SomeFieldLessVariant doc + /// SomeFieldLessVariant, + /// /// SomeVariantWithOneField doc + /// SomeVariantWithOneField(u32), + /// } + /// # + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// } + /// ``` + /// I.e. a regular enum named `Error`, with generic `T` and fieldless or multiple-field + /// variants. + /// + /// Any field type in the enum variants must implement [`scale_info::TypeInfo`] in order to + /// be properly used in the metadata, and its encoded size should be as small as possible, + /// preferably 1 byte in size in order to reduce storage size. The error enum itself has an + /// absolute maximum encoded size specified by + /// [`frame_support::MAX_MODULE_ERROR_ENCODED_SIZE`]. + /// + /// (1 byte can still be 256 different errors. The more specific the error, the easier it + /// is to diagnose problems and give a better experience to the user. Don't skimp on having + /// lots of individual error conditions.) + /// + /// Field types in enum variants must also implement [`frame_support::PalletError`], + /// otherwise the pallet will fail to compile. Rust primitive types have already + /// implemented the [`frame_support::PalletError`] trait along with some commonly used + /// stdlib types such as [`Option`] and [`sp_std::marker::PhantomData`], and hence + /// in most use cases, a manual implementation is not necessary and is discouraged. + /// + /// The generic `T` must not bound anything and a `where` clause is not allowed. That said, + /// bounds and/or a where clause should not needed for any use-case. + /// + /// ## Macro expansion + /// + /// The macro implements the [`Debug`] trait and functions `as_u8` using variant position, + /// and `as_str` using variant doc. + /// + /// The macro also implements `From>` for `&'static str` and `From>` for + /// `DispatchError`. + pub use frame_support_procedural::error; + + /// Allows defining pallet events. + /// + /// Pallet events are stored under the `system` / `events` key when the block is applied + /// (and then replaced when the next block writes it's events). + /// + /// The Event enum can be defined as follows: + /// + /// ``` + /// #[frame_support::pallet(dev_mode)] + /// mod pallet { + /// # use frame_support::pallet_prelude::IsType; + /// # + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// + /// #[pallet::event] + /// #[pallet::generate_deposit(fn deposit_event)] // Optional + /// pub enum Event { + /// /// SomeEvent doc + /// SomeEvent(u16, u32), // SomeEvent with two fields + /// } + /// + /// #[pallet::config] + /// pub trait Config: frame_system::Config { + /// /// The overarching runtime event type. + /// type RuntimeEvent: From> + /// + IsType<::RuntimeEvent>; + /// } + /// } + /// ``` + /// + /// I.e. an enum (with named or unnamed fields variant), named `Event`, with generic: none + /// or `T` or `T: Config`, and optional w here clause. + /// + /// `RuntimeEvent` must be defined in the `Config`, as shown in the example. + /// + /// Each field must implement [`Clone`], [`Eq`], [`PartialEq`], [`codec::Encode`], + /// [`codec::Decode`], and [`Debug`] (on std only). For ease of use, bound by the trait + /// `Member`, available in [`frame_support::pallet_prelude`]. + pub use frame_support_procedural::event; - /// Allows a pallet to declare a set of functions as a *dispatchable extrinsic*. In - /// slightly simplified terms, this macro declares the set of "transactions" of a pallet. + /// Allows a pallet to declare a set of functions as a *dispatchable extrinsic*. + /// + /// In slightly simplified terms, this macro declares the set of "transactions" of a + /// pallet. /// /// > The exact definition of **extrinsic** can be found in /// > [`sp_runtime::generic::UncheckedExtrinsic`]. @@ -2391,14 +2003,24 @@ pub mod pallet_macros { /// If no `#[pallet::call]` exists, then a default implementation corresponding to the /// following code is automatically generated: /// - /// ```ignore - /// #[pallet::call] - /// impl Pallet {} + /// ``` + /// #[frame_support::pallet(dev_mode)] + /// mod pallet { + /// #[pallet::pallet] + /// pub struct Pallet(_); + /// + /// #[pallet::call] // <- automatically generated + /// impl Pallet {} // <- automatically generated + /// + /// #[pallet::config] + /// pub trait Config: frame_system::Config {} + /// } /// ``` pub use frame_support_procedural::call; - /// Enforce the index of a variant in the generated `enum Call`. See [`call`] for more - /// information. + /// Enforce the index of a variant in the generated `enum Call`. + /// + /// See [`call`] for more information. /// /// All call indexes start from 0, until it encounters a dispatchable function with a /// defined call index. The dispatchable function that lexically follows the function with @@ -2408,7 +2030,9 @@ pub mod pallet_macros { pub use frame_support_procedural::call_index; /// Declares the arguments of a [`call`] function to be encoded using - /// [`codec::Compact`]. This will results in smaller extrinsic encoding. + /// [`codec::Compact`]. + /// + /// This will results in smaller extrinsic encoding. /// /// A common example of `compact` is for numeric values that are often times far far away /// from their theoretical maximum. For example, in the context of a crypto-currency, the @@ -2504,8 +2128,8 @@ pub mod pallet_macros { /// ``` pub use frame_support_procedural::genesis_build; - /// The `#[pallet::constant]` attribute can be used to add an associated type trait bounded - /// by [`Get`](frame_support::pallet_prelude::Get) from [`pallet::config`](`macro@config`) + /// Allows adding an associated type trait bounded by + /// [`Get`](frame_support::pallet_prelude::Get) from [`pallet::config`](`macro@config`) /// into metadata. /// /// ## Example @@ -2526,9 +2150,10 @@ pub mod pallet_macros { /// ``` pub use frame_support_procedural::constant; - /// Declares a type alias as a storage item. Storage items are pointers to data stored - /// on-chain (the *blockchain state*), under a specific key. The exact key is dependent on - /// the type of the storage. + /// Declares a type alias as a storage item. + /// + /// Storage items are pointers to data stored on-chain (the *blockchain state*), under a + /// specific key. The exact key is dependent on the type of the storage. /// /// > From the perspective of this pallet, the entire blockchain state is abstracted behind /// > a key-value api, namely [`sp_io::storage`]. @@ -2730,7 +2355,10 @@ pub mod pallet_macros { /// } /// ``` pub use frame_support_procedural::storage; - /// This attribute is attached to a function inside an `impl` block annotated with + + /// Allows defining conditions for a task to run. + /// + /// This attribute is attached to a function inside an `impl` block annoated with /// [`pallet::tasks_experimental`](`tasks_experimental`) to define the conditions for a /// given work item to be valid. /// @@ -2738,29 +2366,39 @@ pub mod pallet_macros { /// should have the same signature as the function it is attached to, except that it should /// return a `bool` instead. pub use frame_support_procedural::task_condition; - /// This attribute is attached to a function inside an `impl` block annotated with + + /// Allows defining an index for a task. + /// + /// This attribute is attached to a function inside an `impl` block annoated with /// [`pallet::tasks_experimental`](`tasks_experimental`) to define the index of a given /// work item. /// /// It takes an integer literal as input, which is then used to define the index. This /// index should be unique for each function in the `impl` block. pub use frame_support_procedural::task_index; - /// This attribute is attached to a function inside an `impl` block annotated with - /// [`pallet::tasks_experimental`](`tasks_experimental`) to define an iterator over the - /// available work items for a task. + + /// Allows defining an iterator over available work items for a task. + /// + /// This attribute is attached to a function inside an `impl` block annoated with + /// [`pallet::tasks_experimental`](`tasks_experimental`). /// /// It takes an iterator as input that yields a tuple with same types as the function /// arguments. pub use frame_support_procedural::task_list; - /// This attribute is attached to a function inside an `impl` block annotated with + + /// Allows defining the weight of a task. + /// + /// This attribute is attached to a function inside an `impl` block annoated with /// [`pallet::tasks_experimental`](`tasks_experimental`) define the weight of a given work /// item. /// /// It takes a closure as input, which should return a `Weight` value. pub use frame_support_procedural::task_weight; + /// Allows you to define some service work that can be recognized by a script or an - /// off-chain worker. Such a script can then create and submit all such work items at any - /// given time. + /// off-chain worker. + /// + /// Such a script can then create and submit all such work items at any given time. /// /// These work items are defined as instances of the [`Task`](frame_support::traits::Task) /// trait. [`pallet:tasks_experimental`](`tasks_experimental`) when attached to an `impl` @@ -2814,7 +2452,7 @@ pub mod pallet_macros { /// } /// ``` /// - /// Or, more commonly used:/ + /// Or, more commonly used: /// /// ``` /// #[frame_support::pallet] @@ -2839,6 +2477,9 @@ pub mod pallet_macros { /// /// Modifying any pallet's origin type will cause the runtime level origin type to also /// change in encoding. If stored anywhere on-chain, this will require a data migration. + /// + /// Read more about origins at the [Origin Reference + /// Docs](../../polkadot_sdk_docs/reference_docs/frame_origin/index.html). pub use frame_support_procedural::origin; } -- GitLab From fd5f9292f500652e1d4792b09fb8ac60e1268ce4 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Mon, 4 Mar 2024 20:12:43 +0100 Subject: [PATCH 339/392] FRAME: Create `TransactionExtension` as a replacement for `SignedExtension` (#2280) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #2160 First part of [Extrinsic Horizon](https://github.com/paritytech/polkadot-sdk/issues/2415) Introduces a new trait `TransactionExtension` to replace `SignedExtension`. Introduce the idea of transactions which obey the runtime's extensions and have according Extension data (né Extra data) yet do not have hard-coded signatures. Deprecate the terminology of "Unsigned" when used for transactions/extrinsics owing to there now being "proper" unsigned transactions which obey the extension framework and "old-style" unsigned which do not. Instead we have __*General*__ for the former and __*Bare*__ for the latter. (Ultimately, the latter will be phased out as a type of transaction, and Bare will only be used for Inherents.) Types of extrinsic are now therefore: - Bare (no hardcoded signature, no Extra data; used to be known as "Unsigned") - Bare transactions (deprecated): Gossiped, validated with `ValidateUnsigned` (deprecated) and the `_bare_compat` bits of `TransactionExtension` (deprecated). - Inherents: Not gossiped, validated with `ProvideInherent`. - Extended (Extra data): Gossiped, validated via `TransactionExtension`. - Signed transactions (with a hardcoded signature). - General transactions (without a hardcoded signature). `TransactionExtension` differs from `SignedExtension` because: - A signature on the underlying transaction may validly not be present. - It may alter the origin during validation. - `pre_dispatch` is renamed to `prepare` and need not contain the checks present in `validate`. - `validate` and `prepare` is passed an `Origin` rather than a `AccountId`. - `validate` may pass arbitrary information into `prepare` via a new user-specifiable type `Val`. - `AdditionalSigned`/`additional_signed` is renamed to `Implicit`/`implicit`. It is encoded *for the entire transaction* and passed in to each extension as a new argument to `validate`. This facilitates the ability of extensions to acts as underlying crypto. There is a new `DispatchTransaction` trait which contains only default function impls and is impl'ed for any `TransactionExtension` impler. It provides several utility functions which reduce some of the tedium from using `TransactionExtension` (indeed, none of its regular functions should now need to be called directly). Three transaction version discriminator ("versions") are now permissible: - 0b000000100: Bare (used to be called "Unsigned"): contains Signature or Extra (extension data). After bare transactions are no longer supported, this will strictly identify an Inherents only. - 0b100000100: Old-school "Signed" Transaction: contains Signature and Extra (extension data). - 0b010000100: New-school "General" Transaction: contains Extra (extension data), but no Signature. For the New-school General Transaction, it becomes trivial for authors to publish extensions to the mechanism for authorizing an Origin, e.g. through new kinds of key-signing schemes, ZK proofs, pallet state, mutations over pre-authenticated origins or any combination of the above. ## Code Migration ### NOW: Getting it to build Wrap your `SignedExtension`s in `AsTransactionExtension`. This should be accompanied by renaming your aggregate type in line with the new terminology. E.g. Before: ```rust /// The SignedExtension to the basic transaction logic. pub type SignedExtra = ( /* snip */ MySpecialSignedExtension, ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; ``` After: ```rust /// The extension to the basic transaction logic. pub type TxExtension = ( /* snip */ AsTransactionExtension, ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; ``` You'll also need to alter any transaction building logic to add a `.into()` to make the conversion happen. E.g. Before: ```rust fn construct_extrinsic( /* snip */ ) -> UncheckedExtrinsic { let extra: SignedExtra = ( /* snip */ MySpecialSignedExtension::new(/* snip */), ); let payload = SignedPayload::new(call.clone(), extra.clone()).unwrap(); let signature = payload.using_encoded(|e| sender.sign(e)); UncheckedExtrinsic::new_signed( /* snip */ Signature::Sr25519(signature), extra, ) } ``` After: ```rust fn construct_extrinsic( /* snip */ ) -> UncheckedExtrinsic { let tx_ext: TxExtension = ( /* snip */ MySpecialSignedExtension::new(/* snip */).into(), ); let payload = SignedPayload::new(call.clone(), tx_ext.clone()).unwrap(); let signature = payload.using_encoded(|e| sender.sign(e)); UncheckedExtrinsic::new_signed( /* snip */ Signature::Sr25519(signature), tx_ext, ) } ``` ### SOON: Migrating to `TransactionExtension` Most `SignedExtension`s can be trivially converted to become a `TransactionExtension`. There are a few things to know. - Instead of a single trait like `SignedExtension`, you should now implement two traits individually: `TransactionExtensionBase` and `TransactionExtension`. - Weights are now a thing and must be provided via the new function `fn weight`. #### `TransactionExtensionBase` This trait takes care of anything which is not dependent on types specific to your runtime, most notably `Call`. - `AdditionalSigned`/`additional_signed` is renamed to `Implicit`/`implicit`. - Weight must be returned by implementing the `weight` function. If your extension is associated with a pallet, you'll probably want to do this via the pallet's existing benchmarking infrastructure. #### `TransactionExtension` Generally: - `pre_dispatch` is now `prepare` and you *should not reexecute the `validate` functionality in there*! - You don't get an account ID any more; you get an origin instead. If you need to presume an account ID, then you can use the trait function `AsSystemOriginSigner::as_system_origin_signer`. - You get an additional ticket, similar to `Pre`, called `Val`. This defines data which is passed from `validate` into `prepare`. This is important since you should not be duplicating logic from `validate` to `prepare`, you need a way of passing your working from the former into the latter. This is it. - This trait takes two type parameters: `Call` and `Context`. `Call` is the runtime call type which used to be an associated type; you can just move it to become a type parameter for your trait impl. `Context` is not currently used and you can safely implement over it as an unbounded type. - There's no `AccountId` associated type any more. Just remove it. Regarding `validate`: - You get three new parameters in `validate`; all can be ignored when migrating from `SignedExtension`. - `validate` returns a tuple on success; the second item in the tuple is the new ticket type `Self::Val` which gets passed in to `prepare`. If you use any information extracted during `validate` (off-chain and on-chain, non-mutating) in `prepare` (on-chain, mutating) then you can pass it through with this. For the tuple's last item, just return the `origin` argument. Regarding `prepare`: - This is renamed from `pre_dispatch`, but there is one change: - FUNCTIONALITY TO VALIDATE THE TRANSACTION NEED NOT BE DUPLICATED FROM `validate`!! - (This is different to `SignedExtension` which was required to run the same checks in `pre_dispatch` as in `validate`.) Regarding `post_dispatch`: - Since there are no unsigned transactions handled by `TransactionExtension`, `Pre` is always defined, so the first parameter is `Self::Pre` rather than `Option`. If you make use of `SignedExtension::validate_unsigned` or `SignedExtension::pre_dispatch_unsigned`, then: - Just use the regular versions of these functions instead. - Have your logic execute in the case that the `origin` is `None`. - Ensure your transaction creation logic creates a General Transaction rather than a Bare Transaction; this means having to include all `TransactionExtension`s' data. - `ValidateUnsigned` can still be used (for now) if you need to be able to construct transactions which contain none of the extension data, however these will be phased out in stage 2 of the Transactions Horizon, so you should consider moving to an extension-centric design. ## TODO - [x] Introduce `CheckSignature` impl of `TransactionExtension` to ensure it's possible to have crypto be done wholly in a `TransactionExtension`. - [x] Deprecate `SignedExtension` and move all uses in codebase to `TransactionExtension`. - [x] `ChargeTransactionPayment` - [x] `DummyExtension` - [x] `ChargeAssetTxPayment` (asset-tx-payment) - [x] `ChargeAssetTxPayment` (asset-conversion-tx-payment) - [x] `CheckWeight` - [x] `CheckTxVersion` - [x] `CheckSpecVersion` - [x] `CheckNonce` - [x] `CheckNonZeroSender` - [x] `CheckMortality` - [x] `CheckGenesis` - [x] `CheckOnlySudoAccount` - [x] `WatchDummy` - [x] `PrevalidateAttests` - [x] `GenericSignedExtension` - [x] `SignedExtension` (chain-polkadot-bulletin) - [x] `RefundSignedExtensionAdapter` - [x] Implement `fn weight` across the board. - [ ] Go through all pre-existing extensions which assume an account signer and explicitly handle the possibility of another kind of origin. - [x] `CheckNonce` should probably succeed in the case of a non-account origin. - [x] `CheckNonZeroSender` should succeed in the case of a non-account origin. - [x] `ChargeTransactionPayment` and family should fail in the case of a non-account origin. - [ ] - [x] Fix any broken tests. --------- Signed-off-by: georgepisaltu Signed-off-by: Alexandru Vasile Signed-off-by: dependabot[bot] Signed-off-by: Oliver Tale-Yazdi Signed-off-by: Alexandru Gheorghe Signed-off-by: Andrei Sandu Co-authored-by: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Co-authored-by: georgepisaltu <52418509+georgepisaltu@users.noreply.github.com> Co-authored-by: Chevdor Co-authored-by: Bastian Köcher Co-authored-by: Maciej Co-authored-by: Javier Viola Co-authored-by: Marcin S. Co-authored-by: Tsvetomir Dimitrov Co-authored-by: Javier Bullrich Co-authored-by: Koute Co-authored-by: Adrian Catangiu Co-authored-by: Vladimir Istyufeev Co-authored-by: Ross Bulat Co-authored-by: Gonçalo Pestana Co-authored-by: Liam Aharon Co-authored-by: Svyatoslav Nikolsky Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> Co-authored-by: Oliver Tale-Yazdi Co-authored-by: s0me0ne-unkn0wn <48632512+s0me0ne-unkn0wn@users.noreply.github.com> Co-authored-by: ordian Co-authored-by: Sebastian Kunert Co-authored-by: Aaro Altonen <48052676+altonen@users.noreply.github.com> Co-authored-by: Dmitry Markin Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> Co-authored-by: Alexander Samusev <41779041+alvicsam@users.noreply.github.com> Co-authored-by: Julian Eager Co-authored-by: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Co-authored-by: Davide Galassi Co-authored-by: Dónal Murray Co-authored-by: yjh Co-authored-by: Tom Mi Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Will | Paradox | ParaNodes.io <79228812+paradox-tt@users.noreply.github.com> Co-authored-by: Bastian Köcher Co-authored-by: Joshy Orndorff Co-authored-by: Joshy Orndorff Co-authored-by: PG Herveou Co-authored-by: Alexander Theißen Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Juan Girini Co-authored-by: bader y Co-authored-by: James Wilson Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Co-authored-by: asynchronous rob Co-authored-by: Parth Co-authored-by: Andrew Jones Co-authored-by: Jonathan Udd Co-authored-by: Serban Iorga Co-authored-by: Egor_P Co-authored-by: Branislav Kontur Co-authored-by: Evgeny Snitko Co-authored-by: Just van Stam Co-authored-by: Francisco Aguirre Co-authored-by: gupnik Co-authored-by: dzmitry-lahoda Co-authored-by: zhiqiangxu <652732310@qq.com> Co-authored-by: Nazar Mokrynskyi Co-authored-by: Anwesh Co-authored-by: cheme Co-authored-by: Sam Johnson Co-authored-by: kianenigma Co-authored-by: Jegor Sidorenko <5252494+jsidorenko@users.noreply.github.com> Co-authored-by: Muharem Co-authored-by: joepetrowski Co-authored-by: Alexandru Gheorghe <49718502+alexggh@users.noreply.github.com> Co-authored-by: Gabriel Facco de Arruda Co-authored-by: Squirrel Co-authored-by: Andrei Sandu <54316454+sandreim@users.noreply.github.com> Co-authored-by: georgepisaltu Co-authored-by: command-bot <> --- Cargo.lock | 35 +- bridges/bin/runtime-common/Cargo.toml | 1 + bridges/bin/runtime-common/src/lib.rs | 72 +- bridges/bin/runtime-common/src/mock.rs | 2 +- .../runtime-common/src/priority_calculator.rs | 11 +- .../src/refund_relayer_extension.rs | 154 +- .../chain-bridge-hub-cumulus/src/lib.rs | 4 +- .../chain-bridge-hub-rococo/src/lib.rs | 2 +- bridges/primitives/chain-kusama/src/lib.rs | 4 +- .../chain-polkadot-bulletin/src/lib.rs | 51 +- bridges/primitives/chain-polkadot/src/lib.rs | 4 +- bridges/primitives/chain-rococo/src/lib.rs | 4 +- bridges/primitives/chain-westend/src/lib.rs | 4 +- bridges/primitives/polkadot-core/src/lib.rs | 37 +- bridges/primitives/runtime/src/extensions.rs | 135 +- .../snowbridge/runtime/test-common/Cargo.toml | 1 + cumulus/parachain-template/runtime/Cargo.toml | 2 + cumulus/parachain-template/runtime/src/lib.rs | 10 +- .../assets/asset-hub-rococo/Cargo.toml | 2 + .../assets/asset-hub-rococo/src/lib.rs | 77 +- .../src/weights/frame_system_extensions.rs | 121 + .../asset-hub-rococo/src/weights/mod.rs | 3 + .../pallet_asset_conversion_tx_payment.rs | 92 + .../src/weights/pallet_transaction_payment.rs | 67 + .../assets/asset-hub-westend/Cargo.toml | 2 + .../assets/asset-hub-westend/src/lib.rs | 77 +- .../src/weights/frame_system_extensions.rs | 121 + .../asset-hub-westend/src/weights/mod.rs | 3 + .../pallet_asset_conversion_tx_payment.rs | 92 + .../src/weights/pallet_transaction_payment.rs | 67 + .../bridge-hubs/bridge-hub-rococo/Cargo.toml | 1 + .../src/bridge_to_bulletin_config.rs | 4 +- .../src/bridge_to_westend_config.rs | 4 +- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 27 +- .../src/weights/frame_system_extensions.rs | 121 + .../bridge-hub-rococo/src/weights/mod.rs | 2 + .../src/weights/pallet_transaction_payment.rs | 67 + .../bridge-hub-rococo/tests/snowbridge.rs | 8 +- .../bridge-hub-rococo/tests/tests.rs | 11 +- .../bridge-hubs/bridge-hub-westend/Cargo.toml | 1 + .../src/bridge_to_rococo_config.rs | 4 +- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 25 +- .../src/weights/frame_system_extensions.rs | 121 + .../bridge-hub-westend/src/weights/mod.rs | 2 + .../src/weights/pallet_transaction_payment.rs | 67 + .../bridge-hub-westend/tests/tests.rs | 11 +- .../collectives-westend/Cargo.toml | 1 + .../collectives-westend/src/lib.rs | 12 +- .../src/weights/frame_system_extensions.rs | 121 + .../collectives-westend/src/weights/mod.rs | 2 + .../src/weights/pallet_transaction_payment.rs | 67 + .../contracts/contracts-rococo/Cargo.toml | 1 + .../contracts/contracts-rococo/src/lib.rs | 10 +- .../coretime/coretime-rococo/Cargo.toml | 1 + .../coretime/coretime-rococo/src/lib.rs | 9 +- .../src/weights/frame_system_extensions.rs | 121 + .../coretime-rococo/src/weights/mod.rs | 2 + .../src/weights/pallet_transaction_payment.rs | 67 + .../coretime/coretime-westend/Cargo.toml | 1 + .../coretime/coretime-westend/src/lib.rs | 9 +- .../src/weights/frame_system_extensions.rs | 121 + .../coretime-westend/src/weights/mod.rs | 2 + .../src/weights/pallet_transaction_payment.rs | 67 + .../glutton/glutton-westend/src/lib.rs | 9 +- .../src/weights/frame_system_extensions.rs | 119 + .../runtimes/people/people-rococo/Cargo.toml | 1 + .../runtimes/people/people-rococo/src/lib.rs | 9 +- .../src/weights/frame_system_extensions.rs | 121 + .../people/people-rococo/src/weights/mod.rs | 2 + .../src/weights/pallet_transaction_payment.rs | 67 + .../runtimes/people/people-westend/Cargo.toml | 1 + .../runtimes/people/people-westend/src/lib.rs | 8 +- .../src/weights/frame_system_extensions.rs | 121 + .../people/people-westend/src/weights/mod.rs | 2 + .../src/weights/pallet_transaction_payment.rs | 67 + .../runtimes/starters/seedling/src/lib.rs | 6 +- .../runtimes/starters/shell/src/lib.rs | 64 +- .../runtimes/testing/penpal/Cargo.toml | 1 + .../runtimes/testing/penpal/src/lib.rs | 26 +- .../testing/rococo-parachain/Cargo.toml | 1 + .../testing/rococo-parachain/src/lib.rs | 7 +- cumulus/polkadot-parachain/Cargo.toml | 1 + .../storage-weight-reclaim/Cargo.toml | 13 +- .../src/benchmarking.rs | 70 + .../storage-weight-reclaim/src/lib.rs | 522 +--- .../storage-weight-reclaim/src/tests.rs | 484 ++++ cumulus/test/client/Cargo.toml | 2 + cumulus/test/client/src/lib.rs | 13 +- cumulus/test/runtime/src/lib.rs | 9 +- cumulus/test/service/Cargo.toml | 2 + cumulus/test/service/src/bench_utils.rs | 4 +- cumulus/test/service/src/lib.rs | 9 +- .../src/reference_docs/extrinsic_encoding.rs | 101 +- .../src/reference_docs/frame_runtime_types.rs | 2 +- docs/sdk/src/reference_docs/mod.rs | 4 +- .../src/reference_docs/signed_extensions.rs | 79 - .../reference_docs/transaction_extensions.rs | 57 + polkadot/node/service/Cargo.toml | 1 + polkadot/node/service/src/benchmarking.rs | 18 +- polkadot/node/test/service/Cargo.toml | 1 + polkadot/node/test/service/src/lib.rs | 11 +- polkadot/runtime/common/Cargo.toml | 1 + polkadot/runtime/common/src/claims.rs | 150 +- polkadot/runtime/rococo/Cargo.toml | 1 + .../constants/src/weights/block_weights.rs | 29 +- .../src/weights/extrinsic_weights.rs | 29 +- polkadot/runtime/rococo/src/lib.rs | 45 +- .../weights/frame_benchmarking_baseline.rs | 43 +- .../rococo/src/weights/frame_system.rs | 103 +- .../src/weights/frame_system_extensions.rs | 123 + polkadot/runtime/rococo/src/weights/mod.rs | 2 + .../rococo/src/weights/pallet_asset_rate.rs | 63 +- .../src/weights/pallet_balances_balances.rs | 58 +- ...allet_balances_nis_counterpart_balances.rs | 58 +- .../rococo/src/weights/pallet_bounties.rs | 218 +- .../src/weights/pallet_child_bounties.rs | 181 +- .../src/weights/pallet_conviction_voting.rs | 196 +- .../rococo/src/weights/pallet_identity.rs | 409 +-- .../rococo/src/weights/pallet_indices.rs | 73 +- .../src/weights/pallet_message_queue.rs | 168 +- .../rococo/src/weights/pallet_multisig.rs | 123 +- .../runtime/rococo/src/weights/pallet_nis.rs | 243 +- .../rococo/src/weights/pallet_preimage.rs | 252 +- .../rococo/src/weights/pallet_proxy.rs | 195 +- .../src/weights/pallet_ranked_collective.rs | 66 +- .../rococo/src/weights/pallet_recovery.rs | 186 ++ .../pallet_referenda_fellowship_referenda.rs | 235 +- .../src/weights/pallet_referenda_referenda.rs | 283 +-- .../rococo/src/weights/pallet_scheduler.rs | 146 +- .../runtime/rococo/src/weights/pallet_sudo.rs | 45 +- .../rococo/src/weights/pallet_timestamp.rs | 35 +- .../src/weights/pallet_transaction_payment.rs | 68 + .../rococo/src/weights/pallet_treasury.rs | 233 +- .../rococo/src/weights/pallet_utility.rs | 47 +- .../rococo/src/weights/pallet_vesting.rs | 254 +- .../rococo/src/weights/pallet_whitelist.rs | 68 +- .../runtime/rococo/src/weights/pallet_xcm.rs | 90 +- .../weights/pallet_xcm_benchmarks_fungible.rs | 191 ++ .../weights/pallet_xcm_benchmarks_generic.rs | 347 +++ .../weights/runtime_common_assigned_slots.rs | 70 +- .../src/weights/runtime_common_auctions.rs | 137 +- .../src/weights/runtime_common_claims.rs | 180 +- .../src/weights/runtime_common_coretime.rs | 86 + .../src/weights/runtime_common_crowdloan.rs | 239 +- .../runtime_common_identity_migrator.rs | 83 +- .../weights/runtime_common_paras_registrar.rs | 281 ++- .../src/weights/runtime_common_slots.rs | 127 +- .../runtime_parachains_assigner_on_demand.rs | 50 +- .../runtime_parachains_configuration.rs | 48 +- .../weights/runtime_parachains_disputes.rs | 23 +- .../src/weights/runtime_parachains_hrmp.rs | 389 ++- .../weights/runtime_parachains_inclusion.rs | 45 +- .../weights/runtime_parachains_initializer.rs | 27 +- .../src/weights/runtime_parachains_paras.rs | 368 +-- .../runtime_parachains_paras_inherent.rs | 429 +++- polkadot/runtime/test-runtime/Cargo.toml | 1 + polkadot/runtime/test-runtime/src/lib.rs | 40 +- polkadot/runtime/westend/Cargo.toml | 1 + polkadot/runtime/westend/src/lib.rs | 25 +- .../src/weights/frame_system_extensions.rs | 116 + polkadot/runtime/westend/src/weights/mod.rs | 2 + .../westend/src/weights/pallet_sudo.rs | 11 + .../src/weights/pallet_transaction_payment.rs | 65 + polkadot/xcm/xcm-builder/Cargo.toml | 1 + .../xcm/xcm-builder/src/tests/pay/mock.rs | 12 +- .../xcm/xcm-simulator/fuzzer/src/parachain.rs | 4 +- .../xcm-simulator/fuzzer/src/relay_chain.rs | 4 +- prdoc/pr_2280.prdoc | 144 ++ substrate/.maintain/frame-weight-template.hbs | 2 +- substrate/bin/minimal/runtime/src/lib.rs | 4 +- substrate/bin/node-template/node/Cargo.toml | 1 + .../node-template/node/src/benchmarking.rs | 9 +- .../bin/node-template/runtime/Cargo.toml | 1 + .../bin/node-template/runtime/src/lib.rs | 12 +- substrate/bin/node/cli/Cargo.toml | 2 + .../bin/node/cli/benches/block_production.rs | 2 +- substrate/bin/node/cli/benches/executor.rs | 6 +- substrate/bin/node/cli/src/service.rs | 77 +- substrate/bin/node/cli/tests/basic.rs | 26 +- substrate/bin/node/cli/tests/fees.rs | 24 +- .../bin/node/cli/tests/submit_transaction.rs | 10 +- substrate/bin/node/runtime/Cargo.toml | 2 + substrate/bin/node/runtime/src/lib.rs | 165 +- substrate/bin/node/testing/src/bench.rs | 26 +- substrate/bin/node/testing/src/keyring.rs | 44 +- .../client/api/src/notifications/tests.rs | 7 +- substrate/client/db/benches/state_access.rs | 5 +- substrate/client/db/src/lib.rs | 262 +- substrate/client/db/src/utils.rs | 11 +- .../network-gossip/src/state_machine.rs | 5 +- substrate/client/network/sync/src/blocks.rs | 7 +- substrate/client/transaction-pool/src/lib.rs | 9 +- substrate/frame/alliance/src/weights.rs | 1033 ++++---- .../frame/asset-conversion/src/weights.rs | 126 +- substrate/frame/asset-rate/src/weights.rs | 73 +- substrate/frame/assets/src/weights.rs | 841 +++---- substrate/frame/babe/src/mock.rs | 5 +- substrate/frame/bags-list/src/weights.rs | 165 +- substrate/frame/balances/Cargo.toml | 1 + .../balances/src/tests/currency_tests.rs | 17 +- substrate/frame/balances/src/tests/mod.rs | 4 +- substrate/frame/balances/src/weights.rs | 98 +- substrate/frame/beefy/src/mock.rs | 6 +- substrate/frame/benchmarking/src/weights.rs | 81 +- substrate/frame/bounties/src/weights.rs | 405 ++- substrate/frame/broker/src/weights.rs | 357 +-- substrate/frame/child-bounties/src/weights.rs | 381 ++- substrate/frame/collective/src/tests.rs | 2 +- substrate/frame/collective/src/weights.rs | 677 ++--- substrate/frame/contracts/src/weights.rs | 2222 +++++++++-------- .../frame/conviction-voting/src/weights.rs | 405 +-- .../frame/core-fellowship/src/weights.rs | 429 ++-- substrate/frame/democracy/src/weights.rs | 1093 ++++---- .../election-provider-multi-phase/src/mock.rs | 2 +- .../src/unsigned.rs | 4 +- .../src/weights.rs | 517 ++-- .../test-staking-e2e/src/mock.rs | 4 +- substrate/frame/elections-phragmen/src/lib.rs | 2 +- .../frame/elections-phragmen/src/weights.rs | 655 ++--- substrate/frame/examples/basic/src/lib.rs | 76 +- substrate/frame/examples/basic/src/tests.rs | 9 +- .../examples/offchain-worker/src/tests.rs | 22 +- substrate/frame/examples/tasks/src/weights.rs | 78 +- substrate/frame/executive/src/tests.rs | 225 +- substrate/frame/fast-unstake/src/weights.rs | 473 ++-- substrate/frame/glutton/src/weights.rs | 249 +- substrate/frame/grandpa/src/mock.rs | 9 +- substrate/frame/identity/src/weights.rs | 825 +++--- substrate/frame/im-online/src/mock.rs | 4 +- substrate/frame/im-online/src/tests.rs | 4 +- substrate/frame/im-online/src/weights.rs | 85 +- substrate/frame/indices/src/weights.rs | 121 +- substrate/frame/lottery/src/weights.rs | 301 +-- substrate/frame/membership/src/weights.rs | 385 ++- substrate/frame/message-queue/src/weights.rs | 247 +- substrate/frame/migrations/src/weights.rs | 183 +- substrate/frame/multisig/src/weights.rs | 243 +- .../nft-fractionalization/src/weights.rs | 209 +- substrate/frame/nfts/src/weights.rs | 1692 ++++++------- substrate/frame/nis/src/weights.rs | 429 ++-- .../frame/nomination-pools/src/weights.rs | 258 +- .../frame/offences/benchmarking/src/mock.rs | 2 +- substrate/frame/parameters/src/weights.rs | 38 +- substrate/frame/preimage/src/weights.rs | 332 +-- substrate/frame/proxy/src/weights.rs | 377 +-- .../frame/ranked-collective/src/weights.rs | 353 +-- substrate/frame/recovery/src/weights.rs | 305 +-- substrate/frame/referenda/src/weights.rs | 1037 ++++---- substrate/frame/remark/src/weights.rs | 37 +- substrate/frame/safe-mode/src/weights.rs | 142 +- substrate/frame/salary/src/weights.rs | 217 +- substrate/frame/sassafras/src/mock.rs | 5 +- substrate/frame/scheduler/src/weights.rs | 266 +- substrate/frame/session/src/weights.rs | 117 +- substrate/frame/society/src/weights.rs | 974 ++++++-- substrate/frame/src/lib.rs | 6 +- substrate/frame/staking/src/weights.rs | 422 ++-- .../frame/state-trie-migration/src/lib.rs | 2 +- .../frame/state-trie-migration/src/weights.rs | 118 +- substrate/frame/sudo/src/benchmarking.rs | 29 +- substrate/frame/sudo/src/extension.rs | 78 +- substrate/frame/sudo/src/lib.rs | 4 +- substrate/frame/sudo/src/weights.rs | 71 +- substrate/frame/support/Cargo.toml | 2 +- .../src/construct_runtime/expand/inherent.rs | 18 +- .../src/construct_runtime/expand/metadata.rs | 6 +- .../src/construct_runtime/expand/origin.rs | 14 + substrate/frame/support/src/dispatch.rs | 29 +- substrate/frame/support/src/lib.rs | 8 +- .../frame/support/src/traits/dispatch.rs | 21 +- substrate/frame/support/src/traits/misc.rs | 13 +- .../support/src/transaction_extensions.rs | 89 + .../support/src/weights/block_weights.rs | 31 +- .../support/src/weights/extrinsic_weights.rs | 31 +- .../support/test/tests/construct_runtime.rs | 2 +- .../deprecated_where_block.stderr | 4 +- substrate/frame/support/test/tests/pallet.rs | 143 +- .../support/test/tests/pallet_instance.rs | 2 +- .../system/benchmarking/src/extensions.rs | 213 ++ .../frame/system/benchmarking/src/lib.rs | 1 + .../frame/system/benchmarking/src/mock.rs | 1 + .../system/src/extensions/check_genesis.rs | 33 +- .../system/src/extensions/check_mortality.rs | 83 +- .../src/extensions/check_non_zero_sender.rs | 95 +- .../system/src/extensions/check_nonce.rs | 184 +- .../src/extensions/check_spec_version.rs | 33 +- .../system/src/extensions/check_tx_version.rs | 32 +- .../system/src/extensions/check_weight.rs | 228 +- substrate/frame/system/src/extensions/mod.rs | 3 + .../frame/system/src/extensions/weights.rs | 196 ++ substrate/frame/system/src/lib.rs | 10 +- substrate/frame/system/src/offchain.rs | 22 +- substrate/frame/system/src/weights.rs | 249 +- substrate/frame/timestamp/src/weights.rs | 65 +- substrate/frame/tips/src/weights.rs | 241 +- .../frame/transaction-payment/Cargo.toml | 9 + .../asset-conversion-tx-payment/Cargo.toml | 12 + .../asset-conversion-tx-payment/README.md | 2 +- .../src/benchmarking.rs | 125 + .../asset-conversion-tx-payment/src/lib.rs | 233 +- .../asset-conversion-tx-payment/src/mock.rs | 70 +- .../asset-conversion-tx-payment/src/tests.rs | 150 +- .../src/weights.rs | 150 ++ .../asset-tx-payment/Cargo.toml | 1 + .../asset-tx-payment/README.md | 2 +- .../asset-tx-payment/src/benchmarking.rs | 123 + .../asset-tx-payment/src/lib.rs | 199 +- .../asset-tx-payment/src/mock.rs | 54 +- .../asset-tx-payment/src/tests.rs | 184 +- .../asset-tx-payment/src/weights.rs | 146 ++ .../skip-feeless-payment/src/lib.rs | 111 +- .../skip-feeless-payment/src/mock.rs | 30 +- .../skip-feeless-payment/src/tests.rs | 5 +- .../transaction-payment/src/benchmarking.rs | 81 + .../frame/transaction-payment/src/lib.rs | 146 +- .../frame/transaction-payment/src/mock.rs | 10 + .../frame/transaction-payment/src/payment.rs | 56 +- .../frame/transaction-payment/src/tests.rs | 444 ++-- .../frame/transaction-payment/src/types.rs | 2 +- .../frame/transaction-payment/src/weights.rs | 92 + .../frame/transaction-storage/src/weights.rs | 185 +- substrate/frame/treasury/src/weights.rs | 348 +-- substrate/frame/tx-pause/src/weights.rs | 38 +- substrate/frame/uniques/src/weights.rs | 368 +-- substrate/frame/utility/src/weights.rs | 161 +- substrate/frame/vesting/src/weights.rs | 234 +- substrate/frame/whitelist/src/weights.rs | 193 +- substrate/primitives/inherents/src/lib.rs | 4 +- substrate/primitives/metadata-ir/src/lib.rs | 2 +- substrate/primitives/metadata-ir/src/types.rs | 19 +- substrate/primitives/metadata-ir/src/v14.rs | 10 +- substrate/primitives/metadata-ir/src/v15.rs | 8 +- substrate/primitives/runtime/Cargo.toml | 2 + .../runtime/src/generic/checked_extrinsic.rs | 112 +- .../primitives/runtime/src/generic/mod.rs | 4 +- .../src/generic/unchecked_extrinsic.rs | 730 ++++-- substrate/primitives/runtime/src/lib.rs | 19 +- substrate/primitives/runtime/src/testing.rs | 195 +- .../runtime/src/{traits.rs => traits/mod.rs} | 244 +- .../as_transaction_extension.rs | 133 + .../dispatch_transaction.rs | 141 ++ .../src/traits/transaction_extension/mod.rs | 526 ++++ .../runtime/src/transaction_validity.rs | 6 +- substrate/scripts/run_all_benchmarks.sh | 13 + substrate/test-utils/runtime/src/extrinsic.rs | 17 +- substrate/test-utils/runtime/src/lib.rs | 93 +- .../benchmarking-cli/src/pallet/template.hbs | 4 + .../frame/remote-externalities/src/lib.rs | 5 +- substrate/utils/frame/rpc/client/src/lib.rs | 8 +- 349 files changed, 25345 insertions(+), 16846 deletions(-) create mode 100644 cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/frame_system_extensions.rs create mode 100644 cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_asset_conversion_tx_payment.rs create mode 100644 cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_transaction_payment.rs create mode 100644 cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/frame_system_extensions.rs create mode 100644 cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_asset_conversion_tx_payment.rs create mode 100644 cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_transaction_payment.rs create mode 100644 cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/frame_system_extensions.rs create mode 100644 cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_transaction_payment.rs create mode 100644 cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/frame_system_extensions.rs create mode 100644 cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_transaction_payment.rs create mode 100644 cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/frame_system_extensions.rs create mode 100644 cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_transaction_payment.rs create mode 100644 cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system_extensions.rs create mode 100644 cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_transaction_payment.rs create mode 100644 cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/frame_system_extensions.rs create mode 100644 cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_transaction_payment.rs create mode 100644 cumulus/parachains/runtimes/glutton/glutton-westend/src/weights/frame_system_extensions.rs create mode 100644 cumulus/parachains/runtimes/people/people-rococo/src/weights/frame_system_extensions.rs create mode 100644 cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_transaction_payment.rs create mode 100644 cumulus/parachains/runtimes/people/people-westend/src/weights/frame_system_extensions.rs create mode 100644 cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_transaction_payment.rs create mode 100644 cumulus/primitives/storage-weight-reclaim/src/benchmarking.rs create mode 100644 cumulus/primitives/storage-weight-reclaim/src/tests.rs delete mode 100644 docs/sdk/src/reference_docs/signed_extensions.rs create mode 100644 docs/sdk/src/reference_docs/transaction_extensions.rs create mode 100644 polkadot/runtime/rococo/src/weights/frame_system_extensions.rs create mode 100644 polkadot/runtime/rococo/src/weights/pallet_recovery.rs create mode 100644 polkadot/runtime/rococo/src/weights/pallet_transaction_payment.rs create mode 100644 polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_fungible.rs create mode 100644 polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_generic.rs create mode 100644 polkadot/runtime/rococo/src/weights/runtime_common_coretime.rs create mode 100644 polkadot/runtime/westend/src/weights/frame_system_extensions.rs create mode 100644 polkadot/runtime/westend/src/weights/pallet_transaction_payment.rs create mode 100644 prdoc/pr_2280.prdoc create mode 100644 substrate/frame/support/src/transaction_extensions.rs create mode 100644 substrate/frame/system/benchmarking/src/extensions.rs create mode 100644 substrate/frame/system/src/extensions/weights.rs create mode 100644 substrate/frame/transaction-payment/asset-conversion-tx-payment/src/benchmarking.rs create mode 100644 substrate/frame/transaction-payment/asset-conversion-tx-payment/src/weights.rs create mode 100644 substrate/frame/transaction-payment/asset-tx-payment/src/benchmarking.rs create mode 100644 substrate/frame/transaction-payment/asset-tx-payment/src/weights.rs create mode 100644 substrate/frame/transaction-payment/src/benchmarking.rs create mode 100644 substrate/frame/transaction-payment/src/weights.rs rename substrate/primitives/runtime/src/{traits.rs => traits/mod.rs} (94%) create mode 100644 substrate/primitives/runtime/src/traits/transaction_extension/as_transaction_extension.rs create mode 100644 substrate/primitives/runtime/src/traits/transaction_extension/dispatch_transaction.rs create mode 100644 substrate/primitives/runtime/src/traits/transaction_extension/mod.rs diff --git a/Cargo.lock b/Cargo.lock index ad218001b40..81881984378 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4070,11 +4070,13 @@ dependencies = [ "cumulus-primitives-proof-size-hostfunction", "cumulus-test-runtime", "docify 0.2.7", + "frame-benchmarking", "frame-support", "frame-system", "log", "parity-scale-codec", "scale-info", + "sp-core", "sp-io", "sp-runtime", "sp-std 14.0.0", @@ -5938,7 +5940,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29f9df8a11882c4e3335eb2d18a0137c505d9ca927470b0cac9c6f0ae07d28f7" dependencies = [ - "rustix 0.38.21", + "rustix 0.38.25", "windows-sys 0.48.0", ] @@ -6827,7 +6829,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi 0.3.2", - "rustix 0.38.21", + "rustix 0.38.25", "windows-sys 0.48.0", ] @@ -7834,9 +7836,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" [[package]] name = "lioness" @@ -9177,6 +9179,7 @@ dependencies = [ name = "pallet-asset-conversion-tx-payment" version = "10.0.0" dependencies = [ + "frame-benchmarking", "frame-support", "frame-system", "pallet-asset-conversion", @@ -11119,6 +11122,7 @@ dependencies = [ name = "pallet-transaction-payment" version = "28.0.0" dependencies = [ + "frame-benchmarking", "frame-support", "frame-system", "pallet-balances", @@ -14333,7 +14337,7 @@ dependencies = [ "hex", "lazy_static", "procfs-core", - "rustix 0.38.21", + "rustix 0.38.25", ] [[package]] @@ -15458,14 +15462,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" dependencies = [ "bitflags 2.4.0", "errno", "libc", - "linux-raw-sys 0.4.10", + "linux-raw-sys 0.4.11", "windows-sys 0.48.0", ] @@ -18721,7 +18725,7 @@ dependencies = [ [[package]] name = "sp-crypto-ec-utils" version = "0.4.1" -source = "git+https://github.com/paritytech/polkadot-sdk#82912acb33a9030c0ef3bf590a34fca09b72dc5f" +source = "git+https://github.com/paritytech/polkadot-sdk#838a534da874cf6071fba1df07643c6c5b033ae0" dependencies = [ "ark-bls12-377", "ark-bls12-377-ext", @@ -19026,6 +19030,7 @@ dependencies = [ "sp-tracing 16.0.0", "sp-weights", "substrate-test-runtime-client", + "tuplex", "zstd 0.12.4", ] @@ -19074,7 +19079,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#82912acb33a9030c0ef3bf590a34fca09b72dc5f" +source = "git+https://github.com/paritytech/polkadot-sdk#838a534da874cf6071fba1df07643c6c5b033ae0" dependencies = [ "Inflector", "proc-macro-crate 1.3.1", @@ -20293,7 +20298,7 @@ dependencies = [ "cfg-if", "fastrand 2.0.0", "redox_syscall 0.4.1", - "rustix 0.38.21", + "rustix 0.38.25", "windows-sys 0.48.0", ] @@ -20312,7 +20317,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "rustix 0.38.21", + "rustix 0.38.25", "windows-sys 0.48.0", ] @@ -21158,6 +21163,12 @@ dependencies = [ "utf-8", ] +[[package]] +name = "tuplex" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "676ac81d5454c4dcf37955d34fa8626ede3490f744b86ca14a7b90168d2a08aa" + [[package]] name = "twox-hash" version = "1.6.3" diff --git a/bridges/bin/runtime-common/Cargo.toml b/bridges/bin/runtime-common/Cargo.toml index fac88b20ca5..ee54f15f38b 100644 --- a/bridges/bin/runtime-common/Cargo.toml +++ b/bridges/bin/runtime-common/Cargo.toml @@ -93,6 +93,7 @@ runtime-benchmarks = [ "pallet-bridge-messages/runtime-benchmarks", "pallet-bridge-parachains/runtime-benchmarks", "pallet-bridge-relayers/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", diff --git a/bridges/bin/runtime-common/src/lib.rs b/bridges/bin/runtime-common/src/lib.rs index 2722f6f1c6d..035077408c4 100644 --- a/bridges/bin/runtime-common/src/lib.rs +++ b/bridges/bin/runtime-common/src/lib.rs @@ -105,43 +105,48 @@ macro_rules! generate_bridge_reject_obsolete_headers_and_messages { ($call:ty, $account_id:ty, $($filter_call:ty),*) => { #[derive(Clone, codec::Decode, Default, codec::Encode, Eq, PartialEq, sp_runtime::RuntimeDebug, scale_info::TypeInfo)] pub struct BridgeRejectObsoleteHeadersAndMessages; - impl sp_runtime::traits::SignedExtension for BridgeRejectObsoleteHeadersAndMessages { + impl sp_runtime::traits::TransactionExtensionBase for BridgeRejectObsoleteHeadersAndMessages { const IDENTIFIER: &'static str = "BridgeRejectObsoleteHeadersAndMessages"; - type AccountId = $account_id; - type Call = $call; - type AdditionalSigned = (); + type Implicit = (); + } + impl sp_runtime::traits::TransactionExtension<$call, Context> for BridgeRejectObsoleteHeadersAndMessages { type Pre = (); - - fn additional_signed(&self) -> sp_std::result::Result< - (), - sp_runtime::transaction_validity::TransactionValidityError, - > { - Ok(()) - } + type Val = (); fn validate( &self, - _who: &Self::AccountId, - call: &Self::Call, - _info: &sp_runtime::traits::DispatchInfoOf, + origin: <$call as sp_runtime::traits::Dispatchable>::RuntimeOrigin, + call: &$call, + _info: &sp_runtime::traits::DispatchInfoOf<$call>, _len: usize, - ) -> sp_runtime::transaction_validity::TransactionValidity { - let valid = sp_runtime::transaction_validity::ValidTransaction::default(); + _context: &mut Context, + _self_implicit: Self::Implicit, + _inherited_implication: &impl codec::Encode, + ) -> Result< + ( + sp_runtime::transaction_validity::ValidTransaction, + Self::Val, + <$call as sp_runtime::traits::Dispatchable>::RuntimeOrigin, + ), sp_runtime::transaction_validity::TransactionValidityError + > { + let tx_validity = sp_runtime::transaction_validity::ValidTransaction::default(); $( - let valid = valid - .combine_with(<$filter_call as $crate::BridgeRuntimeFilterCall<$call>>::validate(call)?); + let call_filter_validity = <$filter_call as $crate::BridgeRuntimeFilterCall<$call>>::validate(call)?; + let tx_validity = tx_validity.combine_with(call_filter_validity); )* - Ok(valid) + Ok((tx_validity, (), origin)) } - fn pre_dispatch( + fn prepare( self, - who: &Self::AccountId, - call: &Self::Call, - info: &sp_runtime::traits::DispatchInfoOf, - len: usize, + _val: Self::Val, + _origin: &<$call as sp_runtime::traits::Dispatchable>::RuntimeOrigin, + _call: &$call, + _info: &sp_runtime::traits::DispatchInfoOf<$call>, + _len: usize, + _context: &Context, ) -> Result { - self.validate(who, call, info, len).map(drop) + Ok(()) } } }; @@ -150,12 +155,14 @@ macro_rules! generate_bridge_reject_obsolete_headers_and_messages { #[cfg(test)] mod tests { use crate::BridgeRuntimeFilterCall; - use frame_support::{assert_err, assert_ok}; + use codec::Encode; + use frame_support::assert_err; use sp_runtime::{ - traits::SignedExtension, + traits::DispatchTransaction, transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction}, }; + #[derive(Encode)] pub struct MockCall { data: u32, } @@ -206,17 +213,20 @@ mod tests { ); assert_err!( - BridgeRejectObsoleteHeadersAndMessages.validate(&(), &MockCall { data: 1 }, &(), 0), + BridgeRejectObsoleteHeadersAndMessages.validate_only((), &MockCall { data: 1 }, &(), 0), InvalidTransaction::Custom(1) ); assert_err!( - BridgeRejectObsoleteHeadersAndMessages.validate(&(), &MockCall { data: 2 }, &(), 0), + BridgeRejectObsoleteHeadersAndMessages.validate_only((), &MockCall { data: 2 }, &(), 0), InvalidTransaction::Custom(2) ); - assert_ok!( - BridgeRejectObsoleteHeadersAndMessages.validate(&(), &MockCall { data: 3 }, &(), 0), + assert_eq!( + BridgeRejectObsoleteHeadersAndMessages + .validate_only((), &MockCall { data: 3 }, &(), 0) + .unwrap() + .0, ValidTransaction { priority: 3, ..Default::default() } ) } diff --git a/bridges/bin/runtime-common/src/mock.rs b/bridges/bin/runtime-common/src/mock.rs index 8877a4fd95c..f147f1404f0 100644 --- a/bridges/bin/runtime-common/src/mock.rs +++ b/bridges/bin/runtime-common/src/mock.rs @@ -164,6 +164,7 @@ impl pallet_balances::Config for TestRuntime { type AccountStore = System; } +#[derive_impl(pallet_transaction_payment::config_preludes::TestDefaultConfig as pallet_transaction_payment::DefaultConfig)] impl pallet_transaction_payment::Config for TestRuntime { type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; type OperationalFeeMultiplier = ConstU8<5>; @@ -176,7 +177,6 @@ impl pallet_transaction_payment::Config for TestRuntime { MinimumMultiplier, MaximumMultiplier, >; - type RuntimeEvent = RuntimeEvent; } impl pallet_bridge_grandpa::Config for TestRuntime { diff --git a/bridges/bin/runtime-common/src/priority_calculator.rs b/bridges/bin/runtime-common/src/priority_calculator.rs index a597fb9e2f4..0c53018330e 100644 --- a/bridges/bin/runtime-common/src/priority_calculator.rs +++ b/bridges/bin/runtime-common/src/priority_calculator.rs @@ -169,12 +169,15 @@ mod integrity_tests { // nodes to the proof (x0.5 because we expect some nodes to be reused) let estimated_message_size = 512; // let's say all our messages have the same dispatch weight - let estimated_message_dispatch_weight = - Runtime::WeightInfo::message_dispatch_weight(estimated_message_size); + let estimated_message_dispatch_weight = >::WeightInfo::message_dispatch_weight( + estimated_message_size + ); // messages proof argument size is (for every message) messages size + some additional // trie nodes. Some of them are reused by different messages, so let's take 2/3 of default // "overhead" constant - let messages_proof_size = Runtime::WeightInfo::expected_extra_storage_proof_size() + let messages_proof_size = >::WeightInfo::expected_extra_storage_proof_size() .saturating_mul(2) .saturating_div(3) .saturating_add(estimated_message_size) @@ -182,7 +185,7 @@ mod integrity_tests { // finally we are able to estimate transaction size and weight let transaction_size = base_tx_size.saturating_add(messages_proof_size); - let transaction_weight = Runtime::WeightInfo::receive_messages_proof_weight( + let transaction_weight = >::WeightInfo::receive_messages_proof_weight( &PreComputedSize(transaction_size as _), messages as _, estimated_message_dispatch_weight.saturating_mul(messages), diff --git a/bridges/bin/runtime-common/src/refund_relayer_extension.rs b/bridges/bin/runtime-common/src/refund_relayer_extension.rs index bfcb82ad166..b912f8445ac 100644 --- a/bridges/bin/runtime-common/src/refund_relayer_extension.rs +++ b/bridges/bin/runtime-common/src/refund_relayer_extension.rs @@ -48,9 +48,12 @@ use pallet_transaction_payment::{Config as TransactionPaymentConfig, OnChargeTra use pallet_utility::{Call as UtilityCall, Config as UtilityConfig, Pallet as UtilityPallet}; use scale_info::TypeInfo; use sp_runtime::{ - traits::{DispatchInfoOf, Dispatchable, Get, PostDispatchInfoOf, SignedExtension, Zero}, + traits::{ + AsSystemOriginSigner, DispatchInfoOf, Dispatchable, Get, PostDispatchInfoOf, + TransactionExtension, TransactionExtensionBase, ValidateResult, Zero, + }, transaction_validity::{ - TransactionPriority, TransactionValidity, TransactionValidityError, ValidTransactionBuilder, + InvalidTransaction, TransactionPriority, TransactionValidityError, ValidTransactionBuilder, }, DispatchResult, FixedPointOperand, RuntimeDebug, }; @@ -239,8 +242,8 @@ pub enum RelayerAccountAction { Slash(AccountId, RewardsAccountParams), } -/// Everything common among our refund signed extensions. -pub trait RefundSignedExtension: +/// Everything common among our refund transaction extensions. +pub trait RefundTransactionExtension: 'static + Clone + Codec + sp_std::fmt::Debug + Default + Eq + PartialEq + Send + Sync + TypeInfo where >::BridgedChain: @@ -456,8 +459,8 @@ where } } -/// Adapter that allow implementing `sp_runtime::traits::SignedExtension` for any -/// `RefundSignedExtension`. +/// Adapter that allow implementing `sp_runtime::traits::TransactionExtension` for any +/// `RefundTransactionExtension`. #[derive( DefaultNoBound, CloneNoBound, @@ -468,12 +471,13 @@ where RuntimeDebugNoBound, TypeInfo, )] -pub struct RefundSignedExtensionAdapter(T) +pub struct RefundTransactionExtensionAdapter(T) where >::BridgedChain: Chain; -impl SignedExtension for RefundSignedExtensionAdapter +impl TransactionExtensionBase + for RefundTransactionExtensionAdapter where >::BridgedChain: Chain, @@ -483,22 +487,35 @@ where + MessagesCallSubType::Instance>, { const IDENTIFIER: &'static str = T::Id::STR; - type AccountId = AccountIdOf; - type Call = CallOf; - type AdditionalSigned = (); - type Pre = Option>>; + type Implicit = (); +} - fn additional_signed(&self) -> Result<(), TransactionValidityError> { - Ok(()) - } +impl TransactionExtension, Context> + for RefundTransactionExtensionAdapter +where + >::BridgedChain: + Chain, + CallOf: Dispatchable + + IsSubType, T::Runtime>> + + GrandpaCallSubType + + MessagesCallSubType::Instance>, + as Dispatchable>::RuntimeOrigin: + AsSystemOriginSigner> + Clone, +{ + type Pre = Option>>; + type Val = Option; fn validate( &self, - who: &Self::AccountId, - call: &Self::Call, - _info: &DispatchInfoOf, + origin: as Dispatchable>::RuntimeOrigin, + call: &CallOf, + _info: &DispatchInfoOf>, _len: usize, - ) -> TransactionValidity { + _context: &mut Context, + _self_implicit: Self::Implicit, + _inherited_implication: &impl Encode, + ) -> ValidateResult> { + let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?; // this is the only relevant line of code for the `pre_dispatch` // // we're not calling `validate` from `pre_dispatch` directly because of performance @@ -511,12 +528,12 @@ where // we only boost priority of presumably correct message delivery transactions let bundled_messages = match T::bundled_messages_for_priority_boost(parsed_call.as_ref()) { Some(bundled_messages) => bundled_messages, - None => return Ok(Default::default()), + None => return Ok((Default::default(), parsed_call, origin)), }; // we only boost priority if relayer has staked required balance if !RelayersPallet::::is_registration_active(who) { - return Ok(Default::default()) + return Ok((Default::default(), parsed_call, origin)) } // compute priority boost @@ -535,20 +552,21 @@ where priority_boost, ); - valid_transaction.build() + let validity = valid_transaction.build()?; + Ok((validity, parsed_call, origin)) } - fn pre_dispatch( + fn prepare( self, - who: &Self::AccountId, - call: &Self::Call, - _info: &DispatchInfoOf, + val: Self::Val, + origin: & as Dispatchable>::RuntimeOrigin, + _call: &CallOf, + _info: &DispatchInfoOf>, _len: usize, + _context: &Context, ) -> Result { - // this is a relevant piece of `validate` that we need here (in `pre_dispatch`) - let parsed_call = T::parse_and_check_for_obsolete_call(call)?; - - Ok(parsed_call.map(|call_info| { + let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?; + Ok(val.map(|call_info| { log::trace!( target: "runtime::bridge", "{} via {:?} parsed bridge transaction in pre-dispatch: {:?}", @@ -561,13 +579,14 @@ where } fn post_dispatch( - pre: Option, - info: &DispatchInfoOf, - post_info: &PostDispatchInfoOf, + pre: Self::Pre, + info: &DispatchInfoOf>, + post_info: &PostDispatchInfoOf>, len: usize, result: &DispatchResult, + _context: &Context, ) -> Result<(), TransactionValidityError> { - let call_result = T::analyze_call_result(pre, info, post_info, len, result); + let call_result = T::analyze_call_result(Some(pre), info, post_info, len, result); match call_result { RelayerAccountAction::None => (), @@ -595,7 +614,7 @@ where } } -/// Signed extension that refunds a relayer for new messages coming from a parachain. +/// Transaction extension that refunds a relayer for new messages coming from a parachain. /// /// Also refunds relayer for successful finality delivery if it comes in batch (`utility.batchAll`) /// with message delivery transaction. Batch may deliver either both relay chain header and @@ -636,7 +655,7 @@ pub struct RefundBridgedParachainMessages, ); -impl RefundSignedExtension +impl RefundTransactionExtension for RefundBridgedParachainMessages where Self: 'static + Send + Sync, @@ -730,13 +749,13 @@ where } } -/// Signed extension that refunds a relayer for new messages coming from a standalone (GRANDPA) +/// Transaction extension that refunds a relayer for new messages coming from a standalone (GRANDPA) /// chain. /// /// Also refunds relayer for successful finality delivery if it comes in batch (`utility.batchAll`) /// with message delivery transaction. Batch may deliver either both relay chain header and -/// parachain head, or just parachain head. Corresponding headers must be used in messages -/// proof verification. +/// parachain head, or just parachain head. Corresponding headers must be used in messages proof +/// verification. /// /// Extension does not refund transaction tip due to security reasons. #[derive( @@ -771,7 +790,7 @@ pub struct RefundBridgedGrandpaMessages, ); -impl RefundSignedExtension +impl RefundTransactionExtension for RefundBridgedGrandpaMessages where Self: 'static + Send + Sync, @@ -869,8 +888,8 @@ mod tests { Call as ParachainsCall, Pallet as ParachainsPallet, RelayBlockHash, }; use sp_runtime::{ - traits::{ConstU64, Header as HeaderT}, - transaction_validity::{InvalidTransaction, ValidTransaction}, + traits::{ConstU64, DispatchTransaction, Header as HeaderT}, + transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction}, DispatchError, }; @@ -899,7 +918,7 @@ mod tests { ConstU64<1>, StrTestExtension, >; - type TestGrandpaExtension = RefundSignedExtensionAdapter; + type TestGrandpaExtension = RefundTransactionExtensionAdapter; type TestExtensionProvider = RefundBridgedParachainMessages< TestRuntime, DefaultRefundableParachainId<(), TestParachain>, @@ -908,7 +927,7 @@ mod tests { ConstU64<1>, StrTestExtension, >; - type TestExtension = RefundSignedExtensionAdapter; + type TestExtension = RefundTransactionExtensionAdapter; fn initial_balance_of_relayer_account_at_this_chain() -> ThisChainBalance { let test_stake: ThisChainBalance = TestStake::get(); @@ -1407,14 +1426,28 @@ mod tests { fn run_validate(call: RuntimeCall) -> TransactionValidity { let extension: TestExtension = - RefundSignedExtensionAdapter(RefundBridgedParachainMessages(PhantomData)); - extension.validate(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0) + RefundTransactionExtensionAdapter(RefundBridgedParachainMessages(PhantomData)); + extension + .validate_only( + Some(relayer_account_at_this_chain()).into(), + &call, + &DispatchInfo::default(), + 0, + ) + .map(|res| res.0) } fn run_grandpa_validate(call: RuntimeCall) -> TransactionValidity { let extension: TestGrandpaExtension = - RefundSignedExtensionAdapter(RefundBridgedGrandpaMessages(PhantomData)); - extension.validate(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0) + RefundTransactionExtensionAdapter(RefundBridgedGrandpaMessages(PhantomData)); + extension + .validate_only( + Some(relayer_account_at_this_chain()).into(), + &call, + &DispatchInfo::default(), + 0, + ) + .map(|res| res.0) } fn run_validate_ignore_priority(call: RuntimeCall) -> TransactionValidity { @@ -1428,16 +1461,30 @@ mod tests { call: RuntimeCall, ) -> Result>, TransactionValidityError> { let extension: TestExtension = - RefundSignedExtensionAdapter(RefundBridgedParachainMessages(PhantomData)); - extension.pre_dispatch(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0) + RefundTransactionExtensionAdapter(RefundBridgedParachainMessages(PhantomData)); + extension + .validate_and_prepare( + Some(relayer_account_at_this_chain()).into(), + &call, + &DispatchInfo::default(), + 0, + ) + .map(|(pre, _)| pre) } fn run_grandpa_pre_dispatch( call: RuntimeCall, ) -> Result>, TransactionValidityError> { let extension: TestGrandpaExtension = - RefundSignedExtensionAdapter(RefundBridgedGrandpaMessages(PhantomData)); - extension.pre_dispatch(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0) + RefundTransactionExtensionAdapter(RefundBridgedGrandpaMessages(PhantomData)); + extension + .validate_and_prepare( + Some(relayer_account_at_this_chain()).into(), + &call, + &DispatchInfo::default(), + 0, + ) + .map(|(pre, _)| pre) } fn dispatch_info() -> DispatchInfo { @@ -1460,11 +1507,12 @@ mod tests { dispatch_result: DispatchResult, ) { let post_dispatch_result = TestExtension::post_dispatch( - Some(pre_dispatch_data), + pre_dispatch_data, &dispatch_info(), &post_dispatch_info(), 1024, &dispatch_result, + &(), ); assert_eq!(post_dispatch_result, Ok(())); } diff --git a/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs b/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs index c49aa4b8563..f186f6427ae 100644 --- a/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs +++ b/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs @@ -26,7 +26,7 @@ pub use bp_polkadot_core::{ }; use bp_messages::*; -use bp_polkadot_core::SuffixedCommonSignedExtension; +use bp_polkadot_core::SuffixedCommonTransactionExtension; use bp_runtime::extensions::{ BridgeRejectObsoleteHeadersAndMessages, RefundBridgedParachainMessagesSchema, }; @@ -164,7 +164,7 @@ pub const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 1024; pub const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 4096; /// Signed extension that is used by all bridge hubs. -pub type SignedExtension = SuffixedCommonSignedExtension<( +pub type TransactionExtension = SuffixedCommonTransactionExtension<( BridgeRejectObsoleteHeadersAndMessages, RefundBridgedParachainMessagesSchema, )>; diff --git a/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs b/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs index c4e697fbe95..992ef1bd7a1 100644 --- a/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs +++ b/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs @@ -107,5 +107,5 @@ frame_support::parameter_types! { /// Transaction fee that is paid at the Rococo BridgeHub for delivering single outbound message confirmation. /// (initially was calculated by test `BridgeHubRococo::can_calculate_fee_for_complex_message_confirmation_transaction` + `33%`) - pub const BridgeHubRococoBaseConfirmationFeeInRocs: u128 = 5_380_829_647; + pub const BridgeHubRococoBaseConfirmationFeeInRocs: u128 = 5_380_904_835; } diff --git a/bridges/primitives/chain-kusama/src/lib.rs b/bridges/primitives/chain-kusama/src/lib.rs index e3b4d0520f6..253a1010e83 100644 --- a/bridges/primitives/chain-kusama/src/lib.rs +++ b/bridges/primitives/chain-kusama/src/lib.rs @@ -59,8 +59,8 @@ impl ChainWithGrandpa for Kusama { const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE; } -// The SignedExtension used by Kusama. -pub use bp_polkadot_core::CommonSignedExtension as SignedExtension; +// The TransactionExtension used by Kusama. +pub use bp_polkadot_core::CommonTransactionExtension as TransactionExtension; /// Name of the parachains pallet in the Kusama runtime. pub const PARAS_PALLET_NAME: &str = "Paras"; diff --git a/bridges/primitives/chain-polkadot-bulletin/src/lib.rs b/bridges/primitives/chain-polkadot-bulletin/src/lib.rs index f2eebf93124..73dd122bd15 100644 --- a/bridges/primitives/chain-polkadot-bulletin/src/lib.rs +++ b/bridges/primitives/chain-polkadot-bulletin/src/lib.rs @@ -25,7 +25,7 @@ use bp_runtime::{ decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, extensions::{ CheckEra, CheckGenesis, CheckNonZeroSender, CheckNonce, CheckSpecVersion, CheckTxVersion, - CheckWeight, GenericSignedExtension, GenericSignedExtensionSchema, + CheckWeight, GenericTransactionExtension, GenericTransactionExtensionSchema, }, Chain, ChainId, TransactionEra, }; @@ -37,7 +37,12 @@ use frame_support::{ }; use frame_system::limits; use scale_info::TypeInfo; -use sp_runtime::{traits::DispatchInfoOf, transaction_validity::TransactionValidityError, Perbill}; +use sp_runtime::{ + impl_tx_ext_default, + traits::{Dispatchable, TransactionExtensionBase}, + transaction_validity::TransactionValidityError, + Perbill, +}; // This chain reuses most of Polkadot primitives. pub use bp_polkadot_core::{ @@ -71,10 +76,10 @@ pub const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 1024; pub const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 4096; /// This signed extension is used to ensure that the chain transactions are signed by proper -pub type ValidateSigned = GenericSignedExtensionSchema<(), ()>; +pub type ValidateSigned = GenericTransactionExtensionSchema<(), ()>; /// Signed extension schema, used by Polkadot Bulletin. -pub type SignedExtensionSchema = GenericSignedExtension<( +pub type TransactionExtensionSchema = GenericTransactionExtension<( ( CheckNonZeroSender, CheckSpecVersion, @@ -87,34 +92,30 @@ pub type SignedExtensionSchema = GenericSignedExtension<( ValidateSigned, )>; -/// Signed extension, used by Polkadot Bulletin. +/// Transaction extension, used by Polkadot Bulletin. #[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -pub struct SignedExtension(SignedExtensionSchema); +pub struct TransactionExtension(TransactionExtensionSchema); -impl sp_runtime::traits::SignedExtension for SignedExtension { +impl TransactionExtensionBase for TransactionExtension { const IDENTIFIER: &'static str = "Not needed."; - type AccountId = (); - type Call = (); - type AdditionalSigned = - ::AdditionalSigned; - type Pre = (); + type Implicit = ::Implicit; - fn additional_signed(&self) -> Result { - self.0.additional_signed() + fn implicit(&self) -> Result { + ::implicit(&self.0) } +} - fn pre_dispatch( - self, - _who: &Self::AccountId, - _call: &Self::Call, - _info: &DispatchInfoOf, - _len: usize, - ) -> Result { - Ok(()) - } +impl sp_runtime::traits::TransactionExtension for TransactionExtension +where + C: Dispatchable, +{ + type Pre = (); + type Val = (); + + impl_tx_ext_default!(C; Context; validate prepare); } -impl SignedExtension { +impl TransactionExtension { /// Create signed extension from its components. pub fn from_params( spec_version: u32, @@ -123,7 +124,7 @@ impl SignedExtension { genesis_hash: Hash, nonce: Nonce, ) -> Self { - Self(GenericSignedExtension::new( + Self(GenericTransactionExtension::new( ( ( (), // non-zero sender diff --git a/bridges/primitives/chain-polkadot/src/lib.rs b/bridges/primitives/chain-polkadot/src/lib.rs index fc5e10308a8..e5e2e7c3a04 100644 --- a/bridges/primitives/chain-polkadot/src/lib.rs +++ b/bridges/primitives/chain-polkadot/src/lib.rs @@ -61,8 +61,8 @@ impl ChainWithGrandpa for Polkadot { const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE; } -/// The SignedExtension used by Polkadot. -pub type SignedExtension = SuffixedCommonSignedExtension; +/// The TransactionExtension used by Polkadot. +pub type TransactionExtension = SuffixedCommonTransactionExtension; /// Name of the parachains pallet in the Polkadot runtime. pub const PARAS_PALLET_NAME: &str = "Paras"; diff --git a/bridges/primitives/chain-rococo/src/lib.rs b/bridges/primitives/chain-rococo/src/lib.rs index f1b256f0f09..267c6b2b1f0 100644 --- a/bridges/primitives/chain-rococo/src/lib.rs +++ b/bridges/primitives/chain-rococo/src/lib.rs @@ -59,8 +59,8 @@ impl ChainWithGrandpa for Rococo { const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE; } -// The SignedExtension used by Rococo. -pub use bp_polkadot_core::CommonSignedExtension as SignedExtension; +// The TransactionExtension used by Rococo. +pub use bp_polkadot_core::CommonTransactionExtension as TransactionExtension; /// Name of the parachains pallet in the Rococo runtime. pub const PARAS_PALLET_NAME: &str = "Paras"; diff --git a/bridges/primitives/chain-westend/src/lib.rs b/bridges/primitives/chain-westend/src/lib.rs index f03fd2160a7..afa02e8ee54 100644 --- a/bridges/primitives/chain-westend/src/lib.rs +++ b/bridges/primitives/chain-westend/src/lib.rs @@ -59,8 +59,8 @@ impl ChainWithGrandpa for Westend { const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE; } -// The SignedExtension used by Westend. -pub use bp_polkadot_core::CommonSignedExtension as SignedExtension; +// The TransactionExtension used by Westend. +pub use bp_polkadot_core::CommonTransactionExtension as TransactionExtension; /// Name of the parachains pallet in the Rococo runtime. pub const PARAS_PALLET_NAME: &str = "Paras"; diff --git a/bridges/primitives/polkadot-core/src/lib.rs b/bridges/primitives/polkadot-core/src/lib.rs index df2836495bb..d59b99db4b5 100644 --- a/bridges/primitives/polkadot-core/src/lib.rs +++ b/bridges/primitives/polkadot-core/src/lib.rs @@ -24,8 +24,8 @@ use bp_runtime::{ self, extensions::{ ChargeTransactionPayment, CheckEra, CheckGenesis, CheckNonZeroSender, CheckNonce, - CheckSpecVersion, CheckTxVersion, CheckWeight, GenericSignedExtension, - SignedExtensionSchema, + CheckSpecVersion, CheckTxVersion, CheckWeight, GenericTransactionExtension, + TransactionExtensionSchema, }, EncodedOrDecodedCall, StorageMapKeyProvider, TransactionEra, }; @@ -229,8 +229,12 @@ pub type SignedBlock = generic::SignedBlock; pub type Balance = u128; /// Unchecked Extrinsic type. -pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic, Signature, SignedExt>; +pub type UncheckedExtrinsic = generic::UncheckedExtrinsic< + AccountAddress, + EncodedOrDecodedCall, + Signature, + TransactionExt, +>; /// Account address, used by the Polkadot-like chain. pub type Address = MultiAddress; @@ -275,7 +279,7 @@ impl AccountInfoStorageMapKeyProvider { } /// Extra signed extension data that is used by most chains. -pub type CommonSignedExtra = ( +pub type CommonTransactionExtra = ( CheckNonZeroSender, CheckSpecVersion, CheckTxVersion, @@ -286,12 +290,12 @@ pub type CommonSignedExtra = ( ChargeTransactionPayment, ); -/// Extra signed extension data that starts with `CommonSignedExtra`. -pub type SuffixedCommonSignedExtension = - GenericSignedExtension<(CommonSignedExtra, Suffix)>; +/// Extra transaction extension data that starts with `CommonTransactionExtra`. +pub type SuffixedCommonTransactionExtension = + GenericTransactionExtension<(CommonTransactionExtra, Suffix)>; -/// Helper trait to define some extra methods on `SuffixedCommonSignedExtension`. -pub trait SuffixedCommonSignedExtensionExt { +/// Helper trait to define some extra methods on `SuffixedCommonTransactionExtension`. +pub trait SuffixedCommonTransactionExtensionExt { /// Create signed extension from its components. fn from_params( spec_version: u32, @@ -300,7 +304,7 @@ pub trait SuffixedCommonSignedExtensionExt { genesis_hash: Hash, nonce: Nonce, tip: Balance, - extra: (Suffix::Payload, Suffix::AdditionalSigned), + extra: (Suffix::Payload, Suffix::Implicit), ) -> Self; /// Return transaction nonce. @@ -310,9 +314,10 @@ pub trait SuffixedCommonSignedExtensionExt { fn tip(&self) -> Balance; } -impl SuffixedCommonSignedExtensionExt for SuffixedCommonSignedExtension +impl SuffixedCommonTransactionExtensionExt + for SuffixedCommonTransactionExtension where - Suffix: SignedExtensionSchema, + Suffix: TransactionExtensionSchema, { fn from_params( spec_version: u32, @@ -321,9 +326,9 @@ where genesis_hash: Hash, nonce: Nonce, tip: Balance, - extra: (Suffix::Payload, Suffix::AdditionalSigned), + extra: (Suffix::Payload, Suffix::Implicit), ) -> Self { - GenericSignedExtension::new( + GenericTransactionExtension::new( ( ( (), // non-zero sender @@ -365,7 +370,7 @@ where } /// Signed extension that is used by most chains. -pub type CommonSignedExtension = SuffixedCommonSignedExtension<()>; +pub type CommonTransactionExtension = SuffixedCommonTransactionExtension<()>; #[cfg(test)] mod tests { diff --git a/bridges/primitives/runtime/src/extensions.rs b/bridges/primitives/runtime/src/extensions.rs index d896bc92eff..a31e7b5bb47 100644 --- a/bridges/primitives/runtime/src/extensions.rs +++ b/bridges/primitives/runtime/src/extensions.rs @@ -20,135 +20,138 @@ use codec::{Compact, Decode, Encode}; use impl_trait_for_tuples::impl_for_tuples; use scale_info::{StaticTypeInfo, TypeInfo}; use sp_runtime::{ - traits::{DispatchInfoOf, SignedExtension}, + impl_tx_ext_default, + traits::{Dispatchable, TransactionExtension, TransactionExtensionBase}, transaction_validity::TransactionValidityError, }; use sp_std::{fmt::Debug, marker::PhantomData}; -/// Trait that describes some properties of a `SignedExtension` that are needed in order to send a -/// transaction to the chain. -pub trait SignedExtensionSchema: Encode + Decode + Debug + Eq + Clone + StaticTypeInfo { +/// Trait that describes some properties of a `TransactionExtension` that are needed in order to +/// send a transaction to the chain. +pub trait TransactionExtensionSchema: + Encode + Decode + Debug + Eq + Clone + StaticTypeInfo +{ /// A type of the data encoded as part of the transaction. type Payload: Encode + Decode + Debug + Eq + Clone + StaticTypeInfo; /// Parameters which are part of the payload used to produce transaction signature, /// but don't end up in the transaction itself (i.e. inherent part of the runtime). - type AdditionalSigned: Encode + Debug + Eq + Clone + StaticTypeInfo; + type Implicit: Encode + Decode + Debug + Eq + Clone + StaticTypeInfo; } -impl SignedExtensionSchema for () { +impl TransactionExtensionSchema for () { type Payload = (); - type AdditionalSigned = (); + type Implicit = (); } -/// An implementation of `SignedExtensionSchema` using generic params. +/// An implementation of `TransactionExtensionSchema` using generic params. #[derive(Encode, Decode, Clone, Debug, PartialEq, Eq, TypeInfo)] -pub struct GenericSignedExtensionSchema(PhantomData<(P, S)>); +pub struct GenericTransactionExtensionSchema(PhantomData<(P, S)>); -impl SignedExtensionSchema for GenericSignedExtensionSchema +impl TransactionExtensionSchema for GenericTransactionExtensionSchema where P: Encode + Decode + Debug + Eq + Clone + StaticTypeInfo, - S: Encode + Debug + Eq + Clone + StaticTypeInfo, + S: Encode + Decode + Debug + Eq + Clone + StaticTypeInfo, { type Payload = P; - type AdditionalSigned = S; + type Implicit = S; } -/// The `SignedExtensionSchema` for `frame_system::CheckNonZeroSender`. -pub type CheckNonZeroSender = GenericSignedExtensionSchema<(), ()>; +/// The `TransactionExtensionSchema` for `frame_system::CheckNonZeroSender`. +pub type CheckNonZeroSender = GenericTransactionExtensionSchema<(), ()>; -/// The `SignedExtensionSchema` for `frame_system::CheckSpecVersion`. -pub type CheckSpecVersion = GenericSignedExtensionSchema<(), u32>; +/// The `TransactionExtensionSchema` for `frame_system::CheckSpecVersion`. +pub type CheckSpecVersion = GenericTransactionExtensionSchema<(), u32>; -/// The `SignedExtensionSchema` for `frame_system::CheckTxVersion`. -pub type CheckTxVersion = GenericSignedExtensionSchema<(), u32>; +/// The `TransactionExtensionSchema` for `frame_system::CheckTxVersion`. +pub type CheckTxVersion = GenericTransactionExtensionSchema<(), u32>; -/// The `SignedExtensionSchema` for `frame_system::CheckGenesis`. -pub type CheckGenesis = GenericSignedExtensionSchema<(), Hash>; +/// The `TransactionExtensionSchema` for `frame_system::CheckGenesis`. +pub type CheckGenesis = GenericTransactionExtensionSchema<(), Hash>; -/// The `SignedExtensionSchema` for `frame_system::CheckEra`. -pub type CheckEra = GenericSignedExtensionSchema; +/// The `TransactionExtensionSchema` for `frame_system::CheckEra`. +pub type CheckEra = GenericTransactionExtensionSchema; -/// The `SignedExtensionSchema` for `frame_system::CheckNonce`. -pub type CheckNonce = GenericSignedExtensionSchema, ()>; +/// The `TransactionExtensionSchema` for `frame_system::CheckNonce`. +pub type CheckNonce = GenericTransactionExtensionSchema, ()>; -/// The `SignedExtensionSchema` for `frame_system::CheckWeight`. -pub type CheckWeight = GenericSignedExtensionSchema<(), ()>; +/// The `TransactionExtensionSchema` for `frame_system::CheckWeight`. +pub type CheckWeight = GenericTransactionExtensionSchema<(), ()>; -/// The `SignedExtensionSchema` for `pallet_transaction_payment::ChargeTransactionPayment`. -pub type ChargeTransactionPayment = GenericSignedExtensionSchema, ()>; +/// The `TransactionExtensionSchema` for `pallet_transaction_payment::ChargeTransactionPayment`. +pub type ChargeTransactionPayment = + GenericTransactionExtensionSchema, ()>; -/// The `SignedExtensionSchema` for `polkadot-runtime-common::PrevalidateAttests`. -pub type PrevalidateAttests = GenericSignedExtensionSchema<(), ()>; +/// The `TransactionExtensionSchema` for `polkadot-runtime-common::PrevalidateAttests`. +pub type PrevalidateAttests = GenericTransactionExtensionSchema<(), ()>; -/// The `SignedExtensionSchema` for `BridgeRejectObsoleteHeadersAndMessages`. -pub type BridgeRejectObsoleteHeadersAndMessages = GenericSignedExtensionSchema<(), ()>; +/// The `TransactionExtensionSchema` for `BridgeRejectObsoleteHeadersAndMessages`. +pub type BridgeRejectObsoleteHeadersAndMessages = GenericTransactionExtensionSchema<(), ()>; -/// The `SignedExtensionSchema` for `RefundBridgedParachainMessages`. +/// The `TransactionExtensionSchema` for `RefundBridgedParachainMessages`. /// This schema is dedicated for `RefundBridgedParachainMessages` signed extension as /// wildcard/placeholder, which relies on the scale encoding for `()` or `((), ())`, or `((), (), /// ())` is the same. So runtime can contains any kind of tuple: /// `(BridgeRefundBridgeHubRococoMessages)` /// `(BridgeRefundBridgeHubRococoMessages, BridgeRefundBridgeHubWestendMessages)` /// `(BridgeRefundParachainMessages1, ..., BridgeRefundParachainMessagesN)` -pub type RefundBridgedParachainMessagesSchema = GenericSignedExtensionSchema<(), ()>; +pub type RefundBridgedParachainMessagesSchema = GenericTransactionExtensionSchema<(), ()>; #[impl_for_tuples(1, 12)] -impl SignedExtensionSchema for Tuple { +impl TransactionExtensionSchema for Tuple { for_tuples!( type Payload = ( #( Tuple::Payload ),* ); ); - for_tuples!( type AdditionalSigned = ( #( Tuple::AdditionalSigned ),* ); ); + for_tuples!( type Implicit = ( #( Tuple::Implicit ),* ); ); } /// A simplified version of signed extensions meant for producing signed transactions /// and signed payloads in the client code. #[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -pub struct GenericSignedExtension { +pub struct GenericTransactionExtension { /// A payload that is included in the transaction. pub payload: S::Payload, #[codec(skip)] // It may be set to `None` if extensions are decoded. We are never reconstructing transactions - // (and it makes no sense to do that) => decoded version of `SignedExtensions` is only used to - // read fields of the `payload`. And when resigning transaction, we're reconstructing - // `SignedExtensions` from scratch. - additional_signed: Option, + // (and it makes no sense to do that) => decoded version of `TransactionExtensions` is only + // used to read fields of the `payload`. And when resigning transaction, we're reconstructing + // `TransactionExtensions` from scratch. + implicit: Option, } -impl GenericSignedExtension { - /// Create new `GenericSignedExtension` object. - pub fn new(payload: S::Payload, additional_signed: Option) -> Self { - Self { payload, additional_signed } +impl GenericTransactionExtension { + /// Create new `GenericTransactionExtension` object. + pub fn new(payload: S::Payload, implicit: Option) -> Self { + Self { payload, implicit } } } -impl SignedExtension for GenericSignedExtension +impl TransactionExtensionBase for GenericTransactionExtension where - S: SignedExtensionSchema, + S: TransactionExtensionSchema, S::Payload: Send + Sync, - S::AdditionalSigned: Send + Sync, + S::Implicit: Send + Sync, { const IDENTIFIER: &'static str = "Not needed."; - type AccountId = (); - type Call = (); - type AdditionalSigned = S::AdditionalSigned; - type Pre = (); + type Implicit = S::Implicit; - fn additional_signed(&self) -> Result { + fn implicit(&self) -> Result { // we shall not ever see this error in relay, because we are never signing decoded // transactions. Instead we're constructing and signing new transactions. So the error code // is kinda random here - self.additional_signed.clone().ok_or( - frame_support::unsigned::TransactionValidityError::Unknown( + self.implicit + .clone() + .ok_or(frame_support::unsigned::TransactionValidityError::Unknown( frame_support::unsigned::UnknownTransaction::Custom(0xFF), - ), - ) + )) } +} +impl TransactionExtension for GenericTransactionExtension +where + C: Dispatchable, + S: TransactionExtensionSchema, + S::Payload: Send + Sync, + S::Implicit: Send + Sync, +{ + type Pre = (); + type Val = (); - fn pre_dispatch( - self, - _who: &Self::AccountId, - _call: &Self::Call, - _info: &DispatchInfoOf, - _len: usize, - ) -> Result { - Ok(()) - } + impl_tx_ext_default!(C; Context; validate prepare); } diff --git a/bridges/snowbridge/runtime/test-common/Cargo.toml b/bridges/snowbridge/runtime/test-common/Cargo.toml index 4e8b311cb97..5f169e82f49 100644 --- a/bridges/snowbridge/runtime/test-common/Cargo.toml +++ b/bridges/snowbridge/runtime/test-common/Cargo.toml @@ -181,6 +181,7 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", diff --git a/cumulus/parachain-template/runtime/Cargo.toml b/cumulus/parachain-template/runtime/Cargo.toml index 1873bd0a23e..60d8d6f5136 100644 --- a/cumulus/parachain-template/runtime/Cargo.toml +++ b/cumulus/parachain-template/runtime/Cargo.toml @@ -138,6 +138,7 @@ runtime-benchmarks = [ "cumulus-pallet-session-benchmarking/runtime-benchmarks", "cumulus-pallet-xcmp-queue/runtime-benchmarks", "cumulus-primitives-core/runtime-benchmarks", + "cumulus-primitives-storage-weight-reclaim/runtime-benchmarks", "cumulus-primitives-utility/runtime-benchmarks", "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", @@ -150,6 +151,7 @@ runtime-benchmarks = [ "pallet-parachain-template/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "parachains-common/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", diff --git a/cumulus/parachain-template/runtime/src/lib.rs b/cumulus/parachain-template/runtime/src/lib.rs index 004a5d70ebc..f7754e594e6 100644 --- a/cumulus/parachain-template/runtime/src/lib.rs +++ b/cumulus/parachain-template/runtime/src/lib.rs @@ -97,8 +97,8 @@ pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( +/// The extension to the basic transaction logic. +pub type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -112,7 +112,7 @@ pub type SignedExtra = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< @@ -353,6 +353,7 @@ impl pallet_transaction_payment::Config for Runtime { type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; type OperationalFeeMultiplier = ConstU8<5>; + type WeightInfo = (); } impl pallet_sudo::Config for Runtime { @@ -529,6 +530,7 @@ construct_runtime!( mod benches { frame_benchmarking::define_benchmarks!( [frame_system, SystemBench::] + [frame_system_extensions, SystemExtensionsBench::] [pallet_balances, Balances] [pallet_session, SessionBench::] [pallet_timestamp, Timestamp] @@ -712,6 +714,7 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; let mut list = Vec::::new(); @@ -727,6 +730,7 @@ impl_runtime_apis! { use frame_benchmarking::{BenchmarkError, Benchmarking, BenchmarkBatch}; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; impl frame_system_benchmarking::Config for Runtime { fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml index 05936e93993..3eb63a24b74 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml @@ -119,6 +119,7 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", + "pallet-asset-conversion-tx-payment/runtime-benchmarks", "pallet-asset-conversion/runtime-benchmarks", "pallet-assets/runtime-benchmarks", "pallet-balances/runtime-benchmarks", @@ -130,6 +131,7 @@ runtime-benchmarks = [ "pallet-proxy/runtime-benchmarks", "pallet-state-trie-migration/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-uniques/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 17a12dd2f6f..32966ab6341 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -178,6 +178,7 @@ impl frame_system::Config for Runtime { type Version = Version; type AccountData = pallet_balances::AccountData; type SystemWeightInfo = weights::frame_system::WeightInfo; + type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; type SS58Prefix = SS58Prefix; type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; type MaxConsumers = frame_support::traits::ConstU32<16>; @@ -234,6 +235,7 @@ impl pallet_transaction_payment::Config for Runtime { type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; type OperationalFeeMultiplier = ConstU8<5>; + type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { @@ -761,6 +763,9 @@ impl pallet_asset_conversion_tx_payment::Config for Runtime { type Fungibles = LocalAndForeignAssets; type OnChargeAssetTransaction = AssetConversionAdapter; + type WeightInfo = weights::pallet_asset_conversion_tx_payment::WeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = AssetConversionTxHelper; } parameter_types! { @@ -948,8 +953,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( +/// The extension to the basic transaction logic. +pub type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -961,7 +966,7 @@ pub type SignedExtra = ( ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. pub type Migrations = ( pallet_collator_selection::migration::v1::MigrateToV1, @@ -1034,14 +1039,77 @@ pub type Executive = frame_executive::Executive< Migrations, >; +#[cfg(feature = "runtime-benchmarks")] +pub struct AssetConversionTxHelper; + +#[cfg(feature = "runtime-benchmarks")] +impl + pallet_asset_conversion_tx_payment::BenchmarkHelperTrait< + AccountId, + xcm::v3::MultiLocation, + xcm::v3::MultiLocation, + > for AssetConversionTxHelper +{ + fn create_asset_id_parameter(seed: u32) -> (xcm::v3::MultiLocation, xcm::v3::MultiLocation) { + // Use a different parachain' foreign assets pallet so that the asset is indeed foreign. + let asset_id = xcm::v3::MultiLocation::new( + 1, + xcm::v3::Junctions::X3( + xcm::v3::Junction::Parachain(3000), + xcm::v3::Junction::PalletInstance(53), + xcm::v3::Junction::GeneralIndex(seed.into()), + ), + ); + (asset_id, asset_id) + } + + fn setup_balances_and_pool(asset_id: xcm::v3::MultiLocation, account: AccountId) { + use frame_support::{assert_ok, traits::fungibles::Mutate}; + assert_ok!(ForeignAssets::force_create( + RuntimeOrigin::root(), + asset_id.into(), + account.clone().into(), /* owner */ + true, /* is_sufficient */ + 1, + )); + + let lp_provider = account.clone(); + use frame_support::traits::Currency; + let _ = Balances::deposit_creating(&lp_provider, u64::MAX.into()); + assert_ok!(ForeignAssets::mint_into(asset_id.into(), &lp_provider, u64::MAX.into())); + + let token_native = Box::new(TokenLocationV3::get()); + let token_second = Box::new(asset_id); + + assert_ok!(AssetConversion::create_pool( + RuntimeOrigin::signed(lp_provider.clone()), + token_native.clone(), + token_second.clone() + )); + + assert_ok!(AssetConversion::add_liquidity( + RuntimeOrigin::signed(lp_provider.clone()), + token_native, + token_second, + (u32::MAX / 8).into(), // 1 desired + u32::MAX.into(), // 2 desired + 1, // 1 min + 1, // 2 min + lp_provider, + )); + } +} + #[cfg(feature = "runtime-benchmarks")] mod benches { frame_benchmarking::define_benchmarks!( [frame_system, SystemBench::] + [frame_system_extensions, SystemExtensionsBench::] [pallet_assets, Local] [pallet_assets, Foreign] [pallet_assets, Pool] [pallet_asset_conversion, AssetConversion] + [pallet_asset_conversion_tx_payment, AssetTxPayment] [pallet_balances, Balances] [pallet_message_queue, MessageQueue] [pallet_multisig, Multisig] @@ -1052,6 +1120,7 @@ mod benches { [pallet_uniques, Uniques] [pallet_utility, Utility] [pallet_timestamp, Timestamp] + [pallet_transaction_payment, TransactionPayment] [pallet_collator_selection, CollatorSelection] [cumulus_pallet_parachain_system, ParachainSystem] [cumulus_pallet_xcmp_queue, XcmpQueue] @@ -1302,6 +1371,7 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; use pallet_xcm_bridge_hub_router::benchmarking::Pallet as XcmBridgeHubRouterBench; @@ -1336,6 +1406,7 @@ impl_runtime_apis! { use sp_storage::TrackedStorageKey; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; impl frame_system_benchmarking::Config for Runtime { fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/frame_system_extensions.rs new file mode 100644 index 00000000000..ed2c5f3056e --- /dev/null +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/frame_system_extensions.rs @@ -0,0 +1,121 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `frame_system_extensions` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=frame_system_extensions +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/ +// --chain=asset-hub-rococo-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_system_extensions`. +pub struct WeightInfo(PhantomData); +impl frame_system::ExtensionsWeightInfo for WeightInfo { + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_genesis() -> Weight { + // Proof Size summary in bytes: + // Measured: `54` + // Estimated: `3509` + // Minimum execution time: 3_637_000 picoseconds. + Weight::from_parts(6_382_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_mortality() -> Weight { + // Proof Size summary in bytes: + // Measured: `92` + // Estimated: `3509` + // Minimum execution time: 5_841_000 picoseconds. + Weight::from_parts(8_776_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + fn check_non_zero_sender() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 561_000 picoseconds. + Weight::from_parts(2_705_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_nonce() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_316_000 picoseconds. + Weight::from_parts(5_771_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_spec_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 511_000 picoseconds. + Weight::from_parts(2_575_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_tx_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 501_000 picoseconds. + Weight::from_parts(2_595_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) + /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::BlockWeight` (r:1 w:1) + /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) + fn check_weight() -> Weight { + // Proof Size summary in bytes: + // Measured: `24` + // Estimated: `1533` + // Minimum execution time: 3_687_000 picoseconds. + Weight::from_parts(6_192_000, 0) + .saturating_add(Weight::from_parts(0, 1533)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/mod.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/mod.rs index fa9e86102c6..134b5341a40 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/mod.rs @@ -19,7 +19,9 @@ pub mod cumulus_pallet_parachain_system; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; +pub mod frame_system_extensions; pub mod pallet_asset_conversion; +pub mod pallet_asset_conversion_tx_payment; pub mod pallet_assets_foreign; pub mod pallet_assets_local; pub mod pallet_assets_pool; @@ -32,6 +34,7 @@ pub mod pallet_nfts; pub mod pallet_proxy; pub mod pallet_session; pub mod pallet_timestamp; +pub mod pallet_transaction_payment; pub mod pallet_uniques; pub mod pallet_utility; pub mod pallet_xcm; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_asset_conversion_tx_payment.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_asset_conversion_tx_payment.rs new file mode 100644 index 00000000000..0a639b368af --- /dev/null +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_asset_conversion_tx_payment.rs @@ -0,0 +1,92 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `pallet_asset_conversion_tx_payment` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2024-01-04, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `Georges-MacBook-Pro.local`, CPU: `` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/debug/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=pallet_asset_conversion_tx_payment +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/ +// --chain=asset-hub-rococo-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_asset_conversion_tx_payment`. +pub struct WeightInfo(PhantomData); +impl pallet_asset_conversion_tx_payment::WeightInfo for WeightInfo { + fn charge_asset_tx_payment_zero() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_000_000 picoseconds. + Weight::from_parts(10_000_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:0) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn charge_asset_tx_payment_native() -> Weight { + // Proof Size summary in bytes: + // Measured: `4` + // Estimated: `3593` + // Minimum execution time: 209_000_000 picoseconds. + Weight::from_parts(212_000_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + } + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `ForeignAssets::Asset` (r:1 w:1) + /// Proof: `ForeignAssets::Asset` (`max_values`: None, `max_size`: Some(808), added: 3283, mode: `MaxEncodedLen`) + /// Storage: `ForeignAssets::Account` (r:2 w:2) + /// Proof: `ForeignAssets::Account` (`max_values`: None, `max_size`: Some(732), added: 3207, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn charge_asset_tx_payment_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `631` + // Estimated: `7404` + // Minimum execution time: 1_228_000_000 picoseconds. + Weight::from_parts(1_268_000_000, 0) + .saturating_add(Weight::from_parts(0, 7404)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } +} diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_transaction_payment.rs new file mode 100644 index 00000000000..035f9a6dbe5 --- /dev/null +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_transaction_payment.rs @@ -0,0 +1,67 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `pallet_transaction_payment` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=pallet_transaction_payment +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/ +// --chain=asset-hub-rococo-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_transaction_payment`. +pub struct WeightInfo(PhantomData); +impl pallet_transaction_payment::WeightInfo for WeightInfo { + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn charge_transaction_payment() -> Weight { + // Proof Size summary in bytes: + // Measured: `4` + // Estimated: `3593` + // Minimum execution time: 33_363_000 picoseconds. + Weight::from_parts(38_793_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml index 78c48507a7a..c10e02bd8a6 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml @@ -110,6 +110,7 @@ runtime-benchmarks = [ "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", "hex-literal", + "pallet-asset-conversion-tx-payment/runtime-benchmarks", "pallet-asset-conversion/runtime-benchmarks", "pallet-assets/runtime-benchmarks", "pallet-balances/runtime-benchmarks", @@ -120,6 +121,7 @@ runtime-benchmarks = [ "pallet-nfts/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-uniques/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 1ead2897855..5246828da31 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -162,6 +162,7 @@ impl frame_system::Config for Runtime { type Version = Version; type AccountData = pallet_balances::AccountData; type SystemWeightInfo = weights::frame_system::WeightInfo; + type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; type SS58Prefix = SS58Prefix; type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; type MaxConsumers = frame_support::traits::ConstU32<16>; @@ -218,6 +219,7 @@ impl pallet_transaction_payment::Config for Runtime { type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; type OperationalFeeMultiplier = ConstU8<5>; + type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { @@ -735,6 +737,9 @@ impl pallet_asset_conversion_tx_payment::Config for Runtime { type Fungibles = LocalAndForeignAssets; type OnChargeAssetTransaction = AssetConversionAdapter; + type WeightInfo = weights::pallet_asset_conversion_tx_payment::WeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = AssetConversionTxHelper; } parameter_types! { @@ -920,8 +925,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( +/// The extension to the basic transaction logic. +pub type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -933,7 +938,7 @@ pub type SignedExtra = ( ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. pub type Migrations = ( @@ -1065,14 +1070,77 @@ pub type Executive = frame_executive::Executive< Migrations, >; +#[cfg(feature = "runtime-benchmarks")] +pub struct AssetConversionTxHelper; + +#[cfg(feature = "runtime-benchmarks")] +impl + pallet_asset_conversion_tx_payment::BenchmarkHelperTrait< + AccountId, + xcm::v3::MultiLocation, + xcm::v3::MultiLocation, + > for AssetConversionTxHelper +{ + fn create_asset_id_parameter(seed: u32) -> (xcm::v3::MultiLocation, xcm::v3::MultiLocation) { + // Use a different parachain' foreign assets pallet so that the asset is indeed foreign. + let asset_id = xcm::v3::MultiLocation::new( + 1, + xcm::v3::Junctions::X3( + xcm::v3::Junction::Parachain(3000), + xcm::v3::Junction::PalletInstance(53), + xcm::v3::Junction::GeneralIndex(seed.into()), + ), + ); + (asset_id, asset_id) + } + + fn setup_balances_and_pool(asset_id: xcm::v3::MultiLocation, account: AccountId) { + use frame_support::{assert_ok, traits::fungibles::Mutate}; + assert_ok!(ForeignAssets::force_create( + RuntimeOrigin::root(), + asset_id.into(), + account.clone().into(), /* owner */ + true, /* is_sufficient */ + 1, + )); + + let lp_provider = account.clone(); + use frame_support::traits::Currency; + let _ = Balances::deposit_creating(&lp_provider, u64::MAX.into()); + assert_ok!(ForeignAssets::mint_into(asset_id.into(), &lp_provider, u64::MAX.into())); + + let token_native = Box::new(xcm::v3::MultiLocation::new(1, xcm::v3::Junctions::Here)); + let token_second = Box::new(asset_id); + + assert_ok!(AssetConversion::create_pool( + RuntimeOrigin::signed(lp_provider.clone()), + token_native.clone(), + token_second.clone() + )); + + assert_ok!(AssetConversion::add_liquidity( + RuntimeOrigin::signed(lp_provider.clone()), + token_native, + token_second, + (u32::MAX / 2).into(), // 1 desired + u32::MAX.into(), // 2 desired + 1, // 1 min + 1, // 2 min + lp_provider, + )); + } +} + #[cfg(feature = "runtime-benchmarks")] mod benches { frame_benchmarking::define_benchmarks!( [frame_system, SystemBench::] + [frame_system_extensions, SystemExtensionsBench::] [pallet_assets, Local] [pallet_assets, Foreign] [pallet_assets, Pool] [pallet_asset_conversion, AssetConversion] + [pallet_asset_conversion_tx_payment, AssetTxPayment] [pallet_balances, Balances] [pallet_message_queue, MessageQueue] [pallet_multisig, Multisig] @@ -1083,6 +1151,7 @@ mod benches { [pallet_uniques, Uniques] [pallet_utility, Utility] [pallet_timestamp, Timestamp] + [pallet_transaction_payment, TransactionPayment] [pallet_collator_selection, CollatorSelection] [cumulus_pallet_parachain_system, ParachainSystem] [cumulus_pallet_xcmp_queue, XcmpQueue] @@ -1379,6 +1448,7 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; use pallet_xcm_bridge_hub_router::benchmarking::Pallet as XcmBridgeHubRouterBench; @@ -1413,6 +1483,7 @@ impl_runtime_apis! { use sp_storage::TrackedStorageKey; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; impl frame_system_benchmarking::Config for Runtime { fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/frame_system_extensions.rs new file mode 100644 index 00000000000..46f4f2bfd96 --- /dev/null +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/frame_system_extensions.rs @@ -0,0 +1,121 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `frame_system_extensions` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-westend-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=frame_system_extensions +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/ +// --chain=asset-hub-westend-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_system_extensions`. +pub struct WeightInfo(PhantomData); +impl frame_system::ExtensionsWeightInfo for WeightInfo { + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_genesis() -> Weight { + // Proof Size summary in bytes: + // Measured: `54` + // Estimated: `3509` + // Minimum execution time: 3_206_000 picoseconds. + Weight::from_parts(6_212_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_mortality() -> Weight { + // Proof Size summary in bytes: + // Measured: `92` + // Estimated: `3509` + // Minimum execution time: 5_851_000 picoseconds. + Weight::from_parts(8_847_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + fn check_non_zero_sender() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 631_000 picoseconds. + Weight::from_parts(3_086_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_nonce() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_446_000 picoseconds. + Weight::from_parts(5_911_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_spec_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 481_000 picoseconds. + Weight::from_parts(2_916_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_tx_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 501_000 picoseconds. + Weight::from_parts(2_595_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) + /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::BlockWeight` (r:1 w:1) + /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) + fn check_weight() -> Weight { + // Proof Size summary in bytes: + // Measured: `24` + // Estimated: `1533` + // Minimum execution time: 3_927_000 picoseconds. + Weight::from_parts(6_613_000, 0) + .saturating_add(Weight::from_parts(0, 1533)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs index 2f1fcfb05f3..691ed2e5730 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs @@ -18,7 +18,9 @@ pub mod cumulus_pallet_parachain_system; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; +pub mod frame_system_extensions; pub mod pallet_asset_conversion; +pub mod pallet_asset_conversion_tx_payment; pub mod pallet_assets_foreign; pub mod pallet_assets_local; pub mod pallet_assets_pool; @@ -31,6 +33,7 @@ pub mod pallet_nfts; pub mod pallet_proxy; pub mod pallet_session; pub mod pallet_timestamp; +pub mod pallet_transaction_payment; pub mod pallet_uniques; pub mod pallet_utility; pub mod pallet_xcm; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_asset_conversion_tx_payment.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_asset_conversion_tx_payment.rs new file mode 100644 index 00000000000..8fe302630fb --- /dev/null +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_asset_conversion_tx_payment.rs @@ -0,0 +1,92 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `pallet_asset_conversion_tx_payment` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2024-01-04, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `Georges-MacBook-Pro.local`, CPU: `` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-westend-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/debug/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=pallet_asset_conversion_tx_payment +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/ +// --chain=asset-hub-westend-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_asset_conversion_tx_payment`. +pub struct WeightInfo(PhantomData); +impl pallet_asset_conversion_tx_payment::WeightInfo for WeightInfo { + fn charge_asset_tx_payment_zero() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(9_000_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:0) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn charge_asset_tx_payment_native() -> Weight { + // Proof Size summary in bytes: + // Measured: `4` + // Estimated: `3593` + // Minimum execution time: 214_000_000 picoseconds. + Weight::from_parts(219_000_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + } + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `ForeignAssets::Asset` (r:1 w:1) + /// Proof: `ForeignAssets::Asset` (`max_values`: None, `max_size`: Some(808), added: 3283, mode: `MaxEncodedLen`) + /// Storage: `ForeignAssets::Account` (r:2 w:2) + /// Proof: `ForeignAssets::Account` (`max_values`: None, `max_size`: Some(732), added: 3207, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn charge_asset_tx_payment_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `631` + // Estimated: `7404` + // Minimum execution time: 1_211_000_000 picoseconds. + Weight::from_parts(1_243_000_000, 0) + .saturating_add(Weight::from_parts(0, 7404)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } +} diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_transaction_payment.rs new file mode 100644 index 00000000000..b4c78a78b48 --- /dev/null +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_transaction_payment.rs @@ -0,0 +1,67 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `pallet_transaction_payment` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-westend-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=pallet_transaction_payment +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/ +// --chain=asset-hub-westend-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_transaction_payment`. +pub struct WeightInfo(PhantomData); +impl pallet_transaction_payment::WeightInfo for WeightInfo { + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn charge_transaction_payment() -> Weight { + // Proof Size summary in bytes: + // Measured: `4` + // Estimated: `3593` + // Minimum execution time: 40_847_000 picoseconds. + Weight::from_parts(49_674_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml index 7a1951fd24b..242627815d3 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml @@ -242,6 +242,7 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm-bridge-hub/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs index 6dbf96edc2a..323e6ed65e6 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs @@ -40,7 +40,7 @@ use bridge_runtime_common::{ XcmBlobMessageDispatch, XcmVersionOfDestAndRemoteBridge, }, refund_relayer_extension::{ - ActualFeeRefund, RefundBridgedGrandpaMessages, RefundSignedExtensionAdapter, + ActualFeeRefund, RefundBridgedGrandpaMessages, RefundTransactionExtensionAdapter, RefundableMessagesLane, }, }; @@ -168,7 +168,7 @@ impl messages::BridgedChainWithMessages for RococoBulletin {} /// Signed extension that refunds relayers that are delivering messages from the Rococo Bulletin /// chain. -pub type OnBridgeHubRococoRefundRococoBulletinMessages = RefundSignedExtensionAdapter< +pub type OnBridgeHubRococoRefundRococoBulletinMessages = RefundTransactionExtensionAdapter< RefundBridgedGrandpaMessages< Runtime, BridgeGrandpaRococoBulletinInstance, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 5d55d7afbac..05d1aa188d2 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -39,7 +39,7 @@ use bridge_runtime_common::{ XcmBlobMessageDispatch, XcmVersionOfDestAndRemoteBridge, }, refund_relayer_extension::{ - ActualFeeRefund, RefundBridgedParachainMessages, RefundSignedExtensionAdapter, + ActualFeeRefund, RefundBridgedParachainMessages, RefundTransactionExtensionAdapter, RefundableMessagesLane, RefundableParachain, }, }; @@ -173,7 +173,7 @@ impl UnderlyingChainProvider for BridgeHubWestend { impl messages::BridgedChainWithMessages for BridgeHubWestend {} /// Signed extension that refunds relayers that are delivering messages from the Westend parachain. -pub type OnBridgeHubRococoRefundBridgeHubWestendMessages = RefundSignedExtensionAdapter< +pub type OnBridgeHubRococoRefundBridgeHubWestendMessages = RefundTransactionExtensionAdapter< RefundBridgedParachainMessages< Runtime, RefundableParachain< diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 0b48d1717fa..16e3b2e8600 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -115,8 +115,8 @@ pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( +/// The TransactionExtension to the basic transaction logic. +pub type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -134,7 +134,7 @@ pub type SignedExtra = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. pub type Migrations = ( @@ -262,6 +262,8 @@ impl frame_system::Config for Runtime { type DbWeight = RocksDbWeight; /// Weight information for the extrinsics of this pallet. type SystemWeightInfo = weights::frame_system::WeightInfo; + /// Weight information for the extensions of this pallet. + type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; /// Block & extrinsics weights: base values and limits. type BlockWeights = RuntimeBlockWeights; /// The maximum length of a block (in bytes). @@ -324,6 +326,7 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; + type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { @@ -759,12 +762,14 @@ bridge_runtime_common::generate_bridge_reject_obsolete_headers_and_messages! { mod benches { frame_benchmarking::define_benchmarks!( [frame_system, SystemBench::] + [frame_system_extensions, SystemExtensionsBench::] [pallet_balances, Balances] [pallet_message_queue, MessageQueue] [pallet_multisig, Multisig] [pallet_session, SessionBench::] [pallet_utility, Utility] [pallet_timestamp, Timestamp] + [pallet_transaction_payment, TransactionPayment] [pallet_collator_selection, CollatorSelection] [cumulus_pallet_parachain_system, ParachainSystem] [cumulus_pallet_xcmp_queue, XcmpQueue] @@ -1065,6 +1070,7 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; @@ -1095,6 +1101,7 @@ impl_runtime_apis! { use sp_storage::TrackedStorageKey; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; impl frame_system_benchmarking::Config for Runtime { fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); @@ -1478,16 +1485,16 @@ mod tests { use codec::Encode; use sp_runtime::{ generic::Era, - traits::{SignedExtension, Zero}, + traits::{TransactionExtensionBase, Zero}, }; #[test] fn ensure_signed_extension_definition_is_compatible_with_relay() { - use bp_polkadot_core::SuffixedCommonSignedExtensionExt; + use bp_polkadot_core::SuffixedCommonTransactionExtensionExt; sp_io::TestExternalities::default().execute_with(|| { frame_system::BlockHash::::insert(BlockNumber::zero(), Hash::default()); - let payload: SignedExtra = ( + let payload: TxExtension = ( frame_system::CheckNonZeroSender::new(), frame_system::CheckSpecVersion::new(), frame_system::CheckTxVersion::new(), @@ -1501,11 +1508,11 @@ mod tests { bridge_to_westend_config::OnBridgeHubRococoRefundBridgeHubWestendMessages::default(), bridge_to_bulletin_config::OnBridgeHubRococoRefundRococoBulletinMessages::default(), ) - ); + ).into(); // for BridgeHubRococo { - let bhr_indirect_payload = bp_bridge_hub_rococo::SignedExtension::from_params( + let bhr_indirect_payload = bp_bridge_hub_rococo::TransactionExtension::from_params( VERSION.spec_version, VERSION.transaction_version, bp_runtime::TransactionEra::Immortal, @@ -1516,8 +1523,8 @@ mod tests { ); assert_eq!(payload.encode(), bhr_indirect_payload.encode()); assert_eq!( - payload.additional_signed().unwrap().encode(), - bhr_indirect_payload.additional_signed().unwrap().encode() + payload.implicit().unwrap().encode(), + bhr_indirect_payload.implicit().unwrap().encode() ) } }); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/frame_system_extensions.rs new file mode 100644 index 00000000000..99e3d6aeba0 --- /dev/null +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/frame_system_extensions.rs @@ -0,0 +1,121 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `frame_system_extensions` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=frame_system_extensions +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/ +// --chain=bridge-hub-rococo-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_system_extensions`. +pub struct WeightInfo(PhantomData); +impl frame_system::ExtensionsWeightInfo for WeightInfo { + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_genesis() -> Weight { + // Proof Size summary in bytes: + // Measured: `54` + // Estimated: `3509` + // Minimum execution time: 3_136_000 picoseconds. + Weight::from_parts(5_842_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_mortality() -> Weight { + // Proof Size summary in bytes: + // Measured: `92` + // Estimated: `3509` + // Minimum execution time: 5_771_000 picoseconds. + Weight::from_parts(8_857_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + fn check_non_zero_sender() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 732_000 picoseconds. + Weight::from_parts(2_875_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_nonce() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_627_000 picoseconds. + Weight::from_parts(6_322_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_spec_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 471_000 picoseconds. + Weight::from_parts(2_455_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_tx_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 491_000 picoseconds. + Weight::from_parts(2_916_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) + /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::BlockWeight` (r:1 w:1) + /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) + fn check_weight() -> Weight { + // Proof Size summary in bytes: + // Measured: `24` + // Estimated: `1533` + // Minimum execution time: 3_798_000 picoseconds. + Weight::from_parts(6_272_000, 0) + .saturating_add(Weight::from_parts(0, 1533)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs index aac39a4564f..d97a30db954 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs @@ -25,6 +25,7 @@ pub mod cumulus_pallet_parachain_system; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; +pub mod frame_system_extensions; pub mod pallet_balances; pub mod pallet_bridge_grandpa; pub mod pallet_bridge_messages_rococo_to_rococo_bulletin; @@ -36,6 +37,7 @@ pub mod pallet_message_queue; pub mod pallet_multisig; pub mod pallet_session; pub mod pallet_timestamp; +pub mod pallet_transaction_payment; pub mod pallet_utility; pub mod pallet_xcm; pub mod paritydb_weights; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_transaction_payment.rs new file mode 100644 index 00000000000..71d17e7259f --- /dev/null +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_transaction_payment.rs @@ -0,0 +1,67 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `pallet_transaction_payment` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=pallet_transaction_payment +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/ +// --chain=bridge-hub-rococo-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_transaction_payment`. +pub struct WeightInfo(PhantomData); +impl pallet_transaction_payment::WeightInfo for WeightInfo { + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn charge_transaction_payment() -> Weight { + // Proof Size summary in bytes: + // Measured: `3` + // Estimated: `3593` + // Minimum execution time: 34_956_000 picoseconds. + Weight::from_parts(40_788_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs index 239bd946e75..46c5df18a15 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs @@ -22,7 +22,7 @@ use bridge_hub_rococo_runtime::{ bridge_to_westend_config::OnBridgeHubRococoRefundBridgeHubWestendMessages, xcm_config::XcmConfig, AllPalletsWithoutSystem, BridgeRejectObsoleteHeadersAndMessages, Executive, MessageQueueServiceWeight, Runtime, RuntimeCall, RuntimeEvent, SessionKeys, - SignedExtra, UncheckedExtrinsic, + TxExtension, UncheckedExtrinsic, }; use codec::{Decode, Encode}; use cumulus_primitives_core::XcmError::{FailedToTransactAsset, NotHoldingFees}; @@ -171,7 +171,7 @@ fn construct_extrinsic( call: RuntimeCall, ) -> UncheckedExtrinsic { let account_id = AccountId32::from(sender.public()); - let extra: SignedExtra = ( + let tx_ext: TxExtension = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -188,13 +188,13 @@ fn construct_extrinsic( OnBridgeHubRococoRefundRococoBulletinMessages::default(), ), ); - let payload = SignedPayload::new(call.clone(), extra.clone()).unwrap(); + let payload = SignedPayload::new(call.clone(), tx_ext.clone()).unwrap(); let signature = payload.using_encoded(|e| sender.sign(e)); UncheckedExtrinsic::new_signed( call, account_id.into(), Signature::Sr25519(signature.clone()), - extra, + tx_ext, ) } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs index f11954cf165..565343c55a5 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs @@ -22,7 +22,7 @@ use bridge_hub_rococo_runtime::{ xcm_config::{RelayNetwork, TokenLocation, XcmConfig}, AllPalletsWithoutSystem, BridgeRejectObsoleteHeadersAndMessages, EthereumGatewayAddress, Executive, ExistentialDeposit, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, - RuntimeEvent, RuntimeOrigin, SessionKeys, SignedExtra, TransactionPayment, UncheckedExtrinsic, + RuntimeEvent, RuntimeOrigin, SessionKeys, TransactionPayment, TxExtension, UncheckedExtrinsic, }; use bridge_hub_test_utils::SlotDurations; use codec::{Decode, Encode}; @@ -48,7 +48,7 @@ fn construct_extrinsic( call: RuntimeCall, ) -> UncheckedExtrinsic { let account_id = AccountId32::from(sender.public()); - let extra: SignedExtra = ( + let tx_ext: TxExtension = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -64,14 +64,15 @@ fn construct_extrinsic( bridge_to_westend_config::OnBridgeHubRococoRefundBridgeHubWestendMessages::default(), bridge_to_bulletin_config::OnBridgeHubRococoRefundRococoBulletinMessages::default(), ), - ); - let payload = SignedPayload::new(call.clone(), extra.clone()).unwrap(); + ) + .into(); + let payload = SignedPayload::new(call.clone(), tx_ext.clone()).unwrap(); let signature = payload.using_encoded(|e| sender.sign(e)); UncheckedExtrinsic::new_signed( call, account_id.into(), Signature::Sr25519(signature.clone()), - extra, + tx_ext, ) } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml index 8623f7cb366..b5fe093b8be 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml @@ -204,6 +204,7 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm-bridge-hub/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index bce722aa5f8..934dce5c2c4 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -36,7 +36,7 @@ use bridge_runtime_common::{ XcmBlobMessageDispatch, XcmVersionOfDestAndRemoteBridge, }, refund_relayer_extension::{ - ActualFeeRefund, RefundBridgedParachainMessages, RefundSignedExtensionAdapter, + ActualFeeRefund, RefundBridgedParachainMessages, RefundTransactionExtensionAdapter, RefundableMessagesLane, RefundableParachain, }, }; @@ -190,7 +190,7 @@ impl ThisChainWithMessages for BridgeHubWestend { } /// Signed extension that refunds relayers that are delivering messages from the Rococo parachain. -pub type OnBridgeHubWestendRefundBridgeHubRococoMessages = RefundSignedExtensionAdapter< +pub type OnBridgeHubWestendRefundBridgeHubRococoMessages = RefundTransactionExtensionAdapter< RefundBridgedParachainMessages< Runtime, RefundableParachain, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index e1344fce63d..86ed8b2f488 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -97,8 +97,8 @@ pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( +/// The TransactionExtension to the basic transaction logic. +pub type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -113,7 +113,7 @@ pub type SignedExtra = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. pub type Migrations = ( @@ -298,6 +298,7 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; + type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { @@ -515,12 +516,14 @@ bridge_runtime_common::generate_bridge_reject_obsolete_headers_and_messages! { mod benches { frame_benchmarking::define_benchmarks!( [frame_system, SystemBench::] + [frame_system_extensions, SystemExtensionsBench::] [pallet_balances, Balances] [pallet_message_queue, MessageQueue] [pallet_multisig, Multisig] [pallet_session, SessionBench::] [pallet_utility, Utility] [pallet_timestamp, Timestamp] + [pallet_transaction_payment, TransactionPayment] [pallet_collator_selection, CollatorSelection] [cumulus_pallet_parachain_system, ParachainSystem] [cumulus_pallet_xcmp_queue, XcmpQueue] @@ -761,6 +764,7 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; @@ -790,6 +794,7 @@ impl_runtime_apis! { use sp_storage::TrackedStorageKey; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; impl frame_system_benchmarking::Config for Runtime { fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); @@ -1135,16 +1140,16 @@ mod tests { use codec::Encode; use sp_runtime::{ generic::Era, - traits::{SignedExtension, Zero}, + traits::{TransactionExtensionBase, Zero}, }; #[test] fn ensure_signed_extension_definition_is_compatible_with_relay() { - use bp_polkadot_core::SuffixedCommonSignedExtensionExt; + use bp_polkadot_core::SuffixedCommonTransactionExtensionExt; sp_io::TestExternalities::default().execute_with(|| { frame_system::BlockHash::::insert(BlockNumber::zero(), Hash::default()); - let payload: SignedExtra = ( + let payload: TxExtension = ( frame_system::CheckNonZeroSender::new(), frame_system::CheckSpecVersion::new(), frame_system::CheckTxVersion::new(), @@ -1157,10 +1162,10 @@ mod tests { ( bridge_to_rococo_config::OnBridgeHubWestendRefundBridgeHubRococoMessages::default(), ), - ); + ).into(); { - let bh_indirect_payload = bp_bridge_hub_westend::SignedExtension::from_params( + let bh_indirect_payload = bp_bridge_hub_westend::TransactionExtension::from_params( VERSION.spec_version, VERSION.transaction_version, bp_runtime::TransactionEra::Immortal, @@ -1171,8 +1176,8 @@ mod tests { ); assert_eq!(payload.encode(), bh_indirect_payload.encode()); assert_eq!( - payload.additional_signed().unwrap().encode(), - bh_indirect_payload.additional_signed().unwrap().encode() + payload.implicit().unwrap().encode(), + bh_indirect_payload.implicit().unwrap().encode() ) } }); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/frame_system_extensions.rs new file mode 100644 index 00000000000..06f1114b4de --- /dev/null +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/frame_system_extensions.rs @@ -0,0 +1,121 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `frame_system_extensions` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-westend-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=frame_system_extensions +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/ +// --chain=bridge-hub-westend-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_system_extensions`. +pub struct WeightInfo(PhantomData); +impl frame_system::ExtensionsWeightInfo for WeightInfo { + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_genesis() -> Weight { + // Proof Size summary in bytes: + // Measured: `54` + // Estimated: `3509` + // Minimum execution time: 3_166_000 picoseconds. + Weight::from_parts(6_021_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_mortality() -> Weight { + // Proof Size summary in bytes: + // Measured: `92` + // Estimated: `3509` + // Minimum execution time: 5_651_000 picoseconds. + Weight::from_parts(9_177_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + fn check_non_zero_sender() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 601_000 picoseconds. + Weight::from_parts(2_805_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_nonce() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_727_000 picoseconds. + Weight::from_parts(6_051_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_spec_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 471_000 picoseconds. + Weight::from_parts(2_494_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_tx_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 521_000 picoseconds. + Weight::from_parts(2_655_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) + /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::BlockWeight` (r:1 w:1) + /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) + fn check_weight() -> Weight { + // Proof Size summary in bytes: + // Measured: `24` + // Estimated: `1533` + // Minimum execution time: 3_808_000 picoseconds. + Weight::from_parts(6_402_000, 0) + .saturating_add(Weight::from_parts(0, 1533)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/mod.rs index a65ee31d3e5..e23033e0dfd 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/mod.rs @@ -25,6 +25,7 @@ pub mod cumulus_pallet_parachain_system; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; +pub mod frame_system_extensions; pub mod pallet_balances; pub mod pallet_bridge_grandpa; pub mod pallet_bridge_messages; @@ -35,6 +36,7 @@ pub mod pallet_message_queue; pub mod pallet_multisig; pub mod pallet_session; pub mod pallet_timestamp; +pub mod pallet_transaction_payment; pub mod pallet_utility; pub mod pallet_xcm; pub mod paritydb_weights; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_transaction_payment.rs new file mode 100644 index 00000000000..92c53b91879 --- /dev/null +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_transaction_payment.rs @@ -0,0 +1,67 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `pallet_transaction_payment` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-westend-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=pallet_transaction_payment +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/ +// --chain=bridge-hub-westend-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_transaction_payment`. +pub struct WeightInfo(PhantomData); +impl pallet_transaction_payment::WeightInfo for WeightInfo { + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn charge_transaction_payment() -> Weight { + // Proof Size summary in bytes: + // Measured: `3` + // Estimated: `3593` + // Minimum execution time: 40_286_000 picoseconds. + Weight::from_parts(45_816_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs index 149a3bbeb75..7ea22befe95 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs @@ -24,7 +24,7 @@ use bridge_hub_westend_runtime::{ xcm_config::{RelayNetwork, WestendLocation, XcmConfig}, AllPalletsWithoutSystem, BridgeRejectObsoleteHeadersAndMessages, Executive, ExistentialDeposit, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, - SignedExtra, TransactionPayment, UncheckedExtrinsic, + TransactionPayment, TxExtension, UncheckedExtrinsic, }; use bridge_to_rococo_config::{ BridgeGrandpaRococoInstance, BridgeHubRococoChainId, BridgeHubRococoLocation, @@ -65,7 +65,7 @@ fn construct_extrinsic( call: RuntimeCall, ) -> UncheckedExtrinsic { let account_id = AccountId32::from(sender.public()); - let extra: SignedExtra = ( + let tx_ext: TxExtension = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -78,14 +78,15 @@ fn construct_extrinsic( pallet_transaction_payment::ChargeTransactionPayment::::from(0), BridgeRejectObsoleteHeadersAndMessages::default(), (bridge_to_rococo_config::OnBridgeHubWestendRefundBridgeHubRococoMessages::default(),), - ); - let payload = SignedPayload::new(call.clone(), extra.clone()).unwrap(); + ) + .into(); + let payload = SignedPayload::new(call.clone(), tx_ext.clone()).unwrap(); let signature = payload.using_encoded(|e| sender.sign(e)); UncheckedExtrinsic::new_signed( call, account_id.into(), Signature::Sr25519(signature.clone()), - extra, + tx_ext, ) } diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml b/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml index ed264f28c26..32d7e97bc45 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml @@ -117,6 +117,7 @@ runtime-benchmarks = [ "pallet-salary/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index 6bcf98c428f..3887a1d74ec 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -175,6 +175,7 @@ impl frame_system::Config for Runtime { type Version = Version; type AccountData = pallet_balances::AccountData; type SystemWeightInfo = weights::frame_system::WeightInfo; + type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; type SS58Prefix = ConstU16<0>; type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; type MaxConsumers = frame_support::traits::ConstU32<16>; @@ -231,6 +232,7 @@ impl pallet_transaction_payment::Config for Runtime { type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; type OperationalFeeMultiplier = ConstU8<5>; + type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { @@ -707,8 +709,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( +/// The extension to the basic transaction logic. +pub type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -719,7 +721,7 @@ pub type SignedExtra = ( ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// All migrations executed on runtime upgrade as a nested tuple of types implementing /// `OnRuntimeUpgrade`. Included migrations must be idempotent. type Migrations = ( @@ -745,6 +747,7 @@ pub type Executive = frame_executive::Executive< mod benches { frame_benchmarking::define_benchmarks!( [frame_system, SystemBench::] + [frame_system_extensions, SystemExtensionsBench::] [pallet_balances, Balances] [pallet_message_queue, MessageQueue] [pallet_multisig, Multisig] @@ -752,6 +755,7 @@ mod benches { [pallet_session, SessionBench::] [pallet_utility, Utility] [pallet_timestamp, Timestamp] + [pallet_transaction_payment, TransactionPayment] [pallet_collator_selection, CollatorSelection] [cumulus_pallet_parachain_system, ParachainSystem] [cumulus_pallet_xcmp_queue, XcmpQueue] @@ -955,6 +959,7 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; @@ -972,6 +977,7 @@ impl_runtime_apis! { use sp_storage::TrackedStorageKey; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; impl frame_system_benchmarking::Config for Runtime { fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/frame_system_extensions.rs new file mode 100644 index 00000000000..f3030cc4f6a --- /dev/null +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/frame_system_extensions.rs @@ -0,0 +1,121 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `frame_system_extensions` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("collectives-westend-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=frame_system_extensions +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/ +// --chain=collectives-westend-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_system_extensions`. +pub struct WeightInfo(PhantomData); +impl frame_system::ExtensionsWeightInfo for WeightInfo { + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_genesis() -> Weight { + // Proof Size summary in bytes: + // Measured: `54` + // Estimated: `3509` + // Minimum execution time: 3_497_000 picoseconds. + Weight::from_parts(5_961_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_mortality() -> Weight { + // Proof Size summary in bytes: + // Measured: `92` + // Estimated: `3509` + // Minimum execution time: 5_240_000 picoseconds. + Weight::from_parts(8_175_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + fn check_non_zero_sender() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 671_000 picoseconds. + Weight::from_parts(3_005_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_nonce() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_426_000 picoseconds. + Weight::from_parts(6_131_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_spec_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 501_000 picoseconds. + Weight::from_parts(2_715_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_tx_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 491_000 picoseconds. + Weight::from_parts(2_635_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) + /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::BlockWeight` (r:1 w:1) + /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) + fn check_weight() -> Weight { + // Proof Size summary in bytes: + // Measured: `24` + // Estimated: `1533` + // Minimum execution time: 3_958_000 picoseconds. + Weight::from_parts(6_753_000, 0) + .saturating_add(Weight::from_parts(0, 1533)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/mod.rs index a9a298e547e..00b3bd92d5e 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/mod.rs @@ -18,6 +18,7 @@ pub mod cumulus_pallet_parachain_system; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; +pub mod frame_system_extensions; pub mod pallet_alliance; pub mod pallet_asset_rate; pub mod pallet_balances; @@ -39,6 +40,7 @@ pub mod pallet_salary_fellowship_salary; pub mod pallet_scheduler; pub mod pallet_session; pub mod pallet_timestamp; +pub mod pallet_transaction_payment; pub mod pallet_treasury; pub mod pallet_utility; pub mod pallet_xcm; diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_transaction_payment.rs new file mode 100644 index 00000000000..5d077b89d56 --- /dev/null +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_transaction_payment.rs @@ -0,0 +1,67 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `pallet_transaction_payment` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("collectives-westend-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=pallet_transaction_payment +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/ +// --chain=collectives-westend-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_transaction_payment`. +pub struct WeightInfo(PhantomData); +impl pallet_transaction_payment::WeightInfo for WeightInfo { + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn charge_transaction_payment() -> Weight { + // Proof Size summary in bytes: + // Measured: `4` + // Estimated: `3593` + // Minimum execution time: 39_815_000 picoseconds. + Weight::from_parts(46_067_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml b/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml index dcc6c4e853a..747f75cf2e2 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml @@ -158,6 +158,7 @@ runtime-benchmarks = [ "pallet-multisig/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "parachains-common/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index 0668b9a4c7d..8ce46ccd34f 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -80,8 +80,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( +/// The extension to the basic transaction logic. +pub type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -93,7 +93,7 @@ pub type SignedExtra = ( ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. pub type Migrations = ( @@ -240,6 +240,7 @@ impl pallet_transaction_payment::Config for Runtime { type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; type OperationalFeeMultiplier = ConstU8<5>; + type WeightInfo = pallet_transaction_payment::weights::SubstrateWeight; } parameter_types! { @@ -423,6 +424,7 @@ construct_runtime!( mod benches { frame_benchmarking::define_benchmarks!( [frame_system, SystemBench::] + [frame_system_extensions, SystemExtensionsBench::] [pallet_balances, Balances] [pallet_message_queue, MessageQueue] [pallet_multisig, Multisig] @@ -686,6 +688,7 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; @@ -703,6 +706,7 @@ impl_runtime_apis! { use sp_storage::TrackedStorageKey; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; impl frame_system_benchmarking::Config for Runtime { fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml index 0bc3b510ed5..70a6a81bdcf 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml @@ -156,6 +156,7 @@ runtime-benchmarks = [ "pallet-multisig/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index cdff371c505..9913e47a93a 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -89,8 +89,8 @@ pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( +/// The TransactionExtension to the basic transaction logic. +pub type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -103,7 +103,7 @@ pub type SignedExtra = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. pub type Migrations = ( @@ -192,6 +192,8 @@ impl frame_system::Config for Runtime { type DbWeight = RocksDbWeight; /// Weight information for the extrinsics of this pallet. type SystemWeightInfo = weights::frame_system::WeightInfo; + /// Weight information for the extensions of this pallet. + type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; /// Block & extrinsics weights: base values and limits. type BlockWeights = RuntimeBlockWeights; /// The maximum length of a block (in bytes). @@ -251,6 +253,7 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; + type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system_extensions.rs new file mode 100644 index 00000000000..aac73680ad1 --- /dev/null +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system_extensions.rs @@ -0,0 +1,121 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `frame_system_extensions` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=frame_system_extensions +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ +// --chain=coretime-rococo-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_system_extensions`. +pub struct WeightInfo(PhantomData); +impl frame_system::ExtensionsWeightInfo for WeightInfo { + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_genesis() -> Weight { + // Proof Size summary in bytes: + // Measured: `54` + // Estimated: `3509` + // Minimum execution time: 3_637_000 picoseconds. + Weight::from_parts(6_382_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_mortality() -> Weight { + // Proof Size summary in bytes: + // Measured: `92` + // Estimated: `3509` + // Minimum execution time: 5_841_000 picoseconds. + Weight::from_parts(8_776_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + fn check_non_zero_sender() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 561_000 picoseconds. + Weight::from_parts(2_705_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_nonce() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_316_000 picoseconds. + Weight::from_parts(5_771_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_spec_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 511_000 picoseconds. + Weight::from_parts(2_575_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_tx_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 501_000 picoseconds. + Weight::from_parts(2_595_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) + /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::BlockWeight` (r:1 w:1) + /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) + fn check_weight() -> Weight { + // Proof Size summary in bytes: + // Measured: `24` + // Estimated: `1533` + // Minimum execution time: 3_687_000 picoseconds. + Weight::from_parts(6_192_000, 0) + .saturating_add(Weight::from_parts(0, 1533)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/mod.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/mod.rs index f1050b3ae63..7b6ab611e6f 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/mod.rs @@ -22,6 +22,7 @@ pub mod cumulus_pallet_parachain_system; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; +pub mod frame_system_extensions; pub mod pallet_balances; pub mod pallet_broker; pub mod pallet_collator_selection; @@ -29,6 +30,7 @@ pub mod pallet_message_queue; pub mod pallet_multisig; pub mod pallet_session; pub mod pallet_timestamp; +pub mod pallet_transaction_payment; pub mod pallet_utility; pub mod pallet_xcm; pub mod paritydb_weights; diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_transaction_payment.rs new file mode 100644 index 00000000000..29d48abab89 --- /dev/null +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_transaction_payment.rs @@ -0,0 +1,67 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `pallet_transaction_payment` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=pallet_transaction_payment +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ +// --chain=coretime-rococo-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_transaction_payment`. +pub struct WeightInfo(PhantomData); +impl pallet_transaction_payment::WeightInfo for WeightInfo { + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn charge_transaction_payment() -> Weight { + // Proof Size summary in bytes: + // Measured: `4` + // Estimated: `3593` + // Minimum execution time: 33_363_000 picoseconds. + Weight::from_parts(38_793_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml b/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml index a7d52dfd784..549ef7ce4d7 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml @@ -153,6 +153,7 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index 7fa70647992..1a330821d3f 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -89,8 +89,8 @@ pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( +/// The TransactionExtension to the basic transaction logic. +pub type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -103,7 +103,7 @@ pub type SignedExtra = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. pub type Migrations = ( @@ -192,6 +192,8 @@ impl frame_system::Config for Runtime { type DbWeight = RocksDbWeight; /// Weight information for the extrinsics of this pallet. type SystemWeightInfo = weights::frame_system::WeightInfo; + /// Weight information for the extensions of this pallet. + type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; /// Block & extrinsics weights: base values and limits. type BlockWeights = RuntimeBlockWeights; /// The maximum length of a block (in bytes). @@ -251,6 +253,7 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; + type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/frame_system_extensions.rs new file mode 100644 index 00000000000..0683158a01a --- /dev/null +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/frame_system_extensions.rs @@ -0,0 +1,121 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `frame_system_extensions` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-westend-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=frame_system_extensions +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/ +// --chain=coretime-westend-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_system_extensions`. +pub struct WeightInfo(PhantomData); +impl frame_system::ExtensionsWeightInfo for WeightInfo { + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_genesis() -> Weight { + // Proof Size summary in bytes: + // Measured: `54` + // Estimated: `3509` + // Minimum execution time: 3_637_000 picoseconds. + Weight::from_parts(6_382_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_mortality() -> Weight { + // Proof Size summary in bytes: + // Measured: `92` + // Estimated: `3509` + // Minimum execution time: 5_841_000 picoseconds. + Weight::from_parts(8_776_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + fn check_non_zero_sender() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 561_000 picoseconds. + Weight::from_parts(2_705_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_nonce() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_316_000 picoseconds. + Weight::from_parts(5_771_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_spec_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 511_000 picoseconds. + Weight::from_parts(2_575_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_tx_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 501_000 picoseconds. + Weight::from_parts(2_595_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) + /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::BlockWeight` (r:1 w:1) + /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) + fn check_weight() -> Weight { + // Proof Size summary in bytes: + // Measured: `24` + // Estimated: `1533` + // Minimum execution time: 3_687_000 picoseconds. + Weight::from_parts(6_192_000, 0) + .saturating_add(Weight::from_parts(0, 1533)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/mod.rs index f1050b3ae63..7b6ab611e6f 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/mod.rs @@ -22,6 +22,7 @@ pub mod cumulus_pallet_parachain_system; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; +pub mod frame_system_extensions; pub mod pallet_balances; pub mod pallet_broker; pub mod pallet_collator_selection; @@ -29,6 +30,7 @@ pub mod pallet_message_queue; pub mod pallet_multisig; pub mod pallet_session; pub mod pallet_timestamp; +pub mod pallet_transaction_payment; pub mod pallet_utility; pub mod pallet_xcm; pub mod paritydb_weights; diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_transaction_payment.rs new file mode 100644 index 00000000000..f159f877afe --- /dev/null +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_transaction_payment.rs @@ -0,0 +1,67 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `pallet_transaction_payment` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-westend-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=pallet_transaction_payment +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/ +// --chain=coretime-westend-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_transaction_payment`. +pub struct WeightInfo(PhantomData); +impl pallet_transaction_payment::WeightInfo for WeightInfo { + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn charge_transaction_payment() -> Weight { + // Proof Size summary in bytes: + // Measured: `4` + // Estimated: `3593` + // Minimum execution time: 33_363_000 picoseconds. + Weight::from_parts(38_793_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs index 232a82115a8..199057c3764 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs @@ -289,8 +289,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( +/// The extension to the basic transaction logic. +pub type TxExtension = ( pallet_sudo::CheckOnlySudoAccount, frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, @@ -301,7 +301,7 @@ pub type SignedExtra = ( ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, @@ -316,6 +316,7 @@ mod benches { frame_benchmarking::define_benchmarks!( [cumulus_pallet_parachain_system, ParachainSystem] [frame_system, SystemBench::] + [frame_system_extensions, SystemExtensionsBench::] [pallet_glutton, Glutton] [pallet_message_queue, MessageQueue] [pallet_timestamp, Timestamp] @@ -439,6 +440,7 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; let mut list = Vec::::new(); list_benchmarks!(list, extra); @@ -455,6 +457,7 @@ impl_runtime_apis! { use sp_storage::TrackedStorageKey; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; impl frame_system_benchmarking::Config for Runtime { fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/weights/frame_system_extensions.rs new file mode 100644 index 00000000000..e6efa762308 --- /dev/null +++ b/cumulus/parachains/runtimes/glutton/glutton-westend/src/weights/frame_system_extensions.rs @@ -0,0 +1,119 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `frame_system_extensions` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("glutton-westend-dev-1300")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=frame_system_extensions +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/glutton/glutton-westend/src/weights/ +// --chain=glutton-westend-dev-1300 + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_system_extensions`. +pub struct WeightInfo(PhantomData); +impl frame_system::ExtensionsWeightInfo for WeightInfo { + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_genesis() -> Weight { + // Proof Size summary in bytes: + // Measured: `54` + // Estimated: `3509` + // Minimum execution time: 3_908_000 picoseconds. + Weight::from_parts(4_007_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_mortality() -> Weight { + // Proof Size summary in bytes: + // Measured: `92` + // Estimated: `3509` + // Minimum execution time: 5_510_000 picoseconds. + Weight::from_parts(6_332_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + fn check_non_zero_sender() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 651_000 picoseconds. + Weight::from_parts(851_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_nonce() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_387_000 picoseconds. + Weight::from_parts(3_646_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_spec_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 491_000 picoseconds. + Weight::from_parts(651_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_tx_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 451_000 picoseconds. + Weight::from_parts(662_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) + /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn check_weight() -> Weight { + // Proof Size summary in bytes: + // Measured: `24` + // Estimated: `1489` + // Minimum execution time: 3_537_000 picoseconds. + Weight::from_parts(4_208_000, 0) + .saturating_add(Weight::from_parts(0, 1489)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml b/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml index c0b8fb7636b..c9781639c3e 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml @@ -152,6 +152,7 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index 2b8cc32f67c..c5e420785de 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -83,8 +83,8 @@ pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( +/// The TransactionExtension to the basic transaction logic. +pub type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -97,7 +97,7 @@ pub type SignedExtra = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. pub type Migrations = ( @@ -178,6 +178,7 @@ impl frame_system::Config for Runtime { type Version = Version; type AccountData = pallet_balances::AccountData; type SystemWeightInfo = weights::frame_system::WeightInfo; + type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; type SS58Prefix = SS58Prefix; type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; type MaxConsumers = ConstU32<16>; @@ -232,6 +233,7 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; + type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { @@ -453,6 +455,7 @@ mod benches { [pallet_session, SessionBench::] [pallet_utility, Utility] [pallet_timestamp, Timestamp] + [pallet_transaction_payment, TransactionPayment] // Polkadot [polkadot_runtime_common::identity_migrator, IdentityMigrator] // Cumulus diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/frame_system_extensions.rs new file mode 100644 index 00000000000..1ba2010991f --- /dev/null +++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/frame_system_extensions.rs @@ -0,0 +1,121 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `frame_system_extensions` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("people-rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=frame_system_extensions +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/people/people-rococo/src/weights/ +// --chain=people-rococo-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_system_extensions`. +pub struct WeightInfo(PhantomData); +impl frame_system::ExtensionsWeightInfo for WeightInfo { + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_genesis() -> Weight { + // Proof Size summary in bytes: + // Measured: `54` + // Estimated: `3509` + // Minimum execution time: 3_637_000 picoseconds. + Weight::from_parts(6_382_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_mortality() -> Weight { + // Proof Size summary in bytes: + // Measured: `92` + // Estimated: `3509` + // Minimum execution time: 5_841_000 picoseconds. + Weight::from_parts(8_776_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + fn check_non_zero_sender() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 561_000 picoseconds. + Weight::from_parts(2_705_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_nonce() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_316_000 picoseconds. + Weight::from_parts(5_771_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_spec_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 511_000 picoseconds. + Weight::from_parts(2_575_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_tx_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 501_000 picoseconds. + Weight::from_parts(2_595_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) + /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::BlockWeight` (r:1 w:1) + /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) + fn check_weight() -> Weight { + // Proof Size summary in bytes: + // Measured: `24` + // Estimated: `1533` + // Minimum execution time: 3_687_000 picoseconds. + Weight::from_parts(6_192_000, 0) + .saturating_add(Weight::from_parts(0, 1533)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/mod.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/mod.rs index 3396a8caea0..c4cea99ee5a 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/mod.rs @@ -20,6 +20,7 @@ pub mod cumulus_pallet_parachain_system; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; +pub mod frame_system_extensions; pub mod pallet_balances; pub mod pallet_collator_selection; pub mod pallet_identity; @@ -27,6 +28,7 @@ pub mod pallet_message_queue; pub mod pallet_multisig; pub mod pallet_session; pub mod pallet_timestamp; +pub mod pallet_transaction_payment; pub mod pallet_utility; pub mod pallet_xcm; pub mod paritydb_weights; diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_transaction_payment.rs new file mode 100644 index 00000000000..555fd5a32fa --- /dev/null +++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_transaction_payment.rs @@ -0,0 +1,67 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `pallet_transaction_payment` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("people-rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=pallet_transaction_payment +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/people/people-rococo/src/weights/ +// --chain=people-rococo-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_transaction_payment`. +pub struct WeightInfo(PhantomData); +impl pallet_transaction_payment::WeightInfo for WeightInfo { + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn charge_transaction_payment() -> Weight { + // Proof Size summary in bytes: + // Measured: `4` + // Estimated: `3593` + // Minimum execution time: 33_363_000 picoseconds. + Weight::from_parts(38_793_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/cumulus/parachains/runtimes/people/people-westend/Cargo.toml b/cumulus/parachains/runtimes/people/people-westend/Cargo.toml index e87e825a34e..8d8421332c1 100644 --- a/cumulus/parachains/runtimes/people/people-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/people/people-westend/Cargo.toml @@ -152,6 +152,7 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index 2dc2d06a66b..dea079a4a98 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -83,8 +83,8 @@ pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( +/// The transactionExtension to the basic transaction logic. +pub type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -97,7 +97,7 @@ pub type SignedExtra = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. pub type Migrations = ( @@ -178,6 +178,7 @@ impl frame_system::Config for Runtime { type Version = Version; type AccountData = pallet_balances::AccountData; type SystemWeightInfo = weights::frame_system::WeightInfo; + type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; type SS58Prefix = SS58Prefix; type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; type MaxConsumers = ConstU32<16>; @@ -232,6 +233,7 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; + type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/frame_system_extensions.rs new file mode 100644 index 00000000000..7130a62ab6a --- /dev/null +++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/frame_system_extensions.rs @@ -0,0 +1,121 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `frame_system_extensions` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("people-westend-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=frame_system_extensions +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/people/people-westend/src/weights/ +// --chain=people-westend-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_system_extensions`. +pub struct WeightInfo(PhantomData); +impl frame_system::ExtensionsWeightInfo for WeightInfo { + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_genesis() -> Weight { + // Proof Size summary in bytes: + // Measured: `54` + // Estimated: `3509` + // Minimum execution time: 3_637_000 picoseconds. + Weight::from_parts(6_382_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_mortality() -> Weight { + // Proof Size summary in bytes: + // Measured: `92` + // Estimated: `3509` + // Minimum execution time: 5_841_000 picoseconds. + Weight::from_parts(8_776_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + fn check_non_zero_sender() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 561_000 picoseconds. + Weight::from_parts(2_705_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_nonce() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_316_000 picoseconds. + Weight::from_parts(5_771_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_spec_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 511_000 picoseconds. + Weight::from_parts(2_575_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_tx_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 501_000 picoseconds. + Weight::from_parts(2_595_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) + /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::BlockWeight` (r:1 w:1) + /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) + fn check_weight() -> Weight { + // Proof Size summary in bytes: + // Measured: `24` + // Estimated: `1533` + // Minimum execution time: 3_687_000 picoseconds. + Weight::from_parts(6_192_000, 0) + .saturating_add(Weight::from_parts(0, 1533)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/mod.rs index 3396a8caea0..c4cea99ee5a 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/mod.rs @@ -20,6 +20,7 @@ pub mod cumulus_pallet_parachain_system; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; +pub mod frame_system_extensions; pub mod pallet_balances; pub mod pallet_collator_selection; pub mod pallet_identity; @@ -27,6 +28,7 @@ pub mod pallet_message_queue; pub mod pallet_multisig; pub mod pallet_session; pub mod pallet_timestamp; +pub mod pallet_transaction_payment; pub mod pallet_utility; pub mod pallet_xcm; pub mod paritydb_weights; diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_transaction_payment.rs new file mode 100644 index 00000000000..30e4524e586 --- /dev/null +++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_transaction_payment.rs @@ -0,0 +1,67 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `pallet_transaction_payment` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("people-westend-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot-parachain +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet=pallet_transaction_payment +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=2 +// --repeat=2 +// --json +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/people/people-westend/src/weights/ +// --chain=people-westend-dev + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_transaction_payment`. +pub struct WeightInfo(PhantomData); +impl pallet_transaction_payment::WeightInfo for WeightInfo { + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn charge_transaction_payment() -> Weight { + // Proof Size summary in bytes: + // Measured: `4` + // Estimated: `3593` + // Minimum execution time: 33_363_000 picoseconds. + Weight::from_parts(38_793_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/cumulus/parachains/runtimes/starters/seedling/src/lib.rs b/cumulus/parachains/runtimes/starters/seedling/src/lib.rs index 4cc0a81ef49..023c9978302 100644 --- a/cumulus/parachains/runtimes/starters/seedling/src/lib.rs +++ b/cumulus/parachains/runtimes/starters/seedling/src/lib.rs @@ -258,8 +258,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( +/// The extension to the basic transaction logic. +pub type TxExtension = ( frame_system::CheckSpecVersion, frame_system::CheckTxVersion, frame_system::CheckGenesis, @@ -269,7 +269,7 @@ pub type SignedExtra = ( ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< diff --git a/cumulus/parachains/runtimes/starters/shell/src/lib.rs b/cumulus/parachains/runtimes/starters/shell/src/lib.rs index 829754731a4..fedac36e48d 100644 --- a/cumulus/parachains/runtimes/starters/shell/src/lib.rs +++ b/cumulus/parachains/runtimes/starters/shell/src/lib.rs @@ -34,15 +34,19 @@ pub mod xcm_config; use codec::{Decode, Encode}; use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; use cumulus_primitives_core::AggregateMessageOrigin; -use frame_support::unsigned::TransactionValidityError; use scale_info::TypeInfo; use sp_api::impl_runtime_apis; pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, - traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, DispatchInfoOf}, - transaction_validity::{TransactionSource, TransactionValidity}, + traits::{ + AccountIdLookup, BlakeTwo256, Block as BlockT, DispatchInfoOf, OriginOf, + TransactionExtension, TransactionExtensionBase, ValidateResult, + }, + transaction_validity::{ + InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError, + }, ApplyExtrinsicResult, }; use sp_std::prelude::*; @@ -275,35 +279,37 @@ construct_runtime! { /// Simple implementation which fails any transaction which is signed. #[derive(Eq, PartialEq, Clone, Default, sp_core::RuntimeDebug, Encode, Decode, TypeInfo)] pub struct DisallowSigned; -impl sp_runtime::traits::SignedExtension for DisallowSigned { + +impl TransactionExtensionBase for DisallowSigned { const IDENTIFIER: &'static str = "DisallowSigned"; - type AccountId = AccountId; - type Call = RuntimeCall; - type AdditionalSigned = (); + type Implicit = (); +} + +impl TransactionExtension for DisallowSigned { + type Val = (); type Pre = (); - fn additional_signed( + fn validate( &self, - ) -> sp_std::result::Result<(), sp_runtime::transaction_validity::TransactionValidityError> { - Ok(()) + _origin: OriginOf, + _call: &RuntimeCall, + _info: &DispatchInfoOf, + _len: usize, + _context: &mut C, + _self_implicit: Self::Implicit, + _inherited_implication: &impl Encode, + ) -> ValidateResult { + Err(InvalidTransaction::BadProof.into()) } - fn pre_dispatch( + fn prepare( self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> Result { - self.validate(who, call, info, len).map(|_| ()) - } - fn validate( - &self, - _who: &Self::AccountId, - _call: &Self::Call, - _info: &sp_runtime::traits::DispatchInfoOf, + _val: Self::Val, + _origin: &OriginOf, + _call: &RuntimeCall, + _info: &DispatchInfoOf, _len: usize, - ) -> TransactionValidity { - let i = sp_runtime::transaction_validity::InvalidTransaction::BadProof; - Err(sp_runtime::transaction_validity::TransactionValidityError::Invalid(i)) + _context: &C, + ) -> Result { + Err(InvalidTransaction::BadProof.into()) } } @@ -323,11 +329,11 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = DisallowSigned; +/// The extension to the basic transaction logic. +pub type TxExtension = DisallowSigned; /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, diff --git a/cumulus/parachains/runtimes/testing/penpal/Cargo.toml b/cumulus/parachains/runtimes/testing/penpal/Cargo.toml index 08e5987d43a..bca6aca051f 100644 --- a/cumulus/parachains/runtimes/testing/penpal/Cargo.toml +++ b/cumulus/parachains/runtimes/testing/penpal/Cargo.toml @@ -158,6 +158,7 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "parachains-common/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs index 0030287edb3..62065619e42 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs @@ -114,8 +114,8 @@ pub type BlockId = generic::BlockId; // Id used for identifying assets. pub type AssetId = u32; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( +/// The extension to the basic transaction logic. +pub type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -128,7 +128,7 @@ pub type SignedExtra = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; pub type Migrations = ( pallet_balances::migration::MigrateToTrackInactive, @@ -419,6 +419,7 @@ impl pallet_transaction_payment::Config for Runtime { type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; type OperationalFeeMultiplier = ConstU8<5>; + type WeightInfo = (); } parameter_types! { @@ -608,6 +609,19 @@ impl pallet_collator_selection::Config for Runtime { type WeightInfo = (); } +#[cfg(feature = "runtime-benchmarks")] +pub struct AssetTxHelper; + +#[cfg(feature = "runtime-benchmarks")] +impl pallet_asset_tx_payment::BenchmarkHelperTrait for AssetTxHelper { + fn create_asset_id_parameter(_id: u32) -> (u32, u32) { + unimplemented!("Penpal uses default weights"); + } + fn setup_balances_and_pool(_asset_id: u32, _account: AccountId) { + unimplemented!("Penpal uses default weights"); + } +} + impl pallet_asset_tx_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Fungibles = Assets; @@ -620,6 +634,9 @@ impl pallet_asset_tx_payment::Config for Runtime { >, AssetsToBlockAuthor, >; + type WeightInfo = (); + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = AssetTxHelper; } impl pallet_sudo::Config for Runtime { @@ -668,6 +685,7 @@ construct_runtime!( mod benches { frame_benchmarking::define_benchmarks!( [frame_system, SystemBench::] + [frame_system_extensions, SystemExtensionsBench::] [pallet_balances, Balances] [pallet_message_queue, MessageQueue] [pallet_session, SessionBench::] @@ -851,6 +869,7 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; let mut list = Vec::::new(); @@ -867,6 +886,7 @@ impl_runtime_apis! { use sp_storage::TrackedStorageKey; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; impl frame_system_benchmarking::Config for Runtime {} use cumulus_pallet_session_benchmarking::Pallet as SessionBench; diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml b/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml index 42169e8949f..2023d9abf5d 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml @@ -126,6 +126,7 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "parachains-common/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs index 2b21a12c3ca..469f06a1aa6 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs @@ -267,6 +267,7 @@ impl pallet_transaction_payment::Config for Runtime { type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = (); type OperationalFeeMultiplier = ConstU8<5>; + type WeightInfo = (); } impl pallet_sudo::Config for Runtime { @@ -644,8 +645,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( +/// The extension to the basic transaction logic. +pub type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -657,7 +658,7 @@ pub type SignedExtra = ( ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, diff --git a/cumulus/polkadot-parachain/Cargo.toml b/cumulus/polkadot-parachain/Cargo.toml index 84a232e954f..a92e8a4c12a 100644 --- a/cumulus/polkadot-parachain/Cargo.toml +++ b/cumulus/polkadot-parachain/Cargo.toml @@ -136,6 +136,7 @@ runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "glutton-westend-runtime/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "parachains-common/runtime-benchmarks", "penpal-runtime/runtime-benchmarks", "people-rococo-runtime/runtime-benchmarks", diff --git a/cumulus/primitives/storage-weight-reclaim/Cargo.toml b/cumulus/primitives/storage-weight-reclaim/Cargo.toml index 4835fb5192b..9e8f60783d4 100644 --- a/cumulus/primitives/storage-weight-reclaim/Cargo.toml +++ b/cumulus/primitives/storage-weight-reclaim/Cargo.toml @@ -14,9 +14,12 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = log = { workspace = true } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } +frame-benchmarking = { path = "../../../substrate/frame/benchmarking", default-features = false, optional = true } frame-support = { path = "../../../substrate/frame/support", default-features = false } frame-system = { path = "../../../substrate/frame/system", default-features = false } +sp-core = { path = "../../../substrate/primitives/core", default-features = false } +sp-io = { path = "../../../substrate/primitives/io", default-features = false } sp-runtime = { path = "../../../substrate/primitives/runtime", default-features = false } sp-std = { path = "../../../substrate/primitives/std", default-features = false } @@ -26,19 +29,27 @@ docify = "0.2.7" [dev-dependencies] sp-trie = { path = "../../../substrate/primitives/trie", default-features = false } -sp-io = { path = "../../../substrate/primitives/io", default-features = false } cumulus-test-runtime = { path = "../../test/runtime" } [features] default = ["std"] +runtime-benchmarks = [ + "cumulus-primitives-core/runtime-benchmarks", + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] std = [ "codec/std", "cumulus-primitives-core/std", "cumulus-primitives-proof-size-hostfunction/std", + "frame-benchmarking/std", "frame-support/std", "frame-system/std", "log/std", "scale-info/std", + "sp-core/std", "sp-io/std", "sp-runtime/std", "sp-std/std", diff --git a/cumulus/primitives/storage-weight-reclaim/src/benchmarking.rs b/cumulus/primitives/storage-weight-reclaim/src/benchmarking.rs new file mode 100644 index 00000000000..2980d08271a --- /dev/null +++ b/cumulus/primitives/storage-weight-reclaim/src/benchmarking.rs @@ -0,0 +1,70 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Benchmarking setup for cumulus-primitives-storage-weight-reclaim + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; + +use frame_benchmarking::{account, v2::*, BenchmarkError}; +use frame_support::pallet_prelude::DispatchClass; +use frame_system::{BlockWeight, RawOrigin}; +use sp_runtime::traits::{DispatchTransaction, Get}; +use sp_std::{ + marker::{Send, Sync}, + prelude::*, +}; + +/// Pallet we're benchmarking here. +pub struct Pallet(frame_system::Pallet); + +#[benchmarks(where + T: Send + Sync, + T::RuntimeCall: Dispatchable +)] +mod benchmarks { + use super::*; + + #[benchmark] + fn storage_weight_reclaim() -> Result<(), BenchmarkError> { + let caller = account("caller", 0, 0); + BlockWeight::::mutate(|current_weight| { + current_weight.set(Weight::from_parts(0, 1000), DispatchClass::Normal); + }); + let base_extrinsic = ::BlockWeights::get() + .get(DispatchClass::Normal) + .base_extrinsic; + let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() }; + let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into(); + let post_info = PostDispatchInfo { + actual_weight: Some(Weight::from_parts(0, 200)), + pays_fee: Default::default(), + }; + let len = 0_usize; + let ext = StorageWeightReclaim::::new(); + + #[block] + { + ext.test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(post_info)) + .unwrap() + .unwrap(); + } + + assert_eq!(BlockWeight::::get().total().proof_size(), 700 + base_extrinsic.proof_size()); + + Ok(()) + } +} diff --git a/cumulus/primitives/storage-weight-reclaim/src/lib.rs b/cumulus/primitives/storage-weight-reclaim/src/lib.rs index 5dddc92e395..4bb40176b78 100644 --- a/cumulus/primitives/storage-weight-reclaim/src/lib.rs +++ b/cumulus/primitives/storage-weight-reclaim/src/lib.rs @@ -29,12 +29,22 @@ use frame_support::{ use frame_system::Config; use scale_info::TypeInfo; use sp_runtime::{ - traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf, SignedExtension}, + impl_tx_ext_default, + traits::{ + DispatchInfoOf, Dispatchable, PostDispatchInfoOf, TransactionExtension, + TransactionExtensionBase, + }, transaction_validity::TransactionValidityError, DispatchResult, }; use sp_std::marker::PhantomData; +#[cfg(test)] +mod tests; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + const LOG_TARGET: &'static str = "runtime::storage_reclaim"; /// `StorageWeightReclaimer` is a mechanism for manually reclaiming storage weight. @@ -43,7 +53,7 @@ const LOG_TARGET: &'static str = "runtime::storage_reclaim"; /// reclaim it computes the real consumed storage weight and refunds excess weight. /// /// # Example -#[doc = docify::embed!("src/lib.rs", simple_reclaimer_example)] +#[doc = docify::embed!("src/tests.rs", simple_reclaimer_example)] pub struct StorageWeightReclaimer { previous_remaining_proof_size: u64, previous_reported_proof_size: Option, @@ -119,42 +129,40 @@ impl core::fmt::Debug for StorageWeightReclaim { } } -impl SignedExtension for StorageWeightReclaim +impl TransactionExtensionBase for StorageWeightReclaim { + const IDENTIFIER: &'static str = "StorageWeightReclaim"; + type Implicit = (); +} + +impl TransactionExtension + for StorageWeightReclaim where T::RuntimeCall: Dispatchable, { - const IDENTIFIER: &'static str = "StorageWeightReclaim"; - - type AccountId = T::AccountId; - type Call = T::RuntimeCall; - type AdditionalSigned = (); + type Val = (); type Pre = Option; - fn additional_signed( - &self, - ) -> Result - { - Ok(()) - } - - fn pre_dispatch( + fn prepare( self, - _who: &Self::AccountId, - _call: &Self::Call, - _info: &sp_runtime::traits::DispatchInfoOf, + _val: Self::Val, + _origin: &T::RuntimeOrigin, + _call: &T::RuntimeCall, + _info: &DispatchInfoOf, _len: usize, - ) -> Result { + _context: &Context, + ) -> Result { Ok(get_proof_size()) } fn post_dispatch( - pre: Option, - info: &DispatchInfoOf, - post_info: &PostDispatchInfoOf, + pre: Self::Pre, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, _len: usize, _result: &DispatchResult, + _context: &Context, ) -> Result<(), TransactionValidityError> { - let Some(Some(pre_dispatch_proof_size)) = pre else { + let Some(pre_dispatch_proof_size) = pre else { return Ok(()); }; @@ -194,470 +202,6 @@ where }); Ok(()) } -} - -#[cfg(test)] -mod tests { - use super::*; - use frame_support::{ - assert_ok, - dispatch::DispatchClass, - weights::{Weight, WeightMeter}, - }; - use frame_system::{BlockWeight, CheckWeight}; - use sp_runtime::{AccountId32, BuildStorage}; - use sp_std::marker::PhantomData; - use sp_trie::proof_size_extension::ProofSizeExt; - - type Test = cumulus_test_runtime::Runtime; - const CALL: &::RuntimeCall = - &cumulus_test_runtime::RuntimeCall::System(frame_system::Call::set_heap_pages { - pages: 0u64, - }); - const ALICE: AccountId32 = AccountId32::new([1u8; 32]); - const LEN: usize = 0; - - pub fn new_test_ext() -> sp_io::TestExternalities { - let ext: sp_io::TestExternalities = cumulus_test_runtime::RuntimeGenesisConfig::default() - .build_storage() - .unwrap() - .into(); - ext - } - - struct TestRecorder { - return_values: Box<[usize]>, - counter: std::sync::atomic::AtomicUsize, - } - - impl TestRecorder { - fn new(values: &[usize]) -> Self { - TestRecorder { return_values: values.into(), counter: Default::default() } - } - } - - impl sp_trie::ProofSizeProvider for TestRecorder { - fn estimate_encoded_size(&self) -> usize { - let counter = self.counter.fetch_add(1, core::sync::atomic::Ordering::Relaxed); - self.return_values[counter] - } - } - - fn setup_test_externalities(proof_values: &[usize]) -> sp_io::TestExternalities { - let mut test_ext = new_test_ext(); - let test_recorder = TestRecorder::new(proof_values); - test_ext.register_extension(ProofSizeExt::new(test_recorder)); - test_ext - } - - fn set_current_storage_weight(new_weight: u64) { - BlockWeight::::mutate(|current_weight| { - current_weight.set(Weight::from_parts(0, new_weight), DispatchClass::Normal); - }); - } - - #[test] - fn basic_refund() { - // The real cost will be 100 bytes of storage size - let mut test_ext = setup_test_externalities(&[0, 100]); - - test_ext.execute_with(|| { - set_current_storage_weight(1000); - - // Benchmarked storage weight: 500 - let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() }; - let post_info = PostDispatchInfo::default(); - - let pre = StorageWeightReclaim::(PhantomData) - .pre_dispatch(&ALICE, CALL, &info, LEN) - .unwrap(); - assert_eq!(pre, Some(0)); - - assert_ok!(CheckWeight::::post_dispatch(None, &info, &post_info, 0, &Ok(()))); - // We expect a refund of 400 - assert_ok!(StorageWeightReclaim::::post_dispatch( - Some(pre), - &info, - &post_info, - LEN, - &Ok(()) - )); - - assert_eq!(BlockWeight::::get().total().proof_size(), 600); - }) - } - - #[test] - fn does_nothing_without_extension() { - let mut test_ext = new_test_ext(); - - // Proof size extension not registered - test_ext.execute_with(|| { - set_current_storage_weight(1000); - - // Benchmarked storage weight: 500 - let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() }; - let post_info = PostDispatchInfo::default(); - - let pre = StorageWeightReclaim::(PhantomData) - .pre_dispatch(&ALICE, CALL, &info, LEN) - .unwrap(); - assert_eq!(pre, None); - - assert_ok!(CheckWeight::::post_dispatch(None, &info, &post_info, 0, &Ok(()))); - assert_ok!(StorageWeightReclaim::::post_dispatch( - Some(pre), - &info, - &post_info, - LEN, - &Ok(()) - )); - - assert_eq!(BlockWeight::::get().total().proof_size(), 1000); - }) - } - - #[test] - fn negative_refund_is_added_to_weight() { - let mut test_ext = setup_test_externalities(&[100, 300]); - - test_ext.execute_with(|| { - set_current_storage_weight(1000); - // Benchmarked storage weight: 100 - let info = DispatchInfo { weight: Weight::from_parts(0, 100), ..Default::default() }; - let post_info = PostDispatchInfo::default(); - - let pre = StorageWeightReclaim::(PhantomData) - .pre_dispatch(&ALICE, CALL, &info, LEN) - .unwrap(); - assert_eq!(pre, Some(100)); - - // We expect no refund - assert_ok!(CheckWeight::::post_dispatch(None, &info, &post_info, 0, &Ok(()))); - assert_ok!(StorageWeightReclaim::::post_dispatch( - Some(pre), - &info, - &post_info, - LEN, - &Ok(()) - )); - - assert_eq!(BlockWeight::::get().total().proof_size(), 1100); - }) - } - - #[test] - fn test_zero_proof_size() { - let mut test_ext = setup_test_externalities(&[0, 0]); - - test_ext.execute_with(|| { - let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() }; - let post_info = PostDispatchInfo::default(); - - let pre = StorageWeightReclaim::(PhantomData) - .pre_dispatch(&ALICE, CALL, &info, LEN) - .unwrap(); - assert_eq!(pre, Some(0)); - - assert_ok!(CheckWeight::::post_dispatch(None, &info, &post_info, 0, &Ok(()))); - assert_ok!(StorageWeightReclaim::::post_dispatch( - Some(pre), - &info, - &post_info, - LEN, - &Ok(()) - )); - - assert_eq!(BlockWeight::::get().total().proof_size(), 0); - }); - } - - #[test] - fn test_larger_pre_dispatch_proof_size() { - let mut test_ext = setup_test_externalities(&[300, 100]); - - test_ext.execute_with(|| { - set_current_storage_weight(1300); - - let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() }; - let post_info = PostDispatchInfo::default(); - - let pre = StorageWeightReclaim::(PhantomData) - .pre_dispatch(&ALICE, CALL, &info, LEN) - .unwrap(); - assert_eq!(pre, Some(300)); - - assert_ok!(CheckWeight::::post_dispatch(None, &info, &post_info, 0, &Ok(()))); - assert_ok!(StorageWeightReclaim::::post_dispatch( - Some(pre), - &info, - &post_info, - LEN, - &Ok(()) - )); - - assert_eq!(BlockWeight::::get().total().proof_size(), 800); - }); - } - - #[test] - fn test_incorporates_check_weight_unspent_weight() { - let mut test_ext = setup_test_externalities(&[100, 300]); - - test_ext.execute_with(|| { - set_current_storage_weight(1000); - - // Benchmarked storage weight: 300 - let info = DispatchInfo { weight: Weight::from_parts(100, 300), ..Default::default() }; - - // Actual weight is 50 - let post_info = PostDispatchInfo { - actual_weight: Some(Weight::from_parts(50, 250)), - pays_fee: Default::default(), - }; - - let pre = StorageWeightReclaim::(PhantomData) - .pre_dispatch(&ALICE, CALL, &info, LEN) - .unwrap(); - assert_eq!(pre, Some(100)); - - // The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo` - // we always need to call `post_dispatch` to verify that they interoperate correctly. - assert_ok!(CheckWeight::::post_dispatch(None, &info, &post_info, 0, &Ok(()))); - assert_ok!(StorageWeightReclaim::::post_dispatch( - Some(pre), - &info, - &post_info, - LEN, - &Ok(()) - )); - - assert_eq!(BlockWeight::::get().total().proof_size(), 900); - }) - } - - #[test] - fn test_incorporates_check_weight_unspent_weight_on_negative() { - let mut test_ext = setup_test_externalities(&[100, 300]); - - test_ext.execute_with(|| { - set_current_storage_weight(1000); - // Benchmarked storage weight: 50 - let info = DispatchInfo { weight: Weight::from_parts(100, 50), ..Default::default() }; - - // Actual weight is 25 - let post_info = PostDispatchInfo { - actual_weight: Some(Weight::from_parts(50, 25)), - pays_fee: Default::default(), - }; - - let pre = StorageWeightReclaim::(PhantomData) - .pre_dispatch(&ALICE, CALL, &info, LEN) - .unwrap(); - assert_eq!(pre, Some(100)); - - // The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo` - // we always need to call `post_dispatch` to verify that they interoperate correctly. - assert_ok!(CheckWeight::::post_dispatch(None, &info, &post_info, 0, &Ok(()))); - assert_ok!(StorageWeightReclaim::::post_dispatch( - Some(pre), - &info, - &post_info, - LEN, - &Ok(()) - )); - - assert_eq!(BlockWeight::::get().total().proof_size(), 1150); - }) - } - - #[test] - fn test_incorporates_check_weight_unspent_weight_reverse_order() { - let mut test_ext = setup_test_externalities(&[100, 300]); - - test_ext.execute_with(|| { - set_current_storage_weight(1000); - - // Benchmarked storage weight: 300 - let info = DispatchInfo { weight: Weight::from_parts(100, 300), ..Default::default() }; - - // Actual weight is 50 - let post_info = PostDispatchInfo { - actual_weight: Some(Weight::from_parts(50, 250)), - pays_fee: Default::default(), - }; - - let pre = StorageWeightReclaim::(PhantomData) - .pre_dispatch(&ALICE, CALL, &info, LEN) - .unwrap(); - assert_eq!(pre, Some(100)); - - assert_ok!(StorageWeightReclaim::::post_dispatch( - Some(pre), - &info, - &post_info, - LEN, - &Ok(()) - )); - // `CheckWeight` gets called after `StorageWeightReclaim` this time. - // The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo` - // we always need to call `post_dispatch` to verify that they interoperate correctly. - assert_ok!(CheckWeight::::post_dispatch(None, &info, &post_info, 0, &Ok(()))); - - assert_eq!(BlockWeight::::get().total().proof_size(), 900); - }) - } - - #[test] - fn test_incorporates_check_weight_unspent_weight_on_negative_reverse_order() { - let mut test_ext = setup_test_externalities(&[100, 300]); - - test_ext.execute_with(|| { - set_current_storage_weight(1000); - // Benchmarked storage weight: 50 - let info = DispatchInfo { weight: Weight::from_parts(100, 50), ..Default::default() }; - // Actual weight is 25 - let post_info = PostDispatchInfo { - actual_weight: Some(Weight::from_parts(50, 25)), - pays_fee: Default::default(), - }; - - let pre = StorageWeightReclaim::(PhantomData) - .pre_dispatch(&ALICE, CALL, &info, LEN) - .unwrap(); - assert_eq!(pre, Some(100)); - - assert_ok!(StorageWeightReclaim::::post_dispatch( - Some(pre), - &info, - &post_info, - LEN, - &Ok(()) - )); - // `CheckWeight` gets called after `StorageWeightReclaim` this time. - // The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo` - // we always need to call `post_dispatch` to verify that they interoperate correctly. - assert_ok!(CheckWeight::::post_dispatch(None, &info, &post_info, 0, &Ok(()))); - - assert_eq!(BlockWeight::::get().total().proof_size(), 1150); - }) - } - - #[test] - fn storage_size_reported_correctly() { - let mut test_ext = setup_test_externalities(&[1000]); - test_ext.execute_with(|| { - assert_eq!(get_proof_size(), Some(1000)); - }); - - let mut test_ext = new_test_ext(); - - let test_recorder = TestRecorder::new(&[0]); - - test_ext.register_extension(ProofSizeExt::new(test_recorder)); - - test_ext.execute_with(|| { - assert_eq!(get_proof_size(), Some(0)); - }); - } - - #[test] - fn storage_size_disabled_reported_correctly() { - let mut test_ext = setup_test_externalities(&[PROOF_RECORDING_DISABLED as usize]); - - test_ext.execute_with(|| { - assert_eq!(get_proof_size(), None); - }); - } - - #[test] - fn test_reclaim_helper() { - let mut test_ext = setup_test_externalities(&[1000, 1300, 1800]); - - test_ext.execute_with(|| { - let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(0, 2000)); - let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter); - remaining_weight_meter.consume(Weight::from_parts(0, 500)); - let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); - - assert_eq!(reclaimed, Some(Weight::from_parts(0, 200))); - - remaining_weight_meter.consume(Weight::from_parts(0, 800)); - let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); - assert_eq!(reclaimed, Some(Weight::from_parts(0, 300))); - assert_eq!(remaining_weight_meter.remaining(), Weight::from_parts(0, 1200)); - }); - } - - #[test] - fn test_reclaim_helper_does_not_reclaim_negative() { - // Benchmarked weight does not change at all - let mut test_ext = setup_test_externalities(&[1000, 1300]); - - test_ext.execute_with(|| { - let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(0, 1000)); - let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter); - let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); - - assert_eq!(reclaimed, Some(Weight::from_parts(0, 0))); - assert_eq!(remaining_weight_meter.remaining(), Weight::from_parts(0, 1000)); - }); - - // Benchmarked weight increases less than storage proof consumes - let mut test_ext = setup_test_externalities(&[1000, 1300]); - - test_ext.execute_with(|| { - let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(0, 1000)); - let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter); - remaining_weight_meter.consume(Weight::from_parts(0, 0)); - let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); - - assert_eq!(reclaimed, Some(Weight::from_parts(0, 0))); - }); - } - - /// Just here for doc purposes - fn get_benched_weight() -> Weight { - Weight::from_parts(0, 5) - } - - /// Just here for doc purposes - fn do_work() {} - - #[docify::export_content(simple_reclaimer_example)] - fn reclaim_with_weight_meter() { - let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(10, 10)); - - let benched_weight = get_benched_weight(); - - // It is important to instantiate the `StorageWeightReclaimer` before we consume the weight - // for a piece of work from the weight meter. - let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter); - - if remaining_weight_meter.try_consume(benched_weight).is_ok() { - // Perform some work that takes has `benched_weight` storage weight. - do_work(); - - // Reclaimer will detect that we only consumed 2 bytes, so 3 bytes are reclaimed. - let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); - - // We reclaimed 3 bytes of storage size! - assert_eq!(reclaimed, Some(Weight::from_parts(0, 3))); - assert_eq!(BlockWeight::::get().total().proof_size(), 10); - assert_eq!(remaining_weight_meter.remaining(), Weight::from_parts(10, 8)); - } - } - - #[test] - fn test_reclaim_helper_works_with_meter() { - // The node will report 12 - 10 = 2 consumed storage size between the calls. - let mut test_ext = setup_test_externalities(&[10, 12]); - - test_ext.execute_with(|| { - // Initial storage size is 10. - set_current_storage_weight(10); - reclaim_with_weight_meter(); - }); - } + impl_tx_ext_default!(T::RuntimeCall; Context; validate); } diff --git a/cumulus/primitives/storage-weight-reclaim/src/tests.rs b/cumulus/primitives/storage-weight-reclaim/src/tests.rs new file mode 100644 index 00000000000..631827cf442 --- /dev/null +++ b/cumulus/primitives/storage-weight-reclaim/src/tests.rs @@ -0,0 +1,484 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use super::*; +use frame_support::{ + assert_ok, + dispatch::DispatchClass, + weights::{Weight, WeightMeter}, +}; +use frame_system::{BlockWeight, CheckWeight}; +use sp_runtime::{traits::DispatchTransaction, AccountId32, BuildStorage}; +use sp_std::marker::PhantomData; +use sp_trie::proof_size_extension::ProofSizeExt; + +type Test = cumulus_test_runtime::Runtime; +const CALL: &::RuntimeCall = + &cumulus_test_runtime::RuntimeCall::System(frame_system::Call::set_heap_pages { pages: 0u64 }); +const ALICE: AccountId32 = AccountId32::new([1u8; 32]); +const LEN: usize = 0; + +fn new_test_ext() -> sp_io::TestExternalities { + let ext: sp_io::TestExternalities = cumulus_test_runtime::RuntimeGenesisConfig::default() + .build_storage() + .unwrap() + .into(); + ext +} + +struct TestRecorder { + return_values: Box<[usize]>, + counter: std::sync::atomic::AtomicUsize, +} + +impl TestRecorder { + fn new(values: &[usize]) -> Self { + TestRecorder { return_values: values.into(), counter: Default::default() } + } +} + +impl sp_trie::ProofSizeProvider for TestRecorder { + fn estimate_encoded_size(&self) -> usize { + let counter = self.counter.fetch_add(1, core::sync::atomic::Ordering::Relaxed); + self.return_values[counter] + } +} + +fn setup_test_externalities(proof_values: &[usize]) -> sp_io::TestExternalities { + let mut test_ext = new_test_ext(); + let test_recorder = TestRecorder::new(proof_values); + test_ext.register_extension(ProofSizeExt::new(test_recorder)); + test_ext +} + +fn set_current_storage_weight(new_weight: u64) { + BlockWeight::::mutate(|current_weight| { + current_weight.set(Weight::from_parts(0, new_weight), DispatchClass::Normal); + }); +} + +#[test] +fn basic_refund() { + // The real cost will be 100 bytes of storage size + let mut test_ext = setup_test_externalities(&[0, 100]); + + test_ext.execute_with(|| { + set_current_storage_weight(1000); + + // Benchmarked storage weight: 500 + let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() }; + let post_info = PostDispatchInfo::default(); + + let (pre, _) = StorageWeightReclaim::(PhantomData) + .validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN) + .unwrap(); + assert_eq!(pre, Some(0)); + + assert_ok!(CheckWeight::::post_dispatch((), &info, &post_info, 0, &Ok(()), &())); + // We expect a refund of 400 + assert_ok!(StorageWeightReclaim::::post_dispatch( + pre, + &info, + &post_info, + LEN, + &Ok(()), + &() + )); + + assert_eq!(BlockWeight::::get().total().proof_size(), 600); + }) +} + +#[test] +fn does_nothing_without_extension() { + let mut test_ext = new_test_ext(); + + // Proof size extension not registered + test_ext.execute_with(|| { + set_current_storage_weight(1000); + + // Benchmarked storage weight: 500 + let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() }; + let post_info = PostDispatchInfo::default(); + + let (pre, _) = StorageWeightReclaim::(PhantomData) + .validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN) + .unwrap(); + assert_eq!(pre, None); + + assert_ok!(CheckWeight::::post_dispatch((), &info, &post_info, 0, &Ok(()), &())); + assert_ok!(StorageWeightReclaim::::post_dispatch( + pre, + &info, + &post_info, + LEN, + &Ok(()), + &() + )); + + assert_eq!(BlockWeight::::get().total().proof_size(), 1000); + }) +} + +#[test] +fn negative_refund_is_added_to_weight() { + let mut test_ext = setup_test_externalities(&[100, 300]); + + test_ext.execute_with(|| { + set_current_storage_weight(1000); + // Benchmarked storage weight: 100 + let info = DispatchInfo { weight: Weight::from_parts(0, 100), ..Default::default() }; + let post_info = PostDispatchInfo::default(); + + let (pre, _) = StorageWeightReclaim::(PhantomData) + .validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN) + .unwrap(); + assert_eq!(pre, Some(100)); + + // We expect no refund + assert_ok!(CheckWeight::::post_dispatch((), &info, &post_info, 0, &Ok(()), &())); + assert_ok!(StorageWeightReclaim::::post_dispatch( + pre, + &info, + &post_info, + LEN, + &Ok(()), + &() + )); + + assert_eq!(BlockWeight::::get().total().proof_size(), 1100); + }) +} + +#[test] +fn test_zero_proof_size() { + let mut test_ext = setup_test_externalities(&[0, 0]); + + test_ext.execute_with(|| { + let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() }; + let post_info = PostDispatchInfo::default(); + + let (pre, _) = StorageWeightReclaim::(PhantomData) + .validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN) + .unwrap(); + assert_eq!(pre, Some(0)); + + assert_ok!(CheckWeight::::post_dispatch((), &info, &post_info, 0, &Ok(()), &())); + assert_ok!(StorageWeightReclaim::::post_dispatch( + pre, + &info, + &post_info, + LEN, + &Ok(()), + &() + )); + + assert_eq!(BlockWeight::::get().total().proof_size(), 0); + }); +} + +#[test] +fn test_larger_pre_dispatch_proof_size() { + let mut test_ext = setup_test_externalities(&[300, 100]); + + test_ext.execute_with(|| { + set_current_storage_weight(1300); + + let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() }; + let post_info = PostDispatchInfo::default(); + + let (pre, _) = StorageWeightReclaim::(PhantomData) + .validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN) + .unwrap(); + assert_eq!(pre, Some(300)); + + assert_ok!(CheckWeight::::post_dispatch((), &info, &post_info, 0, &Ok(()), &())); + assert_ok!(StorageWeightReclaim::::post_dispatch( + pre, + &info, + &post_info, + LEN, + &Ok(()), + &() + )); + + assert_eq!(BlockWeight::::get().total().proof_size(), 800); + }); +} + +#[test] +fn test_incorporates_check_weight_unspent_weight() { + let mut test_ext = setup_test_externalities(&[100, 300]); + + test_ext.execute_with(|| { + set_current_storage_weight(1000); + + // Benchmarked storage weight: 300 + let info = DispatchInfo { weight: Weight::from_parts(100, 300), ..Default::default() }; + + // Actual weight is 50 + let post_info = PostDispatchInfo { + actual_weight: Some(Weight::from_parts(50, 250)), + pays_fee: Default::default(), + }; + + let (pre, _) = StorageWeightReclaim::(PhantomData) + .validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN) + .unwrap(); + assert_eq!(pre, Some(100)); + + // The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo` + // we always need to call `post_dispatch` to verify that they interoperate correctly. + assert_ok!(CheckWeight::::post_dispatch((), &info, &post_info, 0, &Ok(()), &())); + assert_ok!(StorageWeightReclaim::::post_dispatch( + pre, + &info, + &post_info, + LEN, + &Ok(()), + &() + )); + + assert_eq!(BlockWeight::::get().total().proof_size(), 900); + }) +} + +#[test] +fn test_incorporates_check_weight_unspent_weight_on_negative() { + let mut test_ext = setup_test_externalities(&[100, 300]); + + test_ext.execute_with(|| { + set_current_storage_weight(1000); + // Benchmarked storage weight: 50 + let info = DispatchInfo { weight: Weight::from_parts(100, 50), ..Default::default() }; + + // Actual weight is 25 + let post_info = PostDispatchInfo { + actual_weight: Some(Weight::from_parts(50, 25)), + pays_fee: Default::default(), + }; + + let (pre, _) = StorageWeightReclaim::(PhantomData) + .validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN) + .unwrap(); + assert_eq!(pre, Some(100)); + + // The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo` + // we always need to call `post_dispatch` to verify that they interoperate correctly. + assert_ok!(CheckWeight::::post_dispatch((), &info, &post_info, 0, &Ok(()), &())); + assert_ok!(StorageWeightReclaim::::post_dispatch( + pre, + &info, + &post_info, + LEN, + &Ok(()), + &() + )); + + assert_eq!(BlockWeight::::get().total().proof_size(), 1150); + }) +} + +#[test] +fn test_incorporates_check_weight_unspent_weight_reverse_order() { + let mut test_ext = setup_test_externalities(&[100, 300]); + + test_ext.execute_with(|| { + set_current_storage_weight(1000); + + // Benchmarked storage weight: 300 + let info = DispatchInfo { weight: Weight::from_parts(100, 300), ..Default::default() }; + + // Actual weight is 50 + let post_info = PostDispatchInfo { + actual_weight: Some(Weight::from_parts(50, 250)), + pays_fee: Default::default(), + }; + + let (pre, _) = StorageWeightReclaim::(PhantomData) + .validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN) + .unwrap(); + assert_eq!(pre, Some(100)); + + assert_ok!(StorageWeightReclaim::::post_dispatch( + pre, + &info, + &post_info, + LEN, + &Ok(()), + &() + )); + // `CheckWeight` gets called after `StorageWeightReclaim` this time. + // The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo` + // we always need to call `post_dispatch` to verify that they interoperate correctly. + assert_ok!(CheckWeight::::post_dispatch((), &info, &post_info, 0, &Ok(()), &())); + + assert_eq!(BlockWeight::::get().total().proof_size(), 900); + }) +} + +#[test] +fn test_incorporates_check_weight_unspent_weight_on_negative_reverse_order() { + let mut test_ext = setup_test_externalities(&[100, 300]); + + test_ext.execute_with(|| { + set_current_storage_weight(1000); + // Benchmarked storage weight: 50 + let info = DispatchInfo { weight: Weight::from_parts(100, 50), ..Default::default() }; + + // Actual weight is 25 + let post_info = PostDispatchInfo { + actual_weight: Some(Weight::from_parts(50, 25)), + pays_fee: Default::default(), + }; + + let (pre, _) = StorageWeightReclaim::(PhantomData) + .validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN) + .unwrap(); + assert_eq!(pre, Some(100)); + + assert_ok!(StorageWeightReclaim::::post_dispatch( + pre, + &info, + &post_info, + LEN, + &Ok(()), + &() + )); + // `CheckWeight` gets called after `StorageWeightReclaim` this time. + // The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo` + // we always need to call `post_dispatch` to verify that they interoperate correctly. + assert_ok!(CheckWeight::::post_dispatch((), &info, &post_info, 0, &Ok(()), &())); + + assert_eq!(BlockWeight::::get().total().proof_size(), 1150); + }) +} + +#[test] +fn storage_size_reported_correctly() { + let mut test_ext = setup_test_externalities(&[1000]); + test_ext.execute_with(|| { + assert_eq!(get_proof_size(), Some(1000)); + }); + + let mut test_ext = new_test_ext(); + + let test_recorder = TestRecorder::new(&[0]); + + test_ext.register_extension(ProofSizeExt::new(test_recorder)); + + test_ext.execute_with(|| { + assert_eq!(get_proof_size(), Some(0)); + }); +} + +#[test] +fn storage_size_disabled_reported_correctly() { + let mut test_ext = setup_test_externalities(&[PROOF_RECORDING_DISABLED as usize]); + + test_ext.execute_with(|| { + assert_eq!(get_proof_size(), None); + }); +} + +#[test] +fn test_reclaim_helper() { + let mut test_ext = setup_test_externalities(&[1000, 1300, 1800]); + + test_ext.execute_with(|| { + let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(0, 2000)); + let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter); + remaining_weight_meter.consume(Weight::from_parts(0, 500)); + let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); + + assert_eq!(reclaimed, Some(Weight::from_parts(0, 200))); + + remaining_weight_meter.consume(Weight::from_parts(0, 800)); + let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); + assert_eq!(reclaimed, Some(Weight::from_parts(0, 300))); + assert_eq!(remaining_weight_meter.remaining(), Weight::from_parts(0, 1200)); + }); +} + +#[test] +fn test_reclaim_helper_does_not_reclaim_negative() { + // Benchmarked weight does not change at all + let mut test_ext = setup_test_externalities(&[1000, 1300]); + + test_ext.execute_with(|| { + let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(0, 1000)); + let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter); + let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); + + assert_eq!(reclaimed, Some(Weight::from_parts(0, 0))); + assert_eq!(remaining_weight_meter.remaining(), Weight::from_parts(0, 1000)); + }); + + // Benchmarked weight increases less than storage proof consumes + let mut test_ext = setup_test_externalities(&[1000, 1300]); + + test_ext.execute_with(|| { + let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(0, 1000)); + let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter); + remaining_weight_meter.consume(Weight::from_parts(0, 0)); + let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); + + assert_eq!(reclaimed, Some(Weight::from_parts(0, 0))); + }); +} + +/// Just here for doc purposes +fn get_benched_weight() -> Weight { + Weight::from_parts(0, 5) +} + +/// Just here for doc purposes +fn do_work() {} + +#[docify::export_content(simple_reclaimer_example)] +fn reclaim_with_weight_meter() { + let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(10, 10)); + + let benched_weight = get_benched_weight(); + + // It is important to instantiate the `StorageWeightReclaimer` before we consume the weight + // for a piece of work from the weight meter. + let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter); + + if remaining_weight_meter.try_consume(benched_weight).is_ok() { + // Perform some work that takes has `benched_weight` storage weight. + do_work(); + + // Reclaimer will detect that we only consumed 2 bytes, so 3 bytes are reclaimed. + let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); + + // We reclaimed 3 bytes of storage size! + assert_eq!(reclaimed, Some(Weight::from_parts(0, 3))); + assert_eq!(BlockWeight::::get().total().proof_size(), 10); + assert_eq!(remaining_weight_meter.remaining(), Weight::from_parts(10, 8)); + } +} + +#[test] +fn test_reclaim_helper_works_with_meter() { + // The node will report 12 - 10 = 2 consumed storage size between the calls. + let mut test_ext = setup_test_externalities(&[10, 12]); + + test_ext.execute_with(|| { + // Initial storage size is 10. + set_current_storage_weight(10); + reclaim_with_weight_meter(); + }); +} diff --git a/cumulus/test/client/Cargo.toml b/cumulus/test/client/Cargo.toml index 028733ce235..9dfa6ecb351 100644 --- a/cumulus/test/client/Cargo.toml +++ b/cumulus/test/client/Cargo.toml @@ -46,9 +46,11 @@ cumulus-primitives-storage-weight-reclaim = { path = "../../primitives/storage-w [features] runtime-benchmarks = [ "cumulus-primitives-core/runtime-benchmarks", + "cumulus-primitives-storage-weight-reclaim/runtime-benchmarks", "cumulus-test-service/runtime-benchmarks", "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-primitives/runtime-benchmarks", "sc-service/runtime-benchmarks", diff --git a/cumulus/test/client/src/lib.rs b/cumulus/test/client/src/lib.rs index c46f4da7f67..9239ff0f23e 100644 --- a/cumulus/test/client/src/lib.rs +++ b/cumulus/test/client/src/lib.rs @@ -19,7 +19,7 @@ mod block_builder; use codec::{Decode, Encode}; use runtime::{ - Balance, Block, BlockHashCount, Runtime, RuntimeCall, Signature, SignedExtra, SignedPayload, + Balance, Block, BlockHashCount, Runtime, RuntimeCall, Signature, SignedPayload, TxExtension, UncheckedExtrinsic, VERSION, }; use sc_executor::HeapAllocStrategy; @@ -125,7 +125,7 @@ impl DefaultTestClientBuilderExt for TestClientBuilder { /// Create an unsigned extrinsic from a runtime call. pub fn generate_unsigned(function: impl Into) -> UncheckedExtrinsic { - UncheckedExtrinsic::new_unsigned(function.into()) + UncheckedExtrinsic::new_bare(function.into()) } /// Create a signed extrinsic from a runtime call and sign @@ -143,7 +143,7 @@ pub fn generate_extrinsic_with_pair( let period = BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64; let tip = 0; - let extra: SignedExtra = ( + let tx_ext: TxExtension = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckGenesis::::new(), @@ -152,13 +152,14 @@ pub fn generate_extrinsic_with_pair( frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(tip), cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::::new(), - ); + ) + .into(); let function = function.into(); let raw_payload = SignedPayload::from_raw( function.clone(), - extra.clone(), + tx_ext.clone(), ((), VERSION.spec_version, genesis_block, current_block_hash, (), (), (), ()), ); let signature = raw_payload.using_encoded(|e| origin.sign(e)); @@ -167,7 +168,7 @@ pub fn generate_extrinsic_with_pair( function, origin.public().into(), Signature::Sr25519(signature), - extra, + tx_ext, ) } diff --git a/cumulus/test/runtime/src/lib.rs b/cumulus/test/runtime/src/lib.rs index 5ccec8983e9..154948a24b4 100644 --- a/cumulus/test/runtime/src/lib.rs +++ b/cumulus/test/runtime/src/lib.rs @@ -246,6 +246,7 @@ impl pallet_transaction_payment::Config for Runtime { type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = (); type OperationalFeeMultiplier = ConstU8<5>; + type WeightInfo = pallet_transaction_payment::weights::SubstrateWeight; } impl pallet_sudo::Config for Runtime { @@ -322,8 +323,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( +/// The extension to the basic transaction logic. +pub type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckGenesis, @@ -335,7 +336,7 @@ pub type SignedExtra = ( ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, @@ -346,7 +347,7 @@ pub type Executive = frame_executive::Executive< TestOnRuntimeUpgrade, >; /// The payload being signed in transactions. -pub type SignedPayload = generic::SignedPayload; +pub type SignedPayload = generic::SignedPayload; pub struct TestOnRuntimeUpgrade; diff --git a/cumulus/test/service/Cargo.toml b/cumulus/test/service/Cargo.toml index 27273f4e0a8..39e8aeba433 100644 --- a/cumulus/test/service/Cargo.toml +++ b/cumulus/test/service/Cargo.toml @@ -104,10 +104,12 @@ substrate-test-utils = { path = "../../../substrate/test-utils" } runtime-benchmarks = [ "cumulus-pallet-parachain-system/runtime-benchmarks", "cumulus-primitives-core/runtime-benchmarks", + "cumulus-primitives-storage-weight-reclaim/runtime-benchmarks", "cumulus-test-client/runtime-benchmarks", "frame-system/runtime-benchmarks", "pallet-im-online/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "parachains-common/runtime-benchmarks", "polkadot-cli/runtime-benchmarks", "polkadot-primitives/runtime-benchmarks", diff --git a/cumulus/test/service/src/bench_utils.rs b/cumulus/test/service/src/bench_utils.rs index 4ace894b392..15128b23787 100644 --- a/cumulus/test/service/src/bench_utils.rs +++ b/cumulus/test/service/src/bench_utils.rs @@ -69,7 +69,7 @@ pub fn extrinsic_set_time(client: &TestClient) -> OpaqueExtrinsic { let timestamp = best_number as u64 * cumulus_test_runtime::MinimumPeriod::get(); cumulus_test_runtime::UncheckedExtrinsic { - signature: None, + preamble: sp_runtime::generic::Preamble::Bare, function: cumulus_test_runtime::RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: timestamp, }), @@ -102,7 +102,7 @@ pub fn extrinsic_set_validation_data( }; cumulus_test_runtime::UncheckedExtrinsic { - signature: None, + preamble: sp_runtime::generic::Preamble::Bare, function: cumulus_test_runtime::RuntimeCall::ParachainSystem( cumulus_pallet_parachain_system::Call::set_validation_data { data }, ), diff --git a/cumulus/test/service/src/lib.rs b/cumulus/test/service/src/lib.rs index 3554a383f21..f05dc5f180f 100644 --- a/cumulus/test/service/src/lib.rs +++ b/cumulus/test/service/src/lib.rs @@ -883,7 +883,7 @@ pub fn construct_extrinsic( .map(|c| c / 2) .unwrap_or(2) as u64; let tip = 0; - let extra: runtime::SignedExtra = ( + let tx_ext: runtime::TxExtension = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckGenesis::::new(), @@ -895,10 +895,11 @@ pub fn construct_extrinsic( frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(tip), cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::::new(), - ); + ) + .into(); let raw_payload = runtime::SignedPayload::from_raw( function.clone(), - extra.clone(), + tx_ext.clone(), ((), runtime::VERSION.spec_version, genesis_block, current_block_hash, (), (), (), ()), ); let signature = raw_payload.using_encoded(|e| caller.sign(e)); @@ -906,7 +907,7 @@ pub fn construct_extrinsic( function, caller.public().into(), runtime::Signature::Sr25519(signature), - extra, + tx_ext, ) } diff --git a/docs/sdk/src/reference_docs/extrinsic_encoding.rs b/docs/sdk/src/reference_docs/extrinsic_encoding.rs index 8c8568a228f..be1af500038 100644 --- a/docs/sdk/src/reference_docs/extrinsic_encoding.rs +++ b/docs/sdk/src/reference_docs/extrinsic_encoding.rs @@ -56,7 +56,7 @@ //! version_and_signed, //! from_address, //! signature, -//! signed_extensions_extra, +//! transaction_extensions_extra, //! ) //! ``` //! @@ -90,31 +90,31 @@ //! The signature type used on the Polkadot relay chain is [`sp_runtime::MultiSignature`]; the //! variants there are the types of signature that can be provided. //! -//! ### signed_extensions_extra +//! ### transaction_extensions_extra //! //! This is the concatenation of the [SCALE encoded][frame::deps::codec] bytes representing each of -//! the [_signed extensions_][sp_runtime::traits::SignedExtension], and are configured by the -//! fourth generic parameter of [`sp_runtime::generic::UncheckedExtrinsic`]. Learn more about -//! signed extensions [here][crate::reference_docs::signed_extensions]. +//! the [_transaction extensions_][sp_runtime::traits::TransactionExtension], and are configured by +//! the fourth generic parameter of [`sp_runtime::generic::UncheckedExtrinsic`]. Learn more about +//! transaction extensions [here][crate::reference_docs::transaction_extensions]. //! -//! When it comes to constructing an extrinsic, each signed extension has two things that we are -//! interested in here: +//! When it comes to constructing an extrinsic, each transaction extension has two things that we +//! are interested in here: //! -//! - The actual SCALE encoding of the signed extension type itself; this is what will form our -//! `signed_extensions_extra` bytes. -//! - An `AdditionalSigned` type. This is SCALE encoded into the `signed_extensions_additional` data -//! of the _signed payload_ (see below). +//! - The actual SCALE encoding of the transaction extension type itself; this is what will form our +//! `transaction_extensions_extra` bytes. +//! - An `Implicit` type. This is SCALE encoded into the `transaction_extensions_implicit` data of +//! the _signed payload_ (see below). //! //! Either (or both) of these can encode to zero bytes. //! -//! Each chain configures the set of signed extensions that it uses in its runtime configuration. -//! At the time of writing, Polkadot configures them +//! Each chain configures the set of transaction extensions that it uses in its runtime +//! configuration. At the time of writing, Polkadot configures them //! [here](https://github.com/polkadot-fellows/runtimes/blob/1dc04eb954eadf8aadb5d83990b89662dbb5a074/relay/polkadot/src/lib.rs#L1432C25-L1432C25). -//! Some of the common signed extensions are defined -//! [here][frame::deps::frame_system#signed-extensions]. +//! Some of the common transaction extensions are defined +//! [here][frame::deps::frame_system#transaction-extensions]. //! -//! Information about exactly which signed extensions are present on a chain and in what order is -//! also a part of the metadata for the chain. For V15 metadata, it can be +//! Information about exactly which transaction extensions are present on a chain and in what order +//! is also a part of the metadata for the chain. For V15 metadata, it can be //! [found here][frame::deps::frame_support::__private::metadata::v15::ExtrinsicMetadata]. //! //! ## call_data @@ -163,8 +163,8 @@ //! ```text //! signed_payload = concat( //! call_data, -//! signed_extensions_extra, -//! signed_extensions_additional, +//! transaction_extensions_extra, +//! transaction_extensions_implicit, //! ) //! //! if length(signed_payload) > 256 { @@ -172,16 +172,16 @@ //! } //! ``` //! -//! The bytes representing `call_data` and `signed_extensions_extra` can be obtained as described -//! above. `signed_extensions_additional` is constructed by SCALE encoding the -//! ["additional signed" data][sp_runtime::traits::SignedExtension::AdditionalSigned] for each -//! signed extension that the chain is using, in order. +//! The bytes representing `call_data` and `transaction_extensions_extra` can be obtained as +//! descibed above. `transaction_extensions_implicit` is constructed by SCALE encoding the +//! ["implicit" data][sp_runtime::traits::TransactionExtensionBase::Implicit] for each +//! transaction extension that the chain is using, in order. //! //! Once we've concatenated those together, we hash the result if it's greater than 256 bytes in //! length using a Blake2 256bit hasher. //! //! The [`sp_runtime::generic::SignedPayload`] type takes care of assembling the correct payload -//! for us, given `call_data` and a tuple of signed extensions. +//! for us, given `call_data` and a tuple of transaction extensions. //! //! # Example Encoding //! @@ -192,11 +192,12 @@ #[docify::export] pub mod call_data { use parity_scale_codec::{Decode, Encode}; + use sp_runtime::{traits::Dispatchable, DispatchResultWithInfo}; // The outer enum composes calls within // different pallets together. We have two // pallets, "PalletA" and "PalletB". - #[derive(Encode, Decode)] + #[derive(Encode, Decode, Clone)] pub enum Call { #[codec(index = 0)] PalletA(PalletACall), @@ -207,23 +208,33 @@ pub mod call_data { // An inner enum represents the calls within // a specific pallet. "PalletA" has one call, // "Foo". - #[derive(Encode, Decode)] + #[derive(Encode, Decode, Clone)] pub enum PalletACall { #[codec(index = 0)] Foo(String), } - #[derive(Encode, Decode)] + #[derive(Encode, Decode, Clone)] pub enum PalletBCall { #[codec(index = 0)] Bar(String), } + + impl Dispatchable for Call { + type RuntimeOrigin = (); + type Config = (); + type Info = (); + type PostInfo = (); + fn dispatch(self, _origin: Self::RuntimeOrigin) -> DispatchResultWithInfo { + Ok(()) + } + } } #[docify::export] pub mod encoding_example { use super::call_data::{Call, PalletACall}; - use crate::reference_docs::signed_extensions::signed_extensions_example; + use crate::reference_docs::transaction_extensions::transaction_extensions_example; use parity_scale_codec::Encode; use sp_core::crypto::AccountId32; use sp_keyring::sr25519::Keyring; @@ -232,34 +243,40 @@ pub mod encoding_example { MultiAddress, MultiSignature, }; - // Define some signed extensions to use. We'll use a couple of examples - // from the signed extensions reference doc. - type SignedExtensions = - (signed_extensions_example::AddToPayload, signed_extensions_example::AddToSignaturePayload); + // Define some transaction extensions to use. We'll use a couple of examples + // from the transaction extensions reference doc. + type TransactionExtensions = ( + transaction_extensions_example::AddToPayload, + transaction_extensions_example::AddToSignaturePayload, + ); // We'll use `UncheckedExtrinsic` to encode our extrinsic for us. We set // the address and signature type to those used on Polkadot, use our custom - // `Call` type, and use our custom set of `SignedExtensions`. - type Extrinsic = - UncheckedExtrinsic, Call, MultiSignature, SignedExtensions>; + // `Call` type, and use our custom set of `TransactionExtensions`. + type Extrinsic = UncheckedExtrinsic< + MultiAddress, + Call, + MultiSignature, + TransactionExtensions, + >; pub fn encode_demo_extrinsic() -> Vec { // The "from" address will be our Alice dev account. let from_address = MultiAddress::::Id(Keyring::Alice.to_account_id()); - // We provide some values for our expected signed extensions. - let signed_extensions = ( - signed_extensions_example::AddToPayload(1), - signed_extensions_example::AddToSignaturePayload, + // We provide some values for our expected transaction extensions. + let transaction_extensions = ( + transaction_extensions_example::AddToPayload(1), + transaction_extensions_example::AddToSignaturePayload, ); // Construct our call data: let call_data = Call::PalletA(PalletACall::Foo("Hello".to_string())); // The signed payload. This takes care of encoding the call_data, - // signed_extensions_extra and signed_extensions_additional, and hashing + // transaction_extensions_extra and transaction_extensions_implicit, and hashing // the result if it's > 256 bytes: - let signed_payload = SignedPayload::new(&call_data, signed_extensions.clone()); + let signed_payload = SignedPayload::new(call_data.clone(), transaction_extensions.clone()); // Sign the signed payload with our Alice dev account's private key, // and wrap the signature into the expected type: @@ -269,7 +286,7 @@ pub mod encoding_example { }; // Now, we can build and encode our extrinsic: - let ext = Extrinsic::new_signed(call_data, from_address, signature, signed_extensions); + let ext = Extrinsic::new_signed(call_data, from_address, signature, transaction_extensions); let encoded_ext = ext.encode(); encoded_ext diff --git a/docs/sdk/src/reference_docs/frame_runtime_types.rs b/docs/sdk/src/reference_docs/frame_runtime_types.rs index b5838b79e51..883892729d1 100644 --- a/docs/sdk/src/reference_docs/frame_runtime_types.rs +++ b/docs/sdk/src/reference_docs/frame_runtime_types.rs @@ -130,7 +130,7 @@ //! * [`crate::reference_docs::frame_origin`] explores further details about the usage of //! `RuntimeOrigin`. //! * [`RuntimeCall`] is a particularly interesting composite enum as it dictates the encoding of an -//! extrinsic. See [`crate::reference_docs::signed_extensions`] for more information. +//! extrinsic. See [`crate::reference_docs::transaction_extensions`] for more information. //! * See the documentation of [`construct_runtime`]. //! * See the corresponding lecture in the [pba-book](https://polkadot-blockchain-academy.github.io/pba-book/frame/outer-enum/page.html). //! diff --git a/docs/sdk/src/reference_docs/mod.rs b/docs/sdk/src/reference_docs/mod.rs index 0bd204e4b6a..3fd815d2a15 100644 --- a/docs/sdk/src/reference_docs/mod.rs +++ b/docs/sdk/src/reference_docs/mod.rs @@ -39,9 +39,9 @@ pub mod runtime_vs_smart_contract; /// Learn about how extrinsics are encoded to be transmitted to a node and stored in blocks. pub mod extrinsic_encoding; -/// Learn about the signed extensions that form a part of extrinsics. +/// Learn about the transaction extensions that form a part of extrinsics. // TODO: @jsdw https://github.com/paritytech/polkadot-sdk-docs/issues/42 -pub mod signed_extensions; +pub mod transaction_extensions; /// Learn about *Origins*, a topic in FRAME that enables complex account abstractions to be built. pub mod frame_origin; diff --git a/docs/sdk/src/reference_docs/signed_extensions.rs b/docs/sdk/src/reference_docs/signed_extensions.rs deleted file mode 100644 index 28b1426536b..00000000000 --- a/docs/sdk/src/reference_docs/signed_extensions.rs +++ /dev/null @@ -1,79 +0,0 @@ -//! Signed extensions are, briefly, a means for different chains to extend the "basic" extrinsic -//! format with custom data that can be checked by the runtime. -//! -//! # Example -//! -//! Defining a couple of very simple signed extensions looks like the following: -#![doc = docify::embed!("./src/reference_docs/signed_extensions.rs", signed_extensions_example)] - -#[docify::export] -pub mod signed_extensions_example { - use parity_scale_codec::{Decode, Encode}; - use scale_info::TypeInfo; - use sp_runtime::traits::SignedExtension; - - // This doesn't actually check anything, but simply allows - // some arbitrary `u32` to be added to the extrinsic payload - #[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)] - pub struct AddToPayload(pub u32); - - impl SignedExtension for AddToPayload { - const IDENTIFIER: &'static str = "AddToPayload"; - type AccountId = (); - type Call = (); - type AdditionalSigned = (); - type Pre = (); - - fn additional_signed( - &self, - ) -> Result< - Self::AdditionalSigned, - sp_runtime::transaction_validity::TransactionValidityError, - > { - Ok(()) - } - - fn pre_dispatch( - self, - _who: &Self::AccountId, - _call: &Self::Call, - _info: &sp_runtime::traits::DispatchInfoOf, - _len: usize, - ) -> Result { - Ok(()) - } - } - - // This is the opposite; nothing will be added to the extrinsic payload, - // but the AdditionalSigned type (`1234u32`) will be added to the - // payload to be signed. - #[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)] - pub struct AddToSignaturePayload; - - impl SignedExtension for AddToSignaturePayload { - const IDENTIFIER: &'static str = "AddToSignaturePayload"; - type AccountId = (); - type Call = (); - type AdditionalSigned = u32; - type Pre = (); - - fn additional_signed( - &self, - ) -> Result< - Self::AdditionalSigned, - sp_runtime::transaction_validity::TransactionValidityError, - > { - Ok(1234) - } - - fn pre_dispatch( - self, - _who: &Self::AccountId, - _call: &Self::Call, - _info: &sp_runtime::traits::DispatchInfoOf, - _len: usize, - ) -> Result { - Ok(()) - } - } -} diff --git a/docs/sdk/src/reference_docs/transaction_extensions.rs b/docs/sdk/src/reference_docs/transaction_extensions.rs new file mode 100644 index 00000000000..4f96d665d9b --- /dev/null +++ b/docs/sdk/src/reference_docs/transaction_extensions.rs @@ -0,0 +1,57 @@ +//! Transaction extensions are, briefly, a means for different chains to extend the "basic" +//! extrinsic format with custom data that can be checked by the runtime. +//! +//! # Example +//! +//! Defining a couple of very simple transaction extensions looks like the following: +#![doc = docify::embed!("./src/reference_docs/transaction_extensions.rs", transaction_extensions_example)] + +#[docify::export] +pub mod transaction_extensions_example { + use parity_scale_codec::{Decode, Encode}; + use scale_info::TypeInfo; + use sp_runtime::{ + impl_tx_ext_default, + traits::{Dispatchable, TransactionExtension, TransactionExtensionBase}, + TransactionValidityError, + }; + + // This doesn't actually check anything, but simply allows + // some arbitrary `u32` to be added to the extrinsic payload + #[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)] + pub struct AddToPayload(pub u32); + + impl TransactionExtensionBase for AddToPayload { + const IDENTIFIER: &'static str = "AddToPayload"; + type Implicit = (); + } + + impl TransactionExtension for AddToPayload { + type Pre = (); + type Val = (); + + impl_tx_ext_default!(Call; (); validate prepare); + } + + // This is the opposite; nothing will be added to the extrinsic payload, + // but the Implicit type (`1234u32`) will be added to the + // payload to be signed. + #[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)] + pub struct AddToSignaturePayload; + + impl TransactionExtensionBase for AddToSignaturePayload { + const IDENTIFIER: &'static str = "AddToSignaturePayload"; + type Implicit = u32; + + fn implicit(&self) -> Result { + Ok(1234) + } + } + + impl TransactionExtension for AddToSignaturePayload { + type Pre = (); + type Val = (); + + impl_tx_ext_default!(Call; (); validate prepare); + } +} diff --git a/polkadot/node/service/Cargo.toml b/polkadot/node/service/Cargo.toml index 734dcbdeb44..180de70ad6c 100644 --- a/polkadot/node/service/Cargo.toml +++ b/polkadot/node/service/Cargo.toml @@ -196,6 +196,7 @@ runtime-benchmarks = [ "pallet-babe/runtime-benchmarks", "pallet-im-online/runtime-benchmarks", "pallet-staking/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-primitives/runtime-benchmarks", "polkadot-runtime-parachains/runtime-benchmarks", diff --git a/polkadot/node/service/src/benchmarking.rs b/polkadot/node/service/src/benchmarking.rs index 400daf1aee3..29acc5c3ca8 100644 --- a/polkadot/node/service/src/benchmarking.rs +++ b/polkadot/node/service/src/benchmarking.rs @@ -189,7 +189,7 @@ fn westend_sign_call( use sp_core::Pair; use westend_runtime as runtime; - let extra: runtime::SignedExtra = ( + let tx_ext: runtime::TxExtension = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -201,11 +201,12 @@ fn westend_sign_call( frame_system::CheckNonce::::from(nonce), frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(0), - ); + ) + .into(); let payload = runtime::SignedPayload::from_raw( call.clone(), - extra.clone(), + tx_ext.clone(), ( (), runtime::VERSION.spec_version, @@ -223,7 +224,7 @@ fn westend_sign_call( call, sp_runtime::AccountId32::from(acc.public()).into(), polkadot_core_primitives::Signature::Sr25519(signature.clone()), - extra, + tx_ext, ) .into() } @@ -241,7 +242,7 @@ fn rococo_sign_call( use rococo_runtime as runtime; use sp_core::Pair; - let extra: runtime::SignedExtra = ( + let tx_ext: runtime::TxExtension = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -253,11 +254,12 @@ fn rococo_sign_call( frame_system::CheckNonce::::from(nonce), frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(0), - ); + ) + .into(); let payload = runtime::SignedPayload::from_raw( call.clone(), - extra.clone(), + tx_ext.clone(), ( (), runtime::VERSION.spec_version, @@ -275,7 +277,7 @@ fn rococo_sign_call( call, sp_runtime::AccountId32::from(acc.public()).into(), polkadot_core_primitives::Signature::Sr25519(signature.clone()), - extra, + tx_ext, ) .into() } diff --git a/polkadot/node/test/service/Cargo.toml b/polkadot/node/test/service/Cargo.toml index e7892abcd87..02b227e6f34 100644 --- a/polkadot/node/test/service/Cargo.toml +++ b/polkadot/node/test/service/Cargo.toml @@ -71,6 +71,7 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-staking/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", diff --git a/polkadot/node/test/service/src/lib.rs b/polkadot/node/test/service/src/lib.rs index ca904bae28d..1876595c7b4 100644 --- a/polkadot/node/test/service/src/lib.rs +++ b/polkadot/node/test/service/src/lib.rs @@ -32,7 +32,7 @@ use polkadot_service::{ Error, FullClient, IsParachainNode, NewFull, OverseerGen, PrometheusConfig, }; use polkadot_test_runtime::{ - ParasCall, ParasSudoWrapperCall, Runtime, SignedExtra, SignedPayload, SudoCall, + ParasCall, ParasSudoWrapperCall, Runtime, SignedPayload, SudoCall, TxExtension, UncheckedExtrinsic, VERSION, }; @@ -382,7 +382,7 @@ pub fn construct_extrinsic( let period = BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64; let tip = 0; - let extra: SignedExtra = ( + let tx_ext: TxExtension = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -391,10 +391,11 @@ pub fn construct_extrinsic( frame_system::CheckNonce::::from(nonce), frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(tip), - ); + ) + .into(); let raw_payload = SignedPayload::from_raw( function.clone(), - extra.clone(), + tx_ext.clone(), ( (), VERSION.spec_version, @@ -411,7 +412,7 @@ pub fn construct_extrinsic( function.clone(), polkadot_test_runtime::Address::Id(caller.public().into()), polkadot_primitives::Signature::Sr25519(signature.clone()), - extra.clone(), + tx_ext.clone(), ) } diff --git a/polkadot/runtime/common/Cargo.toml b/polkadot/runtime/common/Cargo.toml index eae5d4fb2ef..c2205938295 100644 --- a/polkadot/runtime/common/Cargo.toml +++ b/polkadot/runtime/common/Cargo.toml @@ -132,6 +132,7 @@ runtime-benchmarks = [ "pallet-identity/runtime-benchmarks", "pallet-staking/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", "pallet-vesting/runtime-benchmarks", "primitives/runtime-benchmarks", diff --git a/polkadot/runtime/common/src/claims.rs b/polkadot/runtime/common/src/claims.rs index 68f42914e44..57a95b22af3 100644 --- a/polkadot/runtime/common/src/claims.rs +++ b/polkadot/runtime/common/src/claims.rs @@ -29,7 +29,11 @@ use scale_info::TypeInfo; use serde::{self, Deserialize, Deserializer, Serialize, Serializer}; use sp_io::{crypto::secp256k1_ecdsa_recover, hashing::keccak_256}; use sp_runtime::{ - traits::{CheckedSub, DispatchInfoOf, SignedExtension, Zero}, + impl_tx_ext_default, + traits::{ + AsSystemOriginSigner, CheckedSub, DispatchInfoOf, Dispatchable, TransactionExtension, + TransactionExtensionBase, Zero, + }, transaction_validity::{ InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction, }, @@ -50,6 +54,7 @@ pub trait WeightInfo { fn claim_attest() -> Weight; fn attest() -> Weight; fn move_claim() -> Weight; + fn prevalidate_attests() -> Weight; } pub struct TestWeightInfo; @@ -69,6 +74,9 @@ impl WeightInfo for TestWeightInfo { fn move_claim() -> Weight { Weight::zero() } + fn prevalidate_attests() -> Weight { + Weight::zero() + } } /// The kind of statement an account needs to make for a claim to be valid. @@ -84,7 +92,7 @@ pub enum StatementKind { impl StatementKind { /// Convert this to the (English) statement it represents. - fn to_text(self) -> &'static [u8] { + pub fn to_text(self) -> &'static [u8] { match self { StatementKind::Regular => &b"I hereby agree to the terms of the statement whose SHA-256 multihash is \ @@ -166,6 +174,13 @@ pub mod pallet { #[pallet::without_storage_info] pub struct Pallet(_); + #[cfg(feature = "runtime-benchmarks")] + /// Helper trait to benchmark the `PrevalidateAttests` transaction extension. + pub trait BenchmarkHelperTrait { + /// `Call` to be used when benchmarking the transaction extension. + fn default_call_and_info() -> (RuntimeCall, DispatchInfo); + } + /// Configuration trait. #[pallet::config] pub trait Config: frame_system::Config { @@ -176,6 +191,12 @@ pub mod pallet { type Prefix: Get<&'static [u8]>; type MoveClaimOrigin: EnsureOrigin; type WeightInfo: WeightInfo; + #[cfg(feature = "runtime-benchmarks")] + /// Benchmark helper + type BenchmarkHelper: BenchmarkHelperTrait< + Self::RuntimeCall, + DispatchInfoOf, + >; } #[pallet::event] @@ -402,7 +423,7 @@ pub mod pallet { /// Attest to a statement, needed to finalize the claims process. /// /// WARNING: Insecure unless your chain includes `PrevalidateAttests` as a - /// `SignedExtension`. + /// `TransactionExtension`. /// /// Unsigned Validation: /// A call to attest is deemed valid if the sender has a `Preclaim` registered @@ -612,46 +633,46 @@ impl PrevalidateAttests where ::RuntimeCall: IsSubType>, { - /// Create new `SignedExtension` to check runtime version. + /// Create new `TransactionExtension` to check runtime version. pub fn new() -> Self { Self(sp_std::marker::PhantomData) } } -impl SignedExtension for PrevalidateAttests +impl TransactionExtensionBase for PrevalidateAttests where ::RuntimeCall: IsSubType>, { - type AccountId = T::AccountId; - type Call = ::RuntimeCall; - type AdditionalSigned = (); - type Pre = (); const IDENTIFIER: &'static str = "PrevalidateAttests"; + type Implicit = (); +} - fn additional_signed(&self) -> Result { - Ok(()) - } - - fn pre_dispatch( - self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> Result { - self.validate(who, call, info, len).map(|_| ()) - } +impl TransactionExtension for PrevalidateAttests +where + ::RuntimeCall: IsSubType>, + <::RuntimeCall as Dispatchable>::RuntimeOrigin: + AsSystemOriginSigner + Clone, +{ + type Pre = (); + type Val = (); // // The weight of this logic is included in the `attest` dispatchable. // fn validate( &self, - who: &Self::AccountId, - call: &Self::Call, - _info: &DispatchInfoOf, + origin: ::RuntimeOrigin, + call: &T::RuntimeCall, + _info: &DispatchInfoOf, _len: usize, - ) -> TransactionValidity { + _context: &mut Context, + _self_implicit: Self::Implicit, + _inherited_implication: &impl Encode, + ) -> Result< + (ValidTransaction, Self::Val, ::RuntimeOrigin), + TransactionValidityError, + > { + let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?; if let Some(local_call) = call.is_sub_type() { if let Call::attest { statement: attested_statement } = local_call { let signer = Preclaims::::get(who) @@ -662,8 +683,9 @@ where } } } - Ok(ValidTransaction::default()) + Ok((ValidTransaction::default(), (), origin)) } + impl_tx_ext_default!(T::RuntimeCall; Context; prepare); } #[cfg(any(test, feature = "runtime-benchmarks"))] @@ -696,7 +718,7 @@ mod secp_utils { } #[cfg(test)] -mod tests { +pub(super) mod tests { use super::*; use hex_literal::hex; use secp_utils::*; @@ -714,8 +736,11 @@ mod tests { }; use pallet_balances; use sp_runtime::{ - traits::Identity, transaction_validity::TransactionLongevity, BuildStorage, - DispatchError::BadOrigin, TokenError, + traits::{DispatchTransaction, Identity}, + transaction_validity::TransactionLongevity, + BuildStorage, + DispatchError::BadOrigin, + TokenError, }; type Block = frame_system::mocking::MockBlock; @@ -790,6 +815,19 @@ mod tests { type Prefix = Prefix; type MoveClaimOrigin = frame_system::EnsureSignedBy; type WeightInfo = TestWeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); + } + + #[cfg(feature = "runtime-benchmarks")] + impl BenchmarkHelperTrait> for () { + fn default_call_and_info() -> (RuntimeCall, DispatchInfoOf) { + let call = RuntimeCall::Claims(crate::claims::Call::attest { + statement: StatementKind::Regular.to_text().to_vec(), + }); + let info = call.get_dispatch_info(); + (call, info) + } } fn alice() -> libsecp256k1::SecretKey { @@ -1071,8 +1109,8 @@ mod tests { }); let di = c.get_dispatch_info(); assert_eq!(di.pays_fee, Pays::No); - let r = p.validate(&42, &c, &di, 20); - assert_eq!(r, TransactionValidity::Ok(ValidTransaction::default())); + let r = p.validate_only(Some(42).into(), &c, &di, 20); + assert_eq!(r.unwrap().0, ValidTransaction::default()); }); } @@ -1084,13 +1122,13 @@ mod tests { statement: StatementKind::Regular.to_text().to_vec(), }); let di = c.get_dispatch_info(); - let r = p.validate(&42, &c, &di, 20); + let r = p.validate_only(Some(42).into(), &c, &di, 20); assert!(r.is_err()); let c = RuntimeCall::Claims(ClaimsCall::attest { statement: StatementKind::Saft.to_text().to_vec(), }); let di = c.get_dispatch_info(); - let r = p.validate(&69, &c, &di, 20); + let r = p.validate_only(Some(69).into(), &c, &di, 20); assert!(r.is_err()); }); } @@ -1444,14 +1482,17 @@ mod tests { } #[cfg(feature = "runtime-benchmarks")] -mod benchmarking { +pub(super) mod benchmarking { use super::*; use crate::claims::Call; use frame_benchmarking::{account, benchmarks}; use frame_support::traits::UnfilteredDispatchable; use frame_system::RawOrigin; use secp_utils::*; - use sp_runtime::{traits::ValidateUnsigned, DispatchResult}; + use sp_runtime::{ + traits::{DispatchTransaction, ValidateUnsigned}, + DispatchResult, + }; const SEED: u32 = 0; @@ -1487,6 +1528,11 @@ mod benchmarking { } benchmarks! { + where_clause { where ::RuntimeCall: IsSubType>, + <::RuntimeCall as Dispatchable>::RuntimeOrigin: AsSystemOriginSigner + Clone, + <::RuntimeCall as Dispatchable>::PostInfo: Default, + } + // Benchmark `claim` including `validate_unsigned` logic. claim { let c = MAX_CLAIMS; @@ -1665,6 +1711,38 @@ mod benchmarking { } } + prevalidate_attests { + let c = MAX_CLAIMS; + + for i in 0 .. c / 2 { + create_claim::(c)?; + create_claim_attest::(u32::MAX - c)?; + } + + let ext = PrevalidateAttests::::new(); + let (call, info) = T::BenchmarkHelper::default_call_and_info(); + let attest_c = u32::MAX - c; + let secret_key = libsecp256k1::SecretKey::parse(&keccak_256(&attest_c.encode())).unwrap(); + let eth_address = eth(&secret_key); + let account: T::AccountId = account("user", c, SEED); + let vesting = Some((100_000u32.into(), 1_000u32.into(), 100u32.into())); + let statement = StatementKind::Regular; + let signature = sig::(&secret_key, &account.encode(), statement.to_text()); + super::Pallet::::mint_claim(RawOrigin::Root.into(), eth_address, VALUE.into(), vesting, Some(statement))?; + Preclaims::::insert(&account, eth_address); + assert_eq!(Claims::::get(eth_address), Some(VALUE.into())); + }: { + assert!(ext.test_run( + RawOrigin::Signed(account).into(), + &call, + &info, + 0, + |_| { + Ok(Default::default()) + } + ).unwrap().is_ok()); + } + impl_benchmark_test_suite!( Pallet, crate::claims::tests::new_test_ext(), diff --git a/polkadot/runtime/rococo/Cargo.toml b/polkadot/runtime/rococo/Cargo.toml index 3dc59cc1728..61ca1635ac9 100644 --- a/polkadot/runtime/rococo/Cargo.toml +++ b/polkadot/runtime/rococo/Cargo.toml @@ -246,6 +246,7 @@ runtime-benchmarks = [ "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-tips/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-vesting/runtime-benchmarks", diff --git a/polkadot/runtime/rococo/constants/src/weights/block_weights.rs b/polkadot/runtime/rococo/constants/src/weights/block_weights.rs index e2aa4a6cab7..f7dc2f19316 100644 --- a/polkadot/runtime/rococo/constants/src/weights/block_weights.rs +++ b/polkadot/runtime/rococo/constants/src/weights/block_weights.rs @@ -14,13 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26 (Y/M/D) -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29 (Y/M/D) +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! //! SHORT-NAME: `block`, LONG-NAME: `BlockExecution`, RUNTIME: `Development` //! WARMUPS: `10`, REPEAT: `100` -//! WEIGHT-PATH: `runtime/rococo/constants/src/weights/` +//! WEIGHT-PATH: `./polkadot/runtime/rococo/constants/src/weights/` //! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0` // Executed Command: @@ -28,12 +28,11 @@ // benchmark // overhead // --chain=rococo-dev -// --execution=wasm // --wasm-execution=compiled -// --weight-path=runtime/rococo/constants/src/weights/ +// --weight-path=./polkadot/runtime/rococo/constants/src/weights/ // --warmup=10 // --repeat=100 -// --header=./file_header.txt +// --header=./polkadot/file_header.txt use sp_core::parameter_types; use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight}; @@ -43,17 +42,17 @@ parameter_types! { /// Calculated by multiplying the *Average* with `1.0` and adding `0`. /// /// Stats nanoseconds: - /// Min, Max: 408_659, 450_716 - /// Average: 417_412 - /// Median: 411_177 - /// Std-Dev: 12242.31 + /// Min, Max: 440_142, 476_907 + /// Average: 450_240 + /// Median: 448_633 + /// Std-Dev: 7301.18 /// /// Percentiles nanoseconds: - /// 99th: 445_142 - /// 95th: 442_275 - /// 75th: 414_217 + /// 99th: 470_733 + /// 95th: 465_082 + /// 75th: 452_536 pub const BlockExecutionWeight: Weight = - Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(417_412), 0); + Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(450_240), 0); } #[cfg(test)] diff --git a/polkadot/runtime/rococo/constants/src/weights/extrinsic_weights.rs b/polkadot/runtime/rococo/constants/src/weights/extrinsic_weights.rs index adce840ebbc..000cee8a237 100644 --- a/polkadot/runtime/rococo/constants/src/weights/extrinsic_weights.rs +++ b/polkadot/runtime/rococo/constants/src/weights/extrinsic_weights.rs @@ -14,13 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26 (Y/M/D) -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29 (Y/M/D) +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! //! SHORT-NAME: `extrinsic`, LONG-NAME: `ExtrinsicBase`, RUNTIME: `Development` //! WARMUPS: `10`, REPEAT: `100` -//! WEIGHT-PATH: `runtime/rococo/constants/src/weights/` +//! WEIGHT-PATH: `./polkadot/runtime/rococo/constants/src/weights/` //! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0` // Executed Command: @@ -28,12 +28,11 @@ // benchmark // overhead // --chain=rococo-dev -// --execution=wasm // --wasm-execution=compiled -// --weight-path=runtime/rococo/constants/src/weights/ +// --weight-path=./polkadot/runtime/rococo/constants/src/weights/ // --warmup=10 // --repeat=100 -// --header=./file_header.txt +// --header=./polkadot/file_header.txt use sp_core::parameter_types; use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight}; @@ -43,17 +42,17 @@ parameter_types! { /// Calculated by multiplying the *Average* with `1.0` and adding `0`. /// /// Stats nanoseconds: - /// Min, Max: 97_574, 100_119 - /// Average: 98_236 - /// Median: 98_179 - /// Std-Dev: 394.9 + /// Min, Max: 92_961, 94_143 + /// Average: 93_369 + /// Median: 93_331 + /// Std-Dev: 217.39 /// /// Percentiles nanoseconds: - /// 99th: 99_893 - /// 95th: 98_850 - /// 75th: 98_318 + /// 99th: 93_848 + /// 95th: 93_691 + /// 75th: 93_514 pub const ExtrinsicBaseWeight: Weight = - Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(98_236), 0); + Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(93_369), 0); } #[cfg(test)] diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 96e8c4e0979..ff54c777670 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -199,6 +199,7 @@ impl frame_system::Config for Runtime { type Version = Version; type AccountData = pallet_balances::AccountData; type SystemWeightInfo = weights::frame_system::WeightInfo; + type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; type SS58Prefix = SS58Prefix; type MaxConsumers = frame_support::traits::ConstU32<16>; } @@ -329,6 +330,7 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; + type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { @@ -591,7 +593,7 @@ where // so the actual block number is `n`. .saturating_sub(1); let tip = 0; - let extra: SignedExtra = ( + let tx_ext: TxExtension = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -603,16 +605,17 @@ where frame_system::CheckNonce::::from(nonce), frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(tip), - ); - let raw_payload = SignedPayload::new(call, extra) + ) + .into(); + let raw_payload = SignedPayload::new(call, tx_ext) .map_err(|e| { log::warn!("Unable to create signed payload: {:?}", e); }) .ok()?; let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?; - let (call, extra, _) = raw_payload.deconstruct(); + let (call, tx_ext, _) = raw_payload.deconstruct(); let address = ::Lookup::unlookup(account); - Some((call, (address, signature, extra))) + Some((call, (address, signature, tx_ext))) } } @@ -633,12 +636,32 @@ parameter_types! { pub Prefix: &'static [u8] = b"Pay ROCs to the Rococo account:"; } +#[cfg(feature = "runtime-benchmarks")] +pub struct ClaimsHelper; + +#[cfg(feature = "runtime-benchmarks")] +use frame_support::dispatch::DispatchInfo; + +#[cfg(feature = "runtime-benchmarks")] +impl claims::BenchmarkHelperTrait for ClaimsHelper { + fn default_call_and_info() -> (RuntimeCall, DispatchInfo) { + use frame_support::dispatch::GetDispatchInfo; + let call = RuntimeCall::Claims(claims::Call::attest { + statement: claims::StatementKind::Regular.to_text().to_vec(), + }); + let info = call.get_dispatch_info(); + (call, info) + } +} + impl claims::Config for Runtime { type RuntimeEvent = RuntimeEvent; type VestingSchedule = Vesting; type Prefix = Prefix; type MoveClaimOrigin = EnsureRoot; type WeightInfo = weights::runtime_common_claims::WeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = ClaimsHelper; } parameter_types! { @@ -1447,8 +1470,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// `BlockId` type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The `SignedExtension` to the basic transaction logic. -pub type SignedExtra = ( +/// The extension to the basic transaction logic. +pub type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -1461,7 +1484,7 @@ pub type SignedExtra = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// All migrations that will run on the next runtime upgrade. /// @@ -1675,7 +1698,7 @@ pub type Executive = frame_executive::Executive< Migrations, >; /// The payload being signed in transactions. -pub type SignedPayload = generic::SignedPayload; +pub type SignedPayload = generic::SignedPayload; parameter_types! { // The deposit configuration for the singed migration. Specially if you want to allow any signed account to do the migration (see `SignedFilter`, these deposits should be high) @@ -1746,7 +1769,9 @@ mod benches { [pallet_scheduler, Scheduler] [pallet_sudo, Sudo] [frame_system, SystemBench::] + [frame_system_extensions, SystemExtensionsBench::] [pallet_timestamp, Timestamp] + [pallet_transaction_payment, TransactionPayment] [pallet_treasury, Treasury] [pallet_utility, Utility] [pallet_vesting, Vesting] @@ -2240,6 +2265,7 @@ sp_api::impl_runtime_apis! { use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use frame_benchmarking::baseline::Pallet as Baseline; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; @@ -2260,6 +2286,7 @@ sp_api::impl_runtime_apis! { use frame_support::traits::WhitelistedStorageKeys; use frame_benchmarking::{Benchmarking, BenchmarkBatch, BenchmarkError}; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use frame_benchmarking::baseline::Pallet as Baseline; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; use sp_storage::TrackedStorageKey; diff --git a/polkadot/runtime/rococo/src/weights/frame_benchmarking_baseline.rs b/polkadot/runtime/rococo/src/weights/frame_benchmarking_baseline.rs index dfba0cfc4aa..0f68a5c6fb3 100644 --- a/polkadot/runtime/rococo/src/weights/frame_benchmarking_baseline.rs +++ b/polkadot/runtime/rococo/src/weights/frame_benchmarking_baseline.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `frame_benchmarking::baseline` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=frame_benchmarking::baseline // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/frame_benchmarking_baseline.rs +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/frame_benchmarking_baseline.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -52,8 +55,8 @@ impl frame_benchmarking::baseline::WeightInfo for Weigh // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 157_000 picoseconds. - Weight::from_parts(175_233, 0) + // Minimum execution time: 172_000 picoseconds. + Weight::from_parts(199_481, 0) .saturating_add(Weight::from_parts(0, 0)) } /// The range of component `i` is `[0, 1000000]`. @@ -61,8 +64,8 @@ impl frame_benchmarking::baseline::WeightInfo for Weigh // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 149_000 picoseconds. - Weight::from_parts(183_285, 0) + // Minimum execution time: 171_000 picoseconds. + Weight::from_parts(197_821, 0) .saturating_add(Weight::from_parts(0, 0)) } /// The range of component `i` is `[0, 1000000]`. @@ -70,8 +73,8 @@ impl frame_benchmarking::baseline::WeightInfo for Weigh // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 158_000 picoseconds. - Weight::from_parts(184_720, 0) + // Minimum execution time: 172_000 picoseconds. + Weight::from_parts(200_942, 0) .saturating_add(Weight::from_parts(0, 0)) } /// The range of component `i` is `[0, 1000000]`. @@ -79,16 +82,16 @@ impl frame_benchmarking::baseline::WeightInfo for Weigh // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 152_000 picoseconds. - Weight::from_parts(177_496, 0) + // Minimum execution time: 170_000 picoseconds. + Weight::from_parts(196_906, 0) .saturating_add(Weight::from_parts(0, 0)) } fn hashing() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 19_907_376_000 picoseconds. - Weight::from_parts(19_988_727_000, 0) + // Minimum execution time: 23_346_876_000 picoseconds. + Weight::from_parts(23_363_744_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// The range of component `i` is `[0, 100]`. @@ -96,10 +99,10 @@ impl frame_benchmarking::baseline::WeightInfo for Weigh // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 198_000 picoseconds. - Weight::from_parts(228_000, 0) + // Minimum execution time: 201_000 picoseconds. + Weight::from_parts(219_000, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 20_467 - .saturating_add(Weight::from_parts(47_443_635, 0).saturating_mul(i.into())) + // Standard Error: 14_372 + .saturating_add(Weight::from_parts(45_375_800, 0).saturating_mul(i.into())) } } diff --git a/polkadot/runtime/rococo/src/weights/frame_system.rs b/polkadot/runtime/rococo/src/weights/frame_system.rs index 2e49483dcc6..1742a761ca7 100644 --- a/polkadot/runtime/rococo/src/weights/frame_system.rs +++ b/polkadot/runtime/rococo/src/weights/frame_system.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `frame_system` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=frame_system // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/ +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -52,91 +55,91 @@ impl frame_system::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_283_000 picoseconds. - Weight::from_parts(2_305_000, 0) + // Minimum execution time: 1_541_000 picoseconds. + Weight::from_parts(2_581_470, 0) .saturating_add(Weight::from_parts(0, 0)) // Standard Error: 0 - .saturating_add(Weight::from_parts(366, 0).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(387, 0).saturating_mul(b.into())) } /// The range of component `b` is `[0, 3932160]`. fn remark_with_event(b: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_435_000 picoseconds. - Weight::from_parts(7_581_000, 0) + // Minimum execution time: 5_060_000 picoseconds. + Weight::from_parts(5_167_000, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 0 - .saturating_add(Weight::from_parts(1_408, 0).saturating_mul(b.into())) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_696, 0).saturating_mul(b.into())) } - /// Storage: System Digest (r:1 w:1) - /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: unknown `0x3a686561707061676573` (r:0 w:1) - /// Proof Skipped: unknown `0x3a686561707061676573` (r:0 w:1) + /// Storage: `System::Digest` (r:1 w:1) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: UNKNOWN KEY `0x3a686561707061676573` (r:0 w:1) + /// Proof: UNKNOWN KEY `0x3a686561707061676573` (r:0 w:1) fn set_heap_pages() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `1485` - // Minimum execution time: 4_010_000 picoseconds. - Weight::from_parts(4_112_000, 0) + // Minimum execution time: 2_649_000 picoseconds. + Weight::from_parts(2_909_000, 0) .saturating_add(Weight::from_parts(0, 1485)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: System Digest (r:1 w:1) - /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: unknown `0x3a636f6465` (r:0 w:1) - /// Proof Skipped: unknown `0x3a636f6465` (r:0 w:1) + /// Storage: `System::Digest` (r:1 w:1) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) + /// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) fn set_code() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `1485` - // Minimum execution time: 80_405_511_000 picoseconds. - Weight::from_parts(83_066_478_000, 0) + // Minimum execution time: 88_417_540_000 picoseconds. + Weight::from_parts(91_809_291_000, 0) .saturating_add(Weight::from_parts(0, 1485)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Skipped Metadata (r:0 w:0) - /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// Storage: `Skipped::Metadata` (r:0 w:0) + /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `i` is `[0, 1000]`. fn set_storage(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_210_000 picoseconds. - Weight::from_parts(2_247_000, 0) + // Minimum execution time: 1_538_000 picoseconds. + Weight::from_parts(1_589_000, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 2_058 - .saturating_add(Weight::from_parts(673_943, 0).saturating_mul(i.into())) + // Standard Error: 1_740 + .saturating_add(Weight::from_parts(730_941, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) } - /// Storage: Skipped Metadata (r:0 w:0) - /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// Storage: `Skipped::Metadata` (r:0 w:0) + /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `i` is `[0, 1000]`. fn kill_storage(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_125_000 picoseconds. - Weight::from_parts(2_154_000, 0) + // Minimum execution time: 1_567_000 picoseconds. + Weight::from_parts(1_750_000, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 816 - .saturating_add(Weight::from_parts(491_194, 0).saturating_mul(i.into())) + // Standard Error: 835 + .saturating_add(Weight::from_parts(543_218, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) } - /// Storage: Skipped Metadata (r:0 w:0) - /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// Storage: `Skipped::Metadata` (r:0 w:0) + /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `p` is `[0, 1000]`. fn kill_prefix(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `129 + p * (69 ±0)` - // Estimated: `125 + p * (70 ±0)` - // Minimum execution time: 4_002_000 picoseconds. - Weight::from_parts(4_145_000, 0) - .saturating_add(Weight::from_parts(0, 125)) - // Standard Error: 1_108 - .saturating_add(Weight::from_parts(1_014_971, 0).saturating_mul(p.into())) + // Measured: `80 + p * (69 ±0)` + // Estimated: `83 + p * (70 ±0)` + // Minimum execution time: 3_412_000 picoseconds. + Weight::from_parts(3_448_000, 0) + .saturating_add(Weight::from_parts(0, 83)) + // Standard Error: 1_395 + .saturating_add(Weight::from_parts(1_142_347, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) .saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into())) @@ -147,8 +150,8 @@ impl frame_system::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 33_027_000 picoseconds. - Weight::from_parts(33_027_000, 0) + // Minimum execution time: 9_178_000 picoseconds. + Weight::from_parts(9_780_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -162,8 +165,8 @@ impl frame_system::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `22` // Estimated: `1518` - // Minimum execution time: 118_101_992_000 picoseconds. - Weight::from_parts(118_101_992_000, 0) + // Minimum execution time: 94_523_563_000 picoseconds. + Weight::from_parts(96_983_131_000, 0) .saturating_add(Weight::from_parts(0, 1518)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(3)) diff --git a/polkadot/runtime/rococo/src/weights/frame_system_extensions.rs b/polkadot/runtime/rococo/src/weights/frame_system_extensions.rs new file mode 100644 index 00000000000..40520591f53 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/frame_system_extensions.rs @@ -0,0 +1,123 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Autogenerated weights for `frame_system_extensions` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=frame_system_extensions +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_system_extensions`. +pub struct WeightInfo(PhantomData); +impl frame_system::ExtensionsWeightInfo for WeightInfo { + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_genesis() -> Weight { + // Proof Size summary in bytes: + // Measured: `54` + // Estimated: `3509` + // Minimum execution time: 3_262_000 picoseconds. + Weight::from_parts(3_497_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_mortality() -> Weight { + // Proof Size summary in bytes: + // Measured: `92` + // Estimated: `3509` + // Minimum execution time: 5_416_000 picoseconds. + Weight::from_parts(5_690_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + fn check_non_zero_sender() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 471_000 picoseconds. + Weight::from_parts(552_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn check_nonce() -> Weight { + // Proof Size summary in bytes: + // Measured: `101` + // Estimated: `3593` + // Minimum execution time: 4_847_000 picoseconds. + Weight::from_parts(5_091_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn check_spec_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 388_000 picoseconds. + Weight::from_parts(421_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_tx_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 378_000 picoseconds. + Weight::from_parts(440_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) + /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn check_weight() -> Weight { + // Proof Size summary in bytes: + // Measured: `24` + // Estimated: `1489` + // Minimum execution time: 3_402_000 picoseconds. + Weight::from_parts(3_627_000, 0) + .saturating_add(Weight::from_parts(0, 1489)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/mod.rs b/polkadot/runtime/rococo/src/weights/mod.rs index 7328dca9393..128a3083a9c 100644 --- a/polkadot/runtime/rococo/src/weights/mod.rs +++ b/polkadot/runtime/rococo/src/weights/mod.rs @@ -16,6 +16,7 @@ //! A list of the different weight modules for our runtime. pub mod frame_system; +pub mod frame_system_extensions; pub mod pallet_asset_rate; pub mod pallet_balances_balances; pub mod pallet_balances_nis_counterpart_balances; @@ -36,6 +37,7 @@ pub mod pallet_scheduler; pub mod pallet_session; pub mod pallet_sudo; pub mod pallet_timestamp; +pub mod pallet_transaction_payment; pub mod pallet_treasury; pub mod pallet_utility; pub mod pallet_vesting; diff --git a/polkadot/runtime/rococo/src/weights/pallet_asset_rate.rs b/polkadot/runtime/rococo/src/weights/pallet_asset_rate.rs index da2d1958cef..56b1e2cbc57 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_asset_rate.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_asset_rate.rs @@ -16,25 +16,28 @@ //! Autogenerated weights for `pallet_asset_rate` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-07-03, STEPS: `50`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `cob`, CPU: `` -//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/debug/polkadot +// ./target/production/polkadot // benchmark // pallet // --chain=rococo-dev // --steps=50 -// --repeat=2 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=pallet_asset_rate // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled -// --heap-pages=4096 -// --output=./runtime/rococo/src/weights/ -// --header=./file_header.txt +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,39 +50,39 @@ use core::marker::PhantomData; /// Weight functions for `pallet_asset_rate`. pub struct WeightInfo(PhantomData); impl pallet_asset_rate::WeightInfo for WeightInfo { - /// Storage: AssetRate ConversionRateToNative (r:1 w:1) - /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(1237), added: 3712, mode: MaxEncodedLen) + /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1) + /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(1238), added: 3713, mode: `MaxEncodedLen`) fn create() -> Weight { // Proof Size summary in bytes: - // Measured: `42` - // Estimated: `4702` - // Minimum execution time: 143_000_000 picoseconds. - Weight::from_parts(155_000_000, 0) - .saturating_add(Weight::from_parts(0, 4702)) + // Measured: `142` + // Estimated: `4703` + // Minimum execution time: 10_277_000 picoseconds. + Weight::from_parts(10_487_000, 0) + .saturating_add(Weight::from_parts(0, 4703)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: AssetRate ConversionRateToNative (r:1 w:1) - /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(1237), added: 3712, mode: MaxEncodedLen) + /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1) + /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(1238), added: 3713, mode: `MaxEncodedLen`) fn update() -> Weight { // Proof Size summary in bytes: - // Measured: `110` - // Estimated: `4702` - // Minimum execution time: 156_000_000 picoseconds. - Weight::from_parts(172_000_000, 0) - .saturating_add(Weight::from_parts(0, 4702)) + // Measured: `210` + // Estimated: `4703` + // Minimum execution time: 10_917_000 picoseconds. + Weight::from_parts(11_249_000, 0) + .saturating_add(Weight::from_parts(0, 4703)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: AssetRate ConversionRateToNative (r:1 w:1) - /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(1237), added: 3712, mode: MaxEncodedLen) + /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1) + /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(1238), added: 3713, mode: `MaxEncodedLen`) fn remove() -> Weight { // Proof Size summary in bytes: - // Measured: `110` - // Estimated: `4702` - // Minimum execution time: 150_000_000 picoseconds. - Weight::from_parts(160_000_000, 0) - .saturating_add(Weight::from_parts(0, 4702)) + // Measured: `210` + // Estimated: `4703` + // Minimum execution time: 11_332_000 picoseconds. + Weight::from_parts(11_866_000, 0) + .saturating_add(Weight::from_parts(0, 4703)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/weights/pallet_balances_balances.rs b/polkadot/runtime/rococo/src/weights/pallet_balances_balances.rs index 1b0ae1eeece..3fa54f2c369 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_balances_balances.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_balances_balances.rs @@ -16,24 +16,26 @@ //! Autogenerated weights for `pallet_balances` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-01-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/production/polkadot +// ./target/production/polkadot // benchmark // pallet +// --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_balances // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled -// --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_balances -// --chain=rococo-dev // --header=./polkadot/file_header.txt // --output=./polkadot/runtime/rococo/src/weights/ @@ -54,8 +56,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 44_127_000 picoseconds. - Weight::from_parts(45_099_000, 0) + // Minimum execution time: 45_336_000 picoseconds. + Weight::from_parts(46_189_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -66,8 +68,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 34_265_000 picoseconds. - Weight::from_parts(35_083_000, 0) + // Minimum execution time: 34_880_000 picoseconds. + Weight::from_parts(35_770_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -78,8 +80,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 12_189_000 picoseconds. - Weight::from_parts(12_655_000, 0) + // Minimum execution time: 12_904_000 picoseconds. + Weight::from_parts(13_260_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -90,8 +92,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 16_910_000 picoseconds. - Weight::from_parts(17_474_000, 0) + // Minimum execution time: 17_669_000 picoseconds. + Weight::from_parts(18_228_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -102,8 +104,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `6196` - // Minimum execution time: 45_212_000 picoseconds. - Weight::from_parts(46_320_000, 0) + // Minimum execution time: 46_492_000 picoseconds. + Weight::from_parts(47_639_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -114,8 +116,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 42_500_000 picoseconds. - Weight::from_parts(43_991_000, 0) + // Minimum execution time: 44_342_000 picoseconds. + Weight::from_parts(45_144_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -126,8 +128,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 15_197_000 picoseconds. - Weight::from_parts(15_749_000, 0) + // Minimum execution time: 15_260_000 picoseconds. + Weight::from_parts(15_775_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -140,11 +142,11 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0 + u * (135 ±0)` // Estimated: `990 + u * (2603 ±0)` - // Minimum execution time: 14_414_000 picoseconds. - Weight::from_parts(14_685_000, 0) + // Minimum execution time: 14_703_000 picoseconds. + Weight::from_parts(14_950_000, 0) .saturating_add(Weight::from_parts(0, 990)) - // Standard Error: 7_918 - .saturating_add(Weight::from_parts(13_095_420, 0).saturating_mul(u.into())) + // Standard Error: 7_665 + .saturating_add(Weight::from_parts(13_335_803, 0).saturating_mul(u.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into()))) .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) @@ -153,8 +155,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_239_000 picoseconds. - Weight::from_parts(5_617_000, 0) + // Minimum execution time: 5_506_000 picoseconds. + Weight::from_parts(5_753_000, 0) .saturating_add(Weight::from_parts(0, 0)) } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_balances_nis_counterpart_balances.rs b/polkadot/runtime/rococo/src/weights/pallet_balances_nis_counterpart_balances.rs index 6cca9b9320a..1852ba6c2c4 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_balances_nis_counterpart_balances.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_balances_nis_counterpart_balances.rs @@ -16,24 +16,26 @@ //! Autogenerated weights for `pallet_balances` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-01-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/production/polkadot +// ./target/production/polkadot // benchmark // pallet +// --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_balances // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled -// --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_balances -// --chain=rococo-dev // --header=./polkadot/file_header.txt // --output=./polkadot/runtime/rococo/src/weights/ @@ -56,8 +58,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `6164` - // Minimum execution time: 41_978_000 picoseconds. - Weight::from_parts(42_989_000, 0) + // Minimum execution time: 42_443_000 picoseconds. + Weight::from_parts(43_250_000, 0) .saturating_add(Weight::from_parts(0, 6164)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) @@ -70,8 +72,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `6164` - // Minimum execution time: 32_250_000 picoseconds. - Weight::from_parts(33_074_000, 0) + // Minimum execution time: 32_417_000 picoseconds. + Weight::from_parts(33_247_000, 0) .saturating_add(Weight::from_parts(0, 6164)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) @@ -82,8 +84,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `3577` - // Minimum execution time: 9_906_000 picoseconds. - Weight::from_parts(10_397_000, 0) + // Minimum execution time: 10_091_000 picoseconds. + Weight::from_parts(10_426_000, 0) .saturating_add(Weight::from_parts(0, 3577)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -96,8 +98,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `277` // Estimated: `3593` - // Minimum execution time: 16_298_000 picoseconds. - Weight::from_parts(17_115_000, 0) + // Minimum execution time: 16_546_000 picoseconds. + Weight::from_parts(17_259_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -110,8 +112,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `206` // Estimated: `6196` - // Minimum execution time: 43_283_000 picoseconds. - Weight::from_parts(44_033_000, 0) + // Minimum execution time: 44_322_000 picoseconds. + Weight::from_parts(45_319_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(4)) @@ -124,8 +126,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `6164` - // Minimum execution time: 40_564_000 picoseconds. - Weight::from_parts(41_597_000, 0) + // Minimum execution time: 40_852_000 picoseconds. + Weight::from_parts(42_205_000, 0) .saturating_add(Weight::from_parts(0, 6164)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) @@ -138,8 +140,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `277` // Estimated: `3593` - // Minimum execution time: 15_018_000 picoseconds. - Weight::from_parts(15_532_000, 0) + // Minimum execution time: 15_050_000 picoseconds. + Weight::from_parts(15_813_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -154,11 +156,11 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0 + u * (256 ±0)` // Estimated: `990 + u * (2603 ±0)` - // Minimum execution time: 14_470_000 picoseconds. - Weight::from_parts(14_828_000, 0) + // Minimum execution time: 14_830_000 picoseconds. + Weight::from_parts(15_061_000, 0) .saturating_add(Weight::from_parts(0, 990)) - // Standard Error: 15_515 - .saturating_add(Weight::from_parts(14_505_553, 0).saturating_mul(u.into())) + // Standard Error: 16_072 + .saturating_add(Weight::from_parts(14_981_430, 0).saturating_mul(u.into())) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(u.into()))) .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(u.into()))) .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) @@ -167,8 +169,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_277_000 picoseconds. - Weight::from_parts(5_628_000, 0) + // Minimum execution time: 5_344_000 picoseconds. + Weight::from_parts(5_735_000, 0) .saturating_add(Weight::from_parts(0, 0)) } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_bounties.rs b/polkadot/runtime/rococo/src/weights/pallet_bounties.rs index 38d3645316f..8f8be5f2386 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_bounties.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_bounties.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_bounties` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=pallet_bounties // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/ +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,118 +50,181 @@ use core::marker::PhantomData; /// Weight functions for `pallet_bounties`. pub struct WeightInfo(PhantomData); impl pallet_bounties::WeightInfo for WeightInfo { - /// Storage: Bounties BountyCount (r:1 w:1) - /// Proof: Bounties BountyCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Bounties BountyDescriptions (r:0 w:1) - /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) - /// Storage: Bounties Bounties (r:0 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: `Bounties::BountyCount` (r:1 w:1) + /// Proof: `Bounties::BountyCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) + /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`) + /// Storage: `Bounties::Bounties` (r:0 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) /// The range of component `d` is `[0, 16384]`. fn propose_bounty(d: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `210` // Estimated: `3593` - // Minimum execution time: 28_907_000 picoseconds. - Weight::from_parts(31_356_074, 0) + // Minimum execution time: 21_772_000 picoseconds. + Weight::from_parts(22_861_341, 0) .saturating_add(Weight::from_parts(0, 3593)) - // Standard Error: 18 - .saturating_add(Weight::from_parts(606, 0).saturating_mul(d.into())) + // Standard Error: 3 + .saturating_add(Weight::from_parts(721, 0).saturating_mul(d.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(4)) } + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `Bounties::BountyApprovals` (r:1 w:1) + /// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) fn approve_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `302` + // Estimated: `3642` + // Minimum execution time: 11_218_000 picoseconds. + Weight::from_parts(11_796_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) } + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) fn propose_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `322` + // Estimated: `3642` + // Minimum execution time: 10_959_000 picoseconds. + Weight::from_parts(11_658_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn unassign_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `498` + // Estimated: `3642` + // Minimum execution time: 37_419_000 picoseconds. + Weight::from_parts(38_362_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) } + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn accept_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `494` + // Estimated: `3642` + // Minimum execution time: 27_328_000 picoseconds. + Weight::from_parts(27_661_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) } + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) fn award_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `400` + // Estimated: `3642` + // Minimum execution time: 16_067_000 picoseconds. + Weight::from_parts(16_865_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:3 w:3) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) + /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) + /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`) fn claim_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `764` + // Estimated: `8799` + // Minimum execution time: 101_153_000 picoseconds. + Weight::from_parts(102_480_000, 0) + .saturating_add(Weight::from_parts(0, 8799)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(6)) } - /// Storage: Bounties Bounties (r:1 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: ChildBounties ParentChildBounties (r:1 w:0) - /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Bounties BountyDescriptions (r:0 w:1) - /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) + /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`) fn close_bounty_proposed() -> Weight { // Proof Size summary in bytes: - // Measured: `482` + // Measured: `444` // Estimated: `3642` - // Minimum execution time: 46_020_000 picoseconds. - Weight::from_parts(46_711_000, 0) + // Minimum execution time: 38_838_000 picoseconds. + Weight::from_parts(39_549_000, 0) .saturating_add(Weight::from_parts(0, 3642)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) + /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`) fn close_bounty_active() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `680` + // Estimated: `6196` + // Minimum execution time: 68_592_000 picoseconds. + Weight::from_parts(70_727_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) } + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) fn extend_bounty_expiry() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `358` + // Estimated: `3642` + // Minimum execution time: 11_272_000 picoseconds. + Weight::from_parts(11_592_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Bounties BountyApprovals (r:1 w:1) - /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: `Bounties::BountyApprovals` (r:1 w:1) + /// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: `Bounties::Bounties` (r:100 w:100) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:200 w:200) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `b` is `[0, 100]`. - fn spend_funds(_b: u32, ) -> Weight { + fn spend_funds(b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `1887` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(2_405_233, 0) + // Measured: `0 + b * (297 ±0)` + // Estimated: `1887 + b * (5206 ±0)` + // Minimum execution time: 2_844_000 picoseconds. + Weight::from_parts(2_900_000, 0) .saturating_add(Weight::from_parts(0, 1887)) + // Standard Error: 9_467 + .saturating_add(Weight::from_parts(32_326_595, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(b.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(b.into()))) + .saturating_add(Weight::from_parts(0, 5206).saturating_mul(b.into())) } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_child_bounties.rs b/polkadot/runtime/rococo/src/weights/pallet_child_bounties.rs index e8c798d45e7..47ae3a5c90d 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_child_bounties.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_child_bounties.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_child_bounties` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=pallet_child_bounties // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/ +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,69 +50,153 @@ use core::marker::PhantomData; /// Weight functions for `pallet_child_bounties`. pub struct WeightInfo(PhantomData); impl pallet_child_bounties::WeightInfo for WeightInfo { + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBountyCount` (r:1 w:1) + /// Proof: `ChildBounties::ChildBountyCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) + /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBounties` (r:0 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) /// The range of component `d` is `[0, 16384]`. - fn add_child_bounty(_d: u32, ) -> Weight { + fn add_child_bounty(d: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `540` + // Estimated: `6196` + // Minimum execution time: 57_964_000 picoseconds. + Weight::from_parts(59_559_565, 0) + .saturating_add(Weight::from_parts(0, 6196)) + // Standard Error: 11 + .saturating_add(Weight::from_parts(697, 0).saturating_mul(d.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(6)) } + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) + /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) fn propose_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `594` + // Estimated: `3642` + // Minimum execution time: 17_527_000 picoseconds. + Weight::from_parts(18_257_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) } + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn accept_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `740` + // Estimated: `3642` + // Minimum execution time: 29_354_000 picoseconds. + Weight::from_parts(30_629_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) } + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn unassign_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `740` + // Estimated: `3642` + // Minimum execution time: 40_643_000 picoseconds. + Weight::from_parts(42_072_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) } + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) fn award_child_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `637` + // Estimated: `3642` + // Minimum execution time: 18_616_000 picoseconds. + Weight::from_parts(19_316_000, 0) + .saturating_add(Weight::from_parts(0, 3642)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:3 w:3) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) + /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`) fn claim_child_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `576` + // Estimated: `8799` + // Minimum execution time: 96_376_000 picoseconds. + Weight::from_parts(98_476_000, 0) + .saturating_add(Weight::from_parts(0, 8799)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(6)) } + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) + /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) + /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`) fn close_child_bounty_added() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `840` + // Estimated: `6196` + // Minimum execution time: 64_640_000 picoseconds. + Weight::from_parts(66_174_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(6)) } + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:3 w:3) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) + /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) + /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`) fn close_child_bounty_active() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `1027` + // Estimated: `8799` + // Minimum execution time: 78_159_000 picoseconds. + Weight::from_parts(79_820_000, 0) + .saturating_add(Weight::from_parts(0, 8799)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(7)) } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_conviction_voting.rs b/polkadot/runtime/rococo/src/weights/pallet_conviction_voting.rs index ba505737f1b..5d92c158df4 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_conviction_voting.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_conviction_voting.rs @@ -16,17 +16,17 @@ //! Autogenerated weights for `pallet_conviction_voting` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot // benchmark // pallet -// --chain=kusama-dev +// --chain=rococo-dev // --steps=50 // --repeat=20 // --no-storage-info @@ -36,8 +36,8 @@ // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/kusama/src/weights/ +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,144 +50,152 @@ use core::marker::PhantomData; /// Weight functions for `pallet_conviction_voting`. pub struct WeightInfo(PhantomData); impl pallet_conviction_voting::WeightInfo for WeightInfo { - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) - /// Storage: ConvictionVoting VotingFor (r:1 w:1) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) - /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) + /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) + /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(311), added: 2786, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn vote_new() -> Weight { // Proof Size summary in bytes: - // Measured: `13445` + // Measured: `13407` // Estimated: `42428` - // Minimum execution time: 151_077_000 picoseconds. - Weight::from_parts(165_283_000, 0) + // Minimum execution time: 128_378_000 picoseconds. + Weight::from_parts(131_028_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(5)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) - /// Storage: ConvictionVoting VotingFor (r:1 w:1) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) - /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) + /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) + /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(311), added: 2786, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn vote_existing() -> Weight { // Proof Size summary in bytes: - // Measured: `14166` + // Measured: `14128` // Estimated: `83866` - // Minimum execution time: 232_420_000 picoseconds. - Weight::from_parts(244_439_000, 0) + // Minimum execution time: 155_379_000 picoseconds. + Weight::from_parts(161_597_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(7)) - .saturating_add(T::DbWeight::get().writes(6)) + .saturating_add(T::DbWeight::get().writes(7)) } - /// Storage: ConvictionVoting VotingFor (r:1 w:1) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn remove_vote() -> Weight { // Proof Size summary in bytes: // Measured: `13918` // Estimated: `83866` - // Minimum execution time: 205_017_000 picoseconds. - Weight::from_parts(216_594_000, 0) + // Minimum execution time: 130_885_000 picoseconds. + Weight::from_parts(138_080_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(5)) } - /// Storage: ConvictionVoting VotingFor (r:1 w:1) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: Referenda ReferendumInfoFor (r:1 w:0) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) fn remove_other_vote() -> Weight { // Proof Size summary in bytes: - // Measured: `13004` + // Measured: `13005` // Estimated: `30706` - // Minimum execution time: 84_226_000 picoseconds. - Weight::from_parts(91_255_000, 0) + // Minimum execution time: 71_743_000 picoseconds. + Weight::from_parts(75_170_000, 0) .saturating_add(Weight::from_parts(0, 30706)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: ConvictionVoting VotingFor (r:2 w:2) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: Referenda ReferendumInfoFor (r:512 w:512) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) - /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) - /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `ConvictionVoting::VotingFor` (r:2 w:2) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `Referenda::ReferendumInfoFor` (r:512 w:512) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) + /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(311), added: 2786, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:50) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 512]`. fn delegate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `29640 + r * (365 ±0)` + // Measured: `29602 + r * (365 ±0)` // Estimated: `83866 + r * (3411 ±0)` - // Minimum execution time: 78_708_000 picoseconds. - Weight::from_parts(2_053_488_615, 0) + // Minimum execution time: 58_504_000 picoseconds. + Weight::from_parts(814_301_018, 0) .saturating_add(Weight::from_parts(0, 83866)) - // Standard Error: 179_271 - .saturating_add(Weight::from_parts(47_806_482, 0).saturating_mul(r.into())) + // Standard Error: 59_961 + .saturating_add(Weight::from_parts(20_002_833, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) - .saturating_add(T::DbWeight::get().writes(6)) + .saturating_add(T::DbWeight::get().writes(45)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 3411).saturating_mul(r.into())) } - /// Storage: ConvictionVoting VotingFor (r:2 w:2) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: Referenda ReferendumInfoFor (r:512 w:512) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: `ConvictionVoting::VotingFor` (r:2 w:2) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `Referenda::ReferendumInfoFor` (r:512 w:512) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:50) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 512]`. fn undelegate(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `29555 + r * (365 ±0)` // Estimated: `83866 + r * (3411 ±0)` - // Minimum execution time: 45_232_000 picoseconds. - Weight::from_parts(2_045_021_014, 0) + // Minimum execution time: 34_970_000 picoseconds. + Weight::from_parts(771_155_804, 0) .saturating_add(Weight::from_parts(0, 83866)) - // Standard Error: 185_130 - .saturating_add(Weight::from_parts(47_896_011, 0).saturating_mul(r.into())) + // Standard Error: 57_795 + .saturating_add(Weight::from_parts(19_781_645, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(43)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 3411).saturating_mul(r.into())) } - /// Storage: ConvictionVoting VotingFor (r:1 w:1) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) - /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) + /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(311), added: 2786, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) fn unlock() -> Weight { // Proof Size summary in bytes: - // Measured: `12218` + // Measured: `12180` // Estimated: `30706` - // Minimum execution time: 116_446_000 picoseconds. - Weight::from_parts(124_043_000, 0) + // Minimum execution time: 89_648_000 picoseconds. + Weight::from_parts(97_144_000, 0) .saturating_add(Weight::from_parts(0, 30706)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) diff --git a/polkadot/runtime/rococo/src/weights/pallet_identity.rs b/polkadot/runtime/rococo/src/weights/pallet_identity.rs index b334e21ea03..6df16351f2c 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_identity.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_identity.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_identity` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=pallet_identity // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/ +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,290 +50,291 @@ use core::marker::PhantomData; /// Weight functions for `pallet_identity`. pub struct WeightInfo(PhantomData); impl pallet_identity::WeightInfo for WeightInfo { - /// Storage: Identity Registrars (r:1 w:1) - /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: `Identity::Registrars` (r:1 w:1) + /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 19]`. fn add_registrar(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `32 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 12_290_000 picoseconds. - Weight::from_parts(12_664_362, 0) + // Minimum execution time: 7_673_000 picoseconds. + Weight::from_parts(8_351_866, 0) .saturating_add(Weight::from_parts(0, 2626)) - // Standard Error: 1_347 - .saturating_add(Weight::from_parts(88_179, 0).saturating_mul(r.into())) + // Standard Error: 1_302 + .saturating_add(Weight::from_parts(79_198, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Identity IdentityOf (r:1 w:1) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 20]`. fn set_identity(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `442 + r * (5 ±0)` - // Estimated: `11003` - // Minimum execution time: 31_373_000 picoseconds. - Weight::from_parts(30_435_545, 0) - .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 2_307 - .saturating_add(Weight::from_parts(92_753, 0).saturating_mul(r.into())) + // Measured: `6978 + r * (5 ±0)` + // Estimated: `11037` + // Minimum execution time: 111_646_000 picoseconds. + Weight::from_parts(113_254_991, 0) + .saturating_add(Weight::from_parts(0, 11037)) + // Standard Error: 6_611 + .saturating_add(Weight::from_parts(162_119, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Identity IdentityOf (r:1 w:0) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:100 w:100) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:100 w:100) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. fn set_subs_new(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `101` - // Estimated: `11003 + s * (2589 ±0)` - // Minimum execution time: 9_251_000 picoseconds. - Weight::from_parts(22_039_210, 0) - .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 40_779 - .saturating_add(Weight::from_parts(2_898_525, 0).saturating_mul(s.into())) + // Estimated: `11037 + s * (2589 ±0)` + // Minimum execution time: 8_010_000 picoseconds. + Weight::from_parts(19_868_412, 0) + .saturating_add(Weight::from_parts(0, 11037)) + // Standard Error: 5_018 + .saturating_add(Weight::from_parts(3_115_007, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(s.into()))) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 2589).saturating_mul(s.into())) } - /// Storage: Identity IdentityOf (r:1 w:0) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:0 w:100) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:0 w:100) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) /// The range of component `p` is `[0, 100]`. fn set_subs_old(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `194 + p * (32 ±0)` - // Estimated: `11003` - // Minimum execution time: 9_329_000 picoseconds. - Weight::from_parts(24_055_061, 0) - .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 3_428 - .saturating_add(Weight::from_parts(1_130_604, 0).saturating_mul(p.into())) + // Estimated: `11037` + // Minimum execution time: 8_111_000 picoseconds. + Weight::from_parts(19_482_392, 0) + .saturating_add(Weight::from_parts(0, 11037)) + // Standard Error: 3_156 + .saturating_add(Weight::from_parts(1_305_890, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) } - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) - /// Storage: Identity IdentityOf (r:1 w:1) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:0 w:100) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:0 w:100) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 20]`. /// The range of component `s` is `[0, 100]`. - fn clear_identity(_r: u32, s: u32, ) -> Weight { + fn clear_identity(r: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `469 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` - // Estimated: `11003` - // Minimum execution time: 53_365_000 picoseconds. - Weight::from_parts(35_391_422, 0) - .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 1_353 - .saturating_add(Weight::from_parts(1_074_019, 0).saturating_mul(s.into())) + // Measured: `7070 + r * (5 ±0) + s * (32 ±0)` + // Estimated: `11037` + // Minimum execution time: 54_107_000 picoseconds. + Weight::from_parts(56_347_715, 0) + .saturating_add(Weight::from_parts(0, 11037)) + // Standard Error: 10_944 + .saturating_add(Weight::from_parts(191_321, 0).saturating_mul(r.into())) + // Standard Error: 2_135 + .saturating_add(Weight::from_parts(1_295_872, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) } - /// Storage: Identity Registrars (r:1 w:0) - /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) - /// Storage: Identity IdentityOf (r:1 w:1) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: `Identity::Registrars` (r:1 w:0) + /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 20]`. fn request_judgement(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `367 + r * (57 ±0) + x * (66 ±0)` - // Estimated: `11003` - // Minimum execution time: 32_509_000 picoseconds. - Weight::from_parts(31_745_585, 0) - .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 2_214 - .saturating_add(Weight::from_parts(83_822, 0).saturating_mul(r.into())) - + // Measured: `6968 + r * (57 ±0)` + // Estimated: `11037` + // Minimum execution time: 75_780_000 picoseconds. + Weight::from_parts(76_869_773, 0) + .saturating_add(Weight::from_parts(0, 11037)) + // Standard Error: 5_456 + .saturating_add(Weight::from_parts(135_316, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Identity IdentityOf (r:1 w:1) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 20]`. fn cancel_request(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `398 + x * (66 ±0)` - // Estimated: `11003` - // Minimum execution time: 29_609_000 picoseconds. - Weight::from_parts(28_572_602, 0) - .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 2_528 - .saturating_add(Weight::from_parts(85_593, 0).saturating_mul(r.into())) + // Measured: `6999` + // Estimated: `11037` + // Minimum execution time: 75_769_000 picoseconds. + Weight::from_parts(76_805_143, 0) + .saturating_add(Weight::from_parts(0, 11037)) + // Standard Error: 3_598 + .saturating_add(Weight::from_parts(84_593, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Identity Registrars (r:1 w:1) - /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: `Identity::Registrars` (r:1 w:1) + /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 19]`. fn set_fee(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `89 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 7_793_000 picoseconds. - Weight::from_parts(8_173_888, 0) + // Minimum execution time: 5_357_000 picoseconds. + Weight::from_parts(5_732_132, 0) .saturating_add(Weight::from_parts(0, 2626)) - // Standard Error: 1_569 - .saturating_add(Weight::from_parts(72_367, 0).saturating_mul(r.into())) + // Standard Error: 927 + .saturating_add(Weight::from_parts(70_832, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Identity Registrars (r:1 w:1) - /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: `Identity::Registrars` (r:1 w:1) + /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 19]`. fn set_account_id(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `89 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 7_708_000 picoseconds. - Weight::from_parts(8_091_149, 0) + // Minimum execution time: 5_484_000 picoseconds. + Weight::from_parts(5_892_704, 0) .saturating_add(Weight::from_parts(0, 2626)) - // Standard Error: 869 - .saturating_add(Weight::from_parts(87_993, 0).saturating_mul(r.into())) + // Standard Error: 947 + .saturating_add(Weight::from_parts(71_231, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Identity Registrars (r:1 w:1) - /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: `Identity::Registrars` (r:1 w:1) + /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 19]`. fn set_fields(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `89 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 7_601_000 picoseconds. - Weight::from_parts(8_038_414, 0) + // Minimum execution time: 5_310_000 picoseconds. + Weight::from_parts(5_766_651, 0) .saturating_add(Weight::from_parts(0, 2626)) - // Standard Error: 1_041 - .saturating_add(Weight::from_parts(82_588, 0).saturating_mul(r.into())) + // Standard Error: 916 + .saturating_add(Weight::from_parts(74_776, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Identity Registrars (r:1 w:0) - /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) - /// Storage: Identity IdentityOf (r:1 w:1) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: `Identity::Registrars` (r:1 w:0) + /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 19]`. fn provide_judgement(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `445 + r * (57 ±0) + x * (66 ±0)` - // Estimated: `11003` - // Minimum execution time: 23_114_000 picoseconds. - Weight::from_parts(22_076_548, 0) - .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 2_881 - .saturating_add(Weight::from_parts(109_812, 0).saturating_mul(r.into())) + // Measured: `7046 + r * (57 ±0)` + // Estimated: `11037` + // Minimum execution time: 98_200_000 picoseconds. + Weight::from_parts(100_105_482, 0) + .saturating_add(Weight::from_parts(0, 11037)) + // Standard Error: 6_152 + .saturating_add(Weight::from_parts(58_906, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) - /// Storage: Identity IdentityOf (r:1 w:1) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:0 w:100) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:0 w:100) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 20]`. /// The range of component `s` is `[0, 100]`. fn kill_identity(r: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `676 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` - // Estimated: `11003` - // Minimum execution time: 70_007_000 picoseconds. - Weight::from_parts(50_186_495, 0) - .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 6_533 - .saturating_add(Weight::from_parts(15_486, 0).saturating_mul(r.into())) - // Standard Error: 1_275 - .saturating_add(Weight::from_parts(1_085_117, 0).saturating_mul(s.into())) + // Measured: `7277 + r * (5 ±0) + s * (32 ±0)` + // Estimated: `11037` + // Minimum execution time: 64_647_000 picoseconds. + Weight::from_parts(68_877_027, 0) + .saturating_add(Weight::from_parts(0, 11037)) + // Standard Error: 9_965 + .saturating_add(Weight::from_parts(135_044, 0).saturating_mul(r.into())) + // Standard Error: 1_944 + .saturating_add(Weight::from_parts(1_388_151, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) } - /// Storage: Identity IdentityOf (r:1 w:0) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:1 w:1) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:1 w:1) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 99]`. fn add_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `475 + s * (36 ±0)` - // Estimated: `11003` - // Minimum execution time: 28_453_000 picoseconds. - Weight::from_parts(33_165_934, 0) - .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 1_217 - .saturating_add(Weight::from_parts(65_401, 0).saturating_mul(s.into())) + // Estimated: `11037` + // Minimum execution time: 23_550_000 picoseconds. + Weight::from_parts(29_439_842, 0) + .saturating_add(Weight::from_parts(0, 11037)) + // Standard Error: 1_453 + .saturating_add(Weight::from_parts(96_324, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Identity IdentityOf (r:1 w:0) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:1 w:1) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:1 w:1) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 100]`. fn rename_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `591 + s * (3 ±0)` - // Estimated: `11003` - // Minimum execution time: 12_846_000 picoseconds. - Weight::from_parts(14_710_284, 0) - .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 496 - .saturating_add(Weight::from_parts(19_539, 0).saturating_mul(s.into())) + // Estimated: `11037` + // Minimum execution time: 13_704_000 picoseconds. + Weight::from_parts(15_241_441, 0) + .saturating_add(Weight::from_parts(0, 11037)) + // Standard Error: 498 + .saturating_add(Weight::from_parts(40_973, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Identity IdentityOf (r:1 w:0) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:1 w:1) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:1 w:1) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 100]`. fn remove_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `638 + s * (35 ±0)` - // Estimated: `11003` - // Minimum execution time: 32_183_000 picoseconds. - Weight::from_parts(35_296_731, 0) - .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 854 - .saturating_add(Weight::from_parts(52_028, 0).saturating_mul(s.into())) + // Estimated: `11037` + // Minimum execution time: 29_310_000 picoseconds. + Weight::from_parts(31_712_666, 0) + .saturating_add(Weight::from_parts(0, 11037)) + // Standard Error: 967 + .saturating_add(Weight::from_parts(81_250, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Identity SuperOf (r:1 w:1) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:0) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Identity::SuperOf` (r:1 w:1) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:0) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 99]`. fn quit_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `704 + s * (37 ±0)` // Estimated: `6723` - // Minimum execution time: 24_941_000 picoseconds. - Weight::from_parts(27_433_059, 0) + // Minimum execution time: 22_906_000 picoseconds. + Weight::from_parts(24_638_729, 0) .saturating_add(Weight::from_parts(0, 6723)) - // Standard Error: 856 - .saturating_add(Weight::from_parts(57_463, 0).saturating_mul(s.into())) + // Standard Error: 645 + .saturating_add(Weight::from_parts(75_121, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -340,90 +344,93 @@ impl pallet_identity::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 13_873_000 picoseconds. - Weight::from_parts(13_873_000, 0) + // Minimum execution time: 6_056_000 picoseconds. + Weight::from_parts(6_349_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Identity::UsernameAuthorities` (r:0 w:1) + /// Storage: `Identity::UsernameAuthorities` (r:1 w:1) /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn remove_username_authority() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 10_653_000 picoseconds. - Weight::from_parts(10_653_000, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `80` + // Estimated: `3517` + // Minimum execution time: 9_003_000 picoseconds. + Weight::from_parts(9_276_000, 0) + .saturating_add(Weight::from_parts(0, 3517)) + .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Identity::UsernameAuthorities` (r:1 w:1) /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) /// Storage: `Identity::AccountOfUsername` (r:1 w:1) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Storage: `Identity::PendingUsernames` (r:1 w:0) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) fn set_username_for() -> Weight { // Proof Size summary in bytes: // Measured: `80` // Estimated: `11037` - // Minimum execution time: 75_928_000 picoseconds. - Weight::from_parts(75_928_000, 0) + // Minimum execution time: 64_724_000 picoseconds. + Weight::from_parts(66_597_000, 0) .saturating_add(Weight::from_parts(0, 11037)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Identity::PendingUsernames` (r:1 w:1) - /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// Storage: `Identity::AccountOfUsername` (r:0 w:1) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) fn accept_username() -> Weight { // Proof Size summary in bytes: - // Measured: `106` + // Measured: `115` // Estimated: `11037` - // Minimum execution time: 38_157_000 picoseconds. - Weight::from_parts(38_157_000, 0) + // Minimum execution time: 19_538_000 picoseconds. + Weight::from_parts(20_204_000, 0) .saturating_add(Weight::from_parts(0, 11037)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Identity::PendingUsernames` (r:1 w:1) - /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) fn remove_expired_approval() -> Weight { // Proof Size summary in bytes: - // Measured: `106` - // Estimated: `3542` - // Minimum execution time: 46_821_000 picoseconds. - Weight::from_parts(46_821_000, 0) - .saturating_add(Weight::from_parts(0, 3542)) + // Measured: `115` + // Estimated: `3550` + // Minimum execution time: 16_000_000 picoseconds. + Weight::from_parts(19_354_000, 0) + .saturating_add(Weight::from_parts(0, 3550)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Identity::AccountOfUsername` (r:1 w:0) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) fn set_primary_username() -> Weight { // Proof Size summary in bytes: - // Measured: `247` + // Measured: `257` // Estimated: `11037` - // Minimum execution time: 22_515_000 picoseconds. - Weight::from_parts(22_515_000, 0) + // Minimum execution time: 15_298_000 picoseconds. + Weight::from_parts(15_760_000, 0) .saturating_add(Weight::from_parts(0, 11037)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Identity::AccountOfUsername` (r:1 w:1) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:0) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) fn remove_dangling_username() -> Weight { // Proof Size summary in bytes: - // Measured: `126` + // Measured: `98` // Estimated: `11037` - // Minimum execution time: 15_997_000 picoseconds. - Weight::from_parts(15_997_000, 0) + // Minimum execution time: 10_829_000 picoseconds. + Weight::from_parts(11_113_000, 0) .saturating_add(Weight::from_parts(0, 11037)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/polkadot/runtime/rococo/src/weights/pallet_indices.rs b/polkadot/runtime/rococo/src/weights/pallet_indices.rs index 99ffd3210ed..434db97d4a7 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_indices.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_indices.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_indices` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=pallet_indices // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/ +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,66 +50,66 @@ use core::marker::PhantomData; /// Weight functions for `pallet_indices`. pub struct WeightInfo(PhantomData); impl pallet_indices::WeightInfo for WeightInfo { - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn claim() -> Weight { // Proof Size summary in bytes: - // Measured: `142` + // Measured: `4` // Estimated: `3534` - // Minimum execution time: 25_107_000 picoseconds. - Weight::from_parts(25_655_000, 0) + // Minimum execution time: 18_092_000 picoseconds. + Weight::from_parts(18_533_000, 0) .saturating_add(Weight::from_parts(0, 3534)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn transfer() -> Weight { // Proof Size summary in bytes: - // Measured: `341` + // Measured: `203` // Estimated: `3593` - // Minimum execution time: 36_208_000 picoseconds. - Weight::from_parts(36_521_000, 0) + // Minimum execution time: 31_616_000 picoseconds. + Weight::from_parts(32_556_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn free() -> Weight { // Proof Size summary in bytes: - // Measured: `238` + // Measured: `100` // Estimated: `3534` - // Minimum execution time: 25_915_000 picoseconds. - Weight::from_parts(26_220_000, 0) + // Minimum execution time: 19_593_000 picoseconds. + Weight::from_parts(20_100_000, 0) .saturating_add(Weight::from_parts(0, 3534)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn force_transfer() -> Weight { // Proof Size summary in bytes: - // Measured: `341` + // Measured: `203` // Estimated: `3593` - // Minimum execution time: 28_232_000 picoseconds. - Weight::from_parts(28_845_000, 0) + // Minimum execution time: 21_429_000 picoseconds. + Weight::from_parts(22_146_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn freeze() -> Weight { // Proof Size summary in bytes: - // Measured: `238` + // Measured: `100` // Estimated: `3534` - // Minimum execution time: 27_282_000 picoseconds. - Weight::from_parts(27_754_000, 0) + // Minimum execution time: 20_425_000 picoseconds. + Weight::from_parts(21_023_000, 0) .saturating_add(Weight::from_parts(0, 3534)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/polkadot/runtime/rococo/src/weights/pallet_message_queue.rs b/polkadot/runtime/rococo/src/weights/pallet_message_queue.rs index e1e360d374a..6ebfcd060b6 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_message_queue.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_message_queue.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_message_queue` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=pallet_message_queue // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/ +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,150 +50,149 @@ use core::marker::PhantomData; /// Weight functions for `pallet_message_queue`. pub struct WeightInfo(PhantomData); impl pallet_message_queue::WeightInfo for WeightInfo { - /// Storage: MessageQueue ServiceHead (r:1 w:0) - /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen) - /// Storage: MessageQueue BookStateFor (r:2 w:2) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: `MessageQueue::ServiceHead` (r:1 w:0) + /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(6), added: 501, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::BookStateFor` (r:2 w:2) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) fn ready_ring_knit() -> Weight { // Proof Size summary in bytes: - // Measured: `248` + // Measured: `281` // Estimated: `6050` - // Minimum execution time: 12_106_000 picoseconds. - Weight::from_parts(12_387_000, 0) + // Minimum execution time: 12_830_000 picoseconds. + Weight::from_parts(13_476_000, 0) .saturating_add(Weight::from_parts(0, 6050)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: MessageQueue BookStateFor (r:2 w:2) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) - /// Storage: MessageQueue ServiceHead (r:1 w:1) - /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen) + /// Storage: `MessageQueue::BookStateFor` (r:2 w:2) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::ServiceHead` (r:1 w:1) + /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(6), added: 501, mode: `MaxEncodedLen`) fn ready_ring_unknit() -> Weight { // Proof Size summary in bytes: - // Measured: `248` + // Measured: `281` // Estimated: `6050` - // Minimum execution time: 11_227_000 picoseconds. - Weight::from_parts(11_616_000, 0) + // Minimum execution time: 11_583_000 picoseconds. + Weight::from_parts(11_902_000, 0) .saturating_add(Weight::from_parts(0, 6050)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: MessageQueue BookStateFor (r:1 w:1) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) fn service_queue_base() -> Weight { // Proof Size summary in bytes: // Measured: `42` // Estimated: `3520` - // Minimum execution time: 5_052_000 picoseconds. - Weight::from_parts(5_216_000, 0) + // Minimum execution time: 3_801_000 picoseconds. + Weight::from_parts(3_943_000, 0) .saturating_add(Weight::from_parts(0, 3520)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: MessageQueue Pages (r:1 w:1) - /// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen) + /// Storage: `MessageQueue::Pages` (r:1 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`) fn service_page_base_completion() -> Weight { // Proof Size summary in bytes: // Measured: `115` // Estimated: `36283` - // Minimum execution time: 6_522_000 picoseconds. - Weight::from_parts(6_794_000, 0) + // Minimum execution time: 5_517_000 picoseconds. + Weight::from_parts(5_861_000, 0) .saturating_add(Weight::from_parts(0, 36283)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: MessageQueue Pages (r:1 w:1) - /// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen) + /// Storage: `MessageQueue::Pages` (r:1 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`) fn service_page_base_no_completion() -> Weight { // Proof Size summary in bytes: // Measured: `115` // Estimated: `36283` - // Minimum execution time: 6_918_000 picoseconds. - Weight::from_parts(7_083_000, 0) + // Minimum execution time: 5_870_000 picoseconds. + Weight::from_parts(6_028_000, 0) .saturating_add(Weight::from_parts(0, 36283)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `MessageQueue::BookStateFor` (r:0 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:0 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`) fn service_page_item() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 28_445_000 picoseconds. - Weight::from_parts(28_659_000, 0) + // Minimum execution time: 80_681_000 picoseconds. + Weight::from_parts(81_818_000, 0) .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: MessageQueue ServiceHead (r:1 w:1) - /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen) - /// Storage: MessageQueue BookStateFor (r:1 w:0) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: `MessageQueue::ServiceHead` (r:1 w:1) + /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(6), added: 501, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:0) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) fn bump_service_head() -> Weight { // Proof Size summary in bytes: - // Measured: `149` + // Measured: `220` // Estimated: `3520` - // Minimum execution time: 7_224_000 picoseconds. - Weight::from_parts(7_441_000, 0) + // Minimum execution time: 8_641_000 picoseconds. + Weight::from_parts(8_995_000, 0) .saturating_add(Weight::from_parts(0, 3520)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: MessageQueue BookStateFor (r:1 w:1) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) - /// Storage: MessageQueue Pages (r:1 w:1) - /// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen) - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) - /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:1 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) fn reap_page() -> Weight { // Proof Size summary in bytes: - // Measured: `33232` + // Measured: `32945` // Estimated: `36283` - // Minimum execution time: 45_211_000 picoseconds. - Weight::from_parts(45_505_000, 0) + // Minimum execution time: 38_473_000 picoseconds. + Weight::from_parts(39_831_000, 0) .saturating_add(Weight::from_parts(0, 36283)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: MessageQueue BookStateFor (r:1 w:1) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) - /// Storage: MessageQueue Pages (r:1 w:1) - /// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen) - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) - /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:1 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) fn execute_overweight_page_removed() -> Weight { // Proof Size summary in bytes: - // Measured: `33232` + // Measured: `32945` // Estimated: `36283` - // Minimum execution time: 52_346_000 picoseconds. - Weight::from_parts(52_745_000, 0) + // Minimum execution time: 48_717_000 picoseconds. + Weight::from_parts(49_724_000, 0) .saturating_add(Weight::from_parts(0, 36283)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: MessageQueue BookStateFor (r:1 w:1) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) - /// Storage: MessageQueue Pages (r:1 w:1) - /// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen) - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) - /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:1 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) fn execute_overweight_page_updated() -> Weight { // Proof Size summary in bytes: - // Measured: `33232` + // Measured: `32945` // Estimated: `36283` - // Minimum execution time: 72_567_000 picoseconds. - Weight::from_parts(73_300_000, 0) + // Minimum execution time: 72_718_000 picoseconds. + Weight::from_parts(74_081_000, 0) .saturating_add(Weight::from_parts(0, 36283)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(4)) } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_multisig.rs b/polkadot/runtime/rococo/src/weights/pallet_multisig.rs index a4f33fe198c..f1b81759ece 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_multisig.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_multisig.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_multisig` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=pallet_multisig // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/ +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -52,110 +55,110 @@ impl pallet_multisig::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 11_475_000 picoseconds. - Weight::from_parts(11_904_745, 0) + // Minimum execution time: 12_023_000 picoseconds. + Weight::from_parts(12_643_116, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 1 - .saturating_add(Weight::from_parts(492, 0).saturating_mul(z.into())) + // Standard Error: 3 + .saturating_add(Weight::from_parts(582, 0).saturating_mul(z.into())) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_create(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `193 + s * (2 ±0)` + // Measured: `229 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 38_857_000 picoseconds. - Weight::from_parts(33_611_791, 0) + // Minimum execution time: 39_339_000 picoseconds. + Weight::from_parts(27_243_033, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 400 - .saturating_add(Weight::from_parts(59_263, 0).saturating_mul(s.into())) - // Standard Error: 3 - .saturating_add(Weight::from_parts(1_211, 0).saturating_mul(z.into())) + // Standard Error: 1_319 + .saturating_add(Weight::from_parts(142_212, 0).saturating_mul(s.into())) + // Standard Error: 12 + .saturating_add(Weight::from_parts(1_592, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[3, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_approve(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `211` + // Measured: `248` // Estimated: `6811` - // Minimum execution time: 25_715_000 picoseconds. - Weight::from_parts(20_607_294, 0) + // Minimum execution time: 27_647_000 picoseconds. + Weight::from_parts(15_828_725, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 285 - .saturating_add(Weight::from_parts(58_225, 0).saturating_mul(s.into())) - // Standard Error: 2 - .saturating_add(Weight::from_parts(1_160, 0).saturating_mul(z.into())) + // Standard Error: 908 + .saturating_add(Weight::from_parts(130_880, 0).saturating_mul(s.into())) + // Standard Error: 8 + .saturating_add(Weight::from_parts(1_532, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_complete(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `317 + s * (33 ±0)` + // Measured: `354 + s * (33 ±0)` // Estimated: `6811` - // Minimum execution time: 43_751_000 picoseconds. - Weight::from_parts(37_398_513, 0) + // Minimum execution time: 46_971_000 picoseconds. + Weight::from_parts(32_150_393, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 426 - .saturating_add(Weight::from_parts(70_904, 0).saturating_mul(s.into())) - // Standard Error: 4 - .saturating_add(Weight::from_parts(1_235, 0).saturating_mul(z.into())) + // Standard Error: 1_129 + .saturating_add(Weight::from_parts(154_796, 0).saturating_mul(s.into())) + // Standard Error: 11 + .saturating_add(Weight::from_parts(1_603, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. fn approve_as_multi_create(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `193 + s * (2 ±0)` + // Measured: `229 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 31_278_000 picoseconds. - Weight::from_parts(32_075_573, 0) + // Minimum execution time: 24_947_000 picoseconds. + Weight::from_parts(26_497_183, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 452 - .saturating_add(Weight::from_parts(62_018, 0).saturating_mul(s.into())) + // Standard Error: 1_615 + .saturating_add(Weight::from_parts(147_071, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. fn approve_as_multi_approve(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `211` + // Measured: `248` // Estimated: `6811` - // Minimum execution time: 18_178_000 picoseconds. - Weight::from_parts(18_649_867, 0) + // Minimum execution time: 13_897_000 picoseconds. + Weight::from_parts(14_828_339, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 293 - .saturating_add(Weight::from_parts(56_475, 0).saturating_mul(s.into())) + // Standard Error: 1_136 + .saturating_add(Weight::from_parts(133_925, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. fn cancel_as_multi(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `383 + s * (1 ±0)` + // Measured: `420 + s * (1 ±0)` // Estimated: `6811` - // Minimum execution time: 32_265_000 picoseconds. - Weight::from_parts(32_984_014, 0) + // Minimum execution time: 28_984_000 picoseconds. + Weight::from_parts(29_853_232, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 452 - .saturating_add(Weight::from_parts(59_934, 0).saturating_mul(s.into())) + // Standard Error: 650 + .saturating_add(Weight::from_parts(113_440, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/weights/pallet_nis.rs b/polkadot/runtime/rococo/src/weights/pallet_nis.rs index 35dad482129..38b41f3a8e2 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_nis.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_nis.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_nis` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=pallet_nis // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/ +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,202 +50,186 @@ use core::marker::PhantomData; /// Weight functions for `pallet_nis`. pub struct WeightInfo(PhantomData); impl pallet_nis::WeightInfo for WeightInfo { - /// Storage: Nis Queues (r:1 w:1) - /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) - /// Storage: Nis QueueTotals (r:1 w:1) - /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) + /// Storage: `Nis::Queues` (r:1 w:1) + /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) + /// Storage: `Nis::QueueTotals` (r:1 w:1) + /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) /// The range of component `l` is `[0, 999]`. fn place_bid(l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `6209 + l * (48 ±0)` // Estimated: `51487` - // Minimum execution time: 44_704_000 picoseconds. - Weight::from_parts(44_933_886, 0) + // Minimum execution time: 39_592_000 picoseconds. + Weight::from_parts(38_234_037, 0) .saturating_add(Weight::from_parts(0, 51487)) - // Standard Error: 712 - .saturating_add(Weight::from_parts(71_570, 0).saturating_mul(l.into())) + // Standard Error: 1_237 + .saturating_add(Weight::from_parts(88_816, 0).saturating_mul(l.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: Nis Queues (r:1 w:1) - /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) - /// Storage: Nis QueueTotals (r:1 w:1) - /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) + /// Storage: `Nis::Queues` (r:1 w:1) + /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) + /// Storage: `Nis::QueueTotals` (r:1 w:1) + /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) fn place_bid_max() -> Weight { // Proof Size summary in bytes: // Measured: `54211` // Estimated: `51487` - // Minimum execution time: 126_544_000 picoseconds. - Weight::from_parts(128_271_000, 0) + // Minimum execution time: 134_847_000 picoseconds. + Weight::from_parts(139_510_000, 0) .saturating_add(Weight::from_parts(0, 51487)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: Nis Queues (r:1 w:1) - /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) - /// Storage: Nis QueueTotals (r:1 w:1) - /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) + /// Storage: `Nis::Queues` (r:1 w:1) + /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) + /// Storage: `Nis::QueueTotals` (r:1 w:1) + /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) /// The range of component `l` is `[1, 1000]`. fn retract_bid(l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `6209 + l * (48 ±0)` // Estimated: `51487` - // Minimum execution time: 47_640_000 picoseconds. - Weight::from_parts(42_214_261, 0) + // Minimum execution time: 43_330_000 picoseconds. + Weight::from_parts(35_097_881, 0) .saturating_add(Weight::from_parts(0, 51487)) - // Standard Error: 732 - .saturating_add(Weight::from_parts(87_277, 0).saturating_mul(l.into())) + // Standard Error: 1_119 + .saturating_add(Weight::from_parts(73_640, 0).saturating_mul(l.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: Nis Summary (r:1 w:0) - /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) - /// Storage: Balances InactiveIssuance (r:1 w:0) - /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Nis::Summary` (r:1 w:0) + /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn fund_deficit() -> Weight { // Proof Size summary in bytes: // Measured: `225` // Estimated: `3593` - // Minimum execution time: 38_031_000 picoseconds. - Weight::from_parts(38_441_000, 0) + // Minimum execution time: 29_989_000 picoseconds. + Weight::from_parts(30_865_000, 0) .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Nis Receipts (r:1 w:1) - /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Nis Summary (r:1 w:1) - /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) - /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1) - /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: NisCounterpartBalances Account (r:1 w:1) - /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: `Nis::Receipts` (r:1 w:1) + /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Nis::Summary` (r:1 w:1) + /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) + /// Storage: `NisCounterpartBalances::Account` (r:1 w:1) + /// Proof: `NisCounterpartBalances::Account` (`max_values`: None, `max_size`: Some(112), added: 2587, mode: `MaxEncodedLen`) fn communify() -> Weight { // Proof Size summary in bytes: - // Measured: `469` + // Measured: `387` // Estimated: `3593` - // Minimum execution time: 69_269_000 picoseconds. - Weight::from_parts(70_000_000, 0) + // Minimum execution time: 58_114_000 picoseconds. + Weight::from_parts(59_540_000, 0) .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(6)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(5)) } - /// Storage: Nis Receipts (r:1 w:1) - /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) - /// Storage: Nis Summary (r:1 w:1) - /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) - /// Storage: Balances InactiveIssuance (r:1 w:0) - /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: NisCounterpartBalances Account (r:1 w:1) - /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) - /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1) - /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) + /// Storage: `Nis::Receipts` (r:1 w:1) + /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Storage: `Nis::Summary` (r:1 w:1) + /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `NisCounterpartBalances::Account` (r:1 w:1) + /// Proof: `NisCounterpartBalances::Account` (`max_values`: None, `max_size`: Some(112), added: 2587, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) fn privatize() -> Weight { // Proof Size summary in bytes: - // Measured: `659` + // Measured: `543` // Estimated: `3593` - // Minimum execution time: 85_763_000 picoseconds. - Weight::from_parts(86_707_000, 0) + // Minimum execution time: 75_780_000 picoseconds. + Weight::from_parts(77_097_000, 0) .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(7)) - .saturating_add(T::DbWeight::get().writes(6)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(5)) } - /// Storage: Nis Receipts (r:1 w:1) - /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) - /// Storage: Nis Summary (r:1 w:1) - /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) - /// Storage: Balances InactiveIssuance (r:1 w:0) - /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:0) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) + /// Storage: `Nis::Receipts` (r:1 w:1) + /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Storage: `Nis::Summary` (r:1 w:1) + /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:0) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) fn thaw_private() -> Weight { // Proof Size summary in bytes: // Measured: `387` // Estimated: `3593` - // Minimum execution time: 47_336_000 picoseconds. - Weight::from_parts(47_623_000, 0) + // Minimum execution time: 46_133_000 picoseconds. + Weight::from_parts(47_250_000, 0) .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: Nis Receipts (r:1 w:1) - /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) - /// Storage: Nis Summary (r:1 w:1) - /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) - /// Storage: NisCounterpartBalances Account (r:1 w:1) - /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) - /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1) - /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: Balances InactiveIssuance (r:1 w:0) - /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Nis::Receipts` (r:1 w:1) + /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Storage: `Nis::Summary` (r:1 w:1) + /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) + /// Storage: `NisCounterpartBalances::Account` (r:1 w:1) + /// Proof: `NisCounterpartBalances::Account` (`max_values`: None, `max_size`: Some(112), added: 2587, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn thaw_communal() -> Weight { // Proof Size summary in bytes: - // Measured: `604` + // Measured: `488` // Estimated: `3593` - // Minimum execution time: 90_972_000 picoseconds. - Weight::from_parts(92_074_000, 0) + // Minimum execution time: 77_916_000 picoseconds. + Weight::from_parts(79_427_000, 0) .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: Nis Summary (r:1 w:1) - /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) - /// Storage: Balances InactiveIssuance (r:1 w:0) - /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:0) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Nis QueueTotals (r:1 w:1) - /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) + /// Storage: `Nis::Summary` (r:1 w:1) + /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:0) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Nis::QueueTotals` (r:1 w:1) + /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) fn process_queues() -> Weight { // Proof Size summary in bytes: // Measured: `6658` // Estimated: `7487` - // Minimum execution time: 21_469_000 picoseconds. - Weight::from_parts(21_983_000, 0) + // Minimum execution time: 22_992_000 picoseconds. + Weight::from_parts(24_112_000, 0) .saturating_add(Weight::from_parts(0, 7487)) - .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Nis Queues (r:1 w:1) - /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + /// Storage: `Nis::Queues` (r:1 w:1) + /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) fn process_queue() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `51487` - // Minimum execution time: 4_912_000 picoseconds. - Weight::from_parts(5_013_000, 0) + // Minimum execution time: 3_856_000 picoseconds. + Weight::from_parts(4_125_000, 0) .saturating_add(Weight::from_parts(0, 51487)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Nis Receipts (r:0 w:1) - /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: `Nis::Receipts` (r:0 w:1) + /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) fn process_bid() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_048_000 picoseconds. - Weight::from_parts(7_278_000, 0) + // Minimum execution time: 4_344_000 picoseconds. + Weight::from_parts(4_545_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/weights/pallet_preimage.rs b/polkadot/runtime/rococo/src/weights/pallet_preimage.rs index e051ebd5bba..7a2b77b84d8 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_preimage.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_preimage.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_preimage` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=pallet_preimage // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/ +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,184 +50,219 @@ use core::marker::PhantomData; /// Weight functions for `pallet_preimage`. pub struct WeightInfo(PhantomData); impl pallet_preimage::WeightInfo for WeightInfo { - fn ensure_updated(n: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `193 + n * (91 ±0)` - // Estimated: `3593 + n * (2566 ±0)` - // Minimum execution time: 2_000_000 picoseconds. - Weight::from_parts(2_000_000, 3593) - // Standard Error: 13_720 - .saturating_add(Weight::from_parts(17_309_199, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) - .saturating_add(T::DbWeight::get().writes(1_u64)) - .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 2566).saturating_mul(n.into())) - } - - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) - /// Storage: Preimage PreimageFor (r:0 w:1) - /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) + /// Storage: `Preimage::PreimageFor` (r:0 w:1) + /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 4194304]`. fn note_preimage(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `215` - // Estimated: `3556` - // Minimum execution time: 31_040_000 picoseconds. - Weight::from_parts(31_236_000, 0) - .saturating_add(Weight::from_parts(0, 3556)) - // Standard Error: 1 - .saturating_add(Weight::from_parts(1_974, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `114` + // Estimated: `3568` + // Minimum execution time: 40_363_000 picoseconds. + Weight::from_parts(41_052_000, 0) + .saturating_add(Weight::from_parts(0, 3568)) + // Standard Error: 6 + .saturating_add(Weight::from_parts(2_298, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) - /// Storage: Preimage PreimageFor (r:0 w:1) - /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::PreimageFor` (r:0 w:1) + /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 4194304]`. fn note_requested_preimage(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `178` // Estimated: `3556` - // Minimum execution time: 18_025_000 picoseconds. - Weight::from_parts(18_264_000, 0) + // Minimum execution time: 14_570_000 picoseconds. + Weight::from_parts(14_890_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - // Standard Error: 1 - .saturating_add(Weight::from_parts(1_974, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(1)) + // Standard Error: 2 + .saturating_add(Weight::from_parts(2_364, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) - /// Storage: Preimage PreimageFor (r:0 w:1) - /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::PreimageFor` (r:0 w:1) + /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 4194304]`. fn note_no_deposit_preimage(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `178` // Estimated: `3556` - // Minimum execution time: 17_122_000 picoseconds. - Weight::from_parts(17_332_000, 0) + // Minimum execution time: 13_933_000 picoseconds. + Weight::from_parts(14_290_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - // Standard Error: 1 - .saturating_add(Weight::from_parts(1_968, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(1)) + // Standard Error: 2 + .saturating_add(Weight::from_parts(2_349, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) - /// Storage: Preimage PreimageFor (r:0 w:1) - /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) + /// Storage: `Preimage::PreimageFor` (r:0 w:1) + /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) fn unnote_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `361` - // Estimated: `3556` - // Minimum execution time: 38_218_000 picoseconds. - Weight::from_parts(39_841_000, 0) - .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `315` + // Estimated: `3568` + // Minimum execution time: 54_373_000 picoseconds. + Weight::from_parts(58_205_000, 0) + .saturating_add(Weight::from_parts(0, 3568)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) - /// Storage: Preimage PreimageFor (r:0 w:1) - /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::PreimageFor` (r:0 w:1) + /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) fn unnote_no_deposit_preimage() -> Weight { // Proof Size summary in bytes: // Measured: `216` // Estimated: `3556` - // Minimum execution time: 23_217_000 picoseconds. - Weight::from_parts(24_246_000, 0) + // Minimum execution time: 24_267_000 picoseconds. + Weight::from_parts(27_063_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn request_preimage() -> Weight { // Proof Size summary in bytes: // Measured: `260` // Estimated: `3556` - // Minimum execution time: 21_032_000 picoseconds. - Weight::from_parts(21_844_000, 0) + // Minimum execution time: 25_569_000 picoseconds. + Weight::from_parts(27_895_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn request_no_deposit_preimage() -> Weight { // Proof Size summary in bytes: // Measured: `216` // Estimated: `3556` - // Minimum execution time: 13_954_000 picoseconds. - Weight::from_parts(14_501_000, 0) + // Minimum execution time: 14_182_000 picoseconds. + Weight::from_parts(16_098_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn request_unnoted_preimage() -> Weight { // Proof Size summary in bytes: // Measured: `114` // Estimated: `3556` - // Minimum execution time: 14_874_000 picoseconds. - Weight::from_parts(15_380_000, 0) + // Minimum execution time: 14_681_000 picoseconds. + Weight::from_parts(15_549_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn request_requested_preimage() -> Weight { // Proof Size summary in bytes: // Measured: `178` // Estimated: `3556` - // Minimum execution time: 10_199_000 picoseconds. - Weight::from_parts(10_493_000, 0) + // Minimum execution time: 9_577_000 picoseconds. + Weight::from_parts(10_146_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) - /// Storage: Preimage PreimageFor (r:0 w:1) - /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::PreimageFor` (r:0 w:1) + /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) fn unrequest_preimage() -> Weight { // Proof Size summary in bytes: // Measured: `216` // Estimated: `3556` - // Minimum execution time: 21_772_000 picoseconds. - Weight::from_parts(22_554_000, 0) + // Minimum execution time: 21_003_000 picoseconds. + Weight::from_parts(23_549_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn unrequest_unnoted_preimage() -> Weight { // Proof Size summary in bytes: // Measured: `178` // Estimated: `3556` - // Minimum execution time: 10_115_000 picoseconds. - Weight::from_parts(10_452_000, 0) + // Minimum execution time: 9_507_000 picoseconds. + Weight::from_parts(10_013_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn unrequest_multi_referenced_preimage() -> Weight { // Proof Size summary in bytes: // Measured: `178` // Estimated: `3556` - // Minimum execution time: 10_031_000 picoseconds. - Weight::from_parts(10_310_000, 0) + // Minimum execution time: 9_293_000 picoseconds. + Weight::from_parts(10_055_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `Preimage::StatusFor` (r:1023 w:1023) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1023 w:1023) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1023 w:1023) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:0 w:1023) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// The range of component `n` is `[1, 1024]`. + fn ensure_updated(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + n * (227 ±0)` + // Estimated: `990 + n * (2603 ±0)` + // Minimum execution time: 48_846_000 picoseconds. + Weight::from_parts(49_378_000, 0) + .saturating_add(Weight::from_parts(0, 990)) + // Standard Error: 38_493 + .saturating_add(Weight::from_parts(47_418_285, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes((4_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2603).saturating_mul(n.into())) + } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_proxy.rs b/polkadot/runtime/rococo/src/weights/pallet_proxy.rs index d9737a85c05..c9202593095 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_proxy.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_proxy.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_proxy` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=pallet_proxy // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/ +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,172 +50,176 @@ use core::marker::PhantomData; /// Weight functions for `pallet_proxy`. pub struct WeightInfo(PhantomData); impl pallet_proxy::WeightInfo for WeightInfo { - /// Storage: Proxy Proxies (r:1 w:0) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:0) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) /// The range of component `p` is `[1, 31]`. fn proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `227 + p * (37 ±0)` + // Measured: `89 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 15_956_000 picoseconds. - Weight::from_parts(16_300_358, 0) + // Minimum execution time: 11_267_000 picoseconds. + Weight::from_parts(11_798_007, 0) .saturating_add(Weight::from_parts(0, 4706)) - // Standard Error: 652 - .saturating_add(Weight::from_parts(30_807, 0).saturating_mul(p.into())) + // Standard Error: 858 + .saturating_add(Weight::from_parts(43_735, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1)) } - /// Storage: Proxy Proxies (r:1 w:0) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) - /// Storage: Proxy Announcements (r:1 w:1) - /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:0) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: `Proxy::Announcements` (r:1 w:1) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn proxy_announced(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `554 + a * (68 ±0) + p * (37 ±0)` + // Measured: `416 + a * (68 ±0) + p * (37 ±0)` // Estimated: `5698` - // Minimum execution time: 37_584_000 picoseconds. - Weight::from_parts(37_858_207, 0) + // Minimum execution time: 32_791_000 picoseconds. + Weight::from_parts(32_776_904, 0) .saturating_add(Weight::from_parts(0, 5698)) - // Standard Error: 1_868 - .saturating_add(Weight::from_parts(148_967, 0).saturating_mul(a.into())) - // Standard Error: 1_930 - .saturating_add(Weight::from_parts(13_017, 0).saturating_mul(p.into())) + // Standard Error: 2_382 + .saturating_add(Weight::from_parts(143_857, 0).saturating_mul(a.into())) + // Standard Error: 2_461 + .saturating_add(Weight::from_parts(40_024, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Proxy Announcements (r:1 w:1) - /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Proxy::Announcements` (r:1 w:1) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. - fn remove_announcement(a: u32, _p: u32, ) -> Weight { + fn remove_announcement(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `469 + a * (68 ±0)` + // Measured: `331 + a * (68 ±0)` // Estimated: `5698` - // Minimum execution time: 24_642_000 picoseconds. - Weight::from_parts(25_526_588, 0) + // Minimum execution time: 21_831_000 picoseconds. + Weight::from_parts(22_479_938, 0) .saturating_add(Weight::from_parts(0, 5698)) - // Standard Error: 1_138 - .saturating_add(Weight::from_parts(131_157, 0).saturating_mul(a.into())) + // Standard Error: 1_738 + .saturating_add(Weight::from_parts(146_532, 0).saturating_mul(a.into())) + // Standard Error: 1_796 + .saturating_add(Weight::from_parts(7_499, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Proxy Announcements (r:1 w:1) - /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Proxy::Announcements` (r:1 w:1) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. - fn reject_announcement(a: u32, _p: u32, ) -> Weight { + fn reject_announcement(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `469 + a * (68 ±0)` + // Measured: `331 + a * (68 ±0)` // Estimated: `5698` - // Minimum execution time: 24_377_000 picoseconds. - Weight::from_parts(25_464_033, 0) + // Minimum execution time: 21_776_000 picoseconds. + Weight::from_parts(22_762_843, 0) .saturating_add(Weight::from_parts(0, 5698)) - // Standard Error: 1_116 - .saturating_add(Weight::from_parts(130_722, 0).saturating_mul(a.into())) + // Standard Error: 1_402 + .saturating_add(Weight::from_parts(137_512, 0).saturating_mul(a.into())) + // Standard Error: 1_449 + .saturating_add(Weight::from_parts(3_645, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Proxy Proxies (r:1 w:0) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) - /// Storage: Proxy Announcements (r:1 w:1) - /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:0) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: `Proxy::Announcements` (r:1 w:1) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn announce(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `486 + a * (68 ±0) + p * (37 ±0)` + // Measured: `348 + a * (68 ±0) + p * (37 ±0)` // Estimated: `5698` - // Minimum execution time: 34_202_000 picoseconds. - Weight::from_parts(34_610_079, 0) + // Minimum execution time: 29_108_000 picoseconds. + Weight::from_parts(29_508_910, 0) .saturating_add(Weight::from_parts(0, 5698)) - // Standard Error: 1_234 - .saturating_add(Weight::from_parts(134_197, 0).saturating_mul(a.into())) - // Standard Error: 1_275 - .saturating_add(Weight::from_parts(15_970, 0).saturating_mul(p.into())) + // Standard Error: 2_268 + .saturating_add(Weight::from_parts(144_770, 0).saturating_mul(a.into())) + // Standard Error: 2_343 + .saturating_add(Weight::from_parts(25_851, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Proxy Proxies (r:1 w:1) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:1) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) /// The range of component `p` is `[1, 31]`. fn add_proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `227 + p * (37 ±0)` + // Measured: `89 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 25_492_000 picoseconds. - Weight::from_parts(25_984_867, 0) + // Minimum execution time: 18_942_000 picoseconds. + Weight::from_parts(19_518_812, 0) .saturating_add(Weight::from_parts(0, 4706)) - // Standard Error: 893 - .saturating_add(Weight::from_parts(51_868, 0).saturating_mul(p.into())) + // Standard Error: 1_078 + .saturating_add(Weight::from_parts(46_147, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Proxy Proxies (r:1 w:1) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:1) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) /// The range of component `p` is `[1, 31]`. fn remove_proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `227 + p * (37 ±0)` + // Measured: `89 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 25_492_000 picoseconds. - Weight::from_parts(26_283_445, 0) + // Minimum execution time: 18_993_000 picoseconds. + Weight::from_parts(19_871_741, 0) .saturating_add(Weight::from_parts(0, 4706)) - // Standard Error: 1_442 - .saturating_add(Weight::from_parts(53_504, 0).saturating_mul(p.into())) + // Standard Error: 1_883 + .saturating_add(Weight::from_parts(46_033, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Proxy Proxies (r:1 w:1) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:1) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) /// The range of component `p` is `[1, 31]`. fn remove_proxies(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `227 + p * (37 ±0)` + // Measured: `89 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 22_083_000 picoseconds. - Weight::from_parts(22_688_835, 0) + // Minimum execution time: 17_849_000 picoseconds. + Weight::from_parts(18_776_170, 0) .saturating_add(Weight::from_parts(0, 4706)) - // Standard Error: 994 - .saturating_add(Weight::from_parts(32_994, 0).saturating_mul(p.into())) + // Standard Error: 1_239 + .saturating_add(Weight::from_parts(27_960, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Proxy Proxies (r:1 w:1) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:1) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) /// The range of component `p` is `[1, 31]`. fn create_pure(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `239` + // Measured: `101` // Estimated: `4706` - // Minimum execution time: 27_042_000 picoseconds. - Weight::from_parts(27_624_587, 0) + // Minimum execution time: 20_049_000 picoseconds. + Weight::from_parts(20_881_515, 0) .saturating_add(Weight::from_parts(0, 4706)) - // Standard Error: 671 - .saturating_add(Weight::from_parts(5_888, 0).saturating_mul(p.into())) + // Standard Error: 952 + .saturating_add(Weight::from_parts(5_970, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Proxy Proxies (r:1 w:1) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:1) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) /// The range of component `p` is `[0, 30]`. fn kill_pure(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `264 + p * (37 ±0)` + // Measured: `126 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 23_396_000 picoseconds. - Weight::from_parts(24_003_080, 0) + // Minimum execution time: 18_528_000 picoseconds. + Weight::from_parts(19_384_189, 0) .saturating_add(Weight::from_parts(0, 4706)) - // Standard Error: 684 - .saturating_add(Weight::from_parts(29_878, 0).saturating_mul(p.into())) + // Standard Error: 1_106 + .saturating_add(Weight::from_parts(35_698, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/weights/pallet_ranked_collective.rs b/polkadot/runtime/rococo/src/weights/pallet_ranked_collective.rs index ce9d5fcc0c7..fa2decb1671 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_ranked_collective.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_ranked_collective.rs @@ -16,24 +16,26 @@ //! Autogenerated weights for `pallet_ranked_collective` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-01-24, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-grjcggob-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/production/polkadot +// ./target/production/polkadot // benchmark // pallet +// --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_ranked_collective // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled -// --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_ranked_collective -// --chain=rococo-dev // --header=./polkadot/file_header.txt // --output=./polkadot/runtime/rococo/src/weights/ @@ -60,8 +62,8 @@ impl pallet_ranked_collective::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `42` // Estimated: `3507` - // Minimum execution time: 13_480_000 picoseconds. - Weight::from_parts(13_786_000, 0) + // Minimum execution time: 13_428_000 picoseconds. + Weight::from_parts(14_019_000, 0) .saturating_add(Weight::from_parts(0, 3507)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(4)) @@ -79,11 +81,11 @@ impl pallet_ranked_collective::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `516 + r * (281 ±0)` // Estimated: `3519 + r * (2529 ±0)` - // Minimum execution time: 28_771_000 picoseconds. - Weight::from_parts(29_256_825, 0) + // Minimum execution time: 28_566_000 picoseconds. + Weight::from_parts(29_346_952, 0) .saturating_add(Weight::from_parts(0, 3519)) - // Standard Error: 21_594 - .saturating_add(Weight::from_parts(14_649_527, 0).saturating_mul(r.into())) + // Standard Error: 21_068 + .saturating_add(Weight::from_parts(14_471_237, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(6)) @@ -103,11 +105,11 @@ impl pallet_ranked_collective::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `214 + r * (17 ±0)` // Estimated: `3507` - // Minimum execution time: 16_117_000 picoseconds. - Weight::from_parts(16_978_453, 0) + // Minimum execution time: 16_161_000 picoseconds. + Weight::from_parts(16_981_334, 0) .saturating_add(Weight::from_parts(0, 3507)) - // Standard Error: 4_511 - .saturating_add(Weight::from_parts(324_261, 0).saturating_mul(r.into())) + // Standard Error: 4_596 + .saturating_add(Weight::from_parts(313_386, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -124,11 +126,11 @@ impl pallet_ranked_collective::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `532 + r * (72 ±0)` // Estimated: `3519` - // Minimum execution time: 28_995_000 picoseconds. - Weight::from_parts(31_343_215, 0) + // Minimum execution time: 28_406_000 picoseconds. + Weight::from_parts(31_178_557, 0) .saturating_add(Weight::from_parts(0, 3519)) - // Standard Error: 16_438 - .saturating_add(Weight::from_parts(637_462, 0).saturating_mul(r.into())) + // Standard Error: 17_737 + .saturating_add(Weight::from_parts(627_757, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(6)) } @@ -140,15 +142,17 @@ impl pallet_ranked_collective::WeightInfo for WeightInf /// Proof: `FellowshipCollective::Voting` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn vote() -> Weight { // Proof Size summary in bytes: // Measured: `603` // Estimated: `83866` - // Minimum execution time: 38_820_000 picoseconds. - Weight::from_parts(40_240_000, 0) + // Minimum execution time: 41_164_000 picoseconds. + Weight::from_parts(42_163_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(5)) } /// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:0) /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) @@ -161,11 +165,11 @@ impl pallet_ranked_collective::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `400 + n * (50 ±0)` // Estimated: `4365 + n * (2540 ±0)` - // Minimum execution time: 12_972_000 picoseconds. - Weight::from_parts(15_829_333, 0) + // Minimum execution time: 13_183_000 picoseconds. + Weight::from_parts(15_604_064, 0) .saturating_add(Weight::from_parts(0, 4365)) - // Standard Error: 1_754 - .saturating_add(Weight::from_parts(1_116_520, 0).saturating_mul(n.into())) + // Standard Error: 2_018 + .saturating_add(Weight::from_parts(1_101_088, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) @@ -183,8 +187,8 @@ impl pallet_ranked_collective::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `337` // Estimated: `6048` - // Minimum execution time: 44_601_000 picoseconds. - Weight::from_parts(45_714_000, 0) + // Minimum execution time: 43_603_000 picoseconds. + Weight::from_parts(44_809_000, 0) .saturating_add(Weight::from_parts(0, 6048)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(10)) diff --git a/polkadot/runtime/rococo/src/weights/pallet_recovery.rs b/polkadot/runtime/rococo/src/weights/pallet_recovery.rs new file mode 100644 index 00000000000..ed79aa2b1f1 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_recovery.rs @@ -0,0 +1,186 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Autogenerated weights for `pallet_recovery` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_recovery +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_recovery`. +pub struct WeightInfo(PhantomData); +impl pallet_recovery::WeightInfo for WeightInfo { + /// Storage: `Recovery::Proxy` (r:1 w:0) + /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + fn as_recovered() -> Weight { + // Proof Size summary in bytes: + // Measured: `215` + // Estimated: `3545` + // Minimum execution time: 7_899_000 picoseconds. + Weight::from_parts(8_205_000, 0) + .saturating_add(Weight::from_parts(0, 3545)) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: `Recovery::Proxy` (r:0 w:1) + /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + fn set_recovered() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_258_000 picoseconds. + Weight::from_parts(6_494_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Recovery::Recoverable` (r:1 w:1) + /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) + /// The range of component `n` is `[1, 9]`. + fn create_recovery(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `109` + // Estimated: `3816` + // Minimum execution time: 19_369_000 picoseconds. + Weight::from_parts(20_185_132, 0) + .saturating_add(Weight::from_parts(0, 3816)) + // Standard Error: 4_275 + .saturating_add(Weight::from_parts(78_024, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Recovery::Recoverable` (r:1 w:0) + /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) + /// Storage: `Recovery::ActiveRecoveries` (r:1 w:1) + /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) + fn initiate_recovery() -> Weight { + // Proof Size summary in bytes: + // Measured: `206` + // Estimated: `3854` + // Minimum execution time: 22_425_000 picoseconds. + Weight::from_parts(23_171_000, 0) + .saturating_add(Weight::from_parts(0, 3854)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Recovery::Recoverable` (r:1 w:0) + /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) + /// Storage: `Recovery::ActiveRecoveries` (r:1 w:1) + /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) + /// The range of component `n` is `[1, 9]`. + fn vouch_recovery(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `294 + n * (64 ±0)` + // Estimated: `3854` + // Minimum execution time: 17_308_000 picoseconds. + Weight::from_parts(18_118_782, 0) + .saturating_add(Weight::from_parts(0, 3854)) + // Standard Error: 4_309 + .saturating_add(Weight::from_parts(126_278, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Recovery::Recoverable` (r:1 w:0) + /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) + /// Storage: `Recovery::ActiveRecoveries` (r:1 w:0) + /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) + /// Storage: `Recovery::Proxy` (r:1 w:1) + /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + /// The range of component `n` is `[1, 9]`. + fn claim_recovery(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `326 + n * (64 ±0)` + // Estimated: `3854` + // Minimum execution time: 20_755_000 picoseconds. + Weight::from_parts(21_821_713, 0) + .saturating_add(Weight::from_parts(0, 3854)) + // Standard Error: 4_550 + .saturating_add(Weight::from_parts(101_916, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Recovery::ActiveRecoveries` (r:1 w:1) + /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `n` is `[1, 9]`. + fn close_recovery(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `447 + n * (32 ±0)` + // Estimated: `3854` + // Minimum execution time: 29_957_000 picoseconds. + Weight::from_parts(31_010_309, 0) + .saturating_add(Weight::from_parts(0, 3854)) + // Standard Error: 5_913 + .saturating_add(Weight::from_parts(110_070, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `Recovery::ActiveRecoveries` (r:1 w:0) + /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) + /// Storage: `Recovery::Recoverable` (r:1 w:1) + /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) + /// The range of component `n` is `[1, 9]`. + fn remove_recovery(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `204 + n * (32 ±0)` + // Estimated: `3854` + // Minimum execution time: 24_430_000 picoseconds. + Weight::from_parts(24_462_856, 0) + .saturating_add(Weight::from_parts(0, 3854)) + // Standard Error: 13_646 + .saturating_add(Weight::from_parts(507_715, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Recovery::Proxy` (r:1 w:1) + /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + fn cancel_recovered() -> Weight { + // Proof Size summary in bytes: + // Measured: `215` + // Estimated: `3545` + // Minimum execution time: 9_686_000 picoseconds. + Weight::from_parts(10_071_000, 0) + .saturating_add(Weight::from_parts(0, 3545)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_referenda_fellowship_referenda.rs b/polkadot/runtime/rococo/src/weights/pallet_referenda_fellowship_referenda.rs index 96f172230e1..6dfcea2b832 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_referenda_fellowship_referenda.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_referenda_fellowship_referenda.rs @@ -16,27 +16,28 @@ //! Autogenerated weights for `pallet_referenda` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-07-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-xerhrdyb-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: `Some(Wasm)`, WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/production/polkadot +// ./target/production/polkadot // benchmark // pallet +// --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_referenda // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json -// --pallet=pallet_referenda -// --chain=rococo-dev -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/ +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -59,10 +60,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) fn submit() -> Weight { // Proof Size summary in bytes: - // Measured: `327` + // Measured: `292` // Estimated: `42428` - // Minimum execution time: 29_909_000 picoseconds. - Weight::from_parts(30_645_000, 0) + // Minimum execution time: 24_053_000 picoseconds. + Weight::from_parts(25_121_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) @@ -71,15 +72,17 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_preparing() -> Weight { // Proof Size summary in bytes: - // Measured: `438` + // Measured: `403` // Estimated: `83866` - // Minimum execution time: 54_405_000 picoseconds. - Weight::from_parts(55_583_000, 0) + // Minimum execution time: 45_064_000 picoseconds. + Weight::from_parts(46_112_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) @@ -89,15 +92,17 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `2076` + // Measured: `2041` // Estimated: `42428` - // Minimum execution time: 110_477_000 picoseconds. - Weight::from_parts(119_187_000, 0) + // Minimum execution time: 94_146_000 picoseconds. + Weight::from_parts(98_587_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) @@ -107,15 +112,17 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_not_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `2117` + // Measured: `2082` // Estimated: `42428` - // Minimum execution time: 111_467_000 picoseconds. - Weight::from_parts(117_758_000, 0) + // Minimum execution time: 93_002_000 picoseconds. + Weight::from_parts(96_924_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) @@ -125,15 +132,17 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `774` + // Measured: `739` // Estimated: `83866` - // Minimum execution time: 191_135_000 picoseconds. - Weight::from_parts(210_535_000, 0) + // Minimum execution time: 160_918_000 picoseconds. + Weight::from_parts(175_603_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(5)) } /// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) @@ -143,24 +152,26 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `639` + // Measured: `604` // Estimated: `83866` - // Minimum execution time: 67_168_000 picoseconds. - Weight::from_parts(68_895_000, 0) + // Minimum execution time: 55_253_000 picoseconds. + Weight::from_parts(56_488_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(5)) } /// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) fn refund_decision_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `351` + // Measured: `317` // Estimated: `4365` - // Minimum execution time: 31_298_000 picoseconds. - Weight::from_parts(32_570_000, 0) + // Minimum execution time: 24_497_000 picoseconds. + Weight::from_parts(25_280_000, 0) .saturating_add(Weight::from_parts(0, 4365)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -169,10 +180,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) fn refund_submission_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `201` + // Measured: `167` // Estimated: `4365` - // Minimum execution time: 15_674_000 picoseconds. - Weight::from_parts(16_190_000, 0) + // Minimum execution time: 11_374_000 picoseconds. + Weight::from_parts(11_817_000, 0) .saturating_add(Weight::from_parts(0, 4365)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -181,15 +192,17 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn cancel() -> Weight { // Proof Size summary in bytes: - // Measured: `383` + // Measured: `348` // Estimated: `83866` - // Minimum execution time: 38_927_000 picoseconds. - Weight::from_parts(40_545_000, 0) + // Minimum execution time: 31_805_000 picoseconds. + Weight::from_parts(32_622_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) @@ -197,15 +210,17 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) /// Storage: `FellowshipReferenda::MetadataOf` (r:1 w:0) /// Proof: `FellowshipReferenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn kill() -> Weight { // Proof Size summary in bytes: - // Measured: `484` + // Measured: `449` // Estimated: `83866` - // Minimum execution time: 80_209_000 picoseconds. - Weight::from_parts(82_084_000, 0) + // Minimum execution time: 62_364_000 picoseconds. + Weight::from_parts(63_798_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `FellowshipReferenda::TrackQueue` (r:1 w:0) /// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`) @@ -213,10 +228,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) fn one_fewer_deciding_queue_empty() -> Weight { // Proof Size summary in bytes: - // Measured: `174` + // Measured: `140` // Estimated: `4277` - // Minimum execution time: 9_520_000 picoseconds. - Weight::from_parts(10_088_000, 0) + // Minimum execution time: 8_811_000 picoseconds. + Weight::from_parts(9_224_000, 0) .saturating_add(Weight::from_parts(0, 4277)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -231,10 +246,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn one_fewer_deciding_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `2376` + // Measured: `2341` // Estimated: `42428` - // Minimum execution time: 93_893_000 picoseconds. - Weight::from_parts(101_065_000, 0) + // Minimum execution time: 83_292_000 picoseconds. + Weight::from_parts(89_114_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) @@ -249,10 +264,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn one_fewer_deciding_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `2362` + // Measured: `2327` // Estimated: `42428` - // Minimum execution time: 98_811_000 picoseconds. - Weight::from_parts(103_590_000, 0) + // Minimum execution time: 84_648_000 picoseconds. + Weight::from_parts(89_332_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) @@ -263,10 +278,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`) fn nudge_referendum_requeued_insertion() -> Weight { // Proof Size summary in bytes: - // Measured: `1841` + // Measured: `1807` // Estimated: `4365` - // Minimum execution time: 43_230_000 picoseconds. - Weight::from_parts(46_120_000, 0) + // Minimum execution time: 40_529_000 picoseconds. + Weight::from_parts(45_217_000, 0) .saturating_add(Weight::from_parts(0, 4365)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -277,10 +292,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`) fn nudge_referendum_requeued_slide() -> Weight { // Proof Size summary in bytes: - // Measured: `1808` + // Measured: `1774` // Estimated: `4365` - // Minimum execution time: 43_092_000 picoseconds. - Weight::from_parts(46_018_000, 0) + // Minimum execution time: 40_894_000 picoseconds. + Weight::from_parts(45_726_000, 0) .saturating_add(Weight::from_parts(0, 4365)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -293,10 +308,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`) fn nudge_referendum_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `1824` + // Measured: `1790` // Estimated: `4365` - // Minimum execution time: 49_697_000 picoseconds. - Weight::from_parts(53_795_000, 0) + // Minimum execution time: 48_187_000 picoseconds. + Weight::from_parts(52_655_000, 0) .saturating_add(Weight::from_parts(0, 4365)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -309,10 +324,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`) fn nudge_referendum_not_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `1865` + // Measured: `1831` // Estimated: `4365` - // Minimum execution time: 50_417_000 picoseconds. - Weight::from_parts(53_214_000, 0) + // Minimum execution time: 47_548_000 picoseconds. + Weight::from_parts(51_547_000, 0) .saturating_add(Weight::from_parts(0, 4365)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -323,10 +338,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_no_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `335` + // Measured: `300` // Estimated: `42428` - // Minimum execution time: 25_688_000 picoseconds. - Weight::from_parts(26_575_000, 0) + // Minimum execution time: 20_959_000 picoseconds. + Weight::from_parts(21_837_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -337,10 +352,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_preparing() -> Weight { // Proof Size summary in bytes: - // Measured: `383` + // Measured: `348` // Estimated: `42428` - // Minimum execution time: 26_230_000 picoseconds. - Weight::from_parts(27_235_000, 0) + // Minimum execution time: 21_628_000 picoseconds. + Weight::from_parts(22_192_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -349,10 +364,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) fn nudge_referendum_timed_out() -> Weight { // Proof Size summary in bytes: - // Measured: `242` + // Measured: `208` // Estimated: `4365` - // Minimum execution time: 17_585_000 picoseconds. - Weight::from_parts(18_225_000, 0) + // Minimum execution time: 12_309_000 picoseconds. + Weight::from_parts(12_644_000, 0) .saturating_add(Weight::from_parts(0, 4365)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -367,10 +382,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_begin_deciding_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `584` + // Measured: `549` // Estimated: `42428` - // Minimum execution time: 38_243_000 picoseconds. - Weight::from_parts(39_959_000, 0) + // Minimum execution time: 31_871_000 picoseconds. + Weight::from_parts(33_123_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) @@ -385,10 +400,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_begin_deciding_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `719` + // Measured: `684` // Estimated: `42428` - // Minimum execution time: 88_424_000 picoseconds. - Weight::from_parts(92_969_000, 0) + // Minimum execution time: 73_715_000 picoseconds. + Weight::from_parts(79_980_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) @@ -401,10 +416,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_begin_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `770` + // Measured: `735` // Estimated: `42428` - // Minimum execution time: 138_207_000 picoseconds. - Weight::from_parts(151_726_000, 0) + // Minimum execution time: 128_564_000 picoseconds. + Weight::from_parts(138_536_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -417,10 +432,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_end_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `755` + // Measured: `720` // Estimated: `42428` - // Minimum execution time: 131_001_000 picoseconds. - Weight::from_parts(148_651_000, 0) + // Minimum execution time: 129_775_000 picoseconds. + Weight::from_parts(139_001_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -433,10 +448,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_continue_not_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `770` + // Measured: `735` // Estimated: `42428` - // Minimum execution time: 109_612_000 picoseconds. - Weight::from_parts(143_626_000, 0) + // Minimum execution time: 128_233_000 picoseconds. + Weight::from_parts(135_796_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -449,10 +464,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_continue_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `776` + // Measured: `741` // Estimated: `42428` - // Minimum execution time: 71_754_000 picoseconds. - Weight::from_parts(77_329_000, 0) + // Minimum execution time: 66_995_000 picoseconds. + Weight::from_parts(72_678_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -467,10 +482,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) fn nudge_referendum_approved() -> Weight { // Proof Size summary in bytes: - // Measured: `776` + // Measured: `741` // Estimated: `83866` - // Minimum execution time: 153_244_000 picoseconds. - Weight::from_parts(169_961_000, 0) + // Minimum execution time: 137_764_000 picoseconds. + Weight::from_parts(152_260_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) @@ -483,10 +498,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_rejected() -> Weight { // Proof Size summary in bytes: - // Measured: `772` + // Measured: `737` // Estimated: `42428` - // Minimum execution time: 137_997_000 picoseconds. - Weight::from_parts(157_862_000, 0) + // Minimum execution time: 119_992_000 picoseconds. + Weight::from_parts(134_805_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -495,16 +510,18 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `FellowshipReferenda::MetadataOf` (r:0 w:1) /// Proof: `FellowshipReferenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn set_some_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `458` + // Measured: `424` // Estimated: `4365` - // Minimum execution time: 21_794_000 picoseconds. - Weight::from_parts(22_341_000, 0) + // Minimum execution time: 20_927_000 picoseconds. + Weight::from_parts(21_802_000, 0) .saturating_add(Weight::from_parts(0, 4365)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:0) @@ -513,10 +530,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn clear_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `319` + // Measured: `285` // Estimated: `4365` - // Minimum execution time: 18_458_000 picoseconds. - Weight::from_parts(19_097_000, 0) + // Minimum execution time: 14_253_000 picoseconds. + Weight::from_parts(15_031_000, 0) .saturating_add(Weight::from_parts(0, 4365)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/polkadot/runtime/rococo/src/weights/pallet_referenda_referenda.rs b/polkadot/runtime/rococo/src/weights/pallet_referenda_referenda.rs index b7cc5df28b9..c35925198f9 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_referenda_referenda.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_referenda_referenda.rs @@ -16,27 +16,28 @@ //! Autogenerated weights for `pallet_referenda` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-07-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-xerhrdyb-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: `Some(Wasm)`, WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/production/polkadot +// ./target/production/polkadot // benchmark // pallet +// --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_referenda // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json -// --pallet=pallet_referenda -// --chain=rococo-dev -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/ +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -57,10 +58,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) fn submit() -> Weight { // Proof Size summary in bytes: - // Measured: `324` + // Measured: `185` // Estimated: `42428` - // Minimum execution time: 39_852_000 picoseconds. - Weight::from_parts(41_610_000, 0) + // Minimum execution time: 28_612_000 picoseconds. + Weight::from_parts(30_060_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(3)) @@ -69,15 +70,17 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_preparing() -> Weight { // Proof Size summary in bytes: - // Measured: `577` + // Measured: `438` // Estimated: `83866` - // Minimum execution time: 52_588_000 picoseconds. - Weight::from_parts(54_154_000, 0) + // Minimum execution time: 42_827_000 picoseconds. + Weight::from_parts(44_072_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) @@ -87,15 +90,17 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3334` + // Measured: `3225` // Estimated: `42428` - // Minimum execution time: 70_483_000 picoseconds. - Weight::from_parts(72_731_000, 0) + // Minimum execution time: 56_475_000 picoseconds. + Weight::from_parts(58_888_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) @@ -105,60 +110,62 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_not_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3354` + // Measured: `3245` // Estimated: `42428` - // Minimum execution time: 68_099_000 picoseconds. - Weight::from_parts(71_560_000, 0) + // Minimum execution time: 56_542_000 picoseconds. + Weight::from_parts(58_616_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) /// Storage: `Referenda::DecidingCount` (r:1 w:1) /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Balances::InactiveIssuance` (r:1 w:0) - /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `577` + // Measured: `438` // Estimated: `83866` - // Minimum execution time: 64_357_000 picoseconds. - Weight::from_parts(66_081_000, 0) + // Minimum execution time: 51_218_000 picoseconds. + Weight::from_parts(53_148_000, 0) .saturating_add(Weight::from_parts(0, 83866)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(5)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) /// Storage: `Referenda::DecidingCount` (r:1 w:1) /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Balances::InactiveIssuance` (r:1 w:0) - /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `577` + // Measured: `438` // Estimated: `83866` - // Minimum execution time: 62_709_000 picoseconds. - Weight::from_parts(64_534_000, 0) + // Minimum execution time: 49_097_000 picoseconds. + Weight::from_parts(50_796_000, 0) .saturating_add(Weight::from_parts(0, 83866)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(5)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) fn refund_decision_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `417` + // Measured: `279` // Estimated: `4401` - // Minimum execution time: 31_296_000 picoseconds. - Weight::from_parts(32_221_000, 0) + // Minimum execution time: 23_720_000 picoseconds. + Weight::from_parts(24_327_000, 0) .saturating_add(Weight::from_parts(0, 4401)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -167,10 +174,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) fn refund_submission_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `407` + // Measured: `269` // Estimated: `4401` - // Minimum execution time: 31_209_000 picoseconds. - Weight::from_parts(32_168_000, 0) + // Minimum execution time: 24_089_000 picoseconds. + Weight::from_parts(24_556_000, 0) .saturating_add(Weight::from_parts(0, 4401)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -179,15 +186,17 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn cancel() -> Weight { // Proof Size summary in bytes: - // Measured: `485` + // Measured: `346` // Estimated: `83866` - // Minimum execution time: 38_887_000 picoseconds. - Weight::from_parts(40_193_000, 0) + // Minimum execution time: 29_022_000 picoseconds. + Weight::from_parts(29_590_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) @@ -195,15 +204,17 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) /// Storage: `Referenda::MetadataOf` (r:1 w:0) /// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn kill() -> Weight { // Proof Size summary in bytes: - // Measured: `726` + // Measured: `587` // Estimated: `83866` - // Minimum execution time: 106_054_000 picoseconds. - Weight::from_parts(108_318_000, 0) + // Minimum execution time: 81_920_000 picoseconds. + Weight::from_parts(84_492_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `Referenda::TrackQueue` (r:1 w:0) /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) @@ -211,10 +222,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) fn one_fewer_deciding_queue_empty() -> Weight { // Proof Size summary in bytes: - // Measured: `240` + // Measured: `102` // Estimated: `5477` - // Minimum execution time: 9_263_000 picoseconds. - Weight::from_parts(9_763_000, 0) + // Minimum execution time: 8_134_000 picoseconds. + Weight::from_parts(8_574_000, 0) .saturating_add(Weight::from_parts(0, 5477)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -223,36 +234,32 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) - /// Storage: `Balances::InactiveIssuance` (r:1 w:0) - /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn one_fewer_deciding_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `3254` + // Measured: `3115` // Estimated: `42428` - // Minimum execution time: 50_080_000 picoseconds. - Weight::from_parts(51_858_000, 0) + // Minimum execution time: 39_932_000 picoseconds. + Weight::from_parts(42_086_000, 0) .saturating_add(Weight::from_parts(0, 42428)) - .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Referenda::TrackQueue` (r:1 w:1) /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) - /// Storage: `Balances::InactiveIssuance` (r:1 w:0) - /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn one_fewer_deciding_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `3254` + // Measured: `3115` // Estimated: `42428` - // Minimum execution time: 53_889_000 picoseconds. - Weight::from_parts(55_959_000, 0) + // Minimum execution time: 42_727_000 picoseconds. + Weight::from_parts(44_280_000, 0) .saturating_add(Weight::from_parts(0, 42428)) - .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) @@ -261,10 +268,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) fn nudge_referendum_requeued_insertion() -> Weight { // Proof Size summary in bytes: - // Measured: `3077` + // Measured: `2939` // Estimated: `5477` - // Minimum execution time: 23_266_000 picoseconds. - Weight::from_parts(24_624_000, 0) + // Minimum execution time: 20_918_000 picoseconds. + Weight::from_parts(22_180_000, 0) .saturating_add(Weight::from_parts(0, 5477)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -275,10 +282,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) fn nudge_referendum_requeued_slide() -> Weight { // Proof Size summary in bytes: - // Measured: `3077` + // Measured: `2939` // Estimated: `5477` - // Minimum execution time: 22_846_000 picoseconds. - Weight::from_parts(24_793_000, 0) + // Minimum execution time: 20_943_000 picoseconds. + Weight::from_parts(21_932_000, 0) .saturating_add(Weight::from_parts(0, 5477)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -291,10 +298,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) fn nudge_referendum_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3081` + // Measured: `2943` // Estimated: `5477` - // Minimum execution time: 28_284_000 picoseconds. - Weight::from_parts(29_940_000, 0) + // Minimum execution time: 25_197_000 picoseconds. + Weight::from_parts(26_083_000, 0) .saturating_add(Weight::from_parts(0, 5477)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -307,10 +314,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) fn nudge_referendum_not_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3101` + // Measured: `2963` // Estimated: `5477` - // Minimum execution time: 28_133_000 picoseconds. - Weight::from_parts(29_638_000, 0) + // Minimum execution time: 24_969_000 picoseconds. + Weight::from_parts(26_096_000, 0) .saturating_add(Weight::from_parts(0, 5477)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -321,10 +328,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_no_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `437` + // Measured: `298` // Estimated: `42428` - // Minimum execution time: 25_710_000 picoseconds. - Weight::from_parts(26_500_000, 0) + // Minimum execution time: 18_050_000 picoseconds. + Weight::from_parts(18_790_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -335,10 +342,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_preparing() -> Weight { // Proof Size summary in bytes: - // Measured: `485` + // Measured: `346` // Estimated: `42428` - // Minimum execution time: 25_935_000 picoseconds. - Weight::from_parts(26_803_000, 0) + // Minimum execution time: 18_357_000 picoseconds. + Weight::from_parts(18_957_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -347,10 +354,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) fn nudge_referendum_timed_out() -> Weight { // Proof Size summary in bytes: - // Measured: `344` + // Measured: `206` // Estimated: `4401` - // Minimum execution time: 17_390_000 picoseconds. - Weight::from_parts(18_042_000, 0) + // Minimum execution time: 11_479_000 picoseconds. + Weight::from_parts(11_968_000, 0) .saturating_add(Weight::from_parts(0, 4401)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -359,150 +366,136 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) /// Storage: `Referenda::DecidingCount` (r:1 w:1) /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Balances::InactiveIssuance` (r:1 w:0) - /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_begin_deciding_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `485` + // Measured: `346` // Estimated: `42428` - // Minimum execution time: 35_141_000 picoseconds. - Weight::from_parts(36_318_000, 0) + // Minimum execution time: 24_471_000 picoseconds. + Weight::from_parts(25_440_000, 0) .saturating_add(Weight::from_parts(0, 42428)) - .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) /// Storage: `Referenda::DecidingCount` (r:1 w:1) /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Balances::InactiveIssuance` (r:1 w:0) - /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_begin_deciding_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `485` + // Measured: `346` // Estimated: `42428` - // Minimum execution time: 37_815_000 picoseconds. - Weight::from_parts(39_243_000, 0) + // Minimum execution time: 26_580_000 picoseconds. + Weight::from_parts(27_570_000, 0) .saturating_add(Weight::from_parts(0, 42428)) - .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) - /// Storage: `Balances::InactiveIssuance` (r:1 w:0) - /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_begin_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `538` + // Measured: `399` // Estimated: `42428` - // Minimum execution time: 30_779_000 picoseconds. - Weight::from_parts(31_845_000, 0) + // Minimum execution time: 24_331_000 picoseconds. + Weight::from_parts(25_291_000, 0) .saturating_add(Weight::from_parts(0, 42428)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) - /// Storage: `Balances::InactiveIssuance` (r:1 w:0) - /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_end_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `521` + // Measured: `382` // Estimated: `42428` - // Minimum execution time: 31_908_000 picoseconds. - Weight::from_parts(33_253_000, 0) + // Minimum execution time: 24_768_000 picoseconds. + Weight::from_parts(25_746_000, 0) .saturating_add(Weight::from_parts(0, 42428)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) - /// Storage: `Balances::InactiveIssuance` (r:1 w:0) - /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_continue_not_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `538` + // Measured: `399` // Estimated: `42428` - // Minimum execution time: 28_951_000 picoseconds. - Weight::from_parts(30_004_000, 0) + // Minimum execution time: 23_171_000 picoseconds. + Weight::from_parts(24_161_000, 0) .saturating_add(Weight::from_parts(0, 42428)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) - /// Storage: `Balances::InactiveIssuance` (r:1 w:0) - /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_continue_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `542` + // Measured: `403` // Estimated: `42428` - // Minimum execution time: 27_750_000 picoseconds. - Weight::from_parts(28_588_000, 0) + // Minimum execution time: 22_263_000 picoseconds. + Weight::from_parts(23_062_000, 0) .saturating_add(Weight::from_parts(0, 42428)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) - /// Storage: `Balances::InactiveIssuance` (r:1 w:0) - /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Lookup` (r:1 w:1) /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) fn nudge_referendum_approved() -> Weight { // Proof Size summary in bytes: - // Measured: `542` + // Measured: `403` // Estimated: `83866` - // Minimum execution time: 43_950_000 picoseconds. - Weight::from_parts(46_164_000, 0) + // Minimum execution time: 33_710_000 picoseconds. + Weight::from_parts(34_871_000, 0) .saturating_add(Weight::from_parts(0, 83866)) - .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) - /// Storage: `Balances::InactiveIssuance` (r:1 w:0) - /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_rejected() -> Weight { // Proof Size summary in bytes: - // Measured: `538` + // Measured: `399` // Estimated: `42428` - // Minimum execution time: 31_050_000 picoseconds. - Weight::from_parts(32_169_000, 0) + // Minimum execution time: 24_260_000 picoseconds. + Weight::from_parts(25_104_000, 0) .saturating_add(Weight::from_parts(0, 42428)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Referenda::MetadataOf` (r:0 w:1) /// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn set_some_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `560` + // Measured: `422` // Estimated: `4401` - // Minimum execution time: 21_193_000 picoseconds. - Weight::from_parts(22_116_000, 0) + // Minimum execution time: 19_821_000 picoseconds. + Weight::from_parts(20_641_000, 0) .saturating_add(Weight::from_parts(0, 4401)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) @@ -511,10 +504,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn clear_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `421` + // Measured: `283` // Estimated: `4401` - // Minimum execution time: 18_065_000 picoseconds. - Weight::from_parts(18_781_000, 0) + // Minimum execution time: 13_411_000 picoseconds. + Weight::from_parts(14_070_000, 0) .saturating_add(Weight::from_parts(0, 4401)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/polkadot/runtime/rococo/src/weights/pallet_scheduler.rs b/polkadot/runtime/rococo/src/weights/pallet_scheduler.rs index 0f36dbd384d..5f6b41d2b54 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_scheduler.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_scheduler.rs @@ -16,24 +16,26 @@ //! Autogenerated weights for `pallet_scheduler` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-01-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-grjcggob-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/production/polkadot +// ./target/production/polkadot // benchmark // pallet +// --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_scheduler // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled -// --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_scheduler -// --chain=rococo-dev // --header=./polkadot/file_header.txt // --output=./polkadot/runtime/rococo/src/weights/ @@ -54,8 +56,8 @@ impl pallet_scheduler::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `68` // Estimated: `1489` - // Minimum execution time: 2_869_000 picoseconds. - Weight::from_parts(3_109_000, 0) + // Minimum execution time: 3_114_000 picoseconds. + Weight::from_parts(3_245_000, 0) .saturating_add(Weight::from_parts(0, 1489)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -67,11 +69,11 @@ impl pallet_scheduler::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `115 + s * (177 ±0)` // Estimated: `42428` - // Minimum execution time: 3_326_000 picoseconds. - Weight::from_parts(5_818_563, 0) + // Minimum execution time: 3_430_000 picoseconds. + Weight::from_parts(6_250_920, 0) .saturating_add(Weight::from_parts(0, 42428)) - // Standard Error: 1_261 - .saturating_add(Weight::from_parts(336_446, 0).saturating_mul(s.into())) + // Standard Error: 1_350 + .saturating_add(Weight::from_parts(333_245, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -79,8 +81,8 @@ impl pallet_scheduler::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_007_000 picoseconds. - Weight::from_parts(3_197_000, 0) + // Minimum execution time: 3_166_000 picoseconds. + Weight::from_parts(3_295_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// Storage: `Preimage::PreimageFor` (r:1 w:1) @@ -94,11 +96,11 @@ impl pallet_scheduler::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `251 + s * (1 ±0)` // Estimated: `3716 + s * (1 ±0)` - // Minimum execution time: 16_590_000 picoseconds. - Weight::from_parts(16_869_000, 0) + // Minimum execution time: 17_072_000 picoseconds. + Weight::from_parts(17_393_000, 0) .saturating_add(Weight::from_parts(0, 3716)) - // Standard Error: 9 - .saturating_add(Weight::from_parts(1_308, 0).saturating_mul(s.into())) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_204, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(s.into())) @@ -109,8 +111,8 @@ impl pallet_scheduler::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_320_000 picoseconds. - Weight::from_parts(4_594_000, 0) + // Minimum execution time: 4_566_000 picoseconds. + Weight::from_parts(4_775_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -118,24 +120,24 @@ impl pallet_scheduler::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_956_000 picoseconds. - Weight::from_parts(3_216_000, 0) + // Minimum execution time: 3_180_000 picoseconds. + Weight::from_parts(3_339_000, 0) .saturating_add(Weight::from_parts(0, 0)) } fn execute_dispatch_signed() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_824_000 picoseconds. - Weight::from_parts(1_929_000, 0) + // Minimum execution time: 1_656_000 picoseconds. + Weight::from_parts(1_829_000, 0) .saturating_add(Weight::from_parts(0, 0)) } fn execute_dispatch_unsigned() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_749_000 picoseconds. - Weight::from_parts(1_916_000, 0) + // Minimum execution time: 1_628_000 picoseconds. + Weight::from_parts(1_840_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// Storage: `Scheduler::Agenda` (r:1 w:1) @@ -145,16 +147,18 @@ impl pallet_scheduler::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `115 + s * (177 ±0)` // Estimated: `42428` - // Minimum execution time: 9_086_000 picoseconds. - Weight::from_parts(11_733_696, 0) + // Minimum execution time: 9_523_000 picoseconds. + Weight::from_parts(12_482_434, 0) .saturating_add(Weight::from_parts(0, 42428)) - // Standard Error: 1_362 - .saturating_add(Weight::from_parts(375_266, 0).saturating_mul(s.into())) + // Standard Error: 1_663 + .saturating_add(Weight::from_parts(370_122, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Lookup` (r:0 w:1) /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 50]`. @@ -162,13 +166,13 @@ impl pallet_scheduler::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `115 + s * (177 ±0)` // Estimated: `42428` - // Minimum execution time: 12_716_000 picoseconds. - Weight::from_parts(12_529_180, 0) + // Minimum execution time: 14_649_000 picoseconds. + Weight::from_parts(14_705_132, 0) .saturating_add(Weight::from_parts(0, 42428)) - // Standard Error: 867 - .saturating_add(Weight::from_parts(548_188, 0).saturating_mul(s.into())) + // Standard Error: 1_126 + .saturating_add(Weight::from_parts(547_438, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Scheduler::Lookup` (r:1 w:1) /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) @@ -179,11 +183,11 @@ impl pallet_scheduler::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `292 + s * (185 ±0)` // Estimated: `42428` - // Minimum execution time: 12_053_000 picoseconds. - Weight::from_parts(15_358_056, 0) + // Minimum execution time: 12_335_000 picoseconds. + Weight::from_parts(16_144_217, 0) .saturating_add(Weight::from_parts(0, 42428)) - // Standard Error: 3_176 - .saturating_add(Weight::from_parts(421_589, 0).saturating_mul(s.into())) + // Standard Error: 3_533 + .saturating_add(Weight::from_parts(413_823, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -191,49 +195,48 @@ impl pallet_scheduler::WeightInfo for WeightInfo { /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 50]`. fn cancel_named(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `318 + s * (185 ±0)` // Estimated: `42428` - // Minimum execution time: 14_803_000 picoseconds. - Weight::from_parts(15_805_714, 0) + // Minimum execution time: 16_906_000 picoseconds. + Weight::from_parts(17_846_662, 0) .saturating_add(Weight::from_parts(0, 42428)) - // Standard Error: 2_597 - .saturating_add(Weight::from_parts(611_053, 0).saturating_mul(s.into())) + // Standard Error: 2_687 + .saturating_add(Weight::from_parts(613_356, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `Scheduler::Retries` (r:1 w:2) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Lookup` (r:0 w:1) - /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 50]`. fn schedule_retry(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `196` + // Measured: `155` // Estimated: `42428` - // Minimum execution time: 13_156_000 picoseconds. - Weight::from_parts(13_801_287, 0) + // Minimum execution time: 8_988_000 picoseconds. + Weight::from_parts(9_527_838, 0) .saturating_add(Weight::from_parts(0, 42428)) - // Standard Error: 568 - .saturating_add(Weight::from_parts(35_441, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(4)) + // Standard Error: 523 + .saturating_add(Weight::from_parts(25_453, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Scheduler::Agenda` (r:1 w:0) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Retries` (r:0 w:1) /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) - /// The range of component `s` is `[1, 50]`. fn set_retry() -> Weight { // Proof Size summary in bytes: - // Measured: `115 + s * (177 ±0)` + // Measured: `8965` // Estimated: `42428` - // Minimum execution time: 7_912_000 picoseconds. - Weight::from_parts(8_081_460, 0) + // Minimum execution time: 23_337_000 picoseconds. + Weight::from_parts(24_255_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -244,13 +247,12 @@ impl pallet_scheduler::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Retries` (r:0 w:1) /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) - /// The range of component `s` is `[1, 50]`. fn set_retry_named() -> Weight { // Proof Size summary in bytes: - // Measured: `324 + s * (185 ±0)` + // Measured: `9643` // Estimated: `42428` - // Minimum execution time: 10_673_000 picoseconds. - Weight::from_parts(12_212_185, 0) + // Minimum execution time: 30_704_000 picoseconds. + Weight::from_parts(31_646_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -259,13 +261,12 @@ impl pallet_scheduler::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Retries` (r:0 w:1) /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) - /// The range of component `s` is `[1, 50]`. fn cancel_retry() -> Weight { // Proof Size summary in bytes: - // Measured: `115 + s * (177 ±0)` + // Measured: `8977` // Estimated: `42428` - // Minimum execution time: 7_912_000 picoseconds. - Weight::from_parts(8_081_460, 0) + // Minimum execution time: 22_279_000 picoseconds. + Weight::from_parts(23_106_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -276,13 +277,12 @@ impl pallet_scheduler::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Retries` (r:0 w:1) /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) - /// The range of component `s` is `[1, 50]`. fn cancel_retry_named() -> Weight { // Proof Size summary in bytes: - // Measured: `324 + s * (185 ±0)` + // Measured: `9655` // Estimated: `42428` - // Minimum execution time: 10_673_000 picoseconds. - Weight::from_parts(12_212_185, 0) + // Minimum execution time: 29_649_000 picoseconds. + Weight::from_parts(30_472_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/polkadot/runtime/rococo/src/weights/pallet_sudo.rs b/polkadot/runtime/rococo/src/weights/pallet_sudo.rs index 694174954fc..ecc31dc3fa9 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_sudo.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_sudo.rs @@ -16,24 +16,26 @@ //! Autogenerated weights for `pallet_sudo` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/production/polkadot +// ./target/production/polkadot // benchmark // pallet +// --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_sudo // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled -// --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_sudo -// --chain=rococo-dev // --header=./polkadot/file_header.txt // --output=./polkadot/runtime/rococo/src/weights/ @@ -54,8 +56,8 @@ impl pallet_sudo::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `132` // Estimated: `1517` - // Minimum execution time: 8_432_000 picoseconds. - Weight::from_parts(8_757_000, 0) + // Minimum execution time: 8_336_000 picoseconds. + Weight::from_parts(8_569_000, 0) .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -66,8 +68,8 @@ impl pallet_sudo::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `132` // Estimated: `1517` - // Minimum execution time: 9_167_000 picoseconds. - Weight::from_parts(9_397_000, 0) + // Minimum execution time: 8_858_000 picoseconds. + Weight::from_parts(9_238_000, 0) .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) } @@ -77,8 +79,8 @@ impl pallet_sudo::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `132` // Estimated: `1517` - // Minimum execution time: 9_133_000 picoseconds. - Weight::from_parts(9_573_000, 0) + // Minimum execution time: 8_921_000 picoseconds. + Weight::from_parts(9_324_000, 0) .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) } @@ -88,10 +90,21 @@ impl pallet_sudo::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `132` // Estimated: `1517` - // Minimum execution time: 7_374_000 picoseconds. - Weight::from_parts(7_702_000, 0) + // Minimum execution time: 7_398_000 picoseconds. + Weight::from_parts(7_869_000, 0) .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `Sudo::Key` (r:1 w:0) + /// Proof: `Sudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + fn check_only_sudo_account() -> Weight { + // Proof Size summary in bytes: + // Measured: `132` + // Estimated: `1517` + // Minimum execution time: 3_146_000 picoseconds. + Weight::from_parts(3_314_000, 0) + .saturating_add(Weight::from_parts(0, 1517)) + .saturating_add(T::DbWeight::get().reads(1)) + } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_timestamp.rs b/polkadot/runtime/rococo/src/weights/pallet_timestamp.rs index 1bb2e227ab7..7d79621b9e6 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_timestamp.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_timestamp.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_timestamp` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=pallet_timestamp // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/ +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,26 +50,26 @@ use core::marker::PhantomData; /// Weight functions for `pallet_timestamp`. pub struct WeightInfo(PhantomData); impl pallet_timestamp::WeightInfo for WeightInfo { - /// Storage: Timestamp Now (r:1 w:1) - /// Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Babe CurrentSlot (r:1 w:0) - /// Proof: Babe CurrentSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: `Timestamp::Now` (r:1 w:1) + /// Proof: `Timestamp::Now` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Babe::CurrentSlot` (r:1 w:0) + /// Proof: `Babe::CurrentSlot` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) fn set() -> Weight { // Proof Size summary in bytes: - // Measured: `311` + // Measured: `137` // Estimated: `1493` - // Minimum execution time: 10_103_000 picoseconds. - Weight::from_parts(10_597_000, 0) + // Minimum execution time: 5_596_000 picoseconds. + Weight::from_parts(5_823_000, 0) .saturating_add(Weight::from_parts(0, 1493)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } fn on_finalize() -> Weight { // Proof Size summary in bytes: - // Measured: `94` + // Measured: `57` // Estimated: `0` - // Minimum execution time: 4_718_000 picoseconds. - Weight::from_parts(4_839_000, 0) + // Minimum execution time: 2_777_000 picoseconds. + Weight::from_parts(2_900_000, 0) .saturating_add(Weight::from_parts(0, 0)) } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_transaction_payment.rs b/polkadot/runtime/rococo/src/weights/pallet_transaction_payment.rs new file mode 100644 index 00000000000..44dfab289fb --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_transaction_payment.rs @@ -0,0 +1,68 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Autogenerated weights for `pallet_transaction_payment` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_transaction_payment +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_transaction_payment`. +pub struct WeightInfo(PhantomData); +impl pallet_transaction_payment::WeightInfo for WeightInfo { + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Authorship::Author` (r:1 w:0) + /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `System::Digest` (r:1 w:0) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn charge_transaction_payment() -> Weight { + // Proof Size summary in bytes: + // Measured: `252` + // Estimated: `1737` + // Minimum execution time: 33_070_000 picoseconds. + Weight::from_parts(33_730_000, 0) + .saturating_add(Weight::from_parts(0, 1737)) + .saturating_add(T::DbWeight::get().reads(3)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_treasury.rs b/polkadot/runtime/rococo/src/weights/pallet_treasury.rs index 144e9d5b872..acf09989afc 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_treasury.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_treasury.rs @@ -16,25 +16,28 @@ //! Autogenerated weights for `pallet_treasury` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-07-07, STEPS: `50`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `cob`, CPU: `` -//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/debug/polkadot +// ./target/production/polkadot // benchmark // pallet // --chain=rococo-dev // --steps=50 -// --repeat=2 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=pallet_treasury // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled -// --heap-pages=4096 -// --output=./runtime/rococo/src/weights/ -// --header=./file_header.txt +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,176 +50,168 @@ use core::marker::PhantomData; /// Weight functions for `pallet_treasury`. pub struct WeightInfo(PhantomData); impl pallet_treasury::WeightInfo for WeightInfo { - /// Storage: Treasury ProposalCount (r:1 w:1) - /// Proof: Treasury ProposalCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Treasury Approvals (r:1 w:1) - /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) - /// Storage: Treasury Proposals (r:0 w:1) - /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: `Treasury::ProposalCount` (r:1 w:1) + /// Proof: `Treasury::ProposalCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Approvals` (r:1 w:1) + /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Proposals` (r:0 w:1) + /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) fn spend_local() -> Weight { // Proof Size summary in bytes: - // Measured: `42` + // Measured: `142` // Estimated: `1887` - // Minimum execution time: 177_000_000 picoseconds. - Weight::from_parts(191_000_000, 0) + // Minimum execution time: 9_928_000 picoseconds. + Weight::from_parts(10_560_000, 0) .saturating_add(Weight::from_parts(0, 1887)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: Treasury ProposalCount (r:1 w:1) - /// Proof: Treasury ProposalCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Treasury Proposals (r:0 w:1) - /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: `Treasury::ProposalCount` (r:1 w:1) + /// Proof: `Treasury::ProposalCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Proposals` (r:0 w:1) + /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) fn propose_spend() -> Weight { // Proof Size summary in bytes: - // Measured: `143` + // Measured: `243` // Estimated: `1489` - // Minimum execution time: 354_000_000 picoseconds. - Weight::from_parts(376_000_000, 0) + // Minimum execution time: 20_714_000 picoseconds. + Weight::from_parts(21_137_000, 0) .saturating_add(Weight::from_parts(0, 1489)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Treasury Proposals (r:1 w:1) - /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Treasury::Proposals` (r:1 w:1) + /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn reject_proposal() -> Weight { // Proof Size summary in bytes: - // Measured: `301` + // Measured: `401` // Estimated: `3593` - // Minimum execution time: 547_000_000 picoseconds. - Weight::from_parts(550_000_000, 0) + // Minimum execution time: 31_665_000 picoseconds. + Weight::from_parts(32_442_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Treasury Proposals (r:1 w:0) - /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) - /// Storage: Treasury Approvals (r:1 w:1) - /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: `Treasury::Proposals` (r:1 w:0) + /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Approvals` (r:1 w:1) + /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) /// The range of component `p` is `[0, 99]`. fn approve_proposal(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `470 + p * (8 ±0)` + // Measured: `570 + p * (8 ±0)` // Estimated: `3573` - // Minimum execution time: 104_000_000 picoseconds. - Weight::from_parts(121_184_402, 0) + // Minimum execution time: 6_988_000 picoseconds. + Weight::from_parts(11_464_972, 0) .saturating_add(Weight::from_parts(0, 3573)) - // Standard Error: 42_854 - .saturating_add(Weight::from_parts(153_112, 0).saturating_mul(p.into())) + // Standard Error: 1_722 + .saturating_add(Weight::from_parts(84_536, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Treasury Approvals (r:1 w:1) - /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: `Treasury::Approvals` (r:1 w:1) + /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) fn remove_approval() -> Weight { // Proof Size summary in bytes: - // Measured: `127` + // Measured: `227` // Estimated: `1887` - // Minimum execution time: 80_000_000 picoseconds. - Weight::from_parts(82_000_000, 0) + // Minimum execution time: 5_386_000 picoseconds. + Weight::from_parts(5_585_000, 0) .saturating_add(Weight::from_parts(0, 1887)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Treasury Deactivated (r:1 w:1) - /// Proof: Treasury Deactivated (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: Balances InactiveIssuance (r:1 w:1) - /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: Treasury Approvals (r:1 w:1) - /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) - /// Storage: Treasury Proposals (r:99 w:99) - /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) - /// Storage: System Account (r:199 w:199) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Bounties BountyApprovals (r:1 w:1) - /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: `Treasury::Deactivated` (r:1 w:1) + /// Proof: `Treasury::Deactivated` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Approvals` (r:1 w:1) + /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Proposals` (r:99 w:99) + /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:199 w:199) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Bounties::BountyApprovals` (r:1 w:1) + /// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) /// The range of component `p` is `[0, 99]`. fn on_initialize_proposals(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `331 + p * (251 ±0)` + // Measured: `431 + p * (251 ±0)` // Estimated: `3593 + p * (5206 ±0)` - // Minimum execution time: 887_000_000 picoseconds. - Weight::from_parts(828_616_021, 0) + // Minimum execution time: 43_737_000 picoseconds. + Weight::from_parts(39_883_021, 0) .saturating_add(Weight::from_parts(0, 3593)) - // Standard Error: 695_351 - .saturating_add(Weight::from_parts(566_114_524, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(5)) + // Standard Error: 12_917 + .saturating_add(Weight::from_parts(31_796_205, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(p.into()))) - .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().writes(4)) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(p.into()))) .saturating_add(Weight::from_parts(0, 5206).saturating_mul(p.into())) } - /// Storage: AssetRate ConversionRateToNative (r:1 w:0) - /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(1237), added: 3712, mode: MaxEncodedLen) - /// Storage: Treasury SpendCount (r:1 w:1) - /// Proof: Treasury SpendCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Treasury Spends (r:0 w:1) - /// Proof: Treasury Spends (max_values: None, max_size: Some(1848), added: 4323, mode: MaxEncodedLen) + /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:0) + /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(1238), added: 3713, mode: `MaxEncodedLen`) + /// Storage: `Treasury::SpendCount` (r:1 w:1) + /// Proof: `Treasury::SpendCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Spends` (r:0 w:1) + /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(1853), added: 4328, mode: `MaxEncodedLen`) fn spend() -> Weight { // Proof Size summary in bytes: - // Measured: `114` - // Estimated: `4702` - // Minimum execution time: 208_000_000 picoseconds. - Weight::from_parts(222_000_000, 0) - .saturating_add(Weight::from_parts(0, 4702)) + // Measured: `215` + // Estimated: `4703` + // Minimum execution time: 16_829_000 picoseconds. + Weight::from_parts(17_251_000, 0) + .saturating_add(Weight::from_parts(0, 4703)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Treasury Spends (r:1 w:1) - /// Proof: Treasury Spends (max_values: None, max_size: Some(1848), added: 4323, mode: MaxEncodedLen) - /// Storage: XcmPallet QueryCounter (r:1 w:1) - /// Proof Skipped: XcmPallet QueryCounter (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) - /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) - /// Storage: XcmPallet SupportedVersion (r:1 w:0) - /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) - /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Dmp DownwardMessageQueues (r:1 w:1) - /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) - /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) - /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) - /// Storage: XcmPallet Queries (r:0 w:1) - /// Proof Skipped: XcmPallet Queries (max_values: None, max_size: None, mode: Measured) + /// Storage: `Treasury::Spends` (r:1 w:1) + /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(1853), added: 4328, mode: `MaxEncodedLen`) + /// Storage: `XcmPallet::QueryCounter` (r:1 w:1) + /// Proof: `XcmPallet::QueryCounter` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::Queries` (r:0 w:1) + /// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn payout() -> Weight { // Proof Size summary in bytes: - // Measured: `737` - // Estimated: `5313` - // Minimum execution time: 551_000_000 picoseconds. - Weight::from_parts(569_000_000, 0) - .saturating_add(Weight::from_parts(0, 5313)) - .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(6)) + // Measured: `458` + // Estimated: `5318` + // Minimum execution time: 41_554_000 picoseconds. + Weight::from_parts(42_451_000, 0) + .saturating_add(Weight::from_parts(0, 5318)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(5)) } - /// Storage: Treasury Spends (r:1 w:1) - /// Proof: Treasury Spends (max_values: None, max_size: Some(1848), added: 4323, mode: MaxEncodedLen) - /// Storage: XcmPallet Queries (r:1 w:1) - /// Proof Skipped: XcmPallet Queries (max_values: None, max_size: None, mode: Measured) + /// Storage: `Treasury::Spends` (r:1 w:1) + /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(1853), added: 4328, mode: `MaxEncodedLen`) + /// Storage: `XcmPallet::Queries` (r:1 w:1) + /// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn check_status() -> Weight { // Proof Size summary in bytes: - // Measured: `442` - // Estimated: `5313` - // Minimum execution time: 245_000_000 picoseconds. - Weight::from_parts(281_000_000, 0) - .saturating_add(Weight::from_parts(0, 5313)) + // Measured: `306` + // Estimated: `5318` + // Minimum execution time: 22_546_000 picoseconds. + Weight::from_parts(23_151_000, 0) + .saturating_add(Weight::from_parts(0, 5318)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Treasury Spends (r:1 w:1) - /// Proof: Treasury Spends (max_values: None, max_size: Some(1848), added: 4323, mode: MaxEncodedLen) + /// Storage: `Treasury::Spends` (r:1 w:1) + /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(1853), added: 4328, mode: `MaxEncodedLen`) fn void_spend() -> Weight { // Proof Size summary in bytes: - // Measured: `172` - // Estimated: `5313` - // Minimum execution time: 147_000_000 picoseconds. - Weight::from_parts(160_000_000, 0) - .saturating_add(Weight::from_parts(0, 5313)) + // Measured: `278` + // Estimated: `5318` + // Minimum execution time: 12_169_000 picoseconds. + Weight::from_parts(12_484_000, 0) + .saturating_add(Weight::from_parts(0, 5318)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/weights/pallet_utility.rs b/polkadot/runtime/rococo/src/weights/pallet_utility.rs index f50f60eaad7..6f2a374247f 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_utility.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_utility.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_utility` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=pallet_utility // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/ +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -52,18 +55,18 @@ impl pallet_utility::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_738_000 picoseconds. - Weight::from_parts(2_704_821, 0) + // Minimum execution time: 4_041_000 picoseconds. + Weight::from_parts(5_685_496, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 2_999 - .saturating_add(Weight::from_parts(4_627_278, 0).saturating_mul(c.into())) + // Standard Error: 810 + .saturating_add(Weight::from_parts(3_177_197, 0).saturating_mul(c.into())) } fn as_derivative() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_294_000 picoseconds. - Weight::from_parts(5_467_000, 0) + // Minimum execution time: 3_667_000 picoseconds. + Weight::from_parts(3_871_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// The range of component `c` is `[0, 1000]`. @@ -71,18 +74,18 @@ impl pallet_utility::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_828_000 picoseconds. - Weight::from_parts(4_650_678, 0) + // Minimum execution time: 4_116_000 picoseconds. + Weight::from_parts(6_453_932, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 2_789 - .saturating_add(Weight::from_parts(4_885_004, 0).saturating_mul(c.into())) + // Standard Error: 825 + .saturating_add(Weight::from_parts(3_366_112, 0).saturating_mul(c.into())) } fn dispatch_as() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_020_000 picoseconds. - Weight::from_parts(9_205_000, 0) + // Minimum execution time: 5_630_000 picoseconds. + Weight::from_parts(5_956_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// The range of component `c` is `[0, 1000]`. @@ -90,10 +93,10 @@ impl pallet_utility::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_852_000 picoseconds. - Weight::from_parts(20_703_134, 0) + // Minimum execution time: 4_165_000 picoseconds. + Weight::from_parts(5_442_561, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 3_924 - .saturating_add(Weight::from_parts(4_604_529, 0).saturating_mul(c.into())) + // Standard Error: 460 + .saturating_add(Weight::from_parts(3_173_577, 0).saturating_mul(c.into())) } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_vesting.rs b/polkadot/runtime/rococo/src/weights/pallet_vesting.rs index 2596207d583..c21ab087774 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_vesting.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_vesting.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_vesting` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=pallet_vesting // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/ +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,143 +50,143 @@ use core::marker::PhantomData; /// Weight functions for `pallet_vesting`. pub struct WeightInfo(PhantomData); impl pallet_vesting::WeightInfo for WeightInfo { - /// Storage: Vesting Vesting (r:1 w:1) - /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) /// The range of component `l` is `[0, 49]`. /// The range of component `s` is `[1, 28]`. fn vest_locked(l: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `277 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 32_820_000 picoseconds. - Weight::from_parts(31_640_992, 0) + // Minimum execution time: 29_288_000 picoseconds. + Weight::from_parts(29_095_507, 0) .saturating_add(Weight::from_parts(0, 4764)) - // Standard Error: 449 - .saturating_add(Weight::from_parts(45_254, 0).saturating_mul(l.into())) - // Standard Error: 800 - .saturating_add(Weight::from_parts(72_178, 0).saturating_mul(s.into())) + // Standard Error: 1_679 + .saturating_add(Weight::from_parts(33_164, 0).saturating_mul(l.into())) + // Standard Error: 2_988 + .saturating_add(Weight::from_parts(67_092, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Vesting Vesting (r:1 w:1) - /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) /// The range of component `l` is `[0, 49]`. /// The range of component `s` is `[1, 28]`. fn vest_unlocked(l: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `277 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 36_054_000 picoseconds. - Weight::from_parts(35_825_428, 0) + // Minimum execution time: 31_003_000 picoseconds. + Weight::from_parts(30_528_438, 0) .saturating_add(Weight::from_parts(0, 4764)) - // Standard Error: 749 - .saturating_add(Weight::from_parts(31_738, 0).saturating_mul(l.into())) - // Standard Error: 1_333 - .saturating_add(Weight::from_parts(40_580, 0).saturating_mul(s.into())) + // Standard Error: 1_586 + .saturating_add(Weight::from_parts(35_429, 0).saturating_mul(l.into())) + // Standard Error: 2_823 + .saturating_add(Weight::from_parts(76_505, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Vesting Vesting (r:1 w:1) - /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `l` is `[0, 49]`. /// The range of component `s` is `[1, 28]`. fn vest_other_locked(l: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `380 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 35_440_000 picoseconds. - Weight::from_parts(34_652_647, 0) + // Minimum execution time: 31_269_000 picoseconds. + Weight::from_parts(30_661_898, 0) .saturating_add(Weight::from_parts(0, 4764)) - // Standard Error: 517 - .saturating_add(Weight::from_parts(41_942, 0).saturating_mul(l.into())) - // Standard Error: 920 - .saturating_add(Weight::from_parts(66_074, 0).saturating_mul(s.into())) + // Standard Error: 1_394 + .saturating_add(Weight::from_parts(39_300, 0).saturating_mul(l.into())) + // Standard Error: 2_480 + .saturating_add(Weight::from_parts(78_849, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: Vesting Vesting (r:1 w:1) - /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `l` is `[0, 49]`. /// The range of component `s` is `[1, 28]`. fn vest_other_unlocked(l: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `380 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 38_880_000 picoseconds. - Weight::from_parts(39_625_819, 0) + // Minimum execution time: 33_040_000 picoseconds. + Weight::from_parts(32_469_674, 0) .saturating_add(Weight::from_parts(0, 4764)) - // Standard Error: 1_032 - .saturating_add(Weight::from_parts(29_856, 0).saturating_mul(l.into())) - // Standard Error: 1_837 - .saturating_add(Weight::from_parts(6_210, 0).saturating_mul(s.into())) + // Standard Error: 1_418 + .saturating_add(Weight::from_parts(44_206, 0).saturating_mul(l.into())) + // Standard Error: 2_523 + .saturating_add(Weight::from_parts(74_224, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: Vesting Vesting (r:1 w:1) - /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) /// The range of component `l` is `[0, 49]`. /// The range of component `s` is `[0, 27]`. fn vested_transfer(l: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `451 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 68_294_000 picoseconds. - Weight::from_parts(68_313_394, 0) + // Minimum execution time: 62_032_000 picoseconds. + Weight::from_parts(63_305_621, 0) .saturating_add(Weight::from_parts(0, 4764)) - // Standard Error: 983 - .saturating_add(Weight::from_parts(48_156, 0).saturating_mul(l.into())) - // Standard Error: 1_750 - .saturating_add(Weight::from_parts(87_719, 0).saturating_mul(s.into())) + // Standard Error: 2_277 + .saturating_add(Weight::from_parts(42_767, 0).saturating_mul(l.into())) + // Standard Error: 4_051 + .saturating_add(Weight::from_parts(65_487, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: Vesting Vesting (r:1 w:1) - /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) - /// Storage: System Account (r:2 w:2) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) /// The range of component `l` is `[0, 49]`. /// The range of component `s` is `[0, 27]`. fn force_vested_transfer(l: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `554 + l * (25 ±0) + s * (36 ±0)` // Estimated: `6196` - // Minimum execution time: 70_529_000 picoseconds. - Weight::from_parts(70_619_962, 0) + // Minimum execution time: 63_303_000 picoseconds. + Weight::from_parts(65_180_847, 0) .saturating_add(Weight::from_parts(0, 6196)) - // Standard Error: 1_259 - .saturating_add(Weight::from_parts(50_685, 0).saturating_mul(l.into())) - // Standard Error: 2_241 - .saturating_add(Weight::from_parts(91_444, 0).saturating_mul(s.into())) + // Standard Error: 2_220 + .saturating_add(Weight::from_parts(28_829, 0).saturating_mul(l.into())) + // Standard Error: 3_951 + .saturating_add(Weight::from_parts(84_970, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -192,59 +195,70 @@ impl pallet_vesting::WeightInfo for WeightInfo { /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `l` is `[0, 49]`. /// The range of component `s` is `[2, 28]`. - fn force_remove_vesting_schedule(l: u32, s: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `555 + l * (25 ±0) + s * (36 ±0)` - // Estimated: `4764` - // Minimum execution time: 41_497_000 picoseconds. - Weight::from_parts(38_763_834, 4764) - // Standard Error: 2_030 - .saturating_add(Weight::from_parts(99_580, 0).saturating_mul(l.into())) - // Standard Error: 3_750 - .saturating_add(Weight::from_parts(132_188, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) - } fn not_unlocking_merge_schedules(l: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `378 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 36_428_000 picoseconds. - Weight::from_parts(35_604_430, 0) + // Minimum execution time: 31_440_000 picoseconds. + Weight::from_parts(30_773_053, 0) .saturating_add(Weight::from_parts(0, 4764)) - // Standard Error: 504 - .saturating_add(Weight::from_parts(43_191, 0).saturating_mul(l.into())) - // Standard Error: 931 - .saturating_add(Weight::from_parts(66_795, 0).saturating_mul(s.into())) + // Standard Error: 1_474 + .saturating_add(Weight::from_parts(43_019, 0).saturating_mul(l.into())) + // Standard Error: 2_723 + .saturating_add(Weight::from_parts(73_360, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: Vesting Vesting (r:1 w:1) - /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `l` is `[0, 49]`. /// The range of component `s` is `[2, 28]`. fn unlocking_merge_schedules(l: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `378 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 40_696_000 picoseconds. - Weight::from_parts(39_741_284, 0) + // Minimum execution time: 34_221_000 picoseconds. + Weight::from_parts(33_201_125, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 1_751 + .saturating_add(Weight::from_parts(44_088, 0).saturating_mul(l.into())) + // Standard Error: 3_234 + .saturating_add(Weight::from_parts(86_228, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `l` is `[0, 49]`. + /// The range of component `s` is `[2, 28]`. + fn force_remove_vesting_schedule(l: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `451 + l * (25 ±0) + s * (36 ±0)` + // Estimated: `4764` + // Minimum execution time: 35_553_000 picoseconds. + Weight::from_parts(34_974_083, 0) .saturating_add(Weight::from_parts(0, 4764)) - // Standard Error: 478 - .saturating_add(Weight::from_parts(43_792, 0).saturating_mul(l.into())) - // Standard Error: 883 - .saturating_add(Weight::from_parts(66_540, 0).saturating_mul(s.into())) + // Standard Error: 1_560 + .saturating_add(Weight::from_parts(34_615, 0).saturating_mul(l.into())) + // Standard Error: 2_882 + .saturating_add(Weight::from_parts(83_419, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) } diff --git a/polkadot/runtime/rococo/src/weights/pallet_whitelist.rs b/polkadot/runtime/rococo/src/weights/pallet_whitelist.rs index 7c307deec4c..ec67268d144 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_whitelist.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_whitelist.rs @@ -16,26 +16,28 @@ //! Autogenerated weights for `pallet_whitelist` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-08-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-aahe6cbd-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/production/polkadot +// ./target/production/polkadot // benchmark // pallet +// --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_whitelist // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled -// --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json -// --pallet=pallet_whitelist -// --chain=rococo-dev -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/ +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,67 +52,75 @@ pub struct WeightInfo(PhantomData); impl pallet_whitelist::WeightInfo for WeightInfo { /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Preimage::StatusFor` (r:1 w:1) + /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn whitelist_call() -> Weight { // Proof Size summary in bytes: // Measured: `223` // Estimated: `3556` - // Minimum execution time: 20_035_000 picoseconds. - Weight::from_parts(20_452_000, 0) + // Minimum execution time: 16_686_000 picoseconds. + Weight::from_parts(17_042_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Preimage::StatusFor` (r:1 w:1) + /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn remove_whitelisted_call() -> Weight { // Proof Size summary in bytes: // Measured: `352` // Estimated: `3556` - // Minimum execution time: 20_247_000 picoseconds. - Weight::from_parts(20_808_000, 0) + // Minimum execution time: 18_250_000 picoseconds. + Weight::from_parts(19_026_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:1 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `Measured`) - /// Storage: `Preimage::StatusFor` (r:1 w:1) + /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 4194294]`. fn dispatch_whitelisted_call(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `428 + n * (1 ±0)` // Estimated: `3892 + n * (1 ±0)` - // Minimum execution time: 32_633_000 picoseconds. - Weight::from_parts(32_855_000, 0) + // Minimum execution time: 28_741_000 picoseconds. + Weight::from_parts(29_024_000, 0) .saturating_add(Weight::from_parts(0, 3892)) - // Standard Error: 1 - .saturating_add(Weight::from_parts(1_223, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(3)) + // Standard Error: 7 + .saturating_add(Weight::from_parts(1_305, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Preimage::StatusFor` (r:1 w:1) + /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 10000]`. fn dispatch_whitelisted_call_with_preimage(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `352` // Estimated: `3556` - // Minimum execution time: 23_833_000 picoseconds. - Weight::from_parts(24_698_994, 0) + // Minimum execution time: 21_670_000 picoseconds. + Weight::from_parts(22_561_364, 0) .saturating_add(Weight::from_parts(0, 3556)) // Standard Error: 4 - .saturating_add(Weight::from_parts(1_454, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(Weight::from_parts(1_468, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_xcm.rs b/polkadot/runtime/rococo/src/weights/pallet_xcm.rs index 5544ca44658..d5cf33515e6 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_xcm.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_xcm.rs @@ -17,23 +17,25 @@ //! Autogenerated weights for `pallet_xcm` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/production/polkadot +// ./target/production/polkadot // benchmark // pallet +// --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_xcm // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled -// --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_xcm -// --chain=rococo-dev // --header=./polkadot/file_header.txt // --output=./polkadot/runtime/rococo/src/weights/ @@ -60,8 +62,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `180` // Estimated: `3645` - // Minimum execution time: 25_043_000 picoseconds. - Weight::from_parts(25_682_000, 0) + // Minimum execution time: 25_521_000 picoseconds. + Weight::from_parts(25_922_000, 0) .saturating_add(Weight::from_parts(0, 3645)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) @@ -80,8 +82,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `180` // Estimated: `3645` - // Minimum execution time: 107_570_000 picoseconds. - Weight::from_parts(109_878_000, 0) + // Minimum execution time: 112_185_000 picoseconds. + Weight::from_parts(115_991_000, 0) .saturating_add(Weight::from_parts(0, 3645)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) @@ -100,8 +102,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `232` // Estimated: `3697` - // Minimum execution time: 106_341_000 picoseconds. - Weight::from_parts(109_135_000, 0) + // Minimum execution time: 108_693_000 picoseconds. + Weight::from_parts(111_853_000, 0) .saturating_add(Weight::from_parts(0, 3697)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) @@ -120,8 +122,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `180` // Estimated: `3645` - // Minimum execution time: 108_372_000 picoseconds. - Weight::from_parts(112_890_000, 0) + // Minimum execution time: 113_040_000 picoseconds. + Weight::from_parts(115_635_000, 0) .saturating_add(Weight::from_parts(0, 3645)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) @@ -130,8 +132,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_957_000 picoseconds. - Weight::from_parts(7_417_000, 0) + // Minimum execution time: 6_979_000 picoseconds. + Weight::from_parts(7_342_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// Storage: `XcmPallet::SupportedVersion` (r:0 w:1) @@ -140,8 +142,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_053_000 picoseconds. - Weight::from_parts(7_462_000, 0) + // Minimum execution time: 7_144_000 picoseconds. + Weight::from_parts(7_297_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -149,8 +151,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_918_000 picoseconds. - Weight::from_parts(2_037_000, 0) + // Minimum execution time: 1_886_000 picoseconds. + Weight::from_parts(1_995_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// Storage: `XcmPallet::VersionNotifiers` (r:1 w:1) @@ -171,8 +173,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `180` // Estimated: `3645` - // Minimum execution time: 30_417_000 picoseconds. - Weight::from_parts(31_191_000, 0) + // Minimum execution time: 31_238_000 picoseconds. + Weight::from_parts(31_955_000, 0) .saturating_add(Weight::from_parts(0, 3645)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(5)) @@ -193,8 +195,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `360` // Estimated: `3825` - // Minimum execution time: 36_666_000 picoseconds. - Weight::from_parts(37_779_000, 0) + // Minimum execution time: 37_237_000 picoseconds. + Weight::from_parts(38_569_000, 0) .saturating_add(Weight::from_parts(0, 3825)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) @@ -205,8 +207,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_869_000 picoseconds. - Weight::from_parts(2_003_000, 0) + // Minimum execution time: 1_884_000 picoseconds. + Weight::from_parts(2_028_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -216,8 +218,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `22` // Estimated: `13387` - // Minimum execution time: 16_188_000 picoseconds. - Weight::from_parts(16_435_000, 0) + // Minimum execution time: 16_048_000 picoseconds. + Weight::from_parts(16_617_000, 0) .saturating_add(Weight::from_parts(0, 13387)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -228,8 +230,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `26` // Estimated: `13391` - // Minimum execution time: 16_431_000 picoseconds. - Weight::from_parts(16_935_000, 0) + // Minimum execution time: 16_073_000 picoseconds. + Weight::from_parts(16_672_000, 0) .saturating_add(Weight::from_parts(0, 13391)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -240,8 +242,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `40` // Estimated: `15880` - // Minimum execution time: 18_460_000 picoseconds. - Weight::from_parts(18_885_000, 0) + // Minimum execution time: 18_422_000 picoseconds. + Weight::from_parts(18_900_000, 0) .saturating_add(Weight::from_parts(0, 15880)) .saturating_add(T::DbWeight::get().reads(6)) } @@ -259,8 +261,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `216` // Estimated: `6156` - // Minimum execution time: 29_623_000 picoseconds. - Weight::from_parts(30_661_000, 0) + // Minimum execution time: 30_373_000 picoseconds. + Weight::from_parts(30_972_000, 0) .saturating_add(Weight::from_parts(0, 6156)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) @@ -271,8 +273,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `69` // Estimated: `10959` - // Minimum execution time: 12_043_000 picoseconds. - Weight::from_parts(12_360_000, 0) + // Minimum execution time: 11_863_000 picoseconds. + Weight::from_parts(12_270_000, 0) .saturating_add(Weight::from_parts(0, 10959)) .saturating_add(T::DbWeight::get().reads(4)) } @@ -282,8 +284,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `33` // Estimated: `13398` - // Minimum execution time: 16_511_000 picoseconds. - Weight::from_parts(17_011_000, 0) + // Minimum execution time: 16_733_000 picoseconds. + Weight::from_parts(17_094_000, 0) .saturating_add(Weight::from_parts(0, 13398)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -302,8 +304,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `216` // Estimated: `13581` - // Minimum execution time: 39_041_000 picoseconds. - Weight::from_parts(39_883_000, 0) + // Minimum execution time: 39_236_000 picoseconds. + Weight::from_parts(40_587_000, 0) .saturating_add(Weight::from_parts(0, 13581)) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) @@ -316,8 +318,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `1485` - // Minimum execution time: 2_030_000 picoseconds. - Weight::from_parts(2_150_000, 0) + // Minimum execution time: 2_145_000 picoseconds. + Weight::from_parts(2_255_000, 0) .saturating_add(Weight::from_parts(0, 1485)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -328,8 +330,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7576` // Estimated: `11041` - // Minimum execution time: 22_615_000 picoseconds. - Weight::from_parts(23_008_000, 0) + // Minimum execution time: 22_518_000 picoseconds. + Weight::from_parts(22_926_000, 0) .saturating_add(Weight::from_parts(0, 11041)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_fungible.rs b/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_fungible.rs new file mode 100644 index 00000000000..dc5e5d8ca4b --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_fungible.rs @@ -0,0 +1,191 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Autogenerated weights for `pallet_xcm_benchmarks::fungible` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_xcm_benchmarks::fungible +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_fungible.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_xcm_benchmarks::fungible`. +pub struct WeightInfo(PhantomData); +impl pallet_xcm_benchmarks::fungible::WeightInfo for WeightInfo { + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn withdraw_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `101` + // Estimated: `3593` + // Minimum execution time: 27_223_000 picoseconds. + Weight::from_parts(27_947_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn transfer_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `101` + // Estimated: `6196` + // Minimum execution time: 36_502_000 picoseconds. + Weight::from_parts(37_023_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn transfer_reserve_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `281` + // Estimated: `6196` + // Minimum execution time: 85_152_000 picoseconds. + Weight::from_parts(86_442_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn reserve_asset_deposited() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn initiate_reserve_withdraw() -> Weight { + // Proof Size summary in bytes: + // Measured: `281` + // Estimated: `3746` + // Minimum execution time: 56_571_000 picoseconds. + Weight::from_parts(58_163_000, 0) + .saturating_add(Weight::from_parts(0, 3746)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn receive_teleported_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `103` + // Estimated: `3593` + // Minimum execution time: 27_411_000 picoseconds. + Weight::from_parts(27_953_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn deposit_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 20_776_000 picoseconds. + Weight::from_parts(21_145_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn deposit_reserve_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `180` + // Estimated: `3645` + // Minimum execution time: 51_738_000 picoseconds. + Weight::from_parts(53_251_000, 0) + .saturating_add(Weight::from_parts(0, 3645)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn initiate_teleport() -> Weight { + // Proof Size summary in bytes: + // Measured: `180` + // Estimated: `3645` + // Minimum execution time: 39_333_000 picoseconds. + Weight::from_parts(40_515_000, 0) + .saturating_add(Weight::from_parts(0, 3645)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_generic.rs b/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_generic.rs new file mode 100644 index 00000000000..b62f36172ba --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_generic.rs @@ -0,0 +1,347 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Autogenerated weights for `pallet_xcm_benchmarks::generic` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=pallet_xcm_benchmarks::generic +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_generic.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_xcm_benchmarks::generic`. +pub struct WeightInfo(PhantomData); +impl pallet_xcm_benchmarks::generic::WeightInfo for WeightInfo { + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn report_holding() -> Weight { + // Proof Size summary in bytes: + // Measured: `281` + // Estimated: `3746` + // Minimum execution time: 55_210_000 picoseconds. + Weight::from_parts(56_613_000, 0) + .saturating_add(Weight::from_parts(0, 3746)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + fn buy_execution() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_246_000 picoseconds. + Weight::from_parts(1_339_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `XcmPallet::Queries` (r:1 w:0) + /// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn query_response() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3465` + // Minimum execution time: 5_377_000 picoseconds. + Weight::from_parts(5_549_000, 0) + .saturating_add(Weight::from_parts(0, 3465)) + .saturating_add(T::DbWeight::get().reads(1)) + } + fn transact() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 7_008_000 picoseconds. + Weight::from_parts(7_361_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn refund_surplus() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_700_000 picoseconds. + Weight::from_parts(1_848_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn set_error_handler() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_198_000 picoseconds. + Weight::from_parts(1_265_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn set_appendix() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_197_000 picoseconds. + Weight::from_parts(1_267_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn clear_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_193_000 picoseconds. + Weight::from_parts(1_258_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn descend_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_268_000 picoseconds. + Weight::from_parts(1_342_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn clear_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_173_000 picoseconds. + Weight::from_parts(1_248_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn report_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `281` + // Estimated: `3746` + // Minimum execution time: 53_715_000 picoseconds. + Weight::from_parts(54_860_000, 0) + .saturating_add(Weight::from_parts(0, 3746)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `XcmPallet::AssetTraps` (r:1 w:1) + /// Proof: `XcmPallet::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `23` + // Estimated: `3488` + // Minimum execution time: 8_621_000 picoseconds. + Weight::from_parts(8_903_000, 0) + .saturating_add(Weight::from_parts(0, 3488)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn trap() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_211_000 picoseconds. + Weight::from_parts(1_281_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `XcmPallet::VersionNotifyTargets` (r:1 w:1) + /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn subscribe_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `180` + // Estimated: `3645` + // Minimum execution time: 26_448_000 picoseconds. + Weight::from_parts(27_057_000, 0) + .saturating_add(Weight::from_parts(0, 3645)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `XcmPallet::VersionNotifyTargets` (r:0 w:1) + /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn unsubscribe_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_498_000 picoseconds. + Weight::from_parts(3_614_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn burn_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_575_000 picoseconds. + Weight::from_parts(1_698_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn expect_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_334_000 picoseconds. + Weight::from_parts(1_435_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn expect_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_244_000 picoseconds. + Weight::from_parts(1_337_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn expect_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_244_000 picoseconds. + Weight::from_parts(1_331_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn expect_transact_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_407_000 picoseconds. + Weight::from_parts(1_522_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn query_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `281` + // Estimated: `3746` + // Minimum execution time: 62_963_000 picoseconds. + Weight::from_parts(64_556_000, 0) + .saturating_add(Weight::from_parts(0, 3746)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + fn expect_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_458_000 picoseconds. + Weight::from_parts(8_741_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn report_transact_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `281` + // Estimated: `3746` + // Minimum execution time: 54_068_000 picoseconds. + Weight::from_parts(55_665_000, 0) + .saturating_add(Weight::from_parts(0, 3746)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + fn clear_transact_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_290_000 picoseconds. + Weight::from_parts(1_348_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn set_topic() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_189_000 picoseconds. + Weight::from_parts(1_268_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn clear_topic() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_197_000 picoseconds. + Weight::from_parts(1_276_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn set_fees_mode() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_197_000 picoseconds. + Weight::from_parts(1_253_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn unpaid_execution() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_250_000 picoseconds. + Weight::from_parts(1_354_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_assigned_slots.rs b/polkadot/runtime/rococo/src/weights/runtime_common_assigned_slots.rs index a6beeded428..f41a5d4ebf8 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_common_assigned_slots.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_common_assigned_slots.rs @@ -16,26 +16,28 @@ //! Autogenerated weights for `runtime_common::assigned_slots` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-08-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-ynta1nyy-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: ``, WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/production/polkadot +// ./target/production/polkadot // benchmark // pallet +// --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_common::assigned_slots // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled -// --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json -// --pallet=runtime_common::assigned_slots -// --chain=rococo-dev -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/ +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/runtime_common_assigned_slots.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -48,7 +50,7 @@ use core::marker::PhantomData; /// Weight functions for `runtime_common::assigned_slots`. pub struct WeightInfo(PhantomData); impl runtime_common::assigned_slots::WeightInfo for WeightInfo { - /// Storage: `Registrar::Paras` (r:1 w:1) + /// Storage: `Registrar::Paras` (r:1 w:0) /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Paras::ParaLifecycles` (r:1 w:1) /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -68,15 +70,15 @@ impl runtime_common::assigned_slots::WeightInfo for Wei /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) fn assign_perm_parachain_slot() -> Weight { // Proof Size summary in bytes: - // Measured: `673` - // Estimated: `4138` - // Minimum execution time: 84_646_000 picoseconds. - Weight::from_parts(91_791_000, 0) - .saturating_add(Weight::from_parts(0, 4138)) + // Measured: `730` + // Estimated: `4195` + // Minimum execution time: 71_337_000 picoseconds. + Weight::from_parts(80_807_000, 0) + .saturating_add(Weight::from_parts(0, 4195)) .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(6)) + .saturating_add(T::DbWeight::get().writes(5)) } - /// Storage: `Registrar::Paras` (r:1 w:1) + /// Storage: `Registrar::Paras` (r:1 w:0) /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Paras::ParaLifecycles` (r:1 w:1) /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -98,13 +100,13 @@ impl runtime_common::assigned_slots::WeightInfo for Wei /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) fn assign_temp_parachain_slot() -> Weight { // Proof Size summary in bytes: - // Measured: `673` - // Estimated: `4138` - // Minimum execution time: 68_091_000 picoseconds. - Weight::from_parts(77_310_000, 0) - .saturating_add(Weight::from_parts(0, 4138)) + // Measured: `730` + // Estimated: `4195` + // Minimum execution time: 60_188_000 picoseconds. + Weight::from_parts(63_932_000, 0) + .saturating_add(Weight::from_parts(0, 4195)) .saturating_add(T::DbWeight::get().reads(10)) - .saturating_add(T::DbWeight::get().writes(7)) + .saturating_add(T::DbWeight::get().writes(6)) } /// Storage: `AssignedSlots::PermanentSlots` (r:1 w:0) /// Proof: `AssignedSlots::PermanentSlots` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) @@ -118,11 +120,11 @@ impl runtime_common::assigned_slots::WeightInfo for Wei /// Proof: `AssignedSlots::TemporarySlotCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn unassign_parachain_slot() -> Weight { // Proof Size summary in bytes: - // Measured: `823` - // Estimated: `4288` - // Minimum execution time: 38_081_000 picoseconds. - Weight::from_parts(40_987_000, 0) - .saturating_add(Weight::from_parts(0, 4288)) + // Measured: `856` + // Estimated: `4321` + // Minimum execution time: 35_764_000 picoseconds. + Weight::from_parts(38_355_000, 0) + .saturating_add(Weight::from_parts(0, 4321)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -132,8 +134,8 @@ impl runtime_common::assigned_slots::WeightInfo for Wei // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_182_000 picoseconds. - Weight::from_parts(7_437_000, 0) + // Minimum execution time: 4_634_000 picoseconds. + Weight::from_parts(4_852_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -143,8 +145,8 @@ impl runtime_common::assigned_slots::WeightInfo for Wei // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_153_000 picoseconds. - Weight::from_parts(7_456_000, 0) + // Minimum execution time: 4_563_000 picoseconds. + Weight::from_parts(4_829_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_auctions.rs b/polkadot/runtime/rococo/src/weights/runtime_common_auctions.rs index 3cd7c7a47e9..2b756802289 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_common_auctions.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_common_auctions.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_common::auctions` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=runtime_common::auctions // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/runtime_common_auctions.rs +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/runtime_common_auctions.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,92 +50,90 @@ use core::marker::PhantomData; /// Weight functions for `runtime_common::auctions`. pub struct WeightInfo(PhantomData); impl runtime_common::auctions::WeightInfo for WeightInfo { - /// Storage: Auctions AuctionInfo (r:1 w:1) - /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Auctions AuctionCounter (r:1 w:1) - /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: `Auctions::AuctionInfo` (r:1 w:1) + /// Proof: `Auctions::AuctionInfo` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Auctions::AuctionCounter` (r:1 w:1) + /// Proof: `Auctions::AuctionCounter` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn new_auction() -> Weight { // Proof Size summary in bytes: // Measured: `4` // Estimated: `1493` - // Minimum execution time: 12_805_000 picoseconds. - Weight::from_parts(13_153_000, 0) + // Minimum execution time: 7_307_000 picoseconds. + Weight::from_parts(7_680_000, 0) .saturating_add(Weight::from_parts(0, 1493)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Paras ParaLifecycles (r:1 w:0) - /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) - /// Storage: Auctions AuctionCounter (r:1 w:0) - /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Auctions AuctionInfo (r:1 w:0) - /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Slots Leases (r:1 w:0) - /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) - /// Storage: Auctions Winning (r:1 w:1) - /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) - /// Storage: Auctions ReservedAmounts (r:2 w:2) - /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Paras::ParaLifecycles` (r:1 w:0) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Auctions::AuctionCounter` (r:1 w:0) + /// Proof: `Auctions::AuctionCounter` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Auctions::AuctionInfo` (r:1 w:0) + /// Proof: `Auctions::AuctionInfo` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Slots::Leases` (r:1 w:0) + /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Auctions::Winning` (r:1 w:1) + /// Proof: `Auctions::Winning` (`max_values`: None, `max_size`: Some(1920), added: 4395, mode: `MaxEncodedLen`) + /// Storage: `Auctions::ReservedAmounts` (r:2 w:2) + /// Proof: `Auctions::ReservedAmounts` (`max_values`: None, `max_size`: Some(60), added: 2535, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn bid() -> Weight { // Proof Size summary in bytes: - // Measured: `728` + // Measured: `761` // Estimated: `6060` - // Minimum execution time: 77_380_000 picoseconds. - Weight::from_parts(80_503_000, 0) + // Minimum execution time: 75_448_000 picoseconds. + Weight::from_parts(78_716_000, 0) .saturating_add(Weight::from_parts(0, 6060)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: Auctions AuctionInfo (r:1 w:1) - /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Babe NextRandomness (r:1 w:0) - /// Proof: Babe NextRandomness (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) - /// Storage: Babe EpochStart (r:1 w:0) - /// Proof: Babe EpochStart (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Auctions AuctionCounter (r:1 w:0) - /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Auctions Winning (r:3600 w:3600) - /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) - /// Storage: Auctions ReservedAmounts (r:37 w:36) - /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) - /// Storage: System Account (r:36 w:36) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Slots Leases (r:2 w:2) - /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras ParaLifecycles (r:1 w:1) - /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) - /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) - /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras ActionsQueue (r:1 w:1) - /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) - /// Storage: Registrar Paras (r:1 w:1) - /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: `Auctions::AuctionInfo` (r:1 w:1) + /// Proof: `Auctions::AuctionInfo` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Babe::NextRandomness` (r:1 w:0) + /// Proof: `Babe::NextRandomness` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `Babe::EpochStart` (r:1 w:0) + /// Proof: `Babe::EpochStart` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Auctions::AuctionCounter` (r:1 w:0) + /// Proof: `Auctions::AuctionCounter` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Auctions::Winning` (r:3600 w:3600) + /// Proof: `Auctions::Winning` (`max_values`: None, `max_size`: Some(1920), added: 4395, mode: `MaxEncodedLen`) + /// Storage: `Auctions::ReservedAmounts` (r:37 w:36) + /// Proof: `Auctions::ReservedAmounts` (`max_values`: None, `max_size`: Some(60), added: 2535, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:36 w:36) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Slots::Leases` (r:2 w:2) + /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ParaLifecycles` (r:1 w:1) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ActionsQueue` (r:1 w:1) + /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) fn on_initialize() -> Weight { // Proof Size summary in bytes: - // Measured: `6947789` + // Measured: `6947017` // Estimated: `15822990` - // Minimum execution time: 6_311_055_000 picoseconds. - Weight::from_parts(6_409_142_000, 0) + // Minimum execution time: 7_120_207_000 picoseconds. + Weight::from_parts(7_273_496_000, 0) .saturating_add(Weight::from_parts(0, 15822990)) - .saturating_add(T::DbWeight::get().reads(3683)) - .saturating_add(T::DbWeight::get().writes(3678)) + .saturating_add(T::DbWeight::get().reads(3682)) + .saturating_add(T::DbWeight::get().writes(3677)) } - /// Storage: Auctions ReservedAmounts (r:37 w:36) - /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) - /// Storage: System Account (r:36 w:36) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Auctions Winning (r:3600 w:3600) - /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) - /// Storage: Auctions AuctionInfo (r:0 w:1) - /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: `Auctions::ReservedAmounts` (r:37 w:36) + /// Proof: `Auctions::ReservedAmounts` (`max_values`: None, `max_size`: Some(60), added: 2535, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:36 w:36) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Auctions::Winning` (r:3600 w:3600) + /// Proof: `Auctions::Winning` (`max_values`: None, `max_size`: Some(1920), added: 4395, mode: `MaxEncodedLen`) + /// Storage: `Auctions::AuctionInfo` (r:0 w:1) + /// Proof: `Auctions::AuctionInfo` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) fn cancel_auction() -> Weight { // Proof Size summary in bytes: // Measured: `177732` // Estimated: `15822990` - // Minimum execution time: 4_849_561_000 picoseconds. - Weight::from_parts(4_955_226_000, 0) + // Minimum execution time: 5_536_281_000 picoseconds. + Weight::from_parts(5_675_163_000, 0) .saturating_add(Weight::from_parts(0, 15822990)) .saturating_add(T::DbWeight::get().reads(3673)) .saturating_add(T::DbWeight::get().writes(3673)) diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_claims.rs b/polkadot/runtime/rococo/src/weights/runtime_common_claims.rs index 52e0dd24afa..de2bb71933b 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_common_claims.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_common_claims.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_common::claims` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=runtime_common::claims // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/runtime_common_claims.rs +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/runtime_common_claims.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,120 +50,133 @@ use core::marker::PhantomData; /// Weight functions for `runtime_common::claims`. pub struct WeightInfo(PhantomData); impl runtime_common::claims::WeightInfo for WeightInfo { - /// Storage: Claims Claims (r:1 w:1) - /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) - /// Storage: Claims Signing (r:1 w:1) - /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) - /// Storage: Claims Total (r:1 w:1) - /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Claims Vesting (r:1 w:1) - /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) - /// Storage: Vesting Vesting (r:1 w:1) - /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:0) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: `Claims::Claims` (r:1 w:1) + /// Proof: `Claims::Claims` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Claims::Signing` (r:1 w:1) + /// Proof: `Claims::Signing` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Claims::Total` (r:1 w:1) + /// Proof: `Claims::Total` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Claims::Vesting` (r:1 w:1) + /// Proof: `Claims::Vesting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:0) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) fn claim() -> Weight { // Proof Size summary in bytes: // Measured: `558` // Estimated: `4764` - // Minimum execution time: 144_931_000 picoseconds. - Weight::from_parts(156_550_000, 0) + // Minimum execution time: 181_028_000 picoseconds. + Weight::from_parts(194_590_000, 0) .saturating_add(Weight::from_parts(0, 4764)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(6)) } - /// Storage: Claims Total (r:1 w:1) - /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Claims Vesting (r:0 w:1) - /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) - /// Storage: Claims Claims (r:0 w:1) - /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) - /// Storage: Claims Signing (r:0 w:1) - /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + /// Storage: `Claims::Total` (r:1 w:1) + /// Proof: `Claims::Total` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Claims::Vesting` (r:0 w:1) + /// Proof: `Claims::Vesting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Claims::Claims` (r:0 w:1) + /// Proof: `Claims::Claims` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Claims::Signing` (r:0 w:1) + /// Proof: `Claims::Signing` (`max_values`: None, `max_size`: None, mode: `Measured`) fn mint_claim() -> Weight { // Proof Size summary in bytes: // Measured: `216` // Estimated: `1701` - // Minimum execution time: 11_300_000 picoseconds. - Weight::from_parts(11_642_000, 0) + // Minimum execution time: 11_224_000 picoseconds. + Weight::from_parts(13_342_000, 0) .saturating_add(Weight::from_parts(0, 1701)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: Claims Claims (r:1 w:1) - /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) - /// Storage: Claims Signing (r:1 w:1) - /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) - /// Storage: Claims Total (r:1 w:1) - /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Claims Vesting (r:1 w:1) - /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) - /// Storage: Vesting Vesting (r:1 w:1) - /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:0) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: `Claims::Claims` (r:1 w:1) + /// Proof: `Claims::Claims` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Claims::Signing` (r:1 w:1) + /// Proof: `Claims::Signing` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Claims::Total` (r:1 w:1) + /// Proof: `Claims::Total` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Claims::Vesting` (r:1 w:1) + /// Proof: `Claims::Vesting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:0) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) fn claim_attest() -> Weight { // Proof Size summary in bytes: // Measured: `558` // Estimated: `4764` - // Minimum execution time: 149_112_000 picoseconds. - Weight::from_parts(153_872_000, 0) + // Minimum execution time: 187_964_000 picoseconds. + Weight::from_parts(202_553_000, 0) .saturating_add(Weight::from_parts(0, 4764)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(6)) } - /// Storage: Claims Preclaims (r:1 w:1) - /// Proof Skipped: Claims Preclaims (max_values: None, max_size: None, mode: Measured) - /// Storage: Claims Signing (r:1 w:1) - /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) - /// Storage: Claims Claims (r:1 w:1) - /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) - /// Storage: Claims Total (r:1 w:1) - /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Claims Vesting (r:1 w:1) - /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) - /// Storage: Vesting Vesting (r:1 w:1) - /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:0) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: `Claims::Preclaims` (r:1 w:1) + /// Proof: `Claims::Preclaims` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Claims::Signing` (r:1 w:1) + /// Proof: `Claims::Signing` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Claims::Claims` (r:1 w:1) + /// Proof: `Claims::Claims` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Claims::Total` (r:1 w:1) + /// Proof: `Claims::Total` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Claims::Vesting` (r:1 w:1) + /// Proof: `Claims::Vesting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Vesting::Vesting` (r:1 w:1) + /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:0) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) fn attest() -> Weight { // Proof Size summary in bytes: // Measured: `632` // Estimated: `4764` - // Minimum execution time: 69_619_000 picoseconds. - Weight::from_parts(79_242_000, 0) + // Minimum execution time: 78_210_000 picoseconds. + Weight::from_parts(84_581_000, 0) .saturating_add(Weight::from_parts(0, 4764)) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(7)) } - /// Storage: Claims Claims (r:1 w:2) - /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) - /// Storage: Claims Vesting (r:1 w:2) - /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) - /// Storage: Claims Signing (r:1 w:2) - /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) - /// Storage: Claims Preclaims (r:1 w:1) - /// Proof Skipped: Claims Preclaims (max_values: None, max_size: None, mode: Measured) + /// Storage: `Claims::Claims` (r:1 w:2) + /// Proof: `Claims::Claims` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Claims::Vesting` (r:1 w:2) + /// Proof: `Claims::Vesting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Claims::Signing` (r:1 w:2) + /// Proof: `Claims::Signing` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Claims::Preclaims` (r:1 w:1) + /// Proof: `Claims::Preclaims` (`max_values`: None, `max_size`: None, mode: `Measured`) fn move_claim() -> Weight { // Proof Size summary in bytes: // Measured: `440` // Estimated: `3905` - // Minimum execution time: 22_066_000 picoseconds. - Weight::from_parts(22_483_000, 0) + // Minimum execution time: 33_940_000 picoseconds. + Weight::from_parts(48_438_000, 0) .saturating_add(Weight::from_parts(0, 3905)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(7)) } + /// Storage: `Claims::Preclaims` (r:1 w:0) + /// Proof: `Claims::Preclaims` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Claims::Signing` (r:1 w:0) + /// Proof: `Claims::Signing` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn prevalidate_attests() -> Weight { + // Proof Size summary in bytes: + // Measured: `296` + // Estimated: `3761` + // Minimum execution time: 9_025_000 picoseconds. + Weight::from_parts(10_563_000, 0) + .saturating_add(Weight::from_parts(0, 3761)) + .saturating_add(T::DbWeight::get().reads(2)) + } } diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_coretime.rs b/polkadot/runtime/rococo/src/weights/runtime_common_coretime.rs new file mode 100644 index 00000000000..d068f07e759 --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/runtime_common_coretime.rs @@ -0,0 +1,86 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Autogenerated weights for `runtime_common::coretime` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=rococo-dev +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_common::coretime +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/runtime_common_coretime.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `runtime_common::coretime`. +pub struct WeightInfo(PhantomData); +impl runtime_common::coretime::WeightInfo for WeightInfo { + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn request_core_count() -> Weight { + // Proof Size summary in bytes: + // Measured: `151` + // Estimated: `1636` + // Minimum execution time: 7_543_000 picoseconds. + Weight::from_parts(7_745_000, 0) + .saturating_add(Weight::from_parts(0, 1636)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `CoretimeAssignmentProvider::CoreDescriptors` (r:1 w:1) + /// Proof: `CoretimeAssignmentProvider::CoreDescriptors` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `CoretimeAssignmentProvider::CoreSchedules` (r:0 w:1) + /// Proof: `CoretimeAssignmentProvider::CoreSchedules` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// The range of component `s` is `[1, 100]`. + fn assign_core(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `180` + // Estimated: `3645` + // Minimum execution time: 9_367_000 picoseconds. + Weight::from_parts(9_932_305, 0) + .saturating_add(Weight::from_parts(0, 3645)) + // Standard Error: 231 + .saturating_add(Weight::from_parts(12_947, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_crowdloan.rs b/polkadot/runtime/rococo/src/weights/runtime_common_crowdloan.rs index 0e7420cba2e..8ebab3d551e 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_common_crowdloan.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_common_crowdloan.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_common::crowdloan` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=runtime_common::crowdloan // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/runtime_common_crowdloan.rs +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/runtime_common_crowdloan.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,172 +50,168 @@ use core::marker::PhantomData; /// Weight functions for `runtime_common::crowdloan`. pub struct WeightInfo(PhantomData); impl runtime_common::crowdloan::WeightInfo for WeightInfo { - /// Storage: Crowdloan Funds (r:1 w:1) - /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) - /// Storage: Registrar Paras (r:1 w:1) - /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras ParaLifecycles (r:1 w:0) - /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) - /// Storage: Crowdloan NextFundIndex (r:1 w:1) - /// Proof Skipped: Crowdloan NextFundIndex (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Crowdloan::Funds` (r:1 w:1) + /// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Registrar::Paras` (r:1 w:0) + /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ParaLifecycles` (r:1 w:0) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Crowdloan::NextFundIndex` (r:1 w:1) + /// Proof: `Crowdloan::NextFundIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn create() -> Weight { // Proof Size summary in bytes: // Measured: `438` // Estimated: `3903` - // Minimum execution time: 50_399_000 picoseconds. - Weight::from_parts(51_641_000, 0) + // Minimum execution time: 46_095_000 picoseconds. + Weight::from_parts(48_111_000, 0) .saturating_add(Weight::from_parts(0, 3903)) .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: Crowdloan Funds (r:1 w:1) - /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) - /// Storage: Slots Leases (r:1 w:0) - /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) - /// Storage: Auctions AuctionInfo (r:1 w:0) - /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Balances InactiveIssuance (r:1 w:1) - /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: Crowdloan EndingsCount (r:1 w:0) - /// Proof Skipped: Crowdloan EndingsCount (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Crowdloan NewRaise (r:1 w:1) - /// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) - /// Proof Skipped: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + /// Storage: `Crowdloan::Funds` (r:1 w:1) + /// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Slots::Leases` (r:1 w:0) + /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Auctions::AuctionInfo` (r:1 w:0) + /// Proof: `Auctions::AuctionInfo` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Crowdloan::EndingsCount` (r:1 w:0) + /// Proof: `Crowdloan::EndingsCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Crowdloan::NewRaise` (r:1 w:1) + /// Proof: `Crowdloan::NewRaise` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: UNKNOWN KEY `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + /// Proof: UNKNOWN KEY `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) fn contribute() -> Weight { // Proof Size summary in bytes: - // Measured: `530` - // Estimated: `3995` - // Minimum execution time: 128_898_000 picoseconds. - Weight::from_parts(130_277_000, 0) - .saturating_add(Weight::from_parts(0, 3995)) - .saturating_add(T::DbWeight::get().reads(8)) - .saturating_add(T::DbWeight::get().writes(5)) + // Measured: `563` + // Estimated: `4028` + // Minimum execution time: 133_059_000 picoseconds. + Weight::from_parts(136_515_000, 0) + .saturating_add(Weight::from_parts(0, 4028)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: Crowdloan Funds (r:1 w:1) - /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) - /// Storage: System Account (r:2 w:2) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Balances InactiveIssuance (r:1 w:1) - /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: unknown `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1) - /// Proof Skipped: unknown `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1) + /// Storage: `Crowdloan::Funds` (r:1 w:1) + /// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1) + /// Proof: UNKNOWN KEY `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1) fn withdraw() -> Weight { // Proof Size summary in bytes: - // Measured: `689` + // Measured: `687` // Estimated: `6196` - // Minimum execution time: 69_543_000 picoseconds. - Weight::from_parts(71_522_000, 0) + // Minimum execution time: 71_733_000 picoseconds. + Weight::from_parts(74_034_000, 0) .saturating_add(Weight::from_parts(0, 6196)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: Skipped Metadata (r:0 w:0) - /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// Storage: `Skipped::Metadata` (r:0 w:0) + /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `k` is `[0, 1000]`. fn refund(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `127 + k * (189 ±0)` - // Estimated: `140 + k * (189 ±0)` - // Minimum execution time: 50_735_000 picoseconds. - Weight::from_parts(52_282_000, 0) - .saturating_add(Weight::from_parts(0, 140)) - // Standard Error: 21_607 - .saturating_add(Weight::from_parts(38_955_985, 0).saturating_mul(k.into())) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `125 + k * (189 ±0)` + // Estimated: `138 + k * (189 ±0)` + // Minimum execution time: 46_016_000 picoseconds. + Weight::from_parts(48_260_000, 0) + .saturating_add(Weight::from_parts(0, 138)) + // Standard Error: 21_140 + .saturating_add(Weight::from_parts(39_141_925, 0).saturating_mul(k.into())) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(k.into()))) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes(2)) .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(k.into()))) .saturating_add(Weight::from_parts(0, 189).saturating_mul(k.into())) } - /// Storage: Crowdloan Funds (r:1 w:1) - /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) - /// Storage: System Account (r:2 w:2) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Crowdloan::Funds` (r:1 w:1) + /// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn dissolve() -> Weight { // Proof Size summary in bytes: - // Measured: `515` + // Measured: `514` // Estimated: `6196` - // Minimum execution time: 43_100_000 picoseconds. - Weight::from_parts(44_272_000, 0) + // Minimum execution time: 44_724_000 picoseconds. + Weight::from_parts(47_931_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: Crowdloan Funds (r:1 w:1) - /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: `Crowdloan::Funds` (r:1 w:1) + /// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`) fn edit() -> Weight { // Proof Size summary in bytes: - // Measured: `235` - // Estimated: `3700` - // Minimum execution time: 18_702_000 picoseconds. - Weight::from_parts(19_408_000, 0) - .saturating_add(Weight::from_parts(0, 3700)) + // Measured: `234` + // Estimated: `3699` + // Minimum execution time: 19_512_000 picoseconds. + Weight::from_parts(21_129_000, 0) + .saturating_add(Weight::from_parts(0, 3699)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Crowdloan Funds (r:1 w:0) - /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) - /// Storage: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) - /// Proof Skipped: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + /// Storage: `Crowdloan::Funds` (r:1 w:0) + /// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: UNKNOWN KEY `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + /// Proof: UNKNOWN KEY `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) fn add_memo() -> Weight { // Proof Size summary in bytes: // Measured: `412` // Estimated: `3877` - // Minimum execution time: 25_568_000 picoseconds. - Weight::from_parts(26_203_000, 0) + // Minimum execution time: 33_529_000 picoseconds. + Weight::from_parts(37_082_000, 0) .saturating_add(Weight::from_parts(0, 3877)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Crowdloan Funds (r:1 w:0) - /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) - /// Storage: Crowdloan NewRaise (r:1 w:1) - /// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Crowdloan::Funds` (r:1 w:0) + /// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Crowdloan::NewRaise` (r:1 w:1) + /// Proof: `Crowdloan::NewRaise` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn poke() -> Weight { // Proof Size summary in bytes: - // Measured: `239` - // Estimated: `3704` - // Minimum execution time: 17_832_000 picoseconds. - Weight::from_parts(18_769_000, 0) - .saturating_add(Weight::from_parts(0, 3704)) + // Measured: `238` + // Estimated: `3703` + // Minimum execution time: 23_153_000 picoseconds. + Weight::from_parts(24_181_000, 0) + .saturating_add(Weight::from_parts(0, 3703)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Auctions AuctionInfo (r:1 w:0) - /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Crowdloan EndingsCount (r:1 w:1) - /// Proof Skipped: Crowdloan EndingsCount (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Crowdloan NewRaise (r:1 w:1) - /// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Crowdloan Funds (r:100 w:0) - /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) - /// Storage: Auctions AuctionCounter (r:1 w:0) - /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Paras ParaLifecycles (r:100 w:0) - /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) - /// Storage: Slots Leases (r:100 w:0) - /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) - /// Storage: Auctions Winning (r:1 w:1) - /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) - /// Storage: Auctions ReservedAmounts (r:100 w:100) - /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) - /// Storage: System Account (r:100 w:100) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Auctions::AuctionInfo` (r:1 w:0) + /// Proof: `Auctions::AuctionInfo` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Crowdloan::EndingsCount` (r:1 w:1) + /// Proof: `Crowdloan::EndingsCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Crowdloan::NewRaise` (r:1 w:1) + /// Proof: `Crowdloan::NewRaise` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Crowdloan::Funds` (r:100 w:0) + /// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Auctions::AuctionCounter` (r:1 w:0) + /// Proof: `Auctions::AuctionCounter` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Paras::ParaLifecycles` (r:100 w:0) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Slots::Leases` (r:100 w:0) + /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Auctions::Winning` (r:1 w:1) + /// Proof: `Auctions::Winning` (`max_values`: None, `max_size`: Some(1920), added: 4395, mode: `MaxEncodedLen`) + /// Storage: `Auctions::ReservedAmounts` (r:100 w:100) + /// Proof: `Auctions::ReservedAmounts` (`max_values`: None, `max_size`: Some(60), added: 2535, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:100 w:100) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `n` is `[2, 100]`. fn on_initialize(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `197 + n * (356 ±0)` + // Measured: `229 + n * (356 ±0)` // Estimated: `5385 + n * (2832 ±0)` - // Minimum execution time: 128_319_000 picoseconds. - Weight::from_parts(130_877_000, 0) + // Minimum execution time: 120_164_000 picoseconds. + Weight::from_parts(3_390_119, 0) .saturating_add(Weight::from_parts(0, 5385)) - // Standard Error: 61_381 - .saturating_add(Weight::from_parts(60_209_202, 0).saturating_mul(n.into())) + // Standard Error: 41_727 + .saturating_add(Weight::from_parts(54_453_016, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(3)) diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_identity_migrator.rs b/polkadot/runtime/rococo/src/weights/runtime_common_identity_migrator.rs index cec357453b6..9b0cb98e6c0 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_common_identity_migrator.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_common_identity_migrator.rs @@ -1,36 +1,43 @@ // Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 +// This file is part of Polkadot. -// 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. +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . //! Autogenerated weights for `runtime_common::identity_migrator` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-11-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `sbtb`, CPU: `13th Gen Intel(R) Core(TM) i7-1365U` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/release/polkadot +// ./target/production/polkadot // benchmark // pallet // --chain=rococo-dev -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=runtime_common::identity_migrator // --extrinsic=* -// --output=./migrator-release.rs +// --execution=wasm +// --wasm-execution=compiled +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/runtime_common_identity_migrator.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -44,7 +51,7 @@ use core::marker::PhantomData; pub struct WeightInfo(PhantomData); impl runtime_common::identity_migrator::WeightInfo for WeightInfo { /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// Storage: `Identity::SubsOf` (r:1 w:1) /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:2 w:2) @@ -63,34 +70,34 @@ impl runtime_common::identity_migrator::WeightInfo for /// The range of component `s` is `[0, 100]`. fn reap_identity(r: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `7292 + r * (8 ±0) + s * (32 ±0)` - // Estimated: `11003 + r * (8 ±0) + s * (33 ±0)` - // Minimum execution time: 163_756_000 picoseconds. - Weight::from_parts(158_982_500, 0) - .saturating_add(Weight::from_parts(0, 11003)) - // Standard Error: 1_143_629 - .saturating_add(Weight::from_parts(238_675, 0).saturating_mul(r.into())) - // Standard Error: 228_725 - .saturating_add(Weight::from_parts(1_529_645, 0).saturating_mul(s.into())) + // Measured: `7457 + r * (5 ±0) + s * (32 ±0)` + // Estimated: `11037 + r * (7 ±0) + s * (32 ±0)` + // Minimum execution time: 157_343_000 picoseconds. + Weight::from_parts(159_289_236, 0) + .saturating_add(Weight::from_parts(0, 11037)) + // Standard Error: 16_439 + .saturating_add(Weight::from_parts(224_293, 0).saturating_mul(r.into())) + // Standard Error: 3_367 + .saturating_add(Weight::from_parts(1_383_637, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(8)) - .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().writes(6)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) - .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) - .saturating_add(Weight::from_parts(0, 33).saturating_mul(s.into())) + .saturating_add(Weight::from_parts(0, 7).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(s.into())) } /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Identity::SubsOf` (r:1 w:1) /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) fn poke_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `7229` - // Estimated: `11003` - // Minimum execution time: 137_570_000 picoseconds. - Weight::from_parts(137_570_000, 0) - .saturating_add(Weight::from_parts(0, 11003)) + // Measured: `7242` + // Estimated: `11037` + // Minimum execution time: 114_384_000 picoseconds. + Weight::from_parts(115_741_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_paras_registrar.rs b/polkadot/runtime/rococo/src/weights/runtime_common_paras_registrar.rs index 0a56562a1a9..e066106e134 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_common_paras_registrar.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_common_paras_registrar.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_common::paras_registrar` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=runtime_common::paras_registrar // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/runtime_common_paras_registrar.rs +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/runtime_common_paras_registrar.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,175 +50,169 @@ use core::marker::PhantomData; /// Weight functions for `runtime_common::paras_registrar`. pub struct WeightInfo(PhantomData); impl runtime_common::paras_registrar::WeightInfo for WeightInfo { - /// Storage: Registrar NextFreeParaId (r:1 w:1) - /// Proof Skipped: Registrar NextFreeParaId (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Registrar Paras (r:1 w:1) - /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras ParaLifecycles (r:1 w:0) - /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: `Registrar::NextFreeParaId` (r:1 w:1) + /// Proof: `Registrar::NextFreeParaId` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Registrar::Paras` (r:1 w:1) + /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ParaLifecycles` (r:1 w:0) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) fn reserve() -> Weight { // Proof Size summary in bytes: - // Measured: `97` - // Estimated: `3562` - // Minimum execution time: 29_948_000 picoseconds. - Weight::from_parts(30_433_000, 0) - .saturating_add(Weight::from_parts(0, 3562)) + // Measured: `96` + // Estimated: `3561` + // Minimum execution time: 24_109_000 picoseconds. + Weight::from_parts(24_922_000, 0) + .saturating_add(Weight::from_parts(0, 3561)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Registrar Paras (r:1 w:1) - /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras ParaLifecycles (r:1 w:1) - /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras PvfActiveVoteMap (r:1 w:1) - /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras CodeByHash (r:1 w:1) - /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) - /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) - /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras PvfActiveVoteList (r:1 w:1) - /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras CodeByHashRefs (r:1 w:1) - /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras CurrentCodeHash (r:0 w:1) - /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras UpcomingParasGenesis (r:0 w:1) - /// Proof Skipped: Paras UpcomingParasGenesis (max_values: None, max_size: None, mode: Measured) + /// Storage: `Registrar::Paras` (r:1 w:1) + /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ParaLifecycles` (r:1 w:1) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CodeByHash` (r:1 w:1) + /// Proof: `Paras::CodeByHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) + /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteList` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CodeByHashRefs` (r:1 w:1) + /// Proof: `Paras::CodeByHashRefs` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CurrentCodeHash` (r:0 w:1) + /// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::UpcomingParasGenesis` (r:0 w:1) + /// Proof: `Paras::UpcomingParasGenesis` (`max_values`: None, `max_size`: None, mode: `Measured`) fn register() -> Weight { // Proof Size summary in bytes: - // Measured: `616` - // Estimated: `4081` - // Minimum execution time: 6_332_113_000 picoseconds. - Weight::from_parts(6_407_158_000, 0) - .saturating_add(Weight::from_parts(0, 4081)) - .saturating_add(T::DbWeight::get().reads(8)) + // Measured: `352` + // Estimated: `3817` + // Minimum execution time: 7_207_580_000 picoseconds. + Weight::from_parts(7_298_567_000, 0) + .saturating_add(Weight::from_parts(0, 3817)) + .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(8)) } - /// Storage: Registrar Paras (r:1 w:1) - /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras ParaLifecycles (r:1 w:1) - /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras PvfActiveVoteMap (r:1 w:1) - /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras CodeByHash (r:1 w:1) - /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) - /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) - /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras PvfActiveVoteList (r:1 w:1) - /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras CodeByHashRefs (r:1 w:1) - /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras CurrentCodeHash (r:0 w:1) - /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras UpcomingParasGenesis (r:0 w:1) - /// Proof Skipped: Paras UpcomingParasGenesis (max_values: None, max_size: None, mode: Measured) + /// Storage: `Registrar::Paras` (r:1 w:1) + /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ParaLifecycles` (r:1 w:1) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CodeByHash` (r:1 w:1) + /// Proof: `Paras::CodeByHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) + /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteList` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CodeByHashRefs` (r:1 w:1) + /// Proof: `Paras::CodeByHashRefs` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CurrentCodeHash` (r:0 w:1) + /// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::UpcomingParasGenesis` (r:0 w:1) + /// Proof: `Paras::UpcomingParasGenesis` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_register() -> Weight { // Proof Size summary in bytes: - // Measured: `533` - // Estimated: `3998` - // Minimum execution time: 6_245_403_000 picoseconds. - Weight::from_parts(6_289_575_000, 0) - .saturating_add(Weight::from_parts(0, 3998)) - .saturating_add(T::DbWeight::get().reads(8)) + // Measured: `269` + // Estimated: `3734` + // Minimum execution time: 7_196_460_000 picoseconds. + Weight::from_parts(7_385_729_000, 0) + .saturating_add(Weight::from_parts(0, 3734)) + .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(8)) } - /// Storage: Registrar Paras (r:1 w:1) - /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras ParaLifecycles (r:1 w:1) - /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras FutureCodeHash (r:1 w:0) - /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) - /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) - /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras ActionsQueue (r:1 w:1) - /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) - /// Storage: MessageQueue BookStateFor (r:1 w:0) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) - /// Storage: Registrar PendingSwap (r:0 w:1) - /// Proof Skipped: Registrar PendingSwap (max_values: None, max_size: None, mode: Measured) + /// Storage: `Registrar::Paras` (r:1 w:1) + /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ParaLifecycles` (r:1 w:1) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::FutureCodeHash` (r:1 w:0) + /// Proof: `Paras::FutureCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ActionsQueue` (r:1 w:1) + /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:0) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) + /// Storage: `Registrar::PendingSwap` (r:0 w:1) + /// Proof: `Registrar::PendingSwap` (`max_values`: None, `max_size`: None, mode: `Measured`) fn deregister() -> Weight { // Proof Size summary in bytes: - // Measured: `476` - // Estimated: `3941` - // Minimum execution time: 49_822_000 picoseconds. - Weight::from_parts(50_604_000, 0) - .saturating_add(Weight::from_parts(0, 3941)) + // Measured: `499` + // Estimated: `3964` + // Minimum execution time: 54_761_000 picoseconds. + Weight::from_parts(57_931_000, 0) + .saturating_add(Weight::from_parts(0, 3964)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: Registrar Paras (r:1 w:0) - /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras ParaLifecycles (r:2 w:2) - /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) - /// Storage: Registrar PendingSwap (r:1 w:1) - /// Proof Skipped: Registrar PendingSwap (max_values: None, max_size: None, mode: Measured) - /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) - /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras ActionsQueue (r:1 w:1) - /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) - /// Storage: Crowdloan Funds (r:2 w:2) - /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) - /// Storage: Slots Leases (r:2 w:2) - /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: `Registrar::Paras` (r:1 w:0) + /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ParaLifecycles` (r:2 w:2) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Registrar::PendingSwap` (r:1 w:1) + /// Proof: `Registrar::PendingSwap` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ActionsQueue` (r:1 w:1) + /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Crowdloan::Funds` (r:2 w:2) + /// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Slots::Leases` (r:2 w:2) + /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) fn swap() -> Weight { // Proof Size summary in bytes: - // Measured: `780` - // Estimated: `6720` - // Minimum execution time: 55_166_000 picoseconds. - Weight::from_parts(56_913_000, 0) - .saturating_add(Weight::from_parts(0, 6720)) + // Measured: `837` + // Estimated: `6777` + // Minimum execution time: 59_564_000 picoseconds. + Weight::from_parts(62_910_000, 0) + .saturating_add(Weight::from_parts(0, 6777)) .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(8)) } - /// Storage: Paras FutureCodeHash (r:1 w:1) - /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras UpgradeRestrictionSignal (r:1 w:1) - /// Proof Skipped: Paras UpgradeRestrictionSignal (max_values: None, max_size: None, mode: Measured) - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras CurrentCodeHash (r:1 w:0) - /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras UpgradeCooldowns (r:1 w:1) - /// Proof Skipped: Paras UpgradeCooldowns (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras PvfActiveVoteMap (r:1 w:1) - /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras CodeByHash (r:1 w:1) - /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) - /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) - /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras PvfActiveVoteList (r:1 w:1) - /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras CodeByHashRefs (r:1 w:1) - /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) - /// The range of component `b` is `[1, 3145728]`. + /// Storage: `Paras::FutureCodeHash` (r:1 w:1) + /// Proof: `Paras::FutureCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::UpgradeRestrictionSignal` (r:1 w:1) + /// Proof: `Paras::UpgradeRestrictionSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CurrentCodeHash` (r:1 w:0) + /// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::UpgradeCooldowns` (r:1 w:1) + /// Proof: `Paras::UpgradeCooldowns` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CodeByHash` (r:1 w:1) + /// Proof: `Paras::CodeByHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) + /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteList` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CodeByHashRefs` (r:1 w:1) + /// Proof: `Paras::CodeByHashRefs` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// The range of component `b` is `[9, 3145728]`. fn schedule_code_upgrade(b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `464` - // Estimated: `3929` - // Minimum execution time: 43_650_000 picoseconds. - Weight::from_parts(43_918_000, 0) - .saturating_add(Weight::from_parts(0, 3929)) - // Standard Error: 6 - .saturating_add(Weight::from_parts(2_041, 0).saturating_mul(b.into())) - .saturating_add(T::DbWeight::get().reads(10)) + // Measured: `201` + // Estimated: `3666` + // Minimum execution time: 33_106_000 picoseconds. + Weight::from_parts(33_526_000, 0) + .saturating_add(Weight::from_parts(0, 3666)) + // Standard Error: 2 + .saturating_add(Weight::from_parts(2_334, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(7)) } - /// Storage: Paras Heads (r:0 w:1) - /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// Storage: `Paras::Heads` (r:0 w:1) + /// Proof: `Paras::Heads` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `b` is `[1, 1048576]`. fn set_current_head(b: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_666_000 picoseconds. - Weight::from_parts(8_893_000, 0) + // Minimum execution time: 5_992_000 picoseconds. + Weight::from_parts(12_059_689, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 2 - .saturating_add(Weight::from_parts(855, 0).saturating_mul(b.into())) + // Standard Error: 0 + .saturating_add(Weight::from_parts(959, 0).saturating_mul(b.into())) .saturating_add(T::DbWeight::get().writes(1)) } } diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_slots.rs b/polkadot/runtime/rococo/src/weights/runtime_common_slots.rs index 23ab1ed3ee0..dd10dbbf1f1 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_common_slots.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_common_slots.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_common::slots` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=runtime_common::slots // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/runtime_common_slots.rs +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/runtime_common_slots.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,86 +50,82 @@ use core::marker::PhantomData; /// Weight functions for `runtime_common::slots`. pub struct WeightInfo(PhantomData); impl runtime_common::slots::WeightInfo for WeightInfo { - /// Storage: Slots Leases (r:1 w:1) - /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Slots::Leases` (r:1 w:1) + /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn force_lease() -> Weight { // Proof Size summary in bytes: - // Measured: `287` - // Estimated: `3752` - // Minimum execution time: 29_932_000 picoseconds. - Weight::from_parts(30_334_000, 0) - .saturating_add(Weight::from_parts(0, 3752)) + // Measured: `320` + // Estimated: `3785` + // Minimum execution time: 26_570_000 picoseconds. + Weight::from_parts(27_619_000, 0) + .saturating_add(Weight::from_parts(0, 3785)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: Paras Parachains (r:1 w:0) - /// Proof Skipped: Paras Parachains (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Slots Leases (r:101 w:100) - /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras ParaLifecycles (r:200 w:200) - /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) - /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) - /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras ActionsQueue (r:1 w:1) - /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) - /// Storage: Registrar Paras (r:100 w:100) - /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: `Paras::Parachains` (r:1 w:0) + /// Proof: `Paras::Parachains` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Slots::Leases` (r:101 w:100) + /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ParaLifecycles` (r:200 w:200) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ActionsQueue` (r:1 w:1) + /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `c` is `[0, 100]`. /// The range of component `t` is `[0, 100]`. fn manage_lease_period_start(c: u32, t: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `26 + c * (47 ±0) + t * (308 ±0)` - // Estimated: `2800 + c * (2526 ±0) + t * (2789 ±0)` - // Minimum execution time: 634_547_000 picoseconds. - Weight::from_parts(643_045_000, 0) - .saturating_add(Weight::from_parts(0, 2800)) - // Standard Error: 81_521 - .saturating_add(Weight::from_parts(2_705_219, 0).saturating_mul(c.into())) - // Standard Error: 81_521 - .saturating_add(Weight::from_parts(11_464_132, 0).saturating_mul(t.into())) + // Measured: `594 + c * (20 ±0) + t * (234 ±0)` + // Estimated: `4065 + c * (2496 ±0) + t * (2709 ±0)` + // Minimum execution time: 729_793_000 picoseconds. + Weight::from_parts(740_820_000, 0) + .saturating_add(Weight::from_parts(0, 4065)) + // Standard Error: 88_206 + .saturating_add(Weight::from_parts(2_793_142, 0).saturating_mul(c.into())) + // Standard Error: 88_206 + .saturating_add(Weight::from_parts(8_933_065, 0).saturating_mul(t.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) - .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(t.into()))) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) - .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(t.into()))) - .saturating_add(Weight::from_parts(0, 2526).saturating_mul(c.into())) - .saturating_add(Weight::from_parts(0, 2789).saturating_mul(t.into())) + .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(t.into()))) + .saturating_add(Weight::from_parts(0, 2496).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 2709).saturating_mul(t.into())) } - /// Storage: Slots Leases (r:1 w:1) - /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) - /// Storage: System Account (r:8 w:8) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Slots::Leases` (r:1 w:1) + /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:8 w:8) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn clear_all_leases() -> Weight { // Proof Size summary in bytes: - // Measured: `2759` + // Measured: `2792` // Estimated: `21814` - // Minimum execution time: 129_756_000 picoseconds. - Weight::from_parts(131_810_000, 0) + // Minimum execution time: 123_888_000 picoseconds. + Weight::from_parts(131_245_000, 0) .saturating_add(Weight::from_parts(0, 21814)) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(9)) } - /// Storage: Slots Leases (r:1 w:0) - /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras ParaLifecycles (r:1 w:1) - /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) - /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) - /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras ActionsQueue (r:1 w:1) - /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) - /// Storage: Registrar Paras (r:1 w:1) - /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: `Slots::Leases` (r:1 w:0) + /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ParaLifecycles` (r:1 w:1) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ActionsQueue` (r:1 w:1) + /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) fn trigger_onboard() -> Weight { // Proof Size summary in bytes: - // Measured: `707` - // Estimated: `4172` - // Minimum execution time: 29_527_000 picoseconds. - Weight::from_parts(30_055_000, 0) - .saturating_add(Weight::from_parts(0, 4172)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(3)) + // Measured: `612` + // Estimated: `4077` + // Minimum execution time: 27_341_000 picoseconds. + Weight::from_parts(28_697_000, 0) + .saturating_add(Weight::from_parts(0, 4077)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) } } diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_assigner_on_demand.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_assigner_on_demand.rs index ac0f05301b4..653e1009f31 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_parachains_assigner_on_demand.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_assigner_on_demand.rs @@ -16,26 +16,28 @@ //! Autogenerated weights for `runtime_parachains::assigner_on_demand` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-08-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-fljshgub-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/production/polkadot +// ./target/production/polkadot // benchmark // pallet +// --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::assigner_on_demand // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled -// --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json -// --pallet=runtime_parachains::assigner_on_demand -// --chain=rococo-dev -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/ +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_assigner_on_demand.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -57,13 +59,13 @@ impl runtime_parachains::assigner_on_demand::WeightInfo /// The range of component `s` is `[1, 9999]`. fn place_order_keep_alive(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `297 + s * (4 ±0)` - // Estimated: `3762 + s * (4 ±0)` - // Minimum execution time: 33_522_000 picoseconds. - Weight::from_parts(35_436_835, 0) - .saturating_add(Weight::from_parts(0, 3762)) - // Standard Error: 129 - .saturating_add(Weight::from_parts(14_041, 0).saturating_mul(s.into())) + // Measured: `363 + s * (4 ±0)` + // Estimated: `3828 + s * (4 ±0)` + // Minimum execution time: 25_298_000 picoseconds. + Weight::from_parts(21_486_098, 0) + .saturating_add(Weight::from_parts(0, 3828)) + // Standard Error: 136 + .saturating_add(Weight::from_parts(13_943, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) @@ -77,13 +79,13 @@ impl runtime_parachains::assigner_on_demand::WeightInfo /// The range of component `s` is `[1, 9999]`. fn place_order_allow_death(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `297 + s * (4 ±0)` - // Estimated: `3762 + s * (4 ±0)` - // Minimum execution time: 33_488_000 picoseconds. - Weight::from_parts(34_848_934, 0) - .saturating_add(Weight::from_parts(0, 3762)) - // Standard Error: 143 - .saturating_add(Weight::from_parts(14_215, 0).saturating_mul(s.into())) + // Measured: `363 + s * (4 ±0)` + // Estimated: `3828 + s * (4 ±0)` + // Minimum execution time: 25_421_000 picoseconds. + Weight::from_parts(21_828_043, 0) + .saturating_add(Weight::from_parts(0, 3828)) + // Standard Error: 133 + .saturating_add(Weight::from_parts(13_831, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs index ca0575cb1b6..caad090ae15 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs @@ -17,25 +17,27 @@ //! Autogenerated weights for `runtime_parachains::configuration` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/production/polkadot +// ./target/production/polkadot // benchmark // pallet +// --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --pallet=runtime_parachains::configuration // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled -// --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=runtime_parachains::configuration -// --chain=rococo-dev // --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -58,8 +60,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_789_000 picoseconds. - Weight::from_parts(8_269_000, 0) + // Minimum execution time: 7_689_000 picoseconds. + Weight::from_parts(8_089_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -74,8 +76,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_851_000 picoseconds. - Weight::from_parts(8_152_000, 0) + // Minimum execution time: 7_735_000 picoseconds. + Weight::from_parts(8_150_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -90,8 +92,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_960_000 picoseconds. - Weight::from_parts(8_276_000, 0) + // Minimum execution time: 7_902_000 picoseconds. + Weight::from_parts(8_196_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -116,8 +118,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_912_000 picoseconds. - Weight::from_parts(8_164_000, 0) + // Minimum execution time: 7_634_000 picoseconds. + Weight::from_parts(7_983_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -132,8 +134,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 9_782_000 picoseconds. - Weight::from_parts(10_373_000, 0) + // Minimum execution time: 9_580_000 picoseconds. + Weight::from_parts(9_989_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -148,8 +150,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_870_000 picoseconds. - Weight::from_parts(8_274_000, 0) + // Minimum execution time: 7_787_000 picoseconds. + Weight::from_parts(8_008_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -164,8 +166,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 9_960_000 picoseconds. - Weight::from_parts(10_514_000, 0) + // Minimum execution time: 9_557_000 picoseconds. + Weight::from_parts(9_994_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -180,8 +182,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_913_000 picoseconds. - Weight::from_parts(8_338_000, 0) + // Minimum execution time: 7_775_000 picoseconds. + Weight::from_parts(7_989_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_disputes.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_disputes.rs index 63a8c3addc7..cf1aa36e10e 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_parachains_disputes.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_disputes.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_parachains::disputes` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=runtime_parachains::disputes // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/runtime_parachains_disputes.rs +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_disputes.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,14 +50,14 @@ use core::marker::PhantomData; /// Weight functions for `runtime_parachains::disputes`. pub struct WeightInfo(PhantomData); impl runtime_parachains::disputes::WeightInfo for WeightInfo { - /// Storage: ParasDisputes Frozen (r:0 w:1) - /// Proof Skipped: ParasDisputes Frozen (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `ParasDisputes::Frozen` (r:0 w:1) + /// Proof: `ParasDisputes::Frozen` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn force_unfreeze() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_937_000 picoseconds. - Weight::from_parts(3_082_000, 0) + // Minimum execution time: 1_855_000 picoseconds. + Weight::from_parts(2_015_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_hrmp.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_hrmp.rs index 417820e6627..a3b912491e5 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_parachains_hrmp.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_hrmp.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_parachains::hrmp` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=runtime_parachains::hrmp // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/runtime_parachains_hrmp.rs +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_hrmp.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,105 +50,97 @@ use core::marker::PhantomData; /// Weight functions for `runtime_parachains::hrmp`. pub struct WeightInfo(PhantomData); impl runtime_parachains::hrmp::WeightInfo for WeightInfo { - /// Storage: Paras ParaLifecycles (r:2 w:0) - /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) - /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpChannels (r:1 w:0) - /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:0) - /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) - /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) - /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Dmp DownwardMessageQueues (r:1 w:1) - /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) - /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) - /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + /// Storage: `Paras::ParaLifecycles` (r:1 w:0) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpOpenChannelRequests` (r:1 w:1) + /// Proof: `Hrmp::HrmpOpenChannelRequests` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpChannels` (r:1 w:0) + /// Proof: `Hrmp::HrmpChannels` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpEgressChannelsIndex` (r:1 w:0) + /// Proof: `Hrmp::HrmpEgressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpOpenChannelRequestCount` (r:1 w:1) + /// Proof: `Hrmp::HrmpOpenChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpOpenChannelRequestsList` (r:1 w:1) + /// Proof: `Hrmp::HrmpOpenChannelRequestsList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn hrmp_init_open_channel() -> Weight { // Proof Size summary in bytes: - // Measured: `704` - // Estimated: `6644` - // Minimum execution time: 41_564_000 picoseconds. - Weight::from_parts(42_048_000, 0) - .saturating_add(Weight::from_parts(0, 6644)) - .saturating_add(T::DbWeight::get().reads(10)) + // Measured: `488` + // Estimated: `3953` + // Minimum execution time: 34_911_000 picoseconds. + Weight::from_parts(35_762_000, 0) + .saturating_add(Weight::from_parts(0, 3953)) + .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(5)) } - /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) - /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras ParaLifecycles (r:1 w:0) - /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpIngressChannelsIndex (r:1 w:0) - /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:1 w:1) - /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) - /// Storage: Dmp DownwardMessageQueues (r:1 w:1) - /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) - /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) - /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + /// Storage: `Hrmp::HrmpOpenChannelRequests` (r:1 w:1) + /// Proof: `Hrmp::HrmpOpenChannelRequests` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpIngressChannelsIndex` (r:1 w:0) + /// Proof: `Hrmp::HrmpIngressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpAcceptedChannelRequestCount` (r:1 w:1) + /// Proof: `Hrmp::HrmpAcceptedChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn hrmp_accept_open_channel() -> Weight { // Proof Size summary in bytes: - // Measured: `936` - // Estimated: `4401` - // Minimum execution time: 43_570_000 picoseconds. - Weight::from_parts(44_089_000, 0) - .saturating_add(Weight::from_parts(0, 4401)) - .saturating_add(T::DbWeight::get().reads(7)) + // Measured: `478` + // Estimated: `3943` + // Minimum execution time: 31_483_000 picoseconds. + Weight::from_parts(32_230_000, 0) + .saturating_add(Weight::from_parts(0, 3943)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: Hrmp HrmpChannels (r:1 w:0) - /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpCloseChannelRequests (r:1 w:1) - /// Proof Skipped: Hrmp HrmpCloseChannelRequests (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:1) - /// Proof Skipped: Hrmp HrmpCloseChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Dmp DownwardMessageQueues (r:1 w:1) - /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) - /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) - /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + /// Storage: `Hrmp::HrmpChannels` (r:1 w:0) + /// Proof: `Hrmp::HrmpChannels` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpCloseChannelRequests` (r:1 w:1) + /// Proof: `Hrmp::HrmpCloseChannelRequests` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpCloseChannelRequestsList` (r:1 w:1) + /// Proof: `Hrmp::HrmpCloseChannelRequestsList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn hrmp_close_channel() -> Weight { // Proof Size summary in bytes: - // Measured: `807` - // Estimated: `4272` - // Minimum execution time: 36_594_000 picoseconds. - Weight::from_parts(37_090_000, 0) - .saturating_add(Weight::from_parts(0, 4272)) - .saturating_add(T::DbWeight::get().reads(6)) + // Measured: `591` + // Estimated: `4056` + // Minimum execution time: 32_153_000 picoseconds. + Weight::from_parts(32_982_000, 0) + .saturating_add(Weight::from_parts(0, 4056)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:128) - /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpEgressChannelsIndex (r:128 w:128) - /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpChannels (r:254 w:254) - /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:0 w:1) - /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpChannelContents (r:0 w:254) - /// Proof Skipped: Hrmp HrmpChannelContents (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpOpenChannelRequestCount (r:0 w:1) - /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: `Hrmp::HrmpIngressChannelsIndex` (r:128 w:128) + /// Proof: `Hrmp::HrmpIngressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpEgressChannelsIndex` (r:128 w:128) + /// Proof: `Hrmp::HrmpEgressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpChannels` (r:254 w:254) + /// Proof: `Hrmp::HrmpChannels` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpAcceptedChannelRequestCount` (r:0 w:1) + /// Proof: `Hrmp::HrmpAcceptedChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpChannelContents` (r:0 w:254) + /// Proof: `Hrmp::HrmpChannelContents` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpOpenChannelRequestCount` (r:0 w:1) + /// Proof: `Hrmp::HrmpOpenChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `i` is `[0, 127]`. /// The range of component `e` is `[0, 127]`. fn force_clean_hrmp(i: u32, e: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `264 + e * (100 ±0) + i * (100 ±0)` - // Estimated: `3726 + e * (2575 ±0) + i * (2575 ±0)` - // Minimum execution time: 1_085_140_000 picoseconds. - Weight::from_parts(1_100_901_000, 0) - .saturating_add(Weight::from_parts(0, 3726)) - // Standard Error: 98_982 - .saturating_add(Weight::from_parts(3_229_112, 0).saturating_mul(i.into())) - // Standard Error: 98_982 - .saturating_add(Weight::from_parts(3_210_944, 0).saturating_mul(e.into())) + // Measured: `297 + e * (100 ±0) + i * (100 ±0)` + // Estimated: `3759 + e * (2575 ±0) + i * (2575 ±0)` + // Minimum execution time: 1_240_769_000 picoseconds. + Weight::from_parts(1_249_285_000, 0) + .saturating_add(Weight::from_parts(0, 3759)) + // Standard Error: 112_346 + .saturating_add(Weight::from_parts(3_449_114, 0).saturating_mul(i.into())) + // Standard Error: 112_346 + .saturating_add(Weight::from_parts(3_569_184, 0).saturating_mul(e.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(i.into()))) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(e.into()))) @@ -155,139 +150,139 @@ impl runtime_parachains::hrmp::WeightInfo for WeightInf .saturating_add(Weight::from_parts(0, 2575).saturating_mul(e.into())) .saturating_add(Weight::from_parts(0, 2575).saturating_mul(i.into())) } - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) - /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Hrmp HrmpOpenChannelRequests (r:128 w:128) - /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras ParaLifecycles (r:256 w:0) - /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:128) - /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpEgressChannelsIndex (r:128 w:128) - /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpOpenChannelRequestCount (r:128 w:128) - /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:128 w:128) - /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpChannels (r:0 w:128) - /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: `Hrmp::HrmpOpenChannelRequestsList` (r:1 w:1) + /// Proof: `Hrmp::HrmpOpenChannelRequestsList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpOpenChannelRequests` (r:128 w:128) + /// Proof: `Hrmp::HrmpOpenChannelRequests` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ParaLifecycles` (r:256 w:0) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpIngressChannelsIndex` (r:128 w:128) + /// Proof: `Hrmp::HrmpIngressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpEgressChannelsIndex` (r:128 w:128) + /// Proof: `Hrmp::HrmpEgressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpOpenChannelRequestCount` (r:128 w:128) + /// Proof: `Hrmp::HrmpOpenChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpAcceptedChannelRequestCount` (r:128 w:128) + /// Proof: `Hrmp::HrmpAcceptedChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpChannels` (r:0 w:128) + /// Proof: `Hrmp::HrmpChannels` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `c` is `[0, 128]`. fn force_process_hrmp_open(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `779 + c * (136 ±0)` - // Estimated: `2234 + c * (5086 ±0)` - // Minimum execution time: 10_497_000 picoseconds. - Weight::from_parts(6_987_455, 0) - .saturating_add(Weight::from_parts(0, 2234)) - // Standard Error: 18_540 - .saturating_add(Weight::from_parts(18_788_534, 0).saturating_mul(c.into())) - .saturating_add(T::DbWeight::get().reads(2)) + // Measured: `525 + c * (136 ±0)` + // Estimated: `1980 + c * (5086 ±0)` + // Minimum execution time: 6_026_000 picoseconds. + Weight::from_parts(6_257_000, 0) + .saturating_add(Weight::from_parts(0, 1980)) + // Standard Error: 9_732 + .saturating_add(Weight::from_parts(21_049_890, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads((7_u64).saturating_mul(c.into()))) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes((6_u64).saturating_mul(c.into()))) .saturating_add(Weight::from_parts(0, 5086).saturating_mul(c.into())) } - /// Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:1) - /// Proof Skipped: Hrmp HrmpCloseChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Hrmp HrmpChannels (r:128 w:128) - /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpEgressChannelsIndex (r:128 w:128) - /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:128) - /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpCloseChannelRequests (r:0 w:128) - /// Proof Skipped: Hrmp HrmpCloseChannelRequests (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpChannelContents (r:0 w:128) - /// Proof Skipped: Hrmp HrmpChannelContents (max_values: None, max_size: None, mode: Measured) + /// Storage: `Hrmp::HrmpCloseChannelRequestsList` (r:1 w:1) + /// Proof: `Hrmp::HrmpCloseChannelRequestsList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpChannels` (r:128 w:128) + /// Proof: `Hrmp::HrmpChannels` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpEgressChannelsIndex` (r:128 w:128) + /// Proof: `Hrmp::HrmpEgressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpIngressChannelsIndex` (r:128 w:128) + /// Proof: `Hrmp::HrmpIngressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpCloseChannelRequests` (r:0 w:128) + /// Proof: `Hrmp::HrmpCloseChannelRequests` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpChannelContents` (r:0 w:128) + /// Proof: `Hrmp::HrmpChannelContents` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `c` is `[0, 128]`. fn force_process_hrmp_close(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `335 + c * (124 ±0)` - // Estimated: `1795 + c * (2600 ±0)` - // Minimum execution time: 6_575_000 picoseconds. - Weight::from_parts(1_228_642, 0) - .saturating_add(Weight::from_parts(0, 1795)) - // Standard Error: 14_826 - .saturating_add(Weight::from_parts(11_604_038, 0).saturating_mul(c.into())) + // Measured: `368 + c * (124 ±0)` + // Estimated: `1828 + c * (2600 ±0)` + // Minimum execution time: 4_991_000 picoseconds. + Weight::from_parts(984_758, 0) + .saturating_add(Weight::from_parts(0, 1828)) + // Standard Error: 11_918 + .saturating_add(Weight::from_parts(13_018_813, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(c.into()))) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes((5_u64).saturating_mul(c.into()))) .saturating_add(Weight::from_parts(0, 2600).saturating_mul(c.into())) } - /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) - /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) - /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) - /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: `Hrmp::HrmpOpenChannelRequestsList` (r:1 w:1) + /// Proof: `Hrmp::HrmpOpenChannelRequestsList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpOpenChannelRequests` (r:1 w:1) + /// Proof: `Hrmp::HrmpOpenChannelRequests` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpOpenChannelRequestCount` (r:1 w:1) + /// Proof: `Hrmp::HrmpOpenChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `c` is `[0, 128]`. fn hrmp_cancel_open_request(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1026 + c * (13 ±0)` - // Estimated: `4295 + c * (15 ±0)` - // Minimum execution time: 22_301_000 picoseconds. - Weight::from_parts(26_131_473, 0) - .saturating_add(Weight::from_parts(0, 4295)) - // Standard Error: 830 - .saturating_add(Weight::from_parts(49_448, 0).saturating_mul(c.into())) + // Measured: `1059 + c * (13 ±0)` + // Estimated: `4328 + c * (15 ±0)` + // Minimum execution time: 17_299_000 picoseconds. + Weight::from_parts(27_621_478, 0) + .saturating_add(Weight::from_parts(0, 4328)) + // Standard Error: 2_527 + .saturating_add(Weight::from_parts(121_149, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(Weight::from_parts(0, 15).saturating_mul(c.into())) } - /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) - /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Hrmp HrmpOpenChannelRequests (r:128 w:128) - /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: `Hrmp::HrmpOpenChannelRequestsList` (r:1 w:1) + /// Proof: `Hrmp::HrmpOpenChannelRequestsList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpOpenChannelRequests` (r:128 w:128) + /// Proof: `Hrmp::HrmpOpenChannelRequests` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `c` is `[0, 128]`. fn clean_open_channel_requests(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `243 + c * (63 ±0)` - // Estimated: `1722 + c * (2538 ±0)` - // Minimum execution time: 5_234_000 picoseconds. - Weight::from_parts(7_350_270, 0) - .saturating_add(Weight::from_parts(0, 1722)) - // Standard Error: 3_105 - .saturating_add(Weight::from_parts(2_981_935, 0).saturating_mul(c.into())) + // Measured: `276 + c * (63 ±0)` + // Estimated: `1755 + c * (2538 ±0)` + // Minimum execution time: 3_764_000 picoseconds. + Weight::from_parts(5_935_301, 0) + .saturating_add(Weight::from_parts(0, 1755)) + // Standard Error: 3_761 + .saturating_add(Weight::from_parts(3_290_277, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) .saturating_add(Weight::from_parts(0, 2538).saturating_mul(c.into())) } - /// Storage: Paras ParaLifecycles (r:2 w:0) - /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) - /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpChannels (r:1 w:0) - /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:0) - /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) - /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) - /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Dmp DownwardMessageQueues (r:2 w:2) - /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) - /// Storage: Dmp DownwardMessageQueueHeads (r:2 w:2) - /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpIngressChannelsIndex (r:1 w:0) - /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) - /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:1 w:1) - /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) - fn force_open_hrmp_channel(_c: u32, ) -> Weight { + /// Storage: `Hrmp::HrmpOpenChannelRequests` (r:1 w:1) + /// Proof: `Hrmp::HrmpOpenChannelRequests` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpOpenChannelRequestsList` (r:1 w:1) + /// Proof: `Hrmp::HrmpOpenChannelRequestsList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpOpenChannelRequestCount` (r:1 w:1) + /// Proof: `Hrmp::HrmpOpenChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ParaLifecycles` (r:1 w:0) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpChannels` (r:1 w:0) + /// Proof: `Hrmp::HrmpChannels` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpEgressChannelsIndex` (r:1 w:0) + /// Proof: `Hrmp::HrmpEgressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:2 w:2) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:2 w:2) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpIngressChannelsIndex` (r:1 w:0) + /// Proof: `Hrmp::HrmpIngressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpAcceptedChannelRequestCount` (r:1 w:1) + /// Proof: `Hrmp::HrmpAcceptedChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// The range of component `c` is `[0, 1]`. + fn force_open_hrmp_channel(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `704` - // Estimated: `6644` - // Minimum execution time: 55_611_000 picoseconds. - Weight::from_parts(56_488_000, 0) - .saturating_add(Weight::from_parts(0, 6644)) - .saturating_add(T::DbWeight::get().reads(14)) + // Measured: `488 + c * (235 ±0)` + // Estimated: `6428 + c * (235 ±0)` + // Minimum execution time: 49_506_000 picoseconds. + Weight::from_parts(51_253_075, 0) + .saturating_add(Weight::from_parts(0, 6428)) + // Standard Error: 144_082 + .saturating_add(Weight::from_parts(12_862_224, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(12)) .saturating_add(T::DbWeight::get().writes(8)) + .saturating_add(Weight::from_parts(0, 235).saturating_mul(c.into())) } /// Storage: `Paras::ParaLifecycles` (r:1 w:0) /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -311,11 +306,11 @@ impl runtime_parachains::hrmp::WeightInfo for WeightInf /// Proof: `Hrmp::HrmpAcceptedChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) fn establish_system_channel() -> Weight { // Proof Size summary in bytes: - // Measured: `417` - // Estimated: `6357` - // Minimum execution time: 629_674_000 picoseconds. - Weight::from_parts(640_174_000, 0) - .saturating_add(Weight::from_parts(0, 6357)) + // Measured: `488` + // Estimated: `6428` + // Minimum execution time: 50_016_000 picoseconds. + Weight::from_parts(50_933_000, 0) + .saturating_add(Weight::from_parts(0, 6428)) .saturating_add(T::DbWeight::get().reads(12)) .saturating_add(T::DbWeight::get().writes(8)) } @@ -323,11 +318,11 @@ impl runtime_parachains::hrmp::WeightInfo for WeightInf /// Proof: `Hrmp::HrmpChannels` (`max_values`: None, `max_size`: None, mode: `Measured`) fn poke_channel_deposits() -> Weight { // Proof Size summary in bytes: - // Measured: `263` - // Estimated: `3728` - // Minimum execution time: 173_371_000 picoseconds. - Weight::from_parts(175_860_000, 0) - .saturating_add(Weight::from_parts(0, 3728)) + // Measured: `296` + // Estimated: `3761` + // Minimum execution time: 12_280_000 picoseconds. + Weight::from_parts(12_863_000, 0) + .saturating_add(Weight::from_parts(0, 3761)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_inclusion.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_inclusion.rs index a121ad774ce..b9ec7565bd5 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_parachains_inclusion.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_inclusion.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_parachains::inclusion` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=runtime_parachains::inclusion // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/runtime_parachains_inclusion.rs +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_inclusion.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,27 +50,25 @@ use core::marker::PhantomData; /// Weight functions for `runtime_parachains::inclusion`. pub struct WeightInfo(PhantomData); impl runtime_parachains::inclusion::WeightInfo for WeightInfo { - /// Storage: MessageQueue BookStateFor (r:1 w:1) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) - /// Storage: MessageQueue Pages (r:1 w:999) - /// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen) - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) - /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:1 w:999) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) /// The range of component `i` is `[1, 1000]`. fn receive_upward_messages(i: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `33280` + // Measured: `32993` // Estimated: `36283` - // Minimum execution time: 71_094_000 picoseconds. - Weight::from_parts(71_436_000, 0) + // Minimum execution time: 72_675_000 picoseconds. + Weight::from_parts(73_290_000, 0) .saturating_add(Weight::from_parts(0, 36283)) - // Standard Error: 22_149 - .saturating_add(Weight::from_parts(51_495_472, 0).saturating_mul(i.into())) - .saturating_add(T::DbWeight::get().reads(3)) + // Standard Error: 16_067 + .saturating_add(Weight::from_parts(57_735_739, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) } diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_initializer.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_initializer.rs index 5c627507dfb..e8c554610c9 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_parachains_initializer.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_initializer.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_parachains::initializer` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=runtime_parachains::initializer // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/runtime_parachains_initializer.rs +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_initializer.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,18 +50,18 @@ use core::marker::PhantomData; /// Weight functions for `runtime_parachains::initializer`. pub struct WeightInfo(PhantomData); impl runtime_parachains::initializer::WeightInfo for WeightInfo { - /// Storage: System Digest (r:1 w:1) - /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `System::Digest` (r:1 w:1) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `d` is `[0, 65536]`. fn force_approve(d: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + d * (11 ±0)` // Estimated: `1480 + d * (11 ±0)` - // Minimum execution time: 3_771_000 picoseconds. - Weight::from_parts(6_491_437, 0) + // Minimum execution time: 2_634_000 picoseconds. + Weight::from_parts(2_728_000, 0) .saturating_add(Weight::from_parts(0, 1480)) - // Standard Error: 9 - .saturating_add(Weight::from_parts(1_356, 0).saturating_mul(d.into())) + // Standard Error: 19 + .saturating_add(Weight::from_parts(2_499, 0).saturating_mul(d.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(Weight::from_parts(0, 11).saturating_mul(d.into())) diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_paras.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_paras.rs index dfd95006dc7..af26bfc9ae9 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_parachains_paras.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_paras.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_parachains::paras` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,12 +29,15 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=runtime_parachains::paras // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./file_header.txt -// --output=./runtime/rococo/src/weights/runtime_parachains_paras.rs +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_paras.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,247 +50,248 @@ use core::marker::PhantomData; /// Weight functions for `runtime_parachains::paras`. pub struct WeightInfo(PhantomData); impl runtime_parachains::paras::WeightInfo for WeightInfo { - /// Storage: Paras CurrentCodeHash (r:1 w:1) - /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras CodeByHashRefs (r:1 w:1) - /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras PastCodeMeta (r:1 w:1) - /// Proof Skipped: Paras PastCodeMeta (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras PastCodePruning (r:1 w:1) - /// Proof Skipped: Paras PastCodePruning (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras PastCodeHash (r:0 w:1) - /// Proof Skipped: Paras PastCodeHash (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras CodeByHash (r:0 w:1) - /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: `Paras::CurrentCodeHash` (r:1 w:1) + /// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CodeByHashRefs` (r:1 w:1) + /// Proof: `Paras::CodeByHashRefs` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PastCodeMeta` (r:1 w:1) + /// Proof: `Paras::PastCodeMeta` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PastCodePruning` (r:1 w:1) + /// Proof: `Paras::PastCodePruning` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PastCodeHash` (r:0 w:1) + /// Proof: `Paras::PastCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CodeByHash` (r:0 w:1) + /// Proof: `Paras::CodeByHash` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `c` is `[1, 3145728]`. fn force_set_current_code(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `8309` // Estimated: `11774` - // Minimum execution time: 31_941_000 picoseconds. - Weight::from_parts(32_139_000, 0) + // Minimum execution time: 27_488_000 picoseconds. + Weight::from_parts(27_810_000, 0) .saturating_add(Weight::from_parts(0, 11774)) - // Standard Error: 5 - .saturating_add(Weight::from_parts(2_011, 0).saturating_mul(c.into())) + // Standard Error: 8 + .saturating_add(Weight::from_parts(2_189, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(6)) } - /// Storage: Paras Heads (r:0 w:1) - /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// Storage: `Paras::Heads` (r:0 w:1) + /// Proof: `Paras::Heads` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `s` is `[1, 1048576]`. fn force_set_current_head(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_275_000 picoseconds. - Weight::from_parts(8_321_000, 0) + // Minimum execution time: 5_793_000 picoseconds. + Weight::from_parts(7_987_606, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 2 - .saturating_add(Weight::from_parts(858, 0).saturating_mul(s.into())) + // Standard Error: 1 + .saturating_add(Weight::from_parts(971, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().writes(1)) } - // Storage: Paras Heads (r:0 w:1) + /// Storage: `Paras::MostRecentContext` (r:0 w:1) + /// Proof: `Paras::MostRecentContext` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_set_most_recent_context() -> Weight { - Weight::from_parts(10_155_000, 0) - // Standard Error: 0 - .saturating_add(T::DbWeight::get().writes(1 as u64)) + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_733_000 picoseconds. + Weight::from_parts(2_954_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras FutureCodeHash (r:1 w:1) - /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras CurrentCodeHash (r:1 w:0) - /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras UpgradeCooldowns (r:1 w:1) - /// Proof Skipped: Paras UpgradeCooldowns (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras PvfActiveVoteMap (r:1 w:1) - /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras CodeByHash (r:1 w:1) - /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) - /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) - /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras PvfActiveVoteList (r:1 w:1) - /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras CodeByHashRefs (r:1 w:1) - /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras UpgradeRestrictionSignal (r:0 w:1) - /// Proof Skipped: Paras UpgradeRestrictionSignal (max_values: None, max_size: None, mode: Measured) + /// Storage: `Paras::FutureCodeHash` (r:1 w:1) + /// Proof: `Paras::FutureCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CurrentCodeHash` (r:1 w:0) + /// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::UpgradeCooldowns` (r:1 w:1) + /// Proof: `Paras::UpgradeCooldowns` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CodeByHash` (r:1 w:1) + /// Proof: `Paras::CodeByHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) + /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteList` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CodeByHashRefs` (r:1 w:1) + /// Proof: `Paras::CodeByHashRefs` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::UpgradeRestrictionSignal` (r:0 w:1) + /// Proof: `Paras::UpgradeRestrictionSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `c` is `[1, 3145728]`. fn force_schedule_code_upgrade(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `8715` - // Estimated: `12180` - // Minimum execution time: 49_923_000 picoseconds. - Weight::from_parts(50_688_000, 0) - .saturating_add(Weight::from_parts(0, 12180)) - // Standard Error: 1 - .saturating_add(Weight::from_parts(1_976, 0).saturating_mul(c.into())) - .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(7)) + // Measured: `8452` + // Estimated: `11917` + // Minimum execution time: 6_072_000 picoseconds. + Weight::from_parts(6_128_000, 0) + .saturating_add(Weight::from_parts(0, 11917)) + // Standard Error: 2 + .saturating_add(Weight::from_parts(2_334, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(6)) } - /// Storage: Paras FutureCodeUpgrades (r:1 w:0) - /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras Heads (r:0 w:1) - /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras UpgradeGoAheadSignal (r:0 w:1) - /// Proof Skipped: Paras UpgradeGoAheadSignal (max_values: None, max_size: None, mode: Measured) + /// Storage: `Paras::FutureCodeUpgrades` (r:1 w:0) + /// Proof: `Paras::FutureCodeUpgrades` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Registrar::Paras` (r:1 w:0) + /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::Heads` (r:0 w:1) + /// Proof: `Paras::Heads` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::UpgradeGoAheadSignal` (r:0 w:1) + /// Proof: `Paras::UpgradeGoAheadSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::MostRecentContext` (r:0 w:1) + /// Proof: `Paras::MostRecentContext` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `s` is `[1, 1048576]`. fn force_note_new_head(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `95` - // Estimated: `3560` - // Minimum execution time: 14_408_000 picoseconds. - Weight::from_parts(14_647_000, 0) - .saturating_add(Weight::from_parts(0, 3560)) - // Standard Error: 2 - .saturating_add(Weight::from_parts(858, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `163` + // Estimated: `3628` + // Minimum execution time: 15_166_000 picoseconds. + Weight::from_parts(21_398_053, 0) + .saturating_add(Weight::from_parts(0, 3628)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(976, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) - /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras ActionsQueue (r:1 w:1) - /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ActionsQueue` (r:1 w:1) + /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_queue_action() -> Weight { // Proof Size summary in bytes: - // Measured: `4288` - // Estimated: `7753` - // Minimum execution time: 20_009_000 picoseconds. - Weight::from_parts(20_518_000, 0) - .saturating_add(Weight::from_parts(0, 7753)) + // Measured: `4312` + // Estimated: `7777` + // Minimum execution time: 16_345_000 picoseconds. + Weight::from_parts(16_712_000, 0) + .saturating_add(Weight::from_parts(0, 7777)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: Paras PvfActiveVoteMap (r:1 w:1) - /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras PvfActiveVoteList (r:1 w:1) - /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) - /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras ActionsQueue (r:1 w:1) - /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteList` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ActionsQueue` (r:1 w:1) + /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `c` is `[1, 3145728]`. fn add_trusted_validation_code(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `946` - // Estimated: `4411` - // Minimum execution time: 80_626_000 picoseconds. - Weight::from_parts(52_721_755, 0) - .saturating_add(Weight::from_parts(0, 4411)) - // Standard Error: 1 - .saturating_add(Weight::from_parts(1_443, 0).saturating_mul(c.into())) - .saturating_add(T::DbWeight::get().reads(5)) + // Measured: `683` + // Estimated: `4148` + // Minimum execution time: 78_076_000 picoseconds. + Weight::from_parts(123_193_814, 0) + .saturating_add(Weight::from_parts(0, 4148)) + // Standard Error: 5 + .saturating_add(Weight::from_parts(1_770, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: Paras CodeByHashRefs (r:1 w:0) - /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras CodeByHash (r:0 w:1) - /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: `Paras::CodeByHashRefs` (r:1 w:0) + /// Proof: `Paras::CodeByHashRefs` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CodeByHash` (r:0 w:1) + /// Proof: `Paras::CodeByHash` (`max_values`: None, `max_size`: None, mode: `Measured`) fn poke_unused_validation_code() -> Weight { // Proof Size summary in bytes: // Measured: `28` // Estimated: `3493` - // Minimum execution time: 6_692_000 picoseconds. - Weight::from_parts(7_009_000, 0) + // Minimum execution time: 5_184_000 picoseconds. + Weight::from_parts(5_430_000, 0) .saturating_add(Weight::from_parts(0, 3493)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) - /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) - /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras PvfActiveVoteMap (r:1 w:1) - /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) + /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) fn include_pvf_check_statement() -> Weight { // Proof Size summary in bytes: - // Measured: `26682` - // Estimated: `30147` - // Minimum execution time: 87_994_000 picoseconds. - Weight::from_parts(89_933_000, 0) - .saturating_add(Weight::from_parts(0, 30147)) + // Measured: `26706` + // Estimated: `30171` + // Minimum execution time: 102_995_000 picoseconds. + Weight::from_parts(108_977_000, 0) + .saturating_add(Weight::from_parts(0, 30171)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) - /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) - /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras PvfActiveVoteMap (r:1 w:1) - /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras PvfActiveVoteList (r:1 w:1) - /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras UpcomingUpgrades (r:1 w:1) - /// Proof Skipped: Paras UpcomingUpgrades (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: System Digest (r:1 w:1) - /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras FutureCodeUpgrades (r:0 w:100) - /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) + /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteList` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::UpcomingUpgrades` (r:1 w:1) + /// Proof: `Paras::UpcomingUpgrades` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Digest` (r:1 w:1) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::FutureCodeUpgrades` (r:0 w:100) + /// Proof: `Paras::FutureCodeUpgrades` (`max_values`: None, `max_size`: None, mode: `Measured`) fn include_pvf_check_statement_finalize_upgrade_accept() -> Weight { // Proof Size summary in bytes: - // Measured: `27523` - // Estimated: `30988` - // Minimum execution time: 783_222_000 picoseconds. - Weight::from_parts(794_959_000, 0) - .saturating_add(Weight::from_parts(0, 30988)) - .saturating_add(T::DbWeight::get().reads(7)) + // Measured: `27360` + // Estimated: `30825` + // Minimum execution time: 709_433_000 picoseconds. + Weight::from_parts(725_074_000, 0) + .saturating_add(Weight::from_parts(0, 30825)) + .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(104)) } - /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) - /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) - /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras PvfActiveVoteMap (r:1 w:1) - /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) + /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) fn include_pvf_check_statement_finalize_upgrade_reject() -> Weight { // Proof Size summary in bytes: - // Measured: `27214` - // Estimated: `30679` - // Minimum execution time: 87_424_000 picoseconds. - Weight::from_parts(88_737_000, 0) - .saturating_add(Weight::from_parts(0, 30679)) + // Measured: `27338` + // Estimated: `30803` + // Minimum execution time: 98_973_000 picoseconds. + Weight::from_parts(104_715_000, 0) + .saturating_add(Weight::from_parts(0, 30803)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) - /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) - /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras PvfActiveVoteMap (r:1 w:1) - /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) - /// Storage: Paras PvfActiveVoteList (r:1 w:1) - /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Configuration ActiveConfig (r:1 w:0) - /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras ActionsQueue (r:1 w:1) - /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) + /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteList` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ActionsQueue` (r:1 w:1) + /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) fn include_pvf_check_statement_finalize_onboarding_accept() -> Weight { // Proof Size summary in bytes: - // Measured: `26991` - // Estimated: `30456` - // Minimum execution time: 612_485_000 picoseconds. - Weight::from_parts(621_670_000, 0) - .saturating_add(Weight::from_parts(0, 30456)) - .saturating_add(T::DbWeight::get().reads(6)) + // Measured: `26728` + // Estimated: `30193` + // Minimum execution time: 550_958_000 picoseconds. + Weight::from_parts(564_497_000, 0) + .saturating_add(Weight::from_parts(0, 30193)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) - /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) - /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Paras PvfActiveVoteMap (r:1 w:1) - /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) + /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) + /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) fn include_pvf_check_statement_finalize_onboarding_reject() -> Weight { // Proof Size summary in bytes: - // Measured: `26682` - // Estimated: `30147` - // Minimum execution time: 86_673_000 picoseconds. - Weight::from_parts(87_424_000, 0) - .saturating_add(Weight::from_parts(0, 30147)) + // Measured: `26706` + // Estimated: `30171` + // Minimum execution time: 97_088_000 picoseconds. + Weight::from_parts(103_617_000, 0) + .saturating_add(Weight::from_parts(0, 30171)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_paras_inherent.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_paras_inherent.rs index a102d1903b2..374927f8470 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_parachains_paras_inherent.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_paras_inherent.rs @@ -13,161 +13,334 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . + //! Autogenerated weights for `runtime_parachains::paras_inherent` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2021-11-20, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 128 +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot +// ./target/production/polkadot // benchmark +// pallet // --chain=rococo-dev // --steps=50 // --repeat=20 +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --pallet=runtime_parachains::paras_inherent // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --heap-pages=4096 -// --output=./runtime/rococo/src/weights/runtime_parachains_paras_inherent.rs -// --header=./file_header.txt +// --header=./polkadot/file_header.txt +// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_paras_inherent.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] +#![allow(missing_docs)] use frame_support::{traits::Get, weights::Weight}; -use sp_std::marker::PhantomData; +use core::marker::PhantomData; /// Weight functions for `runtime_parachains::paras_inherent`. pub struct WeightInfo(PhantomData); impl runtime_parachains::paras_inherent::WeightInfo for WeightInfo { - // Storage: ParaInherent Included (r:1 w:1) - // Storage: System ParentHash (r:1 w:0) - // Storage: ParaScheduler AvailabilityCores (r:1 w:1) - // Storage: ParasShared CurrentSessionIndex (r:1 w:0) - // Storage: Configuration ActiveConfig (r:1 w:0) - // Storage: ParaSessionInfo Sessions (r:1 w:0) - // Storage: ParasDisputes Disputes (r:1 w:1) - // Storage: ParasDisputes Included (r:1 w:1) - // Storage: ParasDisputes SpamSlots (r:1 w:1) - // Storage: ParasDisputes Frozen (r:1 w:0) - // Storage: ParaInclusion PendingAvailability (r:2 w:1) - // Storage: ParasShared ActiveValidatorKeys (r:1 w:0) - // Storage: Paras Parachains (r:1 w:0) - // Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) - // Storage: Dmp DownwardMessageQueues (r:1 w:1) - // Storage: Hrmp HrmpChannelDigests (r:1 w:1) - // Storage: Paras FutureCodeUpgrades (r:1 w:0) - // Storage: ParaScheduler SessionStartBlock (r:1 w:0) - // Storage: ParaScheduler ParathreadQueue (r:1 w:1) - // Storage: ParaScheduler Scheduled (r:1 w:1) - // Storage: ParaScheduler ValidatorGroups (r:1 w:0) - // Storage: Ump NeedsDispatch (r:1 w:1) - // Storage: Ump NextDispatchRoundStartWith (r:1 w:1) - // Storage: ParaInherent OnChainVotes (r:0 w:1) - // Storage: Hrmp HrmpWatermarks (r:0 w:1) - // Storage: Paras Heads (r:0 w:1) + /// Storage: `ParaInherent::Included` (r:1 w:1) + /// Proof: `ParaInherent::Included` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::ParentHash` (r:1 w:0) + /// Proof: `System::ParentHash` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `ParasShared::AllowedRelayParents` (r:1 w:1) + /// Proof: `ParasShared::AllowedRelayParents` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParaScheduler::AvailabilityCores` (r:1 w:1) + /// Proof: `ParaScheduler::AvailabilityCores` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) + /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Babe::AuthorVrfRandomness` (r:1 w:0) + /// Proof: `Babe::AuthorVrfRandomness` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) + /// Storage: `ParaSessionInfo::Sessions` (r:1 w:0) + /// Proof: `ParaSessionInfo::Sessions` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasDisputes::Disputes` (r:1 w:1) + /// Proof: `ParasDisputes::Disputes` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasDisputes::BackersOnDisputes` (r:1 w:1) + /// Proof: `ParasDisputes::BackersOnDisputes` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasDisputes::Included` (r:1 w:1) + /// Proof: `ParasDisputes::Included` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParaInherent::OnChainVotes` (r:1 w:1) + /// Proof: `ParaInherent::OnChainVotes` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasDisputes::Frozen` (r:1 w:0) + /// Proof: `ParasDisputes::Frozen` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParaInclusion::PendingAvailability` (r:2 w:1) + /// Proof: `ParaInclusion::PendingAvailability` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParaInclusion::PendingAvailabilityCommitments` (r:1 w:1) + /// Proof: `ParaInclusion::PendingAvailabilityCommitments` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:1) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpChannelDigests` (r:1 w:1) + /// Proof: `Hrmp::HrmpChannelDigests` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::FutureCodeUpgrades` (r:1 w:0) + /// Proof: `Paras::FutureCodeUpgrades` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Registrar::Paras` (r:1 w:0) + /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParaScheduler::SessionStartBlock` (r:1 w:0) + /// Proof: `ParaScheduler::SessionStartBlock` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParaScheduler::ValidatorGroups` (r:1 w:0) + /// Proof: `ParaScheduler::ValidatorGroups` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParaScheduler::ClaimQueue` (r:1 w:1) + /// Proof: `ParaScheduler::ClaimQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `CoretimeAssignmentProvider::CoreDescriptors` (r:1 w:1) + /// Proof: `CoretimeAssignmentProvider::CoreDescriptors` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::ActiveValidatorIndices` (r:1 w:0) + /// Proof: `ParasShared::ActiveValidatorIndices` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Session::DisabledValidators` (r:1 w:0) + /// Proof: `Session::DisabledValidators` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpWatermarks` (r:0 w:1) + /// Proof: `Hrmp::HrmpWatermarks` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::Heads` (r:0 w:1) + /// Proof: `Paras::Heads` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::UpgradeGoAheadSignal` (r:0 w:1) + /// Proof: `Paras::UpgradeGoAheadSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::MostRecentContext` (r:0 w:1) + /// Proof: `Paras::MostRecentContext` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// The range of component `v` is `[10, 200]`. fn enter_variable_disputes(v: u32, ) -> Weight { - Weight::from_parts(352_590_000 as u64, 0) - // Standard Error: 13_000 - .saturating_add(Weight::from_parts(49_254_000 as u64, 0).saturating_mul(v as u64)) - .saturating_add(T::DbWeight::get().reads(24 as u64)) - .saturating_add(T::DbWeight::get().writes(16 as u64)) + // Proof Size summary in bytes: + // Measured: `67819` + // Estimated: `73759 + v * (23 ±0)` + // Minimum execution time: 874_229_000 picoseconds. + Weight::from_parts(486_359_072, 0) + .saturating_add(Weight::from_parts(0, 73759)) + // Standard Error: 19_197 + .saturating_add(Weight::from_parts(41_842_161, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(26)) + .saturating_add(T::DbWeight::get().writes(16)) + .saturating_add(Weight::from_parts(0, 23).saturating_mul(v.into())) } - // Storage: ParaInherent Included (r:1 w:1) - // Storage: System ParentHash (r:1 w:0) - // Storage: ParaScheduler AvailabilityCores (r:1 w:1) - // Storage: ParasShared CurrentSessionIndex (r:1 w:0) - // Storage: Configuration ActiveConfig (r:1 w:0) - // Storage: ParasDisputes Frozen (r:1 w:0) - // Storage: ParasShared ActiveValidatorKeys (r:1 w:0) - // Storage: Paras Parachains (r:1 w:0) - // Storage: ParaInclusion PendingAvailability (r:2 w:1) - // Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) - // Storage: Dmp DownwardMessageQueues (r:1 w:1) - // Storage: Hrmp HrmpChannelDigests (r:1 w:1) - // Storage: Paras FutureCodeUpgrades (r:1 w:0) - // Storage: ParasDisputes Disputes (r:1 w:0) - // Storage: ParaScheduler SessionStartBlock (r:1 w:0) - // Storage: ParaScheduler ParathreadQueue (r:1 w:1) - // Storage: ParaScheduler Scheduled (r:1 w:1) - // Storage: ParaScheduler ValidatorGroups (r:1 w:0) - // Storage: Ump NeedsDispatch (r:1 w:1) - // Storage: Ump NextDispatchRoundStartWith (r:1 w:1) - // Storage: ParaInclusion AvailabilityBitfields (r:0 w:1) - // Storage: ParaInherent OnChainVotes (r:0 w:1) - // Storage: ParasDisputes Included (r:0 w:1) - // Storage: Hrmp HrmpWatermarks (r:0 w:1) - // Storage: Paras Heads (r:0 w:1) + /// Storage: `ParaInherent::Included` (r:1 w:1) + /// Proof: `ParaInherent::Included` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::ParentHash` (r:1 w:0) + /// Proof: `System::ParentHash` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `ParasShared::AllowedRelayParents` (r:1 w:1) + /// Proof: `ParasShared::AllowedRelayParents` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParaScheduler::AvailabilityCores` (r:1 w:1) + /// Proof: `ParaScheduler::AvailabilityCores` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) + /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Babe::AuthorVrfRandomness` (r:1 w:0) + /// Proof: `Babe::AuthorVrfRandomness` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) + /// Storage: `ParaInherent::OnChainVotes` (r:1 w:1) + /// Proof: `ParaInherent::OnChainVotes` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasDisputes::Frozen` (r:1 w:0) + /// Proof: `ParasDisputes::Frozen` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParaInclusion::PendingAvailability` (r:2 w:1) + /// Proof: `ParaInclusion::PendingAvailability` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParaInclusion::PendingAvailabilityCommitments` (r:1 w:1) + /// Proof: `ParaInclusion::PendingAvailabilityCommitments` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:1) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpChannelDigests` (r:1 w:1) + /// Proof: `Hrmp::HrmpChannelDigests` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::FutureCodeUpgrades` (r:1 w:0) + /// Proof: `Paras::FutureCodeUpgrades` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Registrar::Paras` (r:1 w:0) + /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasDisputes::Disputes` (r:1 w:0) + /// Proof: `ParasDisputes::Disputes` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParaScheduler::SessionStartBlock` (r:1 w:0) + /// Proof: `ParaScheduler::SessionStartBlock` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParaScheduler::ValidatorGroups` (r:1 w:0) + /// Proof: `ParaScheduler::ValidatorGroups` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParaScheduler::ClaimQueue` (r:1 w:1) + /// Proof: `ParaScheduler::ClaimQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `CoretimeAssignmentProvider::CoreDescriptors` (r:1 w:1) + /// Proof: `CoretimeAssignmentProvider::CoreDescriptors` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::ActiveValidatorIndices` (r:1 w:0) + /// Proof: `ParasShared::ActiveValidatorIndices` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Session::DisabledValidators` (r:1 w:0) + /// Proof: `Session::DisabledValidators` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParaInclusion::AvailabilityBitfields` (r:0 w:1) + /// Proof: `ParaInclusion::AvailabilityBitfields` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasDisputes::Included` (r:0 w:1) + /// Proof: `ParasDisputes::Included` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpWatermarks` (r:0 w:1) + /// Proof: `Hrmp::HrmpWatermarks` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::Heads` (r:0 w:1) + /// Proof: `Paras::Heads` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::UpgradeGoAheadSignal` (r:0 w:1) + /// Proof: `Paras::UpgradeGoAheadSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::MostRecentContext` (r:0 w:1) + /// Proof: `Paras::MostRecentContext` (`max_values`: None, `max_size`: None, mode: `Measured`) fn enter_bitfields() -> Weight { - Weight::from_parts(299_878_000 as u64, 0) - .saturating_add(T::DbWeight::get().reads(21 as u64)) - .saturating_add(T::DbWeight::get().writes(15 as u64)) + // Proof Size summary in bytes: + // Measured: `42791` + // Estimated: `48731` + // Minimum execution time: 428_757_000 picoseconds. + Weight::from_parts(449_681_000, 0) + .saturating_add(Weight::from_parts(0, 48731)) + .saturating_add(T::DbWeight::get().reads(24)) + .saturating_add(T::DbWeight::get().writes(17)) } - // Storage: ParaInherent Included (r:1 w:1) - // Storage: System ParentHash (r:1 w:0) - // Storage: ParaScheduler AvailabilityCores (r:1 w:1) - // Storage: ParasShared CurrentSessionIndex (r:1 w:0) - // Storage: Configuration ActiveConfig (r:1 w:0) - // Storage: ParasDisputes Frozen (r:1 w:0) - // Storage: ParasShared ActiveValidatorKeys (r:1 w:0) - // Storage: Paras Parachains (r:1 w:0) - // Storage: ParaInclusion PendingAvailability (r:2 w:1) - // Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) - // Storage: Dmp DownwardMessageQueues (r:1 w:1) - // Storage: Hrmp HrmpChannelDigests (r:1 w:1) - // Storage: Paras FutureCodeUpgrades (r:1 w:0) - // Storage: ParasDisputes Disputes (r:2 w:0) - // Storage: ParaScheduler SessionStartBlock (r:1 w:0) - // Storage: ParaScheduler ParathreadQueue (r:1 w:1) - // Storage: ParaScheduler Scheduled (r:1 w:1) - // Storage: ParaScheduler ValidatorGroups (r:1 w:0) - // Storage: Paras PastCodeMeta (r:1 w:0) - // Storage: Paras CurrentCodeHash (r:1 w:0) - // Storage: Ump RelayDispatchQueueSize (r:1 w:0) - // Storage: Ump NeedsDispatch (r:1 w:1) - // Storage: Ump NextDispatchRoundStartWith (r:1 w:1) - // Storage: ParaInherent OnChainVotes (r:0 w:1) - // Storage: ParasDisputes Included (r:0 w:1) - // Storage: Hrmp HrmpWatermarks (r:0 w:1) - // Storage: Paras Heads (r:0 w:1) - fn enter_backed_candidates_variable(_v: u32) -> Weight { - Weight::from_parts(442_472_000 as u64, 0) - .saturating_add(T::DbWeight::get().reads(25 as u64)) - .saturating_add(T::DbWeight::get().writes(14 as u64)) + /// Storage: `ParaInherent::Included` (r:1 w:1) + /// Proof: `ParaInherent::Included` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::ParentHash` (r:1 w:0) + /// Proof: `System::ParentHash` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `ParasShared::AllowedRelayParents` (r:1 w:1) + /// Proof: `ParasShared::AllowedRelayParents` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParaScheduler::AvailabilityCores` (r:1 w:1) + /// Proof: `ParaScheduler::AvailabilityCores` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) + /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Babe::AuthorVrfRandomness` (r:1 w:0) + /// Proof: `Babe::AuthorVrfRandomness` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) + /// Storage: `ParaInherent::OnChainVotes` (r:1 w:1) + /// Proof: `ParaInherent::OnChainVotes` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasDisputes::Frozen` (r:1 w:0) + /// Proof: `ParasDisputes::Frozen` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParaInclusion::PendingAvailability` (r:2 w:1) + /// Proof: `ParaInclusion::PendingAvailability` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParaInclusion::PendingAvailabilityCommitments` (r:1 w:1) + /// Proof: `ParaInclusion::PendingAvailabilityCommitments` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:1) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpChannelDigests` (r:1 w:1) + /// Proof: `Hrmp::HrmpChannelDigests` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::FutureCodeUpgrades` (r:1 w:0) + /// Proof: `Paras::FutureCodeUpgrades` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Registrar::Paras` (r:1 w:0) + /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasDisputes::Disputes` (r:1 w:0) + /// Proof: `ParasDisputes::Disputes` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParaScheduler::SessionStartBlock` (r:1 w:0) + /// Proof: `ParaScheduler::SessionStartBlock` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParaScheduler::ValidatorGroups` (r:1 w:0) + /// Proof: `ParaScheduler::ValidatorGroups` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParaScheduler::ClaimQueue` (r:1 w:1) + /// Proof: `ParaScheduler::ClaimQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `CoretimeAssignmentProvider::CoreDescriptors` (r:1 w:1) + /// Proof: `CoretimeAssignmentProvider::CoreDescriptors` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CurrentCodeHash` (r:1 w:0) + /// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ParaLifecycles` (r:1 w:0) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:0) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) + /// Storage: `ParasShared::ActiveValidatorIndices` (r:1 w:0) + /// Proof: `ParasShared::ActiveValidatorIndices` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Session::DisabledValidators` (r:1 w:0) + /// Proof: `Session::DisabledValidators` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasDisputes::Included` (r:0 w:1) + /// Proof: `ParasDisputes::Included` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpWatermarks` (r:0 w:1) + /// Proof: `Hrmp::HrmpWatermarks` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::Heads` (r:0 w:1) + /// Proof: `Paras::Heads` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::UpgradeGoAheadSignal` (r:0 w:1) + /// Proof: `Paras::UpgradeGoAheadSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::MostRecentContext` (r:0 w:1) + /// Proof: `Paras::MostRecentContext` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// The range of component `v` is `[101, 200]`. + fn enter_backed_candidates_variable(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `42863` + // Estimated: `48803` + // Minimum execution time: 1_276_079_000 picoseconds. + Weight::from_parts(1_313_585_212, 0) + .saturating_add(Weight::from_parts(0, 48803)) + // Standard Error: 18_279 + .saturating_add(Weight::from_parts(43_528, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(27)) + .saturating_add(T::DbWeight::get().writes(16)) } - // Storage: ParaInherent Included (r:1 w:1) - // Storage: System ParentHash (r:1 w:0) - // Storage: ParaScheduler AvailabilityCores (r:1 w:1) - // Storage: ParasShared CurrentSessionIndex (r:1 w:0) - // Storage: Configuration ActiveConfig (r:1 w:0) - // Storage: ParasDisputes Frozen (r:1 w:0) - // Storage: ParasShared ActiveValidatorKeys (r:1 w:0) - // Storage: Paras Parachains (r:1 w:0) - // Storage: ParaInclusion PendingAvailability (r:2 w:1) - // Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) - // Storage: Dmp DownwardMessageQueues (r:1 w:1) - // Storage: Hrmp HrmpChannelDigests (r:1 w:1) - // Storage: Paras FutureCodeUpgrades (r:1 w:0) - // Storage: ParasDisputes Disputes (r:2 w:0) - // Storage: ParaScheduler SessionStartBlock (r:1 w:0) - // Storage: ParaScheduler ParathreadQueue (r:1 w:1) - // Storage: ParaScheduler Scheduled (r:1 w:1) - // Storage: ParaScheduler ValidatorGroups (r:1 w:0) - // Storage: Paras PastCodeMeta (r:1 w:0) - // Storage: Paras CurrentCodeHash (r:1 w:0) - // Storage: Ump RelayDispatchQueueSize (r:1 w:0) - // Storage: Ump NeedsDispatch (r:1 w:1) - // Storage: Ump NextDispatchRoundStartWith (r:1 w:1) - // Storage: ParaInherent OnChainVotes (r:0 w:1) - // Storage: ParasDisputes Included (r:0 w:1) - // Storage: Hrmp HrmpWatermarks (r:0 w:1) - // Storage: Paras Heads (r:0 w:1) + /// Storage: `ParaInherent::Included` (r:1 w:1) + /// Proof: `ParaInherent::Included` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::ParentHash` (r:1 w:0) + /// Proof: `System::ParentHash` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `ParasShared::AllowedRelayParents` (r:1 w:1) + /// Proof: `ParasShared::AllowedRelayParents` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParaScheduler::AvailabilityCores` (r:1 w:1) + /// Proof: `ParaScheduler::AvailabilityCores` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) + /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Babe::AuthorVrfRandomness` (r:1 w:0) + /// Proof: `Babe::AuthorVrfRandomness` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) + /// Storage: `ParaInherent::OnChainVotes` (r:1 w:1) + /// Proof: `ParaInherent::OnChainVotes` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasDisputes::Frozen` (r:1 w:0) + /// Proof: `ParasDisputes::Frozen` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParaInclusion::PendingAvailability` (r:2 w:1) + /// Proof: `ParaInclusion::PendingAvailability` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParaInclusion::PendingAvailabilityCommitments` (r:1 w:1) + /// Proof: `ParaInclusion::PendingAvailabilityCommitments` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:1) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpChannelDigests` (r:1 w:1) + /// Proof: `Hrmp::HrmpChannelDigests` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::FutureCodeUpgrades` (r:1 w:0) + /// Proof: `Paras::FutureCodeUpgrades` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Registrar::Paras` (r:1 w:0) + /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParasDisputes::Disputes` (r:1 w:0) + /// Proof: `ParasDisputes::Disputes` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParaScheduler::SessionStartBlock` (r:1 w:0) + /// Proof: `ParaScheduler::SessionStartBlock` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParaScheduler::ValidatorGroups` (r:1 w:0) + /// Proof: `ParaScheduler::ValidatorGroups` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParaScheduler::ClaimQueue` (r:1 w:1) + /// Proof: `ParaScheduler::ClaimQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `CoretimeAssignmentProvider::CoreDescriptors` (r:1 w:1) + /// Proof: `CoretimeAssignmentProvider::CoreDescriptors` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::CurrentCodeHash` (r:1 w:0) + /// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::FutureCodeHash` (r:1 w:0) + /// Proof: `Paras::FutureCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::UpgradeRestrictionSignal` (r:1 w:0) + /// Proof: `Paras::UpgradeRestrictionSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::ParaLifecycles` (r:1 w:0) + /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:0) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) + /// Storage: `ParasShared::ActiveValidatorIndices` (r:1 w:0) + /// Proof: `ParasShared::ActiveValidatorIndices` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Session::DisabledValidators` (r:1 w:0) + /// Proof: `Session::DisabledValidators` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasDisputes::Included` (r:0 w:1) + /// Proof: `ParasDisputes::Included` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Hrmp::HrmpWatermarks` (r:0 w:1) + /// Proof: `Hrmp::HrmpWatermarks` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::Heads` (r:0 w:1) + /// Proof: `Paras::Heads` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::UpgradeGoAheadSignal` (r:0 w:1) + /// Proof: `Paras::UpgradeGoAheadSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Paras::MostRecentContext` (r:0 w:1) + /// Proof: `Paras::MostRecentContext` (`max_values`: None, `max_size`: None, mode: `Measured`) fn enter_backed_candidate_code_upgrade() -> Weight { - Weight::from_parts(36_903_411_000 as u64, 0) - .saturating_add(T::DbWeight::get().reads(25 as u64)) - .saturating_add(T::DbWeight::get().writes(14 as u64)) + // Proof Size summary in bytes: + // Measured: `42876` + // Estimated: `48816` + // Minimum execution time: 34_352_245_000 picoseconds. + Weight::from_parts(34_587_559_000, 0) + .saturating_add(Weight::from_parts(0, 48816)) + .saturating_add(T::DbWeight::get().reads(29)) + .saturating_add(T::DbWeight::get().writes(16)) } } diff --git a/polkadot/runtime/test-runtime/Cargo.toml b/polkadot/runtime/test-runtime/Cargo.toml index 9753a409304..bdf68864605 100644 --- a/polkadot/runtime/test-runtime/Cargo.toml +++ b/polkadot/runtime/test-runtime/Cargo.toml @@ -155,6 +155,7 @@ runtime-benchmarks = [ "pallet-staking/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-vesting/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index 6c899c52701..a0617b3108f 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -238,6 +238,7 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = frame_support::weights::ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; + type WeightInfo = (); } parameter_types! { @@ -393,7 +394,7 @@ where let current_block = System::block_number().saturated_into::().saturating_sub(1); let tip = 0; - let extra: SignedExtra = ( + let tx_ext: TxExtension = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -405,16 +406,17 @@ where frame_system::CheckNonce::::from(nonce), frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(tip), - ); - let raw_payload = SignedPayload::new(call, extra) + ) + .into(); + let raw_payload = SignedPayload::new(call, tx_ext) .map_err(|e| { log::warn!("Unable to create signed payload: {:?}", e); }) .ok()?; let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?; - let (call, extra, _) = raw_payload.deconstruct(); + let (call, tx_ext, _) = raw_payload.deconstruct(); let address = Indices::unlookup(account); - Some((call, (address, signature, extra))) + Some((call, (address, signature, tx_ext))) } } @@ -442,12 +444,32 @@ parameter_types! { pub Prefix: &'static [u8] = b"Pay KSMs to the Kusama account:"; } +#[cfg(feature = "runtime-benchmarks")] +pub struct ClaimsHelper; + +#[cfg(feature = "runtime-benchmarks")] +use frame_support::dispatch::DispatchInfo; + +#[cfg(feature = "runtime-benchmarks")] +impl claims::BenchmarkHelperTrait for ClaimsHelper { + fn default_call_and_info() -> (RuntimeCall, DispatchInfo) { + use frame_support::dispatch::GetDispatchInfo; + let call = RuntimeCall::Claims(claims::Call::attest { + statement: claims::StatementKind::Regular.to_text().to_vec(), + }); + let info = call.get_dispatch_info(); + (call, info) + } +} + impl claims::Config for Runtime { type RuntimeEvent = RuntimeEvent; type VestingSchedule = Vesting; type Prefix = Prefix; type MoveClaimOrigin = frame_system::EnsureRoot; type WeightInfo = claims::TestWeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = ClaimsHelper; } parameter_types! { @@ -728,8 +750,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// `BlockId` type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The `SignedExtension` to the basic transaction logic. -pub type SignedExtra = ( +/// The extension to the basic transaction logic. +pub type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -741,7 +763,7 @@ pub type SignedExtra = ( ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< @@ -752,7 +774,7 @@ pub type Executive = frame_executive::Executive< AllPalletsWithSystem, >; /// The payload being signed in transactions. -pub type SignedPayload = generic::SignedPayload; +pub type SignedPayload = generic::SignedPayload; pub type Hash = ::Hash; pub type Extrinsic = ::Extrinsic; diff --git a/polkadot/runtime/westend/Cargo.toml b/polkadot/runtime/westend/Cargo.toml index 4180828bcfb..6899edeeaeb 100644 --- a/polkadot/runtime/westend/Cargo.toml +++ b/polkadot/runtime/westend/Cargo.toml @@ -270,6 +270,7 @@ runtime-benchmarks = [ "pallet-state-trie-migration/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-vesting/runtime-benchmarks", diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index b55d68ee0f6..45bbd0260e5 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -200,6 +200,7 @@ impl frame_system::Config for Runtime { type Version = Version; type AccountData = pallet_balances::AccountData; type SystemWeightInfo = weights::frame_system::WeightInfo; + type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; type SS58Prefix = SS58Prefix; type MaxConsumers = frame_support::traits::ConstU32<16>; } @@ -385,6 +386,7 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; + type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { @@ -820,7 +822,7 @@ where // so the actual block number is `n`. .saturating_sub(1); let tip = 0; - let extra: SignedExtra = ( + let tx_ext: TxExtension = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -832,16 +834,17 @@ where frame_system::CheckNonce::::from(nonce), frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(tip), - ); - let raw_payload = SignedPayload::new(call, extra) + ) + .into(); + let raw_payload = SignedPayload::new(call, tx_ext) .map_err(|e| { log::warn!("Unable to create signed payload: {:?}", e); }) .ok()?; let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?; - let (call, extra, _) = raw_payload.deconstruct(); + let (call, tx_ext, _) = raw_payload.deconstruct(); let address = ::Lookup::unlookup(account); - Some((call, (address, signature, extra))) + Some((call, (address, signature, tx_ext))) } } @@ -1548,8 +1551,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// `BlockId` type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The `SignedExtension` to the basic transaction logic. -pub type SignedExtra = ( +/// The extension to the basic transaction logic. +pub type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -1713,7 +1716,7 @@ pub mod migrations { /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, @@ -1724,7 +1727,7 @@ pub type Executive = frame_executive::Executive< Migrations, >; /// The payload being signed in transactions. -pub type SignedPayload = generic::SignedPayload; +pub type SignedPayload = generic::SignedPayload; #[cfg(feature = "runtime-benchmarks")] mod benches { @@ -1770,7 +1773,9 @@ mod benches { [pallet_staking, Staking] [pallet_sudo, Sudo] [frame_system, SystemBench::] + [frame_system_extensions, SystemExtensionsBench::] [pallet_timestamp, Timestamp] + [pallet_transaction_payment, TransactionPayment] [pallet_treasury, Treasury] [pallet_utility, Utility] [pallet_vesting, Vesting] @@ -2312,6 +2317,7 @@ sp_api::impl_runtime_apis! { use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench; type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::; @@ -2340,6 +2346,7 @@ sp_api::impl_runtime_apis! { use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench; impl pallet_session_benchmarking::Config for Runtime {} diff --git a/polkadot/runtime/westend/src/weights/frame_system_extensions.rs b/polkadot/runtime/westend/src/weights/frame_system_extensions.rs new file mode 100644 index 00000000000..e4e1a799ec6 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/frame_system_extensions.rs @@ -0,0 +1,116 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Autogenerated weights for `frame_system_extensions` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-20, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot +// benchmark +// pallet +// --steps=2 +// --repeat=2 +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --pallet=frame-system-extensions +// --chain=westend-dev +// --output=./polkadot/runtime/westend/src/weights/ +// --header=./polkadot/file_header.txt + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `frame_system_extensions`. +pub struct WeightInfo(PhantomData); +impl frame_system::ExtensionsWeightInfo for WeightInfo { + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_genesis() -> Weight { + // Proof Size summary in bytes: + // Measured: `54` + // Estimated: `3509` + // Minimum execution time: 3_356_000 picoseconds. + Weight::from_parts(7_805_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_mortality() -> Weight { + // Proof Size summary in bytes: + // Measured: `92` + // Estimated: `3509` + // Minimum execution time: 5_510_000 picoseconds. + Weight::from_parts(10_009_000, 0) + .saturating_add(Weight::from_parts(0, 3509)) + .saturating_add(T::DbWeight::get().reads(1)) + } + fn check_non_zero_sender() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 761_000 picoseconds. + Weight::from_parts(4_308_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_nonce() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_396_000 picoseconds. + Weight::from_parts(7_585_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_spec_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 521_000 picoseconds. + Weight::from_parts(4_168_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + fn check_tx_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 541_000 picoseconds. + Weight::from_parts(4_228_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) + /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn check_weight() -> Weight { + // Proof Size summary in bytes: + // Measured: `24` + // Estimated: `1489` + // Minimum execution time: 3_807_000 picoseconds. + Weight::from_parts(8_025_000, 0) + .saturating_add(Weight::from_parts(0, 1489)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/polkadot/runtime/westend/src/weights/mod.rs b/polkadot/runtime/westend/src/weights/mod.rs index f6a9008d718..8aeb4216550 100644 --- a/polkadot/runtime/westend/src/weights/mod.rs +++ b/polkadot/runtime/westend/src/weights/mod.rs @@ -17,6 +17,7 @@ pub mod frame_election_provider_support; pub mod frame_system; +pub mod frame_system_extensions; pub mod pallet_asset_rate; pub mod pallet_bags_list; pub mod pallet_balances; @@ -37,6 +38,7 @@ pub mod pallet_session; pub mod pallet_staking; pub mod pallet_sudo; pub mod pallet_timestamp; +pub mod pallet_transaction_payment; pub mod pallet_treasury; pub mod pallet_utility; pub mod pallet_vesting; diff --git a/polkadot/runtime/westend/src/weights/pallet_sudo.rs b/polkadot/runtime/westend/src/weights/pallet_sudo.rs index e9ab3ad37a4..649c43e031d 100644 --- a/polkadot/runtime/westend/src/weights/pallet_sudo.rs +++ b/polkadot/runtime/westend/src/weights/pallet_sudo.rs @@ -94,4 +94,15 @@ impl pallet_sudo::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `Sudo::Key` (r:1 w:0) + /// Proof: `Sudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + fn check_only_sudo_account() -> Weight { + // Proof Size summary in bytes: + // Measured: `132` + // Estimated: `1517` + // Minimum execution time: 2_875_000 picoseconds. + Weight::from_parts(6_803_000, 0) + .saturating_add(Weight::from_parts(0, 1517)) + .saturating_add(T::DbWeight::get().reads(1)) + } } diff --git a/polkadot/runtime/westend/src/weights/pallet_transaction_payment.rs b/polkadot/runtime/westend/src/weights/pallet_transaction_payment.rs new file mode 100644 index 00000000000..001a09f103d --- /dev/null +++ b/polkadot/runtime/westend/src/weights/pallet_transaction_payment.rs @@ -0,0 +1,65 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Autogenerated weights for `pallet_transaction_payment` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/release/polkadot +// benchmark +// pallet +// --steps=2 +// --repeat=2 +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --pallet=pallet_transaction_payment +// --chain=westend-dev +// --output=./polkadot/runtime/westend/src/weights/ +// --header=./polkadot/file_header.txt + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_transaction_payment`. +pub struct WeightInfo(PhantomData); +impl pallet_transaction_payment::WeightInfo for WeightInfo { + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Authorship::Author` (r:1 w:0) + /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `System::Digest` (r:1 w:0) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn charge_transaction_payment() -> Weight { + // Proof Size summary in bytes: + // Measured: `156` + // Estimated: `1641` + // Minimum execution time: 30_888_000 picoseconds. + Weight::from_parts(41_308_000, 0) + .saturating_add(Weight::from_parts(0, 1641)) + .saturating_add(T::DbWeight::get().reads(3)) + } +} diff --git a/polkadot/xcm/xcm-builder/Cargo.toml b/polkadot/xcm/xcm-builder/Cargo.toml index 10726b0f511..660a30605e5 100644 --- a/polkadot/xcm/xcm-builder/Cargo.toml +++ b/polkadot/xcm/xcm-builder/Cargo.toml @@ -47,6 +47,7 @@ runtime-benchmarks = [ "pallet-assets/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-salary/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-parachains/runtime-benchmarks", diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs index 9892c500f2e..3bd2fa4b4f5 100644 --- a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs +++ b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs @@ -25,14 +25,22 @@ use frame_support::{ traits::{ConstU32, Everything}, }; use frame_system::{EnsureRoot, EnsureSigned}; -use polkadot_test_runtime::SignedExtra; use primitives::{AccountIndex, BlakeTwo256, Signature}; use sp_runtime::{generic, traits::MaybeEquivalence, AccountId32, BuildStorage}; use xcm_executor::{traits::ConvertLocation, XcmExecutor}; +pub type TxExtension = ( + frame_system::CheckNonZeroSender, + frame_system::CheckSpecVersion, + frame_system::CheckTxVersion, + frame_system::CheckGenesis, + frame_system::CheckMortality, + frame_system::CheckNonce, + frame_system::CheckWeight, +); pub type Address = sp_runtime::MultiAddress; pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; pub type Header = generic::Header; pub type Block = generic::Block; diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs index a20390b64f9..f953e54111c 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs @@ -46,13 +46,13 @@ use xcm_builder::{ }; use xcm_executor::{Config, XcmExecutor}; -pub type SignedExtra = (frame_system::CheckNonZeroSender,); +pub type TxExtension = (frame_system::CheckNonZeroSender,); pub type BlockNumber = u64; pub type Address = MultiAddress; pub type Header = generic::Header; pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; pub type Block = generic::Block; pub type Signature = MultiSignature; diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs index 5bf65fa9f9a..a11e535492c 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs @@ -45,13 +45,13 @@ use xcm_builder::{ }; use xcm_executor::{Config, XcmExecutor}; -pub type SignedExtra = (frame_system::CheckNonZeroSender,); +pub type TxExtension = (frame_system::CheckNonZeroSender,); pub type BlockNumber = u64; pub type Address = MultiAddress; pub type Header = generic::Header; pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; pub type Block = generic::Block; pub type Signature = MultiSignature; diff --git a/prdoc/pr_2280.prdoc b/prdoc/pr_2280.prdoc new file mode 100644 index 00000000000..3026dc254e6 --- /dev/null +++ b/prdoc/pr_2280.prdoc @@ -0,0 +1,144 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: FRAME Create `TransactionExtension` as a replacement for `SignedExtension` + +doc: + - audience: Runtime User + description: | + Introduces a new trait `TransactionExtension` to replace `SignedExtension`. Introduce the + idea of transactions which obey the runtime's extensions and have according Extension data + (né Extra data) yet do not have hard-coded signatures. + + Deprecate the terminology of "Unsigned" when used for transactions/extrinsics owing to there + now being "proper" unsigned transactions which obey the extension framework and "old-style" + unsigned which do not. Instead we have `General` for the former and `Bare` for the latter. + Unsigned will be phased out as a type of transaction, and `Bare` will only be used for + Inherents. + + Types of extrinsic are now therefore + - Bare (no hardcoded signature, no Extra data; used to be known as "Unsigned") + - Bare transactions (deprecated) - Gossiped, validated with `ValidateUnsigned` + (deprecated) and the `_bare_compat` bits of `TransactionExtension` (deprecated). + - Inherents - Not gossiped, validated with `ProvideInherent`. + - Extended (Extra data) - Gossiped, validated via `TransactionExtension`. + - Signed transactions (with a hardcoded signature). + - General transactions (without a hardcoded signature). + + Notable information on `TransactionExtension` and the differences from `SignedExtension` + - `AdditionalSigned`/`additional_signed` is renamed to `Implicit`/`implicit`. It is encoded + for the entire transaction and passed in to each extension as a new argument to validate. + - `pre_dispatch` is renamed to `prepare`. + - `validate` runs transaction validation logic both off-chain and on-chain, and is + non-mutating. + - `prepare` runs on-chain pre-execution logic using information extracted during validation + and is mutating. + - `validate` and `prepare` are now passed an `Origin` rather than an `AccountId`. If the + extension logic presumes an `AccountId`, consider using the trait function + `AsSystemOriginSigner::as_system_origin_signer`. + - A signature on the underlying transaction may validly not be present. + - The origin may be altered during validation. + - Validation functionality present in `validate` should not be repeated in `prepare`. + Useful information obtained during `validate` should now be passsed in to `prepare` using + the new user-specifiable type `Val`. + - Unsigned logic should be migrated from the old `*_unsigned` functions into the regular + versions of the new functions where the `Origin` is `None`. + - The `Call` type defining the runtime call is now a type parameter. + - `TransactionExtension` now takes a `Context` type parameter. This defines some arbitrary + contextual data that is injected into the transaction extension logic. It is unused in + instances migrated from `SignedExtension`. + - Extensions now track the weight they consume during valdiation, preparation and + post-dispatch through the `TransactionExtensionBase::weight` function. + - `TestXt` was removed and its usage in tests was replaced with `UncheckedExtrinsic` + instances. + + To fix the build issues introduced by this change, use the `AsTransactionExtension` adapter + to wrap existing `SignedExtension`s by converting them using the `From` + generic implementation for `AsTransactionExtension`. More details on migrating existing + `SignedExtension` implementations to `TransactionExtension` in the PR description. + +crates: + - name: bridge-runtime-common + - name: bp-bridge-hub-cumulus + - name: bp-kusama + - name: bp-polkadot-bulletin + - name: bp-polkadot + - name: bp-rococo + - name: bp-westend + - name: bp-polkadot-core + - name: bp-runtime + - name: snowbridge-pallet-inbound-queue + - name: snowbridge-pallet-outbound-queue + - name: snowbridge-pallet-system + - name: snowbridge-runtime-test-common + - name: parachain-template-runtime + - name: asset-hub-rococo-runtime + - name: asset-hub-westend-runtime + - name: bridge-hub-rococo-runtime + - name: bridge-hub-westend-runtime + - name: collectives-westend-runtime + - name: contracts-rococo-runtime + - name: coretime-rococo-runtime + - name: coretime-westend-runtime + - name: glutton-westend-runtime + - name: people-rococo-runtime + - name: people-westend-runtime + - name: seedling-runtime + - name: shell-runtime + - name: penpal-runtime + - name: rococo-parachain-runtime + - name: polkadot-parachain-bin + - name: cumulus-primitives-storage-weight-reclaim + - name: cumulus-test-client + - name: cumulus-test-runtime + - name: cumulus-test-service + - name: polkadot-sdk-docs + - name: polkadot-service + - name: polkadot-test-service + - name: polkadot-runtime-common + - name: rococo-runtime + - name: polkadot-test-runtime + - name: westend-runtime + - name: staging-xcm-builder + - name: minimal-runtime + - name: node-template + - name: node-template-runtime + - name: staging-node-cli + - name: kitchensink-runtime + - name: node-testing + - name: sc-client-api + - name: sc-client-db + - name: sc-network-gossip + - name: sc-network-sync + - name: sc-transaction-pool + - name: frame + - name: pallet-babe + - name: pallet-balances + - name: pallet-beefy + - name: pallet-collective + - name: pallet-election-provider-multi-phase + - name: pallet-elections-phragmen + - name: pallet-example-basic + - name: pallet-example-offchain-worker + - name: frame-executive + - name: pallet-grandpa + - name: pallet-im-online + - name: pallet-offences + - name: pallet-sassafras + - name: pallet-state-trie-migration + - name: pallet-sudo + - name: frame-support-procedural + - name: frame-support + - name: frame-system + - name: frame-system-benchmarking + - name: pallet-transaction-payment + - name: pallet-asset-conversion-tx-payment + - name: pallet-asset-tx-payment + - name: pallet-skip-feeless-payment + - name: sp-inherents + - name: sp-metadata-ir + - name: sp-runtime + - name: substrate-test-runtime + - name: frame-benchmarking-cli + - name: frame-remote-externalities + - name: substrate-rpc-client diff --git a/substrate/.maintain/frame-weight-template.hbs b/substrate/.maintain/frame-weight-template.hbs index ecd384a5145..ec9eee205ce 100644 --- a/substrate/.maintain/frame-weight-template.hbs +++ b/substrate/.maintain/frame-weight-template.hbs @@ -33,7 +33,7 @@ pub trait WeightInfo { /// Weights for `{{pallet}}` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -{{#if (eq pallet "frame_system")}} +{{#if (or (eq pallet "frame_system") (eq pallet "frame_system_extensions"))}} impl WeightInfo for SubstrateWeight { {{else}} impl WeightInfo for SubstrateWeight { diff --git a/substrate/bin/minimal/runtime/src/lib.rs b/substrate/bin/minimal/runtime/src/lib.rs index fb996aef46b..d3e8a2e8ec0 100644 --- a/substrate/bin/minimal/runtime/src/lib.rs +++ b/substrate/bin/minimal/runtime/src/lib.rs @@ -52,7 +52,7 @@ pub fn native_version() -> NativeVersion { NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } } -type SignedExtra = ( +type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -104,7 +104,7 @@ impl pallet_transaction_payment::Config for Runtime { type LengthToFee = FixedFee<1, ::Balance>; } -type Block = frame::runtime::types_common::BlockOf; +type Block = frame::runtime::types_common::BlockOf; type Header = HeaderFor; type RuntimeExecutive = diff --git a/substrate/bin/node-template/node/Cargo.toml b/substrate/bin/node-template/node/Cargo.toml index 9cba2b5a366..2f31947e492 100644 --- a/substrate/bin/node-template/node/Cargo.toml +++ b/substrate/bin/node-template/node/Cargo.toml @@ -78,6 +78,7 @@ runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", "node-template-runtime/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "sc-service/runtime-benchmarks", "sp-runtime/runtime-benchmarks", ] diff --git a/substrate/bin/node-template/node/src/benchmarking.rs b/substrate/bin/node-template/node/src/benchmarking.rs index 6e29ad1a123..eacc367669c 100644 --- a/substrate/bin/node-template/node/src/benchmarking.rs +++ b/substrate/bin/node-template/node/src/benchmarking.rs @@ -109,7 +109,7 @@ pub fn create_benchmark_extrinsic( .checked_next_power_of_two() .map(|c| c / 2) .unwrap_or(2) as u64; - let extra: runtime::SignedExtra = ( + let tx_ext: runtime::TxExtension = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -121,11 +121,12 @@ pub fn create_benchmark_extrinsic( frame_system::CheckNonce::::from(nonce), frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(0), - ); + ) + .into(); let raw_payload = runtime::SignedPayload::from_raw( call.clone(), - extra.clone(), + tx_ext.clone(), ( (), runtime::VERSION.spec_version, @@ -143,7 +144,7 @@ pub fn create_benchmark_extrinsic( call, sp_runtime::AccountId32::from(sender.public()).into(), runtime::Signature::Sr25519(signature), - extra, + tx_ext, ) } diff --git a/substrate/bin/node-template/runtime/Cargo.toml b/substrate/bin/node-template/runtime/Cargo.toml index 86bab0ca375..c7cffa568db 100644 --- a/substrate/bin/node-template/runtime/Cargo.toml +++ b/substrate/bin/node-template/runtime/Cargo.toml @@ -106,6 +106,7 @@ runtime-benchmarks = [ "pallet-sudo/runtime-benchmarks", "pallet-template/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "sp-runtime/runtime-benchmarks", ] try-runtime = [ diff --git a/substrate/bin/node-template/runtime/src/lib.rs b/substrate/bin/node-template/runtime/src/lib.rs index 159697f427f..ee622a691b4 100644 --- a/substrate/bin/node-template/runtime/src/lib.rs +++ b/substrate/bin/node-template/runtime/src/lib.rs @@ -241,6 +241,7 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = IdentityFee; type LengthToFee = IdentityFee; type FeeMultiplierUpdate = ConstFeeMultiplier; + type WeightInfo = pallet_transaction_payment::weights::SubstrateWeight; } impl pallet_sudo::Config for Runtime { @@ -276,8 +277,8 @@ pub type Address = sp_runtime::MultiAddress; pub type Header = generic::Header; /// Block type as expected by this runtime. pub type Block = generic::Block; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( +/// The extension to the basic transaction logic. +pub type TxExtension = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -296,9 +297,9 @@ type Migrations = (); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// The payload being signed in transactions. -pub type SignedPayload = generic::SignedPayload; +pub type SignedPayload = generic::SignedPayload; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, @@ -314,6 +315,7 @@ mod benches { frame_benchmarking::define_benchmarks!( [frame_benchmarking, BaselineBench::] [frame_system, SystemBench::] + [frame_system_extensions, SystemExtensionsBench::] [pallet_balances, Balances] [pallet_timestamp, Timestamp] [pallet_sudo, Sudo] @@ -498,6 +500,7 @@ impl_runtime_apis! { use frame_benchmarking::{baseline, Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use baseline::Pallet as BaselineBench; let mut list = Vec::::new(); @@ -514,6 +517,7 @@ impl_runtime_apis! { use frame_benchmarking::{baseline, Benchmarking, BenchmarkBatch}; use sp_storage::TrackedStorageKey; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use baseline::Pallet as BaselineBench; impl frame_system_benchmarking::Config for Runtime {} diff --git a/substrate/bin/node/cli/Cargo.toml b/substrate/bin/node/cli/Cargo.toml index abe284c41da..c91a83e6d6e 100644 --- a/substrate/bin/node/cli/Cargo.toml +++ b/substrate/bin/node/cli/Cargo.toml @@ -196,6 +196,7 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "kitchensink-runtime/runtime-benchmarks", "node-inspect?/runtime-benchmarks", + "pallet-asset-conversion-tx-payment/runtime-benchmarks", "pallet-asset-tx-payment/runtime-benchmarks", "pallet-assets/runtime-benchmarks", "pallet-balances/runtime-benchmarks", @@ -205,6 +206,7 @@ runtime-benchmarks = [ "pallet-skip-feeless-payment/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", "sc-client-db/runtime-benchmarks", "sc-service/runtime-benchmarks", diff --git a/substrate/bin/node/cli/benches/block_production.rs b/substrate/bin/node/cli/benches/block_production.rs index 23a62cc0bd2..b98a321c338 100644 --- a/substrate/bin/node/cli/benches/block_production.rs +++ b/substrate/bin/node/cli/benches/block_production.rs @@ -110,7 +110,7 @@ fn new_node(tokio_handle: Handle) -> node_cli::service::NewFullBase { fn extrinsic_set_time(now: u64) -> OpaqueExtrinsic { kitchensink_runtime::UncheckedExtrinsic { - signature: None, + preamble: sp_runtime::generic::Preamble::Bare, function: kitchensink_runtime::RuntimeCall::Timestamp(pallet_timestamp::Call::set { now }), } .into() diff --git a/substrate/bin/node/cli/benches/executor.rs b/substrate/bin/node/cli/benches/executor.rs index a326e1a79ea..e13d34f9657 100644 --- a/substrate/bin/node/cli/benches/executor.rs +++ b/substrate/bin/node/cli/benches/executor.rs @@ -29,7 +29,7 @@ use sp_core::{ storage::well_known_keys, traits::{CallContext, CodeExecutor, RuntimeCode}, }; -use sp_runtime::traits::BlakeTwo256; +use sp_runtime::{generic::ExtrinsicFormat, traits::BlakeTwo256}; use sp_state_machine::TestExternalities as CoreTestExternalities; use staging_node_cli::service::RuntimeExecutor; @@ -144,11 +144,11 @@ fn test_blocks( ) -> Vec<(Vec, Hash)> { let mut test_ext = new_test_ext(genesis_config); let mut block1_extrinsics = vec![CheckedExtrinsic { - signed: None, + format: ExtrinsicFormat::Bare, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: 0 }), }]; block1_extrinsics.extend((0..20).map(|i| CheckedExtrinsic { - signed: Some((alice(), signed_extra(i, 0))), + format: ExtrinsicFormat::Signed(alice(), tx_ext(i, 0)), function: RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { dest: bob().into(), value: 1 * DOLLARS, diff --git a/substrate/bin/node/cli/src/service.rs b/substrate/bin/node/cli/src/service.rs index 8f2aba6b44c..157f278fb53 100644 --- a/substrate/bin/node/cli/src/service.rs +++ b/substrate/bin/node/cli/src/service.rs @@ -107,18 +107,21 @@ pub fn create_extrinsic( .map(|c| c / 2) .unwrap_or(2) as u64; let tip = 0; - let extra: kitchensink_runtime::SignedExtra = + let tx_ext: kitchensink_runtime::TxExtension = ( - frame_system::CheckNonZeroSender::::new(), - frame_system::CheckSpecVersion::::new(), - frame_system::CheckTxVersion::::new(), - frame_system::CheckGenesis::::new(), - frame_system::CheckEra::::from(generic::Era::mortal( - period, - best_block.saturated_into(), - )), - frame_system::CheckNonce::::from(nonce), - frame_system::CheckWeight::::new(), + ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckEra::::from(generic::Era::mortal( + period, + best_block.saturated_into(), + )), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + ) + .into(), pallet_skip_feeless_payment::SkipCheckIfFeeless::from( pallet_asset_conversion_tx_payment::ChargeAssetTxPayment::< kitchensink_runtime::Runtime, @@ -128,15 +131,17 @@ pub fn create_extrinsic( let raw_payload = kitchensink_runtime::SignedPayload::from_raw( function.clone(), - extra.clone(), + tx_ext.clone(), ( - (), - kitchensink_runtime::VERSION.spec_version, - kitchensink_runtime::VERSION.transaction_version, - genesis_hash, - best_hash, - (), - (), + ( + (), + kitchensink_runtime::VERSION.spec_version, + kitchensink_runtime::VERSION.transaction_version, + genesis_hash, + best_hash, + (), + (), + ), (), ), ); @@ -146,7 +151,7 @@ pub fn create_extrinsic( function, sp_runtime::AccountId32::from(sender.public()).into(), kitchensink_runtime::Signature::Sr25519(signature), - extra, + tx_ext, ) } @@ -791,7 +796,7 @@ mod tests { use codec::Encode; use kitchensink_runtime::{ constants::{currency::CENTS, time::SLOT_DURATION}, - Address, BalancesCall, RuntimeCall, UncheckedExtrinsic, + Address, BalancesCall, RuntimeCall, TxExtension, UncheckedExtrinsic, }; use node_primitives::{Block, DigestItem, Signature}; use sc_client_api::BlockBackend; @@ -993,25 +998,31 @@ mod tests { let tx_payment = pallet_skip_feeless_payment::SkipCheckIfFeeless::from( pallet_asset_conversion_tx_payment::ChargeAssetTxPayment::from(0, None), ); - let extra = ( - check_non_zero_sender, - check_spec_version, - check_tx_version, - check_genesis, - check_era, - check_nonce, - check_weight, + let tx_ext: TxExtension = ( + ( + check_non_zero_sender, + check_spec_version, + check_tx_version, + check_genesis, + check_era, + check_nonce, + check_weight, + ) + .into(), tx_payment, ); let raw_payload = SignedPayload::from_raw( function, - extra, - ((), spec_version, transaction_version, genesis_hash, genesis_hash, (), (), ()), + tx_ext, + ( + ((), spec_version, transaction_version, genesis_hash, genesis_hash, (), ()), + (), + ), ); let signature = raw_payload.using_encoded(|payload| signer.sign(payload)); - let (function, extra, _) = raw_payload.deconstruct(); + let (function, tx_ext, _) = raw_payload.deconstruct(); index += 1; - UncheckedExtrinsic::new_signed(function, from.into(), signature.into(), extra) + UncheckedExtrinsic::new_signed(function, from.into(), signature.into(), tx_ext) .into() }, ); diff --git a/substrate/bin/node/cli/tests/basic.rs b/substrate/bin/node/cli/tests/basic.rs index 525ab2e39c1..5fcb2295ef0 100644 --- a/substrate/bin/node/cli/tests/basic.rs +++ b/substrate/bin/node/cli/tests/basic.rs @@ -67,7 +67,7 @@ fn transfer_fee(extrinsic: &E) -> Balance { fn xt() -> UncheckedExtrinsic { sign(CheckedExtrinsic { - signed: Some((alice(), signed_extra(0, 0))), + format: sp_runtime::generic::ExtrinsicFormat::Signed(alice(), tx_ext(0, 0)), function: RuntimeCall::Balances(default_transfer_call()), }) } @@ -84,11 +84,11 @@ fn changes_trie_block() -> (Vec, Hash) { GENESIS_HASH.into(), vec![ CheckedExtrinsic { - signed: None, + format: sp_runtime::generic::ExtrinsicFormat::Bare, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time }), }, CheckedExtrinsic { - signed: Some((alice(), signed_extra(0, 0))), + format: sp_runtime::generic::ExtrinsicFormat::Signed(alice(), tx_ext(0, 0)), function: RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { dest: bob().into(), value: 69 * DOLLARS, @@ -111,11 +111,11 @@ fn blocks() -> ((Vec, Hash), (Vec, Hash)) { GENESIS_HASH.into(), vec![ CheckedExtrinsic { - signed: None, + format: sp_runtime::generic::ExtrinsicFormat::Bare, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time1 }), }, CheckedExtrinsic { - signed: Some((alice(), signed_extra(0, 0))), + format: sp_runtime::generic::ExtrinsicFormat::Signed(alice(), tx_ext(0, 0)), function: RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { dest: bob().into(), value: 69 * DOLLARS, @@ -131,18 +131,18 @@ fn blocks() -> ((Vec, Hash), (Vec, Hash)) { block1.1, vec![ CheckedExtrinsic { - signed: None, + format: sp_runtime::generic::ExtrinsicFormat::Bare, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time2 }), }, CheckedExtrinsic { - signed: Some((bob(), signed_extra(0, 0))), + format: sp_runtime::generic::ExtrinsicFormat::Signed(bob(), tx_ext(0, 0)), function: RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { dest: alice().into(), value: 5 * DOLLARS, }), }, CheckedExtrinsic { - signed: Some((alice(), signed_extra(1, 0))), + format: sp_runtime::generic::ExtrinsicFormat::Signed(alice(), tx_ext(1, 0)), function: RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { dest: bob().into(), value: 15 * DOLLARS, @@ -166,11 +166,11 @@ fn block_with_size(time: u64, nonce: u32, size: usize) -> (Vec, Hash) { GENESIS_HASH.into(), vec![ CheckedExtrinsic { - signed: None, + format: sp_runtime::generic::ExtrinsicFormat::Bare, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time * 1000 }), }, CheckedExtrinsic { - signed: Some((alice(), signed_extra(nonce, 0))), + format: sp_runtime::generic::ExtrinsicFormat::Signed(alice(), tx_ext(nonce, 0)), function: RuntimeCall::System(frame_system::Call::remark { remark: vec![0; size] }), }, ], @@ -677,11 +677,11 @@ fn deploying_wasm_contract_should_work() { GENESIS_HASH.into(), vec![ CheckedExtrinsic { - signed: None, + format: sp_runtime::generic::ExtrinsicFormat::Bare, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time }), }, CheckedExtrinsic { - signed: Some((charlie(), signed_extra(0, 0))), + format: sp_runtime::generic::ExtrinsicFormat::Signed(charlie(), tx_ext(0, 0)), function: RuntimeCall::Contracts(pallet_contracts::Call::instantiate_with_code::< Runtime, > { @@ -694,7 +694,7 @@ fn deploying_wasm_contract_should_work() { }), }, CheckedExtrinsic { - signed: Some((charlie(), signed_extra(1, 0))), + format: sp_runtime::generic::ExtrinsicFormat::Signed(charlie(), tx_ext(1, 0)), function: RuntimeCall::Contracts(pallet_contracts::Call::call:: { dest: sp_runtime::MultiAddress::Id(addr.clone()), value: 10, diff --git a/substrate/bin/node/cli/tests/fees.rs b/substrate/bin/node/cli/tests/fees.rs index 8c7b3c87315..9d6407067a3 100644 --- a/substrate/bin/node/cli/tests/fees.rs +++ b/substrate/bin/node/cli/tests/fees.rs @@ -54,11 +54,11 @@ fn fee_multiplier_increases_and_decreases_on_big_weight() { GENESIS_HASH.into(), vec![ CheckedExtrinsic { - signed: None, + format: sp_runtime::generic::ExtrinsicFormat::Bare, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time1 }), }, CheckedExtrinsic { - signed: Some((charlie(), signed_extra(0, 0))), + format: sp_runtime::generic::ExtrinsicFormat::Signed(charlie(), tx_ext(0, 0)), function: RuntimeCall::Sudo(pallet_sudo::Call::sudo { call: Box::new(RuntimeCall::RootTesting( pallet_root_testing::Call::fill_block { ratio: Perbill::from_percent(60) }, @@ -77,11 +77,11 @@ fn fee_multiplier_increases_and_decreases_on_big_weight() { block1.1, vec![ CheckedExtrinsic { - signed: None, + format: sp_runtime::generic::ExtrinsicFormat::Bare, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time2 }), }, CheckedExtrinsic { - signed: Some((charlie(), signed_extra(1, 0))), + format: sp_runtime::generic::ExtrinsicFormat::Signed(charlie(), tx_ext(1, 0)), function: RuntimeCall::System(frame_system::Call::remark { remark: vec![0; 1] }), }, ], @@ -147,7 +147,7 @@ fn transaction_fee_is_correct() { let tip = 1_000_000; let xt = sign(CheckedExtrinsic { - signed: Some((alice(), signed_extra(0, tip))), + format: sp_runtime::generic::ExtrinsicFormat::Signed(alice(), tx_ext(0, tip)), function: RuntimeCall::Balances(default_transfer_call()), }); @@ -211,7 +211,10 @@ fn block_weight_capacity_report() { let num_transfers = block_number * factor; let mut xts = (0..num_transfers) .map(|i| CheckedExtrinsic { - signed: Some((charlie(), signed_extra(nonce + i as Nonce, 0))), + format: sp_runtime::generic::ExtrinsicFormat::Signed( + charlie(), + tx_ext(nonce + i as Nonce, 0), + ), function: RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { dest: bob().into(), value: 0, @@ -222,7 +225,7 @@ fn block_weight_capacity_report() { xts.insert( 0, CheckedExtrinsic { - signed: None, + format: sp_runtime::generic::ExtrinsicFormat::Bare, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time * 1000 }), }, ); @@ -285,13 +288,16 @@ fn block_length_capacity_report() { previous_hash, vec![ CheckedExtrinsic { - signed: None, + format: sp_runtime::generic::ExtrinsicFormat::Bare, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time * 1000, }), }, CheckedExtrinsic { - signed: Some((charlie(), signed_extra(nonce, 0))), + format: sp_runtime::generic::ExtrinsicFormat::Signed( + charlie(), + tx_ext(nonce, 0), + ), function: RuntimeCall::System(frame_system::Call::remark { remark: vec![0u8; (block_number * factor) as usize], }), diff --git a/substrate/bin/node/cli/tests/submit_transaction.rs b/substrate/bin/node/cli/tests/submit_transaction.rs index 5cbb0103d47..f3a5bac8fb5 100644 --- a/substrate/bin/node/cli/tests/submit_transaction.rs +++ b/substrate/bin/node/cli/tests/submit_transaction.rs @@ -130,8 +130,8 @@ fn should_submit_signed_twice_from_the_same_account() { // now check that the transaction nonces are not equal let s = state.read(); fn nonce(tx: UncheckedExtrinsic) -> frame_system::CheckNonce { - let extra = tx.signature.unwrap().2; - extra.5 + let extra = tx.preamble.to_signed().unwrap().2; + (extra.0).5 } let nonce1 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[0]).unwrap()); let nonce2 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[1]).unwrap()); @@ -179,8 +179,8 @@ fn should_submit_signed_twice_from_all_accounts() { // now check that the transaction nonces are not equal let s = state.read(); fn nonce(tx: UncheckedExtrinsic) -> frame_system::CheckNonce { - let extra = tx.signature.unwrap().2; - extra.5 + let extra = tx.preamble.to_signed().unwrap().2; + (extra.0).5 } let nonce1 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[0]).unwrap()); let nonce2 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[1]).unwrap()); @@ -236,7 +236,7 @@ fn submitted_transaction_should_be_valid() { let source = TransactionSource::External; let extrinsic = UncheckedExtrinsic::decode(&mut &*tx0).unwrap(); // add balance to the account - let author = extrinsic.signature.clone().unwrap().0; + let author = extrinsic.preamble.clone().to_signed().clone().unwrap().0; let address = Indices::lookup(author).unwrap(); let data = pallet_balances::AccountData { free: 5_000_000_000_000, ..Default::default() }; let account = frame_system::AccountInfo { providers: 1, data, ..Default::default() }; diff --git a/substrate/bin/node/runtime/Cargo.toml b/substrate/bin/node/runtime/Cargo.toml index 9607d05daf0..bdef42474d0 100644 --- a/substrate/bin/node/runtime/Cargo.toml +++ b/substrate/bin/node/runtime/Cargo.toml @@ -276,6 +276,7 @@ runtime-benchmarks = [ "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", "pallet-alliance/runtime-benchmarks", + "pallet-asset-conversion-tx-payment/runtime-benchmarks", "pallet-asset-conversion/runtime-benchmarks", "pallet-asset-rate/runtime-benchmarks", "pallet-asset-tx-payment/runtime-benchmarks", @@ -333,6 +334,7 @@ runtime-benchmarks = [ "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-tips/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "pallet-transaction-storage/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", "pallet-tx-pause/runtime-benchmarks", diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 5431628c747..f4615802515 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -560,6 +560,7 @@ impl pallet_transaction_payment::Config for Runtime { MinimumMultiplier, MaximumMultiplier, >; + type WeightInfo = pallet_transaction_payment::weights::SubstrateWeight; } impl pallet_asset_tx_payment::Config for Runtime { @@ -569,6 +570,9 @@ impl pallet_asset_tx_payment::Config for Runtime { pallet_assets::BalanceToAssetBalance, CreditToBlockAuthor, >; + type WeightInfo = pallet_asset_tx_payment::weights::SubstrateWeight; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = AssetTxHelper; } impl pallet_asset_conversion_tx_payment::Config for Runtime { @@ -579,6 +583,9 @@ impl pallet_asset_conversion_tx_payment::Config for Runtime { AssetConversion, Native, >; + type WeightInfo = pallet_asset_conversion_tx_payment::weights::SubstrateWeight; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = AssetConversionTxHelper; } impl pallet_skip_feeless_payment::Config for Runtime { @@ -1407,29 +1414,33 @@ where // so the actual block number is `n`. .saturating_sub(1); let era = Era::mortal(period, current_block); - let extra = ( - frame_system::CheckNonZeroSender::::new(), - frame_system::CheckSpecVersion::::new(), - frame_system::CheckTxVersion::::new(), - frame_system::CheckGenesis::::new(), - frame_system::CheckEra::::from(era), - frame_system::CheckNonce::::from(nonce), - frame_system::CheckWeight::::new(), + let tx_ext: TxExtension = ( + ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckEra::::from(era), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + ) + .into(), pallet_skip_feeless_payment::SkipCheckIfFeeless::from( pallet_asset_conversion_tx_payment::ChargeAssetTxPayment::::from( tip, None, ), ), ); - let raw_payload = SignedPayload::new(call, extra) + + let raw_payload = SignedPayload::new(call, tx_ext) .map_err(|e| { log::warn!("Unable to create signed payload: {:?}", e); }) .ok()?; let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?; let address = Indices::unlookup(account); - let (call, extra, _) = raw_payload.deconstruct(); - Some((call, (address, signature, extra))) + let (call, tx_ext, _) = raw_payload.deconstruct(); + Some((call, (address, signature, tx_ext))) } } @@ -2280,19 +2291,21 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The SignedExtension to the basic transaction logic. +/// The TransactionExtension to the basic transaction logic. /// /// When you change this, you **MUST** modify [`sign`] in `bin/node/testing/src/keyring.rs`! /// /// [`sign`]: <../../testing/src/keyring.rs.html> -pub type SignedExtra = ( - frame_system::CheckNonZeroSender, - frame_system::CheckSpecVersion, - frame_system::CheckTxVersion, - frame_system::CheckGenesis, - frame_system::CheckEra, - frame_system::CheckNonce, - frame_system::CheckWeight, +pub type TxExtension = ( + ( + frame_system::CheckNonZeroSender, + frame_system::CheckSpecVersion, + frame_system::CheckTxVersion, + frame_system::CheckGenesis, + frame_system::CheckEra, + frame_system::CheckNonce, + frame_system::CheckWeight, + ), pallet_skip_feeless_payment::SkipCheckIfFeeless< Runtime, pallet_asset_conversion_tx_payment::ChargeAssetTxPayment, @@ -2301,11 +2314,11 @@ pub type SignedExtra = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// The payload being signed in transactions. -pub type SignedPayload = generic::SignedPayload; +pub type SignedPayload = generic::SignedPayload; /// Extrinsic type that has already been checked. -pub type CheckedExtrinsic = generic::CheckedExtrinsic; +pub type CheckedExtrinsic = generic::CheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, @@ -2360,6 +2373,106 @@ mod mmr { pub type Hashing = ::Hashing; } +#[cfg(feature = "runtime-benchmarks")] +pub struct AssetConversionTxHelper; + +#[cfg(feature = "runtime-benchmarks")] +impl pallet_asset_conversion_tx_payment::BenchmarkHelperTrait + for AssetConversionTxHelper +{ + fn create_asset_id_parameter(seed: u32) -> (u32, u32) { + (seed, seed) + } + + fn setup_balances_and_pool(asset_id: u32, account: AccountId) { + use frame_support::{assert_ok, traits::fungibles::Mutate}; + assert_ok!(Assets::force_create( + RuntimeOrigin::root(), + asset_id.into(), + account.clone().into(), /* owner */ + true, /* is_sufficient */ + 1, + )); + + let lp_provider = account.clone(); + let _ = Balances::deposit_creating(&lp_provider, ((u64::MAX as u128) * 100).into()); + assert_ok!(Assets::mint_into( + asset_id.into(), + &lp_provider, + ((u64::MAX as u128) * 100).into() + )); + + let token_native = Box::new(NativeOrWithId::Native); + let token_second = Box::new(NativeOrWithId::WithId(asset_id)); + + assert_ok!(AssetConversion::create_pool( + RuntimeOrigin::signed(lp_provider.clone()), + token_native.clone(), + token_second.clone() + )); + + assert_ok!(AssetConversion::add_liquidity( + RuntimeOrigin::signed(lp_provider.clone()), + token_native, + token_second, + u64::MAX.into(), // 1 desired + u64::MAX.into(), // 2 desired + 1, // 1 min + 1, // 2 min + lp_provider, + )); + } +} + +#[cfg(feature = "runtime-benchmarks")] +pub struct AssetTxHelper; + +#[cfg(feature = "runtime-benchmarks")] +impl pallet_asset_tx_payment::BenchmarkHelperTrait for AssetTxHelper { + fn create_asset_id_parameter(seed: u32) -> (u32, u32) { + (seed, seed) + } + + fn setup_balances_and_pool(asset_id: u32, account: AccountId) { + use frame_support::{assert_ok, traits::fungibles::Mutate}; + assert_ok!(Assets::force_create( + RuntimeOrigin::root(), + asset_id.into(), + account.clone().into(), /* owner */ + true, /* is_sufficient */ + 1, + )); + + let lp_provider = account.clone(); + let _ = Balances::deposit_creating(&lp_provider, ((u64::MAX as u128) * 100).into()); + assert_ok!(Assets::mint_into( + asset_id.into(), + &lp_provider, + ((u64::MAX as u128) * 100).into() + )); + + let token_native = Box::new(NativeOrWithId::Native); + let token_second = Box::new(NativeOrWithId::WithId(asset_id)); + + assert_ok!(AssetConversion::create_pool( + RuntimeOrigin::signed(lp_provider.clone()), + token_native.clone(), + token_second.clone() + )); + + assert_ok!(AssetConversion::add_liquidity( + RuntimeOrigin::signed(lp_provider.clone()), + token_native, + token_second, + u64::MAX.into(), // 1 desired + u64::MAX.into(), // 2 desired + 1, // 1 min + 1, // 2 min + lp_provider, + )); + } +} + #[cfg(feature = "runtime-benchmarks")] mod benches { frame_benchmarking::define_benchmarks!( @@ -2380,6 +2493,9 @@ mod benches { [tasks_example, TasksExample] [pallet_democracy, Democracy] [pallet_asset_conversion, AssetConversion] + [pallet_asset_conversion_tx_payment, AssetConversionTxPayment] + [pallet_asset_tx_payment, AssetTxPayment] + [pallet_transaction_payment, TransactionPayment] [pallet_election_provider_multi_phase, ElectionProviderMultiPhase] [pallet_election_provider_support_benchmarking, EPSBench::] [pallet_elections_phragmen, Elections] @@ -2413,6 +2529,7 @@ mod benches { [pallet_state_trie_migration, StateTrieMigration] [pallet_sudo, Sudo] [frame_system, SystemBench::] + [frame_system_extensions, SystemExtensionsBench::] [pallet_timestamp, Timestamp] [pallet_tips, Tips] [pallet_transaction_storage, TransactionStorage] @@ -2960,6 +3077,7 @@ impl_runtime_apis! { use pallet_offences_benchmarking::Pallet as OffencesBench; use pallet_election_provider_support_benchmarking::Pallet as EPSBench; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use baseline::Pallet as BaselineBench; use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench; @@ -2984,6 +3102,7 @@ impl_runtime_apis! { use pallet_offences_benchmarking::Pallet as OffencesBench; use pallet_election_provider_support_benchmarking::Pallet as EPSBench; use frame_system_benchmarking::Pallet as SystemBench; + use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use baseline::Pallet as BaselineBench; use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench; diff --git a/substrate/bin/node/testing/src/bench.rs b/substrate/bin/node/testing/src/bench.rs index df302a6453b..ccf79eed884 100644 --- a/substrate/bin/node/testing/src/bench.rs +++ b/substrate/bin/node/testing/src/bench.rs @@ -51,6 +51,7 @@ use sp_core::{ed25519, sr25519, traits::SpawnNamed, Pair, Public}; use sp_crypto_hashing::blake2_256; use sp_inherents::InherentData; use sp_runtime::{ + generic::{ExtrinsicFormat, Preamble}, traits::{Block as BlockT, IdentifyAccount, Verify}, OpaqueExtrinsic, }; @@ -295,10 +296,10 @@ impl<'a> Iterator for BlockContentIterator<'a> { let signed = self.keyring.sign( CheckedExtrinsic { - signed: Some(( + format: ExtrinsicFormat::Signed( sender, - signed_extra(0, kitchensink_runtime::ExistentialDeposit::get() + 1), - )), + tx_ext(0, kitchensink_runtime::ExistentialDeposit::get() + 1), + ), function: match self.content.block_type { BlockType::RandomTransfersKeepAlive => RuntimeCall::Balances(BalancesCall::transfer_keep_alive { @@ -562,11 +563,11 @@ impl BenchKeyring { tx_version: u32, genesis_hash: [u8; 32], ) -> UncheckedExtrinsic { - match xt.signed { - Some((signed, extra)) => { + match xt.format { + ExtrinsicFormat::Signed(signed, tx_ext) => { let payload = ( xt.function, - extra.clone(), + tx_ext.clone(), spec_version, tx_version, genesis_hash, @@ -581,11 +582,20 @@ impl BenchKeyring { } }); UncheckedExtrinsic { - signature: Some((sp_runtime::MultiAddress::Id(signed), signature, extra)), + preamble: Preamble::Signed( + sp_runtime::MultiAddress::Id(signed), + signature, + tx_ext, + ), function: payload.0, } }, - None => UncheckedExtrinsic { signature: None, function: xt.function }, + ExtrinsicFormat::Bare => + UncheckedExtrinsic { preamble: Preamble::Bare, function: xt.function }, + ExtrinsicFormat::General(tx_ext) => UncheckedExtrinsic { + preamble: sp_runtime::generic::Preamble::General(tx_ext), + function: xt.function, + }, } } diff --git a/substrate/bin/node/testing/src/keyring.rs b/substrate/bin/node/testing/src/keyring.rs index f712191bed6..13daf915325 100644 --- a/substrate/bin/node/testing/src/keyring.rs +++ b/substrate/bin/node/testing/src/keyring.rs @@ -19,13 +19,13 @@ //! Test accounts. use codec::Encode; -use kitchensink_runtime::{CheckedExtrinsic, SessionKeys, SignedExtra, UncheckedExtrinsic}; +use kitchensink_runtime::{CheckedExtrinsic, SessionKeys, TxExtension, UncheckedExtrinsic}; use node_cli::chain_spec::get_from_seed; use node_primitives::{AccountId, Balance, Nonce}; use sp_core::{ecdsa, ed25519, sr25519}; use sp_crypto_hashing::blake2_256; use sp_keyring::AccountKeyring; -use sp_runtime::generic::Era; +use sp_runtime::generic::{Era, ExtrinsicFormat}; /// Alice's account id. pub fn alice() -> AccountId { @@ -70,15 +70,18 @@ pub fn session_keys_from_seed(seed: &str) -> SessionKeys { } /// Returns transaction extra. -pub fn signed_extra(nonce: Nonce, extra_fee: Balance) -> SignedExtra { +pub fn tx_ext(nonce: Nonce, extra_fee: Balance) -> TxExtension { ( - frame_system::CheckNonZeroSender::new(), - frame_system::CheckSpecVersion::new(), - frame_system::CheckTxVersion::new(), - frame_system::CheckGenesis::new(), - frame_system::CheckEra::from(Era::mortal(256, 0)), - frame_system::CheckNonce::from(nonce), - frame_system::CheckWeight::new(), + ( + frame_system::CheckNonZeroSender::new(), + frame_system::CheckSpecVersion::new(), + frame_system::CheckTxVersion::new(), + frame_system::CheckGenesis::new(), + frame_system::CheckEra::from(Era::mortal(256, 0)), + frame_system::CheckNonce::from(nonce), + frame_system::CheckWeight::new(), + ) + .into(), pallet_skip_feeless_payment::SkipCheckIfFeeless::from( pallet_asset_conversion_tx_payment::ChargeAssetTxPayment::from(extra_fee, None), ), @@ -92,10 +95,10 @@ pub fn sign( tx_version: u32, genesis_hash: [u8; 32], ) -> UncheckedExtrinsic { - match xt.signed { - Some((signed, extra)) => { + match xt.format { + ExtrinsicFormat::Signed(signed, tx_ext) => { let payload = - (xt.function, extra.clone(), spec_version, tx_version, genesis_hash, genesis_hash); + (xt.function, tx_ext.clone(), spec_version, tx_version, genesis_hash, genesis_hash); let key = AccountKeyring::from_account_id(&signed).unwrap(); let signature = payload @@ -108,10 +111,21 @@ pub fn sign( }) .into(); UncheckedExtrinsic { - signature: Some((sp_runtime::MultiAddress::Id(signed), signature, extra)), + preamble: sp_runtime::generic::Preamble::Signed( + sp_runtime::MultiAddress::Id(signed), + signature, + tx_ext, + ), function: payload.0, } }, - None => UncheckedExtrinsic { signature: None, function: xt.function }, + ExtrinsicFormat::Bare => UncheckedExtrinsic { + preamble: sp_runtime::generic::Preamble::Bare, + function: xt.function, + }, + ExtrinsicFormat::General(tx_ext) => UncheckedExtrinsic { + preamble: sp_runtime::generic::Preamble::General(tx_ext), + function: xt.function, + }, } } diff --git a/substrate/client/api/src/notifications/tests.rs b/substrate/client/api/src/notifications/tests.rs index fba829b1cf9..7afdcbd9543 100644 --- a/substrate/client/api/src/notifications/tests.rs +++ b/substrate/client/api/src/notifications/tests.rs @@ -18,7 +18,10 @@ use super::*; -use sp_runtime::testing::{Block as RawBlock, ExtrinsicWrapper, H256 as Hash}; +use sp_runtime::{ + generic::UncheckedExtrinsic, + testing::{Block as RawBlock, H256 as Hash}, +}; use std::iter::{empty, Empty}; type TestChangeSet = ( @@ -50,7 +53,7 @@ impl PartialEq for StorageChangeSet { } } -type Block = RawBlock>; +type Block = RawBlock>; #[test] fn triggering_change_should_notify_wildcard_listeners() { diff --git a/substrate/client/db/benches/state_access.rs b/substrate/client/db/benches/state_access.rs index e47559e710d..9f3b8ca77c2 100644 --- a/substrate/client/db/benches/state_access.rs +++ b/substrate/client/db/benches/state_access.rs @@ -22,12 +22,13 @@ use sc_client_api::{Backend as _, BlockImportOperation, NewBlockState, StateBack use sc_client_db::{Backend, BlocksPruning, DatabaseSettings, DatabaseSource, PruningMode}; use sp_core::H256; use sp_runtime::{ - testing::{Block as RawBlock, ExtrinsicWrapper, Header}, + generic::UncheckedExtrinsic, + testing::{Block as RawBlock, Header, MockCallU64}, StateVersion, Storage, }; use tempfile::TempDir; -pub(crate) type Block = RawBlock>; +pub(crate) type Block = RawBlock>; fn insert_blocks(db: &Backend, storage: Vec<(Vec, Vec)>) -> H256 { let mut op = db.begin_operation().unwrap(); diff --git a/substrate/client/db/src/lib.rs b/substrate/client/db/src/lib.rs index 0faa90dfc4f..f22022ef29a 100644 --- a/substrate/client/db/src/lib.rs +++ b/substrate/client/db/src/lib.rs @@ -2573,7 +2573,8 @@ pub(crate) mod tests { use sp_blockchain::{lowest_common_ancestor, tree_route}; use sp_core::H256; use sp_runtime::{ - testing::{Block as RawBlock, ExtrinsicWrapper, Header}, + generic::UncheckedExtrinsic, + testing::{Block as RawBlock, Header, MockCallU64}, traits::{BlakeTwo256, Hash}, ConsensusEngineId, StateVersion, }; @@ -2581,7 +2582,8 @@ pub(crate) mod tests { const CONS0_ENGINE_ID: ConsensusEngineId = *b"CON0"; const CONS1_ENGINE_ID: ConsensusEngineId = *b"CON1"; - pub(crate) type Block = RawBlock>; + type UncheckedXt = UncheckedExtrinsic; + pub(crate) type Block = RawBlock; pub fn insert_header( backend: &Backend, @@ -2600,7 +2602,7 @@ pub(crate) mod tests { parent_hash: H256, _changes: Option, Vec)>>, extrinsics_root: H256, - body: Vec>, + body: Vec, transaction_index: Option>, ) -> Result { use sp_runtime::testing::Digest; @@ -3414,7 +3416,7 @@ pub(crate) mod tests { prev_hash, None, Default::default(), - vec![i.into()], + vec![UncheckedXt::new_transaction(i.into(), ())], None, ) .unwrap(); @@ -3436,11 +3438,20 @@ pub(crate) mod tests { assert_eq!(None, bc.body(blocks[0]).unwrap()); assert_eq!(None, bc.body(blocks[1]).unwrap()); assert_eq!(None, bc.body(blocks[2]).unwrap()); - assert_eq!(Some(vec![3.into()]), bc.body(blocks[3]).unwrap()); - assert_eq!(Some(vec![4.into()]), bc.body(blocks[4]).unwrap()); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(3.into(), ())]), + bc.body(blocks[3]).unwrap() + ); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(4.into(), ())]), + bc.body(blocks[4]).unwrap() + ); } else { for i in 0..5 { - assert_eq!(Some(vec![(i as u64).into()]), bc.body(blocks[i]).unwrap()); + assert_eq!( + Some(vec![UncheckedXt::new_transaction((i as u64).into(), ())]), + bc.body(blocks[i]).unwrap() + ); } } } @@ -3464,7 +3475,7 @@ pub(crate) mod tests { prev_hash, None, Default::default(), - vec![i.into()], + vec![UncheckedXt::new_transaction(i.into(), ())], None, ) .unwrap(); @@ -3473,16 +3484,26 @@ pub(crate) mod tests { } // insert a fork at block 2 - let fork_hash_root = - insert_block(&backend, 2, blocks[1], None, H256::random(), vec![2.into()], None) - .unwrap(); + let fork_hash_root = insert_block( + &backend, + 2, + blocks[1], + None, + H256::random(), + vec![UncheckedXt::new_transaction(2.into(), ())], + None, + ) + .unwrap(); insert_block( &backend, 3, fork_hash_root, None, H256::random(), - vec![3.into(), 11.into()], + vec![ + UncheckedXt::new_transaction(3.into(), ()), + UncheckedXt::new_transaction(11.into(), ()), + ], None, ) .unwrap(); @@ -3492,7 +3513,10 @@ pub(crate) mod tests { backend.commit_operation(op).unwrap(); let bc = backend.blockchain(); - assert_eq!(Some(vec![2.into()]), bc.body(fork_hash_root).unwrap()); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(2.into(), ())]), + bc.body(fork_hash_root).unwrap() + ); for i in 1..5 { let mut op = backend.begin_operation().unwrap(); @@ -3506,16 +3530,28 @@ pub(crate) mod tests { assert_eq!(None, bc.body(blocks[1]).unwrap()); assert_eq!(None, bc.body(blocks[2]).unwrap()); - assert_eq!(Some(vec![3.into()]), bc.body(blocks[3]).unwrap()); - assert_eq!(Some(vec![4.into()]), bc.body(blocks[4]).unwrap()); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(3.into(), ())]), + bc.body(blocks[3]).unwrap() + ); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(4.into(), ())]), + bc.body(blocks[4]).unwrap() + ); } else { for i in 0..5 { - assert_eq!(Some(vec![(i as u64).into()]), bc.body(blocks[i]).unwrap()); + assert_eq!( + Some(vec![UncheckedXt::new_transaction((i as u64).into(), ())]), + bc.body(blocks[i]).unwrap() + ); } } if matches!(pruning, BlocksPruning::KeepAll) { - assert_eq!(Some(vec![2.into()]), bc.body(fork_hash_root).unwrap()); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(2.into(), ())]), + bc.body(fork_hash_root).unwrap() + ); } else { assert_eq!(None, bc.body(fork_hash_root).unwrap()); } @@ -3536,8 +3572,16 @@ pub(crate) mod tests { let backend = Backend::::new_test_with_tx_storage(BlocksPruning::Some(10), 10); let make_block = |index, parent, val: u64| { - insert_block(&backend, index, parent, None, H256::random(), vec![val.into()], None) - .unwrap() + insert_block( + &backend, + index, + parent, + None, + H256::random(), + vec![UncheckedXt::new_transaction(val.into(), ())], + None, + ) + .unwrap() }; let block_0 = make_block(0, Default::default(), 0x00); @@ -3565,18 +3609,30 @@ pub(crate) mod tests { let bc = backend.blockchain(); assert_eq!(None, bc.body(block_1b).unwrap()); assert_eq!(None, bc.body(block_2b).unwrap()); - assert_eq!(Some(vec![0x00.into()]), bc.body(block_0).unwrap()); - assert_eq!(Some(vec![0x1a.into()]), bc.body(block_1a).unwrap()); - assert_eq!(Some(vec![0x2a.into()]), bc.body(block_2a).unwrap()); - assert_eq!(Some(vec![0x3a.into()]), bc.body(block_3a).unwrap()); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(0x00.into(), ())]), + bc.body(block_0).unwrap() + ); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(0x1a.into(), ())]), + bc.body(block_1a).unwrap() + ); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(0x2a.into(), ())]), + bc.body(block_2a).unwrap() + ); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(0x3a.into(), ())]), + bc.body(block_3a).unwrap() + ); } #[test] fn indexed_data_block_body() { let backend = Backend::::new_test_with_tx_storage(BlocksPruning::Some(1), 10); - let x0 = ExtrinsicWrapper::from(0u64).encode(); - let x1 = ExtrinsicWrapper::from(1u64).encode(); + let x0 = UncheckedXt::new_transaction(0.into(), ()).encode(); + let x1 = UncheckedXt::new_transaction(1.into(), ()).encode(); let x0_hash = as sp_core::Hasher>::hash(&x0[1..]); let x1_hash = as sp_core::Hasher>::hash(&x1[1..]); let index = vec![ @@ -3597,7 +3653,10 @@ pub(crate) mod tests { Default::default(), None, Default::default(), - vec![0u64.into(), 1u64.into()], + vec![ + UncheckedXt::new_transaction(0.into(), ()), + UncheckedXt::new_transaction(1.into(), ()), + ], Some(index), ) .unwrap(); @@ -3619,8 +3678,9 @@ pub(crate) mod tests { fn index_invalid_size() { let backend = Backend::::new_test_with_tx_storage(BlocksPruning::Some(1), 10); - let x0 = ExtrinsicWrapper::from(0u64).encode(); - let x1 = ExtrinsicWrapper::from(1u64).encode(); + let x0 = UncheckedXt::new_transaction(0.into(), ()).encode(); + let x1 = UncheckedXt::new_transaction(1.into(), ()).encode(); + let x0_hash = as sp_core::Hasher>::hash(&x0[..]); let x1_hash = as sp_core::Hasher>::hash(&x1[..]); let index = vec![ @@ -3641,7 +3701,10 @@ pub(crate) mod tests { Default::default(), None, Default::default(), - vec![0u64.into(), 1u64.into()], + vec![ + UncheckedXt::new_transaction(0.into(), ()), + UncheckedXt::new_transaction(1.into(), ()), + ], Some(index), ) .unwrap(); @@ -3655,7 +3718,7 @@ pub(crate) mod tests { let backend = Backend::::new_test_with_tx_storage(BlocksPruning::Some(2), 10); let mut blocks = Vec::new(); let mut prev_hash = Default::default(); - let x1 = ExtrinsicWrapper::from(0u64).encode(); + let x1 = UncheckedXt::new_transaction(0.into(), ()).encode(); let x1_hash = as sp_core::Hasher>::hash(&x1[1..]); for i in 0..10 { let mut index = Vec::new(); @@ -3675,7 +3738,7 @@ pub(crate) mod tests { prev_hash, None, Default::default(), - vec![i.into()], + vec![UncheckedXt::new_transaction(i.into(), ())], Some(index), ) .unwrap(); @@ -3709,7 +3772,7 @@ pub(crate) mod tests { prev_hash, None, Default::default(), - vec![i.into()], + vec![UncheckedXt::new_transaction(i.into(), ())], None, ) .unwrap(); @@ -3724,7 +3787,7 @@ pub(crate) mod tests { blocks[1], None, sp_core::H256::random(), - vec![i.into()], + vec![UncheckedXt::new_transaction(i.into(), ())], None, ) .unwrap(); @@ -3738,7 +3801,7 @@ pub(crate) mod tests { blocks[0], None, sp_core::H256::random(), - vec![42.into()], + vec![UncheckedXt::new_transaction(42.into(), ())], None, ) .unwrap(); @@ -4211,7 +4274,7 @@ pub(crate) mod tests { prev_hash, None, Default::default(), - vec![i.into()], + vec![UncheckedXt::new_transaction(i.into(), ())], None, ) .unwrap(); @@ -4226,7 +4289,10 @@ pub(crate) mod tests { // Check that we can properly access values when there is reference count // but no value. - assert_eq!(Some(vec![1.into()]), bc.body(blocks[1]).unwrap()); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(1.into(), ())]), + bc.body(blocks[1]).unwrap() + ); // Block 1 gets pinned three times backend.pin_block(blocks[1]).unwrap(); @@ -4243,27 +4309,42 @@ pub(crate) mod tests { // Block 0, 1, 2, 3 are pinned, so all values should be cached. // Block 4 is inside the pruning window, its value is in db. - assert_eq!(Some(vec![0.into()]), bc.body(blocks[0]).unwrap()); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(0.into(), ())]), + bc.body(blocks[0]).unwrap() + ); - assert_eq!(Some(vec![1.into()]), bc.body(blocks[1]).unwrap()); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(1.into(), ())]), + bc.body(blocks[1]).unwrap() + ); assert_eq!( Some(Justifications::from(build_justification(1))), bc.justifications(blocks[1]).unwrap() ); - assert_eq!(Some(vec![2.into()]), bc.body(blocks[2]).unwrap()); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(2.into(), ())]), + bc.body(blocks[2]).unwrap() + ); assert_eq!( Some(Justifications::from(build_justification(2))), bc.justifications(blocks[2]).unwrap() ); - assert_eq!(Some(vec![3.into()]), bc.body(blocks[3]).unwrap()); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(3.into(), ())]), + bc.body(blocks[3]).unwrap() + ); assert_eq!( Some(Justifications::from(build_justification(3))), bc.justifications(blocks[3]).unwrap() ); - assert_eq!(Some(vec![4.into()]), bc.body(blocks[4]).unwrap()); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(4.into(), ())]), + bc.body(blocks[4]).unwrap() + ); assert_eq!( Some(Justifications::from(build_justification(4))), bc.justifications(blocks[4]).unwrap() @@ -4294,7 +4375,10 @@ pub(crate) mod tests { assert!(bc.justifications(blocks[1]).unwrap().is_none()); // Block 4 is inside the pruning window and still kept - assert_eq!(Some(vec![4.into()]), bc.body(blocks[4]).unwrap()); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(4.into(), ())]), + bc.body(blocks[4]).unwrap() + ); assert_eq!( Some(Justifications::from(build_justification(4))), bc.justifications(blocks[4]).unwrap() @@ -4302,9 +4386,16 @@ pub(crate) mod tests { // Block tree: // 0 -> 1 -> 2 -> 3 -> 4 -> 5 - let hash = - insert_block(&backend, 5, prev_hash, None, Default::default(), vec![5.into()], None) - .unwrap(); + let hash = insert_block( + &backend, + 5, + prev_hash, + None, + Default::default(), + vec![UncheckedXt::new_transaction(5.into(), ())], + None, + ) + .unwrap(); blocks.push(hash); backend.pin_block(blocks[4]).unwrap(); @@ -4319,12 +4410,18 @@ pub(crate) mod tests { assert!(bc.body(blocks[2]).unwrap().is_none()); assert!(bc.body(blocks[3]).unwrap().is_none()); - assert_eq!(Some(vec![4.into()]), bc.body(blocks[4]).unwrap()); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(4.into(), ())]), + bc.body(blocks[4]).unwrap() + ); assert_eq!( Some(Justifications::from(build_justification(4))), bc.justifications(blocks[4]).unwrap() ); - assert_eq!(Some(vec![5.into()]), bc.body(blocks[5]).unwrap()); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(5.into(), ())]), + bc.body(blocks[5]).unwrap() + ); assert!(bc.header(blocks[5]).ok().flatten().is_some()); backend.unpin_block(blocks[4]); @@ -4334,9 +4431,16 @@ pub(crate) mod tests { // Append a justification to block 5. backend.append_justification(blocks[5], ([0, 0, 0, 1], vec![42])).unwrap(); - let hash = - insert_block(&backend, 6, blocks[5], None, Default::default(), vec![6.into()], None) - .unwrap(); + let hash = insert_block( + &backend, + 6, + blocks[5], + None, + Default::default(), + vec![UncheckedXt::new_transaction(6.into(), ())], + None, + ) + .unwrap(); blocks.push(hash); // Pin block 5 so it gets loaded into the cache on prune @@ -4349,7 +4453,10 @@ pub(crate) mod tests { op.mark_finalized(blocks[6], None).unwrap(); backend.commit_operation(op).unwrap(); - assert_eq!(Some(vec![5.into()]), bc.body(blocks[5]).unwrap()); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(5.into(), ())]), + bc.body(blocks[5]).unwrap() + ); assert!(bc.header(blocks[5]).ok().flatten().is_some()); let mut expected = Justifications::from(build_justification(5)); expected.append(([0, 0, 0, 1], vec![42])); @@ -4371,7 +4478,7 @@ pub(crate) mod tests { prev_hash, None, Default::default(), - vec![i.into()], + vec![UncheckedXt::new_transaction(i.into(), ())], None, ) .unwrap(); @@ -4387,16 +4494,26 @@ pub(crate) mod tests { // Block tree: // 0 -> 1 -> 2 -> 3 -> 4 // \ -> 2 -> 3 - let fork_hash_root = - insert_block(&backend, 2, blocks[1], None, H256::random(), vec![2.into()], None) - .unwrap(); + let fork_hash_root = insert_block( + &backend, + 2, + blocks[1], + None, + H256::random(), + vec![UncheckedXt::new_transaction(2.into(), ())], + None, + ) + .unwrap(); let fork_hash_3 = insert_block( &backend, 3, fork_hash_root, None, H256::random(), - vec![3.into(), 11.into()], + vec![ + UncheckedXt::new_transaction(3.into(), ()), + UncheckedXt::new_transaction(11.into(), ()), + ], None, ) .unwrap(); @@ -4417,14 +4534,35 @@ pub(crate) mod tests { } let bc = backend.blockchain(); - assert_eq!(Some(vec![0.into()]), bc.body(blocks[0]).unwrap()); - assert_eq!(Some(vec![1.into()]), bc.body(blocks[1]).unwrap()); - assert_eq!(Some(vec![2.into()]), bc.body(blocks[2]).unwrap()); - assert_eq!(Some(vec![3.into()]), bc.body(blocks[3]).unwrap()); - assert_eq!(Some(vec![4.into()]), bc.body(blocks[4]).unwrap()); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(0.into(), ())]), + bc.body(blocks[0]).unwrap() + ); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(1.into(), ())]), + bc.body(blocks[1]).unwrap() + ); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(2.into(), ())]), + bc.body(blocks[2]).unwrap() + ); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(3.into(), ())]), + bc.body(blocks[3]).unwrap() + ); + assert_eq!( + Some(vec![UncheckedXt::new_transaction(4.into(), ())]), + bc.body(blocks[4]).unwrap() + ); // Check the fork hashes. assert_eq!(None, bc.body(fork_hash_root).unwrap()); - assert_eq!(Some(vec![3.into(), 11.into()]), bc.body(fork_hash_3).unwrap()); + assert_eq!( + Some(vec![ + UncheckedXt::new_transaction(3.into(), ()), + UncheckedXt::new_transaction(11.into(), ()) + ]), + bc.body(fork_hash_3).unwrap() + ); // Unpin all blocks, except the forked one. for block in &blocks { diff --git a/substrate/client/db/src/utils.rs b/substrate/client/db/src/utils.rs index abf9c4629ce..d2a5f7e718a 100644 --- a/substrate/client/db/src/utils.rs +++ b/substrate/client/db/src/utils.rs @@ -582,14 +582,19 @@ impl<'a, 'b> codec::Input for JoinInput<'a, 'b> { mod tests { use super::*; use codec::Input; - use sp_runtime::testing::{Block as RawBlock, ExtrinsicWrapper}; - type Block = RawBlock>; + use sp_runtime::{ + generic::UncheckedExtrinsic, + testing::{Block as RawBlock, MockCallU64}, + }; + + pub type UncheckedXt = UncheckedExtrinsic; + type Block = RawBlock; #[cfg(feature = "rocksdb")] #[test] fn database_type_subdir_migration() { use std::path::PathBuf; - type Block = RawBlock>; + type Block = RawBlock; fn check_dir_for_db_type( db_type: DatabaseType, diff --git a/substrate/client/network-gossip/src/state_machine.rs b/substrate/client/network-gossip/src/state_machine.rs index 069d7cdba16..f1c830341ea 100644 --- a/substrate/client/network-gossip/src/state_machine.rs +++ b/substrate/client/network-gossip/src/state_machine.rs @@ -550,7 +550,8 @@ mod tests { NotificationSenderError, NotificationSenderT as NotificationSender, ReputationChange, }; use sp_runtime::{ - testing::{Block as RawBlock, ExtrinsicWrapper, H256}, + generic::UncheckedExtrinsic, + testing::{Block as RawBlock, MockCallU64, H256}, traits::NumberFor, }; use std::{ @@ -559,7 +560,7 @@ mod tests { sync::{Arc, Mutex}, }; - type Block = RawBlock>; + type Block = RawBlock>; macro_rules! push_msg { ($consensus:expr, $topic:expr, $hash: expr, $m:expr) => { diff --git a/substrate/client/network/sync/src/blocks.rs b/substrate/client/network/sync/src/blocks.rs index 4988045a478..a115ee94767 100644 --- a/substrate/client/network/sync/src/blocks.rs +++ b/substrate/client/network/sync/src/blocks.rs @@ -265,9 +265,12 @@ mod test { use libp2p::PeerId; use sc_network_common::sync::message; use sp_core::H256; - use sp_runtime::testing::{Block as RawBlock, ExtrinsicWrapper}; + use sp_runtime::{ + generic::UncheckedExtrinsic, + testing::{Block as RawBlock, MockCallU64}, + }; - type Block = RawBlock>; + type Block = RawBlock>; fn is_empty(bc: &BlockCollection) -> bool { bc.blocks.is_empty() && bc.peer_requests.is_empty() diff --git a/substrate/client/transaction-pool/src/lib.rs b/substrate/client/transaction-pool/src/lib.rs index 64b301e6bf3..730cfe36712 100644 --- a/substrate/client/transaction-pool/src/lib.rs +++ b/substrate/client/transaction-pool/src/lib.rs @@ -659,8 +659,13 @@ where }) .unwrap_or_default() .into_iter() - .filter(|tx| tx.is_signed().unwrap_or(true)); - + // TODO [#2415]: This isn't really what we mean - we really want a + // `tx.is_transaction`, since bare transactions may be gossipped as in the case + // of Frontier txs or claims. This will be sorted once we dispense with the + // concept of bare transactions and make inherents the only possible type of + // extrinsics which are bare. At this point we can change this to + // `tx.is_transaction()`. + .filter(|tx| !tx.is_bare()); let mut resubmitted_to_report = 0; resubmit_transactions.extend(block_transactions.into_iter().filter(|tx| { diff --git a/substrate/frame/alliance/src/weights.rs b/substrate/frame/alliance/src/weights.rs index b5bb5095720..0b2d1fca43c 100644 --- a/substrate/frame/alliance/src/weights.rs +++ b/substrate/frame/alliance/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_alliance +//! Autogenerated weights for `pallet_alliance` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/alliance/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/alliance/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_alliance. +/// Weight functions needed for `pallet_alliance`. pub trait WeightInfo { fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight; fn vote(m: u32, ) -> Weight; @@ -74,205 +73,209 @@ pub trait WeightInfo { fn abdicate_fellow_status() -> Weight; } -/// Weights for pallet_alliance using the Substrate node and recommended hardware. +/// Weights for `pallet_alliance` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Alliance Members (r:1 w:0) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion ProposalOf (r:1 w:1) - /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) - /// Storage: AllianceMotion Proposals (r:1 w:1) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion ProposalCount (r:1 w:1) - /// Proof Skipped: AllianceMotion ProposalCount (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Voting (r:0 w:1) - /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:1 w:0) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::ProposalOf` (r:1 w:1) + /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:1) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::ProposalCount` (r:1 w:1) + /// Proof: `AllianceMotion::ProposalCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Voting` (r:0 w:1) + /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `b` is `[1, 1024]`. /// The range of component `m` is `[2, 100]`. /// The range of component `p` is `[1, 100]`. fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `653 + m * (32 ±0) + p * (35 ±0)` + // Measured: `654 + m * (32 ±0) + p * (36 ±0)` // Estimated: `6676 + m * (32 ±0) + p * (36 ±0)` - // Minimum execution time: 36_908_000 picoseconds. - Weight::from_parts(39_040_304, 6676) - // Standard Error: 131 - .saturating_add(Weight::from_parts(781, 0).saturating_mul(b.into())) - // Standard Error: 1_375 - .saturating_add(Weight::from_parts(48_745, 0).saturating_mul(m.into())) - // Standard Error: 1_358 - .saturating_add(Weight::from_parts(148_047, 0).saturating_mul(p.into())) + // Minimum execution time: 30_801_000 picoseconds. + Weight::from_parts(32_942_969, 6676) + // Standard Error: 112 + .saturating_add(Weight::from_parts(614, 0).saturating_mul(b.into())) + // Standard Error: 1_177 + .saturating_add(Weight::from_parts(45_758, 0).saturating_mul(m.into())) + // Standard Error: 1_162 + .saturating_add(Weight::from_parts(136_600, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: Alliance Members (r:1 w:0) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Voting (r:1 w:1) - /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:1 w:0) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Voting` (r:1 w:1) + /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `m` is `[5, 100]`. fn vote(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1042 + m * (64 ±0)` + // Measured: `1113 + m * (64 ±0)` // Estimated: `6676 + m * (64 ±0)` - // Minimum execution time: 30_166_000 picoseconds. - Weight::from_parts(32_798_454, 6676) - // Standard Error: 1_432 - .saturating_add(Weight::from_parts(83_001, 0).saturating_mul(m.into())) + // Minimum execution time: 29_705_000 picoseconds. + Weight::from_parts(30_274_070, 6676) + // Standard Error: 884 + .saturating_add(Weight::from_parts(71_178, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: Alliance Members (r:1 w:0) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Voting (r:1 w:1) - /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: AllianceMotion Members (r:1 w:0) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Proposals (r:1 w:1) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion ProposalOf (r:0 w:1) - /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:1 w:0) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Voting` (r:1 w:1) + /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Members` (r:1 w:0) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:1) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::ProposalOf` (r:0 w:1) + /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_early_disapproved(m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `576 + m * (96 ±0) + p * (36 ±0)` + // Measured: `640 + m * (96 ±0) + p * (36 ±0)` // Estimated: `6676 + m * (97 ±0) + p * (36 ±0)` - // Minimum execution time: 45_173_000 picoseconds. - Weight::from_parts(42_192_020, 6676) - // Standard Error: 1_456 - .saturating_add(Weight::from_parts(66_751, 0).saturating_mul(m.into())) - // Standard Error: 1_420 - .saturating_add(Weight::from_parts(158_161, 0).saturating_mul(p.into())) + // Minimum execution time: 38_596_000 picoseconds. + Weight::from_parts(36_445_536, 6676) + // Standard Error: 1_217 + .saturating_add(Weight::from_parts(69_976, 0).saturating_mul(m.into())) + // Standard Error: 1_187 + .saturating_add(Weight::from_parts(149_706, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 97).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: Alliance Members (r:1 w:0) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Voting (r:1 w:1) - /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: AllianceMotion Members (r:1 w:0) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion ProposalOf (r:1 w:1) - /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) - /// Storage: AllianceMotion Proposals (r:1 w:1) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:1 w:0) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Voting` (r:1 w:1) + /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Members` (r:1 w:0) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::ProposalOf` (r:1 w:1) + /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:1) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `b` is `[1, 1024]`. /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1087 + m * (96 ±0) + p * (39 ±0)` + // Measured: `1220 + m * (96 ±0) + p * (39 ±0)` // Estimated: `6676 + m * (97 ±0) + p * (40 ±0)` - // Minimum execution time: 58_290_000 picoseconds. - Weight::from_parts(54_924_919, 6676) - // Standard Error: 157 - .saturating_add(Weight::from_parts(464, 0).saturating_mul(b.into())) - // Standard Error: 1_665 - .saturating_add(Weight::from_parts(73_183, 0).saturating_mul(m.into())) - // Standard Error: 1_623 - .saturating_add(Weight::from_parts(168_318, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(5_u64)) + // Minimum execution time: 57_602_000 picoseconds. + Weight::from_parts(55_147_214, 6676) + // Standard Error: 127 + .saturating_add(Weight::from_parts(1_650, 0).saturating_mul(b.into())) + // Standard Error: 1_346 + .saturating_add(Weight::from_parts(56_056, 0).saturating_mul(m.into())) + // Standard Error: 1_312 + .saturating_add(Weight::from_parts(168_247, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 97).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) } - /// Storage: Alliance Members (r:1 w:0) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Voting (r:1 w:1) - /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: AllianceMotion Members (r:1 w:0) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Prime (r:1 w:0) - /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Proposals (r:1 w:1) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion ProposalOf (r:0 w:1) - /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:1 w:0) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Voting` (r:1 w:1) + /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Members` (r:1 w:0) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Prime` (r:1 w:0) + /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:1) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::ProposalOf` (r:0 w:1) + /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `m` is `[2, 100]`. /// The range of component `p` is `[1, 100]`. fn close_disapproved(m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `577 + m * (96 ±0) + p * (36 ±0)` + // Measured: `641 + m * (96 ±0) + p * (36 ±0)` // Estimated: `6676 + m * (97 ±0) + p * (36 ±0)` - // Minimum execution time: 46_794_000 picoseconds. - Weight::from_parts(43_092_958, 6676) - // Standard Error: 1_273 - .saturating_add(Weight::from_parts(71_054, 0).saturating_mul(m.into())) - // Standard Error: 1_257 - .saturating_add(Weight::from_parts(152_820, 0).saturating_mul(p.into())) + // Minimum execution time: 40_755_000 picoseconds. + Weight::from_parts(36_953_935, 6676) + // Standard Error: 1_177 + .saturating_add(Weight::from_parts(73_240, 0).saturating_mul(m.into())) + // Standard Error: 1_162 + .saturating_add(Weight::from_parts(149_412, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 97).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: Alliance Members (r:1 w:0) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Voting (r:1 w:1) - /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: AllianceMotion Members (r:1 w:0) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Prime (r:1 w:0) - /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Proposals (r:1 w:1) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion ProposalOf (r:0 w:1) - /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:1 w:0) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Voting` (r:1 w:1) + /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Members` (r:1 w:0) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Prime` (r:1 w:0) + /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:1) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::ProposalOf` (r:0 w:1) + /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `b` is `[1, 1024]`. /// The range of component `m` is `[5, 100]`. /// The range of component `p` is `[1, 100]`. fn close_approved(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `684 + m * (96 ±0) + p * (35 ±0)` + // Measured: `694 + m * (96 ±0) + p * (35 ±0)` // Estimated: `6676 + m * (97 ±0) + p * (36 ±0)` - // Minimum execution time: 47_338_000 picoseconds. - Weight::from_parts(41_257_479, 6676) - // Standard Error: 119 - .saturating_add(Weight::from_parts(1_019, 0).saturating_mul(b.into())) - // Standard Error: 1_277 - .saturating_add(Weight::from_parts(78_453, 0).saturating_mul(m.into())) - // Standard Error: 1_231 - .saturating_add(Weight::from_parts(150_991, 0).saturating_mul(p.into())) + // Minimum execution time: 41_113_000 picoseconds. + Weight::from_parts(36_610_116, 6676) + // Standard Error: 92 + .saturating_add(Weight::from_parts(1_157, 0).saturating_mul(b.into())) + // Standard Error: 984 + .saturating_add(Weight::from_parts(63_050, 0).saturating_mul(m.into())) + // Standard Error: 949 + .saturating_add(Weight::from_parts(150_420, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 97).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: Alliance Members (r:2 w:2) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Members (r:1 w:1) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:2 w:2) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Members` (r:1 w:1) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `m` is `[1, 100]`. /// The range of component `z` is `[0, 100]`. fn init_members(m: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `217` + // Measured: `250` // Estimated: `12362` - // Minimum execution time: 35_012_000 picoseconds. - Weight::from_parts(24_288_079, 12362) - // Standard Error: 878 - .saturating_add(Weight::from_parts(153_615, 0).saturating_mul(m.into())) - // Standard Error: 867 - .saturating_add(Weight::from_parts(129_307, 0).saturating_mul(z.into())) + // Minimum execution time: 30_249_000 picoseconds. + Weight::from_parts(21_364_868, 12362) + // Standard Error: 887 + .saturating_add(Weight::from_parts(131_624, 0).saturating_mul(m.into())) + // Standard Error: 877 + .saturating_add(Weight::from_parts(105_379, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Alliance Members (r:2 w:2) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Proposals (r:1 w:0) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Alliance DepositOf (r:200 w:50) - /// Proof: Alliance DepositOf (max_values: None, max_size: Some(64), added: 2539, mode: MaxEncodedLen) - /// Storage: System Account (r:50 w:50) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: AllianceMotion Members (r:0 w:1) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Prime (r:0 w:1) - /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:2 w:2) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:0) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Alliance::DepositOf` (r:200 w:50) + /// Proof: `Alliance::DepositOf` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:50 w:50) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Members` (r:0 w:1) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Prime` (r:0 w:1) + /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `x` is `[1, 100]`. /// The range of component `y` is `[0, 100]`. /// The range of component `z` is `[0, 50]`. @@ -280,14 +283,14 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0 + x * (50 ±0) + y * (51 ±0) + z * (251 ±0)` // Estimated: `12362 + x * (2539 ±0) + y * (2539 ±0) + z * (2603 ±1)` - // Minimum execution time: 309_235_000 picoseconds. - Weight::from_parts(311_279_000, 12362) - // Standard Error: 26_510 - .saturating_add(Weight::from_parts(543_475, 0).saturating_mul(x.into())) - // Standard Error: 26_382 - .saturating_add(Weight::from_parts(603_169, 0).saturating_mul(y.into())) - // Standard Error: 52_716 - .saturating_add(Weight::from_parts(16_264_836, 0).saturating_mul(z.into())) + // Minimum execution time: 307_414_000 picoseconds. + Weight::from_parts(309_960_000, 12362) + // Standard Error: 29_278 + .saturating_add(Weight::from_parts(588_774, 0).saturating_mul(x.into())) + // Standard Error: 29_137 + .saturating_add(Weight::from_parts(563_245, 0).saturating_mul(y.into())) + // Standard Error: 58_221 + .saturating_add(Weight::from_parts(13_947_604, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(x.into()))) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(y.into()))) @@ -298,397 +301,401 @@ impl WeightInfo for SubstrateWeight { .saturating_add(Weight::from_parts(0, 2539).saturating_mul(y.into())) .saturating_add(Weight::from_parts(0, 2603).saturating_mul(z.into())) } - /// Storage: Alliance Rule (r:0 w:1) - /// Proof: Alliance Rule (max_values: Some(1), max_size: Some(87), added: 582, mode: MaxEncodedLen) + /// Storage: `Alliance::Rule` (r:0 w:1) + /// Proof: `Alliance::Rule` (`max_values`: Some(1), `max_size`: Some(87), added: 582, mode: `MaxEncodedLen`) fn set_rule() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_833_000 picoseconds. - Weight::from_parts(9_313_000, 0) + // Minimum execution time: 6_156_000 picoseconds. + Weight::from_parts(6_560_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Alliance Announcements (r:1 w:1) - /// Proof: Alliance Announcements (max_values: Some(1), max_size: Some(8702), added: 9197, mode: MaxEncodedLen) + /// Storage: `Alliance::Announcements` (r:1 w:1) + /// Proof: `Alliance::Announcements` (`max_values`: Some(1), `max_size`: Some(8702), added: 9197, mode: `MaxEncodedLen`) fn announce() -> Weight { // Proof Size summary in bytes: - // Measured: `246` + // Measured: `279` // Estimated: `10187` - // Minimum execution time: 12_231_000 picoseconds. - Weight::from_parts(12_761_000, 10187) + // Minimum execution time: 8_988_000 picoseconds. + Weight::from_parts(9_476_000, 10187) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Alliance Announcements (r:1 w:1) - /// Proof: Alliance Announcements (max_values: Some(1), max_size: Some(8702), added: 9197, mode: MaxEncodedLen) + /// Storage: `Alliance::Announcements` (r:1 w:1) + /// Proof: `Alliance::Announcements` (`max_values`: Some(1), `max_size`: Some(8702), added: 9197, mode: `MaxEncodedLen`) fn remove_announcement() -> Weight { // Proof Size summary in bytes: - // Measured: `319` + // Measured: `352` // Estimated: `10187` - // Minimum execution time: 13_079_000 picoseconds. - Weight::from_parts(13_612_000, 10187) + // Minimum execution time: 10_126_000 picoseconds. + Weight::from_parts(10_755_000, 10187) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Alliance Members (r:3 w:1) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: Alliance UnscrupulousAccounts (r:1 w:0) - /// Proof: Alliance UnscrupulousAccounts (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Alliance DepositOf (r:0 w:1) - /// Proof: Alliance DepositOf (max_values: None, max_size: Some(64), added: 2539, mode: MaxEncodedLen) + /// Storage: `Alliance::Members` (r:3 w:1) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `Alliance::UnscrupulousAccounts` (r:1 w:0) + /// Proof: `Alliance::UnscrupulousAccounts` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Alliance::DepositOf` (r:0 w:1) + /// Proof: `Alliance::DepositOf` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) fn join_alliance() -> Weight { // Proof Size summary in bytes: - // Measured: `468` + // Measured: `501` // Estimated: `18048` - // Minimum execution time: 44_574_000 picoseconds. - Weight::from_parts(46_157_000, 18048) + // Minimum execution time: 38_878_000 picoseconds. + Weight::from_parts(40_493_000, 18048) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Alliance Members (r:3 w:1) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: Alliance UnscrupulousAccounts (r:1 w:0) - /// Proof: Alliance UnscrupulousAccounts (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: `Alliance::Members` (r:3 w:1) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `Alliance::UnscrupulousAccounts` (r:1 w:0) + /// Proof: `Alliance::UnscrupulousAccounts` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) fn nominate_ally() -> Weight { // Proof Size summary in bytes: - // Measured: `367` + // Measured: `400` // Estimated: `18048` - // Minimum execution time: 26_114_000 picoseconds. - Weight::from_parts(27_069_000, 18048) + // Minimum execution time: 23_265_000 picoseconds. + Weight::from_parts(24_703_000, 18048) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Alliance Members (r:2 w:2) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Proposals (r:1 w:0) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Members (r:0 w:1) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Prime (r:0 w:1) - /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:2 w:2) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:0) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Members` (r:0 w:1) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Prime` (r:0 w:1) + /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn elevate_ally() -> Weight { // Proof Size summary in bytes: - // Measured: `443` + // Measured: `476` // Estimated: `12362` - // Minimum execution time: 25_882_000 picoseconds. - Weight::from_parts(26_923_000, 12362) + // Minimum execution time: 23_049_000 picoseconds. + Weight::from_parts(23_875_000, 12362) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: Alliance Members (r:4 w:2) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Proposals (r:1 w:0) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Members (r:0 w:1) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Prime (r:0 w:1) - /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Alliance RetiringMembers (r:0 w:1) - /// Proof: Alliance RetiringMembers (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: `Alliance::Members` (r:4 w:2) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:0) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Members` (r:0 w:1) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Prime` (r:0 w:1) + /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Alliance::RetiringMembers` (r:0 w:1) + /// Proof: `Alliance::RetiringMembers` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn give_retirement_notice() -> Weight { // Proof Size summary in bytes: - // Measured: `443` + // Measured: `476` // Estimated: `23734` - // Minimum execution time: 34_112_000 picoseconds. - Weight::from_parts(35_499_000, 23734) + // Minimum execution time: 29_124_000 picoseconds. + Weight::from_parts(30_369_000, 23734) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: Alliance RetiringMembers (r:1 w:1) - /// Proof: Alliance RetiringMembers (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) - /// Storage: Alliance Members (r:1 w:1) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: Alliance DepositOf (r:1 w:1) - /// Proof: Alliance DepositOf (max_values: None, max_size: Some(64), added: 2539, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Alliance::RetiringMembers` (r:1 w:1) + /// Proof: `Alliance::RetiringMembers` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `Alliance::Members` (r:1 w:1) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `Alliance::DepositOf` (r:1 w:1) + /// Proof: `Alliance::DepositOf` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn retire() -> Weight { // Proof Size summary in bytes: - // Measured: `687` + // Measured: `720` // Estimated: `6676` - // Minimum execution time: 41_239_000 picoseconds. - Weight::from_parts(42_764_000, 6676) + // Minimum execution time: 36_376_000 picoseconds. + Weight::from_parts(38_221_000, 6676) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: Alliance Members (r:3 w:1) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Proposals (r:1 w:0) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Alliance DepositOf (r:1 w:1) - /// Proof: Alliance DepositOf (max_values: None, max_size: Some(64), added: 2539, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: AllianceMotion Members (r:0 w:1) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Prime (r:0 w:1) - /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:3 w:1) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:0) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Alliance::DepositOf` (r:1 w:1) + /// Proof: `Alliance::DepositOf` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Members` (r:0 w:1) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Prime` (r:0 w:1) + /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn kick_member() -> Weight { // Proof Size summary in bytes: - // Measured: `707` + // Measured: `740` // Estimated: `18048` - // Minimum execution time: 68_071_000 picoseconds. - Weight::from_parts(71_808_000, 18048) + // Minimum execution time: 56_560_000 picoseconds. + Weight::from_parts(58_621_000, 18048) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: Alliance UnscrupulousAccounts (r:1 w:1) - /// Proof: Alliance UnscrupulousAccounts (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) - /// Storage: Alliance UnscrupulousWebsites (r:1 w:1) - /// Proof: Alliance UnscrupulousWebsites (max_values: Some(1), max_size: Some(25702), added: 26197, mode: MaxEncodedLen) + /// Storage: `Alliance::UnscrupulousAccounts` (r:1 w:1) + /// Proof: `Alliance::UnscrupulousAccounts` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `Alliance::UnscrupulousWebsites` (r:1 w:1) + /// Proof: `Alliance::UnscrupulousWebsites` (`max_values`: Some(1), `max_size`: Some(25702), added: 26197, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 100]`. /// The range of component `l` is `[0, 255]`. fn add_unscrupulous_items(n: u32, l: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `246` + // Measured: `279` // Estimated: `27187` - // Minimum execution time: 7_006_000 picoseconds. - Weight::from_parts(7_253_000, 27187) - // Standard Error: 3_403 - .saturating_add(Weight::from_parts(1_680_082, 0).saturating_mul(n.into())) - // Standard Error: 1_333 - .saturating_add(Weight::from_parts(72_943, 0).saturating_mul(l.into())) + // Minimum execution time: 5_191_000 picoseconds. + Weight::from_parts(5_410_000, 27187) + // Standard Error: 3_215 + .saturating_add(Weight::from_parts(1_018_569, 0).saturating_mul(n.into())) + // Standard Error: 1_259 + .saturating_add(Weight::from_parts(68_712, 0).saturating_mul(l.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Alliance UnscrupulousAccounts (r:1 w:1) - /// Proof: Alliance UnscrupulousAccounts (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) - /// Storage: Alliance UnscrupulousWebsites (r:1 w:1) - /// Proof: Alliance UnscrupulousWebsites (max_values: Some(1), max_size: Some(25702), added: 26197, mode: MaxEncodedLen) + /// Storage: `Alliance::UnscrupulousAccounts` (r:1 w:1) + /// Proof: `Alliance::UnscrupulousAccounts` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `Alliance::UnscrupulousWebsites` (r:1 w:1) + /// Proof: `Alliance::UnscrupulousWebsites` (`max_values`: Some(1), `max_size`: Some(25702), added: 26197, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 100]`. /// The range of component `l` is `[0, 255]`. fn remove_unscrupulous_items(n: u32, l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + l * (100 ±0) + n * (289 ±0)` // Estimated: `27187` - // Minimum execution time: 7_292_000 picoseconds. - Weight::from_parts(7_629_000, 27187) - // Standard Error: 176_225 - .saturating_add(Weight::from_parts(16_646_429, 0).saturating_mul(n.into())) - // Standard Error: 69_017 - .saturating_add(Weight::from_parts(310_978, 0).saturating_mul(l.into())) + // Minimum execution time: 5_361_000 picoseconds. + Weight::from_parts(5_494_000, 27187) + // Standard Error: 181_133 + .saturating_add(Weight::from_parts(16_322_982, 0).saturating_mul(n.into())) + // Standard Error: 70_940 + .saturating_add(Weight::from_parts(343_581, 0).saturating_mul(l.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Alliance Members (r:3 w:2) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Proposals (r:1 w:0) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Members (r:0 w:1) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Prime (r:0 w:1) - /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:3 w:2) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:0) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Members` (r:0 w:1) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Prime` (r:0 w:1) + /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn abdicate_fellow_status() -> Weight { // Proof Size summary in bytes: - // Measured: `443` + // Measured: `476` // Estimated: `18048` - // Minimum execution time: 31_798_000 picoseconds. - Weight::from_parts(33_463_000, 18048) + // Minimum execution time: 28_856_000 picoseconds. + Weight::from_parts(29_875_000, 18048) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Alliance Members (r:1 w:0) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion ProposalOf (r:1 w:1) - /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) - /// Storage: AllianceMotion Proposals (r:1 w:1) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion ProposalCount (r:1 w:1) - /// Proof Skipped: AllianceMotion ProposalCount (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Voting (r:0 w:1) - /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:1 w:0) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::ProposalOf` (r:1 w:1) + /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:1) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::ProposalCount` (r:1 w:1) + /// Proof: `AllianceMotion::ProposalCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Voting` (r:0 w:1) + /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `b` is `[1, 1024]`. /// The range of component `m` is `[2, 100]`. /// The range of component `p` is `[1, 100]`. fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `653 + m * (32 ±0) + p * (35 ±0)` + // Measured: `654 + m * (32 ±0) + p * (36 ±0)` // Estimated: `6676 + m * (32 ±0) + p * (36 ±0)` - // Minimum execution time: 36_908_000 picoseconds. - Weight::from_parts(39_040_304, 6676) - // Standard Error: 131 - .saturating_add(Weight::from_parts(781, 0).saturating_mul(b.into())) - // Standard Error: 1_375 - .saturating_add(Weight::from_parts(48_745, 0).saturating_mul(m.into())) - // Standard Error: 1_358 - .saturating_add(Weight::from_parts(148_047, 0).saturating_mul(p.into())) + // Minimum execution time: 30_801_000 picoseconds. + Weight::from_parts(32_942_969, 6676) + // Standard Error: 112 + .saturating_add(Weight::from_parts(614, 0).saturating_mul(b.into())) + // Standard Error: 1_177 + .saturating_add(Weight::from_parts(45_758, 0).saturating_mul(m.into())) + // Standard Error: 1_162 + .saturating_add(Weight::from_parts(136_600, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: Alliance Members (r:1 w:0) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Voting (r:1 w:1) - /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:1 w:0) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Voting` (r:1 w:1) + /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `m` is `[5, 100]`. fn vote(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1042 + m * (64 ±0)` + // Measured: `1113 + m * (64 ±0)` // Estimated: `6676 + m * (64 ±0)` - // Minimum execution time: 30_166_000 picoseconds. - Weight::from_parts(32_798_454, 6676) - // Standard Error: 1_432 - .saturating_add(Weight::from_parts(83_001, 0).saturating_mul(m.into())) + // Minimum execution time: 29_705_000 picoseconds. + Weight::from_parts(30_274_070, 6676) + // Standard Error: 884 + .saturating_add(Weight::from_parts(71_178, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: Alliance Members (r:1 w:0) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Voting (r:1 w:1) - /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: AllianceMotion Members (r:1 w:0) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Proposals (r:1 w:1) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion ProposalOf (r:0 w:1) - /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:1 w:0) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Voting` (r:1 w:1) + /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Members` (r:1 w:0) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:1) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::ProposalOf` (r:0 w:1) + /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_early_disapproved(m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `576 + m * (96 ±0) + p * (36 ±0)` + // Measured: `640 + m * (96 ±0) + p * (36 ±0)` // Estimated: `6676 + m * (97 ±0) + p * (36 ±0)` - // Minimum execution time: 45_173_000 picoseconds. - Weight::from_parts(42_192_020, 6676) - // Standard Error: 1_456 - .saturating_add(Weight::from_parts(66_751, 0).saturating_mul(m.into())) - // Standard Error: 1_420 - .saturating_add(Weight::from_parts(158_161, 0).saturating_mul(p.into())) + // Minimum execution time: 38_596_000 picoseconds. + Weight::from_parts(36_445_536, 6676) + // Standard Error: 1_217 + .saturating_add(Weight::from_parts(69_976, 0).saturating_mul(m.into())) + // Standard Error: 1_187 + .saturating_add(Weight::from_parts(149_706, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 97).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: Alliance Members (r:1 w:0) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Voting (r:1 w:1) - /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: AllianceMotion Members (r:1 w:0) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion ProposalOf (r:1 w:1) - /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) - /// Storage: AllianceMotion Proposals (r:1 w:1) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:1 w:0) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Voting` (r:1 w:1) + /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Members` (r:1 w:0) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::ProposalOf` (r:1 w:1) + /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:1) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `b` is `[1, 1024]`. /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1087 + m * (96 ±0) + p * (39 ±0)` + // Measured: `1220 + m * (96 ±0) + p * (39 ±0)` // Estimated: `6676 + m * (97 ±0) + p * (40 ±0)` - // Minimum execution time: 58_290_000 picoseconds. - Weight::from_parts(54_924_919, 6676) - // Standard Error: 157 - .saturating_add(Weight::from_parts(464, 0).saturating_mul(b.into())) - // Standard Error: 1_665 - .saturating_add(Weight::from_parts(73_183, 0).saturating_mul(m.into())) - // Standard Error: 1_623 - .saturating_add(Weight::from_parts(168_318, 0).saturating_mul(p.into())) - .saturating_add(RocksDbWeight::get().reads(5_u64)) + // Minimum execution time: 57_602_000 picoseconds. + Weight::from_parts(55_147_214, 6676) + // Standard Error: 127 + .saturating_add(Weight::from_parts(1_650, 0).saturating_mul(b.into())) + // Standard Error: 1_346 + .saturating_add(Weight::from_parts(56_056, 0).saturating_mul(m.into())) + // Standard Error: 1_312 + .saturating_add(Weight::from_parts(168_247, 0).saturating_mul(p.into())) + .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 97).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) } - /// Storage: Alliance Members (r:1 w:0) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Voting (r:1 w:1) - /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: AllianceMotion Members (r:1 w:0) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Prime (r:1 w:0) - /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Proposals (r:1 w:1) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion ProposalOf (r:0 w:1) - /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:1 w:0) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Voting` (r:1 w:1) + /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Members` (r:1 w:0) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Prime` (r:1 w:0) + /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:1) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::ProposalOf` (r:0 w:1) + /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `m` is `[2, 100]`. /// The range of component `p` is `[1, 100]`. fn close_disapproved(m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `577 + m * (96 ±0) + p * (36 ±0)` + // Measured: `641 + m * (96 ±0) + p * (36 ±0)` // Estimated: `6676 + m * (97 ±0) + p * (36 ±0)` - // Minimum execution time: 46_794_000 picoseconds. - Weight::from_parts(43_092_958, 6676) - // Standard Error: 1_273 - .saturating_add(Weight::from_parts(71_054, 0).saturating_mul(m.into())) - // Standard Error: 1_257 - .saturating_add(Weight::from_parts(152_820, 0).saturating_mul(p.into())) + // Minimum execution time: 40_755_000 picoseconds. + Weight::from_parts(36_953_935, 6676) + // Standard Error: 1_177 + .saturating_add(Weight::from_parts(73_240, 0).saturating_mul(m.into())) + // Standard Error: 1_162 + .saturating_add(Weight::from_parts(149_412, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 97).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: Alliance Members (r:1 w:0) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Voting (r:1 w:1) - /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: AllianceMotion Members (r:1 w:0) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Prime (r:1 w:0) - /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Proposals (r:1 w:1) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion ProposalOf (r:0 w:1) - /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:1 w:0) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Voting` (r:1 w:1) + /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Members` (r:1 w:0) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Prime` (r:1 w:0) + /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:1) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::ProposalOf` (r:0 w:1) + /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `b` is `[1, 1024]`. /// The range of component `m` is `[5, 100]`. /// The range of component `p` is `[1, 100]`. fn close_approved(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `684 + m * (96 ±0) + p * (35 ±0)` + // Measured: `694 + m * (96 ±0) + p * (35 ±0)` // Estimated: `6676 + m * (97 ±0) + p * (36 ±0)` - // Minimum execution time: 47_338_000 picoseconds. - Weight::from_parts(41_257_479, 6676) - // Standard Error: 119 - .saturating_add(Weight::from_parts(1_019, 0).saturating_mul(b.into())) - // Standard Error: 1_277 - .saturating_add(Weight::from_parts(78_453, 0).saturating_mul(m.into())) - // Standard Error: 1_231 - .saturating_add(Weight::from_parts(150_991, 0).saturating_mul(p.into())) + // Minimum execution time: 41_113_000 picoseconds. + Weight::from_parts(36_610_116, 6676) + // Standard Error: 92 + .saturating_add(Weight::from_parts(1_157, 0).saturating_mul(b.into())) + // Standard Error: 984 + .saturating_add(Weight::from_parts(63_050, 0).saturating_mul(m.into())) + // Standard Error: 949 + .saturating_add(Weight::from_parts(150_420, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 97).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: Alliance Members (r:2 w:2) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Members (r:1 w:1) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:2 w:2) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Members` (r:1 w:1) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `m` is `[1, 100]`. /// The range of component `z` is `[0, 100]`. fn init_members(m: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `217` + // Measured: `250` // Estimated: `12362` - // Minimum execution time: 35_012_000 picoseconds. - Weight::from_parts(24_288_079, 12362) - // Standard Error: 878 - .saturating_add(Weight::from_parts(153_615, 0).saturating_mul(m.into())) - // Standard Error: 867 - .saturating_add(Weight::from_parts(129_307, 0).saturating_mul(z.into())) + // Minimum execution time: 30_249_000 picoseconds. + Weight::from_parts(21_364_868, 12362) + // Standard Error: 887 + .saturating_add(Weight::from_parts(131_624, 0).saturating_mul(m.into())) + // Standard Error: 877 + .saturating_add(Weight::from_parts(105_379, 0).saturating_mul(z.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Alliance Members (r:2 w:2) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Proposals (r:1 w:0) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Alliance DepositOf (r:200 w:50) - /// Proof: Alliance DepositOf (max_values: None, max_size: Some(64), added: 2539, mode: MaxEncodedLen) - /// Storage: System Account (r:50 w:50) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: AllianceMotion Members (r:0 w:1) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Prime (r:0 w:1) - /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:2 w:2) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:0) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Alliance::DepositOf` (r:200 w:50) + /// Proof: `Alliance::DepositOf` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:50 w:50) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Members` (r:0 w:1) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Prime` (r:0 w:1) + /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `x` is `[1, 100]`. /// The range of component `y` is `[0, 100]`. /// The range of component `z` is `[0, 50]`. @@ -696,14 +703,14 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0 + x * (50 ±0) + y * (51 ±0) + z * (251 ±0)` // Estimated: `12362 + x * (2539 ±0) + y * (2539 ±0) + z * (2603 ±1)` - // Minimum execution time: 309_235_000 picoseconds. - Weight::from_parts(311_279_000, 12362) - // Standard Error: 26_510 - .saturating_add(Weight::from_parts(543_475, 0).saturating_mul(x.into())) - // Standard Error: 26_382 - .saturating_add(Weight::from_parts(603_169, 0).saturating_mul(y.into())) - // Standard Error: 52_716 - .saturating_add(Weight::from_parts(16_264_836, 0).saturating_mul(z.into())) + // Minimum execution time: 307_414_000 picoseconds. + Weight::from_parts(309_960_000, 12362) + // Standard Error: 29_278 + .saturating_add(Weight::from_parts(588_774, 0).saturating_mul(x.into())) + // Standard Error: 29_137 + .saturating_add(Weight::from_parts(563_245, 0).saturating_mul(y.into())) + // Standard Error: 58_221 + .saturating_add(Weight::from_parts(13_947_604, 0).saturating_mul(z.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(x.into()))) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(y.into()))) @@ -714,194 +721,194 @@ impl WeightInfo for () { .saturating_add(Weight::from_parts(0, 2539).saturating_mul(y.into())) .saturating_add(Weight::from_parts(0, 2603).saturating_mul(z.into())) } - /// Storage: Alliance Rule (r:0 w:1) - /// Proof: Alliance Rule (max_values: Some(1), max_size: Some(87), added: 582, mode: MaxEncodedLen) + /// Storage: `Alliance::Rule` (r:0 w:1) + /// Proof: `Alliance::Rule` (`max_values`: Some(1), `max_size`: Some(87), added: 582, mode: `MaxEncodedLen`) fn set_rule() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_833_000 picoseconds. - Weight::from_parts(9_313_000, 0) + // Minimum execution time: 6_156_000 picoseconds. + Weight::from_parts(6_560_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Alliance Announcements (r:1 w:1) - /// Proof: Alliance Announcements (max_values: Some(1), max_size: Some(8702), added: 9197, mode: MaxEncodedLen) + /// Storage: `Alliance::Announcements` (r:1 w:1) + /// Proof: `Alliance::Announcements` (`max_values`: Some(1), `max_size`: Some(8702), added: 9197, mode: `MaxEncodedLen`) fn announce() -> Weight { // Proof Size summary in bytes: - // Measured: `246` + // Measured: `279` // Estimated: `10187` - // Minimum execution time: 12_231_000 picoseconds. - Weight::from_parts(12_761_000, 10187) + // Minimum execution time: 8_988_000 picoseconds. + Weight::from_parts(9_476_000, 10187) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Alliance Announcements (r:1 w:1) - /// Proof: Alliance Announcements (max_values: Some(1), max_size: Some(8702), added: 9197, mode: MaxEncodedLen) + /// Storage: `Alliance::Announcements` (r:1 w:1) + /// Proof: `Alliance::Announcements` (`max_values`: Some(1), `max_size`: Some(8702), added: 9197, mode: `MaxEncodedLen`) fn remove_announcement() -> Weight { // Proof Size summary in bytes: - // Measured: `319` + // Measured: `352` // Estimated: `10187` - // Minimum execution time: 13_079_000 picoseconds. - Weight::from_parts(13_612_000, 10187) + // Minimum execution time: 10_126_000 picoseconds. + Weight::from_parts(10_755_000, 10187) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Alliance Members (r:3 w:1) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: Alliance UnscrupulousAccounts (r:1 w:0) - /// Proof: Alliance UnscrupulousAccounts (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Alliance DepositOf (r:0 w:1) - /// Proof: Alliance DepositOf (max_values: None, max_size: Some(64), added: 2539, mode: MaxEncodedLen) + /// Storage: `Alliance::Members` (r:3 w:1) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `Alliance::UnscrupulousAccounts` (r:1 w:0) + /// Proof: `Alliance::UnscrupulousAccounts` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Alliance::DepositOf` (r:0 w:1) + /// Proof: `Alliance::DepositOf` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) fn join_alliance() -> Weight { // Proof Size summary in bytes: - // Measured: `468` + // Measured: `501` // Estimated: `18048` - // Minimum execution time: 44_574_000 picoseconds. - Weight::from_parts(46_157_000, 18048) + // Minimum execution time: 38_878_000 picoseconds. + Weight::from_parts(40_493_000, 18048) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Alliance Members (r:3 w:1) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: Alliance UnscrupulousAccounts (r:1 w:0) - /// Proof: Alliance UnscrupulousAccounts (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: `Alliance::Members` (r:3 w:1) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `Alliance::UnscrupulousAccounts` (r:1 w:0) + /// Proof: `Alliance::UnscrupulousAccounts` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) fn nominate_ally() -> Weight { // Proof Size summary in bytes: - // Measured: `367` + // Measured: `400` // Estimated: `18048` - // Minimum execution time: 26_114_000 picoseconds. - Weight::from_parts(27_069_000, 18048) + // Minimum execution time: 23_265_000 picoseconds. + Weight::from_parts(24_703_000, 18048) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Alliance Members (r:2 w:2) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Proposals (r:1 w:0) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Members (r:0 w:1) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Prime (r:0 w:1) - /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:2 w:2) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:0) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Members` (r:0 w:1) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Prime` (r:0 w:1) + /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn elevate_ally() -> Weight { // Proof Size summary in bytes: - // Measured: `443` + // Measured: `476` // Estimated: `12362` - // Minimum execution time: 25_882_000 picoseconds. - Weight::from_parts(26_923_000, 12362) + // Minimum execution time: 23_049_000 picoseconds. + Weight::from_parts(23_875_000, 12362) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: Alliance Members (r:4 w:2) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Proposals (r:1 w:0) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Members (r:0 w:1) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Prime (r:0 w:1) - /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Alliance RetiringMembers (r:0 w:1) - /// Proof: Alliance RetiringMembers (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: `Alliance::Members` (r:4 w:2) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:0) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Members` (r:0 w:1) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Prime` (r:0 w:1) + /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Alliance::RetiringMembers` (r:0 w:1) + /// Proof: `Alliance::RetiringMembers` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn give_retirement_notice() -> Weight { // Proof Size summary in bytes: - // Measured: `443` + // Measured: `476` // Estimated: `23734` - // Minimum execution time: 34_112_000 picoseconds. - Weight::from_parts(35_499_000, 23734) + // Minimum execution time: 29_124_000 picoseconds. + Weight::from_parts(30_369_000, 23734) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: Alliance RetiringMembers (r:1 w:1) - /// Proof: Alliance RetiringMembers (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) - /// Storage: Alliance Members (r:1 w:1) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: Alliance DepositOf (r:1 w:1) - /// Proof: Alliance DepositOf (max_values: None, max_size: Some(64), added: 2539, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Alliance::RetiringMembers` (r:1 w:1) + /// Proof: `Alliance::RetiringMembers` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `Alliance::Members` (r:1 w:1) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `Alliance::DepositOf` (r:1 w:1) + /// Proof: `Alliance::DepositOf` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn retire() -> Weight { // Proof Size summary in bytes: - // Measured: `687` + // Measured: `720` // Estimated: `6676` - // Minimum execution time: 41_239_000 picoseconds. - Weight::from_parts(42_764_000, 6676) + // Minimum execution time: 36_376_000 picoseconds. + Weight::from_parts(38_221_000, 6676) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: Alliance Members (r:3 w:1) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Proposals (r:1 w:0) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Alliance DepositOf (r:1 w:1) - /// Proof: Alliance DepositOf (max_values: None, max_size: Some(64), added: 2539, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: AllianceMotion Members (r:0 w:1) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Prime (r:0 w:1) - /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:3 w:1) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:0) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Alliance::DepositOf` (r:1 w:1) + /// Proof: `Alliance::DepositOf` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Members` (r:0 w:1) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Prime` (r:0 w:1) + /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn kick_member() -> Weight { // Proof Size summary in bytes: - // Measured: `707` + // Measured: `740` // Estimated: `18048` - // Minimum execution time: 68_071_000 picoseconds. - Weight::from_parts(71_808_000, 18048) + // Minimum execution time: 56_560_000 picoseconds. + Weight::from_parts(58_621_000, 18048) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: Alliance UnscrupulousAccounts (r:1 w:1) - /// Proof: Alliance UnscrupulousAccounts (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) - /// Storage: Alliance UnscrupulousWebsites (r:1 w:1) - /// Proof: Alliance UnscrupulousWebsites (max_values: Some(1), max_size: Some(25702), added: 26197, mode: MaxEncodedLen) + /// Storage: `Alliance::UnscrupulousAccounts` (r:1 w:1) + /// Proof: `Alliance::UnscrupulousAccounts` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `Alliance::UnscrupulousWebsites` (r:1 w:1) + /// Proof: `Alliance::UnscrupulousWebsites` (`max_values`: Some(1), `max_size`: Some(25702), added: 26197, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 100]`. /// The range of component `l` is `[0, 255]`. fn add_unscrupulous_items(n: u32, l: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `246` + // Measured: `279` // Estimated: `27187` - // Minimum execution time: 7_006_000 picoseconds. - Weight::from_parts(7_253_000, 27187) - // Standard Error: 3_403 - .saturating_add(Weight::from_parts(1_680_082, 0).saturating_mul(n.into())) - // Standard Error: 1_333 - .saturating_add(Weight::from_parts(72_943, 0).saturating_mul(l.into())) + // Minimum execution time: 5_191_000 picoseconds. + Weight::from_parts(5_410_000, 27187) + // Standard Error: 3_215 + .saturating_add(Weight::from_parts(1_018_569, 0).saturating_mul(n.into())) + // Standard Error: 1_259 + .saturating_add(Weight::from_parts(68_712, 0).saturating_mul(l.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Alliance UnscrupulousAccounts (r:1 w:1) - /// Proof: Alliance UnscrupulousAccounts (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) - /// Storage: Alliance UnscrupulousWebsites (r:1 w:1) - /// Proof: Alliance UnscrupulousWebsites (max_values: Some(1), max_size: Some(25702), added: 26197, mode: MaxEncodedLen) + /// Storage: `Alliance::UnscrupulousAccounts` (r:1 w:1) + /// Proof: `Alliance::UnscrupulousAccounts` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `Alliance::UnscrupulousWebsites` (r:1 w:1) + /// Proof: `Alliance::UnscrupulousWebsites` (`max_values`: Some(1), `max_size`: Some(25702), added: 26197, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 100]`. /// The range of component `l` is `[0, 255]`. fn remove_unscrupulous_items(n: u32, l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + l * (100 ±0) + n * (289 ±0)` // Estimated: `27187` - // Minimum execution time: 7_292_000 picoseconds. - Weight::from_parts(7_629_000, 27187) - // Standard Error: 176_225 - .saturating_add(Weight::from_parts(16_646_429, 0).saturating_mul(n.into())) - // Standard Error: 69_017 - .saturating_add(Weight::from_parts(310_978, 0).saturating_mul(l.into())) + // Minimum execution time: 5_361_000 picoseconds. + Weight::from_parts(5_494_000, 27187) + // Standard Error: 181_133 + .saturating_add(Weight::from_parts(16_322_982, 0).saturating_mul(n.into())) + // Standard Error: 70_940 + .saturating_add(Weight::from_parts(343_581, 0).saturating_mul(l.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Alliance Members (r:3 w:2) - /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) - /// Storage: AllianceMotion Proposals (r:1 w:0) - /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Members (r:0 w:1) - /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: AllianceMotion Prime (r:0 w:1) - /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Alliance::Members` (r:3 w:2) + /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) + /// Storage: `AllianceMotion::Proposals` (r:1 w:0) + /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Members` (r:0 w:1) + /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `AllianceMotion::Prime` (r:0 w:1) + /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn abdicate_fellow_status() -> Weight { // Proof Size summary in bytes: - // Measured: `443` + // Measured: `476` // Estimated: `18048` - // Minimum execution time: 31_798_000 picoseconds. - Weight::from_parts(33_463_000, 18048) + // Minimum execution time: 28_856_000 picoseconds. + Weight::from_parts(29_875_000, 18048) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } diff --git a/substrate/frame/asset-conversion/src/weights.rs b/substrate/frame/asset-conversion/src/weights.rs index a0e687f7a41..4eaa115c694 100644 --- a/substrate/frame/asset-conversion/src/weights.rs +++ b/substrate/frame/asset-conversion/src/weights.rs @@ -17,24 +17,28 @@ //! Autogenerated weights for `pallet_asset_conversion` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-10-30, STEPS: `5`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `cob`, CPU: `` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/debug/substrate-node +// ./target/production/substrate-node // benchmark // pallet // --chain=dev -// --steps=5 -// --repeat=2 -// --pallet=pallet-asset-conversion +// --steps=50 +// --repeat=20 +// --pallet=pallet_asset_conversion +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 // --output=./substrate/frame/asset-conversion/src/weights.rs +// --header=./substrate/HEADER-APACHE2 // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -59,11 +63,9 @@ pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { /// Storage: `AssetConversion::Pools` (r:1 w:1) /// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) + /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:2 w:2) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:2 w:2) + /// Storage: `Assets::Asset` (r:2 w:0) /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) /// Storage: `AssetConversion::NextPoolAssetId` (r:1 w:1) /// Proof: `AssetConversion::NextPoolAssetId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -73,12 +75,12 @@ impl WeightInfo for SubstrateWeight { /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn create_pool() -> Weight { // Proof Size summary in bytes: - // Measured: `1081` + // Measured: `910` // Estimated: `6360` - // Minimum execution time: 1_576_000_000 picoseconds. - Weight::from_parts(1_668_000_000, 6360) - .saturating_add(T::DbWeight::get().reads(10_u64)) - .saturating_add(T::DbWeight::get().writes(10_u64)) + // Minimum execution time: 82_941_000 picoseconds. + Weight::from_parts(85_526_000, 6360) + .saturating_add(T::DbWeight::get().reads(7_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) } /// Storage: `AssetConversion::Pools` (r:1 w:0) /// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) @@ -86,18 +88,20 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) /// Storage: `Assets::Account` (r:4 w:4) /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `PoolAssets::Asset` (r:1 w:1) /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) /// Storage: `PoolAssets::Account` (r:2 w:2) /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn add_liquidity() -> Weight { // Proof Size summary in bytes: - // Measured: `1761` + // Measured: `1507` // Estimated: `11426` - // Minimum execution time: 1_636_000_000 picoseconds. - Weight::from_parts(1_894_000_000, 11426) - .saturating_add(T::DbWeight::get().reads(10_u64)) - .saturating_add(T::DbWeight::get().writes(9_u64)) + // Minimum execution time: 138_424_000 picoseconds. + Weight::from_parts(142_083_000, 11426) + .saturating_add(T::DbWeight::get().reads(11_u64)) + .saturating_add(T::DbWeight::get().writes(10_u64)) } /// Storage: `AssetConversion::Pools` (r:1 w:0) /// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) @@ -111,10 +115,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn remove_liquidity() -> Weight { // Proof Size summary in bytes: - // Measured: `1750` + // Measured: `1650` // Estimated: `11426` - // Minimum execution time: 1_507_000_000 picoseconds. - Weight::from_parts(1_524_000_000, 11426) + // Minimum execution time: 122_132_000 picoseconds. + Weight::from_parts(125_143_000, 11426) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(8_u64)) } @@ -125,12 +129,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[2, 4]`. fn swap_exact_tokens_for_tokens(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0 + n * (522 ±0)` + // Measured: `89 + n * (419 ±0)` // Estimated: `990 + n * (5218 ±0)` - // Minimum execution time: 937_000_000 picoseconds. - Weight::from_parts(941_000_000, 990) - // Standard Error: 40_863_477 - .saturating_add(Weight::from_parts(205_862_068, 0).saturating_mul(n.into())) + // Minimum execution time: 77_183_000 picoseconds. + Weight::from_parts(78_581_000, 990) + // Standard Error: 306_918 + .saturating_add(Weight::from_parts(10_581_054, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into()))) .saturating_add(Weight::from_parts(0, 5218).saturating_mul(n.into())) @@ -142,12 +146,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[2, 4]`. fn swap_tokens_for_exact_tokens(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0 + n * (522 ±0)` + // Measured: `89 + n * (419 ±0)` // Estimated: `990 + n * (5218 ±0)` - // Minimum execution time: 935_000_000 picoseconds. - Weight::from_parts(947_000_000, 990) - // Standard Error: 46_904_620 - .saturating_add(Weight::from_parts(218_275_862, 0).saturating_mul(n.into())) + // Minimum execution time: 76_962_000 picoseconds. + Weight::from_parts(78_315_000, 990) + // Standard Error: 311_204 + .saturating_add(Weight::from_parts(10_702_400, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into()))) .saturating_add(Weight::from_parts(0, 5218).saturating_mul(n.into())) @@ -158,11 +162,9 @@ impl WeightInfo for SubstrateWeight { impl WeightInfo for () { /// Storage: `AssetConversion::Pools` (r:1 w:1) /// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) + /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:2 w:2) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:2 w:2) + /// Storage: `Assets::Asset` (r:2 w:0) /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) /// Storage: `AssetConversion::NextPoolAssetId` (r:1 w:1) /// Proof: `AssetConversion::NextPoolAssetId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -172,12 +174,12 @@ impl WeightInfo for () { /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn create_pool() -> Weight { // Proof Size summary in bytes: - // Measured: `1081` + // Measured: `910` // Estimated: `6360` - // Minimum execution time: 1_576_000_000 picoseconds. - Weight::from_parts(1_668_000_000, 6360) - .saturating_add(RocksDbWeight::get().reads(10_u64)) - .saturating_add(RocksDbWeight::get().writes(10_u64)) + // Minimum execution time: 82_941_000 picoseconds. + Weight::from_parts(85_526_000, 6360) + .saturating_add(RocksDbWeight::get().reads(7_u64)) + .saturating_add(RocksDbWeight::get().writes(5_u64)) } /// Storage: `AssetConversion::Pools` (r:1 w:0) /// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) @@ -185,18 +187,20 @@ impl WeightInfo for () { /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) /// Storage: `Assets::Account` (r:4 w:4) /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `PoolAssets::Asset` (r:1 w:1) /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) /// Storage: `PoolAssets::Account` (r:2 w:2) /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn add_liquidity() -> Weight { // Proof Size summary in bytes: - // Measured: `1761` + // Measured: `1507` // Estimated: `11426` - // Minimum execution time: 1_636_000_000 picoseconds. - Weight::from_parts(1_894_000_000, 11426) - .saturating_add(RocksDbWeight::get().reads(10_u64)) - .saturating_add(RocksDbWeight::get().writes(9_u64)) + // Minimum execution time: 138_424_000 picoseconds. + Weight::from_parts(142_083_000, 11426) + .saturating_add(RocksDbWeight::get().reads(11_u64)) + .saturating_add(RocksDbWeight::get().writes(10_u64)) } /// Storage: `AssetConversion::Pools` (r:1 w:0) /// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) @@ -210,10 +214,10 @@ impl WeightInfo for () { /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn remove_liquidity() -> Weight { // Proof Size summary in bytes: - // Measured: `1750` + // Measured: `1650` // Estimated: `11426` - // Minimum execution time: 1_507_000_000 picoseconds. - Weight::from_parts(1_524_000_000, 11426) + // Minimum execution time: 122_132_000 picoseconds. + Weight::from_parts(125_143_000, 11426) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(8_u64)) } @@ -224,12 +228,12 @@ impl WeightInfo for () { /// The range of component `n` is `[2, 4]`. fn swap_exact_tokens_for_tokens(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0 + n * (522 ±0)` + // Measured: `89 + n * (419 ±0)` // Estimated: `990 + n * (5218 ±0)` - // Minimum execution time: 937_000_000 picoseconds. - Weight::from_parts(941_000_000, 990) - // Standard Error: 40_863_477 - .saturating_add(Weight::from_parts(205_862_068, 0).saturating_mul(n.into())) + // Minimum execution time: 77_183_000 picoseconds. + Weight::from_parts(78_581_000, 990) + // Standard Error: 306_918 + .saturating_add(Weight::from_parts(10_581_054, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(n.into()))) .saturating_add(Weight::from_parts(0, 5218).saturating_mul(n.into())) @@ -241,12 +245,12 @@ impl WeightInfo for () { /// The range of component `n` is `[2, 4]`. fn swap_tokens_for_exact_tokens(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0 + n * (522 ±0)` + // Measured: `89 + n * (419 ±0)` // Estimated: `990 + n * (5218 ±0)` - // Minimum execution time: 935_000_000 picoseconds. - Weight::from_parts(947_000_000, 990) - // Standard Error: 46_904_620 - .saturating_add(Weight::from_parts(218_275_862, 0).saturating_mul(n.into())) + // Minimum execution time: 76_962_000 picoseconds. + Weight::from_parts(78_315_000, 990) + // Standard Error: 311_204 + .saturating_add(Weight::from_parts(10_702_400, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(n.into()))) .saturating_add(Weight::from_parts(0, 5218).saturating_mul(n.into())) diff --git a/substrate/frame/asset-rate/src/weights.rs b/substrate/frame/asset-rate/src/weights.rs index 582e20e56d7..b8723ee3bed 100644 --- a/substrate/frame/asset-rate/src/weights.rs +++ b/substrate/frame/asset-rate/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_asset_rate +//! Autogenerated weights for `pallet_asset_rate` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/asset-rate/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/asset-rate/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,83 +49,83 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_asset_rate. +/// Weight functions needed for `pallet_asset_rate`. pub trait WeightInfo { fn create() -> Weight; fn update() -> Weight; fn remove() -> Weight; } -/// Weights for pallet_asset_rate using the Substrate node and recommended hardware. +/// Weights for `pallet_asset_rate` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: AssetRate ConversionRateToNative (r:1 w:1) - /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) + /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1) + /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) fn create() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3501` - // Minimum execution time: 11_700_000 picoseconds. - Weight::from_parts(12_158_000, 3501) + // Minimum execution time: 9_447_000 picoseconds. + Weight::from_parts(10_078_000, 3501) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: AssetRate ConversionRateToNative (r:1 w:1) - /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) + /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1) + /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) fn update() -> Weight { // Proof Size summary in bytes: // Measured: `137` // Estimated: `3501` - // Minimum execution time: 12_119_000 picoseconds. - Weight::from_parts(12_548_000, 3501) + // Minimum execution time: 9_844_000 picoseconds. + Weight::from_parts(10_240_000, 3501) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: AssetRate ConversionRateToNative (r:1 w:1) - /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) + /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1) + /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) fn remove() -> Weight { // Proof Size summary in bytes: // Measured: `137` // Estimated: `3501` - // Minimum execution time: 12_541_000 picoseconds. - Weight::from_parts(12_956_000, 3501) + // Minimum execution time: 10_411_000 picoseconds. + Weight::from_parts(10_686_000, 3501) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: AssetRate ConversionRateToNative (r:1 w:1) - /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) + /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1) + /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) fn create() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3501` - // Minimum execution time: 11_700_000 picoseconds. - Weight::from_parts(12_158_000, 3501) + // Minimum execution time: 9_447_000 picoseconds. + Weight::from_parts(10_078_000, 3501) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: AssetRate ConversionRateToNative (r:1 w:1) - /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) + /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1) + /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) fn update() -> Weight { // Proof Size summary in bytes: // Measured: `137` // Estimated: `3501` - // Minimum execution time: 12_119_000 picoseconds. - Weight::from_parts(12_548_000, 3501) + // Minimum execution time: 9_844_000 picoseconds. + Weight::from_parts(10_240_000, 3501) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: AssetRate ConversionRateToNative (r:1 w:1) - /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) + /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1) + /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) fn remove() -> Weight { // Proof Size summary in bytes: // Measured: `137` // Estimated: `3501` - // Minimum execution time: 12_541_000 picoseconds. - Weight::from_parts(12_956_000, 3501) + // Minimum execution time: 10_411_000 picoseconds. + Weight::from_parts(10_686_000, 3501) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/assets/src/weights.rs b/substrate/frame/assets/src/weights.rs index f20f7e317cf..f5199105fe3 100644 --- a/substrate/frame/assets/src/weights.rs +++ b/substrate/frame/assets/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_assets +//! Autogenerated weights for `pallet_assets` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/assets/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/assets/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_assets. +/// Weight functions needed for `pallet_assets`. pub trait WeightInfo { fn create() -> Weight; fn force_create() -> Weight; @@ -86,882 +85,890 @@ pub trait WeightInfo { fn block() -> Weight; } -/// Weights for pallet_assets using the Substrate node and recommended hardware. +/// Weights for `pallet_assets` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn create() -> Weight { // Proof Size summary in bytes: // Measured: `293` // Estimated: `3675` - // Minimum execution time: 31_340_000 picoseconds. - Weight::from_parts(31_977_000, 3675) + // Minimum execution time: 24_690_000 picoseconds. + Weight::from_parts(25_878_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) fn force_create() -> Weight { // Proof Size summary in bytes: // Measured: `153` // Estimated: `3675` - // Minimum execution time: 13_342_000 picoseconds. - Weight::from_parts(13_782_000, 3675) + // Minimum execution time: 10_997_000 picoseconds. + Weight::from_parts(11_369_000, 3675) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) fn start_destroy() -> Weight { // Proof Size summary in bytes: // Measured: `385` // Estimated: `3675` - // Minimum execution time: 14_437_000 picoseconds. - Weight::from_parts(14_833_000, 3675) + // Minimum execution time: 11_536_000 picoseconds. + Weight::from_parts(12_309_000, 3675) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1001 w:1000) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: System Account (r:1000 w:1000) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1001 w:1000) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1000 w:1000) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `c` is `[0, 1000]`. fn destroy_accounts(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + c * (208 ±0)` // Estimated: `3675 + c * (2609 ±0)` - // Minimum execution time: 18_728_000 picoseconds. - Weight::from_parts(18_982_000, 3675) - // Standard Error: 11_708 - .saturating_add(Weight::from_parts(14_363_570, 0).saturating_mul(c.into())) + // Minimum execution time: 15_798_000 picoseconds. + Weight::from_parts(16_005_000, 3675) + // Standard Error: 7_818 + .saturating_add(Weight::from_parts(12_826_278, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(c.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(c.into()))) .saturating_add(Weight::from_parts(0, 2609).saturating_mul(c.into())) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Approvals (r:1001 w:1000) - /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Approvals` (r:1001 w:1000) + /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) /// The range of component `a` is `[0, 1000]`. fn destroy_approvals(a: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `522 + a * (86 ±0)` // Estimated: `3675 + a * (2623 ±0)` - // Minimum execution time: 18_611_000 picoseconds. - Weight::from_parts(18_970_000, 3675) - // Standard Error: 13_224 - .saturating_add(Weight::from_parts(16_397_299, 0).saturating_mul(a.into())) + // Minimum execution time: 16_334_000 picoseconds. + Weight::from_parts(16_616_000, 3675) + // Standard Error: 6_402 + .saturating_add(Weight::from_parts(13_502_238, 0).saturating_mul(a.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(a.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(a.into()))) .saturating_add(Weight::from_parts(0, 2623).saturating_mul(a.into())) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Metadata (r:1 w:0) - /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Metadata` (r:1 w:0) + /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) fn finish_destroy() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 14_504_000 picoseconds. - Weight::from_parts(14_906_000, 3675) + // Minimum execution time: 12_278_000 picoseconds. + Weight::from_parts(12_834_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn mint() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 26_653_000 picoseconds. - Weight::from_parts(27_260_000, 3675) + // Minimum execution time: 21_793_000 picoseconds. + Weight::from_parts(22_284_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn burn() -> Weight { // Proof Size summary in bytes: // Measured: `459` // Estimated: `3675` - // Minimum execution time: 33_625_000 picoseconds. - Weight::from_parts(34_474_000, 3675) + // Minimum execution time: 28_712_000 picoseconds. + Weight::from_parts(29_710_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:2 w:2) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:2 w:2) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn transfer() -> Weight { // Proof Size summary in bytes: // Measured: `498` // Estimated: `6208` - // Minimum execution time: 47_609_000 picoseconds. - Weight::from_parts(48_476_000, 6208) + // Minimum execution time: 41_331_000 picoseconds. + Weight::from_parts(42_362_000, 6208) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:2 w:2) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:2 w:2) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn transfer_keep_alive() -> Weight { // Proof Size summary in bytes: // Measured: `498` // Estimated: `6208` - // Minimum execution time: 41_625_000 picoseconds. - Weight::from_parts(43_030_000, 6208) + // Minimum execution time: 37_316_000 picoseconds. + Weight::from_parts(38_200_000, 6208) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:2 w:2) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:2 w:2) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn force_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `498` // Estimated: `6208` - // Minimum execution time: 47_661_000 picoseconds. - Weight::from_parts(48_469_000, 6208) + // Minimum execution time: 41_347_000 picoseconds. + Weight::from_parts(42_625_000, 6208) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: Assets Asset (r:1 w:0) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:0) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn freeze() -> Weight { // Proof Size summary in bytes: // Measured: `459` // Estimated: `3675` - // Minimum execution time: 17_727_000 picoseconds. - Weight::from_parts(18_384_000, 3675) + // Minimum execution time: 15_072_000 picoseconds. + Weight::from_parts(15_925_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:0) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:0) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn thaw() -> Weight { // Proof Size summary in bytes: // Measured: `459` // Estimated: `3675` - // Minimum execution time: 17_657_000 picoseconds. - Weight::from_parts(18_282_000, 3675) + // Minimum execution time: 14_991_000 picoseconds. + Weight::from_parts(15_987_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) fn freeze_asset() -> Weight { // Proof Size summary in bytes: // Measured: `385` // Estimated: `3675` - // Minimum execution time: 13_743_000 picoseconds. - Weight::from_parts(14_193_000, 3675) + // Minimum execution time: 11_296_000 picoseconds. + Weight::from_parts(12_052_000, 3675) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) fn thaw_asset() -> Weight { // Proof Size summary in bytes: // Measured: `385` // Estimated: `3675` - // Minimum execution time: 13_653_000 picoseconds. - Weight::from_parts(14_263_000, 3675) + // Minimum execution time: 11_446_000 picoseconds. + Weight::from_parts(11_791_000, 3675) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Metadata (r:1 w:0) - /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Metadata` (r:1 w:0) + /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) fn transfer_ownership() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 15_328_000 picoseconds. - Weight::from_parts(16_042_000, 3675) + // Minimum execution time: 13_134_000 picoseconds. + Weight::from_parts(13_401_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) fn set_team() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 14_097_000 picoseconds. - Weight::from_parts(14_641_000, 3675) + // Minimum execution time: 11_395_000 picoseconds. + Weight::from_parts(11_718_000, 3675) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:0) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Metadata (r:1 w:1) - /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:0) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Metadata` (r:1 w:1) + /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 50]`. /// The range of component `s` is `[0, 50]`. - fn set_metadata(_n: u32, _s: u32, ) -> Weight { + fn set_metadata(n: u32, _s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 29_535_000 picoseconds. - Weight::from_parts(31_456_892, 3675) + // Minimum execution time: 25_147_000 picoseconds. + Weight::from_parts(26_614_272, 3675) + // Standard Error: 959 + .saturating_add(Weight::from_parts(2_300, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:0) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Metadata (r:1 w:1) - /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:0) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Metadata` (r:1 w:1) + /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) fn clear_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `515` // Estimated: `3675` - // Minimum execution time: 30_680_000 picoseconds. - Weight::from_parts(31_930_000, 3675) + // Minimum execution time: 26_094_000 picoseconds. + Weight::from_parts(27_199_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:0) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Metadata (r:1 w:1) - /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:0) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Metadata` (r:1 w:1) + /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 50]`. /// The range of component `s` is `[0, 50]`. - fn force_set_metadata(_n: u32, s: u32, ) -> Weight { + fn force_set_metadata(n: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `190` // Estimated: `3675` - // Minimum execution time: 14_660_000 picoseconds. - Weight::from_parts(15_718_387, 3675) - // Standard Error: 622 - .saturating_add(Weight::from_parts(2_640, 0).saturating_mul(s.into())) + // Minimum execution time: 11_977_000 picoseconds. + Weight::from_parts(12_719_933, 3675) + // Standard Error: 429 + .saturating_add(Weight::from_parts(3_239, 0).saturating_mul(n.into())) + // Standard Error: 429 + .saturating_add(Weight::from_parts(3_941, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:0) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Metadata (r:1 w:1) - /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:0) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Metadata` (r:1 w:1) + /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) fn force_clear_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `515` // Estimated: `3675` - // Minimum execution time: 30_853_000 picoseconds. - Weight::from_parts(31_483_000, 3675) + // Minimum execution time: 25_859_000 picoseconds. + Weight::from_parts(26_654_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) fn force_asset_status() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 13_632_000 picoseconds. - Weight::from_parts(14_077_000, 3675) + // Minimum execution time: 10_965_000 picoseconds. + Weight::from_parts(11_595_000, 3675) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Approvals (r:1 w:1) - /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Approvals` (r:1 w:1) + /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) fn approve_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `385` // Estimated: `3675` - // Minimum execution time: 33_780_000 picoseconds. - Weight::from_parts(34_533_000, 3675) + // Minimum execution time: 28_427_000 picoseconds. + Weight::from_parts(29_150_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Approvals (r:1 w:1) - /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) - /// Storage: Assets Account (r:2 w:2) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Approvals` (r:1 w:1) + /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:2 w:2) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn transfer_approved() -> Weight { // Proof Size summary in bytes: // Measured: `668` // Estimated: `6208` - // Minimum execution time: 67_712_000 picoseconds. - Weight::from_parts(69_946_000, 6208) + // Minimum execution time: 60_227_000 picoseconds. + Weight::from_parts(61_839_000, 6208) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Approvals (r:1 w:1) - /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Approvals` (r:1 w:1) + /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) fn cancel_approval() -> Weight { // Proof Size summary in bytes: // Measured: `555` // Estimated: `3675` - // Minimum execution time: 36_668_000 picoseconds. - Weight::from_parts(37_637_000, 3675) + // Minimum execution time: 30_738_000 picoseconds. + Weight::from_parts(31_988_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Approvals (r:1 w:1) - /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Approvals` (r:1 w:1) + /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) fn force_cancel_approval() -> Weight { // Proof Size summary in bytes: // Measured: `555` // Estimated: `3675` - // Minimum execution time: 36_685_000 picoseconds. - Weight::from_parts(37_950_000, 3675) + // Minimum execution time: 31_444_000 picoseconds. + Weight::from_parts(32_126_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) fn set_min_balance() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 14_466_000 picoseconds. - Weight::from_parts(14_924_000, 3675) + // Minimum execution time: 11_890_000 picoseconds. + Weight::from_parts(12_462_000, 3675) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn touch() -> Weight { // Proof Size summary in bytes: // Measured: `453` // Estimated: `3675` - // Minimum execution time: 34_874_000 picoseconds. - Weight::from_parts(36_330_000, 3675) + // Minimum execution time: 30_675_000 picoseconds. + Weight::from_parts(31_749_000, 3675) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) fn touch_other() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 33_278_000 picoseconds. - Weight::from_parts(34_104_000, 3675) + // Minimum execution time: 28_290_000 picoseconds. + Weight::from_parts(29_405_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn refund() -> Weight { // Proof Size summary in bytes: // Measured: `579` // Estimated: `3675` - // Minimum execution time: 32_898_000 picoseconds. - Weight::from_parts(33_489_000, 3675) + // Minimum execution time: 30_195_000 picoseconds. + Weight::from_parts(31_105_000, 3675) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) fn refund_other() -> Weight { // Proof Size summary in bytes: // Measured: `510` // Estimated: `3675` - // Minimum execution time: 31_243_000 picoseconds. - Weight::from_parts(31_909_000, 3675) + // Minimum execution time: 27_785_000 picoseconds. + Weight::from_parts(28_783_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Assets Asset (r:1 w:0) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:0) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn block() -> Weight { // Proof Size summary in bytes: // Measured: `459` // Estimated: `3675` - // Minimum execution time: 17_692_000 picoseconds. - Weight::from_parts(18_253_000, 3675) + // Minimum execution time: 15_318_000 picoseconds. + Weight::from_parts(16_113_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn create() -> Weight { // Proof Size summary in bytes: // Measured: `293` // Estimated: `3675` - // Minimum execution time: 31_340_000 picoseconds. - Weight::from_parts(31_977_000, 3675) + // Minimum execution time: 24_690_000 picoseconds. + Weight::from_parts(25_878_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) fn force_create() -> Weight { // Proof Size summary in bytes: // Measured: `153` // Estimated: `3675` - // Minimum execution time: 13_342_000 picoseconds. - Weight::from_parts(13_782_000, 3675) + // Minimum execution time: 10_997_000 picoseconds. + Weight::from_parts(11_369_000, 3675) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) fn start_destroy() -> Weight { // Proof Size summary in bytes: // Measured: `385` // Estimated: `3675` - // Minimum execution time: 14_437_000 picoseconds. - Weight::from_parts(14_833_000, 3675) + // Minimum execution time: 11_536_000 picoseconds. + Weight::from_parts(12_309_000, 3675) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1001 w:1000) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: System Account (r:1000 w:1000) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1001 w:1000) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1000 w:1000) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `c` is `[0, 1000]`. fn destroy_accounts(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + c * (208 ±0)` // Estimated: `3675 + c * (2609 ±0)` - // Minimum execution time: 18_728_000 picoseconds. - Weight::from_parts(18_982_000, 3675) - // Standard Error: 11_708 - .saturating_add(Weight::from_parts(14_363_570, 0).saturating_mul(c.into())) + // Minimum execution time: 15_798_000 picoseconds. + Weight::from_parts(16_005_000, 3675) + // Standard Error: 7_818 + .saturating_add(Weight::from_parts(12_826_278, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(c.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(RocksDbWeight::get().writes((2_u64).saturating_mul(c.into()))) .saturating_add(Weight::from_parts(0, 2609).saturating_mul(c.into())) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Approvals (r:1001 w:1000) - /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Approvals` (r:1001 w:1000) + /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) /// The range of component `a` is `[0, 1000]`. fn destroy_approvals(a: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `522 + a * (86 ±0)` // Estimated: `3675 + a * (2623 ±0)` - // Minimum execution time: 18_611_000 picoseconds. - Weight::from_parts(18_970_000, 3675) - // Standard Error: 13_224 - .saturating_add(Weight::from_parts(16_397_299, 0).saturating_mul(a.into())) + // Minimum execution time: 16_334_000 picoseconds. + Weight::from_parts(16_616_000, 3675) + // Standard Error: 6_402 + .saturating_add(Weight::from_parts(13_502_238, 0).saturating_mul(a.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(a.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(a.into()))) .saturating_add(Weight::from_parts(0, 2623).saturating_mul(a.into())) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Metadata (r:1 w:0) - /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Metadata` (r:1 w:0) + /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) fn finish_destroy() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 14_504_000 picoseconds. - Weight::from_parts(14_906_000, 3675) + // Minimum execution time: 12_278_000 picoseconds. + Weight::from_parts(12_834_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn mint() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 26_653_000 picoseconds. - Weight::from_parts(27_260_000, 3675) + // Minimum execution time: 21_793_000 picoseconds. + Weight::from_parts(22_284_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn burn() -> Weight { // Proof Size summary in bytes: // Measured: `459` // Estimated: `3675` - // Minimum execution time: 33_625_000 picoseconds. - Weight::from_parts(34_474_000, 3675) + // Minimum execution time: 28_712_000 picoseconds. + Weight::from_parts(29_710_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:2 w:2) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:2 w:2) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn transfer() -> Weight { // Proof Size summary in bytes: // Measured: `498` // Estimated: `6208` - // Minimum execution time: 47_609_000 picoseconds. - Weight::from_parts(48_476_000, 6208) + // Minimum execution time: 41_331_000 picoseconds. + Weight::from_parts(42_362_000, 6208) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:2 w:2) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:2 w:2) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn transfer_keep_alive() -> Weight { // Proof Size summary in bytes: // Measured: `498` // Estimated: `6208` - // Minimum execution time: 41_625_000 picoseconds. - Weight::from_parts(43_030_000, 6208) + // Minimum execution time: 37_316_000 picoseconds. + Weight::from_parts(38_200_000, 6208) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:2 w:2) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:2 w:2) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn force_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `498` // Estimated: `6208` - // Minimum execution time: 47_661_000 picoseconds. - Weight::from_parts(48_469_000, 6208) + // Minimum execution time: 41_347_000 picoseconds. + Weight::from_parts(42_625_000, 6208) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: Assets Asset (r:1 w:0) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:0) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn freeze() -> Weight { // Proof Size summary in bytes: // Measured: `459` // Estimated: `3675` - // Minimum execution time: 17_727_000 picoseconds. - Weight::from_parts(18_384_000, 3675) + // Minimum execution time: 15_072_000 picoseconds. + Weight::from_parts(15_925_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:0) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:0) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn thaw() -> Weight { // Proof Size summary in bytes: // Measured: `459` // Estimated: `3675` - // Minimum execution time: 17_657_000 picoseconds. - Weight::from_parts(18_282_000, 3675) + // Minimum execution time: 14_991_000 picoseconds. + Weight::from_parts(15_987_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) fn freeze_asset() -> Weight { // Proof Size summary in bytes: // Measured: `385` // Estimated: `3675` - // Minimum execution time: 13_743_000 picoseconds. - Weight::from_parts(14_193_000, 3675) + // Minimum execution time: 11_296_000 picoseconds. + Weight::from_parts(12_052_000, 3675) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) fn thaw_asset() -> Weight { // Proof Size summary in bytes: // Measured: `385` // Estimated: `3675` - // Minimum execution time: 13_653_000 picoseconds. - Weight::from_parts(14_263_000, 3675) + // Minimum execution time: 11_446_000 picoseconds. + Weight::from_parts(11_791_000, 3675) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Metadata (r:1 w:0) - /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Metadata` (r:1 w:0) + /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) fn transfer_ownership() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 15_328_000 picoseconds. - Weight::from_parts(16_042_000, 3675) + // Minimum execution time: 13_134_000 picoseconds. + Weight::from_parts(13_401_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) fn set_team() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 14_097_000 picoseconds. - Weight::from_parts(14_641_000, 3675) + // Minimum execution time: 11_395_000 picoseconds. + Weight::from_parts(11_718_000, 3675) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:0) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Metadata (r:1 w:1) - /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:0) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Metadata` (r:1 w:1) + /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 50]`. /// The range of component `s` is `[0, 50]`. - fn set_metadata(_n: u32, _s: u32, ) -> Weight { + fn set_metadata(n: u32, _s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 29_535_000 picoseconds. - Weight::from_parts(31_456_892, 3675) + // Minimum execution time: 25_147_000 picoseconds. + Weight::from_parts(26_614_272, 3675) + // Standard Error: 959 + .saturating_add(Weight::from_parts(2_300, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:0) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Metadata (r:1 w:1) - /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:0) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Metadata` (r:1 w:1) + /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) fn clear_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `515` // Estimated: `3675` - // Minimum execution time: 30_680_000 picoseconds. - Weight::from_parts(31_930_000, 3675) + // Minimum execution time: 26_094_000 picoseconds. + Weight::from_parts(27_199_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:0) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Metadata (r:1 w:1) - /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:0) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Metadata` (r:1 w:1) + /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 50]`. /// The range of component `s` is `[0, 50]`. - fn force_set_metadata(_n: u32, s: u32, ) -> Weight { + fn force_set_metadata(n: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `190` // Estimated: `3675` - // Minimum execution time: 14_660_000 picoseconds. - Weight::from_parts(15_718_387, 3675) - // Standard Error: 622 - .saturating_add(Weight::from_parts(2_640, 0).saturating_mul(s.into())) + // Minimum execution time: 11_977_000 picoseconds. + Weight::from_parts(12_719_933, 3675) + // Standard Error: 429 + .saturating_add(Weight::from_parts(3_239, 0).saturating_mul(n.into())) + // Standard Error: 429 + .saturating_add(Weight::from_parts(3_941, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:0) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Metadata (r:1 w:1) - /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:0) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Metadata` (r:1 w:1) + /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) fn force_clear_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `515` // Estimated: `3675` - // Minimum execution time: 30_853_000 picoseconds. - Weight::from_parts(31_483_000, 3675) + // Minimum execution time: 25_859_000 picoseconds. + Weight::from_parts(26_654_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) fn force_asset_status() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 13_632_000 picoseconds. - Weight::from_parts(14_077_000, 3675) + // Minimum execution time: 10_965_000 picoseconds. + Weight::from_parts(11_595_000, 3675) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Approvals (r:1 w:1) - /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Approvals` (r:1 w:1) + /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) fn approve_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `385` // Estimated: `3675` - // Minimum execution time: 33_780_000 picoseconds. - Weight::from_parts(34_533_000, 3675) + // Minimum execution time: 28_427_000 picoseconds. + Weight::from_parts(29_150_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Approvals (r:1 w:1) - /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) - /// Storage: Assets Account (r:2 w:2) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Approvals` (r:1 w:1) + /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:2 w:2) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn transfer_approved() -> Weight { // Proof Size summary in bytes: // Measured: `668` // Estimated: `6208` - // Minimum execution time: 67_712_000 picoseconds. - Weight::from_parts(69_946_000, 6208) + // Minimum execution time: 60_227_000 picoseconds. + Weight::from_parts(61_839_000, 6208) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Approvals (r:1 w:1) - /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Approvals` (r:1 w:1) + /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) fn cancel_approval() -> Weight { // Proof Size summary in bytes: // Measured: `555` // Estimated: `3675` - // Minimum execution time: 36_668_000 picoseconds. - Weight::from_parts(37_637_000, 3675) + // Minimum execution time: 30_738_000 picoseconds. + Weight::from_parts(31_988_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Approvals (r:1 w:1) - /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Approvals` (r:1 w:1) + /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) fn force_cancel_approval() -> Weight { // Proof Size summary in bytes: // Measured: `555` // Estimated: `3675` - // Minimum execution time: 36_685_000 picoseconds. - Weight::from_parts(37_950_000, 3675) + // Minimum execution time: 31_444_000 picoseconds. + Weight::from_parts(32_126_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) fn set_min_balance() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 14_466_000 picoseconds. - Weight::from_parts(14_924_000, 3675) + // Minimum execution time: 11_890_000 picoseconds. + Weight::from_parts(12_462_000, 3675) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn touch() -> Weight { // Proof Size summary in bytes: // Measured: `453` // Estimated: `3675` - // Minimum execution time: 34_874_000 picoseconds. - Weight::from_parts(36_330_000, 3675) + // Minimum execution time: 30_675_000 picoseconds. + Weight::from_parts(31_749_000, 3675) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) fn touch_other() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 33_278_000 picoseconds. - Weight::from_parts(34_104_000, 3675) + // Minimum execution time: 28_290_000 picoseconds. + Weight::from_parts(29_405_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn refund() -> Weight { // Proof Size summary in bytes: // Measured: `579` // Estimated: `3675` - // Minimum execution time: 32_898_000 picoseconds. - Weight::from_parts(33_489_000, 3675) + // Minimum execution time: 30_195_000 picoseconds. + Weight::from_parts(31_105_000, 3675) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) fn refund_other() -> Weight { // Proof Size summary in bytes: // Measured: `510` // Estimated: `3675` - // Minimum execution time: 31_243_000 picoseconds. - Weight::from_parts(31_909_000, 3675) + // Minimum execution time: 27_785_000 picoseconds. + Weight::from_parts(28_783_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Assets Asset (r:1 w:0) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: `Assets::Asset` (r:1 w:0) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn block() -> Weight { // Proof Size summary in bytes: // Measured: `459` // Estimated: `3675` - // Minimum execution time: 17_692_000 picoseconds. - Weight::from_parts(18_253_000, 3675) + // Minimum execution time: 15_318_000 picoseconds. + Weight::from_parts(16_113_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/babe/src/mock.rs b/substrate/frame/babe/src/mock.rs index b693f4fce9b..1ba0cdd0cc1 100644 --- a/substrate/frame/babe/src/mock.rs +++ b/substrate/frame/babe/src/mock.rs @@ -37,8 +37,9 @@ use sp_core::{ use sp_io; use sp_runtime::{ curve::PiecewiseLinear, + generic::UncheckedExtrinsic, impl_opaque_keys, - testing::{Digest, DigestItem, Header, TestXt}, + testing::{Digest, DigestItem, Header}, traits::{Header as _, OpaqueKeys}, BuildStorage, Perbill, }; @@ -74,7 +75,7 @@ where RuntimeCall: From, { type OverarchingCall = RuntimeCall; - type Extrinsic = TestXt; + type Extrinsic = UncheckedExtrinsic; } impl_opaque_keys! { diff --git a/substrate/frame/bags-list/src/weights.rs b/substrate/frame/bags-list/src/weights.rs index d929c6bb959..804b702cc9a 100644 --- a/substrate/frame/bags-list/src/weights.rs +++ b/substrate/frame/bags-list/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_bags_list +//! Autogenerated weights for `pallet_bags_list` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/bags-list/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/bags-list/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,123 +49,123 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_bags_list. +/// Weight functions needed for `pallet_bags_list`. pub trait WeightInfo { fn rebag_non_terminal() -> Weight; fn rebag_terminal() -> Weight; fn put_in_front_of() -> Weight; } -/// Weights for pallet_bags_list using the Substrate node and recommended hardware. +/// Weights for `pallet_bags_list` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Staking Bonded (r:1 w:0) - /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) - /// Storage: Staking Ledger (r:1 w:0) - /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) - /// Storage: VoterList ListNodes (r:4 w:4) - /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) - /// Storage: VoterList ListBags (r:1 w:1) - /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: `Staking::Bonded` (r:1 w:0) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `Staking::Ledger` (r:1 w:0) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:4 w:4) + /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListBags` (r:1 w:1) + /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) fn rebag_non_terminal() -> Weight { // Proof Size summary in bytes: - // Measured: `1724` + // Measured: `1719` // Estimated: `11506` - // Minimum execution time: 62_137_000 picoseconds. - Weight::from_parts(64_050_000, 11506) + // Minimum execution time: 55_856_000 picoseconds. + Weight::from_parts(59_022_000, 11506) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: Staking Bonded (r:1 w:0) - /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) - /// Storage: Staking Ledger (r:1 w:0) - /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) - /// Storage: VoterList ListNodes (r:3 w:3) - /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) - /// Storage: VoterList ListBags (r:2 w:2) - /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: `Staking::Bonded` (r:1 w:0) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `Staking::Ledger` (r:1 w:0) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:3 w:3) + /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListBags` (r:2 w:2) + /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) fn rebag_terminal() -> Weight { // Proof Size summary in bytes: - // Measured: `1618` + // Measured: `1613` // Estimated: `8877` - // Minimum execution time: 60_880_000 picoseconds. - Weight::from_parts(62_078_000, 8877) + // Minimum execution time: 55_418_000 picoseconds. + Weight::from_parts(57_352_000, 8877) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: VoterList ListNodes (r:4 w:4) - /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) - /// Storage: Staking Bonded (r:2 w:0) - /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) - /// Storage: Staking Ledger (r:2 w:0) - /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) - /// Storage: VoterList CounterForListNodes (r:1 w:1) - /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: VoterList ListBags (r:1 w:1) - /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: `VoterList::ListNodes` (r:4 w:4) + /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) + /// Storage: `Staking::Bonded` (r:2 w:0) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `Staking::Ledger` (r:2 w:0) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) + /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListBags` (r:1 w:1) + /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) fn put_in_front_of() -> Weight { // Proof Size summary in bytes: - // Measured: `1930` + // Measured: `1925` // Estimated: `11506` - // Minimum execution time: 68_911_000 picoseconds. - Weight::from_parts(70_592_000, 11506) + // Minimum execution time: 63_820_000 picoseconds. + Weight::from_parts(65_530_000, 11506) .saturating_add(T::DbWeight::get().reads(10_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Staking Bonded (r:1 w:0) - /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) - /// Storage: Staking Ledger (r:1 w:0) - /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) - /// Storage: VoterList ListNodes (r:4 w:4) - /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) - /// Storage: VoterList ListBags (r:1 w:1) - /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: `Staking::Bonded` (r:1 w:0) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `Staking::Ledger` (r:1 w:0) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:4 w:4) + /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListBags` (r:1 w:1) + /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) fn rebag_non_terminal() -> Weight { // Proof Size summary in bytes: - // Measured: `1724` + // Measured: `1719` // Estimated: `11506` - // Minimum execution time: 62_137_000 picoseconds. - Weight::from_parts(64_050_000, 11506) + // Minimum execution time: 55_856_000 picoseconds. + Weight::from_parts(59_022_000, 11506) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: Staking Bonded (r:1 w:0) - /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) - /// Storage: Staking Ledger (r:1 w:0) - /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) - /// Storage: VoterList ListNodes (r:3 w:3) - /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) - /// Storage: VoterList ListBags (r:2 w:2) - /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: `Staking::Bonded` (r:1 w:0) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `Staking::Ledger` (r:1 w:0) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:3 w:3) + /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListBags` (r:2 w:2) + /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) fn rebag_terminal() -> Weight { // Proof Size summary in bytes: - // Measured: `1618` + // Measured: `1613` // Estimated: `8877` - // Minimum execution time: 60_880_000 picoseconds. - Weight::from_parts(62_078_000, 8877) + // Minimum execution time: 55_418_000 picoseconds. + Weight::from_parts(57_352_000, 8877) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: VoterList ListNodes (r:4 w:4) - /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) - /// Storage: Staking Bonded (r:2 w:0) - /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) - /// Storage: Staking Ledger (r:2 w:0) - /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) - /// Storage: VoterList CounterForListNodes (r:1 w:1) - /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: VoterList ListBags (r:1 w:1) - /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: `VoterList::ListNodes` (r:4 w:4) + /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) + /// Storage: `Staking::Bonded` (r:2 w:0) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `Staking::Ledger` (r:2 w:0) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) + /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListBags` (r:1 w:1) + /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) fn put_in_front_of() -> Weight { // Proof Size summary in bytes: - // Measured: `1930` + // Measured: `1925` // Estimated: `11506` - // Minimum execution time: 68_911_000 picoseconds. - Weight::from_parts(70_592_000, 11506) + // Minimum execution time: 63_820_000 picoseconds. + Weight::from_parts(65_530_000, 11506) .saturating_add(RocksDbWeight::get().reads(10_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } diff --git a/substrate/frame/balances/Cargo.toml b/substrate/frame/balances/Cargo.toml index 64ae90c6757..db114290ed8 100644 --- a/substrate/frame/balances/Cargo.toml +++ b/substrate/frame/balances/Cargo.toml @@ -53,6 +53,7 @@ runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "sp-runtime/runtime-benchmarks", ] try-runtime = [ diff --git a/substrate/frame/balances/src/tests/currency_tests.rs b/substrate/frame/balances/src/tests/currency_tests.rs index 46a4c4caefc..10bb79901f8 100644 --- a/substrate/frame/balances/src/tests/currency_tests.rs +++ b/substrate/frame/balances/src/tests/currency_tests.rs @@ -30,6 +30,7 @@ use frame_support::{ StorageNoopGuard, }; use frame_system::Event as SysEvent; +use sp_runtime::traits::DispatchTransaction; const ID_1: LockIdentifier = *b"1 "; const ID_2: LockIdentifier = *b"2 "; @@ -240,17 +241,17 @@ fn lock_should_work_reserve() { TokenError::Frozen ); assert_noop!(Balances::reserve(&1, 1), Error::::LiquidityRestrictions,); - assert!( as SignedExtension>::pre_dispatch( + assert!(ChargeTransactionPayment::::validate_and_prepare( ChargeTransactionPayment::from(1), - &1, + Some(1).into(), CALL, &info_from_weight(Weight::from_parts(1, 0)), 1, ) .is_err()); - assert!( as SignedExtension>::pre_dispatch( + assert!(ChargeTransactionPayment::::validate_and_prepare( ChargeTransactionPayment::from(0), - &1, + Some(1).into(), CALL, &info_from_weight(Weight::from_parts(1, 0)), 1, @@ -271,17 +272,17 @@ fn lock_should_work_tx_fee() { TokenError::Frozen ); assert_noop!(Balances::reserve(&1, 1), Error::::LiquidityRestrictions,); - assert!( as SignedExtension>::pre_dispatch( + assert!(ChargeTransactionPayment::::validate_and_prepare( ChargeTransactionPayment::from(1), - &1, + Some(1).into(), CALL, &info_from_weight(Weight::from_parts(1, 0)), 1, ) .is_err()); - assert!( as SignedExtension>::pre_dispatch( + assert!(ChargeTransactionPayment::::validate_and_prepare( ChargeTransactionPayment::from(0), - &1, + Some(1).into(), CALL, &info_from_weight(Weight::from_parts(1, 0)), 1, diff --git a/substrate/frame/balances/src/tests/mod.rs b/substrate/frame/balances/src/tests/mod.rs index 599909fa943..ee076a10fd1 100644 --- a/substrate/frame/balances/src/tests/mod.rs +++ b/substrate/frame/balances/src/tests/mod.rs @@ -37,7 +37,7 @@ use scale_info::TypeInfo; use sp_core::hexdisplay::HexDisplay; use sp_io; use sp_runtime::{ - traits::{BadOrigin, SignedExtension, Zero}, + traits::{BadOrigin, Zero}, ArithmeticError, BuildStorage, DispatchError, DispatchResult, FixedPointNumber, RuntimeDebug, TokenError, }; @@ -96,13 +96,13 @@ impl frame_system::Config for Test { type AccountData = super::AccountData; } +#[derive_impl(pallet_transaction_payment::config_preludes::TestDefaultConfig as pallet_transaction_payment::DefaultConfig)] impl pallet_transaction_payment::Config for Test { type RuntimeEvent = RuntimeEvent; type OnChargeTransaction = CurrencyAdapter, ()>; type OperationalFeeMultiplier = ConstU8<5>; type WeightToFee = IdentityFee; type LengthToFee = IdentityFee; - type FeeMultiplierUpdate = (); } pub(crate) type Balance = u64; diff --git a/substrate/frame/balances/src/weights.rs b/substrate/frame/balances/src/weights.rs index f875ea189ba..6bcfe050af7 100644 --- a/substrate/frame/balances/src/weights.rs +++ b/substrate/frame/balances/src/weights.rs @@ -17,26 +17,28 @@ //! Autogenerated weights for `pallet_balances` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-01-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// target/production/substrate-node +// ./target/production/substrate-node // benchmark // pallet +// --chain=dev // --steps=50 // --repeat=20 +// --pallet=pallet_balances +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_balances -// --chain=dev -// --header=./substrate/HEADER-APACHE2 // --output=./substrate/frame/balances/src/weights.rs +// --header=./substrate/HEADER-APACHE2 // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -69,8 +71,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 46_329_000 picoseconds. - Weight::from_parts(47_297_000, 3593) + // Minimum execution time: 46_407_000 picoseconds. + Weight::from_parts(47_561_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -80,8 +82,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 36_187_000 picoseconds. - Weight::from_parts(36_900_000, 3593) + // Minimum execution time: 36_574_000 picoseconds. + Weight::from_parts(37_682_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -91,8 +93,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 13_498_000 picoseconds. - Weight::from_parts(14_143_000, 3593) + // Minimum execution time: 13_990_000 picoseconds. + Weight::from_parts(14_568_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -102,8 +104,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 18_756_000 picoseconds. - Weight::from_parts(19_553_000, 3593) + // Minimum execution time: 19_594_000 picoseconds. + Weight::from_parts(20_148_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -113,8 +115,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `103` // Estimated: `6196` - // Minimum execution time: 47_826_000 picoseconds. - Weight::from_parts(48_834_000, 6196) + // Minimum execution time: 47_945_000 picoseconds. + Weight::from_parts(49_363_000, 6196) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -124,8 +126,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 44_621_000 picoseconds. - Weight::from_parts(45_151_000, 3593) + // Minimum execution time: 45_205_000 picoseconds. + Weight::from_parts(45_952_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -135,8 +137,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 16_194_000 picoseconds. - Weight::from_parts(16_945_000, 3593) + // Minimum execution time: 16_593_000 picoseconds. + Weight::from_parts(17_123_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -147,10 +149,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0 + u * (135 ±0)` // Estimated: `990 + u * (2603 ±0)` - // Minimum execution time: 15_782_000 picoseconds. - Weight::from_parts(16_118_000, 990) - // Standard Error: 10_499 - .saturating_add(Weight::from_parts(13_327_660, 0).saturating_mul(u.into())) + // Minimum execution time: 16_182_000 picoseconds. + Weight::from_parts(16_412_000, 990) + // Standard Error: 10_148 + .saturating_add(Weight::from_parts(13_382_459, 0).saturating_mul(u.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into()))) .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) @@ -159,8 +161,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_157_000 picoseconds. - Weight::from_parts(6_507_000, 0) + // Minimum execution time: 6_478_000 picoseconds. + Weight::from_parts(6_830_000, 0) } } @@ -172,8 +174,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 46_329_000 picoseconds. - Weight::from_parts(47_297_000, 3593) + // Minimum execution time: 46_407_000 picoseconds. + Weight::from_parts(47_561_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -183,8 +185,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 36_187_000 picoseconds. - Weight::from_parts(36_900_000, 3593) + // Minimum execution time: 36_574_000 picoseconds. + Weight::from_parts(37_682_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -194,8 +196,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 13_498_000 picoseconds. - Weight::from_parts(14_143_000, 3593) + // Minimum execution time: 13_990_000 picoseconds. + Weight::from_parts(14_568_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -205,8 +207,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 18_756_000 picoseconds. - Weight::from_parts(19_553_000, 3593) + // Minimum execution time: 19_594_000 picoseconds. + Weight::from_parts(20_148_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -216,8 +218,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `103` // Estimated: `6196` - // Minimum execution time: 47_826_000 picoseconds. - Weight::from_parts(48_834_000, 6196) + // Minimum execution time: 47_945_000 picoseconds. + Weight::from_parts(49_363_000, 6196) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -227,8 +229,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 44_621_000 picoseconds. - Weight::from_parts(45_151_000, 3593) + // Minimum execution time: 45_205_000 picoseconds. + Weight::from_parts(45_952_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -238,8 +240,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 16_194_000 picoseconds. - Weight::from_parts(16_945_000, 3593) + // Minimum execution time: 16_593_000 picoseconds. + Weight::from_parts(17_123_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -250,10 +252,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0 + u * (135 ±0)` // Estimated: `990 + u * (2603 ±0)` - // Minimum execution time: 15_782_000 picoseconds. - Weight::from_parts(16_118_000, 990) - // Standard Error: 10_499 - .saturating_add(Weight::from_parts(13_327_660, 0).saturating_mul(u.into())) + // Minimum execution time: 16_182_000 picoseconds. + Weight::from_parts(16_412_000, 990) + // Standard Error: 10_148 + .saturating_add(Weight::from_parts(13_382_459, 0).saturating_mul(u.into())) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(u.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(u.into()))) .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) @@ -262,7 +264,7 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_157_000 picoseconds. - Weight::from_parts(6_507_000, 0) + // Minimum execution time: 6_478_000 picoseconds. + Weight::from_parts(6_830_000, 0) } } diff --git a/substrate/frame/beefy/src/mock.rs b/substrate/frame/beefy/src/mock.rs index 9cce479890a..5d963d309a4 100644 --- a/substrate/frame/beefy/src/mock.rs +++ b/substrate/frame/beefy/src/mock.rs @@ -29,8 +29,8 @@ use pallet_session::historical as pallet_session_historical; use sp_core::{crypto::KeyTypeId, ConstU128}; use sp_io::TestExternalities; use sp_runtime::{ - app_crypto::ecdsa::Public, curve::PiecewiseLinear, impl_opaque_keys, testing::TestXt, - traits::OpaqueKeys, BuildStorage, Perbill, + app_crypto::ecdsa::Public, curve::PiecewiseLinear, generic::UncheckedExtrinsic, + impl_opaque_keys, traits::OpaqueKeys, BuildStorage, Perbill, }; use sp_staking::{EraIndex, SessionIndex}; use sp_state_machine::BasicExternalities; @@ -73,7 +73,7 @@ where RuntimeCall: From, { type OverarchingCall = RuntimeCall; - type Extrinsic = TestXt; + type Extrinsic = UncheckedExtrinsic; } parameter_types! { diff --git a/substrate/frame/benchmarking/src/weights.rs b/substrate/frame/benchmarking/src/weights.rs index 13d73e420cc..76f9a3fe52b 100644 --- a/substrate/frame/benchmarking/src/weights.rs +++ b/substrate/frame/benchmarking/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for frame_benchmarking +//! Autogenerated weights for `frame_benchmarking` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/benchmarking/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/benchmarking/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for frame_benchmarking. +/// Weight functions needed for `frame_benchmarking`. pub trait WeightInfo { fn addition(i: u32, ) -> Weight; fn subtraction(i: u32, ) -> Weight; @@ -60,7 +59,7 @@ pub trait WeightInfo { fn sr25519_verification(i: u32, ) -> Weight; } -/// Weights for frame_benchmarking using the Substrate node and recommended hardware. +/// Weights for `frame_benchmarking` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { /// The range of component `i` is `[0, 1000000]`. @@ -68,101 +67,101 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 147_000 picoseconds. - Weight::from_parts(185_656, 0) + // Minimum execution time: 150_000 picoseconds. + Weight::from_parts(190_440, 0) } /// The range of component `i` is `[0, 1000000]`. fn subtraction(_i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 146_000 picoseconds. - Weight::from_parts(189_816, 0) + // Minimum execution time: 151_000 picoseconds. + Weight::from_parts(201_397, 0) } /// The range of component `i` is `[0, 1000000]`. fn multiplication(_i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 148_000 picoseconds. - Weight::from_parts(202_367, 0) + // Minimum execution time: 152_000 picoseconds. + Weight::from_parts(187_862, 0) } /// The range of component `i` is `[0, 1000000]`. fn division(_i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 143_000 picoseconds. - Weight::from_parts(189_693, 0) + // Minimum execution time: 146_000 picoseconds. + Weight::from_parts(215_191, 0) } fn hashing() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 24_167_071_000 picoseconds. - Weight::from_parts(24_391_749_000, 0) + // Minimum execution time: 25_432_823_000 picoseconds. + Weight::from_parts(25_568_846_000, 0) } /// The range of component `i` is `[0, 100]`. fn sr25519_verification(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 231_000 picoseconds. - Weight::from_parts(2_998_013, 0) - // Standard Error: 6_256 - .saturating_add(Weight::from_parts(55_456_705, 0).saturating_mul(i.into())) + // Minimum execution time: 193_000 picoseconds. + Weight::from_parts(3_846_690, 0) + // Standard Error: 6_694 + .saturating_add(Weight::from_parts(40_647_582, 0).saturating_mul(i.into())) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { /// The range of component `i` is `[0, 1000000]`. fn addition(_i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 147_000 picoseconds. - Weight::from_parts(185_656, 0) + // Minimum execution time: 150_000 picoseconds. + Weight::from_parts(190_440, 0) } /// The range of component `i` is `[0, 1000000]`. fn subtraction(_i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 146_000 picoseconds. - Weight::from_parts(189_816, 0) + // Minimum execution time: 151_000 picoseconds. + Weight::from_parts(201_397, 0) } /// The range of component `i` is `[0, 1000000]`. fn multiplication(_i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 148_000 picoseconds. - Weight::from_parts(202_367, 0) + // Minimum execution time: 152_000 picoseconds. + Weight::from_parts(187_862, 0) } /// The range of component `i` is `[0, 1000000]`. fn division(_i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 143_000 picoseconds. - Weight::from_parts(189_693, 0) + // Minimum execution time: 146_000 picoseconds. + Weight::from_parts(215_191, 0) } fn hashing() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 24_167_071_000 picoseconds. - Weight::from_parts(24_391_749_000, 0) + // Minimum execution time: 25_432_823_000 picoseconds. + Weight::from_parts(25_568_846_000, 0) } /// The range of component `i` is `[0, 100]`. fn sr25519_verification(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 231_000 picoseconds. - Weight::from_parts(2_998_013, 0) - // Standard Error: 6_256 - .saturating_add(Weight::from_parts(55_456_705, 0).saturating_mul(i.into())) + // Minimum execution time: 193_000 picoseconds. + Weight::from_parts(3_846_690, 0) + // Standard Error: 6_694 + .saturating_add(Weight::from_parts(40_647_582, 0).saturating_mul(i.into())) } } diff --git a/substrate/frame/bounties/src/weights.rs b/substrate/frame/bounties/src/weights.rs index a172d15b56c..1f0e38b6702 100644 --- a/substrate/frame/bounties/src/weights.rs +++ b/substrate/frame/bounties/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_bounties +//! Autogenerated weights for `pallet_bounties` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/bounties/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/bounties/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_bounties. +/// Weight functions needed for `pallet_bounties`. pub trait WeightInfo { fn propose_bounty(d: u32, ) -> Weight; fn approve_bounty() -> Weight; @@ -65,169 +64,169 @@ pub trait WeightInfo { fn spend_funds(b: u32, ) -> Weight; } -/// Weights for pallet_bounties using the Substrate node and recommended hardware. +/// Weights for `pallet_bounties` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Bounties BountyCount (r:1 w:1) - /// Proof: Bounties BountyCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Bounties BountyDescriptions (r:0 w:1) - /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) - /// Storage: Bounties Bounties (r:0 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: `Bounties::BountyCount` (r:1 w:1) + /// Proof: `Bounties::BountyCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) + /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) + /// Storage: `Bounties::Bounties` (r:0 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) /// The range of component `d` is `[0, 300]`. fn propose_bounty(d: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `276` + // Measured: `309` // Estimated: `3593` - // Minimum execution time: 29_384_000 picoseconds. - Weight::from_parts(30_820_018, 3593) - // Standard Error: 298 - .saturating_add(Weight::from_parts(2_920, 0).saturating_mul(d.into())) + // Minimum execution time: 24_286_000 picoseconds. + Weight::from_parts(25_657_314, 3593) + // Standard Error: 215 + .saturating_add(Weight::from_parts(1_116, 0).saturating_mul(d.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: Bounties Bounties (r:1 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: Bounties BountyApprovals (r:1 w:1) - /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `Bounties::BountyApprovals` (r:1 w:1) + /// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) fn approve_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `368` + // Measured: `401` // Estimated: `3642` - // Minimum execution time: 10_873_000 picoseconds. - Weight::from_parts(11_421_000, 3642) + // Minimum execution time: 12_526_000 picoseconds. + Weight::from_parts(13_373_000, 3642) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Bounties Bounties (r:1 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) fn propose_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `388` + // Measured: `421` // Estimated: `3642` - // Minimum execution time: 9_181_000 picoseconds. - Weight::from_parts(9_726_000, 3642) + // Minimum execution time: 11_807_000 picoseconds. + Weight::from_parts(12_340_000, 3642) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Bounties Bounties (r:1 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn unassign_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `564` + // Measured: `597` // Estimated: `3642` - // Minimum execution time: 30_257_000 picoseconds. - Weight::from_parts(30_751_000, 3642) + // Minimum execution time: 27_183_000 picoseconds. + Weight::from_parts(28_250_000, 3642) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Bounties Bounties (r:1 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn accept_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `560` + // Measured: `593` // Estimated: `3642` - // Minimum execution time: 27_850_000 picoseconds. - Weight::from_parts(28_821_000, 3642) + // Minimum execution time: 26_775_000 picoseconds. + Weight::from_parts(27_667_000, 3642) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Bounties Bounties (r:1 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: ChildBounties ParentChildBounties (r:1 w:0) - /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) fn award_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `572` + // Measured: `605` // Estimated: `3642` - // Minimum execution time: 19_164_000 picoseconds. - Weight::from_parts(20_136_000, 3642) + // Minimum execution time: 16_089_000 picoseconds. + Weight::from_parts(16_909_000, 3642) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Bounties Bounties (r:1 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: System Account (r:3 w:3) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) - /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) - /// Storage: Bounties BountyDescriptions (r:0 w:1) - /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:3 w:3) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) + /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) + /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) fn claim_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `936` + // Measured: `969` // Estimated: `8799` - // Minimum execution time: 120_235_000 picoseconds. - Weight::from_parts(121_673_000, 8799) + // Minimum execution time: 104_973_000 picoseconds. + Weight::from_parts(107_696_000, 8799) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: Bounties Bounties (r:1 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: ChildBounties ParentChildBounties (r:1 w:0) - /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Bounties BountyDescriptions (r:0 w:1) - /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) + /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) fn close_bounty_proposed() -> Weight { // Proof Size summary in bytes: - // Measured: `616` + // Measured: `649` // Estimated: `3642` - // Minimum execution time: 35_713_000 picoseconds. - Weight::from_parts(37_174_000, 3642) + // Minimum execution time: 30_702_000 picoseconds. + Weight::from_parts(32_615_000, 3642) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Bounties Bounties (r:1 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: ChildBounties ParentChildBounties (r:1 w:0) - /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) - /// Storage: System Account (r:2 w:2) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Bounties BountyDescriptions (r:0 w:1) - /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) + /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) fn close_bounty_active() -> Weight { // Proof Size summary in bytes: - // Measured: `852` + // Measured: `885` // Estimated: `6196` - // Minimum execution time: 81_037_000 picoseconds. - Weight::from_parts(83_294_000, 6196) + // Minimum execution time: 72_055_000 picoseconds. + Weight::from_parts(73_900_000, 6196) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: Bounties Bounties (r:1 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) fn extend_bounty_expiry() -> Weight { // Proof Size summary in bytes: - // Measured: `424` + // Measured: `457` // Estimated: `3642` - // Minimum execution time: 15_348_000 picoseconds. - Weight::from_parts(15_776_000, 3642) + // Minimum execution time: 12_057_000 picoseconds. + Weight::from_parts(12_744_000, 3642) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Bounties BountyApprovals (r:1 w:1) - /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) - /// Storage: Bounties Bounties (r:100 w:100) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: System Account (r:200 w:200) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Bounties::BountyApprovals` (r:1 w:1) + /// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: `Bounties::Bounties` (r:100 w:100) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:200 w:200) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `b` is `[0, 100]`. fn spend_funds(b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `4 + b * (297 ±0)` + // Measured: `37 + b * (297 ±0)` // Estimated: `1887 + b * (5206 ±0)` - // Minimum execution time: 5_082_000 picoseconds. - Weight::from_parts(5_126_000, 1887) - // Standard Error: 21_949 - .saturating_add(Weight::from_parts(42_635_308, 0).saturating_mul(b.into())) + // Minimum execution time: 3_489_000 picoseconds. + Weight::from_parts(8_384_129, 1887) + // Standard Error: 18_066 + .saturating_add(Weight::from_parts(31_612_331, 0).saturating_mul(b.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(b.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) @@ -236,168 +235,168 @@ impl WeightInfo for SubstrateWeight { } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Bounties BountyCount (r:1 w:1) - /// Proof: Bounties BountyCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Bounties BountyDescriptions (r:0 w:1) - /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) - /// Storage: Bounties Bounties (r:0 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: `Bounties::BountyCount` (r:1 w:1) + /// Proof: `Bounties::BountyCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) + /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) + /// Storage: `Bounties::Bounties` (r:0 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) /// The range of component `d` is `[0, 300]`. fn propose_bounty(d: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `276` + // Measured: `309` // Estimated: `3593` - // Minimum execution time: 29_384_000 picoseconds. - Weight::from_parts(30_820_018, 3593) - // Standard Error: 298 - .saturating_add(Weight::from_parts(2_920, 0).saturating_mul(d.into())) + // Minimum execution time: 24_286_000 picoseconds. + Weight::from_parts(25_657_314, 3593) + // Standard Error: 215 + .saturating_add(Weight::from_parts(1_116, 0).saturating_mul(d.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: Bounties Bounties (r:1 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: Bounties BountyApprovals (r:1 w:1) - /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `Bounties::BountyApprovals` (r:1 w:1) + /// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) fn approve_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `368` + // Measured: `401` // Estimated: `3642` - // Minimum execution time: 10_873_000 picoseconds. - Weight::from_parts(11_421_000, 3642) + // Minimum execution time: 12_526_000 picoseconds. + Weight::from_parts(13_373_000, 3642) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Bounties Bounties (r:1 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) fn propose_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `388` + // Measured: `421` // Estimated: `3642` - // Minimum execution time: 9_181_000 picoseconds. - Weight::from_parts(9_726_000, 3642) + // Minimum execution time: 11_807_000 picoseconds. + Weight::from_parts(12_340_000, 3642) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Bounties Bounties (r:1 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn unassign_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `564` + // Measured: `597` // Estimated: `3642` - // Minimum execution time: 30_257_000 picoseconds. - Weight::from_parts(30_751_000, 3642) + // Minimum execution time: 27_183_000 picoseconds. + Weight::from_parts(28_250_000, 3642) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Bounties Bounties (r:1 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn accept_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `560` + // Measured: `593` // Estimated: `3642` - // Minimum execution time: 27_850_000 picoseconds. - Weight::from_parts(28_821_000, 3642) + // Minimum execution time: 26_775_000 picoseconds. + Weight::from_parts(27_667_000, 3642) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Bounties Bounties (r:1 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: ChildBounties ParentChildBounties (r:1 w:0) - /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) fn award_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `572` + // Measured: `605` // Estimated: `3642` - // Minimum execution time: 19_164_000 picoseconds. - Weight::from_parts(20_136_000, 3642) + // Minimum execution time: 16_089_000 picoseconds. + Weight::from_parts(16_909_000, 3642) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Bounties Bounties (r:1 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: System Account (r:3 w:3) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) - /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) - /// Storage: Bounties BountyDescriptions (r:0 w:1) - /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:3 w:3) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) + /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) + /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) fn claim_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `936` + // Measured: `969` // Estimated: `8799` - // Minimum execution time: 120_235_000 picoseconds. - Weight::from_parts(121_673_000, 8799) + // Minimum execution time: 104_973_000 picoseconds. + Weight::from_parts(107_696_000, 8799) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } - /// Storage: Bounties Bounties (r:1 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: ChildBounties ParentChildBounties (r:1 w:0) - /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Bounties BountyDescriptions (r:0 w:1) - /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) + /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) fn close_bounty_proposed() -> Weight { // Proof Size summary in bytes: - // Measured: `616` + // Measured: `649` // Estimated: `3642` - // Minimum execution time: 35_713_000 picoseconds. - Weight::from_parts(37_174_000, 3642) + // Minimum execution time: 30_702_000 picoseconds. + Weight::from_parts(32_615_000, 3642) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Bounties Bounties (r:1 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: ChildBounties ParentChildBounties (r:1 w:0) - /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) - /// Storage: System Account (r:2 w:2) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Bounties BountyDescriptions (r:0 w:1) - /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) + /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) fn close_bounty_active() -> Weight { // Proof Size summary in bytes: - // Measured: `852` + // Measured: `885` // Estimated: `6196` - // Minimum execution time: 81_037_000 picoseconds. - Weight::from_parts(83_294_000, 6196) + // Minimum execution time: 72_055_000 picoseconds. + Weight::from_parts(73_900_000, 6196) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: Bounties Bounties (r:1 w:1) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:1) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) fn extend_bounty_expiry() -> Weight { // Proof Size summary in bytes: - // Measured: `424` + // Measured: `457` // Estimated: `3642` - // Minimum execution time: 15_348_000 picoseconds. - Weight::from_parts(15_776_000, 3642) + // Minimum execution time: 12_057_000 picoseconds. + Weight::from_parts(12_744_000, 3642) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Bounties BountyApprovals (r:1 w:1) - /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) - /// Storage: Bounties Bounties (r:100 w:100) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: System Account (r:200 w:200) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Bounties::BountyApprovals` (r:1 w:1) + /// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: `Bounties::Bounties` (r:100 w:100) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:200 w:200) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `b` is `[0, 100]`. fn spend_funds(b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `4 + b * (297 ±0)` + // Measured: `37 + b * (297 ±0)` // Estimated: `1887 + b * (5206 ±0)` - // Minimum execution time: 5_082_000 picoseconds. - Weight::from_parts(5_126_000, 1887) - // Standard Error: 21_949 - .saturating_add(Weight::from_parts(42_635_308, 0).saturating_mul(b.into())) + // Minimum execution time: 3_489_000 picoseconds. + Weight::from_parts(8_384_129, 1887) + // Standard Error: 18_066 + .saturating_add(Weight::from_parts(31_612_331, 0).saturating_mul(b.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(b.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) diff --git a/substrate/frame/broker/src/weights.rs b/substrate/frame/broker/src/weights.rs index a8f50eeee6e..133ea63e35f 100644 --- a/substrate/frame/broker/src/weights.rs +++ b/substrate/frame/broker/src/weights.rs @@ -17,26 +17,28 @@ //! Autogenerated weights for `pallet_broker` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-09-04, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-pzhd7p6z-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// target/production/substrate-node +// ./target/production/substrate-node // benchmark // pallet +// --chain=dev // --steps=50 // --repeat=20 +// --pallet=pallet_broker +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_broker -// --chain=dev -// --header=./substrate/HEADER-APACHE2 // --output=./substrate/frame/broker/src/weights.rs +// --header=./substrate/HEADER-APACHE2 // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -87,8 +89,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_040_000 picoseconds. - Weight::from_parts(3_344_000, 0) + // Minimum execution time: 2_701_000 picoseconds. + Weight::from_parts(2_902_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Broker::Reservations` (r:1 w:1) @@ -97,8 +99,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `5016` // Estimated: `7496` - // Minimum execution time: 21_259_000 picoseconds. - Weight::from_parts(22_110_000, 7496) + // Minimum execution time: 18_056_000 picoseconds. + Weight::from_parts(19_093_000, 7496) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -108,8 +110,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `6218` // Estimated: `7496` - // Minimum execution time: 20_330_000 picoseconds. - Weight::from_parts(20_826_000, 7496) + // Minimum execution time: 17_233_000 picoseconds. + Weight::from_parts(17_788_000, 7496) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -119,8 +121,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `239` // Estimated: `1526` - // Minimum execution time: 13_411_000 picoseconds. - Weight::from_parts(13_960_000, 1526) + // Minimum execution time: 9_740_000 picoseconds. + Weight::from_parts(10_504_000, 1526) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -139,14 +141,12 @@ impl WeightInfo for SubstrateWeight { /// Storage: `Broker::Workplan` (r:0 w:10) /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. - fn start_sales(n: u32, ) -> Weight { + fn start_sales(_n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `6330` // Estimated: `8499` - // Minimum execution time: 57_770_000 picoseconds. - Weight::from_parts(61_047_512, 8499) - // Standard Error: 165 - .saturating_add(Weight::from_parts(3, 0).saturating_mul(n.into())) + // Minimum execution time: 49_728_000 picoseconds. + Weight::from_parts(52_765_861, 8499) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(16_u64)) } @@ -162,10 +162,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) fn purchase() -> Weight { // Proof Size summary in bytes: - // Measured: `568` - // Estimated: `2053` - // Minimum execution time: 51_196_000 picoseconds. - Weight::from_parts(52_382_000, 2053) + // Measured: `635` + // Estimated: `2120` + // Minimum execution time: 41_986_000 picoseconds. + Weight::from_parts(43_465_000, 2120) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -185,10 +185,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) fn renew() -> Weight { // Proof Size summary in bytes: - // Measured: `686` + // Measured: `753` // Estimated: `4698` - // Minimum execution time: 71_636_000 picoseconds. - Weight::from_parts(73_679_000, 4698) + // Minimum execution time: 61_779_000 picoseconds. + Weight::from_parts(62_563_000, 4698) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -198,8 +198,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3550` - // Minimum execution time: 19_182_000 picoseconds. - Weight::from_parts(19_775_000, 3550) + // Minimum execution time: 16_962_000 picoseconds. + Weight::from_parts(17_733_000, 3550) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -209,21 +209,21 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3550` - // Minimum execution time: 20_688_000 picoseconds. - Weight::from_parts(21_557_000, 3550) + // Minimum execution time: 18_380_000 picoseconds. + Weight::from_parts(19_105_000, 3550) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Broker::Regions` (r:1 w:2) + /// Storage: `Broker::Regions` (r:1 w:3) /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) fn interlace() -> Weight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3550` - // Minimum execution time: 21_190_000 picoseconds. - Weight::from_parts(22_215_000, 3550) + // Minimum execution time: 20_115_000 picoseconds. + Weight::from_parts(20_741_000, 3550) .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `Broker::Configuration` (r:1 w:0) /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) @@ -237,8 +237,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `740` // Estimated: `4681` - // Minimum execution time: 34_591_000 picoseconds. - Weight::from_parts(36_227_000, 4681) + // Minimum execution time: 31_339_000 picoseconds. + Weight::from_parts(32_639_000, 4681) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -256,8 +256,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `775` // Estimated: `5996` - // Minimum execution time: 40_346_000 picoseconds. - Weight::from_parts(41_951_000, 5996) + // Minimum execution time: 37_542_000 picoseconds. + Weight::from_parts(38_521_000, 5996) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } @@ -272,10 +272,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `859` // Estimated: `6196 + m * (2520 ±0)` - // Minimum execution time: 75_734_000 picoseconds. - Weight::from_parts(78_168_395, 6196) - // Standard Error: 63_180 - .saturating_add(Weight::from_parts(1_076_259, 0).saturating_mul(m.into())) + // Minimum execution time: 66_176_000 picoseconds. + Weight::from_parts(68_356_745, 6196) + // Standard Error: 68_008 + .saturating_add(Weight::from_parts(1_558_419, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(m.into()))) .saturating_add(T::DbWeight::get().writes(5_u64)) @@ -287,8 +287,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `103` // Estimated: `3593` - // Minimum execution time: 46_383_000 picoseconds. - Weight::from_parts(47_405_000, 3593) + // Minimum execution time: 41_130_000 picoseconds. + Weight::from_parts(41_914_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -300,8 +300,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `603` // Estimated: `3550` - // Minimum execution time: 30_994_000 picoseconds. - Weight::from_parts(31_979_000, 3550) + // Minimum execution time: 31_042_000 picoseconds. + Weight::from_parts(34_087_000, 3550) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -315,8 +315,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `601` // Estimated: `3533` - // Minimum execution time: 37_584_000 picoseconds. - Weight::from_parts(44_010_000, 3533) + // Minimum execution time: 39_116_000 picoseconds. + Weight::from_parts(39_990_000, 3533) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -330,10 +330,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn drop_history() -> Weight { // Proof Size summary in bytes: - // Measured: `830` + // Measured: `995` // Estimated: `3593` - // Minimum execution time: 45_266_000 picoseconds. - Weight::from_parts(48_000_000, 3593) + // Minimum execution time: 47_547_000 picoseconds. + Weight::from_parts(50_274_000, 3593) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -343,34 +343,32 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Broker::AllowedRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`) fn drop_renewal() -> Weight { // Proof Size summary in bytes: - // Measured: `525` + // Measured: `661` // Estimated: `4698` - // Minimum execution time: 25_365_000 picoseconds. - Weight::from_parts(26_920_000, 4698) + // Minimum execution time: 26_707_000 picoseconds. + Weight::from_parts(27_217_000, 4698) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// The range of component `n` is `[0, 1000]`. - fn request_core_count(n: u32, ) -> Weight { + fn request_core_count(_n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_519_000 picoseconds. - Weight::from_parts(7_098_698, 0) - // Standard Error: 20 - .saturating_add(Weight::from_parts(8, 0).saturating_mul(n.into())) + // Minimum execution time: 4_651_000 picoseconds. + Weight::from_parts(5_231_385, 0) } - /// Storage: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:1) - /// Proof: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:1) + /// Storage: `Broker::CoreCountInbox` (r:1 w:1) + /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. fn process_core_count(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `98` - // Estimated: `3563` - // Minimum execution time: 7_608_000 picoseconds. - Weight::from_parts(8_157_815, 3563) - // Standard Error: 26 - .saturating_add(Weight::from_parts(48, 0).saturating_mul(n.into())) + // Measured: `404` + // Estimated: `1487` + // Minimum execution time: 6_806_000 picoseconds. + Weight::from_parts(7_264_002, 1487) + // Standard Error: 21 + .saturating_add(Weight::from_parts(31, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -386,10 +384,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn process_revenue() -> Weight { // Proof Size summary in bytes: - // Measured: `905` - // Estimated: `4370` - // Minimum execution time: 59_993_000 picoseconds. - Weight::from_parts(61_752_000, 4370) + // Measured: `972` + // Estimated: `4437` + // Minimum execution time: 48_297_000 picoseconds. + Weight::from_parts(49_613_000, 4437) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -408,10 +406,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `6281` // Estimated: `8499` - // Minimum execution time: 41_863_000 picoseconds. - Weight::from_parts(44_033_031, 8499) - // Standard Error: 116 - .saturating_add(Weight::from_parts(764, 0).saturating_mul(n.into())) + // Minimum execution time: 36_715_000 picoseconds. + Weight::from_parts(38_580_380, 8499) + // Standard Error: 91 + .saturating_add(Weight::from_parts(1_163, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(15_u64)) } @@ -423,8 +421,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `180` // Estimated: `3493` - // Minimum execution time: 9_588_000 picoseconds. - Weight::from_parts(9_925_000, 3493) + // Minimum execution time: 7_564_000 picoseconds. + Weight::from_parts(7_932_000, 3493) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -436,8 +434,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1423` // Estimated: `4681` - // Minimum execution time: 19_308_000 picoseconds. - Weight::from_parts(20_482_000, 4681) + // Minimum execution time: 17_082_000 picoseconds. + Weight::from_parts(17_662_000, 4681) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -445,28 +443,35 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 147_000 picoseconds. - Weight::from_parts(184_000, 0) + // Minimum execution time: 175_000 picoseconds. + Weight::from_parts(223_000, 0) } + /// Storage: `Broker::CoreCountInbox` (r:0 w:1) + /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) fn notify_core_count() -> Weight { - T::DbWeight::get().reads_writes(1, 1) + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_432_000 picoseconds. + Weight::from_parts(2_536_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Broker::Status` (r:1 w:1) /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) /// Storage: `Broker::Configuration` (r:1 w:0) /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) - /// Storage: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:1) - /// Proof: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:1) + /// Storage: `Broker::CoreCountInbox` (r:1 w:0) + /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) /// Storage: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) /// Proof: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) fn do_tick_base() -> Weight { // Proof Size summary in bytes: - // Measured: `699` - // Estimated: `4164` - // Minimum execution time: 19_824_000 picoseconds. - Weight::from_parts(20_983_000, 4164) + // Measured: `603` + // Estimated: `4068` + // Minimum execution time: 13_080_000 picoseconds. + Weight::from_parts(13_937_000, 4068) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) } } @@ -478,8 +483,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_040_000 picoseconds. - Weight::from_parts(3_344_000, 0) + // Minimum execution time: 2_701_000 picoseconds. + Weight::from_parts(2_902_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Broker::Reservations` (r:1 w:1) @@ -488,8 +493,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `5016` // Estimated: `7496` - // Minimum execution time: 21_259_000 picoseconds. - Weight::from_parts(22_110_000, 7496) + // Minimum execution time: 18_056_000 picoseconds. + Weight::from_parts(19_093_000, 7496) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -499,8 +504,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `6218` // Estimated: `7496` - // Minimum execution time: 20_330_000 picoseconds. - Weight::from_parts(20_826_000, 7496) + // Minimum execution time: 17_233_000 picoseconds. + Weight::from_parts(17_788_000, 7496) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -510,8 +515,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `239` // Estimated: `1526` - // Minimum execution time: 13_411_000 picoseconds. - Weight::from_parts(13_960_000, 1526) + // Minimum execution time: 9_740_000 picoseconds. + Weight::from_parts(10_504_000, 1526) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -530,14 +535,12 @@ impl WeightInfo for () { /// Storage: `Broker::Workplan` (r:0 w:10) /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. - fn start_sales(n: u32, ) -> Weight { + fn start_sales(_n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `6330` // Estimated: `8499` - // Minimum execution time: 57_770_000 picoseconds. - Weight::from_parts(61_047_512, 8499) - // Standard Error: 165 - .saturating_add(Weight::from_parts(3, 0).saturating_mul(n.into())) + // Minimum execution time: 49_728_000 picoseconds. + Weight::from_parts(52_765_861, 8499) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(16_u64)) } @@ -553,10 +556,10 @@ impl WeightInfo for () { /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) fn purchase() -> Weight { // Proof Size summary in bytes: - // Measured: `568` - // Estimated: `2053` - // Minimum execution time: 51_196_000 picoseconds. - Weight::from_parts(52_382_000, 2053) + // Measured: `635` + // Estimated: `2120` + // Minimum execution time: 41_986_000 picoseconds. + Weight::from_parts(43_465_000, 2120) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -576,10 +579,10 @@ impl WeightInfo for () { /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) fn renew() -> Weight { // Proof Size summary in bytes: - // Measured: `686` + // Measured: `753` // Estimated: `4698` - // Minimum execution time: 71_636_000 picoseconds. - Weight::from_parts(73_679_000, 4698) + // Minimum execution time: 61_779_000 picoseconds. + Weight::from_parts(62_563_000, 4698) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -589,8 +592,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3550` - // Minimum execution time: 19_182_000 picoseconds. - Weight::from_parts(19_775_000, 3550) + // Minimum execution time: 16_962_000 picoseconds. + Weight::from_parts(17_733_000, 3550) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -600,21 +603,21 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3550` - // Minimum execution time: 20_688_000 picoseconds. - Weight::from_parts(21_557_000, 3550) + // Minimum execution time: 18_380_000 picoseconds. + Weight::from_parts(19_105_000, 3550) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Broker::Regions` (r:1 w:2) + /// Storage: `Broker::Regions` (r:1 w:3) /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) fn interlace() -> Weight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3550` - // Minimum execution time: 21_190_000 picoseconds. - Weight::from_parts(22_215_000, 3550) + // Minimum execution time: 20_115_000 picoseconds. + Weight::from_parts(20_741_000, 3550) .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) } /// Storage: `Broker::Configuration` (r:1 w:0) /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) @@ -628,8 +631,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `740` // Estimated: `4681` - // Minimum execution time: 34_591_000 picoseconds. - Weight::from_parts(36_227_000, 4681) + // Minimum execution time: 31_339_000 picoseconds. + Weight::from_parts(32_639_000, 4681) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -647,8 +650,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `775` // Estimated: `5996` - // Minimum execution time: 40_346_000 picoseconds. - Weight::from_parts(41_951_000, 5996) + // Minimum execution time: 37_542_000 picoseconds. + Weight::from_parts(38_521_000, 5996) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } @@ -663,10 +666,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `859` // Estimated: `6196 + m * (2520 ±0)` - // Minimum execution time: 75_734_000 picoseconds. - Weight::from_parts(78_168_395, 6196) - // Standard Error: 63_180 - .saturating_add(Weight::from_parts(1_076_259, 0).saturating_mul(m.into())) + // Minimum execution time: 66_176_000 picoseconds. + Weight::from_parts(68_356_745, 6196) + // Standard Error: 68_008 + .saturating_add(Weight::from_parts(1_558_419, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(m.into()))) .saturating_add(RocksDbWeight::get().writes(5_u64)) @@ -678,8 +681,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `103` // Estimated: `3593` - // Minimum execution time: 46_383_000 picoseconds. - Weight::from_parts(47_405_000, 3593) + // Minimum execution time: 41_130_000 picoseconds. + Weight::from_parts(41_914_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -691,8 +694,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `603` // Estimated: `3550` - // Minimum execution time: 30_994_000 picoseconds. - Weight::from_parts(31_979_000, 3550) + // Minimum execution time: 31_042_000 picoseconds. + Weight::from_parts(34_087_000, 3550) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -706,8 +709,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `601` // Estimated: `3533` - // Minimum execution time: 37_584_000 picoseconds. - Weight::from_parts(44_010_000, 3533) + // Minimum execution time: 39_116_000 picoseconds. + Weight::from_parts(39_990_000, 3533) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -721,10 +724,10 @@ impl WeightInfo for () { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn drop_history() -> Weight { // Proof Size summary in bytes: - // Measured: `830` + // Measured: `995` // Estimated: `3593` - // Minimum execution time: 45_266_000 picoseconds. - Weight::from_parts(48_000_000, 3593) + // Minimum execution time: 47_547_000 picoseconds. + Weight::from_parts(50_274_000, 3593) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -734,34 +737,32 @@ impl WeightInfo for () { /// Proof: `Broker::AllowedRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`) fn drop_renewal() -> Weight { // Proof Size summary in bytes: - // Measured: `525` + // Measured: `661` // Estimated: `4698` - // Minimum execution time: 25_365_000 picoseconds. - Weight::from_parts(26_920_000, 4698) + // Minimum execution time: 26_707_000 picoseconds. + Weight::from_parts(27_217_000, 4698) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// The range of component `n` is `[0, 1000]`. - fn request_core_count(n: u32, ) -> Weight { + fn request_core_count(_n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_519_000 picoseconds. - Weight::from_parts(7_098_698, 0) - // Standard Error: 20 - .saturating_add(Weight::from_parts(8, 0).saturating_mul(n.into())) + // Minimum execution time: 4_651_000 picoseconds. + Weight::from_parts(5_231_385, 0) } - /// Storage: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:1) - /// Proof: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:1) + /// Storage: `Broker::CoreCountInbox` (r:1 w:1) + /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. fn process_core_count(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `98` - // Estimated: `3563` - // Minimum execution time: 7_608_000 picoseconds. - Weight::from_parts(8_157_815, 3563) - // Standard Error: 26 - .saturating_add(Weight::from_parts(48, 0).saturating_mul(n.into())) + // Measured: `404` + // Estimated: `1487` + // Minimum execution time: 6_806_000 picoseconds. + Weight::from_parts(7_264_002, 1487) + // Standard Error: 21 + .saturating_add(Weight::from_parts(31, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -777,10 +778,10 @@ impl WeightInfo for () { /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn process_revenue() -> Weight { // Proof Size summary in bytes: - // Measured: `905` - // Estimated: `4370` - // Minimum execution time: 59_993_000 picoseconds. - Weight::from_parts(61_752_000, 4370) + // Measured: `972` + // Estimated: `4437` + // Minimum execution time: 48_297_000 picoseconds. + Weight::from_parts(49_613_000, 4437) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -799,10 +800,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `6281` // Estimated: `8499` - // Minimum execution time: 41_863_000 picoseconds. - Weight::from_parts(44_033_031, 8499) - // Standard Error: 116 - .saturating_add(Weight::from_parts(764, 0).saturating_mul(n.into())) + // Minimum execution time: 36_715_000 picoseconds. + Weight::from_parts(38_580_380, 8499) + // Standard Error: 91 + .saturating_add(Weight::from_parts(1_163, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(15_u64)) } @@ -814,8 +815,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `180` // Estimated: `3493` - // Minimum execution time: 9_588_000 picoseconds. - Weight::from_parts(9_925_000, 3493) + // Minimum execution time: 7_564_000 picoseconds. + Weight::from_parts(7_932_000, 3493) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -827,8 +828,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1423` // Estimated: `4681` - // Minimum execution time: 19_308_000 picoseconds. - Weight::from_parts(20_482_000, 4681) + // Minimum execution time: 17_082_000 picoseconds. + Weight::from_parts(17_662_000, 4681) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -836,28 +837,34 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 147_000 picoseconds. - Weight::from_parts(184_000, 0) + // Minimum execution time: 175_000 picoseconds. + Weight::from_parts(223_000, 0) } + /// Storage: `Broker::CoreCountInbox` (r:0 w:1) + /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) fn notify_core_count() -> Weight { - RocksDbWeight::get().reads(1) - .saturating_add(RocksDbWeight::get().writes(1)) + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_432_000 picoseconds. + Weight::from_parts(2_536_000, 0) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Broker::Status` (r:1 w:1) /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) /// Storage: `Broker::Configuration` (r:1 w:0) /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) - /// Storage: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:1) - /// Proof: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:1) + /// Storage: `Broker::CoreCountInbox` (r:1 w:0) + /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) /// Storage: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) /// Proof: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) fn do_tick_base() -> Weight { // Proof Size summary in bytes: - // Measured: `699` - // Estimated: `4164` - // Minimum execution time: 19_824_000 picoseconds. - Weight::from_parts(20_983_000, 4164) + // Measured: `603` + // Estimated: `4068` + // Minimum execution time: 13_080_000 picoseconds. + Weight::from_parts(13_937_000, 4068) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } } diff --git a/substrate/frame/child-bounties/src/weights.rs b/substrate/frame/child-bounties/src/weights.rs index e4c1f238e88..6427517b45b 100644 --- a/substrate/frame/child-bounties/src/weights.rs +++ b/substrate/frame/child-bounties/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_child_bounties +//! Autogenerated weights for `pallet_child_bounties` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/child-bounties/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/child-bounties/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_child_bounties. +/// Weight functions needed for `pallet_child_bounties`. pub trait WeightInfo { fn add_child_bounty(d: u32, ) -> Weight; fn propose_curator() -> Weight; @@ -62,288 +61,288 @@ pub trait WeightInfo { fn close_child_bounty_active() -> Weight; } -/// Weights for pallet_child_bounties using the Substrate node and recommended hardware. +/// Weights for `pallet_child_bounties` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: ChildBounties ParentChildBounties (r:1 w:1) - /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) - /// Storage: Bounties Bounties (r:1 w:0) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: System Account (r:2 w:2) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBountyCount (r:1 w:1) - /// Proof: ChildBounties ChildBountyCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) - /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBounties (r:0 w:1) - /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBountyCount` (r:1 w:1) + /// Proof: `ChildBounties::ChildBountyCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) + /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBounties` (r:0 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) /// The range of component `d` is `[0, 300]`. fn add_child_bounty(_d: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `712` + // Measured: `745` // Estimated: `6196` - // Minimum execution time: 69_805_000 picoseconds. - Weight::from_parts(73_216_717, 6196) + // Minimum execution time: 60_674_000 picoseconds. + Weight::from_parts(63_477_428, 6196) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: Bounties Bounties (r:1 w:0) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBounties (r:1 w:1) - /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) - /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) + /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) fn propose_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `766` + // Measured: `799` // Estimated: `3642` - // Minimum execution time: 18_190_000 picoseconds. - Weight::from_parts(18_932_000, 3642) + // Minimum execution time: 17_754_000 picoseconds. + Weight::from_parts(18_655_000, 3642) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Bounties Bounties (r:1 w:0) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBounties (r:1 w:1) - /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn accept_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `912` + // Measured: `945` // Estimated: `3642` - // Minimum execution time: 35_035_000 picoseconds. - Weight::from_parts(35_975_000, 3642) + // Minimum execution time: 31_580_000 picoseconds. + Weight::from_parts(32_499_000, 3642) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: ChildBounties ChildBounties (r:1 w:1) - /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) - /// Storage: Bounties Bounties (r:1 w:0) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn unassign_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `912` + // Measured: `945` // Estimated: `3642` - // Minimum execution time: 37_636_000 picoseconds. - Weight::from_parts(38_610_000, 3642) + // Minimum execution time: 33_536_000 picoseconds. + Weight::from_parts(34_102_000, 3642) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Bounties Bounties (r:1 w:0) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBounties (r:1 w:1) - /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) fn award_child_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `809` + // Measured: `842` // Estimated: `3642` - // Minimum execution time: 22_457_000 picoseconds. - Weight::from_parts(23_691_000, 3642) + // Minimum execution time: 18_295_000 picoseconds. + Weight::from_parts(19_496_000, 3642) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: ChildBounties ChildBounties (r:1 w:1) - /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) - /// Storage: System Account (r:3 w:3) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: ChildBounties ParentChildBounties (r:1 w:1) - /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) - /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:3 w:3) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) + /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) fn claim_child_bounty() -> Weight { // Proof Size summary in bytes: // Measured: `682` // Estimated: `8799` - // Minimum execution time: 118_272_000 picoseconds. - Weight::from_parts(121_646_000, 8799) + // Minimum execution time: 102_367_000 picoseconds. + Weight::from_parts(104_352_000, 8799) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: Bounties Bounties (r:1 w:0) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBounties (r:1 w:1) - /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) - /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) - /// Storage: ChildBounties ParentChildBounties (r:1 w:1) - /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) - /// Storage: System Account (r:2 w:2) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) - /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) + /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) + /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) fn close_child_bounty_added() -> Weight { // Proof Size summary in bytes: - // Measured: `1012` + // Measured: `1045` // Estimated: `6196` - // Minimum execution time: 75_717_000 picoseconds. - Weight::from_parts(77_837_000, 6196) + // Minimum execution time: 69_051_000 picoseconds. + Weight::from_parts(71_297_000, 6196) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: Bounties Bounties (r:1 w:0) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBounties (r:1 w:1) - /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) - /// Storage: System Account (r:3 w:3) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) - /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) - /// Storage: ChildBounties ParentChildBounties (r:1 w:1) - /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) - /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:3 w:3) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) + /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) + /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) fn close_child_bounty_active() -> Weight { // Proof Size summary in bytes: - // Measured: `1199` + // Measured: `1232` // Estimated: `8799` - // Minimum execution time: 94_215_000 picoseconds. - Weight::from_parts(97_017_000, 8799) + // Minimum execution time: 84_053_000 picoseconds. + Weight::from_parts(86_072_000, 8799) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: ChildBounties ParentChildBounties (r:1 w:1) - /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) - /// Storage: Bounties Bounties (r:1 w:0) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: System Account (r:2 w:2) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBountyCount (r:1 w:1) - /// Proof: ChildBounties ChildBountyCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) - /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBounties (r:0 w:1) - /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBountyCount` (r:1 w:1) + /// Proof: `ChildBounties::ChildBountyCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) + /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBounties` (r:0 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) /// The range of component `d` is `[0, 300]`. fn add_child_bounty(_d: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `712` + // Measured: `745` // Estimated: `6196` - // Minimum execution time: 69_805_000 picoseconds. - Weight::from_parts(73_216_717, 6196) + // Minimum execution time: 60_674_000 picoseconds. + Weight::from_parts(63_477_428, 6196) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } - /// Storage: Bounties Bounties (r:1 w:0) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBounties (r:1 w:1) - /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) - /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) + /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) fn propose_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `766` + // Measured: `799` // Estimated: `3642` - // Minimum execution time: 18_190_000 picoseconds. - Weight::from_parts(18_932_000, 3642) + // Minimum execution time: 17_754_000 picoseconds. + Weight::from_parts(18_655_000, 3642) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Bounties Bounties (r:1 w:0) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBounties (r:1 w:1) - /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn accept_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `912` + // Measured: `945` // Estimated: `3642` - // Minimum execution time: 35_035_000 picoseconds. - Weight::from_parts(35_975_000, 3642) + // Minimum execution time: 31_580_000 picoseconds. + Weight::from_parts(32_499_000, 3642) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: ChildBounties ChildBounties (r:1 w:1) - /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) - /// Storage: Bounties Bounties (r:1 w:0) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn unassign_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `912` + // Measured: `945` // Estimated: `3642` - // Minimum execution time: 37_636_000 picoseconds. - Weight::from_parts(38_610_000, 3642) + // Minimum execution time: 33_536_000 picoseconds. + Weight::from_parts(34_102_000, 3642) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Bounties Bounties (r:1 w:0) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBounties (r:1 w:1) - /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) fn award_child_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `809` + // Measured: `842` // Estimated: `3642` - // Minimum execution time: 22_457_000 picoseconds. - Weight::from_parts(23_691_000, 3642) + // Minimum execution time: 18_295_000 picoseconds. + Weight::from_parts(19_496_000, 3642) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: ChildBounties ChildBounties (r:1 w:1) - /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) - /// Storage: System Account (r:3 w:3) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: ChildBounties ParentChildBounties (r:1 w:1) - /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) - /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:3 w:3) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) + /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) fn claim_child_bounty() -> Weight { // Proof Size summary in bytes: // Measured: `682` // Estimated: `8799` - // Minimum execution time: 118_272_000 picoseconds. - Weight::from_parts(121_646_000, 8799) + // Minimum execution time: 102_367_000 picoseconds. + Weight::from_parts(104_352_000, 8799) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } - /// Storage: Bounties Bounties (r:1 w:0) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBounties (r:1 w:1) - /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) - /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) - /// Storage: ChildBounties ParentChildBounties (r:1 w:1) - /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) - /// Storage: System Account (r:2 w:2) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) - /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) + /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) + /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) fn close_child_bounty_added() -> Weight { // Proof Size summary in bytes: - // Measured: `1012` + // Measured: `1045` // Estimated: `6196` - // Minimum execution time: 75_717_000 picoseconds. - Weight::from_parts(77_837_000, 6196) + // Minimum execution time: 69_051_000 picoseconds. + Weight::from_parts(71_297_000, 6196) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } - /// Storage: Bounties Bounties (r:1 w:0) - /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBounties (r:1 w:1) - /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) - /// Storage: System Account (r:3 w:3) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) - /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) - /// Storage: ChildBounties ParentChildBounties (r:1 w:1) - /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) - /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) - /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) + /// Storage: `Bounties::Bounties` (r:1 w:0) + /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:3 w:3) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) + /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) + /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) + /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) fn close_child_bounty_active() -> Weight { // Proof Size summary in bytes: - // Measured: `1199` + // Measured: `1232` // Estimated: `8799` - // Minimum execution time: 94_215_000 picoseconds. - Weight::from_parts(97_017_000, 8799) + // Minimum execution time: 84_053_000 picoseconds. + Weight::from_parts(86_072_000, 8799) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } diff --git a/substrate/frame/collective/src/tests.rs b/substrate/frame/collective/src/tests.rs index aae17b7ffc2..ac5797c638c 100644 --- a/substrate/frame/collective/src/tests.rs +++ b/substrate/frame/collective/src/tests.rs @@ -29,7 +29,7 @@ use sp_core::H256; use sp_runtime::{testing::Header, traits::BlakeTwo256, BuildStorage}; pub type Block = sp_runtime::generic::Block; -pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; +pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; frame_support::construct_runtime!( pub enum Test diff --git a/substrate/frame/collective/src/weights.rs b/substrate/frame/collective/src/weights.rs index eece6a006b8..85744b4de9d 100644 --- a/substrate/frame/collective/src/weights.rs +++ b/substrate/frame/collective/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_collective +//! Autogenerated weights for `pallet_collective` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/collective/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/collective/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_collective. +/// Weight functions needed for `pallet_collective`. pub trait WeightInfo { fn set_members(m: u32, n: u32, p: u32, ) -> Weight; fn execute(b: u32, m: u32, ) -> Weight; @@ -64,30 +63,30 @@ pub trait WeightInfo { fn disapprove_proposal(p: u32, ) -> Weight; } -/// Weights for pallet_collective using the Substrate node and recommended hardware. +/// Weights for `pallet_collective` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Council Members (r:1 w:1) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Proposals (r:1 w:0) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Voting (r:100 w:100) - /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Council Prime (r:0 w:1) - /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Council::Members` (r:1 w:1) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Proposals` (r:1 w:0) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Voting` (r:100 w:100) + /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Council::Prime` (r:0 w:1) + /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `m` is `[0, 100]`. /// The range of component `n` is `[0, 100]`. /// The range of component `p` is `[0, 100]`. fn set_members(m: u32, _n: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + m * (3232 ±0) + p * (3190 ±0)` - // Estimated: `15861 + m * (1967 ±24) + p * (4332 ±24)` - // Minimum execution time: 17_506_000 picoseconds. - Weight::from_parts(17_767_000, 15861) - // Standard Error: 60_220 - .saturating_add(Weight::from_parts(4_374_805, 0).saturating_mul(m.into())) - // Standard Error: 60_220 - .saturating_add(Weight::from_parts(8_398_316, 0).saturating_mul(p.into())) + // Estimated: `15894 + m * (1967 ±23) + p * (4332 ±23)` + // Minimum execution time: 15_559_000 picoseconds. + Weight::from_parts(15_870_000, 15894) + // Standard Error: 54_310 + .saturating_add(Weight::from_parts(4_117_753, 0).saturating_mul(m.into())) + // Standard Error: 54_310 + .saturating_add(Weight::from_parts(7_677_627, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) .saturating_add(T::DbWeight::get().writes(2_u64)) @@ -95,245 +94,261 @@ impl WeightInfo for SubstrateWeight { .saturating_add(Weight::from_parts(0, 1967).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 4332).saturating_mul(p.into())) } - /// Storage: Council Members (r:1 w:0) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Council::Members` (r:1 w:0) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[1, 100]`. fn execute(b: u32, m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `202 + m * (32 ±0)` - // Estimated: `1688 + m * (32 ±0)` - // Minimum execution time: 16_203_000 picoseconds. - Weight::from_parts(15_348_267, 1688) - // Standard Error: 37 - .saturating_add(Weight::from_parts(1_766, 0).saturating_mul(b.into())) - // Standard Error: 382 - .saturating_add(Weight::from_parts(15_765, 0).saturating_mul(m.into())) - .saturating_add(T::DbWeight::get().reads(1_u64)) + // Measured: `380 + m * (32 ±0)` + // Estimated: `3997 + m * (32 ±0)` + // Minimum execution time: 19_024_000 picoseconds. + Weight::from_parts(18_153_872, 3997) + // Standard Error: 46 + .saturating_add(Weight::from_parts(1_933, 0).saturating_mul(b.into())) + // Standard Error: 478 + .saturating_add(Weight::from_parts(18_872, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) } - /// Storage: Council Members (r:1 w:0) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council ProposalOf (r:1 w:0) - /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: `Council::Members` (r:1 w:0) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::ProposalOf` (r:1 w:0) + /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[1, 100]`. fn propose_execute(b: u32, m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `202 + m * (32 ±0)` - // Estimated: `3668 + m * (32 ±0)` - // Minimum execution time: 18_642_000 picoseconds. - Weight::from_parts(17_708_609, 3668) - // Standard Error: 58 - .saturating_add(Weight::from_parts(2_285, 0).saturating_mul(b.into())) - // Standard Error: 598 - .saturating_add(Weight::from_parts(30_454, 0).saturating_mul(m.into())) - .saturating_add(T::DbWeight::get().reads(2_u64)) + // Measured: `380 + m * (32 ±0)` + // Estimated: `3997 + m * (32 ±0)` + // Minimum execution time: 20_895_000 picoseconds. + Weight::from_parts(20_081_761, 3997) + // Standard Error: 57 + .saturating_add(Weight::from_parts(1_982, 0).saturating_mul(b.into())) + // Standard Error: 594 + .saturating_add(Weight::from_parts(32_085, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) } - /// Storage: Council Members (r:1 w:0) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council ProposalOf (r:1 w:1) - /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) - /// Storage: Council Proposals (r:1 w:1) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council ProposalCount (r:1 w:1) - /// Proof Skipped: Council ProposalCount (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Voting (r:0 w:1) - /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: `Council::Members` (r:1 w:0) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::ProposalOf` (r:1 w:1) + /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Council::Proposals` (r:1 w:1) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::ProposalCount` (r:1 w:1) + /// Proof: `Council::ProposalCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Voting` (r:0 w:1) + /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[2, 100]`. /// The range of component `p` is `[1, 100]`. fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `492 + m * (32 ±0) + p * (36 ±0)` - // Estimated: `3884 + m * (33 ±0) + p * (36 ±0)` - // Minimum execution time: 27_067_000 picoseconds. - Weight::from_parts(25_456_964, 3884) - // Standard Error: 112 - .saturating_add(Weight::from_parts(3_773, 0).saturating_mul(b.into())) - // Standard Error: 1_177 - .saturating_add(Weight::from_parts(32_783, 0).saturating_mul(m.into())) - // Standard Error: 1_162 - .saturating_add(Weight::from_parts(194_388, 0).saturating_mul(p.into())) + // Measured: `525 + m * (32 ±0) + p * (36 ±0)` + // Estimated: `3917 + m * (33 ±0) + p * (36 ±0)` + // Minimum execution time: 22_068_000 picoseconds. + Weight::from_parts(19_639_088, 3917) + // Standard Error: 104 + .saturating_add(Weight::from_parts(3_896, 0).saturating_mul(b.into())) + // Standard Error: 1_095 + .saturating_add(Weight::from_parts(31_634, 0).saturating_mul(m.into())) + // Standard Error: 1_081 + .saturating_add(Weight::from_parts(178_702, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 33).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: Council Members (r:1 w:0) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Voting (r:1 w:1) - /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: `Council::Members` (r:1 w:0) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Voting` (r:1 w:1) + /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `m` is `[5, 100]`. fn vote(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `941 + m * (64 ±0)` - // Estimated: `4405 + m * (64 ±0)` - // Minimum execution time: 26_055_000 picoseconds. - Weight::from_parts(27_251_907, 4405) - // Standard Error: 1_008 - .saturating_add(Weight::from_parts(65_947, 0).saturating_mul(m.into())) + // Measured: `974 + m * (64 ±0)` + // Estimated: `4438 + m * (64 ±0)` + // Minimum execution time: 22_395_000 picoseconds. + Weight::from_parts(23_025_217, 4438) + // Standard Error: 842 + .saturating_add(Weight::from_parts(58_102, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: Council Voting (r:1 w:1) - /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Council Members (r:1 w:0) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Proposals (r:1 w:1) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council ProposalOf (r:0 w:1) - /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: `Council::Voting` (r:1 w:1) + /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Council::Members` (r:1 w:0) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Proposals` (r:1 w:1) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::ProposalOf` (r:0 w:1) + /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_early_disapproved(m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `530 + m * (64 ±0) + p * (36 ±0)` - // Estimated: `3975 + m * (65 ±0) + p * (36 ±0)` - // Minimum execution time: 28_363_000 picoseconds. - Weight::from_parts(28_733_464, 3975) - // Standard Error: 1_275 - .saturating_add(Weight::from_parts(43_236, 0).saturating_mul(m.into())) - // Standard Error: 1_244 - .saturating_add(Weight::from_parts(180_187, 0).saturating_mul(p.into())) + // Measured: `563 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `4008 + m * (65 ±0) + p * (36 ±0)` + // Minimum execution time: 24_179_000 picoseconds. + Weight::from_parts(23_846_394, 4008) + // Standard Error: 1_052 + .saturating_add(Weight::from_parts(40_418, 0).saturating_mul(m.into())) + // Standard Error: 1_026 + .saturating_add(Weight::from_parts(171_653, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 65).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: Council Voting (r:1 w:1) - /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Council Members (r:1 w:0) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council ProposalOf (r:1 w:1) - /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) - /// Storage: Council Proposals (r:1 w:1) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Council::Voting` (r:1 w:1) + /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Council::Members` (r:1 w:0) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::ProposalOf` (r:1 w:1) + /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: `Council::Proposals` (r:1 w:1) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `832 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` - // Estimated: `4149 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` - // Minimum execution time: 40_391_000 picoseconds. - Weight::from_parts(42_695_215, 4149) - // Standard Error: 167 - .saturating_add(Weight::from_parts(3_622, 0).saturating_mul(b.into())) - // Standard Error: 1_772 - .saturating_add(Weight::from_parts(33_830, 0).saturating_mul(m.into())) - // Standard Error: 1_727 - .saturating_add(Weight::from_parts(205_374, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(4_u64)) + // Measured: `1010 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `4327 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` + // Minimum execution time: 42_129_000 picoseconds. + Weight::from_parts(40_808_957, 4327) + // Standard Error: 134 + .saturating_add(Weight::from_parts(3_579, 0).saturating_mul(b.into())) + // Standard Error: 1_425 + .saturating_add(Weight::from_parts(37_166, 0).saturating_mul(m.into())) + // Standard Error: 1_389 + .saturating_add(Weight::from_parts(200_986, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(b.into())) .saturating_add(Weight::from_parts(0, 66).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) } - /// Storage: Council Voting (r:1 w:1) - /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Council Members (r:1 w:0) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Prime (r:1 w:0) - /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Proposals (r:1 w:1) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council ProposalOf (r:0 w:1) - /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: `Council::Voting` (r:1 w:1) + /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Council::Members` (r:1 w:0) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Prime` (r:1 w:0) + /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Proposals` (r:1 w:1) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::ProposalOf` (r:0 w:1) + /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_disapproved(m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `550 + m * (64 ±0) + p * (36 ±0)` - // Estimated: `3995 + m * (65 ±0) + p * (36 ±0)` - // Minimum execution time: 31_368_000 picoseconds. - Weight::from_parts(32_141_835, 3995) - // Standard Error: 1_451 - .saturating_add(Weight::from_parts(36_372, 0).saturating_mul(m.into())) - // Standard Error: 1_415 - .saturating_add(Weight::from_parts(210_635, 0).saturating_mul(p.into())) + // Measured: `583 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `4028 + m * (65 ±0) + p * (36 ±0)` + // Minimum execution time: 26_385_000 picoseconds. + Weight::from_parts(25_713_839, 4028) + // Standard Error: 1_254 + .saturating_add(Weight::from_parts(36_206, 0).saturating_mul(m.into())) + // Standard Error: 1_223 + .saturating_add(Weight::from_parts(195_114, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 65).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: Council Voting (r:1 w:1) - /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Council Members (r:1 w:0) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Prime (r:1 w:0) - /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council ProposalOf (r:1 w:1) - /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) - /// Storage: Council Proposals (r:1 w:1) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Council::Voting` (r:1 w:1) + /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Council::Members` (r:1 w:0) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Prime` (r:1 w:0) + /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::ProposalOf` (r:1 w:1) + /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: `Council::Proposals` (r:1 w:1) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_approved(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `852 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` - // Estimated: `4169 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` - // Minimum execution time: 43_271_000 picoseconds. - Weight::from_parts(45_495_648, 4169) - // Standard Error: 174 - .saturating_add(Weight::from_parts(3_034, 0).saturating_mul(b.into())) - // Standard Error: 1_840 - .saturating_add(Weight::from_parts(42_209, 0).saturating_mul(m.into())) - // Standard Error: 1_793 - .saturating_add(Weight::from_parts(207_525, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(5_u64)) + // Measured: `1030 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `4347 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` + // Minimum execution time: 42_903_000 picoseconds. + Weight::from_parts(43_152_907, 4347) + // Standard Error: 146 + .saturating_add(Weight::from_parts(3_459, 0).saturating_mul(b.into())) + // Standard Error: 1_548 + .saturating_add(Weight::from_parts(35_321, 0).saturating_mul(m.into())) + // Standard Error: 1_509 + .saturating_add(Weight::from_parts(202_541, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(b.into())) .saturating_add(Weight::from_parts(0, 66).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) } - /// Storage: Council Proposals (r:1 w:1) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Voting (r:0 w:1) - /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Council ProposalOf (r:0 w:1) - /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: `Council::Proposals` (r:1 w:1) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Voting` (r:0 w:1) + /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Council::ProposalOf` (r:0 w:1) + /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `p` is `[1, 100]`. fn disapprove_proposal(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `359 + p * (32 ±0)` - // Estimated: `1844 + p * (32 ±0)` - // Minimum execution time: 15_170_000 picoseconds. - Weight::from_parts(17_567_243, 1844) - // Standard Error: 1_430 - .saturating_add(Weight::from_parts(169_040, 0).saturating_mul(p.into())) + // Measured: `392 + p * (32 ±0)` + // Estimated: `1877 + p * (32 ±0)` + // Minimum execution time: 12_656_000 picoseconds. + Weight::from_parts(14_032_951, 1877) + // Standard Error: 1_025 + .saturating_add(Weight::from_parts(159_143, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(p.into())) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Council Members (r:1 w:1) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Proposals (r:1 w:0) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Voting (r:100 w:100) - /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Council Prime (r:0 w:1) - /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Council::Members` (r:1 w:1) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Proposals` (r:1 w:0) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Voting` (r:100 w:100) + /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Council::Prime` (r:0 w:1) + /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `m` is `[0, 100]`. /// The range of component `n` is `[0, 100]`. /// The range of component `p` is `[0, 100]`. fn set_members(m: u32, _n: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + m * (3232 ±0) + p * (3190 ±0)` - // Estimated: `15861 + m * (1967 ±24) + p * (4332 ±24)` - // Minimum execution time: 17_506_000 picoseconds. - Weight::from_parts(17_767_000, 15861) - // Standard Error: 60_220 - .saturating_add(Weight::from_parts(4_374_805, 0).saturating_mul(m.into())) - // Standard Error: 60_220 - .saturating_add(Weight::from_parts(8_398_316, 0).saturating_mul(p.into())) + // Estimated: `15894 + m * (1967 ±23) + p * (4332 ±23)` + // Minimum execution time: 15_559_000 picoseconds. + Weight::from_parts(15_870_000, 15894) + // Standard Error: 54_310 + .saturating_add(Weight::from_parts(4_117_753, 0).saturating_mul(m.into())) + // Standard Error: 54_310 + .saturating_add(Weight::from_parts(7_677_627, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(p.into()))) .saturating_add(RocksDbWeight::get().writes(2_u64)) @@ -341,216 +356,232 @@ impl WeightInfo for () { .saturating_add(Weight::from_parts(0, 1967).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 4332).saturating_mul(p.into())) } - /// Storage: Council Members (r:1 w:0) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Council::Members` (r:1 w:0) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[1, 100]`. fn execute(b: u32, m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `202 + m * (32 ±0)` - // Estimated: `1688 + m * (32 ±0)` - // Minimum execution time: 16_203_000 picoseconds. - Weight::from_parts(15_348_267, 1688) - // Standard Error: 37 - .saturating_add(Weight::from_parts(1_766, 0).saturating_mul(b.into())) - // Standard Error: 382 - .saturating_add(Weight::from_parts(15_765, 0).saturating_mul(m.into())) - .saturating_add(RocksDbWeight::get().reads(1_u64)) + // Measured: `380 + m * (32 ±0)` + // Estimated: `3997 + m * (32 ±0)` + // Minimum execution time: 19_024_000 picoseconds. + Weight::from_parts(18_153_872, 3997) + // Standard Error: 46 + .saturating_add(Weight::from_parts(1_933, 0).saturating_mul(b.into())) + // Standard Error: 478 + .saturating_add(Weight::from_parts(18_872, 0).saturating_mul(m.into())) + .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) } - /// Storage: Council Members (r:1 w:0) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council ProposalOf (r:1 w:0) - /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: `Council::Members` (r:1 w:0) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::ProposalOf` (r:1 w:0) + /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[1, 100]`. fn propose_execute(b: u32, m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `202 + m * (32 ±0)` - // Estimated: `3668 + m * (32 ±0)` - // Minimum execution time: 18_642_000 picoseconds. - Weight::from_parts(17_708_609, 3668) - // Standard Error: 58 - .saturating_add(Weight::from_parts(2_285, 0).saturating_mul(b.into())) - // Standard Error: 598 - .saturating_add(Weight::from_parts(30_454, 0).saturating_mul(m.into())) - .saturating_add(RocksDbWeight::get().reads(2_u64)) + // Measured: `380 + m * (32 ±0)` + // Estimated: `3997 + m * (32 ±0)` + // Minimum execution time: 20_895_000 picoseconds. + Weight::from_parts(20_081_761, 3997) + // Standard Error: 57 + .saturating_add(Weight::from_parts(1_982, 0).saturating_mul(b.into())) + // Standard Error: 594 + .saturating_add(Weight::from_parts(32_085, 0).saturating_mul(m.into())) + .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) } - /// Storage: Council Members (r:1 w:0) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council ProposalOf (r:1 w:1) - /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) - /// Storage: Council Proposals (r:1 w:1) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council ProposalCount (r:1 w:1) - /// Proof Skipped: Council ProposalCount (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Voting (r:0 w:1) - /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: `Council::Members` (r:1 w:0) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::ProposalOf` (r:1 w:1) + /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Council::Proposals` (r:1 w:1) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::ProposalCount` (r:1 w:1) + /// Proof: `Council::ProposalCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Voting` (r:0 w:1) + /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[2, 100]`. /// The range of component `p` is `[1, 100]`. fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `492 + m * (32 ±0) + p * (36 ±0)` - // Estimated: `3884 + m * (33 ±0) + p * (36 ±0)` - // Minimum execution time: 27_067_000 picoseconds. - Weight::from_parts(25_456_964, 3884) - // Standard Error: 112 - .saturating_add(Weight::from_parts(3_773, 0).saturating_mul(b.into())) - // Standard Error: 1_177 - .saturating_add(Weight::from_parts(32_783, 0).saturating_mul(m.into())) - // Standard Error: 1_162 - .saturating_add(Weight::from_parts(194_388, 0).saturating_mul(p.into())) + // Measured: `525 + m * (32 ±0) + p * (36 ±0)` + // Estimated: `3917 + m * (33 ±0) + p * (36 ±0)` + // Minimum execution time: 22_068_000 picoseconds. + Weight::from_parts(19_639_088, 3917) + // Standard Error: 104 + .saturating_add(Weight::from_parts(3_896, 0).saturating_mul(b.into())) + // Standard Error: 1_095 + .saturating_add(Weight::from_parts(31_634, 0).saturating_mul(m.into())) + // Standard Error: 1_081 + .saturating_add(Weight::from_parts(178_702, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 33).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: Council Members (r:1 w:0) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Voting (r:1 w:1) - /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: `Council::Members` (r:1 w:0) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Voting` (r:1 w:1) + /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `m` is `[5, 100]`. fn vote(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `941 + m * (64 ±0)` - // Estimated: `4405 + m * (64 ±0)` - // Minimum execution time: 26_055_000 picoseconds. - Weight::from_parts(27_251_907, 4405) - // Standard Error: 1_008 - .saturating_add(Weight::from_parts(65_947, 0).saturating_mul(m.into())) + // Measured: `974 + m * (64 ±0)` + // Estimated: `4438 + m * (64 ±0)` + // Minimum execution time: 22_395_000 picoseconds. + Weight::from_parts(23_025_217, 4438) + // Standard Error: 842 + .saturating_add(Weight::from_parts(58_102, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: Council Voting (r:1 w:1) - /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Council Members (r:1 w:0) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Proposals (r:1 w:1) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council ProposalOf (r:0 w:1) - /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: `Council::Voting` (r:1 w:1) + /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Council::Members` (r:1 w:0) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Proposals` (r:1 w:1) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::ProposalOf` (r:0 w:1) + /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_early_disapproved(m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `530 + m * (64 ±0) + p * (36 ±0)` - // Estimated: `3975 + m * (65 ±0) + p * (36 ±0)` - // Minimum execution time: 28_363_000 picoseconds. - Weight::from_parts(28_733_464, 3975) - // Standard Error: 1_275 - .saturating_add(Weight::from_parts(43_236, 0).saturating_mul(m.into())) - // Standard Error: 1_244 - .saturating_add(Weight::from_parts(180_187, 0).saturating_mul(p.into())) + // Measured: `563 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `4008 + m * (65 ±0) + p * (36 ±0)` + // Minimum execution time: 24_179_000 picoseconds. + Weight::from_parts(23_846_394, 4008) + // Standard Error: 1_052 + .saturating_add(Weight::from_parts(40_418, 0).saturating_mul(m.into())) + // Standard Error: 1_026 + .saturating_add(Weight::from_parts(171_653, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 65).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: Council Voting (r:1 w:1) - /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Council Members (r:1 w:0) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council ProposalOf (r:1 w:1) - /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) - /// Storage: Council Proposals (r:1 w:1) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Council::Voting` (r:1 w:1) + /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Council::Members` (r:1 w:0) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::ProposalOf` (r:1 w:1) + /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: `Council::Proposals` (r:1 w:1) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `832 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` - // Estimated: `4149 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` - // Minimum execution time: 40_391_000 picoseconds. - Weight::from_parts(42_695_215, 4149) - // Standard Error: 167 - .saturating_add(Weight::from_parts(3_622, 0).saturating_mul(b.into())) - // Standard Error: 1_772 - .saturating_add(Weight::from_parts(33_830, 0).saturating_mul(m.into())) - // Standard Error: 1_727 - .saturating_add(Weight::from_parts(205_374, 0).saturating_mul(p.into())) - .saturating_add(RocksDbWeight::get().reads(4_u64)) + // Measured: `1010 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `4327 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` + // Minimum execution time: 42_129_000 picoseconds. + Weight::from_parts(40_808_957, 4327) + // Standard Error: 134 + .saturating_add(Weight::from_parts(3_579, 0).saturating_mul(b.into())) + // Standard Error: 1_425 + .saturating_add(Weight::from_parts(37_166, 0).saturating_mul(m.into())) + // Standard Error: 1_389 + .saturating_add(Weight::from_parts(200_986, 0).saturating_mul(p.into())) + .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(b.into())) .saturating_add(Weight::from_parts(0, 66).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) } - /// Storage: Council Voting (r:1 w:1) - /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Council Members (r:1 w:0) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Prime (r:1 w:0) - /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Proposals (r:1 w:1) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council ProposalOf (r:0 w:1) - /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: `Council::Voting` (r:1 w:1) + /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Council::Members` (r:1 w:0) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Prime` (r:1 w:0) + /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Proposals` (r:1 w:1) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::ProposalOf` (r:0 w:1) + /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_disapproved(m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `550 + m * (64 ±0) + p * (36 ±0)` - // Estimated: `3995 + m * (65 ±0) + p * (36 ±0)` - // Minimum execution time: 31_368_000 picoseconds. - Weight::from_parts(32_141_835, 3995) - // Standard Error: 1_451 - .saturating_add(Weight::from_parts(36_372, 0).saturating_mul(m.into())) - // Standard Error: 1_415 - .saturating_add(Weight::from_parts(210_635, 0).saturating_mul(p.into())) + // Measured: `583 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `4028 + m * (65 ±0) + p * (36 ±0)` + // Minimum execution time: 26_385_000 picoseconds. + Weight::from_parts(25_713_839, 4028) + // Standard Error: 1_254 + .saturating_add(Weight::from_parts(36_206, 0).saturating_mul(m.into())) + // Standard Error: 1_223 + .saturating_add(Weight::from_parts(195_114, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 65).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: Council Voting (r:1 w:1) - /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Council Members (r:1 w:0) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Prime (r:1 w:0) - /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council ProposalOf (r:1 w:1) - /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) - /// Storage: Council Proposals (r:1 w:1) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Council::Voting` (r:1 w:1) + /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Council::Members` (r:1 w:0) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Prime` (r:1 w:0) + /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::ProposalOf` (r:1 w:1) + /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: `Council::Proposals` (r:1 w:1) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_approved(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `852 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` - // Estimated: `4169 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` - // Minimum execution time: 43_271_000 picoseconds. - Weight::from_parts(45_495_648, 4169) - // Standard Error: 174 - .saturating_add(Weight::from_parts(3_034, 0).saturating_mul(b.into())) - // Standard Error: 1_840 - .saturating_add(Weight::from_parts(42_209, 0).saturating_mul(m.into())) - // Standard Error: 1_793 - .saturating_add(Weight::from_parts(207_525, 0).saturating_mul(p.into())) - .saturating_add(RocksDbWeight::get().reads(5_u64)) + // Measured: `1030 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `4347 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` + // Minimum execution time: 42_903_000 picoseconds. + Weight::from_parts(43_152_907, 4347) + // Standard Error: 146 + .saturating_add(Weight::from_parts(3_459, 0).saturating_mul(b.into())) + // Standard Error: 1_548 + .saturating_add(Weight::from_parts(35_321, 0).saturating_mul(m.into())) + // Standard Error: 1_509 + .saturating_add(Weight::from_parts(202_541, 0).saturating_mul(p.into())) + .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(b.into())) .saturating_add(Weight::from_parts(0, 66).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) } - /// Storage: Council Proposals (r:1 w:1) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Voting (r:0 w:1) - /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Council ProposalOf (r:0 w:1) - /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: `Council::Proposals` (r:1 w:1) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Voting` (r:0 w:1) + /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Council::ProposalOf` (r:0 w:1) + /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `p` is `[1, 100]`. fn disapprove_proposal(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `359 + p * (32 ±0)` - // Estimated: `1844 + p * (32 ±0)` - // Minimum execution time: 15_170_000 picoseconds. - Weight::from_parts(17_567_243, 1844) - // Standard Error: 1_430 - .saturating_add(Weight::from_parts(169_040, 0).saturating_mul(p.into())) + // Measured: `392 + p * (32 ±0)` + // Estimated: `1877 + p * (32 ±0)` + // Minimum execution time: 12_656_000 picoseconds. + Weight::from_parts(14_032_951, 1877) + // Standard Error: 1_025 + .saturating_add(Weight::from_parts(159_143, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(p.into())) diff --git a/substrate/frame/contracts/src/weights.rs b/substrate/frame/contracts/src/weights.rs index 962591290b3..47ca17c7d80 100644 --- a/substrate/frame/contracts/src/weights.rs +++ b/substrate/frame/contracts/src/weights.rs @@ -17,26 +17,28 @@ //! Autogenerated weights for `pallet_contracts` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-01-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// target/production/substrate-node +// ./target/production/substrate-node // benchmark // pallet +// --chain=dev // --steps=50 // --repeat=20 +// --pallet=pallet_contracts +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_contracts -// --chain=dev -// --header=./substrate/HEADER-APACHE2 // --output=./substrate/frame/contracts/src/weights.rs +// --header=./substrate/HEADER-APACHE2 // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -141,8 +143,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 1_997_000 picoseconds. - Weight::from_parts(2_130_000, 1627) + // Minimum execution time: 2_103_000 picoseconds. + Weight::from_parts(2_260_000, 1627) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -152,10 +154,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `452 + k * (69 ±0)` // Estimated: `442 + k * (70 ±0)` - // Minimum execution time: 12_276_000 picoseconds. - Weight::from_parts(1_593_881, 442) - // Standard Error: 1_135 - .saturating_add(Weight::from_parts(1_109_302, 0).saturating_mul(k.into())) + // Minimum execution time: 12_173_000 picoseconds. + Weight::from_parts(12_515_000, 442) + // Standard Error: 1_033 + .saturating_add(Weight::from_parts(1_075_765, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(T::DbWeight::get().writes(2_u64)) @@ -169,8 +171,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `211 + c * (1 ±0)` // Estimated: `6149 + c * (1 ±0)` - // Minimum execution time: 8_176_000 picoseconds. - Weight::from_parts(8_555_388, 6149) + // Minimum execution time: 8_054_000 picoseconds. + Weight::from_parts(8_503_485, 6149) // Standard Error: 1 .saturating_add(Weight::from_parts(1_184, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) @@ -185,8 +187,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `510` // Estimated: `6450` - // Minimum execution time: 16_270_000 picoseconds. - Weight::from_parts(16_779_000, 6450) + // Minimum execution time: 16_966_000 picoseconds. + Weight::from_parts(17_445_000, 6450) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -199,10 +201,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `171 + k * (1 ±0)` // Estimated: `3635 + k * (1 ±0)` - // Minimum execution time: 3_572_000 picoseconds. - Weight::from_parts(1_950_905, 3635) - // Standard Error: 1_597 - .saturating_add(Weight::from_parts(1_123_190, 0).saturating_mul(k.into())) + // Minimum execution time: 3_643_000 picoseconds. + Weight::from_parts(3_714_000, 3635) + // Standard Error: 1_056 + .saturating_add(Weight::from_parts(1_089_042, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(k.into()))) @@ -212,6 +214,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc553053f13fd319a03c211337c76e0fe776df` (r:2 w:0) /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc553022fca90611ba8b7942f8bdb3b97f6580` (r:1 w:1) /// Proof: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc553022fca90611ba8b7942f8bdb3b97f6580` (r:1 w:1) + /// Storage: `Parameters::Parameters` (r:2 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:0 w:1) @@ -219,13 +223,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `c` is `[0, 125952]`. fn v12_migration_step(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `325 + c * (1 ±0)` - // Estimated: `6263 + c * (1 ±0)` - // Minimum execution time: 16_873_000 picoseconds. - Weight::from_parts(16_790_402, 6263) + // Measured: `328 + c * (1 ±0)` + // Estimated: `6266 + c * (1 ±0)` + // Minimum execution time: 19_891_000 picoseconds. + Weight::from_parts(19_961_608, 6266) // Standard Error: 1 - .saturating_add(Weight::from_parts(396, 0).saturating_mul(c.into())) - .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(Weight::from_parts(429, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) } @@ -235,8 +239,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `440` // Estimated: `6380` - // Minimum execution time: 11_904_000 picoseconds. - Weight::from_parts(12_785_000, 6380) + // Minimum execution time: 12_483_000 picoseconds. + Weight::from_parts(13_205_000, 6380) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -245,13 +249,13 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) fn v14_migration_step() -> Weight { // Proof Size summary in bytes: // Measured: `352` // Estimated: `6292` - // Minimum execution time: 44_920_000 picoseconds. - Weight::from_parts(46_163_000, 6292) + // Minimum execution time: 42_443_000 picoseconds. + Weight::from_parts(43_420_000, 6292) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -263,8 +267,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `594` // Estimated: `6534` - // Minimum execution time: 53_864_000 picoseconds. - Weight::from_parts(55_139_000, 6534) + // Minimum execution time: 52_282_000 picoseconds. + Weight::from_parts(54_110_000, 6534) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -274,8 +278,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 2_375_000 picoseconds. - Weight::from_parts(2_487_000, 1627) + // Minimum execution time: 2_539_000 picoseconds. + Weight::from_parts(2_644_000, 1627) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -287,8 +291,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `166` // Estimated: `3631` - // Minimum execution time: 11_580_000 picoseconds. - Weight::from_parts(11_980_000, 3631) + // Minimum execution time: 9_473_000 picoseconds. + Weight::from_parts(9_907_000, 3631) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -298,8 +302,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 4_557_000 picoseconds. - Weight::from_parts(4_807_000, 3607) + // Minimum execution time: 3_532_000 picoseconds. + Weight::from_parts(3_768_000, 3607) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -310,8 +314,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `167` // Estimated: `3632` - // Minimum execution time: 6_253_000 picoseconds. - Weight::from_parts(6_479_000, 3632) + // Minimum execution time: 5_036_000 picoseconds. + Weight::from_parts(5_208_000, 3632) .saturating_add(T::DbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -322,13 +326,15 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 6_166_000 picoseconds. - Weight::from_parts(6_545_000, 3607) + // Minimum execution time: 4_881_000 picoseconds. + Weight::from_parts(5_149_000, 3607) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -344,22 +350,24 @@ impl WeightInfo for SubstrateWeight { /// The range of component `c` is `[0, 125952]`. fn call_with_code_per_byte(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `801 + c * (1 ±0)` - // Estimated: `6739 + c * (1 ±0)` - // Minimum execution time: 282_232_000 picoseconds. - Weight::from_parts(266_148_573, 6739) - // Standard Error: 69 - .saturating_add(Weight::from_parts(34_592, 0).saturating_mul(c.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `804 + c * (1 ±0)` + // Estimated: `9217 + c * (1 ±0)` + // Minimum execution time: 280_047_000 picoseconds. + Weight::from_parts(270_065_882, 9217) + // Standard Error: 86 + .saturating_add(Weight::from_parts(34_361, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:2 w:2) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) /// Storage: `System::EventTopics` (r:3 w:3) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::Nonce` (r:1 w:1) @@ -377,17 +385,17 @@ impl WeightInfo for SubstrateWeight { /// The range of component `s` is `[0, 1048576]`. fn instantiate_with_code(c: u32, i: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `323` - // Estimated: `8737` - // Minimum execution time: 3_760_879_000 picoseconds. - Weight::from_parts(794_812_431, 8737) + // Measured: `326` + // Estimated: `8740` + // Minimum execution time: 3_776_071_000 picoseconds. + Weight::from_parts(706_212_213, 8740) // Standard Error: 149 - .saturating_add(Weight::from_parts(101_881, 0).saturating_mul(c.into())) - // Standard Error: 18 - .saturating_add(Weight::from_parts(1_404, 0).saturating_mul(i.into())) - // Standard Error: 18 - .saturating_add(Weight::from_parts(1_544, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(11_u64)) + .saturating_add(Weight::from_parts(98_798, 0).saturating_mul(c.into())) + // Standard Error: 17 + .saturating_add(Weight::from_parts(1_560, 0).saturating_mul(i.into())) + // Standard Error: 17 + .saturating_add(Weight::from_parts(1_476, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(14_u64)) .saturating_add(T::DbWeight::get().writes(10_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) @@ -396,6 +404,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:1 w:0) /// Proof: `Contracts::PristineCode` (`max_values`: None, `max_size`: Some(125988), added: 128463, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::Nonce` (r:1 w:1) /// Proof: `Contracts::Nonce` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) @@ -407,24 +417,26 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::EventTopics` (r:2 w:2) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) /// The range of component `i` is `[0, 1048576]`. /// The range of component `s` is `[0, 1048576]`. fn instantiate(i: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `560` - // Estimated: `6504` - // Minimum execution time: 1_953_162_000 picoseconds. - Weight::from_parts(374_252_840, 6504) + // Measured: `563` + // Estimated: `8982` + // Minimum execution time: 1_966_301_000 picoseconds. + Weight::from_parts(376_287_434, 8982) // Standard Error: 7 - .saturating_add(Weight::from_parts(1_630, 0).saturating_mul(i.into())) + .saturating_add(Weight::from_parts(1_643, 0).saturating_mul(i.into())) // Standard Error: 7 - .saturating_add(Weight::from_parts(1_650, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(10_u64)) + .saturating_add(Weight::from_parts(1_667, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(13_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -439,19 +451,21 @@ impl WeightInfo for SubstrateWeight { /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) fn call() -> Weight { // Proof Size summary in bytes: - // Measured: `826` - // Estimated: `6766` - // Minimum execution time: 187_899_000 picoseconds. - Weight::from_parts(195_510_000, 6766) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `829` + // Estimated: `9244` + // Minimum execution time: 197_571_000 picoseconds. + Weight::from_parts(206_612_000, 9244) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:2 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) /// Storage: `System::EventTopics` (r:1 w:1) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:0 w:1) @@ -459,13 +473,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `c` is `[0, 125952]`. fn upload_code(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `142` - // Estimated: `3607` - // Minimum execution time: 254_800_000 picoseconds. - Weight::from_parts(285_603_050, 3607) - // Standard Error: 62 - .saturating_add(Weight::from_parts(66_212, 0).saturating_mul(c.into())) - .saturating_add(T::DbWeight::get().reads(4_u64)) + // Measured: `145` + // Estimated: `6085` + // Minimum execution time: 266_006_000 picoseconds. + Weight::from_parts(287_700_788, 6085) + // Standard Error: 67 + .saturating_add(Weight::from_parts(63_196, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) @@ -473,7 +487,7 @@ impl WeightInfo for SubstrateWeight { /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) /// Storage: `System::EventTopics` (r:1 w:1) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:0 w:1) @@ -482,8 +496,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `315` // Estimated: `3780` - // Minimum execution time: 43_553_000 picoseconds. - Weight::from_parts(45_036_000, 3780) + // Minimum execution time: 42_714_000 picoseconds. + Weight::from_parts(44_713_000, 3780) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -499,8 +513,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `552` // Estimated: `8967` - // Minimum execution time: 33_223_000 picoseconds. - Weight::from_parts(34_385_000, 8967) + // Minimum execution time: 33_516_000 picoseconds. + Weight::from_parts(34_823_000, 8967) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -508,6 +522,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -521,13 +537,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_caller(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `866 + r * (6 ±0)` - // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 254_213_000 picoseconds. - Weight::from_parts(273_464_980, 6806) - // Standard Error: 1_362 - .saturating_add(Weight::from_parts(322_619, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `869 + r * (6 ±0)` + // Estimated: `9284 + r * (6 ±0)` + // Minimum execution time: 246_563_000 picoseconds. + Weight::from_parts(274_999_814, 9284) + // Standard Error: 628 + .saturating_add(Weight::from_parts(347_395, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -535,6 +551,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1601 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -548,13 +566,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_is_contract(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `922 + r * (209 ±0)` - // Estimated: `6826 + r * (2684 ±0)` - // Minimum execution time: 250_273_000 picoseconds. - Weight::from_parts(122_072_782, 6826) - // Standard Error: 5_629 - .saturating_add(Weight::from_parts(3_490_256, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `925 + r * (209 ±0)` + // Estimated: `9304 + r * (2684 ±0)` + // Minimum execution time: 252_236_000 picoseconds. + Weight::from_parts(121_390_081, 9304) + // Standard Error: 6_206 + .saturating_add(Weight::from_parts(3_558_718, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 2684).saturating_mul(r.into())) @@ -563,6 +581,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1601 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -576,13 +596,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_code_hash(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `921 + r * (213 ±0)` - // Estimated: `6830 + r * (2688 ±0)` - // Minimum execution time: 255_187_000 picoseconds. - Weight::from_parts(118_082_505, 6830) - // Standard Error: 6_302 - .saturating_add(Weight::from_parts(4_246_968, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `924 + r * (213 ±0)` + // Estimated: `9308 + r * (2688 ±0)` + // Minimum execution time: 269_427_000 picoseconds. + Weight::from_parts(134_879_389, 9308) + // Standard Error: 6_711 + .saturating_add(Weight::from_parts(4_408_658, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 2688).saturating_mul(r.into())) @@ -591,6 +611,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -604,13 +626,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_own_code_hash(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `873 + r * (6 ±0)` - // Estimated: `6815 + r * (6 ±0)` - // Minimum execution time: 256_833_000 picoseconds. - Weight::from_parts(273_330_216, 6815) - // Standard Error: 881 - .saturating_add(Weight::from_parts(400_105, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `876 + r * (6 ±0)` + // Estimated: `9293 + r * (6 ±0)` + // Minimum execution time: 249_382_000 picoseconds. + Weight::from_parts(266_305_110, 9293) + // Standard Error: 1_592 + .saturating_add(Weight::from_parts(460_001, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -618,6 +640,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -631,18 +655,20 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_caller_is_origin(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `863 + r * (3 ±0)` - // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 244_193_000 picoseconds. - Weight::from_parts(271_221_908, 6804) - // Standard Error: 442 - .saturating_add(Weight::from_parts(176_480, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `866 + r * (3 ±0)` + // Estimated: `9282 + r * (3 ±0)` + // Minimum execution time: 252_145_000 picoseconds. + Weight::from_parts(277_211_668, 9282) + // Standard Error: 371 + .saturating_add(Weight::from_parts(174_394, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -656,13 +682,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_caller_is_root(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `753 + r * (3 ±0)` - // Estimated: `6693 + r * (3 ±0)` - // Minimum execution time: 232_603_000 picoseconds. - Weight::from_parts(260_577_368, 6693) - // Standard Error: 365 - .saturating_add(Weight::from_parts(158_126, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(7_u64)) + // Measured: `756 + r * (3 ±0)` + // Estimated: `9171 + r * (3 ±0)` + // Minimum execution time: 251_595_000 picoseconds. + Weight::from_parts(268_102_575, 9171) + // Standard Error: 334 + .saturating_add(Weight::from_parts(154_836, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(10_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) } @@ -670,6 +696,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -683,13 +711,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_address(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `867 + r * (6 ±0)` - // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 247_564_000 picoseconds. - Weight::from_parts(275_108_914, 6807) - // Standard Error: 505 - .saturating_add(Weight::from_parts(315_065, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `870 + r * (6 ±0)` + // Estimated: `9285 + r * (6 ±0)` + // Minimum execution time: 251_404_000 picoseconds. + Weight::from_parts(278_747_574, 9285) + // Standard Error: 782 + .saturating_add(Weight::from_parts(341_598, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -697,6 +725,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -710,13 +740,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_gas_left(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `863 + r * (6 ±0)` - // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 258_799_000 picoseconds. - Weight::from_parts(274_338_256, 6806) - // Standard Error: 632 - .saturating_add(Weight::from_parts(355_032, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `866 + r * (6 ±0)` + // Estimated: `9284 + r * (6 ±0)` + // Minimum execution time: 255_649_000 picoseconds. + Weight::from_parts(276_509_641, 9284) + // Standard Error: 1_262 + .saturating_add(Weight::from_parts(380_225, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -724,6 +754,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:2 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -737,13 +769,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_balance(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1007 + r * (6 ±0)` - // Estimated: `6931 + r * (6 ±0)` - // Minimum execution time: 253_335_000 picoseconds. - Weight::from_parts(273_013_859, 6931) - // Standard Error: 2_007 - .saturating_add(Weight::from_parts(1_540_735, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(9_u64)) + // Measured: `1010 + r * (6 ±0)` + // Estimated: `9409 + r * (6 ±0)` + // Minimum execution time: 267_143_000 picoseconds. + Weight::from_parts(298_166_116, 9409) + // Standard Error: 3_765 + .saturating_add(Weight::from_parts(1_620_886, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -751,6 +783,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -764,13 +798,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_value_transferred(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `877 + r * (6 ±0)` - // Estimated: `6823 + r * (6 ±0)` - // Minimum execution time: 252_325_000 picoseconds. - Weight::from_parts(274_733_944, 6823) - // Standard Error: 603 - .saturating_add(Weight::from_parts(314_467, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `880 + r * (6 ±0)` + // Estimated: `9301 + r * (6 ±0)` + // Minimum execution time: 250_013_000 picoseconds. + Weight::from_parts(281_469_583, 9301) + // Standard Error: 730 + .saturating_add(Weight::from_parts(339_260, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -778,6 +812,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -791,13 +827,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_minimum_balance(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `875 + r * (6 ±0)` - // Estimated: `6816 + r * (6 ±0)` - // Minimum execution time: 250_698_000 picoseconds. - Weight::from_parts(271_707_578, 6816) - // Standard Error: 952 - .saturating_add(Weight::from_parts(318_412, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `878 + r * (6 ±0)` + // Estimated: `9294 + r * (6 ±0)` + // Minimum execution time: 256_219_000 picoseconds. + Weight::from_parts(275_309_266, 9294) + // Standard Error: 1_199 + .saturating_add(Weight::from_parts(350_824, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -805,6 +841,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -818,13 +856,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_block_number(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `872 + r * (6 ±0)` - // Estimated: `6819 + r * (6 ±0)` - // Minimum execution time: 251_854_000 picoseconds. - Weight::from_parts(272_002_212, 6819) - // Standard Error: 622 - .saturating_add(Weight::from_parts(313_353, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `875 + r * (6 ±0)` + // Estimated: `9297 + r * (6 ±0)` + // Minimum execution time: 264_644_000 picoseconds. + Weight::from_parts(283_856_744, 9297) + // Standard Error: 623 + .saturating_add(Weight::from_parts(334_175, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -832,6 +870,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -845,13 +885,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_now(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `863 + r * (6 ±0)` - // Estimated: `6804 + r * (6 ±0)` - // Minimum execution time: 252_010_000 picoseconds. - Weight::from_parts(270_387_000, 6804) - // Standard Error: 659 - .saturating_add(Weight::from_parts(325_856, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `866 + r * (6 ±0)` + // Estimated: `9282 + r * (6 ±0)` + // Minimum execution time: 263_364_000 picoseconds. + Weight::from_parts(281_379_508, 9282) + // Standard Error: 639 + .saturating_add(Weight::from_parts(338_021, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -859,6 +899,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -874,13 +916,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_weight_to_fee(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `937 + r * (14 ±0)` - // Estimated: `6872 + r * (14 ±0)` - // Minimum execution time: 247_933_000 picoseconds. - Weight::from_parts(281_550_162, 6872) - // Standard Error: 660 - .saturating_add(Weight::from_parts(1_090_869, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(9_u64)) + // Measured: `940 + r * (14 ±0)` + // Estimated: `9350 + r * (14 ±0)` + // Minimum execution time: 269_667_000 picoseconds. + Weight::from_parts(284_662_802, 9350) + // Standard Error: 691 + .saturating_add(Weight::from_parts(799_249, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 14).saturating_mul(r.into())) } @@ -888,6 +930,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -901,13 +945,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_input(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `865 + r * (6 ±0)` - // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 251_158_000 picoseconds. - Weight::from_parts(274_623_152, 6807) - // Standard Error: 491 - .saturating_add(Weight::from_parts(263_916, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `868 + r * (6 ±0)` + // Estimated: `9285 + r * (6 ±0)` + // Minimum execution time: 267_018_000 picoseconds. + Weight::from_parts(281_842_630, 9285) + // Standard Error: 453 + .saturating_add(Weight::from_parts(255_373, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -915,6 +959,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -928,19 +974,21 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 1048576]`. fn seal_input_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `869` - // Estimated: `6809` - // Minimum execution time: 263_205_000 picoseconds. - Weight::from_parts(216_792_893, 6809) + // Measured: `872` + // Estimated: `9287` + // Minimum execution time: 258_208_000 picoseconds. + Weight::from_parts(227_686_792, 9287) // Standard Error: 23 .saturating_add(Weight::from_parts(989, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -954,11 +1002,11 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1]`. fn seal_return(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `853 + r * (45 ±0)` - // Estimated: `6793 + r * (45 ±0)` - // Minimum execution time: 239_663_000 picoseconds. - Weight::from_parts(266_124_565, 6793) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `856 + r * (45 ±0)` + // Estimated: `9271 + r * (45 ±0)` + // Minimum execution time: 245_714_000 picoseconds. + Weight::from_parts(272_527_059, 9271) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 45).saturating_mul(r.into())) } @@ -966,6 +1014,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -979,19 +1029,21 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 1048576]`. fn seal_return_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `863` - // Estimated: `6810` - // Minimum execution time: 241_763_000 picoseconds. - Weight::from_parts(266_535_552, 6810) + // Measured: `866` + // Estimated: `9288` + // Minimum execution time: 256_060_000 picoseconds. + Weight::from_parts(276_710_811, 9288) // Standard Error: 0 - .saturating_add(Weight::from_parts(320, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + .saturating_add(Weight::from_parts(312, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:3 w:3) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:1 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:2 w:2) @@ -1005,28 +1057,30 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::EventTopics` (r:4 w:4) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) /// Storage: `Contracts::DeletionQueue` (r:0 w:1) /// Proof: `Contracts::DeletionQueue` (`max_values`: None, `max_size`: Some(142), added: 2617, mode: `Measured`) /// The range of component `r` is `[0, 1]`. fn seal_terminate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2972 + r * (316 ±0)` - // Estimated: `8912 + r * (5266 ±0)` - // Minimum execution time: 265_888_000 picoseconds. - Weight::from_parts(291_232_232, 8912) - // Standard Error: 845_475 - .saturating_add(Weight::from_parts(104_398_867, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) - .saturating_add(T::DbWeight::get().reads((7_u64).saturating_mul(r.into()))) + // Measured: `2902 + r * (529 ±0)` + // Estimated: `11317 + r * (5479 ±0)` + // Minimum execution time: 270_479_000 picoseconds. + Weight::from_parts(296_706_989, 11317) + // Standard Error: 813_407 + .saturating_add(Weight::from_parts(109_236_910, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) + .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(T::DbWeight::get().writes((10_u64).saturating_mul(r.into()))) - .saturating_add(Weight::from_parts(0, 5266).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(0, 5479).saturating_mul(r.into())) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1042,13 +1096,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_random(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `944 + r * (10 ±0)` - // Estimated: `6885 + r * (10 ±0)` - // Minimum execution time: 248_500_000 picoseconds. - Weight::from_parts(282_353_053, 6885) - // Standard Error: 1_144 - .saturating_add(Weight::from_parts(1_193_841, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(9_u64)) + // Measured: `947 + r * (10 ±0)` + // Estimated: `9363 + r * (10 ±0)` + // Minimum execution time: 251_787_000 picoseconds. + Weight::from_parts(284_036_313, 9363) + // Standard Error: 2_560 + .saturating_add(Weight::from_parts(1_238_301, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) } @@ -1056,6 +1110,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1069,13 +1125,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_deposit_event(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `863 + r * (10 ±0)` - // Estimated: `6805 + r * (10 ±0)` - // Minimum execution time: 248_130_000 picoseconds. - Weight::from_parts(279_583_178, 6805) - // Standard Error: 971 - .saturating_add(Weight::from_parts(1_987_941, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `866 + r * (10 ±0)` + // Estimated: `9283 + r * (10 ±0)` + // Minimum execution time: 250_566_000 picoseconds. + Weight::from_parts(275_402_784, 9283) + // Standard Error: 3_939 + .saturating_add(Weight::from_parts(1_941_995, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) } @@ -1083,6 +1139,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1097,15 +1155,15 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 16384]`. fn seal_deposit_event_per_topic_and_byte(t: u32, n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `880 + t * (32 ±0)` - // Estimated: `6825 + t * (2508 ±0)` - // Minimum execution time: 258_594_000 picoseconds. - Weight::from_parts(276_734_422, 6825) - // Standard Error: 102_093 - .saturating_add(Weight::from_parts(2_559_383, 0).saturating_mul(t.into())) + // Measured: `883 + t * (32 ±0)` + // Estimated: `9303 + t * (2508 ±0)` + // Minimum execution time: 267_544_000 picoseconds. + Weight::from_parts(280_117_825, 9303) + // Standard Error: 102_111 + .saturating_add(Weight::from_parts(3_253_038, 0).saturating_mul(t.into())) // Standard Error: 28 - .saturating_add(Weight::from_parts(501, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + .saturating_add(Weight::from_parts(668, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(t.into()))) @@ -1115,6 +1173,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1128,13 +1188,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_debug_message(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `862 + r * (7 ±0)` - // Estimated: `6807 + r * (7 ±0)` - // Minimum execution time: 154_564_000 picoseconds. - Weight::from_parts(168_931_365, 6807) - // Standard Error: 349 - .saturating_add(Weight::from_parts(226_848, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `865 + r * (7 ±0)` + // Estimated: `9285 + r * (7 ±0)` + // Minimum execution time: 157_769_000 picoseconds. + Weight::from_parts(173_026_565, 9285) + // Standard Error: 405 + .saturating_add(Weight::from_parts(219_727, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 7).saturating_mul(r.into())) } @@ -1142,6 +1202,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `MaxEncodedLen`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1155,13 +1217,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `i` is `[0, 1048576]`. fn seal_debug_message_per_byte(i: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `125813` - // Estimated: `131755` - // Minimum execution time: 394_382_000 picoseconds. - Weight::from_parts(376_780_500, 131755) + // Measured: `125816` + // Estimated: `131758` + // Minimum execution time: 403_961_000 picoseconds. + Weight::from_parts(376_480_872, 131758) // Standard Error: 12 - .saturating_add(Weight::from_parts(1_026, 0).saturating_mul(i.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + .saturating_add(Weight::from_parts(1_041, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -1169,13 +1231,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 800]`. fn seal_set_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `924 + r * (292 ±0)` - // Estimated: `926 + r * (293 ±0)` - // Minimum execution time: 249_757_000 picoseconds. - Weight::from_parts(177_324_374, 926) - // Standard Error: 9_512 - .saturating_add(Weight::from_parts(6_176_717, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `927 + r * (292 ±0)` + // Estimated: `929 + r * (293 ±0)` + // Minimum execution time: 256_272_000 picoseconds. + Weight::from_parts(181_058_379, 929) + // Standard Error: 9_838 + .saturating_add(Weight::from_parts(6_316_677, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) @@ -1186,13 +1248,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 16384]`. fn seal_set_storage_per_new_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1447` - // Estimated: `1430` - // Minimum execution time: 267_564_000 picoseconds. - Weight::from_parts(328_701_080, 1430) - // Standard Error: 61 - .saturating_add(Weight::from_parts(576, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(12_u64)) + // Measured: `1450` + // Estimated: `1433` + // Minimum execution time: 268_713_000 picoseconds. + Weight::from_parts(328_329_131, 1433) + // Standard Error: 66 + .saturating_add(Weight::from_parts(962, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(15_u64)) .saturating_add(T::DbWeight::get().writes(8_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -1200,13 +1262,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 16384]`. fn seal_set_storage_per_old_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1253 + n * (1 ±0)` - // Estimated: `1253 + n * (1 ±0)` - // Minimum execution time: 266_347_000 picoseconds. - Weight::from_parts(289_824_718, 1253) - // Standard Error: 34 - .saturating_add(Weight::from_parts(184, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(9_u64)) + // Measured: `1256 + n * (1 ±0)` + // Estimated: `1256 + n * (1 ±0)` + // Minimum execution time: 265_683_000 picoseconds. + Weight::from_parts(293_784_477, 1256) + // Standard Error: 31 + .saturating_add(Weight::from_parts(377, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -1215,13 +1277,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 800]`. fn seal_clear_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `921 + r * (288 ±0)` - // Estimated: `927 + r * (289 ±0)` - // Minimum execution time: 247_207_000 picoseconds. - Weight::from_parts(179_856_075, 927) - // Standard Error: 9_383 - .saturating_add(Weight::from_parts(6_053_198, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `924 + r * (288 ±0)` + // Estimated: `930 + r * (289 ±0)` + // Minimum execution time: 269_959_000 picoseconds. + Weight::from_parts(186_065_911, 930) + // Standard Error: 9_679 + .saturating_add(Weight::from_parts(6_286_855, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) @@ -1232,13 +1294,11 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 16384]`. fn seal_clear_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1249 + n * (1 ±0)` - // Estimated: `1249 + n * (1 ±0)` - // Minimum execution time: 262_655_000 picoseconds. - Weight::from_parts(289_482_543, 1249) - // Standard Error: 35 - .saturating_add(Weight::from_parts(92, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(9_u64)) + // Measured: `1252 + n * (1 ±0)` + // Estimated: `1252 + n * (1 ±0)` + // Minimum execution time: 265_805_000 picoseconds. + Weight::from_parts(294_633_695, 1252) + .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -1247,13 +1307,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 800]`. fn seal_get_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `921 + r * (296 ±0)` - // Estimated: `923 + r * (297 ±0)` - // Minimum execution time: 247_414_000 picoseconds. - Weight::from_parts(203_317_182, 923) - // Standard Error: 7_191 - .saturating_add(Weight::from_parts(4_925_154, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `924 + r * (296 ±0)` + // Estimated: `926 + r * (297 ±0)` + // Minimum execution time: 264_592_000 picoseconds. + Weight::from_parts(204_670_461, 926) + // Standard Error: 6_869 + .saturating_add(Weight::from_parts(5_137_920, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 297).saturating_mul(r.into())) @@ -1263,13 +1323,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 16384]`. fn seal_get_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1265 + n * (1 ±0)` - // Estimated: `1265 + n * (1 ±0)` - // Minimum execution time: 258_910_000 picoseconds. - Weight::from_parts(283_086_514, 1265) - // Standard Error: 39 - .saturating_add(Weight::from_parts(980, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(9_u64)) + // Measured: `1268 + n * (1 ±0)` + // Estimated: `1268 + n * (1 ±0)` + // Minimum execution time: 273_165_000 picoseconds. + Weight::from_parts(297_883_669, 1268) + // Standard Error: 37 + .saturating_add(Weight::from_parts(576, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -1278,13 +1338,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 800]`. fn seal_contains_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `932 + r * (288 ±0)` - // Estimated: `929 + r * (289 ±0)` - // Minimum execution time: 252_410_000 picoseconds. - Weight::from_parts(201_227_879, 929) - // Standard Error: 6_899 - .saturating_add(Weight::from_parts(4_774_983, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `935 + r * (288 ±0)` + // Estimated: `932 + r * (289 ±0)` + // Minimum execution time: 252_257_000 picoseconds. + Weight::from_parts(205_018_595, 932) + // Standard Error: 7_605 + .saturating_add(Weight::from_parts(4_933_378, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 289).saturating_mul(r.into())) @@ -1294,13 +1354,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 16384]`. fn seal_contains_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1252 + n * (1 ±0)` - // Estimated: `1252 + n * (1 ±0)` - // Minimum execution time: 259_053_000 picoseconds. - Weight::from_parts(283_392_084, 1252) - // Standard Error: 41 - .saturating_add(Weight::from_parts(213, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(9_u64)) + // Measured: `1255 + n * (1 ±0)` + // Estimated: `1255 + n * (1 ±0)` + // Minimum execution time: 266_839_000 picoseconds. + Weight::from_parts(292_064_487, 1255) + // Standard Error: 34 + .saturating_add(Weight::from_parts(194, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -1309,13 +1369,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 800]`. fn seal_take_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `914 + r * (296 ±0)` - // Estimated: `919 + r * (297 ±0)` - // Minimum execution time: 251_371_000 picoseconds. - Weight::from_parts(177_119_717, 919) - // Standard Error: 9_421 - .saturating_add(Weight::from_parts(6_226_005, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `917 + r * (296 ±0)` + // Estimated: `922 + r * (297 ±0)` + // Minimum execution time: 266_072_000 picoseconds. + Weight::from_parts(189_018_352, 922) + // Standard Error: 9_530 + .saturating_add(Weight::from_parts(6_481_011, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) @@ -1326,13 +1386,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 16384]`. fn seal_take_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1266 + n * (1 ±0)` - // Estimated: `1266 + n * (1 ±0)` - // Minimum execution time: 263_350_000 picoseconds. - Weight::from_parts(284_323_917, 1266) - // Standard Error: 31 - .saturating_add(Weight::from_parts(921, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(9_u64)) + // Measured: `1269 + n * (1 ±0)` + // Estimated: `1269 + n * (1 ±0)` + // Minimum execution time: 270_703_000 picoseconds. + Weight::from_parts(292_867_105, 1269) + // Standard Error: 30 + .saturating_add(Weight::from_parts(800, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -1340,6 +1400,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1602 w:1601) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1353,13 +1415,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_transfer(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1415 + r * (45 ±0)` - // Estimated: `7307 + r * (2520 ±0)` - // Minimum execution time: 248_701_000 picoseconds. - Weight::from_parts(17_811_969, 7307) - // Standard Error: 35_154 - .saturating_add(Weight::from_parts(31_809_738, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(9_u64)) + // Measured: `1418 + r * (45 ±0)` + // Estimated: `9785 + r * (2520 ±0)` + // Minimum execution time: 251_843_000 picoseconds. + Weight::from_parts(181_026_888, 9785) + // Standard Error: 38_221 + .saturating_add(Weight::from_parts(30_626_681, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) @@ -1369,6 +1431,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:801 w:801) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:2 w:0) @@ -1382,13 +1446,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 800]`. fn seal_call(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1260 + r * (245 ±0)` - // Estimated: `9440 + r * (2721 ±0)` - // Minimum execution time: 247_335_000 picoseconds. - Weight::from_parts(264_025_000, 9440) - // Standard Error: 121_299 - .saturating_add(Weight::from_parts(234_770_827, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(11_u64)) + // Measured: `1263 + r * (245 ±0)` + // Estimated: `9635 + r * (2721 ±0)` + // Minimum execution time: 254_881_000 picoseconds. + Weight::from_parts(272_871_000, 9635) + // Standard Error: 94_527 + .saturating_add(Weight::from_parts(233_379_497, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(14_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(r.into()))) @@ -1398,6 +1462,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:736 w:0) @@ -1412,12 +1478,12 @@ impl WeightInfo for SubstrateWeight { fn seal_delegate_call(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + r * (576 ±0)` - // Estimated: `6812 + r * (2637 ±3)` - // Minimum execution time: 261_011_000 picoseconds. - Weight::from_parts(264_554_000, 6812) - // Standard Error: 104_415 - .saturating_add(Weight::from_parts(231_627_084, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Estimated: `9290 + r * (2637 ±3)` + // Minimum execution time: 266_704_000 picoseconds. + Weight::from_parts(273_165_000, 9290) + // Standard Error: 141_486 + .saturating_add(Weight::from_parts(232_947_049, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) @@ -1427,6 +1493,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:3 w:2) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:2 w:2) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:2 w:0) @@ -1441,15 +1509,15 @@ impl WeightInfo for SubstrateWeight { /// The range of component `c` is `[0, 1048576]`. fn seal_call_per_transfer_clone_byte(t: u32, c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1307 + t * (277 ±0)` - // Estimated: `12197 + t * (5227 ±0)` - // Minimum execution time: 445_561_000 picoseconds. - Weight::from_parts(62_287_490, 12197) - // Standard Error: 11_797_697 - .saturating_add(Weight::from_parts(357_530_529, 0).saturating_mul(t.into())) + // Measured: `1310 + t * (277 ±0)` + // Estimated: `12200 + t * (5227 ±0)` + // Minimum execution time: 446_451_000 picoseconds. + Weight::from_parts(68_175_222, 12200) + // Standard Error: 11_619_250 + .saturating_add(Weight::from_parts(354_237_260, 0).saturating_mul(t.into())) // Standard Error: 17 - .saturating_add(Weight::from_parts(970, 0).saturating_mul(c.into())) - .saturating_add(T::DbWeight::get().reads(13_u64)) + .saturating_add(Weight::from_parts(987, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(16_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(6_u64)) .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(t.into()))) @@ -1459,6 +1527,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:802 w:802) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:801 w:801) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:801 w:800) @@ -1472,17 +1542,17 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::EventTopics` (r:803 w:803) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:800 w:800) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) /// The range of component `r` is `[1, 800]`. fn seal_instantiate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1278 + r * (255 ±0)` - // Estimated: `9620 + r * (2731 ±0)` - // Minimum execution time: 621_897_000 picoseconds. - Weight::from_parts(631_687_000, 9620) - // Standard Error: 215_241 - .saturating_add(Weight::from_parts(350_527_831, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(11_u64)) + // Measured: `1281 + r * (255 ±0)` + // Estimated: `9623 + r * (2731 ±0)` + // Minimum execution time: 628_156_000 picoseconds. + Weight::from_parts(642_052_000, 9623) + // Standard Error: 223_957 + .saturating_add(Weight::from_parts(348_660_264, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(14_u64)) .saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(7_u64)) .saturating_add(T::DbWeight::get().writes((5_u64).saturating_mul(r.into()))) @@ -1492,6 +1562,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:3 w:3) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:2 w:2) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:2 w:1) @@ -1505,23 +1577,23 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::EventTopics` (r:4 w:4) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) /// The range of component `t` is `[0, 1]`. /// The range of component `i` is `[0, 983040]`. /// The range of component `s` is `[0, 983040]`. fn seal_instantiate_per_transfer_input_salt_byte(t: u32, i: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1303 + t * (104 ±0)` - // Estimated: `12211 + t * (2549 ±1)` - // Minimum execution time: 2_181_184_000 picoseconds. - Weight::from_parts(1_194_190_111, 12211) - // Standard Error: 11_578_766 - .saturating_add(Weight::from_parts(6_361_884, 0).saturating_mul(t.into())) - // Standard Error: 18 - .saturating_add(Weight::from_parts(1_025, 0).saturating_mul(i.into())) - // Standard Error: 18 - .saturating_add(Weight::from_parts(1_158, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(16_u64)) + // Measured: `1306 + t * (104 ±0)` + // Estimated: `12214 + t * (2549 ±1)` + // Minimum execution time: 2_106_379_000 picoseconds. + Weight::from_parts(1_098_227_098, 12214) + // Standard Error: 12_549_729 + .saturating_add(Weight::from_parts(21_628_382, 0).saturating_mul(t.into())) + // Standard Error: 19 + .saturating_add(Weight::from_parts(1_059, 0).saturating_mul(i.into())) + // Standard Error: 19 + .saturating_add(Weight::from_parts(1_220, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(19_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(11_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(t.into()))) @@ -1531,6 +1603,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1544,13 +1618,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_hash_sha2_256(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `862 + r * (8 ±0)` - // Estimated: `6801 + r * (8 ±0)` - // Minimum execution time: 241_609_000 picoseconds. - Weight::from_parts(268_716_874, 6801) - // Standard Error: 617 - .saturating_add(Weight::from_parts(377_753, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `865 + r * (8 ±0)` + // Estimated: `9279 + r * (8 ±0)` + // Minimum execution time: 257_102_000 picoseconds. + Weight::from_parts(278_920_692, 9279) + // Standard Error: 464 + .saturating_add(Weight::from_parts(374_120, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) } @@ -1558,6 +1632,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1571,19 +1647,21 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 1048576]`. fn seal_hash_sha2_256_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `870` - // Estimated: `6808` - // Minimum execution time: 261_296_000 picoseconds. - Weight::from_parts(255_531_654, 6808) + // Measured: `873` + // Estimated: `9286` + // Minimum execution time: 266_609_000 picoseconds. + Weight::from_parts(263_034_132, 9286) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_081, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + .saturating_add(Weight::from_parts(1_082, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1597,13 +1675,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_hash_keccak_256(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `864 + r * (8 ±0)` - // Estimated: `6806 + r * (8 ±0)` - // Minimum execution time: 243_583_000 picoseconds. - Weight::from_parts(270_025_058, 6806) - // Standard Error: 560 - .saturating_add(Weight::from_parts(767_519, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `867 + r * (8 ±0)` + // Estimated: `9284 + r * (8 ±0)` + // Minimum execution time: 246_275_000 picoseconds. + Weight::from_parts(279_091_594, 9284) + // Standard Error: 887 + .saturating_add(Weight::from_parts(810_394, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) } @@ -1611,6 +1689,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1624,19 +1704,21 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 1048576]`. fn seal_hash_keccak_256_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `872` - // Estimated: `6814` - // Minimum execution time: 253_798_000 picoseconds. - Weight::from_parts(265_542_351, 6814) + // Measured: `875` + // Estimated: `9292` + // Minimum execution time: 249_254_000 picoseconds. + Weight::from_parts(270_833_823, 9292) // Standard Error: 0 - .saturating_add(Weight::from_parts(3_343, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + .saturating_add(Weight::from_parts(3_347, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1650,13 +1732,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_hash_blake2_256(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `864 + r * (8 ±0)` - // Estimated: `6808 + r * (8 ±0)` - // Minimum execution time: 247_332_000 picoseconds. - Weight::from_parts(269_183_656, 6808) - // Standard Error: 665 - .saturating_add(Weight::from_parts(443_386, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `867 + r * (8 ±0)` + // Estimated: `9286 + r * (8 ±0)` + // Minimum execution time: 259_131_000 picoseconds. + Weight::from_parts(272_665_020, 9286) + // Standard Error: 862 + .saturating_add(Weight::from_parts(451_247, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) } @@ -1664,6 +1746,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1677,19 +1761,21 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 1048576]`. fn seal_hash_blake2_256_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `872` - // Estimated: `6813` - // Minimum execution time: 250_855_000 picoseconds. - Weight::from_parts(258_752_975, 6813) + // Measured: `875` + // Estimated: `9291` + // Minimum execution time: 276_465_000 picoseconds. + Weight::from_parts(269_450_297, 9291) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_202, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + .saturating_add(Weight::from_parts(1_190, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1703,13 +1789,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_hash_blake2_128(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `864 + r * (8 ±0)` - // Estimated: `6805 + r * (8 ±0)` - // Minimum execution time: 240_733_000 picoseconds. - Weight::from_parts(269_134_358, 6805) - // Standard Error: 512 - .saturating_add(Weight::from_parts(440_043, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `867 + r * (8 ±0)` + // Estimated: `9283 + r * (8 ±0)` + // Minimum execution time: 248_349_000 picoseconds. + Weight::from_parts(273_660_686, 9283) + // Standard Error: 656 + .saturating_add(Weight::from_parts(444_293, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) } @@ -1717,6 +1803,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1730,19 +1818,21 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 1048576]`. fn seal_hash_blake2_128_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `872` - // Estimated: `6811` - // Minimum execution time: 247_377_000 picoseconds. - Weight::from_parts(261_077_322, 6811) - // Standard Error: 0 - .saturating_add(Weight::from_parts(1_195, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `875` + // Estimated: `9289` + // Minimum execution time: 252_107_000 picoseconds. + Weight::from_parts(267_427_726, 9289) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_199, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1756,13 +1846,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 125697]`. fn seal_sr25519_verify_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `997 + n * (1 ±0)` - // Estimated: `6934 + n * (1 ±0)` - // Minimum execution time: 307_337_000 picoseconds. - Weight::from_parts(326_710_473, 6934) - // Standard Error: 9 - .saturating_add(Weight::from_parts(5_765, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `1000 + n * (1 ±0)` + // Estimated: `9412 + n * (1 ±0)` + // Minimum execution time: 311_252_000 picoseconds. + Weight::from_parts(333_250_773, 9412) + // Standard Error: 12 + .saturating_add(Weight::from_parts(5_668, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -1770,6 +1860,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1783,13 +1875,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 160]`. fn seal_sr25519_verify(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `805 + r * (112 ±0)` - // Estimated: `6748 + r * (112 ±0)` - // Minimum execution time: 245_432_000 picoseconds. - Weight::from_parts(294_206_377, 6748) - // Standard Error: 7_229 - .saturating_add(Weight::from_parts(41_480_485, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `810 + r * (112 ±0)` + // Estimated: `9226 + r * (112 ±0)` + // Minimum execution time: 267_431_000 picoseconds. + Weight::from_parts(300_733_048, 9226) + // Standard Error: 8_806 + .saturating_add(Weight::from_parts(42_169_197, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(r.into())) } @@ -1797,6 +1889,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1810,13 +1904,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 160]`. fn seal_ecdsa_recover(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `907 + r * (76 ±0)` - // Estimated: `6802 + r * (77 ±0)` - // Minimum execution time: 247_788_000 picoseconds. - Weight::from_parts(303_940_062, 6802) - // Standard Error: 10_671 - .saturating_add(Weight::from_parts(45_730_772, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `910 + r * (76 ±0)` + // Estimated: `9279 + r * (77 ±0)` + // Minimum execution time: 265_905_000 picoseconds. + Weight::from_parts(305_381_951, 9279) + // Standard Error: 9_863 + .saturating_add(Weight::from_parts(45_771_182, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 77).saturating_mul(r.into())) } @@ -1824,6 +1918,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1837,13 +1933,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 160]`. fn seal_ecdsa_to_eth_address(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `877 + r * (42 ±0)` - // Estimated: `6816 + r * (42 ±0)` - // Minimum execution time: 248_825_000 picoseconds. - Weight::from_parts(286_832_225, 6816) - // Standard Error: 5_274 - .saturating_add(Weight::from_parts(11_889_262, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `880 + r * (42 ±0)` + // Estimated: `9294 + r * (42 ±0)` + // Minimum execution time: 266_701_000 picoseconds. + Weight::from_parts(292_407_888, 9294) + // Standard Error: 5_394 + .saturating_add(Weight::from_parts(11_896_065, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 42).saturating_mul(r.into())) } @@ -1851,6 +1947,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1536 w:1536) @@ -1865,12 +1963,12 @@ impl WeightInfo for SubstrateWeight { fn seal_set_code_hash(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + r * (965 ±0)` - // Estimated: `6807 + r * (3090 ±7)` - // Minimum execution time: 244_982_000 picoseconds. - Weight::from_parts(265_297_000, 6807) - // Standard Error: 39_895 - .saturating_add(Weight::from_parts(22_435_888, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Estimated: `9285 + r * (3090 ±7)` + // Minimum execution time: 268_755_000 picoseconds. + Weight::from_parts(272_300_000, 9285) + // Standard Error: 43_747 + .saturating_add(Weight::from_parts(25_001_889, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(r.into()))) @@ -1880,6 +1978,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:33 w:32) @@ -1893,22 +1993,24 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 32]`. fn lock_delegate_dependency(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `928 + r * (131 ±0)` - // Estimated: `6878 + r * (2606 ±0)` - // Minimum execution time: 246_455_000 picoseconds. - Weight::from_parts(275_334_919, 6878) - // Standard Error: 20_911 - .saturating_add(Weight::from_parts(6_427_525, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `937 + r * (131 ±0)` + // Estimated: `9346 + r * (2607 ±0)` + // Minimum execution time: 255_190_000 picoseconds. + Weight::from_parts(285_643_922, 9346) + // Standard Error: 23_582 + .saturating_add(Weight::from_parts(6_289_940, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) - .saturating_add(Weight::from_parts(0, 2606).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(0, 2607).saturating_mul(r.into())) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `MaxEncodedLen`) /// Storage: `Contracts::CodeInfoOf` (r:33 w:32) @@ -1922,13 +2024,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 32]`. fn unlock_delegate_dependency(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `969 + r * (183 ±0)` + // Measured: `972 + r * (184 ±0)` // Estimated: `129453 + r * (2568 ±0)` - // Minimum execution time: 254_472_000 picoseconds. - Weight::from_parts(280_657_909, 129453) - // Standard Error: 20_131 - .saturating_add(Weight::from_parts(5_644_006, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Minimum execution time: 260_061_000 picoseconds. + Weight::from_parts(286_849_343, 129453) + // Standard Error: 22_406 + .saturating_add(Weight::from_parts(5_661_459, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) @@ -1938,6 +2040,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1951,13 +2055,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_reentrance_count(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `858 + r * (3 ±0)` - // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 250_535_000 picoseconds. - Weight::from_parts(270_318_376, 6804) - // Standard Error: 386 - .saturating_add(Weight::from_parts(174_627, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `861 + r * (3 ±0)` + // Estimated: `9282 + r * (3 ±0)` + // Minimum execution time: 250_922_000 picoseconds. + Weight::from_parts(277_294_913, 9282) + // Standard Error: 391 + .saturating_add(Weight::from_parts(169_457, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) } @@ -1965,6 +2069,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1978,13 +2084,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_account_reentrance_count(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2109 + r * (39 ±0)` - // Estimated: `7899 + r * (40 ±0)` - // Minimum execution time: 248_174_000 picoseconds. - Weight::from_parts(301_826_520, 7899) - // Standard Error: 801 - .saturating_add(Weight::from_parts(248_479, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `2112 + r * (39 ±0)` + // Estimated: `10377 + r * (40 ±0)` + // Minimum execution time: 267_293_000 picoseconds. + Weight::from_parts(309_125_635, 10377) + // Standard Error: 637 + .saturating_add(Weight::from_parts(245_508, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) } @@ -1992,6 +2098,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2007,13 +2115,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 1600]`. fn seal_instantiation_nonce(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `861 + r * (3 ±0)` - // Estimated: `6801 + r * (3 ±0)` - // Minimum execution time: 246_540_000 picoseconds. - Weight::from_parts(268_913_509, 6801) - // Standard Error: 378 - .saturating_add(Weight::from_parts(154_950, 0).saturating_mul(r.into())) - .saturating_add(T::DbWeight::get().reads(9_u64)) + // Measured: `864 + r * (3 ±0)` + // Estimated: `9279 + r * (3 ±0)` + // Minimum execution time: 256_057_000 picoseconds. + Weight::from_parts(278_068_870, 9279) + // Standard Error: 335 + .saturating_add(Weight::from_parts(152_083, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) } @@ -2022,10 +2130,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_777_000 picoseconds. - Weight::from_parts(1_707_601, 0) - // Standard Error: 14 - .saturating_add(Weight::from_parts(15_392, 0).saturating_mul(r.into())) + // Minimum execution time: 1_846_000 picoseconds. + Weight::from_parts(1_808_029, 0) + // Standard Error: 9 + .saturating_add(Weight::from_parts(14_937, 0).saturating_mul(r.into())) } } @@ -2037,8 +2145,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 1_997_000 picoseconds. - Weight::from_parts(2_130_000, 1627) + // Minimum execution time: 2_103_000 picoseconds. + Weight::from_parts(2_260_000, 1627) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -2048,10 +2156,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `452 + k * (69 ±0)` // Estimated: `442 + k * (70 ±0)` - // Minimum execution time: 12_276_000 picoseconds. - Weight::from_parts(1_593_881, 442) - // Standard Error: 1_135 - .saturating_add(Weight::from_parts(1_109_302, 0).saturating_mul(k.into())) + // Minimum execution time: 12_173_000 picoseconds. + Weight::from_parts(12_515_000, 442) + // Standard Error: 1_033 + .saturating_add(Weight::from_parts(1_075_765, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(RocksDbWeight::get().writes(2_u64)) @@ -2065,8 +2173,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `211 + c * (1 ±0)` // Estimated: `6149 + c * (1 ±0)` - // Minimum execution time: 8_176_000 picoseconds. - Weight::from_parts(8_555_388, 6149) + // Minimum execution time: 8_054_000 picoseconds. + Weight::from_parts(8_503_485, 6149) // Standard Error: 1 .saturating_add(Weight::from_parts(1_184, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) @@ -2081,8 +2189,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `510` // Estimated: `6450` - // Minimum execution time: 16_270_000 picoseconds. - Weight::from_parts(16_779_000, 6450) + // Minimum execution time: 16_966_000 picoseconds. + Weight::from_parts(17_445_000, 6450) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2095,10 +2203,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `171 + k * (1 ±0)` // Estimated: `3635 + k * (1 ±0)` - // Minimum execution time: 3_572_000 picoseconds. - Weight::from_parts(1_950_905, 3635) - // Standard Error: 1_597 - .saturating_add(Weight::from_parts(1_123_190, 0).saturating_mul(k.into())) + // Minimum execution time: 3_643_000 picoseconds. + Weight::from_parts(3_714_000, 3635) + // Standard Error: 1_056 + .saturating_add(Weight::from_parts(1_089_042, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(k.into()))) @@ -2108,6 +2216,8 @@ impl WeightInfo for () { /// Proof: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc553053f13fd319a03c211337c76e0fe776df` (r:2 w:0) /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc553022fca90611ba8b7942f8bdb3b97f6580` (r:1 w:1) /// Proof: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc553022fca90611ba8b7942f8bdb3b97f6580` (r:1 w:1) + /// Storage: `Parameters::Parameters` (r:2 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:0 w:1) @@ -2115,13 +2225,13 @@ impl WeightInfo for () { /// The range of component `c` is `[0, 125952]`. fn v12_migration_step(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `325 + c * (1 ±0)` - // Estimated: `6263 + c * (1 ±0)` - // Minimum execution time: 16_873_000 picoseconds. - Weight::from_parts(16_790_402, 6263) + // Measured: `328 + c * (1 ±0)` + // Estimated: `6266 + c * (1 ±0)` + // Minimum execution time: 19_891_000 picoseconds. + Weight::from_parts(19_961_608, 6266) // Standard Error: 1 - .saturating_add(Weight::from_parts(396, 0).saturating_mul(c.into())) - .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(Weight::from_parts(429, 0).saturating_mul(c.into())) + .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) } @@ -2131,8 +2241,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `440` // Estimated: `6380` - // Minimum execution time: 11_904_000 picoseconds. - Weight::from_parts(12_785_000, 6380) + // Minimum execution time: 12_483_000 picoseconds. + Weight::from_parts(13_205_000, 6380) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2141,13 +2251,13 @@ impl WeightInfo for () { /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) fn v14_migration_step() -> Weight { // Proof Size summary in bytes: // Measured: `352` // Estimated: `6292` - // Minimum execution time: 44_920_000 picoseconds. - Weight::from_parts(46_163_000, 6292) + // Minimum execution time: 42_443_000 picoseconds. + Weight::from_parts(43_420_000, 6292) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2159,8 +2269,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `594` // Estimated: `6534` - // Minimum execution time: 53_864_000 picoseconds. - Weight::from_parts(55_139_000, 6534) + // Minimum execution time: 52_282_000 picoseconds. + Weight::from_parts(54_110_000, 6534) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -2170,8 +2280,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 2_375_000 picoseconds. - Weight::from_parts(2_487_000, 1627) + // Minimum execution time: 2_539_000 picoseconds. + Weight::from_parts(2_644_000, 1627) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2183,8 +2293,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `166` // Estimated: `3631` - // Minimum execution time: 11_580_000 picoseconds. - Weight::from_parts(11_980_000, 3631) + // Minimum execution time: 9_473_000 picoseconds. + Weight::from_parts(9_907_000, 3631) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -2194,8 +2304,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 4_557_000 picoseconds. - Weight::from_parts(4_807_000, 3607) + // Minimum execution time: 3_532_000 picoseconds. + Weight::from_parts(3_768_000, 3607) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -2206,8 +2316,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `167` // Estimated: `3632` - // Minimum execution time: 6_253_000 picoseconds. - Weight::from_parts(6_479_000, 3632) + // Minimum execution time: 5_036_000 picoseconds. + Weight::from_parts(5_208_000, 3632) .saturating_add(RocksDbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -2218,13 +2328,15 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 6_166_000 picoseconds. - Weight::from_parts(6_545_000, 3607) + // Minimum execution time: 4_881_000 picoseconds. + Weight::from_parts(5_149_000, 3607) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2240,22 +2352,24 @@ impl WeightInfo for () { /// The range of component `c` is `[0, 125952]`. fn call_with_code_per_byte(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `801 + c * (1 ±0)` - // Estimated: `6739 + c * (1 ±0)` - // Minimum execution time: 282_232_000 picoseconds. - Weight::from_parts(266_148_573, 6739) - // Standard Error: 69 - .saturating_add(Weight::from_parts(34_592, 0).saturating_mul(c.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `804 + c * (1 ±0)` + // Estimated: `9217 + c * (1 ±0)` + // Minimum execution time: 280_047_000 picoseconds. + Weight::from_parts(270_065_882, 9217) + // Standard Error: 86 + .saturating_add(Weight::from_parts(34_361, 0).saturating_mul(c.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:2 w:2) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) /// Storage: `System::EventTopics` (r:3 w:3) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::Nonce` (r:1 w:1) @@ -2273,17 +2387,17 @@ impl WeightInfo for () { /// The range of component `s` is `[0, 1048576]`. fn instantiate_with_code(c: u32, i: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `323` - // Estimated: `8737` - // Minimum execution time: 3_760_879_000 picoseconds. - Weight::from_parts(794_812_431, 8737) + // Measured: `326` + // Estimated: `8740` + // Minimum execution time: 3_776_071_000 picoseconds. + Weight::from_parts(706_212_213, 8740) // Standard Error: 149 - .saturating_add(Weight::from_parts(101_881, 0).saturating_mul(c.into())) - // Standard Error: 18 - .saturating_add(Weight::from_parts(1_404, 0).saturating_mul(i.into())) - // Standard Error: 18 - .saturating_add(Weight::from_parts(1_544, 0).saturating_mul(s.into())) - .saturating_add(RocksDbWeight::get().reads(11_u64)) + .saturating_add(Weight::from_parts(98_798, 0).saturating_mul(c.into())) + // Standard Error: 17 + .saturating_add(Weight::from_parts(1_560, 0).saturating_mul(i.into())) + // Standard Error: 17 + .saturating_add(Weight::from_parts(1_476, 0).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(14_u64)) .saturating_add(RocksDbWeight::get().writes(10_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) @@ -2292,6 +2406,8 @@ impl WeightInfo for () { /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:1 w:0) /// Proof: `Contracts::PristineCode` (`max_values`: None, `max_size`: Some(125988), added: 128463, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::Nonce` (r:1 w:1) /// Proof: `Contracts::Nonce` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) @@ -2303,24 +2419,26 @@ impl WeightInfo for () { /// Storage: `System::EventTopics` (r:2 w:2) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) /// The range of component `i` is `[0, 1048576]`. /// The range of component `s` is `[0, 1048576]`. fn instantiate(i: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `560` - // Estimated: `6504` - // Minimum execution time: 1_953_162_000 picoseconds. - Weight::from_parts(374_252_840, 6504) + // Measured: `563` + // Estimated: `8982` + // Minimum execution time: 1_966_301_000 picoseconds. + Weight::from_parts(376_287_434, 8982) // Standard Error: 7 - .saturating_add(Weight::from_parts(1_630, 0).saturating_mul(i.into())) + .saturating_add(Weight::from_parts(1_643, 0).saturating_mul(i.into())) // Standard Error: 7 - .saturating_add(Weight::from_parts(1_650, 0).saturating_mul(s.into())) - .saturating_add(RocksDbWeight::get().reads(10_u64)) + .saturating_add(Weight::from_parts(1_667, 0).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(13_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2335,19 +2453,21 @@ impl WeightInfo for () { /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) fn call() -> Weight { // Proof Size summary in bytes: - // Measured: `826` - // Estimated: `6766` - // Minimum execution time: 187_899_000 picoseconds. - Weight::from_parts(195_510_000, 6766) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `829` + // Estimated: `9244` + // Minimum execution time: 197_571_000 picoseconds. + Weight::from_parts(206_612_000, 9244) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:2 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) /// Storage: `System::EventTopics` (r:1 w:1) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:0 w:1) @@ -2355,13 +2475,13 @@ impl WeightInfo for () { /// The range of component `c` is `[0, 125952]`. fn upload_code(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `142` - // Estimated: `3607` - // Minimum execution time: 254_800_000 picoseconds. - Weight::from_parts(285_603_050, 3607) - // Standard Error: 62 - .saturating_add(Weight::from_parts(66_212, 0).saturating_mul(c.into())) - .saturating_add(RocksDbWeight::get().reads(4_u64)) + // Measured: `145` + // Estimated: `6085` + // Minimum execution time: 266_006_000 picoseconds. + Weight::from_parts(287_700_788, 6085) + // Standard Error: 67 + .saturating_add(Weight::from_parts(63_196, 0).saturating_mul(c.into())) + .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) @@ -2369,7 +2489,7 @@ impl WeightInfo for () { /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) /// Storage: `System::EventTopics` (r:1 w:1) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:0 w:1) @@ -2378,8 +2498,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `315` // Estimated: `3780` - // Minimum execution time: 43_553_000 picoseconds. - Weight::from_parts(45_036_000, 3780) + // Minimum execution time: 42_714_000 picoseconds. + Weight::from_parts(44_713_000, 3780) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -2395,8 +2515,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `552` // Estimated: `8967` - // Minimum execution time: 33_223_000 picoseconds. - Weight::from_parts(34_385_000, 8967) + // Minimum execution time: 33_516_000 picoseconds. + Weight::from_parts(34_823_000, 8967) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -2404,6 +2524,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2417,13 +2539,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_caller(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `866 + r * (6 ±0)` - // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 254_213_000 picoseconds. - Weight::from_parts(273_464_980, 6806) - // Standard Error: 1_362 - .saturating_add(Weight::from_parts(322_619, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `869 + r * (6 ±0)` + // Estimated: `9284 + r * (6 ±0)` + // Minimum execution time: 246_563_000 picoseconds. + Weight::from_parts(274_999_814, 9284) + // Standard Error: 628 + .saturating_add(Weight::from_parts(347_395, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -2431,6 +2553,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1601 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2444,13 +2568,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_is_contract(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `922 + r * (209 ±0)` - // Estimated: `6826 + r * (2684 ±0)` - // Minimum execution time: 250_273_000 picoseconds. - Weight::from_parts(122_072_782, 6826) - // Standard Error: 5_629 - .saturating_add(Weight::from_parts(3_490_256, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `925 + r * (209 ±0)` + // Estimated: `9304 + r * (2684 ±0)` + // Minimum execution time: 252_236_000 picoseconds. + Weight::from_parts(121_390_081, 9304) + // Standard Error: 6_206 + .saturating_add(Weight::from_parts(3_558_718, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 2684).saturating_mul(r.into())) @@ -2459,6 +2583,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1601 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2472,13 +2598,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_code_hash(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `921 + r * (213 ±0)` - // Estimated: `6830 + r * (2688 ±0)` - // Minimum execution time: 255_187_000 picoseconds. - Weight::from_parts(118_082_505, 6830) - // Standard Error: 6_302 - .saturating_add(Weight::from_parts(4_246_968, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `924 + r * (213 ±0)` + // Estimated: `9308 + r * (2688 ±0)` + // Minimum execution time: 269_427_000 picoseconds. + Weight::from_parts(134_879_389, 9308) + // Standard Error: 6_711 + .saturating_add(Weight::from_parts(4_408_658, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 2688).saturating_mul(r.into())) @@ -2487,6 +2613,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2500,13 +2628,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_own_code_hash(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `873 + r * (6 ±0)` - // Estimated: `6815 + r * (6 ±0)` - // Minimum execution time: 256_833_000 picoseconds. - Weight::from_parts(273_330_216, 6815) - // Standard Error: 881 - .saturating_add(Weight::from_parts(400_105, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `876 + r * (6 ±0)` + // Estimated: `9293 + r * (6 ±0)` + // Minimum execution time: 249_382_000 picoseconds. + Weight::from_parts(266_305_110, 9293) + // Standard Error: 1_592 + .saturating_add(Weight::from_parts(460_001, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -2514,6 +2642,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2527,18 +2657,20 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_caller_is_origin(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `863 + r * (3 ±0)` - // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 244_193_000 picoseconds. - Weight::from_parts(271_221_908, 6804) - // Standard Error: 442 - .saturating_add(Weight::from_parts(176_480, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `866 + r * (3 ±0)` + // Estimated: `9282 + r * (3 ±0)` + // Minimum execution time: 252_145_000 picoseconds. + Weight::from_parts(277_211_668, 9282) + // Standard Error: 371 + .saturating_add(Weight::from_parts(174_394, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2552,13 +2684,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_caller_is_root(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `753 + r * (3 ±0)` - // Estimated: `6693 + r * (3 ±0)` - // Minimum execution time: 232_603_000 picoseconds. - Weight::from_parts(260_577_368, 6693) - // Standard Error: 365 - .saturating_add(Weight::from_parts(158_126, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(7_u64)) + // Measured: `756 + r * (3 ±0)` + // Estimated: `9171 + r * (3 ±0)` + // Minimum execution time: 251_595_000 picoseconds. + Weight::from_parts(268_102_575, 9171) + // Standard Error: 334 + .saturating_add(Weight::from_parts(154_836, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(10_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) } @@ -2566,6 +2698,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2579,13 +2713,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_address(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `867 + r * (6 ±0)` - // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 247_564_000 picoseconds. - Weight::from_parts(275_108_914, 6807) - // Standard Error: 505 - .saturating_add(Weight::from_parts(315_065, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `870 + r * (6 ±0)` + // Estimated: `9285 + r * (6 ±0)` + // Minimum execution time: 251_404_000 picoseconds. + Weight::from_parts(278_747_574, 9285) + // Standard Error: 782 + .saturating_add(Weight::from_parts(341_598, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -2593,6 +2727,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2606,13 +2742,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_gas_left(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `863 + r * (6 ±0)` - // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 258_799_000 picoseconds. - Weight::from_parts(274_338_256, 6806) - // Standard Error: 632 - .saturating_add(Weight::from_parts(355_032, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `866 + r * (6 ±0)` + // Estimated: `9284 + r * (6 ±0)` + // Minimum execution time: 255_649_000 picoseconds. + Weight::from_parts(276_509_641, 9284) + // Standard Error: 1_262 + .saturating_add(Weight::from_parts(380_225, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -2620,6 +2756,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:2 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2633,13 +2771,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_balance(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1007 + r * (6 ±0)` - // Estimated: `6931 + r * (6 ±0)` - // Minimum execution time: 253_335_000 picoseconds. - Weight::from_parts(273_013_859, 6931) - // Standard Error: 2_007 - .saturating_add(Weight::from_parts(1_540_735, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(9_u64)) + // Measured: `1010 + r * (6 ±0)` + // Estimated: `9409 + r * (6 ±0)` + // Minimum execution time: 267_143_000 picoseconds. + Weight::from_parts(298_166_116, 9409) + // Standard Error: 3_765 + .saturating_add(Weight::from_parts(1_620_886, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -2647,6 +2785,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2660,13 +2800,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_value_transferred(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `877 + r * (6 ±0)` - // Estimated: `6823 + r * (6 ±0)` - // Minimum execution time: 252_325_000 picoseconds. - Weight::from_parts(274_733_944, 6823) - // Standard Error: 603 - .saturating_add(Weight::from_parts(314_467, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `880 + r * (6 ±0)` + // Estimated: `9301 + r * (6 ±0)` + // Minimum execution time: 250_013_000 picoseconds. + Weight::from_parts(281_469_583, 9301) + // Standard Error: 730 + .saturating_add(Weight::from_parts(339_260, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -2674,6 +2814,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2687,13 +2829,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_minimum_balance(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `875 + r * (6 ±0)` - // Estimated: `6816 + r * (6 ±0)` - // Minimum execution time: 250_698_000 picoseconds. - Weight::from_parts(271_707_578, 6816) - // Standard Error: 952 - .saturating_add(Weight::from_parts(318_412, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `878 + r * (6 ±0)` + // Estimated: `9294 + r * (6 ±0)` + // Minimum execution time: 256_219_000 picoseconds. + Weight::from_parts(275_309_266, 9294) + // Standard Error: 1_199 + .saturating_add(Weight::from_parts(350_824, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -2701,6 +2843,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2714,13 +2858,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_block_number(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `872 + r * (6 ±0)` - // Estimated: `6819 + r * (6 ±0)` - // Minimum execution time: 251_854_000 picoseconds. - Weight::from_parts(272_002_212, 6819) - // Standard Error: 622 - .saturating_add(Weight::from_parts(313_353, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `875 + r * (6 ±0)` + // Estimated: `9297 + r * (6 ±0)` + // Minimum execution time: 264_644_000 picoseconds. + Weight::from_parts(283_856_744, 9297) + // Standard Error: 623 + .saturating_add(Weight::from_parts(334_175, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -2728,6 +2872,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2741,13 +2887,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_now(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `863 + r * (6 ±0)` - // Estimated: `6804 + r * (6 ±0)` - // Minimum execution time: 252_010_000 picoseconds. - Weight::from_parts(270_387_000, 6804) - // Standard Error: 659 - .saturating_add(Weight::from_parts(325_856, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `866 + r * (6 ±0)` + // Estimated: `9282 + r * (6 ±0)` + // Minimum execution time: 263_364_000 picoseconds. + Weight::from_parts(281_379_508, 9282) + // Standard Error: 639 + .saturating_add(Weight::from_parts(338_021, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -2755,6 +2901,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2770,13 +2918,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_weight_to_fee(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `937 + r * (14 ±0)` - // Estimated: `6872 + r * (14 ±0)` - // Minimum execution time: 247_933_000 picoseconds. - Weight::from_parts(281_550_162, 6872) - // Standard Error: 660 - .saturating_add(Weight::from_parts(1_090_869, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(9_u64)) + // Measured: `940 + r * (14 ±0)` + // Estimated: `9350 + r * (14 ±0)` + // Minimum execution time: 269_667_000 picoseconds. + Weight::from_parts(284_662_802, 9350) + // Standard Error: 691 + .saturating_add(Weight::from_parts(799_249, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 14).saturating_mul(r.into())) } @@ -2784,6 +2932,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2797,13 +2947,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_input(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `865 + r * (6 ±0)` - // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 251_158_000 picoseconds. - Weight::from_parts(274_623_152, 6807) - // Standard Error: 491 - .saturating_add(Weight::from_parts(263_916, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `868 + r * (6 ±0)` + // Estimated: `9285 + r * (6 ±0)` + // Minimum execution time: 267_018_000 picoseconds. + Weight::from_parts(281_842_630, 9285) + // Standard Error: 453 + .saturating_add(Weight::from_parts(255_373, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) } @@ -2811,6 +2961,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2824,19 +2976,21 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 1048576]`. fn seal_input_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `869` - // Estimated: `6809` - // Minimum execution time: 263_205_000 picoseconds. - Weight::from_parts(216_792_893, 6809) + // Measured: `872` + // Estimated: `9287` + // Minimum execution time: 258_208_000 picoseconds. + Weight::from_parts(227_686_792, 9287) // Standard Error: 23 .saturating_add(Weight::from_parts(989, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2850,11 +3004,11 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1]`. fn seal_return(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `853 + r * (45 ±0)` - // Estimated: `6793 + r * (45 ±0)` - // Minimum execution time: 239_663_000 picoseconds. - Weight::from_parts(266_124_565, 6793) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `856 + r * (45 ±0)` + // Estimated: `9271 + r * (45 ±0)` + // Minimum execution time: 245_714_000 picoseconds. + Weight::from_parts(272_527_059, 9271) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 45).saturating_mul(r.into())) } @@ -2862,6 +3016,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2875,19 +3031,21 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 1048576]`. fn seal_return_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `863` - // Estimated: `6810` - // Minimum execution time: 241_763_000 picoseconds. - Weight::from_parts(266_535_552, 6810) + // Measured: `866` + // Estimated: `9288` + // Minimum execution time: 256_060_000 picoseconds. + Weight::from_parts(276_710_811, 9288) // Standard Error: 0 - .saturating_add(Weight::from_parts(320, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + .saturating_add(Weight::from_parts(312, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:3 w:3) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:1 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:2 w:2) @@ -2901,28 +3059,30 @@ impl WeightInfo for () { /// Storage: `System::EventTopics` (r:4 w:4) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) /// Storage: `Contracts::DeletionQueue` (r:0 w:1) /// Proof: `Contracts::DeletionQueue` (`max_values`: None, `max_size`: Some(142), added: 2617, mode: `Measured`) /// The range of component `r` is `[0, 1]`. fn seal_terminate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2972 + r * (316 ±0)` - // Estimated: `8912 + r * (5266 ±0)` - // Minimum execution time: 265_888_000 picoseconds. - Weight::from_parts(291_232_232, 8912) - // Standard Error: 845_475 - .saturating_add(Weight::from_parts(104_398_867, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) - .saturating_add(RocksDbWeight::get().reads((7_u64).saturating_mul(r.into()))) + // Measured: `2902 + r * (529 ±0)` + // Estimated: `11317 + r * (5479 ±0)` + // Minimum execution time: 270_479_000 picoseconds. + Weight::from_parts(296_706_989, 11317) + // Standard Error: 813_407 + .saturating_add(Weight::from_parts(109_236_910, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) + .saturating_add(RocksDbWeight::get().reads((5_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(RocksDbWeight::get().writes((10_u64).saturating_mul(r.into()))) - .saturating_add(Weight::from_parts(0, 5266).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(0, 5479).saturating_mul(r.into())) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2938,13 +3098,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_random(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `944 + r * (10 ±0)` - // Estimated: `6885 + r * (10 ±0)` - // Minimum execution time: 248_500_000 picoseconds. - Weight::from_parts(282_353_053, 6885) - // Standard Error: 1_144 - .saturating_add(Weight::from_parts(1_193_841, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(9_u64)) + // Measured: `947 + r * (10 ±0)` + // Estimated: `9363 + r * (10 ±0)` + // Minimum execution time: 251_787_000 picoseconds. + Weight::from_parts(284_036_313, 9363) + // Standard Error: 2_560 + .saturating_add(Weight::from_parts(1_238_301, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) } @@ -2952,6 +3112,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2965,13 +3127,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_deposit_event(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `863 + r * (10 ±0)` - // Estimated: `6805 + r * (10 ±0)` - // Minimum execution time: 248_130_000 picoseconds. - Weight::from_parts(279_583_178, 6805) - // Standard Error: 971 - .saturating_add(Weight::from_parts(1_987_941, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `866 + r * (10 ±0)` + // Estimated: `9283 + r * (10 ±0)` + // Minimum execution time: 250_566_000 picoseconds. + Weight::from_parts(275_402_784, 9283) + // Standard Error: 3_939 + .saturating_add(Weight::from_parts(1_941_995, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) } @@ -2979,6 +3141,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2993,15 +3157,15 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 16384]`. fn seal_deposit_event_per_topic_and_byte(t: u32, n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `880 + t * (32 ±0)` - // Estimated: `6825 + t * (2508 ±0)` - // Minimum execution time: 258_594_000 picoseconds. - Weight::from_parts(276_734_422, 6825) - // Standard Error: 102_093 - .saturating_add(Weight::from_parts(2_559_383, 0).saturating_mul(t.into())) + // Measured: `883 + t * (32 ±0)` + // Estimated: `9303 + t * (2508 ±0)` + // Minimum execution time: 267_544_000 picoseconds. + Weight::from_parts(280_117_825, 9303) + // Standard Error: 102_111 + .saturating_add(Weight::from_parts(3_253_038, 0).saturating_mul(t.into())) // Standard Error: 28 - .saturating_add(Weight::from_parts(501, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + .saturating_add(Weight::from_parts(668, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(t.into()))) @@ -3011,6 +3175,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3024,13 +3190,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_debug_message(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `862 + r * (7 ±0)` - // Estimated: `6807 + r * (7 ±0)` - // Minimum execution time: 154_564_000 picoseconds. - Weight::from_parts(168_931_365, 6807) - // Standard Error: 349 - .saturating_add(Weight::from_parts(226_848, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `865 + r * (7 ±0)` + // Estimated: `9285 + r * (7 ±0)` + // Minimum execution time: 157_769_000 picoseconds. + Weight::from_parts(173_026_565, 9285) + // Standard Error: 405 + .saturating_add(Weight::from_parts(219_727, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 7).saturating_mul(r.into())) } @@ -3038,6 +3204,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `MaxEncodedLen`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3051,13 +3219,13 @@ impl WeightInfo for () { /// The range of component `i` is `[0, 1048576]`. fn seal_debug_message_per_byte(i: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `125813` - // Estimated: `131755` - // Minimum execution time: 394_382_000 picoseconds. - Weight::from_parts(376_780_500, 131755) + // Measured: `125816` + // Estimated: `131758` + // Minimum execution time: 403_961_000 picoseconds. + Weight::from_parts(376_480_872, 131758) // Standard Error: 12 - .saturating_add(Weight::from_parts(1_026, 0).saturating_mul(i.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + .saturating_add(Weight::from_parts(1_041, 0).saturating_mul(i.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -3065,13 +3233,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 800]`. fn seal_set_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `924 + r * (292 ±0)` - // Estimated: `926 + r * (293 ±0)` - // Minimum execution time: 249_757_000 picoseconds. - Weight::from_parts(177_324_374, 926) - // Standard Error: 9_512 - .saturating_add(Weight::from_parts(6_176_717, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `927 + r * (292 ±0)` + // Estimated: `929 + r * (293 ±0)` + // Minimum execution time: 256_272_000 picoseconds. + Weight::from_parts(181_058_379, 929) + // Standard Error: 9_838 + .saturating_add(Weight::from_parts(6_316_677, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r.into()))) @@ -3082,13 +3250,13 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 16384]`. fn seal_set_storage_per_new_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1447` - // Estimated: `1430` - // Minimum execution time: 267_564_000 picoseconds. - Weight::from_parts(328_701_080, 1430) - // Standard Error: 61 - .saturating_add(Weight::from_parts(576, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(12_u64)) + // Measured: `1450` + // Estimated: `1433` + // Minimum execution time: 268_713_000 picoseconds. + Weight::from_parts(328_329_131, 1433) + // Standard Error: 66 + .saturating_add(Weight::from_parts(962, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(15_u64)) .saturating_add(RocksDbWeight::get().writes(8_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -3096,13 +3264,13 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 16384]`. fn seal_set_storage_per_old_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1253 + n * (1 ±0)` - // Estimated: `1253 + n * (1 ±0)` - // Minimum execution time: 266_347_000 picoseconds. - Weight::from_parts(289_824_718, 1253) - // Standard Error: 34 - .saturating_add(Weight::from_parts(184, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(9_u64)) + // Measured: `1256 + n * (1 ±0)` + // Estimated: `1256 + n * (1 ±0)` + // Minimum execution time: 265_683_000 picoseconds. + Weight::from_parts(293_784_477, 1256) + // Standard Error: 31 + .saturating_add(Weight::from_parts(377, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -3111,13 +3279,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 800]`. fn seal_clear_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `921 + r * (288 ±0)` - // Estimated: `927 + r * (289 ±0)` - // Minimum execution time: 247_207_000 picoseconds. - Weight::from_parts(179_856_075, 927) - // Standard Error: 9_383 - .saturating_add(Weight::from_parts(6_053_198, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `924 + r * (288 ±0)` + // Estimated: `930 + r * (289 ±0)` + // Minimum execution time: 269_959_000 picoseconds. + Weight::from_parts(186_065_911, 930) + // Standard Error: 9_679 + .saturating_add(Weight::from_parts(6_286_855, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r.into()))) @@ -3128,13 +3296,11 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 16384]`. fn seal_clear_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1249 + n * (1 ±0)` - // Estimated: `1249 + n * (1 ±0)` - // Minimum execution time: 262_655_000 picoseconds. - Weight::from_parts(289_482_543, 1249) - // Standard Error: 35 - .saturating_add(Weight::from_parts(92, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(9_u64)) + // Measured: `1252 + n * (1 ±0)` + // Estimated: `1252 + n * (1 ±0)` + // Minimum execution time: 265_805_000 picoseconds. + Weight::from_parts(294_633_695, 1252) + .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -3143,13 +3309,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 800]`. fn seal_get_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `921 + r * (296 ±0)` - // Estimated: `923 + r * (297 ±0)` - // Minimum execution time: 247_414_000 picoseconds. - Weight::from_parts(203_317_182, 923) - // Standard Error: 7_191 - .saturating_add(Weight::from_parts(4_925_154, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `924 + r * (296 ±0)` + // Estimated: `926 + r * (297 ±0)` + // Minimum execution time: 264_592_000 picoseconds. + Weight::from_parts(204_670_461, 926) + // Standard Error: 6_869 + .saturating_add(Weight::from_parts(5_137_920, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 297).saturating_mul(r.into())) @@ -3159,13 +3325,13 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 16384]`. fn seal_get_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1265 + n * (1 ±0)` - // Estimated: `1265 + n * (1 ±0)` - // Minimum execution time: 258_910_000 picoseconds. - Weight::from_parts(283_086_514, 1265) - // Standard Error: 39 - .saturating_add(Weight::from_parts(980, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(9_u64)) + // Measured: `1268 + n * (1 ±0)` + // Estimated: `1268 + n * (1 ±0)` + // Minimum execution time: 273_165_000 picoseconds. + Weight::from_parts(297_883_669, 1268) + // Standard Error: 37 + .saturating_add(Weight::from_parts(576, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -3174,13 +3340,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 800]`. fn seal_contains_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `932 + r * (288 ±0)` - // Estimated: `929 + r * (289 ±0)` - // Minimum execution time: 252_410_000 picoseconds. - Weight::from_parts(201_227_879, 929) - // Standard Error: 6_899 - .saturating_add(Weight::from_parts(4_774_983, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `935 + r * (288 ±0)` + // Estimated: `932 + r * (289 ±0)` + // Minimum execution time: 252_257_000 picoseconds. + Weight::from_parts(205_018_595, 932) + // Standard Error: 7_605 + .saturating_add(Weight::from_parts(4_933_378, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 289).saturating_mul(r.into())) @@ -3190,13 +3356,13 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 16384]`. fn seal_contains_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1252 + n * (1 ±0)` - // Estimated: `1252 + n * (1 ±0)` - // Minimum execution time: 259_053_000 picoseconds. - Weight::from_parts(283_392_084, 1252) - // Standard Error: 41 - .saturating_add(Weight::from_parts(213, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(9_u64)) + // Measured: `1255 + n * (1 ±0)` + // Estimated: `1255 + n * (1 ±0)` + // Minimum execution time: 266_839_000 picoseconds. + Weight::from_parts(292_064_487, 1255) + // Standard Error: 34 + .saturating_add(Weight::from_parts(194, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -3205,13 +3371,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 800]`. fn seal_take_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `914 + r * (296 ±0)` - // Estimated: `919 + r * (297 ±0)` - // Minimum execution time: 251_371_000 picoseconds. - Weight::from_parts(177_119_717, 919) - // Standard Error: 9_421 - .saturating_add(Weight::from_parts(6_226_005, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `917 + r * (296 ±0)` + // Estimated: `922 + r * (297 ±0)` + // Minimum execution time: 266_072_000 picoseconds. + Weight::from_parts(189_018_352, 922) + // Standard Error: 9_530 + .saturating_add(Weight::from_parts(6_481_011, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r.into()))) @@ -3222,13 +3388,13 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 16384]`. fn seal_take_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1266 + n * (1 ±0)` - // Estimated: `1266 + n * (1 ±0)` - // Minimum execution time: 263_350_000 picoseconds. - Weight::from_parts(284_323_917, 1266) - // Standard Error: 31 - .saturating_add(Weight::from_parts(921, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(9_u64)) + // Measured: `1269 + n * (1 ±0)` + // Estimated: `1269 + n * (1 ±0)` + // Minimum execution time: 270_703_000 picoseconds. + Weight::from_parts(292_867_105, 1269) + // Standard Error: 30 + .saturating_add(Weight::from_parts(800, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -3236,6 +3402,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1602 w:1601) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3249,13 +3417,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_transfer(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1415 + r * (45 ±0)` - // Estimated: `7307 + r * (2520 ±0)` - // Minimum execution time: 248_701_000 picoseconds. - Weight::from_parts(17_811_969, 7307) - // Standard Error: 35_154 - .saturating_add(Weight::from_parts(31_809_738, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(9_u64)) + // Measured: `1418 + r * (45 ±0)` + // Estimated: `9785 + r * (2520 ±0)` + // Minimum execution time: 251_843_000 picoseconds. + Weight::from_parts(181_026_888, 9785) + // Standard Error: 38_221 + .saturating_add(Weight::from_parts(30_626_681, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r.into()))) @@ -3265,6 +3433,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:801 w:801) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:2 w:0) @@ -3278,13 +3448,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 800]`. fn seal_call(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1260 + r * (245 ±0)` - // Estimated: `9440 + r * (2721 ±0)` - // Minimum execution time: 247_335_000 picoseconds. - Weight::from_parts(264_025_000, 9440) - // Standard Error: 121_299 - .saturating_add(Weight::from_parts(234_770_827, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(11_u64)) + // Measured: `1263 + r * (245 ±0)` + // Estimated: `9635 + r * (2721 ±0)` + // Minimum execution time: 254_881_000 picoseconds. + Weight::from_parts(272_871_000, 9635) + // Standard Error: 94_527 + .saturating_add(Weight::from_parts(233_379_497, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(14_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(RocksDbWeight::get().writes((2_u64).saturating_mul(r.into()))) @@ -3294,6 +3464,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:736 w:0) @@ -3308,12 +3480,12 @@ impl WeightInfo for () { fn seal_delegate_call(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + r * (576 ±0)` - // Estimated: `6812 + r * (2637 ±3)` - // Minimum execution time: 261_011_000 picoseconds. - Weight::from_parts(264_554_000, 6812) - // Standard Error: 104_415 - .saturating_add(Weight::from_parts(231_627_084, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Estimated: `9290 + r * (2637 ±3)` + // Minimum execution time: 266_704_000 picoseconds. + Weight::from_parts(273_165_000, 9290) + // Standard Error: 141_486 + .saturating_add(Weight::from_parts(232_947_049, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r.into()))) @@ -3323,6 +3495,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:3 w:2) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:2 w:2) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:2 w:0) @@ -3337,15 +3511,15 @@ impl WeightInfo for () { /// The range of component `c` is `[0, 1048576]`. fn seal_call_per_transfer_clone_byte(t: u32, c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1307 + t * (277 ±0)` - // Estimated: `12197 + t * (5227 ±0)` - // Minimum execution time: 445_561_000 picoseconds. - Weight::from_parts(62_287_490, 12197) - // Standard Error: 11_797_697 - .saturating_add(Weight::from_parts(357_530_529, 0).saturating_mul(t.into())) + // Measured: `1310 + t * (277 ±0)` + // Estimated: `12200 + t * (5227 ±0)` + // Minimum execution time: 446_451_000 picoseconds. + Weight::from_parts(68_175_222, 12200) + // Standard Error: 11_619_250 + .saturating_add(Weight::from_parts(354_237_260, 0).saturating_mul(t.into())) // Standard Error: 17 - .saturating_add(Weight::from_parts(970, 0).saturating_mul(c.into())) - .saturating_add(RocksDbWeight::get().reads(13_u64)) + .saturating_add(Weight::from_parts(987, 0).saturating_mul(c.into())) + .saturating_add(RocksDbWeight::get().reads(16_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(6_u64)) .saturating_add(RocksDbWeight::get().writes((2_u64).saturating_mul(t.into()))) @@ -3355,6 +3529,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:802 w:802) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:801 w:801) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:801 w:800) @@ -3368,17 +3544,17 @@ impl WeightInfo for () { /// Storage: `System::EventTopics` (r:803 w:803) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:800 w:800) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) /// The range of component `r` is `[1, 800]`. fn seal_instantiate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1278 + r * (255 ±0)` - // Estimated: `9620 + r * (2731 ±0)` - // Minimum execution time: 621_897_000 picoseconds. - Weight::from_parts(631_687_000, 9620) - // Standard Error: 215_241 - .saturating_add(Weight::from_parts(350_527_831, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(11_u64)) + // Measured: `1281 + r * (255 ±0)` + // Estimated: `9623 + r * (2731 ±0)` + // Minimum execution time: 628_156_000 picoseconds. + Weight::from_parts(642_052_000, 9623) + // Standard Error: 223_957 + .saturating_add(Weight::from_parts(348_660_264, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(14_u64)) .saturating_add(RocksDbWeight::get().reads((6_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(7_u64)) .saturating_add(RocksDbWeight::get().writes((5_u64).saturating_mul(r.into()))) @@ -3388,6 +3564,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:3 w:3) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:2 w:2) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:2 w:1) @@ -3401,23 +3579,23 @@ impl WeightInfo for () { /// Storage: `System::EventTopics` (r:4 w:4) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) /// The range of component `t` is `[0, 1]`. /// The range of component `i` is `[0, 983040]`. /// The range of component `s` is `[0, 983040]`. fn seal_instantiate_per_transfer_input_salt_byte(t: u32, i: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1303 + t * (104 ±0)` - // Estimated: `12211 + t * (2549 ±1)` - // Minimum execution time: 2_181_184_000 picoseconds. - Weight::from_parts(1_194_190_111, 12211) - // Standard Error: 11_578_766 - .saturating_add(Weight::from_parts(6_361_884, 0).saturating_mul(t.into())) - // Standard Error: 18 - .saturating_add(Weight::from_parts(1_025, 0).saturating_mul(i.into())) - // Standard Error: 18 - .saturating_add(Weight::from_parts(1_158, 0).saturating_mul(s.into())) - .saturating_add(RocksDbWeight::get().reads(16_u64)) + // Measured: `1306 + t * (104 ±0)` + // Estimated: `12214 + t * (2549 ±1)` + // Minimum execution time: 2_106_379_000 picoseconds. + Weight::from_parts(1_098_227_098, 12214) + // Standard Error: 12_549_729 + .saturating_add(Weight::from_parts(21_628_382, 0).saturating_mul(t.into())) + // Standard Error: 19 + .saturating_add(Weight::from_parts(1_059, 0).saturating_mul(i.into())) + // Standard Error: 19 + .saturating_add(Weight::from_parts(1_220, 0).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(19_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(11_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(t.into()))) @@ -3427,6 +3605,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3440,13 +3620,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_hash_sha2_256(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `862 + r * (8 ±0)` - // Estimated: `6801 + r * (8 ±0)` - // Minimum execution time: 241_609_000 picoseconds. - Weight::from_parts(268_716_874, 6801) - // Standard Error: 617 - .saturating_add(Weight::from_parts(377_753, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `865 + r * (8 ±0)` + // Estimated: `9279 + r * (8 ±0)` + // Minimum execution time: 257_102_000 picoseconds. + Weight::from_parts(278_920_692, 9279) + // Standard Error: 464 + .saturating_add(Weight::from_parts(374_120, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) } @@ -3454,6 +3634,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3467,19 +3649,21 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 1048576]`. fn seal_hash_sha2_256_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `870` - // Estimated: `6808` - // Minimum execution time: 261_296_000 picoseconds. - Weight::from_parts(255_531_654, 6808) + // Measured: `873` + // Estimated: `9286` + // Minimum execution time: 266_609_000 picoseconds. + Weight::from_parts(263_034_132, 9286) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_081, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + .saturating_add(Weight::from_parts(1_082, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3493,13 +3677,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_hash_keccak_256(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `864 + r * (8 ±0)` - // Estimated: `6806 + r * (8 ±0)` - // Minimum execution time: 243_583_000 picoseconds. - Weight::from_parts(270_025_058, 6806) - // Standard Error: 560 - .saturating_add(Weight::from_parts(767_519, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `867 + r * (8 ±0)` + // Estimated: `9284 + r * (8 ±0)` + // Minimum execution time: 246_275_000 picoseconds. + Weight::from_parts(279_091_594, 9284) + // Standard Error: 887 + .saturating_add(Weight::from_parts(810_394, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) } @@ -3507,6 +3691,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3520,19 +3706,21 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 1048576]`. fn seal_hash_keccak_256_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `872` - // Estimated: `6814` - // Minimum execution time: 253_798_000 picoseconds. - Weight::from_parts(265_542_351, 6814) + // Measured: `875` + // Estimated: `9292` + // Minimum execution time: 249_254_000 picoseconds. + Weight::from_parts(270_833_823, 9292) // Standard Error: 0 - .saturating_add(Weight::from_parts(3_343, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + .saturating_add(Weight::from_parts(3_347, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3546,13 +3734,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_hash_blake2_256(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `864 + r * (8 ±0)` - // Estimated: `6808 + r * (8 ±0)` - // Minimum execution time: 247_332_000 picoseconds. - Weight::from_parts(269_183_656, 6808) - // Standard Error: 665 - .saturating_add(Weight::from_parts(443_386, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `867 + r * (8 ±0)` + // Estimated: `9286 + r * (8 ±0)` + // Minimum execution time: 259_131_000 picoseconds. + Weight::from_parts(272_665_020, 9286) + // Standard Error: 862 + .saturating_add(Weight::from_parts(451_247, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) } @@ -3560,6 +3748,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3573,19 +3763,21 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 1048576]`. fn seal_hash_blake2_256_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `872` - // Estimated: `6813` - // Minimum execution time: 250_855_000 picoseconds. - Weight::from_parts(258_752_975, 6813) + // Measured: `875` + // Estimated: `9291` + // Minimum execution time: 276_465_000 picoseconds. + Weight::from_parts(269_450_297, 9291) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_202, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + .saturating_add(Weight::from_parts(1_190, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3599,13 +3791,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_hash_blake2_128(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `864 + r * (8 ±0)` - // Estimated: `6805 + r * (8 ±0)` - // Minimum execution time: 240_733_000 picoseconds. - Weight::from_parts(269_134_358, 6805) - // Standard Error: 512 - .saturating_add(Weight::from_parts(440_043, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `867 + r * (8 ±0)` + // Estimated: `9283 + r * (8 ±0)` + // Minimum execution time: 248_349_000 picoseconds. + Weight::from_parts(273_660_686, 9283) + // Standard Error: 656 + .saturating_add(Weight::from_parts(444_293, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) } @@ -3613,6 +3805,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3626,19 +3820,21 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 1048576]`. fn seal_hash_blake2_128_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `872` - // Estimated: `6811` - // Minimum execution time: 247_377_000 picoseconds. - Weight::from_parts(261_077_322, 6811) - // Standard Error: 0 - .saturating_add(Weight::from_parts(1_195, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `875` + // Estimated: `9289` + // Minimum execution time: 252_107_000 picoseconds. + Weight::from_parts(267_427_726, 9289) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_199, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3652,13 +3848,13 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 125697]`. fn seal_sr25519_verify_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `997 + n * (1 ±0)` - // Estimated: `6934 + n * (1 ±0)` - // Minimum execution time: 307_337_000 picoseconds. - Weight::from_parts(326_710_473, 6934) - // Standard Error: 9 - .saturating_add(Weight::from_parts(5_765, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `1000 + n * (1 ±0)` + // Estimated: `9412 + n * (1 ±0)` + // Minimum execution time: 311_252_000 picoseconds. + Weight::from_parts(333_250_773, 9412) + // Standard Error: 12 + .saturating_add(Weight::from_parts(5_668, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -3666,6 +3862,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3679,13 +3877,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 160]`. fn seal_sr25519_verify(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `805 + r * (112 ±0)` - // Estimated: `6748 + r * (112 ±0)` - // Minimum execution time: 245_432_000 picoseconds. - Weight::from_parts(294_206_377, 6748) - // Standard Error: 7_229 - .saturating_add(Weight::from_parts(41_480_485, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `810 + r * (112 ±0)` + // Estimated: `9226 + r * (112 ±0)` + // Minimum execution time: 267_431_000 picoseconds. + Weight::from_parts(300_733_048, 9226) + // Standard Error: 8_806 + .saturating_add(Weight::from_parts(42_169_197, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(r.into())) } @@ -3693,6 +3891,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3706,13 +3906,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 160]`. fn seal_ecdsa_recover(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `907 + r * (76 ±0)` - // Estimated: `6802 + r * (77 ±0)` - // Minimum execution time: 247_788_000 picoseconds. - Weight::from_parts(303_940_062, 6802) - // Standard Error: 10_671 - .saturating_add(Weight::from_parts(45_730_772, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `910 + r * (76 ±0)` + // Estimated: `9279 + r * (77 ±0)` + // Minimum execution time: 265_905_000 picoseconds. + Weight::from_parts(305_381_951, 9279) + // Standard Error: 9_863 + .saturating_add(Weight::from_parts(45_771_182, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 77).saturating_mul(r.into())) } @@ -3720,6 +3920,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3733,13 +3935,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 160]`. fn seal_ecdsa_to_eth_address(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `877 + r * (42 ±0)` - // Estimated: `6816 + r * (42 ±0)` - // Minimum execution time: 248_825_000 picoseconds. - Weight::from_parts(286_832_225, 6816) - // Standard Error: 5_274 - .saturating_add(Weight::from_parts(11_889_262, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `880 + r * (42 ±0)` + // Estimated: `9294 + r * (42 ±0)` + // Minimum execution time: 266_701_000 picoseconds. + Weight::from_parts(292_407_888, 9294) + // Standard Error: 5_394 + .saturating_add(Weight::from_parts(11_896_065, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 42).saturating_mul(r.into())) } @@ -3747,6 +3949,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1536 w:1536) @@ -3761,12 +3965,12 @@ impl WeightInfo for () { fn seal_set_code_hash(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + r * (965 ±0)` - // Estimated: `6807 + r * (3090 ±7)` - // Minimum execution time: 244_982_000 picoseconds. - Weight::from_parts(265_297_000, 6807) - // Standard Error: 39_895 - .saturating_add(Weight::from_parts(22_435_888, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Estimated: `9285 + r * (3090 ±7)` + // Minimum execution time: 268_755_000 picoseconds. + Weight::from_parts(272_300_000, 9285) + // Standard Error: 43_747 + .saturating_add(Weight::from_parts(25_001_889, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(RocksDbWeight::get().writes((2_u64).saturating_mul(r.into()))) @@ -3776,6 +3980,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:33 w:32) @@ -3789,22 +3995,24 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 32]`. fn lock_delegate_dependency(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `928 + r * (131 ±0)` - // Estimated: `6878 + r * (2606 ±0)` - // Minimum execution time: 246_455_000 picoseconds. - Weight::from_parts(275_334_919, 6878) - // Standard Error: 20_911 - .saturating_add(Weight::from_parts(6_427_525, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `937 + r * (131 ±0)` + // Estimated: `9346 + r * (2607 ±0)` + // Minimum execution time: 255_190_000 picoseconds. + Weight::from_parts(285_643_922, 9346) + // Standard Error: 23_582 + .saturating_add(Weight::from_parts(6_289_940, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r.into()))) - .saturating_add(Weight::from_parts(0, 2606).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(0, 2607).saturating_mul(r.into())) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `MaxEncodedLen`) /// Storage: `Contracts::CodeInfoOf` (r:33 w:32) @@ -3818,13 +4026,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 32]`. fn unlock_delegate_dependency(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `969 + r * (183 ±0)` + // Measured: `972 + r * (184 ±0)` // Estimated: `129453 + r * (2568 ±0)` - // Minimum execution time: 254_472_000 picoseconds. - Weight::from_parts(280_657_909, 129453) - // Standard Error: 20_131 - .saturating_add(Weight::from_parts(5_644_006, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Minimum execution time: 260_061_000 picoseconds. + Weight::from_parts(286_849_343, 129453) + // Standard Error: 22_406 + .saturating_add(Weight::from_parts(5_661_459, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r.into()))) @@ -3834,6 +4042,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3847,13 +4057,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_reentrance_count(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `858 + r * (3 ±0)` - // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 250_535_000 picoseconds. - Weight::from_parts(270_318_376, 6804) - // Standard Error: 386 - .saturating_add(Weight::from_parts(174_627, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `861 + r * (3 ±0)` + // Estimated: `9282 + r * (3 ±0)` + // Minimum execution time: 250_922_000 picoseconds. + Weight::from_parts(277_294_913, 9282) + // Standard Error: 391 + .saturating_add(Weight::from_parts(169_457, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) } @@ -3861,6 +4071,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3874,13 +4086,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_account_reentrance_count(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2109 + r * (39 ±0)` - // Estimated: `7899 + r * (40 ±0)` - // Minimum execution time: 248_174_000 picoseconds. - Weight::from_parts(301_826_520, 7899) - // Standard Error: 801 - .saturating_add(Weight::from_parts(248_479, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `2112 + r * (39 ±0)` + // Estimated: `10377 + r * (40 ±0)` + // Minimum execution time: 267_293_000 picoseconds. + Weight::from_parts(309_125_635, 10377) + // Standard Error: 637 + .saturating_add(Weight::from_parts(245_508, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) } @@ -3888,6 +4100,8 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:3 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3903,13 +4117,13 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 1600]`. fn seal_instantiation_nonce(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `861 + r * (3 ±0)` - // Estimated: `6801 + r * (3 ±0)` - // Minimum execution time: 246_540_000 picoseconds. - Weight::from_parts(268_913_509, 6801) - // Standard Error: 378 - .saturating_add(Weight::from_parts(154_950, 0).saturating_mul(r.into())) - .saturating_add(RocksDbWeight::get().reads(9_u64)) + // Measured: `864 + r * (3 ±0)` + // Estimated: `9279 + r * (3 ±0)` + // Minimum execution time: 256_057_000 picoseconds. + Weight::from_parts(278_068_870, 9279) + // Standard Error: 335 + .saturating_add(Weight::from_parts(152_083, 0).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) } @@ -3918,9 +4132,9 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_777_000 picoseconds. - Weight::from_parts(1_707_601, 0) - // Standard Error: 14 - .saturating_add(Weight::from_parts(15_392, 0).saturating_mul(r.into())) + // Minimum execution time: 1_846_000 picoseconds. + Weight::from_parts(1_808_029, 0) + // Standard Error: 9 + .saturating_add(Weight::from_parts(14_937, 0).saturating_mul(r.into())) } } diff --git a/substrate/frame/conviction-voting/src/weights.rs b/substrate/frame/conviction-voting/src/weights.rs index 225f5c2cadd..75d9e8499ed 100644 --- a/substrate/frame/conviction-voting/src/weights.rs +++ b/substrate/frame/conviction-voting/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_conviction_voting +//! Autogenerated weights for `pallet_conviction_voting` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/conviction-voting/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/conviction-voting/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_conviction_voting. +/// Weight functions needed for `pallet_conviction_voting`. pub trait WeightInfo { fn vote_new() -> Weight; fn vote_existing() -> Weight; @@ -61,280 +60,300 @@ pub trait WeightInfo { fn unlock() -> Weight; } -/// Weights for pallet_conviction_voting using the Substrate node and recommended hardware. +/// Weights for `pallet_conviction_voting` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: ConvictionVoting VotingFor (r:1 w:1) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) - /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(59), added: 2534, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) + /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(59), added: 2534, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn vote_new() -> Weight { // Proof Size summary in bytes: - // Measured: `13074` + // Measured: `13141` // Estimated: `219984` - // Minimum execution time: 112_936_000 picoseconds. - Weight::from_parts(116_972_000, 219984) + // Minimum execution time: 102_539_000 picoseconds. + Weight::from_parts(105_873_000, 219984) .saturating_add(T::DbWeight::get().reads(7_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) + .saturating_add(T::DbWeight::get().writes(7_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: ConvictionVoting VotingFor (r:1 w:1) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) - /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(59), added: 2534, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) + /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(59), added: 2534, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn vote_existing() -> Weight { // Proof Size summary in bytes: - // Measured: `20216` + // Measured: `20283` // Estimated: `219984` - // Minimum execution time: 291_971_000 picoseconds. - Weight::from_parts(301_738_000, 219984) + // Minimum execution time: 275_424_000 picoseconds. + Weight::from_parts(283_690_000, 219984) .saturating_add(T::DbWeight::get().reads(7_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) + .saturating_add(T::DbWeight::get().writes(7_u64)) } - /// Storage: ConvictionVoting VotingFor (r:1 w:1) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn remove_vote() -> Weight { // Proof Size summary in bytes: - // Measured: `19968` + // Measured: `20035` // Estimated: `219984` - // Minimum execution time: 262_582_000 picoseconds. - Weight::from_parts(270_955_000, 219984) + // Minimum execution time: 275_109_000 picoseconds. + Weight::from_parts(281_315_000, 219984) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: ConvictionVoting VotingFor (r:1 w:1) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: Referenda ReferendumInfoFor (r:1 w:0) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) fn remove_other_vote() -> Weight { // Proof Size summary in bytes: - // Measured: `12675` + // Measured: `12742` // Estimated: `30706` - // Minimum execution time: 52_909_000 picoseconds. - Weight::from_parts(56_365_000, 30706) + // Minimum execution time: 49_629_000 picoseconds. + Weight::from_parts(51_300_000, 30706) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: ConvictionVoting VotingFor (r:2 w:2) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) - /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) - /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(59), added: 2534, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `ConvictionVoting::VotingFor` (r:2 w:2) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) + /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(59), added: 2534, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 1]`. fn delegate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `240 + r * (1627 ±0)` + // Measured: `306 + r * (1628 ±0)` // Estimated: `109992 + r * (109992 ±0)` - // Minimum execution time: 54_640_000 picoseconds. - Weight::from_parts(57_185_281, 109992) - // Standard Error: 193_362 - .saturating_add(Weight::from_parts(44_897_418, 0).saturating_mul(r.into())) + // Minimum execution time: 45_776_000 picoseconds. + Weight::from_parts(47_917_822, 109992) + // Standard Error: 124_174 + .saturating_add(Weight::from_parts(43_171_077, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) - .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes((4_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 109992).saturating_mul(r.into())) } - /// Storage: ConvictionVoting VotingFor (r:2 w:2) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `ConvictionVoting::VotingFor` (r:2 w:2) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 1]`. fn undelegate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `406 + r * (1376 ±0)` + // Measured: `472 + r * (1377 ±0)` // Estimated: `109992 + r * (109992 ±0)` - // Minimum execution time: 26_514_000 picoseconds. - Weight::from_parts(28_083_732, 109992) - // Standard Error: 104_905 - .saturating_add(Weight::from_parts(40_722_467, 0).saturating_mul(r.into())) + // Minimum execution time: 23_600_000 picoseconds. + Weight::from_parts(25_001_426, 109992) + // Standard Error: 72_034 + .saturating_add(Weight::from_parts(37_851_873, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(2_u64)) - .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes((4_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 109992).saturating_mul(r.into())) } - /// Storage: ConvictionVoting VotingFor (r:1 w:1) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) - /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(59), added: 2534, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) + /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(59), added: 2534, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) fn unlock() -> Weight { // Proof Size summary in bytes: - // Measured: `11734` + // Measured: `11800` // Estimated: `30706` - // Minimum execution time: 71_140_000 picoseconds. - Weight::from_parts(77_388_000, 30706) + // Minimum execution time: 66_247_000 picoseconds. + Weight::from_parts(67_552_000, 30706) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: ConvictionVoting VotingFor (r:1 w:1) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) - /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(59), added: 2534, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) + /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(59), added: 2534, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn vote_new() -> Weight { // Proof Size summary in bytes: - // Measured: `13074` + // Measured: `13141` // Estimated: `219984` - // Minimum execution time: 112_936_000 picoseconds. - Weight::from_parts(116_972_000, 219984) + // Minimum execution time: 102_539_000 picoseconds. + Weight::from_parts(105_873_000, 219984) .saturating_add(RocksDbWeight::get().reads(7_u64)) - .saturating_add(RocksDbWeight::get().writes(6_u64)) + .saturating_add(RocksDbWeight::get().writes(7_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: ConvictionVoting VotingFor (r:1 w:1) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) - /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(59), added: 2534, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) + /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(59), added: 2534, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn vote_existing() -> Weight { // Proof Size summary in bytes: - // Measured: `20216` + // Measured: `20283` // Estimated: `219984` - // Minimum execution time: 291_971_000 picoseconds. - Weight::from_parts(301_738_000, 219984) + // Minimum execution time: 275_424_000 picoseconds. + Weight::from_parts(283_690_000, 219984) .saturating_add(RocksDbWeight::get().reads(7_u64)) - .saturating_add(RocksDbWeight::get().writes(6_u64)) + .saturating_add(RocksDbWeight::get().writes(7_u64)) } - /// Storage: ConvictionVoting VotingFor (r:1 w:1) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn remove_vote() -> Weight { // Proof Size summary in bytes: - // Measured: `19968` + // Measured: `20035` // Estimated: `219984` - // Minimum execution time: 262_582_000 picoseconds. - Weight::from_parts(270_955_000, 219984) + // Minimum execution time: 275_109_000 picoseconds. + Weight::from_parts(281_315_000, 219984) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(4_u64)) + .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: ConvictionVoting VotingFor (r:1 w:1) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: Referenda ReferendumInfoFor (r:1 w:0) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) fn remove_other_vote() -> Weight { // Proof Size summary in bytes: - // Measured: `12675` + // Measured: `12742` // Estimated: `30706` - // Minimum execution time: 52_909_000 picoseconds. - Weight::from_parts(56_365_000, 30706) + // Minimum execution time: 49_629_000 picoseconds. + Weight::from_parts(51_300_000, 30706) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: ConvictionVoting VotingFor (r:2 w:2) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) - /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) - /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(59), added: 2534, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `ConvictionVoting::VotingFor` (r:2 w:2) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) + /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(59), added: 2534, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 1]`. fn delegate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `240 + r * (1627 ±0)` + // Measured: `306 + r * (1628 ±0)` // Estimated: `109992 + r * (109992 ±0)` - // Minimum execution time: 54_640_000 picoseconds. - Weight::from_parts(57_185_281, 109992) - // Standard Error: 193_362 - .saturating_add(Weight::from_parts(44_897_418, 0).saturating_mul(r.into())) + // Minimum execution time: 45_776_000 picoseconds. + Weight::from_parts(47_917_822, 109992) + // Standard Error: 124_174 + .saturating_add(Weight::from_parts(43_171_077, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) - .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(r.into()))) + .saturating_add(RocksDbWeight::get().writes((4_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 109992).saturating_mul(r.into())) } - /// Storage: ConvictionVoting VotingFor (r:2 w:2) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `ConvictionVoting::VotingFor` (r:2 w:2) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 1]`. fn undelegate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `406 + r * (1376 ±0)` + // Measured: `472 + r * (1377 ±0)` // Estimated: `109992 + r * (109992 ±0)` - // Minimum execution time: 26_514_000 picoseconds. - Weight::from_parts(28_083_732, 109992) - // Standard Error: 104_905 - .saturating_add(Weight::from_parts(40_722_467, 0).saturating_mul(r.into())) + // Minimum execution time: 23_600_000 picoseconds. + Weight::from_parts(25_001_426, 109992) + // Standard Error: 72_034 + .saturating_add(Weight::from_parts(37_851_873, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(2_u64)) - .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(r.into()))) + .saturating_add(RocksDbWeight::get().writes((4_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 109992).saturating_mul(r.into())) } - /// Storage: ConvictionVoting VotingFor (r:1 w:1) - /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) - /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) - /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(59), added: 2534, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) + /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) + /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) + /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(59), added: 2534, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) fn unlock() -> Weight { // Proof Size summary in bytes: - // Measured: `11734` + // Measured: `11800` // Estimated: `30706` - // Minimum execution time: 71_140_000 picoseconds. - Weight::from_parts(77_388_000, 30706) + // Minimum execution time: 66_247_000 picoseconds. + Weight::from_parts(67_552_000, 30706) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } diff --git a/substrate/frame/core-fellowship/src/weights.rs b/substrate/frame/core-fellowship/src/weights.rs index 8bbfd1a4dd8..fce1d3747a8 100644 --- a/substrate/frame/core-fellowship/src/weights.rs +++ b/substrate/frame/core-fellowship/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_core_fellowship +//! Autogenerated weights for `pallet_core_fellowship` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/core-fellowship/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/core-fellowship/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_core_fellowship. +/// Weight functions needed for `pallet_core_fellowship`. pub trait WeightInfo { fn set_params() -> Weight; fn bump_offboard() -> Weight; @@ -64,336 +63,344 @@ pub trait WeightInfo { fn submit_evidence() -> Weight; } -/// Weights for pallet_core_fellowship using the Substrate node and recommended hardware. +/// Weights for `pallet_core_fellowship` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: CoreFellowship Params (r:0 w:1) - /// Proof: CoreFellowship Params (max_values: Some(1), max_size: Some(364), added: 859, mode: MaxEncodedLen) + /// Storage: `CoreFellowship::Params` (r:0 w:1) + /// Proof: `CoreFellowship::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) fn set_params() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_454_000 picoseconds. - Weight::from_parts(9_804_000, 0) + // Minimum execution time: 7_146_000 picoseconds. + Weight::from_parts(7_426_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: CoreFellowship Member (r:1 w:1) - /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: RankedCollective Members (r:1 w:1) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: CoreFellowship Params (r:1 w:0) - /// Proof: CoreFellowship Params (max_values: Some(1), max_size: Some(364), added: 859, mode: MaxEncodedLen) - /// Storage: RankedCollective MemberCount (r:1 w:1) - /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: RankedCollective IdToIndex (r:1 w:0) - /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) - /// Storage: CoreFellowship MemberEvidence (r:1 w:1) - /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) + /// Storage: `CoreFellowship::Member` (r:1 w:1) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::Members` (r:1 w:1) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::Params` (r:1 w:0) + /// Proof: `CoreFellowship::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::MemberCount` (r:1 w:1) + /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IdToIndex` (r:1 w:1) + /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) + /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IndexToId` (r:0 w:1) + /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn bump_offboard() -> Weight { // Proof Size summary in bytes: - // Measured: `16887` + // Measured: `17274` // Estimated: `19894` - // Minimum execution time: 58_489_000 picoseconds. - Weight::from_parts(60_202_000, 19894) + // Minimum execution time: 54_511_000 picoseconds. + Weight::from_parts(56_995_000, 19894) .saturating_add(T::DbWeight::get().reads(6_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) + .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: CoreFellowship Member (r:1 w:1) - /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: RankedCollective Members (r:1 w:1) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: CoreFellowship Params (r:1 w:0) - /// Proof: CoreFellowship Params (max_values: Some(1), max_size: Some(364), added: 859, mode: MaxEncodedLen) - /// Storage: RankedCollective MemberCount (r:1 w:1) - /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: RankedCollective IdToIndex (r:1 w:0) - /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) - /// Storage: CoreFellowship MemberEvidence (r:1 w:1) - /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) + /// Storage: `CoreFellowship::Member` (r:1 w:1) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::Members` (r:1 w:1) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::Params` (r:1 w:0) + /// Proof: `CoreFellowship::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::MemberCount` (r:1 w:1) + /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IdToIndex` (r:1 w:1) + /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) + /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IndexToId` (r:0 w:1) + /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn bump_demote() -> Weight { // Proof Size summary in bytes: - // Measured: `16997` + // Measured: `17384` // Estimated: `19894` - // Minimum execution time: 60_605_000 picoseconds. - Weight::from_parts(63_957_000, 19894) + // Minimum execution time: 56_453_000 picoseconds. + Weight::from_parts(59_030_000, 19894) .saturating_add(T::DbWeight::get().reads(6_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) + .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: RankedCollective Members (r:1 w:0) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: CoreFellowship Member (r:1 w:1) - /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:0) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::Member` (r:1 w:1) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) fn set_active() -> Weight { // Proof Size summary in bytes: // Measured: `388` // Estimated: `3514` - // Minimum execution time: 17_816_000 picoseconds. - Weight::from_parts(18_524_000, 3514) + // Minimum execution time: 15_940_000 picoseconds. + Weight::from_parts(16_381_000, 3514) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: CoreFellowship Member (r:1 w:1) - /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: RankedCollective Members (r:1 w:1) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: RankedCollective MemberCount (r:1 w:1) - /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: RankedCollective IndexToId (r:0 w:1) - /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) - /// Storage: RankedCollective IdToIndex (r:0 w:1) - /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: `CoreFellowship::Member` (r:1 w:1) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::Members` (r:1 w:1) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::MemberCount` (r:1 w:1) + /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IndexToId` (r:0 w:1) + /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IdToIndex` (r:0 w:1) + /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn induct() -> Weight { // Proof Size summary in bytes: // Measured: `146` // Estimated: `3514` - // Minimum execution time: 27_249_000 picoseconds. - Weight::from_parts(28_049_000, 3514) + // Minimum execution time: 24_193_000 picoseconds. + Weight::from_parts(24_963_000, 3514) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: RankedCollective Members (r:1 w:1) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: CoreFellowship Member (r:1 w:1) - /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: CoreFellowship Params (r:1 w:0) - /// Proof: CoreFellowship Params (max_values: Some(1), max_size: Some(364), added: 859, mode: MaxEncodedLen) - /// Storage: RankedCollective MemberCount (r:1 w:1) - /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: CoreFellowship MemberEvidence (r:1 w:1) - /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) - /// Storage: RankedCollective IndexToId (r:0 w:1) - /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) - /// Storage: RankedCollective IdToIndex (r:0 w:1) - /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:1) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::Member` (r:1 w:1) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::Params` (r:1 w:0) + /// Proof: `CoreFellowship::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::MemberCount` (r:1 w:1) + /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) + /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IndexToId` (r:0 w:1) + /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IdToIndex` (r:0 w:1) + /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn promote() -> Weight { // Proof Size summary in bytes: // Measured: `16865` // Estimated: `19894` - // Minimum execution time: 56_642_000 picoseconds. - Weight::from_parts(59_353_000, 19894) + // Minimum execution time: 48_138_000 picoseconds. + Weight::from_parts(50_007_000, 19894) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: RankedCollective Members (r:1 w:0) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: CoreFellowship Member (r:1 w:1) - /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: CoreFellowship MemberEvidence (r:0 w:1) - /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:0) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::Member` (r:1 w:1) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::MemberEvidence` (r:0 w:1) + /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) fn offboard() -> Weight { // Proof Size summary in bytes: - // Measured: `359` + // Measured: `293` // Estimated: `3514` - // Minimum execution time: 17_459_000 picoseconds. - Weight::from_parts(18_033_000, 3514) + // Minimum execution time: 15_225_000 picoseconds. + Weight::from_parts(15_730_000, 3514) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: CoreFellowship Member (r:1 w:1) - /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: RankedCollective Members (r:1 w:0) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: `CoreFellowship::Member` (r:1 w:1) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::Members` (r:1 w:0) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) fn import() -> Weight { // Proof Size summary in bytes: // Measured: `313` // Estimated: `3514` - // Minimum execution time: 16_728_000 picoseconds. - Weight::from_parts(17_263_000, 3514) + // Minimum execution time: 14_507_000 picoseconds. + Weight::from_parts(14_935_000, 3514) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: RankedCollective Members (r:1 w:0) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: CoreFellowship Member (r:1 w:1) - /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: CoreFellowship MemberEvidence (r:1 w:1) - /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:0) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::Member` (r:1 w:1) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) + /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) fn approve() -> Weight { // Proof Size summary in bytes: // Measured: `16843` // Estimated: `19894` - // Minimum execution time: 41_487_000 picoseconds. - Weight::from_parts(43_459_000, 19894) + // Minimum execution time: 34_050_000 picoseconds. + Weight::from_parts(36_323_000, 19894) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: CoreFellowship Member (r:1 w:0) - /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: CoreFellowship MemberEvidence (r:1 w:1) - /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) + /// Storage: `CoreFellowship::Member` (r:1 w:0) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) + /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) fn submit_evidence() -> Weight { // Proof Size summary in bytes: // Measured: `79` // Estimated: `19894` - // Minimum execution time: 26_033_000 picoseconds. - Weight::from_parts(26_612_000, 19894) + // Minimum execution time: 24_016_000 picoseconds. + Weight::from_parts(24_607_000, 19894) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: CoreFellowship Params (r:0 w:1) - /// Proof: CoreFellowship Params (max_values: Some(1), max_size: Some(364), added: 859, mode: MaxEncodedLen) + /// Storage: `CoreFellowship::Params` (r:0 w:1) + /// Proof: `CoreFellowship::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) fn set_params() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_454_000 picoseconds. - Weight::from_parts(9_804_000, 0) + // Minimum execution time: 7_146_000 picoseconds. + Weight::from_parts(7_426_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: CoreFellowship Member (r:1 w:1) - /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: RankedCollective Members (r:1 w:1) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: CoreFellowship Params (r:1 w:0) - /// Proof: CoreFellowship Params (max_values: Some(1), max_size: Some(364), added: 859, mode: MaxEncodedLen) - /// Storage: RankedCollective MemberCount (r:1 w:1) - /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: RankedCollective IdToIndex (r:1 w:0) - /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) - /// Storage: CoreFellowship MemberEvidence (r:1 w:1) - /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) + /// Storage: `CoreFellowship::Member` (r:1 w:1) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::Members` (r:1 w:1) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::Params` (r:1 w:0) + /// Proof: `CoreFellowship::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::MemberCount` (r:1 w:1) + /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IdToIndex` (r:1 w:1) + /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) + /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IndexToId` (r:0 w:1) + /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn bump_offboard() -> Weight { // Proof Size summary in bytes: - // Measured: `16887` + // Measured: `17274` // Estimated: `19894` - // Minimum execution time: 58_489_000 picoseconds. - Weight::from_parts(60_202_000, 19894) + // Minimum execution time: 54_511_000 picoseconds. + Weight::from_parts(56_995_000, 19894) .saturating_add(RocksDbWeight::get().reads(6_u64)) - .saturating_add(RocksDbWeight::get().writes(4_u64)) + .saturating_add(RocksDbWeight::get().writes(6_u64)) } - /// Storage: CoreFellowship Member (r:1 w:1) - /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: RankedCollective Members (r:1 w:1) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: CoreFellowship Params (r:1 w:0) - /// Proof: CoreFellowship Params (max_values: Some(1), max_size: Some(364), added: 859, mode: MaxEncodedLen) - /// Storage: RankedCollective MemberCount (r:1 w:1) - /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: RankedCollective IdToIndex (r:1 w:0) - /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) - /// Storage: CoreFellowship MemberEvidence (r:1 w:1) - /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) + /// Storage: `CoreFellowship::Member` (r:1 w:1) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::Members` (r:1 w:1) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::Params` (r:1 w:0) + /// Proof: `CoreFellowship::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::MemberCount` (r:1 w:1) + /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IdToIndex` (r:1 w:1) + /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) + /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IndexToId` (r:0 w:1) + /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn bump_demote() -> Weight { // Proof Size summary in bytes: - // Measured: `16997` + // Measured: `17384` // Estimated: `19894` - // Minimum execution time: 60_605_000 picoseconds. - Weight::from_parts(63_957_000, 19894) + // Minimum execution time: 56_453_000 picoseconds. + Weight::from_parts(59_030_000, 19894) .saturating_add(RocksDbWeight::get().reads(6_u64)) - .saturating_add(RocksDbWeight::get().writes(4_u64)) + .saturating_add(RocksDbWeight::get().writes(6_u64)) } - /// Storage: RankedCollective Members (r:1 w:0) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: CoreFellowship Member (r:1 w:1) - /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:0) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::Member` (r:1 w:1) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) fn set_active() -> Weight { // Proof Size summary in bytes: // Measured: `388` // Estimated: `3514` - // Minimum execution time: 17_816_000 picoseconds. - Weight::from_parts(18_524_000, 3514) + // Minimum execution time: 15_940_000 picoseconds. + Weight::from_parts(16_381_000, 3514) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: CoreFellowship Member (r:1 w:1) - /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: RankedCollective Members (r:1 w:1) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: RankedCollective MemberCount (r:1 w:1) - /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: RankedCollective IndexToId (r:0 w:1) - /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) - /// Storage: RankedCollective IdToIndex (r:0 w:1) - /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: `CoreFellowship::Member` (r:1 w:1) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::Members` (r:1 w:1) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::MemberCount` (r:1 w:1) + /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IndexToId` (r:0 w:1) + /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IdToIndex` (r:0 w:1) + /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn induct() -> Weight { // Proof Size summary in bytes: // Measured: `146` // Estimated: `3514` - // Minimum execution time: 27_249_000 picoseconds. - Weight::from_parts(28_049_000, 3514) + // Minimum execution time: 24_193_000 picoseconds. + Weight::from_parts(24_963_000, 3514) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: RankedCollective Members (r:1 w:1) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: CoreFellowship Member (r:1 w:1) - /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: CoreFellowship Params (r:1 w:0) - /// Proof: CoreFellowship Params (max_values: Some(1), max_size: Some(364), added: 859, mode: MaxEncodedLen) - /// Storage: RankedCollective MemberCount (r:1 w:1) - /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: CoreFellowship MemberEvidence (r:1 w:1) - /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) - /// Storage: RankedCollective IndexToId (r:0 w:1) - /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) - /// Storage: RankedCollective IdToIndex (r:0 w:1) - /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:1) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::Member` (r:1 w:1) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::Params` (r:1 w:0) + /// Proof: `CoreFellowship::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::MemberCount` (r:1 w:1) + /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) + /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IndexToId` (r:0 w:1) + /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IdToIndex` (r:0 w:1) + /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn promote() -> Weight { // Proof Size summary in bytes: // Measured: `16865` // Estimated: `19894` - // Minimum execution time: 56_642_000 picoseconds. - Weight::from_parts(59_353_000, 19894) + // Minimum execution time: 48_138_000 picoseconds. + Weight::from_parts(50_007_000, 19894) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } - /// Storage: RankedCollective Members (r:1 w:0) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: CoreFellowship Member (r:1 w:1) - /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: CoreFellowship MemberEvidence (r:0 w:1) - /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:0) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::Member` (r:1 w:1) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::MemberEvidence` (r:0 w:1) + /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) fn offboard() -> Weight { // Proof Size summary in bytes: - // Measured: `359` + // Measured: `293` // Estimated: `3514` - // Minimum execution time: 17_459_000 picoseconds. - Weight::from_parts(18_033_000, 3514) + // Minimum execution time: 15_225_000 picoseconds. + Weight::from_parts(15_730_000, 3514) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: CoreFellowship Member (r:1 w:1) - /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: RankedCollective Members (r:1 w:0) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: `CoreFellowship::Member` (r:1 w:1) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::Members` (r:1 w:0) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) fn import() -> Weight { // Proof Size summary in bytes: // Measured: `313` // Estimated: `3514` - // Minimum execution time: 16_728_000 picoseconds. - Weight::from_parts(17_263_000, 3514) + // Minimum execution time: 14_507_000 picoseconds. + Weight::from_parts(14_935_000, 3514) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: RankedCollective Members (r:1 w:0) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: CoreFellowship Member (r:1 w:1) - /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: CoreFellowship MemberEvidence (r:1 w:1) - /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:0) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::Member` (r:1 w:1) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) + /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) fn approve() -> Weight { // Proof Size summary in bytes: // Measured: `16843` // Estimated: `19894` - // Minimum execution time: 41_487_000 picoseconds. - Weight::from_parts(43_459_000, 19894) + // Minimum execution time: 34_050_000 picoseconds. + Weight::from_parts(36_323_000, 19894) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: CoreFellowship Member (r:1 w:0) - /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: CoreFellowship MemberEvidence (r:1 w:1) - /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) + /// Storage: `CoreFellowship::Member` (r:1 w:0) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) + /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) fn submit_evidence() -> Weight { // Proof Size summary in bytes: // Measured: `79` // Estimated: `19894` - // Minimum execution time: 26_033_000 picoseconds. - Weight::from_parts(26_612_000, 19894) + // Minimum execution time: 24_016_000 picoseconds. + Weight::from_parts(24_607_000, 19894) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/democracy/src/weights.rs b/substrate/frame/democracy/src/weights.rs index 241f6c3cb38..d6097922a82 100644 --- a/substrate/frame/democracy/src/weights.rs +++ b/substrate/frame/democracy/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_democracy +//! Autogenerated weights for `pallet_democracy` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/democracy/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/democracy/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_democracy. +/// Weight functions needed for `pallet_democracy`. pub trait WeightInfo { fn propose() -> Weight; fn second() -> Weight; @@ -82,904 +81,916 @@ pub trait WeightInfo { fn clear_referendum_metadata() -> Weight; } -/// Weights for pallet_democracy using the Substrate node and recommended hardware. +/// Weights for `pallet_democracy` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Democracy PublicPropCount (r:1 w:1) - /// Proof: Democracy PublicPropCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Democracy PublicProps (r:1 w:1) - /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) - /// Storage: Democracy Blacklist (r:1 w:0) - /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) - /// Storage: Democracy DepositOf (r:0 w:1) - /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + /// Storage: `Democracy::PublicPropCount` (r:1 w:1) + /// Proof: `Democracy::PublicPropCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Democracy::PublicProps` (r:1 w:1) + /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) + /// Storage: `Democracy::Blacklist` (r:1 w:0) + /// Proof: `Democracy::Blacklist` (`max_values`: None, `max_size`: Some(3238), added: 5713, mode: `MaxEncodedLen`) + /// Storage: `Democracy::DepositOf` (r:0 w:1) + /// Proof: `Democracy::DepositOf` (`max_values`: None, `max_size`: Some(3230), added: 5705, mode: `MaxEncodedLen`) fn propose() -> Weight { // Proof Size summary in bytes: - // Measured: `4801` + // Measured: `4834` // Estimated: `18187` - // Minimum execution time: 49_339_000 picoseconds. - Weight::from_parts(50_942_000, 18187) + // Minimum execution time: 39_930_000 picoseconds. + Weight::from_parts(41_746_000, 18187) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Democracy DepositOf (r:1 w:1) - /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + /// Storage: `Democracy::DepositOf` (r:1 w:1) + /// Proof: `Democracy::DepositOf` (`max_values`: None, `max_size`: Some(3230), added: 5705, mode: `MaxEncodedLen`) fn second() -> Weight { // Proof Size summary in bytes: - // Measured: `3556` + // Measured: `3589` // Estimated: `6695` - // Minimum execution time: 43_291_000 picoseconds. - Weight::from_parts(44_856_000, 6695) + // Minimum execution time: 36_490_000 picoseconds. + Weight::from_parts(37_615_000, 6695) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Democracy ReferendumInfoOf (r:1 w:1) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) - /// Storage: Democracy VotingOf (r:1 w:1) - /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: `Democracy::VotingOf` (r:1 w:1) + /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) fn vote_new() -> Weight { // Proof Size summary in bytes: - // Measured: `3470` + // Measured: `3503` // Estimated: `7260` - // Minimum execution time: 61_890_000 picoseconds. - Weight::from_parts(63_626_000, 7260) + // Minimum execution time: 54_257_000 picoseconds. + Weight::from_parts(55_912_000, 7260) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Democracy ReferendumInfoOf (r:1 w:1) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) - /// Storage: Democracy VotingOf (r:1 w:1) - /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: `Democracy::VotingOf` (r:1 w:1) + /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) fn vote_existing() -> Weight { // Proof Size summary in bytes: - // Measured: `3492` + // Measured: `3525` // Estimated: `7260` - // Minimum execution time: 67_802_000 picoseconds. - Weight::from_parts(69_132_000, 7260) + // Minimum execution time: 56_878_000 picoseconds. + Weight::from_parts(58_796_000, 7260) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Democracy ReferendumInfoOf (r:1 w:1) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) - /// Storage: Democracy Cancellations (r:1 w:1) - /// Proof: Democracy Cancellations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:1 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: `Democracy::Cancellations` (r:1 w:1) + /// Proof: `Democracy::Cancellations` (`max_values`: None, `max_size`: Some(33), added: 2508, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:1 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) fn emergency_cancel() -> Weight { // Proof Size summary in bytes: - // Measured: `366` + // Measured: `399` // Estimated: `3666` - // Minimum execution time: 25_757_000 picoseconds. - Weight::from_parts(27_226_000, 3666) + // Minimum execution time: 22_700_000 picoseconds. + Weight::from_parts(23_539_000, 3666) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Democracy PublicProps (r:1 w:1) - /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) - /// Storage: Democracy DepositOf (r:1 w:1) - /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:3 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) - /// Storage: Democracy NextExternal (r:1 w:1) - /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumInfoOf (r:1 w:1) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) - /// Storage: Democracy Blacklist (r:0 w:1) - /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + /// Storage: `Democracy::PublicProps` (r:1 w:1) + /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) + /// Storage: `Democracy::DepositOf` (r:1 w:1) + /// Proof: `Democracy::DepositOf` (`max_values`: None, `max_size`: Some(3230), added: 5705, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:3 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: `Democracy::NextExternal` (r:1 w:1) + /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: `Democracy::Blacklist` (r:0 w:1) + /// Proof: `Democracy::Blacklist` (`max_values`: None, `max_size`: Some(3238), added: 5713, mode: `MaxEncodedLen`) fn blacklist() -> Weight { // Proof Size summary in bytes: - // Measured: `5910` + // Measured: `5943` // Estimated: `18187` - // Minimum execution time: 113_060_000 picoseconds. - Weight::from_parts(114_813_000, 18187) + // Minimum execution time: 95_398_000 picoseconds. + Weight::from_parts(97_261_000, 18187) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } - /// Storage: Democracy NextExternal (r:1 w:1) - /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) - /// Storage: Democracy Blacklist (r:1 w:0) - /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + /// Storage: `Democracy::NextExternal` (r:1 w:1) + /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) + /// Storage: `Democracy::Blacklist` (r:1 w:0) + /// Proof: `Democracy::Blacklist` (`max_values`: None, `max_size`: Some(3238), added: 5713, mode: `MaxEncodedLen`) fn external_propose() -> Weight { // Proof Size summary in bytes: - // Measured: `3416` + // Measured: `3449` // Estimated: `6703` - // Minimum execution time: 13_413_000 picoseconds. - Weight::from_parts(13_794_000, 6703) + // Minimum execution time: 11_745_000 picoseconds. + Weight::from_parts(12_304_000, 6703) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Democracy NextExternal (r:0 w:1) - /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: `Democracy::NextExternal` (r:0 w:1) + /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) fn external_propose_majority() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_213_000 picoseconds. - Weight::from_parts(3_429_000, 0) + // Minimum execution time: 2_710_000 picoseconds. + Weight::from_parts(2_918_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Democracy NextExternal (r:0 w:1) - /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: `Democracy::NextExternal` (r:0 w:1) + /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) fn external_propose_default() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_280_000 picoseconds. - Weight::from_parts(3_389_000, 0) + // Minimum execution time: 2_664_000 picoseconds. + Weight::from_parts(2_776_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Democracy NextExternal (r:1 w:1) - /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumCount (r:1 w:1) - /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:1 w:2) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumInfoOf (r:0 w:1) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: `Democracy::NextExternal` (r:1 w:1) + /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumCount` (r:1 w:1) + /// Proof: `Democracy::ReferendumCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:1 w:2) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumInfoOf` (r:0 w:1) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) fn fast_track() -> Weight { // Proof Size summary in bytes: - // Measured: `286` + // Measured: `319` // Estimated: `3518` - // Minimum execution time: 28_142_000 picoseconds. - Weight::from_parts(28_862_000, 3518) + // Minimum execution time: 22_585_000 picoseconds. + Weight::from_parts(23_689_000, 3518) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: Democracy NextExternal (r:1 w:1) - /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) - /// Storage: Democracy Blacklist (r:1 w:1) - /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:1 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: `Democracy::NextExternal` (r:1 w:1) + /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) + /// Storage: `Democracy::Blacklist` (r:1 w:1) + /// Proof: `Democracy::Blacklist` (`max_values`: None, `max_size`: Some(3238), added: 5713, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:1 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) fn veto_external() -> Weight { // Proof Size summary in bytes: - // Measured: `3519` + // Measured: `3552` // Estimated: `6703` - // Minimum execution time: 32_395_000 picoseconds. - Weight::from_parts(33_617_000, 6703) + // Minimum execution time: 26_391_000 picoseconds. + Weight::from_parts(27_141_000, 6703) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Democracy PublicProps (r:1 w:1) - /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) - /// Storage: Democracy DepositOf (r:1 w:1) - /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:1 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: `Democracy::PublicProps` (r:1 w:1) + /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) + /// Storage: `Democracy::DepositOf` (r:1 w:1) + /// Proof: `Democracy::DepositOf` (`max_values`: None, `max_size`: Some(3230), added: 5705, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:1 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) fn cancel_proposal() -> Weight { // Proof Size summary in bytes: - // Measured: `5821` + // Measured: `5854` // Estimated: `18187` - // Minimum execution time: 92_255_000 picoseconds. - Weight::from_parts(93_704_000, 18187) + // Minimum execution time: 77_905_000 picoseconds. + Weight::from_parts(79_628_000, 18187) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: Democracy MetadataOf (r:1 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumInfoOf (r:0 w:1) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: `Democracy::MetadataOf` (r:1 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumInfoOf` (r:0 w:1) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) fn cancel_referendum() -> Weight { // Proof Size summary in bytes: - // Measured: `271` + // Measured: `304` // Estimated: `3518` - // Minimum execution time: 19_623_000 picoseconds. - Weight::from_parts(20_545_000, 3518) + // Minimum execution time: 15_735_000 picoseconds. + Weight::from_parts(16_525_000, 3518) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Democracy LowestUnbaked (r:1 w:1) - /// Proof: Democracy LowestUnbaked (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumCount (r:1 w:0) - /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumInfoOf (r:99 w:0) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: `Democracy::LowestUnbaked` (r:1 w:1) + /// Proof: `Democracy::LowestUnbaked` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumCount` (r:1 w:0) + /// Proof: `Democracy::ReferendumCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumInfoOf` (r:99 w:0) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 99]`. fn on_initialize_base(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `244 + r * (86 ±0)` + // Measured: `277 + r * (86 ±0)` // Estimated: `1489 + r * (2676 ±0)` - // Minimum execution time: 7_032_000 picoseconds. - Weight::from_parts(7_931_421, 1489) - // Standard Error: 7_395 - .saturating_add(Weight::from_parts(3_236_964, 0).saturating_mul(r.into())) + // Minimum execution time: 5_274_000 picoseconds. + Weight::from_parts(6_162_399, 1489) + // Standard Error: 6_924 + .saturating_add(Weight::from_parts(3_186_702, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) } - /// Storage: Democracy LowestUnbaked (r:1 w:1) - /// Proof: Democracy LowestUnbaked (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumCount (r:1 w:0) - /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Democracy LastTabledWasExternal (r:1 w:0) - /// Proof: Democracy LastTabledWasExternal (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) - /// Storage: Democracy NextExternal (r:1 w:0) - /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) - /// Storage: Democracy PublicProps (r:1 w:0) - /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumInfoOf (r:99 w:0) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: `Democracy::LowestUnbaked` (r:1 w:1) + /// Proof: `Democracy::LowestUnbaked` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumCount` (r:1 w:0) + /// Proof: `Democracy::ReferendumCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Democracy::LastTabledWasExternal` (r:1 w:0) + /// Proof: `Democracy::LastTabledWasExternal` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `Democracy::NextExternal` (r:1 w:0) + /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) + /// Storage: `Democracy::PublicProps` (r:1 w:0) + /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumInfoOf` (r:99 w:0) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 99]`. fn on_initialize_base_with_launch_period(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `244 + r * (86 ±0)` + // Measured: `277 + r * (86 ±0)` // Estimated: `18187 + r * (2676 ±0)` - // Minimum execution time: 10_524_000 picoseconds. - Weight::from_parts(10_369_064, 18187) - // Standard Error: 8_385 - .saturating_add(Weight::from_parts(3_242_334, 0).saturating_mul(r.into())) + // Minimum execution time: 7_950_000 picoseconds. + Weight::from_parts(7_381_228, 18187) + // Standard Error: 6_650 + .saturating_add(Weight::from_parts(3_198_515, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) } - /// Storage: Democracy VotingOf (r:3 w:3) - /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumInfoOf (r:99 w:99) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `Democracy::VotingOf` (r:3 w:3) + /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumInfoOf` (r:99 w:99) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 99]`. fn delegate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `830 + r * (108 ±0)` + // Measured: `863 + r * (108 ±0)` // Estimated: `19800 + r * (2676 ±0)` - // Minimum execution time: 46_106_000 picoseconds. - Weight::from_parts(48_936_654, 19800) - // Standard Error: 8_879 - .saturating_add(Weight::from_parts(4_708_141, 0).saturating_mul(r.into())) + // Minimum execution time: 40_109_000 picoseconds. + Weight::from_parts(43_164_384, 19800) + // Standard Error: 7_267 + .saturating_add(Weight::from_parts(4_161_526, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) } - /// Storage: Democracy VotingOf (r:2 w:2) - /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumInfoOf (r:99 w:99) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: `Democracy::VotingOf` (r:2 w:2) + /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumInfoOf` (r:99 w:99) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 99]`. fn undelegate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `493 + r * (108 ±0)` + // Measured: `526 + r * (108 ±0)` // Estimated: `13530 + r * (2676 ±0)` - // Minimum execution time: 21_078_000 picoseconds. - Weight::from_parts(22_732_737, 13530) - // Standard Error: 7_969 - .saturating_add(Weight::from_parts(4_626_458, 0).saturating_mul(r.into())) + // Minimum execution time: 17_466_000 picoseconds. + Weight::from_parts(18_004_456, 13530) + // Standard Error: 6_327 + .saturating_add(Weight::from_parts(4_194_583, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) } - /// Storage: Democracy PublicProps (r:0 w:1) - /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: `Democracy::PublicProps` (r:0 w:1) + /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) fn clear_public_proposals() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_229_000 picoseconds. - Weight::from_parts(3_415_000, 0) + // Minimum execution time: 2_824_000 picoseconds. + Weight::from_parts(2_948_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Democracy VotingOf (r:1 w:1) - /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Democracy::VotingOf` (r:1 w:1) + /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 99]`. fn unlock_remove(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `563` + // Measured: `596` // Estimated: `7260` - // Minimum execution time: 25_735_000 picoseconds. - Weight::from_parts(41_341_468, 7260) - // Standard Error: 3_727 - .saturating_add(Weight::from_parts(94_755, 0).saturating_mul(r.into())) + // Minimum execution time: 23_373_000 picoseconds. + Weight::from_parts(34_306_582, 7260) + // Standard Error: 2_849 + .saturating_add(Weight::from_parts(85_027, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Democracy VotingOf (r:1 w:1) - /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Democracy::VotingOf` (r:1 w:1) + /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 99]`. fn unlock_set(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `564 + r * (22 ±0)` + // Measured: `597 + r * (22 ±0)` // Estimated: `7260` - // Minimum execution time: 36_233_000 picoseconds. - Weight::from_parts(39_836_017, 7260) - // Standard Error: 1_791 - .saturating_add(Weight::from_parts(132_158, 0).saturating_mul(r.into())) + // Minimum execution time: 31_574_000 picoseconds. + Weight::from_parts(33_906_658, 7260) + // Standard Error: 1_514 + .saturating_add(Weight::from_parts(124_471, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Democracy ReferendumInfoOf (r:1 w:1) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) - /// Storage: Democracy VotingOf (r:1 w:1) - /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: `Democracy::VotingOf` (r:1 w:1) + /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 100]`. fn remove_vote(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `728 + r * (26 ±0)` + // Measured: `761 + r * (26 ±0)` // Estimated: `7260` - // Minimum execution time: 16_081_000 picoseconds. - Weight::from_parts(19_624_101, 7260) - // Standard Error: 1_639 - .saturating_add(Weight::from_parts(133_630, 0).saturating_mul(r.into())) + // Minimum execution time: 15_204_000 picoseconds. + Weight::from_parts(18_405_879, 7260) + // Standard Error: 1_851 + .saturating_add(Weight::from_parts(119_018, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Democracy ReferendumInfoOf (r:1 w:1) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) - /// Storage: Democracy VotingOf (r:1 w:1) - /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: `Democracy::VotingOf` (r:1 w:1) + /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 100]`. fn remove_other_vote(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `728 + r * (26 ±0)` + // Measured: `761 + r * (26 ±0)` // Estimated: `7260` - // Minimum execution time: 15_634_000 picoseconds. - Weight::from_parts(19_573_407, 7260) - // Standard Error: 1_790 - .saturating_add(Weight::from_parts(139_707, 0).saturating_mul(r.into())) + // Minimum execution time: 15_120_000 picoseconds. + Weight::from_parts(18_282_222, 7260) + // Standard Error: 1_669 + .saturating_add(Weight::from_parts(127_649, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Democracy NextExternal (r:1 w:0) - /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) - /// Storage: Preimage StatusFor (r:1 w:0) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:0 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: `Democracy::NextExternal` (r:1 w:0) + /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:0 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) fn set_external_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `356` + // Measured: `456` // Estimated: `3556` - // Minimum execution time: 18_344_000 picoseconds. - Weight::from_parts(18_727_000, 3556) - .saturating_add(T::DbWeight::get().reads(2_u64)) + // Minimum execution time: 17_351_000 picoseconds. + Weight::from_parts(17_964_000, 3556) + .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Democracy NextExternal (r:1 w:0) - /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:1 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: `Democracy::NextExternal` (r:1 w:0) + /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:1 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) fn clear_external_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `286` + // Measured: `319` // Estimated: `3518` - // Minimum execution time: 16_497_000 picoseconds. - Weight::from_parts(16_892_000, 3518) + // Minimum execution time: 13_669_000 picoseconds. + Weight::from_parts(14_410_000, 3518) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Democracy PublicProps (r:1 w:0) - /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) - /// Storage: Preimage StatusFor (r:1 w:0) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:0 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: `Democracy::PublicProps` (r:1 w:0) + /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:0 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) fn set_proposal_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `4888` + // Measured: `4988` // Estimated: `18187` - // Minimum execution time: 39_517_000 picoseconds. - Weight::from_parts(40_632_000, 18187) - .saturating_add(T::DbWeight::get().reads(2_u64)) + // Minimum execution time: 39_162_000 picoseconds. + Weight::from_parts(40_109_000, 18187) + .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Democracy PublicProps (r:1 w:0) - /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:1 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: `Democracy::PublicProps` (r:1 w:0) + /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:1 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) fn clear_proposal_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `4822` + // Measured: `4855` // Estimated: `18187` - // Minimum execution time: 37_108_000 picoseconds. - Weight::from_parts(37_599_000, 18187) + // Minimum execution time: 34_141_000 picoseconds. + Weight::from_parts(34_732_000, 18187) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Preimage StatusFor (r:1 w:0) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:0 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:0 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) fn set_referendum_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `144` + // Measured: `211` // Estimated: `3556` - // Minimum execution time: 13_997_000 picoseconds. - Weight::from_parts(14_298_000, 3556) - .saturating_add(T::DbWeight::get().reads(1_u64)) + // Minimum execution time: 13_413_000 picoseconds. + Weight::from_parts(14_039_000, 3556) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Democracy ReferendumInfoOf (r:1 w:0) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:1 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:0) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:1 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) fn clear_referendum_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `302` + // Measured: `335` // Estimated: `3666` - // Minimum execution time: 18_122_000 picoseconds. - Weight::from_parts(18_655_000, 3666) + // Minimum execution time: 16_010_000 picoseconds. + Weight::from_parts(16_474_000, 3666) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Democracy PublicPropCount (r:1 w:1) - /// Proof: Democracy PublicPropCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Democracy PublicProps (r:1 w:1) - /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) - /// Storage: Democracy Blacklist (r:1 w:0) - /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) - /// Storage: Democracy DepositOf (r:0 w:1) - /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + /// Storage: `Democracy::PublicPropCount` (r:1 w:1) + /// Proof: `Democracy::PublicPropCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Democracy::PublicProps` (r:1 w:1) + /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) + /// Storage: `Democracy::Blacklist` (r:1 w:0) + /// Proof: `Democracy::Blacklist` (`max_values`: None, `max_size`: Some(3238), added: 5713, mode: `MaxEncodedLen`) + /// Storage: `Democracy::DepositOf` (r:0 w:1) + /// Proof: `Democracy::DepositOf` (`max_values`: None, `max_size`: Some(3230), added: 5705, mode: `MaxEncodedLen`) fn propose() -> Weight { // Proof Size summary in bytes: - // Measured: `4801` + // Measured: `4834` // Estimated: `18187` - // Minimum execution time: 49_339_000 picoseconds. - Weight::from_parts(50_942_000, 18187) + // Minimum execution time: 39_930_000 picoseconds. + Weight::from_parts(41_746_000, 18187) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Democracy DepositOf (r:1 w:1) - /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + /// Storage: `Democracy::DepositOf` (r:1 w:1) + /// Proof: `Democracy::DepositOf` (`max_values`: None, `max_size`: Some(3230), added: 5705, mode: `MaxEncodedLen`) fn second() -> Weight { // Proof Size summary in bytes: - // Measured: `3556` + // Measured: `3589` // Estimated: `6695` - // Minimum execution time: 43_291_000 picoseconds. - Weight::from_parts(44_856_000, 6695) + // Minimum execution time: 36_490_000 picoseconds. + Weight::from_parts(37_615_000, 6695) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Democracy ReferendumInfoOf (r:1 w:1) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) - /// Storage: Democracy VotingOf (r:1 w:1) - /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: `Democracy::VotingOf` (r:1 w:1) + /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) fn vote_new() -> Weight { // Proof Size summary in bytes: - // Measured: `3470` + // Measured: `3503` // Estimated: `7260` - // Minimum execution time: 61_890_000 picoseconds. - Weight::from_parts(63_626_000, 7260) + // Minimum execution time: 54_257_000 picoseconds. + Weight::from_parts(55_912_000, 7260) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Democracy ReferendumInfoOf (r:1 w:1) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) - /// Storage: Democracy VotingOf (r:1 w:1) - /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: `Democracy::VotingOf` (r:1 w:1) + /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) fn vote_existing() -> Weight { // Proof Size summary in bytes: - // Measured: `3492` + // Measured: `3525` // Estimated: `7260` - // Minimum execution time: 67_802_000 picoseconds. - Weight::from_parts(69_132_000, 7260) + // Minimum execution time: 56_878_000 picoseconds. + Weight::from_parts(58_796_000, 7260) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Democracy ReferendumInfoOf (r:1 w:1) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) - /// Storage: Democracy Cancellations (r:1 w:1) - /// Proof: Democracy Cancellations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:1 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: `Democracy::Cancellations` (r:1 w:1) + /// Proof: `Democracy::Cancellations` (`max_values`: None, `max_size`: Some(33), added: 2508, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:1 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) fn emergency_cancel() -> Weight { // Proof Size summary in bytes: - // Measured: `366` + // Measured: `399` // Estimated: `3666` - // Minimum execution time: 25_757_000 picoseconds. - Weight::from_parts(27_226_000, 3666) + // Minimum execution time: 22_700_000 picoseconds. + Weight::from_parts(23_539_000, 3666) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Democracy PublicProps (r:1 w:1) - /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) - /// Storage: Democracy DepositOf (r:1 w:1) - /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:3 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) - /// Storage: Democracy NextExternal (r:1 w:1) - /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumInfoOf (r:1 w:1) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) - /// Storage: Democracy Blacklist (r:0 w:1) - /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + /// Storage: `Democracy::PublicProps` (r:1 w:1) + /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) + /// Storage: `Democracy::DepositOf` (r:1 w:1) + /// Proof: `Democracy::DepositOf` (`max_values`: None, `max_size`: Some(3230), added: 5705, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:3 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: `Democracy::NextExternal` (r:1 w:1) + /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: `Democracy::Blacklist` (r:0 w:1) + /// Proof: `Democracy::Blacklist` (`max_values`: None, `max_size`: Some(3238), added: 5713, mode: `MaxEncodedLen`) fn blacklist() -> Weight { // Proof Size summary in bytes: - // Measured: `5910` + // Measured: `5943` // Estimated: `18187` - // Minimum execution time: 113_060_000 picoseconds. - Weight::from_parts(114_813_000, 18187) + // Minimum execution time: 95_398_000 picoseconds. + Weight::from_parts(97_261_000, 18187) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } - /// Storage: Democracy NextExternal (r:1 w:1) - /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) - /// Storage: Democracy Blacklist (r:1 w:0) - /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + /// Storage: `Democracy::NextExternal` (r:1 w:1) + /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) + /// Storage: `Democracy::Blacklist` (r:1 w:0) + /// Proof: `Democracy::Blacklist` (`max_values`: None, `max_size`: Some(3238), added: 5713, mode: `MaxEncodedLen`) fn external_propose() -> Weight { // Proof Size summary in bytes: - // Measured: `3416` + // Measured: `3449` // Estimated: `6703` - // Minimum execution time: 13_413_000 picoseconds. - Weight::from_parts(13_794_000, 6703) + // Minimum execution time: 11_745_000 picoseconds. + Weight::from_parts(12_304_000, 6703) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Democracy NextExternal (r:0 w:1) - /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: `Democracy::NextExternal` (r:0 w:1) + /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) fn external_propose_majority() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_213_000 picoseconds. - Weight::from_parts(3_429_000, 0) + // Minimum execution time: 2_710_000 picoseconds. + Weight::from_parts(2_918_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Democracy NextExternal (r:0 w:1) - /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: `Democracy::NextExternal` (r:0 w:1) + /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) fn external_propose_default() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_280_000 picoseconds. - Weight::from_parts(3_389_000, 0) + // Minimum execution time: 2_664_000 picoseconds. + Weight::from_parts(2_776_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Democracy NextExternal (r:1 w:1) - /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumCount (r:1 w:1) - /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:1 w:2) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumInfoOf (r:0 w:1) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: `Democracy::NextExternal` (r:1 w:1) + /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumCount` (r:1 w:1) + /// Proof: `Democracy::ReferendumCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:1 w:2) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumInfoOf` (r:0 w:1) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) fn fast_track() -> Weight { // Proof Size summary in bytes: - // Measured: `286` + // Measured: `319` // Estimated: `3518` - // Minimum execution time: 28_142_000 picoseconds. - Weight::from_parts(28_862_000, 3518) + // Minimum execution time: 22_585_000 picoseconds. + Weight::from_parts(23_689_000, 3518) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: Democracy NextExternal (r:1 w:1) - /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) - /// Storage: Democracy Blacklist (r:1 w:1) - /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:1 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: `Democracy::NextExternal` (r:1 w:1) + /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) + /// Storage: `Democracy::Blacklist` (r:1 w:1) + /// Proof: `Democracy::Blacklist` (`max_values`: None, `max_size`: Some(3238), added: 5713, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:1 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) fn veto_external() -> Weight { // Proof Size summary in bytes: - // Measured: `3519` + // Measured: `3552` // Estimated: `6703` - // Minimum execution time: 32_395_000 picoseconds. - Weight::from_parts(33_617_000, 6703) + // Minimum execution time: 26_391_000 picoseconds. + Weight::from_parts(27_141_000, 6703) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Democracy PublicProps (r:1 w:1) - /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) - /// Storage: Democracy DepositOf (r:1 w:1) - /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:1 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: `Democracy::PublicProps` (r:1 w:1) + /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) + /// Storage: `Democracy::DepositOf` (r:1 w:1) + /// Proof: `Democracy::DepositOf` (`max_values`: None, `max_size`: Some(3230), added: 5705, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:1 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) fn cancel_proposal() -> Weight { // Proof Size summary in bytes: - // Measured: `5821` + // Measured: `5854` // Estimated: `18187` - // Minimum execution time: 92_255_000 picoseconds. - Weight::from_parts(93_704_000, 18187) + // Minimum execution time: 77_905_000 picoseconds. + Weight::from_parts(79_628_000, 18187) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: Democracy MetadataOf (r:1 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumInfoOf (r:0 w:1) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: `Democracy::MetadataOf` (r:1 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumInfoOf` (r:0 w:1) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) fn cancel_referendum() -> Weight { // Proof Size summary in bytes: - // Measured: `271` + // Measured: `304` // Estimated: `3518` - // Minimum execution time: 19_623_000 picoseconds. - Weight::from_parts(20_545_000, 3518) + // Minimum execution time: 15_735_000 picoseconds. + Weight::from_parts(16_525_000, 3518) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Democracy LowestUnbaked (r:1 w:1) - /// Proof: Democracy LowestUnbaked (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumCount (r:1 w:0) - /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumInfoOf (r:99 w:0) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: `Democracy::LowestUnbaked` (r:1 w:1) + /// Proof: `Democracy::LowestUnbaked` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumCount` (r:1 w:0) + /// Proof: `Democracy::ReferendumCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumInfoOf` (r:99 w:0) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 99]`. fn on_initialize_base(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `244 + r * (86 ±0)` + // Measured: `277 + r * (86 ±0)` // Estimated: `1489 + r * (2676 ±0)` - // Minimum execution time: 7_032_000 picoseconds. - Weight::from_parts(7_931_421, 1489) - // Standard Error: 7_395 - .saturating_add(Weight::from_parts(3_236_964, 0).saturating_mul(r.into())) + // Minimum execution time: 5_274_000 picoseconds. + Weight::from_parts(6_162_399, 1489) + // Standard Error: 6_924 + .saturating_add(Weight::from_parts(3_186_702, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) } - /// Storage: Democracy LowestUnbaked (r:1 w:1) - /// Proof: Democracy LowestUnbaked (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumCount (r:1 w:0) - /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Democracy LastTabledWasExternal (r:1 w:0) - /// Proof: Democracy LastTabledWasExternal (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) - /// Storage: Democracy NextExternal (r:1 w:0) - /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) - /// Storage: Democracy PublicProps (r:1 w:0) - /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumInfoOf (r:99 w:0) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: `Democracy::LowestUnbaked` (r:1 w:1) + /// Proof: `Democracy::LowestUnbaked` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumCount` (r:1 w:0) + /// Proof: `Democracy::ReferendumCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Democracy::LastTabledWasExternal` (r:1 w:0) + /// Proof: `Democracy::LastTabledWasExternal` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `Democracy::NextExternal` (r:1 w:0) + /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) + /// Storage: `Democracy::PublicProps` (r:1 w:0) + /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumInfoOf` (r:99 w:0) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 99]`. fn on_initialize_base_with_launch_period(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `244 + r * (86 ±0)` + // Measured: `277 + r * (86 ±0)` // Estimated: `18187 + r * (2676 ±0)` - // Minimum execution time: 10_524_000 picoseconds. - Weight::from_parts(10_369_064, 18187) - // Standard Error: 8_385 - .saturating_add(Weight::from_parts(3_242_334, 0).saturating_mul(r.into())) + // Minimum execution time: 7_950_000 picoseconds. + Weight::from_parts(7_381_228, 18187) + // Standard Error: 6_650 + .saturating_add(Weight::from_parts(3_198_515, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) } - /// Storage: Democracy VotingOf (r:3 w:3) - /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumInfoOf (r:99 w:99) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `Democracy::VotingOf` (r:3 w:3) + /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumInfoOf` (r:99 w:99) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 99]`. fn delegate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `830 + r * (108 ±0)` + // Measured: `863 + r * (108 ±0)` // Estimated: `19800 + r * (2676 ±0)` - // Minimum execution time: 46_106_000 picoseconds. - Weight::from_parts(48_936_654, 19800) - // Standard Error: 8_879 - .saturating_add(Weight::from_parts(4_708_141, 0).saturating_mul(r.into())) + // Minimum execution time: 40_109_000 picoseconds. + Weight::from_parts(43_164_384, 19800) + // Standard Error: 7_267 + .saturating_add(Weight::from_parts(4_161_526, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) } - /// Storage: Democracy VotingOf (r:2 w:2) - /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) - /// Storage: Democracy ReferendumInfoOf (r:99 w:99) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: `Democracy::VotingOf` (r:2 w:2) + /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) + /// Storage: `Democracy::ReferendumInfoOf` (r:99 w:99) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 99]`. fn undelegate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `493 + r * (108 ±0)` + // Measured: `526 + r * (108 ±0)` // Estimated: `13530 + r * (2676 ±0)` - // Minimum execution time: 21_078_000 picoseconds. - Weight::from_parts(22_732_737, 13530) - // Standard Error: 7_969 - .saturating_add(Weight::from_parts(4_626_458, 0).saturating_mul(r.into())) + // Minimum execution time: 17_466_000 picoseconds. + Weight::from_parts(18_004_456, 13530) + // Standard Error: 6_327 + .saturating_add(Weight::from_parts(4_194_583, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) } - /// Storage: Democracy PublicProps (r:0 w:1) - /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: `Democracy::PublicProps` (r:0 w:1) + /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) fn clear_public_proposals() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_229_000 picoseconds. - Weight::from_parts(3_415_000, 0) + // Minimum execution time: 2_824_000 picoseconds. + Weight::from_parts(2_948_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Democracy VotingOf (r:1 w:1) - /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Democracy::VotingOf` (r:1 w:1) + /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 99]`. fn unlock_remove(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `563` + // Measured: `596` // Estimated: `7260` - // Minimum execution time: 25_735_000 picoseconds. - Weight::from_parts(41_341_468, 7260) - // Standard Error: 3_727 - .saturating_add(Weight::from_parts(94_755, 0).saturating_mul(r.into())) + // Minimum execution time: 23_373_000 picoseconds. + Weight::from_parts(34_306_582, 7260) + // Standard Error: 2_849 + .saturating_add(Weight::from_parts(85_027, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Democracy VotingOf (r:1 w:1) - /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Democracy::VotingOf` (r:1 w:1) + /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 99]`. fn unlock_set(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `564 + r * (22 ±0)` + // Measured: `597 + r * (22 ±0)` // Estimated: `7260` - // Minimum execution time: 36_233_000 picoseconds. - Weight::from_parts(39_836_017, 7260) - // Standard Error: 1_791 - .saturating_add(Weight::from_parts(132_158, 0).saturating_mul(r.into())) + // Minimum execution time: 31_574_000 picoseconds. + Weight::from_parts(33_906_658, 7260) + // Standard Error: 1_514 + .saturating_add(Weight::from_parts(124_471, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Democracy ReferendumInfoOf (r:1 w:1) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) - /// Storage: Democracy VotingOf (r:1 w:1) - /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: `Democracy::VotingOf` (r:1 w:1) + /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 100]`. fn remove_vote(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `728 + r * (26 ±0)` + // Measured: `761 + r * (26 ±0)` // Estimated: `7260` - // Minimum execution time: 16_081_000 picoseconds. - Weight::from_parts(19_624_101, 7260) - // Standard Error: 1_639 - .saturating_add(Weight::from_parts(133_630, 0).saturating_mul(r.into())) + // Minimum execution time: 15_204_000 picoseconds. + Weight::from_parts(18_405_879, 7260) + // Standard Error: 1_851 + .saturating_add(Weight::from_parts(119_018, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Democracy ReferendumInfoOf (r:1 w:1) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) - /// Storage: Democracy VotingOf (r:1 w:1) - /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: `Democracy::VotingOf` (r:1 w:1) + /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 100]`. fn remove_other_vote(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `728 + r * (26 ±0)` + // Measured: `761 + r * (26 ±0)` // Estimated: `7260` - // Minimum execution time: 15_634_000 picoseconds. - Weight::from_parts(19_573_407, 7260) - // Standard Error: 1_790 - .saturating_add(Weight::from_parts(139_707, 0).saturating_mul(r.into())) + // Minimum execution time: 15_120_000 picoseconds. + Weight::from_parts(18_282_222, 7260) + // Standard Error: 1_669 + .saturating_add(Weight::from_parts(127_649, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Democracy NextExternal (r:1 w:0) - /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) - /// Storage: Preimage StatusFor (r:1 w:0) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:0 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: `Democracy::NextExternal` (r:1 w:0) + /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:0 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) fn set_external_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `356` + // Measured: `456` // Estimated: `3556` - // Minimum execution time: 18_344_000 picoseconds. - Weight::from_parts(18_727_000, 3556) - .saturating_add(RocksDbWeight::get().reads(2_u64)) + // Minimum execution time: 17_351_000 picoseconds. + Weight::from_parts(17_964_000, 3556) + .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Democracy NextExternal (r:1 w:0) - /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:1 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: `Democracy::NextExternal` (r:1 w:0) + /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:1 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) fn clear_external_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `286` + // Measured: `319` // Estimated: `3518` - // Minimum execution time: 16_497_000 picoseconds. - Weight::from_parts(16_892_000, 3518) + // Minimum execution time: 13_669_000 picoseconds. + Weight::from_parts(14_410_000, 3518) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Democracy PublicProps (r:1 w:0) - /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) - /// Storage: Preimage StatusFor (r:1 w:0) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:0 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: `Democracy::PublicProps` (r:1 w:0) + /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:0 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) fn set_proposal_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `4888` + // Measured: `4988` // Estimated: `18187` - // Minimum execution time: 39_517_000 picoseconds. - Weight::from_parts(40_632_000, 18187) - .saturating_add(RocksDbWeight::get().reads(2_u64)) + // Minimum execution time: 39_162_000 picoseconds. + Weight::from_parts(40_109_000, 18187) + .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Democracy PublicProps (r:1 w:0) - /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:1 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: `Democracy::PublicProps` (r:1 w:0) + /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:1 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) fn clear_proposal_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `4822` + // Measured: `4855` // Estimated: `18187` - // Minimum execution time: 37_108_000 picoseconds. - Weight::from_parts(37_599_000, 18187) + // Minimum execution time: 34_141_000 picoseconds. + Weight::from_parts(34_732_000, 18187) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Preimage StatusFor (r:1 w:0) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:0 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:0 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) fn set_referendum_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `144` + // Measured: `211` // Estimated: `3556` - // Minimum execution time: 13_997_000 picoseconds. - Weight::from_parts(14_298_000, 3556) - .saturating_add(RocksDbWeight::get().reads(1_u64)) + // Minimum execution time: 13_413_000 picoseconds. + Weight::from_parts(14_039_000, 3556) + .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Democracy ReferendumInfoOf (r:1 w:0) - /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) - /// Storage: Democracy MetadataOf (r:1 w:1) - /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:0) + /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: `Democracy::MetadataOf` (r:1 w:1) + /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) fn clear_referendum_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `302` + // Measured: `335` // Estimated: `3666` - // Minimum execution time: 18_122_000 picoseconds. - Weight::from_parts(18_655_000, 3666) + // Minimum execution time: 16_010_000 picoseconds. + Weight::from_parts(16_474_000, 3666) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/election-provider-multi-phase/src/mock.rs b/substrate/frame/election-provider-multi-phase/src/mock.rs index 18dcd7061c1..312dc557090 100644 --- a/substrate/frame/election-provider-multi-phase/src/mock.rs +++ b/substrate/frame/election-provider-multi-phase/src/mock.rs @@ -441,7 +441,7 @@ where type Extrinsic = Extrinsic; } -pub type Extrinsic = sp_runtime::testing::TestXt; +pub type Extrinsic = sp_runtime::generic::UncheckedExtrinsic; parameter_types! { pub MaxNominations: u32 = ::LIMIT as u32; diff --git a/substrate/frame/election-provider-multi-phase/src/unsigned.rs b/substrate/frame/election-provider-multi-phase/src/unsigned.rs index 94348181334..94cfd059b6c 100644 --- a/substrate/frame/election-provider-multi-phase/src/unsigned.rs +++ b/substrate/frame/election-provider-multi-phase/src/unsigned.rs @@ -1813,7 +1813,7 @@ mod tests { let encoded = pool.read().transactions[0].clone(); let extrinsic: Extrinsic = codec::Decode::decode(&mut &*encoded).unwrap(); - let call = extrinsic.call; + let call = extrinsic.function; assert!(matches!(call, RuntimeCall::MultiPhase(Call::submit_unsigned { .. }))); }) } @@ -1830,7 +1830,7 @@ mod tests { let encoded = pool.read().transactions[0].clone(); let extrinsic = Extrinsic::decode(&mut &*encoded).unwrap(); - let call = match extrinsic.call { + let call = match extrinsic.function { RuntimeCall::MultiPhase(call @ Call::submit_unsigned { .. }) => call, _ => panic!("bad call: unexpected submission"), }; diff --git a/substrate/frame/election-provider-multi-phase/src/weights.rs b/substrate/frame/election-provider-multi-phase/src/weights.rs index be578fac8c4..ed3e942716e 100644 --- a/substrate/frame/election-provider-multi-phase/src/weights.rs +++ b/substrate/frame/election-provider-multi-phase/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_election_provider_multi_phase +//! Autogenerated weights for `pallet_election_provider_multi_phase` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/election-provider-multi-phase/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/election-provider-multi-phase/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_election_provider_multi_phase. +/// Weight functions needed for `pallet_election_provider_multi_phase`. pub trait WeightInfo { fn on_initialize_nothing() -> Weight; fn on_initialize_open_signed() -> Weight; @@ -64,169 +63,171 @@ pub trait WeightInfo { fn feasibility_check(v: u32, t: u32, a: u32, d: u32, ) -> Weight; } -/// Weights for pallet_election_provider_multi_phase using the Substrate node and recommended hardware. +/// Weights for `pallet_election_provider_multi_phase` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Staking CurrentEra (r:1 w:0) - /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Staking CurrentPlannedSession (r:1 w:0) - /// Proof: Staking CurrentPlannedSession (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Staking ErasStartSessionIndex (r:1 w:0) - /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) - /// Storage: Babe EpochIndex (r:1 w:0) - /// Proof: Babe EpochIndex (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Babe GenesisSlot (r:1 w:0) - /// Proof: Babe GenesisSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Babe CurrentSlot (r:1 w:0) - /// Proof: Babe CurrentSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Staking ForceEra (r:1 w:0) - /// Proof: Staking ForceEra (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) - /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Staking::CurrentEra` (r:1 w:0) + /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::CurrentPlannedSession` (r:1 w:0) + /// Proof: `Staking::CurrentPlannedSession` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::ErasStartSessionIndex` (r:1 w:0) + /// Proof: `Staking::ErasStartSessionIndex` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `Babe::EpochIndex` (r:1 w:0) + /// Proof: `Babe::EpochIndex` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Babe::GenesisSlot` (r:1 w:0) + /// Proof: `Babe::GenesisSlot` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Babe::CurrentSlot` (r:1 w:0) + /// Proof: `Babe::CurrentSlot` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Staking::ForceEra` (r:1 w:0) + /// Proof: `Staking::ForceEra` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn on_initialize_nothing() -> Weight { // Proof Size summary in bytes: - // Measured: `1028` + // Measured: `1061` // Estimated: `3481` - // Minimum execution time: 22_089_000 picoseconds. - Weight::from_parts(22_677_000, 3481) + // Minimum execution time: 19_340_000 picoseconds. + Weight::from_parts(19_886_000, 3481) .saturating_add(T::DbWeight::get().reads(8_u64)) } - /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn on_initialize_open_signed() -> Weight { // Proof Size summary in bytes: // Measured: `148` // Estimated: `1633` - // Minimum execution time: 11_986_000 picoseconds. - Weight::from_parts(12_445_000, 1633) + // Minimum execution time: 8_067_000 picoseconds. + Weight::from_parts(8_508_000, 1633) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn on_initialize_open_unsigned() -> Weight { // Proof Size summary in bytes: // Measured: `148` // Estimated: `1633` - // Minimum execution time: 12_988_000 picoseconds. - Weight::from_parts(13_281_000, 1633) + // Minimum execution time: 8_810_000 picoseconds. + Weight::from_parts(9_061_000, 1633) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: ElectionProviderMultiPhase QueuedSolution (r:0 w:1) - /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ElectionProviderMultiPhase::QueuedSolution` (r:0 w:1) + /// Proof: `ElectionProviderMultiPhase::QueuedSolution` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn finalize_signed_phase_accept_solution() -> Weight { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 32_659_000 picoseconds. - Weight::from_parts(33_281_000, 3593) + // Minimum execution time: 24_339_000 picoseconds. + Weight::from_parts(25_322_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn finalize_signed_phase_reject_solution() -> Weight { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 22_471_000 picoseconds. - Weight::from_parts(23_046_000, 3593) + // Minimum execution time: 16_635_000 picoseconds. + Weight::from_parts(17_497_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:0 w:1) - /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase DesiredTargets (r:0 w:1) - /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase Snapshot (r:0 w:1) - /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `ElectionProviderMultiPhase::SnapshotMetadata` (r:0 w:1) + /// Proof: `ElectionProviderMultiPhase::SnapshotMetadata` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::DesiredTargets` (r:0 w:1) + /// Proof: `ElectionProviderMultiPhase::DesiredTargets` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::Snapshot` (r:0 w:1) + /// Proof: `ElectionProviderMultiPhase::Snapshot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `v` is `[1000, 2000]`. /// The range of component `t` is `[500, 1000]`. fn create_snapshot_internal(v: u32, _t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 262_360_000 picoseconds. - Weight::from_parts(279_313_000, 0) - // Standard Error: 2_384 - .saturating_add(Weight::from_parts(176_415, 0).saturating_mul(v.into())) + // Minimum execution time: 170_730_000 picoseconds. + Weight::from_parts(175_009_000, 0) + // Standard Error: 2_010 + .saturating_add(Weight::from_parts(224_974, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: ElectionProviderMultiPhase SignedSubmissionIndices (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionIndices (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase SignedSubmissionNextIndex (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionNextIndex (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase SignedSubmissionsMap (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionsMap (max_values: None, max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase QueuedSolution (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase Round (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase DesiredTargets (r:0 w:1) - /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase Snapshot (r:0 w:1) - /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `ElectionProviderMultiPhase::SignedSubmissionIndices` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::SignedSubmissionIndices` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::SignedSubmissionNextIndex` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::SignedSubmissionNextIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::SnapshotMetadata` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::SnapshotMetadata` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::SignedSubmissionsMap` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::SignedSubmissionsMap` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::QueuedSolution` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::QueuedSolution` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::DesiredTargets` (r:0 w:1) + /// Proof: `ElectionProviderMultiPhase::DesiredTargets` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::Snapshot` (r:0 w:1) + /// Proof: `ElectionProviderMultiPhase::Snapshot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `a` is `[500, 800]`. /// The range of component `d` is `[200, 400]`. fn elect_queued(a: u32, d: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `371 + a * (768 ±0) + d * (48 ±0)` // Estimated: `3923 + a * (768 ±0) + d * (49 ±0)` - // Minimum execution time: 301_283_000 picoseconds. - Weight::from_parts(324_586_000, 3923) - // Standard Error: 4_763 - .saturating_add(Weight::from_parts(279_812, 0).saturating_mul(a.into())) + // Minimum execution time: 280_705_000 picoseconds. + Weight::from_parts(303_018_000, 3923) + // Standard Error: 4_633 + .saturating_add(Weight::from_parts(307_274, 0).saturating_mul(a.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(8_u64)) .saturating_add(Weight::from_parts(0, 768).saturating_mul(a.into())) .saturating_add(Weight::from_parts(0, 49).saturating_mul(d.into())) } - /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TransactionPayment NextFeeMultiplier (r:1 w:0) - /// Proof: TransactionPayment NextFeeMultiplier (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: ElectionProviderMultiPhase SignedSubmissionIndices (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionIndices (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase SignedSubmissionNextIndex (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionNextIndex (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase SignedSubmissionsMap (r:0 w:1) - /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionsMap (max_values: None, max_size: None, mode: Measured) + /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::SnapshotMetadata` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::SnapshotMetadata` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::SignedSubmissionIndices` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::SignedSubmissionIndices` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::SignedSubmissionNextIndex` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::SignedSubmissionNextIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `ElectionProviderMultiPhase::SignedSubmissionsMap` (r:0 w:1) + /// Proof: `ElectionProviderMultiPhase::SignedSubmissionsMap` (`max_values`: None, `max_size`: None, mode: `Measured`) fn submit() -> Weight { // Proof Size summary in bytes: // Measured: `927` // Estimated: `2412` - // Minimum execution time: 52_276_000 picoseconds. - Weight::from_parts(53_846_000, 2412) - .saturating_add(T::DbWeight::get().reads(5_u64)) + // Minimum execution time: 43_405_000 picoseconds. + Weight::from_parts(45_734_000, 2412) + .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase DesiredTargets (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase QueuedSolution (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase Snapshot (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase MinimumUntrustedScore (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase MinimumUntrustedScore (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::DesiredTargets` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::DesiredTargets` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::QueuedSolution` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::QueuedSolution` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::SnapshotMetadata` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::SnapshotMetadata` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::Snapshot` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::Snapshot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::MinimumUntrustedScore` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::MinimumUntrustedScore` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `v` is `[1000, 2000]`. /// The range of component `t` is `[500, 1000]`. /// The range of component `a` is `[500, 800]`. @@ -235,25 +236,25 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `253 + t * (32 ±0) + v * (553 ±0)` // Estimated: `1738 + t * (32 ±0) + v * (553 ±0)` - // Minimum execution time: 5_448_459_000 picoseconds. - Weight::from_parts(5_525_622_000, 1738) - // Standard Error: 21_478 - .saturating_add(Weight::from_parts(256_345, 0).saturating_mul(v.into())) - // Standard Error: 63_648 - .saturating_add(Weight::from_parts(5_103_224, 0).saturating_mul(a.into())) + // Minimum execution time: 5_059_092_000 picoseconds. + Weight::from_parts(5_263_076_000, 1738) + // Standard Error: 17_317 + .saturating_add(Weight::from_parts(384_051, 0).saturating_mul(v.into())) + // Standard Error: 51_319 + .saturating_add(Weight::from_parts(4_095_128, 0).saturating_mul(a.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(t.into())) .saturating_add(Weight::from_parts(0, 553).saturating_mul(v.into())) } - /// Storage: ElectionProviderMultiPhase DesiredTargets (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase Snapshot (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase MinimumUntrustedScore (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase MinimumUntrustedScore (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `ElectionProviderMultiPhase::DesiredTargets` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::DesiredTargets` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::Snapshot` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::Snapshot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::MinimumUntrustedScore` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::MinimumUntrustedScore` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `v` is `[1000, 2000]`. /// The range of component `t` is `[500, 1000]`. /// The range of component `a` is `[500, 800]`. @@ -262,180 +263,182 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `228 + t * (32 ±0) + v * (553 ±0)` // Estimated: `1713 + t * (32 ±0) + v * (553 ±0)` - // Minimum execution time: 4_724_399_000 picoseconds. - Weight::from_parts(4_886_472_000, 1713) - // Standard Error: 15_220 - .saturating_add(Weight::from_parts(365_569, 0).saturating_mul(v.into())) - // Standard Error: 45_104 - .saturating_add(Weight::from_parts(3_176_675, 0).saturating_mul(a.into())) + // Minimum execution time: 4_426_416_000 picoseconds. + Weight::from_parts(4_466_923_000, 1713) + // Standard Error: 15_415 + .saturating_add(Weight::from_parts(334_047, 0).saturating_mul(v.into())) + // Standard Error: 45_682 + .saturating_add(Weight::from_parts(3_097_318, 0).saturating_mul(a.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(t.into())) .saturating_add(Weight::from_parts(0, 553).saturating_mul(v.into())) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Staking CurrentEra (r:1 w:0) - /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Staking CurrentPlannedSession (r:1 w:0) - /// Proof: Staking CurrentPlannedSession (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Staking ErasStartSessionIndex (r:1 w:0) - /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) - /// Storage: Babe EpochIndex (r:1 w:0) - /// Proof: Babe EpochIndex (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Babe GenesisSlot (r:1 w:0) - /// Proof: Babe GenesisSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Babe CurrentSlot (r:1 w:0) - /// Proof: Babe CurrentSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Staking ForceEra (r:1 w:0) - /// Proof: Staking ForceEra (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) - /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Staking::CurrentEra` (r:1 w:0) + /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::CurrentPlannedSession` (r:1 w:0) + /// Proof: `Staking::CurrentPlannedSession` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::ErasStartSessionIndex` (r:1 w:0) + /// Proof: `Staking::ErasStartSessionIndex` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `Babe::EpochIndex` (r:1 w:0) + /// Proof: `Babe::EpochIndex` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Babe::GenesisSlot` (r:1 w:0) + /// Proof: `Babe::GenesisSlot` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Babe::CurrentSlot` (r:1 w:0) + /// Proof: `Babe::CurrentSlot` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Staking::ForceEra` (r:1 w:0) + /// Proof: `Staking::ForceEra` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn on_initialize_nothing() -> Weight { // Proof Size summary in bytes: - // Measured: `1028` + // Measured: `1061` // Estimated: `3481` - // Minimum execution time: 22_089_000 picoseconds. - Weight::from_parts(22_677_000, 3481) + // Minimum execution time: 19_340_000 picoseconds. + Weight::from_parts(19_886_000, 3481) .saturating_add(RocksDbWeight::get().reads(8_u64)) } - /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn on_initialize_open_signed() -> Weight { // Proof Size summary in bytes: // Measured: `148` // Estimated: `1633` - // Minimum execution time: 11_986_000 picoseconds. - Weight::from_parts(12_445_000, 1633) + // Minimum execution time: 8_067_000 picoseconds. + Weight::from_parts(8_508_000, 1633) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn on_initialize_open_unsigned() -> Weight { // Proof Size summary in bytes: // Measured: `148` // Estimated: `1633` - // Minimum execution time: 12_988_000 picoseconds. - Weight::from_parts(13_281_000, 1633) + // Minimum execution time: 8_810_000 picoseconds. + Weight::from_parts(9_061_000, 1633) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: ElectionProviderMultiPhase QueuedSolution (r:0 w:1) - /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ElectionProviderMultiPhase::QueuedSolution` (r:0 w:1) + /// Proof: `ElectionProviderMultiPhase::QueuedSolution` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn finalize_signed_phase_accept_solution() -> Weight { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 32_659_000 picoseconds. - Weight::from_parts(33_281_000, 3593) + // Minimum execution time: 24_339_000 picoseconds. + Weight::from_parts(25_322_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn finalize_signed_phase_reject_solution() -> Weight { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 22_471_000 picoseconds. - Weight::from_parts(23_046_000, 3593) + // Minimum execution time: 16_635_000 picoseconds. + Weight::from_parts(17_497_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:0 w:1) - /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase DesiredTargets (r:0 w:1) - /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase Snapshot (r:0 w:1) - /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `ElectionProviderMultiPhase::SnapshotMetadata` (r:0 w:1) + /// Proof: `ElectionProviderMultiPhase::SnapshotMetadata` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::DesiredTargets` (r:0 w:1) + /// Proof: `ElectionProviderMultiPhase::DesiredTargets` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::Snapshot` (r:0 w:1) + /// Proof: `ElectionProviderMultiPhase::Snapshot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `v` is `[1000, 2000]`. /// The range of component `t` is `[500, 1000]`. fn create_snapshot_internal(v: u32, _t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 262_360_000 picoseconds. - Weight::from_parts(279_313_000, 0) - // Standard Error: 2_384 - .saturating_add(Weight::from_parts(176_415, 0).saturating_mul(v.into())) + // Minimum execution time: 170_730_000 picoseconds. + Weight::from_parts(175_009_000, 0) + // Standard Error: 2_010 + .saturating_add(Weight::from_parts(224_974, 0).saturating_mul(v.into())) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: ElectionProviderMultiPhase SignedSubmissionIndices (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionIndices (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase SignedSubmissionNextIndex (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionNextIndex (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase SignedSubmissionsMap (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionsMap (max_values: None, max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase QueuedSolution (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase Round (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase DesiredTargets (r:0 w:1) - /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase Snapshot (r:0 w:1) - /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `ElectionProviderMultiPhase::SignedSubmissionIndices` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::SignedSubmissionIndices` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::SignedSubmissionNextIndex` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::SignedSubmissionNextIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::SnapshotMetadata` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::SnapshotMetadata` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::SignedSubmissionsMap` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::SignedSubmissionsMap` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::QueuedSolution` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::QueuedSolution` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::DesiredTargets` (r:0 w:1) + /// Proof: `ElectionProviderMultiPhase::DesiredTargets` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::Snapshot` (r:0 w:1) + /// Proof: `ElectionProviderMultiPhase::Snapshot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `a` is `[500, 800]`. /// The range of component `d` is `[200, 400]`. fn elect_queued(a: u32, d: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `371 + a * (768 ±0) + d * (48 ±0)` // Estimated: `3923 + a * (768 ±0) + d * (49 ±0)` - // Minimum execution time: 301_283_000 picoseconds. - Weight::from_parts(324_586_000, 3923) - // Standard Error: 4_763 - .saturating_add(Weight::from_parts(279_812, 0).saturating_mul(a.into())) + // Minimum execution time: 280_705_000 picoseconds. + Weight::from_parts(303_018_000, 3923) + // Standard Error: 4_633 + .saturating_add(Weight::from_parts(307_274, 0).saturating_mul(a.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(8_u64)) .saturating_add(Weight::from_parts(0, 768).saturating_mul(a.into())) .saturating_add(Weight::from_parts(0, 49).saturating_mul(d.into())) } - /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TransactionPayment NextFeeMultiplier (r:1 w:0) - /// Proof: TransactionPayment NextFeeMultiplier (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: ElectionProviderMultiPhase SignedSubmissionIndices (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionIndices (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase SignedSubmissionNextIndex (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionNextIndex (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase SignedSubmissionsMap (r:0 w:1) - /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionsMap (max_values: None, max_size: None, mode: Measured) + /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::SnapshotMetadata` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::SnapshotMetadata` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::SignedSubmissionIndices` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::SignedSubmissionIndices` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::SignedSubmissionNextIndex` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::SignedSubmissionNextIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `ElectionProviderMultiPhase::SignedSubmissionsMap` (r:0 w:1) + /// Proof: `ElectionProviderMultiPhase::SignedSubmissionsMap` (`max_values`: None, `max_size`: None, mode: `Measured`) fn submit() -> Weight { // Proof Size summary in bytes: // Measured: `927` // Estimated: `2412` - // Minimum execution time: 52_276_000 picoseconds. - Weight::from_parts(53_846_000, 2412) - .saturating_add(RocksDbWeight::get().reads(5_u64)) + // Minimum execution time: 43_405_000 picoseconds. + Weight::from_parts(45_734_000, 2412) + .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase DesiredTargets (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase QueuedSolution (r:1 w:1) - /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase Snapshot (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase MinimumUntrustedScore (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase MinimumUntrustedScore (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::DesiredTargets` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::DesiredTargets` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::QueuedSolution` (r:1 w:1) + /// Proof: `ElectionProviderMultiPhase::QueuedSolution` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::SnapshotMetadata` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::SnapshotMetadata` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::Snapshot` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::Snapshot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::MinimumUntrustedScore` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::MinimumUntrustedScore` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `v` is `[1000, 2000]`. /// The range of component `t` is `[500, 1000]`. /// The range of component `a` is `[500, 800]`. @@ -444,25 +447,25 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `253 + t * (32 ±0) + v * (553 ±0)` // Estimated: `1738 + t * (32 ±0) + v * (553 ±0)` - // Minimum execution time: 5_448_459_000 picoseconds. - Weight::from_parts(5_525_622_000, 1738) - // Standard Error: 21_478 - .saturating_add(Weight::from_parts(256_345, 0).saturating_mul(v.into())) - // Standard Error: 63_648 - .saturating_add(Weight::from_parts(5_103_224, 0).saturating_mul(a.into())) + // Minimum execution time: 5_059_092_000 picoseconds. + Weight::from_parts(5_263_076_000, 1738) + // Standard Error: 17_317 + .saturating_add(Weight::from_parts(384_051, 0).saturating_mul(v.into())) + // Standard Error: 51_319 + .saturating_add(Weight::from_parts(4_095_128, 0).saturating_mul(a.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(t.into())) .saturating_add(Weight::from_parts(0, 553).saturating_mul(v.into())) } - /// Storage: ElectionProviderMultiPhase DesiredTargets (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase Snapshot (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ElectionProviderMultiPhase MinimumUntrustedScore (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase MinimumUntrustedScore (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `ElectionProviderMultiPhase::DesiredTargets` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::DesiredTargets` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::Snapshot` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::Snapshot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ElectionProviderMultiPhase::MinimumUntrustedScore` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::MinimumUntrustedScore` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `v` is `[1000, 2000]`. /// The range of component `t` is `[500, 1000]`. /// The range of component `a` is `[500, 800]`. @@ -471,12 +474,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `228 + t * (32 ±0) + v * (553 ±0)` // Estimated: `1713 + t * (32 ±0) + v * (553 ±0)` - // Minimum execution time: 4_724_399_000 picoseconds. - Weight::from_parts(4_886_472_000, 1713) - // Standard Error: 15_220 - .saturating_add(Weight::from_parts(365_569, 0).saturating_mul(v.into())) - // Standard Error: 45_104 - .saturating_add(Weight::from_parts(3_176_675, 0).saturating_mul(a.into())) + // Minimum execution time: 4_426_416_000 picoseconds. + Weight::from_parts(4_466_923_000, 1713) + // Standard Error: 15_415 + .saturating_add(Weight::from_parts(334_047, 0).saturating_mul(v.into())) + // Standard Error: 45_682 + .saturating_add(Weight::from_parts(3_097_318, 0).saturating_mul(a.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(t.into())) .saturating_add(Weight::from_parts(0, 553).saturating_mul(v.into())) diff --git a/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs b/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs index 882b894bb22..7fade251e6d 100644 --- a/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs +++ b/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs @@ -62,7 +62,7 @@ pub const INIT_TIMESTAMP: BlockNumber = 30_000; pub const BLOCK_TIME: BlockNumber = 1000; type Block = frame_system::mocking::MockBlockU32; -type Extrinsic = testing::TestXt; +type Extrinsic = sp_runtime::generic::UncheckedExtrinsic; frame_support::construct_runtime!( pub enum Runtime { @@ -699,7 +699,7 @@ pub fn roll_to_with_ocw(n: BlockNumber, pool: Arc>, delay_solu for encoded in &pool.read().transactions { let extrinsic = Extrinsic::decode(&mut &encoded[..]).unwrap(); - let _ = match extrinsic.call { + let _ = match extrinsic.function { RuntimeCall::ElectionProviderMultiPhase( call @ Call::submit_unsigned { .. }, ) => { diff --git a/substrate/frame/elections-phragmen/src/lib.rs b/substrate/frame/elections-phragmen/src/lib.rs index 308f2cdc1aa..e08412a6e87 100644 --- a/substrate/frame/elections-phragmen/src/lib.rs +++ b/substrate/frame/elections-phragmen/src/lib.rs @@ -1422,7 +1422,7 @@ mod tests { pub type Block = sp_runtime::generic::Block; pub type UncheckedExtrinsic = - sp_runtime::generic::UncheckedExtrinsic; + sp_runtime::generic::UncheckedExtrinsic; frame_support::construct_runtime!( pub enum Test diff --git a/substrate/frame/elections-phragmen/src/weights.rs b/substrate/frame/elections-phragmen/src/weights.rs index b7ed13dae9f..cd67918e85b 100644 --- a/substrate/frame/elections-phragmen/src/weights.rs +++ b/substrate/frame/elections-phragmen/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_elections_phragmen +//! Autogenerated weights for `pallet_elections_phragmen` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/elections-phragmen/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/elections-phragmen/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_elections_phragmen. +/// Weight functions needed for `pallet_elections_phragmen`. pub trait WeightInfo { fn vote_equal(v: u32, ) -> Weight; fn vote_more(v: u32, ) -> Weight; @@ -66,165 +65,165 @@ pub trait WeightInfo { fn election_phragmen(c: u32, v: u32, e: u32, ) -> Weight; } -/// Weights for pallet_elections_phragmen using the Substrate node and recommended hardware. +/// Weights for `pallet_elections_phragmen` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Elections Candidates (r:1 w:0) - /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Members (r:1 w:0) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections RunnersUp (r:1 w:0) - /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Voting (r:1 w:1) - /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `Elections::Candidates` (r:1 w:0) + /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Members` (r:1 w:0) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::RunnersUp` (r:1 w:0) + /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Voting` (r:1 w:1) + /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// The range of component `v` is `[1, 16]`. fn vote_equal(v: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `403 + v * (80 ±0)` // Estimated: `4764 + v * (80 ±0)` - // Minimum execution time: 33_028_000 picoseconds. - Weight::from_parts(34_073_914, 4764) - // Standard Error: 3_474 - .saturating_add(Weight::from_parts(205_252, 0).saturating_mul(v.into())) + // Minimum execution time: 29_390_000 picoseconds. + Weight::from_parts(30_525_476, 4764) + // Standard Error: 3_185 + .saturating_add(Weight::from_parts(143_073, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 80).saturating_mul(v.into())) } - /// Storage: Elections Candidates (r:1 w:0) - /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Members (r:1 w:0) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections RunnersUp (r:1 w:0) - /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Voting (r:1 w:1) - /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `Elections::Candidates` (r:1 w:0) + /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Members` (r:1 w:0) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::RunnersUp` (r:1 w:0) + /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Voting` (r:1 w:1) + /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// The range of component `v` is `[2, 16]`. fn vote_more(v: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `371 + v * (80 ±0)` // Estimated: `4764 + v * (80 ±0)` - // Minimum execution time: 45_725_000 picoseconds. - Weight::from_parts(47_169_586, 4764) - // Standard Error: 5_148 - .saturating_add(Weight::from_parts(213_742, 0).saturating_mul(v.into())) + // Minimum execution time: 39_765_000 picoseconds. + Weight::from_parts(41_374_102, 4764) + // Standard Error: 4_310 + .saturating_add(Weight::from_parts(153_015, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 80).saturating_mul(v.into())) } - /// Storage: Elections Candidates (r:1 w:0) - /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Members (r:1 w:0) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections RunnersUp (r:1 w:0) - /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Voting (r:1 w:1) - /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `Elections::Candidates` (r:1 w:0) + /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Members` (r:1 w:0) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::RunnersUp` (r:1 w:0) + /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Voting` (r:1 w:1) + /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// The range of component `v` is `[2, 16]`. fn vote_less(v: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `403 + v * (80 ±0)` // Estimated: `4764 + v * (80 ±0)` - // Minimum execution time: 45_519_000 picoseconds. - Weight::from_parts(47_339_108, 4764) - // Standard Error: 5_501 - .saturating_add(Weight::from_parts(195_247, 0).saturating_mul(v.into())) + // Minimum execution time: 39_647_000 picoseconds. + Weight::from_parts(41_474_523, 4764) + // Standard Error: 5_503 + .saturating_add(Weight::from_parts(149_029, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 80).saturating_mul(v.into())) } - /// Storage: Elections Voting (r:1 w:1) - /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `Elections::Voting` (r:1 w:1) + /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) fn remove_voter() -> Weight { // Proof Size summary in bytes: // Measured: `925` // Estimated: `4764` - // Minimum execution time: 50_386_000 picoseconds. - Weight::from_parts(51_378_000, 4764) + // Minimum execution time: 41_882_000 picoseconds. + Weight::from_parts(42_794_000, 4764) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Elections Candidates (r:1 w:1) - /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Members (r:1 w:0) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections RunnersUp (r:1 w:0) - /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Elections::Candidates` (r:1 w:1) + /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Members` (r:1 w:0) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::RunnersUp` (r:1 w:0) + /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `c` is `[1, 64]`. fn submit_candidacy(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `1570 + c * (48 ±0)` // Estimated: `3055 + c * (48 ±0)` - // Minimum execution time: 38_987_000 picoseconds. - Weight::from_parts(41_302_276, 3055) - // Standard Error: 2_047 - .saturating_add(Weight::from_parts(125_200, 0).saturating_mul(c.into())) + // Minimum execution time: 33_719_000 picoseconds. + Weight::from_parts(35_017_073, 3055) + // Standard Error: 1_587 + .saturating_add(Weight::from_parts(121_130, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 48).saturating_mul(c.into())) } - /// Storage: Elections Candidates (r:1 w:1) - /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Elections::Candidates` (r:1 w:1) + /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `c` is `[1, 64]`. fn renounce_candidacy_candidate(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `285 + c * (48 ±0)` // Estimated: `1770 + c * (48 ±0)` - // Minimum execution time: 33_510_000 picoseconds. - Weight::from_parts(34_947_760, 1770) - // Standard Error: 1_781 - .saturating_add(Weight::from_parts(78_851, 0).saturating_mul(c.into())) + // Minimum execution time: 27_263_000 picoseconds. + Weight::from_parts(28_215_666, 1770) + // Standard Error: 1_196 + .saturating_add(Weight::from_parts(86_804, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 48).saturating_mul(c.into())) } - /// Storage: Elections Members (r:1 w:1) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections RunnersUp (r:1 w:1) - /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Prime (r:1 w:1) - /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Proposals (r:1 w:0) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Members (r:0 w:1) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Elections::Members` (r:1 w:1) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::RunnersUp` (r:1 w:1) + /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Prime` (r:1 w:1) + /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Proposals` (r:1 w:0) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Members` (r:0 w:1) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn renounce_candidacy_members() -> Weight { // Proof Size summary in bytes: - // Measured: `1900` - // Estimated: `3385` - // Minimum execution time: 50_603_000 picoseconds. - Weight::from_parts(51_715_000, 3385) + // Measured: `1933` + // Estimated: `3418` + // Minimum execution time: 41_531_000 picoseconds. + Weight::from_parts(42_937_000, 3418) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: Elections RunnersUp (r:1 w:1) - /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Elections::RunnersUp` (r:1 w:1) + /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn renounce_candidacy_runners_up() -> Weight { // Proof Size summary in bytes: // Measured: `880` // Estimated: `2365` - // Minimum execution time: 33_441_000 picoseconds. - Weight::from_parts(34_812_000, 2365) + // Minimum execution time: 27_680_000 picoseconds. + Weight::from_parts(28_810_000, 2365) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Benchmark Override (r:0 w:0) - /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) fn remove_member_without_replacement() -> Weight { // Proof Size summary in bytes: // Measured: `0` @@ -232,87 +231,90 @@ impl WeightInfo for SubstrateWeight { // Minimum execution time: 2_000_000_000_000 picoseconds. Weight::from_parts(2_000_000_000_000, 0) } - /// Storage: Elections Members (r:1 w:1) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Elections RunnersUp (r:1 w:1) - /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Prime (r:1 w:1) - /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Proposals (r:1 w:0) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Members (r:0 w:1) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Elections::Members` (r:1 w:1) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Elections::RunnersUp` (r:1 w:1) + /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Prime` (r:1 w:1) + /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Proposals` (r:1 w:0) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Members` (r:0 w:1) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn remove_member_with_replacement() -> Weight { // Proof Size summary in bytes: - // Measured: `1900` + // Measured: `1933` // Estimated: `3593` - // Minimum execution time: 57_289_000 picoseconds. - Weight::from_parts(58_328_000, 3593) + // Minimum execution time: 45_333_000 picoseconds. + Weight::from_parts(46_523_000, 3593) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: Elections Voting (r:513 w:512) - /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Elections Members (r:1 w:0) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections RunnersUp (r:1 w:0) - /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Candidates (r:1 w:0) - /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Balances Locks (r:512 w:512) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:512 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: System Account (r:512 w:512) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Elections::Voting` (r:257 w:256) + /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Members` (r:1 w:0) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::RunnersUp` (r:1 w:0) + /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Candidates` (r:1 w:0) + /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Balances::Locks` (r:256 w:256) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:256 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:256 w:256) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `v` is `[256, 512]`. /// The range of component `d` is `[0, 256]`. - fn clean_defunct_voters(v: u32, _d: u32, ) -> Weight { + fn clean_defunct_voters(v: u32, d: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1149 + v * (811 ±0)` - // Estimated: `4621 + v * (3774 ±0)` - // Minimum execution time: 18_774_231_000 picoseconds. - Weight::from_parts(18_933_040_000, 4621) - // Standard Error: 301_534 - .saturating_add(Weight::from_parts(44_306_903, 0).saturating_mul(v.into())) + // Measured: `0 + d * (818 ±0) + v * (57 ±0)` + // Estimated: `24906 + d * (3774 ±1) + v * (24 ±0)` + // Minimum execution time: 5_620_000 picoseconds. + Weight::from_parts(5_817_000, 24906) + // Standard Error: 18_357 + .saturating_add(Weight::from_parts(106_164, 0).saturating_mul(v.into())) + // Standard Error: 39_980 + .saturating_add(Weight::from_parts(52_456_337, 0).saturating_mul(d.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(v.into()))) - .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(v.into()))) - .saturating_add(Weight::from_parts(0, 3774).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(d.into()))) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(d.into()))) + .saturating_add(Weight::from_parts(0, 3774).saturating_mul(d.into())) + .saturating_add(Weight::from_parts(0, 24).saturating_mul(v.into())) } - /// Storage: Elections Candidates (r:1 w:1) - /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Members (r:1 w:1) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections RunnersUp (r:1 w:1) - /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Voting (r:513 w:0) - /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Council Proposals (r:1 w:0) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: System Account (r:44 w:44) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Elections ElectionRounds (r:1 w:1) - /// Proof Skipped: Elections ElectionRounds (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Members (r:0 w:1) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Prime (r:0 w:1) - /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Elections::Candidates` (r:1 w:1) + /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Members` (r:1 w:1) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::RunnersUp` (r:1 w:1) + /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Voting` (r:513 w:0) + /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Council::Proposals` (r:1 w:0) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:44 w:44) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Elections::ElectionRounds` (r:1 w:1) + /// Proof: `Elections::ElectionRounds` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Members` (r:0 w:1) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Prime` (r:0 w:1) + /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `c` is `[1, 64]`. /// The range of component `v` is `[1, 512]`. /// The range of component `e` is `[512, 8192]`. fn election_phragmen(c: u32, v: u32, e: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + e * (28 ±0) + v * (606 ±0)` - // Estimated: `178887 + c * (2135 ±7) + e * (12 ±0) + v * (2653 ±6)` - // Minimum execution time: 1_281_877_000 picoseconds. - Weight::from_parts(1_288_147_000, 178887) - // Standard Error: 528_851 - .saturating_add(Weight::from_parts(17_761_407, 0).saturating_mul(v.into())) - // Standard Error: 33_932 - .saturating_add(Weight::from_parts(698_277, 0).saturating_mul(e.into())) + // Estimated: `178920 + c * (2135 ±7) + e * (12 ±0) + v * (2653 ±6)` + // Minimum execution time: 1_082_582_000 picoseconds. + Weight::from_parts(1_084_730_000, 178920) + // Standard Error: 594_096 + .saturating_add(Weight::from_parts(19_096_288, 0).saturating_mul(v.into())) + // Standard Error: 38_118 + .saturating_add(Weight::from_parts(792_945, 0).saturating_mul(e.into())) .saturating_add(T::DbWeight::get().reads(21_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into()))) @@ -324,164 +326,164 @@ impl WeightInfo for SubstrateWeight { } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Elections Candidates (r:1 w:0) - /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Members (r:1 w:0) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections RunnersUp (r:1 w:0) - /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Voting (r:1 w:1) - /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `Elections::Candidates` (r:1 w:0) + /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Members` (r:1 w:0) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::RunnersUp` (r:1 w:0) + /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Voting` (r:1 w:1) + /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// The range of component `v` is `[1, 16]`. fn vote_equal(v: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `403 + v * (80 ±0)` // Estimated: `4764 + v * (80 ±0)` - // Minimum execution time: 33_028_000 picoseconds. - Weight::from_parts(34_073_914, 4764) - // Standard Error: 3_474 - .saturating_add(Weight::from_parts(205_252, 0).saturating_mul(v.into())) + // Minimum execution time: 29_390_000 picoseconds. + Weight::from_parts(30_525_476, 4764) + // Standard Error: 3_185 + .saturating_add(Weight::from_parts(143_073, 0).saturating_mul(v.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 80).saturating_mul(v.into())) } - /// Storage: Elections Candidates (r:1 w:0) - /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Members (r:1 w:0) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections RunnersUp (r:1 w:0) - /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Voting (r:1 w:1) - /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `Elections::Candidates` (r:1 w:0) + /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Members` (r:1 w:0) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::RunnersUp` (r:1 w:0) + /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Voting` (r:1 w:1) + /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// The range of component `v` is `[2, 16]`. fn vote_more(v: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `371 + v * (80 ±0)` // Estimated: `4764 + v * (80 ±0)` - // Minimum execution time: 45_725_000 picoseconds. - Weight::from_parts(47_169_586, 4764) - // Standard Error: 5_148 - .saturating_add(Weight::from_parts(213_742, 0).saturating_mul(v.into())) + // Minimum execution time: 39_765_000 picoseconds. + Weight::from_parts(41_374_102, 4764) + // Standard Error: 4_310 + .saturating_add(Weight::from_parts(153_015, 0).saturating_mul(v.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 80).saturating_mul(v.into())) } - /// Storage: Elections Candidates (r:1 w:0) - /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Members (r:1 w:0) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections RunnersUp (r:1 w:0) - /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Voting (r:1 w:1) - /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `Elections::Candidates` (r:1 w:0) + /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Members` (r:1 w:0) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::RunnersUp` (r:1 w:0) + /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Voting` (r:1 w:1) + /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// The range of component `v` is `[2, 16]`. fn vote_less(v: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `403 + v * (80 ±0)` // Estimated: `4764 + v * (80 ±0)` - // Minimum execution time: 45_519_000 picoseconds. - Weight::from_parts(47_339_108, 4764) - // Standard Error: 5_501 - .saturating_add(Weight::from_parts(195_247, 0).saturating_mul(v.into())) + // Minimum execution time: 39_647_000 picoseconds. + Weight::from_parts(41_474_523, 4764) + // Standard Error: 5_503 + .saturating_add(Weight::from_parts(149_029, 0).saturating_mul(v.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 80).saturating_mul(v.into())) } - /// Storage: Elections Voting (r:1 w:1) - /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `Elections::Voting` (r:1 w:1) + /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) fn remove_voter() -> Weight { // Proof Size summary in bytes: // Measured: `925` // Estimated: `4764` - // Minimum execution time: 50_386_000 picoseconds. - Weight::from_parts(51_378_000, 4764) + // Minimum execution time: 41_882_000 picoseconds. + Weight::from_parts(42_794_000, 4764) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Elections Candidates (r:1 w:1) - /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Members (r:1 w:0) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections RunnersUp (r:1 w:0) - /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Elections::Candidates` (r:1 w:1) + /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Members` (r:1 w:0) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::RunnersUp` (r:1 w:0) + /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `c` is `[1, 64]`. fn submit_candidacy(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `1570 + c * (48 ±0)` // Estimated: `3055 + c * (48 ±0)` - // Minimum execution time: 38_987_000 picoseconds. - Weight::from_parts(41_302_276, 3055) - // Standard Error: 2_047 - .saturating_add(Weight::from_parts(125_200, 0).saturating_mul(c.into())) + // Minimum execution time: 33_719_000 picoseconds. + Weight::from_parts(35_017_073, 3055) + // Standard Error: 1_587 + .saturating_add(Weight::from_parts(121_130, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 48).saturating_mul(c.into())) } - /// Storage: Elections Candidates (r:1 w:1) - /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Elections::Candidates` (r:1 w:1) + /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `c` is `[1, 64]`. fn renounce_candidacy_candidate(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `285 + c * (48 ±0)` // Estimated: `1770 + c * (48 ±0)` - // Minimum execution time: 33_510_000 picoseconds. - Weight::from_parts(34_947_760, 1770) - // Standard Error: 1_781 - .saturating_add(Weight::from_parts(78_851, 0).saturating_mul(c.into())) + // Minimum execution time: 27_263_000 picoseconds. + Weight::from_parts(28_215_666, 1770) + // Standard Error: 1_196 + .saturating_add(Weight::from_parts(86_804, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 48).saturating_mul(c.into())) } - /// Storage: Elections Members (r:1 w:1) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections RunnersUp (r:1 w:1) - /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Prime (r:1 w:1) - /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Proposals (r:1 w:0) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Members (r:0 w:1) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Elections::Members` (r:1 w:1) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::RunnersUp` (r:1 w:1) + /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Prime` (r:1 w:1) + /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Proposals` (r:1 w:0) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Members` (r:0 w:1) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn renounce_candidacy_members() -> Weight { // Proof Size summary in bytes: - // Measured: `1900` - // Estimated: `3385` - // Minimum execution time: 50_603_000 picoseconds. - Weight::from_parts(51_715_000, 3385) + // Measured: `1933` + // Estimated: `3418` + // Minimum execution time: 41_531_000 picoseconds. + Weight::from_parts(42_937_000, 3418) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: Elections RunnersUp (r:1 w:1) - /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Elections::RunnersUp` (r:1 w:1) + /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn renounce_candidacy_runners_up() -> Weight { // Proof Size summary in bytes: // Measured: `880` // Estimated: `2365` - // Minimum execution time: 33_441_000 picoseconds. - Weight::from_parts(34_812_000, 2365) + // Minimum execution time: 27_680_000 picoseconds. + Weight::from_parts(28_810_000, 2365) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Benchmark Override (r:0 w:0) - /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) fn remove_member_without_replacement() -> Weight { // Proof Size summary in bytes: // Measured: `0` @@ -489,87 +491,90 @@ impl WeightInfo for () { // Minimum execution time: 2_000_000_000_000 picoseconds. Weight::from_parts(2_000_000_000_000, 0) } - /// Storage: Elections Members (r:1 w:1) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Elections RunnersUp (r:1 w:1) - /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Prime (r:1 w:1) - /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Proposals (r:1 w:0) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Members (r:0 w:1) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Elections::Members` (r:1 w:1) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Elections::RunnersUp` (r:1 w:1) + /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Prime` (r:1 w:1) + /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Proposals` (r:1 w:0) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Members` (r:0 w:1) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn remove_member_with_replacement() -> Weight { // Proof Size summary in bytes: - // Measured: `1900` + // Measured: `1933` // Estimated: `3593` - // Minimum execution time: 57_289_000 picoseconds. - Weight::from_parts(58_328_000, 3593) + // Minimum execution time: 45_333_000 picoseconds. + Weight::from_parts(46_523_000, 3593) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: Elections Voting (r:513 w:512) - /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Elections Members (r:1 w:0) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections RunnersUp (r:1 w:0) - /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Candidates (r:1 w:0) - /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Balances Locks (r:512 w:512) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:512 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: System Account (r:512 w:512) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Elections::Voting` (r:257 w:256) + /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Members` (r:1 w:0) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::RunnersUp` (r:1 w:0) + /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Candidates` (r:1 w:0) + /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Balances::Locks` (r:256 w:256) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:256 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:256 w:256) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `v` is `[256, 512]`. /// The range of component `d` is `[0, 256]`. - fn clean_defunct_voters(v: u32, _d: u32, ) -> Weight { + fn clean_defunct_voters(v: u32, d: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1149 + v * (811 ±0)` - // Estimated: `4621 + v * (3774 ±0)` - // Minimum execution time: 18_774_231_000 picoseconds. - Weight::from_parts(18_933_040_000, 4621) - // Standard Error: 301_534 - .saturating_add(Weight::from_parts(44_306_903, 0).saturating_mul(v.into())) + // Measured: `0 + d * (818 ±0) + v * (57 ±0)` + // Estimated: `24906 + d * (3774 ±1) + v * (24 ±0)` + // Minimum execution time: 5_620_000 picoseconds. + Weight::from_parts(5_817_000, 24906) + // Standard Error: 18_357 + .saturating_add(Weight::from_parts(106_164, 0).saturating_mul(v.into())) + // Standard Error: 39_980 + .saturating_add(Weight::from_parts(52_456_337, 0).saturating_mul(d.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().reads((4_u64).saturating_mul(v.into()))) - .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(v.into()))) - .saturating_add(Weight::from_parts(0, 3774).saturating_mul(v.into())) + .saturating_add(RocksDbWeight::get().reads((4_u64).saturating_mul(d.into()))) + .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(d.into()))) + .saturating_add(Weight::from_parts(0, 3774).saturating_mul(d.into())) + .saturating_add(Weight::from_parts(0, 24).saturating_mul(v.into())) } - /// Storage: Elections Candidates (r:1 w:1) - /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Members (r:1 w:1) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections RunnersUp (r:1 w:1) - /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Elections Voting (r:513 w:0) - /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) - /// Storage: Council Proposals (r:1 w:0) - /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: System Account (r:44 w:44) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Elections ElectionRounds (r:1 w:1) - /// Proof Skipped: Elections ElectionRounds (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Members (r:0 w:1) - /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Council Prime (r:0 w:1) - /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `Elections::Candidates` (r:1 w:1) + /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Members` (r:1 w:1) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::RunnersUp` (r:1 w:1) + /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Voting` (r:513 w:0) + /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Council::Proposals` (r:1 w:0) + /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:44 w:44) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Elections::ElectionRounds` (r:1 w:1) + /// Proof: `Elections::ElectionRounds` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Members` (r:0 w:1) + /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Council::Prime` (r:0 w:1) + /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `c` is `[1, 64]`. /// The range of component `v` is `[1, 512]`. /// The range of component `e` is `[512, 8192]`. fn election_phragmen(c: u32, v: u32, e: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + e * (28 ±0) + v * (606 ±0)` - // Estimated: `178887 + c * (2135 ±7) + e * (12 ±0) + v * (2653 ±6)` - // Minimum execution time: 1_281_877_000 picoseconds. - Weight::from_parts(1_288_147_000, 178887) - // Standard Error: 528_851 - .saturating_add(Weight::from_parts(17_761_407, 0).saturating_mul(v.into())) - // Standard Error: 33_932 - .saturating_add(Weight::from_parts(698_277, 0).saturating_mul(e.into())) + // Estimated: `178920 + c * (2135 ±7) + e * (12 ±0) + v * (2653 ±6)` + // Minimum execution time: 1_082_582_000 picoseconds. + Weight::from_parts(1_084_730_000, 178920) + // Standard Error: 594_096 + .saturating_add(Weight::from_parts(19_096_288, 0).saturating_mul(v.into())) + // Standard Error: 38_118 + .saturating_add(Weight::from_parts(792_945, 0).saturating_mul(e.into())) .saturating_add(RocksDbWeight::get().reads(21_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(c.into()))) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(v.into()))) diff --git a/substrate/frame/examples/basic/src/lib.rs b/substrate/frame/examples/basic/src/lib.rs index 12cadc969fd..94b2f276e00 100644 --- a/substrate/frame/examples/basic/src/lib.rs +++ b/substrate/frame/examples/basic/src/lib.rs @@ -46,9 +46,10 @@ //! use the [`Config::WeightInfo`] trait to calculate call weights. This can also be overridden, //! as demonstrated by [`Call::set_dummy`]. //! - A private function that performs a storage update. -//! - A simple signed extension implementation (see: [`sp_runtime::traits::SignedExtension`]) which -//! increases the priority of the [`Call::set_dummy`] if it's present and drops any transaction -//! with an encoded length higher than 200 bytes. +//! - A simple transaction extension implementation (see: +//! [`sp_runtime::traits::TransactionExtension`]) which increases the priority of the +//! [`Call::set_dummy`] if it's present and drops any transaction with an encoded length higher +//! than 200 bytes. // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] @@ -64,10 +65,12 @@ use frame_system::ensure_signed; use log::info; use scale_info::TypeInfo; use sp_runtime::{ - traits::{Bounded, DispatchInfoOf, SaturatedConversion, Saturating, SignedExtension}, - transaction_validity::{ - InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction, + impl_tx_ext_default, + traits::{ + Bounded, DispatchInfoOf, OriginOf, SaturatedConversion, Saturating, TransactionExtension, + TransactionExtensionBase, ValidateResult, }, + transaction_validity::{InvalidTransaction, ValidTransaction}, }; use sp_std::vec::Vec; @@ -440,8 +443,8 @@ impl Pallet { // Similar to other FRAME pallets, your pallet can also define a signed extension and perform some // checks and [pre/post]processing [before/after] the transaction. A signed extension can be any -// decodable type that implements `SignedExtension`. See the trait definition for the full list of -// bounds. As a convention, you can follow this approach to create an extension for your pallet: +// decodable type that implements `TransactionExtension`. See the trait definition for the full list +// of bounds. As a convention, you can follow this approach to create an extension for your pallet: // - If the extension does not carry any data, then use a tuple struct with just a `marker` // (needed for the compiler to accept `T: Config`) will suffice. // - Otherwise, create a tuple struct which contains the external data. Of course, for the entire @@ -455,18 +458,18 @@ impl Pallet { // // Using the extension, you can add some hooks to the life cycle of each transaction. Note that by // default, an extension is applied to all `Call` functions (i.e. all transactions). the `Call` enum -// variant is given to each function of `SignedExtension`. Hence, you can filter based on pallet or -// a particular call if needed. +// variant is given to each function of `TransactionExtension`. Hence, you can filter based on +// pallet or a particular call if needed. // // Some extra information, such as encoded length, some static dispatch info like weight and the // sender of the transaction (if signed) are also provided. // // The full list of hooks that can be added to a signed extension can be found -// [here](https://paritytech.github.io/polkadot-sdk/master/sp_runtime/traits/trait.SignedExtension.html). +// [here](https://paritytech.github.io/polkadot-sdk/master/sp_runtime/traits/trait.TransactionExtension.html). // // The signed extensions are aggregated in the runtime file of a substrate chain. All extensions // should be aggregated in a tuple and passed to the `CheckedExtrinsic` and `UncheckedExtrinsic` -// types defined in the runtime. Lookup `pub type SignedExtra = (...)` in `node/runtime` and +// types defined in the runtime. Lookup `pub type TxExtension = (...)` in `node/runtime` and // `node-template` for an example of this. /// A simple signed extension that checks for the `set_dummy` call. In that case, it increases the @@ -484,52 +487,45 @@ impl core::fmt::Debug for WatchDummy { } } -impl SignedExtension for WatchDummy +impl TransactionExtensionBase for WatchDummy { + const IDENTIFIER: &'static str = "WatchDummy"; + type Implicit = (); +} +impl + TransactionExtension<::RuntimeCall, Context> for WatchDummy where ::RuntimeCall: IsSubType>, { - const IDENTIFIER: &'static str = "WatchDummy"; - type AccountId = T::AccountId; - type Call = ::RuntimeCall; - type AdditionalSigned = (); type Pre = (); - - fn additional_signed(&self) -> core::result::Result<(), TransactionValidityError> { - Ok(()) - } - - fn pre_dispatch( - self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> Result { - self.validate(who, call, info, len).map(|_| ()) - } + type Val = (); fn validate( &self, - _who: &Self::AccountId, - call: &Self::Call, - _info: &DispatchInfoOf, + origin: OriginOf<::RuntimeCall>, + call: &::RuntimeCall, + _info: &DispatchInfoOf<::RuntimeCall>, len: usize, - ) -> TransactionValidity { + _context: &mut Context, + _self_implicit: Self::Implicit, + _inherited_implication: &impl Encode, + ) -> ValidateResult::RuntimeCall> { // if the transaction is too big, just drop it. if len > 200 { - return InvalidTransaction::ExhaustsResources.into() + return Err(InvalidTransaction::ExhaustsResources.into()) } // check for `set_dummy` - match call.is_sub_type() { + let validity = match call.is_sub_type() { Some(Call::set_dummy { .. }) => { sp_runtime::print("set_dummy was received."); let valid_tx = ValidTransaction { priority: Bounded::max_value(), ..Default::default() }; - Ok(valid_tx) + valid_tx }, - _ => Ok(Default::default()), - } + _ => Default::default(), + }; + Ok((validity, (), origin)) } + impl_tx_ext_default!(::RuntimeCall; Context; prepare); } diff --git a/substrate/frame/examples/basic/src/tests.rs b/substrate/frame/examples/basic/src/tests.rs index 207e46e428d..e460ad0992f 100644 --- a/substrate/frame/examples/basic/src/tests.rs +++ b/substrate/frame/examples/basic/src/tests.rs @@ -27,7 +27,7 @@ use sp_core::H256; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sp_runtime::{ - traits::{BlakeTwo256, IdentityLookup}, + traits::{BlakeTwo256, DispatchTransaction, IdentityLookup}, BuildStorage, }; // Reexport crate as its pallet name for construct_runtime. @@ -158,13 +158,16 @@ fn signed_ext_watch_dummy_works() { assert_eq!( WatchDummy::(PhantomData) - .validate(&1, &call, &info, 150) + .validate_only(Some(1).into(), &call, &info, 150) .unwrap() + .0 .priority, u64::MAX, ); assert_eq!( - WatchDummy::(PhantomData).validate(&1, &call, &info, 250), + WatchDummy::(PhantomData) + .validate_only(Some(1).into(), &call, &info, 250) + .unwrap_err(), InvalidTransaction::ExhaustsResources.into(), ); }) diff --git a/substrate/frame/examples/offchain-worker/src/tests.rs b/substrate/frame/examples/offchain-worker/src/tests.rs index ea37a2da493..81f2a40840b 100644 --- a/substrate/frame/examples/offchain-worker/src/tests.rs +++ b/substrate/frame/examples/offchain-worker/src/tests.rs @@ -30,7 +30,7 @@ use sp_core::{ use sp_keystore::{testing::MemoryKeystore, Keystore, KeystoreExt}; use sp_runtime::{ - testing::TestXt, + generic::UncheckedExtrinsic, traits::{BlakeTwo256, Extrinsic as ExtrinsicT, IdentifyAccount, IdentityLookup, Verify}, RuntimeAppPublic, }; @@ -73,7 +73,7 @@ impl frame_system::Config for Test { type MaxConsumers = ConstU32<16>; } -type Extrinsic = TestXt; +type Extrinsic = UncheckedExtrinsic; type AccountId = <::Signer as IdentifyAccount>::AccountId; impl frame_system::offchain::SigningTypes for Test { @@ -99,7 +99,7 @@ where _account: AccountId, nonce: u64, ) -> Option<(RuntimeCall, ::SignaturePayload)> { - Some((call, (nonce, ()))) + Some((call, (nonce, (), ()))) } } @@ -219,8 +219,8 @@ fn should_submit_signed_transaction_on_chain() { let tx = pool_state.write().transactions.pop().unwrap(); assert!(pool_state.read().transactions.is_empty()); let tx = Extrinsic::decode(&mut &*tx).unwrap(); - assert_eq!(tx.signature.unwrap().0, 0); - assert_eq!(tx.call, RuntimeCall::Example(crate::Call::submit_price { price: 15523 })); + assert!(matches!(tx.preamble, sp_runtime::generic::Preamble::Signed(0, (), ()))); + assert_eq!(tx.function, RuntimeCall::Example(crate::Call::submit_price { price: 15523 })); }); } @@ -259,11 +259,11 @@ fn should_submit_unsigned_transaction_on_chain_for_any_account() { // then let tx = pool_state.write().transactions.pop().unwrap(); let tx = Extrinsic::decode(&mut &*tx).unwrap(); - assert_eq!(tx.signature, None); + assert!(tx.is_inherent()); if let RuntimeCall::Example(crate::Call::submit_price_unsigned_with_signed_payload { price_payload: body, signature, - }) = tx.call + }) = tx.function { assert_eq!(body, price_payload); @@ -313,11 +313,11 @@ fn should_submit_unsigned_transaction_on_chain_for_all_accounts() { // then let tx = pool_state.write().transactions.pop().unwrap(); let tx = Extrinsic::decode(&mut &*tx).unwrap(); - assert_eq!(tx.signature, None); + assert!(tx.is_inherent()); if let RuntimeCall::Example(crate::Call::submit_price_unsigned_with_signed_payload { price_payload: body, signature, - }) = tx.call + }) = tx.function { assert_eq!(body, price_payload); @@ -353,9 +353,9 @@ fn should_submit_raw_unsigned_transaction_on_chain() { let tx = pool_state.write().transactions.pop().unwrap(); assert!(pool_state.read().transactions.is_empty()); let tx = Extrinsic::decode(&mut &*tx).unwrap(); - assert_eq!(tx.signature, None); + assert!(tx.is_inherent()); assert_eq!( - tx.call, + tx.function, RuntimeCall::Example(crate::Call::submit_price_unsigned { block_number: 1, price: 15523 diff --git a/substrate/frame/examples/tasks/src/weights.rs b/substrate/frame/examples/tasks/src/weights.rs index 793af6e9622..c9ddea6f9a8 100644 --- a/substrate/frame/examples/tasks/src/weights.rs +++ b/substrate/frame/examples/tasks/src/weights.rs @@ -15,30 +15,31 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_example_tasks` +//! Autogenerated weights for `tasks_example` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-02, STEPS: `20`, REPEAT: `10`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `MacBook.local`, CPU: `` -//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/release/node-template +// ./target/production/substrate-node // benchmark // pallet -// --chain -// dev -// --pallet -// pallet_example_tasks -// --extrinsic -// * -// --steps -// 20 -// --repeat -// 10 -// --output -// frame/examples/tasks/src/weights.rs +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=tasks_example +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./substrate/frame/examples/tasks/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -48,37 +49,42 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_template. +/// Weight functions needed for `tasks_example`. pub trait WeightInfo { fn add_number_into_total() -> Weight; } -/// Weight functions for `pallet_example_kitchensink`. +/// Weights for `tasks_example` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Kitchensink OtherFoo (r:0 w:1) - /// Proof Skipped: Kitchensink OtherFoo (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `TasksExample::Numbers` (r:1 w:1) + /// Proof: `TasksExample::Numbers` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `TasksExample::Total` (r:1 w:1) + /// Proof: `TasksExample::Total` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn add_number_into_total() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_000_000 picoseconds. - Weight::from_parts(1_000_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(T::DbWeight::get().writes(1)) + // Measured: `149` + // Estimated: `3614` + // Minimum execution time: 5_776_000 picoseconds. + Weight::from_parts(6_178_000, 3614) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) } } +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Kitchensink OtherFoo (r:0 w:1) - /// Proof Skipped: Kitchensink OtherFoo (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `TasksExample::Numbers` (r:1 w:1) + /// Proof: `TasksExample::Numbers` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `TasksExample::Total` (r:1 w:1) + /// Proof: `TasksExample::Total` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn add_number_into_total() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_000_000 picoseconds. - Weight::from_parts(1_000_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(RocksDbWeight::get().writes(1)) + // Measured: `149` + // Estimated: `3614` + // Minimum execution time: 5_776_000 picoseconds. + Weight::from_parts(6_178_000, 3614) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } } diff --git a/substrate/frame/executive/src/tests.rs b/substrate/frame/executive/src/tests.rs index 70b55f6e855..a3f70a9fc3c 100644 --- a/substrate/frame/executive/src/tests.rs +++ b/substrate/frame/executive/src/tests.rs @@ -327,10 +327,42 @@ impl frame_system::Config for Runtime { type Balance = u64; +pub struct BalancesWeights; +impl pallet_balances::WeightInfo for BalancesWeights { + fn transfer_allow_death() -> Weight { + Weight::from_parts(25, 0) + } + fn transfer_keep_alive() -> Weight { + Weight::zero() + } + fn force_set_balance_creating() -> Weight { + Weight::zero() + } + fn force_set_balance_killing() -> Weight { + Weight::zero() + } + fn force_transfer() -> Weight { + Weight::zero() + } + fn transfer_all() -> Weight { + Weight::zero() + } + fn force_unreserve() -> Weight { + Weight::zero() + } + fn upgrade_accounts(_u: u32) -> Weight { + Weight::zero() + } + fn force_adjust_total_issuance() -> Weight { + Weight::zero() + } +} + #[derive_impl(pallet_balances::config_preludes::TestDefaultConfig as pallet_balances::DefaultConfig)] impl pallet_balances::Config for Runtime { type Balance = Balance; type AccountStore = System; + type WeightInfo = BalancesWeights; } parameter_types! { @@ -343,6 +375,7 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = IdentityFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = (); + type WeightInfo = (); } impl custom::Config for Runtime {} @@ -355,19 +388,46 @@ impl frame_support::traits::Get for RuntimeVersion { } } +#[derive(Clone, Debug, Encode, codec::Decode, PartialEq, Eq, scale_info::TypeInfo)] +pub struct AccountU64(u64); +impl sp_runtime::traits::IdentifyAccount for AccountU64 { + type AccountId = u64; + fn into_account(self) -> u64 { + self.0 + } +} + +impl sp_runtime::traits::Verify for AccountU64 { + type Signer = AccountU64; + fn verify>( + &self, + _msg: L, + _signer: &::AccountId, + ) -> bool { + true + } +} + +impl From for AccountU64 { + fn from(value: u64) -> Self { + Self(value) + } +} + parameter_types! { pub static RuntimeVersionTestValues: sp_version::RuntimeVersion = Default::default(); } -type SignedExtra = ( +type TxExtension = ( frame_system::CheckEra, frame_system::CheckNonce, frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, ); -type TestXt = sp_runtime::testing::TestXt; -type TestBlock = Block; +type UncheckedXt = + sp_runtime::generic::UncheckedExtrinsic; +type TestBlock = Block; // Will contain `true` when the custom runtime logic was called. const CUSTOM_ON_RUNTIME_KEY: &[u8] = b":custom:on_runtime"; @@ -387,7 +447,7 @@ impl OnRuntimeUpgrade for CustomOnRuntimeUpgrade { type Executive = super::Executive< Runtime, - Block, + Block, ChainContext, Runtime, AllPalletsWithSystem, @@ -462,17 +522,14 @@ impl MultiStepMigrator for MockedModeGetter { } } -fn extra(nonce: u64, fee: Balance) -> SignedExtra { +fn tx_ext(nonce: u64, fee: Balance) -> TxExtension { ( frame_system::CheckEra::from(Era::Immortal), frame_system::CheckNonce::from(nonce), frame_system::CheckWeight::new(), pallet_transaction_payment::ChargeTransactionPayment::from(fee), ) -} - -fn sign_extra(who: u64, nonce: u64, fee: Balance) -> Option<(u64, SignedExtra)> { - Some((who, extra(nonce, fee))) + .into() } fn call_transfer(dest: u64, value: u64) -> RuntimeCall { @@ -485,7 +542,7 @@ fn balance_transfer_dispatch_works() { pallet_balances::GenesisConfig:: { balances: vec![(1, 211)] } .assimilate_storage(&mut t) .unwrap(); - let xt = TestXt::new(call_transfer(2, 69), sign_extra(1, 0, 0)); + let xt = UncheckedXt::new_signed(call_transfer(2, 69), 1, 1.into(), tx_ext(0, 0)); let weight = xt.get_dispatch_info().weight + ::BlockWeights::get() .get(DispatchClass::Normal) @@ -596,7 +653,7 @@ fn block_import_of_bad_extrinsic_root_fails() { fn bad_extrinsic_not_inserted() { let mut t = new_test_ext(1); // bad nonce check! - let xt = TestXt::new(call_transfer(33, 69), sign_extra(1, 30, 0)); + let xt = UncheckedXt::new_signed(call_transfer(33, 69), 1, 1.into(), tx_ext(30, 0)); t.execute_with(|| { Executive::initialize_block(&Header::new_from_number(1)); assert_err!( @@ -610,27 +667,24 @@ fn bad_extrinsic_not_inserted() { #[test] fn block_weight_limit_enforced() { let mut t = new_test_ext(10000); - // given: TestXt uses the encoded len as fixed Len: - let xt = TestXt::new( - RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - sign_extra(1, 0, 0), - ); - let encoded = xt.encode(); - let encoded_len = encoded.len() as u64; + let transfer_weight = + <::WeightInfo as pallet_balances::WeightInfo>::transfer_allow_death(); // on_initialize weight + base block execution weight let block_weights = ::BlockWeights::get(); let base_block_weight = Weight::from_parts(175, 0) + block_weights.base_block; let limit = block_weights.get(DispatchClass::Normal).max_total.unwrap() - base_block_weight; - let num_to_exhaust_block = limit.ref_time() / (encoded_len + 5); + let num_to_exhaust_block = limit.ref_time() / (transfer_weight.ref_time() + 5); t.execute_with(|| { Executive::initialize_block(&Header::new_from_number(1)); // Base block execution weight + `on_initialize` weight from the custom module. assert_eq!(>::block_weight().total(), base_block_weight); for nonce in 0..=num_to_exhaust_block { - let xt = TestXt::new( + let xt = UncheckedXt::new_signed( RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - sign_extra(1, nonce.into(), 0), + 1, + 1.into(), + tx_ext(nonce.into(), 0), ); let res = Executive::apply_extrinsic(xt); if nonce != num_to_exhaust_block { @@ -638,7 +692,8 @@ fn block_weight_limit_enforced() { assert_eq!( >::block_weight().total(), //--------------------- on_initialize + block_execution + extrinsic_base weight - Weight::from_parts((encoded_len + 5) * (nonce + 1), 0) + base_block_weight, + Weight::from_parts((transfer_weight.ref_time() + 5) * (nonce + 1), 0) + + base_block_weight, ); assert_eq!( >::extrinsic_index(), @@ -653,19 +708,26 @@ fn block_weight_limit_enforced() { #[test] fn block_weight_and_size_is_stored_per_tx() { - let xt = TestXt::new( + let xt = UncheckedXt::new_signed( RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - sign_extra(1, 0, 0), + 1, + 1.into(), + tx_ext(0, 0), ); - let x1 = TestXt::new( + let x1 = UncheckedXt::new_signed( RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - sign_extra(1, 1, 0), + 1, + 1.into(), + tx_ext(1, 0), ); - let x2 = TestXt::new( + let x2 = UncheckedXt::new_signed( RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - sign_extra(1, 2, 0), + 1, + 1.into(), + tx_ext(2, 0), ); let len = xt.clone().encode().len() as u32; + let transfer_weight = <::WeightInfo as pallet_balances::WeightInfo>::transfer_allow_death(); let mut t = new_test_ext(1); t.execute_with(|| { // Block execution weight + on_initialize weight from custom module @@ -681,8 +743,7 @@ fn block_weight_and_size_is_stored_per_tx() { assert!(Executive::apply_extrinsic(x1.clone()).unwrap().is_ok()); assert!(Executive::apply_extrinsic(x2.clone()).unwrap().is_ok()); - // default weight for `TestXt` == encoded length. - let extrinsic_weight = Weight::from_parts(len as u64, 0) + + let extrinsic_weight = transfer_weight + ::BlockWeights::get() .get(DispatchClass::Normal) .base_extrinsic; @@ -707,8 +768,8 @@ fn block_weight_and_size_is_stored_per_tx() { #[test] fn validate_unsigned() { - let valid = TestXt::new(RuntimeCall::Custom(custom::Call::allowed_unsigned {}), None); - let invalid = TestXt::new(RuntimeCall::Custom(custom::Call::unallowed_unsigned {}), None); + let valid = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::allowed_unsigned {})); + let invalid = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::unallowed_unsigned {})); let mut t = new_test_ext(1); t.execute_with(|| { @@ -745,9 +806,11 @@ fn can_not_pay_for_tx_fee_on_full_lock() { t.execute_with(|| { as fungible::MutateFreeze>::set_freeze(&(), &1, 110) .unwrap(); - let xt = TestXt::new( + let xt = UncheckedXt::new_signed( RuntimeCall::System(frame_system::Call::remark { remark: vec![1u8] }), - sign_extra(1, 0, 0), + 1, + 1.into(), + tx_ext(0, 0), ); Executive::initialize_block(&Header::new_from_number(1)); @@ -872,9 +935,11 @@ fn event_from_runtime_upgrade_is_included() { /// used through the `ExecuteBlock` trait. #[test] fn custom_runtime_upgrade_is_called_when_using_execute_block_trait() { - let xt = TestXt::new( + let xt = UncheckedXt::new_signed( RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - sign_extra(1, 0, 0), + 1, + 1.into(), + tx_ext(0, 0), ); let header = new_test_ext(1).execute_with(|| { @@ -902,7 +967,10 @@ fn custom_runtime_upgrade_is_called_when_using_execute_block_trait() { *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } }); - >>::execute_block(Block::new(header, vec![xt])); + >>::execute_block(Block::new( + header, + vec![xt], + )); assert_eq!(&sp_io::storage::get(TEST_KEY).unwrap()[..], *b"module"); assert_eq!(sp_io::storage::get(CUSTOM_ON_RUNTIME_KEY).unwrap(), true.encode()); @@ -968,7 +1036,7 @@ fn offchain_worker_works_as_expected() { #[test] fn calculating_storage_root_twice_works() { let call = RuntimeCall::Custom(custom::Call::calculate_storage_root {}); - let xt = TestXt::new(call, sign_extra(1, 0, 0)); + let xt = UncheckedXt::new_signed(call, 1, 1.into(), tx_ext(0, 0)); let header = new_test_ext(1).execute_with(|| { // Let's build some fake block. @@ -987,11 +1055,13 @@ fn calculating_storage_root_twice_works() { #[test] #[should_panic(expected = "Invalid inherent position for extrinsic at index 1")] fn invalid_inherent_position_fail() { - let xt1 = TestXt::new( + let xt1 = UncheckedXt::new_signed( RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - sign_extra(1, 0, 0), + 1, + 1.into(), + tx_ext(0, 0), ); - let xt2 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let xt2 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})); let header = new_test_ext(1).execute_with(|| { // Let's build some fake block. @@ -1010,8 +1080,8 @@ fn invalid_inherent_position_fail() { #[test] fn valid_inherents_position_works() { - let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); - let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})); + let xt2 = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0)); let header = new_test_ext(1).execute_with(|| { // Let's build some fake block. @@ -1031,7 +1101,12 @@ fn valid_inherents_position_works() { #[test] #[should_panic(expected = "A call was labelled as mandatory, but resulted in an Error.")] fn invalid_inherents_fail_block_execution() { - let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), sign_extra(1, 0, 0)); + let xt1 = UncheckedXt::new_signed( + RuntimeCall::Custom(custom::Call::inherent {}), + 1, + 1.into(), + tx_ext(0, 0), + ); new_test_ext(1).execute_with(|| { Executive::execute_block(Block::new( @@ -1044,7 +1119,7 @@ fn invalid_inherents_fail_block_execution() { // Inherents are created by the runtime and don't need to be validated. #[test] fn inherents_fail_validate_block() { - let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})); new_test_ext(1).execute_with(|| { assert_eq!( @@ -1058,7 +1133,7 @@ fn inherents_fail_validate_block() { /// Inherents still work while `initialize_block` forbids transactions. #[test] fn inherents_ok_while_exts_forbidden_works() { - let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})); let header = new_test_ext(1).execute_with(|| { Executive::initialize_block(&Header::new_from_number(1)); @@ -1078,8 +1153,8 @@ fn inherents_ok_while_exts_forbidden_works() { #[test] #[should_panic = "Only inherents are allowed in this block"] fn transactions_in_only_inherents_block_errors() { - let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); - let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})); + let xt2 = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0)); let header = new_test_ext(1).execute_with(|| { Executive::initialize_block(&Header::new_from_number(1)); @@ -1099,8 +1174,8 @@ fn transactions_in_only_inherents_block_errors() { /// Same as above but no error. #[test] fn transactions_in_normal_block_works() { - let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); - let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})); + let xt2 = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0)); let header = new_test_ext(1).execute_with(|| { Executive::initialize_block(&Header::new_from_number(1)); @@ -1120,8 +1195,8 @@ fn transactions_in_normal_block_works() { #[test] #[cfg(feature = "try-runtime")] fn try_execute_block_works() { - let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); - let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})); + let xt2 = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0)); let header = new_test_ext(1).execute_with(|| { Executive::initialize_block(&Header::new_from_number(1)); @@ -1148,8 +1223,8 @@ fn try_execute_block_works() { #[cfg(feature = "try-runtime")] #[should_panic = "Only inherents allowed"] fn try_execute_tx_forbidden_errors() { - let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); - let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})); + let xt2 = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0)); let header = new_test_ext(1).execute_with(|| { // Let's build some fake block. @@ -1176,9 +1251,9 @@ fn try_execute_tx_forbidden_errors() { /// Check that `ensure_inherents_are_first` reports the correct indices. #[test] fn ensure_inherents_are_first_works() { - let in1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); - let in2 = TestXt::new(RuntimeCall::Custom2(custom2::Call::inherent {}), None); - let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + let in1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})); + let in2 = UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::inherent {})); + let xt2 = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0)); // Mocked empty header: let header = new_test_ext(1).execute_with(|| { @@ -1256,18 +1331,20 @@ fn callbacks_in_block_execution_works_inner(mbms_active: bool) { for i in 0..n_in { let xt = if i % 2 == 0 { - TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None) + UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})) } else { - TestXt::new(RuntimeCall::Custom2(custom2::Call::optional_inherent {}), None) + UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::optional_inherent {})) }; Executive::apply_extrinsic(xt.clone()).unwrap().unwrap(); extrinsics.push(xt); } for t in 0..n_tx { - let xt = TestXt::new( + let xt = UncheckedXt::new_signed( RuntimeCall::Custom2(custom2::Call::some_call {}), - sign_extra(1, t as u64, 0), + 1, + 1.into(), + tx_ext(t as u64, 0), ); // Extrinsics can be applied even when MBMs are active. Only the `execute_block` // will reject it. @@ -1307,8 +1384,13 @@ fn callbacks_in_block_execution_works_inner(mbms_active: bool) { #[test] fn post_inherent_called_after_all_inherents() { - let in1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::inherent {}), None); - let xt1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::some_call {}), sign_extra(1, 0, 0)); + let in1 = UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::inherent {})); + let xt1 = UncheckedXt::new_signed( + RuntimeCall::Custom2(custom2::Call::some_call {}), + 1, + 1.into(), + tx_ext(0, 0), + ); let header = new_test_ext(1).execute_with(|| { // Let's build some fake block. @@ -1342,8 +1424,13 @@ fn post_inherent_called_after_all_inherents() { /// Regression test for AppSec finding #40. #[test] fn post_inherent_called_after_all_optional_inherents() { - let in1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::optional_inherent {}), None); - let xt1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::some_call {}), sign_extra(1, 0, 0)); + let in1 = UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::optional_inherent {})); + let xt1 = UncheckedXt::new_signed( + RuntimeCall::Custom2(custom2::Call::some_call {}), + 1, + 1.into(), + tx_ext(0, 0), + ); let header = new_test_ext(1).execute_with(|| { // Let's build some fake block. @@ -1376,14 +1463,14 @@ fn post_inherent_called_after_all_optional_inherents() { #[test] fn is_inherent_works() { - let ext = TestXt::new(RuntimeCall::Custom2(custom2::Call::inherent {}), None); + let ext = UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::inherent {})); assert!(Runtime::is_inherent(&ext)); - let ext = TestXt::new(RuntimeCall::Custom2(custom2::Call::optional_inherent {}), None); + let ext = UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::optional_inherent {})); assert!(Runtime::is_inherent(&ext)); - let ext = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + let ext = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0)); assert!(!Runtime::is_inherent(&ext)); - let ext = TestXt::new(RuntimeCall::Custom2(custom2::Call::allowed_unsigned {}), None); + let ext = UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::allowed_unsigned {})); assert!(!Runtime::is_inherent(&ext), "Unsigned ext are not automatically inherents"); } diff --git a/substrate/frame/fast-unstake/src/weights.rs b/substrate/frame/fast-unstake/src/weights.rs index 9c25a409f74..d783ba921bf 100644 --- a/substrate/frame/fast-unstake/src/weights.rs +++ b/substrate/frame/fast-unstake/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_fast_unstake +//! Autogenerated weights for `pallet_fast_unstake` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/fast-unstake/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/fast-unstake/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_fast_unstake. +/// Weight functions needed for `pallet_fast_unstake`. pub trait WeightInfo { fn on_idle_unstake(b: u32, ) -> Weight; fn on_idle_check(v: u32, b: u32, ) -> Weight; @@ -59,301 +58,305 @@ pub trait WeightInfo { fn control() -> Weight; } -/// Weights for pallet_fast_unstake using the Substrate node and recommended hardware. +/// Weights for `pallet_fast_unstake` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) - /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Staking ValidatorCount (r:1 w:0) - /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: FastUnstake Head (r:1 w:1) - /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(5768), added: 6263, mode: MaxEncodedLen) - /// Storage: FastUnstake CounterForQueue (r:1 w:0) - /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Staking CurrentEra (r:1 w:0) - /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Staking SlashingSpans (r:64 w:0) - /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) - /// Storage: Staking Bonded (r:64 w:64) - /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) - /// Storage: Staking Validators (r:64 w:0) - /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) - /// Storage: Staking Nominators (r:64 w:0) - /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) - /// Storage: System Account (r:64 w:64) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:64 w:64) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:64 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: Staking Ledger (r:0 w:64) - /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) - /// Storage: Staking Payee (r:0 w:64) - /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0) + /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::ValidatorCount` (r:1 w:0) + /// Proof: `Staking::ValidatorCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::Head` (r:1 w:1) + /// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::CounterForQueue` (r:1 w:0) + /// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Staking::CurrentEra` (r:1 w:0) + /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::SlashingSpans` (r:64 w:0) + /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Staking::Bonded` (r:64 w:64) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `Staking::Ledger` (r:64 w:64) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:64 w:64) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:64 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:64 w:64) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:64 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:64 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `Staking::Payee` (r:0 w:64) + /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// The range of component `b` is `[1, 64]`. fn on_idle_unstake(b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1378 + b * (343 ±0)` + // Measured: `1475 + b * (452 ±0)` // Estimated: `7253 + b * (3774 ±0)` - // Minimum execution time: 92_847_000 picoseconds. - Weight::from_parts(42_300_813, 7253) - // Standard Error: 40_514 - .saturating_add(Weight::from_parts(58_412_402, 0).saturating_mul(b.into())) + // Minimum execution time: 89_005_000 picoseconds. + Weight::from_parts(50_257_055, 7253) + // Standard Error: 68_836 + .saturating_add(Weight::from_parts(57_329_950, 0).saturating_mul(b.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) - .saturating_add(T::DbWeight::get().reads((7_u64).saturating_mul(b.into()))) + .saturating_add(T::DbWeight::get().reads((8_u64).saturating_mul(b.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(T::DbWeight::get().writes((5_u64).saturating_mul(b.into()))) .saturating_add(Weight::from_parts(0, 3774).saturating_mul(b.into())) } - /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) - /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Staking ValidatorCount (r:1 w:0) - /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: FastUnstake Head (r:1 w:1) - /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(5768), added: 6263, mode: MaxEncodedLen) - /// Storage: FastUnstake CounterForQueue (r:1 w:0) - /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Staking CurrentEra (r:1 w:0) - /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Staking ErasStakers (r:257 w:0) - /// Proof Skipped: Staking ErasStakers (max_values: None, max_size: None, mode: Measured) + /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0) + /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::ValidatorCount` (r:1 w:0) + /// Proof: `Staking::ValidatorCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::Head` (r:1 w:1) + /// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::CounterForQueue` (r:1 w:0) + /// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Staking::CurrentEra` (r:1 w:0) + /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::ErasStakers` (r:1 w:0) + /// Proof: `Staking::ErasStakers` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Staking::ErasStakersPaged` (r:257 w:0) + /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `v` is `[1, 256]`. /// The range of component `b` is `[1, 64]`. fn on_idle_check(v: u32, b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1546 + b * (48 ±0) + v * (10037 ±0)` - // Estimated: `7253 + b * (49 ±0) + v * (12513 ±0)` - // Minimum execution time: 1_685_784_000 picoseconds. - Weight::from_parts(1_693_370_000, 7253) - // Standard Error: 13_295_842 - .saturating_add(Weight::from_parts(425_349_148, 0).saturating_mul(v.into())) - // Standard Error: 53_198_180 - .saturating_add(Weight::from_parts(1_673_328_444, 0).saturating_mul(b.into())) - .saturating_add(T::DbWeight::get().reads(7_u64)) + // Measured: `1879 + b * (55 ±0) + v * (10055 ±0)` + // Estimated: `7253 + b * (56 ±0) + v * (12531 ±0)` + // Minimum execution time: 1_737_131_000 picoseconds. + Weight::from_parts(1_746_770_000, 7253) + // Standard Error: 13_401_143 + .saturating_add(Weight::from_parts(426_946_450, 0).saturating_mul(v.into())) + // Standard Error: 53_619_501 + .saturating_add(Weight::from_parts(1_664_681_508, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) - .saturating_add(Weight::from_parts(0, 49).saturating_mul(b.into())) - .saturating_add(Weight::from_parts(0, 12513).saturating_mul(v.into())) + .saturating_add(Weight::from_parts(0, 56).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 12531).saturating_mul(v.into())) } - /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) - /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Staking Ledger (r:1 w:1) - /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) - /// Storage: FastUnstake Queue (r:1 w:1) - /// Proof: FastUnstake Queue (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) - /// Storage: FastUnstake Head (r:1 w:0) - /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(5768), added: 6263, mode: MaxEncodedLen) - /// Storage: Staking Bonded (r:1 w:0) - /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) - /// Storage: Staking Validators (r:1 w:0) - /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) - /// Storage: Staking Nominators (r:1 w:1) - /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) - /// Storage: Staking CounterForNominators (r:1 w:1) - /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: VoterList ListNodes (r:1 w:1) - /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) - /// Storage: VoterList ListBags (r:1 w:1) - /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) - /// Storage: VoterList CounterForListNodes (r:1 w:1) - /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Staking CurrentEra (r:1 w:0) - /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: FastUnstake CounterForQueue (r:1 w:1) - /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0) + /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::Ledger` (r:1 w:1) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::Queue` (r:1 w:1) + /// Proof: `FastUnstake::Queue` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::Head` (r:1 w:0) + /// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`) + /// Storage: `Staking::Bonded` (r:1 w:0) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1 w:1) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `Staking::CounterForNominators` (r:1 w:1) + /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:1 w:1) + /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListBags` (r:1 w:1) + /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) + /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) + /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::CurrentEra` (r:1 w:0) + /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::CounterForQueue` (r:1 w:1) + /// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn register_fast_unstake() -> Weight { // Proof Size summary in bytes: - // Measured: `1964` + // Measured: `1955` // Estimated: `7253` - // Minimum execution time: 125_512_000 picoseconds. - Weight::from_parts(129_562_000, 7253) + // Minimum execution time: 112_632_000 picoseconds. + Weight::from_parts(117_267_000, 7253) .saturating_add(T::DbWeight::get().reads(15_u64)) .saturating_add(T::DbWeight::get().writes(9_u64)) } - /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) - /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Staking Ledger (r:1 w:0) - /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) - /// Storage: FastUnstake Queue (r:1 w:1) - /// Proof: FastUnstake Queue (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) - /// Storage: FastUnstake Head (r:1 w:0) - /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(5768), added: 6263, mode: MaxEncodedLen) - /// Storage: FastUnstake CounterForQueue (r:1 w:1) - /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0) + /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::Ledger` (r:1 w:0) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::Queue` (r:1 w:1) + /// Proof: `FastUnstake::Queue` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::Head` (r:1 w:0) + /// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::CounterForQueue` (r:1 w:1) + /// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn deregister() -> Weight { // Proof Size summary in bytes: - // Measured: `1223` + // Measured: `1251` // Estimated: `7253` - // Minimum execution time: 43_943_000 picoseconds. - Weight::from_parts(45_842_000, 7253) + // Minimum execution time: 39_253_000 picoseconds. + Weight::from_parts(40_053_000, 7253) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: FastUnstake ErasToCheckPerBlock (r:0 w:1) - /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:0 w:1) + /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn control() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_677_000 picoseconds. - Weight::from_parts(2_849_000, 0) + // Minimum execution time: 2_386_000 picoseconds. + Weight::from_parts(2_508_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) - /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Staking ValidatorCount (r:1 w:0) - /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: FastUnstake Head (r:1 w:1) - /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(5768), added: 6263, mode: MaxEncodedLen) - /// Storage: FastUnstake CounterForQueue (r:1 w:0) - /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Staking CurrentEra (r:1 w:0) - /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Staking SlashingSpans (r:64 w:0) - /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) - /// Storage: Staking Bonded (r:64 w:64) - /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) - /// Storage: Staking Validators (r:64 w:0) - /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) - /// Storage: Staking Nominators (r:64 w:0) - /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) - /// Storage: System Account (r:64 w:64) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:64 w:64) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:64 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: Staking Ledger (r:0 w:64) - /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) - /// Storage: Staking Payee (r:0 w:64) - /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0) + /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::ValidatorCount` (r:1 w:0) + /// Proof: `Staking::ValidatorCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::Head` (r:1 w:1) + /// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::CounterForQueue` (r:1 w:0) + /// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Staking::CurrentEra` (r:1 w:0) + /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::SlashingSpans` (r:64 w:0) + /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Staking::Bonded` (r:64 w:64) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `Staking::Ledger` (r:64 w:64) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:64 w:64) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:64 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:64 w:64) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:64 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:64 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `Staking::Payee` (r:0 w:64) + /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// The range of component `b` is `[1, 64]`. fn on_idle_unstake(b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1378 + b * (343 ±0)` + // Measured: `1475 + b * (452 ±0)` // Estimated: `7253 + b * (3774 ±0)` - // Minimum execution time: 92_847_000 picoseconds. - Weight::from_parts(42_300_813, 7253) - // Standard Error: 40_514 - .saturating_add(Weight::from_parts(58_412_402, 0).saturating_mul(b.into())) + // Minimum execution time: 89_005_000 picoseconds. + Weight::from_parts(50_257_055, 7253) + // Standard Error: 68_836 + .saturating_add(Weight::from_parts(57_329_950, 0).saturating_mul(b.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) - .saturating_add(RocksDbWeight::get().reads((7_u64).saturating_mul(b.into()))) + .saturating_add(RocksDbWeight::get().reads((8_u64).saturating_mul(b.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(RocksDbWeight::get().writes((5_u64).saturating_mul(b.into()))) .saturating_add(Weight::from_parts(0, 3774).saturating_mul(b.into())) } - /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) - /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Staking ValidatorCount (r:1 w:0) - /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: FastUnstake Head (r:1 w:1) - /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(5768), added: 6263, mode: MaxEncodedLen) - /// Storage: FastUnstake CounterForQueue (r:1 w:0) - /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) - /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Staking CurrentEra (r:1 w:0) - /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Staking ErasStakers (r:257 w:0) - /// Proof Skipped: Staking ErasStakers (max_values: None, max_size: None, mode: Measured) + /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0) + /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::ValidatorCount` (r:1 w:0) + /// Proof: `Staking::ValidatorCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::Head` (r:1 w:1) + /// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::CounterForQueue` (r:1 w:0) + /// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) + /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Staking::CurrentEra` (r:1 w:0) + /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::ErasStakers` (r:1 w:0) + /// Proof: `Staking::ErasStakers` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Staking::ErasStakersPaged` (r:257 w:0) + /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `v` is `[1, 256]`. /// The range of component `b` is `[1, 64]`. fn on_idle_check(v: u32, b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1546 + b * (48 ±0) + v * (10037 ±0)` - // Estimated: `7253 + b * (49 ±0) + v * (12513 ±0)` - // Minimum execution time: 1_685_784_000 picoseconds. - Weight::from_parts(1_693_370_000, 7253) - // Standard Error: 13_295_842 - .saturating_add(Weight::from_parts(425_349_148, 0).saturating_mul(v.into())) - // Standard Error: 53_198_180 - .saturating_add(Weight::from_parts(1_673_328_444, 0).saturating_mul(b.into())) - .saturating_add(RocksDbWeight::get().reads(7_u64)) + // Measured: `1879 + b * (55 ±0) + v * (10055 ±0)` + // Estimated: `7253 + b * (56 ±0) + v * (12531 ±0)` + // Minimum execution time: 1_737_131_000 picoseconds. + Weight::from_parts(1_746_770_000, 7253) + // Standard Error: 13_401_143 + .saturating_add(Weight::from_parts(426_946_450, 0).saturating_mul(v.into())) + // Standard Error: 53_619_501 + .saturating_add(Weight::from_parts(1_664_681_508, 0).saturating_mul(b.into())) + .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(v.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) - .saturating_add(Weight::from_parts(0, 49).saturating_mul(b.into())) - .saturating_add(Weight::from_parts(0, 12513).saturating_mul(v.into())) + .saturating_add(Weight::from_parts(0, 56).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 12531).saturating_mul(v.into())) } - /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) - /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Staking Ledger (r:1 w:1) - /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) - /// Storage: FastUnstake Queue (r:1 w:1) - /// Proof: FastUnstake Queue (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) - /// Storage: FastUnstake Head (r:1 w:0) - /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(5768), added: 6263, mode: MaxEncodedLen) - /// Storage: Staking Bonded (r:1 w:0) - /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) - /// Storage: Staking Validators (r:1 w:0) - /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) - /// Storage: Staking Nominators (r:1 w:1) - /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) - /// Storage: Staking CounterForNominators (r:1 w:1) - /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: VoterList ListNodes (r:1 w:1) - /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) - /// Storage: VoterList ListBags (r:1 w:1) - /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) - /// Storage: VoterList CounterForListNodes (r:1 w:1) - /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Staking CurrentEra (r:1 w:0) - /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: FastUnstake CounterForQueue (r:1 w:1) - /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0) + /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::Ledger` (r:1 w:1) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::Queue` (r:1 w:1) + /// Proof: `FastUnstake::Queue` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::Head` (r:1 w:0) + /// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`) + /// Storage: `Staking::Bonded` (r:1 w:0) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) + /// Storage: `Staking::Validators` (r:1 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `Staking::Nominators` (r:1 w:1) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `Staking::CounterForNominators` (r:1 w:1) + /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListNodes` (r:1 w:1) + /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) + /// Storage: `VoterList::ListBags` (r:1 w:1) + /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) + /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) + /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::CurrentEra` (r:1 w:0) + /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::CounterForQueue` (r:1 w:1) + /// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn register_fast_unstake() -> Weight { // Proof Size summary in bytes: - // Measured: `1964` + // Measured: `1955` // Estimated: `7253` - // Minimum execution time: 125_512_000 picoseconds. - Weight::from_parts(129_562_000, 7253) + // Minimum execution time: 112_632_000 picoseconds. + Weight::from_parts(117_267_000, 7253) .saturating_add(RocksDbWeight::get().reads(15_u64)) .saturating_add(RocksDbWeight::get().writes(9_u64)) } - /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) - /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Staking Ledger (r:1 w:0) - /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) - /// Storage: FastUnstake Queue (r:1 w:1) - /// Proof: FastUnstake Queue (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) - /// Storage: FastUnstake Head (r:1 w:0) - /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(5768), added: 6263, mode: MaxEncodedLen) - /// Storage: FastUnstake CounterForQueue (r:1 w:1) - /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0) + /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::Ledger` (r:1 w:0) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::Queue` (r:1 w:1) + /// Proof: `FastUnstake::Queue` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::Head` (r:1 w:0) + /// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`) + /// Storage: `FastUnstake::CounterForQueue` (r:1 w:1) + /// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn deregister() -> Weight { // Proof Size summary in bytes: - // Measured: `1223` + // Measured: `1251` // Estimated: `7253` - // Minimum execution time: 43_943_000 picoseconds. - Weight::from_parts(45_842_000, 7253) + // Minimum execution time: 39_253_000 picoseconds. + Weight::from_parts(40_053_000, 7253) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: FastUnstake ErasToCheckPerBlock (r:0 w:1) - /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:0 w:1) + /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn control() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_677_000 picoseconds. - Weight::from_parts(2_849_000, 0) + // Minimum execution time: 2_386_000 picoseconds. + Weight::from_parts(2_508_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } } diff --git a/substrate/frame/glutton/src/weights.rs b/substrate/frame/glutton/src/weights.rs index cbc0fb022f5..b2e28dc488a 100644 --- a/substrate/frame/glutton/src/weights.rs +++ b/substrate/frame/glutton/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_glutton +//! Autogenerated weights for `pallet_glutton` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/glutton/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/glutton/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_glutton. +/// Weight functions needed for `pallet_glutton`. pub trait WeightInfo { fn initialize_pallet_grow(n: u32, ) -> Weight; fn initialize_pallet_shrink(n: u32, ) -> Weight; @@ -63,39 +62,39 @@ pub trait WeightInfo { fn set_storage() -> Weight; } -/// Weights for pallet_glutton using the Substrate node and recommended hardware. +/// Weights for `pallet_glutton` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Glutton TrashDataCount (r:1 w:1) - /// Proof: Glutton TrashDataCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Glutton TrashData (r:0 w:1000) - /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) + /// Storage: `Glutton::TrashDataCount` (r:1 w:1) + /// Proof: `Glutton::TrashDataCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Glutton::TrashData` (r:0 w:1000) + /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. fn initialize_pallet_grow(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `86` // Estimated: `1489` - // Minimum execution time: 11_488_000 picoseconds. - Weight::from_parts(93_073_710, 1489) - // Standard Error: 22_390 - .saturating_add(Weight::from_parts(9_572_012, 0).saturating_mul(n.into())) + // Minimum execution time: 8_443_000 picoseconds. + Weight::from_parts(103_698_651, 1489) + // Standard Error: 21_777 + .saturating_add(Weight::from_parts(9_529_476, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) } - /// Storage: Glutton TrashDataCount (r:1 w:1) - /// Proof: Glutton TrashDataCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Glutton TrashData (r:0 w:1000) - /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) + /// Storage: `Glutton::TrashDataCount` (r:1 w:1) + /// Proof: `Glutton::TrashDataCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Glutton::TrashData` (r:0 w:1000) + /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. fn initialize_pallet_shrink(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `119` // Estimated: `1489` - // Minimum execution time: 11_378_000 picoseconds. - Weight::from_parts(5_591_508, 1489) - // Standard Error: 1_592 - .saturating_add(Weight::from_parts(1_163_758, 0).saturating_mul(n.into())) + // Minimum execution time: 8_343_000 picoseconds. + Weight::from_parts(304_498, 1489) + // Standard Error: 1_568 + .saturating_add(Weight::from_parts(1_146_553, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) @@ -105,119 +104,119 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 669_000 picoseconds. - Weight::from_parts(990_745, 0) - // Standard Error: 10 - .saturating_add(Weight::from_parts(105_224, 0).saturating_mul(i.into())) + // Minimum execution time: 656_000 picoseconds. + Weight::from_parts(1_875_128, 0) + // Standard Error: 8 + .saturating_add(Weight::from_parts(103_381, 0).saturating_mul(i.into())) } - /// Storage: Glutton TrashData (r:5000 w:0) - /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) + /// Storage: `Glutton::TrashData` (r:5000 w:0) + /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) /// The range of component `i` is `[0, 5000]`. fn waste_proof_size_some(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `119114 + i * (1022 ±0)` // Estimated: `990 + i * (3016 ±0)` - // Minimum execution time: 435_000 picoseconds. - Weight::from_parts(66_547_542, 990) - // Standard Error: 4_557 - .saturating_add(Weight::from_parts(5_851_324, 0).saturating_mul(i.into())) + // Minimum execution time: 454_000 picoseconds. + Weight::from_parts(521_000, 990) + // Standard Error: 1_940 + .saturating_add(Weight::from_parts(5_729_831, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 3016).saturating_mul(i.into())) } - /// Storage: Glutton Storage (r:1 w:0) - /// Proof: Glutton Storage (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Glutton Compute (r:1 w:0) - /// Proof: Glutton Compute (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Glutton TrashData (r:1737 w:0) - /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) + /// Storage: `Glutton::Storage` (r:1 w:0) + /// Proof: `Glutton::Storage` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Glutton::Compute` (r:1 w:0) + /// Proof: `Glutton::Compute` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Glutton::TrashData` (r:1737 w:0) + /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) fn on_idle_high_proof_waste() -> Weight { // Proof Size summary in bytes: // Measured: `1900497` // Estimated: `5239782` - // Minimum execution time: 67_699_845_000 picoseconds. - Weight::from_parts(67_893_204_000, 5239782) + // Minimum execution time: 55_403_909_000 picoseconds. + Weight::from_parts(55_472_412_000, 5239782) .saturating_add(T::DbWeight::get().reads(1739_u64)) } - /// Storage: Glutton Storage (r:1 w:0) - /// Proof: Glutton Storage (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Glutton Compute (r:1 w:0) - /// Proof: Glutton Compute (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Glutton TrashData (r:5 w:0) - /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) + /// Storage: `Glutton::Storage` (r:1 w:0) + /// Proof: `Glutton::Storage` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Glutton::Compute` (r:1 w:0) + /// Proof: `Glutton::Compute` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Glutton::TrashData` (r:5 w:0) + /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) fn on_idle_low_proof_waste() -> Weight { // Proof Size summary in bytes: // Measured: `9547` // Estimated: `16070` - // Minimum execution time: 122_297_527_000 picoseconds. - Weight::from_parts(122_394_818_000, 16070) + // Minimum execution time: 97_959_007_000 picoseconds. + Weight::from_parts(98_030_476_000, 16070) .saturating_add(T::DbWeight::get().reads(7_u64)) } - /// Storage: Glutton Storage (r:1 w:0) - /// Proof: Glutton Storage (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Glutton Compute (r:1 w:0) - /// Proof: Glutton Compute (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: `Glutton::Storage` (r:1 w:0) + /// Proof: `Glutton::Storage` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Glutton::Compute` (r:1 w:0) + /// Proof: `Glutton::Compute` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) fn empty_on_idle() -> Weight { // Proof Size summary in bytes: // Measured: `86` // Estimated: `1493` - // Minimum execution time: 5_882_000 picoseconds. - Weight::from_parts(6_138_000, 1493) + // Minimum execution time: 5_011_000 picoseconds. + Weight::from_parts(5_183_000, 1493) .saturating_add(T::DbWeight::get().reads(2_u64)) } - /// Storage: Glutton Compute (r:0 w:1) - /// Proof: Glutton Compute (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: `Glutton::Compute` (r:0 w:1) + /// Proof: `Glutton::Compute` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) fn set_compute() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_830_000 picoseconds. - Weight::from_parts(8_366_000, 0) + // Minimum execution time: 5_591_000 picoseconds. + Weight::from_parts(5_970_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Glutton Storage (r:0 w:1) - /// Proof: Glutton Storage (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: `Glutton::Storage` (r:0 w:1) + /// Proof: `Glutton::Storage` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) fn set_storage() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_933_000 picoseconds. - Weight::from_parts(8_213_000, 0) + // Minimum execution time: 5_689_000 picoseconds. + Weight::from_parts(6_038_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Glutton TrashDataCount (r:1 w:1) - /// Proof: Glutton TrashDataCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Glutton TrashData (r:0 w:1000) - /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) + /// Storage: `Glutton::TrashDataCount` (r:1 w:1) + /// Proof: `Glutton::TrashDataCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Glutton::TrashData` (r:0 w:1000) + /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. fn initialize_pallet_grow(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `86` // Estimated: `1489` - // Minimum execution time: 11_488_000 picoseconds. - Weight::from_parts(93_073_710, 1489) - // Standard Error: 22_390 - .saturating_add(Weight::from_parts(9_572_012, 0).saturating_mul(n.into())) + // Minimum execution time: 8_443_000 picoseconds. + Weight::from_parts(103_698_651, 1489) + // Standard Error: 21_777 + .saturating_add(Weight::from_parts(9_529_476, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into()))) } - /// Storage: Glutton TrashDataCount (r:1 w:1) - /// Proof: Glutton TrashDataCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Glutton TrashData (r:0 w:1000) - /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) + /// Storage: `Glutton::TrashDataCount` (r:1 w:1) + /// Proof: `Glutton::TrashDataCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Glutton::TrashData` (r:0 w:1000) + /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. fn initialize_pallet_shrink(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `119` // Estimated: `1489` - // Minimum execution time: 11_378_000 picoseconds. - Weight::from_parts(5_591_508, 1489) - // Standard Error: 1_592 - .saturating_add(Weight::from_parts(1_163_758, 0).saturating_mul(n.into())) + // Minimum execution time: 8_343_000 picoseconds. + Weight::from_parts(304_498, 1489) + // Standard Error: 1_568 + .saturating_add(Weight::from_parts(1_146_553, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into()))) @@ -227,83 +226,83 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 669_000 picoseconds. - Weight::from_parts(990_745, 0) - // Standard Error: 10 - .saturating_add(Weight::from_parts(105_224, 0).saturating_mul(i.into())) + // Minimum execution time: 656_000 picoseconds. + Weight::from_parts(1_875_128, 0) + // Standard Error: 8 + .saturating_add(Weight::from_parts(103_381, 0).saturating_mul(i.into())) } - /// Storage: Glutton TrashData (r:5000 w:0) - /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) + /// Storage: `Glutton::TrashData` (r:5000 w:0) + /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) /// The range of component `i` is `[0, 5000]`. fn waste_proof_size_some(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `119114 + i * (1022 ±0)` // Estimated: `990 + i * (3016 ±0)` - // Minimum execution time: 435_000 picoseconds. - Weight::from_parts(66_547_542, 990) - // Standard Error: 4_557 - .saturating_add(Weight::from_parts(5_851_324, 0).saturating_mul(i.into())) + // Minimum execution time: 454_000 picoseconds. + Weight::from_parts(521_000, 990) + // Standard Error: 1_940 + .saturating_add(Weight::from_parts(5_729_831, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 3016).saturating_mul(i.into())) } - /// Storage: Glutton Storage (r:1 w:0) - /// Proof: Glutton Storage (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Glutton Compute (r:1 w:0) - /// Proof: Glutton Compute (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Glutton TrashData (r:1737 w:0) - /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) + /// Storage: `Glutton::Storage` (r:1 w:0) + /// Proof: `Glutton::Storage` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Glutton::Compute` (r:1 w:0) + /// Proof: `Glutton::Compute` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Glutton::TrashData` (r:1737 w:0) + /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) fn on_idle_high_proof_waste() -> Weight { // Proof Size summary in bytes: // Measured: `1900497` // Estimated: `5239782` - // Minimum execution time: 67_699_845_000 picoseconds. - Weight::from_parts(67_893_204_000, 5239782) + // Minimum execution time: 55_403_909_000 picoseconds. + Weight::from_parts(55_472_412_000, 5239782) .saturating_add(RocksDbWeight::get().reads(1739_u64)) } - /// Storage: Glutton Storage (r:1 w:0) - /// Proof: Glutton Storage (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Glutton Compute (r:1 w:0) - /// Proof: Glutton Compute (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Glutton TrashData (r:5 w:0) - /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) + /// Storage: `Glutton::Storage` (r:1 w:0) + /// Proof: `Glutton::Storage` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Glutton::Compute` (r:1 w:0) + /// Proof: `Glutton::Compute` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Glutton::TrashData` (r:5 w:0) + /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) fn on_idle_low_proof_waste() -> Weight { // Proof Size summary in bytes: // Measured: `9547` // Estimated: `16070` - // Minimum execution time: 122_297_527_000 picoseconds. - Weight::from_parts(122_394_818_000, 16070) + // Minimum execution time: 97_959_007_000 picoseconds. + Weight::from_parts(98_030_476_000, 16070) .saturating_add(RocksDbWeight::get().reads(7_u64)) } - /// Storage: Glutton Storage (r:1 w:0) - /// Proof: Glutton Storage (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Glutton Compute (r:1 w:0) - /// Proof: Glutton Compute (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: `Glutton::Storage` (r:1 w:0) + /// Proof: `Glutton::Storage` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Glutton::Compute` (r:1 w:0) + /// Proof: `Glutton::Compute` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) fn empty_on_idle() -> Weight { // Proof Size summary in bytes: // Measured: `86` // Estimated: `1493` - // Minimum execution time: 5_882_000 picoseconds. - Weight::from_parts(6_138_000, 1493) + // Minimum execution time: 5_011_000 picoseconds. + Weight::from_parts(5_183_000, 1493) .saturating_add(RocksDbWeight::get().reads(2_u64)) } - /// Storage: Glutton Compute (r:0 w:1) - /// Proof: Glutton Compute (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: `Glutton::Compute` (r:0 w:1) + /// Proof: `Glutton::Compute` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) fn set_compute() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_830_000 picoseconds. - Weight::from_parts(8_366_000, 0) + // Minimum execution time: 5_591_000 picoseconds. + Weight::from_parts(5_970_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Glutton Storage (r:0 w:1) - /// Proof: Glutton Storage (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: `Glutton::Storage` (r:0 w:1) + /// Proof: `Glutton::Storage` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) fn set_storage() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_933_000 picoseconds. - Weight::from_parts(8_213_000, 0) + // Minimum execution time: 5_689_000 picoseconds. + Weight::from_parts(6_038_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } } diff --git a/substrate/frame/grandpa/src/mock.rs b/substrate/frame/grandpa/src/mock.rs index 5d48f974c31..e1be487dbb7 100644 --- a/substrate/frame/grandpa/src/mock.rs +++ b/substrate/frame/grandpa/src/mock.rs @@ -35,11 +35,8 @@ use sp_consensus_grandpa::{RoundNumber, SetId, GRANDPA_ENGINE_ID}; use sp_core::{crypto::KeyTypeId, H256}; use sp_keyring::Ed25519Keyring; use sp_runtime::{ - curve::PiecewiseLinear, - impl_opaque_keys, - testing::{TestXt, UintAuthorityId}, - traits::OpaqueKeys, - BuildStorage, DigestItem, Perbill, + curve::PiecewiseLinear, generic::UncheckedExtrinsic, impl_opaque_keys, + testing::UintAuthorityId, traits::OpaqueKeys, BuildStorage, DigestItem, Perbill, }; use sp_staking::{EraIndex, SessionIndex}; @@ -77,7 +74,7 @@ where RuntimeCall: From, { type OverarchingCall = RuntimeCall; - type Extrinsic = TestXt; + type Extrinsic = UncheckedExtrinsic; } parameter_types! { diff --git a/substrate/frame/identity/src/weights.rs b/substrate/frame/identity/src/weights.rs index 1feb8252c84..81de520d7f2 100644 --- a/substrate/frame/identity/src/weights.rs +++ b/substrate/frame/identity/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_identity +//! Autogenerated weights for `pallet_identity` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/identity/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/identity/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_identity. +/// Weight functions needed for `pallet_identity`. pub trait WeightInfo { fn add_registrar(r: u32, ) -> Weight; fn set_identity(r: u32, ) -> Weight; @@ -77,278 +76,274 @@ pub trait WeightInfo { fn remove_dangling_username() -> Weight; } -/// Weights for pallet_identity using the Substrate node and recommended hardware. +/// Weights for `pallet_identity` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Identity Registrars (r:1 w:1) - /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: `Identity::Registrars` (r:1 w:1) + /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 19]`. fn add_registrar(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `32 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 11_683_000 picoseconds. - Weight::from_parts(12_515_830, 2626) - // Standard Error: 2_154 - .saturating_add(Weight::from_parts(147_919, 0).saturating_mul(r.into())) + // Minimum execution time: 8_857_000 picoseconds. + Weight::from_parts(9_331_464, 2626) + // Standard Error: 1_745 + .saturating_add(Weight::from_parts(94_096, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Identity IdentityOf (r:1 w:1) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 20]`. - fn set_identity(r: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `442 + r * (5 ±0)` - // Estimated: `11003` - // Minimum execution time: 32_949_000 picoseconds. - Weight::from_parts(31_329_634, 11003) - // Standard Error: 4_496 - .saturating_add(Weight::from_parts(203_570, 0).saturating_mul(r.into())) + fn set_identity(_r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `6978 + r * (5 ±0)` + // Estimated: `11037` + // Minimum execution time: 96_522_000 picoseconds. + Weight::from_parts(102_738_605, 11037) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Identity IdentityOf (r:1 w:0) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:100 w:100) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:100 w:100) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. fn set_subs_new(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `101` - // Estimated: `11003 + s * (2589 ±0)` - // Minimum execution time: 9_157_000 picoseconds. - Weight::from_parts(24_917_444, 11003) - // Standard Error: 4_554 - .saturating_add(Weight::from_parts(3_279_868, 0).saturating_mul(s.into())) + // Estimated: `11037 + s * (2589 ±0)` + // Minimum execution time: 9_112_000 picoseconds. + Weight::from_parts(22_676_873, 11037) + // Standard Error: 6_494 + .saturating_add(Weight::from_parts(3_279_196, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(s.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 2589).saturating_mul(s.into())) } - /// Storage: Identity IdentityOf (r:1 w:0) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:0 w:100) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:0 w:100) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) /// The range of component `p` is `[0, 100]`. fn set_subs_old(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `194 + p * (32 ±0)` - // Estimated: `11003` - // Minimum execution time: 9_240_000 picoseconds. - Weight::from_parts(23_326_035, 11003) - // Standard Error: 3_664 - .saturating_add(Weight::from_parts(1_439_873, 0).saturating_mul(p.into())) + // Estimated: `11037` + // Minimum execution time: 8_902_000 picoseconds. + Weight::from_parts(21_168_031, 11037) + // Standard Error: 3_576 + .saturating_add(Weight::from_parts(1_431_542, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) } - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) - /// Storage: Identity IdentityOf (r:1 w:1) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:0 w:100) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:0 w:100) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 20]`. /// The range of component `s` is `[0, 100]`. - fn clear_identity(r: u32, s: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `469 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` - // Estimated: `11003` - // Minimum execution time: 55_687_000 picoseconds. - Weight::from_parts(30_695_182, 11003) - // Standard Error: 9_921 - .saturating_add(Weight::from_parts(162_357, 0).saturating_mul(r.into())) - // Standard Error: 1_937 - .saturating_add(Weight::from_parts(1_427_998, 0).saturating_mul(s.into())) + fn clear_identity(_r: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `7070 + r * (5 ±0) + s * (32 ±0)` + // Estimated: `11037` + // Minimum execution time: 52_468_000 picoseconds. + Weight::from_parts(56_065_452, 11037) + // Standard Error: 2_274 + .saturating_add(Weight::from_parts(1_399_051, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) } - /// Storage: Identity Registrars (r:1 w:0) - /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) - /// Storage: Identity IdentityOf (r:1 w:1) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: `Identity::Registrars` (r:1 w:0) + /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 20]`. fn request_judgement(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `367 + r * (57 ±0) + x * (66 ±0)` - // Estimated: `11003` - // Minimum execution time: 34_876_000 picoseconds. - Weight::from_parts(32_207_018, 11003) - // Standard Error: 5_247 - .saturating_add(Weight::from_parts(249_156, 0).saturating_mul(r.into())) + // Measured: `6968 + r * (57 ±0)` + // Estimated: `11037` + // Minimum execution time: 67_951_000 picoseconds. + Weight::from_parts(69_591_058, 11037) + // Standard Error: 4_420 + .saturating_add(Weight::from_parts(209_239, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Identity IdentityOf (r:1 w:1) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 20]`. fn cancel_request(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `398 + x * (66 ±0)` - // Estimated: `11003` - // Minimum execution time: 30_689_000 picoseconds. - Weight::from_parts(31_967_170, 11003) - // Standard Error: 5_387 - .saturating_add(Weight::from_parts(42_676, 0).saturating_mul(r.into())) + // Measured: `6999` + // Estimated: `11037` + // Minimum execution time: 67_818_000 picoseconds. + Weight::from_parts(70_356_319, 11037) + // Standard Error: 5_116 + .saturating_add(Weight::from_parts(4_264, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Identity Registrars (r:1 w:1) - /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: `Identity::Registrars` (r:1 w:1) + /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 19]`. fn set_fee(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `89 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 7_357_000 picoseconds. - Weight::from_parts(7_932_950, 2626) - // Standard Error: 1_804 - .saturating_add(Weight::from_parts(132_653, 0).saturating_mul(r.into())) + // Minimum execution time: 6_096_000 picoseconds. + Weight::from_parts(6_470_752, 2626) + // Standard Error: 1_328 + .saturating_add(Weight::from_parts(94_764, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Identity Registrars (r:1 w:1) - /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: `Identity::Registrars` (r:1 w:1) + /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 19]`. fn set_account_id(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `89 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 7_437_000 picoseconds. - Weight::from_parts(8_051_889, 2626) - // Standard Error: 1_997 - .saturating_add(Weight::from_parts(129_592, 0).saturating_mul(r.into())) + // Minimum execution time: 6_278_000 picoseconds. + Weight::from_parts(6_678_997, 2626) + // Standard Error: 1_396 + .saturating_add(Weight::from_parts(87_207, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Identity Registrars (r:1 w:1) - /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: `Identity::Registrars` (r:1 w:1) + /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 19]`. fn set_fields(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `89 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 7_385_000 picoseconds. - Weight::from_parts(7_911_589, 2626) - // Standard Error: 1_791 - .saturating_add(Weight::from_parts(125_788, 0).saturating_mul(r.into())) + // Minimum execution time: 6_130_000 picoseconds. + Weight::from_parts(6_516_146, 2626) + // Standard Error: 1_356 + .saturating_add(Weight::from_parts(88_455, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Identity Registrars (r:1 w:0) - /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) - /// Storage: Identity IdentityOf (r:1 w:1) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: `Identity::Registrars` (r:1 w:0) + /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 19]`. fn provide_judgement(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `445 + r * (57 ±0) + x * (66 ±0)` - // Estimated: `11003` - // Minimum execution time: 24_073_000 picoseconds. - Weight::from_parts(17_817_684, 11003) - // Standard Error: 8_612 - .saturating_add(Weight::from_parts(406_251, 0).saturating_mul(r.into())) + // Measured: `7046 + r * (57 ±0)` + // Estimated: `11037` + // Minimum execution time: 87_100_000 picoseconds. + Weight::from_parts(87_601_945, 11037) + // Standard Error: 22_724 + .saturating_add(Weight::from_parts(458_296, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) - /// Storage: Identity IdentityOf (r:1 w:1) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:0 w:100) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:0 w:100) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 20]`. /// The range of component `s` is `[0, 100]`. fn kill_identity(r: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `676 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` - // Estimated: `11003` - // Minimum execution time: 73_981_000 picoseconds. - Weight::from_parts(51_684_057, 11003) - // Standard Error: 12_662 - .saturating_add(Weight::from_parts(145_285, 0).saturating_mul(r.into())) - // Standard Error: 2_472 - .saturating_add(Weight::from_parts(1_421_039, 0).saturating_mul(s.into())) + // Measured: `7277 + r * (5 ±0) + s * (32 ±0)` + // Estimated: `11037` + // Minimum execution time: 65_925_000 picoseconds. + Weight::from_parts(70_786_250, 11037) + // Standard Error: 19_680 + .saturating_add(Weight::from_parts(29_782, 0).saturating_mul(r.into())) + // Standard Error: 3_839 + .saturating_add(Weight::from_parts(1_377_604, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) } - /// Storage: Identity IdentityOf (r:1 w:0) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:1 w:1) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:1 w:1) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 99]`. fn add_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `475 + s * (36 ±0)` - // Estimated: `11003` - // Minimum execution time: 29_367_000 picoseconds. - Weight::from_parts(34_214_998, 11003) - // Standard Error: 1_522 - .saturating_add(Weight::from_parts(114_551, 0).saturating_mul(s.into())) + // Estimated: `11037` + // Minimum execution time: 25_916_000 picoseconds. + Weight::from_parts(29_781_270, 11037) + // Standard Error: 1_326 + .saturating_add(Weight::from_parts(101_515, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Identity IdentityOf (r:1 w:0) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:1 w:1) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:1 w:1) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 100]`. fn rename_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `591 + s * (3 ±0)` - // Estimated: `11003` - // Minimum execution time: 12_384_000 picoseconds. - Weight::from_parts(14_417_903, 11003) - // Standard Error: 539 - .saturating_add(Weight::from_parts(38_371, 0).saturating_mul(s.into())) + // Estimated: `11037` + // Minimum execution time: 12_142_000 picoseconds. + Weight::from_parts(14_179_741, 11037) + // Standard Error: 538 + .saturating_add(Weight::from_parts(38_847, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Identity IdentityOf (r:1 w:0) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:1 w:1) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:1 w:1) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 100]`. fn remove_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `638 + s * (35 ±0)` - // Estimated: `11003` - // Minimum execution time: 33_327_000 picoseconds. - Weight::from_parts(36_208_941, 11003) - // Standard Error: 1_240 - .saturating_add(Weight::from_parts(105_805, 0).saturating_mul(s.into())) + // Estimated: `11037` + // Minimum execution time: 29_327_000 picoseconds. + Weight::from_parts(32_163_402, 11037) + // Standard Error: 1_047 + .saturating_add(Weight::from_parts(87_159, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Identity SuperOf (r:1 w:1) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:0) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Identity::SuperOf` (r:1 w:1) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:0) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 99]`. fn quit_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `704 + s * (37 ±0)` // Estimated: `6723` - // Minimum execution time: 23_764_000 picoseconds. - Weight::from_parts(26_407_731, 6723) - // Standard Error: 1_025 - .saturating_add(Weight::from_parts(101_112, 0).saturating_mul(s.into())) + // Minimum execution time: 22_380_000 picoseconds. + Weight::from_parts(24_557_574, 6723) + // Standard Error: 1_131 + .saturating_add(Weight::from_parts(86_358, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -358,367 +353,359 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 13_873_000 picoseconds. - Weight::from_parts(13_873_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(T::DbWeight::get().writes(1)) + // Minimum execution time: 6_791_000 picoseconds. + Weight::from_parts(7_126_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Identity::UsernameAuthorities` (r:0 w:1) + /// Storage: `Identity::UsernameAuthorities` (r:1 w:1) /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn remove_username_authority() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 10_653_000 picoseconds. - Weight::from_parts(10_653_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(T::DbWeight::get().writes(1)) + // Measured: `80` + // Estimated: `3517` + // Minimum execution time: 9_657_000 picoseconds. + Weight::from_parts(9_922_000, 3517) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Identity::UsernameAuthorities` (r:1 w:1) /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) /// Storage: `Identity::AccountOfUsername` (r:1 w:1) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Storage: `Identity::PendingUsernames` (r:1 w:0) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) fn set_username_for() -> Weight { // Proof Size summary in bytes: // Measured: `80` // Estimated: `11037` - // Minimum execution time: 75_928_000 picoseconds. - Weight::from_parts(75_928_000, 0) - .saturating_add(Weight::from_parts(0, 11037)) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(3)) + // Minimum execution time: 67_928_000 picoseconds. + Weight::from_parts(69_993_000, 11037) + .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `Identity::PendingUsernames` (r:1 w:1) - /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// Storage: `Identity::AccountOfUsername` (r:0 w:1) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) fn accept_username() -> Weight { // Proof Size summary in bytes: - // Measured: `106` + // Measured: `115` // Estimated: `11037` - // Minimum execution time: 38_157_000 picoseconds. - Weight::from_parts(38_157_000, 0) - .saturating_add(Weight::from_parts(0, 11037)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(3)) + // Minimum execution time: 20_496_000 picoseconds. + Weight::from_parts(20_971_000, 11037) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `Identity::PendingUsernames` (r:1 w:1) - /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) fn remove_expired_approval() -> Weight { // Proof Size summary in bytes: - // Measured: `106` - // Estimated: `3542` - // Minimum execution time: 46_821_000 picoseconds. - Weight::from_parts(46_821_000, 0) - .saturating_add(Weight::from_parts(0, 3542)) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) + // Measured: `115` + // Estimated: `3550` + // Minimum execution time: 13_845_000 picoseconds. + Weight::from_parts(16_201_000, 3550) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Identity::AccountOfUsername` (r:1 w:0) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) fn set_primary_username() -> Weight { // Proof Size summary in bytes: - // Measured: `247` + // Measured: `257` // Estimated: `11037` - // Minimum execution time: 22_515_000 picoseconds. - Weight::from_parts(22_515_000, 0) - .saturating_add(Weight::from_parts(0, 11037)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) + // Minimum execution time: 15_900_000 picoseconds. + Weight::from_parts(16_716_000, 11037) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Identity::AccountOfUsername` (r:1 w:1) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:0) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) fn remove_dangling_username() -> Weight { // Proof Size summary in bytes: - // Measured: `126` + // Measured: `98` // Estimated: `11037` - // Minimum execution time: 15_997_000 picoseconds. - Weight::from_parts(15_997_000, 0) - .saturating_add(Weight::from_parts(0, 11037)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) + // Minimum execution time: 11_538_000 picoseconds. + Weight::from_parts(11_898_000, 11037) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Identity Registrars (r:1 w:1) - /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: `Identity::Registrars` (r:1 w:1) + /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 19]`. fn add_registrar(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `32 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 11_683_000 picoseconds. - Weight::from_parts(12_515_830, 2626) - // Standard Error: 2_154 - .saturating_add(Weight::from_parts(147_919, 0).saturating_mul(r.into())) + // Minimum execution time: 8_857_000 picoseconds. + Weight::from_parts(9_331_464, 2626) + // Standard Error: 1_745 + .saturating_add(Weight::from_parts(94_096, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Identity IdentityOf (r:1 w:1) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 20]`. - fn set_identity(r: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `442 + r * (5 ±0)` - // Estimated: `11003` - // Minimum execution time: 32_949_000 picoseconds. - Weight::from_parts(31_329_634, 11003) - // Standard Error: 4_496 - .saturating_add(Weight::from_parts(203_570, 0).saturating_mul(r.into())) + fn set_identity(_r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `6978 + r * (5 ±0)` + // Estimated: `11037` + // Minimum execution time: 96_522_000 picoseconds. + Weight::from_parts(102_738_605, 11037) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Identity IdentityOf (r:1 w:0) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:100 w:100) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:100 w:100) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. fn set_subs_new(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `101` - // Estimated: `11003 + s * (2589 ±0)` - // Minimum execution time: 9_157_000 picoseconds. - Weight::from_parts(24_917_444, 11003) - // Standard Error: 4_554 - .saturating_add(Weight::from_parts(3_279_868, 0).saturating_mul(s.into())) + // Estimated: `11037 + s * (2589 ±0)` + // Minimum execution time: 9_112_000 picoseconds. + Weight::from_parts(22_676_873, 11037) + // Standard Error: 6_494 + .saturating_add(Weight::from_parts(3_279_196, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(s.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 2589).saturating_mul(s.into())) } - /// Storage: Identity IdentityOf (r:1 w:0) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:0 w:100) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:0 w:100) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) /// The range of component `p` is `[0, 100]`. fn set_subs_old(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `194 + p * (32 ±0)` - // Estimated: `11003` - // Minimum execution time: 9_240_000 picoseconds. - Weight::from_parts(23_326_035, 11003) - // Standard Error: 3_664 - .saturating_add(Weight::from_parts(1_439_873, 0).saturating_mul(p.into())) + // Estimated: `11037` + // Minimum execution time: 8_902_000 picoseconds. + Weight::from_parts(21_168_031, 11037) + // Standard Error: 3_576 + .saturating_add(Weight::from_parts(1_431_542, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(p.into()))) } - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) - /// Storage: Identity IdentityOf (r:1 w:1) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:0 w:100) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:0 w:100) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 20]`. /// The range of component `s` is `[0, 100]`. - fn clear_identity(r: u32, s: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `469 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` - // Estimated: `11003` - // Minimum execution time: 55_687_000 picoseconds. - Weight::from_parts(30_695_182, 11003) - // Standard Error: 9_921 - .saturating_add(Weight::from_parts(162_357, 0).saturating_mul(r.into())) - // Standard Error: 1_937 - .saturating_add(Weight::from_parts(1_427_998, 0).saturating_mul(s.into())) + fn clear_identity(_r: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `7070 + r * (5 ±0) + s * (32 ±0)` + // Estimated: `11037` + // Minimum execution time: 52_468_000 picoseconds. + Weight::from_parts(56_065_452, 11037) + // Standard Error: 2_274 + .saturating_add(Weight::from_parts(1_399_051, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) } - /// Storage: Identity Registrars (r:1 w:0) - /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) - /// Storage: Identity IdentityOf (r:1 w:1) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: `Identity::Registrars` (r:1 w:0) + /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 20]`. fn request_judgement(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `367 + r * (57 ±0) + x * (66 ±0)` - // Estimated: `11003` - // Minimum execution time: 34_876_000 picoseconds. - Weight::from_parts(32_207_018, 11003) - // Standard Error: 5_247 - .saturating_add(Weight::from_parts(249_156, 0).saturating_mul(r.into())) + // Measured: `6968 + r * (57 ±0)` + // Estimated: `11037` + // Minimum execution time: 67_951_000 picoseconds. + Weight::from_parts(69_591_058, 11037) + // Standard Error: 4_420 + .saturating_add(Weight::from_parts(209_239, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Identity IdentityOf (r:1 w:1) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 20]`. fn cancel_request(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `398 + x * (66 ±0)` - // Estimated: `11003` - // Minimum execution time: 30_689_000 picoseconds. - Weight::from_parts(31_967_170, 11003) - // Standard Error: 5_387 - .saturating_add(Weight::from_parts(42_676, 0).saturating_mul(r.into())) + // Measured: `6999` + // Estimated: `11037` + // Minimum execution time: 67_818_000 picoseconds. + Weight::from_parts(70_356_319, 11037) + // Standard Error: 5_116 + .saturating_add(Weight::from_parts(4_264, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Identity Registrars (r:1 w:1) - /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: `Identity::Registrars` (r:1 w:1) + /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 19]`. fn set_fee(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `89 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 7_357_000 picoseconds. - Weight::from_parts(7_932_950, 2626) - // Standard Error: 1_804 - .saturating_add(Weight::from_parts(132_653, 0).saturating_mul(r.into())) + // Minimum execution time: 6_096_000 picoseconds. + Weight::from_parts(6_470_752, 2626) + // Standard Error: 1_328 + .saturating_add(Weight::from_parts(94_764, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Identity Registrars (r:1 w:1) - /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: `Identity::Registrars` (r:1 w:1) + /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 19]`. fn set_account_id(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `89 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 7_437_000 picoseconds. - Weight::from_parts(8_051_889, 2626) - // Standard Error: 1_997 - .saturating_add(Weight::from_parts(129_592, 0).saturating_mul(r.into())) + // Minimum execution time: 6_278_000 picoseconds. + Weight::from_parts(6_678_997, 2626) + // Standard Error: 1_396 + .saturating_add(Weight::from_parts(87_207, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Identity Registrars (r:1 w:1) - /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: `Identity::Registrars` (r:1 w:1) + /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 19]`. fn set_fields(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `89 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 7_385_000 picoseconds. - Weight::from_parts(7_911_589, 2626) - // Standard Error: 1_791 - .saturating_add(Weight::from_parts(125_788, 0).saturating_mul(r.into())) + // Minimum execution time: 6_130_000 picoseconds. + Weight::from_parts(6_516_146, 2626) + // Standard Error: 1_356 + .saturating_add(Weight::from_parts(88_455, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Identity Registrars (r:1 w:0) - /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) - /// Storage: Identity IdentityOf (r:1 w:1) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: `Identity::Registrars` (r:1 w:0) + /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 19]`. fn provide_judgement(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `445 + r * (57 ±0) + x * (66 ±0)` - // Estimated: `11003` - // Minimum execution time: 24_073_000 picoseconds. - Weight::from_parts(17_817_684, 11003) - // Standard Error: 8_612 - .saturating_add(Weight::from_parts(406_251, 0).saturating_mul(r.into())) + // Measured: `7046 + r * (57 ±0)` + // Estimated: `11037` + // Minimum execution time: 87_100_000 picoseconds. + Weight::from_parts(87_601_945, 11037) + // Standard Error: 22_724 + .saturating_add(Weight::from_parts(458_296, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) - /// Storage: Identity IdentityOf (r:1 w:1) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:0 w:100) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `Identity::IdentityOf` (r:1 w:1) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:0 w:100) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 20]`. /// The range of component `s` is `[0, 100]`. fn kill_identity(r: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `676 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` - // Estimated: `11003` - // Minimum execution time: 73_981_000 picoseconds. - Weight::from_parts(51_684_057, 11003) - // Standard Error: 12_662 - .saturating_add(Weight::from_parts(145_285, 0).saturating_mul(r.into())) - // Standard Error: 2_472 - .saturating_add(Weight::from_parts(1_421_039, 0).saturating_mul(s.into())) + // Measured: `7277 + r * (5 ±0) + s * (32 ±0)` + // Estimated: `11037` + // Minimum execution time: 65_925_000 picoseconds. + Weight::from_parts(70_786_250, 11037) + // Standard Error: 19_680 + .saturating_add(Weight::from_parts(29_782, 0).saturating_mul(r.into())) + // Standard Error: 3_839 + .saturating_add(Weight::from_parts(1_377_604, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) } - /// Storage: Identity IdentityOf (r:1 w:0) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:1 w:1) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:1 w:1) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 99]`. fn add_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `475 + s * (36 ±0)` - // Estimated: `11003` - // Minimum execution time: 29_367_000 picoseconds. - Weight::from_parts(34_214_998, 11003) - // Standard Error: 1_522 - .saturating_add(Weight::from_parts(114_551, 0).saturating_mul(s.into())) + // Estimated: `11037` + // Minimum execution time: 25_916_000 picoseconds. + Weight::from_parts(29_781_270, 11037) + // Standard Error: 1_326 + .saturating_add(Weight::from_parts(101_515, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Identity IdentityOf (r:1 w:0) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:1 w:1) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:1 w:1) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 100]`. fn rename_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `591 + s * (3 ±0)` - // Estimated: `11003` - // Minimum execution time: 12_384_000 picoseconds. - Weight::from_parts(14_417_903, 11003) - // Standard Error: 539 - .saturating_add(Weight::from_parts(38_371, 0).saturating_mul(s.into())) + // Estimated: `11037` + // Minimum execution time: 12_142_000 picoseconds. + Weight::from_parts(14_179_741, 11037) + // Standard Error: 538 + .saturating_add(Weight::from_parts(38_847, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Identity IdentityOf (r:1 w:0) - /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) - /// Storage: Identity SuperOf (r:1 w:1) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: `Identity::IdentityOf` (r:1 w:0) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: `Identity::SuperOf` (r:1 w:1) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 100]`. fn remove_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `638 + s * (35 ±0)` - // Estimated: `11003` - // Minimum execution time: 33_327_000 picoseconds. - Weight::from_parts(36_208_941, 11003) - // Standard Error: 1_240 - .saturating_add(Weight::from_parts(105_805, 0).saturating_mul(s.into())) + // Estimated: `11037` + // Minimum execution time: 29_327_000 picoseconds. + Weight::from_parts(32_163_402, 11037) + // Standard Error: 1_047 + .saturating_add(Weight::from_parts(87_159, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Identity SuperOf (r:1 w:1) - /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) - /// Storage: Identity SubsOf (r:1 w:1) - /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:0) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Identity::SuperOf` (r:1 w:1) + /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: `Identity::SubsOf` (r:1 w:1) + /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:0) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 99]`. fn quit_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `704 + s * (37 ±0)` // Estimated: `6723` - // Minimum execution time: 23_764_000 picoseconds. - Weight::from_parts(26_407_731, 6723) - // Standard Error: 1_025 - .saturating_add(Weight::from_parts(101_112, 0).saturating_mul(s.into())) + // Minimum execution time: 22_380_000 picoseconds. + Weight::from_parts(24_557_574, 6723) + // Standard Error: 1_131 + .saturating_add(Weight::from_parts(86_358, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -728,92 +715,88 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 13_873_000 picoseconds. - Weight::from_parts(13_873_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(RocksDbWeight::get().writes(1)) + // Minimum execution time: 6_791_000 picoseconds. + Weight::from_parts(7_126_000, 0) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Identity::UsernameAuthorities` (r:0 w:1) + /// Storage: `Identity::UsernameAuthorities` (r:1 w:1) /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn remove_username_authority() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 10_653_000 picoseconds. - Weight::from_parts(10_653_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(RocksDbWeight::get().writes(1)) + // Measured: `80` + // Estimated: `3517` + // Minimum execution time: 9_657_000 picoseconds. + Weight::from_parts(9_922_000, 3517) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Identity::UsernameAuthorities` (r:1 w:1) /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) /// Storage: `Identity::AccountOfUsername` (r:1 w:1) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Storage: `Identity::PendingUsernames` (r:1 w:0) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) fn set_username_for() -> Weight { // Proof Size summary in bytes: // Measured: `80` // Estimated: `11037` - // Minimum execution time: 75_928_000 picoseconds. - Weight::from_parts(75_928_000, 0) - .saturating_add(Weight::from_parts(0, 11037)) - .saturating_add(RocksDbWeight::get().reads(3)) - .saturating_add(RocksDbWeight::get().writes(3)) + // Minimum execution time: 67_928_000 picoseconds. + Weight::from_parts(69_993_000, 11037) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) } /// Storage: `Identity::PendingUsernames` (r:1 w:1) - /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// Storage: `Identity::AccountOfUsername` (r:0 w:1) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) fn accept_username() -> Weight { // Proof Size summary in bytes: - // Measured: `106` + // Measured: `115` // Estimated: `11037` - // Minimum execution time: 38_157_000 picoseconds. - Weight::from_parts(38_157_000, 0) - .saturating_add(Weight::from_parts(0, 11037)) - .saturating_add(RocksDbWeight::get().reads(2)) - .saturating_add(RocksDbWeight::get().writes(3)) + // Minimum execution time: 20_496_000 picoseconds. + Weight::from_parts(20_971_000, 11037) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) } /// Storage: `Identity::PendingUsernames` (r:1 w:1) - /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) fn remove_expired_approval() -> Weight { // Proof Size summary in bytes: - // Measured: `106` - // Estimated: `3542` - // Minimum execution time: 46_821_000 picoseconds. - Weight::from_parts(46_821_000, 0) - .saturating_add(Weight::from_parts(0, 3542)) - .saturating_add(RocksDbWeight::get().reads(1)) - .saturating_add(RocksDbWeight::get().writes(1)) + // Measured: `115` + // Estimated: `3550` + // Minimum execution time: 13_845_000 picoseconds. + Weight::from_parts(16_201_000, 3550) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Identity::AccountOfUsername` (r:1 w:0) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) fn set_primary_username() -> Weight { // Proof Size summary in bytes: - // Measured: `247` + // Measured: `257` // Estimated: `11037` - // Minimum execution time: 22_515_000 picoseconds. - Weight::from_parts(22_515_000, 0) - .saturating_add(Weight::from_parts(0, 11037)) - .saturating_add(RocksDbWeight::get().reads(2)) - .saturating_add(RocksDbWeight::get().writes(1)) + // Minimum execution time: 15_900_000 picoseconds. + Weight::from_parts(16_716_000, 11037) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Identity::AccountOfUsername` (r:1 w:1) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:0) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) fn remove_dangling_username() -> Weight { // Proof Size summary in bytes: - // Measured: `126` + // Measured: `98` // Estimated: `11037` - // Minimum execution time: 15_997_000 picoseconds. - Weight::from_parts(15_997_000, 0) - .saturating_add(Weight::from_parts(0, 11037)) - .saturating_add(RocksDbWeight::get().reads(2)) - .saturating_add(RocksDbWeight::get().writes(1)) + // Minimum execution time: 11_538_000 picoseconds. + Weight::from_parts(11_898_000, 11037) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } } diff --git a/substrate/frame/im-online/src/mock.rs b/substrate/frame/im-online/src/mock.rs index 9dad148b10f..c0ba9143e13 100644 --- a/substrate/frame/im-online/src/mock.rs +++ b/substrate/frame/im-online/src/mock.rs @@ -27,7 +27,7 @@ use frame_support::{ use pallet_session::historical as pallet_session_historical; use sp_core::H256; use sp_runtime::{ - testing::{TestXt, UintAuthorityId}, + testing::UintAuthorityId, traits::{BlakeTwo256, ConvertInto, IdentityLookup}, BuildStorage, Permill, }; @@ -78,7 +78,7 @@ impl pallet_session::historical::SessionManager for TestSessionManager } /// An extrinsic type used for tests. -pub type Extrinsic = TestXt; +pub type Extrinsic = sp_runtime::generic::UncheckedExtrinsic; type IdentificationTuple = (u64, u64); type Offence = crate::UnresponsivenessOffence; diff --git a/substrate/frame/im-online/src/tests.rs b/substrate/frame/im-online/src/tests.rs index 79036760c2d..7efca926eb0 100644 --- a/substrate/frame/im-online/src/tests.rs +++ b/substrate/frame/im-online/src/tests.rs @@ -231,7 +231,7 @@ fn should_generate_heartbeats() { // check stuff about the transaction. let ex: Extrinsic = Decode::decode(&mut &*transaction).unwrap(); - let heartbeat = match ex.call { + let heartbeat = match ex.function { crate::mock::RuntimeCall::ImOnline(crate::Call::heartbeat { heartbeat, .. }) => heartbeat, e => panic!("Unexpected call: {:?}", e), @@ -345,7 +345,7 @@ fn should_not_send_a_report_if_already_online() { assert_eq!(pool_state.read().transactions.len(), 0); // check stuff about the transaction. let ex: Extrinsic = Decode::decode(&mut &*transaction).unwrap(); - let heartbeat = match ex.call { + let heartbeat = match ex.function { crate::mock::RuntimeCall::ImOnline(crate::Call::heartbeat { heartbeat, .. }) => heartbeat, e => panic!("Unexpected call: {:?}", e), diff --git a/substrate/frame/im-online/src/weights.rs b/substrate/frame/im-online/src/weights.rs index c3db02af257..11357b1e7b7 100644 --- a/substrate/frame/im-online/src/weights.rs +++ b/substrate/frame/im-online/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_im_online +//! Autogenerated weights for `pallet_im_online` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/im-online/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/im-online/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,60 +49,60 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_im_online. +/// Weight functions needed for `pallet_im_online`. pub trait WeightInfo { fn validate_unsigned_and_then_heartbeat(k: u32, ) -> Weight; } -/// Weights for pallet_im_online using the Substrate node and recommended hardware. +/// Weights for `pallet_im_online` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Session Validators (r:1 w:0) - /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Session CurrentIndex (r:1 w:0) - /// Proof Skipped: Session CurrentIndex (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ImOnline Keys (r:1 w:0) - /// Proof: ImOnline Keys (max_values: Some(1), max_size: Some(320002), added: 320497, mode: MaxEncodedLen) - /// Storage: ImOnline ReceivedHeartbeats (r:1 w:1) - /// Proof: ImOnline ReceivedHeartbeats (max_values: None, max_size: Some(25), added: 2500, mode: MaxEncodedLen) - /// Storage: ImOnline AuthoredBlocks (r:1 w:0) - /// Proof: ImOnline AuthoredBlocks (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) + /// Storage: `Session::Validators` (r:1 w:0) + /// Proof: `Session::Validators` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Session::CurrentIndex` (r:1 w:0) + /// Proof: `Session::CurrentIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ImOnline::Keys` (r:1 w:0) + /// Proof: `ImOnline::Keys` (`max_values`: Some(1), `max_size`: Some(320002), added: 320497, mode: `MaxEncodedLen`) + /// Storage: `ImOnline::ReceivedHeartbeats` (r:1 w:1) + /// Proof: `ImOnline::ReceivedHeartbeats` (`max_values`: None, `max_size`: Some(25), added: 2500, mode: `MaxEncodedLen`) + /// Storage: `ImOnline::AuthoredBlocks` (r:1 w:0) + /// Proof: `ImOnline::AuthoredBlocks` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `MaxEncodedLen`) /// The range of component `k` is `[1, 1000]`. fn validate_unsigned_and_then_heartbeat(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `295 + k * (32 ±0)` + // Measured: `327 + k * (32 ±0)` // Estimated: `321487 + k * (1761 ±0)` - // Minimum execution time: 80_568_000 picoseconds. - Weight::from_parts(95_175_595, 321487) - // Standard Error: 627 - .saturating_add(Weight::from_parts(39_094, 0).saturating_mul(k.into())) + // Minimum execution time: 65_515_000 picoseconds. + Weight::from_parts(74_765_329, 321487) + // Standard Error: 500 + .saturating_add(Weight::from_parts(39_171, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1761).saturating_mul(k.into())) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Session Validators (r:1 w:0) - /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Session CurrentIndex (r:1 w:0) - /// Proof Skipped: Session CurrentIndex (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ImOnline Keys (r:1 w:0) - /// Proof: ImOnline Keys (max_values: Some(1), max_size: Some(320002), added: 320497, mode: MaxEncodedLen) - /// Storage: ImOnline ReceivedHeartbeats (r:1 w:1) - /// Proof: ImOnline ReceivedHeartbeats (max_values: None, max_size: Some(25), added: 2500, mode: MaxEncodedLen) - /// Storage: ImOnline AuthoredBlocks (r:1 w:0) - /// Proof: ImOnline AuthoredBlocks (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) + /// Storage: `Session::Validators` (r:1 w:0) + /// Proof: `Session::Validators` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Session::CurrentIndex` (r:1 w:0) + /// Proof: `Session::CurrentIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ImOnline::Keys` (r:1 w:0) + /// Proof: `ImOnline::Keys` (`max_values`: Some(1), `max_size`: Some(320002), added: 320497, mode: `MaxEncodedLen`) + /// Storage: `ImOnline::ReceivedHeartbeats` (r:1 w:1) + /// Proof: `ImOnline::ReceivedHeartbeats` (`max_values`: None, `max_size`: Some(25), added: 2500, mode: `MaxEncodedLen`) + /// Storage: `ImOnline::AuthoredBlocks` (r:1 w:0) + /// Proof: `ImOnline::AuthoredBlocks` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `MaxEncodedLen`) /// The range of component `k` is `[1, 1000]`. fn validate_unsigned_and_then_heartbeat(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `295 + k * (32 ±0)` + // Measured: `327 + k * (32 ±0)` // Estimated: `321487 + k * (1761 ±0)` - // Minimum execution time: 80_568_000 picoseconds. - Weight::from_parts(95_175_595, 321487) - // Standard Error: 627 - .saturating_add(Weight::from_parts(39_094, 0).saturating_mul(k.into())) + // Minimum execution time: 65_515_000 picoseconds. + Weight::from_parts(74_765_329, 321487) + // Standard Error: 500 + .saturating_add(Weight::from_parts(39_171, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1761).saturating_mul(k.into())) diff --git a/substrate/frame/indices/src/weights.rs b/substrate/frame/indices/src/weights.rs index d081cc738b1..6b571164eb6 100644 --- a/substrate/frame/indices/src/weights.rs +++ b/substrate/frame/indices/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_indices +//! Autogenerated weights for `pallet_indices` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/indices/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/indices/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_indices. +/// Weight functions needed for `pallet_indices`. pub trait WeightInfo { fn claim() -> Weight; fn transfer() -> Weight; @@ -59,128 +58,128 @@ pub trait WeightInfo { fn freeze() -> Weight; } -/// Weights for pallet_indices using the Substrate node and recommended hardware. +/// Weights for `pallet_indices` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn claim() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3534` - // Minimum execution time: 25_491_000 picoseconds. - Weight::from_parts(26_456_000, 3534) + // Minimum execution time: 20_825_000 picoseconds. + Weight::from_parts(21_507_000, 3534) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn transfer() -> Weight { // Proof Size summary in bytes: // Measured: `275` // Estimated: `3593` - // Minimum execution time: 38_027_000 picoseconds. - Weight::from_parts(38_749_000, 3593) + // Minimum execution time: 31_091_000 picoseconds. + Weight::from_parts(31_923_000, 3593) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn free() -> Weight { // Proof Size summary in bytes: // Measured: `172` // Estimated: `3534` - // Minimum execution time: 26_652_000 picoseconds. - Weight::from_parts(27_273_000, 3534) + // Minimum execution time: 21_832_000 picoseconds. + Weight::from_parts(22_436_000, 3534) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn force_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `275` // Estimated: `3593` - // Minimum execution time: 29_464_000 picoseconds. - Weight::from_parts(30_959_000, 3593) + // Minimum execution time: 23_876_000 picoseconds. + Weight::from_parts(24_954_000, 3593) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn freeze() -> Weight { // Proof Size summary in bytes: // Measured: `172` // Estimated: `3534` - // Minimum execution time: 29_015_000 picoseconds. - Weight::from_parts(29_714_000, 3534) + // Minimum execution time: 22_954_000 picoseconds. + Weight::from_parts(23_792_000, 3534) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn claim() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3534` - // Minimum execution time: 25_491_000 picoseconds. - Weight::from_parts(26_456_000, 3534) + // Minimum execution time: 20_825_000 picoseconds. + Weight::from_parts(21_507_000, 3534) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn transfer() -> Weight { // Proof Size summary in bytes: // Measured: `275` // Estimated: `3593` - // Minimum execution time: 38_027_000 picoseconds. - Weight::from_parts(38_749_000, 3593) + // Minimum execution time: 31_091_000 picoseconds. + Weight::from_parts(31_923_000, 3593) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn free() -> Weight { // Proof Size summary in bytes: // Measured: `172` // Estimated: `3534` - // Minimum execution time: 26_652_000 picoseconds. - Weight::from_parts(27_273_000, 3534) + // Minimum execution time: 21_832_000 picoseconds. + Weight::from_parts(22_436_000, 3534) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn force_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `275` // Estimated: `3593` - // Minimum execution time: 29_464_000 picoseconds. - Weight::from_parts(30_959_000, 3593) + // Minimum execution time: 23_876_000 picoseconds. + Weight::from_parts(24_954_000, 3593) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Indices Accounts (r:1 w:1) - /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `Indices::Accounts` (r:1 w:1) + /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn freeze() -> Weight { // Proof Size summary in bytes: // Measured: `172` // Estimated: `3534` - // Minimum execution time: 29_015_000 picoseconds. - Weight::from_parts(29_714_000, 3534) + // Minimum execution time: 22_954_000 picoseconds. + Weight::from_parts(23_792_000, 3534) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/lottery/src/weights.rs b/substrate/frame/lottery/src/weights.rs index 3b4e5623753..7e56cdf90db 100644 --- a/substrate/frame/lottery/src/weights.rs +++ b/substrate/frame/lottery/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_lottery +//! Autogenerated weights for `pallet_lottery` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/lottery/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/lottery/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_lottery. +/// Weight functions needed for `pallet_lottery`. pub trait WeightInfo { fn buy_ticket() -> Weight; fn set_calls(n: u32, ) -> Weight; @@ -60,214 +59,222 @@ pub trait WeightInfo { fn on_initialize_repeat() -> Weight; } -/// Weights for pallet_lottery using the Substrate node and recommended hardware. +/// Weights for `pallet_lottery` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Lottery Lottery (r:1 w:0) - /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) - /// Storage: Lottery CallIndices (r:1 w:0) - /// Proof: Lottery CallIndices (max_values: Some(1), max_size: Some(21), added: 516, mode: MaxEncodedLen) - /// Storage: Lottery TicketsCount (r:1 w:1) - /// Proof: Lottery TicketsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Lottery Participants (r:1 w:1) - /// Proof: Lottery Participants (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) - /// Storage: Lottery LotteryIndex (r:1 w:0) - /// Proof: Lottery LotteryIndex (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Lottery Tickets (r:0 w:1) - /// Proof: Lottery Tickets (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: `Lottery::Lottery` (r:1 w:0) + /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) + /// Storage: `Lottery::CallIndices` (r:1 w:0) + /// Proof: `Lottery::CallIndices` (`max_values`: Some(1), `max_size`: Some(21), added: 516, mode: `MaxEncodedLen`) + /// Storage: `Lottery::TicketsCount` (r:1 w:1) + /// Proof: `Lottery::TicketsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Lottery::Participants` (r:1 w:1) + /// Proof: `Lottery::Participants` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: `Lottery::LotteryIndex` (r:1 w:0) + /// Proof: `Lottery::LotteryIndex` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Lottery::Tickets` (r:0 w:1) + /// Proof: `Lottery::Tickets` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) fn buy_ticket() -> Weight { // Proof Size summary in bytes: - // Measured: `452` - // Estimated: `3593` - // Minimum execution time: 60_298_000 picoseconds. - Weight::from_parts(62_058_000, 3593) - .saturating_add(T::DbWeight::get().reads(6_u64)) + // Measured: `492` + // Estimated: `3997` + // Minimum execution time: 57_891_000 picoseconds. + Weight::from_parts(59_508_000, 3997) + .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: Lottery CallIndices (r:0 w:1) - /// Proof: Lottery CallIndices (max_values: Some(1), max_size: Some(21), added: 516, mode: MaxEncodedLen) + /// Storage: `Lottery::CallIndices` (r:0 w:1) + /// Proof: `Lottery::CallIndices` (`max_values`: Some(1), `max_size`: Some(21), added: 516, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 10]`. fn set_calls(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_291_000 picoseconds. - Weight::from_parts(8_178_186, 0) - // Standard Error: 3_048 - .saturating_add(Weight::from_parts(330_871, 0).saturating_mul(n.into())) + // Minimum execution time: 5_026_000 picoseconds. + Weight::from_parts(5_854_666, 0) + // Standard Error: 3_233 + .saturating_add(Weight::from_parts(334_818, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Lottery Lottery (r:1 w:1) - /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) - /// Storage: Lottery LotteryIndex (r:1 w:1) - /// Proof: Lottery LotteryIndex (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Lottery::Lottery` (r:1 w:1) + /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) + /// Storage: `Lottery::LotteryIndex` (r:1 w:1) + /// Proof: `Lottery::LotteryIndex` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn start_lottery() -> Weight { // Proof Size summary in bytes: - // Measured: `161` + // Measured: `194` // Estimated: `3593` - // Minimum execution time: 36_741_000 picoseconds. - Weight::from_parts(38_288_000, 3593) + // Minimum execution time: 26_216_000 picoseconds. + Weight::from_parts(27_216_000, 3593) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Lottery Lottery (r:1 w:1) - /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) + /// Storage: `Lottery::Lottery` (r:1 w:1) + /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) fn stop_repeat() -> Weight { // Proof Size summary in bytes: - // Measured: `219` + // Measured: `252` // Estimated: `1514` - // Minimum execution time: 7_270_000 picoseconds. - Weight::from_parts(7_578_000, 1514) + // Minimum execution time: 6_208_000 picoseconds. + Weight::from_parts(6_427_000, 1514) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) - /// Proof: RandomnessCollectiveFlip RandomMaterial (max_values: Some(1), max_size: Some(2594), added: 3089, mode: MaxEncodedLen) - /// Storage: Lottery Lottery (r:1 w:1) - /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) - /// Storage: System Account (r:2 w:2) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Lottery TicketsCount (r:1 w:1) - /// Proof: Lottery TicketsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Lottery Tickets (r:1 w:0) - /// Proof: Lottery Tickets (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) + /// Storage: `RandomnessCollectiveFlip::RandomMaterial` (r:1 w:0) + /// Proof: `RandomnessCollectiveFlip::RandomMaterial` (`max_values`: Some(1), `max_size`: Some(2594), added: 3089, mode: `MaxEncodedLen`) + /// Storage: `Lottery::Lottery` (r:1 w:1) + /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Lottery::TicketsCount` (r:1 w:1) + /// Proof: `Lottery::TicketsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Lottery::Tickets` (r:1 w:0) + /// Proof: `Lottery::Tickets` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) fn on_initialize_end() -> Weight { // Proof Size summary in bytes: - // Measured: `558` + // Measured: `591` // Estimated: `6196` - // Minimum execution time: 76_611_000 picoseconds. - Weight::from_parts(78_107_000, 6196) + // Minimum execution time: 58_660_000 picoseconds. + Weight::from_parts(59_358_000, 6196) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) - /// Proof: RandomnessCollectiveFlip RandomMaterial (max_values: Some(1), max_size: Some(2594), added: 3089, mode: MaxEncodedLen) - /// Storage: Lottery Lottery (r:1 w:1) - /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) - /// Storage: System Account (r:2 w:2) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Lottery TicketsCount (r:1 w:1) - /// Proof: Lottery TicketsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Lottery Tickets (r:1 w:0) - /// Proof: Lottery Tickets (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) - /// Storage: Lottery LotteryIndex (r:1 w:1) - /// Proof: Lottery LotteryIndex (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: `RandomnessCollectiveFlip::RandomMaterial` (r:1 w:0) + /// Proof: `RandomnessCollectiveFlip::RandomMaterial` (`max_values`: Some(1), `max_size`: Some(2594), added: 3089, mode: `MaxEncodedLen`) + /// Storage: `Lottery::Lottery` (r:1 w:1) + /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Lottery::TicketsCount` (r:1 w:1) + /// Proof: `Lottery::TicketsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Lottery::Tickets` (r:1 w:0) + /// Proof: `Lottery::Tickets` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + /// Storage: `Lottery::LotteryIndex` (r:1 w:1) + /// Proof: `Lottery::LotteryIndex` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn on_initialize_repeat() -> Weight { // Proof Size summary in bytes: - // Measured: `558` + // Measured: `591` // Estimated: `6196` - // Minimum execution time: 78_731_000 picoseconds. - Weight::from_parts(80_248_000, 6196) + // Minimum execution time: 59_376_000 picoseconds. + Weight::from_parts(60_598_000, 6196) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Lottery Lottery (r:1 w:0) - /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) - /// Storage: Lottery CallIndices (r:1 w:0) - /// Proof: Lottery CallIndices (max_values: Some(1), max_size: Some(21), added: 516, mode: MaxEncodedLen) - /// Storage: Lottery TicketsCount (r:1 w:1) - /// Proof: Lottery TicketsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Lottery Participants (r:1 w:1) - /// Proof: Lottery Participants (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) - /// Storage: Lottery LotteryIndex (r:1 w:0) - /// Proof: Lottery LotteryIndex (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Lottery Tickets (r:0 w:1) - /// Proof: Lottery Tickets (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: `Lottery::Lottery` (r:1 w:0) + /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) + /// Storage: `Lottery::CallIndices` (r:1 w:0) + /// Proof: `Lottery::CallIndices` (`max_values`: Some(1), `max_size`: Some(21), added: 516, mode: `MaxEncodedLen`) + /// Storage: `Lottery::TicketsCount` (r:1 w:1) + /// Proof: `Lottery::TicketsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Lottery::Participants` (r:1 w:1) + /// Proof: `Lottery::Participants` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: `Lottery::LotteryIndex` (r:1 w:0) + /// Proof: `Lottery::LotteryIndex` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Lottery::Tickets` (r:0 w:1) + /// Proof: `Lottery::Tickets` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) fn buy_ticket() -> Weight { // Proof Size summary in bytes: - // Measured: `452` - // Estimated: `3593` - // Minimum execution time: 60_298_000 picoseconds. - Weight::from_parts(62_058_000, 3593) - .saturating_add(RocksDbWeight::get().reads(6_u64)) + // Measured: `492` + // Estimated: `3997` + // Minimum execution time: 57_891_000 picoseconds. + Weight::from_parts(59_508_000, 3997) + .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: Lottery CallIndices (r:0 w:1) - /// Proof: Lottery CallIndices (max_values: Some(1), max_size: Some(21), added: 516, mode: MaxEncodedLen) + /// Storage: `Lottery::CallIndices` (r:0 w:1) + /// Proof: `Lottery::CallIndices` (`max_values`: Some(1), `max_size`: Some(21), added: 516, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 10]`. fn set_calls(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_291_000 picoseconds. - Weight::from_parts(8_178_186, 0) - // Standard Error: 3_048 - .saturating_add(Weight::from_parts(330_871, 0).saturating_mul(n.into())) + // Minimum execution time: 5_026_000 picoseconds. + Weight::from_parts(5_854_666, 0) + // Standard Error: 3_233 + .saturating_add(Weight::from_parts(334_818, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Lottery Lottery (r:1 w:1) - /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) - /// Storage: Lottery LotteryIndex (r:1 w:1) - /// Proof: Lottery LotteryIndex (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Lottery::Lottery` (r:1 w:1) + /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) + /// Storage: `Lottery::LotteryIndex` (r:1 w:1) + /// Proof: `Lottery::LotteryIndex` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn start_lottery() -> Weight { // Proof Size summary in bytes: - // Measured: `161` + // Measured: `194` // Estimated: `3593` - // Minimum execution time: 36_741_000 picoseconds. - Weight::from_parts(38_288_000, 3593) + // Minimum execution time: 26_216_000 picoseconds. + Weight::from_parts(27_216_000, 3593) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Lottery Lottery (r:1 w:1) - /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) + /// Storage: `Lottery::Lottery` (r:1 w:1) + /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) fn stop_repeat() -> Weight { // Proof Size summary in bytes: - // Measured: `219` + // Measured: `252` // Estimated: `1514` - // Minimum execution time: 7_270_000 picoseconds. - Weight::from_parts(7_578_000, 1514) + // Minimum execution time: 6_208_000 picoseconds. + Weight::from_parts(6_427_000, 1514) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) - /// Proof: RandomnessCollectiveFlip RandomMaterial (max_values: Some(1), max_size: Some(2594), added: 3089, mode: MaxEncodedLen) - /// Storage: Lottery Lottery (r:1 w:1) - /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) - /// Storage: System Account (r:2 w:2) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Lottery TicketsCount (r:1 w:1) - /// Proof: Lottery TicketsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Lottery Tickets (r:1 w:0) - /// Proof: Lottery Tickets (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) + /// Storage: `RandomnessCollectiveFlip::RandomMaterial` (r:1 w:0) + /// Proof: `RandomnessCollectiveFlip::RandomMaterial` (`max_values`: Some(1), `max_size`: Some(2594), added: 3089, mode: `MaxEncodedLen`) + /// Storage: `Lottery::Lottery` (r:1 w:1) + /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Lottery::TicketsCount` (r:1 w:1) + /// Proof: `Lottery::TicketsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Lottery::Tickets` (r:1 w:0) + /// Proof: `Lottery::Tickets` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) fn on_initialize_end() -> Weight { // Proof Size summary in bytes: - // Measured: `558` + // Measured: `591` // Estimated: `6196` - // Minimum execution time: 76_611_000 picoseconds. - Weight::from_parts(78_107_000, 6196) + // Minimum execution time: 58_660_000 picoseconds. + Weight::from_parts(59_358_000, 6196) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) - /// Proof: RandomnessCollectiveFlip RandomMaterial (max_values: Some(1), max_size: Some(2594), added: 3089, mode: MaxEncodedLen) - /// Storage: Lottery Lottery (r:1 w:1) - /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) - /// Storage: System Account (r:2 w:2) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Lottery TicketsCount (r:1 w:1) - /// Proof: Lottery TicketsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Lottery Tickets (r:1 w:0) - /// Proof: Lottery Tickets (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) - /// Storage: Lottery LotteryIndex (r:1 w:1) - /// Proof: Lottery LotteryIndex (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: `RandomnessCollectiveFlip::RandomMaterial` (r:1 w:0) + /// Proof: `RandomnessCollectiveFlip::RandomMaterial` (`max_values`: Some(1), `max_size`: Some(2594), added: 3089, mode: `MaxEncodedLen`) + /// Storage: `Lottery::Lottery` (r:1 w:1) + /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Lottery::TicketsCount` (r:1 w:1) + /// Proof: `Lottery::TicketsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Lottery::Tickets` (r:1 w:0) + /// Proof: `Lottery::Tickets` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + /// Storage: `Lottery::LotteryIndex` (r:1 w:1) + /// Proof: `Lottery::LotteryIndex` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn on_initialize_repeat() -> Weight { // Proof Size summary in bytes: - // Measured: `558` + // Measured: `591` // Estimated: `6196` - // Minimum execution time: 78_731_000 picoseconds. - Weight::from_parts(80_248_000, 6196) + // Minimum execution time: 59_376_000 picoseconds. + Weight::from_parts(60_598_000, 6196) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } diff --git a/substrate/frame/membership/src/weights.rs b/substrate/frame/membership/src/weights.rs index 2d18848b89a..f21867d6870 100644 --- a/substrate/frame/membership/src/weights.rs +++ b/substrate/frame/membership/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_membership +//! Autogenerated weights for `pallet_membership` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/membership/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/membership/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_membership. +/// Weight functions needed for `pallet_membership`. pub trait WeightInfo { fn add_member(m: u32, ) -> Weight; fn remove_member(m: u32, ) -> Weight; @@ -61,299 +60,299 @@ pub trait WeightInfo { fn clear_prime() -> Weight; } -/// Weights for pallet_membership using the Substrate node and recommended hardware. +/// Weights for `pallet_membership` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: TechnicalMembership Members (r:1 w:1) - /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Proposals (r:1 w:0) - /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalCommittee Members (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalCommittee Prime (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `TechnicalMembership::Members` (r:1 w:1) + /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) + /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalCommittee::Members` (r:0 w:1) + /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) + /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `m` is `[1, 99]`. fn add_member(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `208 + m * (64 ±0)` + // Measured: `207 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 17_040_000 picoseconds. - Weight::from_parts(18_344_571, 4687) - // Standard Error: 847 - .saturating_add(Weight::from_parts(50_842, 0).saturating_mul(m.into())) + // Minimum execution time: 12_126_000 picoseconds. + Weight::from_parts(13_085_583, 4687) + // Standard Error: 659 + .saturating_add(Weight::from_parts(36_103, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: TechnicalMembership Members (r:1 w:1) - /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Proposals (r:1 w:0) - /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalMembership Prime (r:1 w:0) - /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Members (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalCommittee Prime (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `TechnicalMembership::Members` (r:1 w:1) + /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) + /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalMembership::Prime` (r:1 w:0) + /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Members` (r:0 w:1) + /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) + /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `m` is `[2, 100]`. fn remove_member(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `312 + m * (64 ±0)` + // Measured: `311 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 20_088_000 picoseconds. - Weight::from_parts(21_271_384, 4687) - // Standard Error: 786 - .saturating_add(Weight::from_parts(44_806, 0).saturating_mul(m.into())) + // Minimum execution time: 14_571_000 picoseconds. + Weight::from_parts(15_532_232, 4687) + // Standard Error: 531 + .saturating_add(Weight::from_parts(35_757, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: TechnicalMembership Members (r:1 w:1) - /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Proposals (r:1 w:0) - /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalMembership Prime (r:1 w:0) - /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Members (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalCommittee Prime (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `TechnicalMembership::Members` (r:1 w:1) + /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) + /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalMembership::Prime` (r:1 w:0) + /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Members` (r:0 w:1) + /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) + /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `m` is `[2, 100]`. fn swap_member(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `312 + m * (64 ±0)` + // Measured: `311 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 20_308_000 picoseconds. - Weight::from_parts(21_469_843, 4687) - // Standard Error: 782 - .saturating_add(Weight::from_parts(56_893, 0).saturating_mul(m.into())) + // Minimum execution time: 14_833_000 picoseconds. + Weight::from_parts(15_657_084, 4687) + // Standard Error: 650 + .saturating_add(Weight::from_parts(44_467, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: TechnicalMembership Members (r:1 w:1) - /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Proposals (r:1 w:0) - /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalMembership Prime (r:1 w:0) - /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Members (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalCommittee Prime (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `TechnicalMembership::Members` (r:1 w:1) + /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) + /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalMembership::Prime` (r:1 w:0) + /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Members` (r:0 w:1) + /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) + /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `m` is `[1, 100]`. fn reset_members(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `312 + m * (64 ±0)` + // Measured: `311 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 19_464_000 picoseconds. - Weight::from_parts(21_223_702, 4687) - // Standard Error: 1_068 - .saturating_add(Weight::from_parts(165_438, 0).saturating_mul(m.into())) + // Minimum execution time: 14_629_000 picoseconds. + Weight::from_parts(15_578_203, 4687) + // Standard Error: 910 + .saturating_add(Weight::from_parts(145_101, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: TechnicalMembership Members (r:1 w:1) - /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Proposals (r:1 w:0) - /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalMembership Prime (r:1 w:1) - /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Members (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalCommittee Prime (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `TechnicalMembership::Members` (r:1 w:1) + /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) + /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalMembership::Prime` (r:1 w:1) + /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Members` (r:0 w:1) + /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) + /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `m` is `[1, 100]`. fn change_key(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `312 + m * (64 ±0)` + // Measured: `311 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 20_965_000 picoseconds. - Weight::from_parts(22_551_007, 4687) - // Standard Error: 860 - .saturating_add(Weight::from_parts(52_397, 0).saturating_mul(m.into())) + // Minimum execution time: 15_218_000 picoseconds. + Weight::from_parts(16_388_690, 4687) + // Standard Error: 626 + .saturating_add(Weight::from_parts(46_204, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: TechnicalMembership Members (r:1 w:0) - /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) - /// Storage: TechnicalMembership Prime (r:0 w:1) - /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Prime (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `TechnicalMembership::Members` (r:1 w:0) + /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `TechnicalMembership::Prime` (r:0 w:1) + /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) + /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `m` is `[1, 100]`. fn set_prime(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `32 + m * (32 ±0)` + // Measured: `31 + m * (32 ±0)` // Estimated: `4687 + m * (32 ±0)` - // Minimum execution time: 7_481_000 picoseconds. - Weight::from_parts(7_959_053, 4687) - // Standard Error: 364 - .saturating_add(Weight::from_parts(18_653, 0).saturating_mul(m.into())) + // Minimum execution time: 5_954_000 picoseconds. + Weight::from_parts(6_544_638, 4687) + // Standard Error: 346 + .saturating_add(Weight::from_parts(17_638, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) } - /// Storage: TechnicalMembership Prime (r:0 w:1) - /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Prime (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `TechnicalMembership::Prime` (r:0 w:1) + /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) + /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn clear_prime() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_373_000 picoseconds. - Weight::from_parts(3_750_452, 0) + // Minimum execution time: 2_569_000 picoseconds. + Weight::from_parts(2_776_000, 0) .saturating_add(T::DbWeight::get().writes(2_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: TechnicalMembership Members (r:1 w:1) - /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Proposals (r:1 w:0) - /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalCommittee Members (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalCommittee Prime (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `TechnicalMembership::Members` (r:1 w:1) + /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) + /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalCommittee::Members` (r:0 w:1) + /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) + /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `m` is `[1, 99]`. fn add_member(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `208 + m * (64 ±0)` + // Measured: `207 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 17_040_000 picoseconds. - Weight::from_parts(18_344_571, 4687) - // Standard Error: 847 - .saturating_add(Weight::from_parts(50_842, 0).saturating_mul(m.into())) + // Minimum execution time: 12_126_000 picoseconds. + Weight::from_parts(13_085_583, 4687) + // Standard Error: 659 + .saturating_add(Weight::from_parts(36_103, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: TechnicalMembership Members (r:1 w:1) - /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Proposals (r:1 w:0) - /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalMembership Prime (r:1 w:0) - /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Members (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalCommittee Prime (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `TechnicalMembership::Members` (r:1 w:1) + /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) + /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalMembership::Prime` (r:1 w:0) + /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Members` (r:0 w:1) + /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) + /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `m` is `[2, 100]`. fn remove_member(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `312 + m * (64 ±0)` + // Measured: `311 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 20_088_000 picoseconds. - Weight::from_parts(21_271_384, 4687) - // Standard Error: 786 - .saturating_add(Weight::from_parts(44_806, 0).saturating_mul(m.into())) + // Minimum execution time: 14_571_000 picoseconds. + Weight::from_parts(15_532_232, 4687) + // Standard Error: 531 + .saturating_add(Weight::from_parts(35_757, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: TechnicalMembership Members (r:1 w:1) - /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Proposals (r:1 w:0) - /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalMembership Prime (r:1 w:0) - /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Members (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalCommittee Prime (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `TechnicalMembership::Members` (r:1 w:1) + /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) + /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalMembership::Prime` (r:1 w:0) + /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Members` (r:0 w:1) + /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) + /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `m` is `[2, 100]`. fn swap_member(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `312 + m * (64 ±0)` + // Measured: `311 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 20_308_000 picoseconds. - Weight::from_parts(21_469_843, 4687) - // Standard Error: 782 - .saturating_add(Weight::from_parts(56_893, 0).saturating_mul(m.into())) + // Minimum execution time: 14_833_000 picoseconds. + Weight::from_parts(15_657_084, 4687) + // Standard Error: 650 + .saturating_add(Weight::from_parts(44_467, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: TechnicalMembership Members (r:1 w:1) - /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Proposals (r:1 w:0) - /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalMembership Prime (r:1 w:0) - /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Members (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalCommittee Prime (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `TechnicalMembership::Members` (r:1 w:1) + /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) + /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalMembership::Prime` (r:1 w:0) + /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Members` (r:0 w:1) + /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) + /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `m` is `[1, 100]`. fn reset_members(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `312 + m * (64 ±0)` + // Measured: `311 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 19_464_000 picoseconds. - Weight::from_parts(21_223_702, 4687) - // Standard Error: 1_068 - .saturating_add(Weight::from_parts(165_438, 0).saturating_mul(m.into())) + // Minimum execution time: 14_629_000 picoseconds. + Weight::from_parts(15_578_203, 4687) + // Standard Error: 910 + .saturating_add(Weight::from_parts(145_101, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: TechnicalMembership Members (r:1 w:1) - /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Proposals (r:1 w:0) - /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalMembership Prime (r:1 w:1) - /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Members (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: TechnicalCommittee Prime (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `TechnicalMembership::Members` (r:1 w:1) + /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) + /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalMembership::Prime` (r:1 w:1) + /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Members` (r:0 w:1) + /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) + /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `m` is `[1, 100]`. fn change_key(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `312 + m * (64 ±0)` + // Measured: `311 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 20_965_000 picoseconds. - Weight::from_parts(22_551_007, 4687) - // Standard Error: 860 - .saturating_add(Weight::from_parts(52_397, 0).saturating_mul(m.into())) + // Minimum execution time: 15_218_000 picoseconds. + Weight::from_parts(16_388_690, 4687) + // Standard Error: 626 + .saturating_add(Weight::from_parts(46_204, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: TechnicalMembership Members (r:1 w:0) - /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) - /// Storage: TechnicalMembership Prime (r:0 w:1) - /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Prime (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `TechnicalMembership::Members` (r:1 w:0) + /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: `TechnicalMembership::Prime` (r:0 w:1) + /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) + /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `m` is `[1, 100]`. fn set_prime(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `32 + m * (32 ±0)` + // Measured: `31 + m * (32 ±0)` // Estimated: `4687 + m * (32 ±0)` - // Minimum execution time: 7_481_000 picoseconds. - Weight::from_parts(7_959_053, 4687) - // Standard Error: 364 - .saturating_add(Weight::from_parts(18_653, 0).saturating_mul(m.into())) + // Minimum execution time: 5_954_000 picoseconds. + Weight::from_parts(6_544_638, 4687) + // Standard Error: 346 + .saturating_add(Weight::from_parts(17_638, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) } - /// Storage: TechnicalMembership Prime (r:0 w:1) - /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) - /// Storage: TechnicalCommittee Prime (r:0 w:1) - /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `TechnicalMembership::Prime` (r:0 w:1) + /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) + /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn clear_prime() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_373_000 picoseconds. - Weight::from_parts(3_750_452, 0) + // Minimum execution time: 2_569_000 picoseconds. + Weight::from_parts(2_776_000, 0) .saturating_add(RocksDbWeight::get().writes(2_u64)) } } diff --git a/substrate/frame/message-queue/src/weights.rs b/substrate/frame/message-queue/src/weights.rs index e86f23e274f..001e2834e1c 100644 --- a/substrate/frame/message-queue/src/weights.rs +++ b/substrate/frame/message-queue/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_message_queue +//! Autogenerated weights for `pallet_message_queue` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/message-queue/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/message-queue/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_message_queue. +/// Weight functions needed for `pallet_message_queue`. pub trait WeightInfo { fn ready_ring_knit() -> Weight; fn ready_ring_unknit() -> Weight; @@ -64,246 +63,256 @@ pub trait WeightInfo { fn execute_overweight_page_updated() -> Weight; } -/// Weights for pallet_message_queue using the Substrate node and recommended hardware. +/// Weights for `pallet_message_queue` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: MessageQueue ServiceHead (r:1 w:0) - /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: MessageQueue BookStateFor (r:2 w:2) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `MessageQueue::ServiceHead` (r:1 w:0) + /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::BookStateFor` (r:2 w:2) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) fn ready_ring_knit() -> Weight { // Proof Size summary in bytes: - // Measured: `267` + // Measured: `301` // Estimated: `6038` - // Minimum execution time: 12_025_000 picoseconds. - Weight::from_parts(12_597_000, 6038) + // Minimum execution time: 11_563_000 picoseconds. + Weight::from_parts(11_956_000, 6038) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: MessageQueue BookStateFor (r:2 w:2) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: MessageQueue ServiceHead (r:1 w:1) - /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: `MessageQueue::BookStateFor` (r:2 w:2) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::ServiceHead` (r:1 w:1) + /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn ready_ring_unknit() -> Weight { // Proof Size summary in bytes: - // Measured: `267` + // Measured: `301` // Estimated: `6038` - // Minimum execution time: 11_563_000 picoseconds. - Weight::from_parts(11_785_000, 6038) + // Minimum execution time: 10_263_000 picoseconds. + Weight::from_parts(10_638_000, 6038) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: MessageQueue BookStateFor (r:1 w:1) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) fn service_queue_base() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3514` - // Minimum execution time: 4_467_000 picoseconds. - Weight::from_parts(4_655_000, 3514) + // Minimum execution time: 4_335_000 picoseconds. + Weight::from_parts(4_552_000, 3514) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: MessageQueue Pages (r:1 w:1) - /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) + /// Storage: `MessageQueue::Pages` (r:1 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) fn service_page_base_completion() -> Weight { // Proof Size summary in bytes: // Measured: `147` // Estimated: `69049` - // Minimum execution time: 6_103_000 picoseconds. - Weight::from_parts(6_254_000, 69049) + // Minimum execution time: 6_016_000 picoseconds. + Weight::from_parts(6_224_000, 69049) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: MessageQueue Pages (r:1 w:1) - /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) + /// Storage: `MessageQueue::Pages` (r:1 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) fn service_page_base_no_completion() -> Weight { // Proof Size summary in bytes: // Measured: `147` // Estimated: `69049` - // Minimum execution time: 6_320_000 picoseconds. - Weight::from_parts(6_565_000, 69049) + // Minimum execution time: 6_183_000 picoseconds. + Weight::from_parts(6_348_000, 69049) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } + /// Storage: `MessageQueue::BookStateFor` (r:0 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:0 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) fn service_page_item() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 66_062_000 picoseconds. - Weight::from_parts(66_371_000, 0) + // Minimum execution time: 112_864_000 picoseconds. + Weight::from_parts(114_269_000, 0) + .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: MessageQueue ServiceHead (r:1 w:1) - /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: MessageQueue BookStateFor (r:1 w:0) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `MessageQueue::ServiceHead` (r:1 w:1) + /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:0) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) fn bump_service_head() -> Weight { // Proof Size summary in bytes: - // Measured: `174` + // Measured: `246` // Estimated: `3514` - // Minimum execution time: 6_788_000 picoseconds. - Weight::from_parts(7_176_000, 3514) + // Minimum execution time: 6_665_000 picoseconds. + Weight::from_parts(7_108_000, 3514) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: MessageQueue BookStateFor (r:1 w:1) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: MessageQueue Pages (r:1 w:1) - /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:1 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) fn reap_page() -> Weight { // Proof Size summary in bytes: // Measured: `65744` // Estimated: `69049` - // Minimum execution time: 52_865_000 picoseconds. - Weight::from_parts(54_398_000, 69049) + // Minimum execution time: 51_420_000 picoseconds. + Weight::from_parts(52_252_000, 69049) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: MessageQueue BookStateFor (r:1 w:1) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: MessageQueue Pages (r:1 w:1) - /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:1 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) fn execute_overweight_page_removed() -> Weight { // Proof Size summary in bytes: // Measured: `65744` // Estimated: `69049` - // Minimum execution time: 69_168_000 picoseconds. - Weight::from_parts(70_560_000, 69049) + // Minimum execution time: 71_195_000 picoseconds. + Weight::from_parts(72_981_000, 69049) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: MessageQueue BookStateFor (r:1 w:1) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: MessageQueue Pages (r:1 w:1) - /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:1 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) fn execute_overweight_page_updated() -> Weight { // Proof Size summary in bytes: // Measured: `65744` // Estimated: `69049` - // Minimum execution time: 80_947_000 picoseconds. - Weight::from_parts(82_715_000, 69049) + // Minimum execution time: 83_238_000 picoseconds. + Weight::from_parts(84_422_000, 69049) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: MessageQueue ServiceHead (r:1 w:0) - /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: MessageQueue BookStateFor (r:2 w:2) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `MessageQueue::ServiceHead` (r:1 w:0) + /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::BookStateFor` (r:2 w:2) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) fn ready_ring_knit() -> Weight { // Proof Size summary in bytes: - // Measured: `267` + // Measured: `301` // Estimated: `6038` - // Minimum execution time: 12_025_000 picoseconds. - Weight::from_parts(12_597_000, 6038) + // Minimum execution time: 11_563_000 picoseconds. + Weight::from_parts(11_956_000, 6038) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: MessageQueue BookStateFor (r:2 w:2) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: MessageQueue ServiceHead (r:1 w:1) - /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: `MessageQueue::BookStateFor` (r:2 w:2) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::ServiceHead` (r:1 w:1) + /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn ready_ring_unknit() -> Weight { // Proof Size summary in bytes: - // Measured: `267` + // Measured: `301` // Estimated: `6038` - // Minimum execution time: 11_563_000 picoseconds. - Weight::from_parts(11_785_000, 6038) + // Minimum execution time: 10_263_000 picoseconds. + Weight::from_parts(10_638_000, 6038) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: MessageQueue BookStateFor (r:1 w:1) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) fn service_queue_base() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3514` - // Minimum execution time: 4_467_000 picoseconds. - Weight::from_parts(4_655_000, 3514) + // Minimum execution time: 4_335_000 picoseconds. + Weight::from_parts(4_552_000, 3514) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: MessageQueue Pages (r:1 w:1) - /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) + /// Storage: `MessageQueue::Pages` (r:1 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) fn service_page_base_completion() -> Weight { // Proof Size summary in bytes: // Measured: `147` // Estimated: `69049` - // Minimum execution time: 6_103_000 picoseconds. - Weight::from_parts(6_254_000, 69049) + // Minimum execution time: 6_016_000 picoseconds. + Weight::from_parts(6_224_000, 69049) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: MessageQueue Pages (r:1 w:1) - /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) + /// Storage: `MessageQueue::Pages` (r:1 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) fn service_page_base_no_completion() -> Weight { // Proof Size summary in bytes: // Measured: `147` // Estimated: `69049` - // Minimum execution time: 6_320_000 picoseconds. - Weight::from_parts(6_565_000, 69049) + // Minimum execution time: 6_183_000 picoseconds. + Weight::from_parts(6_348_000, 69049) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } + /// Storage: `MessageQueue::BookStateFor` (r:0 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:0 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) fn service_page_item() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 66_062_000 picoseconds. - Weight::from_parts(66_371_000, 0) + // Minimum execution time: 112_864_000 picoseconds. + Weight::from_parts(114_269_000, 0) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: MessageQueue ServiceHead (r:1 w:1) - /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: MessageQueue BookStateFor (r:1 w:0) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: `MessageQueue::ServiceHead` (r:1 w:1) + /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:0) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) fn bump_service_head() -> Weight { // Proof Size summary in bytes: - // Measured: `174` + // Measured: `246` // Estimated: `3514` - // Minimum execution time: 6_788_000 picoseconds. - Weight::from_parts(7_176_000, 3514) + // Minimum execution time: 6_665_000 picoseconds. + Weight::from_parts(7_108_000, 3514) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: MessageQueue BookStateFor (r:1 w:1) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: MessageQueue Pages (r:1 w:1) - /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:1 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) fn reap_page() -> Weight { // Proof Size summary in bytes: // Measured: `65744` // Estimated: `69049` - // Minimum execution time: 52_865_000 picoseconds. - Weight::from_parts(54_398_000, 69049) + // Minimum execution time: 51_420_000 picoseconds. + Weight::from_parts(52_252_000, 69049) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: MessageQueue BookStateFor (r:1 w:1) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: MessageQueue Pages (r:1 w:1) - /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:1 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) fn execute_overweight_page_removed() -> Weight { // Proof Size summary in bytes: // Measured: `65744` // Estimated: `69049` - // Minimum execution time: 69_168_000 picoseconds. - Weight::from_parts(70_560_000, 69049) + // Minimum execution time: 71_195_000 picoseconds. + Weight::from_parts(72_981_000, 69049) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: MessageQueue BookStateFor (r:1 w:1) - /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: MessageQueue Pages (r:1 w:1) - /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:1 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) fn execute_overweight_page_updated() -> Weight { // Proof Size summary in bytes: // Measured: `65744` // Estimated: `69049` - // Minimum execution time: 80_947_000 picoseconds. - Weight::from_parts(82_715_000, 69049) + // Minimum execution time: 83_238_000 picoseconds. + Weight::from_parts(84_422_000, 69049) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } diff --git a/substrate/frame/migrations/src/weights.rs b/substrate/frame/migrations/src/weights.rs index c9b63258c44..9eca48ac3fd 100644 --- a/substrate/frame/migrations/src/weights.rs +++ b/substrate/frame/migrations/src/weights.rs @@ -17,26 +17,29 @@ //! Autogenerated weights for `pallet_migrations` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-04, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `loud1`, CPU: `AMD EPYC 7282 16-Core Processor` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// target/release/substrate-node +// ./target/production/substrate-node // benchmark // pallet -// --chain -// dev -// --pallet -// pallet-migrations -// --extrinsic -// -// --output -// weight.rs -// --template -// ../../polkadot-sdk/substrate/.maintain/frame-weight-template.hbs +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_migrations +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./substrate/frame/migrations/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -71,10 +74,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) fn onboard_new_mbms() -> Weight { // Proof Size summary in bytes: - // Measured: `243` + // Measured: `276` // Estimated: `67035` - // Minimum execution time: 13_980_000 picoseconds. - Weight::from_parts(14_290_000, 67035) + // Minimum execution time: 7_932_000 picoseconds. + Weight::from_parts(8_428_000, 67035) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -82,10 +85,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) fn progress_mbms_none() -> Weight { // Proof Size summary in bytes: - // Measured: `109` + // Measured: `142` // Estimated: `67035` - // Minimum execution time: 3_770_000 picoseconds. - Weight::from_parts(4_001_000, 67035) + // Minimum execution time: 2_229_000 picoseconds. + Weight::from_parts(2_329_000, 67035) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) @@ -96,8 +99,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `134` // Estimated: `3599` - // Minimum execution time: 10_900_000 picoseconds. - Weight::from_parts(11_251_000, 3599) + // Minimum execution time: 6_051_000 picoseconds. + Weight::from_parts(6_483_000, 3599) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -107,10 +110,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) fn exec_migration_skipped_historic() -> Weight { // Proof Size summary in bytes: - // Measured: `297` - // Estimated: `3762` - // Minimum execution time: 17_891_000 picoseconds. - Weight::from_parts(18_501_000, 3762) + // Measured: `330` + // Estimated: `3795` + // Minimum execution time: 10_066_000 picoseconds. + Weight::from_parts(10_713_000, 3795) .saturating_add(T::DbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) @@ -119,10 +122,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) fn exec_migration_advance() -> Weight { // Proof Size summary in bytes: - // Measured: `243` - // Estimated: `3731` - // Minimum execution time: 18_271_000 picoseconds. - Weight::from_parts(18_740_000, 3731) + // Measured: `276` + // Estimated: `3741` + // Minimum execution time: 10_026_000 picoseconds. + Weight::from_parts(10_379_000, 3741) .saturating_add(T::DbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) @@ -131,10 +134,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) fn exec_migration_complete() -> Weight { // Proof Size summary in bytes: - // Measured: `243` - // Estimated: `3731` - // Minimum execution time: 21_241_000 picoseconds. - Weight::from_parts(21_911_000, 3731) + // Measured: `276` + // Estimated: `3741` + // Minimum execution time: 11_680_000 picoseconds. + Weight::from_parts(12_184_000, 3741) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -146,10 +149,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) fn exec_migration_fail() -> Weight { // Proof Size summary in bytes: - // Measured: `243` - // Estimated: `3731` - // Minimum execution time: 22_740_000 picoseconds. - Weight::from_parts(23_231_000, 3731) + // Measured: `276` + // Estimated: `3741` + // Minimum execution time: 12_334_000 picoseconds. + Weight::from_parts(12_899_000, 3741) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -157,8 +160,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 440_000 picoseconds. - Weight::from_parts(500_000, 0) + // Minimum execution time: 187_000 picoseconds. + Weight::from_parts(209_000, 0) } /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) @@ -166,8 +169,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_751_000 picoseconds. - Weight::from_parts(5_950_000, 0) + // Minimum execution time: 2_688_000 picoseconds. + Weight::from_parts(2_874_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) @@ -176,8 +179,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_350_000 picoseconds. - Weight::from_parts(6_560_000, 0) + // Minimum execution time: 3_108_000 picoseconds. + Weight::from_parts(3_263_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) @@ -186,10 +189,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) fn force_onboard_mbms() -> Weight { // Proof Size summary in bytes: - // Measured: `218` + // Measured: `251` // Estimated: `67035` - // Minimum execution time: 11_121_000 picoseconds. - Weight::from_parts(11_530_000, 67035) + // Minimum execution time: 5_993_000 picoseconds. + Weight::from_parts(6_359_000, 67035) .saturating_add(T::DbWeight::get().reads(2_u64)) } /// Storage: `MultiBlockMigrations::Historic` (r:256 w:256) @@ -197,12 +200,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 256]`. fn clear_historic(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1089 + n * (271 ±0)` + // Measured: `1122 + n * (271 ±0)` // Estimated: `3834 + n * (2740 ±0)` - // Minimum execution time: 21_891_000 picoseconds. - Weight::from_parts(18_572_306, 3834) - // Standard Error: 3_236 - .saturating_add(Weight::from_parts(1_648_429, 0).saturating_mul(n.into())) + // Minimum execution time: 16_003_000 picoseconds. + Weight::from_parts(14_453_014, 3834) + // Standard Error: 3_305 + .saturating_add(Weight::from_parts(1_325_026, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) @@ -218,10 +221,10 @@ impl WeightInfo for () { /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) fn onboard_new_mbms() -> Weight { // Proof Size summary in bytes: - // Measured: `243` + // Measured: `276` // Estimated: `67035` - // Minimum execution time: 13_980_000 picoseconds. - Weight::from_parts(14_290_000, 67035) + // Minimum execution time: 7_932_000 picoseconds. + Weight::from_parts(8_428_000, 67035) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -229,10 +232,10 @@ impl WeightInfo for () { /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) fn progress_mbms_none() -> Weight { // Proof Size summary in bytes: - // Measured: `109` + // Measured: `142` // Estimated: `67035` - // Minimum execution time: 3_770_000 picoseconds. - Weight::from_parts(4_001_000, 67035) + // Minimum execution time: 2_229_000 picoseconds. + Weight::from_parts(2_329_000, 67035) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) @@ -243,8 +246,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `134` // Estimated: `3599` - // Minimum execution time: 10_900_000 picoseconds. - Weight::from_parts(11_251_000, 3599) + // Minimum execution time: 6_051_000 picoseconds. + Weight::from_parts(6_483_000, 3599) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -254,10 +257,10 @@ impl WeightInfo for () { /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) fn exec_migration_skipped_historic() -> Weight { // Proof Size summary in bytes: - // Measured: `297` - // Estimated: `3762` - // Minimum execution time: 17_891_000 picoseconds. - Weight::from_parts(18_501_000, 3762) + // Measured: `330` + // Estimated: `3795` + // Minimum execution time: 10_066_000 picoseconds. + Weight::from_parts(10_713_000, 3795) .saturating_add(RocksDbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) @@ -266,10 +269,10 @@ impl WeightInfo for () { /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) fn exec_migration_advance() -> Weight { // Proof Size summary in bytes: - // Measured: `243` - // Estimated: `3731` - // Minimum execution time: 18_271_000 picoseconds. - Weight::from_parts(18_740_000, 3731) + // Measured: `276` + // Estimated: `3741` + // Minimum execution time: 10_026_000 picoseconds. + Weight::from_parts(10_379_000, 3741) .saturating_add(RocksDbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) @@ -278,10 +281,10 @@ impl WeightInfo for () { /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) fn exec_migration_complete() -> Weight { // Proof Size summary in bytes: - // Measured: `243` - // Estimated: `3731` - // Minimum execution time: 21_241_000 picoseconds. - Weight::from_parts(21_911_000, 3731) + // Measured: `276` + // Estimated: `3741` + // Minimum execution time: 11_680_000 picoseconds. + Weight::from_parts(12_184_000, 3741) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -293,10 +296,10 @@ impl WeightInfo for () { /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) fn exec_migration_fail() -> Weight { // Proof Size summary in bytes: - // Measured: `243` - // Estimated: `3731` - // Minimum execution time: 22_740_000 picoseconds. - Weight::from_parts(23_231_000, 3731) + // Measured: `276` + // Estimated: `3741` + // Minimum execution time: 12_334_000 picoseconds. + Weight::from_parts(12_899_000, 3741) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -304,8 +307,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 440_000 picoseconds. - Weight::from_parts(500_000, 0) + // Minimum execution time: 187_000 picoseconds. + Weight::from_parts(209_000, 0) } /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) @@ -313,8 +316,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_751_000 picoseconds. - Weight::from_parts(5_950_000, 0) + // Minimum execution time: 2_688_000 picoseconds. + Weight::from_parts(2_874_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) @@ -323,8 +326,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_350_000 picoseconds. - Weight::from_parts(6_560_000, 0) + // Minimum execution time: 3_108_000 picoseconds. + Weight::from_parts(3_263_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) @@ -333,10 +336,10 @@ impl WeightInfo for () { /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) fn force_onboard_mbms() -> Weight { // Proof Size summary in bytes: - // Measured: `218` + // Measured: `251` // Estimated: `67035` - // Minimum execution time: 11_121_000 picoseconds. - Weight::from_parts(11_530_000, 67035) + // Minimum execution time: 5_993_000 picoseconds. + Weight::from_parts(6_359_000, 67035) .saturating_add(RocksDbWeight::get().reads(2_u64)) } /// Storage: `MultiBlockMigrations::Historic` (r:256 w:256) @@ -344,12 +347,12 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 256]`. fn clear_historic(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1089 + n * (271 ±0)` + // Measured: `1122 + n * (271 ±0)` // Estimated: `3834 + n * (2740 ±0)` - // Minimum execution time: 21_891_000 picoseconds. - Weight::from_parts(18_572_306, 3834) - // Standard Error: 3_236 - .saturating_add(Weight::from_parts(1_648_429, 0).saturating_mul(n.into())) + // Minimum execution time: 16_003_000 picoseconds. + Weight::from_parts(14_453_014, 3834) + // Standard Error: 3_305 + .saturating_add(Weight::from_parts(1_325_026, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into()))) diff --git a/substrate/frame/multisig/src/weights.rs b/substrate/frame/multisig/src/weights.rs index 7b87d258d38..4cbe7bb03b7 100644 --- a/substrate/frame/multisig/src/weights.rs +++ b/substrate/frame/multisig/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_multisig +//! Autogenerated weights for `pallet_multisig` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/multisig/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/multisig/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_multisig. +/// Weight functions needed for `pallet_multisig`. pub trait WeightInfo { fn as_multi_threshold_1(z: u32, ) -> Weight; fn as_multi_create(s: u32, z: u32, ) -> Weight; @@ -61,220 +60,238 @@ pub trait WeightInfo { fn cancel_as_multi(s: u32, ) -> Weight; } -/// Weights for pallet_multisig using the Substrate node and recommended hardware. +/// Weights for `pallet_multisig` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `z` is `[0, 10000]`. fn as_multi_threshold_1(z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 13_452_000 picoseconds. - Weight::from_parts(14_425_869, 0) + // Measured: `145` + // Estimated: `3997` + // Minimum execution time: 18_893_000 picoseconds. + Weight::from_parts(20_278_307, 3997) // Standard Error: 4 - .saturating_add(Weight::from_parts(493, 0).saturating_mul(z.into())) + .saturating_add(Weight::from_parts(488, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_create(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `301 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 46_012_000 picoseconds. - Weight::from_parts(34_797_344, 6811) - // Standard Error: 833 - .saturating_add(Weight::from_parts(127_671, 0).saturating_mul(s.into())) - // Standard Error: 8 - .saturating_add(Weight::from_parts(1_498, 0).saturating_mul(z.into())) + // Minimum execution time: 39_478_000 picoseconds. + Weight::from_parts(29_195_487, 6811) + // Standard Error: 739 + .saturating_add(Weight::from_parts(118_766, 0).saturating_mul(s.into())) + // Standard Error: 7 + .saturating_add(Weight::from_parts(1_511, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[3, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_approve(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `320` // Estimated: `6811` - // Minimum execution time: 29_834_000 picoseconds. - Weight::from_parts(20_189_154, 6811) - // Standard Error: 637 - .saturating_add(Weight::from_parts(110_080, 0).saturating_mul(s.into())) - // Standard Error: 6 - .saturating_add(Weight::from_parts(1_483, 0).saturating_mul(z.into())) + // Minimum execution time: 26_401_000 picoseconds. + Weight::from_parts(17_277_296, 6811) + // Standard Error: 492 + .saturating_add(Weight::from_parts(101_763, 0).saturating_mul(s.into())) + // Standard Error: 4 + .saturating_add(Weight::from_parts(1_486, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_complete(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `426 + s * (33 ±0)` + // Measured: `571 + s * (33 ±0)` // Estimated: `6811` - // Minimum execution time: 51_464_000 picoseconds. - Weight::from_parts(39_246_644, 6811) - // Standard Error: 1_251 - .saturating_add(Weight::from_parts(143_313, 0).saturating_mul(s.into())) + // Minimum execution time: 52_430_000 picoseconds. + Weight::from_parts(40_585_478, 6811) + // Standard Error: 1_240 + .saturating_add(Weight::from_parts(161_405, 0).saturating_mul(s.into())) // Standard Error: 12 - .saturating_add(Weight::from_parts(1_523, 0).saturating_mul(z.into())) - .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(Weight::from_parts(1_547, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. fn approve_as_multi_create(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `301 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 33_275_000 picoseconds. - Weight::from_parts(34_073_221, 6811) - // Standard Error: 1_163 - .saturating_add(Weight::from_parts(124_815, 0).saturating_mul(s.into())) + // Minimum execution time: 27_797_000 picoseconds. + Weight::from_parts(29_064_584, 6811) + // Standard Error: 817 + .saturating_add(Weight::from_parts(108_179, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. fn approve_as_multi_approve(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `320` // Estimated: `6811` - // Minimum execution time: 18_411_000 picoseconds. - Weight::from_parts(19_431_787, 6811) - // Standard Error: 694 - .saturating_add(Weight::from_parts(107_220, 0).saturating_mul(s.into())) + // Minimum execution time: 15_236_000 picoseconds. + Weight::from_parts(16_360_247, 6811) + // Standard Error: 584 + .saturating_add(Weight::from_parts(94_917, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. fn cancel_as_multi(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `492 + s * (1 ±0)` // Estimated: `6811` - // Minimum execution time: 33_985_000 picoseconds. - Weight::from_parts(35_547_970, 6811) - // Standard Error: 1_135 - .saturating_add(Weight::from_parts(116_537, 0).saturating_mul(s.into())) + // Minimum execution time: 28_730_000 picoseconds. + Weight::from_parts(30_056_661, 6811) + // Standard Error: 792 + .saturating_add(Weight::from_parts(108_212, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `z` is `[0, 10000]`. fn as_multi_threshold_1(z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 13_452_000 picoseconds. - Weight::from_parts(14_425_869, 0) + // Measured: `145` + // Estimated: `3997` + // Minimum execution time: 18_893_000 picoseconds. + Weight::from_parts(20_278_307, 3997) // Standard Error: 4 - .saturating_add(Weight::from_parts(493, 0).saturating_mul(z.into())) + .saturating_add(Weight::from_parts(488, 0).saturating_mul(z.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_create(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `301 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 46_012_000 picoseconds. - Weight::from_parts(34_797_344, 6811) - // Standard Error: 833 - .saturating_add(Weight::from_parts(127_671, 0).saturating_mul(s.into())) - // Standard Error: 8 - .saturating_add(Weight::from_parts(1_498, 0).saturating_mul(z.into())) + // Minimum execution time: 39_478_000 picoseconds. + Weight::from_parts(29_195_487, 6811) + // Standard Error: 739 + .saturating_add(Weight::from_parts(118_766, 0).saturating_mul(s.into())) + // Standard Error: 7 + .saturating_add(Weight::from_parts(1_511, 0).saturating_mul(z.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[3, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_approve(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `320` // Estimated: `6811` - // Minimum execution time: 29_834_000 picoseconds. - Weight::from_parts(20_189_154, 6811) - // Standard Error: 637 - .saturating_add(Weight::from_parts(110_080, 0).saturating_mul(s.into())) - // Standard Error: 6 - .saturating_add(Weight::from_parts(1_483, 0).saturating_mul(z.into())) + // Minimum execution time: 26_401_000 picoseconds. + Weight::from_parts(17_277_296, 6811) + // Standard Error: 492 + .saturating_add(Weight::from_parts(101_763, 0).saturating_mul(s.into())) + // Standard Error: 4 + .saturating_add(Weight::from_parts(1_486, 0).saturating_mul(z.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_complete(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `426 + s * (33 ±0)` + // Measured: `571 + s * (33 ±0)` // Estimated: `6811` - // Minimum execution time: 51_464_000 picoseconds. - Weight::from_parts(39_246_644, 6811) - // Standard Error: 1_251 - .saturating_add(Weight::from_parts(143_313, 0).saturating_mul(s.into())) + // Minimum execution time: 52_430_000 picoseconds. + Weight::from_parts(40_585_478, 6811) + // Standard Error: 1_240 + .saturating_add(Weight::from_parts(161_405, 0).saturating_mul(s.into())) // Standard Error: 12 - .saturating_add(Weight::from_parts(1_523, 0).saturating_mul(z.into())) - .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(Weight::from_parts(1_547, 0).saturating_mul(z.into())) + .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. fn approve_as_multi_create(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `301 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 33_275_000 picoseconds. - Weight::from_parts(34_073_221, 6811) - // Standard Error: 1_163 - .saturating_add(Weight::from_parts(124_815, 0).saturating_mul(s.into())) + // Minimum execution time: 27_797_000 picoseconds. + Weight::from_parts(29_064_584, 6811) + // Standard Error: 817 + .saturating_add(Weight::from_parts(108_179, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. fn approve_as_multi_approve(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `320` // Estimated: `6811` - // Minimum execution time: 18_411_000 picoseconds. - Weight::from_parts(19_431_787, 6811) - // Standard Error: 694 - .saturating_add(Weight::from_parts(107_220, 0).saturating_mul(s.into())) + // Minimum execution time: 15_236_000 picoseconds. + Weight::from_parts(16_360_247, 6811) + // Standard Error: 584 + .saturating_add(Weight::from_parts(94_917, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Multisig Multisigs (r:1 w:1) - /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: `Multisig::Multisigs` (r:1 w:1) + /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. fn cancel_as_multi(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `492 + s * (1 ±0)` // Estimated: `6811` - // Minimum execution time: 33_985_000 picoseconds. - Weight::from_parts(35_547_970, 6811) - // Standard Error: 1_135 - .saturating_add(Weight::from_parts(116_537, 0).saturating_mul(s.into())) + // Minimum execution time: 28_730_000 picoseconds. + Weight::from_parts(30_056_661, 6811) + // Standard Error: 792 + .saturating_add(Weight::from_parts(108_212, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/nft-fractionalization/src/weights.rs b/substrate/frame/nft-fractionalization/src/weights.rs index ebb4aa0fbcf..07872ebaea9 100644 --- a/substrate/frame/nft-fractionalization/src/weights.rs +++ b/substrate/frame/nft-fractionalization/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_nft_fractionalization +//! Autogenerated weights for `pallet_nft_fractionalization` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/nft-fractionalization/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/nft-fractionalization/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,136 +49,136 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_nft_fractionalization. +/// Weight functions needed for `pallet_nft_fractionalization`. pub trait WeightInfo { fn fractionalize() -> Weight; fn unify() -> Weight; } -/// Weights for pallet_nft_fractionalization using the Substrate node and recommended hardware. +/// Weights for `pallet_nft_fractionalization` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Nfts Item (r:1 w:0) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:1 w:1) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Assets Metadata (r:1 w:1) - /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) - /// Storage: NftFractionalization NftToAsset (r:0 w:1) - /// Proof: NftFractionalization NftToAsset (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: `Nfts::Item` (r:1 w:0) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:1 w:1) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Assets::Metadata` (r:1 w:1) + /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + /// Storage: `NftFractionalization::NftToAsset` (r:0 w:1) + /// Proof: `NftFractionalization::NftToAsset` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) fn fractionalize() -> Weight { // Proof Size summary in bytes: // Measured: `609` // Estimated: `4326` - // Minimum execution time: 187_416_000 picoseconds. - Weight::from_parts(191_131_000, 4326) + // Minimum execution time: 164_764_000 picoseconds. + Weight::from_parts(168_243_000, 4326) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(8_u64)) } - /// Storage: NftFractionalization NftToAsset (r:1 w:1) - /// Proof: NftFractionalization NftToAsset (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:1 w:1) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:0) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) - /// Storage: Nfts Account (r:0 w:1) - /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) - /// Storage: Nfts ItemPriceOf (r:0 w:1) - /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) - /// Storage: Nfts PendingSwapOf (r:0 w:1) - /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) + /// Storage: `NftFractionalization::NftToAsset` (r:1 w:1) + /// Proof: `NftFractionalization::NftToAsset` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:1 w:1) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Account` (r:0 w:1) + /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemPriceOf` (r:0 w:1) + /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) + /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) + /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) fn unify() -> Weight { // Proof Size summary in bytes: // Measured: `1422` // Estimated: `4326` - // Minimum execution time: 134_159_000 picoseconds. - Weight::from_parts(136_621_000, 4326) + // Minimum execution time: 120_036_000 picoseconds. + Weight::from_parts(123_550_000, 4326) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(10_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Nfts Item (r:1 w:0) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:1 w:1) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Assets Metadata (r:1 w:1) - /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) - /// Storage: NftFractionalization NftToAsset (r:0 w:1) - /// Proof: NftFractionalization NftToAsset (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: `Nfts::Item` (r:1 w:0) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:1 w:1) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Assets::Metadata` (r:1 w:1) + /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + /// Storage: `NftFractionalization::NftToAsset` (r:0 w:1) + /// Proof: `NftFractionalization::NftToAsset` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) fn fractionalize() -> Weight { // Proof Size summary in bytes: // Measured: `609` // Estimated: `4326` - // Minimum execution time: 187_416_000 picoseconds. - Weight::from_parts(191_131_000, 4326) + // Minimum execution time: 164_764_000 picoseconds. + Weight::from_parts(168_243_000, 4326) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(8_u64)) } - /// Storage: NftFractionalization NftToAsset (r:1 w:1) - /// Proof: NftFractionalization NftToAsset (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:1 w:1) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:0) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) - /// Storage: Nfts Account (r:0 w:1) - /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) - /// Storage: Nfts ItemPriceOf (r:0 w:1) - /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) - /// Storage: Nfts PendingSwapOf (r:0 w:1) - /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) + /// Storage: `NftFractionalization::NftToAsset` (r:1 w:1) + /// Proof: `NftFractionalization::NftToAsset` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:1 w:1) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Account` (r:0 w:1) + /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemPriceOf` (r:0 w:1) + /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) + /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) + /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) fn unify() -> Weight { // Proof Size summary in bytes: // Measured: `1422` // Estimated: `4326` - // Minimum execution time: 134_159_000 picoseconds. - Weight::from_parts(136_621_000, 4326) + // Minimum execution time: 120_036_000 picoseconds. + Weight::from_parts(123_550_000, 4326) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(10_u64)) } diff --git a/substrate/frame/nfts/src/weights.rs b/substrate/frame/nfts/src/weights.rs index 6b8c577bb12..4fcc1e601f4 100644 --- a/substrate/frame/nfts/src/weights.rs +++ b/substrate/frame/nfts/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_nfts +//! Autogenerated weights for `pallet_nfts` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -37,9 +37,9 @@ // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/nfts/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/nfts/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_nfts. +/// Weight functions needed for `pallet_nfts`. pub trait WeightInfo { fn create() -> Weight; fn force_create() -> Weight; @@ -92,564 +92,568 @@ pub trait WeightInfo { fn set_attributes_pre_signed(n: u32, ) -> Weight; } -/// Weights for pallet_nfts using the Substrate node and recommended hardware. +/// Weights for `pallet_nfts` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Nfts NextCollectionId (r:1 w:1) - /// Proof: Nfts NextCollectionId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionRoleOf (r:0 w:1) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:0 w:1) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts CollectionAccount (r:0 w:1) - /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: `Nfts::NextCollectionId` (r:1 w:1) + /// Proof: `Nfts::NextCollectionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionRoleOf` (r:0 w:1) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:0 w:1) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionAccount` (r:0 w:1) + /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn create() -> Weight { // Proof Size summary in bytes: // Measured: `216` // Estimated: `3549` - // Minimum execution time: 40_489_000 picoseconds. - Weight::from_parts(41_320_000, 3549) + // Minimum execution time: 34_035_000 picoseconds. + Weight::from_parts(35_228_000, 3549) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: Nfts NextCollectionId (r:1 w:1) - /// Proof: Nfts NextCollectionId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionRoleOf (r:0 w:1) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:0 w:1) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts CollectionAccount (r:0 w:1) - /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: `Nfts::NextCollectionId` (r:1 w:1) + /// Proof: `Nfts::NextCollectionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionRoleOf` (r:0 w:1) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:0 w:1) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionAccount` (r:0 w:1) + /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn force_create() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3549` - // Minimum execution time: 23_257_000 picoseconds. - Weight::from_parts(23_770_000, 3549) + // Minimum execution time: 19_430_000 picoseconds. + Weight::from_parts(20_054_000, 3549) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts ItemMetadataOf (r:1 w:0) - /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) - /// Storage: Nfts CollectionRoleOf (r:1 w:1) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:1001 w:1000) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1000 w:1000) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts CollectionMetadataOf (r:0 w:1) - /// Proof: Nfts CollectionMetadataOf (max_values: None, max_size: Some(87), added: 2562, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:0 w:1) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts CollectionAccount (r:0 w:1) - /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemMetadataOf` (r:1 w:0) + /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:1) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:1001 w:1000) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1000 w:1000) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionMetadataOf` (r:0 w:1) + /// Proof: `Nfts::CollectionMetadataOf` (`max_values`: None, `max_size`: Some(294), added: 2769, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:0 w:1) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionAccount` (r:0 w:1) + /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) /// The range of component `m` is `[0, 1000]`. /// The range of component `c` is `[0, 1000]`. /// The range of component `a` is `[0, 1000]`. fn destroy(_m: u32, _c: u32, a: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `32220 + a * (332 ±0)` - // Estimated: `2523990 + a * (2921 ±0)` - // Minimum execution time: 1_310_198_000 picoseconds. - Weight::from_parts(1_479_261_043, 2523990) - // Standard Error: 4_415 - .saturating_add(Weight::from_parts(6_016_212, 0).saturating_mul(a.into())) + // Measured: `32204 + a * (366 ±0)` + // Estimated: `2523990 + a * (2954 ±0)` + // Minimum execution time: 1_249_733_000 picoseconds. + Weight::from_parts(1_293_703_849, 2523990) + // Standard Error: 4_764 + .saturating_add(Weight::from_parts(6_433_523, 0).saturating_mul(a.into())) .saturating_add(T::DbWeight::get().reads(1004_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(a.into()))) .saturating_add(T::DbWeight::get().writes(1005_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(a.into()))) - .saturating_add(Weight::from_parts(0, 2921).saturating_mul(a.into())) - } - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:1) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts Account (r:0 w:1) - /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + .saturating_add(Weight::from_parts(0, 2954).saturating_mul(a.into())) + } + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Account` (r:0 w:1) + /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) fn mint() -> Weight { // Proof Size summary in bytes: // Measured: `455` // Estimated: `4326` - // Minimum execution time: 51_910_000 picoseconds. - Weight::from_parts(53_441_000, 4326) + // Minimum execution time: 48_645_000 picoseconds. + Weight::from_parts(50_287_000, 4326) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:1) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts Account (r:0 w:1) - /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Account` (r:0 w:1) + /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) fn force_mint() -> Weight { // Proof Size summary in bytes: // Measured: `455` // Estimated: `4326` - // Minimum execution time: 50_168_000 picoseconds. - Weight::from_parts(51_380_000, 4326) + // Minimum execution time: 46_688_000 picoseconds. + Weight::from_parts(47_680_000, 4326) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: Nfts ItemConfigOf (r:1 w:1) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts ItemMetadataOf (r:1 w:0) - /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) - /// Storage: Nfts Account (r:0 w:1) - /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) - /// Storage: Nfts ItemPriceOf (r:0 w:1) - /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) - /// Storage: Nfts ItemAttributesApprovalsOf (r:0 w:1) - /// Proof: Nfts ItemAttributesApprovalsOf (max_values: None, max_size: Some(681), added: 3156, mode: MaxEncodedLen) - /// Storage: Nfts PendingSwapOf (r:0 w:1) - /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) + /// Storage: `Nfts::Attribute` (r:1 w:0) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemMetadataOf` (r:1 w:0) + /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Account` (r:0 w:1) + /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemPriceOf` (r:0 w:1) + /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemAttributesApprovalsOf` (r:0 w:1) + /// Proof: `Nfts::ItemAttributesApprovalsOf` (`max_values`: None, `max_size`: Some(681), added: 3156, mode: `MaxEncodedLen`) + /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) + /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) fn burn() -> Weight { // Proof Size summary in bytes: // Measured: `564` // Estimated: `4326` - // Minimum execution time: 50_738_000 picoseconds. - Weight::from_parts(51_850_000, 4326) - .saturating_add(T::DbWeight::get().reads(4_u64)) + // Minimum execution time: 51_771_000 picoseconds. + Weight::from_parts(53_492_000, 4326) + .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } - /// Storage: Nfts Collection (r:1 w:0) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:1 w:0) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:0) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts Account (r:0 w:2) - /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) - /// Storage: Nfts ItemPriceOf (r:0 w:1) - /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) - /// Storage: Nfts PendingSwapOf (r:0 w:1) - /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) + /// Storage: `Nfts::Collection` (r:1 w:0) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:1 w:0) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Account` (r:0 w:2) + /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemPriceOf` (r:0 w:1) + /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) + /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) + /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) fn transfer() -> Weight { // Proof Size summary in bytes: // Measured: `593` // Estimated: `4326` - // Minimum execution time: 41_055_000 picoseconds. - Weight::from_parts(42_336_000, 4326) + // Minimum execution time: 39_166_000 picoseconds. + Weight::from_parts(40_128_000, 4326) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: Nfts Collection (r:1 w:0) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts Item (r:5000 w:5000) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: `Nfts::Collection` (r:1 w:0) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Item` (r:5000 w:5000) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) /// The range of component `i` is `[0, 5000]`. fn redeposit(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `763 + i * (108 ±0)` // Estimated: `3549 + i * (3336 ±0)` - // Minimum execution time: 15_688_000 picoseconds. - Weight::from_parts(15_921_000, 3549) - // Standard Error: 14_827 - .saturating_add(Weight::from_parts(17_105_395, 0).saturating_mul(i.into())) + // Minimum execution time: 13_804_000 picoseconds. + Weight::from_parts(14_159_000, 3549) + // Standard Error: 13_812 + .saturating_add(Weight::from_parts(14_661_284, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(i.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 3336).saturating_mul(i.into())) } - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:1) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) fn lock_item_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `435` // Estimated: `3534` - // Minimum execution time: 19_981_000 picoseconds. - Weight::from_parts(20_676_000, 3534) + // Minimum execution time: 17_485_000 picoseconds. + Weight::from_parts(18_412_000, 3534) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:1) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) fn unlock_item_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `435` // Estimated: `3534` - // Minimum execution time: 19_911_000 picoseconds. - Weight::from_parts(20_612_000, 3534) + // Minimum execution time: 17_335_000 picoseconds. + Weight::from_parts(18_543_000, 3534) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Nfts Collection (r:1 w:0) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:1) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: `Nfts::Collection` (r:1 w:0) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:1) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn lock_collection() -> Weight { // Proof Size summary in bytes: // Measured: `340` // Estimated: `3549` - // Minimum execution time: 16_441_000 picoseconds. - Weight::from_parts(16_890_000, 3549) + // Minimum execution time: 14_608_000 picoseconds. + Weight::from_parts(15_696_000, 3549) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Nfts OwnershipAcceptance (r:1 w:1) - /// Proof: Nfts OwnershipAcceptance (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionAccount (r:0 w:2) - /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: `Nfts::OwnershipAcceptance` (r:1 w:1) + /// Proof: `Nfts::OwnershipAcceptance` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionAccount` (r:0 w:2) + /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn transfer_ownership() -> Weight { // Proof Size summary in bytes: - // Measured: `388` - // Estimated: `3549` - // Minimum execution time: 22_610_000 picoseconds. - Weight::from_parts(23_422_000, 3549) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) + // Measured: `562` + // Estimated: `3593` + // Minimum execution time: 25_686_000 picoseconds. + Weight::from_parts(26_433_000, 3593) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionRoleOf (r:2 w:4) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionRoleOf` (r:2 w:4) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn set_team() -> Weight { // Proof Size summary in bytes: // Measured: `369` // Estimated: `6078` - // Minimum execution time: 39_739_000 picoseconds. - Weight::from_parts(41_306_000, 6078) + // Minimum execution time: 37_192_000 picoseconds. + Weight::from_parts(38_561_000, 6078) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionAccount (r:0 w:2) - /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionAccount` (r:0 w:2) + /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn force_collection_owner() -> Weight { // Proof Size summary in bytes: // Measured: `311` // Estimated: `3549` - // Minimum execution time: 17_685_000 picoseconds. - Weight::from_parts(18_258_000, 3549) + // Minimum execution time: 15_401_000 picoseconds. + Weight::from_parts(15_826_000, 3549) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Nfts Collection (r:1 w:0) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:0 w:1) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: `Nfts::Collection` (r:1 w:0) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:0 w:1) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn force_collection_config() -> Weight { // Proof Size summary in bytes: // Measured: `276` // Estimated: `3549` - // Minimum execution time: 13_734_000 picoseconds. - Weight::from_parts(14_337_000, 3549) + // Minimum execution time: 11_683_000 picoseconds. + Weight::from_parts(12_255_000, 3549) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:1) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) fn lock_item_properties() -> Weight { // Proof Size summary in bytes: // Measured: `435` // Estimated: `3534` - // Minimum execution time: 19_269_000 picoseconds. - Weight::from_parts(19_859_000, 3534) + // Minimum execution time: 16_899_000 picoseconds. + Weight::from_parts(17_404_000, 3534) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:0) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:1 w:1) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:1 w:1) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) fn set_attribute() -> Weight { // Proof Size summary in bytes: // Measured: `539` - // Estimated: `3911` - // Minimum execution time: 51_540_000 picoseconds. - Weight::from_parts(52_663_000, 3911) + // Estimated: `3944` + // Minimum execution time: 46_768_000 picoseconds. + Weight::from_parts(47_834_000, 3944) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:1 w:1) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:1 w:1) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) fn force_set_attribute() -> Weight { // Proof Size summary in bytes: // Measured: `344` - // Estimated: `3911` - // Minimum execution time: 26_529_000 picoseconds. - Weight::from_parts(27_305_000, 3911) + // Estimated: `3944` + // Minimum execution time: 23_356_000 picoseconds. + Weight::from_parts(24_528_000, 3944) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Nfts Attribute (r:1 w:1) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:0) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: `Nfts::Attribute` (r:1 w:1) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) fn clear_attribute() -> Weight { // Proof Size summary in bytes: - // Measured: `950` - // Estimated: `3911` - // Minimum execution time: 46_951_000 picoseconds. - Weight::from_parts(48_481_000, 3911) + // Measured: `983` + // Estimated: `3944` + // Minimum execution time: 43_061_000 picoseconds. + Weight::from_parts(44_024_000, 3944) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Nfts Item (r:1 w:0) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts ItemAttributesApprovalsOf (r:1 w:1) - /// Proof: Nfts ItemAttributesApprovalsOf (max_values: None, max_size: Some(681), added: 3156, mode: MaxEncodedLen) + /// Storage: `Nfts::Item` (r:1 w:0) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemAttributesApprovalsOf` (r:1 w:1) + /// Proof: `Nfts::ItemAttributesApprovalsOf` (`max_values`: None, `max_size`: Some(681), added: 3156, mode: `MaxEncodedLen`) fn approve_item_attributes() -> Weight { // Proof Size summary in bytes: // Measured: `381` // Estimated: `4326` - // Minimum execution time: 17_222_000 picoseconds. - Weight::from_parts(17_819_000, 4326) + // Minimum execution time: 14_929_000 picoseconds. + Weight::from_parts(15_344_000, 4326) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Nfts Item (r:1 w:0) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts ItemAttributesApprovalsOf (r:1 w:1) - /// Proof: Nfts ItemAttributesApprovalsOf (max_values: None, max_size: Some(681), added: 3156, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:1001 w:1000) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Nfts::Item` (r:1 w:0) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemAttributesApprovalsOf` (r:1 w:1) + /// Proof: `Nfts::ItemAttributesApprovalsOf` (`max_values`: None, `max_size`: Some(681), added: 3156, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:1001 w:1000) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. fn cancel_item_attributes_approval(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `837 + n * (364 ±0)` - // Estimated: `4326 + n * (2921 ±0)` - // Minimum execution time: 26_185_000 picoseconds. - Weight::from_parts(27_038_000, 4326) - // Standard Error: 2_378 - .saturating_add(Weight::from_parts(6_067_888, 0).saturating_mul(n.into())) + // Measured: `831 + n * (398 ±0)` + // Estimated: `4326 + n * (2954 ±0)` + // Minimum execution time: 23_707_000 picoseconds. + Weight::from_parts(24_688_000, 4326) + // Standard Error: 3_813 + .saturating_add(Weight::from_parts(6_422_256, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 2921).saturating_mul(n.into())) - } - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:0) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts ItemMetadataOf (r:1 w:1) - /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + .saturating_add(Weight::from_parts(0, 2954).saturating_mul(n.into())) + } + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemMetadataOf` (r:1 w:1) + /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) fn set_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `539` - // Estimated: `3605` - // Minimum execution time: 42_120_000 picoseconds. - Weight::from_parts(43_627_000, 3605) + // Estimated: `3812` + // Minimum execution time: 37_882_000 picoseconds. + Weight::from_parts(39_222_000, 3812) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts ItemMetadataOf (r:1 w:1) - /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:0) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemMetadataOf` (r:1 w:1) + /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) fn clear_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `642` - // Estimated: `3605` - // Minimum execution time: 40_732_000 picoseconds. - Weight::from_parts(42_760_000, 3605) + // Measured: `849` + // Estimated: `3812` + // Minimum execution time: 36_629_000 picoseconds. + Weight::from_parts(37_351_000, 3812) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionMetadataOf (r:1 w:1) - /// Proof: Nfts CollectionMetadataOf (max_values: None, max_size: Some(87), added: 2562, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionMetadataOf` (r:1 w:1) + /// Proof: `Nfts::CollectionMetadataOf` (`max_values`: None, `max_size`: Some(294), added: 2769, mode: `MaxEncodedLen`) fn set_collection_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `398` - // Estimated: `3552` - // Minimum execution time: 39_443_000 picoseconds. - Weight::from_parts(40_482_000, 3552) + // Estimated: `3759` + // Minimum execution time: 34_853_000 picoseconds. + Weight::from_parts(35_914_000, 3759) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:0) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts CollectionMetadataOf (r:1 w:1) - /// Proof: Nfts CollectionMetadataOf (max_values: None, max_size: Some(87), added: 2562, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:0) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionMetadataOf` (r:1 w:1) + /// Proof: `Nfts::CollectionMetadataOf` (`max_values`: None, `max_size`: Some(294), added: 2769, mode: `MaxEncodedLen`) fn clear_collection_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `509` - // Estimated: `3552` - // Minimum execution time: 37_676_000 picoseconds. - Weight::from_parts(39_527_000, 3552) + // Measured: `716` + // Estimated: `3759` + // Minimum execution time: 33_759_000 picoseconds. + Weight::from_parts(34_729_000, 3759) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn approve_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `410` // Estimated: `4326` - // Minimum execution time: 20_787_000 picoseconds. - Weight::from_parts(21_315_000, 4326) + // Minimum execution time: 17_583_000 picoseconds. + Weight::from_parts(18_675_000, 4326) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) fn cancel_approval() -> Weight { // Proof Size summary in bytes: // Measured: `418` // Estimated: `4326` - // Minimum execution time: 18_200_000 picoseconds. - Weight::from_parts(19_064_000, 4326) + // Minimum execution time: 15_036_000 picoseconds. + Weight::from_parts(15_995_000, 4326) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) fn clear_all_transfer_approvals() -> Weight { // Proof Size summary in bytes: // Measured: `418` // Estimated: `4326` - // Minimum execution time: 17_128_000 picoseconds. - Weight::from_parts(17_952_000, 4326) + // Minimum execution time: 14_666_000 picoseconds. + Weight::from_parts(15_152_000, 4326) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Nfts OwnershipAcceptance (r:1 w:1) - /// Proof: Nfts OwnershipAcceptance (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: `Nfts::OwnershipAcceptance` (r:1 w:1) + /// Proof: `Nfts::OwnershipAcceptance` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn set_accept_ownership() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3517` - // Minimum execution time: 14_667_000 picoseconds. - Weight::from_parts(15_262_000, 3517) + // Minimum execution time: 12_393_000 picoseconds. + Weight::from_parts(12_895_000, 3517) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Nfts CollectionConfigOf (r:1 w:1) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:0) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:1) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:0) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) fn set_collection_max_supply() -> Weight { // Proof Size summary in bytes: // Measured: `340` // Estimated: `3549` - // Minimum execution time: 18_435_000 picoseconds. - Weight::from_parts(18_775_000, 3549) + // Minimum execution time: 16_034_000 picoseconds. + Weight::from_parts(16_617_000, 3549) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:1) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:1) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn update_mint_settings() -> Weight { // Proof Size summary in bytes: // Measured: `323` // Estimated: `3538` - // Minimum execution time: 18_125_000 picoseconds. - Weight::from_parts(18_415_000, 3538) + // Minimum execution time: 15_812_000 picoseconds. + Weight::from_parts(16_644_000, 3538) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Nfts Item (r:1 w:0) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:0) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts ItemPriceOf (r:0 w:1) - /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) + /// Storage: `Nfts::Item` (r:1 w:0) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemPriceOf` (r:0 w:1) + /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) fn set_price() -> Weight { // Proof Size summary in bytes: // Measured: `518` // Estimated: `4326` - // Minimum execution time: 23_237_000 picoseconds. - Weight::from_parts(24_128_000, 4326) + // Minimum execution time: 21_650_000 picoseconds. + Weight::from_parts(22_443_000, 4326) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts ItemPriceOf (r:1 w:1) - /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:0) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:1 w:0) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:0) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts Account (r:0 w:2) - /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) - /// Storage: Nfts PendingSwapOf (r:0 w:1) - /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemPriceOf` (r:1 w:1) + /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:0) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:1 w:0) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Account` (r:0 w:2) + /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) + /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) fn buy_item() -> Weight { // Proof Size summary in bytes: // Measured: `705` // Estimated: `4326` - // Minimum execution time: 53_291_000 picoseconds. - Weight::from_parts(54_614_000, 4326) + // Minimum execution time: 49_463_000 picoseconds. + Weight::from_parts(50_937_000, 4326) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } @@ -658,681 +662,685 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_192_000 picoseconds. - Weight::from_parts(4_039_901, 0) - // Standard Error: 10_309 - .saturating_add(Weight::from_parts(3_934_017, 0).saturating_mul(n.into())) - } - /// Storage: Nfts Item (r:2 w:0) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts PendingSwapOf (r:0 w:1) - /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) + // Minimum execution time: 2_029_000 picoseconds. + Weight::from_parts(3_749_829, 0) + // Standard Error: 8_497 + .saturating_add(Weight::from_parts(1_913_514, 0).saturating_mul(n.into())) + } + /// Storage: `Nfts::Item` (r:2 w:0) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) + /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) fn create_swap() -> Weight { // Proof Size summary in bytes: // Measured: `494` // Estimated: `7662` - // Minimum execution time: 21_011_000 picoseconds. - Weight::from_parts(22_065_000, 7662) + // Minimum execution time: 18_181_000 picoseconds. + Weight::from_parts(18_698_000, 7662) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Nfts PendingSwapOf (r:1 w:1) - /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) - /// Storage: Nfts Item (r:1 w:0) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: `Nfts::PendingSwapOf` (r:1 w:1) + /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Item` (r:1 w:0) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) fn cancel_swap() -> Weight { // Proof Size summary in bytes: // Measured: `513` // Estimated: `4326` - // Minimum execution time: 21_423_000 picoseconds. - Weight::from_parts(21_743_000, 4326) + // Minimum execution time: 18_228_000 picoseconds. + Weight::from_parts(18_940_000, 4326) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Nfts Item (r:2 w:2) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts PendingSwapOf (r:1 w:2) - /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:0) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:2 w:0) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:2 w:0) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts Account (r:0 w:4) - /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) - /// Storage: Nfts ItemPriceOf (r:0 w:2) - /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) + /// Storage: `Nfts::Item` (r:2 w:2) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::PendingSwapOf` (r:1 w:2) + /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:0) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:2 w:0) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:2 w:0) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Account` (r:0 w:4) + /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemPriceOf` (r:0 w:2) + /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) fn claim_swap() -> Weight { // Proof Size summary in bytes: // Measured: `834` // Estimated: `7662` - // Minimum execution time: 86_059_000 picoseconds. - Weight::from_parts(88_401_000, 7662) + // Minimum execution time: 77_983_000 picoseconds. + Weight::from_parts(79_887_000, 7662) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(10_u64)) } - /// Storage: Nfts CollectionRoleOf (r:2 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:1) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:10 w:10) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: Nfts ItemMetadataOf (r:1 w:1) - /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) - /// Storage: Nfts Account (r:0 w:1) - /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionRoleOf` (r:2 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:10 w:10) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemMetadataOf` (r:1 w:1) + /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Account` (r:0 w:1) + /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 10]`. fn mint_pre_signed(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `629` - // Estimated: `6078 + n * (2921 ±0)` - // Minimum execution time: 146_746_000 picoseconds. - Weight::from_parts(152_885_862, 6078) - // Standard Error: 40_442 - .saturating_add(Weight::from_parts(32_887_800, 0).saturating_mul(n.into())) + // Estimated: `6078 + n * (2954 ±0)` + // Minimum execution time: 126_998_000 picoseconds. + Weight::from_parts(134_149_389, 6078) + // Standard Error: 33_180 + .saturating_add(Weight::from_parts(30_711_206, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(6_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 2921).saturating_mul(n.into())) - } - /// Storage: Nfts Item (r:1 w:0) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts ItemAttributesApprovalsOf (r:1 w:1) - /// Proof: Nfts ItemAttributesApprovalsOf (max_values: None, max_size: Some(681), added: 3156, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:10 w:10) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + .saturating_add(Weight::from_parts(0, 2954).saturating_mul(n.into())) + } + /// Storage: `Nfts::Item` (r:1 w:0) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemAttributesApprovalsOf` (r:1 w:1) + /// Proof: `Nfts::ItemAttributesApprovalsOf` (`max_values`: None, `max_size`: Some(681), added: 3156, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:10 w:10) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 10]`. fn set_attributes_pre_signed(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `659` - // Estimated: `4326 + n * (2921 ±0)` - // Minimum execution time: 83_960_000 picoseconds. - Weight::from_parts(98_609_885, 4326) - // Standard Error: 85_991 - .saturating_add(Weight::from_parts(32_633_495, 0).saturating_mul(n.into())) + // Estimated: `4326 + n * (2954 ±0)` + // Minimum execution time: 66_213_000 picoseconds. + Weight::from_parts(81_661_819, 4326) + // Standard Error: 87_003 + .saturating_add(Weight::from_parts(29_550_476, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 2921).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 2954).saturating_mul(n.into())) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Nfts NextCollectionId (r:1 w:1) - /// Proof: Nfts NextCollectionId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionRoleOf (r:0 w:1) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:0 w:1) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts CollectionAccount (r:0 w:1) - /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: `Nfts::NextCollectionId` (r:1 w:1) + /// Proof: `Nfts::NextCollectionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionRoleOf` (r:0 w:1) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:0 w:1) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionAccount` (r:0 w:1) + /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn create() -> Weight { // Proof Size summary in bytes: // Measured: `216` // Estimated: `3549` - // Minimum execution time: 40_489_000 picoseconds. - Weight::from_parts(41_320_000, 3549) + // Minimum execution time: 34_035_000 picoseconds. + Weight::from_parts(35_228_000, 3549) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: Nfts NextCollectionId (r:1 w:1) - /// Proof: Nfts NextCollectionId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionRoleOf (r:0 w:1) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:0 w:1) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts CollectionAccount (r:0 w:1) - /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: `Nfts::NextCollectionId` (r:1 w:1) + /// Proof: `Nfts::NextCollectionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionRoleOf` (r:0 w:1) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:0 w:1) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionAccount` (r:0 w:1) + /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn force_create() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3549` - // Minimum execution time: 23_257_000 picoseconds. - Weight::from_parts(23_770_000, 3549) + // Minimum execution time: 19_430_000 picoseconds. + Weight::from_parts(20_054_000, 3549) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts ItemMetadataOf (r:1 w:0) - /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) - /// Storage: Nfts CollectionRoleOf (r:1 w:1) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:1001 w:1000) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1000 w:1000) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts CollectionMetadataOf (r:0 w:1) - /// Proof: Nfts CollectionMetadataOf (max_values: None, max_size: Some(87), added: 2562, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:0 w:1) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts CollectionAccount (r:0 w:1) - /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemMetadataOf` (r:1 w:0) + /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:1) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:1001 w:1000) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1000 w:1000) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionMetadataOf` (r:0 w:1) + /// Proof: `Nfts::CollectionMetadataOf` (`max_values`: None, `max_size`: Some(294), added: 2769, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:0 w:1) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionAccount` (r:0 w:1) + /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) /// The range of component `m` is `[0, 1000]`. /// The range of component `c` is `[0, 1000]`. /// The range of component `a` is `[0, 1000]`. fn destroy(_m: u32, _c: u32, a: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `32220 + a * (332 ±0)` - // Estimated: `2523990 + a * (2921 ±0)` - // Minimum execution time: 1_310_198_000 picoseconds. - Weight::from_parts(1_479_261_043, 2523990) - // Standard Error: 4_415 - .saturating_add(Weight::from_parts(6_016_212, 0).saturating_mul(a.into())) + // Measured: `32204 + a * (366 ±0)` + // Estimated: `2523990 + a * (2954 ±0)` + // Minimum execution time: 1_249_733_000 picoseconds. + Weight::from_parts(1_293_703_849, 2523990) + // Standard Error: 4_764 + .saturating_add(Weight::from_parts(6_433_523, 0).saturating_mul(a.into())) .saturating_add(RocksDbWeight::get().reads(1004_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(a.into()))) .saturating_add(RocksDbWeight::get().writes(1005_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(a.into()))) - .saturating_add(Weight::from_parts(0, 2921).saturating_mul(a.into())) - } - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:1) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts Account (r:0 w:1) - /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + .saturating_add(Weight::from_parts(0, 2954).saturating_mul(a.into())) + } + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Account` (r:0 w:1) + /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) fn mint() -> Weight { // Proof Size summary in bytes: // Measured: `455` // Estimated: `4326` - // Minimum execution time: 51_910_000 picoseconds. - Weight::from_parts(53_441_000, 4326) + // Minimum execution time: 48_645_000 picoseconds. + Weight::from_parts(50_287_000, 4326) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:1) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts Account (r:0 w:1) - /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Account` (r:0 w:1) + /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) fn force_mint() -> Weight { // Proof Size summary in bytes: // Measured: `455` // Estimated: `4326` - // Minimum execution time: 50_168_000 picoseconds. - Weight::from_parts(51_380_000, 4326) + // Minimum execution time: 46_688_000 picoseconds. + Weight::from_parts(47_680_000, 4326) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: Nfts ItemConfigOf (r:1 w:1) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts ItemMetadataOf (r:1 w:0) - /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) - /// Storage: Nfts Account (r:0 w:1) - /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) - /// Storage: Nfts ItemPriceOf (r:0 w:1) - /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) - /// Storage: Nfts ItemAttributesApprovalsOf (r:0 w:1) - /// Proof: Nfts ItemAttributesApprovalsOf (max_values: None, max_size: Some(681), added: 3156, mode: MaxEncodedLen) - /// Storage: Nfts PendingSwapOf (r:0 w:1) - /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) + /// Storage: `Nfts::Attribute` (r:1 w:0) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemMetadataOf` (r:1 w:0) + /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Account` (r:0 w:1) + /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemPriceOf` (r:0 w:1) + /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemAttributesApprovalsOf` (r:0 w:1) + /// Proof: `Nfts::ItemAttributesApprovalsOf` (`max_values`: None, `max_size`: Some(681), added: 3156, mode: `MaxEncodedLen`) + /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) + /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) fn burn() -> Weight { // Proof Size summary in bytes: // Measured: `564` // Estimated: `4326` - // Minimum execution time: 50_738_000 picoseconds. - Weight::from_parts(51_850_000, 4326) - .saturating_add(RocksDbWeight::get().reads(4_u64)) + // Minimum execution time: 51_771_000 picoseconds. + Weight::from_parts(53_492_000, 4326) + .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } - /// Storage: Nfts Collection (r:1 w:0) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:1 w:0) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:0) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts Account (r:0 w:2) - /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) - /// Storage: Nfts ItemPriceOf (r:0 w:1) - /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) - /// Storage: Nfts PendingSwapOf (r:0 w:1) - /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) + /// Storage: `Nfts::Collection` (r:1 w:0) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:1 w:0) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Account` (r:0 w:2) + /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemPriceOf` (r:0 w:1) + /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) + /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) + /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) fn transfer() -> Weight { // Proof Size summary in bytes: // Measured: `593` // Estimated: `4326` - // Minimum execution time: 41_055_000 picoseconds. - Weight::from_parts(42_336_000, 4326) + // Minimum execution time: 39_166_000 picoseconds. + Weight::from_parts(40_128_000, 4326) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: Nfts Collection (r:1 w:0) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts Item (r:5000 w:5000) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: `Nfts::Collection` (r:1 w:0) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Item` (r:5000 w:5000) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) /// The range of component `i` is `[0, 5000]`. fn redeposit(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `763 + i * (108 ±0)` // Estimated: `3549 + i * (3336 ±0)` - // Minimum execution time: 15_688_000 picoseconds. - Weight::from_parts(15_921_000, 3549) - // Standard Error: 14_827 - .saturating_add(Weight::from_parts(17_105_395, 0).saturating_mul(i.into())) + // Minimum execution time: 13_804_000 picoseconds. + Weight::from_parts(14_159_000, 3549) + // Standard Error: 13_812 + .saturating_add(Weight::from_parts(14_661_284, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(i.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 3336).saturating_mul(i.into())) } - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:1) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) fn lock_item_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `435` // Estimated: `3534` - // Minimum execution time: 19_981_000 picoseconds. - Weight::from_parts(20_676_000, 3534) + // Minimum execution time: 17_485_000 picoseconds. + Weight::from_parts(18_412_000, 3534) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:1) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) fn unlock_item_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `435` // Estimated: `3534` - // Minimum execution time: 19_911_000 picoseconds. - Weight::from_parts(20_612_000, 3534) + // Minimum execution time: 17_335_000 picoseconds. + Weight::from_parts(18_543_000, 3534) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Nfts Collection (r:1 w:0) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:1) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: `Nfts::Collection` (r:1 w:0) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:1) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn lock_collection() -> Weight { // Proof Size summary in bytes: // Measured: `340` // Estimated: `3549` - // Minimum execution time: 16_441_000 picoseconds. - Weight::from_parts(16_890_000, 3549) + // Minimum execution time: 14_608_000 picoseconds. + Weight::from_parts(15_696_000, 3549) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Nfts OwnershipAcceptance (r:1 w:1) - /// Proof: Nfts OwnershipAcceptance (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionAccount (r:0 w:2) - /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: `Nfts::OwnershipAcceptance` (r:1 w:1) + /// Proof: `Nfts::OwnershipAcceptance` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionAccount` (r:0 w:2) + /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn transfer_ownership() -> Weight { // Proof Size summary in bytes: - // Measured: `388` - // Estimated: `3549` - // Minimum execution time: 22_610_000 picoseconds. - Weight::from_parts(23_422_000, 3549) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(4_u64)) + // Measured: `562` + // Estimated: `3593` + // Minimum execution time: 25_686_000 picoseconds. + Weight::from_parts(26_433_000, 3593) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionRoleOf (r:2 w:4) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionRoleOf` (r:2 w:4) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) fn set_team() -> Weight { // Proof Size summary in bytes: // Measured: `369` // Estimated: `6078` - // Minimum execution time: 39_739_000 picoseconds. - Weight::from_parts(41_306_000, 6078) + // Minimum execution time: 37_192_000 picoseconds. + Weight::from_parts(38_561_000, 6078) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionAccount (r:0 w:2) - /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionAccount` (r:0 w:2) + /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn force_collection_owner() -> Weight { // Proof Size summary in bytes: // Measured: `311` // Estimated: `3549` - // Minimum execution time: 17_685_000 picoseconds. - Weight::from_parts(18_258_000, 3549) + // Minimum execution time: 15_401_000 picoseconds. + Weight::from_parts(15_826_000, 3549) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Nfts Collection (r:1 w:0) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:0 w:1) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: `Nfts::Collection` (r:1 w:0) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:0 w:1) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn force_collection_config() -> Weight { // Proof Size summary in bytes: // Measured: `276` // Estimated: `3549` - // Minimum execution time: 13_734_000 picoseconds. - Weight::from_parts(14_337_000, 3549) + // Minimum execution time: 11_683_000 picoseconds. + Weight::from_parts(12_255_000, 3549) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:1) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) fn lock_item_properties() -> Weight { // Proof Size summary in bytes: // Measured: `435` // Estimated: `3534` - // Minimum execution time: 19_269_000 picoseconds. - Weight::from_parts(19_859_000, 3534) + // Minimum execution time: 16_899_000 picoseconds. + Weight::from_parts(17_404_000, 3534) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:0) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:1 w:1) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:1 w:1) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) fn set_attribute() -> Weight { // Proof Size summary in bytes: // Measured: `539` - // Estimated: `3911` - // Minimum execution time: 51_540_000 picoseconds. - Weight::from_parts(52_663_000, 3911) + // Estimated: `3944` + // Minimum execution time: 46_768_000 picoseconds. + Weight::from_parts(47_834_000, 3944) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:1 w:1) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:1 w:1) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) fn force_set_attribute() -> Weight { // Proof Size summary in bytes: // Measured: `344` - // Estimated: `3911` - // Minimum execution time: 26_529_000 picoseconds. - Weight::from_parts(27_305_000, 3911) + // Estimated: `3944` + // Minimum execution time: 23_356_000 picoseconds. + Weight::from_parts(24_528_000, 3944) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Nfts Attribute (r:1 w:1) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:0) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: `Nfts::Attribute` (r:1 w:1) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) fn clear_attribute() -> Weight { // Proof Size summary in bytes: - // Measured: `950` - // Estimated: `3911` - // Minimum execution time: 46_951_000 picoseconds. - Weight::from_parts(48_481_000, 3911) + // Measured: `983` + // Estimated: `3944` + // Minimum execution time: 43_061_000 picoseconds. + Weight::from_parts(44_024_000, 3944) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Nfts Item (r:1 w:0) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts ItemAttributesApprovalsOf (r:1 w:1) - /// Proof: Nfts ItemAttributesApprovalsOf (max_values: None, max_size: Some(681), added: 3156, mode: MaxEncodedLen) + /// Storage: `Nfts::Item` (r:1 w:0) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemAttributesApprovalsOf` (r:1 w:1) + /// Proof: `Nfts::ItemAttributesApprovalsOf` (`max_values`: None, `max_size`: Some(681), added: 3156, mode: `MaxEncodedLen`) fn approve_item_attributes() -> Weight { // Proof Size summary in bytes: // Measured: `381` // Estimated: `4326` - // Minimum execution time: 17_222_000 picoseconds. - Weight::from_parts(17_819_000, 4326) + // Minimum execution time: 14_929_000 picoseconds. + Weight::from_parts(15_344_000, 4326) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Nfts Item (r:1 w:0) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts ItemAttributesApprovalsOf (r:1 w:1) - /// Proof: Nfts ItemAttributesApprovalsOf (max_values: None, max_size: Some(681), added: 3156, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:1001 w:1000) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Nfts::Item` (r:1 w:0) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemAttributesApprovalsOf` (r:1 w:1) + /// Proof: `Nfts::ItemAttributesApprovalsOf` (`max_values`: None, `max_size`: Some(681), added: 3156, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:1001 w:1000) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. fn cancel_item_attributes_approval(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `837 + n * (364 ±0)` - // Estimated: `4326 + n * (2921 ±0)` - // Minimum execution time: 26_185_000 picoseconds. - Weight::from_parts(27_038_000, 4326) - // Standard Error: 2_378 - .saturating_add(Weight::from_parts(6_067_888, 0).saturating_mul(n.into())) + // Measured: `831 + n * (398 ±0)` + // Estimated: `4326 + n * (2954 ±0)` + // Minimum execution time: 23_707_000 picoseconds. + Weight::from_parts(24_688_000, 4326) + // Standard Error: 3_813 + .saturating_add(Weight::from_parts(6_422_256, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 2921).saturating_mul(n.into())) - } - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:0) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts ItemMetadataOf (r:1 w:1) - /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + .saturating_add(Weight::from_parts(0, 2954).saturating_mul(n.into())) + } + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemMetadataOf` (r:1 w:1) + /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) fn set_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `539` - // Estimated: `3605` - // Minimum execution time: 42_120_000 picoseconds. - Weight::from_parts(43_627_000, 3605) + // Estimated: `3812` + // Minimum execution time: 37_882_000 picoseconds. + Weight::from_parts(39_222_000, 3812) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts ItemMetadataOf (r:1 w:1) - /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:0) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemMetadataOf` (r:1 w:1) + /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) fn clear_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `642` - // Estimated: `3605` - // Minimum execution time: 40_732_000 picoseconds. - Weight::from_parts(42_760_000, 3605) + // Measured: `849` + // Estimated: `3812` + // Minimum execution time: 36_629_000 picoseconds. + Weight::from_parts(37_351_000, 3812) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionMetadataOf (r:1 w:1) - /// Proof: Nfts CollectionMetadataOf (max_values: None, max_size: Some(87), added: 2562, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionMetadataOf` (r:1 w:1) + /// Proof: `Nfts::CollectionMetadataOf` (`max_values`: None, `max_size`: Some(294), added: 2769, mode: `MaxEncodedLen`) fn set_collection_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `398` - // Estimated: `3552` - // Minimum execution time: 39_443_000 picoseconds. - Weight::from_parts(40_482_000, 3552) + // Estimated: `3759` + // Minimum execution time: 34_853_000 picoseconds. + Weight::from_parts(35_914_000, 3759) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:0) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts CollectionMetadataOf (r:1 w:1) - /// Proof: Nfts CollectionMetadataOf (max_values: None, max_size: Some(87), added: 2562, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:0) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionMetadataOf` (r:1 w:1) + /// Proof: `Nfts::CollectionMetadataOf` (`max_values`: None, `max_size`: Some(294), added: 2769, mode: `MaxEncodedLen`) fn clear_collection_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `509` - // Estimated: `3552` - // Minimum execution time: 37_676_000 picoseconds. - Weight::from_parts(39_527_000, 3552) + // Measured: `716` + // Estimated: `3759` + // Minimum execution time: 33_759_000 picoseconds. + Weight::from_parts(34_729_000, 3759) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn approve_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `410` // Estimated: `4326` - // Minimum execution time: 20_787_000 picoseconds. - Weight::from_parts(21_315_000, 4326) + // Minimum execution time: 17_583_000 picoseconds. + Weight::from_parts(18_675_000, 4326) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) fn cancel_approval() -> Weight { // Proof Size summary in bytes: // Measured: `418` // Estimated: `4326` - // Minimum execution time: 18_200_000 picoseconds. - Weight::from_parts(19_064_000, 4326) + // Minimum execution time: 15_036_000 picoseconds. + Weight::from_parts(15_995_000, 4326) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) fn clear_all_transfer_approvals() -> Weight { // Proof Size summary in bytes: // Measured: `418` // Estimated: `4326` - // Minimum execution time: 17_128_000 picoseconds. - Weight::from_parts(17_952_000, 4326) + // Minimum execution time: 14_666_000 picoseconds. + Weight::from_parts(15_152_000, 4326) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Nfts OwnershipAcceptance (r:1 w:1) - /// Proof: Nfts OwnershipAcceptance (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: `Nfts::OwnershipAcceptance` (r:1 w:1) + /// Proof: `Nfts::OwnershipAcceptance` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn set_accept_ownership() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3517` - // Minimum execution time: 14_667_000 picoseconds. - Weight::from_parts(15_262_000, 3517) + // Minimum execution time: 12_393_000 picoseconds. + Weight::from_parts(12_895_000, 3517) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Nfts CollectionConfigOf (r:1 w:1) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:0) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:1) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:0) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) fn set_collection_max_supply() -> Weight { // Proof Size summary in bytes: // Measured: `340` // Estimated: `3549` - // Minimum execution time: 18_435_000 picoseconds. - Weight::from_parts(18_775_000, 3549) + // Minimum execution time: 16_034_000 picoseconds. + Weight::from_parts(16_617_000, 3549) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Nfts CollectionRoleOf (r:1 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:1) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:1) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn update_mint_settings() -> Weight { // Proof Size summary in bytes: // Measured: `323` // Estimated: `3538` - // Minimum execution time: 18_125_000 picoseconds. - Weight::from_parts(18_415_000, 3538) + // Minimum execution time: 15_812_000 picoseconds. + Weight::from_parts(16_644_000, 3538) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Nfts Item (r:1 w:0) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:0) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts ItemPriceOf (r:0 w:1) - /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) + /// Storage: `Nfts::Item` (r:1 w:0) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemPriceOf` (r:0 w:1) + /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) fn set_price() -> Weight { // Proof Size summary in bytes: // Measured: `518` // Estimated: `4326` - // Minimum execution time: 23_237_000 picoseconds. - Weight::from_parts(24_128_000, 4326) + // Minimum execution time: 21_650_000 picoseconds. + Weight::from_parts(22_443_000, 4326) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts ItemPriceOf (r:1 w:1) - /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:0) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:1 w:0) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:0) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts Account (r:0 w:2) - /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) - /// Storage: Nfts PendingSwapOf (r:0 w:1) - /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemPriceOf` (r:1 w:1) + /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:0) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:1 w:0) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Account` (r:0 w:2) + /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) + /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) fn buy_item() -> Weight { // Proof Size summary in bytes: // Measured: `705` // Estimated: `4326` - // Minimum execution time: 53_291_000 picoseconds. - Weight::from_parts(54_614_000, 4326) + // Minimum execution time: 49_463_000 picoseconds. + Weight::from_parts(50_937_000, 4326) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } @@ -1341,120 +1349,120 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_192_000 picoseconds. - Weight::from_parts(4_039_901, 0) - // Standard Error: 10_309 - .saturating_add(Weight::from_parts(3_934_017, 0).saturating_mul(n.into())) - } - /// Storage: Nfts Item (r:2 w:0) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts PendingSwapOf (r:0 w:1) - /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) + // Minimum execution time: 2_029_000 picoseconds. + Weight::from_parts(3_749_829, 0) + // Standard Error: 8_497 + .saturating_add(Weight::from_parts(1_913_514, 0).saturating_mul(n.into())) + } + /// Storage: `Nfts::Item` (r:2 w:0) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) + /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) fn create_swap() -> Weight { // Proof Size summary in bytes: // Measured: `494` // Estimated: `7662` - // Minimum execution time: 21_011_000 picoseconds. - Weight::from_parts(22_065_000, 7662) + // Minimum execution time: 18_181_000 picoseconds. + Weight::from_parts(18_698_000, 7662) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Nfts PendingSwapOf (r:1 w:1) - /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) - /// Storage: Nfts Item (r:1 w:0) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: `Nfts::PendingSwapOf` (r:1 w:1) + /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Item` (r:1 w:0) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) fn cancel_swap() -> Weight { // Proof Size summary in bytes: // Measured: `513` // Estimated: `4326` - // Minimum execution time: 21_423_000 picoseconds. - Weight::from_parts(21_743_000, 4326) + // Minimum execution time: 18_228_000 picoseconds. + Weight::from_parts(18_940_000, 4326) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Nfts Item (r:2 w:2) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts PendingSwapOf (r:1 w:2) - /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:0) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:2 w:0) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:2 w:0) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: Nfts Account (r:0 w:4) - /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) - /// Storage: Nfts ItemPriceOf (r:0 w:2) - /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) + /// Storage: `Nfts::Item` (r:2 w:2) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::PendingSwapOf` (r:1 w:2) + /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:0) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:2 w:0) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:2 w:0) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Account` (r:0 w:4) + /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemPriceOf` (r:0 w:2) + /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) fn claim_swap() -> Weight { // Proof Size summary in bytes: // Measured: `834` // Estimated: `7662` - // Minimum execution time: 86_059_000 picoseconds. - Weight::from_parts(88_401_000, 7662) + // Minimum execution time: 77_983_000 picoseconds. + Weight::from_parts(79_887_000, 7662) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(10_u64)) } - /// Storage: Nfts CollectionRoleOf (r:2 w:0) - /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts Item (r:1 w:1) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts ItemConfigOf (r:1 w:1) - /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:10 w:10) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: Nfts ItemMetadataOf (r:1 w:1) - /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) - /// Storage: Nfts Account (r:0 w:1) - /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: `Nfts::CollectionRoleOf` (r:2 w:0) + /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Item` (r:1 w:1) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) + /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:10 w:10) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemMetadataOf` (r:1 w:1) + /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Account` (r:0 w:1) + /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 10]`. fn mint_pre_signed(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `629` - // Estimated: `6078 + n * (2921 ±0)` - // Minimum execution time: 146_746_000 picoseconds. - Weight::from_parts(152_885_862, 6078) - // Standard Error: 40_442 - .saturating_add(Weight::from_parts(32_887_800, 0).saturating_mul(n.into())) + // Estimated: `6078 + n * (2954 ±0)` + // Minimum execution time: 126_998_000 picoseconds. + Weight::from_parts(134_149_389, 6078) + // Standard Error: 33_180 + .saturating_add(Weight::from_parts(30_711_206, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes(6_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 2921).saturating_mul(n.into())) - } - /// Storage: Nfts Item (r:1 w:0) - /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) - /// Storage: Nfts ItemAttributesApprovalsOf (r:1 w:1) - /// Proof: Nfts ItemAttributesApprovalsOf (max_values: None, max_size: Some(681), added: 3156, mode: MaxEncodedLen) - /// Storage: Nfts CollectionConfigOf (r:1 w:0) - /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) - /// Storage: Nfts Collection (r:1 w:1) - /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) - /// Storage: Nfts Attribute (r:10 w:10) - /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + .saturating_add(Weight::from_parts(0, 2954).saturating_mul(n.into())) + } + /// Storage: `Nfts::Item` (r:1 w:0) + /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: `Nfts::ItemAttributesApprovalsOf` (r:1 w:1) + /// Proof: `Nfts::ItemAttributesApprovalsOf` (`max_values`: None, `max_size`: Some(681), added: 3156, mode: `MaxEncodedLen`) + /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) + /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Collection` (r:1 w:1) + /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: `Nfts::Attribute` (r:10 w:10) + /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 10]`. fn set_attributes_pre_signed(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `659` - // Estimated: `4326 + n * (2921 ±0)` - // Minimum execution time: 83_960_000 picoseconds. - Weight::from_parts(98_609_885, 4326) - // Standard Error: 85_991 - .saturating_add(Weight::from_parts(32_633_495, 0).saturating_mul(n.into())) + // Estimated: `4326 + n * (2954 ±0)` + // Minimum execution time: 66_213_000 picoseconds. + Weight::from_parts(81_661_819, 4326) + // Standard Error: 87_003 + .saturating_add(Weight::from_parts(29_550_476, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 2921).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 2954).saturating_mul(n.into())) } } diff --git a/substrate/frame/nis/src/weights.rs b/substrate/frame/nis/src/weights.rs index cba2f004905..63908271391 100644 --- a/substrate/frame/nis/src/weights.rs +++ b/substrate/frame/nis/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_nis +//! Autogenerated weights for `pallet_nis` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/nis/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/nis/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_nis. +/// Weight functions needed for `pallet_nis`. pub trait WeightInfo { fn place_bid(l: u32, ) -> Weight; fn place_bid_max() -> Weight; @@ -65,367 +64,367 @@ pub trait WeightInfo { fn process_bid() -> Weight; } -/// Weights for pallet_nis using the Substrate node and recommended hardware. +/// Weights for `pallet_nis` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Nis Queues (r:1 w:1) - /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) - /// Storage: Nis QueueTotals (r:1 w:1) - /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) + /// Storage: `Nis::Queues` (r:1 w:1) + /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `Nis::QueueTotals` (r:1 w:1) + /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) /// The range of component `l` is `[0, 999]`. fn place_bid(l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `6176 + l * (48 ±0)` // Estimated: `51487` - // Minimum execution time: 49_410_000 picoseconds. - Weight::from_parts(57_832_282, 51487) - // Standard Error: 288 - .saturating_add(Weight::from_parts(51_621, 0).saturating_mul(l.into())) + // Minimum execution time: 47_908_000 picoseconds. + Weight::from_parts(50_096_676, 51487) + // Standard Error: 208 + .saturating_add(Weight::from_parts(41_318, 0).saturating_mul(l.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Nis Queues (r:1 w:1) - /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) - /// Storage: Nis QueueTotals (r:1 w:1) - /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) + /// Storage: `Nis::Queues` (r:1 w:1) + /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `Nis::QueueTotals` (r:1 w:1) + /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) fn place_bid_max() -> Weight { // Proof Size summary in bytes: // Measured: `54178` // Estimated: `51487` - // Minimum execution time: 119_696_000 picoseconds. - Weight::from_parts(121_838_000, 51487) + // Minimum execution time: 100_836_000 picoseconds. + Weight::from_parts(102_497_000, 51487) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Nis Queues (r:1 w:1) - /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) - /// Storage: Nis QueueTotals (r:1 w:1) - /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) + /// Storage: `Nis::Queues` (r:1 w:1) + /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `Nis::QueueTotals` (r:1 w:1) + /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) /// The range of component `l` is `[1, 1000]`. fn retract_bid(l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `6176 + l * (48 ±0)` // Estimated: `51487` - // Minimum execution time: 50_843_000 picoseconds. - Weight::from_parts(54_237_365, 51487) - // Standard Error: 243 - .saturating_add(Weight::from_parts(67_732, 0).saturating_mul(l.into())) + // Minimum execution time: 45_830_000 picoseconds. + Weight::from_parts(46_667_676, 51487) + // Standard Error: 130 + .saturating_add(Weight::from_parts(33_007, 0).saturating_mul(l.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Nis Summary (r:1 w:0) - /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Nis::Summary` (r:1 w:0) + /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn fund_deficit() -> Weight { // Proof Size summary in bytes: // Measured: `191` // Estimated: `3593` - // Minimum execution time: 40_752_000 picoseconds. - Weight::from_parts(41_899_000, 3593) + // Minimum execution time: 30_440_000 picoseconds. + Weight::from_parts(31_240_000, 3593) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Nis Receipts (r:1 w:1) - /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Nis Summary (r:1 w:1) - /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: `Nis::Receipts` (r:1 w:1) + /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Nis::Summary` (r:1 w:1) + /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn communify() -> Weight { // Proof Size summary in bytes: // Measured: `668` // Estimated: `3675` - // Minimum execution time: 79_779_000 picoseconds. - Weight::from_parts(82_478_000, 3675) + // Minimum execution time: 71_017_000 picoseconds. + Weight::from_parts(72_504_000, 3675) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: Nis Receipts (r:1 w:1) - /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) - /// Storage: Nis Summary (r:1 w:1) - /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) + /// Storage: `Nis::Receipts` (r:1 w:1) + /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Storage: `Nis::Summary` (r:1 w:1) + /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) fn privatize() -> Weight { // Proof Size summary in bytes: // Measured: `829` // Estimated: `3675` - // Minimum execution time: 99_588_000 picoseconds. - Weight::from_parts(102_340_000, 3675) + // Minimum execution time: 89_138_000 picoseconds. + Weight::from_parts(91_290_000, 3675) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: Nis Receipts (r:1 w:1) - /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) - /// Storage: Nis Summary (r:1 w:1) - /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:0) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) + /// Storage: `Nis::Receipts` (r:1 w:1) + /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Storage: `Nis::Summary` (r:1 w:1) + /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:0) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) fn thaw_private() -> Weight { // Proof Size summary in bytes: // Measured: `354` - // Estimated: `3593` - // Minimum execution time: 53_094_000 picoseconds. - Weight::from_parts(54_543_000, 3593) + // Estimated: `3658` + // Minimum execution time: 47_917_000 picoseconds. + Weight::from_parts(49_121_000, 3658) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Nis Receipts (r:1 w:1) - /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) - /// Storage: Nis Summary (r:1 w:1) - /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Nis::Receipts` (r:1 w:1) + /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Storage: `Nis::Summary` (r:1 w:1) + /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn thaw_communal() -> Weight { // Proof Size summary in bytes: // Measured: `773` // Estimated: `3675` - // Minimum execution time: 107_248_000 picoseconds. - Weight::from_parts(109_923_000, 3675) + // Minimum execution time: 91_320_000 picoseconds. + Weight::from_parts(93_080_000, 3675) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: Nis Summary (r:1 w:1) - /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:0) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Nis QueueTotals (r:1 w:1) - /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) + /// Storage: `Nis::Summary` (r:1 w:1) + /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:0) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Nis::QueueTotals` (r:1 w:1) + /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) fn process_queues() -> Weight { // Proof Size summary in bytes: // Measured: `6624` // Estimated: `7487` - // Minimum execution time: 27_169_000 picoseconds. - Weight::from_parts(29_201_000, 7487) + // Minimum execution time: 20_117_000 picoseconds. + Weight::from_parts(20_829_000, 7487) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Nis Queues (r:1 w:1) - /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + /// Storage: `Nis::Queues` (r:1 w:1) + /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) fn process_queue() -> Weight { // Proof Size summary in bytes: // Measured: `42` // Estimated: `51487` - // Minimum execution time: 4_540_000 picoseconds. - Weight::from_parts(4_699_000, 51487) + // Minimum execution time: 4_460_000 picoseconds. + Weight::from_parts(4_797_000, 51487) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Nis Receipts (r:0 w:1) - /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: `Nis::Receipts` (r:0 w:1) + /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) fn process_bid() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_085_000 picoseconds. - Weight::from_parts(7_336_000, 0) + // Minimum execution time: 4_609_000 picoseconds. + Weight::from_parts(4_834_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Nis Queues (r:1 w:1) - /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) - /// Storage: Nis QueueTotals (r:1 w:1) - /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) + /// Storage: `Nis::Queues` (r:1 w:1) + /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `Nis::QueueTotals` (r:1 w:1) + /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) /// The range of component `l` is `[0, 999]`. fn place_bid(l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `6176 + l * (48 ±0)` // Estimated: `51487` - // Minimum execution time: 49_410_000 picoseconds. - Weight::from_parts(57_832_282, 51487) - // Standard Error: 288 - .saturating_add(Weight::from_parts(51_621, 0).saturating_mul(l.into())) + // Minimum execution time: 47_908_000 picoseconds. + Weight::from_parts(50_096_676, 51487) + // Standard Error: 208 + .saturating_add(Weight::from_parts(41_318, 0).saturating_mul(l.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Nis Queues (r:1 w:1) - /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) - /// Storage: Nis QueueTotals (r:1 w:1) - /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) + /// Storage: `Nis::Queues` (r:1 w:1) + /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `Nis::QueueTotals` (r:1 w:1) + /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) fn place_bid_max() -> Weight { // Proof Size summary in bytes: // Measured: `54178` // Estimated: `51487` - // Minimum execution time: 119_696_000 picoseconds. - Weight::from_parts(121_838_000, 51487) + // Minimum execution time: 100_836_000 picoseconds. + Weight::from_parts(102_497_000, 51487) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Nis Queues (r:1 w:1) - /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) - /// Storage: Nis QueueTotals (r:1 w:1) - /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) + /// Storage: `Nis::Queues` (r:1 w:1) + /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `Nis::QueueTotals` (r:1 w:1) + /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) /// The range of component `l` is `[1, 1000]`. fn retract_bid(l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `6176 + l * (48 ±0)` // Estimated: `51487` - // Minimum execution time: 50_843_000 picoseconds. - Weight::from_parts(54_237_365, 51487) - // Standard Error: 243 - .saturating_add(Weight::from_parts(67_732, 0).saturating_mul(l.into())) + // Minimum execution time: 45_830_000 picoseconds. + Weight::from_parts(46_667_676, 51487) + // Standard Error: 130 + .saturating_add(Weight::from_parts(33_007, 0).saturating_mul(l.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Nis Summary (r:1 w:0) - /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Nis::Summary` (r:1 w:0) + /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn fund_deficit() -> Weight { // Proof Size summary in bytes: // Measured: `191` // Estimated: `3593` - // Minimum execution time: 40_752_000 picoseconds. - Weight::from_parts(41_899_000, 3593) + // Minimum execution time: 30_440_000 picoseconds. + Weight::from_parts(31_240_000, 3593) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Nis Receipts (r:1 w:1) - /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Nis Summary (r:1 w:1) - /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: `Nis::Receipts` (r:1 w:1) + /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Nis::Summary` (r:1 w:1) + /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn communify() -> Weight { // Proof Size summary in bytes: // Measured: `668` // Estimated: `3675` - // Minimum execution time: 79_779_000 picoseconds. - Weight::from_parts(82_478_000, 3675) + // Minimum execution time: 71_017_000 picoseconds. + Weight::from_parts(72_504_000, 3675) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } - /// Storage: Nis Receipts (r:1 w:1) - /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) - /// Storage: Nis Summary (r:1 w:1) - /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) + /// Storage: `Nis::Receipts` (r:1 w:1) + /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Storage: `Nis::Summary` (r:1 w:1) + /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) fn privatize() -> Weight { // Proof Size summary in bytes: // Measured: `829` // Estimated: `3675` - // Minimum execution time: 99_588_000 picoseconds. - Weight::from_parts(102_340_000, 3675) + // Minimum execution time: 89_138_000 picoseconds. + Weight::from_parts(91_290_000, 3675) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } - /// Storage: Nis Receipts (r:1 w:1) - /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) - /// Storage: Nis Summary (r:1 w:1) - /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:0) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Balances Holds (r:1 w:1) - /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) + /// Storage: `Nis::Receipts` (r:1 w:1) + /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Storage: `Nis::Summary` (r:1 w:1) + /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:0) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) fn thaw_private() -> Weight { // Proof Size summary in bytes: // Measured: `354` - // Estimated: `3593` - // Minimum execution time: 53_094_000 picoseconds. - Weight::from_parts(54_543_000, 3593) + // Estimated: `3658` + // Minimum execution time: 47_917_000 picoseconds. + Weight::from_parts(49_121_000, 3658) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Nis Receipts (r:1 w:1) - /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) - /// Storage: Nis Summary (r:1 w:1) - /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:1 w:1) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Nis::Receipts` (r:1 w:1) + /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Storage: `Nis::Summary` (r:1 w:1) + /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn thaw_communal() -> Weight { // Proof Size summary in bytes: // Measured: `773` // Estimated: `3675` - // Minimum execution time: 107_248_000 picoseconds. - Weight::from_parts(109_923_000, 3675) + // Minimum execution time: 91_320_000 picoseconds. + Weight::from_parts(93_080_000, 3675) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: Nis Summary (r:1 w:1) - /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:0) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Nis QueueTotals (r:1 w:1) - /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) + /// Storage: `Nis::Summary` (r:1 w:1) + /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:0) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Nis::QueueTotals` (r:1 w:1) + /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) fn process_queues() -> Weight { // Proof Size summary in bytes: // Measured: `6624` // Estimated: `7487` - // Minimum execution time: 27_169_000 picoseconds. - Weight::from_parts(29_201_000, 7487) + // Minimum execution time: 20_117_000 picoseconds. + Weight::from_parts(20_829_000, 7487) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Nis Queues (r:1 w:1) - /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + /// Storage: `Nis::Queues` (r:1 w:1) + /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) fn process_queue() -> Weight { // Proof Size summary in bytes: // Measured: `42` // Estimated: `51487` - // Minimum execution time: 4_540_000 picoseconds. - Weight::from_parts(4_699_000, 51487) + // Minimum execution time: 4_460_000 picoseconds. + Weight::from_parts(4_797_000, 51487) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Nis Receipts (r:0 w:1) - /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: `Nis::Receipts` (r:0 w:1) + /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) fn process_bid() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_085_000 picoseconds. - Weight::from_parts(7_336_000, 0) + // Minimum execution time: 4_609_000 picoseconds. + Weight::from_parts(4_834_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } } diff --git a/substrate/frame/nomination-pools/src/weights.rs b/substrate/frame/nomination-pools/src/weights.rs index 047a17c3f9a..2749af7937f 100644 --- a/substrate/frame/nomination-pools/src/weights.rs +++ b/substrate/frame/nomination-pools/src/weights.rs @@ -17,26 +17,28 @@ //! Autogenerated weights for `pallet_nomination_pools` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-11-23, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// target/production/substrate-node +// ./target/production/substrate-node // benchmark // pallet +// --chain=dev // --steps=50 // --repeat=20 +// --pallet=pallet_nomination_pools +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_nomination_pools -// --chain=dev -// --header=./substrate/HEADER-APACHE2 // --output=./substrate/frame/nomination-pools/src/weights.rs +// --header=./substrate/HEADER-APACHE2 // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -112,8 +114,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `3425` // Estimated: `8877` - // Minimum execution time: 184_295_000 picoseconds. - Weight::from_parts(188_860_000, 8877) + // Minimum execution time: 181_861_000 picoseconds. + Weight::from_parts(186_375_000, 8877) .saturating_add(T::DbWeight::get().reads(20_u64)) .saturating_add(T::DbWeight::get().writes(13_u64)) } @@ -145,8 +147,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `3435` // Estimated: `8877` - // Minimum execution time: 188_777_000 picoseconds. - Weight::from_parts(192_646_000, 8877) + // Minimum execution time: 182_273_000 picoseconds. + Weight::from_parts(186_635_000, 8877) .saturating_add(T::DbWeight::get().reads(17_u64)) .saturating_add(T::DbWeight::get().writes(13_u64)) } @@ -180,8 +182,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `3500` // Estimated: `8877` - // Minimum execution time: 221_728_000 picoseconds. - Weight::from_parts(227_569_000, 8877) + // Minimum execution time: 217_878_000 picoseconds. + Weight::from_parts(221_493_000, 8877) .saturating_add(T::DbWeight::get().reads(18_u64)) .saturating_add(T::DbWeight::get().writes(14_u64)) } @@ -201,8 +203,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1172` // Estimated: `3719` - // Minimum execution time: 75_310_000 picoseconds. - Weight::from_parts(77_709_000, 3719) + // Minimum execution time: 74_509_000 picoseconds. + Weight::from_parts(76_683_000, 3719) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -242,8 +244,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `3622` // Estimated: `27847` - // Minimum execution time: 170_656_000 picoseconds. - Weight::from_parts(174_950_000, 27847) + // Minimum execution time: 166_424_000 picoseconds. + Weight::from_parts(169_698_000, 27847) .saturating_add(T::DbWeight::get().reads(20_u64)) .saturating_add(T::DbWeight::get().writes(13_u64)) } @@ -259,18 +261,20 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:0) + /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// Storage: `NominationPools::TotalValueLocked` (r:1 w:1) /// Proof: `NominationPools::TotalValueLocked` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. fn pool_withdraw_unbonded(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1817` + // Measured: `1848` // Estimated: `4764` - // Minimum execution time: 68_866_000 picoseconds. - Weight::from_parts(72_312_887, 4764) - // Standard Error: 1_635 - .saturating_add(Weight::from_parts(41_679, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(7_u64)) + // Minimum execution time: 66_110_000 picoseconds. + Weight::from_parts(68_620_141, 4764) + // Standard Error: 1_379 + .saturating_add(Weight::from_parts(54_961, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `NominationPools::PoolMembers` (r:1 w:1) @@ -291,6 +295,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:0) + /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// Storage: `NominationPools::TotalValueLocked` (r:1 w:1) /// Proof: `NominationPools::TotalValueLocked` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `NominationPools::CounterForPoolMembers` (r:1 w:1) @@ -300,13 +306,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_update(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2207` + // Measured: `2238` // Estimated: `27847` - // Minimum execution time: 131_383_000 picoseconds. - Weight::from_parts(136_595_971, 27847) - // Standard Error: 2_715 - .saturating_add(Weight::from_parts(52_351, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(11_u64)) + // Minimum execution time: 125_669_000 picoseconds. + Weight::from_parts(130_907_641, 27847) + // Standard Error: 2_490 + .saturating_add(Weight::from_parts(75_219, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(9_u64)) } /// Storage: `NominationPools::PoolMembers` (r:1 w:1) @@ -333,12 +339,12 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:0) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:1) + /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// Storage: `NominationPools::TotalValueLocked` (r:1 w:1) /// Proof: `NominationPools::TotalValueLocked` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `NominationPools::CounterForPoolMembers` (r:1 w:1) /// Proof: `NominationPools::CounterForPoolMembers` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:1) - /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// Storage: `NominationPools::CounterForReversePoolIdLookup` (r:1 w:1) /// Proof: `NominationPools::CounterForReversePoolIdLookup` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `NominationPools::RewardPools` (r:1 w:1) @@ -360,8 +366,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2525` // Estimated: `27847` - // Minimum execution time: 233_314_000 picoseconds. - Weight::from_parts(241_694_316, 27847) + // Minimum execution time: 225_700_000 picoseconds. + Weight::from_parts(234_390_990, 27847) .saturating_add(T::DbWeight::get().reads(24_u64)) .saturating_add(T::DbWeight::get().writes(20_u64)) } @@ -413,8 +419,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1169` // Estimated: `8538` - // Minimum execution time: 171_465_000 picoseconds. - Weight::from_parts(176_478_000, 8538) + // Minimum execution time: 167_171_000 picoseconds. + Weight::from_parts(170_531_000, 8538) .saturating_add(T::DbWeight::get().reads(23_u64)) .saturating_add(T::DbWeight::get().writes(17_u64)) } @@ -447,10 +453,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1808` // Estimated: `4556 + n * (2520 ±0)` - // Minimum execution time: 63_588_000 picoseconds. - Weight::from_parts(64_930_584, 4556) - // Standard Error: 9_167 - .saturating_add(Weight::from_parts(1_595_779, 0).saturating_mul(n.into())) + // Minimum execution time: 63_785_000 picoseconds. + Weight::from_parts(64_592_302, 4556) + // Standard Error: 9_416 + .saturating_add(Weight::from_parts(1_524_398, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(5_u64)) @@ -466,8 +472,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1434` // Estimated: `4556` - // Minimum execution time: 32_899_000 picoseconds. - Weight::from_parts(33_955_000, 4556) + // Minimum execution time: 32_096_000 picoseconds. + Weight::from_parts(33_533_000, 4556) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -482,10 +488,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `532` // Estimated: `3735` - // Minimum execution time: 13_778_000 picoseconds. - Weight::from_parts(14_770_006, 3735) - // Standard Error: 151 - .saturating_add(Weight::from_parts(1_900, 0).saturating_mul(n.into())) + // Minimum execution time: 13_914_000 picoseconds. + Weight::from_parts(14_800_402, 3735) + // Standard Error: 146 + .saturating_add(Weight::from_parts(940, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -505,8 +511,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_550_000 picoseconds. - Weight::from_parts(4_935_000, 0) + // Minimum execution time: 4_373_000 picoseconds. + Weight::from_parts(4_592_000, 0) .saturating_add(T::DbWeight::get().writes(6_u64)) } /// Storage: `NominationPools::BondedPools` (r:1 w:1) @@ -515,8 +521,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `532` // Estimated: `3719` - // Minimum execution time: 16_759_000 picoseconds. - Weight::from_parts(17_346_000, 3719) + // Minimum execution time: 16_662_000 picoseconds. + Weight::from_parts(17_531_000, 3719) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -542,8 +548,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1971` // Estimated: `4556` - // Minimum execution time: 61_970_000 picoseconds. - Weight::from_parts(63_738_000, 4556) + // Minimum execution time: 61_348_000 picoseconds. + Weight::from_parts(63_712_000, 4556) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } @@ -559,8 +565,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `804` // Estimated: `3719` - // Minimum execution time: 31_950_000 picoseconds. - Weight::from_parts(33_190_000, 3719) + // Minimum execution time: 32_232_000 picoseconds. + Weight::from_parts(33_433_000, 3719) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -572,8 +578,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `572` // Estimated: `3719` - // Minimum execution time: 16_807_000 picoseconds. - Weight::from_parts(17_733_000, 3719) + // Minimum execution time: 16_774_000 picoseconds. + Weight::from_parts(17_671_000, 3719) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -583,8 +589,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `532` // Estimated: `3719` - // Minimum execution time: 16_710_000 picoseconds. - Weight::from_parts(17_563_000, 3719) + // Minimum execution time: 16_724_000 picoseconds. + Weight::from_parts(17_181_000, 3719) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -594,8 +600,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `532` // Estimated: `3719` - // Minimum execution time: 16_493_000 picoseconds. - Weight::from_parts(17_022_000, 3719) + // Minimum execution time: 16_362_000 picoseconds. + Weight::from_parts(17_135_000, 3719) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -607,8 +613,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `542` // Estimated: `3702` - // Minimum execution time: 14_248_000 picoseconds. - Weight::from_parts(15_095_000, 3702) + // Minimum execution time: 14_125_000 picoseconds. + Weight::from_parts(14_705_000, 3702) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -624,8 +630,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1002` // Estimated: `3719` - // Minimum execution time: 61_969_000 picoseconds. - Weight::from_parts(63_965_000, 3719) + // Minimum execution time: 61_699_000 picoseconds. + Weight::from_parts(63_605_000, 3719) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -641,8 +647,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `901` // Estimated: `4764` - // Minimum execution time: 65_462_000 picoseconds. - Weight::from_parts(67_250_000, 4764) + // Minimum execution time: 64_930_000 picoseconds. + Weight::from_parts(66_068_000, 4764) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -686,8 +692,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `3425` // Estimated: `8877` - // Minimum execution time: 184_295_000 picoseconds. - Weight::from_parts(188_860_000, 8877) + // Minimum execution time: 181_861_000 picoseconds. + Weight::from_parts(186_375_000, 8877) .saturating_add(RocksDbWeight::get().reads(20_u64)) .saturating_add(RocksDbWeight::get().writes(13_u64)) } @@ -719,8 +725,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `3435` // Estimated: `8877` - // Minimum execution time: 188_777_000 picoseconds. - Weight::from_parts(192_646_000, 8877) + // Minimum execution time: 182_273_000 picoseconds. + Weight::from_parts(186_635_000, 8877) .saturating_add(RocksDbWeight::get().reads(17_u64)) .saturating_add(RocksDbWeight::get().writes(13_u64)) } @@ -754,8 +760,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `3500` // Estimated: `8877` - // Minimum execution time: 221_728_000 picoseconds. - Weight::from_parts(227_569_000, 8877) + // Minimum execution time: 217_878_000 picoseconds. + Weight::from_parts(221_493_000, 8877) .saturating_add(RocksDbWeight::get().reads(18_u64)) .saturating_add(RocksDbWeight::get().writes(14_u64)) } @@ -775,8 +781,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1172` // Estimated: `3719` - // Minimum execution time: 75_310_000 picoseconds. - Weight::from_parts(77_709_000, 3719) + // Minimum execution time: 74_509_000 picoseconds. + Weight::from_parts(76_683_000, 3719) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -816,8 +822,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `3622` // Estimated: `27847` - // Minimum execution time: 170_656_000 picoseconds. - Weight::from_parts(174_950_000, 27847) + // Minimum execution time: 166_424_000 picoseconds. + Weight::from_parts(169_698_000, 27847) .saturating_add(RocksDbWeight::get().reads(20_u64)) .saturating_add(RocksDbWeight::get().writes(13_u64)) } @@ -833,18 +839,20 @@ impl WeightInfo for () { /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:0) + /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// Storage: `NominationPools::TotalValueLocked` (r:1 w:1) /// Proof: `NominationPools::TotalValueLocked` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. fn pool_withdraw_unbonded(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1817` + // Measured: `1848` // Estimated: `4764` - // Minimum execution time: 68_866_000 picoseconds. - Weight::from_parts(72_312_887, 4764) - // Standard Error: 1_635 - .saturating_add(Weight::from_parts(41_679, 0).saturating_mul(s.into())) - .saturating_add(RocksDbWeight::get().reads(7_u64)) + // Minimum execution time: 66_110_000 picoseconds. + Weight::from_parts(68_620_141, 4764) + // Standard Error: 1_379 + .saturating_add(Weight::from_parts(54_961, 0).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } /// Storage: `NominationPools::PoolMembers` (r:1 w:1) @@ -865,6 +873,8 @@ impl WeightInfo for () { /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:0) + /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// Storage: `NominationPools::TotalValueLocked` (r:1 w:1) /// Proof: `NominationPools::TotalValueLocked` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `NominationPools::CounterForPoolMembers` (r:1 w:1) @@ -874,13 +884,13 @@ impl WeightInfo for () { /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_update(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2207` + // Measured: `2238` // Estimated: `27847` - // Minimum execution time: 131_383_000 picoseconds. - Weight::from_parts(136_595_971, 27847) - // Standard Error: 2_715 - .saturating_add(Weight::from_parts(52_351, 0).saturating_mul(s.into())) - .saturating_add(RocksDbWeight::get().reads(11_u64)) + // Minimum execution time: 125_669_000 picoseconds. + Weight::from_parts(130_907_641, 27847) + // Standard Error: 2_490 + .saturating_add(Weight::from_parts(75_219, 0).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(9_u64)) } /// Storage: `NominationPools::PoolMembers` (r:1 w:1) @@ -907,12 +917,12 @@ impl WeightInfo for () { /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:0) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) + /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:1) + /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// Storage: `NominationPools::TotalValueLocked` (r:1 w:1) /// Proof: `NominationPools::TotalValueLocked` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `NominationPools::CounterForPoolMembers` (r:1 w:1) /// Proof: `NominationPools::CounterForPoolMembers` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:1) - /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// Storage: `NominationPools::CounterForReversePoolIdLookup` (r:1 w:1) /// Proof: `NominationPools::CounterForReversePoolIdLookup` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `NominationPools::RewardPools` (r:1 w:1) @@ -934,8 +944,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2525` // Estimated: `27847` - // Minimum execution time: 233_314_000 picoseconds. - Weight::from_parts(241_694_316, 27847) + // Minimum execution time: 225_700_000 picoseconds. + Weight::from_parts(234_390_990, 27847) .saturating_add(RocksDbWeight::get().reads(24_u64)) .saturating_add(RocksDbWeight::get().writes(20_u64)) } @@ -987,8 +997,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1169` // Estimated: `8538` - // Minimum execution time: 171_465_000 picoseconds. - Weight::from_parts(176_478_000, 8538) + // Minimum execution time: 167_171_000 picoseconds. + Weight::from_parts(170_531_000, 8538) .saturating_add(RocksDbWeight::get().reads(23_u64)) .saturating_add(RocksDbWeight::get().writes(17_u64)) } @@ -1021,10 +1031,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1808` // Estimated: `4556 + n * (2520 ±0)` - // Minimum execution time: 63_588_000 picoseconds. - Weight::from_parts(64_930_584, 4556) - // Standard Error: 9_167 - .saturating_add(Weight::from_parts(1_595_779, 0).saturating_mul(n.into())) + // Minimum execution time: 63_785_000 picoseconds. + Weight::from_parts(64_592_302, 4556) + // Standard Error: 9_416 + .saturating_add(Weight::from_parts(1_524_398, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes(5_u64)) @@ -1040,8 +1050,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1434` // Estimated: `4556` - // Minimum execution time: 32_899_000 picoseconds. - Weight::from_parts(33_955_000, 4556) + // Minimum execution time: 32_096_000 picoseconds. + Weight::from_parts(33_533_000, 4556) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1056,10 +1066,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `532` // Estimated: `3735` - // Minimum execution time: 13_778_000 picoseconds. - Weight::from_parts(14_770_006, 3735) - // Standard Error: 151 - .saturating_add(Weight::from_parts(1_900, 0).saturating_mul(n.into())) + // Minimum execution time: 13_914_000 picoseconds. + Weight::from_parts(14_800_402, 3735) + // Standard Error: 146 + .saturating_add(Weight::from_parts(940, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -1079,8 +1089,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_550_000 picoseconds. - Weight::from_parts(4_935_000, 0) + // Minimum execution time: 4_373_000 picoseconds. + Weight::from_parts(4_592_000, 0) .saturating_add(RocksDbWeight::get().writes(6_u64)) } /// Storage: `NominationPools::BondedPools` (r:1 w:1) @@ -1089,8 +1099,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `532` // Estimated: `3719` - // Minimum execution time: 16_759_000 picoseconds. - Weight::from_parts(17_346_000, 3719) + // Minimum execution time: 16_662_000 picoseconds. + Weight::from_parts(17_531_000, 3719) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1116,8 +1126,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1971` // Estimated: `4556` - // Minimum execution time: 61_970_000 picoseconds. - Weight::from_parts(63_738_000, 4556) + // Minimum execution time: 61_348_000 picoseconds. + Weight::from_parts(63_712_000, 4556) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } @@ -1133,8 +1143,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `804` // Estimated: `3719` - // Minimum execution time: 31_950_000 picoseconds. - Weight::from_parts(33_190_000, 3719) + // Minimum execution time: 32_232_000 picoseconds. + Weight::from_parts(33_433_000, 3719) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -1146,8 +1156,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `572` // Estimated: `3719` - // Minimum execution time: 16_807_000 picoseconds. - Weight::from_parts(17_733_000, 3719) + // Minimum execution time: 16_774_000 picoseconds. + Weight::from_parts(17_671_000, 3719) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1157,8 +1167,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `532` // Estimated: `3719` - // Minimum execution time: 16_710_000 picoseconds. - Weight::from_parts(17_563_000, 3719) + // Minimum execution time: 16_724_000 picoseconds. + Weight::from_parts(17_181_000, 3719) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1168,8 +1178,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `532` // Estimated: `3719` - // Minimum execution time: 16_493_000 picoseconds. - Weight::from_parts(17_022_000, 3719) + // Minimum execution time: 16_362_000 picoseconds. + Weight::from_parts(17_135_000, 3719) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1181,8 +1191,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `542` // Estimated: `3702` - // Minimum execution time: 14_248_000 picoseconds. - Weight::from_parts(15_095_000, 3702) + // Minimum execution time: 14_125_000 picoseconds. + Weight::from_parts(14_705_000, 3702) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1198,8 +1208,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1002` // Estimated: `3719` - // Minimum execution time: 61_969_000 picoseconds. - Weight::from_parts(63_965_000, 3719) + // Minimum execution time: 61_699_000 picoseconds. + Weight::from_parts(63_605_000, 3719) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -1215,8 +1225,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `901` // Estimated: `4764` - // Minimum execution time: 65_462_000 picoseconds. - Weight::from_parts(67_250_000, 4764) + // Minimum execution time: 64_930_000 picoseconds. + Weight::from_parts(66_068_000, 4764) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } diff --git a/substrate/frame/offences/benchmarking/src/mock.rs b/substrate/frame/offences/benchmarking/src/mock.rs index 01ad8d64f10..b3260f0841f 100644 --- a/substrate/frame/offences/benchmarking/src/mock.rs +++ b/substrate/frame/offences/benchmarking/src/mock.rs @@ -148,7 +148,7 @@ parameter_types! { pub static ElectionsBounds: ElectionBounds = ElectionBoundsBuilder::default().build(); } -pub type Extrinsic = sp_runtime::testing::TestXt; +pub type Extrinsic = sp_runtime::generic::UncheckedExtrinsic; pub struct OnChainSeqPhragmen; impl onchain::Config for OnChainSeqPhragmen { diff --git a/substrate/frame/parameters/src/weights.rs b/substrate/frame/parameters/src/weights.rs index 6746960b1b7..340eb9e31b7 100644 --- a/substrate/frame/parameters/src/weights.rs +++ b/substrate/frame/parameters/src/weights.rs @@ -18,25 +18,27 @@ //! Autogenerated weights for `pallet_parameters` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// target/production/substrate-node +// ./target/production/substrate-node // benchmark // pallet +// --chain=dev // --steps=50 // --repeat=20 +// --pallet=pallet_parameters +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_parameters -// --chain=dev -// --header=./substrate/HEADER-APACHE2 // --output=./substrate/frame/parameters/src/weights.rs +// --header=./substrate/HEADER-APACHE2 // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -55,22 +57,30 @@ pub trait WeightInfo { /// Weights for `pallet_parameters` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { + /// Storage: `Parameters::Parameters` (r:1 w:1) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) fn set_parameter() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) + // Measured: `3` + // Estimated: `3501` + // Minimum execution time: 8_400_000 picoseconds. + Weight::from_parts(8_682_000, 3501) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) } } // For backwards compatibility and tests. impl WeightInfo for () { + /// Storage: `Parameters::Parameters` (r:1 w:1) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) fn set_parameter() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 0_000 picoseconds. - Weight::from_parts(0, 0) + // Measured: `3` + // Estimated: `3501` + // Minimum execution time: 8_400_000 picoseconds. + Weight::from_parts(8_682_000, 3501) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } } diff --git a/substrate/frame/preimage/src/weights.rs b/substrate/frame/preimage/src/weights.rs index c11ab74c1e5..6167cd53029 100644 --- a/substrate/frame/preimage/src/weights.rs +++ b/substrate/frame/preimage/src/weights.rs @@ -17,26 +17,28 @@ //! Autogenerated weights for `pallet_preimage` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-09-06, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-mia4uyug-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// target/production/substrate-node +// ./target/production/substrate-node // benchmark // pallet +// --chain=dev // --steps=50 // --repeat=20 +// --pallet=pallet_preimage +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_preimage -// --chain=dev -// --header=./substrate/HEADER-APACHE2 // --output=./substrate/frame/preimage/src/weights.rs +// --header=./substrate/HEADER-APACHE2 // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -70,200 +72,209 @@ impl WeightInfo for SubstrateWeight { /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Parameters::Parameters` (r:2 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 4194304]`. fn note_preimage(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `42` - // Estimated: `3556` - // Minimum execution time: 15_936_000 picoseconds. - Weight::from_parts(16_271_000, 3556) - // Standard Error: 1 - .saturating_add(Weight::from_parts(1_916, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + // Measured: `112` + // Estimated: `6012` + // Minimum execution time: 48_893_000 picoseconds. + Weight::from_parts(44_072_327, 6012) + // Standard Error: 2 + .saturating_add(Weight::from_parts(1_684, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 4194304]`. fn note_requested_preimage(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `106` + // Measured: `173` // Estimated: `3556` - // Minimum execution time: 16_468_000 picoseconds. - Weight::from_parts(17_031_000, 3556) + // Minimum execution time: 15_675_000 picoseconds. + Weight::from_parts(4_564_145, 3556) // Standard Error: 2 - .saturating_add(Weight::from_parts(1_948, 0).saturating_mul(s.into())) + .saturating_add(Weight::from_parts(1_678, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 4194304]`. fn note_no_deposit_preimage(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `106` + // Measured: `173` // Estimated: `3556` - // Minimum execution time: 16_342_000 picoseconds. - Weight::from_parts(16_535_000, 3556) + // Minimum execution time: 14_959_000 picoseconds. + Weight::from_parts(15_335_000, 3556) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_906, 0).saturating_mul(s.into())) + .saturating_add(Weight::from_parts(1_687, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) fn unnote_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `172` - // Estimated: `3556` - // Minimum execution time: 31_047_000 picoseconds. - Weight::from_parts(34_099_000, 3556) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + // Measured: `311` + // Estimated: `3658` + // Minimum execution time: 47_378_000 picoseconds. + Weight::from_parts(48_776_000, 3658) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) fn unnote_no_deposit_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `144` + // Measured: `211` // Estimated: `3556` - // Minimum execution time: 32_559_000 picoseconds. - Weight::from_parts(36_677_000, 3556) + // Minimum execution time: 20_939_000 picoseconds. + Weight::from_parts(21_577_000, 3556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn request_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `172` + // Measured: `255` // Estimated: `3556` - // Minimum execution time: 27_887_000 picoseconds. - Weight::from_parts(30_303_000, 3556) + // Minimum execution time: 17_945_000 picoseconds. + Weight::from_parts(18_448_000, 3556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn request_no_deposit_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `144` + // Measured: `211` // Estimated: `3556` - // Minimum execution time: 17_256_000 picoseconds. - Weight::from_parts(19_481_000, 3556) + // Minimum execution time: 12_132_000 picoseconds. + Weight::from_parts(12_710_000, 3556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn request_unnoted_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `42` + // Measured: `109` // Estimated: `3556` - // Minimum execution time: 22_344_000 picoseconds. - Weight::from_parts(23_868_000, 3556) + // Minimum execution time: 13_014_000 picoseconds. + Weight::from_parts(13_726_000, 3556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn request_requested_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `106` + // Measured: `173` // Estimated: `3556` - // Minimum execution time: 10_542_000 picoseconds. - Weight::from_parts(11_571_000, 3556) + // Minimum execution time: 9_785_000 picoseconds. + Weight::from_parts(10_266_000, 3556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) fn unrequest_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `144` + // Measured: `211` // Estimated: `3556` - // Minimum execution time: 29_054_000 picoseconds. - Weight::from_parts(32_996_000, 3556) + // Minimum execution time: 18_764_000 picoseconds. + Weight::from_parts(19_635_000, 3556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn unrequest_unnoted_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `106` + // Measured: `173` // Estimated: `3556` - // Minimum execution time: 10_775_000 picoseconds. - Weight::from_parts(11_937_000, 3556) + // Minimum execution time: 9_624_000 picoseconds. + Weight::from_parts(10_044_000, 3556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn unrequest_multi_referenced_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `106` + // Measured: `173` // Estimated: `3556` - // Minimum execution time: 10_696_000 picoseconds. - Weight::from_parts(11_717_000, 3556) + // Minimum execution time: 9_432_000 picoseconds. + Weight::from_parts(9_991_000, 3556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Preimage::StatusFor` (r:1024 w:1024) + /// Storage: `Preimage::StatusFor` (r:1023 w:1023) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) + /// Storage: `System::Account` (r:1023 w:1023) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:0 w:1024) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) - /// The range of component `n` is `[0, 1024]`. + /// Storage: `Parameters::Parameters` (r:2 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1023 w:1023) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:0 w:1023) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// The range of component `n` is `[1, 1024]`. fn ensure_updated(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `193 + n * (91 ±0)` - // Estimated: `3593 + n * (2566 ±0)` - // Minimum execution time: 2_452_000 picoseconds. - Weight::from_parts(2_641_000, 3593) - // Standard Error: 19_797 - .saturating_add(Weight::from_parts(15_620_946, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) - .saturating_add(T::DbWeight::get().writes(1_u64)) - .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 2566).saturating_mul(n.into())) + // Measured: `0 + n * (227 ±0)` + // Estimated: `6012 + n * (2668 ±0)` + // Minimum execution time: 54_056_000 picoseconds. + Weight::from_parts(54_912_000, 6012) + // Standard Error: 42_469 + .saturating_add(Weight::from_parts(50_710_258, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes((4_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2668).saturating_mul(n.into())) } } @@ -272,199 +283,208 @@ impl WeightInfo for () { /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Parameters::Parameters` (r:2 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 4194304]`. fn note_preimage(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `42` - // Estimated: `3556` - // Minimum execution time: 15_936_000 picoseconds. - Weight::from_parts(16_271_000, 3556) - // Standard Error: 1 - .saturating_add(Weight::from_parts(1_916, 0).saturating_mul(s.into())) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) + // Measured: `112` + // Estimated: `6012` + // Minimum execution time: 48_893_000 picoseconds. + Weight::from_parts(44_072_327, 6012) + // Standard Error: 2 + .saturating_add(Weight::from_parts(1_684, 0).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 4194304]`. fn note_requested_preimage(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `106` + // Measured: `173` // Estimated: `3556` - // Minimum execution time: 16_468_000 picoseconds. - Weight::from_parts(17_031_000, 3556) + // Minimum execution time: 15_675_000 picoseconds. + Weight::from_parts(4_564_145, 3556) // Standard Error: 2 - .saturating_add(Weight::from_parts(1_948, 0).saturating_mul(s.into())) + .saturating_add(Weight::from_parts(1_678, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 4194304]`. fn note_no_deposit_preimage(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `106` + // Measured: `173` // Estimated: `3556` - // Minimum execution time: 16_342_000 picoseconds. - Weight::from_parts(16_535_000, 3556) + // Minimum execution time: 14_959_000 picoseconds. + Weight::from_parts(15_335_000, 3556) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_906, 0).saturating_mul(s.into())) + .saturating_add(Weight::from_parts(1_687, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) fn unnote_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `172` - // Estimated: `3556` - // Minimum execution time: 31_047_000 picoseconds. - Weight::from_parts(34_099_000, 3556) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) + // Measured: `311` + // Estimated: `3658` + // Minimum execution time: 47_378_000 picoseconds. + Weight::from_parts(48_776_000, 3658) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) fn unnote_no_deposit_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `144` + // Measured: `211` // Estimated: `3556` - // Minimum execution time: 32_559_000 picoseconds. - Weight::from_parts(36_677_000, 3556) + // Minimum execution time: 20_939_000 picoseconds. + Weight::from_parts(21_577_000, 3556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn request_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `172` + // Measured: `255` // Estimated: `3556` - // Minimum execution time: 27_887_000 picoseconds. - Weight::from_parts(30_303_000, 3556) + // Minimum execution time: 17_945_000 picoseconds. + Weight::from_parts(18_448_000, 3556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn request_no_deposit_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `144` + // Measured: `211` // Estimated: `3556` - // Minimum execution time: 17_256_000 picoseconds. - Weight::from_parts(19_481_000, 3556) + // Minimum execution time: 12_132_000 picoseconds. + Weight::from_parts(12_710_000, 3556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn request_unnoted_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `42` + // Measured: `109` // Estimated: `3556` - // Minimum execution time: 22_344_000 picoseconds. - Weight::from_parts(23_868_000, 3556) + // Minimum execution time: 13_014_000 picoseconds. + Weight::from_parts(13_726_000, 3556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn request_requested_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `106` + // Measured: `173` // Estimated: `3556` - // Minimum execution time: 10_542_000 picoseconds. - Weight::from_parts(11_571_000, 3556) + // Minimum execution time: 9_785_000 picoseconds. + Weight::from_parts(10_266_000, 3556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) fn unrequest_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `144` + // Measured: `211` // Estimated: `3556` - // Minimum execution time: 29_054_000 picoseconds. - Weight::from_parts(32_996_000, 3556) + // Minimum execution time: 18_764_000 picoseconds. + Weight::from_parts(19_635_000, 3556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn unrequest_unnoted_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `106` + // Measured: `173` // Estimated: `3556` - // Minimum execution time: 10_775_000 picoseconds. - Weight::from_parts(11_937_000, 3556) + // Minimum execution time: 9_624_000 picoseconds. + Weight::from_parts(10_044_000, 3556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn unrequest_multi_referenced_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `106` + // Measured: `173` // Estimated: `3556` - // Minimum execution time: 10_696_000 picoseconds. - Weight::from_parts(11_717_000, 3556) + // Minimum execution time: 9_432_000 picoseconds. + Weight::from_parts(9_991_000, 3556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Preimage::StatusFor` (r:1024 w:1024) + /// Storage: `Preimage::StatusFor` (r:1023 w:1023) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) + /// Storage: `System::Account` (r:1023 w:1023) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:0 w:1024) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) - /// The range of component `n` is `[0, 1024]`. + /// Storage: `Parameters::Parameters` (r:2 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1023 w:1023) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:0 w:1023) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// The range of component `n` is `[1, 1024]`. fn ensure_updated(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `193 + n * (91 ±0)` - // Estimated: `3593 + n * (2566 ±0)` - // Minimum execution time: 2_452_000 picoseconds. - Weight::from_parts(2_641_000, 3593) - // Standard Error: 19_797 - .saturating_add(Weight::from_parts(15_620_946, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - .saturating_add(RocksDbWeight::get().writes((2_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 2566).saturating_mul(n.into())) + // Measured: `0 + n * (227 ±0)` + // Estimated: `6012 + n * (2668 ±0)` + // Minimum execution time: 54_056_000 picoseconds. + Weight::from_parts(54_912_000, 6012) + // Standard Error: 42_469 + .saturating_add(Weight::from_parts(50_710_258, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(n.into()))) + .saturating_add(RocksDbWeight::get().writes((4_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2668).saturating_mul(n.into())) } } diff --git a/substrate/frame/proxy/src/weights.rs b/substrate/frame/proxy/src/weights.rs index f30fe73d27a..3c37c91d500 100644 --- a/substrate/frame/proxy/src/weights.rs +++ b/substrate/frame/proxy/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_proxy +//! Autogenerated weights for `pallet_proxy` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/proxy/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/proxy/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_proxy. +/// Weight functions needed for `pallet_proxy`. pub trait WeightInfo { fn proxy(p: u32, ) -> Weight; fn proxy_announced(a: u32, p: u32, ) -> Weight; @@ -64,336 +63,352 @@ pub trait WeightInfo { fn kill_pure(p: u32, ) -> Weight; } -/// Weights for pallet_proxy using the Substrate node and recommended hardware. +/// Weights for `pallet_proxy` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Proxy Proxies (r:1 w:0) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:0) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `p` is `[1, 31]`. fn proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `161 + p * (37 ±0)` + // Measured: `306 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 15_182_000 picoseconds. - Weight::from_parts(15_919_146, 4706) - // Standard Error: 1_586 - .saturating_add(Weight::from_parts(31_768, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(1_u64)) + // Minimum execution time: 18_437_000 picoseconds. + Weight::from_parts(19_610_577, 4706) + // Standard Error: 2_531 + .saturating_add(Weight::from_parts(26_001, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(3_u64)) } - /// Storage: Proxy Proxies (r:1 w:0) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) - /// Storage: Proxy Announcements (r:1 w:1) - /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:0) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: `Proxy::Announcements` (r:1 w:1) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn proxy_announced(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `488 + a * (68 ±0) + p * (37 ±0)` + // Measured: `633 + a * (68 ±0) + p * (37 ±0)` // Estimated: `5698` - // Minimum execution time: 40_256_000 picoseconds. - Weight::from_parts(40_373_648, 5698) - // Standard Error: 3_978 - .saturating_add(Weight::from_parts(166_936, 0).saturating_mul(a.into())) - // Standard Error: 4_110 - .saturating_add(Weight::from_parts(54_329, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(3_u64)) + // Minimum execution time: 40_426_000 picoseconds. + Weight::from_parts(40_200_295, 5698) + // Standard Error: 2_922 + .saturating_add(Weight::from_parts(161_885, 0).saturating_mul(a.into())) + // Standard Error: 3_019 + .saturating_add(Weight::from_parts(69_710, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Proxy Announcements (r:1 w:1) - /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Proxy::Announcements` (r:1 w:1) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn remove_announcement(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `403 + a * (68 ±0)` // Estimated: `5698` - // Minimum execution time: 25_040_000 picoseconds. - Weight::from_parts(25_112_188, 5698) - // Standard Error: 2_143 - .saturating_add(Weight::from_parts(189_027, 0).saturating_mul(a.into())) - // Standard Error: 2_214 - .saturating_add(Weight::from_parts(26_683, 0).saturating_mul(p.into())) + // Minimum execution time: 21_905_000 picoseconds. + Weight::from_parts(22_717_430, 5698) + // Standard Error: 2_004 + .saturating_add(Weight::from_parts(153_390, 0).saturating_mul(a.into())) + // Standard Error: 2_071 + .saturating_add(Weight::from_parts(5_676, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Proxy Announcements (r:1 w:1) - /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Proxy::Announcements` (r:1 w:1) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn reject_announcement(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `403 + a * (68 ±0)` // Estimated: `5698` - // Minimum execution time: 24_884_000 picoseconds. - Weight::from_parts(25_359_291, 5698) - // Standard Error: 2_019 - .saturating_add(Weight::from_parts(181_470, 0).saturating_mul(a.into())) - // Standard Error: 2_086 - .saturating_add(Weight::from_parts(17_725, 0).saturating_mul(p.into())) + // Minimum execution time: 21_974_000 picoseconds. + Weight::from_parts(22_484_324, 5698) + // Standard Error: 1_846 + .saturating_add(Weight::from_parts(153_904, 0).saturating_mul(a.into())) + // Standard Error: 1_907 + .saturating_add(Weight::from_parts(9_616, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Proxy Proxies (r:1 w:0) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) - /// Storage: Proxy Announcements (r:1 w:1) - /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:0) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: `Proxy::Announcements` (r:1 w:1) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn announce(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `420 + a * (68 ±0) + p * (37 ±0)` // Estimated: `5698` - // Minimum execution time: 35_039_000 picoseconds. - Weight::from_parts(36_727_868, 5698) - // Standard Error: 4_463 - .saturating_add(Weight::from_parts(167_060, 0).saturating_mul(a.into())) - // Standard Error: 4_611 - .saturating_add(Weight::from_parts(59_836, 0).saturating_mul(p.into())) + // Minimum execution time: 30_454_000 picoseconds. + Weight::from_parts(32_128_158, 5698) + // Standard Error: 3_778 + .saturating_add(Weight::from_parts(137_366, 0).saturating_mul(a.into())) + // Standard Error: 3_904 + .saturating_add(Weight::from_parts(53_040, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Proxy Proxies (r:1 w:1) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:1) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) /// The range of component `p` is `[1, 31]`. fn add_proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `161 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 25_697_000 picoseconds. - Weight::from_parts(26_611_090, 4706) - // Standard Error: 2_306 - .saturating_add(Weight::from_parts(85_165, 0).saturating_mul(p.into())) + // Minimum execution time: 21_391_000 picoseconds. + Weight::from_parts(22_202_614, 4706) + // Standard Error: 1_750 + .saturating_add(Weight::from_parts(49_639, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Proxy Proxies (r:1 w:1) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:1) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) /// The range of component `p` is `[1, 31]`. fn remove_proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `161 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 25_638_000 picoseconds. - Weight::from_parts(26_904_510, 4706) - // Standard Error: 2_669 - .saturating_add(Weight::from_parts(61_668, 0).saturating_mul(p.into())) + // Minimum execution time: 21_375_000 picoseconds. + Weight::from_parts(22_392_601, 4706) + // Standard Error: 2_415 + .saturating_add(Weight::from_parts(40_345, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Proxy Proxies (r:1 w:1) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:1) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) /// The range of component `p` is `[1, 31]`. fn remove_proxies(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `161 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 22_737_000 picoseconds. - Weight::from_parts(23_618_441, 4706) - // Standard Error: 1_729 - .saturating_add(Weight::from_parts(44_009, 0).saturating_mul(p.into())) + // Minimum execution time: 19_833_000 picoseconds. + Weight::from_parts(20_839_747, 4706) + // Standard Error: 1_742 + .saturating_add(Weight::from_parts(40_874, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Proxy Proxies (r:1 w:1) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:1) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) /// The range of component `p` is `[1, 31]`. fn create_pure(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `173` // Estimated: `4706` - // Minimum execution time: 27_364_000 picoseconds. - Weight::from_parts(28_632_271, 4706) - // Standard Error: 1_613 - .saturating_add(Weight::from_parts(2_453, 0).saturating_mul(p.into())) + // Minimum execution time: 22_231_000 picoseconds. + Weight::from_parts(23_370_995, 4706) + // Standard Error: 1_521 + .saturating_add(Weight::from_parts(4_892, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Proxy Proxies (r:1 w:1) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:1) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) /// The range of component `p` is `[0, 30]`. fn kill_pure(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `198 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 23_552_000 picoseconds. - Weight::from_parts(24_874_553, 4706) - // Standard Error: 1_919 - .saturating_add(Weight::from_parts(38_799, 0).saturating_mul(p.into())) + // Minimum execution time: 20_614_000 picoseconds. + Weight::from_parts(21_845_970, 4706) + // Standard Error: 1_636 + .saturating_add(Weight::from_parts(34_480, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Proxy Proxies (r:1 w:0) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:0) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `p` is `[1, 31]`. fn proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `161 + p * (37 ±0)` + // Measured: `306 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 15_182_000 picoseconds. - Weight::from_parts(15_919_146, 4706) - // Standard Error: 1_586 - .saturating_add(Weight::from_parts(31_768, 0).saturating_mul(p.into())) - .saturating_add(RocksDbWeight::get().reads(1_u64)) + // Minimum execution time: 18_437_000 picoseconds. + Weight::from_parts(19_610_577, 4706) + // Standard Error: 2_531 + .saturating_add(Weight::from_parts(26_001, 0).saturating_mul(p.into())) + .saturating_add(RocksDbWeight::get().reads(3_u64)) } - /// Storage: Proxy Proxies (r:1 w:0) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) - /// Storage: Proxy Announcements (r:1 w:1) - /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:0) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: `Proxy::Announcements` (r:1 w:1) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn proxy_announced(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `488 + a * (68 ±0) + p * (37 ±0)` + // Measured: `633 + a * (68 ±0) + p * (37 ±0)` // Estimated: `5698` - // Minimum execution time: 40_256_000 picoseconds. - Weight::from_parts(40_373_648, 5698) - // Standard Error: 3_978 - .saturating_add(Weight::from_parts(166_936, 0).saturating_mul(a.into())) - // Standard Error: 4_110 - .saturating_add(Weight::from_parts(54_329, 0).saturating_mul(p.into())) - .saturating_add(RocksDbWeight::get().reads(3_u64)) + // Minimum execution time: 40_426_000 picoseconds. + Weight::from_parts(40_200_295, 5698) + // Standard Error: 2_922 + .saturating_add(Weight::from_parts(161_885, 0).saturating_mul(a.into())) + // Standard Error: 3_019 + .saturating_add(Weight::from_parts(69_710, 0).saturating_mul(p.into())) + .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Proxy Announcements (r:1 w:1) - /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Proxy::Announcements` (r:1 w:1) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn remove_announcement(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `403 + a * (68 ±0)` // Estimated: `5698` - // Minimum execution time: 25_040_000 picoseconds. - Weight::from_parts(25_112_188, 5698) - // Standard Error: 2_143 - .saturating_add(Weight::from_parts(189_027, 0).saturating_mul(a.into())) - // Standard Error: 2_214 - .saturating_add(Weight::from_parts(26_683, 0).saturating_mul(p.into())) + // Minimum execution time: 21_905_000 picoseconds. + Weight::from_parts(22_717_430, 5698) + // Standard Error: 2_004 + .saturating_add(Weight::from_parts(153_390, 0).saturating_mul(a.into())) + // Standard Error: 2_071 + .saturating_add(Weight::from_parts(5_676, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Proxy Announcements (r:1 w:1) - /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Proxy::Announcements` (r:1 w:1) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn reject_announcement(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `403 + a * (68 ±0)` // Estimated: `5698` - // Minimum execution time: 24_884_000 picoseconds. - Weight::from_parts(25_359_291, 5698) - // Standard Error: 2_019 - .saturating_add(Weight::from_parts(181_470, 0).saturating_mul(a.into())) - // Standard Error: 2_086 - .saturating_add(Weight::from_parts(17_725, 0).saturating_mul(p.into())) + // Minimum execution time: 21_974_000 picoseconds. + Weight::from_parts(22_484_324, 5698) + // Standard Error: 1_846 + .saturating_add(Weight::from_parts(153_904, 0).saturating_mul(a.into())) + // Standard Error: 1_907 + .saturating_add(Weight::from_parts(9_616, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Proxy Proxies (r:1 w:0) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) - /// Storage: Proxy Announcements (r:1 w:1) - /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:0) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: `Proxy::Announcements` (r:1 w:1) + /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn announce(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `420 + a * (68 ±0) + p * (37 ±0)` // Estimated: `5698` - // Minimum execution time: 35_039_000 picoseconds. - Weight::from_parts(36_727_868, 5698) - // Standard Error: 4_463 - .saturating_add(Weight::from_parts(167_060, 0).saturating_mul(a.into())) - // Standard Error: 4_611 - .saturating_add(Weight::from_parts(59_836, 0).saturating_mul(p.into())) + // Minimum execution time: 30_454_000 picoseconds. + Weight::from_parts(32_128_158, 5698) + // Standard Error: 3_778 + .saturating_add(Weight::from_parts(137_366, 0).saturating_mul(a.into())) + // Standard Error: 3_904 + .saturating_add(Weight::from_parts(53_040, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Proxy Proxies (r:1 w:1) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:1) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) /// The range of component `p` is `[1, 31]`. fn add_proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `161 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 25_697_000 picoseconds. - Weight::from_parts(26_611_090, 4706) - // Standard Error: 2_306 - .saturating_add(Weight::from_parts(85_165, 0).saturating_mul(p.into())) + // Minimum execution time: 21_391_000 picoseconds. + Weight::from_parts(22_202_614, 4706) + // Standard Error: 1_750 + .saturating_add(Weight::from_parts(49_639, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Proxy Proxies (r:1 w:1) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:1) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) /// The range of component `p` is `[1, 31]`. fn remove_proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `161 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 25_638_000 picoseconds. - Weight::from_parts(26_904_510, 4706) - // Standard Error: 2_669 - .saturating_add(Weight::from_parts(61_668, 0).saturating_mul(p.into())) + // Minimum execution time: 21_375_000 picoseconds. + Weight::from_parts(22_392_601, 4706) + // Standard Error: 2_415 + .saturating_add(Weight::from_parts(40_345, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Proxy Proxies (r:1 w:1) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:1) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) /// The range of component `p` is `[1, 31]`. fn remove_proxies(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `161 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 22_737_000 picoseconds. - Weight::from_parts(23_618_441, 4706) - // Standard Error: 1_729 - .saturating_add(Weight::from_parts(44_009, 0).saturating_mul(p.into())) + // Minimum execution time: 19_833_000 picoseconds. + Weight::from_parts(20_839_747, 4706) + // Standard Error: 1_742 + .saturating_add(Weight::from_parts(40_874, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Proxy Proxies (r:1 w:1) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:1) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) /// The range of component `p` is `[1, 31]`. fn create_pure(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `173` // Estimated: `4706` - // Minimum execution time: 27_364_000 picoseconds. - Weight::from_parts(28_632_271, 4706) - // Standard Error: 1_613 - .saturating_add(Weight::from_parts(2_453, 0).saturating_mul(p.into())) + // Minimum execution time: 22_231_000 picoseconds. + Weight::from_parts(23_370_995, 4706) + // Standard Error: 1_521 + .saturating_add(Weight::from_parts(4_892, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Proxy Proxies (r:1 w:1) - /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: `Proxy::Proxies` (r:1 w:1) + /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) /// The range of component `p` is `[0, 30]`. fn kill_pure(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `198 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 23_552_000 picoseconds. - Weight::from_parts(24_874_553, 4706) - // Standard Error: 1_919 - .saturating_add(Weight::from_parts(38_799, 0).saturating_mul(p.into())) + // Minimum execution time: 20_614_000 picoseconds. + Weight::from_parts(21_845_970, 4706) + // Standard Error: 1_636 + .saturating_add(Weight::from_parts(34_480, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/ranked-collective/src/weights.rs b/substrate/frame/ranked-collective/src/weights.rs index 4ff0c3337d5..5721858f7e2 100644 --- a/substrate/frame/ranked-collective/src/weights.rs +++ b/substrate/frame/ranked-collective/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_ranked_collective +//! Autogenerated weights for `pallet_ranked_collective` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/ranked-collective/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/ranked-collective/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_ranked_collective. +/// Weight functions needed for `pallet_ranked_collective`. pub trait WeightInfo { fn add_member() -> Weight; fn remove_member(r: u32, ) -> Weight; @@ -61,283 +60,295 @@ pub trait WeightInfo { fn exchange_member() -> Weight; } -/// Weights for pallet_ranked_collective using the Substrate node and recommended hardware. +/// Weights for `pallet_ranked_collective` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: RankedCollective Members (r:1 w:1) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: RankedCollective MemberCount (r:1 w:1) - /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: RankedCollective IndexToId (r:0 w:1) - /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) - /// Storage: RankedCollective IdToIndex (r:0 w:1) - /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:1) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::MemberCount` (r:1 w:1) + /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IndexToId` (r:0 w:1) + /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IdToIndex` (r:0 w:1) + /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn add_member() -> Weight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3507` - // Minimum execution time: 17_245_000 picoseconds. - Weight::from_parts(17_930_000, 3507) + // Minimum execution time: 15_389_000 picoseconds. + Weight::from_parts(15_901_000, 3507) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: RankedCollective Members (r:1 w:1) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: RankedCollective MemberCount (r:11 w:11) - /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: RankedCollective IdToIndex (r:11 w:11) - /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) - /// Storage: RankedCollective IndexToId (r:11 w:11) - /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:1) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::MemberCount` (r:11 w:11) + /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IdToIndex` (r:11 w:22) + /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IndexToId` (r:11 w:22) + /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 10]`. fn remove_member(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `616 + r * (281 ±0)` // Estimated: `3519 + r * (2529 ±0)` - // Minimum execution time: 29_534_000 picoseconds. - Weight::from_parts(32_847_495, 3519) - // Standard Error: 24_211 - .saturating_add(Weight::from_parts(13_949_639, 0).saturating_mul(r.into())) + // Minimum execution time: 29_541_000 picoseconds. + Weight::from_parts(32_239_358, 3519) + // Standard Error: 23_406 + .saturating_add(Weight::from_parts(16_030_191, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) - .saturating_add(T::DbWeight::get().writes(4_u64)) - .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(6_u64)) + .saturating_add(T::DbWeight::get().writes((5_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2529).saturating_mul(r.into())) } - /// Storage: RankedCollective Members (r:1 w:1) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: RankedCollective MemberCount (r:1 w:1) - /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: RankedCollective IndexToId (r:0 w:1) - /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) - /// Storage: RankedCollective IdToIndex (r:0 w:1) - /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:1) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::MemberCount` (r:1 w:1) + /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IndexToId` (r:0 w:1) + /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IdToIndex` (r:0 w:1) + /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 10]`. fn promote_member(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `314 + r * (17 ±0)` // Estimated: `3507` - // Minimum execution time: 20_333_000 picoseconds. - Weight::from_parts(21_592_224, 3507) - // Standard Error: 6_423 - .saturating_add(Weight::from_parts(321_314, 0).saturating_mul(r.into())) + // Minimum execution time: 17_939_000 picoseconds. + Weight::from_parts(19_290_416, 3507) + // Standard Error: 5_710 + .saturating_add(Weight::from_parts(374_399, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: RankedCollective Members (r:1 w:1) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: RankedCollective MemberCount (r:1 w:1) - /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: RankedCollective IdToIndex (r:1 w:1) - /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) - /// Storage: RankedCollective IndexToId (r:1 w:1) - /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:1) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::MemberCount` (r:1 w:1) + /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IdToIndex` (r:1 w:2) + /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IndexToId` (r:1 w:2) + /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 10]`. fn demote_member(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `632 + r * (72 ±0)` // Estimated: `3519` - // Minimum execution time: 29_446_000 picoseconds. - Weight::from_parts(32_447_715, 3519) - // Standard Error: 28_791 - .saturating_add(Weight::from_parts(822_890, 0).saturating_mul(r.into())) + // Minimum execution time: 29_609_000 picoseconds. + Weight::from_parts(32_686_167, 3519) + // Standard Error: 27_588 + .saturating_add(Weight::from_parts(789_212, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) + .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: RankedCollective Members (r:1 w:0) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: RankedPolls ReferendumInfoFor (r:1 w:1) - /// Proof: RankedPolls ReferendumInfoFor (max_values: None, max_size: Some(330), added: 2805, mode: MaxEncodedLen) - /// Storage: RankedCollective Voting (r:1 w:1) - /// Proof: RankedCollective Voting (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:0) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `RankedPolls::ReferendumInfoFor` (r:1 w:1) + /// Proof: `RankedPolls::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(330), added: 2805, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::Voting` (r:1 w:1) + /// Proof: `RankedCollective::Voting` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn vote() -> Weight { // Proof Size summary in bytes: // Measured: `628` // Estimated: `219984` - // Minimum execution time: 45_474_000 picoseconds. - Weight::from_parts(47_228_000, 219984) + // Minimum execution time: 41_151_000 picoseconds. + Weight::from_parts(42_435_000, 219984) .saturating_add(T::DbWeight::get().reads(5_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: RankedPolls ReferendumInfoFor (r:1 w:0) - /// Proof: RankedPolls ReferendumInfoFor (max_values: None, max_size: Some(330), added: 2805, mode: MaxEncodedLen) - /// Storage: RankedCollective VotingCleanup (r:1 w:0) - /// Proof: RankedCollective VotingCleanup (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) - /// Storage: RankedCollective Voting (r:100 w:100) - /// Proof: RankedCollective Voting (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: `RankedPolls::ReferendumInfoFor` (r:1 w:0) + /// Proof: `RankedPolls::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(330), added: 2805, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::VotingCleanup` (r:1 w:0) + /// Proof: `RankedCollective::VotingCleanup` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::Voting` (r:100 w:100) + /// Proof: `RankedCollective::Voting` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 100]`. fn cleanup_poll(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `462 + n * (50 ±0)` // Estimated: `3795 + n * (2540 ±0)` - // Minimum execution time: 13_903_000 picoseconds. - Weight::from_parts(18_209_102, 3795) - // Standard Error: 2_556 - .saturating_add(Weight::from_parts(1_237_454, 0).saturating_mul(n.into())) + // Minimum execution time: 13_563_000 picoseconds. + Weight::from_parts(17_495_215, 3795) + // Standard Error: 2_294 + .saturating_add(Weight::from_parts(1_207_393, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) .saturating_add(Weight::from_parts(0, 2540).saturating_mul(n.into())) } - /// Storage: `RankedCollective::Members` (r:2 w:2) /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) /// Storage: `RankedCollective::MemberCount` (r:2 w:2) /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:2 w:2) + /// Storage: `RankedCollective::IdToIndex` (r:2 w:4) /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::Member` (r:2 w:2) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:0) + /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) + /// Storage: `Salary::Claimant` (r:2 w:2) + /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) /// Storage: `RankedCollective::IndexToId` (r:0 w:2) /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn exchange_member() -> Weight { // Proof Size summary in bytes: - // Measured: `437` - // Estimated: `6048` - // Minimum execution time: 138_000_000 picoseconds. - Weight::from_parts(141_000_000, 0) - .saturating_add(Weight::from_parts(0, 6048)) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(8)) + // Measured: `625` + // Estimated: `19894` + // Minimum execution time: 70_713_000 picoseconds. + Weight::from_parts(72_831_000, 19894) + .saturating_add(T::DbWeight::get().reads(11_u64)) + .saturating_add(T::DbWeight::get().writes(14_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: RankedCollective Members (r:1 w:1) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: RankedCollective MemberCount (r:1 w:1) - /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: RankedCollective IndexToId (r:0 w:1) - /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) - /// Storage: RankedCollective IdToIndex (r:0 w:1) - /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:1) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::MemberCount` (r:1 w:1) + /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IndexToId` (r:0 w:1) + /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IdToIndex` (r:0 w:1) + /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn add_member() -> Weight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3507` - // Minimum execution time: 17_245_000 picoseconds. - Weight::from_parts(17_930_000, 3507) + // Minimum execution time: 15_389_000 picoseconds. + Weight::from_parts(15_901_000, 3507) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: RankedCollective Members (r:1 w:1) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: RankedCollective MemberCount (r:11 w:11) - /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: RankedCollective IdToIndex (r:11 w:11) - /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) - /// Storage: RankedCollective IndexToId (r:11 w:11) - /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:1) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::MemberCount` (r:11 w:11) + /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IdToIndex` (r:11 w:22) + /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IndexToId` (r:11 w:22) + /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 10]`. fn remove_member(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `616 + r * (281 ±0)` // Estimated: `3519 + r * (2529 ±0)` - // Minimum execution time: 29_534_000 picoseconds. - Weight::from_parts(32_847_495, 3519) - // Standard Error: 24_211 - .saturating_add(Weight::from_parts(13_949_639, 0).saturating_mul(r.into())) + // Minimum execution time: 29_541_000 picoseconds. + Weight::from_parts(32_239_358, 3519) + // Standard Error: 23_406 + .saturating_add(Weight::from_parts(16_030_191, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) - .saturating_add(RocksDbWeight::get().writes(4_u64)) - .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(r.into()))) + .saturating_add(RocksDbWeight::get().writes(6_u64)) + .saturating_add(RocksDbWeight::get().writes((5_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2529).saturating_mul(r.into())) } - /// Storage: RankedCollective Members (r:1 w:1) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: RankedCollective MemberCount (r:1 w:1) - /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: RankedCollective IndexToId (r:0 w:1) - /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) - /// Storage: RankedCollective IdToIndex (r:0 w:1) - /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:1) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::MemberCount` (r:1 w:1) + /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IndexToId` (r:0 w:1) + /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IdToIndex` (r:0 w:1) + /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 10]`. fn promote_member(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `314 + r * (17 ±0)` // Estimated: `3507` - // Minimum execution time: 20_333_000 picoseconds. - Weight::from_parts(21_592_224, 3507) - // Standard Error: 6_423 - .saturating_add(Weight::from_parts(321_314, 0).saturating_mul(r.into())) + // Minimum execution time: 17_939_000 picoseconds. + Weight::from_parts(19_290_416, 3507) + // Standard Error: 5_710 + .saturating_add(Weight::from_parts(374_399, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: RankedCollective Members (r:1 w:1) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: RankedCollective MemberCount (r:1 w:1) - /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: RankedCollective IdToIndex (r:1 w:1) - /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) - /// Storage: RankedCollective IndexToId (r:1 w:1) - /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:1) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::MemberCount` (r:1 w:1) + /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IdToIndex` (r:1 w:2) + /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::IndexToId` (r:1 w:2) + /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) /// The range of component `r` is `[0, 10]`. fn demote_member(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `632 + r * (72 ±0)` // Estimated: `3519` - // Minimum execution time: 29_446_000 picoseconds. - Weight::from_parts(32_447_715, 3519) - // Standard Error: 28_791 - .saturating_add(Weight::from_parts(822_890, 0).saturating_mul(r.into())) + // Minimum execution time: 29_609_000 picoseconds. + Weight::from_parts(32_686_167, 3519) + // Standard Error: 27_588 + .saturating_add(Weight::from_parts(789_212, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(4_u64)) + .saturating_add(RocksDbWeight::get().writes(6_u64)) } - /// Storage: RankedCollective Members (r:1 w:0) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: RankedPolls ReferendumInfoFor (r:1 w:1) - /// Proof: RankedPolls ReferendumInfoFor (max_values: None, max_size: Some(330), added: 2805, mode: MaxEncodedLen) - /// Storage: RankedCollective Voting (r:1 w:1) - /// Proof: RankedCollective Voting (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:0) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `RankedPolls::ReferendumInfoFor` (r:1 w:1) + /// Proof: `RankedPolls::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(330), added: 2805, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::Voting` (r:1 w:1) + /// Proof: `RankedCollective::Voting` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn vote() -> Weight { // Proof Size summary in bytes: // Measured: `628` // Estimated: `219984` - // Minimum execution time: 45_474_000 picoseconds. - Weight::from_parts(47_228_000, 219984) + // Minimum execution time: 41_151_000 picoseconds. + Weight::from_parts(42_435_000, 219984) .saturating_add(RocksDbWeight::get().reads(5_u64)) - .saturating_add(RocksDbWeight::get().writes(4_u64)) + .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: RankedPolls ReferendumInfoFor (r:1 w:0) - /// Proof: RankedPolls ReferendumInfoFor (max_values: None, max_size: Some(330), added: 2805, mode: MaxEncodedLen) - /// Storage: RankedCollective VotingCleanup (r:1 w:0) - /// Proof: RankedCollective VotingCleanup (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) - /// Storage: RankedCollective Voting (r:100 w:100) - /// Proof: RankedCollective Voting (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: `RankedPolls::ReferendumInfoFor` (r:1 w:0) + /// Proof: `RankedPolls::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(330), added: 2805, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::VotingCleanup` (r:1 w:0) + /// Proof: `RankedCollective::VotingCleanup` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::Voting` (r:100 w:100) + /// Proof: `RankedCollective::Voting` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 100]`. fn cleanup_poll(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `462 + n * (50 ±0)` // Estimated: `3795 + n * (2540 ±0)` - // Minimum execution time: 13_903_000 picoseconds. - Weight::from_parts(18_209_102, 3795) - // Standard Error: 2_556 - .saturating_add(Weight::from_parts(1_237_454, 0).saturating_mul(n.into())) + // Minimum execution time: 13_563_000 picoseconds. + Weight::from_parts(17_495_215, 3795) + // Standard Error: 2_294 + .saturating_add(Weight::from_parts(1_207_393, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into()))) .saturating_add(Weight::from_parts(0, 2540).saturating_mul(n.into())) } - /// Storage: `RankedCollective::Members` (r:2 w:2) /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) /// Storage: `RankedCollective::MemberCount` (r:2 w:2) /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:2 w:2) + /// Storage: `RankedCollective::IdToIndex` (r:2 w:4) /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::Member` (r:2 w:2) + /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:0) + /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) + /// Storage: `Salary::Claimant` (r:2 w:2) + /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) /// Storage: `RankedCollective::IndexToId` (r:0 w:2) /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn exchange_member() -> Weight { // Proof Size summary in bytes: - // Measured: `437` - // Estimated: `6048` - // Minimum execution time: 138_000_000 picoseconds. - Weight::from_parts(141_000_000, 0) - .saturating_add(Weight::from_parts(0, 6048)) - .saturating_add(RocksDbWeight::get().reads(6)) - .saturating_add(RocksDbWeight::get().writes(8)) + // Measured: `625` + // Estimated: `19894` + // Minimum execution time: 70_713_000 picoseconds. + Weight::from_parts(72_831_000, 19894) + .saturating_add(RocksDbWeight::get().reads(11_u64)) + .saturating_add(RocksDbWeight::get().writes(14_u64)) } } diff --git a/substrate/frame/recovery/src/weights.rs b/substrate/frame/recovery/src/weights.rs index 84b19ae694e..fe5dbcfc222 100644 --- a/substrate/frame/recovery/src/weights.rs +++ b/substrate/frame/recovery/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_recovery +//! Autogenerated weights for `pallet_recovery` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/recovery/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/recovery/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_recovery. +/// Weight functions needed for `pallet_recovery`. pub trait WeightInfo { fn as_recovered() -> Weight; fn set_recovered() -> Weight; @@ -63,258 +62,266 @@ pub trait WeightInfo { fn cancel_recovered() -> Weight; } -/// Weights for pallet_recovery using the Substrate node and recommended hardware. +/// Weights for `pallet_recovery` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Recovery Proxy (r:1 w:0) - /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) + /// Storage: `Recovery::Proxy` (r:1 w:0) + /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) fn as_recovered() -> Weight { // Proof Size summary in bytes: - // Measured: `281` - // Estimated: `3545` - // Minimum execution time: 9_360_000 picoseconds. - Weight::from_parts(9_773_000, 3545) - .saturating_add(T::DbWeight::get().reads(1_u64)) + // Measured: `497` + // Estimated: `3997` + // Minimum execution time: 14_898_000 picoseconds. + Weight::from_parts(15_464_000, 3997) + .saturating_add(T::DbWeight::get().reads(3_u64)) } - /// Storage: Recovery Proxy (r:0 w:1) - /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) + /// Storage: `Recovery::Proxy` (r:0 w:1) + /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) fn set_recovered() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_146_000 picoseconds. - Weight::from_parts(9_507_000, 0) + // Minimum execution time: 7_424_000 picoseconds. + Weight::from_parts(7_830_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Recovery Recoverable (r:1 w:1) - /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// Storage: `Recovery::Recoverable` (r:1 w:1) + /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 9]`. fn create_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `175` + // Measured: `246` // Estimated: `3816` - // Minimum execution time: 26_472_000 picoseconds. - Weight::from_parts(27_917_651, 3816) - // Standard Error: 7_129 - .saturating_add(Weight::from_parts(59_239, 0).saturating_mul(n.into())) + // Minimum execution time: 21_968_000 picoseconds. + Weight::from_parts(23_594_232, 3816) + // Standard Error: 5_848 + .saturating_add(Weight::from_parts(24_843, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Recovery Recoverable (r:1 w:0) - /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) - /// Storage: Recovery ActiveRecoveries (r:1 w:1) - /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + /// Storage: `Recovery::Recoverable` (r:1 w:0) + /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) + /// Storage: `Recovery::ActiveRecoveries` (r:1 w:1) + /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) fn initiate_recovery() -> Weight { // Proof Size summary in bytes: - // Measured: `272` + // Measured: `343` // Estimated: `3854` - // Minimum execution time: 29_618_000 picoseconds. - Weight::from_parts(30_192_000, 3854) + // Minimum execution time: 25_494_000 picoseconds. + Weight::from_parts(26_290_000, 3854) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Recovery Recoverable (r:1 w:0) - /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) - /// Storage: Recovery ActiveRecoveries (r:1 w:1) - /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + /// Storage: `Recovery::Recoverable` (r:1 w:0) + /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) + /// Storage: `Recovery::ActiveRecoveries` (r:1 w:1) + /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 9]`. fn vouch_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `360 + n * (64 ±0)` + // Measured: `431 + n * (64 ±0)` // Estimated: `3854` - // Minimum execution time: 19_464_000 picoseconds. - Weight::from_parts(20_642_522, 3854) - // Standard Error: 5_974 - .saturating_add(Weight::from_parts(142_308, 0).saturating_mul(n.into())) + // Minimum execution time: 17_044_000 picoseconds. + Weight::from_parts(18_299_617, 3854) + // Standard Error: 5_580 + .saturating_add(Weight::from_parts(187_568, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Recovery Recoverable (r:1 w:0) - /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) - /// Storage: Recovery ActiveRecoveries (r:1 w:0) - /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) - /// Storage: Recovery Proxy (r:1 w:1) - /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) + /// Storage: `Recovery::Recoverable` (r:1 w:0) + /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) + /// Storage: `Recovery::ActiveRecoveries` (r:1 w:0) + /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) + /// Storage: `Recovery::Proxy` (r:1 w:1) + /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 9]`. fn claim_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `392 + n * (64 ±0)` + // Measured: `463 + n * (64 ±0)` // Estimated: `3854` - // Minimum execution time: 23_656_000 picoseconds. - Weight::from_parts(24_903_269, 3854) - // Standard Error: 5_771 - .saturating_add(Weight::from_parts(117_343, 0).saturating_mul(n.into())) + // Minimum execution time: 22_186_000 picoseconds. + Weight::from_parts(23_476_807, 3854) + // Standard Error: 6_392 + .saturating_add(Weight::from_parts(89_770, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Recovery ActiveRecoveries (r:1 w:1) - /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Recovery::ActiveRecoveries` (r:1 w:1) + /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 9]`. fn close_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `513 + n * (32 ±0)` + // Measured: `584 + n * (32 ±0)` // Estimated: `3854` - // Minimum execution time: 34_866_000 picoseconds. - Weight::from_parts(36_368_748, 3854) - // Standard Error: 6_600 - .saturating_add(Weight::from_parts(118_610, 0).saturating_mul(n.into())) + // Minimum execution time: 31_045_000 picoseconds. + Weight::from_parts(32_623_578, 3854) + // Standard Error: 7_203 + .saturating_add(Weight::from_parts(61_466, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Recovery ActiveRecoveries (r:1 w:0) - /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) - /// Storage: Recovery Recoverable (r:1 w:1) - /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// Storage: `Recovery::ActiveRecoveries` (r:1 w:0) + /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) + /// Storage: `Recovery::Recoverable` (r:1 w:1) + /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 9]`. fn remove_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `270 + n * (32 ±0)` + // Measured: `341 + n * (32 ±0)` // Estimated: `3854` - // Minimum execution time: 31_405_000 picoseconds. - Weight::from_parts(32_552_838, 3854) - // Standard Error: 8_043 - .saturating_add(Weight::from_parts(171_605, 0).saturating_mul(n.into())) + // Minimum execution time: 27_925_000 picoseconds. + Weight::from_parts(29_258_264, 3854) + // Standard Error: 8_192 + .saturating_add(Weight::from_parts(128_124, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Recovery Proxy (r:1 w:1) - /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) + /// Storage: `Recovery::Proxy` (r:1 w:1) + /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) fn cancel_recovered() -> Weight { // Proof Size summary in bytes: - // Measured: `281` + // Measured: `352` // Estimated: `3545` - // Minimum execution time: 11_530_000 picoseconds. - Weight::from_parts(11_851_000, 3545) + // Minimum execution time: 11_623_000 picoseconds. + Weight::from_parts(12_043_000, 3545) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Recovery Proxy (r:1 w:0) - /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) + /// Storage: `Recovery::Proxy` (r:1 w:0) + /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) fn as_recovered() -> Weight { // Proof Size summary in bytes: - // Measured: `281` - // Estimated: `3545` - // Minimum execution time: 9_360_000 picoseconds. - Weight::from_parts(9_773_000, 3545) - .saturating_add(RocksDbWeight::get().reads(1_u64)) + // Measured: `497` + // Estimated: `3997` + // Minimum execution time: 14_898_000 picoseconds. + Weight::from_parts(15_464_000, 3997) + .saturating_add(RocksDbWeight::get().reads(3_u64)) } - /// Storage: Recovery Proxy (r:0 w:1) - /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) + /// Storage: `Recovery::Proxy` (r:0 w:1) + /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) fn set_recovered() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_146_000 picoseconds. - Weight::from_parts(9_507_000, 0) + // Minimum execution time: 7_424_000 picoseconds. + Weight::from_parts(7_830_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Recovery Recoverable (r:1 w:1) - /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// Storage: `Recovery::Recoverable` (r:1 w:1) + /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 9]`. fn create_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `175` + // Measured: `246` // Estimated: `3816` - // Minimum execution time: 26_472_000 picoseconds. - Weight::from_parts(27_917_651, 3816) - // Standard Error: 7_129 - .saturating_add(Weight::from_parts(59_239, 0).saturating_mul(n.into())) + // Minimum execution time: 21_968_000 picoseconds. + Weight::from_parts(23_594_232, 3816) + // Standard Error: 5_848 + .saturating_add(Weight::from_parts(24_843, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Recovery Recoverable (r:1 w:0) - /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) - /// Storage: Recovery ActiveRecoveries (r:1 w:1) - /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + /// Storage: `Recovery::Recoverable` (r:1 w:0) + /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) + /// Storage: `Recovery::ActiveRecoveries` (r:1 w:1) + /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) fn initiate_recovery() -> Weight { // Proof Size summary in bytes: - // Measured: `272` + // Measured: `343` // Estimated: `3854` - // Minimum execution time: 29_618_000 picoseconds. - Weight::from_parts(30_192_000, 3854) + // Minimum execution time: 25_494_000 picoseconds. + Weight::from_parts(26_290_000, 3854) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Recovery Recoverable (r:1 w:0) - /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) - /// Storage: Recovery ActiveRecoveries (r:1 w:1) - /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + /// Storage: `Recovery::Recoverable` (r:1 w:0) + /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) + /// Storage: `Recovery::ActiveRecoveries` (r:1 w:1) + /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 9]`. fn vouch_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `360 + n * (64 ±0)` + // Measured: `431 + n * (64 ±0)` // Estimated: `3854` - // Minimum execution time: 19_464_000 picoseconds. - Weight::from_parts(20_642_522, 3854) - // Standard Error: 5_974 - .saturating_add(Weight::from_parts(142_308, 0).saturating_mul(n.into())) + // Minimum execution time: 17_044_000 picoseconds. + Weight::from_parts(18_299_617, 3854) + // Standard Error: 5_580 + .saturating_add(Weight::from_parts(187_568, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Recovery Recoverable (r:1 w:0) - /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) - /// Storage: Recovery ActiveRecoveries (r:1 w:0) - /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) - /// Storage: Recovery Proxy (r:1 w:1) - /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) + /// Storage: `Recovery::Recoverable` (r:1 w:0) + /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) + /// Storage: `Recovery::ActiveRecoveries` (r:1 w:0) + /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) + /// Storage: `Recovery::Proxy` (r:1 w:1) + /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 9]`. fn claim_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `392 + n * (64 ±0)` + // Measured: `463 + n * (64 ±0)` // Estimated: `3854` - // Minimum execution time: 23_656_000 picoseconds. - Weight::from_parts(24_903_269, 3854) - // Standard Error: 5_771 - .saturating_add(Weight::from_parts(117_343, 0).saturating_mul(n.into())) + // Minimum execution time: 22_186_000 picoseconds. + Weight::from_parts(23_476_807, 3854) + // Standard Error: 6_392 + .saturating_add(Weight::from_parts(89_770, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Recovery ActiveRecoveries (r:1 w:1) - /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Recovery::ActiveRecoveries` (r:1 w:1) + /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 9]`. fn close_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `513 + n * (32 ±0)` + // Measured: `584 + n * (32 ±0)` // Estimated: `3854` - // Minimum execution time: 34_866_000 picoseconds. - Weight::from_parts(36_368_748, 3854) - // Standard Error: 6_600 - .saturating_add(Weight::from_parts(118_610, 0).saturating_mul(n.into())) + // Minimum execution time: 31_045_000 picoseconds. + Weight::from_parts(32_623_578, 3854) + // Standard Error: 7_203 + .saturating_add(Weight::from_parts(61_466, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Recovery ActiveRecoveries (r:1 w:0) - /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) - /// Storage: Recovery Recoverable (r:1 w:1) - /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// Storage: `Recovery::ActiveRecoveries` (r:1 w:0) + /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) + /// Storage: `Recovery::Recoverable` (r:1 w:1) + /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 9]`. fn remove_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `270 + n * (32 ±0)` + // Measured: `341 + n * (32 ±0)` // Estimated: `3854` - // Minimum execution time: 31_405_000 picoseconds. - Weight::from_parts(32_552_838, 3854) - // Standard Error: 8_043 - .saturating_add(Weight::from_parts(171_605, 0).saturating_mul(n.into())) + // Minimum execution time: 27_925_000 picoseconds. + Weight::from_parts(29_258_264, 3854) + // Standard Error: 8_192 + .saturating_add(Weight::from_parts(128_124, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Recovery Proxy (r:1 w:1) - /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) + /// Storage: `Recovery::Proxy` (r:1 w:1) + /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) fn cancel_recovered() -> Weight { // Proof Size summary in bytes: - // Measured: `281` + // Measured: `352` // Estimated: `3545` - // Minimum execution time: 11_530_000 picoseconds. - Weight::from_parts(11_851_000, 3545) + // Minimum execution time: 11_623_000 picoseconds. + Weight::from_parts(12_043_000, 3545) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/referenda/src/weights.rs b/substrate/frame/referenda/src/weights.rs index 4b89379b311..1f1b69873eb 100644 --- a/substrate/frame/referenda/src/weights.rs +++ b/substrate/frame/referenda/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_referenda +//! Autogenerated weights for `pallet_referenda` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/referenda/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/referenda/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_referenda. +/// Weight functions needed for `pallet_referenda`. pub trait WeightInfo { fn submit() -> Weight; fn place_decision_deposit_preparing() -> Weight; @@ -84,842 +83,874 @@ pub trait WeightInfo { fn clear_metadata() -> Weight; } -/// Weights for pallet_referenda using the Substrate node and recommended hardware. +/// Weights for `pallet_referenda` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Referenda ReferendumCount (r:1 w:1) - /// Proof: Referenda ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) - /// Storage: Referenda ReferendumInfoFor (r:0 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumCount` (r:1 w:1) + /// Proof: `Referenda::ReferendumCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Referenda::ReferendumInfoFor` (r:0 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) fn submit() -> Weight { // Proof Size summary in bytes: - // Measured: `220` + // Measured: `286` // Estimated: `110487` - // Minimum execution time: 40_175_000 picoseconds. - Weight::from_parts(41_107_000, 110487) + // Minimum execution time: 31_536_000 picoseconds. + Weight::from_parts(32_797_000, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_preparing() -> Weight { // Proof Size summary in bytes: - // Measured: `473` + // Measured: `539` // Estimated: `219984` - // Minimum execution time: 50_922_000 picoseconds. - Weight::from_parts(52_179_000, 219984) + // Minimum execution time: 42_579_000 picoseconds. + Weight::from_parts(43_877_000, 219984) .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda DecidingCount (r:1 w:0) - /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: Referenda TrackQueue (r:1 w:1) - /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::DecidingCount` (r:1 w:0) + /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Referenda::TrackQueue` (r:1 w:1) + /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3260` + // Measured: `3326` // Estimated: `110487` - // Minimum execution time: 69_559_000 picoseconds. - Weight::from_parts(72_143_000, 110487) + // Minimum execution time: 61_439_000 picoseconds. + Weight::from_parts(63_681_000, 110487) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda DecidingCount (r:1 w:0) - /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: Referenda TrackQueue (r:1 w:1) - /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::DecidingCount` (r:1 w:0) + /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Referenda::TrackQueue` (r:1 w:1) + /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_not_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3280` + // Measured: `3346` // Estimated: `110487` - // Minimum execution time: 68_833_000 picoseconds. - Weight::from_parts(70_987_000, 110487) + // Minimum execution time: 60_136_000 picoseconds. + Weight::from_parts(61_841_000, 110487) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda DecidingCount (r:1 w:1) - /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::DecidingCount` (r:1 w:1) + /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `473` + // Measured: `539` // Estimated: `219984` - // Minimum execution time: 61_794_000 picoseconds. - Weight::from_parts(62_846_000, 219984) + // Minimum execution time: 49_865_000 picoseconds. + Weight::from_parts(51_347_000, 219984) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) - } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda DecidingCount (r:1 w:1) - /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + .saturating_add(T::DbWeight::get().writes(5_u64)) + } + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::DecidingCount` (r:1 w:1) + /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `473` + // Measured: `539` // Estimated: `219984` - // Minimum execution time: 58_664_000 picoseconds. - Weight::from_parts(60_195_000, 219984) + // Minimum execution time: 47_887_000 picoseconds. + Weight::from_parts(49_927_000, 219984) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) fn refund_decision_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `351` + // Measured: `417` // Estimated: `3831` - // Minimum execution time: 30_850_000 picoseconds. - Weight::from_parts(32_130_000, 3831) + // Minimum execution time: 25_721_000 picoseconds. + Weight::from_parts(26_922_000, 3831) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) fn refund_submission_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `341` + // Measured: `407` // Estimated: `3831` - // Minimum execution time: 30_747_000 picoseconds. - Weight::from_parts(32_196_000, 3831) + // Minimum execution time: 25_840_000 picoseconds. + Weight::from_parts(26_498_000, 3831) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn cancel() -> Weight { // Proof Size summary in bytes: - // Measured: `381` + // Measured: `447` // Estimated: `219984` - // Minimum execution time: 36_139_000 picoseconds. - Weight::from_parts(37_252_000, 219984) + // Minimum execution time: 30_530_000 picoseconds. + Weight::from_parts(31_547_000, 219984) .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) - /// Storage: Referenda MetadataOf (r:1 w:0) - /// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Referenda::MetadataOf` (r:1 w:0) + /// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn kill() -> Weight { // Proof Size summary in bytes: - // Measured: `622` + // Measured: `688` // Estimated: `219984` - // Minimum execution time: 80_862_000 picoseconds. - Weight::from_parts(83_045_000, 219984) + // Minimum execution time: 64_011_000 picoseconds. + Weight::from_parts(65_240_000, 219984) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: Referenda TrackQueue (r:1 w:0) - /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) - /// Storage: Referenda DecidingCount (r:1 w:1) - /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: `Referenda::TrackQueue` (r:1 w:0) + /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) + /// Storage: `Referenda::DecidingCount` (r:1 w:1) + /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) fn one_fewer_deciding_queue_empty() -> Weight { // Proof Size summary in bytes: - // Measured: `174` + // Measured: `240` // Estimated: `5477` - // Minimum execution time: 10_136_000 picoseconds. - Weight::from_parts(10_638_000, 5477) + // Minimum execution time: 9_568_000 picoseconds. + Weight::from_parts(10_004_000, 5477) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Referenda TrackQueue (r:1 w:1) - /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::TrackQueue` (r:1 w:1) + /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn one_fewer_deciding_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `3150` + // Measured: `3216` // Estimated: `110487` - // Minimum execution time: 52_022_000 picoseconds. - Weight::from_parts(53_910_000, 110487) + // Minimum execution time: 43_325_000 picoseconds. + Weight::from_parts(45_335_000, 110487) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Referenda TrackQueue (r:1 w:1) - /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::TrackQueue` (r:1 w:1) + /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn one_fewer_deciding_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `3150` + // Measured: `3216` // Estimated: `110487` - // Minimum execution time: 53_683_000 picoseconds. - Weight::from_parts(55_707_000, 110487) + // Minimum execution time: 44_287_000 picoseconds. + Weight::from_parts(45_164_000, 110487) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:0) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda TrackQueue (r:1 w:1) - /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::TrackQueue` (r:1 w:1) + /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) fn nudge_referendum_requeued_insertion() -> Weight { // Proof Size summary in bytes: - // Measured: `3011` + // Measured: `3077` // Estimated: `5477` - // Minimum execution time: 24_043_000 picoseconds. - Weight::from_parts(24_512_000, 5477) + // Minimum execution time: 21_909_000 picoseconds. + Weight::from_parts(22_641_000, 5477) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:0) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda TrackQueue (r:1 w:1) - /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::TrackQueue` (r:1 w:1) + /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) fn nudge_referendum_requeued_slide() -> Weight { // Proof Size summary in bytes: - // Measured: `3011` + // Measured: `3077` // Estimated: `5477` - // Minimum execution time: 23_588_000 picoseconds. - Weight::from_parts(24_422_000, 5477) + // Minimum execution time: 21_626_000 picoseconds. + Weight::from_parts(22_338_000, 5477) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda DecidingCount (r:1 w:0) - /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: Referenda TrackQueue (r:1 w:1) - /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::DecidingCount` (r:1 w:0) + /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Referenda::TrackQueue` (r:1 w:1) + /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) fn nudge_referendum_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3015` + // Measured: `3081` // Estimated: `5477` - // Minimum execution time: 31_443_000 picoseconds. - Weight::from_parts(32_725_000, 5477) + // Minimum execution time: 29_245_000 picoseconds. + Weight::from_parts(30_147_000, 5477) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda DecidingCount (r:1 w:0) - /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: Referenda TrackQueue (r:1 w:1) - /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::DecidingCount` (r:1 w:0) + /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Referenda::TrackQueue` (r:1 w:1) + /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) fn nudge_referendum_not_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3035` + // Measured: `3101` // Estimated: `5477` - // Minimum execution time: 30_319_000 picoseconds. - Weight::from_parts(31_652_000, 5477) + // Minimum execution time: 28_512_000 picoseconds. + Weight::from_parts(29_781_000, 5477) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn nudge_referendum_no_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `333` + // Measured: `399` // Estimated: `110487` - // Minimum execution time: 23_062_000 picoseconds. - Weight::from_parts(23_614_000, 110487) + // Minimum execution time: 19_208_000 picoseconds. + Weight::from_parts(19_947_000, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn nudge_referendum_preparing() -> Weight { // Proof Size summary in bytes: - // Measured: `381` + // Measured: `447` // Estimated: `110487` - // Minimum execution time: 23_537_000 picoseconds. - Weight::from_parts(24_267_000, 110487) + // Minimum execution time: 19_708_000 picoseconds. + Weight::from_parts(20_783_000, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) fn nudge_referendum_timed_out() -> Weight { // Proof Size summary in bytes: - // Measured: `278` + // Measured: `344` // Estimated: `3831` - // Minimum execution time: 16_388_000 picoseconds. - Weight::from_parts(16_676_000, 3831) + // Minimum execution time: 12_947_000 picoseconds. + Weight::from_parts(13_582_000, 3831) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda DecidingCount (r:1 w:1) - /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::DecidingCount` (r:1 w:1) + /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn nudge_referendum_begin_deciding_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `381` + // Measured: `447` // Estimated: `110487` - // Minimum execution time: 32_801_000 picoseconds. - Weight::from_parts(34_053_000, 110487) + // Minimum execution time: 26_699_000 picoseconds. + Weight::from_parts(28_048_000, 110487) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda DecidingCount (r:1 w:1) - /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::DecidingCount` (r:1 w:1) + /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn nudge_referendum_begin_deciding_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `381` + // Measured: `447` // Estimated: `110487` - // Minimum execution time: 35_704_000 picoseconds. - Weight::from_parts(36_451_000, 110487) + // Minimum execution time: 28_132_000 picoseconds. + Weight::from_parts(29_520_000, 110487) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn nudge_referendum_begin_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `434` + // Measured: `500` // Estimated: `110487` - // Minimum execution time: 29_151_000 picoseconds. - Weight::from_parts(30_055_000, 110487) + // Minimum execution time: 23_212_000 picoseconds. + Weight::from_parts(24_200_000, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn nudge_referendum_end_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `417` + // Measured: `483` // Estimated: `110487` - // Minimum execution time: 29_265_000 picoseconds. - Weight::from_parts(30_213_000, 110487) + // Minimum execution time: 22_807_000 picoseconds. + Weight::from_parts(23_858_000, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn nudge_referendum_continue_not_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `434` + // Measured: `500` // Estimated: `110487` - // Minimum execution time: 27_760_000 picoseconds. - Weight::from_parts(28_381_000, 110487) + // Minimum execution time: 22_862_000 picoseconds. + Weight::from_parts(23_627_000, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn nudge_referendum_continue_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `438` + // Measured: `504` // Estimated: `110487` - // Minimum execution time: 25_464_000 picoseconds. - Weight::from_parts(26_348_000, 110487) + // Minimum execution time: 21_030_000 picoseconds. + Weight::from_parts(21_710_000, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) - /// Storage: Scheduler Lookup (r:1 w:1) - /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Lookup` (r:1 w:1) + /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) fn nudge_referendum_approved() -> Weight { // Proof Size summary in bytes: - // Measured: `438` + // Measured: `504` // Estimated: `219984` - // Minimum execution time: 42_629_000 picoseconds. - Weight::from_parts(43_732_000, 219984) + // Minimum execution time: 33_031_000 picoseconds. + Weight::from_parts(34_518_000, 219984) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn nudge_referendum_rejected() -> Weight { // Proof Size summary in bytes: - // Measured: `434` + // Measured: `500` // Estimated: `110487` - // Minimum execution time: 30_015_000 picoseconds. - Weight::from_parts(30_827_000, 110487) + // Minimum execution time: 23_198_000 picoseconds. + Weight::from_parts(24_238_000, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:0) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Preimage StatusFor (r:1 w:0) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) - /// Storage: Referenda MetadataOf (r:0 w:1) - /// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Referenda::MetadataOf` (r:0 w:1) + /// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn set_some_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `422` + // Measured: `555` // Estimated: `3831` - // Minimum execution time: 19_901_000 picoseconds. - Weight::from_parts(20_681_000, 3831) - .saturating_add(T::DbWeight::get().reads(2_u64)) + // Minimum execution time: 19_502_000 picoseconds. + Weight::from_parts(20_105_000, 3831) + .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:0) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda MetadataOf (r:1 w:1) - /// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::MetadataOf` (r:1 w:1) + /// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn clear_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `355` + // Measured: `421` // Estimated: `3831` - // Minimum execution time: 17_323_000 picoseconds. - Weight::from_parts(18_227_000, 3831) + // Minimum execution time: 15_417_000 picoseconds. + Weight::from_parts(15_916_000, 3831) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Referenda ReferendumCount (r:1 w:1) - /// Proof: Referenda ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) - /// Storage: Referenda ReferendumInfoFor (r:0 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumCount` (r:1 w:1) + /// Proof: `Referenda::ReferendumCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Referenda::ReferendumInfoFor` (r:0 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) fn submit() -> Weight { // Proof Size summary in bytes: - // Measured: `220` + // Measured: `286` // Estimated: `110487` - // Minimum execution time: 40_175_000 picoseconds. - Weight::from_parts(41_107_000, 110487) + // Minimum execution time: 31_536_000 picoseconds. + Weight::from_parts(32_797_000, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_preparing() -> Weight { // Proof Size summary in bytes: - // Measured: `473` + // Measured: `539` // Estimated: `219984` - // Minimum execution time: 50_922_000 picoseconds. - Weight::from_parts(52_179_000, 219984) + // Minimum execution time: 42_579_000 picoseconds. + Weight::from_parts(43_877_000, 219984) .saturating_add(RocksDbWeight::get().reads(3_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda DecidingCount (r:1 w:0) - /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: Referenda TrackQueue (r:1 w:1) - /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::DecidingCount` (r:1 w:0) + /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Referenda::TrackQueue` (r:1 w:1) + /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3260` + // Measured: `3326` // Estimated: `110487` - // Minimum execution time: 69_559_000 picoseconds. - Weight::from_parts(72_143_000, 110487) + // Minimum execution time: 61_439_000 picoseconds. + Weight::from_parts(63_681_000, 110487) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda DecidingCount (r:1 w:0) - /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: Referenda TrackQueue (r:1 w:1) - /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::DecidingCount` (r:1 w:0) + /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Referenda::TrackQueue` (r:1 w:1) + /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_not_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3280` + // Measured: `3346` // Estimated: `110487` - // Minimum execution time: 68_833_000 picoseconds. - Weight::from_parts(70_987_000, 110487) + // Minimum execution time: 60_136_000 picoseconds. + Weight::from_parts(61_841_000, 110487) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda DecidingCount (r:1 w:1) - /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::DecidingCount` (r:1 w:1) + /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `473` + // Measured: `539` // Estimated: `219984` - // Minimum execution time: 61_794_000 picoseconds. - Weight::from_parts(62_846_000, 219984) + // Minimum execution time: 49_865_000 picoseconds. + Weight::from_parts(51_347_000, 219984) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(4_u64)) - } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda DecidingCount (r:1 w:1) - /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + .saturating_add(RocksDbWeight::get().writes(5_u64)) + } + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::DecidingCount` (r:1 w:1) + /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `473` + // Measured: `539` // Estimated: `219984` - // Minimum execution time: 58_664_000 picoseconds. - Weight::from_parts(60_195_000, 219984) + // Minimum execution time: 47_887_000 picoseconds. + Weight::from_parts(49_927_000, 219984) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(4_u64)) + .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) fn refund_decision_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `351` + // Measured: `417` // Estimated: `3831` - // Minimum execution time: 30_850_000 picoseconds. - Weight::from_parts(32_130_000, 3831) + // Minimum execution time: 25_721_000 picoseconds. + Weight::from_parts(26_922_000, 3831) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) fn refund_submission_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `341` + // Measured: `407` // Estimated: `3831` - // Minimum execution time: 30_747_000 picoseconds. - Weight::from_parts(32_196_000, 3831) + // Minimum execution time: 25_840_000 picoseconds. + Weight::from_parts(26_498_000, 3831) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn cancel() -> Weight { // Proof Size summary in bytes: - // Measured: `381` + // Measured: `447` // Estimated: `219984` - // Minimum execution time: 36_139_000 picoseconds. - Weight::from_parts(37_252_000, 219984) + // Minimum execution time: 30_530_000 picoseconds. + Weight::from_parts(31_547_000, 219984) .saturating_add(RocksDbWeight::get().reads(3_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) - /// Storage: Referenda MetadataOf (r:1 w:0) - /// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Referenda::MetadataOf` (r:1 w:0) + /// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn kill() -> Weight { // Proof Size summary in bytes: - // Measured: `622` + // Measured: `688` // Estimated: `219984` - // Minimum execution time: 80_862_000 picoseconds. - Weight::from_parts(83_045_000, 219984) + // Minimum execution time: 64_011_000 picoseconds. + Weight::from_parts(65_240_000, 219984) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: Referenda TrackQueue (r:1 w:0) - /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) - /// Storage: Referenda DecidingCount (r:1 w:1) - /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: `Referenda::TrackQueue` (r:1 w:0) + /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) + /// Storage: `Referenda::DecidingCount` (r:1 w:1) + /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) fn one_fewer_deciding_queue_empty() -> Weight { // Proof Size summary in bytes: - // Measured: `174` + // Measured: `240` // Estimated: `5477` - // Minimum execution time: 10_136_000 picoseconds. - Weight::from_parts(10_638_000, 5477) + // Minimum execution time: 9_568_000 picoseconds. + Weight::from_parts(10_004_000, 5477) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Referenda TrackQueue (r:1 w:1) - /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::TrackQueue` (r:1 w:1) + /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn one_fewer_deciding_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `3150` + // Measured: `3216` // Estimated: `110487` - // Minimum execution time: 52_022_000 picoseconds. - Weight::from_parts(53_910_000, 110487) + // Minimum execution time: 43_325_000 picoseconds. + Weight::from_parts(45_335_000, 110487) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Referenda TrackQueue (r:1 w:1) - /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::TrackQueue` (r:1 w:1) + /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn one_fewer_deciding_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `3150` + // Measured: `3216` // Estimated: `110487` - // Minimum execution time: 53_683_000 picoseconds. - Weight::from_parts(55_707_000, 110487) + // Minimum execution time: 44_287_000 picoseconds. + Weight::from_parts(45_164_000, 110487) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:0) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda TrackQueue (r:1 w:1) - /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::TrackQueue` (r:1 w:1) + /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) fn nudge_referendum_requeued_insertion() -> Weight { // Proof Size summary in bytes: - // Measured: `3011` + // Measured: `3077` // Estimated: `5477` - // Minimum execution time: 24_043_000 picoseconds. - Weight::from_parts(24_512_000, 5477) + // Minimum execution time: 21_909_000 picoseconds. + Weight::from_parts(22_641_000, 5477) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:0) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda TrackQueue (r:1 w:1) - /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::TrackQueue` (r:1 w:1) + /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) fn nudge_referendum_requeued_slide() -> Weight { // Proof Size summary in bytes: - // Measured: `3011` + // Measured: `3077` // Estimated: `5477` - // Minimum execution time: 23_588_000 picoseconds. - Weight::from_parts(24_422_000, 5477) + // Minimum execution time: 21_626_000 picoseconds. + Weight::from_parts(22_338_000, 5477) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda DecidingCount (r:1 w:0) - /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: Referenda TrackQueue (r:1 w:1) - /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::DecidingCount` (r:1 w:0) + /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Referenda::TrackQueue` (r:1 w:1) + /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) fn nudge_referendum_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3015` + // Measured: `3081` // Estimated: `5477` - // Minimum execution time: 31_443_000 picoseconds. - Weight::from_parts(32_725_000, 5477) + // Minimum execution time: 29_245_000 picoseconds. + Weight::from_parts(30_147_000, 5477) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda DecidingCount (r:1 w:0) - /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: Referenda TrackQueue (r:1 w:1) - /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::DecidingCount` (r:1 w:0) + /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Referenda::TrackQueue` (r:1 w:1) + /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) fn nudge_referendum_not_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3035` + // Measured: `3101` // Estimated: `5477` - // Minimum execution time: 30_319_000 picoseconds. - Weight::from_parts(31_652_000, 5477) + // Minimum execution time: 28_512_000 picoseconds. + Weight::from_parts(29_781_000, 5477) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn nudge_referendum_no_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `333` + // Measured: `399` // Estimated: `110487` - // Minimum execution time: 23_062_000 picoseconds. - Weight::from_parts(23_614_000, 110487) + // Minimum execution time: 19_208_000 picoseconds. + Weight::from_parts(19_947_000, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn nudge_referendum_preparing() -> Weight { // Proof Size summary in bytes: - // Measured: `381` + // Measured: `447` // Estimated: `110487` - // Minimum execution time: 23_537_000 picoseconds. - Weight::from_parts(24_267_000, 110487) + // Minimum execution time: 19_708_000 picoseconds. + Weight::from_parts(20_783_000, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) fn nudge_referendum_timed_out() -> Weight { // Proof Size summary in bytes: - // Measured: `278` + // Measured: `344` // Estimated: `3831` - // Minimum execution time: 16_388_000 picoseconds. - Weight::from_parts(16_676_000, 3831) + // Minimum execution time: 12_947_000 picoseconds. + Weight::from_parts(13_582_000, 3831) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda DecidingCount (r:1 w:1) - /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::DecidingCount` (r:1 w:1) + /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn nudge_referendum_begin_deciding_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `381` + // Measured: `447` // Estimated: `110487` - // Minimum execution time: 32_801_000 picoseconds. - Weight::from_parts(34_053_000, 110487) + // Minimum execution time: 26_699_000 picoseconds. + Weight::from_parts(28_048_000, 110487) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda DecidingCount (r:1 w:1) - /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::DecidingCount` (r:1 w:1) + /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn nudge_referendum_begin_deciding_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `381` + // Measured: `447` // Estimated: `110487` - // Minimum execution time: 35_704_000 picoseconds. - Weight::from_parts(36_451_000, 110487) + // Minimum execution time: 28_132_000 picoseconds. + Weight::from_parts(29_520_000, 110487) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn nudge_referendum_begin_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `434` + // Measured: `500` // Estimated: `110487` - // Minimum execution time: 29_151_000 picoseconds. - Weight::from_parts(30_055_000, 110487) + // Minimum execution time: 23_212_000 picoseconds. + Weight::from_parts(24_200_000, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn nudge_referendum_end_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `417` + // Measured: `483` // Estimated: `110487` - // Minimum execution time: 29_265_000 picoseconds. - Weight::from_parts(30_213_000, 110487) + // Minimum execution time: 22_807_000 picoseconds. + Weight::from_parts(23_858_000, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn nudge_referendum_continue_not_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `434` + // Measured: `500` // Estimated: `110487` - // Minimum execution time: 27_760_000 picoseconds. - Weight::from_parts(28_381_000, 110487) + // Minimum execution time: 22_862_000 picoseconds. + Weight::from_parts(23_627_000, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn nudge_referendum_continue_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `438` + // Measured: `504` // Estimated: `110487` - // Minimum execution time: 25_464_000 picoseconds. - Weight::from_parts(26_348_000, 110487) + // Minimum execution time: 21_030_000 picoseconds. + Weight::from_parts(21_710_000, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:2 w:2) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) - /// Storage: Scheduler Lookup (r:1 w:1) - /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:2 w:2) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Lookup` (r:1 w:1) + /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) fn nudge_referendum_approved() -> Weight { // Proof Size summary in bytes: - // Measured: `438` + // Measured: `504` // Estimated: `219984` - // Minimum execution time: 42_629_000 picoseconds. - Weight::from_parts(43_732_000, 219984) + // Minimum execution time: 33_031_000 picoseconds. + Weight::from_parts(34_518_000, 219984) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:1) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Scheduler Agenda (r:1 w:1) - /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Agenda` (r:1 w:1) + /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) fn nudge_referendum_rejected() -> Weight { // Proof Size summary in bytes: - // Measured: `434` + // Measured: `500` // Estimated: `110487` - // Minimum execution time: 30_015_000 picoseconds. - Weight::from_parts(30_827_000, 110487) + // Minimum execution time: 23_198_000 picoseconds. + Weight::from_parts(24_238_000, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:0) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Preimage StatusFor (r:1 w:0) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) - /// Storage: Referenda MetadataOf (r:0 w:1) - /// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Referenda::MetadataOf` (r:0 w:1) + /// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn set_some_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `422` + // Measured: `555` // Estimated: `3831` - // Minimum execution time: 19_901_000 picoseconds. - Weight::from_parts(20_681_000, 3831) - .saturating_add(RocksDbWeight::get().reads(2_u64)) + // Minimum execution time: 19_502_000 picoseconds. + Weight::from_parts(20_105_000, 3831) + .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Referenda ReferendumInfoFor (r:1 w:0) - /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) - /// Storage: Referenda MetadataOf (r:1 w:1) - /// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) + /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: `Referenda::MetadataOf` (r:1 w:1) + /// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn clear_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `355` + // Measured: `421` // Estimated: `3831` - // Minimum execution time: 17_323_000 picoseconds. - Weight::from_parts(18_227_000, 3831) + // Minimum execution time: 15_417_000 picoseconds. + Weight::from_parts(15_916_000, 3831) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/remark/src/weights.rs b/substrate/frame/remark/src/weights.rs index 46475db163f..61cca5b7d05 100644 --- a/substrate/frame/remark/src/weights.rs +++ b/substrate/frame/remark/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_remark +//! Autogenerated weights for `pallet_remark` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/remark/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/remark/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,12 +49,12 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_remark. +/// Weight functions needed for `pallet_remark`. pub trait WeightInfo { fn store(l: u32, ) -> Weight; } -/// Weights for pallet_remark using the Substrate node and recommended hardware. +/// Weights for `pallet_remark` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { /// The range of component `l` is `[1, 1048576]`. @@ -63,23 +62,23 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_471_000 picoseconds. - Weight::from_parts(8_586_000, 0) + // Minimum execution time: 6_623_000 picoseconds. + Weight::from_parts(6_757_000, 0) // Standard Error: 0 - .saturating_add(Weight::from_parts(1_359, 0).saturating_mul(l.into())) + .saturating_add(Weight::from_parts(1_368, 0).saturating_mul(l.into())) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { /// The range of component `l` is `[1, 1048576]`. fn store(l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_471_000 picoseconds. - Weight::from_parts(8_586_000, 0) + // Minimum execution time: 6_623_000 picoseconds. + Weight::from_parts(6_757_000, 0) // Standard Error: 0 - .saturating_add(Weight::from_parts(1_359, 0).saturating_mul(l.into())) + .saturating_add(Weight::from_parts(1_368, 0).saturating_mul(l.into())) } } diff --git a/substrate/frame/safe-mode/src/weights.rs b/substrate/frame/safe-mode/src/weights.rs index f72bebcab9a..d326fab0f0f 100644 --- a/substrate/frame/safe-mode/src/weights.rs +++ b/substrate/frame/safe-mode/src/weights.rs @@ -17,27 +17,29 @@ //! Autogenerated weights for `pallet_safe_mode` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-08-24, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-aahe6cbd-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// target/production/substrate-node +// ./target/production/substrate-node // benchmark // pallet +// --chain=dev // --steps=50 // --repeat=20 +// --pallet=pallet_safe_mode +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/substrate/.git/.artifacts/bench.json -// --pallet=pallet_safe_mode -// --chain=dev -// --header=./HEADER-APACHE2 -// --output=./frame/safe-mode/src/weights.rs -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/safe-mode/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -70,8 +72,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1489` - // Minimum execution time: 2_500_000 picoseconds. - Weight::from_parts(2_594_000, 1489) + // Minimum execution time: 2_216_000 picoseconds. + Weight::from_parts(2_309_000, 1489) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `SafeMode::EnteredUntil` (r:1 w:1) @@ -80,23 +82,23 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `169` // Estimated: `1489` - // Minimum execution time: 8_868_000 picoseconds. - Weight::from_parts(9_415_000, 1489) + // Minimum execution time: 6_124_000 picoseconds. + Weight::from_parts(6_601_000, 1489) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `SafeMode::EnteredUntil` (r:1 w:1) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) /// Storage: `SafeMode::Deposits` (r:0 w:1) /// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn enter() -> Weight { // Proof Size summary in bytes: // Measured: `142` - // Estimated: `3550` - // Minimum execution time: 50_541_000 picoseconds. - Weight::from_parts(51_558_000, 3550) + // Estimated: `3658` + // Minimum execution time: 44_825_000 picoseconds. + Weight::from_parts(45_845_000, 3658) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -106,23 +108,23 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1489` - // Minimum execution time: 10_489_000 picoseconds. - Weight::from_parts(10_833_000, 1489) + // Minimum execution time: 7_603_000 picoseconds. + Weight::from_parts(7_954_000, 1489) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `SafeMode::EnteredUntil` (r:1 w:1) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) /// Storage: `SafeMode::Deposits` (r:0 w:1) /// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn extend() -> Weight { // Proof Size summary in bytes: // Measured: `169` - // Estimated: `3550` - // Minimum execution time: 50_818_000 picoseconds. - Weight::from_parts(51_873_000, 3550) + // Estimated: `3658` + // Minimum execution time: 44_716_000 picoseconds. + Weight::from_parts(46_039_000, 3658) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -132,8 +134,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `169` // Estimated: `1489` - // Minimum execution time: 10_843_000 picoseconds. - Weight::from_parts(11_314_000, 1489) + // Minimum execution time: 8_231_000 picoseconds. + Weight::from_parts(8_731_000, 1489) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -143,8 +145,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `169` // Estimated: `1489` - // Minimum execution time: 10_382_000 picoseconds. - Weight::from_parts(10_814_000, 1489) + // Minimum execution time: 8_015_000 picoseconds. + Weight::from_parts(8_247_000, 1489) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -153,39 +155,39 @@ impl WeightInfo for SubstrateWeight { /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) fn release_deposit() -> Weight { // Proof Size summary in bytes: // Measured: `292` - // Estimated: `3550` - // Minimum execution time: 42_828_000 picoseconds. - Weight::from_parts(43_752_000, 3550) + // Estimated: `3658` + // Minimum execution time: 39_149_000 picoseconds. + Weight::from_parts(40_005_000, 3658) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `SafeMode::Deposits` (r:1 w:1) /// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) fn force_release_deposit() -> Weight { // Proof Size summary in bytes: // Measured: `292` - // Estimated: `3550` - // Minimum execution time: 40_196_000 picoseconds. - Weight::from_parts(41_298_000, 3550) + // Estimated: `3658` + // Minimum execution time: 37_528_000 picoseconds. + Weight::from_parts(38_473_000, 3658) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `SafeMode::Deposits` (r:1 w:1) /// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) fn force_slash_deposit() -> Weight { // Proof Size summary in bytes: // Measured: `292` - // Estimated: `3550` - // Minimum execution time: 33_660_000 picoseconds. - Weight::from_parts(34_426_000, 3550) + // Estimated: `3658` + // Minimum execution time: 29_417_000 picoseconds. + Weight::from_parts(30_195_000, 3658) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -199,8 +201,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1489` - // Minimum execution time: 2_500_000 picoseconds. - Weight::from_parts(2_594_000, 1489) + // Minimum execution time: 2_216_000 picoseconds. + Weight::from_parts(2_309_000, 1489) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `SafeMode::EnteredUntil` (r:1 w:1) @@ -209,23 +211,23 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `169` // Estimated: `1489` - // Minimum execution time: 8_868_000 picoseconds. - Weight::from_parts(9_415_000, 1489) + // Minimum execution time: 6_124_000 picoseconds. + Weight::from_parts(6_601_000, 1489) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `SafeMode::EnteredUntil` (r:1 w:1) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) /// Storage: `SafeMode::Deposits` (r:0 w:1) /// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn enter() -> Weight { // Proof Size summary in bytes: // Measured: `142` - // Estimated: `3550` - // Minimum execution time: 50_541_000 picoseconds. - Weight::from_parts(51_558_000, 3550) + // Estimated: `3658` + // Minimum execution time: 44_825_000 picoseconds. + Weight::from_parts(45_845_000, 3658) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -235,23 +237,23 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1489` - // Minimum execution time: 10_489_000 picoseconds. - Weight::from_parts(10_833_000, 1489) + // Minimum execution time: 7_603_000 picoseconds. + Weight::from_parts(7_954_000, 1489) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `SafeMode::EnteredUntil` (r:1 w:1) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) /// Storage: `SafeMode::Deposits` (r:0 w:1) /// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn extend() -> Weight { // Proof Size summary in bytes: // Measured: `169` - // Estimated: `3550` - // Minimum execution time: 50_818_000 picoseconds. - Weight::from_parts(51_873_000, 3550) + // Estimated: `3658` + // Minimum execution time: 44_716_000 picoseconds. + Weight::from_parts(46_039_000, 3658) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -261,8 +263,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `169` // Estimated: `1489` - // Minimum execution time: 10_843_000 picoseconds. - Weight::from_parts(11_314_000, 1489) + // Minimum execution time: 8_231_000 picoseconds. + Weight::from_parts(8_731_000, 1489) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -272,8 +274,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `169` // Estimated: `1489` - // Minimum execution time: 10_382_000 picoseconds. - Weight::from_parts(10_814_000, 1489) + // Minimum execution time: 8_015_000 picoseconds. + Weight::from_parts(8_247_000, 1489) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -282,39 +284,39 @@ impl WeightInfo for () { /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) fn release_deposit() -> Weight { // Proof Size summary in bytes: // Measured: `292` - // Estimated: `3550` - // Minimum execution time: 42_828_000 picoseconds. - Weight::from_parts(43_752_000, 3550) + // Estimated: `3658` + // Minimum execution time: 39_149_000 picoseconds. + Weight::from_parts(40_005_000, 3658) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `SafeMode::Deposits` (r:1 w:1) /// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) fn force_release_deposit() -> Weight { // Proof Size summary in bytes: // Measured: `292` - // Estimated: `3550` - // Minimum execution time: 40_196_000 picoseconds. - Weight::from_parts(41_298_000, 3550) + // Estimated: `3658` + // Minimum execution time: 37_528_000 picoseconds. + Weight::from_parts(38_473_000, 3658) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `SafeMode::Deposits` (r:1 w:1) /// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) fn force_slash_deposit() -> Weight { // Proof Size summary in bytes: // Measured: `292` - // Estimated: `3550` - // Minimum execution time: 33_660_000 picoseconds. - Weight::from_parts(34_426_000, 3550) + // Estimated: `3658` + // Minimum execution time: 29_417_000 picoseconds. + Weight::from_parts(30_195_000, 3658) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } diff --git a/substrate/frame/salary/src/weights.rs b/substrate/frame/salary/src/weights.rs index 3d3b9e31595..c4f22a027eb 100644 --- a/substrate/frame/salary/src/weights.rs +++ b/substrate/frame/salary/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_salary +//! Autogenerated weights for `pallet_salary` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/salary/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/salary/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_salary. +/// Weight functions needed for `pallet_salary`. pub trait WeightInfo { fn init() -> Weight; fn bump() -> Weight; @@ -61,204 +60,204 @@ pub trait WeightInfo { fn check_payment() -> Weight; } -/// Weights for pallet_salary using the Substrate node and recommended hardware. +/// Weights for `pallet_salary` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Salary Status (r:1 w:1) - /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) + /// Storage: `Salary::Status` (r:1 w:1) + /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) fn init() -> Weight { // Proof Size summary in bytes: // Measured: `4` // Estimated: `1541` - // Minimum execution time: 10_778_000 picoseconds. - Weight::from_parts(11_084_000, 1541) + // Minimum execution time: 7_421_000 picoseconds. + Weight::from_parts(7_819_000, 1541) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Salary Status (r:1 w:1) - /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) + /// Storage: `Salary::Status` (r:1 w:1) + /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) fn bump() -> Weight { // Proof Size summary in bytes: // Measured: `86` // Estimated: `1541` - // Minimum execution time: 12_042_000 picoseconds. - Weight::from_parts(12_645_000, 1541) + // Minimum execution time: 8_651_000 picoseconds. + Weight::from_parts(9_056_000, 1541) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Salary Status (r:1 w:0) - /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) - /// Storage: RankedCollective Members (r:1 w:0) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: Salary Claimant (r:1 w:1) - /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) + /// Storage: `Salary::Status` (r:1 w:0) + /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::Members` (r:1 w:0) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `Salary::Claimant` (r:1 w:1) + /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) fn induct() -> Weight { // Proof Size summary in bytes: // Measured: `395` // Estimated: `3543` - // Minimum execution time: 18_374_000 picoseconds. - Weight::from_parts(19_200_000, 3543) + // Minimum execution time: 16_513_000 picoseconds. + Weight::from_parts(17_305_000, 3543) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: RankedCollective Members (r:1 w:0) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: Salary Status (r:1 w:1) - /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) - /// Storage: Salary Claimant (r:1 w:1) - /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:0) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `Salary::Status` (r:1 w:1) + /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) + /// Storage: `Salary::Claimant` (r:1 w:1) + /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) fn register() -> Weight { // Proof Size summary in bytes: // Measured: `462` // Estimated: `3543` - // Minimum execution time: 22_696_000 picoseconds. - Weight::from_parts(23_275_000, 3543) + // Minimum execution time: 18_913_000 picoseconds. + Weight::from_parts(19_867_000, 3543) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Salary Status (r:1 w:1) - /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) - /// Storage: Salary Claimant (r:1 w:1) - /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) - /// Storage: RankedCollective Members (r:1 w:0) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: `Salary::Status` (r:1 w:1) + /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) + /// Storage: `Salary::Claimant` (r:1 w:1) + /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::Members` (r:1 w:0) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) fn payout() -> Weight { // Proof Size summary in bytes: // Measured: `462` // Estimated: `3543` - // Minimum execution time: 63_660_000 picoseconds. - Weight::from_parts(65_006_000, 3543) + // Minimum execution time: 53_297_000 picoseconds. + Weight::from_parts(55_144_000, 3543) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Salary Status (r:1 w:1) - /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) - /// Storage: Salary Claimant (r:1 w:1) - /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) - /// Storage: RankedCollective Members (r:1 w:0) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Salary::Status` (r:1 w:1) + /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) + /// Storage: `Salary::Claimant` (r:1 w:1) + /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::Members` (r:1 w:0) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn payout_other() -> Weight { // Proof Size summary in bytes: // Measured: `462` // Estimated: `3593` - // Minimum execution time: 64_706_000 picoseconds. - Weight::from_parts(65_763_000, 3593) + // Minimum execution time: 53_638_000 picoseconds. + Weight::from_parts(55_328_000, 3593) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Salary Status (r:1 w:1) - /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) - /// Storage: Salary Claimant (r:1 w:1) - /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) + /// Storage: `Salary::Status` (r:1 w:1) + /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) + /// Storage: `Salary::Claimant` (r:1 w:1) + /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) fn check_payment() -> Weight { // Proof Size summary in bytes: // Measured: `170` // Estimated: `3543` - // Minimum execution time: 11_838_000 picoseconds. - Weight::from_parts(12_323_000, 3543) + // Minimum execution time: 10_557_000 picoseconds. + Weight::from_parts(11_145_000, 3543) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Salary Status (r:1 w:1) - /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) + /// Storage: `Salary::Status` (r:1 w:1) + /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) fn init() -> Weight { // Proof Size summary in bytes: // Measured: `4` // Estimated: `1541` - // Minimum execution time: 10_778_000 picoseconds. - Weight::from_parts(11_084_000, 1541) + // Minimum execution time: 7_421_000 picoseconds. + Weight::from_parts(7_819_000, 1541) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Salary Status (r:1 w:1) - /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) + /// Storage: `Salary::Status` (r:1 w:1) + /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) fn bump() -> Weight { // Proof Size summary in bytes: // Measured: `86` // Estimated: `1541` - // Minimum execution time: 12_042_000 picoseconds. - Weight::from_parts(12_645_000, 1541) + // Minimum execution time: 8_651_000 picoseconds. + Weight::from_parts(9_056_000, 1541) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Salary Status (r:1 w:0) - /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) - /// Storage: RankedCollective Members (r:1 w:0) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: Salary Claimant (r:1 w:1) - /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) + /// Storage: `Salary::Status` (r:1 w:0) + /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::Members` (r:1 w:0) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `Salary::Claimant` (r:1 w:1) + /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) fn induct() -> Weight { // Proof Size summary in bytes: // Measured: `395` // Estimated: `3543` - // Minimum execution time: 18_374_000 picoseconds. - Weight::from_parts(19_200_000, 3543) + // Minimum execution time: 16_513_000 picoseconds. + Weight::from_parts(17_305_000, 3543) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: RankedCollective Members (r:1 w:0) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: Salary Status (r:1 w:1) - /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) - /// Storage: Salary Claimant (r:1 w:1) - /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) + /// Storage: `RankedCollective::Members` (r:1 w:0) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `Salary::Status` (r:1 w:1) + /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) + /// Storage: `Salary::Claimant` (r:1 w:1) + /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) fn register() -> Weight { // Proof Size summary in bytes: // Measured: `462` // Estimated: `3543` - // Minimum execution time: 22_696_000 picoseconds. - Weight::from_parts(23_275_000, 3543) + // Minimum execution time: 18_913_000 picoseconds. + Weight::from_parts(19_867_000, 3543) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Salary Status (r:1 w:1) - /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) - /// Storage: Salary Claimant (r:1 w:1) - /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) - /// Storage: RankedCollective Members (r:1 w:0) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: `Salary::Status` (r:1 w:1) + /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) + /// Storage: `Salary::Claimant` (r:1 w:1) + /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::Members` (r:1 w:0) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) fn payout() -> Weight { // Proof Size summary in bytes: // Measured: `462` // Estimated: `3543` - // Minimum execution time: 63_660_000 picoseconds. - Weight::from_parts(65_006_000, 3543) + // Minimum execution time: 53_297_000 picoseconds. + Weight::from_parts(55_144_000, 3543) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Salary Status (r:1 w:1) - /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) - /// Storage: Salary Claimant (r:1 w:1) - /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) - /// Storage: RankedCollective Members (r:1 w:0) - /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Salary::Status` (r:1 w:1) + /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) + /// Storage: `Salary::Claimant` (r:1 w:1) + /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) + /// Storage: `RankedCollective::Members` (r:1 w:0) + /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn payout_other() -> Weight { // Proof Size summary in bytes: // Measured: `462` // Estimated: `3593` - // Minimum execution time: 64_706_000 picoseconds. - Weight::from_parts(65_763_000, 3593) + // Minimum execution time: 53_638_000 picoseconds. + Weight::from_parts(55_328_000, 3593) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Salary Status (r:1 w:1) - /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) - /// Storage: Salary Claimant (r:1 w:1) - /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) + /// Storage: `Salary::Status` (r:1 w:1) + /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) + /// Storage: `Salary::Claimant` (r:1 w:1) + /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) fn check_payment() -> Weight { // Proof Size summary in bytes: // Measured: `170` // Estimated: `3543` - // Minimum execution time: 11_838_000 picoseconds. - Weight::from_parts(12_323_000, 3543) + // Minimum execution time: 10_557_000 picoseconds. + Weight::from_parts(11_145_000, 3543) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } diff --git a/substrate/frame/sassafras/src/mock.rs b/substrate/frame/sassafras/src/mock.rs index 5e5909fcb0d..4c6efaa63a9 100644 --- a/substrate/frame/sassafras/src/mock.rs +++ b/substrate/frame/sassafras/src/mock.rs @@ -34,7 +34,8 @@ use sp_core::{ H256, U256, }; use sp_runtime::{ - testing::{Digest, DigestItem, Header, TestXt}, + generic::UncheckedExtrinsic, + testing::{Digest, DigestItem, Header}, BuildStorage, }; @@ -53,7 +54,7 @@ where RuntimeCall: From, { type OverarchingCall = RuntimeCall; - type Extrinsic = TestXt; + type Extrinsic = UncheckedExtrinsic; } impl pallet_sassafras::Config for Test { diff --git a/substrate/frame/scheduler/src/weights.rs b/substrate/frame/scheduler/src/weights.rs index 9b7e5405a1b..6c98145d266 100644 --- a/substrate/frame/scheduler/src/weights.rs +++ b/substrate/frame/scheduler/src/weights.rs @@ -17,26 +17,28 @@ //! Autogenerated weights for `pallet_scheduler` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-01-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-grjcggob-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// target/production/substrate-node +// ./target/production/substrate-node // benchmark // pallet +// --chain=dev // --steps=50 // --repeat=20 +// --pallet=pallet_scheduler +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_scheduler -// --chain=dev -// --header=./substrate/HEADER-APACHE2 // --output=./substrate/frame/scheduler/src/weights.rs +// --header=./substrate/HEADER-APACHE2 // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -77,8 +79,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `31` // Estimated: `1489` - // Minimum execution time: 3_040_000 picoseconds. - Weight::from_parts(3_202_000, 1489) + // Minimum execution time: 3_128_000 picoseconds. + Weight::from_parts(3_372_000, 1489) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -89,10 +91,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `81 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 3_462_000 picoseconds. - Weight::from_parts(6_262_125, 110487) - // Standard Error: 536 - .saturating_add(Weight::from_parts(332_570, 0).saturating_mul(s.into())) + // Minimum execution time: 3_560_000 picoseconds. + Weight::from_parts(6_356_795, 110487) + // Standard Error: 493 + .saturating_add(Weight::from_parts(315_098, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -100,8 +102,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_425_000 picoseconds. - Weight::from_parts(3_680_000, 0) + // Minimum execution time: 3_501_000 picoseconds. + Weight::from_parts(3_722_000, 0) } /// Storage: `Preimage::PreimageFor` (r:1 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `Measured`) @@ -114,10 +116,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `246 + s * (1 ±0)` // Estimated: `3711 + s * (1 ±0)` - // Minimum execution time: 17_564_000 picoseconds. - Weight::from_parts(17_887_000, 3711) - // Standard Error: 1 - .saturating_add(Weight::from_parts(1_253, 0).saturating_mul(s.into())) + // Minimum execution time: 17_976_000 picoseconds. + Weight::from_parts(18_137_000, 3711) + // Standard Error: 0 + .saturating_add(Weight::from_parts(1_173, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(s.into())) @@ -128,16 +130,16 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_934_000 picoseconds. - Weight::from_parts(5_275_000, 0) + // Minimum execution time: 4_935_000 picoseconds. + Weight::from_parts(5_133_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } fn service_task_periodic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_348_000 picoseconds. - Weight::from_parts(3_561_000, 0) + // Minimum execution time: 3_467_000 picoseconds. + Weight::from_parts(3_654_000, 0) } /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -147,16 +149,16 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3997` - // Minimum execution time: 6_395_000 picoseconds. - Weight::from_parts(6_642_000, 3997) + // Minimum execution time: 6_528_000 picoseconds. + Weight::from_parts(6_820_000, 3997) .saturating_add(T::DbWeight::get().reads(2_u64)) } fn execute_dispatch_unsigned() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_167_000 picoseconds. - Weight::from_parts(2_266_000, 0) + // Minimum execution time: 2_202_000 picoseconds. + Weight::from_parts(2_360_000, 0) } /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) @@ -165,15 +167,17 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `81 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 10_009_000 picoseconds. - Weight::from_parts(13_565_985, 110487) - // Standard Error: 575 - .saturating_add(Weight::from_parts(354_760, 0).saturating_mul(s.into())) + // Minimum execution time: 10_222_000 picoseconds. + Weight::from_parts(13_654_958, 110487) + // Standard Error: 676 + .saturating_add(Weight::from_parts(338_633, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Lookup` (r:0 w:1) /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 512]`. @@ -181,12 +185,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `81 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 14_048_000 picoseconds. - Weight::from_parts(15_141_696, 110487) - // Standard Error: 1_082 - .saturating_add(Weight::from_parts(533_390, 0).saturating_mul(s.into())) + // Minimum execution time: 15_517_000 picoseconds. + Weight::from_parts(17_464_075, 110487) + // Standard Error: 952 + .saturating_add(Weight::from_parts(495_806, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `Scheduler::Lookup` (r:1 w:1) /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) @@ -197,10 +201,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `596 + s * (178 ±0)` // Estimated: `110487` - // Minimum execution time: 12_902_000 picoseconds. - Weight::from_parts(18_957_156, 110487) - // Standard Error: 792 - .saturating_add(Weight::from_parts(361_909, 0).saturating_mul(s.into())) + // Minimum execution time: 13_091_000 picoseconds. + Weight::from_parts(19_101_313, 110487) + // Standard Error: 662 + .saturating_add(Weight::from_parts(342_468, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -208,35 +212,35 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 512]`. fn cancel_named(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `709 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 15_933_000 picoseconds. - Weight::from_parts(18_091_415, 110487) - // Standard Error: 779 - .saturating_add(Weight::from_parts(534_402, 0).saturating_mul(s.into())) + // Minimum execution time: 17_579_000 picoseconds. + Weight::from_parts(20_561_921, 110487) + // Standard Error: 792 + .saturating_add(Weight::from_parts(500_463, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Scheduler::Retries` (r:1 w:2) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Lookup` (r:0 w:1) - /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 512]`. fn schedule_retry(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `159` + // Measured: `118` // Estimated: `110487` - // Minimum execution time: 14_155_000 picoseconds. - Weight::from_parts(16_447_031, 110487) - // Standard Error: 233 - .saturating_add(Weight::from_parts(8_424, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) + // Minimum execution time: 8_996_000 picoseconds. + Weight::from_parts(11_393_234, 110487) + // Standard Error: 190 + .saturating_add(Weight::from_parts(6_714, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Scheduler::Agenda` (r:1 w:0) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) @@ -244,10 +248,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn set_retry() -> Weight { // Proof Size summary in bytes: - // Measured: `81 + s * (177 ±0)` + // Measured: `90705` // Estimated: `110487` - // Minimum execution time: 8_130_000 picoseconds. - Weight::from_parts(9_047_554, 110487) + // Minimum execution time: 121_505_000 picoseconds. + Weight::from_parts(124_306_000, 110487) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -259,10 +263,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn set_retry_named() -> Weight { // Proof Size summary in bytes: - // Measured: `647 + s * (178 ±0)` + // Measured: `91747` // Estimated: `110487` - // Minimum execution time: 10_838_000 picoseconds. - Weight::from_parts(12_804_076, 110487) + // Minimum execution time: 128_070_000 picoseconds. + Weight::from_parts(132_683_000, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -272,10 +276,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn cancel_retry() -> Weight { // Proof Size summary in bytes: - // Measured: `81 + s * (177 ±0)` + // Measured: `90717` // Estimated: `110487` - // Minimum execution time: 8_130_000 picoseconds. - Weight::from_parts(9_047_554, 110487) + // Minimum execution time: 118_260_000 picoseconds. + Weight::from_parts(119_722_000, 110487) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -287,10 +291,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn cancel_retry_named() -> Weight { // Proof Size summary in bytes: - // Measured: `647 + s * (178 ±0)` + // Measured: `91759` // Estimated: `110487` - // Minimum execution time: 10_838_000 picoseconds. - Weight::from_parts(12_804_076, 110487) + // Minimum execution time: 129_036_000 picoseconds. + Weight::from_parts(133_975_000, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -304,8 +308,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `31` // Estimated: `1489` - // Minimum execution time: 3_040_000 picoseconds. - Weight::from_parts(3_202_000, 1489) + // Minimum execution time: 3_128_000 picoseconds. + Weight::from_parts(3_372_000, 1489) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -316,10 +320,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `81 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 3_462_000 picoseconds. - Weight::from_parts(6_262_125, 110487) - // Standard Error: 536 - .saturating_add(Weight::from_parts(332_570, 0).saturating_mul(s.into())) + // Minimum execution time: 3_560_000 picoseconds. + Weight::from_parts(6_356_795, 110487) + // Standard Error: 493 + .saturating_add(Weight::from_parts(315_098, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -327,8 +331,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_425_000 picoseconds. - Weight::from_parts(3_680_000, 0) + // Minimum execution time: 3_501_000 picoseconds. + Weight::from_parts(3_722_000, 0) } /// Storage: `Preimage::PreimageFor` (r:1 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `Measured`) @@ -341,10 +345,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `246 + s * (1 ±0)` // Estimated: `3711 + s * (1 ±0)` - // Minimum execution time: 17_564_000 picoseconds. - Weight::from_parts(17_887_000, 3711) - // Standard Error: 1 - .saturating_add(Weight::from_parts(1_253, 0).saturating_mul(s.into())) + // Minimum execution time: 17_976_000 picoseconds. + Weight::from_parts(18_137_000, 3711) + // Standard Error: 0 + .saturating_add(Weight::from_parts(1_173, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(s.into())) @@ -355,16 +359,16 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_934_000 picoseconds. - Weight::from_parts(5_275_000, 0) + // Minimum execution time: 4_935_000 picoseconds. + Weight::from_parts(5_133_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } fn service_task_periodic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_348_000 picoseconds. - Weight::from_parts(3_561_000, 0) + // Minimum execution time: 3_467_000 picoseconds. + Weight::from_parts(3_654_000, 0) } /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -374,16 +378,16 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3997` - // Minimum execution time: 6_395_000 picoseconds. - Weight::from_parts(6_642_000, 3997) + // Minimum execution time: 6_528_000 picoseconds. + Weight::from_parts(6_820_000, 3997) .saturating_add(RocksDbWeight::get().reads(2_u64)) } fn execute_dispatch_unsigned() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_167_000 picoseconds. - Weight::from_parts(2_266_000, 0) + // Minimum execution time: 2_202_000 picoseconds. + Weight::from_parts(2_360_000, 0) } /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) @@ -392,15 +396,17 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `81 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 10_009_000 picoseconds. - Weight::from_parts(13_565_985, 110487) - // Standard Error: 575 - .saturating_add(Weight::from_parts(354_760, 0).saturating_mul(s.into())) + // Minimum execution time: 10_222_000 picoseconds. + Weight::from_parts(13_654_958, 110487) + // Standard Error: 676 + .saturating_add(Weight::from_parts(338_633, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Lookup` (r:0 w:1) /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 512]`. @@ -408,12 +414,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `81 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 14_048_000 picoseconds. - Weight::from_parts(15_141_696, 110487) - // Standard Error: 1_082 - .saturating_add(Weight::from_parts(533_390, 0).saturating_mul(s.into())) + // Minimum execution time: 15_517_000 picoseconds. + Weight::from_parts(17_464_075, 110487) + // Standard Error: 952 + .saturating_add(Weight::from_parts(495_806, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) } /// Storage: `Scheduler::Lookup` (r:1 w:1) /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) @@ -424,10 +430,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `596 + s * (178 ±0)` // Estimated: `110487` - // Minimum execution time: 12_902_000 picoseconds. - Weight::from_parts(18_957_156, 110487) - // Standard Error: 792 - .saturating_add(Weight::from_parts(361_909, 0).saturating_mul(s.into())) + // Minimum execution time: 13_091_000 picoseconds. + Weight::from_parts(19_101_313, 110487) + // Standard Error: 662 + .saturating_add(Weight::from_parts(342_468, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -435,35 +441,35 @@ impl WeightInfo for () { /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 512]`. fn cancel_named(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `709 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 15_933_000 picoseconds. - Weight::from_parts(18_091_415, 110487) - // Standard Error: 779 - .saturating_add(Weight::from_parts(534_402, 0).saturating_mul(s.into())) + // Minimum execution time: 17_579_000 picoseconds. + Weight::from_parts(20_561_921, 110487) + // Standard Error: 792 + .saturating_add(Weight::from_parts(500_463, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Scheduler::Retries` (r:1 w:2) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Lookup` (r:0 w:1) - /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Retries` (r:0 w:1) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 512]`. fn schedule_retry(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `159` + // Measured: `118` // Estimated: `110487` - // Minimum execution time: 14_155_000 picoseconds. - Weight::from_parts(16_447_031, 110487) - // Standard Error: 233 - .saturating_add(Weight::from_parts(8_424, 0).saturating_mul(s.into())) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(4_u64)) + // Minimum execution time: 8_996_000 picoseconds. + Weight::from_parts(11_393_234, 110487) + // Standard Error: 190 + .saturating_add(Weight::from_parts(6_714, 0).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Scheduler::Agenda` (r:1 w:0) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) @@ -471,10 +477,10 @@ impl WeightInfo for () { /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn set_retry() -> Weight { // Proof Size summary in bytes: - // Measured: `81 + s * (177 ±0)` + // Measured: `90705` // Estimated: `110487` - // Minimum execution time: 8_130_000 picoseconds. - Weight::from_parts(9_047_554, 110487) + // Minimum execution time: 121_505_000 picoseconds. + Weight::from_parts(124_306_000, 110487) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -486,10 +492,10 @@ impl WeightInfo for () { /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn set_retry_named() -> Weight { // Proof Size summary in bytes: - // Measured: `647 + s * (178 ±0)` + // Measured: `91747` // Estimated: `110487` - // Minimum execution time: 10_838_000 picoseconds. - Weight::from_parts(12_804_076, 110487) + // Minimum execution time: 128_070_000 picoseconds. + Weight::from_parts(132_683_000, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -499,10 +505,10 @@ impl WeightInfo for () { /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn cancel_retry() -> Weight { // Proof Size summary in bytes: - // Measured: `81 + s * (177 ±0)` + // Measured: `90717` // Estimated: `110487` - // Minimum execution time: 8_130_000 picoseconds. - Weight::from_parts(9_047_554, 110487) + // Minimum execution time: 118_260_000 picoseconds. + Weight::from_parts(119_722_000, 110487) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -514,10 +520,10 @@ impl WeightInfo for () { /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn cancel_retry_named() -> Weight { // Proof Size summary in bytes: - // Measured: `647 + s * (178 ±0)` + // Measured: `91759` // Estimated: `110487` - // Minimum execution time: 10_838_000 picoseconds. - Weight::from_parts(12_804_076, 110487) + // Minimum execution time: 129_036_000 picoseconds. + Weight::from_parts(133_975_000, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/session/src/weights.rs b/substrate/frame/session/src/weights.rs index dd9848fd2c1..09eb665ff3d 100644 --- a/substrate/frame/session/src/weights.rs +++ b/substrate/frame/session/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_session +//! Autogenerated weights for `pallet_session` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/session/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/session/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,77 +49,77 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_session. +/// Weight functions needed for `pallet_session`. pub trait WeightInfo { fn set_keys() -> Weight; fn purge_keys() -> Weight; } -/// Weights for pallet_session using the Substrate node and recommended hardware. +/// Weights for `pallet_session` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Staking Ledger (r:1 w:0) - /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) - /// Storage: Session NextKeys (r:1 w:1) - /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) - /// Storage: Session KeyOwner (r:4 w:4) - /// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured) + /// Storage: `Staking::Ledger` (r:1 w:0) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `Session::NextKeys` (r:1 w:1) + /// Proof: `Session::NextKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Session::KeyOwner` (r:6 w:6) + /// Proof: `Session::KeyOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) fn set_keys() -> Weight { // Proof Size summary in bytes: - // Measured: `1924` - // Estimated: `12814` - // Minimum execution time: 55_459_000 picoseconds. - Weight::from_parts(56_180_000, 12814) - .saturating_add(T::DbWeight::get().reads(6_u64)) - .saturating_add(T::DbWeight::get().writes(5_u64)) + // Measured: `1919` + // Estimated: `17759` + // Minimum execution time: 57_921_000 picoseconds. + Weight::from_parts(58_960_000, 17759) + .saturating_add(T::DbWeight::get().reads(8_u64)) + .saturating_add(T::DbWeight::get().writes(7_u64)) } - /// Storage: Staking Ledger (r:1 w:0) - /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) - /// Storage: Session NextKeys (r:1 w:1) - /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) - /// Storage: Session KeyOwner (r:0 w:4) - /// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured) + /// Storage: `Staking::Ledger` (r:1 w:0) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `Session::NextKeys` (r:1 w:1) + /// Proof: `Session::NextKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Session::KeyOwner` (r:0 w:6) + /// Proof: `Session::KeyOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) fn purge_keys() -> Weight { // Proof Size summary in bytes: - // Measured: `1791` - // Estimated: `5256` - // Minimum execution time: 40_194_000 picoseconds. - Weight::from_parts(41_313_000, 5256) + // Measured: `1817` + // Estimated: `5282` + // Minimum execution time: 40_983_000 picoseconds. + Weight::from_parts(42_700_000, 5282) .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(5_u64)) + .saturating_add(T::DbWeight::get().writes(7_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Staking Ledger (r:1 w:0) - /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) - /// Storage: Session NextKeys (r:1 w:1) - /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) - /// Storage: Session KeyOwner (r:4 w:4) - /// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured) + /// Storage: `Staking::Ledger` (r:1 w:0) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `Session::NextKeys` (r:1 w:1) + /// Proof: `Session::NextKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Session::KeyOwner` (r:6 w:6) + /// Proof: `Session::KeyOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) fn set_keys() -> Weight { // Proof Size summary in bytes: - // Measured: `1924` - // Estimated: `12814` - // Minimum execution time: 55_459_000 picoseconds. - Weight::from_parts(56_180_000, 12814) - .saturating_add(RocksDbWeight::get().reads(6_u64)) - .saturating_add(RocksDbWeight::get().writes(5_u64)) + // Measured: `1919` + // Estimated: `17759` + // Minimum execution time: 57_921_000 picoseconds. + Weight::from_parts(58_960_000, 17759) + .saturating_add(RocksDbWeight::get().reads(8_u64)) + .saturating_add(RocksDbWeight::get().writes(7_u64)) } - /// Storage: Staking Ledger (r:1 w:0) - /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) - /// Storage: Session NextKeys (r:1 w:1) - /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) - /// Storage: Session KeyOwner (r:0 w:4) - /// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured) + /// Storage: `Staking::Ledger` (r:1 w:0) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `Session::NextKeys` (r:1 w:1) + /// Proof: `Session::NextKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Session::KeyOwner` (r:0 w:6) + /// Proof: `Session::KeyOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) fn purge_keys() -> Weight { // Proof Size summary in bytes: - // Measured: `1791` - // Estimated: `5256` - // Minimum execution time: 40_194_000 picoseconds. - Weight::from_parts(41_313_000, 5256) + // Measured: `1817` + // Estimated: `5282` + // Minimum execution time: 40_983_000 picoseconds. + Weight::from_parts(42_700_000, 5282) .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(5_u64)) + .saturating_add(RocksDbWeight::get().writes(7_u64)) } } diff --git a/substrate/frame/society/src/weights.rs b/substrate/frame/society/src/weights.rs index c32c2383ac9..1245f762972 100644 --- a/substrate/frame/society/src/weights.rs +++ b/substrate/frame/society/src/weights.rs @@ -7,7 +7,7 @@ // 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 +// 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, @@ -15,35 +15,41 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_society +//! Autogenerated weights for `pallet_society` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2022-09-13, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev // --steps=50 // --repeat=20 // --pallet=pallet_society +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled -// --template=./.maintain/frame-weight-template.hbs -// --header=./HEADER-APACHE2 -// --output=./frame/society/src/weights.rs +// --heap-pages=4096 +// --output=./substrate/frame/society/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] +#![allow(missing_docs)] use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_society. +/// Weight functions needed for `pallet_society`. pub trait WeightInfo { fn bid() -> Weight; fn unbid() -> Weight; @@ -67,309 +73,739 @@ pub trait WeightInfo { fn cleanup_challenge() -> Weight; } -/// Weights for pallet_society using the Substrate node and recommended hardware. +/// Weights for `pallet_society` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - // Storage: Society Bids (r:1 w:1) - // Storage: Society Candidates (r:1 w:0) - // Storage: Society Members (r:1 w:0) - // Storage: Society SuspendedMembers (r:1 w:0) - // Storage: Society Parameters (r:1 w:0) + /// Storage: `Society::Bids` (r:1 w:1) + /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Candidates` (r:1 w:0) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:1 w:0) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::SuspendedMembers` (r:1 w:0) + /// Proof: `Society::SuspendedMembers` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Parameters` (r:1 w:0) + /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn bid() -> Weight { - Weight::zero() - } - // Storage: Society Bids (r:1 w:1) + // Proof Size summary in bytes: + // Measured: `444` + // Estimated: `3909` + // Minimum execution time: 29_905_000 picoseconds. + Weight::from_parts(31_031_000, 3909) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `Society::Bids` (r:1 w:1) + /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn unbid() -> Weight { - Weight::zero() - } - // Storage: Society Bids (r:1 w:1) - // Storage: Society Candidates (r:1 w:0) - // Storage: Society Members (r:2 w:1) - // Storage: Society SuspendedMembers (r:1 w:0) + // Proof Size summary in bytes: + // Measured: `461` + // Estimated: `1946` + // Minimum execution time: 23_038_000 picoseconds. + Weight::from_parts(23_904_000, 1946) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `Society::Bids` (r:1 w:1) + /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Candidates` (r:1 w:0) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:2 w:1) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::SuspendedMembers` (r:1 w:0) + /// Proof: `Society::SuspendedMembers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn vouch() -> Weight { - Weight::zero() - } - // Storage: Society Bids (r:1 w:1) - // Storage: Society Members (r:1 w:1) + // Proof Size summary in bytes: + // Measured: `481` + // Estimated: `6421` + // Minimum execution time: 21_197_000 picoseconds. + Weight::from_parts(22_043_000, 6421) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `Society::Bids` (r:1 w:1) + /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:1 w:1) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) fn unvouch() -> Weight { - Weight::zero() - } - // Storage: Society Candidates (r:1 w:1) - // Storage: Society Members (r:1 w:0) - // Storage: Society Votes (r:1 w:1) + // Proof Size summary in bytes: + // Measured: `535` + // Estimated: `4000` + // Minimum execution time: 14_402_000 picoseconds. + Weight::from_parts(15_171_000, 4000) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `Society::Candidates` (r:1 w:1) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:1 w:0) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Votes` (r:1 w:1) + /// Proof: `Society::Votes` (`max_values`: None, `max_size`: None, mode: `Measured`) fn vote() -> Weight { - Weight::zero() - } - // Storage: Society Defending (r:1 w:1) - // Storage: Society Members (r:1 w:0) - // Storage: Society ChallengeRoundCount (r:1 w:0) - // Storage: Society DefenderVotes (r:1 w:1) + // Proof Size summary in bytes: + // Measured: `569` + // Estimated: `4034` + // Minimum execution time: 21_930_000 picoseconds. + Weight::from_parts(22_666_000, 4034) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `Society::Defending` (r:1 w:1) + /// Proof: `Society::Defending` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:1 w:0) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::ChallengeRoundCount` (r:1 w:0) + /// Proof: `Society::ChallengeRoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::DefenderVotes` (r:1 w:1) + /// Proof: `Society::DefenderVotes` (`max_values`: None, `max_size`: None, mode: `Measured`) fn defender_vote() -> Weight { - Weight::zero() - } - // Storage: Society Members (r:1 w:0) - // Storage: Society Payouts (r:1 w:1) - // Storage: System Account (r:1 w:1) + // Proof Size summary in bytes: + // Measured: `561` + // Estimated: `4026` + // Minimum execution time: 18_821_000 picoseconds. + Weight::from_parts(19_633_000, 4026) + .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `Society::Members` (r:1 w:0) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Payouts` (r:1 w:1) + /// Proof: `Society::Payouts` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn payout() -> Weight { - Weight::zero() - } - // Storage: Society Members (r:1 w:1) - // Storage: Society Payouts (r:1 w:1) + // Proof Size summary in bytes: + // Measured: `650` + // Estimated: `4115` + // Minimum execution time: 47_262_000 picoseconds. + Weight::from_parts(48_313_000, 4115) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `Society::Members` (r:1 w:1) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Payouts` (r:1 w:1) + /// Proof: `Society::Payouts` (`max_values`: None, `max_size`: None, mode: `Measured`) fn waive_repay() -> Weight { - Weight::zero() - } - // Storage: Society Head (r:1 w:1) - // Storage: Society MemberCount (r:1 w:1) - // Storage: Society MemberByIndex (r:0 w:1) - // Storage: Society Founder (r:0 w:1) - // Storage: Society Rules (r:0 w:1) - // Storage: Society Members (r:0 w:1) - // Storage: Society Parameters (r:0 w:1) + // Proof Size summary in bytes: + // Measured: `547` + // Estimated: `4012` + // Minimum execution time: 18_189_000 picoseconds. + Weight::from_parts(19_038_000, 4012) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `Society::Head` (r:1 w:1) + /// Proof: `Society::Head` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::MemberCount` (r:1 w:1) + /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::MemberByIndex` (r:0 w:1) + /// Proof: `Society::MemberByIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Founder` (r:0 w:1) + /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Rules` (r:0 w:1) + /// Proof: `Society::Rules` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:0 w:1) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Parameters` (r:0 w:1) + /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn found_society() -> Weight { - Weight::zero() - } - // Storage: Society Founder (r:1 w:1) - // Storage: Society MemberCount (r:1 w:1) - // Storage: Society Head (r:0 w:1) - // Storage: Society Defending (r:0 w:1) - // Storage: Society ChallengeRoundCount (r:0 w:1) - // Storage: Society MemberByIndex (r:0 w:5) - // Storage: Society Skeptic (r:0 w:1) - // Storage: Society Candidates (r:0 w:4) - // Storage: Society Pot (r:0 w:1) - // Storage: Society Rules (r:0 w:1) - // Storage: Society Votes (r:0 w:4) - // Storage: Society Members (r:0 w:5) - // Storage: Society RoundCount (r:0 w:1) - // Storage: Society Bids (r:0 w:1) - // Storage: Society Parameters (r:0 w:1) - // Storage: Society NextHead (r:0 w:1) + // Proof Size summary in bytes: + // Measured: `180` + // Estimated: `1665` + // Minimum execution time: 14_815_000 picoseconds. + Weight::from_parts(15_426_000, 1665) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(7_u64)) + } + /// Storage: `Society::Founder` (r:1 w:1) + /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::MemberCount` (r:1 w:1) + /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:5 w:5) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::MemberByIndex` (r:5 w:5) + /// Proof: `Society::MemberByIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Votes` (r:4 w:4) + /// Proof: `Society::Votes` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Candidates` (r:4 w:4) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Head` (r:0 w:1) + /// Proof: `Society::Head` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Defending` (r:0 w:1) + /// Proof: `Society::Defending` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::ChallengeRoundCount` (r:0 w:1) + /// Proof: `Society::ChallengeRoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Skeptic` (r:0 w:1) + /// Proof: `Society::Skeptic` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Pot` (r:0 w:1) + /// Proof: `Society::Pot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Rules` (r:0 w:1) + /// Proof: `Society::Rules` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::RoundCount` (r:0 w:1) + /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Bids` (r:0 w:1) + /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Parameters` (r:0 w:1) + /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::NextHead` (r:0 w:1) + /// Proof: `Society::NextHead` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn dissolve() -> Weight { - Weight::zero() - } - // Storage: Society Founder (r:1 w:0) - // Storage: Society SuspendedMembers (r:1 w:1) - // Storage: Society Payouts (r:1 w:0) - // Storage: Society Pot (r:1 w:1) + // Proof Size summary in bytes: + // Measured: `1654` + // Estimated: `15019` + // Minimum execution time: 57_787_000 picoseconds. + Weight::from_parts(59_489_000, 15019) + .saturating_add(T::DbWeight::get().reads(20_u64)) + .saturating_add(T::DbWeight::get().writes(30_u64)) + } + /// Storage: `Society::Founder` (r:1 w:0) + /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::SuspendedMembers` (r:1 w:1) + /// Proof: `Society::SuspendedMembers` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Payouts` (r:1 w:0) + /// Proof: `Society::Payouts` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Pot` (r:1 w:1) + /// Proof: `Society::Pot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn judge_suspended_member() -> Weight { - Weight::zero() - } - // Storage: Society Founder (r:1 w:0) - // Storage: Society MemberCount (r:1 w:0) - // Storage: Society Parameters (r:0 w:1) + // Proof Size summary in bytes: + // Measured: `505` + // Estimated: `3970` + // Minimum execution time: 19_262_000 picoseconds. + Weight::from_parts(19_752_000, 3970) + .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `Society::Founder` (r:1 w:0) + /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::MemberCount` (r:1 w:0) + /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Parameters` (r:0 w:1) + /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn set_parameters() -> Weight { - Weight::zero() - } - // Storage: Society Candidates (r:1 w:1) - // Storage: Society RoundCount (r:1 w:0) - // Storage: Society Skeptic (r:1 w:0) - // Storage: Society Votes (r:1 w:0) - // Storage: Society Members (r:1 w:1) - // Storage: Society Parameters (r:1 w:0) + // Proof Size summary in bytes: + // Measured: `387` + // Estimated: `1872` + // Minimum execution time: 10_656_000 picoseconds. + Weight::from_parts(11_063_000, 1872) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `Society::Candidates` (r:1 w:1) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::RoundCount` (r:1 w:0) + /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Skeptic` (r:1 w:0) + /// Proof: `Society::Skeptic` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Votes` (r:1 w:0) + /// Proof: `Society::Votes` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:1 w:1) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Parameters` (r:1 w:0) + /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn punish_skeptic() -> Weight { - Weight::zero() - } - // Storage: Society Candidates (r:1 w:1) - // Storage: Society RoundCount (r:1 w:0) - // Storage: Society Parameters (r:1 w:0) - // Storage: Society MemberCount (r:1 w:1) - // Storage: Society NextHead (r:1 w:1) - // Storage: System Account (r:1 w:1) - // Storage: Society MemberByIndex (r:0 w:1) - // Storage: Society Members (r:0 w:1) + // Proof Size summary in bytes: + // Measured: `636` + // Estimated: `4101` + // Minimum execution time: 22_837_000 picoseconds. + Weight::from_parts(23_738_000, 4101) + .saturating_add(T::DbWeight::get().reads(6_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `Society::Candidates` (r:1 w:1) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::RoundCount` (r:1 w:0) + /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Parameters` (r:1 w:0) + /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::MemberCount` (r:1 w:1) + /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::NextHead` (r:1 w:1) + /// Proof: `Society::NextHead` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Society::MemberByIndex` (r:0 w:1) + /// Proof: `Society::MemberByIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:0 w:1) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) fn claim_membership() -> Weight { - Weight::zero() - } - // Storage: Society Founder (r:1 w:0) - // Storage: Society Candidates (r:1 w:1) - // Storage: Society RoundCount (r:1 w:0) - // Storage: Society Parameters (r:1 w:0) - // Storage: Society MemberCount (r:1 w:1) - // Storage: Society NextHead (r:1 w:1) - // Storage: System Account (r:1 w:1) - // Storage: Society MemberByIndex (r:0 w:1) - // Storage: Society Members (r:0 w:1) + // Proof Size summary in bytes: + // Measured: `632` + // Estimated: `4097` + // Minimum execution time: 35_142_000 picoseconds. + Weight::from_parts(36_811_000, 4097) + .saturating_add(T::DbWeight::get().reads(6_u64)) + .saturating_add(T::DbWeight::get().writes(6_u64)) + } + /// Storage: `Society::Founder` (r:1 w:0) + /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Candidates` (r:1 w:1) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::RoundCount` (r:1 w:0) + /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Parameters` (r:1 w:0) + /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::MemberCount` (r:1 w:1) + /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::NextHead` (r:1 w:1) + /// Proof: `Society::NextHead` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Society::MemberByIndex` (r:0 w:1) + /// Proof: `Society::MemberByIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:0 w:1) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) fn bestow_membership() -> Weight { - Weight::zero() - } - // Storage: Society Founder (r:1 w:0) - // Storage: Society Candidates (r:1 w:1) - // Storage: Society RoundCount (r:1 w:0) + // Proof Size summary in bytes: + // Measured: `650` + // Estimated: `4115` + // Minimum execution time: 37_133_000 picoseconds. + Weight::from_parts(38_366_000, 4115) + .saturating_add(T::DbWeight::get().reads(7_u64)) + .saturating_add(T::DbWeight::get().writes(6_u64)) + } + /// Storage: `Society::Founder` (r:1 w:0) + /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Candidates` (r:1 w:1) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::RoundCount` (r:1 w:0) + /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn kick_candidate() -> Weight { - Weight::zero() - } - // Storage: Society Candidates (r:1 w:1) - // Storage: Society RoundCount (r:1 w:0) + // Proof Size summary in bytes: + // Measured: `776` + // Estimated: `6196` + // Minimum execution time: 37_033_000 picoseconds. + Weight::from_parts(38_293_000, 6196) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) + } + /// Storage: `Society::Candidates` (r:1 w:1) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::RoundCount` (r:1 w:0) + /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn resign_candidacy() -> Weight { - Weight::zero() - } - // Storage: Society Candidates (r:1 w:1) - // Storage: Society RoundCount (r:1 w:0) + // Proof Size summary in bytes: + // Measured: `746` + // Estimated: `6196` + // Minimum execution time: 35_203_000 picoseconds. + Weight::from_parts(36_252_000, 6196) + .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) + } + /// Storage: `Society::Candidates` (r:1 w:1) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::RoundCount` (r:1 w:0) + /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn drop_candidate() -> Weight { - Weight::zero() - } - // Storage: Society Candidates (r:1 w:0) - // Storage: Society VoteClearCursor (r:1 w:0) - // Storage: Society Votes (r:0 w:2) + // Proof Size summary in bytes: + // Measured: `758` + // Estimated: `6196` + // Minimum execution time: 35_518_000 picoseconds. + Weight::from_parts(36_508_000, 6196) + .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) + } + /// Storage: `Society::Candidates` (r:1 w:0) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::VoteClearCursor` (r:1 w:0) + /// Proof: `Society::VoteClearCursor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Votes` (r:2 w:2) + /// Proof: `Society::Votes` (`max_values`: None, `max_size`: None, mode: `Measured`) fn cleanup_candidacy() -> Weight { - Weight::zero() - } - // Storage: Society ChallengeRoundCount (r:1 w:0) - // Storage: Society DefenderVotes (r:0 w:1) + // Proof Size summary in bytes: + // Measured: `552` + // Estimated: `6492` + // Minimum execution time: 17_001_000 picoseconds. + Weight::from_parts(17_845_000, 6492) + .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `Society::ChallengeRoundCount` (r:1 w:0) + /// Proof: `Society::ChallengeRoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::DefenderVotes` (r:1 w:1) + /// Proof: `Society::DefenderVotes` (`max_values`: None, `max_size`: None, mode: `Measured`) fn cleanup_challenge() -> Weight { - Weight::zero() + // Proof Size summary in bytes: + // Measured: `510` + // Estimated: `3975` + // Minimum execution time: 11_583_000 picoseconds. + Weight::from_parts(12_134_000, 3975) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - // Storage: Society Bids (r:1 w:1) - // Storage: Society Candidates (r:1 w:0) - // Storage: Society Members (r:1 w:0) - // Storage: Society SuspendedMembers (r:1 w:0) - // Storage: Society Parameters (r:1 w:0) + /// Storage: `Society::Bids` (r:1 w:1) + /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Candidates` (r:1 w:0) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:1 w:0) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::SuspendedMembers` (r:1 w:0) + /// Proof: `Society::SuspendedMembers` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Parameters` (r:1 w:0) + /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn bid() -> Weight { - Weight::zero() - } - // Storage: Society Bids (r:1 w:1) + // Proof Size summary in bytes: + // Measured: `444` + // Estimated: `3909` + // Minimum execution time: 29_905_000 picoseconds. + Weight::from_parts(31_031_000, 3909) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `Society::Bids` (r:1 w:1) + /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn unbid() -> Weight { - Weight::zero() - } - // Storage: Society Bids (r:1 w:1) - // Storage: Society Candidates (r:1 w:0) - // Storage: Society Members (r:2 w:1) - // Storage: Society SuspendedMembers (r:1 w:0) + // Proof Size summary in bytes: + // Measured: `461` + // Estimated: `1946` + // Minimum execution time: 23_038_000 picoseconds. + Weight::from_parts(23_904_000, 1946) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `Society::Bids` (r:1 w:1) + /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Candidates` (r:1 w:0) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:2 w:1) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::SuspendedMembers` (r:1 w:0) + /// Proof: `Society::SuspendedMembers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn vouch() -> Weight { - Weight::zero() - } - // Storage: Society Bids (r:1 w:1) - // Storage: Society Members (r:1 w:1) + // Proof Size summary in bytes: + // Measured: `481` + // Estimated: `6421` + // Minimum execution time: 21_197_000 picoseconds. + Weight::from_parts(22_043_000, 6421) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `Society::Bids` (r:1 w:1) + /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:1 w:1) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) fn unvouch() -> Weight { - Weight::zero() - } - // Storage: Society Candidates (r:1 w:1) - // Storage: Society Members (r:1 w:0) - // Storage: Society Votes (r:1 w:1) + // Proof Size summary in bytes: + // Measured: `535` + // Estimated: `4000` + // Minimum execution time: 14_402_000 picoseconds. + Weight::from_parts(15_171_000, 4000) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `Society::Candidates` (r:1 w:1) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:1 w:0) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Votes` (r:1 w:1) + /// Proof: `Society::Votes` (`max_values`: None, `max_size`: None, mode: `Measured`) fn vote() -> Weight { - Weight::zero() - } - // Storage: Society Defending (r:1 w:1) - // Storage: Society Members (r:1 w:0) - // Storage: Society ChallengeRoundCount (r:1 w:0) - // Storage: Society DefenderVotes (r:1 w:1) + // Proof Size summary in bytes: + // Measured: `569` + // Estimated: `4034` + // Minimum execution time: 21_930_000 picoseconds. + Weight::from_parts(22_666_000, 4034) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `Society::Defending` (r:1 w:1) + /// Proof: `Society::Defending` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:1 w:0) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::ChallengeRoundCount` (r:1 w:0) + /// Proof: `Society::ChallengeRoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::DefenderVotes` (r:1 w:1) + /// Proof: `Society::DefenderVotes` (`max_values`: None, `max_size`: None, mode: `Measured`) fn defender_vote() -> Weight { - Weight::zero() - } - // Storage: Society Members (r:1 w:0) - // Storage: Society Payouts (r:1 w:1) - // Storage: System Account (r:1 w:1) + // Proof Size summary in bytes: + // Measured: `561` + // Estimated: `4026` + // Minimum execution time: 18_821_000 picoseconds. + Weight::from_parts(19_633_000, 4026) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `Society::Members` (r:1 w:0) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Payouts` (r:1 w:1) + /// Proof: `Society::Payouts` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn payout() -> Weight { - Weight::zero() - } - // Storage: Society Members (r:1 w:1) - // Storage: Society Payouts (r:1 w:1) + // Proof Size summary in bytes: + // Measured: `650` + // Estimated: `4115` + // Minimum execution time: 47_262_000 picoseconds. + Weight::from_parts(48_313_000, 4115) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `Society::Members` (r:1 w:1) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Payouts` (r:1 w:1) + /// Proof: `Society::Payouts` (`max_values`: None, `max_size`: None, mode: `Measured`) fn waive_repay() -> Weight { - Weight::zero() - } - // Storage: Society Head (r:1 w:1) - // Storage: Society MemberCount (r:1 w:1) - // Storage: Society MemberByIndex (r:0 w:1) - // Storage: Society Founder (r:0 w:1) - // Storage: Society Rules (r:0 w:1) - // Storage: Society Members (r:0 w:1) - // Storage: Society Parameters (r:0 w:1) + // Proof Size summary in bytes: + // Measured: `547` + // Estimated: `4012` + // Minimum execution time: 18_189_000 picoseconds. + Weight::from_parts(19_038_000, 4012) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `Society::Head` (r:1 w:1) + /// Proof: `Society::Head` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::MemberCount` (r:1 w:1) + /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::MemberByIndex` (r:0 w:1) + /// Proof: `Society::MemberByIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Founder` (r:0 w:1) + /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Rules` (r:0 w:1) + /// Proof: `Society::Rules` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:0 w:1) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Parameters` (r:0 w:1) + /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn found_society() -> Weight { - Weight::zero() - } - // Storage: Society Founder (r:1 w:1) - // Storage: Society MemberCount (r:1 w:1) - // Storage: Society Head (r:0 w:1) - // Storage: Society Defending (r:0 w:1) - // Storage: Society ChallengeRoundCount (r:0 w:1) - // Storage: Society MemberByIndex (r:0 w:5) - // Storage: Society Skeptic (r:0 w:1) - // Storage: Society Candidates (r:0 w:4) - // Storage: Society Pot (r:0 w:1) - // Storage: Society Rules (r:0 w:1) - // Storage: Society Votes (r:0 w:4) - // Storage: Society Members (r:0 w:5) - // Storage: Society RoundCount (r:0 w:1) - // Storage: Society Bids (r:0 w:1) - // Storage: Society Parameters (r:0 w:1) - // Storage: Society NextHead (r:0 w:1) + // Proof Size summary in bytes: + // Measured: `180` + // Estimated: `1665` + // Minimum execution time: 14_815_000 picoseconds. + Weight::from_parts(15_426_000, 1665) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(7_u64)) + } + /// Storage: `Society::Founder` (r:1 w:1) + /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::MemberCount` (r:1 w:1) + /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:5 w:5) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::MemberByIndex` (r:5 w:5) + /// Proof: `Society::MemberByIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Votes` (r:4 w:4) + /// Proof: `Society::Votes` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Candidates` (r:4 w:4) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Head` (r:0 w:1) + /// Proof: `Society::Head` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Defending` (r:0 w:1) + /// Proof: `Society::Defending` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::ChallengeRoundCount` (r:0 w:1) + /// Proof: `Society::ChallengeRoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Skeptic` (r:0 w:1) + /// Proof: `Society::Skeptic` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Pot` (r:0 w:1) + /// Proof: `Society::Pot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Rules` (r:0 w:1) + /// Proof: `Society::Rules` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::RoundCount` (r:0 w:1) + /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Bids` (r:0 w:1) + /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Parameters` (r:0 w:1) + /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::NextHead` (r:0 w:1) + /// Proof: `Society::NextHead` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn dissolve() -> Weight { - Weight::zero() - } - // Storage: Society Founder (r:1 w:0) - // Storage: Society SuspendedMembers (r:1 w:1) - // Storage: Society Payouts (r:1 w:0) - // Storage: Society Pot (r:1 w:1) + // Proof Size summary in bytes: + // Measured: `1654` + // Estimated: `15019` + // Minimum execution time: 57_787_000 picoseconds. + Weight::from_parts(59_489_000, 15019) + .saturating_add(RocksDbWeight::get().reads(20_u64)) + .saturating_add(RocksDbWeight::get().writes(30_u64)) + } + /// Storage: `Society::Founder` (r:1 w:0) + /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::SuspendedMembers` (r:1 w:1) + /// Proof: `Society::SuspendedMembers` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Payouts` (r:1 w:0) + /// Proof: `Society::Payouts` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Pot` (r:1 w:1) + /// Proof: `Society::Pot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn judge_suspended_member() -> Weight { - Weight::zero() - } - // Storage: Society Founder (r:1 w:0) - // Storage: Society MemberCount (r:1 w:0) - // Storage: Society Parameters (r:0 w:1) + // Proof Size summary in bytes: + // Measured: `505` + // Estimated: `3970` + // Minimum execution time: 19_262_000 picoseconds. + Weight::from_parts(19_752_000, 3970) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `Society::Founder` (r:1 w:0) + /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::MemberCount` (r:1 w:0) + /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Parameters` (r:0 w:1) + /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn set_parameters() -> Weight { - Weight::zero() - } - // Storage: Society Candidates (r:1 w:1) - // Storage: Society RoundCount (r:1 w:0) - // Storage: Society Skeptic (r:1 w:0) - // Storage: Society Votes (r:1 w:0) - // Storage: Society Members (r:1 w:1) - // Storage: Society Parameters (r:1 w:0) + // Proof Size summary in bytes: + // Measured: `387` + // Estimated: `1872` + // Minimum execution time: 10_656_000 picoseconds. + Weight::from_parts(11_063_000, 1872) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `Society::Candidates` (r:1 w:1) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::RoundCount` (r:1 w:0) + /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Skeptic` (r:1 w:0) + /// Proof: `Society::Skeptic` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Votes` (r:1 w:0) + /// Proof: `Society::Votes` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:1 w:1) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Parameters` (r:1 w:0) + /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn punish_skeptic() -> Weight { - Weight::zero() - } - // Storage: Society Candidates (r:1 w:1) - // Storage: Society RoundCount (r:1 w:0) - // Storage: Society Parameters (r:1 w:0) - // Storage: Society MemberCount (r:1 w:1) - // Storage: Society NextHead (r:1 w:1) - // Storage: System Account (r:1 w:1) - // Storage: Society MemberByIndex (r:0 w:1) - // Storage: Society Members (r:0 w:1) + // Proof Size summary in bytes: + // Measured: `636` + // Estimated: `4101` + // Minimum execution time: 22_837_000 picoseconds. + Weight::from_parts(23_738_000, 4101) + .saturating_add(RocksDbWeight::get().reads(6_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `Society::Candidates` (r:1 w:1) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::RoundCount` (r:1 w:0) + /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Parameters` (r:1 w:0) + /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::MemberCount` (r:1 w:1) + /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::NextHead` (r:1 w:1) + /// Proof: `Society::NextHead` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Society::MemberByIndex` (r:0 w:1) + /// Proof: `Society::MemberByIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:0 w:1) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) fn claim_membership() -> Weight { - Weight::zero() - } - // Storage: Society Founder (r:1 w:0) - // Storage: Society Candidates (r:1 w:1) - // Storage: Society RoundCount (r:1 w:0) - // Storage: Society Parameters (r:1 w:0) - // Storage: Society MemberCount (r:1 w:1) - // Storage: Society NextHead (r:1 w:1) - // Storage: System Account (r:1 w:1) - // Storage: Society MemberByIndex (r:0 w:1) - // Storage: Society Members (r:0 w:1) + // Proof Size summary in bytes: + // Measured: `632` + // Estimated: `4097` + // Minimum execution time: 35_142_000 picoseconds. + Weight::from_parts(36_811_000, 4097) + .saturating_add(RocksDbWeight::get().reads(6_u64)) + .saturating_add(RocksDbWeight::get().writes(6_u64)) + } + /// Storage: `Society::Founder` (r:1 w:0) + /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Candidates` (r:1 w:1) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::RoundCount` (r:1 w:0) + /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Parameters` (r:1 w:0) + /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::MemberCount` (r:1 w:1) + /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::NextHead` (r:1 w:1) + /// Proof: `Society::NextHead` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Society::MemberByIndex` (r:0 w:1) + /// Proof: `Society::MemberByIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Members` (r:0 w:1) + /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) fn bestow_membership() -> Weight { - Weight::zero() - } - // Storage: Society Founder (r:1 w:0) - // Storage: Society Candidates (r:1 w:1) - // Storage: Society RoundCount (r:1 w:0) + // Proof Size summary in bytes: + // Measured: `650` + // Estimated: `4115` + // Minimum execution time: 37_133_000 picoseconds. + Weight::from_parts(38_366_000, 4115) + .saturating_add(RocksDbWeight::get().reads(7_u64)) + .saturating_add(RocksDbWeight::get().writes(6_u64)) + } + /// Storage: `Society::Founder` (r:1 w:0) + /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::Candidates` (r:1 w:1) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::RoundCount` (r:1 w:0) + /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn kick_candidate() -> Weight { - Weight::zero() - } - // Storage: Society Candidates (r:1 w:1) - // Storage: Society RoundCount (r:1 w:0) + // Proof Size summary in bytes: + // Measured: `776` + // Estimated: `6196` + // Minimum execution time: 37_033_000 picoseconds. + Weight::from_parts(38_293_000, 6196) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } + /// Storage: `Society::Candidates` (r:1 w:1) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::RoundCount` (r:1 w:0) + /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn resign_candidacy() -> Weight { - Weight::zero() - } - // Storage: Society Candidates (r:1 w:1) - // Storage: Society RoundCount (r:1 w:0) + // Proof Size summary in bytes: + // Measured: `746` + // Estimated: `6196` + // Minimum execution time: 35_203_000 picoseconds. + Weight::from_parts(36_252_000, 6196) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } + /// Storage: `Society::Candidates` (r:1 w:1) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::RoundCount` (r:1 w:0) + /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn drop_candidate() -> Weight { - Weight::zero() - } - // Storage: Society Candidates (r:1 w:0) - // Storage: Society VoteClearCursor (r:1 w:0) - // Storage: Society Votes (r:0 w:2) + // Proof Size summary in bytes: + // Measured: `758` + // Estimated: `6196` + // Minimum execution time: 35_518_000 picoseconds. + Weight::from_parts(36_508_000, 6196) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + } + /// Storage: `Society::Candidates` (r:1 w:0) + /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::VoteClearCursor` (r:1 w:0) + /// Proof: `Society::VoteClearCursor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Society::Votes` (r:2 w:2) + /// Proof: `Society::Votes` (`max_values`: None, `max_size`: None, mode: `Measured`) fn cleanup_candidacy() -> Weight { - Weight::zero() - } - // Storage: Society ChallengeRoundCount (r:1 w:0) - // Storage: Society DefenderVotes (r:0 w:1) + // Proof Size summary in bytes: + // Measured: `552` + // Estimated: `6492` + // Minimum execution time: 17_001_000 picoseconds. + Weight::from_parts(17_845_000, 6492) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `Society::ChallengeRoundCount` (r:1 w:0) + /// Proof: `Society::ChallengeRoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Society::DefenderVotes` (r:1 w:1) + /// Proof: `Society::DefenderVotes` (`max_values`: None, `max_size`: None, mode: `Measured`) fn cleanup_challenge() -> Weight { - Weight::zero() + // Proof Size summary in bytes: + // Measured: `510` + // Estimated: `3975` + // Minimum execution time: 11_583_000 picoseconds. + Weight::from_parts(12_134_000, 3975) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } } diff --git a/substrate/frame/src/lib.rs b/substrate/frame/src/lib.rs index 52db7c34bfd..549e177491d 100644 --- a/substrate/frame/src/lib.rs +++ b/substrate/frame/src/lib.rs @@ -249,8 +249,8 @@ pub mod runtime { /// The block type, which should be fed into [`frame_system::Config`]. /// - /// Should be parameterized with `T: frame_system::Config` and a tuple of `SignedExtension`. - /// When in doubt, use [`SystemSignedExtensionsOf`]. + /// Should be parameterized with `T: frame_system::Config` and a tuple of + /// `TransactionExtension`. When in doubt, use [`SystemTransactionExtensionsOf`]. // Note that this cannot be dependent on `T` for block-number because it would lead to a // circular dependency (self-referential generics). pub type BlockOf = generic::Block>; @@ -264,7 +264,7 @@ pub mod runtime { /// Default set of signed extensions exposed from the `frame_system`. /// /// crucially, this does NOT contain any tx-payment extension. - pub type SystemSignedExtensionsOf = ( + pub type SystemTransactionExtensionsOf = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, diff --git a/substrate/frame/staking/src/weights.rs b/substrate/frame/staking/src/weights.rs index 6f729e08ba5..8288591a787 100644 --- a/substrate/frame/staking/src/weights.rs +++ b/substrate/frame/staking/src/weights.rs @@ -17,26 +17,28 @@ //! Autogenerated weights for `pallet_staking` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-01-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-q7z7ruxr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// target/production/substrate-node +// ./target/production/substrate-node // benchmark // pallet +// --chain=dev // --steps=50 // --repeat=20 +// --pallet=pallet_staking +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_staking -// --chain=dev -// --header=./substrate/HEADER-APACHE2 // --output=./substrate/frame/staking/src/weights.rs +// --header=./substrate/HEADER-APACHE2 // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -99,8 +101,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `927` // Estimated: `4764` - // Minimum execution time: 42_042_000 picoseconds. - Weight::from_parts(43_292_000, 4764) + // Minimum execution time: 41_318_000 picoseconds. + Weight::from_parts(43_268_000, 4764) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -120,8 +122,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1990` // Estimated: `8877` - // Minimum execution time: 85_050_000 picoseconds. - Weight::from_parts(87_567_000, 8877) + // Minimum execution time: 85_666_000 picoseconds. + Weight::from_parts(88_749_000, 8877) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } @@ -147,8 +149,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2195` // Estimated: `8877` - // Minimum execution time: 89_076_000 picoseconds. - Weight::from_parts(92_715_000, 8877) + // Minimum execution time: 90_282_000 picoseconds. + Weight::from_parts(92_332_000, 8877) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } @@ -162,16 +164,18 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:0) + /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_update(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1115` + // Measured: `1297` // Estimated: `4764` - // Minimum execution time: 42_067_000 picoseconds. - Weight::from_parts(43_239_807, 4764) - // Standard Error: 831 - .saturating_add(Weight::from_parts(46_257, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(5_u64)) + // Minimum execution time: 44_626_000 picoseconds. + Weight::from_parts(47_254_657, 4764) + // Standard Error: 1_179 + .saturating_add(Weight::from_parts(57_657, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Staking::Ledger` (r:1 w:1) @@ -207,10 +211,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2196 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 86_490_000 picoseconds. - Weight::from_parts(95_358_751, 6248) - // Standard Error: 3_952 - .saturating_add(Weight::from_parts(1_294_907, 0).saturating_mul(s.into())) + // Minimum execution time: 86_769_000 picoseconds. + Weight::from_parts(95_212_867, 6248) + // Standard Error: 3_706 + .saturating_add(Weight::from_parts(1_320_752, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(13_u64)) .saturating_add(T::DbWeight::get().writes(11_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) @@ -242,8 +246,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1372` // Estimated: `4556` - // Minimum execution time: 50_326_000 picoseconds. - Weight::from_parts(52_253_000, 4556) + // Minimum execution time: 50_410_000 picoseconds. + Weight::from_parts(52_576_000, 4556) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } @@ -256,10 +260,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1280 + k * (569 ±0)` // Estimated: `4556 + k * (3033 ±0)` - // Minimum execution time: 29_305_000 picoseconds. - Weight::from_parts(32_199_604, 4556) - // Standard Error: 7_150 - .saturating_add(Weight::from_parts(6_437_124, 0).saturating_mul(k.into())) + // Minimum execution time: 29_017_000 picoseconds. + Weight::from_parts(33_019_206, 4556) + // Standard Error: 6_368 + .saturating_add(Weight::from_parts(6_158_681, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(k.into()))) @@ -292,10 +296,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1866 + n * (102 ±0)` // Estimated: `6248 + n * (2520 ±0)` - // Minimum execution time: 63_267_000 picoseconds. - Weight::from_parts(61_741_404, 6248) - // Standard Error: 12_955 - .saturating_add(Weight::from_parts(3_811_743, 0).saturating_mul(n.into())) + // Minimum execution time: 63_452_000 picoseconds. + Weight::from_parts(60_924_066, 6248) + // Standard Error: 14_416 + .saturating_add(Weight::from_parts(3_921_589, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(6_u64)) @@ -319,8 +323,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1650` // Estimated: `6248` - // Minimum execution time: 52_862_000 picoseconds. - Weight::from_parts(54_108_000, 6248) + // Minimum execution time: 54_253_000 picoseconds. + Weight::from_parts(55_286_000, 6248) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -334,8 +338,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `902` // Estimated: `4556` - // Minimum execution time: 16_350_000 picoseconds. - Weight::from_parts(16_802_000, 4556) + // Minimum execution time: 16_812_000 picoseconds. + Weight::from_parts(17_380_000, 4556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -349,8 +353,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `969` // Estimated: `4556` - // Minimum execution time: 19_981_000 picoseconds. - Weight::from_parts(20_539_000, 4556) + // Minimum execution time: 20_590_000 picoseconds. + Weight::from_parts(21_096_000, 4556) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -362,8 +366,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `902` // Estimated: `4556` - // Minimum execution time: 19_304_000 picoseconds. - Weight::from_parts(20_000_000, 4556) + // Minimum execution time: 19_923_000 picoseconds. + Weight::from_parts(20_880_000, 4556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -373,8 +377,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_568_000 picoseconds. - Weight::from_parts(2_708_000, 0) + // Minimum execution time: 2_599_000 picoseconds. + Weight::from_parts(2_751_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -383,8 +387,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_950_000 picoseconds. - Weight::from_parts(8_348_000, 0) + // Minimum execution time: 6_941_000 picoseconds. + Weight::from_parts(7_288_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -393,8 +397,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_967_000 picoseconds. - Weight::from_parts(8_222_000, 0) + // Minimum execution time: 6_757_000 picoseconds. + Weight::from_parts(7_200_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -403,8 +407,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_006_000 picoseconds. - Weight::from_parts(8_440_000, 0) + // Minimum execution time: 7_028_000 picoseconds. + Weight::from_parts(7_366_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::Invulnerables` (r:0 w:1) @@ -414,10 +418,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_524_000 picoseconds. - Weight::from_parts(3_123_608, 0) - // Standard Error: 59 - .saturating_add(Weight::from_parts(11_596, 0).saturating_mul(v.into())) + // Minimum execution time: 2_741_000 picoseconds. + Weight::from_parts(3_212_598, 0) + // Standard Error: 68 + .saturating_add(Weight::from_parts(11_695, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::Ledger` (r:5900 w:11800) @@ -431,10 +435,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1356 + i * (151 ±0)` // Estimated: `990 + i * (3566 ±0)` - // Minimum execution time: 2_092_000 picoseconds. - Weight::from_parts(2_258_000, 990) - // Standard Error: 32_695 - .saturating_add(Weight::from_parts(16_669_219, 0).saturating_mul(i.into())) + // Minimum execution time: 2_132_000 picoseconds. + Weight::from_parts(2_289_000, 990) + // Standard Error: 34_227 + .saturating_add(Weight::from_parts(17_006_583, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(i.into()))) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 3566).saturating_mul(i.into())) @@ -472,10 +476,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2196 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 84_275_000 picoseconds. - Weight::from_parts(92_512_416, 6248) - // Standard Error: 3_633 - .saturating_add(Weight::from_parts(1_315_923, 0).saturating_mul(s.into())) + // Minimum execution time: 85_308_000 picoseconds. + Weight::from_parts(93_689_468, 6248) + // Standard Error: 5_425 + .saturating_add(Weight::from_parts(1_307_604, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(13_u64)) .saturating_add(T::DbWeight::get().writes(12_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) @@ -488,10 +492,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `66672` // Estimated: `70137` - // Minimum execution time: 101_707_000 picoseconds. - Weight::from_parts(912_819_462, 70137) - // Standard Error: 57_547 - .saturating_add(Weight::from_parts(4_856_799, 0).saturating_mul(s.into())) + // Minimum execution time: 103_242_000 picoseconds. + Weight::from_parts(1_162_296_080, 70137) + // Standard Error: 76_741 + .saturating_add(Weight::from_parts(6_487_522, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -528,10 +532,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `33297 + n * (377 ±0)` // Estimated: `30944 + n * (3774 ±0)` - // Minimum execution time: 138_657_000 picoseconds. - Weight::from_parts(167_173_445, 30944) - // Standard Error: 25_130 - .saturating_add(Weight::from_parts(44_566_012, 0).saturating_mul(n.into())) + // Minimum execution time: 140_740_000 picoseconds. + Weight::from_parts(182_886_963, 30944) + // Standard Error: 39_852 + .saturating_add(Weight::from_parts(43_140_752, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(14_u64)) .saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) @@ -555,10 +559,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1991 + l * (7 ±0)` // Estimated: `8877` - // Minimum execution time: 80_061_000 picoseconds. - Weight::from_parts(82_836_434, 8877) - // Standard Error: 4_348 - .saturating_add(Weight::from_parts(75_744, 0).saturating_mul(l.into())) + // Minimum execution time: 80_372_000 picoseconds. + Weight::from_parts(83_335_027, 8877) + // Standard Error: 4_780 + .saturating_add(Weight::from_parts(72_180, 0).saturating_mul(l.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } @@ -593,10 +597,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2196 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 92_560_000 picoseconds. - Weight::from_parts(97_684_741, 6248) - // Standard Error: 3_361 - .saturating_add(Weight::from_parts(1_292_732, 0).saturating_mul(s.into())) + // Minimum execution time: 93_920_000 picoseconds. + Weight::from_parts(98_022_911, 6248) + // Standard Error: 4_096 + .saturating_add(Weight::from_parts(1_287_745, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(11_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) @@ -642,12 +646,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0 + n * (720 ±0) + v * (3598 ±0)` // Estimated: `512390 + n * (3566 ±0) + v * (3566 ±0)` - // Minimum execution time: 564_963_000 picoseconds. - Weight::from_parts(569_206_000, 512390) - // Standard Error: 2_033_235 - .saturating_add(Weight::from_parts(68_025_841, 0).saturating_mul(v.into())) - // Standard Error: 202_600 - .saturating_add(Weight::from_parts(17_916_770, 0).saturating_mul(n.into())) + // Minimum execution time: 556_012_000 picoseconds. + Weight::from_parts(560_339_000, 512390) + // Standard Error: 2_115_076 + .saturating_add(Weight::from_parts(69_456_497, 0).saturating_mul(v.into())) + // Standard Error: 210_755 + .saturating_add(Weight::from_parts(17_974_873, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(206_u64)) .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into()))) .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) @@ -678,12 +682,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `3175 + n * (911 ±0) + v * (395 ±0)` // Estimated: `512390 + n * (3566 ±0) + v * (3566 ±0)` - // Minimum execution time: 32_196_540_000 picoseconds. - Weight::from_parts(32_341_871_000, 512390) - // Standard Error: 354_657 - .saturating_add(Weight::from_parts(5_143_440, 0).saturating_mul(v.into())) - // Standard Error: 354_657 - .saturating_add(Weight::from_parts(3_328_189, 0).saturating_mul(n.into())) + // Minimum execution time: 32_792_819_000 picoseconds. + Weight::from_parts(32_986_606_000, 512390) + // Standard Error: 360_905 + .saturating_add(Weight::from_parts(5_260_151, 0).saturating_mul(v.into())) + // Standard Error: 360_905 + .saturating_add(Weight::from_parts(3_599_219, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(201_u64)) .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into()))) .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) @@ -700,10 +704,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `979 + v * (50 ±0)` // Estimated: `3510 + v * (2520 ±0)` - // Minimum execution time: 2_381_903_000 picoseconds. - Weight::from_parts(32_693_059, 3510) - // Standard Error: 10_000 - .saturating_add(Weight::from_parts(4_736_173, 0).saturating_mul(v.into())) + // Minimum execution time: 2_434_755_000 picoseconds. + Weight::from_parts(38_574_764, 3510) + // Standard Error: 14_467 + .saturating_add(Weight::from_parts(4_821_702, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into()))) .saturating_add(Weight::from_parts(0, 2520).saturating_mul(v.into())) @@ -714,6 +718,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::MinValidatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxValidatorsCount` (r:0 w:1) /// Proof: `Staking::MaxValidatorsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::MaxStakedRewards` (r:0 w:1) + /// Proof: `Staking::MaxStakedRewards` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) /// Storage: `Staking::ChillThreshold` (r:0 w:1) /// Proof: `Staking::ChillThreshold` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxNominatorsCount` (r:0 w:1) @@ -724,9 +730,9 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_434_000 picoseconds. - Weight::from_parts(5_742_000, 0) - .saturating_add(T::DbWeight::get().writes(6_u64)) + // Minimum execution time: 5_765_000 picoseconds. + Weight::from_parts(6_140_000, 0) + .saturating_add(T::DbWeight::get().writes(7_u64)) } /// Storage: `Staking::MinCommission` (r:0 w:1) /// Proof: `Staking::MinCommission` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -734,6 +740,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::MinValidatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxValidatorsCount` (r:0 w:1) /// Proof: `Staking::MaxValidatorsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::MaxStakedRewards` (r:0 w:1) + /// Proof: `Staking::MaxStakedRewards` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) /// Storage: `Staking::ChillThreshold` (r:0 w:1) /// Proof: `Staking::ChillThreshold` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxNominatorsCount` (r:0 w:1) @@ -744,9 +752,9 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_588_000 picoseconds. - Weight::from_parts(4_854_000, 0) - .saturating_add(T::DbWeight::get().writes(6_u64)) + // Minimum execution time: 5_025_000 picoseconds. + Weight::from_parts(5_354_000, 0) + .saturating_add(T::DbWeight::get().writes(7_u64)) } /// Storage: `Staking::Bonded` (r:1 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) @@ -774,8 +782,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1939` // Estimated: `6248` - // Minimum execution time: 68_780_000 picoseconds. - Weight::from_parts(71_479_000, 6248) + // Minimum execution time: 69_656_000 picoseconds. + Weight::from_parts(71_574_000, 6248) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -787,8 +795,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `691` // Estimated: `3510` - // Minimum execution time: 12_268_000 picoseconds. - Weight::from_parts(12_661_000, 3510) + // Minimum execution time: 12_523_000 picoseconds. + Weight::from_parts(13_315_000, 3510) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -798,8 +806,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_071_000 picoseconds. - Weight::from_parts(3_334_000, 0) + // Minimum execution time: 3_125_000 picoseconds. + Weight::from_parts(3_300_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } } @@ -820,8 +828,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `927` // Estimated: `4764` - // Minimum execution time: 42_042_000 picoseconds. - Weight::from_parts(43_292_000, 4764) + // Minimum execution time: 41_318_000 picoseconds. + Weight::from_parts(43_268_000, 4764) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -841,8 +849,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1990` // Estimated: `8877` - // Minimum execution time: 85_050_000 picoseconds. - Weight::from_parts(87_567_000, 8877) + // Minimum execution time: 85_666_000 picoseconds. + Weight::from_parts(88_749_000, 8877) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } @@ -868,8 +876,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2195` // Estimated: `8877` - // Minimum execution time: 89_076_000 picoseconds. - Weight::from_parts(92_715_000, 8877) + // Minimum execution time: 90_282_000 picoseconds. + Weight::from_parts(92_332_000, 8877) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } @@ -883,16 +891,18 @@ impl WeightInfo for () { /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:0) + /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_update(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1115` + // Measured: `1297` // Estimated: `4764` - // Minimum execution time: 42_067_000 picoseconds. - Weight::from_parts(43_239_807, 4764) - // Standard Error: 831 - .saturating_add(Weight::from_parts(46_257, 0).saturating_mul(s.into())) - .saturating_add(RocksDbWeight::get().reads(5_u64)) + // Minimum execution time: 44_626_000 picoseconds. + Weight::from_parts(47_254_657, 4764) + // Standard Error: 1_179 + .saturating_add(Weight::from_parts(57_657, 0).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Staking::Ledger` (r:1 w:1) @@ -928,10 +938,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2196 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 86_490_000 picoseconds. - Weight::from_parts(95_358_751, 6248) - // Standard Error: 3_952 - .saturating_add(Weight::from_parts(1_294_907, 0).saturating_mul(s.into())) + // Minimum execution time: 86_769_000 picoseconds. + Weight::from_parts(95_212_867, 6248) + // Standard Error: 3_706 + .saturating_add(Weight::from_parts(1_320_752, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(13_u64)) .saturating_add(RocksDbWeight::get().writes(11_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) @@ -963,8 +973,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1372` // Estimated: `4556` - // Minimum execution time: 50_326_000 picoseconds. - Weight::from_parts(52_253_000, 4556) + // Minimum execution time: 50_410_000 picoseconds. + Weight::from_parts(52_576_000, 4556) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } @@ -977,10 +987,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1280 + k * (569 ±0)` // Estimated: `4556 + k * (3033 ±0)` - // Minimum execution time: 29_305_000 picoseconds. - Weight::from_parts(32_199_604, 4556) - // Standard Error: 7_150 - .saturating_add(Weight::from_parts(6_437_124, 0).saturating_mul(k.into())) + // Minimum execution time: 29_017_000 picoseconds. + Weight::from_parts(33_019_206, 4556) + // Standard Error: 6_368 + .saturating_add(Weight::from_parts(6_158_681, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(k.into()))) @@ -1013,10 +1023,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1866 + n * (102 ±0)` // Estimated: `6248 + n * (2520 ±0)` - // Minimum execution time: 63_267_000 picoseconds. - Weight::from_parts(61_741_404, 6248) - // Standard Error: 12_955 - .saturating_add(Weight::from_parts(3_811_743, 0).saturating_mul(n.into())) + // Minimum execution time: 63_452_000 picoseconds. + Weight::from_parts(60_924_066, 6248) + // Standard Error: 14_416 + .saturating_add(Weight::from_parts(3_921_589, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes(6_u64)) @@ -1040,8 +1050,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1650` // Estimated: `6248` - // Minimum execution time: 52_862_000 picoseconds. - Weight::from_parts(54_108_000, 6248) + // Minimum execution time: 54_253_000 picoseconds. + Weight::from_parts(55_286_000, 6248) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -1055,8 +1065,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `902` // Estimated: `4556` - // Minimum execution time: 16_350_000 picoseconds. - Weight::from_parts(16_802_000, 4556) + // Minimum execution time: 16_812_000 picoseconds. + Weight::from_parts(17_380_000, 4556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1070,8 +1080,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `969` // Estimated: `4556` - // Minimum execution time: 19_981_000 picoseconds. - Weight::from_parts(20_539_000, 4556) + // Minimum execution time: 20_590_000 picoseconds. + Weight::from_parts(21_096_000, 4556) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1083,8 +1093,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `902` // Estimated: `4556` - // Minimum execution time: 19_304_000 picoseconds. - Weight::from_parts(20_000_000, 4556) + // Minimum execution time: 19_923_000 picoseconds. + Weight::from_parts(20_880_000, 4556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -1094,8 +1104,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_568_000 picoseconds. - Weight::from_parts(2_708_000, 0) + // Minimum execution time: 2_599_000 picoseconds. + Weight::from_parts(2_751_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -1104,8 +1114,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_950_000 picoseconds. - Weight::from_parts(8_348_000, 0) + // Minimum execution time: 6_941_000 picoseconds. + Weight::from_parts(7_288_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -1114,8 +1124,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_967_000 picoseconds. - Weight::from_parts(8_222_000, 0) + // Minimum execution time: 6_757_000 picoseconds. + Weight::from_parts(7_200_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -1124,8 +1134,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_006_000 picoseconds. - Weight::from_parts(8_440_000, 0) + // Minimum execution time: 7_028_000 picoseconds. + Weight::from_parts(7_366_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::Invulnerables` (r:0 w:1) @@ -1135,10 +1145,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_524_000 picoseconds. - Weight::from_parts(3_123_608, 0) - // Standard Error: 59 - .saturating_add(Weight::from_parts(11_596, 0).saturating_mul(v.into())) + // Minimum execution time: 2_741_000 picoseconds. + Weight::from_parts(3_212_598, 0) + // Standard Error: 68 + .saturating_add(Weight::from_parts(11_695, 0).saturating_mul(v.into())) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::Ledger` (r:5900 w:11800) @@ -1152,10 +1162,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1356 + i * (151 ±0)` // Estimated: `990 + i * (3566 ±0)` - // Minimum execution time: 2_092_000 picoseconds. - Weight::from_parts(2_258_000, 990) - // Standard Error: 32_695 - .saturating_add(Weight::from_parts(16_669_219, 0).saturating_mul(i.into())) + // Minimum execution time: 2_132_000 picoseconds. + Weight::from_parts(2_289_000, 990) + // Standard Error: 34_227 + .saturating_add(Weight::from_parts(17_006_583, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(i.into()))) .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 3566).saturating_mul(i.into())) @@ -1193,10 +1203,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2196 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 84_275_000 picoseconds. - Weight::from_parts(92_512_416, 6248) - // Standard Error: 3_633 - .saturating_add(Weight::from_parts(1_315_923, 0).saturating_mul(s.into())) + // Minimum execution time: 85_308_000 picoseconds. + Weight::from_parts(93_689_468, 6248) + // Standard Error: 5_425 + .saturating_add(Weight::from_parts(1_307_604, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(13_u64)) .saturating_add(RocksDbWeight::get().writes(12_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) @@ -1209,10 +1219,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `66672` // Estimated: `70137` - // Minimum execution time: 101_707_000 picoseconds. - Weight::from_parts(912_819_462, 70137) - // Standard Error: 57_547 - .saturating_add(Weight::from_parts(4_856_799, 0).saturating_mul(s.into())) + // Minimum execution time: 103_242_000 picoseconds. + Weight::from_parts(1_162_296_080, 70137) + // Standard Error: 76_741 + .saturating_add(Weight::from_parts(6_487_522, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1249,10 +1259,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `33297 + n * (377 ±0)` // Estimated: `30944 + n * (3774 ±0)` - // Minimum execution time: 138_657_000 picoseconds. - Weight::from_parts(167_173_445, 30944) - // Standard Error: 25_130 - .saturating_add(Weight::from_parts(44_566_012, 0).saturating_mul(n.into())) + // Minimum execution time: 140_740_000 picoseconds. + Weight::from_parts(182_886_963, 30944) + // Standard Error: 39_852 + .saturating_add(Weight::from_parts(43_140_752, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(14_u64)) .saturating_add(RocksDbWeight::get().reads((6_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) @@ -1276,10 +1286,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1991 + l * (7 ±0)` // Estimated: `8877` - // Minimum execution time: 80_061_000 picoseconds. - Weight::from_parts(82_836_434, 8877) - // Standard Error: 4_348 - .saturating_add(Weight::from_parts(75_744, 0).saturating_mul(l.into())) + // Minimum execution time: 80_372_000 picoseconds. + Weight::from_parts(83_335_027, 8877) + // Standard Error: 4_780 + .saturating_add(Weight::from_parts(72_180, 0).saturating_mul(l.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } @@ -1314,10 +1324,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2196 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 92_560_000 picoseconds. - Weight::from_parts(97_684_741, 6248) - // Standard Error: 3_361 - .saturating_add(Weight::from_parts(1_292_732, 0).saturating_mul(s.into())) + // Minimum execution time: 93_920_000 picoseconds. + Weight::from_parts(98_022_911, 6248) + // Standard Error: 4_096 + .saturating_add(Weight::from_parts(1_287_745, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(11_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) @@ -1363,12 +1373,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0 + n * (720 ±0) + v * (3598 ±0)` // Estimated: `512390 + n * (3566 ±0) + v * (3566 ±0)` - // Minimum execution time: 564_963_000 picoseconds. - Weight::from_parts(569_206_000, 512390) - // Standard Error: 2_033_235 - .saturating_add(Weight::from_parts(68_025_841, 0).saturating_mul(v.into())) - // Standard Error: 202_600 - .saturating_add(Weight::from_parts(17_916_770, 0).saturating_mul(n.into())) + // Minimum execution time: 556_012_000 picoseconds. + Weight::from_parts(560_339_000, 512390) + // Standard Error: 2_115_076 + .saturating_add(Weight::from_parts(69_456_497, 0).saturating_mul(v.into())) + // Standard Error: 210_755 + .saturating_add(Weight::from_parts(17_974_873, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(206_u64)) .saturating_add(RocksDbWeight::get().reads((5_u64).saturating_mul(v.into()))) .saturating_add(RocksDbWeight::get().reads((4_u64).saturating_mul(n.into()))) @@ -1399,12 +1409,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `3175 + n * (911 ±0) + v * (395 ±0)` // Estimated: `512390 + n * (3566 ±0) + v * (3566 ±0)` - // Minimum execution time: 32_196_540_000 picoseconds. - Weight::from_parts(32_341_871_000, 512390) - // Standard Error: 354_657 - .saturating_add(Weight::from_parts(5_143_440, 0).saturating_mul(v.into())) - // Standard Error: 354_657 - .saturating_add(Weight::from_parts(3_328_189, 0).saturating_mul(n.into())) + // Minimum execution time: 32_792_819_000 picoseconds. + Weight::from_parts(32_986_606_000, 512390) + // Standard Error: 360_905 + .saturating_add(Weight::from_parts(5_260_151, 0).saturating_mul(v.into())) + // Standard Error: 360_905 + .saturating_add(Weight::from_parts(3_599_219, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(201_u64)) .saturating_add(RocksDbWeight::get().reads((5_u64).saturating_mul(v.into()))) .saturating_add(RocksDbWeight::get().reads((4_u64).saturating_mul(n.into()))) @@ -1421,10 +1431,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `979 + v * (50 ±0)` // Estimated: `3510 + v * (2520 ±0)` - // Minimum execution time: 2_381_903_000 picoseconds. - Weight::from_parts(32_693_059, 3510) - // Standard Error: 10_000 - .saturating_add(Weight::from_parts(4_736_173, 0).saturating_mul(v.into())) + // Minimum execution time: 2_434_755_000 picoseconds. + Weight::from_parts(38_574_764, 3510) + // Standard Error: 14_467 + .saturating_add(Weight::from_parts(4_821_702, 0).saturating_mul(v.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(v.into()))) .saturating_add(Weight::from_parts(0, 2520).saturating_mul(v.into())) @@ -1435,6 +1445,8 @@ impl WeightInfo for () { /// Proof: `Staking::MinValidatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxValidatorsCount` (r:0 w:1) /// Proof: `Staking::MaxValidatorsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::MaxStakedRewards` (r:0 w:1) + /// Proof: `Staking::MaxStakedRewards` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) /// Storage: `Staking::ChillThreshold` (r:0 w:1) /// Proof: `Staking::ChillThreshold` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxNominatorsCount` (r:0 w:1) @@ -1445,9 +1457,9 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_434_000 picoseconds. - Weight::from_parts(5_742_000, 0) - .saturating_add(RocksDbWeight::get().writes(6_u64)) + // Minimum execution time: 5_765_000 picoseconds. + Weight::from_parts(6_140_000, 0) + .saturating_add(RocksDbWeight::get().writes(7_u64)) } /// Storage: `Staking::MinCommission` (r:0 w:1) /// Proof: `Staking::MinCommission` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -1455,6 +1467,8 @@ impl WeightInfo for () { /// Proof: `Staking::MinValidatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxValidatorsCount` (r:0 w:1) /// Proof: `Staking::MaxValidatorsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Staking::MaxStakedRewards` (r:0 w:1) + /// Proof: `Staking::MaxStakedRewards` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) /// Storage: `Staking::ChillThreshold` (r:0 w:1) /// Proof: `Staking::ChillThreshold` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxNominatorsCount` (r:0 w:1) @@ -1465,9 +1479,9 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_588_000 picoseconds. - Weight::from_parts(4_854_000, 0) - .saturating_add(RocksDbWeight::get().writes(6_u64)) + // Minimum execution time: 5_025_000 picoseconds. + Weight::from_parts(5_354_000, 0) + .saturating_add(RocksDbWeight::get().writes(7_u64)) } /// Storage: `Staking::Bonded` (r:1 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) @@ -1495,8 +1509,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1939` // Estimated: `6248` - // Minimum execution time: 68_780_000 picoseconds. - Weight::from_parts(71_479_000, 6248) + // Minimum execution time: 69_656_000 picoseconds. + Weight::from_parts(71_574_000, 6248) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -1508,8 +1522,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `691` // Estimated: `3510` - // Minimum execution time: 12_268_000 picoseconds. - Weight::from_parts(12_661_000, 3510) + // Minimum execution time: 12_523_000 picoseconds. + Weight::from_parts(13_315_000, 3510) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1519,8 +1533,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_071_000 picoseconds. - Weight::from_parts(3_334_000, 0) + // Minimum execution time: 3_125_000 picoseconds. + Weight::from_parts(3_300_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } } diff --git a/substrate/frame/state-trie-migration/src/lib.rs b/substrate/frame/state-trie-migration/src/lib.rs index 6b3aa9934e0..b89159ef3ec 100644 --- a/substrate/frame/state-trie-migration/src/lib.rs +++ b/substrate/frame/state-trie-migration/src/lib.rs @@ -1801,7 +1801,7 @@ mod remote_tests_local { use std::env::var as env_var; // we only use the hash type from this, so using the mock should be fine. - type Extrinsic = sp_runtime::testing::TestXt; + type Extrinsic = sp_runtime::generic::UncheckedExtrinsic; type Block = sp_runtime::testing::Block; #[tokio::test] diff --git a/substrate/frame/state-trie-migration/src/weights.rs b/substrate/frame/state-trie-migration/src/weights.rs index 8fa80b38957..23dad9e3380 100644 --- a/substrate/frame/state-trie-migration/src/weights.rs +++ b/substrate/frame/state-trie-migration/src/weights.rs @@ -17,26 +17,28 @@ //! Autogenerated weights for `pallet_state_trie_migration` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-01-24, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-grjcggob-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// target/production/substrate-node +// ./target/production/substrate-node // benchmark // pallet +// --chain=dev // --steps=50 // --repeat=20 +// --pallet=pallet_state_trie_migration +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_state_trie_migration -// --chain=dev -// --header=./substrate/HEADER-APACHE2 // --output=./substrate/frame/state-trie-migration/src/weights.rs +// --header=./substrate/HEADER-APACHE2 // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -64,15 +66,15 @@ impl WeightInfo for SubstrateWeight { /// Storage: `StateTrieMigration::SignedMigrationMaxLimits` (r:1 w:0) /// Proof: `StateTrieMigration::SignedMigrationMaxLimits` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) /// Storage: `StateTrieMigration::MigrationProcess` (r:1 w:1) /// Proof: `StateTrieMigration::MigrationProcess` (`max_values`: Some(1), `max_size`: Some(1042), added: 1537, mode: `MaxEncodedLen`) fn continue_migrate() -> Weight { // Proof Size summary in bytes: // Measured: `108` - // Estimated: `3640` - // Minimum execution time: 18_520_000 picoseconds. - Weight::from_parts(19_171_000, 3640) + // Estimated: `3658` + // Minimum execution time: 17_661_000 picoseconds. + Weight::from_parts(18_077_000, 3658) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -82,53 +84,53 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `1493` - // Minimum execution time: 3_786_000 picoseconds. - Weight::from_parts(4_038_000, 1493) + // Minimum execution time: 4_036_000 picoseconds. + Weight::from_parts(4_267_000, 1493) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) fn migrate_custom_top_success() -> Weight { // Proof Size summary in bytes: // Measured: `0` - // Estimated: `3640` - // Minimum execution time: 11_144_000 picoseconds. - Weight::from_parts(11_556_000, 3640) + // Estimated: `3658` + // Minimum execution time: 11_348_000 picoseconds. + Weight::from_parts(11_899_000, 3658) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) /// Storage: UNKNOWN KEY `0x666f6f` (r:1 w:1) /// Proof: UNKNOWN KEY `0x666f6f` (r:1 w:1) fn migrate_custom_top_fail() -> Weight { // Proof Size summary in bytes: // Measured: `113` - // Estimated: `3640` - // Minimum execution time: 59_288_000 picoseconds. - Weight::from_parts(60_276_000, 3640) + // Estimated: `3658` + // Minimum execution time: 59_819_000 picoseconds. + Weight::from_parts(61_066_000, 3658) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) fn migrate_custom_child_success() -> Weight { // Proof Size summary in bytes: // Measured: `0` - // Estimated: `3640` - // Minimum execution time: 11_258_000 picoseconds. - Weight::from_parts(11_626_000, 3640) + // Estimated: `3658` + // Minimum execution time: 11_424_000 picoseconds. + Weight::from_parts(11_765_000, 3658) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) /// Storage: UNKNOWN KEY `0x666f6f` (r:1 w:1) /// Proof: UNKNOWN KEY `0x666f6f` (r:1 w:1) fn migrate_custom_child_fail() -> Weight { // Proof Size summary in bytes: // Measured: `106` - // Estimated: `3640` - // Minimum execution time: 61_575_000 picoseconds. - Weight::from_parts(63_454_000, 3640) + // Estimated: `3658` + // Minimum execution time: 61_086_000 picoseconds. + Weight::from_parts(62_546_000, 3658) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -139,10 +141,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `197 + v * (1 ±0)` // Estimated: `3662 + v * (1 ±0)` - // Minimum execution time: 5_259_000 picoseconds. - Weight::from_parts(5_433_000, 3662) + // Minimum execution time: 5_375_000 picoseconds. + Weight::from_parts(5_552_000, 3662) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_159, 0).saturating_mul(v.into())) + .saturating_add(Weight::from_parts(1_146, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(v.into())) @@ -154,15 +156,15 @@ impl WeightInfo for () { /// Storage: `StateTrieMigration::SignedMigrationMaxLimits` (r:1 w:0) /// Proof: `StateTrieMigration::SignedMigrationMaxLimits` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) /// Storage: `StateTrieMigration::MigrationProcess` (r:1 w:1) /// Proof: `StateTrieMigration::MigrationProcess` (`max_values`: Some(1), `max_size`: Some(1042), added: 1537, mode: `MaxEncodedLen`) fn continue_migrate() -> Weight { // Proof Size summary in bytes: // Measured: `108` - // Estimated: `3640` - // Minimum execution time: 18_520_000 picoseconds. - Weight::from_parts(19_171_000, 3640) + // Estimated: `3658` + // Minimum execution time: 17_661_000 picoseconds. + Weight::from_parts(18_077_000, 3658) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -172,53 +174,53 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `76` // Estimated: `1493` - // Minimum execution time: 3_786_000 picoseconds. - Weight::from_parts(4_038_000, 1493) + // Minimum execution time: 4_036_000 picoseconds. + Weight::from_parts(4_267_000, 1493) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) fn migrate_custom_top_success() -> Weight { // Proof Size summary in bytes: // Measured: `0` - // Estimated: `3640` - // Minimum execution time: 11_144_000 picoseconds. - Weight::from_parts(11_556_000, 3640) + // Estimated: `3658` + // Minimum execution time: 11_348_000 picoseconds. + Weight::from_parts(11_899_000, 3658) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) /// Storage: UNKNOWN KEY `0x666f6f` (r:1 w:1) /// Proof: UNKNOWN KEY `0x666f6f` (r:1 w:1) fn migrate_custom_top_fail() -> Weight { // Proof Size summary in bytes: // Measured: `113` - // Estimated: `3640` - // Minimum execution time: 59_288_000 picoseconds. - Weight::from_parts(60_276_000, 3640) + // Estimated: `3658` + // Minimum execution time: 59_819_000 picoseconds. + Weight::from_parts(61_066_000, 3658) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) fn migrate_custom_child_success() -> Weight { // Proof Size summary in bytes: // Measured: `0` - // Estimated: `3640` - // Minimum execution time: 11_258_000 picoseconds. - Weight::from_parts(11_626_000, 3640) + // Estimated: `3658` + // Minimum execution time: 11_424_000 picoseconds. + Weight::from_parts(11_765_000, 3658) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) /// Storage: UNKNOWN KEY `0x666f6f` (r:1 w:1) /// Proof: UNKNOWN KEY `0x666f6f` (r:1 w:1) fn migrate_custom_child_fail() -> Weight { // Proof Size summary in bytes: // Measured: `106` - // Estimated: `3640` - // Minimum execution time: 61_575_000 picoseconds. - Weight::from_parts(63_454_000, 3640) + // Estimated: `3658` + // Minimum execution time: 61_086_000 picoseconds. + Weight::from_parts(62_546_000, 3658) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -229,10 +231,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `197 + v * (1 ±0)` // Estimated: `3662 + v * (1 ±0)` - // Minimum execution time: 5_259_000 picoseconds. - Weight::from_parts(5_433_000, 3662) + // Minimum execution time: 5_375_000 picoseconds. + Weight::from_parts(5_552_000, 3662) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_159, 0).saturating_mul(v.into())) + .saturating_add(Weight::from_parts(1_146, 0).saturating_mul(v.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(v.into())) diff --git a/substrate/frame/sudo/src/benchmarking.rs b/substrate/frame/sudo/src/benchmarking.rs index e64233fe748..cdd7d707600 100644 --- a/substrate/frame/sudo/src/benchmarking.rs +++ b/substrate/frame/sudo/src/benchmarking.rs @@ -20,14 +20,23 @@ use super::*; use crate::Pallet; use frame_benchmarking::v2::*; +use frame_support::dispatch::DispatchInfo; use frame_system::RawOrigin; +use sp_runtime::traits::{AsSystemOriginSigner, DispatchTransaction, Dispatchable}; fn assert_last_event(generic_event: crate::Event) { let re: ::RuntimeEvent = generic_event.into(); frame_system::Pallet::::assert_last_event(re.into()); } -#[benchmarks(where ::RuntimeCall: From>)] +#[benchmarks(where + T: Send + Sync, + ::RuntimeCall: From>, + ::RuntimeCall: Dispatchable, + <::RuntimeCall as Dispatchable>::PostInfo: From<()>, + <::RuntimeCall as Dispatchable>::RuntimeOrigin: + AsSystemOriginSigner + Clone, +)] mod benchmarks { use super::*; @@ -85,5 +94,23 @@ mod benchmarks { assert_last_event::(Event::KeyRemoved {}); } + #[benchmark] + fn check_only_sudo_account() { + let caller: T::AccountId = whitelisted_caller(); + Key::::put(&caller); + + let call = frame_system::Call::remark { remark: vec![] }.into(); + let info = DispatchInfo { ..Default::default() }; + let ext = CheckOnlySudoAccount::::new(); + + #[block] + { + assert!(ext + .test_run(RawOrigin::Signed(caller).into(), &call, &info, 0, |_| Ok(().into())) + .unwrap() + .is_ok()); + } + } + impl_benchmark_test_suite!(Pallet, crate::mock::new_bench_ext(), crate::mock::Test); } diff --git a/substrate/frame/sudo/src/extension.rs b/substrate/frame/sudo/src/extension.rs index e90286e5a7c..2cd8f945edd 100644 --- a/substrate/frame/sudo/src/extension.rs +++ b/substrate/frame/sudo/src/extension.rs @@ -20,10 +20,14 @@ use codec::{Decode, Encode}; use frame_support::{dispatch::DispatchInfo, ensure}; use scale_info::TypeInfo; use sp_runtime::{ - traits::{DispatchInfoOf, Dispatchable, SignedExtension}, + impl_tx_ext_default, + traits::{ + AsSystemOriginSigner, DispatchInfoOf, Dispatchable, TransactionExtension, + TransactionExtensionBase, + }, transaction_validity::{ - InvalidTransaction, TransactionPriority, TransactionValidity, TransactionValidityError, - UnknownTransaction, ValidTransaction, + InvalidTransaction, TransactionPriority, TransactionValidityError, UnknownTransaction, + ValidTransaction, }, }; use sp_std::{fmt, marker::PhantomData}; @@ -59,49 +63,61 @@ impl fmt::Debug for CheckOnlySudoAccount { } impl CheckOnlySudoAccount { - /// Creates new `SignedExtension` to check sudo key. + /// Creates new `TransactionExtension` to check sudo key. pub fn new() -> Self { Self::default() } } -impl SignedExtension for CheckOnlySudoAccount -where - ::RuntimeCall: Dispatchable, -{ +impl TransactionExtensionBase for CheckOnlySudoAccount { const IDENTIFIER: &'static str = "CheckOnlySudoAccount"; - type AccountId = T::AccountId; - type Call = ::RuntimeCall; - type AdditionalSigned = (); - type Pre = (); + type Implicit = (); - fn additional_signed(&self) -> Result { - Ok(()) + fn weight(&self) -> frame_support::weights::Weight { + use crate::weights::WeightInfo; + T::WeightInfo::check_only_sudo_account() } +} +impl + TransactionExtension<::RuntimeCall, Context> for CheckOnlySudoAccount +where + ::RuntimeCall: Dispatchable, + <::RuntimeCall as Dispatchable>::RuntimeOrigin: + AsSystemOriginSigner + Clone, +{ + type Pre = (); + type Val = (); fn validate( &self, - who: &Self::AccountId, - _call: &Self::Call, - info: &DispatchInfoOf, + origin: <::RuntimeCall as Dispatchable>::RuntimeOrigin, + _call: &::RuntimeCall, + info: &DispatchInfoOf<::RuntimeCall>, _len: usize, - ) -> TransactionValidity { + _context: &mut Context, + _self_implicit: Self::Implicit, + _inherited_implication: &impl Encode, + ) -> Result< + ( + ValidTransaction, + Self::Val, + <::RuntimeCall as Dispatchable>::RuntimeOrigin, + ), + TransactionValidityError, + > { + let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?; let sudo_key: T::AccountId = Key::::get().ok_or(UnknownTransaction::CannotLookup)?; ensure!(*who == sudo_key, InvalidTransaction::BadSigner); - Ok(ValidTransaction { - priority: info.weight.ref_time() as TransactionPriority, - ..Default::default() - }) + Ok(( + ValidTransaction { + priority: info.weight.ref_time() as TransactionPriority, + ..Default::default() + }, + (), + origin, + )) } - fn pre_dispatch( - self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> Result { - self.validate(who, call, info, len).map(|_| ()) - } + impl_tx_ext_default!(::RuntimeCall; Context; prepare); } diff --git a/substrate/frame/sudo/src/lib.rs b/substrate/frame/sudo/src/lib.rs index 2ebe4cb0157..2c953368b22 100644 --- a/substrate/frame/sudo/src/lib.rs +++ b/substrate/frame/sudo/src/lib.rs @@ -85,8 +85,8 @@ //! meant to be used by constructing runtime calls from outside the runtime. //! //! -//! This pallet also defines a [`SignedExtension`](sp_runtime::traits::SignedExtension) called -//! [`CheckOnlySudoAccount`] to ensure that only signed transactions by the sudo account are +//! This pallet also defines a [`TransactionExtension`](sp_runtime::traits::TransactionExtension) +//! called [`CheckOnlySudoAccount`] to ensure that only signed transactions by the sudo account are //! accepted by the transaction pool. The intended use of this signed extension is to prevent other //! accounts from spamming the transaction pool for the initial phase of a chain, during which //! developers may only want a sudo account to be able to make transactions. diff --git a/substrate/frame/sudo/src/weights.rs b/substrate/frame/sudo/src/weights.rs index 10d1a9f7a51..aa8f69fd4e6 100644 --- a/substrate/frame/sudo/src/weights.rs +++ b/substrate/frame/sudo/src/weights.rs @@ -17,26 +17,28 @@ //! Autogenerated weights for `pallet_sudo` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// target/production/substrate-node +// ./target/production/substrate-node // benchmark // pallet +// --chain=dev // --steps=50 // --repeat=20 +// --pallet=pallet_sudo +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_sudo -// --chain=dev -// --header=./substrate/HEADER-APACHE2 // --output=./substrate/frame/sudo/src/weights.rs +// --header=./substrate/HEADER-APACHE2 // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -53,6 +55,7 @@ pub trait WeightInfo { fn sudo() -> Weight; fn sudo_as() -> Weight; fn remove_key() -> Weight; + fn check_only_sudo_account() -> Weight; } /// Weights for `pallet_sudo` using the Substrate node and recommended hardware. @@ -64,8 +67,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `165` // Estimated: `1517` - // Minimum execution time: 9_600_000 picoseconds. - Weight::from_parts(10_076_000, 1517) + // Minimum execution time: 9_590_000 picoseconds. + Weight::from_parts(9_924_000, 1517) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -75,8 +78,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `165` // Estimated: `1517` - // Minimum execution time: 10_453_000 picoseconds. - Weight::from_parts(10_931_000, 1517) + // Minimum execution time: 9_825_000 picoseconds. + Weight::from_parts(10_373_000, 1517) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Sudo::Key` (r:1 w:0) @@ -85,8 +88,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `165` // Estimated: `1517` - // Minimum execution time: 10_202_000 picoseconds. - Weight::from_parts(10_800_000, 1517) + // Minimum execution time: 10_140_000 picoseconds. + Weight::from_parts(10_382_000, 1517) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Sudo::Key` (r:1 w:1) @@ -95,11 +98,21 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `165` // Estimated: `1517` - // Minimum execution time: 8_555_000 picoseconds. - Weight::from_parts(8_846_000, 1517) + // Minimum execution time: 8_610_000 picoseconds. + Weight::from_parts(8_975_000, 1517) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } + /// Storage: `Sudo::Key` (r:1 w:0) + /// Proof: `Sudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + fn check_only_sudo_account() -> Weight { + // Proof Size summary in bytes: + // Measured: `165` + // Estimated: `1517` + // Minimum execution time: 3_416_000 picoseconds. + Weight::from_parts(3_645_000, 1517) + .saturating_add(T::DbWeight::get().reads(1_u64)) + } } // For backwards compatibility and tests. @@ -110,8 +123,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `165` // Estimated: `1517` - // Minimum execution time: 9_600_000 picoseconds. - Weight::from_parts(10_076_000, 1517) + // Minimum execution time: 9_590_000 picoseconds. + Weight::from_parts(9_924_000, 1517) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -121,8 +134,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `165` // Estimated: `1517` - // Minimum execution time: 10_453_000 picoseconds. - Weight::from_parts(10_931_000, 1517) + // Minimum execution time: 9_825_000 picoseconds. + Weight::from_parts(10_373_000, 1517) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Sudo::Key` (r:1 w:0) @@ -131,8 +144,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `165` // Estimated: `1517` - // Minimum execution time: 10_202_000 picoseconds. - Weight::from_parts(10_800_000, 1517) + // Minimum execution time: 10_140_000 picoseconds. + Weight::from_parts(10_382_000, 1517) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Sudo::Key` (r:1 w:1) @@ -141,9 +154,19 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `165` // Estimated: `1517` - // Minimum execution time: 8_555_000 picoseconds. - Weight::from_parts(8_846_000, 1517) + // Minimum execution time: 8_610_000 picoseconds. + Weight::from_parts(8_975_000, 1517) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } + /// Storage: `Sudo::Key` (r:1 w:0) + /// Proof: `Sudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + fn check_only_sudo_account() -> Weight { + // Proof Size summary in bytes: + // Measured: `165` + // Estimated: `1517` + // Minimum execution time: 3_416_000 picoseconds. + Weight::from_parts(3_645_000, 1517) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + } } diff --git a/substrate/frame/support/Cargo.toml b/substrate/frame/support/Cargo.toml index fb9cb3d4511..113af41751e 100644 --- a/substrate/frame/support/Cargo.toml +++ b/substrate/frame/support/Cargo.toml @@ -95,9 +95,9 @@ std = [ "sp-staking/std", "sp-state-machine/std", "sp-std/std", + "sp-timestamp/std", "sp-tracing/std", "sp-weights/std", - "sp-timestamp/std" ] runtime-benchmarks = [ "frame-system/runtime-benchmarks", diff --git a/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs b/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs index da483fa6cf0..d21cfef4a92 100644 --- a/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs +++ b/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs @@ -73,11 +73,9 @@ pub fn expand_outer_inherent( #( #pallet_attrs if let Some(inherent) = #pallet_names::create_inherent(self) { - let inherent = <#unchecked_extrinsic as #scrate::sp_runtime::traits::Extrinsic>::new( + let inherent = <#unchecked_extrinsic as #scrate::sp_runtime::traits::Extrinsic>::new_inherent( inherent.into(), - None, - ).expect("Runtime UncheckedExtrinsic is not Opaque, so it has to return \ - `Some`; qed"); + ); inherents.push(inherent); } @@ -123,7 +121,7 @@ pub fn expand_outer_inherent( for xt in block.extrinsics() { // Inherents are before any other extrinsics. // And signed extrinsics are not inherents. - if #scrate::sp_runtime::traits::Extrinsic::is_signed(xt).unwrap_or(false) { + if !(#scrate::sp_runtime::traits::Extrinsic::is_bare(xt)) { break } @@ -161,10 +159,9 @@ pub fn expand_outer_inherent( match #pallet_names::is_inherent_required(self) { Ok(Some(e)) => { let found = block.extrinsics().iter().any(|xt| { - let is_signed = #scrate::sp_runtime::traits::Extrinsic::is_signed(xt) - .unwrap_or(false); + let is_bare = #scrate::sp_runtime::traits::Extrinsic::is_bare(xt); - if !is_signed { + if is_bare { let call = < #unchecked_extrinsic as ExtrinsicCall >::call(xt); @@ -209,8 +206,9 @@ pub fn expand_outer_inherent( use #scrate::inherent::ProvideInherent; use #scrate::traits::{IsSubType, ExtrinsicCall}; - if #scrate::sp_runtime::traits::Extrinsic::is_signed(ext).unwrap_or(false) { - // Signed extrinsics are never inherents. + let is_bare = #scrate::sp_runtime::traits::Extrinsic::is_bare(ext); + if !is_bare { + // Signed extrinsics are not inherents. return false } diff --git a/substrate/frame/support/procedural/src/construct_runtime/expand/metadata.rs b/substrate/frame/support/procedural/src/construct_runtime/expand/metadata.rs index 0e76f9a9246..f55ca677d89 100644 --- a/substrate/frame/support/procedural/src/construct_runtime/expand/metadata.rs +++ b/substrate/frame/support/procedural/src/construct_runtime/expand/metadata.rs @@ -119,13 +119,13 @@ pub fn expand_runtime_metadata( call_ty, signature_ty, extra_ty, - signed_extensions: < + extensions: < < #extrinsic as #scrate::sp_runtime::traits::ExtrinsicMetadata - >::SignedExtensions as #scrate::sp_runtime::traits::SignedExtension + >::Extra as #scrate::sp_runtime::traits::TransactionExtensionBase >::metadata() .into_iter() - .map(|meta| #scrate::__private::metadata_ir::SignedExtensionMetadataIR { + .map(|meta| #scrate::__private::metadata_ir::TransactionExtensionMetadataIR { identifier: meta.identifier, ty: meta.ty, additional_signed: meta.additional_signed, diff --git a/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs b/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs index 83049919d01..341621deb09 100644 --- a/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs +++ b/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs @@ -153,6 +153,10 @@ pub fn expand_outer_origin( self.filter = #scrate::__private::sp_std::rc::Rc::new(Box::new(filter)); } + fn set_caller(&mut self, caller: OriginCaller) { + self.caller = caller; + } + fn set_caller_from(&mut self, other: impl Into) { self.caller = other.into().caller; } @@ -301,6 +305,16 @@ pub fn expand_outer_origin( } } + impl #scrate::__private::AsSystemOriginSigner<<#runtime as #system_path::Config>::AccountId> for RuntimeOrigin { + fn as_system_origin_signer(&self) -> Option<&<#runtime as #system_path::Config>::AccountId> { + if let OriginCaller::system(#system_path::Origin::<#runtime>::Signed(ref signed)) = &self.caller { + Some(signed) + } else { + None + } + } + } + #pallet_conversions }) } diff --git a/substrate/frame/support/src/dispatch.rs b/substrate/frame/support/src/dispatch.rs index 4a313551aca..61787a74012 100644 --- a/substrate/frame/support/src/dispatch.rs +++ b/substrate/frame/support/src/dispatch.rs @@ -25,7 +25,7 @@ use scale_info::TypeInfo; use serde::{Deserialize, Serialize}; use sp_runtime::{ generic::{CheckedExtrinsic, UncheckedExtrinsic}, - traits::SignedExtension, + traits::Dispatchable, DispatchError, RuntimeDebug, }; use sp_std::fmt; @@ -268,7 +268,8 @@ pub fn extract_actual_weight(result: &DispatchResultWithPostInfo, info: &Dispatc .calc_actual_weight(info) } -/// Extract the actual pays_fee from a dispatch result if any or fall back to the default weight. +/// Extract the actual pays_fee from a dispatch result if any or fall back to the default +/// weight. pub fn extract_actual_pays_fee(result: &DispatchResultWithPostInfo, info: &DispatchInfo) -> Pays { match result { Ok(post_info) => post_info, @@ -368,11 +369,10 @@ where } /// Implementation for unchecked extrinsic. -impl GetDispatchInfo - for UncheckedExtrinsic +impl GetDispatchInfo + for UncheckedExtrinsic where - Call: GetDispatchInfo, - Extra: SignedExtension, + Call: GetDispatchInfo + Dispatchable, { fn get_dispatch_info(&self) -> DispatchInfo { self.function.get_dispatch_info() @@ -380,7 +380,7 @@ where } /// Implementation for checked extrinsic. -impl GetDispatchInfo for CheckedExtrinsic +impl GetDispatchInfo for CheckedExtrinsic where Call: GetDispatchInfo, { @@ -389,21 +389,6 @@ where } } -/// Implementation for test extrinsic. -#[cfg(feature = "std")] -impl GetDispatchInfo - for sp_runtime::testing::TestXt -{ - fn get_dispatch_info(&self) -> DispatchInfo { - // for testing: weight == size. - DispatchInfo { - weight: Weight::from_parts(self.encode().len() as _, 0), - pays_fee: Pays::Yes, - class: self.call.get_dispatch_info().class, - } - } -} - /// A struct holding value for each `DispatchClass`. #[derive(Clone, Eq, PartialEq, Default, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] pub struct PerDispatchClass { diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs index caf9457d666..b5b1ac09c60 100644 --- a/substrate/frame/support/src/lib.rs +++ b/substrate/frame/support/src/lib.rs @@ -54,7 +54,8 @@ pub mod __private { #[cfg(feature = "std")] pub use sp_runtime::{bounded_btree_map, bounded_vec}; pub use sp_runtime::{ - traits::Dispatchable, DispatchError, RuntimeDebug, StateVersion, TransactionOutcome, + traits::{AsSystemOriginSigner, Dispatchable}, + DispatchError, RuntimeDebug, StateVersion, TransactionOutcome, }; #[cfg(feature = "std")] pub use sp_state_machine::BasicExternalities; @@ -75,6 +76,7 @@ pub mod storage; #[cfg(test)] mod tests; pub mod traits; +pub mod transaction_extensions; pub mod weights; #[doc(hidden)] pub mod unsigned { @@ -1602,8 +1604,8 @@ pub mod pallet_macros { /// [`ValidateUnsigned`](frame_support::pallet_prelude::ValidateUnsigned) for /// type `Pallet`, and some optional where clause. /// - /// NOTE: There is also the [`sp_runtime::traits::SignedExtension`] trait that can be used - /// to add some specific logic for transaction validation. + /// NOTE: There is also the [`sp_runtime::traits::TransactionExtension`] trait that can be + /// used to add some specific logic for transaction validation. /// /// ## Macro expansion /// diff --git a/substrate/frame/support/src/traits/dispatch.rs b/substrate/frame/support/src/traits/dispatch.rs index de50ce7a26c..212c3080352 100644 --- a/substrate/frame/support/src/traits/dispatch.rs +++ b/substrate/frame/support/src/traits/dispatch.rs @@ -482,7 +482,7 @@ pub trait OriginTrait: Sized { type Call; /// The caller origin, overarching type of all pallets origins. - type PalletsOrigin: Into + CallerTrait + MaxEncodedLen; + type PalletsOrigin: Send + Sync + Into + CallerTrait + MaxEncodedLen; /// The AccountId used across the system. type AccountId; @@ -496,6 +496,14 @@ pub trait OriginTrait: Sized { /// Replace the caller with caller from the other origin fn set_caller_from(&mut self, other: impl Into); + /// Replace the caller with caller from the other origin + fn set_caller(&mut self, caller: Self::PalletsOrigin); + + /// Replace the caller with caller from the other origin + fn set_caller_from_signed(&mut self, caller_account: Self::AccountId) { + self.set_caller(Self::PalletsOrigin::from(RawOrigin::Signed(caller_account))) + } + /// Filter the call if caller is not root, if false is returned then the call must be filtered /// out. /// @@ -544,6 +552,17 @@ pub trait OriginTrait: Sized { fn as_system_ref(&self) -> Option<&RawOrigin> { self.caller().as_system_ref() } + + /// Extract a reference to the sytsem signer, if that's what the caller is. + fn as_system_signer(&self) -> Option<&Self::AccountId> { + self.caller().as_system_ref().and_then(|s| { + if let RawOrigin::Signed(ref who) = s { + Some(who) + } else { + None + } + }) + } } #[cfg(test)] diff --git a/substrate/frame/support/src/traits/misc.rs b/substrate/frame/support/src/traits/misc.rs index 1f634a64282..fba546ce21b 100644 --- a/substrate/frame/support/src/traits/misc.rs +++ b/substrate/frame/support/src/traits/misc.rs @@ -919,24 +919,13 @@ pub trait ExtrinsicCall: sp_runtime::traits::Extrinsic { fn call(&self) -> &Self::Call; } -#[cfg(feature = "std")] -impl ExtrinsicCall for sp_runtime::testing::TestXt -where - Call: codec::Codec + Sync + Send + TypeInfo, - Extra: TypeInfo, -{ - fn call(&self) -> &Self::Call { - &self.call - } -} - impl ExtrinsicCall for sp_runtime::generic::UncheckedExtrinsic where Address: TypeInfo, Call: TypeInfo, Signature: TypeInfo, - Extra: sp_runtime::traits::SignedExtension + TypeInfo, + Extra: TypeInfo, { fn call(&self) -> &Self::Call { &self.function diff --git a/substrate/frame/support/src/transaction_extensions.rs b/substrate/frame/support/src/transaction_extensions.rs new file mode 100644 index 00000000000..98d78b9b4e4 --- /dev/null +++ b/substrate/frame/support/src/transaction_extensions.rs @@ -0,0 +1,89 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Transaction extensions. + +use crate::{CloneNoBound, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound}; +use codec::{Decode, Encode}; +use scale_info::TypeInfo; +use sp_io::hashing::blake2_256; +use sp_runtime::{ + impl_tx_ext_default, + traits::{ + transaction_extension::{TransactionExtensionBase, TransactionExtensionInterior}, + DispatchInfoOf, Dispatchable, IdentifyAccount, TransactionExtension, Verify, + }, + transaction_validity::{InvalidTransaction, TransactionValidityError, ValidTransaction}, +}; + +#[derive( + CloneNoBound, EqNoBound, PartialEqNoBound, Encode, Decode, RuntimeDebugNoBound, TypeInfo, +)] +#[codec(encode_bound())] +#[codec(decode_bound())] +pub struct VerifyMultiSignature +where + V: TransactionExtensionInterior, + ::AccountId: TransactionExtensionInterior, +{ + signature: V, + account: ::AccountId, +} + +impl TransactionExtensionBase for VerifyMultiSignature +where + V: TransactionExtensionInterior, + ::AccountId: TransactionExtensionInterior, +{ + const IDENTIFIER: &'static str = "VerifyMultiSignature"; + type Implicit = (); +} + +impl TransactionExtension + for VerifyMultiSignature +where + V: TransactionExtensionInterior, + ::AccountId: TransactionExtensionInterior, + ::RuntimeOrigin: From::AccountId>>, +{ + type Val = (); + type Pre = (); + impl_tx_ext_default!(Call; Context; prepare); + + fn validate( + &self, + _origin: ::RuntimeOrigin, + _call: &Call, + _info: &DispatchInfoOf, + _len: usize, + _: &mut Context, + _: (), + inherited_implication: &impl Encode, + ) -> Result< + (ValidTransaction, Self::Val, ::RuntimeOrigin), + TransactionValidityError, + > { + let msg = inherited_implication.using_encoded(blake2_256); + + if !self.signature.verify(&msg[..], &self.account) { + Err(InvalidTransaction::BadProof)? + } + // We clobber the original origin. Maybe we shuld check that it's none? + let origin = Some(self.account.clone()).into(); + Ok((ValidTransaction::default(), (), origin)) + } +} diff --git a/substrate/frame/support/src/weights/block_weights.rs b/substrate/frame/support/src/weights/block_weights.rs index 57a68554755..647b6198357 100644 --- a/substrate/frame/support/src/weights/block_weights.rs +++ b/substrate/frame/support/src/weights/block_weights.rs @@ -15,24 +15,23 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16 (Y/M/D) -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01 (Y/M/D) +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! //! SHORT-NAME: `block`, LONG-NAME: `BlockExecution`, RUNTIME: `Development` //! WARMUPS: `10`, REPEAT: `100` -//! WEIGHT-PATH: `./frame/support/src/weights/` +//! WEIGHT-PATH: `./substrate/frame/support/src/weights/` //! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // overhead // --chain=dev -// --execution=wasm // --wasm-execution=compiled -// --weight-path=./frame/support/src/weights/ -// --header=./HEADER-APACHE2 +// --weight-path=./substrate/frame/support/src/weights/ +// --header=./substrate/HEADER-APACHE2 // --warmup=10 // --repeat=100 @@ -44,17 +43,17 @@ parameter_types! { /// Calculated by multiplying the *Average* with `1.0` and adding `0`. /// /// Stats nanoseconds: - /// Min, Max: 376_949, 622_462 - /// Average: 390_584 - /// Median: 386_322 - /// Std-Dev: 24792.0 + /// Min, Max: 424_332, 493_017 + /// Average: 437_118 + /// Median: 434_920 + /// Std-Dev: 8798.01 /// /// Percentiles nanoseconds: - /// 99th: 433_299 - /// 95th: 402_688 - /// 75th: 391_645 + /// 99th: 460_074 + /// 95th: 451_580 + /// 75th: 440_307 pub const BlockExecutionWeight: Weight = - Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(390_584), 0); + Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(437_118), 0); } #[cfg(test)] diff --git a/substrate/frame/support/src/weights/extrinsic_weights.rs b/substrate/frame/support/src/weights/extrinsic_weights.rs index a304f089ff7..99b392c4369 100644 --- a/substrate/frame/support/src/weights/extrinsic_weights.rs +++ b/substrate/frame/support/src/weights/extrinsic_weights.rs @@ -15,24 +15,23 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16 (Y/M/D) -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01 (Y/M/D) +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! //! SHORT-NAME: `extrinsic`, LONG-NAME: `ExtrinsicBase`, RUNTIME: `Development` //! WARMUPS: `10`, REPEAT: `100` -//! WEIGHT-PATH: `./frame/support/src/weights/` +//! WEIGHT-PATH: `./substrate/frame/support/src/weights/` //! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // overhead // --chain=dev -// --execution=wasm // --wasm-execution=compiled -// --weight-path=./frame/support/src/weights/ -// --header=./HEADER-APACHE2 +// --weight-path=./substrate/frame/support/src/weights/ +// --header=./substrate/HEADER-APACHE2 // --warmup=10 // --repeat=100 @@ -44,17 +43,17 @@ parameter_types! { /// Calculated by multiplying the *Average* with `1.0` and adding `0`. /// /// Stats nanoseconds: - /// Min, Max: 123_875, 128_419 - /// Average: 124_414 - /// Median: 124_332 - /// Std-Dev: 497.74 + /// Min, Max: 106_053, 107_403 + /// Average: 106_446 + /// Median: 106_415 + /// Std-Dev: 216.17 /// /// Percentiles nanoseconds: - /// 99th: 125_245 - /// 95th: 124_989 - /// 75th: 124_498 + /// 99th: 107_042 + /// 95th: 106_841 + /// 75th: 106_544 pub const ExtrinsicBaseWeight: Weight = - Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(124_414), 0); + Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(106_446), 0); } #[cfg(test)] diff --git a/substrate/frame/support/test/tests/construct_runtime.rs b/substrate/frame/support/test/tests/construct_runtime.rs index b7698681886..83691451ccd 100644 --- a/substrate/frame/support/test/tests/construct_runtime.rs +++ b/substrate/frame/support/test/tests/construct_runtime.rs @@ -815,7 +815,7 @@ fn test_metadata() { ty: meta_type::(), version: 4, signed_extensions: vec![SignedExtensionMetadata { - identifier: "UnitSignedExtension", + identifier: "UnitTransactionExtension", ty: meta_type::<()>(), additional_signed: meta_type::<()>(), }], diff --git a/substrate/frame/support/test/tests/construct_runtime_ui/deprecated_where_block.stderr b/substrate/frame/support/test/tests/construct_runtime_ui/deprecated_where_block.stderr index 61cfc07caed..9dd460da75a 100644 --- a/substrate/frame/support/test/tests/construct_runtime_ui/deprecated_where_block.stderr +++ b/substrate/frame/support/test/tests/construct_runtime_ui/deprecated_where_block.stderr @@ -477,7 +477,7 @@ note: required because it appears within the type `RuntimeCall` | ||_- in this macro invocation ... | note: required by a bound in `frame_support::sp_runtime::traits::Dispatchable::Config` - --> $WORKSPACE/substrate/primitives/runtime/src/traits.rs + --> $WORKSPACE/substrate/primitives/runtime/src/traits/mod.rs | | type Config; | ^^^^^^^^^^^^ required by this bound in `Dispatchable::Config` @@ -510,7 +510,7 @@ note: required because it appears within the type `RuntimeCall` | ||_- in this macro invocation ... | note: required by a bound in `frame_support::pallet_prelude::ValidateUnsigned::Call` - --> $WORKSPACE/substrate/primitives/runtime/src/traits.rs + --> $WORKSPACE/substrate/primitives/runtime/src/traits/mod.rs | | type Call; | ^^^^^^^^^^ required by this bound in `ValidateUnsigned::Call` diff --git a/substrate/frame/support/test/tests/pallet.rs b/substrate/frame/support/test/tests/pallet.rs index 607f54ccc13..4d2737d411e 100644 --- a/substrate/frame/support/test/tests/pallet.rs +++ b/substrate/frame/support/test/tests/pallet.rs @@ -743,10 +743,40 @@ impl pallet5::Config for Runtime { type RuntimeOrigin = RuntimeOrigin; } +#[derive(Clone, Debug, codec::Encode, codec::Decode, PartialEq, Eq, scale_info::TypeInfo)] +pub struct AccountU64(u64); +impl sp_runtime::traits::IdentifyAccount for AccountU64 { + type AccountId = u64; + fn into_account(self) -> u64 { + self.0 + } +} + +impl sp_runtime::traits::Verify for AccountU64 { + type Signer = AccountU64; + fn verify>( + &self, + _msg: L, + _signer: &::AccountId, + ) -> bool { + true + } +} + +impl From for AccountU64 { + fn from(value: u64) -> Self { + Self(value) + } +} + pub type Header = sp_runtime::generic::Header; pub type Block = sp_runtime::generic::Block; -pub type UncheckedExtrinsic = - sp_runtime::testing::TestXt>; +pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic< + u64, + RuntimeCall, + AccountU64, + frame_system::CheckNonZeroSender, +>; frame_support::construct_runtime!( pub struct Runtime { @@ -896,10 +926,8 @@ fn inherent_expand() { let inherents = InherentData::new().create_extrinsics(); - let expected = vec![UncheckedExtrinsic { - call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}), - signature: None, - }]; + let expected = + vec![UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_no_post_info {}))]; assert_eq!(expected, inherents); let block = Block::new( @@ -911,14 +939,11 @@ fn inherent_expand() { Digest::default(), ), vec![ - UncheckedExtrinsic { - call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}), - signature: None, - }, - UncheckedExtrinsic { - call: RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 0 }), - signature: None, - }, + UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_no_post_info {})), + UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo { + foo: 1, + bar: 0, + })), ], ); @@ -933,14 +958,11 @@ fn inherent_expand() { Digest::default(), ), vec![ - UncheckedExtrinsic { - call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}), - signature: None, - }, - UncheckedExtrinsic { - call: RuntimeCall::Example(pallet::Call::foo { foo: 0, bar: 0 }), - signature: None, - }, + UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_no_post_info {})), + UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo { + foo: 0, + bar: 0, + })), ], ); @@ -954,10 +976,9 @@ fn inherent_expand() { BlakeTwo256::hash(b"test"), Digest::default(), ), - vec![UncheckedExtrinsic { - call: RuntimeCall::Example(pallet::Call::foo_storage_layer { foo: 0 }), - signature: None, - }], + vec![UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_storage_layer { + foo: 0, + }))], ); let mut inherent = InherentData::new(); @@ -972,10 +993,12 @@ fn inherent_expand() { BlakeTwo256::hash(b"test"), Digest::default(), ), - vec![UncheckedExtrinsic { - call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}), - signature: Some((1, Default::default())), - }], + vec![UncheckedExtrinsic::new_signed( + RuntimeCall::Example(pallet::Call::foo_no_post_info {}), + 1, + 1.into(), + Default::default(), + )], ); let mut inherent = InherentData::new(); @@ -991,14 +1014,13 @@ fn inherent_expand() { Digest::default(), ), vec![ - UncheckedExtrinsic { - call: RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 1 }), - signature: None, - }, - UncheckedExtrinsic { - call: RuntimeCall::Example(pallet::Call::foo_storage_layer { foo: 0 }), - signature: None, - }, + UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo { + foo: 1, + bar: 1, + })), + UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_storage_layer { + foo: 0, + })), ], ); @@ -1013,18 +1035,14 @@ fn inherent_expand() { Digest::default(), ), vec![ - UncheckedExtrinsic { - call: RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 1 }), - signature: None, - }, - UncheckedExtrinsic { - call: RuntimeCall::Example(pallet::Call::foo_storage_layer { foo: 0 }), - signature: None, - }, - UncheckedExtrinsic { - call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}), - signature: None, - }, + UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo { + foo: 1, + bar: 1, + })), + UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_storage_layer { + foo: 0, + })), + UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_no_post_info {})), ], ); @@ -1039,18 +1057,17 @@ fn inherent_expand() { Digest::default(), ), vec![ - UncheckedExtrinsic { - call: RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 1 }), - signature: None, - }, - UncheckedExtrinsic { - call: RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 0 }), - signature: Some((1, Default::default())), - }, - UncheckedExtrinsic { - call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}), - signature: None, - }, + UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo { + foo: 1, + bar: 1, + })), + UncheckedExtrinsic::new_signed( + RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 0 }), + 1, + 1.into(), + Default::default(), + ), + UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_no_post_info {})), ], ); @@ -1933,7 +1950,7 @@ fn extrinsic_metadata_ir_types() { >(), ir.signature_ty ); - assert_eq!(meta_type::<()>(), ir.signature_ty); + assert_eq!(meta_type::(), ir.signature_ty); assert_eq!(meta_type::<<::SignaturePayload as SignaturePayloadT>::SignatureExtra>(), ir.extra_ty); assert_eq!(meta_type::>(), ir.extra_ty); diff --git a/substrate/frame/support/test/tests/pallet_instance.rs b/substrate/frame/support/test/tests/pallet_instance.rs index f8cc97623b8..505400a7c21 100644 --- a/substrate/frame/support/test/tests/pallet_instance.rs +++ b/substrate/frame/support/test/tests/pallet_instance.rs @@ -943,7 +943,7 @@ fn metadata() { ty: scale_info::meta_type::(), version: 4, signed_extensions: vec![SignedExtensionMetadata { - identifier: "UnitSignedExtension", + identifier: "UnitTransactionExtension", ty: scale_info::meta_type::<()>(), additional_signed: scale_info::meta_type::<()>(), }], diff --git a/substrate/frame/system/benchmarking/src/extensions.rs b/substrate/frame/system/benchmarking/src/extensions.rs new file mode 100644 index 00000000000..1721501dead --- /dev/null +++ b/substrate/frame/system/benchmarking/src/extensions.rs @@ -0,0 +1,213 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +// Benchmarks for System Extensions + +#![cfg(feature = "runtime-benchmarks")] + +use frame_benchmarking::{account, impl_benchmark_test_suite, v2::*, BenchmarkError}; +use frame_support::{ + dispatch::{DispatchClass, DispatchInfo, PostDispatchInfo}, + weights::Weight, +}; +use frame_system::{ + pallet_prelude::*, CheckGenesis, CheckMortality, CheckNonZeroSender, CheckNonce, + CheckSpecVersion, CheckTxVersion, CheckWeight, Config, Pallet as System, RawOrigin, +}; +use sp_runtime::{ + generic::Era, + traits::{AsSystemOriginSigner, DispatchTransaction, Dispatchable, Get}, +}; +use sp_std::prelude::*; + +pub struct Pallet(System); + +#[benchmarks(where + T: Send + Sync, + T::RuntimeCall: Dispatchable, + ::RuntimeOrigin: AsSystemOriginSigner + Clone) +] +mod benchmarks { + use super::*; + + #[benchmark] + fn check_genesis() -> Result<(), BenchmarkError> { + let len = 0_usize; + let caller = account("caller", 0, 0); + let info = DispatchInfo { weight: Weight::zero(), ..Default::default() }; + let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into(); + + #[block] + { + CheckGenesis::::new() + .test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(().into())) + .unwrap() + .unwrap(); + } + + Ok(()) + } + + #[benchmark] + fn check_mortality() -> Result<(), BenchmarkError> { + let len = 0_usize; + let ext = CheckMortality::::from(Era::mortal(16, 256)); + let block_number: BlockNumberFor = 17u32.into(); + System::::set_block_number(block_number); + let prev_block: BlockNumberFor = 16u32.into(); + let default_hash: T::Hash = Default::default(); + frame_system::BlockHash::::insert(prev_block, default_hash); + let caller = account("caller", 0, 0); + let info = DispatchInfo { + weight: Weight::from_parts(100, 0), + class: DispatchClass::Normal, + ..Default::default() + }; + let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into(); + + #[block] + { + ext.test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(().into())) + .unwrap() + .unwrap(); + } + Ok(()) + } + + #[benchmark] + fn check_non_zero_sender() -> Result<(), BenchmarkError> { + let len = 0_usize; + let ext = CheckNonZeroSender::::new(); + let caller = account("caller", 0, 0); + let info = DispatchInfo { weight: Weight::zero(), ..Default::default() }; + let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into(); + + #[block] + { + ext.test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(().into())) + .unwrap() + .unwrap(); + } + Ok(()) + } + + #[benchmark] + fn check_nonce() -> Result<(), BenchmarkError> { + let caller: T::AccountId = account("caller", 0, 0); + let mut info = frame_system::AccountInfo::default(); + info.nonce = 1u32.into(); + info.providers = 1; + let expected_nonce = info.nonce + 1u32.into(); + frame_system::Account::::insert(caller.clone(), info); + let len = 0_usize; + let ext = CheckNonce::::from(1u32.into()); + let info = DispatchInfo { weight: Weight::zero(), ..Default::default() }; + let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into(); + + #[block] + { + ext.test_run(RawOrigin::Signed(caller.clone()).into(), &call, &info, len, |_| { + Ok(().into()) + }) + .unwrap() + .unwrap(); + } + + let updated_info = frame_system::Account::::get(caller.clone()); + assert_eq!(updated_info.nonce, expected_nonce); + Ok(()) + } + + #[benchmark] + fn check_spec_version() -> Result<(), BenchmarkError> { + let len = 0_usize; + let caller = account("caller", 0, 0); + let info = DispatchInfo { weight: Weight::zero(), ..Default::default() }; + let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into(); + + #[block] + { + CheckSpecVersion::::new() + .test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(().into())) + .unwrap() + .unwrap(); + } + Ok(()) + } + + #[benchmark] + fn check_tx_version() -> Result<(), BenchmarkError> { + let len = 0_usize; + let caller = account("caller", 0, 0); + let info = DispatchInfo { weight: Weight::zero(), ..Default::default() }; + let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into(); + + #[block] + { + CheckTxVersion::::new() + .test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(().into())) + .unwrap() + .unwrap(); + } + Ok(()) + } + + #[benchmark] + fn check_weight() -> Result<(), BenchmarkError> { + let caller = account("caller", 0, 0); + let base_extrinsic = ::BlockWeights::get() + .get(DispatchClass::Normal) + .base_extrinsic; + let info = DispatchInfo { + weight: Weight::from_parts(base_extrinsic.ref_time() * 5, 0), + class: DispatchClass::Normal, + ..Default::default() + }; + let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into(); + let post_info = PostDispatchInfo { + actual_weight: Some(Weight::from_parts(base_extrinsic.ref_time() * 2, 0)), + pays_fee: Default::default(), + }; + let len = 0_usize; + let base_extrinsic = ::BlockWeights::get() + .get(DispatchClass::Normal) + .base_extrinsic; + + let ext = CheckWeight::::new(); + + let initial_block_weight = Weight::from_parts(base_extrinsic.ref_time() * 2, 0); + frame_system::BlockWeight::::mutate(|current_weight| { + current_weight.set(Weight::zero(), DispatchClass::Mandatory); + current_weight.set(initial_block_weight, DispatchClass::Normal); + }); + + #[block] + { + ext.test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(post_info)) + .unwrap() + .unwrap(); + } + + assert_eq!( + System::::block_weight().total(), + initial_block_weight + base_extrinsic + post_info.actual_weight.unwrap(), + ); + Ok(()) + } + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test,); +} diff --git a/substrate/frame/system/benchmarking/src/lib.rs b/substrate/frame/system/benchmarking/src/lib.rs index 18bfb85f52d..ebd16275bcb 100644 --- a/substrate/frame/system/benchmarking/src/lib.rs +++ b/substrate/frame/system/benchmarking/src/lib.rs @@ -28,6 +28,7 @@ use sp_core::storage::well_known_keys; use sp_runtime::traits::Hash; use sp_std::{prelude::*, vec}; +pub mod extensions; mod mock; pub struct Pallet(System); diff --git a/substrate/frame/system/benchmarking/src/mock.rs b/substrate/frame/system/benchmarking/src/mock.rs index edbf74a9a51..1f84dd53004 100644 --- a/substrate/frame/system/benchmarking/src/mock.rs +++ b/substrate/frame/system/benchmarking/src/mock.rs @@ -57,6 +57,7 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type ExtensionsWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); type MaxConsumers = frame_support::traits::ConstU32<16>; diff --git a/substrate/frame/system/src/extensions/check_genesis.rs b/substrate/frame/system/src/extensions/check_genesis.rs index 76a711a823e..3f11f745cd9 100644 --- a/substrate/frame/system/src/extensions/check_genesis.rs +++ b/substrate/frame/system/src/extensions/check_genesis.rs @@ -19,7 +19,8 @@ use crate::{pallet_prelude::BlockNumberFor, Config, Pallet}; use codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_runtime::{ - traits::{DispatchInfoOf, SignedExtension, Zero}, + impl_tx_ext_default, + traits::{TransactionExtension, TransactionExtensionBase, Zero}, transaction_validity::TransactionValidityError, }; @@ -46,30 +47,26 @@ impl sp_std::fmt::Debug for CheckGenesis { } impl CheckGenesis { - /// Creates new `SignedExtension` to check genesis hash. + /// Creates new `TransactionExtension` to check genesis hash. pub fn new() -> Self { Self(sp_std::marker::PhantomData) } } -impl SignedExtension for CheckGenesis { - type AccountId = T::AccountId; - type Call = ::RuntimeCall; - type AdditionalSigned = T::Hash; - type Pre = (); +impl TransactionExtensionBase for CheckGenesis { const IDENTIFIER: &'static str = "CheckGenesis"; - - fn additional_signed(&self) -> Result { + type Implicit = T::Hash; + fn implicit(&self) -> Result { Ok(>::block_hash(BlockNumberFor::::zero())) } - - fn pre_dispatch( - self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> Result { - self.validate(who, call, info, len).map(|_| ()) + fn weight(&self) -> sp_weights::Weight { + ::check_genesis() } } +impl TransactionExtension + for CheckGenesis +{ + type Val = (); + type Pre = (); + impl_tx_ext_default!(T::RuntimeCall; Context; validate prepare); +} diff --git a/substrate/frame/system/src/extensions/check_mortality.rs b/substrate/frame/system/src/extensions/check_mortality.rs index 148dfd4aad4..deb44880d64 100644 --- a/substrate/frame/system/src/extensions/check_mortality.rs +++ b/substrate/frame/system/src/extensions/check_mortality.rs @@ -20,10 +20,12 @@ use codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_runtime::{ generic::Era, - traits::{DispatchInfoOf, SaturatedConversion, SignedExtension}, - transaction_validity::{ - InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction, + impl_tx_ext_default, + traits::{ + DispatchInfoOf, SaturatedConversion, TransactionExtension, TransactionExtensionBase, + ValidateResult, }, + transaction_validity::{InvalidTransaction, TransactionValidityError, ValidTransaction}, }; /// Check for transaction mortality. @@ -54,29 +56,11 @@ impl sp_std::fmt::Debug for CheckMortality { } } -impl SignedExtension for CheckMortality { - type AccountId = T::AccountId; - type Call = T::RuntimeCall; - type AdditionalSigned = T::Hash; - type Pre = (); +impl TransactionExtensionBase for CheckMortality { const IDENTIFIER: &'static str = "CheckMortality"; + type Implicit = T::Hash; - fn validate( - &self, - _who: &Self::AccountId, - _call: &Self::Call, - _info: &DispatchInfoOf, - _len: usize, - ) -> TransactionValidity { - let current_u64 = >::block_number().saturated_into::(); - let valid_till = self.0.death(current_u64); - Ok(ValidTransaction { - longevity: valid_till.saturating_sub(current_u64), - ..Default::default() - }) - } - - fn additional_signed(&self) -> Result { + fn implicit(&self) -> Result { let current_u64 = >::block_number().saturated_into::(); let n = self.0.birth(current_u64).saturated_into::>(); if !>::contains_key(n) { @@ -85,16 +69,38 @@ impl SignedExtension for CheckMortality { Ok(>::block_hash(n)) } } + fn weight(&self) -> sp_weights::Weight { + ::check_mortality() + } +} +impl TransactionExtension + for CheckMortality +{ + type Pre = (); + type Val = (); - fn pre_dispatch( - self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> Result { - self.validate(who, call, info, len).map(|_| ()) + fn validate( + &self, + origin: ::RuntimeOrigin, + _call: &T::RuntimeCall, + _info: &DispatchInfoOf, + _len: usize, + _context: &mut Context, + _self_implicit: Self::Implicit, + _inherited_implication: &impl Encode, + ) -> ValidateResult { + let current_u64 = >::block_number().saturated_into::(); + let valid_till = self.0.death(current_u64); + Ok(( + ValidTransaction { + longevity: valid_till.saturating_sub(current_u64), + ..Default::default() + }, + (), + origin, + )) } + impl_tx_ext_default!(T::RuntimeCall; Context; prepare); } #[cfg(test)] @@ -106,23 +112,21 @@ mod tests { weights::Weight, }; use sp_core::H256; + use sp_runtime::traits::DispatchTransaction; #[test] fn signed_ext_check_era_should_work() { new_test_ext().execute_with(|| { // future assert_eq!( - CheckMortality::::from(Era::mortal(4, 2)) - .additional_signed() - .err() - .unwrap(), + CheckMortality::::from(Era::mortal(4, 2)).implicit().err().unwrap(), InvalidTransaction::AncientBirthBlock.into(), ); // correct System::set_block_number(13); >::insert(12, H256::repeat_byte(1)); - assert!(CheckMortality::::from(Era::mortal(4, 12)).additional_signed().is_ok()); + assert!(CheckMortality::::from(Era::mortal(4, 12)).implicit().is_ok()); }) } @@ -142,7 +146,10 @@ mod tests { System::set_block_number(17); >::insert(16, H256::repeat_byte(1)); - assert_eq!(ext.validate(&1, CALL, &normal, len).unwrap().longevity, 15); + assert_eq!( + ext.validate_only(Some(1).into(), CALL, &normal, len).unwrap().0.longevity, + 15 + ); }) } } diff --git a/substrate/frame/system/src/extensions/check_non_zero_sender.rs b/substrate/frame/system/src/extensions/check_non_zero_sender.rs index 92eed60fc66..115ffac9b03 100644 --- a/substrate/frame/system/src/extensions/check_non_zero_sender.rs +++ b/substrate/frame/system/src/extensions/check_non_zero_sender.rs @@ -17,13 +17,14 @@ use crate::Config; use codec::{Decode, Encode}; -use frame_support::{dispatch::DispatchInfo, DefaultNoBound}; +use frame_support::{traits::OriginTrait, DefaultNoBound}; use scale_info::TypeInfo; use sp_runtime::{ - traits::{DispatchInfoOf, Dispatchable, SignedExtension}, - transaction_validity::{ - InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction, + impl_tx_ext_default, + traits::{ + transaction_extension::TransactionExtensionBase, DispatchInfoOf, TransactionExtension, }, + transaction_validity::InvalidTransaction, }; use sp_std::{marker::PhantomData, prelude::*}; @@ -45,66 +46,82 @@ impl sp_std::fmt::Debug for CheckNonZeroSender { } impl CheckNonZeroSender { - /// Create new `SignedExtension` to check runtime version. + /// Create new `TransactionExtension` to check runtime version. pub fn new() -> Self { Self(sp_std::marker::PhantomData) } } -impl SignedExtension for CheckNonZeroSender -where - T::RuntimeCall: Dispatchable, -{ - type AccountId = T::AccountId; - type Call = T::RuntimeCall; - type AdditionalSigned = (); - type Pre = (); +impl TransactionExtensionBase for CheckNonZeroSender { const IDENTIFIER: &'static str = "CheckNonZeroSender"; - - fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { - Ok(()) + type Implicit = (); + fn weight(&self) -> sp_weights::Weight { + ::check_non_zero_sender() } - - fn pre_dispatch( - self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> Result { - self.validate(who, call, info, len).map(|_| ()) - } - +} +impl TransactionExtension + for CheckNonZeroSender +{ + type Val = (); + type Pre = (); fn validate( &self, - who: &Self::AccountId, - _call: &Self::Call, - _info: &DispatchInfoOf, + origin: ::RuntimeOrigin, + _call: &T::RuntimeCall, + _info: &DispatchInfoOf, _len: usize, - ) -> TransactionValidity { - if who.using_encoded(|d| d.iter().all(|x| *x == 0)) { - return Err(TransactionValidityError::Invalid(InvalidTransaction::BadSigner)) + _context: &mut Context, + _self_implicit: Self::Implicit, + _inherited_implication: &impl Encode, + ) -> sp_runtime::traits::ValidateResult { + if let Some(who) = origin.as_system_signer() { + if who.using_encoded(|d| d.iter().all(|x| *x == 0)) { + return Err(InvalidTransaction::BadSigner.into()) + } } - Ok(ValidTransaction::default()) + Ok((Default::default(), (), origin)) } + impl_tx_ext_default!(T::RuntimeCall; Context; prepare); } #[cfg(test)] mod tests { use super::*; use crate::mock::{new_test_ext, Test, CALL}; - use frame_support::{assert_noop, assert_ok}; + use frame_support::{assert_ok, dispatch::DispatchInfo}; + use sp_runtime::{traits::DispatchTransaction, TransactionValidityError}; #[test] fn zero_account_ban_works() { new_test_ext().execute_with(|| { let info = DispatchInfo::default(); let len = 0_usize; - assert_noop!( - CheckNonZeroSender::::new().validate(&0, CALL, &info, len), - InvalidTransaction::BadSigner + assert_eq!( + CheckNonZeroSender::::new() + .validate_only(Some(0).into(), CALL, &info, len) + .unwrap_err(), + TransactionValidityError::from(InvalidTransaction::BadSigner) ); - assert_ok!(CheckNonZeroSender::::new().validate(&1, CALL, &info, len)); + assert_ok!(CheckNonZeroSender::::new().validate_only( + Some(1).into(), + CALL, + &info, + len + )); + }) + } + + #[test] + fn unsigned_origin_works() { + new_test_ext().execute_with(|| { + let info = DispatchInfo::default(); + let len = 0_usize; + assert_ok!(CheckNonZeroSender::::new().validate_only( + None.into(), + CALL, + &info, + len + )); }) } } diff --git a/substrate/frame/system/src/extensions/check_nonce.rs b/substrate/frame/system/src/extensions/check_nonce.rs index 7504a814aef..ead9d9f7c81 100644 --- a/substrate/frame/system/src/extensions/check_nonce.rs +++ b/substrate/frame/system/src/extensions/check_nonce.rs @@ -15,16 +15,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::Config; +use crate::{AccountInfo, Config}; use codec::{Decode, Encode}; use frame_support::dispatch::DispatchInfo; use scale_info::TypeInfo; use sp_runtime::{ - traits::{DispatchInfoOf, Dispatchable, One, SignedExtension, Zero}, + traits::{ + AsSystemOriginSigner, DispatchInfoOf, Dispatchable, One, TransactionExtension, + TransactionExtensionBase, ValidateResult, Zero, + }, transaction_validity::{ - InvalidTransaction, TransactionLongevity, TransactionValidity, TransactionValidityError, - ValidTransaction, + InvalidTransaction, TransactionLongevity, TransactionValidityError, ValidTransaction, }, + Saturating, }; use sp_std::vec; @@ -58,75 +61,78 @@ impl sp_std::fmt::Debug for CheckNonce { } } -impl SignedExtension for CheckNonce +impl TransactionExtensionBase for CheckNonce { + const IDENTIFIER: &'static str = "CheckNonce"; + type Implicit = (); + fn weight(&self) -> sp_weights::Weight { + ::check_nonce() + } +} +impl TransactionExtension for CheckNonce where T::RuntimeCall: Dispatchable, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, { - type AccountId = T::AccountId; - type Call = T::RuntimeCall; - type AdditionalSigned = (); + type Val = Option<(T::AccountId, AccountInfo)>; type Pre = (); - const IDENTIFIER: &'static str = "CheckNonce"; - - fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { - Ok(()) - } - - fn pre_dispatch( - self, - who: &Self::AccountId, - _call: &Self::Call, - _info: &DispatchInfoOf, - _len: usize, - ) -> Result<(), TransactionValidityError> { - let mut account = crate::Account::::get(who); - if account.providers.is_zero() && account.sufficients.is_zero() { - // Nonce storage not paid for - return Err(InvalidTransaction::Payment.into()) - } - if self.0 != account.nonce { - return Err(if self.0 < account.nonce { - InvalidTransaction::Stale - } else { - InvalidTransaction::Future - } - .into()) - } - account.nonce += T::Nonce::one(); - crate::Account::::insert(who, account); - Ok(()) - } fn validate( &self, - who: &Self::AccountId, - _call: &Self::Call, - _info: &DispatchInfoOf, + origin: ::RuntimeOrigin, + _call: &T::RuntimeCall, + _info: &DispatchInfoOf, _len: usize, - ) -> TransactionValidity { + _context: &mut Context, + _self_implicit: Self::Implicit, + _inherited_implication: &impl Encode, + ) -> ValidateResult { + let Some(who) = origin.as_system_origin_signer() else { + return Ok((Default::default(), None, origin)) + }; let account = crate::Account::::get(who); if account.providers.is_zero() && account.sufficients.is_zero() { // Nonce storage not paid for - return InvalidTransaction::Payment.into() + return Err(InvalidTransaction::Payment.into()) } if self.0 < account.nonce { - return InvalidTransaction::Stale.into() + return Err(InvalidTransaction::Stale.into()) } - let provides = vec![Encode::encode(&(who, self.0))]; + let provides = vec![Encode::encode(&(who.clone(), self.0))]; let requires = if account.nonce < self.0 { - vec![Encode::encode(&(who, self.0 - One::one()))] + vec![Encode::encode(&(who.clone(), self.0.saturating_sub(One::one())))] } else { vec![] }; - Ok(ValidTransaction { + let validity = ValidTransaction { priority: 0, requires, provides, longevity: TransactionLongevity::max_value(), propagate: true, - }) + }; + + Ok((validity, Some((who.clone(), account)), origin)) + } + + fn prepare( + self, + val: Self::Val, + _origin: &T::RuntimeOrigin, + _call: &T::RuntimeCall, + _info: &DispatchInfoOf, + _len: usize, + _context: &Context, + ) -> Result { + let Some((who, mut account)) = val else { return Ok(()) }; + // `self.0 < account.nonce` already checked in `validate`. + if self.0 > account.nonce { + return Err(InvalidTransaction::Future.into()) + } + account.nonce.saturating_inc(); + crate::Account::::insert(who, account); + Ok(()) } } @@ -134,7 +140,8 @@ where mod tests { use super::*; use crate::mock::{new_test_ext, Test, CALL}; - use frame_support::{assert_noop, assert_ok}; + use frame_support::assert_ok; + use sp_runtime::traits::DispatchTransaction; #[test] fn signed_ext_check_nonce_works() { @@ -152,22 +159,33 @@ mod tests { let info = DispatchInfo::default(); let len = 0_usize; // stale - assert_noop!( - CheckNonce::(0).validate(&1, CALL, &info, len), - InvalidTransaction::Stale + assert_eq!( + CheckNonce::(0) + .validate_only(Some(1).into(), CALL, &info, len,) + .unwrap_err(), + TransactionValidityError::Invalid(InvalidTransaction::Stale) ); - assert_noop!( - CheckNonce::(0).pre_dispatch(&1, CALL, &info, len), - InvalidTransaction::Stale + assert_eq!( + CheckNonce::(0) + .validate_and_prepare(Some(1).into(), CALL, &info, len) + .unwrap_err(), + InvalidTransaction::Stale.into() ); // correct - assert_ok!(CheckNonce::(1).validate(&1, CALL, &info, len)); - assert_ok!(CheckNonce::(1).pre_dispatch(&1, CALL, &info, len)); + assert_ok!(CheckNonce::(1).validate_only(Some(1).into(), CALL, &info, len)); + assert_ok!(CheckNonce::(1).validate_and_prepare( + Some(1).into(), + CALL, + &info, + len + )); // future - assert_ok!(CheckNonce::(5).validate(&1, CALL, &info, len)); - assert_noop!( - CheckNonce::(5).pre_dispatch(&1, CALL, &info, len), - InvalidTransaction::Future + assert_ok!(CheckNonce::(5).validate_only(Some(1).into(), CALL, &info, len)); + assert_eq!( + CheckNonce::(5) + .validate_and_prepare(Some(1).into(), CALL, &info, len) + .unwrap_err(), + InvalidTransaction::Future.into() ); }) } @@ -198,20 +216,44 @@ mod tests { let info = DispatchInfo::default(); let len = 0_usize; // Both providers and sufficients zero - assert_noop!( - CheckNonce::(1).validate(&1, CALL, &info, len), - InvalidTransaction::Payment + assert_eq!( + CheckNonce::(1) + .validate_only(Some(1).into(), CALL, &info, len) + .unwrap_err(), + TransactionValidityError::Invalid(InvalidTransaction::Payment) ); - assert_noop!( - CheckNonce::(1).pre_dispatch(&1, CALL, &info, len), - InvalidTransaction::Payment + assert_eq!( + CheckNonce::(1) + .validate_and_prepare(Some(1).into(), CALL, &info, len) + .unwrap_err(), + TransactionValidityError::Invalid(InvalidTransaction::Payment) ); // Non-zero providers - assert_ok!(CheckNonce::(1).validate(&2, CALL, &info, len)); - assert_ok!(CheckNonce::(1).pre_dispatch(&2, CALL, &info, len)); + assert_ok!(CheckNonce::(1).validate_only(Some(2).into(), CALL, &info, len)); + assert_ok!(CheckNonce::(1).validate_and_prepare( + Some(2).into(), + CALL, + &info, + len + )); // Non-zero sufficients - assert_ok!(CheckNonce::(1).validate(&3, CALL, &info, len)); - assert_ok!(CheckNonce::(1).pre_dispatch(&3, CALL, &info, len)); + assert_ok!(CheckNonce::(1).validate_only(Some(3).into(), CALL, &info, len)); + assert_ok!(CheckNonce::(1).validate_and_prepare( + Some(3).into(), + CALL, + &info, + len + )); + }) + } + + #[test] + fn unsigned_check_nonce_works() { + new_test_ext().execute_with(|| { + let info = DispatchInfo::default(); + let len = 0_usize; + assert_ok!(CheckNonce::(1).validate_only(None.into(), CALL, &info, len)); + assert_ok!(CheckNonce::(1).validate_and_prepare(None.into(), CALL, &info, len)); }) } } diff --git a/substrate/frame/system/src/extensions/check_spec_version.rs b/substrate/frame/system/src/extensions/check_spec_version.rs index 24d5ef9cafb..3109708f48e 100644 --- a/substrate/frame/system/src/extensions/check_spec_version.rs +++ b/substrate/frame/system/src/extensions/check_spec_version.rs @@ -19,7 +19,8 @@ use crate::{Config, Pallet}; use codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_runtime::{ - traits::{DispatchInfoOf, SignedExtension}, + impl_tx_ext_default, + traits::{transaction_extension::TransactionExtensionBase, TransactionExtension}, transaction_validity::TransactionValidityError, }; @@ -46,30 +47,26 @@ impl sp_std::fmt::Debug for CheckSpecVersion { } impl CheckSpecVersion { - /// Create new `SignedExtension` to check runtime version. + /// Create new `TransactionExtension` to check runtime version. pub fn new() -> Self { Self(sp_std::marker::PhantomData) } } -impl SignedExtension for CheckSpecVersion { - type AccountId = T::AccountId; - type Call = ::RuntimeCall; - type AdditionalSigned = u32; - type Pre = (); +impl TransactionExtensionBase for CheckSpecVersion { const IDENTIFIER: &'static str = "CheckSpecVersion"; - - fn additional_signed(&self) -> Result { + type Implicit = u32; + fn implicit(&self) -> Result { Ok(>::runtime_version().spec_version) } - - fn pre_dispatch( - self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> Result { - self.validate(who, call, info, len).map(|_| ()) + fn weight(&self) -> sp_weights::Weight { + ::check_spec_version() } } +impl TransactionExtension<::RuntimeCall, Context> + for CheckSpecVersion +{ + type Val = (); + type Pre = (); + impl_tx_ext_default!(::RuntimeCall; Context; validate prepare); +} diff --git a/substrate/frame/system/src/extensions/check_tx_version.rs b/substrate/frame/system/src/extensions/check_tx_version.rs index 3f9d6a1903f..ee1d507e7bc 100644 --- a/substrate/frame/system/src/extensions/check_tx_version.rs +++ b/substrate/frame/system/src/extensions/check_tx_version.rs @@ -19,7 +19,8 @@ use crate::{Config, Pallet}; use codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_runtime::{ - traits::{DispatchInfoOf, SignedExtension}, + impl_tx_ext_default, + traits::{transaction_extension::TransactionExtensionBase, TransactionExtension}, transaction_validity::TransactionValidityError, }; @@ -46,29 +47,26 @@ impl sp_std::fmt::Debug for CheckTxVersion { } impl CheckTxVersion { - /// Create new `SignedExtension` to check transaction version. + /// Create new `TransactionExtension` to check transaction version. pub fn new() -> Self { Self(sp_std::marker::PhantomData) } } -impl SignedExtension for CheckTxVersion { - type AccountId = T::AccountId; - type Call = ::RuntimeCall; - type AdditionalSigned = u32; - type Pre = (); +impl TransactionExtensionBase for CheckTxVersion { const IDENTIFIER: &'static str = "CheckTxVersion"; - - fn additional_signed(&self) -> Result { + type Implicit = u32; + fn implicit(&self) -> Result { Ok(>::runtime_version().transaction_version) } - fn pre_dispatch( - self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> Result { - self.validate(who, call, info, len).map(|_| ()) + fn weight(&self) -> sp_weights::Weight { + ::check_tx_version() } } +impl TransactionExtension<::RuntimeCall, Context> + for CheckTxVersion +{ + type Val = (); + type Pre = (); + impl_tx_ext_default!(::RuntimeCall; Context; validate prepare); +} diff --git a/substrate/frame/system/src/extensions/check_weight.rs b/substrate/frame/system/src/extensions/check_weight.rs index 70d1e756332..5c35acfb3f3 100644 --- a/substrate/frame/system/src/extensions/check_weight.rs +++ b/substrate/frame/system/src/extensions/check_weight.rs @@ -23,9 +23,12 @@ use frame_support::{ }; use scale_info::TypeInfo; use sp_runtime::{ - traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf, SignedExtension}, - transaction_validity::{InvalidTransaction, TransactionValidity, TransactionValidityError}, - DispatchResult, + traits::{ + DispatchInfoOf, Dispatchable, PostDispatchInfoOf, TransactionExtension, + TransactionExtensionBase, ValidateResult, + }, + transaction_validity::{InvalidTransaction, TransactionValidityError}, + DispatchResult, ValidTransaction, }; use sp_weights::Weight; @@ -100,39 +103,43 @@ where } } - /// Creates new `SignedExtension` to check weight of the extrinsic. + /// Creates new `TransactionExtension` to check weight of the extrinsic. pub fn new() -> Self { Self(Default::default()) } - /// Do the pre-dispatch checks. This can be applied to both signed and unsigned. + /// Do the validate checks. This can be applied to both signed and unsigned. /// - /// It checks and notes the new weight and length. - pub fn do_pre_dispatch( + /// It only checks that the block weight and length limit will not exceed. + /// + /// Returns the transaction validity and the next block length, to be used in `prepare`. + pub fn do_validate( info: &DispatchInfoOf, len: usize, - ) -> Result<(), TransactionValidityError> { + ) -> Result<(ValidTransaction, u32), TransactionValidityError> { + // ignore the next length. If they return `Ok`, then it is below the limit. let next_len = Self::check_block_length(info, len)?; - let next_weight = Self::check_block_weight(info)?; + // during validation we skip block limit check. Since the `validate_transaction` + // call runs on an empty block anyway, by this we prevent `on_initialize` weight + // consumption from causing false negatives. Self::check_extrinsic_weight(info)?; - crate::AllExtrinsicsLen::::put(next_len); - crate::BlockWeight::::put(next_weight); - Ok(()) + Ok((Default::default(), next_len)) } - /// Do the validate checks. This can be applied to both signed and unsigned. + /// Do the pre-dispatch checks. This can be applied to both signed and unsigned. /// - /// It only checks that the block weight and length limit will not exceed. - pub fn do_validate(info: &DispatchInfoOf, len: usize) -> TransactionValidity { - // ignore the next length. If they return `Ok`, then it is below the limit. - let _ = Self::check_block_length(info, len)?; - // during validation we skip block limit check. Since the `validate_transaction` - // call runs on an empty block anyway, by this we prevent `on_initialize` weight - // consumption from causing false negatives. - Self::check_extrinsic_weight(info)?; + /// It checks and notes the new weight and length. + pub fn do_prepare( + info: &DispatchInfoOf, + next_len: u32, + ) -> Result<(), TransactionValidityError> { + let next_weight = Self::check_block_weight(info)?; + // Extrinsic weight already checked in `validate`. - Ok(Default::default()) + crate::AllExtrinsicsLen::::put(next_len); + crate::BlockWeight::::put(next_weight); + Ok(()) } } @@ -201,62 +208,55 @@ where Ok(all_weight) } -impl SignedExtension for CheckWeight +impl TransactionExtensionBase for CheckWeight { + const IDENTIFIER: &'static str = "CheckWeight"; + type Implicit = (); + + fn weight(&self) -> Weight { + ::check_weight() + } +} +impl TransactionExtension + for CheckWeight where T::RuntimeCall: Dispatchable, { - type AccountId = T::AccountId; - type Call = T::RuntimeCall; - type AdditionalSigned = (); type Pre = (); - const IDENTIFIER: &'static str = "CheckWeight"; - - fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { - Ok(()) - } - - fn pre_dispatch( - self, - _who: &Self::AccountId, - _call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> Result<(), TransactionValidityError> { - Self::do_pre_dispatch(info, len) - } + type Val = u32; /* next block length */ fn validate( &self, - _who: &Self::AccountId, - _call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> TransactionValidity { - Self::do_validate(info, len) - } - - fn pre_dispatch_unsigned( - _call: &Self::Call, - info: &DispatchInfoOf, + origin: T::RuntimeOrigin, + _call: &T::RuntimeCall, + info: &DispatchInfoOf, len: usize, - ) -> Result<(), TransactionValidityError> { - Self::do_pre_dispatch(info, len) + _context: &mut Context, + _self_implicit: Self::Implicit, + _inherited_implication: &impl Encode, + ) -> ValidateResult { + let (validity, next_len) = Self::do_validate(info, len)?; + Ok((validity, next_len, origin)) } - fn validate_unsigned( - _call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> TransactionValidity { - Self::do_validate(info, len) + fn prepare( + self, + val: Self::Val, + _origin: &T::RuntimeOrigin, + _call: &T::RuntimeCall, + info: &DispatchInfoOf, + _len: usize, + _context: &Context, + ) -> Result { + Self::do_prepare(info, val) } fn post_dispatch( - _pre: Option, - info: &DispatchInfoOf, - post_info: &PostDispatchInfoOf, + _pre: Self::Pre, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, _len: usize, _result: &DispatchResult, + _context: &Context, ) -> Result<(), TransactionValidityError> { let unspent = post_info.calc_unspent(info); if unspent.any_gt(Weight::zero()) { @@ -301,6 +301,7 @@ mod tests { AllExtrinsicsLen, BlockWeight, DispatchClass, }; use frame_support::{assert_err, assert_ok, dispatch::Pays, weights::Weight}; + use sp_runtime::traits::DispatchTransaction; use sp_std::marker::PhantomData; fn block_weights() -> crate::limits::BlockWeights { @@ -338,7 +339,8 @@ mod tests { } check(|max, len| { - assert_ok!(CheckWeight::::do_pre_dispatch(max, len)); + let next_len = CheckWeight::::check_block_length(max, len).unwrap(); + assert_ok!(CheckWeight::::do_prepare(max, next_len)); assert_eq!(System::block_weight().total(), Weight::MAX); assert!(System::block_weight().total().ref_time() > block_weight_limit().ref_time()); }); @@ -419,9 +421,11 @@ mod tests { let len = 0_usize; - assert_ok!(CheckWeight::::do_pre_dispatch(&max_normal, len)); + let next_len = CheckWeight::::check_block_length(&max_normal, len).unwrap(); + assert_ok!(CheckWeight::::do_prepare(&max_normal, next_len)); assert_eq!(System::block_weight().total(), Weight::from_parts(768, 0)); - assert_ok!(CheckWeight::::do_pre_dispatch(&rest_operational, len)); + let next_len = CheckWeight::::check_block_length(&rest_operational, len).unwrap(); + assert_ok!(CheckWeight::::do_prepare(&rest_operational, next_len)); assert_eq!(block_weight_limit(), Weight::from_parts(1024, u64::MAX)); assert_eq!(System::block_weight().total(), block_weight_limit().set_proof_size(0)); // Checking single extrinsic should not take current block weight into account. @@ -443,10 +447,12 @@ mod tests { let len = 0_usize; - assert_ok!(CheckWeight::::do_pre_dispatch(&rest_operational, len)); + let next_len = CheckWeight::::check_block_length(&rest_operational, len).unwrap(); + assert_ok!(CheckWeight::::do_prepare(&rest_operational, next_len)); // Extra 20 here from block execution + base extrinsic weight assert_eq!(System::block_weight().total(), Weight::from_parts(266, 0)); - assert_ok!(CheckWeight::::do_pre_dispatch(&max_normal, len)); + let next_len = CheckWeight::::check_block_length(&max_normal, len).unwrap(); + assert_ok!(CheckWeight::::do_prepare(&max_normal, next_len)); assert_eq!(block_weight_limit(), Weight::from_parts(1024, u64::MAX)); assert_eq!(System::block_weight().total(), block_weight_limit().set_proof_size(0)); }); @@ -469,16 +475,19 @@ mod tests { }; let len = 0_usize; + let next_len = CheckWeight::::check_block_length(&dispatch_normal, len).unwrap(); assert_err!( - CheckWeight::::do_pre_dispatch(&dispatch_normal, len), + CheckWeight::::do_prepare(&dispatch_normal, next_len), InvalidTransaction::ExhaustsResources ); + let next_len = + CheckWeight::::check_block_length(&dispatch_operational, len).unwrap(); // Thank goodness we can still do an operational transaction to possibly save the // blockchain. - assert_ok!(CheckWeight::::do_pre_dispatch(&dispatch_operational, len)); + assert_ok!(CheckWeight::::do_prepare(&dispatch_operational, next_len)); // Not too much though assert_err!( - CheckWeight::::do_pre_dispatch(&dispatch_operational, len), + CheckWeight::::do_prepare(&dispatch_operational, next_len), InvalidTransaction::ExhaustsResources ); // Even with full block, validity of single transaction should be correct. @@ -503,21 +512,35 @@ mod tests { current_weight.set(normal_limit, DispatchClass::Normal) }); // will not fit. - assert_err!( - CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &normal, len), - InvalidTransaction::ExhaustsResources + assert_eq!( + CheckWeight::(PhantomData) + .validate_and_prepare(Some(1).into(), CALL, &normal, len) + .unwrap_err(), + InvalidTransaction::ExhaustsResources.into() ); // will fit. - assert_ok!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &op, len)); + assert_ok!(CheckWeight::(PhantomData).validate_and_prepare( + Some(1).into(), + CALL, + &op, + len + )); // likewise for length limit. let len = 100_usize; AllExtrinsicsLen::::put(normal_length_limit()); - assert_err!( - CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &normal, len), - InvalidTransaction::ExhaustsResources + assert_eq!( + CheckWeight::(PhantomData) + .validate_and_prepare(Some(1).into(), CALL, &normal, len) + .unwrap_err(), + InvalidTransaction::ExhaustsResources.into() ); - assert_ok!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &op, len)); + assert_ok!(CheckWeight::(PhantomData).validate_and_prepare( + Some(1).into(), + CALL, + &op, + len + )); }) } @@ -528,7 +551,12 @@ mod tests { let normal_limit = normal_weight_limit().ref_time() as usize; let reset_check_weight = |tx, s, f| { AllExtrinsicsLen::::put(0); - let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, tx, s); + let r = CheckWeight::(PhantomData).validate_and_prepare( + Some(1).into(), + CALL, + tx, + s, + ); if f { assert!(r.is_err()) } else { @@ -571,7 +599,12 @@ mod tests { BlockWeight::::mutate(|current_weight| { current_weight.set(s, DispatchClass::Normal) }); - let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, i, len); + let r = CheckWeight::(PhantomData).validate_and_prepare( + Some(1).into(), + CALL, + i, + len, + ); if f { assert!(r.is_err()) } else { @@ -604,18 +637,22 @@ mod tests { .set(Weight::from_parts(256, 0) - base_extrinsic, DispatchClass::Normal); }); - let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); + let pre = CheckWeight::(PhantomData) + .validate_and_prepare(Some(1).into(), CALL, &info, len) + .unwrap() + .0; assert_eq!( BlockWeight::::get().total(), info.weight + Weight::from_parts(256, 0) ); assert_ok!(CheckWeight::::post_dispatch( - Some(pre), + pre, &info, &post_info, len, - &Ok(()) + &Ok(()), + &() )); assert_eq!( BlockWeight::::get().total(), @@ -639,7 +676,10 @@ mod tests { current_weight.set(Weight::from_parts(128, 0), DispatchClass::Normal); }); - let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); + let pre = CheckWeight::(PhantomData) + .validate_and_prepare(Some(1).into(), CALL, &info, len) + .unwrap() + .0; assert_eq!( BlockWeight::::get().total(), info.weight + @@ -648,11 +688,12 @@ mod tests { ); assert_ok!(CheckWeight::::post_dispatch( - Some(pre), + pre, &info, &post_info, len, - &Ok(()) + &Ok(()), + &() )); assert_eq!( BlockWeight::::get().total(), @@ -672,7 +713,12 @@ mod tests { // Initial weight from `weights.base_block` assert_eq!(System::block_weight().total(), weights.base_block); - assert_ok!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &free, len)); + assert_ok!(CheckWeight::(PhantomData).validate_and_prepare( + Some(1).into(), + CALL, + &free, + len + )); assert_eq!( System::block_weight().total(), weights.get(DispatchClass::Normal).base_extrinsic + weights.base_block @@ -696,9 +742,11 @@ mod tests { let len = 0_usize; - assert_ok!(CheckWeight::::do_pre_dispatch(&max_normal, len)); + let next_len = CheckWeight::::check_block_length(&max_normal, len).unwrap(); + assert_ok!(CheckWeight::::do_prepare(&max_normal, next_len)); assert_eq!(System::block_weight().total(), Weight::from_parts(768, 0)); - assert_ok!(CheckWeight::::do_pre_dispatch(&mandatory, len)); + let next_len = CheckWeight::::check_block_length(&mandatory, len).unwrap(); + assert_ok!(CheckWeight::::do_prepare(&mandatory, next_len)); assert_eq!(block_weight_limit(), Weight::from_parts(1024, u64::MAX)); assert_eq!(System::block_weight().total(), Weight::from_parts(1024 + 768, 0)); assert_eq!(CheckWeight::::check_extrinsic_weight(&mandatory), Ok(())); diff --git a/substrate/frame/system/src/extensions/mod.rs b/substrate/frame/system/src/extensions/mod.rs index a88c9fbf96e..d79104d2240 100644 --- a/substrate/frame/system/src/extensions/mod.rs +++ b/substrate/frame/system/src/extensions/mod.rs @@ -22,3 +22,6 @@ pub mod check_nonce; pub mod check_spec_version; pub mod check_tx_version; pub mod check_weight; +pub mod weights; + +pub use weights::WeightInfo; diff --git a/substrate/frame/system/src/extensions/weights.rs b/substrate/frame/system/src/extensions/weights.rs new file mode 100644 index 00000000000..0d2fcb15ee6 --- /dev/null +++ b/substrate/frame/system/src/extensions/weights.rs @@ -0,0 +1,196 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Autogenerated weights for `frame_system_extensions` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` + +// Executed Command: +// ./target/production/substrate-node +// benchmark +// pallet +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=frame_system_extensions +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./substrate/frame/system/src/extensions/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for `frame_system_extensions`. +pub trait WeightInfo { + fn check_genesis() -> Weight; + fn check_mortality() -> Weight; + fn check_non_zero_sender() -> Weight; + fn check_nonce() -> Weight; + fn check_spec_version() -> Weight; + fn check_tx_version() -> Weight; + fn check_weight() -> Weight; +} + +/// Weights for `frame_system_extensions` using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_genesis() -> Weight { + // Proof Size summary in bytes: + // Measured: `54` + // Estimated: `3509` + // Minimum execution time: 3_876_000 picoseconds. + Weight::from_parts(4_160_000, 3509) + .saturating_add(T::DbWeight::get().reads(1_u64)) + } + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_mortality() -> Weight { + // Proof Size summary in bytes: + // Measured: `92` + // Estimated: `3509` + // Minimum execution time: 6_296_000 picoseconds. + Weight::from_parts(6_523_000, 3509) + .saturating_add(T::DbWeight::get().reads(1_u64)) + } + fn check_non_zero_sender() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 449_000 picoseconds. + Weight::from_parts(527_000, 0) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn check_nonce() -> Weight { + // Proof Size summary in bytes: + // Measured: `101` + // Estimated: `3593` + // Minimum execution time: 5_689_000 picoseconds. + Weight::from_parts(6_000_000, 3593) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + fn check_spec_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 399_000 picoseconds. + Weight::from_parts(461_000, 0) + } + fn check_tx_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 390_000 picoseconds. + Weight::from_parts(439_000, 0) + } + /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) + /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn check_weight() -> Weight { + // Proof Size summary in bytes: + // Measured: `24` + // Estimated: `1489` + // Minimum execution time: 4_375_000 picoseconds. + Weight::from_parts(4_747_000, 1489) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } +} + +// For backwards compatibility and tests. +impl WeightInfo for () { + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_genesis() -> Weight { + // Proof Size summary in bytes: + // Measured: `54` + // Estimated: `3509` + // Minimum execution time: 3_876_000 picoseconds. + Weight::from_parts(4_160_000, 3509) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + } + /// Storage: `System::BlockHash` (r:1 w:0) + /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + fn check_mortality() -> Weight { + // Proof Size summary in bytes: + // Measured: `92` + // Estimated: `3509` + // Minimum execution time: 6_296_000 picoseconds. + Weight::from_parts(6_523_000, 3509) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + } + fn check_non_zero_sender() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 449_000 picoseconds. + Weight::from_parts(527_000, 0) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn check_nonce() -> Weight { + // Proof Size summary in bytes: + // Measured: `101` + // Estimated: `3593` + // Minimum execution time: 5_689_000 picoseconds. + Weight::from_parts(6_000_000, 3593) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + fn check_spec_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 399_000 picoseconds. + Weight::from_parts(461_000, 0) + } + fn check_tx_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 390_000 picoseconds. + Weight::from_parts(439_000, 0) + } + /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) + /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn check_weight() -> Weight { + // Proof Size summary in bytes: + // Measured: `24` + // Estimated: `1489` + // Minimum execution time: 4_375_000 picoseconds. + Weight::from_parts(4_747_000, 1489) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } +} diff --git a/substrate/frame/system/src/lib.rs b/substrate/frame/system/src/lib.rs index 3b659916379..21393cb3e20 100644 --- a/substrate/frame/system/src/lib.rs +++ b/substrate/frame/system/src/lib.rs @@ -166,7 +166,7 @@ pub use extensions::{ check_genesis::CheckGenesis, check_mortality::CheckMortality, check_non_zero_sender::CheckNonZeroSender, check_nonce::CheckNonce, check_spec_version::CheckSpecVersion, check_tx_version::CheckTxVersion, - check_weight::CheckWeight, + check_weight::CheckWeight, WeightInfo as ExtensionsWeightInfo, }; // Backward compatible re-export. pub use extensions::check_mortality::CheckMortality as CheckEra; @@ -284,6 +284,7 @@ pub mod pallet { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type ExtensionsWeightInfo = (); type SS58Prefix = (); type Version = (); type BlockWeights = (); @@ -356,6 +357,9 @@ pub mod pallet { /// Weight information for the extrinsics of this pallet. type SystemWeightInfo = (); + /// Weight information for the extensions of this pallet. + type ExtensionsWeightInfo = (); + /// This is used as an identifier of the chain. type SS58Prefix = (); @@ -563,8 +567,12 @@ pub mod pallet { /// All resources should be cleaned up associated with the given account. type OnKilledAccount: OnKilledAccount; + /// Weight information for the extrinsics of this pallet. type SystemWeightInfo: WeightInfo; + /// Weight information for the transaction extensions of this pallet. + type ExtensionsWeightInfo: extensions::WeightInfo; + /// The designated SS58 prefix of this chain. /// /// This replaces the "ss58Format" property declared in the chain spec. Reason is diff --git a/substrate/frame/system/src/offchain.rs b/substrate/frame/system/src/offchain.rs index a019cfd666e..ee73e33fe31 100644 --- a/substrate/frame/system/src/offchain.rs +++ b/substrate/frame/system/src/offchain.rs @@ -79,6 +79,9 @@ pub struct SubmitTransaction, Overarchi _phantom: sp_std::marker::PhantomData<(T, OverarchingCall)>, } +// TODO [#2415]: Avoid splitting call and the totally opaque `signature`; `CreateTransaction` trait +// should provide something which impls `Encode`, which can be sent onwards to +// `sp_io::offchain::submit_transaction`. There's no great need to split things up as in here. impl SubmitTransaction where T: SendTransactionTypes, @@ -88,6 +91,8 @@ where call: >::OverarchingCall, signature: Option<::SignaturePayload>, ) -> Result<(), ()> { + // TODO: Use regular transaction API instead. + #[allow(deprecated)] let xt = T::Extrinsic::new(call, signature).ok_or(())?; sp_io::offchain::submit_transaction(xt.encode()) } @@ -471,7 +476,7 @@ pub trait SendTransactionTypes { /// /// This trait is meant to be implemented by the runtime and is responsible for constructing /// a payload to be signed and contained within the extrinsic. -/// This will most likely include creation of `SignedExtra` (a set of `SignedExtensions`). +/// This will most likely include creation of `TxExtension` (a tuple of `TransactionExtension`s). /// Note that the result can be altered by inspecting the `Call` (for instance adjusting /// fees, or mortality depending on the `pallet` being called). pub trait CreateSignedTransaction: @@ -621,14 +626,17 @@ mod tests { use crate::mock::{RuntimeCall, Test as TestRuntime, CALL}; use codec::Decode; use sp_core::offchain::{testing, TransactionPoolExt}; - use sp_runtime::testing::{TestSignature, TestXt, UintAuthorityId}; + use sp_runtime::{ + generic::UncheckedExtrinsic, + testing::{TestSignature, UintAuthorityId}, + }; impl SigningTypes for TestRuntime { type Public = UintAuthorityId; type Signature = TestSignature; } - type Extrinsic = TestXt; + type Extrinsic = UncheckedExtrinsic; impl SendTransactionTypes for TestRuntime { type Extrinsic = Extrinsic; @@ -693,7 +701,7 @@ mod tests { let _tx3 = pool_state.write().transactions.pop().unwrap(); assert!(pool_state.read().transactions.is_empty()); let tx1 = Extrinsic::decode(&mut &*tx1).unwrap(); - assert_eq!(tx1.signature, None); + assert!(tx1.is_inherent()); }); } @@ -724,7 +732,7 @@ mod tests { let tx1 = pool_state.write().transactions.pop().unwrap(); assert!(pool_state.read().transactions.is_empty()); let tx1 = Extrinsic::decode(&mut &*tx1).unwrap(); - assert_eq!(tx1.signature, None); + assert!(tx1.is_inherent()); }); } @@ -758,7 +766,7 @@ mod tests { let _tx2 = pool_state.write().transactions.pop().unwrap(); assert!(pool_state.read().transactions.is_empty()); let tx1 = Extrinsic::decode(&mut &*tx1).unwrap(); - assert_eq!(tx1.signature, None); + assert!(tx1.is_inherent()); }); } @@ -790,7 +798,7 @@ mod tests { let tx1 = pool_state.write().transactions.pop().unwrap(); assert!(pool_state.read().transactions.is_empty()); let tx1 = Extrinsic::decode(&mut &*tx1).unwrap(); - assert_eq!(tx1.signature, None); + assert!(tx1.is_inherent()); }); } } diff --git a/substrate/frame/system/src/weights.rs b/substrate/frame/system/src/weights.rs index 41807dea1c5..bd64bbf3763 100644 --- a/substrate/frame/system/src/weights.rs +++ b/substrate/frame/system/src/weights.rs @@ -15,30 +15,31 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for frame_system +//! Autogenerated weights for `frame_system` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-s7kdgajz-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// target/production/substrate +// ./target/production/substrate-node // benchmark // pallet +// --chain=dev // --steps=50 // --repeat=20 +// --pallet=frame_system +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/substrate/.git/.artifacts/bench.json -// --pallet=frame-system -// --chain=dev -// --header=./HEADER-APACHE2 -// --output=./frame/system/src/weights.rs -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/system/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -48,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for frame_system. +/// Weight functions needed for `frame_system`. pub trait WeightInfo { fn remark(b: u32, ) -> Weight; fn remark_with_event(b: u32, ) -> Weight; @@ -61,7 +62,7 @@ pub trait WeightInfo { fn apply_authorized_upgrade() -> Weight; } -/// Weights for frame_system using the Substrate node and recommended hardware. +/// Weights for `frame_system` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { /// The range of component `b` is `[0, 3932160]`. @@ -69,84 +70,86 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_004_000 picoseconds. - Weight::from_parts(2_119_000, 0) + // Minimum execution time: 2_130_000 picoseconds. + Weight::from_parts(2_976_430, 0) // Standard Error: 0 - .saturating_add(Weight::from_parts(390, 0).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(386, 0).saturating_mul(b.into())) } /// The range of component `b` is `[0, 3932160]`. fn remark_with_event(b: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_032_000 picoseconds. - Weight::from_parts(8_097_000, 0) - // Standard Error: 2 - .saturating_add(Weight::from_parts(1_455, 0).saturating_mul(b.into())) + // Minimum execution time: 5_690_000 picoseconds. + Weight::from_parts(15_071_416, 0) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_387, 0).saturating_mul(b.into())) } - /// Storage: System Digest (r:1 w:1) - /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: unknown `0x3a686561707061676573` (r:0 w:1) - /// Proof Skipped: unknown `0x3a686561707061676573` (r:0 w:1) + /// Storage: `System::Digest` (r:1 w:1) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: UNKNOWN KEY `0x3a686561707061676573` (r:0 w:1) + /// Proof: UNKNOWN KEY `0x3a686561707061676573` (r:0 w:1) fn set_heap_pages() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `1485` - // Minimum execution time: 4_446_000 picoseconds. - Weight::from_parts(4_782_000, 1485) + // Minimum execution time: 3_822_000 picoseconds. + Weight::from_parts(4_099_000, 1485) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: System Digest (r:1 w:1) - /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: unknown `0x3a636f6465` (r:0 w:1) - /// Proof Skipped: unknown `0x3a636f6465` (r:0 w:1) + /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + /// Storage: `System::Digest` (r:1 w:1) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) + /// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) fn set_code() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `1485` - // Minimum execution time: 84_000_503_000 picoseconds. - Weight::from_parts(87_586_619_000, 1485) - .saturating_add(T::DbWeight::get().reads(1_u64)) + // Measured: `142` + // Estimated: `67035` + // Minimum execution time: 81_512_045_000 picoseconds. + Weight::from_parts(82_321_281_000, 67035) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Skipped Metadata (r:0 w:0) - /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// Storage: `Skipped::Metadata` (r:0 w:0) + /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `i` is `[0, 1000]`. fn set_storage(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_086_000 picoseconds. - Weight::from_parts(2_175_000, 0) - // Standard Error: 1_056 - .saturating_add(Weight::from_parts(841_511, 0).saturating_mul(i.into())) + // Minimum execution time: 2_074_000 picoseconds. + Weight::from_parts(2_137_000, 0) + // Standard Error: 879 + .saturating_add(Weight::from_parts(797_224, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) } - /// Storage: Skipped Metadata (r:0 w:0) - /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// Storage: `Skipped::Metadata` (r:0 w:0) + /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `i` is `[0, 1000]`. fn kill_storage(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_000_000 picoseconds. - Weight::from_parts(2_255_000, 0) - // Standard Error: 1_425 - .saturating_add(Weight::from_parts(662_473, 0).saturating_mul(i.into())) + // Minimum execution time: 2_122_000 picoseconds. + Weight::from_parts(2_208_000, 0) + // Standard Error: 855 + .saturating_add(Weight::from_parts(594_034, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) } - /// Storage: Skipped Metadata (r:0 w:0) - /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// Storage: `Skipped::Metadata` (r:0 w:0) + /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `p` is `[0, 1000]`. fn kill_prefix(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `115 + p * (69 ±0)` - // Estimated: `128 + p * (70 ±0)` - // Minimum execution time: 4_189_000 picoseconds. - Weight::from_parts(4_270_000, 128) - // Standard Error: 2_296 - .saturating_add(Weight::from_parts(1_389_650, 0).saturating_mul(p.into())) + // Measured: `129 + p * (69 ±0)` + // Estimated: `135 + p * (70 ±0)` + // Minimum execution time: 3_992_000 picoseconds. + Weight::from_parts(4_170_000, 135) + // Standard Error: 1_377 + .saturating_add(Weight::from_parts(1_267_892, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) .saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into())) @@ -157,114 +160,116 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 33_027_000 picoseconds. - Weight::from_parts(33_027_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(T::DbWeight::get().writes(1)) + // Minimum execution time: 8_872_000 picoseconds. + Weight::from_parts(9_513_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `System::AuthorizedUpgrade` (r:1 w:1) /// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) + /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) /// Storage: `System::Digest` (r:1 w:1) /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) /// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) fn apply_authorized_upgrade() -> Weight { // Proof Size summary in bytes: - // Measured: `22` - // Estimated: `1518` - // Minimum execution time: 118_101_992_000 picoseconds. - Weight::from_parts(118_101_992_000, 0) - .saturating_add(Weight::from_parts(0, 1518)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(3)) + // Measured: `164` + // Estimated: `67035` + // Minimum execution time: 85_037_546_000 picoseconds. + Weight::from_parts(85_819_414_000, 67035) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { /// The range of component `b` is `[0, 3932160]`. fn remark(b: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_004_000 picoseconds. - Weight::from_parts(2_119_000, 0) + // Minimum execution time: 2_130_000 picoseconds. + Weight::from_parts(2_976_430, 0) // Standard Error: 0 - .saturating_add(Weight::from_parts(390, 0).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(386, 0).saturating_mul(b.into())) } /// The range of component `b` is `[0, 3932160]`. fn remark_with_event(b: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_032_000 picoseconds. - Weight::from_parts(8_097_000, 0) - // Standard Error: 2 - .saturating_add(Weight::from_parts(1_455, 0).saturating_mul(b.into())) + // Minimum execution time: 5_690_000 picoseconds. + Weight::from_parts(15_071_416, 0) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_387, 0).saturating_mul(b.into())) } - /// Storage: System Digest (r:1 w:1) - /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: unknown `0x3a686561707061676573` (r:0 w:1) - /// Proof Skipped: unknown `0x3a686561707061676573` (r:0 w:1) + /// Storage: `System::Digest` (r:1 w:1) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: UNKNOWN KEY `0x3a686561707061676573` (r:0 w:1) + /// Proof: UNKNOWN KEY `0x3a686561707061676573` (r:0 w:1) fn set_heap_pages() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `1485` - // Minimum execution time: 4_446_000 picoseconds. - Weight::from_parts(4_782_000, 1485) + // Minimum execution time: 3_822_000 picoseconds. + Weight::from_parts(4_099_000, 1485) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: System Digest (r:1 w:1) - /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: unknown `0x3a636f6465` (r:0 w:1) - /// Proof Skipped: unknown `0x3a636f6465` (r:0 w:1) + /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + /// Storage: `System::Digest` (r:1 w:1) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) + /// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) fn set_code() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `1485` - // Minimum execution time: 84_000_503_000 picoseconds. - Weight::from_parts(87_586_619_000, 1485) - .saturating_add(RocksDbWeight::get().reads(1_u64)) + // Measured: `142` + // Estimated: `67035` + // Minimum execution time: 81_512_045_000 picoseconds. + Weight::from_parts(82_321_281_000, 67035) + .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Skipped Metadata (r:0 w:0) - /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// Storage: `Skipped::Metadata` (r:0 w:0) + /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `i` is `[0, 1000]`. fn set_storage(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_086_000 picoseconds. - Weight::from_parts(2_175_000, 0) - // Standard Error: 1_056 - .saturating_add(Weight::from_parts(841_511, 0).saturating_mul(i.into())) + // Minimum execution time: 2_074_000 picoseconds. + Weight::from_parts(2_137_000, 0) + // Standard Error: 879 + .saturating_add(Weight::from_parts(797_224, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(i.into()))) } - /// Storage: Skipped Metadata (r:0 w:0) - /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// Storage: `Skipped::Metadata` (r:0 w:0) + /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `i` is `[0, 1000]`. fn kill_storage(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_000_000 picoseconds. - Weight::from_parts(2_255_000, 0) - // Standard Error: 1_425 - .saturating_add(Weight::from_parts(662_473, 0).saturating_mul(i.into())) + // Minimum execution time: 2_122_000 picoseconds. + Weight::from_parts(2_208_000, 0) + // Standard Error: 855 + .saturating_add(Weight::from_parts(594_034, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(i.into()))) } - /// Storage: Skipped Metadata (r:0 w:0) - /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) + /// Storage: `Skipped::Metadata` (r:0 w:0) + /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `p` is `[0, 1000]`. fn kill_prefix(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `115 + p * (69 ±0)` - // Estimated: `128 + p * (70 ±0)` - // Minimum execution time: 4_189_000 picoseconds. - Weight::from_parts(4_270_000, 128) - // Standard Error: 2_296 - .saturating_add(Weight::from_parts(1_389_650, 0).saturating_mul(p.into())) + // Measured: `129 + p * (69 ±0)` + // Estimated: `135 + p * (70 ±0)` + // Minimum execution time: 3_992_000 picoseconds. + Weight::from_parts(4_170_000, 135) + // Standard Error: 1_377 + .saturating_add(Weight::from_parts(1_267_892, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(p.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(p.into()))) .saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into())) @@ -275,25 +280,25 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 33_027_000 picoseconds. - Weight::from_parts(33_027_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(RocksDbWeight::get().writes(1)) + // Minimum execution time: 8_872_000 picoseconds. + Weight::from_parts(9_513_000, 0) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `System::AuthorizedUpgrade` (r:1 w:1) /// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) + /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) /// Storage: `System::Digest` (r:1 w:1) /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) /// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) fn apply_authorized_upgrade() -> Weight { // Proof Size summary in bytes: - // Measured: `22` - // Estimated: `1518` - // Minimum execution time: 118_101_992_000 picoseconds. - Weight::from_parts(118_101_992_000, 0) - .saturating_add(Weight::from_parts(0, 1518)) - .saturating_add(RocksDbWeight::get().reads(2)) - .saturating_add(RocksDbWeight::get().writes(3)) + // Measured: `164` + // Estimated: `67035` + // Minimum execution time: 85_037_546_000 picoseconds. + Weight::from_parts(85_819_414_000, 67035) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) } } diff --git a/substrate/frame/timestamp/src/weights.rs b/substrate/frame/timestamp/src/weights.rs index 46c54473486..2df68ba0f1e 100644 --- a/substrate/frame/timestamp/src/weights.rs +++ b/substrate/frame/timestamp/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_timestamp +//! Autogenerated weights for `pallet_timestamp` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/timestamp/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/timestamp/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,57 +49,57 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_timestamp. +/// Weight functions needed for `pallet_timestamp`. pub trait WeightInfo { fn set() -> Weight; fn on_finalize() -> Weight; } -/// Weights for pallet_timestamp using the Substrate node and recommended hardware. +/// Weights for `pallet_timestamp` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Timestamp Now (r:1 w:1) - /// Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Babe CurrentSlot (r:1 w:0) - /// Proof: Babe CurrentSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: `Timestamp::Now` (r:1 w:1) + /// Proof: `Timestamp::Now` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Babe::CurrentSlot` (r:1 w:0) + /// Proof: `Babe::CurrentSlot` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) fn set() -> Weight { // Proof Size summary in bytes: - // Measured: `312` + // Measured: `345` // Estimated: `1493` - // Minimum execution time: 9_857_000 picoseconds. - Weight::from_parts(10_492_000, 1493) + // Minimum execution time: 8_417_000 picoseconds. + Weight::from_parts(8_932_000, 1493) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } fn on_finalize() -> Weight { // Proof Size summary in bytes: - // Measured: `161` + // Measured: `194` // Estimated: `0` - // Minimum execution time: 4_175_000 picoseconds. - Weight::from_parts(4_334_000, 0) + // Minimum execution time: 3_911_000 picoseconds. + Weight::from_parts(4_092_000, 0) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Timestamp Now (r:1 w:1) - /// Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - /// Storage: Babe CurrentSlot (r:1 w:0) - /// Proof: Babe CurrentSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: `Timestamp::Now` (r:1 w:1) + /// Proof: `Timestamp::Now` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Babe::CurrentSlot` (r:1 w:0) + /// Proof: `Babe::CurrentSlot` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) fn set() -> Weight { // Proof Size summary in bytes: - // Measured: `312` + // Measured: `345` // Estimated: `1493` - // Minimum execution time: 9_857_000 picoseconds. - Weight::from_parts(10_492_000, 1493) + // Minimum execution time: 8_417_000 picoseconds. + Weight::from_parts(8_932_000, 1493) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } fn on_finalize() -> Weight { // Proof Size summary in bytes: - // Measured: `161` + // Measured: `194` // Estimated: `0` - // Minimum execution time: 4_175_000 picoseconds. - Weight::from_parts(4_334_000, 0) + // Minimum execution time: 3_911_000 picoseconds. + Weight::from_parts(4_092_000, 0) } } diff --git a/substrate/frame/tips/src/weights.rs b/substrate/frame/tips/src/weights.rs index ec622866715..dbe1ed246ff 100644 --- a/substrate/frame/tips/src/weights.rs +++ b/substrate/frame/tips/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_tips +//! Autogenerated weights for `pallet_tips` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/tips/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/tips/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_tips. +/// Weight functions needed for `pallet_tips`. pub trait WeightInfo { fn report_awesome(r: u32, ) -> Weight; fn retract_tip() -> Weight; @@ -60,220 +59,220 @@ pub trait WeightInfo { fn slash_tip(t: u32, ) -> Weight; } -/// Weights for pallet_tips using the Substrate node and recommended hardware. +/// Weights for `pallet_tips` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Tips Reasons (r:1 w:1) - /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) - /// Storage: Tips Tips (r:1 w:1) - /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: `Tips::Reasons` (r:1 w:1) + /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Tips::Tips` (r:1 w:1) + /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `r` is `[0, 300]`. fn report_awesome(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `4` // Estimated: `3469` - // Minimum execution time: 29_576_000 picoseconds. - Weight::from_parts(30_722_650, 3469) - // Standard Error: 192 - .saturating_add(Weight::from_parts(2_601, 0).saturating_mul(r.into())) + // Minimum execution time: 25_145_000 picoseconds. + Weight::from_parts(26_085_800, 3469) + // Standard Error: 216 + .saturating_add(Weight::from_parts(5_121, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Tips Tips (r:1 w:1) - /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) - /// Storage: Tips Reasons (r:0 w:1) - /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// Storage: `Tips::Tips` (r:1 w:1) + /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Tips::Reasons` (r:0 w:1) + /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) fn retract_tip() -> Weight { // Proof Size summary in bytes: // Measured: `221` // Estimated: `3686` - // Minimum execution time: 28_522_000 picoseconds. - Weight::from_parts(29_323_000, 3686) + // Minimum execution time: 25_302_000 picoseconds. + Weight::from_parts(26_229_000, 3686) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Elections Members (r:1 w:0) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Tips Reasons (r:1 w:1) - /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) - /// Storage: Tips Tips (r:0 w:1) - /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: `Elections::Members` (r:1 w:0) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Tips::Reasons` (r:1 w:1) + /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Tips::Tips` (r:0 w:1) + /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `r` is `[0, 300]`. /// The range of component `t` is `[1, 13]`. fn tip_new(r: u32, t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `526 + t * (64 ±0)` // Estimated: `3991 + t * (64 ±0)` - // Minimum execution time: 19_650_000 picoseconds. - Weight::from_parts(19_837_982, 3991) - // Standard Error: 151 - .saturating_add(Weight::from_parts(1_746, 0).saturating_mul(r.into())) - // Standard Error: 3_588 - .saturating_add(Weight::from_parts(102_359, 0).saturating_mul(t.into())) + // Minimum execution time: 16_600_000 picoseconds. + Weight::from_parts(17_071_638, 3991) + // Standard Error: 131 + .saturating_add(Weight::from_parts(1_138, 0).saturating_mul(r.into())) + // Standard Error: 3_125 + .saturating_add(Weight::from_parts(82_996, 0).saturating_mul(t.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(t.into())) } - /// Storage: Elections Members (r:1 w:0) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Tips Tips (r:1 w:1) - /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: `Elections::Members` (r:1 w:0) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Tips::Tips` (r:1 w:1) + /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `t` is `[1, 13]`. fn tip(t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `747 + t * (112 ±0)` // Estimated: `4212 + t * (112 ±0)` - // Minimum execution time: 15_641_000 picoseconds. - Weight::from_parts(15_745_460, 4212) - // Standard Error: 5_106 - .saturating_add(Weight::from_parts(229_475, 0).saturating_mul(t.into())) + // Minimum execution time: 13_972_000 picoseconds. + Weight::from_parts(14_269_356, 4212) + // Standard Error: 4_695 + .saturating_add(Weight::from_parts(205_433, 0).saturating_mul(t.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(t.into())) } - /// Storage: Tips Tips (r:1 w:1) - /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) - /// Storage: Elections Members (r:1 w:0) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Tips Reasons (r:0 w:1) - /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// Storage: `Tips::Tips` (r:1 w:1) + /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Members` (r:1 w:0) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Tips::Reasons` (r:0 w:1) + /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `t` is `[1, 13]`. fn close_tip(t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `786 + t * (112 ±0)` // Estimated: `4242 + t * (112 ±0)` - // Minimum execution time: 62_059_000 picoseconds. - Weight::from_parts(64_604_554, 4242) - // Standard Error: 11_818 - .saturating_add(Weight::from_parts(116_297, 0).saturating_mul(t.into())) + // Minimum execution time: 51_878_000 picoseconds. + Weight::from_parts(54_513_477, 4242) + // Standard Error: 12_281 + .saturating_add(Weight::from_parts(126_605, 0).saturating_mul(t.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(t.into())) } - /// Storage: Tips Tips (r:1 w:1) - /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) - /// Storage: Tips Reasons (r:0 w:1) - /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// Storage: `Tips::Tips` (r:1 w:1) + /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Tips::Reasons` (r:0 w:1) + /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `t` is `[1, 13]`. fn slash_tip(t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `269` // Estimated: `3734` - // Minimum execution time: 14_133_000 picoseconds. - Weight::from_parts(14_957_547, 3734) - // Standard Error: 2_765 - .saturating_add(Weight::from_parts(22_138, 0).saturating_mul(t.into())) + // Minimum execution time: 11_800_000 picoseconds. + Weight::from_parts(12_520_984, 3734) + // Standard Error: 2_360 + .saturating_add(Weight::from_parts(28_777, 0).saturating_mul(t.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Tips Reasons (r:1 w:1) - /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) - /// Storage: Tips Tips (r:1 w:1) - /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: `Tips::Reasons` (r:1 w:1) + /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Tips::Tips` (r:1 w:1) + /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `r` is `[0, 300]`. fn report_awesome(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `4` // Estimated: `3469` - // Minimum execution time: 29_576_000 picoseconds. - Weight::from_parts(30_722_650, 3469) - // Standard Error: 192 - .saturating_add(Weight::from_parts(2_601, 0).saturating_mul(r.into())) + // Minimum execution time: 25_145_000 picoseconds. + Weight::from_parts(26_085_800, 3469) + // Standard Error: 216 + .saturating_add(Weight::from_parts(5_121, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Tips Tips (r:1 w:1) - /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) - /// Storage: Tips Reasons (r:0 w:1) - /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// Storage: `Tips::Tips` (r:1 w:1) + /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Tips::Reasons` (r:0 w:1) + /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) fn retract_tip() -> Weight { // Proof Size summary in bytes: // Measured: `221` // Estimated: `3686` - // Minimum execution time: 28_522_000 picoseconds. - Weight::from_parts(29_323_000, 3686) + // Minimum execution time: 25_302_000 picoseconds. + Weight::from_parts(26_229_000, 3686) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Elections Members (r:1 w:0) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Tips Reasons (r:1 w:1) - /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) - /// Storage: Tips Tips (r:0 w:1) - /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: `Elections::Members` (r:1 w:0) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Tips::Reasons` (r:1 w:1) + /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Tips::Tips` (r:0 w:1) + /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `r` is `[0, 300]`. /// The range of component `t` is `[1, 13]`. fn tip_new(r: u32, t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `526 + t * (64 ±0)` // Estimated: `3991 + t * (64 ±0)` - // Minimum execution time: 19_650_000 picoseconds. - Weight::from_parts(19_837_982, 3991) - // Standard Error: 151 - .saturating_add(Weight::from_parts(1_746, 0).saturating_mul(r.into())) - // Standard Error: 3_588 - .saturating_add(Weight::from_parts(102_359, 0).saturating_mul(t.into())) + // Minimum execution time: 16_600_000 picoseconds. + Weight::from_parts(17_071_638, 3991) + // Standard Error: 131 + .saturating_add(Weight::from_parts(1_138, 0).saturating_mul(r.into())) + // Standard Error: 3_125 + .saturating_add(Weight::from_parts(82_996, 0).saturating_mul(t.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(t.into())) } - /// Storage: Elections Members (r:1 w:0) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Tips Tips (r:1 w:1) - /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: `Elections::Members` (r:1 w:0) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Tips::Tips` (r:1 w:1) + /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `t` is `[1, 13]`. fn tip(t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `747 + t * (112 ±0)` // Estimated: `4212 + t * (112 ±0)` - // Minimum execution time: 15_641_000 picoseconds. - Weight::from_parts(15_745_460, 4212) - // Standard Error: 5_106 - .saturating_add(Weight::from_parts(229_475, 0).saturating_mul(t.into())) + // Minimum execution time: 13_972_000 picoseconds. + Weight::from_parts(14_269_356, 4212) + // Standard Error: 4_695 + .saturating_add(Weight::from_parts(205_433, 0).saturating_mul(t.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(t.into())) } - /// Storage: Tips Tips (r:1 w:1) - /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) - /// Storage: Elections Members (r:1 w:0) - /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Tips Reasons (r:0 w:1) - /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// Storage: `Tips::Tips` (r:1 w:1) + /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Elections::Members` (r:1 w:0) + /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Tips::Reasons` (r:0 w:1) + /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `t` is `[1, 13]`. fn close_tip(t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `786 + t * (112 ±0)` // Estimated: `4242 + t * (112 ±0)` - // Minimum execution time: 62_059_000 picoseconds. - Weight::from_parts(64_604_554, 4242) - // Standard Error: 11_818 - .saturating_add(Weight::from_parts(116_297, 0).saturating_mul(t.into())) + // Minimum execution time: 51_878_000 picoseconds. + Weight::from_parts(54_513_477, 4242) + // Standard Error: 12_281 + .saturating_add(Weight::from_parts(126_605, 0).saturating_mul(t.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(t.into())) } - /// Storage: Tips Tips (r:1 w:1) - /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) - /// Storage: Tips Reasons (r:0 w:1) - /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// Storage: `Tips::Tips` (r:1 w:1) + /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Tips::Reasons` (r:0 w:1) + /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `t` is `[1, 13]`. fn slash_tip(t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `269` // Estimated: `3734` - // Minimum execution time: 14_133_000 picoseconds. - Weight::from_parts(14_957_547, 3734) - // Standard Error: 2_765 - .saturating_add(Weight::from_parts(22_138, 0).saturating_mul(t.into())) + // Minimum execution time: 11_800_000 picoseconds. + Weight::from_parts(12_520_984, 3734) + // Standard Error: 2_360 + .saturating_add(Weight::from_parts(28_777, 0).saturating_mul(t.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } diff --git a/substrate/frame/transaction-payment/Cargo.toml b/substrate/frame/transaction-payment/Cargo.toml index 275e1c01f92..66e0bef1436 100644 --- a/substrate/frame/transaction-payment/Cargo.toml +++ b/substrate/frame/transaction-payment/Cargo.toml @@ -21,6 +21,7 @@ codec = { package = "parity-scale-codec", version = "3.6.1", default-features = ] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } serde = { optional = true, workspace = true, default-features = true } +frame-benchmarking = { path = "../benchmarking", default-features = false, optional = true } frame-support = { path = "../support", default-features = false } frame-system = { path = "../system", default-features = false } sp-core = { path = "../../primitives/core", default-features = false } @@ -36,6 +37,7 @@ pallet-balances = { path = "../balances" } default = ["std"] std = [ "codec/std", + "frame-benchmarking?/std", "frame-support/std", "frame-system/std", "pallet-balances/std", @@ -46,6 +48,13 @@ std = [ "sp-runtime/std", "sp-std/std", ] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/Cargo.toml b/substrate/frame/transaction-payment/asset-conversion-tx-payment/Cargo.toml index 7640cc815e5..528f29e8e4a 100644 --- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/Cargo.toml +++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/Cargo.toml @@ -19,6 +19,7 @@ targets = ["x86_64-unknown-linux-gnu"] # Substrate dependencies sp-runtime = { path = "../../../primitives/runtime", default-features = false } sp-std = { path = "../../../primitives/std", default-features = false } +frame-benchmarking = { path = "../../benchmarking", default-features = false, optional = true } frame-support = { path = "../../support", default-features = false } frame-system = { path = "../../system", default-features = false } pallet-asset-conversion = { path = "../../asset-conversion", default-features = false } @@ -37,6 +38,7 @@ pallet-balances = { path = "../../balances" } default = ["std"] std = [ "codec/std", + "frame-benchmarking?/std", "frame-support/std", "frame-system/std", "pallet-asset-conversion/std", @@ -50,6 +52,16 @@ std = [ "sp-std/std", "sp-storage/std", ] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-asset-conversion/runtime-benchmarks", + "pallet-assets/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/README.md b/substrate/frame/transaction-payment/asset-conversion-tx-payment/README.md index eccba773673..fcd1527526e 100644 --- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/README.md +++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/README.md @@ -16,6 +16,6 @@ asset. ### Integration This pallet wraps FRAME's transaction payment pallet and functions as a replacement. This means you should include both pallets in your `construct_runtime` macro, but only include this -pallet's [`SignedExtension`] ([`ChargeAssetTxPayment`]). +pallet's [`TransactionExtension`] ([`ChargeAssetTxPayment`]). License: Apache-2.0 diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/benchmarking.rs b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/benchmarking.rs new file mode 100644 index 00000000000..0bffb991e4a --- /dev/null +++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/benchmarking.rs @@ -0,0 +1,125 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Benchmarks for Asset Conversion Tx Payment Pallet's transaction extension + +use super::*; +use crate::Pallet; +use frame_benchmarking::v2::*; +use frame_support::{ + dispatch::{DispatchInfo, PostDispatchInfo}, + pallet_prelude::*, +}; +use frame_system::RawOrigin; +use sp_runtime::traits::{AsSystemOriginSigner, DispatchTransaction, Dispatchable}; + +#[benchmarks(where + T::RuntimeCall: Dispatchable, + AssetBalanceOf: Send + Sync, + BalanceOf: Send + + Sync + + From + + Into> + + Into> + + From>, + ChargeAssetIdOf: Send + Sync + Default, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, +)] +mod benchmarks { + use super::*; + + #[benchmark] + fn charge_asset_tx_payment_zero() { + let caller: T::AccountId = whitelisted_caller(); + let ext: ChargeAssetTxPayment = ChargeAssetTxPayment::from(0u64.into(), None); + let inner = frame_system::Call::remark { remark: vec![] }; + let call = T::RuntimeCall::from(inner); + let info = DispatchInfo { + weight: Weight::zero(), + class: DispatchClass::Normal, + pays_fee: Pays::No, + }; + let post_info = PostDispatchInfo { actual_weight: None, pays_fee: Pays::No }; + #[block] + { + assert!(ext + .test_run(RawOrigin::Signed(caller).into(), &call, &info, 0, |_| Ok(post_info)) + .unwrap() + .is_ok()); + } + } + + #[benchmark] + fn charge_asset_tx_payment_native() { + let caller: T::AccountId = whitelisted_caller(); + let (fun_asset_id, _) = ::BenchmarkHelper::create_asset_id_parameter(1); + ::BenchmarkHelper::setup_balances_and_pool(fun_asset_id, caller.clone()); + let ext: ChargeAssetTxPayment = ChargeAssetTxPayment::from(10u64.into(), None); + let inner = frame_system::Call::remark { remark: vec![] }; + let call = T::RuntimeCall::from(inner); + let info = DispatchInfo { + weight: Weight::from_parts(10, 0), + class: DispatchClass::Operational, + pays_fee: Pays::Yes, + }; + let post_info = PostDispatchInfo { + actual_weight: Some(Weight::from_parts(10, 0)), + pays_fee: Pays::Yes, + }; + + #[block] + { + assert!(ext + .test_run(RawOrigin::Signed(caller).into(), &call, &info, 0, |_| Ok(post_info)) + .unwrap() + .is_ok()); + } + } + + #[benchmark] + fn charge_asset_tx_payment_asset() { + let caller: T::AccountId = whitelisted_caller(); + let (fun_asset_id, asset_id) = ::BenchmarkHelper::create_asset_id_parameter(1); + ::BenchmarkHelper::setup_balances_and_pool(fun_asset_id, caller.clone()); + + let tip = 10u64.into(); + let ext: ChargeAssetTxPayment = ChargeAssetTxPayment::from(tip, Some(asset_id)); + let inner = frame_system::Call::remark { remark: vec![] }; + let call = T::RuntimeCall::from(inner); + let info = DispatchInfo { + weight: Weight::from_parts(10, 0), + class: DispatchClass::Operational, + pays_fee: Pays::Yes, + }; + let post_info = PostDispatchInfo { + actual_weight: Some(Weight::from_parts(10, 0)), + pays_fee: Pays::Yes, + }; + + #[block] + { + assert!(ext + .test_run(RawOrigin::Signed(caller.clone()).into(), &call, &info, 0, |_| Ok( + post_info + )) + .unwrap() + .is_ok()); + } + } + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Runtime); +} diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/lib.rs b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/lib.rs index ed0ed56e6e0..8ef7c2ba38e 100644 --- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/lib.rs +++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/lib.rs @@ -20,8 +20,8 @@ //! //! ## Overview //! -//! This pallet provides a `SignedExtension` with an optional `AssetId` that specifies the asset -//! to be used for payment (defaulting to the native token on `None`). It expects an +//! This pallet provides a `TransactionExtension` with an optional `AssetId` that specifies the +//! asset to be used for payment (defaulting to the native token on `None`). It expects an //! [`OnChargeAssetTransaction`] implementation analogous to [`pallet-transaction-payment`]. The //! included [`AssetConversionAdapter`] (implementing [`OnChargeAssetTransaction`]) determines the //! fee amount by converting the fee calculated by [`pallet-transaction-payment`] in the native @@ -31,7 +31,7 @@ //! //! This pallet does not have any dispatchable calls or storage. It wraps FRAME's Transaction //! Payment pallet and functions as a replacement. This means you should include both pallets in -//! your `construct_runtime` macro, but only include this pallet's [`SignedExtension`] +//! your `construct_runtime` macro, but only include this pallet's [`TransactionExtension`] //! ([`ChargeAssetTxPayment`]). //! //! ## Terminology @@ -53,23 +53,29 @@ use frame_support::{ }, DefaultNoBound, }; -use pallet_transaction_payment::OnChargeTransaction; +use pallet_transaction_payment::{ChargeTransactionPayment, OnChargeTransaction}; use scale_info::TypeInfo; use sp_runtime::{ - traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf, SignedExtension, Zero}, - transaction_validity::{ - InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction, + traits::{ + AsSystemOriginSigner, DispatchInfoOf, Dispatchable, PostDispatchInfoOf, + TransactionExtension, TransactionExtensionBase, ValidateResult, Zero, }, + transaction_validity::{InvalidTransaction, TransactionValidityError, ValidTransaction}, }; #[cfg(test)] mod mock; #[cfg(test)] mod tests; +pub mod weights; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; mod payment; -use frame_support::traits::tokens::AssetId; +use frame_support::{pallet_prelude::Weight, traits::tokens::AssetId}; pub use payment::*; +pub use weights::WeightInfo; /// Type aliases used for interaction with `OnChargeTransaction`. pub(crate) type OnChargeTransactionOf = @@ -125,11 +131,30 @@ pub mod pallet { type Fungibles: Balanced; /// The actual transaction charging logic that charges the fees. type OnChargeAssetTransaction: OnChargeAssetTransaction; + /// The weight information of this pallet. + type WeightInfo: WeightInfo; + #[cfg(feature = "runtime-benchmarks")] + /// Benchmark helper + type BenchmarkHelper: BenchmarkHelperTrait< + Self::AccountId, + <::Fungibles as Inspect>::AssetId, + <::OnChargeAssetTransaction as OnChargeAssetTransaction>::AssetId, + >; } #[pallet::pallet] pub struct Pallet(_); + #[cfg(feature = "runtime-benchmarks")] + /// Helper trait to benchmark the `ChargeAssetTxPayment` transaction extension. + pub trait BenchmarkHelperTrait { + /// Returns the `AssetId` to be used in the liquidity pool by the benchmarking code. + fn create_asset_id_parameter(id: u32) -> (FunAssetIdParameter, AssetIdParameter); + /// Create a liquidity pool for a given asset and sufficiently endow accounts to benchmark + /// the extension. + fn setup_balances_and_pool(asset_id: FunAssetIdParameter, account: AccountId); + } + #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { @@ -179,9 +204,8 @@ where who: &T::AccountId, call: &T::RuntimeCall, info: &DispatchInfoOf, - len: usize, + fee: BalanceOf, ) -> Result<(BalanceOf, InitialPayment), TransactionValidityError> { - let fee = pallet_transaction_payment::Pallet::::compute_fee(len as u32, info, self.tip); debug_assert!(self.tip <= fee, "tip should be included in the computed fee"); if fee.is_zero() { Ok((fee, InitialPayment::Nothing)) @@ -225,9 +249,8 @@ impl sp_std::fmt::Debug for ChargeAssetTxPayment { } } -impl SignedExtension for ChargeAssetTxPayment +impl TransactionExtensionBase for ChargeAssetTxPayment where - T::RuntimeCall: Dispatchable, AssetBalanceOf: Send + Sync, BalanceOf: Send + Sync @@ -238,109 +261,145 @@ where ChargeAssetIdOf: Send + Sync, { const IDENTIFIER: &'static str = "ChargeAssetTxPayment"; - type AccountId = T::AccountId; - type Call = T::RuntimeCall; - type AdditionalSigned = (); + type Implicit = (); + + fn weight(&self) -> Weight { + if self.asset_id.is_some() { + ::WeightInfo::charge_asset_tx_payment_asset() + } else { + ::WeightInfo::charge_asset_tx_payment_native() + } + } +} + +impl TransactionExtension for ChargeAssetTxPayment +where + T::RuntimeCall: Dispatchable, + AssetBalanceOf: Send + Sync, + BalanceOf: Send + + Sync + + From + + Into> + + Into> + + From>, + ChargeAssetIdOf: Send + Sync, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, +{ + type Val = ( + // tip + BalanceOf, + // who paid the fee + T::AccountId, + // transaction fee + BalanceOf, + ); type Pre = ( // tip BalanceOf, // who paid the fee - Self::AccountId, + T::AccountId, // imbalance resulting from withdrawing the fee InitialPayment, // asset_id for the transaction payment Option>, ); - fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { - Ok(()) - } - fn validate( &self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, + origin: ::RuntimeOrigin, + _call: &T::RuntimeCall, + info: &DispatchInfoOf, len: usize, - ) -> TransactionValidity { - use pallet_transaction_payment::ChargeTransactionPayment; - let (fee, _) = self.withdraw_fee(who, call, info, len)?; + _context: &mut Context, + _self_implicit: Self::Implicit, + _inherited_implication: &impl Encode, + ) -> ValidateResult { + let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?; + // Non-mutating call of `compute_fee` to calculate the fee used in the transaction priority. + let fee = pallet_transaction_payment::Pallet::::compute_fee(len as u32, info, self.tip); let priority = ChargeTransactionPayment::::get_priority(info, len, self.tip, fee); - Ok(ValidTransaction { priority, ..Default::default() }) + let validity = ValidTransaction { priority, ..Default::default() }; + let val = (self.tip, who.clone(), fee); + Ok((validity, val, origin)) } - fn pre_dispatch( + fn prepare( self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, - len: usize, + val: Self::Val, + _origin: &::RuntimeOrigin, + call: &T::RuntimeCall, + info: &DispatchInfoOf, + _len: usize, + _context: &Context, ) -> Result { - let (_fee, initial_payment) = self.withdraw_fee(who, call, info, len)?; - Ok((self.tip, who.clone(), initial_payment, self.asset_id)) + let (tip, who, fee) = val; + // Mutating call of `withdraw_fee` to actually charge for the transaction. + let (_fee, initial_payment) = self.withdraw_fee(&who, call, info, fee)?; + Ok((tip, who, initial_payment, self.asset_id.clone())) } fn post_dispatch( - pre: Option, - info: &DispatchInfoOf, - post_info: &PostDispatchInfoOf, + pre: Self::Pre, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, len: usize, result: &DispatchResult, + _context: &Context, ) -> Result<(), TransactionValidityError> { - if let Some((tip, who, initial_payment, asset_id)) = pre { - match initial_payment { - InitialPayment::Native(already_withdrawn) => { - debug_assert!( - asset_id.is_none(), - "For that payment type the `asset_id` should be None" - ); - pallet_transaction_payment::ChargeTransactionPayment::::post_dispatch( - Some((tip, who, already_withdrawn)), + let (tip, who, initial_payment, asset_id) = pre; + match initial_payment { + InitialPayment::Native(already_withdrawn) => { + debug_assert!( + asset_id.is_none(), + "For that payment type the `asset_id` should be None" + ); + pallet_transaction_payment::ChargeTransactionPayment::::post_dispatch( + (tip, who, already_withdrawn), + info, + post_info, + len, + result, + &(), + )?; + }, + InitialPayment::Asset(already_withdrawn) => { + debug_assert!( + asset_id.is_some(), + "For that payment type the `asset_id` should be set" + ); + let actual_fee = pallet_transaction_payment::Pallet::::compute_actual_fee( + len as u32, info, post_info, tip, + ); + + if let Some(asset_id) = asset_id { + let (used_for_fee, received_exchanged, asset_consumed) = already_withdrawn; + let converted_fee = T::OnChargeAssetTransaction::correct_and_deposit_fee( + &who, info, post_info, - len, - result, + actual_fee.into(), + tip.into(), + used_for_fee.into(), + received_exchanged.into(), + asset_id.clone(), + asset_consumed.into(), )?; - }, - InitialPayment::Asset(already_withdrawn) => { - debug_assert!( - asset_id.is_some(), - "For that payment type the `asset_id` should be set" - ); - let actual_fee = pallet_transaction_payment::Pallet::::compute_actual_fee( - len as u32, info, post_info, tip, - ); - - if let Some(asset_id) = asset_id { - let (used_for_fee, received_exchanged, asset_consumed) = already_withdrawn; - let converted_fee = T::OnChargeAssetTransaction::correct_and_deposit_fee( - &who, - info, - post_info, - actual_fee.into(), - tip.into(), - used_for_fee.into(), - received_exchanged.into(), - asset_id.clone(), - asset_consumed.into(), - )?; - Pallet::::deposit_event(Event::::AssetTxFeePaid { - who, - actual_fee: converted_fee, - tip, - asset_id, - }); - } - }, - InitialPayment::Nothing => { - // `actual_fee` should be zero here for any signed extrinsic. It would be - // non-zero here in case of unsigned extrinsics as they don't pay fees but - // `compute_actual_fee` is not aware of them. In both cases it's fine to just - // move ahead without adjusting the fee, though, so we do nothing. - debug_assert!(tip.is_zero(), "tip should be zero if initial fee was zero."); - }, - } + Pallet::::deposit_event(Event::::AssetTxFeePaid { + who, + actual_fee: converted_fee, + tip, + asset_id, + }); + } + }, + InitialPayment::Nothing => { + // `actual_fee` should be zero here for any signed extrinsic. It would be + // non-zero here in case of unsigned extrinsics as they don't pay fees but + // `compute_actual_fee` is not aware of them. In both cases it's fine to just + // move ahead without adjusting the fee, though, so we do nothing. + debug_assert!(tip.is_zero(), "tip should be zero if initial fee was zero."); + }, } Ok(()) diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs index c8bf2eb8f44..853753d41cf 100644 --- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs +++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs @@ -168,12 +168,12 @@ impl OnUnbalanced> for DealWithFees } } +#[derive_impl(pallet_transaction_payment::config_preludes::TestDefaultConfig as pallet_transaction_payment::DefaultConfig)] impl pallet_transaction_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; type OnChargeTransaction = CurrencyAdapter; type WeightToFee = WeightToFee; type LengthToFee = TransactionByteFee; - type FeeMultiplierUpdate = (); type OperationalFeeMultiplier = ConstU8<5>; } @@ -269,4 +269,72 @@ impl Config for Runtime { type RuntimeEvent = RuntimeEvent; type Fungibles = Assets; type OnChargeAssetTransaction = AssetConversionAdapter; + type WeightInfo = (); + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = Helper; +} + +#[cfg(feature = "runtime-benchmarks")] +pub fn new_test_ext() -> sp_io::TestExternalities { + let base_weight = 5; + let balance_factor = 100; + crate::tests::ExtBuilder::default() + .balance_factor(balance_factor) + .base_weight(Weight::from_parts(base_weight, 0)) + .build() +} + +#[cfg(feature = "runtime-benchmarks")] +pub struct Helper; + +#[cfg(feature = "runtime-benchmarks")] +impl BenchmarkHelperTrait for Helper { + fn create_asset_id_parameter(id: u32) -> (u32, u32) { + (id, id) + } + + fn setup_balances_and_pool(asset_id: u32, account: u64) { + use frame_support::{assert_ok, traits::fungibles::Mutate}; + use sp_runtime::traits::StaticLookup; + assert_ok!(Assets::force_create( + RuntimeOrigin::root(), + asset_id.into(), + 42, /* owner */ + true, /* is_sufficient */ + 1, + )); + + let lp_provider = 12; + assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), lp_provider, u64::MAX / 2)); + let lp_provider_account = ::Lookup::unlookup(lp_provider); + assert_ok!(Assets::mint_into(asset_id.into(), &lp_provider_account, u64::MAX / 2)); + + let token_1 = Box::new(NativeOrWithId::Native); + let token_2 = Box::new(NativeOrWithId::WithId(asset_id)); + assert_ok!(AssetConversion::create_pool( + RuntimeOrigin::signed(lp_provider), + token_1.clone(), + token_2.clone() + )); + + assert_ok!(AssetConversion::add_liquidity( + RuntimeOrigin::signed(lp_provider), + token_1, + token_2, + (u32::MAX / 8).into(), // 1 desired + u32::MAX.into(), // 2 desired + 1, // 1 min + 1, // 2 min + lp_provider_account, + )); + + use frame_support::traits::Currency; + let _ = Balances::deposit_creating(&account, u32::MAX.into()); + + let beneficiary = ::Lookup::unlookup(account); + let balance = 1000; + + assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance)); + assert_eq!(Assets::balance(asset_id, account), balance); + } } diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/tests.rs b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/tests.rs index 62faed269d3..619077c0a5e 100644 --- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/tests.rs +++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/tests.rs @@ -28,7 +28,10 @@ use frame_support::{ use frame_system as system; use mock::{ExtrinsicBaseWeight, *}; use pallet_balances::Call as BalancesCall; -use sp_runtime::{traits::StaticLookup, BuildStorage}; +use sp_runtime::{ + traits::{DispatchTransaction, StaticLookup}, + BuildStorage, +}; const CALL: &::RuntimeCall = &RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 2, value: 69 }); @@ -160,33 +163,35 @@ fn transaction_payment_in_native_possible() { .build() .execute_with(|| { let len = 10; - let pre = ChargeAssetTxPayment::::from(0, None) - .pre_dispatch(&1, CALL, &info_from_weight(WEIGHT_5), len) + let (pre, _) = ChargeAssetTxPayment::::from(0, None) + .validate_and_prepare(Some(1).into(), CALL, &info_from_weight(WEIGHT_5), len) .unwrap(); let initial_balance = 10 * balance_factor; assert_eq!(Balances::free_balance(1), initial_balance - 5 - 5 - 10); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - Some(pre), + pre, &info_from_weight(WEIGHT_5), &default_post_info(), len, - &Ok(()) + &Ok(()), + &() )); assert_eq!(Balances::free_balance(1), initial_balance - 5 - 5 - 10); - let pre = ChargeAssetTxPayment::::from(5 /* tipped */, None) - .pre_dispatch(&2, CALL, &info_from_weight(WEIGHT_100), len) + let (pre, _) = ChargeAssetTxPayment::::from(5 /* tipped */, None) + .validate_and_prepare(Some(2).into(), CALL, &info_from_weight(WEIGHT_100), len) .unwrap(); let initial_balance_for_2 = 20 * balance_factor; assert_eq!(Balances::free_balance(2), initial_balance_for_2 - 5 - 10 - 100 - 5); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - Some(pre), + pre, &info_from_weight(WEIGHT_100), &post_info_from_weight(WEIGHT_50), len, - &Ok(()) + &Ok(()), + &() )); assert_eq!(Balances::free_balance(2), initial_balance_for_2 - 5 - 10 - 50 - 5); }); @@ -237,8 +242,8 @@ fn transaction_payment_in_asset_possible() { let fee_in_asset = input_quote.unwrap(); assert_eq!(Assets::balance(asset_id, caller), balance); - let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .pre_dispatch(&caller, CALL, &info_from_weight(WEIGHT_5), len) + let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .validate_and_prepare(Some(caller).into(), CALL, &info_from_weight(WEIGHT_5), len) .unwrap(); // assert that native balance is not used assert_eq!(Balances::free_balance(caller), 10 * balance_factor); @@ -247,11 +252,12 @@ fn transaction_payment_in_asset_possible() { assert_eq!(Assets::balance(asset_id, caller), balance - fee_in_asset); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - Some(pre), + pre, &info_from_weight(WEIGHT_5), // estimated tx weight &default_post_info(), // weight actually used == estimated len, - &Ok(()) + &Ok(()), + &() )); assert_eq!(Assets::balance(asset_id, caller), balance - fee_in_asset); @@ -289,12 +295,8 @@ fn transaction_payment_in_asset_fails_if_no_pool_for_that_asset() { assert_eq!(Assets::balance(asset_id, caller), balance); let len = 10; - let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)).pre_dispatch( - &caller, - CALL, - &info_from_weight(WEIGHT_5), - len, - ); + let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .validate_and_prepare(Some(caller).into(), CALL, &info_from_weight(WEIGHT_5), len); // As there is no pool in the dex set up for this asset, conversion should fail. assert!(pre.is_err()); @@ -344,8 +346,8 @@ fn transaction_payment_without_fee() { assert_eq!(input_quote, Some(201)); let fee_in_asset = input_quote.unwrap(); - let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .pre_dispatch(&caller, CALL, &info_from_weight(WEIGHT_5), len) + let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .validate_and_prepare(Some(caller).into(), CALL, &info_from_weight(WEIGHT_5), len) .unwrap(); // assert that native balance is not used @@ -363,11 +365,12 @@ fn transaction_payment_without_fee() { assert_eq!(refund, 199); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - Some(pre), + pre, &info_from_weight(WEIGHT_5), &post_info_from_pays(Pays::No), len, - &Ok(()) + &Ok(()), + &() )); // caller should get refunded @@ -419,8 +422,8 @@ fn asset_transaction_payment_with_tip_and_refund() { assert_eq!(input_quote, Some(1206)); let fee_in_asset = input_quote.unwrap(); - let pre = ChargeAssetTxPayment::::from(tip, Some(asset_id)) - .pre_dispatch(&caller, CALL, &info_from_weight(WEIGHT_100), len) + let (pre, _) = ChargeAssetTxPayment::::from(tip, Some(asset_id)) + .validate_and_prepare(Some(caller).into(), CALL, &info_from_weight(WEIGHT_100), len) .unwrap(); assert_eq!(Assets::balance(asset_id, caller), balance - fee_in_asset); @@ -435,11 +438,12 @@ fn asset_transaction_payment_with_tip_and_refund() { .unwrap(); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - Some(pre), + pre, &info_from_weight(WEIGHT_100), &post_info_from_weight(WEIGHT_50), len, - &Ok(()) + &Ok(()), + &() )); assert_eq!(TipUnbalancedAmount::get(), tip); @@ -500,8 +504,8 @@ fn payment_from_account_with_only_assets() { .unwrap(); assert_eq!(fee_in_asset, 301); - let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .pre_dispatch(&caller, CALL, &info_from_weight(WEIGHT_5), len) + let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .validate_and_prepare(Some(caller).into(), CALL, &info_from_weight(WEIGHT_5), len) .unwrap(); assert_eq!(Balances::free_balance(caller), ed); // check that fee was charged in the given asset @@ -516,11 +520,12 @@ fn payment_from_account_with_only_assets() { .unwrap(); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - Some(pre), + pre, &info_from_weight(WEIGHT_5), &default_post_info(), len, - &Ok(()) + &Ok(()), + &() )); assert_eq!(Assets::balance(asset_id, caller), balance - fee_in_asset + refund); assert_eq!(Balances::free_balance(caller), 0); @@ -565,18 +570,19 @@ fn converted_fee_is_never_zero_if_input_fee_is_not() { // there will be no conversion when the fee is zero { - let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .pre_dispatch(&caller, CALL, &info_from_pays(Pays::No), len) + let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .validate_and_prepare(Some(caller).into(), CALL, &info_from_pays(Pays::No), len) .unwrap(); // `Pays::No` implies there are no fees assert_eq!(Assets::balance(asset_id, caller), balance); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - Some(pre), + pre, &info_from_pays(Pays::No), &post_info_from_pays(Pays::No), len, - &Ok(()) + &Ok(()), + &() )); assert_eq!(Assets::balance(asset_id, caller), balance); } @@ -591,17 +597,23 @@ fn converted_fee_is_never_zero_if_input_fee_is_not() { ) .unwrap(); - let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len) + let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .validate_and_prepare( + Some(caller).into(), + CALL, + &info_from_weight(Weight::from_parts(weight, 0)), + len, + ) .unwrap(); assert_eq!(Assets::balance(asset_id, caller), balance - fee_in_asset); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - Some(pre), + pre, &info_from_weight(Weight::from_parts(weight, 0)), &default_post_info(), len, - &Ok(()) + &Ok(()), + &() )); assert_eq!(Assets::balance(asset_id, caller), balance - fee_in_asset); }); @@ -641,8 +653,8 @@ fn post_dispatch_fee_is_zero_if_pre_dispatch_fee_is_zero() { // calculated fee is greater than 0 assert!(fee > 0); - let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .pre_dispatch(&caller, CALL, &info_from_pays(Pays::No), len) + let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .validate_and_prepare(Some(caller).into(), CALL, &info_from_pays(Pays::No), len) .unwrap(); // `Pays::No` implies no pre-dispatch fees @@ -658,62 +670,12 @@ fn post_dispatch_fee_is_zero_if_pre_dispatch_fee_is_zero() { // `Pays::Yes` on post-dispatch does not mean we pay (we never charge more than the // initial fee) assert_ok!(ChargeAssetTxPayment::::post_dispatch( - Some(pre), + pre, &info_from_pays(Pays::No), &post_info_from_pays(Pays::Yes), len, - &Ok(()) - )); - assert_eq!(Assets::balance(asset_id, caller), balance); - }); -} - -#[test] -fn post_dispatch_fee_is_zero_if_unsigned_pre_dispatch_fee_is_zero() { - let base_weight = 1; - ExtBuilder::default() - .balance_factor(100) - .base_weight(Weight::from_parts(base_weight, 0)) - .build() - .execute_with(|| { - // create the asset - let asset_id = 1; - let min_balance = 100; - assert_ok!(Assets::force_create( - RuntimeOrigin::root(), - asset_id.into(), - 42, /* owner */ - true, /* is_sufficient */ - min_balance - )); - - // mint into the caller account - let caller = 333; - let beneficiary = ::Lookup::unlookup(caller); - let balance = 1000; - - assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance)); - assert_eq!(Assets::balance(asset_id, caller), balance); - - let weight = 1; - let len = 1; - ChargeAssetTxPayment::::pre_dispatch_unsigned( - CALL, - &info_from_weight(Weight::from_parts(weight, 0)), - len, - ) - .unwrap(); - - assert_eq!(Assets::balance(asset_id, caller), balance); - - // `Pays::Yes` on post-dispatch does not mean we pay (we never charge more than the - // initial fee) - assert_ok!(ChargeAssetTxPayment::::post_dispatch( - None, - &info_from_weight(Weight::from_parts(weight, 0)), - &post_info_from_pays(Pays::Yes), - len, - &Ok(()) + &Ok(()), + &() )); assert_eq!(Assets::balance(asset_id, caller), balance); }); diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/weights.rs b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/weights.rs new file mode 100644 index 00000000000..f95e49f8073 --- /dev/null +++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/weights.rs @@ -0,0 +1,150 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Autogenerated weights for `pallet_asset_conversion_tx_payment` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` + +// Executed Command: +// ./target/production/substrate-node +// benchmark +// pallet +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_asset_conversion_tx_payment +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./substrate/frame/transaction-payment/asset-conversion-tx-payment/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for `pallet_asset_conversion_tx_payment`. +pub trait WeightInfo { + fn charge_asset_tx_payment_zero() -> Weight; + fn charge_asset_tx_payment_native() -> Weight; + fn charge_asset_tx_payment_asset() -> Weight; +} + +/// Weights for `pallet_asset_conversion_tx_payment` using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + fn charge_asset_tx_payment_zero() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 628_000 picoseconds. + Weight::from_parts(694_000, 0) + } + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Authorship::Author` (r:1 w:0) + /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `System::Digest` (r:1 w:0) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn charge_asset_tx_payment_native() -> Weight { + // Proof Size summary in bytes: + // Measured: `248` + // Estimated: `1733` + // Minimum execution time: 34_410_000 picoseconds. + Weight::from_parts(35_263_000, 1733) + .saturating_add(T::DbWeight::get().reads(3_u64)) + } + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:2 w:2) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Authorship::Author` (r:1 w:0) + /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `System::Digest` (r:1 w:0) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn charge_asset_tx_payment_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `888` + // Estimated: `6208` + // Minimum execution time: 112_432_000 picoseconds. + Weight::from_parts(113_992_000, 6208) + .saturating_add(T::DbWeight::get().reads(7_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) + } +} + +// For backwards compatibility and tests. +impl WeightInfo for () { + fn charge_asset_tx_payment_zero() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 628_000 picoseconds. + Weight::from_parts(694_000, 0) + } + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Authorship::Author` (r:1 w:0) + /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `System::Digest` (r:1 w:0) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn charge_asset_tx_payment_native() -> Weight { + // Proof Size summary in bytes: + // Measured: `248` + // Estimated: `1733` + // Minimum execution time: 34_410_000 picoseconds. + Weight::from_parts(35_263_000, 1733) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + } + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:2 w:2) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Authorship::Author` (r:1 w:0) + /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `System::Digest` (r:1 w:0) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn charge_asset_tx_payment_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `888` + // Estimated: `6208` + // Minimum execution time: 112_432_000 picoseconds. + Weight::from_parts(113_992_000, 6208) + .saturating_add(RocksDbWeight::get().reads(7_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) + } +} diff --git a/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml b/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml index 1da3237df08..06d9c30792e 100644 --- a/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml +++ b/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml @@ -66,6 +66,7 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "pallet-assets/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", "sp-runtime/runtime-benchmarks", ] try-runtime = [ diff --git a/substrate/frame/transaction-payment/asset-tx-payment/README.md b/substrate/frame/transaction-payment/asset-tx-payment/README.md index fc860347d85..933ce13b0ee 100644 --- a/substrate/frame/transaction-payment/asset-tx-payment/README.md +++ b/substrate/frame/transaction-payment/asset-tx-payment/README.md @@ -16,6 +16,6 @@ asset. ### Integration This pallet wraps FRAME's transaction payment pallet and functions as a replacement. This means you should include both pallets in your `construct_runtime` macro, but only include this -pallet's [`SignedExtension`] ([`ChargeAssetTxPayment`]). +pallet's [`TransactionExtension`] ([`ChargeAssetTxPayment`]). License: Apache-2.0 diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/benchmarking.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/benchmarking.rs new file mode 100644 index 00000000000..17e96e2b025 --- /dev/null +++ b/substrate/frame/transaction-payment/asset-tx-payment/src/benchmarking.rs @@ -0,0 +1,123 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Benchmarks for Asset Tx Payment Pallet's transaction extension + +use super::*; +use crate::Pallet; +use frame_benchmarking::v2::*; +use frame_support::{ + dispatch::{DispatchInfo, PostDispatchInfo}, + pallet_prelude::*, +}; +use frame_system::RawOrigin; +use sp_runtime::traits::{AsSystemOriginSigner, DispatchTransaction, Dispatchable}; + +#[benchmarks(where + T::RuntimeCall: Dispatchable, + AssetBalanceOf: Send + Sync, + BalanceOf: Send + Sync + From + IsType>, + ChargeAssetIdOf: Send + Sync, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, + Credit: IsType>, +)] +mod benchmarks { + use super::*; + + #[benchmark] + fn charge_asset_tx_payment_zero() { + let caller: T::AccountId = whitelisted_caller(); + let ext: ChargeAssetTxPayment = ChargeAssetTxPayment::from(0u32.into(), None); + let inner = frame_system::Call::remark { remark: vec![] }; + let call = T::RuntimeCall::from(inner); + let info = DispatchInfo { + weight: Weight::zero(), + class: DispatchClass::Normal, + pays_fee: Pays::No, + }; + let post_info = PostDispatchInfo { actual_weight: None, pays_fee: Pays::No }; + #[block] + { + assert!(ext + .test_run(RawOrigin::Signed(caller).into(), &call, &info, 0, |_| Ok(post_info)) + .unwrap() + .is_ok()); + } + } + + #[benchmark] + fn charge_asset_tx_payment_native() { + let caller: T::AccountId = whitelisted_caller(); + let (fun_asset_id, _) = ::BenchmarkHelper::create_asset_id_parameter(1); + ::BenchmarkHelper::setup_balances_and_pool(fun_asset_id, caller.clone()); + let ext: ChargeAssetTxPayment = ChargeAssetTxPayment::from(10u32.into(), None); + let inner = frame_system::Call::remark { remark: vec![] }; + let call = T::RuntimeCall::from(inner); + let info = DispatchInfo { + weight: Weight::from_parts(10, 0), + class: DispatchClass::Operational, + pays_fee: Pays::Yes, + }; + let post_info = PostDispatchInfo { + actual_weight: Some(Weight::from_parts(10, 0)), + pays_fee: Pays::Yes, + }; + + #[block] + { + assert!(ext + .test_run(RawOrigin::Signed(caller).into(), &call, &info, 0, |_| Ok(post_info)) + .unwrap() + .is_ok()); + } + } + + #[benchmark] + fn charge_asset_tx_payment_asset() { + let caller: T::AccountId = whitelisted_caller(); + let (fun_asset_id, asset_id) = ::BenchmarkHelper::create_asset_id_parameter(1); + ::BenchmarkHelper::setup_balances_and_pool( + fun_asset_id.clone(), + caller.clone(), + ); + let tip = 10u32.into(); + let ext: ChargeAssetTxPayment = ChargeAssetTxPayment::from(tip, Some(asset_id)); + let inner = frame_system::Call::remark { remark: vec![] }; + let call = T::RuntimeCall::from(inner); + let info = DispatchInfo { + weight: Weight::from_parts(10, 0), + class: DispatchClass::Operational, + pays_fee: Pays::Yes, + }; + let post_info = PostDispatchInfo { + actual_weight: Some(Weight::from_parts(10, 0)), + pays_fee: Pays::Yes, + }; + + #[block] + { + assert!(ext + .test_run(RawOrigin::Signed(caller.clone()).into(), &call, &info, 0, |_| Ok( + post_info + )) + .unwrap() + .is_ok()); + } + } + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Runtime); +} diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/lib.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/lib.rs index 753fae747a3..991b5f31406 100644 --- a/substrate/frame/transaction-payment/asset-tx-payment/src/lib.rs +++ b/substrate/frame/transaction-payment/asset-tx-payment/src/lib.rs @@ -31,7 +31,7 @@ //! This pallet wraps FRAME's transaction payment pallet and functions as a replacement. This means //! you should include both pallets in your `construct_runtime` macro, but only include this -//! pallet's [`SignedExtension`] ([`ChargeAssetTxPayment`]). +//! pallet's [`TransactionExtension`] ([`ChargeAssetTxPayment`]). #![cfg_attr(not(feature = "std"), no_std)] @@ -40,6 +40,7 @@ use sp_std::prelude::*; use codec::{Decode, Encode}; use frame_support::{ dispatch::{DispatchInfo, DispatchResult, PostDispatchInfo}, + pallet_prelude::Weight, traits::{ tokens::{ fungibles::{Balanced, Credit, Inspect}, @@ -52,10 +53,11 @@ use frame_support::{ use pallet_transaction_payment::OnChargeTransaction; use scale_info::TypeInfo; use sp_runtime::{ - traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf, SignedExtension, Zero}, - transaction_validity::{ - InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction, + traits::{ + AsSystemOriginSigner, DispatchInfoOf, Dispatchable, PostDispatchInfoOf, + TransactionExtension, TransactionExtensionBase, Zero, }, + transaction_validity::{InvalidTransaction, TransactionValidityError, ValidTransaction}, }; #[cfg(test)] @@ -63,8 +65,14 @@ mod mock; #[cfg(test)] mod tests; +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + mod payment; +pub mod weights; + pub use payment::*; +pub use weights::WeightInfo; /// Type aliases used for interaction with `OnChargeTransaction`. pub(crate) type OnChargeTransactionOf = @@ -120,11 +128,30 @@ pub mod pallet { type Fungibles: Balanced; /// The actual transaction charging logic that charges the fees. type OnChargeAssetTransaction: OnChargeAssetTransaction; + /// The weight information of this pallet. + type WeightInfo: WeightInfo; + #[cfg(feature = "runtime-benchmarks")] + /// Benchmark helper + type BenchmarkHelper: BenchmarkHelperTrait< + Self::AccountId, + <::Fungibles as Inspect>::AssetId, + <::OnChargeAssetTransaction as OnChargeAssetTransaction>::AssetId, + >; } #[pallet::pallet] pub struct Pallet(_); + #[cfg(feature = "runtime-benchmarks")] + /// Helper trait to benchmark the `ChargeAssetTxPayment` transaction extension. + pub trait BenchmarkHelperTrait { + /// Returns the `AssetId` to be used in the liquidity pool by the benchmarking code. + fn create_asset_id_parameter(id: u32) -> (FunAssetIdParameter, AssetIdParameter); + /// Create a liquidity pool for a given asset and sufficiently endow accounts to benchmark + /// the extension. + fn setup_balances_and_pool(asset_id: FunAssetIdParameter, account: AccountId); + } + #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { @@ -172,9 +199,8 @@ where who: &T::AccountId, call: &T::RuntimeCall, info: &DispatchInfoOf, - len: usize, + fee: BalanceOf, ) -> Result<(BalanceOf, InitialPayment), TransactionValidityError> { - let fee = pallet_transaction_payment::Pallet::::compute_fee(len as u32, info, self.tip); debug_assert!(self.tip <= fee, "tip should be included in the computed fee"); if fee.is_zero() { Ok((fee, InitialPayment::Nothing)) @@ -209,104 +235,139 @@ impl sp_std::fmt::Debug for ChargeAssetTxPayment { } } -impl SignedExtension for ChargeAssetTxPayment +impl TransactionExtensionBase for ChargeAssetTxPayment where - T::RuntimeCall: Dispatchable, AssetBalanceOf: Send + Sync, BalanceOf: Send + Sync + From + IsType>, ChargeAssetIdOf: Send + Sync, Credit: IsType>, { const IDENTIFIER: &'static str = "ChargeAssetTxPayment"; - type AccountId = T::AccountId; - type Call = T::RuntimeCall; - type AdditionalSigned = (); + type Implicit = (); + + fn weight(&self) -> Weight { + if self.asset_id.is_some() { + ::WeightInfo::charge_asset_tx_payment_asset() + } else { + ::WeightInfo::charge_asset_tx_payment_native() + } + } +} + +impl TransactionExtension for ChargeAssetTxPayment +where + T::RuntimeCall: Dispatchable, + AssetBalanceOf: Send + Sync, + BalanceOf: Send + Sync + From + IsType>, + ChargeAssetIdOf: Send + Sync, + Credit: IsType>, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, +{ + type Val = ( + // tip + BalanceOf, + // who paid the fee + T::AccountId, + // transaction fee + BalanceOf, + ); type Pre = ( // tip BalanceOf, // who paid the fee - Self::AccountId, + T::AccountId, // imbalance resulting from withdrawing the fee InitialPayment, // asset_id for the transaction payment Option>, ); - fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { - Ok(()) - } - fn validate( &self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, + origin: ::RuntimeOrigin, + _call: &T::RuntimeCall, + info: &DispatchInfoOf, len: usize, - ) -> TransactionValidity { + _context: &mut Context, + _self_implicit: Self::Implicit, + _inherited_implication: &impl Encode, + ) -> Result< + (ValidTransaction, Self::Val, ::RuntimeOrigin), + TransactionValidityError, + > { use pallet_transaction_payment::ChargeTransactionPayment; - let (fee, _) = self.withdraw_fee(who, call, info, len)?; + let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?; + // Non-mutating call of `compute_fee` to calculate the fee used in the transaction priority. + let fee = pallet_transaction_payment::Pallet::::compute_fee(len as u32, info, self.tip); let priority = ChargeTransactionPayment::::get_priority(info, len, self.tip, fee); - Ok(ValidTransaction { priority, ..Default::default() }) + let val = (self.tip, who.clone(), fee); + let validity = ValidTransaction { priority, ..Default::default() }; + Ok((validity, val, origin)) } - fn pre_dispatch( + fn prepare( self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, - len: usize, + val: Self::Val, + _origin: &::RuntimeOrigin, + call: &T::RuntimeCall, + info: &DispatchInfoOf, + _len: usize, + _context: &Context, ) -> Result { - let (_fee, initial_payment) = self.withdraw_fee(who, call, info, len)?; - Ok((self.tip, who.clone(), initial_payment, self.asset_id)) + let (tip, who, fee) = val; + // Mutating call of `withdraw_fee` to actually charge for the transaction. + let (_fee, initial_payment) = self.withdraw_fee(&who, call, info, fee)?; + Ok((tip, who, initial_payment, self.asset_id)) } fn post_dispatch( - pre: Option, - info: &DispatchInfoOf, - post_info: &PostDispatchInfoOf, + pre: Self::Pre, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, len: usize, result: &DispatchResult, + _context: &Context, ) -> Result<(), TransactionValidityError> { - if let Some((tip, who, initial_payment, asset_id)) = pre { - match initial_payment { - InitialPayment::Native(already_withdrawn) => { - pallet_transaction_payment::ChargeTransactionPayment::::post_dispatch( - Some((tip, who, already_withdrawn)), + let (tip, who, initial_payment, asset_id) = pre; + match initial_payment { + InitialPayment::Native(already_withdrawn) => { + pallet_transaction_payment::ChargeTransactionPayment::::post_dispatch( + (tip, who, already_withdrawn), + info, + post_info, + len, + result, + &(), + )?; + }, + InitialPayment::Asset(already_withdrawn) => { + let actual_fee = pallet_transaction_payment::Pallet::::compute_actual_fee( + len as u32, info, post_info, tip, + ); + + let (converted_fee, converted_tip) = + T::OnChargeAssetTransaction::correct_and_deposit_fee( + &who, info, post_info, - len, - result, + actual_fee.into(), + tip.into(), + already_withdrawn.into(), )?; - }, - InitialPayment::Asset(already_withdrawn) => { - let actual_fee = pallet_transaction_payment::Pallet::::compute_actual_fee( - len as u32, info, post_info, tip, - ); - - let (converted_fee, converted_tip) = - T::OnChargeAssetTransaction::correct_and_deposit_fee( - &who, - info, - post_info, - actual_fee.into(), - tip.into(), - already_withdrawn.into(), - )?; - Pallet::::deposit_event(Event::::AssetTxFeePaid { - who, - actual_fee: converted_fee, - tip: converted_tip, - asset_id, - }); - }, - InitialPayment::Nothing => { - // `actual_fee` should be zero here for any signed extrinsic. It would be - // non-zero here in case of unsigned extrinsics as they don't pay fees but - // `compute_actual_fee` is not aware of them. In both cases it's fine to just - // move ahead without adjusting the fee, though, so we do nothing. - debug_assert!(tip.is_zero(), "tip should be zero if initial fee was zero."); - }, - } + Pallet::::deposit_event(Event::::AssetTxFeePaid { + who, + actual_fee: converted_fee, + tip: converted_tip, + asset_id, + }); + }, + InitialPayment::Nothing => { + // `actual_fee` should be zero here for any signed extrinsic. It would be + // non-zero here in case of unsigned extrinsics as they don't pay fees but + // `compute_actual_fee` is not aware of them. In both cases it's fine to just + // move ahead without adjusting the fee, though, so we do nothing. + debug_assert!(tip.is_zero(), "tip should be zero if initial fee was zero."); + }, } Ok(()) diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs index 1f335b4f6c4..bb484795e82 100644 --- a/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs +++ b/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs @@ -136,12 +136,12 @@ impl WeightToFeeT for TransactionByteFee { } } +#[derive_impl(pallet_transaction_payment::config_preludes::TestDefaultConfig as pallet_transaction_payment::DefaultConfig)] impl pallet_transaction_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; type OnChargeTransaction = CurrencyAdapter; type WeightToFee = WeightToFee; type LengthToFee = TransactionByteFee; - type FeeMultiplierUpdate = (); type OperationalFeeMultiplier = ConstU8<5>; } @@ -205,4 +205,56 @@ impl Config for Runtime { pallet_assets::BalanceToAssetBalance, CreditToBlockAuthor, >; + type WeightInfo = (); + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = Helper; +} + +#[cfg(feature = "runtime-benchmarks")] +pub fn new_test_ext() -> sp_io::TestExternalities { + let base_weight = 5; + let balance_factor = 100; + crate::tests::ExtBuilder::default() + .balance_factor(balance_factor) + .base_weight(Weight::from_parts(base_weight, 0)) + .build() +} + +#[cfg(feature = "runtime-benchmarks")] +pub struct Helper; + +#[cfg(feature = "runtime-benchmarks")] +impl BenchmarkHelperTrait for Helper { + fn create_asset_id_parameter(id: u32) -> (u32, u32) { + (id.into(), id.into()) + } + + fn setup_balances_and_pool(asset_id: u32, account: u64) { + use frame_support::{assert_ok, traits::fungibles::Mutate}; + use sp_runtime::traits::StaticLookup; + let min_balance = 1; + assert_ok!(Assets::force_create( + RuntimeOrigin::root(), + asset_id.into(), + 42, /* owner */ + true, /* is_sufficient */ + min_balance + )); + + // mint into the caller account + let caller = 2; + let beneficiary = ::Lookup::unlookup(caller); + let balance = 1000; + assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance)); + assert_eq!(Assets::balance(asset_id, caller), balance); + + use frame_support::traits::Currency; + let _ = Balances::deposit_creating(&account, u32::MAX.into()); + + let beneficiary = ::Lookup::unlookup(account); + let balance = 1000; + + assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance)); + assert_eq!(Assets::balance(asset_id, account), balance); + } } diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs index 8df98ceda99..42b8f2cf5fa 100644 --- a/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs +++ b/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs @@ -25,7 +25,10 @@ use frame_support::{ use frame_system as system; use mock::{ExtrinsicBaseWeight, *}; use pallet_balances::Call as BalancesCall; -use sp_runtime::{traits::StaticLookup, BuildStorage}; +use sp_runtime::{ + traits::{DispatchTransaction, StaticLookup}, + BuildStorage, +}; const CALL: &::RuntimeCall = &RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 2, value: 69 }); @@ -116,33 +119,45 @@ fn transaction_payment_in_native_possible() { .build() .execute_with(|| { let len = 10; - let pre = ChargeAssetTxPayment::::from(0, None) - .pre_dispatch(&1, CALL, &info_from_weight(Weight::from_parts(5, 0)), len) + let (pre, _) = ChargeAssetTxPayment::::from(0, None) + .validate_and_prepare( + Some(1).into(), + CALL, + &info_from_weight(Weight::from_parts(5, 0)), + len, + ) .unwrap(); let initial_balance = 10 * balance_factor; assert_eq!(Balances::free_balance(1), initial_balance - 5 - 5 - 10); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - Some(pre), + pre, &info_from_weight(Weight::from_parts(5, 0)), &default_post_info(), len, - &Ok(()) + &Ok(()), + &() )); assert_eq!(Balances::free_balance(1), initial_balance - 5 - 5 - 10); - let pre = ChargeAssetTxPayment::::from(5 /* tipped */, None) - .pre_dispatch(&2, CALL, &info_from_weight(Weight::from_parts(100, 0)), len) + let (pre, _) = ChargeAssetTxPayment::::from(5 /* tipped */, None) + .validate_and_prepare( + Some(2).into(), + CALL, + &info_from_weight(Weight::from_parts(100, 0)), + len, + ) .unwrap(); let initial_balance_for_2 = 20 * balance_factor; assert_eq!(Balances::free_balance(2), initial_balance_for_2 - 5 - 10 - 100 - 5); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - Some(pre), + pre, &info_from_weight(Weight::from_parts(100, 0)), &post_info_from_weight(Weight::from_parts(50, 0)), len, - &Ok(()) + &Ok(()), + &() )); assert_eq!(Balances::free_balance(2), initial_balance_for_2 - 5 - 10 - 50 - 5); }); @@ -179,8 +194,13 @@ fn transaction_payment_in_asset_possible() { // we convert the from weight to fee based on the ratio between asset min balance and // existential deposit let fee = (base_weight + weight + len as u64) * min_balance / ExistentialDeposit::get(); - let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len) + let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .validate_and_prepare( + Some(caller).into(), + CALL, + &info_from_weight(Weight::from_parts(weight, 0)), + len, + ) .unwrap(); // assert that native balance is not used assert_eq!(Balances::free_balance(caller), 10 * balance_factor); @@ -189,11 +209,12 @@ fn transaction_payment_in_asset_possible() { assert_eq!(Assets::balance(asset_id, BLOCK_AUTHOR), 0); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - Some(pre), + pre, &info_from_weight(Weight::from_parts(weight, 0)), &default_post_info(), len, - &Ok(()) + &Ok(()), + &() )); assert_eq!(Assets::balance(asset_id, caller), balance - fee); // check that the block author gets rewarded @@ -232,8 +253,13 @@ fn transaction_payment_without_fee() { // we convert the from weight to fee based on the ratio between asset min balance and // existential deposit let fee = (base_weight + weight + len as u64) * min_balance / ExistentialDeposit::get(); - let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len) + let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .validate_and_prepare( + Some(caller).into(), + CALL, + &info_from_weight(Weight::from_parts(weight, 0)), + len, + ) .unwrap(); // assert that native balance is not used assert_eq!(Balances::free_balance(caller), 10 * balance_factor); @@ -242,11 +268,12 @@ fn transaction_payment_without_fee() { assert_eq!(Assets::balance(asset_id, BLOCK_AUTHOR), 0); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - Some(pre), + pre, &info_from_weight(Weight::from_parts(weight, 0)), &post_info_from_pays(Pays::No), len, - &Ok(()) + &Ok(()), + &() )); // caller should be refunded assert_eq!(Assets::balance(asset_id, caller), balance); @@ -287,18 +314,24 @@ fn asset_transaction_payment_with_tip_and_refund() { // existential deposit let fee_with_tip = (base_weight + weight + len as u64 + tip) * min_balance / ExistentialDeposit::get(); - let pre = ChargeAssetTxPayment::::from(tip, Some(asset_id)) - .pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len) + let (pre, _) = ChargeAssetTxPayment::::from(tip, Some(asset_id)) + .validate_and_prepare( + Some(caller).into(), + CALL, + &info_from_weight(Weight::from_parts(weight, 0)), + len, + ) .unwrap(); assert_eq!(Assets::balance(asset_id, caller), balance - fee_with_tip); let final_weight = 50; assert_ok!(ChargeAssetTxPayment::::post_dispatch( - Some(pre), + pre, &info_from_weight(Weight::from_parts(weight, 0)), &post_info_from_weight(Weight::from_parts(final_weight, 0)), len, - &Ok(()) + &Ok(()), + &() )); let final_fee = fee_with_tip - (weight - final_weight) * min_balance / ExistentialDeposit::get(); @@ -339,19 +372,25 @@ fn payment_from_account_with_only_assets() { // we convert the from weight to fee based on the ratio between asset min balance and // existential deposit let fee = (base_weight + weight + len as u64) * min_balance / ExistentialDeposit::get(); - let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len) + let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .validate_and_prepare( + Some(caller).into(), + CALL, + &info_from_weight(Weight::from_parts(weight, 0)), + len, + ) .unwrap(); assert_eq!(Balances::free_balance(caller), 0); // check that fee was charged in the given asset assert_eq!(Assets::balance(asset_id, caller), balance - fee); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - Some(pre), + pre, &info_from_weight(Weight::from_parts(weight, 0)), &default_post_info(), len, - &Ok(()) + &Ok(()), + &() )); assert_eq!(Assets::balance(asset_id, caller), balance - fee); assert_eq!(Balances::free_balance(caller), 0); @@ -372,7 +411,12 @@ fn payment_only_with_existing_sufficient_asset() { let len = 10; // pre_dispatch fails for non-existent asset assert!(ChargeAssetTxPayment::::from(0, Some(asset_id)) - .pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len) + .validate_and_prepare( + Some(caller).into(), + CALL, + &info_from_weight(Weight::from_parts(weight, 0)), + len + ) .is_err()); // create the non-sufficient asset @@ -386,7 +430,12 @@ fn payment_only_with_existing_sufficient_asset() { )); // pre_dispatch fails for non-sufficient asset assert!(ChargeAssetTxPayment::::from(0, Some(asset_id)) - .pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len) + .validate_and_prepare( + Some(caller).into(), + CALL, + &info_from_weight(Weight::from_parts(weight, 0)), + len + ) .is_err()); }); } @@ -424,33 +473,40 @@ fn converted_fee_is_never_zero_if_input_fee_is_not() { // naive fee calculation would round down to zero assert_eq!(fee, 0); { - let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .pre_dispatch(&caller, CALL, &info_from_pays(Pays::No), len) + let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .validate_and_prepare(Some(caller).into(), CALL, &info_from_pays(Pays::No), len) .unwrap(); // `Pays::No` still implies no fees assert_eq!(Assets::balance(asset_id, caller), balance); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - Some(pre), + pre, &info_from_pays(Pays::No), &post_info_from_pays(Pays::No), len, - &Ok(()) + &Ok(()), + &() )); assert_eq!(Assets::balance(asset_id, caller), balance); } - let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len) + let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .validate_and_prepare( + Some(caller).into(), + CALL, + &info_from_weight(Weight::from_parts(weight, 0)), + len, + ) .unwrap(); // check that at least one coin was charged in the given asset assert_eq!(Assets::balance(asset_id, caller), balance - 1); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - Some(pre), + pre, &info_from_weight(Weight::from_parts(weight, 0)), &default_post_info(), len, - &Ok(()) + &Ok(()), + &() )); assert_eq!(Assets::balance(asset_id, caller), balance - 1); }); @@ -488,8 +544,8 @@ fn post_dispatch_fee_is_zero_if_pre_dispatch_fee_is_zero() { let fee = (base_weight + weight + len as u64) * min_balance / ExistentialDeposit::get(); // calculated fee is greater than 0 assert!(fee > 0); - let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .pre_dispatch(&caller, CALL, &info_from_pays(Pays::No), len) + let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .validate_and_prepare(Some(caller).into(), CALL, &info_from_pays(Pays::No), len) .unwrap(); // `Pays::No` implies no pre-dispatch fees assert_eq!(Assets::balance(asset_id, caller), balance); @@ -503,60 +559,12 @@ fn post_dispatch_fee_is_zero_if_pre_dispatch_fee_is_zero() { // `Pays::Yes` on post-dispatch does not mean we pay (we never charge more than the // initial fee) assert_ok!(ChargeAssetTxPayment::::post_dispatch( - Some(pre), + pre, &info_from_pays(Pays::No), &post_info_from_pays(Pays::Yes), len, - &Ok(()) - )); - assert_eq!(Assets::balance(asset_id, caller), balance); - }); -} - -#[test] -fn post_dispatch_fee_is_zero_if_unsigned_pre_dispatch_fee_is_zero() { - let base_weight = 1; - ExtBuilder::default() - .balance_factor(100) - .base_weight(Weight::from_parts(base_weight, 0)) - .build() - .execute_with(|| { - // create the asset - let asset_id = 1; - let min_balance = 100; - assert_ok!(Assets::force_create( - RuntimeOrigin::root(), - asset_id.into(), - 42, /* owner */ - true, /* is_sufficient */ - min_balance - )); - - // mint into the caller account - let caller = 333; - let beneficiary = ::Lookup::unlookup(caller); - let balance = 100; - assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance)); - assert_eq!(Assets::balance(asset_id, caller), balance); - let weight = 1; - let len = 1; - ChargeAssetTxPayment::::pre_dispatch_unsigned( - CALL, - &info_from_weight(Weight::from_parts(weight, 0)), - len, - ) - .unwrap(); - - assert_eq!(Assets::balance(asset_id, caller), balance); - - // `Pays::Yes` on post-dispatch does not mean we pay (we never charge more than the - // initial fee) - assert_ok!(ChargeAssetTxPayment::::post_dispatch( - None, - &info_from_weight(Weight::from_parts(weight, 0)), - &post_info_from_pays(Pays::Yes), - len, - &Ok(()) + &Ok(()), + &() )); assert_eq!(Assets::balance(asset_id, caller), balance); }); diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/weights.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/weights.rs new file mode 100644 index 00000000000..1af1c94177d --- /dev/null +++ b/substrate/frame/transaction-payment/asset-tx-payment/src/weights.rs @@ -0,0 +1,146 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Autogenerated weights for `pallet_asset_tx_payment` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` + +// Executed Command: +// ./target/production/substrate-node +// benchmark +// pallet +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_asset_tx_payment +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./substrate/frame/transaction-payment/asset-tx-payment/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for `pallet_asset_tx_payment`. +pub trait WeightInfo { + fn charge_asset_tx_payment_zero() -> Weight; + fn charge_asset_tx_payment_native() -> Weight; + fn charge_asset_tx_payment_asset() -> Weight; +} + +/// Weights for `pallet_asset_tx_payment` using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + fn charge_asset_tx_payment_zero() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 542_000 picoseconds. + Weight::from_parts(597_000, 0) + } + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Authorship::Author` (r:1 w:0) + /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `System::Digest` (r:1 w:0) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn charge_asset_tx_payment_native() -> Weight { + // Proof Size summary in bytes: + // Measured: `248` + // Estimated: `1733` + // Minimum execution time: 33_162_000 picoseconds. + Weight::from_parts(34_716_000, 1733) + .saturating_add(T::DbWeight::get().reads(3_u64)) + } + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Authorship::Author` (r:1 w:0) + /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `System::Digest` (r:1 w:0) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn charge_asset_tx_payment_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `747` + // Estimated: `3675` + // Minimum execution time: 44_230_000 picoseconds. + Weight::from_parts(45_297_000, 3675) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } +} + +// For backwards compatibility and tests. +impl WeightInfo for () { + fn charge_asset_tx_payment_zero() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 542_000 picoseconds. + Weight::from_parts(597_000, 0) + } + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Authorship::Author` (r:1 w:0) + /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `System::Digest` (r:1 w:0) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn charge_asset_tx_payment_native() -> Weight { + // Proof Size summary in bytes: + // Measured: `248` + // Estimated: `1733` + // Minimum execution time: 33_162_000 picoseconds. + Weight::from_parts(34_716_000, 1733) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + } + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:1 w:1) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Authorship::Author` (r:1 w:0) + /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `System::Digest` (r:1 w:0) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn charge_asset_tx_payment_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `747` + // Estimated: `3675` + // Minimum execution time: 44_230_000 picoseconds. + Weight::from_parts(45_297_000, 3675) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } +} diff --git a/substrate/frame/transaction-payment/skip-feeless-payment/src/lib.rs b/substrate/frame/transaction-payment/skip-feeless-payment/src/lib.rs index 6c34c26ce92..9810ea08c79 100644 --- a/substrate/frame/transaction-payment/skip-feeless-payment/src/lib.rs +++ b/substrate/frame/transaction-payment/skip-feeless-payment/src/lib.rs @@ -21,7 +21,7 @@ //! //! ## Overview //! -//! It does this by wrapping an existing [`SignedExtension`] implementation (e.g. +//! It does this by wrapping an existing [`TransactionExtension`] implementation (e.g. //! [`pallet-transaction-payment`]) and checking if the dispatchable is feeless before applying the //! wrapped extension. If the dispatchable is indeed feeless, the extension is skipped and a custom //! event is emitted instead. Otherwise, the extension is applied as usual. @@ -31,7 +31,8 @@ //! //! This pallet wraps an existing transaction payment pallet. This means you should both pallets //! in your `construct_runtime` macro and include this pallet's -//! [`SignedExtension`] ([`SkipCheckIfFeeless`]) that would accept the existing one as an argument. +//! [`TransactionExtension`] ([`SkipCheckIfFeeless`]) that would accept the existing one as an +//! argument. #![cfg_attr(not(feature = "std"), no_std)] @@ -42,7 +43,10 @@ use frame_support::{ }; use scale_info::{StaticTypeInfo, TypeInfo}; use sp_runtime::{ - traits::{DispatchInfoOf, PostDispatchInfoOf, SignedExtension}, + traits::{ + DispatchInfoOf, OriginOf, PostDispatchInfoOf, TransactionExtension, + TransactionExtensionBase, ValidateResult, + }, transaction_validity::TransactionValidityError, }; @@ -70,11 +74,11 @@ pub mod pallet { #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { /// A transaction fee was skipped. - FeeSkipped { who: T::AccountId }, + FeeSkipped { origin: ::PalletsOrigin }, } } -/// A [`SignedExtension`] that skips the wrapped extension if the dispatchable is feeless. +/// A [`TransactionExtension`] that skips the wrapped extension if the dispatchable is feeless. #[derive(Encode, Decode, Clone, Eq, PartialEq)] pub struct SkipCheckIfFeeless(pub S, sp_std::marker::PhantomData); @@ -103,53 +107,96 @@ impl From for SkipCheckIfFeeless { } } -impl> SignedExtension +pub enum Intermediate { + /// The wrapped extension should be applied. + Apply(T), + /// The wrapped extension should be skipped. + Skip(O), +} +use Intermediate::*; + +impl TransactionExtensionBase for SkipCheckIfFeeless -where - S::Call: CheckIfFeeless>, { - type AccountId = T::AccountId; - type Call = S::Call; - type AdditionalSigned = S::AdditionalSigned; - type Pre = (Self::AccountId, Option<::Pre>); // From the outside this extension should be "invisible", because it just extends the wrapped // extension with an extra check in `pre_dispatch` and `post_dispatch`. Thus, we should forward // the identifier of the wrapped extension to let wallets see this extension as it would only be // the wrapped extension itself. const IDENTIFIER: &'static str = S::IDENTIFIER; + type Implicit = S::Implicit; + + fn implicit(&self) -> Result { + self.0.implicit() + } - fn additional_signed(&self) -> Result { - self.0.additional_signed() + fn weight(&self) -> frame_support::weights::Weight { + self.0.weight() } +} - fn pre_dispatch( +impl> + TransactionExtension for SkipCheckIfFeeless +where + T::RuntimeCall: CheckIfFeeless>, +{ + type Val = Intermediate as OriginTrait>::PalletsOrigin>; + type Pre = Intermediate as OriginTrait>::PalletsOrigin>; + + fn validate( + &self, + origin: OriginOf, + call: &T::RuntimeCall, + info: &DispatchInfoOf, + len: usize, + context: &mut Context, + self_implicit: S::Implicit, + inherited_implication: &impl Encode, + ) -> ValidateResult { + if call.is_feeless(&origin) { + Ok((Default::default(), Skip(origin.caller().clone()), origin)) + } else { + let (x, y, z) = self.0.validate( + origin, + call, + info, + len, + context, + self_implicit, + inherited_implication, + )?; + Ok((x, Apply(y), z)) + } + } + + fn prepare( self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, + val: Self::Val, + origin: &OriginOf, + call: &T::RuntimeCall, + info: &DispatchInfoOf, len: usize, + context: &Context, ) -> Result { - if call.is_feeless(&::RuntimeOrigin::signed(who.clone())) { - Ok((who.clone(), None)) - } else { - Ok((who.clone(), Some(self.0.pre_dispatch(who, call, info, len)?))) + match val { + Apply(val) => self.0.prepare(val, origin, call, info, len, context).map(Apply), + Skip(origin) => Ok(Skip(origin)), } } fn post_dispatch( - pre: Option, - info: &DispatchInfoOf, - post_info: &PostDispatchInfoOf, + pre: Self::Pre, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, len: usize, result: &DispatchResult, + context: &Context, ) -> Result<(), TransactionValidityError> { - if let Some(pre) = pre { - if let Some(pre) = pre.1 { - S::post_dispatch(Some(pre), info, post_info, len, result)?; - } else { - Pallet::::deposit_event(Event::::FeeSkipped { who: pre.0 }); - } + match pre { + Apply(pre) => S::post_dispatch(pre, info, post_info, len, result, context), + Skip(origin) => { + Pallet::::deposit_event(Event::::FeeSkipped { origin }); + Ok(()) + }, } - Ok(()) } } diff --git a/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs b/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs index 17c4c773997..06948de4c3c 100644 --- a/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs +++ b/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs @@ -18,9 +18,12 @@ use crate as pallet_skip_feeless_payment; use frame_support::{derive_impl, parameter_types}; use frame_system as system; +use sp_runtime::{ + impl_tx_ext_default, + traits::{OriginOf, TransactionExtension}, +}; type Block = frame_system::mocking::MockBlock; -type AccountId = u64; #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Runtime { @@ -38,21 +41,22 @@ parameter_types! { #[derive(Clone, Eq, PartialEq, Debug, Encode, Decode, TypeInfo)] pub struct DummyExtension; -impl SignedExtension for DummyExtension { - type AccountId = AccountId; - type Call = RuntimeCall; - type AdditionalSigned = (); - type Pre = (); +impl TransactionExtensionBase for DummyExtension { const IDENTIFIER: &'static str = "DummyExtension"; - fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { - Ok(()) - } - fn pre_dispatch( + type Implicit = (); +} +impl TransactionExtension for DummyExtension { + type Val = (); + type Pre = (); + impl_tx_ext_default!(RuntimeCall; C; validate); + fn prepare( self, - _who: &Self::AccountId, - _call: &Self::Call, - _info: &DispatchInfoOf, + _val: Self::Val, + _origin: &OriginOf, + _call: &RuntimeCall, + _info: &DispatchInfoOf, _len: usize, + _context: &C, ) -> Result { PreDispatchCount::mutate(|c| *c += 1); Ok(()) diff --git a/substrate/frame/transaction-payment/skip-feeless-payment/src/tests.rs b/substrate/frame/transaction-payment/skip-feeless-payment/src/tests.rs index 4b4dd699741..96b4af7e203 100644 --- a/substrate/frame/transaction-payment/skip-feeless-payment/src/tests.rs +++ b/substrate/frame/transaction-payment/skip-feeless-payment/src/tests.rs @@ -16,18 +16,19 @@ use super::*; use crate::mock::{pallet_dummy::Call, DummyExtension, PreDispatchCount, Runtime, RuntimeCall}; use frame_support::dispatch::DispatchInfo; +use sp_runtime::traits::DispatchTransaction; #[test] fn skip_feeless_payment_works() { let call = RuntimeCall::DummyPallet(Call::::aux { data: 1 }); SkipCheckIfFeeless::::from(DummyExtension) - .pre_dispatch(&0, &call, &DispatchInfo::default(), 0) + .validate_and_prepare(Some(0).into(), &call, &DispatchInfo::default(), 0) .unwrap(); assert_eq!(PreDispatchCount::get(), 1); let call = RuntimeCall::DummyPallet(Call::::aux { data: 0 }); SkipCheckIfFeeless::::from(DummyExtension) - .pre_dispatch(&0, &call, &DispatchInfo::default(), 0) + .validate_and_prepare(Some(0).into(), &call, &DispatchInfo::default(), 0) .unwrap(); assert_eq!(PreDispatchCount::get(), 1); } diff --git a/substrate/frame/transaction-payment/src/benchmarking.rs b/substrate/frame/transaction-payment/src/benchmarking.rs new file mode 100644 index 00000000000..d63c5a7d746 --- /dev/null +++ b/substrate/frame/transaction-payment/src/benchmarking.rs @@ -0,0 +1,81 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Benchmarks for Transaction Payment Pallet's transaction extension + +use super::*; +use crate::Pallet; +use frame_benchmarking::v2::*; +use frame_support::dispatch::{DispatchInfo, PostDispatchInfo}; +use frame_system::{EventRecord, RawOrigin}; +use sp_runtime::traits::{DispatchTransaction, Dispatchable}; + +fn assert_last_event(generic_event: ::RuntimeEvent) { + let events = frame_system::Pallet::::events(); + let system_event: ::RuntimeEvent = generic_event.into(); + // compare to the last event record + let EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); +} + +#[benchmarks(where + T: Config, + T::RuntimeCall: Dispatchable, + BalanceOf: Send + Sync + From, +)] +mod benchmarks { + use super::*; + + #[benchmark] + fn charge_transaction_payment() { + let caller: T::AccountId = whitelisted_caller(); + >::endow_account( + &caller, + >::minimum_balance() * 1000.into(), + ); + let tip = >::minimum_balance(); + let ext: ChargeTransactionPayment = ChargeTransactionPayment::from(tip); + let inner = frame_system::Call::remark { remark: vec![] }; + let call = T::RuntimeCall::from(inner); + let info = DispatchInfo { + weight: Weight::from_parts(100, 0), + class: DispatchClass::Operational, + pays_fee: Pays::Yes, + }; + let post_info = PostDispatchInfo { + actual_weight: Some(Weight::from_parts(10, 0)), + pays_fee: Pays::Yes, + }; + + #[block] + { + assert!(ext + .test_run(RawOrigin::Signed(caller.clone()).into(), &call, &info, 10, |_| Ok( + post_info + )) + .unwrap() + .is_ok()); + } + + let actual_fee = Pallet::::compute_actual_fee(10, &info, &post_info, tip); + assert_last_event::( + Event::::TransactionFeePaid { who: caller, actual_fee, tip }.into(), + ); + } + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Runtime); +} diff --git a/substrate/frame/transaction-payment/src/lib.rs b/substrate/frame/transaction-payment/src/lib.rs index efadfd60bdd..6b17616bdc7 100644 --- a/substrate/frame/transaction-payment/src/lib.rs +++ b/substrate/frame/transaction-payment/src/lib.rs @@ -62,23 +62,28 @@ pub use payment::*; use sp_runtime::{ traits::{ Convert, DispatchInfoOf, Dispatchable, One, PostDispatchInfoOf, SaturatedConversion, - Saturating, SignedExtension, Zero, + Saturating, TransactionExtension, TransactionExtensionBase, Zero, }, transaction_validity::{ - TransactionPriority, TransactionValidity, TransactionValidityError, ValidTransaction, + InvalidTransaction, TransactionPriority, TransactionValidityError, ValidTransaction, }, FixedPointNumber, FixedU128, Perbill, Perquintill, RuntimeDebug, }; use sp_std::prelude::*; pub use types::{FeeDetails, InclusionFee, RuntimeDispatchInfo}; +pub use weights::WeightInfo; #[cfg(test)] mod mock; #[cfg(test)] mod tests; +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + mod payment; mod types; +pub mod weights; /// Fee multiplier. pub type Multiplier = FixedU128; @@ -335,6 +340,7 @@ pub mod pallet { type RuntimeEvent = (); type FeeMultiplierUpdate = (); type OperationalFeeMultiplier = (); + type WeightInfo = (); } } @@ -387,6 +393,9 @@ pub mod pallet { /// transactions. #[pallet::constant] type OperationalFeeMultiplier: Get; + + /// The weight information of this pallet. + type WeightInfo: WeightInfo; } #[pallet::type_value] @@ -507,11 +516,11 @@ impl Pallet { // a very very little potential gain in the future. let dispatch_info = ::get_dispatch_info(&unchecked_extrinsic); - let partial_fee = if unchecked_extrinsic.is_signed().unwrap_or(false) { - Self::compute_fee(len, &dispatch_info, 0u32.into()) - } else { - // Unsigned extrinsics have no partial fee. + let partial_fee = if unchecked_extrinsic.is_bare() { + // Bare extrinsics have no partial fee. 0u32.into() + } else { + Self::compute_fee(len, &dispatch_info, 0u32.into()) }; let DispatchInfo { weight, class, .. } = dispatch_info; @@ -531,11 +540,11 @@ impl Pallet { let tip = 0u32.into(); - if unchecked_extrinsic.is_signed().unwrap_or(false) { - Self::compute_fee_details(len, &dispatch_info, tip) - } else { - // Unsigned extrinsics have no inclusion fee. + if unchecked_extrinsic.is_bare() { + // Bare extrinsics have no inclusion fee. FeeDetails { inclusion_fee: None, tip } + } else { + Self::compute_fee_details(len, &dispatch_info, tip) } } @@ -714,7 +723,7 @@ where who: &T::AccountId, call: &T::RuntimeCall, info: &DispatchInfoOf, - len: usize, + fee: BalanceOf, ) -> Result< ( BalanceOf, @@ -723,7 +732,6 @@ where TransactionValidityError, > { let tip = self.0; - let fee = Pallet::::compute_fee(len as u32, info, tip); <::OnChargeTransaction as OnChargeTransaction>::withdraw_fee( who, call, info, fee, tip, @@ -731,6 +739,22 @@ where .map(|i| (fee, i)) } + fn can_withdraw_fee( + &self, + who: &T::AccountId, + call: &T::RuntimeCall, + info: &DispatchInfoOf, + len: usize, + ) -> Result, TransactionValidityError> { + let tip = self.0; + let fee = Pallet::::compute_fee(len as u32, info, tip); + + <::OnChargeTransaction as OnChargeTransaction>::can_withdraw_fee( + who, call, info, fee, tip, + )?; + Ok(fee) + } + /// Get an appropriate priority for a transaction with the given `DispatchInfo`, encoded length /// and user-included tip. /// @@ -817,67 +841,93 @@ impl sp_std::fmt::Debug for ChargeTransactionPayment { } } -impl SignedExtension for ChargeTransactionPayment +impl TransactionExtensionBase for ChargeTransactionPayment { + const IDENTIFIER: &'static str = "ChargeTransactionPayment"; + type Implicit = (); + + fn weight(&self) -> Weight { + T::WeightInfo::charge_transaction_payment() + } +} + +impl TransactionExtension + for ChargeTransactionPayment where BalanceOf: Send + Sync + From, T::RuntimeCall: Dispatchable, { - const IDENTIFIER: &'static str = "ChargeTransactionPayment"; - type AccountId = T::AccountId; - type Call = T::RuntimeCall; - type AdditionalSigned = (); + type Val = ( + // tip + BalanceOf, + // who paid the fee + T::AccountId, + // computed fee + BalanceOf, + ); type Pre = ( // tip BalanceOf, - // who paid the fee - this is an option to allow for a Default impl. - Self::AccountId, + // who paid the fee + T::AccountId, // imbalance resulting from withdrawing the fee <::OnChargeTransaction as OnChargeTransaction>::LiquidityInfo, ); - fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { - Ok(()) - } fn validate( &self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, + origin: ::RuntimeOrigin, + call: &T::RuntimeCall, + info: &DispatchInfoOf, len: usize, - ) -> TransactionValidity { - let (final_fee, _) = self.withdraw_fee(who, call, info, len)?; + _context: &mut Context, + _: (), + _implication: &impl Encode, + ) -> Result< + (ValidTransaction, Self::Val, ::RuntimeOrigin), + TransactionValidityError, + > { + let who = frame_system::ensure_signed(origin.clone()) + .map_err(|_| InvalidTransaction::BadSigner)?; + let final_fee = self.can_withdraw_fee(&who, call, info, len)?; let tip = self.0; - Ok(ValidTransaction { - priority: Self::get_priority(info, len, tip, final_fee), - ..Default::default() - }) + Ok(( + ValidTransaction { + priority: Self::get_priority(info, len, tip, final_fee), + ..Default::default() + }, + (self.0, who, final_fee), + origin, + )) } - fn pre_dispatch( + fn prepare( self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, - len: usize, + val: Self::Val, + _origin: &::RuntimeOrigin, + call: &T::RuntimeCall, + info: &DispatchInfoOf, + _len: usize, + _context: &Context, ) -> Result { - let (_fee, imbalance) = self.withdraw_fee(who, call, info, len)?; - Ok((self.0, who.clone(), imbalance)) + let (tip, who, fee) = val; + // Mutating call to `withdraw_fee` to actually charge for the transaction. + let (_final_fee, imbalance) = self.withdraw_fee(&who, call, info, fee)?; + Ok((tip, who, imbalance)) } fn post_dispatch( - maybe_pre: Option, - info: &DispatchInfoOf, - post_info: &PostDispatchInfoOf, + (tip, who, imbalance): Self::Pre, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, len: usize, _result: &DispatchResult, + _context: &Context, ) -> Result<(), TransactionValidityError> { - if let Some((tip, who, imbalance)) = maybe_pre { - let actual_fee = Pallet::::compute_actual_fee(len as u32, info, post_info, tip); - T::OnChargeTransaction::correct_and_deposit_fee( - &who, info, post_info, actual_fee, tip, imbalance, - )?; - Pallet::::deposit_event(Event::::TransactionFeePaid { who, actual_fee, tip }); - } + let actual_fee = Pallet::::compute_actual_fee(len as u32, info, post_info, tip); + T::OnChargeTransaction::correct_and_deposit_fee( + &who, info, post_info, actual_fee, tip, imbalance, + )?; + Pallet::::deposit_event(Event::::TransactionFeePaid { who, actual_fee, tip }); Ok(()) } } diff --git a/substrate/frame/transaction-payment/src/mock.rs b/substrate/frame/transaction-payment/src/mock.rs index 1ca2e3d7347..eda234ffcae 100644 --- a/substrate/frame/transaction-payment/src/mock.rs +++ b/substrate/frame/transaction-payment/src/mock.rs @@ -157,4 +157,14 @@ impl Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = TransactionByteFee; type FeeMultiplierUpdate = (); + type WeightInfo = (); +} + +#[cfg(feature = "runtime-benchmarks")] +pub fn new_test_ext() -> sp_io::TestExternalities { + crate::tests::ExtBuilder::default() + .base_weight(Weight::from_parts(100, 0)) + .byte_fee(10) + .balance_factor(0) + .build() } diff --git a/substrate/frame/transaction-payment/src/payment.rs b/substrate/frame/transaction-payment/src/payment.rs index 886683f2e0b..a13e73b50b0 100644 --- a/substrate/frame/transaction-payment/src/payment.rs +++ b/substrate/frame/transaction-payment/src/payment.rs @@ -20,7 +20,7 @@ use crate::Config; use core::marker::PhantomData; use sp_runtime::{ - traits::{DispatchInfoOf, PostDispatchInfoOf, Saturating, Zero}, + traits::{CheckedSub, DispatchInfoOf, PostDispatchInfoOf, Saturating, Zero}, transaction_validity::InvalidTransaction, }; @@ -51,6 +51,17 @@ pub trait OnChargeTransaction { tip: Self::Balance, ) -> Result; + /// Check if the predicted fee from the transaction origin can be withdrawn. + /// + /// Note: The `fee` already includes the `tip`. + fn can_withdraw_fee( + who: &T::AccountId, + call: &T::RuntimeCall, + dispatch_info: &DispatchInfoOf, + fee: Self::Balance, + tip: Self::Balance, + ) -> Result<(), TransactionValidityError>; + /// After the transaction was executed the actual fee can be calculated. /// This function should refund any overpaid fees and optionally deposit /// the corrected amount. @@ -64,6 +75,12 @@ pub trait OnChargeTransaction { tip: Self::Balance, already_withdrawn: Self::LiquidityInfo, ) -> Result<(), TransactionValidityError>; + + #[cfg(feature = "runtime-benchmarks")] + fn endow_account(who: &T::AccountId, amount: Self::Balance); + + #[cfg(feature = "runtime-benchmarks")] + fn minimum_balance() -> Self::Balance; } /// Implements the transaction payment for a pallet implementing the `Currency` @@ -121,6 +138,33 @@ where } } + /// Check if the predicted fee from the transaction origin can be withdrawn. + /// + /// Note: The `fee` already includes the `tip`. + fn can_withdraw_fee( + who: &T::AccountId, + _call: &T::RuntimeCall, + _info: &DispatchInfoOf, + fee: Self::Balance, + tip: Self::Balance, + ) -> Result<(), TransactionValidityError> { + if fee.is_zero() { + return Ok(()) + } + + let withdraw_reason = if tip.is_zero() { + WithdrawReasons::TRANSACTION_PAYMENT + } else { + WithdrawReasons::TRANSACTION_PAYMENT | WithdrawReasons::TIP + }; + + let new_balance = + C::free_balance(who).checked_sub(&fee).ok_or(InvalidTransaction::Payment)?; + C::ensure_can_withdraw(who, fee, withdraw_reason, new_balance) + .map(|_| ()) + .map_err(|_| InvalidTransaction::Payment.into()) + } + /// Hand the fee and the tip over to the `[OnUnbalanced]` implementation. /// Since the predicted fee might have been too high, parts of the fee may /// be refunded. @@ -153,4 +197,14 @@ where } Ok(()) } + + #[cfg(feature = "runtime-benchmarks")] + fn endow_account(who: &T::AccountId, amount: Self::Balance) { + let _ = C::deposit_creating(who, amount); + } + + #[cfg(feature = "runtime-benchmarks")] + fn minimum_balance() -> Self::Balance { + C::minimum_balance() + } } diff --git a/substrate/frame/transaction-payment/src/tests.rs b/substrate/frame/transaction-payment/src/tests.rs index d3a1721ccb9..7a49f8111e2 100644 --- a/substrate/frame/transaction-payment/src/tests.rs +++ b/substrate/frame/transaction-payment/src/tests.rs @@ -21,11 +21,14 @@ use crate as pallet_transaction_payment; use codec::Encode; use sp_runtime::{ - testing::TestXt, traits::One, transaction_validity::InvalidTransaction, BuildStorage, + generic::UncheckedExtrinsic, + traits::{DispatchTransaction, One}, + transaction_validity::InvalidTransaction, + BuildStorage, }; use frame_support::{ - assert_noop, assert_ok, + assert_ok, dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, PostDispatchInfo}, traits::Currency, weights::Weight, @@ -128,44 +131,37 @@ fn default_post_info() -> PostDispatchInfo { PostDispatchInfo { actual_weight: None, pays_fee: Default::default() } } +type Ext = ChargeTransactionPayment; + #[test] -fn signed_extension_transaction_payment_work() { +fn transaction_extension_transaction_payment_work() { ExtBuilder::default() .balance_factor(10) .base_weight(Weight::from_parts(5, 0)) .build() .execute_with(|| { - let len = 10; - let pre = ChargeTransactionPayment::::from(0) - .pre_dispatch(&1, CALL, &info_from_weight(Weight::from_parts(5, 0)), len) + let info = info_from_weight(Weight::from_parts(5, 0)); + Ext::from(0) + .test_run(Some(1).into(), CALL, &info, 10, |_| { + assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10); + Ok(default_post_info()) + }) + .unwrap() .unwrap(); assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10); - - assert_ok!(ChargeTransactionPayment::::post_dispatch( - Some(pre), - &info_from_weight(Weight::from_parts(5, 0)), - &default_post_info(), - len, - &Ok(()) - )); - assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10); assert_eq!(FeeUnbalancedAmount::get(), 5 + 5 + 10); assert_eq!(TipUnbalancedAmount::get(), 0); FeeUnbalancedAmount::mutate(|a| *a = 0); - let pre = ChargeTransactionPayment::::from(5 /* tipped */) - .pre_dispatch(&2, CALL, &info_from_weight(Weight::from_parts(100, 0)), len) + let info = info_from_weight(Weight::from_parts(100, 0)); + Ext::from(5 /* tipped */) + .test_run(Some(2).into(), CALL, &info, 10, |_| { + assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); + Ok(post_info_from_weight(Weight::from_parts(50, 0))) + }) + .unwrap() .unwrap(); - assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); - - assert_ok!(ChargeTransactionPayment::::post_dispatch( - Some(pre), - &info_from_weight(Weight::from_parts(100, 0)), - &post_info_from_weight(Weight::from_parts(50, 0)), - len, - &Ok(()) - )); assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 50 - 5); assert_eq!(FeeUnbalancedAmount::get(), 5 + 10 + 50); assert_eq!(TipUnbalancedAmount::get(), 5); @@ -173,43 +169,37 @@ fn signed_extension_transaction_payment_work() { } #[test] -fn signed_extension_transaction_payment_multiplied_refund_works() { +fn transaction_extension_transaction_payment_multiplied_refund_works() { ExtBuilder::default() .balance_factor(10) .base_weight(Weight::from_parts(5, 0)) .build() .execute_with(|| { - let len = 10; >::put(Multiplier::saturating_from_rational(3, 2)); - let pre = ChargeTransactionPayment::::from(5 /* tipped */) - .pre_dispatch(&2, CALL, &info_from_weight(Weight::from_parts(100, 0)), len) + let len = 10; + let origin = Some(2).into(); + let info = info_from_weight(Weight::from_parts(100, 0)); + Ext::from(5 /* tipped */) + .test_run(origin, CALL, &info, len, |_| { + // 5 base fee, 10 byte fee, 3/2 * 100 weight fee, 5 tip + assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 150 - 5); + Ok(post_info_from_weight(Weight::from_parts(50, 0))) + }) + .unwrap() .unwrap(); - // 5 base fee, 10 byte fee, 3/2 * 100 weight fee, 5 tip - assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 150 - 5); - - assert_ok!(ChargeTransactionPayment::::post_dispatch( - Some(pre), - &info_from_weight(Weight::from_parts(100, 0)), - &post_info_from_weight(Weight::from_parts(50, 0)), - len, - &Ok(()) - )); + // 75 (3/2 of the returned 50 units of weight) is refunded assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 75 - 5); }); } #[test] -fn signed_extension_transaction_payment_is_bounded() { +fn transaction_extension_transaction_payment_is_bounded() { ExtBuilder::default().balance_factor(1000).byte_fee(0).build().execute_with(|| { // maximum weight possible - assert_ok!(ChargeTransactionPayment::::from(0).pre_dispatch( - &1, - CALL, - &info_from_weight(Weight::MAX), - 10 - )); + let info = info_from_weight(Weight::MAX); + assert_ok!(Ext::from(0).validate_and_prepare(Some(1).into(), CALL, &info, 10)); // fee will be proportional to what is the actual maximum weight in the runtime. assert_eq!( Balances::free_balance(&1), @@ -220,7 +210,7 @@ fn signed_extension_transaction_payment_is_bounded() { } #[test] -fn signed_extension_allows_free_transactions() { +fn transaction_extension_allows_free_transactions() { ExtBuilder::default() .base_weight(Weight::from_parts(100, 0)) .balance_factor(0) @@ -232,38 +222,28 @@ fn signed_extension_allows_free_transactions() { let len = 100; // This is a completely free (and thus wholly insecure/DoS-ridden) transaction. - let operational_transaction = DispatchInfo { + let op_tx = DispatchInfo { weight: Weight::from_parts(0, 0), class: DispatchClass::Operational, pays_fee: Pays::No, }; - assert_ok!(ChargeTransactionPayment::::from(0).validate( - &1, - CALL, - &operational_transaction, - len - )); + assert_ok!(Ext::from(0).validate_only(Some(1).into(), CALL, &op_tx, len)); // like a InsecureFreeNormal - let free_transaction = DispatchInfo { + let free_tx = DispatchInfo { weight: Weight::from_parts(0, 0), class: DispatchClass::Normal, pays_fee: Pays::Yes, }; - assert_noop!( - ChargeTransactionPayment::::from(0).validate( - &1, - CALL, - &free_transaction, - len - ), + assert_eq!( + Ext::from(0).validate_only(Some(1).into(), CALL, &free_tx, len).unwrap_err(), TransactionValidityError::Invalid(InvalidTransaction::Payment), ); }); } #[test] -fn signed_ext_length_fee_is_also_updated_per_congestion() { +fn transaction_ext_length_fee_is_also_updated_per_congestion() { ExtBuilder::default() .base_weight(Weight::from_parts(5, 0)) .balance_factor(10) @@ -272,16 +252,15 @@ fn signed_ext_length_fee_is_also_updated_per_congestion() { // all fees should be x1.5 >::put(Multiplier::saturating_from_rational(3, 2)); let len = 10; - - assert_ok!(ChargeTransactionPayment::::from(10) // tipped - .pre_dispatch(&1, CALL, &info_from_weight(Weight::from_parts(3, 0)), len)); + let info = &info_from_weight(Weight::from_parts(3, 0)); + assert_ok!(Ext::from(10).validate_and_prepare(Some(1).into(), CALL, info, len)); assert_eq!( Balances::free_balance(1), 100 // original - - 10 // tip - - 5 // base - - 10 // len - - (3 * 3 / 2) // adjusted weight + - 10 // tip + - 5 // base + - 10 // len + - (3 * 3 / 2) // adjusted weight ); }) } @@ -291,62 +270,62 @@ fn query_info_and_fee_details_works() { let call = RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 2, value: 69 }); let origin = 111111; let extra = (); - let xt = TestXt::new(call.clone(), Some((origin, extra))); + let xt = UncheckedExtrinsic::new_signed(call.clone(), origin, (), extra); let info = xt.get_dispatch_info(); let ext = xt.encode(); let len = ext.len() as u32; - let unsigned_xt = TestXt::<_, ()>::new(call, None); + let unsigned_xt = UncheckedExtrinsic::::new_bare(call); let unsigned_xt_info = unsigned_xt.get_dispatch_info(); ExtBuilder::default() - .base_weight(Weight::from_parts(5, 0)) - .weight_fee(2) - .build() - .execute_with(|| { - // all fees should be x1.5 - >::put(Multiplier::saturating_from_rational(3, 2)); - - assert_eq!( - TransactionPayment::query_info(xt.clone(), len), - RuntimeDispatchInfo { - weight: info.weight, - class: info.class, - partial_fee: 5 * 2 /* base * weight_fee */ - + len as u64 /* len * 1 */ - + info.weight.min(BlockWeights::get().max_block).ref_time() as u64 * 2 * 3 / 2 /* weight */ - }, - ); - - assert_eq!( - TransactionPayment::query_info(unsigned_xt.clone(), len), - RuntimeDispatchInfo { - weight: unsigned_xt_info.weight, - class: unsigned_xt_info.class, - partial_fee: 0, - }, - ); - - assert_eq!( - TransactionPayment::query_fee_details(xt, len), - FeeDetails { - inclusion_fee: Some(InclusionFee { - base_fee: 5 * 2, - len_fee: len as u64, - adjusted_weight_fee: info - .weight - .min(BlockWeights::get().max_block) - .ref_time() as u64 * 2 * 3 / 2 - }), - tip: 0, - }, - ); - - assert_eq!( - TransactionPayment::query_fee_details(unsigned_xt, len), - FeeDetails { inclusion_fee: None, tip: 0 }, - ); - }); + .base_weight(Weight::from_parts(5, 0)) + .weight_fee(2) + .build() + .execute_with(|| { + // all fees should be x1.5 + >::put(Multiplier::saturating_from_rational(3, 2)); + + assert_eq!( + TransactionPayment::query_info(xt.clone(), len), + RuntimeDispatchInfo { + weight: info.weight, + class: info.class, + partial_fee: 5 * 2 /* base * weight_fee */ + + len as u64 /* len * 1 */ + + info.weight.min(BlockWeights::get().max_block).ref_time() as u64 * 2 * 3 / 2 /* weight */ + }, + ); + + assert_eq!( + TransactionPayment::query_info(unsigned_xt.clone(), len), + RuntimeDispatchInfo { + weight: unsigned_xt_info.weight, + class: unsigned_xt_info.class, + partial_fee: 0, + }, + ); + + assert_eq!( + TransactionPayment::query_fee_details(xt, len), + FeeDetails { + inclusion_fee: Some(InclusionFee { + base_fee: 5 * 2, + len_fee: len as u64, + adjusted_weight_fee: info + .weight + .min(BlockWeights::get().max_block) + .ref_time() as u64 * 2 * 3 / 2 + }), + tip: 0, + }, + ); + + assert_eq!( + TransactionPayment::query_fee_details(unsigned_xt, len), + FeeDetails { inclusion_fee: None, tip: 0 }, + ); + }); } #[test] @@ -357,39 +336,39 @@ fn query_call_info_and_fee_details_works() { let len = encoded_call.len() as u32; ExtBuilder::default() - .base_weight(Weight::from_parts(5, 0)) - .weight_fee(2) - .build() - .execute_with(|| { - // all fees should be x1.5 - >::put(Multiplier::saturating_from_rational(3, 2)); - - assert_eq!( - TransactionPayment::query_call_info(call.clone(), len), - RuntimeDispatchInfo { - weight: info.weight, - class: info.class, - partial_fee: 5 * 2 /* base * weight_fee */ - + len as u64 /* len * 1 */ - + info.weight.min(BlockWeights::get().max_block).ref_time() as u64 * 2 * 3 / 2 /* weight */ - }, - ); - - assert_eq!( - TransactionPayment::query_call_fee_details(call, len), - FeeDetails { - inclusion_fee: Some(InclusionFee { - base_fee: 5 * 2, /* base * weight_fee */ - len_fee: len as u64, /* len * 1 */ - adjusted_weight_fee: info - .weight - .min(BlockWeights::get().max_block) - .ref_time() as u64 * 2 * 3 / 2 /* weight * weight_fee * multipler */ - }), - tip: 0, - }, - ); - }); + .base_weight(Weight::from_parts(5, 0)) + .weight_fee(2) + .build() + .execute_with(|| { + // all fees should be x1.5 + >::put(Multiplier::saturating_from_rational(3, 2)); + + assert_eq!( + TransactionPayment::query_call_info(call.clone(), len), + RuntimeDispatchInfo { + weight: info.weight, + class: info.class, + partial_fee: 5 * 2 /* base * weight_fee */ + + len as u64 /* len * 1 */ + + info.weight.min(BlockWeights::get().max_block).ref_time() as u64 * 2 * 3 / 2 /* weight */ + }, + ); + + assert_eq!( + TransactionPayment::query_call_fee_details(call, len), + FeeDetails { + inclusion_fee: Some(InclusionFee { + base_fee: 5 * 2, /* base * weight_fee */ + len_fee: len as u64, /* len * 1 */ + adjusted_weight_fee: info + .weight + .min(BlockWeights::get().max_block) + .ref_time() as u64 * 2 * 3 / 2 /* weight * weight_fee * multipler */ + }), + tip: 0, + }, + ); + }); } #[test] @@ -526,27 +505,23 @@ fn refund_does_not_recreate_account() { .execute_with(|| { // So events are emitted System::set_block_number(10); - let len = 10; - let pre = ChargeTransactionPayment::::from(5 /* tipped */) - .pre_dispatch(&2, CALL, &info_from_weight(Weight::from_parts(100, 0)), len) + let info = info_from_weight(Weight::from_parts(100, 0)); + Ext::from(5 /* tipped */) + .test_run(Some(2).into(), CALL, &info, 10, |origin| { + assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); + + // kill the account between pre and post dispatch + assert_ok!(Balances::transfer_allow_death( + origin, + 3, + Balances::free_balance(2) + )); + assert_eq!(Balances::free_balance(2), 0); + + Ok(post_info_from_weight(Weight::from_parts(50, 0))) + }) + .unwrap() .unwrap(); - assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); - - // kill the account between pre and post dispatch - assert_ok!(Balances::transfer_allow_death( - Some(2).into(), - 3, - Balances::free_balance(2) - )); - assert_eq!(Balances::free_balance(2), 0); - - assert_ok!(ChargeTransactionPayment::::post_dispatch( - Some(pre), - &info_from_weight(Weight::from_parts(100, 0)), - &post_info_from_weight(Weight::from_parts(50, 0)), - len, - &Ok(()) - )); assert_eq!(Balances::free_balance(2), 0); // Transfer Event System::assert_has_event(RuntimeEvent::Balances(pallet_balances::Event::Transfer { @@ -568,20 +543,15 @@ fn actual_weight_higher_than_max_refunds_nothing() { .base_weight(Weight::from_parts(5, 0)) .build() .execute_with(|| { - let len = 10; - let pre = ChargeTransactionPayment::::from(5 /* tipped */) - .pre_dispatch(&2, CALL, &info_from_weight(Weight::from_parts(100, 0)), len) + let info = info_from_weight(Weight::from_parts(100, 0)); + Ext::from(5 /* tipped */) + .test_run(Some(2).into(), CALL, &info, 10, |_| { + assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); + Ok(post_info_from_weight(Weight::from_parts(101, 0))) + }) + .unwrap() .unwrap(); assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); - - assert_ok!(ChargeTransactionPayment::::post_dispatch( - Some(pre), - &info_from_weight(Weight::from_parts(100, 0)), - &post_info_from_weight(Weight::from_parts(101, 0)), - len, - &Ok(()) - )); - assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); }); } @@ -594,25 +564,20 @@ fn zero_transfer_on_free_transaction() { .execute_with(|| { // So events are emitted System::set_block_number(10); - let len = 10; - let dispatch_info = DispatchInfo { + let info = DispatchInfo { weight: Weight::from_parts(100, 0), pays_fee: Pays::No, class: DispatchClass::Normal, }; let user = 69; - let pre = ChargeTransactionPayment::::from(0) - .pre_dispatch(&user, CALL, &dispatch_info, len) + Ext::from(0) + .test_run(Some(user).into(), CALL, &info, 10, |_| { + assert_eq!(Balances::total_balance(&user), 0); + Ok(default_post_info()) + }) + .unwrap() .unwrap(); assert_eq!(Balances::total_balance(&user), 0); - assert_ok!(ChargeTransactionPayment::::post_dispatch( - Some(pre), - &dispatch_info, - &default_post_info(), - len, - &Ok(()) - )); - assert_eq!(Balances::total_balance(&user), 0); // TransactionFeePaid Event System::assert_has_event(RuntimeEvent::TransactionPayment( pallet_transaction_payment::Event::TransactionFeePaid { @@ -639,19 +604,11 @@ fn refund_consistent_with_actual_weight() { >::put(Multiplier::saturating_from_rational(5, 4)); - let pre = ChargeTransactionPayment::::from(tip) - .pre_dispatch(&2, CALL, &info, len) + Ext::from(tip) + .test_run(Some(2).into(), CALL, &info, len, |_| Ok(post_info)) + .unwrap() .unwrap(); - ChargeTransactionPayment::::post_dispatch( - Some(pre), - &info, - &post_info, - len, - &Ok(()), - ) - .unwrap(); - let refund_based_fee = prev_balance - Balances::free_balance(2); let actual_fee = Pallet::::compute_actual_fee(len as u32, &info, &post_info, tip); @@ -673,18 +630,13 @@ fn should_alter_operational_priority() { class: DispatchClass::Normal, pays_fee: Pays::Yes, }; - let priority = ChargeTransactionPayment::(tip) - .validate(&2, CALL, &normal, len) - .unwrap() - .priority; + let ext = Ext::from(tip); + let priority = ext.validate_only(Some(2).into(), CALL, &normal, len).unwrap().0.priority; assert_eq!(priority, 60); - let priority = ChargeTransactionPayment::(2 * tip) - .validate(&2, CALL, &normal, len) - .unwrap() - .priority; - + let ext = Ext::from(2 * tip); + let priority = ext.validate_only(Some(2).into(), CALL, &normal, len).unwrap().0.priority; assert_eq!(priority, 110); }); @@ -694,16 +646,13 @@ fn should_alter_operational_priority() { class: DispatchClass::Operational, pays_fee: Pays::Yes, }; - let priority = ChargeTransactionPayment::(tip) - .validate(&2, CALL, &op, len) - .unwrap() - .priority; + + let ext = Ext::from(tip); + let priority = ext.validate_only(Some(2).into(), CALL, &op, len).unwrap().0.priority; assert_eq!(priority, 5810); - let priority = ChargeTransactionPayment::(2 * tip) - .validate(&2, CALL, &op, len) - .unwrap() - .priority; + let ext = Ext::from(2 * tip); + let priority = ext.validate_only(Some(2).into(), CALL, &op, len).unwrap().0.priority; assert_eq!(priority, 6110); }); } @@ -719,11 +668,8 @@ fn no_tip_has_some_priority() { class: DispatchClass::Normal, pays_fee: Pays::Yes, }; - let priority = ChargeTransactionPayment::(tip) - .validate(&2, CALL, &normal, len) - .unwrap() - .priority; - + let ext = Ext::from(tip); + let priority = ext.validate_only(Some(2).into(), CALL, &normal, len).unwrap().0.priority; assert_eq!(priority, 10); }); @@ -733,10 +679,8 @@ fn no_tip_has_some_priority() { class: DispatchClass::Operational, pays_fee: Pays::Yes, }; - let priority = ChargeTransactionPayment::(tip) - .validate(&2, CALL, &op, len) - .unwrap() - .priority; + let ext = Ext::from(tip); + let priority = ext.validate_only(Some(2).into(), CALL, &op, len).unwrap().0.priority; assert_eq!(priority, 5510); }); } @@ -744,8 +688,8 @@ fn no_tip_has_some_priority() { #[test] fn higher_tip_have_higher_priority() { let get_priorities = |tip: u64| { - let mut priority1 = 0; - let mut priority2 = 0; + let mut pri1 = 0; + let mut pri2 = 0; let len = 10; ExtBuilder::default().balance_factor(100).build().execute_with(|| { let normal = DispatchInfo { @@ -753,10 +697,8 @@ fn higher_tip_have_higher_priority() { class: DispatchClass::Normal, pays_fee: Pays::Yes, }; - priority1 = ChargeTransactionPayment::(tip) - .validate(&2, CALL, &normal, len) - .unwrap() - .priority; + let ext = Ext::from(tip); + pri1 = ext.validate_only(Some(2).into(), CALL, &normal, len).unwrap().0.priority; }); ExtBuilder::default().balance_factor(100).build().execute_with(|| { @@ -765,13 +707,11 @@ fn higher_tip_have_higher_priority() { class: DispatchClass::Operational, pays_fee: Pays::Yes, }; - priority2 = ChargeTransactionPayment::(tip) - .validate(&2, CALL, &op, len) - .unwrap() - .priority; + let ext = Ext::from(tip); + pri2 = ext.validate_only(Some(2).into(), CALL, &op, len).unwrap().0.priority; }); - (priority1, priority2) + (pri1, pri2) }; let mut prev_priorities = get_priorities(0); @@ -799,19 +739,11 @@ fn post_info_can_change_pays_fee() { >::put(Multiplier::saturating_from_rational(5, 4)); - let pre = ChargeTransactionPayment::::from(tip) - .pre_dispatch(&2, CALL, &info, len) + let post_info = ChargeTransactionPayment::::from(tip) + .test_run(Some(2).into(), CALL, &info, len, |_| Ok(post_info)) + .unwrap() .unwrap(); - ChargeTransactionPayment::::post_dispatch( - Some(pre), - &info, - &post_info, - len, - &Ok(()), - ) - .unwrap(); - let refund_based_fee = prev_balance - Balances::free_balance(2); let actual_fee = Pallet::::compute_actual_fee(len as u32, &info, &post_info, tip); diff --git a/substrate/frame/transaction-payment/src/types.rs b/substrate/frame/transaction-payment/src/types.rs index 25cecc58a63..bfb3012fef0 100644 --- a/substrate/frame/transaction-payment/src/types.rs +++ b/substrate/frame/transaction-payment/src/types.rs @@ -112,7 +112,7 @@ pub struct RuntimeDispatchInfo /// The inclusion fee of this dispatch. /// /// This does not include a tip or anything else that - /// depends on the signature (i.e. depends on a `SignedExtension`). + /// depends on the signature (i.e. depends on a `TransactionExtension`). #[cfg_attr(feature = "std", serde(with = "serde_balance"))] pub partial_fee: Balance, } diff --git a/substrate/frame/transaction-payment/src/weights.rs b/substrate/frame/transaction-payment/src/weights.rs new file mode 100644 index 00000000000..bcffb2eb331 --- /dev/null +++ b/substrate/frame/transaction-payment/src/weights.rs @@ -0,0 +1,92 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Autogenerated weights for `pallet_transaction_payment` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` + +// Executed Command: +// ./target/production/substrate-node +// benchmark +// pallet +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_transaction_payment +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./substrate/frame/transaction-payment/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for `pallet_transaction_payment`. +pub trait WeightInfo { + fn charge_transaction_payment() -> Weight; +} + +/// Weights for `pallet_transaction_payment` using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Authorship::Author` (r:1 w:0) + /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `System::Digest` (r:1 w:0) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn charge_transaction_payment() -> Weight { + // Proof Size summary in bytes: + // Measured: `248` + // Estimated: `1733` + // Minimum execution time: 40_506_000 picoseconds. + Weight::from_parts(41_647_000, 1733) + .saturating_add(T::DbWeight::get().reads(3_u64)) + } +} + +// For backwards compatibility and tests. +impl WeightInfo for () { + /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) + /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Authorship::Author` (r:1 w:0) + /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `System::Digest` (r:1 w:0) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn charge_transaction_payment() -> Weight { + // Proof Size summary in bytes: + // Measured: `248` + // Estimated: `1733` + // Minimum execution time: 40_506_000 picoseconds. + Weight::from_parts(41_647_000, 1733) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + } +} diff --git a/substrate/frame/transaction-storage/src/weights.rs b/substrate/frame/transaction-storage/src/weights.rs index 519317177c4..bfbed62c5a3 100644 --- a/substrate/frame/transaction-storage/src/weights.rs +++ b/substrate/frame/transaction-storage/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_transaction_storage +//! Autogenerated weights for `pallet_transaction_storage` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/transaction-storage/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/transaction-storage/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,125 +49,133 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_transaction_storage. +/// Weight functions needed for `pallet_transaction_storage`. pub trait WeightInfo { fn store(l: u32, ) -> Weight; fn renew() -> Weight; fn check_proof_max() -> Weight; } -/// Weights for pallet_transaction_storage using the Substrate node and recommended hardware. +/// Weights for `pallet_transaction_storage` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: TransactionStorage ByteFee (r:1 w:0) - /// Proof: TransactionStorage ByteFee (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: TransactionStorage EntryFee (r:1 w:0) - /// Proof: TransactionStorage EntryFee (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: TransactionStorage BlockTransactions (r:1 w:1) - /// Proof: TransactionStorage BlockTransactions (max_values: Some(1), max_size: Some(36866), added: 37361, mode: MaxEncodedLen) + /// Storage: `TransactionStorage::ByteFee` (r:1 w:0) + /// Proof: `TransactionStorage::ByteFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `TransactionStorage::EntryFee` (r:1 w:0) + /// Proof: `TransactionStorage::EntryFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `TransactionStorage::BlockTransactions` (r:1 w:1) + /// Proof: `TransactionStorage::BlockTransactions` (`max_values`: Some(1), `max_size`: Some(36866), added: 37361, mode: `MaxEncodedLen`) /// The range of component `l` is `[1, 8388608]`. fn store(l: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `176` + // Measured: `242` // Estimated: `38351` - // Minimum execution time: 34_844_000 picoseconds. - Weight::from_parts(35_489_000, 38351) + // Minimum execution time: 57_912_000 picoseconds. + Weight::from_parts(58_642_000, 38351) // Standard Error: 11 - .saturating_add(Weight::from_parts(6_912, 0).saturating_mul(l.into())) - .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + .saturating_add(Weight::from_parts(6_778, 0).saturating_mul(l.into())) + .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: TransactionStorage Transactions (r:1 w:0) - /// Proof: TransactionStorage Transactions (max_values: None, max_size: Some(36886), added: 39361, mode: MaxEncodedLen) - /// Storage: TransactionStorage ByteFee (r:1 w:0) - /// Proof: TransactionStorage ByteFee (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: TransactionStorage EntryFee (r:1 w:0) - /// Proof: TransactionStorage EntryFee (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: TransactionStorage BlockTransactions (r:1 w:1) - /// Proof: TransactionStorage BlockTransactions (max_values: Some(1), max_size: Some(36866), added: 37361, mode: MaxEncodedLen) + /// Storage: `TransactionStorage::Transactions` (r:1 w:0) + /// Proof: `TransactionStorage::Transactions` (`max_values`: None, `max_size`: Some(36886), added: 39361, mode: `MaxEncodedLen`) + /// Storage: `TransactionStorage::ByteFee` (r:1 w:0) + /// Proof: `TransactionStorage::ByteFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `TransactionStorage::EntryFee` (r:1 w:0) + /// Proof: `TransactionStorage::EntryFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `TransactionStorage::BlockTransactions` (r:1 w:1) + /// Proof: `TransactionStorage::BlockTransactions` (`max_values`: Some(1), `max_size`: Some(36866), added: 37361, mode: `MaxEncodedLen`) fn renew() -> Weight { // Proof Size summary in bytes: - // Measured: `326` + // Measured: `430` // Estimated: `40351` - // Minimum execution time: 48_244_000 picoseconds. - Weight::from_parts(50_939_000, 40351) - .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + // Minimum execution time: 72_571_000 picoseconds. + Weight::from_parts(74_832_000, 40351) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: TransactionStorage ProofChecked (r:1 w:1) - /// Proof: TransactionStorage ProofChecked (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) - /// Storage: TransactionStorage StoragePeriod (r:1 w:0) - /// Proof: TransactionStorage StoragePeriod (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: TransactionStorage ChunkCount (r:1 w:0) - /// Proof: TransactionStorage ChunkCount (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) - /// Storage: System ParentHash (r:1 w:0) - /// Proof: System ParentHash (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) - /// Storage: TransactionStorage Transactions (r:1 w:0) - /// Proof: TransactionStorage Transactions (max_values: None, max_size: Some(36886), added: 39361, mode: MaxEncodedLen) + /// Storage: `TransactionStorage::ProofChecked` (r:1 w:1) + /// Proof: `TransactionStorage::ProofChecked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `TransactionStorage::StoragePeriod` (r:1 w:0) + /// Proof: `TransactionStorage::StoragePeriod` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TransactionStorage::ChunkCount` (r:1 w:0) + /// Proof: `TransactionStorage::ChunkCount` (`max_values`: None, `max_size`: Some(24), added: 2499, mode: `MaxEncodedLen`) + /// Storage: `System::ParentHash` (r:1 w:0) + /// Proof: `System::ParentHash` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `TransactionStorage::Transactions` (r:1 w:0) + /// Proof: `TransactionStorage::Transactions` (`max_values`: None, `max_size`: Some(36886), added: 39361, mode: `MaxEncodedLen`) fn check_proof_max() -> Weight { // Proof Size summary in bytes: - // Measured: `37145` + // Measured: `37211` // Estimated: `40351` - // Minimum execution time: 80_913_000 picoseconds. - Weight::from_parts(84_812_000, 40351) + // Minimum execution time: 65_985_000 picoseconds. + Weight::from_parts(72_960_000, 40351) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: TransactionStorage ByteFee (r:1 w:0) - /// Proof: TransactionStorage ByteFee (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: TransactionStorage EntryFee (r:1 w:0) - /// Proof: TransactionStorage EntryFee (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: TransactionStorage BlockTransactions (r:1 w:1) - /// Proof: TransactionStorage BlockTransactions (max_values: Some(1), max_size: Some(36866), added: 37361, mode: MaxEncodedLen) + /// Storage: `TransactionStorage::ByteFee` (r:1 w:0) + /// Proof: `TransactionStorage::ByteFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `TransactionStorage::EntryFee` (r:1 w:0) + /// Proof: `TransactionStorage::EntryFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `TransactionStorage::BlockTransactions` (r:1 w:1) + /// Proof: `TransactionStorage::BlockTransactions` (`max_values`: Some(1), `max_size`: Some(36866), added: 37361, mode: `MaxEncodedLen`) /// The range of component `l` is `[1, 8388608]`. fn store(l: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `176` + // Measured: `242` // Estimated: `38351` - // Minimum execution time: 34_844_000 picoseconds. - Weight::from_parts(35_489_000, 38351) + // Minimum execution time: 57_912_000 picoseconds. + Weight::from_parts(58_642_000, 38351) // Standard Error: 11 - .saturating_add(Weight::from_parts(6_912, 0).saturating_mul(l.into())) - .saturating_add(RocksDbWeight::get().reads(3_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + .saturating_add(Weight::from_parts(6_778, 0).saturating_mul(l.into())) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: TransactionStorage Transactions (r:1 w:0) - /// Proof: TransactionStorage Transactions (max_values: None, max_size: Some(36886), added: 39361, mode: MaxEncodedLen) - /// Storage: TransactionStorage ByteFee (r:1 w:0) - /// Proof: TransactionStorage ByteFee (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: TransactionStorage EntryFee (r:1 w:0) - /// Proof: TransactionStorage EntryFee (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: TransactionStorage BlockTransactions (r:1 w:1) - /// Proof: TransactionStorage BlockTransactions (max_values: Some(1), max_size: Some(36866), added: 37361, mode: MaxEncodedLen) + /// Storage: `TransactionStorage::Transactions` (r:1 w:0) + /// Proof: `TransactionStorage::Transactions` (`max_values`: None, `max_size`: Some(36886), added: 39361, mode: `MaxEncodedLen`) + /// Storage: `TransactionStorage::ByteFee` (r:1 w:0) + /// Proof: `TransactionStorage::ByteFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `TransactionStorage::EntryFee` (r:1 w:0) + /// Proof: `TransactionStorage::EntryFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: `TransactionStorage::BlockTransactions` (r:1 w:1) + /// Proof: `TransactionStorage::BlockTransactions` (`max_values`: Some(1), `max_size`: Some(36866), added: 37361, mode: `MaxEncodedLen`) fn renew() -> Weight { // Proof Size summary in bytes: - // Measured: `326` + // Measured: `430` // Estimated: `40351` - // Minimum execution time: 48_244_000 picoseconds. - Weight::from_parts(50_939_000, 40351) - .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + // Minimum execution time: 72_571_000 picoseconds. + Weight::from_parts(74_832_000, 40351) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: TransactionStorage ProofChecked (r:1 w:1) - /// Proof: TransactionStorage ProofChecked (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) - /// Storage: TransactionStorage StoragePeriod (r:1 w:0) - /// Proof: TransactionStorage StoragePeriod (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: TransactionStorage ChunkCount (r:1 w:0) - /// Proof: TransactionStorage ChunkCount (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) - /// Storage: System ParentHash (r:1 w:0) - /// Proof: System ParentHash (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) - /// Storage: TransactionStorage Transactions (r:1 w:0) - /// Proof: TransactionStorage Transactions (max_values: None, max_size: Some(36886), added: 39361, mode: MaxEncodedLen) + /// Storage: `TransactionStorage::ProofChecked` (r:1 w:1) + /// Proof: `TransactionStorage::ProofChecked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `TransactionStorage::StoragePeriod` (r:1 w:0) + /// Proof: `TransactionStorage::StoragePeriod` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TransactionStorage::ChunkCount` (r:1 w:0) + /// Proof: `TransactionStorage::ChunkCount` (`max_values`: None, `max_size`: Some(24), added: 2499, mode: `MaxEncodedLen`) + /// Storage: `System::ParentHash` (r:1 w:0) + /// Proof: `System::ParentHash` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `TransactionStorage::Transactions` (r:1 w:0) + /// Proof: `TransactionStorage::Transactions` (`max_values`: None, `max_size`: Some(36886), added: 39361, mode: `MaxEncodedLen`) fn check_proof_max() -> Weight { // Proof Size summary in bytes: - // Measured: `37145` + // Measured: `37211` // Estimated: `40351` - // Minimum execution time: 80_913_000 picoseconds. - Weight::from_parts(84_812_000, 40351) + // Minimum execution time: 65_985_000 picoseconds. + Weight::from_parts(72_960_000, 40351) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/treasury/src/weights.rs b/substrate/frame/treasury/src/weights.rs index 030e18980eb..8ef4f89fd65 100644 --- a/substrate/frame/treasury/src/weights.rs +++ b/substrate/frame/treasury/src/weights.rs @@ -15,27 +15,31 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_treasury +//! Autogenerated weights for `pallet_treasury` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-07-07, STEPS: `20`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `cob`, CPU: `` -//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/debug/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev -// --steps=20 -// --repeat=2 -// --pallet=pallet-treasury +// --steps=50 +// --repeat=20 +// --pallet=pallet_treasury +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/treasury/src/._weights.rs -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/treasury/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -45,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_treasury. +/// Weight functions needed for `pallet_treasury`. pub trait WeightInfo { fn spend_local() -> Weight; fn propose_spend() -> Weight; @@ -59,304 +63,304 @@ pub trait WeightInfo { fn void_spend() -> Weight; } -/// Weights for pallet_treasury using the Substrate node and recommended hardware. +/// Weights for `pallet_treasury` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Treasury ProposalCount (r:1 w:1) - /// Proof: Treasury ProposalCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Treasury Approvals (r:1 w:1) - /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) - /// Storage: Treasury Proposals (r:0 w:1) - /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: `Treasury::ProposalCount` (r:1 w:1) + /// Proof: `Treasury::ProposalCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Approvals` (r:1 w:1) + /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Proposals` (r:0 w:1) + /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) fn spend_local() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `1887` - // Minimum execution time: 179_000_000 picoseconds. - Weight::from_parts(190_000_000, 1887) + // Minimum execution time: 11_686_000 picoseconds. + Weight::from_parts(12_138_000, 1887) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: Treasury ProposalCount (r:1 w:1) - /// Proof: Treasury ProposalCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Treasury Proposals (r:0 w:1) - /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: `Treasury::ProposalCount` (r:1 w:1) + /// Proof: `Treasury::ProposalCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Proposals` (r:0 w:1) + /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) fn propose_spend() -> Weight { // Proof Size summary in bytes: // Measured: `177` // Estimated: `1489` - // Minimum execution time: 349_000_000 picoseconds. - Weight::from_parts(398_000_000, 1489) + // Minimum execution time: 23_773_000 picoseconds. + Weight::from_parts(24_801_000, 1489) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Treasury Proposals (r:1 w:1) - /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Treasury::Proposals` (r:1 w:1) + /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn reject_proposal() -> Weight { // Proof Size summary in bytes: // Measured: `335` // Estimated: `3593` - // Minimum execution time: 367_000_000 picoseconds. - Weight::from_parts(388_000_000, 3593) + // Minimum execution time: 24_533_000 picoseconds. + Weight::from_parts(25_731_000, 3593) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Treasury Proposals (r:1 w:0) - /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) - /// Storage: Treasury Approvals (r:1 w:1) - /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: `Treasury::Proposals` (r:1 w:0) + /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Approvals` (r:1 w:1) + /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) /// The range of component `p` is `[0, 99]`. fn approve_proposal(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `483 + p * (9 ±0)` + // Measured: `504 + p * (8 ±0)` // Estimated: `3573` - // Minimum execution time: 111_000_000 picoseconds. - Weight::from_parts(108_813_243, 3573) - // Standard Error: 147_887 - .saturating_add(Weight::from_parts(683_216, 0).saturating_mul(p.into())) + // Minimum execution time: 8_245_000 picoseconds. + Weight::from_parts(11_300_222, 3573) + // Standard Error: 1_080 + .saturating_add(Weight::from_parts(71_375, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Treasury Approvals (r:1 w:1) - /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: `Treasury::Approvals` (r:1 w:1) + /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) fn remove_approval() -> Weight { // Proof Size summary in bytes: // Measured: `161` // Estimated: `1887` - // Minimum execution time: 71_000_000 picoseconds. - Weight::from_parts(78_000_000, 1887) + // Minimum execution time: 6_231_000 picoseconds. + Weight::from_parts(6_517_000, 1887) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Treasury Deactivated (r:1 w:1) - /// Proof: Treasury Deactivated (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: Treasury Approvals (r:1 w:1) - /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) - /// Storage: Treasury Proposals (r:99 w:99) - /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) - /// Storage: System Account (r:198 w:198) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Bounties BountyApprovals (r:1 w:1) - /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: `Treasury::Deactivated` (r:1 w:1) + /// Proof: `Treasury::Deactivated` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Approvals` (r:1 w:1) + /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Proposals` (r:99 w:99) + /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:198 w:198) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Bounties::BountyApprovals` (r:1 w:1) + /// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) /// The range of component `p` is `[0, 99]`. fn on_initialize_proposals(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `427 + p * (251 ±0)` + // Measured: `451 + p * (251 ±0)` // Estimated: `1887 + p * (5206 ±0)` - // Minimum execution time: 614_000_000 picoseconds. - Weight::from_parts(498_501_558, 1887) - // Standard Error: 1_070_260 - .saturating_add(Weight::from_parts(599_011_690, 0).saturating_mul(p.into())) + // Minimum execution time: 30_729_000 picoseconds. + Weight::from_parts(37_861_389, 1887) + // Standard Error: 18_741 + .saturating_add(Weight::from_parts(31_377_118, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(p.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(p.into()))) .saturating_add(Weight::from_parts(0, 5206).saturating_mul(p.into())) } - /// Storage: AssetRate ConversionRateToNative (r:1 w:0) - /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) - /// Storage: Treasury SpendCount (r:1 w:1) - /// Proof: Treasury SpendCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Treasury Spends (r:0 w:1) - /// Proof: Treasury Spends (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:0) + /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `Treasury::SpendCount` (r:1 w:1) + /// Proof: `Treasury::SpendCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Spends` (r:0 w:1) + /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn spend() -> Weight { // Proof Size summary in bytes: // Measured: `140` // Estimated: `3501` - // Minimum execution time: 214_000_000 picoseconds. - Weight::from_parts(216_000_000, 3501) + // Minimum execution time: 13_700_000 picoseconds. + Weight::from_parts(14_519_000, 3501) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Treasury Spends (r:1 w:1) - /// Proof: Treasury Spends (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:2 w:2) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Treasury::Spends` (r:1 w:1) + /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:2 w:2) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn payout() -> Weight { // Proof Size summary in bytes: - // Measured: `705` + // Measured: `709` // Estimated: `6208` - // Minimum execution time: 760_000_000 picoseconds. - Weight::from_parts(822_000_000, 6208) + // Minimum execution time: 54_888_000 picoseconds. + Weight::from_parts(55_966_000, 6208) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: Treasury Spends (r:1 w:1) - /// Proof: Treasury Spends (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `Treasury::Spends` (r:1 w:1) + /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn check_status() -> Weight { // Proof Size summary in bytes: - // Measured: `194` - // Estimated: `3534` - // Minimum execution time: 153_000_000 picoseconds. - Weight::from_parts(160_000_000, 3534) + // Measured: `198` + // Estimated: `3538` + // Minimum execution time: 11_802_000 picoseconds. + Weight::from_parts(12_421_000, 3538) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: Treasury Spends (r:1 w:1) - /// Proof: Treasury Spends (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `Treasury::Spends` (r:1 w:1) + /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn void_spend() -> Weight { // Proof Size summary in bytes: - // Measured: `194` - // Estimated: `3534` - // Minimum execution time: 147_000_000 picoseconds. - Weight::from_parts(181_000_000, 3534) + // Measured: `198` + // Estimated: `3538` + // Minimum execution time: 10_571_000 picoseconds. + Weight::from_parts(11_052_000, 3538) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Treasury ProposalCount (r:1 w:1) - /// Proof: Treasury ProposalCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Treasury Approvals (r:1 w:1) - /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) - /// Storage: Treasury Proposals (r:0 w:1) - /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: `Treasury::ProposalCount` (r:1 w:1) + /// Proof: `Treasury::ProposalCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Approvals` (r:1 w:1) + /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Proposals` (r:0 w:1) + /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) fn spend_local() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `1887` - // Minimum execution time: 179_000_000 picoseconds. - Weight::from_parts(190_000_000, 1887) + // Minimum execution time: 11_686_000 picoseconds. + Weight::from_parts(12_138_000, 1887) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: Treasury ProposalCount (r:1 w:1) - /// Proof: Treasury ProposalCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Treasury Proposals (r:0 w:1) - /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: `Treasury::ProposalCount` (r:1 w:1) + /// Proof: `Treasury::ProposalCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Proposals` (r:0 w:1) + /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) fn propose_spend() -> Weight { // Proof Size summary in bytes: // Measured: `177` // Estimated: `1489` - // Minimum execution time: 349_000_000 picoseconds. - Weight::from_parts(398_000_000, 1489) + // Minimum execution time: 23_773_000 picoseconds. + Weight::from_parts(24_801_000, 1489) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Treasury Proposals (r:1 w:1) - /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Treasury::Proposals` (r:1 w:1) + /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn reject_proposal() -> Weight { // Proof Size summary in bytes: // Measured: `335` // Estimated: `3593` - // Minimum execution time: 367_000_000 picoseconds. - Weight::from_parts(388_000_000, 3593) + // Minimum execution time: 24_533_000 picoseconds. + Weight::from_parts(25_731_000, 3593) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Treasury Proposals (r:1 w:0) - /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) - /// Storage: Treasury Approvals (r:1 w:1) - /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: `Treasury::Proposals` (r:1 w:0) + /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Approvals` (r:1 w:1) + /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) /// The range of component `p` is `[0, 99]`. fn approve_proposal(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `483 + p * (9 ±0)` + // Measured: `504 + p * (8 ±0)` // Estimated: `3573` - // Minimum execution time: 111_000_000 picoseconds. - Weight::from_parts(108_813_243, 3573) - // Standard Error: 147_887 - .saturating_add(Weight::from_parts(683_216, 0).saturating_mul(p.into())) + // Minimum execution time: 8_245_000 picoseconds. + Weight::from_parts(11_300_222, 3573) + // Standard Error: 1_080 + .saturating_add(Weight::from_parts(71_375, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Treasury Approvals (r:1 w:1) - /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: `Treasury::Approvals` (r:1 w:1) + /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) fn remove_approval() -> Weight { // Proof Size summary in bytes: // Measured: `161` // Estimated: `1887` - // Minimum execution time: 71_000_000 picoseconds. - Weight::from_parts(78_000_000, 1887) + // Minimum execution time: 6_231_000 picoseconds. + Weight::from_parts(6_517_000, 1887) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Treasury Deactivated (r:1 w:1) - /// Proof: Treasury Deactivated (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) - /// Storage: Treasury Approvals (r:1 w:1) - /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) - /// Storage: Treasury Proposals (r:99 w:99) - /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) - /// Storage: System Account (r:198 w:198) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Bounties BountyApprovals (r:1 w:1) - /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: `Treasury::Deactivated` (r:1 w:1) + /// Proof: `Treasury::Deactivated` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Approvals` (r:1 w:1) + /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Proposals` (r:99 w:99) + /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:198 w:198) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Bounties::BountyApprovals` (r:1 w:1) + /// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) /// The range of component `p` is `[0, 99]`. fn on_initialize_proposals(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `427 + p * (251 ±0)` + // Measured: `451 + p * (251 ±0)` // Estimated: `1887 + p * (5206 ±0)` - // Minimum execution time: 614_000_000 picoseconds. - Weight::from_parts(498_501_558, 1887) - // Standard Error: 1_070_260 - .saturating_add(Weight::from_parts(599_011_690, 0).saturating_mul(p.into())) + // Minimum execution time: 30_729_000 picoseconds. + Weight::from_parts(37_861_389, 1887) + // Standard Error: 18_741 + .saturating_add(Weight::from_parts(31_377_118, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(p.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(p.into()))) .saturating_add(Weight::from_parts(0, 5206).saturating_mul(p.into())) } - /// Storage: AssetRate ConversionRateToNative (r:1 w:0) - /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) - /// Storage: Treasury SpendCount (r:1 w:1) - /// Proof: Treasury SpendCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: Treasury Spends (r:0 w:1) - /// Proof: Treasury Spends (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:0) + /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: `Treasury::SpendCount` (r:1 w:1) + /// Proof: `Treasury::SpendCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Treasury::Spends` (r:0 w:1) + /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn spend() -> Weight { // Proof Size summary in bytes: // Measured: `140` // Estimated: `3501` - // Minimum execution time: 214_000_000 picoseconds. - Weight::from_parts(216_000_000, 3501) + // Minimum execution time: 13_700_000 picoseconds. + Weight::from_parts(14_519_000, 3501) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Treasury Spends (r:1 w:1) - /// Proof: Treasury Spends (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) - /// Storage: Assets Asset (r:1 w:1) - /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) - /// Storage: Assets Account (r:2 w:2) - /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: `Treasury::Spends` (r:1 w:1) + /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `Assets::Account` (r:2 w:2) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn payout() -> Weight { // Proof Size summary in bytes: - // Measured: `705` + // Measured: `709` // Estimated: `6208` - // Minimum execution time: 760_000_000 picoseconds. - Weight::from_parts(822_000_000, 6208) + // Minimum execution time: 54_888_000 picoseconds. + Weight::from_parts(55_966_000, 6208) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: Treasury Spends (r:1 w:1) - /// Proof: Treasury Spends (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `Treasury::Spends` (r:1 w:1) + /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn check_status() -> Weight { // Proof Size summary in bytes: - // Measured: `194` - // Estimated: `3534` - // Minimum execution time: 153_000_000 picoseconds. - Weight::from_parts(160_000_000, 3534) + // Measured: `198` + // Estimated: `3538` + // Minimum execution time: 11_802_000 picoseconds. + Weight::from_parts(12_421_000, 3538) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: Treasury Spends (r:1 w:1) - /// Proof: Treasury Spends (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: `Treasury::Spends` (r:1 w:1) + /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn void_spend() -> Weight { // Proof Size summary in bytes: - // Measured: `194` - // Estimated: `3534` - // Minimum execution time: 147_000_000 picoseconds. - Weight::from_parts(181_000_000, 3534) + // Measured: `198` + // Estimated: `3538` + // Minimum execution time: 10_571_000 picoseconds. + Weight::from_parts(11_052_000, 3538) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/tx-pause/src/weights.rs b/substrate/frame/tx-pause/src/weights.rs index b733e64b159..14fead12a8e 100644 --- a/substrate/frame/tx-pause/src/weights.rs +++ b/substrate/frame/tx-pause/src/weights.rs @@ -17,27 +17,29 @@ //! Autogenerated weights for `pallet_tx_pause` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-08-24, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-aahe6cbd-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// target/production/substrate-node +// ./target/production/substrate-node // benchmark // pallet +// --chain=dev // --steps=50 // --repeat=20 +// --pallet=pallet_tx_pause +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/substrate/.git/.artifacts/bench.json -// --pallet=pallet_tx_pause -// --chain=dev -// --header=./HEADER-APACHE2 -// --output=./frame/tx-pause/src/weights.rs -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/tx-pause/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -62,8 +64,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `3` // Estimated: `3997` - // Minimum execution time: 15_096_000 picoseconds. - Weight::from_parts(15_437_000, 3997) + // Minimum execution time: 12_014_000 picoseconds. + Weight::from_parts(12_980_000, 3997) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -73,8 +75,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `565` // Estimated: `3997` - // Minimum execution time: 21_546_000 picoseconds. - Weight::from_parts(22_178_000, 3997) + // Minimum execution time: 17_955_000 picoseconds. + Weight::from_parts(18_348_000, 3997) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -88,8 +90,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `3` // Estimated: `3997` - // Minimum execution time: 15_096_000 picoseconds. - Weight::from_parts(15_437_000, 3997) + // Minimum execution time: 12_014_000 picoseconds. + Weight::from_parts(12_980_000, 3997) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -99,8 +101,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `565` // Estimated: `3997` - // Minimum execution time: 21_546_000 picoseconds. - Weight::from_parts(22_178_000, 3997) + // Minimum execution time: 17_955_000 picoseconds. + Weight::from_parts(18_348_000, 3997) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/uniques/src/weights.rs b/substrate/frame/uniques/src/weights.rs index eb80ee550a1..6c7b60b82e5 100644 --- a/substrate/frame/uniques/src/weights.rs +++ b/substrate/frame/uniques/src/weights.rs @@ -17,27 +17,29 @@ //! Autogenerated weights for `pallet_uniques` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-07-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-gghbxkbs-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: ``, WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// target/production/substrate +// ./target/production/substrate-node // benchmark // pallet +// --chain=dev // --steps=50 // --repeat=20 +// --pallet=pallet_uniques +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/substrate/.git/.artifacts/bench.json -// --pallet=pallet_uniques -// --chain=dev -// --header=./HEADER-APACHE2 -// --output=./frame/uniques/src/weights.rs -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/uniques/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -88,8 +90,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `249` // Estimated: `3643` - // Minimum execution time: 31_393_000 picoseconds. - Weight::from_parts(32_933_000, 3643) + // Minimum execution time: 27_960_000 picoseconds. + Weight::from_parts(28_781_000, 3643) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -101,8 +103,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `109` // Estimated: `3643` - // Minimum execution time: 14_827_000 picoseconds. - Weight::from_parts(15_273_000, 3643) + // Minimum execution time: 11_970_000 picoseconds. + Weight::from_parts(12_512_000, 3643) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -111,13 +113,13 @@ impl WeightInfo for SubstrateWeight { /// Storage: `Uniques::Asset` (r:1001 w:1000) /// Proof: `Uniques::Asset` (`max_values`: None, `max_size`: Some(122), added: 2597, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1000 w:1000) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) /// Storage: `Uniques::Attribute` (r:1000 w:1000) - /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(172), added: 2647, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassAccount` (r:0 w:1) /// Proof: `Uniques::ClassAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassMetadataOf` (r:0 w:1) - /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(167), added: 2642, mode: `MaxEncodedLen`) /// Storage: `Uniques::Account` (r:0 w:1000) /// Proof: `Uniques::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) /// Storage: `Uniques::CollectionMaxSupply` (r:0 w:1) @@ -128,15 +130,15 @@ impl WeightInfo for SubstrateWeight { fn destroy(n: u32, m: u32, a: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `418 + a * (107 ±0) + m * (56 ±0) + n * (76 ±0)` - // Estimated: `3643 + a * (2839 ±0) + m * (2583 ±0) + n * (2597 ±0)` - // Minimum execution time: 3_281_673_000 picoseconds. - Weight::from_parts(3_443_387_000, 3643) - // Standard Error: 41_937 - .saturating_add(Weight::from_parts(7_914_842, 0).saturating_mul(n.into())) - // Standard Error: 41_937 - .saturating_add(Weight::from_parts(519_960, 0).saturating_mul(m.into())) - // Standard Error: 41_937 - .saturating_add(Weight::from_parts(462_690, 0).saturating_mul(a.into())) + // Estimated: `3643 + a * (2647 ±0) + m * (2662 ±0) + n * (2597 ±0)` + // Minimum execution time: 2_979_858_000 picoseconds. + Weight::from_parts(3_007_268_000, 3643) + // Standard Error: 29_899 + .saturating_add(Weight::from_parts(6_943_612, 0).saturating_mul(n.into())) + // Standard Error: 29_899 + .saturating_add(Weight::from_parts(398_114, 0).saturating_mul(m.into())) + // Standard Error: 29_899 + .saturating_add(Weight::from_parts(369_941, 0).saturating_mul(a.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(m.into()))) @@ -145,8 +147,8 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(m.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(a.into()))) - .saturating_add(Weight::from_parts(0, 2839).saturating_mul(a.into())) - .saturating_add(Weight::from_parts(0, 2583).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 2647).saturating_mul(a.into())) + .saturating_add(Weight::from_parts(0, 2662).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 2597).saturating_mul(n.into())) } /// Storage: `Uniques::Asset` (r:1 w:1) @@ -161,8 +163,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 38_122_000 picoseconds. - Weight::from_parts(38_924_000, 3643) + // Minimum execution time: 32_733_000 picoseconds. + Weight::from_parts(33_487_000, 3643) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -178,8 +180,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 38_835_000 picoseconds. - Weight::from_parts(39_754_000, 3643) + // Minimum execution time: 34_202_000 picoseconds. + Weight::from_parts(35_146_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -195,8 +197,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 27_032_000 picoseconds. - Weight::from_parts(27_793_000, 3643) + // Minimum execution time: 24_285_000 picoseconds. + Weight::from_parts(25_300_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -209,10 +211,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `805 + i * (76 ±0)` // Estimated: `3643 + i * (2597 ±0)` - // Minimum execution time: 14_737_000 picoseconds. - Weight::from_parts(15_070_000, 3643) - // Standard Error: 22_500 - .saturating_add(Weight::from_parts(18_855_468, 0).saturating_mul(i.into())) + // Minimum execution time: 11_641_000 picoseconds. + Weight::from_parts(12_261_000, 3643) + // Standard Error: 18_897 + .saturating_add(Weight::from_parts(15_263_570, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(i.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) @@ -227,8 +229,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 18_664_000 picoseconds. - Weight::from_parts(19_455_000, 3643) + // Minimum execution time: 16_122_000 picoseconds. + Weight::from_parts(16_627_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -240,8 +242,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 18_247_000 picoseconds. - Weight::from_parts(18_763_000, 3643) + // Minimum execution time: 15_824_000 picoseconds. + Weight::from_parts(16_522_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -251,8 +253,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 13_219_000 picoseconds. - Weight::from_parts(13_923_000, 3643) + // Minimum execution time: 10_802_000 picoseconds. + Weight::from_parts(11_206_000, 3643) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -262,8 +264,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 13_376_000 picoseconds. - Weight::from_parts(13_904_000, 3643) + // Minimum execution time: 10_805_000 picoseconds. + Weight::from_parts(11_340_000, 3643) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -271,16 +273,18 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Uniques::OwnershipAcceptance` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassAccount` (r:0 w:2) /// Proof: `Uniques::ClassAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn transfer_ownership() -> Weight { // Proof Size summary in bytes: - // Measured: `423` + // Measured: `597` // Estimated: `3643` - // Minimum execution time: 22_353_000 picoseconds. - Weight::from_parts(23_222_000, 3643) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) + // Minimum execution time: 24_213_000 picoseconds. + Weight::from_parts(25_547_000, 3643) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) @@ -288,8 +292,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 14_072_000 picoseconds. - Weight::from_parts(14_619_000, 3643) + // Minimum execution time: 11_256_000 picoseconds. + Weight::from_parts(11_585_000, 3643) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -301,90 +305,90 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 17_081_000 picoseconds. - Weight::from_parts(17_698_000, 3643) + // Minimum execution time: 14_616_000 picoseconds. + Weight::from_parts(15_064_000, 3643) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1 w:0) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) /// Storage: `Uniques::Attribute` (r:1 w:1) - /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(172), added: 2647, mode: `MaxEncodedLen`) fn set_attribute() -> Weight { // Proof Size summary in bytes: - // Measured: `547` - // Estimated: `3829` - // Minimum execution time: 41_501_000 picoseconds. - Weight::from_parts(43_101_000, 3829) + // Measured: `626` + // Estimated: `3652` + // Minimum execution time: 35_640_000 picoseconds. + Weight::from_parts(37_007_000, 3652) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1 w:0) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) /// Storage: `Uniques::Attribute` (r:1 w:1) - /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(172), added: 2647, mode: `MaxEncodedLen`) fn clear_attribute() -> Weight { // Proof Size summary in bytes: - // Measured: `936` - // Estimated: `3829` - // Minimum execution time: 39_722_000 picoseconds. - Weight::from_parts(40_390_000, 3829) + // Measured: `823` + // Estimated: `3652` + // Minimum execution time: 34_410_000 picoseconds. + Weight::from_parts(35_431_000, 3652) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1 w:1) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) fn set_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `415` - // Estimated: `3643` - // Minimum execution time: 30_726_000 picoseconds. - Weight::from_parts(31_557_000, 3643) + // Estimated: `3652` + // Minimum execution time: 26_187_000 picoseconds. + Weight::from_parts(27_837_000, 3652) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1 w:1) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) fn clear_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `547` - // Estimated: `3643` - // Minimum execution time: 31_303_000 picoseconds. - Weight::from_parts(32_389_000, 3643) + // Measured: `626` + // Estimated: `3652` + // Minimum execution time: 26_640_000 picoseconds. + Weight::from_parts(27_688_000, 3652) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassMetadataOf` (r:1 w:1) - /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(167), added: 2642, mode: `MaxEncodedLen`) fn set_collection_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 32_155_000 picoseconds. - Weight::from_parts(32_885_000, 3643) + // Minimum execution time: 26_781_000 picoseconds. + Weight::from_parts(27_628_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:0) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassMetadataOf` (r:1 w:1) - /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(167), added: 2642, mode: `MaxEncodedLen`) fn clear_collection_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `461` + // Measured: `540` // Estimated: `3643` - // Minimum execution time: 30_044_000 picoseconds. - Weight::from_parts(31_405_000, 3643) + // Minimum execution time: 26_295_000 picoseconds. + Weight::from_parts(26_903_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -396,8 +400,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 18_904_000 picoseconds. - Weight::from_parts(19_687_000, 3643) + // Minimum execution time: 16_678_000 picoseconds. + Weight::from_parts(17_548_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -409,8 +413,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `528` // Estimated: `3643` - // Minimum execution time: 19_144_000 picoseconds. - Weight::from_parts(19_706_000, 3643) + // Minimum execution time: 16_408_000 picoseconds. + Weight::from_parts(16_957_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -420,8 +424,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `109` // Estimated: `3517` - // Minimum execution time: 15_339_000 picoseconds. - Weight::from_parts(15_918_000, 3517) + // Minimum execution time: 12_568_000 picoseconds. + Weight::from_parts(12_960_000, 3517) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -433,8 +437,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 15_387_000 picoseconds. - Weight::from_parts(15_726_000, 3643) + // Minimum execution time: 13_110_000 picoseconds. + Weight::from_parts(13_620_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -446,8 +450,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `326` // Estimated: `3587` - // Minimum execution time: 15_873_000 picoseconds. - Weight::from_parts(16_860_000, 3587) + // Minimum execution time: 13_568_000 picoseconds. + Weight::from_parts(14_211_000, 3587) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -463,8 +467,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `607` // Estimated: `3643` - // Minimum execution time: 37_245_000 picoseconds. - Weight::from_parts(38_383_000, 3643) + // Minimum execution time: 32_660_000 picoseconds. + Weight::from_parts(33_734_000, 3643) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -480,8 +484,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `249` // Estimated: `3643` - // Minimum execution time: 31_393_000 picoseconds. - Weight::from_parts(32_933_000, 3643) + // Minimum execution time: 27_960_000 picoseconds. + Weight::from_parts(28_781_000, 3643) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -493,8 +497,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `109` // Estimated: `3643` - // Minimum execution time: 14_827_000 picoseconds. - Weight::from_parts(15_273_000, 3643) + // Minimum execution time: 11_970_000 picoseconds. + Weight::from_parts(12_512_000, 3643) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -503,13 +507,13 @@ impl WeightInfo for () { /// Storage: `Uniques::Asset` (r:1001 w:1000) /// Proof: `Uniques::Asset` (`max_values`: None, `max_size`: Some(122), added: 2597, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1000 w:1000) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) /// Storage: `Uniques::Attribute` (r:1000 w:1000) - /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(172), added: 2647, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassAccount` (r:0 w:1) /// Proof: `Uniques::ClassAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassMetadataOf` (r:0 w:1) - /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(167), added: 2642, mode: `MaxEncodedLen`) /// Storage: `Uniques::Account` (r:0 w:1000) /// Proof: `Uniques::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) /// Storage: `Uniques::CollectionMaxSupply` (r:0 w:1) @@ -520,15 +524,15 @@ impl WeightInfo for () { fn destroy(n: u32, m: u32, a: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `418 + a * (107 ±0) + m * (56 ±0) + n * (76 ±0)` - // Estimated: `3643 + a * (2839 ±0) + m * (2583 ±0) + n * (2597 ±0)` - // Minimum execution time: 3_281_673_000 picoseconds. - Weight::from_parts(3_443_387_000, 3643) - // Standard Error: 41_937 - .saturating_add(Weight::from_parts(7_914_842, 0).saturating_mul(n.into())) - // Standard Error: 41_937 - .saturating_add(Weight::from_parts(519_960, 0).saturating_mul(m.into())) - // Standard Error: 41_937 - .saturating_add(Weight::from_parts(462_690, 0).saturating_mul(a.into())) + // Estimated: `3643 + a * (2647 ±0) + m * (2662 ±0) + n * (2597 ±0)` + // Minimum execution time: 2_979_858_000 picoseconds. + Weight::from_parts(3_007_268_000, 3643) + // Standard Error: 29_899 + .saturating_add(Weight::from_parts(6_943_612, 0).saturating_mul(n.into())) + // Standard Error: 29_899 + .saturating_add(Weight::from_parts(398_114, 0).saturating_mul(m.into())) + // Standard Error: 29_899 + .saturating_add(Weight::from_parts(369_941, 0).saturating_mul(a.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(m.into()))) @@ -537,8 +541,8 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().writes((2_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(m.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(a.into()))) - .saturating_add(Weight::from_parts(0, 2839).saturating_mul(a.into())) - .saturating_add(Weight::from_parts(0, 2583).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 2647).saturating_mul(a.into())) + .saturating_add(Weight::from_parts(0, 2662).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 2597).saturating_mul(n.into())) } /// Storage: `Uniques::Asset` (r:1 w:1) @@ -553,8 +557,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 38_122_000 picoseconds. - Weight::from_parts(38_924_000, 3643) + // Minimum execution time: 32_733_000 picoseconds. + Weight::from_parts(33_487_000, 3643) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -570,8 +574,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 38_835_000 picoseconds. - Weight::from_parts(39_754_000, 3643) + // Minimum execution time: 34_202_000 picoseconds. + Weight::from_parts(35_146_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -587,8 +591,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 27_032_000 picoseconds. - Weight::from_parts(27_793_000, 3643) + // Minimum execution time: 24_285_000 picoseconds. + Weight::from_parts(25_300_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -601,10 +605,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `805 + i * (76 ±0)` // Estimated: `3643 + i * (2597 ±0)` - // Minimum execution time: 14_737_000 picoseconds. - Weight::from_parts(15_070_000, 3643) - // Standard Error: 22_500 - .saturating_add(Weight::from_parts(18_855_468, 0).saturating_mul(i.into())) + // Minimum execution time: 11_641_000 picoseconds. + Weight::from_parts(12_261_000, 3643) + // Standard Error: 18_897 + .saturating_add(Weight::from_parts(15_263_570, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(i.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) @@ -619,8 +623,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 18_664_000 picoseconds. - Weight::from_parts(19_455_000, 3643) + // Minimum execution time: 16_122_000 picoseconds. + Weight::from_parts(16_627_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -632,8 +636,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 18_247_000 picoseconds. - Weight::from_parts(18_763_000, 3643) + // Minimum execution time: 15_824_000 picoseconds. + Weight::from_parts(16_522_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -643,8 +647,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 13_219_000 picoseconds. - Weight::from_parts(13_923_000, 3643) + // Minimum execution time: 10_802_000 picoseconds. + Weight::from_parts(11_206_000, 3643) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -654,8 +658,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 13_376_000 picoseconds. - Weight::from_parts(13_904_000, 3643) + // Minimum execution time: 10_805_000 picoseconds. + Weight::from_parts(11_340_000, 3643) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -663,16 +667,18 @@ impl WeightInfo for () { /// Proof: `Uniques::OwnershipAcceptance` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassAccount` (r:0 w:2) /// Proof: `Uniques::ClassAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn transfer_ownership() -> Weight { // Proof Size summary in bytes: - // Measured: `423` + // Measured: `597` // Estimated: `3643` - // Minimum execution time: 22_353_000 picoseconds. - Weight::from_parts(23_222_000, 3643) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(4_u64)) + // Minimum execution time: 24_213_000 picoseconds. + Weight::from_parts(25_547_000, 3643) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(5_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) @@ -680,8 +686,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 14_072_000 picoseconds. - Weight::from_parts(14_619_000, 3643) + // Minimum execution time: 11_256_000 picoseconds. + Weight::from_parts(11_585_000, 3643) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -693,90 +699,90 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 17_081_000 picoseconds. - Weight::from_parts(17_698_000, 3643) + // Minimum execution time: 14_616_000 picoseconds. + Weight::from_parts(15_064_000, 3643) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1 w:0) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) /// Storage: `Uniques::Attribute` (r:1 w:1) - /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(172), added: 2647, mode: `MaxEncodedLen`) fn set_attribute() -> Weight { // Proof Size summary in bytes: - // Measured: `547` - // Estimated: `3829` - // Minimum execution time: 41_501_000 picoseconds. - Weight::from_parts(43_101_000, 3829) + // Measured: `626` + // Estimated: `3652` + // Minimum execution time: 35_640_000 picoseconds. + Weight::from_parts(37_007_000, 3652) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1 w:0) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) /// Storage: `Uniques::Attribute` (r:1 w:1) - /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) + /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(172), added: 2647, mode: `MaxEncodedLen`) fn clear_attribute() -> Weight { // Proof Size summary in bytes: - // Measured: `936` - // Estimated: `3829` - // Minimum execution time: 39_722_000 picoseconds. - Weight::from_parts(40_390_000, 3829) + // Measured: `823` + // Estimated: `3652` + // Minimum execution time: 34_410_000 picoseconds. + Weight::from_parts(35_431_000, 3652) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1 w:1) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) fn set_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `415` - // Estimated: `3643` - // Minimum execution time: 30_726_000 picoseconds. - Weight::from_parts(31_557_000, 3643) + // Estimated: `3652` + // Minimum execution time: 26_187_000 picoseconds. + Weight::from_parts(27_837_000, 3652) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1 w:1) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) fn clear_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `547` - // Estimated: `3643` - // Minimum execution time: 31_303_000 picoseconds. - Weight::from_parts(32_389_000, 3643) + // Measured: `626` + // Estimated: `3652` + // Minimum execution time: 26_640_000 picoseconds. + Weight::from_parts(27_688_000, 3652) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassMetadataOf` (r:1 w:1) - /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(167), added: 2642, mode: `MaxEncodedLen`) fn set_collection_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 32_155_000 picoseconds. - Weight::from_parts(32_885_000, 3643) + // Minimum execution time: 26_781_000 picoseconds. + Weight::from_parts(27_628_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:0) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassMetadataOf` (r:1 w:1) - /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(167), added: 2642, mode: `MaxEncodedLen`) fn clear_collection_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `461` + // Measured: `540` // Estimated: `3643` - // Minimum execution time: 30_044_000 picoseconds. - Weight::from_parts(31_405_000, 3643) + // Minimum execution time: 26_295_000 picoseconds. + Weight::from_parts(26_903_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -788,8 +794,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 18_904_000 picoseconds. - Weight::from_parts(19_687_000, 3643) + // Minimum execution time: 16_678_000 picoseconds. + Weight::from_parts(17_548_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -801,8 +807,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `528` // Estimated: `3643` - // Minimum execution time: 19_144_000 picoseconds. - Weight::from_parts(19_706_000, 3643) + // Minimum execution time: 16_408_000 picoseconds. + Weight::from_parts(16_957_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -812,8 +818,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `109` // Estimated: `3517` - // Minimum execution time: 15_339_000 picoseconds. - Weight::from_parts(15_918_000, 3517) + // Minimum execution time: 12_568_000 picoseconds. + Weight::from_parts(12_960_000, 3517) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -825,8 +831,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 15_387_000 picoseconds. - Weight::from_parts(15_726_000, 3643) + // Minimum execution time: 13_110_000 picoseconds. + Weight::from_parts(13_620_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -838,8 +844,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `326` // Estimated: `3587` - // Minimum execution time: 15_873_000 picoseconds. - Weight::from_parts(16_860_000, 3587) + // Minimum execution time: 13_568_000 picoseconds. + Weight::from_parts(14_211_000, 3587) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -855,8 +861,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `607` // Estimated: `3643` - // Minimum execution time: 37_245_000 picoseconds. - Weight::from_parts(38_383_000, 3643) + // Minimum execution time: 32_660_000 picoseconds. + Weight::from_parts(33_734_000, 3643) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } diff --git a/substrate/frame/utility/src/weights.rs b/substrate/frame/utility/src/weights.rs index 1a3ea6c1f7f..60b1c48f086 100644 --- a/substrate/frame/utility/src/weights.rs +++ b/substrate/frame/utility/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_utility +//! Autogenerated weights for `pallet_utility` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/utility/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/utility/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_utility. +/// Weight functions needed for `pallet_utility`. pub trait WeightInfo { fn batch(c: u32, ) -> Weight; fn as_derivative() -> Weight; @@ -59,99 +58,139 @@ pub trait WeightInfo { fn force_batch(c: u32, ) -> Weight; } -/// Weights for pallet_utility using the Substrate node and recommended hardware. +/// Weights for `pallet_utility` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `c` is `[0, 1000]`. fn batch(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 6_763_000 picoseconds. - Weight::from_parts(16_943_157, 0) - // Standard Error: 1_904 - .saturating_add(Weight::from_parts(4_653_855, 0).saturating_mul(c.into())) + // Measured: `145` + // Estimated: `3997` + // Minimum execution time: 5_143_000 picoseconds. + Weight::from_parts(11_552_299, 3997) + // Standard Error: 2_325 + .saturating_add(Weight::from_parts(4_708_951, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) } + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) fn as_derivative() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 5_149_000 picoseconds. - Weight::from_parts(5_268_000, 0) + // Measured: `145` + // Estimated: `3997` + // Minimum execution time: 9_103_000 picoseconds. + Weight::from_parts(9_549_000, 3997) + .saturating_add(T::DbWeight::get().reads(2_u64)) } + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `c` is `[0, 1000]`. fn batch_all(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 6_976_000 picoseconds. - Weight::from_parts(16_448_433, 0) - // Standard Error: 1_834 - .saturating_add(Weight::from_parts(4_796_983, 0).saturating_mul(c.into())) + // Measured: `145` + // Estimated: `3997` + // Minimum execution time: 5_147_000 picoseconds. + Weight::from_parts(15_698_086, 3997) + // Standard Error: 3_066 + .saturating_add(Weight::from_parts(4_809_412, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) } fn dispatch_as() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_102_000 picoseconds. - Weight::from_parts(9_353_000, 0) + // Minimum execution time: 6_683_000 picoseconds. + Weight::from_parts(7_047_000, 0) } + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `c` is `[0, 1000]`. fn force_batch(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 6_840_000 picoseconds. - Weight::from_parts(17_748_474, 0) - // Standard Error: 2_059 - .saturating_add(Weight::from_parts(4_630_079, 0).saturating_mul(c.into())) + // Measured: `145` + // Estimated: `3997` + // Minimum execution time: 4_982_000 picoseconds. + Weight::from_parts(14_474_780, 3997) + // Standard Error: 2_291 + .saturating_add(Weight::from_parts(4_632_643, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `c` is `[0, 1000]`. fn batch(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 6_763_000 picoseconds. - Weight::from_parts(16_943_157, 0) - // Standard Error: 1_904 - .saturating_add(Weight::from_parts(4_653_855, 0).saturating_mul(c.into())) + // Measured: `145` + // Estimated: `3997` + // Minimum execution time: 5_143_000 picoseconds. + Weight::from_parts(11_552_299, 3997) + // Standard Error: 2_325 + .saturating_add(Weight::from_parts(4_708_951, 0).saturating_mul(c.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) } + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) fn as_derivative() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 5_149_000 picoseconds. - Weight::from_parts(5_268_000, 0) + // Measured: `145` + // Estimated: `3997` + // Minimum execution time: 9_103_000 picoseconds. + Weight::from_parts(9_549_000, 3997) + .saturating_add(RocksDbWeight::get().reads(2_u64)) } + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `c` is `[0, 1000]`. fn batch_all(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 6_976_000 picoseconds. - Weight::from_parts(16_448_433, 0) - // Standard Error: 1_834 - .saturating_add(Weight::from_parts(4_796_983, 0).saturating_mul(c.into())) + // Measured: `145` + // Estimated: `3997` + // Minimum execution time: 5_147_000 picoseconds. + Weight::from_parts(15_698_086, 3997) + // Standard Error: 3_066 + .saturating_add(Weight::from_parts(4_809_412, 0).saturating_mul(c.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) } fn dispatch_as() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_102_000 picoseconds. - Weight::from_parts(9_353_000, 0) + // Minimum execution time: 6_683_000 picoseconds. + Weight::from_parts(7_047_000, 0) } + /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) + /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `TxPause::PausedCalls` (r:1 w:0) + /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `c` is `[0, 1000]`. fn force_batch(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 6_840_000 picoseconds. - Weight::from_parts(17_748_474, 0) - // Standard Error: 2_059 - .saturating_add(Weight::from_parts(4_630_079, 0).saturating_mul(c.into())) + // Measured: `145` + // Estimated: `3997` + // Minimum execution time: 4_982_000 picoseconds. + Weight::from_parts(14_474_780, 3997) + // Standard Error: 2_291 + .saturating_add(Weight::from_parts(4_632_643, 0).saturating_mul(c.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) } } diff --git a/substrate/frame/vesting/src/weights.rs b/substrate/frame/vesting/src/weights.rs index ddc7db8fa61..d91c47ae195 100644 --- a/substrate/frame/vesting/src/weights.rs +++ b/substrate/frame/vesting/src/weights.rs @@ -17,26 +17,28 @@ //! Autogenerated weights for `pallet_vesting` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-10-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-vmdtonbz-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// target/production/substrate-node +// ./target/production/substrate-node // benchmark // pallet +// --chain=dev // --steps=50 // --repeat=20 +// --pallet=pallet_vesting +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_vesting -// --chain=dev -// --header=./substrate/HEADER-APACHE2 // --output=./substrate/frame/vesting/src/weights.rs +// --header=./substrate/HEADER-APACHE2 // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -75,12 +77,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `381 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 32_846_000 picoseconds. - Weight::from_parts(30_974_459, 4764) - // Standard Error: 1_755 - .saturating_add(Weight::from_parts(73_138, 0).saturating_mul(l.into())) - // Standard Error: 3_123 - .saturating_add(Weight::from_parts(82_417, 0).saturating_mul(s.into())) + // Minimum execution time: 31_890_000 picoseconds. + Weight::from_parts(31_128_476, 4764) + // Standard Error: 1_193 + .saturating_add(Weight::from_parts(63_760, 0).saturating_mul(l.into())) + // Standard Error: 2_124 + .saturating_add(Weight::from_parts(57_247, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -96,12 +98,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `381 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 34_360_000 picoseconds. - Weight::from_parts(34_964_080, 4764) - // Standard Error: 1_996 - .saturating_add(Weight::from_parts(48_024, 0).saturating_mul(l.into())) - // Standard Error: 3_552 - .saturating_add(Weight::from_parts(34_411, 0).saturating_mul(s.into())) + // Minimum execution time: 33_958_000 picoseconds. + Weight::from_parts(33_537_005, 4764) + // Standard Error: 1_354 + .saturating_add(Weight::from_parts(60_604, 0).saturating_mul(l.into())) + // Standard Error: 2_410 + .saturating_add(Weight::from_parts(51_378, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -119,12 +121,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `484 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 33_859_000 picoseconds. - Weight::from_parts(32_950_681, 4764) - // Standard Error: 1_745 - .saturating_add(Weight::from_parts(69_323, 0).saturating_mul(l.into())) - // Standard Error: 3_105 - .saturating_add(Weight::from_parts(86_370, 0).saturating_mul(s.into())) + // Minimum execution time: 33_243_000 picoseconds. + Weight::from_parts(32_552_805, 4764) + // Standard Error: 1_413 + .saturating_add(Weight::from_parts(67_137, 0).saturating_mul(l.into())) + // Standard Error: 2_515 + .saturating_add(Weight::from_parts(70_000, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -142,12 +144,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `484 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 36_239_000 picoseconds. - Weight::from_parts(36_459_756, 4764) - // Standard Error: 2_051 - .saturating_add(Weight::from_parts(56_670, 0).saturating_mul(l.into())) - // Standard Error: 3_650 - .saturating_add(Weight::from_parts(49_663, 0).saturating_mul(s.into())) + // Minimum execution time: 35_396_000 picoseconds. + Weight::from_parts(35_774_949, 4764) + // Standard Error: 1_404 + .saturating_add(Weight::from_parts(55_349, 0).saturating_mul(l.into())) + // Standard Error: 2_497 + .saturating_add(Weight::from_parts(39_228, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -165,12 +167,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `555 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 70_330_000 picoseconds. - Weight::from_parts(71_196_328, 4764) - // Standard Error: 2_923 - .saturating_add(Weight::from_parts(67_238, 0).saturating_mul(l.into())) - // Standard Error: 5_201 - .saturating_add(Weight::from_parts(89_102, 0).saturating_mul(s.into())) + // Minimum execution time: 68_441_000 picoseconds. + Weight::from_parts(68_961_970, 4764) + // Standard Error: 2_509 + .saturating_add(Weight::from_parts(83_345, 0).saturating_mul(l.into())) + // Standard Error: 4_464 + .saturating_add(Weight::from_parts(124_158, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -188,12 +190,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `658 + l * (25 ±0) + s * (36 ±0)` // Estimated: `6196` - // Minimum execution time: 70_235_000 picoseconds. - Weight::from_parts(71_960_020, 6196) - // Standard Error: 2_493 - .saturating_add(Weight::from_parts(64_835, 0).saturating_mul(l.into())) - // Standard Error: 4_436 - .saturating_add(Weight::from_parts(102_159, 0).saturating_mul(s.into())) + // Minimum execution time: 70_190_000 picoseconds. + Weight::from_parts(72_355_984, 6196) + // Standard Error: 2_295 + .saturating_add(Weight::from_parts(59_968, 0).saturating_mul(l.into())) + // Standard Error: 4_084 + .saturating_add(Weight::from_parts(87_090, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -211,12 +213,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `482 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 34_352_000 picoseconds. - Weight::from_parts(33_697_027, 4764) - // Standard Error: 2_008 - .saturating_add(Weight::from_parts(79_270, 0).saturating_mul(l.into())) - // Standard Error: 3_710 - .saturating_add(Weight::from_parts(60_691, 0).saturating_mul(s.into())) + // Minimum execution time: 33_911_000 picoseconds. + Weight::from_parts(33_243_006, 4764) + // Standard Error: 1_199 + .saturating_add(Weight::from_parts(70_586, 0).saturating_mul(l.into())) + // Standard Error: 2_214 + .saturating_add(Weight::from_parts(60_985, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -234,12 +236,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `482 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 37_467_000 picoseconds. - Weight::from_parts(36_866_847, 4764) - // Standard Error: 1_692 - .saturating_add(Weight::from_parts(57_882, 0).saturating_mul(l.into())) - // Standard Error: 3_124 - .saturating_add(Weight::from_parts(80_266, 0).saturating_mul(s.into())) + // Minimum execution time: 36_242_000 picoseconds. + Weight::from_parts(35_812_994, 4764) + // Standard Error: 1_351 + .saturating_add(Weight::from_parts(68_256, 0).saturating_mul(l.into())) + // Standard Error: 2_496 + .saturating_add(Weight::from_parts(66_171, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -257,12 +259,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `555 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 41_497_000 picoseconds. - Weight::from_parts(38_763_834, 4764) - // Standard Error: 2_030 - .saturating_add(Weight::from_parts(99_580, 0).saturating_mul(l.into())) - // Standard Error: 3_750 - .saturating_add(Weight::from_parts(132_188, 0).saturating_mul(s.into())) + // Minimum execution time: 37_817_000 picoseconds. + Weight::from_parts(37_397_127, 4764) + // Standard Error: 1_665 + .saturating_add(Weight::from_parts(72_049, 0).saturating_mul(l.into())) + // Standard Error: 3_075 + .saturating_add(Weight::from_parts(60_973, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -282,12 +284,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `381 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 32_846_000 picoseconds. - Weight::from_parts(30_974_459, 4764) - // Standard Error: 1_755 - .saturating_add(Weight::from_parts(73_138, 0).saturating_mul(l.into())) - // Standard Error: 3_123 - .saturating_add(Weight::from_parts(82_417, 0).saturating_mul(s.into())) + // Minimum execution time: 31_890_000 picoseconds. + Weight::from_parts(31_128_476, 4764) + // Standard Error: 1_193 + .saturating_add(Weight::from_parts(63_760, 0).saturating_mul(l.into())) + // Standard Error: 2_124 + .saturating_add(Weight::from_parts(57_247, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -303,12 +305,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `381 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 34_360_000 picoseconds. - Weight::from_parts(34_964_080, 4764) - // Standard Error: 1_996 - .saturating_add(Weight::from_parts(48_024, 0).saturating_mul(l.into())) - // Standard Error: 3_552 - .saturating_add(Weight::from_parts(34_411, 0).saturating_mul(s.into())) + // Minimum execution time: 33_958_000 picoseconds. + Weight::from_parts(33_537_005, 4764) + // Standard Error: 1_354 + .saturating_add(Weight::from_parts(60_604, 0).saturating_mul(l.into())) + // Standard Error: 2_410 + .saturating_add(Weight::from_parts(51_378, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -326,12 +328,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `484 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 33_859_000 picoseconds. - Weight::from_parts(32_950_681, 4764) - // Standard Error: 1_745 - .saturating_add(Weight::from_parts(69_323, 0).saturating_mul(l.into())) - // Standard Error: 3_105 - .saturating_add(Weight::from_parts(86_370, 0).saturating_mul(s.into())) + // Minimum execution time: 33_243_000 picoseconds. + Weight::from_parts(32_552_805, 4764) + // Standard Error: 1_413 + .saturating_add(Weight::from_parts(67_137, 0).saturating_mul(l.into())) + // Standard Error: 2_515 + .saturating_add(Weight::from_parts(70_000, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -349,12 +351,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `484 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 36_239_000 picoseconds. - Weight::from_parts(36_459_756, 4764) - // Standard Error: 2_051 - .saturating_add(Weight::from_parts(56_670, 0).saturating_mul(l.into())) - // Standard Error: 3_650 - .saturating_add(Weight::from_parts(49_663, 0).saturating_mul(s.into())) + // Minimum execution time: 35_396_000 picoseconds. + Weight::from_parts(35_774_949, 4764) + // Standard Error: 1_404 + .saturating_add(Weight::from_parts(55_349, 0).saturating_mul(l.into())) + // Standard Error: 2_497 + .saturating_add(Weight::from_parts(39_228, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -372,12 +374,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `555 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 70_330_000 picoseconds. - Weight::from_parts(71_196_328, 4764) - // Standard Error: 2_923 - .saturating_add(Weight::from_parts(67_238, 0).saturating_mul(l.into())) - // Standard Error: 5_201 - .saturating_add(Weight::from_parts(89_102, 0).saturating_mul(s.into())) + // Minimum execution time: 68_441_000 picoseconds. + Weight::from_parts(68_961_970, 4764) + // Standard Error: 2_509 + .saturating_add(Weight::from_parts(83_345, 0).saturating_mul(l.into())) + // Standard Error: 4_464 + .saturating_add(Weight::from_parts(124_158, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -395,12 +397,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `658 + l * (25 ±0) + s * (36 ±0)` // Estimated: `6196` - // Minimum execution time: 70_235_000 picoseconds. - Weight::from_parts(71_960_020, 6196) - // Standard Error: 2_493 - .saturating_add(Weight::from_parts(64_835, 0).saturating_mul(l.into())) - // Standard Error: 4_436 - .saturating_add(Weight::from_parts(102_159, 0).saturating_mul(s.into())) + // Minimum execution time: 70_190_000 picoseconds. + Weight::from_parts(72_355_984, 6196) + // Standard Error: 2_295 + .saturating_add(Weight::from_parts(59_968, 0).saturating_mul(l.into())) + // Standard Error: 4_084 + .saturating_add(Weight::from_parts(87_090, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -418,12 +420,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `482 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 34_352_000 picoseconds. - Weight::from_parts(33_697_027, 4764) - // Standard Error: 2_008 - .saturating_add(Weight::from_parts(79_270, 0).saturating_mul(l.into())) - // Standard Error: 3_710 - .saturating_add(Weight::from_parts(60_691, 0).saturating_mul(s.into())) + // Minimum execution time: 33_911_000 picoseconds. + Weight::from_parts(33_243_006, 4764) + // Standard Error: 1_199 + .saturating_add(Weight::from_parts(70_586, 0).saturating_mul(l.into())) + // Standard Error: 2_214 + .saturating_add(Weight::from_parts(60_985, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -441,12 +443,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `482 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 37_467_000 picoseconds. - Weight::from_parts(36_866_847, 4764) - // Standard Error: 1_692 - .saturating_add(Weight::from_parts(57_882, 0).saturating_mul(l.into())) - // Standard Error: 3_124 - .saturating_add(Weight::from_parts(80_266, 0).saturating_mul(s.into())) + // Minimum execution time: 36_242_000 picoseconds. + Weight::from_parts(35_812_994, 4764) + // Standard Error: 1_351 + .saturating_add(Weight::from_parts(68_256, 0).saturating_mul(l.into())) + // Standard Error: 2_496 + .saturating_add(Weight::from_parts(66_171, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -464,12 +466,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `555 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 41_497_000 picoseconds. - Weight::from_parts(38_763_834, 4764) - // Standard Error: 2_030 - .saturating_add(Weight::from_parts(99_580, 0).saturating_mul(l.into())) - // Standard Error: 3_750 - .saturating_add(Weight::from_parts(132_188, 0).saturating_mul(s.into())) + // Minimum execution time: 37_817_000 picoseconds. + Weight::from_parts(37_397_127, 4764) + // Standard Error: 1_665 + .saturating_add(Weight::from_parts(72_049, 0).saturating_mul(l.into())) + // Standard Error: 3_075 + .saturating_add(Weight::from_parts(60_973, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } diff --git a/substrate/frame/whitelist/src/weights.rs b/substrate/frame/whitelist/src/weights.rs index de42c5a5841..13b653f6ca7 100644 --- a/substrate/frame/whitelist/src/weights.rs +++ b/substrate/frame/whitelist/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_whitelist +//! Autogenerated weights for `pallet_whitelist` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate +// ./target/production/substrate-node // benchmark // pallet // --chain=dev @@ -35,12 +35,11 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./frame/whitelist/src/weights.rs -// --header=./HEADER-APACHE2 -// --template=./.maintain/frame-weight-template.hbs +// --output=./substrate/frame/whitelist/src/weights.rs +// --header=./substrate/HEADER-APACHE2 +// --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for pallet_whitelist. +/// Weight functions needed for `pallet_whitelist`. pub trait WeightInfo { fn whitelist_call() -> Weight; fn remove_whitelisted_call() -> Weight; @@ -58,133 +57,149 @@ pub trait WeightInfo { fn dispatch_whitelisted_call_with_preimage(n: u32, ) -> Weight; } -/// Weights for pallet_whitelist using the Substrate node and recommended hardware. +/// Weights for `pallet_whitelist` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: Whitelist WhitelistedCall (r:1 w:1) - /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) + /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn whitelist_call() -> Weight { // Proof Size summary in bytes: - // Measured: `217` + // Measured: `317` // Estimated: `3556` - // Minimum execution time: 19_914_000 picoseconds. - Weight::from_parts(20_892_000, 3556) - .saturating_add(T::DbWeight::get().reads(2_u64)) + // Minimum execution time: 18_503_000 picoseconds. + Weight::from_parts(19_497_000, 3556) + .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Whitelist WhitelistedCall (r:1 w:1) - /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) + /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn remove_whitelisted_call() -> Weight { // Proof Size summary in bytes: - // Measured: `346` + // Measured: `446` // Estimated: `3556` - // Minimum execution time: 18_142_000 picoseconds. - Weight::from_parts(18_529_000, 3556) - .saturating_add(T::DbWeight::get().reads(2_u64)) + // Minimum execution time: 17_633_000 picoseconds. + Weight::from_parts(18_196_000, 3556) + .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: Whitelist WhitelistedCall (r:1 w:1) - /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) - /// Storage: Preimage PreimageFor (r:1 w:1) - /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: Measured) - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) + /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) + /// Storage: `Preimage::PreimageFor` (r:1 w:1) + /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `Measured`) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 4194294]`. fn dispatch_whitelisted_call(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `422 + n * (1 ±0)` - // Estimated: `3886 + n * (1 ±0)` - // Minimum execution time: 30_671_000 picoseconds. - Weight::from_parts(31_197_000, 3886) + // Measured: `522 + n * (1 ±0)` + // Estimated: `3986 + n * (1 ±0)` + // Minimum execution time: 28_020_000 picoseconds. + Weight::from_parts(28_991_000, 3986) // Standard Error: 0 - .saturating_add(Weight::from_parts(1_163, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(Weight::from_parts(1_171, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } - /// Storage: Whitelist WhitelistedCall (r:1 w:1) - /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) + /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 10000]`. fn dispatch_whitelisted_call_with_preimage(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `346` + // Measured: `446` // Estimated: `3556` - // Minimum execution time: 22_099_000 picoseconds. - Weight::from_parts(23_145_477, 3556) - // Standard Error: 5 - .saturating_add(Weight::from_parts(1_422, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(2_u64)) + // Minimum execution time: 21_916_000 picoseconds. + Weight::from_parts(23_082_065, 3556) + // Standard Error: 6 + .saturating_add(Weight::from_parts(1_388, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: Whitelist WhitelistedCall (r:1 w:1) - /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) + /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn whitelist_call() -> Weight { // Proof Size summary in bytes: - // Measured: `217` + // Measured: `317` // Estimated: `3556` - // Minimum execution time: 19_914_000 picoseconds. - Weight::from_parts(20_892_000, 3556) - .saturating_add(RocksDbWeight::get().reads(2_u64)) + // Minimum execution time: 18_503_000 picoseconds. + Weight::from_parts(19_497_000, 3556) + .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Whitelist WhitelistedCall (r:1 w:1) - /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) + /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn remove_whitelisted_call() -> Weight { // Proof Size summary in bytes: - // Measured: `346` + // Measured: `446` // Estimated: `3556` - // Minimum execution time: 18_142_000 picoseconds. - Weight::from_parts(18_529_000, 3556) - .saturating_add(RocksDbWeight::get().reads(2_u64)) + // Minimum execution time: 17_633_000 picoseconds. + Weight::from_parts(18_196_000, 3556) + .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: Whitelist WhitelistedCall (r:1 w:1) - /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) - /// Storage: Preimage PreimageFor (r:1 w:1) - /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: Measured) - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) + /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) + /// Storage: `Preimage::PreimageFor` (r:1 w:1) + /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `Measured`) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 4194294]`. fn dispatch_whitelisted_call(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `422 + n * (1 ±0)` - // Estimated: `3886 + n * (1 ±0)` - // Minimum execution time: 30_671_000 picoseconds. - Weight::from_parts(31_197_000, 3886) + // Measured: `522 + n * (1 ±0)` + // Estimated: `3986 + n * (1 ±0)` + // Minimum execution time: 28_020_000 picoseconds. + Weight::from_parts(28_991_000, 3986) // Standard Error: 0 - .saturating_add(Weight::from_parts(1_163, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(Weight::from_parts(1_171, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } - /// Storage: Whitelist WhitelistedCall (r:1 w:1) - /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) - /// Storage: Preimage StatusFor (r:1 w:1) - /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) + /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) + /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 10000]`. fn dispatch_whitelisted_call_with_preimage(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `346` + // Measured: `446` // Estimated: `3556` - // Minimum execution time: 22_099_000 picoseconds. - Weight::from_parts(23_145_477, 3556) - // Standard Error: 5 - .saturating_add(Weight::from_parts(1_422, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(2_u64)) + // Minimum execution time: 21_916_000 picoseconds. + Weight::from_parts(23_082_065, 3556) + // Standard Error: 6 + .saturating_add(Weight::from_parts(1_388, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } } diff --git a/substrate/primitives/inherents/src/lib.rs b/substrate/primitives/inherents/src/lib.rs index dd7c294f1e2..415319a6849 100644 --- a/substrate/primitives/inherents/src/lib.rs +++ b/substrate/primitives/inherents/src/lib.rs @@ -98,10 +98,10 @@ //! and production. //! //! ``` -//! # use sp_runtime::testing::ExtrinsicWrapper; +//! # use sp_runtime::{generic::UncheckedExtrinsic, testing::MockCallU64}; //! # use sp_inherents::{InherentIdentifier, InherentData}; //! # use futures::FutureExt; -//! # type Block = sp_runtime::testing::Block>; +//! # type Block = sp_runtime::testing::Block>; //! # const INHERENT_IDENTIFIER: InherentIdentifier = *b"testinh0"; //! # struct InherentDataProvider; //! # #[async_trait::async_trait] diff --git a/substrate/primitives/metadata-ir/src/lib.rs b/substrate/primitives/metadata-ir/src/lib.rs index edfa58f8618..66aff2c599f 100644 --- a/substrate/primitives/metadata-ir/src/lib.rs +++ b/substrate/primitives/metadata-ir/src/lib.rs @@ -84,7 +84,7 @@ mod test { call_ty: meta_type::<()>(), signature_ty: meta_type::<()>(), extra_ty: meta_type::<()>(), - signed_extensions: vec![], + extensions: vec![], }, ty: meta_type::<()>(), apis: vec![], diff --git a/substrate/primitives/metadata-ir/src/types.rs b/substrate/primitives/metadata-ir/src/types.rs index b107d20a8e2..e60881ed6b8 100644 --- a/substrate/primitives/metadata-ir/src/types.rs +++ b/substrate/primitives/metadata-ir/src/types.rs @@ -166,10 +166,11 @@ pub struct ExtrinsicMetadataIR { pub call_ty: T::Type, /// The type of the extrinsic's signature. pub signature_ty: T::Type, - /// The type of the outermost Extra enum. + /// The type of the outermost Extra/Extensions enum. + // TODO: metadata-v16: rename this to `extension_ty`. pub extra_ty: T::Type, - /// The signed extensions in the order they appear in the extrinsic. - pub signed_extensions: Vec>, + /// The transaction extensions in the order they appear in the extrinsic. + pub extensions: Vec>, } impl IntoPortable for ExtrinsicMetadataIR { @@ -183,27 +184,27 @@ impl IntoPortable for ExtrinsicMetadataIR { call_ty: registry.register_type(&self.call_ty), signature_ty: registry.register_type(&self.signature_ty), extra_ty: registry.register_type(&self.extra_ty), - signed_extensions: registry.map_into_portable(self.signed_extensions), + extensions: registry.map_into_portable(self.extensions), } } } /// Metadata of an extrinsic's signed extension. #[derive(Clone, PartialEq, Eq, Encode, Debug)] -pub struct SignedExtensionMetadataIR { +pub struct TransactionExtensionMetadataIR { /// The unique signed extension identifier, which may be different from the type name. pub identifier: T::String, /// The type of the signed extension, with the data to be included in the extrinsic. pub ty: T::Type, - /// The type of the additional signed data, with the data to be included in the signed payload + /// The type of the additional signed data, with the data to be included in the signed payload. pub additional_signed: T::Type, } -impl IntoPortable for SignedExtensionMetadataIR { - type Output = SignedExtensionMetadataIR; +impl IntoPortable for TransactionExtensionMetadataIR { + type Output = TransactionExtensionMetadataIR; fn into_portable(self, registry: &mut Registry) -> Self::Output { - SignedExtensionMetadataIR { + TransactionExtensionMetadataIR { identifier: self.identifier.into_portable(registry), ty: registry.register_type(&self.ty), additional_signed: registry.register_type(&self.additional_signed), diff --git a/substrate/primitives/metadata-ir/src/v14.rs b/substrate/primitives/metadata-ir/src/v14.rs index e1b7a24f765..ec08de34786 100644 --- a/substrate/primitives/metadata-ir/src/v14.rs +++ b/substrate/primitives/metadata-ir/src/v14.rs @@ -20,8 +20,8 @@ use super::types::{ ExtrinsicMetadataIR, MetadataIR, PalletCallMetadataIR, PalletConstantMetadataIR, PalletErrorMetadataIR, PalletEventMetadataIR, PalletMetadataIR, PalletStorageMetadataIR, - SignedExtensionMetadataIR, StorageEntryMetadataIR, StorageEntryModifierIR, StorageEntryTypeIR, - StorageHasherIR, + StorageEntryMetadataIR, StorageEntryModifierIR, StorageEntryTypeIR, StorageHasherIR, + TransactionExtensionMetadataIR, }; use frame_metadata::v14::{ @@ -137,8 +137,8 @@ impl From for PalletErrorMetadata { } } -impl From for SignedExtensionMetadata { - fn from(ir: SignedExtensionMetadataIR) -> Self { +impl From for SignedExtensionMetadata { + fn from(ir: TransactionExtensionMetadataIR) -> Self { SignedExtensionMetadata { identifier: ir.identifier, ty: ir.ty, @@ -152,7 +152,7 @@ impl From for ExtrinsicMetadata { ExtrinsicMetadata { ty: ir.ty, version: ir.version, - signed_extensions: ir.signed_extensions.into_iter().map(Into::into).collect(), + signed_extensions: ir.extensions.into_iter().map(Into::into).collect(), } } } diff --git a/substrate/primitives/metadata-ir/src/v15.rs b/substrate/primitives/metadata-ir/src/v15.rs index a942eb73223..dc5ce1c88fd 100644 --- a/substrate/primitives/metadata-ir/src/v15.rs +++ b/substrate/primitives/metadata-ir/src/v15.rs @@ -21,7 +21,7 @@ use crate::OuterEnumsIR; use super::types::{ ExtrinsicMetadataIR, MetadataIR, PalletMetadataIR, RuntimeApiMetadataIR, - RuntimeApiMethodMetadataIR, RuntimeApiMethodParamMetadataIR, SignedExtensionMetadataIR, + RuntimeApiMethodMetadataIR, RuntimeApiMethodParamMetadataIR, TransactionExtensionMetadataIR, }; use frame_metadata::v15::{ @@ -87,8 +87,8 @@ impl From for PalletMetadata { } } -impl From for SignedExtensionMetadata { - fn from(ir: SignedExtensionMetadataIR) -> Self { +impl From for SignedExtensionMetadata { + fn from(ir: TransactionExtensionMetadataIR) -> Self { SignedExtensionMetadata { identifier: ir.identifier, ty: ir.ty, @@ -105,7 +105,7 @@ impl From for ExtrinsicMetadata { call_ty: ir.call_ty, signature_ty: ir.signature_ty, extra_ty: ir.extra_ty, - signed_extensions: ir.signed_extensions.into_iter().map(Into::into).collect(), + signed_extensions: ir.extensions.into_iter().map(Into::into).collect(), } } } diff --git a/substrate/primitives/runtime/Cargo.toml b/substrate/primitives/runtime/Cargo.toml index cacfc059722..758cd8944fd 100644 --- a/substrate/primitives/runtime/Cargo.toml +++ b/substrate/primitives/runtime/Cargo.toml @@ -17,6 +17,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] +tuplex = { version = "0.1.2", default-features = false } codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive", "max-encoded-len"] } either = { version = "1.5", default-features = false } hash256-std-hasher = { version = "0.15.2", default-features = false } @@ -67,6 +68,7 @@ std = [ "sp-std/std", "sp-tracing/std", "sp-weights/std", + "tuplex/std", ] # Serde support without relying on std features. diff --git a/substrate/primitives/runtime/src/generic/checked_extrinsic.rs b/substrate/primitives/runtime/src/generic/checked_extrinsic.rs index 44325920bee..e28c8fe424a 100644 --- a/substrate/primitives/runtime/src/generic/checked_extrinsic.rs +++ b/substrate/primitives/runtime/src/generic/checked_extrinsic.rs @@ -18,81 +18,115 @@ //! Generic implementation of an extrinsic that has passed the verification //! stage. +use codec::Encode; + use crate::{ traits::{ - self, DispatchInfoOf, Dispatchable, MaybeDisplay, Member, PostDispatchInfoOf, - SignedExtension, ValidateUnsigned, + self, transaction_extension::TransactionExtension, DispatchInfoOf, DispatchTransaction, + Dispatchable, MaybeDisplay, Member, PostDispatchInfoOf, ValidateUnsigned, }, transaction_validity::{TransactionSource, TransactionValidity}, }; +/// The kind of extrinsic this is, including any fields required of that kind. This is basically +/// the full extrinsic except the `Call`. +#[derive(PartialEq, Eq, Clone, sp_core::RuntimeDebug)] +pub enum ExtrinsicFormat { + /// Extrinsic is bare; it must pass either the bare forms of `TransactionExtension` or + /// `ValidateUnsigned`, both deprecated, or alternatively a `ProvideInherent`. + Bare, + /// Extrinsic has a default `Origin` of `Signed(AccountId)` and must pass all + /// `TransactionExtension`s regular checks and includes all extension data. + Signed(AccountId, Extension), + /// Extrinsic has a default `Origin` of `None` and must pass all `TransactionExtension`s. + /// regular checks and includes all extension data. + General(Extension), +} + +// TODO: Rename ValidateUnsigned to ValidateInherent +// TODO: Consider changing ValidateInherent API to avoid need for duplicating validate +// code into pre_dispatch (rename that to `prepare`). +// TODO: New extrinsic type corresponding to `ExtrinsicFormat::General`, which is +// unsigned but includes extension data. +// TODO: Move usage of `signed` to `format`: +// - Inherent instead of None. +// - Signed(id, extension) instead of Some((id, extra)). +// - Introduce General(extension) for one without a signature. + /// Definition of something that the external world might want to say; its existence implies that it /// has been checked and is good, particularly with regards to the signature. /// /// This is typically passed into [`traits::Applyable::apply`], which should execute /// [`CheckedExtrinsic::function`], alongside all other bits and bobs. #[derive(PartialEq, Eq, Clone, sp_core::RuntimeDebug)] -pub struct CheckedExtrinsic { +pub struct CheckedExtrinsic { /// Who this purports to be from and the number of extrinsics have come before /// from the same signer, if anyone (note this is not a signature). - pub signed: Option<(AccountId, Extra)>, + pub format: ExtrinsicFormat, /// The function that should be called. pub function: Call, } -impl traits::Applyable - for CheckedExtrinsic +impl traits::Applyable + for CheckedExtrinsic where AccountId: Member + MaybeDisplay, - Call: Member + Dispatchable, - Extra: SignedExtension, + Call: Member + Dispatchable + Encode, + Extension: TransactionExtension, RuntimeOrigin: From>, { type Call = Call; - fn validate>( + fn validate>( &self, - // TODO [#5006;ToDr] should source be passed to `SignedExtension`s? - // Perhaps a change for 2.0 to avoid breaking too much APIs? source: TransactionSource, info: &DispatchInfoOf, len: usize, ) -> TransactionValidity { - if let Some((ref id, ref extra)) = self.signed { - Extra::validate(extra, id, &self.function, info, len) - } else { - let valid = Extra::validate_unsigned(&self.function, info, len)?; - let unsigned_validation = U::validate_unsigned(source, &self.function)?; - Ok(valid.combine_with(unsigned_validation)) + match self.format { + ExtrinsicFormat::Bare => { + let inherent_validation = I::validate_unsigned(source, &self.function)?; + #[allow(deprecated)] + let legacy_validation = Extension::validate_bare_compat(&self.function, info, len)?; + Ok(legacy_validation.combine_with(inherent_validation)) + }, + ExtrinsicFormat::Signed(ref signer, ref extension) => { + let origin = Some(signer.clone()).into(); + extension.validate_only(origin, &self.function, info, len).map(|x| x.0) + }, + ExtrinsicFormat::General(ref extension) => + extension.validate_only(None.into(), &self.function, info, len).map(|x| x.0), } } - fn apply>( + fn apply>( self, info: &DispatchInfoOf, len: usize, ) -> crate::ApplyExtrinsicResultWithInfo> { - let (maybe_who, maybe_pre) = if let Some((id, extra)) = self.signed { - let pre = Extra::pre_dispatch(extra, &id, &self.function, info, len)?; - (Some(id), Some(pre)) - } else { - Extra::pre_dispatch_unsigned(&self.function, info, len)?; - U::pre_dispatch(&self.function)?; - (None, None) - }; - let res = self.function.dispatch(RuntimeOrigin::from(maybe_who)); - let post_info = match res { - Ok(info) => info, - Err(err) => err.post_info, - }; - Extra::post_dispatch( - maybe_pre, - info, - &post_info, - len, - &res.map(|_| ()).map_err(|e| e.error), - )?; - Ok(res) + match self.format { + ExtrinsicFormat::Bare => { + I::pre_dispatch(&self.function)?; + // TODO: Remove below once `pre_dispatch_unsigned` is removed from `LegacyExtension` + // or `LegacyExtension` is removed. + #[allow(deprecated)] + Extension::validate_bare_compat(&self.function, info, len)?; + #[allow(deprecated)] + Extension::pre_dispatch_bare_compat(&self.function, info, len)?; + let res = self.function.dispatch(None.into()); + let post_info = res.unwrap_or_else(|err| err.post_info); + let pd_res = res.map(|_| ()).map_err(|e| e.error); + // TODO: Remove below once `pre_dispatch_unsigned` is removed from `LegacyExtension` + // or `LegacyExtension` is removed. + #[allow(deprecated)] + Extension::post_dispatch_bare_compat(info, &post_info, len, &pd_res)?; + Ok(res) + }, + ExtrinsicFormat::Signed(signer, extension) => + extension.dispatch_transaction(Some(signer).into(), self.function, info, len), + ExtrinsicFormat::General(extension) => + extension.dispatch_transaction(None.into(), self.function, info, len), + } } } diff --git a/substrate/primitives/runtime/src/generic/mod.rs b/substrate/primitives/runtime/src/generic/mod.rs index 3687f7cdb3b..5713c166b04 100644 --- a/substrate/primitives/runtime/src/generic/mod.rs +++ b/substrate/primitives/runtime/src/generic/mod.rs @@ -29,9 +29,9 @@ mod unchecked_extrinsic; pub use self::{ block::{Block, BlockId, SignedBlock}, - checked_extrinsic::CheckedExtrinsic, + checked_extrinsic::{CheckedExtrinsic, ExtrinsicFormat}, digest::{Digest, DigestItem, DigestItemRef, OpaqueDigestItemId}, era::{Era, Phase}, header::Header, - unchecked_extrinsic::{SignedPayload, UncheckedExtrinsic}, + unchecked_extrinsic::{Preamble, SignedPayload, UncheckedExtrinsic}, }; diff --git a/substrate/primitives/runtime/src/generic/unchecked_extrinsic.rs b/substrate/primitives/runtime/src/generic/unchecked_extrinsic.rs index 5b54caf597b..44dfda13d94 100644 --- a/substrate/primitives/runtime/src/generic/unchecked_extrinsic.rs +++ b/substrate/primitives/runtime/src/generic/unchecked_extrinsic.rs @@ -18,10 +18,11 @@ //! Generic implementation of an unchecked (pre-verification) extrinsic. use crate::{ - generic::CheckedExtrinsic, + generic::{CheckedExtrinsic, ExtrinsicFormat}, traits::{ - self, Checkable, Extrinsic, ExtrinsicMetadata, IdentifyAccount, MaybeDisplay, Member, - SignaturePayload, SignedExtension, + self, transaction_extension::TransactionExtensionBase, Checkable, Dispatchable, Extrinsic, + ExtrinsicMetadata, IdentifyAccount, MaybeDisplay, Member, SignaturePayload, + TransactionExtension, }, transaction_validity::{InvalidTransaction, TransactionValidityError}, OpaqueExtrinsic, @@ -40,8 +41,60 @@ use sp_std::{fmt, prelude::*}; /// the decoding fails. const EXTRINSIC_FORMAT_VERSION: u8 = 4; -/// The `SingaturePayload` of `UncheckedExtrinsic`. -type UncheckedSignaturePayload = (Address, Signature, Extra); +/// The `SignaturePayload` of `UncheckedExtrinsic`. +type UncheckedSignaturePayload = (Address, Signature, Extension); + +impl SignaturePayload + for UncheckedSignaturePayload +{ + type SignatureAddress = Address; + type Signature = Signature; + type SignatureExtra = Extension; +} + +/// A "header" for extrinsics leading up to the call itself. Determines the type of extrinsic and +/// holds any necessary specialized data. +#[derive(Eq, PartialEq, Clone, Encode, Decode)] +pub enum Preamble { + /// An extrinsic without a signature or any extension. This means it's either an inherent or + /// an old-school "Unsigned" (we don't use that terminology any more since it's confusable with + /// the general transaction which is without a signature but does have an extension). + /// + /// NOTE: In the future, once we remove `ValidateUnsigned`, this will only serve Inherent + /// extrinsics and thus can be renamed to `Inherent`. + #[codec(index = 0b00000100)] + Bare, + /// An old-school transaction extrinsic which includes a signature of some hard-coded crypto. + #[codec(index = 0b10000100)] + Signed(Address, Signature, Extension), + /// A new-school transaction extrinsic which does not include a signature. + #[codec(index = 0b01000100)] + General(Extension), +} + +impl Preamble { + /// Returns `Some` if this is a signed extrinsic, together with the relevant inner fields. + pub fn to_signed(self) -> Option<(Address, Signature, Extension)> { + match self { + Self::Signed(a, s, e) => Some((a, s, e)), + _ => None, + } + } +} + +impl fmt::Debug for Preamble +where + Address: fmt::Debug, + Extension: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::Bare => write!(f, "Bare"), + Self::Signed(address, _, tx_ext) => write!(f, "Signed({:?}, {:?})", address, tx_ext), + Self::General(tx_ext) => write!(f, "General({:?})", tx_ext), + } + } +} /// An extrinsic right from the external world. This is unchecked and so can contain a signature. /// @@ -65,41 +118,28 @@ type UncheckedSignaturePayload = (Address, Signature, /// This can be checked using [`Checkable`], yielding a [`CheckedExtrinsic`], which is the /// counterpart of this type after its signature (and other non-negotiable validity checks) have /// passed. -#[derive(PartialEq, Eq, Clone)] -pub struct UncheckedExtrinsic -where - Extra: SignedExtension, -{ - /// The signature, address, number of extrinsics have come before from the same signer and an - /// era describing the longevity of this transaction, if this is a signed extrinsic. - /// - /// `None` if it is unsigned or an inherent. - pub signature: Option>, +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct UncheckedExtrinsic { + /// Information regarding the type of extrinsic this is (inherent or transaction) as well as + /// associated extension (`Extension`) data if it's a transaction and a possible signature. + pub preamble: Preamble, /// The function that should be called. pub function: Call, } -impl SignaturePayload - for UncheckedSignaturePayload -{ - type SignatureAddress = Address; - type Signature = Signature; - type SignatureExtra = Extra; -} - /// Manual [`TypeInfo`] implementation because of custom encoding. The data is a valid encoded /// `Vec`, but requires some logic to extract the signature and payload. /// /// See [`UncheckedExtrinsic::encode`] and [`UncheckedExtrinsic::decode`]. -impl TypeInfo - for UncheckedExtrinsic +impl TypeInfo + for UncheckedExtrinsic where Address: StaticTypeInfo, Call: StaticTypeInfo, Signature: StaticTypeInfo, - Extra: SignedExtension + StaticTypeInfo, + Extension: StaticTypeInfo, { - type Identity = UncheckedExtrinsic; + type Identity = UncheckedExtrinsic; fn type_info() -> Type { Type::builder() @@ -111,7 +151,7 @@ where TypeParameter::new("Address", Some(meta_type::
())), TypeParameter::new("Call", Some(meta_type::())), TypeParameter::new("Signature", Some(meta_type::())), - TypeParameter::new("Extra", Some(meta_type::())), + TypeParameter::new("Extra", Some(meta_type::())), ]) .docs(&["UncheckedExtrinsic raw bytes, requires custom decoding routine"]) // Because of the custom encoding, we can only accurately describe the encoding as an @@ -121,66 +161,113 @@ where } } -impl - UncheckedExtrinsic -{ - /// New instance of a signed extrinsic aka "transaction". - pub fn new_signed(function: Call, signed: Address, signature: Signature, extra: Extra) -> Self { - Self { signature: Some((signed, signature, extra)), function } +impl UncheckedExtrinsic { + /// New instance of a bare (ne unsigned) extrinsic. This could be used for an inherent or an + /// old-school "unsigned transaction" (which are new being deprecated in favour of general + /// transactions). + #[deprecated = "Use new_bare instead"] + pub fn new_unsigned(function: Call) -> Self { + Self::new_bare(function) } - /// New instance of an unsigned extrinsic aka "inherent". - pub fn new_unsigned(function: Call) -> Self { - Self { signature: None, function } + /// Returns `true` if this extrinsic instance is an inherent, `false`` otherwise. + pub fn is_inherent(&self) -> bool { + matches!(self.preamble, Preamble::Bare) + } + + /// Returns `true` if this extrinsic instance is an old-school signed transaction, `false` + /// otherwise. + pub fn is_signed(&self) -> bool { + matches!(self.preamble, Preamble::Signed(..)) + } + + /// Create an `UncheckedExtrinsic` from a `Preamble` and the actual `Call`. + pub fn from_parts(function: Call, preamble: Preamble) -> Self { + Self { preamble, function } + } + + /// New instance of a bare (ne unsigned) extrinsic. + pub fn new_bare(function: Call) -> Self { + Self { preamble: Preamble::Bare, function } + } + + /// New instance of an old-school signed transaction. + pub fn new_signed( + function: Call, + signed: Address, + signature: Signature, + tx_ext: Extension, + ) -> Self { + Self { preamble: Preamble::Signed(signed, signature, tx_ext), function } + } + + /// New instance of an new-school unsigned transaction. + pub fn new_transaction(function: Call, tx_ext: Extension) -> Self { + Self { preamble: Preamble::General(tx_ext), function } } } -impl - Extrinsic for UncheckedExtrinsic +// TODO: We can get rid of this trait and just use UncheckedExtrinsic directly. + +impl Extrinsic + for UncheckedExtrinsic { type Call = Call; - type SignaturePayload = UncheckedSignaturePayload; + type SignaturePayload = UncheckedSignaturePayload; + + fn is_bare(&self) -> bool { + matches!(self.preamble, Preamble::Bare) + } fn is_signed(&self) -> Option { - Some(self.signature.is_some()) + Some(matches!(self.preamble, Preamble::Signed(..))) } fn new(function: Call, signed_data: Option) -> Option { Some(if let Some((address, signature, extra)) = signed_data { Self::new_signed(function, address, signature, extra) } else { - Self::new_unsigned(function) + Self::new_bare(function) }) } + + fn new_inherent(function: Call) -> Self { + Self::new_bare(function) + } } -impl Checkable - for UncheckedExtrinsic +impl Checkable + for UncheckedExtrinsic where LookupSource: Member + MaybeDisplay, - Call: Encode + Member, + Call: Encode + Member + Dispatchable, Signature: Member + traits::Verify, ::Signer: IdentifyAccount, - Extra: SignedExtension, + Extension: Encode + TransactionExtension, AccountId: Member + MaybeDisplay, Lookup: traits::Lookup, { - type Checked = CheckedExtrinsic; + type Checked = CheckedExtrinsic; fn check(self, lookup: &Lookup) -> Result { - Ok(match self.signature { - Some((signed, signature, extra)) => { + Ok(match self.preamble { + Preamble::Signed(signed, signature, tx_ext) => { let signed = lookup.lookup(signed)?; - let raw_payload = SignedPayload::new(self.function, extra)?; + // CHECK! Should this not contain implicit? + let raw_payload = SignedPayload::new(self.function, tx_ext)?; if !raw_payload.using_encoded(|payload| signature.verify(payload, &signed)) { return Err(InvalidTransaction::BadProof.into()) } - - let (function, extra, _) = raw_payload.deconstruct(); - CheckedExtrinsic { signed: Some((signed, extra)), function } + let (function, tx_ext, _) = raw_payload.deconstruct(); + CheckedExtrinsic { format: ExtrinsicFormat::Signed(signed, tx_ext), function } + }, + Preamble::General(tx_ext) => CheckedExtrinsic { + format: ExtrinsicFormat::General(tx_ext), + function: self.function, }, - None => CheckedExtrinsic { signed: None, function: self.function }, + Preamble::Bare => + CheckedExtrinsic { format: ExtrinsicFormat::Bare, function: self.function }, }) } @@ -189,91 +276,38 @@ where self, lookup: &Lookup, ) -> Result { - Ok(match self.signature { - Some((signed, _, extra)) => { + Ok(match self.preamble { + Preamble::Signed(signed, _, extra) => { let signed = lookup.lookup(signed)?; - let raw_payload = SignedPayload::new(self.function, extra)?; - let (function, extra, _) = raw_payload.deconstruct(); - CheckedExtrinsic { signed: Some((signed, extra)), function } + CheckedExtrinsic { + format: ExtrinsicFormat::Signed(signed, extra), + function: self.function, + } }, - None => CheckedExtrinsic { signed: None, function: self.function }, + Preamble::General(extra) => CheckedExtrinsic { + format: ExtrinsicFormat::General(extra), + function: self.function, + }, + Preamble::Bare => + CheckedExtrinsic { format: ExtrinsicFormat::Bare, function: self.function }, }) } } -impl ExtrinsicMetadata - for UncheckedExtrinsic -where - Extra: SignedExtension, +impl> + ExtrinsicMetadata for UncheckedExtrinsic { const VERSION: u8 = EXTRINSIC_FORMAT_VERSION; - type SignedExtensions = Extra; -} - -/// A payload that has been signed for an unchecked extrinsics. -/// -/// Note that the payload that we sign to produce unchecked extrinsic signature -/// is going to be different than the `SignaturePayload` - so the thing the extrinsic -/// actually contains. -pub struct SignedPayload((Call, Extra, Extra::AdditionalSigned)); - -impl SignedPayload -where - Call: Encode, - Extra: SignedExtension, -{ - /// Create new `SignedPayload`. - /// - /// This function may fail if `additional_signed` of `Extra` is not available. - pub fn new(call: Call, extra: Extra) -> Result { - let additional_signed = extra.additional_signed()?; - let raw_payload = (call, extra, additional_signed); - Ok(Self(raw_payload)) - } - - /// Create new `SignedPayload` from raw components. - pub fn from_raw(call: Call, extra: Extra, additional_signed: Extra::AdditionalSigned) -> Self { - Self((call, extra, additional_signed)) - } - - /// Deconstruct the payload into it's components. - pub fn deconstruct(self) -> (Call, Extra, Extra::AdditionalSigned) { - self.0 - } + type Extra = Extension; } -impl Encode for SignedPayload -where - Call: Encode, - Extra: SignedExtension, -{ - /// Get an encoded version of this payload. - /// - /// Payloads longer than 256 bytes are going to be `blake2_256`-hashed. - fn using_encoded R>(&self, f: F) -> R { - self.0.using_encoded(|payload| { - if payload.len() > 256 { - f(&blake2_256(payload)[..]) - } else { - f(payload) - } - }) - } -} - -impl EncodeLike for SignedPayload -where - Call: Encode, - Extra: SignedExtension, -{ -} - -impl Decode for UncheckedExtrinsic +impl Decode + for UncheckedExtrinsic where Address: Decode, Signature: Decode, Call: Decode, - Extra: SignedExtension, + Extension: Decode, { fn decode(input: &mut I) -> Result { // This is a little more complicated than usual since the binary format must be compatible @@ -282,15 +316,7 @@ where let expected_length: Compact = Decode::decode(input)?; let before_length = input.remaining_len()?; - let version = input.read_byte()?; - - let is_signed = version & 0b1000_0000 != 0; - let version = version & 0b0111_1111; - if version != EXTRINSIC_FORMAT_VERSION { - return Err("Invalid transaction version".into()) - } - - let signature = is_signed.then(|| Decode::decode(input)).transpose()?; + let preamble = Decode::decode(input)?; let function = Decode::decode(input)?; if let Some((before_length, after_length)) = @@ -303,31 +329,20 @@ where } } - Ok(Self { signature, function }) + Ok(Self { preamble, function }) } } #[docify::export(unchecked_extrinsic_encode_impl)] -impl Encode for UncheckedExtrinsic +impl Encode + for UncheckedExtrinsic where - Address: Encode, - Signature: Encode, + Preamble: Encode, Call: Encode, - Extra: SignedExtension, + Extension: Encode, { fn encode(&self) -> Vec { - let mut tmp = Vec::with_capacity(sp_std::mem::size_of::()); - - // 1 byte version id. - match self.signature.as_ref() { - Some(s) => { - tmp.push(EXTRINSIC_FORMAT_VERSION | 0b1000_0000); - s.encode_to(&mut tmp); - }, - None => { - tmp.push(EXTRINSIC_FORMAT_VERSION & 0b0111_1111); - }, - } + let mut tmp = self.preamble.encode(); self.function.encode_to(&mut tmp); let compact_len = codec::Compact::(tmp.len() as u32); @@ -342,19 +357,19 @@ where } } -impl EncodeLike - for UncheckedExtrinsic +impl EncodeLike + for UncheckedExtrinsic where Address: Encode, Signature: Encode, - Call: Encode, - Extra: SignedExtension, + Call: Encode + Dispatchable, + Extension: TransactionExtension, { } #[cfg(feature = "serde")] -impl serde::Serialize - for UncheckedExtrinsic +impl serde::Serialize + for UncheckedExtrinsic { fn serialize(&self, seq: S) -> Result where @@ -365,45 +380,88 @@ impl s } #[cfg(feature = "serde")] -impl<'a, Address: Decode, Signature: Decode, Call: Decode, Extra: SignedExtension> - serde::Deserialize<'a> for UncheckedExtrinsic +impl<'a, Address: Decode, Signature: Decode, Call: Decode, Extension: Decode> serde::Deserialize<'a> + for UncheckedExtrinsic { fn deserialize(de: D) -> Result where D: serde::Deserializer<'a>, { let r = sp_core::bytes::deserialize(de)?; - Decode::decode(&mut &r[..]) + Self::decode(&mut &r[..]) .map_err(|e| serde::de::Error::custom(format!("Decode error: {}", e))) } } -impl fmt::Debug - for UncheckedExtrinsic +/// A payload that has been signed for an unchecked extrinsics. +/// +/// Note that the payload that we sign to produce unchecked extrinsic signature +/// is going to be different than the `SignaturePayload` - so the thing the extrinsic +/// actually contains. +pub struct SignedPayload( + (Call, Extension, Extension::Implicit), +); + +impl SignedPayload where - Address: fmt::Debug, - Call: fmt::Debug, - Extra: SignedExtension, + Call: Encode + Dispatchable, + Extension: TransactionExtensionBase, { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "UncheckedExtrinsic({:?}, {:?})", - self.signature.as_ref().map(|x| (&x.0, &x.2)), - self.function, - ) + /// Create new `SignedPayload`. + /// + /// This function may fail if `implicit` of `Extension` is not available. + pub fn new(call: Call, tx_ext: Extension) -> Result { + let implicit = Extension::implicit(&tx_ext)?; + let raw_payload = (call, tx_ext, implicit); + Ok(Self(raw_payload)) + } + + /// Create new `SignedPayload` from raw components. + pub fn from_raw(call: Call, tx_ext: Extension, implicit: Extension::Implicit) -> Self { + Self((call, tx_ext, implicit)) + } + + /// Deconstruct the payload into it's components. + pub fn deconstruct(self) -> (Call, Extension, Extension::Implicit) { + self.0 } } -impl From> - for OpaqueExtrinsic +impl Encode for SignedPayload +where + Call: Encode + Dispatchable, + Extension: TransactionExtensionBase, +{ + /// Get an encoded version of this payload. + /// + /// Payloads longer than 256 bytes are going to be `blake2_256`-hashed. + fn using_encoded R>(&self, f: F) -> R { + self.0.using_encoded(|payload| { + if payload.len() > 256 { + f(&blake2_256(payload)[..]) + } else { + f(payload) + } + }) + } +} + +impl EncodeLike for SignedPayload +where + Call: Encode + Dispatchable, + Extension: TransactionExtensionBase, +{ +} + +impl + From> for OpaqueExtrinsic where Address: Encode, Signature: Encode, Call: Encode, - Extra: SignedExtension, + Extension: Encode, { - fn from(extrinsic: UncheckedExtrinsic) -> Self { + fn from(extrinsic: UncheckedExtrinsic) -> Self { Self::from_bytes(extrinsic.encode().as_slice()).expect( "both OpaqueExtrinsic and UncheckedExtrinsic have encoding that is compatible with \ raw Vec encoding; qed", @@ -411,60 +469,198 @@ where } } +#[cfg(test)] +mod legacy { + use codec::{Compact, Decode, Encode, EncodeLike, Error, Input}; + use scale_info::{ + build::Fields, meta_type, Path, StaticTypeInfo, Type, TypeInfo, TypeParameter, + }; + + pub type OldUncheckedSignaturePayload = (Address, Signature, Extra); + + #[derive(PartialEq, Eq, Clone, Debug)] + pub struct OldUncheckedExtrinsic { + pub signature: Option>, + pub function: Call, + } + + impl TypeInfo + for OldUncheckedExtrinsic + where + Address: StaticTypeInfo, + Call: StaticTypeInfo, + Signature: StaticTypeInfo, + Extra: StaticTypeInfo, + { + type Identity = OldUncheckedExtrinsic; + + fn type_info() -> Type { + Type::builder() + .path(Path::new("UncheckedExtrinsic", module_path!())) + // Include the type parameter types, even though they are not used directly in any + // of the described fields. These type definitions can be used by downstream + // consumers to help construct the custom decoding from the opaque bytes (see + // below). + .type_params(vec![ + TypeParameter::new("Address", Some(meta_type::
())), + TypeParameter::new("Call", Some(meta_type::())), + TypeParameter::new("Signature", Some(meta_type::())), + TypeParameter::new("Extra", Some(meta_type::())), + ]) + .docs(&["OldUncheckedExtrinsic raw bytes, requires custom decoding routine"]) + // Because of the custom encoding, we can only accurately describe the encoding as + // an opaque `Vec`. Downstream consumers will need to manually implement the + // codec to encode/decode the `signature` and `function` fields. + .composite(Fields::unnamed().field(|f| f.ty::>())) + } + } + + impl OldUncheckedExtrinsic { + pub fn new_signed( + function: Call, + signed: Address, + signature: Signature, + extra: Extra, + ) -> Self { + Self { signature: Some((signed, signature, extra)), function } + } + + pub fn new_unsigned(function: Call) -> Self { + Self { signature: None, function } + } + } + + impl Decode + for OldUncheckedExtrinsic + where + Address: Decode, + Signature: Decode, + Call: Decode, + Extra: Decode, + { + fn decode(input: &mut I) -> Result { + // This is a little more complicated than usual since the binary format must be + // compatible with SCALE's generic `Vec` type. Basically this just means accepting + // that there will be a prefix of vector length. + let expected_length: Compact = Decode::decode(input)?; + let before_length = input.remaining_len()?; + + let version = input.read_byte()?; + + let is_signed = version & 0b1000_0000 != 0; + let version = version & 0b0111_1111; + if version != 4u8 { + return Err("Invalid transaction version".into()) + } + + let signature = is_signed.then(|| Decode::decode(input)).transpose()?; + let function = Decode::decode(input)?; + + if let Some((before_length, after_length)) = + input.remaining_len()?.and_then(|a| before_length.map(|b| (b, a))) + { + let length = before_length.saturating_sub(after_length); + + if length != expected_length.0 as usize { + return Err("Invalid length prefix".into()) + } + } + + Ok(Self { signature, function }) + } + } + + #[docify::export(unchecked_extrinsic_encode_impl)] + impl Encode + for OldUncheckedExtrinsic + where + Address: Encode, + Signature: Encode, + Call: Encode, + Extra: Encode, + { + fn encode(&self) -> Vec { + let mut tmp = Vec::with_capacity(sp_std::mem::size_of::()); + + // 1 byte version id. + match self.signature.as_ref() { + Some(s) => { + tmp.push(4u8 | 0b1000_0000); + s.encode_to(&mut tmp); + }, + None => { + tmp.push(4u8 & 0b0111_1111); + }, + } + self.function.encode_to(&mut tmp); + + let compact_len = codec::Compact::(tmp.len() as u32); + + // Allocate the output buffer with the correct length + let mut output = Vec::with_capacity(compact_len.size_hint() + tmp.len()); + + compact_len.encode_to(&mut output); + output.extend(tmp); + + output + } + } + + impl EncodeLike + for OldUncheckedExtrinsic + where + Address: Encode, + Signature: Encode, + Call: Encode, + Extra: Encode, + { + } +} + #[cfg(test)] mod tests { - use super::*; + use super::{legacy::OldUncheckedExtrinsic, *}; use crate::{ codec::{Decode, Encode}, + impl_tx_ext_default, testing::TestSignature as TestSig, - traits::{DispatchInfoOf, IdentityLookup, SignedExtension}, + traits::{FakeDispatchable, IdentityLookup, TransactionExtension}, }; use sp_io::hashing::blake2_256; type TestContext = IdentityLookup; type TestAccountId = u64; - type TestCall = Vec; + type TestCall = FakeDispatchable>; const TEST_ACCOUNT: TestAccountId = 0; // NOTE: this is demonstration. One can simply use `()` for testing. #[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, Ord, PartialOrd, TypeInfo)] - struct TestExtra; - impl SignedExtension for TestExtra { - const IDENTIFIER: &'static str = "TestExtra"; - type AccountId = u64; - type Call = (); - type AdditionalSigned = (); + struct DummyExtension; + impl TransactionExtensionBase for DummyExtension { + const IDENTIFIER: &'static str = "DummyExtension"; + type Implicit = (); + } + impl TransactionExtension for DummyExtension { + type Val = (); type Pre = (); - - fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { - Ok(()) - } - - fn pre_dispatch( - self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> Result { - self.validate(who, call, info, len).map(|_| ()) - } + impl_tx_ext_default!(TestCall; Context; validate prepare); } - type Ex = UncheckedExtrinsic; - type CEx = CheckedExtrinsic; + type Ex = UncheckedExtrinsic; + type CEx = CheckedExtrinsic; #[test] fn unsigned_codec_should_work() { - let ux = Ex::new_unsigned(vec![0u8; 0]); + let call: TestCall = vec![0u8; 0].into(); + let ux = Ex::new_inherent(call); let encoded = ux.encode(); assert_eq!(Ex::decode(&mut &encoded[..]), Ok(ux)); } #[test] fn invalid_length_prefix_is_detected() { - let ux = Ex::new_unsigned(vec![0u8; 0]); + let ux = Ex::new_inherent(vec![0u8; 0].into()); let mut encoded = ux.encode(); let length = Compact::::decode(&mut &encoded[..]).unwrap(); @@ -473,13 +669,20 @@ mod tests { assert_eq!(Ex::decode(&mut &encoded[..]), Err("Invalid length prefix".into())); } + #[test] + fn transaction_codec_should_work() { + let ux = Ex::new_transaction(vec![0u8; 0].into(), DummyExtension); + let encoded = ux.encode(); + assert_eq!(Ex::decode(&mut &encoded[..]), Ok(ux)); + } + #[test] fn signed_codec_should_work() { let ux = Ex::new_signed( - vec![0u8; 0], + vec![0u8; 0].into(), TEST_ACCOUNT, - TestSig(TEST_ACCOUNT, (vec![0u8; 0], TestExtra).encode()), - TestExtra, + TestSig(TEST_ACCOUNT, (vec![0u8; 0], DummyExtension).encode()), + DummyExtension, ); let encoded = ux.encode(); assert_eq!(Ex::decode(&mut &encoded[..]), Ok(ux)); @@ -488,13 +691,13 @@ mod tests { #[test] fn large_signed_codec_should_work() { let ux = Ex::new_signed( - vec![0u8; 0], + vec![0u8; 0].into(), TEST_ACCOUNT, TestSig( TEST_ACCOUNT, - (vec![0u8; 257], TestExtra).using_encoded(blake2_256)[..].to_owned(), + (vec![0u8; 257], DummyExtension).using_encoded(blake2_256)[..].to_owned(), ), - TestExtra, + DummyExtension, ); let encoded = ux.encode(); assert_eq!(Ex::decode(&mut &encoded[..]), Ok(ux)); @@ -502,44 +705,63 @@ mod tests { #[test] fn unsigned_check_should_work() { - let ux = Ex::new_unsigned(vec![0u8; 0]); - assert!(!ux.is_signed().unwrap_or(false)); - assert!(>::check(ux, &Default::default()).is_ok()); + let ux = Ex::new_inherent(vec![0u8; 0].into()); + assert!(ux.is_inherent()); + assert_eq!( + >::check(ux, &Default::default()), + Ok(CEx { format: ExtrinsicFormat::Bare, function: vec![0u8; 0].into() }), + ); } #[test] fn badly_signed_check_should_fail() { let ux = Ex::new_signed( - vec![0u8; 0], + vec![0u8; 0].into(), TEST_ACCOUNT, - TestSig(TEST_ACCOUNT, vec![0u8; 0]), - TestExtra, + TestSig(TEST_ACCOUNT, vec![0u8; 0].into()), + DummyExtension, ); - assert!(ux.is_signed().unwrap_or(false)); + assert!(!ux.is_inherent()); assert_eq!( >::check(ux, &Default::default()), Err(InvalidTransaction::BadProof.into()), ); } + #[test] + fn transaction_check_should_work() { + let ux = Ex::new_transaction(vec![0u8; 0].into(), DummyExtension); + assert!(!ux.is_inherent()); + assert_eq!( + >::check(ux, &Default::default()), + Ok(CEx { + format: ExtrinsicFormat::General(DummyExtension), + function: vec![0u8; 0].into() + }), + ); + } + #[test] fn signed_check_should_work() { let ux = Ex::new_signed( - vec![0u8; 0], + vec![0u8; 0].into(), TEST_ACCOUNT, - TestSig(TEST_ACCOUNT, (vec![0u8; 0], TestExtra).encode()), - TestExtra, + TestSig(TEST_ACCOUNT, (vec![0u8; 0], DummyExtension).encode()), + DummyExtension, ); - assert!(ux.is_signed().unwrap_or(false)); + assert!(!ux.is_inherent()); assert_eq!( >::check(ux, &Default::default()), - Ok(CEx { signed: Some((TEST_ACCOUNT, TestExtra)), function: vec![0u8; 0] }), + Ok(CEx { + format: ExtrinsicFormat::Signed(TEST_ACCOUNT, DummyExtension), + function: vec![0u8; 0].into() + }), ); } #[test] fn encoding_matches_vec() { - let ex = Ex::new_unsigned(vec![0u8; 0]); + let ex = Ex::new_inherent(vec![0u8; 0].into()); let encoded = ex.encode(); let decoded = Ex::decode(&mut encoded.as_slice()).unwrap(); assert_eq!(decoded, ex); @@ -549,7 +771,7 @@ mod tests { #[test] fn conversion_to_opaque() { - let ux = Ex::new_unsigned(vec![0u8; 0]); + let ux = Ex::new_inherent(vec![0u8; 0].into()); let encoded = ux.encode(); let opaque: OpaqueExtrinsic = ux.into(); let opaque_encoded = opaque.encode(); @@ -558,10 +780,62 @@ mod tests { #[test] fn large_bad_prefix_should_work() { - let encoded = Compact::::from(u32::MAX).encode(); - assert_eq!( - Ex::decode(&mut &encoded[..]), - Err(Error::from("Not enough data to fill buffer")) - ); + let encoded = (Compact::::from(u32::MAX), Preamble::<(), (), ()>::Bare).encode(); + assert!(Ex::decode(&mut &encoded[..]).is_err()); + } + + #[test] + fn legacy_signed_encode_decode() { + let call: TestCall = vec![0u8; 0].into(); + let signed = TEST_ACCOUNT; + let signature = TestSig(TEST_ACCOUNT, (vec![0u8; 0], DummyExtension).encode()); + let extension = DummyExtension; + + let new_ux = Ex::new_signed(call.clone(), signed, signature.clone(), extension.clone()); + let old_ux = + OldUncheckedExtrinsic::::new_signed( + call, signed, signature, extension, + ); + + let encoded_new_ux = new_ux.encode(); + let encoded_old_ux = old_ux.encode(); + + assert_eq!(encoded_new_ux, encoded_old_ux); + + let decoded_new_ux = Ex::decode(&mut &encoded_new_ux[..]).unwrap(); + let decoded_old_ux = + OldUncheckedExtrinsic::::decode( + &mut &encoded_old_ux[..], + ) + .unwrap(); + + assert_eq!(new_ux, decoded_new_ux); + assert_eq!(old_ux, decoded_old_ux); + } + + #[test] + fn legacy_unsigned_encode_decode() { + let call: TestCall = vec![0u8; 0].into(); + + let new_ux = Ex::new_bare(call.clone()); + let old_ux = + OldUncheckedExtrinsic::::new_unsigned( + call, + ); + + let encoded_new_ux = new_ux.encode(); + let encoded_old_ux = old_ux.encode(); + + assert_eq!(encoded_new_ux, encoded_old_ux); + + let decoded_new_ux = Ex::decode(&mut &encoded_new_ux[..]).unwrap(); + let decoded_old_ux = + OldUncheckedExtrinsic::::decode( + &mut &encoded_old_ux[..], + ) + .unwrap(); + + assert_eq!(new_ux, decoded_new_ux); + assert_eq!(old_ux, decoded_old_ux); } } diff --git a/substrate/primitives/runtime/src/lib.rs b/substrate/primitives/runtime/src/lib.rs index 44bf3c969e5..70605970b4e 100644 --- a/substrate/primitives/runtime/src/lib.rs +++ b/substrate/primitives/runtime/src/lib.rs @@ -125,6 +125,11 @@ pub use sp_arithmetic::{ Perquintill, Rational128, Rounding, UpperOf, }; +pub use transaction_validity::{ + InvalidTransaction, TransactionSource, TransactionValidityError, UnknownTransaction, + ValidTransaction, +}; + pub use either::Either; /// The number of bytes of the module-specific `error` field defined in [`ModuleError`]. @@ -443,21 +448,21 @@ impl std::fmt::Display for MultiSigner { impl Verify for MultiSignature { type Signer = MultiSigner; fn verify>(&self, mut msg: L, signer: &AccountId32) -> bool { - match (self, signer) { - (Self::Ed25519(ref sig), who) => match ed25519::Public::from_slice(who.as_ref()) { + match self { + Self::Ed25519(ref sig) => match ed25519::Public::from_slice(signer.as_ref()) { Ok(signer) => sig.verify(msg, &signer), Err(()) => false, }, - (Self::Sr25519(ref sig), who) => match sr25519::Public::from_slice(who.as_ref()) { + Self::Sr25519(ref sig) => match sr25519::Public::from_slice(signer.as_ref()) { Ok(signer) => sig.verify(msg, &signer), Err(()) => false, }, - (Self::Ecdsa(ref sig), who) => { + Self::Ecdsa(ref sig) => { let m = sp_io::hashing::blake2_256(msg.get()); match sp_io::crypto::secp256k1_ecdsa_recover_compressed(sig.as_ref(), &m) { Ok(pubkey) => &sp_io::hashing::blake2_256(pubkey.as_ref()) == - >::as_ref(who), + >::as_ref(signer), _ => false, } }, @@ -944,9 +949,13 @@ impl<'a> ::serde::Deserialize<'a> for OpaqueExtrinsic { } } +// TODO: OpaqueExtrinsics cannot act like regular extrinsics, right?! impl traits::Extrinsic for OpaqueExtrinsic { type Call = (); type SignaturePayload = (); + fn is_bare(&self) -> bool { + false + } } /// Print something that implements `Printable` from the runtime. diff --git a/substrate/primitives/runtime/src/testing.rs b/substrate/primitives/runtime/src/testing.rs index 5f94c834a8f..3d6e0b5ab8b 100644 --- a/substrate/primitives/runtime/src/testing.rs +++ b/substrate/primitives/runtime/src/testing.rs @@ -21,24 +21,16 @@ use crate::{ codec::{Codec, Decode, Encode, MaxEncodedLen}, generic, scale_info::TypeInfo, - traits::{ - self, Applyable, BlakeTwo256, Checkable, DispatchInfoOf, Dispatchable, OpaqueKeys, - PostDispatchInfoOf, SignaturePayload, SignedExtension, ValidateUnsigned, - }, - transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError}, - ApplyExtrinsicResultWithInfo, KeyTypeId, + traits::{self, BlakeTwo256, Dispatchable, OpaqueKeys}, + DispatchResultWithInfo, KeyTypeId, }; -use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize, Serializer}; +use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize}; use sp_core::{ crypto::{key_types, ByteArray, CryptoType, Dummy}, U256, }; pub use sp_core::{sr25519, H256}; -use std::{ - cell::RefCell, - fmt::{self, Debug}, - ops::Deref, -}; +use std::{cell::RefCell, fmt::Debug}; /// A dummy type which can be used instead of regular cryptographic primitives. /// @@ -198,42 +190,6 @@ impl Header { } } -/// An opaque extrinsic wrapper type. -#[derive(PartialEq, Eq, Clone, Debug, Encode, Decode)] -pub struct ExtrinsicWrapper(Xt); - -impl traits::Extrinsic for ExtrinsicWrapper { - type Call = (); - type SignaturePayload = (); - - fn is_signed(&self) -> Option { - None - } -} - -impl serde::Serialize for ExtrinsicWrapper { - fn serialize(&self, seq: S) -> Result - where - S: ::serde::Serializer, - { - self.using_encoded(|bytes| seq.serialize_bytes(bytes)) - } -} - -impl From for ExtrinsicWrapper { - fn from(xt: Xt) -> Self { - ExtrinsicWrapper(xt) - } -} - -impl Deref for ExtrinsicWrapper { - type Target = Xt; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - /// Testing block #[derive(PartialEq, Eq, Clone, Serialize, Debug, Encode, Decode, TypeInfo)] pub struct Block { @@ -283,139 +239,22 @@ where } } -/// The signature payload of a `TestXt`. -type TxSingaturePayload = (u64, Extra); - -impl SignaturePayload for TxSingaturePayload { - type SignatureAddress = u64; - type Signature = (); - type SignatureExtra = Extra; -} - -/// Test transaction, tuple of (sender, call, signed_extra) -/// with index only used if sender is some. -/// -/// If sender is some then the transaction is signed otherwise it is unsigned. -#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo)] -pub struct TestXt { - /// Signature of the extrinsic. - pub signature: Option>, - /// Call of the extrinsic. - pub call: Call, -} - -impl TestXt { - /// Create a new `TextXt`. - pub fn new(call: Call, signature: Option<(u64, Extra)>) -> Self { - Self { call, signature } - } -} - -impl Serialize for TestXt -where - TestXt: Encode, -{ - fn serialize(&self, seq: S) -> Result - where - S: Serializer, - { - self.using_encoded(|bytes| seq.serialize_bytes(bytes)) - } -} +/// Wrapper over a `u64` that can be used as a `RuntimeCall`. +#[derive(PartialEq, Eq, Debug, Clone, Encode, Decode, TypeInfo)] +pub struct MockCallU64(pub u64); -impl Debug for TestXt { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "TestXt({:?}, ...)", self.signature.as_ref().map(|x| &x.0)) +impl Dispatchable for MockCallU64 { + type RuntimeOrigin = u64; + type Config = (); + type Info = (); + type PostInfo = (); + fn dispatch(self, _origin: Self::RuntimeOrigin) -> DispatchResultWithInfo { + Ok(()) } } -impl Checkable for TestXt { - type Checked = Self; - fn check(self, _: &Context) -> Result { - Ok(self) - } - - #[cfg(feature = "try-runtime")] - fn unchecked_into_checked_i_know_what_i_am_doing( - self, - _: &Context, - ) -> Result { - unreachable!() - } -} - -impl traits::Extrinsic - for TestXt -{ - type Call = Call; - type SignaturePayload = TxSingaturePayload; - - fn is_signed(&self) -> Option { - Some(self.signature.is_some()) - } - - fn new(c: Call, sig: Option) -> Option { - Some(TestXt { signature: sig, call: c }) - } -} - -impl traits::ExtrinsicMetadata for TestXt -where - Call: Codec + Sync + Send, - Extra: SignedExtension, -{ - type SignedExtensions = Extra; - const VERSION: u8 = 0u8; -} - -impl Applyable for TestXt -where - Call: 'static - + Sized - + Send - + Sync - + Clone - + Eq - + Codec - + Debug - + Dispatchable, - Extra: SignedExtension, - Origin: From>, -{ - type Call = Call; - - /// Checks to see if this is a valid *transaction*. It returns information on it if so. - fn validate>( - &self, - source: TransactionSource, - info: &DispatchInfoOf, - len: usize, - ) -> TransactionValidity { - if let Some((ref id, ref extra)) = self.signature { - Extra::validate(extra, id, &self.call, info, len) - } else { - let valid = Extra::validate_unsigned(&self.call, info, len)?; - let unsigned_validation = U::validate_unsigned(source, &self.call)?; - Ok(valid.combine_with(unsigned_validation)) - } - } - - /// Executes all necessary logic needed prior to dispatch and deconstructs into function call, - /// index and sender. - fn apply>( - self, - info: &DispatchInfoOf, - len: usize, - ) -> ApplyExtrinsicResultWithInfo> { - let maybe_who = if let Some((who, extra)) = self.signature { - Extra::pre_dispatch(extra, &who, &self.call, info, len)?; - Some(who) - } else { - Extra::pre_dispatch_unsigned(&self.call, info, len)?; - U::pre_dispatch(&self.call)?; - None - }; - - Ok(self.call.dispatch(maybe_who.into())) +impl From for MockCallU64 { + fn from(value: u64) -> Self { + Self(value) } } diff --git a/substrate/primitives/runtime/src/traits.rs b/substrate/primitives/runtime/src/traits/mod.rs similarity index 94% rename from substrate/primitives/runtime/src/traits.rs rename to substrate/primitives/runtime/src/traits/mod.rs index caede5e2b59..b217166d8de 100644 --- a/substrate/primitives/runtime/src/traits.rs +++ b/substrate/primitives/runtime/src/traits/mod.rs @@ -19,7 +19,7 @@ use crate::{ generic::Digest, - scale_info::{MetaType, StaticTypeInfo, TypeInfo}, + scale_info::{StaticTypeInfo, TypeInfo}, transaction_validity::{ TransactionSource, TransactionValidity, TransactionValidityError, UnknownTransaction, ValidTransaction, @@ -52,6 +52,12 @@ use std::fmt::Display; #[cfg(feature = "std")] use std::str::FromStr; +pub mod transaction_extension; +pub use transaction_extension::{ + DispatchTransaction, TransactionExtension, TransactionExtensionBase, + TransactionExtensionInterior, TransactionExtensionMetadata, ValidateResult, +}; + /// A lazy value. pub trait Lazy { /// Get a reference to the underlying value. @@ -1253,7 +1259,7 @@ pub trait Header: // that is then used to define `UncheckedExtrinsic`. // ```ignore // pub type UncheckedExtrinsic = -// generic::UncheckedExtrinsic; +// generic::UncheckedExtrinsic; // ``` // This `UncheckedExtrinsic` is supplied to the `Block`. // ```ignore @@ -1323,19 +1329,31 @@ pub trait Extrinsic: Sized { /// Is this `Extrinsic` signed? /// If no information are available about signed/unsigned, `None` should be returned. + #[deprecated = "Use and implement `!is_bare()` instead"] fn is_signed(&self) -> Option { None } - /// Create new instance of the extrinsic. - /// - /// Extrinsics can be split into: - /// 1. Inherents (no signature; created by validators during block production) - /// 2. Unsigned Transactions (no signature; represent "system calls" or other special kinds of - /// calls) 3. Signed Transactions (with signature; a regular transactions with known origin) + /// Returns `true` if this `Extrinsic` is bare. + fn is_bare(&self) -> bool { + #[allow(deprecated)] + !self + .is_signed() + .expect("`is_signed` must return `Some` on production extrinsics; qed") + } + + /// Create a new old-school extrinsic, either a bare extrinsic if `_signed_data` is `None` or + /// a signed transaction is it is `Some`. + #[deprecated = "Use `new_inherent` or the `CreateTransaction` trait instead"] fn new(_call: Self::Call, _signed_data: Option) -> Option { None } + + /// Create a new inherent extrinsic. + fn new_inherent(function: Self::Call) -> Self { + #[allow(deprecated)] + Self::new(function, None).expect("Extrinsic must provide inherents; qed") + } } /// Something that acts like a [`SignaturePayload`](Extrinsic::SignaturePayload) of an @@ -1371,7 +1389,8 @@ pub trait ExtrinsicMetadata { const VERSION: u8; /// Signed extensions attached to this `Extrinsic`. - type SignedExtensions: SignedExtension; + // TODO: metadata-v16: rename to `Extension`. + type Extra; } /// Extract the hashing type for a block. @@ -1456,6 +1475,8 @@ pub trait Dispatchable { -> crate::DispatchResultWithInfo; } +/// Shortcut to reference the `Origin` type of a `Dispatchable`. +pub type OriginOf = ::RuntimeOrigin; /// Shortcut to reference the `Info` type of a `Dispatchable`. pub type DispatchInfoOf = ::Info; /// Shortcut to reference the `PostInfo` type of a `Dispatchable`. @@ -1474,8 +1495,49 @@ impl Dispatchable for () { } } +/// Dispatchable impl containing an arbitrary value which panics if it actually is dispatched. +#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] +pub struct FakeDispatchable(pub Inner); +impl From for FakeDispatchable { + fn from(inner: Inner) -> Self { + Self(inner) + } +} +impl FakeDispatchable { + /// Take `self` and return the underlying inner value. + pub fn deconstruct(self) -> Inner { + self.0 + } +} +impl AsRef for FakeDispatchable { + fn as_ref(&self) -> &Inner { + &self.0 + } +} + +impl Dispatchable for FakeDispatchable { + type RuntimeOrigin = (); + type Config = (); + type Info = (); + type PostInfo = (); + fn dispatch( + self, + _origin: Self::RuntimeOrigin, + ) -> crate::DispatchResultWithInfo { + panic!("This implementation should not be used for actual dispatch."); + } +} + +/// Runtime Origin which includes a System Origin variant whose `AccountId` is the parameter. +pub trait AsSystemOriginSigner { + /// Extract a reference of the inner value of the System `Origin::Signed` variant, if self has + /// that variant. + fn as_system_origin_signer(&self) -> Option<&AccountId>; +} + /// Means by which a transaction may be extended. This type embodies both the data and the logic /// that should be additionally associated with the transaction. It should be plain old data. +#[deprecated = "Use `TransactionExtension` instead."] pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq + StaticTypeInfo { @@ -1493,7 +1555,7 @@ pub trait SignedExtension: /// Any additional data that will go into the signed payload. This may be created dynamically /// from the transaction using the `additional_signed` function. - type AdditionalSigned: Encode + TypeInfo; + type AdditionalSigned: Codec + TypeInfo; /// The type that encodes information that can be passed from pre_dispatch to post-dispatch. type Pre; @@ -1532,38 +1594,6 @@ pub trait SignedExtension: len: usize, ) -> Result; - /// Validate an unsigned transaction for the transaction queue. - /// - /// This function can be called frequently by the transaction queue - /// to obtain transaction validity against current state. - /// It should perform all checks that determine a valid unsigned transaction, - /// and quickly eliminate ones that are stale or incorrect. - /// - /// Make sure to perform the same checks in `pre_dispatch_unsigned` function. - fn validate_unsigned( - _call: &Self::Call, - _info: &DispatchInfoOf, - _len: usize, - ) -> TransactionValidity { - Ok(ValidTransaction::default()) - } - - /// Do any pre-flight stuff for a unsigned transaction. - /// - /// Note this function by default delegates to `validate_unsigned`, so that - /// all checks performed for the transaction queue are also performed during - /// the dispatch phase (applying the extrinsic). - /// - /// If you ever override this function, you need to make sure to always - /// perform the same validation as in `validate_unsigned`. - fn pre_dispatch_unsigned( - call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> Result<(), TransactionValidityError> { - Self::validate_unsigned(call, info, len).map(|_| ()).map_err(Into::into) - } - /// Do any post-flight stuff for an extrinsic. /// /// If the transaction is signed, then `_pre` will contain the output of `pre_dispatch`, @@ -1594,126 +1624,47 @@ pub trait SignedExtension: /// /// As a [`SignedExtension`] can be a tuple of [`SignedExtension`]s we need to return a `Vec` /// that holds the metadata of each one. Each individual `SignedExtension` must return - /// *exactly* one [`SignedExtensionMetadata`]. + /// *exactly* one [`TransactionExtensionMetadata`]. /// /// This method provides a default implementation that returns a vec containing a single - /// [`SignedExtensionMetadata`]. - fn metadata() -> Vec { - sp_std::vec![SignedExtensionMetadata { + /// [`TransactionExtensionMetadata`]. + fn metadata() -> Vec { + sp_std::vec![TransactionExtensionMetadata { identifier: Self::IDENTIFIER, ty: scale_info::meta_type::(), additional_signed: scale_info::meta_type::() }] } -} - -/// Information about a [`SignedExtension`] for the runtime metadata. -pub struct SignedExtensionMetadata { - /// The unique identifier of the [`SignedExtension`]. - pub identifier: &'static str, - /// The type of the [`SignedExtension`]. - pub ty: MetaType, - /// The type of the [`SignedExtension`] additional signed data for the payload. - pub additional_signed: MetaType, -} - -#[impl_for_tuples(1, 12)] -impl SignedExtension for Tuple { - for_tuples!( where #( Tuple: SignedExtension )* ); - type AccountId = AccountId; - type Call = Call; - const IDENTIFIER: &'static str = "You should call `identifier()`!"; - for_tuples!( type AdditionalSigned = ( #( Tuple::AdditionalSigned ),* ); ); - for_tuples!( type Pre = ( #( Tuple::Pre ),* ); ); - - fn additional_signed(&self) -> Result { - Ok(for_tuples!( ( #( Tuple.additional_signed()? ),* ) )) - } - - fn validate( - &self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> TransactionValidity { - let valid = ValidTransaction::default(); - for_tuples!( #( let valid = valid.combine_with(Tuple.validate(who, call, info, len)?); )* ); - Ok(valid) - } - - fn pre_dispatch( - self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> Result { - Ok(for_tuples!( ( #( Tuple.pre_dispatch(who, call, info, len)? ),* ) )) - } + /// Validate an unsigned transaction for the transaction queue. + /// + /// This function can be called frequently by the transaction queue + /// to obtain transaction validity against current state. + /// It should perform all checks that determine a valid unsigned transaction, + /// and quickly eliminate ones that are stale or incorrect. fn validate_unsigned( - call: &Self::Call, - info: &DispatchInfoOf, - len: usize, + _call: &Self::Call, + _info: &DispatchInfoOf, + _len: usize, ) -> TransactionValidity { - let valid = ValidTransaction::default(); - for_tuples!( #( let valid = valid.combine_with(Tuple::validate_unsigned(call, info, len)?); )* ); - Ok(valid) + Ok(ValidTransaction::default()) } + /// Do any pre-flight stuff for an unsigned transaction. + /// + /// Note this function by default delegates to `validate_unsigned`, so that + /// all checks performed for the transaction queue are also performed during + /// the dispatch phase (applying the extrinsic). + /// + /// If you ever override this function, you need not perform the same validation as in + /// `validate_unsigned`. fn pre_dispatch_unsigned( - call: &Self::Call, - info: &DispatchInfoOf, - len: usize, + _call: &Self::Call, + _info: &DispatchInfoOf, + _len: usize, ) -> Result<(), TransactionValidityError> { - for_tuples!( #( Tuple::pre_dispatch_unsigned(call, info, len)?; )* ); Ok(()) } - - fn post_dispatch( - pre: Option, - info: &DispatchInfoOf, - post_info: &PostDispatchInfoOf, - len: usize, - result: &DispatchResult, - ) -> Result<(), TransactionValidityError> { - match pre { - Some(x) => { - for_tuples!( #( Tuple::post_dispatch(Some(x.Tuple), info, post_info, len, result)?; )* ); - }, - None => { - for_tuples!( #( Tuple::post_dispatch(None, info, post_info, len, result)?; )* ); - }, - } - Ok(()) - } - - fn metadata() -> Vec { - let mut ids = Vec::new(); - for_tuples!( #( ids.extend(Tuple::metadata()); )* ); - ids - } -} - -impl SignedExtension for () { - type AccountId = u64; - type AdditionalSigned = (); - type Call = (); - type Pre = (); - const IDENTIFIER: &'static str = "UnitSignedExtension"; - fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { - Ok(()) - } - fn pre_dispatch( - self, - who: &Self::AccountId, - call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> Result { - self.validate(who, call, info, len).map(|_| ()) - } } /// An "executable" piece of information, used by the standard Substrate Executive in order to @@ -1762,6 +1713,7 @@ pub trait GetNodeBlockType { /// function is called right before dispatching the call wrapped by an unsigned extrinsic. The /// [`validate_unsigned`](Self::validate_unsigned) function is mainly being used in the context of /// the transaction pool to check the validity of the call wrapped by an unsigned extrinsic. +// TODO: Rename to ValidateBareTransaction (or just remove). pub trait ValidateUnsigned { /// The call to validate type Call; diff --git a/substrate/primitives/runtime/src/traits/transaction_extension/as_transaction_extension.rs b/substrate/primitives/runtime/src/traits/transaction_extension/as_transaction_extension.rs new file mode 100644 index 00000000000..a834e88c0b4 --- /dev/null +++ b/substrate/primitives/runtime/src/traits/transaction_extension/as_transaction_extension.rs @@ -0,0 +1,133 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! The [AsTransactionExtension] adapter struct for adapting [SignedExtension]s to +//! [TransactionExtension]s. + +#![allow(deprecated)] + +use scale_info::TypeInfo; +use sp_core::RuntimeDebug; + +use crate::{ + traits::{AsSystemOriginSigner, SignedExtension, ValidateResult}, + InvalidTransaction, +}; + +use super::*; + +/// Adapter to use a `SignedExtension` in the place of a `TransactionExtension`. +#[derive(TypeInfo, Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] +#[deprecated = "Convert your SignedExtension to a TransactionExtension."] +pub struct AsTransactionExtension(pub SE); + +impl Default for AsTransactionExtension { + fn default() -> Self { + Self(SE::default()) + } +} + +impl From for AsTransactionExtension { + fn from(value: SE) -> Self { + Self(value) + } +} + +impl TransactionExtensionBase for AsTransactionExtension { + const IDENTIFIER: &'static str = SE::IDENTIFIER; + type Implicit = SE::AdditionalSigned; + + fn implicit(&self) -> Result { + self.0.additional_signed() + } + fn metadata() -> Vec { + SE::metadata() + } +} + +impl TransactionExtension + for AsTransactionExtension +where + ::RuntimeOrigin: AsSystemOriginSigner + Clone, +{ + type Val = (); + type Pre = SE::Pre; + + fn validate( + &self, + origin: ::RuntimeOrigin, + call: &SE::Call, + info: &DispatchInfoOf, + len: usize, + _context: &mut Context, + _self_implicit: Self::Implicit, + _inherited_implication: &impl Encode, + ) -> ValidateResult { + let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?; + let r = self.0.validate(who, call, info, len)?; + Ok((r, (), origin)) + } + + fn prepare( + self, + _: (), + origin: &::RuntimeOrigin, + call: &SE::Call, + info: &DispatchInfoOf, + len: usize, + _context: &Context, + ) -> Result { + let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?; + self.0.pre_dispatch(who, call, info, len) + } + + fn post_dispatch( + pre: Self::Pre, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, + len: usize, + result: &DispatchResult, + _context: &Context, + ) -> Result<(), TransactionValidityError> { + SE::post_dispatch(Some(pre), info, post_info, len, result) + } + + fn validate_bare_compat( + call: &SE::Call, + info: &DispatchInfoOf, + len: usize, + ) -> TransactionValidity { + SE::validate_unsigned(call, info, len) + } + + fn pre_dispatch_bare_compat( + call: &SE::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result<(), TransactionValidityError> { + SE::pre_dispatch_unsigned(call, info, len) + } + + fn post_dispatch_bare_compat( + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, + len: usize, + result: &DispatchResult, + ) -> Result<(), TransactionValidityError> { + SE::post_dispatch(None, info, post_info, len, result) + } +} diff --git a/substrate/primitives/runtime/src/traits/transaction_extension/dispatch_transaction.rs b/substrate/primitives/runtime/src/traits/transaction_extension/dispatch_transaction.rs new file mode 100644 index 00000000000..8efa586aa0e --- /dev/null +++ b/substrate/primitives/runtime/src/traits/transaction_extension/dispatch_transaction.rs @@ -0,0 +1,141 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! The [DispatchTransaction] trait. + +use super::*; + +/// Single-function utility trait with a blanket impl over [TransactionExtension] in order to +/// provide transaction dispatching functionality. We avoid implementing this directly on the trait +/// since we never want it to be overriden by the trait implementation. +pub trait DispatchTransaction { + /// The origin type of the transaction. + type Origin; + /// The info type. + type Info; + /// The resultant type. + type Result; + /// The `Val` of the extension. + type Val; + /// The `Pre` of the extension. + type Pre; + /// Just validate a transaction. + /// + /// The is basically the same as [validate](TransactionExtension::validate), except that there + /// is no need to supply the bond data. + fn validate_only( + &self, + origin: Self::Origin, + call: &Call, + info: &Self::Info, + len: usize, + ) -> Result<(ValidTransaction, Self::Val, Self::Origin), TransactionValidityError>; + /// Prepare and validate a transaction, ready for dispatch. + fn validate_and_prepare( + self, + origin: Self::Origin, + call: &Call, + info: &Self::Info, + len: usize, + ) -> Result<(Self::Pre, Self::Origin), TransactionValidityError>; + /// Dispatch a transaction with the given base origin and call. + fn dispatch_transaction( + self, + origin: Self::Origin, + call: Call, + info: &Self::Info, + len: usize, + ) -> Self::Result; + /// Do everything which would be done in a [dispatch_transaction](Self::dispatch_transaction), + /// but instead of executing the call, execute `substitute` instead. Since this doesn't actually + /// dispatch the call, it doesn't need to consume it and so `call` can be passed as a reference. + fn test_run( + self, + origin: Self::Origin, + call: &Call, + info: &Self::Info, + len: usize, + substitute: impl FnOnce( + Self::Origin, + ) -> crate::DispatchResultWithInfo<::PostInfo>, + ) -> Self::Result; +} + +impl, Call: Dispatchable + Encode> DispatchTransaction + for T +{ + type Origin = ::RuntimeOrigin; + type Info = DispatchInfoOf; + type Result = crate::ApplyExtrinsicResultWithInfo>; + type Val = T::Val; + type Pre = T::Pre; + + fn validate_only( + &self, + origin: Self::Origin, + call: &Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result<(ValidTransaction, T::Val, Self::Origin), TransactionValidityError> { + self.validate(origin, call, info, len, &mut (), self.implicit()?, call) + } + fn validate_and_prepare( + self, + origin: Self::Origin, + call: &Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result<(T::Pre, Self::Origin), TransactionValidityError> { + let (_, val, origin) = self.validate_only(origin, call, info, len)?; + let pre = self.prepare(val, &origin, &call, info, len, &())?; + Ok((pre, origin)) + } + fn dispatch_transaction( + self, + origin: ::RuntimeOrigin, + call: Call, + info: &DispatchInfoOf, + len: usize, + ) -> Self::Result { + let (pre, origin) = self.validate_and_prepare(origin, &call, info, len)?; + let res = call.dispatch(origin); + let post_info = res.unwrap_or_else(|err| err.post_info); + let pd_res = res.map(|_| ()).map_err(|e| e.error); + T::post_dispatch(pre, info, &post_info, len, &pd_res, &())?; + Ok(res) + } + fn test_run( + self, + origin: Self::Origin, + call: &Call, + info: &Self::Info, + len: usize, + substitute: impl FnOnce( + Self::Origin, + ) -> crate::DispatchResultWithInfo<::PostInfo>, + ) -> Self::Result { + let (pre, origin) = self.validate_and_prepare(origin, &call, info, len)?; + let res = substitute(origin); + let post_info = match res { + Ok(info) => info, + Err(err) => err.post_info, + }; + let pd_res = res.map(|_| ()).map_err(|e| e.error); + T::post_dispatch(pre, info, &post_info, len, &pd_res, &())?; + Ok(res) + } +} diff --git a/substrate/primitives/runtime/src/traits/transaction_extension/mod.rs b/substrate/primitives/runtime/src/traits/transaction_extension/mod.rs new file mode 100644 index 00000000000..69a0ba18adb --- /dev/null +++ b/substrate/primitives/runtime/src/traits/transaction_extension/mod.rs @@ -0,0 +1,526 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! The transaction extension trait. + +use crate::{ + scale_info::{MetaType, StaticTypeInfo}, + transaction_validity::{TransactionValidity, TransactionValidityError, ValidTransaction}, + DispatchResult, +}; +use codec::{Codec, Decode, Encode}; +use impl_trait_for_tuples::impl_for_tuples; +#[doc(hidden)] +pub use sp_std::marker::PhantomData; +use sp_std::{self, fmt::Debug, prelude::*}; +use sp_weights::Weight; +use tuplex::{PopFront, PushBack}; + +use super::{DispatchInfoOf, Dispatchable, OriginOf, PostDispatchInfoOf}; + +mod as_transaction_extension; +mod dispatch_transaction; +#[allow(deprecated)] +pub use as_transaction_extension::AsTransactionExtension; +pub use dispatch_transaction::DispatchTransaction; + +/// Shortcut for the result value of the `validate` function. +pub type ValidateResult = + Result<(ValidTransaction, Val, OriginOf), TransactionValidityError>; + +/// Simple blanket implementation trait to denote the bounds of a type which can be contained within +/// a [`TransactionExtension`]. +pub trait TransactionExtensionInterior: + Codec + Debug + Sync + Send + Clone + Eq + PartialEq + StaticTypeInfo +{ +} +impl + TransactionExtensionInterior for T +{ +} + +/// Base for [TransactionExtension]s; this contains the associated types and does not require any +/// generic parameterization. +pub trait TransactionExtensionBase: TransactionExtensionInterior { + /// Unique identifier of this signed extension. + /// + /// This will be exposed in the metadata to identify the signed extension used in an extrinsic. + const IDENTIFIER: &'static str; + + /// Any additional data which was known at the time of transaction construction and can be + /// useful in authenticating the transaction. This is determined dynamically in part from the + /// on-chain environment using the `implicit` function and not directly contained in the + /// transaction itself and therefore is considered "implicit". + type Implicit: Codec + StaticTypeInfo; + + /// Determine any additional data which was known at the time of transaction construction and + /// can be useful in authenticating the transaction. The expected usage of this is to include in + /// any data which is signed and verified as part of transactiob validation. Also perform any + /// pre-signature-verification checks and return an error if needed. + fn implicit(&self) -> Result { + use crate::InvalidTransaction::IndeterminateImplicit; + Ok(Self::Implicit::decode(&mut &[][..]).map_err(|_| IndeterminateImplicit)?) + } + + /// The weight consumed by executing this extension instance fully during transaction dispatch. + fn weight(&self) -> Weight { + Weight::zero() + } + + /// Returns the metadata for this extension. + /// + /// As a [`TransactionExtension`] can be a tuple of [`TransactionExtension`]s we need to return + /// a `Vec` that holds the metadata of each one. Each individual `TransactionExtension` must + /// return *exactly* one [`TransactionExtensionMetadata`]. + /// + /// This method provides a default implementation that returns a vec containing a single + /// [`TransactionExtensionMetadata`]. + fn metadata() -> Vec { + sp_std::vec![TransactionExtensionMetadata { + identifier: Self::IDENTIFIER, + ty: scale_info::meta_type::(), + // TODO: Metadata-v16: Rename to "implicit" + additional_signed: scale_info::meta_type::() + }] + } +} + +/// Means by which a transaction may be extended. This type embodies both the data and the logic +/// that should be additionally associated with the transaction. It should be plain old data. +/// +/// The simplest transaction extension would be the Unit type (and empty pipeline) `()`. This +/// executes no additional logic and implies a dispatch of the transaction's call using the +/// inherited origin (either `None` or `Signed`, depending on whether this is a signed or general +/// transaction). +/// +/// Transaction extensions are capable of altering certain associated semantics: +/// +/// - They may define the origin with which the transaction's call should be dispatched. +/// - They may define various parameters used by the transction queue to determine under what +/// conditions the transaction should be retained and introduced on-chain. +/// - They may define whether this transaction is acceptable for introduction on-chain at all. +/// +/// Each of these semantics are defined by the `validate` function. +/// +/// **NOTE: Transaction extensions cannot under any circumctances alter the call itself.** +/// +/// Transaction extensions are capable of defining logic which is executed additionally to the +/// dispatch of the call: +/// +/// - They may define logic which must be executed prior to the dispatch of the call. +/// - They may also define logic which must be executed after the dispatch of the call. +/// +/// Each of these semantics are defined by the `prepare` and `post_dispatch` functions respectively. +/// +/// Finally, transaction extensions may define additional data to help define the implications of +/// the logic they introduce. This additional data may be explicitly defined by the transaction +/// author (in which case it is included as part of the transaction body), or it may be implicitly +/// defined by the transaction extension based around the on-chain state (which the transaction +/// author is assumed to know). This data may be utilized by the above logic to alter how a node's +/// transaction queue treats this transaction. +/// +/// ## Default implementations +/// +/// Of the 5 functions in this trait, 3 of them must return a value of an associated type on +/// success, and none of these types implement [Default] or anything like it. This means that +/// default implementations cannot be provided for these functions. However, a macro is provided +/// [impl_tx_ext_default](crate::impl_tx_ext_default) which is capable of generating default +/// implementations for each of these 3 functions. If you do not wish to introduce additional logic +/// into the transaction pipeline, then it is recommended that you use this macro to implement these +/// functions. +/// +/// ## Pipelines, Inherited Implications, and Authorized Origins +/// +/// Requiring a single transaction extension to define all of the above semantics would be +/// cumbersome and would lead to a lot of boilerplate. Instead, transaction extensions are +/// aggregated into pipelines, which are tuples of transaction extensions. Each extension in the +/// pipeline is executed in order, and the output of each extension is aggregated and/or relayed as +/// the input to the next extension in the pipeline. +/// +/// This ordered composition happens with all datatypes ([Val](TransactionExtension::Val), +/// [Pre](TransactionExtension::Pre) and [Implicit](TransactionExtensionBase::Implicit)) as well as +/// all functions. There are important consequences stemming from how the composition affects the +/// meaning of the `origin` and `implication` parameters as well as the results. Whereas the +/// [prepare](TransactionExtension::prepare) and +/// [post_dispatch](TransactionExtension::post_dispatch) functions are clear in their meaning, the +/// [validate](TransactionExtension::validate) function is fairly sophisticated and warrants +/// further explanation. +/// +/// Firstly, the `origin` parameter. The `origin` passed into the first item in a pipeline is simply +/// that passed into the tuple itself. It represents an authority who has authorized the implication +/// of the transaction, as of the extension it has been passed into *and any further extensions it +/// may pass though, all the way to, and including, the transaction's dispatch call itself. Each +/// following item in the pipeline is passed the origin which the previous item returned. The origin +/// returned from the final item in the pipeline is the origin which is returned by the tuple +/// itself. +/// +/// This means that if a constituent extension returns a different origin to the one it was called +/// with, then (assuming no other extension changes it further) *this new origin will be used for +/// all extensions following it in the pipeline, and will be returned from the pipeline to be used +/// as the origin for the call's dispatch*. The call itself as well as all these extensions +/// following may each imply consequence for this origin. We call this the *inherited implication*. +/// +/// The *inherited implication* is the cumulated on-chain effects born by whatever origin is +/// returned. It is expressed to the [validate](TransactionExtension::validate) function only as the +/// `implication` argument which implements the [Encode] trait. A transaction extension may define +/// its own implications through its own fields and the +/// [implicit](TransactionExtensionBase::implicit) function. This is only utilized by extensions +/// which preceed it in a pipeline or, if the transaction is an old-school signed trasnaction, the +/// underlying transaction verification logic. +/// +/// **The inherited implication passed as the `implication` parameter to +/// [validate](TransactionExtension::validate) does not include the extension's inner data itself +/// nor does it include the result of the extension's `implicit` function.** If you both provide an +/// implication and rely on the implication, then you need to manually aggregate your extensions +/// implication with the aggregated implication passed in. +pub trait TransactionExtension: TransactionExtensionBase { + /// The type that encodes information that can be passed from validate to prepare. + type Val; + + /// The type that encodes information that can be passed from prepare to post-dispatch. + type Pre; + + /// Validate a transaction for the transaction queue. + /// + /// This function can be called frequently by the transaction queue to obtain transaction + /// validity against current state. It should perform all checks that determine a valid + /// transaction, that can pay for its execution and quickly eliminate ones that are stale or + /// incorrect. + /// + /// Parameters: + /// - `origin`: The origin of the transaction which this extension inherited; coming from an + /// "old-school" *signed transaction*, this will be a system `RawOrigin::Signed` value. If the + /// transaction is a "new-school" *General Transaction*, then this will be a system + /// `RawOrigin::None` value. If this extension is an item in a composite, then it could be + /// anything which was previously returned as an `origin` value in the result of a `validate` + /// call. + /// - `call`: The `Call` wrapped by this extension. + /// - `info`: Information concerning, and inherent to, the transaction's call. + /// - `len`: The total length of the encoded transaction. + /// - `inherited_implication`: The *implication* which this extension inherits. This is a tuple + /// of the transaction's call and some additional opaque-but-encodable data. Coming directly + /// from a transaction, the latter is [()]. However, if this extension is expressed as part of + /// a composite type, then the latter component is equal to any further implications to which + /// the returned `origin` could potentially apply. See Pipelines, Inherited Implications, and + /// Authorized Origins for more information. + /// - `context`: Some opaque mutable context, as yet unused. + /// + /// Returns a [ValidateResult], which is a [Result] whose success type is a tuple of + /// [ValidTransaction] (defining useful metadata for the transaction queue), the [Self::Val] + /// token of this transaction, which gets passed into [prepare](TransactionExtension::prepare), + /// and the origin of the transaction, which gets passed into + /// [prepare](TransactionExtension::prepare) and is ultimately used for dispatch. + fn validate( + &self, + origin: OriginOf, + call: &Call, + info: &DispatchInfoOf, + len: usize, + context: &mut Context, + self_implicit: Self::Implicit, + inherited_implication: &impl Encode, + ) -> ValidateResult; + + /// Do any pre-flight stuff for a transaction after validation. + /// + /// This is for actions which do not happen in the transaction queue but only immediately prior + /// to the point of dispatch on-chain. This should not return an error, since errors should + /// already have been identified during the [validate](TransactionExtension::validate) call. If + /// an error is returned, the transaction will be considered invalid but no state changes will + /// happen and therefore work done in [validate](TransactionExtension::validate) will not be + /// paid for. + /// + /// Unlike `validate`, this function may consume `self`. + /// + /// Parameters: + /// - `val`: `Self::Val` returned by the result of the `validate` call. + /// - `origin`: The origin returned by the result of the `validate` call. + /// - `call`: The `Call` wrapped by this extension. + /// - `info`: Information concerning, and inherent to, the transaction's call. + /// - `len`: The total length of the encoded transaction. + /// - `context`: Some opaque mutable context, as yet unused. + /// + /// Returns a [Self::Pre] value on success, which gets passed into + /// [post_dispatch](TransactionExtension::post_dispatch) and after the call is dispatched. + /// + /// IMPORTANT: **Checks made in validation need not be repeated here.** + fn prepare( + self, + val: Self::Val, + origin: &OriginOf, + call: &Call, + info: &DispatchInfoOf, + len: usize, + context: &Context, + ) -> Result; + + /// Do any post-flight stuff for an extrinsic. + /// + /// `_pre` contains the output of `prepare`. + /// + /// This gets given the `DispatchResult` `_result` from the extrinsic and can, if desired, + /// introduce a `TransactionValidityError`, causing the block to become invalid for including + /// it. + /// + /// Parameters: + /// - `pre`: `Self::Pre` returned by the result of the `prepare` call prior to dispatch. + /// - `info`: Information concerning, and inherent to, the transaction's call. + /// - `post_info`: Information concerning the dispatch of the transaction's call. + /// - `len`: The total length of the encoded transaction. + /// - `result`: The result of the dispatch. + /// - `context`: Some opaque mutable context, as yet unused. + /// + /// WARNING: It is dangerous to return an error here. To do so will fundamentally invalidate the + /// transaction and any block that it is included in, causing the block author to not be + /// compensated for their work in validating the transaction or producing the block so far. It + /// can only be used safely when you *know* that the transaction is one that would only be + /// introduced by the current block author. + fn post_dispatch( + _pre: Self::Pre, + _info: &DispatchInfoOf, + _post_info: &PostDispatchInfoOf, + _len: usize, + _result: &DispatchResult, + _context: &Context, + ) -> Result<(), TransactionValidityError> { + Ok(()) + } + + /// Compatibility function for supporting the `SignedExtension::validate_unsigned` function. + /// + /// DO NOT USE! THIS MAY BE REMOVED AT ANY TIME! + #[deprecated = "Only for compatibility. DO NOT USE."] + fn validate_bare_compat( + _call: &Call, + _info: &DispatchInfoOf, + _len: usize, + ) -> TransactionValidity { + Ok(ValidTransaction::default()) + } + + /// Compatibility function for supporting the `SignedExtension::pre_dispatch_unsigned` function. + /// + /// DO NOT USE! THIS MAY BE REMOVED AT ANY TIME! + #[deprecated = "Only for compatibility. DO NOT USE."] + fn pre_dispatch_bare_compat( + _call: &Call, + _info: &DispatchInfoOf, + _len: usize, + ) -> Result<(), TransactionValidityError> { + Ok(()) + } + + /// Compatibility function for supporting the `SignedExtension::post_dispatch` function where + /// `pre` is `None`. + /// + /// DO NOT USE! THIS MAY BE REMOVED AT ANY TIME! + #[deprecated = "Only for compatibility. DO NOT USE."] + fn post_dispatch_bare_compat( + _info: &DispatchInfoOf, + _post_info: &PostDispatchInfoOf, + _len: usize, + _result: &DispatchResult, + ) -> Result<(), TransactionValidityError> { + Ok(()) + } +} + +/// Implict +#[macro_export] +macro_rules! impl_tx_ext_default { + ($call:ty ; $context:ty ; , $( $rest:tt )*) => { + impl_tx_ext_default!{$call ; $context ; $( $rest )*} + }; + ($call:ty ; $context:ty ; validate $( $rest:tt )*) => { + fn validate( + &self, + origin: $crate::traits::OriginOf<$call>, + _call: &$call, + _info: &$crate::traits::DispatchInfoOf<$call>, + _len: usize, + _context: &mut $context, + _self_implicit: Self::Implicit, + _inherited_implication: &impl $crate::codec::Encode, + ) -> $crate::traits::ValidateResult { + Ok((Default::default(), Default::default(), origin)) + } + impl_tx_ext_default!{$call ; $context ; $( $rest )*} + }; + ($call:ty ; $context:ty ; prepare $( $rest:tt )*) => { + fn prepare( + self, + _val: Self::Val, + _origin: &$crate::traits::OriginOf<$call>, + _call: &$call, + _info: &$crate::traits::DispatchInfoOf<$call>, + _len: usize, + _context: & $context, + ) -> Result { + Ok(Default::default()) + } + impl_tx_ext_default!{$call ; $context ; $( $rest )*} + }; + ($call:ty ; $context:ty ;) => {}; +} + +/// Information about a [`TransactionExtension`] for the runtime metadata. +pub struct TransactionExtensionMetadata { + /// The unique identifier of the [`TransactionExtension`]. + pub identifier: &'static str, + /// The type of the [`TransactionExtension`]. + pub ty: MetaType, + /// The type of the [`TransactionExtension`] additional signed data for the payload. + // TODO: Rename "implicit" + pub additional_signed: MetaType, +} + +#[impl_for_tuples(1, 12)] +impl TransactionExtensionBase for Tuple { + for_tuples!( where #( Tuple: TransactionExtensionBase )* ); + const IDENTIFIER: &'static str = "Use `metadata()`!"; + for_tuples!( type Implicit = ( #( Tuple::Implicit ),* ); ); + fn implicit(&self) -> Result { + Ok(for_tuples!( ( #( Tuple.implicit()? ),* ) )) + } + fn weight(&self) -> Weight { + let mut weight = Weight::zero(); + for_tuples!( #( weight += Tuple.weight(); )* ); + weight + } + fn metadata() -> Vec { + let mut ids = Vec::new(); + for_tuples!( #( ids.extend(Tuple::metadata()); )* ); + ids + } +} + +#[impl_for_tuples(1, 12)] +impl TransactionExtension for Tuple { + for_tuples!( where #( Tuple: TransactionExtension )* ); + for_tuples!( type Val = ( #( Tuple::Val ),* ); ); + for_tuples!( type Pre = ( #( Tuple::Pre ),* ); ); + + fn validate( + &self, + origin: ::RuntimeOrigin, + call: &Call, + info: &DispatchInfoOf, + len: usize, + context: &mut Context, + self_implicit: Self::Implicit, + inherited_implication: &impl Encode, + ) -> Result< + (ValidTransaction, Self::Val, ::RuntimeOrigin), + TransactionValidityError, + > { + let valid = ValidTransaction::default(); + let val = (); + let following_explicit_implications = for_tuples!( ( #( &self.Tuple ),* ) ); + let following_implicit_implications = self_implicit; + + for_tuples!(#( + // Implication of this pipeline element not relevant for later items, so we pop it. + let (_item, following_explicit_implications) = following_explicit_implications.pop_front(); + let (item_implicit, following_implicit_implications) = following_implicit_implications.pop_front(); + let (item_valid, item_val, origin) = { + let implications = ( + // The first is the implications born of the fact we return the mutated + // origin. + inherited_implication, + // This is the explicitly made implication born of the fact the new origin is + // passed into the next items in this pipeline-tuple. + &following_explicit_implications, + // This is the implicitly made implication born of the fact the new origin is + // passed into the next items in this pipeline-tuple. + &following_implicit_implications, + ); + Tuple.validate(origin, call, info, len, context, item_implicit, &implications)? + }; + let valid = valid.combine_with(item_valid); + let val = val.push_back(item_val); + )* ); + Ok((valid, val, origin)) + } + + fn prepare( + self, + val: Self::Val, + origin: &::RuntimeOrigin, + call: &Call, + info: &DispatchInfoOf, + len: usize, + context: &Context, + ) -> Result { + Ok(for_tuples!( ( #( + Tuple::prepare(self.Tuple, val.Tuple, origin, call, info, len, context)? + ),* ) )) + } + + fn post_dispatch( + pre: Self::Pre, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, + len: usize, + result: &DispatchResult, + context: &Context, + ) -> Result<(), TransactionValidityError> { + for_tuples!( #( Tuple::post_dispatch(pre.Tuple, info, post_info, len, result, context)?; )* ); + Ok(()) + } +} + +impl TransactionExtensionBase for () { + const IDENTIFIER: &'static str = "UnitTransactionExtension"; + type Implicit = (); + fn implicit(&self) -> sp_std::result::Result { + Ok(()) + } + fn weight(&self) -> Weight { + Weight::zero() + } +} + +impl TransactionExtension for () { + type Val = (); + type Pre = (); + fn validate( + &self, + origin: ::RuntimeOrigin, + _call: &Call, + _info: &DispatchInfoOf, + _len: usize, + _context: &mut Context, + _self_implicit: Self::Implicit, + _inherited_implication: &impl Encode, + ) -> Result< + (ValidTransaction, (), ::RuntimeOrigin), + TransactionValidityError, + > { + Ok((ValidTransaction::default(), (), origin)) + } + fn prepare( + self, + _val: (), + _origin: &::RuntimeOrigin, + _call: &Call, + _info: &DispatchInfoOf, + _len: usize, + _context: &Context, + ) -> Result<(), TransactionValidityError> { + Ok(()) + } +} diff --git a/substrate/primitives/runtime/src/transaction_validity.rs b/substrate/primitives/runtime/src/transaction_validity.rs index 83694849382..24124128083 100644 --- a/substrate/primitives/runtime/src/transaction_validity.rs +++ b/substrate/primitives/runtime/src/transaction_validity.rs @@ -82,6 +82,8 @@ pub enum InvalidTransaction { MandatoryValidation, /// The sending address is disabled or known to be invalid. BadSigner, + /// The implicit data was unable to be calculated. + IndeterminateImplicit, } impl InvalidTransaction { @@ -113,6 +115,8 @@ impl From for &'static str { "Transaction dispatch is mandatory; transactions must not be validated.", InvalidTransaction::Custom(_) => "InvalidTransaction custom error", InvalidTransaction::BadSigner => "Invalid signing address", + InvalidTransaction::IndeterminateImplicit => + "The implicit data was unable to be calculated", } } } @@ -338,7 +342,7 @@ pub struct ValidTransactionBuilder { impl ValidTransactionBuilder { /// Set the priority of a transaction. /// - /// Note that the final priority for `FRAME` is combined from all `SignedExtension`s. + /// Note that the final priority for `FRAME` is combined from all `TransactionExtension`s. /// Most likely for unsigned transactions you want the priority to be higher /// than for regular transactions. We recommend exposing a base priority for unsigned /// transactions as a runtime module parameter, so that the runtime can tune inter-module diff --git a/substrate/scripts/run_all_benchmarks.sh b/substrate/scripts/run_all_benchmarks.sh index 6dd7cede319..fe5f89a5b56 100755 --- a/substrate/scripts/run_all_benchmarks.sh +++ b/substrate/scripts/run_all_benchmarks.sh @@ -107,6 +107,19 @@ for PALLET in "${PALLETS[@]}"; do FOLDER="$(echo "${PALLET#*_}" | tr '_' '-')"; WEIGHT_FILE="./frame/${FOLDER}/src/weights.rs" + + # Special handling of custom weight paths. + if [ "$PALLET" == "frame_system_extensions" ] || [ "$PALLET" == "frame-system-extensions" ] + then + WEIGHT_FILE="./frame/system/src/extensions/weights.rs" + elif [ "$PALLET" == "pallet_asset_conversion_tx_payment" ] || [ "$PALLET" == "pallet-asset-conversion-tx-payment" ] + then + WEIGHT_FILE="./frame/transaction-payment/asset-conversion-tx-payment/src/weights.rs" + elif [ "$PALLET" == "pallet_asset_tx_payment" ] || [ "$PALLET" == "pallet-asset-tx-payment" ] + then + WEIGHT_FILE="./frame/transaction-payment/asset-tx-payment/src/weights.rs" + fi + echo "[+] Benchmarking $PALLET with weight file $WEIGHT_FILE"; OUTPUT=$( diff --git a/substrate/test-utils/runtime/src/extrinsic.rs b/substrate/test-utils/runtime/src/extrinsic.rs index 05ffb7db5d5..7eb1839e97b 100644 --- a/substrate/test-utils/runtime/src/extrinsic.rs +++ b/substrate/test-utils/runtime/src/extrinsic.rs @@ -25,7 +25,7 @@ use codec::Encode; use frame_system::{CheckNonce, CheckWeight}; use sp_core::crypto::Pair as TraitPair; use sp_keyring::AccountKeyring; -use sp_runtime::{transaction_validity::TransactionPriority, Perbill}; +use sp_runtime::{generic::Preamble, transaction_validity::TransactionPriority, Perbill}; use sp_std::prelude::*; /// Transfer used in test substrate pallet. Extrinsic is created and signed using this data. @@ -66,11 +66,11 @@ impl TryFrom<&Extrinsic> for TransferData { match uxt { Extrinsic { function: RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest, value }), - signature: Some((from, _, (CheckNonce(nonce), ..))), + preamble: Preamble::Signed(from, _, ((CheckNonce(nonce), ..), ..)), } => Ok(TransferData { from: *from, to: *dest, amount: *value, nonce: *nonce }), Extrinsic { function: RuntimeCall::SubstrateTest(PalletCall::bench_call { transfer }), - signature: None, + preamble: Preamble::Bare, } => Ok(transfer.clone()), _ => Err(()), } @@ -190,18 +190,17 @@ impl ExtrinsicBuilder { /// Build `Extrinsic` using embedded parameters pub fn build(self) -> Extrinsic { if let Some(signer) = self.signer { - let extra = ( - CheckNonce::from(self.nonce.unwrap_or(0)), - CheckWeight::new(), + let tx_ext = ( + (CheckNonce::from(self.nonce.unwrap_or(0)), CheckWeight::new()), CheckSubstrateCall {}, ); let raw_payload = - SignedPayload::from_raw(self.function.clone(), extra.clone(), ((), (), ())); + SignedPayload::from_raw(self.function.clone(), tx_ext.clone(), (((), ()), ())); let signature = raw_payload.using_encoded(|e| signer.sign(e)); - Extrinsic::new_signed(self.function, signer.public(), signature, extra) + Extrinsic::new_signed(self.function, signer.public(), signature, tx_ext) } else { - Extrinsic::new_unsigned(self.function) + Extrinsic::new_bare(self.function) } } } diff --git a/substrate/test-utils/runtime/src/lib.rs b/substrate/test-utils/runtime/src/lib.rs index 63e0aa6e137..7ec5f6722c4 100644 --- a/substrate/test-utils/runtime/src/lib.rs +++ b/substrate/test-utils/runtime/src/lib.rs @@ -58,9 +58,11 @@ use sp_api::{decl_runtime_apis, impl_runtime_apis}; pub use sp_core::hash::H256; use sp_inherents::{CheckInherentsResult, InherentData}; use sp_runtime::{ - create_runtime_str, impl_opaque_keys, - traits::{BlakeTwo256, Block as BlockT, DispatchInfoOf, NumberFor, Verify}, - transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError}, + create_runtime_str, impl_opaque_keys, impl_tx_ext_default, + traits::{BlakeTwo256, Block as BlockT, DispatchInfoOf, Dispatchable, NumberFor, Verify}, + transaction_validity::{ + TransactionSource, TransactionValidity, TransactionValidityError, ValidTransaction, + }, ApplyExtrinsicResult, ExtrinsicInclusionMode, Perbill, }; #[cfg(any(feature = "std", test))] @@ -142,13 +144,14 @@ pub type Signature = sr25519::Signature; #[cfg(feature = "std")] pub type Pair = sp_core::sr25519::Pair; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = (CheckNonce, CheckWeight, CheckSubstrateCall); +// TODO: Remove after the Checks are migrated to TxExtension. +/// The extension to the basic transaction logic. +pub type TxExtension = ((CheckNonce, CheckWeight), CheckSubstrateCall); /// The payload being signed in transactions. -pub type SignedPayload = sp_runtime::generic::SignedPayload; +pub type SignedPayload = sp_runtime::generic::SignedPayload; /// Unchecked extrinsic type as expected by this runtime. pub type Extrinsic = - sp_runtime::generic::UncheckedExtrinsic; + sp_runtime::generic::UncheckedExtrinsic; /// An identifier for an account on this system. pub type AccountId = ::Signer; @@ -243,7 +246,7 @@ impl sp_runtime::traits::Printable for CheckSubstrateCall { } impl sp_runtime::traits::Dispatchable for CheckSubstrateCall { - type RuntimeOrigin = CheckSubstrateCall; + type RuntimeOrigin = RuntimeOrigin; type Config = CheckSubstrateCall; type Info = CheckSubstrateCall; type PostInfo = CheckSubstrateCall; @@ -256,42 +259,37 @@ impl sp_runtime::traits::Dispatchable for CheckSubstrateCall { } } -impl sp_runtime::traits::SignedExtension for CheckSubstrateCall { - type AccountId = AccountId; - type Call = RuntimeCall; - type AdditionalSigned = (); - type Pre = (); +impl sp_runtime::traits::TransactionExtensionBase for CheckSubstrateCall { const IDENTIFIER: &'static str = "CheckSubstrateCall"; - - fn additional_signed( - &self, - ) -> sp_std::result::Result { - Ok(()) - } + type Implicit = (); +} +impl sp_runtime::traits::TransactionExtension + for CheckSubstrateCall +{ + type Pre = (); + type Val = (); + impl_tx_ext_default!(RuntimeCall; Context; prepare); fn validate( &self, - _who: &Self::AccountId, - call: &Self::Call, - _info: &DispatchInfoOf, + origin: ::RuntimeOrigin, + call: &RuntimeCall, + _info: &DispatchInfoOf, _len: usize, - ) -> TransactionValidity { + _context: &mut Context, + _self_implicit: Self::Implicit, + _inherited_implication: &impl Encode, + ) -> Result< + (ValidTransaction, Self::Val, ::RuntimeOrigin), + TransactionValidityError, + > { log::trace!(target: LOG_TARGET, "validate"); - match call { + let v = match call { RuntimeCall::SubstrateTest(ref substrate_test_call) => - substrate_test_pallet::validate_runtime_call(substrate_test_call), - _ => Ok(Default::default()), - } - } - - fn pre_dispatch( - self, - who: &Self::AccountId, - call: &Self::Call, - info: &sp_runtime::traits::DispatchInfoOf, - len: usize, - ) -> Result { - self.validate(who, call, info, len).map(drop) + substrate_test_pallet::validate_runtime_call(substrate_test_call)?, + _ => Default::default(), + }; + Ok((v, (), origin)) } } @@ -364,6 +362,7 @@ impl frame_system::pallet::Config for Runtime { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); + type ExtensionsWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); type MaxConsumers = ConstU32<16>; @@ -672,7 +671,7 @@ impl_runtime_apis! { impl sp_offchain::OffchainWorkerApi for Runtime { fn offchain_worker(header: &::Header) { - let ext = Extrinsic::new_unsigned( + let ext = Extrinsic::new_bare( substrate_test_pallet::pallet::Call::storage_change{ key:b"some_key".encode(), value:Some(header.number.encode()) @@ -1025,7 +1024,7 @@ mod tests { use sp_core::{storage::well_known_keys::HEAP_PAGES, traits::CallContext}; use sp_keyring::AccountKeyring; use sp_runtime::{ - traits::{Hash as _, SignedExtension}, + traits::{DispatchTransaction, Hash as _}, transaction_validity::{InvalidTransaction, ValidTransaction}, }; use substrate_test_runtime_client::{ @@ -1174,31 +1173,33 @@ mod tests { fn check_substrate_check_signed_extension_works() { sp_tracing::try_init_simple(); new_test_ext().execute_with(|| { - let x = sp_keyring::AccountKeyring::Alice.into(); + let x: AccountId = sp_keyring::AccountKeyring::Alice.into(); let info = DispatchInfo::default(); let len = 0_usize; assert_eq!( CheckSubstrateCall {} - .validate( - &x, + .validate_only( + Some(x).into(), &ExtrinsicBuilder::new_call_with_priority(16).build().function, &info, - len + len, ) .unwrap() + .0 .priority, 16 ); assert_eq!( CheckSubstrateCall {} - .validate( - &x, + .validate_only( + Some(x).into(), &ExtrinsicBuilder::new_call_do_not_propagate().build().function, &info, - len + len, ) .unwrap() + .0 .propagate, false ); diff --git a/substrate/utils/frame/benchmarking-cli/src/pallet/template.hbs b/substrate/utils/frame/benchmarking-cli/src/pallet/template.hbs index 1e5e294acba..a044049a0d6 100644 --- a/substrate/utils/frame/benchmarking-cli/src/pallet/template.hbs +++ b/substrate/utils/frame/benchmarking-cli/src/pallet/template.hbs @@ -22,7 +22,11 @@ use core::marker::PhantomData; /// Weight functions for `{{pallet}}`. pub struct WeightInfo(PhantomData); +{{#if (eq pallet "frame_system_extensions")}} +impl frame_system::ExtensionsWeightInfo for WeightInfo { +{{else}} impl {{pallet}}::WeightInfo for WeightInfo { +{{/if}} {{#each benchmarks as |benchmark|}} {{#each benchmark.comments as |comment|}} /// {{comment}} diff --git a/substrate/utils/frame/remote-externalities/src/lib.rs b/substrate/utils/frame/remote-externalities/src/lib.rs index c7399468da9..d49479d9cda 100644 --- a/substrate/utils/frame/remote-externalities/src/lib.rs +++ b/substrate/utils/frame/remote-externalities/src/lib.rs @@ -1204,8 +1204,9 @@ where #[cfg(test)] mod test_prelude { pub(crate) use super::*; - pub(crate) use sp_runtime::testing::{Block as RawBlock, ExtrinsicWrapper, H256 as Hash}; - pub(crate) type Block = RawBlock>; + pub(crate) use sp_runtime::testing::{Block as RawBlock, MockCallU64}; + pub(crate) type UncheckedXt = sp_runtime::generic::UncheckedExtrinsic; + pub(crate) type Block = RawBlock; pub(crate) fn init_logger() { sp_tracing::try_init_simple(); diff --git a/substrate/utils/frame/rpc/client/src/lib.rs b/substrate/utils/frame/rpc/client/src/lib.rs index 221f260b156..4f4f4bbef56 100644 --- a/substrate/utils/frame/rpc/client/src/lib.rs +++ b/substrate/utils/frame/rpc/client/src/lib.rs @@ -199,11 +199,15 @@ where #[cfg(test)] mod tests { use super::*; - use sp_runtime::testing::{Block as TBlock, ExtrinsicWrapper, Header, H256}; + use sp_runtime::{ + generic::UncheckedExtrinsic, + testing::{Block as TBlock, Header, MockCallU64, H256}, + }; use std::sync::Arc; use tokio::sync::Mutex; - type Block = TBlock>; + type UncheckedXt = UncheckedExtrinsic; + type Block = TBlock; type BlockNumber = u64; type Hash = H256; -- GitLab From 0708cf382daec9996c890ab494122196a2c23d4d Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Mon, 4 Mar 2024 21:32:03 +0100 Subject: [PATCH 340/392] Contracts: Fix typo (#3563) --- substrate/frame/contracts/uapi/src/host.rs | 2 +- substrate/frame/contracts/uapi/src/host/riscv32.rs | 2 +- substrate/frame/contracts/uapi/src/host/wasm32.rs | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/substrate/frame/contracts/uapi/src/host.rs b/substrate/frame/contracts/uapi/src/host.rs index c25be4479ce..04f58895ab4 100644 --- a/substrate/frame/contracts/uapi/src/host.rs +++ b/substrate/frame/contracts/uapi/src/host.rs @@ -180,7 +180,7 @@ pub trait HostFn { flags: CallFlags, callee: &[u8], ref_time_limit: u64, - proof_time_limit: u64, + proof_size_limit: u64, deposit: Option<&[u8]>, value: &[u8], input_data: &[u8], diff --git a/substrate/frame/contracts/uapi/src/host/riscv32.rs b/substrate/frame/contracts/uapi/src/host/riscv32.rs index dbd5abc4240..561ab28747d 100644 --- a/substrate/frame/contracts/uapi/src/host/riscv32.rs +++ b/substrate/frame/contracts/uapi/src/host/riscv32.rs @@ -130,7 +130,7 @@ impl HostFn for HostFnImpl { flags: CallFlags, callee: &[u8], ref_time_limit: u64, - proof_time_limit: u64, + proof_size_limit: u64, deposit: Option<&[u8]>, value: &[u8], input_data: &[u8], diff --git a/substrate/frame/contracts/uapi/src/host/wasm32.rs b/substrate/frame/contracts/uapi/src/host/wasm32.rs index 9651aa73d6f..17c0fd341b5 100644 --- a/substrate/frame/contracts/uapi/src/host/wasm32.rs +++ b/substrate/frame/contracts/uapi/src/host/wasm32.rs @@ -223,7 +223,7 @@ mod sys { pub fn weight_to_fee( ref_time_limit: u64, - proof_time_limit: u64, + proof_size_limit: u64, output_ptr: *mut u8, output_len_ptr: *mut u32, ); @@ -239,7 +239,7 @@ mod sys { flags: u32, callee_ptr: *const u8, ref_time_limit: u64, - proof_time_limit: u64, + proof_size_limit: u64, deposit_ptr: *const u8, transferred_value_ptr: *const u8, input_data_ptr: *const u8, @@ -251,7 +251,7 @@ mod sys { pub fn instantiate( code_hash_ptr: *const u8, ref_time_limit: u64, - proof_time_limit: u64, + proof_size_limit: u64, deposit_ptr: *const u8, value_ptr: *const u8, input_ptr: *const u8, @@ -487,7 +487,7 @@ impl HostFn for HostFnImpl { flags: CallFlags, callee: &[u8], ref_time_limit: u64, - proof_time_limit: u64, + proof_size_limit: u64, deposit: Option<&[u8]>, value: &[u8], input_data: &[u8], @@ -501,7 +501,7 @@ impl HostFn for HostFnImpl { flags.bits(), callee.as_ptr(), ref_time_limit, - proof_time_limit, + proof_size_limit, deposit_ptr, value.as_ptr(), input_data.as_ptr(), -- GitLab From ec30d2f5da839a7fb3f34778013c63e5afc9e90f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 22:41:26 +0000 Subject: [PATCH 341/392] Bump mio from 0.8.8 to 0.8.11 (#3569) Bumps [mio](https://github.com/tokio-rs/mio) from 0.8.8 to 0.8.11.
Changelog

Sourced from mio's changelog.

0.8.11

0.8.10

Added

0.8.9

Added

Fixed

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=mio&package-manager=cargo&previous-version=0.8.8&new-version=0.8.11)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/paritytech/polkadot-sdk/network/alerts).
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 81881984378..9ee48f33074 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8234,9 +8234,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "wasi 0.11.0+wasi-snapshot-preview1", -- GitLab From c34ad77d0524add1ef7cec3de72df7874c67f8a9 Mon Sep 17 00:00:00 2001 From: Nazar Mokrynskyi Date: Tue, 5 Mar 2024 09:47:10 +0200 Subject: [PATCH 342/392] Remove useless Result import (#3534) Latest Rust nightly complains with `the item `Result` is imported redundantly` Co-authored-by: Sebastian Kunert Co-authored-by: Liam Aharon --- substrate/primitives/consensus/babe/src/inherents.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/substrate/primitives/consensus/babe/src/inherents.rs b/substrate/primitives/consensus/babe/src/inherents.rs index 909769f3031..54b7b644016 100644 --- a/substrate/primitives/consensus/babe/src/inherents.rs +++ b/substrate/primitives/consensus/babe/src/inherents.rs @@ -17,7 +17,6 @@ //! Inherents for BABE -use core::result::Result; use sp_inherents::{Error, InherentData, InherentIdentifier}; /// The BABE inherent identifier. -- GitLab From 0eda0b3f175338a22e263489320fe2280875711b Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Tue, 5 Mar 2024 10:47:42 +0100 Subject: [PATCH 343/392] Contracts call extract_from_slice in macro (#3566) --- substrate/frame/contracts/uapi/src/host/wasm32.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/substrate/frame/contracts/uapi/src/host/wasm32.rs b/substrate/frame/contracts/uapi/src/host/wasm32.rs index 17c0fd341b5..bc697238061 100644 --- a/substrate/frame/contracts/uapi/src/host/wasm32.rs +++ b/substrate/frame/contracts/uapi/src/host/wasm32.rs @@ -301,6 +301,7 @@ macro_rules! impl_wrapper_for { unsafe { $( $mod )::*::$name(output.as_mut_ptr(), &mut output_len); } + extract_from_slice(output, output_len as usize) } } }; -- GitLab From efcea0edab085f036b1e0033781f5f39a73b7904 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Tue, 5 Mar 2024 10:50:57 +0100 Subject: [PATCH 344/392] rpc server: add prometheus label `is_rate_limited` (#3504) After some discussion with @kogeler after the we added the rate-limit middleware it may slow down the rpc call timings metrics significantly because it works as follows: 1. The rate limit guard is checked when the call comes and if a slot is available -> process the call 2. If no free spot is available then the call will be sleeping `jitter_delay + min_time_rate_guard` then woken up and checked at most ten times 3. If no spot is available after 10 iterations -> the call is rejected (this may take tens of seconds) Thus, this PR adds a label "is_rate_limited" to filter those out on the metrics "substrate_rpc_calls_time" and "substrate_rpc_calls_finished". I had to merge two middleware layers Metrics and RateLimit to avoid shared state in a hacky way. --------- Co-authored-by: James Wilson --- Cargo.lock | 1 - prdoc/pr_3504.prdoc | 13 ++ substrate/client/rpc-servers/Cargo.toml | 1 - substrate/client/rpc-servers/src/lib.rs | 25 ++- .../rpc-servers/src/middleware/metrics.rs | 196 +++++++----------- .../client/rpc-servers/src/middleware/mod.rs | 129 +++++++++++- .../rpc-servers/src/middleware/rate_limit.rs | 86 ++------ 7 files changed, 239 insertions(+), 212 deletions(-) create mode 100644 prdoc/pr_3504.prdoc diff --git a/Cargo.lock b/Cargo.lock index 9ee48f33074..d262c1795a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16745,7 +16745,6 @@ dependencies = [ "hyper", "jsonrpsee", "log", - "pin-project", "serde_json", "substrate-prometheus-endpoint", "tokio", diff --git a/prdoc/pr_3504.prdoc b/prdoc/pr_3504.prdoc new file mode 100644 index 00000000000..90a8ddd38b8 --- /dev/null +++ b/prdoc/pr_3504.prdoc @@ -0,0 +1,13 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: add prometheus label "is_rate_limited" to rpc calls + +doc: + - audience: Node Operator + description: | + This PR adds a label "is_rate_limited" to the prometheus metrics "substrate_rpc_calls_time" and "substrate_rpc_calls_finished" + than can be used to distinguish rate-limited RPC calls from other RPC calls. Because rate-limited RPC calls may take + tens of seconds. + +crates: [ ] diff --git a/substrate/client/rpc-servers/Cargo.toml b/substrate/client/rpc-servers/Cargo.toml index 7f7a86799e0..3adc81c57d5 100644 --- a/substrate/client/rpc-servers/Cargo.toml +++ b/substrate/client/rpc-servers/Cargo.toml @@ -26,5 +26,4 @@ tower = { version = "0.4.13", features = ["util"] } http = "0.2.8" hyper = "0.14.27" futures = "0.3.29" -pin-project = "1.1.3" governor = "0.6.0" diff --git a/substrate/client/rpc-servers/src/lib.rs b/substrate/client/rpc-servers/src/lib.rs index e65d954bed5..ad4b444c7ff 100644 --- a/substrate/client/rpc-servers/src/lib.rs +++ b/substrate/client/rpc-servers/src/lib.rs @@ -49,7 +49,7 @@ pub use jsonrpsee::{ }, server::{middleware::rpc::RpcServiceBuilder, BatchRequestConfig}, }; -pub use middleware::{MetricsLayer, RateLimitLayer, RpcMetrics}; +pub use middleware::{Metrics, MiddlewareLayer, RpcMetrics}; const MEGABYTE: u32 = 1024 * 1024; @@ -173,13 +173,22 @@ where let is_websocket = ws::is_upgrade_request(&req); let transport_label = if is_websocket { "ws" } else { "http" }; - let metrics = metrics.map(|m| MetricsLayer::new(m, transport_label)); - let rate_limit = rate_limit.map(|r| RateLimitLayer::per_minute(r)); + let middleware_layer = match (metrics, rate_limit) { + (None, None) => None, + (Some(metrics), None) => Some( + MiddlewareLayer::new().with_metrics(Metrics::new(metrics, transport_label)), + ), + (None, Some(rate_limit)) => + Some(MiddlewareLayer::new().with_rate_limit_per_minute(rate_limit)), + (Some(metrics), Some(rate_limit)) => Some( + MiddlewareLayer::new() + .with_metrics(Metrics::new(metrics, transport_label)) + .with_rate_limit_per_minute(rate_limit), + ), + }; - // NOTE: The metrics needs to run first to include rate-limited calls in the - // metrics. let rpc_middleware = - RpcServiceBuilder::new().option_layer(metrics.clone()).option_layer(rate_limit); + RpcServiceBuilder::new().option_layer(middleware_layer.clone()); let mut svc = service_builder.set_rpc_middleware(rpc_middleware).build(methods, stop_handle); @@ -191,9 +200,9 @@ where // Spawn a task to handle when the connection is closed. tokio_handle.spawn(async move { let now = std::time::Instant::now(); - metrics.as_ref().map(|m| m.ws_connect()); + middleware_layer.as_ref().map(|m| m.ws_connect()); on_disconnect.await; - metrics.as_ref().map(|m| m.ws_disconnect(now)); + middleware_layer.as_ref().map(|m| m.ws_disconnect(now)); }); } diff --git a/substrate/client/rpc-servers/src/middleware/metrics.rs b/substrate/client/rpc-servers/src/middleware/metrics.rs index c2d1956c3b3..17849dc0c44 100644 --- a/substrate/client/rpc-servers/src/middleware/metrics.rs +++ b/substrate/client/rpc-servers/src/middleware/metrics.rs @@ -18,15 +18,9 @@ //! RPC middleware to collect prometheus metrics on RPC calls. -use std::{ - future::Future, - pin::Pin, - task::{Context, Poll}, - time::Instant, -}; +use std::time::Instant; -use jsonrpsee::{server::middleware::rpc::RpcServiceT, types::Request, MethodResponse}; -use pin_project::pin_project; +use jsonrpsee::{types::Request, MethodResponse}; use prometheus_endpoint::{ register, Counter, CounterVec, HistogramOpts, HistogramVec, Opts, PrometheusError, Registry, U64, @@ -77,7 +71,7 @@ impl RpcMetrics { "Total time [μs] of processed RPC calls", ) .buckets(HISTOGRAM_BUCKETS.to_vec()), - &["protocol", "method"], + &["protocol", "method", "is_rate_limited"], )?, metrics_registry, )?, @@ -97,7 +91,7 @@ impl RpcMetrics { "substrate_rpc_calls_finished", "Number of processed RPC calls (unique un-batched requests)", ), - &["protocol", "method", "is_error"], + &["protocol", "method", "is_error", "is_rate_limited"], )?, metrics_registry, )?, @@ -144,138 +138,90 @@ impl RpcMetrics { self.ws_sessions_closed.as_ref().map(|counter| counter.inc()); self.ws_sessions_time.with_label_values(&["ws"]).observe(micros as _); } -} - -/// Metrics layer. -#[derive(Clone)] -pub struct MetricsLayer { - inner: RpcMetrics, - transport_label: &'static str, -} - -impl MetricsLayer { - /// Create a new [`MetricsLayer`]. - pub fn new(metrics: RpcMetrics, transport_label: &'static str) -> Self { - Self { inner: metrics, transport_label } - } - - pub(crate) fn ws_connect(&self) { - self.inner.ws_connect(); - } - - pub(crate) fn ws_disconnect(&self, now: Instant) { - self.inner.ws_disconnect(now) - } -} - -impl tower::Layer for MetricsLayer { - type Service = Metrics; - - fn layer(&self, inner: S) -> Self::Service { - Metrics::new(inner, self.inner.clone(), self.transport_label) - } -} - -/// Metrics middleware. -#[derive(Clone)] -pub struct Metrics { - service: S, - metrics: RpcMetrics, - transport_label: &'static str, -} - -impl Metrics { - /// Create a new metrics middleware. - pub fn new(service: S, metrics: RpcMetrics, transport_label: &'static str) -> Metrics { - Metrics { service, metrics, transport_label } - } -} - -impl<'a, S> RpcServiceT<'a> for Metrics -where - S: Send + Sync + RpcServiceT<'a>, -{ - type Future = ResponseFuture<'a, S::Future>; - - fn call(&self, req: Request<'a>) -> Self::Future { - let now = Instant::now(); + pub(crate) fn on_call(&self, req: &Request, transport_label: &'static str) { log::trace!( target: "rpc_metrics", - "[{}] on_call name={} params={:?}", - self.transport_label, + "[{transport_label}] on_call name={} params={:?}", req.method_name(), req.params(), ); - self.metrics - .calls_started - .with_label_values(&[self.transport_label, req.method_name()]) + + self.calls_started + .with_label_values(&[transport_label, req.method_name()]) .inc(); + } - ResponseFuture { - fut: self.service.call(req.clone()), - metrics: self.metrics.clone(), - req, - now, - transport_label: self.transport_label, - } + pub(crate) fn on_response( + &self, + req: &Request, + rp: &MethodResponse, + is_rate_limited: bool, + transport_label: &'static str, + now: Instant, + ) { + log::trace!(target: "rpc_metrics", "[{transport_label}] on_response started_at={:?}", now); + log::trace!(target: "rpc_metrics::extra", "[{transport_label}] result={}", rp.as_result()); + + let micros = now.elapsed().as_micros(); + log::debug!( + target: "rpc_metrics", + "[{transport_label}] {} call took {} μs", + req.method_name(), + micros, + ); + self.calls_time + .with_label_values(&[ + transport_label, + req.method_name(), + if is_rate_limited { "true" } else { "false" }, + ]) + .observe(micros as _); + self.calls_finished + .with_label_values(&[ + transport_label, + req.method_name(), + // the label "is_error", so `success` should be regarded as false + // and vice-versa to be registrered correctly. + if rp.is_success() { "false" } else { "true" }, + if is_rate_limited { "true" } else { "false" }, + ]) + .inc(); } } -/// Response future for metrics. -#[pin_project] -pub struct ResponseFuture<'a, F> { - #[pin] - fut: F, - metrics: RpcMetrics, - req: Request<'a>, - now: Instant, - transport_label: &'static str, +/// Metrics with transport label. +#[derive(Clone, Debug)] +pub struct Metrics { + pub(crate) inner: RpcMetrics, + pub(crate) transport_label: &'static str, } -impl<'a, F> std::fmt::Debug for ResponseFuture<'a, F> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str("ResponseFuture") +impl Metrics { + /// Create a new [`Metrics`]. + pub fn new(metrics: RpcMetrics, transport_label: &'static str) -> Self { + Self { inner: metrics, transport_label } } -} -impl<'a, F: Future> Future for ResponseFuture<'a, F> { - type Output = F::Output; - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let this = self.project(); + pub(crate) fn ws_connect(&self) { + self.inner.ws_connect(); + } - let res = this.fut.poll(cx); - if let Poll::Ready(rp) = &res { - let method_name = this.req.method_name(); - let transport_label = &this.transport_label; - let now = this.now; - let metrics = &this.metrics; + pub(crate) fn ws_disconnect(&self, now: Instant) { + self.inner.ws_disconnect(now) + } - log::trace!(target: "rpc_metrics", "[{transport_label}] on_response started_at={:?}", now); - log::trace!(target: "rpc_metrics::extra", "[{transport_label}] result={:?}", rp); + pub(crate) fn on_call(&self, req: &Request) { + self.inner.on_call(req, self.transport_label) + } - let micros = now.elapsed().as_micros(); - log::debug!( - target: "rpc_metrics", - "[{transport_label}] {method_name} call took {} μs", - micros, - ); - metrics - .calls_time - .with_label_values(&[transport_label, method_name]) - .observe(micros as _); - metrics - .calls_finished - .with_label_values(&[ - transport_label, - method_name, - // the label "is_error", so `success` should be regarded as false - // and vice-versa to be registrered correctly. - if rp.is_success() { "false" } else { "true" }, - ]) - .inc(); - } - res + pub(crate) fn on_response( + &self, + req: &Request, + rp: &MethodResponse, + is_rate_limited: bool, + now: Instant, + ) { + self.inner.on_response(req, rp, is_rate_limited, self.transport_label, now) } } diff --git a/substrate/client/rpc-servers/src/middleware/mod.rs b/substrate/client/rpc-servers/src/middleware/mod.rs index cac516913d3..88ed8b2f433 100644 --- a/substrate/client/rpc-servers/src/middleware/mod.rs +++ b/substrate/client/rpc-servers/src/middleware/mod.rs @@ -18,10 +18,131 @@ //! JSON-RPC specific middleware. -/// Grafana metrics middleware. -pub mod metrics; -/// Rate limit middleware. -pub mod rate_limit; +use std::{ + num::NonZeroU32, + time::{Duration, Instant}, +}; + +use futures::future::{BoxFuture, FutureExt}; +use governor::{clock::Clock, Jitter}; +use jsonrpsee::{ + server::middleware::rpc::RpcServiceT, + types::{ErrorObject, Id, Request}, + MethodResponse, +}; + +mod metrics; +mod rate_limit; pub use metrics::*; pub use rate_limit::*; + +const MAX_JITTER: Duration = Duration::from_millis(50); +const MAX_RETRIES: usize = 10; + +/// JSON-RPC middleware layer. +#[derive(Debug, Clone, Default)] +pub struct MiddlewareLayer { + rate_limit: Option, + metrics: Option, +} + +impl MiddlewareLayer { + /// Create an empty MiddlewareLayer. + pub fn new() -> Self { + Self::default() + } + + /// Enable new rate limit middleware enforced per minute. + pub fn with_rate_limit_per_minute(self, n: NonZeroU32) -> Self { + Self { rate_limit: Some(RateLimit::per_minute(n)), metrics: self.metrics } + } + + /// Enable metrics middleware. + pub fn with_metrics(self, metrics: Metrics) -> Self { + Self { rate_limit: self.rate_limit, metrics: Some(metrics) } + } + + /// Register a new websocket connection. + pub fn ws_connect(&self) { + self.metrics.as_ref().map(|m| m.ws_connect()); + } + + /// Register that a websocket connection was closed. + pub fn ws_disconnect(&self, now: Instant) { + self.metrics.as_ref().map(|m| m.ws_disconnect(now)); + } +} + +impl tower::Layer for MiddlewareLayer { + type Service = Middleware; + + fn layer(&self, service: S) -> Self::Service { + Middleware { service, rate_limit: self.rate_limit.clone(), metrics: self.metrics.clone() } + } +} + +/// JSON-RPC middleware that handles metrics +/// and rate-limiting. +/// +/// These are part of the same middleware +/// because the metrics needs to know whether +/// a call was rate-limited or not because +/// it will impact the roundtrip for a call. +pub struct Middleware { + service: S, + rate_limit: Option, + metrics: Option, +} + +impl<'a, S> RpcServiceT<'a> for Middleware +where + S: Send + Sync + RpcServiceT<'a> + Clone + 'static, +{ + type Future = BoxFuture<'a, MethodResponse>; + + fn call(&self, req: Request<'a>) -> Self::Future { + let now = Instant::now(); + + self.metrics.as_ref().map(|m| m.on_call(&req)); + + let service = self.service.clone(); + let rate_limit = self.rate_limit.clone(); + let metrics = self.metrics.clone(); + + async move { + let mut is_rate_limited = false; + + if let Some(limit) = rate_limit.as_ref() { + let mut attempts = 0; + let jitter = Jitter::up_to(MAX_JITTER); + + loop { + if attempts >= MAX_RETRIES { + return reject_too_many_calls(req.id); + } + + if let Err(rejected) = limit.inner.check() { + tokio::time::sleep(jitter + rejected.wait_time_from(limit.clock.now())) + .await; + } else { + break; + } + + is_rate_limited = true; + attempts += 1; + } + } + + let rp = service.call(req.clone()).await; + metrics.as_ref().map(|m| m.on_response(&req, &rp, is_rate_limited, now)); + + rp + } + .boxed() + } +} + +fn reject_too_many_calls(id: Id) -> MethodResponse { + MethodResponse::error(id, ErrorObject::owned(-32999, "RPC rate limit exceeded", None::<()>)) +} diff --git a/substrate/client/rpc-servers/src/middleware/rate_limit.rs b/substrate/client/rpc-servers/src/middleware/rate_limit.rs index cdcc3ebf66f..23335eb3768 100644 --- a/substrate/client/rpc-servers/src/middleware/rate_limit.rs +++ b/substrate/client/rpc-servers/src/middleware/rate_limit.rs @@ -16,92 +16,32 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! RPC rate limiting middleware. +//! RPC rate limit. -use std::{num::NonZeroU32, sync::Arc, time::Duration}; - -use futures::future::{BoxFuture, FutureExt}; use governor::{ - clock::{Clock, DefaultClock, QuantaClock}, + clock::{DefaultClock, QuantaClock}, middleware::NoOpMiddleware, state::{InMemoryState, NotKeyed}, - Jitter, -}; -use jsonrpsee::{ - server::middleware::rpc::RpcServiceT, - types::{ErrorObject, Id, Request}, - MethodResponse, + Quota, }; +use std::{num::NonZeroU32, sync::Arc}; type RateLimitInner = governor::RateLimiter; -const MAX_JITTER: Duration = Duration::from_millis(50); -const MAX_RETRIES: usize = 10; - -/// JSON-RPC rate limit middleware layer. +/// Rate limit. #[derive(Debug, Clone)] -pub struct RateLimitLayer(governor::Quota); - -impl RateLimitLayer { - /// Create new rate limit enforced per minute. - pub fn per_minute(n: NonZeroU32) -> Self { - Self(governor::Quota::per_minute(n)) - } +pub struct RateLimit { + pub(crate) inner: Arc, + pub(crate) clock: QuantaClock, } -/// JSON-RPC rate limit middleware -pub struct RateLimit { - service: S, - rate_limit: Arc, - clock: QuantaClock, -} - -impl tower::Layer for RateLimitLayer { - type Service = RateLimit; - - fn layer(&self, service: S) -> Self::Service { +impl RateLimit { + /// Create a new `RateLimit` per minute. + pub fn per_minute(n: NonZeroU32) -> Self { let clock = QuantaClock::default(); - RateLimit { - service, - rate_limit: Arc::new(RateLimitInner::direct_with_clock(self.0, &clock)), + Self { + inner: Arc::new(RateLimitInner::direct_with_clock(Quota::per_minute(n), &clock)), clock, } } } - -impl<'a, S> RpcServiceT<'a> for RateLimit -where - S: Send + Sync + RpcServiceT<'a> + Clone + 'static, -{ - type Future = BoxFuture<'a, MethodResponse>; - - fn call(&self, req: Request<'a>) -> Self::Future { - let service = self.service.clone(); - let rate_limit = self.rate_limit.clone(); - let clock = self.clock.clone(); - - async move { - let mut attempts = 0; - let jitter = Jitter::up_to(MAX_JITTER); - - loop { - if attempts >= MAX_RETRIES { - break reject_too_many_calls(req.id); - } - - if let Err(rejected) = rate_limit.check() { - tokio::time::sleep(jitter + rejected.wait_time_from(clock.now())).await; - } else { - break service.call(req).await; - } - - attempts += 1; - } - } - .boxed() - } -} - -fn reject_too_many_calls(id: Id) -> MethodResponse { - MethodResponse::error(id, ErrorObject::owned(-32999, "RPC rate limit exceeded", None::<()>)) -} -- GitLab From 601b77d9986d551ecfb2c09de9e75384f055cda4 Mon Sep 17 00:00:00 2001 From: philoniare Date: Tue, 5 Mar 2024 18:46:56 +0800 Subject: [PATCH 345/392] [Documentation] Delete unused outdated `polkadot/testing.md` (#3559) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description *Deletes `testing.md` file in accordance with the discussion on issue #2527.* Old references to Gurke or simnet have been removed. Fixes #2527 --------- Co-authored-by: Bastian Köcher --- polkadot/doc/testing.md | 302 ---------------------------------------- 1 file changed, 302 deletions(-) delete mode 100644 polkadot/doc/testing.md diff --git a/polkadot/doc/testing.md b/polkadot/doc/testing.md deleted file mode 100644 index 76703b1b439..00000000000 --- a/polkadot/doc/testing.md +++ /dev/null @@ -1,302 +0,0 @@ -# Testing - -Testing is an essential tool to assure correctness. This document describes how we test the Polkadot code, whether -locally, at scale, and/or automatically in CI. - -## Scopes - -The testing strategy for Polkadot is 4-fold: - -### Unit testing (1) - -Boring, small scale correctness tests of individual functions. It is usually -enough to run `cargo test` in the crate you are testing. - -For full coverage you may have to pass some additional features. For example: - -```sh -cargo test --features ci-only-tests -``` - -### Integration tests - -There are the following variants of integration tests: - -#### Subsystem tests (2) - -One particular subsystem (subsystem under test) interacts with a mocked overseer that is made to assert incoming and -outgoing messages of the subsystem under test. See e.g. the `statement-distribution` tests. - -#### Behavior tests (3) - -Launching small scale networks, with multiple adversarial nodes. This should include tests around the thresholds in -order to evaluate the error handling once certain assumed invariants fail. - -Currently, we commonly use **zombienet** to run mini test-networks, whether locally or in CI. To run on your machine: - -- First, make sure you have [zombienet][zombienet] installed. - -- Now, all the required binaries must be installed in your $PATH. You must run the following from the `polkadot/` -directory in order to test your changes. (Not `zombienet setup`, or you will get the released binaries without your -local changes!) - -```sh -cargo install --path . --locked -``` - -- You will also need to install whatever binaries are required for your specific tests. For example, to install -`undying-collator`, from `polkadot/`, run: - -```sh -cargo install --path ./parachain/test-parachains/undying/collator --locked -``` - -- Finally, run the zombienet test from the `polkadot` directory: - -```sh -RUST_LOG=parachain::pvf=trace zombienet --provider=native spawn zombienet_tests/functional/0001-parachains-pvf.toml -``` - -- You can pick a validator node like `alice` from the output and view its logs -(`tail -f `) or metrics. Make sure there is nothing funny in the logs -(try `grep WARN `). - -#### Testing at scale (4) - -Launching many nodes with configurable network speed and node features in a cluster of nodes. At this scale the -[Simnet][simnet] comes into play which launches a full cluster of nodes. The scale is handled by spawning a kubernetes -cluster and the meta description is covered by [Gurke][Gurke]. Asserts are made using Grafana rules, based on the -existing prometheus metrics. This can be extended by adding an additional service translating `jaeger` spans into -addition prometheus avoiding additional Polkadot source changes. - -_Behavior tests_ and _testing at scale_ have naturally soft boundary. The most significant difference is the presence of -a real network and the number of nodes, since a single host often not capable to run multiple nodes at once. - -## Observing Logs - -To verify expected behavior it's often useful to observe logs. To avoid too many -logs at once, you can run one test at a time: - -1. Add `sp_tracing::try_init_simple();` to the beginning of a test -2. Specify `RUST_LOG=::=trace` before the cargo command. - -For example: - -```sh -RUST_LOG=parachain::pvf=trace cargo test execute_can_run_serially -``` - -For more info on how our logs work, check [the docs][logs]. - -## Coverage - -Coverage gives a _hint_ of the actually covered source lines by tests and test applications. - -The state of the art is currently tarpaulin which unfortunately yields a lot of false negatives. Lines that -are in fact covered, marked as uncovered due to a mere linebreak in a statement can cause these artifacts. This leads to -lower coverage percentages than there actually is. - -Since late 2020 rust has gained [MIR based coverage tooling]( -https://blog.rust-lang.org/inside-rust/2020/11/12/source-based-code-coverage.html). - -```sh -# setup -rustup component add llvm-tools-preview -cargo install grcov miniserve - -export CARGO_INCREMENTAL=0 -# wasm is not happy with the instrumentation -export SKIP_BUILD_WASM=true -export BUILD_DUMMY_WASM_BINARY=true -# the actully collected coverage data -export LLVM_PROFILE_FILE="llvmcoveragedata-%p-%m.profraw" -# build wasm without instrumentation -export WASM_TARGET_DIRECTORY=/tmp/wasm -cargo +nightly build -# required rust flags -export RUSTFLAGS="-Zinstrument-coverage" -# assure target dir is clean -rm -r target/{debug,tests} -# run tests to get coverage data -cargo +nightly test --all - -# create the *html* report out of all the test binaries -# mostly useful for local inspection -grcov . --binary-path ./target/debug -s . -t html --branch --ignore-not-existing -o ./coverage/ -miniserve -r ./coverage - -# create a *codecov* compatible report -grcov . --binary-path ./target/debug/ -s . -t lcov --branch --ignore-not-existing --ignore "/*" -o lcov.info -``` - -The test coverage in `lcov` can the be published to . - -```sh -bash <(curl -s https://codecov.io/bash) -f lcov.info -``` - -or just printed as part of the PR using a github action i.e. -[`jest-lcov-reporter`](https://github.com/marketplace/actions/jest-lcov-reporter). - -For full examples on how to use [`grcov` /w Polkadot specifics see the github -repo](https://github.com/mozilla/grcov#coverallscodecov-output). - -## Fuzzing - -Fuzzing is an approach to verify correctness against arbitrary or partially structured inputs. - -Currently implemented fuzzing targets: - -- `erasure-coding` - -The tooling of choice here is `honggfuzz-rs` as it allows _fastest_ coverage according to "some paper" which is a -positive feature when run as part of PRs. - -Fuzzing is generally not applicable for data secured by cryptographic hashes or signatures. Either the input has to be -specifically crafted, such that the discarded input percentage stays in an acceptable range. System level fuzzing is -hence simply not feasible due to the amount of state that is required. - -Other candidates to implement fuzzing are: - -- `rpc` -- ... - -## Performance metrics - -There are various ways of performance metrics. - -- timing with `criterion` -- cache hits/misses w/ `iai` harness or `criterion-perf` -- `coz` a performance based compiler - -Most of them are standard tools to aid in the creation of statistical tests regarding change in time of certain unit -tests. - -`coz` is meant for runtime. In our case, the system is far too large to yield a sufficient number of measurements in -finite time. An alternative approach could be to record incoming package streams per subsystem and store dumps of them, -which in return could be replayed repeatedly at an accelerated speed, with which enough metrics could be obtained to -yield information on which areas would improve the metrics. This unfortunately will not yield much information, since -most if not all of the subsystem code is linear based on the input to generate one or multiple output messages, it is -unlikely to get any useful metrics without mocking a sufficiently large part of the other subsystem which overlaps with -[#Integration tests] which is unfortunately not repeatable as of now. As such the effort gain seems low and this is not -pursued at the current time. - -## Writing small scope integration tests with preconfigured workers - -Requirements: - -- spawn nodes with preconfigured behaviors -- allow multiple types of configuration to be specified -- allow extendability via external crates -- ... - ---- - -## Implementation of different behavior strain nodes - -### Goals - -The main goals are is to allow creating a test node which exhibits a certain behavior by utilizing a subset of _wrapped_ -or _replaced_ subsystems easily. The runtime must not matter at all for these tests and should be simplistic. The -execution must be fast, this mostly means to assure a close to zero network latency as well as shorting the block time -and epoch times down to a few `100ms` and a few dozend blocks per epoch. - -### Approach - -#### MVP - -A simple small scale builder pattern would suffice for stage one implementation of allowing to replace individual -subsystems. An alternative would be to harness the existing `AllSubsystems` type and replace the subsystems as needed. - -#### Full `proc-macro` implementation - -`Overseer` is a common pattern. It could be extracted as `proc` macro and generative `proc-macro`. This would replace -the `AllSubsystems` type as well as implicitly create the `AllMessages` enum as `AllSubsystemsGen` does today. - -The implementation is yet to be completed, see the [implementation PR](https://github.com/paritytech/polkadot/pull/2962) -for details. - -##### Declare an overseer implementation - -```rust -struct BehaveMaleficient; - -impl OverseerGen for BehaveMaleficient { - fn generate<'a, Spawner, RuntimeClient>( - &self, - args: OverseerGenArgs<'a, Spawner, RuntimeClient>, - ) -> Result<(Overseer>, OverseerHandler), Error> - where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, - Spawner: 'static + overseer::gen::Spawner + Clone + Unpin, - { - let spawner = args.spawner.clone(); - let leaves = args.leaves.clone(); - let runtime_client = args.runtime_client.clone(); - let registry = args.registry.clone(); - let candidate_validation_config = args.candidate_validation_config.clone(); - // modify the subsystem(s) as needed: - let all_subsystems = create_default_subsystems(args)?. - // or spawn an entirely new set - - replace_candidate_validation( - // create the filtered subsystem - FilteredSubsystem::new( - CandidateValidationSubsystem::with_config( - candidate_validation_config, - Metrics::register(registry)?, - ), - // an implementation of - Skippy::default(), - ), - ); - - Overseer::new(leaves, all_subsystems, registry, runtime_client, spawner) - .map_err(|e| e.into()) - - // A builder pattern will simplify this further - // WIP https://github.com/paritytech/polkadot/pull/2962 - } -} - -fn main() -> eyre::Result<()> { - color_eyre::install()?; - let cli = Cli::from_args(); - assert_matches::assert_matches!(cli.subcommand, None); - polkadot_cli::run_node(cli, BehaveMaleficient)?; - Ok(()) -} -``` - -[`variant-a`](../node/malus/src/variant-a.rs) is a fully working example. - -#### Simnet - -Spawn a kubernetes cluster based on a meta description using [Gurke] with the [Simnet] scripts. - -Coordinated attacks of multiple nodes or subsystems must be made possible via a side-channel, that is out of scope for -this document. - -The individual node configurations are done as targets with a particular builder configuration. - -#### Behavior tests w/o Simnet - -Commonly this will require multiple nodes, and most machines are limited to running two or three nodes concurrently. -Hence, this is not the common case and is just an implementation _idea_. - -```rust -behavior_testcase!{ -"TestRuntime" => -"Alice": , -"Bob": , -"Charles": Default, -"David": "Charles", -"Eve": "Bob", -} -``` - -[zombienet]: https://github.com/paritytech/zombienet -[Gurke]: https://github.com/paritytech/gurke -[simnet]: https://github.com/paritytech/simnet_scripts -[logs]: https://github.com/paritytech/polkadot-sdk/blob/master/polkadot/node/gum/src/lib.rs -- GitLab From 3ff78a7888b859af7b4c5ea7247b3ddd0895728d Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Tue, 5 Mar 2024 12:04:05 +0100 Subject: [PATCH 346/392] Increase 0002-validators-warp-sync timeout (#3575) Fixes failures like: https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/5436619#L3319 --- .../0002-validators-warp-sync/test-validators-warp-sync.zndsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.zndsl b/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.zndsl index ea0f15e5d8a..b68bce508c0 100644 --- a/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.zndsl +++ b/substrate/zombienet/0002-validators-warp-sync/test-validators-warp-sync.zndsl @@ -34,8 +34,8 @@ bob: reports block height is at least {{DB_BLOCK_HEIGHT}} within 10 seconds alice: reports substrate_beefy_best_block is at least {{DB_BLOCK_HEIGHT}} within 180 seconds bob: reports substrate_beefy_best_block is at least {{DB_BLOCK_HEIGHT}} within 180 seconds -alice: reports substrate_beefy_best_block is greater than {{DB_BLOCK_HEIGHT}} within 60 seconds -bob: reports substrate_beefy_best_block is greater than {{DB_BLOCK_HEIGHT}} within 60 seconds +alice: reports substrate_beefy_best_block is greater than {{DB_BLOCK_HEIGHT}} within 180 seconds +bob: reports substrate_beefy_best_block is greater than {{DB_BLOCK_HEIGHT}} within 180 seconds alice: count of log lines containing "error" is 0 within 10 seconds bob: count of log lines containing "verification failed" is 0 within 10 seconds -- GitLab From a71f018c7a6a7374d929e54b3466f1bd9bdd9de8 Mon Sep 17 00:00:00 2001 From: Matteo Muraca <56828990+muraca@users.noreply.github.com> Date: Tue, 5 Mar 2024 12:04:11 +0100 Subject: [PATCH 347/392] Removed `pallet::getter` usage from `pallet-collective` (#3456) Part of #3326 This one is easier as all the storage items are public. @ggwpez @kianenigma @shawntabrizi --------- Signed-off-by: Matteo Muraca Co-authored-by: Liam Aharon Co-authored-by: command-bot <> Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- .../collectives-westend/src/impls.rs | 2 +- prdoc/pr_3456.prdoc | 15 ++++ substrate/bin/node/runtime/src/impls.rs | 8 +-- substrate/frame/alliance/src/mock.rs | 2 +- substrate/frame/alliance/src/tests.rs | 4 +- .../frame/collective/src/benchmarking.rs | 32 ++++----- substrate/frame/collective/src/lib.rs | 72 +++++++++---------- substrate/frame/collective/src/tests.rs | 44 ++++++------ 8 files changed, 94 insertions(+), 85 deletions(-) create mode 100644 prdoc/pr_3456.prdoc diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/impls.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/impls.rs index caf0cddec66..e5b176fc778 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/impls.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/impls.rs @@ -81,7 +81,7 @@ where } fn proposal_of(proposal_hash: HashOf) -> Option> { - pallet_collective::Pallet::::proposal_of(proposal_hash) + pallet_collective::ProposalOf::::get(proposal_hash) } } diff --git a/prdoc/pr_3456.prdoc b/prdoc/pr_3456.prdoc new file mode 100644 index 00000000000..c7327e17e57 --- /dev/null +++ b/prdoc/pr_3456.prdoc @@ -0,0 +1,15 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Removed `pallet::getter` usage from `pallet-collective` + +doc: + - audience: Runtime Dev + description: | + This PR removes `pallet::getter` usage from `pallet-collective`, and updates dependant code accordingly. + The syntax `StorageItem::::get()` should be used instead. + +crates: + - name: pallet-collective + - name: kitchensink-runtime + - name: collectives-westend-runtime diff --git a/substrate/bin/node/runtime/src/impls.rs b/substrate/bin/node/runtime/src/impls.rs index 7ff52a758b3..34f043b33a4 100644 --- a/substrate/bin/node/runtime/src/impls.rs +++ b/substrate/bin/node/runtime/src/impls.rs @@ -30,8 +30,8 @@ use pallet_identity::legacy::IdentityField; use sp_std::prelude::*; use crate::{ - AccountId, AllianceMotion, Assets, Authorship, Balances, Hash, NegativeImbalance, Runtime, - RuntimeCall, + AccountId, AllianceCollective, AllianceMotion, Assets, Authorship, Balances, Hash, + NegativeImbalance, Runtime, RuntimeCall, }; pub struct Author; @@ -107,7 +107,7 @@ impl ProposalProvider for AllianceProposalProvider } fn proposal_of(proposal_hash: Hash) -> Option { - AllianceMotion::proposal_of(proposal_hash) + pallet_collective::ProposalOf::::get(proposal_hash) } } @@ -276,7 +276,7 @@ mod multiplier_tests { let next = runtime_multiplier_update(fm); fm = next; if fm == min_multiplier() { - break + break; } iterations += 1; } diff --git a/substrate/frame/alliance/src/mock.rs b/substrate/frame/alliance/src/mock.rs index 4a65485ed8f..fd44d33ef93 100644 --- a/substrate/frame/alliance/src/mock.rs +++ b/substrate/frame/alliance/src/mock.rs @@ -208,7 +208,7 @@ impl ProposalProvider for AllianceProposalProvider } fn proposal_of(proposal_hash: H256) -> Option { - AllianceMotion::proposal_of(proposal_hash) + pallet_collective::ProposalOf::::get(proposal_hash) } } diff --git a/substrate/frame/alliance/src/tests.rs b/substrate/frame/alliance/src/tests.rs index 8011627b237..710de5a54bc 100644 --- a/substrate/frame/alliance/src/tests.rs +++ b/substrate/frame/alliance/src/tests.rs @@ -187,8 +187,8 @@ fn propose_works() { Box::new(proposal.clone()), proposal_len )); - assert_eq!(*AllianceMotion::proposals(), vec![hash]); - assert_eq!(AllianceMotion::proposal_of(&hash), Some(proposal)); + assert_eq!(*pallet_collective::Proposals::::get(), vec![hash]); + assert_eq!(pallet_collective::ProposalOf::::get(&hash), Some(proposal)); assert_eq!( System::events(), vec![EventRecord { diff --git a/substrate/frame/collective/src/benchmarking.rs b/substrate/frame/collective/src/benchmarking.rs index af10eae5b67..7b5df17b60a 100644 --- a/substrate/frame/collective/src/benchmarking.rs +++ b/substrate/frame/collective/src/benchmarking.rs @@ -105,7 +105,7 @@ benchmarks_instance_pallet! { }: _(SystemOrigin::Root, new_members.clone(), new_members.last().cloned(), T::MaxMembers::get()) verify { new_members.sort(); - assert_eq!(Collective::::members(), new_members); + assert_eq!(Members::::get(), new_members); } execute { @@ -199,14 +199,14 @@ benchmarks_instance_pallet! { )?; } - assert_eq!(Collective::::proposals().len(), (p - 1) as usize); + assert_eq!(Proposals::::get().len(), (p - 1) as usize); let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(p, b as usize) }.into(); }: propose(SystemOrigin::Signed(caller.clone()), threshold, Box::new(proposal.clone()), bytes_in_storage) verify { // New proposal is recorded - assert_eq!(Collective::::proposals().len(), p as usize); + assert_eq!(Proposals::::get().len(), p as usize); let proposal_hash = T::Hashing::hash_of(&proposal); assert_last_event::(Event::Proposed { account: caller, proposal_index: p - 1, proposal_hash, threshold }.into()); } @@ -269,7 +269,7 @@ benchmarks_instance_pallet! { approve, )?; - assert_eq!(Collective::::proposals().len(), p as usize); + assert_eq!(Proposals::::get().len(), p as usize); // Voter switches vote to nay, but does not kill the vote, just updates + inserts let approve = false; @@ -280,8 +280,8 @@ benchmarks_instance_pallet! { }: _(SystemOrigin::Signed(voter), last_hash, index, approve) verify { // All proposals exist and the last proposal has just been updated. - assert_eq!(Collective::::proposals().len(), p as usize); - let voting = Collective::::voting(&last_hash).ok_or("Proposal Missing")?; + assert_eq!(Proposals::::get().len(), p as usize); + let voting = Voting::::get(&last_hash).ok_or("Proposal Missing")?; assert_eq!(voting.ayes.len(), (m - 3) as usize); assert_eq!(voting.nays.len(), 1); } @@ -344,7 +344,7 @@ benchmarks_instance_pallet! { approve, )?; - assert_eq!(Collective::::proposals().len(), p as usize); + assert_eq!(Proposals::::get().len(), p as usize); // Voter switches vote to nay, which kills the vote let approve = false; @@ -361,7 +361,7 @@ benchmarks_instance_pallet! { }: close(SystemOrigin::Signed(voter), last_hash, index, Weight::MAX, bytes_in_storage) verify { // The last proposal is removed. - assert_eq!(Collective::::proposals().len(), (p - 1) as usize); + assert_eq!(Proposals::::get().len(), (p - 1) as usize); assert_last_event::(Event::Disapproved { proposal_hash: last_hash }.into()); } @@ -428,7 +428,7 @@ benchmarks_instance_pallet! { true, )?; - assert_eq!(Collective::::proposals().len(), p as usize); + assert_eq!(Proposals::::get().len(), p as usize); // Caller switches vote to aye, which passes the vote let index = p - 1; @@ -442,7 +442,7 @@ benchmarks_instance_pallet! { }: close(SystemOrigin::Signed(caller), last_hash, index, Weight::MAX, bytes_in_storage) verify { // The last proposal is removed. - assert_eq!(Collective::::proposals().len(), (p - 1) as usize); + assert_eq!(Proposals::::get().len(), (p - 1) as usize); assert_last_event::(Event::Executed { proposal_hash: last_hash, result: Ok(()) }.into()); } @@ -519,12 +519,12 @@ benchmarks_instance_pallet! { )?; System::::set_block_number(BlockNumberFor::::max_value()); - assert_eq!(Collective::::proposals().len(), p as usize); + assert_eq!(Proposals::::get().len(), p as usize); // Prime nay will close it as disapproved }: close(SystemOrigin::Signed(caller), last_hash, index, Weight::MAX, bytes_in_storage) verify { - assert_eq!(Collective::::proposals().len(), (p - 1) as usize); + assert_eq!(Proposals::::get().len(), (p - 1) as usize); assert_last_event::(Event::Disapproved { proposal_hash: last_hash }.into()); } @@ -591,12 +591,12 @@ benchmarks_instance_pallet! { // caller is prime, prime already votes aye by creating the proposal System::::set_block_number(BlockNumberFor::::max_value()); - assert_eq!(Collective::::proposals().len(), p as usize); + assert_eq!(Proposals::::get().len(), p as usize); // Prime aye will close it as approved }: close(SystemOrigin::Signed(caller), last_hash, p - 1, Weight::MAX, bytes_in_storage) verify { - assert_eq!(Collective::::proposals().len(), (p - 1) as usize); + assert_eq!(Proposals::::get().len(), (p - 1) as usize); assert_last_event::(Event::Executed { proposal_hash: last_hash, result: Ok(()) }.into()); } @@ -640,11 +640,11 @@ benchmarks_instance_pallet! { } System::::set_block_number(BlockNumberFor::::max_value()); - assert_eq!(Collective::::proposals().len(), p as usize); + assert_eq!(Proposals::::get().len(), p as usize); }: _(SystemOrigin::Root, last_hash) verify { - assert_eq!(Collective::::proposals().len(), (p - 1) as usize); + assert_eq!(Proposals::::get().len(), (p - 1) as usize); assert_last_event::(Event::Disapproved { proposal_hash: last_hash }.into()); } diff --git a/substrate/frame/collective/src/lib.rs b/substrate/frame/collective/src/lib.rs index dd481b53681..882e99a6d00 100644 --- a/substrate/frame/collective/src/lib.rs +++ b/substrate/frame/collective/src/lib.rs @@ -261,36 +261,30 @@ pub mod pallet { /// The hashes of the active proposals. #[pallet::storage] - #[pallet::getter(fn proposals)] pub type Proposals, I: 'static = ()> = StorageValue<_, BoundedVec, ValueQuery>; /// Actual proposal for a given hash, if it's current. #[pallet::storage] - #[pallet::getter(fn proposal_of)] pub type ProposalOf, I: 'static = ()> = StorageMap<_, Identity, T::Hash, >::Proposal, OptionQuery>; /// Votes on a given proposal, if it is ongoing. #[pallet::storage] - #[pallet::getter(fn voting)] pub type Voting, I: 'static = ()> = StorageMap<_, Identity, T::Hash, Votes>, OptionQuery>; /// Proposals so far. #[pallet::storage] - #[pallet::getter(fn proposal_count)] pub type ProposalCount, I: 'static = ()> = StorageValue<_, u32, ValueQuery>; /// The current members of the collective. This is stored sorted (just by value). #[pallet::storage] - #[pallet::getter(fn members)] pub type Members, I: 'static = ()> = StorageValue<_, Vec, ValueQuery>; /// The prime member that helps determine the default vote behavior in case of absentations. #[pallet::storage] - #[pallet::getter(fn prime)] pub type Prime, I: 'static = ()> = StorageValue<_, T::AccountId, OptionQuery>; #[pallet::event] @@ -459,7 +453,7 @@ pub mod pallet { #[pallet::compact] length_bound: u32, ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - let members = Self::members(); + let members = Members::::get(); ensure!(members.contains(&who), Error::::NotMember); let proposal_len = proposal.encoded_size(); ensure!(proposal_len <= length_bound as usize, Error::::WrongProposalLength); @@ -519,7 +513,7 @@ pub mod pallet { #[pallet::compact] length_bound: u32, ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - let members = Self::members(); + let members = Members::::get(); ensure!(members.contains(&who), Error::::NotMember); if threshold < 2 { @@ -565,7 +559,7 @@ pub mod pallet { approve: bool, ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - let members = Self::members(); + let members = Members::::get(); ensure!(members.contains(&who), Error::::NotMember); // Detects first vote of the member in the motion @@ -669,7 +663,7 @@ impl, I: 'static> Pallet { pub fn is_member(who: &T::AccountId) -> bool { // Note: The dispatchables *do not* use this to check membership so make sure // to update those if this is changed. - Self::members().contains(who) + Members::::get().contains(who) } /// Execute immediately when adding a new proposal. @@ -688,7 +682,7 @@ impl, I: 'static> Pallet { let proposal_hash = T::Hashing::hash_of(&proposal); ensure!(!>::contains_key(proposal_hash), Error::::DuplicateProposal); - let seats = Self::members().len() as MemberCount; + let seats = Members::::get().len() as MemberCount; let result = proposal.dispatch(RawOrigin::Members(1, seats).into()); Self::deposit_event(Event::Executed { proposal_hash, @@ -721,7 +715,7 @@ impl, I: 'static> Pallet { Ok(proposals.len()) })?; - let index = Self::proposal_count(); + let index = ProposalCount::::get(); >::mutate(|i| *i += 1); >::insert(proposal_hash, proposal); let votes = { @@ -747,7 +741,7 @@ impl, I: 'static> Pallet { index: ProposalIndex, approve: bool, ) -> Result { - let mut voting = Self::voting(&proposal).ok_or(Error::::ProposalMissing)?; + let mut voting = Voting::::get(&proposal).ok_or(Error::::ProposalMissing)?; ensure!(voting.index == index, Error::::WrongIndex); let position_yes = voting.ayes.iter().position(|a| a == &who); @@ -798,12 +792,12 @@ impl, I: 'static> Pallet { proposal_weight_bound: Weight, length_bound: u32, ) -> DispatchResultWithPostInfo { - let voting = Self::voting(&proposal_hash).ok_or(Error::::ProposalMissing)?; + let voting = Voting::::get(&proposal_hash).ok_or(Error::::ProposalMissing)?; ensure!(voting.index == index, Error::::WrongIndex); let mut no_votes = voting.nays.len() as MemberCount; let mut yes_votes = voting.ayes.len() as MemberCount; - let seats = Self::members().len() as MemberCount; + let seats = Members::::get().len() as MemberCount; let approved = yes_votes >= voting.threshold; let disapproved = seats.saturating_sub(no_votes) < voting.threshold; // Allow (dis-)approving the proposal as soon as there are enough votes. @@ -837,7 +831,7 @@ impl, I: 'static> Pallet { // Only allow actual closing of the proposal after the voting period has ended. ensure!(frame_system::Pallet::::block_number() >= voting.end, Error::::TooEarly); - let prime_vote = Self::prime().map(|who| voting.ayes.iter().any(|a| a == &who)); + let prime_vote = Prime::::get().map(|who| voting.ayes.iter().any(|a| a == &who)); // default voting strategy. let default = T::DefaultVote::default_vote(prime_vote, yes_votes, no_votes, seats); @@ -978,29 +972,28 @@ impl, I: 'static> Pallet { /// * The prime account must be a member of the collective. #[cfg(any(feature = "try-runtime", test))] fn do_try_state() -> Result<(), TryRuntimeError> { - Self::proposals() - .into_iter() - .try_for_each(|proposal| -> Result<(), TryRuntimeError> { + Proposals::::get().into_iter().try_for_each( + |proposal| -> Result<(), TryRuntimeError> { ensure!( - Self::proposal_of(proposal).is_some(), + ProposalOf::::get(proposal).is_some(), "Proposal hash from `Proposals` is not found inside the `ProposalOf` mapping." ); Ok(()) - })?; + }, + )?; ensure!( - Self::proposals().into_iter().count() <= Self::proposal_count() as usize, + Proposals::::get().into_iter().count() <= ProposalCount::::get() as usize, "The actual number of proposals is greater than `ProposalCount`" ); ensure!( - Self::proposals().into_iter().count() == >::iter_keys().count(), + Proposals::::get().into_iter().count() == >::iter_keys().count(), "Proposal count inside `Proposals` is not equal to the proposal count in `ProposalOf`" ); - Self::proposals() - .into_iter() - .try_for_each(|proposal| -> Result<(), TryRuntimeError> { - if let Some(votes) = Self::voting(proposal) { + Proposals::::get().into_iter().try_for_each( + |proposal| -> Result<(), TryRuntimeError> { + if let Some(votes) = Voting::::get(proposal) { let ayes = votes.ayes.len(); let nays = votes.nays.len(); @@ -1010,13 +1003,13 @@ impl, I: 'static> Pallet { ); } Ok(()) - })?; + }, + )?; let mut proposal_indices = vec![]; - Self::proposals() - .into_iter() - .try_for_each(|proposal| -> Result<(), TryRuntimeError> { - if let Some(votes) = Self::voting(proposal) { + Proposals::::get().into_iter().try_for_each( + |proposal| -> Result<(), TryRuntimeError> { + if let Some(votes) = Voting::::get(proposal) { let proposal_index = votes.index; ensure!( !proposal_indices.contains(&proposal_index), @@ -1025,12 +1018,13 @@ impl, I: 'static> Pallet { proposal_indices.push(proposal_index); } Ok(()) - })?; + }, + )?; >::iter_keys().try_for_each( |proposal_hash| -> Result<(), TryRuntimeError> { ensure!( - Self::proposals().contains(&proposal_hash), + Proposals::::get().contains(&proposal_hash), "`Proposals` doesn't contain the proposal hash from the `Voting` storage map." ); Ok(()) @@ -1038,17 +1032,17 @@ impl, I: 'static> Pallet { )?; ensure!( - Self::members().len() <= T::MaxMembers::get() as usize, + Members::::get().len() <= T::MaxMembers::get() as usize, "The member count is greater than `MaxMembers`." ); ensure!( - Self::members().windows(2).all(|members| members[0] <= members[1]), + Members::::get().windows(2).all(|members| members[0] <= members[1]), "The members are not sorted by value." ); - if let Some(prime) = Self::prime() { - ensure!(Self::members().contains(&prime), "Prime account is not a member."); + if let Some(prime) = Prime::::get() { + ensure!(Members::::get().contains(&prime), "Prime account is not a member."); } Ok(()) @@ -1082,7 +1076,7 @@ impl, I: 'static> ChangeMembers for Pallet { // remove accounts from all current voting in motions. let mut outgoing = outgoing.to_vec(); outgoing.sort(); - for h in Self::proposals().into_iter() { + for h in Proposals::::get().into_iter() { >::mutate(h, |v| { if let Some(mut votes) = v.take() { votes.ayes = votes diff --git a/substrate/frame/collective/src/tests.rs b/substrate/frame/collective/src/tests.rs index ac5797c638c..92418794c5f 100644 --- a/substrate/frame/collective/src/tests.rs +++ b/substrate/frame/collective/src/tests.rs @@ -193,8 +193,8 @@ fn default_max_proposal_weight() -> Weight { #[test] fn motions_basic_environment_works() { ExtBuilder::default().build_and_execute(|| { - assert_eq!(Collective::members(), vec![1, 2, 3]); - assert_eq!(*Collective::proposals(), Vec::::new()); + assert_eq!(Members::::get(), vec![1, 2, 3]); + assert_eq!(*Proposals::::get(), Vec::::new()); }); } @@ -205,7 +205,7 @@ fn initialize_members_sorts_members() { ExtBuilder::default() .set_collective_members(unsorted_members) .build_and_execute(|| { - assert_eq!(Collective::members(), expected_members); + assert_eq!(Members::::get(), expected_members); }); } @@ -219,8 +219,8 @@ fn set_members_with_prime_works() { Some(3), MaxMembers::get() )); - assert_eq!(Collective::members(), members.clone()); - assert_eq!(Collective::prime(), Some(3)); + assert_eq!(Members::::get(), members.clone()); + assert_eq!(Prime::::get(), Some(3)); assert_noop!( Collective::set_members(RuntimeOrigin::root(), members, Some(4), MaxMembers::get()), Error::::PrimeAccountNotMember @@ -632,12 +632,12 @@ fn removal_of_old_voters_votes_works() { assert_ok!(Collective::vote(RuntimeOrigin::signed(1), hash, 0, true)); assert_ok!(Collective::vote(RuntimeOrigin::signed(2), hash, 0, true)); assert_eq!( - Collective::voting(&hash), + Voting::::get(&hash), Some(Votes { index: 0, threshold: 3, ayes: vec![1, 2], nays: vec![], end }) ); Collective::change_members_sorted(&[4], &[1], &[2, 3, 4]); assert_eq!( - Collective::voting(&hash), + Voting::::get(&hash), Some(Votes { index: 0, threshold: 3, ayes: vec![2], nays: vec![], end }) ); @@ -653,12 +653,12 @@ fn removal_of_old_voters_votes_works() { assert_ok!(Collective::vote(RuntimeOrigin::signed(2), hash, 1, true)); assert_ok!(Collective::vote(RuntimeOrigin::signed(3), hash, 1, false)); assert_eq!( - Collective::voting(&hash), + Voting::::get(&hash), Some(Votes { index: 1, threshold: 2, ayes: vec![2], nays: vec![3], end }) ); Collective::change_members_sorted(&[], &[3], &[2, 4]); assert_eq!( - Collective::voting(&hash), + Voting::::get(&hash), Some(Votes { index: 1, threshold: 2, ayes: vec![2], nays: vec![], end }) ); }); @@ -680,7 +680,7 @@ fn removal_of_old_voters_votes_works_with_set_members() { assert_ok!(Collective::vote(RuntimeOrigin::signed(1), hash, 0, true)); assert_ok!(Collective::vote(RuntimeOrigin::signed(2), hash, 0, true)); assert_eq!( - Collective::voting(&hash), + Voting::::get(&hash), Some(Votes { index: 0, threshold: 3, ayes: vec![1, 2], nays: vec![], end }) ); assert_ok!(Collective::set_members( @@ -690,7 +690,7 @@ fn removal_of_old_voters_votes_works_with_set_members() { MaxMembers::get() )); assert_eq!( - Collective::voting(&hash), + Voting::::get(&hash), Some(Votes { index: 0, threshold: 3, ayes: vec![2], nays: vec![], end }) ); @@ -706,7 +706,7 @@ fn removal_of_old_voters_votes_works_with_set_members() { assert_ok!(Collective::vote(RuntimeOrigin::signed(2), hash, 1, true)); assert_ok!(Collective::vote(RuntimeOrigin::signed(3), hash, 1, false)); assert_eq!( - Collective::voting(&hash), + Voting::::get(&hash), Some(Votes { index: 1, threshold: 2, ayes: vec![2], nays: vec![3], end }) ); assert_ok!(Collective::set_members( @@ -716,7 +716,7 @@ fn removal_of_old_voters_votes_works_with_set_members() { MaxMembers::get() )); assert_eq!( - Collective::voting(&hash), + Voting::::get(&hash), Some(Votes { index: 1, threshold: 2, ayes: vec![2], nays: vec![], end }) ); }); @@ -735,10 +735,10 @@ fn propose_works() { Box::new(proposal.clone()), proposal_len )); - assert_eq!(*Collective::proposals(), vec![hash]); - assert_eq!(Collective::proposal_of(&hash), Some(proposal)); + assert_eq!(*Proposals::::get(), vec![hash]); + assert_eq!(ProposalOf::::get(&hash), Some(proposal)); assert_eq!( - Collective::voting(&hash), + Voting::::get(&hash), Some(Votes { index: 0, threshold: 3, ayes: vec![], nays: vec![], end }) ); @@ -898,13 +898,13 @@ fn motions_vote_after_works() { )); // Initially there a no votes when the motion is proposed. assert_eq!( - Collective::voting(&hash), + Voting::::get(&hash), Some(Votes { index: 0, threshold: 2, ayes: vec![], nays: vec![], end }) ); // Cast first aye vote. assert_ok!(Collective::vote(RuntimeOrigin::signed(1), hash, 0, true)); assert_eq!( - Collective::voting(&hash), + Voting::::get(&hash), Some(Votes { index: 0, threshold: 2, ayes: vec![1], nays: vec![], end }) ); // Try to cast a duplicate aye vote. @@ -915,7 +915,7 @@ fn motions_vote_after_works() { // Cast a nay vote. assert_ok!(Collective::vote(RuntimeOrigin::signed(1), hash, 0, false)); assert_eq!( - Collective::voting(&hash), + Voting::::get(&hash), Some(Votes { index: 0, threshold: 2, ayes: vec![], nays: vec![1], end }) ); // Try to cast a duplicate nay vote. @@ -966,7 +966,7 @@ fn motions_all_first_vote_free_works() { proposal_len, )); assert_eq!( - Collective::voting(&hash), + Voting::::get(&hash), Some(Votes { index: 0, threshold: 2, ayes: vec![], nays: vec![], end }) ); @@ -1031,14 +1031,14 @@ fn motions_reproposing_disapproved_works() { proposal_weight, proposal_len )); - assert_eq!(*Collective::proposals(), vec![]); + assert_eq!(*Proposals::::get(), vec![]); assert_ok!(Collective::propose( RuntimeOrigin::signed(1), 2, Box::new(proposal.clone()), proposal_len )); - assert_eq!(*Collective::proposals(), vec![hash]); + assert_eq!(*Proposals::::get(), vec![hash]); }); } -- GitLab From 4c810609d6c72b48bd748398165da5c27a604778 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Tue, 5 Mar 2024 11:40:37 +0000 Subject: [PATCH 348/392] Repot all templates into a single directory (#3460) The first step towards https://github.com/paritytech/polkadot-sdk/issues/3155 Brings all templates under the following structure ``` templates | parachain | | polkadot-launch | | runtime --> parachain-template-runtime | | pallets --> pallet-parachain-template | | node --> parachain-template-node | minimal | | runtime --> minimal-template-runtime | | pallets --> pallet-minimal-template | | node --> minimal-template-node | solochain | | runtime --> solochain-template-runtime | | pallets --> pallet-template (the naming is not consistent here) | | node --> solochain-template-node ``` The only note-worthy changes in this PR are: - More `Cargo.toml` fields are forwarded to use the one from the workspace. - parachain template now has weights and benchmarks - adds a shell pallet to the minimal template - remove a few unused deps A list of possible follow-ups: - [ ] Unify READMEs, create a parent README for all - [ ] remove references to `docs.substrate.io` in templates - [ ] make all templates use `#[derive_impl]` - [ ] update and unify all licenses - [ ] Remove polkadot launch, use https://github.com/paritytech/polkadot-sdk/blob/35349df993ea2e7c4769914ef5d199e787b23d4c/cumulus/zombienet/examples/small_network.toml instead. --- .github/scripts/check-workspace.py | 22 +- .github/workflows/check-licenses.yml | 1 - .gitlab/pipeline/build.yml | 2 +- Cargo.lock | 195 +++++++++--------- Cargo.toml | 21 +- .../pallets/template/README.md | 1 - .../pallets/template/src/benchmarking.rs | 20 -- prdoc/pr_3460.prdoc | 26 +++ substrate/bin/minimal/node/Cargo.toml | 60 ------ substrate/bin/minimal/runtime/Cargo.toml | 50 ----- substrate/bin/node-template/.editorconfig | 16 -- substrate/bin/node-template/env-setup/.envrc | 1 - substrate/bin/node-template/node/Cargo.toml | 93 --------- .../bin/node-template/runtime/Cargo.toml | 126 ----------- substrate/frame/Cargo.toml | 13 +- .../frame/examples/default-config/src/lib.rs | 2 +- substrate/frame/system/src/lib.rs | 2 +- templates/minimal/README.md | 0 templates/minimal/node/Cargo.toml | 62 ++++++ .../bin => templates}/minimal/node/build.rs | 0 .../minimal/node/src/chain_spec.rs | 0 .../bin => templates}/minimal/node/src/cli.rs | 0 .../minimal/node/src/command.rs | 0 .../bin => templates}/minimal/node/src/lib.rs | 2 +- .../minimal/node/src/main.rs | 0 .../bin => templates}/minimal/node/src/rpc.rs | 0 .../minimal/node/src/service.rs | 0 templates/minimal/pallets/template/Cargo.toml | 33 +++ templates/minimal/pallets/template/src/lib.rs | 19 ++ templates/minimal/runtime/Cargo.toml | 59 ++++++ .../minimal/runtime/build.rs | 0 .../minimal/runtime/src/lib.rs | 15 +- .../parachain}/LICENSE | 0 .../parachain}/README.md | 0 .../parachain}/node/Cargo.toml | 33 +-- .../parachain}/node/build.rs | 0 .../parachain}/node/src/chain_spec.rs | 13 +- .../parachain}/node/src/cli.rs | 0 .../parachain}/node/src/command.rs | 0 .../parachain}/node/src/main.rs | 0 .../parachain}/node/src/rpc.rs | 0 .../parachain}/node/src/service.rs | 0 .../parachain}/pallets/template/Cargo.toml | 30 +-- .../parachain}/pallets/template/README.md | 0 .../pallets/template/src/benchmarking.rs | 0 .../parachain}/pallets/template/src/lib.rs | 4 + .../parachain}/pallets/template/src/mock.rs | 1 + .../parachain}/pallets/template/src/tests.rs | 0 .../pallets/template/src/weights.rs | 0 .../parachain}/polkadot-launch/config.json | 0 .../parachain}/runtime/Cargo.toml | 49 +++-- .../parachain}/runtime/build.rs | 0 .../parachain}/runtime/src/lib.rs | 5 +- .../runtime/src/weights/block_weights.rs | 0 .../runtime/src/weights/extrinsic_weights.rs | 0 .../parachain}/runtime/src/weights/mod.rs | 0 .../runtime/src/weights/paritydb_weights.rs | 0 .../runtime/src/weights/rocksdb_weights.rs | 0 .../parachain}/runtime/src/xcm_config.rs | 0 .../solochain}/LICENSE | 0 .../solochain}/README.md | 0 .../solochain}/docs/rust-setup.md | 0 .../solochain}/env-setup/README.md | 0 .../solochain}/env-setup/flake.lock | 0 .../solochain}/env-setup/flake.nix | 0 .../solochain}/env-setup/rust-toolchain.toml | 0 templates/solochain/node/Cargo.toml | 92 +++++++++ .../solochain}/node/build.rs | 0 .../solochain}/node/src/benchmarking.rs | 2 +- .../solochain}/node/src/chain_spec.rs | 2 +- .../solochain}/node/src/cli.rs | 0 .../solochain}/node/src/command.rs | 2 +- .../solochain}/node/src/main.rs | 0 .../solochain}/node/src/rpc.rs | 2 +- .../solochain}/node/src/service.rs | 2 +- .../solochain}/pallets/template/Cargo.toml | 30 +-- .../solochain/pallets/template/README.md | 1 + .../pallets/template/src/benchmarking.rs | 35 ++++ .../solochain}/pallets/template/src/lib.rs | 0 .../solochain}/pallets/template/src/mock.rs | 0 .../solochain}/pallets/template/src/tests.rs | 0 .../solochain/pallets/template/src/weights.rs | 90 ++++++++ templates/solochain/runtime/Cargo.toml | 152 ++++++++++++++ .../solochain}/runtime/build.rs | 0 .../solochain}/runtime/src/lib.rs | 9 +- 85 files changed, 819 insertions(+), 576 deletions(-) delete mode 100644 cumulus/parachain-template/pallets/template/README.md delete mode 100644 cumulus/parachain-template/pallets/template/src/benchmarking.rs create mode 100644 prdoc/pr_3460.prdoc delete mode 100644 substrate/bin/minimal/node/Cargo.toml delete mode 100644 substrate/bin/minimal/runtime/Cargo.toml delete mode 100644 substrate/bin/node-template/.editorconfig delete mode 100644 substrate/bin/node-template/env-setup/.envrc delete mode 100644 substrate/bin/node-template/node/Cargo.toml delete mode 100644 substrate/bin/node-template/runtime/Cargo.toml create mode 100644 templates/minimal/README.md create mode 100644 templates/minimal/node/Cargo.toml rename {substrate/bin => templates}/minimal/node/build.rs (100%) rename {substrate/bin => templates}/minimal/node/src/chain_spec.rs (100%) rename {substrate/bin => templates}/minimal/node/src/cli.rs (100%) rename {substrate/bin => templates}/minimal/node/src/command.rs (100%) rename {substrate/bin => templates}/minimal/node/src/lib.rs (94%) rename {substrate/bin => templates}/minimal/node/src/main.rs (100%) rename {substrate/bin => templates}/minimal/node/src/rpc.rs (100%) rename {substrate/bin => templates}/minimal/node/src/service.rs (100%) create mode 100644 templates/minimal/pallets/template/Cargo.toml create mode 100644 templates/minimal/pallets/template/src/lib.rs create mode 100644 templates/minimal/runtime/Cargo.toml rename {substrate/bin => templates}/minimal/runtime/build.rs (100%) rename {substrate/bin => templates}/minimal/runtime/src/lib.rs (95%) rename {cumulus/parachain-template => templates/parachain}/LICENSE (100%) rename {cumulus/parachain-template => templates/parachain}/README.md (100%) rename {cumulus/parachain-template => templates/parachain}/node/Cargo.toml (78%) rename {cumulus/parachain-template => templates/parachain}/node/build.rs (100%) rename {cumulus/parachain-template => templates/parachain}/node/src/chain_spec.rs (93%) rename {cumulus/parachain-template => templates/parachain}/node/src/cli.rs (100%) rename {cumulus/parachain-template => templates/parachain}/node/src/command.rs (100%) rename {cumulus/parachain-template => templates/parachain}/node/src/main.rs (100%) rename {cumulus/parachain-template => templates/parachain}/node/src/rpc.rs (100%) rename {cumulus/parachain-template => templates/parachain}/node/src/service.rs (100%) rename {cumulus/parachain-template => templates/parachain}/pallets/template/Cargo.toml (68%) rename {substrate/bin/node-template => templates/parachain}/pallets/template/README.md (100%) rename {substrate/bin/node-template => templates/parachain}/pallets/template/src/benchmarking.rs (100%) rename {cumulus/parachain-template => templates/parachain}/pallets/template/src/lib.rs (96%) rename {cumulus/parachain-template => templates/parachain}/pallets/template/src/mock.rs (98%) rename {cumulus/parachain-template => templates/parachain}/pallets/template/src/tests.rs (100%) rename {substrate/bin/node-template => templates/parachain}/pallets/template/src/weights.rs (100%) rename {cumulus/parachain-template => templates/parachain}/polkadot-launch/config.json (100%) rename {cumulus/parachain-template => templates/parachain}/runtime/Cargo.toml (82%) rename {cumulus/parachain-template => templates/parachain}/runtime/build.rs (100%) rename {cumulus/parachain-template => templates/parachain}/runtime/src/lib.rs (99%) rename {cumulus/parachain-template => templates/parachain}/runtime/src/weights/block_weights.rs (100%) rename {cumulus/parachain-template => templates/parachain}/runtime/src/weights/extrinsic_weights.rs (100%) rename {cumulus/parachain-template => templates/parachain}/runtime/src/weights/mod.rs (100%) rename {cumulus/parachain-template => templates/parachain}/runtime/src/weights/paritydb_weights.rs (100%) rename {cumulus/parachain-template => templates/parachain}/runtime/src/weights/rocksdb_weights.rs (100%) rename {cumulus/parachain-template => templates/parachain}/runtime/src/xcm_config.rs (100%) rename {substrate/bin/node-template => templates/solochain}/LICENSE (100%) rename {substrate/bin/node-template => templates/solochain}/README.md (100%) rename {substrate/bin/node-template => templates/solochain}/docs/rust-setup.md (100%) rename {substrate/bin/node-template => templates/solochain}/env-setup/README.md (100%) rename {substrate/bin/node-template => templates/solochain}/env-setup/flake.lock (100%) rename {substrate/bin/node-template => templates/solochain}/env-setup/flake.nix (100%) rename {substrate/bin/node-template => templates/solochain}/env-setup/rust-toolchain.toml (100%) create mode 100644 templates/solochain/node/Cargo.toml rename {substrate/bin/node-template => templates/solochain}/node/build.rs (100%) rename {substrate/bin/node-template => templates/solochain}/node/src/benchmarking.rs (99%) rename {substrate/bin/node-template => templates/solochain}/node/src/chain_spec.rs (97%) rename {substrate/bin/node-template => templates/solochain}/node/src/cli.rs (100%) rename {substrate/bin/node-template => templates/solochain}/node/src/command.rs (98%) rename {substrate/bin/node-template => templates/solochain}/node/src/main.rs (100%) rename {substrate/bin/node-template => templates/solochain}/node/src/rpc.rs (96%) rename {substrate/bin/node-template => templates/solochain}/node/src/service.rs (99%) rename {substrate/bin/node-template => templates/solochain}/pallets/template/Cargo.toml (55%) create mode 100644 templates/solochain/pallets/template/README.md create mode 100644 templates/solochain/pallets/template/src/benchmarking.rs rename {substrate/bin/node-template => templates/solochain}/pallets/template/src/lib.rs (100%) rename {substrate/bin/node-template => templates/solochain}/pallets/template/src/mock.rs (100%) rename {substrate/bin/node-template => templates/solochain}/pallets/template/src/tests.rs (100%) create mode 100644 templates/solochain/pallets/template/src/weights.rs create mode 100644 templates/solochain/runtime/Cargo.toml rename {substrate/bin/node-template => templates/solochain}/runtime/build.rs (100%) rename {substrate/bin/node-template => templates/solochain}/runtime/src/lib.rs (98%) diff --git a/.github/scripts/check-workspace.py b/.github/scripts/check-workspace.py index d200122fee9..1f8f103e4e1 100644 --- a/.github/scripts/check-workspace.py +++ b/.github/scripts/check-workspace.py @@ -18,7 +18,7 @@ def parse_args(): parser.add_argument('workspace_dir', help='The directory to check', metavar='workspace_dir', type=str, nargs=1) parser.add_argument('--exclude', help='Exclude crate paths from the check', metavar='exclude', type=str, nargs='*', default=[]) - + args = parser.parse_args() return (args.workspace_dir[0], args.exclude) @@ -26,7 +26,7 @@ def main(root, exclude): workspace_crates = get_members(root, exclude) all_crates = get_crates(root, exclude) print(f'📦 Found {len(all_crates)} crates in total') - + check_duplicates(workspace_crates) check_missing(workspace_crates, all_crates) check_links(all_crates) @@ -48,14 +48,14 @@ def get_members(workspace_dir, exclude): if not 'members' in root_manifest['workspace']: return [] - + members = [] for member in root_manifest['workspace']['members']: if member in exclude: print(f'❌ Excluded member should not appear in the workspace {member}') sys.exit(1) members.append(member) - + return members # List all members of the workspace. @@ -74,12 +74,12 @@ def get_crates(workspace_dir, exclude_crates) -> dict: with open(path, "r") as f: content = f.read() manifest = toml.loads(content) - + if 'workspace' in manifest: if root != workspace_dir: print("⏩ Excluded recursive workspace at %s" % path) continue - + # Cut off the root path and the trailing /Cargo.toml. path = path[len(workspace_dir)+1:-11] name = manifest['package']['name'] @@ -87,7 +87,7 @@ def get_crates(workspace_dir, exclude_crates) -> dict: print("⏩ Excluded crate %s at %s" % (name, path)) continue crates[name] = (path, manifest) - + return crates # Check that there are no duplicate entries in the workspace. @@ -138,23 +138,23 @@ def check_links(all_crates): if not 'path' in deps[dep]: broken.append((name, dep_name, "crate must be linked via `path`")) return - + def check_crate(deps): to_checks = ['dependencies', 'dev-dependencies', 'build-dependencies'] for to_check in to_checks: if to_check in deps: check_deps(deps[to_check]) - + # There could possibly target dependant deps: if 'target' in manifest: # Target dependant deps can only have one level of nesting: for _, target in manifest['target'].items(): check_crate(target) - + check_crate(manifest) - + links.sort() broken.sort() diff --git a/.github/workflows/check-licenses.yml b/.github/workflows/check-licenses.yml index e1e92d288ce..c32b6fcf89e 100644 --- a/.github/workflows/check-licenses.yml +++ b/.github/workflows/check-licenses.yml @@ -42,5 +42,4 @@ jobs: shopt -s globstar npx @paritytech/license-scanner scan \ --ensure-licenses ${{ env.LICENSES }} \ - --exclude ./substrate/bin/node-template \ -- ./substrate/**/*.rs diff --git a/.gitlab/pipeline/build.yml b/.gitlab/pipeline/build.yml index 423587c1fb5..f8de6135572 100644 --- a/.gitlab/pipeline/build.yml +++ b/.gitlab/pipeline/build.yml @@ -337,7 +337,7 @@ build-runtimes-polkavm: - .common-refs - .run-immediately script: - - SUBSTRATE_RUNTIME_TARGET=riscv cargo check -p minimal-runtime + - SUBSTRATE_RUNTIME_TARGET=riscv cargo check -p minimal-template-runtime - SUBSTRATE_RUNTIME_TARGET=riscv cargo check -p westend-runtime - SUBSTRATE_RUNTIME_TARGET=riscv cargo check -p rococo-runtime - SUBSTRATE_RUNTIME_TARGET=riscv cargo check -p polkadot-test-runtime diff --git a/Cargo.lock b/Cargo.lock index d262c1795a6..26e134448ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8172,15 +8172,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] -name = "minimal-node" -version = "4.0.0-dev" +name = "minimal-template-node" +version = "0.0.0" dependencies = [ "clap 4.5.1", "frame", "futures", "futures-timer", "jsonrpsee", - "minimal-runtime", + "minimal-template-runtime", "sc-basic-authorship", "sc-cli", "sc-client-api", @@ -8207,12 +8207,12 @@ dependencies = [ ] [[package]] -name = "minimal-runtime" -version = "0.1.0" +name = "minimal-template-runtime" +version = "0.0.0" dependencies = [ "frame", - "frame-support", "pallet-balances", + "pallet-minimal-template", "pallet-sudo", "pallet-timestamp", "pallet-transaction-payment", @@ -8726,50 +8726,6 @@ dependencies = [ "kitchensink-runtime", ] -[[package]] -name = "node-template" -version = "4.0.0-dev" -dependencies = [ - "clap 4.5.1", - "frame-benchmarking", - "frame-benchmarking-cli", - "frame-system", - "futures", - "jsonrpsee", - "node-template-runtime", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc", - "sc-basic-authorship", - "sc-cli", - "sc-client-api", - "sc-consensus", - "sc-consensus-aura", - "sc-consensus-grandpa", - "sc-executor", - "sc-network", - "sc-offchain", - "sc-rpc-api", - "sc-service", - "sc-telemetry", - "sc-transaction-pool", - "sc-transaction-pool-api", - "serde_json", - "sp-api", - "sp-block-builder", - "sp-blockchain", - "sp-consensus-aura", - "sp-consensus-grandpa", - "sp-core", - "sp-inherents", - "sp-io", - "sp-keyring", - "sp-runtime", - "sp-timestamp", - "substrate-build-script-utils", - "substrate-frame-rpc-system", - "try-runtime-cli", -] - [[package]] name = "node-template-release" version = "3.0.0" @@ -8784,45 +8740,6 @@ dependencies = [ "toml_edit 0.19.15", ] -[[package]] -name = "node-template-runtime" -version = "4.0.0-dev" -dependencies = [ - "frame-benchmarking", - "frame-executive", - "frame-support", - "frame-system", - "frame-system-benchmarking", - "frame-system-rpc-runtime-api", - "frame-try-runtime", - "pallet-aura", - "pallet-balances", - "pallet-grandpa", - "pallet-sudo", - "pallet-template", - "pallet-timestamp", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc-runtime-api", - "parity-scale-codec", - "scale-info", - "serde_json", - "sp-api", - "sp-block-builder", - "sp-consensus-aura", - "sp-consensus-grandpa", - "sp-core", - "sp-genesis-builder", - "sp-inherents", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-std 14.0.0", - "sp-storage 19.0.0", - "sp-transaction-pool", - "sp-version", - "substrate-wasm-builder", -] - [[package]] name = "node-testing" version = "3.0.0-dev" @@ -10302,6 +10219,15 @@ dependencies = [ "sp-version", ] +[[package]] +name = "pallet-minimal-template" +version = "0.0.0" +dependencies = [ + "frame", + "parity-scale-codec", + "scale-info", +] + [[package]] name = "pallet-mixnet" version = "0.4.0" @@ -10603,14 +10529,13 @@ dependencies = [ [[package]] name = "pallet-parachain-template" -version = "0.7.0" +version = "0.0.0" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", "parity-scale-codec", "scale-info", - "serde", "sp-core", "sp-io", "sp-runtime", @@ -11065,7 +10990,7 @@ dependencies = [ [[package]] name = "pallet-template" -version = "4.0.0-dev" +version = "0.0.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -11075,7 +11000,6 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std 14.0.0", ] [[package]] @@ -11389,7 +11313,7 @@ dependencies = [ [[package]] name = "parachain-template-node" -version = "0.1.0" +version = "0.0.0" dependencies = [ "clap 4.5.1", "color-print", @@ -11447,7 +11371,7 @@ dependencies = [ [[package]] name = "parachain-template-runtime" -version = "0.7.0" +version = "0.0.0" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", @@ -18356,6 +18280,87 @@ dependencies = [ "sha-1 0.9.8", ] +[[package]] +name = "solochain-template-node" +version = "0.0.0" +dependencies = [ + "clap 4.5.1", + "frame-benchmarking-cli", + "frame-system", + "futures", + "jsonrpsee", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc", + "sc-basic-authorship", + "sc-cli", + "sc-client-api", + "sc-consensus", + "sc-consensus-aura", + "sc-consensus-grandpa", + "sc-executor", + "sc-network", + "sc-offchain", + "sc-rpc-api", + "sc-service", + "sc-telemetry", + "sc-transaction-pool", + "sc-transaction-pool-api", + "serde_json", + "solochain-template-runtime", + "sp-api", + "sp-block-builder", + "sp-blockchain", + "sp-consensus-aura", + "sp-consensus-grandpa", + "sp-core", + "sp-inherents", + "sp-io", + "sp-keyring", + "sp-runtime", + "sp-timestamp", + "substrate-build-script-utils", + "substrate-frame-rpc-system", + "try-runtime-cli", +] + +[[package]] +name = "solochain-template-runtime" +version = "0.0.0" +dependencies = [ + "frame-benchmarking", + "frame-executive", + "frame-support", + "frame-system", + "frame-system-benchmarking", + "frame-system-rpc-runtime-api", + "frame-try-runtime", + "pallet-aura", + "pallet-balances", + "pallet-grandpa", + "pallet-sudo", + "pallet-template", + "pallet-timestamp", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-block-builder", + "sp-consensus-aura", + "sp-consensus-grandpa", + "sp-core", + "sp-genesis-builder", + "sp-inherents", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-std 14.0.0", + "sp-storage 19.0.0", + "sp-transaction-pool", + "sp-version", + "substrate-wasm-builder", +] + [[package]] name = "sp-api" version = "26.0.0" diff --git a/Cargo.toml b/Cargo.toml index 48aa25f5c5a..a2e22e0b927 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ authors = ["Parity Technologies "] edition = "2021" repository = "https://github.com/paritytech/polkadot-sdk.git" license = "GPL-3.0-only" +homepage = "https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/index.html" [workspace] resolver = "2" @@ -74,9 +75,6 @@ members = [ "cumulus/pallets/solo-to-para", "cumulus/pallets/xcm", "cumulus/pallets/xcmp-queue", - "cumulus/parachain-template/node", - "cumulus/parachain-template/pallets/template", - "cumulus/parachain-template/runtime", "cumulus/parachains/common", "cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo", "cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-westend", @@ -219,11 +217,6 @@ members = [ "polkadot/xcm/xcm-simulator", "polkadot/xcm/xcm-simulator/example", "polkadot/xcm/xcm-simulator/fuzzer", - "substrate/bin/minimal/node", - "substrate/bin/minimal/runtime", - "substrate/bin/node-template/node", - "substrate/bin/node-template/pallets/template", - "substrate/bin/node-template/runtime", "substrate/bin/node/bench", "substrate/bin/node/cli", "substrate/bin/node/inspect", @@ -504,6 +497,18 @@ members = [ "substrate/utils/frame/try-runtime/cli", "substrate/utils/prometheus", "substrate/utils/wasm-builder", + + "templates/minimal/node", + "templates/minimal/pallets/template", + "templates/minimal/runtime", + + "templates/solochain/node", + "templates/solochain/pallets/template", + "templates/solochain/runtime", + + "templates/parachain/node", + "templates/parachain/pallets/template", + "templates/parachain/runtime", ] default-members = ["polkadot", "substrate/bin/node/cli"] diff --git a/cumulus/parachain-template/pallets/template/README.md b/cumulus/parachain-template/pallets/template/README.md deleted file mode 100644 index 5a646123346..00000000000 --- a/cumulus/parachain-template/pallets/template/README.md +++ /dev/null @@ -1 +0,0 @@ -License: Unlicense diff --git a/cumulus/parachain-template/pallets/template/src/benchmarking.rs b/cumulus/parachain-template/pallets/template/src/benchmarking.rs deleted file mode 100644 index 8bba2a09867..00000000000 --- a/cumulus/parachain-template/pallets/template/src/benchmarking.rs +++ /dev/null @@ -1,20 +0,0 @@ -//! Benchmarking setup for pallet-parachain-template - -use super::*; - -#[allow(unused)] -use crate::Pallet as Template; -use frame_benchmarking::{benchmarks, impl_benchmark_test_suite, whitelisted_caller}; -use frame_system::RawOrigin; - -benchmarks! { - do_something { - let s in 0 .. 100; - let caller: T::AccountId = whitelisted_caller(); - }: _(RawOrigin::Signed(caller), s) - verify { - assert_eq!(Something::::get(), Some(s)); - } -} - -impl_benchmark_test_suite!(Template, crate::mock::new_test_ext(), crate::mock::Test,); diff --git a/prdoc/pr_3460.prdoc b/prdoc/pr_3460.prdoc new file mode 100644 index 00000000000..1f16fe08908 --- /dev/null +++ b/prdoc/pr_3460.prdoc @@ -0,0 +1,26 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Repot all templates + +doc: + - audience: Runtime Dev + description: | + This PR moves all templates into a single folder in the polkadot-sdk repo (`/templates`) and + unifies their crate names as well. Most notably, the crate name for what was formerly known + as `node-template` is no `solochain-template-node`. The other two crates in the template are + consequently called: `solochain-runtime-template` and `pallet-solochain-template`. + The other two template crate names follow a similar patter, just replacing `solochain` with + `parachain` or `minimal`. + + This PR is part of a bigger step toward automating the template repositories, see the + following: https://github.com/paritytech/polkadot-sdk/issues/3155 + +# the following crates are removed and renamed, although none are released. +crates: + - name: minimal-template-runtime # formerly called minimal-runtime + - name: minimal-template-node # formerly called minimal-node + - name: solochain-template-node # formerly called node-template + - name: solochain-template-runtime # formerly called node-template-runtime + - name: parachain-template-runtime # formerly called parachain-runtime + - name: parachain-template-runtime # formerly called parachain-node diff --git a/substrate/bin/minimal/node/Cargo.toml b/substrate/bin/minimal/node/Cargo.toml deleted file mode 100644 index 65644861c9a..00000000000 --- a/substrate/bin/minimal/node/Cargo.toml +++ /dev/null @@ -1,60 +0,0 @@ -[package] -name = "minimal-node" -version = "4.0.0-dev" -description = "A fresh FRAME-based Substrate node, ready for hacking." -authors = ["Substrate DevHub "] -homepage = "https://substrate.io/" -edition = "2021" -license = "MIT-0" -publish = false -repository = "https://github.com/substrate-developer-hub/substrate-node-template/" -build = "build.rs" - -[lints] -workspace = true - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[[bin]] -name = "minimal-node" - -[dependencies] -clap = { version = "4.5.1", features = ["derive"] } -futures = { version = "0.3.21", features = ["thread-pool"] } -futures-timer = "3.0.1" -jsonrpsee = { version = "0.22", features = ["server"] } -serde_json = { workspace = true, default-features = true } - -sc-cli = { path = "../../../client/cli" } -sc-executor = { path = "../../../client/executor" } -sc-network = { path = "../../../client/network" } -sc-service = { path = "../../../client/service" } -sc-telemetry = { path = "../../../client/telemetry" } -sc-transaction-pool = { path = "../../../client/transaction-pool" } -sc-transaction-pool-api = { path = "../../../client/transaction-pool/api" } -sc-consensus = { path = "../../../client/consensus/common" } -sc-consensus-manual-seal = { path = "../../../client/consensus/manual-seal" } -sc-rpc-api = { path = "../../../client/rpc-api" } -sc-basic-authorship = { path = "../../../client/basic-authorship" } -sc-offchain = { path = "../../../client/offchain" } -sc-client-api = { path = "../../../client/api" } - -sp-timestamp = { path = "../../../primitives/timestamp" } -sp-keyring = { path = "../../../primitives/keyring" } -sp-api = { path = "../../../primitives/api" } -sp-blockchain = { path = "../../../primitives/blockchain" } -sp-block-builder = { path = "../../../primitives/block-builder" } -sp-io = { path = "../../../primitives/io" } -sp-runtime = { path = "../../../primitives/runtime" } - -substrate-frame-rpc-system = { path = "../../../utils/frame/rpc/system" } - -frame = { path = "../../../frame", features = ["experimental", "runtime"] } -runtime = { package = "minimal-runtime", path = "../runtime" } - -[build-dependencies] -substrate-build-script-utils = { path = "../../../utils/build-script-utils" } - -[features] -default = [] diff --git a/substrate/bin/minimal/runtime/Cargo.toml b/substrate/bin/minimal/runtime/Cargo.toml deleted file mode 100644 index 296106544bb..00000000000 --- a/substrate/bin/minimal/runtime/Cargo.toml +++ /dev/null @@ -1,50 +0,0 @@ -[package] -name = "minimal-runtime" -version = "0.1.0" -authors.workspace = true -description = "A minimal Substrate example runtime" -edition.workspace = true -repository.workspace = true -license.workspace = true -publish = false - -[lints] -workspace = true - -[dependencies] -parity-scale-codec = { version = "3.0.0", default-features = false } -scale-info = { version = "2.6.0", default-features = false } - -# this is a frame-based runtime, thus importing `frame` with runtime feature enabled. -frame = { path = "../../../frame", default-features = false, features = ["experimental", "runtime"] } -frame-support = { path = "../../../frame/support", default-features = false } - -# pallets that we want to use -pallet-balances = { path = "../../../frame/balances", default-features = false } -pallet-sudo = { path = "../../../frame/sudo", default-features = false } -pallet-timestamp = { path = "../../../frame/timestamp", default-features = false } -pallet-transaction-payment = { path = "../../../frame/transaction-payment", default-features = false } -pallet-transaction-payment-rpc-runtime-api = { path = "../../../frame/transaction-payment/rpc/runtime-api", default-features = false } - -# genesis builder that allows us to interacto with runtime genesis config -sp-genesis-builder = { path = "../../../primitives/genesis-builder", default-features = false } - - -[build-dependencies] -substrate-wasm-builder = { path = "../../../utils/wasm-builder", optional = true } - -[features] -default = ["std"] -std = [ - "frame-support/std", - "frame/std", - "pallet-balances/std", - "pallet-sudo/std", - "pallet-timestamp/std", - "pallet-transaction-payment-rpc-runtime-api/std", - "pallet-transaction-payment/std", - "parity-scale-codec/std", - "scale-info/std", - "sp-genesis-builder/std", - "substrate-wasm-builder", -] diff --git a/substrate/bin/node-template/.editorconfig b/substrate/bin/node-template/.editorconfig deleted file mode 100644 index 5adac74ca24..00000000000 --- a/substrate/bin/node-template/.editorconfig +++ /dev/null @@ -1,16 +0,0 @@ -root = true - -[*] -indent_style=space -indent_size=2 -tab_width=2 -end_of_line=lf -charset=utf-8 -trim_trailing_whitespace=true -insert_final_newline = true - -[*.{rs,toml}] -indent_style=tab -indent_size=tab -tab_width=4 -max_line_length=100 diff --git a/substrate/bin/node-template/env-setup/.envrc b/substrate/bin/node-template/env-setup/.envrc deleted file mode 100644 index 3550a30f2de..00000000000 --- a/substrate/bin/node-template/env-setup/.envrc +++ /dev/null @@ -1 +0,0 @@ -use flake diff --git a/substrate/bin/node-template/node/Cargo.toml b/substrate/bin/node-template/node/Cargo.toml deleted file mode 100644 index 2f31947e492..00000000000 --- a/substrate/bin/node-template/node/Cargo.toml +++ /dev/null @@ -1,93 +0,0 @@ -[package] -name = "node-template" -version = "4.0.0-dev" -description = "A fresh FRAME-based Substrate node, ready for hacking." -authors = ["Substrate DevHub "] -homepage = "https://substrate.io/" -edition.workspace = true -license = "MIT-0" -publish = false -repository = "https://github.com/substrate-developer-hub/substrate-node-template/" -build = "build.rs" - -[lints] -workspace = true - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[[bin]] -name = "node-template" - -[dependencies] -clap = { version = "4.5.1", features = ["derive"] } -futures = { version = "0.3.21", features = ["thread-pool"] } -serde_json = { workspace = true, default-features = true } - -sc-cli = { path = "../../../client/cli" } -sp-core = { path = "../../../primitives/core" } -sc-executor = { path = "../../../client/executor" } -sc-network = { path = "../../../client/network" } -sc-service = { path = "../../../client/service" } -sc-telemetry = { path = "../../../client/telemetry" } -sc-transaction-pool = { path = "../../../client/transaction-pool" } -sc-transaction-pool-api = { path = "../../../client/transaction-pool/api" } -sc-offchain = { path = "../../../client/offchain" } -sc-consensus-aura = { path = "../../../client/consensus/aura" } -sp-consensus-aura = { path = "../../../primitives/consensus/aura" } -sc-consensus = { path = "../../../client/consensus/common" } -sc-consensus-grandpa = { path = "../../../client/consensus/grandpa" } -sp-consensus-grandpa = { path = "../../../primitives/consensus/grandpa" } -sc-client-api = { path = "../../../client/api" } -sp-runtime = { path = "../../../primitives/runtime" } -sp-io = { path = "../../../primitives/io" } -sp-timestamp = { path = "../../../primitives/timestamp" } -sp-inherents = { path = "../../../primitives/inherents" } -sp-keyring = { path = "../../../primitives/keyring" } -frame-system = { path = "../../../frame/system" } -pallet-transaction-payment = { path = "../../../frame/transaction-payment", default-features = false } - -# These dependencies are used for the node template's RPCs -jsonrpsee = { version = "0.22", features = ["server"] } -sp-api = { path = "../../../primitives/api" } -sc-rpc-api = { path = "../../../client/rpc-api" } -sp-blockchain = { path = "../../../primitives/blockchain" } -sp-block-builder = { path = "../../../primitives/block-builder" } -sc-basic-authorship = { path = "../../../client/basic-authorship" } -substrate-frame-rpc-system = { path = "../../../utils/frame/rpc/system" } -pallet-transaction-payment-rpc = { path = "../../../frame/transaction-payment/rpc" } - -# These dependencies are used for runtime benchmarking -frame-benchmarking = { path = "../../../frame/benchmarking" } -frame-benchmarking-cli = { path = "../../../utils/frame/benchmarking-cli" } - -# Local Dependencies -node-template-runtime = { path = "../runtime" } - -# CLI-specific dependencies -try-runtime-cli = { path = "../../../utils/frame/try-runtime/cli", optional = true } - -[build-dependencies] -substrate-build-script-utils = { path = "../../../utils/build-script-utils" } - -[features] -default = [] -# Dependencies that are only required if runtime benchmarking should be build. -runtime-benchmarks = [ - "frame-benchmarking-cli/runtime-benchmarks", - "frame-benchmarking/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "node-template-runtime/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", - "sc-service/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", -] -# Enable features that allow the runtime to be tried and debugged. Name might be subject to change -# in the near future. -try-runtime = [ - "frame-system/try-runtime", - "node-template-runtime/try-runtime", - "pallet-transaction-payment/try-runtime", - "sp-runtime/try-runtime", - "try-runtime-cli/try-runtime", -] diff --git a/substrate/bin/node-template/runtime/Cargo.toml b/substrate/bin/node-template/runtime/Cargo.toml deleted file mode 100644 index c7cffa568db..00000000000 --- a/substrate/bin/node-template/runtime/Cargo.toml +++ /dev/null @@ -1,126 +0,0 @@ -[package] -name = "node-template-runtime" -version = "4.0.0-dev" -description = "A fresh FRAME-based Substrate node, ready for hacking." -authors = ["Substrate DevHub "] -homepage = "https://substrate.io/" -edition.workspace = true -license = "MIT-0" -publish = false -repository = "https://github.com/substrate-developer-hub/substrate-node-template/" - -[lints] -workspace = true - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } -scale-info = { version = "2.10.0", default-features = false, features = ["derive", "serde"] } - -pallet-aura = { path = "../../../frame/aura", default-features = false } -pallet-balances = { path = "../../../frame/balances", default-features = false } -frame-support = { path = "../../../frame/support", default-features = false } -pallet-grandpa = { path = "../../../frame/grandpa", default-features = false } -pallet-sudo = { path = "../../../frame/sudo", default-features = false } -frame-system = { path = "../../../frame/system", default-features = false } -frame-try-runtime = { path = "../../../frame/try-runtime", default-features = false, optional = true } -pallet-timestamp = { path = "../../../frame/timestamp", default-features = false } -pallet-transaction-payment = { path = "../../../frame/transaction-payment", default-features = false } -frame-executive = { path = "../../../frame/executive", default-features = false } -sp-api = { path = "../../../primitives/api", default-features = false } -sp-block-builder = { path = "../../../primitives/block-builder", default-features = false } -sp-consensus-aura = { path = "../../../primitives/consensus/aura", default-features = false, features = ["serde"] } -sp-consensus-grandpa = { path = "../../../primitives/consensus/grandpa", default-features = false, features = ["serde"] } -sp-core = { path = "../../../primitives/core", default-features = false, features = ["serde"] } -sp-inherents = { path = "../../../primitives/inherents", default-features = false } -sp-offchain = { path = "../../../primitives/offchain", default-features = false } -sp-runtime = { path = "../../../primitives/runtime", default-features = false, features = ["serde"] } -sp-session = { path = "../../../primitives/session", default-features = false } -sp-std = { path = "../../../primitives/std", default-features = false } -sp-storage = { path = "../../../primitives/storage", default-features = false } -sp-transaction-pool = { path = "../../../primitives/transaction-pool", default-features = false } -sp-version = { path = "../../../primitives/version", default-features = false, features = ["serde"] } -serde_json = { features = ["alloc"], workspace = true } -sp-genesis-builder = { default-features = false, path = "../../../primitives/genesis-builder" } - -# Used for the node template's RPCs -frame-system-rpc-runtime-api = { path = "../../../frame/system/rpc/runtime-api", default-features = false } -pallet-transaction-payment-rpc-runtime-api = { path = "../../../frame/transaction-payment/rpc/runtime-api", default-features = false } - -# Used for runtime benchmarking -frame-benchmarking = { path = "../../../frame/benchmarking", default-features = false, optional = true } -frame-system-benchmarking = { path = "../../../frame/system/benchmarking", default-features = false, optional = true } - -# Local Dependencies -pallet-template = { path = "../pallets/template", default-features = false } - -[build-dependencies] -substrate-wasm-builder = { path = "../../../utils/wasm-builder", optional = true } - -[features] -default = ["std"] -std = [ - "codec/std", - "frame-benchmarking?/std", - "frame-executive/std", - "frame-support/std", - "frame-system-benchmarking?/std", - "frame-system-rpc-runtime-api/std", - "frame-system/std", - "frame-try-runtime?/std", - "pallet-aura/std", - "pallet-balances/std", - "pallet-grandpa/std", - "pallet-sudo/std", - "pallet-template/std", - "pallet-timestamp/std", - "pallet-transaction-payment-rpc-runtime-api/std", - "pallet-transaction-payment/std", - "scale-info/std", - "serde_json/std", - "sp-api/std", - "sp-block-builder/std", - "sp-consensus-aura/std", - "sp-consensus-grandpa/std", - "sp-core/std", - "sp-genesis-builder/std", - "sp-inherents/std", - "sp-offchain/std", - "sp-runtime/std", - "sp-session/std", - "sp-std/std", - "sp-storage/std", - "sp-transaction-pool/std", - "sp-version/std", - "substrate-wasm-builder", -] -runtime-benchmarks = [ - "frame-benchmarking/runtime-benchmarks", - "frame-support/runtime-benchmarks", - "frame-system-benchmarking/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "pallet-balances/runtime-benchmarks", - "pallet-grandpa/runtime-benchmarks", - "pallet-sudo/runtime-benchmarks", - "pallet-template/runtime-benchmarks", - "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", -] -try-runtime = [ - "frame-executive/try-runtime", - "frame-support/try-runtime", - "frame-system/try-runtime", - "frame-try-runtime/try-runtime", - "pallet-aura/try-runtime", - "pallet-balances/try-runtime", - "pallet-grandpa/try-runtime", - "pallet-sudo/try-runtime", - "pallet-template/try-runtime", - "pallet-timestamp/try-runtime", - "pallet-transaction-payment/try-runtime", - "sp-runtime/try-runtime", -] -experimental = ["pallet-aura/experimental"] diff --git a/substrate/frame/Cargo.toml b/substrate/frame/Cargo.toml index 3f148bf4c83..6746723e72f 100644 --- a/substrate/frame/Cargo.toml +++ b/substrate/frame/Cargo.toml @@ -19,8 +19,12 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] # external deps -parity-scale-codec = { version = "3.2.2", default-features = false, features = ["derive"] } -scale-info = { version = "2.6.0", default-features = false, features = ["derive"] } +parity-scale-codec = { version = "3.2.2", default-features = false, features = [ + "derive", +] } +scale-info = { version = "2.6.0", default-features = false, features = [ + "derive", +] } # primitive deps, used for developing FRAME pallets. sp-runtime = { default-features = false, path = "../primitives/runtime" } @@ -57,8 +61,6 @@ pallet-examples = { path = "./examples" } default = ["runtime", "std"] experimental = ["frame-support/experimental"] runtime = [ - "frame-executive", - "frame-system-rpc-runtime-api", "sp-api", "sp-block-builder", "sp-consensus-aura", @@ -68,6 +70,9 @@ runtime = [ "sp-session", "sp-transaction-pool", "sp-version", + + "frame-executive", + "frame-system-rpc-runtime-api", ] std = [ "frame-executive?/std", diff --git a/substrate/frame/examples/default-config/src/lib.rs b/substrate/frame/examples/default-config/src/lib.rs index 69eca055965..224faf9dfd4 100644 --- a/substrate/frame/examples/default-config/src/lib.rs +++ b/substrate/frame/examples/default-config/src/lib.rs @@ -108,7 +108,7 @@ pub mod pallet { } /// A type providing default configurations for this pallet in another environment. Examples - /// could be a parachain, or a solo-chain. + /// could be a parachain, or a solochain. /// /// Appropriate derive for `frame_system::DefaultConfig` needs to be provided. In this /// example, we simple derive `frame_system::config_preludes::TestDefaultConfig` again. diff --git a/substrate/frame/system/src/lib.rs b/substrate/frame/system/src/lib.rs index 21393cb3e20..0318f77342e 100644 --- a/substrate/frame/system/src/lib.rs +++ b/substrate/frame/system/src/lib.rs @@ -310,7 +310,7 @@ pub mod pallet { type PostTransactions = (); } - /// Default configurations of this pallet in a solo-chain environment. + /// Default configurations of this pallet in a solochain environment. /// /// ## Considerations: /// diff --git a/templates/minimal/README.md b/templates/minimal/README.md new file mode 100644 index 00000000000..e69de29bb2d diff --git a/templates/minimal/node/Cargo.toml b/templates/minimal/node/Cargo.toml new file mode 100644 index 00000000000..410cfc9f6c3 --- /dev/null +++ b/templates/minimal/node/Cargo.toml @@ -0,0 +1,62 @@ +[package] +name = "minimal-template-node" +description = "A miniaml Substrate-based Substrate node, ready for hacking." +version = "0.0.0" +license = "MIT-0" +authors.workspace = true +homepage.workspace = true +repository.workspace = true +edition.workspace = true +publish = false +build = "build.rs" + +[lints] +workspace = true + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +clap = { version = "4.5.1", features = ["derive"] } +futures = { version = "0.3.21", features = ["thread-pool"] } +futures-timer = "3.0.1" +jsonrpsee = { version = "0.22", features = ["server"] } +serde_json = { workspace = true, default-features = true } + +sc-cli = { path = "../../../substrate/client/cli" } +sc-executor = { path = "../../../substrate/client/executor" } +sc-network = { path = "../../../substrate/client/network" } +sc-service = { path = "../../../substrate/client/service" } +sc-telemetry = { path = "../../../substrate/client/telemetry" } +sc-transaction-pool = { path = "../../../substrate/client/transaction-pool" } +sc-transaction-pool-api = { path = "../../../substrate/client/transaction-pool/api" } +sc-consensus = { path = "../../../substrate/client/consensus/common" } +sc-consensus-manual-seal = { path = "../../../substrate/client/consensus/manual-seal" } +sc-rpc-api = { path = "../../../substrate/client/rpc-api" } +sc-basic-authorship = { path = "../../../substrate/client/basic-authorship" } +sc-offchain = { path = "../../../substrate/client/offchain" } +sc-client-api = { path = "../../../substrate/client/api" } + +sp-timestamp = { path = "../../../substrate/primitives/timestamp" } +sp-keyring = { path = "../../../substrate/primitives/keyring" } +sp-api = { path = "../../../substrate/primitives/api" } +sp-blockchain = { path = "../../../substrate/primitives/blockchain" } +sp-block-builder = { path = "../../../substrate/primitives/block-builder" } +sp-io = { path = "../../../substrate/primitives/io" } +sp-runtime = { path = "../../../substrate/primitives/runtime" } + +substrate-frame-rpc-system = { path = "../../../substrate/utils/frame/rpc/system" } + +# Once the native runtime is gone, there should be little to no dependency on FRAME here, and +# certainly no dependency on the runtime. +frame = { path = "../../../substrate/frame", features = [ + "experimental", + "runtime", +] } +runtime = { package = "minimal-template-runtime", path = "../runtime" } + +[build-dependencies] +substrate-build-script-utils = { path = "../../../substrate/utils/build-script-utils" } + +[features] +default = [] diff --git a/substrate/bin/minimal/node/build.rs b/templates/minimal/node/build.rs similarity index 100% rename from substrate/bin/minimal/node/build.rs rename to templates/minimal/node/build.rs diff --git a/substrate/bin/minimal/node/src/chain_spec.rs b/templates/minimal/node/src/chain_spec.rs similarity index 100% rename from substrate/bin/minimal/node/src/chain_spec.rs rename to templates/minimal/node/src/chain_spec.rs diff --git a/substrate/bin/minimal/node/src/cli.rs b/templates/minimal/node/src/cli.rs similarity index 100% rename from substrate/bin/minimal/node/src/cli.rs rename to templates/minimal/node/src/cli.rs diff --git a/substrate/bin/minimal/node/src/command.rs b/templates/minimal/node/src/command.rs similarity index 100% rename from substrate/bin/minimal/node/src/command.rs rename to templates/minimal/node/src/command.rs diff --git a/substrate/bin/minimal/node/src/lib.rs b/templates/minimal/node/src/lib.rs similarity index 94% rename from substrate/bin/minimal/node/src/lib.rs rename to templates/minimal/node/src/lib.rs index c2065def736..cb8ed3bd209 100644 --- a/substrate/bin/minimal/node/src/lib.rs +++ b/templates/minimal/node/src/lib.rs @@ -1,4 +1,4 @@ -// This file is part of Substrate. +// This file is part of Polkadot Sdk. // Copyright (C) Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 diff --git a/substrate/bin/minimal/node/src/main.rs b/templates/minimal/node/src/main.rs similarity index 100% rename from substrate/bin/minimal/node/src/main.rs rename to templates/minimal/node/src/main.rs diff --git a/substrate/bin/minimal/node/src/rpc.rs b/templates/minimal/node/src/rpc.rs similarity index 100% rename from substrate/bin/minimal/node/src/rpc.rs rename to templates/minimal/node/src/rpc.rs diff --git a/substrate/bin/minimal/node/src/service.rs b/templates/minimal/node/src/service.rs similarity index 100% rename from substrate/bin/minimal/node/src/service.rs rename to templates/minimal/node/src/service.rs diff --git a/templates/minimal/pallets/template/Cargo.toml b/templates/minimal/pallets/template/Cargo.toml new file mode 100644 index 00000000000..9982e5ea53b --- /dev/null +++ b/templates/minimal/pallets/template/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "pallet-minimal-template" +description = "A minimal pallet built with FRAME, part of Polkadot Sdk." +version = "0.0.0" +license = "MIT-0" +authors.workspace = true +homepage.workspace = true +repository.workspace = true +edition.workspace = true +publish = false + +[lints] +workspace = true + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.0.0", features = [ + "derive", +], default-features = false } +scale-info = { version = "2.10.0", default-features = false, features = [ + "derive", +] } +frame = { path = "../../../../substrate/frame", default-features = false, features = [ + "experimental", + "runtime", +] } + + +[features] +default = ["std"] +std = ["codec/std", "frame/std", "scale-info/std"] diff --git a/templates/minimal/pallets/template/src/lib.rs b/templates/minimal/pallets/template/src/lib.rs new file mode 100644 index 00000000000..713f014bbe6 --- /dev/null +++ b/templates/minimal/pallets/template/src/lib.rs @@ -0,0 +1,19 @@ +//! A shell pallet built with [`frame`]. + +#![cfg_attr(not(feature = "std"), no_std)] + +use frame::prelude::*; + +// Re-export all pallet parts, this is needed to properly import the pallet into the runtime. +pub use pallet::*; + +#[frame::pallet] +pub mod pallet { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(_); +} diff --git a/templates/minimal/runtime/Cargo.toml b/templates/minimal/runtime/Cargo.toml new file mode 100644 index 00000000000..20ffb706eb4 --- /dev/null +++ b/templates/minimal/runtime/Cargo.toml @@ -0,0 +1,59 @@ +[package] +name = "minimal-template-runtime" +description = "A solochain runtime template built with Substrate, part of Polkadot Sdk." +version = "0.0.0" +license = "MIT-0" +authors.workspace = true +homepage.workspace = true +repository.workspace = true +edition.workspace = true +publish = false + +[lints] +workspace = true + +[dependencies] +parity-scale-codec = { version = "3.0.0", default-features = false } +scale-info = { version = "2.6.0", default-features = false } + +# this is a frame-based runtime, thus importing `frame` with runtime feature enabled. +frame = { path = "../../../substrate/frame", default-features = false, features = [ + "experimental", + "runtime", +] } + +# pallets that we want to use +pallet-balances = { path = "../../../substrate/frame/balances", default-features = false } +pallet-sudo = { path = "../../../substrate/frame/sudo", default-features = false } +pallet-timestamp = { path = "../../../substrate/frame/timestamp", default-features = false } +pallet-transaction-payment = { path = "../../../substrate/frame/transaction-payment", default-features = false } +pallet-transaction-payment-rpc-runtime-api = { path = "../../../substrate/frame/transaction-payment/rpc/runtime-api", default-features = false } + +# genesis builder that allows us to interacto with runtime genesis config +sp-genesis-builder = { path = "../../../substrate/primitives/genesis-builder", default-features = false } + +# local pallet templates +pallet-minimal-template = { path = "../pallets/template", default-features = false } + +[build-dependencies] +substrate-wasm-builder = { path = "../../../substrate/utils/wasm-builder", optional = true } + +[features] +default = ["std"] +std = [ + "parity-scale-codec/std", + "scale-info/std", + + "frame/std", + + "pallet-balances/std", + "pallet-sudo/std", + "pallet-timestamp/std", + "pallet-transaction-payment-rpc-runtime-api/std", + "pallet-transaction-payment/std", + + "pallet-minimal-template/std", + + "sp-genesis-builder/std", + "substrate-wasm-builder", +] diff --git a/substrate/bin/minimal/runtime/build.rs b/templates/minimal/runtime/build.rs similarity index 100% rename from substrate/bin/minimal/runtime/build.rs rename to templates/minimal/runtime/build.rs diff --git a/substrate/bin/minimal/runtime/src/lib.rs b/templates/minimal/runtime/src/lib.rs similarity index 95% rename from substrate/bin/minimal/runtime/src/lib.rs rename to templates/minimal/runtime/src/lib.rs index d3e8a2e8ec0..6920511e276 100644 --- a/substrate/bin/minimal/runtime/src/lib.rs +++ b/templates/minimal/runtime/src/lib.rs @@ -22,7 +22,10 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); use frame::{ - deps::frame_support::weights::{FixedFee, NoFee}, + deps::frame_support::{ + genesis_builder_helper::{build_config, create_default_config}, + weights::{FixedFee, NoFee}, + }, prelude::*, runtime::{ apis::{ @@ -32,12 +35,11 @@ use frame::{ prelude::*, }, }; -use frame_support::genesis_builder_helper::{build_config, create_default_config}; #[runtime_version] pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: create_runtime_str!("minimal-runtime"), - impl_name: create_runtime_str!("minimal-runtime"), + spec_name: create_runtime_str!("minimal-template-runtime"), + impl_name: create_runtime_str!("minimal-template-runtime"), authoring_version: 1, spec_version: 0, impl_version: 1, @@ -71,6 +73,9 @@ construct_runtime!( Balances: pallet_balances, Sudo: pallet_sudo, TransactionPayment: pallet_transaction_payment, + + // our local pallet + Template: pallet_minimal_template, } ); @@ -104,6 +109,8 @@ impl pallet_transaction_payment::Config for Runtime { type LengthToFee = FixedFee<1, ::Balance>; } +impl pallet_minimal_template::Config for Runtime {} + type Block = frame::runtime::types_common::BlockOf; type Header = HeaderFor; diff --git a/cumulus/parachain-template/LICENSE b/templates/parachain/LICENSE similarity index 100% rename from cumulus/parachain-template/LICENSE rename to templates/parachain/LICENSE diff --git a/cumulus/parachain-template/README.md b/templates/parachain/README.md similarity index 100% rename from cumulus/parachain-template/README.md rename to templates/parachain/README.md diff --git a/cumulus/parachain-template/node/Cargo.toml b/templates/parachain/node/Cargo.toml similarity index 78% rename from cumulus/parachain-template/node/Cargo.toml rename to templates/parachain/node/Cargo.toml index 0ef678c4cba..b4f3a504a4d 100644 --- a/cumulus/parachain-template/node/Cargo.toml +++ b/templates/parachain/node/Cargo.toml @@ -1,18 +1,21 @@ [package] name = "parachain-template-node" -version = "0.1.0" -authors = ["Anonymous"] -description = "A new Cumulus FRAME-based Substrate Node, ready for hacking together a parachain." -license = "Unlicense" -homepage = "https://substrate.io" +description = "A parachain node template built with Substrate and Cumulus, part of Polkadot Sdk." +version = "0.0.0" +license = "MIT-0" +authors.workspace = true +homepage.workspace = true repository.workspace = true edition.workspace = true -build = "build.rs" publish = false +build = "build.rs" [lints] workspace = true +# [[bin]] +# name = "parachain-template-node" + [dependencies] clap = { version = "4.5.1", features = ["derive"] } log = { workspace = true, default-features = true } @@ -63,15 +66,15 @@ polkadot-primitives = { path = "../../../polkadot/primitives" } xcm = { package = "staging-xcm", path = "../../../polkadot/xcm", default-features = false } # Cumulus -cumulus-client-cli = { path = "../../client/cli" } -cumulus-client-collator = { path = "../../client/collator" } -cumulus-client-consensus-aura = { path = "../../client/consensus/aura" } -cumulus-client-consensus-common = { path = "../../client/consensus/common" } -cumulus-client-consensus-proposer = { path = "../../client/consensus/proposer" } -cumulus-client-service = { path = "../../client/service" } -cumulus-primitives-core = { path = "../../primitives/core" } -cumulus-primitives-parachain-inherent = { path = "../../primitives/parachain-inherent" } -cumulus-relay-chain-interface = { path = "../../client/relay-chain-interface" } +cumulus-client-cli = { path = "../../../cumulus/client/cli" } +cumulus-client-collator = { path = "../../../cumulus/client/collator" } +cumulus-client-consensus-aura = { path = "../../../cumulus/client/consensus/aura" } +cumulus-client-consensus-common = { path = "../../../cumulus/client/consensus/common" } +cumulus-client-consensus-proposer = { path = "../../../cumulus/client/consensus/proposer" } +cumulus-client-service = { path = "../../../cumulus/client/service" } +cumulus-primitives-core = { path = "../../../cumulus/primitives/core" } +cumulus-primitives-parachain-inherent = { path = "../../../cumulus/primitives/parachain-inherent" } +cumulus-relay-chain-interface = { path = "../../../cumulus/client/relay-chain-interface" } color-print = "0.3.4" [build-dependencies] diff --git a/cumulus/parachain-template/node/build.rs b/templates/parachain/node/build.rs similarity index 100% rename from cumulus/parachain-template/node/build.rs rename to templates/parachain/node/build.rs diff --git a/cumulus/parachain-template/node/src/chain_spec.rs b/templates/parachain/node/src/chain_spec.rs similarity index 93% rename from cumulus/parachain-template/node/src/chain_spec.rs rename to templates/parachain/node/src/chain_spec.rs index a79c78699c0..16c91865cdb 100644 --- a/cumulus/parachain-template/node/src/chain_spec.rs +++ b/templates/parachain/node/src/chain_spec.rs @@ -1,5 +1,6 @@ use cumulus_primitives_core::ParaId; -use parachain_template_runtime::{AccountId, AuraId, Signature, EXISTENTIAL_DEPOSIT}; +use parachain_template_runtime as runtime; +use runtime::{AccountId, AuraId, Signature, EXISTENTIAL_DEPOSIT}; use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup}; use sc_service::ChainType; use serde::{Deserialize, Serialize}; @@ -56,8 +57,8 @@ where /// Generate the session keys from individual elements. /// /// The input must be a tuple of individual keys (a single arg for now since we have just one key). -pub fn template_session_keys(keys: AuraId) -> parachain_template_runtime::SessionKeys { - parachain_template_runtime::SessionKeys { aura: keys } +pub fn template_session_keys(keys: AuraId) -> runtime::SessionKeys { + runtime::SessionKeys { aura: keys } } pub fn development_config() -> ChainSpec { @@ -68,8 +69,7 @@ pub fn development_config() -> ChainSpec { properties.insert("ss58Format".into(), 42.into()); ChainSpec::builder( - parachain_template_runtime::WASM_BINARY - .expect("WASM binary was not built, please build it!"), + runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"), Extensions { relay_chain: "rococo-local".into(), // You MUST set this to the correct network! @@ -120,8 +120,7 @@ pub fn local_testnet_config() -> ChainSpec { #[allow(deprecated)] ChainSpec::builder( - parachain_template_runtime::WASM_BINARY - .expect("WASM binary was not built, please build it!"), + runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"), Extensions { relay_chain: "rococo-local".into(), // You MUST set this to the correct network! diff --git a/cumulus/parachain-template/node/src/cli.rs b/templates/parachain/node/src/cli.rs similarity index 100% rename from cumulus/parachain-template/node/src/cli.rs rename to templates/parachain/node/src/cli.rs diff --git a/cumulus/parachain-template/node/src/command.rs b/templates/parachain/node/src/command.rs similarity index 100% rename from cumulus/parachain-template/node/src/command.rs rename to templates/parachain/node/src/command.rs diff --git a/cumulus/parachain-template/node/src/main.rs b/templates/parachain/node/src/main.rs similarity index 100% rename from cumulus/parachain-template/node/src/main.rs rename to templates/parachain/node/src/main.rs diff --git a/cumulus/parachain-template/node/src/rpc.rs b/templates/parachain/node/src/rpc.rs similarity index 100% rename from cumulus/parachain-template/node/src/rpc.rs rename to templates/parachain/node/src/rpc.rs diff --git a/cumulus/parachain-template/node/src/service.rs b/templates/parachain/node/src/service.rs similarity index 100% rename from cumulus/parachain-template/node/src/service.rs rename to templates/parachain/node/src/service.rs diff --git a/cumulus/parachain-template/pallets/template/Cargo.toml b/templates/parachain/pallets/template/Cargo.toml similarity index 68% rename from cumulus/parachain-template/pallets/template/Cargo.toml rename to templates/parachain/pallets/template/Cargo.toml index 04858a161fa..89eb9d51716 100644 --- a/cumulus/parachain-template/pallets/template/Cargo.toml +++ b/templates/parachain/pallets/template/Cargo.toml @@ -1,12 +1,13 @@ [package] name = "pallet-parachain-template" -authors = ["Anonymous"] description = "FRAME pallet template for defining custom runtime logic." -version = "0.7.0" -license = "Unlicense" -homepage = "https://substrate.io" +version = "0.0.0" +license = "MIT-0" +authors.workspace = true +homepage.workspace = true repository.workspace = true edition.workspace = true +publish = false [lints] workspace = true @@ -15,21 +16,22 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "3.0.0", features = ["derive"], default-features = false } -scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = [ + "derive", +] } +scale-info = { version = "2.10.0", default-features = false, features = [ + "derive", +] } -# Substrate +# frame deps frame-benchmarking = { path = "../../../../substrate/frame/benchmarking", default-features = false, optional = true } frame-support = { path = "../../../../substrate/frame/support", default-features = false } frame-system = { path = "../../../../substrate/frame/system", default-features = false } [dev-dependencies] -serde = { workspace = true, default-features = true } - -# Substrate -sp-core = { path = "../../../../substrate/primitives/core", default-features = false } -sp-io = { path = "../../../../substrate/primitives/io", default-features = false } -sp-runtime = { path = "../../../../substrate/primitives/runtime", default-features = false } +sp-core = { path = "../../../../substrate/primitives/core" } +sp-io = { path = "../../../../substrate/primitives/io" } +sp-runtime = { path = "../../../../substrate/primitives/runtime" } [features] default = ["std"] @@ -41,7 +43,7 @@ runtime-benchmarks = [ ] std = [ "codec/std", - "frame-benchmarking/std", + "frame-benchmarking?/std", "frame-support/std", "frame-system/std", "scale-info/std", diff --git a/substrate/bin/node-template/pallets/template/README.md b/templates/parachain/pallets/template/README.md similarity index 100% rename from substrate/bin/node-template/pallets/template/README.md rename to templates/parachain/pallets/template/README.md diff --git a/substrate/bin/node-template/pallets/template/src/benchmarking.rs b/templates/parachain/pallets/template/src/benchmarking.rs similarity index 100% rename from substrate/bin/node-template/pallets/template/src/benchmarking.rs rename to templates/parachain/pallets/template/src/benchmarking.rs diff --git a/cumulus/parachain-template/pallets/template/src/lib.rs b/templates/parachain/pallets/template/src/lib.rs similarity index 96% rename from cumulus/parachain-template/pallets/template/src/lib.rs rename to templates/parachain/pallets/template/src/lib.rs index 24226d6cf40..11587d1df42 100644 --- a/cumulus/parachain-template/pallets/template/src/lib.rs +++ b/templates/parachain/pallets/template/src/lib.rs @@ -11,6 +11,8 @@ mod mock; #[cfg(test)] mod tests; +pub mod weights; + #[cfg(feature = "runtime-benchmarks")] mod benchmarking; @@ -24,6 +26,8 @@ pub mod pallet { pub trait Config: frame_system::Config { /// Because this pallet emits events, it depends on the runtime's definition of an event. type RuntimeEvent: From> + IsType<::RuntimeEvent>; + /// A type representing the weights required by the dispatchables of this pallet. + type WeightInfo: crate::weights::WeightInfo; } #[pallet::pallet] diff --git a/cumulus/parachain-template/pallets/template/src/mock.rs b/templates/parachain/pallets/template/src/mock.rs similarity index 98% rename from cumulus/parachain-template/pallets/template/src/mock.rs rename to templates/parachain/pallets/template/src/mock.rs index 411a16b116c..f510a8b773a 100644 --- a/cumulus/parachain-template/pallets/template/src/mock.rs +++ b/templates/parachain/pallets/template/src/mock.rs @@ -51,6 +51,7 @@ impl system::Config for Test { impl crate::Config for Test { type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); } // Build genesis storage according to the mock runtime. diff --git a/cumulus/parachain-template/pallets/template/src/tests.rs b/templates/parachain/pallets/template/src/tests.rs similarity index 100% rename from cumulus/parachain-template/pallets/template/src/tests.rs rename to templates/parachain/pallets/template/src/tests.rs diff --git a/substrate/bin/node-template/pallets/template/src/weights.rs b/templates/parachain/pallets/template/src/weights.rs similarity index 100% rename from substrate/bin/node-template/pallets/template/src/weights.rs rename to templates/parachain/pallets/template/src/weights.rs diff --git a/cumulus/parachain-template/polkadot-launch/config.json b/templates/parachain/polkadot-launch/config.json similarity index 100% rename from cumulus/parachain-template/polkadot-launch/config.json rename to templates/parachain/polkadot-launch/config.json diff --git a/cumulus/parachain-template/runtime/Cargo.toml b/templates/parachain/runtime/Cargo.toml similarity index 82% rename from cumulus/parachain-template/runtime/Cargo.toml rename to templates/parachain/runtime/Cargo.toml index 60d8d6f5136..44e9341b568 100644 --- a/cumulus/parachain-template/runtime/Cargo.toml +++ b/templates/parachain/runtime/Cargo.toml @@ -1,12 +1,13 @@ [package] name = "parachain-template-runtime" -version = "0.7.0" -authors = ["Anonymous"] -description = "A new Cumulus FRAME-based Substrate Runtime, ready for hacking together a parachain." -license = "Unlicense" -homepage = "https://substrate.io" +description = "A parachain runtime template built with Substrate and Cumulus, part of Polkadot Sdk." +version = "0.0.0" +license = "MIT-0" +authors.workspace = true +homepage.workspace = true repository.workspace = true edition.workspace = true +publish = false [lints] workspace = true @@ -18,16 +19,20 @@ targets = ["x86_64-unknown-linux-gnu"] substrate-wasm-builder = { path = "../../../substrate/utils/wasm-builder", optional = true } [dependencies] -codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ + "derive", +] } hex-literal = { version = "0.4.1", optional = true } log = { workspace = true } -scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } +scale-info = { version = "2.10.0", default-features = false, features = [ + "derive", +] } smallvec = "1.11.0" # Local pallet-parachain-template = { path = "../pallets/template", default-features = false } -# Substrate +# Substrate / FRAME frame-benchmarking = { path = "../../../substrate/frame/benchmarking", default-features = false, optional = true } frame-executive = { path = "../../../substrate/frame/executive", default-features = false } frame-support = { path = "../../../substrate/frame/support", default-features = false } @@ -35,6 +40,8 @@ frame-system = { path = "../../../substrate/frame/system", default-features = fa frame-system-benchmarking = { path = "../../../substrate/frame/system/benchmarking", default-features = false, optional = true } frame-system-rpc-runtime-api = { path = "../../../substrate/frame/system/rpc/runtime-api", default-features = false } frame-try-runtime = { path = "../../../substrate/frame/try-runtime", default-features = false, optional = true } + +# FRAME Pallets pallet-aura = { path = "../../../substrate/frame/aura", default-features = false } pallet-authorship = { path = "../../../substrate/frame/authorship", default-features = false } pallet-balances = { path = "../../../substrate/frame/balances", default-features = false } @@ -44,6 +51,8 @@ pallet-sudo = { path = "../../../substrate/frame/sudo", default-features = false pallet-timestamp = { path = "../../../substrate/frame/timestamp", default-features = false } pallet-transaction-payment = { path = "../../../substrate/frame/transaction-payment", default-features = false } pallet-transaction-payment-rpc-runtime-api = { path = "../../../substrate/frame/transaction-payment/rpc/runtime-api", default-features = false } + +# Substrate Primitives sp-api = { path = "../../../substrate/primitives/api", default-features = false } sp-block-builder = { path = "../../../substrate/primitives/block-builder", default-features = false } sp-consensus-aura = { path = "../../../substrate/primitives/consensus/aura", default-features = false } @@ -66,17 +75,19 @@ xcm-builder = { package = "staging-xcm-builder", path = "../../../polkadot/xcm/x xcm-executor = { package = "staging-xcm-executor", path = "../../../polkadot/xcm/xcm-executor", default-features = false } # Cumulus -cumulus-pallet-aura-ext = { path = "../../pallets/aura-ext", default-features = false } -cumulus-pallet-parachain-system = { path = "../../pallets/parachain-system", default-features = false, features = ["parameterized-consensus-hook"] } -cumulus-pallet-session-benchmarking = { path = "../../pallets/session-benchmarking", default-features = false } -cumulus-pallet-xcm = { path = "../../pallets/xcm", default-features = false } -cumulus-pallet-xcmp-queue = { path = "../../pallets/xcmp-queue", default-features = false } -cumulus-primitives-core = { path = "../../primitives/core", default-features = false } -cumulus-primitives-utility = { path = "../../primitives/utility", default-features = false } -cumulus-primitives-storage-weight-reclaim = { path = "../../primitives/storage-weight-reclaim", default-features = false } -pallet-collator-selection = { path = "../../pallets/collator-selection", default-features = false } -parachains-common = { path = "../../parachains/common", default-features = false } -parachain-info = { package = "staging-parachain-info", path = "../../parachains/pallets/parachain-info", default-features = false } +cumulus-pallet-aura-ext = { path = "../../../cumulus/pallets/aura-ext", default-features = false } +cumulus-pallet-parachain-system = { path = "../../../cumulus/pallets/parachain-system", default-features = false, features = [ + "parameterized-consensus-hook", +] } +cumulus-pallet-session-benchmarking = { path = "../../../cumulus/pallets/session-benchmarking", default-features = false } +cumulus-pallet-xcm = { path = "../../../cumulus/pallets/xcm", default-features = false } +cumulus-pallet-xcmp-queue = { path = "../../../cumulus/pallets/xcmp-queue", default-features = false } +cumulus-primitives-core = { path = "../../../cumulus/primitives/core", default-features = false } +cumulus-primitives-utility = { path = "../../../cumulus/primitives/utility", default-features = false } +cumulus-primitives-storage-weight-reclaim = { path = "../../../cumulus/primitives/storage-weight-reclaim", default-features = false } +pallet-collator-selection = { path = "../../../cumulus/pallets/collator-selection", default-features = false } +parachains-common = { path = "../../../cumulus/parachains/common", default-features = false } +parachain-info = { package = "staging-parachain-info", path = "../../../cumulus/parachains/pallets/parachain-info", default-features = false } [features] default = ["std"] diff --git a/cumulus/parachain-template/runtime/build.rs b/templates/parachain/runtime/build.rs similarity index 100% rename from cumulus/parachain-template/runtime/build.rs rename to templates/parachain/runtime/build.rs diff --git a/cumulus/parachain-template/runtime/src/lib.rs b/templates/parachain/runtime/src/lib.rs similarity index 99% rename from cumulus/parachain-template/runtime/src/lib.rs rename to templates/parachain/runtime/src/lib.rs index f7754e594e6..74ecd751f67 100644 --- a/cumulus/parachain-template/runtime/src/lib.rs +++ b/templates/parachain/runtime/src/lib.rs @@ -180,8 +180,8 @@ impl_opaque_keys! { #[sp_version::runtime_version] pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: create_runtime_str!("template-parachain"), - impl_name: create_runtime_str!("template-parachain"), + spec_name: create_runtime_str!("parachain-template-runtime"), + impl_name: create_runtime_str!("parachain-template-runtime"), authoring_version: 1, spec_version: 1, impl_version: 0, @@ -490,6 +490,7 @@ impl pallet_collator_selection::Config for Runtime { /// Configure the pallet template in pallets/template. impl pallet_parachain_template::Config for Runtime { type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_parachain_template::weights::SubstrateWeight; } // Create the runtime by composing the FRAME pallets that were previously configured. diff --git a/cumulus/parachain-template/runtime/src/weights/block_weights.rs b/templates/parachain/runtime/src/weights/block_weights.rs similarity index 100% rename from cumulus/parachain-template/runtime/src/weights/block_weights.rs rename to templates/parachain/runtime/src/weights/block_weights.rs diff --git a/cumulus/parachain-template/runtime/src/weights/extrinsic_weights.rs b/templates/parachain/runtime/src/weights/extrinsic_weights.rs similarity index 100% rename from cumulus/parachain-template/runtime/src/weights/extrinsic_weights.rs rename to templates/parachain/runtime/src/weights/extrinsic_weights.rs diff --git a/cumulus/parachain-template/runtime/src/weights/mod.rs b/templates/parachain/runtime/src/weights/mod.rs similarity index 100% rename from cumulus/parachain-template/runtime/src/weights/mod.rs rename to templates/parachain/runtime/src/weights/mod.rs diff --git a/cumulus/parachain-template/runtime/src/weights/paritydb_weights.rs b/templates/parachain/runtime/src/weights/paritydb_weights.rs similarity index 100% rename from cumulus/parachain-template/runtime/src/weights/paritydb_weights.rs rename to templates/parachain/runtime/src/weights/paritydb_weights.rs diff --git a/cumulus/parachain-template/runtime/src/weights/rocksdb_weights.rs b/templates/parachain/runtime/src/weights/rocksdb_weights.rs similarity index 100% rename from cumulus/parachain-template/runtime/src/weights/rocksdb_weights.rs rename to templates/parachain/runtime/src/weights/rocksdb_weights.rs diff --git a/cumulus/parachain-template/runtime/src/xcm_config.rs b/templates/parachain/runtime/src/xcm_config.rs similarity index 100% rename from cumulus/parachain-template/runtime/src/xcm_config.rs rename to templates/parachain/runtime/src/xcm_config.rs diff --git a/substrate/bin/node-template/LICENSE b/templates/solochain/LICENSE similarity index 100% rename from substrate/bin/node-template/LICENSE rename to templates/solochain/LICENSE diff --git a/substrate/bin/node-template/README.md b/templates/solochain/README.md similarity index 100% rename from substrate/bin/node-template/README.md rename to templates/solochain/README.md diff --git a/substrate/bin/node-template/docs/rust-setup.md b/templates/solochain/docs/rust-setup.md similarity index 100% rename from substrate/bin/node-template/docs/rust-setup.md rename to templates/solochain/docs/rust-setup.md diff --git a/substrate/bin/node-template/env-setup/README.md b/templates/solochain/env-setup/README.md similarity index 100% rename from substrate/bin/node-template/env-setup/README.md rename to templates/solochain/env-setup/README.md diff --git a/substrate/bin/node-template/env-setup/flake.lock b/templates/solochain/env-setup/flake.lock similarity index 100% rename from substrate/bin/node-template/env-setup/flake.lock rename to templates/solochain/env-setup/flake.lock diff --git a/substrate/bin/node-template/env-setup/flake.nix b/templates/solochain/env-setup/flake.nix similarity index 100% rename from substrate/bin/node-template/env-setup/flake.nix rename to templates/solochain/env-setup/flake.nix diff --git a/substrate/bin/node-template/env-setup/rust-toolchain.toml b/templates/solochain/env-setup/rust-toolchain.toml similarity index 100% rename from substrate/bin/node-template/env-setup/rust-toolchain.toml rename to templates/solochain/env-setup/rust-toolchain.toml diff --git a/templates/solochain/node/Cargo.toml b/templates/solochain/node/Cargo.toml new file mode 100644 index 00000000000..5e50e6106c1 --- /dev/null +++ b/templates/solochain/node/Cargo.toml @@ -0,0 +1,92 @@ +[package] +name = "solochain-template-node" +description = "A solochain node template built with Substrate, part of Polkadot Sdk." +version = "0.0.0" +license = "MIT-0" +authors.workspace = true +homepage.workspace = true +repository.workspace = true +edition.workspace = true +publish = false + +build = "build.rs" + +[lints] +workspace = true + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +clap = { version = "4.5.1", features = ["derive"] } +futures = { version = "0.3.21", features = ["thread-pool"] } +serde_json = { workspace = true, default-features = true } +jsonrpsee = { version = "0.22", features = ["server"] } + +# substrate client +sc-cli = { path = "../../../substrate/client/cli" } +sp-core = { path = "../../../substrate/primitives/core" } +sc-executor = { path = "../../../substrate/client/executor" } +sc-network = { path = "../../../substrate/client/network" } +sc-service = { path = "../../../substrate/client/service" } +sc-telemetry = { path = "../../../substrate/client/telemetry" } +sc-transaction-pool = { path = "../../../substrate/client/transaction-pool" } +sc-transaction-pool-api = { path = "../../../substrate/client/transaction-pool/api" } +sc-offchain = { path = "../../../substrate/client/offchain" } +sc-consensus-aura = { path = "../../../substrate/client/consensus/aura" } +sp-consensus-aura = { path = "../../../substrate/primitives/consensus/aura" } +sc-consensus = { path = "../../../substrate/client/consensus/common" } +sc-consensus-grandpa = { path = "../../../substrate/client/consensus/grandpa" } +sp-consensus-grandpa = { path = "../../../substrate/primitives/consensus/grandpa" } +sc-client-api = { path = "../../../substrate/client/api" } +sc-rpc-api = { path = "../../../substrate/client/rpc-api" } +sc-basic-authorship = { path = "../../../substrate/client/basic-authorship" } + +# substrate primitives +sp-runtime = { path = "../../../substrate/primitives/runtime" } +sp-io = { path = "../../../substrate/primitives/io" } +sp-timestamp = { path = "../../../substrate/primitives/timestamp" } +sp-inherents = { path = "../../../substrate/primitives/inherents" } +sp-keyring = { path = "../../../substrate/primitives/keyring" } +sp-api = { path = "../../../substrate/primitives/api" } +sp-blockchain = { path = "../../../substrate/primitives/blockchain" } +sp-block-builder = { path = "../../../substrate/primitives/block-builder" } + +# frame and pallets +frame-system = { path = "../../../substrate/frame/system" } +pallet-transaction-payment = { path = "../../../substrate/frame/transaction-payment", default-features = false } +pallet-transaction-payment-rpc = { path = "../../../substrate/frame/transaction-payment/rpc" } +substrate-frame-rpc-system = { path = "../../../substrate/utils/frame/rpc/system" } + +# These dependencies are used for runtime benchmarking +frame-benchmarking-cli = { path = "../../../substrate/utils/frame/benchmarking-cli" } + +# Local Dependencies +solochain-template-runtime = { path = "../runtime" } + +# CLI-specific dependencies +try-runtime-cli = { path = "../../../substrate/utils/frame/try-runtime/cli", optional = true } + +[build-dependencies] +substrate-build-script-utils = { path = "../../../substrate/utils/build-script-utils" } + +[features] +default = [] +# Dependencies that are only required if runtime benchmarking should be build. +runtime-benchmarks = [ + "frame-benchmarking-cli/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", + "sc-service/runtime-benchmarks", + "solochain-template-runtime/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] +# Enable features that allow the runtime to be tried and debugged. Name might be subject to change +# in the near future. +try-runtime = [ + "frame-system/try-runtime", + "pallet-transaction-payment/try-runtime", + "solochain-template-runtime/try-runtime", + "sp-runtime/try-runtime", + "try-runtime-cli/try-runtime", +] diff --git a/substrate/bin/node-template/node/build.rs b/templates/solochain/node/build.rs similarity index 100% rename from substrate/bin/node-template/node/build.rs rename to templates/solochain/node/build.rs diff --git a/substrate/bin/node-template/node/src/benchmarking.rs b/templates/solochain/node/src/benchmarking.rs similarity index 99% rename from substrate/bin/node-template/node/src/benchmarking.rs rename to templates/solochain/node/src/benchmarking.rs index eacc367669c..8710f303e1f 100644 --- a/substrate/bin/node-template/node/src/benchmarking.rs +++ b/templates/solochain/node/src/benchmarking.rs @@ -4,10 +4,10 @@ use crate::service::FullClient; -use node_template_runtime as runtime; use runtime::{AccountId, Balance, BalancesCall, SystemCall}; use sc_cli::Result; use sc_client_api::BlockBackend; +use solochain_template_runtime as runtime; use sp_core::{Encode, Pair}; use sp_inherents::{InherentData, InherentDataProvider}; use sp_keyring::Sr25519Keyring; diff --git a/substrate/bin/node-template/node/src/chain_spec.rs b/templates/solochain/node/src/chain_spec.rs similarity index 97% rename from substrate/bin/node-template/node/src/chain_spec.rs rename to templates/solochain/node/src/chain_spec.rs index 6e0d78f647a..be49f2c1fc7 100644 --- a/substrate/bin/node-template/node/src/chain_spec.rs +++ b/templates/solochain/node/src/chain_spec.rs @@ -1,5 +1,5 @@ -use node_template_runtime::{AccountId, RuntimeGenesisConfig, Signature, WASM_BINARY}; use sc_service::ChainType; +use solochain_template_runtime::{AccountId, RuntimeGenesisConfig, Signature, WASM_BINARY}; use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_consensus_grandpa::AuthorityId as GrandpaId; use sp_core::{sr25519, Pair, Public}; diff --git a/substrate/bin/node-template/node/src/cli.rs b/templates/solochain/node/src/cli.rs similarity index 100% rename from substrate/bin/node-template/node/src/cli.rs rename to templates/solochain/node/src/cli.rs diff --git a/substrate/bin/node-template/node/src/command.rs b/templates/solochain/node/src/command.rs similarity index 98% rename from substrate/bin/node-template/node/src/command.rs rename to templates/solochain/node/src/command.rs index 3778df66422..42d1477f22f 100644 --- a/substrate/bin/node-template/node/src/command.rs +++ b/templates/solochain/node/src/command.rs @@ -5,9 +5,9 @@ use crate::{ service, }; use frame_benchmarking_cli::{BenchmarkCmd, ExtrinsicFactory, SUBSTRATE_REFERENCE_HARDWARE}; -use node_template_runtime::{Block, EXISTENTIAL_DEPOSIT}; use sc_cli::SubstrateCli; use sc_service::PartialComponents; +use solochain_template_runtime::{Block, EXISTENTIAL_DEPOSIT}; use sp_keyring::Sr25519Keyring; impl SubstrateCli for Cli { diff --git a/substrate/bin/node-template/node/src/main.rs b/templates/solochain/node/src/main.rs similarity index 100% rename from substrate/bin/node-template/node/src/main.rs rename to templates/solochain/node/src/main.rs diff --git a/substrate/bin/node-template/node/src/rpc.rs b/templates/solochain/node/src/rpc.rs similarity index 96% rename from substrate/bin/node-template/node/src/rpc.rs rename to templates/solochain/node/src/rpc.rs index 246391adcbb..fe2b6ca72ed 100644 --- a/substrate/bin/node-template/node/src/rpc.rs +++ b/templates/solochain/node/src/rpc.rs @@ -8,8 +8,8 @@ use std::sync::Arc; use jsonrpsee::RpcModule; -use node_template_runtime::{opaque::Block, AccountId, Balance, Nonce}; use sc_transaction_pool_api::TransactionPool; +use solochain_template_runtime::{opaque::Block, AccountId, Balance, Nonce}; use sp_api::ProvideRuntimeApi; use sp_block_builder::BlockBuilder; use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata}; diff --git a/substrate/bin/node-template/node/src/service.rs b/templates/solochain/node/src/service.rs similarity index 99% rename from substrate/bin/node-template/node/src/service.rs rename to templates/solochain/node/src/service.rs index 125cca13927..dc25f757912 100644 --- a/substrate/bin/node-template/node/src/service.rs +++ b/templates/solochain/node/src/service.rs @@ -1,13 +1,13 @@ //! Service and ServiceFactory implementation. Specialized wrapper over substrate service. use futures::FutureExt; -use node_template_runtime::{self, opaque::Block, RuntimeApi}; use sc_client_api::{Backend, BlockBackend}; use sc_consensus_aura::{ImportQueueParams, SlotProportion, StartAuraParams}; use sc_consensus_grandpa::SharedVoterState; use sc_service::{error::Error as ServiceError, Configuration, TaskManager, WarpSyncParams}; use sc_telemetry::{Telemetry, TelemetryWorker}; use sc_transaction_pool_api::OffchainTransactionPoolFactory; +use solochain_template_runtime::{self, opaque::Block, RuntimeApi}; use sp_consensus_aura::sr25519::AuthorityPair as AuraPair; use std::{sync::Arc, time::Duration}; diff --git a/substrate/bin/node-template/pallets/template/Cargo.toml b/templates/solochain/pallets/template/Cargo.toml similarity index 55% rename from substrate/bin/node-template/pallets/template/Cargo.toml rename to templates/solochain/pallets/template/Cargo.toml index 51410a71c7b..bd234715198 100644 --- a/substrate/bin/node-template/pallets/template/Cargo.toml +++ b/templates/solochain/pallets/template/Cargo.toml @@ -1,13 +1,13 @@ [package] name = "pallet-template" -version = "4.0.0-dev" description = "FRAME pallet template for defining custom runtime logic." -authors = ["Substrate DevHub "] -homepage = "https://substrate.io" -edition.workspace = true +version = "0.0.0" license = "MIT-0" +authors.workspace = true +homepage.workspace = true +repository.workspace = true +edition.workspace = true publish = false -repository = "https://github.com/substrate-developer-hub/substrate-node-template/" [lints] workspace = true @@ -19,16 +19,19 @@ targets = ["x86_64-unknown-linux-gnu"] codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = [ "derive", ] } -scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -frame-benchmarking = { path = "../../../../frame/benchmarking", default-features = false, optional = true } -frame-support = { path = "../../../../frame/support", default-features = false } -frame-system = { path = "../../../../frame/system", default-features = false } -sp-std = { path = "../../../../primitives/std", default-features = false } +scale-info = { version = "2.10.0", default-features = false, features = [ + "derive", +] } + +# frame deps +frame-benchmarking = { path = "../../../../substrate/frame/benchmarking", default-features = false, optional = true } +frame-support = { path = "../../../../substrate/frame/support", default-features = false } +frame-system = { path = "../../../../substrate/frame/system", default-features = false } [dev-dependencies] -sp-core = { path = "../../../../primitives/core" } -sp-io = { path = "../../../../primitives/io" } -sp-runtime = { path = "../../../../primitives/runtime" } +sp-core = { path = "../../../../substrate/primitives/core" } +sp-io = { path = "../../../../substrate/primitives/io" } +sp-runtime = { path = "../../../../substrate/primitives/runtime" } [features] default = ["std"] @@ -41,7 +44,6 @@ std = [ "sp-core/std", "sp-io/std", "sp-runtime/std", - "sp-std/std", ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", diff --git a/templates/solochain/pallets/template/README.md b/templates/solochain/pallets/template/README.md new file mode 100644 index 00000000000..9e4dc55267d --- /dev/null +++ b/templates/solochain/pallets/template/README.md @@ -0,0 +1 @@ +License: MIT-0 diff --git a/templates/solochain/pallets/template/src/benchmarking.rs b/templates/solochain/pallets/template/src/benchmarking.rs new file mode 100644 index 00000000000..5a262417629 --- /dev/null +++ b/templates/solochain/pallets/template/src/benchmarking.rs @@ -0,0 +1,35 @@ +//! Benchmarking setup for pallet-template +#![cfg(feature = "runtime-benchmarks")] +use super::*; + +#[allow(unused)] +use crate::Pallet as Template; +use frame_benchmarking::v2::*; +use frame_system::RawOrigin; + +#[benchmarks] +mod benchmarks { + use super::*; + + #[benchmark] + fn do_something() { + let value = 100u32.into(); + let caller: T::AccountId = whitelisted_caller(); + #[extrinsic_call] + do_something(RawOrigin::Signed(caller), value); + + assert_eq!(Something::::get(), Some(value)); + } + + #[benchmark] + fn cause_error() { + Something::::put(100u32); + let caller: T::AccountId = whitelisted_caller(); + #[extrinsic_call] + cause_error(RawOrigin::Signed(caller)); + + assert_eq!(Something::::get(), Some(101u32)); + } + + impl_benchmark_test_suite!(Template, crate::mock::new_test_ext(), crate::mock::Test); +} diff --git a/substrate/bin/node-template/pallets/template/src/lib.rs b/templates/solochain/pallets/template/src/lib.rs similarity index 100% rename from substrate/bin/node-template/pallets/template/src/lib.rs rename to templates/solochain/pallets/template/src/lib.rs diff --git a/substrate/bin/node-template/pallets/template/src/mock.rs b/templates/solochain/pallets/template/src/mock.rs similarity index 100% rename from substrate/bin/node-template/pallets/template/src/mock.rs rename to templates/solochain/pallets/template/src/mock.rs diff --git a/substrate/bin/node-template/pallets/template/src/tests.rs b/templates/solochain/pallets/template/src/tests.rs similarity index 100% rename from substrate/bin/node-template/pallets/template/src/tests.rs rename to templates/solochain/pallets/template/src/tests.rs diff --git a/templates/solochain/pallets/template/src/weights.rs b/templates/solochain/pallets/template/src/weights.rs new file mode 100644 index 00000000000..7c42936e09f --- /dev/null +++ b/templates/solochain/pallets/template/src/weights.rs @@ -0,0 +1,90 @@ + +//! Autogenerated weights for pallet_template +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-04-06, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `Alexs-MacBook-Pro-2.local`, CPU: `` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 + +// Executed Command: +// ../../target/release/node-template +// benchmark +// pallet +// --chain +// dev +// --pallet +// pallet_template +// --extrinsic +// * +// --steps=50 +// --repeat=20 +// --wasm-execution=compiled +// --output +// pallets/template/src/weights.rs +// --template +// ../../.maintain/frame-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for pallet_template. +pub trait WeightInfo { + fn do_something() -> Weight; + fn cause_error() -> Weight; +} + +/// Weights for pallet_template using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + /// Storage: TemplateModule Something (r:0 w:1) + /// Proof: TemplateModule Something (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn do_something() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(9_000_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: TemplateModule Something (r:1 w:1) + /// Proof: TemplateModule Something (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn cause_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `32` + // Estimated: `1489` + // Minimum execution time: 6_000_000 picoseconds. + Weight::from_parts(6_000_000, 1489) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + /// Storage: TemplateModule Something (r:0 w:1) + /// Proof: TemplateModule Something (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn do_something() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(9_000_000, 0) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: TemplateModule Something (r:1 w:1) + /// Proof: TemplateModule Something (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn cause_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `32` + // Estimated: `1489` + // Minimum execution time: 6_000_000 picoseconds. + Weight::from_parts(6_000_000, 1489) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } +} diff --git a/templates/solochain/runtime/Cargo.toml b/templates/solochain/runtime/Cargo.toml new file mode 100644 index 00000000000..4f22e7ff6a3 --- /dev/null +++ b/templates/solochain/runtime/Cargo.toml @@ -0,0 +1,152 @@ +[package] +name = "solochain-template-runtime" +description = "A solochain runtime template built with Substrate, part of Polkadot Sdk." +version = "0.0.0" +license = "MIT-0" +authors.workspace = true +homepage.workspace = true +repository.workspace = true +edition.workspace = true +publish = false + +[lints] +workspace = true + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = [ + "derive", +] } +scale-info = { version = "2.10.0", default-features = false, features = [ + "derive", + "serde", +] } + +# frame +frame-support = { path = "../../../substrate/frame/support", default-features = false } +frame-system = { path = "../../../substrate/frame/system", default-features = false } +frame-try-runtime = { path = "../../../substrate/frame/try-runtime", default-features = false, optional = true } +frame-executive = { path = "../../../substrate/frame/executive", default-features = false } + +# frame pallets +pallet-aura = { path = "../../../substrate/frame/aura", default-features = false } +pallet-balances = { path = "../../../substrate/frame/balances", default-features = false } +pallet-grandpa = { path = "../../../substrate/frame/grandpa", default-features = false } +pallet-sudo = { path = "../../../substrate/frame/sudo", default-features = false } +pallet-timestamp = { path = "../../../substrate/frame/timestamp", default-features = false } +pallet-transaction-payment = { path = "../../../substrate/frame/transaction-payment", default-features = false } + +# primitives +sp-api = { path = "../../../substrate/primitives/api", default-features = false } +sp-block-builder = { path = "../../../substrate/primitives/block-builder", default-features = false } +sp-consensus-aura = { path = "../../../substrate/primitives/consensus/aura", default-features = false, features = [ + "serde", +] } +sp-consensus-grandpa = { path = "../../../substrate/primitives/consensus/grandpa", default-features = false, features = [ + "serde", +] } +sp-core = { path = "../../../substrate/primitives/core", default-features = false, features = [ + "serde", +] } +sp-inherents = { path = "../../../substrate/primitives/inherents", default-features = false } +sp-offchain = { path = "../../../substrate/primitives/offchain", default-features = false } +sp-runtime = { path = "../../../substrate/primitives/runtime", default-features = false, features = [ + "serde", +] } +sp-session = { path = "../../../substrate/primitives/session", default-features = false } +sp-std = { path = "../../../substrate/primitives/std", default-features = false } +sp-storage = { path = "../../../substrate/primitives/storage", default-features = false } +sp-transaction-pool = { path = "../../../substrate/primitives/transaction-pool", default-features = false } +sp-version = { path = "../../../substrate/primitives/version", default-features = false, features = [ + "serde", +] } +sp-genesis-builder = { default-features = false, path = "../../../substrate/primitives/genesis-builder" } + +# RPC related +frame-system-rpc-runtime-api = { path = "../../../substrate/frame/system/rpc/runtime-api", default-features = false } +pallet-transaction-payment-rpc-runtime-api = { path = "../../../substrate/frame/transaction-payment/rpc/runtime-api", default-features = false } + +# Used for runtime benchmarking +frame-benchmarking = { path = "../../../substrate/frame/benchmarking", default-features = false, optional = true } +frame-system-benchmarking = { path = "../../../substrate/frame/system/benchmarking", default-features = false, optional = true } + +# The pallet in this template. +pallet-template = { path = "../pallets/template", default-features = false } + +[build-dependencies] +substrate-wasm-builder = { path = "../../../substrate/utils/wasm-builder", optional = true } + +[features] +default = ["std"] +std = [ + "codec/std", + "scale-info/std", + + "frame-executive/std", + "frame-support/std", + "frame-system-benchmarking?/std", + "frame-system-rpc-runtime-api/std", + "frame-system/std", + + "frame-benchmarking?/std", + "frame-try-runtime?/std", + + "pallet-aura/std", + "pallet-balances/std", + "pallet-grandpa/std", + "pallet-sudo/std", + "pallet-template/std", + "pallet-timestamp/std", + "pallet-transaction-payment-rpc-runtime-api/std", + "pallet-transaction-payment/std", + + "sp-api/std", + "sp-block-builder/std", + "sp-consensus-aura/std", + "sp-consensus-grandpa/std", + "sp-core/std", + "sp-genesis-builder/std", + "sp-inherents/std", + "sp-offchain/std", + "sp-runtime/std", + "sp-session/std", + "sp-std/std", + "sp-storage/std", + "sp-transaction-pool/std", + "sp-version/std", + + "substrate-wasm-builder", +] + +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system-benchmarking/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-grandpa/runtime-benchmarks", + "pallet-sudo/runtime-benchmarks", + "pallet-template/runtime-benchmarks", + "pallet-timestamp/runtime-benchmarks", + "pallet-transaction-payment/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] + +try-runtime = [ + "frame-executive/try-runtime", + "frame-support/try-runtime", + "frame-system/try-runtime", + "frame-try-runtime/try-runtime", + "pallet-aura/try-runtime", + "pallet-balances/try-runtime", + "pallet-grandpa/try-runtime", + "pallet-sudo/try-runtime", + "pallet-template/try-runtime", + "pallet-timestamp/try-runtime", + "pallet-transaction-payment/try-runtime", + "sp-runtime/try-runtime", +] + +experimental = ["pallet-aura/experimental"] diff --git a/substrate/bin/node-template/runtime/build.rs b/templates/solochain/runtime/build.rs similarity index 100% rename from substrate/bin/node-template/runtime/build.rs rename to templates/solochain/runtime/build.rs diff --git a/substrate/bin/node-template/runtime/src/lib.rs b/templates/solochain/runtime/src/lib.rs similarity index 98% rename from substrate/bin/node-template/runtime/src/lib.rs rename to templates/solochain/runtime/src/lib.rs index ee622a691b4..409b639f021 100644 --- a/substrate/bin/node-template/runtime/src/lib.rs +++ b/templates/solochain/runtime/src/lib.rs @@ -1,8 +1,5 @@ #![cfg_attr(not(feature = "std"), no_std)] -// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. -#![recursion_limit = "256"] -// Make the WASM binary available. #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); @@ -22,7 +19,6 @@ use sp_version::NativeVersion; use sp_version::RuntimeVersion; use frame_support::genesis_builder_helper::{build_config, create_default_config}; -// A few exports that help ease life for downstream crates. pub use frame_support::{ construct_runtime, derive_impl, parameter_types, traits::{ @@ -95,8 +91,8 @@ pub mod opaque { // https://docs.substrate.io/main-docs/build/upgrade#runtime-versioning #[sp_version::runtime_version] pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: create_runtime_str!("node-template"), - impl_name: create_runtime_str!("node-template"), + spec_name: create_runtime_str!("solochain-template-runtime"), + impl_name: create_runtime_str!("solochain-template-runtime"), authoring_version: 1, // The version of the runtime specification. A full node will not attempt to use its native // runtime in substitute for the on-chain Wasm runtime unless all of `spec_name`, @@ -266,6 +262,7 @@ construct_runtime!( Balances: pallet_balances, TransactionPayment: pallet_transaction_payment, Sudo: pallet_sudo, + // Include the custom logic from the pallet-template in the runtime. TemplateModule: pallet_template, } -- GitLab From c367ac2488db23a68e1cdf446cece58c66ea93d5 Mon Sep 17 00:00:00 2001 From: Rodrigo Quelhas <22591718+RomarQ@users.noreply.github.com> Date: Tue, 5 Mar 2024 14:05:04 +0000 Subject: [PATCH 349/392] remove deprecated type 'GenesisConfig' (#3378) # Description Removed deprecated type `GenesisConfig` from the codebase. Closes https://github.com/paritytech/polkadot-sdk/issues/175 # Checklist - [x] My PR includes a detailed description as outlined in the "Description" section above - [x] My PR follows the [labeling requirements](CONTRIBUTING.md#Process) of this project (at minimum one label for `T` required) - [x] I have made corresponding changes to the documentation (if applicable) --------- Co-authored-by: Liam Aharon Co-authored-by: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> --- prdoc/pr_3378.prdoc | 13 +++++++++ .../chain-spec/src/genesis_config_builder.rs | 24 ++++++++------- .../src/construct_runtime/expand/config.rs | 4 --- .../deprecated_where_block.stderr | 2 +- .../primitives/genesis-builder/Cargo.toml | 2 +- .../primitives/genesis-builder/src/lib.rs | 29 ++++++++++--------- 6 files changed, 43 insertions(+), 31 deletions(-) create mode 100644 prdoc/pr_3378.prdoc diff --git a/prdoc/pr_3378.prdoc b/prdoc/pr_3378.prdoc new file mode 100644 index 00000000000..2470fc15851 --- /dev/null +++ b/prdoc/pr_3378.prdoc @@ -0,0 +1,13 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Remove deprecated GenesisConfig + +doc: + - audience: Runtime Dev + description: | + Removes deprecated type `GenesisConfig`, it was replaced by `RuntimeGenesisConfig` on May 24 of 2023. + The type `GenesisConfig` was deprecated on May 24 of 2023 [#14210](https://github.com/paritytech/substrate/pull/14210) + +crates: + - name: frame-support-procedural \ No newline at end of file diff --git a/substrate/client/chain-spec/src/genesis_config_builder.rs b/substrate/client/chain-spec/src/genesis_config_builder.rs index 6b956316203..c8b54f66be6 100644 --- a/substrate/client/chain-spec/src/genesis_config_builder.rs +++ b/substrate/client/chain-spec/src/genesis_config_builder.rs @@ -81,7 +81,8 @@ where .0 } - /// Returns the default `GenesisConfig` provided by the `runtime`. + /// Returns a json representation of the default `RuntimeGenesisConfig` provided by the + /// `runtime`. /// /// Calls [`GenesisBuilder::create_default_config`](sp_genesis_builder::GenesisBuilder::create_default_config) in the `runtime`. pub fn get_default_config(&self) -> core::result::Result { @@ -94,7 +95,7 @@ where Ok(from_slice(&default_config[..]).expect("returned value is json. qed.")) } - /// Build the given `GenesisConfig` and returns the genesis state. + /// Builds `RuntimeGenesisConfig` from given json blob and returns the genesis state. /// /// Calls [`GenesisBuilder::build_config`](sp_genesis_builder::GenesisBuilder::build_config) /// provided by the `runtime`. @@ -111,25 +112,26 @@ where Ok(ext.into_storages()) } - /// Creates the genesis state by patching the default `GenesisConfig` and applying it. + /// Creates the genesis state by patching the default `RuntimeGenesisConfig`. /// - /// This function generates the `GenesisConfig` for the runtime by applying a provided JSON - /// patch. The patch modifies the default `GenesisConfig` allowing customization of the specific - /// keys. The resulting `GenesisConfig` is then deserialized from the patched JSON - /// representation and stored in the storage. + /// This function generates the `RuntimeGenesisConfig` for the runtime by applying a provided + /// JSON patch. The patch modifies the default `RuntimeGenesisConfig` allowing customization of + /// the specific keys. The resulting `RuntimeGenesisConfig` is then deserialized from the + /// patched JSON representation and stored in the storage. /// /// If the provided JSON patch is incorrect or the deserialization fails the error will be /// returned. /// - /// The patching process modifies the default `GenesisConfig` according to the following rules: + /// The patching process modifies the default `RuntimeGenesisConfig` according to the following + /// rules: /// 1. Existing keys in the default configuration will be overridden by the corresponding values /// in the patch. /// 2. If a key exists in the patch but not in the default configuration, it will be added to - /// the resulting `GenesisConfig`. + /// the resulting `RuntimeGenesisConfig`. /// 3. Keys in the default configuration that have null values in the patch will be removed from - /// the resulting `GenesisConfig`. This is helpful for changing enum variant value. + /// the resulting `RuntimeGenesisConfig`. This is helpful for changing enum variant value. /// - /// Please note that the patch may contain full `GenesisConfig`. + /// Please note that the patch may contain full `RuntimeGenesisConfig`. pub fn get_storage_for_patch(&self, patch: Value) -> core::result::Result { let mut config = self.get_default_config()?; crate::json_patch::merge(&mut config, patch); diff --git a/substrate/frame/support/procedural/src/construct_runtime/expand/config.rs b/substrate/frame/support/procedural/src/construct_runtime/expand/config.rs index 5613047359a..dbbe6ba6e6c 100644 --- a/substrate/frame/support/procedural/src/construct_runtime/expand/config.rs +++ b/substrate/frame/support/procedural/src/construct_runtime/expand/config.rs @@ -76,10 +76,6 @@ pub fn expand_outer_config( #fields } - #[cfg(any(feature = "std", test))] - #[deprecated(note = "GenesisConfig is planned to be removed in December 2023. Use `RuntimeGenesisConfig` instead.")] - pub type GenesisConfig = RuntimeGenesisConfig; - #[cfg(any(feature = "std", test))] impl #scrate::sp_runtime::BuildStorage for RuntimeGenesisConfig { fn assimilate_storage( diff --git a/substrate/frame/support/test/tests/construct_runtime_ui/deprecated_where_block.stderr b/substrate/frame/support/test/tests/construct_runtime_ui/deprecated_where_block.stderr index 9dd460da75a..c677ddcd672 100644 --- a/substrate/frame/support/test/tests/construct_runtime_ui/deprecated_where_block.stderr +++ b/substrate/frame/support/test/tests/construct_runtime_ui/deprecated_where_block.stderr @@ -347,7 +347,7 @@ error[E0277]: the trait bound `Runtime: Config` is not satisfied 26 | System: frame_system::{Pallet, Call, Storage, Config, Event}, | ^^^^^^ the trait `Config` is not implemented for `Runtime` | -note: required by a bound in `frame_system::GenesisConfig` +note: required by a bound in `GenesisConfig` --> $WORKSPACE/substrate/frame/system/src/lib.rs | | pub struct GenesisConfig { diff --git a/substrate/primitives/genesis-builder/Cargo.toml b/substrate/primitives/genesis-builder/Cargo.toml index bf12433c5f4..15440b4811e 100644 --- a/substrate/primitives/genesis-builder/Cargo.toml +++ b/substrate/primitives/genesis-builder/Cargo.toml @@ -6,7 +6,7 @@ edition.workspace = true license = "Apache-2.0" homepage = "https://substrate.io" repository.workspace = true -description = "Substrate GenesisConfig builder API" +description = "Substrate RuntimeGenesisConfig builder API" readme = "README.md" [lints] diff --git a/substrate/primitives/genesis-builder/src/lib.rs b/substrate/primitives/genesis-builder/src/lib.rs index e002cd3aa6f..bb1a2a35248 100644 --- a/substrate/primitives/genesis-builder/src/lib.rs +++ b/substrate/primitives/genesis-builder/src/lib.rs @@ -19,36 +19,37 @@ //! Substrate genesis config builder //! -//! This Runtime API allows to construct `GenesisConfig`, in particular: -//! - serialize the runtime default `GenesisConfig` struct into json format, -//! - put the GenesisConfig struct into the storage. Internally this operation calls +//! This Runtime API allows to construct `RuntimeGenesisConfig`, in particular: +//! - serialize the runtime default `RuntimeGenesisConfig` struct into json format, +//! - put the RuntimeGenesisConfig struct into the storage. Internally this operation calls //! `GenesisBuild::build` function for all runtime pallets, which is typically provided by //! pallet's author. -//! - deserialize the `GenesisConfig` from given json blob and put `GenesisConfig` into the state -//! storage. Allows to build customized configuration. +//! - deserialize the `RuntimeGenesisConfig` from given json blob and put `RuntimeGenesisConfig` +//! into the state storage. Allows to build customized configuration. //! -//! Providing externalities with empty storage and putting `GenesisConfig` into storage allows to -//! catch and build the raw storage of `GenesisConfig` which is the foundation for genesis block. +//! Providing externalities with empty storage and putting `RuntimeGenesisConfig` into storage +//! allows to catch and build the raw storage of `RuntimeGenesisConfig` which is the foundation for +//! genesis block. /// The result type alias, used in build methods. `Err` contains formatted error message. pub type Result = core::result::Result<(), sp_runtime::RuntimeString>; sp_api::decl_runtime_apis! { - /// API to interact with GenesisConfig for the runtime + /// API to interact with RuntimeGenesisConfig for the runtime pub trait GenesisBuilder { - /// Creates the default `GenesisConfig` and returns it as a JSON blob. + /// Creates the default `RuntimeGenesisConfig` and returns it as a JSON blob. /// - /// This function instantiates the default `GenesisConfig` struct for the runtime and serializes it into a JSON - /// blob. It returns a `Vec` containing the JSON representation of the default `GenesisConfig`. + /// This function instantiates the default `RuntimeGenesisConfig` struct for the runtime and serializes it into a JSON + /// blob. It returns a `Vec` containing the JSON representation of the default `RuntimeGenesisConfig`. fn create_default_config() -> sp_std::vec::Vec; - /// Build `GenesisConfig` from a JSON blob not using any defaults and store it in the storage. + /// Build `RuntimeGenesisConfig` from a JSON blob not using any defaults and store it in the storage. /// - /// This function deserializes the full `GenesisConfig` from the given JSON blob and puts it into the storage. + /// This function deserializes the full `RuntimeGenesisConfig` from the given JSON blob and puts it into the storage. /// If the provided JSON blob is incorrect or incomplete or the deserialization fails, an error is returned. /// It is recommended to log any errors encountered during the process. /// - /// Please note that provided json blob must contain all `GenesisConfig` fields, no defaults will be used. + /// Please note that provided json blob must contain all `RuntimeGenesisConfig` fields, no defaults will be used. fn build_config(json: sp_std::vec::Vec) -> Result; } } -- GitLab From 329c07723614836a05b1d9158e1a8fdea6fb6508 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Tue, 5 Mar 2024 18:16:24 +0100 Subject: [PATCH 350/392] [FRAME] Use 'ready' pages in XCMP suspend logic (#2393) Changes: - `QueueFootprint` gets a new field; `ready_pages` that contains the non-overweight and not yet processed pages. - `XCMP` queue pallet is change to use the `ready_pages` instead of `pages` to calculate the channel suspension thresholds. This should give the XCMP queue pallet a more correct view of when to suspend channels. --------- Signed-off-by: Oliver Tale-Yazdi --- cumulus/pallets/xcmp-queue/src/lib.rs | 6 +++--- cumulus/pallets/xcmp-queue/src/mock.rs | 1 + prdoc/pr_2393.prdoc | 16 ++++++++++++++++ .../frame/message-queue/src/integration_test.rs | 5 +++++ substrate/frame/message-queue/src/lib.rs | 9 +++++++-- substrate/frame/message-queue/src/mock.rs | 4 ++-- substrate/frame/message-queue/src/tests.rs | 13 +++++++++---- substrate/frame/support/src/traits/messages.rs | 2 ++ 8 files changed, 45 insertions(+), 11 deletions(-) create mode 100644 prdoc/pr_2393.prdoc diff --git a/cumulus/pallets/xcmp-queue/src/lib.rs b/cumulus/pallets/xcmp-queue/src/lib.rs index 5b900769622..e92169be16b 100644 --- a/cumulus/pallets/xcmp-queue/src/lib.rs +++ b/cumulus/pallets/xcmp-queue/src/lib.rs @@ -600,7 +600,7 @@ impl Pallet { let QueueConfigData { drop_threshold, .. } = >::get(); let fp = T::XcmpQueue::footprint(sender); // Assume that it will not fit into the current page: - let new_pages = fp.pages.saturating_add(1); + let new_pages = fp.ready_pages.saturating_add(1); if new_pages > drop_threshold { // This should not happen since the channel should have been suspended in // [`on_queue_changed`]. @@ -663,12 +663,12 @@ impl OnQueueChanged for Pallet { let mut suspended_channels = >::get(); let suspended = suspended_channels.contains(¶); - if suspended && fp.pages <= resume_threshold { + if suspended && fp.ready_pages <= resume_threshold { Self::send_signal(para, ChannelSignal::Resume); suspended_channels.remove(¶); >::put(suspended_channels); - } else if !suspended && fp.pages >= suspend_threshold { + } else if !suspended && fp.ready_pages >= suspend_threshold { log::warn!("XCMP queue for sibling {:?} is full; suspending channel.", para); Self::send_signal(para, ChannelSignal::Suspend); diff --git a/cumulus/pallets/xcmp-queue/src/mock.rs b/cumulus/pallets/xcmp-queue/src/mock.rs index 08ab58ce816..1fb88cafd93 100644 --- a/cumulus/pallets/xcmp-queue/src/mock.rs +++ b/cumulus/pallets/xcmp-queue/src/mock.rs @@ -247,6 +247,7 @@ impl> EnqueueMessage for EnqueueToLocalStorage } } footprint.pages = footprint.storage.size as u32 / 16; // Number does not matter + footprint.ready_pages = footprint.pages; footprint } } diff --git a/prdoc/pr_2393.prdoc b/prdoc/pr_2393.prdoc new file mode 100644 index 00000000000..708d017fafd --- /dev/null +++ b/prdoc/pr_2393.prdoc @@ -0,0 +1,16 @@ +title: "[XCMP] Use the number of 'ready' pages in XCMP suspend logic" + +doc: + - audience: Runtime Dev + description: | + Semantics of the suspension logic in the XCMP queue pallet change from using the number of + total pages to the number of 'ready' pages. The number of ready pages is now also exposed by + the `MessageQueue` pallet to downstream via the queue `footprint`. + +crates: + - name: cumulus-pallet-xcmp-queue + bump: patch + - name: pallet-message-queue + bump: patch + - name: frame-support + bump: major diff --git a/substrate/frame/message-queue/src/integration_test.rs b/substrate/frame/message-queue/src/integration_test.rs index cc3da6ebdc6..ce8eb80805a 100644 --- a/substrate/frame/message-queue/src/integration_test.rs +++ b/substrate/frame/message-queue/src/integration_test.rs @@ -330,6 +330,11 @@ fn process_some_messages(num_msgs: u32) { ServiceWeight::set(Some(weight)); let consumed = next_block(); + for origin in BookStateFor::::iter_keys() { + let fp = MessageQueue::footprint(origin); + assert_eq!(fp.pages, fp.ready_pages); + } + assert_eq!(consumed, weight, "\n{}", MessageQueue::debug_info()); assert_eq!(NumMessagesProcessed::take(), num_msgs as usize); } diff --git a/substrate/frame/message-queue/src/lib.rs b/substrate/frame/message-queue/src/lib.rs index 07eb0041985..61028057394 100644 --- a/substrate/frame/message-queue/src/lib.rs +++ b/substrate/frame/message-queue/src/lib.rs @@ -208,8 +208,9 @@ use frame_support::{ defensive, pallet_prelude::*, traits::{ - Defensive, DefensiveTruncateFrom, EnqueueMessage, ExecuteOverweightError, Footprint, - ProcessMessage, ProcessMessageError, QueueFootprint, QueuePausedQuery, ServiceQueues, + Defensive, DefensiveSaturating, DefensiveTruncateFrom, EnqueueMessage, + ExecuteOverweightError, Footprint, ProcessMessage, ProcessMessageError, QueueFootprint, + QueuePausedQuery, ServiceQueues, }, BoundedSlice, CloneNoBound, DefaultNoBound, }; @@ -442,6 +443,7 @@ impl From> for QueueFootprint { fn from(book: BookState) -> Self { QueueFootprint { pages: book.count, + ready_pages: book.end.defensive_saturating_sub(book.begin), storage: Footprint { count: book.message_count, size: book.size }, } } @@ -1281,6 +1283,9 @@ impl Pallet { ensure!(book.message_count < 1 << 30, "Likely overflow or corruption"); ensure!(book.size < 1 << 30, "Likely overflow or corruption"); ensure!(book.count < 1 << 30, "Likely overflow or corruption"); + + let fp: QueueFootprint = book.into(); + ensure!(fp.ready_pages <= fp.pages, "There cannot be more ready than total pages"); } //loop around this origin diff --git a/substrate/frame/message-queue/src/mock.rs b/substrate/frame/message-queue/src/mock.rs index a46fa31df3e..d176a981ca8 100644 --- a/substrate/frame/message-queue/src/mock.rs +++ b/substrate/frame/message-queue/src/mock.rs @@ -355,8 +355,8 @@ pub fn num_overweight_enqueued_events() -> u32 { .count() as u32 } -pub fn fp(pages: u32, count: u64, size: u64) -> QueueFootprint { - QueueFootprint { storage: Footprint { count, size }, pages } +pub fn fp(pages: u32, ready_pages: u32, count: u64, size: u64) -> QueueFootprint { + QueueFootprint { storage: Footprint { count, size }, pages, ready_pages } } /// A random seed that can be overwritten with `MQ_SEED`. diff --git a/substrate/frame/message-queue/src/tests.rs b/substrate/frame/message-queue/src/tests.rs index 86a8b79fe8b..dbef94b3b10 100644 --- a/substrate/frame/message-queue/src/tests.rs +++ b/substrate/frame/message-queue/src/tests.rs @@ -1064,13 +1064,13 @@ fn footprint_num_pages_works() { MessageQueue::enqueue_message(msg("weight=2"), Here); MessageQueue::enqueue_message(msg("weight=3"), Here); - assert_eq!(MessageQueue::footprint(Here), fp(2, 2, 16)); + assert_eq!(MessageQueue::footprint(Here), fp(2, 2, 2, 16)); // Mark the messages as overweight. assert_eq!(MessageQueue::service_queues(1.into_weight()), 0.into_weight()); assert_eq!(System::events().len(), 2); - // Overweight does not change the footprint. - assert_eq!(MessageQueue::footprint(Here), fp(2, 2, 16)); + // `ready_pages` decreases but `page` count does not. + assert_eq!(MessageQueue::footprint(Here), fp(2, 0, 2, 16)); // Now execute the second message. assert_eq!( @@ -1078,7 +1078,7 @@ fn footprint_num_pages_works() { .unwrap(), 3.into_weight() ); - assert_eq!(MessageQueue::footprint(Here), fp(1, 1, 8)); + assert_eq!(MessageQueue::footprint(Here), fp(1, 0, 1, 8)); // And the first one: assert_eq!( ::execute_overweight(2.into_weight(), (Here, 0, 0)) @@ -1086,6 +1086,11 @@ fn footprint_num_pages_works() { 2.into_weight() ); assert_eq!(MessageQueue::footprint(Here), Default::default()); + assert_eq!(MessageQueue::footprint(Here), fp(0, 0, 0, 0)); + + // `ready_pages` and normal `pages` increases again: + MessageQueue::enqueue_message(msg("weight=3"), Here); + assert_eq!(MessageQueue::footprint(Here), fp(1, 1, 1, 8)); }) } diff --git a/substrate/frame/support/src/traits/messages.rs b/substrate/frame/support/src/traits/messages.rs index 995ac4f7179..f3d893bcc1d 100644 --- a/substrate/frame/support/src/traits/messages.rs +++ b/substrate/frame/support/src/traits/messages.rs @@ -123,6 +123,8 @@ impl ServiceQueues for NoopServiceQueues { pub struct QueueFootprint { /// The number of pages in the queue (including overweight pages). pub pages: u32, + /// The number of pages that are ready (not yet processed and also not overweight). + pub ready_pages: u32, /// The storage footprint of the queue (including overweight messages). pub storage: Footprint, } -- GitLab From 8f8297e9debe79139e3a41be8b54a5fcd603f783 Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Wed, 6 Mar 2024 01:49:18 +0100 Subject: [PATCH 351/392] Permissioned contract deployment (#3377) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes: #3196 --------- Co-authored-by: Alexander Theißen Co-authored-by: PG Herveou --- .../contracts-rococo/src/contracts.rs | 3 + prdoc/pr_3377.prdoc | 14 ++ substrate/bin/node/runtime/src/lib.rs | 2 + .../src/parachain/contracts_config.rs | 4 +- substrate/frame/contracts/src/lib.rs | 35 ++++- substrate/frame/contracts/src/tests.rs | 131 +++++++++++++++++- 6 files changed, 182 insertions(+), 7 deletions(-) create mode 100644 prdoc/pr_3377.prdoc diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/contracts.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/contracts.rs index 681b95ce6a5..171ac6a9528 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/contracts.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/contracts.rs @@ -21,6 +21,7 @@ use frame_support::{ parameter_types, traits::{ConstBool, ConstU32, Nothing}, }; +use frame_system::EnsureSigned; use pallet_contracts::{ weights::SubstrateWeight, Config, DebugInfo, DefaultAddressGenerator, Frame, Schedule, }; @@ -65,6 +66,8 @@ impl Config for Runtime { type MaxCodeLen = ConstU32<{ 123 * 1024 }>; type MaxStorageKeyLen = ConstU32<128>; type UnsafeUnstableInterface = ConstBool; + type UploadOrigin = EnsureSigned; + type InstantiateOrigin = EnsureSigned; type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>; type MaxDelegateDependencies = ConstU32<32>; type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent; diff --git a/prdoc/pr_3377.prdoc b/prdoc/pr_3377.prdoc new file mode 100644 index 00000000000..8e5b3935512 --- /dev/null +++ b/prdoc/pr_3377.prdoc @@ -0,0 +1,14 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Permissioned contract deployment + +doc: + - audience: Runtime Dev + description: | + This PR introduces two new config types that specify the origins allowed to + upload and instantiate contract code. However, this check is not enforced when + a contract instantiates another contract. + +crates: +- name: pallet-contracts diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index f4615802515..18ce13cff80 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -1365,6 +1365,8 @@ impl pallet_contracts::Config for Runtime { type MaxCodeLen = ConstU32<{ 123 * 1024 }>; type MaxStorageKeyLen = ConstU32<128>; type UnsafeUnstableInterface = ConstBool; + type UploadOrigin = EnsureSigned; + type InstantiateOrigin = EnsureSigned; type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>; type RuntimeHoldReason = RuntimeHoldReason; #[cfg(not(feature = "runtime-benchmarks"))] diff --git a/substrate/frame/contracts/mock-network/src/parachain/contracts_config.rs b/substrate/frame/contracts/mock-network/src/parachain/contracts_config.rs index 3f26c6f372e..3c06131dd60 100644 --- a/substrate/frame/contracts/mock-network/src/parachain/contracts_config.rs +++ b/substrate/frame/contracts/mock-network/src/parachain/contracts_config.rs @@ -25,7 +25,7 @@ use frame_support::{ traits::{ConstBool, ConstU32, Contains, Randomness}, weights::Weight, }; -use frame_system::pallet_prelude::BlockNumberFor; +use frame_system::{pallet_prelude::BlockNumberFor, EnsureSigned}; use pallet_xcm::BalanceOf; use sp_runtime::{traits::Convert, Perbill}; @@ -90,6 +90,8 @@ impl pallet_contracts::Config for Runtime { type Schedule = Schedule; type Time = super::Timestamp; type UnsafeUnstableInterface = ConstBool; + type UploadOrigin = EnsureSigned; + type InstantiateOrigin = EnsureSigned; type WeightInfo = (); type WeightPrice = Self; type Debug = (); diff --git a/substrate/frame/contracts/src/lib.rs b/substrate/frame/contracts/src/lib.rs index 32d789a458f..f941f152ffe 100644 --- a/substrate/frame/contracts/src/lib.rs +++ b/substrate/frame/contracts/src/lib.rs @@ -379,6 +379,24 @@ pub mod pallet { #[pallet::constant] type MaxDebugBufferLen: Get; + /// Origin allowed to upload code. + /// + /// By default, it is safe to set this to `EnsureSigned`, allowing anyone to upload contract + /// code. + type UploadOrigin: EnsureOrigin; + + /// Origin allowed to instantiate code. + /// + /// # Note + /// + /// This is not enforced when a contract instantiates another contract. The + /// [`Self::UploadOrigin`] should make sure that no code is deployed that does unwanted + /// instantiations. + /// + /// By default, it is safe to set this to `EnsureSigned`, allowing anyone to instantiate + /// contract code. + type InstantiateOrigin: EnsureOrigin; + /// Overarching hold reason. type RuntimeHoldReason: From; @@ -636,7 +654,7 @@ pub mod pallet { determinism: Determinism, ) -> DispatchResult { Migration::::ensure_migrated()?; - let origin = ensure_signed(origin)?; + let origin = T::UploadOrigin::ensure_origin(origin)?; Self::bare_upload_code(origin, code, storage_deposit_limit.map(Into::into), determinism) .map(|_| ()) } @@ -785,11 +803,17 @@ pub mod pallet { salt: Vec, ) -> DispatchResultWithPostInfo { Migration::::ensure_migrated()?; - let origin = ensure_signed(origin)?; + + // These two origins will usually be the same; however, we treat them as separate since + // it is possible for the `Success` value of `UploadOrigin` and `InstantiateOrigin` to + // differ. + let upload_origin = T::UploadOrigin::ensure_origin(origin.clone())?; + let instantiate_origin = T::InstantiateOrigin::ensure_origin(origin)?; + let code_len = code.len() as u32; let (module, upload_deposit) = Self::try_upload_code( - origin.clone(), + upload_origin, code, storage_deposit_limit.clone().map(Into::into), Determinism::Enforced, @@ -803,7 +827,7 @@ pub mod pallet { let data_len = data.len() as u32; let salt_len = salt.len() as u32; let common = CommonInput { - origin: Origin::from_account_id(origin), + origin: Origin::from_account_id(instantiate_origin), value, data, gas_limit, @@ -844,10 +868,11 @@ pub mod pallet { salt: Vec, ) -> DispatchResultWithPostInfo { Migration::::ensure_migrated()?; + let origin = T::InstantiateOrigin::ensure_origin(origin)?; let data_len = data.len() as u32; let salt_len = salt.len() as u32; let common = CommonInput { - origin: Origin::from_runtime_origin(origin)?, + origin: Origin::from_account_id(origin), value, data, gas_limit, diff --git a/substrate/frame/contracts/src/tests.rs b/substrate/frame/contracts/src/tests.rs index 2d1c5b315a3..2f8f6d4a437 100644 --- a/substrate/frame/contracts/src/tests.rs +++ b/substrate/frame/contracts/src/tests.rs @@ -45,6 +45,7 @@ use frame_support::{ assert_err, assert_err_ignore_postinfo, assert_err_with_weight, assert_noop, assert_ok, derive_impl, dispatch::{DispatchErrorWithPostInfo, PostDispatchInfo}, + pallet_prelude::EnsureOrigin, parameter_types, storage::child, traits::{ @@ -434,6 +435,33 @@ impl Contains for TestFilter { } } +parameter_types! { + pub static UploadAccount: Option<::AccountId> = None; + pub static InstantiateAccount: Option<::AccountId> = None; +} + +pub struct EnsureAccount(sp_std::marker::PhantomData<(T, A)>); +impl>>> + EnsureOrigin<::RuntimeOrigin> for EnsureAccount +where + ::AccountId: From, +{ + type Success = T::AccountId; + + fn try_origin(o: T::RuntimeOrigin) -> Result { + let who = as EnsureOrigin<_>>::try_origin(o.clone())?; + if matches!(A::get(), Some(a) if who != a) { + return Err(o) + } + + Ok(who) + } + + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin() -> Result { + Err(()) + } +} parameter_types! { pub static UnstableInterface: bool = true; } @@ -458,6 +486,8 @@ impl Config for Test { type MaxCodeLen = ConstU32<{ 123 * 1024 }>; type MaxStorageKeyLen = ConstU32<128>; type UnsafeUnstableInterface = UnstableInterface; + type UploadOrigin = EnsureAccount; + type InstantiateOrigin = EnsureAccount; type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>; type RuntimeHoldReason = RuntimeHoldReason; type Migrations = crate::migration::codegen::BenchMigrations; @@ -5924,7 +5954,106 @@ fn root_cannot_instantiate() { vec![], vec![], ), - DispatchError::RootNotAllowed + DispatchError::BadOrigin + ); + }); +} + +#[test] +fn only_upload_origin_can_upload() { + let (wasm, _) = compile_module::("dummy").unwrap(); + UploadAccount::set(Some(ALICE)); + ExtBuilder::default().build().execute_with(|| { + let _ = Balances::set_balance(&ALICE, 1_000_000); + let _ = Balances::set_balance(&BOB, 1_000_000); + + assert_err!( + Contracts::upload_code( + RuntimeOrigin::root(), + wasm.clone(), + None, + Determinism::Enforced, + ), + DispatchError::BadOrigin + ); + + assert_err!( + Contracts::upload_code( + RuntimeOrigin::signed(BOB), + wasm.clone(), + None, + Determinism::Enforced, + ), + DispatchError::BadOrigin + ); + + // Only alice is allowed to upload contract code. + assert_ok!(Contracts::upload_code( + RuntimeOrigin::signed(ALICE), + wasm.clone(), + None, + Determinism::Enforced, + )); + }); +} + +#[test] +fn only_instantiation_origin_can_instantiate() { + let (code, code_hash) = compile_module::("dummy").unwrap(); + InstantiateAccount::set(Some(ALICE)); + ExtBuilder::default().build().execute_with(|| { + let _ = Balances::set_balance(&ALICE, 1_000_000); + let _ = Balances::set_balance(&BOB, 1_000_000); + + assert_err_ignore_postinfo!( + Contracts::instantiate_with_code( + RuntimeOrigin::root(), + 0, + GAS_LIMIT, + None, + code.clone(), + vec![], + vec![], + ), + DispatchError::BadOrigin + ); + + assert_err_ignore_postinfo!( + Contracts::instantiate_with_code( + RuntimeOrigin::signed(BOB), + 0, + GAS_LIMIT, + None, + code.clone(), + vec![], + vec![], + ), + DispatchError::BadOrigin + ); + + // Only Alice can instantiate + assert_ok!(Contracts::instantiate_with_code( + RuntimeOrigin::signed(ALICE), + 0, + GAS_LIMIT, + None, + code, + vec![], + vec![], + ),); + + // Bob cannot instantiate with either `instantiate_with_code` or `instantiate`. + assert_err_ignore_postinfo!( + Contracts::instantiate( + RuntimeOrigin::signed(BOB), + 0, + GAS_LIMIT, + None, + code_hash, + vec![], + vec![], + ), + DispatchError::BadOrigin ); }); } -- GitLab From 475e7a147676a4e7a9d255ddc7969dd35ea22882 Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Wed, 6 Mar 2024 07:47:33 +0100 Subject: [PATCH 352/392] Contracts: Charge min amount when processing deletion queue (#2934) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Alexander Theißen --- substrate/frame/contracts/src/storage.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/substrate/frame/contracts/src/storage.rs b/substrate/frame/contracts/src/storage.rs index 3304166607d..52c5150ca21 100644 --- a/substrate/frame/contracts/src/storage.rs +++ b/substrate/frame/contracts/src/storage.rs @@ -322,7 +322,8 @@ impl ContractInfo { KillStorageResult::SomeRemaining(_) => return weight_limit, KillStorageResult::AllRemoved(keys_removed) => { entry.remove(); - remaining_key_budget = remaining_key_budget.saturating_sub(keys_removed); + // charge at least one key even if none were removed. + remaining_key_budget = remaining_key_budget.saturating_sub(keys_removed.max(1)); }, }; } -- GitLab From f5bf4654e0b9cd089d1ca38ff3d692543ed555d3 Mon Sep 17 00:00:00 2001 From: Usama Ali Date: Wed, 6 Mar 2024 18:18:56 +0500 Subject: [PATCH 353/392] FIX: Make `sc-network-sync` types Public (#3586) This PR makes `sc-network-sync` types public following [this](https://github.com/paritytech/polkadot-sdk/issues/3556) issue. Fixes #3556 --- substrate/client/network/sync/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/client/network/sync/src/lib.rs b/substrate/client/network/sync/src/lib.rs index e23a23e735d..9f6c0f45d08 100644 --- a/substrate/client/network/sync/src/lib.rs +++ b/substrate/client/network/sync/src/lib.rs @@ -28,7 +28,7 @@ mod justification_requests; mod pending_responses; mod request_metrics; mod schema; -mod types; +pub mod types; pub mod block_relay_protocol; pub mod block_request_handler; -- GitLab From adce09057dc3853a62af8b399fe046c60a2777ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= <123550+andresilva@users.noreply.github.com> Date: Wed, 6 Mar 2024 14:54:36 +0000 Subject: [PATCH 354/392] sc-manual-seal: don't spawn threads in tests (#3595) Hopefully helps with test flakiness. --- .../client/consensus/manual-seal/src/lib.rs | 68 ++++++++----------- 1 file changed, 27 insertions(+), 41 deletions(-) diff --git a/substrate/client/consensus/manual-seal/src/lib.rs b/substrate/client/consensus/manual-seal/src/lib.rs index e3608f6716c..f04c0d42d60 100644 --- a/substrate/client/consensus/manual-seal/src/lib.rs +++ b/substrate/client/consensus/manual-seal/src/lib.rs @@ -429,7 +429,9 @@ mod tests { sender, } }); - let future = run_manual_seal(ManualSealParams { + + // spawn the background authorship task + tokio::spawn(run_manual_seal(ManualSealParams { block_import: client.clone(), env, client: client.clone(), @@ -438,12 +440,8 @@ mod tests { select_chain, create_inherent_data_providers: |_, _| async { Ok(()) }, consensus_data_provider: None, - }); - std::thread::spawn(|| { - let rt = tokio::runtime::Runtime::new().unwrap(); - // spawn the background authorship task - rt.block_on(future); - }); + })); + // submit a transaction to pool. let result = pool.submit_one(genesis_hash, SOURCE, uxt(Alice, 0)).await; // assert that it was successfully imported @@ -507,7 +505,8 @@ mod tests { } }); - let future_instant_seal = run_manual_seal(ManualSealParams { + // spawn the background authorship task + tokio::spawn(run_manual_seal(ManualSealParams { block_import: client.clone(), commands_stream, env, @@ -516,24 +515,16 @@ mod tests { select_chain, create_inherent_data_providers: |_, _| async { Ok(()) }, consensus_data_provider: None, - }); - std::thread::spawn(|| { - let rt = tokio::runtime::Runtime::new().unwrap(); - // spawn the background authorship task - rt.block_on(future_instant_seal); - }); + })); let delay_sec = 5; - let future_delayed_finalize = run_delayed_finalize(DelayedFinalizeParams { + + // spawn the background finality task + tokio::spawn(run_delayed_finalize(DelayedFinalizeParams { client: client.clone(), delay_sec, spawn_handle: spawner, - }); - std::thread::spawn(|| { - let rt = tokio::runtime::Runtime::new().unwrap(); - // spawn the background authorship task - rt.block_on(future_delayed_finalize); - }); + })); let mut finality_stream = client.finality_notification_stream(); // submit a transaction to pool. @@ -589,7 +580,9 @@ mod tests { // this test checks that blocks are created as soon as an engine command is sent over the // stream. let (mut sink, commands_stream) = futures::channel::mpsc::channel(1024); - let future = run_manual_seal(ManualSealParams { + + // spawn the background authorship task + tokio::spawn(run_manual_seal(ManualSealParams { block_import: client.clone(), env, client: client.clone(), @@ -598,12 +591,8 @@ mod tests { select_chain, consensus_data_provider: None, create_inherent_data_providers: |_, _| async { Ok(()) }, - }); - std::thread::spawn(|| { - let rt = tokio::runtime::Runtime::new().unwrap(); - // spawn the background authorship task - rt.block_on(future); - }); + })); + // submit a transaction to pool. let result = pool.submit_one(genesis_hash, SOURCE, uxt(Alice, 0)).await; // assert that it was successfully imported @@ -675,7 +664,9 @@ mod tests { // this test checks that blocks are created as soon as an engine command is sent over the // stream. let (mut sink, commands_stream) = futures::channel::mpsc::channel(1024); - let future = run_manual_seal(ManualSealParams { + + // spawn the background authorship task + tokio::spawn(run_manual_seal(ManualSealParams { block_import: client.clone(), env, client: client.clone(), @@ -684,12 +675,8 @@ mod tests { select_chain, consensus_data_provider: None, create_inherent_data_providers: |_, _| async { Ok(()) }, - }); - std::thread::spawn(|| { - let rt = tokio::runtime::Runtime::new().unwrap(); - // spawn the background authorship task - rt.block_on(future); - }); + })); + // submit a transaction to pool. let result = pool.submit_one(genesis_hash, SOURCE, uxt(Alice, 0)).await; // assert that it was successfully imported @@ -781,7 +768,9 @@ mod tests { let env = ProposerFactory::new(spawner.clone(), client.clone(), pool.clone(), None, None); let (mut sink, commands_stream) = futures::channel::mpsc::channel(1024); - let future = run_manual_seal(ManualSealParams { + + // spawn the background authorship task + tokio::spawn(run_manual_seal(ManualSealParams { block_import: client.clone(), env, client: client.clone(), @@ -791,11 +780,8 @@ mod tests { // use a provider that pushes some post digest data consensus_data_provider: Some(Box::new(TestDigestProvider { _client: client.clone() })), create_inherent_data_providers: |_, _| async { Ok(()) }, - }); - std::thread::spawn(|| { - let rt = tokio::runtime::Runtime::new().unwrap(); - rt.block_on(future); - }); + })); + let (tx, rx) = futures::channel::oneshot::channel(); sink.send(EngineCommand::SealNewBlock { parent_hash: None, -- GitLab From f2f4b154d7641ef3c237a0d7df4b77280b5a81d0 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> Date: Wed, 6 Mar 2024 17:52:30 +0200 Subject: [PATCH 355/392] chainHead/follow: Provide multiple block hashes to the initialized event (#3445) This PR extends the Initialized event of the chainHead_follow subscription. Now, the event provides multiple finalized block hashes. This information allows clients that are disconnected, and that want to reconnect, to not lose information about the state of the chain. At the moment, the spec encourages servers to provide at least 1 minute of finalized blocks (~10 blocks). The users are responsible for unpinning these blocks at a later time. This PR tries to report at least 1 finalized block and at most 16 blocks, if they are available. Closes: https://github.com/paritytech/polkadot-sdk/issues/3432 cc @paritytech/subxt-team --------- Signed-off-by: Alexandru Vasile Co-authored-by: Niklas Adolfsson --- .../src/chain_head/chain_head_follow.rs | 63 +++++++++++++++---- .../rpc-spec-v2/src/chain_head/event.rs | 16 ++--- .../rpc-spec-v2/src/chain_head/tests.rs | 22 ++++--- 3 files changed, 73 insertions(+), 28 deletions(-) diff --git a/substrate/client/rpc-spec-v2/src/chain_head/chain_head_follow.rs b/substrate/client/rpc-spec-v2/src/chain_head/chain_head_follow.rs index e94374aebd9..afa99f3aa16 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/chain_head_follow.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/chain_head_follow.rs @@ -42,7 +42,14 @@ use sp_blockchain::{ Backend as BlockChainBackend, Error as BlockChainError, HeaderBackend, HeaderMetadata, Info, }; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; -use std::{collections::HashSet, sync::Arc}; +use std::{ + collections::{HashSet, VecDeque}, + sync::Arc, +}; + +/// The maximum number of finalized blocks provided by the +/// `Initialized` event. +const MAX_FINALIZED_BLOCKS: usize = 16; use super::subscription::InsertedSubscriptionData; @@ -95,6 +102,8 @@ struct InitialBlocks { /// /// It is a tuple of (block hash, parent hash). finalized_block_descendants: Vec<(Block::Hash, Block::Hash)>, + /// Hashes of the last finalized blocks + finalized_block_hashes: VecDeque, /// Blocks that should not be reported as pruned by the `Finalized` event. /// /// Substrate database will perform the pruning of height N at @@ -178,13 +187,14 @@ where } /// Get the in-memory blocks of the client, starting from the provided finalized hash. + /// + /// The reported blocks are pinned by this function. fn get_init_blocks_with_forks( &self, - startup_point: &StartupPoint, + finalized: Block::Hash, ) -> Result, SubscriptionManagementError> { let blockchain = self.backend.blockchain(); let leaves = blockchain.leaves()?; - let finalized = startup_point.finalized_hash; let mut pruned_forks = HashSet::new(); let mut finalized_block_descendants = Vec::new(); let mut unique_descendants = HashSet::new(); @@ -198,17 +208,47 @@ where // Ensure a `NewBlock` event is generated for all children of the // finalized block. Describe the tree route as (child_node, parent_node) // Note: the order of elements matters here. - let parents = std::iter::once(finalized).chain(blocks.clone()); + let mut parent = finalized; + for child in blocks { + let pair = (child, parent); - for pair in blocks.zip(parents) { if unique_descendants.insert(pair) { + // The finalized block is pinned below. + self.sub_handle.pin_block(&self.sub_id, child)?; finalized_block_descendants.push(pair); } + + parent = child; } } } - Ok(InitialBlocks { finalized_block_descendants, pruned_forks }) + let mut current_block = finalized; + // The header of the finalized block must not be pruned. + let Some(header) = blockchain.header(current_block)? else { + return Err(SubscriptionManagementError::BlockHeaderAbsent); + }; + + // Report at most `MAX_FINALIZED_BLOCKS`. Note: The node might not have that many blocks. + let mut finalized_block_hashes = VecDeque::with_capacity(MAX_FINALIZED_BLOCKS); + + // Pin the finalized block. + self.sub_handle.pin_block(&self.sub_id, current_block)?; + finalized_block_hashes.push_front(current_block); + current_block = *header.parent_hash(); + + for _ in 0..MAX_FINALIZED_BLOCKS - 1 { + let Ok(Some(header)) = blockchain.header(current_block) else { break }; + // Block cannot be reported if pinning fails. + if self.sub_handle.pin_block(&self.sub_id, current_block).is_err() { + break + }; + + finalized_block_hashes.push_front(current_block); + current_block = *header.parent_hash(); + } + + Ok(InitialBlocks { finalized_block_descendants, finalized_block_hashes, pruned_forks }) } /// Generate the initial events reported by the RPC `follow` method. @@ -220,18 +260,17 @@ where startup_point: &StartupPoint, ) -> Result<(Vec>, HashSet), SubscriptionManagementError> { - let init = self.get_init_blocks_with_forks(startup_point)?; + let init = self.get_init_blocks_with_forks(startup_point.finalized_hash)?; + // The initialized event is the first one sent. let initial_blocks = init.finalized_block_descendants; + let finalized_block_hashes = init.finalized_block_hashes; - // The initialized event is the first one sent. let finalized_block_hash = startup_point.finalized_hash; - self.sub_handle.pin_block(&self.sub_id, finalized_block_hash)?; - let finalized_block_runtime = self.generate_runtime_event(finalized_block_hash, None); let initialized_event = FollowEvent::Initialized(Initialized { - finalized_block_hash, + finalized_block_hashes: finalized_block_hashes.into(), finalized_block_runtime, with_runtime: self.with_runtime, }); @@ -240,8 +279,6 @@ where finalized_block_descendants.push(initialized_event); for (child, parent) in initial_blocks.into_iter() { - self.sub_handle.pin_block(&self.sub_id, child)?; - let new_runtime = self.generate_runtime_event(child, Some(parent)); let event = FollowEvent::NewBlock(NewBlock { diff --git a/substrate/client/rpc-spec-v2/src/chain_head/event.rs b/substrate/client/rpc-spec-v2/src/chain_head/event.rs index 560ab87eab4..e0c804d16eb 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/event.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/event.rs @@ -111,8 +111,8 @@ impl From for RuntimeEvent { #[derive(Debug, Clone, PartialEq, Deserialize)] #[serde(rename_all = "camelCase")] pub struct Initialized { - /// The hash of the latest finalized block. - pub finalized_block_hash: Hash, + /// The hash of the lastest finalized blocks. + pub finalized_block_hashes: Vec, /// The runtime version of the finalized block. /// /// # Note @@ -135,12 +135,12 @@ impl Serialize for Initialized { { if self.with_runtime { let mut state = serializer.serialize_struct("Initialized", 2)?; - state.serialize_field("finalizedBlockHash", &self.finalized_block_hash)?; + state.serialize_field("finalizedBlockHashes", &self.finalized_block_hashes)?; state.serialize_field("finalizedBlockRuntime", &self.finalized_block_runtime)?; state.end() } else { let mut state = serializer.serialize_struct("Initialized", 1)?; - state.serialize_field("finalizedBlockHash", &self.finalized_block_hash)?; + state.serialize_field("finalizedBlockHashes", &self.finalized_block_hashes)?; state.end() } } @@ -348,13 +348,13 @@ mod tests { fn follow_initialized_event_no_updates() { // Runtime flag is false. let event: FollowEvent = FollowEvent::Initialized(Initialized { - finalized_block_hash: "0x1".into(), + finalized_block_hashes: vec!["0x1".into()], finalized_block_runtime: None, with_runtime: false, }); let ser = serde_json::to_string(&event).unwrap(); - let exp = r#"{"event":"initialized","finalizedBlockHash":"0x1"}"#; + let exp = r#"{"event":"initialized","finalizedBlockHashes":["0x1"]}"#; assert_eq!(ser, exp); let event_dec: FollowEvent = serde_json::from_str(exp).unwrap(); @@ -373,7 +373,7 @@ mod tests { let runtime_event = RuntimeEvent::Valid(RuntimeVersionEvent { spec: runtime.into() }); let mut initialized = Initialized { - finalized_block_hash: "0x1".into(), + finalized_block_hashes: vec!["0x1".into()], finalized_block_runtime: Some(runtime_event), with_runtime: true, }; @@ -381,7 +381,7 @@ mod tests { let ser = serde_json::to_string(&event).unwrap(); let exp = concat!( - r#"{"event":"initialized","finalizedBlockHash":"0x1","#, + r#"{"event":"initialized","finalizedBlockHashes":["0x1"],"#, r#""finalizedBlockRuntime":{"type":"valid","spec":{"specName":"ABC","implName":"Impl","#, r#""specVersion":1,"implVersion":0,"apis":{},"transactionVersion":0}}}"#, ); diff --git a/substrate/client/rpc-spec-v2/src/chain_head/tests.rs b/substrate/client/rpc-spec-v2/src/chain_head/tests.rs index 89d8c4ce271..4d9dfb24e0a 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/tests.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/tests.rs @@ -173,7 +173,7 @@ async fn follow_subscription_produces_blocks() { // Initialized must always be reported first. let event: FollowEvent = get_next_event(&mut sub).await; let expected = FollowEvent::Initialized(Initialized { - finalized_block_hash: format!("{:?}", finalized_hash), + finalized_block_hashes: vec![format!("{:?}", finalized_hash)], finalized_block_runtime: None, with_runtime: false, }); @@ -255,7 +255,7 @@ async fn follow_with_runtime() { Some(RuntimeEvent::Valid(RuntimeVersionEvent { spec: runtime.clone().into() })); // Runtime must always be reported with the first event. let expected = FollowEvent::Initialized(Initialized { - finalized_block_hash: format!("{:?}", finalized_hash), + finalized_block_hashes: vec![format!("{:?}", finalized_hash)], finalized_block_runtime, with_runtime: false, }); @@ -1344,7 +1344,7 @@ async fn follow_generates_initial_blocks() { // Initialized must always be reported first. let event: FollowEvent = get_next_event(&mut sub).await; let expected = FollowEvent::Initialized(Initialized { - finalized_block_hash: format!("{:?}", finalized_hash), + finalized_block_hashes: vec![format!("{:?}", finalized_hash)], finalized_block_runtime: None, with_runtime: false, }); @@ -1896,7 +1896,7 @@ async fn follow_prune_best_block() { // Initialized must always be reported first. let event: FollowEvent = get_next_event(&mut sub).await; let expected = FollowEvent::Initialized(Initialized { - finalized_block_hash: format!("{:?}", finalized_hash), + finalized_block_hashes: vec![format!("{:?}", finalized_hash)], finalized_block_runtime: None, with_runtime: false, }); @@ -2081,6 +2081,7 @@ async fn follow_forks_pruned_block() { // ^^^ finalized // -> block 1 -> block 2_f -> block 3_f // + let finalized_hash = client.info().finalized_hash; let block_1 = BlockBuilderBuilder::new(&*client) .on_parent_block(client.chain_info().genesis_hash) @@ -2090,6 +2091,7 @@ async fn follow_forks_pruned_block() { .build() .unwrap() .block; + let block_1_hash = block_1.header.hash(); client.import(BlockOrigin::Own, block_1.clone()).await.unwrap(); let block_2 = BlockBuilderBuilder::new(&*client) @@ -2100,6 +2102,7 @@ async fn follow_forks_pruned_block() { .build() .unwrap() .block; + let block_2_hash = block_2.header.hash(); client.import(BlockOrigin::Own, block_2.clone()).await.unwrap(); let block_3 = BlockBuilderBuilder::new(&*client) @@ -2156,7 +2159,12 @@ async fn follow_forks_pruned_block() { // Initialized must always be reported first. let event: FollowEvent = get_next_event(&mut sub).await; let expected = FollowEvent::Initialized(Initialized { - finalized_block_hash: format!("{:?}", block_3_hash), + finalized_block_hashes: vec![ + format!("{:?}", finalized_hash), + format!("{:?}", block_1_hash), + format!("{:?}", block_2_hash), + format!("{:?}", block_3_hash), + ], finalized_block_runtime: None, with_runtime: false, }); @@ -2310,7 +2318,7 @@ async fn follow_report_multiple_pruned_block() { // Initialized must always be reported first. let event: FollowEvent = get_next_event(&mut sub).await; let expected = FollowEvent::Initialized(Initialized { - finalized_block_hash: format!("{:?}", finalized_hash), + finalized_block_hashes: vec![format!("{:?}", finalized_hash)], finalized_block_runtime: None, with_runtime: false, }); @@ -2632,7 +2640,7 @@ async fn follow_finalized_before_new_block() { let finalized_hash = client.info().finalized_hash; let event: FollowEvent = get_next_event(&mut sub).await; let expected = FollowEvent::Initialized(Initialized { - finalized_block_hash: format!("{:?}", finalized_hash), + finalized_block_hashes: vec![format!("{:?}", finalized_hash)], finalized_block_runtime: None, with_runtime: false, }); -- GitLab From 9952786e1b688109b1571248042d71b82bbe2256 Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Wed, 6 Mar 2024 17:35:55 +0100 Subject: [PATCH 356/392] Contracts upload with Determinism::Enforced when possible (#3540) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cyrill Leutwiler Co-authored-by: command-bot <> Co-authored-by: Alexander Theißen --- prdoc/pr_3540.prdoc | 10 + .../frame/contracts/src/benchmarking/code.rs | 19 +- .../frame/contracts/src/benchmarking/mod.rs | 27 +- substrate/frame/contracts/src/lib.rs | 11 +- substrate/frame/contracts/src/tests.rs | 20 + substrate/frame/contracts/src/wasm/mod.rs | 5 + substrate/frame/contracts/src/wasm/prepare.rs | 25 +- substrate/frame/contracts/src/weights.rs | 1275 +++++++++-------- 8 files changed, 756 insertions(+), 636 deletions(-) create mode 100644 prdoc/pr_3540.prdoc diff --git a/prdoc/pr_3540.prdoc b/prdoc/pr_3540.prdoc new file mode 100644 index 00000000000..d0a91882b6b --- /dev/null +++ b/prdoc/pr_3540.prdoc @@ -0,0 +1,10 @@ +title: "[pallet-contracts] Only allow non-deterministic code to be uploaded with Determinism::Relaxed" + +doc: + - audience: Runtime Dev + description: | + The `upload_code` extrinsic, will now only allow non-deterministic code to be uploaded with the `Determinism::Relaxed` flag. + This prevent an attacker from uploading "deterministic" code with the `Determinism::Relaxed` flag, preventing the code to be instantiated for on-chain execution. + +crates: + - name: pallet-contracts diff --git a/substrate/frame/contracts/src/benchmarking/code.rs b/substrate/frame/contracts/src/benchmarking/code.rs index 644c2abf0a8..96ce11f8c41 100644 --- a/substrate/frame/contracts/src/benchmarking/code.rs +++ b/substrate/frame/contracts/src/benchmarking/code.rs @@ -26,7 +26,7 @@ use crate::Config; use frame_support::traits::Get; -use sp_runtime::traits::Hash; +use sp_runtime::{traits::Hash, Saturating}; use sp_std::{borrow::ToOwned, prelude::*}; use wasm_instrument::parity_wasm::{ builder, @@ -262,22 +262,25 @@ impl WasmModule { /// `instantiate_with_code` for different sizes of wasm modules. The generated module maximizes /// instrumentation runtime by nesting blocks as deeply as possible given the byte budget. /// `code_location`: Whether to place the code into `deploy` or `call`. - pub fn sized(target_bytes: u32, code_location: Location) -> Self { + pub fn sized(target_bytes: u32, code_location: Location, use_float: bool) -> Self { use self::elements::Instruction::{End, GetLocal, If, Return}; // Base size of a contract is 63 bytes and each expansion adds 6 bytes. // We do one expansion less to account for the code section and function body // size fields inside the binary wasm module representation which are leb128 encoded // and therefore grow in size when the contract grows. We are not allowed to overshoot // because of the maximum code size that is enforced by `instantiate_with_code`. - let expansions = (target_bytes.saturating_sub(63) / 6).saturating_sub(1); + let mut expansions = (target_bytes.saturating_sub(63) / 6).saturating_sub(1); const EXPANSION: [Instruction; 4] = [GetLocal(0), If(BlockType::NoResult), Return, End]; + let mut locals = vec![Local::new(1, ValueType::I32)]; + if use_float { + locals.push(Local::new(1, ValueType::F32)); + locals.push(Local::new(2, ValueType::F32)); + locals.push(Local::new(3, ValueType::F32)); + expansions.saturating_dec(); + } let mut module = ModuleDefinition { memory: Some(ImportedMemory::max::()), ..Default::default() }; - let body = Some(body::repeated_with_locals( - &[Local::new(1, ValueType::I32)], - expansions, - &EXPANSION, - )); + let body = Some(body::repeated_with_locals(&locals, expansions, &EXPANSION)); match code_location { Location::Call => module.call_body = body, Location::Deploy => module.deploy_body = body, diff --git a/substrate/frame/contracts/src/benchmarking/mod.rs b/substrate/frame/contracts/src/benchmarking/mod.rs index 4b6ff63c6f5..2ecd56b412d 100644 --- a/substrate/frame/contracts/src/benchmarking/mod.rs +++ b/substrate/frame/contracts/src/benchmarking/mod.rs @@ -362,7 +362,7 @@ benchmarks! { call_with_code_per_byte { let c in 0 .. T::MaxCodeLen::get(); let instance = Contract::::with_caller( - whitelisted_caller(), WasmModule::sized(c, Location::Deploy), vec![], + whitelisted_caller(), WasmModule::sized(c, Location::Deploy, false), vec![], )?; let value = Pallet::::min_balance(); let origin = RawOrigin::Signed(instance.caller.clone()); @@ -389,7 +389,7 @@ benchmarks! { let value = Pallet::::min_balance(); let caller = whitelisted_caller(); T::Currency::set_balance(&caller, caller_funding::()); - let WasmModule { code, hash, .. } = WasmModule::::sized(c, Location::Call); + let WasmModule { code, hash, .. } = WasmModule::::sized(c, Location::Call, false); let origin = RawOrigin::Signed(caller.clone()); let addr = Contracts::::contract_address(&caller, &hash, &input, &salt); }: _(origin, value, Weight::MAX, None, code, input, salt) @@ -468,19 +468,36 @@ benchmarks! { // It creates a maximum number of metering blocks per byte. // `c`: Size of the code in bytes. #[pov_mode = Measured] - upload_code { + upload_code_determinism_enforced { let c in 0 .. T::MaxCodeLen::get(); let caller = whitelisted_caller(); T::Currency::set_balance(&caller, caller_funding::()); - let WasmModule { code, hash, .. } = WasmModule::::sized(c, Location::Call); + let WasmModule { code, hash, .. } = WasmModule::::sized(c, Location::Call, false); let origin = RawOrigin::Signed(caller.clone()); - }: _(origin, code, None, Determinism::Enforced) + }: upload_code(origin, code, None, Determinism::Enforced) verify { // uploading the code reserves some balance in the callers account assert!(T::Currency::total_balance_on_hold(&caller) > 0u32.into()); assert!(>::code_exists(&hash)); } + // Uploading code with [`Determinism::Relaxed`] should be more expensive than uploading code with [`Determinism::Enforced`], + // as we always try to save the code with [`Determinism::Enforced`] first. + #[pov_mode = Measured] + upload_code_determinism_relaxed { + let c in 0 .. T::MaxCodeLen::get(); + let caller = whitelisted_caller(); + T::Currency::set_balance(&caller, caller_funding::()); + let WasmModule { code, hash, .. } = WasmModule::::sized(c, Location::Call, true); + let origin = RawOrigin::Signed(caller.clone()); + }: upload_code(origin, code, None, Determinism::Relaxed) + verify { + assert!(T::Currency::total_balance_on_hold(&caller) > 0u32.into()); + assert!(>::code_exists(&hash)); + // Ensure that the benchmark follows the most expensive path, i.e., the code is saved with [`Determinism::Relaxed`] after trying to save it with [`Determinism::Enforced`]. + assert_eq!(CodeInfoOf::::get(&hash).unwrap().determinism(), Determinism::Relaxed); + } + // Removing code does not depend on the size of the contract because all the information // needed to verify the removal claim (refcount, owner) is stored in a separate storage // item (`CodeInfoOf`). diff --git a/substrate/frame/contracts/src/lib.rs b/substrate/frame/contracts/src/lib.rs index f941f152ffe..0511bcf7f3f 100644 --- a/substrate/frame/contracts/src/lib.rs +++ b/substrate/frame/contracts/src/lib.rs @@ -645,8 +645,17 @@ pub mod pallet { /// To avoid this situation a constructor could employ access control so that it can /// only be instantiated by permissioned entities. The same is true when uploading /// through [`Self::instantiate_with_code`]. + /// + /// Use [`Determinism::Relaxed`] exclusively for non-deterministic code. If the uploaded + /// code is deterministic, specifying [`Determinism::Relaxed`] will be disregarded and + /// result in higher gas costs. #[pallet::call_index(3)] - #[pallet::weight(T::WeightInfo::upload_code(code.len() as u32))] + #[pallet::weight( + match determinism { + Determinism::Enforced => T::WeightInfo::upload_code_determinism_enforced(code.len() as u32), + Determinism::Relaxed => T::WeightInfo::upload_code_determinism_relaxed(code.len() as u32), + } + )] pub fn upload_code( origin: OriginFor, code: Vec, diff --git a/substrate/frame/contracts/src/tests.rs b/substrate/frame/contracts/src/tests.rs index 2f8f6d4a437..011b2b25b2b 100644 --- a/substrate/frame/contracts/src/tests.rs +++ b/substrate/frame/contracts/src/tests.rs @@ -5185,6 +5185,26 @@ fn deposit_limit_honors_min_leftover() { }); } +#[test] +fn upload_should_enforce_deterministic_mode_when_possible() { + let upload = |fixture, determinism| { + let (wasm, code_hash) = compile_module::(fixture).unwrap(); + ExtBuilder::default() + .build() + .execute_with(|| -> Result { + let _ = ::Currency::set_balance(&ALICE, 1_000_000); + Contracts::bare_upload_code(ALICE, wasm, None, determinism)?; + let info = CodeInfoOf::::get(code_hash).unwrap(); + Ok(info.determinism()) + }) + }; + + assert_eq!(upload("dummy", Determinism::Enforced), Ok(Determinism::Enforced)); + assert_eq!(upload("dummy", Determinism::Relaxed), Ok(Determinism::Enforced)); + assert_eq!(upload("float_instruction", Determinism::Relaxed), Ok(Determinism::Relaxed)); + assert!(upload("float_instruction", Determinism::Enforced).is_err()); +} + #[test] fn cannot_instantiate_indeterministic_code() { let (wasm, code_hash) = compile_module::("float_instruction").unwrap(); diff --git a/substrate/frame/contracts/src/wasm/mod.rs b/substrate/frame/contracts/src/wasm/mod.rs index 34b45cba5d2..87e92cd72e8 100644 --- a/substrate/frame/contracts/src/wasm/mod.rs +++ b/substrate/frame/contracts/src/wasm/mod.rs @@ -313,6 +313,11 @@ impl CodeInfo { } } + /// Returns the determinism of the module. + pub fn determinism(&self) -> Determinism { + self.determinism + } + /// Returns reference count of the module. pub fn refcount(&self) -> u64 { self.refcount diff --git a/substrate/frame/contracts/src/wasm/prepare.rs b/substrate/frame/contracts/src/wasm/prepare.rs index 5cdf5600fcd..5efea8c3a23 100644 --- a/substrate/frame/contracts/src/wasm/prepare.rs +++ b/substrate/frame/contracts/src/wasm/prepare.rs @@ -79,7 +79,10 @@ impl LoadedModule { } let engine = Engine::new(&config); - let module = Module::new(&engine, code).map_err(|_| "Can't load the module into wasmi!")?; + let module = Module::new(&engine, code).map_err(|err| { + log::debug!(target: LOG_TARGET, "Module creation failed: {:?}", err); + "Can't load the module into wasmi!" + })?; // Return a `LoadedModule` instance with // __valid__ module. @@ -220,7 +223,7 @@ impl LoadedModule { fn validate( code: &[u8], schedule: &Schedule, - determinism: Determinism, + determinism: &mut Determinism, ) -> Result<(), (DispatchError, &'static str)> where E: Environment<()>, @@ -229,7 +232,17 @@ where (|| { // We check that the module is generally valid, // and does not have restricted WebAssembly features, here. - let contract_module = LoadedModule::new::(code, determinism, None)?; + let contract_module = match *determinism { + Determinism::Relaxed => + if let Ok(module) = LoadedModule::new::(code, Determinism::Enforced, None) { + *determinism = Determinism::Enforced; + module + } else { + LoadedModule::new::(code, Determinism::Relaxed, None)? + }, + Determinism::Enforced => LoadedModule::new::(code, Determinism::Enforced, None)?, + }; + // The we check that module satisfies constraints the pallet puts on contracts. contract_module.scan_exports()?; contract_module.scan_imports::(schedule)?; @@ -252,7 +265,7 @@ where &code, (), schedule, - determinism, + *determinism, stack_limits, AllowDeprecatedInterface::No, ) @@ -276,13 +289,13 @@ pub fn prepare( code: CodeVec, schedule: &Schedule, owner: AccountIdOf, - determinism: Determinism, + mut determinism: Determinism, ) -> Result, (DispatchError, &'static str)> where E: Environment<()>, T: Config, { - validate::(code.as_ref(), schedule, determinism)?; + validate::(code.as_ref(), schedule, &mut determinism)?; // Calculate deposit for storing contract code and `code_info` in two different storage items. let code_len = code.len() as u32; diff --git a/substrate/frame/contracts/src/weights.rs b/substrate/frame/contracts/src/weights.rs index 47ca17c7d80..6e09120c141 100644 --- a/substrate/frame/contracts/src/weights.rs +++ b/substrate/frame/contracts/src/weights.rs @@ -18,27 +18,25 @@ //! Autogenerated weights for `pallet_contracts` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-03-04, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-p5qp1txx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate-node +// target/production/substrate-node // benchmark // pallet -// --chain=dev // --steps=50 // --repeat=20 -// --pallet=pallet_contracts -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/contracts/src/weights.rs +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_contracts +// --chain=dev // --header=./substrate/HEADER-APACHE2 +// --output=./substrate/frame/contracts/src/weights.rs // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -69,7 +67,8 @@ pub trait WeightInfo { fn instantiate_with_code(c: u32, i: u32, s: u32, ) -> Weight; fn instantiate(i: u32, s: u32, ) -> Weight; fn call() -> Weight; - fn upload_code(c: u32, ) -> Weight; + fn upload_code_determinism_enforced(c: u32, ) -> Weight; + fn upload_code_determinism_relaxed(c: u32, ) -> Weight; fn remove_code() -> Weight; fn set_code() -> Weight; fn seal_caller(r: u32, ) -> Weight; @@ -143,8 +142,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 2_103_000 picoseconds. - Weight::from_parts(2_260_000, 1627) + // Minimum execution time: 2_054_000 picoseconds. + Weight::from_parts(2_178_000, 1627) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -154,10 +153,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `452 + k * (69 ±0)` // Estimated: `442 + k * (70 ±0)` - // Minimum execution time: 12_173_000 picoseconds. - Weight::from_parts(12_515_000, 442) - // Standard Error: 1_033 - .saturating_add(Weight::from_parts(1_075_765, 0).saturating_mul(k.into())) + // Minimum execution time: 12_119_000 picoseconds. + Weight::from_parts(12_536_000, 442) + // Standard Error: 1_254 + .saturating_add(Weight::from_parts(1_161_885, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(T::DbWeight::get().writes(2_u64)) @@ -171,10 +170,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `211 + c * (1 ±0)` // Estimated: `6149 + c * (1 ±0)` - // Minimum execution time: 8_054_000 picoseconds. - Weight::from_parts(8_503_485, 6149) + // Minimum execution time: 8_146_000 picoseconds. + Weight::from_parts(8_560_745, 6149) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_184, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(1_182, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -187,8 +186,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `510` // Estimated: `6450` - // Minimum execution time: 16_966_000 picoseconds. - Weight::from_parts(17_445_000, 6450) + // Minimum execution time: 16_183_000 picoseconds. + Weight::from_parts(16_825_000, 6450) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -201,10 +200,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `171 + k * (1 ±0)` // Estimated: `3635 + k * (1 ±0)` - // Minimum execution time: 3_643_000 picoseconds. - Weight::from_parts(3_714_000, 3635) - // Standard Error: 1_056 - .saturating_add(Weight::from_parts(1_089_042, 0).saturating_mul(k.into())) + // Minimum execution time: 3_645_000 picoseconds. + Weight::from_parts(604_365, 3635) + // Standard Error: 1_013 + .saturating_add(Weight::from_parts(1_100_277, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(k.into()))) @@ -225,10 +224,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `328 + c * (1 ±0)` // Estimated: `6266 + c * (1 ±0)` - // Minimum execution time: 19_891_000 picoseconds. - Weight::from_parts(19_961_608, 6266) + // Minimum execution time: 19_500_000 picoseconds. + Weight::from_parts(20_074_895, 6266) // Standard Error: 1 - .saturating_add(Weight::from_parts(429, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(422, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -239,8 +238,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `440` // Estimated: `6380` - // Minimum execution time: 12_483_000 picoseconds. - Weight::from_parts(13_205_000, 6380) + // Minimum execution time: 12_530_000 picoseconds. + Weight::from_parts(13_362_000, 6380) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -254,8 +253,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `352` // Estimated: `6292` - // Minimum execution time: 42_443_000 picoseconds. - Weight::from_parts(43_420_000, 6292) + // Minimum execution time: 44_275_000 picoseconds. + Weight::from_parts(45_718_000, 6292) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -267,8 +266,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `594` // Estimated: `6534` - // Minimum execution time: 52_282_000 picoseconds. - Weight::from_parts(54_110_000, 6534) + // Minimum execution time: 55_095_000 picoseconds. + Weight::from_parts(58_009_000, 6534) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -278,8 +277,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 2_539_000 picoseconds. - Weight::from_parts(2_644_000, 1627) + // Minimum execution time: 2_455_000 picoseconds. + Weight::from_parts(2_608_000, 1627) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -291,8 +290,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `166` // Estimated: `3631` - // Minimum execution time: 9_473_000 picoseconds. - Weight::from_parts(9_907_000, 3631) + // Minimum execution time: 11_207_000 picoseconds. + Weight::from_parts(11_802_000, 3631) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -302,8 +301,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 3_532_000 picoseconds. - Weight::from_parts(3_768_000, 3607) + // Minimum execution time: 4_581_000 picoseconds. + Weight::from_parts(4_781_000, 3607) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -314,8 +313,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `167` // Estimated: `3632` - // Minimum execution time: 5_036_000 picoseconds. - Weight::from_parts(5_208_000, 3632) + // Minimum execution time: 5_887_000 picoseconds. + Weight::from_parts(6_393_000, 3632) .saturating_add(T::DbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -326,8 +325,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 4_881_000 picoseconds. - Weight::from_parts(5_149_000, 3607) + // Minimum execution time: 6_025_000 picoseconds. + Weight::from_parts(6_298_000, 3607) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -352,10 +351,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `804 + c * (1 ±0)` // Estimated: `9217 + c * (1 ±0)` - // Minimum execution time: 280_047_000 picoseconds. - Weight::from_parts(270_065_882, 9217) - // Standard Error: 86 - .saturating_add(Weight::from_parts(34_361, 0).saturating_mul(c.into())) + // Minimum execution time: 294_976_000 picoseconds. + Weight::from_parts(277_235_948, 9217) + // Standard Error: 65 + .saturating_add(Weight::from_parts(34_445, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -387,14 +386,14 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `326` // Estimated: `8740` - // Minimum execution time: 3_776_071_000 picoseconds. - Weight::from_parts(706_212_213, 8740) - // Standard Error: 149 - .saturating_add(Weight::from_parts(98_798, 0).saturating_mul(c.into())) - // Standard Error: 17 - .saturating_add(Weight::from_parts(1_560, 0).saturating_mul(i.into())) - // Standard Error: 17 - .saturating_add(Weight::from_parts(1_476, 0).saturating_mul(s.into())) + // Minimum execution time: 3_864_558_000 picoseconds. + Weight::from_parts(421_676_889, 8740) + // Standard Error: 188 + .saturating_add(Weight::from_parts(103_788, 0).saturating_mul(c.into())) + // Standard Error: 22 + .saturating_add(Weight::from_parts(1_715, 0).saturating_mul(i.into())) + // Standard Error: 22 + .saturating_add(Weight::from_parts(1_774, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(14_u64)) .saturating_add(T::DbWeight::get().writes(10_u64)) } @@ -424,12 +423,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `563` // Estimated: `8982` - // Minimum execution time: 1_966_301_000 picoseconds. - Weight::from_parts(376_287_434, 8982) - // Standard Error: 7 - .saturating_add(Weight::from_parts(1_643, 0).saturating_mul(i.into())) - // Standard Error: 7 - .saturating_add(Weight::from_parts(1_667, 0).saturating_mul(s.into())) + // Minimum execution time: 2_069_276_000 picoseconds. + Weight::from_parts(377_210_279, 8982) + // Standard Error: 9 + .saturating_add(Weight::from_parts(1_719, 0).saturating_mul(i.into())) + // Standard Error: 9 + .saturating_add(Weight::from_parts(1_728, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(13_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } @@ -453,8 +452,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `829` // Estimated: `9244` - // Minimum execution time: 197_571_000 picoseconds. - Weight::from_parts(206_612_000, 9244) + // Minimum execution time: 199_037_000 picoseconds. + Weight::from_parts(213_931_000, 9244) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -471,14 +470,38 @@ impl WeightInfo for SubstrateWeight { /// Storage: `Contracts::PristineCode` (r:0 w:1) /// Proof: `Contracts::PristineCode` (`max_values`: None, `max_size`: Some(125988), added: 128463, mode: `Measured`) /// The range of component `c` is `[0, 125952]`. - fn upload_code(c: u32, ) -> Weight { + fn upload_code_determinism_enforced(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `145` // Estimated: `6085` - // Minimum execution time: 266_006_000 picoseconds. - Weight::from_parts(287_700_788, 6085) - // Standard Error: 67 - .saturating_add(Weight::from_parts(63_196, 0).saturating_mul(c.into())) + // Minimum execution time: 278_482_000 picoseconds. + Weight::from_parts(262_753_879, 6085) + // Standard Error: 112 + .saturating_add(Weight::from_parts(66_129, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(6_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) + } + /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) + /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:2 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) + /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) + /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) + /// Storage: `System::EventTopics` (r:1 w:1) + /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Contracts::PristineCode` (r:0 w:1) + /// Proof: `Contracts::PristineCode` (`max_values`: None, `max_size`: Some(125988), added: 128463, mode: `Measured`) + /// The range of component `c` is `[0, 125952]`. + fn upload_code_determinism_relaxed(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `145` + // Estimated: `6085` + // Minimum execution time: 286_902_000 picoseconds. + Weight::from_parts(269_003_959, 6085) + // Standard Error: 123 + .saturating_add(Weight::from_parts(66_629, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -496,8 +519,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `315` // Estimated: `3780` - // Minimum execution time: 42_714_000 picoseconds. - Weight::from_parts(44_713_000, 3780) + // Minimum execution time: 44_128_000 picoseconds. + Weight::from_parts(46_044_000, 3780) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -513,8 +536,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `552` // Estimated: `8967` - // Minimum execution time: 33_516_000 picoseconds. - Weight::from_parts(34_823_000, 8967) + // Minimum execution time: 33_567_000 picoseconds. + Weight::from_parts(35_057_000, 8967) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -539,10 +562,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `869 + r * (6 ±0)` // Estimated: `9284 + r * (6 ±0)` - // Minimum execution time: 246_563_000 picoseconds. - Weight::from_parts(274_999_814, 9284) - // Standard Error: 628 - .saturating_add(Weight::from_parts(347_395, 0).saturating_mul(r.into())) + // Minimum execution time: 272_376_000 picoseconds. + Weight::from_parts(284_162_161, 9284) + // Standard Error: 501 + .saturating_add(Weight::from_parts(341_575, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -568,10 +591,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `925 + r * (209 ±0)` // Estimated: `9304 + r * (2684 ±0)` - // Minimum execution time: 252_236_000 picoseconds. - Weight::from_parts(121_390_081, 9304) - // Standard Error: 6_206 - .saturating_add(Weight::from_parts(3_558_718, 0).saturating_mul(r.into())) + // Minimum execution time: 256_990_000 picoseconds. + Weight::from_parts(107_167_044, 9304) + // Standard Error: 7_545 + .saturating_add(Weight::from_parts(3_628_112, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -598,10 +621,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `924 + r * (213 ±0)` // Estimated: `9308 + r * (2688 ±0)` - // Minimum execution time: 269_427_000 picoseconds. - Weight::from_parts(134_879_389, 9308) - // Standard Error: 6_711 - .saturating_add(Weight::from_parts(4_408_658, 0).saturating_mul(r.into())) + // Minimum execution time: 272_889_000 picoseconds. + Weight::from_parts(110_341_799, 9308) + // Standard Error: 7_881 + .saturating_add(Weight::from_parts(4_427_043, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -628,10 +651,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `876 + r * (6 ±0)` // Estimated: `9293 + r * (6 ±0)` - // Minimum execution time: 249_382_000 picoseconds. - Weight::from_parts(266_305_110, 9293) - // Standard Error: 1_592 - .saturating_add(Weight::from_parts(460_001, 0).saturating_mul(r.into())) + // Minimum execution time: 275_027_000 picoseconds. + Weight::from_parts(283_302_223, 9293) + // Standard Error: 1_179 + .saturating_add(Weight::from_parts(436_023, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -657,10 +680,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `866 + r * (3 ±0)` // Estimated: `9282 + r * (3 ±0)` - // Minimum execution time: 252_145_000 picoseconds. - Weight::from_parts(277_211_668, 9282) - // Standard Error: 371 - .saturating_add(Weight::from_parts(174_394, 0).saturating_mul(r.into())) + // Minimum execution time: 270_137_000 picoseconds. + Weight::from_parts(282_756_362, 9282) + // Standard Error: 384 + .saturating_add(Weight::from_parts(171_660, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -684,10 +707,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `756 + r * (3 ±0)` // Estimated: `9171 + r * (3 ±0)` - // Minimum execution time: 251_595_000 picoseconds. - Weight::from_parts(268_102_575, 9171) - // Standard Error: 334 - .saturating_add(Weight::from_parts(154_836, 0).saturating_mul(r.into())) + // Minimum execution time: 255_131_000 picoseconds. + Weight::from_parts(269_207_006, 9171) + // Standard Error: 542 + .saturating_add(Weight::from_parts(161_597, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(10_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -713,10 +736,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `870 + r * (6 ±0)` // Estimated: `9285 + r * (6 ±0)` - // Minimum execution time: 251_404_000 picoseconds. - Weight::from_parts(278_747_574, 9285) - // Standard Error: 782 - .saturating_add(Weight::from_parts(341_598, 0).saturating_mul(r.into())) + // Minimum execution time: 272_172_000 picoseconds. + Weight::from_parts(283_747_134, 9285) + // Standard Error: 885 + .saturating_add(Weight::from_parts(343_968, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -742,10 +765,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `866 + r * (6 ±0)` // Estimated: `9284 + r * (6 ±0)` - // Minimum execution time: 255_649_000 picoseconds. - Weight::from_parts(276_509_641, 9284) - // Standard Error: 1_262 - .saturating_add(Weight::from_parts(380_225, 0).saturating_mul(r.into())) + // Minimum execution time: 263_220_000 picoseconds. + Weight::from_parts(277_062_382, 9284) + // Standard Error: 1_783 + .saturating_add(Weight::from_parts(399_631, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -771,10 +794,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1010 + r * (6 ±0)` // Estimated: `9409 + r * (6 ±0)` - // Minimum execution time: 267_143_000 picoseconds. - Weight::from_parts(298_166_116, 9409) - // Standard Error: 3_765 - .saturating_add(Weight::from_parts(1_620_886, 0).saturating_mul(r.into())) + // Minimum execution time: 253_218_000 picoseconds. + Weight::from_parts(282_251_452, 9409) + // Standard Error: 2_367 + .saturating_add(Weight::from_parts(1_604_060, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -800,10 +823,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `880 + r * (6 ±0)` // Estimated: `9301 + r * (6 ±0)` - // Minimum execution time: 250_013_000 picoseconds. - Weight::from_parts(281_469_583, 9301) - // Standard Error: 730 - .saturating_add(Weight::from_parts(339_260, 0).saturating_mul(r.into())) + // Minimum execution time: 271_797_000 picoseconds. + Weight::from_parts(288_594_393, 9301) + // Standard Error: 846 + .saturating_add(Weight::from_parts(335_063, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -829,10 +852,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `878 + r * (6 ±0)` // Estimated: `9294 + r * (6 ±0)` - // Minimum execution time: 256_219_000 picoseconds. - Weight::from_parts(275_309_266, 9294) - // Standard Error: 1_199 - .saturating_add(Weight::from_parts(350_824, 0).saturating_mul(r.into())) + // Minimum execution time: 254_997_000 picoseconds. + Weight::from_parts(284_331_894, 9294) + // Standard Error: 885 + .saturating_add(Weight::from_parts(337_073, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -858,10 +881,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `875 + r * (6 ±0)` // Estimated: `9297 + r * (6 ±0)` - // Minimum execution time: 264_644_000 picoseconds. - Weight::from_parts(283_856_744, 9297) - // Standard Error: 623 - .saturating_add(Weight::from_parts(334_175, 0).saturating_mul(r.into())) + // Minimum execution time: 273_845_000 picoseconds. + Weight::from_parts(285_291_242, 9297) + // Standard Error: 690 + .saturating_add(Weight::from_parts(332_783, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -887,10 +910,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `866 + r * (6 ±0)` // Estimated: `9282 + r * (6 ±0)` - // Minimum execution time: 263_364_000 picoseconds. - Weight::from_parts(281_379_508, 9282) - // Standard Error: 639 - .saturating_add(Weight::from_parts(338_021, 0).saturating_mul(r.into())) + // Minimum execution time: 268_302_000 picoseconds. + Weight::from_parts(280_463_257, 9282) + // Standard Error: 1_035 + .saturating_add(Weight::from_parts(345_811, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -918,10 +941,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `940 + r * (14 ±0)` // Estimated: `9350 + r * (14 ±0)` - // Minimum execution time: 269_667_000 picoseconds. - Weight::from_parts(284_662_802, 9350) - // Standard Error: 691 - .saturating_add(Weight::from_parts(799_249, 0).saturating_mul(r.into())) + // Minimum execution time: 263_433_000 picoseconds. + Weight::from_parts(290_098_370, 9350) + // Standard Error: 1_905 + .saturating_add(Weight::from_parts(805_299, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 14).saturating_mul(r.into())) @@ -947,10 +970,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `868 + r * (6 ±0)` // Estimated: `9285 + r * (6 ±0)` - // Minimum execution time: 267_018_000 picoseconds. - Weight::from_parts(281_842_630, 9285) - // Standard Error: 453 - .saturating_add(Weight::from_parts(255_373, 0).saturating_mul(r.into())) + // Minimum execution time: 273_588_000 picoseconds. + Weight::from_parts(287_133_565, 9285) + // Standard Error: 799 + .saturating_add(Weight::from_parts(254_114, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -976,10 +999,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `872` // Estimated: `9287` - // Minimum execution time: 258_208_000 picoseconds. - Weight::from_parts(227_686_792, 9287) - // Standard Error: 23 - .saturating_add(Weight::from_parts(989, 0).saturating_mul(n.into())) + // Minimum execution time: 257_843_000 picoseconds. + Weight::from_parts(228_177_495, 9287) + // Standard Error: 24 + .saturating_add(Weight::from_parts(985, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1004,8 +1027,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `856 + r * (45 ±0)` // Estimated: `9271 + r * (45 ±0)` - // Minimum execution time: 245_714_000 picoseconds. - Weight::from_parts(272_527_059, 9271) + // Minimum execution time: 248_332_000 picoseconds. + Weight::from_parts(274_998_906, 9271) + // Standard Error: 949_561 + .saturating_add(Weight::from_parts(5_570_693, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 45).saturating_mul(r.into())) @@ -1031,10 +1056,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `866` // Estimated: `9288` - // Minimum execution time: 256_060_000 picoseconds. - Weight::from_parts(276_710_811, 9288) - // Standard Error: 0 - .saturating_add(Weight::from_parts(312, 0).saturating_mul(n.into())) + // Minimum execution time: 272_055_000 picoseconds. + Weight::from_parts(282_280_090, 9288) + // Standard Error: 1 + .saturating_add(Weight::from_parts(330, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1065,10 +1090,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2902 + r * (529 ±0)` // Estimated: `11317 + r * (5479 ±0)` - // Minimum execution time: 270_479_000 picoseconds. - Weight::from_parts(296_706_989, 11317) - // Standard Error: 813_407 - .saturating_add(Weight::from_parts(109_236_910, 0).saturating_mul(r.into())) + // Minimum execution time: 274_842_000 picoseconds. + Weight::from_parts(299_824_497, 11317) + // Standard Error: 902_686 + .saturating_add(Weight::from_parts(106_562_902, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1098,10 +1123,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `947 + r * (10 ±0)` // Estimated: `9363 + r * (10 ±0)` - // Minimum execution time: 251_787_000 picoseconds. - Weight::from_parts(284_036_313, 9363) - // Standard Error: 2_560 - .saturating_add(Weight::from_parts(1_238_301, 0).saturating_mul(r.into())) + // Minimum execution time: 255_393_000 picoseconds. + Weight::from_parts(309_814_338, 9363) + // Standard Error: 2_978 + .saturating_add(Weight::from_parts(1_203_507, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -1127,10 +1152,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `866 + r * (10 ±0)` // Estimated: `9283 + r * (10 ±0)` - // Minimum execution time: 250_566_000 picoseconds. - Weight::from_parts(275_402_784, 9283) - // Standard Error: 3_939 - .saturating_add(Weight::from_parts(1_941_995, 0).saturating_mul(r.into())) + // Minimum execution time: 250_378_000 picoseconds. + Weight::from_parts(287_003_144, 9283) + // Standard Error: 2_726 + .saturating_add(Weight::from_parts(1_850_967, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -1157,12 +1182,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `883 + t * (32 ±0)` // Estimated: `9303 + t * (2508 ±0)` - // Minimum execution time: 267_544_000 picoseconds. - Weight::from_parts(280_117_825, 9303) - // Standard Error: 102_111 - .saturating_add(Weight::from_parts(3_253_038, 0).saturating_mul(t.into())) - // Standard Error: 28 - .saturating_add(Weight::from_parts(668, 0).saturating_mul(n.into())) + // Minimum execution time: 266_787_000 picoseconds. + Weight::from_parts(284_368_661, 9303) + // Standard Error: 121_315 + .saturating_add(Weight::from_parts(2_690_211, 0).saturating_mul(t.into())) + // Standard Error: 33 + .saturating_add(Weight::from_parts(789, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1190,10 +1215,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `865 + r * (7 ±0)` // Estimated: `9285 + r * (7 ±0)` - // Minimum execution time: 157_769_000 picoseconds. - Weight::from_parts(173_026_565, 9285) - // Standard Error: 405 - .saturating_add(Weight::from_parts(219_727, 0).saturating_mul(r.into())) + // Minimum execution time: 166_804_000 picoseconds. + Weight::from_parts(175_118_291, 9285) + // Standard Error: 398 + .saturating_add(Weight::from_parts(220_961, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 7).saturating_mul(r.into())) @@ -1219,10 +1244,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `125816` // Estimated: `131758` - // Minimum execution time: 403_961_000 picoseconds. - Weight::from_parts(376_480_872, 131758) + // Minimum execution time: 398_436_000 picoseconds. + Weight::from_parts(385_003_285, 131758) // Standard Error: 12 - .saturating_add(Weight::from_parts(1_041, 0).saturating_mul(i.into())) + .saturating_add(Weight::from_parts(1_038, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1233,10 +1258,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `927 + r * (292 ±0)` // Estimated: `929 + r * (293 ±0)` - // Minimum execution time: 256_272_000 picoseconds. - Weight::from_parts(181_058_379, 929) - // Standard Error: 9_838 - .saturating_add(Weight::from_parts(6_316_677, 0).saturating_mul(r.into())) + // Minimum execution time: 274_099_000 picoseconds. + Weight::from_parts(174_282_817, 929) + // Standard Error: 10_547 + .saturating_add(Weight::from_parts(6_262_173, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1250,10 +1275,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1450` // Estimated: `1433` - // Minimum execution time: 268_713_000 picoseconds. - Weight::from_parts(328_329_131, 1433) + // Minimum execution time: 274_061_000 picoseconds. + Weight::from_parts(334_755_333, 1433) // Standard Error: 66 - .saturating_add(Weight::from_parts(962, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(771, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(15_u64)) .saturating_add(T::DbWeight::get().writes(8_u64)) } @@ -1264,10 +1289,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1256 + n * (1 ±0)` // Estimated: `1256 + n * (1 ±0)` - // Minimum execution time: 265_683_000 picoseconds. - Weight::from_parts(293_784_477, 1256) - // Standard Error: 31 - .saturating_add(Weight::from_parts(377, 0).saturating_mul(n.into())) + // Minimum execution time: 272_657_000 picoseconds. + Weight::from_parts(299_061_594, 1256) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1279,10 +1302,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `924 + r * (288 ±0)` // Estimated: `930 + r * (289 ±0)` - // Minimum execution time: 269_959_000 picoseconds. - Weight::from_parts(186_065_911, 930) - // Standard Error: 9_679 - .saturating_add(Weight::from_parts(6_286_855, 0).saturating_mul(r.into())) + // Minimum execution time: 270_524_000 picoseconds. + Weight::from_parts(177_959_667, 930) + // Standard Error: 10_397 + .saturating_add(Weight::from_parts(6_270_181, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1296,8 +1319,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1252 + n * (1 ±0)` // Estimated: `1252 + n * (1 ±0)` - // Minimum execution time: 265_805_000 picoseconds. - Weight::from_parts(294_633_695, 1252) + // Minimum execution time: 270_757_000 picoseconds. + Weight::from_parts(298_627_896, 1252) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1309,10 +1332,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `924 + r * (296 ±0)` // Estimated: `926 + r * (297 ±0)` - // Minimum execution time: 264_592_000 picoseconds. - Weight::from_parts(204_670_461, 926) - // Standard Error: 6_869 - .saturating_add(Weight::from_parts(5_137_920, 0).saturating_mul(r.into())) + // Minimum execution time: 268_082_000 picoseconds. + Weight::from_parts(202_583_730, 926) + // Standard Error: 9_029 + .saturating_add(Weight::from_parts(5_028_517, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1325,10 +1348,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1268 + n * (1 ±0)` // Estimated: `1268 + n * (1 ±0)` - // Minimum execution time: 273_165_000 picoseconds. - Weight::from_parts(297_883_669, 1268) - // Standard Error: 37 - .saturating_add(Weight::from_parts(576, 0).saturating_mul(n.into())) + // Minimum execution time: 274_100_000 picoseconds. + Weight::from_parts(296_981_515, 1268) + // Standard Error: 34 + .saturating_add(Weight::from_parts(578, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1340,10 +1363,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `935 + r * (288 ±0)` // Estimated: `932 + r * (289 ±0)` - // Minimum execution time: 252_257_000 picoseconds. - Weight::from_parts(205_018_595, 932) - // Standard Error: 7_605 - .saturating_add(Weight::from_parts(4_933_378, 0).saturating_mul(r.into())) + // Minimum execution time: 269_697_000 picoseconds. + Weight::from_parts(198_346_516, 932) + // Standard Error: 8_623 + .saturating_add(Weight::from_parts(4_964_116, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1356,10 +1379,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1255 + n * (1 ±0)` // Estimated: `1255 + n * (1 ±0)` - // Minimum execution time: 266_839_000 picoseconds. - Weight::from_parts(292_064_487, 1255) - // Standard Error: 34 - .saturating_add(Weight::from_parts(194, 0).saturating_mul(n.into())) + // Minimum execution time: 264_210_000 picoseconds. + Weight::from_parts(291_387_652, 1255) + // Standard Error: 36 + .saturating_add(Weight::from_parts(524, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1371,10 +1394,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `917 + r * (296 ±0)` // Estimated: `922 + r * (297 ±0)` - // Minimum execution time: 266_072_000 picoseconds. - Weight::from_parts(189_018_352, 922) - // Standard Error: 9_530 - .saturating_add(Weight::from_parts(6_481_011, 0).saturating_mul(r.into())) + // Minimum execution time: 267_219_000 picoseconds. + Weight::from_parts(175_866_982, 922) + // Standard Error: 11_275 + .saturating_add(Weight::from_parts(6_424_755, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1388,10 +1411,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1269 + n * (1 ±0)` // Estimated: `1269 + n * (1 ±0)` - // Minimum execution time: 270_703_000 picoseconds. - Weight::from_parts(292_867_105, 1269) - // Standard Error: 30 - .saturating_add(Weight::from_parts(800, 0).saturating_mul(n.into())) + // Minimum execution time: 274_634_000 picoseconds. + Weight::from_parts(294_272_009, 1269) + // Standard Error: 36 + .saturating_add(Weight::from_parts(1_219, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1417,10 +1440,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1418 + r * (45 ±0)` // Estimated: `9785 + r * (2520 ±0)` - // Minimum execution time: 251_843_000 picoseconds. - Weight::from_parts(181_026_888, 9785) - // Standard Error: 38_221 - .saturating_add(Weight::from_parts(30_626_681, 0).saturating_mul(r.into())) + // Minimum execution time: 266_833_000 picoseconds. + Weight::from_parts(186_049_741, 9785) + // Standard Error: 40_311 + .saturating_add(Weight::from_parts(31_365_585, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) @@ -1448,10 +1471,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1263 + r * (245 ±0)` // Estimated: `9635 + r * (2721 ±0)` - // Minimum execution time: 254_881_000 picoseconds. - Weight::from_parts(272_871_000, 9635) - // Standard Error: 94_527 - .saturating_add(Weight::from_parts(233_379_497, 0).saturating_mul(r.into())) + // Minimum execution time: 272_140_000 picoseconds. + Weight::from_parts(275_009_000, 9635) + // Standard Error: 99_187 + .saturating_add(Weight::from_parts(240_702_479, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(14_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) @@ -1478,11 +1501,11 @@ impl WeightInfo for SubstrateWeight { fn seal_delegate_call(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + r * (576 ±0)` - // Estimated: `9290 + r * (2637 ±3)` - // Minimum execution time: 266_704_000 picoseconds. - Weight::from_parts(273_165_000, 9290) - // Standard Error: 141_486 - .saturating_add(Weight::from_parts(232_947_049, 0).saturating_mul(r.into())) + // Estimated: `9290 + r * (2637 ±10)` + // Minimum execution time: 263_664_000 picoseconds. + Weight::from_parts(277_240_000, 9290) + // Standard Error: 169_147 + .saturating_add(Weight::from_parts(240_084_929, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1511,12 +1534,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1310 + t * (277 ±0)` // Estimated: `12200 + t * (5227 ±0)` - // Minimum execution time: 446_451_000 picoseconds. - Weight::from_parts(68_175_222, 12200) - // Standard Error: 11_619_250 - .saturating_add(Weight::from_parts(354_237_260, 0).saturating_mul(t.into())) + // Minimum execution time: 464_644_000 picoseconds. + Weight::from_parts(40_377_313, 12200) + // Standard Error: 12_060_226 + .saturating_add(Weight::from_parts(380_635_982, 0).saturating_mul(t.into())) // Standard Error: 17 - .saturating_add(Weight::from_parts(987, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(1_014, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(16_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(6_u64)) @@ -1548,10 +1571,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1281 + r * (255 ±0)` // Estimated: `9623 + r * (2731 ±0)` - // Minimum execution time: 628_156_000 picoseconds. - Weight::from_parts(642_052_000, 9623) - // Standard Error: 223_957 - .saturating_add(Weight::from_parts(348_660_264, 0).saturating_mul(r.into())) + // Minimum execution time: 641_845_000 picoseconds. + Weight::from_parts(649_908_000, 9623) + // Standard Error: 278_514 + .saturating_add(Weight::from_parts(361_164_598, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(14_u64)) .saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(7_u64)) @@ -1585,14 +1608,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1306 + t * (104 ±0)` // Estimated: `12214 + t * (2549 ±1)` - // Minimum execution time: 2_106_379_000 picoseconds. - Weight::from_parts(1_098_227_098, 12214) - // Standard Error: 12_549_729 - .saturating_add(Weight::from_parts(21_628_382, 0).saturating_mul(t.into())) - // Standard Error: 19 - .saturating_add(Weight::from_parts(1_059, 0).saturating_mul(i.into())) - // Standard Error: 19 - .saturating_add(Weight::from_parts(1_220, 0).saturating_mul(s.into())) + // Minimum execution time: 2_111_632_000 picoseconds. + Weight::from_parts(1_213_125_745, 12214) + // Standard Error: 22 + .saturating_add(Weight::from_parts(1_055, 0).saturating_mul(i.into())) + // Standard Error: 22 + .saturating_add(Weight::from_parts(1_192, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(19_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(11_u64)) @@ -1620,10 +1641,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `865 + r * (8 ±0)` // Estimated: `9279 + r * (8 ±0)` - // Minimum execution time: 257_102_000 picoseconds. - Weight::from_parts(278_920_692, 9279) - // Standard Error: 464 - .saturating_add(Weight::from_parts(374_120, 0).saturating_mul(r.into())) + // Minimum execution time: 264_227_000 picoseconds. + Weight::from_parts(281_015_995, 9279) + // Standard Error: 710 + .saturating_add(Weight::from_parts(365_734, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1649,10 +1670,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `873` // Estimated: `9286` - // Minimum execution time: 266_609_000 picoseconds. - Weight::from_parts(263_034_132, 9286) + // Minimum execution time: 270_709_000 picoseconds. + Weight::from_parts(268_416_051, 9286) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_082, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_080, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1677,10 +1698,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `867 + r * (8 ±0)` // Estimated: `9284 + r * (8 ±0)` - // Minimum execution time: 246_275_000 picoseconds. - Weight::from_parts(279_091_594, 9284) - // Standard Error: 887 - .saturating_add(Weight::from_parts(810_394, 0).saturating_mul(r.into())) + // Minimum execution time: 267_283_000 picoseconds. + Weight::from_parts(280_706_659, 9284) + // Standard Error: 540 + .saturating_add(Weight::from_parts(790_312, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1706,10 +1727,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `875` // Estimated: `9292` - // Minimum execution time: 249_254_000 picoseconds. - Weight::from_parts(270_833_823, 9292) - // Standard Error: 0 - .saturating_add(Weight::from_parts(3_347, 0).saturating_mul(n.into())) + // Minimum execution time: 262_010_000 picoseconds. + Weight::from_parts(273_278_744, 9292) + // Standard Error: 1 + .saturating_add(Weight::from_parts(3_362, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1734,10 +1755,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `867 + r * (8 ±0)` // Estimated: `9286 + r * (8 ±0)` - // Minimum execution time: 259_131_000 picoseconds. - Weight::from_parts(272_665_020, 9286) - // Standard Error: 862 - .saturating_add(Weight::from_parts(451_247, 0).saturating_mul(r.into())) + // Minimum execution time: 268_698_000 picoseconds. + Weight::from_parts(282_890_578, 9286) + // Standard Error: 622 + .saturating_add(Weight::from_parts(441_131, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1763,10 +1784,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `875` // Estimated: `9291` - // Minimum execution time: 276_465_000 picoseconds. - Weight::from_parts(269_450_297, 9291) + // Minimum execution time: 252_846_000 picoseconds. + Weight::from_parts(267_657_561, 9291) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_190, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_208, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1791,10 +1812,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `867 + r * (8 ±0)` // Estimated: `9283 + r * (8 ±0)` - // Minimum execution time: 248_349_000 picoseconds. - Weight::from_parts(273_660_686, 9283) - // Standard Error: 656 - .saturating_add(Weight::from_parts(444_293, 0).saturating_mul(r.into())) + // Minimum execution time: 266_899_000 picoseconds. + Weight::from_parts(276_862_067, 9283) + // Standard Error: 1_249 + .saturating_add(Weight::from_parts(443_970, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1820,10 +1841,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `875` // Estimated: `9289` - // Minimum execution time: 252_107_000 picoseconds. - Weight::from_parts(267_427_726, 9289) + // Minimum execution time: 265_413_000 picoseconds. + Weight::from_parts(265_600_840, 9289) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_199, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_203, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1848,10 +1869,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1000 + n * (1 ±0)` // Estimated: `9412 + n * (1 ±0)` - // Minimum execution time: 311_252_000 picoseconds. - Weight::from_parts(333_250_773, 9412) - // Standard Error: 12 - .saturating_add(Weight::from_parts(5_668, 0).saturating_mul(n.into())) + // Minimum execution time: 328_341_000 picoseconds. + Weight::from_parts(341_038_581, 9412) + // Standard Error: 10 + .saturating_add(Weight::from_parts(5_863, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1875,12 +1896,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 160]`. fn seal_sr25519_verify(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `810 + r * (112 ±0)` + // Measured: `808 + r * (112 ±0)` // Estimated: `9226 + r * (112 ±0)` - // Minimum execution time: 267_431_000 picoseconds. - Weight::from_parts(300_733_048, 9226) - // Standard Error: 8_806 - .saturating_add(Weight::from_parts(42_169_197, 0).saturating_mul(r.into())) + // Minimum execution time: 272_730_000 picoseconds. + Weight::from_parts(339_349_232, 9226) + // Standard Error: 13_004 + .saturating_add(Weight::from_parts(41_649_026, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(r.into())) @@ -1906,10 +1927,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `910 + r * (76 ±0)` // Estimated: `9279 + r * (77 ±0)` - // Minimum execution time: 265_905_000 picoseconds. - Weight::from_parts(305_381_951, 9279) - // Standard Error: 9_863 - .saturating_add(Weight::from_parts(45_771_182, 0).saturating_mul(r.into())) + // Minimum execution time: 273_892_000 picoseconds. + Weight::from_parts(352_853_960, 9279) + // Standard Error: 16_745 + .saturating_add(Weight::from_parts(45_853_294, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 77).saturating_mul(r.into())) @@ -1935,10 +1956,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `880 + r * (42 ±0)` // Estimated: `9294 + r * (42 ±0)` - // Minimum execution time: 266_701_000 picoseconds. - Weight::from_parts(292_407_888, 9294) - // Standard Error: 5_394 - .saturating_add(Weight::from_parts(11_896_065, 0).saturating_mul(r.into())) + // Minimum execution time: 268_431_000 picoseconds. + Weight::from_parts(319_727_796, 9294) + // Standard Error: 10_276 + .saturating_add(Weight::from_parts(11_928_882, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 42).saturating_mul(r.into())) @@ -1964,10 +1985,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0 + r * (965 ±0)` // Estimated: `9285 + r * (3090 ±7)` - // Minimum execution time: 268_755_000 picoseconds. - Weight::from_parts(272_300_000, 9285) - // Standard Error: 43_747 - .saturating_add(Weight::from_parts(25_001_889, 0).saturating_mul(r.into())) + // Minimum execution time: 275_482_000 picoseconds. + Weight::from_parts(279_155_000, 9285) + // Standard Error: 65_388 + .saturating_add(Weight::from_parts(26_634_187, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1995,10 +2016,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `937 + r * (131 ±0)` // Estimated: `9346 + r * (2607 ±0)` - // Minimum execution time: 255_190_000 picoseconds. - Weight::from_parts(285_643_922, 9346) - // Standard Error: 23_582 - .saturating_add(Weight::from_parts(6_289_940, 0).saturating_mul(r.into())) + // Minimum execution time: 270_001_000 picoseconds. + Weight::from_parts(286_792_689, 9346) + // Standard Error: 21_074 + .saturating_add(Weight::from_parts(6_465_885, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -2026,10 +2047,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `972 + r * (184 ±0)` // Estimated: `129453 + r * (2568 ±0)` - // Minimum execution time: 260_061_000 picoseconds. - Weight::from_parts(286_849_343, 129453) - // Standard Error: 22_406 - .saturating_add(Weight::from_parts(5_661_459, 0).saturating_mul(r.into())) + // Minimum execution time: 270_652_000 picoseconds. + Weight::from_parts(293_369_452, 129453) + // Standard Error: 24_321 + .saturating_add(Weight::from_parts(5_575_600, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -2057,10 +2078,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `861 + r * (3 ±0)` // Estimated: `9282 + r * (3 ±0)` - // Minimum execution time: 250_922_000 picoseconds. - Weight::from_parts(277_294_913, 9282) - // Standard Error: 391 - .saturating_add(Weight::from_parts(169_457, 0).saturating_mul(r.into())) + // Minimum execution time: 267_749_000 picoseconds. + Weight::from_parts(280_373_341, 9282) + // Standard Error: 464 + .saturating_add(Weight::from_parts(170_398, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -2086,10 +2107,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2112 + r * (39 ±0)` // Estimated: `10377 + r * (40 ±0)` - // Minimum execution time: 267_293_000 picoseconds. - Weight::from_parts(309_125_635, 10377) - // Standard Error: 637 - .saturating_add(Weight::from_parts(245_508, 0).saturating_mul(r.into())) + // Minimum execution time: 270_260_000 picoseconds. + Weight::from_parts(337_969_172, 10377) + // Standard Error: 1_557 + .saturating_add(Weight::from_parts(305_735, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) @@ -2117,10 +2138,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `864 + r * (3 ±0)` // Estimated: `9279 + r * (3 ±0)` - // Minimum execution time: 256_057_000 picoseconds. - Weight::from_parts(278_068_870, 9279) - // Standard Error: 335 - .saturating_add(Weight::from_parts(152_083, 0).saturating_mul(r.into())) + // Minimum execution time: 265_607_000 picoseconds. + Weight::from_parts(283_396_630, 9279) + // Standard Error: 449 + .saturating_add(Weight::from_parts(149_018, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -2130,10 +2151,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_846_000 picoseconds. - Weight::from_parts(1_808_029, 0) - // Standard Error: 9 - .saturating_add(Weight::from_parts(14_937, 0).saturating_mul(r.into())) + // Minimum execution time: 1_813_000 picoseconds. + Weight::from_parts(1_264_945, 0) + // Standard Error: 19 + .saturating_add(Weight::from_parts(15_098, 0).saturating_mul(r.into())) } } @@ -2145,8 +2166,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 2_103_000 picoseconds. - Weight::from_parts(2_260_000, 1627) + // Minimum execution time: 2_054_000 picoseconds. + Weight::from_parts(2_178_000, 1627) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -2156,10 +2177,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `452 + k * (69 ±0)` // Estimated: `442 + k * (70 ±0)` - // Minimum execution time: 12_173_000 picoseconds. - Weight::from_parts(12_515_000, 442) - // Standard Error: 1_033 - .saturating_add(Weight::from_parts(1_075_765, 0).saturating_mul(k.into())) + // Minimum execution time: 12_119_000 picoseconds. + Weight::from_parts(12_536_000, 442) + // Standard Error: 1_254 + .saturating_add(Weight::from_parts(1_161_885, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(RocksDbWeight::get().writes(2_u64)) @@ -2173,10 +2194,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `211 + c * (1 ±0)` // Estimated: `6149 + c * (1 ±0)` - // Minimum execution time: 8_054_000 picoseconds. - Weight::from_parts(8_503_485, 6149) + // Minimum execution time: 8_146_000 picoseconds. + Weight::from_parts(8_560_745, 6149) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_184, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(1_182, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -2189,8 +2210,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `510` // Estimated: `6450` - // Minimum execution time: 16_966_000 picoseconds. - Weight::from_parts(17_445_000, 6450) + // Minimum execution time: 16_183_000 picoseconds. + Weight::from_parts(16_825_000, 6450) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2203,10 +2224,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `171 + k * (1 ±0)` // Estimated: `3635 + k * (1 ±0)` - // Minimum execution time: 3_643_000 picoseconds. - Weight::from_parts(3_714_000, 3635) - // Standard Error: 1_056 - .saturating_add(Weight::from_parts(1_089_042, 0).saturating_mul(k.into())) + // Minimum execution time: 3_645_000 picoseconds. + Weight::from_parts(604_365, 3635) + // Standard Error: 1_013 + .saturating_add(Weight::from_parts(1_100_277, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(k.into()))) @@ -2227,10 +2248,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `328 + c * (1 ±0)` // Estimated: `6266 + c * (1 ±0)` - // Minimum execution time: 19_891_000 picoseconds. - Weight::from_parts(19_961_608, 6266) + // Minimum execution time: 19_500_000 picoseconds. + Weight::from_parts(20_074_895, 6266) // Standard Error: 1 - .saturating_add(Weight::from_parts(429, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(422, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -2241,8 +2262,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `440` // Estimated: `6380` - // Minimum execution time: 12_483_000 picoseconds. - Weight::from_parts(13_205_000, 6380) + // Minimum execution time: 12_530_000 picoseconds. + Weight::from_parts(13_362_000, 6380) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2256,8 +2277,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `352` // Estimated: `6292` - // Minimum execution time: 42_443_000 picoseconds. - Weight::from_parts(43_420_000, 6292) + // Minimum execution time: 44_275_000 picoseconds. + Weight::from_parts(45_718_000, 6292) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2269,8 +2290,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `594` // Estimated: `6534` - // Minimum execution time: 52_282_000 picoseconds. - Weight::from_parts(54_110_000, 6534) + // Minimum execution time: 55_095_000 picoseconds. + Weight::from_parts(58_009_000, 6534) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -2280,8 +2301,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 2_539_000 picoseconds. - Weight::from_parts(2_644_000, 1627) + // Minimum execution time: 2_455_000 picoseconds. + Weight::from_parts(2_608_000, 1627) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2293,8 +2314,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `166` // Estimated: `3631` - // Minimum execution time: 9_473_000 picoseconds. - Weight::from_parts(9_907_000, 3631) + // Minimum execution time: 11_207_000 picoseconds. + Weight::from_parts(11_802_000, 3631) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -2304,8 +2325,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 3_532_000 picoseconds. - Weight::from_parts(3_768_000, 3607) + // Minimum execution time: 4_581_000 picoseconds. + Weight::from_parts(4_781_000, 3607) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -2316,8 +2337,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `167` // Estimated: `3632` - // Minimum execution time: 5_036_000 picoseconds. - Weight::from_parts(5_208_000, 3632) + // Minimum execution time: 5_887_000 picoseconds. + Weight::from_parts(6_393_000, 3632) .saturating_add(RocksDbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -2328,8 +2349,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 4_881_000 picoseconds. - Weight::from_parts(5_149_000, 3607) + // Minimum execution time: 6_025_000 picoseconds. + Weight::from_parts(6_298_000, 3607) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2354,10 +2375,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `804 + c * (1 ±0)` // Estimated: `9217 + c * (1 ±0)` - // Minimum execution time: 280_047_000 picoseconds. - Weight::from_parts(270_065_882, 9217) - // Standard Error: 86 - .saturating_add(Weight::from_parts(34_361, 0).saturating_mul(c.into())) + // Minimum execution time: 294_976_000 picoseconds. + Weight::from_parts(277_235_948, 9217) + // Standard Error: 65 + .saturating_add(Weight::from_parts(34_445, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -2389,14 +2410,14 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `326` // Estimated: `8740` - // Minimum execution time: 3_776_071_000 picoseconds. - Weight::from_parts(706_212_213, 8740) - // Standard Error: 149 - .saturating_add(Weight::from_parts(98_798, 0).saturating_mul(c.into())) - // Standard Error: 17 - .saturating_add(Weight::from_parts(1_560, 0).saturating_mul(i.into())) - // Standard Error: 17 - .saturating_add(Weight::from_parts(1_476, 0).saturating_mul(s.into())) + // Minimum execution time: 3_864_558_000 picoseconds. + Weight::from_parts(421_676_889, 8740) + // Standard Error: 188 + .saturating_add(Weight::from_parts(103_788, 0).saturating_mul(c.into())) + // Standard Error: 22 + .saturating_add(Weight::from_parts(1_715, 0).saturating_mul(i.into())) + // Standard Error: 22 + .saturating_add(Weight::from_parts(1_774, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(14_u64)) .saturating_add(RocksDbWeight::get().writes(10_u64)) } @@ -2426,12 +2447,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `563` // Estimated: `8982` - // Minimum execution time: 1_966_301_000 picoseconds. - Weight::from_parts(376_287_434, 8982) - // Standard Error: 7 - .saturating_add(Weight::from_parts(1_643, 0).saturating_mul(i.into())) - // Standard Error: 7 - .saturating_add(Weight::from_parts(1_667, 0).saturating_mul(s.into())) + // Minimum execution time: 2_069_276_000 picoseconds. + Weight::from_parts(377_210_279, 8982) + // Standard Error: 9 + .saturating_add(Weight::from_parts(1_719, 0).saturating_mul(i.into())) + // Standard Error: 9 + .saturating_add(Weight::from_parts(1_728, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(13_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } @@ -2455,8 +2476,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `829` // Estimated: `9244` - // Minimum execution time: 197_571_000 picoseconds. - Weight::from_parts(206_612_000, 9244) + // Minimum execution time: 199_037_000 picoseconds. + Weight::from_parts(213_931_000, 9244) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -2473,14 +2494,38 @@ impl WeightInfo for () { /// Storage: `Contracts::PristineCode` (r:0 w:1) /// Proof: `Contracts::PristineCode` (`max_values`: None, `max_size`: Some(125988), added: 128463, mode: `Measured`) /// The range of component `c` is `[0, 125952]`. - fn upload_code(c: u32, ) -> Weight { + fn upload_code_determinism_enforced(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `145` // Estimated: `6085` - // Minimum execution time: 266_006_000 picoseconds. - Weight::from_parts(287_700_788, 6085) - // Standard Error: 67 - .saturating_add(Weight::from_parts(63_196, 0).saturating_mul(c.into())) + // Minimum execution time: 278_482_000 picoseconds. + Weight::from_parts(262_753_879, 6085) + // Standard Error: 112 + .saturating_add(Weight::from_parts(66_129, 0).saturating_mul(c.into())) + .saturating_add(RocksDbWeight::get().reads(6_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) + } + /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) + /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:2 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) + /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) + /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) + /// Storage: `System::EventTopics` (r:1 w:1) + /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Contracts::PristineCode` (r:0 w:1) + /// Proof: `Contracts::PristineCode` (`max_values`: None, `max_size`: Some(125988), added: 128463, mode: `Measured`) + /// The range of component `c` is `[0, 125952]`. + fn upload_code_determinism_relaxed(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `145` + // Estimated: `6085` + // Minimum execution time: 286_902_000 picoseconds. + Weight::from_parts(269_003_959, 6085) + // Standard Error: 123 + .saturating_add(Weight::from_parts(66_629, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -2498,8 +2543,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `315` // Estimated: `3780` - // Minimum execution time: 42_714_000 picoseconds. - Weight::from_parts(44_713_000, 3780) + // Minimum execution time: 44_128_000 picoseconds. + Weight::from_parts(46_044_000, 3780) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -2515,8 +2560,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `552` // Estimated: `8967` - // Minimum execution time: 33_516_000 picoseconds. - Weight::from_parts(34_823_000, 8967) + // Minimum execution time: 33_567_000 picoseconds. + Weight::from_parts(35_057_000, 8967) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -2541,10 +2586,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `869 + r * (6 ±0)` // Estimated: `9284 + r * (6 ±0)` - // Minimum execution time: 246_563_000 picoseconds. - Weight::from_parts(274_999_814, 9284) - // Standard Error: 628 - .saturating_add(Weight::from_parts(347_395, 0).saturating_mul(r.into())) + // Minimum execution time: 272_376_000 picoseconds. + Weight::from_parts(284_162_161, 9284) + // Standard Error: 501 + .saturating_add(Weight::from_parts(341_575, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2570,10 +2615,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `925 + r * (209 ±0)` // Estimated: `9304 + r * (2684 ±0)` - // Minimum execution time: 252_236_000 picoseconds. - Weight::from_parts(121_390_081, 9304) - // Standard Error: 6_206 - .saturating_add(Weight::from_parts(3_558_718, 0).saturating_mul(r.into())) + // Minimum execution time: 256_990_000 picoseconds. + Weight::from_parts(107_167_044, 9304) + // Standard Error: 7_545 + .saturating_add(Weight::from_parts(3_628_112, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2600,10 +2645,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `924 + r * (213 ±0)` // Estimated: `9308 + r * (2688 ±0)` - // Minimum execution time: 269_427_000 picoseconds. - Weight::from_parts(134_879_389, 9308) - // Standard Error: 6_711 - .saturating_add(Weight::from_parts(4_408_658, 0).saturating_mul(r.into())) + // Minimum execution time: 272_889_000 picoseconds. + Weight::from_parts(110_341_799, 9308) + // Standard Error: 7_881 + .saturating_add(Weight::from_parts(4_427_043, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2630,10 +2675,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `876 + r * (6 ±0)` // Estimated: `9293 + r * (6 ±0)` - // Minimum execution time: 249_382_000 picoseconds. - Weight::from_parts(266_305_110, 9293) - // Standard Error: 1_592 - .saturating_add(Weight::from_parts(460_001, 0).saturating_mul(r.into())) + // Minimum execution time: 275_027_000 picoseconds. + Weight::from_parts(283_302_223, 9293) + // Standard Error: 1_179 + .saturating_add(Weight::from_parts(436_023, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2659,10 +2704,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `866 + r * (3 ±0)` // Estimated: `9282 + r * (3 ±0)` - // Minimum execution time: 252_145_000 picoseconds. - Weight::from_parts(277_211_668, 9282) - // Standard Error: 371 - .saturating_add(Weight::from_parts(174_394, 0).saturating_mul(r.into())) + // Minimum execution time: 270_137_000 picoseconds. + Weight::from_parts(282_756_362, 9282) + // Standard Error: 384 + .saturating_add(Weight::from_parts(171_660, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -2686,10 +2731,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `756 + r * (3 ±0)` // Estimated: `9171 + r * (3 ±0)` - // Minimum execution time: 251_595_000 picoseconds. - Weight::from_parts(268_102_575, 9171) - // Standard Error: 334 - .saturating_add(Weight::from_parts(154_836, 0).saturating_mul(r.into())) + // Minimum execution time: 255_131_000 picoseconds. + Weight::from_parts(269_207_006, 9171) + // Standard Error: 542 + .saturating_add(Weight::from_parts(161_597, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(10_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -2715,10 +2760,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `870 + r * (6 ±0)` // Estimated: `9285 + r * (6 ±0)` - // Minimum execution time: 251_404_000 picoseconds. - Weight::from_parts(278_747_574, 9285) - // Standard Error: 782 - .saturating_add(Weight::from_parts(341_598, 0).saturating_mul(r.into())) + // Minimum execution time: 272_172_000 picoseconds. + Weight::from_parts(283_747_134, 9285) + // Standard Error: 885 + .saturating_add(Weight::from_parts(343_968, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2744,10 +2789,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `866 + r * (6 ±0)` // Estimated: `9284 + r * (6 ±0)` - // Minimum execution time: 255_649_000 picoseconds. - Weight::from_parts(276_509_641, 9284) - // Standard Error: 1_262 - .saturating_add(Weight::from_parts(380_225, 0).saturating_mul(r.into())) + // Minimum execution time: 263_220_000 picoseconds. + Weight::from_parts(277_062_382, 9284) + // Standard Error: 1_783 + .saturating_add(Weight::from_parts(399_631, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2773,10 +2818,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1010 + r * (6 ±0)` // Estimated: `9409 + r * (6 ±0)` - // Minimum execution time: 267_143_000 picoseconds. - Weight::from_parts(298_166_116, 9409) - // Standard Error: 3_765 - .saturating_add(Weight::from_parts(1_620_886, 0).saturating_mul(r.into())) + // Minimum execution time: 253_218_000 picoseconds. + Weight::from_parts(282_251_452, 9409) + // Standard Error: 2_367 + .saturating_add(Weight::from_parts(1_604_060, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2802,10 +2847,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `880 + r * (6 ±0)` // Estimated: `9301 + r * (6 ±0)` - // Minimum execution time: 250_013_000 picoseconds. - Weight::from_parts(281_469_583, 9301) - // Standard Error: 730 - .saturating_add(Weight::from_parts(339_260, 0).saturating_mul(r.into())) + // Minimum execution time: 271_797_000 picoseconds. + Weight::from_parts(288_594_393, 9301) + // Standard Error: 846 + .saturating_add(Weight::from_parts(335_063, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2831,10 +2876,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `878 + r * (6 ±0)` // Estimated: `9294 + r * (6 ±0)` - // Minimum execution time: 256_219_000 picoseconds. - Weight::from_parts(275_309_266, 9294) - // Standard Error: 1_199 - .saturating_add(Weight::from_parts(350_824, 0).saturating_mul(r.into())) + // Minimum execution time: 254_997_000 picoseconds. + Weight::from_parts(284_331_894, 9294) + // Standard Error: 885 + .saturating_add(Weight::from_parts(337_073, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2860,10 +2905,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `875 + r * (6 ±0)` // Estimated: `9297 + r * (6 ±0)` - // Minimum execution time: 264_644_000 picoseconds. - Weight::from_parts(283_856_744, 9297) - // Standard Error: 623 - .saturating_add(Weight::from_parts(334_175, 0).saturating_mul(r.into())) + // Minimum execution time: 273_845_000 picoseconds. + Weight::from_parts(285_291_242, 9297) + // Standard Error: 690 + .saturating_add(Weight::from_parts(332_783, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2889,10 +2934,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `866 + r * (6 ±0)` // Estimated: `9282 + r * (6 ±0)` - // Minimum execution time: 263_364_000 picoseconds. - Weight::from_parts(281_379_508, 9282) - // Standard Error: 639 - .saturating_add(Weight::from_parts(338_021, 0).saturating_mul(r.into())) + // Minimum execution time: 268_302_000 picoseconds. + Weight::from_parts(280_463_257, 9282) + // Standard Error: 1_035 + .saturating_add(Weight::from_parts(345_811, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2920,10 +2965,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `940 + r * (14 ±0)` // Estimated: `9350 + r * (14 ±0)` - // Minimum execution time: 269_667_000 picoseconds. - Weight::from_parts(284_662_802, 9350) - // Standard Error: 691 - .saturating_add(Weight::from_parts(799_249, 0).saturating_mul(r.into())) + // Minimum execution time: 263_433_000 picoseconds. + Weight::from_parts(290_098_370, 9350) + // Standard Error: 1_905 + .saturating_add(Weight::from_parts(805_299, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 14).saturating_mul(r.into())) @@ -2949,10 +2994,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `868 + r * (6 ±0)` // Estimated: `9285 + r * (6 ±0)` - // Minimum execution time: 267_018_000 picoseconds. - Weight::from_parts(281_842_630, 9285) - // Standard Error: 453 - .saturating_add(Weight::from_parts(255_373, 0).saturating_mul(r.into())) + // Minimum execution time: 273_588_000 picoseconds. + Weight::from_parts(287_133_565, 9285) + // Standard Error: 799 + .saturating_add(Weight::from_parts(254_114, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2978,10 +3023,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `872` // Estimated: `9287` - // Minimum execution time: 258_208_000 picoseconds. - Weight::from_parts(227_686_792, 9287) - // Standard Error: 23 - .saturating_add(Weight::from_parts(989, 0).saturating_mul(n.into())) + // Minimum execution time: 257_843_000 picoseconds. + Weight::from_parts(228_177_495, 9287) + // Standard Error: 24 + .saturating_add(Weight::from_parts(985, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3006,8 +3051,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `856 + r * (45 ±0)` // Estimated: `9271 + r * (45 ±0)` - // Minimum execution time: 245_714_000 picoseconds. - Weight::from_parts(272_527_059, 9271) + // Minimum execution time: 248_332_000 picoseconds. + Weight::from_parts(274_998_906, 9271) + // Standard Error: 949_561 + .saturating_add(Weight::from_parts(5_570_693, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 45).saturating_mul(r.into())) @@ -3033,10 +3080,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `866` // Estimated: `9288` - // Minimum execution time: 256_060_000 picoseconds. - Weight::from_parts(276_710_811, 9288) - // Standard Error: 0 - .saturating_add(Weight::from_parts(312, 0).saturating_mul(n.into())) + // Minimum execution time: 272_055_000 picoseconds. + Weight::from_parts(282_280_090, 9288) + // Standard Error: 1 + .saturating_add(Weight::from_parts(330, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3067,10 +3114,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2902 + r * (529 ±0)` // Estimated: `11317 + r * (5479 ±0)` - // Minimum execution time: 270_479_000 picoseconds. - Weight::from_parts(296_706_989, 11317) - // Standard Error: 813_407 - .saturating_add(Weight::from_parts(109_236_910, 0).saturating_mul(r.into())) + // Minimum execution time: 274_842_000 picoseconds. + Weight::from_parts(299_824_497, 11317) + // Standard Error: 902_686 + .saturating_add(Weight::from_parts(106_562_902, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((5_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3100,10 +3147,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `947 + r * (10 ±0)` // Estimated: `9363 + r * (10 ±0)` - // Minimum execution time: 251_787_000 picoseconds. - Weight::from_parts(284_036_313, 9363) - // Standard Error: 2_560 - .saturating_add(Weight::from_parts(1_238_301, 0).saturating_mul(r.into())) + // Minimum execution time: 255_393_000 picoseconds. + Weight::from_parts(309_814_338, 9363) + // Standard Error: 2_978 + .saturating_add(Weight::from_parts(1_203_507, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -3129,10 +3176,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `866 + r * (10 ±0)` // Estimated: `9283 + r * (10 ±0)` - // Minimum execution time: 250_566_000 picoseconds. - Weight::from_parts(275_402_784, 9283) - // Standard Error: 3_939 - .saturating_add(Weight::from_parts(1_941_995, 0).saturating_mul(r.into())) + // Minimum execution time: 250_378_000 picoseconds. + Weight::from_parts(287_003_144, 9283) + // Standard Error: 2_726 + .saturating_add(Weight::from_parts(1_850_967, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -3159,12 +3206,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `883 + t * (32 ±0)` // Estimated: `9303 + t * (2508 ±0)` - // Minimum execution time: 267_544_000 picoseconds. - Weight::from_parts(280_117_825, 9303) - // Standard Error: 102_111 - .saturating_add(Weight::from_parts(3_253_038, 0).saturating_mul(t.into())) - // Standard Error: 28 - .saturating_add(Weight::from_parts(668, 0).saturating_mul(n.into())) + // Minimum execution time: 266_787_000 picoseconds. + Weight::from_parts(284_368_661, 9303) + // Standard Error: 121_315 + .saturating_add(Weight::from_parts(2_690_211, 0).saturating_mul(t.into())) + // Standard Error: 33 + .saturating_add(Weight::from_parts(789, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3192,10 +3239,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `865 + r * (7 ±0)` // Estimated: `9285 + r * (7 ±0)` - // Minimum execution time: 157_769_000 picoseconds. - Weight::from_parts(173_026_565, 9285) - // Standard Error: 405 - .saturating_add(Weight::from_parts(219_727, 0).saturating_mul(r.into())) + // Minimum execution time: 166_804_000 picoseconds. + Weight::from_parts(175_118_291, 9285) + // Standard Error: 398 + .saturating_add(Weight::from_parts(220_961, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 7).saturating_mul(r.into())) @@ -3221,10 +3268,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `125816` // Estimated: `131758` - // Minimum execution time: 403_961_000 picoseconds. - Weight::from_parts(376_480_872, 131758) + // Minimum execution time: 398_436_000 picoseconds. + Weight::from_parts(385_003_285, 131758) // Standard Error: 12 - .saturating_add(Weight::from_parts(1_041, 0).saturating_mul(i.into())) + .saturating_add(Weight::from_parts(1_038, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3235,10 +3282,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `927 + r * (292 ±0)` // Estimated: `929 + r * (293 ±0)` - // Minimum execution time: 256_272_000 picoseconds. - Weight::from_parts(181_058_379, 929) - // Standard Error: 9_838 - .saturating_add(Weight::from_parts(6_316_677, 0).saturating_mul(r.into())) + // Minimum execution time: 274_099_000 picoseconds. + Weight::from_parts(174_282_817, 929) + // Standard Error: 10_547 + .saturating_add(Weight::from_parts(6_262_173, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3252,10 +3299,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1450` // Estimated: `1433` - // Minimum execution time: 268_713_000 picoseconds. - Weight::from_parts(328_329_131, 1433) + // Minimum execution time: 274_061_000 picoseconds. + Weight::from_parts(334_755_333, 1433) // Standard Error: 66 - .saturating_add(Weight::from_parts(962, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(771, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(15_u64)) .saturating_add(RocksDbWeight::get().writes(8_u64)) } @@ -3266,10 +3313,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1256 + n * (1 ±0)` // Estimated: `1256 + n * (1 ±0)` - // Minimum execution time: 265_683_000 picoseconds. - Weight::from_parts(293_784_477, 1256) - // Standard Error: 31 - .saturating_add(Weight::from_parts(377, 0).saturating_mul(n.into())) + // Minimum execution time: 272_657_000 picoseconds. + Weight::from_parts(299_061_594, 1256) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3281,10 +3326,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `924 + r * (288 ±0)` // Estimated: `930 + r * (289 ±0)` - // Minimum execution time: 269_959_000 picoseconds. - Weight::from_parts(186_065_911, 930) - // Standard Error: 9_679 - .saturating_add(Weight::from_parts(6_286_855, 0).saturating_mul(r.into())) + // Minimum execution time: 270_524_000 picoseconds. + Weight::from_parts(177_959_667, 930) + // Standard Error: 10_397 + .saturating_add(Weight::from_parts(6_270_181, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3298,8 +3343,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1252 + n * (1 ±0)` // Estimated: `1252 + n * (1 ±0)` - // Minimum execution time: 265_805_000 picoseconds. - Weight::from_parts(294_633_695, 1252) + // Minimum execution time: 270_757_000 picoseconds. + Weight::from_parts(298_627_896, 1252) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3311,10 +3356,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `924 + r * (296 ±0)` // Estimated: `926 + r * (297 ±0)` - // Minimum execution time: 264_592_000 picoseconds. - Weight::from_parts(204_670_461, 926) - // Standard Error: 6_869 - .saturating_add(Weight::from_parts(5_137_920, 0).saturating_mul(r.into())) + // Minimum execution time: 268_082_000 picoseconds. + Weight::from_parts(202_583_730, 926) + // Standard Error: 9_029 + .saturating_add(Weight::from_parts(5_028_517, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3327,10 +3372,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1268 + n * (1 ±0)` // Estimated: `1268 + n * (1 ±0)` - // Minimum execution time: 273_165_000 picoseconds. - Weight::from_parts(297_883_669, 1268) - // Standard Error: 37 - .saturating_add(Weight::from_parts(576, 0).saturating_mul(n.into())) + // Minimum execution time: 274_100_000 picoseconds. + Weight::from_parts(296_981_515, 1268) + // Standard Error: 34 + .saturating_add(Weight::from_parts(578, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3342,10 +3387,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `935 + r * (288 ±0)` // Estimated: `932 + r * (289 ±0)` - // Minimum execution time: 252_257_000 picoseconds. - Weight::from_parts(205_018_595, 932) - // Standard Error: 7_605 - .saturating_add(Weight::from_parts(4_933_378, 0).saturating_mul(r.into())) + // Minimum execution time: 269_697_000 picoseconds. + Weight::from_parts(198_346_516, 932) + // Standard Error: 8_623 + .saturating_add(Weight::from_parts(4_964_116, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3358,10 +3403,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1255 + n * (1 ±0)` // Estimated: `1255 + n * (1 ±0)` - // Minimum execution time: 266_839_000 picoseconds. - Weight::from_parts(292_064_487, 1255) - // Standard Error: 34 - .saturating_add(Weight::from_parts(194, 0).saturating_mul(n.into())) + // Minimum execution time: 264_210_000 picoseconds. + Weight::from_parts(291_387_652, 1255) + // Standard Error: 36 + .saturating_add(Weight::from_parts(524, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3373,10 +3418,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `917 + r * (296 ±0)` // Estimated: `922 + r * (297 ±0)` - // Minimum execution time: 266_072_000 picoseconds. - Weight::from_parts(189_018_352, 922) - // Standard Error: 9_530 - .saturating_add(Weight::from_parts(6_481_011, 0).saturating_mul(r.into())) + // Minimum execution time: 267_219_000 picoseconds. + Weight::from_parts(175_866_982, 922) + // Standard Error: 11_275 + .saturating_add(Weight::from_parts(6_424_755, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3390,10 +3435,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1269 + n * (1 ±0)` // Estimated: `1269 + n * (1 ±0)` - // Minimum execution time: 270_703_000 picoseconds. - Weight::from_parts(292_867_105, 1269) - // Standard Error: 30 - .saturating_add(Weight::from_parts(800, 0).saturating_mul(n.into())) + // Minimum execution time: 274_634_000 picoseconds. + Weight::from_parts(294_272_009, 1269) + // Standard Error: 36 + .saturating_add(Weight::from_parts(1_219, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3419,10 +3464,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1418 + r * (45 ±0)` // Estimated: `9785 + r * (2520 ±0)` - // Minimum execution time: 251_843_000 picoseconds. - Weight::from_parts(181_026_888, 9785) - // Standard Error: 38_221 - .saturating_add(Weight::from_parts(30_626_681, 0).saturating_mul(r.into())) + // Minimum execution time: 266_833_000 picoseconds. + Weight::from_parts(186_049_741, 9785) + // Standard Error: 40_311 + .saturating_add(Weight::from_parts(31_365_585, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) @@ -3450,10 +3495,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1263 + r * (245 ±0)` // Estimated: `9635 + r * (2721 ±0)` - // Minimum execution time: 254_881_000 picoseconds. - Weight::from_parts(272_871_000, 9635) - // Standard Error: 94_527 - .saturating_add(Weight::from_parts(233_379_497, 0).saturating_mul(r.into())) + // Minimum execution time: 272_140_000 picoseconds. + Weight::from_parts(275_009_000, 9635) + // Standard Error: 99_187 + .saturating_add(Weight::from_parts(240_702_479, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(14_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) @@ -3480,11 +3525,11 @@ impl WeightInfo for () { fn seal_delegate_call(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + r * (576 ±0)` - // Estimated: `9290 + r * (2637 ±3)` - // Minimum execution time: 266_704_000 picoseconds. - Weight::from_parts(273_165_000, 9290) - // Standard Error: 141_486 - .saturating_add(Weight::from_parts(232_947_049, 0).saturating_mul(r.into())) + // Estimated: `9290 + r * (2637 ±10)` + // Minimum execution time: 263_664_000 picoseconds. + Weight::from_parts(277_240_000, 9290) + // Standard Error: 169_147 + .saturating_add(Weight::from_parts(240_084_929, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3513,12 +3558,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1310 + t * (277 ±0)` // Estimated: `12200 + t * (5227 ±0)` - // Minimum execution time: 446_451_000 picoseconds. - Weight::from_parts(68_175_222, 12200) - // Standard Error: 11_619_250 - .saturating_add(Weight::from_parts(354_237_260, 0).saturating_mul(t.into())) + // Minimum execution time: 464_644_000 picoseconds. + Weight::from_parts(40_377_313, 12200) + // Standard Error: 12_060_226 + .saturating_add(Weight::from_parts(380_635_982, 0).saturating_mul(t.into())) // Standard Error: 17 - .saturating_add(Weight::from_parts(987, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(1_014, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(16_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(6_u64)) @@ -3550,10 +3595,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1281 + r * (255 ±0)` // Estimated: `9623 + r * (2731 ±0)` - // Minimum execution time: 628_156_000 picoseconds. - Weight::from_parts(642_052_000, 9623) - // Standard Error: 223_957 - .saturating_add(Weight::from_parts(348_660_264, 0).saturating_mul(r.into())) + // Minimum execution time: 641_845_000 picoseconds. + Weight::from_parts(649_908_000, 9623) + // Standard Error: 278_514 + .saturating_add(Weight::from_parts(361_164_598, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(14_u64)) .saturating_add(RocksDbWeight::get().reads((6_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(7_u64)) @@ -3587,14 +3632,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1306 + t * (104 ±0)` // Estimated: `12214 + t * (2549 ±1)` - // Minimum execution time: 2_106_379_000 picoseconds. - Weight::from_parts(1_098_227_098, 12214) - // Standard Error: 12_549_729 - .saturating_add(Weight::from_parts(21_628_382, 0).saturating_mul(t.into())) - // Standard Error: 19 - .saturating_add(Weight::from_parts(1_059, 0).saturating_mul(i.into())) - // Standard Error: 19 - .saturating_add(Weight::from_parts(1_220, 0).saturating_mul(s.into())) + // Minimum execution time: 2_111_632_000 picoseconds. + Weight::from_parts(1_213_125_745, 12214) + // Standard Error: 22 + .saturating_add(Weight::from_parts(1_055, 0).saturating_mul(i.into())) + // Standard Error: 22 + .saturating_add(Weight::from_parts(1_192, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(19_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(11_u64)) @@ -3622,10 +3665,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `865 + r * (8 ±0)` // Estimated: `9279 + r * (8 ±0)` - // Minimum execution time: 257_102_000 picoseconds. - Weight::from_parts(278_920_692, 9279) - // Standard Error: 464 - .saturating_add(Weight::from_parts(374_120, 0).saturating_mul(r.into())) + // Minimum execution time: 264_227_000 picoseconds. + Weight::from_parts(281_015_995, 9279) + // Standard Error: 710 + .saturating_add(Weight::from_parts(365_734, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3651,10 +3694,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `873` // Estimated: `9286` - // Minimum execution time: 266_609_000 picoseconds. - Weight::from_parts(263_034_132, 9286) + // Minimum execution time: 270_709_000 picoseconds. + Weight::from_parts(268_416_051, 9286) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_082, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_080, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3679,10 +3722,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `867 + r * (8 ±0)` // Estimated: `9284 + r * (8 ±0)` - // Minimum execution time: 246_275_000 picoseconds. - Weight::from_parts(279_091_594, 9284) - // Standard Error: 887 - .saturating_add(Weight::from_parts(810_394, 0).saturating_mul(r.into())) + // Minimum execution time: 267_283_000 picoseconds. + Weight::from_parts(280_706_659, 9284) + // Standard Error: 540 + .saturating_add(Weight::from_parts(790_312, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3708,10 +3751,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `875` // Estimated: `9292` - // Minimum execution time: 249_254_000 picoseconds. - Weight::from_parts(270_833_823, 9292) - // Standard Error: 0 - .saturating_add(Weight::from_parts(3_347, 0).saturating_mul(n.into())) + // Minimum execution time: 262_010_000 picoseconds. + Weight::from_parts(273_278_744, 9292) + // Standard Error: 1 + .saturating_add(Weight::from_parts(3_362, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3736,10 +3779,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `867 + r * (8 ±0)` // Estimated: `9286 + r * (8 ±0)` - // Minimum execution time: 259_131_000 picoseconds. - Weight::from_parts(272_665_020, 9286) - // Standard Error: 862 - .saturating_add(Weight::from_parts(451_247, 0).saturating_mul(r.into())) + // Minimum execution time: 268_698_000 picoseconds. + Weight::from_parts(282_890_578, 9286) + // Standard Error: 622 + .saturating_add(Weight::from_parts(441_131, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3765,10 +3808,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `875` // Estimated: `9291` - // Minimum execution time: 276_465_000 picoseconds. - Weight::from_parts(269_450_297, 9291) + // Minimum execution time: 252_846_000 picoseconds. + Weight::from_parts(267_657_561, 9291) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_190, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_208, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3793,10 +3836,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `867 + r * (8 ±0)` // Estimated: `9283 + r * (8 ±0)` - // Minimum execution time: 248_349_000 picoseconds. - Weight::from_parts(273_660_686, 9283) - // Standard Error: 656 - .saturating_add(Weight::from_parts(444_293, 0).saturating_mul(r.into())) + // Minimum execution time: 266_899_000 picoseconds. + Weight::from_parts(276_862_067, 9283) + // Standard Error: 1_249 + .saturating_add(Weight::from_parts(443_970, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3822,10 +3865,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `875` // Estimated: `9289` - // Minimum execution time: 252_107_000 picoseconds. - Weight::from_parts(267_427_726, 9289) + // Minimum execution time: 265_413_000 picoseconds. + Weight::from_parts(265_600_840, 9289) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_199, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_203, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3850,10 +3893,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1000 + n * (1 ±0)` // Estimated: `9412 + n * (1 ±0)` - // Minimum execution time: 311_252_000 picoseconds. - Weight::from_parts(333_250_773, 9412) - // Standard Error: 12 - .saturating_add(Weight::from_parts(5_668, 0).saturating_mul(n.into())) + // Minimum execution time: 328_341_000 picoseconds. + Weight::from_parts(341_038_581, 9412) + // Standard Error: 10 + .saturating_add(Weight::from_parts(5_863, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3877,12 +3920,12 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 160]`. fn seal_sr25519_verify(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `810 + r * (112 ±0)` + // Measured: `808 + r * (112 ±0)` // Estimated: `9226 + r * (112 ±0)` - // Minimum execution time: 267_431_000 picoseconds. - Weight::from_parts(300_733_048, 9226) - // Standard Error: 8_806 - .saturating_add(Weight::from_parts(42_169_197, 0).saturating_mul(r.into())) + // Minimum execution time: 272_730_000 picoseconds. + Weight::from_parts(339_349_232, 9226) + // Standard Error: 13_004 + .saturating_add(Weight::from_parts(41_649_026, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(r.into())) @@ -3908,10 +3951,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `910 + r * (76 ±0)` // Estimated: `9279 + r * (77 ±0)` - // Minimum execution time: 265_905_000 picoseconds. - Weight::from_parts(305_381_951, 9279) - // Standard Error: 9_863 - .saturating_add(Weight::from_parts(45_771_182, 0).saturating_mul(r.into())) + // Minimum execution time: 273_892_000 picoseconds. + Weight::from_parts(352_853_960, 9279) + // Standard Error: 16_745 + .saturating_add(Weight::from_parts(45_853_294, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 77).saturating_mul(r.into())) @@ -3937,10 +3980,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `880 + r * (42 ±0)` // Estimated: `9294 + r * (42 ±0)` - // Minimum execution time: 266_701_000 picoseconds. - Weight::from_parts(292_407_888, 9294) - // Standard Error: 5_394 - .saturating_add(Weight::from_parts(11_896_065, 0).saturating_mul(r.into())) + // Minimum execution time: 268_431_000 picoseconds. + Weight::from_parts(319_727_796, 9294) + // Standard Error: 10_276 + .saturating_add(Weight::from_parts(11_928_882, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 42).saturating_mul(r.into())) @@ -3966,10 +4009,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0 + r * (965 ±0)` // Estimated: `9285 + r * (3090 ±7)` - // Minimum execution time: 268_755_000 picoseconds. - Weight::from_parts(272_300_000, 9285) - // Standard Error: 43_747 - .saturating_add(Weight::from_parts(25_001_889, 0).saturating_mul(r.into())) + // Minimum execution time: 275_482_000 picoseconds. + Weight::from_parts(279_155_000, 9285) + // Standard Error: 65_388 + .saturating_add(Weight::from_parts(26_634_187, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3997,10 +4040,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `937 + r * (131 ±0)` // Estimated: `9346 + r * (2607 ±0)` - // Minimum execution time: 255_190_000 picoseconds. - Weight::from_parts(285_643_922, 9346) - // Standard Error: 23_582 - .saturating_add(Weight::from_parts(6_289_940, 0).saturating_mul(r.into())) + // Minimum execution time: 270_001_000 picoseconds. + Weight::from_parts(286_792_689, 9346) + // Standard Error: 21_074 + .saturating_add(Weight::from_parts(6_465_885, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -4028,10 +4071,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `972 + r * (184 ±0)` // Estimated: `129453 + r * (2568 ±0)` - // Minimum execution time: 260_061_000 picoseconds. - Weight::from_parts(286_849_343, 129453) - // Standard Error: 22_406 - .saturating_add(Weight::from_parts(5_661_459, 0).saturating_mul(r.into())) + // Minimum execution time: 270_652_000 picoseconds. + Weight::from_parts(293_369_452, 129453) + // Standard Error: 24_321 + .saturating_add(Weight::from_parts(5_575_600, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -4059,10 +4102,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `861 + r * (3 ±0)` // Estimated: `9282 + r * (3 ±0)` - // Minimum execution time: 250_922_000 picoseconds. - Weight::from_parts(277_294_913, 9282) - // Standard Error: 391 - .saturating_add(Weight::from_parts(169_457, 0).saturating_mul(r.into())) + // Minimum execution time: 267_749_000 picoseconds. + Weight::from_parts(280_373_341, 9282) + // Standard Error: 464 + .saturating_add(Weight::from_parts(170_398, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -4088,10 +4131,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2112 + r * (39 ±0)` // Estimated: `10377 + r * (40 ±0)` - // Minimum execution time: 267_293_000 picoseconds. - Weight::from_parts(309_125_635, 10377) - // Standard Error: 637 - .saturating_add(Weight::from_parts(245_508, 0).saturating_mul(r.into())) + // Minimum execution time: 270_260_000 picoseconds. + Weight::from_parts(337_969_172, 10377) + // Standard Error: 1_557 + .saturating_add(Weight::from_parts(305_735, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) @@ -4119,10 +4162,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `864 + r * (3 ±0)` // Estimated: `9279 + r * (3 ±0)` - // Minimum execution time: 256_057_000 picoseconds. - Weight::from_parts(278_068_870, 9279) - // Standard Error: 335 - .saturating_add(Weight::from_parts(152_083, 0).saturating_mul(r.into())) + // Minimum execution time: 265_607_000 picoseconds. + Weight::from_parts(283_396_630, 9279) + // Standard Error: 449 + .saturating_add(Weight::from_parts(149_018, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -4132,9 +4175,9 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_846_000 picoseconds. - Weight::from_parts(1_808_029, 0) - // Standard Error: 9 - .saturating_add(Weight::from_parts(14_937, 0).saturating_mul(r.into())) + // Minimum execution time: 1_813_000 picoseconds. + Weight::from_parts(1_264_945, 0) + // Standard Error: 19 + .saturating_add(Weight::from_parts(15_098, 0).saturating_mul(r.into())) } } -- GitLab From 117a9433dac88d5ac00c058c9b39c511d47749d2 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 6 Mar 2024 22:44:03 +0100 Subject: [PATCH 357/392] Make `penpal-runtime`'s `TrustedReserves` more connfigurable (#3564) The current `penpal` runtime utilizes the `EthereumLocation` parameter, which is employed for XCM emulated integration tests concerning the Rococo <> ETH bridge. It includes a hard-coded chainId for the Ethereum testnet utilized in Rococo. The `EthereumLocation` serves the purpose of aligning with the `TrustedReserves`. However, due to this hard-coded configuration, reusing `penpal` for testing various environments such as Kusama/Polkadot versus Ethereum bridge becomes unfeasible. This PR introduces the capability to easily customize the asset location for `TrustedReserves` without needing to know anything about Ethereum. ## TODO - [x] fix integration tests with `System::set_storage(CustomizableAssetFromSystemAssetHub::key(), )` @claravanstaden - [ ] ~~maybe add some helper function/macro to support `set_storage` for other runtimes (that we could reuse)~~ - [ ] Release patch for: `penpal-runtime` + emulated crate with `set_storage` support (if needed) - [ ] backport to 1.7.0 - [ ] backport to 1.8.0 --------- Co-authored-by: Clara van Staden --- Cargo.lock | 1 - .../chains/parachains/testing/penpal/src/lib.rs | 3 ++- .../bridge-hub-rococo/src/tests/snowbridge.rs | 11 +++++++++++ .../parachains/runtimes/testing/penpal/Cargo.toml | 2 -- .../runtimes/testing/penpal/src/xcm_config.rs | 15 ++++++++++----- 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 26e134448ff..fbd347c5fde 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11754,7 +11754,6 @@ dependencies = [ "staging-xcm-builder", "staging-xcm-executor", "substrate-wasm-builder", - "testnet-parachains-constants", ] [[package]] diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs index 8f586a46a75..c1e03046655 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs @@ -16,7 +16,8 @@ mod genesis; pub use genesis::{genesis, ED, PARA_ID_A, PARA_ID_B}; pub use penpal_runtime::xcm_config::{ - LocalTeleportableToAssetHub, LocalTeleportableToAssetHubV3, XcmConfig, + CustomizableAssetFromSystemAssetHub, LocalTeleportableToAssetHub, + LocalTeleportableToAssetHubV3, XcmConfig, }; // Substrate diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs index a5957ee3393..ff069e2d344 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs @@ -18,6 +18,7 @@ use codec::{Decode, Encode}; use emulated_integration_tests_common::xcm_emulator::ConvertLocation; use frame_support::pallet_prelude::TypeInfo; use hex_literal::hex; +use rococo_system_emulated_network::penpal_emulated_chain::CustomizableAssetFromSystemAssetHub; use rococo_westend_system_emulated_network::BridgeHubRococoParaSender as BridgeHubRococoSender; use snowbridge_core::outbound::OperatingMode; use snowbridge_pallet_inbound_queue_fixtures::{ @@ -253,6 +254,16 @@ fn send_token_from_ethereum_to_penpal() { (PenpalASender::get(), INITIAL_FUND), ]); + PenpalA::execute_with(|| { + assert_ok!(::System::set_storage( + ::RuntimeOrigin::root(), + vec![( + CustomizableAssetFromSystemAssetHub::key().to_vec(), + Location::new(2, [GlobalConsensus(Ethereum { chain_id: CHAIN_ID })]).encode(), + )], + )); + }); + // The Weth asset location, identified by the contract address on Ethereum let weth_asset_location: Location = (Parent, Parent, EthereumNetwork::get(), AccountKey20 { network: None, key: WETH }).into(); diff --git a/cumulus/parachains/runtimes/testing/penpal/Cargo.toml b/cumulus/parachains/runtimes/testing/penpal/Cargo.toml index bca6aca051f..5a8b15740e4 100644 --- a/cumulus/parachains/runtimes/testing/penpal/Cargo.toml +++ b/cumulus/parachains/runtimes/testing/penpal/Cargo.toml @@ -77,7 +77,6 @@ cumulus-primitives-utility = { path = "../../../../primitives/utility", default- pallet-collator-selection = { path = "../../../../pallets/collator-selection", default-features = false } parachain-info = { package = "staging-parachain-info", path = "../../../pallets/parachain-info", default-features = false } parachains-common = { path = "../../../common", default-features = false } -testnet-parachains-constants = { path = "../../constants", default-features = false, features = ["rococo"] } assets-common = { path = "../../assets/common", default-features = false } [features] @@ -133,7 +132,6 @@ std = [ "sp-transaction-pool/std", "sp-version/std", "substrate-wasm-builder", - "testnet-parachains-constants/std", "xcm-builder/std", "xcm-executor/std", "xcm/std", diff --git a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs index ef4f466d484..84b8fd9bb0a 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs @@ -43,7 +43,6 @@ use pallet_xcm::XcmPassthrough; use polkadot_parachain_primitives::primitives::Sibling; use polkadot_runtime_common::impls::ToAuthor; use sp_runtime::traits::Zero; -use testnet_parachains_constants::rococo::snowbridge::EthereumNetwork; use xcm::latest::prelude::*; use xcm_builder::{ AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, @@ -295,7 +294,13 @@ parameter_types! { 0, [xcm::v3::Junction::PalletInstance(50), xcm::v3::Junction::GeneralIndex(TELEPORTABLE_ASSET_ID.into())] ); - pub EthereumLocation: Location = Location::new(2, [GlobalConsensus(EthereumNetwork::get())]); + + /// The Penpal runtime is utilized for testing with various environment setups. + /// This storage item provides the opportunity to customize testing scenarios + /// by configuring the trusted asset from the `SystemAssetHub`. + /// + /// By default, it is configured as a `SystemAssetHubLocation` and can be modified using `System::set_storage`. + pub storage CustomizableAssetFromSystemAssetHub: Location = SystemAssetHubLocation::get(); } /// Accepts asset with ID `AssetLocation` and is coming from `Origin` chain. @@ -310,11 +315,11 @@ impl, Origin: Get> ContainsPair, NativeAssetFrom, - AssetPrefixFrom, + AssetPrefixFrom, ); pub type TrustedTeleporters = (AssetFromChain,); @@ -326,7 +331,7 @@ impl xcm_executor::Config for XcmConfig { // How to withdraw and deposit an asset. type AssetTransactor = AssetTransactors; type OriginConverter = XcmOriginToTransactDispatchOrigin; - type IsReserve = Reserves; + type IsReserve = TrustedReserves; // no teleport trust established with other chains type IsTeleporter = TrustedTeleporters; type UniversalLocation = UniversalLocation; -- GitLab From 4ae7398818c4c49bec9b4185943cf01cbfb00144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Thu, 7 Mar 2024 09:05:04 +0800 Subject: [PATCH 358/392] contracts: Remove wat support from test fixtures (#3588) In order to prepare for PolkaVM support I removed the wat support from our test fixture crate. - Removed redundant tests (invalid module checks are already inside the prepare module where they belong - Converted the gas_sync tests to Rust - Moved the start function test to the `wasm` module --- Cargo.lock | 1 - substrate/frame/contracts/fixtures/Cargo.toml | 1 - ...tract_no_call.rs => caller_is_origin_n.rs} | 17 +- .../data/invalid_contract_no_memory.wat | 5 - .../fixtures/data/invalid_module.wat | 8 - .../fixtures/data/run_out_of_gas_start_fn.wat | 10 -- .../fixtures/data/seal_input_noop.wat | 14 -- .../fixtures/data/seal_input_once.wat | 22 --- .../fixtures/data/seal_input_twice.wat | 28 --- substrate/frame/contracts/fixtures/src/lib.rs | 41 +---- substrate/frame/contracts/src/tests.rs | 167 ++---------------- substrate/frame/contracts/src/wasm/mod.rs | 18 ++ 12 files changed, 49 insertions(+), 283 deletions(-) rename substrate/frame/contracts/fixtures/contracts/{invalid_contract_no_call.rs => caller_is_origin_n.rs} (74%) delete mode 100644 substrate/frame/contracts/fixtures/data/invalid_contract_no_memory.wat delete mode 100644 substrate/frame/contracts/fixtures/data/invalid_module.wat delete mode 100644 substrate/frame/contracts/fixtures/data/run_out_of_gas_start_fn.wat delete mode 100644 substrate/frame/contracts/fixtures/data/seal_input_noop.wat delete mode 100644 substrate/frame/contracts/fixtures/data/seal_input_once.wat delete mode 100644 substrate/frame/contracts/fixtures/data/seal_input_twice.wat diff --git a/Cargo.lock b/Cargo.lock index fbd347c5fde..177d76b8706 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9634,7 +9634,6 @@ dependencies = [ "tempfile", "toml 0.8.8", "twox-hash", - "wat", ] [[package]] diff --git a/substrate/frame/contracts/fixtures/Cargo.toml b/substrate/frame/contracts/fixtures/Cargo.toml index 7fdf56a91fc..9ca9e404c31 100644 --- a/substrate/frame/contracts/fixtures/Cargo.toml +++ b/substrate/frame/contracts/fixtures/Cargo.toml @@ -11,7 +11,6 @@ description = "Fixtures for testing contracts pallet." workspace = true [dependencies] -wat = "1" frame-system = { path = "../../system" } sp-runtime = { path = "../../../primitives/runtime" } anyhow = "1.0.0" diff --git a/substrate/frame/contracts/fixtures/contracts/invalid_contract_no_call.rs b/substrate/frame/contracts/fixtures/contracts/caller_is_origin_n.rs similarity index 74% rename from substrate/frame/contracts/fixtures/contracts/invalid_contract_no_call.rs rename to substrate/frame/contracts/fixtures/contracts/caller_is_origin_n.rs index 13af3eb22b1..fd6f59802fa 100644 --- a/substrate/frame/contracts/fixtures/contracts/invalid_contract_no_call.rs +++ b/substrate/frame/contracts/fixtures/contracts/caller_is_origin_n.rs @@ -14,12 +14,25 @@ // 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. -//! Valid module but missing the call function + +//! This fixture calls caller_is_origin `n` times. + #![no_std] #![no_main] -extern crate common; +use common::input; +use uapi::{HostFn, HostFnImpl as api}; #[no_mangle] #[polkavm_derive::polkavm_export] pub extern "C" fn deploy() {} + +#[no_mangle] +#[polkavm_derive::polkavm_export] +pub extern "C" fn call() { + input!(n: u32, ); + + for _ in 0..n { + let _ = api::caller_is_origin(); + } +} diff --git a/substrate/frame/contracts/fixtures/data/invalid_contract_no_memory.wat b/substrate/frame/contracts/fixtures/data/invalid_contract_no_memory.wat deleted file mode 100644 index 0aeefbcb7eb..00000000000 --- a/substrate/frame/contracts/fixtures/data/invalid_contract_no_memory.wat +++ /dev/null @@ -1,5 +0,0 @@ -;; A valid contract which does nothing at all -(module - (func (export "deploy")) - (func (export "call")) -) diff --git a/substrate/frame/contracts/fixtures/data/invalid_module.wat b/substrate/frame/contracts/fixtures/data/invalid_module.wat deleted file mode 100644 index e4a72f74273..00000000000 --- a/substrate/frame/contracts/fixtures/data/invalid_module.wat +++ /dev/null @@ -1,8 +0,0 @@ -;; An invalid module -(module - (func (export "deploy")) - (func (export "call") - ;; imbalanced stack - (i32.const 7) - ) -) diff --git a/substrate/frame/contracts/fixtures/data/run_out_of_gas_start_fn.wat b/substrate/frame/contracts/fixtures/data/run_out_of_gas_start_fn.wat deleted file mode 100644 index 6591d7ede78..00000000000 --- a/substrate/frame/contracts/fixtures/data/run_out_of_gas_start_fn.wat +++ /dev/null @@ -1,10 +0,0 @@ -(module - (import "env" "memory" (memory 1 1)) - (start $start) - (func $start - (loop $inf (br $inf)) ;; just run out of gas - (unreachable) - ) - (func (export "call")) - (func (export "deploy")) -) diff --git a/substrate/frame/contracts/fixtures/data/seal_input_noop.wat b/substrate/frame/contracts/fixtures/data/seal_input_noop.wat deleted file mode 100644 index 7b5a1e32af4..00000000000 --- a/substrate/frame/contracts/fixtures/data/seal_input_noop.wat +++ /dev/null @@ -1,14 +0,0 @@ -;; Everything prepared for the host function call, but no call is performed. -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; [0, 8) buffer to write input - - ;; [8, 12) size of the input buffer - (data (i32.const 8) "\04") - - (func (export "call")) - - (func (export "deploy")) -) diff --git a/substrate/frame/contracts/fixtures/data/seal_input_once.wat b/substrate/frame/contracts/fixtures/data/seal_input_once.wat deleted file mode 100644 index 919a03a9b69..00000000000 --- a/substrate/frame/contracts/fixtures/data/seal_input_once.wat +++ /dev/null @@ -1,22 +0,0 @@ -;; Stores a value of the passed size. The host function is called once. -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; [0, 8) buffer to write input - - ;; [8, 12) size of the input buffer - (data (i32.const 8) "\04") - - (func (export "call") - ;; instructions to consume engine fuel - (drop - (i32.const 42) - ) - - (call $seal_input (i32.const 0) (i32.const 8)) - - ) - - (func (export "deploy")) -) diff --git a/substrate/frame/contracts/fixtures/data/seal_input_twice.wat b/substrate/frame/contracts/fixtures/data/seal_input_twice.wat deleted file mode 100644 index 3a8be814efb..00000000000 --- a/substrate/frame/contracts/fixtures/data/seal_input_twice.wat +++ /dev/null @@ -1,28 +0,0 @@ -;; Stores a value of the passed size. The host function is called twice. -(module - (import "seal0" "seal_input" (func $seal_input (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; [0, 8) buffer to write input - - ;; [8, 12) size of the input buffer - (data (i32.const 8) "\04") - - (func (export "call") - ;; instructions to consume engine fuel - (drop - (i32.const 42) - ) - - (call $seal_input (i32.const 0) (i32.const 8)) - - ;; instructions to consume engine fuel - (drop - (i32.const 42) - ) - - (call $seal_input (i32.const 0) (i32.const 8)) - ) - - (func (export "deploy")) -) diff --git a/substrate/frame/contracts/fixtures/src/lib.rs b/substrate/frame/contracts/fixtures/src/lib.rs index e0d9d4f8bd5..56a8e2321c5 100644 --- a/substrate/frame/contracts/fixtures/src/lib.rs +++ b/substrate/frame/contracts/fixtures/src/lib.rs @@ -16,34 +16,7 @@ // limitations under the License. use sp_runtime::traits::Hash; -use std::{env::var, fs, path::PathBuf}; - -fn wat_root_dir() -> PathBuf { - match (var("CARGO_MANIFEST_DIR"), var("CARGO_PKG_NAME")) { - // When `CARGO_MANIFEST_DIR` is not set, Rust resolves relative paths from the root folder - (Err(_), _) => "substrate/frame/contracts/fixtures/data".into(), - (Ok(path), Ok(s)) if s == "pallet-contracts" => PathBuf::from(path).join("fixtures/data"), - (Ok(path), Ok(s)) if s == "pallet-contracts-mock-network" => - PathBuf::from(path).parent().unwrap().join("fixtures/data"), - (Ok(_), pkg_name) => panic!("Failed to resolve fixture dir for tests from {pkg_name:?}."), - } -} - -/// Load a given wasm module represented by a .wat file and returns a wasm binary contents along -/// with it's hash. -/// -/// The fixture files are located under the `fixtures/` directory. -fn legacy_compile_module( - fixture_name: &str, -) -> anyhow::Result<(Vec, ::Output)> -where - T: frame_system::Config, -{ - let fixture_path = wat_root_dir().join(format!("{fixture_name}.wat")); - let wasm_binary = wat::parse_file(fixture_path)?; - let code_hash = T::Hashing::hash(&wasm_binary); - Ok((wasm_binary, code_hash)) -} +use std::{fs, path::PathBuf}; /// Load a given wasm module and returns a wasm binary contents along with it's hash. /// Use the legacy compile_module as fallback, if the rust fixture does not exist yet. @@ -53,15 +26,11 @@ pub fn compile_module( where T: frame_system::Config, { - let out_dir: std::path::PathBuf = env!("OUT_DIR").into(); + let out_dir: PathBuf = env!("OUT_DIR").into(); let fixture_path = out_dir.join(format!("{fixture_name}.wasm")); - match fs::read(fixture_path) { - Ok(wasm_binary) => { - let code_hash = T::Hashing::hash(&wasm_binary); - Ok((wasm_binary, code_hash)) - }, - Err(_) => legacy_compile_module::(fixture_name), - } + let binary = fs::read(fixture_path)?; + let code_hash = T::Hashing::hash(&binary); + Ok((binary, code_hash)) } #[cfg(test)] diff --git a/substrate/frame/contracts/src/tests.rs b/substrate/frame/contracts/src/tests.rs index 011b2b25b2b..4c1f65e28d5 100644 --- a/substrate/frame/contracts/src/tests.rs +++ b/substrate/frame/contracts/src/tests.rs @@ -852,27 +852,6 @@ fn deposit_event_max_value_limit() { }); } -// Fail out of fuel (ref_time weight) inside the start function. -#[test] -fn run_out_of_fuel_start_fun() { - let (wasm, _code_hash) = compile_module::("run_out_of_gas_start_fn").unwrap(); - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - let _ = ::Currency::set_balance(&ALICE, 1_000_000); - assert_err_ignore_postinfo!( - Contracts::instantiate_with_code( - RuntimeOrigin::signed(ALICE), - 0, - Weight::from_parts(1_000_000_000_000, u64::MAX), - None, - wasm, - vec![], - vec![], - ), - Error::::OutOfGas, - ); - }); -} - // Fail out of fuel (ref_time weight) in the engine. #[test] fn run_out_of_fuel_engine() { @@ -956,50 +935,15 @@ fn run_out_of_fuel_host() { #[test] fn gas_syncs_work() { - let (wasm0, _code_hash) = compile_module::("seal_input_noop").unwrap(); - let (wasm1, _code_hash) = compile_module::("seal_input_once").unwrap(); - let (wasm2, _code_hash) = compile_module::("seal_input_twice").unwrap(); + let (code, _code_hash) = compile_module::("caller_is_origin_n").unwrap(); ExtBuilder::default().existential_deposit(200).build().execute_with(|| { let _ = ::Currency::set_balance(&ALICE, 1_000_000); - // Instantiate noop contract. - let addr0 = Contracts::bare_instantiate( - ALICE, - 0, - GAS_LIMIT, - None, - Code::Upload(wasm0), - vec![], - vec![], - DebugInfo::Skip, - CollectEvents::Skip, - ) - .result - .unwrap() - .account_id; - - // Instantiate 1st contract. - let addr1 = Contracts::bare_instantiate( - ALICE, - 0, - GAS_LIMIT, - None, - Code::Upload(wasm1), - vec![], - vec![], - DebugInfo::Skip, - CollectEvents::Skip, - ) - .result - .unwrap() - .account_id; - - // Instantiate 2nd contract. - let addr2 = Contracts::bare_instantiate( + let addr = Contracts::bare_instantiate( ALICE, 0, GAS_LIMIT, None, - Code::Upload(wasm2), + Code::Upload(code), vec![], vec![], DebugInfo::Skip, @@ -1011,11 +955,11 @@ fn gas_syncs_work() { let result = Contracts::bare_call( ALICE, - addr0, + addr.clone(), 0, GAS_LIMIT, None, - 1u8.to_le_bytes().to_vec(), + 0u32.encode(), DebugInfo::Skip, CollectEvents::Skip, Determinism::Enforced, @@ -1025,27 +969,28 @@ fn gas_syncs_work() { let result = Contracts::bare_call( ALICE, - addr1, + addr.clone(), 0, GAS_LIMIT, None, - 1u8.to_le_bytes().to_vec(), + 1u32.encode(), DebugInfo::Skip, CollectEvents::Skip, Determinism::Enforced, ); assert_ok!(result.result); let gas_consumed_once = result.gas_consumed.ref_time(); - let host_consumed_once = ::Schedule::get().host_fn_weights.input.ref_time(); + let host_consumed_once = + ::Schedule::get().host_fn_weights.caller_is_origin.ref_time(); let engine_consumed_once = gas_consumed_once - host_consumed_once - engine_consumed_noop; let result = Contracts::bare_call( ALICE, - addr2, + addr, 0, GAS_LIMIT, None, - 1u8.to_le_bytes().to_vec(), + 2u32.encode(), DebugInfo::Skip, CollectEvents::Skip, Determinism::Enforced, @@ -4453,96 +4398,6 @@ fn contract_reverted() { }); } -#[test] -fn code_rejected_error_works() { - ExtBuilder::default().existential_deposit(200).build().execute_with(|| { - let _ = ::Currency::set_balance(&ALICE, 1_000_000); - - let (wasm, _) = compile_module::("invalid_module").unwrap(); - assert_noop!( - Contracts::upload_code( - RuntimeOrigin::signed(ALICE), - wasm.clone(), - None, - Determinism::Enforced - ), - >::CodeRejected, - ); - let result = Contracts::bare_instantiate( - ALICE, - 0, - GAS_LIMIT, - None, - Code::Upload(wasm), - vec![], - vec![], - DebugInfo::UnsafeDebug, - CollectEvents::Skip, - ); - assert_err!(result.result, >::CodeRejected); - assert_eq!( - std::str::from_utf8(&result.debug_message).unwrap(), - "Can't load the module into wasmi!" - ); - - let (wasm, _) = compile_module::("invalid_contract_no_call").unwrap(); - assert_noop!( - Contracts::upload_code( - RuntimeOrigin::signed(ALICE), - wasm.clone(), - None, - Determinism::Enforced - ), - >::CodeRejected, - ); - - let result = Contracts::bare_instantiate( - ALICE, - 0, - GAS_LIMIT, - None, - Code::Upload(wasm), - vec![], - vec![], - DebugInfo::UnsafeDebug, - CollectEvents::Skip, - ); - assert_err!(result.result, >::CodeRejected); - assert_eq!( - std::str::from_utf8(&result.debug_message).unwrap(), - "call function isn't exported" - ); - - let (wasm, _) = compile_module::("invalid_contract_no_memory").unwrap(); - assert_noop!( - Contracts::upload_code( - RuntimeOrigin::signed(ALICE), - wasm.clone(), - None, - Determinism::Enforced - ), - >::CodeRejected, - ); - - let result = Contracts::bare_instantiate( - ALICE, - 0, - GAS_LIMIT, - None, - Code::Upload(wasm), - vec![], - vec![], - DebugInfo::UnsafeDebug, - CollectEvents::Skip, - ); - assert_err!(result.result, >::CodeRejected); - assert_eq!( - std::str::from_utf8(&result.debug_message).unwrap(), - "No memory import found in the module" - ); - }); -} - #[test] fn set_code_hash() { let (wasm, code_hash) = compile_module::("set_code_hash").unwrap(); diff --git a/substrate/frame/contracts/src/wasm/mod.rs b/substrate/frame/contracts/src/wasm/mod.rs index 87e92cd72e8..23363780b14 100644 --- a/substrate/frame/contracts/src/wasm/mod.rs +++ b/substrate/frame/contracts/src/wasm/mod.rs @@ -3442,4 +3442,22 @@ mod tests { runtime.read_sandbox_memory_as(&memory, 0u32).unwrap(); assert_eq!(decoded.into_inner(), data); } + + #[test] + fn run_out_of_gas_in_start_fn() { + const CODE: &str = r#" +(module + (import "env" "memory" (memory 1 1)) + (start $start) + (func $start + (loop $inf (br $inf)) ;; just run out of gas + (unreachable) + ) + (func (export "call")) + (func (export "deploy")) +) +"#; + let mut mock_ext = MockExt::default(); + assert_err!(execute(&CODE, vec![], &mut mock_ext), >::OutOfGas); + } } -- GitLab From c16fcc47bc427dd01ed3d1c17d6483bd388bc92f Mon Sep 17 00:00:00 2001 From: Andrei Sandu <54316454+sandreim@users.noreply.github.com> Date: Thu, 7 Mar 2024 11:11:43 +0200 Subject: [PATCH 359/392] ParaInherent create: update `apply_weight_limit` wrt elastic scaling (#3573) Changes the way we perform the random selection of backed candidates when there isn't enough room for all of them. Instead of picking individual backed candidates `apply_weight` now operates on chains of candidates. This is fully backwards compatible and relies on the node side (provisioner/prospective parachains) doing the heavy lifting and providing the candidates in the order they form a chain. The same approach can be implemented for bitfields random selection once https://github.com/paritytech/polkadot-sdk/pull/3479 is merged. The approach taken in this PR aims for reduced additional complexity at the cost of being less fair wrt how many backed candidates from each chain are picked. It favors elastic scaling parachains vs parachains not using elastic scaling, but from my perspective it should be fine as this should happen under exceptional circumstances like dispute storms. Note: to make things more fair we can consider specializing `random_sel` such that it will try to pick candidates one by one in the order provided by the provisioner such that non elastic scaling parachains have the same chance of getting a candidate backed. --------- Signed-off-by: Andrei Sandu --- .../parachains/src/paras_inherent/mod.rs | 64 +++++++-- .../parachains/src/paras_inherent/tests.rs | 125 +++++++++++++++++- 2 files changed, 174 insertions(+), 15 deletions(-) diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index cebf858c24a..723a15bdba7 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -788,7 +788,7 @@ fn random_sel Weight>( /// Assumes disputes are already filtered by the time this is called. /// /// Returns the total weight consumed by `bitfields` and `candidates`. -fn apply_weight_limit( +pub(crate) fn apply_weight_limit( candidates: &mut Vec::Hash>>, bitfields: &mut UncheckedSignedAvailabilityBitfields, max_consumable_weight: Weight, @@ -805,35 +805,71 @@ fn apply_weight_limit( return total } - // Prefer code upgrades, they tend to be large and hence stand no chance to be picked - // late while maintaining the weight bounds. - let preferred_indices = candidates + // Invariant: block author provides candidate in the order in which they form a chain + // wrt elastic scaling. If the invariant is broken, we'd fail later when filtering candidates + // which are unchained. + + let mut chained_candidates: Vec> = Vec::new(); + let mut current_para_id = None; + + for candidate in sp_std::mem::take(candidates).into_iter() { + let candidate_para_id = candidate.descriptor().para_id; + if Some(candidate_para_id) == current_para_id { + let chain = chained_candidates + .last_mut() + .expect("if the current_para_id is Some, then vec is not empty; qed"); + chain.push(candidate); + } else { + current_para_id = Some(candidate_para_id); + chained_candidates.push(vec![candidate]); + } + } + + // Elastic scaling: we prefer chains that have a code upgrade among the candidates, + // as the candidates containing the upgrade tend to be large and hence stand no chance to + // be picked late while maintaining the weight bounds. + // + // Limitations: For simplicity if total weight of a chain of candidates is larger than + // the remaining weight, the chain will still not be included while it could still be possible + // to include part of that chain. + let preferred_chain_indices = chained_candidates .iter() .enumerate() - .filter_map(|(idx, candidate)| { - candidate.candidate().commitments.new_validation_code.as_ref().map(|_code| idx) + .filter_map(|(idx, candidates)| { + // Check if any of the candidate in chain contains a code upgrade. + if candidates + .iter() + .any(|candidate| candidate.candidate().commitments.new_validation_code.is_some()) + { + Some(idx) + } else { + None + } }) .collect::>(); - // There is weight remaining to be consumed by a subset of candidates + // There is weight remaining to be consumed by a subset of chained candidates // which are going to be picked now. if let Some(max_consumable_by_candidates) = max_consumable_weight.checked_sub(&total_bitfields_weight) { - let (acc_candidate_weight, indices) = - random_sel::::Hash>, _>( + let (acc_candidate_weight, chained_indices) = + random_sel::::Hash>>, _>( rng, - &candidates, - preferred_indices, - |c| backed_candidate_weight::(c), + &chained_candidates, + preferred_chain_indices, + |candidates| backed_candidates_weight::(&candidates), max_consumable_by_candidates, ); - log::debug!(target: LOG_TARGET, "Indices Candidates: {:?}, size: {}", indices, candidates.len()); - candidates.indexed_retain(|idx, _backed_candidate| indices.binary_search(&idx).is_ok()); + log::debug!(target: LOG_TARGET, "Indices Candidates: {:?}, size: {}", chained_indices, candidates.len()); + chained_candidates + .indexed_retain(|idx, _backed_candidates| chained_indices.binary_search(&idx).is_ok()); // pick all bitfields, and // fill the remaining space with candidates let total_consumed = acc_candidate_weight.saturating_add(total_bitfields_weight); + *candidates = chained_candidates.into_iter().flatten().collect::>(); + return total_consumed } diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index b7285ec884a..fb4d1bd2226 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -22,7 +22,7 @@ use super::*; #[cfg(not(feature = "runtime-benchmarks"))] mod enter { - use super::*; + use super::{inclusion::tests::TestCandidateBuilder, *}; use crate::{ builder::{Bench, BenchBuilder}, mock::{mock_assigner, new_test_ext, BlockLength, BlockWeights, MockGenesisConfig, Test}, @@ -925,6 +925,129 @@ mod enter { }); } + // Helper fn that builds chained dummy candidates for elastic scaling tests + fn build_backed_candidate_chain( + para_id: ParaId, + len: usize, + start_core_index: usize, + code_upgrade_index: Option, + ) -> Vec { + if let Some(code_upgrade_index) = code_upgrade_index { + assert!(code_upgrade_index < len, "Code upgrade index out of bounds"); + } + + (0..len) + .into_iter() + .map(|idx| { + let mut builder = TestCandidateBuilder::default(); + builder.para_id = para_id; + let mut ccr = builder.build(); + + if Some(idx) == code_upgrade_index { + ccr.commitments.new_validation_code = Some(vec![1, 2, 3, 4].into()); + } + + ccr.commitments.processed_downward_messages = idx as u32; + let core_index = start_core_index + idx; + + BackedCandidate::new( + ccr.into(), + Default::default(), + Default::default(), + Some(CoreIndex(core_index as u32)), + ) + }) + .collect::>() + } + + // Ensure that overweight parachain inherents are always rejected by the runtime. + // Runtime should panic and return `InherentOverweight` error. + #[test] + fn test_backed_candidates_apply_weight_works_for_elastic_scaling() { + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + let seed = [ + 1, 0, 52, 0, 0, 0, 0, 0, 1, 0, 10, 0, 22, 32, 0, 0, 2, 0, 55, 49, 0, 11, 0, 0, 3, + 0, 0, 0, 0, 0, 2, 92, + ]; + let mut rng = rand_chacha::ChaChaRng::from_seed(seed); + + // Create an overweight inherent and oversized block + let mut backed_and_concluding = BTreeMap::new(); + + for i in 0..30 { + backed_and_concluding.insert(i, i); + } + + let scenario = make_inherent_data(TestConfig { + dispute_statements: Default::default(), + dispute_sessions: vec![], // 3 cores with disputes + backed_and_concluding, + num_validators_per_core: 5, + code_upgrade: None, + fill_claimqueue: false, + }); + + let mut para_inherent_data = scenario.data.clone(); + + // Check the para inherent data is as expected: + // * 1 bitfield per validator (5 validators per core, 30 backed candidates, 0 disputes + // => 5*30 = 150) + assert_eq!(para_inherent_data.bitfields.len(), 150); + // * 30 backed candidates + assert_eq!(para_inherent_data.backed_candidates.len(), 30); + + let mut input_candidates = + build_backed_candidate_chain(ParaId::from(1000), 3, 0, Some(1)); + let chained_candidates_weight = backed_candidates_weight::(&input_candidates); + + input_candidates.append(&mut para_inherent_data.backed_candidates); + let input_bitfields = para_inherent_data.bitfields; + + // Test if weight insufficient even for 1 candidate (which doesn't contain a code + // upgrade). + let max_weight = backed_candidate_weight::(&input_candidates[0]) + + signed_bitfields_weight::(&input_bitfields); + let mut backed_candidates = input_candidates.clone(); + let mut bitfields = input_bitfields.clone(); + apply_weight_limit::( + &mut backed_candidates, + &mut bitfields, + max_weight, + &mut rng, + ); + + // The chained candidates are not picked, instead a single other candidate is picked + assert_eq!(backed_candidates.len(), 1); + assert_ne!(backed_candidates[0].descriptor().para_id, ParaId::from(1000)); + + // All bitfields are kept. + assert_eq!(bitfields.len(), 150); + + // Test if para_id 1000 chained candidates make it if there is enough room for its 3 + // candidates. + let max_weight = + chained_candidates_weight + signed_bitfields_weight::(&input_bitfields); + let mut backed_candidates = input_candidates.clone(); + let mut bitfields = input_bitfields.clone(); + apply_weight_limit::( + &mut backed_candidates, + &mut bitfields, + max_weight, + &mut rng, + ); + + // Only the chained candidates should pass filter. + assert_eq!(backed_candidates.len(), 3); + // Check the actual candidates + assert_eq!(backed_candidates[0].descriptor().para_id, ParaId::from(1000)); + assert_eq!(backed_candidates[1].descriptor().para_id, ParaId::from(1000)); + assert_eq!(backed_candidates[2].descriptor().para_id, ParaId::from(1000)); + + // All bitfields are kept. + assert_eq!(bitfields.len(), 150); + }); + } + // Ensure that overweight parachain inherents are always rejected by the runtime. // Runtime should panic and return `InherentOverweight` error. #[test] -- GitLab From 11831df8e709061e9c6b3292facb5d7d9709f151 Mon Sep 17 00:00:00 2001 From: Dastan <88332432+dastansam@users.noreply.github.com> Date: Thu, 7 Mar 2024 11:36:30 +0100 Subject: [PATCH 360/392] `nomination-pools`: add permissionless condition to `chill` (#3453) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, pool member funds cannot be unbonded if the depositor's stake is less than `MinNominatorBond`. This usually happens after `T::MinNominatorBond` is increased. To fix this, the above mentioned condition is added as a case for permissionless dispatch of `chill`. After pool is chilled, pool members can unbond their funds since pool won't be nominating anymore. Consequently, same check is added to `nominate` call, i.e pool can not start nominating if it's depositor does not have `MinNominatorBond` cc @Ank4n @kianenigma closes #2350 Polkadot address: 16FqwPZ8GRC5U5D4Fu7W33nA55ZXzXGWHwmbnE1eT6pxuqcT --------- Co-authored-by: Ankan <10196091+Ank4n@users.noreply.github.com> Co-authored-by: Gonçalo Pestana Co-authored-by: command-bot <> --- prdoc/pr_3453.prdoc | 13 + substrate/frame/nomination-pools/src/lib.rs | 39 ++- substrate/frame/nomination-pools/src/tests.rs | 42 +++ .../frame/nomination-pools/src/weights.rs | 268 ++++++++++-------- .../nomination-pools/test-staking/src/lib.rs | 133 ++++++++- 5 files changed, 367 insertions(+), 128 deletions(-) create mode 100644 prdoc/pr_3453.prdoc diff --git a/prdoc/pr_3453.prdoc b/prdoc/pr_3453.prdoc new file mode 100644 index 00000000000..1f01440f722 --- /dev/null +++ b/prdoc/pr_3453.prdoc @@ -0,0 +1,13 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: "[pallet-nomination-pools]: `chill` is permissionless if depositor's stake is less than `min_nominator_bond`" + +doc: + - audience: Runtime Dev + description: | + Nomination pools currently have an issue whereby member funds cannot be unbonded if the depositor bonded amount is less than `MinNominatorBond`. + This PR makes the `chill` function permissionless if this condition is met. + Consequently, `nominate` function also checks for `depositor` to have at least `MinNominatorBond`, and returns `MinimumBondNotMet` error if not. +crates: + - name: pallet-nomination-pools diff --git a/substrate/frame/nomination-pools/src/lib.rs b/substrate/frame/nomination-pools/src/lib.rs index c64db9ed692..a0dbdb3aaa4 100644 --- a/substrate/frame/nomination-pools/src/lib.rs +++ b/substrate/frame/nomination-pools/src/lib.rs @@ -2401,6 +2401,11 @@ pub mod pallet { /// /// This directly forward the call to the staking pallet, on behalf of the pool bonded /// account. + /// + /// # Note + /// + /// In addition to a `root` or `nominator` role of `origin`, pool's depositor needs to have + /// at least `depositor_min_bond` in the pool to start nominating. #[pallet::call_index(8)] #[pallet::weight(T::WeightInfo::nominate(validators.len() as u32))] pub fn nominate( @@ -2411,6 +2416,16 @@ pub mod pallet { let who = ensure_signed(origin)?; let bonded_pool = BondedPool::::get(pool_id).ok_or(Error::::PoolNotFound)?; ensure!(bonded_pool.can_nominate(&who), Error::::NotNominator); + + let depositor_points = PoolMembers::::get(&bonded_pool.roles.depositor) + .ok_or(Error::::PoolMemberNotFound)? + .active_points(); + + ensure!( + bonded_pool.points_to_balance(depositor_points) >= Self::depositor_min_bond(), + Error::::MinimumBondNotMet + ); + T::Staking::nominate(&bonded_pool.bonded_account(), validators) } @@ -2573,17 +2588,37 @@ pub mod pallet { /// Chill on behalf of the pool. /// - /// The dispatch origin of this call must be signed by the pool nominator or the pool + /// The dispatch origin of this call can be signed by the pool nominator or the pool /// root role, same as [`Pallet::nominate`]. /// + /// Under certain conditions, this call can be dispatched permissionlessly (i.e. by any + /// account). + /// + /// # Conditions for a permissionless dispatch: + /// * When pool depositor has less than `MinNominatorBond` staked, otherwise pool members + /// are unable to unbond. + /// + /// # Conditions for permissioned dispatch: + /// * The caller has a nominator or root role of the pool. /// This directly forward the call to the staking pallet, on behalf of the pool bonded /// account. #[pallet::call_index(13)] #[pallet::weight(T::WeightInfo::chill())] pub fn chill(origin: OriginFor, pool_id: PoolId) -> DispatchResult { let who = ensure_signed(origin)?; + let bonded_pool = BondedPool::::get(pool_id).ok_or(Error::::PoolNotFound)?; - ensure!(bonded_pool.can_nominate(&who), Error::::NotNominator); + + let depositor_points = PoolMembers::::get(&bonded_pool.roles.depositor) + .ok_or(Error::::PoolMemberNotFound)? + .active_points(); + + if bonded_pool.points_to_balance(depositor_points) >= + T::Staking::minimum_nominator_bond() + { + ensure!(bonded_pool.can_nominate(&who), Error::::NotNominator); + } + T::Staking::chill(&bonded_pool.bonded_account()) } diff --git a/substrate/frame/nomination-pools/src/tests.rs b/substrate/frame/nomination-pools/src/tests.rs index 13298fa64f5..8fb2b41b88a 100644 --- a/substrate/frame/nomination-pools/src/tests.rs +++ b/substrate/frame/nomination-pools/src/tests.rs @@ -4848,6 +4848,18 @@ mod nominate { Error::::NotNominator ); + // if `depositor` stake is less than the `MinimumNominatorBond`, they can't nominate + StakingMinBond::set(20); + + // Can't nominate if depositor's stake is less than the `MinimumNominatorBond` + assert_noop!( + Pools::nominate(RuntimeOrigin::signed(900), 1, vec![21]), + Error::::MinimumBondNotMet + ); + + // restore `MinimumNominatorBond` + StakingMinBond::set(10); + // Root can nominate assert_ok!(Pools::nominate(RuntimeOrigin::signed(900), 1, vec![21])); assert_eq!(Nominations::get().unwrap(), vec![21]); @@ -7338,3 +7350,33 @@ mod slash { }); } } + +mod chill { + use super::*; + + #[test] + fn chill_works() { + ExtBuilder::default().build_and_execute(|| { + // only nominator or root can chill + assert_noop!( + Pools::chill(RuntimeOrigin::signed(10), 1), + Error::::NotNominator + ); + + // root can chill and re-nominate + assert_ok!(Pools::chill(RuntimeOrigin::signed(900), 1)); + assert_ok!(Pools::nominate(RuntimeOrigin::signed(900), 1, vec![31])); + + // nominator can chill and re-nominate + assert_ok!(Pools::chill(RuntimeOrigin::signed(901), 1)); + assert_ok!(Pools::nominate(RuntimeOrigin::signed(901), 1, vec![31])); + + // if `depositor` stake is less than the `MinimumNominatorBond`, then this call + // becomes permissionless; + StakingMinBond::set(20); + + // any account can chill + assert_ok!(Pools::chill(RuntimeOrigin::signed(10), 1)); + }) + } +} diff --git a/substrate/frame/nomination-pools/src/weights.rs b/substrate/frame/nomination-pools/src/weights.rs index 2749af7937f..987ddd71703 100644 --- a/substrate/frame/nomination-pools/src/weights.rs +++ b/substrate/frame/nomination-pools/src/weights.rs @@ -18,27 +18,25 @@ //! Autogenerated weights for `pallet_nomination_pools` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-03-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-p5qp1txx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate-node +// target/production/substrate-node // benchmark // pallet -// --chain=dev // --steps=50 // --repeat=20 -// --pallet=pallet_nomination_pools -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/nomination-pools/src/weights.rs +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_nomination_pools +// --chain=dev // --header=./substrate/HEADER-APACHE2 +// --output=./substrate/frame/nomination-pools/src/weights.rs // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -114,8 +112,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `3425` // Estimated: `8877` - // Minimum execution time: 181_861_000 picoseconds. - Weight::from_parts(186_375_000, 8877) + // Minimum execution time: 182_643_000 picoseconds. + Weight::from_parts(186_106_000, 8877) .saturating_add(T::DbWeight::get().reads(20_u64)) .saturating_add(T::DbWeight::get().writes(13_u64)) } @@ -147,8 +145,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `3435` // Estimated: `8877` - // Minimum execution time: 182_273_000 picoseconds. - Weight::from_parts(186_635_000, 8877) + // Minimum execution time: 181_464_000 picoseconds. + Weight::from_parts(184_672_000, 8877) .saturating_add(T::DbWeight::get().reads(17_u64)) .saturating_add(T::DbWeight::get().writes(13_u64)) } @@ -182,8 +180,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `3500` // Estimated: `8877` - // Minimum execution time: 217_878_000 picoseconds. - Weight::from_parts(221_493_000, 8877) + // Minimum execution time: 216_182_000 picoseconds. + Weight::from_parts(218_448_000, 8877) .saturating_add(T::DbWeight::get().reads(18_u64)) .saturating_add(T::DbWeight::get().writes(14_u64)) } @@ -203,8 +201,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1172` // Estimated: `3719` - // Minimum execution time: 74_509_000 picoseconds. - Weight::from_parts(76_683_000, 3719) + // Minimum execution time: 73_830_000 picoseconds. + Weight::from_parts(75_271_000, 3719) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -244,8 +242,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `3622` // Estimated: `27847` - // Minimum execution time: 166_424_000 picoseconds. - Weight::from_parts(169_698_000, 27847) + // Minimum execution time: 166_099_000 picoseconds. + Weight::from_parts(170_355_000, 27847) .saturating_add(T::DbWeight::get().reads(20_u64)) .saturating_add(T::DbWeight::get().writes(13_u64)) } @@ -270,10 +268,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1848` // Estimated: `4764` - // Minimum execution time: 66_110_000 picoseconds. - Weight::from_parts(68_620_141, 4764) - // Standard Error: 1_379 - .saturating_add(Weight::from_parts(54_961, 0).saturating_mul(s.into())) + // Minimum execution time: 64_787_000 picoseconds. + Weight::from_parts(67_920_914, 4764) + // Standard Error: 1_482 + .saturating_add(Weight::from_parts(43_264, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -308,10 +306,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2238` // Estimated: `27847` - // Minimum execution time: 125_669_000 picoseconds. - Weight::from_parts(130_907_641, 27847) - // Standard Error: 2_490 - .saturating_add(Weight::from_parts(75_219, 0).saturating_mul(s.into())) + // Minimum execution time: 124_990_000 picoseconds. + Weight::from_parts(129_041_398, 27847) + // Standard Error: 2_335 + .saturating_add(Weight::from_parts(67_889, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(9_u64)) } @@ -362,12 +360,14 @@ impl WeightInfo for SubstrateWeight { /// Storage: `NominationPools::ClaimPermissions` (r:0 w:1) /// Proof: `NominationPools::ClaimPermissions` (`max_values`: None, `max_size`: Some(41), added: 2516, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. - fn withdraw_unbonded_kill(_s: u32, ) -> Weight { + fn withdraw_unbonded_kill(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `2525` // Estimated: `27847` - // Minimum execution time: 225_700_000 picoseconds. - Weight::from_parts(234_390_990, 27847) + // Minimum execution time: 221_955_000 picoseconds. + Weight::from_parts(230_244_437, 27847) + // Standard Error: 4_059 + .saturating_add(Weight::from_parts(7_522, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(24_u64)) .saturating_add(T::DbWeight::get().writes(20_u64)) } @@ -419,19 +419,25 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1169` // Estimated: `8538` - // Minimum execution time: 167_171_000 picoseconds. - Weight::from_parts(170_531_000, 8538) + // Minimum execution time: 165_358_000 picoseconds. + Weight::from_parts(169_683_000, 8538) .saturating_add(T::DbWeight::get().reads(23_u64)) .saturating_add(T::DbWeight::get().writes(17_u64)) } /// Storage: `NominationPools::BondedPools` (r:1 w:0) /// Proof: `NominationPools::BondedPools` (`max_values`: None, `max_size`: Some(254), added: 2729, mode: `MaxEncodedLen`) + /// Storage: `NominationPools::PoolMembers` (r:1 w:0) + /// Proof: `NominationPools::PoolMembers` (`max_values`: None, `max_size`: Some(237), added: 2712, mode: `MaxEncodedLen`) /// Storage: `Staking::Bonded` (r:1 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:0) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) /// Storage: `Staking::MinNominatorBond` (r:1 w:0) /// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `NominationPools::MinCreateBond` (r:1 w:0) + /// Proof: `NominationPools::MinCreateBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `NominationPools::MinJoinBond` (r:1 w:0) + /// Proof: `NominationPools::MinJoinBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:1) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxNominatorsCount` (r:1 w:0) @@ -451,13 +457,13 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[1, 16]`. fn nominate(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1808` + // Measured: `1976` // Estimated: `4556 + n * (2520 ±0)` - // Minimum execution time: 63_785_000 picoseconds. - Weight::from_parts(64_592_302, 4556) - // Standard Error: 9_416 - .saturating_add(Weight::from_parts(1_524_398, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(12_u64)) + // Minimum execution time: 74_483_000 picoseconds. + Weight::from_parts(76_611_288, 4556) + // Standard Error: 9_013 + .saturating_add(Weight::from_parts(1_475_128, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(15_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(5_u64)) .saturating_add(Weight::from_parts(0, 2520).saturating_mul(n.into())) @@ -472,8 +478,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1434` // Estimated: `4556` - // Minimum execution time: 32_096_000 picoseconds. - Weight::from_parts(33_533_000, 4556) + // Minimum execution time: 32_598_000 picoseconds. + Weight::from_parts(33_350_000, 4556) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -488,10 +494,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `532` // Estimated: `3735` - // Minimum execution time: 13_914_000 picoseconds. - Weight::from_parts(14_800_402, 3735) - // Standard Error: 146 - .saturating_add(Weight::from_parts(940, 0).saturating_mul(n.into())) + // Minimum execution time: 13_705_000 picoseconds. + Weight::from_parts(14_594_211, 3735) + // Standard Error: 141 + .saturating_add(Weight::from_parts(2_119, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -511,8 +517,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_373_000 picoseconds. - Weight::from_parts(4_592_000, 0) + // Minimum execution time: 4_222_000 picoseconds. + Weight::from_parts(4_527_000, 0) .saturating_add(T::DbWeight::get().writes(6_u64)) } /// Storage: `NominationPools::BondedPools` (r:1 w:1) @@ -521,17 +527,21 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `532` // Estimated: `3719` - // Minimum execution time: 16_662_000 picoseconds. - Weight::from_parts(17_531_000, 3719) + // Minimum execution time: 16_106_000 picoseconds. + Weight::from_parts(17_365_000, 3719) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `NominationPools::BondedPools` (r:1 w:0) /// Proof: `NominationPools::BondedPools` (`max_values`: None, `max_size`: Some(254), added: 2729, mode: `MaxEncodedLen`) + /// Storage: `NominationPools::PoolMembers` (r:1 w:0) + /// Proof: `NominationPools::PoolMembers` (`max_values`: None, `max_size`: Some(237), added: 2712, mode: `MaxEncodedLen`) /// Storage: `Staking::Bonded` (r:1 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:0) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `Staking::MinNominatorBond` (r:1 w:0) + /// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:1) @@ -546,11 +556,11 @@ impl WeightInfo for SubstrateWeight { /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn chill() -> Weight { // Proof Size summary in bytes: - // Measured: `1971` + // Measured: `2143` // Estimated: `4556` - // Minimum execution time: 61_348_000 picoseconds. - Weight::from_parts(63_712_000, 4556) - .saturating_add(T::DbWeight::get().reads(9_u64)) + // Minimum execution time: 71_301_000 picoseconds. + Weight::from_parts(73_626_000, 4556) + .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } /// Storage: `NominationPools::BondedPools` (r:1 w:1) @@ -565,8 +575,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `804` // Estimated: `3719` - // Minimum execution time: 32_232_000 picoseconds. - Weight::from_parts(33_433_000, 3719) + // Minimum execution time: 32_363_000 picoseconds. + Weight::from_parts(33_400_000, 3719) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -578,8 +588,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `572` // Estimated: `3719` - // Minimum execution time: 16_774_000 picoseconds. - Weight::from_parts(17_671_000, 3719) + // Minimum execution time: 16_686_000 picoseconds. + Weight::from_parts(17_294_000, 3719) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -589,8 +599,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `532` // Estimated: `3719` - // Minimum execution time: 16_724_000 picoseconds. - Weight::from_parts(17_181_000, 3719) + // Minimum execution time: 16_417_000 picoseconds. + Weight::from_parts(17_028_000, 3719) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -600,8 +610,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `532` // Estimated: `3719` - // Minimum execution time: 16_362_000 picoseconds. - Weight::from_parts(17_135_000, 3719) + // Minimum execution time: 16_350_000 picoseconds. + Weight::from_parts(16_905_000, 3719) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -613,8 +623,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `542` // Estimated: `3702` - // Minimum execution time: 14_125_000 picoseconds. - Weight::from_parts(14_705_000, 3702) + // Minimum execution time: 14_081_000 picoseconds. + Weight::from_parts(14_608_000, 3702) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -630,8 +640,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1002` // Estimated: `3719` - // Minimum execution time: 61_699_000 picoseconds. - Weight::from_parts(63_605_000, 3719) + // Minimum execution time: 62_178_000 picoseconds. + Weight::from_parts(64_039_000, 3719) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -647,8 +657,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `901` // Estimated: `4764` - // Minimum execution time: 64_930_000 picoseconds. - Weight::from_parts(66_068_000, 4764) + // Minimum execution time: 64_880_000 picoseconds. + Weight::from_parts(66_541_000, 4764) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -692,8 +702,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `3425` // Estimated: `8877` - // Minimum execution time: 181_861_000 picoseconds. - Weight::from_parts(186_375_000, 8877) + // Minimum execution time: 182_643_000 picoseconds. + Weight::from_parts(186_106_000, 8877) .saturating_add(RocksDbWeight::get().reads(20_u64)) .saturating_add(RocksDbWeight::get().writes(13_u64)) } @@ -725,8 +735,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `3435` // Estimated: `8877` - // Minimum execution time: 182_273_000 picoseconds. - Weight::from_parts(186_635_000, 8877) + // Minimum execution time: 181_464_000 picoseconds. + Weight::from_parts(184_672_000, 8877) .saturating_add(RocksDbWeight::get().reads(17_u64)) .saturating_add(RocksDbWeight::get().writes(13_u64)) } @@ -760,8 +770,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `3500` // Estimated: `8877` - // Minimum execution time: 217_878_000 picoseconds. - Weight::from_parts(221_493_000, 8877) + // Minimum execution time: 216_182_000 picoseconds. + Weight::from_parts(218_448_000, 8877) .saturating_add(RocksDbWeight::get().reads(18_u64)) .saturating_add(RocksDbWeight::get().writes(14_u64)) } @@ -781,8 +791,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1172` // Estimated: `3719` - // Minimum execution time: 74_509_000 picoseconds. - Weight::from_parts(76_683_000, 3719) + // Minimum execution time: 73_830_000 picoseconds. + Weight::from_parts(75_271_000, 3719) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -822,8 +832,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `3622` // Estimated: `27847` - // Minimum execution time: 166_424_000 picoseconds. - Weight::from_parts(169_698_000, 27847) + // Minimum execution time: 166_099_000 picoseconds. + Weight::from_parts(170_355_000, 27847) .saturating_add(RocksDbWeight::get().reads(20_u64)) .saturating_add(RocksDbWeight::get().writes(13_u64)) } @@ -848,10 +858,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1848` // Estimated: `4764` - // Minimum execution time: 66_110_000 picoseconds. - Weight::from_parts(68_620_141, 4764) - // Standard Error: 1_379 - .saturating_add(Weight::from_parts(54_961, 0).saturating_mul(s.into())) + // Minimum execution time: 64_787_000 picoseconds. + Weight::from_parts(67_920_914, 4764) + // Standard Error: 1_482 + .saturating_add(Weight::from_parts(43_264, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -886,10 +896,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2238` // Estimated: `27847` - // Minimum execution time: 125_669_000 picoseconds. - Weight::from_parts(130_907_641, 27847) - // Standard Error: 2_490 - .saturating_add(Weight::from_parts(75_219, 0).saturating_mul(s.into())) + // Minimum execution time: 124_990_000 picoseconds. + Weight::from_parts(129_041_398, 27847) + // Standard Error: 2_335 + .saturating_add(Weight::from_parts(67_889, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(9_u64)) } @@ -940,12 +950,14 @@ impl WeightInfo for () { /// Storage: `NominationPools::ClaimPermissions` (r:0 w:1) /// Proof: `NominationPools::ClaimPermissions` (`max_values`: None, `max_size`: Some(41), added: 2516, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. - fn withdraw_unbonded_kill(_s: u32, ) -> Weight { + fn withdraw_unbonded_kill(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `2525` // Estimated: `27847` - // Minimum execution time: 225_700_000 picoseconds. - Weight::from_parts(234_390_990, 27847) + // Minimum execution time: 221_955_000 picoseconds. + Weight::from_parts(230_244_437, 27847) + // Standard Error: 4_059 + .saturating_add(Weight::from_parts(7_522, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(24_u64)) .saturating_add(RocksDbWeight::get().writes(20_u64)) } @@ -997,19 +1009,25 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1169` // Estimated: `8538` - // Minimum execution time: 167_171_000 picoseconds. - Weight::from_parts(170_531_000, 8538) + // Minimum execution time: 165_358_000 picoseconds. + Weight::from_parts(169_683_000, 8538) .saturating_add(RocksDbWeight::get().reads(23_u64)) .saturating_add(RocksDbWeight::get().writes(17_u64)) } /// Storage: `NominationPools::BondedPools` (r:1 w:0) /// Proof: `NominationPools::BondedPools` (`max_values`: None, `max_size`: Some(254), added: 2729, mode: `MaxEncodedLen`) + /// Storage: `NominationPools::PoolMembers` (r:1 w:0) + /// Proof: `NominationPools::PoolMembers` (`max_values`: None, `max_size`: Some(237), added: 2712, mode: `MaxEncodedLen`) /// Storage: `Staking::Bonded` (r:1 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:0) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) /// Storage: `Staking::MinNominatorBond` (r:1 w:0) /// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `NominationPools::MinCreateBond` (r:1 w:0) + /// Proof: `NominationPools::MinCreateBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) + /// Storage: `NominationPools::MinJoinBond` (r:1 w:0) + /// Proof: `NominationPools::MinJoinBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:1) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxNominatorsCount` (r:1 w:0) @@ -1029,13 +1047,13 @@ impl WeightInfo for () { /// The range of component `n` is `[1, 16]`. fn nominate(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1808` + // Measured: `1976` // Estimated: `4556 + n * (2520 ±0)` - // Minimum execution time: 63_785_000 picoseconds. - Weight::from_parts(64_592_302, 4556) - // Standard Error: 9_416 - .saturating_add(Weight::from_parts(1_524_398, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(12_u64)) + // Minimum execution time: 74_483_000 picoseconds. + Weight::from_parts(76_611_288, 4556) + // Standard Error: 9_013 + .saturating_add(Weight::from_parts(1_475_128, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(15_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes(5_u64)) .saturating_add(Weight::from_parts(0, 2520).saturating_mul(n.into())) @@ -1050,8 +1068,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1434` // Estimated: `4556` - // Minimum execution time: 32_096_000 picoseconds. - Weight::from_parts(33_533_000, 4556) + // Minimum execution time: 32_598_000 picoseconds. + Weight::from_parts(33_350_000, 4556) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1066,10 +1084,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `532` // Estimated: `3735` - // Minimum execution time: 13_914_000 picoseconds. - Weight::from_parts(14_800_402, 3735) - // Standard Error: 146 - .saturating_add(Weight::from_parts(940, 0).saturating_mul(n.into())) + // Minimum execution time: 13_705_000 picoseconds. + Weight::from_parts(14_594_211, 3735) + // Standard Error: 141 + .saturating_add(Weight::from_parts(2_119, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -1089,8 +1107,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_373_000 picoseconds. - Weight::from_parts(4_592_000, 0) + // Minimum execution time: 4_222_000 picoseconds. + Weight::from_parts(4_527_000, 0) .saturating_add(RocksDbWeight::get().writes(6_u64)) } /// Storage: `NominationPools::BondedPools` (r:1 w:1) @@ -1099,17 +1117,21 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `532` // Estimated: `3719` - // Minimum execution time: 16_662_000 picoseconds. - Weight::from_parts(17_531_000, 3719) + // Minimum execution time: 16_106_000 picoseconds. + Weight::from_parts(17_365_000, 3719) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `NominationPools::BondedPools` (r:1 w:0) /// Proof: `NominationPools::BondedPools` (`max_values`: None, `max_size`: Some(254), added: 2729, mode: `MaxEncodedLen`) + /// Storage: `NominationPools::PoolMembers` (r:1 w:0) + /// Proof: `NominationPools::PoolMembers` (`max_values`: None, `max_size`: Some(237), added: 2712, mode: `MaxEncodedLen`) /// Storage: `Staking::Bonded` (r:1 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:0) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) + /// Storage: `Staking::MinNominatorBond` (r:1 w:0) + /// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:1) @@ -1124,11 +1146,11 @@ impl WeightInfo for () { /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn chill() -> Weight { // Proof Size summary in bytes: - // Measured: `1971` + // Measured: `2143` // Estimated: `4556` - // Minimum execution time: 61_348_000 picoseconds. - Weight::from_parts(63_712_000, 4556) - .saturating_add(RocksDbWeight::get().reads(9_u64)) + // Minimum execution time: 71_301_000 picoseconds. + Weight::from_parts(73_626_000, 4556) + .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } /// Storage: `NominationPools::BondedPools` (r:1 w:1) @@ -1143,8 +1165,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `804` // Estimated: `3719` - // Minimum execution time: 32_232_000 picoseconds. - Weight::from_parts(33_433_000, 3719) + // Minimum execution time: 32_363_000 picoseconds. + Weight::from_parts(33_400_000, 3719) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -1156,8 +1178,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `572` // Estimated: `3719` - // Minimum execution time: 16_774_000 picoseconds. - Weight::from_parts(17_671_000, 3719) + // Minimum execution time: 16_686_000 picoseconds. + Weight::from_parts(17_294_000, 3719) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1167,8 +1189,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `532` // Estimated: `3719` - // Minimum execution time: 16_724_000 picoseconds. - Weight::from_parts(17_181_000, 3719) + // Minimum execution time: 16_417_000 picoseconds. + Weight::from_parts(17_028_000, 3719) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1178,8 +1200,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `532` // Estimated: `3719` - // Minimum execution time: 16_362_000 picoseconds. - Weight::from_parts(17_135_000, 3719) + // Minimum execution time: 16_350_000 picoseconds. + Weight::from_parts(16_905_000, 3719) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1191,8 +1213,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `542` // Estimated: `3702` - // Minimum execution time: 14_125_000 picoseconds. - Weight::from_parts(14_705_000, 3702) + // Minimum execution time: 14_081_000 picoseconds. + Weight::from_parts(14_608_000, 3702) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1208,8 +1230,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1002` // Estimated: `3719` - // Minimum execution time: 61_699_000 picoseconds. - Weight::from_parts(63_605_000, 3719) + // Minimum execution time: 62_178_000 picoseconds. + Weight::from_parts(64_039_000, 3719) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -1225,8 +1247,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `901` // Estimated: `4764` - // Minimum execution time: 64_930_000 picoseconds. - Weight::from_parts(66_068_000, 4764) + // Minimum execution time: 64_880_000 picoseconds. + Weight::from_parts(66_541_000, 4764) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } diff --git a/substrate/frame/nomination-pools/test-staking/src/lib.rs b/substrate/frame/nomination-pools/test-staking/src/lib.rs index 865b7a71e68..98bff537c90 100644 --- a/substrate/frame/nomination-pools/test-staking/src/lib.rs +++ b/substrate/frame/nomination-pools/test-staking/src/lib.rs @@ -22,10 +22,12 @@ mod mock; use frame_support::{assert_noop, assert_ok, traits::Currency}; use mock::*; use pallet_nomination_pools::{ - BondedPools, Error as PoolsError, Event as PoolsEvent, LastPoolId, PoolMember, PoolMembers, - PoolState, + BondExtra, BondedPools, Error as PoolsError, Event as PoolsEvent, LastPoolId, PoolMember, + PoolMembers, PoolState, +}; +use pallet_staking::{ + CurrentEra, Error as StakingError, Event as StakingEvent, Payee, RewardDestination, }; -use pallet_staking::{CurrentEra, Event as StakingEvent, Payee, RewardDestination}; use sp_runtime::{bounded_btree_map, traits::Zero}; #[test] @@ -191,6 +193,131 @@ fn pool_lifecycle_e2e() { }) } +#[test] +fn pool_chill_e2e() { + new_test_ext().execute_with(|| { + assert_eq!(Balances::minimum_balance(), 5); + assert_eq!(Staking::current_era(), None); + + // create the pool, we know this has id 1. + assert_ok!(Pools::create(RuntimeOrigin::signed(10), 50, 10, 10, 10)); + assert_eq!(LastPoolId::::get(), 1); + + // have the pool nominate. + assert_ok!(Pools::nominate(RuntimeOrigin::signed(10), 1, vec![1, 2, 3])); + + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Bonded { stash: POOL1_BONDED, amount: 50 }] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::Created { depositor: 10, pool_id: 1 }, + PoolsEvent::Bonded { member: 10, pool_id: 1, bonded: 50, joined: true }, + ] + ); + + // have two members join + assert_ok!(Pools::join(RuntimeOrigin::signed(20), 10, 1)); + assert_ok!(Pools::join(RuntimeOrigin::signed(21), 10, 1)); + + assert_eq!( + staking_events_since_last_call(), + vec![ + StakingEvent::Bonded { stash: POOL1_BONDED, amount: 10 }, + StakingEvent::Bonded { stash: POOL1_BONDED, amount: 10 }, + ] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::Bonded { member: 20, pool_id: 1, bonded: 10, joined: true }, + PoolsEvent::Bonded { member: 21, pool_id: 1, bonded: 10, joined: true }, + ] + ); + + // in case depositor does not have more than `MinNominatorBond` staked, we can end up in + // situation where a member unbonding would cause pool balance to drop below + // `MinNominatorBond` and hence not allowed. This can happen if the `MinNominatorBond` is + // increased after the pool is created. + assert_ok!(Staking::set_staking_configs( + RuntimeOrigin::root(), + pallet_staking::ConfigOp::Set(55), // minimum nominator bond + pallet_staking::ConfigOp::Noop, + pallet_staking::ConfigOp::Noop, + pallet_staking::ConfigOp::Noop, + pallet_staking::ConfigOp::Noop, + pallet_staking::ConfigOp::Noop, + pallet_staking::ConfigOp::Noop, + )); + + // members can unbond as long as total stake of the pool is above min nominator bond + assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, 10),); + assert_eq!(PoolMembers::::get(20).unwrap().unbonding_eras.len(), 1); + assert_eq!(PoolMembers::::get(20).unwrap().points, 0); + + // this member cannot unbond since it will cause `pool stake < MinNominatorBond` + assert_noop!( + Pools::unbond(RuntimeOrigin::signed(21), 21, 10), + StakingError::::InsufficientBond, + ); + + // members can call `chill` permissionlessly now + assert_ok!(Pools::chill(RuntimeOrigin::signed(20), 1)); + + // now another member can unbond. + assert_ok!(Pools::unbond(RuntimeOrigin::signed(21), 21, 10)); + assert_eq!(PoolMembers::::get(21).unwrap().unbonding_eras.len(), 1); + assert_eq!(PoolMembers::::get(21).unwrap().points, 0); + + // nominator can not resume nomination until depositor have enough stake + assert_noop!( + Pools::nominate(RuntimeOrigin::signed(10), 1, vec![1, 2, 3]), + PoolsError::::MinimumBondNotMet, + ); + + // other members joining pool does not affect the depositor's ability to resume nomination + assert_ok!(Pools::join(RuntimeOrigin::signed(22), 10, 1)); + + assert_noop!( + Pools::nominate(RuntimeOrigin::signed(10), 1, vec![1, 2, 3]), + PoolsError::::MinimumBondNotMet, + ); + + // depositor can bond extra stake + assert_ok!(Pools::bond_extra(RuntimeOrigin::signed(10), BondExtra::FreeBalance(10))); + + // `chill` can not be called permissionlessly anymore + assert_noop!( + Pools::chill(RuntimeOrigin::signed(20), 1), + PoolsError::::NotNominator, + ); + + // now nominator can resume nomination + assert_ok!(Pools::nominate(RuntimeOrigin::signed(10), 1, vec![1, 2, 3])); + + // skip to make the unbonding period end. + CurrentEra::::set(Some(BondingDuration::get())); + + // members can now withdraw. + assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(20), 20, 0)); + assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(21), 21, 0)); + + assert_eq!( + staking_events_since_last_call(), + vec![ + StakingEvent::Unbonded { stash: POOL1_BONDED, amount: 10 }, + StakingEvent::Chilled { stash: POOL1_BONDED }, + StakingEvent::Unbonded { stash: POOL1_BONDED, amount: 10 }, + StakingEvent::Bonded { stash: POOL1_BONDED, amount: 10 }, // other member bonding + StakingEvent::Bonded { stash: POOL1_BONDED, amount: 10 }, // depositor bond extra + StakingEvent::Withdrawn { stash: POOL1_BONDED, amount: 20 }, + ] + ); + }) +} + #[test] fn pool_slash_e2e() { new_test_ext().execute_with(|| { -- GitLab From 30c32e3d8456984e19a7edf9e851b0db6135f376 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= <123550+andresilva@users.noreply.github.com> Date: Thu, 7 Mar 2024 10:45:56 +0000 Subject: [PATCH 361/392] move substrate-bip39 into polkadot-sdk (#3579) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moves [substrate-bip39](https://github.com/paritytech/substrate-bip39) into substrate. All git history is preserved. Dependencies have been updated to use the same version as the rest of the repo. Fixes https://github.com/paritytech/polkadot-sdk/issues/1934. --------- Co-authored-by: Maciej Hirsz Co-authored-by: Maciej Hirsz <1096222+maciejhirsz@users.noreply.github.com> Co-authored-by: Gav Wood Co-authored-by: Stanislav Tkach Co-authored-by: Robert Habermeier Co-authored-by: Pierre Krieger Co-authored-by: Demi M. Obenour Co-authored-by: Bastian Köcher Co-authored-by: NikVolf Co-authored-by: Bastian Köcher Co-authored-by: Benjamin Kampmann Co-authored-by: Maciej Hirsz Co-authored-by: cheme Co-authored-by: adoerr <0xad@gmx.net> Co-authored-by: Jun Jiang Co-authored-by: Dan Shields <35669742+NukeManDan@users.noreply.github.com> Co-authored-by: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> --- Cargo.lock | 172 +++---------- Cargo.toml | 1 + polkadot/node/core/approval-voting/Cargo.toml | 2 +- polkadot/node/subsystem-bench/Cargo.toml | 5 +- substrate/primitives/core/Cargo.toml | 4 +- substrate/utils/substrate-bip39/Cargo.toml | 31 +++ substrate/utils/substrate-bip39/README.md | 55 +++++ substrate/utils/substrate-bip39/src/lib.rs | 232 ++++++++++++++++++ 8 files changed, 359 insertions(+), 143 deletions(-) create mode 100644 substrate/utils/substrate-bip39/Cargo.toml create mode 100644 substrate/utils/substrate-bip39/README.md create mode 100644 substrate/utils/substrate-bip39/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 177d76b8706..4815e976b5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -744,12 +744,6 @@ dependencies = [ "nodrop", ] -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - [[package]] name = "arrayvec" version = "0.7.4" @@ -1334,7 +1328,7 @@ dependencies = [ "ark-std 0.4.0", "dleq_vrf", "fflonk", - "merlin 3.0.0", + "merlin", "rand_chacha 0.3.1", "rand_core 0.6.4", "ring 0.1.0", @@ -1559,18 +1553,6 @@ dependencies = [ "constant_time_eq 0.3.0", ] -[[package]] -name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -dependencies = [ - "block-padding", - "byte-tools", - "byteorder", - "generic-array 0.12.4", -] - [[package]] name = "block-buffer" version = "0.9.0" @@ -1589,15 +1571,6 @@ dependencies = [ "generic-array 0.14.7", ] -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -dependencies = [ - "byte-tools", -] - [[package]] name = "blocking" version = "1.3.1" @@ -2634,9 +2607,9 @@ dependencies = [ [[package]] name = "clap-num" -version = "1.0.2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488557e97528174edaa2ee268b23a809e0c598213a4bbcb4f34575a46fda147e" +checksum = "0e063d263364859dc54fb064cedb7c122740cd4733644b14b176c097f51e8ab7" dependencies = [ "num-traits", ] @@ -2854,11 +2827,10 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "colored" -version = "2.0.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" dependencies = [ - "is-terminal", "lazy_static", "windows-sys 0.48.0", ] @@ -2886,7 +2858,7 @@ dependencies = [ "ark-std 0.4.0", "fflonk", "getrandom_or_panic", - "merlin 3.0.0", + "merlin", "rand_chacha 0.3.1", ] @@ -3526,16 +3498,6 @@ dependencies = [ "subtle 2.5.0", ] -[[package]] -name = "crypto-mac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" -dependencies = [ - "generic-array 0.14.7", - "subtle 2.5.0", -] - [[package]] name = "ctr" version = "0.7.0" @@ -4396,19 +4358,6 @@ dependencies = [ "url", ] -[[package]] -name = "curve25519-dalek" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a9b85542f99a2dfa2a1b8e192662741c9859a846b296bef1c92ef9b58b5a216" -dependencies = [ - "byteorder", - "digest 0.8.1", - "rand_core 0.5.1", - "subtle 2.5.0", - "zeroize", -] - [[package]] name = "curve25519-dalek" version = "3.2.0" @@ -5238,12 +5187,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - [[package]] name = "fallible-iterator" version = "0.2.0" @@ -5353,7 +5296,7 @@ dependencies = [ "ark-poly", "ark-serialize 0.4.2", "ark-std 0.4.0", - "merlin 3.0.0", + "merlin", ] [[package]] @@ -6428,16 +6371,6 @@ dependencies = [ "digest 0.9.0", ] -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac 0.11.0", - "digest 0.9.0", -] - [[package]] name = "hmac" version = "0.12.1" @@ -8124,18 +8057,6 @@ dependencies = [ "hash-db", ] -[[package]] -name = "merlin" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e261cf0f8b3c42ded9f7d2bb59dea03aa52bc8a1cbc7482f9fc3fd1229d3b42" -dependencies = [ - "byteorder", - "keccak", - "rand_core 0.5.1", - "zeroize", -] - [[package]] name = "merlin" version = "3.0.0" @@ -11642,19 +11563,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7924d1d0ad836f665c9065e26d016c673ece3993f30d340068b16f282afc1156" [[package]] -name = "paste" -version = "1.0.14" +name = "password-hash" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle 2.5.0", +] [[package]] -name = "pbkdf2" -version = "0.8.0" +name = "paste" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa" -dependencies = [ - "crypto-mac 0.11.0", -] +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "pbkdf2" @@ -11663,6 +11586,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest 0.10.7", + "password-hash", ] [[package]] @@ -12454,7 +12378,7 @@ dependencies = [ "kvdb", "kvdb-memorydb", "log", - "merlin 3.0.0", + "merlin", "parity-scale-codec", "parking_lot 0.12.1", "polkadot-node-jaeger", @@ -13672,7 +13596,7 @@ dependencies = [ "sc-keystore", "sc-network", "sc-service", - "schnorrkel 0.9.1", + "schnorrkel 0.11.4", "serde", "serde_yaml", "sha1", @@ -14921,7 +14845,7 @@ dependencies = [ "blake2 0.10.6", "common", "fflonk", - "merlin 3.0.0", + "merlin", ] [[package]] @@ -17103,22 +17027,6 @@ dependencies = [ "hashbrown 0.13.2", ] -[[package]] -name = "schnorrkel" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862" -dependencies = [ - "arrayref", - "arrayvec 0.5.2", - "curve25519-dalek 2.1.3", - "merlin 2.0.1", - "rand_core 0.5.1", - "sha2 0.8.2", - "subtle 2.5.0", - "zeroize", -] - [[package]] name = "schnorrkel" version = "0.10.2" @@ -17128,7 +17036,7 @@ dependencies = [ "arrayref", "arrayvec 0.7.4", "curve25519-dalek-ng", - "merlin 3.0.0", + "merlin", "rand_core 0.6.4", "sha2 0.9.9", "subtle-ng", @@ -17146,7 +17054,7 @@ dependencies = [ "arrayvec 0.7.4", "curve25519-dalek 4.1.2", "getrandom_or_panic", - "merlin 3.0.0", + "merlin", "rand_core 0.6.4", "serde_bytes", "sha2 0.10.7", @@ -17510,18 +17418,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "sha2" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" -dependencies = [ - "block-buffer 0.7.3", - "digest 0.8.1", - "fake-simd", - "opaque-debug 0.2.3", -] - [[package]] name = "sha2" version = "0.9.9" @@ -17756,13 +17652,13 @@ dependencies = [ "hmac 0.12.1", "itertools 0.11.0", "libsecp256k1", - "merlin 3.0.0", + "merlin", "no-std-net", "nom", "num-bigint", "num-rational", "num-traits", - "pbkdf2 0.12.2", + "pbkdf2", "pin-project", "poly1305 0.8.0", "rand", @@ -18673,7 +18569,7 @@ dependencies = [ "lazy_static", "libsecp256k1", "log", - "merlin 3.0.0", + "merlin", "parity-scale-codec", "parking_lot 0.12.1", "paste", @@ -19829,14 +19725,14 @@ dependencies = [ [[package]] name = "substrate-bip39" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e620c7098893ba667438b47169c00aacdd9e7c10e042250ce2b60b087ec97328" +version = "0.4.7" dependencies = [ - "hmac 0.11.0", - "pbkdf2 0.8.0", - "schnorrkel 0.9.1", - "sha2 0.9.9", + "bip39", + "hmac 0.12.1", + "pbkdf2", + "rustc-hex", + "schnorrkel 0.11.4", + "sha2 0.10.7", "zeroize", ] diff --git a/Cargo.toml b/Cargo.toml index a2e22e0b927..80068596685 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -496,6 +496,7 @@ members = [ "substrate/utils/frame/rpc/system", "substrate/utils/frame/try-runtime/cli", "substrate/utils/prometheus", + "substrate/utils/substrate-bip39", "substrate/utils/wasm-builder", "templates/minimal/node", diff --git a/polkadot/node/core/approval-voting/Cargo.toml b/polkadot/node/core/approval-voting/Cargo.toml index f6d89dbc152..2a5b6198b9a 100644 --- a/polkadot/node/core/approval-voting/Cargo.toml +++ b/polkadot/node/core/approval-voting/Cargo.toml @@ -35,7 +35,7 @@ sp-consensus = { path = "../../../../substrate/primitives/consensus/common", def sp-consensus-slots = { path = "../../../../substrate/primitives/consensus/slots", default-features = false } sp-application-crypto = { path = "../../../../substrate/primitives/application-crypto", default-features = false, features = ["full_crypto"] } sp-runtime = { path = "../../../../substrate/primitives/runtime", default-features = false } -# should match schnorrkel +# rand_core should match schnorrkel rand_core = "0.6.2" rand_chacha = { version = "0.3.1" } rand = "0.8.5" diff --git a/polkadot/node/subsystem-bench/Cargo.toml b/polkadot/node/subsystem-bench/Cargo.toml index 726e7de4587..7c60ff48269 100644 --- a/polkadot/node/subsystem-bench/Cargo.toml +++ b/polkadot/node/subsystem-bench/Cargo.toml @@ -78,8 +78,9 @@ sp-consensus-babe = { path = "../../../substrate/primitives/consensus/babe" } sp-runtime = { path = "../../../substrate/primitives/runtime", default-features = false } sp-timestamp = { path = "../../../substrate/primitives/timestamp" } -schnorrkel = { version = "0.9.1", default-features = false } -rand_core = "0.6.2" # should match schnorrkel +schnorrkel = { version = "0.11.4", default-features = false } +# rand_core should match schnorrkel +rand_core = "0.6.2" rand_chacha = { version = "0.3.1" } paste = "1.0.14" orchestra = { version = "0.3.5", default-features = false, features = ["futures_channel"] } diff --git a/substrate/primitives/core/Cargo.toml b/substrate/primitives/core/Cargo.toml index 8fcabfeb238..70ca7be6a2d 100644 --- a/substrate/primitives/core/Cargo.toml +++ b/substrate/primitives/core/Cargo.toml @@ -27,7 +27,7 @@ hash-db = { version = "0.16.0", default-features = false } hash256-std-hasher = { version = "0.15.2", default-features = false } bs58 = { version = "0.5.0", default-features = false, optional = true } rand = { version = "0.8.5", features = ["small_rng"], optional = true } -substrate-bip39 = { version = "0.4.5", optional = true } +substrate-bip39 = { path = "../../utils/substrate-bip39", optional = true } bip39 = { version = "2.0.0", default-features = false } zeroize = { version = "1.4.3", default-features = false } secrecy = { version = "0.8.0", default-features = false } @@ -116,7 +116,7 @@ std = [ "sp-std/std", "sp-storage/std", "ss58-registry/std", - "substrate-bip39", + "substrate-bip39/std", "thiserror", "tracing", "w3f-bls?/std", diff --git a/substrate/utils/substrate-bip39/Cargo.toml b/substrate/utils/substrate-bip39/Cargo.toml new file mode 100644 index 00000000000..a46f81ee24d --- /dev/null +++ b/substrate/utils/substrate-bip39/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "substrate-bip39" +version = "0.4.7" +license = "Apache-2.0" +description = "Converting BIP39 entropy to valid Substrate (sr25519) SecretKeys" +documentation = "https://docs.rs/substrate-bip39" +authors.workspace = true +edition.workspace = true +repository.workspace = true + +[dependencies] +hmac = "0.12.1" +pbkdf2 = { version = "0.12.2", default-features = false } +schnorrkel = { version = "0.11.4", default-features = false } +sha2 = { version = "0.10.7", default-features = false } +zeroize = { version = "1.4.3", default-features = false } + +[dev-dependencies] +bip39 = "2.0.0" +rustc-hex = "2.1.0" + +[features] +default = ["std"] +std = [ + "hmac/std", + "pbkdf2/std", + "schnorrkel/std", + "sha2/std", + "zeroize/alloc", + "zeroize/std", +] diff --git a/substrate/utils/substrate-bip39/README.md b/substrate/utils/substrate-bip39/README.md new file mode 100644 index 00000000000..368d18f406b --- /dev/null +++ b/substrate/utils/substrate-bip39/README.md @@ -0,0 +1,55 @@ +# Substrate BIP39 + +This is a crate for deriving secret keys for Ristretto compressed Ed25519 (should be compatible with Ed25519 at this +time) from BIP39 phrases. + +## Why? + +The natural approach here would be to use the 64-byte seed generated from the BIP39 phrase, and use that to construct +the key. This approach, while reasonable and fairly straight forward to implement, also means we would have to inherit +all the characteristics of seed generation. Since we are breaking compatibility with both BIP32 and BIP44 anyway (which +we are free to do as we are no longer using the Secp256k1 curve), there is also no reason why we should adhere to BIP39 +seed generation from the mnemonic. + +BIP39 seed generation was designed to be compatible with user supplied brain wallet phrases as well as being extensible +to wallets providing their own dictionaries and checksum mechanism. Issues with those two points: + +1. Brain wallets are a horrible idea, simply because humans are bad entropy generators. It's next to impossible to + educate users on how to use that feature in a secure manner. The 2048 rounds of PBKDF2 is a mere inconvenience that + offers no real protection against dictionary attacks for anyone equipped with modern consumer hardware. Brain wallets + have given users false sense of security. _People have lost money_ this way and wallet providers today tend to stick + to CSPRNG supplied dictionary phrases. + +2. Providing own dictionaries felt into the _you ain't gonna need it_ anti-pattern category on day 1. Wallet providers + (be it hardware or software) typically want their products to be compatibile with other wallets so that users can + migrate to their product without having to migrate all their assets. + +To achieve the above phrases have to be precisely encoded in _The One True Canonical Encoding_, for which UTF-8 NFKD was +chosen. This is largely irrelevant (and even ignored) for English phrases, as they encode to basically just ASCII in +virtualy every character encoding known to mankind, but immedietly becomes a problem for dictionaries that do use +non-ASCII characters. Even if the right encoding is used and implemented correctly, there are still [other caveats +present for some non-english dictionaries](https://github.com/bitcoin/bips/blob/master/bip-0039/bip-0039-wordlists.md), +such as normalizing spaces to a canonical form, or making some latin based characters equivalent to their base in +dictionary lookups (eg. Spanish `ñ` and `n` are meant to be interchangeable). Thinking about all of this gives me a +headache, and opens doors for disagreements between buggy implementations, breaking compatibility. + +BIP39 does already provide a form of the mnemonic that is free from all of these issues: the entropy byte array. Since +veryfing the checksum requires that we recover the entropy from which the phrase was generated, no extra work is +actually needed here. Wallet implementators can encode the dictionaries in whatever encoding they find convenient (as +long as they are the standard BIP39 dictionaries), no harm in using UTF-16 string primitives that Java and JavaScript +provide. Since the dictionary is fixed and known, and the checksum is done on the entropy itself, the exact character +encoding used becomes irrelevant, as are the precise codepoints and amount of whitespace around the words. It is thus +much harder to create a buggy implementation. + +PBKDF2 was kept in place, along with the password. Using 24 words (with its 256 bits entropy) makes the extra hashing +redundant (if you could brute force 256 bit entropy, you can also just brute force secret keys), however some users +might be still using 12 word phrases from other applications. There is no good reason to prohibit users from recovering +their old wallets using 12 words that I can see, in which case the extra hashing does provide _some_ protection. +Passwords are also a feature that some power users find useful - particularly for creating a decoy address with a small +balance with empty password, while the funds proper are stored on an address that requires a password to be entered. + +## Why not ditch BIP39 altogether? + +Because there are hardware wallets that use a single phrase for the entire device, and operate multiple accounts on +multiple networks using that. A completely different wordlist would make their life much harder when it comes to +providing future Substrate support. diff --git a/substrate/utils/substrate-bip39/src/lib.rs b/substrate/utils/substrate-bip39/src/lib.rs new file mode 100644 index 00000000000..3673d20faed --- /dev/null +++ b/substrate/utils/substrate-bip39/src/lib.rs @@ -0,0 +1,232 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(not(feature = "std"))] +extern crate alloc; +#[cfg(not(feature = "std"))] +use alloc::string::String; + +use hmac::Hmac; +use pbkdf2::pbkdf2; +use schnorrkel::keys::MiniSecretKey; +use sha2::Sha512; +use zeroize::Zeroize; + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum Error { + InvalidEntropy, +} + +/// `entropy` should be a byte array from a correctly recovered and checksumed BIP39. +/// +/// This function accepts slices of different length for different word lengths: +/// +/// + 16 bytes for 12 words. +/// + 20 bytes for 15 words. +/// + 24 bytes for 18 words. +/// + 28 bytes for 21 words. +/// + 32 bytes for 24 words. +/// +/// Any other length will return an error. +/// +/// `password` is analog to BIP39 seed generation itself, with an empty string being defalt. +pub fn mini_secret_from_entropy(entropy: &[u8], password: &str) -> Result { + let seed = seed_from_entropy(entropy, password)?; + Ok(MiniSecretKey::from_bytes(&seed[..32]).expect("Length is always correct; qed")) +} + +/// Similar to `mini_secret_from_entropy`, except that it provides the 64-byte seed directly. +pub fn seed_from_entropy(entropy: &[u8], password: &str) -> Result<[u8; 64], Error> { + if entropy.len() < 16 || entropy.len() > 32 || entropy.len() % 4 != 0 { + return Err(Error::InvalidEntropy); + } + + let mut salt = String::with_capacity(8 + password.len()); + salt.push_str("mnemonic"); + salt.push_str(password); + + let mut seed = [0u8; 64]; + + pbkdf2::>(entropy, salt.as_bytes(), 2048, &mut seed) + .map_err(|_| Error::InvalidEntropy)?; + + salt.zeroize(); + + Ok(seed) +} + +#[cfg(test)] +mod test { + use super::*; + + #[cfg(not(feature = "std"))] + use alloc::vec::Vec; + + use bip39::{Language, Mnemonic}; + use rustc_hex::FromHex; + + // phrase, entropy, seed, expanded secret_key + // + // ALL SEEDS GENERATED USING "Substrate" PASSWORD! + static VECTORS: &[[&str; 3]] = &[ + [ + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", + "00000000000000000000000000000000", + "44e9d125f037ac1d51f0a7d3649689d422c2af8b1ec8e00d71db4d7bf6d127e33f50c3d5c84fa3e5399c72d6cbbbbc4a49bf76f76d952f479d74655a2ef2d453", + ], + [ + "legal winner thank year wave sausage worth useful legal winner thank yellow", + "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", + "4313249608fe8ac10fd5886c92c4579007272cb77c21551ee5b8d60b780416850f1e26c1f4b8d88ece681cb058ab66d6182bc2ce5a03181f7b74c27576b5c8bf", + ], + [ + "letter advice cage absurd amount doctor acoustic avoid letter advice cage above", + "80808080808080808080808080808080", + "27f3eb595928c60d5bc91a4d747da40ed236328183046892ed6cd5aa9ae38122acd1183adf09a89839acb1e6eaa7fb563cc958a3f9161248d5a036e0d0af533d", + ], + [ + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong", + "ffffffffffffffffffffffffffffffff", + "227d6256fd4f9ccaf06c45eaa4b2345969640462bbb00c5f51f43cb43418c7a753265f9b1e0c0822c155a9cabc769413ecc14553e135fe140fc50b6722c6b9df", + ], + [ + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent", + "000000000000000000000000000000000000000000000000", + "44e9d125f037ac1d51f0a7d3649689d422c2af8b1ec8e00d71db4d7bf6d127e33f50c3d5c84fa3e5399c72d6cbbbbc4a49bf76f76d952f479d74655a2ef2d453", + ], + [ + "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will", + "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", + "cb1d50e14101024a88905a098feb1553d4306d072d7460e167a60ccb3439a6817a0afc59060f45d999ddebc05308714733c9e1e84f30feccddd4ad6f95c8a445", + ], + [ + "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always", + "808080808080808080808080808080808080808080808080", + "9ddecf32ce6bee77f867f3c4bb842d1f0151826a145cb4489598fe71ac29e3551b724f01052d1bc3f6d9514d6df6aa6d0291cfdf997a5afdb7b6a614c88ab36a", + ], + [ + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when", + "ffffffffffffffffffffffffffffffffffffffffffffffff", + "8971cb290e7117c64b63379c97ed3b5c6da488841bd9f95cdc2a5651ac89571e2c64d391d46e2475e8b043911885457cd23e99a28b5a18535fe53294dc8e1693", + ], + [ + "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art", + "0000000000000000000000000000000000000000000000000000000000000000", + "44e9d125f037ac1d51f0a7d3649689d422c2af8b1ec8e00d71db4d7bf6d127e33f50c3d5c84fa3e5399c72d6cbbbbc4a49bf76f76d952f479d74655a2ef2d453", + ], + [ + "legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title", + "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", + "3037276a5d05fcd7edf51869eb841bdde27c574dae01ac8cfb1ea476f6bea6ef57ab9afe14aea1df8a48f97ae25b37d7c8326e49289efb25af92ba5a25d09ed3", + ], + [ + "letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless", + "8080808080808080808080808080808080808080808080808080808080808080", + "2c9c6144a06ae5a855453d98c3dea470e2a8ffb78179c2e9eb15208ccca7d831c97ddafe844ab933131e6eb895f675ede2f4e39837bb5769d4e2bc11df58ac42", + ], + [ + "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "047e89ef7739cbfe30da0ad32eb1720d8f62441dd4f139b981b8e2d0bd412ed4eb14b89b5098c49db2301d4e7df4e89c21e53f345138e56a5e7d63fae21c5939", + ], + [ + "ozone drill grab fiber curtain grace pudding thank cruise elder eight picnic", + "9e885d952ad362caeb4efe34a8e91bd2", + "f4956be6960bc145cdab782e649a5056598fd07cd3f32ceb73421c3da27833241324dc2c8b0a4d847eee457e6d4c5429f5e625ece22abaa6a976e82f1ec5531d", + ], + [ + "gravity machine north sort system female filter attitude volume fold club stay feature office ecology stable narrow fog", + "6610b25967cdcca9d59875f5cb50b0ea75433311869e930b", + "fbcc5229ade0c0ff018cb7a329c5459f91876e4dde2a97ddf03c832eab7f26124366a543f1485479c31a9db0d421bda82d7e1fe562e57f3533cb1733b001d84d", + ], + [ + "hamster diagram private dutch cause delay private meat slide toddler razor book happy fancy gospel tennis maple dilemma loan word shrug inflict delay length", + "68a79eaca2324873eacc50cb9c6eca8cc68ea5d936f98787c60c7ebc74e6ce7c", + "7c60c555126c297deddddd59f8cdcdc9e3608944455824dd604897984b5cc369cad749803bb36eb8b786b570c9cdc8db275dbe841486676a6adf389f3be3f076", + ], + [ + "scheme spot photo card baby mountain device kick cradle pact join borrow", + "c0ba5a8e914111210f2bd131f3d5e08d", + "c12157bf2506526c4bd1b79a056453b071361538e9e2c19c28ba2cfa39b5f23034b974e0164a1e8acd30f5b4c4de7d424fdb52c0116bfc6a965ba8205e6cc121", + ], + [ + "horn tenant knee talent sponsor spell gate clip pulse soap slush warm silver nephew swap uncle crack brave", + "6d9be1ee6ebd27a258115aad99b7317b9c8d28b6d76431c3", + "23766723e970e6b79dec4d5e4fdd627fd27d1ee026eb898feb9f653af01ad22080c6f306d1061656d01c4fe9a14c05f991d2c7d8af8730780de4f94cd99bd819", + ], + [ + "panda eyebrow bullet gorilla call smoke muffin taste mesh discover soft ostrich alcohol speed nation flash devote level hobby quick inner drive ghost inside", + "9f6a2878b2520799a44ef18bc7df394e7061a224d2c33cd015b157d746869863", + "f4c83c86617cb014d35cd87d38b5ef1c5d5c3d58a73ab779114438a7b358f457e0462c92bddab5a406fe0e6b97c71905cf19f925f356bc673ceb0e49792f4340", + ], + [ + "cat swing flag economy stadium alone churn speed unique patch report train", + "23db8160a31d3e0dca3688ed941adbf3", + "719d4d4de0638a1705bf5237262458983da76933e718b2d64eb592c470f3c5d222e345cc795337bb3da393b94375ff4a56cfcd68d5ea25b577ee9384d35f4246", + ], + [ + "light rule cinnamon wrap drastic word pride squirrel upgrade then income fatal apart sustain crack supply proud access", + "8197a4a47f0425faeaa69deebc05ca29c0a5b5cc76ceacc0", + "7ae1291db32d16457c248567f2b101e62c5549d2a64cd2b7605d503ec876d58707a8d663641e99663bc4f6cc9746f4852e75e7e54de5bc1bd3c299c9a113409e", + ], + [ + "all hour make first leader extend hole alien behind guard gospel lava path output census museum junior mass reopen famous sing advance salt reform", + "066dca1a2bb7e8a1db2832148ce9933eea0f3ac9548d793112d9a95c9407efad", + "a911a5f4db0940b17ecb79c4dcf9392bf47dd18acaebdd4ef48799909ebb49672947cc15f4ef7e8ef47103a1a91a6732b821bda2c667e5b1d491c54788c69391", + ], + [ + "vessel ladder alter error federal sibling chat ability sun glass valve picture", + "f30f8c1da665478f49b001d94c5fc452", + "4e2314ca7d9eebac6fe5a05a5a8d3546bc891785414d82207ac987926380411e559c885190d641ff7e686ace8c57db6f6e4333c1081e3d88d7141a74cf339c8f", + ], + [ + "scissors invite lock maple supreme raw rapid void congress muscle digital elegant little brisk hair mango congress clump", + "c10ec20dc3cd9f652c7fac2f1230f7a3c828389a14392f05", + "7a83851102849edc5d2a3ca9d8044d0d4f00e5c4a292753ed3952e40808593251b0af1dd3c9ed9932d46e8608eb0b928216a6160bd4fc775a6e6fbd493d7c6b2", + ], + [ + "void come effort suffer camp survey warrior heavy shoot primary clutch crush open amazing screen patrol group space point ten exist slush involve unfold", + "f585c11aec520db57dd353c69554b21a89b20fb0650966fa0a9d6f74fd989d8f", + "938ba18c3f521f19bd4a399c8425b02c716844325b1a65106b9d1593fbafe5e0b85448f523f91c48e331995ff24ae406757cff47d11f240847352b348ff436ed", + ] + ]; + + #[test] + fn vectors_are_correct() { + for vector in VECTORS { + let phrase = vector[0]; + + let expected_entropy: Vec = vector[1].from_hex().unwrap(); + let expected_seed: Vec = vector[2].from_hex().unwrap(); + + let mnemonic = Mnemonic::parse_in(Language::English, phrase).unwrap(); + let seed = seed_from_entropy(&mnemonic.to_entropy(), "Substrate").unwrap(); + let secret = mini_secret_from_entropy(&mnemonic.to_entropy(), "Substrate") + .unwrap() + .to_bytes(); + + assert_eq!( + mnemonic.to_entropy(), + &expected_entropy[..], + "Entropy is incorrect for {}", + phrase + ); + assert_eq!(&seed[..], &expected_seed[..], "Seed is incorrect for {}", phrase); + assert_eq!(&secret[..], &expected_seed[..32], "Secret is incorrect for {}", phrase); + } + } +} -- GitLab From 50cc1c2f7efa0e61ac773b8e89171c9640315475 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Thu, 7 Mar 2024 11:40:30 +0000 Subject: [PATCH 362/392] Add documentation around pallet coupling (#3542) substrate.io deprecation companion: https://github.com/substrate-developer-hub/substrate-docs/pull/2139 pba-content companion: https://github.com/Polkadot-Blockchain-Academy/pba-content/pull/978 partially inspired by: https://github.com/paritytech/polkadot-sdk/issues/3535 --------- Co-authored-by: Ankan <10196091+Ank4n@users.noreply.github.com> --- Cargo.lock | 1 + docs/sdk/Cargo.toml | 1 + docs/sdk/src/polkadot_sdk/frame_runtime.rs | 144 +++++---- .../reference_docs/frame_pallet_coupling.rs | 296 ++++++++++++++++++ docs/sdk/src/reference_docs/mod.rs | 4 + substrate/frame/support/src/lib.rs | 5 +- 6 files changed, 374 insertions(+), 77 deletions(-) create mode 100644 docs/sdk/src/reference_docs/frame_pallet_coupling.rs diff --git a/Cargo.lock b/Cargo.lock index 4815e976b5d..e38f09db4d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13332,6 +13332,7 @@ dependencies = [ "frame-support", "frame-system", "kitchensink-runtime", + "pallet-assets", "pallet-aura", "pallet-authorship", "pallet-balances", diff --git a/docs/sdk/Cargo.toml b/docs/sdk/Cargo.toml index 735b3d7df61..8b498d407c0 100644 --- a/docs/sdk/Cargo.toml +++ b/docs/sdk/Cargo.toml @@ -65,6 +65,7 @@ pallet-aura = { path = "../../substrate/frame/aura", default-features = false } # Pallets and FRAME internals pallet-timestamp = { path = "../../substrate/frame/timestamp" } pallet-balances = { path = "../../substrate/frame/balances" } +pallet-assets = { path = "../../substrate/frame/assets" } pallet-transaction-payment = { path = "../../substrate/frame/transaction-payment" } pallet-utility = { path = "../../substrate/frame/utility" } pallet-multisig = { path = "../../substrate/frame/multisig" } diff --git a/docs/sdk/src/polkadot_sdk/frame_runtime.rs b/docs/sdk/src/polkadot_sdk/frame_runtime.rs index c9eba7d64bd..f178fc82bf4 100644 --- a/docs/sdk/src/polkadot_sdk/frame_runtime.rs +++ b/docs/sdk/src/polkadot_sdk/frame_runtime.rs @@ -87,93 +87,89 @@ //! * writing a runtime in pure Rust, as done in [this template](https://github.com/JoshOrndorff/frameless-node-template). //! * writing a runtime in AssemblyScript,as explored in [this project](https://github.com/LimeChain/subsembly). -#[cfg(test)] -mod tests { - use frame::prelude::*; +use frame::prelude::*; - /// A FRAME based pallet. This `mod` is the entry point for everything else. All - /// `#[pallet::xxx]` macros must be defined in this `mod`. Although, frame also provides an - /// experimental feature to break these parts into different `mod`s. See [`pallet_examples`] for - /// more. - #[docify::export] - #[frame::pallet(dev_mode)] - pub mod pallet { - use super::*; +/// A FRAME based pallet. This `mod` is the entry point for everything else. All +/// `#[pallet::xxx]` macros must be defined in this `mod`. Although, frame also provides an +/// experimental feature to break these parts into different `mod`s. See [`pallet_examples`] for +/// more. +#[docify::export] +#[frame::pallet(dev_mode)] +pub mod pallet { + use super::*; - /// The configuration trait of a pallet. Mandatory. Allows a pallet to receive types at a - /// later point from the runtime that wishes to contain it. It allows the pallet to be - /// parameterized over both types and values. - #[pallet::config] - pub trait Config: frame_system::Config { - /// A type that is not known now, but the runtime that will contain this pallet will - /// know it later, therefore we define it here as an associated type. - type RuntimeEvent: IsType<::RuntimeEvent> - + From>; + /// The configuration trait of a pallet. Mandatory. Allows a pallet to receive types at a + /// later point from the runtime that wishes to contain it. It allows the pallet to be + /// parameterized over both types and values. + #[pallet::config] + pub trait Config: frame_system::Config { + /// A type that is not known now, but the runtime that will contain this pallet will + /// know it later, therefore we define it here as an associated type. + type RuntimeEvent: IsType<::RuntimeEvent> + From>; - /// A parameterize-able value that we receive later via the `Get<_>` trait. - type ValueParameter: Get; + /// A parameterize-able value that we receive later via the `Get<_>` trait. + type ValueParameter: Get; - /// Similar to [`Config::ValueParameter`], but using `const`. Both are functionally - /// equal, but offer different tradeoffs. - const ANOTHER_VALUE_PARAMETER: u32; - } + /// Similar to [`Config::ValueParameter`], but using `const`. Both are functionally + /// equal, but offer different tradeoffs. + const ANOTHER_VALUE_PARAMETER: u32; + } - /// A mandatory struct in each pallet. All functions callable by external users (aka. - /// transactions) must be attached to this type (see [`frame::pallet_macros::call`]). For - /// convenience, internal (private) functions can also be attached to this type. - #[pallet::pallet] - pub struct Pallet(PhantomData); + /// A mandatory struct in each pallet. All functions callable by external users (aka. + /// transactions) must be attached to this type (see [`frame::pallet_macros::call`]). For + /// convenience, internal (private) functions can also be attached to this type. + #[pallet::pallet] + pub struct Pallet(PhantomData); - /// The events tha this pallet can emit. - #[pallet::event] - pub enum Event {} + /// The events tha this pallet can emit. + #[pallet::event] + pub enum Event {} - /// A storage item that this pallet contains. This will be part of the state root trie/root - /// of the blockchain. - #[pallet::storage] - pub type Value = StorageValue; + /// A storage item that this pallet contains. This will be part of the state root trie/root + /// of the blockchain. + #[pallet::storage] + pub type Value = StorageValue; - /// All *dispatchable* call functions (aka. transactions) are attached to `Pallet` in a - /// `impl` block. - #[pallet::call] - impl Pallet { - /// This will be callable by external users, and has two u32s as a parameter. - pub fn some_dispatchable( - _origin: OriginFor, - _param: u32, - _other_para: u32, - ) -> DispatchResult { - Ok(()) - } + /// All *dispatchable* call functions (aka. transactions) are attached to `Pallet` in a + /// `impl` block. + #[pallet::call] + impl Pallet { + /// This will be callable by external users, and has two u32s as a parameter. + pub fn some_dispatchable( + _origin: OriginFor, + _param: u32, + _other_para: u32, + ) -> DispatchResult { + Ok(()) } } +} - /// A simple runtime that contains the above pallet and `frame_system`, the mandatory pallet of - /// all runtimes. This runtime is for testing, but it shares a lot of similarities with a *real* - /// runtime. - #[docify::export] - pub mod runtime { - use super::pallet as pallet_example; - use frame::{prelude::*, testing_prelude::*}; - - // The major macro that amalgamates pallets into `enum Runtime` - construct_runtime!( - pub enum Runtime { - System: frame_system, - Example: pallet_example, - } - ); +/// A simple runtime that contains the above pallet and `frame_system`, the mandatory pallet of +/// all runtimes. This runtime is for testing, but it shares a lot of similarities with a *real* +/// runtime. +#[docify::export] +pub mod runtime { + use super::pallet as pallet_example; + use frame::{prelude::*, testing_prelude::*}; - // These `impl` blocks specify the parameters of each pallet's `trait Config`. - #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] - impl frame_system::Config for Runtime { - type Block = MockBlock; + // The major macro that amalgamates pallets into `enum Runtime` + construct_runtime!( + pub enum Runtime { + System: frame_system, + Example: pallet_example, } + ); - impl pallet_example::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type ValueParameter = ConstU32<42>; - const ANOTHER_VALUE_PARAMETER: u32 = 42; - } + // These `impl` blocks specify the parameters of each pallet's `trait Config`. + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + impl frame_system::Config for Runtime { + type Block = MockBlock; + } + + impl pallet_example::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type ValueParameter = ConstU32<42>; + const ANOTHER_VALUE_PARAMETER: u32 = 42; } } diff --git a/docs/sdk/src/reference_docs/frame_pallet_coupling.rs b/docs/sdk/src/reference_docs/frame_pallet_coupling.rs new file mode 100644 index 00000000000..942717ecfb2 --- /dev/null +++ b/docs/sdk/src/reference_docs/frame_pallet_coupling.rs @@ -0,0 +1,296 @@ +//! # FRAME Pallet Coupling +//! +//! This reference document explains how FRAME pallets can be combined to interact together. +//! +//! It is suggested to re-read [`crate::polkadot_sdk::frame_runtime`], notably the information +//! around [`frame::pallet_macros::config`]. Recall that: +//! +//! > Configuration trait of a pallet: It allows a pallet to receive types at a later +//! > point from the runtime that wishes to contain it. It allows the pallet to be parameterized +//! > over both types and values. +//! +//! ## Context, Background +//! +//! FRAME pallets, as per described in [`crate::polkadot_sdk::frame_runtime`] are: +//! +//! > A pallet is a unit of encapsulated logic. It has a clearly defined responsibility and can be +//! linked to other pallets. +//! +//! That is to say: +//! +//! * *encapsulated*: Ideally, a FRAME pallet contains encapsulated logic which has clear +//! boundaries. It is generally a bad idea to build a single monolithic pallet that does multiple +//! things, such as handling currencies, identities and staking all at the same time. +//! * *linked to other pallets*: But, adhering extensively to the above also hinders the ability to +//! write useful applications. Pallets often need to work with each other, communicate and use +//! each other's functionalities. +//! +//! The broad principle that allows pallets to be linked together is the same way through which a +//! pallet uses its `Config` trait to receive types and values from the runtime that contains it. +//! +//! There are generally two ways to achieve this: +//! +//! 1. Tight coupling pallets +//! 2. Loose coupling pallets +//! +//! To explain the difference between the two, consider two pallets, `A` and `B`. In both cases, `A` +//! wants to use some functionality exposed by `B`. +//! +//! When tightly coupling pallets, `A` can only exist in a runtime if `B` is also present in the +//! same runtime. That is, `A` is expressing that can only work if `B` is present. +//! +//! This translates to the following Rust code: +//! +//! ``` +//! trait Pallet_B_Config {} +//! trait Pallet_A_Config: Pallet_B_Config {} +//! ``` +//! +//! Contrary, when pallets are loosely coupled, `A` expresses that some functionality, expressed via +//! a trait `F`, needs to be fulfilled. This trait is then implemented by `B`, and the two pallets +//! are linked together at the runtime level. This means that `A` only relies on the implementation +//! of `F`, which may be `B`, or another implementation of `F`. +//! +//! This translates to the following Rust code: +//! +//! ``` +//! trait F {} +//! trait Pallet_A_Config { +//! type F: F; +//! } +//! // Pallet_B will implement and fulfill `F`. +//! ``` +//! +//! ## Example +//! +//! Consider the following example, in which `pallet-foo` needs another pallet to provide the block +//! author to it, and `pallet-author` which has access to this information. +#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", pallet_foo)] +#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", pallet_author)] +//! +//! ### Tight Coupling Pallets +//! +//! To tightly couple `pallet-foo` and `pallet-author`, we use Rust's supertrait system. When a +//! pallet makes its own `trait Config` be bounded by another pallet's `trait Config`, it is +//! expressing two things: +//! +//! 1. that it can only exist in a runtime if the other pallet is also present. +//! 2. that it can use the other pallet's functionality. +//! +//! `pallet-foo`'s `Config` would then look like: +#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", tight_config)] +//! +//! And `pallet-foo` can use the method exposed by `pallet_author::Pallet` directly: +#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", tight_usage)] +//! +//! +//! ### Loosely Coupling Pallets +//! +//! If `pallet-foo` wants to *not* rely on `pallet-author` directly, it can leverage its +//! `Config`'s associated types. First, we need a trait to express the functionality that +//! `pallet-foo` wants to obtain: +#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", AuthorProvider)] +//! +//! > We sometimes refer to such traits that help two pallets interact as "glue traits". +//! +//! Next, `pallet-foo` states that it needs this trait to be provided to it, at the runtime level, +//! via an associated type: +#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", loose_config)] +//! +//! Then, `pallet-foo` can use this trait to obtain the block author, without knowing where it comes +//! from: +#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", loose_usage)] +//! +//! Then, if `pallet-author` implements this glue-trait: +#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", pallet_author_provider)] +//! +//! And upon the creation of the runtime, the two pallets are linked together as such: +#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", runtime_author_provider)] +//! +//! Crucially, when using loose coupling, we gain the flexibility of providing different +//! implementations of `AuthorProvider`, such that different users of a `pallet-foo` can use +//! different ones, without any code change being needed. For example, in the code snippets of this +//! module, you can fund [`OtherAuthorProvider`] which is an alternative implementation of +//! [`AuthorProvider`]. +#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", other_author_provider)] +//! +//! A common pattern in polkadot-sdk is to provide an implementation of such glu traits for the unit +//! type as a "default/test behavior". +#![doc = docify::embed!("./src/reference_docs/frame_pallet_coupling.rs", unit_author_provider)] +//! +//! ## Frame System +//! +//! With the above information in context, we can conclude that **`frame_system` is a special pallet +//! that is tightly coupled with every other pallet**. This is because it provides the fundamental +//! system functionality that every pallet needs, such as some types like +//! [`frame::prelude::frame_system::Config::AccountId`], +//! [`frame::prelude::frame_system::Config::Hash`], and some functionality such as block number, +//! etc. +//! +//! ## Recap +//! +//! To recap, consider the following rules of thumb: +//! +//! * In all cases, try and break down big pallets apart with clear boundaries of responsibility. In +//! general, it is easier to argue about multiple pallet if they only communicate together via a +//! known trait, rather than having access to all of each others public items, such as storage and +//! dispatchables. +//! * If a group of pallets are meant to work together, and but are not foreseen to be generalized, +//! or used by others, consider tightly coupling pallets, *if it simplifies the development*. +//! * If a pallet needs a functionality provided by another pallet, but multiple implementations can +//! be foreseen, consider loosely coupling pallets. +//! +//! For example, all pallets in `polkadot-sdk` that needed to work with currencies could have been +//! tightly coupled with [`pallet_balances`]. But, `polkadot-sdk` also provides [`pallet_assets`] +//! (and more implementations by the community), therefore all pallets use traits to loosely couple +//! with balances or assets pallet. More on this in [`crate::reference_docs::frame_currency`]. +//! +//! ## Further References +//! +//! - +//! - +//! +//! [`AuthorProvider`]: crate::reference_docs::frame_pallet_coupling::AuthorProvider +//! [`OtherAuthorProvider`]: crate::reference_docs::frame_pallet_coupling::OtherAuthorProvider + +#![allow(unused)] + +use frame::prelude::*; + +#[docify::export] +#[frame::pallet] +pub mod pallet_foo { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(_); + + impl Pallet { + fn do_stuff_with_author() { + // needs block author here + } + } +} + +#[docify::export] +#[frame::pallet] +pub mod pallet_author { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(_); + + impl Pallet { + pub fn author() -> T::AccountId { + todo!("somehow has access to the block author and can return it here") + } + } +} + +#[frame::pallet] +pub mod pallet_foo_tight { + use super::*; + + #[pallet::pallet] + pub struct Pallet(_); + + #[docify::export(tight_config)] + /// This pallet can only live in a runtime that has both `frame_system` and `pallet_author`. + #[pallet::config] + pub trait Config: frame_system::Config + pallet_author::Config {} + + #[docify::export(tight_usage)] + impl Pallet { + // anywhere in `pallet-foo`, we can call into `pallet-author` directly, namely because + // `T: pallet_author::Config` + fn do_stuff_with_author() { + let _ = pallet_author::Pallet::::author(); + } + } +} + +#[docify::export] +/// Abstraction over "something that can provide the block author". +pub trait AuthorProvider { + fn author() -> AccountId; +} + +#[frame::pallet] +pub mod pallet_foo_loose { + use super::*; + + #[pallet::pallet] + pub struct Pallet(_); + + #[docify::export(loose_config)] + #[pallet::config] + pub trait Config: frame_system::Config { + /// This pallet relies on the existence of something that implements [`AuthorProvider`], + /// which may or may not be `pallet-author`. + type AuthorProvider: AuthorProvider; + } + + #[docify::export(loose_usage)] + impl Pallet { + fn do_stuff_with_author() { + let _ = T::AuthorProvider::author(); + } + } +} + +#[docify::export(pallet_author_provider)] +impl AuthorProvider for pallet_author::Pallet { + fn author() -> T::AccountId { + pallet_author::Pallet::::author() + } +} + +pub struct OtherAuthorProvider; + +#[docify::export(other_author_provider)] +impl AuthorProvider for OtherAuthorProvider { + fn author() -> AccountId { + todo!("somehow get the block author here") + } +} + +#[docify::export(unit_author_provider)] +impl AuthorProvider for () { + fn author() -> AccountId { + todo!("somehow get the block author here") + } +} + +pub mod runtime { + use super::*; + use cumulus_pallet_aura_ext::pallet; + use frame::{runtime::prelude::*, testing_prelude::*}; + + construct_runtime!( + pub struct Runtime { + System: frame_system, + PalletFoo: pallet_foo_loose, + PalletAuthor: pallet_author, + } + ); + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + impl frame_system::Config for Runtime { + type Block = MockBlock; + } + + impl pallet_author::Config for Runtime {} + + #[docify::export(runtime_author_provider)] + impl pallet_foo_loose::Config for Runtime { + type AuthorProvider = pallet_author::Pallet; + // which is also equivalent to + // type AuthorProvider = PalletAuthor; + } +} diff --git a/docs/sdk/src/reference_docs/mod.rs b/docs/sdk/src/reference_docs/mod.rs index 3fd815d2a15..f4b52208e2f 100644 --- a/docs/sdk/src/reference_docs/mod.rs +++ b/docs/sdk/src/reference_docs/mod.rs @@ -103,3 +103,7 @@ pub mod light_nodes; /// Learn about the offchain workers, how they function, and how to use them, as provided by the /// [`frame`] APIs. pub mod frame_offchain_workers; + +/// Learn about the different ways through which multiple [`frame`] pallets can be combined to work +/// together. +pub mod frame_pallet_coupling; diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs index b5b1ac09c60..6ea7fa33e77 100644 --- a/substrate/frame/support/src/lib.rs +++ b/substrate/frame/support/src/lib.rs @@ -1531,9 +1531,8 @@ pub mod pallet_macros { /// The attribute currently only supports enum definitions, and identifiers that are named /// `FreezeReason`, `HoldReason`, `LockId` or `SlashReason`. Arbitrary identifiers for the /// enum are not supported. The aggregate enum generated by - /// [`frame_support::construct_runtime`](frame_support::construct_runtime) will have the - /// name of `RuntimeFreezeReason`, `RuntimeHoldReason`, `RuntimeLockId` and - /// `RuntimeSlashReason` respectively. + /// [`frame_support::construct_runtime`] will have the name of `RuntimeFreezeReason`, + /// `RuntimeHoldReason`, `RuntimeLockId` and `RuntimeSlashReason` respectively. /// /// NOTE: The aggregate enum generated by `construct_runtime` generates a conversion /// function from the pallet enum to the aggregate enum, and automatically derives the -- GitLab From c89b3997df47408a324e8870693e80ddc4a42b7d Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Thu, 7 Mar 2024 12:47:30 +0100 Subject: [PATCH 363/392] Contracts: Remove changelog (#3605) This is not maintained, and we should be able to get information from the release changelog --- substrate/frame/contracts/CHANGELOG.md | 116 ------------------------- 1 file changed, 116 deletions(-) delete mode 100644 substrate/frame/contracts/CHANGELOG.md diff --git a/substrate/frame/contracts/CHANGELOG.md b/substrate/frame/contracts/CHANGELOG.md deleted file mode 100644 index aca94e5b149..00000000000 --- a/substrate/frame/contracts/CHANGELOG.md +++ /dev/null @@ -1,116 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -The semantic versioning guarantees cover the interface to the Substrate runtime which -includes this pallet as a dependency. This module will also add storage migrations whenever -changes require it. Stability with regard to offchain tooling is explicitly excluded from -this guarantee: For example adding a new field to an in-storage data structure will require -changes to frontends to properly display it. However, those changes will still be regarded -as a minor version bump. - -The interface provided to smart contracts will adhere to semver with one exception: Even -major version bumps will be backwards compatible with regard to already deployed contracts. -In other words: Upgrading this pallet will not break pre-existing contracts. - -## [Unreleased] - -### Added - -- Forbid calling back to contracts after switching to runtime -[#13443](https://github.com/paritytech/substrate/pull/13443) - -- Allow contracts to dispatch calls into the runtime (**unstable**) -[#9276](https://github.com/paritytech/substrate/pull/9276) - -- New version of `seal_call` that offers more features. -[#8909](https://github.com/paritytech/substrate/pull/8909) - -- New `instantiate` RPC that allows clients to dry-run contract instantiation. -[#8451](https://github.com/paritytech/substrate/pull/8451) - -- New version of `seal_random` which exposes additional information. -[#8329](https://github.com/paritytech/substrate/pull/8329) - -### Changed - -- Replaced storage rent with automatic storage deposits -[#9669](https://github.com/paritytech/substrate/pull/9669) -[#10082](https://github.com/paritytech/substrate/pull/10082) - -- Replaced `seal_println` with the `seal_debug_message` API which allows outputting debug -messages to the console and RPC clients. -[#8773](https://github.com/paritytech/substrate/pull/8773) -[#9550](https://github.com/paritytech/substrate/pull/9550) - -- Make storage and fields of `Schedule` private to the crate. -[#8359](https://github.com/paritytech/substrate/pull/8359) - -### Fixed - -- Remove pre-charging which caused wrongly estimated weights -[#8976](https://github.com/paritytech/substrate/pull/8976) - -## [v3.0.0] 2021-02-25 - -This version constitutes the first release that brings any stability guarantees (see above). - -### Added - -- Emit an event when a contract terminates (self-destructs). -[#8014](https://github.com/paritytech/substrate/pull/8014) - -- Charge rent for code stored on the chain in addition to the already existing -rent that is paid for data storage. -[#7935](https://github.com/paritytech/substrate/pull/7935) - -- Allow the runtime to configure per storage item costs in addition -to the already existing per byte costs. -[#7819](https://github.com/paritytech/substrate/pull/7819) - -- Contracts are now deleted lazily so that the user who removes a contract -does not need to pay for the deletion of the contract storage. -[#7740](https://github.com/paritytech/substrate/pull/7740) - -- Allow runtime authors to define chain extensions in order to provide custom -functionality to contracts. -[#7548](https://github.com/paritytech/substrate/pull/7548) -[#8003](https://github.com/paritytech/substrate/pull/8003) - -- Proper weights which are fully automated by benchmarking. -[#6715](https://github.com/paritytech/substrate/pull/6715) -[#7017](https://github.com/paritytech/substrate/pull/7017) -[#7361](https://github.com/paritytech/substrate/pull/7361) - -### Changed - -- Collect the rent for one block during instantiation. -[#7847](https://github.com/paritytech/substrate/pull/7847) - -- Instantiation takes a `salt` argument to allow for easier instantion of the -same code by the same sender. -[#7482](https://github.com/paritytech/substrate/pull/7482) - -- Improve the information returned by the `contracts_call` RPC. -[#7468](https://github.com/paritytech/substrate/pull/7468) - -- Simplify the node configuration necessary to add this module. -[#7409](https://github.com/paritytech/substrate/pull/7409) - -### Fixed - -- Consider the code size of a contract in the weight that is charged for -loading a contract from storage. -[#8086](https://github.com/paritytech/substrate/pull/8086) - -- Fix possible overflow in storage size calculation -[#7885](https://github.com/paritytech/substrate/pull/7885) - -- Cap the surcharge reward that can be claimed. -[#7870](https://github.com/paritytech/substrate/pull/7870) - -- Fix a possible DoS vector where contracts could allocate too large buffers. -[#7818](https://github.com/paritytech/substrate/pull/7818) -- GitLab From 6792d4b5b84e80ab771aa32666ce08dbcca39b97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Thu, 7 Mar 2024 20:10:12 +0800 Subject: [PATCH 364/392] Disable flaky test (#3602) Unfortunately, the flakiness wasn't fixed by https://github.com/paritytech/polkadot-sdk/pull/3595. Let's disable the test in the meanwhile since it is hanging on the CI a lot. --------- Co-authored-by: Liam Aharon --- substrate/client/consensus/manual-seal/src/lib.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/substrate/client/consensus/manual-seal/src/lib.rs b/substrate/client/consensus/manual-seal/src/lib.rs index f04c0d42d60..c3d360f0719 100644 --- a/substrate/client/consensus/manual-seal/src/lib.rs +++ b/substrate/client/consensus/manual-seal/src/lib.rs @@ -467,7 +467,10 @@ mod tests { assert_eq!(client.header(created_block.hash).unwrap().unwrap().number, 1) } - #[tokio::test] + // TODO: enable once the flakiness is fixed + // See https://github.com/paritytech/polkadot-sdk/issues/3603 + //#[tokio::test] + #[allow(unused)] async fn instant_seal_delayed_finalize() { let builder = TestClientBuilder::new(); let (client, select_chain) = builder.build_with_longest_chain(); -- GitLab From de9411aa4c29a28cb2c964cce8153bdaa1bdc7ea Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Thu, 7 Mar 2024 13:39:39 +0100 Subject: [PATCH 365/392] Contracts: Remove unstable on lock/unlock_delegate_dependency host fns (#3606) Oversight from PR https://github.com/paritytech/polkadot-sdk/pull/3384. These 2 functions should have been tagged as stable --- prdoc/pr_3606.prdoc | 9 +++++++++ substrate/frame/contracts/src/wasm/runtime.rs | 2 -- 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 prdoc/pr_3606.prdoc diff --git a/prdoc/pr_3606.prdoc b/prdoc/pr_3606.prdoc new file mode 100644 index 00000000000..18b71de9477 --- /dev/null +++ b/prdoc/pr_3606.prdoc @@ -0,0 +1,9 @@ +title: "[pallet_contracts] mark lock/unlock_delegate_dependency as stable" + +doc: + - audience: Runtime Dev + description: | + Lock and unlock delegate dependency are stable now, so we can mark them as such. + +crates: + - name: pallet-contracts diff --git a/substrate/frame/contracts/src/wasm/runtime.rs b/substrate/frame/contracts/src/wasm/runtime.rs index f440c818166..402ff78dcde 100644 --- a/substrate/frame/contracts/src/wasm/runtime.rs +++ b/substrate/frame/contracts/src/wasm/runtime.rs @@ -2305,7 +2305,6 @@ pub mod env { /// Adds a new delegate dependency to the contract. /// See [`pallet_contracts_uapi::HostFn::lock_delegate_dependency`]. - #[unstable] fn lock_delegate_dependency(ctx: _, memory: _, code_hash_ptr: u32) -> Result<(), TrapReason> { ctx.charge_gas(RuntimeCosts::LockDelegateDependency)?; let code_hash = ctx.read_sandbox_memory_as(memory, code_hash_ptr)?; @@ -2315,7 +2314,6 @@ pub mod env { /// Removes the delegate dependency from the contract. /// see [`pallet_contracts_uapi::HostFn::unlock_delegate_dependency`]. - #[unstable] fn unlock_delegate_dependency(ctx: _, memory: _, code_hash_ptr: u32) -> Result<(), TrapReason> { ctx.charge_gas(RuntimeCosts::UnlockDelegateDependency)?; let code_hash = ctx.read_sandbox_memory_as(memory, code_hash_ptr)?; -- GitLab From 629506ce061db76d31d4f7a81f4a497752b27259 Mon Sep 17 00:00:00 2001 From: Muharem Date: Thu, 7 Mar 2024 16:13:17 +0100 Subject: [PATCH 366/392] Deprecate xcm::body::TREASURER_INDEX constant, use standard Treasury varian instead (#3608) Deprecate the `xcm::body::TREASURER_INDEX` constant and use the standard Treasury variant from the `xcm::BodyId` type instead. To align with the production runtimes: https://github.com/polkadot-fellows/runtimes/pull/149 --- .../collectives/collectives-westend/src/xcm_config.rs | 2 +- polkadot/runtime/westend/constants/src/lib.rs | 2 ++ polkadot/runtime/westend/src/xcm_config.rs | 6 ++---- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs index cc25cbda0a4..87f637d5b59 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs @@ -59,7 +59,7 @@ parameter_types! { pub const GovernanceLocation: Location = Location::parent(); pub const FellowshipAdminBodyId: BodyId = BodyId::Index(xcm_constants::body::FELLOWSHIP_ADMIN_INDEX); pub AssetHub: Location = (Parent, Parachain(1000)).into(); - pub const TreasurerBodyId: BodyId = BodyId::Index(xcm_constants::body::TREASURER_INDEX); + pub const TreasurerBodyId: BodyId = BodyId::Treasury; pub AssetHubUsdtId: AssetId = (PalletInstance(50), GeneralIndex(1984)).into(); pub UsdtAssetHub: LocatableAssetId = LocatableAssetId { location: AssetHub::get(), diff --git a/polkadot/runtime/westend/constants/src/lib.rs b/polkadot/runtime/westend/constants/src/lib.rs index 3bc27177d7a..c98f4b114fd 100644 --- a/polkadot/runtime/westend/constants/src/lib.rs +++ b/polkadot/runtime/westend/constants/src/lib.rs @@ -130,6 +130,8 @@ pub mod xcm { const ROOT_INDEX: u32 = 0; // The bodies corresponding to the Polkadot OpenGov Origins. pub const FELLOWSHIP_ADMIN_INDEX: u32 = 1; + #[deprecated = "Will be removed after August 2024; Use `xcm::latest::BodyId::Treasury` \ + instead"] pub const TREASURER_INDEX: u32 = 2; } } diff --git a/polkadot/runtime/westend/src/xcm_config.rs b/polkadot/runtime/westend/src/xcm_config.rs index c3aa75a86a4..c57af987ca7 100644 --- a/polkadot/runtime/westend/src/xcm_config.rs +++ b/polkadot/runtime/westend/src/xcm_config.rs @@ -34,9 +34,7 @@ use runtime_common::{ }; use sp_core::ConstU32; use westend_runtime_constants::{ - currency::CENTS, - system_parachain::*, - xcm::body::{FELLOWSHIP_ADMIN_INDEX, TREASURER_INDEX}, + currency::CENTS, system_parachain::*, xcm::body::FELLOWSHIP_ADMIN_INDEX, }; use xcm::latest::prelude::*; use xcm_builder::{ @@ -231,7 +229,7 @@ parameter_types! { // FellowshipAdmin pluralistic body. pub const FellowshipAdminBodyId: BodyId = BodyId::Index(FELLOWSHIP_ADMIN_INDEX); // `Treasurer` pluralistic body. - pub const TreasurerBodyId: BodyId = BodyId::Index(TREASURER_INDEX); + pub const TreasurerBodyId: BodyId = BodyId::Treasury; } /// Type to convert the `GeneralAdmin` origin to a Plurality `Location` value. -- GitLab From f4fbddec420384e3550703ea7c9db3ea923f66e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Andr=C3=A9s=20Dorado=20Su=C3=A1rez?= Date: Thu, 7 Mar 2024 18:19:52 -0500 Subject: [PATCH 367/392] fix(pallet-benchmarking): split test functions in v2 (#3574) Closes #376 --------- Co-authored-by: command-bot <> --- .../collator-selection/src/benchmarking.rs | 4 +- .../collective-content/src/benchmarking.rs | 2 +- .../runtime/common/src/identity_migrator.rs | 2 +- .../parachains/src/hrmp/benchmarking.rs | 2 +- prdoc/pr_3574.prdoc | 23 +++++++++++ substrate/frame/alliance/src/benchmarking.rs | 2 +- substrate/frame/identity/src/benchmarking.rs | 4 +- substrate/frame/lottery/src/benchmarking.rs | 1 - .../frame/support/procedural/src/benchmark.rs | 38 ++++++++++++++++++- .../system/benchmarking/src/extensions.rs | 2 +- .../frame/system/benchmarking/src/lib.rs | 2 +- 11 files changed, 67 insertions(+), 15 deletions(-) create mode 100644 prdoc/pr_3574.prdoc diff --git a/cumulus/pallets/collator-selection/src/benchmarking.rs b/cumulus/pallets/collator-selection/src/benchmarking.rs index 2c40f4dd0ea..e2af74a6e60 100644 --- a/cumulus/pallets/collator-selection/src/benchmarking.rs +++ b/cumulus/pallets/collator-selection/src/benchmarking.rs @@ -22,9 +22,7 @@ use super::*; #[allow(unused)] use crate::Pallet as CollatorSelection; use codec::Decode; -use frame_benchmarking::{ - account, impl_benchmark_test_suite, v2::*, whitelisted_caller, BenchmarkError, -}; +use frame_benchmarking::{account, v2::*, whitelisted_caller, BenchmarkError}; use frame_support::traits::{Currency, EnsureOrigin, Get, ReservableCurrency}; use frame_system::{pallet_prelude::BlockNumberFor, EventRecord, RawOrigin}; use pallet_authorship::EventHandler; diff --git a/cumulus/parachains/pallets/collective-content/src/benchmarking.rs b/cumulus/parachains/pallets/collective-content/src/benchmarking.rs index 943386a8427..3d6bf073778 100644 --- a/cumulus/parachains/pallets/collective-content/src/benchmarking.rs +++ b/cumulus/parachains/pallets/collective-content/src/benchmarking.rs @@ -16,7 +16,7 @@ //! The pallet benchmarks. use super::{Pallet as CollectiveContent, *}; -use frame_benchmarking::{impl_benchmark_test_suite, v2::*}; +use frame_benchmarking::v2::*; use frame_support::traits::EnsureOrigin; fn assert_last_event, I: 'static>(generic_event: >::RuntimeEvent) { diff --git a/polkadot/runtime/common/src/identity_migrator.rs b/polkadot/runtime/common/src/identity_migrator.rs index 0dfb03b06ba..bf334a63e95 100644 --- a/polkadot/runtime/common/src/identity_migrator.rs +++ b/polkadot/runtime/common/src/identity_migrator.rs @@ -31,7 +31,7 @@ use pallet_identity; use sp_core::Get; #[cfg(feature = "runtime-benchmarks")] -use frame_benchmarking::{account, impl_benchmark_test_suite, v2::*, BenchmarkError}; +use frame_benchmarking::{account, v2::*, BenchmarkError}; pub trait WeightInfo { fn reap_identity(r: u32, s: u32) -> Weight; diff --git a/polkadot/runtime/parachains/src/hrmp/benchmarking.rs b/polkadot/runtime/parachains/src/hrmp/benchmarking.rs index 2cb49c88d43..c6baf2f30cf 100644 --- a/polkadot/runtime/parachains/src/hrmp/benchmarking.rs +++ b/polkadot/runtime/parachains/src/hrmp/benchmarking.rs @@ -22,7 +22,7 @@ use crate::{ paras::{Pallet as Paras, ParaKind, ParachainsCache}, shared::Pallet as Shared, }; -use frame_benchmarking::{impl_benchmark_test_suite, v2::*, whitelisted_caller}; +use frame_benchmarking::{v2::*, whitelisted_caller}; use frame_support::{assert_ok, traits::Currency}; type BalanceOf = diff --git a/prdoc/pr_3574.prdoc b/prdoc/pr_3574.prdoc new file mode 100644 index 00000000000..99868ea8a13 --- /dev/null +++ b/prdoc/pr_3574.prdoc @@ -0,0 +1,23 @@ +title: Generate test functions for each benchmark with benchmarking v2 + +doc: + - audience: Runtime Dev + description: | + This PR fixes an issue where using `impl_benchmark_test_suite` macro + within modules that use the benchmarking v2 macros (`#[benchmarks]` + and `#[instance_benchmarks]`) always produced a single test called + `test_benchmarks` instead of a separate benchmark test for every + benchmark (noted with the `#[benchmark]` macro). + + By using this macro from now on, new tests will be created named + `test_benchmark_{name}` where `name` is the name of the benchmark + function. Those tests will be nested inside the module intended for + benchmark functions. + + Also, when using `impl_benchmark_test_suite` inside the module, + the import of such marco will not be necessary, so any explicit + import of it will be marked as unused, the same way it works for + v1 macros so far. + +crates: + - name: frame-support-procedural diff --git a/substrate/frame/alliance/src/benchmarking.rs b/substrate/frame/alliance/src/benchmarking.rs index 9fe0e29b42c..4ccd0fc08f6 100644 --- a/substrate/frame/alliance/src/benchmarking.rs +++ b/substrate/frame/alliance/src/benchmarking.rs @@ -26,7 +26,7 @@ use core::{ }; use sp_runtime::traits::{Bounded, Hash, StaticLookup}; -use frame_benchmarking::{account, impl_benchmark_test_suite, v2::*, BenchmarkError}; +use frame_benchmarking::{account, v2::*, BenchmarkError}; use frame_support::traits::{EnsureOrigin, Get, UnfilteredDispatchable}; use frame_system::{pallet_prelude::BlockNumberFor, Pallet as System, RawOrigin as SystemOrigin}; diff --git a/substrate/frame/identity/src/benchmarking.rs b/substrate/frame/identity/src/benchmarking.rs index fe2fb0b0489..e0b45eeecd1 100644 --- a/substrate/frame/identity/src/benchmarking.rs +++ b/substrate/frame/identity/src/benchmarking.rs @@ -23,9 +23,7 @@ use super::*; use crate::Pallet as Identity; use codec::Encode; -use frame_benchmarking::{ - account, impl_benchmark_test_suite, v2::*, whitelisted_caller, BenchmarkError, -}; +use frame_benchmarking::{account, v2::*, whitelisted_caller, BenchmarkError}; use frame_support::{ assert_ok, ensure, traits::{EnsureOrigin, Get, OnFinalize, OnInitialize}, diff --git a/substrate/frame/lottery/src/benchmarking.rs b/substrate/frame/lottery/src/benchmarking.rs index 1510d250dbe..123b425b976 100644 --- a/substrate/frame/lottery/src/benchmarking.rs +++ b/substrate/frame/lottery/src/benchmarking.rs @@ -23,7 +23,6 @@ use super::*; use crate::Pallet as Lottery; use frame_benchmarking::{ - impl_benchmark_test_suite, v1::{account, whitelisted_caller, BenchmarkError}, v2::*, }; diff --git a/substrate/frame/support/procedural/src/benchmark.rs b/substrate/frame/support/procedural/src/benchmark.rs index 6ded82d91aa..d16ad2aaa51 100644 --- a/substrate/frame/support/procedural/src/benchmark.rs +++ b/substrate/frame/support/procedural/src/benchmark.rs @@ -431,7 +431,7 @@ pub fn benchmarks( let mut benchmarks_by_name_mappings: Vec = Vec::new(); let test_idents: Vec = benchmark_names_str .iter() - .map(|n| Ident::new(format!("test_{}", n).as_str(), Span::call_site())) + .map(|n| Ident::new(format!("test_benchmark_{}", n).as_str(), Span::call_site())) .collect(); for i in 0..benchmark_names.len() { let name_ident = &benchmark_names[i]; @@ -441,6 +441,37 @@ pub fn benchmarks( benchmarks_by_name_mappings.push(quote!(#name_str => Self::#test_ident())) } + let impl_test_function = content + .iter_mut() + .find_map(|item| { + let Item::Macro(item_macro) = item else { + return None; + }; + + if !item_macro + .mac + .path + .segments + .iter() + .any(|s| s.ident == "impl_benchmark_test_suite") + { + return None; + } + + let tokens = item_macro.mac.tokens.clone(); + *item = Item::Verbatim(quote! {}); + + Some(quote! { + impl_test_function!( + (#( {} #benchmark_names )*) + (#( #extra_benchmark_names )*) + (#( #skip_meta_benchmark_names )*) + #tokens + ); + }) + }) + .unwrap_or(quote! {}); + // emit final quoted tokens let res = quote! { #(#mod_attrs) @@ -676,6 +707,8 @@ pub fn benchmarks( } } } + + #impl_test_function } #mod_vis use #mod_name::*; }; @@ -733,7 +766,8 @@ fn expand_benchmark( let setup_stmts = benchmark_def.setup_stmts; let verify_stmts = benchmark_def.verify_stmts; let last_stmt = benchmark_def.last_stmt; - let test_ident = Ident::new(format!("test_{}", name.to_string()).as_str(), Span::call_site()); + let test_ident = + Ident::new(format!("test_benchmark_{}", name.to_string()).as_str(), Span::call_site()); // unroll params (prepare for quoting) let unrolled = UnrolledParams::from(&benchmark_def.params); diff --git a/substrate/frame/system/benchmarking/src/extensions.rs b/substrate/frame/system/benchmarking/src/extensions.rs index 1721501dead..bfc3b4343a6 100644 --- a/substrate/frame/system/benchmarking/src/extensions.rs +++ b/substrate/frame/system/benchmarking/src/extensions.rs @@ -19,7 +19,7 @@ #![cfg(feature = "runtime-benchmarks")] -use frame_benchmarking::{account, impl_benchmark_test_suite, v2::*, BenchmarkError}; +use frame_benchmarking::{account, v2::*, BenchmarkError}; use frame_support::{ dispatch::{DispatchClass, DispatchInfo, PostDispatchInfo}, weights::Weight, diff --git a/substrate/frame/system/benchmarking/src/lib.rs b/substrate/frame/system/benchmarking/src/lib.rs index ebd16275bcb..c9f0869d3bc 100644 --- a/substrate/frame/system/benchmarking/src/lib.rs +++ b/substrate/frame/system/benchmarking/src/lib.rs @@ -21,7 +21,7 @@ #![cfg(feature = "runtime-benchmarks")] use codec::Encode; -use frame_benchmarking::{impl_benchmark_test_suite, v2::*}; +use frame_benchmarking::v2::*; use frame_support::{dispatch::DispatchClass, storage, traits::Get}; use frame_system::{Call, Pallet as System, RawOrigin}; use sp_core::storage::well_known_keys; -- GitLab From 2aa006e094e248110af14a742d4e2f56b7931959 Mon Sep 17 00:00:00 2001 From: Sebastian Kunert Date: Fri, 8 Mar 2024 00:31:59 +0100 Subject: [PATCH 368/392] Refactor polkadot-parachain service for more code reuse (#3511) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a refactoring, no changes to the logic are included (if you find some, report :D). ## Change Overview In https://github.com/paritytech/polkadot-sdk/issues/2455, dependency on actual runtimes was removed for the system parachains. This means that the trait bounds we have on various `start_node_xy` do not check anything anymore, since they all point to the same runtime. Exception is asset-hub-polkadot which uses a different key type. This PR unifies the different nodes as much as possible. `start_node_impl` is doing the heavy lifting and has been made a bit more flexible to support the rpc extension instantiation that was there before. The generics for `Runtime` and `AuraId` have been removed where possible. The fake runtime is imported as `FakeRuntime` to make it very clear to readers that it is not the generic parameter. Multiple nodes where using the same import queue/start_consensus closure, they have been unified. --------- Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Francisco Aguirre Co-authored-by: Adrian Catangiu Co-authored-by: Egor_P Co-authored-by: Dmitry Markin Co-authored-by: Xiliang Chen Co-authored-by: Andrei Eres Co-authored-by: Alexander Samusev <41779041+alvicsam@users.noreply.github.com> Co-authored-by: Alin Dima Co-authored-by: gupnik Co-authored-by: Liam Aharon Co-authored-by: Dónal Murray --- cumulus/polkadot-parachain/src/command.rs | 84 +- cumulus/polkadot-parachain/src/service.rs | 2329 ++++++--------------- 2 files changed, 717 insertions(+), 1696 deletions(-) diff --git a/cumulus/polkadot-parachain/src/command.rs b/cumulus/polkadot-parachain/src/command.rs index 4d44879af51..9ba7b7876b3 100644 --- a/cumulus/polkadot-parachain/src/command.rs +++ b/cumulus/polkadot-parachain/src/command.rs @@ -399,7 +399,7 @@ macro_rules! construct_partials { Runtime::AssetHubPolkadot => { let $partials = new_partial::( &$config, - crate::service::aura_build_import_queue::<_, AssetHubPolkadotAuraId>, + crate::service::build_relay_to_aura_import_queue::<_, AssetHubPolkadotAuraId>, )?; $code }, @@ -413,28 +413,21 @@ macro_rules! construct_partials { Runtime::People(_) => { let $partials = new_partial::( &$config, - crate::service::aura_build_import_queue::<_, AuraId>, + crate::service::build_relay_to_aura_import_queue::<_, AuraId>, )?; $code }, Runtime::GluttonWestend | Runtime::Glutton | Runtime::Shell | Runtime::Seedling => { let $partials = new_partial::( &$config, - crate::service::shell_build_import_queue, + crate::service::build_shell_import_queue, )?; $code }, - Runtime::ContractsRococo => { + Runtime::ContractsRococo | Runtime::Penpal(_) | Runtime::Default => { let $partials = new_partial::( &$config, - crate::service::contracts_rococo_build_import_queue, - )?; - $code - }, - Runtime::Penpal(_) | Runtime::Default => { - let $partials = new_partial::( - &$config, - crate::service::rococo_parachain_build_import_queue, + crate::service::build_aura_import_queue, )?; $code }, @@ -450,7 +443,7 @@ macro_rules! construct_async_run { runner.async_run(|$config| { let $components = new_partial::( &$config, - crate::service::aura_build_import_queue::<_, AssetHubPolkadotAuraId>, + crate::service::build_relay_to_aura_import_queue::<_, AssetHubPolkadotAuraId>, )?; let task_manager = $components.task_manager; { $( $code )* }.map(|v| (v, task_manager)) @@ -467,7 +460,7 @@ macro_rules! construct_async_run { runner.async_run(|$config| { let $components = new_partial::( &$config, - crate::service::aura_build_import_queue::<_, AuraId>, + crate::service::build_relay_to_aura_import_queue::<_, AuraId>, )?; let task_manager = $components.task_manager; { $( $code )* }.map(|v| (v, task_manager)) @@ -480,30 +473,20 @@ macro_rules! construct_async_run { runner.async_run(|$config| { let $components = new_partial::( &$config, - crate::service::shell_build_import_queue, + crate::service::build_shell_import_queue, )?; let task_manager = $components.task_manager; { $( $code )* }.map(|v| (v, task_manager)) }) } - Runtime::ContractsRococo => { - runner.async_run(|$config| { - let $components = new_partial::( - &$config, - crate::service::contracts_rococo_build_import_queue, - )?; - let task_manager = $components.task_manager; - { $( $code )* }.map(|v| (v, task_manager)) - }) - }, - Runtime::Penpal(_) | Runtime::Default => { + Runtime::ContractsRococo | Runtime::Penpal(_) | Runtime::Default => { runner.async_run(|$config| { let $components = new_partial::< RuntimeApi, _, >( &$config, - crate::service::rococo_parachain_build_import_queue, + crate::service::build_aura_import_queue, )?; let task_manager = $components.task_manager; { $( $code )* }.map(|v| (v, task_manager)) @@ -715,25 +698,19 @@ pub fn run() -> Result<()> { .map_err(Into::into), CollectivesPolkadot => - crate::service::start_generic_aura_node::< - RuntimeApi, - AuraId, - >(config, polkadot_config, collator_options, id, hwbench) + crate::service::start_generic_aura_node(config, polkadot_config, collator_options, id, hwbench) .await .map(|r| r.0) .map_err(Into::into), CollectivesWestend => - crate::service::start_generic_aura_lookahead_node::< - RuntimeApi, - AuraId, - >(config, polkadot_config, collator_options, id, hwbench) + crate::service::start_generic_aura_lookahead_node(config, polkadot_config, collator_options, id, hwbench) .await .map(|r| r.0) .map_err(Into::into), Seedling | Shell => - crate::service::start_shell_node::( + crate::service::start_shell_node( config, polkadot_config, collator_options, @@ -758,36 +735,24 @@ pub fn run() -> Result<()> { BridgeHub(bridge_hub_runtime_type) => match bridge_hub_runtime_type { chain_spec::bridge_hubs::BridgeHubRuntimeType::Polkadot | chain_spec::bridge_hubs::BridgeHubRuntimeType::PolkadotLocal => - crate::service::start_generic_aura_node::< - RuntimeApi, - AuraId, - >(config, polkadot_config, collator_options, id, hwbench) + crate::service::start_generic_aura_node(config, polkadot_config, collator_options, id, hwbench) .await .map(|r| r.0), chain_spec::bridge_hubs::BridgeHubRuntimeType::Kusama | chain_spec::bridge_hubs::BridgeHubRuntimeType::KusamaLocal => - crate::service::start_generic_aura_node::< - RuntimeApi, - AuraId, - >(config, polkadot_config, collator_options, id, hwbench) + crate::service::start_generic_aura_node(config, polkadot_config, collator_options, id, hwbench) .await .map(|r| r.0), chain_spec::bridge_hubs::BridgeHubRuntimeType::Westend | chain_spec::bridge_hubs::BridgeHubRuntimeType::WestendLocal | chain_spec::bridge_hubs::BridgeHubRuntimeType::WestendDevelopment => - crate::service::start_generic_aura_lookahead_node::< - RuntimeApi, - AuraId, - >(config, polkadot_config, collator_options, id, hwbench) + crate::service::start_generic_aura_lookahead_node(config, polkadot_config, collator_options, id, hwbench) .await .map(|r| r.0), chain_spec::bridge_hubs::BridgeHubRuntimeType::Rococo | chain_spec::bridge_hubs::BridgeHubRuntimeType::RococoLocal | chain_spec::bridge_hubs::BridgeHubRuntimeType::RococoDevelopment => - crate::service::start_generic_aura_lookahead_node::< - RuntimeApi, - AuraId, - >(config, polkadot_config, collator_options, id, hwbench) + crate::service::start_generic_aura_lookahead_node(config, polkadot_config, collator_options, id, hwbench) .await .map(|r| r.0), } @@ -800,10 +765,7 @@ pub fn run() -> Result<()> { chain_spec::coretime::CoretimeRuntimeType::Westend | chain_spec::coretime::CoretimeRuntimeType::WestendLocal | chain_spec::coretime::CoretimeRuntimeType::WestendDevelopment => - crate::service::start_generic_aura_lookahead_node::< - RuntimeApi, - AuraId, - >(config, polkadot_config, collator_options, id, hwbench) + crate::service::start_generic_aura_lookahead_node(config, polkadot_config, collator_options, id, hwbench) .await .map(|r| r.0), } @@ -822,10 +784,7 @@ pub fn run() -> Result<()> { .map_err(Into::into), Glutton | GluttonWestend => - crate::service::start_basic_lookahead_node::< - RuntimeApi, - AuraId, - >(config, polkadot_config, collator_options, id, hwbench) + crate::service::start_basic_lookahead_node(config, polkadot_config, collator_options, id, hwbench) .await .map(|r| r.0) .map_err(Into::into), @@ -837,10 +796,7 @@ pub fn run() -> Result<()> { chain_spec::people::PeopleRuntimeType::Westend | chain_spec::people::PeopleRuntimeType::WestendLocal | chain_spec::people::PeopleRuntimeType::WestendDevelopment => - crate::service::start_generic_aura_lookahead_node::< - RuntimeApi, - AuraId, - >(config, polkadot_config, collator_options, id, hwbench) + crate::service::start_generic_aura_lookahead_node(config, polkadot_config, collator_options, id, hwbench) .await .map(|r| r.0), } diff --git a/cumulus/polkadot-parachain/src/service.rs b/cumulus/polkadot-parachain/src/service.rs index 386551102e4..ddf595ca70c 100644 --- a/cumulus/polkadot-parachain/src/service.rs +++ b/cumulus/polkadot-parachain/src/service.rs @@ -36,12 +36,13 @@ use cumulus_primitives_core::{ ParaId, }; use cumulus_relay_chain_interface::{OverseerHandle, RelayChainInterface}; +use sc_rpc::DenyUnsafe; use sp_core::Pair; use jsonrpsee::RpcModule; -use crate::{fake_runtime_api::aura::RuntimeApi, rpc}; -pub use parachains_common::{AccountId, Balance, Block, Hash, Header, Nonce}; +use crate::{fake_runtime_api::aura::RuntimeApi as FakeRuntimeApi, rpc}; +pub use parachains_common::{AccountId, AuraId, Balance, Block, Hash, Header, Nonce}; use cumulus_client_consensus_relay_chain::Verifier as RelayChainVerifier; use futures::{lock::Mutex, prelude::*}; @@ -85,141 +86,6 @@ type ParachainBackend = TFullBackend; type ParachainBlockImport = TParachainBlockImport>, ParachainBackend>; -/// Native executor instance. -pub struct ShellRuntimeExecutor; - -impl sc_executor::NativeExecutionDispatch for ShellRuntimeExecutor { - type ExtendHostFunctions = (); - - fn dispatch(method: &str, data: &[u8]) -> Option> { - shell_runtime::api::dispatch(method, data) - } - - fn native_version() -> sc_executor::NativeVersion { - shell_runtime::native_version() - } -} - -/// Native Asset Hub Westend (Westmint) executor instance. -pub struct AssetHubWestendExecutor; -impl sc_executor::NativeExecutionDispatch for AssetHubWestendExecutor { - type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; - - fn dispatch(method: &str, data: &[u8]) -> Option> { - asset_hub_westend_runtime::api::dispatch(method, data) - } - - fn native_version() -> sc_executor::NativeVersion { - asset_hub_westend_runtime::native_version() - } -} - -/// Native Westend Collectives executor instance. -pub struct CollectivesWestendRuntimeExecutor; - -impl sc_executor::NativeExecutionDispatch for CollectivesWestendRuntimeExecutor { - type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; - - fn dispatch(method: &str, data: &[u8]) -> Option> { - collectives_westend_runtime::api::dispatch(method, data) - } - - fn native_version() -> sc_executor::NativeVersion { - collectives_westend_runtime::native_version() - } -} - -/// Native BridgeHubRococo executor instance. -pub struct BridgeHubRococoRuntimeExecutor; -impl sc_executor::NativeExecutionDispatch for BridgeHubRococoRuntimeExecutor { - type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; - - fn dispatch(method: &str, data: &[u8]) -> Option> { - bridge_hub_rococo_runtime::api::dispatch(method, data) - } - - fn native_version() -> sc_executor::NativeVersion { - bridge_hub_rococo_runtime::native_version() - } -} - -/// Native `CoretimeRococo` executor instance. -pub struct CoretimeRococoRuntimeExecutor; -impl sc_executor::NativeExecutionDispatch for CoretimeRococoRuntimeExecutor { - type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; - fn dispatch(method: &str, data: &[u8]) -> Option> { - coretime_rococo_runtime::api::dispatch(method, data) - } - fn native_version() -> sc_executor::NativeVersion { - coretime_rococo_runtime::native_version() - } -} - -/// Native `CoretimeWestend` executor instance. -pub struct CoretimeWestendRuntimeExecutor; -impl sc_executor::NativeExecutionDispatch for CoretimeWestendRuntimeExecutor { - type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; - fn dispatch(method: &str, data: &[u8]) -> Option> { - coretime_westend_runtime::api::dispatch(method, data) - } - fn native_version() -> sc_executor::NativeVersion { - coretime_westend_runtime::native_version() - } -} - -/// Native contracts executor instance. -pub struct ContractsRococoRuntimeExecutor; -impl sc_executor::NativeExecutionDispatch for ContractsRococoRuntimeExecutor { - type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; - - fn dispatch(method: &str, data: &[u8]) -> Option> { - contracts_rococo_runtime::api::dispatch(method, data) - } - - fn native_version() -> sc_executor::NativeVersion { - contracts_rococo_runtime::native_version() - } -} - -/// Native Westend Glutton executor instance. -pub struct GluttonWestendRuntimeExecutor; - -impl sc_executor::NativeExecutionDispatch for GluttonWestendRuntimeExecutor { - type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; - - fn dispatch(method: &str, data: &[u8]) -> Option> { - glutton_westend_runtime::api::dispatch(method, data) - } - - fn native_version() -> sc_executor::NativeVersion { - glutton_westend_runtime::native_version() - } -} - -/// Native `PeopleWestend` executor instance. -pub struct PeopleWestendRuntimeExecutor; -impl sc_executor::NativeExecutionDispatch for PeopleWestendRuntimeExecutor { - type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; - fn dispatch(method: &str, data: &[u8]) -> Option> { - people_westend_runtime::api::dispatch(method, data) - } - fn native_version() -> sc_executor::NativeVersion { - people_westend_runtime::native_version() - } -} - -/// Native `PeopleRococo` executor instance. -pub struct PeopleRococoRuntimeExecutor; -impl sc_executor::NativeExecutionDispatch for PeopleRococoRuntimeExecutor { - type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; - fn dispatch(method: &str, data: &[u8]) -> Option> { - people_rococo_runtime::api::dispatch(method, data) - } - fn native_version() -> sc_executor::NativeVersion { - people_rococo_runtime::native_version() - } -} - /// Assembly of PartialComponents (enough to run chain ops subcommands) pub type Service = PartialComponents< ParachainClient, @@ -323,12 +189,11 @@ where }) } -/// Start a shell node with the given parachain `Configuration` and relay chain `Configuration`. +/// Start a node with the given parachain `Configuration` and relay chain `Configuration`. /// -/// This is the actual implementation that is abstract over the executor and the runtime api for -/// shell nodes. +/// This is the actual implementation that is abstract over the executor and the runtime api. #[sc_tracing::logging::prefix_logs_with("Parachain")] -async fn start_shell_node_impl( +async fn start_node_impl( parachain_config: Configuration, polkadot_config: Configuration, collator_options: CollatorOptions, @@ -347,8 +212,15 @@ where + sp_api::ApiExt + sp_offchain::OffchainWorkerApi + sp_block_builder::BlockBuilder - + cumulus_primitives_core::CollectCollationInfo, - RB: Fn(Arc>) -> Result, sc_service::Error> + + cumulus_primitives_core::CollectCollationInfo + + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi + + frame_rpc_system::AccountNonceApi, + RB: Fn( + DenyUnsafe, + Arc>, + Arc, + Arc>>, + ) -> Result, sc_service::Error> + 'static, BIQ: FnOnce( Arc>, @@ -372,6 +244,7 @@ where CollatorPair, OverseerHandle, Arc>) + Send + Sync>, + Arc, ) -> Result<(), sc_service::Error>, { let parachain_config = prepare_node_config(parachain_config); @@ -383,7 +256,6 @@ where let backend = params.backend.clone(); let mut task_manager = params.task_manager; - let (relay_chain_interface, collator_key) = build_relay_chain_interface( polkadot_config, ¶chain_config, @@ -415,8 +287,20 @@ where }) .await?; - let rpc_client = client.clone(); - let rpc_builder = Box::new(move |_, _| rpc_ext_builder(rpc_client.clone())); + let rpc_builder = { + let client = client.clone(); + let transaction_pool = transaction_pool.clone(); + let backend_for_rpc = backend.clone(); + + Box::new(move |deny_unsafe, _| { + rpc_ext_builder( + deny_unsafe, + client.clone(), + backend_for_rpc.clone(), + transaction_pool.clone(), + ) + }) + }; sc_service::spawn_tasks(sc_service::SpawnTasksParams { rpc_builder, @@ -493,6 +377,7 @@ where collator_key.expect("Command line arguments do not allow this. qed"), overseer_handle, announce_block, + backend.clone(), )?; } @@ -501,676 +386,179 @@ where Ok((task_manager, client)) } -/// Start a node with the given parachain `Configuration` and relay chain `Configuration`. -/// -/// This is the actual implementation that is abstract over the executor and the runtime api. -#[sc_tracing::logging::prefix_logs_with("Parachain")] -async fn start_node_impl( +/// Build the import queue for Aura-based runtimes. +pub fn build_aura_import_queue( + client: Arc>, + block_import: ParachainBlockImport, + config: &Configuration, + telemetry: Option, + task_manager: &TaskManager, +) -> Result, sc_service::Error> { + let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; + + cumulus_client_consensus_aura::import_queue::< + sp_consensus_aura::sr25519::AuthorityPair, + _, + _, + _, + _, + _, + >(cumulus_client_consensus_aura::ImportQueueParams { + block_import, + client, + create_inherent_data_providers: move |_, _| async move { + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + + let slot = + sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( + *timestamp, + slot_duration, + ); + + Ok((slot, timestamp)) + }, + registry: config.prometheus_registry(), + spawner: &task_manager.spawn_essential_handle(), + telemetry, + }) + .map_err(Into::into) +} + +/// Start a rococo parachain node. +pub async fn start_rococo_parachain_node( parachain_config: Configuration, polkadot_config: Configuration, collator_options: CollatorOptions, - sybil_resistance_level: CollatorSybilResistance, para_id: ParaId, - _rpc_ext_builder: RB, - build_import_queue: BIQ, - start_consensus: SC, hwbench: Option, -) -> sc_service::error::Result<(TaskManager, Arc>)> +) -> sc_service::error::Result<(TaskManager, Arc>)> { + start_node_impl::( + parachain_config, + polkadot_config, + collator_options, + CollatorSybilResistance::Resistant, // Aura + para_id, + build_parachain_rpc_extensions::, + build_aura_import_queue, + start_lookahead_aura_consensus, + hwbench, + ) + .await +} + +/// Build the import queue for the shell runtime. +pub fn build_shell_import_queue( + client: Arc>, + block_import: ParachainBlockImport, + config: &Configuration, + _: Option, + task_manager: &TaskManager, +) -> Result, sc_service::Error> { + cumulus_client_consensus_relay_chain::import_queue( + client, + block_import, + |_, _| async { Ok(()) }, + &task_manager.spawn_essential_handle(), + config.prometheus_registry(), + ) + .map_err(Into::into) +} + +fn build_parachain_rpc_extensions( + deny_unsafe: sc_rpc::DenyUnsafe, + client: Arc>, + backend: Arc, + pool: Arc>>, +) -> Result, sc_service::Error> where RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue - + sp_api::Metadata - + sp_session::SessionKeys - + sp_api::ApiExt - + sp_offchain::OffchainWorkerApi + sp_block_builder::BlockBuilder - + cumulus_primitives_core::CollectCollationInfo + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi + frame_rpc_system::AccountNonceApi, - RB: Fn(Arc>) -> Result, sc_service::Error>, - BIQ: FnOnce( - Arc>, - ParachainBlockImport, - &Configuration, - Option, - &TaskManager, - ) -> Result, sc_service::Error>, - SC: FnOnce( - Arc>, - ParachainBlockImport, - Option<&Registry>, - Option, - &TaskManager, - Arc, - Arc>>, - Arc>, - KeystorePtr, - Duration, - ParaId, - CollatorPair, - OverseerHandle, - Arc>) + Send + Sync>, - Arc, - ) -> Result<(), sc_service::Error>, { - let parachain_config = prepare_node_config(parachain_config); + let deps = rpc::FullDeps { client, pool, deny_unsafe }; - let params = new_partial::(¶chain_config, build_import_queue)?; - let (block_import, mut telemetry, telemetry_worker_handle) = params.other; + rpc::create_full(deps, backend).map_err(Into::into) +} - let client = params.client.clone(); - let backend = params.backend.clone(); +fn build_contracts_rpc_extensions( + deny_unsafe: sc_rpc::DenyUnsafe, + client: Arc>, + _backend: Arc, + pool: Arc>>, +) -> Result, sc_service::Error> { + let deps = crate::rpc::FullDeps { client: client.clone(), pool: pool.clone(), deny_unsafe }; - let mut task_manager = params.task_manager; - let (relay_chain_interface, collator_key) = build_relay_chain_interface( + crate::rpc::create_contracts_rococo(deps).map_err(Into::into) +} + +/// Start a polkadot-shell parachain node. +pub async fn start_shell_node( + parachain_config: Configuration, + polkadot_config: Configuration, + collator_options: CollatorOptions, + para_id: ParaId, + hwbench: Option, +) -> sc_service::error::Result<(TaskManager, Arc>)> { + start_node_impl::( + parachain_config, polkadot_config, - ¶chain_config, - telemetry_worker_handle, - &mut task_manager, - collator_options.clone(), - hwbench.clone(), + collator_options, + CollatorSybilResistance::Unresistant, // free-for-all consensus + para_id, + |_, _, _, _| Ok(RpcModule::new(())), + build_shell_import_queue, + start_relay_chain_consensus, + hwbench, ) .await - .map_err(|e| sc_service::Error::Application(Box::new(e) as Box<_>))?; - - let validator = parachain_config.role.is_authority(); - let prometheus_registry = parachain_config.prometheus_registry().cloned(); - let transaction_pool = params.transaction_pool.clone(); - let import_queue_service = params.import_queue.service(); - let net_config = FullNetworkConfiguration::new(¶chain_config.network); - - let (network, system_rpc_tx, tx_handler_controller, start_network, sync_service) = - build_network(BuildNetworkParams { - parachain_config: ¶chain_config, - net_config, - client: client.clone(), - transaction_pool: transaction_pool.clone(), - para_id, - spawn_handle: task_manager.spawn_handle(), - relay_chain_interface: relay_chain_interface.clone(), - import_queue: params.import_queue, - sybil_resistance_level, - }) - .await?; +} - let rpc_builder = { - let client = client.clone(); - let transaction_pool = transaction_pool.clone(); +enum BuildOnAccess { + Uninitialized(Option R + Send + Sync>>), + Initialized(R), +} - let backend_for_rpc = backend.clone(); - Box::new(move |deny_unsafe, _| { - let deps = rpc::FullDeps { - client: client.clone(), - pool: transaction_pool.clone(), - deny_unsafe, - }; +impl BuildOnAccess { + fn get_mut(&mut self) -> &mut R { + loop { + match self { + Self::Uninitialized(f) => { + *self = Self::Initialized((f.take().unwrap())()); + }, + Self::Initialized(ref mut r) => return r, + } + } + } +} - rpc::create_full(deps, backend_for_rpc.clone()).map_err(Into::into) - }) - }; +/// Special [`ParachainConsensus`] implementation that waits for the upgrade from +/// shell to a parachain runtime that implements Aura. +struct WaitForAuraConsensus { + client: Arc, + aura_consensus: Arc>>>>, + relay_chain_consensus: Arc>>>, + _phantom: PhantomData, +} - sc_service::spawn_tasks(sc_service::SpawnTasksParams { - rpc_builder, - client: client.clone(), - transaction_pool: transaction_pool.clone(), - task_manager: &mut task_manager, - config: parachain_config, - keystore: params.keystore_container.keystore(), - backend: backend.clone(), - network: network.clone(), - sync_service: sync_service.clone(), - system_rpc_tx, - tx_handler_controller, - telemetry: telemetry.as_mut(), - })?; - - if let Some(hwbench) = hwbench { - sc_sysinfo::print_hwbench(&hwbench); - if validator { - warn_if_slow_hardware(&hwbench); - } - - if let Some(ref mut telemetry) = telemetry { - let telemetry_handle = telemetry.handle(); - task_manager.spawn_handle().spawn( - "telemetry_hwbench", - None, - sc_sysinfo::initialize_hwbench_telemetry(telemetry_handle, hwbench), - ); +impl Clone for WaitForAuraConsensus { + fn clone(&self) -> Self { + Self { + client: self.client.clone(), + aura_consensus: self.aura_consensus.clone(), + relay_chain_consensus: self.relay_chain_consensus.clone(), + _phantom: PhantomData, } } - - let announce_block = { - let sync_service = sync_service.clone(); - Arc::new(move |hash, data| sync_service.announce_block(hash, data)) - }; - - let relay_chain_slot_duration = Duration::from_secs(6); - - let overseer_handle = relay_chain_interface - .overseer_handle() - .map_err(|e| sc_service::Error::Application(Box::new(e)))?; - - start_relay_chain_tasks(StartRelayChainTasksParams { - client: client.clone(), - announce_block: announce_block.clone(), - para_id, - relay_chain_interface: relay_chain_interface.clone(), - task_manager: &mut task_manager, - da_recovery_profile: if validator { - DARecoveryProfile::Collator - } else { - DARecoveryProfile::FullNode - }, - import_queue: import_queue_service, - relay_chain_slot_duration, - recovery_handle: Box::new(overseer_handle.clone()), - sync_service: sync_service.clone(), - })?; - - if validator { - start_consensus( - client.clone(), - block_import, - prometheus_registry.as_ref(), - telemetry.as_ref().map(|t| t.handle()), - &task_manager, - relay_chain_interface.clone(), - transaction_pool, - sync_service.clone(), - params.keystore_container.keystore(), - relay_chain_slot_duration, - para_id, - collator_key.expect("Command line arguments do not allow this. qed"), - overseer_handle, - announce_block, - backend.clone(), - )?; - } - - start_network.start_network(); - - Ok((task_manager, client)) } -/// Start a node with the given parachain `Configuration` and relay chain `Configuration`. -/// -/// This is the actual implementation that is abstract over the executor and the runtime api. -/// -/// This node is basic in the sense that it doesn't support functionality like transaction -/// payment. Intended to replace start_shell_node in use for glutton, shell, and seedling. -#[sc_tracing::logging::prefix_logs_with("Parachain")] -async fn start_basic_lookahead_node_impl( - parachain_config: Configuration, - polkadot_config: Configuration, - collator_options: CollatorOptions, - sybil_resistance_level: CollatorSybilResistance, - para_id: ParaId, - rpc_ext_builder: RB, - build_import_queue: BIQ, - start_consensus: SC, - hwbench: Option, -) -> sc_service::error::Result<(TaskManager, Arc>)> +#[async_trait::async_trait] +impl ParachainConsensus for WaitForAuraConsensus where - RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, - RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue - + sp_api::Metadata - + sp_session::SessionKeys - + sp_api::ApiExt - + sp_offchain::OffchainWorkerApi - + sp_block_builder::BlockBuilder - + cumulus_primitives_core::CollectCollationInfo - + frame_rpc_system::AccountNonceApi, - RB: Fn(Arc>) -> Result, sc_service::Error> - + 'static, - BIQ: FnOnce( - Arc>, - ParachainBlockImport, - &Configuration, - Option, - &TaskManager, - ) -> Result, sc_service::Error>, - SC: FnOnce( - Arc>, - ParachainBlockImport, - Option<&Registry>, - Option, - &TaskManager, - Arc, - Arc>>, - Arc>, - KeystorePtr, - Duration, - ParaId, - CollatorPair, - OverseerHandle, - Arc>) + Send + Sync>, - Arc, - ) -> Result<(), sc_service::Error>, -{ - let parachain_config = prepare_node_config(parachain_config); - - let params = new_partial::(¶chain_config, build_import_queue)?; - let (block_import, mut telemetry, telemetry_worker_handle) = params.other; - - let client = params.client.clone(); - let backend = params.backend.clone(); - - let mut task_manager = params.task_manager; - let (relay_chain_interface, collator_key) = build_relay_chain_interface( - polkadot_config, - ¶chain_config, - telemetry_worker_handle, - &mut task_manager, - collator_options.clone(), - hwbench.clone(), - ) - .await - .map_err(|e| sc_service::Error::Application(Box::new(e) as Box<_>))?; - - let validator = parachain_config.role.is_authority(); - let prometheus_registry = parachain_config.prometheus_registry().cloned(); - let transaction_pool = params.transaction_pool.clone(); - let import_queue_service = params.import_queue.service(); - let net_config = FullNetworkConfiguration::new(¶chain_config.network); - - let (network, system_rpc_tx, tx_handler_controller, start_network, sync_service) = - build_network(BuildNetworkParams { - parachain_config: ¶chain_config, - net_config, - client: client.clone(), - transaction_pool: transaction_pool.clone(), - para_id, - spawn_handle: task_manager.spawn_handle(), - relay_chain_interface: relay_chain_interface.clone(), - import_queue: params.import_queue, - sybil_resistance_level, - }) - .await?; - - let rpc_client = client.clone(); - let rpc_builder = Box::new(move |_, _| rpc_ext_builder(rpc_client.clone())); - - sc_service::spawn_tasks(sc_service::SpawnTasksParams { - rpc_builder, - client: client.clone(), - transaction_pool: transaction_pool.clone(), - task_manager: &mut task_manager, - config: parachain_config, - keystore: params.keystore_container.keystore(), - backend: backend.clone(), - network: network.clone(), - sync_service: sync_service.clone(), - system_rpc_tx, - tx_handler_controller, - telemetry: telemetry.as_mut(), - })?; - - if let Some(hwbench) = hwbench { - sc_sysinfo::print_hwbench(&hwbench); - if validator { - warn_if_slow_hardware(&hwbench); - } - - if let Some(ref mut telemetry) = telemetry { - let telemetry_handle = telemetry.handle(); - task_manager.spawn_handle().spawn( - "telemetry_hwbench", - None, - sc_sysinfo::initialize_hwbench_telemetry(telemetry_handle, hwbench), - ); - } - } - - let announce_block = { - let sync_service = sync_service.clone(); - Arc::new(move |hash, data| sync_service.announce_block(hash, data)) - }; - - let relay_chain_slot_duration = Duration::from_secs(6); - - let overseer_handle = relay_chain_interface - .overseer_handle() - .map_err(|e| sc_service::Error::Application(Box::new(e)))?; - - start_relay_chain_tasks(StartRelayChainTasksParams { - client: client.clone(), - announce_block: announce_block.clone(), - para_id, - relay_chain_interface: relay_chain_interface.clone(), - task_manager: &mut task_manager, - da_recovery_profile: if validator { - DARecoveryProfile::Collator - } else { - DARecoveryProfile::FullNode - }, - import_queue: import_queue_service, - relay_chain_slot_duration, - recovery_handle: Box::new(overseer_handle.clone()), - sync_service: sync_service.clone(), - })?; - - if validator { - start_consensus( - client.clone(), - block_import, - prometheus_registry.as_ref(), - telemetry.as_ref().map(|t| t.handle()), - &task_manager, - relay_chain_interface.clone(), - transaction_pool, - sync_service.clone(), - params.keystore_container.keystore(), - relay_chain_slot_duration, - para_id, - collator_key.expect("Command line arguments do not allow this. qed"), - overseer_handle, - announce_block, - backend.clone(), - )?; - } - - start_network.start_network(); - - Ok((task_manager, client)) -} - -/// Build the import queue for the rococo parachain runtime. -pub fn rococo_parachain_build_import_queue( - client: Arc>, - block_import: ParachainBlockImport, - config: &Configuration, - telemetry: Option, - task_manager: &TaskManager, -) -> Result, sc_service::Error> { - let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; - - cumulus_client_consensus_aura::import_queue::< - sp_consensus_aura::sr25519::AuthorityPair, - _, - _, - _, - _, - _, - >(cumulus_client_consensus_aura::ImportQueueParams { - block_import, - client, - create_inherent_data_providers: move |_, _| async move { - let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); - - let slot = - sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( - *timestamp, - slot_duration, - ); - - Ok((slot, timestamp)) - }, - registry: config.prometheus_registry(), - spawner: &task_manager.spawn_essential_handle(), - telemetry, - }) - .map_err(Into::into) -} - -/// Start a rococo parachain node. -pub async fn start_rococo_parachain_node( - parachain_config: Configuration, - polkadot_config: Configuration, - collator_options: CollatorOptions, - para_id: ParaId, - hwbench: Option, -) -> sc_service::error::Result<(TaskManager, Arc>)> { - start_node_impl::( - parachain_config, - polkadot_config, - collator_options, - CollatorSybilResistance::Resistant, // Aura - para_id, - |_| Ok(RpcModule::new(())), - rococo_parachain_build_import_queue, - |client, - block_import, - prometheus_registry, - telemetry, - task_manager, - relay_chain_interface, - transaction_pool, - sync_oracle, - keystore, - relay_chain_slot_duration, - para_id, - collator_key, - overseer_handle, - announce_block, - backend| { - let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( - task_manager.spawn_handle(), - client.clone(), - transaction_pool, - prometheus_registry, - telemetry.clone(), - ); - let proposer = Proposer::new(proposer_factory); - - let collator_service = CollatorService::new( - client.clone(), - Arc::new(task_manager.spawn_handle()), - announce_block, - client.clone(), - ); - - let params = AuraParams { - create_inherent_data_providers: move |_, ()| async move { Ok(()) }, - block_import, - para_client: client.clone(), - para_backend: backend.clone(), - relay_client: relay_chain_interface, - code_hash_provider: move |block_hash| { - client.code_at(block_hash).ok().map(|c| ValidationCode::from(c).hash()) - }, - sync_oracle, - keystore, - collator_key, - para_id, - overseer_handle, - relay_chain_slot_duration, - proposer, - collator_service, - authoring_duration: Duration::from_millis(1500), - reinitialize: false, - }; - - let fut = aura::run::< - Block, - sp_consensus_aura::sr25519::AuthorityPair, - _, - _, - _, - _, - _, - _, - _, - _, - _, - >(params); - task_manager.spawn_essential_handle().spawn("aura", None, fut); - - Ok(()) - }, - hwbench, - ) - .await -} - -/// Build the import queue for the shell runtime. -pub fn shell_build_import_queue( - client: Arc>, - block_import: ParachainBlockImport, - config: &Configuration, - _: Option, - task_manager: &TaskManager, -) -> Result, sc_service::Error> -where - RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, - RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue - + sp_api::Metadata - + sp_session::SessionKeys - + sp_api::ApiExt - + sp_offchain::OffchainWorkerApi - + sp_block_builder::BlockBuilder, -{ - cumulus_client_consensus_relay_chain::import_queue( - client, - block_import, - |_, _| async { Ok(()) }, - &task_manager.spawn_essential_handle(), - config.prometheus_registry(), - ) - .map_err(Into::into) -} - -/// Start a polkadot-shell parachain node. -pub async fn start_shell_node( - parachain_config: Configuration, - polkadot_config: Configuration, - collator_options: CollatorOptions, - para_id: ParaId, - hwbench: Option, -) -> sc_service::error::Result<(TaskManager, Arc>)> -where - RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, - RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue - + sp_api::Metadata - + sp_session::SessionKeys - + sp_api::ApiExt - + sp_offchain::OffchainWorkerApi - + sp_block_builder::BlockBuilder - + cumulus_primitives_core::CollectCollationInfo, -{ - start_shell_node_impl::( - parachain_config, - polkadot_config, - collator_options, - CollatorSybilResistance::Unresistant, // free-for-all consensus - para_id, - |_| Ok(RpcModule::new(())), - shell_build_import_queue, - |client, - block_import, - prometheus_registry, - telemetry, - task_manager, - relay_chain_interface, - transaction_pool, - _sync_oracle, - _keystore, - _relay_chain_slot_duration, - para_id, - collator_key, - overseer_handle, - announce_block| { - let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( - task_manager.spawn_handle(), - client.clone(), - transaction_pool, - prometheus_registry, - telemetry, - ); - - let free_for_all = cumulus_client_consensus_relay_chain::build_relay_chain_consensus( - cumulus_client_consensus_relay_chain::BuildRelayChainConsensusParams { - para_id, - proposer_factory, - block_import, - relay_chain_interface: relay_chain_interface.clone(), - create_inherent_data_providers: move |_, (relay_parent, validation_data)| { - let relay_chain_interface = relay_chain_interface.clone(); - async move { - let parachain_inherent = - cumulus_client_parachain_inherent::ParachainInherentDataProvider::create_at( - relay_parent, - &relay_chain_interface, - &validation_data, - para_id, - ).await; - let parachain_inherent = parachain_inherent.ok_or_else(|| { - Box::::from( - "Failed to create parachain inherent", - ) - })?; - Ok(parachain_inherent) - } - }, - }, - ); - - let spawner = task_manager.spawn_handle(); - - // Required for free-for-all consensus - #[allow(deprecated)] - old_consensus::start_collator_sync(old_consensus::StartCollatorParams { - para_id, - block_status: client.clone(), - announce_block, - overseer_handle, - spawner, - key: collator_key, - parachain_consensus: free_for_all, - runtime_api: client.clone(), - }); - - Ok(()) - }, - hwbench, - ) - .await -} - -enum BuildOnAccess { - Uninitialized(Option R + Send + Sync>>), - Initialized(R), -} - -impl BuildOnAccess { - fn get_mut(&mut self) -> &mut R { - loop { - match self { - Self::Uninitialized(f) => { - *self = Self::Initialized((f.take().unwrap())()); - }, - Self::Initialized(ref mut r) => return r, - } - } - } -} - -/// Special [`ParachainConsensus`] implementation that waits for the upgrade from -/// shell to a parachain runtime that implements Aura. -struct WaitForAuraConsensus { - client: Arc, - aura_consensus: Arc>>>>, - relay_chain_consensus: Arc>>>, - _phantom: PhantomData, -} - -impl Clone for WaitForAuraConsensus { - fn clone(&self) -> Self { - Self { - client: self.client.clone(), - aura_consensus: self.aura_consensus.clone(), - relay_chain_consensus: self.relay_chain_consensus.clone(), - _phantom: PhantomData, - } - } -} - -#[async_trait::async_trait] -impl ParachainConsensus for WaitForAuraConsensus -where - Client: sp_api::ProvideRuntimeApi + Send + Sync, - Client::Api: AuraApi, - AuraId: Send + Codec + Sync, + Client: sp_api::ProvideRuntimeApi + Send + Sync, + Client::Api: AuraApi, + AuraId: Send + Codec + Sync, { async fn produce_candidate( &mut self, @@ -1190,464 +578,56 @@ where .get_mut() .produce_candidate(parent, relay_parent, validation_data) .await - } else { - self.relay_chain_consensus - .lock() - .await - .produce_candidate(parent, relay_parent, validation_data) - .await - } - } -} - -struct Verifier { - client: Arc, - aura_verifier: BuildOnAccess>>, - relay_chain_verifier: Box>, - _phantom: PhantomData, -} - -#[async_trait::async_trait] -impl VerifierT for Verifier -where - Client: sp_api::ProvideRuntimeApi + Send + Sync, - Client::Api: AuraApi, - AuraId: Send + Sync + Codec, -{ - async fn verify( - &mut self, - block_import: BlockImportParams, - ) -> Result, String> { - if self - .client - .runtime_api() - .has_api::>(*block_import.header.parent_hash()) - .unwrap_or(false) - { - self.aura_verifier.get_mut().verify(block_import).await - } else { - self.relay_chain_verifier.verify(block_import).await - } - } -} - -/// Build the import queue for Aura-based runtimes. -pub fn aura_build_import_queue( - client: Arc>, - block_import: ParachainBlockImport, - config: &Configuration, - telemetry_handle: Option, - task_manager: &TaskManager, -) -> Result, sc_service::Error> -where - RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, - RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue - + sp_api::Metadata - + sp_session::SessionKeys - + sp_api::ApiExt - + sp_offchain::OffchainWorkerApi - + sp_block_builder::BlockBuilder - + sp_consensus_aura::AuraApi::Pair as Pair>::Public>, - <::Pair as Pair>::Signature: - TryFrom> + std::hash::Hash + sp_runtime::traits::Member + Codec, -{ - let verifier_client = client.clone(); - - let aura_verifier = move || { - Box::new(cumulus_client_consensus_aura::build_verifier::< - ::Pair, - _, - _, - _, - >(cumulus_client_consensus_aura::BuildVerifierParams { - client: verifier_client.clone(), - create_inherent_data_providers: move |parent_hash, _| { - let cidp_client = verifier_client.clone(); - async move { - let slot_duration = cumulus_client_consensus_aura::slot_duration_at( - &*cidp_client, - parent_hash, - )?; - let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); - - let slot = - sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( - *timestamp, - slot_duration, - ); - - Ok((slot, timestamp)) - } - }, - telemetry: telemetry_handle, - })) as Box<_> - }; - - let relay_chain_verifier = - Box::new(RelayChainVerifier::new(client.clone(), |_, _| async { Ok(()) })) as Box<_>; - - let verifier = Verifier { - client, - relay_chain_verifier, - aura_verifier: BuildOnAccess::Uninitialized(Some(Box::new(aura_verifier))), - _phantom: PhantomData, - }; - - let registry = config.prometheus_registry(); - let spawner = task_manager.spawn_essential_handle(); - - Ok(BasicQueue::new(verifier, Box::new(block_import), None, &spawner, registry)) -} - -/// Start an aura powered parachain node. Some system chains use this. -pub async fn start_generic_aura_node( - parachain_config: Configuration, - polkadot_config: Configuration, - collator_options: CollatorOptions, - para_id: ParaId, - hwbench: Option, -) -> sc_service::error::Result<(TaskManager, Arc>)> -where - RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, - RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue - + sp_api::Metadata - + sp_session::SessionKeys - + sp_api::ApiExt - + sp_offchain::OffchainWorkerApi - + sp_block_builder::BlockBuilder - + cumulus_primitives_core::CollectCollationInfo - + sp_consensus_aura::AuraApi::Pair as Pair>::Public> - + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi - + frame_rpc_system::AccountNonceApi, - <::Pair as Pair>::Signature: - TryFrom> + std::hash::Hash + sp_runtime::traits::Member + Codec, -{ - start_node_impl::( - parachain_config, - polkadot_config, - collator_options, - CollatorSybilResistance::Resistant, // Aura - para_id, - |_| Ok(RpcModule::new(())), - aura_build_import_queue::<_, AuraId>, - |client, - block_import, - prometheus_registry, - telemetry, - task_manager, - relay_chain_interface, - transaction_pool, - sync_oracle, - keystore, - relay_chain_slot_duration, - para_id, - collator_key, - overseer_handle, - announce_block, - _backend| { - let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; - - let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( - task_manager.spawn_handle(), - client.clone(), - transaction_pool, - prometheus_registry, - telemetry.clone(), - ); - let proposer = Proposer::new(proposer_factory); - - let collator_service = CollatorService::new( - client.clone(), - Arc::new(task_manager.spawn_handle()), - announce_block, - client.clone(), - ); - - let params = BasicAuraParams { - create_inherent_data_providers: move |_, ()| async move { Ok(()) }, - block_import, - para_client: client, - relay_client: relay_chain_interface, - sync_oracle, - keystore, - collator_key, - para_id, - overseer_handle, - slot_duration, - relay_chain_slot_duration, - proposer, - collator_service, - // Very limited proposal time. - authoring_duration: Duration::from_millis(500), - collation_request_receiver: None, - }; - - let fut = - basic_aura::run::::Pair, _, _, _, _, _, _, _>(params); - task_manager.spawn_essential_handle().spawn("aura", None, fut); - - Ok(()) - }, - hwbench, - ) - .await -} - -/// Uses the lookahead collator to support async backing. -/// -/// Start an aura powered parachain node. Some system chains use this. -pub async fn start_generic_aura_lookahead_node( - parachain_config: Configuration, - polkadot_config: Configuration, - collator_options: CollatorOptions, - para_id: ParaId, - hwbench: Option, -) -> sc_service::error::Result<(TaskManager, Arc>)> -where - RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, - RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue - + sp_api::Metadata - + sp_session::SessionKeys - + sp_api::ApiExt - + sp_offchain::OffchainWorkerApi - + sp_block_builder::BlockBuilder - + cumulus_primitives_core::CollectCollationInfo - + sp_consensus_aura::AuraApi::Pair as Pair>::Public> - + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi - + frame_rpc_system::AccountNonceApi - + cumulus_primitives_aura::AuraUnincludedSegmentApi, - <::Pair as Pair>::Signature: - TryFrom> + std::hash::Hash + sp_runtime::traits::Member + Codec, -{ - start_node_impl::( - parachain_config, - polkadot_config, - collator_options, - CollatorSybilResistance::Resistant, // Aura - para_id, - |_| Ok(RpcModule::new(())), - aura_build_import_queue::<_, AuraId>, - |client, - block_import, - prometheus_registry, - telemetry, - task_manager, - relay_chain_interface, - transaction_pool, - sync_oracle, - keystore, - relay_chain_slot_duration, - para_id, - collator_key, - overseer_handle, - announce_block, - backend| { - let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( - task_manager.spawn_handle(), - client.clone(), - transaction_pool, - prometheus_registry, - telemetry.clone(), - ); - let proposer = Proposer::new(proposer_factory); - - let collator_service = CollatorService::new( - client.clone(), - Arc::new(task_manager.spawn_handle()), - announce_block, - client.clone(), - ); - - let params = AuraParams { - create_inherent_data_providers: move |_, ()| async move { Ok(()) }, - block_import, - para_client: client.clone(), - para_backend: backend, - relay_client: relay_chain_interface, - code_hash_provider: move |block_hash| { - client.code_at(block_hash).ok().map(|c| ValidationCode::from(c).hash()) - }, - sync_oracle, - keystore, - collator_key, - para_id, - overseer_handle, - relay_chain_slot_duration, - proposer, - collator_service, - authoring_duration: Duration::from_millis(1500), - reinitialize: false, - }; - - let fut = - aura::run::::Pair, _, _, _, _, _, _, _, _, _>(params); - task_manager.spawn_essential_handle().spawn("aura", None, fut); - - Ok(()) - }, - hwbench, - ) - .await -} - -/// Start a shell node which should later transition into an Aura powered parachain node. Asset Hub -/// uses this because at genesis, Asset Hub was on the `shell` runtime which didn't have Aura and -/// needs to sync and upgrade before it can run `AuraApi` functions. -pub async fn start_asset_hub_node( - parachain_config: Configuration, - polkadot_config: Configuration, - collator_options: CollatorOptions, - para_id: ParaId, - hwbench: Option, -) -> sc_service::error::Result<(TaskManager, Arc>)> -where - RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, - RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue - + sp_api::Metadata - + sp_session::SessionKeys - + sp_api::ApiExt - + sp_offchain::OffchainWorkerApi - + sp_block_builder::BlockBuilder - + cumulus_primitives_core::CollectCollationInfo - + sp_consensus_aura::AuraApi::Pair as Pair>::Public> - + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi - + frame_rpc_system::AccountNonceApi, - <::Pair as Pair>::Signature: - TryFrom> + std::hash::Hash + sp_runtime::traits::Member + Codec, -{ - start_node_impl::( - parachain_config, - polkadot_config, - collator_options, - CollatorSybilResistance::Resistant, // Aura - para_id, - |_| Ok(RpcModule::new(())), - aura_build_import_queue::<_, AuraId>, - |client, - block_import, - prometheus_registry, - telemetry, - task_manager, - relay_chain_interface, - transaction_pool, - sync_oracle, - keystore, - relay_chain_slot_duration, - para_id, - collator_key, - overseer_handle, - announce_block, - _backend| { - let relay_chain_interface2 = relay_chain_interface.clone(); - - let collator_service = CollatorService::new( - client.clone(), - Arc::new(task_manager.spawn_handle()), - announce_block, - client.clone(), - ); - - let spawner = task_manager.spawn_handle(); - - let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( - spawner, - client.clone(), - transaction_pool, - prometheus_registry, - telemetry.clone(), - ); - - let collation_future = Box::pin(async move { - // Start collating with the `shell` runtime while waiting for an upgrade to an Aura - // compatible runtime. - let mut request_stream = cumulus_client_collator::relay_chain_driven::init( - collator_key.clone(), - para_id, - overseer_handle.clone(), - ) - .await; - while let Some(request) = request_stream.next().await { - let pvd = request.persisted_validation_data().clone(); - let last_head_hash = - match ::Header::decode(&mut &pvd.parent_head.0[..]) { - Ok(header) => header.hash(), - Err(e) => { - log::error!("Could not decode the head data: {e}"); - request.complete(None); - continue - }, - }; - - // Check if we have upgraded to an Aura compatible runtime and transition if - // necessary. - if client - .runtime_api() - .has_api::>(last_head_hash) - .unwrap_or(false) - { - // Respond to this request before transitioning to Aura. - request.complete(None); - break - } - } - - // Move to Aura consensus. - let slot_duration = match cumulus_client_consensus_aura::slot_duration(&*client) { - Ok(d) => d, - Err(e) => { - log::error!("Could not get Aura slot duration: {e}"); - return - }, - }; - - let proposer = Proposer::new(proposer_factory); - - let params = BasicAuraParams { - create_inherent_data_providers: move |_, ()| async move { Ok(()) }, - block_import, - para_client: client, - relay_client: relay_chain_interface2, - sync_oracle, - keystore, - collator_key, - para_id, - overseer_handle, - slot_duration, - relay_chain_slot_duration, - proposer, - collator_service, - // Very limited proposal time. - authoring_duration: Duration::from_millis(500), - collation_request_receiver: Some(request_stream), - }; - - basic_aura::run::::Pair, _, _, _, _, _, _, _>(params) - .await - }); + } else { + self.relay_chain_consensus + .lock() + .await + .produce_candidate(parent, relay_parent, validation_data) + .await + } + } +} - let spawner = task_manager.spawn_essential_handle(); - spawner.spawn_essential("cumulus-asset-hub-collator", None, collation_future); +struct Verifier { + client: Arc, + aura_verifier: BuildOnAccess>>, + relay_chain_verifier: Box>, + _phantom: PhantomData, +} - Ok(()) - }, - hwbench, - ) - .await +#[async_trait::async_trait] +impl VerifierT for Verifier +where + Client: sp_api::ProvideRuntimeApi + Send + Sync, + Client::Api: AuraApi, + AuraId: Send + Sync + Codec, +{ + async fn verify( + &mut self, + block_import: BlockImportParams, + ) -> Result, String> { + if self + .client + .runtime_api() + .has_api::>(*block_import.header.parent_hash()) + .unwrap_or(false) + { + self.aura_verifier.get_mut().verify(block_import).await + } else { + self.relay_chain_verifier.verify(block_import).await + } + } } -/// Start a shell node which should later transition into an Aura powered parachain node. Asset Hub -/// uses this because at genesis, Asset Hub was on the `shell` runtime which didn't have Aura and -/// needs to sync and upgrade before it can run `AuraApi` functions. -/// -/// Uses the lookahead collator to support async backing. -#[sc_tracing::logging::prefix_logs_with("Parachain")] -pub async fn start_asset_hub_lookahead_node( - parachain_config: Configuration, - polkadot_config: Configuration, - collator_options: CollatorOptions, - para_id: ParaId, - hwbench: Option, -) -> sc_service::error::Result<(TaskManager, Arc>)> +/// Build the import queue for parachain runtimes that started with relay chain consensus and +/// switched to aura. +pub fn build_relay_to_aura_import_queue( + client: Arc>, + block_import: ParachainBlockImport, + config: &Configuration, + telemetry_handle: Option, + task_manager: &TaskManager, +) -> Result, sc_service::Error> where RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue @@ -1656,162 +636,74 @@ where + sp_api::ApiExt + sp_offchain::OffchainWorkerApi + sp_block_builder::BlockBuilder - + cumulus_primitives_core::CollectCollationInfo - + sp_consensus_aura::AuraApi::Pair as Pair>::Public> - + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi - + frame_rpc_system::AccountNonceApi - + cumulus_primitives_aura::AuraUnincludedSegmentApi, + + sp_consensus_aura::AuraApi::Pair as Pair>::Public>, <::Pair as Pair>::Signature: TryFrom> + std::hash::Hash + sp_runtime::traits::Member + Codec, { - start_node_impl::( - parachain_config, - polkadot_config, - collator_options, - CollatorSybilResistance::Resistant, // Aura - para_id, - |_| Ok(RpcModule::new(())), - aura_build_import_queue::<_, AuraId>, - |client, - block_import, - prometheus_registry, - telemetry, - task_manager, - relay_chain_interface, - transaction_pool, - sync_oracle, - keystore, - relay_chain_slot_duration, - para_id, - collator_key, - overseer_handle, - announce_block, - backend| { - let relay_chain_interface2 = relay_chain_interface.clone(); - - let collator_service = CollatorService::new( - client.clone(), - Arc::new(task_manager.spawn_handle()), - announce_block, - client.clone(), - ); - - let spawner = task_manager.spawn_handle(); + let verifier_client = client.clone(); - let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( - spawner, - client.clone(), - transaction_pool, - prometheus_registry, - telemetry.clone(), - ); + let aura_verifier = move || { + Box::new(cumulus_client_consensus_aura::build_verifier::< + ::Pair, + _, + _, + _, + >(cumulus_client_consensus_aura::BuildVerifierParams { + client: verifier_client.clone(), + create_inherent_data_providers: move |parent_hash, _| { + let cidp_client = verifier_client.clone(); + async move { + let slot_duration = cumulus_client_consensus_aura::slot_duration_at( + &*cidp_client, + parent_hash, + )?; + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); - let collation_future = Box::pin(async move { - // Start collating with the `shell` runtime while waiting for an upgrade to an Aura - // compatible runtime. - let mut request_stream = cumulus_client_collator::relay_chain_driven::init( - collator_key.clone(), - para_id, - overseer_handle.clone(), - ) - .await; - while let Some(request) = request_stream.next().await { - let pvd = request.persisted_validation_data().clone(); - let last_head_hash = - match ::Header::decode(&mut &pvd.parent_head.0[..]) { - Ok(header) => header.hash(), - Err(e) => { - log::error!("Could not decode the head data: {e}"); - request.complete(None); - continue - }, - }; + let slot = + sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( + *timestamp, + slot_duration, + ); - // Check if we have upgraded to an Aura compatible runtime and transition if - // necessary. - if client - .runtime_api() - .has_api::>(last_head_hash) - .unwrap_or(false) - { - // Respond to this request before transitioning to Aura. - request.complete(None); - break - } + Ok((slot, timestamp)) } + }, + telemetry: telemetry_handle, + })) as Box<_> + }; - // Move to Aura consensus. - let proposer = Proposer::new(proposer_factory); - - let params = AuraParams { - create_inherent_data_providers: move |_, ()| async move { Ok(()) }, - block_import, - para_client: client.clone(), - para_backend: backend, - relay_client: relay_chain_interface2, - code_hash_provider: move |block_hash| { - client.code_at(block_hash).ok().map(|c| ValidationCode::from(c).hash()) - }, - sync_oracle, - keystore, - collator_key, - para_id, - overseer_handle, - relay_chain_slot_duration, - proposer, - collator_service, - authoring_duration: Duration::from_millis(1500), - reinitialize: true, /* we need to always re-initialize for asset-hub moving - * to aura */ - }; + let relay_chain_verifier = + Box::new(RelayChainVerifier::new(client.clone(), |_, _| async { Ok(()) })) as Box<_>; - aura::run::::Pair, _, _, _, _, _, _, _, _, _>(params) - .await - }); + let verifier = Verifier { + client, + relay_chain_verifier, + aura_verifier: BuildOnAccess::Uninitialized(Some(Box::new(aura_verifier))), + _phantom: PhantomData, + }; - let spawner = task_manager.spawn_essential_handle(); - spawner.spawn_essential("cumulus-asset-hub-collator", None, collation_future); + let registry = config.prometheus_registry(); + let spawner = task_manager.spawn_essential_handle(); - Ok(()) - }, - hwbench, - ) - .await + Ok(BasicQueue::new(verifier, Box::new(block_import), None, &spawner, registry)) } -/// Start an aura powered parachain node which uses the lookahead collator to support async backing. -/// This node is basic in the sense that its runtime api doesn't include common contents such as -/// transaction payment. Used for aura glutton. -pub async fn start_basic_lookahead_node( +/// Start an aura powered parachain node. Some system chains use this. +pub async fn start_generic_aura_node( parachain_config: Configuration, polkadot_config: Configuration, collator_options: CollatorOptions, para_id: ParaId, hwbench: Option, -) -> sc_service::error::Result<(TaskManager, Arc>)> -where - RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, - RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue - + sp_api::Metadata - + sp_session::SessionKeys - + sp_api::ApiExt - + sp_offchain::OffchainWorkerApi - + sp_block_builder::BlockBuilder - + cumulus_primitives_core::CollectCollationInfo - + sp_consensus_aura::AuraApi::Pair as Pair>::Public> - + frame_rpc_system::AccountNonceApi - + cumulus_primitives_aura::AuraUnincludedSegmentApi, - <::Pair as Pair>::Signature: - TryFrom> + std::hash::Hash + sp_runtime::traits::Member + Codec, -{ - start_basic_lookahead_node_impl::( +) -> sc_service::error::Result<(TaskManager, Arc>)> { + start_node_impl::( parachain_config, polkadot_config, collator_options, CollatorSybilResistance::Resistant, // Aura para_id, - |_| Ok(RpcModule::new(())), - aura_build_import_queue::<_, AuraId>, + build_parachain_rpc_extensions::, + build_relay_to_aura_import_queue::<_, AuraId>, |client, block_import, prometheus_registry, @@ -1826,7 +718,9 @@ where collator_key, overseer_handle, announce_block, - backend| { + _backend| { + let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; + let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( task_manager.spawn_handle(), client.clone(), @@ -1843,29 +737,27 @@ where client.clone(), ); - let params = AuraParams { + let params = BasicAuraParams { create_inherent_data_providers: move |_, ()| async move { Ok(()) }, block_import, - para_client: client.clone(), - para_backend: backend.clone(), + para_client: client, relay_client: relay_chain_interface, - code_hash_provider: move |block_hash| { - client.code_at(block_hash).ok().map(|c| ValidationCode::from(c).hash()) - }, sync_oracle, keystore, collator_key, para_id, overseer_handle, + slot_duration, relay_chain_slot_duration, proposer, collator_service, - authoring_duration: Duration::from_millis(1500), - reinitialize: false, + // Very limited proposal time. + authoring_duration: Duration::from_millis(500), + collation_request_receiver: None, }; let fut = - aura::run::::Pair, _, _, _, _, _, _, _, _, _>(params); + basic_aura::run::::Pair, _, _, _, _, _, _, _>(params); task_manager.spawn_essential_handle().spawn("aura", None, fut); Ok(()) @@ -1875,16 +767,38 @@ where .await } -#[sc_tracing::logging::prefix_logs_with("Parachain")] -async fn start_contracts_rococo_node_impl( +/// Uses the lookahead collator to support async backing. +/// +/// Start an aura powered parachain node. Some system chains use this. +pub async fn start_generic_aura_lookahead_node( + parachain_config: Configuration, + polkadot_config: Configuration, + collator_options: CollatorOptions, + para_id: ParaId, + hwbench: Option, +) -> sc_service::error::Result<(TaskManager, Arc>)> { + start_node_impl::( + parachain_config, + polkadot_config, + collator_options, + CollatorSybilResistance::Resistant, // Aura + para_id, + build_parachain_rpc_extensions::, + build_relay_to_aura_import_queue::<_, AuraId>, + start_lookahead_aura_consensus, + hwbench, + ) + .await +} + +/// Start a shell node which should later transition into an Aura powered parachain node. Asset Hub +/// uses this because at genesis, Asset Hub was on the `shell` runtime which didn't have Aura and +/// needs to sync and upgrade before it can run `AuraApi` functions. +pub async fn start_asset_hub_node( parachain_config: Configuration, polkadot_config: Configuration, collator_options: CollatorOptions, - sybil_resistance_level: CollatorSybilResistance, para_id: ParaId, - _rpc_ext_builder: RB, - build_import_queue: BIQ, - start_consensus: SC, hwbench: Option, ) -> sc_service::error::Result<(TaskManager, Arc>)> where @@ -1896,228 +810,169 @@ where + sp_offchain::OffchainWorkerApi + sp_block_builder::BlockBuilder + cumulus_primitives_core::CollectCollationInfo + + sp_consensus_aura::AuraApi::Pair as Pair>::Public> + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi - + frame_rpc_system::AccountNonceApi - + cumulus_primitives_aura::AuraUnincludedSegmentApi, - RB: Fn(Arc>) -> Result, sc_service::Error>, - BIQ: FnOnce( - Arc>, - ParachainBlockImport, - &Configuration, - Option, - &TaskManager, - ) -> Result, sc_service::Error>, - SC: FnOnce( - Arc>, - ParachainBlockImport, - Option<&Registry>, - Option, - &TaskManager, - Arc, - Arc>>, - Arc>, - KeystorePtr, - Duration, - ParaId, - CollatorPair, - OverseerHandle, - Arc>) + Send + Sync>, - Arc, - ) -> Result<(), sc_service::Error>, + + frame_rpc_system::AccountNonceApi, + <::Pair as Pair>::Signature: + TryFrom> + std::hash::Hash + sp_runtime::traits::Member + Codec, { - let parachain_config = prepare_node_config(parachain_config); - - let params = new_partial::(¶chain_config, build_import_queue)?; - let (block_import, mut telemetry, telemetry_worker_handle) = params.other; - - let client = params.client.clone(); - let backend = params.backend.clone(); - let mut task_manager = params.task_manager; - - let (relay_chain_interface, collator_key) = build_relay_chain_interface( + start_node_impl::( + parachain_config, polkadot_config, - ¶chain_config, - telemetry_worker_handle, - &mut task_manager, - collator_options.clone(), - hwbench.clone(), - ) - .await - .map_err(|e| sc_service::Error::Application(Box::new(e) as Box<_>))?; - - let validator = parachain_config.role.is_authority(); - let prometheus_registry = parachain_config.prometheus_registry().cloned(); - let transaction_pool = params.transaction_pool.clone(); - let import_queue_service = params.import_queue.service(); - let net_config = FullNetworkConfiguration::new(¶chain_config.network); - - let (network, system_rpc_tx, tx_handler_controller, start_network, sync_service) = - build_network(BuildNetworkParams { - parachain_config: ¶chain_config, - net_config, - client: client.clone(), - transaction_pool: transaction_pool.clone(), - para_id, - spawn_handle: task_manager.spawn_handle(), - relay_chain_interface: relay_chain_interface.clone(), - import_queue: params.import_queue, - sybil_resistance_level, - }) - .await?; - - let rpc_builder = { - let client = client.clone(); - let transaction_pool = transaction_pool.clone(); - - Box::new(move |deny_unsafe, _| { - let deps = crate::rpc::FullDeps { - client: client.clone(), - pool: transaction_pool.clone(), - deny_unsafe, - }; - - crate::rpc::create_contracts_rococo(deps).map_err(Into::into) - }) - }; - - sc_service::spawn_tasks(sc_service::SpawnTasksParams { - rpc_builder, - client: client.clone(), - transaction_pool: transaction_pool.clone(), - task_manager: &mut task_manager, - config: parachain_config, - keystore: params.keystore_container.keystore(), - backend: backend.clone(), - network: network.clone(), - sync_service: sync_service.clone(), - system_rpc_tx, - tx_handler_controller, - telemetry: telemetry.as_mut(), - })?; - - if let Some(hwbench) = hwbench { - sc_sysinfo::print_hwbench(&hwbench); - if validator { - warn_if_slow_hardware(&hwbench); - } - - if let Some(ref mut telemetry) = telemetry { - let telemetry_handle = telemetry.handle(); - task_manager.spawn_handle().spawn( - "telemetry_hwbench", - None, - sc_sysinfo::initialize_hwbench_telemetry(telemetry_handle, hwbench), - ); - } - } - - let announce_block = { - let sync_service = sync_service.clone(); - Arc::new(move |hash, data| sync_service.announce_block(hash, data)) - }; - - let relay_chain_slot_duration = Duration::from_secs(6); - - let overseer_handle = relay_chain_interface - .overseer_handle() - .map_err(|e| sc_service::Error::Application(Box::new(e)))?; - - start_relay_chain_tasks(StartRelayChainTasksParams { - client: client.clone(), - announce_block: announce_block.clone(), + collator_options, + CollatorSybilResistance::Resistant, // Aura para_id, - relay_chain_interface: relay_chain_interface.clone(), - task_manager: &mut task_manager, - da_recovery_profile: if validator { - DARecoveryProfile::Collator - } else { - DARecoveryProfile::FullNode - }, - import_queue: import_queue_service, - relay_chain_slot_duration, - recovery_handle: Box::new(overseer_handle.clone()), - sync_service: sync_service.clone(), - })?; + build_parachain_rpc_extensions::, + build_relay_to_aura_import_queue::<_, AuraId>, + |client, + block_import, + prometheus_registry, + telemetry, + task_manager, + relay_chain_interface, + transaction_pool, + sync_oracle, + keystore, + relay_chain_slot_duration, + para_id, + collator_key, + overseer_handle, + announce_block, + _backend| { + let relay_chain_interface2 = relay_chain_interface.clone(); - if validator { - start_consensus( - client.clone(), - block_import, - prometheus_registry.as_ref(), - telemetry.as_ref().map(|t| t.handle()), - &task_manager, - relay_chain_interface.clone(), - transaction_pool, - sync_service.clone(), - params.keystore_container.keystore(), - relay_chain_slot_duration, - para_id, - collator_key.expect("Command line arguments do not allow this. qed"), - overseer_handle, - announce_block, - backend.clone(), - )?; - } + let collator_service = CollatorService::new( + client.clone(), + Arc::new(task_manager.spawn_handle()), + announce_block, + client.clone(), + ); - start_network.start_network(); + let spawner = task_manager.spawn_handle(); - Ok((task_manager, client)) -} + let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( + spawner, + client.clone(), + transaction_pool, + prometheus_registry, + telemetry.clone(), + ); -#[allow(clippy::type_complexity)] -pub fn contracts_rococo_build_import_queue( - client: Arc>, - block_import: ParachainBlockImport, - config: &Configuration, - telemetry: Option, - task_manager: &TaskManager, -) -> Result, sc_service::Error> { - let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; + let collation_future = Box::pin(async move { + // Start collating with the `shell` runtime while waiting for an upgrade to an Aura + // compatible runtime. + let mut request_stream = cumulus_client_collator::relay_chain_driven::init( + collator_key.clone(), + para_id, + overseer_handle.clone(), + ) + .await; + while let Some(request) = request_stream.next().await { + let pvd = request.persisted_validation_data().clone(); + let last_head_hash = + match ::Header::decode(&mut &pvd.parent_head.0[..]) { + Ok(header) => header.hash(), + Err(e) => { + log::error!("Could not decode the head data: {e}"); + request.complete(None); + continue + }, + }; - cumulus_client_consensus_aura::import_queue::< - sp_consensus_aura::sr25519::AuthorityPair, - _, - _, - _, - _, - _, - >(cumulus_client_consensus_aura::ImportQueueParams { - block_import, - client, - create_inherent_data_providers: move |_, _| async move { - let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + // Check if we have upgraded to an Aura compatible runtime and transition if + // necessary. + if client + .runtime_api() + .has_api::>(last_head_hash) + .unwrap_or(false) + { + // Respond to this request before transitioning to Aura. + request.complete(None); + break + } + } - let slot = - sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( - *timestamp, + // Move to Aura consensus. + let slot_duration = match cumulus_client_consensus_aura::slot_duration(&*client) { + Ok(d) => d, + Err(e) => { + log::error!("Could not get Aura slot duration: {e}"); + return + }, + }; + + let proposer = Proposer::new(proposer_factory); + + let params = BasicAuraParams { + create_inherent_data_providers: move |_, ()| async move { Ok(()) }, + block_import, + para_client: client, + relay_client: relay_chain_interface2, + sync_oracle, + keystore, + collator_key, + para_id, + overseer_handle, slot_duration, - ); + relay_chain_slot_duration, + proposer, + collator_service, + // Very limited proposal time. + authoring_duration: Duration::from_millis(500), + collation_request_receiver: Some(request_stream), + }; - Ok((slot, timestamp)) + basic_aura::run::::Pair, _, _, _, _, _, _, _>(params) + .await + }); + + let spawner = task_manager.spawn_essential_handle(); + spawner.spawn_essential("cumulus-asset-hub-collator", None, collation_future); + + Ok(()) }, - registry: config.prometheus_registry(), - spawner: &task_manager.spawn_essential_handle(), - telemetry, - }) - .map_err(Into::into) + hwbench, + ) + .await } -/// Start a parachain node. -pub async fn start_contracts_rococo_node( +/// Start a shell node which should later transition into an Aura powered parachain node. Asset Hub +/// uses this because at genesis, Asset Hub was on the `shell` runtime which didn't have Aura and +/// needs to sync and upgrade before it can run `AuraApi` functions. +/// +/// Uses the lookahead collator to support async backing. +#[sc_tracing::logging::prefix_logs_with("Parachain")] +pub async fn start_asset_hub_lookahead_node( parachain_config: Configuration, polkadot_config: Configuration, collator_options: CollatorOptions, para_id: ParaId, hwbench: Option, -) -> sc_service::error::Result<(TaskManager, Arc>)> { - start_contracts_rococo_node_impl::( +) -> sc_service::error::Result<(TaskManager, Arc>)> +where + RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue + + sp_api::Metadata + + sp_session::SessionKeys + + sp_api::ApiExt + + sp_offchain::OffchainWorkerApi + + sp_block_builder::BlockBuilder + + cumulus_primitives_core::CollectCollationInfo + + sp_consensus_aura::AuraApi::Pair as Pair>::Public> + + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi + + frame_rpc_system::AccountNonceApi + + cumulus_primitives_aura::AuraUnincludedSegmentApi, + <::Pair as Pair>::Signature: + TryFrom> + std::hash::Hash + sp_runtime::traits::Member + Codec, +{ + start_node_impl::( parachain_config, polkadot_config, collator_options, CollatorSybilResistance::Resistant, // Aura para_id, - |_| Ok(RpcModule::new(())), - contracts_rococo_build_import_queue, + build_parachain_rpc_extensions::, + build_relay_to_aura_import_queue::<_, AuraId>, |client, block_import, prometheus_registry, @@ -2133,14 +988,7 @@ pub async fn start_contracts_rococo_node( overseer_handle, announce_block, backend| { - let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( - task_manager.spawn_handle(), - client.clone(), - transaction_pool, - prometheus_registry, - telemetry.clone(), - ); - let proposer = Proposer::new(proposer_factory); + let relay_chain_interface2 = relay_chain_interface.clone(); let collator_service = CollatorService::new( client.clone(), @@ -2149,42 +997,81 @@ pub async fn start_contracts_rococo_node( client.clone(), ); - let params = AuraParams { - create_inherent_data_providers: move |_, ()| async move { Ok(()) }, - block_import, - para_client: client.clone(), - para_backend: backend.clone(), - relay_client: relay_chain_interface, - code_hash_provider: move |block_hash| { - client.code_at(block_hash).ok().map(|c| ValidationCode::from(c).hash()) - }, - sync_oracle, - keystore, - collator_key, - para_id, - overseer_handle, - relay_chain_slot_duration, - proposer, - collator_service, - // Very limited proposal time. - authoring_duration: Duration::from_millis(1500), - reinitialize: false, - }; + let spawner = task_manager.spawn_handle(); - let fut = aura::run::< - Block, - sp_consensus_aura::sr25519::AuthorityPair, - _, - _, - _, - _, - _, - _, - _, - _, - _, - >(params); - task_manager.spawn_essential_handle().spawn("aura", None, fut); + let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( + spawner, + client.clone(), + transaction_pool, + prometheus_registry, + telemetry.clone(), + ); + + let collation_future = Box::pin(async move { + // Start collating with the `shell` runtime while waiting for an upgrade to an Aura + // compatible runtime. + let mut request_stream = cumulus_client_collator::relay_chain_driven::init( + collator_key.clone(), + para_id, + overseer_handle.clone(), + ) + .await; + while let Some(request) = request_stream.next().await { + let pvd = request.persisted_validation_data().clone(); + let last_head_hash = + match ::Header::decode(&mut &pvd.parent_head.0[..]) { + Ok(header) => header.hash(), + Err(e) => { + log::error!("Could not decode the head data: {e}"); + request.complete(None); + continue + }, + }; + + // Check if we have upgraded to an Aura compatible runtime and transition if + // necessary. + if client + .runtime_api() + .has_api::>(last_head_hash) + .unwrap_or(false) + { + // Respond to this request before transitioning to Aura. + request.complete(None); + break + } + } + + // Move to Aura consensus. + let proposer = Proposer::new(proposer_factory); + + let params = AuraParams { + create_inherent_data_providers: move |_, ()| async move { Ok(()) }, + block_import, + para_client: client.clone(), + para_backend: backend, + relay_client: relay_chain_interface2, + code_hash_provider: move |block_hash| { + client.code_at(block_hash).ok().map(|c| ValidationCode::from(c).hash()) + }, + sync_oracle, + keystore, + collator_key, + para_id, + overseer_handle, + relay_chain_slot_duration, + proposer, + collator_service, + authoring_duration: Duration::from_millis(1500), + reinitialize: true, /* we need to always re-initialize for asset-hub moving + * to aura */ + }; + + aura::run::::Pair, _, _, _, _, _, _, _, _, _>(params) + .await + }); + + let spawner = task_manager.spawn_essential_handle(); + spawner.spawn_essential("cumulus-asset-hub-collator", None, collation_future); Ok(()) }, @@ -2193,6 +1080,184 @@ pub async fn start_contracts_rococo_node( .await } +/// Start relay-chain consensus that is free for all. Everyone can submit a block, the relay-chain +/// decides what is backed and included. +fn start_relay_chain_consensus( + client: Arc>, + block_import: ParachainBlockImport, + prometheus_registry: Option<&Registry>, + telemetry: Option, + task_manager: &TaskManager, + relay_chain_interface: Arc, + transaction_pool: Arc>>, + _sync_oracle: Arc>, + _keystore: KeystorePtr, + _relay_chain_slot_duration: Duration, + para_id: ParaId, + collator_key: CollatorPair, + overseer_handle: OverseerHandle, + announce_block: Arc>) + Send + Sync>, + _backend: Arc, +) -> Result<(), sc_service::Error> { + let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( + task_manager.spawn_handle(), + client.clone(), + transaction_pool, + prometheus_registry, + telemetry, + ); + + let free_for_all = cumulus_client_consensus_relay_chain::build_relay_chain_consensus( + cumulus_client_consensus_relay_chain::BuildRelayChainConsensusParams { + para_id, + proposer_factory, + block_import, + relay_chain_interface: relay_chain_interface.clone(), + create_inherent_data_providers: move |_, (relay_parent, validation_data)| { + let relay_chain_interface = relay_chain_interface.clone(); + async move { + let parachain_inherent = + cumulus_client_parachain_inherent::ParachainInherentDataProvider::create_at( + relay_parent, + &relay_chain_interface, + &validation_data, + para_id, + ).await; + let parachain_inherent = parachain_inherent.ok_or_else(|| { + Box::::from( + "Failed to create parachain inherent", + ) + })?; + Ok(parachain_inherent) + } + }, + }, + ); + + let spawner = task_manager.spawn_handle(); + + // Required for free-for-all consensus + #[allow(deprecated)] + old_consensus::start_collator_sync(old_consensus::StartCollatorParams { + para_id, + block_status: client.clone(), + announce_block, + overseer_handle, + spawner, + key: collator_key, + parachain_consensus: free_for_all, + runtime_api: client.clone(), + }); + + Ok(()) +} + +/// Start consensus using the lookahead aura collator. +fn start_lookahead_aura_consensus( + client: Arc>, + block_import: ParachainBlockImport, + prometheus_registry: Option<&Registry>, + telemetry: Option, + task_manager: &TaskManager, + relay_chain_interface: Arc, + transaction_pool: Arc>>, + sync_oracle: Arc>, + keystore: KeystorePtr, + relay_chain_slot_duration: Duration, + para_id: ParaId, + collator_key: CollatorPair, + overseer_handle: OverseerHandle, + announce_block: Arc>) + Send + Sync>, + backend: Arc, +) -> Result<(), sc_service::Error> { + let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( + task_manager.spawn_handle(), + client.clone(), + transaction_pool, + prometheus_registry, + telemetry.clone(), + ); + + let collator_service = CollatorService::new( + client.clone(), + Arc::new(task_manager.spawn_handle()), + announce_block, + client.clone(), + ); + + let params = AuraParams { + create_inherent_data_providers: move |_, ()| async move { Ok(()) }, + block_import, + para_client: client.clone(), + para_backend: backend, + relay_client: relay_chain_interface, + code_hash_provider: move |block_hash| { + client.code_at(block_hash).ok().map(|c| ValidationCode::from(c).hash()) + }, + sync_oracle, + keystore, + collator_key, + para_id, + overseer_handle, + relay_chain_slot_duration, + proposer: Proposer::new(proposer_factory), + collator_service, + authoring_duration: Duration::from_millis(1500), + reinitialize: false, + }; + + let fut = aura::run::::Pair, _, _, _, _, _, _, _, _, _>(params); + task_manager.spawn_essential_handle().spawn("aura", None, fut); + + Ok(()) +} + +/// Start an aura powered parachain node which uses the lookahead collator to support async backing. +/// This node is basic in the sense that its runtime api doesn't include common contents such as +/// transaction payment. Used for aura glutton. +pub async fn start_basic_lookahead_node( + parachain_config: Configuration, + polkadot_config: Configuration, + collator_options: CollatorOptions, + para_id: ParaId, + hwbench: Option, +) -> sc_service::error::Result<(TaskManager, Arc>)> { + start_node_impl::( + parachain_config, + polkadot_config, + collator_options, + CollatorSybilResistance::Resistant, // Aura + para_id, + |_, _, _, _| Ok(RpcModule::new(())), + build_relay_to_aura_import_queue::<_, AuraId>, + start_lookahead_aura_consensus, + hwbench, + ) + .await +} + +/// Start a parachain node for Rococo Contracts. +pub async fn start_contracts_rococo_node( + parachain_config: Configuration, + polkadot_config: Configuration, + collator_options: CollatorOptions, + para_id: ParaId, + hwbench: Option, +) -> sc_service::error::Result<(TaskManager, Arc>)> { + start_node_impl::( + parachain_config, + polkadot_config, + collator_options, + CollatorSybilResistance::Resistant, // Aura + para_id, + build_contracts_rpc_extensions, + build_aura_import_queue, + start_lookahead_aura_consensus, + hwbench, + ) + .await +} + /// Checks that the hardware meets the requirements and print a warning otherwise. fn warn_if_slow_hardware(hwbench: &sc_sysinfo::HwBench) { // Polkadot para-chains should generally use these requirements to ensure that the relay-chain -- GitLab From f977c211573e65b9f89886e7211e9b3148ce7e05 Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Fri, 8 Mar 2024 10:48:55 +0100 Subject: [PATCH 369/392] Contracts Bump ApiVersion and add test (#3619) ApiVersion should have been bumped with https://github.com/paritytech/polkadot-sdk/pull/3606 this does that and add a test so we don't forget to do that everytime --- substrate/frame/contracts/proc-macro/src/lib.rs | 5 +++++ substrate/frame/contracts/src/lib.rs | 11 ++++++++++- substrate/frame/contracts/src/wasm/mod.rs | 3 +++ substrate/frame/contracts/src/wasm/runtime.rs | 1 - 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/substrate/frame/contracts/proc-macro/src/lib.rs b/substrate/frame/contracts/proc-macro/src/lib.rs index de961776c32..1794d09d5ad 100644 --- a/substrate/frame/contracts/proc-macro/src/lib.rs +++ b/substrate/frame/contracts/proc-macro/src/lib.rs @@ -497,9 +497,14 @@ fn expand_docs(def: &EnvDef) -> TokenStream2 { fn expand_env(def: &EnvDef, docs: bool) -> TokenStream2 { let impls = expand_impls(def); let docs = docs.then_some(expand_docs(def)).unwrap_or(TokenStream2::new()); + let stable_api_count = def.host_funcs.iter().filter(|f| f.is_stable).count(); quote! { pub struct Env; + + #[cfg(test)] + pub const STABLE_API_COUNT: usize = #stable_api_count; + #impls /// Documentation of the API (host functions) available to contracts. /// diff --git a/substrate/frame/contracts/src/lib.rs b/substrate/frame/contracts/src/lib.rs index 0511bcf7f3f..de84d5220c5 100644 --- a/substrate/frame/contracts/src/lib.rs +++ b/substrate/frame/contracts/src/lib.rs @@ -222,10 +222,19 @@ pub struct Environment { pub struct ApiVersion(u16); impl Default for ApiVersion { fn default() -> Self { - Self(1) + Self(2) } } +#[test] +fn api_version_is_up_to_date() { + assert_eq!( + 109, + crate::wasm::STABLE_API_COUNT, + "Stable API count has changed. Bump the returned value of ApiVersion::default() and update the test." + ); +} + #[frame_support::pallet] pub mod pallet { use super::*; diff --git a/substrate/frame/contracts/src/wasm/mod.rs b/substrate/frame/contracts/src/wasm/mod.rs index 23363780b14..af287a6f2df 100644 --- a/substrate/frame/contracts/src/wasm/mod.rs +++ b/substrate/frame/contracts/src/wasm/mod.rs @@ -21,6 +21,9 @@ mod prepare; mod runtime; +#[cfg(test)] +pub use runtime::STABLE_API_COUNT; + #[cfg(doc)] pub use crate::wasm::runtime::api_doc; diff --git a/substrate/frame/contracts/src/wasm/runtime.rs b/substrate/frame/contracts/src/wasm/runtime.rs index 402ff78dcde..7d43d30ba58 100644 --- a/substrate/frame/contracts/src/wasm/runtime.rs +++ b/substrate/frame/contracts/src/wasm/runtime.rs @@ -987,7 +987,6 @@ impl<'a, E: Ext + 'a> Runtime<'a, E> { // for every function. #[define_env(doc)] pub mod env { - /// Set the value at the given key in the contract storage. /// See [`pallet_contracts_uapi::HostFn::set_storage`] #[prefixed_alias] -- GitLab From 6f3caac0517278f0fdd614545c9ef620200bc02f Mon Sep 17 00:00:00 2001 From: Alexandru Gheorghe <49718502+alexggh@users.noreply.github.com> Date: Fri, 8 Mar 2024 14:10:47 +0200 Subject: [PATCH 370/392] collator-protocol: Always stay connected to validators in backing group (#3544) Looking at rococo-asset-hub https://github.com/paritytech/polkadot-sdk/issues/3519 there seems to be a lot of instances where collator did not advertise their collations, while there are multiple problems there, one of it is that we are connecting and disconnecting to our assigned validators every block, because on reconnect_timeout every 4s we call connect_to_validators and that will produce 0 validators when all went well, so set_reseverd_peers called from validator discovery will disconnect all our peers. More details here: https://github.com/paritytech/polkadot-sdk/issues/3519#issuecomment-1972667343 Now, this shouldn't be a problem, but it stacks with an existing bug in our network stack where if disconnect from a peer the peer might not notice it, so it won't detect the reconnect either and it won't send us the necessary view updates, so we won't advertise the collation to it more details here: https://github.com/paritytech/polkadot-sdk/issues/3519#issuecomment-1972958276 To avoid hitting this condition that often, let's keep the peers in the reserved set for the entire duration we are allocated to a backing group. Backing group sizes(1 rococo, 3 kusama, 5 polkadot) are really small, so this shouldn't lead to that many connections. Additionally, the validators would disconnect us any way if we don't advertise anything for 4 blocks. ## TODO - [x] More testing. - [x] Confirm on rococo that this is improving the situation. (It doesn't but just because other things are going wrong there). --------- Signed-off-by: Alexandru Gheorghe --- .../src/collator_side/validators_buffer.rs | 38 +++++++++++++++---- .../src/validator_side/mod.rs | 2 +- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/polkadot/node/network/collator-protocol/src/collator_side/validators_buffer.rs b/polkadot/node/network/collator-protocol/src/collator_side/validators_buffer.rs index 5b88efc99d8..1533f2eda5a 100644 --- a/polkadot/node/network/collator-protocol/src/collator_side/validators_buffer.rs +++ b/polkadot/node/network/collator-protocol/src/collator_side/validators_buffer.rs @@ -90,8 +90,7 @@ impl ValidatorGroupsBuffer { } } - /// Returns discovery ids of validators we have at least one advertised-but-not-fetched - /// collation for. + /// Returns discovery ids of validators we are assigned to in this backing group window. pub fn validators_to_connect(&self) -> Vec { let validators_num = self.validators.len(); let bits = self @@ -99,11 +98,22 @@ impl ValidatorGroupsBuffer { .values() .fold(bitvec![0; validators_num], |acc, next| acc | next); - self.validators + let mut should_be_connected: Vec = self + .validators .iter() .enumerate() .filter_map(|(idx, authority_id)| bits[idx].then_some(authority_id.clone())) - .collect() + .collect(); + + if let Some(last_group) = self.group_infos.iter().last() { + for validator in self.validators.iter().rev().take(last_group.len) { + if !should_be_connected.contains(validator) { + should_be_connected.push(validator.clone()); + } + } + } + + should_be_connected } /// Note a new advertisement, marking that we want to be connected to validators @@ -279,7 +289,7 @@ mod tests { assert_eq!(buf.validators_to_connect(), validators[..2].to_vec()); buf.reset_validator_interest(hash_a, &validators[1]); - assert_eq!(buf.validators_to_connect(), vec![validators[0].clone()]); + assert_eq!(buf.validators_to_connect(), validators[0..2].to_vec()); buf.note_collation_advertised(hash_b, 0, GroupIndex(1), &validators[2..]); assert_eq!(buf.validators_to_connect(), validators[2..].to_vec()); @@ -287,7 +297,11 @@ mod tests { for validator in &validators[2..] { buf.reset_validator_interest(hash_b, validator); } - assert!(buf.validators_to_connect().is_empty()); + let mut expected = validators[2..].to_vec(); + expected.sort(); + let mut result = buf.validators_to_connect(); + result.sort(); + assert_eq!(result, expected); } #[test] @@ -320,10 +334,18 @@ mod tests { } buf.reset_validator_interest(hashes[1], &validators[0]); - assert_eq!(buf.validators_to_connect(), validators[..2].to_vec()); + let mut expected: Vec<_> = validators[..4].iter().cloned().collect(); + let mut result = buf.validators_to_connect(); + expected.sort(); + result.sort(); + assert_eq!(result, expected); buf.reset_validator_interest(hashes[0], &validators[0]); - assert_eq!(buf.validators_to_connect(), vec![validators[1].clone()]); + let mut expected: Vec<_> = validators[1..4].iter().cloned().collect(); + expected.sort(); + let mut result = buf.validators_to_connect(); + result.sort(); + assert_eq!(result, expected); buf.note_collation_advertised(hashes[3], 0, GroupIndex(1), &validators[2..4]); buf.note_collation_advertised( diff --git a/polkadot/node/network/collator-protocol/src/validator_side/mod.rs b/polkadot/node/network/collator-protocol/src/validator_side/mod.rs index 48ad3c711a6..a1b93fff348 100644 --- a/polkadot/node/network/collator-protocol/src/validator_side/mod.rs +++ b/polkadot/node/network/collator-protocol/src/validator_side/mod.rs @@ -1883,7 +1883,7 @@ async fn disconnect_inactive_peers( ) { for (peer, peer_data) in peers { if peer_data.is_inactive(&eviction_policy) { - gum::trace!(target: LOG_TARGET, "Disconnecting inactive peer"); + gum::trace!(target: LOG_TARGET, ?peer, "Disconnecting inactive peer"); disconnect_peer(sender, *peer).await; } } -- GitLab From a0c9a3d65adb63d83afdf5b29d2e555dea0fa35e Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Fri, 8 Mar 2024 17:36:09 +0100 Subject: [PATCH 371/392] benchmark: allow range trailing comma in RangeArgs (#3598) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rustfmt will add a trailing comma for longer expression, this change will make sure that the Range parameters can still be parsed. --------- Co-authored-by: command-bot <> Co-authored-by: Alexander Theißen --- substrate/frame/support/procedural/src/benchmark.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/substrate/frame/support/procedural/src/benchmark.rs b/substrate/frame/support/procedural/src/benchmark.rs index d16ad2aaa51..27c75a7f054 100644 --- a/substrate/frame/support/procedural/src/benchmark.rs +++ b/substrate/frame/support/procedural/src/benchmark.rs @@ -65,6 +65,7 @@ struct RangeArgs { start: syn::GenericArgument, _comma: Comma, end: syn::GenericArgument, + _trailing_comma: Option, _gt_token: Gt, } -- GitLab From 1fe3c5f23b9c057a2ff1926daf4ecfd5b022da45 Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Fri, 8 Mar 2024 19:13:31 +0100 Subject: [PATCH 372/392] Contracts: Fix terminate benchmark (#3558) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Alexander Theißen Co-authored-by: command-bot <> --- substrate/frame/contracts/src/benchmarking/mod.rs | 3 ++- substrate/frame/contracts/src/storage.rs | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/substrate/frame/contracts/src/benchmarking/mod.rs b/substrate/frame/contracts/src/benchmarking/mod.rs index 2ecd56b412d..794777ef05c 100644 --- a/substrate/frame/contracts/src/benchmarking/mod.rs +++ b/substrate/frame/contracts/src/benchmarking/mod.rs @@ -927,7 +927,7 @@ benchmarks! { value: code_hashes_bytes, }, ], - deploy_body: Some(body::repeated_dyn(r, vec![ + deploy_body: Some(body::repeated_dyn(T::MaxDelegateDependencies::get(), vec![ Counter(beneficiary_len as u32, code_hash_len as u32), // code_hash_ptr Regular(Instruction::Call(1)), ])), @@ -943,6 +943,7 @@ benchmarks! { assert_eq!(T::Currency::total_balance(&beneficiary), 0u32.into()); assert_eq!(T::Currency::balance(&instance.account_id), Pallet::::min_balance() * 2u32.into()); assert_ne!(T::Currency::balance_on_hold(&HoldReason::StorageDepositReserve.into(), &instance.account_id), 0u32.into()); + assert_eq!(ContractInfoOf::::get(&instance.account_id).unwrap().delegate_dependencies_count() as u32, T::MaxDelegateDependencies::get()); }: call(origin, instance.addr.clone(), 0u32.into(), Weight::MAX, None, vec![]) verify { if r > 0 { diff --git a/substrate/frame/contracts/src/storage.rs b/substrate/frame/contracts/src/storage.rs index 52c5150ca21..e99afd5d42e 100644 --- a/substrate/frame/contracts/src/storage.rs +++ b/substrate/frame/contracts/src/storage.rs @@ -108,6 +108,11 @@ impl ContractInfo { Ok(contract) } + /// Returns the number of locked delegate dependencies. + pub fn delegate_dependencies_count(&self) -> usize { + self.delegate_dependencies.len() + } + /// Associated child trie unique id is built from the hash part of the trie id. pub fn child_trie_info(&self) -> ChildInfo { ChildInfo::new_default(self.trie_id.as_ref()) -- GitLab From ea458d0b95d819d31683a8a09ca7973ae10b49be Mon Sep 17 00:00:00 2001 From: cuinix <65650185+cuinix@users.noreply.github.com> Date: Sat, 9 Mar 2024 05:28:04 +0800 Subject: [PATCH 373/392] fix some typos (#3587) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: cuinix <915115094@qq.com> Co-authored-by: Bastian Köcher --- bridges/primitives/test-utils/src/lib.rs | 2 +- cumulus/client/parachain-inherent/src/lib.rs | 4 ++-- .../parachains/integration-tests/emulated/common/src/impls.rs | 2 +- .../runtimes/coretime/coretime-rococo/src/xcm_config.rs | 2 +- .../runtimes/coretime/coretime-westend/src/xcm_config.rs | 2 +- .../runtimes/people/people-rococo/src/xcm_config.rs | 2 +- .../runtimes/people/people-westend/src/xcm_config.rs | 2 +- polkadot/cli/src/cli.rs | 2 +- polkadot/node/core/dispute-coordinator/src/initialized.rs | 2 +- polkadot/node/core/pvf-checker/src/lib.rs | 4 ++-- polkadot/node/subsystem-bench/README.md | 4 ++-- polkadot/node/subsystem-bench/src/lib/availability/mod.rs | 2 +- polkadot/node/subsystem-bench/src/lib/mock/av_store.rs | 2 +- polkadot/node/subsystem-bench/src/lib/network.rs | 4 ++-- polkadot/primitives/src/v6/slashing.rs | 2 +- polkadot/runtime/parachains/src/paras/mod.rs | 2 +- substrate/bin/node/cli/src/cli.rs | 2 +- templates/parachain/node/src/cli.rs | 2 +- templates/solochain/node/src/cli.rs | 2 +- 19 files changed, 23 insertions(+), 23 deletions(-) diff --git a/bridges/primitives/test-utils/src/lib.rs b/bridges/primitives/test-utils/src/lib.rs index f23ddd1a10d..1d80890779b 100644 --- a/bridges/primitives/test-utils/src/lib.rs +++ b/bridges/primitives/test-utils/src/lib.rs @@ -129,7 +129,7 @@ pub fn make_justification_for_header( votes_ancestries.push(child.clone()); } - // The header we need to use when pre-commiting is the one at the highest height + // The header we need to use when pre-committing is the one at the highest height // on our chain. let precommit_candidate = chain.last().map(|h| (h.hash(), *h.number())).unwrap(); unsigned_precommits.push(precommit_candidate); diff --git a/cumulus/client/parachain-inherent/src/lib.rs b/cumulus/client/parachain-inherent/src/lib.rs index 57353638e19..051eb6764c8 100644 --- a/cumulus/client/parachain-inherent/src/lib.rs +++ b/cumulus/client/parachain-inherent/src/lib.rs @@ -159,7 +159,7 @@ impl ParachainInherentDataProvider { target: LOG_TARGET, relay_parent = ?relay_parent, error = ?e, - "An error occured during requesting the downward messages.", + "An error occurred during requesting the downward messages.", ); }) .ok()?; @@ -171,7 +171,7 @@ impl ParachainInherentDataProvider { target: LOG_TARGET, relay_parent = ?relay_parent, error = ?e, - "An error occured during requesting the inbound HRMP messages.", + "An error occurred during requesting the inbound HRMP messages.", ); }) .ok()?; diff --git a/cumulus/parachains/integration-tests/emulated/common/src/impls.rs b/cumulus/parachains/integration-tests/emulated/common/src/impls.rs index 4bbb4701e43..c93484829fe 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/impls.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/impls.rs @@ -265,7 +265,7 @@ macro_rules! impl_assert_events_helpers_for_relay_chain { $crate::impls::assert_expected_events!( Self, vec![ - // XCM is succesfully received and proccessed + // XCM is successfully received and proccessed [<$chain RuntimeEvent>]::::MessageQueue($crate::impls::pallet_message_queue::Event::Processed { origin: $crate::impls::AggregateMessageOrigin::Ump($crate::impls::UmpQueueId::Para(id)), weight_used, diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs index 37bb8809dab..1722e1fcb31 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs @@ -192,7 +192,7 @@ pub type Barrier = TrailingSetTopicAsId< AllowKnownQueryResponses, WithComputedOrigin< ( - // If the message is one that immediately attemps to pay for execution, then + // If the message is one that immediately attempts to pay for execution, then // allow it. AllowTopLevelPaidExecutionFrom, // Parent and its pluralities (i.e. governance bodies) get free execution. diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs index 44049adf027..b03c7748fe0 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs @@ -198,7 +198,7 @@ pub type Barrier = TrailingSetTopicAsId< AllowKnownQueryResponses, WithComputedOrigin< ( - // If the message is one that immediately attemps to pay for execution, then + // If the message is one that immediately attempts to pay for execution, then // allow it. AllowTopLevelPaidExecutionFrom, // Parent, its pluralities (i.e. governance bodies), and the Fellows plurality diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs index 311128a17ca..534d6519086 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs @@ -207,7 +207,7 @@ pub type Barrier = TrailingSetTopicAsId< AllowKnownQueryResponses, WithComputedOrigin< ( - // If the message is one that immediately attemps to pay for execution, then + // If the message is one that immediately attempts to pay for execution, then // allow it. AllowTopLevelPaidExecutionFrom, // Parent and its pluralities (i.e. governance bodies) get free execution. diff --git a/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs index 4b7da91c17e..6353a581352 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs @@ -214,7 +214,7 @@ pub type Barrier = TrailingSetTopicAsId< AllowKnownQueryResponses, WithComputedOrigin< ( - // If the message is one that immediately attemps to pay for execution, then + // If the message is one that immediately attempts to pay for execution, then // allow it. AllowTopLevelPaidExecutionFrom, // Parent, its pluralities (i.e. governance bodies), and the Fellows plurality diff --git a/polkadot/cli/src/cli.rs b/polkadot/cli/src/cli.rs index 30f35ebcb6f..e1bc2309a94 100644 --- a/polkadot/cli/src/cli.rs +++ b/polkadot/cli/src/cli.rs @@ -52,7 +52,7 @@ pub enum Subcommand { /// Try-runtime has migrated to a standalone CLI /// (). The subcommand exists as a stub and - /// deprecation notice. It will be removed entirely some time after Janurary 2024. + /// deprecation notice. It will be removed entirely some time after January 2024. TryRuntime, /// Key management CLI utilities diff --git a/polkadot/node/core/dispute-coordinator/src/initialized.rs b/polkadot/node/core/dispute-coordinator/src/initialized.rs index 54e0410268f..5f86da87f21 100644 --- a/polkadot/node/core/dispute-coordinator/src/initialized.rs +++ b/polkadot/node/core/dispute-coordinator/src/initialized.rs @@ -99,7 +99,7 @@ pub(crate) struct Initialized { /// This is the highest `SessionIndex` seen via `ActiveLeavesUpdate`. It doesn't matter if it /// was cached successfully or not. It is used to detect ancient disputes. highest_session_seen: SessionIndex, - /// Will be set to `true` if an error occured during the last caching attempt + /// Will be set to `true` if an error occurred during the last caching attempt gaps_in_cache: bool, spam_slots: SpamSlots, participation: Participation, diff --git a/polkadot/node/core/pvf-checker/src/lib.rs b/polkadot/node/core/pvf-checker/src/lib.rs index ae0fae6b4f9..c00ec0d952f 100644 --- a/polkadot/node/core/pvf-checker/src/lib.rs +++ b/polkadot/node/core/pvf-checker/src/lib.rs @@ -415,7 +415,7 @@ async fn check_signing_credentials( gum::warn!( target: LOG_TARGET, relay_parent = ?leaf, - "error occured during requesting validators: {:?}", + "error occurred during requesting validators: {:?}", e ); return None @@ -508,7 +508,7 @@ async fn sign_and_submit_pvf_check_statement( target: LOG_TARGET, ?relay_parent, ?validation_code_hash, - "error occured during submitting a vote: {:?}", + "error occurred during submitting a vote: {:?}", e, ); }, diff --git a/polkadot/node/subsystem-bench/README.md b/polkadot/node/subsystem-bench/README.md index 3aac2810ad5..94a449ed0bb 100644 --- a/polkadot/node/subsystem-bench/README.md +++ b/polkadot/node/subsystem-bench/README.md @@ -45,7 +45,7 @@ docker compose up Please follow the [official installation guide](https://prometheus.io/docs/prometheus/latest/installation/) for your platform/OS. -After succesfully installing and starting up Prometheus, we need to alter it's configuration such that it +After successfully installing and starting up Prometheus, we need to alter it's configuration such that it will scrape the benchmark prometheus endpoint `127.0.0.1:9999`. Please check the prometheus official documentation regarding the location of `prometheus.yml`. On MacOS for example the full path `/opt/homebrew/etc/prometheus.yml` @@ -211,7 +211,7 @@ You can select log target, subtarget and verbosity just like with Polkadot node ### View test metrics -Assuming the Grafana/Prometheus stack installation steps completed succesfully, you should be able to +Assuming the Grafana/Prometheus stack installation steps completed successfully, you should be able to view the test progress in real time by accessing [this link](http://localhost:3000/goto/SM5B8pNSR?orgId=1). Now run diff --git a/polkadot/node/subsystem-bench/src/lib/availability/mod.rs b/polkadot/node/subsystem-bench/src/lib/availability/mod.rs index f012a5a907e..dc4e1e40310 100644 --- a/polkadot/node/subsystem-bench/src/lib/availability/mod.rs +++ b/polkadot/node/subsystem-bench/src/lib/availability/mod.rs @@ -598,7 +598,7 @@ pub async fn benchmark_availability_write( gum::info!(target: LOG_TARGET, "Waiting for all emulated peers to receive their chunk from us ..."); for receiver in receivers.into_iter() { - let response = receiver.await.expect("Chunk is always served succesfully"); + let response = receiver.await.expect("Chunk is always served successfully"); // TODO: check if chunk is the one the peer expects to receive. assert!(response.result.is_ok()); } diff --git a/polkadot/node/subsystem-bench/src/lib/mock/av_store.rs b/polkadot/node/subsystem-bench/src/lib/mock/av_store.rs index 41c4fe2cbad..9064f17940f 100644 --- a/polkadot/node/subsystem-bench/src/lib/mock/av_store.rs +++ b/polkadot/node/subsystem-bench/src/lib/mock/av_store.rs @@ -97,7 +97,7 @@ impl HandleNetworkMessage for NetworkAvailabilityState { outgoing_request .pending_response .send(response) - .expect("Response is always sent succesfully"); + .expect("Response is always sent successfully"); None }, _ => Some(NetworkMessage::RequestFromNode(peer, request)), diff --git a/polkadot/node/subsystem-bench/src/lib/network.rs b/polkadot/node/subsystem-bench/src/lib/network.rs index 1e09441792d..1bc35a014ff 100644 --- a/polkadot/node/subsystem-bench/src/lib/network.rs +++ b/polkadot/node/subsystem-bench/src/lib/network.rs @@ -219,7 +219,7 @@ impl Future for ProxiedRequest { Poll::Ready(response) => Poll::Ready(ProxiedResponse { sender: self.sender.take().expect("sender already used"), result: response - .expect("Response is always succesfully received.") + .expect("Response is always successfully received.") .result .map_err(|_| RequestFailure::Refused), }), @@ -761,7 +761,7 @@ pub fn new_network( gum::info!(target: LOG_TARGET, "{}",format!("connectivity {}%, latency {:?}", config.connectivity, config.latency).bright_black()); let metrics = - Metrics::new(&dependencies.registry).expect("Metrics always register succesfully"); + Metrics::new(&dependencies.registry).expect("Metrics always register successfully"); let mut validator_authority_id_mapping = HashMap::new(); // Create the channel from `peer` to `NetworkInterface` . diff --git a/polkadot/primitives/src/v6/slashing.rs b/polkadot/primitives/src/v6/slashing.rs index efffb932cdc..bcd7d0c2fc4 100644 --- a/polkadot/primitives/src/v6/slashing.rs +++ b/polkadot/primitives/src/v6/slashing.rs @@ -54,7 +54,7 @@ impl DisputesTimeSlot { /// is required to identify and verify it. #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, Debug)] pub struct DisputeProof { - /// Time slot when the dispute occured. + /// Time slot when the dispute occurred. pub time_slot: DisputesTimeSlot, /// The dispute outcome. pub kind: SlashingOffenceKind, diff --git a/polkadot/runtime/parachains/src/paras/mod.rs b/polkadot/runtime/parachains/src/paras/mod.rs index 39371391b1f..5acdb9683bb 100644 --- a/polkadot/runtime/parachains/src/paras/mod.rs +++ b/polkadot/runtime/parachains/src/paras/mod.rs @@ -1374,7 +1374,7 @@ impl Pallet { outgoing } - // note replacement of the code of para with given `id`, which occured in the + // note replacement of the code of para with given `id`, which occurred in the // context of the given relay-chain block number. provide the replaced code. // // `at` for para-triggered replacement is the block number of the relay-chain diff --git a/substrate/bin/node/cli/src/cli.rs b/substrate/bin/node/cli/src/cli.rs index f3c0435fd32..3345afae4fd 100644 --- a/substrate/bin/node/cli/src/cli.rs +++ b/substrate/bin/node/cli/src/cli.rs @@ -63,7 +63,7 @@ pub enum Subcommand { /// Try-runtime has migrated to a standalone CLI /// (). The subcommand exists as a stub and - /// deprecation notice. It will be removed entirely some time after Janurary 2024. + /// deprecation notice. It will be removed entirely some time after January 2024. TryRuntime, /// Key management cli utilities diff --git a/templates/parachain/node/src/cli.rs b/templates/parachain/node/src/cli.rs index 73ef996b750..a5c55b8118a 100644 --- a/templates/parachain/node/src/cli.rs +++ b/templates/parachain/node/src/cli.rs @@ -40,7 +40,7 @@ pub enum Subcommand { /// Try-runtime has migrated to a standalone /// [CLI](). The subcommand exists as a stub and - /// deprecation notice. It will be removed entirely some time after Janurary 2024. + /// deprecation notice. It will be removed entirely some time after January 2024. TryRuntime, } diff --git a/templates/solochain/node/src/cli.rs b/templates/solochain/node/src/cli.rs index 98037eb886a..7f1b67b3696 100644 --- a/templates/solochain/node/src/cli.rs +++ b/templates/solochain/node/src/cli.rs @@ -43,7 +43,7 @@ pub enum Subcommand { /// Try-runtime has migrated to a standalone CLI /// (). The subcommand exists as a stub and - /// deprecation notice. It will be removed entirely some time after Janurary 2024. + /// deprecation notice. It will be removed entirely some time after January 2024. TryRuntime, /// Db meta columns information. -- GitLab From 9f5d9fa96f88007292c2d59810b7c3c855da58a7 Mon Sep 17 00:00:00 2001 From: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Date: Sat, 9 Mar 2024 11:14:06 +0100 Subject: [PATCH 374/392] core: replace secp256k with k256 in crypto::ecdsa (#3525) This PR replaces the usage of [secp256k](https://crates.io/crates/secp256k1) crate with [k256](https://crates.io/crates/k256) in `core::crypto::ecdsa` for `non-std` environments as outcome of discussion in #3448. `secp256k1` is used in `std`, meaning that we should not affect host performance with this PR. `k256` is enabled in runtimes (`no-std`), and is required to proceed with #2044. If desirable, in future we can switch to `k256` also for `std`. That would require some performance evaluation (e.g. for EVM chains as per https://github.com/paritytech/polkadot-sdk/issues/3448#issuecomment-1976780391). Closes https://github.com/paritytech/polkadot-sdk/issues/3448 --------- Co-authored-by: command-bot <> Co-authored-by: Davide Galassi --- Cargo.lock | 27 ++++- substrate/primitives/core/Cargo.toml | 9 +- substrate/primitives/core/src/ecdsa.rs | 145 +++++++++++++++++-------- 3 files changed, 129 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e38f09db4d3..0b7ea71a536 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4815,6 +4815,7 @@ dependencies = [ "digest 0.10.7", "elliptic-curve", "rfc6979", + "serdect", "signature", "spki", ] @@ -4881,9 +4882,9 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.13.5" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", @@ -4894,6 +4895,7 @@ dependencies = [ "pkcs8", "rand_core 0.6.4", "sec1", + "serdect", "subtle 2.5.0", "zeroize", ] @@ -6971,14 +6973,15 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", "once_cell", + "serdect", "sha2 0.10.7", ] @@ -17101,6 +17104,7 @@ dependencies = [ "der", "generic-array 0.14.7", "pkcs8", + "serdect", "subtle 2.5.0", "zeroize", ] @@ -17359,6 +17363,16 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct", + "serde", +] + [[package]] name = "serial_test" version = "2.0.0" @@ -18567,6 +18581,7 @@ dependencies = [ "hash256-std-hasher", "impl-serde", "itertools 0.10.5", + "k256", "lazy_static", "libsecp256k1", "log", @@ -22553,9 +22568,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" dependencies = [ "zeroize_derive", ] diff --git a/substrate/primitives/core/Cargo.toml b/substrate/primitives/core/Cargo.toml index 70ca7be6a2d..f7cc2b4fcf7 100644 --- a/substrate/primitives/core/Cargo.toml +++ b/substrate/primitives/core/Cargo.toml @@ -52,9 +52,12 @@ blake2 = { version = "0.10.4", default-features = false, optional = true } libsecp256k1 = { version = "0.7", default-features = false, features = ["static-context"], optional = true } schnorrkel = { version = "0.11.4", features = ["preaudit_deprecated"], default-features = false } merlin = { version = "3.0", default-features = false } -secp256k1 = { version = "0.28.0", default-features = false, features = ["alloc", "recovery"], optional = true } sp-crypto-hashing = { path = "../crypto/hashing", default-features = false, optional = true } sp-runtime-interface = { path = "../runtime-interface", default-features = false } +# k256 crate, better portability, intended to be used in substrate-runtimes (no-std) +k256 = { version = "0.13.3", features = ["alloc", "ecdsa"], default-features = false } +# secp256k1 crate, better performance, intended to be used on host side (std) +secp256k1 = { version = "0.28.0", default-features = false, features = ["alloc", "recovery"], optional = true } # bls crypto w3f-bls = { version = "0.1.3", default-features = false, optional = true } @@ -76,6 +79,7 @@ bench = false [features] default = ["std"] + std = [ "array-bytes", "bandersnatch_vrfs?/std", @@ -94,6 +98,7 @@ std = [ "hash256-std-hasher/std", "impl-serde/std", "itertools", + "k256/std", "libsecp256k1/std", "log/std", "merlin/std", @@ -132,6 +137,7 @@ serde = [ "bs58/alloc", "dep:serde", "impl-serde", + "k256/serde", "primitive-types/serde_no_std", "scale-info/serde", "secrecy/alloc", @@ -147,7 +153,6 @@ full_crypto = [ "blake2", "ed25519-zebra", "libsecp256k1", - "secp256k1", "sp-crypto-hashing", "sp-runtime-interface/disable_target_static_assertions", ] diff --git a/substrate/primitives/core/src/ecdsa.rs b/substrate/primitives/core/src/ecdsa.rs index f172b3a7d02..e6bd2c7eb57 100644 --- a/substrate/primitives/core/src/ecdsa.rs +++ b/substrate/primitives/core/src/ecdsa.rs @@ -28,14 +28,15 @@ use crate::crypto::{ }; #[cfg(feature = "full_crypto")] use crate::crypto::{DeriveError, DeriveJunction, Pair as TraitPair, SecretStringError}; -#[cfg(all(feature = "full_crypto", not(feature = "std")))] -use secp256k1::Secp256k1; -#[cfg(feature = "std")] -use secp256k1::SECP256K1; -#[cfg(feature = "full_crypto")] + +#[cfg(all(not(feature = "std"), feature = "full_crypto"))] +use k256::ecdsa::SigningKey as SecretKey; +#[cfg(not(feature = "std"))] +use k256::ecdsa::VerifyingKey; +#[cfg(all(feature = "std", feature = "full_crypto"))] use secp256k1::{ ecdsa::{RecoverableSignature, RecoveryId}, - Message, PublicKey, SecretKey, + Message, PublicKey, SecretKey, SECP256K1, }; #[cfg(feature = "serde")] use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; @@ -53,9 +54,9 @@ pub const PUBLIC_KEY_SERIALIZED_SIZE: usize = 33; /// The byte length of signature pub const SIGNATURE_SERIALIZED_SIZE: usize = 65; -/// A secret seed (which is bytewise essentially equivalent to a SecretKey). +/// The secret seed. /// -/// We need it as a different type because `Seed` is expected to be AsRef<[u8]>. +/// The raw secret seed, which can be used to create the `Pair`. #[cfg(feature = "full_crypto")] type Seed = [u8; 32]; @@ -96,18 +97,21 @@ impl Public { /// Create a new instance from the given full public key. /// /// This will convert the full public key into the compressed format. - #[cfg(feature = "std")] pub fn from_full(full: &[u8]) -> Result { - let pubkey = if full.len() == 64 { + let mut tagged_full = [0u8; 65]; + let full = if full.len() == 64 { // Tag it as uncompressed public key. - let mut tagged_full = [0u8; 65]; tagged_full[0] = 0x04; tagged_full[1..].copy_from_slice(full); - secp256k1::PublicKey::from_slice(&tagged_full) + &tagged_full } else { - secp256k1::PublicKey::from_slice(full) + full }; - pubkey.map(|k| Self(k.serialize())).map_err(|_| ()) + #[cfg(feature = "std")] + let pubkey = PublicKey::from_slice(&full); + #[cfg(not(feature = "std"))] + let pubkey = VerifyingKey::from_sec1_bytes(&full); + pubkey.map(|k| k.into()).map_err(|_| ()) } } @@ -131,6 +135,24 @@ impl AsMut<[u8]> for Public { } } +#[cfg(feature = "std")] +impl From for Public { + fn from(pubkey: PublicKey) -> Self { + Self(pubkey.serialize()) + } +} + +#[cfg(not(feature = "std"))] +impl From for Public { + fn from(pubkey: VerifyingKey) -> Self { + Self::unchecked_from( + pubkey.to_sec1_bytes()[..] + .try_into() + .expect("valid key is serializable to [u8,33]. qed."), + ) + } +} + impl TryFrom<&[u8]> for Public { type Error = (); @@ -331,23 +353,34 @@ impl Signature { /// Recover the public key from this signature and a pre-hashed message. #[cfg(feature = "full_crypto")] pub fn recover_prehashed(&self, message: &[u8; 32]) -> Option { - let rid = RecoveryId::from_i32(self.0[64] as i32).ok()?; - let sig = RecoverableSignature::from_compact(&self.0[..64], rid).ok()?; - let message = Message::from_digest_slice(message).expect("Message is 32 bytes; qed"); - #[cfg(feature = "std")] - let context = SECP256K1; + { + let rid = RecoveryId::from_i32(self.0[64] as i32).ok()?; + let sig = RecoverableSignature::from_compact(&self.0[..64], rid).ok()?; + let message = Message::from_digest_slice(message).expect("Message is 32 bytes; qed"); + SECP256K1.recover_ecdsa(&message, &sig).ok().map(Public::from) + } + #[cfg(not(feature = "std"))] - let context = Secp256k1::verification_only(); + { + let rid = k256::ecdsa::RecoveryId::from_byte(self.0[64])?; + let sig = k256::ecdsa::Signature::from_bytes((&self.0[..64]).into()).ok()?; + VerifyingKey::recover_from_prehash(message, &sig, rid).map(Public::from).ok() + } + } +} - context - .recover_ecdsa(&message, &sig) - .ok() - .map(|pubkey| Public(pubkey.serialize())) +#[cfg(not(feature = "std"))] +impl From<(k256::ecdsa::Signature, k256::ecdsa::RecoveryId)> for Signature { + fn from(recsig: (k256::ecdsa::Signature, k256::ecdsa::RecoveryId)) -> Signature { + let mut r = Self::default(); + r.0[..64].copy_from_slice(&recsig.0.to_bytes()); + r.0[64] = recsig.1.to_byte(); + r } } -#[cfg(feature = "full_crypto")] +#[cfg(all(feature = "std", feature = "full_crypto"))] impl From for Signature { fn from(recsig: RecoverableSignature) -> Signature { let mut r = Self::default(); @@ -384,17 +417,19 @@ impl TraitPair for Pair { /// /// You should never need to use this; generate(), generate_with_phrase fn from_seed_slice(seed_slice: &[u8]) -> Result { - let secret = - SecretKey::from_slice(seed_slice).map_err(|_| SecretStringError::InvalidSeedLength)?; - #[cfg(feature = "std")] - let context = SECP256K1; - #[cfg(not(feature = "std"))] - let context = Secp256k1::signing_only(); + { + let secret = SecretKey::from_slice(seed_slice) + .map_err(|_| SecretStringError::InvalidSeedLength)?; + Ok(Pair { public: PublicKey::from_secret_key(&SECP256K1, &secret).into(), secret }) + } - let public = PublicKey::from_secret_key(&context, &secret); - let public = Public(public.serialize()); - Ok(Pair { public, secret }) + #[cfg(not(feature = "std"))] + { + let secret = SecretKey::from_slice(seed_slice) + .map_err(|_| SecretStringError::InvalidSeedLength)?; + Ok(Pair { public: VerifyingKey::from(&secret).into(), secret }) + } } /// Derive a child key from a series of given junctions. @@ -438,7 +473,14 @@ impl TraitPair for Pair { impl Pair { /// Get the seed for this key. pub fn seed(&self) -> Seed { - self.secret.secret_bytes() + #[cfg(feature = "std")] + { + self.secret.secret_bytes() + } + #[cfg(not(feature = "std"))] + { + self.secret.to_bytes().into() + } } /// Exactly as `from_string` except that if no matches are found then, the the first 32 @@ -455,14 +497,19 @@ impl Pair { /// Sign a pre-hashed message pub fn sign_prehashed(&self, message: &[u8; 32]) -> Signature { - let message = Message::from_digest_slice(message).expect("Message is 32 bytes; qed"); - #[cfg(feature = "std")] - let context = SECP256K1; - #[cfg(not(feature = "std"))] - let context = Secp256k1::signing_only(); + { + let message = Message::from_digest_slice(message).expect("Message is 32 bytes; qed"); + SECP256K1.sign_ecdsa_recoverable(&message, &self.secret).into() + } - context.sign_ecdsa_recoverable(&message, &self.secret).into() + #[cfg(not(feature = "std"))] + { + self.secret + .sign_prehash_recoverable(message) + .expect("signing may not fail (???). qed.") + .into() + } } /// Verify a signature on a pre-hashed message. Return `true` if the signature is valid @@ -503,7 +550,7 @@ impl Pair { // NOTE: this solution is not effective when `Pair` is moved around memory. // The very same problem affects other cryptographic backends that are just using // `zeroize`for their secrets. -#[cfg(feature = "full_crypto")] +#[cfg(all(feature = "std", feature = "full_crypto"))] impl Drop for Pair { fn drop(&mut self) { self.secret.non_secure_erase() @@ -770,8 +817,18 @@ mod test { let msg = [0u8; 32]; let sig1 = pair.sign_prehashed(&msg); let sig2: Signature = { - let message = Message::from_digest_slice(&msg).unwrap(); - SECP256K1.sign_ecdsa_recoverable(&message, &pair.secret).into() + #[cfg(feature = "std")] + { + let message = Message::from_digest_slice(&msg).unwrap(); + SECP256K1.sign_ecdsa_recoverable(&message, &pair.secret).into() + } + #[cfg(not(feature = "std"))] + { + pair.secret + .sign_prehash_recoverable(&msg) + .expect("signing may not fail (???). qed.") + .into() + } }; assert_eq!(sig1, sig2); -- GitLab From 1c435e91c117b877c803427a91c0ccd18c527382 Mon Sep 17 00:00:00 2001 From: Viki Val Date: Sat, 9 Mar 2024 07:32:53 -0800 Subject: [PATCH 375/392] :bug: Depositing PalletAttributeSet on incorrect nft (#2740) ## Context Implementing `HolderOf(collection_id)` we have observed a fancy glitch where pallet deposits event with incorrect values ### Test case [Observe following extrinsic](https://assethub-polkadot.subscan.io/extrinsic/0xdc72321b7674aa209c2f194ed49bd6bd12708af103f98b5b9196e0132dcba777) To mint in collection `51` user needs to be `HolderOf(50)`. Therefore current user is owner of item `394` `witness_data { owned_item: 394 }` All checking is done correctly, storage is updated correctly ![photo_2023-12-18 16 07 11](https://github.com/paritytech/polkadot-sdk/assets/22471030/ca991272-156d-4db1-97b2-1a2873fc5d3f) However the event which is emitted does not make semantic sense as we updated storage for `50-394` not for `51-114` ![photo_2023-12-18 16 07 17](https://github.com/paritytech/polkadot-sdk/assets/22471030/c998a92c-e306-4433-aad8-103078140e23) ## The fix This PR fixes that depositing `PalletAttributeSet` emits correct values. --------- Co-authored-by: Jegor Sidorenko Co-authored-by: Jegor Sidorenko <5252494+jsidorenko@users.noreply.github.com> --- substrate/frame/nfts/src/lib.rs | 4 ++-- substrate/frame/nfts/src/tests.rs | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/substrate/frame/nfts/src/lib.rs b/substrate/frame/nfts/src/lib.rs index 7cf7cdc61a7..615720268fe 100644 --- a/substrate/frame/nfts/src/lib.rs +++ b/substrate/frame/nfts/src/lib.rs @@ -874,8 +874,8 @@ pub mod pallet { ), ); Self::deposit_event(Event::PalletAttributeSet { - collection, - item: Some(item), + collection: collection_id, + item: Some(owned_item), attribute: pallet_attribute, value: attribute_value, }); diff --git a/substrate/frame/nfts/src/tests.rs b/substrate/frame/nfts/src/tests.rs index 9e521537534..6bf9427f4e6 100644 --- a/substrate/frame/nfts/src/tests.rs +++ b/substrate/frame/nfts/src/tests.rs @@ -440,6 +440,12 @@ fn mint_should_work() { account(2), Some(MintWitness { owned_item: Some(43), ..Default::default() }) )); + assert!(events().contains(&Event::::PalletAttributeSet { + collection: 0, + item: Some(43), + attribute: PalletAttributes::<::CollectionId>::UsedToClaim(1), + value: Nfts::construct_attribute_value(vec![]).unwrap(), + })); // can't mint twice assert_noop!( -- GitLab From bbaa5a3bb5451fc0c51fd42fd91d765f5589c033 Mon Sep 17 00:00:00 2001 From: Muharem Date: Sun, 10 Mar 2024 22:24:41 +0100 Subject: [PATCH 376/392] Asset Conversion: doc guide to address incorrect exchange rate for non-withdrawable pool (#3275) This documentation guide to address an incorrect exchange rate for a non-withdrawable pool. --- substrate/frame/asset-conversion/src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/substrate/frame/asset-conversion/src/lib.rs b/substrate/frame/asset-conversion/src/lib.rs index f13d40d3e7e..c9725f9d39d 100644 --- a/substrate/frame/asset-conversion/src/lib.rs +++ b/substrate/frame/asset-conversion/src/lib.rs @@ -413,6 +413,11 @@ pub mod pallet { /// Params `amount1_min`/`amount2_min` represent that. /// `mint_to` will be sent the liquidity tokens that represent this share of the pool. /// + /// NOTE: when encountering an incorrect exchange rate and non-withdrawable pool liquidity, + /// batch an atomic call with [`Pallet::add_liquidity`] and + /// [`Pallet::swap_exact_tokens_for_tokens`] or [`Pallet::swap_tokens_for_exact_tokens`] + /// calls to render the liquidity withdrawable and rectify the exchange rate. + /// /// Once liquidity is added, someone may successfully call /// [`Pallet::swap_exact_tokens_for_tokens`] successfully. #[pallet::call_index(1)] -- GitLab From a6713c55fd5082d333518c3ca13f2a4294726fcc Mon Sep 17 00:00:00 2001 From: Egor_P Date: Mon, 11 Mar 2024 16:37:22 +0700 Subject: [PATCH 377/392] Fix release docker image GHA (#3547) This PR add extra checks for the input fields in the GHA which does the docker image build and publishing. --- .github/scripts/common/lib.sh | 96 ++++++++++++++++++- .../workflows/release-50_publish-docker.yml | 16 +++- .../workflows/release-99_notif-published.yml | 10 +- 3 files changed, 107 insertions(+), 15 deletions(-) diff --git a/.github/scripts/common/lib.sh b/.github/scripts/common/lib.sh index bd12d9c6e6f..29dc269ffd2 100755 --- a/.github/scripts/common/lib.sh +++ b/.github/scripts/common/lib.sh @@ -237,6 +237,61 @@ fetch_release_artifacts() { popd > /dev/null } +# Fetch the release artifacts like binary and sigantures from S3. Assumes the ENV are set: +# - RELEASE_ID +# - GITHUB_TOKEN +# - REPO in the form paritytech/polkadot +fetch_release_artifacts_from_s3() { + echo "Version : $VERSION" + echo "Repo : $REPO" + echo "Binary : $BINARY" + OUTPUT_DIR=${OUTPUT_DIR:-"./release-artifacts/${BINARY}"} + echo "OUTPUT_DIR : $OUTPUT_DIR" + + URL_BASE=$(get_s3_url_base $BINARY) + echo "URL_BASE=$URL_BASE" + + URL_BINARY=$URL_BASE/$VERSION/$BINARY + URL_SHA=$URL_BASE/$VERSION/$BINARY.sha256 + URL_ASC=$URL_BASE/$VERSION/$BINARY.asc + + # Fetch artifacts + mkdir -p "$OUTPUT_DIR" + pushd "$OUTPUT_DIR" > /dev/null + + echo "Fetching artifacts..." + for URL in $URL_BINARY $URL_SHA $URL_ASC; do + echo "Fetching %s" "$URL" + curl --progress-bar -LO "$URL" || echo "Missing $URL" + done + + pwd + ls -al --color + popd > /dev/null + +} + +# Pass the name of the binary as input, it will +# return the s3 base url +function get_s3_url_base() { + name=$1 + case $name in + polkadot | polkadot-execute-worker | polkadot-prepare-worker | staking-miner) + printf "https://releases.parity.io/polkadot" + ;; + + polkadot-parachain) + printf "https://releases.parity.io/cumulus" + ;; + + *) + printf "UNSUPPORTED BINARY $name" + exit 1 + ;; + esac +} + + # Check the checksum for a given binary function check_sha256() { echo "Checking SHA256 for $1" @@ -248,13 +303,11 @@ function check_sha256() { function import_gpg_keys() { GPG_KEYSERVER=${GPG_KEYSERVER:-"keyserver.ubuntu.com"} SEC="9D4B2B6EB8F97156D19669A9FF0812D491B96798" - WILL="2835EAF92072BC01D188AF2C4A092B93E97CE1E2" EGOR="E6FC4D4782EB0FA64A4903CCDB7D3555DD3932D3" - MARA="533C920F40E73A21EEB7E9EBF27AEA7E7594C9CF" MORGAN="2E92A9D8B15D7891363D1AE8AF9E6C43F7F8C4CF" echo "Importing GPG keys from $GPG_KEYSERVER in parallel" - for key in $SEC $WILL $EGOR $MARA $MORGAN; do + for key in $SEC $EGOR $MORGAN; do ( echo "Importing GPG key $key" gpg --no-tty --quiet --keyserver $GPG_KEYSERVER --recv-keys $key @@ -344,3 +397,40 @@ function find_runtimes() { done echo $JSON } + +# Filter the version matches the particular pattern and return it. +# input: version (v1.8.0 or v1.8.0-rc1) +# output: none +filter_version_from_input() { + version=$1 + regex="(^v[0-9]+\.[0-9]+\.[0-9]+)$|(^v[0-9]+\.[0-9]+\.[0-9]+-rc[0-9]+)$" + + if [[ $version =~ $regex ]]; then + if [ -n "${BASH_REMATCH[1]}" ]; then + echo "${BASH_REMATCH[1]}" + elif [ -n "${BASH_REMATCH[2]}" ]; then + echo "${BASH_REMATCH[2]}" + fi + else + echo "Invalid version: $version" + exit 1 + fi + +} + +# Check if the release_id is valid number +# input: release_id +# output: release_id or exit 1 +check_release_id() { + input=$1 + + release_id=$(echo "$input" | sed 's/[^0-9]//g') + + if [[ $release_id =~ ^[0-9]+$ ]]; then + echo "$release_id" + else + echo "Invalid release_id from input: $input" + exit 1 + fi + +} diff --git a/.github/workflows/release-50_publish-docker.yml b/.github/workflows/release-50_publish-docker.yml index ecbac01cd3a..67e93ee9657 100644 --- a/.github/workflows/release-50_publish-docker.yml +++ b/.github/workflows/release-50_publish-docker.yml @@ -36,7 +36,7 @@ on: -H "Authorization: Bearer ${GITHUB_TOKEN}" https://api.github.com/repos/$OWNER/$REPO/releases | \ jq '.[] | { name: .name, id: .id }' required: true - type: string + type: number registry: description: Container registry @@ -61,7 +61,6 @@ permissions: contents: write env: - RELEASE_ID: ${{ inputs.release_id }} ENGINE: docker REGISTRY: ${{ inputs.registry }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -71,6 +70,7 @@ env: # EVENT_ACTION: ${{ github.event.action }} EVENT_NAME: ${{ github.event_name }} IMAGE_TYPE: ${{ inputs.image_type }} + VERSION: ${{ inputs.version }} jobs: fetch-artifacts: # this job will be triggered for the polkadot-parachain rc and release or polkadot rc image build @@ -95,13 +95,16 @@ jobs: # chmod a+x $BINARY # ls -al - - name: Fetch rc artifacts or release artifacts based on release id + - name: Fetch rc artifacts or release artifacts from s3 based on version #this step runs only if the workflow is triggered manually if: ${{ env.EVENT_NAME == 'workflow_dispatch' }} run: | . ./.github/scripts/common/lib.sh - fetch_release_artifacts + VERSION=$(filter_version_from_input "${{ inputs.version }}") + echo "VERSION=${VERSION}" >> $GITHUB_ENV + + fetch_release_artifacts_from_s3 - name: Cache the artifacts uses: actions/cache@e12d46a63a90f2fae62d114769bbf2a179198b5c # v3.3.3 @@ -147,7 +150,10 @@ jobs: if: ${{ env.IMAGE_TYPE == 'rc' }} id: fetch_rc_refs run: | - release=release-${{ inputs.release_id }} && \ + . ./.github/scripts/common/lib.sh + + RELEASE_ID=$(check_release_id "${{ inputs.release_id }}") + release=release-$RELEASE_ID && \ echo "release=${release}" >> $GITHUB_OUTPUT commit=$(git rev-parse --short HEAD) && \ diff --git a/.github/workflows/release-99_notif-published.yml b/.github/workflows/release-99_notif-published.yml index 732db15d9c0..05c9d6a47f5 100644 --- a/.github/workflows/release-99_notif-published.yml +++ b/.github/workflows/release-99_notif-published.yml @@ -16,12 +16,6 @@ jobs: - name: "RelEng: Polkadot Release Coordination" room: '!cqAmzdIcbOFwrdrubV:parity.io' pre-release: true - - name: 'General: Rust, Polkadot, Substrate' - room: '!aJymqQYtCjjqImFLSb:parity.io' - pre-release: false - - name: 'Team: DevOps' - room: '!lUslSijLMgNcEKcAiE:parity.io' - pre-release: true # External - name: 'Ledger <> Polkadot Coordination' @@ -48,7 +42,9 @@ jobs: access_token: ${{ secrets.RELEASENOTES_MATRIX_V2_ACCESS_TOKEN }} server: m.parity.io message: | - A (pre)release has been ${{github.event.action}} in **${{github.event.repository.full_name}}:**
+ @room + + A new node release has been ${{github.event.action}} in **${{github.event.repository.full_name}}:**
Release version: [${{github.event.release.tag_name}}](${{github.event.release.html_url}}) ----- -- GitLab From 8dc6048d5eb20886f5d0781d54e073441d3bd86c Mon Sep 17 00:00:00 2001 From: eskimor Date: Mon, 11 Mar 2024 15:11:55 +0100 Subject: [PATCH 378/392] Remove unused FullCandidateReceipt (#3641) Currently redesigning candidate data structures, noticed that this one seems dead. Co-authored-by: eskimor --- polkadot/primitives/src/v6/mod.rs | 12 --------- .../implementers-guide/src/types/README.md | 11 -------- .../implementers-guide/src/types/candidate.md | 26 ++----------------- 3 files changed, 2 insertions(+), 47 deletions(-) diff --git a/polkadot/primitives/src/v6/mod.rs b/polkadot/primitives/src/v6/mod.rs index 89431f7801f..cab34deeb50 100644 --- a/polkadot/primitives/src/v6/mod.rs +++ b/polkadot/primitives/src/v6/mod.rs @@ -533,18 +533,6 @@ impl CandidateReceipt { } } -/// All data pertaining to the execution of a para candidate. -#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] -pub struct FullCandidateReceipt { - /// The inner candidate receipt. - pub inner: CandidateReceipt, - /// The validation data derived from the relay-chain state at that - /// point. The hash of the persisted validation data should - /// match the `persisted_validation_data_hash` in the descriptor - /// of the receipt. - pub validation_data: PersistedValidationData, -} - /// A candidate-receipt with commitments directly included. #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Hash))] diff --git a/polkadot/roadmap/implementers-guide/src/types/README.md b/polkadot/roadmap/implementers-guide/src/types/README.md index 87092bf3a00..5fd3050f949 100644 --- a/polkadot/roadmap/implementers-guide/src/types/README.md +++ b/polkadot/roadmap/implementers-guide/src/types/README.md @@ -55,17 +55,6 @@ digraph { CandidateCommitmentsHash [label = "Hash", shape="doublecircle", fill="gray90"] CandidateCommitmentsHash -> CandidateCommitments:name - FullCandidateReceipt [label = < - - - - -
FullCandidateReceipt<H = Hash, N = BlockNumber>
innerCandidateReceipt<H>
validation_dataValidationData<N>
- >] - - FullCandidateReceipt:inner -> CandidateReceipt:name - FullCandidateReceipt:validation_data -> ValidationData:name - CommittedCandidateReceipt [label = < diff --git a/polkadot/roadmap/implementers-guide/src/types/candidate.md b/polkadot/roadmap/implementers-guide/src/types/candidate.md index 00176229e5a..399d7854ac4 100644 --- a/polkadot/roadmap/implementers-guide/src/types/candidate.md +++ b/polkadot/roadmap/implementers-guide/src/types/candidate.md @@ -20,12 +20,8 @@ struct ParaId(u32); ## Candidate Receipt -Much info in a [`FullCandidateReceipt`](#full-candidate-receipt) is duplicated from the relay-chain state. When the -corresponding relay-chain state is considered widely available, the Candidate Receipt should be favored over the -`FullCandidateReceipt`. - -Examples of situations where the state is readily available includes within the scope of work done by subsystems working -on a given relay-parent, or within the logic of the runtime importing a backed candidate. +Compact representation of the result of a validation. This is what validators +receive from collators, together with the PoV. ```rust /// A candidate-receipt. @@ -37,24 +33,6 @@ struct CandidateReceipt { } ``` -## Full Candidate Receipt - -This is the full receipt type. The `PersistedValidationData` are technically redundant with the `inner.relay_parent`, -which uniquely describes the block in the blockchain from whose state these values are derived. The -[`CandidateReceipt`](#candidate-receipt) variant is often used instead for this reason. - -However, the Full Candidate Receipt type is useful as a means of avoiding the implicit dependency on availability of old -blockchain state. In situations such as availability and approval, having the full description of the candidate within a -self-contained struct is convenient. - -```rust -/// All data pertaining to the execution of a para candidate. -struct FullCandidateReceipt { - inner: CandidateReceipt, - validation_data: PeristedValidationData, -} -``` - ## Committed Candidate Receipt This is a variant of the candidate receipt which includes the commitments of the candidate receipt alongside the -- GitLab From aa35328371d967e6af20c03e86db0b6e5c11cdf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=B3nal=20Murray?= Date: Mon, 11 Mar 2024 21:12:27 +0700 Subject: [PATCH 379/392] [pallet_broker] Fix `adapt_price` behaviour at zero (#3636) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes the behaviour of `Linear` which is the default implementation of the `AdaptPrice` trait in the broker pallet. Previously if cores were offered but not sold in only one sale, the price would be set to zero and due to the logic being purely multiplicative, the price would stay at 0 indefinitely. This could be further paired with a configurable minimum in the broker pallet itself, which will be a future PR. This affects the Rococo and Westend Coretime chains, but Kusama has a different implementation so this isn't required for the Kusama launch. I actually thought I opened this a while ago. --------- Co-authored-by: Bastian Köcher --- prdoc/pr_3636.prdoc | 15 +++++++++ substrate/frame/broker/src/adapt_price.rs | 38 ++++++++++++++++++++--- 2 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 prdoc/pr_3636.prdoc diff --git a/prdoc/pr_3636.prdoc b/prdoc/pr_3636.prdoc new file mode 100644 index 00000000000..934158ac102 --- /dev/null +++ b/prdoc/pr_3636.prdoc @@ -0,0 +1,15 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: "[pallet_broker] Fix `Linear::adapt_price` behavior at zero" + +doc: + - audience: Runtime Dev + description: | + This fixes the behaviour of `Linear` which is the default implementation of the `AdaptPrice` + trait in the broker pallet. Previously if cores were offered but not sold in only one sale, + the price would be set to zero and due to the logic being purely multiplicative, the price + would stay at 0 indefinitely. + +crates: + - name: pallet-broker diff --git a/substrate/frame/broker/src/adapt_price.rs b/substrate/frame/broker/src/adapt_price.rs index 8266625687a..fbcd7afdf0d 100644 --- a/substrate/frame/broker/src/adapt_price.rs +++ b/substrate/frame/broker/src/adapt_price.rs @@ -19,6 +19,7 @@ use crate::CoreIndex; use sp_arithmetic::{traits::One, FixedU64}; +use sp_runtime::Saturating; /// Type for determining how to set price. pub trait AdaptPrice { @@ -49,14 +50,24 @@ impl AdaptPrice for () { pub struct Linear; impl AdaptPrice for Linear { fn leadin_factor_at(when: FixedU64) -> FixedU64 { - FixedU64::from(2) - when + FixedU64::from(2).saturating_sub(when) } fn adapt_price(sold: CoreIndex, target: CoreIndex, limit: CoreIndex) -> FixedU64 { if sold <= target { - FixedU64::from_rational(sold.into(), target.into()) + // Range of [0.5, 1.0]. + FixedU64::from_rational(1, 2).saturating_add(FixedU64::from_rational( + sold.into(), + target.saturating_mul(2).into(), + )) } else { - FixedU64::one() + - FixedU64::from_rational((sold - target).into(), (limit - target).into()) + // Range of (1.0, 2]. + + // Unchecked math: In this branch we know that sold > target. The limit must be >= sold + // by construction, and thus target must be < limit. + FixedU64::one().saturating_add(FixedU64::from_rational( + (sold - target).into(), + (limit - target).into(), + )) } } } @@ -81,4 +92,23 @@ mod tests { } } } + + #[test] + fn linear_bound_check() { + // Using constraints from pallet implementation i.e. `limit >= sold`. + // Check extremes + let limit = 10; + let target = 5; + + // Maximally sold: `sold == limit` + assert_eq!(Linear::adapt_price(limit, target, limit), FixedU64::from_float(2.0)); + // Ideally sold: `sold == target` + assert_eq!(Linear::adapt_price(target, target, limit), FixedU64::one()); + // Minimally sold: `sold == 0` + assert_eq!(Linear::adapt_price(0, target, limit), FixedU64::from_float(0.5)); + // Optimistic target: `target == limit` + assert_eq!(Linear::adapt_price(limit, limit, limit), FixedU64::one()); + // Pessimistic target: `target == 0` + assert_eq!(Linear::adapt_price(limit, 0, limit), FixedU64::from_float(2.0)); + } } -- GitLab From 4249a3d6cbca1da2ee15237c05691005973502e9 Mon Sep 17 00:00:00 2001 From: s0me0ne-unkn0wn <48632512+s0me0ne-unkn0wn@users.noreply.github.com> Date: Mon, 11 Mar 2024 15:38:44 +0100 Subject: [PATCH 380/392] Remove getters from `im-online` pallet (#3589) As I've been dancing around this pallet for quite some time anyway, I decided to remove getters at once. There were only a few leftovers in tests. Related: #3326 CC @muraca --- prdoc/pr_3589.prdoc | 10 ++++++++++ substrate/frame/im-online/src/lib.rs | 12 ++++-------- substrate/frame/im-online/src/tests.rs | 9 +++------ 3 files changed, 17 insertions(+), 14 deletions(-) create mode 100644 prdoc/pr_3589.prdoc diff --git a/prdoc/pr_3589.prdoc b/prdoc/pr_3589.prdoc new file mode 100644 index 00000000000..98b9b1039ab --- /dev/null +++ b/prdoc/pr_3589.prdoc @@ -0,0 +1,10 @@ +title: Removed `pallet::getter` usage from `pallet-im-online` + +doc: + - audience: Runtime Dev + description: | + This PR removes `pallet::getter` usage from `pallet-im-online`, and updates dependant code accordingly. + The syntax `StorageItem::::get()` should be used instead. + +crates: + - name: pallet-im-online diff --git a/substrate/frame/im-online/src/lib.rs b/substrate/frame/im-online/src/lib.rs index f14093aa09a..239b47834d1 100644 --- a/substrate/frame/im-online/src/lib.rs +++ b/substrate/frame/im-online/src/lib.rs @@ -338,26 +338,22 @@ pub mod pallet { /// progress estimate from `NextSessionRotation`, as those estimates should be /// more accurate then the value we calculate for `HeartbeatAfter`. #[pallet::storage] - #[pallet::getter(fn heartbeat_after)] - pub(super) type HeartbeatAfter = StorageValue<_, BlockNumberFor, ValueQuery>; + pub type HeartbeatAfter = StorageValue<_, BlockNumberFor, ValueQuery>; /// The current set of keys that may issue a heartbeat. #[pallet::storage] - #[pallet::getter(fn keys)] - pub(super) type Keys = + pub type Keys = StorageValue<_, WeakBoundedVec, ValueQuery>; /// For each session index, we keep a mapping of `SessionIndex` and `AuthIndex`. #[pallet::storage] - #[pallet::getter(fn received_heartbeats)] - pub(super) type ReceivedHeartbeats = + pub type ReceivedHeartbeats = StorageDoubleMap<_, Twox64Concat, SessionIndex, Twox64Concat, AuthIndex, bool>; /// For each session index, we keep a mapping of `ValidatorId` to the /// number of blocks authored by the given authority. #[pallet::storage] - #[pallet::getter(fn authored_blocks)] - pub(super) type AuthoredBlocks = StorageDoubleMap< + pub type AuthoredBlocks = StorageDoubleMap< _, Twox64Concat, SessionIndex, diff --git a/substrate/frame/im-online/src/tests.rs b/substrate/frame/im-online/src/tests.rs index 7efca926eb0..6f5a14d7e7f 100644 --- a/substrate/frame/im-online/src/tests.rs +++ b/substrate/frame/im-online/src/tests.rs @@ -26,10 +26,7 @@ use sp_core::offchain::{ testing::{TestOffchainExt, TestTransactionPoolExt}, OffchainDbExt, OffchainWorkerExt, TransactionPoolExt, }; -use sp_runtime::{ - testing::UintAuthorityId, - transaction_validity::{InvalidTransaction, TransactionValidityError}, -}; +use sp_runtime::testing::UintAuthorityId; #[test] fn test_unresponsiveness_slash_fraction() { @@ -267,14 +264,14 @@ fn should_cleanup_received_heartbeats_on_session_end() { let _ = heartbeat(1, 2, 0, 1.into(), Session::validators()).unwrap(); // the heartbeat is stored - assert!(!ImOnline::received_heartbeats(&2, &0).is_none()); + assert!(!super::pallet::ReceivedHeartbeats::::get(2, 0).is_none()); advance_session(); // after the session has ended we have already processed the heartbeat // message, so any messages received on the previous session should have // been pruned. - assert!(ImOnline::received_heartbeats(&2, &0).is_none()); + assert!(super::pallet::ReceivedHeartbeats::::get(2, 0).is_none()); }); } -- GitLab From 02f1f2c47609483be04097e27fc52c06883a6540 Mon Sep 17 00:00:00 2001 From: Tsvetomir Dimitrov Date: Mon, 11 Mar 2024 18:00:52 +0200 Subject: [PATCH 381/392] Small fixes in para-scheduler pallet (#3524) Fixes some typos, outdated comments and test asserts. Also uses safe math and `defensive` for arithmetic operations. --- polkadot/runtime/parachains/src/scheduler.rs | 23 ++++++++++++------- .../runtime/parachains/src/scheduler/tests.rs | 11 +++++---- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/polkadot/runtime/parachains/src/scheduler.rs b/polkadot/runtime/parachains/src/scheduler.rs index 61ab36dbe96..f231864a85e 100644 --- a/polkadot/runtime/parachains/src/scheduler.rs +++ b/polkadot/runtime/parachains/src/scheduler.rs @@ -37,7 +37,7 @@ //! availability cores over time. use crate::{configuration, initializer::SessionChangeNotification, paras}; -use frame_support::pallet_prelude::*; +use frame_support::{pallet_prelude::*, traits::Defensive}; use frame_system::pallet_prelude::BlockNumberFor; pub use polkadot_core_primitives::v2::BlockNumber; use primitives::{ @@ -59,6 +59,7 @@ pub use pallet::*; mod tests; const LOG_TARGET: &str = "runtime::parachains::scheduler"; + pub mod migration; #[frame_support::pallet] @@ -88,10 +89,8 @@ pub mod pallet { #[pallet::getter(fn validator_groups)] pub(crate) type ValidatorGroups = StorageValue<_, Vec>, ValueQuery>; - /// One entry for each availability core. Entries are `None` if the core is not currently - /// occupied. Can be temporarily `Some` if scheduled but not occupied. - /// The i'th parachain belongs to the i'th core, with the remaining cores all being - /// parathread-multiplexers. + /// One entry for each availability core. The i'th parachain belongs to the i'th core, with the + /// remaining cores all being on demand parachain multiplexers. /// /// Bounded by the maximum of either of these two values: /// * The number of parachains and parathread multiplexers @@ -146,7 +145,7 @@ pub mod pallet { /// One entry for each availability core. The `VecDeque` represents the assignments to be /// scheduled on that core. The value contained here will not be valid after the end of - /// a block. Runtime APIs should be used to determine scheduled cores/ for the upcoming block. + /// a block. Runtime APIs should be used to determine scheduled cores for the upcoming block. #[pallet::storage] #[pallet::getter(fn claimqueue)] pub(crate) type ClaimQueue = @@ -236,8 +235,16 @@ impl Pallet { if n_cores == 0 || validators.is_empty() { ValidatorGroups::::set(Vec::new()); } else { - let group_base_size = validators.len() / n_cores as usize; - let n_larger_groups = validators.len() % n_cores as usize; + let group_base_size = validators + .len() + .checked_div(n_cores as usize) + .defensive_proof("n_cores should not be 0") + .unwrap_or(0); + let n_larger_groups = validators + .len() + .checked_rem(n_cores as usize) + .defensive_proof("n_cores should not be 0") + .unwrap_or(0); // Groups contain indices into the validators from the session change notification, // which are already shuffled. diff --git a/polkadot/runtime/parachains/src/scheduler/tests.rs b/polkadot/runtime/parachains/src/scheduler/tests.rs index 28b3a6b4f5d..e6a1e66b3a5 100644 --- a/polkadot/runtime/parachains/src/scheduler/tests.rs +++ b/polkadot/runtime/parachains/src/scheduler/tests.rs @@ -213,6 +213,7 @@ fn claimqueue_ttl_drop_fn_works() { // Drop expired claim. Scheduler::drop_expired_claims_from_claimqueue(); + assert!(!claimqueue_contains_para_ids::(vec![para_id])); // Add a claim on core 0 with a ttl == now (17) let paras_entry_non_expired = ParasEntry::new(Assignment::Bulk(para_id), now); @@ -222,7 +223,7 @@ fn claimqueue_ttl_drop_fn_works() { Scheduler::add_to_claimqueue(core_idx, paras_entry_expired.clone()); Scheduler::add_to_claimqueue(core_idx, paras_entry_non_expired.clone()); let cq = Scheduler::claimqueue(); - assert!(cq.get(&core_idx).unwrap().len() == 3); + assert_eq!(cq.get(&core_idx).unwrap().len(), 3); // Add a claim to the test assignment provider. let assignment = Assignment::Bulk(para_id); @@ -234,8 +235,9 @@ fn claimqueue_ttl_drop_fn_works() { let cq = Scheduler::claimqueue(); let cqc = cq.get(&core_idx).unwrap(); - // Same number of claims - assert!(cqc.len() == 3); + // Same number of claims, because a new claim is popped from `MockAssigner` instead of the + // expired one + assert_eq!(cqc.len(), 3); // The first 2 claims in the queue should have a ttl of 17, // being the ones set up prior in this test as claims 1 and 3. @@ -355,14 +357,13 @@ fn fill_claimqueue_fills() { schedule_blank_para(para_b); schedule_blank_para(para_c); - // start a new session to activate, 3 validators for 3 cores. + // start a new session to activate, 2 validators for 2 cores. run_to_block(1, |number| match number { 1 => Some(SessionChangeNotification { new_config: default_config(), validators: vec![ ValidatorId::from(Sr25519Keyring::Alice.public()), ValidatorId::from(Sr25519Keyring::Bob.public()), - ValidatorId::from(Sr25519Keyring::Charlie.public()), ], ..Default::default() }), -- GitLab From 05381afcb2e2015fe7f379ddba7522d595a5e8cc Mon Sep 17 00:00:00 2001 From: Andrei Eres Date: Mon, 11 Mar 2024 17:17:45 +0100 Subject: [PATCH 382/392] subsystem-bench: adjust test config to Kusama (#3583) Fixes https://github.com/paritytech/polkadot-sdk/issues/3528 ```rust latency: mean_latency_ms = 30 // common sense std_dev = 2.0 // common sense n_validators = 300 // max number of validators, from chain config n_cores = 60 // 300/5 max_validators_per_core = 5 // default min_pov_size = 5120 // max max_pov_size = 5120 // max peer_bandwidth = 44040192 // from the Parity's kusama validators bandwidth = 44040192 // from the Parity's kusama validators connectivity = 90 // we need to be connected to 90-95% of peers ``` --- ...ilability-distribution-regression-bench.rs | 19 +++------- .../availability-recovery-regression-bench.rs | 13 +------ .../subsystem-bench/src/lib/configuration.rs | 38 ++++++++++++++----- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/polkadot/node/network/availability-distribution/tests/availability-distribution-regression-bench.rs b/polkadot/node/network/availability-distribution/tests/availability-distribution-regression-bench.rs index f2872f3c72b..7a490d5e47f 100644 --- a/polkadot/node/network/availability-distribution/tests/availability-distribution-regression-bench.rs +++ b/polkadot/node/network/availability-distribution/tests/availability-distribution-regression-bench.rs @@ -16,7 +16,7 @@ //! availability-read regression tests //! -//! TODO: Explain the test case after configuration adjusted to Kusama +//! Availability read benchmark based on Kusama parameters and scale. //! //! Subsystems involved: //! - availability-distribution @@ -25,28 +25,19 @@ use polkadot_subsystem_bench::{ availability::{benchmark_availability_write, prepare_test, TestDataAvailability, TestState}, - configuration::{PeerLatency, TestConfiguration}, + configuration::TestConfiguration, usage::BenchmarkUsage, }; const BENCH_COUNT: usize = 3; -const WARM_UP_COUNT: usize = 20; +const WARM_UP_COUNT: usize = 30; const WARM_UP_PRECISION: f64 = 0.01; fn main() -> Result<(), String> { let mut messages = vec![]; - - // TODO: Adjust the test configurations to Kusama values let mut config = TestConfiguration::default(); - config.latency = Some(PeerLatency { mean_latency_ms: 30, std_dev: 2.0 }); - config.n_validators = 1000; - config.n_cores = 200; - config.max_validators_per_core = 5; - config.min_pov_size = 5120; - config.max_pov_size = 5120; - config.peer_bandwidth = 52428800; - config.bandwidth = 52428800; - config.connectivity = 75; + // A single node effort roughly n_cores * needed_approvals / n_validators = 60 * 30 / 300 + config.n_cores = 6; config.num_blocks = 3; config.generate_pov_sizes(); diff --git a/polkadot/node/network/availability-recovery/tests/availability-recovery-regression-bench.rs b/polkadot/node/network/availability-recovery/tests/availability-recovery-regression-bench.rs index beb063e7ae0..30cc4d47ecc 100644 --- a/polkadot/node/network/availability-recovery/tests/availability-recovery-regression-bench.rs +++ b/polkadot/node/network/availability-recovery/tests/availability-recovery-regression-bench.rs @@ -16,7 +16,7 @@ //! availability-write regression tests //! -//! TODO: Explain the test case after configuration adjusted to Kusama +//! Availability write benchmark based on Kusama parameters and scale. //! //! Subsystems involved: //! - availability-recovery @@ -26,7 +26,7 @@ use polkadot_subsystem_bench::{ benchmark_availability_read, prepare_test, DataAvailabilityReadOptions, TestDataAvailability, TestState, }, - configuration::{PeerLatency, TestConfiguration}, + configuration::TestConfiguration, usage::BenchmarkUsage, }; @@ -37,18 +37,9 @@ const WARM_UP_PRECISION: f64 = 0.01; fn main() -> Result<(), String> { let mut messages = vec![]; - // TODO: Adjust the test configurations to Kusama values let options = DataAvailabilityReadOptions { fetch_from_backers: true }; let mut config = TestConfiguration::default(); - config.latency = Some(PeerLatency { mean_latency_ms: 100, std_dev: 1.0 }); - config.n_validators = 300; - config.n_cores = 20; - config.min_pov_size = 5120; - config.max_pov_size = 5120; - config.peer_bandwidth = 52428800; - config.bandwidth = 52428800; config.num_blocks = 3; - config.connectivity = 90; config.generate_pov_sizes(); warm_up(config.clone(), options.clone())?; diff --git a/polkadot/node/subsystem-bench/src/lib/configuration.rs b/polkadot/node/subsystem-bench/src/lib/configuration.rs index c7693308527..17c81c4fd35 100644 --- a/polkadot/node/subsystem-bench/src/lib/configuration.rs +++ b/polkadot/node/subsystem-bench/src/lib/configuration.rs @@ -35,19 +35,34 @@ pub struct PeerLatency { pub std_dev: f64, } +// Based on Kusama `max_validators` +fn default_n_validators() -> usize { + 300 +} + +// Based on Kusama cores +fn default_n_cores() -> usize { + 60 +} + // Default PoV size in KiB. fn default_pov_size() -> usize { - 5120 + 5 * 1024 } -// Default bandwidth in bytes +// Default bandwidth in bytes, based stats from Kusama validators fn default_bandwidth() -> usize { - 52428800 + 42 * 1024 * 1024 +} + +// Default peer latency +fn default_peer_latency() -> Option { + Some(PeerLatency { mean_latency_ms: 30, std_dev: 2.0 }) } // Default connectivity percentage fn default_connectivity() -> usize { - 100 + 90 } // Default backing group size @@ -63,6 +78,7 @@ fn default_needed_approvals() -> usize { fn default_zeroth_delay_tranche_width() -> usize { 0 } + fn default_relay_vrf_modulo_samples() -> usize { 6 } @@ -78,8 +94,10 @@ fn default_no_show_slots() -> usize { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct TestConfiguration { /// Number of validators + #[serde(default = "default_n_validators")] pub n_validators: usize, /// Number of cores + #[serde(default = "default_n_cores")] pub n_cores: usize, /// The number of needed votes to approve a candidate. #[serde(default = "default_needed_approvals")] @@ -111,10 +129,10 @@ pub struct TestConfiguration { #[serde(default = "default_bandwidth")] pub bandwidth: usize, /// Optional peer emulation latency (round trip time) wrt node under test - #[serde(default)] + #[serde(default = "default_peer_latency")] pub latency: Option, - /// Connectivity ratio, the percentage of peers we are not connected to, but ar part of - /// the topology. + /// Connectivity ratio, the percentage of peers we are connected to, but as part of the + /// topology. #[serde(default = "default_connectivity")] pub connectivity: usize, /// Number of blocks to run the test for @@ -124,8 +142,8 @@ pub struct TestConfiguration { impl Default for TestConfiguration { fn default() -> Self { Self { - n_validators: Default::default(), - n_cores: Default::default(), + n_validators: default_n_validators(), + n_cores: default_n_cores(), needed_approvals: default_needed_approvals(), zeroth_delay_tranche_width: default_zeroth_delay_tranche_width(), relay_vrf_modulo_samples: default_relay_vrf_modulo_samples(), @@ -137,7 +155,7 @@ impl Default for TestConfiguration { pov_sizes: Default::default(), peer_bandwidth: default_bandwidth(), bandwidth: default_bandwidth(), - latency: Default::default(), + latency: default_peer_latency(), connectivity: default_connectivity(), num_blocks: Default::default(), } -- GitLab From d3f81056ad1054731e711f2761673ef72686697f Mon Sep 17 00:00:00 2001 From: philoniare Date: Tue, 12 Mar 2024 04:39:21 +0800 Subject: [PATCH 383/392] [Deprecation] Remove the deprecated Store trait (#3532) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description *Removes the deprecated `trait Store` feature from the code base* Fixes #222 --------- Co-authored-by: Dónal Murray --- prdoc/pr_3532.prdoc | 15 +++++ substrate/frame/support/procedural/src/lib.rs | 10 --- .../procedural/src/pallet/expand/mod.rs | 3 - .../src/pallet/expand/store_trait.rs | 67 ------------------- .../procedural/src/pallet/parse/mod.rs | 2 - .../src/pallet/parse/pallet_struct.rs | 26 +------ substrate/frame/support/src/lib.rs | 24 +------ .../tests/pallet_ui/deprecated_store_attr.rs | 28 -------- .../pallet_ui/deprecated_store_attr.stderr | 10 --- .../tests/pallet_ui/duplicate_store_attr.rs | 42 ------------ .../pallet_ui/duplicate_store_attr.stderr | 5 -- .../pallet_struct_invalid_attr.stderr | 2 +- .../pallet_ui/store_trait_leak_private.rs | 42 ------------ .../pallet_ui/store_trait_leak_private.stderr | 19 ------ .../support/test/tests/storage_transaction.rs | 1 - 15 files changed, 20 insertions(+), 276 deletions(-) create mode 100644 prdoc/pr_3532.prdoc delete mode 100644 substrate/frame/support/procedural/src/pallet/expand/store_trait.rs delete mode 100644 substrate/frame/support/test/tests/pallet_ui/deprecated_store_attr.rs delete mode 100644 substrate/frame/support/test/tests/pallet_ui/deprecated_store_attr.stderr delete mode 100644 substrate/frame/support/test/tests/pallet_ui/duplicate_store_attr.rs delete mode 100644 substrate/frame/support/test/tests/pallet_ui/duplicate_store_attr.stderr delete mode 100644 substrate/frame/support/test/tests/pallet_ui/store_trait_leak_private.rs delete mode 100644 substrate/frame/support/test/tests/pallet_ui/store_trait_leak_private.stderr diff --git a/prdoc/pr_3532.prdoc b/prdoc/pr_3532.prdoc new file mode 100644 index 00000000000..d47c8d1d491 --- /dev/null +++ b/prdoc/pr_3532.prdoc @@ -0,0 +1,15 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Remove deprecated `trait Store` + +doc: + - audience: Runtime Dev + description: | + The deprecated `trait Store` feature has been removed from the codebase. Please remove usages of `generate_store` + macro from your pallets and access the storage through generics. For example, + `::StoredRange::mutate` will need to be updated to `StoredRange::::mutate`. + +crates: + - name: frame-support + - name: frame \ No newline at end of file diff --git a/substrate/frame/support/procedural/src/lib.rs b/substrate/frame/support/procedural/src/lib.rs index 036da52a7ba..89e39a5c9bb 100644 --- a/substrate/frame/support/procedural/src/lib.rs +++ b/substrate/frame/support/procedural/src/lib.rs @@ -858,16 +858,6 @@ pub fn disable_frame_system_supertrait_check(_: TokenStream, _: TokenStream) -> pallet_macro_stub() } -/// -/// --- -/// -/// Rust-Analyzer Users: Documentation for this macro can be found at -/// `frame_support::pallet_macros::generate_store`. -#[proc_macro_attribute] -pub fn generate_store(_: TokenStream, _: TokenStream) -> TokenStream { - pallet_macro_stub() -} - /// /// --- /// diff --git a/substrate/frame/support/procedural/src/pallet/expand/mod.rs b/substrate/frame/support/procedural/src/pallet/expand/mod.rs index 3da7d9293c7..067839c2846 100644 --- a/substrate/frame/support/procedural/src/pallet/expand/mod.rs +++ b/substrate/frame/support/procedural/src/pallet/expand/mod.rs @@ -31,7 +31,6 @@ mod instances; mod origin; mod pallet_struct; mod storage; -mod store_trait; mod tasks; mod tt_default_parts; mod type_value; @@ -68,7 +67,6 @@ pub fn expand(mut def: Def) -> proc_macro2::TokenStream { let storages = storage::expand_storages(&mut def); let inherents = inherent::expand_inherents(&mut def); let instances = instances::expand_instances(&mut def); - let store_trait = store_trait::expand_store_trait(&mut def); let hooks = hooks::expand_hooks(&mut def); let genesis_build = genesis_build::expand_genesis_build(&mut def); let genesis_config = genesis_config::expand_genesis_config(&mut def); @@ -110,7 +108,6 @@ storage item. Otherwise, all storage items are listed among [*Type Definitions*] #storages #inherents #instances - #store_trait #hooks #genesis_build #genesis_config diff --git a/substrate/frame/support/procedural/src/pallet/expand/store_trait.rs b/substrate/frame/support/procedural/src/pallet/expand/store_trait.rs deleted file mode 100644 index 6635adc9881..00000000000 --- a/substrate/frame/support/procedural/src/pallet/expand/store_trait.rs +++ /dev/null @@ -1,67 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// 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. - -use crate::pallet::Def; -use syn::spanned::Spanned; - -/// If attribute `#[pallet::generate_store(..)]` is defined then: -/// * generate Store trait with all storages, -/// * implement Store trait for Pallet. -pub fn expand_store_trait(def: &mut Def) -> proc_macro2::TokenStream { - let (trait_vis, trait_store, attribute_span) = - if let Some(store) = &def.pallet_struct.store { store } else { return Default::default() }; - - let type_impl_gen = &def.type_impl_generics(trait_store.span()); - let type_use_gen = &def.type_use_generics(trait_store.span()); - let pallet_ident = &def.pallet_struct.pallet; - - let mut where_clauses = vec![&def.config.where_clause]; - where_clauses.extend(def.storages.iter().map(|storage| &storage.where_clause)); - let completed_where_clause = super::merge_where_clauses(&where_clauses); - - let storage_names = &def.storages.iter().map(|storage| &storage.ident).collect::>(); - let storage_cfg_attrs = - &def.storages.iter().map(|storage| &storage.cfg_attrs).collect::>(); - let warnig_struct_name = syn::Ident::new("Store", *attribute_span); - let warning: syn::ItemStruct = syn::parse_quote!( - #[deprecated(note = r" - Use of `#[pallet::generate_store(pub(super) trait Store)]` will be removed after July 2023. - Check https://github.com/paritytech/substrate/pull/13535 for more details.")] - struct #warnig_struct_name; - ); - - quote::quote_spanned!(trait_store.span() => - const _:() = { - #warning - const _: Option<#warnig_struct_name> = None; - }; - #trait_vis trait #trait_store { - #( - #(#storage_cfg_attrs)* - type #storage_names; - )* - } - impl<#type_impl_gen> #trait_store for #pallet_ident<#type_use_gen> - #completed_where_clause - { - #( - #(#storage_cfg_attrs)* - type #storage_names = #storage_names<#type_use_gen>; - )* - } - ) -} diff --git a/substrate/frame/support/procedural/src/pallet/parse/mod.rs b/substrate/frame/support/procedural/src/pallet/parse/mod.rs index e1efdbcc202..b55f130a93a 100644 --- a/substrate/frame/support/procedural/src/pallet/parse/mod.rs +++ b/substrate/frame/support/procedural/src/pallet/parse/mod.rs @@ -558,8 +558,6 @@ mod keyword { syn::custom_keyword!(validate_unsigned); syn::custom_keyword!(type_value); syn::custom_keyword!(pallet); - syn::custom_keyword!(generate_store); - syn::custom_keyword!(Store); syn::custom_keyword!(extra_constants); syn::custom_keyword!(composite_enum); } diff --git a/substrate/frame/support/procedural/src/pallet/parse/pallet_struct.rs b/substrate/frame/support/procedural/src/pallet/parse/pallet_struct.rs index c2855ae38ef..b645760998f 100644 --- a/substrate/frame/support/procedural/src/pallet/parse/pallet_struct.rs +++ b/substrate/frame/support/procedural/src/pallet/parse/pallet_struct.rs @@ -23,10 +23,8 @@ use syn::spanned::Spanned; mod keyword { syn::custom_keyword!(pallet); syn::custom_keyword!(Pallet); - syn::custom_keyword!(generate_store); syn::custom_keyword!(without_storage_info); syn::custom_keyword!(storage_version); - syn::custom_keyword!(Store); } /// Definition of the pallet pallet. @@ -37,8 +35,6 @@ pub struct PalletStructDef { pub instances: Vec, /// The keyword Pallet used (contains span). pub pallet: keyword::Pallet, - /// Whether the trait `Store` must be generated. - pub store: Option<(syn::Visibility, keyword::Store, proc_macro2::Span)>, /// The span of the pallet::pallet attribute. pub attr_span: proc_macro2::Span, /// Whether to specify the storages max encoded len when implementing `StorageInfoTrait`. @@ -49,11 +45,9 @@ pub struct PalletStructDef { } /// Parse for one variant of: -/// * `#[pallet::generate_store($vis trait Store)]` /// * `#[pallet::without_storage_info]` /// * `#[pallet::storage_version(STORAGE_VERSION)]` pub enum PalletStructAttr { - GenerateStore { span: proc_macro2::Span, vis: syn::Visibility, keyword: keyword::Store }, WithoutStorageInfoTrait(proc_macro2::Span), StorageVersion { storage_version: syn::Path, span: proc_macro2::Span }, } @@ -61,9 +55,7 @@ pub enum PalletStructAttr { impl PalletStructAttr { fn span(&self) -> proc_macro2::Span { match self { - Self::GenerateStore { span, .. } | - Self::WithoutStorageInfoTrait(span) | - Self::StorageVersion { span, .. } => *span, + Self::WithoutStorageInfoTrait(span) | Self::StorageVersion { span, .. } => *span, } } } @@ -77,16 +69,7 @@ impl syn::parse::Parse for PalletStructAttr { content.parse::()?; let lookahead = content.lookahead1(); - if lookahead.peek(keyword::generate_store) { - content.parse::()?; - let generate_content; - syn::parenthesized!(generate_content in content); - let vis = generate_content.parse::()?; - generate_content.parse::()?; - let keyword = generate_content.parse::()?; - let span = content.span(); - Ok(Self::GenerateStore { vis, keyword, span }) - } else if lookahead.peek(keyword::without_storage_info) { + if lookahead.peek(keyword::without_storage_info) { let span = content.parse::()?.span(); Ok(Self::WithoutStorageInfoTrait(span)) } else if lookahead.peek(keyword::storage_version) { @@ -116,16 +99,12 @@ impl PalletStructDef { return Err(syn::Error::new(item.span(), msg)) }; - let mut store = None; let mut without_storage_info = None; let mut storage_version_found = None; let struct_attrs: Vec = helper::take_item_pallet_attrs(&mut item.attrs)?; for attr in struct_attrs { match attr { - PalletStructAttr::GenerateStore { vis, keyword, span } if store.is_none() => { - store = Some((vis, keyword, span)); - }, PalletStructAttr::WithoutStorageInfoTrait(span) if without_storage_info.is_none() => { @@ -162,7 +141,6 @@ impl PalletStructDef { index, instances, pallet, - store, attr_span, without_storage_info, storage_version: storage_version_found, diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs index 6ea7fa33e77..07560abd935 100644 --- a/substrate/frame/support/src/lib.rs +++ b/substrate/frame/support/src/lib.rs @@ -702,7 +702,7 @@ pub use frame_support_procedural::crate_to_crate_version; #[macro_export] macro_rules! fail { ( $y:expr ) => {{ - return Err($y.into()) + return Err($y.into()); }}; } @@ -949,7 +949,7 @@ pub mod pallet_prelude { /// pub trait Config: frame_system::Config {} /// } /// ``` -/// +// /// I.e. a regular struct definition named `Pallet`, with generic T and no where clause. /// /// ## Macro expansion: @@ -1341,26 +1341,6 @@ pub mod pallet_macros { /// See [`pallet::storage`](`frame_support::pallet_macros::storage`) for more info. pub use frame_support_procedural::getter; - /// Allows generating the `Store` trait for all storages. - /// - /// DEPRECATED: Will be removed, do not use. - /// See for more details. - /// - /// To generate a `Store` trait associating all storages, annotate your `Pallet` struct - /// with the attribute `#[pallet::generate_store($vis trait Store)]`, e.g.: - /// - /// ```ignore - /// #[pallet::pallet] - /// #[pallet::generate_store(pub(super) trait Store)] - /// pub struct Pallet(_); - /// ``` - /// More precisely, the `Store` trait contains an associated type for each storage. It is - /// implemented for `Pallet` allowing access to the storage from pallet struct. - /// - /// Thus when defining a storage named `Foo`, it can later be accessed from `Pallet` using - /// `::Foo`. - pub use frame_support_procedural::generate_store; - /// Defines constants that are added to the constant field of /// [`PalletMetadata`](frame_metadata::v15::PalletMetadata) struct for this pallet. /// diff --git a/substrate/frame/support/test/tests/pallet_ui/deprecated_store_attr.rs b/substrate/frame/support/test/tests/pallet_ui/deprecated_store_attr.rs deleted file mode 100644 index 72ad7896dfe..00000000000 --- a/substrate/frame/support/test/tests/pallet_ui/deprecated_store_attr.rs +++ /dev/null @@ -1,28 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// 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. - -#[frame_support::pallet] -mod pallet { - #[pallet::config] - pub trait Config: frame_system::Config {} - - #[pallet::pallet] - #[pallet::generate_store(trait Store)] - pub struct Pallet(core::marker::PhantomData); -} - -fn main() {} diff --git a/substrate/frame/support/test/tests/pallet_ui/deprecated_store_attr.stderr b/substrate/frame/support/test/tests/pallet_ui/deprecated_store_attr.stderr deleted file mode 100644 index e227033d364..00000000000 --- a/substrate/frame/support/test/tests/pallet_ui/deprecated_store_attr.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: use of deprecated struct `pallet::_::Store`: - Use of `#[pallet::generate_store(pub(super) trait Store)]` will be removed after July 2023. - Check https://github.com/paritytech/substrate/pull/13535 for more details. - --> tests/pallet_ui/deprecated_store_attr.rs:24:3 - | -24 | #[pallet::generate_store(trait Store)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `-D deprecated` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(deprecated)]` diff --git a/substrate/frame/support/test/tests/pallet_ui/duplicate_store_attr.rs b/substrate/frame/support/test/tests/pallet_ui/duplicate_store_attr.rs deleted file mode 100644 index 334fd8a46af..00000000000 --- a/substrate/frame/support/test/tests/pallet_ui/duplicate_store_attr.rs +++ /dev/null @@ -1,42 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// 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. - -#[frame_support::pallet] -mod pallet { - use frame_support::pallet_prelude::Hooks; - use frame_system::pallet_prelude::BlockNumberFor; - use frame_support::pallet_prelude::StorageValue; - - #[pallet::config] - pub trait Config: frame_system::Config {} - - #[pallet::pallet] - #[pallet::generate_store(trait Store)] - #[pallet::generate_store(trait Store)] - pub struct Pallet(core::marker::PhantomData); - - #[pallet::hooks] - impl Hooks> for Pallet {} - - #[pallet::call] - impl Pallet {} - - #[pallet::storage] - type Foo = StorageValue<_, u8>; -} - -fn main() {} diff --git a/substrate/frame/support/test/tests/pallet_ui/duplicate_store_attr.stderr b/substrate/frame/support/test/tests/pallet_ui/duplicate_store_attr.stderr deleted file mode 100644 index 864b399326e..00000000000 --- a/substrate/frame/support/test/tests/pallet_ui/duplicate_store_attr.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: Unexpected duplicated attribute - --> tests/pallet_ui/duplicate_store_attr.rs:29:3 - | -29 | #[pallet::generate_store(trait Store)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/substrate/frame/support/test/tests/pallet_ui/pallet_struct_invalid_attr.stderr b/substrate/frame/support/test/tests/pallet_ui/pallet_struct_invalid_attr.stderr index 33a2d1da786..6f7f5617f7e 100644 --- a/substrate/frame/support/test/tests/pallet_ui/pallet_struct_invalid_attr.stderr +++ b/substrate/frame/support/test/tests/pallet_ui/pallet_struct_invalid_attr.stderr @@ -1,4 +1,4 @@ -error: expected one of: `generate_store`, `without_storage_info`, `storage_version` +error: expected `without_storage_info` or `storage_version` --> tests/pallet_ui/pallet_struct_invalid_attr.rs:24:12 | 24 | #[pallet::generate_storage_info] // invalid diff --git a/substrate/frame/support/test/tests/pallet_ui/store_trait_leak_private.rs b/substrate/frame/support/test/tests/pallet_ui/store_trait_leak_private.rs deleted file mode 100644 index 55dd315fb29..00000000000 --- a/substrate/frame/support/test/tests/pallet_ui/store_trait_leak_private.rs +++ /dev/null @@ -1,42 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// 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. - -#[frame_support::pallet] -mod pallet { - use frame_support::pallet_prelude::Hooks; - use frame_system::pallet_prelude::BlockNumberFor; - use frame_support::pallet_prelude::StorageValue; - - #[pallet::config] - pub trait Config: frame_system::Config {} - - #[pallet::pallet] - #[pallet::generate_store(pub trait Store)] - pub struct Pallet(core::marker::PhantomData); - - #[pallet::hooks] - impl Hooks> for Pallet {} - - #[pallet::call] - impl Pallet {} - - #[pallet::storage] - type Foo = StorageValue<_, u8>; -} - -fn main() { -} diff --git a/substrate/frame/support/test/tests/pallet_ui/store_trait_leak_private.stderr b/substrate/frame/support/test/tests/pallet_ui/store_trait_leak_private.stderr deleted file mode 100644 index ccb55122e81..00000000000 --- a/substrate/frame/support/test/tests/pallet_ui/store_trait_leak_private.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error: use of deprecated struct `pallet::_::Store`: - Use of `#[pallet::generate_store(pub(super) trait Store)]` will be removed after July 2023. - Check https://github.com/paritytech/substrate/pull/13535 for more details. - --> tests/pallet_ui/store_trait_leak_private.rs:28:3 - | -28 | #[pallet::generate_store(pub trait Store)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `-D deprecated` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(deprecated)]` - -error[E0446]: private type `_GeneratedPrefixForStorageFoo` in public interface - --> tests/pallet_ui/store_trait_leak_private.rs:28:37 - | -28 | #[pallet::generate_store(pub trait Store)] - | ^^^^^ can't leak private type -... -37 | #[pallet::storage] - | ------- `_GeneratedPrefixForStorageFoo` declared as private diff --git a/substrate/frame/support/test/tests/storage_transaction.rs b/substrate/frame/support/test/tests/storage_transaction.rs index c4774330860..f1489a8b0a6 100644 --- a/substrate/frame/support/test/tests/storage_transaction.rs +++ b/substrate/frame/support/test/tests/storage_transaction.rs @@ -41,7 +41,6 @@ pub mod pallet { use frame_system::pallet_prelude::*; #[pallet::pallet] - #[pallet::generate_store(pub (super) trait Store)] pub struct Pallet(_); #[pallet::config] -- GitLab From 7839400f1203b1c1de2ff84db5f5ffcf31e20d87 Mon Sep 17 00:00:00 2001 From: georgepisaltu <52418509+georgepisaltu@users.noreply.github.com> Date: Tue, 12 Mar 2024 00:12:58 +0200 Subject: [PATCH 384/392] [Collator Selection] Fix weight refund for `set_candidacy_bond` (#3643) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #3642 This PR implements the weight refund of `pallet_collator_selection::set_candidacy_bond` to account for no iterations when the bond is decreased. --------- Signed-off-by: georgepisaltu Co-authored-by: Bastian Köcher --- cumulus/pallets/collator-selection/src/lib.rs | 6 +++++- prdoc/pr_3643.prdoc | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 prdoc/pr_3643.prdoc diff --git a/cumulus/pallets/collator-selection/src/lib.rs b/cumulus/pallets/collator-selection/src/lib.rs index fb4c4a445df..62c00737f91 100644 --- a/cumulus/pallets/collator-selection/src/lib.rs +++ b/cumulus/pallets/collator-selection/src/lib.rs @@ -495,7 +495,11 @@ pub mod pallet { }) .unwrap_or_default(); Self::deposit_event(Event::NewCandidacyBond { bond_amount: bond }); - Ok(Some(T::WeightInfo::set_candidacy_bond(initial_len as u32, kicked as u32)).into()) + Ok(Some(T::WeightInfo::set_candidacy_bond( + bond_increased.then(|| initial_len as u32).unwrap_or_default(), + kicked as u32, + )) + .into()) } /// Register this account as a collator candidate. The account must (a) already have diff --git a/prdoc/pr_3643.prdoc b/prdoc/pr_3643.prdoc new file mode 100644 index 00000000000..6e85af8d99a --- /dev/null +++ b/prdoc/pr_3643.prdoc @@ -0,0 +1,12 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Fix weight refund for `pallet_collator_selection::set_candidacy_bond` + +doc: + - audience: Runtime Dev + description: | + This PR implements the weight refund of `pallet_collator_selection::set_candidacy_bond` to + account for no iterations over the candidate list when the candidacy bond is decreased. +crates: + - name: pallet-collator-selection -- GitLab From 7a644fa082f09b557a8a198ed56412f02062bbcf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Mar 2024 23:20:48 +0100 Subject: [PATCH 385/392] Bump handlebars from 4.3.7 to 5.1.0 (#3248) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [handlebars](https://github.com/sunng87/handlebars-rust) from 4.3.7 to 5.1.0.
Release notes

Sourced from handlebars's releases.

v5.1.0

What's Changed

New Contributors

Full Changelog: https://github.com/sunng87/handlebars-rust/compare/v5.0.0...v5.1.0

v5.0.0

5.0.0

A semver major release that introduces some API breaking changes.

Highlights

  • RenderError has been rewritten for typed error reason. In previous versions we use string message for RenderError which is impossible to handle with code. This version introduces RenderErrorReason so you can use match to deal various error reasons.
  • Lifetime in Helper trait has been simplified.

Changes compared to 4.3

  • [Added] public mutable access to local variables in BlockContext #533
  • [Changed] Simplified lifetime specifiers for Helper, ScopedJson and some other related types and functions. #532
  • [Changed] Updated TemplateError to reduce its size. Direct field access is removed in favor of access methods
  • [Changed] Introducing RenderErrorReason for typed render error
  • [Changed] Changed register_template_directory api for more customizations #[610]
  • [Changed] Updated rust-embed to 8.0

Collaboration Wanted

I'm looking for collaborations to join the development with me on this project. Contact via email if your are interested in.

Auto-generated changelog

... (truncated)

Changelog

Sourced from handlebars's changelog.

5.1.0 - 2024-01-17

  • [Added] Chained else if block support #629

5.0.0 - 2023-12-31

  • [Added] public mutable access to local variables in BlockContext #533
  • [Changed] Simplified lifetime specifiers for Helper, ScopedJson and some other related types and functions. #532
  • [Changed] Updated TemplateError to reduce its size. Direct field access is removed in favor of access methods
  • [Changed] Introducing RenderErrorReason for typed render error
  • [Changed] Changed register_template_directory api for more customizations #[610]
  • [Changed] Updated rust-embed to 8.0

4.3.4 - 2022-09-11

  • [Added] New write_fmt function for Output #522
  • [Added] reason() method for TemplateError to access underlying reason, this replaces original direct .reason access.
  • [Changed] Direct access to TemplateError's reason field is depreacted will be removed in future.

4.3.3 - 2022-07-20

  • [Fixed] Disable partial expression indentation with {{~> partial}} to bring behavior closer in line with original javascript version. #518
  • [Fixed] Support for using partial context together with partial parameters #520

4.3.2 - 2022-07-14

  • [Added] Render functions that reuse Context for custom std::io::Write: render_with_context_to_write and render_template_with_context_to_write

4.3.1 - 2022-06-09

  • [Added] Added support for {{~{variable}~}} syntax #509

4.3.0 - 2022-05-18

  • [Changed] update MSRV to 1.57 as rhai requires
  • [Fixed] Reimplemented indent support for partial expression {{> partial}}, which is introduced in 4.2.0. The new implementation is aligned with original javascript version, that every text line generated from partial are indented as {{> partial}} does. prevent_indent will turn-off this feature. #505
  • [Changed] changed error support library from quick_error to thiserror

... (truncated)

Commits
  • d8d9a78 chore: Release handlebars version 5.1.0
  • 137bce5 chore: minor cleanup for chained else support in #629
  • e30d8ab Merge pull request #629 from progmboy/else_chain
  • 8f16353 format code
  • 786d132 add else chain support
  • 23672e8 Merge pull request #628 from sunng87/dependabot/npm_and_yarn/playground/www/f...
  • b849efd chore(deps-dev): bump follow-redirects in /playground/www
  • 7071c9d test: add test for error reason
  • 4664a34 (cargo-release) version 5.0.0
  • ca27748 Merge pull request #625 from sunng87/refactor/render-error-reason-2
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=handlebars&package-manager=cargo&previous-version=4.3.7&new-version=5.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) You can trigger a rebase of this PR by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
> **Note** > Automatic rebases have been disabled on this pull request as it has been open for over 30 days. Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Bastian Köcher --- Cargo.lock | 4 ++-- substrate/utils/frame/benchmarking-cli/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0b7ea71a536..7eaf3e44a1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6256,9 +6256,9 @@ checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" [[package]] name = "handlebars" -version = "4.3.7" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c3372087601b532857d332f5957cbae686da52bb7810bf038c3e3c3cc2fa0d" +checksum = "ab283476b99e66691dee3f1640fea91487a8d81f50fb5ecc75538f8f8879a1e4" dependencies = [ "log", "pest", diff --git a/substrate/utils/frame/benchmarking-cli/Cargo.toml b/substrate/utils/frame/benchmarking-cli/Cargo.toml index a2db83052c5..a25ab3a8f5b 100644 --- a/substrate/utils/frame/benchmarking-cli/Cargo.toml +++ b/substrate/utils/frame/benchmarking-cli/Cargo.toml @@ -21,7 +21,7 @@ chrono = "0.4" clap = { version = "4.5.1", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.6.1" } comfy-table = { version = "7.1.0", default-features = false } -handlebars = "4.2.2" +handlebars = "5.1.0" Inflector = "0.11.4" itertools = "0.10.3" lazy_static = "1.4.0" -- GitLab From 7315a9b8fdc18848025a83f18c643573d9be9e1e Mon Sep 17 00:00:00 2001 From: gupnik Date: Tue, 12 Mar 2024 10:12:58 +0530 Subject: [PATCH 386/392] Adds default config for assets pallet (#3637) Step in https://github.com/paritytech/polkadot-sdk/issues/171 --- substrate/frame/assets/src/lib.rs | 43 +++++++++++++++++++++++++++++- substrate/frame/assets/src/mock.rs | 16 +---------- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/substrate/frame/assets/src/lib.rs b/substrate/frame/assets/src/lib.rs index 60316f8cdcf..09d59ae1b8b 100644 --- a/substrate/frame/assets/src/lib.rs +++ b/substrate/frame/assets/src/lib.rs @@ -226,10 +226,42 @@ pub mod pallet { } } - #[pallet::config] + /// Default implementations of [`DefaultConfig`], which can be used to implement [`Config`]. + pub mod config_preludes { + use super::*; + use frame_support::{derive_impl, traits::ConstU64}; + pub struct TestDefaultConfig; + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig, no_aggregated_types)] + impl frame_system::DefaultConfig for TestDefaultConfig {} + + #[frame_support::register_default_impl(TestDefaultConfig)] + impl DefaultConfig for TestDefaultConfig { + #[inject_runtime_type] + type RuntimeEvent = (); + type Balance = u64; + type RemoveItemsLimit = ConstU32<5>; + type AssetId = u32; + type AssetIdParameter = u32; + type AssetDeposit = ConstU64<1>; + type AssetAccountDeposit = ConstU64<10>; + type MetadataDepositBase = ConstU64<1>; + type MetadataDepositPerByte = ConstU64<1>; + type ApprovalDeposit = ConstU64<1>; + type StringLimit = ConstU32<50>; + type Extra = (); + type CallbackHandle = (); + type WeightInfo = (); + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); + } + } + + #[pallet::config(with_default)] /// The module configuration trait. pub trait Config: frame_system::Config { /// The overarching event type. + #[pallet::no_default_bounds] type RuntimeEvent: From> + IsType<::RuntimeEvent>; @@ -262,10 +294,12 @@ pub mod pallet { type AssetIdParameter: Parameter + From + Into + MaxEncodedLen; /// The currency mechanism. + #[pallet::no_default] type Currency: ReservableCurrency; /// Standard asset class creation is only allowed if the origin attempting it and the /// asset class are in this set. + #[pallet::no_default] type CreateOrigin: EnsureOriginWithArg< Self::RuntimeOrigin, Self::AssetId, @@ -274,28 +308,34 @@ pub mod pallet { /// The origin which may forcibly create or destroy an asset or otherwise alter privileged /// attributes. + #[pallet::no_default] type ForceOrigin: EnsureOrigin; /// The basic amount of funds that must be reserved for an asset. #[pallet::constant] + #[pallet::no_default_bounds] type AssetDeposit: Get>; /// The amount of funds that must be reserved for a non-provider asset account to be /// maintained. #[pallet::constant] + #[pallet::no_default_bounds] type AssetAccountDeposit: Get>; /// The basic amount of funds that must be reserved when adding metadata to your asset. #[pallet::constant] + #[pallet::no_default_bounds] type MetadataDepositBase: Get>; /// The additional funds that must be reserved for the number of bytes you store in your /// metadata. #[pallet::constant] + #[pallet::no_default_bounds] type MetadataDepositPerByte: Get>; /// The amount of funds that must be reserved when creating a new approval. #[pallet::constant] + #[pallet::no_default_bounds] type ApprovalDeposit: Get>; /// The maximum length of a name or symbol stored on-chain. @@ -304,6 +344,7 @@ pub mod pallet { /// A hook to allow a per-asset, per-account minimum balance to be enforced. This must be /// respected in all permissionless operations. + #[pallet::no_default] type Freezer: FrozenBalance; /// Additional data to be stored with an account's asset balance. diff --git a/substrate/frame/assets/src/mock.rs b/substrate/frame/assets/src/mock.rs index e1722200c35..906febb0214 100644 --- a/substrate/frame/assets/src/mock.rs +++ b/substrate/frame/assets/src/mock.rs @@ -108,27 +108,13 @@ impl AssetsCallbackHandle { } } +#[derive_impl(crate::config_preludes::TestDefaultConfig)] impl Config for Test { - type RuntimeEvent = RuntimeEvent; - type Balance = u64; - type AssetId = u32; - type AssetIdParameter = u32; type Currency = Balances; type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = frame_system::EnsureRoot; - type AssetDeposit = ConstU64<1>; - type AssetAccountDeposit = ConstU64<10>; - type MetadataDepositBase = ConstU64<1>; - type MetadataDepositPerByte = ConstU64<1>; - type ApprovalDeposit = ConstU64<1>; - type StringLimit = ConstU32<50>; type Freezer = TestFreezer; - type WeightInfo = (); type CallbackHandle = AssetsCallbackHandle; - type Extra = (); - type RemoveItemsLimit = ConstU32<5>; - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = (); } use std::collections::HashMap; -- GitLab From b0f34e4b2953f814254f92c8d151f22ffcf9c034 Mon Sep 17 00:00:00 2001 From: Koute Date: Tue, 12 Mar 2024 14:23:06 +0900 Subject: [PATCH 387/392] Add a PolkaVM-based executor (#3458) This PR adds a new PolkaVM-based executor to Substrate. - The executor can now be used to actually run a PolkaVM-based runtime, and successfully produces blocks. - The executor is always compiled-in, but is disabled by default. - The `SUBSTRATE_ENABLE_POLKAVM` environment variable must be set to `1` to enable the executor, in which case the node will accept both WASM and PolkaVM program blobs (otherwise it'll default to WASM-only). This is deliberately undocumented and not explicitly exposed anywhere (e.g. in the command line arguments, or in the API) to disincentivize anyone from enabling it in production. If/when we'll move this into production usage I'll remove the environment variable and do it "properly". - I did not use our legacy runtime allocator for the PolkaVM executor, so currently every allocation inside of the runtime will leak guest memory until that particular instance is destroyed. The idea here is that I will work on the https://github.com/polkadot-fellows/RFCs/pull/4 which will remove the need for the legacy allocator under WASM, and that will also allow us to use a proper non-leaking allocator under PolkaVM. - I also did some minor cleanups of the WASM executor and deleted some dead code. No prdocs included since this is not intended to be an end-user feature, but an unofficial experiment, and shouldn't affect any current production user. Once this is production-ready a full Polkadot Fellowship RFC will be necessary anyway. --- Cargo.lock | 74 ++++- Cargo.toml | 6 +- .../core/pvf/common/src/executor_interface.rs | 4 +- substrate/client/executor/Cargo.toml | 1 + substrate/client/executor/common/Cargo.toml | 1 + substrate/client/executor/common/src/error.rs | 18 ++ substrate/client/executor/common/src/lib.rs | 4 + .../common/src/runtime_blob/runtime_blob.rs | 153 +++++----- .../executor/common/src/wasm_runtime.rs | 50 +--- substrate/client/executor/polkavm/Cargo.toml | 23 ++ substrate/client/executor/polkavm/README.md | 1 + substrate/client/executor/polkavm/src/lib.rs | 261 ++++++++++++++++++ substrate/client/executor/src/wasm_runtime.rs | 4 + .../executor/wasmtime/src/instance_wrapper.rs | 148 ++-------- .../client/executor/wasmtime/src/runtime.rs | 19 +- substrate/primitives/io/Cargo.toml | 3 + .../primitives/io/src/global_alloc_riscv.rs | 19 ++ .../primitives/io/src/global_alloc_wasm.rs | 34 +++ substrate/primitives/io/src/lib.rs | 34 +-- .../utils/wasm-builder/src/wasm_project.rs | 2 +- 20 files changed, 559 insertions(+), 300 deletions(-) create mode 100644 substrate/client/executor/polkavm/Cargo.toml create mode 100644 substrate/client/executor/polkavm/README.md create mode 100644 substrate/client/executor/polkavm/src/lib.rs create mode 100644 substrate/primitives/io/src/global_alloc_riscv.rs create mode 100644 substrate/primitives/io/src/global_alloc_wasm.rs diff --git a/Cargo.lock b/Cargo.lock index 7eaf3e44a1b..5eab3cf7c24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13805,6 +13805,28 @@ dependencies = [ "westend-runtime", ] +[[package]] +name = "polkavm" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a3693e5efdb2bf74e449cd25fd777a28bd7ed87e41f5d5da75eb31b4de48b94" +dependencies = [ + "libc", + "log", + "polkavm-assembler", + "polkavm-common 0.9.0", + "polkavm-linux-raw", +] + +[[package]] +name = "polkavm-assembler" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa96d6d868243acc12de813dd48e756cbadcc8e13964c70d272753266deadc1" +dependencies = [ + "log", +] + [[package]] name = "polkavm-common" version = "0.5.0" @@ -13813,9 +13835,12 @@ checksum = "88b4e215c80fe876147f3d58158d5dfeae7dabdd6047e175af77095b78d0035c" [[package]] name = "polkavm-common" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92c99f7eee94e7be43ba37eef65ad0ee8cbaf89b7c00001c3f6d2be985cb1817" +checksum = "1d9428a5cfcc85c5d7b9fc4b6a18c4b802d0173d768182a51cc7751640f08b92" +dependencies = [ + "log", +] [[package]] name = "polkavm-derive" @@ -13829,9 +13854,9 @@ dependencies = [ [[package]] name = "polkavm-derive" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79fa916f7962348bd1bb1a65a83401675e6fc86c51a0fdbcf92a3108e58e6125" +checksum = "ae8c4bea6f3e11cd89bb18bcdddac10bd9a24015399bd1c485ad68a985a19606" dependencies = [ "polkavm-derive-impl-macro", ] @@ -13850,11 +13875,11 @@ dependencies = [ [[package]] name = "polkavm-derive-impl" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c10b2654a8a10a83c260bfb93e97b262cf0017494ab94a65d389e0eda6de6c9c" +checksum = "5c4fdfc49717fb9a196e74a5d28e0bc764eb394a2c803eb11133a31ac996c60c" dependencies = [ - "polkavm-common 0.8.0", + "polkavm-common 0.9.0", "proc-macro2", "quote", "syn 2.0.50", @@ -13862,11 +13887,11 @@ dependencies = [ [[package]] name = "polkavm-derive-impl-macro" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e85319a0d5129dc9f021c62607e0804f5fb777a05cdda44d750ac0732def66" +checksum = "8ba81f7b5faac81e528eb6158a6f3c9e0bb1008e0ffa19653bc8dea925ecb429" dependencies = [ - "polkavm-derive-impl 0.8.0", + "polkavm-derive-impl 0.9.0", "syn 2.0.50", ] @@ -13887,19 +13912,25 @@ dependencies = [ [[package]] name = "polkavm-linker" -version = "0.8.2" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdec1451cb18261d5d01de82acc15305e417fb59588cdcb3127d3dcc9672b925" +checksum = "9c7be503e60cf56c0eb785f90aaba4b583b36bff00e93997d93fef97f9553c39" dependencies = [ "gimli 0.28.0", "hashbrown 0.14.3", "log", "object 0.32.2", - "polkavm-common 0.8.0", + "polkavm-common 0.9.0", "regalloc2 0.9.3", "rustc-demangle", ] +[[package]] +name = "polkavm-linux-raw" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26e85d3456948e650dff0cfc85603915847faf893ed1e66b020bb82ef4557120" + [[package]] name = "polling" version = "2.8.0" @@ -16112,6 +16143,7 @@ dependencies = [ "paste", "regex", "sc-executor-common", + "sc-executor-polkavm", "sc-executor-wasmtime", "sc-runtime-test", "sc-tracing", @@ -16141,6 +16173,7 @@ dependencies = [ name = "sc-executor-common" version = "0.29.0" dependencies = [ + "polkavm", "sc-allocator", "sp-maybe-compressed-blob", "sp-wasm-interface 20.0.0", @@ -16148,6 +16181,16 @@ dependencies = [ "wasm-instrument", ] +[[package]] +name = "sc-executor-polkavm" +version = "0.29.0" +dependencies = [ + "log", + "polkavm", + "sc-executor-common", + "sp-wasm-interface 20.0.0", +] + [[package]] name = "sc-executor-wasmtime" version = "0.29.0" @@ -18781,6 +18824,7 @@ dependencies = [ "libsecp256k1", "log", "parity-scale-codec", + "polkavm-derive 0.9.1", "rustversion", "secp256k1", "sp-core", @@ -18973,7 +19017,7 @@ dependencies = [ "bytes", "impl-trait-for-tuples", "parity-scale-codec", - "polkavm-derive 0.8.0", + "polkavm-derive 0.9.1", "primitive-types", "rustversion", "sp-core", @@ -19995,7 +20039,7 @@ dependencies = [ "console", "filetime", "parity-wasm", - "polkavm-linker 0.8.2", + "polkavm-linker 0.9.2", "sp-maybe-compressed-blob", "strum 0.24.1", "tempfile", diff --git a/Cargo.toml b/Cargo.toml index 80068596685..f256d02808a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -249,6 +249,7 @@ members = [ "substrate/client/db", "substrate/client/executor", "substrate/client/executor/common", + "substrate/client/executor/polkavm", "substrate/client/executor/runtime-test", "substrate/client/executor/wasmtime", "substrate/client/informant", @@ -543,8 +544,9 @@ extra-unused-type-parameters = { level = "allow", priority = 2 } # stylistic default_constructed_unit_structs = { level = "allow", priority = 2 } # stylistic [workspace.dependencies] -polkavm-linker = "0.8.2" -polkavm-derive = "0.8.0" +polkavm = "0.9.3" +polkavm-linker = "0.9.2" +polkavm-derive = "0.9.1" log = { version = "0.4.20", default-features = false } quote = { version = "1.0.33" } serde = { version = "1.0.197", default-features = false } diff --git a/polkadot/node/core/pvf/common/src/executor_interface.rs b/polkadot/node/core/pvf/common/src/executor_interface.rs index b69a87890f6..252e611db8a 100644 --- a/polkadot/node/core/pvf/common/src/executor_interface.rs +++ b/polkadot/node/core/pvf/common/src/executor_interface.rs @@ -24,7 +24,7 @@ use polkadot_primitives::{ use sc_executor_common::{ error::WasmError, runtime_blob::RuntimeBlob, - wasm_runtime::{HeapAllocStrategy, InvokeMethod, WasmModule as _}, + wasm_runtime::{HeapAllocStrategy, WasmModule as _}, }; use sc_executor_wasmtime::{Config, DeterministicStackLimit, Semantics, WasmtimeRuntime}; use sp_core::storage::{ChildInfo, TrackedStorageKey}; @@ -119,7 +119,7 @@ pub unsafe fn execute_artifact( match sc_executor::with_externalities_safe(&mut ext, || { let runtime = create_runtime_from_artifact_bytes(compiled_artifact_blob, executor_params)?; - runtime.new_instance()?.call(InvokeMethod::Export("validate_block"), params) + runtime.new_instance()?.call("validate_block", params) }) { Ok(Ok(ok)) => Ok(ok), Ok(Err(err)) | Err(err) => Err(err), diff --git a/substrate/client/executor/Cargo.toml b/substrate/client/executor/Cargo.toml index 4e36de3c4f4..7fad7e3a2a0 100644 --- a/substrate/client/executor/Cargo.toml +++ b/substrate/client/executor/Cargo.toml @@ -23,6 +23,7 @@ tracing = "0.1.29" codec = { package = "parity-scale-codec", version = "3.6.1" } sc-executor-common = { path = "common" } +sc-executor-polkavm = { path = "polkavm" } sc-executor-wasmtime = { path = "wasmtime" } sp-api = { path = "../../primitives/api" } sp-core = { path = "../../primitives/core" } diff --git a/substrate/client/executor/common/Cargo.toml b/substrate/client/executor/common/Cargo.toml index bfd1fa6b740..8ff34c3709a 100644 --- a/substrate/client/executor/common/Cargo.toml +++ b/substrate/client/executor/common/Cargo.toml @@ -22,6 +22,7 @@ wasm-instrument = "0.4" sc-allocator = { path = "../../allocator" } sp-maybe-compressed-blob = { path = "../../../primitives/maybe-compressed-blob" } sp-wasm-interface = { path = "../../../primitives/wasm-interface" } +polkavm = { workspace = true } [features] default = [] diff --git a/substrate/client/executor/common/src/error.rs b/substrate/client/executor/common/src/error.rs index 2a0dc364b41..b7c7e2b7019 100644 --- a/substrate/client/executor/common/src/error.rs +++ b/substrate/client/executor/common/src/error.rs @@ -150,6 +150,24 @@ pub enum WasmError { Other(String), } +impl From for WasmError { + fn from(error: polkavm::ProgramParseError) -> Self { + WasmError::Other(error.to_string()) + } +} + +impl From for WasmError { + fn from(error: polkavm::Error) -> Self { + WasmError::Other(error.to_string()) + } +} + +impl From for Error { + fn from(error: polkavm::Error) -> Self { + Error::Other(error.to_string()) + } +} + /// An error message with an attached backtrace. #[derive(Debug)] pub struct MessageWithBacktrace { diff --git a/substrate/client/executor/common/src/lib.rs b/substrate/client/executor/common/src/lib.rs index 751801fb30d..ff9fab2c888 100644 --- a/substrate/client/executor/common/src/lib.rs +++ b/substrate/client/executor/common/src/lib.rs @@ -25,3 +25,7 @@ pub mod error; pub mod runtime_blob; pub mod util; pub mod wasm_runtime; + +pub(crate) fn is_polkavm_enabled() -> bool { + std::env::var_os("SUBSTRATE_ENABLE_POLKAVM").map_or(false, |value| value == "1") +} diff --git a/substrate/client/executor/common/src/runtime_blob/runtime_blob.rs b/substrate/client/executor/common/src/runtime_blob/runtime_blob.rs index becf9e219b0..d689083b2f8 100644 --- a/substrate/client/executor/common/src/runtime_blob/runtime_blob.rs +++ b/substrate/client/executor/common/src/runtime_blob/runtime_blob.rs @@ -17,23 +17,23 @@ // along with this program. If not, see . use crate::{error::WasmError, wasm_runtime::HeapAllocStrategy}; -use wasm_instrument::{ - export_mutable_globals, - parity_wasm::elements::{ - deserialize_buffer, serialize, ExportEntry, External, Internal, MemorySection, MemoryType, - Module, Section, - }, +use wasm_instrument::parity_wasm::elements::{ + deserialize_buffer, serialize, ExportEntry, External, Internal, MemorySection, MemoryType, + Module, Section, }; -/// A bunch of information collected from a WebAssembly module. +/// A program blob containing a Substrate runtime. #[derive(Clone)] -pub struct RuntimeBlob { - raw_module: Module, +pub struct RuntimeBlob(BlobKind); + +#[derive(Clone)] +enum BlobKind { + WebAssembly(Module), + PolkaVM(polkavm::ProgramBlob<'static>), } impl RuntimeBlob { - /// Create `RuntimeBlob` from the given wasm code. Will attempt to decompress the code before - /// deserializing it. + /// Create `RuntimeBlob` from the given WASM or PolkaVM compressed program blob. /// /// See [`sp_maybe_compressed_blob`] for details about decompression. pub fn uncompress_if_needed(wasm_code: &[u8]) -> Result { @@ -43,31 +43,26 @@ impl RuntimeBlob { Self::new(&wasm_code) } - /// Create `RuntimeBlob` from the given wasm code. + /// Create `RuntimeBlob` from the given WASM or PolkaVM program blob. /// - /// Returns `Err` if the wasm code cannot be deserialized. - pub fn new(wasm_code: &[u8]) -> Result { - let raw_module: Module = deserialize_buffer(wasm_code) - .map_err(|e| WasmError::Other(format!("cannot deserialize module: {:?}", e)))?; - Ok(Self { raw_module }) - } - - /// The number of globals defined in locally in this module. - pub fn declared_globals_count(&self) -> u32 { - self.raw_module - .global_section() - .map(|gs| gs.entries().len() as u32) - .unwrap_or(0) - } - - /// The number of imports of globals. - pub fn imported_globals_count(&self) -> u32 { - self.raw_module.import_section().map(|is| is.globals() as u32).unwrap_or(0) - } + /// Returns `Err` if the blob cannot be deserialized. + /// + /// Will only accept a PolkaVM program if the `SUBSTRATE_ENABLE_POLKAVM` environment + /// variable is set to `1`. + pub fn new(raw_blob: &[u8]) -> Result { + if raw_blob.starts_with(b"PVM\0") { + if crate::is_polkavm_enabled() { + return Ok(Self(BlobKind::PolkaVM( + polkavm::ProgramBlob::parse(raw_blob)?.into_owned(), + ))); + } else { + return Err(WasmError::Other("expected a WASM runtime blob, found a PolkaVM runtime blob; set the 'SUBSTRATE_ENABLE_POLKAVM' environment variable to enable the experimental PolkaVM-based executor".to_string())); + } + } - /// Perform an instrumentation that makes sure that the mutable globals are exported. - pub fn expose_mutable_globals(&mut self) { - export_mutable_globals(&mut self.raw_module, "exported_internal_global"); + let raw_module: Module = deserialize_buffer(raw_blob) + .map_err(|e| WasmError::Other(format!("cannot deserialize module: {:?}", e)))?; + Ok(Self(BlobKind::WebAssembly(raw_module))) } /// Run a pass that instrument this module so as to introduce a deterministic stack height @@ -80,26 +75,16 @@ impl RuntimeBlob { /// /// The stack cost of a function is computed based on how much locals there are and the maximum /// depth of the wasm operand stack. + /// + /// Only valid for WASM programs; will return an error if the blob is a PolkaVM program. pub fn inject_stack_depth_metering(self, stack_depth_limit: u32) -> Result { let injected_module = - wasm_instrument::inject_stack_limiter(self.raw_module, stack_depth_limit).map_err( - |e| WasmError::Other(format!("cannot inject the stack limiter: {:?}", e)), - )?; - - Ok(Self { raw_module: injected_module }) - } + wasm_instrument::inject_stack_limiter(self.into_webassembly_blob()?, stack_depth_limit) + .map_err(|e| { + WasmError::Other(format!("cannot inject the stack limiter: {:?}", e)) + })?; - /// Perform an instrumentation that makes sure that a specific function `entry_point` is - /// exported - pub fn entry_point_exists(&self, entry_point: &str) -> bool { - self.raw_module - .export_section() - .map(|e| { - e.entries().iter().any(|e| { - matches!(e.internal(), Internal::Function(_)) && e.field() == entry_point - }) - }) - .unwrap_or_default() + Ok(Self(BlobKind::WebAssembly(injected_module))) } /// Converts a WASM memory import into a memory section and exports it. @@ -107,8 +92,11 @@ impl RuntimeBlob { /// Does nothing if there's no memory import. /// /// May return an error in case the WASM module is invalid. + /// + /// Only valid for WASM programs; will return an error if the blob is a PolkaVM program. pub fn convert_memory_import_into_export(&mut self) -> Result<(), WasmError> { - let import_section = match self.raw_module.import_section_mut() { + let raw_module = self.as_webassembly_blob_mut()?; + let import_section = match raw_module.import_section_mut() { Some(import_section) => import_section, None => return Ok(()), }; @@ -124,7 +112,7 @@ impl RuntimeBlob { let memory_name = entry.field().to_owned(); import_entries.remove(index); - self.raw_module + raw_module .insert_section(Section::Memory(MemorySection::with_entries(vec![memory_ty]))) .map_err(|error| { WasmError::Other(format!( @@ -133,14 +121,14 @@ impl RuntimeBlob { )) })?; - if self.raw_module.export_section_mut().is_none() { + if raw_module.export_section_mut().is_none() { // A module without an export section is somewhat unrealistic, but let's do this // just in case to cover all of our bases. - self.raw_module + raw_module .insert_section(Section::Export(Default::default())) .expect("an export section can be always inserted if it doesn't exist; qed"); } - self.raw_module + raw_module .export_section_mut() .expect("export section already existed or we just added it above, so it always exists; qed") .entries_mut() @@ -156,12 +144,14 @@ impl RuntimeBlob { /// /// Will return an error in case there is no memory section present, /// or if the memory section is empty. + /// + /// Only valid for WASM programs; will return an error if the blob is a PolkaVM program. pub fn setup_memory_according_to_heap_alloc_strategy( &mut self, heap_alloc_strategy: HeapAllocStrategy, ) -> Result<(), WasmError> { - let memory_section = self - .raw_module + let raw_module = self.as_webassembly_blob_mut()?; + let memory_section = raw_module .memory_section_mut() .ok_or_else(|| WasmError::Other("no memory section found".into()))?; @@ -187,8 +177,11 @@ impl RuntimeBlob { /// Scans the wasm blob for the first section with the name that matches the given. Returns the /// contents of the custom section if found or `None` otherwise. + /// + /// Only valid for WASM programs; will return an error if the blob is a PolkaVM program. pub fn custom_section_contents(&self, section_name: &str) -> Option<&[u8]> { - self.raw_module + self.as_webassembly_blob() + .ok()? .custom_sections() .find(|cs| cs.name() == section_name) .map(|cs| cs.payload()) @@ -196,11 +189,45 @@ impl RuntimeBlob { /// Consumes this runtime blob and serializes it. pub fn serialize(self) -> Vec { - serialize(self.raw_module).expect("serializing into a vec should succeed; qed") + match self.0 { + BlobKind::WebAssembly(raw_module) => + serialize(raw_module).expect("serializing into a vec should succeed; qed"), + BlobKind::PolkaVM(ref blob) => blob.as_bytes().to_vec(), + } + } + + fn as_webassembly_blob(&self) -> Result<&Module, WasmError> { + match self.0 { + BlobKind::WebAssembly(ref raw_module) => Ok(raw_module), + BlobKind::PolkaVM(..) => Err(WasmError::Other( + "expected a WebAssembly program; found a PolkaVM program blob".into(), + )), + } } - /// Destructure this structure into the underlying parity-wasm Module. - pub fn into_inner(self) -> Module { - self.raw_module + fn as_webassembly_blob_mut(&mut self) -> Result<&mut Module, WasmError> { + match self.0 { + BlobKind::WebAssembly(ref mut raw_module) => Ok(raw_module), + BlobKind::PolkaVM(..) => Err(WasmError::Other( + "expected a WebAssembly program; found a PolkaVM program blob".into(), + )), + } + } + + fn into_webassembly_blob(self) -> Result { + match self.0 { + BlobKind::WebAssembly(raw_module) => Ok(raw_module), + BlobKind::PolkaVM(..) => Err(WasmError::Other( + "expected a WebAssembly program; found a PolkaVM program blob".into(), + )), + } + } + + /// Gets a reference to the inner PolkaVM program blob, if this is a PolkaVM program. + pub fn as_polkavm_blob(&self) -> Option<&polkavm::ProgramBlob> { + match self.0 { + BlobKind::WebAssembly(..) => None, + BlobKind::PolkaVM(ref blob) => Some(blob), + } } } diff --git a/substrate/client/executor/common/src/wasm_runtime.rs b/substrate/client/executor/common/src/wasm_runtime.rs index d8e142b9d55..e8f429a3dbb 100644 --- a/substrate/client/executor/common/src/wasm_runtime.rs +++ b/substrate/client/executor/common/src/wasm_runtime.rs @@ -19,7 +19,6 @@ //! Definitions for a wasm runtime. use crate::error::Error; -use sp_wasm_interface::Value; pub use sc_allocator::AllocationStats; @@ -30,46 +29,6 @@ pub const DEFAULT_HEAP_ALLOC_STRATEGY: HeapAllocStrategy = /// Default heap allocation pages. pub const DEFAULT_HEAP_ALLOC_PAGES: u32 = 2048; -/// A method to be used to find the entrypoint when calling into the runtime -/// -/// Contains variants on how to resolve wasm function that will be invoked. -pub enum InvokeMethod<'a> { - /// Call function exported with this name. - /// - /// Located function should have (u32, u32) -> u64 signature. - Export(&'a str), - /// Call a function found in the exported table found under the given index. - /// - /// Located function should have (u32, u32) -> u64 signature. - Table(u32), - /// Call function by reference from table through a wrapper. - /// - /// Invoked function (`dispatcher_ref`) function - /// should have (u32, u32, u32) -> u64 signature. - /// - /// `func` will be passed to the invoked function as a first argument. - TableWithWrapper { - /// Wrapper for the call. - /// - /// Function pointer, index into runtime exported table. - dispatcher_ref: u32, - /// Extra argument for dispatch. - /// - /// Common usage would be to use it as an actual wasm function pointer - /// that should be invoked, but can be used as any extra argument on the - /// callee side. - /// - /// This is typically generated and invoked by the runtime itself. - func: u32, - }, -} - -impl<'a> From<&'a str> for InvokeMethod<'a> { - fn from(val: &'a str) -> InvokeMethod<'a> { - InvokeMethod::Export(val) - } -} - /// A trait that defines an abstract WASM runtime module. /// /// This can be implemented by an execution engine. @@ -87,7 +46,7 @@ pub trait WasmInstance: Send { /// Before execution, instance is reset. /// /// Returns the encoded result on success. - fn call(&mut self, method: InvokeMethod, data: &[u8]) -> Result, Error> { + fn call(&mut self, method: &str, data: &[u8]) -> Result, Error> { self.call_with_allocation_stats(method, data).0 } @@ -98,7 +57,7 @@ pub trait WasmInstance: Send { /// Returns the encoded result on success. fn call_with_allocation_stats( &mut self, - method: InvokeMethod, + method: &str, data: &[u8], ) -> (Result, Error>, Option); @@ -110,11 +69,6 @@ pub trait WasmInstance: Send { fn call_export(&mut self, method: &str, data: &[u8]) -> Result, Error> { self.call(method.into(), data) } - - /// Get the value from a global with the given `name`. - /// - /// This method is only suitable for getting immutable globals. - fn get_global_const(&mut self, name: &str) -> Result, Error>; } /// Defines the heap pages allocation strategy the wasm runtime should use. diff --git a/substrate/client/executor/polkavm/Cargo.toml b/substrate/client/executor/polkavm/Cargo.toml new file mode 100644 index 00000000000..9d0eb8ccf0e --- /dev/null +++ b/substrate/client/executor/polkavm/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "sc-executor-polkavm" +version = "0.29.0" +authors.workspace = true +edition.workspace = true +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" +homepage = "https://substrate.io" +repository.workspace = true +description = "PolkaVM executor for Substrate" +readme = "README.md" + +[lints] +workspace = true + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +log = { workspace = true } +polkavm = { workspace = true } + +sc-executor-common = { path = "../common" } +sp-wasm-interface = { path = "../../../primitives/wasm-interface" } diff --git a/substrate/client/executor/polkavm/README.md b/substrate/client/executor/polkavm/README.md new file mode 100644 index 00000000000..64fc2fa0c28 --- /dev/null +++ b/substrate/client/executor/polkavm/README.md @@ -0,0 +1 @@ +License: GPL-3.0-or-later WITH Classpath-exception-2.0 diff --git a/substrate/client/executor/polkavm/src/lib.rs b/substrate/client/executor/polkavm/src/lib.rs new file mode 100644 index 00000000000..1bd72eb33d3 --- /dev/null +++ b/substrate/client/executor/polkavm/src/lib.rs @@ -0,0 +1,261 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use polkavm::{Caller, Reg}; +use sc_executor_common::{ + error::{Error, WasmError}, + wasm_runtime::{AllocationStats, WasmInstance, WasmModule}, +}; +use sp_wasm_interface::{ + Function, FunctionContext, HostFunctions, Pointer, Value, ValueType, WordSize, +}; + +#[repr(transparent)] +pub struct InstancePre(polkavm::InstancePre<()>); + +#[repr(transparent)] +pub struct Instance(polkavm::Instance<()>); + +impl WasmModule for InstancePre { + fn new_instance(&self) -> Result, Error> { + Ok(Box::new(Instance(self.0.instantiate()?))) + } +} + +impl WasmInstance for Instance { + fn call_with_allocation_stats( + &mut self, + name: &str, + raw_data: &[u8], + ) -> (Result, Error>, Option) { + let Some(method_index) = self.0.module().lookup_export(name) else { + return ( + Err(format!("cannot call into the runtime: export not found: '{name}'").into()), + None, + ); + }; + + let Ok(raw_data_length) = u32::try_from(raw_data.len()) else { + return ( + Err(format!("cannot call runtime method '{name}': input payload is too big").into()), + None, + ); + }; + + // TODO: This will leak guest memory; find a better solution. + let mut state_args = polkavm::StateArgs::new(); + + // Make sure the memory is cleared... + state_args.reset_memory(true); + // ...and allocate space for the input payload. + state_args.sbrk(raw_data_length); + + match self.0.update_state(state_args) { + Ok(()) => {}, + Err(polkavm::ExecutionError::Trap(trap)) => { + return (Err(format!("call into the runtime method '{name}' failed: failed to prepare the guest's memory: {trap}").into()), None); + }, + Err(polkavm::ExecutionError::Error(error)) => { + return (Err(format!("call into the runtime method '{name}' failed: failed to prepare the guest's memory: {error}").into()), None); + }, + Err(polkavm::ExecutionError::OutOfGas) => unreachable!("gas metering is never enabled"), + } + + // Grab the address of where the guest's heap starts; that's where we've just allocated + // the memory for the input payload. + let data_pointer = self.0.module().memory_map().heap_base(); + + if let Err(error) = self.0.write_memory(data_pointer, raw_data) { + return (Err(format!("call into the runtime method '{name}': failed to write the input payload into guest memory: {error}").into()), None); + } + + let mut state = (); + let mut call_args = polkavm::CallArgs::new(&mut state, method_index); + call_args.args_untyped(&[data_pointer, raw_data_length]); + + match self.0.call(Default::default(), call_args) { + Ok(()) => {}, + Err(polkavm::ExecutionError::Trap(trap)) => { + return ( + Err(format!("call into the runtime method '{name}' failed: {trap}").into()), + None, + ); + }, + Err(polkavm::ExecutionError::Error(error)) => { + return ( + Err(format!("call into the runtime method '{name}' failed: {error}").into()), + None, + ); + }, + Err(polkavm::ExecutionError::OutOfGas) => unreachable!("gas metering is never enabled"), + } + + let result_pointer = self.0.get_reg(Reg::A0); + let result_length = self.0.get_reg(Reg::A1); + let output = match self.0.read_memory_into_vec(result_pointer, result_length) { + Ok(output) => output, + Err(error) => { + return (Err(format!("call into the runtime method '{name}' failed: failed to read the return payload: {error}").into()), None) + }, + }; + + (Ok(output), None) + } +} + +struct Context<'r, 'a>(&'r mut polkavm::Caller<'a, ()>); + +impl<'r, 'a> FunctionContext for Context<'r, 'a> { + fn read_memory_into( + &self, + address: Pointer, + dest: &mut [u8], + ) -> sp_wasm_interface::Result<()> { + self.0 + .read_memory_into_slice(u32::from(address), dest) + .map_err(|error| error.to_string()) + .map(|_| ()) + } + + fn write_memory(&mut self, address: Pointer, data: &[u8]) -> sp_wasm_interface::Result<()> { + self.0.write_memory(u32::from(address), data).map_err(|error| error.to_string()) + } + + fn allocate_memory(&mut self, size: WordSize) -> sp_wasm_interface::Result> { + let pointer = self.0.sbrk(0).expect("fetching the current heap pointer never fails"); + + // TODO: This will leak guest memory; find a better solution. + self.0.sbrk(size).ok_or_else(|| String::from("allocation failed"))?; + + Ok(Pointer::new(pointer)) + } + + fn deallocate_memory(&mut self, _ptr: Pointer) -> sp_wasm_interface::Result<()> { + // This is only used by the allocator host function, which is unused under PolkaVM. + unimplemented!("'deallocate_memory' is never used when running under PolkaVM"); + } + + fn register_panic_error_message(&mut self, _message: &str) { + unimplemented!("'register_panic_error_message' is never used when running under PolkaVM"); + } +} + +fn call_host_function( + caller: &mut Caller<()>, + function: &dyn Function, +) -> Result<(), polkavm::Trap> { + let mut args = [Value::I64(0); Reg::ARG_REGS.len()]; + let mut nth_reg = 0; + for (nth_arg, kind) in function.signature().args.iter().enumerate() { + match kind { + ValueType::I32 => { + args[nth_arg] = Value::I32(caller.get_reg(Reg::ARG_REGS[nth_reg]) as i32); + nth_reg += 1; + }, + ValueType::F32 => { + args[nth_arg] = Value::F32(caller.get_reg(Reg::ARG_REGS[nth_reg])); + nth_reg += 1; + }, + ValueType::I64 => { + let value_lo = caller.get_reg(Reg::ARG_REGS[nth_reg]); + nth_reg += 1; + + let value_hi = caller.get_reg(Reg::ARG_REGS[nth_reg]); + nth_reg += 1; + + args[nth_arg] = + Value::I64((u64::from(value_lo) | (u64::from(value_hi) << 32)) as i64); + }, + ValueType::F64 => { + let value_lo = caller.get_reg(Reg::ARG_REGS[nth_reg]); + nth_reg += 1; + + let value_hi = caller.get_reg(Reg::ARG_REGS[nth_reg]); + nth_reg += 1; + + args[nth_arg] = Value::F64(u64::from(value_lo) | (u64::from(value_hi) << 32)); + }, + } + } + + log::trace!( + "Calling host function: '{}', args = {:?}", + function.name(), + &args[..function.signature().args.len()] + ); + + let value = match function + .execute(&mut Context(caller), &mut args.into_iter().take(function.signature().args.len())) + { + Ok(value) => value, + Err(error) => { + log::warn!("Call into the host function '{}' failed: {error}", function.name()); + return Err(polkavm::Trap::default()); + }, + }; + + if let Some(value) = value { + match value { + Value::I32(value) => { + caller.set_reg(Reg::A0, value as u32); + }, + Value::F32(value) => { + caller.set_reg(Reg::A0, value); + }, + Value::I64(value) => { + caller.set_reg(Reg::A0, value as u32); + caller.set_reg(Reg::A1, (value >> 32) as u32); + }, + Value::F64(value) => { + caller.set_reg(Reg::A0, value as u32); + caller.set_reg(Reg::A1, (value >> 32) as u32); + }, + } + } + + Ok(()) +} + +pub fn create_runtime(blob: &polkavm::ProgramBlob) -> Result, WasmError> +where + H: HostFunctions, +{ + static ENGINE: std::sync::OnceLock> = + std::sync::OnceLock::new(); + + let engine = ENGINE.get_or_init(|| { + let config = polkavm::Config::from_env()?; + polkavm::Engine::new(&config) + }); + + let engine = match engine { + Ok(ref engine) => engine, + Err(ref error) => { + return Err(WasmError::Other(error.to_string())); + }, + }; + + let module = polkavm::Module::from_blob(&engine, &polkavm::ModuleConfig::default(), blob)?; + let mut linker = polkavm::Linker::new(&engine); + for function in H::host_functions() { + linker.func_new(function.name(), |mut caller| call_host_function(&mut caller, function))?; + } + + let instance_pre = linker.instantiate_pre(&module)?; + Ok(Box::new(InstancePre(instance_pre))) +} diff --git a/substrate/client/executor/src/wasm_runtime.rs b/substrate/client/executor/src/wasm_runtime.rs index 501279a312c..be8344ba79b 100644 --- a/substrate/client/executor/src/wasm_runtime.rs +++ b/substrate/client/executor/src/wasm_runtime.rs @@ -297,6 +297,10 @@ pub fn create_wasm_runtime_with_code( where H: HostFunctions, { + if let Some(blob) = blob.as_polkavm_blob() { + return sc_executor_polkavm::create_runtime::(blob); + } + match wasm_method { WasmExecutionMethod::Compiled { instantiation_strategy } => sc_executor_wasmtime::create_runtime::( diff --git a/substrate/client/executor/wasmtime/src/instance_wrapper.rs b/substrate/client/executor/wasmtime/src/instance_wrapper.rs index 8852532adbc..4f67d1df9c5 100644 --- a/substrate/client/executor/wasmtime/src/instance_wrapper.rs +++ b/substrate/client/executor/wasmtime/src/instance_wrapper.rs @@ -22,36 +22,12 @@ use std::sync::Arc; use crate::runtime::{InstanceCounter, ReleaseInstanceHandle, Store, StoreData}; -use sc_executor_common::{ - error::{Backtrace, Error, MessageWithBacktrace, Result, WasmError}, - wasm_runtime::InvokeMethod, -}; -use sp_wasm_interface::{Pointer, Value, WordSize}; -use wasmtime::{ - AsContext, AsContextMut, Engine, Extern, Instance, InstancePre, Memory, Table, Val, -}; - -/// Invoked entrypoint format. -pub enum EntryPointType { - /// Direct call. - /// - /// Call is made by providing only payload reference and length. - Direct { entrypoint: wasmtime::TypedFunc<(u32, u32), u64> }, - /// Indirect call. - /// - /// Call is made by providing payload reference and length, and extra argument - /// for advanced routing. - Wrapped { - /// The extra argument passed to the runtime. It is typically a wasm function pointer. - func: u32, - dispatcher: wasmtime::TypedFunc<(u32, u32, u32), u64>, - }, -} +use sc_executor_common::error::{Backtrace, Error, MessageWithBacktrace, Result, WasmError}; +use sp_wasm_interface::{Pointer, WordSize}; +use wasmtime::{AsContext, AsContextMut, Engine, Instance, InstancePre, Memory}; /// Wasm blob entry point. -pub struct EntryPoint { - call_type: EntryPointType, -} +pub struct EntryPoint(wasmtime::TypedFunc<(u32, u32), u64>); impl EntryPoint { /// Call this entry point. @@ -64,13 +40,7 @@ impl EntryPoint { let data_ptr = u32::from(data_ptr); let data_len = u32::from(data_len); - match self.call_type { - EntryPointType::Direct { ref entrypoint } => - entrypoint.call(&mut *store, (data_ptr, data_len)), - EntryPointType::Wrapped { func, ref dispatcher } => - dispatcher.call(&mut *store, (func, data_ptr, data_len)), - } - .map_err(|trap| { + self.0.call(&mut *store, (data_ptr, data_len)).map_err(|trap| { let host_state = store .data_mut() .host_state @@ -99,18 +69,7 @@ impl EntryPoint { let entrypoint = func .typed::<(u32, u32), u64>(ctx) .map_err(|_| "Invalid signature for direct entry point")?; - Ok(Self { call_type: EntryPointType::Direct { entrypoint } }) - } - - pub fn wrapped( - dispatcher: wasmtime::Func, - func: u32, - ctx: impl AsContext, - ) -> std::result::Result { - let dispatcher = dispatcher - .typed::<(u32, u32, u32), u64>(ctx) - .map_err(|_| "Invalid signature for wrapped entry point")?; - Ok(Self { call_type: EntryPointType::Wrapped { func, dispatcher } }) + Ok(Self(entrypoint)) } } @@ -178,10 +137,8 @@ impl InstanceWrapper { })?; let memory = get_linear_memory(&instance, &mut store)?; - let table = get_table(&instance, &mut store); store.data_mut().memory = Some(memory); - store.data_mut().table = table; Ok(InstanceWrapper { instance, store, _release_instance_handle }) } @@ -190,61 +147,17 @@ impl InstanceWrapper { /// /// An entrypoint must have a signature `(i32, i32) -> i64`, otherwise this function will return /// an error. - pub fn resolve_entrypoint(&mut self, method: InvokeMethod) -> Result { - Ok(match method { - InvokeMethod::Export(method) => { - // Resolve the requested method and verify that it has a proper signature. - let export = - self.instance.get_export(&mut self.store, method).ok_or_else(|| { - Error::from(format!("Exported method {} is not found", method)) - })?; - let func = export - .into_func() - .ok_or_else(|| Error::from(format!("Export {} is not a function", method)))?; - EntryPoint::direct(func, &self.store).map_err(|_| { - Error::from(format!("Exported function '{}' has invalid signature.", method)) - })? - }, - InvokeMethod::Table(func_ref) => { - let table = self - .instance - .get_table(&mut self.store, "__indirect_function_table") - .ok_or(Error::NoTable)?; - let val = table - .get(&mut self.store, func_ref) - .ok_or(Error::NoTableEntryWithIndex(func_ref))?; - let func = val - .funcref() - .ok_or(Error::TableElementIsNotAFunction(func_ref))? - .ok_or(Error::FunctionRefIsNull(func_ref))?; - - EntryPoint::direct(*func, &self.store).map_err(|_| { - Error::from(format!( - "Function @{} in exported table has invalid signature for direct call.", - func_ref, - )) - })? - }, - InvokeMethod::TableWithWrapper { dispatcher_ref, func } => { - let table = self - .instance - .get_table(&mut self.store, "__indirect_function_table") - .ok_or(Error::NoTable)?; - let val = table - .get(&mut self.store, dispatcher_ref) - .ok_or(Error::NoTableEntryWithIndex(dispatcher_ref))?; - let dispatcher = val - .funcref() - .ok_or(Error::TableElementIsNotAFunction(dispatcher_ref))? - .ok_or(Error::FunctionRefIsNull(dispatcher_ref))?; - - EntryPoint::wrapped(*dispatcher, func, &self.store).map_err(|_| { - Error::from(format!( - "Function @{} in exported table has invalid signature for wrapped call.", - dispatcher_ref, - )) - })? - }, + pub fn resolve_entrypoint(&mut self, method: &str) -> Result { + // Resolve the requested method and verify that it has a proper signature. + let export = self + .instance + .get_export(&mut self.store, method) + .ok_or_else(|| Error::from(format!("Exported method {} is not found", method)))?; + let func = export + .into_func() + .ok_or_else(|| Error::from(format!("Export {} is not a function", method)))?; + EntryPoint::direct(func, &self.store).map_err(|_| { + Error::from(format!("Exported function '{}' has invalid signature.", method)) }) } @@ -268,24 +181,6 @@ impl InstanceWrapper { Ok(heap_base as u32) } - - /// Get the value from a global with the given `name`. - pub fn get_global_val(&mut self, name: &str) -> Result> { - let global = match self.instance.get_export(&mut self.store, name) { - Some(global) => global, - None => return Ok(None), - }; - - let global = global.into_global().ok_or_else(|| format!("`{}` is not a global", name))?; - - match global.get(&mut self.store) { - Val::I32(val) => Ok(Some(Value::I32(val))), - Val::I64(val) => Ok(Some(Value::I64(val))), - Val::F32(val) => Ok(Some(Value::F32(val))), - Val::F64(val) => Ok(Some(Value::F64(val))), - _ => Err("Unknown value type".into()), - } - } } /// Extract linear memory instance from the given instance. @@ -301,15 +196,6 @@ fn get_linear_memory(instance: &Instance, ctx: impl AsContextMut) -> Result Option
CommittedCandidateReceipt<H = Hash>
{ - instance - .get_export(ctx, "__indirect_function_table") - .as_ref() - .cloned() - .and_then(Extern::into_table) -} - /// Functions related to memory. impl InstanceWrapper { pub(crate) fn store(&self) -> &Store { diff --git a/substrate/client/executor/wasmtime/src/runtime.rs b/substrate/client/executor/wasmtime/src/runtime.rs index ac88663f4e7..595cc503272 100644 --- a/substrate/client/executor/wasmtime/src/runtime.rs +++ b/substrate/client/executor/wasmtime/src/runtime.rs @@ -30,10 +30,10 @@ use sc_executor_common::{ error::{Error, Result, WasmError}, runtime_blob::RuntimeBlob, util::checked_range, - wasm_runtime::{HeapAllocStrategy, InvokeMethod, WasmInstance, WasmModule}, + wasm_runtime::{HeapAllocStrategy, WasmInstance, WasmModule}, }; use sp_runtime_interface::unpack_ptr_and_len; -use sp_wasm_interface::{HostFunctions, Pointer, Value, WordSize}; +use sp_wasm_interface::{HostFunctions, Pointer, WordSize}; use std::{ path::{Path, PathBuf}, sync::{ @@ -41,7 +41,7 @@ use std::{ Arc, }, }; -use wasmtime::{AsContext, Engine, Memory, Table}; +use wasmtime::{AsContext, Engine, Memory}; const MAX_INSTANCE_COUNT: u32 = 64; @@ -51,8 +51,6 @@ pub(crate) struct StoreData { pub(crate) host_state: Option, /// This will be always set once the store is initialized. pub(crate) memory: Option, - /// This will be set only if the runtime actually contains a table. - pub(crate) table: Option
, } impl StoreData { @@ -164,7 +162,7 @@ pub struct WasmtimeInstance { impl WasmtimeInstance { fn call_impl( &mut self, - method: InvokeMethod, + method: &str, data: &[u8], allocation_stats: &mut Option, ) -> Result> { @@ -184,20 +182,13 @@ impl WasmtimeInstance { impl WasmInstance for WasmtimeInstance { fn call_with_allocation_stats( &mut self, - method: InvokeMethod, + method: &str, data: &[u8], ) -> (Result>, Option) { let mut allocation_stats = None; let result = self.call_impl(method, data, &mut allocation_stats); (result, allocation_stats) } - - fn get_global_const(&mut self, name: &str) -> Result> { - match &mut self.strategy { - Strategy::RecreateInstance(ref mut instance_creator) => - instance_creator.instantiate()?.get_global_val(name), - } - } } /// Prepare a directory structure and a config file to enable wasmtime caching. diff --git a/substrate/primitives/io/Cargo.toml b/substrate/primitives/io/Cargo.toml index c78def9bf44..e47775d56d9 100644 --- a/substrate/primitives/io/Cargo.toml +++ b/substrate/primitives/io/Cargo.toml @@ -38,6 +38,9 @@ tracing-core = { version = "0.1.32", default-features = false } # Required for backwards compatibility reason, but only used for verifying when `UseDalekExt` is set. ed25519-dalek = { version = "2.1", default-features = false, optional = true } +[target.'cfg(all(any(target_arch = "riscv32", target_arch = "riscv64"), substrate_runtime))'.dependencies] +polkavm-derive = { workspace = true } + [build-dependencies] rustversion = "1.0.6" diff --git a/substrate/primitives/io/src/global_alloc_riscv.rs b/substrate/primitives/io/src/global_alloc_riscv.rs new file mode 100644 index 00000000000..8d7c69c2094 --- /dev/null +++ b/substrate/primitives/io/src/global_alloc_riscv.rs @@ -0,0 +1,19 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#[global_allocator] +static ALLOCATOR: polkavm_derive::LeakingAllocator = polkavm_derive::LeakingAllocator; diff --git a/substrate/primitives/io/src/global_alloc_wasm.rs b/substrate/primitives/io/src/global_alloc_wasm.rs new file mode 100644 index 00000000000..cf19a6e21a2 --- /dev/null +++ b/substrate/primitives/io/src/global_alloc_wasm.rs @@ -0,0 +1,34 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use core::alloc::{GlobalAlloc, Layout}; + +/// Allocator used by Substrate from within the runtime. +struct RuntimeAllocator; + +#[global_allocator] +static ALLOCATOR: RuntimeAllocator = RuntimeAllocator; + +unsafe impl GlobalAlloc for RuntimeAllocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + crate::allocator::malloc(layout.size() as u32) + } + + unsafe fn dealloc(&self, ptr: *mut u8, _: Layout) { + crate::allocator::free(ptr) + } +} diff --git a/substrate/primitives/io/src/lib.rs b/substrate/primitives/io/src/lib.rs index 6d34199416a..684854ea5c8 100644 --- a/substrate/primitives/io/src/lib.rs +++ b/substrate/primitives/io/src/lib.rs @@ -129,6 +129,16 @@ use sp_externalities::{Externalities, ExternalitiesExt}; pub use sp_externalities::MultiRemovalResults; +#[cfg(all(not(feature = "disable_allocator"), substrate_runtime, target_family = "wasm"))] +mod global_alloc_wasm; + +#[cfg(all( + not(feature = "disable_allocator"), + substrate_runtime, + any(target_arch = "riscv32", target_arch = "riscv64") +))] +mod global_alloc_riscv; + #[cfg(feature = "std")] const LOG_TARGET: &str = "runtime::io"; @@ -1737,30 +1747,6 @@ mod tracing_setup { pub use tracing_setup::init_tracing; -/// Allocator used by Substrate from within the runtime. -#[cfg(substrate_runtime)] -struct RuntimeAllocator; - -#[cfg(all(not(feature = "disable_allocator"), substrate_runtime))] -#[global_allocator] -static ALLOCATOR: RuntimeAllocator = RuntimeAllocator; - -#[cfg(substrate_runtime)] -mod allocator_impl { - use super::*; - use core::alloc::{GlobalAlloc, Layout}; - - unsafe impl GlobalAlloc for RuntimeAllocator { - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - allocator::malloc(layout.size() as u32) - } - - unsafe fn dealloc(&self, ptr: *mut u8, _: Layout) { - allocator::free(ptr) - } - } -} - /// Crashes the execution of the program. /// /// Equivalent to the WASM `unreachable` instruction, RISC-V `unimp` instruction, diff --git a/substrate/utils/wasm-builder/src/wasm_project.rs b/substrate/utils/wasm-builder/src/wasm_project.rs index 9ffb5c72fd9..13db9fce431 100644 --- a/substrate/utils/wasm-builder/src/wasm_project.rs +++ b/substrate/utils/wasm-builder/src/wasm_project.rs @@ -855,7 +855,7 @@ fn build_bloaty_blob( println!("{} {}", colorize_info_message("Using rustc version:"), cargo_cmd.rustc_version()); // Use `process::exit(1)` to have a clean error output. - if !matches!(build_cmd.status().map(|s| s.success()), Ok(true)) { + if !build_cmd.status().map_or(false, |s| s.success()) { process::exit(1); } -- GitLab From 1ead59773e2dab336d2b54295419bbc3fe7c687f Mon Sep 17 00:00:00 2001 From: Alexandru Gheorghe <49718502+alexggh@users.noreply.github.com> Date: Tue, 12 Mar 2024 10:33:54 +0200 Subject: [PATCH 388/392] Add api-name in `cannot query the runtime API version` warning (#3653) Sometimes we see nodes printing this warning: ``` cannot query the runtime API version: Api called for an unknown Block: State already discarded for ``` The log is harmless, but let's print the api we got this for, so that we can track its call site and truly confirm it is harmless or fix it. Signed-off-by: Alexandru Gheorghe --- polkadot/node/core/runtime-api/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/polkadot/node/core/runtime-api/src/lib.rs b/polkadot/node/core/runtime-api/src/lib.rs index 4bedfd82734..3ff1a35d068 100644 --- a/polkadot/node/core/runtime-api/src/lib.rs +++ b/polkadot/node/core/runtime-api/src/lib.rs @@ -433,6 +433,7 @@ where .unwrap_or_else(|e| { gum::warn!( target: LOG_TARGET, + api = ?stringify!($api_name), "cannot query the runtime API version: {}", e, ); -- GitLab From a756baf3b211efc57ca4a0089b7ceba4c20b9f12 Mon Sep 17 00:00:00 2001 From: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Date: Tue, 12 Mar 2024 12:43:31 +0100 Subject: [PATCH 389/392] Support for `keyring` in runtimes (#2044) This functionality is required for #1984. This PR enables [`sp-keyring`](https://github.com/paritytech/polkadot-sdk/blob/21d36b7b4229c4d5225944f197918cde23fda4ea/substrate/primitives/keyring/src/sr25519.rs#L31-L40) in `no-std` environments, allowing to generate the public key (e.g. `AccountKeyring::Alice.public().to_ss58check()`), which can be later used in the any of built-in [_runtime-genesis-config_ variant](https://github.com/paritytech/polkadot-sdk/blob/21d36b7b4229c4d5225944f197918cde23fda4ea/polkadot/node/service/src/chain_spec.rs#L1066-L1073). The proposal is as follows: - expose [`core::Pair` trait](https://github.com/paritytech/polkadot-sdk/blob/d6f15306282e3de848a09c9aa9cba6f95a7811f0/substrate/primitives/core/src/crypto.rs#L832) in `no-std`, - `full_crypto` feature enables `sign` method, - `std` feature enables `generate_with_phrase` and `generate` methods (randomness is required), - All other functionality, currently gated by `full_crypto` will be available unconditionally (`no-std`): -- `from_string` -- `from_string_with_seed` -- `from seed` -- `from_seed_slice` -- `from_phrase` -- `derive` -- `verify` --- Depends on https://github.com/rust-bitcoin/rust-bip39/pull/57 --------- Co-authored-by: command-bot <> Co-authored-by: Davide Galassi --- .gitlab/pipeline/check.yml | 16 +++++ Cargo.lock | 43 ++++++++++++-- substrate/client/cli/Cargo.toml | 3 +- substrate/client/cli/src/commands/generate.rs | 2 +- .../check-features-variants.sh | 12 ++++ .../application-crypto/src/bls377.rs | 5 +- .../application-crypto/src/ecdsa.rs | 4 +- .../application-crypto/src/ecdsa_bls377.rs | 1 + .../application-crypto/src/ed25519.rs | 4 +- .../primitives/application-crypto/src/lib.rs | 59 +++++++++++++------ .../application-crypto/src/sr25519.rs | 4 +- .../application-crypto/src/traits.rs | 14 +---- substrate/primitives/core/Cargo.toml | 24 +++----- .../core/check-features-variants.sh | 13 ++++ substrate/primitives/core/src/address_uri.rs | 2 +- substrate/primitives/core/src/bandersnatch.rs | 28 ++++----- substrate/primitives/core/src/bls.rs | 31 +++------- substrate/primitives/core/src/crypto.rs | 24 +------- substrate/primitives/core/src/ecdsa.rs | 34 ++++------- substrate/primitives/core/src/ed25519.rs | 21 ++----- substrate/primitives/core/src/lib.rs | 3 - .../primitives/core/src/paired_crypto.rs | 27 +++------ substrate/primitives/core/src/sr25519.rs | 30 +++------- substrate/primitives/keyring/Cargo.toml | 7 ++- .../keyring/check-features-variants.sh | 8 +++ .../primitives/keyring/src/bandersnatch.rs | 20 +++++-- substrate/primitives/keyring/src/ed25519.rs | 12 +++- substrate/primitives/keyring/src/lib.rs | 2 + substrate/primitives/keyring/src/sr25519.rs | 20 +++++-- substrate/test-utils/runtime/Cargo.toml | 6 +- 30 files changed, 247 insertions(+), 232 deletions(-) create mode 100755 substrate/primitives/application-crypto/check-features-variants.sh create mode 100755 substrate/primitives/core/check-features-variants.sh create mode 100755 substrate/primitives/keyring/check-features-variants.sh diff --git a/.gitlab/pipeline/check.yml b/.gitlab/pipeline/check.yml index 4d71a473372..52da3355050 100644 --- a/.gitlab/pipeline/check.yml +++ b/.gitlab/pipeline/check.yml @@ -259,3 +259,19 @@ find-fail-ci-phrase: echo "No $ASSERT_REGEX was found, exiting with 0"; exit 0; fi + +check-core-crypto-features: + stage: check + extends: + - .docker-env + - .common-refs + script: + - pushd substrate/primitives/core + - ./check-features-variants.sh + - popd + - pushd substrate/primitives/application-crypto + - ./check-features-variants.sh + - popd + - pushd substrate/primitives/keyring + - ./check-features-variants.sh + - popd diff --git a/Cargo.lock b/Cargo.lock index 5eab3cf7c24..37c5a5177c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1434,9 +1434,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" dependencies = [ - "bitcoin_hashes", - "rand", - "rand_core 0.6.4", + "bitcoin_hashes 0.11.0", "serde", "unicode-normalization", ] @@ -1456,12 +1454,28 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +[[package]] +name = "bitcoin-internals" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb" + [[package]] name = "bitcoin_hashes" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" +[[package]] +name = "bitcoin_hashes" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" +dependencies = [ + "bitcoin-internals", + "hex-conservative", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -6348,6 +6362,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hex-conservative" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ed443af458ccb6d81c1e7e661545f94d3176752fb1df2f543b902a1e0f51e2" + [[package]] name = "hex-literal" version = "0.4.1" @@ -11411,6 +11431,19 @@ dependencies = [ "substrate-wasm-builder", ] +[[package]] +name = "parity-bip39" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e69bf016dc406eff7d53a7d3f7cf1c2e72c82b9088aac1118591e36dd2cd3e9" +dependencies = [ + "bitcoin_hashes 0.13.0", + "rand", + "rand_core 0.6.4", + "serde", + "unicode-normalization", +] + [[package]] name = "parity-bytes" version = "0.1.2" @@ -15662,7 +15695,6 @@ name = "sc-cli" version = "0.36.0" dependencies = [ "array-bytes 6.1.0", - "bip39", "chrono", "clap 4.5.1", "fdlimit", @@ -15672,6 +15704,7 @@ dependencies = [ "libp2p-identity", "log", "names", + "parity-bip39", "parity-scale-codec", "rand", "regex", @@ -18611,7 +18644,6 @@ version = "28.0.0" dependencies = [ "array-bytes 6.1.0", "bandersnatch_vrfs", - "bip39", "bitflags 1.3.2", "blake2 0.10.6", "bounded-collections", @@ -18629,6 +18661,7 @@ dependencies = [ "libsecp256k1", "log", "merlin", + "parity-bip39", "parity-scale-codec", "parking_lot 0.12.1", "paste", diff --git a/substrate/client/cli/Cargo.toml b/substrate/client/cli/Cargo.toml index 0582018283c..c70a0893c72 100644 --- a/substrate/client/cli/Cargo.toml +++ b/substrate/client/cli/Cargo.toml @@ -32,7 +32,8 @@ rpassword = "7.0.0" serde = { workspace = true, default-features = true } serde_json = { workspace = true, default-features = true } thiserror = { workspace = true } -bip39 = "2.0.0" +# personal fork here as workaround for: https://github.com/rust-bitcoin/rust-bip39/pull/64 +bip39 = { package = "parity-bip39", version = "2.0.1", features = ["rand"] } tokio = { version = "1.22.0", features = ["parking_lot", "rt-multi-thread", "signal"] } sc-client-api = { path = "../api" } sc-client-db = { path = "../db", default-features = false } diff --git a/substrate/client/cli/src/commands/generate.rs b/substrate/client/cli/src/commands/generate.rs index c465bcc85a4..94769279e21 100644 --- a/substrate/client/cli/src/commands/generate.rs +++ b/substrate/client/cli/src/commands/generate.rs @@ -64,7 +64,7 @@ impl GenerateCmd { let password = self.keystore_params.read_password()?; let output = self.output_scheme.output_type; - let phrase = mnemonic.word_iter().join(" "); + let phrase = mnemonic.words().join(" "); with_crypto_scheme!( self.crypto_scheme.scheme, diff --git a/substrate/primitives/application-crypto/check-features-variants.sh b/substrate/primitives/application-crypto/check-features-variants.sh new file mode 100755 index 00000000000..dd45a212bae --- /dev/null +++ b/substrate/primitives/application-crypto/check-features-variants.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env -S bash -eux + +export RUSTFLAGS="-Cdebug-assertions=y -Dwarnings" +T=wasm32-unknown-unknown +cargo check --release +cargo check --release --target=$T --no-default-features +cargo check --release --target=$T --no-default-features --features="full_crypto" +cargo check --release --target=$T --no-default-features --features="serde" +cargo check --release --target=$T --no-default-features --features="serde,full_crypto" +cargo check --release --target=$T --no-default-features --features="bandersnatch-experimental" +cargo check --release --target=$T --no-default-features --features="bls-experimental" +cargo check --release --target=$T --no-default-features --features="bls-experimental,full_crypto" diff --git a/substrate/primitives/application-crypto/src/bls377.rs b/substrate/primitives/application-crypto/src/bls377.rs index ee17060564f..3bd01de139c 100644 --- a/substrate/primitives/application-crypto/src/bls377.rs +++ b/substrate/primitives/application-crypto/src/bls377.rs @@ -19,14 +19,13 @@ use crate::{KeyTypeId, RuntimePublic}; pub use sp_core::bls::bls377::*; +use sp_std::vec::Vec; mod app { crate::app_crypto!(super, sp_core::testing::BLS377); } -#[cfg(feature = "full_crypto")] -pub use app::Pair as AppPair; -pub use app::{Public as AppPublic, Signature as AppSignature}; +pub use app::{Pair as AppPair, Public as AppPublic, Signature as AppSignature}; impl RuntimePublic for Public { type Signature = Signature; diff --git a/substrate/primitives/application-crypto/src/ecdsa.rs b/substrate/primitives/application-crypto/src/ecdsa.rs index 27ffe12579f..439b51dc604 100644 --- a/substrate/primitives/application-crypto/src/ecdsa.rs +++ b/substrate/primitives/application-crypto/src/ecdsa.rs @@ -27,9 +27,7 @@ mod app { crate::app_crypto!(super, sp_core::testing::ECDSA); } -#[cfg(feature = "full_crypto")] -pub use app::Pair as AppPair; -pub use app::{Public as AppPublic, Signature as AppSignature}; +pub use app::{Pair as AppPair, Public as AppPublic, Signature as AppSignature}; impl RuntimePublic for Public { type Signature = Signature; diff --git a/substrate/primitives/application-crypto/src/ecdsa_bls377.rs b/substrate/primitives/application-crypto/src/ecdsa_bls377.rs index 70940587ced..8dee73095fb 100644 --- a/substrate/primitives/application-crypto/src/ecdsa_bls377.rs +++ b/substrate/primitives/application-crypto/src/ecdsa_bls377.rs @@ -18,6 +18,7 @@ //! ECDSA and BLS12-377 paired crypto applications. use crate::{KeyTypeId, RuntimePublic}; +use sp_std::vec::Vec; pub use sp_core::paired_crypto::ecdsa_bls377::*; diff --git a/substrate/primitives/application-crypto/src/ed25519.rs b/substrate/primitives/application-crypto/src/ed25519.rs index bc05018370e..addefe7daf6 100644 --- a/substrate/primitives/application-crypto/src/ed25519.rs +++ b/substrate/primitives/application-crypto/src/ed25519.rs @@ -27,9 +27,7 @@ mod app { crate::app_crypto!(super, sp_core::testing::ED25519); } -#[cfg(feature = "full_crypto")] -pub use app::Pair as AppPair; -pub use app::{Public as AppPublic, Signature as AppSignature}; +pub use app::{Pair as AppPair, Public as AppPublic, Signature as AppSignature}; impl RuntimePublic for Public { type Signature = Signature; diff --git a/substrate/primitives/application-crypto/src/lib.rs b/substrate/primitives/application-crypto/src/lib.rs index 686b486f335..ea2e5a83127 100644 --- a/substrate/primitives/application-crypto/src/lib.rs +++ b/substrate/primitives/application-crypto/src/lib.rs @@ -20,12 +20,9 @@ #![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -pub use sp_core::crypto::{key_types, CryptoTypeId, KeyTypeId}; +pub use sp_core::crypto::{key_types, CryptoTypeId, DeriveJunction, KeyTypeId, Ss58Codec}; #[doc(hidden)] -#[cfg(feature = "full_crypto")] pub use sp_core::crypto::{DeriveError, Pair, SecretStringError}; -#[cfg(any(feature = "full_crypto", feature = "serde"))] -pub use sp_core::crypto::{DeriveJunction, Ss58Codec}; #[doc(hidden)] pub use sp_core::{ self, @@ -85,7 +82,7 @@ macro_rules! app_crypto { $module::CRYPTO_ID ); $crate::app_crypto_signature_common!($module::Signature, $key_type); - $crate::app_crypto_pair!($module::Pair, $key_type, $module::CRYPTO_ID); + $crate::app_crypto_pair_common!($module::Pair, $key_type, $module::CRYPTO_ID); }; } @@ -116,13 +113,15 @@ macro_rules! app_crypto { $module::CRYPTO_ID ); $crate::app_crypto_signature_common!($module::Signature, $key_type); + $crate::app_crypto_pair_common!($module::Pair, $key_type, $module::CRYPTO_ID); }; } /// Declares `Pair` type which is functionally equivalent to `$pair`, but is /// new application-specific type whose identifier is `$key_type`. +/// It is a common part shared between full_crypto and non full_crypto environments. #[macro_export] -macro_rules! app_crypto_pair { +macro_rules! app_crypto_pair_common { ($pair:ty, $key_type:expr, $crypto_type:expr) => { $crate::wrap! { /// A generic `AppPublic` wrapper type over $pair crypto; this has no specific App. @@ -140,7 +139,14 @@ macro_rules! app_crypto_pair { type Signature = Signature; $crate::app_crypto_pair_functions_if_std!($pair); + $crate::app_crypto_pair_functions_if_full_crypto!($pair); + fn from_phrase( + phrase: &str, + password: Option<&str>, + ) -> Result<(Self, Self::Seed), $crate::SecretStringError> { + <$pair>::from_phrase(phrase, password).map(|r| (Self(r.0), r.1)) + } fn derive>( &self, path: Iter, @@ -154,9 +160,6 @@ macro_rules! app_crypto_pair { fn from_seed_slice(seed: &[u8]) -> Result { <$pair>::from_seed_slice(seed).map(Self) } - fn sign(&self, msg: &[u8]) -> Self::Signature { - Signature(self.0.sign(msg)) - } fn verify>( sig: &Self::Signature, message: M, @@ -203,13 +206,6 @@ macro_rules! app_crypto_pair_functions_if_std { let r = <$pair>::generate_with_phrase(password); (Self(r.0), r.1, r.2) } - - fn from_phrase( - phrase: &str, - password: Option<&str>, - ) -> Result<(Self, Self::Seed), $crate::SecretStringError> { - <$pair>::from_phrase(phrase, password).map(|r| (Self(r.0), r.1)) - } }; } @@ -220,6 +216,25 @@ macro_rules! app_crypto_pair_functions_if_std { ($pair:ty) => {}; } +/// Implements functions for the `Pair` trait when `feature = "full_crypto"` is enabled. +#[doc(hidden)] +#[cfg(feature = "full_crypto")] +#[macro_export] +macro_rules! app_crypto_pair_functions_if_full_crypto { + ($pair:ty) => { + fn sign(&self, msg: &[u8]) -> Self::Signature { + Signature(self.0.sign(msg)) + } + }; +} + +#[doc(hidden)] +#[cfg(not(feature = "full_crypto"))] +#[macro_export] +macro_rules! app_crypto_pair_functions_if_full_crypto { + ($pair:ty) => {}; +} + /// Declares `Public` type which is functionally equivalent to `$public` but is /// new application-specific type whose identifier is `$key_type`. /// For full functionality, `app_crypto_public_common!` must be called too. @@ -267,7 +282,7 @@ macro_rules! app_crypto_public_not_full_crypto { $crate::wrap! { /// A generic `AppPublic` wrapper type over $public crypto; this has no specific App. #[derive( - Clone, Eq, PartialEq, Ord, PartialOrd, + Clone, Eq, Hash, PartialEq, Ord, PartialOrd, $crate::codec::Encode, $crate::codec::Decode, $crate::RuntimeDebug, @@ -277,10 +292,13 @@ macro_rules! app_crypto_public_not_full_crypto { pub struct Public($public); } - impl $crate::CryptoType for Public {} + impl $crate::CryptoType for Public { + type Pair = Pair; + } impl $crate::AppCrypto for Public { type Public = Public; + type Pair = Pair; type Signature = Signature; const ID: $crate::KeyTypeId = $key_type; const CRYPTO_ID: $crate::CryptoTypeId = $crypto_type; @@ -452,10 +470,13 @@ macro_rules! app_crypto_signature_not_full_crypto { pub struct Signature($sig); } - impl $crate::CryptoType for Signature {} + impl $crate::CryptoType for Signature { + type Pair = Pair; + } impl $crate::AppCrypto for Signature { type Public = Public; + type Pair = Pair; type Signature = Signature; const ID: $crate::KeyTypeId = $key_type; const CRYPTO_ID: $crate::CryptoTypeId = $crypto_type; diff --git a/substrate/primitives/application-crypto/src/sr25519.rs b/substrate/primitives/application-crypto/src/sr25519.rs index 7c91bfa7bb5..d411cc253c0 100644 --- a/substrate/primitives/application-crypto/src/sr25519.rs +++ b/substrate/primitives/application-crypto/src/sr25519.rs @@ -27,9 +27,7 @@ mod app { crate::app_crypto!(super, sp_core::testing::SR25519); } -#[cfg(feature = "full_crypto")] -pub use app::Pair as AppPair; -pub use app::{Public as AppPublic, Signature as AppSignature}; +pub use app::{Pair as AppPair, Public as AppPublic, Signature as AppSignature}; impl RuntimePublic for Public { type Signature = Signature; diff --git a/substrate/primitives/application-crypto/src/traits.rs b/substrate/primitives/application-crypto/src/traits.rs index e9b1080f63d..0b59abf272d 100644 --- a/substrate/primitives/application-crypto/src/traits.rs +++ b/substrate/primitives/application-crypto/src/traits.rs @@ -18,9 +18,7 @@ use codec::Codec; use scale_info::TypeInfo; -#[cfg(feature = "full_crypto")] -use sp_core::crypto::Pair; -use sp_core::crypto::{CryptoType, CryptoTypeId, IsWrappedBy, KeyTypeId, Public}; +use sp_core::crypto::{CryptoType, CryptoTypeId, IsWrappedBy, KeyTypeId, Pair, Public}; use sp_std::{fmt::Debug, vec::Vec}; /// Application-specific cryptographic object. @@ -45,24 +43,14 @@ pub trait AppCrypto: 'static + Sized + CryptoType { type Signature: AppSignature; /// The corresponding key pair type in this application scheme. - #[cfg(feature = "full_crypto")] type Pair: AppPair; } /// Type which implements Hash in std, not when no-std (std variant). -#[cfg(any(feature = "std", feature = "full_crypto"))] pub trait MaybeHash: sp_std::hash::Hash {} -#[cfg(any(feature = "std", feature = "full_crypto"))] impl MaybeHash for T {} -/// Type which implements Hash in std, not when no-std (no-std variant). -#[cfg(all(not(feature = "std"), not(feature = "full_crypto")))] -pub trait MaybeHash {} -#[cfg(all(not(feature = "std"), not(feature = "full_crypto")))] -impl MaybeHash for T {} - /// Application-specific key pair. -#[cfg(feature = "full_crypto")] pub trait AppPair: AppCrypto + Pair::Public, Signature = ::Signature> { diff --git a/substrate/primitives/core/Cargo.toml b/substrate/primitives/core/Cargo.toml index f7cc2b4fcf7..908f2498de5 100644 --- a/substrate/primitives/core/Cargo.toml +++ b/substrate/primitives/core/Cargo.toml @@ -27,10 +27,11 @@ hash-db = { version = "0.16.0", default-features = false } hash256-std-hasher = { version = "0.15.2", default-features = false } bs58 = { version = "0.5.0", default-features = false, optional = true } rand = { version = "0.8.5", features = ["small_rng"], optional = true } -substrate-bip39 = { path = "../../utils/substrate-bip39", optional = true } -bip39 = { version = "2.0.0", default-features = false } +substrate-bip39 = { path = "../../utils/substrate-bip39", default-features = false } +# personal fork here as workaround for: https://github.com/rust-bitcoin/rust-bip39/pull/64 +bip39 = { package = "parity-bip39", version = "2.0.1", default-features = false, features = ["alloc"] } zeroize = { version = "1.4.3", default-features = false } -secrecy = { version = "0.8.0", default-features = false } +secrecy = { version = "0.8.0", default-features = false, features = ["alloc"] } parking_lot = { version = "0.12.1", optional = true } ss58-registry = { version = "1.34.0", default-features = false } sp-std = { path = "../std", default-features = false } @@ -46,13 +47,13 @@ paste = "1.0.7" itertools = { version = "0.10.3", optional = true } # full crypto -array-bytes = { version = "6.1", optional = true } -ed25519-zebra = { version = "3.1.0", default-features = false, optional = true } +array-bytes = { version = "6.1" } +ed25519-zebra = { version = "3.1.0", default-features = false } blake2 = { version = "0.10.4", default-features = false, optional = true } -libsecp256k1 = { version = "0.7", default-features = false, features = ["static-context"], optional = true } +libsecp256k1 = { version = "0.7", default-features = false, features = ["static-context"] } schnorrkel = { version = "0.11.4", features = ["preaudit_deprecated"], default-features = false } merlin = { version = "3.0", default-features = false } -sp-crypto-hashing = { path = "../crypto/hashing", default-features = false, optional = true } +sp-crypto-hashing = { path = "../crypto/hashing", default-features = false } sp-runtime-interface = { path = "../runtime-interface", default-features = false } # k256 crate, better portability, intended to be used in substrate-runtimes (no-std) k256 = { version = "0.13.3", features = ["alloc", "ecdsa"], default-features = false } @@ -81,7 +82,6 @@ bench = false default = ["std"] std = [ - "array-bytes", "bandersnatch_vrfs?/std", "bip39/rand", "bip39/std", @@ -112,7 +112,6 @@ std = [ "schnorrkel/std", "secp256k1/global-context", "secp256k1/std", - "secrecy/alloc", "serde/std", "sp-crypto-hashing/std", "sp-debug-derive/std", @@ -131,7 +130,6 @@ std = [ # Serde support without relying on std features. serde = [ - "array-bytes", "blake2", "bounded-collections/serde", "bs58/alloc", @@ -140,8 +138,6 @@ serde = [ "k256/serde", "primitive-types/serde_no_std", "scale-info/serde", - "secrecy/alloc", - "sp-crypto-hashing", "sp-storage/serde", ] @@ -149,11 +145,7 @@ serde = [ # or Intel SGX. # For the regular wasm runtime builds this should not be used. full_crypto = [ - "array-bytes", "blake2", - "ed25519-zebra", - "libsecp256k1", - "sp-crypto-hashing", "sp-runtime-interface/disable_target_static_assertions", ] diff --git a/substrate/primitives/core/check-features-variants.sh b/substrate/primitives/core/check-features-variants.sh new file mode 100755 index 00000000000..6d28212065a --- /dev/null +++ b/substrate/primitives/core/check-features-variants.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env -S bash -eux + +export RUSTFLAGS="-Cdebug-assertions=y -Dwarnings" +T=wasm32-unknown-unknown + +cargo check --target=$T --release --no-default-features --features="bls-experimental" +cargo check --target=$T --release --no-default-features --features="full_crypto,bls-experimental" +cargo check --target=$T --release --no-default-features --features="bandersnatch-experimental" +cargo check --target=$T --release --no-default-features --features="full_crypto,serde,bandersnatch-experimental" +cargo check --target=$T --release --no-default-features --features="full_crypto,serde" +cargo check --target=$T --release --no-default-features --features="full_crypto" +cargo check --target=$T --release --no-default-features --features="serde" +cargo check --target=$T --release --no-default-features diff --git a/substrate/primitives/core/src/address_uri.rs b/substrate/primitives/core/src/address_uri.rs index 211d47c0093..2e32d0cd86d 100644 --- a/substrate/primitives/core/src/address_uri.rs +++ b/substrate/primitives/core/src/address_uri.rs @@ -17,7 +17,7 @@ //! Little util for parsing an address URI. Replaces regular expressions. -#[cfg(all(not(feature = "std"), any(feature = "serde", feature = "full_crypto")))] +#[cfg(not(feature = "std"))] use sp_std::{ alloc::string::{String, ToString}, vec::Vec, diff --git a/substrate/primitives/core/src/bandersnatch.rs b/substrate/primitives/core/src/bandersnatch.rs index 61e7162544a..5cae6047f16 100644 --- a/substrate/primitives/core/src/bandersnatch.rs +++ b/substrate/primitives/core/src/bandersnatch.rs @@ -22,19 +22,18 @@ #[cfg(feature = "serde")] use crate::crypto::Ss58Codec; +#[cfg(feature = "full_crypto")] +use crate::crypto::VrfSecret; use crate::crypto::{ - ByteArray, CryptoType, CryptoTypeId, Derive, Public as TraitPublic, UncheckedFrom, VrfPublic, + ByteArray, CryptoType, CryptoTypeId, Derive, DeriveError, DeriveJunction, Pair as TraitPair, + Public as TraitPublic, SecretStringError, UncheckedFrom, VrfPublic, }; -#[cfg(feature = "full_crypto")] -use crate::crypto::{DeriveError, DeriveJunction, Pair as TraitPair, SecretStringError, VrfSecret}; #[cfg(feature = "serde")] use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; #[cfg(all(not(feature = "std"), feature = "serde"))] use sp_std::alloc::{format, string::String}; -use bandersnatch_vrfs::CanonicalSerialize; -#[cfg(feature = "full_crypto")] -use bandersnatch_vrfs::SecretKey; +use bandersnatch_vrfs::{CanonicalSerialize, SecretKey}; use codec::{Decode, Encode, EncodeLike, MaxEncodedLen}; use scale_info::TypeInfo; @@ -45,10 +44,8 @@ use sp_std::{vec, vec::Vec}; pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"band"); /// Context used to produce a plain signature without any VRF input/output. -#[cfg(feature = "full_crypto")] pub const SIGNING_CTX: &[u8] = b"BandersnatchSigningContext"; -#[cfg(feature = "full_crypto")] const SEED_SERIALIZED_SIZE: usize = 32; const PUBLIC_SERIALIZED_SIZE: usize = 33; @@ -56,7 +53,6 @@ const SIGNATURE_SERIALIZED_SIZE: usize = 65; const PREOUT_SERIALIZED_SIZE: usize = 33; /// Bandersnatch public key. -#[cfg_attr(feature = "full_crypto", derive(Hash))] #[derive( Clone, Copy, @@ -69,6 +65,7 @@ const PREOUT_SERIALIZED_SIZE: usize = 33; PassByInner, MaxEncodedLen, TypeInfo, + Hash, )] pub struct Public(pub [u8; PUBLIC_SERIALIZED_SIZE]); @@ -116,7 +113,6 @@ impl ByteArray for Public { impl TraitPublic for Public {} impl CryptoType for Public { - #[cfg(feature = "full_crypto")] type Pair = Pair; } @@ -154,8 +150,9 @@ impl<'de> Deserialize<'de> for Public { /// /// The signature is created via the [`VrfSecret::vrf_sign`] using [`SIGNING_CTX`] as transcript /// `label`. -#[cfg_attr(feature = "full_crypto", derive(Hash))] -#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, PassByInner, MaxEncodedLen, TypeInfo)] +#[derive( + Clone, Copy, PartialEq, Eq, Encode, Decode, PassByInner, MaxEncodedLen, TypeInfo, Hash, +)] pub struct Signature([u8; SIGNATURE_SERIALIZED_SIZE]); impl UncheckedFrom<[u8; SIGNATURE_SERIALIZED_SIZE]> for Signature { @@ -194,7 +191,6 @@ impl ByteArray for Signature { } impl CryptoType for Signature { - #[cfg(feature = "full_crypto")] type Pair = Pair; } @@ -211,18 +207,15 @@ impl sp_std::fmt::Debug for Signature { } /// The raw secret seed, which can be used to reconstruct the secret [`Pair`]. -#[cfg(feature = "full_crypto")] type Seed = [u8; SEED_SERIALIZED_SIZE]; /// Bandersnatch secret key. -#[cfg(feature = "full_crypto")] #[derive(Clone)] pub struct Pair { secret: SecretKey, seed: Seed, } -#[cfg(feature = "full_crypto")] impl Pair { /// Get the key seed. pub fn seed(&self) -> Seed { @@ -230,7 +223,6 @@ impl Pair { } } -#[cfg(feature = "full_crypto")] impl TraitPair for Pair { type Seed = Seed; type Public = Public; @@ -287,6 +279,7 @@ impl TraitPair for Pair { /// the constant label [`SIGNING_CTX`] and `data` without any additional data. /// /// See [`vrf::VrfSignData`] for additional details. + #[cfg(feature = "full_crypto")] fn sign(&self, data: &[u8]) -> Signature { let data = vrf::VrfSignData::new_unchecked(SIGNING_CTX, &[data], None); self.vrf_sign(&data).signature @@ -305,7 +298,6 @@ impl TraitPair for Pair { } } -#[cfg(feature = "full_crypto")] impl CryptoType for Pair { type Pair = Pair; } diff --git a/substrate/primitives/core/src/bls.rs b/substrate/primitives/core/src/bls.rs index 0c84d0ba8e6..2256e4cd823 100644 --- a/substrate/primitives/core/src/bls.rs +++ b/substrate/primitives/core/src/bls.rs @@ -25,11 +25,11 @@ #[cfg(feature = "serde")] use crate::crypto::Ss58Codec; -use crate::crypto::{ByteArray, CryptoType, Derive, Public as TraitPublic, UncheckedFrom}; -#[cfg(feature = "full_crypto")] -use crate::crypto::{DeriveError, DeriveJunction, Pair as TraitPair, SecretStringError}; +use crate::crypto::{ + ByteArray, CryptoType, Derive, DeriveError, DeriveJunction, Pair as TraitPair, + Public as TraitPublic, SecretStringError, UncheckedFrom, +}; -#[cfg(feature = "full_crypto")] use sp_std::vec::Vec; use codec::{Decode, Encode, MaxEncodedLen}; @@ -40,9 +40,10 @@ use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; #[cfg(all(not(feature = "std"), feature = "serde"))] use sp_std::alloc::{format, string::String}; -use w3f_bls::{DoublePublicKey, DoubleSignature, EngineBLS, SerializableToBytes, TinyBLS381}; -#[cfg(feature = "full_crypto")] -use w3f_bls::{DoublePublicKeyScheme, Keypair, Message, SecretKey}; +use w3f_bls::{ + DoublePublicKey, DoublePublicKeyScheme, DoubleSignature, EngineBLS, Keypair, Message, + SecretKey, SerializableToBytes, TinyBLS381, +}; use sp_runtime_interface::pass_by::{self, PassBy, PassByInner}; use sp_std::{convert::TryFrom, marker::PhantomData, ops::Deref}; @@ -57,7 +58,6 @@ pub mod bls377 { pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"bls7"); /// BLS12-377 key pair. - #[cfg(feature = "full_crypto")] pub type Pair = super::Pair; /// BLS12-377 public key. pub type Public = super::Public; @@ -79,7 +79,6 @@ pub mod bls381 { pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"bls8"); /// BLS12-381 key pair. - #[cfg(feature = "full_crypto")] pub type Pair = super::Pair; /// BLS12-381 public key. pub type Public = super::Public; @@ -96,7 +95,6 @@ trait BlsBound: EngineBLS + HardJunctionId + Send + Sync + 'static {} impl BlsBound for T {} /// Secret key serialized size -#[cfg(feature = "full_crypto")] const SECRET_KEY_SERIALIZED_SIZE: usize = as SerializableToBytes>::SERIALIZED_BYTES_SIZE; @@ -113,7 +111,6 @@ pub const SIGNATURE_SERIALIZED_SIZE: usize = /// It's not called a "secret key" because ring doesn't expose the secret keys /// of the key pair (yeah, dumb); as such we're forced to remember the seed manually if we /// will need it later (such as for HDKD). -#[cfg(feature = "full_crypto")] type Seed = [u8; SECRET_KEY_SERIALIZED_SIZE]; /// A public key. @@ -150,7 +147,6 @@ impl Ord for Public { } } -#[cfg(feature = "full_crypto")] impl sp_std::hash::Hash for Public { fn hash(&self, state: &mut H) { self.inner.hash(state) @@ -226,7 +222,6 @@ impl From> for [u8; PUBLIC_KEY_SERIALIZED_SIZE] { } } -#[cfg(feature = "full_crypto")] impl From> for Public { fn from(x: Pair) -> Self { x.public() @@ -296,7 +291,6 @@ impl TraitPublic for Public {} impl Derive for Public {} impl CryptoType for Public { - #[cfg(feature = "full_crypto")] type Pair = Pair; } @@ -322,7 +316,6 @@ impl PartialEq for Signature { impl Eq for Signature {} -#[cfg(feature = "full_crypto")] impl sp_std::hash::Hash for Signature { fn hash(&self, state: &mut H) { self.inner.hash(state) @@ -412,15 +405,12 @@ impl UncheckedFrom<[u8; SIGNATURE_SERIALIZED_SIZE]> for Signature { } impl CryptoType for Signature { - #[cfg(feature = "full_crypto")] type Pair = Pair; } /// A key pair. -#[cfg(feature = "full_crypto")] pub struct Pair(Keypair); -#[cfg(feature = "full_crypto")] impl Clone for Pair { fn clone(&self) -> Self { Pair(self.0.clone()) @@ -432,15 +422,12 @@ trait HardJunctionId { } /// Derive a single hard junction. -#[cfg(feature = "full_crypto")] fn derive_hard_junction(secret_seed: &Seed, cc: &[u8; 32]) -> Seed { (T::ID, secret_seed, cc).using_encoded(sp_crypto_hashing::blake2_256) } -#[cfg(feature = "full_crypto")] impl Pair {} -#[cfg(feature = "full_crypto")] impl TraitPair for Pair { type Seed = Seed; type Public = Public; @@ -480,6 +467,7 @@ impl TraitPair for Pair { Self::Public::unchecked_from(raw) } + #[cfg(feature = "full_crypto")] fn sign(&self, message: &[u8]) -> Self::Signature { let mut mutable_self = self.clone(); let r: [u8; SIGNATURE_SERIALIZED_SIZE] = @@ -523,7 +511,6 @@ impl TraitPair for Pair { } } -#[cfg(feature = "full_crypto")] impl CryptoType for Pair { type Pair = Pair; } diff --git a/substrate/primitives/core/src/crypto.rs b/substrate/primitives/core/src/crypto.rs index 2a8be2a2ba8..fab865d8c1f 100644 --- a/substrate/primitives/core/src/crypto.rs +++ b/substrate/primitives/core/src/crypto.rs @@ -18,7 +18,6 @@ //! Cryptographic utilities. use crate::{ed25519, sr25519}; -#[cfg(feature = "std")] use bip39::{Language, Mnemonic}; use codec::{Decode, Encode, MaxEncodedLen}; #[cfg(feature = "std")] @@ -26,7 +25,6 @@ use itertools::Itertools; #[cfg(feature = "std")] use rand::{rngs::OsRng, RngCore}; use scale_info::TypeInfo; -#[cfg(feature = "std")] pub use secrecy::{ExposeSecret, SecretString}; use sp_runtime_interface::pass_by::PassByInner; #[doc(hidden)] @@ -41,10 +39,7 @@ pub use ss58_registry::{from_known_address_format, Ss58AddressFormat, Ss58Addres /// Trait to zeroize a memory buffer. pub use zeroize::Zeroize; -#[cfg(feature = "std")] -pub use crate::address_uri::AddressUri; -#[cfg(any(feature = "std", feature = "full_crypto"))] -pub use crate::address_uri::Error as AddressUriError; +pub use crate::address_uri::{AddressUri, Error as AddressUriError}; /// The root phrase for our publicly known keys. pub const DEV_PHRASE: &str = @@ -82,7 +77,6 @@ impl> UncheckedInto for S { /// An error with the interpretation of a secret. #[cfg_attr(feature = "std", derive(thiserror::Error))] #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg(feature = "full_crypto")] pub enum SecretStringError { /// The overall format was invalid (e.g. the seed phrase contained symbols). #[cfg_attr(feature = "std", error("Invalid format {0}"))] @@ -104,7 +98,6 @@ pub enum SecretStringError { InvalidPath, } -#[cfg(any(feature = "std", feature = "full_crypto"))] impl From for SecretStringError { fn from(e: AddressUriError) -> Self { Self::InvalidFormat(e) @@ -114,7 +107,6 @@ impl From for SecretStringError { /// An error when deriving a key. #[cfg_attr(feature = "std", derive(thiserror::Error))] #[derive(Debug, Clone, PartialEq, Eq)] -#[cfg(feature = "full_crypto")] pub enum DeriveError { /// A soft key was found in the path (and is unsupported). #[cfg_attr(feature = "std", error("Soft key in path"))] @@ -125,7 +117,6 @@ pub enum DeriveError { /// a new secret key from an existing secret key and, in the case of `SoftRaw` and `SoftIndex` /// a new public key from an existing public key. #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Encode, Decode)] -#[cfg(any(feature = "full_crypto", feature = "serde"))] pub enum DeriveJunction { /// Soft (vanilla) derivation. Public keys have a correspondent derivation. Soft([u8; JUNCTION_ID_LEN]), @@ -133,7 +124,6 @@ pub enum DeriveJunction { Hard([u8; JUNCTION_ID_LEN]), } -#[cfg(any(feature = "full_crypto", feature = "serde"))] impl DeriveJunction { /// Consume self to return a soft derive junction with the same chain code. pub fn soften(self) -> Self { @@ -192,7 +182,6 @@ impl DeriveJunction { } } -#[cfg(any(feature = "full_crypto", feature = "serde"))] impl> From for DeriveJunction { fn from(j: T) -> DeriveJunction { let j = j.as_ref(); @@ -812,7 +801,6 @@ mod dummy { /// assert_eq!("0xe5be9a5092b81bca64be81d212e7f2f9eba183bb7a90954f7b76361f6edb5c0a", suri.phrase.expose_secret()); /// assert!(suri.password.is_none()); /// ``` -#[cfg(feature = "std")] pub struct SecretUri { /// The phrase to derive the private key. /// @@ -824,7 +812,6 @@ pub struct SecretUri { pub junctions: Vec, } -#[cfg(feature = "std")] impl sp_std::str::FromStr for SecretUri { type Err = SecretStringError; @@ -845,7 +832,6 @@ impl sp_std::str::FromStr for SecretUri { /// Trait suitable for typical cryptographic PKI key pair type. /// /// For now it just specifies how to create a key from a phrase and derivation path. -#[cfg(feature = "full_crypto")] pub trait Pair: CryptoType + Sized { /// The type which is used to encode a public key. type Public: Public + Hash; @@ -878,21 +864,19 @@ pub trait Pair: CryptoType + Sized { #[cfg(feature = "std")] fn generate_with_phrase(password: Option<&str>) -> (Self, String, Self::Seed) { let mnemonic = Mnemonic::generate(12).expect("Mnemonic generation always works; qed"); - let phrase = mnemonic.word_iter().join(" "); + let phrase = mnemonic.words().join(" "); let (pair, seed) = Self::from_phrase(&phrase, password) .expect("All phrases generated by Mnemonic are valid; qed"); (pair, phrase.to_owned(), seed) } /// Returns the KeyPair from the English BIP39 seed `phrase`, or an error if it's invalid. - #[cfg(feature = "std")] fn from_phrase( phrase: &str, password: Option<&str>, ) -> Result<(Self, Self::Seed), SecretStringError> { let mnemonic = Mnemonic::parse_in(Language::English, phrase) .map_err(|_| SecretStringError::InvalidPhrase)?; - let (entropy, entropy_len) = mnemonic.to_entropy_array(); let big_seed = substrate_bip39::seed_from_entropy(&entropy[0..entropy_len], password.unwrap_or("")) @@ -928,6 +912,7 @@ pub trait Pair: CryptoType + Sized { fn from_seed_slice(seed: &[u8]) -> Result; /// Sign a message. + #[cfg(feature = "full_crypto")] fn sign(&self, message: &[u8]) -> Self::Signature; /// Verify a signature on a message. Returns true if the signature is good. @@ -962,7 +947,6 @@ pub trait Pair: CryptoType + Sized { /// Notably, integer junction indices may be legally prefixed with arbitrary number of zeros. /// Similarly an empty password (ending the SURI with `///`) is perfectly valid and will /// generally be equivalent to no password at all. - #[cfg(feature = "std")] fn from_string_with_seed( s: &str, password_override: Option<&str>, @@ -996,7 +980,6 @@ pub trait Pair: CryptoType + Sized { /// Interprets the string `s` in order to generate a key pair. /// /// See [`from_string_with_seed`](Pair::from_string_with_seed) for more extensive documentation. - #[cfg(feature = "std")] fn from_string(s: &str, password_override: Option<&str>) -> Result { Self::from_string_with_seed(s, password_override).map(|x| x.0) } @@ -1054,7 +1037,6 @@ where /// Type which has a particular kind of crypto associated with it. pub trait CryptoType { /// The pair key type of this crypto. - #[cfg(feature = "full_crypto")] type Pair: Pair; } diff --git a/substrate/primitives/core/src/ecdsa.rs b/substrate/primitives/core/src/ecdsa.rs index e6bd2c7eb57..fa071e1b03f 100644 --- a/substrate/primitives/core/src/ecdsa.rs +++ b/substrate/primitives/core/src/ecdsa.rs @@ -24,16 +24,13 @@ use sp_runtime_interface::pass_by::PassByInner; #[cfg(feature = "serde")] use crate::crypto::Ss58Codec; use crate::crypto::{ - ByteArray, CryptoType, CryptoTypeId, Derive, Public as TraitPublic, UncheckedFrom, + ByteArray, CryptoType, CryptoTypeId, Derive, DeriveError, DeriveJunction, Pair as TraitPair, + Public as TraitPublic, SecretStringError, UncheckedFrom, }; -#[cfg(feature = "full_crypto")] -use crate::crypto::{DeriveError, DeriveJunction, Pair as TraitPair, SecretStringError}; -#[cfg(all(not(feature = "std"), feature = "full_crypto"))] -use k256::ecdsa::SigningKey as SecretKey; #[cfg(not(feature = "std"))] -use k256::ecdsa::VerifyingKey; -#[cfg(all(feature = "std", feature = "full_crypto"))] +use k256::ecdsa::{SigningKey as SecretKey, VerifyingKey}; +#[cfg(feature = "std")] use secp256k1::{ ecdsa::{RecoverableSignature, RecoveryId}, Message, PublicKey, SecretKey, SECP256K1, @@ -42,7 +39,7 @@ use secp256k1::{ use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; #[cfg(all(not(feature = "std"), feature = "serde"))] use sp_std::alloc::{format, string::String}; -#[cfg(feature = "full_crypto")] +#[cfg(not(feature = "std"))] use sp_std::vec::Vec; /// An identifier used to match public keys against ecdsa keys @@ -57,11 +54,9 @@ pub const SIGNATURE_SERIALIZED_SIZE: usize = 65; /// The secret seed. /// /// The raw secret seed, which can be used to create the `Pair`. -#[cfg(feature = "full_crypto")] type Seed = [u8; 32]; /// The ECDSA compressed public key. -#[cfg_attr(feature = "full_crypto", derive(Hash))] #[derive( Clone, Copy, @@ -74,6 +69,7 @@ type Seed = [u8; 32]; PartialEq, PartialOrd, Ord, + Hash, )] pub struct Public(pub [u8; PUBLIC_KEY_SERIALIZED_SIZE]); @@ -221,8 +217,7 @@ impl<'de> Deserialize<'de> for Public { } /// A signature (a 512-bit value, plus 8 bits for recovery ID). -#[cfg_attr(feature = "full_crypto", derive(Hash))] -#[derive(Encode, Decode, MaxEncodedLen, PassByInner, TypeInfo, PartialEq, Eq)] +#[derive(Hash, Encode, Decode, MaxEncodedLen, PassByInner, TypeInfo, PartialEq, Eq)] pub struct Signature(pub [u8; SIGNATURE_SERIALIZED_SIZE]); impl ByteArray for Signature { @@ -345,13 +340,11 @@ impl Signature { } /// Recover the public key from this signature and a message. - #[cfg(feature = "full_crypto")] pub fn recover>(&self, message: M) -> Option { self.recover_prehashed(&sp_crypto_hashing::blake2_256(message.as_ref())) } /// Recover the public key from this signature and a pre-hashed message. - #[cfg(feature = "full_crypto")] pub fn recover_prehashed(&self, message: &[u8; 32]) -> Option { #[cfg(feature = "std")] { @@ -380,7 +373,7 @@ impl From<(k256::ecdsa::Signature, k256::ecdsa::RecoveryId)> for Signature { } } -#[cfg(all(feature = "std", feature = "full_crypto"))] +#[cfg(feature = "std")] impl From for Signature { fn from(recsig: RecoverableSignature) -> Signature { let mut r = Self::default(); @@ -393,20 +386,17 @@ impl From for Signature { } /// Derive a single hard junction. -#[cfg(feature = "full_crypto")] fn derive_hard_junction(secret_seed: &Seed, cc: &[u8; 32]) -> Seed { ("Secp256k1HDKD", secret_seed, cc).using_encoded(sp_crypto_hashing::blake2_256) } /// A key pair. -#[cfg(feature = "full_crypto")] #[derive(Clone)] pub struct Pair { public: Public, secret: SecretKey, } -#[cfg(feature = "full_crypto")] impl TraitPair for Pair { type Public = Public; type Seed = Seed; @@ -454,6 +444,7 @@ impl TraitPair for Pair { } /// Sign a message. + #[cfg(feature = "full_crypto")] fn sign(&self, message: &[u8]) -> Signature { self.sign_prehashed(&sp_crypto_hashing::blake2_256(message)) } @@ -469,7 +460,6 @@ impl TraitPair for Pair { } } -#[cfg(feature = "full_crypto")] impl Pair { /// Get the seed for this key. pub fn seed(&self) -> Seed { @@ -496,6 +486,7 @@ impl Pair { } /// Sign a pre-hashed message + #[cfg(feature = "full_crypto")] pub fn sign_prehashed(&self, message: &[u8; 32]) -> Signature { #[cfg(feature = "std")] { @@ -550,7 +541,7 @@ impl Pair { // NOTE: this solution is not effective when `Pair` is moved around memory. // The very same problem affects other cryptographic backends that are just using // `zeroize`for their secrets. -#[cfg(all(feature = "std", feature = "full_crypto"))] +#[cfg(feature = "std")] impl Drop for Pair { fn drop(&mut self) { self.secret.non_secure_erase() @@ -558,16 +549,13 @@ impl Drop for Pair { } impl CryptoType for Public { - #[cfg(feature = "full_crypto")] type Pair = Pair; } impl CryptoType for Signature { - #[cfg(feature = "full_crypto")] type Pair = Pair; } -#[cfg(feature = "full_crypto")] impl CryptoType for Pair { type Pair = Pair; } diff --git a/substrate/primitives/core/src/ed25519.rs b/substrate/primitives/core/src/ed25519.rs index 60ebd93e12d..9f42b36dc8b 100644 --- a/substrate/primitives/core/src/ed25519.rs +++ b/substrate/primitives/core/src/ed25519.rs @@ -19,7 +19,6 @@ //! Simple Ed25519 API. // end::description[] -#[cfg(feature = "full_crypto")] use sp_std::vec::Vec; use crate::{ @@ -32,13 +31,11 @@ use scale_info::TypeInfo; #[cfg(feature = "serde")] use crate::crypto::Ss58Codec; use crate::crypto::{ - CryptoType, CryptoTypeId, Derive, FromEntropy, Public as TraitPublic, UncheckedFrom, + CryptoType, CryptoTypeId, Derive, DeriveError, DeriveJunction, FromEntropy, Pair as TraitPair, + Public as TraitPublic, SecretStringError, UncheckedFrom, }; #[cfg(feature = "full_crypto")] -use crate::crypto::{DeriveError, DeriveJunction, Pair as TraitPair, SecretStringError}; -#[cfg(feature = "full_crypto")] use core::convert::TryFrom; -#[cfg(feature = "full_crypto")] use ed25519_zebra::{SigningKey, VerificationKey}; #[cfg(feature = "serde")] use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; @@ -53,11 +50,9 @@ pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"ed25"); /// A secret seed. It's not called a "secret key" because ring doesn't expose the secret keys /// of the key pair (yeah, dumb); as such we're forced to remember the seed manually if we /// will need it later (such as for HDKD). -#[cfg(feature = "full_crypto")] type Seed = [u8; 32]; /// A public key. -#[cfg_attr(feature = "full_crypto", derive(Hash))] #[derive( PartialEq, Eq, @@ -70,11 +65,11 @@ type Seed = [u8; 32]; PassByInner, MaxEncodedLen, TypeInfo, + Hash, )] pub struct Public(pub [u8; 32]); /// A key pair. -#[cfg(feature = "full_crypto")] #[derive(Copy, Clone)] pub struct Pair { public: VerificationKey, @@ -210,8 +205,7 @@ impl<'de> Deserialize<'de> for Public { } /// A signature (a 512-bit value). -#[cfg_attr(feature = "full_crypto", derive(Hash))] -#[derive(Encode, Decode, MaxEncodedLen, PassByInner, TypeInfo, PartialEq, Eq)] +#[derive(Encode, Decode, MaxEncodedLen, PassByInner, TypeInfo, PartialEq, Eq, Hash)] pub struct Signature(pub [u8; 64]); impl TryFrom<&[u8]> for Signature { @@ -370,12 +364,10 @@ impl TraitPublic for Public {} impl Derive for Public {} /// Derive a single hard junction. -#[cfg(feature = "full_crypto")] fn derive_hard_junction(secret_seed: &Seed, cc: &[u8; 32]) -> Seed { ("Ed25519HDKD", secret_seed, cc).using_encoded(sp_crypto_hashing::blake2_256) } -#[cfg(feature = "full_crypto")] impl TraitPair for Pair { type Public = Public; type Seed = Seed; @@ -414,6 +406,7 @@ impl TraitPair for Pair { } /// Sign a message. + #[cfg(feature = "full_crypto")] fn sign(&self, message: &[u8]) -> Signature { Signature::from_raw(self.secret.sign(message).into()) } @@ -433,7 +426,6 @@ impl TraitPair for Pair { } } -#[cfg(feature = "full_crypto")] impl Pair { /// Get the seed for this key. pub fn seed(&self) -> Seed { @@ -454,16 +446,13 @@ impl Pair { } impl CryptoType for Public { - #[cfg(feature = "full_crypto")] type Pair = Pair; } impl CryptoType for Signature { - #[cfg(feature = "full_crypto")] type Pair = Pair; } -#[cfg(feature = "full_crypto")] impl CryptoType for Pair { type Pair = Pair; } diff --git a/substrate/primitives/core/src/lib.rs b/substrate/primitives/core/src/lib.rs index 0d43eea9962..c0b41234460 100644 --- a/substrate/primitives/core/src/lib.rs +++ b/substrate/primitives/core/src/lib.rs @@ -46,7 +46,6 @@ pub use sp_debug_derive::RuntimeDebug; #[cfg(feature = "serde")] pub use impl_serde::serialize as bytes; -#[cfg(feature = "full_crypto")] #[deprecated( since = "27.0.0", note = "`sp-crypto-hashing` re-exports will be removed after June 2024. Use `sp-crypto-hashing` instead." @@ -58,7 +57,6 @@ pub mod crypto; pub mod hexdisplay; pub use paste; -#[cfg(any(feature = "full_crypto", feature = "std"))] mod address_uri; #[cfg(feature = "bandersnatch-experimental")] pub mod bandersnatch; @@ -87,7 +85,6 @@ pub use self::{ hash::{convert_hash, H160, H256, H512}, uint::{U256, U512}, }; -#[cfg(feature = "full_crypto")] pub use crypto::{ByteArray, DeriveJunction, Pair, Public}; #[cfg(feature = "std")] diff --git a/substrate/primitives/core/src/paired_crypto.rs b/substrate/primitives/core/src/paired_crypto.rs index 20b32c339bd..6d2e6ddf334 100644 --- a/substrate/primitives/core/src/paired_crypto.rs +++ b/substrate/primitives/core/src/paired_crypto.rs @@ -19,11 +19,11 @@ #[cfg(feature = "serde")] use crate::crypto::Ss58Codec; -use crate::crypto::{ByteArray, CryptoType, Derive, Public as PublicT, UncheckedFrom}; -#[cfg(feature = "full_crypto")] -use crate::crypto::{DeriveError, DeriveJunction, Pair as PairT, SecretStringError}; +use crate::crypto::{ + ByteArray, CryptoType, Derive, DeriveError, DeriveJunction, Pair as PairT, Public as PublicT, + SecretStringError, UncheckedFrom, +}; -#[cfg(feature = "full_crypto")] use sp_std::vec::Vec; use codec::{Decode, Encode, MaxEncodedLen}; @@ -39,12 +39,11 @@ use sp_std::convert::TryFrom; /// ECDSA and BLS12-377 paired crypto scheme #[cfg(feature = "bls-experimental")] pub mod ecdsa_bls377 { + use crate::{bls377, crypto::CryptoTypeId, ecdsa}; #[cfg(feature = "full_crypto")] - use crate::Hasher; use crate::{ - bls377, - crypto::{CryptoTypeId, Pair as PairT, UncheckedFrom}, - ecdsa, + crypto::{Pair as PairT, UncheckedFrom}, + Hasher, }; /// An identifier used to match public keys against BLS12-377 keys @@ -56,7 +55,6 @@ pub mod ecdsa_bls377 { ecdsa::SIGNATURE_SERIALIZED_SIZE + bls377::SIGNATURE_SERIALIZED_SIZE; /// (ECDSA,BLS12-377) key-pair pair. - #[cfg(feature = "full_crypto")] pub type Pair = super::Pair; /// (ECDSA,BLS12-377) public key pair. pub type Public = super::Public; @@ -64,16 +62,13 @@ pub mod ecdsa_bls377 { pub type Signature = super::Signature; impl super::CryptoType for Public { - #[cfg(feature = "full_crypto")] type Pair = Pair; } impl super::CryptoType for Signature { - #[cfg(feature = "full_crypto")] type Pair = Pair; } - #[cfg(feature = "full_crypto")] impl super::CryptoType for Pair { type Pair = Pair; } @@ -136,7 +131,6 @@ pub mod ecdsa_bls377 { /// Secure seed length. /// /// Currently only supporting sub-schemes whose seed is a 32-bytes array. -#[cfg(feature = "full_crypto")] const SECURE_SEED_LEN: usize = 32; /// A secret seed. @@ -144,14 +138,12 @@ const SECURE_SEED_LEN: usize = 32; /// It's not called a "secret key" because ring doesn't expose the secret keys /// of the key pair (yeah, dumb); as such we're forced to remember the seed manually if we /// will need it later (such as for HDKD). -#[cfg(feature = "full_crypto")] type Seed = [u8; SECURE_SEED_LEN]; /// A public key. #[derive(Clone, Encode, Decode, MaxEncodedLen, TypeInfo, PartialEq, Eq, PartialOrd, Ord)] pub struct Public([u8; LEFT_PLUS_RIGHT_LEN]); -#[cfg(feature = "full_crypto")] impl sp_std::hash::Hash for Public { fn hash(&self, state: &mut H) { self.0.hash(state); @@ -215,7 +207,6 @@ impl PassBy for Public { type PassBy = pass_by::Inner; } -#[cfg(feature = "full_crypto")] impl< LeftPair: PairT, RightPair: PairT, @@ -311,7 +302,6 @@ impl SignatureBound for T {} #[derive(Clone, Encode, Decode, MaxEncodedLen, TypeInfo, PartialEq, Eq)] pub struct Signature([u8; LEFT_PLUS_RIGHT_LEN]); -#[cfg(feature = "full_crypto")] impl sp_std::hash::Hash for Signature { fn hash(&self, state: &mut H) { self.0.hash(state); @@ -411,7 +401,6 @@ impl UncheckedFrom<[u8; LEFT_PLUS_RIGHT_LEN]> } /// A key pair. -#[cfg(feature = "full_crypto")] #[derive(Clone)] pub struct Pair< LeftPair: PairT, @@ -423,7 +412,6 @@ pub struct Pair< right: RightPair, } -#[cfg(feature = "full_crypto")] impl< LeftPair: PairT, RightPair: PairT, @@ -483,6 +471,7 @@ where Self::Public::unchecked_from(raw) } + #[cfg(feature = "full_crypto")] fn sign(&self, message: &[u8]) -> Self::Signature { let mut raw: [u8; SIGNATURE_LEN] = [0u8; SIGNATURE_LEN]; raw[..LeftPair::Signature::LEN].copy_from_slice(self.left.sign(message).as_ref()); diff --git a/substrate/primitives/core/src/sr25519.rs b/substrate/primitives/core/src/sr25519.rs index 7c02afc3cd5..6c04eb8def1 100644 --- a/substrate/primitives/core/src/sr25519.rs +++ b/substrate/primitives/core/src/sr25519.rs @@ -19,20 +19,14 @@ //! //! Note: `CHAIN_CODE_LENGTH` must be equal to `crate::crypto::JUNCTION_ID_LEN` //! for this to work. -#[cfg(any(feature = "full_crypto", feature = "serde"))] -use crate::crypto::DeriveJunction; #[cfg(feature = "serde")] use crate::crypto::Ss58Codec; +use crate::crypto::{DeriveError, DeriveJunction, Pair as TraitPair, SecretStringError}; #[cfg(feature = "full_crypto")] -use crate::crypto::{DeriveError, Pair as TraitPair, SecretStringError}; -#[cfg(feature = "full_crypto")] -use schnorrkel::{ - derive::CHAIN_CODE_LENGTH, signing_context, ExpansionMode, Keypair, MiniSecretKey, SecretKey, -}; -#[cfg(any(feature = "full_crypto", feature = "serde"))] +use schnorrkel::signing_context; use schnorrkel::{ - derive::{ChainCode, Derivation}, - PublicKey, + derive::{ChainCode, Derivation, CHAIN_CODE_LENGTH}, + ExpansionMode, Keypair, MiniSecretKey, PublicKey, SecretKey, }; use sp_std::vec::Vec; @@ -47,7 +41,6 @@ use codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; use sp_std::ops::Deref; -#[cfg(feature = "full_crypto")] use schnorrkel::keys::{MINI_SECRET_KEY_LENGTH, SECRET_KEY_LENGTH}; #[cfg(feature = "serde")] use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; @@ -56,14 +49,12 @@ use sp_runtime_interface::pass_by::PassByInner; use sp_std::alloc::{format, string::String}; // signing context -#[cfg(feature = "full_crypto")] const SIGNING_CTX: &[u8] = b"substrate"; /// An identifier used to match public keys against sr25519 keys pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"sr25"); /// An Schnorrkel/Ristretto x25519 ("sr25519") public key. -#[cfg_attr(feature = "full_crypto", derive(Hash))] #[derive( PartialEq, Eq, @@ -76,14 +67,13 @@ pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"sr25"); PassByInner, MaxEncodedLen, TypeInfo, + Hash, )] pub struct Public(pub [u8; 32]); /// An Schnorrkel/Ristretto x25519 ("sr25519") key pair. -#[cfg(feature = "full_crypto")] pub struct Pair(Keypair); -#[cfg(feature = "full_crypto")] impl Clone for Pair { fn clone(&self) -> Self { Pair(schnorrkel::Keypair { @@ -216,8 +206,7 @@ impl<'de> Deserialize<'de> for Public { } /// An Schnorrkel/Ristretto x25519 ("sr25519") signature. -#[cfg_attr(feature = "full_crypto", derive(Hash))] -#[derive(Encode, Decode, MaxEncodedLen, PassByInner, TypeInfo, PartialEq, Eq)] +#[derive(Encode, Decode, MaxEncodedLen, PassByInner, TypeInfo, PartialEq, Eq, Hash)] pub struct Signature(pub [u8; 64]); impl TryFrom<&[u8]> for Signature { @@ -435,16 +424,13 @@ impl AsRef for Pair { } /// Derive a single hard junction. -#[cfg(feature = "full_crypto")] fn derive_hard_junction(secret: &SecretKey, cc: &[u8; CHAIN_CODE_LENGTH]) -> MiniSecretKey { secret.hard_derive_mini_secret_key(Some(ChainCode(*cc)), b"").0 } /// The raw secret seed, which can be used to recreate the `Pair`. -#[cfg(feature = "full_crypto")] type Seed = [u8; MINI_SECRET_KEY_LENGTH]; -#[cfg(feature = "full_crypto")] impl TraitPair for Pair { type Public = Public; type Seed = Seed; @@ -499,6 +485,7 @@ impl TraitPair for Pair { Ok((Self(result.into()), seed.map(|s| MiniSecretKey::to_bytes(&s)))) } + #[cfg(feature = "full_crypto")] fn sign(&self, message: &[u8]) -> Signature { let context = signing_context(SIGNING_CTX); self.0.sign(context.bytes(message)).into() @@ -533,16 +520,13 @@ impl Pair { } impl CryptoType for Public { - #[cfg(feature = "full_crypto")] type Pair = Pair; } impl CryptoType for Signature { - #[cfg(feature = "full_crypto")] type Pair = Pair; } -#[cfg(feature = "full_crypto")] impl CryptoType for Pair { type Pair = Pair; } diff --git a/substrate/primitives/keyring/Cargo.toml b/substrate/primitives/keyring/Cargo.toml index 1c936b6685b..940fe90916d 100644 --- a/substrate/primitives/keyring/Cargo.toml +++ b/substrate/primitives/keyring/Cargo.toml @@ -18,10 +18,13 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] strum = { version = "0.24.1", features = ["derive"], default-features = false } -sp-core = { path = "../core" } -sp-runtime = { path = "../runtime" } +sp-core = { path = "../core", default-features = false } +sp-runtime = { path = "../runtime", default-features = false } [features] +default = ["std"] +std = ["sp-core/std", "sp-runtime/std", "strum/std"] + # This feature adds Bandersnatch crypto primitives. # It should not be used in production since the implementation and interface may still # be subject to significant changes. diff --git a/substrate/primitives/keyring/check-features-variants.sh b/substrate/primitives/keyring/check-features-variants.sh new file mode 100755 index 00000000000..9c28d835894 --- /dev/null +++ b/substrate/primitives/keyring/check-features-variants.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env -S bash -eux + +export RUSTFLAGS="-Cdebug-assertions=y -Dwarnings" +T=wasm32-unknown-unknown + +cargo check --release +cargo check --release --features="bandersnatch-experimental" +cargo check --release --target=$T --no-default-features diff --git a/substrate/primitives/keyring/src/bandersnatch.rs b/substrate/primitives/keyring/src/bandersnatch.rs index eb60f856327..67fc5c47df6 100644 --- a/substrate/primitives/keyring/src/bandersnatch.rs +++ b/substrate/primitives/keyring/src/bandersnatch.rs @@ -18,14 +18,21 @@ //! A set of well-known keys used for testing. pub use sp_core::bandersnatch; +#[cfg(feature = "std")] +use sp_core::bandersnatch::Signature; use sp_core::{ - bandersnatch::{Pair, Public, Signature}, + bandersnatch::{Pair, Public}, crypto::UncheckedFrom, hex2array, ByteArray, Pair as PairT, }; +extern crate alloc; +use alloc::{fmt, format, str::FromStr, string::String, vec::Vec}; + /// Set of test accounts. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum::Display, strum::EnumIter)] +#[derive( + Debug, Clone, Copy, PartialEq, Eq, Hash, strum::Display, strum::EnumIter, Ord, PartialOrd, +)] pub enum Keyring { Alice, Bob, @@ -56,6 +63,7 @@ impl Keyring { Public::from(self).to_raw_vec() } + #[cfg(feature = "std")] pub fn sign(self, msg: &[u8]) -> Signature { Pair::from(self).sign(msg) } @@ -102,16 +110,16 @@ impl From for &'static str { #[derive(Debug)] pub struct ParseKeyringError; -impl std::fmt::Display for ParseKeyringError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl fmt::Display for ParseKeyringError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "ParseKeyringError") } } -impl std::str::FromStr for Keyring { +impl FromStr for Keyring { type Err = ParseKeyringError; - fn from_str(s: &str) -> Result::Err> { + fn from_str(s: &str) -> Result::Err> { match s { "Alice" => Ok(Keyring::Alice), "Bob" => Ok(Keyring::Bob), diff --git a/substrate/primitives/keyring/src/ed25519.rs b/substrate/primitives/keyring/src/ed25519.rs index ade42b29494..98ca368e53c 100644 --- a/substrate/primitives/keyring/src/ed25519.rs +++ b/substrate/primitives/keyring/src/ed25519.rs @@ -18,14 +18,21 @@ //! Support code for the runtime. A set of test accounts. pub use sp_core::ed25519; +#[cfg(feature = "std")] +use sp_core::ed25519::Signature; use sp_core::{ - ed25519::{Pair, Public, Signature}, + ed25519::{Pair, Public}, hex2array, ByteArray, Pair as PairT, H256, }; use sp_runtime::AccountId32; +extern crate alloc; +use alloc::{format, string::String, vec::Vec}; + /// Set of test accounts. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum::Display, strum::EnumIter)] +#[derive( + Debug, Clone, Copy, PartialEq, Eq, Hash, strum::Display, strum::EnumIter, Ord, PartialOrd, +)] pub enum Keyring { Alice, Bob, @@ -76,6 +83,7 @@ impl Keyring { self.to_raw_public().into() } + #[cfg(feature = "std")] pub fn sign(self, msg: &[u8]) -> Signature { Pair::from(self).sign(msg) } diff --git a/substrate/primitives/keyring/src/lib.rs b/substrate/primitives/keyring/src/lib.rs index ee7fd56ba11..f753bf4b0dd 100644 --- a/substrate/primitives/keyring/src/lib.rs +++ b/substrate/primitives/keyring/src/lib.rs @@ -17,6 +17,8 @@ //! Support code for the runtime. A set of test accounts. +#![cfg_attr(not(feature = "std"), no_std)] + /// Test account crypto for sr25519. pub mod sr25519; diff --git a/substrate/primitives/keyring/src/sr25519.rs b/substrate/primitives/keyring/src/sr25519.rs index 1c2a2526efb..a3a506152d7 100644 --- a/substrate/primitives/keyring/src/sr25519.rs +++ b/substrate/primitives/keyring/src/sr25519.rs @@ -18,15 +18,22 @@ //! Support code for the runtime. A set of test accounts. pub use sp_core::sr25519; +#[cfg(feature = "std")] +use sp_core::sr25519::Signature; use sp_core::{ hex2array, - sr25519::{Pair, Public, Signature}, + sr25519::{Pair, Public}, ByteArray, Pair as PairT, H256, }; use sp_runtime::AccountId32; +extern crate alloc; +use alloc::{fmt, format, str::FromStr, string::String, vec::Vec}; + /// Set of test accounts. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum::Display, strum::EnumIter)] +#[derive( + Debug, Clone, Copy, PartialEq, Eq, Hash, strum::Display, strum::EnumIter, Ord, PartialOrd, +)] pub enum Keyring { Alice, Bob, @@ -77,6 +84,7 @@ impl Keyring { self.to_raw_public().into() } + #[cfg(feature = "std")] pub fn sign(self, msg: &[u8]) -> Signature { Pair::from(self).sign(msg) } @@ -140,16 +148,16 @@ impl From for sp_runtime::MultiSigner { #[derive(Debug)] pub struct ParseKeyringError; -impl std::fmt::Display for ParseKeyringError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl fmt::Display for ParseKeyringError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "ParseKeyringError") } } -impl std::str::FromStr for Keyring { +impl FromStr for Keyring { type Err = ParseKeyringError; - fn from_str(s: &str) -> Result::Err> { + fn from_str(s: &str) -> Result::Err> { match s { "alice" => Ok(Keyring::Alice), "bob" => Ok(Keyring::Bob), diff --git a/substrate/test-utils/runtime/Cargo.toml b/substrate/test-utils/runtime/Cargo.toml index 3bba5cd5bf0..b6e6346e801 100644 --- a/substrate/test-utils/runtime/Cargo.toml +++ b/substrate/test-utils/runtime/Cargo.toml @@ -24,9 +24,9 @@ sp-block-builder = { path = "../../primitives/block-builder", default-features = codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } sp-inherents = { path = "../../primitives/inherents", default-features = false } -sp-keyring = { path = "../../primitives/keyring", optional = true } +sp-keyring = { path = "../../primitives/keyring", default-features = false } sp-offchain = { path = "../../primitives/offchain", default-features = false } -sp-core = { path = "../../primitives/core", default-features = false } +sp-core = { path = "../../primitives/core", default-features = false, features = ["serde"] } sp-crypto-hashing = { path = "../../primitives/crypto/hashing", default-features = false } sp-std = { path = "../../primitives/std", default-features = false } sp-io = { path = "../../primitives/io", default-features = false } @@ -99,7 +99,7 @@ std = [ "sp-genesis-builder/std", "sp-inherents/std", "sp-io/std", - "sp-keyring", + "sp-keyring/std", "sp-offchain/std", "sp-runtime/std", "sp-session/std", -- GitLab From 82f3c3e2e81d3ea4b9bc35a14432d3ab93fb5b52 Mon Sep 17 00:00:00 2001 From: gupnik Date: Wed, 13 Mar 2024 12:31:01 +0530 Subject: [PATCH 390/392] Construct Runtime v2 (#1378) Moved from https://github.com/paritytech/substrate/pull/14788 ---- Fixes https://github.com/paritytech/polkadot-sdk/issues/232 This PR introduces outer-macro approach for `construct_runtime` as discussed in the linked issue. It looks like the following: ```rust #[frame_support::runtime] mod runtime { #[runtime::runtime] #[runtime::derive( RuntimeCall, RuntimeEvent, RuntimeError, RuntimeOrigin, RuntimeFreezeReason, RuntimeHoldReason, RuntimeSlashReason, RuntimeLockId, RuntimeTask, )] pub struct Runtime; #[runtime::pallet_index(0)] pub type System = frame_system; #[runtime::pallet_index(1)] pub type Timestamp = pallet_timestamp; #[runtime::pallet_index(2)] pub type Aura = pallet_aura; #[runtime::pallet_index(3)] pub type Grandpa = pallet_grandpa; #[runtime::pallet_index(4)] pub type Balances = pallet_balances; #[runtime::pallet_index(5)] pub type TransactionPayment = pallet_transaction_payment; #[runtime::pallet_index(6)] pub type Sudo = pallet_sudo; // Include the custom logic from the pallet-template in the runtime. #[runtime::pallet_index(7)] pub type TemplateModule = pallet_template; } ``` ## Features - `#[runtime::runtime]` attached to a struct defines the main runtime - `#[runtime::derive]` attached to this struct defines the types generated by runtime - `#[runtime::pallet_index]` must be attached to a pallet to define its index - `#[runtime::disable_call]` can be optionally attached to a pallet to disable its calls - `#[runtime::disable_unsigned]` can be optionally attached to a pallet to disable unsigned calls - A pallet instance can be defined as `TemplateModule: pallet_template` - An optional attribute can be defined as `#[frame_support::runtime(legacy_ordering)]` to ensure that the order of hooks is same as the order of pallets (and not based on the pallet_index). This is to support legacy runtimes and should be avoided for new ones. ## Todo - [x] Update the latest syntax in kitchensink and tests - [x] Update UI tests - [x] Docs ## Extension - Abstract away the Executive similar to https://github.com/paritytech/substrate/pull/14742 - Optionally avoid the need to specify all runtime types (TBD) --------- Co-authored-by: Francisco Aguirre Co-authored-by: Nikhil Gupta <> --- prdoc/pr_1378.prdoc | 27 + substrate/bin/node/runtime/Cargo.toml | 2 +- substrate/bin/node/runtime/src/lib.rs | 342 ++++-- substrate/frame/support/Cargo.toml | 4 +- substrate/frame/support/procedural/Cargo.toml | 1 + .../procedural/src/construct_runtime/mod.rs | 15 +- substrate/frame/support/procedural/src/lib.rs | 68 ++ .../src/pallet/expand/tt_default_parts.rs | 74 ++ .../procedural/src/pallet/parse/helper.rs | 6 + .../procedural/src/runtime/expand/mod.rs | 320 ++++++ .../support/procedural/src/runtime/mod.rs | 236 +++++ .../procedural/src/runtime/parse/helper.rs | 37 + .../procedural/src/runtime/parse/mod.rs | 266 +++++ .../procedural/src/runtime/parse/pallet.rs | 99 ++ .../src/runtime/parse/pallet_decl.rs | 60 ++ .../src/runtime/parse/runtime_struct.rs | 35 + .../src/runtime/parse/runtime_types.rs | 76 ++ substrate/frame/support/src/lib.rs | 3 + substrate/frame/support/test/Cargo.toml | 2 +- .../{construct_runtime.rs => runtime.rs} | 282 +++-- .../test/tests/runtime_legacy_ordering.rs | 993 ++++++++++++++++++ .../frame/support/test/tests/runtime_ui.rs | 36 + .../runtime_ui/can_only_be_attached_to_mod.rs | 21 + .../can_only_be_attached_to_mod.stderr | 5 + .../runtime_ui/conflicting_pallet_index.rs | 43 + .../conflicting_pallet_index.stderr | 11 + .../runtime_ui/conflicting_pallet_name.rs | 43 + .../runtime_ui/conflicting_pallet_name.stderr | 11 + .../tests/runtime_ui/invalid_attribute.rs | 23 + .../tests/runtime_ui/invalid_attribute.stderr | 5 + .../tests/runtime_ui/invalid_pallet_index.rs | 28 + .../runtime_ui/invalid_pallet_index.stderr | 5 + .../runtime_ui/invalid_runtime_type_derive.rs | 25 + .../invalid_runtime_type_derive.stderr | 5 + .../test/tests/runtime_ui/missing_runtime.rs | 21 + .../tests/runtime_ui/missing_runtime.stderr | 5 + .../missing_runtime_types_derive.rs | 24 + .../missing_runtime_types_derive.stderr | 5 + .../tests/runtime_ui/missing_system_pallet.rs | 25 + .../runtime_ui/missing_system_pallet.stderr | 5 + .../test/tests/runtime_ui/pass/basic.rs | 37 + .../test/tests/runtime_ui/runtime_struct.rs | 24 + .../tests/runtime_ui/runtime_struct.stderr | 5 + templates/solochain/runtime/Cargo.toml | 2 +- templates/solochain/runtime/src/lib.rs | 55 +- 45 files changed, 3212 insertions(+), 205 deletions(-) create mode 100644 prdoc/pr_1378.prdoc create mode 100644 substrate/frame/support/procedural/src/runtime/expand/mod.rs create mode 100644 substrate/frame/support/procedural/src/runtime/mod.rs create mode 100644 substrate/frame/support/procedural/src/runtime/parse/helper.rs create mode 100644 substrate/frame/support/procedural/src/runtime/parse/mod.rs create mode 100644 substrate/frame/support/procedural/src/runtime/parse/pallet.rs create mode 100644 substrate/frame/support/procedural/src/runtime/parse/pallet_decl.rs create mode 100644 substrate/frame/support/procedural/src/runtime/parse/runtime_struct.rs create mode 100644 substrate/frame/support/procedural/src/runtime/parse/runtime_types.rs rename substrate/frame/support/test/tests/{construct_runtime.rs => runtime.rs} (89%) create mode 100644 substrate/frame/support/test/tests/runtime_legacy_ordering.rs create mode 100644 substrate/frame/support/test/tests/runtime_ui.rs create mode 100644 substrate/frame/support/test/tests/runtime_ui/can_only_be_attached_to_mod.rs create mode 100644 substrate/frame/support/test/tests/runtime_ui/can_only_be_attached_to_mod.stderr create mode 100644 substrate/frame/support/test/tests/runtime_ui/conflicting_pallet_index.rs create mode 100644 substrate/frame/support/test/tests/runtime_ui/conflicting_pallet_index.stderr create mode 100644 substrate/frame/support/test/tests/runtime_ui/conflicting_pallet_name.rs create mode 100644 substrate/frame/support/test/tests/runtime_ui/conflicting_pallet_name.stderr create mode 100644 substrate/frame/support/test/tests/runtime_ui/invalid_attribute.rs create mode 100644 substrate/frame/support/test/tests/runtime_ui/invalid_attribute.stderr create mode 100644 substrate/frame/support/test/tests/runtime_ui/invalid_pallet_index.rs create mode 100644 substrate/frame/support/test/tests/runtime_ui/invalid_pallet_index.stderr create mode 100644 substrate/frame/support/test/tests/runtime_ui/invalid_runtime_type_derive.rs create mode 100644 substrate/frame/support/test/tests/runtime_ui/invalid_runtime_type_derive.stderr create mode 100644 substrate/frame/support/test/tests/runtime_ui/missing_runtime.rs create mode 100644 substrate/frame/support/test/tests/runtime_ui/missing_runtime.stderr create mode 100644 substrate/frame/support/test/tests/runtime_ui/missing_runtime_types_derive.rs create mode 100644 substrate/frame/support/test/tests/runtime_ui/missing_runtime_types_derive.stderr create mode 100644 substrate/frame/support/test/tests/runtime_ui/missing_system_pallet.rs create mode 100644 substrate/frame/support/test/tests/runtime_ui/missing_system_pallet.stderr create mode 100644 substrate/frame/support/test/tests/runtime_ui/pass/basic.rs create mode 100644 substrate/frame/support/test/tests/runtime_ui/runtime_struct.rs create mode 100644 substrate/frame/support/test/tests/runtime_ui/runtime_struct.stderr diff --git a/prdoc/pr_1378.prdoc b/prdoc/pr_1378.prdoc new file mode 100644 index 00000000000..6533dcb6630 --- /dev/null +++ b/prdoc/pr_1378.prdoc @@ -0,0 +1,27 @@ +title: Construct Runtime V2 - An outer macro approach to define the runtime + +doc: + - audience: Runtime Dev + description: | + Introduces `#[frame_support::runtime]` that can be attached to a mod to define a runtime. The items + in this mod can be attached to the following attributes to define the key components of the runtime. + 1. `#[runtime::runtime]` attached to a struct defines the main runtime + 2. `#[runtime::derive]` attached to the runtime struct defines the types generated by the runtime + 3. `#[runtime::pallet_index]` must be attached to a pallet to define its index + 4. `#[runtime::disable_call]` can be optionally attached to a pallet to disable its calls + 5. `#[runtime::disable_unsigned]` can be optionally attached to a pallet to disable unsigned calls + 6. A pallet instance can be defined as `TemplateModule: pallet_template` + An optional attribute can be defined as `#[frame_support::runtime(legacy_ordering)]` to ensure that + the order of hooks is same as the order of pallets (and not based on the pallet_index). This is to support + legacy runtimes and should be avoided for new ones. + +migrations: + db: [] + + runtime: [] + +crates: + - name: frame-support + - name: frame-support-procedural + +host_functions: [] diff --git a/substrate/bin/node/runtime/Cargo.toml b/substrate/bin/node/runtime/Cargo.toml index bdef42474d0..09c8fb4ed3d 100644 --- a/substrate/bin/node/runtime/Cargo.toml +++ b/substrate/bin/node/runtime/Cargo.toml @@ -58,7 +58,7 @@ sp-io = { path = "../../../primitives/io", default-features = false } frame-executive = { path = "../../../frame/executive", default-features = false } frame-benchmarking = { path = "../../../frame/benchmarking", default-features = false } frame-benchmarking-pallet-pov = { path = "../../../frame/benchmarking/pov", default-features = false } -frame-support = { path = "../../../frame/support", default-features = false, features = ["tuples-96"] } +frame-support = { path = "../../../frame/support", default-features = false, features = ["experimental", "tuples-96"] } frame-system = { path = "../../../frame/system", default-features = false } frame-system-benchmarking = { path = "../../../frame/system/benchmarking", default-features = false, optional = true } frame-election-provider-support = { path = "../../../frame/election-provider-support", default-features = false } diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 18ce13cff80..96611f5a144 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -28,7 +28,7 @@ use frame_election_provider_support::{ onchain, BalancingConfig, ElectionDataProvider, SequentialPhragmen, VoteWeight, }; use frame_support::{ - construct_runtime, derive_impl, + derive_impl, dispatch::DispatchClass, dynamic_params::{dynamic_pallet_params, dynamic_params}, genesis_builder_helper::{build_config, create_default_config}, @@ -2196,92 +2196,260 @@ impl pallet_parameters::Config for Runtime { type WeightInfo = (); } -construct_runtime!( - pub enum Runtime { - System: frame_system, - Utility: pallet_utility, - Babe: pallet_babe, - Timestamp: pallet_timestamp, - // Authorship must be before session in order to note author in the correct session and era - // for im-online and staking. - Authorship: pallet_authorship, - Indices: pallet_indices, - Balances: pallet_balances, - TransactionPayment: pallet_transaction_payment, - AssetTxPayment: pallet_asset_tx_payment, - AssetConversionTxPayment: pallet_asset_conversion_tx_payment, - ElectionProviderMultiPhase: pallet_election_provider_multi_phase, - Staking: pallet_staking, - Session: pallet_session, - Democracy: pallet_democracy, - Council: pallet_collective::, - TechnicalCommittee: pallet_collective::, - Elections: pallet_elections_phragmen, - TechnicalMembership: pallet_membership::, - Grandpa: pallet_grandpa, - Treasury: pallet_treasury, - AssetRate: pallet_asset_rate, - Contracts: pallet_contracts, - Sudo: pallet_sudo, - ImOnline: pallet_im_online, - AuthorityDiscovery: pallet_authority_discovery, - Offences: pallet_offences, - Historical: pallet_session_historical, - RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip, - Identity: pallet_identity, - Society: pallet_society, - Recovery: pallet_recovery, - Vesting: pallet_vesting, - Scheduler: pallet_scheduler, - Glutton: pallet_glutton, - Preimage: pallet_preimage, - Proxy: pallet_proxy, - Multisig: pallet_multisig, - Bounties: pallet_bounties, - Tips: pallet_tips, - Assets: pallet_assets::, - PoolAssets: pallet_assets::, - Beefy: pallet_beefy, - // MMR leaf construction must be after session in order to have a leaf's next_auth_set - // refer to block. See issue polkadot-fellows/runtimes#160 for details. - Mmr: pallet_mmr, - MmrLeaf: pallet_beefy_mmr, - Lottery: pallet_lottery, - Nis: pallet_nis, - Uniques: pallet_uniques, - Nfts: pallet_nfts, - NftFractionalization: pallet_nft_fractionalization, - Salary: pallet_salary, - CoreFellowship: pallet_core_fellowship, - TransactionStorage: pallet_transaction_storage, - VoterList: pallet_bags_list::, - StateTrieMigration: pallet_state_trie_migration, - ChildBounties: pallet_child_bounties, - Referenda: pallet_referenda, - Remark: pallet_remark, - RootTesting: pallet_root_testing, - ConvictionVoting: pallet_conviction_voting, - Whitelist: pallet_whitelist, - AllianceMotion: pallet_collective::, - Alliance: pallet_alliance, - NominationPools: pallet_nomination_pools, - RankedPolls: pallet_referenda::, - RankedCollective: pallet_ranked_collective, - AssetConversion: pallet_asset_conversion, - FastUnstake: pallet_fast_unstake, - MessageQueue: pallet_message_queue, - Pov: frame_benchmarking_pallet_pov, - TxPause: pallet_tx_pause, - SafeMode: pallet_safe_mode, - Statement: pallet_statement, - MultiBlockMigrations: pallet_migrations, - Broker: pallet_broker, - TasksExample: pallet_example_tasks, - Mixnet: pallet_mixnet, - Parameters: pallet_parameters, - SkipFeelessPayment: pallet_skip_feeless_payment, - } -); +#[frame_support::runtime] +mod runtime { + #[runtime::runtime] + #[runtime::derive( + RuntimeCall, + RuntimeEvent, + RuntimeError, + RuntimeOrigin, + RuntimeFreezeReason, + RuntimeHoldReason, + RuntimeSlashReason, + RuntimeLockId, + RuntimeTask + )] + pub struct Runtime; + + #[runtime::pallet_index(0)] + pub type System = frame_system; + + #[runtime::pallet_index(1)] + pub type Utility = pallet_utility; + + #[runtime::pallet_index(2)] + pub type Babe = pallet_babe; + + #[runtime::pallet_index(3)] + pub type Timestamp = pallet_timestamp; + + // Authorship must be before session in order to note author in the correct session and era + // for im-online and staking. + #[runtime::pallet_index(4)] + pub type Authorship = pallet_authorship; + + #[runtime::pallet_index(5)] + pub type Indices = pallet_indices; + + #[runtime::pallet_index(6)] + pub type Balances = pallet_balances; + + #[runtime::pallet_index(7)] + pub type TransactionPayment = pallet_transaction_payment; + + #[runtime::pallet_index(8)] + pub type AssetTxPayment = pallet_asset_tx_payment; + + #[runtime::pallet_index(9)] + pub type AssetConversionTxPayment = pallet_asset_conversion_tx_payment; + + #[runtime::pallet_index(10)] + pub type ElectionProviderMultiPhase = pallet_election_provider_multi_phase; + + #[runtime::pallet_index(11)] + pub type Staking = pallet_staking; + + #[runtime::pallet_index(12)] + pub type Session = pallet_session; + + #[runtime::pallet_index(13)] + pub type Democracy = pallet_democracy; + + #[runtime::pallet_index(14)] + pub type Council = pallet_collective; + + #[runtime::pallet_index(15)] + pub type TechnicalCommittee = pallet_collective; + + #[runtime::pallet_index(16)] + pub type Elections = pallet_elections_phragmen; + + #[runtime::pallet_index(17)] + pub type TechnicalMembership = pallet_membership; + + #[runtime::pallet_index(18)] + pub type Grandpa = pallet_grandpa; + + #[runtime::pallet_index(19)] + pub type Treasury = pallet_treasury; + + #[runtime::pallet_index(20)] + pub type AssetRate = pallet_asset_rate; + + #[runtime::pallet_index(21)] + pub type Contracts = pallet_contracts; + + #[runtime::pallet_index(22)] + pub type Sudo = pallet_sudo; + + #[runtime::pallet_index(23)] + pub type ImOnline = pallet_im_online; + + #[runtime::pallet_index(24)] + pub type AuthorityDiscovery = pallet_authority_discovery; + + #[runtime::pallet_index(25)] + pub type Offences = pallet_offences; + + #[runtime::pallet_index(26)] + pub type Historical = pallet_session_historical; + + #[runtime::pallet_index(27)] + pub type RandomnessCollectiveFlip = pallet_insecure_randomness_collective_flip; + + #[runtime::pallet_index(28)] + pub type Identity = pallet_identity; + + #[runtime::pallet_index(29)] + pub type Society = pallet_society; + + #[runtime::pallet_index(30)] + pub type Recovery = pallet_recovery; + + #[runtime::pallet_index(31)] + pub type Vesting = pallet_vesting; + + #[runtime::pallet_index(32)] + pub type Scheduler = pallet_scheduler; + + #[runtime::pallet_index(33)] + pub type Glutton = pallet_glutton; + + #[runtime::pallet_index(34)] + pub type Preimage = pallet_preimage; + + #[runtime::pallet_index(35)] + pub type Proxy = pallet_proxy; + + #[runtime::pallet_index(36)] + pub type Multisig = pallet_multisig; + + #[runtime::pallet_index(37)] + pub type Bounties = pallet_bounties; + + #[runtime::pallet_index(38)] + pub type Tips = pallet_tips; + + #[runtime::pallet_index(39)] + pub type Assets = pallet_assets; + + #[runtime::pallet_index(40)] + pub type PoolAssets = pallet_assets; + + #[runtime::pallet_index(41)] + pub type Beefy = pallet_beefy; + + // MMR leaf construction must be after session in order to have a leaf's next_auth_set + // refer to block. See issue polkadot-fellows/runtimes#160 for details. + #[runtime::pallet_index(42)] + pub type Mmr = pallet_mmr; + + #[runtime::pallet_index(43)] + pub type MmrLeaf = pallet_beefy_mmr; + + #[runtime::pallet_index(44)] + pub type Lottery = pallet_lottery; + + #[runtime::pallet_index(45)] + pub type Nis = pallet_nis; + + #[runtime::pallet_index(46)] + pub type Uniques = pallet_uniques; + + #[runtime::pallet_index(47)] + pub type Nfts = pallet_nfts; + + #[runtime::pallet_index(48)] + pub type NftFractionalization = pallet_nft_fractionalization; + + #[runtime::pallet_index(49)] + pub type Salary = pallet_salary; + + #[runtime::pallet_index(50)] + pub type CoreFellowship = pallet_core_fellowship; + + #[runtime::pallet_index(51)] + pub type TransactionStorage = pallet_transaction_storage; + + #[runtime::pallet_index(52)] + pub type VoterList = pallet_bags_list; + + #[runtime::pallet_index(53)] + pub type StateTrieMigration = pallet_state_trie_migration; + + #[runtime::pallet_index(54)] + pub type ChildBounties = pallet_child_bounties; + + #[runtime::pallet_index(55)] + pub type Referenda = pallet_referenda; + + #[runtime::pallet_index(56)] + pub type Remark = pallet_remark; + + #[runtime::pallet_index(57)] + pub type RootTesting = pallet_root_testing; + + #[runtime::pallet_index(58)] + pub type ConvictionVoting = pallet_conviction_voting; + + #[runtime::pallet_index(59)] + pub type Whitelist = pallet_whitelist; + + #[runtime::pallet_index(60)] + pub type AllianceMotion = pallet_collective; + + #[runtime::pallet_index(61)] + pub type Alliance = pallet_alliance; + + #[runtime::pallet_index(62)] + pub type NominationPools = pallet_nomination_pools; + + #[runtime::pallet_index(63)] + pub type RankedPolls = pallet_referenda; + + #[runtime::pallet_index(64)] + pub type RankedCollective = pallet_ranked_collective; + + #[runtime::pallet_index(65)] + pub type AssetConversion = pallet_asset_conversion; + + #[runtime::pallet_index(66)] + pub type FastUnstake = pallet_fast_unstake; + + #[runtime::pallet_index(67)] + pub type MessageQueue = pallet_message_queue; + + #[runtime::pallet_index(68)] + pub type Pov = frame_benchmarking_pallet_pov; + + #[runtime::pallet_index(69)] + pub type TxPause = pallet_tx_pause; + + #[runtime::pallet_index(70)] + pub type SafeMode = pallet_safe_mode; + + #[runtime::pallet_index(71)] + pub type Statement = pallet_statement; + + #[runtime::pallet_index(72)] + pub type MultiBlockMigrations = pallet_migrations; + + #[runtime::pallet_index(73)] + pub type Broker = pallet_broker; + + #[runtime::pallet_index(74)] + pub type TasksExample = pallet_example_tasks; + + #[runtime::pallet_index(75)] + pub type Mixnet = pallet_mixnet; + + #[runtime::pallet_index(76)] + pub type Parameters = pallet_parameters; + + #[runtime::pallet_index(77)] + pub type SkipFeelessPayment = pallet_skip_feeless_payment; +} /// The address format for describing accounts. pub type Address = sp_runtime::MultiAddress; diff --git a/substrate/frame/support/Cargo.toml b/substrate/frame/support/Cargo.toml index 113af41751e..be60068f122 100644 --- a/substrate/frame/support/Cargo.toml +++ b/substrate/frame/support/Cargo.toml @@ -109,7 +109,9 @@ try-runtime = [ "sp-debug-derive/force-debug", "sp-runtime/try-runtime", ] -experimental = [] +experimental = [ + "frame-support-procedural/experimental", +] # By default some types have documentation, `no-metadata-docs` allows to reduce the documentation # in the metadata. no-metadata-docs = [ diff --git a/substrate/frame/support/procedural/Cargo.toml b/substrate/frame/support/procedural/Cargo.toml index 85947503802..dd0688f2ad0 100644 --- a/substrate/frame/support/procedural/Cargo.toml +++ b/substrate/frame/support/procedural/Cargo.toml @@ -38,6 +38,7 @@ regex = "1" default = ["std"] std = ["sp-crypto-hashing/std"] no-metadata-docs = [] +experimental = [] # Generate impl-trait for tuples with the given number of tuples. Will be needed as the number of # pallets in a runtime grows. Does increase the compile time! tuples-96 = [] diff --git a/substrate/frame/support/procedural/src/construct_runtime/mod.rs b/substrate/frame/support/procedural/src/construct_runtime/mod.rs index 6e95fdf116a..1937dfa9ca4 100644 --- a/substrate/frame/support/procedural/src/construct_runtime/mod.rs +++ b/substrate/frame/support/procedural/src/construct_runtime/mod.rs @@ -208,8 +208,8 @@ //! This macro returns the ` :: expanded { Error }` list of additional parts we would like to //! expose. -mod expand; -mod parse; +pub(crate) mod expand; +pub(crate) mod parse; use crate::pallet::parse::helper::two128_str; use cfg_expr::Predicate; @@ -515,7 +515,7 @@ fn construct_runtime_final_expansion( Ok(res) } -fn decl_all_pallets<'a>( +pub(crate) fn decl_all_pallets<'a>( runtime: &'a Ident, pallet_declarations: impl Iterator, features: &HashSet<&str>, @@ -624,7 +624,8 @@ fn decl_all_pallets<'a>( #( #all_pallets_without_system )* ) } -fn decl_pallet_runtime_setup( + +pub(crate) fn decl_pallet_runtime_setup( runtime: &Ident, pallet_declarations: &[Pallet], scrate: &TokenStream2, @@ -730,7 +731,7 @@ fn decl_pallet_runtime_setup( ) } -fn decl_integrity_test(scrate: &TokenStream2) -> TokenStream2 { +pub(crate) fn decl_integrity_test(scrate: &TokenStream2) -> TokenStream2 { quote!( #[cfg(test)] mod __construct_runtime_integrity_test { @@ -745,7 +746,7 @@ fn decl_integrity_test(scrate: &TokenStream2) -> TokenStream2 { ) } -fn decl_static_assertions( +pub(crate) fn decl_static_assertions( runtime: &Ident, pallet_decls: &[Pallet], scrate: &TokenStream2, @@ -776,7 +777,7 @@ fn decl_static_assertions( } } -fn check_pallet_number(input: TokenStream2, pallet_num: usize) -> Result<()> { +pub(crate) fn check_pallet_number(input: TokenStream2, pallet_num: usize) -> Result<()> { let max_pallet_num = { if cfg!(feature = "tuples-96") { 96 diff --git a/substrate/frame/support/procedural/src/lib.rs b/substrate/frame/support/procedural/src/lib.rs index 89e39a5c9bb..dee6d522d25 100644 --- a/substrate/frame/support/procedural/src/lib.rs +++ b/substrate/frame/support/procedural/src/lib.rs @@ -31,6 +31,7 @@ mod match_and_insert; mod no_bound; mod pallet; mod pallet_error; +mod runtime; mod storage_alias; mod transactional; mod tt_macro; @@ -1220,6 +1221,73 @@ pub fn import_section(attr: TokenStream, tokens: TokenStream) -> TokenStream { .into() } +/// Construct a runtime, with the given name and the given pallets. +/// +/// # Example: +/// +/// ```ignore +/// #[frame_support::runtime] +/// mod runtime { +/// // The main runtime +/// #[runtime::runtime] +/// // Runtime Types to be generated +/// #[runtime::derive( +/// RuntimeCall, +/// RuntimeEvent, +/// RuntimeError, +/// RuntimeOrigin, +/// RuntimeFreezeReason, +/// RuntimeHoldReason, +/// RuntimeSlashReason, +/// RuntimeLockId, +/// RuntimeTask, +/// )] +/// pub struct Runtime; +/// +/// #[runtime::pallet_index(0)] +/// pub type System = frame_system; +/// +/// #[runtime::pallet_index(1)] +/// pub type Test = path::to::test; +/// +/// // Pallet with instance. +/// #[runtime::pallet_index(2)] +/// pub type Test2_Instance1 = test2; +/// +/// // Pallet with calls disabled. +/// #[runtime::pallet_index(3)] +/// #[runtime::disable_call] +/// pub type Test3 = test3; +/// +/// // Pallet with unsigned extrinsics disabled. +/// #[runtime::pallet_index(4)] +/// #[runtime::disable_unsigned] +/// pub type Test4 = test4; +/// } +/// ``` +/// +/// # Legacy Ordering +/// +/// An optional attribute can be defined as #[frame_support::runtime(legacy_ordering)] to +/// ensure that the order of hooks is same as the order of pallets (and not based on the +/// pallet_index). This is to support legacy runtimes and should be avoided for new ones. +/// +/// # Note +/// +/// The population of the genesis storage depends on the order of pallets. So, if one of your +/// pallets depends on another pallet, the pallet that is depended upon needs to come before +/// the pallet depending on it. +/// +/// # Type definitions +/// +/// * The macro generates a type alias for each pallet to their `Pallet`. E.g. `type System = +/// frame_system::Pallet` +#[cfg(feature = "experimental")] +#[proc_macro_attribute] +pub fn runtime(attr: TokenStream, item: TokenStream) -> TokenStream { + runtime::runtime(attr, item) +} + /// Mark a module that contains dynamic parameters. /// /// See the `pallet_parameters` for a full example. diff --git a/substrate/frame/support/procedural/src/pallet/expand/tt_default_parts.rs b/substrate/frame/support/procedural/src/pallet/expand/tt_default_parts.rs index 7cc1415dfdd..99364aaa96c 100644 --- a/substrate/frame/support/procedural/src/pallet/expand/tt_default_parts.rs +++ b/substrate/frame/support/procedural/src/pallet/expand/tt_default_parts.rs @@ -28,6 +28,8 @@ pub fn expand_tt_default_parts(def: &mut Def) -> proc_macro2::TokenStream { syn::Ident::new(&format!("__tt_default_parts_{}", count), def.item.span()); let extra_parts_unique_id = syn::Ident::new(&format!("__tt_extra_parts_{}", count), def.item.span()); + let default_parts_unique_id_v2 = + syn::Ident::new(&format!("__tt_default_parts_v2_{}", count), def.item.span()); let call_part = def.call.as_ref().map(|_| quote::quote!(Call,)); @@ -81,6 +83,58 @@ pub fn expand_tt_default_parts(def: &mut Def) -> proc_macro2::TokenStream { .any(|c| matches!(c.composite_keyword, CompositeKeyword::SlashReason(_))) .then_some(quote::quote!(SlashReason,)); + let call_part_v2 = def.call.as_ref().map(|_| quote::quote!(+ Call)); + + let task_part_v2 = def.task_enum.as_ref().map(|_| quote::quote!(+ Task)); + + let storage_part_v2 = (!def.storages.is_empty()).then(|| quote::quote!(+ Storage)); + + let event_part_v2 = def.event.as_ref().map(|event| { + let gen = event.gen_kind.is_generic().then(|| quote::quote!()); + quote::quote!(+ Event #gen) + }); + + let error_part_v2 = def.error.as_ref().map(|_| quote::quote!(+ Error)); + + let origin_part_v2 = def.origin.as_ref().map(|origin| { + let gen = origin.is_generic.then(|| quote::quote!()); + quote::quote!(+ Origin #gen) + }); + + let config_part_v2 = def.genesis_config.as_ref().map(|genesis_config| { + let gen = genesis_config.gen_kind.is_generic().then(|| quote::quote!()); + quote::quote!(+ Config #gen) + }); + + let inherent_part_v2 = def.inherent.as_ref().map(|_| quote::quote!(+ Inherent)); + + let validate_unsigned_part_v2 = + def.validate_unsigned.as_ref().map(|_| quote::quote!(+ ValidateUnsigned)); + + let freeze_reason_part_v2 = def + .composites + .iter() + .any(|c| matches!(c.composite_keyword, CompositeKeyword::FreezeReason(_))) + .then_some(quote::quote!(+ FreezeReason)); + + let hold_reason_part_v2 = def + .composites + .iter() + .any(|c| matches!(c.composite_keyword, CompositeKeyword::HoldReason(_))) + .then_some(quote::quote!(+ HoldReason)); + + let lock_id_part_v2 = def + .composites + .iter() + .any(|c| matches!(c.composite_keyword, CompositeKeyword::LockId(_))) + .then_some(quote::quote!(+ LockId)); + + let slash_reason_part_v2 = def + .composites + .iter() + .any(|c| matches!(c.composite_keyword, CompositeKeyword::SlashReason(_))) + .then_some(quote::quote!(+ SlashReason)); + quote::quote!( // This macro follows the conventions as laid out by the `tt-call` crate. It does not // accept any arguments and simply returns the pallet parts, separated by commas, then @@ -138,5 +192,25 @@ pub fn expand_tt_default_parts(def: &mut Def) -> proc_macro2::TokenStream { } pub use #extra_parts_unique_id as tt_extra_parts; + + #[macro_export] + #[doc(hidden)] + macro_rules! #default_parts_unique_id_v2 { + { + $caller:tt + frame_support = [{ $($frame_support:ident)::* }] + } => { + $($frame_support)*::__private::tt_return! { + $caller + tokens = [{ + + Pallet #call_part_v2 #storage_part_v2 #event_part_v2 #error_part_v2 #origin_part_v2 #config_part_v2 + #inherent_part_v2 #validate_unsigned_part_v2 #freeze_reason_part_v2 #task_part_v2 + #hold_reason_part_v2 #lock_id_part_v2 #slash_reason_part_v2 + }] + } + }; + } + + pub use #default_parts_unique_id_v2 as tt_default_parts_v2; ) } diff --git a/substrate/frame/support/procedural/src/pallet/parse/helper.rs b/substrate/frame/support/procedural/src/pallet/parse/helper.rs index 538226a8745..3187c9139c8 100644 --- a/substrate/frame/support/procedural/src/pallet/parse/helper.rs +++ b/substrate/frame/support/procedural/src/pallet/parse/helper.rs @@ -148,6 +148,12 @@ impl MutItemAttrs for syn::ImplItemFn { } } +impl MutItemAttrs for syn::ItemType { + fn mut_item_attrs(&mut self) -> Option<&mut Vec> { + Some(&mut self.attrs) + } +} + /// Parse for `()` struct Unit; impl syn::parse::Parse for Unit { diff --git a/substrate/frame/support/procedural/src/runtime/expand/mod.rs b/substrate/frame/support/procedural/src/runtime/expand/mod.rs new file mode 100644 index 00000000000..93c88fce94b --- /dev/null +++ b/substrate/frame/support/procedural/src/runtime/expand/mod.rs @@ -0,0 +1,320 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use super::parse::runtime_types::RuntimeType; +use crate::{ + construct_runtime::{ + check_pallet_number, decl_all_pallets, decl_integrity_test, decl_pallet_runtime_setup, + decl_static_assertions, expand, + }, + runtime::{ + parse::{ + AllPalletsDeclaration, ExplicitAllPalletsDeclaration, ImplicitAllPalletsDeclaration, + }, + Def, + }, +}; +use cfg_expr::Predicate; +use frame_support_procedural_tools::{ + generate_access_from_frame_or_crate, generate_crate_access, generate_hidden_includes, +}; +use proc_macro2::TokenStream as TokenStream2; +use quote::quote; +use std::collections::HashSet; +use syn::{Ident, Result}; + +/// The fixed name of the system pallet. +const SYSTEM_PALLET_NAME: &str = "System"; + +pub fn expand(def: Def, legacy_ordering: bool) -> TokenStream2 { + let input = def.input; + + let (check_pallet_number_res, res) = match def.pallets { + AllPalletsDeclaration::Implicit(ref decl) => ( + check_pallet_number(input.clone(), decl.pallet_count), + construct_runtime_implicit_to_explicit(input.into(), decl.clone(), legacy_ordering), + ), + AllPalletsDeclaration::Explicit(ref decl) => ( + check_pallet_number(input, decl.pallets.len()), + construct_runtime_final_expansion( + def.runtime_struct.ident.clone(), + decl.clone(), + def.runtime_types.clone(), + legacy_ordering, + ), + ), + }; + + let res = res.unwrap_or_else(|e| e.to_compile_error()); + + // We want to provide better error messages to the user and thus, handle the error here + // separately. If there is an error, we print the error and still generate all of the code to + // get in overall less errors for the user. + let res = if let Err(error) = check_pallet_number_res { + let error = error.to_compile_error(); + + quote! { + #error + + #res + } + } else { + res + }; + + let res = expander::Expander::new("construct_runtime") + .dry(std::env::var("FRAME_EXPAND").is_err()) + .verbose(true) + .write_to_out_dir(res) + .expect("Does not fail because of IO in OUT_DIR; qed"); + + res.into() +} + +fn construct_runtime_implicit_to_explicit( + input: TokenStream2, + definition: ImplicitAllPalletsDeclaration, + legacy_ordering: bool, +) -> Result { + let frame_support = generate_access_from_frame_or_crate("frame-support")?; + let attr = if legacy_ordering { quote!((legacy_ordering)) } else { quote!() }; + let mut expansion = quote::quote!( + #[frame_support::runtime #attr] + #input + ); + for pallet in definition.pallet_decls.iter() { + let pallet_path = &pallet.path; + let pallet_name = &pallet.name; + let pallet_instance = pallet.instance.as_ref().map(|instance| quote::quote!(<#instance>)); + expansion = quote::quote!( + #frame_support::__private::tt_call! { + macro = [{ #pallet_path::tt_default_parts_v2 }] + frame_support = [{ #frame_support }] + ~~> #frame_support::match_and_insert! { + target = [{ #expansion }] + pattern = [{ #pallet_name = #pallet_path #pallet_instance }] + } + } + ); + } + + Ok(expansion) +} + +fn construct_runtime_final_expansion( + name: Ident, + definition: ExplicitAllPalletsDeclaration, + runtime_types: Vec, + legacy_ordering: bool, +) -> Result { + let ExplicitAllPalletsDeclaration { mut pallets, name: pallets_name } = definition; + + if !legacy_ordering { + // Ensure that order of hooks is based on the pallet index + pallets.sort_by_key(|p| p.index); + } + + let system_pallet = + pallets.iter().find(|decl| decl.name == SYSTEM_PALLET_NAME).ok_or_else(|| { + syn::Error::new( + pallets_name.span(), + "`System` pallet declaration is missing. \ + Please add this line: `pub type System = frame_system;`", + ) + })?; + if !system_pallet.cfg_pattern.is_empty() { + return Err(syn::Error::new( + system_pallet.name.span(), + "`System` pallet declaration is feature gated, please remove any `#[cfg]` attributes", + )) + } + + let features = pallets + .iter() + .filter_map(|decl| { + (!decl.cfg_pattern.is_empty()).then(|| { + decl.cfg_pattern.iter().flat_map(|attr| { + attr.predicates().filter_map(|pred| match pred { + Predicate::Feature(feat) => Some(feat), + Predicate::Test => Some("test"), + _ => None, + }) + }) + }) + }) + .flatten() + .collect::>(); + + let hidden_crate_name = "construct_runtime"; + let scrate = generate_crate_access(hidden_crate_name, "frame-support"); + let scrate_decl = generate_hidden_includes(hidden_crate_name, "frame-support"); + + let frame_system = generate_access_from_frame_or_crate("frame-system")?; + let block = quote!(<#name as #frame_system::Config>::Block); + let unchecked_extrinsic = quote!(<#block as #scrate::sp_runtime::traits::Block>::Extrinsic); + + let mut dispatch = None; + let mut outer_event = None; + let mut outer_error = None; + let mut outer_origin = None; + let mut freeze_reason = None; + let mut hold_reason = None; + let mut slash_reason = None; + let mut lock_id = None; + let mut task = None; + + for runtime_type in runtime_types.iter() { + match runtime_type { + RuntimeType::RuntimeCall(_) => { + dispatch = + Some(expand::expand_outer_dispatch(&name, system_pallet, &pallets, &scrate)); + }, + RuntimeType::RuntimeEvent(_) => { + outer_event = Some(expand::expand_outer_enum( + &name, + &pallets, + &scrate, + expand::OuterEnumType::Event, + )?); + }, + RuntimeType::RuntimeError(_) => { + outer_error = Some(expand::expand_outer_enum( + &name, + &pallets, + &scrate, + expand::OuterEnumType::Error, + )?); + }, + RuntimeType::RuntimeOrigin(_) => { + outer_origin = + Some(expand::expand_outer_origin(&name, system_pallet, &pallets, &scrate)?); + }, + RuntimeType::RuntimeFreezeReason(_) => { + freeze_reason = Some(expand::expand_outer_freeze_reason(&pallets, &scrate)); + }, + RuntimeType::RuntimeHoldReason(_) => { + hold_reason = Some(expand::expand_outer_hold_reason(&pallets, &scrate)); + }, + RuntimeType::RuntimeSlashReason(_) => { + slash_reason = Some(expand::expand_outer_slash_reason(&pallets, &scrate)); + }, + RuntimeType::RuntimeLockId(_) => { + lock_id = Some(expand::expand_outer_lock_id(&pallets, &scrate)); + }, + RuntimeType::RuntimeTask(_) => { + task = Some(expand::expand_outer_task(&name, &pallets, &scrate)); + }, + } + } + + let all_pallets = decl_all_pallets(&name, pallets.iter(), &features); + let pallet_to_index = decl_pallet_runtime_setup(&name, &pallets, &scrate); + + let metadata = expand::expand_runtime_metadata( + &name, + &pallets, + &scrate, + &unchecked_extrinsic, + &system_pallet.path, + ); + let outer_config = expand::expand_outer_config(&name, &pallets, &scrate); + let inherent = + expand::expand_outer_inherent(&name, &block, &unchecked_extrinsic, &pallets, &scrate); + let validate_unsigned = expand::expand_outer_validate_unsigned(&name, &pallets, &scrate); + let integrity_test = decl_integrity_test(&scrate); + let static_assertions = decl_static_assertions(&name, &pallets, &scrate); + + let res = quote!( + #scrate_decl + + // Prevent UncheckedExtrinsic to print unused warning. + const _: () = { + #[allow(unused)] + type __hidden_use_of_unchecked_extrinsic = #unchecked_extrinsic; + }; + + #[derive( + Clone, Copy, PartialEq, Eq, #scrate::sp_runtime::RuntimeDebug, + #scrate::__private::scale_info::TypeInfo + )] + pub struct #name; + impl #scrate::sp_runtime::traits::GetRuntimeBlockType for #name { + type RuntimeBlock = #block; + } + + // Each runtime must expose the `runtime_metadata()` to fetch the runtime API metadata. + // The function is implemented by calling `impl_runtime_apis!`. + // + // However, the `runtime` may be used without calling `impl_runtime_apis!`. + // Rely on the `Deref` trait to differentiate between a runtime that implements + // APIs (by macro impl_runtime_apis!) and a runtime that is simply created (by macro runtime). + // + // Both `InternalConstructRuntime` and `InternalImplRuntimeApis` expose a `runtime_metadata()` function. + // `InternalConstructRuntime` is implemented by the `runtime` for Runtime references (`& Runtime`), + // while `InternalImplRuntimeApis` is implemented by the `impl_runtime_apis!` for Runtime (`Runtime`). + // + // Therefore, the `Deref` trait will resolve the `runtime_metadata` from `impl_runtime_apis!` + // when both macros are called; and will resolve an empty `runtime_metadata` when only the `runtime` + // is used. + + #[doc(hidden)] + trait InternalConstructRuntime { + #[inline(always)] + fn runtime_metadata(&self) -> #scrate::__private::sp_std::vec::Vec<#scrate::__private::metadata_ir::RuntimeApiMetadataIR> { + Default::default() + } + } + #[doc(hidden)] + impl InternalConstructRuntime for &#name {} + + #outer_event + + #outer_error + + #outer_origin + + #all_pallets + + #pallet_to_index + + #dispatch + + #task + + #metadata + + #outer_config + + #inherent + + #validate_unsigned + + #freeze_reason + + #hold_reason + + #lock_id + + #slash_reason + + #integrity_test + + #static_assertions + ); + + Ok(res) +} diff --git a/substrate/frame/support/procedural/src/runtime/mod.rs b/substrate/frame/support/procedural/src/runtime/mod.rs new file mode 100644 index 00000000000..aaae579eb08 --- /dev/null +++ b/substrate/frame/support/procedural/src/runtime/mod.rs @@ -0,0 +1,236 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Implementation of `runtime`. +//! +//! `runtime` implementation is recursive and can generate code which will call itself +//! in order to get all the pallet parts for each pallet. +//! +//! Pallets can define their parts: +//! - Implicitly: `pub type System = frame_system;` +//! - Explicitly: `pub type System = frame_system + Pallet + Call;` +//! +//! The `runtime` transitions from the implicit definition to the explicit one. +//! From the explicit state, Substrate expands the pallets with additional information +//! that is to be included in the runtime metadata. +//! +//! Pallets must provide the `tt_default_parts_v2` macro for these transitions. +//! These are automatically implemented by the `#[pallet::pallet]` macro. +//! +//! This macro also generates the following enums for ease of decoding if the respective type +//! is defined inside `#[runtime::derive]`: +//! - `enum RuntimeCall`: This type contains the information needed to decode extrinsics. +//! - `enum RuntimeEvent`: This type contains the information needed to decode events. +//! - `enum RuntimeError`: While this cannot be used directly to decode `sp_runtime::DispatchError` +//! from the chain, it contains the information needed to decode the +//! `sp_runtime::DispatchError::Module`. +//! +//! # State Transitions +//! +//! ```ignore +//! +----------+ +//! | Implicit | +//! +----------+ +//! | +//! v +//! +----------+ +//! | Explicit | +//! +----------+ +//! ``` +//! +//! The `runtime` macro transforms the implicit declaration of each pallet +//! `System: frame_system` to an explicit one `System: frame_system + Pallet + Call` using the +//! `tt_default_parts_v2` macro. +//! +//! The `tt_default_parts_v2` macro exposes a plus separated list of pallet parts. For example, the +//! `Event` part is exposed only if the pallet implements an event via `#[pallet::event]` macro. +//! The tokens generated by this macro are `+ Pallet + Call` for our example. +//! +//! The `match_and_insert` macro takes in 3 arguments: +//! - target: This is the `TokenStream` that contains the `runtime` macro. +//! - pattern: The pattern to match against in the target stream. +//! - tokens: The tokens to added after the pattern match. +//! +//! The `runtime` macro uses the `tt_call` to get the default pallet parts via +//! the `tt_default_parts_v2` macro defined by each pallet. The pallet parts are then returned as +//! input to the `match_and_replace` macro. +//! The `match_and_replace` then will modify the `runtime` to expand the implicit +//! definition to the explicit one. +//! +//! For example, +//! +//! ```ignore +//! #[frame_support::runtime] +//! mod runtime { +//! //... +//! +//! #[runtime::pallet_index(0)] +//! pub type System = frame_system; // Implicit definition of parts +//! +//! #[runtime::pallet_index(1)] +//! pub type Balances = pallet_balances; // Implicit definition of parts +//! } +//! ``` +//! This call has some implicit pallet parts, thus it will expand to: +//! ```ignore +//! frame_support::__private::tt_call! { +//! macro = [{ pallet_balances::tt_default_parts_v2 }] +//! ~~> frame_support::match_and_insert! { +//! target = [{ +//! frame_support::__private::tt_call! { +//! macro = [{ frame_system::tt_default_parts_v2 }] +//! ~~> frame_support::match_and_insert! { +//! target = [{ +//! #[frame_support::runtime] +//! mod runtime { +//! //... +//! +//! #[runtime::pallet_index(0)] +//! pub type System = frame_system; +//! +//! #[runtime::pallet_index(1)] +//! pub type Balances = pallet_balances; +//! } +//! }] +//! pattern = [{ System = frame_system }] +//! } +//! } +//! }] +//! pattern = [{ Balances = pallet_balances }] +//! } +//! } +//! ``` +//! `tt_default_parts_v2` must be defined. It returns the pallet parts inside some tokens, and +//! then `tt_call` will pipe the returned pallet parts into the input of `match_and_insert`. +//! Thus `match_and_insert` will initially receive the following inputs: +//! ```ignore +//! frame_support::match_and_insert! { +//! target = [{ +//! frame_support::match_and_insert! { +//! target = [{ +//! #[frame_support::runtime] +//! mod runtime { +//! //... +//! +//! #[runtime::pallet_index(0)] +//! pub type System = frame_system; +//! +//! #[runtime::pallet_index(1)] +//! pub type Balances = pallet_balances; +//! } +//! }] +//! pattern = [{ System = frame_system }] +//! tokens = [{ ::{+ Pallet + Call} }] +//! } +//! }] +//! pattern = [{ Balances = pallet_balances }] +//! tokens = [{ ::{+ Pallet + Call} }] +//! } +//! ``` +//! After dealing with `pallet_balances`, the inner `match_and_insert` will expand to: +//! ```ignore +//! frame_support::match_and_insert! { +//! target = [{ +//! #[frame_support::runtime] +//! mod runtime { +//! //... +//! +//! #[runtime::pallet_index(0)] +//! pub type System = frame_system; // Implicit definition of parts +//! +//! #[runtime::pallet_index(1)] +//! pub type Balances = pallet_balances + Pallet + Call; // Explicit definition of parts +//! } +//! }] +//! pattern = [{ System = frame_system }] +//! tokens = [{ ::{+ Pallet + Call} }] +//! } +//! ``` +//! +//! Which will then finally expand to the following: +//! ```ignore +//! #[frame_support::runtime] +//! mod runtime { +//! //... +//! +//! #[runtime::pallet_index(0)] +//! pub type System = frame_system + Pallet + Call; +//! +//! #[runtime::pallet_index(1)] +//! pub type Balances = pallet_balances + Pallet + Call; +//! } +//! ``` +//! +//! This call has no implicit pallet parts, thus it will expand to the runtime construction: +//! ```ignore +//! pub struct Runtime { ... } +//! pub struct Call { ... } +//! impl Call ... +//! pub enum Origin { ... } +//! ... +//! ``` +//! +//! Visualizing the entire flow of `#[frame_support::runtime]`, it would look like the following: +//! +//! ```ignore +//! +----------------------+ +------------------------+ +-------------------+ +//! | | | (defined in pallet) | | | +//! | runtime | --> | tt_default_parts_v2! | --> | match_and_insert! | +//! | w/ no pallet parts | | | | | +//! +----------------------+ +------------------------+ +-------------------+ +//! +//! +----------------------+ +//! | | +//! --> | runtime | +//! | w/ pallet parts | +//! +----------------------+ +//! ``` + +#![cfg(feature = "experimental")] + +pub use parse::Def; +use proc_macro::TokenStream; +use syn::spanned::Spanned; + +mod expand; +mod parse; + +mod keyword { + syn::custom_keyword!(legacy_ordering); +} + +pub fn runtime(attr: TokenStream, tokens: TokenStream) -> TokenStream { + let mut legacy_ordering = false; + if !attr.is_empty() { + if let Ok(_) = syn::parse::(attr.clone()) { + legacy_ordering = true; + } else { + let msg = "Invalid runtime macro call: unexpected attribute. Macro call must be \ + bare, such as `#[frame_support::runtime]` or `#[runtime]`, or must specify the \ + `legacy_ordering` attribute, such as `#[frame_support::runtime(legacy_ordering)]` or \ + #[runtime(legacy_ordering)]."; + let span = proc_macro2::TokenStream::from(attr).span(); + return syn::Error::new(span, msg).to_compile_error().into() + } + } + + let item = syn::parse_macro_input!(tokens as syn::ItemMod); + match parse::Def::try_from(item) { + Ok(def) => expand::expand(def, legacy_ordering).into(), + Err(e) => e.to_compile_error().into(), + } +} diff --git a/substrate/frame/support/procedural/src/runtime/parse/helper.rs b/substrate/frame/support/procedural/src/runtime/parse/helper.rs new file mode 100644 index 00000000000..f05395f9b7a --- /dev/null +++ b/substrate/frame/support/procedural/src/runtime/parse/helper.rs @@ -0,0 +1,37 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use crate::pallet::parse::helper::MutItemAttrs; +use quote::ToTokens; + +pub(crate) fn take_first_item_runtime_attr( + item: &mut impl MutItemAttrs, +) -> syn::Result> +where + Attr: syn::parse::Parse, +{ + let attrs = if let Some(attrs) = item.mut_item_attrs() { attrs } else { return Ok(None) }; + + if let Some(index) = attrs.iter().position(|attr| { + attr.path().segments.first().map_or(false, |segment| segment.ident == "runtime") + }) { + let runtime_attr = attrs.remove(index); + Ok(Some(syn::parse2(runtime_attr.into_token_stream())?)) + } else { + Ok(None) + } +} diff --git a/substrate/frame/support/procedural/src/runtime/parse/mod.rs b/substrate/frame/support/procedural/src/runtime/parse/mod.rs new file mode 100644 index 00000000000..893cb4726e2 --- /dev/null +++ b/substrate/frame/support/procedural/src/runtime/parse/mod.rs @@ -0,0 +1,266 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +pub mod helper; +pub mod pallet; +pub mod pallet_decl; +pub mod runtime_struct; +pub mod runtime_types; + +use crate::construct_runtime::parse::Pallet; +use pallet_decl::PalletDeclaration; +use proc_macro2::TokenStream as TokenStream2; +use quote::ToTokens; +use std::collections::HashMap; +use syn::{spanned::Spanned, Ident, Token}; + +use frame_support_procedural_tools::syn_ext as ext; +use runtime_types::RuntimeType; + +mod keyword { + use syn::custom_keyword; + + custom_keyword!(runtime); + custom_keyword!(derive); + custom_keyword!(pallet_index); + custom_keyword!(disable_call); + custom_keyword!(disable_unsigned); +} + +enum RuntimeAttr { + Runtime(proc_macro2::Span), + Derive(proc_macro2::Span, Vec), + PalletIndex(proc_macro2::Span, u8), + DisableCall(proc_macro2::Span), + DisableUnsigned(proc_macro2::Span), +} + +impl RuntimeAttr { + fn span(&self) -> proc_macro2::Span { + match self { + Self::Runtime(span) => *span, + Self::Derive(span, _) => *span, + Self::PalletIndex(span, _) => *span, + Self::DisableCall(span) => *span, + Self::DisableUnsigned(span) => *span, + } + } +} + +impl syn::parse::Parse for RuntimeAttr { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + let content; + syn::bracketed!(content in input); + content.parse::()?; + content.parse::()?; + + let lookahead = content.lookahead1(); + if lookahead.peek(keyword::runtime) { + Ok(RuntimeAttr::Runtime(content.parse::()?.span())) + } else if lookahead.peek(keyword::derive) { + let _ = content.parse::(); + let derive_content; + syn::parenthesized!(derive_content in content); + let runtime_types = + derive_content.parse::>()?; + let runtime_types = runtime_types.inner.into_iter().collect(); + Ok(RuntimeAttr::Derive(derive_content.span(), runtime_types)) + } else if lookahead.peek(keyword::pallet_index) { + let _ = content.parse::(); + let pallet_index_content; + syn::parenthesized!(pallet_index_content in content); + let pallet_index = pallet_index_content.parse::()?; + if !pallet_index.suffix().is_empty() { + let msg = "Number literal must not have a suffix"; + return Err(syn::Error::new(pallet_index.span(), msg)) + } + Ok(RuntimeAttr::PalletIndex(pallet_index.span(), pallet_index.base10_parse()?)) + } else if lookahead.peek(keyword::disable_call) { + Ok(RuntimeAttr::DisableCall(content.parse::()?.span())) + } else if lookahead.peek(keyword::disable_unsigned) { + Ok(RuntimeAttr::DisableUnsigned(content.parse::()?.span())) + } else { + Err(lookahead.error()) + } + } +} + +#[derive(Debug, Clone)] +pub enum AllPalletsDeclaration { + Implicit(ImplicitAllPalletsDeclaration), + Explicit(ExplicitAllPalletsDeclaration), +} + +/// Declaration of a runtime with some pallet with implicit declaration of parts. +#[derive(Debug, Clone)] +pub struct ImplicitAllPalletsDeclaration { + pub name: Ident, + pub pallet_decls: Vec, + pub pallet_count: usize, +} + +/// Declaration of a runtime with all pallet having explicit declaration of parts. +#[derive(Debug, Clone)] +pub struct ExplicitAllPalletsDeclaration { + pub name: Ident, + pub pallets: Vec, +} + +pub struct Def { + pub input: TokenStream2, + pub item: syn::ItemMod, + pub runtime_struct: runtime_struct::RuntimeStructDef, + pub pallets: AllPalletsDeclaration, + pub runtime_types: Vec, +} + +impl Def { + pub fn try_from(mut item: syn::ItemMod) -> syn::Result { + let input: TokenStream2 = item.to_token_stream().into(); + let item_span = item.span(); + let items = &mut item + .content + .as_mut() + .ok_or_else(|| { + let msg = "Invalid runtime definition, expected mod to be inlined."; + syn::Error::new(item_span, msg) + })? + .1; + + let mut runtime_struct = None; + let mut runtime_types = None; + + let mut indices = HashMap::new(); + let mut names = HashMap::new(); + + let mut pallet_decls = vec![]; + let mut pallets = vec![]; + + for item in items.iter_mut() { + let mut pallet_item = None; + let mut pallet_index = 0; + + let mut disable_call = false; + let mut disable_unsigned = false; + + while let Some(runtime_attr) = + helper::take_first_item_runtime_attr::(item)? + { + match runtime_attr { + RuntimeAttr::Runtime(span) if runtime_struct.is_none() => { + let p = runtime_struct::RuntimeStructDef::try_from(span, item)?; + runtime_struct = Some(p); + }, + RuntimeAttr::Derive(_, types) if runtime_types.is_none() => { + runtime_types = Some(types); + }, + RuntimeAttr::PalletIndex(span, index) => { + pallet_index = index; + pallet_item = if let syn::Item::Type(item) = item { + Some(item.clone()) + } else { + let msg = "Invalid runtime::pallet_index, expected type definition"; + return Err(syn::Error::new(span, msg)) + }; + }, + RuntimeAttr::DisableCall(_) => disable_call = true, + RuntimeAttr::DisableUnsigned(_) => disable_unsigned = true, + attr => { + let msg = "Invalid duplicated attribute"; + return Err(syn::Error::new(attr.span(), msg)) + }, + } + } + + if let Some(pallet_item) = pallet_item { + match *pallet_item.ty.clone() { + syn::Type::Path(ref path) => { + let pallet_decl = + PalletDeclaration::try_from(item.span(), &pallet_item, path)?; + + if let Some(used_pallet) = + names.insert(pallet_decl.name.clone(), pallet_decl.name.span()) + { + let msg = "Two pallets with the same name!"; + + let mut err = syn::Error::new(used_pallet, &msg); + err.combine(syn::Error::new(pallet_decl.name.span(), &msg)); + return Err(err) + } + + pallet_decls.push(pallet_decl); + }, + syn::Type::TraitObject(syn::TypeTraitObject { bounds, .. }) => { + let pallet = Pallet::try_from( + item.span(), + &pallet_item, + pallet_index, + disable_call, + disable_unsigned, + &bounds, + )?; + + if let Some(used_pallet) = indices.insert(pallet.index, pallet.name.clone()) + { + let msg = format!( + "Pallet indices are conflicting: Both pallets {} and {} are at index {}", + used_pallet, pallet.name, pallet.index, + ); + let mut err = syn::Error::new(used_pallet.span(), &msg); + err.combine(syn::Error::new(pallet.name.span(), msg)); + return Err(err) + } + + pallets.push(pallet); + }, + _ => continue, + } + } + } + + let name = item.ident.clone(); + let decl_count = pallet_decls.len(); + let pallets = if decl_count > 0 { + AllPalletsDeclaration::Implicit(ImplicitAllPalletsDeclaration { + name, + pallet_decls, + pallet_count: decl_count.saturating_add(pallets.len()), + }) + } else { + AllPalletsDeclaration::Explicit(ExplicitAllPalletsDeclaration { name, pallets }) + }; + + let def = Def { + input, + item, + runtime_struct: runtime_struct.ok_or_else(|| { + syn::Error::new(item_span, + "Missing Runtime. Please add a struct inside the module and annotate it with `#[runtime::runtime]`" + ) + })?, + pallets, + runtime_types: runtime_types.ok_or_else(|| { + syn::Error::new(item_span, + "Missing Runtime Types. Please annotate the runtime struct with `#[runtime::derive]`" + ) + })?, + }; + + Ok(def) + } +} diff --git a/substrate/frame/support/procedural/src/runtime/parse/pallet.rs b/substrate/frame/support/procedural/src/runtime/parse/pallet.rs new file mode 100644 index 00000000000..d2f1857fb2b --- /dev/null +++ b/substrate/frame/support/procedural/src/runtime/parse/pallet.rs @@ -0,0 +1,99 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use crate::construct_runtime::parse::{Pallet, PalletPart, PalletPartKeyword, PalletPath}; +use quote::ToTokens; +use syn::{punctuated::Punctuated, spanned::Spanned, token, Error, Ident, PathArguments}; + +impl Pallet { + pub fn try_from( + attr_span: proc_macro2::Span, + item: &syn::ItemType, + pallet_index: u8, + disable_call: bool, + disable_unsigned: bool, + bounds: &Punctuated, + ) -> syn::Result { + let name = item.ident.clone(); + + let mut pallet_path = None; + let mut pallet_parts = vec![]; + + for (index, bound) in bounds.into_iter().enumerate() { + if let syn::TypeParamBound::Trait(syn::TraitBound { path, .. }) = bound { + if index == 0 { + pallet_path = Some(PalletPath { inner: path.clone() }); + } else { + let pallet_part = syn::parse2::(bound.into_token_stream())?; + pallet_parts.push(pallet_part); + } + } else { + return Err(Error::new( + attr_span, + "Invalid pallet declaration, expected a path or a trait object", + )) + }; + } + + let mut path = pallet_path.ok_or(Error::new( + attr_span, + "Invalid pallet declaration, expected a path or a trait object", + ))?; + + let mut instance = None; + if let Some(segment) = path.inner.segments.iter_mut().find(|seg| !seg.arguments.is_empty()) + { + if let PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments { + args, .. + }) = segment.arguments.clone() + { + if let Some(syn::GenericArgument::Type(syn::Type::Path(arg_path))) = args.first() { + instance = + Some(Ident::new(&arg_path.to_token_stream().to_string(), arg_path.span())); + segment.arguments = PathArguments::None; + } + } + } + + pallet_parts = pallet_parts + .into_iter() + .filter(|part| { + if let (true, &PalletPartKeyword::Call(_)) = (disable_call, &part.keyword) { + false + } else if let (true, &PalletPartKeyword::ValidateUnsigned(_)) = + (disable_unsigned, &part.keyword) + { + false + } else { + true + } + }) + .collect(); + + let cfg_pattern = vec![]; + + Ok(Pallet { + is_expanded: true, + name, + index: pallet_index, + path, + instance, + cfg_pattern, + pallet_parts, + }) + } +} diff --git a/substrate/frame/support/procedural/src/runtime/parse/pallet_decl.rs b/substrate/frame/support/procedural/src/runtime/parse/pallet_decl.rs new file mode 100644 index 00000000000..437a163cfbc --- /dev/null +++ b/substrate/frame/support/procedural/src/runtime/parse/pallet_decl.rs @@ -0,0 +1,60 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use quote::ToTokens; +use syn::{spanned::Spanned, Attribute, Ident, PathArguments}; + +/// The declaration of a pallet. +#[derive(Debug, Clone)] +pub struct PalletDeclaration { + /// The name of the pallet, e.g.`System` in `System: frame_system`. + pub name: Ident, + /// Optional attributes tagged right above a pallet declaration. + pub attrs: Vec, + /// The path of the pallet, e.g. `frame_system` in `System: frame_system`. + pub path: syn::Path, + /// The instance of the pallet, e.g. `Instance1` in `Council: pallet_collective::`. + pub instance: Option, +} + +impl PalletDeclaration { + pub fn try_from( + _attr_span: proc_macro2::Span, + item: &syn::ItemType, + path: &syn::TypePath, + ) -> syn::Result { + let name = item.ident.clone(); + + let mut path = path.path.clone(); + + let mut instance = None; + if let Some(segment) = path.segments.iter_mut().find(|seg| !seg.arguments.is_empty()) { + if let PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments { + args, .. + }) = segment.arguments.clone() + { + if let Some(syn::GenericArgument::Type(syn::Type::Path(arg_path))) = args.first() { + instance = + Some(Ident::new(&arg_path.to_token_stream().to_string(), arg_path.span())); + segment.arguments = PathArguments::None; + } + } + } + + Ok(Self { name, path, instance, attrs: item.attrs.clone() }) + } +} diff --git a/substrate/frame/support/procedural/src/runtime/parse/runtime_struct.rs b/substrate/frame/support/procedural/src/runtime/parse/runtime_struct.rs new file mode 100644 index 00000000000..8fa746ee807 --- /dev/null +++ b/substrate/frame/support/procedural/src/runtime/parse/runtime_struct.rs @@ -0,0 +1,35 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use syn::spanned::Spanned; +pub struct RuntimeStructDef { + pub ident: syn::Ident, + pub attr_span: proc_macro2::Span, +} + +impl RuntimeStructDef { + pub fn try_from(attr_span: proc_macro2::Span, item: &mut syn::Item) -> syn::Result { + let item = if let syn::Item::Struct(item) = item { + item + } else { + let msg = "Invalid runtime::runtime, expected struct definition"; + return Err(syn::Error::new(item.span(), msg)) + }; + + Ok(Self { ident: item.ident.clone(), attr_span }) + } +} diff --git a/substrate/frame/support/procedural/src/runtime/parse/runtime_types.rs b/substrate/frame/support/procedural/src/runtime/parse/runtime_types.rs new file mode 100644 index 00000000000..a4480e2a1fd --- /dev/null +++ b/substrate/frame/support/procedural/src/runtime/parse/runtime_types.rs @@ -0,0 +1,76 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use syn::{ + parse::{Parse, ParseStream}, + Result, +}; + +mod keyword { + use syn::custom_keyword; + + custom_keyword!(RuntimeCall); + custom_keyword!(RuntimeEvent); + custom_keyword!(RuntimeError); + custom_keyword!(RuntimeOrigin); + custom_keyword!(RuntimeFreezeReason); + custom_keyword!(RuntimeHoldReason); + custom_keyword!(RuntimeSlashReason); + custom_keyword!(RuntimeLockId); + custom_keyword!(RuntimeTask); +} + +#[derive(Debug, Clone, PartialEq)] +pub enum RuntimeType { + RuntimeCall(keyword::RuntimeCall), + RuntimeEvent(keyword::RuntimeEvent), + RuntimeError(keyword::RuntimeError), + RuntimeOrigin(keyword::RuntimeOrigin), + RuntimeFreezeReason(keyword::RuntimeFreezeReason), + RuntimeHoldReason(keyword::RuntimeHoldReason), + RuntimeSlashReason(keyword::RuntimeSlashReason), + RuntimeLockId(keyword::RuntimeLockId), + RuntimeTask(keyword::RuntimeTask), +} + +impl Parse for RuntimeType { + fn parse(input: ParseStream) -> Result { + let lookahead = input.lookahead1(); + + if lookahead.peek(keyword::RuntimeCall) { + Ok(Self::RuntimeCall(input.parse()?)) + } else if lookahead.peek(keyword::RuntimeEvent) { + Ok(Self::RuntimeEvent(input.parse()?)) + } else if lookahead.peek(keyword::RuntimeError) { + Ok(Self::RuntimeError(input.parse()?)) + } else if lookahead.peek(keyword::RuntimeOrigin) { + Ok(Self::RuntimeOrigin(input.parse()?)) + } else if lookahead.peek(keyword::RuntimeFreezeReason) { + Ok(Self::RuntimeFreezeReason(input.parse()?)) + } else if lookahead.peek(keyword::RuntimeHoldReason) { + Ok(Self::RuntimeHoldReason(input.parse()?)) + } else if lookahead.peek(keyword::RuntimeSlashReason) { + Ok(Self::RuntimeSlashReason(input.parse()?)) + } else if lookahead.peek(keyword::RuntimeLockId) { + Ok(Self::RuntimeLockId(input.parse()?)) + } else if lookahead.peek(keyword::RuntimeTask) { + Ok(Self::RuntimeTask(input.parse()?)) + } else { + Err(lookahead.error()) + } + } +} diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs index 07560abd935..af8449c9697 100644 --- a/substrate/frame/support/src/lib.rs +++ b/substrate/frame/support/src/lib.rs @@ -510,6 +510,9 @@ pub use frame_support_procedural::{ construct_runtime, match_and_insert, transactional, PalletError, RuntimeDebugNoBound, }; +#[cfg(feature = "experimental")] +pub use frame_support_procedural::runtime; + #[doc(hidden)] pub use frame_support_procedural::{__create_tt_macro, __generate_dummy_part_checker}; diff --git a/substrate/frame/support/test/Cargo.toml b/substrate/frame/support/test/Cargo.toml index ae2c56a531f..2f12cc00ed9 100644 --- a/substrate/frame/support/test/Cargo.toml +++ b/substrate/frame/support/test/Cargo.toml @@ -24,7 +24,7 @@ sp-api = { path = "../../../primitives/api", default-features = false } sp-arithmetic = { path = "../../../primitives/arithmetic", default-features = false } sp-io = { path = "../../../primitives/io", default-features = false } sp-state-machine = { path = "../../../primitives/state-machine", optional = true } -frame-support = { path = "..", default-features = false } +frame-support = { path = "..", default-features = false, features = ["experimental"] } frame-benchmarking = { path = "../../benchmarking", default-features = false } sp-runtime = { path = "../../../primitives/runtime", default-features = false } sp-core = { path = "../../../primitives/core", default-features = false } diff --git a/substrate/frame/support/test/tests/construct_runtime.rs b/substrate/frame/support/test/tests/runtime.rs similarity index 89% rename from substrate/frame/support/test/tests/construct_runtime.rs rename to substrate/frame/support/test/tests/runtime.rs index 83691451ccd..7e33ee46458 100644 --- a/substrate/frame/support/test/tests/construct_runtime.rs +++ b/substrate/frame/support/test/tests/runtime.rs @@ -30,7 +30,7 @@ use scale_info::TypeInfo; use sp_core::{sr25519, ConstU64}; use sp_runtime::{ generic, - traits::{BlakeTwo256, Verify}, + traits::{BlakeTwo256, ValidateUnsigned, Verify}, DispatchError, ModuleError, }; use sp_version::RuntimeVersion; @@ -176,6 +176,17 @@ mod nested { impl BuildGenesisConfig for GenesisConfig { fn build(&self) {} } + + #[pallet::validate_unsigned] + impl ValidateUnsigned for Pallet { + type Call = Call; + fn validate_unsigned( + _source: TransactionSource, + _call: &Self::Call, + ) -> TransactionValidity { + Err(TransactionValidityError::Invalid(InvalidTransaction::Call)) + } + } } } @@ -247,6 +258,20 @@ pub mod module3 { impl BuildGenesisConfig for GenesisConfig { fn build(&self) {} } + + #[pallet::storage] + pub type Storage = StorageValue<_, u32>; + + #[pallet::validate_unsigned] + impl ValidateUnsigned for Pallet { + type Call = Call; + fn validate_unsigned( + _source: TransactionSource, + _call: &Self::Call, + ) -> TransactionValidity { + Err(TransactionValidityError::Invalid(InvalidTransaction::Call)) + } + } } pub type BlockNumber = u64; @@ -256,24 +281,64 @@ pub type Header = generic::Header; pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; pub type Block = generic::Block; -frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Event, Origin} = 30, - Module1_1: module1::::{Pallet, Call, Storage, Event, Origin}, - Module2: module2::{Pallet, Call, Storage, Event, Origin}, - Module1_2: module1::::{Pallet, Call, Storage, Event, Origin}, - NestedModule3: nested::module3::{Pallet, Call, Config, Storage, Event, Origin}, - Module3: self::module3::{Pallet, Call, Config, Storage, Event, Origin}, - Module1_3: module1::::{Pallet, Storage, Event } = 6, - Module1_4: module1::::{Pallet, Call, Event } = 3, - Module1_5: module1::::{Pallet, Event}, - Module1_6: module1::::{Pallet, Call, Storage, Event, Origin} = 1, - Module1_7: module1::::{Pallet, Call, Storage, Event, Origin}, - Module1_8: module1::::{Pallet, Call, Storage, Event, Origin} = 12, - Module1_9: module1::::{Pallet, Call, Storage, Event, Origin}, - } -); +#[frame_support::runtime] +mod runtime { + #[runtime::runtime] + #[runtime::derive( + RuntimeCall, + RuntimeEvent, + RuntimeError, + RuntimeOrigin, + RuntimeFreezeReason, + RuntimeHoldReason, + RuntimeSlashReason, + RuntimeLockId, + RuntimeTask + )] + pub struct Runtime; + + #[runtime::pallet_index(30)] + pub type System = frame_system + Pallet + Call + Event + Origin; + + #[runtime::pallet_index(31)] + pub type Module1_1 = module1; + + #[runtime::pallet_index(32)] + pub type Module2 = module2; + + #[runtime::pallet_index(33)] + pub type Module1_2 = module1; + + #[runtime::pallet_index(34)] + pub type NestedModule3 = nested::module3; + + #[runtime::pallet_index(35)] + #[runtime::disable_unsigned] + pub type Module3 = self::module3; + + #[runtime::pallet_index(6)] + #[runtime::disable_call] + pub type Module1_3 = module1; + + #[runtime::pallet_index(3)] + pub type Module1_4 = module1; + + #[runtime::pallet_index(4)] + #[runtime::disable_call] + pub type Module1_5 = module1; + + #[runtime::pallet_index(1)] + pub type Module1_6 = module1; + + #[runtime::pallet_index(2)] + pub type Module1_7 = module1; + + #[runtime::pallet_index(12)] + pub type Module1_8 = module1; + + #[runtime::pallet_index(13)] + pub type Module1_9 = module1; +} #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Runtime { @@ -605,17 +670,17 @@ fn get_module_names() { let module_names = RuntimeCall::get_module_names(); assert_eq!( [ + "Module1_6", + "Module1_7", + "Module1_4", + "Module1_8", + "Module1_9", "System", "Module1_1", "Module2", "Module1_2", "NestedModule3", "Module3", - "Module1_4", - "Module1_6", - "Module1_7", - "Module1_8", - "Module1_9", ], module_names ); @@ -636,9 +701,13 @@ fn call_subtype_conversion() { #[test] fn test_metadata() { - use frame_metadata::{v14::*, *}; + use frame_metadata::{ + v14::{StorageEntryType::Plain, *}, + *, + }; use scale_info::meta_type; use sp_core::Encode; + use sp_metadata_ir::StorageEntryModifierIR::Optional; fn maybe_docs(doc: Vec<&'static str>) -> Vec<&'static str> { if cfg!(feature = "no-metadata-docs") { @@ -649,6 +718,69 @@ fn test_metadata() { } let pallets = vec![ + PalletMetadata { + name: "Module1_6", + storage:None, + calls: Some(meta_type::>().into()), + event: Some(meta_type::>().into()), + constants: vec![], + error: Some(meta_type::>().into()), + index: 1, + }, + PalletMetadata { + name: "Module1_7", + storage: None, + calls: Some(meta_type::>().into()), + event: Some(meta_type::>().into()), + constants: vec![], + error: Some(meta_type::>().into()), + index: 2, + }, + PalletMetadata { + name: "Module1_4", + storage: None, + calls: Some(meta_type::>().into()), + event: Some(meta_type::>().into()), + constants: vec![], + error: Some(meta_type::>().into()), + index: 3, + }, + PalletMetadata { + name: "Module1_5", + storage: None, + calls: None, + event: Some(meta_type::>().into()), + constants: vec![], + error: Some(meta_type::>().into()), + index: 4, + }, + PalletMetadata { + name: "Module1_3", + storage: None, + calls: None, + event: Some(meta_type::>().into()), + constants: vec![], + error: Some(meta_type::>().into()), + index: 6, + }, + PalletMetadata { + name: "Module1_8", + storage: None, + calls: Some(meta_type::>().into()), + event: Some(meta_type::>().into()), + constants: vec![], + error: Some(meta_type::>().into()), + index: 12, + }, + PalletMetadata { + name: "Module1_9", + storage: None, + calls: Some(meta_type::>().into()), + event: Some(meta_type::>().into()), + constants: vec![], + error: Some(meta_type::>().into()), + index: 13, + }, PalletMetadata { name: "System", storage: None, @@ -703,7 +835,7 @@ fn test_metadata() { }, PalletMetadata { name: "Module1_1", - storage: Some(PalletStorageMetadata { prefix: "Module1_1", entries: vec![] }), + storage: None, calls: Some(meta_type::>().into()), event: Some(meta_type::>().into()), constants: vec![], @@ -712,7 +844,7 @@ fn test_metadata() { }, PalletMetadata { name: "Module2", - storage: Some(PalletStorageMetadata { prefix: "Module2", entries: vec![] }), + storage: None, calls: Some(meta_type::>().into()), event: Some(meta_type::>().into()), constants: vec![], @@ -721,7 +853,7 @@ fn test_metadata() { }, PalletMetadata { name: "Module1_2", - storage: Some(PalletStorageMetadata { prefix: "Module1_2", entries: vec![] }), + storage: None, calls: Some(meta_type::>().into()), event: Some(meta_type::>().into()), constants: vec![], @@ -730,7 +862,7 @@ fn test_metadata() { }, PalletMetadata { name: "NestedModule3", - storage: Some(PalletStorageMetadata { prefix: "NestedModule3", entries: vec![] }), + storage: None, calls: Some(meta_type::>().into()), event: Some(meta_type::>().into()), constants: vec![], @@ -739,76 +871,24 @@ fn test_metadata() { }, PalletMetadata { name: "Module3", - storage: Some(PalletStorageMetadata { prefix: "Module3", entries: vec![] }), + storage: Some(PalletStorageMetadata { + prefix: "Module3", + entries: vec![ + StorageEntryMetadata { + name: "Storage", + modifier: Optional.into(), + ty: Plain(meta_type::().into()), + default: vec![0], + docs: vec![], + }, + ] + }), calls: Some(meta_type::>().into()), event: Some(meta_type::>().into()), constants: vec![], error: Some(meta_type::>().into()), index: 35, }, - PalletMetadata { - name: "Module1_3", - storage: Some(PalletStorageMetadata { prefix: "Module1_3", entries: vec![] }), - calls: None, - event: Some(meta_type::>().into()), - constants: vec![], - error: Some(meta_type::>().into()), - index: 6, - }, - PalletMetadata { - name: "Module1_4", - storage: None, - calls: Some(meta_type::>().into()), - event: Some(meta_type::>().into()), - constants: vec![], - error: Some(meta_type::>().into()), - index: 3, - }, - PalletMetadata { - name: "Module1_5", - storage: None, - calls: None, - event: Some(meta_type::>().into()), - constants: vec![], - error: Some(meta_type::>().into()), - index: 4, - }, - PalletMetadata { - name: "Module1_6", - storage: Some(PalletStorageMetadata { prefix: "Module1_6", entries: vec![] }), - calls: Some(meta_type::>().into()), - event: Some(meta_type::>().into()), - constants: vec![], - error: Some(meta_type::>().into()), - index: 1, - }, - PalletMetadata { - name: "Module1_7", - storage: Some(PalletStorageMetadata { prefix: "Module1_7", entries: vec![] }), - calls: Some(meta_type::>().into()), - event: Some(meta_type::>().into()), - constants: vec![], - error: Some(meta_type::>().into()), - index: 2, - }, - PalletMetadata { - name: "Module1_8", - storage: Some(PalletStorageMetadata { prefix: "Module1_8", entries: vec![] }), - calls: Some(meta_type::>().into()), - event: Some(meta_type::>().into()), - constants: vec![], - error: Some(meta_type::>().into()), - index: 12, - }, - PalletMetadata { - name: "Module1_9", - storage: Some(PalletStorageMetadata { prefix: "Module1_9", entries: vec![] }), - calls: Some(meta_type::>().into()), - event: Some(meta_type::>().into()), - constants: vec![], - error: Some(meta_type::>().into()), - index: 13, - }, ]; let extrinsic = ExtrinsicMetadata { @@ -895,3 +975,19 @@ fn pallet_in_runtime_is_correct() { assert_eq!(PalletInfo::module_name::().unwrap(), "module1"); assert!(PalletInfo::crate_version::().is_some()); } + +#[test] +fn test_validate_unsigned() { + use frame_support::pallet_prelude::*; + + let call = RuntimeCall::NestedModule3(nested::module3::Call::fail {}); + let validity = Runtime::validate_unsigned(TransactionSource::Local, &call).unwrap_err(); + assert_eq!(validity, TransactionValidityError::Invalid(InvalidTransaction::Call)); + + let call = RuntimeCall::Module3(module3::Call::fail {}); + let validity = Runtime::validate_unsigned(TransactionSource::Local, &call).unwrap_err(); + assert_eq!( + validity, + TransactionValidityError::Unknown(UnknownTransaction::NoUnsignedValidator) + ); +} diff --git a/substrate/frame/support/test/tests/runtime_legacy_ordering.rs b/substrate/frame/support/test/tests/runtime_legacy_ordering.rs new file mode 100644 index 00000000000..38875517018 --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_legacy_ordering.rs @@ -0,0 +1,993 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! General tests for construct_runtime macro, test for: +//! * error declared with decl_error works +//! * integrity test is generated + +#![recursion_limit = "128"] + +use codec::MaxEncodedLen; +use frame_support::{ + derive_impl, parameter_types, traits::PalletInfo as _, weights::RuntimeDbWeight, +}; +use frame_system::limits::{BlockLength, BlockWeights}; +use scale_info::TypeInfo; +use sp_core::{sr25519, ConstU64}; +use sp_runtime::{ + generic, + traits::{BlakeTwo256, ValidateUnsigned, Verify}, + DispatchError, ModuleError, +}; +use sp_version::RuntimeVersion; + +parameter_types! { + pub static IntegrityTestExec: u32 = 0; +} + +#[frame_support::pallet(dev_mode)] +mod module1 { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeEvent: From> + + IsType<::RuntimeEvent>; + } + + #[pallet::call] + impl, I: 'static> Pallet { + pub fn fail(_origin: OriginFor) -> DispatchResult { + Err(Error::::Something.into()) + } + } + + #[pallet::origin] + #[derive(Clone, PartialEq, Eq, RuntimeDebug, Encode, Decode, MaxEncodedLen, TypeInfo)] + #[scale_info(skip_type_params(I))] + pub struct Origin(pub PhantomData<(T, I)>); + + #[pallet::event] + pub enum Event, I: 'static = ()> { + A(::AccountId), + } + + #[pallet::error] + pub enum Error { + Something, + } +} + +#[frame_support::pallet(dev_mode)] +mod module2 { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + } + + #[pallet::hooks] + impl Hooks> for Pallet { + fn integrity_test() { + IntegrityTestExec::mutate(|i| *i += 1); + } + } + + #[pallet::call] + impl Pallet { + pub fn fail(_origin: OriginFor) -> DispatchResult { + Err(Error::::Something.into()) + } + } + + #[pallet::origin] + #[derive(Clone, PartialEq, Eq, RuntimeDebug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub struct Origin; + + #[pallet::event] + pub enum Event { + A, + } + + #[pallet::error] + pub enum Error { + Something, + } +} + +mod nested { + use super::*; + + #[frame_support::pallet(dev_mode)] + pub mod module3 { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeEvent: From> + + IsType<::RuntimeEvent>; + } + + #[pallet::hooks] + impl Hooks> for Pallet { + fn integrity_test() { + IntegrityTestExec::mutate(|i| *i += 1); + } + } + + #[pallet::call] + impl Pallet { + pub fn fail(_origin: OriginFor) -> DispatchResult { + Err(Error::::Something.into()) + } + } + + #[pallet::origin] + #[derive(Clone, PartialEq, Eq, RuntimeDebug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub struct Origin; + + #[pallet::event] + pub enum Event { + A, + } + + #[pallet::error] + pub enum Error { + Something, + } + + #[pallet::genesis_config] + #[derive(frame_support::DefaultNoBound)] + pub struct GenesisConfig { + #[serde(skip)] + pub _config: sp_std::marker::PhantomData, + } + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) {} + } + + #[pallet::validate_unsigned] + impl ValidateUnsigned for Pallet { + type Call = Call; + fn validate_unsigned( + _source: TransactionSource, + _call: &Self::Call, + ) -> TransactionValidity { + Err(TransactionValidityError::Invalid(InvalidTransaction::Call)) + } + } + } +} + +#[frame_support::pallet(dev_mode)] +pub mod module3 { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + } + + #[pallet::call] + impl Pallet { + pub fn fail(_origin: OriginFor) -> DispatchResult { + Err(Error::::Something.into()) + } + pub fn aux_1(_origin: OriginFor, #[pallet::compact] _data: u32) -> DispatchResult { + unreachable!() + } + pub fn aux_2( + _origin: OriginFor, + _data: i32, + #[pallet::compact] _data2: u32, + ) -> DispatchResult { + unreachable!() + } + #[pallet::weight(0)] + pub fn aux_3(_origin: OriginFor, _data: i32, _data2: String) -> DispatchResult { + unreachable!() + } + #[pallet::weight(3)] + pub fn aux_4(_origin: OriginFor) -> DispatchResult { + unreachable!() + } + #[pallet::weight((5, DispatchClass::Operational))] + pub fn operational(_origin: OriginFor) -> DispatchResult { + unreachable!() + } + } + + #[pallet::origin] + #[derive(Clone, PartialEq, Eq, RuntimeDebug, Encode, Decode, MaxEncodedLen, TypeInfo)] + pub struct Origin(pub PhantomData); + + #[pallet::event] + pub enum Event { + A, + } + + #[pallet::error] + pub enum Error { + Something, + } + + #[pallet::genesis_config] + #[derive(frame_support::DefaultNoBound)] + pub struct GenesisConfig { + #[serde(skip)] + pub _config: sp_std::marker::PhantomData, + } + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) {} + } + + #[pallet::storage] + pub type Storage = StorageValue<_, u32>; + + #[pallet::validate_unsigned] + impl ValidateUnsigned for Pallet { + type Call = Call; + fn validate_unsigned( + _source: TransactionSource, + _call: &Self::Call, + ) -> TransactionValidity { + Err(TransactionValidityError::Invalid(InvalidTransaction::Call)) + } + } +} + +pub type BlockNumber = u64; +pub type Signature = sr25519::Signature; +pub type AccountId = ::Signer; +pub type Header = generic::Header; +pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; +pub type Block = generic::Block; + +#[frame_support::runtime(legacy_ordering)] +mod runtime { + #[runtime::runtime] + #[runtime::derive( + RuntimeCall, + RuntimeEvent, + RuntimeError, + RuntimeOrigin, + RuntimeFreezeReason, + RuntimeHoldReason, + RuntimeSlashReason, + RuntimeLockId, + RuntimeTask + )] + pub struct Runtime; + + #[runtime::pallet_index(30)] + pub type System = frame_system + Pallet + Call + Event + Origin; + + #[runtime::pallet_index(31)] + pub type Module1_1 = module1; + + #[runtime::pallet_index(32)] + pub type Module2 = module2; + + #[runtime::pallet_index(33)] + pub type Module1_2 = module1; + + #[runtime::pallet_index(34)] + pub type NestedModule3 = nested::module3; + + #[runtime::pallet_index(35)] + #[runtime::disable_unsigned] + pub type Module3 = self::module3; + + #[runtime::pallet_index(6)] + #[runtime::disable_call] + pub type Module1_3 = module1; + + #[runtime::pallet_index(3)] + pub type Module1_4 = module1; + + #[runtime::pallet_index(4)] + #[runtime::disable_call] + pub type Module1_5 = module1; + + #[runtime::pallet_index(1)] + pub type Module1_6 = module1; + + #[runtime::pallet_index(2)] + pub type Module1_7 = module1; + + #[runtime::pallet_index(12)] + pub type Module1_8 = module1; + + #[runtime::pallet_index(13)] + pub type Module1_9 = module1; +} + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Runtime { + type AccountId = AccountId; + type Lookup = sp_runtime::traits::IdentityLookup; + type BaseCallFilter = frame_support::traits::Everything; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type PalletInfo = PalletInfo; + type OnSetCode = (); + type Block = Block; + type BlockHashCount = ConstU64<10>; +} + +impl module1::Config for Runtime { + type RuntimeEvent = RuntimeEvent; +} +impl module1::Config for Runtime { + type RuntimeEvent = RuntimeEvent; +} +impl module1::Config for Runtime { + type RuntimeEvent = RuntimeEvent; +} +impl module1::Config for Runtime { + type RuntimeEvent = RuntimeEvent; +} +impl module1::Config for Runtime { + type RuntimeEvent = RuntimeEvent; +} +impl module1::Config for Runtime { + type RuntimeEvent = RuntimeEvent; +} +impl module1::Config for Runtime { + type RuntimeEvent = RuntimeEvent; +} +impl module1::Config for Runtime { + type RuntimeEvent = RuntimeEvent; +} +impl module1::Config for Runtime { + type RuntimeEvent = RuntimeEvent; +} +impl module2::Config for Runtime { + type RuntimeEvent = RuntimeEvent; +} +impl nested::module3::Config for Runtime { + type RuntimeEvent = RuntimeEvent; +} +impl module3::Config for Runtime { + type RuntimeEvent = RuntimeEvent; +} + +fn test_pub() -> AccountId { + AccountId::from_raw([0; 32]) +} + +#[test] +fn check_modules_error_type() { + sp_io::TestExternalities::default().execute_with(|| { + assert_eq!( + Module1_1::fail(frame_system::Origin::::Root.into()), + Err(DispatchError::Module(ModuleError { + index: 31, + error: [0; 4], + message: Some("Something") + })), + ); + assert_eq!( + Module2::fail(frame_system::Origin::::Root.into()), + Err(DispatchError::Module(ModuleError { + index: 32, + error: [0; 4], + message: Some("Something") + })), + ); + assert_eq!( + Module1_2::fail(frame_system::Origin::::Root.into()), + Err(DispatchError::Module(ModuleError { + index: 33, + error: [0; 4], + message: Some("Something") + })), + ); + assert_eq!( + NestedModule3::fail(frame_system::Origin::::Root.into()), + Err(DispatchError::Module(ModuleError { + index: 34, + error: [0; 4], + message: Some("Something") + })), + ); + assert_eq!( + Module1_3::fail(frame_system::Origin::::Root.into()), + Err(DispatchError::Module(ModuleError { + index: 6, + error: [0; 4], + message: Some("Something") + })), + ); + assert_eq!( + Module1_4::fail(frame_system::Origin::::Root.into()), + Err(DispatchError::Module(ModuleError { + index: 3, + error: [0; 4], + message: Some("Something") + })), + ); + assert_eq!( + Module1_5::fail(frame_system::Origin::::Root.into()), + Err(DispatchError::Module(ModuleError { + index: 4, + error: [0; 4], + message: Some("Something") + })), + ); + assert_eq!( + Module1_6::fail(frame_system::Origin::::Root.into()), + Err(DispatchError::Module(ModuleError { + index: 1, + error: [0; 4], + message: Some("Something") + })), + ); + assert_eq!( + Module1_7::fail(frame_system::Origin::::Root.into()), + Err(DispatchError::Module(ModuleError { + index: 2, + error: [0; 4], + message: Some("Something") + })), + ); + assert_eq!( + Module1_8::fail(frame_system::Origin::::Root.into()), + Err(DispatchError::Module(ModuleError { + index: 12, + error: [0; 4], + message: Some("Something") + })), + ); + assert_eq!( + Module1_9::fail(frame_system::Origin::::Root.into()), + Err(DispatchError::Module(ModuleError { + index: 13, + error: [0; 4], + message: Some("Something") + })), + ); + }) +} + +#[test] +fn integrity_test_works() { + __construct_runtime_integrity_test::runtime_integrity_tests(); + assert_eq!(IntegrityTestExec::get(), 2); +} + +#[test] +fn origin_codec() { + use codec::Encode; + + let origin = OriginCaller::system(frame_system::RawOrigin::None); + assert_eq!(origin.encode()[0], 30); + + let origin = OriginCaller::Module1_1(module1::Origin(Default::default())); + assert_eq!(origin.encode()[0], 31); + + let origin = OriginCaller::Module2(module2::Origin); + assert_eq!(origin.encode()[0], 32); + + let origin = OriginCaller::Module1_2(module1::Origin(Default::default())); + assert_eq!(origin.encode()[0], 33); + + let origin = OriginCaller::NestedModule3(nested::module3::Origin); + assert_eq!(origin.encode()[0], 34); + + let origin = OriginCaller::Module3(module3::Origin(Default::default())); + assert_eq!(origin.encode()[0], 35); + + let origin = OriginCaller::Module1_6(module1::Origin(Default::default())); + assert_eq!(origin.encode()[0], 1); + + let origin = OriginCaller::Module1_7(module1::Origin(Default::default())); + assert_eq!(origin.encode()[0], 2); + + let origin = OriginCaller::Module1_8(module1::Origin(Default::default())); + assert_eq!(origin.encode()[0], 12); + + let origin = OriginCaller::Module1_9(module1::Origin(Default::default())); + assert_eq!(origin.encode()[0], 13); +} + +#[test] +fn event_codec() { + use codec::Encode; + + let event = + frame_system::Event::::ExtrinsicSuccess { dispatch_info: Default::default() }; + assert_eq!(RuntimeEvent::from(event).encode()[0], 30); + + let event = module1::Event::::A(test_pub()); + assert_eq!(RuntimeEvent::from(event).encode()[0], 31); + + let event = module2::Event::A; + assert_eq!(RuntimeEvent::from(event).encode()[0], 32); + + let event = module1::Event::::A(test_pub()); + assert_eq!(RuntimeEvent::from(event).encode()[0], 33); + + let event = nested::module3::Event::A; + assert_eq!(RuntimeEvent::from(event).encode()[0], 34); + + let event = module3::Event::A; + assert_eq!(RuntimeEvent::from(event).encode()[0], 35); + + let event = module1::Event::::A(test_pub()); + assert_eq!(RuntimeEvent::from(event).encode()[0], 4); + + let event = module1::Event::::A(test_pub()); + assert_eq!(RuntimeEvent::from(event).encode()[0], 1); + + let event = module1::Event::::A(test_pub()); + assert_eq!(RuntimeEvent::from(event).encode()[0], 2); + + let event = module1::Event::::A(test_pub()); + assert_eq!(RuntimeEvent::from(event).encode()[0], 12); + + let event = module1::Event::::A(test_pub()); + assert_eq!(RuntimeEvent::from(event).encode()[0], 13); +} + +#[test] +fn call_codec() { + use codec::Encode; + assert_eq!(RuntimeCall::System(frame_system::Call::remark { remark: vec![1] }).encode()[0], 30); + assert_eq!(RuntimeCall::Module1_1(module1::Call::fail {}).encode()[0], 31); + assert_eq!(RuntimeCall::Module2(module2::Call::fail {}).encode()[0], 32); + assert_eq!(RuntimeCall::Module1_2(module1::Call::fail {}).encode()[0], 33); + assert_eq!(RuntimeCall::NestedModule3(nested::module3::Call::fail {}).encode()[0], 34); + assert_eq!(RuntimeCall::Module3(module3::Call::fail {}).encode()[0], 35); + assert_eq!(RuntimeCall::Module1_4(module1::Call::fail {}).encode()[0], 3); + assert_eq!(RuntimeCall::Module1_6(module1::Call::fail {}).encode()[0], 1); + assert_eq!(RuntimeCall::Module1_7(module1::Call::fail {}).encode()[0], 2); + assert_eq!(RuntimeCall::Module1_8(module1::Call::fail {}).encode()[0], 12); + assert_eq!(RuntimeCall::Module1_9(module1::Call::fail {}).encode()[0], 13); +} + +#[test] +fn call_compact_attr() { + use codec::Encode; + let call: module3::Call = module3::Call::aux_1 { data: 1 }; + let encoded = call.encode(); + assert_eq!(2, encoded.len()); + assert_eq!(vec![1, 4], encoded); + + let call: module3::Call = module3::Call::aux_2 { data: 1, data2: 2 }; + let encoded = call.encode(); + assert_eq!(6, encoded.len()); + assert_eq!(vec![2, 1, 0, 0, 0, 8], encoded); +} + +#[test] +fn call_encode_is_correct_and_decode_works() { + use codec::{Decode, Encode}; + let call: module3::Call = module3::Call::fail {}; + let encoded = call.encode(); + assert_eq!(vec![0], encoded); + let decoded = module3::Call::::decode(&mut &encoded[..]).unwrap(); + assert_eq!(decoded, call); + + let call: module3::Call = module3::Call::aux_3 { data: 32, data2: "hello".into() }; + let encoded = call.encode(); + assert_eq!(vec![3, 32, 0, 0, 0, 20, 104, 101, 108, 108, 111], encoded); + let decoded = module3::Call::::decode(&mut &encoded[..]).unwrap(); + assert_eq!(decoded, call); +} + +#[test] +fn call_weight_should_attach_to_call_enum() { + use frame_support::{ + dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, Pays}, + weights::Weight, + }; + // operational. + assert_eq!( + module3::Call::::operational {}.get_dispatch_info(), + DispatchInfo { + weight: Weight::from_parts(5, 0), + class: DispatchClass::Operational, + pays_fee: Pays::Yes + }, + ); + // custom basic + assert_eq!( + module3::Call::::aux_4 {}.get_dispatch_info(), + DispatchInfo { + weight: Weight::from_parts(3, 0), + class: DispatchClass::Normal, + pays_fee: Pays::Yes + }, + ); +} + +#[test] +fn call_name() { + use frame_support::traits::GetCallName; + let name = module3::Call::::aux_4 {}.get_call_name(); + assert_eq!("aux_4", name); +} + +#[test] +fn call_metadata() { + use frame_support::traits::{CallMetadata, GetCallMetadata}; + let call = RuntimeCall::Module3(module3::Call::::aux_4 {}); + let metadata = call.get_call_metadata(); + let expected = CallMetadata { function_name: "aux_4".into(), pallet_name: "Module3".into() }; + assert_eq!(metadata, expected); +} + +#[test] +fn get_call_names() { + use frame_support::traits::GetCallName; + let call_names = module3::Call::::get_call_names(); + assert_eq!(["fail", "aux_1", "aux_2", "aux_3", "aux_4", "operational"], call_names); +} + +#[test] +fn get_module_names() { + use frame_support::traits::GetCallMetadata; + let module_names = RuntimeCall::get_module_names(); + assert_eq!( + [ + "System", + "Module1_1", + "Module2", + "Module1_2", + "NestedModule3", + "Module3", + "Module1_4", + "Module1_6", + "Module1_7", + "Module1_8", + "Module1_9", + ], + module_names + ); +} + +#[test] +fn call_subtype_conversion() { + use frame_support::{dispatch::CallableCallFor, traits::IsSubType}; + let call = RuntimeCall::Module3(module3::Call::::fail {}); + let subcall: Option<&CallableCallFor> = call.is_sub_type(); + let subcall_none: Option<&CallableCallFor> = call.is_sub_type(); + assert_eq!(Some(&module3::Call::::fail {}), subcall); + assert_eq!(None, subcall_none); + + let from = RuntimeCall::from(subcall.unwrap().clone()); + assert_eq!(from, call); +} + +#[test] +fn test_metadata() { + use frame_metadata::{ + v14::{StorageEntryType::Plain, *}, + *, + }; + use scale_info::meta_type; + use sp_core::Encode; + use sp_metadata_ir::StorageEntryModifierIR::Optional; + + fn maybe_docs(doc: Vec<&'static str>) -> Vec<&'static str> { + if cfg!(feature = "no-metadata-docs") { + vec![] + } else { + doc + } + } + + let pallets = vec![ + PalletMetadata { + name: "System", + storage: None, + calls: Some(meta_type::>().into()), + event: Some(meta_type::>().into()), + constants: vec![ + PalletConstantMetadata { + name: "BlockWeights", + ty: meta_type::(), + value: BlockWeights::default().encode(), + docs: maybe_docs(vec![" Block & extrinsics weights: base values and limits."]), + }, + PalletConstantMetadata { + name: "BlockLength", + ty: meta_type::(), + value: BlockLength::default().encode(), + docs: maybe_docs(vec![" The maximum length of a block (in bytes)."]), + }, + PalletConstantMetadata { + name: "BlockHashCount", + ty: meta_type::(), + value: 10u64.encode(), + docs: maybe_docs(vec![" Maximum number of block number to block hash mappings to keep (oldest pruned first)."]), + }, + PalletConstantMetadata { + name: "DbWeight", + ty: meta_type::(), + value: RuntimeDbWeight::default().encode(), + docs: maybe_docs(vec![" The weight of runtime database operations the runtime can invoke.",]), + }, + PalletConstantMetadata { + name: "Version", + ty: meta_type::(), + value: RuntimeVersion::default().encode(), + docs: maybe_docs(vec![ " Get the chain's current version."]), + }, + PalletConstantMetadata { + name: "SS58Prefix", + ty: meta_type::(), + value: 0u16.encode(), + docs: maybe_docs(vec![ + " The designated SS58 prefix of this chain.", + "", + " This replaces the \"ss58Format\" property declared in the chain spec. Reason is", + " that the runtime should know about the prefix in order to make use of it as", + " an identifier of the chain.", + ]), + }, + ], + error: Some(meta_type::>().into()), + index: 30, + }, + PalletMetadata { + name: "Module1_1", + storage: None, + calls: Some(meta_type::>().into()), + event: Some(meta_type::>().into()), + constants: vec![], + error: Some(meta_type::>().into()), + index: 31, + }, + PalletMetadata { + name: "Module2", + storage: None, + calls: Some(meta_type::>().into()), + event: Some(meta_type::>().into()), + constants: vec![], + error: Some(meta_type::>().into()), + index: 32, + }, + PalletMetadata { + name: "Module1_2", + storage: None, + calls: Some(meta_type::>().into()), + event: Some(meta_type::>().into()), + constants: vec![], + error: Some(meta_type::>().into()), + index: 33, + }, + PalletMetadata { + name: "NestedModule3", + storage: None, + calls: Some(meta_type::>().into()), + event: Some(meta_type::>().into()), + constants: vec![], + error: Some(meta_type::>().into()), + index: 34, + }, + PalletMetadata { + name: "Module3", + storage: Some(PalletStorageMetadata { + prefix: "Module3", + entries: vec![ + StorageEntryMetadata { + name: "Storage", + modifier: Optional.into(), + ty: Plain(meta_type::().into()), + default: vec![0], + docs: vec![], + }, + ] + }), + calls: Some(meta_type::>().into()), + event: Some(meta_type::>().into()), + constants: vec![], + error: Some(meta_type::>().into()), + index: 35, + }, + PalletMetadata { + name: "Module1_3", + storage: None, + calls: None, + event: Some(meta_type::>().into()), + constants: vec![], + error: Some(meta_type::>().into()), + index: 6, + }, + PalletMetadata { + name: "Module1_4", + storage: None, + calls: Some(meta_type::>().into()), + event: Some(meta_type::>().into()), + constants: vec![], + error: Some(meta_type::>().into()), + index: 3, + }, + PalletMetadata { + name: "Module1_5", + storage: None, + calls: None, + event: Some(meta_type::>().into()), + constants: vec![], + error: Some(meta_type::>().into()), + index: 4, + }, + PalletMetadata { + name: "Module1_6", + storage:None, + calls: Some(meta_type::>().into()), + event: Some(meta_type::>().into()), + constants: vec![], + error: Some(meta_type::>().into()), + index: 1, + }, + PalletMetadata { + name: "Module1_7", + storage: None, + calls: Some(meta_type::>().into()), + event: Some(meta_type::>().into()), + constants: vec![], + error: Some(meta_type::>().into()), + index: 2, + }, + PalletMetadata { + name: "Module1_8", + storage: None, + calls: Some(meta_type::>().into()), + event: Some(meta_type::>().into()), + constants: vec![], + error: Some(meta_type::>().into()), + index: 12, + }, + PalletMetadata { + name: "Module1_9", + storage: None, + calls: Some(meta_type::>().into()), + event: Some(meta_type::>().into()), + constants: vec![], + error: Some(meta_type::>().into()), + index: 13, + }, + ]; + + let extrinsic = ExtrinsicMetadata { + ty: meta_type::(), + version: 4, + signed_extensions: vec![SignedExtensionMetadata { + identifier: "UnitTransactionExtension", + ty: meta_type::<()>(), + additional_signed: meta_type::<()>(), + }], + }; + + let expected_metadata: RuntimeMetadataPrefixed = + RuntimeMetadataLastVersion::new(pallets, extrinsic, meta_type::()).into(); + let actual_metadata = Runtime::metadata(); + + pretty_assertions::assert_eq!(actual_metadata, expected_metadata); +} + +#[test] +fn pallet_in_runtime_is_correct() { + assert_eq!(PalletInfo::index::().unwrap(), 30); + assert_eq!(PalletInfo::name::().unwrap(), "System"); + assert_eq!(PalletInfo::module_name::().unwrap(), "frame_system"); + assert!(PalletInfo::crate_version::().is_some()); + + assert_eq!(PalletInfo::index::().unwrap(), 31); + assert_eq!(PalletInfo::name::().unwrap(), "Module1_1"); + assert_eq!(PalletInfo::module_name::().unwrap(), "module1"); + assert!(PalletInfo::crate_version::().is_some()); + + assert_eq!(PalletInfo::index::().unwrap(), 32); + assert_eq!(PalletInfo::name::().unwrap(), "Module2"); + assert_eq!(PalletInfo::module_name::().unwrap(), "module2"); + assert!(PalletInfo::crate_version::().is_some()); + + assert_eq!(PalletInfo::index::().unwrap(), 33); + assert_eq!(PalletInfo::name::().unwrap(), "Module1_2"); + assert_eq!(PalletInfo::module_name::().unwrap(), "module1"); + assert!(PalletInfo::crate_version::().is_some()); + + assert_eq!(PalletInfo::index::().unwrap(), 34); + assert_eq!(PalletInfo::name::().unwrap(), "NestedModule3"); + assert_eq!(PalletInfo::module_name::().unwrap(), "nested::module3"); + assert!(PalletInfo::crate_version::().is_some()); + + assert_eq!(PalletInfo::index::().unwrap(), 35); + assert_eq!(PalletInfo::name::().unwrap(), "Module3"); + assert_eq!(PalletInfo::module_name::().unwrap(), "self::module3"); + assert!(PalletInfo::crate_version::().is_some()); + + assert_eq!(PalletInfo::index::().unwrap(), 6); + assert_eq!(PalletInfo::name::().unwrap(), "Module1_3"); + assert_eq!(PalletInfo::module_name::().unwrap(), "module1"); + assert!(PalletInfo::crate_version::().is_some()); + + assert_eq!(PalletInfo::index::().unwrap(), 3); + assert_eq!(PalletInfo::name::().unwrap(), "Module1_4"); + assert_eq!(PalletInfo::module_name::().unwrap(), "module1"); + assert!(PalletInfo::crate_version::().is_some()); + + assert_eq!(PalletInfo::index::().unwrap(), 4); + assert_eq!(PalletInfo::name::().unwrap(), "Module1_5"); + assert_eq!(PalletInfo::module_name::().unwrap(), "module1"); + assert!(PalletInfo::crate_version::().is_some()); + + assert_eq!(PalletInfo::index::().unwrap(), 1); + assert_eq!(PalletInfo::name::().unwrap(), "Module1_6"); + assert_eq!(PalletInfo::module_name::().unwrap(), "module1"); + assert!(PalletInfo::crate_version::().is_some()); + + assert_eq!(PalletInfo::index::().unwrap(), 2); + assert_eq!(PalletInfo::name::().unwrap(), "Module1_7"); + assert_eq!(PalletInfo::module_name::().unwrap(), "module1"); + assert!(PalletInfo::crate_version::().is_some()); + + assert_eq!(PalletInfo::index::().unwrap(), 12); + assert_eq!(PalletInfo::name::().unwrap(), "Module1_8"); + assert_eq!(PalletInfo::module_name::().unwrap(), "module1"); + assert!(PalletInfo::crate_version::().is_some()); + + assert_eq!(PalletInfo::index::().unwrap(), 13); + assert_eq!(PalletInfo::name::().unwrap(), "Module1_9"); + assert_eq!(PalletInfo::module_name::().unwrap(), "module1"); + assert!(PalletInfo::crate_version::().is_some()); +} + +#[test] +fn test_validate_unsigned() { + use frame_support::pallet_prelude::*; + + let call = RuntimeCall::NestedModule3(nested::module3::Call::fail {}); + let validity = Runtime::validate_unsigned(TransactionSource::Local, &call).unwrap_err(); + assert_eq!(validity, TransactionValidityError::Invalid(InvalidTransaction::Call)); + + let call = RuntimeCall::Module3(module3::Call::fail {}); + let validity = Runtime::validate_unsigned(TransactionSource::Local, &call).unwrap_err(); + assert_eq!( + validity, + TransactionValidityError::Unknown(UnknownTransaction::NoUnsignedValidator) + ); +} diff --git a/substrate/frame/support/test/tests/runtime_ui.rs b/substrate/frame/support/test/tests/runtime_ui.rs new file mode 100644 index 00000000000..dbe150f38ed --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui.rs @@ -0,0 +1,36 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#[rustversion::attr(not(stable), ignore)] +#[cfg(not(feature = "disable-ui-tests"))] +#[test] +fn ui() { + // Only run the ui tests when `RUN_UI_TESTS` is set. + if std::env::var("RUN_UI_TESTS").is_err() { + return + } + + // As trybuild is using `cargo check`, we don't need the real WASM binaries. + std::env::set_var("SKIP_WASM_BUILD", "1"); + + // Deny all warnings since we emit warnings as part of a Runtime's UI. + std::env::set_var("RUSTFLAGS", "--deny warnings"); + + let t = trybuild::TestCases::new(); + t.compile_fail("tests/runtime_ui/*.rs"); + t.pass("tests/runtime_ui/pass/*.rs"); +} diff --git a/substrate/frame/support/test/tests/runtime_ui/can_only_be_attached_to_mod.rs b/substrate/frame/support/test/tests/runtime_ui/can_only_be_attached_to_mod.rs new file mode 100644 index 00000000000..eb586809041 --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/can_only_be_attached_to_mod.rs @@ -0,0 +1,21 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#[frame_support::runtime] +fn construct_runtime() {} + +fn main() {} diff --git a/substrate/frame/support/test/tests/runtime_ui/can_only_be_attached_to_mod.stderr b/substrate/frame/support/test/tests/runtime_ui/can_only_be_attached_to_mod.stderr new file mode 100644 index 00000000000..7c2f0d1f169 --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/can_only_be_attached_to_mod.stderr @@ -0,0 +1,5 @@ +error: expected `mod` + --> tests/runtime_ui/can_only_be_attached_to_mod.rs:19:1 + | +19 | fn construct_runtime() {} + | ^^ diff --git a/substrate/frame/support/test/tests/runtime_ui/conflicting_pallet_index.rs b/substrate/frame/support/test/tests/runtime_ui/conflicting_pallet_index.rs new file mode 100644 index 00000000000..648812b52c4 --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/conflicting_pallet_index.rs @@ -0,0 +1,43 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#[frame_support::pallet] +mod pallet { + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::call] + impl Pallet {} +} + +#[frame_support::runtime] +mod runtime { + #[runtime::runtime] + #[runtime::derive(RuntimeCall)] + pub struct Runtime; + + #[runtime::pallet_index(0)] + pub type System = frame_system; + + #[runtime::pallet_index(0)] + pub type Pallet = pallet; +} + +fn main() {} diff --git a/substrate/frame/support/test/tests/runtime_ui/conflicting_pallet_index.stderr b/substrate/frame/support/test/tests/runtime_ui/conflicting_pallet_index.stderr new file mode 100644 index 00000000000..8963c5d3f26 --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/conflicting_pallet_index.stderr @@ -0,0 +1,11 @@ +error: Pallet indices are conflicting: Both pallets System and Pallet are at index 0 + --> tests/runtime_ui/conflicting_pallet_index.rs:37:14 + | +37 | pub type System = frame_system; + | ^^^^^^ + +error: Pallet indices are conflicting: Both pallets System and Pallet are at index 0 + --> tests/runtime_ui/conflicting_pallet_index.rs:40:14 + | +40 | pub type Pallet = pallet; + | ^^^^^^ diff --git a/substrate/frame/support/test/tests/runtime_ui/conflicting_pallet_name.rs b/substrate/frame/support/test/tests/runtime_ui/conflicting_pallet_name.rs new file mode 100644 index 00000000000..c68f9a8082b --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/conflicting_pallet_name.rs @@ -0,0 +1,43 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#[frame_support::pallet] +mod pallet { + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::call] + impl Pallet {} +} + +#[frame_support::runtime] +mod runtime { + #[runtime::runtime] + #[runtime::derive(RuntimeCall)] + pub struct Runtime; + + #[runtime::pallet_index(0)] + pub type System = frame_system; + + #[runtime::pallet_index(1)] + pub type System = pallet; +} + +fn main() {} diff --git a/substrate/frame/support/test/tests/runtime_ui/conflicting_pallet_name.stderr b/substrate/frame/support/test/tests/runtime_ui/conflicting_pallet_name.stderr new file mode 100644 index 00000000000..c250c24e3e7 --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/conflicting_pallet_name.stderr @@ -0,0 +1,11 @@ +error: Two pallets with the same name! + --> tests/runtime_ui/conflicting_pallet_name.rs:37:14 + | +37 | pub type System = frame_system; + | ^^^^^^ + +error: Two pallets with the same name! + --> tests/runtime_ui/conflicting_pallet_name.rs:40:14 + | +40 | pub type System = pallet; + | ^^^^^^ diff --git a/substrate/frame/support/test/tests/runtime_ui/invalid_attribute.rs b/substrate/frame/support/test/tests/runtime_ui/invalid_attribute.rs new file mode 100644 index 00000000000..5df2491cb24 --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/invalid_attribute.rs @@ -0,0 +1,23 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#[frame_support::runtime(dummy)] +mod runtime { + +} + +fn main() {} diff --git a/substrate/frame/support/test/tests/runtime_ui/invalid_attribute.stderr b/substrate/frame/support/test/tests/runtime_ui/invalid_attribute.stderr new file mode 100644 index 00000000000..e13552413c0 --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/invalid_attribute.stderr @@ -0,0 +1,5 @@ +error: Invalid runtime macro call: unexpected attribute. Macro call must be bare, such as `#[frame_support::runtime]` or `#[runtime]`, or must specify the `legacy_ordering` attribute, such as `#[frame_support::runtime(legacy_ordering)]` or #[runtime(legacy_ordering)]. + --> tests/runtime_ui/invalid_attribute.rs:18:26 + | +18 | #[frame_support::runtime(dummy)] + | ^^^^^ diff --git a/substrate/frame/support/test/tests/runtime_ui/invalid_pallet_index.rs b/substrate/frame/support/test/tests/runtime_ui/invalid_pallet_index.rs new file mode 100644 index 00000000000..de89bb60224 --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/invalid_pallet_index.rs @@ -0,0 +1,28 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#[frame_support::runtime] +mod runtime { + #[runtime::runtime] + #[runtime::derive(RuntimeCall)] + pub struct Runtime; + + #[runtime::pallet_index("0")] + pub type System = frame_system; +} + +fn main() {} diff --git a/substrate/frame/support/test/tests/runtime_ui/invalid_pallet_index.stderr b/substrate/frame/support/test/tests/runtime_ui/invalid_pallet_index.stderr new file mode 100644 index 00000000000..1fbd086ddbe --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/invalid_pallet_index.stderr @@ -0,0 +1,5 @@ +error: expected integer literal + --> tests/runtime_ui/invalid_pallet_index.rs:24:29 + | +24 | #[runtime::pallet_index("0")] + | ^^^ diff --git a/substrate/frame/support/test/tests/runtime_ui/invalid_runtime_type_derive.rs b/substrate/frame/support/test/tests/runtime_ui/invalid_runtime_type_derive.rs new file mode 100644 index 00000000000..89ba2f23bb1 --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/invalid_runtime_type_derive.rs @@ -0,0 +1,25 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#[frame_support::runtime] +mod runtime { + #[runtime::runtime] + #[runtime::derive(RuntimeInfo)] + pub struct Runtime; +} + +fn main() {} diff --git a/substrate/frame/support/test/tests/runtime_ui/invalid_runtime_type_derive.stderr b/substrate/frame/support/test/tests/runtime_ui/invalid_runtime_type_derive.stderr new file mode 100644 index 00000000000..0b128c3dd45 --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/invalid_runtime_type_derive.stderr @@ -0,0 +1,5 @@ +error: expected one of: `RuntimeCall`, `RuntimeEvent`, `RuntimeError`, `RuntimeOrigin`, `RuntimeFreezeReason`, `RuntimeHoldReason`, `RuntimeSlashReason`, `RuntimeLockId`, `RuntimeTask` + --> tests/runtime_ui/invalid_runtime_type_derive.rs:21:23 + | +21 | #[runtime::derive(RuntimeInfo)] + | ^^^^^^^^^^^ diff --git a/substrate/frame/support/test/tests/runtime_ui/missing_runtime.rs b/substrate/frame/support/test/tests/runtime_ui/missing_runtime.rs new file mode 100644 index 00000000000..c5febbe5287 --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/missing_runtime.rs @@ -0,0 +1,21 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#[frame_support::runtime] +mod runtime {} + +fn main() {} diff --git a/substrate/frame/support/test/tests/runtime_ui/missing_runtime.stderr b/substrate/frame/support/test/tests/runtime_ui/missing_runtime.stderr new file mode 100644 index 00000000000..9790c5dbc1a --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/missing_runtime.stderr @@ -0,0 +1,5 @@ +error: Missing Runtime. Please add a struct inside the module and annotate it with `#[runtime::runtime]` + --> tests/runtime_ui/missing_runtime.rs:19:1 + | +19 | mod runtime {} + | ^^^ diff --git a/substrate/frame/support/test/tests/runtime_ui/missing_runtime_types_derive.rs b/substrate/frame/support/test/tests/runtime_ui/missing_runtime_types_derive.rs new file mode 100644 index 00000000000..c3fb0fd454f --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/missing_runtime_types_derive.rs @@ -0,0 +1,24 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#[frame_support::runtime] +mod runtime { + #[runtime::runtime] + pub struct Runtime; +} + +fn main() {} diff --git a/substrate/frame/support/test/tests/runtime_ui/missing_runtime_types_derive.stderr b/substrate/frame/support/test/tests/runtime_ui/missing_runtime_types_derive.stderr new file mode 100644 index 00000000000..1a8deebe549 --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/missing_runtime_types_derive.stderr @@ -0,0 +1,5 @@ +error: Missing Runtime Types. Please annotate the runtime struct with `#[runtime::derive]` + --> tests/runtime_ui/missing_runtime_types_derive.rs:19:1 + | +19 | mod runtime { + | ^^^ diff --git a/substrate/frame/support/test/tests/runtime_ui/missing_system_pallet.rs b/substrate/frame/support/test/tests/runtime_ui/missing_system_pallet.rs new file mode 100644 index 00000000000..f9a15fcf992 --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/missing_system_pallet.rs @@ -0,0 +1,25 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#[frame_support::runtime] +mod runtime { + #[runtime::runtime] + #[runtime::derive(RuntimeCall)] + pub struct Runtime; +} + +fn main() {} diff --git a/substrate/frame/support/test/tests/runtime_ui/missing_system_pallet.stderr b/substrate/frame/support/test/tests/runtime_ui/missing_system_pallet.stderr new file mode 100644 index 00000000000..dc3ac4cd5d5 --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/missing_system_pallet.stderr @@ -0,0 +1,5 @@ +error: `System` pallet declaration is missing. Please add this line: `pub type System = frame_system;` + --> tests/runtime_ui/missing_system_pallet.rs:19:5 + | +19 | mod runtime { + | ^^^^^^^ diff --git a/substrate/frame/support/test/tests/runtime_ui/pass/basic.rs b/substrate/frame/support/test/tests/runtime_ui/pass/basic.rs new file mode 100644 index 00000000000..514f1501801 --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/pass/basic.rs @@ -0,0 +1,37 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use frame_support::derive_impl; + +pub type Block = frame_system::mocking::MockBlock; + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Runtime { + type Block = Block; +} + +#[frame_support::runtime] +mod runtime { + #[runtime::runtime] + #[runtime::derive(RuntimeCall, RuntimeEvent, RuntimeOrigin, RuntimeError, RuntimeTask)] + pub struct Runtime; + + #[runtime::pallet_index(0)] + pub type System = frame_system; +} + +fn main() {} diff --git a/substrate/frame/support/test/tests/runtime_ui/runtime_struct.rs b/substrate/frame/support/test/tests/runtime_ui/runtime_struct.rs new file mode 100644 index 00000000000..bfa2fb75f04 --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/runtime_struct.rs @@ -0,0 +1,24 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#[frame_support::runtime] +mod runtime { + #[runtime::runtime] + pub enum Runtime {} +} + +fn main() {} diff --git a/substrate/frame/support/test/tests/runtime_ui/runtime_struct.stderr b/substrate/frame/support/test/tests/runtime_ui/runtime_struct.stderr new file mode 100644 index 00000000000..04192bcf7f1 --- /dev/null +++ b/substrate/frame/support/test/tests/runtime_ui/runtime_struct.stderr @@ -0,0 +1,5 @@ +error: Invalid runtime::runtime, expected struct definition + --> tests/runtime_ui/runtime_struct.rs:21:5 + | +21 | pub enum Runtime {} + | ^^^ diff --git a/templates/solochain/runtime/Cargo.toml b/templates/solochain/runtime/Cargo.toml index 4f22e7ff6a3..706ea863d0f 100644 --- a/templates/solochain/runtime/Cargo.toml +++ b/templates/solochain/runtime/Cargo.toml @@ -25,7 +25,7 @@ scale-info = { version = "2.10.0", default-features = false, features = [ ] } # frame -frame-support = { path = "../../../substrate/frame/support", default-features = false } +frame-support = { path = "../../../substrate/frame/support", default-features = false, features = ["experimental"] } frame-system = { path = "../../../substrate/frame/system", default-features = false } frame-try-runtime = { path = "../../../substrate/frame/try-runtime", default-features = false, optional = true } frame-executive = { path = "../../../substrate/frame/executive", default-features = false } diff --git a/templates/solochain/runtime/src/lib.rs b/templates/solochain/runtime/src/lib.rs index 409b639f021..303122da564 100644 --- a/templates/solochain/runtime/src/lib.rs +++ b/templates/solochain/runtime/src/lib.rs @@ -253,20 +253,47 @@ impl pallet_template::Config for Runtime { } // Create the runtime by composing the FRAME pallets that were previously configured. -construct_runtime!( - pub enum Runtime { - System: frame_system, - Timestamp: pallet_timestamp, - Aura: pallet_aura, - Grandpa: pallet_grandpa, - Balances: pallet_balances, - TransactionPayment: pallet_transaction_payment, - Sudo: pallet_sudo, - - // Include the custom logic from the pallet-template in the runtime. - TemplateModule: pallet_template, - } -); +#[frame_support::runtime] +mod runtime { + #[runtime::runtime] + #[runtime::derive( + RuntimeCall, + RuntimeEvent, + RuntimeError, + RuntimeOrigin, + RuntimeFreezeReason, + RuntimeHoldReason, + RuntimeSlashReason, + RuntimeLockId, + RuntimeTask + )] + pub struct Runtime; + + #[runtime::pallet_index(0)] + pub type System = frame_system; + + #[runtime::pallet_index(1)] + pub type Timestamp = pallet_timestamp; + + #[runtime::pallet_index(2)] + pub type Aura = pallet_aura; + + #[runtime::pallet_index(3)] + pub type Grandpa = pallet_grandpa; + + #[runtime::pallet_index(4)] + pub type Balances = pallet_balances; + + #[runtime::pallet_index(5)] + pub type TransactionPayment = pallet_transaction_payment; + + #[runtime::pallet_index(6)] + pub type Sudo = pallet_sudo; + + // Include the custom logic from the pallet-template in the runtime. + #[runtime::pallet_index(7)] + pub type TemplateModule = pallet_template; +} /// The address format for describing accounts. pub type Address = sp_runtime::MultiAddress; -- GitLab From 60ac5a723c6c0eeef0e35a0788792378c8200ec5 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> Date: Wed, 13 Mar 2024 13:33:27 +0200 Subject: [PATCH 391/392] authority-discovery: Add log for debugging DHT authority records (#3668) This PR adds a debug log for displaying all the public addresses that will later be advertised in the DHT record of the authority. The Authority DHT record will contain the address ++ `/p2p/peerID` (if not already present). This log enables us to check if different nodes will advertise in the DHT record of the authority the same IP address, however with different peer IDs. Signed-off-by: Alexandru Vasile --- .../client/authority-discovery/src/worker.rs | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/substrate/client/authority-discovery/src/worker.rs b/substrate/client/authority-discovery/src/worker.rs index 6db25416dee..9bccb96ff37 100644 --- a/substrate/client/authority-discovery/src/worker.rs +++ b/substrate/client/authority-discovery/src/worker.rs @@ -306,29 +306,30 @@ where fn addresses_to_publish(&self) -> impl Iterator { let peer_id: Multihash = self.network.local_peer_id().into(); let publish_non_global_ips = self.publish_non_global_ips; - self.network - .external_addresses() - .into_iter() - .filter(move |a| { - if publish_non_global_ips { - return true - } + let addresses = self.network.external_addresses().into_iter().filter(move |a| { + if publish_non_global_ips { + return true + } - a.iter().all(|p| match p { - // The `ip_network` library is used because its `is_global()` method is stable, - // while `is_global()` in the standard library currently isn't. - multiaddr::Protocol::Ip4(ip) if !IpNetwork::from(ip).is_global() => false, - multiaddr::Protocol::Ip6(ip) if !IpNetwork::from(ip).is_global() => false, - _ => true, - }) - }) - .map(move |a| { - if a.iter().any(|p| matches!(p, multiaddr::Protocol::P2p(_))) { - a - } else { - a.with(multiaddr::Protocol::P2p(peer_id)) - } + a.iter().all(|p| match p { + // The `ip_network` library is used because its `is_global()` method is stable, + // while `is_global()` in the standard library currently isn't. + multiaddr::Protocol::Ip4(ip) if !IpNetwork::from(ip).is_global() => false, + multiaddr::Protocol::Ip6(ip) if !IpNetwork::from(ip).is_global() => false, + _ => true, }) + }); + + debug!(target: LOG_TARGET, "Authority DHT record peer_id='{:?}' addresses='{:?}'", peer_id, addresses.clone().collect::>()); + + // The address must include the peer id if not already set. + addresses.map(move |a| { + if a.iter().any(|p| matches!(p, multiaddr::Protocol::P2p(_))) { + a + } else { + a.with(multiaddr::Protocol::P2p(peer_id)) + } + }) } /// Publish own public addresses. -- GitLab From bbd51ce867967f71657b901f1a956ad4f75d352e Mon Sep 17 00:00:00 2001 From: georgepisaltu <52418509+georgepisaltu@users.noreply.github.com> Date: Wed, 13 Mar 2024 16:10:59 +0200 Subject: [PATCH 392/392] Revert "FRAME: Create `TransactionExtension` as a replacement for `SignedExtension` (#2280)" (#3665) This PR reverts #2280 which introduced `TransactionExtension` to replace `SignedExtension`. As a result of the discussion [here](https://github.com/paritytech/polkadot-sdk/pull/3623#issuecomment-1986789700), the changes will be reverted for now with plans to reintroduce the concept in the future. --------- Signed-off-by: georgepisaltu --- Cargo.lock | 35 +- bridges/bin/runtime-common/Cargo.toml | 1 - bridges/bin/runtime-common/src/lib.rs | 72 +- bridges/bin/runtime-common/src/mock.rs | 2 +- .../runtime-common/src/priority_calculator.rs | 11 +- .../src/refund_relayer_extension.rs | 154 +- .../chain-bridge-hub-cumulus/src/lib.rs | 4 +- .../chain-bridge-hub-rococo/src/lib.rs | 2 +- bridges/primitives/chain-kusama/src/lib.rs | 4 +- .../chain-polkadot-bulletin/src/lib.rs | 51 +- bridges/primitives/chain-polkadot/src/lib.rs | 4 +- bridges/primitives/chain-rococo/src/lib.rs | 4 +- bridges/primitives/chain-westend/src/lib.rs | 4 +- bridges/primitives/polkadot-core/src/lib.rs | 37 +- bridges/primitives/runtime/src/extensions.rs | 135 +- .../snowbridge/runtime/test-common/Cargo.toml | 1 - .../assets/asset-hub-rococo/Cargo.toml | 2 - .../assets/asset-hub-rococo/src/lib.rs | 77 +- .../src/weights/frame_system_extensions.rs | 121 -- .../asset-hub-rococo/src/weights/mod.rs | 3 - .../pallet_asset_conversion_tx_payment.rs | 92 - .../src/weights/pallet_transaction_payment.rs | 67 - .../assets/asset-hub-westend/Cargo.toml | 2 - .../assets/asset-hub-westend/src/lib.rs | 77 +- .../src/weights/frame_system_extensions.rs | 121 -- .../asset-hub-westend/src/weights/mod.rs | 3 - .../pallet_asset_conversion_tx_payment.rs | 92 - .../src/weights/pallet_transaction_payment.rs | 67 - .../bridge-hubs/bridge-hub-rococo/Cargo.toml | 1 - .../src/bridge_to_bulletin_config.rs | 4 +- .../src/bridge_to_westend_config.rs | 4 +- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 27 +- .../src/weights/frame_system_extensions.rs | 121 -- .../bridge-hub-rococo/src/weights/mod.rs | 2 - .../src/weights/pallet_transaction_payment.rs | 67 - .../bridge-hub-rococo/tests/snowbridge.rs | 8 +- .../bridge-hub-rococo/tests/tests.rs | 11 +- .../bridge-hubs/bridge-hub-westend/Cargo.toml | 1 - .../src/bridge_to_rococo_config.rs | 4 +- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 25 +- .../src/weights/frame_system_extensions.rs | 121 -- .../bridge-hub-westend/src/weights/mod.rs | 2 - .../src/weights/pallet_transaction_payment.rs | 67 - .../bridge-hub-westend/tests/tests.rs | 11 +- .../collectives-westend/Cargo.toml | 1 - .../collectives-westend/src/lib.rs | 12 +- .../src/weights/frame_system_extensions.rs | 121 -- .../collectives-westend/src/weights/mod.rs | 2 - .../src/weights/pallet_transaction_payment.rs | 67 - .../contracts/contracts-rococo/Cargo.toml | 1 - .../contracts/contracts-rococo/src/lib.rs | 10 +- .../coretime/coretime-rococo/Cargo.toml | 1 - .../coretime/coretime-rococo/src/lib.rs | 9 +- .../src/weights/frame_system_extensions.rs | 121 -- .../coretime-rococo/src/weights/mod.rs | 2 - .../src/weights/pallet_transaction_payment.rs | 67 - .../coretime/coretime-westend/Cargo.toml | 1 - .../coretime/coretime-westend/src/lib.rs | 9 +- .../src/weights/frame_system_extensions.rs | 121 -- .../coretime-westend/src/weights/mod.rs | 2 - .../src/weights/pallet_transaction_payment.rs | 67 - .../glutton/glutton-westend/src/lib.rs | 9 +- .../src/weights/frame_system_extensions.rs | 119 -- .../runtimes/people/people-rococo/Cargo.toml | 1 - .../runtimes/people/people-rococo/src/lib.rs | 9 +- .../src/weights/frame_system_extensions.rs | 121 -- .../people/people-rococo/src/weights/mod.rs | 2 - .../src/weights/pallet_transaction_payment.rs | 67 - .../runtimes/people/people-westend/Cargo.toml | 1 - .../runtimes/people/people-westend/src/lib.rs | 8 +- .../src/weights/frame_system_extensions.rs | 121 -- .../people/people-westend/src/weights/mod.rs | 2 - .../src/weights/pallet_transaction_payment.rs | 67 - .../runtimes/starters/seedling/src/lib.rs | 6 +- .../runtimes/starters/shell/src/lib.rs | 64 +- .../runtimes/testing/penpal/Cargo.toml | 1 - .../runtimes/testing/penpal/src/lib.rs | 26 +- .../testing/rococo-parachain/Cargo.toml | 1 - .../testing/rococo-parachain/src/lib.rs | 7 +- cumulus/polkadot-parachain/Cargo.toml | 1 - .../storage-weight-reclaim/Cargo.toml | 13 +- .../src/benchmarking.rs | 70 - .../storage-weight-reclaim/src/lib.rs | 522 ++++- .../storage-weight-reclaim/src/tests.rs | 484 ----- cumulus/test/client/Cargo.toml | 2 - cumulus/test/client/src/lib.rs | 13 +- cumulus/test/runtime/src/lib.rs | 9 +- cumulus/test/service/Cargo.toml | 2 - cumulus/test/service/src/bench_utils.rs | 4 +- cumulus/test/service/src/lib.rs | 9 +- .../src/reference_docs/extrinsic_encoding.rs | 101 +- .../src/reference_docs/frame_runtime_types.rs | 2 +- docs/sdk/src/reference_docs/mod.rs | 4 +- .../src/reference_docs/signed_extensions.rs | 79 + .../reference_docs/transaction_extensions.rs | 57 - polkadot/node/service/Cargo.toml | 1 - polkadot/node/service/src/benchmarking.rs | 18 +- polkadot/node/test/service/Cargo.toml | 1 - polkadot/node/test/service/src/lib.rs | 11 +- polkadot/runtime/common/Cargo.toml | 1 - polkadot/runtime/common/src/claims.rs | 150 +- polkadot/runtime/rococo/Cargo.toml | 1 - .../constants/src/weights/block_weights.rs | 29 +- .../src/weights/extrinsic_weights.rs | 29 +- polkadot/runtime/rococo/src/lib.rs | 45 +- .../weights/frame_benchmarking_baseline.rs | 43 +- .../rococo/src/weights/frame_system.rs | 103 +- .../src/weights/frame_system_extensions.rs | 123 -- polkadot/runtime/rococo/src/weights/mod.rs | 2 - .../rococo/src/weights/pallet_asset_rate.rs | 63 +- .../src/weights/pallet_balances_balances.rs | 58 +- ...allet_balances_nis_counterpart_balances.rs | 58 +- .../rococo/src/weights/pallet_bounties.rs | 218 +-- .../src/weights/pallet_child_bounties.rs | 181 +- .../src/weights/pallet_conviction_voting.rs | 196 +- .../rococo/src/weights/pallet_identity.rs | 409 ++-- .../rococo/src/weights/pallet_indices.rs | 73 +- .../src/weights/pallet_message_queue.rs | 168 +- .../rococo/src/weights/pallet_multisig.rs | 123 +- .../runtime/rococo/src/weights/pallet_nis.rs | 243 +-- .../rococo/src/weights/pallet_preimage.rs | 252 ++- .../rococo/src/weights/pallet_proxy.rs | 195 +- .../src/weights/pallet_ranked_collective.rs | 66 +- .../rococo/src/weights/pallet_recovery.rs | 186 -- .../pallet_referenda_fellowship_referenda.rs | 235 ++- .../src/weights/pallet_referenda_referenda.rs | 283 +-- .../rococo/src/weights/pallet_scheduler.rs | 146 +- .../runtime/rococo/src/weights/pallet_sudo.rs | 45 +- .../rococo/src/weights/pallet_timestamp.rs | 35 +- .../src/weights/pallet_transaction_payment.rs | 68 - .../rococo/src/weights/pallet_treasury.rs | 233 +-- .../rococo/src/weights/pallet_utility.rs | 47 +- .../rococo/src/weights/pallet_vesting.rs | 254 ++- .../rococo/src/weights/pallet_whitelist.rs | 68 +- .../runtime/rococo/src/weights/pallet_xcm.rs | 90 +- .../weights/pallet_xcm_benchmarks_fungible.rs | 191 -- .../weights/pallet_xcm_benchmarks_generic.rs | 347 ---- .../weights/runtime_common_assigned_slots.rs | 70 +- .../src/weights/runtime_common_auctions.rs | 137 +- .../src/weights/runtime_common_claims.rs | 180 +- .../src/weights/runtime_common_coretime.rs | 86 - .../src/weights/runtime_common_crowdloan.rs | 239 +-- .../runtime_common_identity_migrator.rs | 83 +- .../weights/runtime_common_paras_registrar.rs | 281 +-- .../src/weights/runtime_common_slots.rs | 127 +- .../runtime_parachains_assigner_on_demand.rs | 50 +- .../runtime_parachains_configuration.rs | 48 +- .../weights/runtime_parachains_disputes.rs | 23 +- .../src/weights/runtime_parachains_hrmp.rs | 389 ++-- .../weights/runtime_parachains_inclusion.rs | 45 +- .../weights/runtime_parachains_initializer.rs | 27 +- .../src/weights/runtime_parachains_paras.rs | 368 ++-- .../runtime_parachains_paras_inherent.rs | 429 ++--- polkadot/runtime/test-runtime/Cargo.toml | 1 - polkadot/runtime/test-runtime/src/lib.rs | 40 +- polkadot/runtime/westend/Cargo.toml | 1 - polkadot/runtime/westend/src/lib.rs | 25 +- .../src/weights/frame_system_extensions.rs | 116 -- polkadot/runtime/westend/src/weights/mod.rs | 2 - .../westend/src/weights/pallet_sudo.rs | 11 - .../src/weights/pallet_transaction_payment.rs | 65 - polkadot/xcm/xcm-builder/Cargo.toml | 1 - .../xcm/xcm-builder/src/tests/pay/mock.rs | 12 +- .../xcm/xcm-simulator/fuzzer/src/parachain.rs | 4 +- .../xcm-simulator/fuzzer/src/relay_chain.rs | 4 +- prdoc/pr_2280.prdoc | 144 -- prdoc/pr_3665.prdoc | 11 + substrate/.maintain/frame-weight-template.hbs | 2 +- substrate/bin/node/cli/Cargo.toml | 2 - .../bin/node/cli/benches/block_production.rs | 2 +- substrate/bin/node/cli/benches/executor.rs | 6 +- substrate/bin/node/cli/src/service.rs | 77 +- substrate/bin/node/cli/tests/basic.rs | 26 +- substrate/bin/node/cli/tests/fees.rs | 24 +- .../bin/node/cli/tests/submit_transaction.rs | 10 +- substrate/bin/node/runtime/Cargo.toml | 2 - substrate/bin/node/runtime/src/lib.rs | 165 +- substrate/bin/node/testing/src/bench.rs | 26 +- substrate/bin/node/testing/src/keyring.rs | 44 +- .../client/api/src/notifications/tests.rs | 7 +- substrate/client/db/benches/state_access.rs | 5 +- substrate/client/db/src/lib.rs | 262 +-- substrate/client/db/src/utils.rs | 11 +- .../network-gossip/src/state_machine.rs | 5 +- substrate/client/network/sync/src/blocks.rs | 7 +- substrate/client/transaction-pool/src/lib.rs | 9 +- substrate/frame/alliance/src/weights.rs | 1033 +++++----- .../frame/asset-conversion/src/weights.rs | 126 +- substrate/frame/asset-rate/src/weights.rs | 73 +- substrate/frame/assets/src/weights.rs | 841 ++++---- substrate/frame/babe/src/mock.rs | 5 +- substrate/frame/bags-list/src/weights.rs | 165 +- substrate/frame/balances/Cargo.toml | 1 - .../balances/src/tests/currency_tests.rs | 17 +- substrate/frame/balances/src/tests/mod.rs | 4 +- substrate/frame/balances/src/weights.rs | 98 +- substrate/frame/beefy/src/mock.rs | 6 +- substrate/frame/benchmarking/src/weights.rs | 81 +- substrate/frame/bounties/src/weights.rs | 405 ++-- substrate/frame/broker/src/weights.rs | 357 ++-- substrate/frame/child-bounties/src/weights.rs | 381 ++-- substrate/frame/collective/src/tests.rs | 2 +- substrate/frame/collective/src/weights.rs | 677 ++++--- substrate/frame/contracts/src/weights.rs | 265 +-- .../frame/conviction-voting/src/weights.rs | 405 ++-- .../frame/core-fellowship/src/weights.rs | 429 ++--- substrate/frame/democracy/src/weights.rs | 1093 ++++++----- .../election-provider-multi-phase/src/mock.rs | 2 +- .../src/unsigned.rs | 4 +- .../src/weights.rs | 517 +++-- .../test-staking-e2e/src/mock.rs | 4 +- substrate/frame/elections-phragmen/src/lib.rs | 2 +- .../frame/elections-phragmen/src/weights.rs | 655 ++++--- substrate/frame/examples/basic/src/lib.rs | 76 +- substrate/frame/examples/basic/src/tests.rs | 9 +- .../examples/offchain-worker/src/tests.rs | 22 +- substrate/frame/examples/tasks/src/weights.rs | 78 +- substrate/frame/executive/src/tests.rs | 225 +-- substrate/frame/fast-unstake/src/weights.rs | 473 +++-- substrate/frame/glutton/src/weights.rs | 249 +-- substrate/frame/grandpa/src/mock.rs | 9 +- substrate/frame/identity/src/weights.rs | 825 ++++---- substrate/frame/im-online/src/mock.rs | 4 +- substrate/frame/im-online/src/tests.rs | 4 +- substrate/frame/im-online/src/weights.rs | 85 +- substrate/frame/indices/src/weights.rs | 121 +- substrate/frame/lottery/src/weights.rs | 301 ++- substrate/frame/membership/src/weights.rs | 385 ++-- substrate/frame/message-queue/src/weights.rs | 247 ++- substrate/frame/migrations/src/weights.rs | 183 +- substrate/frame/multisig/src/weights.rs | 243 ++- .../nft-fractionalization/src/weights.rs | 209 +- substrate/frame/nfts/src/weights.rs | 1692 ++++++++--------- substrate/frame/nis/src/weights.rs | 429 ++--- .../frame/nomination-pools/src/weights.rs | 29 +- .../frame/offences/benchmarking/src/mock.rs | 2 +- substrate/frame/parameters/src/weights.rs | 38 +- substrate/frame/preimage/src/weights.rs | 332 ++-- substrate/frame/proxy/src/weights.rs | 377 ++-- .../frame/ranked-collective/src/weights.rs | 353 ++-- substrate/frame/recovery/src/weights.rs | 305 ++- substrate/frame/referenda/src/weights.rs | 1037 +++++----- substrate/frame/remark/src/weights.rs | 37 +- substrate/frame/safe-mode/src/weights.rs | 142 +- substrate/frame/salary/src/weights.rs | 217 +-- substrate/frame/sassafras/src/mock.rs | 5 +- substrate/frame/scheduler/src/weights.rs | 266 ++- substrate/frame/session/src/weights.rs | 117 +- substrate/frame/society/src/weights.rs | 974 +++------- substrate/frame/src/lib.rs | 6 +- substrate/frame/staking/src/weights.rs | 422 ++-- .../frame/state-trie-migration/src/lib.rs | 2 +- .../frame/state-trie-migration/src/weights.rs | 118 +- substrate/frame/sudo/src/benchmarking.rs | 29 +- substrate/frame/sudo/src/extension.rs | 78 +- substrate/frame/sudo/src/lib.rs | 4 +- substrate/frame/sudo/src/weights.rs | 71 +- .../src/construct_runtime/expand/inherent.rs | 18 +- .../src/construct_runtime/expand/metadata.rs | 6 +- .../src/construct_runtime/expand/origin.rs | 14 - substrate/frame/support/src/dispatch.rs | 29 +- substrate/frame/support/src/lib.rs | 8 +- .../frame/support/src/traits/dispatch.rs | 21 +- substrate/frame/support/src/traits/misc.rs | 13 +- .../support/src/transaction_extensions.rs | 89 - .../support/src/weights/block_weights.rs | 31 +- .../support/src/weights/extrinsic_weights.rs | 31 +- .../deprecated_where_block.stderr | 4 +- substrate/frame/support/test/tests/pallet.rs | 143 +- .../support/test/tests/pallet_instance.rs | 2 +- substrate/frame/support/test/tests/runtime.rs | 2 +- .../test/tests/runtime_legacy_ordering.rs | 4 +- .../system/benchmarking/src/extensions.rs | 213 --- .../frame/system/benchmarking/src/lib.rs | 1 - .../frame/system/benchmarking/src/mock.rs | 1 - .../system/src/extensions/check_genesis.rs | 33 +- .../system/src/extensions/check_mortality.rs | 83 +- .../src/extensions/check_non_zero_sender.rs | 95 +- .../system/src/extensions/check_nonce.rs | 184 +- .../src/extensions/check_spec_version.rs | 33 +- .../system/src/extensions/check_tx_version.rs | 32 +- .../system/src/extensions/check_weight.rs | 228 +-- substrate/frame/system/src/extensions/mod.rs | 3 - .../frame/system/src/extensions/weights.rs | 196 -- substrate/frame/system/src/lib.rs | 10 +- substrate/frame/system/src/offchain.rs | 22 +- substrate/frame/system/src/weights.rs | 249 ++- substrate/frame/timestamp/src/weights.rs | 65 +- substrate/frame/tips/src/weights.rs | 241 +-- .../frame/transaction-payment/Cargo.toml | 9 - .../asset-conversion-tx-payment/Cargo.toml | 12 - .../asset-conversion-tx-payment/README.md | 2 +- .../src/benchmarking.rs | 125 -- .../asset-conversion-tx-payment/src/lib.rs | 233 +-- .../asset-conversion-tx-payment/src/mock.rs | 70 +- .../asset-conversion-tx-payment/src/tests.rs | 150 +- .../src/weights.rs | 150 -- .../asset-tx-payment/Cargo.toml | 1 - .../asset-tx-payment/README.md | 2 +- .../asset-tx-payment/src/benchmarking.rs | 123 -- .../asset-tx-payment/src/lib.rs | 199 +- .../asset-tx-payment/src/mock.rs | 54 +- .../asset-tx-payment/src/tests.rs | 184 +- .../asset-tx-payment/src/weights.rs | 146 -- .../skip-feeless-payment/src/lib.rs | 111 +- .../skip-feeless-payment/src/mock.rs | 30 +- .../skip-feeless-payment/src/tests.rs | 5 +- .../transaction-payment/src/benchmarking.rs | 81 - .../frame/transaction-payment/src/lib.rs | 146 +- .../frame/transaction-payment/src/mock.rs | 10 - .../frame/transaction-payment/src/payment.rs | 56 +- .../frame/transaction-payment/src/tests.rs | 444 +++-- .../frame/transaction-payment/src/types.rs | 2 +- .../frame/transaction-payment/src/weights.rs | 92 - .../frame/transaction-storage/src/weights.rs | 185 +- substrate/frame/treasury/src/weights.rs | 348 ++-- substrate/frame/tx-pause/src/weights.rs | 38 +- substrate/frame/uniques/src/weights.rs | 368 ++-- substrate/frame/utility/src/weights.rs | 161 +- substrate/frame/vesting/src/weights.rs | 234 ++- substrate/frame/whitelist/src/weights.rs | 193 +- substrate/primitives/inherents/src/lib.rs | 4 +- substrate/primitives/metadata-ir/src/lib.rs | 2 +- substrate/primitives/metadata-ir/src/types.rs | 19 +- substrate/primitives/metadata-ir/src/v14.rs | 10 +- substrate/primitives/metadata-ir/src/v15.rs | 8 +- substrate/primitives/runtime/Cargo.toml | 2 - .../runtime/src/generic/checked_extrinsic.rs | 112 +- .../primitives/runtime/src/generic/mod.rs | 4 +- .../src/generic/unchecked_extrinsic.rs | 730 +++---- substrate/primitives/runtime/src/lib.rs | 19 +- substrate/primitives/runtime/src/testing.rs | 195 +- .../runtime/src/{traits/mod.rs => traits.rs} | 244 ++- .../as_transaction_extension.rs | 133 -- .../dispatch_transaction.rs | 141 -- .../src/traits/transaction_extension/mod.rs | 526 ----- .../runtime/src/transaction_validity.rs | 6 +- substrate/scripts/run_all_benchmarks.sh | 13 - substrate/test-utils/runtime/src/extrinsic.rs | 17 +- substrate/test-utils/runtime/src/lib.rs | 93 +- .../benchmarking-cli/src/pallet/template.hbs | 4 - .../frame/remote-externalities/src/lib.rs | 5 +- substrate/utils/frame/rpc/client/src/lib.rs | 8 +- templates/minimal/runtime/src/lib.rs | 4 +- templates/parachain/runtime/Cargo.toml | 2 - templates/parachain/runtime/src/lib.rs | 10 +- templates/solochain/node/Cargo.toml | 1 - templates/solochain/node/src/benchmarking.rs | 9 +- templates/solochain/runtime/Cargo.toml | 1 - templates/solochain/runtime/src/lib.rs | 12 +- 350 files changed, 15770 insertions(+), 24248 deletions(-) delete mode 100644 cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/frame_system_extensions.rs delete mode 100644 cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_asset_conversion_tx_payment.rs delete mode 100644 cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_transaction_payment.rs delete mode 100644 cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/frame_system_extensions.rs delete mode 100644 cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_asset_conversion_tx_payment.rs delete mode 100644 cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_transaction_payment.rs delete mode 100644 cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/frame_system_extensions.rs delete mode 100644 cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_transaction_payment.rs delete mode 100644 cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/frame_system_extensions.rs delete mode 100644 cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_transaction_payment.rs delete mode 100644 cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/frame_system_extensions.rs delete mode 100644 cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_transaction_payment.rs delete mode 100644 cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system_extensions.rs delete mode 100644 cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_transaction_payment.rs delete mode 100644 cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/frame_system_extensions.rs delete mode 100644 cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_transaction_payment.rs delete mode 100644 cumulus/parachains/runtimes/glutton/glutton-westend/src/weights/frame_system_extensions.rs delete mode 100644 cumulus/parachains/runtimes/people/people-rococo/src/weights/frame_system_extensions.rs delete mode 100644 cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_transaction_payment.rs delete mode 100644 cumulus/parachains/runtimes/people/people-westend/src/weights/frame_system_extensions.rs delete mode 100644 cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_transaction_payment.rs delete mode 100644 cumulus/primitives/storage-weight-reclaim/src/benchmarking.rs delete mode 100644 cumulus/primitives/storage-weight-reclaim/src/tests.rs create mode 100644 docs/sdk/src/reference_docs/signed_extensions.rs delete mode 100644 docs/sdk/src/reference_docs/transaction_extensions.rs delete mode 100644 polkadot/runtime/rococo/src/weights/frame_system_extensions.rs delete mode 100644 polkadot/runtime/rococo/src/weights/pallet_recovery.rs delete mode 100644 polkadot/runtime/rococo/src/weights/pallet_transaction_payment.rs delete mode 100644 polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_fungible.rs delete mode 100644 polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_generic.rs delete mode 100644 polkadot/runtime/rococo/src/weights/runtime_common_coretime.rs delete mode 100644 polkadot/runtime/westend/src/weights/frame_system_extensions.rs delete mode 100644 polkadot/runtime/westend/src/weights/pallet_transaction_payment.rs delete mode 100644 prdoc/pr_2280.prdoc create mode 100644 prdoc/pr_3665.prdoc delete mode 100644 substrate/frame/support/src/transaction_extensions.rs delete mode 100644 substrate/frame/system/benchmarking/src/extensions.rs delete mode 100644 substrate/frame/system/src/extensions/weights.rs delete mode 100644 substrate/frame/transaction-payment/asset-conversion-tx-payment/src/benchmarking.rs delete mode 100644 substrate/frame/transaction-payment/asset-conversion-tx-payment/src/weights.rs delete mode 100644 substrate/frame/transaction-payment/asset-tx-payment/src/benchmarking.rs delete mode 100644 substrate/frame/transaction-payment/asset-tx-payment/src/weights.rs delete mode 100644 substrate/frame/transaction-payment/src/benchmarking.rs delete mode 100644 substrate/frame/transaction-payment/src/weights.rs rename substrate/primitives/runtime/src/{traits/mod.rs => traits.rs} (94%) delete mode 100644 substrate/primitives/runtime/src/traits/transaction_extension/as_transaction_extension.rs delete mode 100644 substrate/primitives/runtime/src/traits/transaction_extension/dispatch_transaction.rs delete mode 100644 substrate/primitives/runtime/src/traits/transaction_extension/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 37c5a5177c0..8cbbbce209a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4046,13 +4046,11 @@ dependencies = [ "cumulus-primitives-proof-size-hostfunction", "cumulus-test-runtime", "docify 0.2.7", - "frame-benchmarking", "frame-support", "frame-system", "log", "parity-scale-codec", "scale-info", - "sp-core", "sp-io", "sp-runtime", "sp-std 14.0.0", @@ -5899,7 +5897,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29f9df8a11882c4e3335eb2d18a0137c505d9ca927470b0cac9c6f0ae07d28f7" dependencies = [ - "rustix 0.38.25", + "rustix 0.38.21", "windows-sys 0.48.0", ] @@ -6784,7 +6782,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi 0.3.2", - "rustix 0.38.25", + "rustix 0.38.21", "windows-sys 0.48.0", ] @@ -7792,9 +7790,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.11" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] name = "lioness" @@ -9040,7 +9038,6 @@ dependencies = [ name = "pallet-asset-conversion-tx-payment" version = "10.0.0" dependencies = [ - "frame-benchmarking", "frame-support", "frame-system", "pallet-asset-conversion", @@ -10989,7 +10986,6 @@ dependencies = [ name = "pallet-transaction-payment" version = "28.0.0" dependencies = [ - "frame-benchmarking", "frame-support", "frame-system", "pallet-balances", @@ -14251,7 +14247,7 @@ dependencies = [ "hex", "lazy_static", "procfs-core", - "rustix 0.38.25", + "rustix 0.38.21", ] [[package]] @@ -15376,14 +15372,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.25" +version = "0.38.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" dependencies = [ "bitflags 2.4.0", "errno", "libc", - "linux-raw-sys 0.4.11", + "linux-raw-sys 0.4.10", "windows-sys 0.48.0", ] @@ -18715,7 +18711,7 @@ dependencies = [ [[package]] name = "sp-crypto-ec-utils" version = "0.4.1" -source = "git+https://github.com/paritytech/polkadot-sdk#838a534da874cf6071fba1df07643c6c5b033ae0" +source = "git+https://github.com/paritytech/polkadot-sdk#82912acb33a9030c0ef3bf590a34fca09b72dc5f" dependencies = [ "ark-bls12-377", "ark-bls12-377-ext", @@ -19021,7 +19017,6 @@ dependencies = [ "sp-tracing 16.0.0", "sp-weights", "substrate-test-runtime-client", - "tuplex", "zstd 0.12.4", ] @@ -19070,7 +19065,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "11.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#838a534da874cf6071fba1df07643c6c5b033ae0" +source = "git+https://github.com/paritytech/polkadot-sdk#82912acb33a9030c0ef3bf590a34fca09b72dc5f" dependencies = [ "Inflector", "proc-macro-crate 1.3.1", @@ -20289,7 +20284,7 @@ dependencies = [ "cfg-if", "fastrand 2.0.0", "redox_syscall 0.4.1", - "rustix 0.38.25", + "rustix 0.38.21", "windows-sys 0.48.0", ] @@ -20308,7 +20303,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "rustix 0.38.25", + "rustix 0.38.21", "windows-sys 0.48.0", ] @@ -21154,12 +21149,6 @@ dependencies = [ "utf-8", ] -[[package]] -name = "tuplex" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "676ac81d5454c4dcf37955d34fa8626ede3490f744b86ca14a7b90168d2a08aa" - [[package]] name = "twox-hash" version = "1.6.3" diff --git a/bridges/bin/runtime-common/Cargo.toml b/bridges/bin/runtime-common/Cargo.toml index ee54f15f38b..fac88b20ca5 100644 --- a/bridges/bin/runtime-common/Cargo.toml +++ b/bridges/bin/runtime-common/Cargo.toml @@ -93,7 +93,6 @@ runtime-benchmarks = [ "pallet-bridge-messages/runtime-benchmarks", "pallet-bridge-parachains/runtime-benchmarks", "pallet-bridge-relayers/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", diff --git a/bridges/bin/runtime-common/src/lib.rs b/bridges/bin/runtime-common/src/lib.rs index 035077408c4..2722f6f1c6d 100644 --- a/bridges/bin/runtime-common/src/lib.rs +++ b/bridges/bin/runtime-common/src/lib.rs @@ -105,48 +105,43 @@ macro_rules! generate_bridge_reject_obsolete_headers_and_messages { ($call:ty, $account_id:ty, $($filter_call:ty),*) => { #[derive(Clone, codec::Decode, Default, codec::Encode, Eq, PartialEq, sp_runtime::RuntimeDebug, scale_info::TypeInfo)] pub struct BridgeRejectObsoleteHeadersAndMessages; - impl sp_runtime::traits::TransactionExtensionBase for BridgeRejectObsoleteHeadersAndMessages { + impl sp_runtime::traits::SignedExtension for BridgeRejectObsoleteHeadersAndMessages { const IDENTIFIER: &'static str = "BridgeRejectObsoleteHeadersAndMessages"; - type Implicit = (); - } - impl sp_runtime::traits::TransactionExtension<$call, Context> for BridgeRejectObsoleteHeadersAndMessages { + type AccountId = $account_id; + type Call = $call; + type AdditionalSigned = (); type Pre = (); - type Val = (); + + fn additional_signed(&self) -> sp_std::result::Result< + (), + sp_runtime::transaction_validity::TransactionValidityError, + > { + Ok(()) + } fn validate( &self, - origin: <$call as sp_runtime::traits::Dispatchable>::RuntimeOrigin, - call: &$call, - _info: &sp_runtime::traits::DispatchInfoOf<$call>, + _who: &Self::AccountId, + call: &Self::Call, + _info: &sp_runtime::traits::DispatchInfoOf, _len: usize, - _context: &mut Context, - _self_implicit: Self::Implicit, - _inherited_implication: &impl codec::Encode, - ) -> Result< - ( - sp_runtime::transaction_validity::ValidTransaction, - Self::Val, - <$call as sp_runtime::traits::Dispatchable>::RuntimeOrigin, - ), sp_runtime::transaction_validity::TransactionValidityError - > { - let tx_validity = sp_runtime::transaction_validity::ValidTransaction::default(); + ) -> sp_runtime::transaction_validity::TransactionValidity { + let valid = sp_runtime::transaction_validity::ValidTransaction::default(); $( - let call_filter_validity = <$filter_call as $crate::BridgeRuntimeFilterCall<$call>>::validate(call)?; - let tx_validity = tx_validity.combine_with(call_filter_validity); + let valid = valid + .combine_with(<$filter_call as $crate::BridgeRuntimeFilterCall<$call>>::validate(call)?); )* - Ok((tx_validity, (), origin)) + Ok(valid) } - fn prepare( + fn pre_dispatch( self, - _val: Self::Val, - _origin: &<$call as sp_runtime::traits::Dispatchable>::RuntimeOrigin, - _call: &$call, - _info: &sp_runtime::traits::DispatchInfoOf<$call>, - _len: usize, - _context: &Context, + who: &Self::AccountId, + call: &Self::Call, + info: &sp_runtime::traits::DispatchInfoOf, + len: usize, ) -> Result { - Ok(()) + self.validate(who, call, info, len).map(drop) } } }; @@ -155,14 +150,12 @@ macro_rules! generate_bridge_reject_obsolete_headers_and_messages { #[cfg(test)] mod tests { use crate::BridgeRuntimeFilterCall; - use codec::Encode; - use frame_support::assert_err; + use frame_support::{assert_err, assert_ok}; use sp_runtime::{ - traits::DispatchTransaction, + traits::SignedExtension, transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction}, }; - #[derive(Encode)] pub struct MockCall { data: u32, } @@ -213,20 +206,17 @@ mod tests { ); assert_err!( - BridgeRejectObsoleteHeadersAndMessages.validate_only((), &MockCall { data: 1 }, &(), 0), + BridgeRejectObsoleteHeadersAndMessages.validate(&(), &MockCall { data: 1 }, &(), 0), InvalidTransaction::Custom(1) ); assert_err!( - BridgeRejectObsoleteHeadersAndMessages.validate_only((), &MockCall { data: 2 }, &(), 0), + BridgeRejectObsoleteHeadersAndMessages.validate(&(), &MockCall { data: 2 }, &(), 0), InvalidTransaction::Custom(2) ); - assert_eq!( - BridgeRejectObsoleteHeadersAndMessages - .validate_only((), &MockCall { data: 3 }, &(), 0) - .unwrap() - .0, + assert_ok!( + BridgeRejectObsoleteHeadersAndMessages.validate(&(), &MockCall { data: 3 }, &(), 0), ValidTransaction { priority: 3, ..Default::default() } ) } diff --git a/bridges/bin/runtime-common/src/mock.rs b/bridges/bin/runtime-common/src/mock.rs index f147f1404f0..8877a4fd95c 100644 --- a/bridges/bin/runtime-common/src/mock.rs +++ b/bridges/bin/runtime-common/src/mock.rs @@ -164,7 +164,6 @@ impl pallet_balances::Config for TestRuntime { type AccountStore = System; } -#[derive_impl(pallet_transaction_payment::config_preludes::TestDefaultConfig as pallet_transaction_payment::DefaultConfig)] impl pallet_transaction_payment::Config for TestRuntime { type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; type OperationalFeeMultiplier = ConstU8<5>; @@ -177,6 +176,7 @@ impl pallet_transaction_payment::Config for TestRuntime { MinimumMultiplier, MaximumMultiplier, >; + type RuntimeEvent = RuntimeEvent; } impl pallet_bridge_grandpa::Config for TestRuntime { diff --git a/bridges/bin/runtime-common/src/priority_calculator.rs b/bridges/bin/runtime-common/src/priority_calculator.rs index 0c53018330e..a597fb9e2f4 100644 --- a/bridges/bin/runtime-common/src/priority_calculator.rs +++ b/bridges/bin/runtime-common/src/priority_calculator.rs @@ -169,15 +169,12 @@ mod integrity_tests { // nodes to the proof (x0.5 because we expect some nodes to be reused) let estimated_message_size = 512; // let's say all our messages have the same dispatch weight - let estimated_message_dispatch_weight = >::WeightInfo::message_dispatch_weight( - estimated_message_size - ); + let estimated_message_dispatch_weight = + Runtime::WeightInfo::message_dispatch_weight(estimated_message_size); // messages proof argument size is (for every message) messages size + some additional // trie nodes. Some of them are reused by different messages, so let's take 2/3 of default // "overhead" constant - let messages_proof_size = >::WeightInfo::expected_extra_storage_proof_size() + let messages_proof_size = Runtime::WeightInfo::expected_extra_storage_proof_size() .saturating_mul(2) .saturating_div(3) .saturating_add(estimated_message_size) @@ -185,7 +182,7 @@ mod integrity_tests { // finally we are able to estimate transaction size and weight let transaction_size = base_tx_size.saturating_add(messages_proof_size); - let transaction_weight = >::WeightInfo::receive_messages_proof_weight( + let transaction_weight = Runtime::WeightInfo::receive_messages_proof_weight( &PreComputedSize(transaction_size as _), messages as _, estimated_message_dispatch_weight.saturating_mul(messages), diff --git a/bridges/bin/runtime-common/src/refund_relayer_extension.rs b/bridges/bin/runtime-common/src/refund_relayer_extension.rs index b912f8445ac..bfcb82ad166 100644 --- a/bridges/bin/runtime-common/src/refund_relayer_extension.rs +++ b/bridges/bin/runtime-common/src/refund_relayer_extension.rs @@ -48,12 +48,9 @@ use pallet_transaction_payment::{Config as TransactionPaymentConfig, OnChargeTra use pallet_utility::{Call as UtilityCall, Config as UtilityConfig, Pallet as UtilityPallet}; use scale_info::TypeInfo; use sp_runtime::{ - traits::{ - AsSystemOriginSigner, DispatchInfoOf, Dispatchable, Get, PostDispatchInfoOf, - TransactionExtension, TransactionExtensionBase, ValidateResult, Zero, - }, + traits::{DispatchInfoOf, Dispatchable, Get, PostDispatchInfoOf, SignedExtension, Zero}, transaction_validity::{ - InvalidTransaction, TransactionPriority, TransactionValidityError, ValidTransactionBuilder, + TransactionPriority, TransactionValidity, TransactionValidityError, ValidTransactionBuilder, }, DispatchResult, FixedPointOperand, RuntimeDebug, }; @@ -242,8 +239,8 @@ pub enum RelayerAccountAction { Slash(AccountId, RewardsAccountParams), } -/// Everything common among our refund transaction extensions. -pub trait RefundTransactionExtension: +/// Everything common among our refund signed extensions. +pub trait RefundSignedExtension: 'static + Clone + Codec + sp_std::fmt::Debug + Default + Eq + PartialEq + Send + Sync + TypeInfo where >::BridgedChain: @@ -459,8 +456,8 @@ where } } -/// Adapter that allow implementing `sp_runtime::traits::TransactionExtension` for any -/// `RefundTransactionExtension`. +/// Adapter that allow implementing `sp_runtime::traits::SignedExtension` for any +/// `RefundSignedExtension`. #[derive( DefaultNoBound, CloneNoBound, @@ -471,13 +468,12 @@ where RuntimeDebugNoBound, TypeInfo, )] -pub struct RefundTransactionExtensionAdapter(T) +pub struct RefundSignedExtensionAdapter(T) where >::BridgedChain: Chain; -impl TransactionExtensionBase - for RefundTransactionExtensionAdapter +impl SignedExtension for RefundSignedExtensionAdapter where >::BridgedChain: Chain, @@ -487,35 +483,22 @@ where + MessagesCallSubType::Instance>, { const IDENTIFIER: &'static str = T::Id::STR; - type Implicit = (); -} - -impl TransactionExtension, Context> - for RefundTransactionExtensionAdapter -where - >::BridgedChain: - Chain, - CallOf: Dispatchable - + IsSubType, T::Runtime>> - + GrandpaCallSubType - + MessagesCallSubType::Instance>, - as Dispatchable>::RuntimeOrigin: - AsSystemOriginSigner> + Clone, -{ + type AccountId = AccountIdOf; + type Call = CallOf; + type AdditionalSigned = (); type Pre = Option>>; - type Val = Option; + + fn additional_signed(&self) -> Result<(), TransactionValidityError> { + Ok(()) + } fn validate( &self, - origin: as Dispatchable>::RuntimeOrigin, - call: &CallOf, - _info: &DispatchInfoOf>, + who: &Self::AccountId, + call: &Self::Call, + _info: &DispatchInfoOf, _len: usize, - _context: &mut Context, - _self_implicit: Self::Implicit, - _inherited_implication: &impl Encode, - ) -> ValidateResult> { - let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?; + ) -> TransactionValidity { // this is the only relevant line of code for the `pre_dispatch` // // we're not calling `validate` from `pre_dispatch` directly because of performance @@ -528,12 +511,12 @@ where // we only boost priority of presumably correct message delivery transactions let bundled_messages = match T::bundled_messages_for_priority_boost(parsed_call.as_ref()) { Some(bundled_messages) => bundled_messages, - None => return Ok((Default::default(), parsed_call, origin)), + None => return Ok(Default::default()), }; // we only boost priority if relayer has staked required balance if !RelayersPallet::::is_registration_active(who) { - return Ok((Default::default(), parsed_call, origin)) + return Ok(Default::default()) } // compute priority boost @@ -552,21 +535,20 @@ where priority_boost, ); - let validity = valid_transaction.build()?; - Ok((validity, parsed_call, origin)) + valid_transaction.build() } - fn prepare( + fn pre_dispatch( self, - val: Self::Val, - origin: & as Dispatchable>::RuntimeOrigin, - _call: &CallOf, - _info: &DispatchInfoOf>, + who: &Self::AccountId, + call: &Self::Call, + _info: &DispatchInfoOf, _len: usize, - _context: &Context, ) -> Result { - let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?; - Ok(val.map(|call_info| { + // this is a relevant piece of `validate` that we need here (in `pre_dispatch`) + let parsed_call = T::parse_and_check_for_obsolete_call(call)?; + + Ok(parsed_call.map(|call_info| { log::trace!( target: "runtime::bridge", "{} via {:?} parsed bridge transaction in pre-dispatch: {:?}", @@ -579,14 +561,13 @@ where } fn post_dispatch( - pre: Self::Pre, - info: &DispatchInfoOf>, - post_info: &PostDispatchInfoOf>, + pre: Option, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, len: usize, result: &DispatchResult, - _context: &Context, ) -> Result<(), TransactionValidityError> { - let call_result = T::analyze_call_result(Some(pre), info, post_info, len, result); + let call_result = T::analyze_call_result(pre, info, post_info, len, result); match call_result { RelayerAccountAction::None => (), @@ -614,7 +595,7 @@ where } } -/// Transaction extension that refunds a relayer for new messages coming from a parachain. +/// Signed extension that refunds a relayer for new messages coming from a parachain. /// /// Also refunds relayer for successful finality delivery if it comes in batch (`utility.batchAll`) /// with message delivery transaction. Batch may deliver either both relay chain header and @@ -655,7 +636,7 @@ pub struct RefundBridgedParachainMessages, ); -impl RefundTransactionExtension +impl RefundSignedExtension for RefundBridgedParachainMessages where Self: 'static + Send + Sync, @@ -749,13 +730,13 @@ where } } -/// Transaction extension that refunds a relayer for new messages coming from a standalone (GRANDPA) +/// Signed extension that refunds a relayer for new messages coming from a standalone (GRANDPA) /// chain. /// /// Also refunds relayer for successful finality delivery if it comes in batch (`utility.batchAll`) /// with message delivery transaction. Batch may deliver either both relay chain header and -/// parachain head, or just parachain head. Corresponding headers must be used in messages proof -/// verification. +/// parachain head, or just parachain head. Corresponding headers must be used in messages +/// proof verification. /// /// Extension does not refund transaction tip due to security reasons. #[derive( @@ -790,7 +771,7 @@ pub struct RefundBridgedGrandpaMessages, ); -impl RefundTransactionExtension +impl RefundSignedExtension for RefundBridgedGrandpaMessages where Self: 'static + Send + Sync, @@ -888,8 +869,8 @@ mod tests { Call as ParachainsCall, Pallet as ParachainsPallet, RelayBlockHash, }; use sp_runtime::{ - traits::{ConstU64, DispatchTransaction, Header as HeaderT}, - transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction}, + traits::{ConstU64, Header as HeaderT}, + transaction_validity::{InvalidTransaction, ValidTransaction}, DispatchError, }; @@ -918,7 +899,7 @@ mod tests { ConstU64<1>, StrTestExtension, >; - type TestGrandpaExtension = RefundTransactionExtensionAdapter; + type TestGrandpaExtension = RefundSignedExtensionAdapter; type TestExtensionProvider = RefundBridgedParachainMessages< TestRuntime, DefaultRefundableParachainId<(), TestParachain>, @@ -927,7 +908,7 @@ mod tests { ConstU64<1>, StrTestExtension, >; - type TestExtension = RefundTransactionExtensionAdapter; + type TestExtension = RefundSignedExtensionAdapter; fn initial_balance_of_relayer_account_at_this_chain() -> ThisChainBalance { let test_stake: ThisChainBalance = TestStake::get(); @@ -1426,28 +1407,14 @@ mod tests { fn run_validate(call: RuntimeCall) -> TransactionValidity { let extension: TestExtension = - RefundTransactionExtensionAdapter(RefundBridgedParachainMessages(PhantomData)); - extension - .validate_only( - Some(relayer_account_at_this_chain()).into(), - &call, - &DispatchInfo::default(), - 0, - ) - .map(|res| res.0) + RefundSignedExtensionAdapter(RefundBridgedParachainMessages(PhantomData)); + extension.validate(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0) } fn run_grandpa_validate(call: RuntimeCall) -> TransactionValidity { let extension: TestGrandpaExtension = - RefundTransactionExtensionAdapter(RefundBridgedGrandpaMessages(PhantomData)); - extension - .validate_only( - Some(relayer_account_at_this_chain()).into(), - &call, - &DispatchInfo::default(), - 0, - ) - .map(|res| res.0) + RefundSignedExtensionAdapter(RefundBridgedGrandpaMessages(PhantomData)); + extension.validate(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0) } fn run_validate_ignore_priority(call: RuntimeCall) -> TransactionValidity { @@ -1461,30 +1428,16 @@ mod tests { call: RuntimeCall, ) -> Result>, TransactionValidityError> { let extension: TestExtension = - RefundTransactionExtensionAdapter(RefundBridgedParachainMessages(PhantomData)); - extension - .validate_and_prepare( - Some(relayer_account_at_this_chain()).into(), - &call, - &DispatchInfo::default(), - 0, - ) - .map(|(pre, _)| pre) + RefundSignedExtensionAdapter(RefundBridgedParachainMessages(PhantomData)); + extension.pre_dispatch(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0) } fn run_grandpa_pre_dispatch( call: RuntimeCall, ) -> Result>, TransactionValidityError> { let extension: TestGrandpaExtension = - RefundTransactionExtensionAdapter(RefundBridgedGrandpaMessages(PhantomData)); - extension - .validate_and_prepare( - Some(relayer_account_at_this_chain()).into(), - &call, - &DispatchInfo::default(), - 0, - ) - .map(|(pre, _)| pre) + RefundSignedExtensionAdapter(RefundBridgedGrandpaMessages(PhantomData)); + extension.pre_dispatch(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0) } fn dispatch_info() -> DispatchInfo { @@ -1507,12 +1460,11 @@ mod tests { dispatch_result: DispatchResult, ) { let post_dispatch_result = TestExtension::post_dispatch( - pre_dispatch_data, + Some(pre_dispatch_data), &dispatch_info(), &post_dispatch_info(), 1024, &dispatch_result, - &(), ); assert_eq!(post_dispatch_result, Ok(())); } diff --git a/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs b/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs index f186f6427ae..c49aa4b8563 100644 --- a/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs +++ b/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs @@ -26,7 +26,7 @@ pub use bp_polkadot_core::{ }; use bp_messages::*; -use bp_polkadot_core::SuffixedCommonTransactionExtension; +use bp_polkadot_core::SuffixedCommonSignedExtension; use bp_runtime::extensions::{ BridgeRejectObsoleteHeadersAndMessages, RefundBridgedParachainMessagesSchema, }; @@ -164,7 +164,7 @@ pub const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 1024; pub const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 4096; /// Signed extension that is used by all bridge hubs. -pub type TransactionExtension = SuffixedCommonTransactionExtension<( +pub type SignedExtension = SuffixedCommonSignedExtension<( BridgeRejectObsoleteHeadersAndMessages, RefundBridgedParachainMessagesSchema, )>; diff --git a/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs b/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs index 992ef1bd7a1..c4e697fbe95 100644 --- a/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs +++ b/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs @@ -107,5 +107,5 @@ frame_support::parameter_types! { /// Transaction fee that is paid at the Rococo BridgeHub for delivering single outbound message confirmation. /// (initially was calculated by test `BridgeHubRococo::can_calculate_fee_for_complex_message_confirmation_transaction` + `33%`) - pub const BridgeHubRococoBaseConfirmationFeeInRocs: u128 = 5_380_904_835; + pub const BridgeHubRococoBaseConfirmationFeeInRocs: u128 = 5_380_829_647; } diff --git a/bridges/primitives/chain-kusama/src/lib.rs b/bridges/primitives/chain-kusama/src/lib.rs index 253a1010e83..e3b4d0520f6 100644 --- a/bridges/primitives/chain-kusama/src/lib.rs +++ b/bridges/primitives/chain-kusama/src/lib.rs @@ -59,8 +59,8 @@ impl ChainWithGrandpa for Kusama { const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE; } -// The TransactionExtension used by Kusama. -pub use bp_polkadot_core::CommonTransactionExtension as TransactionExtension; +// The SignedExtension used by Kusama. +pub use bp_polkadot_core::CommonSignedExtension as SignedExtension; /// Name of the parachains pallet in the Kusama runtime. pub const PARAS_PALLET_NAME: &str = "Paras"; diff --git a/bridges/primitives/chain-polkadot-bulletin/src/lib.rs b/bridges/primitives/chain-polkadot-bulletin/src/lib.rs index 73dd122bd15..f2eebf93124 100644 --- a/bridges/primitives/chain-polkadot-bulletin/src/lib.rs +++ b/bridges/primitives/chain-polkadot-bulletin/src/lib.rs @@ -25,7 +25,7 @@ use bp_runtime::{ decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, extensions::{ CheckEra, CheckGenesis, CheckNonZeroSender, CheckNonce, CheckSpecVersion, CheckTxVersion, - CheckWeight, GenericTransactionExtension, GenericTransactionExtensionSchema, + CheckWeight, GenericSignedExtension, GenericSignedExtensionSchema, }, Chain, ChainId, TransactionEra, }; @@ -37,12 +37,7 @@ use frame_support::{ }; use frame_system::limits; use scale_info::TypeInfo; -use sp_runtime::{ - impl_tx_ext_default, - traits::{Dispatchable, TransactionExtensionBase}, - transaction_validity::TransactionValidityError, - Perbill, -}; +use sp_runtime::{traits::DispatchInfoOf, transaction_validity::TransactionValidityError, Perbill}; // This chain reuses most of Polkadot primitives. pub use bp_polkadot_core::{ @@ -76,10 +71,10 @@ pub const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 1024; pub const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 4096; /// This signed extension is used to ensure that the chain transactions are signed by proper -pub type ValidateSigned = GenericTransactionExtensionSchema<(), ()>; +pub type ValidateSigned = GenericSignedExtensionSchema<(), ()>; /// Signed extension schema, used by Polkadot Bulletin. -pub type TransactionExtensionSchema = GenericTransactionExtension<( +pub type SignedExtensionSchema = GenericSignedExtension<( ( CheckNonZeroSender, CheckSpecVersion, @@ -92,30 +87,34 @@ pub type TransactionExtensionSchema = GenericTransactionExtension<( ValidateSigned, )>; -/// Transaction extension, used by Polkadot Bulletin. +/// Signed extension, used by Polkadot Bulletin. #[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -pub struct TransactionExtension(TransactionExtensionSchema); +pub struct SignedExtension(SignedExtensionSchema); -impl TransactionExtensionBase for TransactionExtension { +impl sp_runtime::traits::SignedExtension for SignedExtension { const IDENTIFIER: &'static str = "Not needed."; - type Implicit = ::Implicit; + type AccountId = (); + type Call = (); + type AdditionalSigned = + ::AdditionalSigned; + type Pre = (); - fn implicit(&self) -> Result { - ::implicit(&self.0) + fn additional_signed(&self) -> Result { + self.0.additional_signed() } -} -impl sp_runtime::traits::TransactionExtension for TransactionExtension -where - C: Dispatchable, -{ - type Pre = (); - type Val = (); - - impl_tx_ext_default!(C; Context; validate prepare); + fn pre_dispatch( + self, + _who: &Self::AccountId, + _call: &Self::Call, + _info: &DispatchInfoOf, + _len: usize, + ) -> Result { + Ok(()) + } } -impl TransactionExtension { +impl SignedExtension { /// Create signed extension from its components. pub fn from_params( spec_version: u32, @@ -124,7 +123,7 @@ impl TransactionExtension { genesis_hash: Hash, nonce: Nonce, ) -> Self { - Self(GenericTransactionExtension::new( + Self(GenericSignedExtension::new( ( ( (), // non-zero sender diff --git a/bridges/primitives/chain-polkadot/src/lib.rs b/bridges/primitives/chain-polkadot/src/lib.rs index e5e2e7c3a04..fc5e10308a8 100644 --- a/bridges/primitives/chain-polkadot/src/lib.rs +++ b/bridges/primitives/chain-polkadot/src/lib.rs @@ -61,8 +61,8 @@ impl ChainWithGrandpa for Polkadot { const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE; } -/// The TransactionExtension used by Polkadot. -pub type TransactionExtension = SuffixedCommonTransactionExtension; +/// The SignedExtension used by Polkadot. +pub type SignedExtension = SuffixedCommonSignedExtension; /// Name of the parachains pallet in the Polkadot runtime. pub const PARAS_PALLET_NAME: &str = "Paras"; diff --git a/bridges/primitives/chain-rococo/src/lib.rs b/bridges/primitives/chain-rococo/src/lib.rs index 267c6b2b1f0..f1b256f0f09 100644 --- a/bridges/primitives/chain-rococo/src/lib.rs +++ b/bridges/primitives/chain-rococo/src/lib.rs @@ -59,8 +59,8 @@ impl ChainWithGrandpa for Rococo { const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE; } -// The TransactionExtension used by Rococo. -pub use bp_polkadot_core::CommonTransactionExtension as TransactionExtension; +// The SignedExtension used by Rococo. +pub use bp_polkadot_core::CommonSignedExtension as SignedExtension; /// Name of the parachains pallet in the Rococo runtime. pub const PARAS_PALLET_NAME: &str = "Paras"; diff --git a/bridges/primitives/chain-westend/src/lib.rs b/bridges/primitives/chain-westend/src/lib.rs index afa02e8ee54..f03fd2160a7 100644 --- a/bridges/primitives/chain-westend/src/lib.rs +++ b/bridges/primitives/chain-westend/src/lib.rs @@ -59,8 +59,8 @@ impl ChainWithGrandpa for Westend { const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE; } -// The TransactionExtension used by Westend. -pub use bp_polkadot_core::CommonTransactionExtension as TransactionExtension; +// The SignedExtension used by Westend. +pub use bp_polkadot_core::CommonSignedExtension as SignedExtension; /// Name of the parachains pallet in the Rococo runtime. pub const PARAS_PALLET_NAME: &str = "Paras"; diff --git a/bridges/primitives/polkadot-core/src/lib.rs b/bridges/primitives/polkadot-core/src/lib.rs index d59b99db4b5..df2836495bb 100644 --- a/bridges/primitives/polkadot-core/src/lib.rs +++ b/bridges/primitives/polkadot-core/src/lib.rs @@ -24,8 +24,8 @@ use bp_runtime::{ self, extensions::{ ChargeTransactionPayment, CheckEra, CheckGenesis, CheckNonZeroSender, CheckNonce, - CheckSpecVersion, CheckTxVersion, CheckWeight, GenericTransactionExtension, - TransactionExtensionSchema, + CheckSpecVersion, CheckTxVersion, CheckWeight, GenericSignedExtension, + SignedExtensionSchema, }, EncodedOrDecodedCall, StorageMapKeyProvider, TransactionEra, }; @@ -229,12 +229,8 @@ pub type SignedBlock = generic::SignedBlock; pub type Balance = u128; /// Unchecked Extrinsic type. -pub type UncheckedExtrinsic = generic::UncheckedExtrinsic< - AccountAddress, - EncodedOrDecodedCall, - Signature, - TransactionExt, ->; +pub type UncheckedExtrinsic = + generic::UncheckedExtrinsic, Signature, SignedExt>; /// Account address, used by the Polkadot-like chain. pub type Address = MultiAddress; @@ -279,7 +275,7 @@ impl AccountInfoStorageMapKeyProvider { } /// Extra signed extension data that is used by most chains. -pub type CommonTransactionExtra = ( +pub type CommonSignedExtra = ( CheckNonZeroSender, CheckSpecVersion, CheckTxVersion, @@ -290,12 +286,12 @@ pub type CommonTransactionExtra = ( ChargeTransactionPayment, ); -/// Extra transaction extension data that starts with `CommonTransactionExtra`. -pub type SuffixedCommonTransactionExtension = - GenericTransactionExtension<(CommonTransactionExtra, Suffix)>; +/// Extra signed extension data that starts with `CommonSignedExtra`. +pub type SuffixedCommonSignedExtension = + GenericSignedExtension<(CommonSignedExtra, Suffix)>; -/// Helper trait to define some extra methods on `SuffixedCommonTransactionExtension`. -pub trait SuffixedCommonTransactionExtensionExt { +/// Helper trait to define some extra methods on `SuffixedCommonSignedExtension`. +pub trait SuffixedCommonSignedExtensionExt { /// Create signed extension from its components. fn from_params( spec_version: u32, @@ -304,7 +300,7 @@ pub trait SuffixedCommonTransactionExtensionExt Self; /// Return transaction nonce. @@ -314,10 +310,9 @@ pub trait SuffixedCommonTransactionExtensionExt Balance; } -impl SuffixedCommonTransactionExtensionExt - for SuffixedCommonTransactionExtension +impl SuffixedCommonSignedExtensionExt for SuffixedCommonSignedExtension where - Suffix: TransactionExtensionSchema, + Suffix: SignedExtensionSchema, { fn from_params( spec_version: u32, @@ -326,9 +321,9 @@ where genesis_hash: Hash, nonce: Nonce, tip: Balance, - extra: (Suffix::Payload, Suffix::Implicit), + extra: (Suffix::Payload, Suffix::AdditionalSigned), ) -> Self { - GenericTransactionExtension::new( + GenericSignedExtension::new( ( ( (), // non-zero sender @@ -370,7 +365,7 @@ where } /// Signed extension that is used by most chains. -pub type CommonTransactionExtension = SuffixedCommonTransactionExtension<()>; +pub type CommonSignedExtension = SuffixedCommonSignedExtension<()>; #[cfg(test)] mod tests { diff --git a/bridges/primitives/runtime/src/extensions.rs b/bridges/primitives/runtime/src/extensions.rs index a31e7b5bb47..d896bc92eff 100644 --- a/bridges/primitives/runtime/src/extensions.rs +++ b/bridges/primitives/runtime/src/extensions.rs @@ -20,138 +20,135 @@ use codec::{Compact, Decode, Encode}; use impl_trait_for_tuples::impl_for_tuples; use scale_info::{StaticTypeInfo, TypeInfo}; use sp_runtime::{ - impl_tx_ext_default, - traits::{Dispatchable, TransactionExtension, TransactionExtensionBase}, + traits::{DispatchInfoOf, SignedExtension}, transaction_validity::TransactionValidityError, }; use sp_std::{fmt::Debug, marker::PhantomData}; -/// Trait that describes some properties of a `TransactionExtension` that are needed in order to -/// send a transaction to the chain. -pub trait TransactionExtensionSchema: - Encode + Decode + Debug + Eq + Clone + StaticTypeInfo -{ +/// Trait that describes some properties of a `SignedExtension` that are needed in order to send a +/// transaction to the chain. +pub trait SignedExtensionSchema: Encode + Decode + Debug + Eq + Clone + StaticTypeInfo { /// A type of the data encoded as part of the transaction. type Payload: Encode + Decode + Debug + Eq + Clone + StaticTypeInfo; /// Parameters which are part of the payload used to produce transaction signature, /// but don't end up in the transaction itself (i.e. inherent part of the runtime). - type Implicit: Encode + Decode + Debug + Eq + Clone + StaticTypeInfo; + type AdditionalSigned: Encode + Debug + Eq + Clone + StaticTypeInfo; } -impl TransactionExtensionSchema for () { +impl SignedExtensionSchema for () { type Payload = (); - type Implicit = (); + type AdditionalSigned = (); } -/// An implementation of `TransactionExtensionSchema` using generic params. +/// An implementation of `SignedExtensionSchema` using generic params. #[derive(Encode, Decode, Clone, Debug, PartialEq, Eq, TypeInfo)] -pub struct GenericTransactionExtensionSchema(PhantomData<(P, S)>); +pub struct GenericSignedExtensionSchema(PhantomData<(P, S)>); -impl TransactionExtensionSchema for GenericTransactionExtensionSchema +impl SignedExtensionSchema for GenericSignedExtensionSchema where P: Encode + Decode + Debug + Eq + Clone + StaticTypeInfo, - S: Encode + Decode + Debug + Eq + Clone + StaticTypeInfo, + S: Encode + Debug + Eq + Clone + StaticTypeInfo, { type Payload = P; - type Implicit = S; + type AdditionalSigned = S; } -/// The `TransactionExtensionSchema` for `frame_system::CheckNonZeroSender`. -pub type CheckNonZeroSender = GenericTransactionExtensionSchema<(), ()>; +/// The `SignedExtensionSchema` for `frame_system::CheckNonZeroSender`. +pub type CheckNonZeroSender = GenericSignedExtensionSchema<(), ()>; -/// The `TransactionExtensionSchema` for `frame_system::CheckSpecVersion`. -pub type CheckSpecVersion = GenericTransactionExtensionSchema<(), u32>; +/// The `SignedExtensionSchema` for `frame_system::CheckSpecVersion`. +pub type CheckSpecVersion = GenericSignedExtensionSchema<(), u32>; -/// The `TransactionExtensionSchema` for `frame_system::CheckTxVersion`. -pub type CheckTxVersion = GenericTransactionExtensionSchema<(), u32>; +/// The `SignedExtensionSchema` for `frame_system::CheckTxVersion`. +pub type CheckTxVersion = GenericSignedExtensionSchema<(), u32>; -/// The `TransactionExtensionSchema` for `frame_system::CheckGenesis`. -pub type CheckGenesis = GenericTransactionExtensionSchema<(), Hash>; +/// The `SignedExtensionSchema` for `frame_system::CheckGenesis`. +pub type CheckGenesis = GenericSignedExtensionSchema<(), Hash>; -/// The `TransactionExtensionSchema` for `frame_system::CheckEra`. -pub type CheckEra = GenericTransactionExtensionSchema; +/// The `SignedExtensionSchema` for `frame_system::CheckEra`. +pub type CheckEra = GenericSignedExtensionSchema; -/// The `TransactionExtensionSchema` for `frame_system::CheckNonce`. -pub type CheckNonce = GenericTransactionExtensionSchema, ()>; +/// The `SignedExtensionSchema` for `frame_system::CheckNonce`. +pub type CheckNonce = GenericSignedExtensionSchema, ()>; -/// The `TransactionExtensionSchema` for `frame_system::CheckWeight`. -pub type CheckWeight = GenericTransactionExtensionSchema<(), ()>; +/// The `SignedExtensionSchema` for `frame_system::CheckWeight`. +pub type CheckWeight = GenericSignedExtensionSchema<(), ()>; -/// The `TransactionExtensionSchema` for `pallet_transaction_payment::ChargeTransactionPayment`. -pub type ChargeTransactionPayment = - GenericTransactionExtensionSchema, ()>; +/// The `SignedExtensionSchema` for `pallet_transaction_payment::ChargeTransactionPayment`. +pub type ChargeTransactionPayment = GenericSignedExtensionSchema, ()>; -/// The `TransactionExtensionSchema` for `polkadot-runtime-common::PrevalidateAttests`. -pub type PrevalidateAttests = GenericTransactionExtensionSchema<(), ()>; +/// The `SignedExtensionSchema` for `polkadot-runtime-common::PrevalidateAttests`. +pub type PrevalidateAttests = GenericSignedExtensionSchema<(), ()>; -/// The `TransactionExtensionSchema` for `BridgeRejectObsoleteHeadersAndMessages`. -pub type BridgeRejectObsoleteHeadersAndMessages = GenericTransactionExtensionSchema<(), ()>; +/// The `SignedExtensionSchema` for `BridgeRejectObsoleteHeadersAndMessages`. +pub type BridgeRejectObsoleteHeadersAndMessages = GenericSignedExtensionSchema<(), ()>; -/// The `TransactionExtensionSchema` for `RefundBridgedParachainMessages`. +/// The `SignedExtensionSchema` for `RefundBridgedParachainMessages`. /// This schema is dedicated for `RefundBridgedParachainMessages` signed extension as /// wildcard/placeholder, which relies on the scale encoding for `()` or `((), ())`, or `((), (), /// ())` is the same. So runtime can contains any kind of tuple: /// `(BridgeRefundBridgeHubRococoMessages)` /// `(BridgeRefundBridgeHubRococoMessages, BridgeRefundBridgeHubWestendMessages)` /// `(BridgeRefundParachainMessages1, ..., BridgeRefundParachainMessagesN)` -pub type RefundBridgedParachainMessagesSchema = GenericTransactionExtensionSchema<(), ()>; +pub type RefundBridgedParachainMessagesSchema = GenericSignedExtensionSchema<(), ()>; #[impl_for_tuples(1, 12)] -impl TransactionExtensionSchema for Tuple { +impl SignedExtensionSchema for Tuple { for_tuples!( type Payload = ( #( Tuple::Payload ),* ); ); - for_tuples!( type Implicit = ( #( Tuple::Implicit ),* ); ); + for_tuples!( type AdditionalSigned = ( #( Tuple::AdditionalSigned ),* ); ); } /// A simplified version of signed extensions meant for producing signed transactions /// and signed payloads in the client code. #[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -pub struct GenericTransactionExtension { +pub struct GenericSignedExtension { /// A payload that is included in the transaction. pub payload: S::Payload, #[codec(skip)] // It may be set to `None` if extensions are decoded. We are never reconstructing transactions - // (and it makes no sense to do that) => decoded version of `TransactionExtensions` is only - // used to read fields of the `payload`. And when resigning transaction, we're reconstructing - // `TransactionExtensions` from scratch. - implicit: Option, + // (and it makes no sense to do that) => decoded version of `SignedExtensions` is only used to + // read fields of the `payload`. And when resigning transaction, we're reconstructing + // `SignedExtensions` from scratch. + additional_signed: Option, } -impl GenericTransactionExtension { - /// Create new `GenericTransactionExtension` object. - pub fn new(payload: S::Payload, implicit: Option) -> Self { - Self { payload, implicit } +impl GenericSignedExtension { + /// Create new `GenericSignedExtension` object. + pub fn new(payload: S::Payload, additional_signed: Option) -> Self { + Self { payload, additional_signed } } } -impl TransactionExtensionBase for GenericTransactionExtension +impl SignedExtension for GenericSignedExtension where - S: TransactionExtensionSchema, + S: SignedExtensionSchema, S::Payload: Send + Sync, - S::Implicit: Send + Sync, + S::AdditionalSigned: Send + Sync, { const IDENTIFIER: &'static str = "Not needed."; - type Implicit = S::Implicit; + type AccountId = (); + type Call = (); + type AdditionalSigned = S::AdditionalSigned; + type Pre = (); - fn implicit(&self) -> Result { + fn additional_signed(&self) -> Result { // we shall not ever see this error in relay, because we are never signing decoded // transactions. Instead we're constructing and signing new transactions. So the error code // is kinda random here - self.implicit - .clone() - .ok_or(frame_support::unsigned::TransactionValidityError::Unknown( + self.additional_signed.clone().ok_or( + frame_support::unsigned::TransactionValidityError::Unknown( frame_support::unsigned::UnknownTransaction::Custom(0xFF), - )) + ), + ) } -} -impl TransactionExtension for GenericTransactionExtension -where - C: Dispatchable, - S: TransactionExtensionSchema, - S::Payload: Send + Sync, - S::Implicit: Send + Sync, -{ - type Pre = (); - type Val = (); - impl_tx_ext_default!(C; Context; validate prepare); + fn pre_dispatch( + self, + _who: &Self::AccountId, + _call: &Self::Call, + _info: &DispatchInfoOf, + _len: usize, + ) -> Result { + Ok(()) + } } diff --git a/bridges/snowbridge/runtime/test-common/Cargo.toml b/bridges/snowbridge/runtime/test-common/Cargo.toml index 5f169e82f49..4e8b311cb97 100644 --- a/bridges/snowbridge/runtime/test-common/Cargo.toml +++ b/bridges/snowbridge/runtime/test-common/Cargo.toml @@ -181,7 +181,6 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml index 3eb63a24b74..05936e93993 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml @@ -119,7 +119,6 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", - "pallet-asset-conversion-tx-payment/runtime-benchmarks", "pallet-asset-conversion/runtime-benchmarks", "pallet-assets/runtime-benchmarks", "pallet-balances/runtime-benchmarks", @@ -131,7 +130,6 @@ runtime-benchmarks = [ "pallet-proxy/runtime-benchmarks", "pallet-state-trie-migration/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-uniques/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 32966ab6341..17a12dd2f6f 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -178,7 +178,6 @@ impl frame_system::Config for Runtime { type Version = Version; type AccountData = pallet_balances::AccountData; type SystemWeightInfo = weights::frame_system::WeightInfo; - type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; type SS58Prefix = SS58Prefix; type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; type MaxConsumers = frame_support::traits::ConstU32<16>; @@ -235,7 +234,6 @@ impl pallet_transaction_payment::Config for Runtime { type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; type OperationalFeeMultiplier = ConstU8<5>; - type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { @@ -763,9 +761,6 @@ impl pallet_asset_conversion_tx_payment::Config for Runtime { type Fungibles = LocalAndForeignAssets; type OnChargeAssetTransaction = AssetConversionAdapter; - type WeightInfo = weights::pallet_asset_conversion_tx_payment::WeightInfo; - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = AssetConversionTxHelper; } parameter_types! { @@ -953,8 +948,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The extension to the basic transaction logic. -pub type TxExtension = ( +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -966,7 +961,7 @@ pub type TxExtension = ( ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. pub type Migrations = ( pallet_collator_selection::migration::v1::MigrateToV1, @@ -1039,77 +1034,14 @@ pub type Executive = frame_executive::Executive< Migrations, >; -#[cfg(feature = "runtime-benchmarks")] -pub struct AssetConversionTxHelper; - -#[cfg(feature = "runtime-benchmarks")] -impl - pallet_asset_conversion_tx_payment::BenchmarkHelperTrait< - AccountId, - xcm::v3::MultiLocation, - xcm::v3::MultiLocation, - > for AssetConversionTxHelper -{ - fn create_asset_id_parameter(seed: u32) -> (xcm::v3::MultiLocation, xcm::v3::MultiLocation) { - // Use a different parachain' foreign assets pallet so that the asset is indeed foreign. - let asset_id = xcm::v3::MultiLocation::new( - 1, - xcm::v3::Junctions::X3( - xcm::v3::Junction::Parachain(3000), - xcm::v3::Junction::PalletInstance(53), - xcm::v3::Junction::GeneralIndex(seed.into()), - ), - ); - (asset_id, asset_id) - } - - fn setup_balances_and_pool(asset_id: xcm::v3::MultiLocation, account: AccountId) { - use frame_support::{assert_ok, traits::fungibles::Mutate}; - assert_ok!(ForeignAssets::force_create( - RuntimeOrigin::root(), - asset_id.into(), - account.clone().into(), /* owner */ - true, /* is_sufficient */ - 1, - )); - - let lp_provider = account.clone(); - use frame_support::traits::Currency; - let _ = Balances::deposit_creating(&lp_provider, u64::MAX.into()); - assert_ok!(ForeignAssets::mint_into(asset_id.into(), &lp_provider, u64::MAX.into())); - - let token_native = Box::new(TokenLocationV3::get()); - let token_second = Box::new(asset_id); - - assert_ok!(AssetConversion::create_pool( - RuntimeOrigin::signed(lp_provider.clone()), - token_native.clone(), - token_second.clone() - )); - - assert_ok!(AssetConversion::add_liquidity( - RuntimeOrigin::signed(lp_provider.clone()), - token_native, - token_second, - (u32::MAX / 8).into(), // 1 desired - u32::MAX.into(), // 2 desired - 1, // 1 min - 1, // 2 min - lp_provider, - )); - } -} - #[cfg(feature = "runtime-benchmarks")] mod benches { frame_benchmarking::define_benchmarks!( [frame_system, SystemBench::] - [frame_system_extensions, SystemExtensionsBench::] [pallet_assets, Local] [pallet_assets, Foreign] [pallet_assets, Pool] [pallet_asset_conversion, AssetConversion] - [pallet_asset_conversion_tx_payment, AssetTxPayment] [pallet_balances, Balances] [pallet_message_queue, MessageQueue] [pallet_multisig, Multisig] @@ -1120,7 +1052,6 @@ mod benches { [pallet_uniques, Uniques] [pallet_utility, Utility] [pallet_timestamp, Timestamp] - [pallet_transaction_payment, TransactionPayment] [pallet_collator_selection, CollatorSelection] [cumulus_pallet_parachain_system, ParachainSystem] [cumulus_pallet_xcmp_queue, XcmpQueue] @@ -1371,7 +1302,6 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; use pallet_xcm_bridge_hub_router::benchmarking::Pallet as XcmBridgeHubRouterBench; @@ -1406,7 +1336,6 @@ impl_runtime_apis! { use sp_storage::TrackedStorageKey; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; impl frame_system_benchmarking::Config for Runtime { fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/frame_system_extensions.rs deleted file mode 100644 index ed2c5f3056e..00000000000 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/frame_system_extensions.rs +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `frame_system_extensions` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-rococo-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=frame_system_extensions -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/ -// --chain=asset-hub-rococo-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `frame_system_extensions`. -pub struct WeightInfo(PhantomData); -impl frame_system::ExtensionsWeightInfo for WeightInfo { - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_genesis() -> Weight { - // Proof Size summary in bytes: - // Measured: `54` - // Estimated: `3509` - // Minimum execution time: 3_637_000 picoseconds. - Weight::from_parts(6_382_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_mortality() -> Weight { - // Proof Size summary in bytes: - // Measured: `92` - // Estimated: `3509` - // Minimum execution time: 5_841_000 picoseconds. - Weight::from_parts(8_776_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - fn check_non_zero_sender() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 561_000 picoseconds. - Weight::from_parts(2_705_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_nonce() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 3_316_000 picoseconds. - Weight::from_parts(5_771_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_spec_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 511_000 picoseconds. - Weight::from_parts(2_575_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_tx_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 501_000 picoseconds. - Weight::from_parts(2_595_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) - /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `System::BlockWeight` (r:1 w:1) - /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) - fn check_weight() -> Weight { - // Proof Size summary in bytes: - // Measured: `24` - // Estimated: `1533` - // Minimum execution time: 3_687_000 picoseconds. - Weight::from_parts(6_192_000, 0) - .saturating_add(Weight::from_parts(0, 1533)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) - } -} diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/mod.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/mod.rs index 134b5341a40..fa9e86102c6 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/mod.rs @@ -19,9 +19,7 @@ pub mod cumulus_pallet_parachain_system; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; -pub mod frame_system_extensions; pub mod pallet_asset_conversion; -pub mod pallet_asset_conversion_tx_payment; pub mod pallet_assets_foreign; pub mod pallet_assets_local; pub mod pallet_assets_pool; @@ -34,7 +32,6 @@ pub mod pallet_nfts; pub mod pallet_proxy; pub mod pallet_session; pub mod pallet_timestamp; -pub mod pallet_transaction_payment; pub mod pallet_uniques; pub mod pallet_utility; pub mod pallet_xcm; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_asset_conversion_tx_payment.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_asset_conversion_tx_payment.rs deleted file mode 100644 index 0a639b368af..00000000000 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_asset_conversion_tx_payment.rs +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `pallet_asset_conversion_tx_payment` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-01-04, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `Georges-MacBook-Pro.local`, CPU: `` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-rococo-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/debug/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=pallet_asset_conversion_tx_payment -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/ -// --chain=asset-hub-rococo-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `pallet_asset_conversion_tx_payment`. -pub struct WeightInfo(PhantomData); -impl pallet_asset_conversion_tx_payment::WeightInfo for WeightInfo { - fn charge_asset_tx_payment_zero() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(10_000_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:0) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn charge_asset_tx_payment_native() -> Weight { - // Proof Size summary in bytes: - // Measured: `4` - // Estimated: `3593` - // Minimum execution time: 209_000_000 picoseconds. - Weight::from_parts(212_000_000, 0) - .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(2)) - } - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `ForeignAssets::Asset` (r:1 w:1) - /// Proof: `ForeignAssets::Asset` (`max_values`: None, `max_size`: Some(808), added: 3283, mode: `MaxEncodedLen`) - /// Storage: `ForeignAssets::Account` (r:2 w:2) - /// Proof: `ForeignAssets::Account` (`max_values`: None, `max_size`: Some(732), added: 3207, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn charge_asset_tx_payment_asset() -> Weight { - // Proof Size summary in bytes: - // Measured: `631` - // Estimated: `7404` - // Minimum execution time: 1_228_000_000 picoseconds. - Weight::from_parts(1_268_000_000, 0) - .saturating_add(Weight::from_parts(0, 7404)) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(4)) - } -} diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_transaction_payment.rs deleted file mode 100644 index 035f9a6dbe5..00000000000 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_transaction_payment.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `pallet_transaction_payment` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-rococo-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=pallet_transaction_payment -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/ -// --chain=asset-hub-rococo-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `pallet_transaction_payment`. -pub struct WeightInfo(PhantomData); -impl pallet_transaction_payment::WeightInfo for WeightInfo { - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn charge_transaction_payment() -> Weight { - // Proof Size summary in bytes: - // Measured: `4` - // Estimated: `3593` - // Minimum execution time: 33_363_000 picoseconds. - Weight::from_parts(38_793_000, 0) - .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) - } -} diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml index c10e02bd8a6..78c48507a7a 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml @@ -110,7 +110,6 @@ runtime-benchmarks = [ "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", "hex-literal", - "pallet-asset-conversion-tx-payment/runtime-benchmarks", "pallet-asset-conversion/runtime-benchmarks", "pallet-assets/runtime-benchmarks", "pallet-balances/runtime-benchmarks", @@ -121,7 +120,6 @@ runtime-benchmarks = [ "pallet-nfts/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-uniques/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 5246828da31..1ead2897855 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -162,7 +162,6 @@ impl frame_system::Config for Runtime { type Version = Version; type AccountData = pallet_balances::AccountData; type SystemWeightInfo = weights::frame_system::WeightInfo; - type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; type SS58Prefix = SS58Prefix; type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; type MaxConsumers = frame_support::traits::ConstU32<16>; @@ -219,7 +218,6 @@ impl pallet_transaction_payment::Config for Runtime { type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; type OperationalFeeMultiplier = ConstU8<5>; - type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { @@ -737,9 +735,6 @@ impl pallet_asset_conversion_tx_payment::Config for Runtime { type Fungibles = LocalAndForeignAssets; type OnChargeAssetTransaction = AssetConversionAdapter; - type WeightInfo = weights::pallet_asset_conversion_tx_payment::WeightInfo; - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = AssetConversionTxHelper; } parameter_types! { @@ -925,8 +920,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The extension to the basic transaction logic. -pub type TxExtension = ( +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -938,7 +933,7 @@ pub type TxExtension = ( ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. pub type Migrations = ( @@ -1070,77 +1065,14 @@ pub type Executive = frame_executive::Executive< Migrations, >; -#[cfg(feature = "runtime-benchmarks")] -pub struct AssetConversionTxHelper; - -#[cfg(feature = "runtime-benchmarks")] -impl - pallet_asset_conversion_tx_payment::BenchmarkHelperTrait< - AccountId, - xcm::v3::MultiLocation, - xcm::v3::MultiLocation, - > for AssetConversionTxHelper -{ - fn create_asset_id_parameter(seed: u32) -> (xcm::v3::MultiLocation, xcm::v3::MultiLocation) { - // Use a different parachain' foreign assets pallet so that the asset is indeed foreign. - let asset_id = xcm::v3::MultiLocation::new( - 1, - xcm::v3::Junctions::X3( - xcm::v3::Junction::Parachain(3000), - xcm::v3::Junction::PalletInstance(53), - xcm::v3::Junction::GeneralIndex(seed.into()), - ), - ); - (asset_id, asset_id) - } - - fn setup_balances_and_pool(asset_id: xcm::v3::MultiLocation, account: AccountId) { - use frame_support::{assert_ok, traits::fungibles::Mutate}; - assert_ok!(ForeignAssets::force_create( - RuntimeOrigin::root(), - asset_id.into(), - account.clone().into(), /* owner */ - true, /* is_sufficient */ - 1, - )); - - let lp_provider = account.clone(); - use frame_support::traits::Currency; - let _ = Balances::deposit_creating(&lp_provider, u64::MAX.into()); - assert_ok!(ForeignAssets::mint_into(asset_id.into(), &lp_provider, u64::MAX.into())); - - let token_native = Box::new(xcm::v3::MultiLocation::new(1, xcm::v3::Junctions::Here)); - let token_second = Box::new(asset_id); - - assert_ok!(AssetConversion::create_pool( - RuntimeOrigin::signed(lp_provider.clone()), - token_native.clone(), - token_second.clone() - )); - - assert_ok!(AssetConversion::add_liquidity( - RuntimeOrigin::signed(lp_provider.clone()), - token_native, - token_second, - (u32::MAX / 2).into(), // 1 desired - u32::MAX.into(), // 2 desired - 1, // 1 min - 1, // 2 min - lp_provider, - )); - } -} - #[cfg(feature = "runtime-benchmarks")] mod benches { frame_benchmarking::define_benchmarks!( [frame_system, SystemBench::] - [frame_system_extensions, SystemExtensionsBench::] [pallet_assets, Local] [pallet_assets, Foreign] [pallet_assets, Pool] [pallet_asset_conversion, AssetConversion] - [pallet_asset_conversion_tx_payment, AssetTxPayment] [pallet_balances, Balances] [pallet_message_queue, MessageQueue] [pallet_multisig, Multisig] @@ -1151,7 +1083,6 @@ mod benches { [pallet_uniques, Uniques] [pallet_utility, Utility] [pallet_timestamp, Timestamp] - [pallet_transaction_payment, TransactionPayment] [pallet_collator_selection, CollatorSelection] [cumulus_pallet_parachain_system, ParachainSystem] [cumulus_pallet_xcmp_queue, XcmpQueue] @@ -1448,7 +1379,6 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; use pallet_xcm_bridge_hub_router::benchmarking::Pallet as XcmBridgeHubRouterBench; @@ -1483,7 +1413,6 @@ impl_runtime_apis! { use sp_storage::TrackedStorageKey; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; impl frame_system_benchmarking::Config for Runtime { fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/frame_system_extensions.rs deleted file mode 100644 index 46f4f2bfd96..00000000000 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/frame_system_extensions.rs +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `frame_system_extensions` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-westend-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=frame_system_extensions -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/ -// --chain=asset-hub-westend-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `frame_system_extensions`. -pub struct WeightInfo(PhantomData); -impl frame_system::ExtensionsWeightInfo for WeightInfo { - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_genesis() -> Weight { - // Proof Size summary in bytes: - // Measured: `54` - // Estimated: `3509` - // Minimum execution time: 3_206_000 picoseconds. - Weight::from_parts(6_212_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_mortality() -> Weight { - // Proof Size summary in bytes: - // Measured: `92` - // Estimated: `3509` - // Minimum execution time: 5_851_000 picoseconds. - Weight::from_parts(8_847_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - fn check_non_zero_sender() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 631_000 picoseconds. - Weight::from_parts(3_086_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_nonce() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 3_446_000 picoseconds. - Weight::from_parts(5_911_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_spec_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 481_000 picoseconds. - Weight::from_parts(2_916_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_tx_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 501_000 picoseconds. - Weight::from_parts(2_595_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) - /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `System::BlockWeight` (r:1 w:1) - /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) - fn check_weight() -> Weight { - // Proof Size summary in bytes: - // Measured: `24` - // Estimated: `1533` - // Minimum execution time: 3_927_000 picoseconds. - Weight::from_parts(6_613_000, 0) - .saturating_add(Weight::from_parts(0, 1533)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) - } -} diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs index 691ed2e5730..2f1fcfb05f3 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs @@ -18,9 +18,7 @@ pub mod cumulus_pallet_parachain_system; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; -pub mod frame_system_extensions; pub mod pallet_asset_conversion; -pub mod pallet_asset_conversion_tx_payment; pub mod pallet_assets_foreign; pub mod pallet_assets_local; pub mod pallet_assets_pool; @@ -33,7 +31,6 @@ pub mod pallet_nfts; pub mod pallet_proxy; pub mod pallet_session; pub mod pallet_timestamp; -pub mod pallet_transaction_payment; pub mod pallet_uniques; pub mod pallet_utility; pub mod pallet_xcm; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_asset_conversion_tx_payment.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_asset_conversion_tx_payment.rs deleted file mode 100644 index 8fe302630fb..00000000000 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_asset_conversion_tx_payment.rs +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `pallet_asset_conversion_tx_payment` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-01-04, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `Georges-MacBook-Pro.local`, CPU: `` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-westend-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/debug/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=pallet_asset_conversion_tx_payment -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/ -// --chain=asset-hub-westend-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `pallet_asset_conversion_tx_payment`. -pub struct WeightInfo(PhantomData); -impl pallet_asset_conversion_tx_payment::WeightInfo for WeightInfo { - fn charge_asset_tx_payment_zero() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 8_000_000 picoseconds. - Weight::from_parts(9_000_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:0) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn charge_asset_tx_payment_native() -> Weight { - // Proof Size summary in bytes: - // Measured: `4` - // Estimated: `3593` - // Minimum execution time: 214_000_000 picoseconds. - Weight::from_parts(219_000_000, 0) - .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(2)) - } - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `ForeignAssets::Asset` (r:1 w:1) - /// Proof: `ForeignAssets::Asset` (`max_values`: None, `max_size`: Some(808), added: 3283, mode: `MaxEncodedLen`) - /// Storage: `ForeignAssets::Account` (r:2 w:2) - /// Proof: `ForeignAssets::Account` (`max_values`: None, `max_size`: Some(732), added: 3207, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn charge_asset_tx_payment_asset() -> Weight { - // Proof Size summary in bytes: - // Measured: `631` - // Estimated: `7404` - // Minimum execution time: 1_211_000_000 picoseconds. - Weight::from_parts(1_243_000_000, 0) - .saturating_add(Weight::from_parts(0, 7404)) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(4)) - } -} diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_transaction_payment.rs deleted file mode 100644 index b4c78a78b48..00000000000 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_transaction_payment.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `pallet_transaction_payment` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-westend-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=pallet_transaction_payment -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/ -// --chain=asset-hub-westend-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `pallet_transaction_payment`. -pub struct WeightInfo(PhantomData); -impl pallet_transaction_payment::WeightInfo for WeightInfo { - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn charge_transaction_payment() -> Weight { - // Proof Size summary in bytes: - // Measured: `4` - // Estimated: `3593` - // Minimum execution time: 40_847_000 picoseconds. - Weight::from_parts(49_674_000, 0) - .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) - } -} diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml index 242627815d3..7a1951fd24b 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml @@ -242,7 +242,6 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm-bridge-hub/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs index 323e6ed65e6..6dbf96edc2a 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs @@ -40,7 +40,7 @@ use bridge_runtime_common::{ XcmBlobMessageDispatch, XcmVersionOfDestAndRemoteBridge, }, refund_relayer_extension::{ - ActualFeeRefund, RefundBridgedGrandpaMessages, RefundTransactionExtensionAdapter, + ActualFeeRefund, RefundBridgedGrandpaMessages, RefundSignedExtensionAdapter, RefundableMessagesLane, }, }; @@ -168,7 +168,7 @@ impl messages::BridgedChainWithMessages for RococoBulletin {} /// Signed extension that refunds relayers that are delivering messages from the Rococo Bulletin /// chain. -pub type OnBridgeHubRococoRefundRococoBulletinMessages = RefundTransactionExtensionAdapter< +pub type OnBridgeHubRococoRefundRococoBulletinMessages = RefundSignedExtensionAdapter< RefundBridgedGrandpaMessages< Runtime, BridgeGrandpaRococoBulletinInstance, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 05d1aa188d2..5d55d7afbac 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -39,7 +39,7 @@ use bridge_runtime_common::{ XcmBlobMessageDispatch, XcmVersionOfDestAndRemoteBridge, }, refund_relayer_extension::{ - ActualFeeRefund, RefundBridgedParachainMessages, RefundTransactionExtensionAdapter, + ActualFeeRefund, RefundBridgedParachainMessages, RefundSignedExtensionAdapter, RefundableMessagesLane, RefundableParachain, }, }; @@ -173,7 +173,7 @@ impl UnderlyingChainProvider for BridgeHubWestend { impl messages::BridgedChainWithMessages for BridgeHubWestend {} /// Signed extension that refunds relayers that are delivering messages from the Westend parachain. -pub type OnBridgeHubRococoRefundBridgeHubWestendMessages = RefundTransactionExtensionAdapter< +pub type OnBridgeHubRococoRefundBridgeHubWestendMessages = RefundSignedExtensionAdapter< RefundBridgedParachainMessages< Runtime, RefundableParachain< diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 16e3b2e8600..0b48d1717fa 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -115,8 +115,8 @@ pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The TransactionExtension to the basic transaction logic. -pub type TxExtension = ( +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -134,7 +134,7 @@ pub type TxExtension = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. pub type Migrations = ( @@ -262,8 +262,6 @@ impl frame_system::Config for Runtime { type DbWeight = RocksDbWeight; /// Weight information for the extrinsics of this pallet. type SystemWeightInfo = weights::frame_system::WeightInfo; - /// Weight information for the extensions of this pallet. - type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; /// Block & extrinsics weights: base values and limits. type BlockWeights = RuntimeBlockWeights; /// The maximum length of a block (in bytes). @@ -326,7 +324,6 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; - type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { @@ -762,14 +759,12 @@ bridge_runtime_common::generate_bridge_reject_obsolete_headers_and_messages! { mod benches { frame_benchmarking::define_benchmarks!( [frame_system, SystemBench::] - [frame_system_extensions, SystemExtensionsBench::] [pallet_balances, Balances] [pallet_message_queue, MessageQueue] [pallet_multisig, Multisig] [pallet_session, SessionBench::] [pallet_utility, Utility] [pallet_timestamp, Timestamp] - [pallet_transaction_payment, TransactionPayment] [pallet_collator_selection, CollatorSelection] [cumulus_pallet_parachain_system, ParachainSystem] [cumulus_pallet_xcmp_queue, XcmpQueue] @@ -1070,7 +1065,6 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; @@ -1101,7 +1095,6 @@ impl_runtime_apis! { use sp_storage::TrackedStorageKey; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; impl frame_system_benchmarking::Config for Runtime { fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); @@ -1485,16 +1478,16 @@ mod tests { use codec::Encode; use sp_runtime::{ generic::Era, - traits::{TransactionExtensionBase, Zero}, + traits::{SignedExtension, Zero}, }; #[test] fn ensure_signed_extension_definition_is_compatible_with_relay() { - use bp_polkadot_core::SuffixedCommonTransactionExtensionExt; + use bp_polkadot_core::SuffixedCommonSignedExtensionExt; sp_io::TestExternalities::default().execute_with(|| { frame_system::BlockHash::::insert(BlockNumber::zero(), Hash::default()); - let payload: TxExtension = ( + let payload: SignedExtra = ( frame_system::CheckNonZeroSender::new(), frame_system::CheckSpecVersion::new(), frame_system::CheckTxVersion::new(), @@ -1508,11 +1501,11 @@ mod tests { bridge_to_westend_config::OnBridgeHubRococoRefundBridgeHubWestendMessages::default(), bridge_to_bulletin_config::OnBridgeHubRococoRefundRococoBulletinMessages::default(), ) - ).into(); + ); // for BridgeHubRococo { - let bhr_indirect_payload = bp_bridge_hub_rococo::TransactionExtension::from_params( + let bhr_indirect_payload = bp_bridge_hub_rococo::SignedExtension::from_params( VERSION.spec_version, VERSION.transaction_version, bp_runtime::TransactionEra::Immortal, @@ -1523,8 +1516,8 @@ mod tests { ); assert_eq!(payload.encode(), bhr_indirect_payload.encode()); assert_eq!( - payload.implicit().unwrap().encode(), - bhr_indirect_payload.implicit().unwrap().encode() + payload.additional_signed().unwrap().encode(), + bhr_indirect_payload.additional_signed().unwrap().encode() ) } }); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/frame_system_extensions.rs deleted file mode 100644 index 99e3d6aeba0..00000000000 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/frame_system_extensions.rs +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `frame_system_extensions` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=frame_system_extensions -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/ -// --chain=bridge-hub-rococo-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `frame_system_extensions`. -pub struct WeightInfo(PhantomData); -impl frame_system::ExtensionsWeightInfo for WeightInfo { - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_genesis() -> Weight { - // Proof Size summary in bytes: - // Measured: `54` - // Estimated: `3509` - // Minimum execution time: 3_136_000 picoseconds. - Weight::from_parts(5_842_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_mortality() -> Weight { - // Proof Size summary in bytes: - // Measured: `92` - // Estimated: `3509` - // Minimum execution time: 5_771_000 picoseconds. - Weight::from_parts(8_857_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - fn check_non_zero_sender() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 732_000 picoseconds. - Weight::from_parts(2_875_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_nonce() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 3_627_000 picoseconds. - Weight::from_parts(6_322_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_spec_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 471_000 picoseconds. - Weight::from_parts(2_455_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_tx_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 491_000 picoseconds. - Weight::from_parts(2_916_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) - /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `System::BlockWeight` (r:1 w:1) - /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) - fn check_weight() -> Weight { - // Proof Size summary in bytes: - // Measured: `24` - // Estimated: `1533` - // Minimum execution time: 3_798_000 picoseconds. - Weight::from_parts(6_272_000, 0) - .saturating_add(Weight::from_parts(0, 1533)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) - } -} diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs index d97a30db954..aac39a4564f 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs @@ -25,7 +25,6 @@ pub mod cumulus_pallet_parachain_system; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; -pub mod frame_system_extensions; pub mod pallet_balances; pub mod pallet_bridge_grandpa; pub mod pallet_bridge_messages_rococo_to_rococo_bulletin; @@ -37,7 +36,6 @@ pub mod pallet_message_queue; pub mod pallet_multisig; pub mod pallet_session; pub mod pallet_timestamp; -pub mod pallet_transaction_payment; pub mod pallet_utility; pub mod pallet_xcm; pub mod paritydb_weights; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_transaction_payment.rs deleted file mode 100644 index 71d17e7259f..00000000000 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_transaction_payment.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `pallet_transaction_payment` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=pallet_transaction_payment -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/ -// --chain=bridge-hub-rococo-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `pallet_transaction_payment`. -pub struct WeightInfo(PhantomData); -impl pallet_transaction_payment::WeightInfo for WeightInfo { - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn charge_transaction_payment() -> Weight { - // Proof Size summary in bytes: - // Measured: `3` - // Estimated: `3593` - // Minimum execution time: 34_956_000 picoseconds. - Weight::from_parts(40_788_000, 0) - .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) - } -} diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs index 46c5df18a15..239bd946e75 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs @@ -22,7 +22,7 @@ use bridge_hub_rococo_runtime::{ bridge_to_westend_config::OnBridgeHubRococoRefundBridgeHubWestendMessages, xcm_config::XcmConfig, AllPalletsWithoutSystem, BridgeRejectObsoleteHeadersAndMessages, Executive, MessageQueueServiceWeight, Runtime, RuntimeCall, RuntimeEvent, SessionKeys, - TxExtension, UncheckedExtrinsic, + SignedExtra, UncheckedExtrinsic, }; use codec::{Decode, Encode}; use cumulus_primitives_core::XcmError::{FailedToTransactAsset, NotHoldingFees}; @@ -171,7 +171,7 @@ fn construct_extrinsic( call: RuntimeCall, ) -> UncheckedExtrinsic { let account_id = AccountId32::from(sender.public()); - let tx_ext: TxExtension = ( + let extra: SignedExtra = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -188,13 +188,13 @@ fn construct_extrinsic( OnBridgeHubRococoRefundRococoBulletinMessages::default(), ), ); - let payload = SignedPayload::new(call.clone(), tx_ext.clone()).unwrap(); + let payload = SignedPayload::new(call.clone(), extra.clone()).unwrap(); let signature = payload.using_encoded(|e| sender.sign(e)); UncheckedExtrinsic::new_signed( call, account_id.into(), Signature::Sr25519(signature.clone()), - tx_ext, + extra, ) } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs index 565343c55a5..f11954cf165 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs @@ -22,7 +22,7 @@ use bridge_hub_rococo_runtime::{ xcm_config::{RelayNetwork, TokenLocation, XcmConfig}, AllPalletsWithoutSystem, BridgeRejectObsoleteHeadersAndMessages, EthereumGatewayAddress, Executive, ExistentialDeposit, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, - RuntimeEvent, RuntimeOrigin, SessionKeys, TransactionPayment, TxExtension, UncheckedExtrinsic, + RuntimeEvent, RuntimeOrigin, SessionKeys, SignedExtra, TransactionPayment, UncheckedExtrinsic, }; use bridge_hub_test_utils::SlotDurations; use codec::{Decode, Encode}; @@ -48,7 +48,7 @@ fn construct_extrinsic( call: RuntimeCall, ) -> UncheckedExtrinsic { let account_id = AccountId32::from(sender.public()); - let tx_ext: TxExtension = ( + let extra: SignedExtra = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -64,15 +64,14 @@ fn construct_extrinsic( bridge_to_westend_config::OnBridgeHubRococoRefundBridgeHubWestendMessages::default(), bridge_to_bulletin_config::OnBridgeHubRococoRefundRococoBulletinMessages::default(), ), - ) - .into(); - let payload = SignedPayload::new(call.clone(), tx_ext.clone()).unwrap(); + ); + let payload = SignedPayload::new(call.clone(), extra.clone()).unwrap(); let signature = payload.using_encoded(|e| sender.sign(e)); UncheckedExtrinsic::new_signed( call, account_id.into(), Signature::Sr25519(signature.clone()), - tx_ext, + extra, ) } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml index b5fe093b8be..8623f7cb366 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml @@ -204,7 +204,6 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm-bridge-hub/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index 934dce5c2c4..bce722aa5f8 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -36,7 +36,7 @@ use bridge_runtime_common::{ XcmBlobMessageDispatch, XcmVersionOfDestAndRemoteBridge, }, refund_relayer_extension::{ - ActualFeeRefund, RefundBridgedParachainMessages, RefundTransactionExtensionAdapter, + ActualFeeRefund, RefundBridgedParachainMessages, RefundSignedExtensionAdapter, RefundableMessagesLane, RefundableParachain, }, }; @@ -190,7 +190,7 @@ impl ThisChainWithMessages for BridgeHubWestend { } /// Signed extension that refunds relayers that are delivering messages from the Rococo parachain. -pub type OnBridgeHubWestendRefundBridgeHubRococoMessages = RefundTransactionExtensionAdapter< +pub type OnBridgeHubWestendRefundBridgeHubRococoMessages = RefundSignedExtensionAdapter< RefundBridgedParachainMessages< Runtime, RefundableParachain, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 86ed8b2f488..e1344fce63d 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -97,8 +97,8 @@ pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The TransactionExtension to the basic transaction logic. -pub type TxExtension = ( +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -113,7 +113,7 @@ pub type TxExtension = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. pub type Migrations = ( @@ -298,7 +298,6 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; - type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { @@ -516,14 +515,12 @@ bridge_runtime_common::generate_bridge_reject_obsolete_headers_and_messages! { mod benches { frame_benchmarking::define_benchmarks!( [frame_system, SystemBench::] - [frame_system_extensions, SystemExtensionsBench::] [pallet_balances, Balances] [pallet_message_queue, MessageQueue] [pallet_multisig, Multisig] [pallet_session, SessionBench::] [pallet_utility, Utility] [pallet_timestamp, Timestamp] - [pallet_transaction_payment, TransactionPayment] [pallet_collator_selection, CollatorSelection] [cumulus_pallet_parachain_system, ParachainSystem] [cumulus_pallet_xcmp_queue, XcmpQueue] @@ -764,7 +761,6 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; @@ -794,7 +790,6 @@ impl_runtime_apis! { use sp_storage::TrackedStorageKey; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; impl frame_system_benchmarking::Config for Runtime { fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); @@ -1140,16 +1135,16 @@ mod tests { use codec::Encode; use sp_runtime::{ generic::Era, - traits::{TransactionExtensionBase, Zero}, + traits::{SignedExtension, Zero}, }; #[test] fn ensure_signed_extension_definition_is_compatible_with_relay() { - use bp_polkadot_core::SuffixedCommonTransactionExtensionExt; + use bp_polkadot_core::SuffixedCommonSignedExtensionExt; sp_io::TestExternalities::default().execute_with(|| { frame_system::BlockHash::::insert(BlockNumber::zero(), Hash::default()); - let payload: TxExtension = ( + let payload: SignedExtra = ( frame_system::CheckNonZeroSender::new(), frame_system::CheckSpecVersion::new(), frame_system::CheckTxVersion::new(), @@ -1162,10 +1157,10 @@ mod tests { ( bridge_to_rococo_config::OnBridgeHubWestendRefundBridgeHubRococoMessages::default(), ), - ).into(); + ); { - let bh_indirect_payload = bp_bridge_hub_westend::TransactionExtension::from_params( + let bh_indirect_payload = bp_bridge_hub_westend::SignedExtension::from_params( VERSION.spec_version, VERSION.transaction_version, bp_runtime::TransactionEra::Immortal, @@ -1176,8 +1171,8 @@ mod tests { ); assert_eq!(payload.encode(), bh_indirect_payload.encode()); assert_eq!( - payload.implicit().unwrap().encode(), - bh_indirect_payload.implicit().unwrap().encode() + payload.additional_signed().unwrap().encode(), + bh_indirect_payload.additional_signed().unwrap().encode() ) } }); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/frame_system_extensions.rs deleted file mode 100644 index 06f1114b4de..00000000000 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/frame_system_extensions.rs +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `frame_system_extensions` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-westend-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=frame_system_extensions -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/ -// --chain=bridge-hub-westend-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `frame_system_extensions`. -pub struct WeightInfo(PhantomData); -impl frame_system::ExtensionsWeightInfo for WeightInfo { - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_genesis() -> Weight { - // Proof Size summary in bytes: - // Measured: `54` - // Estimated: `3509` - // Minimum execution time: 3_166_000 picoseconds. - Weight::from_parts(6_021_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_mortality() -> Weight { - // Proof Size summary in bytes: - // Measured: `92` - // Estimated: `3509` - // Minimum execution time: 5_651_000 picoseconds. - Weight::from_parts(9_177_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - fn check_non_zero_sender() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 601_000 picoseconds. - Weight::from_parts(2_805_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_nonce() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 3_727_000 picoseconds. - Weight::from_parts(6_051_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_spec_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 471_000 picoseconds. - Weight::from_parts(2_494_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_tx_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 521_000 picoseconds. - Weight::from_parts(2_655_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) - /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `System::BlockWeight` (r:1 w:1) - /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) - fn check_weight() -> Weight { - // Proof Size summary in bytes: - // Measured: `24` - // Estimated: `1533` - // Minimum execution time: 3_808_000 picoseconds. - Weight::from_parts(6_402_000, 0) - .saturating_add(Weight::from_parts(0, 1533)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) - } -} diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/mod.rs index e23033e0dfd..a65ee31d3e5 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/mod.rs @@ -25,7 +25,6 @@ pub mod cumulus_pallet_parachain_system; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; -pub mod frame_system_extensions; pub mod pallet_balances; pub mod pallet_bridge_grandpa; pub mod pallet_bridge_messages; @@ -36,7 +35,6 @@ pub mod pallet_message_queue; pub mod pallet_multisig; pub mod pallet_session; pub mod pallet_timestamp; -pub mod pallet_transaction_payment; pub mod pallet_utility; pub mod pallet_xcm; pub mod paritydb_weights; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_transaction_payment.rs deleted file mode 100644 index 92c53b91879..00000000000 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_transaction_payment.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `pallet_transaction_payment` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-westend-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=pallet_transaction_payment -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/ -// --chain=bridge-hub-westend-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `pallet_transaction_payment`. -pub struct WeightInfo(PhantomData); -impl pallet_transaction_payment::WeightInfo for WeightInfo { - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn charge_transaction_payment() -> Weight { - // Proof Size summary in bytes: - // Measured: `3` - // Estimated: `3593` - // Minimum execution time: 40_286_000 picoseconds. - Weight::from_parts(45_816_000, 0) - .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) - } -} diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs index 7ea22befe95..149a3bbeb75 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs @@ -24,7 +24,7 @@ use bridge_hub_westend_runtime::{ xcm_config::{RelayNetwork, WestendLocation, XcmConfig}, AllPalletsWithoutSystem, BridgeRejectObsoleteHeadersAndMessages, Executive, ExistentialDeposit, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, - TransactionPayment, TxExtension, UncheckedExtrinsic, + SignedExtra, TransactionPayment, UncheckedExtrinsic, }; use bridge_to_rococo_config::{ BridgeGrandpaRococoInstance, BridgeHubRococoChainId, BridgeHubRococoLocation, @@ -65,7 +65,7 @@ fn construct_extrinsic( call: RuntimeCall, ) -> UncheckedExtrinsic { let account_id = AccountId32::from(sender.public()); - let tx_ext: TxExtension = ( + let extra: SignedExtra = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -78,15 +78,14 @@ fn construct_extrinsic( pallet_transaction_payment::ChargeTransactionPayment::::from(0), BridgeRejectObsoleteHeadersAndMessages::default(), (bridge_to_rococo_config::OnBridgeHubWestendRefundBridgeHubRococoMessages::default(),), - ) - .into(); - let payload = SignedPayload::new(call.clone(), tx_ext.clone()).unwrap(); + ); + let payload = SignedPayload::new(call.clone(), extra.clone()).unwrap(); let signature = payload.using_encoded(|e| sender.sign(e)); UncheckedExtrinsic::new_signed( call, account_id.into(), Signature::Sr25519(signature.clone()), - tx_ext, + extra, ) } diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml b/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml index 32d7e97bc45..ed264f28c26 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml @@ -117,7 +117,6 @@ runtime-benchmarks = [ "pallet-salary/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index 3887a1d74ec..6bcf98c428f 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -175,7 +175,6 @@ impl frame_system::Config for Runtime { type Version = Version; type AccountData = pallet_balances::AccountData; type SystemWeightInfo = weights::frame_system::WeightInfo; - type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; type SS58Prefix = ConstU16<0>; type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; type MaxConsumers = frame_support::traits::ConstU32<16>; @@ -232,7 +231,6 @@ impl pallet_transaction_payment::Config for Runtime { type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; type OperationalFeeMultiplier = ConstU8<5>; - type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { @@ -709,8 +707,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The extension to the basic transaction logic. -pub type TxExtension = ( +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -721,7 +719,7 @@ pub type TxExtension = ( ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// All migrations executed on runtime upgrade as a nested tuple of types implementing /// `OnRuntimeUpgrade`. Included migrations must be idempotent. type Migrations = ( @@ -747,7 +745,6 @@ pub type Executive = frame_executive::Executive< mod benches { frame_benchmarking::define_benchmarks!( [frame_system, SystemBench::] - [frame_system_extensions, SystemExtensionsBench::] [pallet_balances, Balances] [pallet_message_queue, MessageQueue] [pallet_multisig, Multisig] @@ -755,7 +752,6 @@ mod benches { [pallet_session, SessionBench::] [pallet_utility, Utility] [pallet_timestamp, Timestamp] - [pallet_transaction_payment, TransactionPayment] [pallet_collator_selection, CollatorSelection] [cumulus_pallet_parachain_system, ParachainSystem] [cumulus_pallet_xcmp_queue, XcmpQueue] @@ -959,7 +955,6 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; @@ -977,7 +972,6 @@ impl_runtime_apis! { use sp_storage::TrackedStorageKey; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; impl frame_system_benchmarking::Config for Runtime { fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/frame_system_extensions.rs deleted file mode 100644 index f3030cc4f6a..00000000000 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/frame_system_extensions.rs +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `frame_system_extensions` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("collectives-westend-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=frame_system_extensions -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/ -// --chain=collectives-westend-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `frame_system_extensions`. -pub struct WeightInfo(PhantomData); -impl frame_system::ExtensionsWeightInfo for WeightInfo { - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_genesis() -> Weight { - // Proof Size summary in bytes: - // Measured: `54` - // Estimated: `3509` - // Minimum execution time: 3_497_000 picoseconds. - Weight::from_parts(5_961_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_mortality() -> Weight { - // Proof Size summary in bytes: - // Measured: `92` - // Estimated: `3509` - // Minimum execution time: 5_240_000 picoseconds. - Weight::from_parts(8_175_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - fn check_non_zero_sender() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 671_000 picoseconds. - Weight::from_parts(3_005_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_nonce() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 3_426_000 picoseconds. - Weight::from_parts(6_131_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_spec_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 501_000 picoseconds. - Weight::from_parts(2_715_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_tx_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 491_000 picoseconds. - Weight::from_parts(2_635_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) - /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `System::BlockWeight` (r:1 w:1) - /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) - fn check_weight() -> Weight { - // Proof Size summary in bytes: - // Measured: `24` - // Estimated: `1533` - // Minimum execution time: 3_958_000 picoseconds. - Weight::from_parts(6_753_000, 0) - .saturating_add(Weight::from_parts(0, 1533)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) - } -} diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/mod.rs index 00b3bd92d5e..a9a298e547e 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/mod.rs @@ -18,7 +18,6 @@ pub mod cumulus_pallet_parachain_system; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; -pub mod frame_system_extensions; pub mod pallet_alliance; pub mod pallet_asset_rate; pub mod pallet_balances; @@ -40,7 +39,6 @@ pub mod pallet_salary_fellowship_salary; pub mod pallet_scheduler; pub mod pallet_session; pub mod pallet_timestamp; -pub mod pallet_transaction_payment; pub mod pallet_treasury; pub mod pallet_utility; pub mod pallet_xcm; diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_transaction_payment.rs deleted file mode 100644 index 5d077b89d56..00000000000 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_transaction_payment.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `pallet_transaction_payment` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("collectives-westend-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=pallet_transaction_payment -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/ -// --chain=collectives-westend-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `pallet_transaction_payment`. -pub struct WeightInfo(PhantomData); -impl pallet_transaction_payment::WeightInfo for WeightInfo { - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn charge_transaction_payment() -> Weight { - // Proof Size summary in bytes: - // Measured: `4` - // Estimated: `3593` - // Minimum execution time: 39_815_000 picoseconds. - Weight::from_parts(46_067_000, 0) - .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) - } -} diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml b/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml index 747f75cf2e2..dcc6c4e853a 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml @@ -158,7 +158,6 @@ runtime-benchmarks = [ "pallet-multisig/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "parachains-common/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index 8ce46ccd34f..0668b9a4c7d 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -80,8 +80,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The extension to the basic transaction logic. -pub type TxExtension = ( +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -93,7 +93,7 @@ pub type TxExtension = ( ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. pub type Migrations = ( @@ -240,7 +240,6 @@ impl pallet_transaction_payment::Config for Runtime { type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; type OperationalFeeMultiplier = ConstU8<5>; - type WeightInfo = pallet_transaction_payment::weights::SubstrateWeight; } parameter_types! { @@ -424,7 +423,6 @@ construct_runtime!( mod benches { frame_benchmarking::define_benchmarks!( [frame_system, SystemBench::] - [frame_system_extensions, SystemExtensionsBench::] [pallet_balances, Balances] [pallet_message_queue, MessageQueue] [pallet_multisig, Multisig] @@ -688,7 +686,6 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; @@ -706,7 +703,6 @@ impl_runtime_apis! { use sp_storage::TrackedStorageKey; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; impl frame_system_benchmarking::Config for Runtime { fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml index 70a6a81bdcf..0bc3b510ed5 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml @@ -156,7 +156,6 @@ runtime-benchmarks = [ "pallet-multisig/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index 9913e47a93a..cdff371c505 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -89,8 +89,8 @@ pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The TransactionExtension to the basic transaction logic. -pub type TxExtension = ( +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -103,7 +103,7 @@ pub type TxExtension = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. pub type Migrations = ( @@ -192,8 +192,6 @@ impl frame_system::Config for Runtime { type DbWeight = RocksDbWeight; /// Weight information for the extrinsics of this pallet. type SystemWeightInfo = weights::frame_system::WeightInfo; - /// Weight information for the extensions of this pallet. - type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; /// Block & extrinsics weights: base values and limits. type BlockWeights = RuntimeBlockWeights; /// The maximum length of a block (in bytes). @@ -253,7 +251,6 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; - type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system_extensions.rs deleted file mode 100644 index aac73680ad1..00000000000 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system_extensions.rs +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `frame_system_extensions` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=frame_system_extensions -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ -// --chain=coretime-rococo-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `frame_system_extensions`. -pub struct WeightInfo(PhantomData); -impl frame_system::ExtensionsWeightInfo for WeightInfo { - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_genesis() -> Weight { - // Proof Size summary in bytes: - // Measured: `54` - // Estimated: `3509` - // Minimum execution time: 3_637_000 picoseconds. - Weight::from_parts(6_382_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_mortality() -> Weight { - // Proof Size summary in bytes: - // Measured: `92` - // Estimated: `3509` - // Minimum execution time: 5_841_000 picoseconds. - Weight::from_parts(8_776_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - fn check_non_zero_sender() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 561_000 picoseconds. - Weight::from_parts(2_705_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_nonce() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 3_316_000 picoseconds. - Weight::from_parts(5_771_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_spec_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 511_000 picoseconds. - Weight::from_parts(2_575_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_tx_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 501_000 picoseconds. - Weight::from_parts(2_595_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) - /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `System::BlockWeight` (r:1 w:1) - /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) - fn check_weight() -> Weight { - // Proof Size summary in bytes: - // Measured: `24` - // Estimated: `1533` - // Minimum execution time: 3_687_000 picoseconds. - Weight::from_parts(6_192_000, 0) - .saturating_add(Weight::from_parts(0, 1533)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) - } -} diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/mod.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/mod.rs index 7b6ab611e6f..f1050b3ae63 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/mod.rs @@ -22,7 +22,6 @@ pub mod cumulus_pallet_parachain_system; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; -pub mod frame_system_extensions; pub mod pallet_balances; pub mod pallet_broker; pub mod pallet_collator_selection; @@ -30,7 +29,6 @@ pub mod pallet_message_queue; pub mod pallet_multisig; pub mod pallet_session; pub mod pallet_timestamp; -pub mod pallet_transaction_payment; pub mod pallet_utility; pub mod pallet_xcm; pub mod paritydb_weights; diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_transaction_payment.rs deleted file mode 100644 index 29d48abab89..00000000000 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_transaction_payment.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `pallet_transaction_payment` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=pallet_transaction_payment -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ -// --chain=coretime-rococo-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `pallet_transaction_payment`. -pub struct WeightInfo(PhantomData); -impl pallet_transaction_payment::WeightInfo for WeightInfo { - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn charge_transaction_payment() -> Weight { - // Proof Size summary in bytes: - // Measured: `4` - // Estimated: `3593` - // Minimum execution time: 33_363_000 picoseconds. - Weight::from_parts(38_793_000, 0) - .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) - } -} diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml b/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml index 549ef7ce4d7..a7d52dfd784 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml @@ -153,7 +153,6 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index 1a330821d3f..7fa70647992 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -89,8 +89,8 @@ pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The TransactionExtension to the basic transaction logic. -pub type TxExtension = ( +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -103,7 +103,7 @@ pub type TxExtension = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. pub type Migrations = ( @@ -192,8 +192,6 @@ impl frame_system::Config for Runtime { type DbWeight = RocksDbWeight; /// Weight information for the extrinsics of this pallet. type SystemWeightInfo = weights::frame_system::WeightInfo; - /// Weight information for the extensions of this pallet. - type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; /// Block & extrinsics weights: base values and limits. type BlockWeights = RuntimeBlockWeights; /// The maximum length of a block (in bytes). @@ -253,7 +251,6 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; - type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/frame_system_extensions.rs deleted file mode 100644 index 0683158a01a..00000000000 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/frame_system_extensions.rs +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `frame_system_extensions` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-westend-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=frame_system_extensions -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/ -// --chain=coretime-westend-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `frame_system_extensions`. -pub struct WeightInfo(PhantomData); -impl frame_system::ExtensionsWeightInfo for WeightInfo { - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_genesis() -> Weight { - // Proof Size summary in bytes: - // Measured: `54` - // Estimated: `3509` - // Minimum execution time: 3_637_000 picoseconds. - Weight::from_parts(6_382_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_mortality() -> Weight { - // Proof Size summary in bytes: - // Measured: `92` - // Estimated: `3509` - // Minimum execution time: 5_841_000 picoseconds. - Weight::from_parts(8_776_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - fn check_non_zero_sender() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 561_000 picoseconds. - Weight::from_parts(2_705_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_nonce() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 3_316_000 picoseconds. - Weight::from_parts(5_771_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_spec_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 511_000 picoseconds. - Weight::from_parts(2_575_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_tx_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 501_000 picoseconds. - Weight::from_parts(2_595_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) - /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `System::BlockWeight` (r:1 w:1) - /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) - fn check_weight() -> Weight { - // Proof Size summary in bytes: - // Measured: `24` - // Estimated: `1533` - // Minimum execution time: 3_687_000 picoseconds. - Weight::from_parts(6_192_000, 0) - .saturating_add(Weight::from_parts(0, 1533)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) - } -} diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/mod.rs index 7b6ab611e6f..f1050b3ae63 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/mod.rs @@ -22,7 +22,6 @@ pub mod cumulus_pallet_parachain_system; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; -pub mod frame_system_extensions; pub mod pallet_balances; pub mod pallet_broker; pub mod pallet_collator_selection; @@ -30,7 +29,6 @@ pub mod pallet_message_queue; pub mod pallet_multisig; pub mod pallet_session; pub mod pallet_timestamp; -pub mod pallet_transaction_payment; pub mod pallet_utility; pub mod pallet_xcm; pub mod paritydb_weights; diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_transaction_payment.rs deleted file mode 100644 index f159f877afe..00000000000 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_transaction_payment.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `pallet_transaction_payment` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-westend-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=pallet_transaction_payment -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/ -// --chain=coretime-westend-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `pallet_transaction_payment`. -pub struct WeightInfo(PhantomData); -impl pallet_transaction_payment::WeightInfo for WeightInfo { - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn charge_transaction_payment() -> Weight { - // Proof Size summary in bytes: - // Measured: `4` - // Estimated: `3593` - // Minimum execution time: 33_363_000 picoseconds. - Weight::from_parts(38_793_000, 0) - .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) - } -} diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs index 199057c3764..232a82115a8 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs @@ -289,8 +289,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The extension to the basic transaction logic. -pub type TxExtension = ( +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( pallet_sudo::CheckOnlySudoAccount, frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, @@ -301,7 +301,7 @@ pub type TxExtension = ( ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, @@ -316,7 +316,6 @@ mod benches { frame_benchmarking::define_benchmarks!( [cumulus_pallet_parachain_system, ParachainSystem] [frame_system, SystemBench::] - [frame_system_extensions, SystemExtensionsBench::] [pallet_glutton, Glutton] [pallet_message_queue, MessageQueue] [pallet_timestamp, Timestamp] @@ -440,7 +439,6 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; let mut list = Vec::::new(); list_benchmarks!(list, extra); @@ -457,7 +455,6 @@ impl_runtime_apis! { use sp_storage::TrackedStorageKey; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; impl frame_system_benchmarking::Config for Runtime { fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/weights/frame_system_extensions.rs deleted file mode 100644 index e6efa762308..00000000000 --- a/cumulus/parachains/runtimes/glutton/glutton-westend/src/weights/frame_system_extensions.rs +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `frame_system_extensions` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("glutton-westend-dev-1300")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=frame_system_extensions -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/glutton/glutton-westend/src/weights/ -// --chain=glutton-westend-dev-1300 - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `frame_system_extensions`. -pub struct WeightInfo(PhantomData); -impl frame_system::ExtensionsWeightInfo for WeightInfo { - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_genesis() -> Weight { - // Proof Size summary in bytes: - // Measured: `54` - // Estimated: `3509` - // Minimum execution time: 3_908_000 picoseconds. - Weight::from_parts(4_007_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_mortality() -> Weight { - // Proof Size summary in bytes: - // Measured: `92` - // Estimated: `3509` - // Minimum execution time: 5_510_000 picoseconds. - Weight::from_parts(6_332_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - fn check_non_zero_sender() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 651_000 picoseconds. - Weight::from_parts(851_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_nonce() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 3_387_000 picoseconds. - Weight::from_parts(3_646_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_spec_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 491_000 picoseconds. - Weight::from_parts(651_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_tx_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 451_000 picoseconds. - Weight::from_parts(662_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) - /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - fn check_weight() -> Weight { - // Proof Size summary in bytes: - // Measured: `24` - // Estimated: `1489` - // Minimum execution time: 3_537_000 picoseconds. - Weight::from_parts(4_208_000, 0) - .saturating_add(Weight::from_parts(0, 1489)) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) - } -} diff --git a/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml b/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml index c9781639c3e..c0b8fb7636b 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml @@ -152,7 +152,6 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index c5e420785de..2b8cc32f67c 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -83,8 +83,8 @@ pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The TransactionExtension to the basic transaction logic. -pub type TxExtension = ( +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -97,7 +97,7 @@ pub type TxExtension = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. pub type Migrations = ( @@ -178,7 +178,6 @@ impl frame_system::Config for Runtime { type Version = Version; type AccountData = pallet_balances::AccountData; type SystemWeightInfo = weights::frame_system::WeightInfo; - type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; type SS58Prefix = SS58Prefix; type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; type MaxConsumers = ConstU32<16>; @@ -233,7 +232,6 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; - type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { @@ -455,7 +453,6 @@ mod benches { [pallet_session, SessionBench::] [pallet_utility, Utility] [pallet_timestamp, Timestamp] - [pallet_transaction_payment, TransactionPayment] // Polkadot [polkadot_runtime_common::identity_migrator, IdentityMigrator] // Cumulus diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/frame_system_extensions.rs deleted file mode 100644 index 1ba2010991f..00000000000 --- a/cumulus/parachains/runtimes/people/people-rococo/src/weights/frame_system_extensions.rs +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `frame_system_extensions` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("people-rococo-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=frame_system_extensions -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/people/people-rococo/src/weights/ -// --chain=people-rococo-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `frame_system_extensions`. -pub struct WeightInfo(PhantomData); -impl frame_system::ExtensionsWeightInfo for WeightInfo { - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_genesis() -> Weight { - // Proof Size summary in bytes: - // Measured: `54` - // Estimated: `3509` - // Minimum execution time: 3_637_000 picoseconds. - Weight::from_parts(6_382_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_mortality() -> Weight { - // Proof Size summary in bytes: - // Measured: `92` - // Estimated: `3509` - // Minimum execution time: 5_841_000 picoseconds. - Weight::from_parts(8_776_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - fn check_non_zero_sender() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 561_000 picoseconds. - Weight::from_parts(2_705_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_nonce() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 3_316_000 picoseconds. - Weight::from_parts(5_771_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_spec_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 511_000 picoseconds. - Weight::from_parts(2_575_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_tx_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 501_000 picoseconds. - Weight::from_parts(2_595_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) - /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `System::BlockWeight` (r:1 w:1) - /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) - fn check_weight() -> Weight { - // Proof Size summary in bytes: - // Measured: `24` - // Estimated: `1533` - // Minimum execution time: 3_687_000 picoseconds. - Weight::from_parts(6_192_000, 0) - .saturating_add(Weight::from_parts(0, 1533)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) - } -} diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/mod.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/mod.rs index c4cea99ee5a..3396a8caea0 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/mod.rs @@ -20,7 +20,6 @@ pub mod cumulus_pallet_parachain_system; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; -pub mod frame_system_extensions; pub mod pallet_balances; pub mod pallet_collator_selection; pub mod pallet_identity; @@ -28,7 +27,6 @@ pub mod pallet_message_queue; pub mod pallet_multisig; pub mod pallet_session; pub mod pallet_timestamp; -pub mod pallet_transaction_payment; pub mod pallet_utility; pub mod pallet_xcm; pub mod paritydb_weights; diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_transaction_payment.rs deleted file mode 100644 index 555fd5a32fa..00000000000 --- a/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_transaction_payment.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `pallet_transaction_payment` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("people-rococo-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=pallet_transaction_payment -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/people/people-rococo/src/weights/ -// --chain=people-rococo-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `pallet_transaction_payment`. -pub struct WeightInfo(PhantomData); -impl pallet_transaction_payment::WeightInfo for WeightInfo { - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn charge_transaction_payment() -> Weight { - // Proof Size summary in bytes: - // Measured: `4` - // Estimated: `3593` - // Minimum execution time: 33_363_000 picoseconds. - Weight::from_parts(38_793_000, 0) - .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) - } -} diff --git a/cumulus/parachains/runtimes/people/people-westend/Cargo.toml b/cumulus/parachains/runtimes/people/people-westend/Cargo.toml index 8d8421332c1..e87e825a34e 100644 --- a/cumulus/parachains/runtimes/people/people-westend/Cargo.toml +++ b/cumulus/parachains/runtimes/people/people-westend/Cargo.toml @@ -152,7 +152,6 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index dea079a4a98..2dc2d06a66b 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -83,8 +83,8 @@ pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The transactionExtension to the basic transaction logic. -pub type TxExtension = ( +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -97,7 +97,7 @@ pub type TxExtension = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. pub type Migrations = ( @@ -178,7 +178,6 @@ impl frame_system::Config for Runtime { type Version = Version; type AccountData = pallet_balances::AccountData; type SystemWeightInfo = weights::frame_system::WeightInfo; - type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; type SS58Prefix = SS58Prefix; type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; type MaxConsumers = ConstU32<16>; @@ -233,7 +232,6 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; - type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/frame_system_extensions.rs deleted file mode 100644 index 7130a62ab6a..00000000000 --- a/cumulus/parachains/runtimes/people/people-westend/src/weights/frame_system_extensions.rs +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `frame_system_extensions` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("people-westend-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=frame_system_extensions -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/people/people-westend/src/weights/ -// --chain=people-westend-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `frame_system_extensions`. -pub struct WeightInfo(PhantomData); -impl frame_system::ExtensionsWeightInfo for WeightInfo { - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_genesis() -> Weight { - // Proof Size summary in bytes: - // Measured: `54` - // Estimated: `3509` - // Minimum execution time: 3_637_000 picoseconds. - Weight::from_parts(6_382_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_mortality() -> Weight { - // Proof Size summary in bytes: - // Measured: `92` - // Estimated: `3509` - // Minimum execution time: 5_841_000 picoseconds. - Weight::from_parts(8_776_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - fn check_non_zero_sender() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 561_000 picoseconds. - Weight::from_parts(2_705_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_nonce() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 3_316_000 picoseconds. - Weight::from_parts(5_771_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_spec_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 511_000 picoseconds. - Weight::from_parts(2_575_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_tx_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 501_000 picoseconds. - Weight::from_parts(2_595_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) - /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `System::BlockWeight` (r:1 w:1) - /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) - fn check_weight() -> Weight { - // Proof Size summary in bytes: - // Measured: `24` - // Estimated: `1533` - // Minimum execution time: 3_687_000 picoseconds. - Weight::from_parts(6_192_000, 0) - .saturating_add(Weight::from_parts(0, 1533)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) - } -} diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/mod.rs index c4cea99ee5a..3396a8caea0 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/mod.rs @@ -20,7 +20,6 @@ pub mod cumulus_pallet_parachain_system; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; -pub mod frame_system_extensions; pub mod pallet_balances; pub mod pallet_collator_selection; pub mod pallet_identity; @@ -28,7 +27,6 @@ pub mod pallet_message_queue; pub mod pallet_multisig; pub mod pallet_session; pub mod pallet_timestamp; -pub mod pallet_transaction_payment; pub mod pallet_utility; pub mod pallet_xcm; pub mod paritydb_weights; diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_transaction_payment.rs deleted file mode 100644 index 30e4524e586..00000000000 --- a/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_transaction_payment.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . - -//! Autogenerated weights for `pallet_transaction_payment` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("people-westend-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot-parachain -// benchmark -// pallet -// --wasm-execution=compiled -// --pallet=pallet_transaction_payment -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --steps=2 -// --repeat=2 -// --json -// --header=./cumulus/file_header.txt -// --output=./cumulus/parachains/runtimes/people/people-westend/src/weights/ -// --chain=people-westend-dev - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `pallet_transaction_payment`. -pub struct WeightInfo(PhantomData); -impl pallet_transaction_payment::WeightInfo for WeightInfo { - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn charge_transaction_payment() -> Weight { - // Proof Size summary in bytes: - // Measured: `4` - // Estimated: `3593` - // Minimum execution time: 33_363_000 picoseconds. - Weight::from_parts(38_793_000, 0) - .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) - } -} diff --git a/cumulus/parachains/runtimes/starters/seedling/src/lib.rs b/cumulus/parachains/runtimes/starters/seedling/src/lib.rs index 023c9978302..4cc0a81ef49 100644 --- a/cumulus/parachains/runtimes/starters/seedling/src/lib.rs +++ b/cumulus/parachains/runtimes/starters/seedling/src/lib.rs @@ -258,8 +258,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The extension to the basic transaction logic. -pub type TxExtension = ( +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( frame_system::CheckSpecVersion, frame_system::CheckTxVersion, frame_system::CheckGenesis, @@ -269,7 +269,7 @@ pub type TxExtension = ( ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< diff --git a/cumulus/parachains/runtimes/starters/shell/src/lib.rs b/cumulus/parachains/runtimes/starters/shell/src/lib.rs index fedac36e48d..829754731a4 100644 --- a/cumulus/parachains/runtimes/starters/shell/src/lib.rs +++ b/cumulus/parachains/runtimes/starters/shell/src/lib.rs @@ -34,19 +34,15 @@ pub mod xcm_config; use codec::{Decode, Encode}; use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; use cumulus_primitives_core::AggregateMessageOrigin; +use frame_support::unsigned::TransactionValidityError; use scale_info::TypeInfo; use sp_api::impl_runtime_apis; pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, - traits::{ - AccountIdLookup, BlakeTwo256, Block as BlockT, DispatchInfoOf, OriginOf, - TransactionExtension, TransactionExtensionBase, ValidateResult, - }, - transaction_validity::{ - InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError, - }, + traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, DispatchInfoOf}, + transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, }; use sp_std::prelude::*; @@ -279,37 +275,35 @@ construct_runtime! { /// Simple implementation which fails any transaction which is signed. #[derive(Eq, PartialEq, Clone, Default, sp_core::RuntimeDebug, Encode, Decode, TypeInfo)] pub struct DisallowSigned; - -impl TransactionExtensionBase for DisallowSigned { +impl sp_runtime::traits::SignedExtension for DisallowSigned { const IDENTIFIER: &'static str = "DisallowSigned"; - type Implicit = (); -} - -impl TransactionExtension for DisallowSigned { - type Val = (); + type AccountId = AccountId; + type Call = RuntimeCall; + type AdditionalSigned = (); type Pre = (); - fn validate( + fn additional_signed( &self, - _origin: OriginOf, - _call: &RuntimeCall, - _info: &DispatchInfoOf, - _len: usize, - _context: &mut C, - _self_implicit: Self::Implicit, - _inherited_implication: &impl Encode, - ) -> ValidateResult { - Err(InvalidTransaction::BadProof.into()) + ) -> sp_std::result::Result<(), sp_runtime::transaction_validity::TransactionValidityError> { + Ok(()) } - fn prepare( + fn pre_dispatch( self, - _val: Self::Val, - _origin: &OriginOf, - _call: &RuntimeCall, - _info: &DispatchInfoOf, - _len: usize, - _context: &C, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, ) -> Result { - Err(InvalidTransaction::BadProof.into()) + self.validate(who, call, info, len).map(|_| ()) + } + fn validate( + &self, + _who: &Self::AccountId, + _call: &Self::Call, + _info: &sp_runtime::traits::DispatchInfoOf, + _len: usize, + ) -> TransactionValidity { + let i = sp_runtime::transaction_validity::InvalidTransaction::BadProof; + Err(sp_runtime::transaction_validity::TransactionValidityError::Invalid(i)) } } @@ -329,11 +323,11 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The extension to the basic transaction logic. -pub type TxExtension = DisallowSigned; +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = DisallowSigned; /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, diff --git a/cumulus/parachains/runtimes/testing/penpal/Cargo.toml b/cumulus/parachains/runtimes/testing/penpal/Cargo.toml index 5a8b15740e4..7f3e898d923 100644 --- a/cumulus/parachains/runtimes/testing/penpal/Cargo.toml +++ b/cumulus/parachains/runtimes/testing/penpal/Cargo.toml @@ -156,7 +156,6 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "parachains-common/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs index 62065619e42..0030287edb3 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs @@ -114,8 +114,8 @@ pub type BlockId = generic::BlockId; // Id used for identifying assets. pub type AssetId = u32; -/// The extension to the basic transaction logic. -pub type TxExtension = ( +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -128,7 +128,7 @@ pub type TxExtension = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; pub type Migrations = ( pallet_balances::migration::MigrateToTrackInactive, @@ -419,7 +419,6 @@ impl pallet_transaction_payment::Config for Runtime { type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; type OperationalFeeMultiplier = ConstU8<5>; - type WeightInfo = (); } parameter_types! { @@ -609,19 +608,6 @@ impl pallet_collator_selection::Config for Runtime { type WeightInfo = (); } -#[cfg(feature = "runtime-benchmarks")] -pub struct AssetTxHelper; - -#[cfg(feature = "runtime-benchmarks")] -impl pallet_asset_tx_payment::BenchmarkHelperTrait for AssetTxHelper { - fn create_asset_id_parameter(_id: u32) -> (u32, u32) { - unimplemented!("Penpal uses default weights"); - } - fn setup_balances_and_pool(_asset_id: u32, _account: AccountId) { - unimplemented!("Penpal uses default weights"); - } -} - impl pallet_asset_tx_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Fungibles = Assets; @@ -634,9 +620,6 @@ impl pallet_asset_tx_payment::Config for Runtime { >, AssetsToBlockAuthor, >; - type WeightInfo = (); - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = AssetTxHelper; } impl pallet_sudo::Config for Runtime { @@ -685,7 +668,6 @@ construct_runtime!( mod benches { frame_benchmarking::define_benchmarks!( [frame_system, SystemBench::] - [frame_system_extensions, SystemExtensionsBench::] [pallet_balances, Balances] [pallet_message_queue, MessageQueue] [pallet_session, SessionBench::] @@ -869,7 +851,6 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; let mut list = Vec::::new(); @@ -886,7 +867,6 @@ impl_runtime_apis! { use sp_storage::TrackedStorageKey; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; impl frame_system_benchmarking::Config for Runtime {} use cumulus_pallet_session_benchmarking::Pallet as SessionBench; diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml b/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml index 2023d9abf5d..42169e8949f 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml @@ -126,7 +126,6 @@ runtime-benchmarks = [ "pallet-message-queue/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "parachains-common/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs index 469f06a1aa6..2b21a12c3ca 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs @@ -267,7 +267,6 @@ impl pallet_transaction_payment::Config for Runtime { type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = (); type OperationalFeeMultiplier = ConstU8<5>; - type WeightInfo = (); } impl pallet_sudo::Config for Runtime { @@ -645,8 +644,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The extension to the basic transaction logic. -pub type TxExtension = ( +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -658,7 +657,7 @@ pub type TxExtension = ( ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, diff --git a/cumulus/polkadot-parachain/Cargo.toml b/cumulus/polkadot-parachain/Cargo.toml index a92e8a4c12a..84a232e954f 100644 --- a/cumulus/polkadot-parachain/Cargo.toml +++ b/cumulus/polkadot-parachain/Cargo.toml @@ -136,7 +136,6 @@ runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "glutton-westend-runtime/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "parachains-common/runtime-benchmarks", "penpal-runtime/runtime-benchmarks", "people-rococo-runtime/runtime-benchmarks", diff --git a/cumulus/primitives/storage-weight-reclaim/Cargo.toml b/cumulus/primitives/storage-weight-reclaim/Cargo.toml index 9e8f60783d4..4835fb5192b 100644 --- a/cumulus/primitives/storage-weight-reclaim/Cargo.toml +++ b/cumulus/primitives/storage-weight-reclaim/Cargo.toml @@ -14,12 +14,9 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = log = { workspace = true } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -frame-benchmarking = { path = "../../../substrate/frame/benchmarking", default-features = false, optional = true } frame-support = { path = "../../../substrate/frame/support", default-features = false } frame-system = { path = "../../../substrate/frame/system", default-features = false } -sp-core = { path = "../../../substrate/primitives/core", default-features = false } -sp-io = { path = "../../../substrate/primitives/io", default-features = false } sp-runtime = { path = "../../../substrate/primitives/runtime", default-features = false } sp-std = { path = "../../../substrate/primitives/std", default-features = false } @@ -29,27 +26,19 @@ docify = "0.2.7" [dev-dependencies] sp-trie = { path = "../../../substrate/primitives/trie", default-features = false } +sp-io = { path = "../../../substrate/primitives/io", default-features = false } cumulus-test-runtime = { path = "../../test/runtime" } [features] default = ["std"] -runtime-benchmarks = [ - "cumulus-primitives-core/runtime-benchmarks", - "frame-benchmarking/runtime-benchmarks", - "frame-support/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", -] std = [ "codec/std", "cumulus-primitives-core/std", "cumulus-primitives-proof-size-hostfunction/std", - "frame-benchmarking/std", "frame-support/std", "frame-system/std", "log/std", "scale-info/std", - "sp-core/std", "sp-io/std", "sp-runtime/std", "sp-std/std", diff --git a/cumulus/primitives/storage-weight-reclaim/src/benchmarking.rs b/cumulus/primitives/storage-weight-reclaim/src/benchmarking.rs deleted file mode 100644 index 2980d08271a..00000000000 --- a/cumulus/primitives/storage-weight-reclaim/src/benchmarking.rs +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// 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. - -//! Benchmarking setup for cumulus-primitives-storage-weight-reclaim - -#![cfg(feature = "runtime-benchmarks")] - -use super::*; - -use frame_benchmarking::{account, v2::*, BenchmarkError}; -use frame_support::pallet_prelude::DispatchClass; -use frame_system::{BlockWeight, RawOrigin}; -use sp_runtime::traits::{DispatchTransaction, Get}; -use sp_std::{ - marker::{Send, Sync}, - prelude::*, -}; - -/// Pallet we're benchmarking here. -pub struct Pallet(frame_system::Pallet); - -#[benchmarks(where - T: Send + Sync, - T::RuntimeCall: Dispatchable -)] -mod benchmarks { - use super::*; - - #[benchmark] - fn storage_weight_reclaim() -> Result<(), BenchmarkError> { - let caller = account("caller", 0, 0); - BlockWeight::::mutate(|current_weight| { - current_weight.set(Weight::from_parts(0, 1000), DispatchClass::Normal); - }); - let base_extrinsic = ::BlockWeights::get() - .get(DispatchClass::Normal) - .base_extrinsic; - let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() }; - let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into(); - let post_info = PostDispatchInfo { - actual_weight: Some(Weight::from_parts(0, 200)), - pays_fee: Default::default(), - }; - let len = 0_usize; - let ext = StorageWeightReclaim::::new(); - - #[block] - { - ext.test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(post_info)) - .unwrap() - .unwrap(); - } - - assert_eq!(BlockWeight::::get().total().proof_size(), 700 + base_extrinsic.proof_size()); - - Ok(()) - } -} diff --git a/cumulus/primitives/storage-weight-reclaim/src/lib.rs b/cumulus/primitives/storage-weight-reclaim/src/lib.rs index 4bb40176b78..5dddc92e395 100644 --- a/cumulus/primitives/storage-weight-reclaim/src/lib.rs +++ b/cumulus/primitives/storage-weight-reclaim/src/lib.rs @@ -29,22 +29,12 @@ use frame_support::{ use frame_system::Config; use scale_info::TypeInfo; use sp_runtime::{ - impl_tx_ext_default, - traits::{ - DispatchInfoOf, Dispatchable, PostDispatchInfoOf, TransactionExtension, - TransactionExtensionBase, - }, + traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf, SignedExtension}, transaction_validity::TransactionValidityError, DispatchResult, }; use sp_std::marker::PhantomData; -#[cfg(test)] -mod tests; - -#[cfg(feature = "runtime-benchmarks")] -mod benchmarking; - const LOG_TARGET: &'static str = "runtime::storage_reclaim"; /// `StorageWeightReclaimer` is a mechanism for manually reclaiming storage weight. @@ -53,7 +43,7 @@ const LOG_TARGET: &'static str = "runtime::storage_reclaim"; /// reclaim it computes the real consumed storage weight and refunds excess weight. /// /// # Example -#[doc = docify::embed!("src/tests.rs", simple_reclaimer_example)] +#[doc = docify::embed!("src/lib.rs", simple_reclaimer_example)] pub struct StorageWeightReclaimer { previous_remaining_proof_size: u64, previous_reported_proof_size: Option, @@ -129,40 +119,42 @@ impl core::fmt::Debug for StorageWeightReclaim { } } -impl TransactionExtensionBase for StorageWeightReclaim { - const IDENTIFIER: &'static str = "StorageWeightReclaim"; - type Implicit = (); -} - -impl TransactionExtension - for StorageWeightReclaim +impl SignedExtension for StorageWeightReclaim where T::RuntimeCall: Dispatchable, { - type Val = (); + const IDENTIFIER: &'static str = "StorageWeightReclaim"; + + type AccountId = T::AccountId; + type Call = T::RuntimeCall; + type AdditionalSigned = (); type Pre = Option; - fn prepare( + fn additional_signed( + &self, + ) -> Result + { + Ok(()) + } + + fn pre_dispatch( self, - _val: Self::Val, - _origin: &T::RuntimeOrigin, - _call: &T::RuntimeCall, - _info: &DispatchInfoOf, + _who: &Self::AccountId, + _call: &Self::Call, + _info: &sp_runtime::traits::DispatchInfoOf, _len: usize, - _context: &Context, - ) -> Result { + ) -> Result { Ok(get_proof_size()) } fn post_dispatch( - pre: Self::Pre, - info: &DispatchInfoOf, - post_info: &PostDispatchInfoOf, + pre: Option, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, _len: usize, _result: &DispatchResult, - _context: &Context, ) -> Result<(), TransactionValidityError> { - let Some(pre_dispatch_proof_size) = pre else { + let Some(Some(pre_dispatch_proof_size)) = pre else { return Ok(()); }; @@ -202,6 +194,470 @@ where }); Ok(()) } +} + +#[cfg(test)] +mod tests { + use super::*; + use frame_support::{ + assert_ok, + dispatch::DispatchClass, + weights::{Weight, WeightMeter}, + }; + use frame_system::{BlockWeight, CheckWeight}; + use sp_runtime::{AccountId32, BuildStorage}; + use sp_std::marker::PhantomData; + use sp_trie::proof_size_extension::ProofSizeExt; + + type Test = cumulus_test_runtime::Runtime; + const CALL: &::RuntimeCall = + &cumulus_test_runtime::RuntimeCall::System(frame_system::Call::set_heap_pages { + pages: 0u64, + }); + const ALICE: AccountId32 = AccountId32::new([1u8; 32]); + const LEN: usize = 0; + + pub fn new_test_ext() -> sp_io::TestExternalities { + let ext: sp_io::TestExternalities = cumulus_test_runtime::RuntimeGenesisConfig::default() + .build_storage() + .unwrap() + .into(); + ext + } + + struct TestRecorder { + return_values: Box<[usize]>, + counter: std::sync::atomic::AtomicUsize, + } + + impl TestRecorder { + fn new(values: &[usize]) -> Self { + TestRecorder { return_values: values.into(), counter: Default::default() } + } + } + + impl sp_trie::ProofSizeProvider for TestRecorder { + fn estimate_encoded_size(&self) -> usize { + let counter = self.counter.fetch_add(1, core::sync::atomic::Ordering::Relaxed); + self.return_values[counter] + } + } + + fn setup_test_externalities(proof_values: &[usize]) -> sp_io::TestExternalities { + let mut test_ext = new_test_ext(); + let test_recorder = TestRecorder::new(proof_values); + test_ext.register_extension(ProofSizeExt::new(test_recorder)); + test_ext + } + + fn set_current_storage_weight(new_weight: u64) { + BlockWeight::::mutate(|current_weight| { + current_weight.set(Weight::from_parts(0, new_weight), DispatchClass::Normal); + }); + } + + #[test] + fn basic_refund() { + // The real cost will be 100 bytes of storage size + let mut test_ext = setup_test_externalities(&[0, 100]); + + test_ext.execute_with(|| { + set_current_storage_weight(1000); + + // Benchmarked storage weight: 500 + let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() }; + let post_info = PostDispatchInfo::default(); + + let pre = StorageWeightReclaim::(PhantomData) + .pre_dispatch(&ALICE, CALL, &info, LEN) + .unwrap(); + assert_eq!(pre, Some(0)); + + assert_ok!(CheckWeight::::post_dispatch(None, &info, &post_info, 0, &Ok(()))); + // We expect a refund of 400 + assert_ok!(StorageWeightReclaim::::post_dispatch( + Some(pre), + &info, + &post_info, + LEN, + &Ok(()) + )); + + assert_eq!(BlockWeight::::get().total().proof_size(), 600); + }) + } + + #[test] + fn does_nothing_without_extension() { + let mut test_ext = new_test_ext(); + + // Proof size extension not registered + test_ext.execute_with(|| { + set_current_storage_weight(1000); + + // Benchmarked storage weight: 500 + let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() }; + let post_info = PostDispatchInfo::default(); + + let pre = StorageWeightReclaim::(PhantomData) + .pre_dispatch(&ALICE, CALL, &info, LEN) + .unwrap(); + assert_eq!(pre, None); + + assert_ok!(CheckWeight::::post_dispatch(None, &info, &post_info, 0, &Ok(()))); + assert_ok!(StorageWeightReclaim::::post_dispatch( + Some(pre), + &info, + &post_info, + LEN, + &Ok(()) + )); + + assert_eq!(BlockWeight::::get().total().proof_size(), 1000); + }) + } + + #[test] + fn negative_refund_is_added_to_weight() { + let mut test_ext = setup_test_externalities(&[100, 300]); + + test_ext.execute_with(|| { + set_current_storage_weight(1000); + // Benchmarked storage weight: 100 + let info = DispatchInfo { weight: Weight::from_parts(0, 100), ..Default::default() }; + let post_info = PostDispatchInfo::default(); + + let pre = StorageWeightReclaim::(PhantomData) + .pre_dispatch(&ALICE, CALL, &info, LEN) + .unwrap(); + assert_eq!(pre, Some(100)); + + // We expect no refund + assert_ok!(CheckWeight::::post_dispatch(None, &info, &post_info, 0, &Ok(()))); + assert_ok!(StorageWeightReclaim::::post_dispatch( + Some(pre), + &info, + &post_info, + LEN, + &Ok(()) + )); + + assert_eq!(BlockWeight::::get().total().proof_size(), 1100); + }) + } + + #[test] + fn test_zero_proof_size() { + let mut test_ext = setup_test_externalities(&[0, 0]); + + test_ext.execute_with(|| { + let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() }; + let post_info = PostDispatchInfo::default(); + + let pre = StorageWeightReclaim::(PhantomData) + .pre_dispatch(&ALICE, CALL, &info, LEN) + .unwrap(); + assert_eq!(pre, Some(0)); + + assert_ok!(CheckWeight::::post_dispatch(None, &info, &post_info, 0, &Ok(()))); + assert_ok!(StorageWeightReclaim::::post_dispatch( + Some(pre), + &info, + &post_info, + LEN, + &Ok(()) + )); + + assert_eq!(BlockWeight::::get().total().proof_size(), 0); + }); + } + + #[test] + fn test_larger_pre_dispatch_proof_size() { + let mut test_ext = setup_test_externalities(&[300, 100]); + + test_ext.execute_with(|| { + set_current_storage_weight(1300); + + let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() }; + let post_info = PostDispatchInfo::default(); + + let pre = StorageWeightReclaim::(PhantomData) + .pre_dispatch(&ALICE, CALL, &info, LEN) + .unwrap(); + assert_eq!(pre, Some(300)); + + assert_ok!(CheckWeight::::post_dispatch(None, &info, &post_info, 0, &Ok(()))); + assert_ok!(StorageWeightReclaim::::post_dispatch( + Some(pre), + &info, + &post_info, + LEN, + &Ok(()) + )); + + assert_eq!(BlockWeight::::get().total().proof_size(), 800); + }); + } + + #[test] + fn test_incorporates_check_weight_unspent_weight() { + let mut test_ext = setup_test_externalities(&[100, 300]); + + test_ext.execute_with(|| { + set_current_storage_weight(1000); + + // Benchmarked storage weight: 300 + let info = DispatchInfo { weight: Weight::from_parts(100, 300), ..Default::default() }; + + // Actual weight is 50 + let post_info = PostDispatchInfo { + actual_weight: Some(Weight::from_parts(50, 250)), + pays_fee: Default::default(), + }; + + let pre = StorageWeightReclaim::(PhantomData) + .pre_dispatch(&ALICE, CALL, &info, LEN) + .unwrap(); + assert_eq!(pre, Some(100)); + + // The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo` + // we always need to call `post_dispatch` to verify that they interoperate correctly. + assert_ok!(CheckWeight::::post_dispatch(None, &info, &post_info, 0, &Ok(()))); + assert_ok!(StorageWeightReclaim::::post_dispatch( + Some(pre), + &info, + &post_info, + LEN, + &Ok(()) + )); + + assert_eq!(BlockWeight::::get().total().proof_size(), 900); + }) + } + + #[test] + fn test_incorporates_check_weight_unspent_weight_on_negative() { + let mut test_ext = setup_test_externalities(&[100, 300]); + + test_ext.execute_with(|| { + set_current_storage_weight(1000); + // Benchmarked storage weight: 50 + let info = DispatchInfo { weight: Weight::from_parts(100, 50), ..Default::default() }; + + // Actual weight is 25 + let post_info = PostDispatchInfo { + actual_weight: Some(Weight::from_parts(50, 25)), + pays_fee: Default::default(), + }; + + let pre = StorageWeightReclaim::(PhantomData) + .pre_dispatch(&ALICE, CALL, &info, LEN) + .unwrap(); + assert_eq!(pre, Some(100)); + + // The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo` + // we always need to call `post_dispatch` to verify that they interoperate correctly. + assert_ok!(CheckWeight::::post_dispatch(None, &info, &post_info, 0, &Ok(()))); + assert_ok!(StorageWeightReclaim::::post_dispatch( + Some(pre), + &info, + &post_info, + LEN, + &Ok(()) + )); + + assert_eq!(BlockWeight::::get().total().proof_size(), 1150); + }) + } + + #[test] + fn test_incorporates_check_weight_unspent_weight_reverse_order() { + let mut test_ext = setup_test_externalities(&[100, 300]); + + test_ext.execute_with(|| { + set_current_storage_weight(1000); + + // Benchmarked storage weight: 300 + let info = DispatchInfo { weight: Weight::from_parts(100, 300), ..Default::default() }; + + // Actual weight is 50 + let post_info = PostDispatchInfo { + actual_weight: Some(Weight::from_parts(50, 250)), + pays_fee: Default::default(), + }; + + let pre = StorageWeightReclaim::(PhantomData) + .pre_dispatch(&ALICE, CALL, &info, LEN) + .unwrap(); + assert_eq!(pre, Some(100)); + + assert_ok!(StorageWeightReclaim::::post_dispatch( + Some(pre), + &info, + &post_info, + LEN, + &Ok(()) + )); + // `CheckWeight` gets called after `StorageWeightReclaim` this time. + // The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo` + // we always need to call `post_dispatch` to verify that they interoperate correctly. + assert_ok!(CheckWeight::::post_dispatch(None, &info, &post_info, 0, &Ok(()))); + + assert_eq!(BlockWeight::::get().total().proof_size(), 900); + }) + } + + #[test] + fn test_incorporates_check_weight_unspent_weight_on_negative_reverse_order() { + let mut test_ext = setup_test_externalities(&[100, 300]); + + test_ext.execute_with(|| { + set_current_storage_weight(1000); + // Benchmarked storage weight: 50 + let info = DispatchInfo { weight: Weight::from_parts(100, 50), ..Default::default() }; - impl_tx_ext_default!(T::RuntimeCall; Context; validate); + // Actual weight is 25 + let post_info = PostDispatchInfo { + actual_weight: Some(Weight::from_parts(50, 25)), + pays_fee: Default::default(), + }; + + let pre = StorageWeightReclaim::(PhantomData) + .pre_dispatch(&ALICE, CALL, &info, LEN) + .unwrap(); + assert_eq!(pre, Some(100)); + + assert_ok!(StorageWeightReclaim::::post_dispatch( + Some(pre), + &info, + &post_info, + LEN, + &Ok(()) + )); + // `CheckWeight` gets called after `StorageWeightReclaim` this time. + // The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo` + // we always need to call `post_dispatch` to verify that they interoperate correctly. + assert_ok!(CheckWeight::::post_dispatch(None, &info, &post_info, 0, &Ok(()))); + + assert_eq!(BlockWeight::::get().total().proof_size(), 1150); + }) + } + + #[test] + fn storage_size_reported_correctly() { + let mut test_ext = setup_test_externalities(&[1000]); + test_ext.execute_with(|| { + assert_eq!(get_proof_size(), Some(1000)); + }); + + let mut test_ext = new_test_ext(); + + let test_recorder = TestRecorder::new(&[0]); + + test_ext.register_extension(ProofSizeExt::new(test_recorder)); + + test_ext.execute_with(|| { + assert_eq!(get_proof_size(), Some(0)); + }); + } + + #[test] + fn storage_size_disabled_reported_correctly() { + let mut test_ext = setup_test_externalities(&[PROOF_RECORDING_DISABLED as usize]); + + test_ext.execute_with(|| { + assert_eq!(get_proof_size(), None); + }); + } + + #[test] + fn test_reclaim_helper() { + let mut test_ext = setup_test_externalities(&[1000, 1300, 1800]); + + test_ext.execute_with(|| { + let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(0, 2000)); + let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter); + remaining_weight_meter.consume(Weight::from_parts(0, 500)); + let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); + + assert_eq!(reclaimed, Some(Weight::from_parts(0, 200))); + + remaining_weight_meter.consume(Weight::from_parts(0, 800)); + let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); + assert_eq!(reclaimed, Some(Weight::from_parts(0, 300))); + assert_eq!(remaining_weight_meter.remaining(), Weight::from_parts(0, 1200)); + }); + } + + #[test] + fn test_reclaim_helper_does_not_reclaim_negative() { + // Benchmarked weight does not change at all + let mut test_ext = setup_test_externalities(&[1000, 1300]); + + test_ext.execute_with(|| { + let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(0, 1000)); + let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter); + let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); + + assert_eq!(reclaimed, Some(Weight::from_parts(0, 0))); + assert_eq!(remaining_weight_meter.remaining(), Weight::from_parts(0, 1000)); + }); + + // Benchmarked weight increases less than storage proof consumes + let mut test_ext = setup_test_externalities(&[1000, 1300]); + + test_ext.execute_with(|| { + let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(0, 1000)); + let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter); + remaining_weight_meter.consume(Weight::from_parts(0, 0)); + let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); + + assert_eq!(reclaimed, Some(Weight::from_parts(0, 0))); + }); + } + + /// Just here for doc purposes + fn get_benched_weight() -> Weight { + Weight::from_parts(0, 5) + } + + /// Just here for doc purposes + fn do_work() {} + + #[docify::export_content(simple_reclaimer_example)] + fn reclaim_with_weight_meter() { + let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(10, 10)); + + let benched_weight = get_benched_weight(); + + // It is important to instantiate the `StorageWeightReclaimer` before we consume the weight + // for a piece of work from the weight meter. + let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter); + + if remaining_weight_meter.try_consume(benched_weight).is_ok() { + // Perform some work that takes has `benched_weight` storage weight. + do_work(); + + // Reclaimer will detect that we only consumed 2 bytes, so 3 bytes are reclaimed. + let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); + + // We reclaimed 3 bytes of storage size! + assert_eq!(reclaimed, Some(Weight::from_parts(0, 3))); + assert_eq!(BlockWeight::::get().total().proof_size(), 10); + assert_eq!(remaining_weight_meter.remaining(), Weight::from_parts(10, 8)); + } + } + + #[test] + fn test_reclaim_helper_works_with_meter() { + // The node will report 12 - 10 = 2 consumed storage size between the calls. + let mut test_ext = setup_test_externalities(&[10, 12]); + + test_ext.execute_with(|| { + // Initial storage size is 10. + set_current_storage_weight(10); + reclaim_with_weight_meter(); + }); + } } diff --git a/cumulus/primitives/storage-weight-reclaim/src/tests.rs b/cumulus/primitives/storage-weight-reclaim/src/tests.rs deleted file mode 100644 index 631827cf442..00000000000 --- a/cumulus/primitives/storage-weight-reclaim/src/tests.rs +++ /dev/null @@ -1,484 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// 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. - -use super::*; -use frame_support::{ - assert_ok, - dispatch::DispatchClass, - weights::{Weight, WeightMeter}, -}; -use frame_system::{BlockWeight, CheckWeight}; -use sp_runtime::{traits::DispatchTransaction, AccountId32, BuildStorage}; -use sp_std::marker::PhantomData; -use sp_trie::proof_size_extension::ProofSizeExt; - -type Test = cumulus_test_runtime::Runtime; -const CALL: &::RuntimeCall = - &cumulus_test_runtime::RuntimeCall::System(frame_system::Call::set_heap_pages { pages: 0u64 }); -const ALICE: AccountId32 = AccountId32::new([1u8; 32]); -const LEN: usize = 0; - -fn new_test_ext() -> sp_io::TestExternalities { - let ext: sp_io::TestExternalities = cumulus_test_runtime::RuntimeGenesisConfig::default() - .build_storage() - .unwrap() - .into(); - ext -} - -struct TestRecorder { - return_values: Box<[usize]>, - counter: std::sync::atomic::AtomicUsize, -} - -impl TestRecorder { - fn new(values: &[usize]) -> Self { - TestRecorder { return_values: values.into(), counter: Default::default() } - } -} - -impl sp_trie::ProofSizeProvider for TestRecorder { - fn estimate_encoded_size(&self) -> usize { - let counter = self.counter.fetch_add(1, core::sync::atomic::Ordering::Relaxed); - self.return_values[counter] - } -} - -fn setup_test_externalities(proof_values: &[usize]) -> sp_io::TestExternalities { - let mut test_ext = new_test_ext(); - let test_recorder = TestRecorder::new(proof_values); - test_ext.register_extension(ProofSizeExt::new(test_recorder)); - test_ext -} - -fn set_current_storage_weight(new_weight: u64) { - BlockWeight::::mutate(|current_weight| { - current_weight.set(Weight::from_parts(0, new_weight), DispatchClass::Normal); - }); -} - -#[test] -fn basic_refund() { - // The real cost will be 100 bytes of storage size - let mut test_ext = setup_test_externalities(&[0, 100]); - - test_ext.execute_with(|| { - set_current_storage_weight(1000); - - // Benchmarked storage weight: 500 - let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() }; - let post_info = PostDispatchInfo::default(); - - let (pre, _) = StorageWeightReclaim::(PhantomData) - .validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN) - .unwrap(); - assert_eq!(pre, Some(0)); - - assert_ok!(CheckWeight::::post_dispatch((), &info, &post_info, 0, &Ok(()), &())); - // We expect a refund of 400 - assert_ok!(StorageWeightReclaim::::post_dispatch( - pre, - &info, - &post_info, - LEN, - &Ok(()), - &() - )); - - assert_eq!(BlockWeight::::get().total().proof_size(), 600); - }) -} - -#[test] -fn does_nothing_without_extension() { - let mut test_ext = new_test_ext(); - - // Proof size extension not registered - test_ext.execute_with(|| { - set_current_storage_weight(1000); - - // Benchmarked storage weight: 500 - let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() }; - let post_info = PostDispatchInfo::default(); - - let (pre, _) = StorageWeightReclaim::(PhantomData) - .validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN) - .unwrap(); - assert_eq!(pre, None); - - assert_ok!(CheckWeight::::post_dispatch((), &info, &post_info, 0, &Ok(()), &())); - assert_ok!(StorageWeightReclaim::::post_dispatch( - pre, - &info, - &post_info, - LEN, - &Ok(()), - &() - )); - - assert_eq!(BlockWeight::::get().total().proof_size(), 1000); - }) -} - -#[test] -fn negative_refund_is_added_to_weight() { - let mut test_ext = setup_test_externalities(&[100, 300]); - - test_ext.execute_with(|| { - set_current_storage_weight(1000); - // Benchmarked storage weight: 100 - let info = DispatchInfo { weight: Weight::from_parts(0, 100), ..Default::default() }; - let post_info = PostDispatchInfo::default(); - - let (pre, _) = StorageWeightReclaim::(PhantomData) - .validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN) - .unwrap(); - assert_eq!(pre, Some(100)); - - // We expect no refund - assert_ok!(CheckWeight::::post_dispatch((), &info, &post_info, 0, &Ok(()), &())); - assert_ok!(StorageWeightReclaim::::post_dispatch( - pre, - &info, - &post_info, - LEN, - &Ok(()), - &() - )); - - assert_eq!(BlockWeight::::get().total().proof_size(), 1100); - }) -} - -#[test] -fn test_zero_proof_size() { - let mut test_ext = setup_test_externalities(&[0, 0]); - - test_ext.execute_with(|| { - let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() }; - let post_info = PostDispatchInfo::default(); - - let (pre, _) = StorageWeightReclaim::(PhantomData) - .validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN) - .unwrap(); - assert_eq!(pre, Some(0)); - - assert_ok!(CheckWeight::::post_dispatch((), &info, &post_info, 0, &Ok(()), &())); - assert_ok!(StorageWeightReclaim::::post_dispatch( - pre, - &info, - &post_info, - LEN, - &Ok(()), - &() - )); - - assert_eq!(BlockWeight::::get().total().proof_size(), 0); - }); -} - -#[test] -fn test_larger_pre_dispatch_proof_size() { - let mut test_ext = setup_test_externalities(&[300, 100]); - - test_ext.execute_with(|| { - set_current_storage_weight(1300); - - let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() }; - let post_info = PostDispatchInfo::default(); - - let (pre, _) = StorageWeightReclaim::(PhantomData) - .validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN) - .unwrap(); - assert_eq!(pre, Some(300)); - - assert_ok!(CheckWeight::::post_dispatch((), &info, &post_info, 0, &Ok(()), &())); - assert_ok!(StorageWeightReclaim::::post_dispatch( - pre, - &info, - &post_info, - LEN, - &Ok(()), - &() - )); - - assert_eq!(BlockWeight::::get().total().proof_size(), 800); - }); -} - -#[test] -fn test_incorporates_check_weight_unspent_weight() { - let mut test_ext = setup_test_externalities(&[100, 300]); - - test_ext.execute_with(|| { - set_current_storage_weight(1000); - - // Benchmarked storage weight: 300 - let info = DispatchInfo { weight: Weight::from_parts(100, 300), ..Default::default() }; - - // Actual weight is 50 - let post_info = PostDispatchInfo { - actual_weight: Some(Weight::from_parts(50, 250)), - pays_fee: Default::default(), - }; - - let (pre, _) = StorageWeightReclaim::(PhantomData) - .validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN) - .unwrap(); - assert_eq!(pre, Some(100)); - - // The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo` - // we always need to call `post_dispatch` to verify that they interoperate correctly. - assert_ok!(CheckWeight::::post_dispatch((), &info, &post_info, 0, &Ok(()), &())); - assert_ok!(StorageWeightReclaim::::post_dispatch( - pre, - &info, - &post_info, - LEN, - &Ok(()), - &() - )); - - assert_eq!(BlockWeight::::get().total().proof_size(), 900); - }) -} - -#[test] -fn test_incorporates_check_weight_unspent_weight_on_negative() { - let mut test_ext = setup_test_externalities(&[100, 300]); - - test_ext.execute_with(|| { - set_current_storage_weight(1000); - // Benchmarked storage weight: 50 - let info = DispatchInfo { weight: Weight::from_parts(100, 50), ..Default::default() }; - - // Actual weight is 25 - let post_info = PostDispatchInfo { - actual_weight: Some(Weight::from_parts(50, 25)), - pays_fee: Default::default(), - }; - - let (pre, _) = StorageWeightReclaim::(PhantomData) - .validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN) - .unwrap(); - assert_eq!(pre, Some(100)); - - // The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo` - // we always need to call `post_dispatch` to verify that they interoperate correctly. - assert_ok!(CheckWeight::::post_dispatch((), &info, &post_info, 0, &Ok(()), &())); - assert_ok!(StorageWeightReclaim::::post_dispatch( - pre, - &info, - &post_info, - LEN, - &Ok(()), - &() - )); - - assert_eq!(BlockWeight::::get().total().proof_size(), 1150); - }) -} - -#[test] -fn test_incorporates_check_weight_unspent_weight_reverse_order() { - let mut test_ext = setup_test_externalities(&[100, 300]); - - test_ext.execute_with(|| { - set_current_storage_weight(1000); - - // Benchmarked storage weight: 300 - let info = DispatchInfo { weight: Weight::from_parts(100, 300), ..Default::default() }; - - // Actual weight is 50 - let post_info = PostDispatchInfo { - actual_weight: Some(Weight::from_parts(50, 250)), - pays_fee: Default::default(), - }; - - let (pre, _) = StorageWeightReclaim::(PhantomData) - .validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN) - .unwrap(); - assert_eq!(pre, Some(100)); - - assert_ok!(StorageWeightReclaim::::post_dispatch( - pre, - &info, - &post_info, - LEN, - &Ok(()), - &() - )); - // `CheckWeight` gets called after `StorageWeightReclaim` this time. - // The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo` - // we always need to call `post_dispatch` to verify that they interoperate correctly. - assert_ok!(CheckWeight::::post_dispatch((), &info, &post_info, 0, &Ok(()), &())); - - assert_eq!(BlockWeight::::get().total().proof_size(), 900); - }) -} - -#[test] -fn test_incorporates_check_weight_unspent_weight_on_negative_reverse_order() { - let mut test_ext = setup_test_externalities(&[100, 300]); - - test_ext.execute_with(|| { - set_current_storage_weight(1000); - // Benchmarked storage weight: 50 - let info = DispatchInfo { weight: Weight::from_parts(100, 50), ..Default::default() }; - - // Actual weight is 25 - let post_info = PostDispatchInfo { - actual_weight: Some(Weight::from_parts(50, 25)), - pays_fee: Default::default(), - }; - - let (pre, _) = StorageWeightReclaim::(PhantomData) - .validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN) - .unwrap(); - assert_eq!(pre, Some(100)); - - assert_ok!(StorageWeightReclaim::::post_dispatch( - pre, - &info, - &post_info, - LEN, - &Ok(()), - &() - )); - // `CheckWeight` gets called after `StorageWeightReclaim` this time. - // The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo` - // we always need to call `post_dispatch` to verify that they interoperate correctly. - assert_ok!(CheckWeight::::post_dispatch((), &info, &post_info, 0, &Ok(()), &())); - - assert_eq!(BlockWeight::::get().total().proof_size(), 1150); - }) -} - -#[test] -fn storage_size_reported_correctly() { - let mut test_ext = setup_test_externalities(&[1000]); - test_ext.execute_with(|| { - assert_eq!(get_proof_size(), Some(1000)); - }); - - let mut test_ext = new_test_ext(); - - let test_recorder = TestRecorder::new(&[0]); - - test_ext.register_extension(ProofSizeExt::new(test_recorder)); - - test_ext.execute_with(|| { - assert_eq!(get_proof_size(), Some(0)); - }); -} - -#[test] -fn storage_size_disabled_reported_correctly() { - let mut test_ext = setup_test_externalities(&[PROOF_RECORDING_DISABLED as usize]); - - test_ext.execute_with(|| { - assert_eq!(get_proof_size(), None); - }); -} - -#[test] -fn test_reclaim_helper() { - let mut test_ext = setup_test_externalities(&[1000, 1300, 1800]); - - test_ext.execute_with(|| { - let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(0, 2000)); - let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter); - remaining_weight_meter.consume(Weight::from_parts(0, 500)); - let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); - - assert_eq!(reclaimed, Some(Weight::from_parts(0, 200))); - - remaining_weight_meter.consume(Weight::from_parts(0, 800)); - let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); - assert_eq!(reclaimed, Some(Weight::from_parts(0, 300))); - assert_eq!(remaining_weight_meter.remaining(), Weight::from_parts(0, 1200)); - }); -} - -#[test] -fn test_reclaim_helper_does_not_reclaim_negative() { - // Benchmarked weight does not change at all - let mut test_ext = setup_test_externalities(&[1000, 1300]); - - test_ext.execute_with(|| { - let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(0, 1000)); - let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter); - let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); - - assert_eq!(reclaimed, Some(Weight::from_parts(0, 0))); - assert_eq!(remaining_weight_meter.remaining(), Weight::from_parts(0, 1000)); - }); - - // Benchmarked weight increases less than storage proof consumes - let mut test_ext = setup_test_externalities(&[1000, 1300]); - - test_ext.execute_with(|| { - let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(0, 1000)); - let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter); - remaining_weight_meter.consume(Weight::from_parts(0, 0)); - let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); - - assert_eq!(reclaimed, Some(Weight::from_parts(0, 0))); - }); -} - -/// Just here for doc purposes -fn get_benched_weight() -> Weight { - Weight::from_parts(0, 5) -} - -/// Just here for doc purposes -fn do_work() {} - -#[docify::export_content(simple_reclaimer_example)] -fn reclaim_with_weight_meter() { - let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(10, 10)); - - let benched_weight = get_benched_weight(); - - // It is important to instantiate the `StorageWeightReclaimer` before we consume the weight - // for a piece of work from the weight meter. - let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter); - - if remaining_weight_meter.try_consume(benched_weight).is_ok() { - // Perform some work that takes has `benched_weight` storage weight. - do_work(); - - // Reclaimer will detect that we only consumed 2 bytes, so 3 bytes are reclaimed. - let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter); - - // We reclaimed 3 bytes of storage size! - assert_eq!(reclaimed, Some(Weight::from_parts(0, 3))); - assert_eq!(BlockWeight::::get().total().proof_size(), 10); - assert_eq!(remaining_weight_meter.remaining(), Weight::from_parts(10, 8)); - } -} - -#[test] -fn test_reclaim_helper_works_with_meter() { - // The node will report 12 - 10 = 2 consumed storage size between the calls. - let mut test_ext = setup_test_externalities(&[10, 12]); - - test_ext.execute_with(|| { - // Initial storage size is 10. - set_current_storage_weight(10); - reclaim_with_weight_meter(); - }); -} diff --git a/cumulus/test/client/Cargo.toml b/cumulus/test/client/Cargo.toml index 9dfa6ecb351..028733ce235 100644 --- a/cumulus/test/client/Cargo.toml +++ b/cumulus/test/client/Cargo.toml @@ -46,11 +46,9 @@ cumulus-primitives-storage-weight-reclaim = { path = "../../primitives/storage-w [features] runtime-benchmarks = [ "cumulus-primitives-core/runtime-benchmarks", - "cumulus-primitives-storage-weight-reclaim/runtime-benchmarks", "cumulus-test-service/runtime-benchmarks", "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-primitives/runtime-benchmarks", "sc-service/runtime-benchmarks", diff --git a/cumulus/test/client/src/lib.rs b/cumulus/test/client/src/lib.rs index 9239ff0f23e..c46f4da7f67 100644 --- a/cumulus/test/client/src/lib.rs +++ b/cumulus/test/client/src/lib.rs @@ -19,7 +19,7 @@ mod block_builder; use codec::{Decode, Encode}; use runtime::{ - Balance, Block, BlockHashCount, Runtime, RuntimeCall, Signature, SignedPayload, TxExtension, + Balance, Block, BlockHashCount, Runtime, RuntimeCall, Signature, SignedExtra, SignedPayload, UncheckedExtrinsic, VERSION, }; use sc_executor::HeapAllocStrategy; @@ -125,7 +125,7 @@ impl DefaultTestClientBuilderExt for TestClientBuilder { /// Create an unsigned extrinsic from a runtime call. pub fn generate_unsigned(function: impl Into) -> UncheckedExtrinsic { - UncheckedExtrinsic::new_bare(function.into()) + UncheckedExtrinsic::new_unsigned(function.into()) } /// Create a signed extrinsic from a runtime call and sign @@ -143,7 +143,7 @@ pub fn generate_extrinsic_with_pair( let period = BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64; let tip = 0; - let tx_ext: TxExtension = ( + let extra: SignedExtra = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckGenesis::::new(), @@ -152,14 +152,13 @@ pub fn generate_extrinsic_with_pair( frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(tip), cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::::new(), - ) - .into(); + ); let function = function.into(); let raw_payload = SignedPayload::from_raw( function.clone(), - tx_ext.clone(), + extra.clone(), ((), VERSION.spec_version, genesis_block, current_block_hash, (), (), (), ()), ); let signature = raw_payload.using_encoded(|e| origin.sign(e)); @@ -168,7 +167,7 @@ pub fn generate_extrinsic_with_pair( function, origin.public().into(), Signature::Sr25519(signature), - tx_ext, + extra, ) } diff --git a/cumulus/test/runtime/src/lib.rs b/cumulus/test/runtime/src/lib.rs index 154948a24b4..5ccec8983e9 100644 --- a/cumulus/test/runtime/src/lib.rs +++ b/cumulus/test/runtime/src/lib.rs @@ -246,7 +246,6 @@ impl pallet_transaction_payment::Config for Runtime { type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = (); type OperationalFeeMultiplier = ConstU8<5>; - type WeightInfo = pallet_transaction_payment::weights::SubstrateWeight; } impl pallet_sudo::Config for Runtime { @@ -323,8 +322,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The extension to the basic transaction logic. -pub type TxExtension = ( +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckGenesis, @@ -336,7 +335,7 @@ pub type TxExtension = ( ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, @@ -347,7 +346,7 @@ pub type Executive = frame_executive::Executive< TestOnRuntimeUpgrade, >; /// The payload being signed in transactions. -pub type SignedPayload = generic::SignedPayload; +pub type SignedPayload = generic::SignedPayload; pub struct TestOnRuntimeUpgrade; diff --git a/cumulus/test/service/Cargo.toml b/cumulus/test/service/Cargo.toml index 39e8aeba433..27273f4e0a8 100644 --- a/cumulus/test/service/Cargo.toml +++ b/cumulus/test/service/Cargo.toml @@ -104,12 +104,10 @@ substrate-test-utils = { path = "../../../substrate/test-utils" } runtime-benchmarks = [ "cumulus-pallet-parachain-system/runtime-benchmarks", "cumulus-primitives-core/runtime-benchmarks", - "cumulus-primitives-storage-weight-reclaim/runtime-benchmarks", "cumulus-test-client/runtime-benchmarks", "frame-system/runtime-benchmarks", "pallet-im-online/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "parachains-common/runtime-benchmarks", "polkadot-cli/runtime-benchmarks", "polkadot-primitives/runtime-benchmarks", diff --git a/cumulus/test/service/src/bench_utils.rs b/cumulus/test/service/src/bench_utils.rs index 15128b23787..4ace894b392 100644 --- a/cumulus/test/service/src/bench_utils.rs +++ b/cumulus/test/service/src/bench_utils.rs @@ -69,7 +69,7 @@ pub fn extrinsic_set_time(client: &TestClient) -> OpaqueExtrinsic { let timestamp = best_number as u64 * cumulus_test_runtime::MinimumPeriod::get(); cumulus_test_runtime::UncheckedExtrinsic { - preamble: sp_runtime::generic::Preamble::Bare, + signature: None, function: cumulus_test_runtime::RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: timestamp, }), @@ -102,7 +102,7 @@ pub fn extrinsic_set_validation_data( }; cumulus_test_runtime::UncheckedExtrinsic { - preamble: sp_runtime::generic::Preamble::Bare, + signature: None, function: cumulus_test_runtime::RuntimeCall::ParachainSystem( cumulus_pallet_parachain_system::Call::set_validation_data { data }, ), diff --git a/cumulus/test/service/src/lib.rs b/cumulus/test/service/src/lib.rs index f05dc5f180f..3554a383f21 100644 --- a/cumulus/test/service/src/lib.rs +++ b/cumulus/test/service/src/lib.rs @@ -883,7 +883,7 @@ pub fn construct_extrinsic( .map(|c| c / 2) .unwrap_or(2) as u64; let tip = 0; - let tx_ext: runtime::TxExtension = ( + let extra: runtime::SignedExtra = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckGenesis::::new(), @@ -895,11 +895,10 @@ pub fn construct_extrinsic( frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(tip), cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::::new(), - ) - .into(); + ); let raw_payload = runtime::SignedPayload::from_raw( function.clone(), - tx_ext.clone(), + extra.clone(), ((), runtime::VERSION.spec_version, genesis_block, current_block_hash, (), (), (), ()), ); let signature = raw_payload.using_encoded(|e| caller.sign(e)); @@ -907,7 +906,7 @@ pub fn construct_extrinsic( function, caller.public().into(), runtime::Signature::Sr25519(signature), - tx_ext, + extra, ) } diff --git a/docs/sdk/src/reference_docs/extrinsic_encoding.rs b/docs/sdk/src/reference_docs/extrinsic_encoding.rs index be1af500038..8c8568a228f 100644 --- a/docs/sdk/src/reference_docs/extrinsic_encoding.rs +++ b/docs/sdk/src/reference_docs/extrinsic_encoding.rs @@ -56,7 +56,7 @@ //! version_and_signed, //! from_address, //! signature, -//! transaction_extensions_extra, +//! signed_extensions_extra, //! ) //! ``` //! @@ -90,31 +90,31 @@ //! The signature type used on the Polkadot relay chain is [`sp_runtime::MultiSignature`]; the //! variants there are the types of signature that can be provided. //! -//! ### transaction_extensions_extra +//! ### signed_extensions_extra //! //! This is the concatenation of the [SCALE encoded][frame::deps::codec] bytes representing each of -//! the [_transaction extensions_][sp_runtime::traits::TransactionExtension], and are configured by -//! the fourth generic parameter of [`sp_runtime::generic::UncheckedExtrinsic`]. Learn more about -//! transaction extensions [here][crate::reference_docs::transaction_extensions]. +//! the [_signed extensions_][sp_runtime::traits::SignedExtension], and are configured by the +//! fourth generic parameter of [`sp_runtime::generic::UncheckedExtrinsic`]. Learn more about +//! signed extensions [here][crate::reference_docs::signed_extensions]. //! -//! When it comes to constructing an extrinsic, each transaction extension has two things that we -//! are interested in here: +//! When it comes to constructing an extrinsic, each signed extension has two things that we are +//! interested in here: //! -//! - The actual SCALE encoding of the transaction extension type itself; this is what will form our -//! `transaction_extensions_extra` bytes. -//! - An `Implicit` type. This is SCALE encoded into the `transaction_extensions_implicit` data of -//! the _signed payload_ (see below). +//! - The actual SCALE encoding of the signed extension type itself; this is what will form our +//! `signed_extensions_extra` bytes. +//! - An `AdditionalSigned` type. This is SCALE encoded into the `signed_extensions_additional` data +//! of the _signed payload_ (see below). //! //! Either (or both) of these can encode to zero bytes. //! -//! Each chain configures the set of transaction extensions that it uses in its runtime -//! configuration. At the time of writing, Polkadot configures them +//! Each chain configures the set of signed extensions that it uses in its runtime configuration. +//! At the time of writing, Polkadot configures them //! [here](https://github.com/polkadot-fellows/runtimes/blob/1dc04eb954eadf8aadb5d83990b89662dbb5a074/relay/polkadot/src/lib.rs#L1432C25-L1432C25). -//! Some of the common transaction extensions are defined -//! [here][frame::deps::frame_system#transaction-extensions]. +//! Some of the common signed extensions are defined +//! [here][frame::deps::frame_system#signed-extensions]. //! -//! Information about exactly which transaction extensions are present on a chain and in what order -//! is also a part of the metadata for the chain. For V15 metadata, it can be +//! Information about exactly which signed extensions are present on a chain and in what order is +//! also a part of the metadata for the chain. For V15 metadata, it can be //! [found here][frame::deps::frame_support::__private::metadata::v15::ExtrinsicMetadata]. //! //! ## call_data @@ -163,8 +163,8 @@ //! ```text //! signed_payload = concat( //! call_data, -//! transaction_extensions_extra, -//! transaction_extensions_implicit, +//! signed_extensions_extra, +//! signed_extensions_additional, //! ) //! //! if length(signed_payload) > 256 { @@ -172,16 +172,16 @@ //! } //! ``` //! -//! The bytes representing `call_data` and `transaction_extensions_extra` can be obtained as -//! descibed above. `transaction_extensions_implicit` is constructed by SCALE encoding the -//! ["implicit" data][sp_runtime::traits::TransactionExtensionBase::Implicit] for each -//! transaction extension that the chain is using, in order. +//! The bytes representing `call_data` and `signed_extensions_extra` can be obtained as described +//! above. `signed_extensions_additional` is constructed by SCALE encoding the +//! ["additional signed" data][sp_runtime::traits::SignedExtension::AdditionalSigned] for each +//! signed extension that the chain is using, in order. //! //! Once we've concatenated those together, we hash the result if it's greater than 256 bytes in //! length using a Blake2 256bit hasher. //! //! The [`sp_runtime::generic::SignedPayload`] type takes care of assembling the correct payload -//! for us, given `call_data` and a tuple of transaction extensions. +//! for us, given `call_data` and a tuple of signed extensions. //! //! # Example Encoding //! @@ -192,12 +192,11 @@ #[docify::export] pub mod call_data { use parity_scale_codec::{Decode, Encode}; - use sp_runtime::{traits::Dispatchable, DispatchResultWithInfo}; // The outer enum composes calls within // different pallets together. We have two // pallets, "PalletA" and "PalletB". - #[derive(Encode, Decode, Clone)] + #[derive(Encode, Decode)] pub enum Call { #[codec(index = 0)] PalletA(PalletACall), @@ -208,33 +207,23 @@ pub mod call_data { // An inner enum represents the calls within // a specific pallet. "PalletA" has one call, // "Foo". - #[derive(Encode, Decode, Clone)] + #[derive(Encode, Decode)] pub enum PalletACall { #[codec(index = 0)] Foo(String), } - #[derive(Encode, Decode, Clone)] + #[derive(Encode, Decode)] pub enum PalletBCall { #[codec(index = 0)] Bar(String), } - - impl Dispatchable for Call { - type RuntimeOrigin = (); - type Config = (); - type Info = (); - type PostInfo = (); - fn dispatch(self, _origin: Self::RuntimeOrigin) -> DispatchResultWithInfo { - Ok(()) - } - } } #[docify::export] pub mod encoding_example { use super::call_data::{Call, PalletACall}; - use crate::reference_docs::transaction_extensions::transaction_extensions_example; + use crate::reference_docs::signed_extensions::signed_extensions_example; use parity_scale_codec::Encode; use sp_core::crypto::AccountId32; use sp_keyring::sr25519::Keyring; @@ -243,40 +232,34 @@ pub mod encoding_example { MultiAddress, MultiSignature, }; - // Define some transaction extensions to use. We'll use a couple of examples - // from the transaction extensions reference doc. - type TransactionExtensions = ( - transaction_extensions_example::AddToPayload, - transaction_extensions_example::AddToSignaturePayload, - ); + // Define some signed extensions to use. We'll use a couple of examples + // from the signed extensions reference doc. + type SignedExtensions = + (signed_extensions_example::AddToPayload, signed_extensions_example::AddToSignaturePayload); // We'll use `UncheckedExtrinsic` to encode our extrinsic for us. We set // the address and signature type to those used on Polkadot, use our custom - // `Call` type, and use our custom set of `TransactionExtensions`. - type Extrinsic = UncheckedExtrinsic< - MultiAddress, - Call, - MultiSignature, - TransactionExtensions, - >; + // `Call` type, and use our custom set of `SignedExtensions`. + type Extrinsic = + UncheckedExtrinsic, Call, MultiSignature, SignedExtensions>; pub fn encode_demo_extrinsic() -> Vec { // The "from" address will be our Alice dev account. let from_address = MultiAddress::::Id(Keyring::Alice.to_account_id()); - // We provide some values for our expected transaction extensions. - let transaction_extensions = ( - transaction_extensions_example::AddToPayload(1), - transaction_extensions_example::AddToSignaturePayload, + // We provide some values for our expected signed extensions. + let signed_extensions = ( + signed_extensions_example::AddToPayload(1), + signed_extensions_example::AddToSignaturePayload, ); // Construct our call data: let call_data = Call::PalletA(PalletACall::Foo("Hello".to_string())); // The signed payload. This takes care of encoding the call_data, - // transaction_extensions_extra and transaction_extensions_implicit, and hashing + // signed_extensions_extra and signed_extensions_additional, and hashing // the result if it's > 256 bytes: - let signed_payload = SignedPayload::new(call_data.clone(), transaction_extensions.clone()); + let signed_payload = SignedPayload::new(&call_data, signed_extensions.clone()); // Sign the signed payload with our Alice dev account's private key, // and wrap the signature into the expected type: @@ -286,7 +269,7 @@ pub mod encoding_example { }; // Now, we can build and encode our extrinsic: - let ext = Extrinsic::new_signed(call_data, from_address, signature, transaction_extensions); + let ext = Extrinsic::new_signed(call_data, from_address, signature, signed_extensions); let encoded_ext = ext.encode(); encoded_ext diff --git a/docs/sdk/src/reference_docs/frame_runtime_types.rs b/docs/sdk/src/reference_docs/frame_runtime_types.rs index 883892729d1..b5838b79e51 100644 --- a/docs/sdk/src/reference_docs/frame_runtime_types.rs +++ b/docs/sdk/src/reference_docs/frame_runtime_types.rs @@ -130,7 +130,7 @@ //! * [`crate::reference_docs::frame_origin`] explores further details about the usage of //! `RuntimeOrigin`. //! * [`RuntimeCall`] is a particularly interesting composite enum as it dictates the encoding of an -//! extrinsic. See [`crate::reference_docs::transaction_extensions`] for more information. +//! extrinsic. See [`crate::reference_docs::signed_extensions`] for more information. //! * See the documentation of [`construct_runtime`]. //! * See the corresponding lecture in the [pba-book](https://polkadot-blockchain-academy.github.io/pba-book/frame/outer-enum/page.html). //! diff --git a/docs/sdk/src/reference_docs/mod.rs b/docs/sdk/src/reference_docs/mod.rs index f4b52208e2f..de0b012bb12 100644 --- a/docs/sdk/src/reference_docs/mod.rs +++ b/docs/sdk/src/reference_docs/mod.rs @@ -39,9 +39,9 @@ pub mod runtime_vs_smart_contract; /// Learn about how extrinsics are encoded to be transmitted to a node and stored in blocks. pub mod extrinsic_encoding; -/// Learn about the transaction extensions that form a part of extrinsics. +/// Learn about the signed extensions that form a part of extrinsics. // TODO: @jsdw https://github.com/paritytech/polkadot-sdk-docs/issues/42 -pub mod transaction_extensions; +pub mod signed_extensions; /// Learn about *Origins*, a topic in FRAME that enables complex account abstractions to be built. pub mod frame_origin; diff --git a/docs/sdk/src/reference_docs/signed_extensions.rs b/docs/sdk/src/reference_docs/signed_extensions.rs new file mode 100644 index 00000000000..28b1426536b --- /dev/null +++ b/docs/sdk/src/reference_docs/signed_extensions.rs @@ -0,0 +1,79 @@ +//! Signed extensions are, briefly, a means for different chains to extend the "basic" extrinsic +//! format with custom data that can be checked by the runtime. +//! +//! # Example +//! +//! Defining a couple of very simple signed extensions looks like the following: +#![doc = docify::embed!("./src/reference_docs/signed_extensions.rs", signed_extensions_example)] + +#[docify::export] +pub mod signed_extensions_example { + use parity_scale_codec::{Decode, Encode}; + use scale_info::TypeInfo; + use sp_runtime::traits::SignedExtension; + + // This doesn't actually check anything, but simply allows + // some arbitrary `u32` to be added to the extrinsic payload + #[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)] + pub struct AddToPayload(pub u32); + + impl SignedExtension for AddToPayload { + const IDENTIFIER: &'static str = "AddToPayload"; + type AccountId = (); + type Call = (); + type AdditionalSigned = (); + type Pre = (); + + fn additional_signed( + &self, + ) -> Result< + Self::AdditionalSigned, + sp_runtime::transaction_validity::TransactionValidityError, + > { + Ok(()) + } + + fn pre_dispatch( + self, + _who: &Self::AccountId, + _call: &Self::Call, + _info: &sp_runtime::traits::DispatchInfoOf, + _len: usize, + ) -> Result { + Ok(()) + } + } + + // This is the opposite; nothing will be added to the extrinsic payload, + // but the AdditionalSigned type (`1234u32`) will be added to the + // payload to be signed. + #[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)] + pub struct AddToSignaturePayload; + + impl SignedExtension for AddToSignaturePayload { + const IDENTIFIER: &'static str = "AddToSignaturePayload"; + type AccountId = (); + type Call = (); + type AdditionalSigned = u32; + type Pre = (); + + fn additional_signed( + &self, + ) -> Result< + Self::AdditionalSigned, + sp_runtime::transaction_validity::TransactionValidityError, + > { + Ok(1234) + } + + fn pre_dispatch( + self, + _who: &Self::AccountId, + _call: &Self::Call, + _info: &sp_runtime::traits::DispatchInfoOf, + _len: usize, + ) -> Result { + Ok(()) + } + } +} diff --git a/docs/sdk/src/reference_docs/transaction_extensions.rs b/docs/sdk/src/reference_docs/transaction_extensions.rs deleted file mode 100644 index 4f96d665d9b..00000000000 --- a/docs/sdk/src/reference_docs/transaction_extensions.rs +++ /dev/null @@ -1,57 +0,0 @@ -//! Transaction extensions are, briefly, a means for different chains to extend the "basic" -//! extrinsic format with custom data that can be checked by the runtime. -//! -//! # Example -//! -//! Defining a couple of very simple transaction extensions looks like the following: -#![doc = docify::embed!("./src/reference_docs/transaction_extensions.rs", transaction_extensions_example)] - -#[docify::export] -pub mod transaction_extensions_example { - use parity_scale_codec::{Decode, Encode}; - use scale_info::TypeInfo; - use sp_runtime::{ - impl_tx_ext_default, - traits::{Dispatchable, TransactionExtension, TransactionExtensionBase}, - TransactionValidityError, - }; - - // This doesn't actually check anything, but simply allows - // some arbitrary `u32` to be added to the extrinsic payload - #[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)] - pub struct AddToPayload(pub u32); - - impl TransactionExtensionBase for AddToPayload { - const IDENTIFIER: &'static str = "AddToPayload"; - type Implicit = (); - } - - impl TransactionExtension for AddToPayload { - type Pre = (); - type Val = (); - - impl_tx_ext_default!(Call; (); validate prepare); - } - - // This is the opposite; nothing will be added to the extrinsic payload, - // but the Implicit type (`1234u32`) will be added to the - // payload to be signed. - #[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)] - pub struct AddToSignaturePayload; - - impl TransactionExtensionBase for AddToSignaturePayload { - const IDENTIFIER: &'static str = "AddToSignaturePayload"; - type Implicit = u32; - - fn implicit(&self) -> Result { - Ok(1234) - } - } - - impl TransactionExtension for AddToSignaturePayload { - type Pre = (); - type Val = (); - - impl_tx_ext_default!(Call; (); validate prepare); - } -} diff --git a/polkadot/node/service/Cargo.toml b/polkadot/node/service/Cargo.toml index 180de70ad6c..734dcbdeb44 100644 --- a/polkadot/node/service/Cargo.toml +++ b/polkadot/node/service/Cargo.toml @@ -196,7 +196,6 @@ runtime-benchmarks = [ "pallet-babe/runtime-benchmarks", "pallet-im-online/runtime-benchmarks", "pallet-staking/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-primitives/runtime-benchmarks", "polkadot-runtime-parachains/runtime-benchmarks", diff --git a/polkadot/node/service/src/benchmarking.rs b/polkadot/node/service/src/benchmarking.rs index 29acc5c3ca8..400daf1aee3 100644 --- a/polkadot/node/service/src/benchmarking.rs +++ b/polkadot/node/service/src/benchmarking.rs @@ -189,7 +189,7 @@ fn westend_sign_call( use sp_core::Pair; use westend_runtime as runtime; - let tx_ext: runtime::TxExtension = ( + let extra: runtime::SignedExtra = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -201,12 +201,11 @@ fn westend_sign_call( frame_system::CheckNonce::::from(nonce), frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(0), - ) - .into(); + ); let payload = runtime::SignedPayload::from_raw( call.clone(), - tx_ext.clone(), + extra.clone(), ( (), runtime::VERSION.spec_version, @@ -224,7 +223,7 @@ fn westend_sign_call( call, sp_runtime::AccountId32::from(acc.public()).into(), polkadot_core_primitives::Signature::Sr25519(signature.clone()), - tx_ext, + extra, ) .into() } @@ -242,7 +241,7 @@ fn rococo_sign_call( use rococo_runtime as runtime; use sp_core::Pair; - let tx_ext: runtime::TxExtension = ( + let extra: runtime::SignedExtra = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -254,12 +253,11 @@ fn rococo_sign_call( frame_system::CheckNonce::::from(nonce), frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(0), - ) - .into(); + ); let payload = runtime::SignedPayload::from_raw( call.clone(), - tx_ext.clone(), + extra.clone(), ( (), runtime::VERSION.spec_version, @@ -277,7 +275,7 @@ fn rococo_sign_call( call, sp_runtime::AccountId32::from(acc.public()).into(), polkadot_core_primitives::Signature::Sr25519(signature.clone()), - tx_ext, + extra, ) .into() } diff --git a/polkadot/node/test/service/Cargo.toml b/polkadot/node/test/service/Cargo.toml index 02b227e6f34..e7892abcd87 100644 --- a/polkadot/node/test/service/Cargo.toml +++ b/polkadot/node/test/service/Cargo.toml @@ -71,7 +71,6 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-staking/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", diff --git a/polkadot/node/test/service/src/lib.rs b/polkadot/node/test/service/src/lib.rs index 1876595c7b4..ca904bae28d 100644 --- a/polkadot/node/test/service/src/lib.rs +++ b/polkadot/node/test/service/src/lib.rs @@ -32,7 +32,7 @@ use polkadot_service::{ Error, FullClient, IsParachainNode, NewFull, OverseerGen, PrometheusConfig, }; use polkadot_test_runtime::{ - ParasCall, ParasSudoWrapperCall, Runtime, SignedPayload, SudoCall, TxExtension, + ParasCall, ParasSudoWrapperCall, Runtime, SignedExtra, SignedPayload, SudoCall, UncheckedExtrinsic, VERSION, }; @@ -382,7 +382,7 @@ pub fn construct_extrinsic( let period = BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64; let tip = 0; - let tx_ext: TxExtension = ( + let extra: SignedExtra = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -391,11 +391,10 @@ pub fn construct_extrinsic( frame_system::CheckNonce::::from(nonce), frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(tip), - ) - .into(); + ); let raw_payload = SignedPayload::from_raw( function.clone(), - tx_ext.clone(), + extra.clone(), ( (), VERSION.spec_version, @@ -412,7 +411,7 @@ pub fn construct_extrinsic( function.clone(), polkadot_test_runtime::Address::Id(caller.public().into()), polkadot_primitives::Signature::Sr25519(signature.clone()), - tx_ext.clone(), + extra.clone(), ) } diff --git a/polkadot/runtime/common/Cargo.toml b/polkadot/runtime/common/Cargo.toml index c2205938295..eae5d4fb2ef 100644 --- a/polkadot/runtime/common/Cargo.toml +++ b/polkadot/runtime/common/Cargo.toml @@ -132,7 +132,6 @@ runtime-benchmarks = [ "pallet-identity/runtime-benchmarks", "pallet-staking/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", "pallet-vesting/runtime-benchmarks", "primitives/runtime-benchmarks", diff --git a/polkadot/runtime/common/src/claims.rs b/polkadot/runtime/common/src/claims.rs index 57a95b22af3..68f42914e44 100644 --- a/polkadot/runtime/common/src/claims.rs +++ b/polkadot/runtime/common/src/claims.rs @@ -29,11 +29,7 @@ use scale_info::TypeInfo; use serde::{self, Deserialize, Deserializer, Serialize, Serializer}; use sp_io::{crypto::secp256k1_ecdsa_recover, hashing::keccak_256}; use sp_runtime::{ - impl_tx_ext_default, - traits::{ - AsSystemOriginSigner, CheckedSub, DispatchInfoOf, Dispatchable, TransactionExtension, - TransactionExtensionBase, Zero, - }, + traits::{CheckedSub, DispatchInfoOf, SignedExtension, Zero}, transaction_validity::{ InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction, }, @@ -54,7 +50,6 @@ pub trait WeightInfo { fn claim_attest() -> Weight; fn attest() -> Weight; fn move_claim() -> Weight; - fn prevalidate_attests() -> Weight; } pub struct TestWeightInfo; @@ -74,9 +69,6 @@ impl WeightInfo for TestWeightInfo { fn move_claim() -> Weight { Weight::zero() } - fn prevalidate_attests() -> Weight { - Weight::zero() - } } /// The kind of statement an account needs to make for a claim to be valid. @@ -92,7 +84,7 @@ pub enum StatementKind { impl StatementKind { /// Convert this to the (English) statement it represents. - pub fn to_text(self) -> &'static [u8] { + fn to_text(self) -> &'static [u8] { match self { StatementKind::Regular => &b"I hereby agree to the terms of the statement whose SHA-256 multihash is \ @@ -174,13 +166,6 @@ pub mod pallet { #[pallet::without_storage_info] pub struct Pallet(_); - #[cfg(feature = "runtime-benchmarks")] - /// Helper trait to benchmark the `PrevalidateAttests` transaction extension. - pub trait BenchmarkHelperTrait { - /// `Call` to be used when benchmarking the transaction extension. - fn default_call_and_info() -> (RuntimeCall, DispatchInfo); - } - /// Configuration trait. #[pallet::config] pub trait Config: frame_system::Config { @@ -191,12 +176,6 @@ pub mod pallet { type Prefix: Get<&'static [u8]>; type MoveClaimOrigin: EnsureOrigin; type WeightInfo: WeightInfo; - #[cfg(feature = "runtime-benchmarks")] - /// Benchmark helper - type BenchmarkHelper: BenchmarkHelperTrait< - Self::RuntimeCall, - DispatchInfoOf, - >; } #[pallet::event] @@ -423,7 +402,7 @@ pub mod pallet { /// Attest to a statement, needed to finalize the claims process. /// /// WARNING: Insecure unless your chain includes `PrevalidateAttests` as a - /// `TransactionExtension`. + /// `SignedExtension`. /// /// Unsigned Validation: /// A call to attest is deemed valid if the sender has a `Preclaim` registered @@ -633,46 +612,46 @@ impl PrevalidateAttests where ::RuntimeCall: IsSubType>, { - /// Create new `TransactionExtension` to check runtime version. + /// Create new `SignedExtension` to check runtime version. pub fn new() -> Self { Self(sp_std::marker::PhantomData) } } -impl TransactionExtensionBase for PrevalidateAttests +impl SignedExtension for PrevalidateAttests where ::RuntimeCall: IsSubType>, { + type AccountId = T::AccountId; + type Call = ::RuntimeCall; + type AdditionalSigned = (); + type Pre = (); const IDENTIFIER: &'static str = "PrevalidateAttests"; - type Implicit = (); -} -impl TransactionExtension for PrevalidateAttests -where - ::RuntimeCall: IsSubType>, - <::RuntimeCall as Dispatchable>::RuntimeOrigin: - AsSystemOriginSigner + Clone, -{ - type Pre = (); - type Val = (); + fn additional_signed(&self) -> Result { + Ok(()) + } + + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + self.validate(who, call, info, len).map(|_| ()) + } // // The weight of this logic is included in the `attest` dispatchable. // fn validate( &self, - origin: ::RuntimeOrigin, - call: &T::RuntimeCall, - _info: &DispatchInfoOf, + who: &Self::AccountId, + call: &Self::Call, + _info: &DispatchInfoOf, _len: usize, - _context: &mut Context, - _self_implicit: Self::Implicit, - _inherited_implication: &impl Encode, - ) -> Result< - (ValidTransaction, Self::Val, ::RuntimeOrigin), - TransactionValidityError, - > { - let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?; + ) -> TransactionValidity { if let Some(local_call) = call.is_sub_type() { if let Call::attest { statement: attested_statement } = local_call { let signer = Preclaims::::get(who) @@ -683,9 +662,8 @@ where } } } - Ok((ValidTransaction::default(), (), origin)) + Ok(ValidTransaction::default()) } - impl_tx_ext_default!(T::RuntimeCall; Context; prepare); } #[cfg(any(test, feature = "runtime-benchmarks"))] @@ -718,7 +696,7 @@ mod secp_utils { } #[cfg(test)] -pub(super) mod tests { +mod tests { use super::*; use hex_literal::hex; use secp_utils::*; @@ -736,11 +714,8 @@ pub(super) mod tests { }; use pallet_balances; use sp_runtime::{ - traits::{DispatchTransaction, Identity}, - transaction_validity::TransactionLongevity, - BuildStorage, - DispatchError::BadOrigin, - TokenError, + traits::Identity, transaction_validity::TransactionLongevity, BuildStorage, + DispatchError::BadOrigin, TokenError, }; type Block = frame_system::mocking::MockBlock; @@ -815,19 +790,6 @@ pub(super) mod tests { type Prefix = Prefix; type MoveClaimOrigin = frame_system::EnsureSignedBy; type WeightInfo = TestWeightInfo; - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = (); - } - - #[cfg(feature = "runtime-benchmarks")] - impl BenchmarkHelperTrait> for () { - fn default_call_and_info() -> (RuntimeCall, DispatchInfoOf) { - let call = RuntimeCall::Claims(crate::claims::Call::attest { - statement: StatementKind::Regular.to_text().to_vec(), - }); - let info = call.get_dispatch_info(); - (call, info) - } } fn alice() -> libsecp256k1::SecretKey { @@ -1109,8 +1071,8 @@ pub(super) mod tests { }); let di = c.get_dispatch_info(); assert_eq!(di.pays_fee, Pays::No); - let r = p.validate_only(Some(42).into(), &c, &di, 20); - assert_eq!(r.unwrap().0, ValidTransaction::default()); + let r = p.validate(&42, &c, &di, 20); + assert_eq!(r, TransactionValidity::Ok(ValidTransaction::default())); }); } @@ -1122,13 +1084,13 @@ pub(super) mod tests { statement: StatementKind::Regular.to_text().to_vec(), }); let di = c.get_dispatch_info(); - let r = p.validate_only(Some(42).into(), &c, &di, 20); + let r = p.validate(&42, &c, &di, 20); assert!(r.is_err()); let c = RuntimeCall::Claims(ClaimsCall::attest { statement: StatementKind::Saft.to_text().to_vec(), }); let di = c.get_dispatch_info(); - let r = p.validate_only(Some(69).into(), &c, &di, 20); + let r = p.validate(&69, &c, &di, 20); assert!(r.is_err()); }); } @@ -1482,17 +1444,14 @@ pub(super) mod tests { } #[cfg(feature = "runtime-benchmarks")] -pub(super) mod benchmarking { +mod benchmarking { use super::*; use crate::claims::Call; use frame_benchmarking::{account, benchmarks}; use frame_support::traits::UnfilteredDispatchable; use frame_system::RawOrigin; use secp_utils::*; - use sp_runtime::{ - traits::{DispatchTransaction, ValidateUnsigned}, - DispatchResult, - }; + use sp_runtime::{traits::ValidateUnsigned, DispatchResult}; const SEED: u32 = 0; @@ -1528,11 +1487,6 @@ pub(super) mod benchmarking { } benchmarks! { - where_clause { where ::RuntimeCall: IsSubType>, - <::RuntimeCall as Dispatchable>::RuntimeOrigin: AsSystemOriginSigner + Clone, - <::RuntimeCall as Dispatchable>::PostInfo: Default, - } - // Benchmark `claim` including `validate_unsigned` logic. claim { let c = MAX_CLAIMS; @@ -1711,38 +1665,6 @@ pub(super) mod benchmarking { } } - prevalidate_attests { - let c = MAX_CLAIMS; - - for i in 0 .. c / 2 { - create_claim::(c)?; - create_claim_attest::(u32::MAX - c)?; - } - - let ext = PrevalidateAttests::::new(); - let (call, info) = T::BenchmarkHelper::default_call_and_info(); - let attest_c = u32::MAX - c; - let secret_key = libsecp256k1::SecretKey::parse(&keccak_256(&attest_c.encode())).unwrap(); - let eth_address = eth(&secret_key); - let account: T::AccountId = account("user", c, SEED); - let vesting = Some((100_000u32.into(), 1_000u32.into(), 100u32.into())); - let statement = StatementKind::Regular; - let signature = sig::(&secret_key, &account.encode(), statement.to_text()); - super::Pallet::::mint_claim(RawOrigin::Root.into(), eth_address, VALUE.into(), vesting, Some(statement))?; - Preclaims::::insert(&account, eth_address); - assert_eq!(Claims::::get(eth_address), Some(VALUE.into())); - }: { - assert!(ext.test_run( - RawOrigin::Signed(account).into(), - &call, - &info, - 0, - |_| { - Ok(Default::default()) - } - ).unwrap().is_ok()); - } - impl_benchmark_test_suite!( Pallet, crate::claims::tests::new_test_ext(), diff --git a/polkadot/runtime/rococo/Cargo.toml b/polkadot/runtime/rococo/Cargo.toml index 61ca1635ac9..3dc59cc1728 100644 --- a/polkadot/runtime/rococo/Cargo.toml +++ b/polkadot/runtime/rococo/Cargo.toml @@ -246,7 +246,6 @@ runtime-benchmarks = [ "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-tips/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-vesting/runtime-benchmarks", diff --git a/polkadot/runtime/rococo/constants/src/weights/block_weights.rs b/polkadot/runtime/rococo/constants/src/weights/block_weights.rs index f7dc2f19316..e2aa4a6cab7 100644 --- a/polkadot/runtime/rococo/constants/src/weights/block_weights.rs +++ b/polkadot/runtime/rococo/constants/src/weights/block_weights.rs @@ -14,13 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29 (Y/M/D) -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26 (Y/M/D) +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` //! //! SHORT-NAME: `block`, LONG-NAME: `BlockExecution`, RUNTIME: `Development` //! WARMUPS: `10`, REPEAT: `100` -//! WEIGHT-PATH: `./polkadot/runtime/rococo/constants/src/weights/` +//! WEIGHT-PATH: `runtime/rococo/constants/src/weights/` //! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0` // Executed Command: @@ -28,11 +28,12 @@ // benchmark // overhead // --chain=rococo-dev +// --execution=wasm // --wasm-execution=compiled -// --weight-path=./polkadot/runtime/rococo/constants/src/weights/ +// --weight-path=runtime/rococo/constants/src/weights/ // --warmup=10 // --repeat=100 -// --header=./polkadot/file_header.txt +// --header=./file_header.txt use sp_core::parameter_types; use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight}; @@ -42,17 +43,17 @@ parameter_types! { /// Calculated by multiplying the *Average* with `1.0` and adding `0`. /// /// Stats nanoseconds: - /// Min, Max: 440_142, 476_907 - /// Average: 450_240 - /// Median: 448_633 - /// Std-Dev: 7301.18 + /// Min, Max: 408_659, 450_716 + /// Average: 417_412 + /// Median: 411_177 + /// Std-Dev: 12242.31 /// /// Percentiles nanoseconds: - /// 99th: 470_733 - /// 95th: 465_082 - /// 75th: 452_536 + /// 99th: 445_142 + /// 95th: 442_275 + /// 75th: 414_217 pub const BlockExecutionWeight: Weight = - Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(450_240), 0); + Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(417_412), 0); } #[cfg(test)] diff --git a/polkadot/runtime/rococo/constants/src/weights/extrinsic_weights.rs b/polkadot/runtime/rococo/constants/src/weights/extrinsic_weights.rs index 000cee8a237..adce840ebbc 100644 --- a/polkadot/runtime/rococo/constants/src/weights/extrinsic_weights.rs +++ b/polkadot/runtime/rococo/constants/src/weights/extrinsic_weights.rs @@ -14,13 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29 (Y/M/D) -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26 (Y/M/D) +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` //! //! SHORT-NAME: `extrinsic`, LONG-NAME: `ExtrinsicBase`, RUNTIME: `Development` //! WARMUPS: `10`, REPEAT: `100` -//! WEIGHT-PATH: `./polkadot/runtime/rococo/constants/src/weights/` +//! WEIGHT-PATH: `runtime/rococo/constants/src/weights/` //! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0` // Executed Command: @@ -28,11 +28,12 @@ // benchmark // overhead // --chain=rococo-dev +// --execution=wasm // --wasm-execution=compiled -// --weight-path=./polkadot/runtime/rococo/constants/src/weights/ +// --weight-path=runtime/rococo/constants/src/weights/ // --warmup=10 // --repeat=100 -// --header=./polkadot/file_header.txt +// --header=./file_header.txt use sp_core::parameter_types; use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight}; @@ -42,17 +43,17 @@ parameter_types! { /// Calculated by multiplying the *Average* with `1.0` and adding `0`. /// /// Stats nanoseconds: - /// Min, Max: 92_961, 94_143 - /// Average: 93_369 - /// Median: 93_331 - /// Std-Dev: 217.39 + /// Min, Max: 97_574, 100_119 + /// Average: 98_236 + /// Median: 98_179 + /// Std-Dev: 394.9 /// /// Percentiles nanoseconds: - /// 99th: 93_848 - /// 95th: 93_691 - /// 75th: 93_514 + /// 99th: 99_893 + /// 95th: 98_850 + /// 75th: 98_318 pub const ExtrinsicBaseWeight: Weight = - Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(93_369), 0); + Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(98_236), 0); } #[cfg(test)] diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index ff54c777670..96e8c4e0979 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -199,7 +199,6 @@ impl frame_system::Config for Runtime { type Version = Version; type AccountData = pallet_balances::AccountData; type SystemWeightInfo = weights::frame_system::WeightInfo; - type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; type SS58Prefix = SS58Prefix; type MaxConsumers = frame_support::traits::ConstU32<16>; } @@ -330,7 +329,6 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; - type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { @@ -593,7 +591,7 @@ where // so the actual block number is `n`. .saturating_sub(1); let tip = 0; - let tx_ext: TxExtension = ( + let extra: SignedExtra = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -605,17 +603,16 @@ where frame_system::CheckNonce::::from(nonce), frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(tip), - ) - .into(); - let raw_payload = SignedPayload::new(call, tx_ext) + ); + let raw_payload = SignedPayload::new(call, extra) .map_err(|e| { log::warn!("Unable to create signed payload: {:?}", e); }) .ok()?; let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?; - let (call, tx_ext, _) = raw_payload.deconstruct(); + let (call, extra, _) = raw_payload.deconstruct(); let address = ::Lookup::unlookup(account); - Some((call, (address, signature, tx_ext))) + Some((call, (address, signature, extra))) } } @@ -636,32 +633,12 @@ parameter_types! { pub Prefix: &'static [u8] = b"Pay ROCs to the Rococo account:"; } -#[cfg(feature = "runtime-benchmarks")] -pub struct ClaimsHelper; - -#[cfg(feature = "runtime-benchmarks")] -use frame_support::dispatch::DispatchInfo; - -#[cfg(feature = "runtime-benchmarks")] -impl claims::BenchmarkHelperTrait for ClaimsHelper { - fn default_call_and_info() -> (RuntimeCall, DispatchInfo) { - use frame_support::dispatch::GetDispatchInfo; - let call = RuntimeCall::Claims(claims::Call::attest { - statement: claims::StatementKind::Regular.to_text().to_vec(), - }); - let info = call.get_dispatch_info(); - (call, info) - } -} - impl claims::Config for Runtime { type RuntimeEvent = RuntimeEvent; type VestingSchedule = Vesting; type Prefix = Prefix; type MoveClaimOrigin = EnsureRoot; type WeightInfo = weights::runtime_common_claims::WeightInfo; - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = ClaimsHelper; } parameter_types! { @@ -1470,8 +1447,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// `BlockId` type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The extension to the basic transaction logic. -pub type TxExtension = ( +/// The `SignedExtension` to the basic transaction logic. +pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -1484,7 +1461,7 @@ pub type TxExtension = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// All migrations that will run on the next runtime upgrade. /// @@ -1698,7 +1675,7 @@ pub type Executive = frame_executive::Executive< Migrations, >; /// The payload being signed in transactions. -pub type SignedPayload = generic::SignedPayload; +pub type SignedPayload = generic::SignedPayload; parameter_types! { // The deposit configuration for the singed migration. Specially if you want to allow any signed account to do the migration (see `SignedFilter`, these deposits should be high) @@ -1769,9 +1746,7 @@ mod benches { [pallet_scheduler, Scheduler] [pallet_sudo, Sudo] [frame_system, SystemBench::] - [frame_system_extensions, SystemExtensionsBench::] [pallet_timestamp, Timestamp] - [pallet_transaction_payment, TransactionPayment] [pallet_treasury, Treasury] [pallet_utility, Utility] [pallet_vesting, Vesting] @@ -2265,7 +2240,6 @@ sp_api::impl_runtime_apis! { use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use frame_benchmarking::baseline::Pallet as Baseline; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; @@ -2286,7 +2260,6 @@ sp_api::impl_runtime_apis! { use frame_support::traits::WhitelistedStorageKeys; use frame_benchmarking::{Benchmarking, BenchmarkBatch, BenchmarkError}; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use frame_benchmarking::baseline::Pallet as Baseline; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; use sp_storage::TrackedStorageKey; diff --git a/polkadot/runtime/rococo/src/weights/frame_benchmarking_baseline.rs b/polkadot/runtime/rococo/src/weights/frame_benchmarking_baseline.rs index 0f68a5c6fb3..dfba0cfc4aa 100644 --- a/polkadot/runtime/rococo/src/weights/frame_benchmarking_baseline.rs +++ b/polkadot/runtime/rococo/src/weights/frame_benchmarking_baseline.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `frame_benchmarking::baseline` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=frame_benchmarking::baseline // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/frame_benchmarking_baseline.rs +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/frame_benchmarking_baseline.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -55,8 +52,8 @@ impl frame_benchmarking::baseline::WeightInfo for Weigh // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 172_000 picoseconds. - Weight::from_parts(199_481, 0) + // Minimum execution time: 157_000 picoseconds. + Weight::from_parts(175_233, 0) .saturating_add(Weight::from_parts(0, 0)) } /// The range of component `i` is `[0, 1000000]`. @@ -64,8 +61,8 @@ impl frame_benchmarking::baseline::WeightInfo for Weigh // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 171_000 picoseconds. - Weight::from_parts(197_821, 0) + // Minimum execution time: 149_000 picoseconds. + Weight::from_parts(183_285, 0) .saturating_add(Weight::from_parts(0, 0)) } /// The range of component `i` is `[0, 1000000]`. @@ -73,8 +70,8 @@ impl frame_benchmarking::baseline::WeightInfo for Weigh // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 172_000 picoseconds. - Weight::from_parts(200_942, 0) + // Minimum execution time: 158_000 picoseconds. + Weight::from_parts(184_720, 0) .saturating_add(Weight::from_parts(0, 0)) } /// The range of component `i` is `[0, 1000000]`. @@ -82,16 +79,16 @@ impl frame_benchmarking::baseline::WeightInfo for Weigh // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 170_000 picoseconds. - Weight::from_parts(196_906, 0) + // Minimum execution time: 152_000 picoseconds. + Weight::from_parts(177_496, 0) .saturating_add(Weight::from_parts(0, 0)) } fn hashing() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 23_346_876_000 picoseconds. - Weight::from_parts(23_363_744_000, 0) + // Minimum execution time: 19_907_376_000 picoseconds. + Weight::from_parts(19_988_727_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// The range of component `i` is `[0, 100]`. @@ -99,10 +96,10 @@ impl frame_benchmarking::baseline::WeightInfo for Weigh // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 201_000 picoseconds. - Weight::from_parts(219_000, 0) + // Minimum execution time: 198_000 picoseconds. + Weight::from_parts(228_000, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 14_372 - .saturating_add(Weight::from_parts(45_375_800, 0).saturating_mul(i.into())) + // Standard Error: 20_467 + .saturating_add(Weight::from_parts(47_443_635, 0).saturating_mul(i.into())) } } diff --git a/polkadot/runtime/rococo/src/weights/frame_system.rs b/polkadot/runtime/rococo/src/weights/frame_system.rs index 1742a761ca7..2e49483dcc6 100644 --- a/polkadot/runtime/rococo/src/weights/frame_system.rs +++ b/polkadot/runtime/rococo/src/weights/frame_system.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `frame_system` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=frame_system // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -55,91 +52,91 @@ impl frame_system::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_541_000 picoseconds. - Weight::from_parts(2_581_470, 0) + // Minimum execution time: 2_283_000 picoseconds. + Weight::from_parts(2_305_000, 0) .saturating_add(Weight::from_parts(0, 0)) // Standard Error: 0 - .saturating_add(Weight::from_parts(387, 0).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(366, 0).saturating_mul(b.into())) } /// The range of component `b` is `[0, 3932160]`. fn remark_with_event(b: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_060_000 picoseconds. - Weight::from_parts(5_167_000, 0) + // Minimum execution time: 7_435_000 picoseconds. + Weight::from_parts(7_581_000, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 1 - .saturating_add(Weight::from_parts(1_696, 0).saturating_mul(b.into())) + // Standard Error: 0 + .saturating_add(Weight::from_parts(1_408, 0).saturating_mul(b.into())) } - /// Storage: `System::Digest` (r:1 w:1) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x3a686561707061676573` (r:0 w:1) - /// Proof: UNKNOWN KEY `0x3a686561707061676573` (r:0 w:1) + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a686561707061676573` (r:0 w:1) + /// Proof Skipped: unknown `0x3a686561707061676573` (r:0 w:1) fn set_heap_pages() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `1485` - // Minimum execution time: 2_649_000 picoseconds. - Weight::from_parts(2_909_000, 0) + // Minimum execution time: 4_010_000 picoseconds. + Weight::from_parts(4_112_000, 0) .saturating_add(Weight::from_parts(0, 1485)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `System::Digest` (r:1 w:1) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) - /// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a636f6465` (r:0 w:1) + /// Proof Skipped: unknown `0x3a636f6465` (r:0 w:1) fn set_code() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `1485` - // Minimum execution time: 88_417_540_000 picoseconds. - Weight::from_parts(91_809_291_000, 0) + // Minimum execution time: 80_405_511_000 picoseconds. + Weight::from_parts(83_066_478_000, 0) .saturating_add(Weight::from_parts(0, 1485)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Skipped::Metadata` (r:0 w:0) - /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) /// The range of component `i` is `[0, 1000]`. fn set_storage(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_538_000 picoseconds. - Weight::from_parts(1_589_000, 0) + // Minimum execution time: 2_210_000 picoseconds. + Weight::from_parts(2_247_000, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 1_740 - .saturating_add(Weight::from_parts(730_941, 0).saturating_mul(i.into())) + // Standard Error: 2_058 + .saturating_add(Weight::from_parts(673_943, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) } - /// Storage: `Skipped::Metadata` (r:0 w:0) - /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) /// The range of component `i` is `[0, 1000]`. fn kill_storage(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_567_000 picoseconds. - Weight::from_parts(1_750_000, 0) + // Minimum execution time: 2_125_000 picoseconds. + Weight::from_parts(2_154_000, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 835 - .saturating_add(Weight::from_parts(543_218, 0).saturating_mul(i.into())) + // Standard Error: 816 + .saturating_add(Weight::from_parts(491_194, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) } - /// Storage: `Skipped::Metadata` (r:0 w:0) - /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) /// The range of component `p` is `[0, 1000]`. fn kill_prefix(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `80 + p * (69 ±0)` - // Estimated: `83 + p * (70 ±0)` - // Minimum execution time: 3_412_000 picoseconds. - Weight::from_parts(3_448_000, 0) - .saturating_add(Weight::from_parts(0, 83)) - // Standard Error: 1_395 - .saturating_add(Weight::from_parts(1_142_347, 0).saturating_mul(p.into())) + // Measured: `129 + p * (69 ±0)` + // Estimated: `125 + p * (70 ±0)` + // Minimum execution time: 4_002_000 picoseconds. + Weight::from_parts(4_145_000, 0) + .saturating_add(Weight::from_parts(0, 125)) + // Standard Error: 1_108 + .saturating_add(Weight::from_parts(1_014_971, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) .saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into())) @@ -150,8 +147,8 @@ impl frame_system::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_178_000 picoseconds. - Weight::from_parts(9_780_000, 0) + // Minimum execution time: 33_027_000 picoseconds. + Weight::from_parts(33_027_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -165,8 +162,8 @@ impl frame_system::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `22` // Estimated: `1518` - // Minimum execution time: 94_523_563_000 picoseconds. - Weight::from_parts(96_983_131_000, 0) + // Minimum execution time: 118_101_992_000 picoseconds. + Weight::from_parts(118_101_992_000, 0) .saturating_add(Weight::from_parts(0, 1518)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(3)) diff --git a/polkadot/runtime/rococo/src/weights/frame_system_extensions.rs b/polkadot/runtime/rococo/src/weights/frame_system_extensions.rs deleted file mode 100644 index 40520591f53..00000000000 --- a/polkadot/runtime/rococo/src/weights/frame_system_extensions.rs +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Polkadot. - -// Polkadot is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Polkadot is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Polkadot. If not, see . - -//! Autogenerated weights for `frame_system_extensions` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/production/polkadot -// benchmark -// pallet -// --chain=rococo-dev -// --steps=50 -// --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=frame_system_extensions -// --extrinsic=* -// --execution=wasm -// --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `frame_system_extensions`. -pub struct WeightInfo(PhantomData); -impl frame_system::ExtensionsWeightInfo for WeightInfo { - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_genesis() -> Weight { - // Proof Size summary in bytes: - // Measured: `54` - // Estimated: `3509` - // Minimum execution time: 3_262_000 picoseconds. - Weight::from_parts(3_497_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_mortality() -> Weight { - // Proof Size summary in bytes: - // Measured: `92` - // Estimated: `3509` - // Minimum execution time: 5_416_000 picoseconds. - Weight::from_parts(5_690_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - fn check_non_zero_sender() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 471_000 picoseconds. - Weight::from_parts(552_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn check_nonce() -> Weight { - // Proof Size summary in bytes: - // Measured: `101` - // Estimated: `3593` - // Minimum execution time: 4_847_000 picoseconds. - Weight::from_parts(5_091_000, 0) - .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) - } - fn check_spec_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 388_000 picoseconds. - Weight::from_parts(421_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_tx_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 378_000 picoseconds. - Weight::from_parts(440_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) - /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - fn check_weight() -> Weight { - // Proof Size summary in bytes: - // Measured: `24` - // Estimated: `1489` - // Minimum execution time: 3_402_000 picoseconds. - Weight::from_parts(3_627_000, 0) - .saturating_add(Weight::from_parts(0, 1489)) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) - } -} diff --git a/polkadot/runtime/rococo/src/weights/mod.rs b/polkadot/runtime/rococo/src/weights/mod.rs index 128a3083a9c..7328dca9393 100644 --- a/polkadot/runtime/rococo/src/weights/mod.rs +++ b/polkadot/runtime/rococo/src/weights/mod.rs @@ -16,7 +16,6 @@ //! A list of the different weight modules for our runtime. pub mod frame_system; -pub mod frame_system_extensions; pub mod pallet_asset_rate; pub mod pallet_balances_balances; pub mod pallet_balances_nis_counterpart_balances; @@ -37,7 +36,6 @@ pub mod pallet_scheduler; pub mod pallet_session; pub mod pallet_sudo; pub mod pallet_timestamp; -pub mod pallet_transaction_payment; pub mod pallet_treasury; pub mod pallet_utility; pub mod pallet_vesting; diff --git a/polkadot/runtime/rococo/src/weights/pallet_asset_rate.rs b/polkadot/runtime/rococo/src/weights/pallet_asset_rate.rs index 56b1e2cbc57..da2d1958cef 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_asset_rate.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_asset_rate.rs @@ -16,28 +16,25 @@ //! Autogenerated weights for `pallet_asset_rate` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-07-03, STEPS: `50`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `cob`, CPU: `` +//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// ./target/debug/polkadot // benchmark // pallet // --chain=rococo-dev // --steps=50 -// --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares +// --repeat=2 // --pallet=pallet_asset_rate // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --heap-pages=4096 +// --output=./runtime/rococo/src/weights/ +// --header=./file_header.txt #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,39 +47,39 @@ use core::marker::PhantomData; /// Weight functions for `pallet_asset_rate`. pub struct WeightInfo(PhantomData); impl pallet_asset_rate::WeightInfo for WeightInfo { - /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1) - /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(1238), added: 3713, mode: `MaxEncodedLen`) + /// Storage: AssetRate ConversionRateToNative (r:1 w:1) + /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(1237), added: 3712, mode: MaxEncodedLen) fn create() -> Weight { // Proof Size summary in bytes: - // Measured: `142` - // Estimated: `4703` - // Minimum execution time: 10_277_000 picoseconds. - Weight::from_parts(10_487_000, 0) - .saturating_add(Weight::from_parts(0, 4703)) + // Measured: `42` + // Estimated: `4702` + // Minimum execution time: 143_000_000 picoseconds. + Weight::from_parts(155_000_000, 0) + .saturating_add(Weight::from_parts(0, 4702)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1) - /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(1238), added: 3713, mode: `MaxEncodedLen`) + /// Storage: AssetRate ConversionRateToNative (r:1 w:1) + /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(1237), added: 3712, mode: MaxEncodedLen) fn update() -> Weight { // Proof Size summary in bytes: - // Measured: `210` - // Estimated: `4703` - // Minimum execution time: 10_917_000 picoseconds. - Weight::from_parts(11_249_000, 0) - .saturating_add(Weight::from_parts(0, 4703)) + // Measured: `110` + // Estimated: `4702` + // Minimum execution time: 156_000_000 picoseconds. + Weight::from_parts(172_000_000, 0) + .saturating_add(Weight::from_parts(0, 4702)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1) - /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(1238), added: 3713, mode: `MaxEncodedLen`) + /// Storage: AssetRate ConversionRateToNative (r:1 w:1) + /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(1237), added: 3712, mode: MaxEncodedLen) fn remove() -> Weight { // Proof Size summary in bytes: - // Measured: `210` - // Estimated: `4703` - // Minimum execution time: 11_332_000 picoseconds. - Weight::from_parts(11_866_000, 0) - .saturating_add(Weight::from_parts(0, 4703)) + // Measured: `110` + // Estimated: `4702` + // Minimum execution time: 150_000_000 picoseconds. + Weight::from_parts(160_000_000, 0) + .saturating_add(Weight::from_parts(0, 4702)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/weights/pallet_balances_balances.rs b/polkadot/runtime/rococo/src/weights/pallet_balances_balances.rs index 3fa54f2c369..1b0ae1eeece 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_balances_balances.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_balances_balances.rs @@ -16,26 +16,24 @@ //! Autogenerated weights for `pallet_balances` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2024-01-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// target/production/polkadot // benchmark // pallet -// --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=pallet_balances // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_balances +// --chain=rococo-dev // --header=./polkadot/file_header.txt // --output=./polkadot/runtime/rococo/src/weights/ @@ -56,8 +54,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 45_336_000 picoseconds. - Weight::from_parts(46_189_000, 0) + // Minimum execution time: 44_127_000 picoseconds. + Weight::from_parts(45_099_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -68,8 +66,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 34_880_000 picoseconds. - Weight::from_parts(35_770_000, 0) + // Minimum execution time: 34_265_000 picoseconds. + Weight::from_parts(35_083_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -80,8 +78,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 12_904_000 picoseconds. - Weight::from_parts(13_260_000, 0) + // Minimum execution time: 12_189_000 picoseconds. + Weight::from_parts(12_655_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -92,8 +90,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 17_669_000 picoseconds. - Weight::from_parts(18_228_000, 0) + // Minimum execution time: 16_910_000 picoseconds. + Weight::from_parts(17_474_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -104,8 +102,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `6196` - // Minimum execution time: 46_492_000 picoseconds. - Weight::from_parts(47_639_000, 0) + // Minimum execution time: 45_212_000 picoseconds. + Weight::from_parts(46_320_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -116,8 +114,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 44_342_000 picoseconds. - Weight::from_parts(45_144_000, 0) + // Minimum execution time: 42_500_000 picoseconds. + Weight::from_parts(43_991_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -128,8 +126,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 15_260_000 picoseconds. - Weight::from_parts(15_775_000, 0) + // Minimum execution time: 15_197_000 picoseconds. + Weight::from_parts(15_749_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -142,11 +140,11 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0 + u * (135 ±0)` // Estimated: `990 + u * (2603 ±0)` - // Minimum execution time: 14_703_000 picoseconds. - Weight::from_parts(14_950_000, 0) + // Minimum execution time: 14_414_000 picoseconds. + Weight::from_parts(14_685_000, 0) .saturating_add(Weight::from_parts(0, 990)) - // Standard Error: 7_665 - .saturating_add(Weight::from_parts(13_335_803, 0).saturating_mul(u.into())) + // Standard Error: 7_918 + .saturating_add(Weight::from_parts(13_095_420, 0).saturating_mul(u.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into()))) .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) @@ -155,8 +153,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_506_000 picoseconds. - Weight::from_parts(5_753_000, 0) + // Minimum execution time: 5_239_000 picoseconds. + Weight::from_parts(5_617_000, 0) .saturating_add(Weight::from_parts(0, 0)) } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_balances_nis_counterpart_balances.rs b/polkadot/runtime/rococo/src/weights/pallet_balances_nis_counterpart_balances.rs index 1852ba6c2c4..6cca9b9320a 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_balances_nis_counterpart_balances.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_balances_nis_counterpart_balances.rs @@ -16,26 +16,24 @@ //! Autogenerated weights for `pallet_balances` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2024-01-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// target/production/polkadot // benchmark // pallet -// --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=pallet_balances // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_balances +// --chain=rococo-dev // --header=./polkadot/file_header.txt // --output=./polkadot/runtime/rococo/src/weights/ @@ -58,8 +56,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `6164` - // Minimum execution time: 42_443_000 picoseconds. - Weight::from_parts(43_250_000, 0) + // Minimum execution time: 41_978_000 picoseconds. + Weight::from_parts(42_989_000, 0) .saturating_add(Weight::from_parts(0, 6164)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) @@ -72,8 +70,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `6164` - // Minimum execution time: 32_417_000 picoseconds. - Weight::from_parts(33_247_000, 0) + // Minimum execution time: 32_250_000 picoseconds. + Weight::from_parts(33_074_000, 0) .saturating_add(Weight::from_parts(0, 6164)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) @@ -84,8 +82,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `3577` - // Minimum execution time: 10_091_000 picoseconds. - Weight::from_parts(10_426_000, 0) + // Minimum execution time: 9_906_000 picoseconds. + Weight::from_parts(10_397_000, 0) .saturating_add(Weight::from_parts(0, 3577)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -98,8 +96,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `277` // Estimated: `3593` - // Minimum execution time: 16_546_000 picoseconds. - Weight::from_parts(17_259_000, 0) + // Minimum execution time: 16_298_000 picoseconds. + Weight::from_parts(17_115_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -112,8 +110,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `206` // Estimated: `6196` - // Minimum execution time: 44_322_000 picoseconds. - Weight::from_parts(45_319_000, 0) + // Minimum execution time: 43_283_000 picoseconds. + Weight::from_parts(44_033_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(4)) @@ -126,8 +124,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `6164` - // Minimum execution time: 40_852_000 picoseconds. - Weight::from_parts(42_205_000, 0) + // Minimum execution time: 40_564_000 picoseconds. + Weight::from_parts(41_597_000, 0) .saturating_add(Weight::from_parts(0, 6164)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) @@ -140,8 +138,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `277` // Estimated: `3593` - // Minimum execution time: 15_050_000 picoseconds. - Weight::from_parts(15_813_000, 0) + // Minimum execution time: 15_018_000 picoseconds. + Weight::from_parts(15_532_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -156,11 +154,11 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0 + u * (256 ±0)` // Estimated: `990 + u * (2603 ±0)` - // Minimum execution time: 14_830_000 picoseconds. - Weight::from_parts(15_061_000, 0) + // Minimum execution time: 14_470_000 picoseconds. + Weight::from_parts(14_828_000, 0) .saturating_add(Weight::from_parts(0, 990)) - // Standard Error: 16_072 - .saturating_add(Weight::from_parts(14_981_430, 0).saturating_mul(u.into())) + // Standard Error: 15_515 + .saturating_add(Weight::from_parts(14_505_553, 0).saturating_mul(u.into())) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(u.into()))) .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(u.into()))) .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) @@ -169,8 +167,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_344_000 picoseconds. - Weight::from_parts(5_735_000, 0) + // Minimum execution time: 5_277_000 picoseconds. + Weight::from_parts(5_628_000, 0) .saturating_add(Weight::from_parts(0, 0)) } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_bounties.rs b/polkadot/runtime/rococo/src/weights/pallet_bounties.rs index 8f8be5f2386..38d3645316f 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_bounties.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_bounties.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_bounties` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=pallet_bounties // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,181 +47,118 @@ use core::marker::PhantomData; /// Weight functions for `pallet_bounties`. pub struct WeightInfo(PhantomData); impl pallet_bounties::WeightInfo for WeightInfo { - /// Storage: `Bounties::BountyCount` (r:1 w:1) - /// Proof: `Bounties::BountyCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) - /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`) - /// Storage: `Bounties::Bounties` (r:0 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: Bounties BountyCount (r:1 w:1) + /// Proof: Bounties BountyCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) + /// Storage: Bounties Bounties (r:0 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) /// The range of component `d` is `[0, 16384]`. fn propose_bounty(d: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `210` // Estimated: `3593` - // Minimum execution time: 21_772_000 picoseconds. - Weight::from_parts(22_861_341, 0) + // Minimum execution time: 28_907_000 picoseconds. + Weight::from_parts(31_356_074, 0) .saturating_add(Weight::from_parts(0, 3593)) - // Standard Error: 3 - .saturating_add(Weight::from_parts(721, 0).saturating_mul(d.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(606, 0).saturating_mul(d.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `Bounties::BountyApprovals` (r:1 w:1) - /// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) fn approve_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `302` - // Estimated: `3642` - // Minimum execution time: 11_218_000 picoseconds. - Weight::from_parts(11_796_000, 0) - .saturating_add(Weight::from_parts(0, 3642)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) fn propose_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `322` - // Estimated: `3642` - // Minimum execution time: 10_959_000 picoseconds. - Weight::from_parts(11_658_000, 0) - .saturating_add(Weight::from_parts(0, 3642)) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn unassign_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `498` - // Estimated: `3642` - // Minimum execution time: 37_419_000 picoseconds. - Weight::from_parts(38_362_000, 0) - .saturating_add(Weight::from_parts(0, 3642)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn accept_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `494` - // Estimated: `3642` - // Minimum execution time: 27_328_000 picoseconds. - Weight::from_parts(27_661_000, 0) - .saturating_add(Weight::from_parts(0, 3642)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) fn award_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `400` - // Estimated: `3642` - // Minimum execution time: 16_067_000 picoseconds. - Weight::from_parts(16_865_000, 0) - .saturating_add(Weight::from_parts(0, 3642)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:3 w:3) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) - /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) - /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`) fn claim_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `764` - // Estimated: `8799` - // Minimum execution time: 101_153_000 picoseconds. - Weight::from_parts(102_480_000, 0) - .saturating_add(Weight::from_parts(0, 8799)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(6)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) - /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:0) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen) fn close_bounty_proposed() -> Weight { // Proof Size summary in bytes: - // Measured: `444` + // Measured: `482` // Estimated: `3642` - // Minimum execution time: 38_838_000 picoseconds. - Weight::from_parts(39_549_000, 0) + // Minimum execution time: 46_020_000 picoseconds. + Weight::from_parts(46_711_000, 0) .saturating_add(Weight::from_parts(0, 3642)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) - /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`) fn close_bounty_active() -> Weight { // Proof Size summary in bytes: - // Measured: `680` - // Estimated: `6196` - // Minimum execution time: 68_592_000 picoseconds. - Weight::from_parts(70_727_000, 0) - .saturating_add(Weight::from_parts(0, 6196)) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(4)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) fn extend_bounty_expiry() -> Weight { // Proof Size summary in bytes: - // Measured: `358` - // Estimated: `3642` - // Minimum execution time: 11_272_000 picoseconds. - Weight::from_parts(11_592_000, 0) - .saturating_add(Weight::from_parts(0, 3642)) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: `Bounties::BountyApprovals` (r:1 w:1) - /// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) - /// Storage: `Bounties::Bounties` (r:100 w:100) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:200 w:200) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Bounties BountyApprovals (r:1 w:1) + /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) /// The range of component `b` is `[0, 100]`. - fn spend_funds(b: u32, ) -> Weight { + fn spend_funds(_b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0 + b * (297 ±0)` - // Estimated: `1887 + b * (5206 ±0)` - // Minimum execution time: 2_844_000 picoseconds. - Weight::from_parts(2_900_000, 0) + // Measured: `0` + // Estimated: `1887` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(2_405_233, 0) .saturating_add(Weight::from_parts(0, 1887)) - // Standard Error: 9_467 - .saturating_add(Weight::from_parts(32_326_595, 0).saturating_mul(b.into())) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(b.into()))) - .saturating_add(T::DbWeight::get().writes(1)) - .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(b.into()))) - .saturating_add(Weight::from_parts(0, 5206).saturating_mul(b.into())) } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_child_bounties.rs b/polkadot/runtime/rococo/src/weights/pallet_child_bounties.rs index 47ae3a5c90d..e8c798d45e7 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_child_bounties.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_child_bounties.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_child_bounties` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=pallet_child_bounties // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,153 +47,69 @@ use core::marker::PhantomData; /// Weight functions for `pallet_child_bounties`. pub struct WeightInfo(PhantomData); impl pallet_child_bounties::WeightInfo for WeightInfo { - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBountyCount` (r:1 w:1) - /// Proof: `ChildBounties::ChildBountyCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) - /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBounties` (r:0 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) /// The range of component `d` is `[0, 16384]`. - fn add_child_bounty(d: u32, ) -> Weight { + fn add_child_bounty(_d: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `540` - // Estimated: `6196` - // Minimum execution time: 57_964_000 picoseconds. - Weight::from_parts(59_559_565, 0) - .saturating_add(Weight::from_parts(0, 6196)) - // Standard Error: 11 - .saturating_add(Weight::from_parts(697, 0).saturating_mul(d.into())) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(6)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) - /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) fn propose_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `594` - // Estimated: `3642` - // Minimum execution time: 17_527_000 picoseconds. - Weight::from_parts(18_257_000, 0) - .saturating_add(Weight::from_parts(0, 3642)) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn accept_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `740` - // Estimated: `3642` - // Minimum execution time: 29_354_000 picoseconds. - Weight::from_parts(30_629_000, 0) - .saturating_add(Weight::from_parts(0, 3642)) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn unassign_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `740` - // Estimated: `3642` - // Minimum execution time: 40_643_000 picoseconds. - Weight::from_parts(42_072_000, 0) - .saturating_add(Weight::from_parts(0, 3642)) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) fn award_child_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `637` - // Estimated: `3642` - // Minimum execution time: 18_616_000 picoseconds. - Weight::from_parts(19_316_000, 0) - .saturating_add(Weight::from_parts(0, 3642)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:3 w:3) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) - /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`) fn claim_child_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `576` - // Estimated: `8799` - // Minimum execution time: 96_376_000 picoseconds. - Weight::from_parts(98_476_000, 0) - .saturating_add(Weight::from_parts(0, 8799)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(6)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) - /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) - /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`) fn close_child_bounty_added() -> Weight { // Proof Size summary in bytes: - // Measured: `840` - // Estimated: `6196` - // Minimum execution time: 64_640_000 picoseconds. - Weight::from_parts(66_174_000, 0) - .saturating_add(Weight::from_parts(0, 6196)) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(6)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:3 w:3) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) - /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) - /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`) fn close_child_bounty_active() -> Weight { // Proof Size summary in bytes: - // Measured: `1027` - // Estimated: `8799` - // Minimum execution time: 78_159_000 picoseconds. - Weight::from_parts(79_820_000, 0) - .saturating_add(Weight::from_parts(0, 8799)) - .saturating_add(T::DbWeight::get().reads(7)) - .saturating_add(T::DbWeight::get().writes(7)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) + .saturating_add(Weight::from_parts(0, 0)) } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_conviction_voting.rs b/polkadot/runtime/rococo/src/weights/pallet_conviction_voting.rs index 5d92c158df4..ba505737f1b 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_conviction_voting.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_conviction_voting.rs @@ -16,17 +16,17 @@ //! Autogenerated weights for `pallet_conviction_voting` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot // benchmark // pallet -// --chain=rococo-dev +// --chain=kusama-dev // --steps=50 // --repeat=20 // --no-storage-info @@ -36,8 +36,8 @@ // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,152 +50,144 @@ use core::marker::PhantomData; /// Weight functions for `pallet_conviction_voting`. pub struct WeightInfo(PhantomData); impl pallet_conviction_voting::WeightInfo for WeightInfo { - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) - /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) - /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(311), added: 2786, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) fn vote_new() -> Weight { // Proof Size summary in bytes: - // Measured: `13407` + // Measured: `13445` // Estimated: `42428` - // Minimum execution time: 128_378_000 picoseconds. - Weight::from_parts(131_028_000, 0) + // Minimum execution time: 151_077_000 picoseconds. + Weight::from_parts(165_283_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(5)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) - /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) - /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(311), added: 2786, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) fn vote_existing() -> Weight { // Proof Size summary in bytes: - // Measured: `14128` + // Measured: `14166` // Estimated: `83866` - // Minimum execution time: 155_379_000 picoseconds. - Weight::from_parts(161_597_000, 0) + // Minimum execution time: 232_420_000 picoseconds. + Weight::from_parts(244_439_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(7)) - .saturating_add(T::DbWeight::get().writes(7)) + .saturating_add(T::DbWeight::get().writes(6)) } - /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) fn remove_vote() -> Weight { // Proof Size summary in bytes: // Measured: `13918` // Estimated: `83866` - // Minimum execution time: 130_885_000 picoseconds. - Weight::from_parts(138_080_000, 0) + // Minimum execution time: 205_017_000 picoseconds. + Weight::from_parts(216_594_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) fn remove_other_vote() -> Weight { // Proof Size summary in bytes: - // Measured: `13005` + // Measured: `13004` // Estimated: `30706` - // Minimum execution time: 71_743_000 picoseconds. - Weight::from_parts(75_170_000, 0) + // Minimum execution time: 84_226_000 picoseconds. + Weight::from_parts(91_255_000, 0) .saturating_add(Weight::from_parts(0, 30706)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `ConvictionVoting::VotingFor` (r:2 w:2) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `Referenda::ReferendumInfoFor` (r:512 w:512) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) - /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(311), added: 2786, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:50) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: ConvictionVoting VotingFor (r:2 w:2) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:512 w:512) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) /// The range of component `r` is `[0, 512]`. fn delegate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `29602 + r * (365 ±0)` + // Measured: `29640 + r * (365 ±0)` // Estimated: `83866 + r * (3411 ±0)` - // Minimum execution time: 58_504_000 picoseconds. - Weight::from_parts(814_301_018, 0) + // Minimum execution time: 78_708_000 picoseconds. + Weight::from_parts(2_053_488_615, 0) .saturating_add(Weight::from_parts(0, 83866)) - // Standard Error: 59_961 - .saturating_add(Weight::from_parts(20_002_833, 0).saturating_mul(r.into())) + // Standard Error: 179_271 + .saturating_add(Weight::from_parts(47_806_482, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) - .saturating_add(T::DbWeight::get().writes(45)) + .saturating_add(T::DbWeight::get().writes(6)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 3411).saturating_mul(r.into())) } - /// Storage: `ConvictionVoting::VotingFor` (r:2 w:2) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `Referenda::ReferendumInfoFor` (r:512 w:512) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:50) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: ConvictionVoting VotingFor (r:2 w:2) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:512 w:512) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen) /// The range of component `r` is `[0, 512]`. fn undelegate(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `29555 + r * (365 ±0)` // Estimated: `83866 + r * (3411 ±0)` - // Minimum execution time: 34_970_000 picoseconds. - Weight::from_parts(771_155_804, 0) + // Minimum execution time: 45_232_000 picoseconds. + Weight::from_parts(2_045_021_014, 0) .saturating_add(Weight::from_parts(0, 83866)) - // Standard Error: 57_795 - .saturating_add(Weight::from_parts(19_781_645, 0).saturating_mul(r.into())) + // Standard Error: 185_130 + .saturating_add(Weight::from_parts(47_896_011, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) - .saturating_add(T::DbWeight::get().writes(43)) + .saturating_add(T::DbWeight::get().writes(4)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 3411).saturating_mul(r.into())) } - /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) - /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(311), added: 2786, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) fn unlock() -> Weight { // Proof Size summary in bytes: - // Measured: `12180` + // Measured: `12218` // Estimated: `30706` - // Minimum execution time: 89_648_000 picoseconds. - Weight::from_parts(97_144_000, 0) + // Minimum execution time: 116_446_000 picoseconds. + Weight::from_parts(124_043_000, 0) .saturating_add(Weight::from_parts(0, 30706)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) diff --git a/polkadot/runtime/rococo/src/weights/pallet_identity.rs b/polkadot/runtime/rococo/src/weights/pallet_identity.rs index 6df16351f2c..b334e21ea03 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_identity.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_identity.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_identity` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=pallet_identity // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,291 +47,290 @@ use core::marker::PhantomData; /// Weight functions for `pallet_identity`. pub struct WeightInfo(PhantomData); impl pallet_identity::WeightInfo for WeightInfo { - /// Storage: `Identity::Registrars` (r:1 w:1) - /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) /// The range of component `r` is `[1, 19]`. fn add_registrar(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `32 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 7_673_000 picoseconds. - Weight::from_parts(8_351_866, 0) + // Minimum execution time: 12_290_000 picoseconds. + Weight::from_parts(12_664_362, 0) .saturating_add(Weight::from_parts(0, 2626)) - // Standard Error: 1_302 - .saturating_add(Weight::from_parts(79_198, 0).saturating_mul(r.into())) + // Standard Error: 1_347 + .saturating_add(Weight::from_parts(88_179, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) /// The range of component `r` is `[1, 20]`. fn set_identity(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `6978 + r * (5 ±0)` - // Estimated: `11037` - // Minimum execution time: 111_646_000 picoseconds. - Weight::from_parts(113_254_991, 0) - .saturating_add(Weight::from_parts(0, 11037)) - // Standard Error: 6_611 - .saturating_add(Weight::from_parts(162_119, 0).saturating_mul(r.into())) + // Measured: `442 + r * (5 ±0)` + // Estimated: `11003` + // Minimum execution time: 31_373_000 picoseconds. + Weight::from_parts(30_435_545, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 2_307 + .saturating_add(Weight::from_parts(92_753, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Identity::IdentityOf` (r:1 w:0) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:100 w:100) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:100 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) /// The range of component `s` is `[0, 100]`. fn set_subs_new(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `101` - // Estimated: `11037 + s * (2589 ±0)` - // Minimum execution time: 8_010_000 picoseconds. - Weight::from_parts(19_868_412, 0) - .saturating_add(Weight::from_parts(0, 11037)) - // Standard Error: 5_018 - .saturating_add(Weight::from_parts(3_115_007, 0).saturating_mul(s.into())) + // Estimated: `11003 + s * (2589 ±0)` + // Minimum execution time: 9_251_000 picoseconds. + Weight::from_parts(22_039_210, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 40_779 + .saturating_add(Weight::from_parts(2_898_525, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(s.into()))) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 2589).saturating_mul(s.into())) } - /// Storage: `Identity::IdentityOf` (r:1 w:0) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:0 w:100) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) /// The range of component `p` is `[0, 100]`. fn set_subs_old(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `194 + p * (32 ±0)` - // Estimated: `11037` - // Minimum execution time: 8_111_000 picoseconds. - Weight::from_parts(19_482_392, 0) - .saturating_add(Weight::from_parts(0, 11037)) - // Standard Error: 3_156 - .saturating_add(Weight::from_parts(1_305_890, 0).saturating_mul(p.into())) + // Estimated: `11003` + // Minimum execution time: 9_329_000 picoseconds. + Weight::from_parts(24_055_061, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 3_428 + .saturating_add(Weight::from_parts(1_130_604, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) } - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:0 w:100) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) /// The range of component `r` is `[1, 20]`. /// The range of component `s` is `[0, 100]`. - fn clear_identity(r: u32, s: u32, ) -> Weight { + fn clear_identity(_r: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `7070 + r * (5 ±0) + s * (32 ±0)` - // Estimated: `11037` - // Minimum execution time: 54_107_000 picoseconds. - Weight::from_parts(56_347_715, 0) - .saturating_add(Weight::from_parts(0, 11037)) - // Standard Error: 10_944 - .saturating_add(Weight::from_parts(191_321, 0).saturating_mul(r.into())) - // Standard Error: 2_135 - .saturating_add(Weight::from_parts(1_295_872, 0).saturating_mul(s.into())) + // Measured: `469 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 53_365_000 picoseconds. + Weight::from_parts(35_391_422, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 1_353 + .saturating_add(Weight::from_parts(1_074_019, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) } - /// Storage: `Identity::Registrars` (r:1 w:0) - /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: Identity Registrars (r:1 w:0) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) /// The range of component `r` is `[1, 20]`. fn request_judgement(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `6968 + r * (57 ±0)` - // Estimated: `11037` - // Minimum execution time: 75_780_000 picoseconds. - Weight::from_parts(76_869_773, 0) - .saturating_add(Weight::from_parts(0, 11037)) - // Standard Error: 5_456 - .saturating_add(Weight::from_parts(135_316, 0).saturating_mul(r.into())) + // Measured: `367 + r * (57 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 32_509_000 picoseconds. + Weight::from_parts(31_745_585, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 2_214 + .saturating_add(Weight::from_parts(83_822, 0).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) /// The range of component `r` is `[1, 20]`. fn cancel_request(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `6999` - // Estimated: `11037` - // Minimum execution time: 75_769_000 picoseconds. - Weight::from_parts(76_805_143, 0) - .saturating_add(Weight::from_parts(0, 11037)) - // Standard Error: 3_598 - .saturating_add(Weight::from_parts(84_593, 0).saturating_mul(r.into())) + // Measured: `398 + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 29_609_000 picoseconds. + Weight::from_parts(28_572_602, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 2_528 + .saturating_add(Weight::from_parts(85_593, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Identity::Registrars` (r:1 w:1) - /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) /// The range of component `r` is `[1, 19]`. fn set_fee(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `89 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 5_357_000 picoseconds. - Weight::from_parts(5_732_132, 0) + // Minimum execution time: 7_793_000 picoseconds. + Weight::from_parts(8_173_888, 0) .saturating_add(Weight::from_parts(0, 2626)) - // Standard Error: 927 - .saturating_add(Weight::from_parts(70_832, 0).saturating_mul(r.into())) + // Standard Error: 1_569 + .saturating_add(Weight::from_parts(72_367, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Identity::Registrars` (r:1 w:1) - /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) /// The range of component `r` is `[1, 19]`. fn set_account_id(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `89 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 5_484_000 picoseconds. - Weight::from_parts(5_892_704, 0) + // Minimum execution time: 7_708_000 picoseconds. + Weight::from_parts(8_091_149, 0) .saturating_add(Weight::from_parts(0, 2626)) - // Standard Error: 947 - .saturating_add(Weight::from_parts(71_231, 0).saturating_mul(r.into())) + // Standard Error: 869 + .saturating_add(Weight::from_parts(87_993, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Identity::Registrars` (r:1 w:1) - /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) /// The range of component `r` is `[1, 19]`. fn set_fields(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `89 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 5_310_000 picoseconds. - Weight::from_parts(5_766_651, 0) + // Minimum execution time: 7_601_000 picoseconds. + Weight::from_parts(8_038_414, 0) .saturating_add(Weight::from_parts(0, 2626)) - // Standard Error: 916 - .saturating_add(Weight::from_parts(74_776, 0).saturating_mul(r.into())) + // Standard Error: 1_041 + .saturating_add(Weight::from_parts(82_588, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Identity::Registrars` (r:1 w:0) - /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: Identity Registrars (r:1 w:0) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) /// The range of component `r` is `[1, 19]`. fn provide_judgement(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `7046 + r * (57 ±0)` - // Estimated: `11037` - // Minimum execution time: 98_200_000 picoseconds. - Weight::from_parts(100_105_482, 0) - .saturating_add(Weight::from_parts(0, 11037)) - // Standard Error: 6_152 - .saturating_add(Weight::from_parts(58_906, 0).saturating_mul(r.into())) + // Measured: `445 + r * (57 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 23_114_000 picoseconds. + Weight::from_parts(22_076_548, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 2_881 + .saturating_add(Weight::from_parts(109_812, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:0 w:100) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) /// The range of component `r` is `[1, 20]`. /// The range of component `s` is `[0, 100]`. fn kill_identity(r: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `7277 + r * (5 ±0) + s * (32 ±0)` - // Estimated: `11037` - // Minimum execution time: 64_647_000 picoseconds. - Weight::from_parts(68_877_027, 0) - .saturating_add(Weight::from_parts(0, 11037)) - // Standard Error: 9_965 - .saturating_add(Weight::from_parts(135_044, 0).saturating_mul(r.into())) - // Standard Error: 1_944 - .saturating_add(Weight::from_parts(1_388_151, 0).saturating_mul(s.into())) + // Measured: `676 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 70_007_000 picoseconds. + Weight::from_parts(50_186_495, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 6_533 + .saturating_add(Weight::from_parts(15_486, 0).saturating_mul(r.into())) + // Standard Error: 1_275 + .saturating_add(Weight::from_parts(1_085_117, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) } - /// Storage: `Identity::IdentityOf` (r:1 w:0) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:1 w:1) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) /// The range of component `s` is `[0, 99]`. fn add_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `475 + s * (36 ±0)` - // Estimated: `11037` - // Minimum execution time: 23_550_000 picoseconds. - Weight::from_parts(29_439_842, 0) - .saturating_add(Weight::from_parts(0, 11037)) - // Standard Error: 1_453 - .saturating_add(Weight::from_parts(96_324, 0).saturating_mul(s.into())) + // Estimated: `11003` + // Minimum execution time: 28_453_000 picoseconds. + Weight::from_parts(33_165_934, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 1_217 + .saturating_add(Weight::from_parts(65_401, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Identity::IdentityOf` (r:1 w:0) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:1 w:1) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) /// The range of component `s` is `[1, 100]`. fn rename_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `591 + s * (3 ±0)` - // Estimated: `11037` - // Minimum execution time: 13_704_000 picoseconds. - Weight::from_parts(15_241_441, 0) - .saturating_add(Weight::from_parts(0, 11037)) - // Standard Error: 498 - .saturating_add(Weight::from_parts(40_973, 0).saturating_mul(s.into())) + // Estimated: `11003` + // Minimum execution time: 12_846_000 picoseconds. + Weight::from_parts(14_710_284, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 496 + .saturating_add(Weight::from_parts(19_539, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Identity::IdentityOf` (r:1 w:0) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:1 w:1) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) /// The range of component `s` is `[1, 100]`. fn remove_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `638 + s * (35 ±0)` - // Estimated: `11037` - // Minimum execution time: 29_310_000 picoseconds. - Weight::from_parts(31_712_666, 0) - .saturating_add(Weight::from_parts(0, 11037)) - // Standard Error: 967 - .saturating_add(Weight::from_parts(81_250, 0).saturating_mul(s.into())) + // Estimated: `11003` + // Minimum execution time: 32_183_000 picoseconds. + Weight::from_parts(35_296_731, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 854 + .saturating_add(Weight::from_parts(52_028, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Identity::SuperOf` (r:1 w:1) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:0) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `s` is `[0, 99]`. fn quit_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `704 + s * (37 ±0)` // Estimated: `6723` - // Minimum execution time: 22_906_000 picoseconds. - Weight::from_parts(24_638_729, 0) + // Minimum execution time: 24_941_000 picoseconds. + Weight::from_parts(27_433_059, 0) .saturating_add(Weight::from_parts(0, 6723)) - // Standard Error: 645 - .saturating_add(Weight::from_parts(75_121, 0).saturating_mul(s.into())) + // Standard Error: 856 + .saturating_add(Weight::from_parts(57_463, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -344,93 +340,90 @@ impl pallet_identity::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_056_000 picoseconds. - Weight::from_parts(6_349_000, 0) + // Minimum execution time: 13_873_000 picoseconds. + Weight::from_parts(13_873_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Identity::UsernameAuthorities` (r:1 w:1) + /// Storage: `Identity::UsernameAuthorities` (r:0 w:1) /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn remove_username_authority() -> Weight { // Proof Size summary in bytes: - // Measured: `80` - // Estimated: `3517` - // Minimum execution time: 9_003_000 picoseconds. - Weight::from_parts(9_276_000, 0) - .saturating_add(Weight::from_parts(0, 3517)) - .saturating_add(T::DbWeight::get().reads(1)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 10_653_000 picoseconds. + Weight::from_parts(10_653_000, 0) + .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Identity::UsernameAuthorities` (r:1 w:1) /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) /// Storage: `Identity::AccountOfUsername` (r:1 w:1) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) - /// Storage: `Identity::PendingUsernames` (r:1 w:0) - /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) fn set_username_for() -> Weight { // Proof Size summary in bytes: // Measured: `80` // Estimated: `11037` - // Minimum execution time: 64_724_000 picoseconds. - Weight::from_parts(66_597_000, 0) + // Minimum execution time: 75_928_000 picoseconds. + Weight::from_parts(75_928_000, 0) .saturating_add(Weight::from_parts(0, 11037)) - .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Identity::PendingUsernames` (r:1 w:1) - /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// Storage: `Identity::AccountOfUsername` (r:0 w:1) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn accept_username() -> Weight { // Proof Size summary in bytes: - // Measured: `115` + // Measured: `106` // Estimated: `11037` - // Minimum execution time: 19_538_000 picoseconds. - Weight::from_parts(20_204_000, 0) + // Minimum execution time: 38_157_000 picoseconds. + Weight::from_parts(38_157_000, 0) .saturating_add(Weight::from_parts(0, 11037)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Identity::PendingUsernames` (r:1 w:1) - /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) fn remove_expired_approval() -> Weight { // Proof Size summary in bytes: - // Measured: `115` - // Estimated: `3550` - // Minimum execution time: 16_000_000 picoseconds. - Weight::from_parts(19_354_000, 0) - .saturating_add(Weight::from_parts(0, 3550)) + // Measured: `106` + // Estimated: `3542` + // Minimum execution time: 46_821_000 picoseconds. + Weight::from_parts(46_821_000, 0) + .saturating_add(Weight::from_parts(0, 3542)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Identity::AccountOfUsername` (r:1 w:0) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) fn set_primary_username() -> Weight { // Proof Size summary in bytes: - // Measured: `257` + // Measured: `247` // Estimated: `11037` - // Minimum execution time: 15_298_000 picoseconds. - Weight::from_parts(15_760_000, 0) + // Minimum execution time: 22_515_000 picoseconds. + Weight::from_parts(22_515_000, 0) .saturating_add(Weight::from_parts(0, 11037)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Identity::AccountOfUsername` (r:1 w:1) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:0) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) fn remove_dangling_username() -> Weight { // Proof Size summary in bytes: - // Measured: `98` + // Measured: `126` // Estimated: `11037` - // Minimum execution time: 10_829_000 picoseconds. - Weight::from_parts(11_113_000, 0) + // Minimum execution time: 15_997_000 picoseconds. + Weight::from_parts(15_997_000, 0) .saturating_add(Weight::from_parts(0, 11037)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/polkadot/runtime/rococo/src/weights/pallet_indices.rs b/polkadot/runtime/rococo/src/weights/pallet_indices.rs index 434db97d4a7..99ffd3210ed 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_indices.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_indices.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_indices` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=pallet_indices // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,66 +47,66 @@ use core::marker::PhantomData; /// Weight functions for `pallet_indices`. pub struct WeightInfo(PhantomData); impl pallet_indices::WeightInfo for WeightInfo { - /// Storage: `Indices::Accounts` (r:1 w:1) - /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) fn claim() -> Weight { // Proof Size summary in bytes: - // Measured: `4` + // Measured: `142` // Estimated: `3534` - // Minimum execution time: 18_092_000 picoseconds. - Weight::from_parts(18_533_000, 0) + // Minimum execution time: 25_107_000 picoseconds. + Weight::from_parts(25_655_000, 0) .saturating_add(Weight::from_parts(0, 3534)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Indices::Accounts` (r:1 w:1) - /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn transfer() -> Weight { // Proof Size summary in bytes: - // Measured: `203` + // Measured: `341` // Estimated: `3593` - // Minimum execution time: 31_616_000 picoseconds. - Weight::from_parts(32_556_000, 0) + // Minimum execution time: 36_208_000 picoseconds. + Weight::from_parts(36_521_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Indices::Accounts` (r:1 w:1) - /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) fn free() -> Weight { // Proof Size summary in bytes: - // Measured: `100` + // Measured: `238` // Estimated: `3534` - // Minimum execution time: 19_593_000 picoseconds. - Weight::from_parts(20_100_000, 0) + // Minimum execution time: 25_915_000 picoseconds. + Weight::from_parts(26_220_000, 0) .saturating_add(Weight::from_parts(0, 3534)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Indices::Accounts` (r:1 w:1) - /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn force_transfer() -> Weight { // Proof Size summary in bytes: - // Measured: `203` + // Measured: `341` // Estimated: `3593` - // Minimum execution time: 21_429_000 picoseconds. - Weight::from_parts(22_146_000, 0) + // Minimum execution time: 28_232_000 picoseconds. + Weight::from_parts(28_845_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Indices::Accounts` (r:1 w:1) - /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) fn freeze() -> Weight { // Proof Size summary in bytes: - // Measured: `100` + // Measured: `238` // Estimated: `3534` - // Minimum execution time: 20_425_000 picoseconds. - Weight::from_parts(21_023_000, 0) + // Minimum execution time: 27_282_000 picoseconds. + Weight::from_parts(27_754_000, 0) .saturating_add(Weight::from_parts(0, 3534)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/polkadot/runtime/rococo/src/weights/pallet_message_queue.rs b/polkadot/runtime/rococo/src/weights/pallet_message_queue.rs index 6ebfcd060b6..e1e360d374a 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_message_queue.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_message_queue.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_message_queue` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=pallet_message_queue // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,149 +47,150 @@ use core::marker::PhantomData; /// Weight functions for `pallet_message_queue`. pub struct WeightInfo(PhantomData); impl pallet_message_queue::WeightInfo for WeightInfo { - /// Storage: `MessageQueue::ServiceHead` (r:1 w:0) - /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(6), added: 501, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::BookStateFor` (r:2 w:2) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) + /// Storage: MessageQueue ServiceHead (r:1 w:0) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:2 w:2) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) fn ready_ring_knit() -> Weight { // Proof Size summary in bytes: - // Measured: `281` + // Measured: `248` // Estimated: `6050` - // Minimum execution time: 12_830_000 picoseconds. - Weight::from_parts(13_476_000, 0) + // Minimum execution time: 12_106_000 picoseconds. + Weight::from_parts(12_387_000, 0) .saturating_add(Weight::from_parts(0, 6050)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `MessageQueue::BookStateFor` (r:2 w:2) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::ServiceHead` (r:1 w:1) - /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(6), added: 501, mode: `MaxEncodedLen`) + /// Storage: MessageQueue BookStateFor (r:2 w:2) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen) fn ready_ring_unknit() -> Weight { // Proof Size summary in bytes: - // Measured: `281` + // Measured: `248` // Estimated: `6050` - // Minimum execution time: 11_583_000 picoseconds. - Weight::from_parts(11_902_000, 0) + // Minimum execution time: 11_227_000 picoseconds. + Weight::from_parts(11_616_000, 0) .saturating_add(Weight::from_parts(0, 6050)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) fn service_queue_base() -> Weight { // Proof Size summary in bytes: // Measured: `42` // Estimated: `3520` - // Minimum execution time: 3_801_000 picoseconds. - Weight::from_parts(3_943_000, 0) + // Minimum execution time: 5_052_000 picoseconds. + Weight::from_parts(5_216_000, 0) .saturating_add(Weight::from_parts(0, 3520)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `MessageQueue::Pages` (r:1 w:1) - /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen) fn service_page_base_completion() -> Weight { // Proof Size summary in bytes: // Measured: `115` // Estimated: `36283` - // Minimum execution time: 5_517_000 picoseconds. - Weight::from_parts(5_861_000, 0) + // Minimum execution time: 6_522_000 picoseconds. + Weight::from_parts(6_794_000, 0) .saturating_add(Weight::from_parts(0, 36283)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `MessageQueue::Pages` (r:1 w:1) - /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen) fn service_page_base_no_completion() -> Weight { // Proof Size summary in bytes: // Measured: `115` // Estimated: `36283` - // Minimum execution time: 5_870_000 picoseconds. - Weight::from_parts(6_028_000, 0) + // Minimum execution time: 6_918_000 picoseconds. + Weight::from_parts(7_083_000, 0) .saturating_add(Weight::from_parts(0, 36283)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `MessageQueue::BookStateFor` (r:0 w:1) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::Pages` (r:0 w:1) - /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`) fn service_page_item() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 80_681_000 picoseconds. - Weight::from_parts(81_818_000, 0) + // Minimum execution time: 28_445_000 picoseconds. + Weight::from_parts(28_659_000, 0) .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `MessageQueue::ServiceHead` (r:1 w:1) - /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(6), added: 501, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::BookStateFor` (r:1 w:0) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:1 w:0) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) fn bump_service_head() -> Weight { // Proof Size summary in bytes: - // Measured: `220` + // Measured: `149` // Estimated: `3520` - // Minimum execution time: 8_641_000 picoseconds. - Weight::from_parts(8_995_000, 0) + // Minimum execution time: 7_224_000 picoseconds. + Weight::from_parts(7_441_000, 0) .saturating_add(Weight::from_parts(0, 3520)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::Pages` (r:1 w:1) - /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`) - /// Storage: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Proof: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Storage: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) - /// Proof: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) fn reap_page() -> Weight { // Proof Size summary in bytes: - // Measured: `32945` + // Measured: `33232` // Estimated: `36283` - // Minimum execution time: 38_473_000 picoseconds. - Weight::from_parts(39_831_000, 0) + // Minimum execution time: 45_211_000 picoseconds. + Weight::from_parts(45_505_000, 0) .saturating_add(Weight::from_parts(0, 36283)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::Pages` (r:1 w:1) - /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`) - /// Storage: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Proof: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Storage: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) - /// Proof: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) fn execute_overweight_page_removed() -> Weight { // Proof Size summary in bytes: - // Measured: `32945` + // Measured: `33232` // Estimated: `36283` - // Minimum execution time: 48_717_000 picoseconds. - Weight::from_parts(49_724_000, 0) + // Minimum execution time: 52_346_000 picoseconds. + Weight::from_parts(52_745_000, 0) .saturating_add(Weight::from_parts(0, 36283)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::Pages` (r:1 w:1) - /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`) - /// Storage: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Proof: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Storage: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) - /// Proof: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) fn execute_overweight_page_updated() -> Weight { // Proof Size summary in bytes: - // Measured: `32945` + // Measured: `33232` // Estimated: `36283` - // Minimum execution time: 72_718_000 picoseconds. - Weight::from_parts(74_081_000, 0) + // Minimum execution time: 72_567_000 picoseconds. + Weight::from_parts(73_300_000, 0) .saturating_add(Weight::from_parts(0, 36283)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(4)) } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_multisig.rs b/polkadot/runtime/rococo/src/weights/pallet_multisig.rs index f1b81759ece..a4f33fe198c 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_multisig.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_multisig.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_multisig` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=pallet_multisig // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -55,110 +52,110 @@ impl pallet_multisig::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 12_023_000 picoseconds. - Weight::from_parts(12_643_116, 0) + // Minimum execution time: 11_475_000 picoseconds. + Weight::from_parts(11_904_745, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 3 - .saturating_add(Weight::from_parts(582, 0).saturating_mul(z.into())) + // Standard Error: 1 + .saturating_add(Weight::from_parts(492, 0).saturating_mul(z.into())) } - /// Storage: `Multisig::Multisigs` (r:1 w:1) - /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_create(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `229 + s * (2 ±0)` + // Measured: `193 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 39_339_000 picoseconds. - Weight::from_parts(27_243_033, 0) + // Minimum execution time: 38_857_000 picoseconds. + Weight::from_parts(33_611_791, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 1_319 - .saturating_add(Weight::from_parts(142_212, 0).saturating_mul(s.into())) - // Standard Error: 12 - .saturating_add(Weight::from_parts(1_592, 0).saturating_mul(z.into())) + // Standard Error: 400 + .saturating_add(Weight::from_parts(59_263, 0).saturating_mul(s.into())) + // Standard Error: 3 + .saturating_add(Weight::from_parts(1_211, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Multisig::Multisigs` (r:1 w:1) - /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) /// The range of component `s` is `[3, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_approve(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `248` + // Measured: `211` // Estimated: `6811` - // Minimum execution time: 27_647_000 picoseconds. - Weight::from_parts(15_828_725, 0) + // Minimum execution time: 25_715_000 picoseconds. + Weight::from_parts(20_607_294, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 908 - .saturating_add(Weight::from_parts(130_880, 0).saturating_mul(s.into())) - // Standard Error: 8 - .saturating_add(Weight::from_parts(1_532, 0).saturating_mul(z.into())) + // Standard Error: 285 + .saturating_add(Weight::from_parts(58_225, 0).saturating_mul(s.into())) + // Standard Error: 2 + .saturating_add(Weight::from_parts(1_160, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Multisig::Multisigs` (r:1 w:1) - /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_complete(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `354 + s * (33 ±0)` + // Measured: `317 + s * (33 ±0)` // Estimated: `6811` - // Minimum execution time: 46_971_000 picoseconds. - Weight::from_parts(32_150_393, 0) + // Minimum execution time: 43_751_000 picoseconds. + Weight::from_parts(37_398_513, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 1_129 - .saturating_add(Weight::from_parts(154_796, 0).saturating_mul(s.into())) - // Standard Error: 11 - .saturating_add(Weight::from_parts(1_603, 0).saturating_mul(z.into())) + // Standard Error: 426 + .saturating_add(Weight::from_parts(70_904, 0).saturating_mul(s.into())) + // Standard Error: 4 + .saturating_add(Weight::from_parts(1_235, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Multisig::Multisigs` (r:1 w:1) - /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) /// The range of component `s` is `[2, 100]`. fn approve_as_multi_create(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `229 + s * (2 ±0)` + // Measured: `193 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 24_947_000 picoseconds. - Weight::from_parts(26_497_183, 0) + // Minimum execution time: 31_278_000 picoseconds. + Weight::from_parts(32_075_573, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 1_615 - .saturating_add(Weight::from_parts(147_071, 0).saturating_mul(s.into())) + // Standard Error: 452 + .saturating_add(Weight::from_parts(62_018, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Multisig::Multisigs` (r:1 w:1) - /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) /// The range of component `s` is `[2, 100]`. fn approve_as_multi_approve(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `248` + // Measured: `211` // Estimated: `6811` - // Minimum execution time: 13_897_000 picoseconds. - Weight::from_parts(14_828_339, 0) + // Minimum execution time: 18_178_000 picoseconds. + Weight::from_parts(18_649_867, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 1_136 - .saturating_add(Weight::from_parts(133_925, 0).saturating_mul(s.into())) + // Standard Error: 293 + .saturating_add(Weight::from_parts(56_475, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Multisig::Multisigs` (r:1 w:1) - /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) /// The range of component `s` is `[2, 100]`. fn cancel_as_multi(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `420 + s * (1 ±0)` + // Measured: `383 + s * (1 ±0)` // Estimated: `6811` - // Minimum execution time: 28_984_000 picoseconds. - Weight::from_parts(29_853_232, 0) + // Minimum execution time: 32_265_000 picoseconds. + Weight::from_parts(32_984_014, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 650 - .saturating_add(Weight::from_parts(113_440, 0).saturating_mul(s.into())) + // Standard Error: 452 + .saturating_add(Weight::from_parts(59_934, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/weights/pallet_nis.rs b/polkadot/runtime/rococo/src/weights/pallet_nis.rs index 38b41f3a8e2..35dad482129 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_nis.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_nis.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_nis` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=pallet_nis // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,186 +47,202 @@ use core::marker::PhantomData; /// Weight functions for `pallet_nis`. pub struct WeightInfo(PhantomData); impl pallet_nis::WeightInfo for WeightInfo { - /// Storage: `Nis::Queues` (r:1 w:1) - /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) - /// Storage: `Nis::QueueTotals` (r:1 w:1) - /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) /// The range of component `l` is `[0, 999]`. fn place_bid(l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `6209 + l * (48 ±0)` // Estimated: `51487` - // Minimum execution time: 39_592_000 picoseconds. - Weight::from_parts(38_234_037, 0) + // Minimum execution time: 44_704_000 picoseconds. + Weight::from_parts(44_933_886, 0) .saturating_add(Weight::from_parts(0, 51487)) - // Standard Error: 1_237 - .saturating_add(Weight::from_parts(88_816, 0).saturating_mul(l.into())) + // Standard Error: 712 + .saturating_add(Weight::from_parts(71_570, 0).saturating_mul(l.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `Nis::Queues` (r:1 w:1) - /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) - /// Storage: `Nis::QueueTotals` (r:1 w:1) - /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) fn place_bid_max() -> Weight { // Proof Size summary in bytes: // Measured: `54211` // Estimated: `51487` - // Minimum execution time: 134_847_000 picoseconds. - Weight::from_parts(139_510_000, 0) + // Minimum execution time: 126_544_000 picoseconds. + Weight::from_parts(128_271_000, 0) .saturating_add(Weight::from_parts(0, 51487)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `Nis::Queues` (r:1 w:1) - /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) - /// Storage: `Nis::QueueTotals` (r:1 w:1) - /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) /// The range of component `l` is `[1, 1000]`. fn retract_bid(l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `6209 + l * (48 ±0)` // Estimated: `51487` - // Minimum execution time: 43_330_000 picoseconds. - Weight::from_parts(35_097_881, 0) + // Minimum execution time: 47_640_000 picoseconds. + Weight::from_parts(42_214_261, 0) .saturating_add(Weight::from_parts(0, 51487)) - // Standard Error: 1_119 - .saturating_add(Weight::from_parts(73_640, 0).saturating_mul(l.into())) + // Standard Error: 732 + .saturating_add(Weight::from_parts(87_277, 0).saturating_mul(l.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `Nis::Summary` (r:1 w:0) - /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Nis Summary (r:1 w:0) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn fund_deficit() -> Weight { // Proof Size summary in bytes: // Measured: `225` // Estimated: `3593` - // Minimum execution time: 29_989_000 picoseconds. - Weight::from_parts(30_865_000, 0) + // Minimum execution time: 38_031_000 picoseconds. + Weight::from_parts(38_441_000, 0) .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Nis::Receipts` (r:1 w:1) - /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Nis::Summary` (r:1 w:1) - /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) - /// Storage: `NisCounterpartBalances::Account` (r:1 w:1) - /// Proof: `NisCounterpartBalances::Account` (`max_values`: None, `max_size`: Some(112), added: 2587, mode: `MaxEncodedLen`) + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1) + /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances Account (r:1 w:1) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) fn communify() -> Weight { // Proof Size summary in bytes: - // Measured: `387` + // Measured: `469` // Estimated: `3593` - // Minimum execution time: 58_114_000 picoseconds. - Weight::from_parts(59_540_000, 0) + // Minimum execution time: 69_269_000 picoseconds. + Weight::from_parts(70_000_000, 0) .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(6)) } - /// Storage: `Nis::Receipts` (r:1 w:1) - /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) - /// Storage: `Nis::Summary` (r:1 w:1) - /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `NisCounterpartBalances::Account` (r:1 w:1) - /// Proof: `NisCounterpartBalances::Account` (`max_values`: None, `max_size`: Some(112), added: 2587, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances Account (r:1 w:1) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1) + /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) fn privatize() -> Weight { // Proof Size summary in bytes: - // Measured: `543` + // Measured: `659` // Estimated: `3593` - // Minimum execution time: 75_780_000 picoseconds. - Weight::from_parts(77_097_000, 0) + // Minimum execution time: 85_763_000 picoseconds. + Weight::from_parts(86_707_000, 0) .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(6)) } - /// Storage: `Nis::Receipts` (r:1 w:1) - /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) - /// Storage: `Nis::Summary` (r:1 w:1) - /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:0) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen) fn thaw_private() -> Weight { // Proof Size summary in bytes: // Measured: `387` // Estimated: `3593` - // Minimum execution time: 46_133_000 picoseconds. - Weight::from_parts(47_250_000, 0) + // Minimum execution time: 47_336_000 picoseconds. + Weight::from_parts(47_623_000, 0) .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `Nis::Receipts` (r:1 w:1) - /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) - /// Storage: `Nis::Summary` (r:1 w:1) - /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) - /// Storage: `NisCounterpartBalances::Account` (r:1 w:1) - /// Proof: `NisCounterpartBalances::Account` (`max_values`: None, `max_size`: Some(112), added: 2587, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances Account (r:1 w:1) + /// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen) + /// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1) + /// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn thaw_communal() -> Weight { // Proof Size summary in bytes: - // Measured: `488` + // Measured: `604` // Estimated: `3593` - // Minimum execution time: 77_916_000 picoseconds. - Weight::from_parts(79_427_000, 0) + // Minimum execution time: 90_972_000 picoseconds. + Weight::from_parts(92_074_000, 0) .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(5)) } - /// Storage: `Nis::Summary` (r:1 w:1) - /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:0) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Nis::QueueTotals` (r:1 w:1) - /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:0) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) fn process_queues() -> Weight { // Proof Size summary in bytes: // Measured: `6658` // Estimated: `7487` - // Minimum execution time: 22_992_000 picoseconds. - Weight::from_parts(24_112_000, 0) + // Minimum execution time: 21_469_000 picoseconds. + Weight::from_parts(21_983_000, 0) .saturating_add(Weight::from_parts(0, 7487)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Nis::Queues` (r:1 w:1) - /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) fn process_queue() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `51487` - // Minimum execution time: 3_856_000 picoseconds. - Weight::from_parts(4_125_000, 0) + // Minimum execution time: 4_912_000 picoseconds. + Weight::from_parts(5_013_000, 0) .saturating_add(Weight::from_parts(0, 51487)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Nis::Receipts` (r:0 w:1) - /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Storage: Nis Receipts (r:0 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) fn process_bid() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_344_000 picoseconds. - Weight::from_parts(4_545_000, 0) + // Minimum execution time: 7_048_000 picoseconds. + Weight::from_parts(7_278_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/weights/pallet_preimage.rs b/polkadot/runtime/rococo/src/weights/pallet_preimage.rs index 7a2b77b84d8..e051ebd5bba 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_preimage.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_preimage.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_preimage` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=pallet_preimage // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,219 +47,184 @@ use core::marker::PhantomData; /// Weight functions for `pallet_preimage`. pub struct WeightInfo(PhantomData); impl pallet_preimage::WeightInfo for WeightInfo { - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) - /// Storage: `Preimage::PreimageFor` (r:0 w:1) - /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) + fn ensure_updated(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `193 + n * (91 ±0)` + // Estimated: `3593 + n * (2566 ±0)` + // Minimum execution time: 2_000_000 picoseconds. + Weight::from_parts(2_000_000, 3593) + // Standard Error: 13_720 + .saturating_add(Weight::from_parts(17_309_199, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(1_u64)) + .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2566).saturating_mul(n.into())) + } + + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) /// The range of component `s` is `[0, 4194304]`. fn note_preimage(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `114` - // Estimated: `3568` - // Minimum execution time: 40_363_000 picoseconds. - Weight::from_parts(41_052_000, 0) - .saturating_add(Weight::from_parts(0, 3568)) - // Standard Error: 6 - .saturating_add(Weight::from_parts(2_298, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(3)) + // Measured: `215` + // Estimated: `3556` + // Minimum execution time: 31_040_000 picoseconds. + Weight::from_parts(31_236_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_974, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::PreimageFor` (r:0 w:1) - /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) /// The range of component `s` is `[0, 4194304]`. fn note_requested_preimage(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `178` // Estimated: `3556` - // Minimum execution time: 14_570_000 picoseconds. - Weight::from_parts(14_890_000, 0) + // Minimum execution time: 18_025_000 picoseconds. + Weight::from_parts(18_264_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - // Standard Error: 2 - .saturating_add(Weight::from_parts(2_364, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(2)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_974, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::PreimageFor` (r:0 w:1) - /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) /// The range of component `s` is `[0, 4194304]`. fn note_no_deposit_preimage(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `178` // Estimated: `3556` - // Minimum execution time: 13_933_000 picoseconds. - Weight::from_parts(14_290_000, 0) + // Minimum execution time: 17_122_000 picoseconds. + Weight::from_parts(17_332_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - // Standard Error: 2 - .saturating_add(Weight::from_parts(2_349, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(2)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_968, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) - /// Storage: `Preimage::PreimageFor` (r:0 w:1) - /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) fn unnote_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `315` - // Estimated: `3568` - // Minimum execution time: 54_373_000 picoseconds. - Weight::from_parts(58_205_000, 0) - .saturating_add(Weight::from_parts(0, 3568)) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(3)) + // Measured: `361` + // Estimated: `3556` + // Minimum execution time: 38_218_000 picoseconds. + Weight::from_parts(39_841_000, 0) + .saturating_add(Weight::from_parts(0, 3556)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::PreimageFor` (r:0 w:1) - /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) fn unnote_no_deposit_preimage() -> Weight { // Proof Size summary in bytes: // Measured: `216` // Estimated: `3556` - // Minimum execution time: 24_267_000 picoseconds. - Weight::from_parts(27_063_000, 0) + // Minimum execution time: 23_217_000 picoseconds. + Weight::from_parts(24_246_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) fn request_preimage() -> Weight { // Proof Size summary in bytes: // Measured: `260` // Estimated: `3556` - // Minimum execution time: 25_569_000 picoseconds. - Weight::from_parts(27_895_000, 0) + // Minimum execution time: 21_032_000 picoseconds. + Weight::from_parts(21_844_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) fn request_no_deposit_preimage() -> Weight { // Proof Size summary in bytes: // Measured: `216` // Estimated: `3556` - // Minimum execution time: 14_182_000 picoseconds. - Weight::from_parts(16_098_000, 0) + // Minimum execution time: 13_954_000 picoseconds. + Weight::from_parts(14_501_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) fn request_unnoted_preimage() -> Weight { // Proof Size summary in bytes: // Measured: `114` // Estimated: `3556` - // Minimum execution time: 14_681_000 picoseconds. - Weight::from_parts(15_549_000, 0) + // Minimum execution time: 14_874_000 picoseconds. + Weight::from_parts(15_380_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) fn request_requested_preimage() -> Weight { // Proof Size summary in bytes: // Measured: `178` // Estimated: `3556` - // Minimum execution time: 9_577_000 picoseconds. - Weight::from_parts(10_146_000, 0) + // Minimum execution time: 10_199_000 picoseconds. + Weight::from_parts(10_493_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::PreimageFor` (r:0 w:1) - /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:0 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen) fn unrequest_preimage() -> Weight { // Proof Size summary in bytes: // Measured: `216` // Estimated: `3556` - // Minimum execution time: 21_003_000 picoseconds. - Weight::from_parts(23_549_000, 0) + // Minimum execution time: 21_772_000 picoseconds. + Weight::from_parts(22_554_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) fn unrequest_unnoted_preimage() -> Weight { // Proof Size summary in bytes: // Measured: `178` // Estimated: `3556` - // Minimum execution time: 9_507_000 picoseconds. - Weight::from_parts(10_013_000, 0) + // Minimum execution time: 10_115_000 picoseconds. + Weight::from_parts(10_452_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) fn unrequest_multi_referenced_preimage() -> Weight { // Proof Size summary in bytes: // Measured: `178` // Estimated: `3556` - // Minimum execution time: 9_293_000 picoseconds. - Weight::from_parts(10_055_000, 0) + // Minimum execution time: 10_031_000 picoseconds. + Weight::from_parts(10_310_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Preimage::StatusFor` (r:1023 w:1023) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1023 w:1023) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1023 w:1023) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:0 w:1023) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// The range of component `n` is `[1, 1024]`. - fn ensure_updated(n: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `0 + n * (227 ±0)` - // Estimated: `990 + n * (2603 ±0)` - // Minimum execution time: 48_846_000 picoseconds. - Weight::from_parts(49_378_000, 0) - .saturating_add(Weight::from_parts(0, 990)) - // Standard Error: 38_493 - .saturating_add(Weight::from_parts(47_418_285, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into()))) - .saturating_add(T::DbWeight::get().writes((4_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 2603).saturating_mul(n.into())) - } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_proxy.rs b/polkadot/runtime/rococo/src/weights/pallet_proxy.rs index c9202593095..d9737a85c05 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_proxy.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_proxy.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_proxy` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=pallet_proxy // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,176 +47,172 @@ use core::marker::PhantomData; /// Weight functions for `pallet_proxy`. pub struct WeightInfo(PhantomData); impl pallet_proxy::WeightInfo for WeightInfo { - /// Storage: `Proxy::Proxies` (r:1 w:0) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) /// The range of component `p` is `[1, 31]`. fn proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `89 + p * (37 ±0)` + // Measured: `227 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 11_267_000 picoseconds. - Weight::from_parts(11_798_007, 0) + // Minimum execution time: 15_956_000 picoseconds. + Weight::from_parts(16_300_358, 0) .saturating_add(Weight::from_parts(0, 4706)) - // Standard Error: 858 - .saturating_add(Weight::from_parts(43_735, 0).saturating_mul(p.into())) + // Standard Error: 652 + .saturating_add(Weight::from_parts(30_807, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1)) } - /// Storage: `Proxy::Proxies` (r:1 w:0) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) - /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn proxy_announced(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `416 + a * (68 ±0) + p * (37 ±0)` + // Measured: `554 + a * (68 ±0) + p * (37 ±0)` // Estimated: `5698` - // Minimum execution time: 32_791_000 picoseconds. - Weight::from_parts(32_776_904, 0) + // Minimum execution time: 37_584_000 picoseconds. + Weight::from_parts(37_858_207, 0) .saturating_add(Weight::from_parts(0, 5698)) - // Standard Error: 2_382 - .saturating_add(Weight::from_parts(143_857, 0).saturating_mul(a.into())) - // Standard Error: 2_461 - .saturating_add(Weight::from_parts(40_024, 0).saturating_mul(p.into())) + // Standard Error: 1_868 + .saturating_add(Weight::from_parts(148_967, 0).saturating_mul(a.into())) + // Standard Error: 1_930 + .saturating_add(Weight::from_parts(13_017, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. - fn remove_announcement(a: u32, p: u32, ) -> Weight { + fn remove_announcement(a: u32, _p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `331 + a * (68 ±0)` + // Measured: `469 + a * (68 ±0)` // Estimated: `5698` - // Minimum execution time: 21_831_000 picoseconds. - Weight::from_parts(22_479_938, 0) + // Minimum execution time: 24_642_000 picoseconds. + Weight::from_parts(25_526_588, 0) .saturating_add(Weight::from_parts(0, 5698)) - // Standard Error: 1_738 - .saturating_add(Weight::from_parts(146_532, 0).saturating_mul(a.into())) - // Standard Error: 1_796 - .saturating_add(Weight::from_parts(7_499, 0).saturating_mul(p.into())) + // Standard Error: 1_138 + .saturating_add(Weight::from_parts(131_157, 0).saturating_mul(a.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. - fn reject_announcement(a: u32, p: u32, ) -> Weight { + fn reject_announcement(a: u32, _p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `331 + a * (68 ±0)` + // Measured: `469 + a * (68 ±0)` // Estimated: `5698` - // Minimum execution time: 21_776_000 picoseconds. - Weight::from_parts(22_762_843, 0) + // Minimum execution time: 24_377_000 picoseconds. + Weight::from_parts(25_464_033, 0) .saturating_add(Weight::from_parts(0, 5698)) - // Standard Error: 1_402 - .saturating_add(Weight::from_parts(137_512, 0).saturating_mul(a.into())) - // Standard Error: 1_449 - .saturating_add(Weight::from_parts(3_645, 0).saturating_mul(p.into())) + // Standard Error: 1_116 + .saturating_add(Weight::from_parts(130_722, 0).saturating_mul(a.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Proxy::Proxies` (r:1 w:0) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) - /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn announce(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `348 + a * (68 ±0) + p * (37 ±0)` + // Measured: `486 + a * (68 ±0) + p * (37 ±0)` // Estimated: `5698` - // Minimum execution time: 29_108_000 picoseconds. - Weight::from_parts(29_508_910, 0) + // Minimum execution time: 34_202_000 picoseconds. + Weight::from_parts(34_610_079, 0) .saturating_add(Weight::from_parts(0, 5698)) - // Standard Error: 2_268 - .saturating_add(Weight::from_parts(144_770, 0).saturating_mul(a.into())) - // Standard Error: 2_343 - .saturating_add(Weight::from_parts(25_851, 0).saturating_mul(p.into())) + // Standard Error: 1_234 + .saturating_add(Weight::from_parts(134_197, 0).saturating_mul(a.into())) + // Standard Error: 1_275 + .saturating_add(Weight::from_parts(15_970, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) /// The range of component `p` is `[1, 31]`. fn add_proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `89 + p * (37 ±0)` + // Measured: `227 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 18_942_000 picoseconds. - Weight::from_parts(19_518_812, 0) + // Minimum execution time: 25_492_000 picoseconds. + Weight::from_parts(25_984_867, 0) .saturating_add(Weight::from_parts(0, 4706)) - // Standard Error: 1_078 - .saturating_add(Weight::from_parts(46_147, 0).saturating_mul(p.into())) + // Standard Error: 893 + .saturating_add(Weight::from_parts(51_868, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) /// The range of component `p` is `[1, 31]`. fn remove_proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `89 + p * (37 ±0)` + // Measured: `227 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 18_993_000 picoseconds. - Weight::from_parts(19_871_741, 0) + // Minimum execution time: 25_492_000 picoseconds. + Weight::from_parts(26_283_445, 0) .saturating_add(Weight::from_parts(0, 4706)) - // Standard Error: 1_883 - .saturating_add(Weight::from_parts(46_033, 0).saturating_mul(p.into())) + // Standard Error: 1_442 + .saturating_add(Weight::from_parts(53_504, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) /// The range of component `p` is `[1, 31]`. fn remove_proxies(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `89 + p * (37 ±0)` + // Measured: `227 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 17_849_000 picoseconds. - Weight::from_parts(18_776_170, 0) + // Minimum execution time: 22_083_000 picoseconds. + Weight::from_parts(22_688_835, 0) .saturating_add(Weight::from_parts(0, 4706)) - // Standard Error: 1_239 - .saturating_add(Weight::from_parts(27_960, 0).saturating_mul(p.into())) + // Standard Error: 994 + .saturating_add(Weight::from_parts(32_994, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) /// The range of component `p` is `[1, 31]`. fn create_pure(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `101` + // Measured: `239` // Estimated: `4706` - // Minimum execution time: 20_049_000 picoseconds. - Weight::from_parts(20_881_515, 0) + // Minimum execution time: 27_042_000 picoseconds. + Weight::from_parts(27_624_587, 0) .saturating_add(Weight::from_parts(0, 4706)) - // Standard Error: 952 - .saturating_add(Weight::from_parts(5_970, 0).saturating_mul(p.into())) + // Standard Error: 671 + .saturating_add(Weight::from_parts(5_888, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) /// The range of component `p` is `[0, 30]`. fn kill_pure(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `126 + p * (37 ±0)` + // Measured: `264 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 18_528_000 picoseconds. - Weight::from_parts(19_384_189, 0) + // Minimum execution time: 23_396_000 picoseconds. + Weight::from_parts(24_003_080, 0) .saturating_add(Weight::from_parts(0, 4706)) - // Standard Error: 1_106 - .saturating_add(Weight::from_parts(35_698, 0).saturating_mul(p.into())) + // Standard Error: 684 + .saturating_add(Weight::from_parts(29_878, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/weights/pallet_ranked_collective.rs b/polkadot/runtime/rococo/src/weights/pallet_ranked_collective.rs index fa2decb1671..ce9d5fcc0c7 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_ranked_collective.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_ranked_collective.rs @@ -16,26 +16,24 @@ //! Autogenerated weights for `pallet_ranked_collective` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2024-01-24, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-grjcggob-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// target/production/polkadot // benchmark // pallet -// --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=pallet_ranked_collective // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_ranked_collective +// --chain=rococo-dev // --header=./polkadot/file_header.txt // --output=./polkadot/runtime/rococo/src/weights/ @@ -62,8 +60,8 @@ impl pallet_ranked_collective::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `42` // Estimated: `3507` - // Minimum execution time: 13_428_000 picoseconds. - Weight::from_parts(14_019_000, 0) + // Minimum execution time: 13_480_000 picoseconds. + Weight::from_parts(13_786_000, 0) .saturating_add(Weight::from_parts(0, 3507)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(4)) @@ -81,11 +79,11 @@ impl pallet_ranked_collective::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `516 + r * (281 ±0)` // Estimated: `3519 + r * (2529 ±0)` - // Minimum execution time: 28_566_000 picoseconds. - Weight::from_parts(29_346_952, 0) + // Minimum execution time: 28_771_000 picoseconds. + Weight::from_parts(29_256_825, 0) .saturating_add(Weight::from_parts(0, 3519)) - // Standard Error: 21_068 - .saturating_add(Weight::from_parts(14_471_237, 0).saturating_mul(r.into())) + // Standard Error: 21_594 + .saturating_add(Weight::from_parts(14_649_527, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(6)) @@ -105,11 +103,11 @@ impl pallet_ranked_collective::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `214 + r * (17 ±0)` // Estimated: `3507` - // Minimum execution time: 16_161_000 picoseconds. - Weight::from_parts(16_981_334, 0) + // Minimum execution time: 16_117_000 picoseconds. + Weight::from_parts(16_978_453, 0) .saturating_add(Weight::from_parts(0, 3507)) - // Standard Error: 4_596 - .saturating_add(Weight::from_parts(313_386, 0).saturating_mul(r.into())) + // Standard Error: 4_511 + .saturating_add(Weight::from_parts(324_261, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -126,11 +124,11 @@ impl pallet_ranked_collective::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `532 + r * (72 ±0)` // Estimated: `3519` - // Minimum execution time: 28_406_000 picoseconds. - Weight::from_parts(31_178_557, 0) + // Minimum execution time: 28_995_000 picoseconds. + Weight::from_parts(31_343_215, 0) .saturating_add(Weight::from_parts(0, 3519)) - // Standard Error: 17_737 - .saturating_add(Weight::from_parts(627_757, 0).saturating_mul(r.into())) + // Standard Error: 16_438 + .saturating_add(Weight::from_parts(637_462, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(6)) } @@ -142,17 +140,15 @@ impl pallet_ranked_collective::WeightInfo for WeightInf /// Proof: `FellowshipCollective::Voting` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn vote() -> Weight { // Proof Size summary in bytes: // Measured: `603` // Estimated: `83866` - // Minimum execution time: 41_164_000 picoseconds. - Weight::from_parts(42_163_000, 0) + // Minimum execution time: 38_820_000 picoseconds. + Weight::from_parts(40_240_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:0) /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) @@ -165,11 +161,11 @@ impl pallet_ranked_collective::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `400 + n * (50 ±0)` // Estimated: `4365 + n * (2540 ±0)` - // Minimum execution time: 13_183_000 picoseconds. - Weight::from_parts(15_604_064, 0) + // Minimum execution time: 12_972_000 picoseconds. + Weight::from_parts(15_829_333, 0) .saturating_add(Weight::from_parts(0, 4365)) - // Standard Error: 2_018 - .saturating_add(Weight::from_parts(1_101_088, 0).saturating_mul(n.into())) + // Standard Error: 1_754 + .saturating_add(Weight::from_parts(1_116_520, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) @@ -187,8 +183,8 @@ impl pallet_ranked_collective::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `337` // Estimated: `6048` - // Minimum execution time: 43_603_000 picoseconds. - Weight::from_parts(44_809_000, 0) + // Minimum execution time: 44_601_000 picoseconds. + Weight::from_parts(45_714_000, 0) .saturating_add(Weight::from_parts(0, 6048)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(10)) diff --git a/polkadot/runtime/rococo/src/weights/pallet_recovery.rs b/polkadot/runtime/rococo/src/weights/pallet_recovery.rs deleted file mode 100644 index ed79aa2b1f1..00000000000 --- a/polkadot/runtime/rococo/src/weights/pallet_recovery.rs +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Polkadot. - -// Polkadot is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Polkadot is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Polkadot. If not, see . - -//! Autogenerated weights for `pallet_recovery` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/production/polkadot -// benchmark -// pallet -// --chain=rococo-dev -// --steps=50 -// --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=pallet_recovery -// --extrinsic=* -// --execution=wasm -// --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `pallet_recovery`. -pub struct WeightInfo(PhantomData); -impl pallet_recovery::WeightInfo for WeightInfo { - /// Storage: `Recovery::Proxy` (r:1 w:0) - /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) - fn as_recovered() -> Weight { - // Proof Size summary in bytes: - // Measured: `215` - // Estimated: `3545` - // Minimum execution time: 7_899_000 picoseconds. - Weight::from_parts(8_205_000, 0) - .saturating_add(Weight::from_parts(0, 3545)) - .saturating_add(T::DbWeight::get().reads(1)) - } - /// Storage: `Recovery::Proxy` (r:0 w:1) - /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) - fn set_recovered() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 6_258_000 picoseconds. - Weight::from_parts(6_494_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(T::DbWeight::get().writes(1)) - } - /// Storage: `Recovery::Recoverable` (r:1 w:1) - /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) - /// The range of component `n` is `[1, 9]`. - fn create_recovery(n: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `109` - // Estimated: `3816` - // Minimum execution time: 19_369_000 picoseconds. - Weight::from_parts(20_185_132, 0) - .saturating_add(Weight::from_parts(0, 3816)) - // Standard Error: 4_275 - .saturating_add(Weight::from_parts(78_024, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) - } - /// Storage: `Recovery::Recoverable` (r:1 w:0) - /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) - /// Storage: `Recovery::ActiveRecoveries` (r:1 w:1) - /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) - fn initiate_recovery() -> Weight { - // Proof Size summary in bytes: - // Measured: `206` - // Estimated: `3854` - // Minimum execution time: 22_425_000 picoseconds. - Weight::from_parts(23_171_000, 0) - .saturating_add(Weight::from_parts(0, 3854)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) - } - /// Storage: `Recovery::Recoverable` (r:1 w:0) - /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) - /// Storage: `Recovery::ActiveRecoveries` (r:1 w:1) - /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) - /// The range of component `n` is `[1, 9]`. - fn vouch_recovery(n: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `294 + n * (64 ±0)` - // Estimated: `3854` - // Minimum execution time: 17_308_000 picoseconds. - Weight::from_parts(18_118_782, 0) - .saturating_add(Weight::from_parts(0, 3854)) - // Standard Error: 4_309 - .saturating_add(Weight::from_parts(126_278, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) - } - /// Storage: `Recovery::Recoverable` (r:1 w:0) - /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) - /// Storage: `Recovery::ActiveRecoveries` (r:1 w:0) - /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) - /// Storage: `Recovery::Proxy` (r:1 w:1) - /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) - /// The range of component `n` is `[1, 9]`. - fn claim_recovery(n: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `326 + n * (64 ±0)` - // Estimated: `3854` - // Minimum execution time: 20_755_000 picoseconds. - Weight::from_parts(21_821_713, 0) - .saturating_add(Weight::from_parts(0, 3854)) - // Standard Error: 4_550 - .saturating_add(Weight::from_parts(101_916, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(1)) - } - /// Storage: `Recovery::ActiveRecoveries` (r:1 w:1) - /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// The range of component `n` is `[1, 9]`. - fn close_recovery(n: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `447 + n * (32 ±0)` - // Estimated: `3854` - // Minimum execution time: 29_957_000 picoseconds. - Weight::from_parts(31_010_309, 0) - .saturating_add(Weight::from_parts(0, 3854)) - // Standard Error: 5_913 - .saturating_add(Weight::from_parts(110_070, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) - } - /// Storage: `Recovery::ActiveRecoveries` (r:1 w:0) - /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) - /// Storage: `Recovery::Recoverable` (r:1 w:1) - /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) - /// The range of component `n` is `[1, 9]`. - fn remove_recovery(n: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `204 + n * (32 ±0)` - // Estimated: `3854` - // Minimum execution time: 24_430_000 picoseconds. - Weight::from_parts(24_462_856, 0) - .saturating_add(Weight::from_parts(0, 3854)) - // Standard Error: 13_646 - .saturating_add(Weight::from_parts(507_715, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(1)) - } - /// Storage: `Recovery::Proxy` (r:1 w:1) - /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) - fn cancel_recovered() -> Weight { - // Proof Size summary in bytes: - // Measured: `215` - // Estimated: `3545` - // Minimum execution time: 9_686_000 picoseconds. - Weight::from_parts(10_071_000, 0) - .saturating_add(Weight::from_parts(0, 3545)) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) - } -} diff --git a/polkadot/runtime/rococo/src/weights/pallet_referenda_fellowship_referenda.rs b/polkadot/runtime/rococo/src/weights/pallet_referenda_fellowship_referenda.rs index 6dfcea2b832..96f172230e1 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_referenda_fellowship_referenda.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_referenda_fellowship_referenda.rs @@ -16,28 +16,27 @@ //! Autogenerated weights for `pallet_referenda` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-07-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `runner-xerhrdyb-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: `Some(Wasm)`, WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// target/production/polkadot // benchmark // pallet -// --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=pallet_referenda // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=pallet_referenda +// --chain=rococo-dev +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -60,10 +59,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) fn submit() -> Weight { // Proof Size summary in bytes: - // Measured: `292` + // Measured: `327` // Estimated: `42428` - // Minimum execution time: 24_053_000 picoseconds. - Weight::from_parts(25_121_000, 0) + // Minimum execution time: 29_909_000 picoseconds. + Weight::from_parts(30_645_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) @@ -72,17 +71,15 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_preparing() -> Weight { // Proof Size summary in bytes: - // Measured: `403` + // Measured: `438` // Estimated: `83866` - // Minimum execution time: 45_064_000 picoseconds. - Weight::from_parts(46_112_000, 0) + // Minimum execution time: 54_405_000 picoseconds. + Weight::from_parts(55_583_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) @@ -92,17 +89,15 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `2041` + // Measured: `2076` // Estimated: `42428` - // Minimum execution time: 94_146_000 picoseconds. - Weight::from_parts(98_587_000, 0) + // Minimum execution time: 110_477_000 picoseconds. + Weight::from_parts(119_187_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) @@ -112,17 +107,15 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_not_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `2082` + // Measured: `2117` // Estimated: `42428` - // Minimum execution time: 93_002_000 picoseconds. - Weight::from_parts(96_924_000, 0) + // Minimum execution time: 111_467_000 picoseconds. + Weight::from_parts(117_758_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) @@ -132,17 +125,15 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `739` + // Measured: `774` // Estimated: `83866` - // Minimum execution time: 160_918_000 picoseconds. - Weight::from_parts(175_603_000, 0) + // Minimum execution time: 191_135_000 picoseconds. + Weight::from_parts(210_535_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) @@ -152,26 +143,24 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `604` + // Measured: `639` // Estimated: `83866` - // Minimum execution time: 55_253_000 picoseconds. - Weight::from_parts(56_488_000, 0) + // Minimum execution time: 67_168_000 picoseconds. + Weight::from_parts(68_895_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) fn refund_decision_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `317` + // Measured: `351` // Estimated: `4365` - // Minimum execution time: 24_497_000 picoseconds. - Weight::from_parts(25_280_000, 0) + // Minimum execution time: 31_298_000 picoseconds. + Weight::from_parts(32_570_000, 0) .saturating_add(Weight::from_parts(0, 4365)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -180,10 +169,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) fn refund_submission_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `167` + // Measured: `201` // Estimated: `4365` - // Minimum execution time: 11_374_000 picoseconds. - Weight::from_parts(11_817_000, 0) + // Minimum execution time: 15_674_000 picoseconds. + Weight::from_parts(16_190_000, 0) .saturating_add(Weight::from_parts(0, 4365)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -192,17 +181,15 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn cancel() -> Weight { // Proof Size summary in bytes: - // Measured: `348` + // Measured: `383` // Estimated: `83866` - // Minimum execution time: 31_805_000 picoseconds. - Weight::from_parts(32_622_000, 0) + // Minimum execution time: 38_927_000 picoseconds. + Weight::from_parts(40_545_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) @@ -210,17 +197,15 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) /// Storage: `FellowshipReferenda::MetadataOf` (r:1 w:0) /// Proof: `FellowshipReferenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn kill() -> Weight { // Proof Size summary in bytes: - // Measured: `449` + // Measured: `484` // Estimated: `83866` - // Minimum execution time: 62_364_000 picoseconds. - Weight::from_parts(63_798_000, 0) + // Minimum execution time: 80_209_000 picoseconds. + Weight::from_parts(82_084_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `FellowshipReferenda::TrackQueue` (r:1 w:0) /// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`) @@ -228,10 +213,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) fn one_fewer_deciding_queue_empty() -> Weight { // Proof Size summary in bytes: - // Measured: `140` + // Measured: `174` // Estimated: `4277` - // Minimum execution time: 8_811_000 picoseconds. - Weight::from_parts(9_224_000, 0) + // Minimum execution time: 9_520_000 picoseconds. + Weight::from_parts(10_088_000, 0) .saturating_add(Weight::from_parts(0, 4277)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -246,10 +231,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn one_fewer_deciding_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `2341` + // Measured: `2376` // Estimated: `42428` - // Minimum execution time: 83_292_000 picoseconds. - Weight::from_parts(89_114_000, 0) + // Minimum execution time: 93_893_000 picoseconds. + Weight::from_parts(101_065_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) @@ -264,10 +249,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn one_fewer_deciding_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `2327` + // Measured: `2362` // Estimated: `42428` - // Minimum execution time: 84_648_000 picoseconds. - Weight::from_parts(89_332_000, 0) + // Minimum execution time: 98_811_000 picoseconds. + Weight::from_parts(103_590_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) @@ -278,10 +263,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`) fn nudge_referendum_requeued_insertion() -> Weight { // Proof Size summary in bytes: - // Measured: `1807` + // Measured: `1841` // Estimated: `4365` - // Minimum execution time: 40_529_000 picoseconds. - Weight::from_parts(45_217_000, 0) + // Minimum execution time: 43_230_000 picoseconds. + Weight::from_parts(46_120_000, 0) .saturating_add(Weight::from_parts(0, 4365)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -292,10 +277,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`) fn nudge_referendum_requeued_slide() -> Weight { // Proof Size summary in bytes: - // Measured: `1774` + // Measured: `1808` // Estimated: `4365` - // Minimum execution time: 40_894_000 picoseconds. - Weight::from_parts(45_726_000, 0) + // Minimum execution time: 43_092_000 picoseconds. + Weight::from_parts(46_018_000, 0) .saturating_add(Weight::from_parts(0, 4365)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -308,10 +293,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`) fn nudge_referendum_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `1790` + // Measured: `1824` // Estimated: `4365` - // Minimum execution time: 48_187_000 picoseconds. - Weight::from_parts(52_655_000, 0) + // Minimum execution time: 49_697_000 picoseconds. + Weight::from_parts(53_795_000, 0) .saturating_add(Weight::from_parts(0, 4365)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -324,10 +309,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`) fn nudge_referendum_not_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `1831` + // Measured: `1865` // Estimated: `4365` - // Minimum execution time: 47_548_000 picoseconds. - Weight::from_parts(51_547_000, 0) + // Minimum execution time: 50_417_000 picoseconds. + Weight::from_parts(53_214_000, 0) .saturating_add(Weight::from_parts(0, 4365)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -338,10 +323,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_no_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `300` + // Measured: `335` // Estimated: `42428` - // Minimum execution time: 20_959_000 picoseconds. - Weight::from_parts(21_837_000, 0) + // Minimum execution time: 25_688_000 picoseconds. + Weight::from_parts(26_575_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -352,10 +337,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_preparing() -> Weight { // Proof Size summary in bytes: - // Measured: `348` + // Measured: `383` // Estimated: `42428` - // Minimum execution time: 21_628_000 picoseconds. - Weight::from_parts(22_192_000, 0) + // Minimum execution time: 26_230_000 picoseconds. + Weight::from_parts(27_235_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -364,10 +349,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) fn nudge_referendum_timed_out() -> Weight { // Proof Size summary in bytes: - // Measured: `208` + // Measured: `242` // Estimated: `4365` - // Minimum execution time: 12_309_000 picoseconds. - Weight::from_parts(12_644_000, 0) + // Minimum execution time: 17_585_000 picoseconds. + Weight::from_parts(18_225_000, 0) .saturating_add(Weight::from_parts(0, 4365)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -382,10 +367,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_begin_deciding_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `549` + // Measured: `584` // Estimated: `42428` - // Minimum execution time: 31_871_000 picoseconds. - Weight::from_parts(33_123_000, 0) + // Minimum execution time: 38_243_000 picoseconds. + Weight::from_parts(39_959_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) @@ -400,10 +385,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_begin_deciding_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `684` + // Measured: `719` // Estimated: `42428` - // Minimum execution time: 73_715_000 picoseconds. - Weight::from_parts(79_980_000, 0) + // Minimum execution time: 88_424_000 picoseconds. + Weight::from_parts(92_969_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) @@ -416,10 +401,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_begin_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `735` + // Measured: `770` // Estimated: `42428` - // Minimum execution time: 128_564_000 picoseconds. - Weight::from_parts(138_536_000, 0) + // Minimum execution time: 138_207_000 picoseconds. + Weight::from_parts(151_726_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -432,10 +417,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_end_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `720` + // Measured: `755` // Estimated: `42428` - // Minimum execution time: 129_775_000 picoseconds. - Weight::from_parts(139_001_000, 0) + // Minimum execution time: 131_001_000 picoseconds. + Weight::from_parts(148_651_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -448,10 +433,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_continue_not_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `735` + // Measured: `770` // Estimated: `42428` - // Minimum execution time: 128_233_000 picoseconds. - Weight::from_parts(135_796_000, 0) + // Minimum execution time: 109_612_000 picoseconds. + Weight::from_parts(143_626_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -464,10 +449,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_continue_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `741` + // Measured: `776` // Estimated: `42428` - // Minimum execution time: 66_995_000 picoseconds. - Weight::from_parts(72_678_000, 0) + // Minimum execution time: 71_754_000 picoseconds. + Weight::from_parts(77_329_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -482,10 +467,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) fn nudge_referendum_approved() -> Weight { // Proof Size summary in bytes: - // Measured: `741` + // Measured: `776` // Estimated: `83866` - // Minimum execution time: 137_764_000 picoseconds. - Weight::from_parts(152_260_000, 0) + // Minimum execution time: 153_244_000 picoseconds. + Weight::from_parts(169_961_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) @@ -498,10 +483,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_rejected() -> Weight { // Proof Size summary in bytes: - // Measured: `737` + // Measured: `772` // Estimated: `42428` - // Minimum execution time: 119_992_000 picoseconds. - Weight::from_parts(134_805_000, 0) + // Minimum execution time: 137_997_000 picoseconds. + Weight::from_parts(157_862_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -510,18 +495,16 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`) /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `FellowshipReferenda::MetadataOf` (r:0 w:1) /// Proof: `FellowshipReferenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn set_some_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `424` + // Measured: `458` // Estimated: `4365` - // Minimum execution time: 20_927_000 picoseconds. - Weight::from_parts(21_802_000, 0) + // Minimum execution time: 21_794_000 picoseconds. + Weight::from_parts(22_341_000, 0) .saturating_add(Weight::from_parts(0, 4365)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:0) @@ -530,10 +513,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `FellowshipReferenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn clear_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `285` + // Measured: `319` // Estimated: `4365` - // Minimum execution time: 14_253_000 picoseconds. - Weight::from_parts(15_031_000, 0) + // Minimum execution time: 18_458_000 picoseconds. + Weight::from_parts(19_097_000, 0) .saturating_add(Weight::from_parts(0, 4365)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/polkadot/runtime/rococo/src/weights/pallet_referenda_referenda.rs b/polkadot/runtime/rococo/src/weights/pallet_referenda_referenda.rs index c35925198f9..b7cc5df28b9 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_referenda_referenda.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_referenda_referenda.rs @@ -16,28 +16,27 @@ //! Autogenerated weights for `pallet_referenda` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-07-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `runner-xerhrdyb-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: `Some(Wasm)`, WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// target/production/polkadot // benchmark // pallet -// --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=pallet_referenda // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=pallet_referenda +// --chain=rococo-dev +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -58,10 +57,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) fn submit() -> Weight { // Proof Size summary in bytes: - // Measured: `185` + // Measured: `324` // Estimated: `42428` - // Minimum execution time: 28_612_000 picoseconds. - Weight::from_parts(30_060_000, 0) + // Minimum execution time: 39_852_000 picoseconds. + Weight::from_parts(41_610_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(3)) @@ -70,17 +69,15 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_preparing() -> Weight { // Proof Size summary in bytes: - // Measured: `438` + // Measured: `577` // Estimated: `83866` - // Minimum execution time: 42_827_000 picoseconds. - Weight::from_parts(44_072_000, 0) + // Minimum execution time: 52_588_000 picoseconds. + Weight::from_parts(54_154_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) @@ -90,17 +87,15 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3225` + // Measured: `3334` // Estimated: `42428` - // Minimum execution time: 56_475_000 picoseconds. - Weight::from_parts(58_888_000, 0) + // Minimum execution time: 70_483_000 picoseconds. + Weight::from_parts(72_731_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) @@ -110,62 +105,60 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_not_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3245` + // Measured: `3354` // Estimated: `42428` - // Minimum execution time: 56_542_000 picoseconds. - Weight::from_parts(58_616_000, 0) + // Minimum execution time: 68_099_000 picoseconds. + Weight::from_parts(71_560_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) /// Storage: `Referenda::DecidingCount` (r:1 w:1) /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Balances::InactiveIssuance` (r:1 w:0) + /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `438` + // Measured: `577` // Estimated: `83866` - // Minimum execution time: 51_218_000 picoseconds. - Weight::from_parts(53_148_000, 0) + // Minimum execution time: 64_357_000 picoseconds. + Weight::from_parts(66_081_000, 0) .saturating_add(Weight::from_parts(0, 83866)) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) /// Storage: `Referenda::DecidingCount` (r:1 w:1) /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Balances::InactiveIssuance` (r:1 w:0) + /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn place_decision_deposit_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `438` + // Measured: `577` // Estimated: `83866` - // Minimum execution time: 49_097_000 picoseconds. - Weight::from_parts(50_796_000, 0) + // Minimum execution time: 62_709_000 picoseconds. + Weight::from_parts(64_534_000, 0) .saturating_add(Weight::from_parts(0, 83866)) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) fn refund_decision_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `279` + // Measured: `417` // Estimated: `4401` - // Minimum execution time: 23_720_000 picoseconds. - Weight::from_parts(24_327_000, 0) + // Minimum execution time: 31_296_000 picoseconds. + Weight::from_parts(32_221_000, 0) .saturating_add(Weight::from_parts(0, 4401)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -174,10 +167,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) fn refund_submission_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `269` + // Measured: `407` // Estimated: `4401` - // Minimum execution time: 24_089_000 picoseconds. - Weight::from_parts(24_556_000, 0) + // Minimum execution time: 31_209_000 picoseconds. + Weight::from_parts(32_168_000, 0) .saturating_add(Weight::from_parts(0, 4401)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -186,17 +179,15 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn cancel() -> Weight { // Proof Size summary in bytes: - // Measured: `346` + // Measured: `485` // Estimated: `83866` - // Minimum execution time: 29_022_000 picoseconds. - Weight::from_parts(29_590_000, 0) + // Minimum execution time: 38_887_000 picoseconds. + Weight::from_parts(40_193_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) @@ -204,17 +195,15 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) /// Storage: `Referenda::MetadataOf` (r:1 w:0) /// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn kill() -> Weight { // Proof Size summary in bytes: - // Measured: `587` + // Measured: `726` // Estimated: `83866` - // Minimum execution time: 81_920_000 picoseconds. - Weight::from_parts(84_492_000, 0) + // Minimum execution time: 106_054_000 picoseconds. + Weight::from_parts(108_318_000, 0) .saturating_add(Weight::from_parts(0, 83866)) .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Referenda::TrackQueue` (r:1 w:0) /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) @@ -222,10 +211,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) fn one_fewer_deciding_queue_empty() -> Weight { // Proof Size summary in bytes: - // Measured: `102` + // Measured: `240` // Estimated: `5477` - // Minimum execution time: 8_134_000 picoseconds. - Weight::from_parts(8_574_000, 0) + // Minimum execution time: 9_263_000 picoseconds. + Weight::from_parts(9_763_000, 0) .saturating_add(Weight::from_parts(0, 5477)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -234,32 +223,36 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) + /// Storage: `Balances::InactiveIssuance` (r:1 w:0) + /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn one_fewer_deciding_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `3115` + // Measured: `3254` // Estimated: `42428` - // Minimum execution time: 39_932_000 picoseconds. - Weight::from_parts(42_086_000, 0) + // Minimum execution time: 50_080_000 picoseconds. + Weight::from_parts(51_858_000, 0) .saturating_add(Weight::from_parts(0, 42428)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Referenda::TrackQueue` (r:1 w:1) /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) + /// Storage: `Balances::InactiveIssuance` (r:1 w:0) + /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn one_fewer_deciding_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `3115` + // Measured: `3254` // Estimated: `42428` - // Minimum execution time: 42_727_000 picoseconds. - Weight::from_parts(44_280_000, 0) + // Minimum execution time: 53_889_000 picoseconds. + Weight::from_parts(55_959_000, 0) .saturating_add(Weight::from_parts(0, 42428)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) @@ -268,10 +261,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) fn nudge_referendum_requeued_insertion() -> Weight { // Proof Size summary in bytes: - // Measured: `2939` + // Measured: `3077` // Estimated: `5477` - // Minimum execution time: 20_918_000 picoseconds. - Weight::from_parts(22_180_000, 0) + // Minimum execution time: 23_266_000 picoseconds. + Weight::from_parts(24_624_000, 0) .saturating_add(Weight::from_parts(0, 5477)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -282,10 +275,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) fn nudge_referendum_requeued_slide() -> Weight { // Proof Size summary in bytes: - // Measured: `2939` + // Measured: `3077` // Estimated: `5477` - // Minimum execution time: 20_943_000 picoseconds. - Weight::from_parts(21_932_000, 0) + // Minimum execution time: 22_846_000 picoseconds. + Weight::from_parts(24_793_000, 0) .saturating_add(Weight::from_parts(0, 5477)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -298,10 +291,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) fn nudge_referendum_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `2943` + // Measured: `3081` // Estimated: `5477` - // Minimum execution time: 25_197_000 picoseconds. - Weight::from_parts(26_083_000, 0) + // Minimum execution time: 28_284_000 picoseconds. + Weight::from_parts(29_940_000, 0) .saturating_add(Weight::from_parts(0, 5477)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -314,10 +307,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) fn nudge_referendum_not_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `2963` + // Measured: `3101` // Estimated: `5477` - // Minimum execution time: 24_969_000 picoseconds. - Weight::from_parts(26_096_000, 0) + // Minimum execution time: 28_133_000 picoseconds. + Weight::from_parts(29_638_000, 0) .saturating_add(Weight::from_parts(0, 5477)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -328,10 +321,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_no_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `298` + // Measured: `437` // Estimated: `42428` - // Minimum execution time: 18_050_000 picoseconds. - Weight::from_parts(18_790_000, 0) + // Minimum execution time: 25_710_000 picoseconds. + Weight::from_parts(26_500_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -342,10 +335,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_preparing() -> Weight { // Proof Size summary in bytes: - // Measured: `346` + // Measured: `485` // Estimated: `42428` - // Minimum execution time: 18_357_000 picoseconds. - Weight::from_parts(18_957_000, 0) + // Minimum execution time: 25_935_000 picoseconds. + Weight::from_parts(26_803_000, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -354,10 +347,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) fn nudge_referendum_timed_out() -> Weight { // Proof Size summary in bytes: - // Measured: `206` + // Measured: `344` // Estimated: `4401` - // Minimum execution time: 11_479_000 picoseconds. - Weight::from_parts(11_968_000, 0) + // Minimum execution time: 17_390_000 picoseconds. + Weight::from_parts(18_042_000, 0) .saturating_add(Weight::from_parts(0, 4401)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -366,136 +359,150 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) /// Storage: `Referenda::DecidingCount` (r:1 w:1) /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Balances::InactiveIssuance` (r:1 w:0) + /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_begin_deciding_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `346` + // Measured: `485` // Estimated: `42428` - // Minimum execution time: 24_471_000 picoseconds. - Weight::from_parts(25_440_000, 0) + // Minimum execution time: 35_141_000 picoseconds. + Weight::from_parts(36_318_000, 0) .saturating_add(Weight::from_parts(0, 42428)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) /// Storage: `Referenda::DecidingCount` (r:1 w:1) /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: `Balances::InactiveIssuance` (r:1 w:0) + /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_begin_deciding_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `346` + // Measured: `485` // Estimated: `42428` - // Minimum execution time: 26_580_000 picoseconds. - Weight::from_parts(27_570_000, 0) + // Minimum execution time: 37_815_000 picoseconds. + Weight::from_parts(39_243_000, 0) .saturating_add(Weight::from_parts(0, 42428)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) + /// Storage: `Balances::InactiveIssuance` (r:1 w:0) + /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_begin_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `399` + // Measured: `538` // Estimated: `42428` - // Minimum execution time: 24_331_000 picoseconds. - Weight::from_parts(25_291_000, 0) + // Minimum execution time: 30_779_000 picoseconds. + Weight::from_parts(31_845_000, 0) .saturating_add(Weight::from_parts(0, 42428)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) + /// Storage: `Balances::InactiveIssuance` (r:1 w:0) + /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_end_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `382` + // Measured: `521` // Estimated: `42428` - // Minimum execution time: 24_768_000 picoseconds. - Weight::from_parts(25_746_000, 0) + // Minimum execution time: 31_908_000 picoseconds. + Weight::from_parts(33_253_000, 0) .saturating_add(Weight::from_parts(0, 42428)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) + /// Storage: `Balances::InactiveIssuance` (r:1 w:0) + /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_continue_not_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `399` + // Measured: `538` // Estimated: `42428` - // Minimum execution time: 23_171_000 picoseconds. - Weight::from_parts(24_161_000, 0) + // Minimum execution time: 28_951_000 picoseconds. + Weight::from_parts(30_004_000, 0) .saturating_add(Weight::from_parts(0, 42428)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) + /// Storage: `Balances::InactiveIssuance` (r:1 w:0) + /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_continue_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `403` + // Measured: `542` // Estimated: `42428` - // Minimum execution time: 22_263_000 picoseconds. - Weight::from_parts(23_062_000, 0) + // Minimum execution time: 27_750_000 picoseconds. + Weight::from_parts(28_588_000, 0) .saturating_add(Weight::from_parts(0, 42428)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) + /// Storage: `Balances::InactiveIssuance` (r:1 w:0) + /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:2 w:2) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Lookup` (r:1 w:1) /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) fn nudge_referendum_approved() -> Weight { // Proof Size summary in bytes: - // Measured: `403` + // Measured: `542` // Estimated: `83866` - // Minimum execution time: 33_710_000 picoseconds. - Weight::from_parts(34_871_000, 0) + // Minimum execution time: 43_950_000 picoseconds. + Weight::from_parts(46_164_000, 0) .saturating_add(Weight::from_parts(0, 83866)) - .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) + /// Storage: `Balances::InactiveIssuance` (r:1 w:0) + /// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) fn nudge_referendum_rejected() -> Weight { // Proof Size summary in bytes: - // Measured: `399` + // Measured: `538` // Estimated: `42428` - // Minimum execution time: 24_260_000 picoseconds. - Weight::from_parts(25_104_000, 0) + // Minimum execution time: 31_050_000 picoseconds. + Weight::from_parts(32_169_000, 0) .saturating_add(Weight::from_parts(0, 42428)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`) /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Referenda::MetadataOf` (r:0 w:1) /// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn set_some_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `422` + // Measured: `560` // Estimated: `4401` - // Minimum execution time: 19_821_000 picoseconds. - Weight::from_parts(20_641_000, 0) + // Minimum execution time: 21_193_000 picoseconds. + Weight::from_parts(22_116_000, 0) .saturating_add(Weight::from_parts(0, 4401)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) @@ -504,10 +511,10 @@ impl pallet_referenda::WeightInfo for WeightInfo { /// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn clear_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `283` + // Measured: `421` // Estimated: `4401` - // Minimum execution time: 13_411_000 picoseconds. - Weight::from_parts(14_070_000, 0) + // Minimum execution time: 18_065_000 picoseconds. + Weight::from_parts(18_781_000, 0) .saturating_add(Weight::from_parts(0, 4401)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/polkadot/runtime/rococo/src/weights/pallet_scheduler.rs b/polkadot/runtime/rococo/src/weights/pallet_scheduler.rs index 5f6b41d2b54..0f36dbd384d 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_scheduler.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_scheduler.rs @@ -16,26 +16,24 @@ //! Autogenerated weights for `pallet_scheduler` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2024-01-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-grjcggob-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// target/production/polkadot // benchmark // pallet -// --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=pallet_scheduler // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_scheduler +// --chain=rococo-dev // --header=./polkadot/file_header.txt // --output=./polkadot/runtime/rococo/src/weights/ @@ -56,8 +54,8 @@ impl pallet_scheduler::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `68` // Estimated: `1489` - // Minimum execution time: 3_114_000 picoseconds. - Weight::from_parts(3_245_000, 0) + // Minimum execution time: 2_869_000 picoseconds. + Weight::from_parts(3_109_000, 0) .saturating_add(Weight::from_parts(0, 1489)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -69,11 +67,11 @@ impl pallet_scheduler::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `115 + s * (177 ±0)` // Estimated: `42428` - // Minimum execution time: 3_430_000 picoseconds. - Weight::from_parts(6_250_920, 0) + // Minimum execution time: 3_326_000 picoseconds. + Weight::from_parts(5_818_563, 0) .saturating_add(Weight::from_parts(0, 42428)) - // Standard Error: 1_350 - .saturating_add(Weight::from_parts(333_245, 0).saturating_mul(s.into())) + // Standard Error: 1_261 + .saturating_add(Weight::from_parts(336_446, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -81,8 +79,8 @@ impl pallet_scheduler::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_166_000 picoseconds. - Weight::from_parts(3_295_000, 0) + // Minimum execution time: 3_007_000 picoseconds. + Weight::from_parts(3_197_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// Storage: `Preimage::PreimageFor` (r:1 w:1) @@ -96,11 +94,11 @@ impl pallet_scheduler::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `251 + s * (1 ±0)` // Estimated: `3716 + s * (1 ±0)` - // Minimum execution time: 17_072_000 picoseconds. - Weight::from_parts(17_393_000, 0) + // Minimum execution time: 16_590_000 picoseconds. + Weight::from_parts(16_869_000, 0) .saturating_add(Weight::from_parts(0, 3716)) - // Standard Error: 1 - .saturating_add(Weight::from_parts(1_204, 0).saturating_mul(s.into())) + // Standard Error: 9 + .saturating_add(Weight::from_parts(1_308, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(s.into())) @@ -111,8 +109,8 @@ impl pallet_scheduler::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_566_000 picoseconds. - Weight::from_parts(4_775_000, 0) + // Minimum execution time: 4_320_000 picoseconds. + Weight::from_parts(4_594_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -120,24 +118,24 @@ impl pallet_scheduler::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_180_000 picoseconds. - Weight::from_parts(3_339_000, 0) + // Minimum execution time: 2_956_000 picoseconds. + Weight::from_parts(3_216_000, 0) .saturating_add(Weight::from_parts(0, 0)) } fn execute_dispatch_signed() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_656_000 picoseconds. - Weight::from_parts(1_829_000, 0) + // Minimum execution time: 1_824_000 picoseconds. + Weight::from_parts(1_929_000, 0) .saturating_add(Weight::from_parts(0, 0)) } fn execute_dispatch_unsigned() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_628_000 picoseconds. - Weight::from_parts(1_840_000, 0) + // Minimum execution time: 1_749_000 picoseconds. + Weight::from_parts(1_916_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// Storage: `Scheduler::Agenda` (r:1 w:1) @@ -147,18 +145,16 @@ impl pallet_scheduler::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `115 + s * (177 ±0)` // Estimated: `42428` - // Minimum execution time: 9_523_000 picoseconds. - Weight::from_parts(12_482_434, 0) + // Minimum execution time: 9_086_000 picoseconds. + Weight::from_parts(11_733_696, 0) .saturating_add(Weight::from_parts(0, 42428)) - // Standard Error: 1_663 - .saturating_add(Weight::from_parts(370_122, 0).saturating_mul(s.into())) + // Standard Error: 1_362 + .saturating_add(Weight::from_parts(375_266, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Lookup` (r:0 w:1) /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 50]`. @@ -166,13 +162,13 @@ impl pallet_scheduler::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `115 + s * (177 ±0)` // Estimated: `42428` - // Minimum execution time: 14_649_000 picoseconds. - Weight::from_parts(14_705_132, 0) + // Minimum execution time: 12_716_000 picoseconds. + Weight::from_parts(12_529_180, 0) .saturating_add(Weight::from_parts(0, 42428)) - // Standard Error: 1_126 - .saturating_add(Weight::from_parts(547_438, 0).saturating_mul(s.into())) + // Standard Error: 867 + .saturating_add(Weight::from_parts(548_188, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Scheduler::Lookup` (r:1 w:1) /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) @@ -183,11 +179,11 @@ impl pallet_scheduler::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `292 + s * (185 ±0)` // Estimated: `42428` - // Minimum execution time: 12_335_000 picoseconds. - Weight::from_parts(16_144_217, 0) + // Minimum execution time: 12_053_000 picoseconds. + Weight::from_parts(15_358_056, 0) .saturating_add(Weight::from_parts(0, 42428)) - // Standard Error: 3_533 - .saturating_add(Weight::from_parts(413_823, 0).saturating_mul(s.into())) + // Standard Error: 3_176 + .saturating_add(Weight::from_parts(421_589, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -195,48 +191,49 @@ impl pallet_scheduler::WeightInfo for WeightInfo { /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 50]`. fn cancel_named(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `318 + s * (185 ±0)` // Estimated: `42428` - // Minimum execution time: 16_906_000 picoseconds. - Weight::from_parts(17_846_662, 0) + // Minimum execution time: 14_803_000 picoseconds. + Weight::from_parts(15_805_714, 0) .saturating_add(Weight::from_parts(0, 42428)) - // Standard Error: 2_687 - .saturating_add(Weight::from_parts(613_356, 0).saturating_mul(s.into())) + // Standard Error: 2_597 + .saturating_add(Weight::from_parts(611_053, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes(2)) } + /// Storage: `Scheduler::Retries` (r:1 w:2) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Lookup` (r:0 w:1) + /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 50]`. fn schedule_retry(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `155` + // Measured: `196` // Estimated: `42428` - // Minimum execution time: 8_988_000 picoseconds. - Weight::from_parts(9_527_838, 0) + // Minimum execution time: 13_156_000 picoseconds. + Weight::from_parts(13_801_287, 0) .saturating_add(Weight::from_parts(0, 42428)) - // Standard Error: 523 - .saturating_add(Weight::from_parts(25_453, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(2)) + // Standard Error: 568 + .saturating_add(Weight::from_parts(35_441, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `Scheduler::Agenda` (r:1 w:0) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Retries` (r:0 w:1) /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// The range of component `s` is `[1, 50]`. fn set_retry() -> Weight { // Proof Size summary in bytes: - // Measured: `8965` + // Measured: `115 + s * (177 ±0)` // Estimated: `42428` - // Minimum execution time: 23_337_000 picoseconds. - Weight::from_parts(24_255_000, 0) + // Minimum execution time: 7_912_000 picoseconds. + Weight::from_parts(8_081_460, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -247,12 +244,13 @@ impl pallet_scheduler::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Retries` (r:0 w:1) /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// The range of component `s` is `[1, 50]`. fn set_retry_named() -> Weight { // Proof Size summary in bytes: - // Measured: `9643` + // Measured: `324 + s * (185 ±0)` // Estimated: `42428` - // Minimum execution time: 30_704_000 picoseconds. - Weight::from_parts(31_646_000, 0) + // Minimum execution time: 10_673_000 picoseconds. + Weight::from_parts(12_212_185, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -261,12 +259,13 @@ impl pallet_scheduler::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Retries` (r:0 w:1) /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// The range of component `s` is `[1, 50]`. fn cancel_retry() -> Weight { // Proof Size summary in bytes: - // Measured: `8977` + // Measured: `115 + s * (177 ±0)` // Estimated: `42428` - // Minimum execution time: 22_279_000 picoseconds. - Weight::from_parts(23_106_000, 0) + // Minimum execution time: 7_912_000 picoseconds. + Weight::from_parts(8_081_460, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -277,12 +276,13 @@ impl pallet_scheduler::WeightInfo for WeightInfo { /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Retries` (r:0 w:1) /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// The range of component `s` is `[1, 50]`. fn cancel_retry_named() -> Weight { // Proof Size summary in bytes: - // Measured: `9655` + // Measured: `324 + s * (185 ±0)` // Estimated: `42428` - // Minimum execution time: 29_649_000 picoseconds. - Weight::from_parts(30_472_000, 0) + // Minimum execution time: 10_673_000 picoseconds. + Weight::from_parts(12_212_185, 0) .saturating_add(Weight::from_parts(0, 42428)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/polkadot/runtime/rococo/src/weights/pallet_sudo.rs b/polkadot/runtime/rococo/src/weights/pallet_sudo.rs index ecc31dc3fa9..694174954fc 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_sudo.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_sudo.rs @@ -16,26 +16,24 @@ //! Autogenerated weights for `pallet_sudo` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// target/production/polkadot // benchmark // pallet -// --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=pallet_sudo // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_sudo +// --chain=rococo-dev // --header=./polkadot/file_header.txt // --output=./polkadot/runtime/rococo/src/weights/ @@ -56,8 +54,8 @@ impl pallet_sudo::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `132` // Estimated: `1517` - // Minimum execution time: 8_336_000 picoseconds. - Weight::from_parts(8_569_000, 0) + // Minimum execution time: 8_432_000 picoseconds. + Weight::from_parts(8_757_000, 0) .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -68,8 +66,8 @@ impl pallet_sudo::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `132` // Estimated: `1517` - // Minimum execution time: 8_858_000 picoseconds. - Weight::from_parts(9_238_000, 0) + // Minimum execution time: 9_167_000 picoseconds. + Weight::from_parts(9_397_000, 0) .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) } @@ -79,8 +77,8 @@ impl pallet_sudo::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `132` // Estimated: `1517` - // Minimum execution time: 8_921_000 picoseconds. - Weight::from_parts(9_324_000, 0) + // Minimum execution time: 9_133_000 picoseconds. + Weight::from_parts(9_573_000, 0) .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) } @@ -90,21 +88,10 @@ impl pallet_sudo::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `132` // Estimated: `1517` - // Minimum execution time: 7_398_000 picoseconds. - Weight::from_parts(7_869_000, 0) + // Minimum execution time: 7_374_000 picoseconds. + Weight::from_parts(7_702_000, 0) .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Sudo::Key` (r:1 w:0) - /// Proof: `Sudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - fn check_only_sudo_account() -> Weight { - // Proof Size summary in bytes: - // Measured: `132` - // Estimated: `1517` - // Minimum execution time: 3_146_000 picoseconds. - Weight::from_parts(3_314_000, 0) - .saturating_add(Weight::from_parts(0, 1517)) - .saturating_add(T::DbWeight::get().reads(1)) - } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_timestamp.rs b/polkadot/runtime/rococo/src/weights/pallet_timestamp.rs index 7d79621b9e6..1bb2e227ab7 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_timestamp.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_timestamp.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_timestamp` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=pallet_timestamp // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,26 +47,26 @@ use core::marker::PhantomData; /// Weight functions for `pallet_timestamp`. pub struct WeightInfo(PhantomData); impl pallet_timestamp::WeightInfo for WeightInfo { - /// Storage: `Timestamp::Now` (r:1 w:1) - /// Proof: `Timestamp::Now` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Babe::CurrentSlot` (r:1 w:0) - /// Proof: `Babe::CurrentSlot` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: Timestamp Now (r:1 w:1) + /// Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe CurrentSlot (r:1 w:0) + /// Proof: Babe CurrentSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) fn set() -> Weight { // Proof Size summary in bytes: - // Measured: `137` + // Measured: `311` // Estimated: `1493` - // Minimum execution time: 5_596_000 picoseconds. - Weight::from_parts(5_823_000, 0) + // Minimum execution time: 10_103_000 picoseconds. + Weight::from_parts(10_597_000, 0) .saturating_add(Weight::from_parts(0, 1493)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } fn on_finalize() -> Weight { // Proof Size summary in bytes: - // Measured: `57` + // Measured: `94` // Estimated: `0` - // Minimum execution time: 2_777_000 picoseconds. - Weight::from_parts(2_900_000, 0) + // Minimum execution time: 4_718_000 picoseconds. + Weight::from_parts(4_839_000, 0) .saturating_add(Weight::from_parts(0, 0)) } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_transaction_payment.rs b/polkadot/runtime/rococo/src/weights/pallet_transaction_payment.rs deleted file mode 100644 index 44dfab289fb..00000000000 --- a/polkadot/runtime/rococo/src/weights/pallet_transaction_payment.rs +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Polkadot. - -// Polkadot is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Polkadot is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Polkadot. If not, see . - -//! Autogenerated weights for `pallet_transaction_payment` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/production/polkadot -// benchmark -// pallet -// --chain=rococo-dev -// --steps=50 -// --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=pallet_transaction_payment -// --extrinsic=* -// --execution=wasm -// --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `pallet_transaction_payment`. -pub struct WeightInfo(PhantomData); -impl pallet_transaction_payment::WeightInfo for WeightInfo { - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - fn charge_transaction_payment() -> Weight { - // Proof Size summary in bytes: - // Measured: `252` - // Estimated: `1737` - // Minimum execution time: 33_070_000 picoseconds. - Weight::from_parts(33_730_000, 0) - .saturating_add(Weight::from_parts(0, 1737)) - .saturating_add(T::DbWeight::get().reads(3)) - } -} diff --git a/polkadot/runtime/rococo/src/weights/pallet_treasury.rs b/polkadot/runtime/rococo/src/weights/pallet_treasury.rs index acf09989afc..144e9d5b872 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_treasury.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_treasury.rs @@ -16,28 +16,25 @@ //! Autogenerated weights for `pallet_treasury` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-07-07, STEPS: `50`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `cob`, CPU: `` +//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// ./target/debug/polkadot // benchmark // pallet // --chain=rococo-dev // --steps=50 -// --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares +// --repeat=2 // --pallet=pallet_treasury // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --heap-pages=4096 +// --output=./runtime/rococo/src/weights/ +// --header=./file_header.txt #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,168 +47,176 @@ use core::marker::PhantomData; /// Weight functions for `pallet_treasury`. pub struct WeightInfo(PhantomData); impl pallet_treasury::WeightInfo for WeightInfo { - /// Storage: `Treasury::ProposalCount` (r:1 w:1) - /// Proof: `Treasury::ProposalCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Approvals` (r:1 w:1) - /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Proposals` (r:0 w:1) - /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Storage: Treasury ProposalCount (r:1 w:1) + /// Proof: Treasury ProposalCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: Treasury Proposals (r:0 w:1) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) fn spend_local() -> Weight { // Proof Size summary in bytes: - // Measured: `142` + // Measured: `42` // Estimated: `1887` - // Minimum execution time: 9_928_000 picoseconds. - Weight::from_parts(10_560_000, 0) + // Minimum execution time: 177_000_000 picoseconds. + Weight::from_parts(191_000_000, 0) .saturating_add(Weight::from_parts(0, 1887)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `Treasury::ProposalCount` (r:1 w:1) - /// Proof: `Treasury::ProposalCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Proposals` (r:0 w:1) - /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Storage: Treasury ProposalCount (r:1 w:1) + /// Proof: Treasury ProposalCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Treasury Proposals (r:0 w:1) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) fn propose_spend() -> Weight { // Proof Size summary in bytes: - // Measured: `243` + // Measured: `143` // Estimated: `1489` - // Minimum execution time: 20_714_000 picoseconds. - Weight::from_parts(21_137_000, 0) + // Minimum execution time: 354_000_000 picoseconds. + Weight::from_parts(376_000_000, 0) .saturating_add(Weight::from_parts(0, 1489)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Treasury::Proposals` (r:1 w:1) - /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Treasury Proposals (r:1 w:1) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn reject_proposal() -> Weight { // Proof Size summary in bytes: - // Measured: `401` + // Measured: `301` // Estimated: `3593` - // Minimum execution time: 31_665_000 picoseconds. - Weight::from_parts(32_442_000, 0) + // Minimum execution time: 547_000_000 picoseconds. + Weight::from_parts(550_000_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Treasury::Proposals` (r:1 w:0) - /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Approvals` (r:1 w:1) - /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: Treasury Proposals (r:1 w:0) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) /// The range of component `p` is `[0, 99]`. fn approve_proposal(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `570 + p * (8 ±0)` + // Measured: `470 + p * (8 ±0)` // Estimated: `3573` - // Minimum execution time: 6_988_000 picoseconds. - Weight::from_parts(11_464_972, 0) + // Minimum execution time: 104_000_000 picoseconds. + Weight::from_parts(121_184_402, 0) .saturating_add(Weight::from_parts(0, 3573)) - // Standard Error: 1_722 - .saturating_add(Weight::from_parts(84_536, 0).saturating_mul(p.into())) + // Standard Error: 42_854 + .saturating_add(Weight::from_parts(153_112, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Treasury::Approvals` (r:1 w:1) - /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) fn remove_approval() -> Weight { // Proof Size summary in bytes: - // Measured: `227` + // Measured: `127` // Estimated: `1887` - // Minimum execution time: 5_386_000 picoseconds. - Weight::from_parts(5_585_000, 0) + // Minimum execution time: 80_000_000 picoseconds. + Weight::from_parts(82_000_000, 0) .saturating_add(Weight::from_parts(0, 1887)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Treasury::Deactivated` (r:1 w:1) - /// Proof: `Treasury::Deactivated` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Approvals` (r:1 w:1) - /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Proposals` (r:99 w:99) - /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:199 w:199) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Bounties::BountyApprovals` (r:1 w:1) - /// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: Treasury Deactivated (r:1 w:1) + /// Proof: Treasury Deactivated (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:1) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: Treasury Proposals (r:99 w:99) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: System Account (r:199 w:199) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyApprovals (r:1 w:1) + /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) /// The range of component `p` is `[0, 99]`. fn on_initialize_proposals(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `431 + p * (251 ±0)` + // Measured: `331 + p * (251 ±0)` // Estimated: `3593 + p * (5206 ±0)` - // Minimum execution time: 43_737_000 picoseconds. - Weight::from_parts(39_883_021, 0) + // Minimum execution time: 887_000_000 picoseconds. + Weight::from_parts(828_616_021, 0) .saturating_add(Weight::from_parts(0, 3593)) - // Standard Error: 12_917 - .saturating_add(Weight::from_parts(31_796_205, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(4)) + // Standard Error: 695_351 + .saturating_add(Weight::from_parts(566_114_524, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(p.into()))) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(5)) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(p.into()))) .saturating_add(Weight::from_parts(0, 5206).saturating_mul(p.into())) } - /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:0) - /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(1238), added: 3713, mode: `MaxEncodedLen`) - /// Storage: `Treasury::SpendCount` (r:1 w:1) - /// Proof: `Treasury::SpendCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Spends` (r:0 w:1) - /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(1853), added: 4328, mode: `MaxEncodedLen`) + /// Storage: AssetRate ConversionRateToNative (r:1 w:0) + /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(1237), added: 3712, mode: MaxEncodedLen) + /// Storage: Treasury SpendCount (r:1 w:1) + /// Proof: Treasury SpendCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Treasury Spends (r:0 w:1) + /// Proof: Treasury Spends (max_values: None, max_size: Some(1848), added: 4323, mode: MaxEncodedLen) fn spend() -> Weight { // Proof Size summary in bytes: - // Measured: `215` - // Estimated: `4703` - // Minimum execution time: 16_829_000 picoseconds. - Weight::from_parts(17_251_000, 0) - .saturating_add(Weight::from_parts(0, 4703)) + // Measured: `114` + // Estimated: `4702` + // Minimum execution time: 208_000_000 picoseconds. + Weight::from_parts(222_000_000, 0) + .saturating_add(Weight::from_parts(0, 4702)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Treasury::Spends` (r:1 w:1) - /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(1853), added: 4328, mode: `MaxEncodedLen`) - /// Storage: `XcmPallet::QueryCounter` (r:1 w:1) - /// Proof: `XcmPallet::QueryCounter` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) - /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) - /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `XcmPallet::Queries` (r:0 w:1) - /// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Treasury Spends (r:1 w:1) + /// Proof: Treasury Spends (max_values: None, max_size: Some(1848), added: 4323, mode: MaxEncodedLen) + /// Storage: XcmPallet QueryCounter (r:1 w:1) + /// Proof Skipped: XcmPallet QueryCounter (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DeliveryFeeFactor (r:1 w:0) + /// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet SupportedVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: XcmPallet SafeXcmVersion (r:1 w:0) + /// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + /// Storage: XcmPallet Queries (r:0 w:1) + /// Proof Skipped: XcmPallet Queries (max_values: None, max_size: None, mode: Measured) fn payout() -> Weight { // Proof Size summary in bytes: - // Measured: `458` - // Estimated: `5318` - // Minimum execution time: 41_554_000 picoseconds. - Weight::from_parts(42_451_000, 0) - .saturating_add(Weight::from_parts(0, 5318)) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(5)) + // Measured: `737` + // Estimated: `5313` + // Minimum execution time: 551_000_000 picoseconds. + Weight::from_parts(569_000_000, 0) + .saturating_add(Weight::from_parts(0, 5313)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(6)) } - /// Storage: `Treasury::Spends` (r:1 w:1) - /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(1853), added: 4328, mode: `MaxEncodedLen`) - /// Storage: `XcmPallet::Queries` (r:1 w:1) - /// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Treasury Spends (r:1 w:1) + /// Proof: Treasury Spends (max_values: None, max_size: Some(1848), added: 4323, mode: MaxEncodedLen) + /// Storage: XcmPallet Queries (r:1 w:1) + /// Proof Skipped: XcmPallet Queries (max_values: None, max_size: None, mode: Measured) fn check_status() -> Weight { // Proof Size summary in bytes: - // Measured: `306` - // Estimated: `5318` - // Minimum execution time: 22_546_000 picoseconds. - Weight::from_parts(23_151_000, 0) - .saturating_add(Weight::from_parts(0, 5318)) + // Measured: `442` + // Estimated: `5313` + // Minimum execution time: 245_000_000 picoseconds. + Weight::from_parts(281_000_000, 0) + .saturating_add(Weight::from_parts(0, 5313)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Treasury::Spends` (r:1 w:1) - /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(1853), added: 4328, mode: `MaxEncodedLen`) + /// Storage: Treasury Spends (r:1 w:1) + /// Proof: Treasury Spends (max_values: None, max_size: Some(1848), added: 4323, mode: MaxEncodedLen) fn void_spend() -> Weight { // Proof Size summary in bytes: - // Measured: `278` - // Estimated: `5318` - // Minimum execution time: 12_169_000 picoseconds. - Weight::from_parts(12_484_000, 0) - .saturating_add(Weight::from_parts(0, 5318)) + // Measured: `172` + // Estimated: `5313` + // Minimum execution time: 147_000_000 picoseconds. + Weight::from_parts(160_000_000, 0) + .saturating_add(Weight::from_parts(0, 5313)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/weights/pallet_utility.rs b/polkadot/runtime/rococo/src/weights/pallet_utility.rs index 6f2a374247f..f50f60eaad7 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_utility.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_utility.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_utility` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=pallet_utility // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -55,18 +52,18 @@ impl pallet_utility::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_041_000 picoseconds. - Weight::from_parts(5_685_496, 0) + // Minimum execution time: 6_738_000 picoseconds. + Weight::from_parts(2_704_821, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 810 - .saturating_add(Weight::from_parts(3_177_197, 0).saturating_mul(c.into())) + // Standard Error: 2_999 + .saturating_add(Weight::from_parts(4_627_278, 0).saturating_mul(c.into())) } fn as_derivative() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_667_000 picoseconds. - Weight::from_parts(3_871_000, 0) + // Minimum execution time: 5_294_000 picoseconds. + Weight::from_parts(5_467_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// The range of component `c` is `[0, 1000]`. @@ -74,18 +71,18 @@ impl pallet_utility::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_116_000 picoseconds. - Weight::from_parts(6_453_932, 0) + // Minimum execution time: 6_828_000 picoseconds. + Weight::from_parts(4_650_678, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 825 - .saturating_add(Weight::from_parts(3_366_112, 0).saturating_mul(c.into())) + // Standard Error: 2_789 + .saturating_add(Weight::from_parts(4_885_004, 0).saturating_mul(c.into())) } fn dispatch_as() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_630_000 picoseconds. - Weight::from_parts(5_956_000, 0) + // Minimum execution time: 9_020_000 picoseconds. + Weight::from_parts(9_205_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// The range of component `c` is `[0, 1000]`. @@ -93,10 +90,10 @@ impl pallet_utility::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_165_000 picoseconds. - Weight::from_parts(5_442_561, 0) + // Minimum execution time: 6_852_000 picoseconds. + Weight::from_parts(20_703_134, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 460 - .saturating_add(Weight::from_parts(3_173_577, 0).saturating_mul(c.into())) + // Standard Error: 3_924 + .saturating_add(Weight::from_parts(4_604_529, 0).saturating_mul(c.into())) } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_vesting.rs b/polkadot/runtime/rococo/src/weights/pallet_vesting.rs index c21ab087774..2596207d583 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_vesting.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_vesting.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `pallet_vesting` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=pallet_vesting // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,143 +47,143 @@ use core::marker::PhantomData; /// Weight functions for `pallet_vesting`. pub struct WeightInfo(PhantomData); impl pallet_vesting::WeightInfo for WeightInfo { - /// Storage: `Vesting::Vesting` (r:1 w:1) - /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) /// The range of component `l` is `[0, 49]`. /// The range of component `s` is `[1, 28]`. fn vest_locked(l: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `277 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 29_288_000 picoseconds. - Weight::from_parts(29_095_507, 0) + // Minimum execution time: 32_820_000 picoseconds. + Weight::from_parts(31_640_992, 0) .saturating_add(Weight::from_parts(0, 4764)) - // Standard Error: 1_679 - .saturating_add(Weight::from_parts(33_164, 0).saturating_mul(l.into())) - // Standard Error: 2_988 - .saturating_add(Weight::from_parts(67_092, 0).saturating_mul(s.into())) + // Standard Error: 449 + .saturating_add(Weight::from_parts(45_254, 0).saturating_mul(l.into())) + // Standard Error: 800 + .saturating_add(Weight::from_parts(72_178, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Vesting::Vesting` (r:1 w:1) - /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) /// The range of component `l` is `[0, 49]`. /// The range of component `s` is `[1, 28]`. fn vest_unlocked(l: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `277 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 31_003_000 picoseconds. - Weight::from_parts(30_528_438, 0) + // Minimum execution time: 36_054_000 picoseconds. + Weight::from_parts(35_825_428, 0) .saturating_add(Weight::from_parts(0, 4764)) - // Standard Error: 1_586 - .saturating_add(Weight::from_parts(35_429, 0).saturating_mul(l.into())) - // Standard Error: 2_823 - .saturating_add(Weight::from_parts(76_505, 0).saturating_mul(s.into())) + // Standard Error: 749 + .saturating_add(Weight::from_parts(31_738, 0).saturating_mul(l.into())) + // Standard Error: 1_333 + .saturating_add(Weight::from_parts(40_580, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Vesting::Vesting` (r:1 w:1) - /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `l` is `[0, 49]`. /// The range of component `s` is `[1, 28]`. fn vest_other_locked(l: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `380 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 31_269_000 picoseconds. - Weight::from_parts(30_661_898, 0) + // Minimum execution time: 35_440_000 picoseconds. + Weight::from_parts(34_652_647, 0) .saturating_add(Weight::from_parts(0, 4764)) - // Standard Error: 1_394 - .saturating_add(Weight::from_parts(39_300, 0).saturating_mul(l.into())) - // Standard Error: 2_480 - .saturating_add(Weight::from_parts(78_849, 0).saturating_mul(s.into())) + // Standard Error: 517 + .saturating_add(Weight::from_parts(41_942, 0).saturating_mul(l.into())) + // Standard Error: 920 + .saturating_add(Weight::from_parts(66_074, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `Vesting::Vesting` (r:1 w:1) - /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `l` is `[0, 49]`. /// The range of component `s` is `[1, 28]`. fn vest_other_unlocked(l: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `380 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 33_040_000 picoseconds. - Weight::from_parts(32_469_674, 0) + // Minimum execution time: 38_880_000 picoseconds. + Weight::from_parts(39_625_819, 0) .saturating_add(Weight::from_parts(0, 4764)) - // Standard Error: 1_418 - .saturating_add(Weight::from_parts(44_206, 0).saturating_mul(l.into())) - // Standard Error: 2_523 - .saturating_add(Weight::from_parts(74_224, 0).saturating_mul(s.into())) + // Standard Error: 1_032 + .saturating_add(Weight::from_parts(29_856, 0).saturating_mul(l.into())) + // Standard Error: 1_837 + .saturating_add(Weight::from_parts(6_210, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `Vesting::Vesting` (r:1 w:1) - /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) /// The range of component `l` is `[0, 49]`. /// The range of component `s` is `[0, 27]`. fn vested_transfer(l: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `451 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 62_032_000 picoseconds. - Weight::from_parts(63_305_621, 0) + // Minimum execution time: 68_294_000 picoseconds. + Weight::from_parts(68_313_394, 0) .saturating_add(Weight::from_parts(0, 4764)) - // Standard Error: 2_277 - .saturating_add(Weight::from_parts(42_767, 0).saturating_mul(l.into())) - // Standard Error: 4_051 - .saturating_add(Weight::from_parts(65_487, 0).saturating_mul(s.into())) + // Standard Error: 983 + .saturating_add(Weight::from_parts(48_156, 0).saturating_mul(l.into())) + // Standard Error: 1_750 + .saturating_add(Weight::from_parts(87_719, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `Vesting::Vesting` (r:1 w:1) - /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) /// The range of component `l` is `[0, 49]`. /// The range of component `s` is `[0, 27]`. fn force_vested_transfer(l: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `554 + l * (25 ±0) + s * (36 ±0)` // Estimated: `6196` - // Minimum execution time: 63_303_000 picoseconds. - Weight::from_parts(65_180_847, 0) + // Minimum execution time: 70_529_000 picoseconds. + Weight::from_parts(70_619_962, 0) .saturating_add(Weight::from_parts(0, 6196)) - // Standard Error: 2_220 - .saturating_add(Weight::from_parts(28_829, 0).saturating_mul(l.into())) - // Standard Error: 3_951 - .saturating_add(Weight::from_parts(84_970, 0).saturating_mul(s.into())) + // Standard Error: 1_259 + .saturating_add(Weight::from_parts(50_685, 0).saturating_mul(l.into())) + // Standard Error: 2_241 + .saturating_add(Weight::from_parts(91_444, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -195,70 +192,59 @@ impl pallet_vesting::WeightInfo for WeightInfo { /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `l` is `[0, 49]`. /// The range of component `s` is `[2, 28]`. - fn not_unlocking_merge_schedules(l: u32, s: u32, ) -> Weight { + fn force_remove_vesting_schedule(l: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `378 + l * (25 ±0) + s * (36 ±0)` + // Measured: `555 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 31_440_000 picoseconds. - Weight::from_parts(30_773_053, 0) - .saturating_add(Weight::from_parts(0, 4764)) - // Standard Error: 1_474 - .saturating_add(Weight::from_parts(43_019, 0).saturating_mul(l.into())) - // Standard Error: 2_723 - .saturating_add(Weight::from_parts(73_360, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(3)) + // Minimum execution time: 41_497_000 picoseconds. + Weight::from_parts(38_763_834, 4764) + // Standard Error: 2_030 + .saturating_add(Weight::from_parts(99_580, 0).saturating_mul(l.into())) + // Standard Error: 3_750 + .saturating_add(Weight::from_parts(132_188, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Vesting::Vesting` (r:1 w:1) - /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// The range of component `l` is `[0, 49]`. - /// The range of component `s` is `[2, 28]`. - fn unlocking_merge_schedules(l: u32, s: u32, ) -> Weight { + fn not_unlocking_merge_schedules(l: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `378 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 34_221_000 picoseconds. - Weight::from_parts(33_201_125, 0) + // Minimum execution time: 36_428_000 picoseconds. + Weight::from_parts(35_604_430, 0) .saturating_add(Weight::from_parts(0, 4764)) - // Standard Error: 1_751 - .saturating_add(Weight::from_parts(44_088, 0).saturating_mul(l.into())) - // Standard Error: 3_234 - .saturating_add(Weight::from_parts(86_228, 0).saturating_mul(s.into())) + // Standard Error: 504 + .saturating_add(Weight::from_parts(43_191, 0).saturating_mul(l.into())) + // Standard Error: 931 + .saturating_add(Weight::from_parts(66_795, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `Vesting::Vesting` (r:1 w:1) - /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `l` is `[0, 49]`. /// The range of component `s` is `[2, 28]`. - fn force_remove_vesting_schedule(l: u32, s: u32, ) -> Weight { + fn unlocking_merge_schedules(l: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `451 + l * (25 ±0) + s * (36 ±0)` + // Measured: `378 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 35_553_000 picoseconds. - Weight::from_parts(34_974_083, 0) + // Minimum execution time: 40_696_000 picoseconds. + Weight::from_parts(39_741_284, 0) .saturating_add(Weight::from_parts(0, 4764)) - // Standard Error: 1_560 - .saturating_add(Weight::from_parts(34_615, 0).saturating_mul(l.into())) - // Standard Error: 2_882 - .saturating_add(Weight::from_parts(83_419, 0).saturating_mul(s.into())) + // Standard Error: 478 + .saturating_add(Weight::from_parts(43_792, 0).saturating_mul(l.into())) + // Standard Error: 883 + .saturating_add(Weight::from_parts(66_540, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) } diff --git a/polkadot/runtime/rococo/src/weights/pallet_whitelist.rs b/polkadot/runtime/rococo/src/weights/pallet_whitelist.rs index ec67268d144..7c307deec4c 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_whitelist.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_whitelist.rs @@ -16,28 +16,26 @@ //! Autogenerated weights for `pallet_whitelist` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-08-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-aahe6cbd-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// target/production/polkadot // benchmark // pallet -// --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=pallet_whitelist // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/ +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=pallet_whitelist +// --chain=rococo-dev +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -52,75 +50,67 @@ pub struct WeightInfo(PhantomData); impl pallet_whitelist::WeightInfo for WeightInfo { /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Storage: `Preimage::StatusFor` (r:1 w:1) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn whitelist_call() -> Weight { // Proof Size summary in bytes: // Measured: `223` // Estimated: `3556` - // Minimum execution time: 16_686_000 picoseconds. - Weight::from_parts(17_042_000, 0) + // Minimum execution time: 20_035_000 picoseconds. + Weight::from_parts(20_452_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Storage: `Preimage::StatusFor` (r:1 w:1) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) fn remove_whitelisted_call() -> Weight { // Proof Size summary in bytes: // Measured: `352` // Estimated: `3556` - // Minimum execution time: 18_250_000 picoseconds. - Weight::from_parts(19_026_000, 0) + // Minimum execution time: 20_247_000 picoseconds. + Weight::from_parts(20_808_000, 0) .saturating_add(Weight::from_parts(0, 3556)) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:1 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `Measured`) - /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Storage: `Preimage::StatusFor` (r:1 w:1) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 4194294]`. fn dispatch_whitelisted_call(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `428 + n * (1 ±0)` // Estimated: `3892 + n * (1 ±0)` - // Minimum execution time: 28_741_000 picoseconds. - Weight::from_parts(29_024_000, 0) + // Minimum execution time: 32_633_000 picoseconds. + Weight::from_parts(32_855_000, 0) .saturating_add(Weight::from_parts(0, 3892)) - // Standard Error: 7 - .saturating_add(Weight::from_parts(1_305, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(4)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_223, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Preimage::StatusFor` (r:1 w:0) + /// Storage: `Preimage::StatusFor` (r:1 w:1) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 10000]`. fn dispatch_whitelisted_call_with_preimage(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `352` // Estimated: `3556` - // Minimum execution time: 21_670_000 picoseconds. - Weight::from_parts(22_561_364, 0) + // Minimum execution time: 23_833_000 picoseconds. + Weight::from_parts(24_698_994, 0) .saturating_add(Weight::from_parts(0, 3556)) // Standard Error: 4 - .saturating_add(Weight::from_parts(1_468, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(Weight::from_parts(1_454, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_xcm.rs b/polkadot/runtime/rococo/src/weights/pallet_xcm.rs index d5cf33515e6..5544ca44658 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_xcm.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_xcm.rs @@ -17,25 +17,23 @@ //! Autogenerated weights for `pallet_xcm` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// target/production/polkadot // benchmark // pallet -// --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=pallet_xcm // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_xcm +// --chain=rococo-dev // --header=./polkadot/file_header.txt // --output=./polkadot/runtime/rococo/src/weights/ @@ -62,8 +60,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `180` // Estimated: `3645` - // Minimum execution time: 25_521_000 picoseconds. - Weight::from_parts(25_922_000, 0) + // Minimum execution time: 25_043_000 picoseconds. + Weight::from_parts(25_682_000, 0) .saturating_add(Weight::from_parts(0, 3645)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) @@ -82,8 +80,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `180` // Estimated: `3645` - // Minimum execution time: 112_185_000 picoseconds. - Weight::from_parts(115_991_000, 0) + // Minimum execution time: 107_570_000 picoseconds. + Weight::from_parts(109_878_000, 0) .saturating_add(Weight::from_parts(0, 3645)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) @@ -102,8 +100,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `232` // Estimated: `3697` - // Minimum execution time: 108_693_000 picoseconds. - Weight::from_parts(111_853_000, 0) + // Minimum execution time: 106_341_000 picoseconds. + Weight::from_parts(109_135_000, 0) .saturating_add(Weight::from_parts(0, 3697)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) @@ -122,8 +120,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `180` // Estimated: `3645` - // Minimum execution time: 113_040_000 picoseconds. - Weight::from_parts(115_635_000, 0) + // Minimum execution time: 108_372_000 picoseconds. + Weight::from_parts(112_890_000, 0) .saturating_add(Weight::from_parts(0, 3645)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) @@ -132,8 +130,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_979_000 picoseconds. - Weight::from_parts(7_342_000, 0) + // Minimum execution time: 6_957_000 picoseconds. + Weight::from_parts(7_417_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// Storage: `XcmPallet::SupportedVersion` (r:0 w:1) @@ -142,8 +140,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_144_000 picoseconds. - Weight::from_parts(7_297_000, 0) + // Minimum execution time: 7_053_000 picoseconds. + Weight::from_parts(7_462_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -151,8 +149,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_886_000 picoseconds. - Weight::from_parts(1_995_000, 0) + // Minimum execution time: 1_918_000 picoseconds. + Weight::from_parts(2_037_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// Storage: `XcmPallet::VersionNotifiers` (r:1 w:1) @@ -173,8 +171,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `180` // Estimated: `3645` - // Minimum execution time: 31_238_000 picoseconds. - Weight::from_parts(31_955_000, 0) + // Minimum execution time: 30_417_000 picoseconds. + Weight::from_parts(31_191_000, 0) .saturating_add(Weight::from_parts(0, 3645)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(5)) @@ -195,8 +193,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `360` // Estimated: `3825` - // Minimum execution time: 37_237_000 picoseconds. - Weight::from_parts(38_569_000, 0) + // Minimum execution time: 36_666_000 picoseconds. + Weight::from_parts(37_779_000, 0) .saturating_add(Weight::from_parts(0, 3825)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) @@ -207,8 +205,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_884_000 picoseconds. - Weight::from_parts(2_028_000, 0) + // Minimum execution time: 1_869_000 picoseconds. + Weight::from_parts(2_003_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -218,8 +216,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `22` // Estimated: `13387` - // Minimum execution time: 16_048_000 picoseconds. - Weight::from_parts(16_617_000, 0) + // Minimum execution time: 16_188_000 picoseconds. + Weight::from_parts(16_435_000, 0) .saturating_add(Weight::from_parts(0, 13387)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -230,8 +228,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `26` // Estimated: `13391` - // Minimum execution time: 16_073_000 picoseconds. - Weight::from_parts(16_672_000, 0) + // Minimum execution time: 16_431_000 picoseconds. + Weight::from_parts(16_935_000, 0) .saturating_add(Weight::from_parts(0, 13391)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -242,8 +240,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `40` // Estimated: `15880` - // Minimum execution time: 18_422_000 picoseconds. - Weight::from_parts(18_900_000, 0) + // Minimum execution time: 18_460_000 picoseconds. + Weight::from_parts(18_885_000, 0) .saturating_add(Weight::from_parts(0, 15880)) .saturating_add(T::DbWeight::get().reads(6)) } @@ -261,8 +259,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `216` // Estimated: `6156` - // Minimum execution time: 30_373_000 picoseconds. - Weight::from_parts(30_972_000, 0) + // Minimum execution time: 29_623_000 picoseconds. + Weight::from_parts(30_661_000, 0) .saturating_add(Weight::from_parts(0, 6156)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) @@ -273,8 +271,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `69` // Estimated: `10959` - // Minimum execution time: 11_863_000 picoseconds. - Weight::from_parts(12_270_000, 0) + // Minimum execution time: 12_043_000 picoseconds. + Weight::from_parts(12_360_000, 0) .saturating_add(Weight::from_parts(0, 10959)) .saturating_add(T::DbWeight::get().reads(4)) } @@ -284,8 +282,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `33` // Estimated: `13398` - // Minimum execution time: 16_733_000 picoseconds. - Weight::from_parts(17_094_000, 0) + // Minimum execution time: 16_511_000 picoseconds. + Weight::from_parts(17_011_000, 0) .saturating_add(Weight::from_parts(0, 13398)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -304,8 +302,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `216` // Estimated: `13581` - // Minimum execution time: 39_236_000 picoseconds. - Weight::from_parts(40_587_000, 0) + // Minimum execution time: 39_041_000 picoseconds. + Weight::from_parts(39_883_000, 0) .saturating_add(Weight::from_parts(0, 13581)) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) @@ -318,8 +316,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `1485` - // Minimum execution time: 2_145_000 picoseconds. - Weight::from_parts(2_255_000, 0) + // Minimum execution time: 2_030_000 picoseconds. + Weight::from_parts(2_150_000, 0) .saturating_add(Weight::from_parts(0, 1485)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -330,8 +328,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7576` // Estimated: `11041` - // Minimum execution time: 22_518_000 picoseconds. - Weight::from_parts(22_926_000, 0) + // Minimum execution time: 22_615_000 picoseconds. + Weight::from_parts(23_008_000, 0) .saturating_add(Weight::from_parts(0, 11041)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_fungible.rs b/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_fungible.rs deleted file mode 100644 index dc5e5d8ca4b..00000000000 --- a/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_fungible.rs +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Polkadot. - -// Polkadot is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Polkadot is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Polkadot. If not, see . - -//! Autogenerated weights for `pallet_xcm_benchmarks::fungible` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/production/polkadot -// benchmark -// pallet -// --chain=rococo-dev -// --steps=50 -// --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=pallet_xcm_benchmarks::fungible -// --extrinsic=* -// --execution=wasm -// --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_fungible.rs - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `pallet_xcm_benchmarks::fungible`. -pub struct WeightInfo(PhantomData); -impl pallet_xcm_benchmarks::fungible::WeightInfo for WeightInfo { - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn withdraw_asset() -> Weight { - // Proof Size summary in bytes: - // Measured: `101` - // Estimated: `3593` - // Minimum execution time: 27_223_000 picoseconds. - Weight::from_parts(27_947_000, 0) - .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) - } - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn transfer_asset() -> Weight { - // Proof Size summary in bytes: - // Measured: `101` - // Estimated: `6196` - // Minimum execution time: 36_502_000 picoseconds. - Weight::from_parts(37_023_000, 0) - .saturating_add(Weight::from_parts(0, 6196)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) - } - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) - /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) - /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn transfer_reserve_asset() -> Weight { - // Proof Size summary in bytes: - // Measured: `281` - // Estimated: `6196` - // Minimum execution time: 85_152_000 picoseconds. - Weight::from_parts(86_442_000, 0) - .saturating_add(Weight::from_parts(0, 6196)) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(4)) - } - /// Storage: `Benchmark::Override` (r:0 w:0) - /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn reserve_asset_deposited() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. - Weight::from_parts(18_446_744_073_709_551_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) - /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) - /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn initiate_reserve_withdraw() -> Weight { - // Proof Size summary in bytes: - // Measured: `281` - // Estimated: `3746` - // Minimum execution time: 56_571_000 picoseconds. - Weight::from_parts(58_163_000, 0) - .saturating_add(Weight::from_parts(0, 3746)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(3)) - } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn receive_teleported_asset() -> Weight { - // Proof Size summary in bytes: - // Measured: `103` - // Estimated: `3593` - // Minimum execution time: 27_411_000 picoseconds. - Weight::from_parts(27_953_000, 0) - .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) - } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn deposit_asset() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `3593` - // Minimum execution time: 20_776_000 picoseconds. - Weight::from_parts(21_145_000, 0) - .saturating_add(Weight::from_parts(0, 3593)) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) - } - /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) - /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) - /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn deposit_reserve_asset() -> Weight { - // Proof Size summary in bytes: - // Measured: `180` - // Estimated: `3645` - // Minimum execution time: 51_738_000 picoseconds. - Weight::from_parts(53_251_000, 0) - .saturating_add(Weight::from_parts(0, 3645)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(3)) - } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) - /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) - /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn initiate_teleport() -> Weight { - // Proof Size summary in bytes: - // Measured: `180` - // Estimated: `3645` - // Minimum execution time: 39_333_000 picoseconds. - Weight::from_parts(40_515_000, 0) - .saturating_add(Weight::from_parts(0, 3645)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(3)) - } -} diff --git a/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_generic.rs b/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_generic.rs deleted file mode 100644 index b62f36172ba..00000000000 --- a/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_generic.rs +++ /dev/null @@ -1,347 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Polkadot. - -// Polkadot is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Polkadot is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Polkadot. If not, see . - -//! Autogenerated weights for `pallet_xcm_benchmarks::generic` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/production/polkadot -// benchmark -// pallet -// --chain=rococo-dev -// --steps=50 -// --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=pallet_xcm_benchmarks::generic -// --extrinsic=* -// --execution=wasm -// --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_generic.rs - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `pallet_xcm_benchmarks::generic`. -pub struct WeightInfo(PhantomData); -impl pallet_xcm_benchmarks::generic::WeightInfo for WeightInfo { - /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) - /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) - /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn report_holding() -> Weight { - // Proof Size summary in bytes: - // Measured: `281` - // Estimated: `3746` - // Minimum execution time: 55_210_000 picoseconds. - Weight::from_parts(56_613_000, 0) - .saturating_add(Weight::from_parts(0, 3746)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(3)) - } - fn buy_execution() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_246_000 picoseconds. - Weight::from_parts(1_339_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `XcmPallet::Queries` (r:1 w:0) - /// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn query_response() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `3465` - // Minimum execution time: 5_377_000 picoseconds. - Weight::from_parts(5_549_000, 0) - .saturating_add(Weight::from_parts(0, 3465)) - .saturating_add(T::DbWeight::get().reads(1)) - } - fn transact() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 7_008_000 picoseconds. - Weight::from_parts(7_361_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn refund_surplus() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_700_000 picoseconds. - Weight::from_parts(1_848_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn set_error_handler() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_198_000 picoseconds. - Weight::from_parts(1_265_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn set_appendix() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_197_000 picoseconds. - Weight::from_parts(1_267_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn clear_error() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_193_000 picoseconds. - Weight::from_parts(1_258_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn descend_origin() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_268_000 picoseconds. - Weight::from_parts(1_342_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn clear_origin() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_173_000 picoseconds. - Weight::from_parts(1_248_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) - /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) - /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn report_error() -> Weight { - // Proof Size summary in bytes: - // Measured: `281` - // Estimated: `3746` - // Minimum execution time: 53_715_000 picoseconds. - Weight::from_parts(54_860_000, 0) - .saturating_add(Weight::from_parts(0, 3746)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(3)) - } - /// Storage: `XcmPallet::AssetTraps` (r:1 w:1) - /// Proof: `XcmPallet::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn claim_asset() -> Weight { - // Proof Size summary in bytes: - // Measured: `23` - // Estimated: `3488` - // Minimum execution time: 8_621_000 picoseconds. - Weight::from_parts(8_903_000, 0) - .saturating_add(Weight::from_parts(0, 3488)) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) - } - fn trap() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_211_000 picoseconds. - Weight::from_parts(1_281_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `XcmPallet::VersionNotifyTargets` (r:1 w:1) - /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) - /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) - /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn subscribe_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `180` - // Estimated: `3645` - // Minimum execution time: 26_448_000 picoseconds. - Weight::from_parts(27_057_000, 0) - .saturating_add(Weight::from_parts(0, 3645)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(3)) - } - /// Storage: `XcmPallet::VersionNotifyTargets` (r:0 w:1) - /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn unsubscribe_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 3_498_000 picoseconds. - Weight::from_parts(3_614_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(T::DbWeight::get().writes(1)) - } - fn burn_asset() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_575_000 picoseconds. - Weight::from_parts(1_698_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn expect_asset() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_334_000 picoseconds. - Weight::from_parts(1_435_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn expect_origin() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_244_000 picoseconds. - Weight::from_parts(1_337_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn expect_error() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_244_000 picoseconds. - Weight::from_parts(1_331_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn expect_transact_status() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_407_000 picoseconds. - Weight::from_parts(1_522_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) - /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) - /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn query_pallet() -> Weight { - // Proof Size summary in bytes: - // Measured: `281` - // Estimated: `3746` - // Minimum execution time: 62_963_000 picoseconds. - Weight::from_parts(64_556_000, 0) - .saturating_add(Weight::from_parts(0, 3746)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(3)) - } - fn expect_pallet() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 8_458_000 picoseconds. - Weight::from_parts(8_741_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) - /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) - /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn report_transact_status() -> Weight { - // Proof Size summary in bytes: - // Measured: `281` - // Estimated: `3746` - // Minimum execution time: 54_068_000 picoseconds. - Weight::from_parts(55_665_000, 0) - .saturating_add(Weight::from_parts(0, 3746)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(3)) - } - fn clear_transact_status() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_290_000 picoseconds. - Weight::from_parts(1_348_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn set_topic() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_189_000 picoseconds. - Weight::from_parts(1_268_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn clear_topic() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_197_000 picoseconds. - Weight::from_parts(1_276_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn set_fees_mode() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_197_000 picoseconds. - Weight::from_parts(1_253_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn unpaid_execution() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 1_250_000 picoseconds. - Weight::from_parts(1_354_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } -} diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_assigned_slots.rs b/polkadot/runtime/rococo/src/weights/runtime_common_assigned_slots.rs index f41a5d4ebf8..a6beeded428 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_common_assigned_slots.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_common_assigned_slots.rs @@ -16,28 +16,26 @@ //! Autogenerated weights for `runtime_common::assigned_slots` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-08-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `runner-ynta1nyy-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: ``, WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// target/production/polkadot // benchmark // pallet -// --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=runtime_common::assigned_slots // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/runtime_common_assigned_slots.rs +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=runtime_common::assigned_slots +// --chain=rococo-dev +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,7 +48,7 @@ use core::marker::PhantomData; /// Weight functions for `runtime_common::assigned_slots`. pub struct WeightInfo(PhantomData); impl runtime_common::assigned_slots::WeightInfo for WeightInfo { - /// Storage: `Registrar::Paras` (r:1 w:0) + /// Storage: `Registrar::Paras` (r:1 w:1) /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Paras::ParaLifecycles` (r:1 w:1) /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -70,15 +68,15 @@ impl runtime_common::assigned_slots::WeightInfo for Wei /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) fn assign_perm_parachain_slot() -> Weight { // Proof Size summary in bytes: - // Measured: `730` - // Estimated: `4195` - // Minimum execution time: 71_337_000 picoseconds. - Weight::from_parts(80_807_000, 0) - .saturating_add(Weight::from_parts(0, 4195)) + // Measured: `673` + // Estimated: `4138` + // Minimum execution time: 84_646_000 picoseconds. + Weight::from_parts(91_791_000, 0) + .saturating_add(Weight::from_parts(0, 4138)) .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().writes(6)) } - /// Storage: `Registrar::Paras` (r:1 w:0) + /// Storage: `Registrar::Paras` (r:1 w:1) /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Paras::ParaLifecycles` (r:1 w:1) /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -100,13 +98,13 @@ impl runtime_common::assigned_slots::WeightInfo for Wei /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) fn assign_temp_parachain_slot() -> Weight { // Proof Size summary in bytes: - // Measured: `730` - // Estimated: `4195` - // Minimum execution time: 60_188_000 picoseconds. - Weight::from_parts(63_932_000, 0) - .saturating_add(Weight::from_parts(0, 4195)) + // Measured: `673` + // Estimated: `4138` + // Minimum execution time: 68_091_000 picoseconds. + Weight::from_parts(77_310_000, 0) + .saturating_add(Weight::from_parts(0, 4138)) .saturating_add(T::DbWeight::get().reads(10)) - .saturating_add(T::DbWeight::get().writes(6)) + .saturating_add(T::DbWeight::get().writes(7)) } /// Storage: `AssignedSlots::PermanentSlots` (r:1 w:0) /// Proof: `AssignedSlots::PermanentSlots` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) @@ -120,11 +118,11 @@ impl runtime_common::assigned_slots::WeightInfo for Wei /// Proof: `AssignedSlots::TemporarySlotCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn unassign_parachain_slot() -> Weight { // Proof Size summary in bytes: - // Measured: `856` - // Estimated: `4321` - // Minimum execution time: 35_764_000 picoseconds. - Weight::from_parts(38_355_000, 0) - .saturating_add(Weight::from_parts(0, 4321)) + // Measured: `823` + // Estimated: `4288` + // Minimum execution time: 38_081_000 picoseconds. + Weight::from_parts(40_987_000, 0) + .saturating_add(Weight::from_parts(0, 4288)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -134,8 +132,8 @@ impl runtime_common::assigned_slots::WeightInfo for Wei // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_634_000 picoseconds. - Weight::from_parts(4_852_000, 0) + // Minimum execution time: 7_182_000 picoseconds. + Weight::from_parts(7_437_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -145,8 +143,8 @@ impl runtime_common::assigned_slots::WeightInfo for Wei // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_563_000 picoseconds. - Weight::from_parts(4_829_000, 0) + // Minimum execution time: 7_153_000 picoseconds. + Weight::from_parts(7_456_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_auctions.rs b/polkadot/runtime/rococo/src/weights/runtime_common_auctions.rs index 2b756802289..3cd7c7a47e9 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_common_auctions.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_common_auctions.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_common::auctions` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=runtime_common::auctions // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/runtime_common_auctions.rs +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_common_auctions.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,90 +47,92 @@ use core::marker::PhantomData; /// Weight functions for `runtime_common::auctions`. pub struct WeightInfo(PhantomData); impl runtime_common::auctions::WeightInfo for WeightInfo { - /// Storage: `Auctions::AuctionInfo` (r:1 w:1) - /// Proof: `Auctions::AuctionInfo` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Auctions::AuctionCounter` (r:1 w:1) - /// Proof: `Auctions::AuctionCounter` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: Auctions AuctionInfo (r:1 w:1) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Auctions AuctionCounter (r:1 w:1) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) fn new_auction() -> Weight { // Proof Size summary in bytes: // Measured: `4` // Estimated: `1493` - // Minimum execution time: 7_307_000 picoseconds. - Weight::from_parts(7_680_000, 0) + // Minimum execution time: 12_805_000 picoseconds. + Weight::from_parts(13_153_000, 0) .saturating_add(Weight::from_parts(0, 1493)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Paras::ParaLifecycles` (r:1 w:0) - /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Auctions::AuctionCounter` (r:1 w:0) - /// Proof: `Auctions::AuctionCounter` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Auctions::AuctionInfo` (r:1 w:0) - /// Proof: `Auctions::AuctionInfo` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Slots::Leases` (r:1 w:0) - /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Auctions::Winning` (r:1 w:1) - /// Proof: `Auctions::Winning` (`max_values`: None, `max_size`: Some(1920), added: 4395, mode: `MaxEncodedLen`) - /// Storage: `Auctions::ReservedAmounts` (r:2 w:2) - /// Proof: `Auctions::ReservedAmounts` (`max_values`: None, `max_size`: Some(60), added: 2535, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions AuctionCounter (r:1 w:0) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Auctions AuctionInfo (r:1 w:0) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Slots Leases (r:1 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions Winning (r:1 w:1) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions ReservedAmounts (r:2 w:2) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn bid() -> Weight { // Proof Size summary in bytes: - // Measured: `761` + // Measured: `728` // Estimated: `6060` - // Minimum execution time: 75_448_000 picoseconds. - Weight::from_parts(78_716_000, 0) + // Minimum execution time: 77_380_000 picoseconds. + Weight::from_parts(80_503_000, 0) .saturating_add(Weight::from_parts(0, 6060)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: `Auctions::AuctionInfo` (r:1 w:1) - /// Proof: `Auctions::AuctionInfo` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Babe::NextRandomness` (r:1 w:0) - /// Proof: `Babe::NextRandomness` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `Babe::EpochStart` (r:1 w:0) - /// Proof: `Babe::EpochStart` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Auctions::AuctionCounter` (r:1 w:0) - /// Proof: `Auctions::AuctionCounter` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Auctions::Winning` (r:3600 w:3600) - /// Proof: `Auctions::Winning` (`max_values`: None, `max_size`: Some(1920), added: 4395, mode: `MaxEncodedLen`) - /// Storage: `Auctions::ReservedAmounts` (r:37 w:36) - /// Proof: `Auctions::ReservedAmounts` (`max_values`: None, `max_size`: Some(60), added: 2535, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:36 w:36) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Slots::Leases` (r:2 w:2) - /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ParaLifecycles` (r:1 w:1) - /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) - /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ActionsQueue` (r:1 w:1) - /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Auctions AuctionInfo (r:1 w:1) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe NextRandomness (r:1 w:0) + /// Proof: Babe NextRandomness (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: Babe EpochStart (r:1 w:0) + /// Proof: Babe EpochStart (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Auctions AuctionCounter (r:1 w:0) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Auctions Winning (r:3600 w:3600) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions ReservedAmounts (r:37 w:36) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:36 w:36) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Slots Leases (r:2 w:2) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) fn on_initialize() -> Weight { // Proof Size summary in bytes: - // Measured: `6947017` + // Measured: `6947789` // Estimated: `15822990` - // Minimum execution time: 7_120_207_000 picoseconds. - Weight::from_parts(7_273_496_000, 0) + // Minimum execution time: 6_311_055_000 picoseconds. + Weight::from_parts(6_409_142_000, 0) .saturating_add(Weight::from_parts(0, 15822990)) - .saturating_add(T::DbWeight::get().reads(3682)) - .saturating_add(T::DbWeight::get().writes(3677)) + .saturating_add(T::DbWeight::get().reads(3683)) + .saturating_add(T::DbWeight::get().writes(3678)) } - /// Storage: `Auctions::ReservedAmounts` (r:37 w:36) - /// Proof: `Auctions::ReservedAmounts` (`max_values`: None, `max_size`: Some(60), added: 2535, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:36 w:36) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Auctions::Winning` (r:3600 w:3600) - /// Proof: `Auctions::Winning` (`max_values`: None, `max_size`: Some(1920), added: 4395, mode: `MaxEncodedLen`) - /// Storage: `Auctions::AuctionInfo` (r:0 w:1) - /// Proof: `Auctions::AuctionInfo` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: Auctions ReservedAmounts (r:37 w:36) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:36 w:36) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Auctions Winning (r:3600 w:3600) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions AuctionInfo (r:0 w:1) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) fn cancel_auction() -> Weight { // Proof Size summary in bytes: // Measured: `177732` // Estimated: `15822990` - // Minimum execution time: 5_536_281_000 picoseconds. - Weight::from_parts(5_675_163_000, 0) + // Minimum execution time: 4_849_561_000 picoseconds. + Weight::from_parts(4_955_226_000, 0) .saturating_add(Weight::from_parts(0, 15822990)) .saturating_add(T::DbWeight::get().reads(3673)) .saturating_add(T::DbWeight::get().writes(3673)) diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_claims.rs b/polkadot/runtime/rococo/src/weights/runtime_common_claims.rs index de2bb71933b..52e0dd24afa 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_common_claims.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_common_claims.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_common::claims` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=runtime_common::claims // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/runtime_common_claims.rs +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_common_claims.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,133 +47,120 @@ use core::marker::PhantomData; /// Weight functions for `runtime_common::claims`. pub struct WeightInfo(PhantomData); impl runtime_common::claims::WeightInfo for WeightInfo { - /// Storage: `Claims::Claims` (r:1 w:1) - /// Proof: `Claims::Claims` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Claims::Signing` (r:1 w:1) - /// Proof: `Claims::Signing` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Claims::Total` (r:1 w:1) - /// Proof: `Claims::Total` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Claims::Vesting` (r:1 w:1) - /// Proof: `Claims::Vesting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Vesting::Vesting` (r:1 w:1) - /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:0) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: Claims Claims (r:1 w:1) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:1 w:1) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Total (r:1 w:1) + /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:1 w:1) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) fn claim() -> Weight { // Proof Size summary in bytes: // Measured: `558` // Estimated: `4764` - // Minimum execution time: 181_028_000 picoseconds. - Weight::from_parts(194_590_000, 0) + // Minimum execution time: 144_931_000 picoseconds. + Weight::from_parts(156_550_000, 0) .saturating_add(Weight::from_parts(0, 4764)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(6)) } - /// Storage: `Claims::Total` (r:1 w:1) - /// Proof: `Claims::Total` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Claims::Vesting` (r:0 w:1) - /// Proof: `Claims::Vesting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Claims::Claims` (r:0 w:1) - /// Proof: `Claims::Claims` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Claims::Signing` (r:0 w:1) - /// Proof: `Claims::Signing` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Claims Total (r:1 w:1) + /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:0 w:1) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Claims (r:0 w:1) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:0 w:1) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) fn mint_claim() -> Weight { // Proof Size summary in bytes: // Measured: `216` // Estimated: `1701` - // Minimum execution time: 11_224_000 picoseconds. - Weight::from_parts(13_342_000, 0) + // Minimum execution time: 11_300_000 picoseconds. + Weight::from_parts(11_642_000, 0) .saturating_add(Weight::from_parts(0, 1701)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: `Claims::Claims` (r:1 w:1) - /// Proof: `Claims::Claims` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Claims::Signing` (r:1 w:1) - /// Proof: `Claims::Signing` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Claims::Total` (r:1 w:1) - /// Proof: `Claims::Total` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Claims::Vesting` (r:1 w:1) - /// Proof: `Claims::Vesting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Vesting::Vesting` (r:1 w:1) - /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:0) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: Claims Claims (r:1 w:1) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:1 w:1) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Total (r:1 w:1) + /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:1 w:1) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) fn claim_attest() -> Weight { // Proof Size summary in bytes: // Measured: `558` // Estimated: `4764` - // Minimum execution time: 187_964_000 picoseconds. - Weight::from_parts(202_553_000, 0) + // Minimum execution time: 149_112_000 picoseconds. + Weight::from_parts(153_872_000, 0) .saturating_add(Weight::from_parts(0, 4764)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(6)) } - /// Storage: `Claims::Preclaims` (r:1 w:1) - /// Proof: `Claims::Preclaims` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Claims::Signing` (r:1 w:1) - /// Proof: `Claims::Signing` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Claims::Claims` (r:1 w:1) - /// Proof: `Claims::Claims` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Claims::Total` (r:1 w:1) - /// Proof: `Claims::Total` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Claims::Vesting` (r:1 w:1) - /// Proof: `Claims::Vesting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Vesting::Vesting` (r:1 w:1) - /// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:0) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: Claims Preclaims (r:1 w:1) + /// Proof Skipped: Claims Preclaims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:1 w:1) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Claims (r:1 w:1) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Total (r:1 w:1) + /// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:1 w:1) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Vesting Vesting (r:1 w:1) + /// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) fn attest() -> Weight { // Proof Size summary in bytes: // Measured: `632` // Estimated: `4764` - // Minimum execution time: 78_210_000 picoseconds. - Weight::from_parts(84_581_000, 0) + // Minimum execution time: 69_619_000 picoseconds. + Weight::from_parts(79_242_000, 0) .saturating_add(Weight::from_parts(0, 4764)) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(7)) } - /// Storage: `Claims::Claims` (r:1 w:2) - /// Proof: `Claims::Claims` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Claims::Vesting` (r:1 w:2) - /// Proof: `Claims::Vesting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Claims::Signing` (r:1 w:2) - /// Proof: `Claims::Signing` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Claims::Preclaims` (r:1 w:1) - /// Proof: `Claims::Preclaims` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Claims Claims (r:1 w:2) + /// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Vesting (r:1 w:2) + /// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Signing (r:1 w:2) + /// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured) + /// Storage: Claims Preclaims (r:1 w:1) + /// Proof Skipped: Claims Preclaims (max_values: None, max_size: None, mode: Measured) fn move_claim() -> Weight { // Proof Size summary in bytes: // Measured: `440` // Estimated: `3905` - // Minimum execution time: 33_940_000 picoseconds. - Weight::from_parts(48_438_000, 0) + // Minimum execution time: 22_066_000 picoseconds. + Weight::from_parts(22_483_000, 0) .saturating_add(Weight::from_parts(0, 3905)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(7)) } - /// Storage: `Claims::Preclaims` (r:1 w:0) - /// Proof: `Claims::Preclaims` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Claims::Signing` (r:1 w:0) - /// Proof: `Claims::Signing` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn prevalidate_attests() -> Weight { - // Proof Size summary in bytes: - // Measured: `296` - // Estimated: `3761` - // Minimum execution time: 9_025_000 picoseconds. - Weight::from_parts(10_563_000, 0) - .saturating_add(Weight::from_parts(0, 3761)) - .saturating_add(T::DbWeight::get().reads(2)) - } } diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_coretime.rs b/polkadot/runtime/rococo/src/weights/runtime_common_coretime.rs deleted file mode 100644 index d068f07e759..00000000000 --- a/polkadot/runtime/rococo/src/weights/runtime_common_coretime.rs +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Polkadot. - -// Polkadot is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Polkadot is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Polkadot. If not, see . - -//! Autogenerated weights for `runtime_common::coretime` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/production/polkadot -// benchmark -// pallet -// --chain=rococo-dev -// --steps=50 -// --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=runtime_common::coretime -// --extrinsic=* -// --execution=wasm -// --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/runtime_common_coretime.rs - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `runtime_common::coretime`. -pub struct WeightInfo(PhantomData); -impl runtime_common::coretime::WeightInfo for WeightInfo { - /// Storage: `Configuration::PendingConfigs` (r:1 w:1) - /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) - /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) - /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - fn request_core_count() -> Weight { - // Proof Size summary in bytes: - // Measured: `151` - // Estimated: `1636` - // Minimum execution time: 7_543_000 picoseconds. - Weight::from_parts(7_745_000, 0) - .saturating_add(Weight::from_parts(0, 1636)) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(1)) - } - /// Storage: `CoretimeAssignmentProvider::CoreDescriptors` (r:1 w:1) - /// Proof: `CoretimeAssignmentProvider::CoreDescriptors` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `CoretimeAssignmentProvider::CoreSchedules` (r:0 w:1) - /// Proof: `CoretimeAssignmentProvider::CoreSchedules` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `s` is `[1, 100]`. - fn assign_core(s: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `180` - // Estimated: `3645` - // Minimum execution time: 9_367_000 picoseconds. - Weight::from_parts(9_932_305, 0) - .saturating_add(Weight::from_parts(0, 3645)) - // Standard Error: 231 - .saturating_add(Weight::from_parts(12_947, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(2)) - } -} diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_crowdloan.rs b/polkadot/runtime/rococo/src/weights/runtime_common_crowdloan.rs index 8ebab3d551e..0e7420cba2e 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_common_crowdloan.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_common_crowdloan.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_common::crowdloan` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=runtime_common::crowdloan // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/runtime_common_crowdloan.rs +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_common_crowdloan.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,168 +47,172 @@ use core::marker::PhantomData; /// Weight functions for `runtime_common::crowdloan`. pub struct WeightInfo(PhantomData); impl runtime_common::crowdloan::WeightInfo for WeightInfo { - /// Storage: `Crowdloan::Funds` (r:1 w:1) - /// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Registrar::Paras` (r:1 w:0) - /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ParaLifecycles` (r:1 w:0) - /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Crowdloan::NextFundIndex` (r:1 w:1) - /// Proof: `Crowdloan::NextFundIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Crowdloan NextFundIndex (r:1 w:1) + /// Proof Skipped: Crowdloan NextFundIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn create() -> Weight { // Proof Size summary in bytes: // Measured: `438` // Estimated: `3903` - // Minimum execution time: 46_095_000 picoseconds. - Weight::from_parts(48_111_000, 0) + // Minimum execution time: 50_399_000 picoseconds. + Weight::from_parts(51_641_000, 0) .saturating_add(Weight::from_parts(0, 3903)) .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: `Crowdloan::Funds` (r:1 w:1) - /// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Slots::Leases` (r:1 w:0) - /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Auctions::AuctionInfo` (r:1 w:0) - /// Proof: `Auctions::AuctionInfo` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Crowdloan::EndingsCount` (r:1 w:0) - /// Proof: `Crowdloan::EndingsCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Crowdloan::NewRaise` (r:1 w:1) - /// Proof: `Crowdloan::NewRaise` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: UNKNOWN KEY `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) - /// Proof: UNKNOWN KEY `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Slots Leases (r:1 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions AuctionInfo (r:1 w:0) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:1) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Crowdloan EndingsCount (r:1 w:0) + /// Proof Skipped: Crowdloan EndingsCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Crowdloan NewRaise (r:1 w:1) + /// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + /// Proof Skipped: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) fn contribute() -> Weight { // Proof Size summary in bytes: - // Measured: `563` - // Estimated: `4028` - // Minimum execution time: 133_059_000 picoseconds. - Weight::from_parts(136_515_000, 0) - .saturating_add(Weight::from_parts(0, 4028)) - .saturating_add(T::DbWeight::get().reads(7)) - .saturating_add(T::DbWeight::get().writes(4)) + // Measured: `530` + // Estimated: `3995` + // Minimum execution time: 128_898_000 picoseconds. + Weight::from_parts(130_277_000, 0) + .saturating_add(Weight::from_parts(0, 3995)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(5)) } - /// Storage: `Crowdloan::Funds` (r:1 w:1) - /// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: UNKNOWN KEY `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1) - /// Proof: UNKNOWN KEY `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1) + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances InactiveIssuance (r:1 w:1) + /// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: unknown `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1) + /// Proof Skipped: unknown `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1) fn withdraw() -> Weight { // Proof Size summary in bytes: - // Measured: `687` + // Measured: `689` // Estimated: `6196` - // Minimum execution time: 71_733_000 picoseconds. - Weight::from_parts(74_034_000, 0) + // Minimum execution time: 69_543_000 picoseconds. + Weight::from_parts(71_522_000, 0) .saturating_add(Weight::from_parts(0, 6196)) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(5)) } - /// Storage: `Skipped::Metadata` (r:0 w:0) - /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) /// The range of component `k` is `[0, 1000]`. fn refund(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `125 + k * (189 ±0)` - // Estimated: `138 + k * (189 ±0)` - // Minimum execution time: 46_016_000 picoseconds. - Weight::from_parts(48_260_000, 0) - .saturating_add(Weight::from_parts(0, 138)) - // Standard Error: 21_140 - .saturating_add(Weight::from_parts(39_141_925, 0).saturating_mul(k.into())) - .saturating_add(T::DbWeight::get().reads(3)) + // Measured: `127 + k * (189 ±0)` + // Estimated: `140 + k * (189 ±0)` + // Minimum execution time: 50_735_000 picoseconds. + Weight::from_parts(52_282_000, 0) + .saturating_add(Weight::from_parts(0, 140)) + // Standard Error: 21_607 + .saturating_add(Weight::from_parts(38_955_985, 0).saturating_mul(k.into())) + .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(k.into()))) - .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(k.into()))) .saturating_add(Weight::from_parts(0, 189).saturating_mul(k.into())) } - /// Storage: `Crowdloan::Funds` (r:1 w:1) - /// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn dissolve() -> Weight { // Proof Size summary in bytes: - // Measured: `514` + // Measured: `515` // Estimated: `6196` - // Minimum execution time: 44_724_000 picoseconds. - Weight::from_parts(47_931_000, 0) + // Minimum execution time: 43_100_000 picoseconds. + Weight::from_parts(44_272_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `Crowdloan::Funds` (r:1 w:1) - /// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Crowdloan Funds (r:1 w:1) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) fn edit() -> Weight { // Proof Size summary in bytes: - // Measured: `234` - // Estimated: `3699` - // Minimum execution time: 19_512_000 picoseconds. - Weight::from_parts(21_129_000, 0) - .saturating_add(Weight::from_parts(0, 3699)) + // Measured: `235` + // Estimated: `3700` + // Minimum execution time: 18_702_000 picoseconds. + Weight::from_parts(19_408_000, 0) + .saturating_add(Weight::from_parts(0, 3700)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Crowdloan::Funds` (r:1 w:0) - /// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: UNKNOWN KEY `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) - /// Proof: UNKNOWN KEY `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + /// Storage: Crowdloan Funds (r:1 w:0) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) + /// Proof Skipped: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1) fn add_memo() -> Weight { // Proof Size summary in bytes: // Measured: `412` // Estimated: `3877` - // Minimum execution time: 33_529_000 picoseconds. - Weight::from_parts(37_082_000, 0) + // Minimum execution time: 25_568_000 picoseconds. + Weight::from_parts(26_203_000, 0) .saturating_add(Weight::from_parts(0, 3877)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Crowdloan::Funds` (r:1 w:0) - /// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Crowdloan::NewRaise` (r:1 w:1) - /// Proof: `Crowdloan::NewRaise` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Crowdloan Funds (r:1 w:0) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Crowdloan NewRaise (r:1 w:1) + /// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured) fn poke() -> Weight { // Proof Size summary in bytes: - // Measured: `238` - // Estimated: `3703` - // Minimum execution time: 23_153_000 picoseconds. - Weight::from_parts(24_181_000, 0) - .saturating_add(Weight::from_parts(0, 3703)) + // Measured: `239` + // Estimated: `3704` + // Minimum execution time: 17_832_000 picoseconds. + Weight::from_parts(18_769_000, 0) + .saturating_add(Weight::from_parts(0, 3704)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Auctions::AuctionInfo` (r:1 w:0) - /// Proof: `Auctions::AuctionInfo` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Crowdloan::EndingsCount` (r:1 w:1) - /// Proof: `Crowdloan::EndingsCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Crowdloan::NewRaise` (r:1 w:1) - /// Proof: `Crowdloan::NewRaise` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Crowdloan::Funds` (r:100 w:0) - /// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Auctions::AuctionCounter` (r:1 w:0) - /// Proof: `Auctions::AuctionCounter` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Paras::ParaLifecycles` (r:100 w:0) - /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Slots::Leases` (r:100 w:0) - /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Auctions::Winning` (r:1 w:1) - /// Proof: `Auctions::Winning` (`max_values`: None, `max_size`: Some(1920), added: 4395, mode: `MaxEncodedLen`) - /// Storage: `Auctions::ReservedAmounts` (r:100 w:100) - /// Proof: `Auctions::ReservedAmounts` (`max_values`: None, `max_size`: Some(60), added: 2535, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:100 w:100) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Auctions AuctionInfo (r:1 w:0) + /// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Crowdloan EndingsCount (r:1 w:1) + /// Proof Skipped: Crowdloan EndingsCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Crowdloan NewRaise (r:1 w:1) + /// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Crowdloan Funds (r:100 w:0) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions AuctionCounter (r:1 w:0) + /// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Paras ParaLifecycles (r:100 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Slots Leases (r:100 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Auctions Winning (r:1 w:1) + /// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen) + /// Storage: Auctions ReservedAmounts (r:100 w:100) + /// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen) + /// Storage: System Account (r:100 w:100) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `n` is `[2, 100]`. fn on_initialize(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `229 + n * (356 ±0)` + // Measured: `197 + n * (356 ±0)` // Estimated: `5385 + n * (2832 ±0)` - // Minimum execution time: 120_164_000 picoseconds. - Weight::from_parts(3_390_119, 0) + // Minimum execution time: 128_319_000 picoseconds. + Weight::from_parts(130_877_000, 0) .saturating_add(Weight::from_parts(0, 5385)) - // Standard Error: 41_727 - .saturating_add(Weight::from_parts(54_453_016, 0).saturating_mul(n.into())) + // Standard Error: 61_381 + .saturating_add(Weight::from_parts(60_209_202, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(3)) diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_identity_migrator.rs b/polkadot/runtime/rococo/src/weights/runtime_common_identity_migrator.rs index 9b0cb98e6c0..cec357453b6 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_common_identity_migrator.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_common_identity_migrator.rs @@ -1,43 +1,36 @@ // Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Polkadot. +// SPDX-License-Identifier: Apache-2.0 -// Polkadot is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Polkadot is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Polkadot. If not, see . +// 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. //! Autogenerated weights for `runtime_common::identity_migrator` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-11-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `sbtb`, CPU: `13th Gen Intel(R) Core(TM) i7-1365U` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// ./target/release/polkadot // benchmark // pallet // --chain=rococo-dev -// --steps=50 -// --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares +// --steps=2 +// --repeat=1 // --pallet=runtime_common::identity_migrator // --extrinsic=* -// --execution=wasm -// --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/runtime_common_identity_migrator.rs +// --output=./migrator-release.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -51,7 +44,7 @@ use core::marker::PhantomData; pub struct WeightInfo(PhantomData); impl runtime_common::identity_migrator::WeightInfo for WeightInfo { /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) /// Storage: `Identity::SubsOf` (r:1 w:1) /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:2 w:2) @@ -70,34 +63,34 @@ impl runtime_common::identity_migrator::WeightInfo for /// The range of component `s` is `[0, 100]`. fn reap_identity(r: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `7457 + r * (5 ±0) + s * (32 ±0)` - // Estimated: `11037 + r * (7 ±0) + s * (32 ±0)` - // Minimum execution time: 157_343_000 picoseconds. - Weight::from_parts(159_289_236, 0) - .saturating_add(Weight::from_parts(0, 11037)) - // Standard Error: 16_439 - .saturating_add(Weight::from_parts(224_293, 0).saturating_mul(r.into())) - // Standard Error: 3_367 - .saturating_add(Weight::from_parts(1_383_637, 0).saturating_mul(s.into())) + // Measured: `7292 + r * (8 ±0) + s * (32 ±0)` + // Estimated: `11003 + r * (8 ±0) + s * (33 ±0)` + // Minimum execution time: 163_756_000 picoseconds. + Weight::from_parts(158_982_500, 0) + .saturating_add(Weight::from_parts(0, 11003)) + // Standard Error: 1_143_629 + .saturating_add(Weight::from_parts(238_675, 0).saturating_mul(r.into())) + // Standard Error: 228_725 + .saturating_add(Weight::from_parts(1_529_645, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(8)) - .saturating_add(T::DbWeight::get().writes(6)) + .saturating_add(T::DbWeight::get().writes(5)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) - .saturating_add(Weight::from_parts(0, 7).saturating_mul(r.into())) - .saturating_add(Weight::from_parts(0, 32).saturating_mul(s.into())) + .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(0, 33).saturating_mul(s.into())) } /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Identity::SubsOf` (r:1 w:1) /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) fn poke_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `7242` - // Estimated: `11037` - // Minimum execution time: 114_384_000 picoseconds. - Weight::from_parts(115_741_000, 0) - .saturating_add(Weight::from_parts(0, 11037)) + // Measured: `7229` + // Estimated: `11003` + // Minimum execution time: 137_570_000 picoseconds. + Weight::from_parts(137_570_000, 0) + .saturating_add(Weight::from_parts(0, 11003)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) } diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_paras_registrar.rs b/polkadot/runtime/rococo/src/weights/runtime_common_paras_registrar.rs index e066106e134..0a56562a1a9 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_common_paras_registrar.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_common_paras_registrar.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_common::paras_registrar` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=runtime_common::paras_registrar // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/runtime_common_paras_registrar.rs +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_common_paras_registrar.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,169 +47,175 @@ use core::marker::PhantomData; /// Weight functions for `runtime_common::paras_registrar`. pub struct WeightInfo(PhantomData); impl runtime_common::paras_registrar::WeightInfo for WeightInfo { - /// Storage: `Registrar::NextFreeParaId` (r:1 w:1) - /// Proof: `Registrar::NextFreeParaId` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Registrar::Paras` (r:1 w:1) - /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ParaLifecycles` (r:1 w:0) - /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Registrar NextFreeParaId (r:1 w:1) + /// Proof Skipped: Registrar NextFreeParaId (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) fn reserve() -> Weight { // Proof Size summary in bytes: - // Measured: `96` - // Estimated: `3561` - // Minimum execution time: 24_109_000 picoseconds. - Weight::from_parts(24_922_000, 0) - .saturating_add(Weight::from_parts(0, 3561)) + // Measured: `97` + // Estimated: `3562` + // Minimum execution time: 29_948_000 picoseconds. + Weight::from_parts(30_433_000, 0) + .saturating_add(Weight::from_parts(0, 3562)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Registrar::Paras` (r:1 w:1) - /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ParaLifecycles` (r:1 w:1) - /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) - /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::CodeByHash` (r:1 w:1) - /// Proof: `Paras::CodeByHash` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) - /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::PvfActiveVoteList` (r:1 w:1) - /// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::CodeByHashRefs` (r:1 w:1) - /// Proof: `Paras::CodeByHashRefs` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::CurrentCodeHash` (r:0 w:1) - /// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::UpcomingParasGenesis` (r:0 w:1) - /// Proof: `Paras::UpcomingParasGenesis` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:0 w:1) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpcomingParasGenesis (r:0 w:1) + /// Proof Skipped: Paras UpcomingParasGenesis (max_values: None, max_size: None, mode: Measured) fn register() -> Weight { // Proof Size summary in bytes: - // Measured: `352` - // Estimated: `3817` - // Minimum execution time: 7_207_580_000 picoseconds. - Weight::from_parts(7_298_567_000, 0) - .saturating_add(Weight::from_parts(0, 3817)) - .saturating_add(T::DbWeight::get().reads(7)) + // Measured: `616` + // Estimated: `4081` + // Minimum execution time: 6_332_113_000 picoseconds. + Weight::from_parts(6_407_158_000, 0) + .saturating_add(Weight::from_parts(0, 4081)) + .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(8)) } - /// Storage: `Registrar::Paras` (r:1 w:1) - /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ParaLifecycles` (r:1 w:1) - /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) - /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::CodeByHash` (r:1 w:1) - /// Proof: `Paras::CodeByHash` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) - /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::PvfActiveVoteList` (r:1 w:1) - /// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::CodeByHashRefs` (r:1 w:1) - /// Proof: `Paras::CodeByHashRefs` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::CurrentCodeHash` (r:0 w:1) - /// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::UpcomingParasGenesis` (r:0 w:1) - /// Proof: `Paras::UpcomingParasGenesis` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:0 w:1) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpcomingParasGenesis (r:0 w:1) + /// Proof Skipped: Paras UpcomingParasGenesis (max_values: None, max_size: None, mode: Measured) fn force_register() -> Weight { // Proof Size summary in bytes: - // Measured: `269` - // Estimated: `3734` - // Minimum execution time: 7_196_460_000 picoseconds. - Weight::from_parts(7_385_729_000, 0) - .saturating_add(Weight::from_parts(0, 3734)) - .saturating_add(T::DbWeight::get().reads(7)) + // Measured: `533` + // Estimated: `3998` + // Minimum execution time: 6_245_403_000 picoseconds. + Weight::from_parts(6_289_575_000, 0) + .saturating_add(Weight::from_parts(0, 3998)) + .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(8)) } - /// Storage: `Registrar::Paras` (r:1 w:1) - /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ParaLifecycles` (r:1 w:1) - /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::FutureCodeHash` (r:1 w:0) - /// Proof: `Paras::FutureCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) - /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ActionsQueue` (r:1 w:1) - /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `MessageQueue::BookStateFor` (r:1 w:0) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) - /// Storage: `Registrar::PendingSwap` (r:0 w:1) - /// Proof: `Registrar::PendingSwap` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras FutureCodeHash (r:1 w:0) + /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: MessageQueue BookStateFor (r:1 w:0) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: Registrar PendingSwap (r:0 w:1) + /// Proof Skipped: Registrar PendingSwap (max_values: None, max_size: None, mode: Measured) fn deregister() -> Weight { // Proof Size summary in bytes: - // Measured: `499` - // Estimated: `3964` - // Minimum execution time: 54_761_000 picoseconds. - Weight::from_parts(57_931_000, 0) - .saturating_add(Weight::from_parts(0, 3964)) + // Measured: `476` + // Estimated: `3941` + // Minimum execution time: 49_822_000 picoseconds. + Weight::from_parts(50_604_000, 0) + .saturating_add(Weight::from_parts(0, 3941)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: `Registrar::Paras` (r:1 w:0) - /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ParaLifecycles` (r:2 w:2) - /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Registrar::PendingSwap` (r:1 w:1) - /// Proof: `Registrar::PendingSwap` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) - /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ActionsQueue` (r:1 w:1) - /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Crowdloan::Funds` (r:2 w:2) - /// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Slots::Leases` (r:2 w:2) - /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Registrar Paras (r:1 w:0) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:2 w:2) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar PendingSwap (r:1 w:1) + /// Proof Skipped: Registrar PendingSwap (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Crowdloan Funds (r:2 w:2) + /// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured) + /// Storage: Slots Leases (r:2 w:2) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) fn swap() -> Weight { // Proof Size summary in bytes: - // Measured: `837` - // Estimated: `6777` - // Minimum execution time: 59_564_000 picoseconds. - Weight::from_parts(62_910_000, 0) - .saturating_add(Weight::from_parts(0, 6777)) + // Measured: `780` + // Estimated: `6720` + // Minimum execution time: 55_166_000 picoseconds. + Weight::from_parts(56_913_000, 0) + .saturating_add(Weight::from_parts(0, 6720)) .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(8)) } - /// Storage: `Paras::FutureCodeHash` (r:1 w:1) - /// Proof: `Paras::FutureCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::UpgradeRestrictionSignal` (r:1 w:1) - /// Proof: `Paras::UpgradeRestrictionSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::CurrentCodeHash` (r:1 w:0) - /// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::UpgradeCooldowns` (r:1 w:1) - /// Proof: `Paras::UpgradeCooldowns` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) - /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::CodeByHash` (r:1 w:1) - /// Proof: `Paras::CodeByHash` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) - /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::PvfActiveVoteList` (r:1 w:1) - /// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::CodeByHashRefs` (r:1 w:1) - /// Proof: `Paras::CodeByHashRefs` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `b` is `[9, 3145728]`. + /// Storage: Paras FutureCodeHash (r:1 w:1) + /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeRestrictionSignal (r:1 w:1) + /// Proof Skipped: Paras UpgradeRestrictionSignal (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:1 w:0) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeCooldowns (r:1 w:1) + /// Proof Skipped: Paras UpgradeCooldowns (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// The range of component `b` is `[1, 3145728]`. fn schedule_code_upgrade(b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `201` - // Estimated: `3666` - // Minimum execution time: 33_106_000 picoseconds. - Weight::from_parts(33_526_000, 0) - .saturating_add(Weight::from_parts(0, 3666)) - // Standard Error: 2 - .saturating_add(Weight::from_parts(2_334, 0).saturating_mul(b.into())) - .saturating_add(T::DbWeight::get().reads(9)) + // Measured: `464` + // Estimated: `3929` + // Minimum execution time: 43_650_000 picoseconds. + Weight::from_parts(43_918_000, 0) + .saturating_add(Weight::from_parts(0, 3929)) + // Standard Error: 6 + .saturating_add(Weight::from_parts(2_041, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(7)) } - /// Storage: `Paras::Heads` (r:0 w:1) - /// Proof: `Paras::Heads` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) /// The range of component `b` is `[1, 1048576]`. fn set_current_head(b: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_992_000 picoseconds. - Weight::from_parts(12_059_689, 0) + // Minimum execution time: 8_666_000 picoseconds. + Weight::from_parts(8_893_000, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 0 - .saturating_add(Weight::from_parts(959, 0).saturating_mul(b.into())) + // Standard Error: 2 + .saturating_add(Weight::from_parts(855, 0).saturating_mul(b.into())) .saturating_add(T::DbWeight::get().writes(1)) } } diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_slots.rs b/polkadot/runtime/rococo/src/weights/runtime_common_slots.rs index dd10dbbf1f1..23ab1ed3ee0 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_common_slots.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_common_slots.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_common::slots` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=runtime_common::slots // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/runtime_common_slots.rs +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_common_slots.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,82 +47,86 @@ use core::marker::PhantomData; /// Weight functions for `runtime_common::slots`. pub struct WeightInfo(PhantomData); impl runtime_common::slots::WeightInfo for WeightInfo { - /// Storage: `Slots::Leases` (r:1 w:1) - /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Slots Leases (r:1 w:1) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn force_lease() -> Weight { // Proof Size summary in bytes: - // Measured: `320` - // Estimated: `3785` - // Minimum execution time: 26_570_000 picoseconds. - Weight::from_parts(27_619_000, 0) - .saturating_add(Weight::from_parts(0, 3785)) + // Measured: `287` + // Estimated: `3752` + // Minimum execution time: 29_932_000 picoseconds. + Weight::from_parts(30_334_000, 0) + .saturating_add(Weight::from_parts(0, 3752)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Paras::Parachains` (r:1 w:0) - /// Proof: `Paras::Parachains` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Slots::Leases` (r:101 w:100) - /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ParaLifecycles` (r:200 w:200) - /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) - /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ActionsQueue` (r:1 w:1) - /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Paras Parachains (r:1 w:0) + /// Proof Skipped: Paras Parachains (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Slots Leases (r:101 w:100) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:200 w:200) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:100 w:100) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) /// The range of component `c` is `[0, 100]`. /// The range of component `t` is `[0, 100]`. fn manage_lease_period_start(c: u32, t: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `594 + c * (20 ±0) + t * (234 ±0)` - // Estimated: `4065 + c * (2496 ±0) + t * (2709 ±0)` - // Minimum execution time: 729_793_000 picoseconds. - Weight::from_parts(740_820_000, 0) - .saturating_add(Weight::from_parts(0, 4065)) - // Standard Error: 88_206 - .saturating_add(Weight::from_parts(2_793_142, 0).saturating_mul(c.into())) - // Standard Error: 88_206 - .saturating_add(Weight::from_parts(8_933_065, 0).saturating_mul(t.into())) + // Measured: `26 + c * (47 ±0) + t * (308 ±0)` + // Estimated: `2800 + c * (2526 ±0) + t * (2789 ±0)` + // Minimum execution time: 634_547_000 picoseconds. + Weight::from_parts(643_045_000, 0) + .saturating_add(Weight::from_parts(0, 2800)) + // Standard Error: 81_521 + .saturating_add(Weight::from_parts(2_705_219, 0).saturating_mul(c.into())) + // Standard Error: 81_521 + .saturating_add(Weight::from_parts(11_464_132, 0).saturating_mul(t.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) - .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(t.into()))) + .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) - .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(t.into()))) - .saturating_add(Weight::from_parts(0, 2496).saturating_mul(c.into())) - .saturating_add(Weight::from_parts(0, 2709).saturating_mul(t.into())) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(t.into()))) + .saturating_add(Weight::from_parts(0, 2526).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 2789).saturating_mul(t.into())) } - /// Storage: `Slots::Leases` (r:1 w:1) - /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:8 w:8) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Slots Leases (r:1 w:1) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: System Account (r:8 w:8) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn clear_all_leases() -> Weight { // Proof Size summary in bytes: - // Measured: `2792` + // Measured: `2759` // Estimated: `21814` - // Minimum execution time: 123_888_000 picoseconds. - Weight::from_parts(131_245_000, 0) + // Minimum execution time: 129_756_000 picoseconds. + Weight::from_parts(131_810_000, 0) .saturating_add(Weight::from_parts(0, 21814)) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(9)) } - /// Storage: `Slots::Leases` (r:1 w:0) - /// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ParaLifecycles` (r:1 w:1) - /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) - /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ActionsQueue` (r:1 w:1) - /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Slots Leases (r:1 w:0) + /// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:1) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) + /// Storage: Registrar Paras (r:1 w:1) + /// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured) fn trigger_onboard() -> Weight { // Proof Size summary in bytes: - // Measured: `612` - // Estimated: `4077` - // Minimum execution time: 27_341_000 picoseconds. - Weight::from_parts(28_697_000, 0) - .saturating_add(Weight::from_parts(0, 4077)) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `707` + // Estimated: `4172` + // Minimum execution time: 29_527_000 picoseconds. + Weight::from_parts(30_055_000, 0) + .saturating_add(Weight::from_parts(0, 4172)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) } } diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_assigner_on_demand.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_assigner_on_demand.rs index 653e1009f31..ac0f05301b4 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_parachains_assigner_on_demand.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_assigner_on_demand.rs @@ -16,28 +16,26 @@ //! Autogenerated weights for `runtime_parachains::assigner_on_demand` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-08-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-fljshgub-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// target/production/polkadot // benchmark // pallet -// --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=runtime_parachains::assigner_on_demand // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_assigner_on_demand.rs +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json +// --pallet=runtime_parachains::assigner_on_demand +// --chain=rococo-dev +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -59,13 +57,13 @@ impl runtime_parachains::assigner_on_demand::WeightInfo /// The range of component `s` is `[1, 9999]`. fn place_order_keep_alive(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `363 + s * (4 ±0)` - // Estimated: `3828 + s * (4 ±0)` - // Minimum execution time: 25_298_000 picoseconds. - Weight::from_parts(21_486_098, 0) - .saturating_add(Weight::from_parts(0, 3828)) - // Standard Error: 136 - .saturating_add(Weight::from_parts(13_943, 0).saturating_mul(s.into())) + // Measured: `297 + s * (4 ±0)` + // Estimated: `3762 + s * (4 ±0)` + // Minimum execution time: 33_522_000 picoseconds. + Weight::from_parts(35_436_835, 0) + .saturating_add(Weight::from_parts(0, 3762)) + // Standard Error: 129 + .saturating_add(Weight::from_parts(14_041, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) @@ -79,13 +77,13 @@ impl runtime_parachains::assigner_on_demand::WeightInfo /// The range of component `s` is `[1, 9999]`. fn place_order_allow_death(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `363 + s * (4 ±0)` - // Estimated: `3828 + s * (4 ±0)` - // Minimum execution time: 25_421_000 picoseconds. - Weight::from_parts(21_828_043, 0) - .saturating_add(Weight::from_parts(0, 3828)) - // Standard Error: 133 - .saturating_add(Weight::from_parts(13_831, 0).saturating_mul(s.into())) + // Measured: `297 + s * (4 ±0)` + // Estimated: `3762 + s * (4 ±0)` + // Minimum execution time: 33_488_000 picoseconds. + Weight::from_parts(34_848_934, 0) + .saturating_add(Weight::from_parts(0, 3762)) + // Standard Error: 143 + .saturating_add(Weight::from_parts(14_215, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs index caad090ae15..ca0575cb1b6 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs @@ -17,27 +17,25 @@ //! Autogenerated weights for `runtime_parachains::configuration` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-02-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// target/production/polkadot // benchmark // pallet -// --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=runtime_parachains::configuration // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=runtime_parachains::configuration +// --chain=rococo-dev // --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs +// --output=./polkadot/runtime/rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -60,8 +58,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_689_000 picoseconds. - Weight::from_parts(8_089_000, 0) + // Minimum execution time: 7_789_000 picoseconds. + Weight::from_parts(8_269_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -76,8 +74,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_735_000 picoseconds. - Weight::from_parts(8_150_000, 0) + // Minimum execution time: 7_851_000 picoseconds. + Weight::from_parts(8_152_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -92,8 +90,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_902_000 picoseconds. - Weight::from_parts(8_196_000, 0) + // Minimum execution time: 7_960_000 picoseconds. + Weight::from_parts(8_276_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -118,8 +116,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_634_000 picoseconds. - Weight::from_parts(7_983_000, 0) + // Minimum execution time: 7_912_000 picoseconds. + Weight::from_parts(8_164_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -134,8 +132,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 9_580_000 picoseconds. - Weight::from_parts(9_989_000, 0) + // Minimum execution time: 9_782_000 picoseconds. + Weight::from_parts(10_373_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -150,8 +148,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_787_000 picoseconds. - Weight::from_parts(8_008_000, 0) + // Minimum execution time: 7_870_000 picoseconds. + Weight::from_parts(8_274_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -166,8 +164,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 9_557_000 picoseconds. - Weight::from_parts(9_994_000, 0) + // Minimum execution time: 9_960_000 picoseconds. + Weight::from_parts(10_514_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -182,8 +180,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_775_000 picoseconds. - Weight::from_parts(7_989_000, 0) + // Minimum execution time: 7_913_000 picoseconds. + Weight::from_parts(8_338_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_disputes.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_disputes.rs index cf1aa36e10e..63a8c3addc7 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_parachains_disputes.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_disputes.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_parachains::disputes` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=runtime_parachains::disputes // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_disputes.rs +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_parachains_disputes.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,14 +47,14 @@ use core::marker::PhantomData; /// Weight functions for `runtime_parachains::disputes`. pub struct WeightInfo(PhantomData); impl runtime_parachains::disputes::WeightInfo for WeightInfo { - /// Storage: `ParasDisputes::Frozen` (r:0 w:1) - /// Proof: `ParasDisputes::Frozen` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: ParasDisputes Frozen (r:0 w:1) + /// Proof Skipped: ParasDisputes Frozen (max_values: Some(1), max_size: None, mode: Measured) fn force_unfreeze() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_855_000 picoseconds. - Weight::from_parts(2_015_000, 0) + // Minimum execution time: 2_937_000 picoseconds. + Weight::from_parts(3_082_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_hrmp.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_hrmp.rs index a3b912491e5..417820e6627 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_parachains_hrmp.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_hrmp.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_parachains::hrmp` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=runtime_parachains::hrmp // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_hrmp.rs +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_parachains_hrmp.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,97 +47,105 @@ use core::marker::PhantomData; /// Weight functions for `runtime_parachains::hrmp`. pub struct WeightInfo(PhantomData); impl runtime_parachains::hrmp::WeightInfo for WeightInfo { - /// Storage: `Paras::ParaLifecycles` (r:1 w:0) - /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpOpenChannelRequests` (r:1 w:1) - /// Proof: `Hrmp::HrmpOpenChannelRequests` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpChannels` (r:1 w:0) - /// Proof: `Hrmp::HrmpChannels` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpEgressChannelsIndex` (r:1 w:0) - /// Proof: `Hrmp::HrmpEgressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpOpenChannelRequestCount` (r:1 w:1) - /// Proof: `Hrmp::HrmpOpenChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpOpenChannelRequestsList` (r:1 w:1) - /// Proof: `Hrmp::HrmpOpenChannelRequestsList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Paras ParaLifecycles (r:2 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:1 w:0) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) fn hrmp_init_open_channel() -> Weight { // Proof Size summary in bytes: - // Measured: `488` - // Estimated: `3953` - // Minimum execution time: 34_911_000 picoseconds. - Weight::from_parts(35_762_000, 0) - .saturating_add(Weight::from_parts(0, 3953)) - .saturating_add(T::DbWeight::get().reads(8)) + // Measured: `704` + // Estimated: `6644` + // Minimum execution time: 41_564_000 picoseconds. + Weight::from_parts(42_048_000, 0) + .saturating_add(Weight::from_parts(0, 6644)) + .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(5)) } - /// Storage: `Hrmp::HrmpOpenChannelRequests` (r:1 w:1) - /// Proof: `Hrmp::HrmpOpenChannelRequests` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpIngressChannelsIndex` (r:1 w:0) - /// Proof: `Hrmp::HrmpIngressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpAcceptedChannelRequestCount` (r:1 w:1) - /// Proof: `Hrmp::HrmpAcceptedChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:1 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) fn hrmp_accept_open_channel() -> Weight { // Proof Size summary in bytes: - // Measured: `478` - // Estimated: `3943` - // Minimum execution time: 31_483_000 picoseconds. - Weight::from_parts(32_230_000, 0) - .saturating_add(Weight::from_parts(0, 3943)) - .saturating_add(T::DbWeight::get().reads(5)) + // Measured: `936` + // Estimated: `4401` + // Minimum execution time: 43_570_000 picoseconds. + Weight::from_parts(44_089_000, 0) + .saturating_add(Weight::from_parts(0, 4401)) + .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: `Hrmp::HrmpChannels` (r:1 w:0) - /// Proof: `Hrmp::HrmpChannels` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpCloseChannelRequests` (r:1 w:1) - /// Proof: `Hrmp::HrmpCloseChannelRequests` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpCloseChannelRequestsList` (r:1 w:1) - /// Proof: `Hrmp::HrmpCloseChannelRequestsList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Hrmp HrmpChannels (r:1 w:0) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpCloseChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpCloseChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpCloseChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) fn hrmp_close_channel() -> Weight { // Proof Size summary in bytes: - // Measured: `591` - // Estimated: `4056` - // Minimum execution time: 32_153_000 picoseconds. - Weight::from_parts(32_982_000, 0) - .saturating_add(Weight::from_parts(0, 4056)) - .saturating_add(T::DbWeight::get().reads(5)) + // Measured: `807` + // Estimated: `4272` + // Minimum execution time: 36_594_000 picoseconds. + Weight::from_parts(37_090_000, 0) + .saturating_add(Weight::from_parts(0, 4272)) + .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: `Hrmp::HrmpIngressChannelsIndex` (r:128 w:128) - /// Proof: `Hrmp::HrmpIngressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpEgressChannelsIndex` (r:128 w:128) - /// Proof: `Hrmp::HrmpEgressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpChannels` (r:254 w:254) - /// Proof: `Hrmp::HrmpChannels` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpAcceptedChannelRequestCount` (r:0 w:1) - /// Proof: `Hrmp::HrmpAcceptedChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpChannelContents` (r:0 w:254) - /// Proof: `Hrmp::HrmpChannelContents` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpOpenChannelRequestCount` (r:0 w:1) - /// Proof: `Hrmp::HrmpOpenChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:254 w:254) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:0 w:1) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelContents (r:0 w:254) + /// Proof Skipped: Hrmp HrmpChannelContents (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:0 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) /// The range of component `i` is `[0, 127]`. /// The range of component `e` is `[0, 127]`. fn force_clean_hrmp(i: u32, e: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `297 + e * (100 ±0) + i * (100 ±0)` - // Estimated: `3759 + e * (2575 ±0) + i * (2575 ±0)` - // Minimum execution time: 1_240_769_000 picoseconds. - Weight::from_parts(1_249_285_000, 0) - .saturating_add(Weight::from_parts(0, 3759)) - // Standard Error: 112_346 - .saturating_add(Weight::from_parts(3_449_114, 0).saturating_mul(i.into())) - // Standard Error: 112_346 - .saturating_add(Weight::from_parts(3_569_184, 0).saturating_mul(e.into())) + // Measured: `264 + e * (100 ±0) + i * (100 ±0)` + // Estimated: `3726 + e * (2575 ±0) + i * (2575 ±0)` + // Minimum execution time: 1_085_140_000 picoseconds. + Weight::from_parts(1_100_901_000, 0) + .saturating_add(Weight::from_parts(0, 3726)) + // Standard Error: 98_982 + .saturating_add(Weight::from_parts(3_229_112, 0).saturating_mul(i.into())) + // Standard Error: 98_982 + .saturating_add(Weight::from_parts(3_210_944, 0).saturating_mul(e.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(i.into()))) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(e.into()))) @@ -150,139 +155,139 @@ impl runtime_parachains::hrmp::WeightInfo for WeightInf .saturating_add(Weight::from_parts(0, 2575).saturating_mul(e.into())) .saturating_add(Weight::from_parts(0, 2575).saturating_mul(i.into())) } - /// Storage: `Hrmp::HrmpOpenChannelRequestsList` (r:1 w:1) - /// Proof: `Hrmp::HrmpOpenChannelRequestsList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpOpenChannelRequests` (r:128 w:128) - /// Proof: `Hrmp::HrmpOpenChannelRequests` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ParaLifecycles` (r:256 w:0) - /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpIngressChannelsIndex` (r:128 w:128) - /// Proof: `Hrmp::HrmpIngressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpEgressChannelsIndex` (r:128 w:128) - /// Proof: `Hrmp::HrmpEgressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpOpenChannelRequestCount` (r:128 w:128) - /// Proof: `Hrmp::HrmpOpenChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpAcceptedChannelRequestCount` (r:128 w:128) - /// Proof: `Hrmp::HrmpAcceptedChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpChannels` (r:0 w:128) - /// Proof: `Hrmp::HrmpChannels` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:128 w:128) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras ParaLifecycles (r:256 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:128 w:128) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:128 w:128) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:0 w:128) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) /// The range of component `c` is `[0, 128]`. fn force_process_hrmp_open(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `525 + c * (136 ±0)` - // Estimated: `1980 + c * (5086 ±0)` - // Minimum execution time: 6_026_000 picoseconds. - Weight::from_parts(6_257_000, 0) - .saturating_add(Weight::from_parts(0, 1980)) - // Standard Error: 9_732 - .saturating_add(Weight::from_parts(21_049_890, 0).saturating_mul(c.into())) - .saturating_add(T::DbWeight::get().reads(1)) + // Measured: `779 + c * (136 ±0)` + // Estimated: `2234 + c * (5086 ±0)` + // Minimum execution time: 10_497_000 picoseconds. + Weight::from_parts(6_987_455, 0) + .saturating_add(Weight::from_parts(0, 2234)) + // Standard Error: 18_540 + .saturating_add(Weight::from_parts(18_788_534, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().reads((7_u64).saturating_mul(c.into()))) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes((6_u64).saturating_mul(c.into()))) .saturating_add(Weight::from_parts(0, 5086).saturating_mul(c.into())) } - /// Storage: `Hrmp::HrmpCloseChannelRequestsList` (r:1 w:1) - /// Proof: `Hrmp::HrmpCloseChannelRequestsList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpChannels` (r:128 w:128) - /// Proof: `Hrmp::HrmpChannels` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpEgressChannelsIndex` (r:128 w:128) - /// Proof: `Hrmp::HrmpEgressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpIngressChannelsIndex` (r:128 w:128) - /// Proof: `Hrmp::HrmpIngressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpCloseChannelRequests` (r:0 w:128) - /// Proof: `Hrmp::HrmpCloseChannelRequests` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpChannelContents` (r:0 w:128) - /// Proof: `Hrmp::HrmpChannelContents` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpCloseChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:128 w:128) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:128) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpCloseChannelRequests (r:0 w:128) + /// Proof Skipped: Hrmp HrmpCloseChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannelContents (r:0 w:128) + /// Proof Skipped: Hrmp HrmpChannelContents (max_values: None, max_size: None, mode: Measured) /// The range of component `c` is `[0, 128]`. fn force_process_hrmp_close(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `368 + c * (124 ±0)` - // Estimated: `1828 + c * (2600 ±0)` - // Minimum execution time: 4_991_000 picoseconds. - Weight::from_parts(984_758, 0) - .saturating_add(Weight::from_parts(0, 1828)) - // Standard Error: 11_918 - .saturating_add(Weight::from_parts(13_018_813, 0).saturating_mul(c.into())) + // Measured: `335 + c * (124 ±0)` + // Estimated: `1795 + c * (2600 ±0)` + // Minimum execution time: 6_575_000 picoseconds. + Weight::from_parts(1_228_642, 0) + .saturating_add(Weight::from_parts(0, 1795)) + // Standard Error: 14_826 + .saturating_add(Weight::from_parts(11_604_038, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(c.into()))) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes((5_u64).saturating_mul(c.into()))) .saturating_add(Weight::from_parts(0, 2600).saturating_mul(c.into())) } - /// Storage: `Hrmp::HrmpOpenChannelRequestsList` (r:1 w:1) - /// Proof: `Hrmp::HrmpOpenChannelRequestsList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpOpenChannelRequests` (r:1 w:1) - /// Proof: `Hrmp::HrmpOpenChannelRequests` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpOpenChannelRequestCount` (r:1 w:1) - /// Proof: `Hrmp::HrmpOpenChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) /// The range of component `c` is `[0, 128]`. fn hrmp_cancel_open_request(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1059 + c * (13 ±0)` - // Estimated: `4328 + c * (15 ±0)` - // Minimum execution time: 17_299_000 picoseconds. - Weight::from_parts(27_621_478, 0) - .saturating_add(Weight::from_parts(0, 4328)) - // Standard Error: 2_527 - .saturating_add(Weight::from_parts(121_149, 0).saturating_mul(c.into())) + // Measured: `1026 + c * (13 ±0)` + // Estimated: `4295 + c * (15 ±0)` + // Minimum execution time: 22_301_000 picoseconds. + Weight::from_parts(26_131_473, 0) + .saturating_add(Weight::from_parts(0, 4295)) + // Standard Error: 830 + .saturating_add(Weight::from_parts(49_448, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(Weight::from_parts(0, 15).saturating_mul(c.into())) } - /// Storage: `Hrmp::HrmpOpenChannelRequestsList` (r:1 w:1) - /// Proof: `Hrmp::HrmpOpenChannelRequestsList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpOpenChannelRequests` (r:128 w:128) - /// Proof: `Hrmp::HrmpOpenChannelRequests` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:128 w:128) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) /// The range of component `c` is `[0, 128]`. fn clean_open_channel_requests(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `276 + c * (63 ±0)` - // Estimated: `1755 + c * (2538 ±0)` - // Minimum execution time: 3_764_000 picoseconds. - Weight::from_parts(5_935_301, 0) - .saturating_add(Weight::from_parts(0, 1755)) - // Standard Error: 3_761 - .saturating_add(Weight::from_parts(3_290_277, 0).saturating_mul(c.into())) + // Measured: `243 + c * (63 ±0)` + // Estimated: `1722 + c * (2538 ±0)` + // Minimum execution time: 5_234_000 picoseconds. + Weight::from_parts(7_350_270, 0) + .saturating_add(Weight::from_parts(0, 1722)) + // Standard Error: 3_105 + .saturating_add(Weight::from_parts(2_981_935, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) .saturating_add(Weight::from_parts(0, 2538).saturating_mul(c.into())) } - /// Storage: `Hrmp::HrmpOpenChannelRequests` (r:1 w:1) - /// Proof: `Hrmp::HrmpOpenChannelRequests` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpOpenChannelRequestsList` (r:1 w:1) - /// Proof: `Hrmp::HrmpOpenChannelRequestsList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpOpenChannelRequestCount` (r:1 w:1) - /// Proof: `Hrmp::HrmpOpenChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ParaLifecycles` (r:1 w:0) - /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpChannels` (r:1 w:0) - /// Proof: `Hrmp::HrmpChannels` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpEgressChannelsIndex` (r:1 w:0) - /// Proof: `Hrmp::HrmpEgressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:2 w:2) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueueHeads` (r:2 w:2) - /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpIngressChannelsIndex` (r:1 w:0) - /// Proof: `Hrmp::HrmpIngressChannelsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpAcceptedChannelRequestCount` (r:1 w:1) - /// Proof: `Hrmp::HrmpAcceptedChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `c` is `[0, 1]`. - fn force_open_hrmp_channel(c: u32, ) -> Weight { + /// Storage: Paras ParaLifecycles (r:2 w:0) + /// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequests (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpChannels (r:1 w:0) + /// Proof Skipped: Hrmp HrmpChannels (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpEgressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestCount (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + /// Proof Skipped: Hrmp HrmpOpenChannelRequestsList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueues (r:2 w:2) + /// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured) + /// Storage: Dmp DownwardMessageQueueHeads (r:2 w:2) + /// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpIngressChannelsIndex (r:1 w:0) + /// Proof Skipped: Hrmp HrmpIngressChannelsIndex (max_values: None, max_size: None, mode: Measured) + /// Storage: Hrmp HrmpAcceptedChannelRequestCount (r:1 w:1) + /// Proof Skipped: Hrmp HrmpAcceptedChannelRequestCount (max_values: None, max_size: None, mode: Measured) + fn force_open_hrmp_channel(_c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `488 + c * (235 ±0)` - // Estimated: `6428 + c * (235 ±0)` - // Minimum execution time: 49_506_000 picoseconds. - Weight::from_parts(51_253_075, 0) - .saturating_add(Weight::from_parts(0, 6428)) - // Standard Error: 144_082 - .saturating_add(Weight::from_parts(12_862_224, 0).saturating_mul(c.into())) - .saturating_add(T::DbWeight::get().reads(12)) + // Measured: `704` + // Estimated: `6644` + // Minimum execution time: 55_611_000 picoseconds. + Weight::from_parts(56_488_000, 0) + .saturating_add(Weight::from_parts(0, 6644)) + .saturating_add(T::DbWeight::get().reads(14)) .saturating_add(T::DbWeight::get().writes(8)) - .saturating_add(Weight::from_parts(0, 235).saturating_mul(c.into())) } /// Storage: `Paras::ParaLifecycles` (r:1 w:0) /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -306,11 +311,11 @@ impl runtime_parachains::hrmp::WeightInfo for WeightInf /// Proof: `Hrmp::HrmpAcceptedChannelRequestCount` (`max_values`: None, `max_size`: None, mode: `Measured`) fn establish_system_channel() -> Weight { // Proof Size summary in bytes: - // Measured: `488` - // Estimated: `6428` - // Minimum execution time: 50_016_000 picoseconds. - Weight::from_parts(50_933_000, 0) - .saturating_add(Weight::from_parts(0, 6428)) + // Measured: `417` + // Estimated: `6357` + // Minimum execution time: 629_674_000 picoseconds. + Weight::from_parts(640_174_000, 0) + .saturating_add(Weight::from_parts(0, 6357)) .saturating_add(T::DbWeight::get().reads(12)) .saturating_add(T::DbWeight::get().writes(8)) } @@ -318,11 +323,11 @@ impl runtime_parachains::hrmp::WeightInfo for WeightInf /// Proof: `Hrmp::HrmpChannels` (`max_values`: None, `max_size`: None, mode: `Measured`) fn poke_channel_deposits() -> Weight { // Proof Size summary in bytes: - // Measured: `296` - // Estimated: `3761` - // Minimum execution time: 12_280_000 picoseconds. - Weight::from_parts(12_863_000, 0) - .saturating_add(Weight::from_parts(0, 3761)) + // Measured: `263` + // Estimated: `3728` + // Minimum execution time: 173_371_000 picoseconds. + Weight::from_parts(175_860_000, 0) + .saturating_add(Weight::from_parts(0, 3728)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_inclusion.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_inclusion.rs index b9ec7565bd5..a121ad774ce 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_parachains_inclusion.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_inclusion.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_parachains::inclusion` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=runtime_parachains::inclusion // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_inclusion.rs +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_parachains_inclusion.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,25 +47,27 @@ use core::marker::PhantomData; /// Weight functions for `runtime_parachains::inclusion`. pub struct WeightInfo(PhantomData); impl runtime_parachains::inclusion::WeightInfo for WeightInfo { - /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::Pages` (r:1 w:999) - /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`) - /// Storage: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Proof: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) - /// Storage: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) - /// Proof: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:999) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1) + /// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) + /// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1) /// The range of component `i` is `[1, 1000]`. fn receive_upward_messages(i: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `32993` + // Measured: `33280` // Estimated: `36283` - // Minimum execution time: 72_675_000 picoseconds. - Weight::from_parts(73_290_000, 0) + // Minimum execution time: 71_094_000 picoseconds. + Weight::from_parts(71_436_000, 0) .saturating_add(Weight::from_parts(0, 36283)) - // Standard Error: 16_067 - .saturating_add(Weight::from_parts(57_735_739, 0).saturating_mul(i.into())) - .saturating_add(T::DbWeight::get().reads(2)) + // Standard Error: 22_149 + .saturating_add(Weight::from_parts(51_495_472, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) } diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_initializer.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_initializer.rs index e8c554610c9..5c627507dfb 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_parachains_initializer.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_initializer.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_parachains::initializer` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=runtime_parachains::initializer // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_initializer.rs +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_parachains_initializer.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,18 +47,18 @@ use core::marker::PhantomData; /// Weight functions for `runtime_parachains::initializer`. pub struct WeightInfo(PhantomData); impl runtime_parachains::initializer::WeightInfo for WeightInfo { - /// Storage: `System::Digest` (r:1 w:1) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `d` is `[0, 65536]`. fn force_approve(d: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + d * (11 ±0)` // Estimated: `1480 + d * (11 ±0)` - // Minimum execution time: 2_634_000 picoseconds. - Weight::from_parts(2_728_000, 0) + // Minimum execution time: 3_771_000 picoseconds. + Weight::from_parts(6_491_437, 0) .saturating_add(Weight::from_parts(0, 1480)) - // Standard Error: 19 - .saturating_add(Weight::from_parts(2_499, 0).saturating_mul(d.into())) + // Standard Error: 9 + .saturating_add(Weight::from_parts(1_356, 0).saturating_mul(d.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(Weight::from_parts(0, 11).saturating_mul(d.into())) diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_paras.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_paras.rs index af26bfc9ae9..dfd95006dc7 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_parachains_paras.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_paras.rs @@ -16,11 +16,11 @@ //! Autogenerated weights for `runtime_parachains::paras` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: // ./target/production/polkadot @@ -29,15 +29,12 @@ // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=runtime_parachains::paras // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_paras.rs +// --header=./file_header.txt +// --output=./runtime/rococo/src/weights/runtime_parachains_paras.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,248 +47,247 @@ use core::marker::PhantomData; /// Weight functions for `runtime_parachains::paras`. pub struct WeightInfo(PhantomData); impl runtime_parachains::paras::WeightInfo for WeightInfo { - /// Storage: `Paras::CurrentCodeHash` (r:1 w:1) - /// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::CodeByHashRefs` (r:1 w:1) - /// Proof: `Paras::CodeByHashRefs` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::PastCodeMeta` (r:1 w:1) - /// Proof: `Paras::PastCodeMeta` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::PastCodePruning` (r:1 w:1) - /// Proof: `Paras::PastCodePruning` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::PastCodeHash` (r:0 w:1) - /// Proof: `Paras::PastCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::CodeByHash` (r:0 w:1) - /// Proof: `Paras::CodeByHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Paras CurrentCodeHash (r:1 w:1) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PastCodeMeta (r:1 w:1) + /// Proof Skipped: Paras PastCodeMeta (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PastCodePruning (r:1 w:1) + /// Proof Skipped: Paras PastCodePruning (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PastCodeHash (r:0 w:1) + /// Proof Skipped: Paras PastCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:0 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) /// The range of component `c` is `[1, 3145728]`. fn force_set_current_code(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `8309` // Estimated: `11774` - // Minimum execution time: 27_488_000 picoseconds. - Weight::from_parts(27_810_000, 0) + // Minimum execution time: 31_941_000 picoseconds. + Weight::from_parts(32_139_000, 0) .saturating_add(Weight::from_parts(0, 11774)) - // Standard Error: 8 - .saturating_add(Weight::from_parts(2_189, 0).saturating_mul(c.into())) + // Standard Error: 5 + .saturating_add(Weight::from_parts(2_011, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(6)) } - /// Storage: `Paras::Heads` (r:0 w:1) - /// Proof: `Paras::Heads` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) /// The range of component `s` is `[1, 1048576]`. fn force_set_current_head(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_793_000 picoseconds. - Weight::from_parts(7_987_606, 0) + // Minimum execution time: 8_275_000 picoseconds. + Weight::from_parts(8_321_000, 0) .saturating_add(Weight::from_parts(0, 0)) - // Standard Error: 1 - .saturating_add(Weight::from_parts(971, 0).saturating_mul(s.into())) + // Standard Error: 2 + .saturating_add(Weight::from_parts(858, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Paras::MostRecentContext` (r:0 w:1) - /// Proof: `Paras::MostRecentContext` (`max_values`: None, `max_size`: None, mode: `Measured`) + // Storage: Paras Heads (r:0 w:1) fn force_set_most_recent_context() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 2_733_000 picoseconds. - Weight::from_parts(2_954_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(T::DbWeight::get().writes(1)) + Weight::from_parts(10_155_000, 0) + // Standard Error: 0 + .saturating_add(T::DbWeight::get().writes(1 as u64)) } - /// Storage: `Paras::FutureCodeHash` (r:1 w:1) - /// Proof: `Paras::FutureCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::CurrentCodeHash` (r:1 w:0) - /// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::UpgradeCooldowns` (r:1 w:1) - /// Proof: `Paras::UpgradeCooldowns` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) - /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::CodeByHash` (r:1 w:1) - /// Proof: `Paras::CodeByHash` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) - /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::PvfActiveVoteList` (r:1 w:1) - /// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::CodeByHashRefs` (r:1 w:1) - /// Proof: `Paras::CodeByHashRefs` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::UpgradeRestrictionSignal` (r:0 w:1) - /// Proof: `Paras::UpgradeRestrictionSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras FutureCodeHash (r:1 w:1) + /// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CurrentCodeHash (r:1 w:0) + /// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeCooldowns (r:1 w:1) + /// Proof Skipped: Paras UpgradeCooldowns (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:1 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras CodeByHashRefs (r:1 w:1) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeRestrictionSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeRestrictionSignal (max_values: None, max_size: None, mode: Measured) /// The range of component `c` is `[1, 3145728]`. fn force_schedule_code_upgrade(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `8452` - // Estimated: `11917` - // Minimum execution time: 6_072_000 picoseconds. - Weight::from_parts(6_128_000, 0) - .saturating_add(Weight::from_parts(0, 11917)) - // Standard Error: 2 - .saturating_add(Weight::from_parts(2_334, 0).saturating_mul(c.into())) - .saturating_add(T::DbWeight::get().reads(7)) - .saturating_add(T::DbWeight::get().writes(6)) + // Measured: `8715` + // Estimated: `12180` + // Minimum execution time: 49_923_000 picoseconds. + Weight::from_parts(50_688_000, 0) + .saturating_add(Weight::from_parts(0, 12180)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_976, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(7)) } - /// Storage: `Paras::FutureCodeUpgrades` (r:1 w:0) - /// Proof: `Paras::FutureCodeUpgrades` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Registrar::Paras` (r:1 w:0) - /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::Heads` (r:0 w:1) - /// Proof: `Paras::Heads` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::UpgradeGoAheadSignal` (r:0 w:1) - /// Proof: `Paras::UpgradeGoAheadSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::MostRecentContext` (r:0 w:1) - /// Proof: `Paras::MostRecentContext` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Paras FutureCodeUpgrades (r:1 w:0) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras Heads (r:0 w:1) + /// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras UpgradeGoAheadSignal (r:0 w:1) + /// Proof Skipped: Paras UpgradeGoAheadSignal (max_values: None, max_size: None, mode: Measured) /// The range of component `s` is `[1, 1048576]`. fn force_note_new_head(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `163` - // Estimated: `3628` - // Minimum execution time: 15_166_000 picoseconds. - Weight::from_parts(21_398_053, 0) - .saturating_add(Weight::from_parts(0, 3628)) - // Standard Error: 1 - .saturating_add(Weight::from_parts(976, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(3)) + // Measured: `95` + // Estimated: `3560` + // Minimum execution time: 14_408_000 picoseconds. + Weight::from_parts(14_647_000, 0) + .saturating_add(Weight::from_parts(0, 3560)) + // Standard Error: 2 + .saturating_add(Weight::from_parts(858, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) - /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ActionsQueue` (r:1 w:1) - /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) fn force_queue_action() -> Weight { // Proof Size summary in bytes: - // Measured: `4312` - // Estimated: `7777` - // Minimum execution time: 16_345_000 picoseconds. - Weight::from_parts(16_712_000, 0) - .saturating_add(Weight::from_parts(0, 7777)) + // Measured: `4288` + // Estimated: `7753` + // Minimum execution time: 20_009_000 picoseconds. + Weight::from_parts(20_518_000, 0) + .saturating_add(Weight::from_parts(0, 7753)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) - /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::PvfActiveVoteList` (r:1 w:1) - /// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) - /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ActionsQueue` (r:1 w:1) - /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) /// The range of component `c` is `[1, 3145728]`. fn add_trusted_validation_code(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `683` - // Estimated: `4148` - // Minimum execution time: 78_076_000 picoseconds. - Weight::from_parts(123_193_814, 0) - .saturating_add(Weight::from_parts(0, 4148)) - // Standard Error: 5 - .saturating_add(Weight::from_parts(1_770, 0).saturating_mul(c.into())) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `946` + // Estimated: `4411` + // Minimum execution time: 80_626_000 picoseconds. + Weight::from_parts(52_721_755, 0) + .saturating_add(Weight::from_parts(0, 4411)) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_443, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `Paras::CodeByHashRefs` (r:1 w:0) - /// Proof: `Paras::CodeByHashRefs` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::CodeByHash` (r:0 w:1) - /// Proof: `Paras::CodeByHash` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Paras CodeByHashRefs (r:1 w:0) + /// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras CodeByHash (r:0 w:1) + /// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured) fn poke_unused_validation_code() -> Weight { // Proof Size summary in bytes: // Measured: `28` // Estimated: `3493` - // Minimum execution time: 5_184_000 picoseconds. - Weight::from_parts(5_430_000, 0) + // Minimum execution time: 6_692_000 picoseconds. + Weight::from_parts(7_009_000, 0) .saturating_add(Weight::from_parts(0, 3493)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) - /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) - /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) - /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) fn include_pvf_check_statement() -> Weight { // Proof Size summary in bytes: - // Measured: `26706` - // Estimated: `30171` - // Minimum execution time: 102_995_000 picoseconds. - Weight::from_parts(108_977_000, 0) - .saturating_add(Weight::from_parts(0, 30171)) + // Measured: `26682` + // Estimated: `30147` + // Minimum execution time: 87_994_000 picoseconds. + Weight::from_parts(89_933_000, 0) + .saturating_add(Weight::from_parts(0, 30147)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) - /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) - /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) - /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::PvfActiveVoteList` (r:1 w:1) - /// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::UpcomingUpgrades` (r:1 w:1) - /// Proof: `Paras::UpcomingUpgrades` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::Digest` (r:1 w:1) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::FutureCodeUpgrades` (r:0 w:100) - /// Proof: `Paras::FutureCodeUpgrades` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras UpcomingUpgrades (r:1 w:1) + /// Proof Skipped: Paras UpcomingUpgrades (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras FutureCodeUpgrades (r:0 w:100) + /// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured) fn include_pvf_check_statement_finalize_upgrade_accept() -> Weight { // Proof Size summary in bytes: - // Measured: `27360` - // Estimated: `30825` - // Minimum execution time: 709_433_000 picoseconds. - Weight::from_parts(725_074_000, 0) - .saturating_add(Weight::from_parts(0, 30825)) - .saturating_add(T::DbWeight::get().reads(6)) + // Measured: `27523` + // Estimated: `30988` + // Minimum execution time: 783_222_000 picoseconds. + Weight::from_parts(794_959_000, 0) + .saturating_add(Weight::from_parts(0, 30988)) + .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(104)) } - /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) - /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) - /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) - /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) fn include_pvf_check_statement_finalize_upgrade_reject() -> Weight { // Proof Size summary in bytes: - // Measured: `27338` - // Estimated: `30803` - // Minimum execution time: 98_973_000 picoseconds. - Weight::from_parts(104_715_000, 0) - .saturating_add(Weight::from_parts(0, 30803)) + // Measured: `27214` + // Estimated: `30679` + // Minimum execution time: 87_424_000 picoseconds. + Weight::from_parts(88_737_000, 0) + .saturating_add(Weight::from_parts(0, 30679)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) - /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) - /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) - /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::PvfActiveVoteList` (r:1 w:1) - /// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ActionsQueue` (r:1 w:1) - /// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteList (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Configuration ActiveConfig (r:1 w:0) + /// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras ActionsQueue (r:1 w:1) + /// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured) fn include_pvf_check_statement_finalize_onboarding_accept() -> Weight { // Proof Size summary in bytes: - // Measured: `26728` - // Estimated: `30193` - // Minimum execution time: 550_958_000 picoseconds. - Weight::from_parts(564_497_000, 0) - .saturating_add(Weight::from_parts(0, 30193)) - .saturating_add(T::DbWeight::get().reads(5)) + // Measured: `26991` + // Estimated: `30456` + // Minimum execution time: 612_485_000 picoseconds. + Weight::from_parts(621_670_000, 0) + .saturating_add(Weight::from_parts(0, 30456)) + .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) - /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) - /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1) - /// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + /// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParasShared CurrentSessionIndex (r:1 w:0) + /// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Paras PvfActiveVoteMap (r:1 w:1) + /// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured) fn include_pvf_check_statement_finalize_onboarding_reject() -> Weight { // Proof Size summary in bytes: - // Measured: `26706` - // Estimated: `30171` - // Minimum execution time: 97_088_000 picoseconds. - Weight::from_parts(103_617_000, 0) - .saturating_add(Weight::from_parts(0, 30171)) + // Measured: `26682` + // Estimated: `30147` + // Minimum execution time: 86_673_000 picoseconds. + Weight::from_parts(87_424_000, 0) + .saturating_add(Weight::from_parts(0, 30147)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_paras_inherent.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_paras_inherent.rs index 374927f8470..a102d1903b2 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_parachains_paras_inherent.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_paras_inherent.rs @@ -13,334 +13,161 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . - //! Autogenerated weights for `runtime_parachains::paras_inherent` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2021-11-20, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 128 // Executed Command: -// ./target/production/polkadot +// target/release/polkadot // benchmark -// pallet // --chain=rococo-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --pallet=runtime_parachains::paras_inherent // --extrinsic=* // --execution=wasm // --wasm-execution=compiled -// --header=./polkadot/file_header.txt -// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_paras_inherent.rs +// --heap-pages=4096 +// --output=./runtime/rococo/src/weights/runtime_parachains_paras_inherent.rs +// --header=./file_header.txt #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] -#![allow(missing_docs)] use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; +use sp_std::marker::PhantomData; /// Weight functions for `runtime_parachains::paras_inherent`. pub struct WeightInfo(PhantomData); impl runtime_parachains::paras_inherent::WeightInfo for WeightInfo { - /// Storage: `ParaInherent::Included` (r:1 w:1) - /// Proof: `ParaInherent::Included` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::ParentHash` (r:1 w:0) - /// Proof: `System::ParentHash` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `ParasShared::AllowedRelayParents` (r:1 w:1) - /// Proof: `ParasShared::AllowedRelayParents` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) - /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParaScheduler::AvailabilityCores` (r:1 w:1) - /// Proof: `ParaScheduler::AvailabilityCores` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) - /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Babe::AuthorVrfRandomness` (r:1 w:0) - /// Proof: `Babe::AuthorVrfRandomness` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) - /// Storage: `ParaSessionInfo::Sessions` (r:1 w:0) - /// Proof: `ParaSessionInfo::Sessions` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParasDisputes::Disputes` (r:1 w:1) - /// Proof: `ParasDisputes::Disputes` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParasDisputes::BackersOnDisputes` (r:1 w:1) - /// Proof: `ParasDisputes::BackersOnDisputes` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParasDisputes::Included` (r:1 w:1) - /// Proof: `ParasDisputes::Included` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParaInherent::OnChainVotes` (r:1 w:1) - /// Proof: `ParaInherent::OnChainVotes` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasDisputes::Frozen` (r:1 w:0) - /// Proof: `ParasDisputes::Frozen` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParaInclusion::PendingAvailability` (r:2 w:1) - /// Proof: `ParaInclusion::PendingAvailability` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParaInclusion::PendingAvailabilityCommitments` (r:1 w:1) - /// Proof: `ParaInclusion::PendingAvailabilityCommitments` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:1) - /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpChannelDigests` (r:1 w:1) - /// Proof: `Hrmp::HrmpChannelDigests` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::FutureCodeUpgrades` (r:1 w:0) - /// Proof: `Paras::FutureCodeUpgrades` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Registrar::Paras` (r:1 w:0) - /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParaScheduler::SessionStartBlock` (r:1 w:0) - /// Proof: `ParaScheduler::SessionStartBlock` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParaScheduler::ValidatorGroups` (r:1 w:0) - /// Proof: `ParaScheduler::ValidatorGroups` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParaScheduler::ClaimQueue` (r:1 w:1) - /// Proof: `ParaScheduler::ClaimQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `CoretimeAssignmentProvider::CoreDescriptors` (r:1 w:1) - /// Proof: `CoretimeAssignmentProvider::CoreDescriptors` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::ActiveValidatorIndices` (r:1 w:0) - /// Proof: `ParasShared::ActiveValidatorIndices` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Session::DisabledValidators` (r:1 w:0) - /// Proof: `Session::DisabledValidators` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpWatermarks` (r:0 w:1) - /// Proof: `Hrmp::HrmpWatermarks` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::Heads` (r:0 w:1) - /// Proof: `Paras::Heads` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::UpgradeGoAheadSignal` (r:0 w:1) - /// Proof: `Paras::UpgradeGoAheadSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::MostRecentContext` (r:0 w:1) - /// Proof: `Paras::MostRecentContext` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `v` is `[10, 200]`. + // Storage: ParaInherent Included (r:1 w:1) + // Storage: System ParentHash (r:1 w:0) + // Storage: ParaScheduler AvailabilityCores (r:1 w:1) + // Storage: ParasShared CurrentSessionIndex (r:1 w:0) + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: ParaSessionInfo Sessions (r:1 w:0) + // Storage: ParasDisputes Disputes (r:1 w:1) + // Storage: ParasDisputes Included (r:1 w:1) + // Storage: ParasDisputes SpamSlots (r:1 w:1) + // Storage: ParasDisputes Frozen (r:1 w:0) + // Storage: ParaInclusion PendingAvailability (r:2 w:1) + // Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + // Storage: Paras Parachains (r:1 w:0) + // Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + // Storage: Hrmp HrmpChannelDigests (r:1 w:1) + // Storage: Paras FutureCodeUpgrades (r:1 w:0) + // Storage: ParaScheduler SessionStartBlock (r:1 w:0) + // Storage: ParaScheduler ParathreadQueue (r:1 w:1) + // Storage: ParaScheduler Scheduled (r:1 w:1) + // Storage: ParaScheduler ValidatorGroups (r:1 w:0) + // Storage: Ump NeedsDispatch (r:1 w:1) + // Storage: Ump NextDispatchRoundStartWith (r:1 w:1) + // Storage: ParaInherent OnChainVotes (r:0 w:1) + // Storage: Hrmp HrmpWatermarks (r:0 w:1) + // Storage: Paras Heads (r:0 w:1) fn enter_variable_disputes(v: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `67819` - // Estimated: `73759 + v * (23 ±0)` - // Minimum execution time: 874_229_000 picoseconds. - Weight::from_parts(486_359_072, 0) - .saturating_add(Weight::from_parts(0, 73759)) - // Standard Error: 19_197 - .saturating_add(Weight::from_parts(41_842_161, 0).saturating_mul(v.into())) - .saturating_add(T::DbWeight::get().reads(26)) - .saturating_add(T::DbWeight::get().writes(16)) - .saturating_add(Weight::from_parts(0, 23).saturating_mul(v.into())) + Weight::from_parts(352_590_000 as u64, 0) + // Standard Error: 13_000 + .saturating_add(Weight::from_parts(49_254_000 as u64, 0).saturating_mul(v as u64)) + .saturating_add(T::DbWeight::get().reads(24 as u64)) + .saturating_add(T::DbWeight::get().writes(16 as u64)) } - /// Storage: `ParaInherent::Included` (r:1 w:1) - /// Proof: `ParaInherent::Included` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::ParentHash` (r:1 w:0) - /// Proof: `System::ParentHash` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `ParasShared::AllowedRelayParents` (r:1 w:1) - /// Proof: `ParasShared::AllowedRelayParents` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) - /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParaScheduler::AvailabilityCores` (r:1 w:1) - /// Proof: `ParaScheduler::AvailabilityCores` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) - /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Babe::AuthorVrfRandomness` (r:1 w:0) - /// Proof: `Babe::AuthorVrfRandomness` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) - /// Storage: `ParaInherent::OnChainVotes` (r:1 w:1) - /// Proof: `ParaInherent::OnChainVotes` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasDisputes::Frozen` (r:1 w:0) - /// Proof: `ParasDisputes::Frozen` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParaInclusion::PendingAvailability` (r:2 w:1) - /// Proof: `ParaInclusion::PendingAvailability` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParaInclusion::PendingAvailabilityCommitments` (r:1 w:1) - /// Proof: `ParaInclusion::PendingAvailabilityCommitments` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:1) - /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpChannelDigests` (r:1 w:1) - /// Proof: `Hrmp::HrmpChannelDigests` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::FutureCodeUpgrades` (r:1 w:0) - /// Proof: `Paras::FutureCodeUpgrades` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Registrar::Paras` (r:1 w:0) - /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParasDisputes::Disputes` (r:1 w:0) - /// Proof: `ParasDisputes::Disputes` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParaScheduler::SessionStartBlock` (r:1 w:0) - /// Proof: `ParaScheduler::SessionStartBlock` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParaScheduler::ValidatorGroups` (r:1 w:0) - /// Proof: `ParaScheduler::ValidatorGroups` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParaScheduler::ClaimQueue` (r:1 w:1) - /// Proof: `ParaScheduler::ClaimQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `CoretimeAssignmentProvider::CoreDescriptors` (r:1 w:1) - /// Proof: `CoretimeAssignmentProvider::CoreDescriptors` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::ActiveValidatorIndices` (r:1 w:0) - /// Proof: `ParasShared::ActiveValidatorIndices` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Session::DisabledValidators` (r:1 w:0) - /// Proof: `Session::DisabledValidators` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParaInclusion::AvailabilityBitfields` (r:0 w:1) - /// Proof: `ParaInclusion::AvailabilityBitfields` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParasDisputes::Included` (r:0 w:1) - /// Proof: `ParasDisputes::Included` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpWatermarks` (r:0 w:1) - /// Proof: `Hrmp::HrmpWatermarks` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::Heads` (r:0 w:1) - /// Proof: `Paras::Heads` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::UpgradeGoAheadSignal` (r:0 w:1) - /// Proof: `Paras::UpgradeGoAheadSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::MostRecentContext` (r:0 w:1) - /// Proof: `Paras::MostRecentContext` (`max_values`: None, `max_size`: None, mode: `Measured`) + // Storage: ParaInherent Included (r:1 w:1) + // Storage: System ParentHash (r:1 w:0) + // Storage: ParaScheduler AvailabilityCores (r:1 w:1) + // Storage: ParasShared CurrentSessionIndex (r:1 w:0) + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: ParasDisputes Frozen (r:1 w:0) + // Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + // Storage: Paras Parachains (r:1 w:0) + // Storage: ParaInclusion PendingAvailability (r:2 w:1) + // Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + // Storage: Hrmp HrmpChannelDigests (r:1 w:1) + // Storage: Paras FutureCodeUpgrades (r:1 w:0) + // Storage: ParasDisputes Disputes (r:1 w:0) + // Storage: ParaScheduler SessionStartBlock (r:1 w:0) + // Storage: ParaScheduler ParathreadQueue (r:1 w:1) + // Storage: ParaScheduler Scheduled (r:1 w:1) + // Storage: ParaScheduler ValidatorGroups (r:1 w:0) + // Storage: Ump NeedsDispatch (r:1 w:1) + // Storage: Ump NextDispatchRoundStartWith (r:1 w:1) + // Storage: ParaInclusion AvailabilityBitfields (r:0 w:1) + // Storage: ParaInherent OnChainVotes (r:0 w:1) + // Storage: ParasDisputes Included (r:0 w:1) + // Storage: Hrmp HrmpWatermarks (r:0 w:1) + // Storage: Paras Heads (r:0 w:1) fn enter_bitfields() -> Weight { - // Proof Size summary in bytes: - // Measured: `42791` - // Estimated: `48731` - // Minimum execution time: 428_757_000 picoseconds. - Weight::from_parts(449_681_000, 0) - .saturating_add(Weight::from_parts(0, 48731)) - .saturating_add(T::DbWeight::get().reads(24)) - .saturating_add(T::DbWeight::get().writes(17)) + Weight::from_parts(299_878_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(21 as u64)) + .saturating_add(T::DbWeight::get().writes(15 as u64)) } - /// Storage: `ParaInherent::Included` (r:1 w:1) - /// Proof: `ParaInherent::Included` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::ParentHash` (r:1 w:0) - /// Proof: `System::ParentHash` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `ParasShared::AllowedRelayParents` (r:1 w:1) - /// Proof: `ParasShared::AllowedRelayParents` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) - /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParaScheduler::AvailabilityCores` (r:1 w:1) - /// Proof: `ParaScheduler::AvailabilityCores` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) - /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Babe::AuthorVrfRandomness` (r:1 w:0) - /// Proof: `Babe::AuthorVrfRandomness` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) - /// Storage: `ParaInherent::OnChainVotes` (r:1 w:1) - /// Proof: `ParaInherent::OnChainVotes` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasDisputes::Frozen` (r:1 w:0) - /// Proof: `ParasDisputes::Frozen` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParaInclusion::PendingAvailability` (r:2 w:1) - /// Proof: `ParaInclusion::PendingAvailability` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParaInclusion::PendingAvailabilityCommitments` (r:1 w:1) - /// Proof: `ParaInclusion::PendingAvailabilityCommitments` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:1) - /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpChannelDigests` (r:1 w:1) - /// Proof: `Hrmp::HrmpChannelDigests` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::FutureCodeUpgrades` (r:1 w:0) - /// Proof: `Paras::FutureCodeUpgrades` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Registrar::Paras` (r:1 w:0) - /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParasDisputes::Disputes` (r:1 w:0) - /// Proof: `ParasDisputes::Disputes` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParaScheduler::SessionStartBlock` (r:1 w:0) - /// Proof: `ParaScheduler::SessionStartBlock` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParaScheduler::ValidatorGroups` (r:1 w:0) - /// Proof: `ParaScheduler::ValidatorGroups` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParaScheduler::ClaimQueue` (r:1 w:1) - /// Proof: `ParaScheduler::ClaimQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `CoretimeAssignmentProvider::CoreDescriptors` (r:1 w:1) - /// Proof: `CoretimeAssignmentProvider::CoreDescriptors` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::CurrentCodeHash` (r:1 w:0) - /// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ParaLifecycles` (r:1 w:0) - /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `MessageQueue::BookStateFor` (r:1 w:0) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) - /// Storage: `ParasShared::ActiveValidatorIndices` (r:1 w:0) - /// Proof: `ParasShared::ActiveValidatorIndices` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Session::DisabledValidators` (r:1 w:0) - /// Proof: `Session::DisabledValidators` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasDisputes::Included` (r:0 w:1) - /// Proof: `ParasDisputes::Included` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpWatermarks` (r:0 w:1) - /// Proof: `Hrmp::HrmpWatermarks` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::Heads` (r:0 w:1) - /// Proof: `Paras::Heads` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::UpgradeGoAheadSignal` (r:0 w:1) - /// Proof: `Paras::UpgradeGoAheadSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::MostRecentContext` (r:0 w:1) - /// Proof: `Paras::MostRecentContext` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `v` is `[101, 200]`. - fn enter_backed_candidates_variable(v: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `42863` - // Estimated: `48803` - // Minimum execution time: 1_276_079_000 picoseconds. - Weight::from_parts(1_313_585_212, 0) - .saturating_add(Weight::from_parts(0, 48803)) - // Standard Error: 18_279 - .saturating_add(Weight::from_parts(43_528, 0).saturating_mul(v.into())) - .saturating_add(T::DbWeight::get().reads(27)) - .saturating_add(T::DbWeight::get().writes(16)) + // Storage: ParaInherent Included (r:1 w:1) + // Storage: System ParentHash (r:1 w:0) + // Storage: ParaScheduler AvailabilityCores (r:1 w:1) + // Storage: ParasShared CurrentSessionIndex (r:1 w:0) + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: ParasDisputes Frozen (r:1 w:0) + // Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + // Storage: Paras Parachains (r:1 w:0) + // Storage: ParaInclusion PendingAvailability (r:2 w:1) + // Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + // Storage: Hrmp HrmpChannelDigests (r:1 w:1) + // Storage: Paras FutureCodeUpgrades (r:1 w:0) + // Storage: ParasDisputes Disputes (r:2 w:0) + // Storage: ParaScheduler SessionStartBlock (r:1 w:0) + // Storage: ParaScheduler ParathreadQueue (r:1 w:1) + // Storage: ParaScheduler Scheduled (r:1 w:1) + // Storage: ParaScheduler ValidatorGroups (r:1 w:0) + // Storage: Paras PastCodeMeta (r:1 w:0) + // Storage: Paras CurrentCodeHash (r:1 w:0) + // Storage: Ump RelayDispatchQueueSize (r:1 w:0) + // Storage: Ump NeedsDispatch (r:1 w:1) + // Storage: Ump NextDispatchRoundStartWith (r:1 w:1) + // Storage: ParaInherent OnChainVotes (r:0 w:1) + // Storage: ParasDisputes Included (r:0 w:1) + // Storage: Hrmp HrmpWatermarks (r:0 w:1) + // Storage: Paras Heads (r:0 w:1) + fn enter_backed_candidates_variable(_v: u32) -> Weight { + Weight::from_parts(442_472_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(25 as u64)) + .saturating_add(T::DbWeight::get().writes(14 as u64)) } - /// Storage: `ParaInherent::Included` (r:1 w:1) - /// Proof: `ParaInherent::Included` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::ParentHash` (r:1 w:0) - /// Proof: `System::ParentHash` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `ParasShared::AllowedRelayParents` (r:1 w:1) - /// Proof: `ParasShared::AllowedRelayParents` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) - /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParaScheduler::AvailabilityCores` (r:1 w:1) - /// Proof: `ParaScheduler::AvailabilityCores` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0) - /// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Babe::AuthorVrfRandomness` (r:1 w:0) - /// Proof: `Babe::AuthorVrfRandomness` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) - /// Storage: `ParaInherent::OnChainVotes` (r:1 w:1) - /// Proof: `ParaInherent::OnChainVotes` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasDisputes::Frozen` (r:1 w:0) - /// Proof: `ParasDisputes::Frozen` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParaInclusion::PendingAvailability` (r:2 w:1) - /// Proof: `ParaInclusion::PendingAvailability` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParaInclusion::PendingAvailabilityCommitments` (r:1 w:1) - /// Proof: `ParaInclusion::PendingAvailabilityCommitments` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) - /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:1) - /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpChannelDigests` (r:1 w:1) - /// Proof: `Hrmp::HrmpChannelDigests` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::FutureCodeUpgrades` (r:1 w:0) - /// Proof: `Paras::FutureCodeUpgrades` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Registrar::Paras` (r:1 w:0) - /// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParasDisputes::Disputes` (r:1 w:0) - /// Proof: `ParasDisputes::Disputes` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ParaScheduler::SessionStartBlock` (r:1 w:0) - /// Proof: `ParaScheduler::SessionStartBlock` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParaScheduler::ValidatorGroups` (r:1 w:0) - /// Proof: `ParaScheduler::ValidatorGroups` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParaScheduler::ClaimQueue` (r:1 w:1) - /// Proof: `ParaScheduler::ClaimQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `CoretimeAssignmentProvider::CoreDescriptors` (r:1 w:1) - /// Proof: `CoretimeAssignmentProvider::CoreDescriptors` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::CurrentCodeHash` (r:1 w:0) - /// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::FutureCodeHash` (r:1 w:0) - /// Proof: `Paras::FutureCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::UpgradeRestrictionSignal` (r:1 w:0) - /// Proof: `Paras::UpgradeRestrictionSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::ParaLifecycles` (r:1 w:0) - /// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `MessageQueue::BookStateFor` (r:1 w:0) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`) - /// Storage: `ParasShared::ActiveValidatorIndices` (r:1 w:0) - /// Proof: `ParasShared::ActiveValidatorIndices` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Session::DisabledValidators` (r:1 w:0) - /// Proof: `Session::DisabledValidators` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ParasDisputes::Included` (r:0 w:1) - /// Proof: `ParasDisputes::Included` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Hrmp::HrmpWatermarks` (r:0 w:1) - /// Proof: `Hrmp::HrmpWatermarks` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::Heads` (r:0 w:1) - /// Proof: `Paras::Heads` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::UpgradeGoAheadSignal` (r:0 w:1) - /// Proof: `Paras::UpgradeGoAheadSignal` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Paras::MostRecentContext` (r:0 w:1) - /// Proof: `Paras::MostRecentContext` (`max_values`: None, `max_size`: None, mode: `Measured`) + // Storage: ParaInherent Included (r:1 w:1) + // Storage: System ParentHash (r:1 w:0) + // Storage: ParaScheduler AvailabilityCores (r:1 w:1) + // Storage: ParasShared CurrentSessionIndex (r:1 w:0) + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: ParasDisputes Frozen (r:1 w:0) + // Storage: ParasShared ActiveValidatorKeys (r:1 w:0) + // Storage: Paras Parachains (r:1 w:0) + // Storage: ParaInclusion PendingAvailability (r:2 w:1) + // Storage: ParaInclusion PendingAvailabilityCommitments (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + // Storage: Hrmp HrmpChannelDigests (r:1 w:1) + // Storage: Paras FutureCodeUpgrades (r:1 w:0) + // Storage: ParasDisputes Disputes (r:2 w:0) + // Storage: ParaScheduler SessionStartBlock (r:1 w:0) + // Storage: ParaScheduler ParathreadQueue (r:1 w:1) + // Storage: ParaScheduler Scheduled (r:1 w:1) + // Storage: ParaScheduler ValidatorGroups (r:1 w:0) + // Storage: Paras PastCodeMeta (r:1 w:0) + // Storage: Paras CurrentCodeHash (r:1 w:0) + // Storage: Ump RelayDispatchQueueSize (r:1 w:0) + // Storage: Ump NeedsDispatch (r:1 w:1) + // Storage: Ump NextDispatchRoundStartWith (r:1 w:1) + // Storage: ParaInherent OnChainVotes (r:0 w:1) + // Storage: ParasDisputes Included (r:0 w:1) + // Storage: Hrmp HrmpWatermarks (r:0 w:1) + // Storage: Paras Heads (r:0 w:1) fn enter_backed_candidate_code_upgrade() -> Weight { - // Proof Size summary in bytes: - // Measured: `42876` - // Estimated: `48816` - // Minimum execution time: 34_352_245_000 picoseconds. - Weight::from_parts(34_587_559_000, 0) - .saturating_add(Weight::from_parts(0, 48816)) - .saturating_add(T::DbWeight::get().reads(29)) - .saturating_add(T::DbWeight::get().writes(16)) + Weight::from_parts(36_903_411_000 as u64, 0) + .saturating_add(T::DbWeight::get().reads(25 as u64)) + .saturating_add(T::DbWeight::get().writes(14 as u64)) } } diff --git a/polkadot/runtime/test-runtime/Cargo.toml b/polkadot/runtime/test-runtime/Cargo.toml index bdf68864605..9753a409304 100644 --- a/polkadot/runtime/test-runtime/Cargo.toml +++ b/polkadot/runtime/test-runtime/Cargo.toml @@ -155,7 +155,6 @@ runtime-benchmarks = [ "pallet-staking/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-vesting/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index a0617b3108f..6c899c52701 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -238,7 +238,6 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = frame_support::weights::ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; - type WeightInfo = (); } parameter_types! { @@ -394,7 +393,7 @@ where let current_block = System::block_number().saturated_into::().saturating_sub(1); let tip = 0; - let tx_ext: TxExtension = ( + let extra: SignedExtra = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -406,17 +405,16 @@ where frame_system::CheckNonce::::from(nonce), frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(tip), - ) - .into(); - let raw_payload = SignedPayload::new(call, tx_ext) + ); + let raw_payload = SignedPayload::new(call, extra) .map_err(|e| { log::warn!("Unable to create signed payload: {:?}", e); }) .ok()?; let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?; - let (call, tx_ext, _) = raw_payload.deconstruct(); + let (call, extra, _) = raw_payload.deconstruct(); let address = Indices::unlookup(account); - Some((call, (address, signature, tx_ext))) + Some((call, (address, signature, extra))) } } @@ -444,32 +442,12 @@ parameter_types! { pub Prefix: &'static [u8] = b"Pay KSMs to the Kusama account:"; } -#[cfg(feature = "runtime-benchmarks")] -pub struct ClaimsHelper; - -#[cfg(feature = "runtime-benchmarks")] -use frame_support::dispatch::DispatchInfo; - -#[cfg(feature = "runtime-benchmarks")] -impl claims::BenchmarkHelperTrait for ClaimsHelper { - fn default_call_and_info() -> (RuntimeCall, DispatchInfo) { - use frame_support::dispatch::GetDispatchInfo; - let call = RuntimeCall::Claims(claims::Call::attest { - statement: claims::StatementKind::Regular.to_text().to_vec(), - }); - let info = call.get_dispatch_info(); - (call, info) - } -} - impl claims::Config for Runtime { type RuntimeEvent = RuntimeEvent; type VestingSchedule = Vesting; type Prefix = Prefix; type MoveClaimOrigin = frame_system::EnsureRoot; type WeightInfo = claims::TestWeightInfo; - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = ClaimsHelper; } parameter_types! { @@ -750,8 +728,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// `BlockId` type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The extension to the basic transaction logic. -pub type TxExtension = ( +/// The `SignedExtension` to the basic transaction logic. +pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -763,7 +741,7 @@ pub type TxExtension = ( ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< @@ -774,7 +752,7 @@ pub type Executive = frame_executive::Executive< AllPalletsWithSystem, >; /// The payload being signed in transactions. -pub type SignedPayload = generic::SignedPayload; +pub type SignedPayload = generic::SignedPayload; pub type Hash = ::Hash; pub type Extrinsic = ::Extrinsic; diff --git a/polkadot/runtime/westend/Cargo.toml b/polkadot/runtime/westend/Cargo.toml index 6899edeeaeb..4180828bcfb 100644 --- a/polkadot/runtime/westend/Cargo.toml +++ b/polkadot/runtime/westend/Cargo.toml @@ -270,7 +270,6 @@ runtime-benchmarks = [ "pallet-state-trie-migration/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-vesting/runtime-benchmarks", diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 45bbd0260e5..b55d68ee0f6 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -200,7 +200,6 @@ impl frame_system::Config for Runtime { type Version = Version; type AccountData = pallet_balances::AccountData; type SystemWeightInfo = weights::frame_system::WeightInfo; - type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo; type SS58Prefix = SS58Prefix; type MaxConsumers = frame_support::traits::ConstU32<16>; } @@ -386,7 +385,6 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; - type WeightInfo = weights::pallet_transaction_payment::WeightInfo; } parameter_types! { @@ -822,7 +820,7 @@ where // so the actual block number is `n`. .saturating_sub(1); let tip = 0; - let tx_ext: TxExtension = ( + let extra: SignedExtra = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -834,17 +832,16 @@ where frame_system::CheckNonce::::from(nonce), frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(tip), - ) - .into(); - let raw_payload = SignedPayload::new(call, tx_ext) + ); + let raw_payload = SignedPayload::new(call, extra) .map_err(|e| { log::warn!("Unable to create signed payload: {:?}", e); }) .ok()?; let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?; - let (call, tx_ext, _) = raw_payload.deconstruct(); + let (call, extra, _) = raw_payload.deconstruct(); let address = ::Lookup::unlookup(account); - Some((call, (address, signature, tx_ext))) + Some((call, (address, signature, extra))) } } @@ -1551,8 +1548,8 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// `BlockId` type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The extension to the basic transaction logic. -pub type TxExtension = ( +/// The `SignedExtension` to the basic transaction logic. +pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -1716,7 +1713,7 @@ pub mod migrations { /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, @@ -1727,7 +1724,7 @@ pub type Executive = frame_executive::Executive< Migrations, >; /// The payload being signed in transactions. -pub type SignedPayload = generic::SignedPayload; +pub type SignedPayload = generic::SignedPayload; #[cfg(feature = "runtime-benchmarks")] mod benches { @@ -1773,9 +1770,7 @@ mod benches { [pallet_staking, Staking] [pallet_sudo, Sudo] [frame_system, SystemBench::] - [frame_system_extensions, SystemExtensionsBench::] [pallet_timestamp, Timestamp] - [pallet_transaction_payment, TransactionPayment] [pallet_treasury, Treasury] [pallet_utility, Utility] [pallet_vesting, Vesting] @@ -2317,7 +2312,6 @@ sp_api::impl_runtime_apis! { use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench; type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::; @@ -2346,7 +2340,6 @@ sp_api::impl_runtime_apis! { use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench; impl pallet_session_benchmarking::Config for Runtime {} diff --git a/polkadot/runtime/westend/src/weights/frame_system_extensions.rs b/polkadot/runtime/westend/src/weights/frame_system_extensions.rs deleted file mode 100644 index e4e1a799ec6..00000000000 --- a/polkadot/runtime/westend/src/weights/frame_system_extensions.rs +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Polkadot. - -// Polkadot is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Polkadot is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Polkadot. If not, see . - -//! Autogenerated weights for `frame_system_extensions` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-20, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot -// benchmark -// pallet -// --steps=2 -// --repeat=2 -// --extrinsic=* -// --wasm-execution=compiled -// --heap-pages=4096 -// --pallet=frame-system-extensions -// --chain=westend-dev -// --output=./polkadot/runtime/westend/src/weights/ -// --header=./polkadot/file_header.txt - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `frame_system_extensions`. -pub struct WeightInfo(PhantomData); -impl frame_system::ExtensionsWeightInfo for WeightInfo { - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_genesis() -> Weight { - // Proof Size summary in bytes: - // Measured: `54` - // Estimated: `3509` - // Minimum execution time: 3_356_000 picoseconds. - Weight::from_parts(7_805_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_mortality() -> Weight { - // Proof Size summary in bytes: - // Measured: `92` - // Estimated: `3509` - // Minimum execution time: 5_510_000 picoseconds. - Weight::from_parts(10_009_000, 0) - .saturating_add(Weight::from_parts(0, 3509)) - .saturating_add(T::DbWeight::get().reads(1)) - } - fn check_non_zero_sender() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 761_000 picoseconds. - Weight::from_parts(4_308_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_nonce() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 3_396_000 picoseconds. - Weight::from_parts(7_585_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_spec_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 521_000 picoseconds. - Weight::from_parts(4_168_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - fn check_tx_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 541_000 picoseconds. - Weight::from_parts(4_228_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } - /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) - /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - fn check_weight() -> Weight { - // Proof Size summary in bytes: - // Measured: `24` - // Estimated: `1489` - // Minimum execution time: 3_807_000 picoseconds. - Weight::from_parts(8_025_000, 0) - .saturating_add(Weight::from_parts(0, 1489)) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) - } -} diff --git a/polkadot/runtime/westend/src/weights/mod.rs b/polkadot/runtime/westend/src/weights/mod.rs index 8aeb4216550..f6a9008d718 100644 --- a/polkadot/runtime/westend/src/weights/mod.rs +++ b/polkadot/runtime/westend/src/weights/mod.rs @@ -17,7 +17,6 @@ pub mod frame_election_provider_support; pub mod frame_system; -pub mod frame_system_extensions; pub mod pallet_asset_rate; pub mod pallet_bags_list; pub mod pallet_balances; @@ -38,7 +37,6 @@ pub mod pallet_session; pub mod pallet_staking; pub mod pallet_sudo; pub mod pallet_timestamp; -pub mod pallet_transaction_payment; pub mod pallet_treasury; pub mod pallet_utility; pub mod pallet_vesting; diff --git a/polkadot/runtime/westend/src/weights/pallet_sudo.rs b/polkadot/runtime/westend/src/weights/pallet_sudo.rs index 649c43e031d..e9ab3ad37a4 100644 --- a/polkadot/runtime/westend/src/weights/pallet_sudo.rs +++ b/polkadot/runtime/westend/src/weights/pallet_sudo.rs @@ -94,15 +94,4 @@ impl pallet_sudo::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Sudo::Key` (r:1 w:0) - /// Proof: `Sudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - fn check_only_sudo_account() -> Weight { - // Proof Size summary in bytes: - // Measured: `132` - // Estimated: `1517` - // Minimum execution time: 2_875_000 picoseconds. - Weight::from_parts(6_803_000, 0) - .saturating_add(Weight::from_parts(0, 1517)) - .saturating_add(T::DbWeight::get().reads(1)) - } } diff --git a/polkadot/runtime/westend/src/weights/pallet_transaction_payment.rs b/polkadot/runtime/westend/src/weights/pallet_transaction_payment.rs deleted file mode 100644 index 001a09f103d..00000000000 --- a/polkadot/runtime/westend/src/weights/pallet_transaction_payment.rs +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Polkadot. - -// Polkadot is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Polkadot is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Polkadot. If not, see . - -//! Autogenerated weights for `pallet_transaction_payment` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024 - -// Executed Command: -// ./target/release/polkadot -// benchmark -// pallet -// --steps=2 -// --repeat=2 -// --extrinsic=* -// --wasm-execution=compiled -// --heap-pages=4096 -// --pallet=pallet_transaction_payment -// --chain=westend-dev -// --output=./polkadot/runtime/westend/src/weights/ -// --header=./polkadot/file_header.txt - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::Weight}; -use core::marker::PhantomData; - -/// Weight functions for `pallet_transaction_payment`. -pub struct WeightInfo(PhantomData); -impl pallet_transaction_payment::WeightInfo for WeightInfo { - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - fn charge_transaction_payment() -> Weight { - // Proof Size summary in bytes: - // Measured: `156` - // Estimated: `1641` - // Minimum execution time: 30_888_000 picoseconds. - Weight::from_parts(41_308_000, 0) - .saturating_add(Weight::from_parts(0, 1641)) - .saturating_add(T::DbWeight::get().reads(3)) - } -} diff --git a/polkadot/xcm/xcm-builder/Cargo.toml b/polkadot/xcm/xcm-builder/Cargo.toml index 660a30605e5..10726b0f511 100644 --- a/polkadot/xcm/xcm-builder/Cargo.toml +++ b/polkadot/xcm/xcm-builder/Cargo.toml @@ -47,7 +47,6 @@ runtime-benchmarks = [ "pallet-assets/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-salary/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-parachains/runtime-benchmarks", diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs index 3bd2fa4b4f5..9892c500f2e 100644 --- a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs +++ b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs @@ -25,22 +25,14 @@ use frame_support::{ traits::{ConstU32, Everything}, }; use frame_system::{EnsureRoot, EnsureSigned}; +use polkadot_test_runtime::SignedExtra; use primitives::{AccountIndex, BlakeTwo256, Signature}; use sp_runtime::{generic, traits::MaybeEquivalence, AccountId32, BuildStorage}; use xcm_executor::{traits::ConvertLocation, XcmExecutor}; -pub type TxExtension = ( - frame_system::CheckNonZeroSender, - frame_system::CheckSpecVersion, - frame_system::CheckTxVersion, - frame_system::CheckGenesis, - frame_system::CheckMortality, - frame_system::CheckNonce, - frame_system::CheckWeight, -); pub type Address = sp_runtime::MultiAddress; pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; pub type Header = generic::Header; pub type Block = generic::Block; diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs index f953e54111c..a20390b64f9 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs @@ -46,13 +46,13 @@ use xcm_builder::{ }; use xcm_executor::{Config, XcmExecutor}; -pub type TxExtension = (frame_system::CheckNonZeroSender,); +pub type SignedExtra = (frame_system::CheckNonZeroSender,); pub type BlockNumber = u64; pub type Address = MultiAddress; pub type Header = generic::Header; pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; pub type Block = generic::Block; pub type Signature = MultiSignature; diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs index a11e535492c..5bf65fa9f9a 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs @@ -45,13 +45,13 @@ use xcm_builder::{ }; use xcm_executor::{Config, XcmExecutor}; -pub type TxExtension = (frame_system::CheckNonZeroSender,); +pub type SignedExtra = (frame_system::CheckNonZeroSender,); pub type BlockNumber = u64; pub type Address = MultiAddress; pub type Header = generic::Header; pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; pub type Block = generic::Block; pub type Signature = MultiSignature; diff --git a/prdoc/pr_2280.prdoc b/prdoc/pr_2280.prdoc deleted file mode 100644 index 3026dc254e6..00000000000 --- a/prdoc/pr_2280.prdoc +++ /dev/null @@ -1,144 +0,0 @@ -# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 -# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json - -title: FRAME Create `TransactionExtension` as a replacement for `SignedExtension` - -doc: - - audience: Runtime User - description: | - Introduces a new trait `TransactionExtension` to replace `SignedExtension`. Introduce the - idea of transactions which obey the runtime's extensions and have according Extension data - (né Extra data) yet do not have hard-coded signatures. - - Deprecate the terminology of "Unsigned" when used for transactions/extrinsics owing to there - now being "proper" unsigned transactions which obey the extension framework and "old-style" - unsigned which do not. Instead we have `General` for the former and `Bare` for the latter. - Unsigned will be phased out as a type of transaction, and `Bare` will only be used for - Inherents. - - Types of extrinsic are now therefore - - Bare (no hardcoded signature, no Extra data; used to be known as "Unsigned") - - Bare transactions (deprecated) - Gossiped, validated with `ValidateUnsigned` - (deprecated) and the `_bare_compat` bits of `TransactionExtension` (deprecated). - - Inherents - Not gossiped, validated with `ProvideInherent`. - - Extended (Extra data) - Gossiped, validated via `TransactionExtension`. - - Signed transactions (with a hardcoded signature). - - General transactions (without a hardcoded signature). - - Notable information on `TransactionExtension` and the differences from `SignedExtension` - - `AdditionalSigned`/`additional_signed` is renamed to `Implicit`/`implicit`. It is encoded - for the entire transaction and passed in to each extension as a new argument to validate. - - `pre_dispatch` is renamed to `prepare`. - - `validate` runs transaction validation logic both off-chain and on-chain, and is - non-mutating. - - `prepare` runs on-chain pre-execution logic using information extracted during validation - and is mutating. - - `validate` and `prepare` are now passed an `Origin` rather than an `AccountId`. If the - extension logic presumes an `AccountId`, consider using the trait function - `AsSystemOriginSigner::as_system_origin_signer`. - - A signature on the underlying transaction may validly not be present. - - The origin may be altered during validation. - - Validation functionality present in `validate` should not be repeated in `prepare`. - Useful information obtained during `validate` should now be passsed in to `prepare` using - the new user-specifiable type `Val`. - - Unsigned logic should be migrated from the old `*_unsigned` functions into the regular - versions of the new functions where the `Origin` is `None`. - - The `Call` type defining the runtime call is now a type parameter. - - `TransactionExtension` now takes a `Context` type parameter. This defines some arbitrary - contextual data that is injected into the transaction extension logic. It is unused in - instances migrated from `SignedExtension`. - - Extensions now track the weight they consume during valdiation, preparation and - post-dispatch through the `TransactionExtensionBase::weight` function. - - `TestXt` was removed and its usage in tests was replaced with `UncheckedExtrinsic` - instances. - - To fix the build issues introduced by this change, use the `AsTransactionExtension` adapter - to wrap existing `SignedExtension`s by converting them using the `From` - generic implementation for `AsTransactionExtension`. More details on migrating existing - `SignedExtension` implementations to `TransactionExtension` in the PR description. - -crates: - - name: bridge-runtime-common - - name: bp-bridge-hub-cumulus - - name: bp-kusama - - name: bp-polkadot-bulletin - - name: bp-polkadot - - name: bp-rococo - - name: bp-westend - - name: bp-polkadot-core - - name: bp-runtime - - name: snowbridge-pallet-inbound-queue - - name: snowbridge-pallet-outbound-queue - - name: snowbridge-pallet-system - - name: snowbridge-runtime-test-common - - name: parachain-template-runtime - - name: asset-hub-rococo-runtime - - name: asset-hub-westend-runtime - - name: bridge-hub-rococo-runtime - - name: bridge-hub-westend-runtime - - name: collectives-westend-runtime - - name: contracts-rococo-runtime - - name: coretime-rococo-runtime - - name: coretime-westend-runtime - - name: glutton-westend-runtime - - name: people-rococo-runtime - - name: people-westend-runtime - - name: seedling-runtime - - name: shell-runtime - - name: penpal-runtime - - name: rococo-parachain-runtime - - name: polkadot-parachain-bin - - name: cumulus-primitives-storage-weight-reclaim - - name: cumulus-test-client - - name: cumulus-test-runtime - - name: cumulus-test-service - - name: polkadot-sdk-docs - - name: polkadot-service - - name: polkadot-test-service - - name: polkadot-runtime-common - - name: rococo-runtime - - name: polkadot-test-runtime - - name: westend-runtime - - name: staging-xcm-builder - - name: minimal-runtime - - name: node-template - - name: node-template-runtime - - name: staging-node-cli - - name: kitchensink-runtime - - name: node-testing - - name: sc-client-api - - name: sc-client-db - - name: sc-network-gossip - - name: sc-network-sync - - name: sc-transaction-pool - - name: frame - - name: pallet-babe - - name: pallet-balances - - name: pallet-beefy - - name: pallet-collective - - name: pallet-election-provider-multi-phase - - name: pallet-elections-phragmen - - name: pallet-example-basic - - name: pallet-example-offchain-worker - - name: frame-executive - - name: pallet-grandpa - - name: pallet-im-online - - name: pallet-offences - - name: pallet-sassafras - - name: pallet-state-trie-migration - - name: pallet-sudo - - name: frame-support-procedural - - name: frame-support - - name: frame-system - - name: frame-system-benchmarking - - name: pallet-transaction-payment - - name: pallet-asset-conversion-tx-payment - - name: pallet-asset-tx-payment - - name: pallet-skip-feeless-payment - - name: sp-inherents - - name: sp-metadata-ir - - name: sp-runtime - - name: substrate-test-runtime - - name: frame-benchmarking-cli - - name: frame-remote-externalities - - name: substrate-rpc-client diff --git a/prdoc/pr_3665.prdoc b/prdoc/pr_3665.prdoc new file mode 100644 index 00000000000..67725d24d18 --- /dev/null +++ b/prdoc/pr_3665.prdoc @@ -0,0 +1,11 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Revert "FRAME Create TransactionExtension as a replacement for SignedExtension (#2280)" + +doc: + - audience: Runtime Dev + description: | + This PR reverts the PR which introduced `TransactionExtension` to replace `SignedExtension`. + +crates: [ ] diff --git a/substrate/.maintain/frame-weight-template.hbs b/substrate/.maintain/frame-weight-template.hbs index ec9eee205ce..ecd384a5145 100644 --- a/substrate/.maintain/frame-weight-template.hbs +++ b/substrate/.maintain/frame-weight-template.hbs @@ -33,7 +33,7 @@ pub trait WeightInfo { /// Weights for `{{pallet}}` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); -{{#if (or (eq pallet "frame_system") (eq pallet "frame_system_extensions"))}} +{{#if (eq pallet "frame_system")}} impl WeightInfo for SubstrateWeight { {{else}} impl WeightInfo for SubstrateWeight { diff --git a/substrate/bin/node/cli/Cargo.toml b/substrate/bin/node/cli/Cargo.toml index c91a83e6d6e..abe284c41da 100644 --- a/substrate/bin/node/cli/Cargo.toml +++ b/substrate/bin/node/cli/Cargo.toml @@ -196,7 +196,6 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "kitchensink-runtime/runtime-benchmarks", "node-inspect?/runtime-benchmarks", - "pallet-asset-conversion-tx-payment/runtime-benchmarks", "pallet-asset-tx-payment/runtime-benchmarks", "pallet-assets/runtime-benchmarks", "pallet-balances/runtime-benchmarks", @@ -206,7 +205,6 @@ runtime-benchmarks = [ "pallet-skip-feeless-payment/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", "sc-client-db/runtime-benchmarks", "sc-service/runtime-benchmarks", diff --git a/substrate/bin/node/cli/benches/block_production.rs b/substrate/bin/node/cli/benches/block_production.rs index b98a321c338..23a62cc0bd2 100644 --- a/substrate/bin/node/cli/benches/block_production.rs +++ b/substrate/bin/node/cli/benches/block_production.rs @@ -110,7 +110,7 @@ fn new_node(tokio_handle: Handle) -> node_cli::service::NewFullBase { fn extrinsic_set_time(now: u64) -> OpaqueExtrinsic { kitchensink_runtime::UncheckedExtrinsic { - preamble: sp_runtime::generic::Preamble::Bare, + signature: None, function: kitchensink_runtime::RuntimeCall::Timestamp(pallet_timestamp::Call::set { now }), } .into() diff --git a/substrate/bin/node/cli/benches/executor.rs b/substrate/bin/node/cli/benches/executor.rs index e13d34f9657..a326e1a79ea 100644 --- a/substrate/bin/node/cli/benches/executor.rs +++ b/substrate/bin/node/cli/benches/executor.rs @@ -29,7 +29,7 @@ use sp_core::{ storage::well_known_keys, traits::{CallContext, CodeExecutor, RuntimeCode}, }; -use sp_runtime::{generic::ExtrinsicFormat, traits::BlakeTwo256}; +use sp_runtime::traits::BlakeTwo256; use sp_state_machine::TestExternalities as CoreTestExternalities; use staging_node_cli::service::RuntimeExecutor; @@ -144,11 +144,11 @@ fn test_blocks( ) -> Vec<(Vec, Hash)> { let mut test_ext = new_test_ext(genesis_config); let mut block1_extrinsics = vec![CheckedExtrinsic { - format: ExtrinsicFormat::Bare, + signed: None, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: 0 }), }]; block1_extrinsics.extend((0..20).map(|i| CheckedExtrinsic { - format: ExtrinsicFormat::Signed(alice(), tx_ext(i, 0)), + signed: Some((alice(), signed_extra(i, 0))), function: RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { dest: bob().into(), value: 1 * DOLLARS, diff --git a/substrate/bin/node/cli/src/service.rs b/substrate/bin/node/cli/src/service.rs index 157f278fb53..8f2aba6b44c 100644 --- a/substrate/bin/node/cli/src/service.rs +++ b/substrate/bin/node/cli/src/service.rs @@ -107,21 +107,18 @@ pub fn create_extrinsic( .map(|c| c / 2) .unwrap_or(2) as u64; let tip = 0; - let tx_ext: kitchensink_runtime::TxExtension = + let extra: kitchensink_runtime::SignedExtra = ( - ( - frame_system::CheckNonZeroSender::::new(), - frame_system::CheckSpecVersion::::new(), - frame_system::CheckTxVersion::::new(), - frame_system::CheckGenesis::::new(), - frame_system::CheckEra::::from(generic::Era::mortal( - period, - best_block.saturated_into(), - )), - frame_system::CheckNonce::::from(nonce), - frame_system::CheckWeight::::new(), - ) - .into(), + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckEra::::from(generic::Era::mortal( + period, + best_block.saturated_into(), + )), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), pallet_skip_feeless_payment::SkipCheckIfFeeless::from( pallet_asset_conversion_tx_payment::ChargeAssetTxPayment::< kitchensink_runtime::Runtime, @@ -131,17 +128,15 @@ pub fn create_extrinsic( let raw_payload = kitchensink_runtime::SignedPayload::from_raw( function.clone(), - tx_ext.clone(), + extra.clone(), ( - ( - (), - kitchensink_runtime::VERSION.spec_version, - kitchensink_runtime::VERSION.transaction_version, - genesis_hash, - best_hash, - (), - (), - ), + (), + kitchensink_runtime::VERSION.spec_version, + kitchensink_runtime::VERSION.transaction_version, + genesis_hash, + best_hash, + (), + (), (), ), ); @@ -151,7 +146,7 @@ pub fn create_extrinsic( function, sp_runtime::AccountId32::from(sender.public()).into(), kitchensink_runtime::Signature::Sr25519(signature), - tx_ext, + extra, ) } @@ -796,7 +791,7 @@ mod tests { use codec::Encode; use kitchensink_runtime::{ constants::{currency::CENTS, time::SLOT_DURATION}, - Address, BalancesCall, RuntimeCall, TxExtension, UncheckedExtrinsic, + Address, BalancesCall, RuntimeCall, UncheckedExtrinsic, }; use node_primitives::{Block, DigestItem, Signature}; use sc_client_api::BlockBackend; @@ -998,31 +993,25 @@ mod tests { let tx_payment = pallet_skip_feeless_payment::SkipCheckIfFeeless::from( pallet_asset_conversion_tx_payment::ChargeAssetTxPayment::from(0, None), ); - let tx_ext: TxExtension = ( - ( - check_non_zero_sender, - check_spec_version, - check_tx_version, - check_genesis, - check_era, - check_nonce, - check_weight, - ) - .into(), + let extra = ( + check_non_zero_sender, + check_spec_version, + check_tx_version, + check_genesis, + check_era, + check_nonce, + check_weight, tx_payment, ); let raw_payload = SignedPayload::from_raw( function, - tx_ext, - ( - ((), spec_version, transaction_version, genesis_hash, genesis_hash, (), ()), - (), - ), + extra, + ((), spec_version, transaction_version, genesis_hash, genesis_hash, (), (), ()), ); let signature = raw_payload.using_encoded(|payload| signer.sign(payload)); - let (function, tx_ext, _) = raw_payload.deconstruct(); + let (function, extra, _) = raw_payload.deconstruct(); index += 1; - UncheckedExtrinsic::new_signed(function, from.into(), signature.into(), tx_ext) + UncheckedExtrinsic::new_signed(function, from.into(), signature.into(), extra) .into() }, ); diff --git a/substrate/bin/node/cli/tests/basic.rs b/substrate/bin/node/cli/tests/basic.rs index 5fcb2295ef0..525ab2e39c1 100644 --- a/substrate/bin/node/cli/tests/basic.rs +++ b/substrate/bin/node/cli/tests/basic.rs @@ -67,7 +67,7 @@ fn transfer_fee(extrinsic: &E) -> Balance { fn xt() -> UncheckedExtrinsic { sign(CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Signed(alice(), tx_ext(0, 0)), + signed: Some((alice(), signed_extra(0, 0))), function: RuntimeCall::Balances(default_transfer_call()), }) } @@ -84,11 +84,11 @@ fn changes_trie_block() -> (Vec, Hash) { GENESIS_HASH.into(), vec![ CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Bare, + signed: None, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time }), }, CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Signed(alice(), tx_ext(0, 0)), + signed: Some((alice(), signed_extra(0, 0))), function: RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { dest: bob().into(), value: 69 * DOLLARS, @@ -111,11 +111,11 @@ fn blocks() -> ((Vec, Hash), (Vec, Hash)) { GENESIS_HASH.into(), vec![ CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Bare, + signed: None, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time1 }), }, CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Signed(alice(), tx_ext(0, 0)), + signed: Some((alice(), signed_extra(0, 0))), function: RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { dest: bob().into(), value: 69 * DOLLARS, @@ -131,18 +131,18 @@ fn blocks() -> ((Vec, Hash), (Vec, Hash)) { block1.1, vec![ CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Bare, + signed: None, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time2 }), }, CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Signed(bob(), tx_ext(0, 0)), + signed: Some((bob(), signed_extra(0, 0))), function: RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { dest: alice().into(), value: 5 * DOLLARS, }), }, CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Signed(alice(), tx_ext(1, 0)), + signed: Some((alice(), signed_extra(1, 0))), function: RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { dest: bob().into(), value: 15 * DOLLARS, @@ -166,11 +166,11 @@ fn block_with_size(time: u64, nonce: u32, size: usize) -> (Vec, Hash) { GENESIS_HASH.into(), vec![ CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Bare, + signed: None, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time * 1000 }), }, CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Signed(alice(), tx_ext(nonce, 0)), + signed: Some((alice(), signed_extra(nonce, 0))), function: RuntimeCall::System(frame_system::Call::remark { remark: vec![0; size] }), }, ], @@ -677,11 +677,11 @@ fn deploying_wasm_contract_should_work() { GENESIS_HASH.into(), vec![ CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Bare, + signed: None, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time }), }, CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Signed(charlie(), tx_ext(0, 0)), + signed: Some((charlie(), signed_extra(0, 0))), function: RuntimeCall::Contracts(pallet_contracts::Call::instantiate_with_code::< Runtime, > { @@ -694,7 +694,7 @@ fn deploying_wasm_contract_should_work() { }), }, CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Signed(charlie(), tx_ext(1, 0)), + signed: Some((charlie(), signed_extra(1, 0))), function: RuntimeCall::Contracts(pallet_contracts::Call::call:: { dest: sp_runtime::MultiAddress::Id(addr.clone()), value: 10, diff --git a/substrate/bin/node/cli/tests/fees.rs b/substrate/bin/node/cli/tests/fees.rs index 9d6407067a3..8c7b3c87315 100644 --- a/substrate/bin/node/cli/tests/fees.rs +++ b/substrate/bin/node/cli/tests/fees.rs @@ -54,11 +54,11 @@ fn fee_multiplier_increases_and_decreases_on_big_weight() { GENESIS_HASH.into(), vec![ CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Bare, + signed: None, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time1 }), }, CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Signed(charlie(), tx_ext(0, 0)), + signed: Some((charlie(), signed_extra(0, 0))), function: RuntimeCall::Sudo(pallet_sudo::Call::sudo { call: Box::new(RuntimeCall::RootTesting( pallet_root_testing::Call::fill_block { ratio: Perbill::from_percent(60) }, @@ -77,11 +77,11 @@ fn fee_multiplier_increases_and_decreases_on_big_weight() { block1.1, vec![ CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Bare, + signed: None, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time2 }), }, CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Signed(charlie(), tx_ext(1, 0)), + signed: Some((charlie(), signed_extra(1, 0))), function: RuntimeCall::System(frame_system::Call::remark { remark: vec![0; 1] }), }, ], @@ -147,7 +147,7 @@ fn transaction_fee_is_correct() { let tip = 1_000_000; let xt = sign(CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Signed(alice(), tx_ext(0, tip)), + signed: Some((alice(), signed_extra(0, tip))), function: RuntimeCall::Balances(default_transfer_call()), }); @@ -211,10 +211,7 @@ fn block_weight_capacity_report() { let num_transfers = block_number * factor; let mut xts = (0..num_transfers) .map(|i| CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Signed( - charlie(), - tx_ext(nonce + i as Nonce, 0), - ), + signed: Some((charlie(), signed_extra(nonce + i as Nonce, 0))), function: RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { dest: bob().into(), value: 0, @@ -225,7 +222,7 @@ fn block_weight_capacity_report() { xts.insert( 0, CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Bare, + signed: None, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time * 1000 }), }, ); @@ -288,16 +285,13 @@ fn block_length_capacity_report() { previous_hash, vec![ CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Bare, + signed: None, function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time * 1000, }), }, CheckedExtrinsic { - format: sp_runtime::generic::ExtrinsicFormat::Signed( - charlie(), - tx_ext(nonce, 0), - ), + signed: Some((charlie(), signed_extra(nonce, 0))), function: RuntimeCall::System(frame_system::Call::remark { remark: vec![0u8; (block_number * factor) as usize], }), diff --git a/substrate/bin/node/cli/tests/submit_transaction.rs b/substrate/bin/node/cli/tests/submit_transaction.rs index f3a5bac8fb5..5cbb0103d47 100644 --- a/substrate/bin/node/cli/tests/submit_transaction.rs +++ b/substrate/bin/node/cli/tests/submit_transaction.rs @@ -130,8 +130,8 @@ fn should_submit_signed_twice_from_the_same_account() { // now check that the transaction nonces are not equal let s = state.read(); fn nonce(tx: UncheckedExtrinsic) -> frame_system::CheckNonce { - let extra = tx.preamble.to_signed().unwrap().2; - (extra.0).5 + let extra = tx.signature.unwrap().2; + extra.5 } let nonce1 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[0]).unwrap()); let nonce2 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[1]).unwrap()); @@ -179,8 +179,8 @@ fn should_submit_signed_twice_from_all_accounts() { // now check that the transaction nonces are not equal let s = state.read(); fn nonce(tx: UncheckedExtrinsic) -> frame_system::CheckNonce { - let extra = tx.preamble.to_signed().unwrap().2; - (extra.0).5 + let extra = tx.signature.unwrap().2; + extra.5 } let nonce1 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[0]).unwrap()); let nonce2 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[1]).unwrap()); @@ -236,7 +236,7 @@ fn submitted_transaction_should_be_valid() { let source = TransactionSource::External; let extrinsic = UncheckedExtrinsic::decode(&mut &*tx0).unwrap(); // add balance to the account - let author = extrinsic.preamble.clone().to_signed().clone().unwrap().0; + let author = extrinsic.signature.clone().unwrap().0; let address = Indices::lookup(author).unwrap(); let data = pallet_balances::AccountData { free: 5_000_000_000_000, ..Default::default() }; let account = frame_system::AccountInfo { providers: 1, data, ..Default::default() }; diff --git a/substrate/bin/node/runtime/Cargo.toml b/substrate/bin/node/runtime/Cargo.toml index 09c8fb4ed3d..4d342ceb460 100644 --- a/substrate/bin/node/runtime/Cargo.toml +++ b/substrate/bin/node/runtime/Cargo.toml @@ -276,7 +276,6 @@ runtime-benchmarks = [ "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", "pallet-alliance/runtime-benchmarks", - "pallet-asset-conversion-tx-payment/runtime-benchmarks", "pallet-asset-conversion/runtime-benchmarks", "pallet-asset-rate/runtime-benchmarks", "pallet-asset-tx-payment/runtime-benchmarks", @@ -334,7 +333,6 @@ runtime-benchmarks = [ "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-tips/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-transaction-storage/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", "pallet-tx-pause/runtime-benchmarks", diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 96611f5a144..437f76c9d5f 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -560,7 +560,6 @@ impl pallet_transaction_payment::Config for Runtime { MinimumMultiplier, MaximumMultiplier, >; - type WeightInfo = pallet_transaction_payment::weights::SubstrateWeight; } impl pallet_asset_tx_payment::Config for Runtime { @@ -570,9 +569,6 @@ impl pallet_asset_tx_payment::Config for Runtime { pallet_assets::BalanceToAssetBalance, CreditToBlockAuthor, >; - type WeightInfo = pallet_asset_tx_payment::weights::SubstrateWeight; - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = AssetTxHelper; } impl pallet_asset_conversion_tx_payment::Config for Runtime { @@ -583,9 +579,6 @@ impl pallet_asset_conversion_tx_payment::Config for Runtime { AssetConversion, Native, >; - type WeightInfo = pallet_asset_conversion_tx_payment::weights::SubstrateWeight; - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = AssetConversionTxHelper; } impl pallet_skip_feeless_payment::Config for Runtime { @@ -1416,33 +1409,29 @@ where // so the actual block number is `n`. .saturating_sub(1); let era = Era::mortal(period, current_block); - let tx_ext: TxExtension = ( - ( - frame_system::CheckNonZeroSender::::new(), - frame_system::CheckSpecVersion::::new(), - frame_system::CheckTxVersion::::new(), - frame_system::CheckGenesis::::new(), - frame_system::CheckEra::::from(era), - frame_system::CheckNonce::::from(nonce), - frame_system::CheckWeight::::new(), - ) - .into(), + let extra = ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckEra::::from(era), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), pallet_skip_feeless_payment::SkipCheckIfFeeless::from( pallet_asset_conversion_tx_payment::ChargeAssetTxPayment::::from( tip, None, ), ), ); - - let raw_payload = SignedPayload::new(call, tx_ext) + let raw_payload = SignedPayload::new(call, extra) .map_err(|e| { log::warn!("Unable to create signed payload: {:?}", e); }) .ok()?; let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?; let address = Indices::unlookup(account); - let (call, tx_ext, _) = raw_payload.deconstruct(); - Some((call, (address, signature, tx_ext))) + let (call, extra, _) = raw_payload.deconstruct(); + Some((call, (address, signature, extra))) } } @@ -2461,21 +2450,19 @@ pub type Block = generic::Block; pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The TransactionExtension to the basic transaction logic. +/// The SignedExtension to the basic transaction logic. /// /// When you change this, you **MUST** modify [`sign`] in `bin/node/testing/src/keyring.rs`! /// /// [`sign`]: <../../testing/src/keyring.rs.html> -pub type TxExtension = ( - ( - frame_system::CheckNonZeroSender, - frame_system::CheckSpecVersion, - frame_system::CheckTxVersion, - frame_system::CheckGenesis, - frame_system::CheckEra, - frame_system::CheckNonce, - frame_system::CheckWeight, - ), +pub type SignedExtra = ( + frame_system::CheckNonZeroSender, + frame_system::CheckSpecVersion, + frame_system::CheckTxVersion, + frame_system::CheckGenesis, + frame_system::CheckEra, + frame_system::CheckNonce, + frame_system::CheckWeight, pallet_skip_feeless_payment::SkipCheckIfFeeless< Runtime, pallet_asset_conversion_tx_payment::ChargeAssetTxPayment, @@ -2484,11 +2471,11 @@ pub type TxExtension = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// The payload being signed in transactions. -pub type SignedPayload = generic::SignedPayload; +pub type SignedPayload = generic::SignedPayload; /// Extrinsic type that has already been checked. -pub type CheckedExtrinsic = generic::CheckedExtrinsic; +pub type CheckedExtrinsic = generic::CheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, @@ -2543,106 +2530,6 @@ mod mmr { pub type Hashing = ::Hashing; } -#[cfg(feature = "runtime-benchmarks")] -pub struct AssetConversionTxHelper; - -#[cfg(feature = "runtime-benchmarks")] -impl pallet_asset_conversion_tx_payment::BenchmarkHelperTrait - for AssetConversionTxHelper -{ - fn create_asset_id_parameter(seed: u32) -> (u32, u32) { - (seed, seed) - } - - fn setup_balances_and_pool(asset_id: u32, account: AccountId) { - use frame_support::{assert_ok, traits::fungibles::Mutate}; - assert_ok!(Assets::force_create( - RuntimeOrigin::root(), - asset_id.into(), - account.clone().into(), /* owner */ - true, /* is_sufficient */ - 1, - )); - - let lp_provider = account.clone(); - let _ = Balances::deposit_creating(&lp_provider, ((u64::MAX as u128) * 100).into()); - assert_ok!(Assets::mint_into( - asset_id.into(), - &lp_provider, - ((u64::MAX as u128) * 100).into() - )); - - let token_native = Box::new(NativeOrWithId::Native); - let token_second = Box::new(NativeOrWithId::WithId(asset_id)); - - assert_ok!(AssetConversion::create_pool( - RuntimeOrigin::signed(lp_provider.clone()), - token_native.clone(), - token_second.clone() - )); - - assert_ok!(AssetConversion::add_liquidity( - RuntimeOrigin::signed(lp_provider.clone()), - token_native, - token_second, - u64::MAX.into(), // 1 desired - u64::MAX.into(), // 2 desired - 1, // 1 min - 1, // 2 min - lp_provider, - )); - } -} - -#[cfg(feature = "runtime-benchmarks")] -pub struct AssetTxHelper; - -#[cfg(feature = "runtime-benchmarks")] -impl pallet_asset_tx_payment::BenchmarkHelperTrait for AssetTxHelper { - fn create_asset_id_parameter(seed: u32) -> (u32, u32) { - (seed, seed) - } - - fn setup_balances_and_pool(asset_id: u32, account: AccountId) { - use frame_support::{assert_ok, traits::fungibles::Mutate}; - assert_ok!(Assets::force_create( - RuntimeOrigin::root(), - asset_id.into(), - account.clone().into(), /* owner */ - true, /* is_sufficient */ - 1, - )); - - let lp_provider = account.clone(); - let _ = Balances::deposit_creating(&lp_provider, ((u64::MAX as u128) * 100).into()); - assert_ok!(Assets::mint_into( - asset_id.into(), - &lp_provider, - ((u64::MAX as u128) * 100).into() - )); - - let token_native = Box::new(NativeOrWithId::Native); - let token_second = Box::new(NativeOrWithId::WithId(asset_id)); - - assert_ok!(AssetConversion::create_pool( - RuntimeOrigin::signed(lp_provider.clone()), - token_native.clone(), - token_second.clone() - )); - - assert_ok!(AssetConversion::add_liquidity( - RuntimeOrigin::signed(lp_provider.clone()), - token_native, - token_second, - u64::MAX.into(), // 1 desired - u64::MAX.into(), // 2 desired - 1, // 1 min - 1, // 2 min - lp_provider, - )); - } -} - #[cfg(feature = "runtime-benchmarks")] mod benches { frame_benchmarking::define_benchmarks!( @@ -2663,9 +2550,6 @@ mod benches { [tasks_example, TasksExample] [pallet_democracy, Democracy] [pallet_asset_conversion, AssetConversion] - [pallet_asset_conversion_tx_payment, AssetConversionTxPayment] - [pallet_asset_tx_payment, AssetTxPayment] - [pallet_transaction_payment, TransactionPayment] [pallet_election_provider_multi_phase, ElectionProviderMultiPhase] [pallet_election_provider_support_benchmarking, EPSBench::] [pallet_elections_phragmen, Elections] @@ -2699,7 +2583,6 @@ mod benches { [pallet_state_trie_migration, StateTrieMigration] [pallet_sudo, Sudo] [frame_system, SystemBench::] - [frame_system_extensions, SystemExtensionsBench::] [pallet_timestamp, Timestamp] [pallet_tips, Tips] [pallet_transaction_storage, TransactionStorage] @@ -3247,7 +3130,6 @@ impl_runtime_apis! { use pallet_offences_benchmarking::Pallet as OffencesBench; use pallet_election_provider_support_benchmarking::Pallet as EPSBench; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use baseline::Pallet as BaselineBench; use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench; @@ -3272,7 +3154,6 @@ impl_runtime_apis! { use pallet_offences_benchmarking::Pallet as OffencesBench; use pallet_election_provider_support_benchmarking::Pallet as EPSBench; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use baseline::Pallet as BaselineBench; use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench; diff --git a/substrate/bin/node/testing/src/bench.rs b/substrate/bin/node/testing/src/bench.rs index ccf79eed884..df302a6453b 100644 --- a/substrate/bin/node/testing/src/bench.rs +++ b/substrate/bin/node/testing/src/bench.rs @@ -51,7 +51,6 @@ use sp_core::{ed25519, sr25519, traits::SpawnNamed, Pair, Public}; use sp_crypto_hashing::blake2_256; use sp_inherents::InherentData; use sp_runtime::{ - generic::{ExtrinsicFormat, Preamble}, traits::{Block as BlockT, IdentifyAccount, Verify}, OpaqueExtrinsic, }; @@ -296,10 +295,10 @@ impl<'a> Iterator for BlockContentIterator<'a> { let signed = self.keyring.sign( CheckedExtrinsic { - format: ExtrinsicFormat::Signed( + signed: Some(( sender, - tx_ext(0, kitchensink_runtime::ExistentialDeposit::get() + 1), - ), + signed_extra(0, kitchensink_runtime::ExistentialDeposit::get() + 1), + )), function: match self.content.block_type { BlockType::RandomTransfersKeepAlive => RuntimeCall::Balances(BalancesCall::transfer_keep_alive { @@ -563,11 +562,11 @@ impl BenchKeyring { tx_version: u32, genesis_hash: [u8; 32], ) -> UncheckedExtrinsic { - match xt.format { - ExtrinsicFormat::Signed(signed, tx_ext) => { + match xt.signed { + Some((signed, extra)) => { let payload = ( xt.function, - tx_ext.clone(), + extra.clone(), spec_version, tx_version, genesis_hash, @@ -582,20 +581,11 @@ impl BenchKeyring { } }); UncheckedExtrinsic { - preamble: Preamble::Signed( - sp_runtime::MultiAddress::Id(signed), - signature, - tx_ext, - ), + signature: Some((sp_runtime::MultiAddress::Id(signed), signature, extra)), function: payload.0, } }, - ExtrinsicFormat::Bare => - UncheckedExtrinsic { preamble: Preamble::Bare, function: xt.function }, - ExtrinsicFormat::General(tx_ext) => UncheckedExtrinsic { - preamble: sp_runtime::generic::Preamble::General(tx_ext), - function: xt.function, - }, + None => UncheckedExtrinsic { signature: None, function: xt.function }, } } diff --git a/substrate/bin/node/testing/src/keyring.rs b/substrate/bin/node/testing/src/keyring.rs index 13daf915325..f712191bed6 100644 --- a/substrate/bin/node/testing/src/keyring.rs +++ b/substrate/bin/node/testing/src/keyring.rs @@ -19,13 +19,13 @@ //! Test accounts. use codec::Encode; -use kitchensink_runtime::{CheckedExtrinsic, SessionKeys, TxExtension, UncheckedExtrinsic}; +use kitchensink_runtime::{CheckedExtrinsic, SessionKeys, SignedExtra, UncheckedExtrinsic}; use node_cli::chain_spec::get_from_seed; use node_primitives::{AccountId, Balance, Nonce}; use sp_core::{ecdsa, ed25519, sr25519}; use sp_crypto_hashing::blake2_256; use sp_keyring::AccountKeyring; -use sp_runtime::generic::{Era, ExtrinsicFormat}; +use sp_runtime::generic::Era; /// Alice's account id. pub fn alice() -> AccountId { @@ -70,18 +70,15 @@ pub fn session_keys_from_seed(seed: &str) -> SessionKeys { } /// Returns transaction extra. -pub fn tx_ext(nonce: Nonce, extra_fee: Balance) -> TxExtension { +pub fn signed_extra(nonce: Nonce, extra_fee: Balance) -> SignedExtra { ( - ( - frame_system::CheckNonZeroSender::new(), - frame_system::CheckSpecVersion::new(), - frame_system::CheckTxVersion::new(), - frame_system::CheckGenesis::new(), - frame_system::CheckEra::from(Era::mortal(256, 0)), - frame_system::CheckNonce::from(nonce), - frame_system::CheckWeight::new(), - ) - .into(), + frame_system::CheckNonZeroSender::new(), + frame_system::CheckSpecVersion::new(), + frame_system::CheckTxVersion::new(), + frame_system::CheckGenesis::new(), + frame_system::CheckEra::from(Era::mortal(256, 0)), + frame_system::CheckNonce::from(nonce), + frame_system::CheckWeight::new(), pallet_skip_feeless_payment::SkipCheckIfFeeless::from( pallet_asset_conversion_tx_payment::ChargeAssetTxPayment::from(extra_fee, None), ), @@ -95,10 +92,10 @@ pub fn sign( tx_version: u32, genesis_hash: [u8; 32], ) -> UncheckedExtrinsic { - match xt.format { - ExtrinsicFormat::Signed(signed, tx_ext) => { + match xt.signed { + Some((signed, extra)) => { let payload = - (xt.function, tx_ext.clone(), spec_version, tx_version, genesis_hash, genesis_hash); + (xt.function, extra.clone(), spec_version, tx_version, genesis_hash, genesis_hash); let key = AccountKeyring::from_account_id(&signed).unwrap(); let signature = payload @@ -111,21 +108,10 @@ pub fn sign( }) .into(); UncheckedExtrinsic { - preamble: sp_runtime::generic::Preamble::Signed( - sp_runtime::MultiAddress::Id(signed), - signature, - tx_ext, - ), + signature: Some((sp_runtime::MultiAddress::Id(signed), signature, extra)), function: payload.0, } }, - ExtrinsicFormat::Bare => UncheckedExtrinsic { - preamble: sp_runtime::generic::Preamble::Bare, - function: xt.function, - }, - ExtrinsicFormat::General(tx_ext) => UncheckedExtrinsic { - preamble: sp_runtime::generic::Preamble::General(tx_ext), - function: xt.function, - }, + None => UncheckedExtrinsic { signature: None, function: xt.function }, } } diff --git a/substrate/client/api/src/notifications/tests.rs b/substrate/client/api/src/notifications/tests.rs index 7afdcbd9543..fba829b1cf9 100644 --- a/substrate/client/api/src/notifications/tests.rs +++ b/substrate/client/api/src/notifications/tests.rs @@ -18,10 +18,7 @@ use super::*; -use sp_runtime::{ - generic::UncheckedExtrinsic, - testing::{Block as RawBlock, H256 as Hash}, -}; +use sp_runtime::testing::{Block as RawBlock, ExtrinsicWrapper, H256 as Hash}; use std::iter::{empty, Empty}; type TestChangeSet = ( @@ -53,7 +50,7 @@ impl PartialEq for StorageChangeSet { } } -type Block = RawBlock>; +type Block = RawBlock>; #[test] fn triggering_change_should_notify_wildcard_listeners() { diff --git a/substrate/client/db/benches/state_access.rs b/substrate/client/db/benches/state_access.rs index 9f3b8ca77c2..e47559e710d 100644 --- a/substrate/client/db/benches/state_access.rs +++ b/substrate/client/db/benches/state_access.rs @@ -22,13 +22,12 @@ use sc_client_api::{Backend as _, BlockImportOperation, NewBlockState, StateBack use sc_client_db::{Backend, BlocksPruning, DatabaseSettings, DatabaseSource, PruningMode}; use sp_core::H256; use sp_runtime::{ - generic::UncheckedExtrinsic, - testing::{Block as RawBlock, Header, MockCallU64}, + testing::{Block as RawBlock, ExtrinsicWrapper, Header}, StateVersion, Storage, }; use tempfile::TempDir; -pub(crate) type Block = RawBlock>; +pub(crate) type Block = RawBlock>; fn insert_blocks(db: &Backend, storage: Vec<(Vec, Vec)>) -> H256 { let mut op = db.begin_operation().unwrap(); diff --git a/substrate/client/db/src/lib.rs b/substrate/client/db/src/lib.rs index f22022ef29a..0faa90dfc4f 100644 --- a/substrate/client/db/src/lib.rs +++ b/substrate/client/db/src/lib.rs @@ -2573,8 +2573,7 @@ pub(crate) mod tests { use sp_blockchain::{lowest_common_ancestor, tree_route}; use sp_core::H256; use sp_runtime::{ - generic::UncheckedExtrinsic, - testing::{Block as RawBlock, Header, MockCallU64}, + testing::{Block as RawBlock, ExtrinsicWrapper, Header}, traits::{BlakeTwo256, Hash}, ConsensusEngineId, StateVersion, }; @@ -2582,8 +2581,7 @@ pub(crate) mod tests { const CONS0_ENGINE_ID: ConsensusEngineId = *b"CON0"; const CONS1_ENGINE_ID: ConsensusEngineId = *b"CON1"; - type UncheckedXt = UncheckedExtrinsic; - pub(crate) type Block = RawBlock; + pub(crate) type Block = RawBlock>; pub fn insert_header( backend: &Backend, @@ -2602,7 +2600,7 @@ pub(crate) mod tests { parent_hash: H256, _changes: Option, Vec)>>, extrinsics_root: H256, - body: Vec, + body: Vec>, transaction_index: Option>, ) -> Result { use sp_runtime::testing::Digest; @@ -3416,7 +3414,7 @@ pub(crate) mod tests { prev_hash, None, Default::default(), - vec![UncheckedXt::new_transaction(i.into(), ())], + vec![i.into()], None, ) .unwrap(); @@ -3438,20 +3436,11 @@ pub(crate) mod tests { assert_eq!(None, bc.body(blocks[0]).unwrap()); assert_eq!(None, bc.body(blocks[1]).unwrap()); assert_eq!(None, bc.body(blocks[2]).unwrap()); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(3.into(), ())]), - bc.body(blocks[3]).unwrap() - ); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(4.into(), ())]), - bc.body(blocks[4]).unwrap() - ); + assert_eq!(Some(vec![3.into()]), bc.body(blocks[3]).unwrap()); + assert_eq!(Some(vec![4.into()]), bc.body(blocks[4]).unwrap()); } else { for i in 0..5 { - assert_eq!( - Some(vec![UncheckedXt::new_transaction((i as u64).into(), ())]), - bc.body(blocks[i]).unwrap() - ); + assert_eq!(Some(vec![(i as u64).into()]), bc.body(blocks[i]).unwrap()); } } } @@ -3475,7 +3464,7 @@ pub(crate) mod tests { prev_hash, None, Default::default(), - vec![UncheckedXt::new_transaction(i.into(), ())], + vec![i.into()], None, ) .unwrap(); @@ -3484,26 +3473,16 @@ pub(crate) mod tests { } // insert a fork at block 2 - let fork_hash_root = insert_block( - &backend, - 2, - blocks[1], - None, - H256::random(), - vec![UncheckedXt::new_transaction(2.into(), ())], - None, - ) - .unwrap(); + let fork_hash_root = + insert_block(&backend, 2, blocks[1], None, H256::random(), vec![2.into()], None) + .unwrap(); insert_block( &backend, 3, fork_hash_root, None, H256::random(), - vec![ - UncheckedXt::new_transaction(3.into(), ()), - UncheckedXt::new_transaction(11.into(), ()), - ], + vec![3.into(), 11.into()], None, ) .unwrap(); @@ -3513,10 +3492,7 @@ pub(crate) mod tests { backend.commit_operation(op).unwrap(); let bc = backend.blockchain(); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(2.into(), ())]), - bc.body(fork_hash_root).unwrap() - ); + assert_eq!(Some(vec![2.into()]), bc.body(fork_hash_root).unwrap()); for i in 1..5 { let mut op = backend.begin_operation().unwrap(); @@ -3530,28 +3506,16 @@ pub(crate) mod tests { assert_eq!(None, bc.body(blocks[1]).unwrap()); assert_eq!(None, bc.body(blocks[2]).unwrap()); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(3.into(), ())]), - bc.body(blocks[3]).unwrap() - ); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(4.into(), ())]), - bc.body(blocks[4]).unwrap() - ); + assert_eq!(Some(vec![3.into()]), bc.body(blocks[3]).unwrap()); + assert_eq!(Some(vec![4.into()]), bc.body(blocks[4]).unwrap()); } else { for i in 0..5 { - assert_eq!( - Some(vec![UncheckedXt::new_transaction((i as u64).into(), ())]), - bc.body(blocks[i]).unwrap() - ); + assert_eq!(Some(vec![(i as u64).into()]), bc.body(blocks[i]).unwrap()); } } if matches!(pruning, BlocksPruning::KeepAll) { - assert_eq!( - Some(vec![UncheckedXt::new_transaction(2.into(), ())]), - bc.body(fork_hash_root).unwrap() - ); + assert_eq!(Some(vec![2.into()]), bc.body(fork_hash_root).unwrap()); } else { assert_eq!(None, bc.body(fork_hash_root).unwrap()); } @@ -3572,16 +3536,8 @@ pub(crate) mod tests { let backend = Backend::::new_test_with_tx_storage(BlocksPruning::Some(10), 10); let make_block = |index, parent, val: u64| { - insert_block( - &backend, - index, - parent, - None, - H256::random(), - vec![UncheckedXt::new_transaction(val.into(), ())], - None, - ) - .unwrap() + insert_block(&backend, index, parent, None, H256::random(), vec![val.into()], None) + .unwrap() }; let block_0 = make_block(0, Default::default(), 0x00); @@ -3609,30 +3565,18 @@ pub(crate) mod tests { let bc = backend.blockchain(); assert_eq!(None, bc.body(block_1b).unwrap()); assert_eq!(None, bc.body(block_2b).unwrap()); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(0x00.into(), ())]), - bc.body(block_0).unwrap() - ); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(0x1a.into(), ())]), - bc.body(block_1a).unwrap() - ); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(0x2a.into(), ())]), - bc.body(block_2a).unwrap() - ); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(0x3a.into(), ())]), - bc.body(block_3a).unwrap() - ); + assert_eq!(Some(vec![0x00.into()]), bc.body(block_0).unwrap()); + assert_eq!(Some(vec![0x1a.into()]), bc.body(block_1a).unwrap()); + assert_eq!(Some(vec![0x2a.into()]), bc.body(block_2a).unwrap()); + assert_eq!(Some(vec![0x3a.into()]), bc.body(block_3a).unwrap()); } #[test] fn indexed_data_block_body() { let backend = Backend::::new_test_with_tx_storage(BlocksPruning::Some(1), 10); - let x0 = UncheckedXt::new_transaction(0.into(), ()).encode(); - let x1 = UncheckedXt::new_transaction(1.into(), ()).encode(); + let x0 = ExtrinsicWrapper::from(0u64).encode(); + let x1 = ExtrinsicWrapper::from(1u64).encode(); let x0_hash = as sp_core::Hasher>::hash(&x0[1..]); let x1_hash = as sp_core::Hasher>::hash(&x1[1..]); let index = vec![ @@ -3653,10 +3597,7 @@ pub(crate) mod tests { Default::default(), None, Default::default(), - vec![ - UncheckedXt::new_transaction(0.into(), ()), - UncheckedXt::new_transaction(1.into(), ()), - ], + vec![0u64.into(), 1u64.into()], Some(index), ) .unwrap(); @@ -3678,9 +3619,8 @@ pub(crate) mod tests { fn index_invalid_size() { let backend = Backend::::new_test_with_tx_storage(BlocksPruning::Some(1), 10); - let x0 = UncheckedXt::new_transaction(0.into(), ()).encode(); - let x1 = UncheckedXt::new_transaction(1.into(), ()).encode(); - + let x0 = ExtrinsicWrapper::from(0u64).encode(); + let x1 = ExtrinsicWrapper::from(1u64).encode(); let x0_hash = as sp_core::Hasher>::hash(&x0[..]); let x1_hash = as sp_core::Hasher>::hash(&x1[..]); let index = vec![ @@ -3701,10 +3641,7 @@ pub(crate) mod tests { Default::default(), None, Default::default(), - vec![ - UncheckedXt::new_transaction(0.into(), ()), - UncheckedXt::new_transaction(1.into(), ()), - ], + vec![0u64.into(), 1u64.into()], Some(index), ) .unwrap(); @@ -3718,7 +3655,7 @@ pub(crate) mod tests { let backend = Backend::::new_test_with_tx_storage(BlocksPruning::Some(2), 10); let mut blocks = Vec::new(); let mut prev_hash = Default::default(); - let x1 = UncheckedXt::new_transaction(0.into(), ()).encode(); + let x1 = ExtrinsicWrapper::from(0u64).encode(); let x1_hash = as sp_core::Hasher>::hash(&x1[1..]); for i in 0..10 { let mut index = Vec::new(); @@ -3738,7 +3675,7 @@ pub(crate) mod tests { prev_hash, None, Default::default(), - vec![UncheckedXt::new_transaction(i.into(), ())], + vec![i.into()], Some(index), ) .unwrap(); @@ -3772,7 +3709,7 @@ pub(crate) mod tests { prev_hash, None, Default::default(), - vec![UncheckedXt::new_transaction(i.into(), ())], + vec![i.into()], None, ) .unwrap(); @@ -3787,7 +3724,7 @@ pub(crate) mod tests { blocks[1], None, sp_core::H256::random(), - vec![UncheckedXt::new_transaction(i.into(), ())], + vec![i.into()], None, ) .unwrap(); @@ -3801,7 +3738,7 @@ pub(crate) mod tests { blocks[0], None, sp_core::H256::random(), - vec![UncheckedXt::new_transaction(42.into(), ())], + vec![42.into()], None, ) .unwrap(); @@ -4274,7 +4211,7 @@ pub(crate) mod tests { prev_hash, None, Default::default(), - vec![UncheckedXt::new_transaction(i.into(), ())], + vec![i.into()], None, ) .unwrap(); @@ -4289,10 +4226,7 @@ pub(crate) mod tests { // Check that we can properly access values when there is reference count // but no value. - assert_eq!( - Some(vec![UncheckedXt::new_transaction(1.into(), ())]), - bc.body(blocks[1]).unwrap() - ); + assert_eq!(Some(vec![1.into()]), bc.body(blocks[1]).unwrap()); // Block 1 gets pinned three times backend.pin_block(blocks[1]).unwrap(); @@ -4309,42 +4243,27 @@ pub(crate) mod tests { // Block 0, 1, 2, 3 are pinned, so all values should be cached. // Block 4 is inside the pruning window, its value is in db. - assert_eq!( - Some(vec![UncheckedXt::new_transaction(0.into(), ())]), - bc.body(blocks[0]).unwrap() - ); + assert_eq!(Some(vec![0.into()]), bc.body(blocks[0]).unwrap()); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(1.into(), ())]), - bc.body(blocks[1]).unwrap() - ); + assert_eq!(Some(vec![1.into()]), bc.body(blocks[1]).unwrap()); assert_eq!( Some(Justifications::from(build_justification(1))), bc.justifications(blocks[1]).unwrap() ); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(2.into(), ())]), - bc.body(blocks[2]).unwrap() - ); + assert_eq!(Some(vec![2.into()]), bc.body(blocks[2]).unwrap()); assert_eq!( Some(Justifications::from(build_justification(2))), bc.justifications(blocks[2]).unwrap() ); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(3.into(), ())]), - bc.body(blocks[3]).unwrap() - ); + assert_eq!(Some(vec![3.into()]), bc.body(blocks[3]).unwrap()); assert_eq!( Some(Justifications::from(build_justification(3))), bc.justifications(blocks[3]).unwrap() ); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(4.into(), ())]), - bc.body(blocks[4]).unwrap() - ); + assert_eq!(Some(vec![4.into()]), bc.body(blocks[4]).unwrap()); assert_eq!( Some(Justifications::from(build_justification(4))), bc.justifications(blocks[4]).unwrap() @@ -4375,10 +4294,7 @@ pub(crate) mod tests { assert!(bc.justifications(blocks[1]).unwrap().is_none()); // Block 4 is inside the pruning window and still kept - assert_eq!( - Some(vec![UncheckedXt::new_transaction(4.into(), ())]), - bc.body(blocks[4]).unwrap() - ); + assert_eq!(Some(vec![4.into()]), bc.body(blocks[4]).unwrap()); assert_eq!( Some(Justifications::from(build_justification(4))), bc.justifications(blocks[4]).unwrap() @@ -4386,16 +4302,9 @@ pub(crate) mod tests { // Block tree: // 0 -> 1 -> 2 -> 3 -> 4 -> 5 - let hash = insert_block( - &backend, - 5, - prev_hash, - None, - Default::default(), - vec![UncheckedXt::new_transaction(5.into(), ())], - None, - ) - .unwrap(); + let hash = + insert_block(&backend, 5, prev_hash, None, Default::default(), vec![5.into()], None) + .unwrap(); blocks.push(hash); backend.pin_block(blocks[4]).unwrap(); @@ -4410,18 +4319,12 @@ pub(crate) mod tests { assert!(bc.body(blocks[2]).unwrap().is_none()); assert!(bc.body(blocks[3]).unwrap().is_none()); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(4.into(), ())]), - bc.body(blocks[4]).unwrap() - ); + assert_eq!(Some(vec![4.into()]), bc.body(blocks[4]).unwrap()); assert_eq!( Some(Justifications::from(build_justification(4))), bc.justifications(blocks[4]).unwrap() ); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(5.into(), ())]), - bc.body(blocks[5]).unwrap() - ); + assert_eq!(Some(vec![5.into()]), bc.body(blocks[5]).unwrap()); assert!(bc.header(blocks[5]).ok().flatten().is_some()); backend.unpin_block(blocks[4]); @@ -4431,16 +4334,9 @@ pub(crate) mod tests { // Append a justification to block 5. backend.append_justification(blocks[5], ([0, 0, 0, 1], vec![42])).unwrap(); - let hash = insert_block( - &backend, - 6, - blocks[5], - None, - Default::default(), - vec![UncheckedXt::new_transaction(6.into(), ())], - None, - ) - .unwrap(); + let hash = + insert_block(&backend, 6, blocks[5], None, Default::default(), vec![6.into()], None) + .unwrap(); blocks.push(hash); // Pin block 5 so it gets loaded into the cache on prune @@ -4453,10 +4349,7 @@ pub(crate) mod tests { op.mark_finalized(blocks[6], None).unwrap(); backend.commit_operation(op).unwrap(); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(5.into(), ())]), - bc.body(blocks[5]).unwrap() - ); + assert_eq!(Some(vec![5.into()]), bc.body(blocks[5]).unwrap()); assert!(bc.header(blocks[5]).ok().flatten().is_some()); let mut expected = Justifications::from(build_justification(5)); expected.append(([0, 0, 0, 1], vec![42])); @@ -4478,7 +4371,7 @@ pub(crate) mod tests { prev_hash, None, Default::default(), - vec![UncheckedXt::new_transaction(i.into(), ())], + vec![i.into()], None, ) .unwrap(); @@ -4494,26 +4387,16 @@ pub(crate) mod tests { // Block tree: // 0 -> 1 -> 2 -> 3 -> 4 // \ -> 2 -> 3 - let fork_hash_root = insert_block( - &backend, - 2, - blocks[1], - None, - H256::random(), - vec![UncheckedXt::new_transaction(2.into(), ())], - None, - ) - .unwrap(); + let fork_hash_root = + insert_block(&backend, 2, blocks[1], None, H256::random(), vec![2.into()], None) + .unwrap(); let fork_hash_3 = insert_block( &backend, 3, fork_hash_root, None, H256::random(), - vec![ - UncheckedXt::new_transaction(3.into(), ()), - UncheckedXt::new_transaction(11.into(), ()), - ], + vec![3.into(), 11.into()], None, ) .unwrap(); @@ -4534,35 +4417,14 @@ pub(crate) mod tests { } let bc = backend.blockchain(); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(0.into(), ())]), - bc.body(blocks[0]).unwrap() - ); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(1.into(), ())]), - bc.body(blocks[1]).unwrap() - ); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(2.into(), ())]), - bc.body(blocks[2]).unwrap() - ); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(3.into(), ())]), - bc.body(blocks[3]).unwrap() - ); - assert_eq!( - Some(vec![UncheckedXt::new_transaction(4.into(), ())]), - bc.body(blocks[4]).unwrap() - ); + assert_eq!(Some(vec![0.into()]), bc.body(blocks[0]).unwrap()); + assert_eq!(Some(vec![1.into()]), bc.body(blocks[1]).unwrap()); + assert_eq!(Some(vec![2.into()]), bc.body(blocks[2]).unwrap()); + assert_eq!(Some(vec![3.into()]), bc.body(blocks[3]).unwrap()); + assert_eq!(Some(vec![4.into()]), bc.body(blocks[4]).unwrap()); // Check the fork hashes. assert_eq!(None, bc.body(fork_hash_root).unwrap()); - assert_eq!( - Some(vec![ - UncheckedXt::new_transaction(3.into(), ()), - UncheckedXt::new_transaction(11.into(), ()) - ]), - bc.body(fork_hash_3).unwrap() - ); + assert_eq!(Some(vec![3.into(), 11.into()]), bc.body(fork_hash_3).unwrap()); // Unpin all blocks, except the forked one. for block in &blocks { diff --git a/substrate/client/db/src/utils.rs b/substrate/client/db/src/utils.rs index d2a5f7e718a..abf9c4629ce 100644 --- a/substrate/client/db/src/utils.rs +++ b/substrate/client/db/src/utils.rs @@ -582,19 +582,14 @@ impl<'a, 'b> codec::Input for JoinInput<'a, 'b> { mod tests { use super::*; use codec::Input; - use sp_runtime::{ - generic::UncheckedExtrinsic, - testing::{Block as RawBlock, MockCallU64}, - }; - - pub type UncheckedXt = UncheckedExtrinsic; - type Block = RawBlock; + use sp_runtime::testing::{Block as RawBlock, ExtrinsicWrapper}; + type Block = RawBlock>; #[cfg(feature = "rocksdb")] #[test] fn database_type_subdir_migration() { use std::path::PathBuf; - type Block = RawBlock; + type Block = RawBlock>; fn check_dir_for_db_type( db_type: DatabaseType, diff --git a/substrate/client/network-gossip/src/state_machine.rs b/substrate/client/network-gossip/src/state_machine.rs index f1c830341ea..069d7cdba16 100644 --- a/substrate/client/network-gossip/src/state_machine.rs +++ b/substrate/client/network-gossip/src/state_machine.rs @@ -550,8 +550,7 @@ mod tests { NotificationSenderError, NotificationSenderT as NotificationSender, ReputationChange, }; use sp_runtime::{ - generic::UncheckedExtrinsic, - testing::{Block as RawBlock, MockCallU64, H256}, + testing::{Block as RawBlock, ExtrinsicWrapper, H256}, traits::NumberFor, }; use std::{ @@ -560,7 +559,7 @@ mod tests { sync::{Arc, Mutex}, }; - type Block = RawBlock>; + type Block = RawBlock>; macro_rules! push_msg { ($consensus:expr, $topic:expr, $hash: expr, $m:expr) => { diff --git a/substrate/client/network/sync/src/blocks.rs b/substrate/client/network/sync/src/blocks.rs index a115ee94767..4988045a478 100644 --- a/substrate/client/network/sync/src/blocks.rs +++ b/substrate/client/network/sync/src/blocks.rs @@ -265,12 +265,9 @@ mod test { use libp2p::PeerId; use sc_network_common::sync::message; use sp_core::H256; - use sp_runtime::{ - generic::UncheckedExtrinsic, - testing::{Block as RawBlock, MockCallU64}, - }; + use sp_runtime::testing::{Block as RawBlock, ExtrinsicWrapper}; - type Block = RawBlock>; + type Block = RawBlock>; fn is_empty(bc: &BlockCollection) -> bool { bc.blocks.is_empty() && bc.peer_requests.is_empty() diff --git a/substrate/client/transaction-pool/src/lib.rs b/substrate/client/transaction-pool/src/lib.rs index 730cfe36712..64b301e6bf3 100644 --- a/substrate/client/transaction-pool/src/lib.rs +++ b/substrate/client/transaction-pool/src/lib.rs @@ -659,13 +659,8 @@ where }) .unwrap_or_default() .into_iter() - // TODO [#2415]: This isn't really what we mean - we really want a - // `tx.is_transaction`, since bare transactions may be gossipped as in the case - // of Frontier txs or claims. This will be sorted once we dispense with the - // concept of bare transactions and make inherents the only possible type of - // extrinsics which are bare. At this point we can change this to - // `tx.is_transaction()`. - .filter(|tx| !tx.is_bare()); + .filter(|tx| tx.is_signed().unwrap_or(true)); + let mut resubmitted_to_report = 0; resubmit_transactions.extend(block_transactions.into_iter().filter(|tx| { diff --git a/substrate/frame/alliance/src/weights.rs b/substrate/frame/alliance/src/weights.rs index 0b2d1fca43c..b5bb5095720 100644 --- a/substrate/frame/alliance/src/weights.rs +++ b/substrate/frame/alliance/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_alliance` +//! Autogenerated weights for pallet_alliance //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/alliance/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/alliance/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_alliance`. +/// Weight functions needed for pallet_alliance. pub trait WeightInfo { fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight; fn vote(m: u32, ) -> Weight; @@ -73,209 +74,205 @@ pub trait WeightInfo { fn abdicate_fellow_status() -> Weight; } -/// Weights for `pallet_alliance` using the Substrate node and recommended hardware. +/// Weights for pallet_alliance using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Alliance::Members` (r:1 w:0) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::ProposalOf` (r:1 w:1) - /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:1) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::ProposalCount` (r:1 w:1) - /// Proof: `AllianceMotion::ProposalCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Voting` (r:0 w:1) - /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:1 w:0) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion ProposalOf (r:1 w:1) + /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: AllianceMotion Proposals (r:1 w:1) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion ProposalCount (r:1 w:1) + /// Proof Skipped: AllianceMotion ProposalCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Voting (r:0 w:1) + /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) /// The range of component `b` is `[1, 1024]`. /// The range of component `m` is `[2, 100]`. /// The range of component `p` is `[1, 100]`. fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `654 + m * (32 ±0) + p * (36 ±0)` + // Measured: `653 + m * (32 ±0) + p * (35 ±0)` // Estimated: `6676 + m * (32 ±0) + p * (36 ±0)` - // Minimum execution time: 30_801_000 picoseconds. - Weight::from_parts(32_942_969, 6676) - // Standard Error: 112 - .saturating_add(Weight::from_parts(614, 0).saturating_mul(b.into())) - // Standard Error: 1_177 - .saturating_add(Weight::from_parts(45_758, 0).saturating_mul(m.into())) - // Standard Error: 1_162 - .saturating_add(Weight::from_parts(136_600, 0).saturating_mul(p.into())) + // Minimum execution time: 36_908_000 picoseconds. + Weight::from_parts(39_040_304, 6676) + // Standard Error: 131 + .saturating_add(Weight::from_parts(781, 0).saturating_mul(b.into())) + // Standard Error: 1_375 + .saturating_add(Weight::from_parts(48_745, 0).saturating_mul(m.into())) + // Standard Error: 1_358 + .saturating_add(Weight::from_parts(148_047, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: `Alliance::Members` (r:1 w:0) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Voting` (r:1 w:1) - /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:1 w:0) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Voting (r:1 w:1) + /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) /// The range of component `m` is `[5, 100]`. fn vote(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1113 + m * (64 ±0)` + // Measured: `1042 + m * (64 ±0)` // Estimated: `6676 + m * (64 ±0)` - // Minimum execution time: 29_705_000 picoseconds. - Weight::from_parts(30_274_070, 6676) - // Standard Error: 884 - .saturating_add(Weight::from_parts(71_178, 0).saturating_mul(m.into())) + // Minimum execution time: 30_166_000 picoseconds. + Weight::from_parts(32_798_454, 6676) + // Standard Error: 1_432 + .saturating_add(Weight::from_parts(83_001, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: `Alliance::Members` (r:1 w:0) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Voting` (r:1 w:1) - /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Members` (r:1 w:0) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:1) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::ProposalOf` (r:0 w:1) - /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:1 w:0) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Voting (r:1 w:1) + /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: AllianceMotion Members (r:1 w:0) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Proposals (r:1 w:1) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion ProposalOf (r:0 w:1) + /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_early_disapproved(m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `640 + m * (96 ±0) + p * (36 ±0)` + // Measured: `576 + m * (96 ±0) + p * (36 ±0)` // Estimated: `6676 + m * (97 ±0) + p * (36 ±0)` - // Minimum execution time: 38_596_000 picoseconds. - Weight::from_parts(36_445_536, 6676) - // Standard Error: 1_217 - .saturating_add(Weight::from_parts(69_976, 0).saturating_mul(m.into())) - // Standard Error: 1_187 - .saturating_add(Weight::from_parts(149_706, 0).saturating_mul(p.into())) + // Minimum execution time: 45_173_000 picoseconds. + Weight::from_parts(42_192_020, 6676) + // Standard Error: 1_456 + .saturating_add(Weight::from_parts(66_751, 0).saturating_mul(m.into())) + // Standard Error: 1_420 + .saturating_add(Weight::from_parts(158_161, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 97).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: `Alliance::Members` (r:1 w:0) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Voting` (r:1 w:1) - /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Members` (r:1 w:0) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::ProposalOf` (r:1 w:1) - /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:1) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:1 w:0) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Voting (r:1 w:1) + /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: AllianceMotion Members (r:1 w:0) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion ProposalOf (r:1 w:1) + /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: AllianceMotion Proposals (r:1 w:1) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `b` is `[1, 1024]`. /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1220 + m * (96 ±0) + p * (39 ±0)` + // Measured: `1087 + m * (96 ±0) + p * (39 ±0)` // Estimated: `6676 + m * (97 ±0) + p * (40 ±0)` - // Minimum execution time: 57_602_000 picoseconds. - Weight::from_parts(55_147_214, 6676) - // Standard Error: 127 - .saturating_add(Weight::from_parts(1_650, 0).saturating_mul(b.into())) - // Standard Error: 1_346 - .saturating_add(Weight::from_parts(56_056, 0).saturating_mul(m.into())) - // Standard Error: 1_312 - .saturating_add(Weight::from_parts(168_247, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(7_u64)) + // Minimum execution time: 58_290_000 picoseconds. + Weight::from_parts(54_924_919, 6676) + // Standard Error: 157 + .saturating_add(Weight::from_parts(464, 0).saturating_mul(b.into())) + // Standard Error: 1_665 + .saturating_add(Weight::from_parts(73_183, 0).saturating_mul(m.into())) + // Standard Error: 1_623 + .saturating_add(Weight::from_parts(168_318, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 97).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) } - /// Storage: `Alliance::Members` (r:1 w:0) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Voting` (r:1 w:1) - /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Members` (r:1 w:0) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Prime` (r:1 w:0) - /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:1) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::ProposalOf` (r:0 w:1) - /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:1 w:0) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Voting (r:1 w:1) + /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: AllianceMotion Members (r:1 w:0) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Prime (r:1 w:0) + /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Proposals (r:1 w:1) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion ProposalOf (r:0 w:1) + /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) /// The range of component `m` is `[2, 100]`. /// The range of component `p` is `[1, 100]`. fn close_disapproved(m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `641 + m * (96 ±0) + p * (36 ±0)` + // Measured: `577 + m * (96 ±0) + p * (36 ±0)` // Estimated: `6676 + m * (97 ±0) + p * (36 ±0)` - // Minimum execution time: 40_755_000 picoseconds. - Weight::from_parts(36_953_935, 6676) - // Standard Error: 1_177 - .saturating_add(Weight::from_parts(73_240, 0).saturating_mul(m.into())) - // Standard Error: 1_162 - .saturating_add(Weight::from_parts(149_412, 0).saturating_mul(p.into())) + // Minimum execution time: 46_794_000 picoseconds. + Weight::from_parts(43_092_958, 6676) + // Standard Error: 1_273 + .saturating_add(Weight::from_parts(71_054, 0).saturating_mul(m.into())) + // Standard Error: 1_257 + .saturating_add(Weight::from_parts(152_820, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 97).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: `Alliance::Members` (r:1 w:0) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Voting` (r:1 w:1) - /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Members` (r:1 w:0) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Prime` (r:1 w:0) - /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:1) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::ProposalOf` (r:0 w:1) - /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:1 w:0) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Voting (r:1 w:1) + /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: AllianceMotion Members (r:1 w:0) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Prime (r:1 w:0) + /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Proposals (r:1 w:1) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion ProposalOf (r:0 w:1) + /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) /// The range of component `b` is `[1, 1024]`. /// The range of component `m` is `[5, 100]`. /// The range of component `p` is `[1, 100]`. fn close_approved(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `694 + m * (96 ±0) + p * (35 ±0)` + // Measured: `684 + m * (96 ±0) + p * (35 ±0)` // Estimated: `6676 + m * (97 ±0) + p * (36 ±0)` - // Minimum execution time: 41_113_000 picoseconds. - Weight::from_parts(36_610_116, 6676) - // Standard Error: 92 - .saturating_add(Weight::from_parts(1_157, 0).saturating_mul(b.into())) - // Standard Error: 984 - .saturating_add(Weight::from_parts(63_050, 0).saturating_mul(m.into())) - // Standard Error: 949 - .saturating_add(Weight::from_parts(150_420, 0).saturating_mul(p.into())) + // Minimum execution time: 47_338_000 picoseconds. + Weight::from_parts(41_257_479, 6676) + // Standard Error: 119 + .saturating_add(Weight::from_parts(1_019, 0).saturating_mul(b.into())) + // Standard Error: 1_277 + .saturating_add(Weight::from_parts(78_453, 0).saturating_mul(m.into())) + // Standard Error: 1_231 + .saturating_add(Weight::from_parts(150_991, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 97).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: `Alliance::Members` (r:2 w:2) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Members` (r:1 w:1) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:2 w:2) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Members (r:1 w:1) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `m` is `[1, 100]`. /// The range of component `z` is `[0, 100]`. fn init_members(m: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `250` + // Measured: `217` // Estimated: `12362` - // Minimum execution time: 30_249_000 picoseconds. - Weight::from_parts(21_364_868, 12362) - // Standard Error: 887 - .saturating_add(Weight::from_parts(131_624, 0).saturating_mul(m.into())) - // Standard Error: 877 - .saturating_add(Weight::from_parts(105_379, 0).saturating_mul(z.into())) + // Minimum execution time: 35_012_000 picoseconds. + Weight::from_parts(24_288_079, 12362) + // Standard Error: 878 + .saturating_add(Weight::from_parts(153_615, 0).saturating_mul(m.into())) + // Standard Error: 867 + .saturating_add(Weight::from_parts(129_307, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Alliance::Members` (r:2 w:2) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:0) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Alliance::DepositOf` (r:200 w:50) - /// Proof: `Alliance::DepositOf` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:50 w:50) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Members` (r:0 w:1) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Prime` (r:0 w:1) - /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:2 w:2) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Proposals (r:1 w:0) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Alliance DepositOf (r:200 w:50) + /// Proof: Alliance DepositOf (max_values: None, max_size: Some(64), added: 2539, mode: MaxEncodedLen) + /// Storage: System Account (r:50 w:50) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: AllianceMotion Members (r:0 w:1) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Prime (r:0 w:1) + /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `x` is `[1, 100]`. /// The range of component `y` is `[0, 100]`. /// The range of component `z` is `[0, 50]`. @@ -283,14 +280,14 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0 + x * (50 ±0) + y * (51 ±0) + z * (251 ±0)` // Estimated: `12362 + x * (2539 ±0) + y * (2539 ±0) + z * (2603 ±1)` - // Minimum execution time: 307_414_000 picoseconds. - Weight::from_parts(309_960_000, 12362) - // Standard Error: 29_278 - .saturating_add(Weight::from_parts(588_774, 0).saturating_mul(x.into())) - // Standard Error: 29_137 - .saturating_add(Weight::from_parts(563_245, 0).saturating_mul(y.into())) - // Standard Error: 58_221 - .saturating_add(Weight::from_parts(13_947_604, 0).saturating_mul(z.into())) + // Minimum execution time: 309_235_000 picoseconds. + Weight::from_parts(311_279_000, 12362) + // Standard Error: 26_510 + .saturating_add(Weight::from_parts(543_475, 0).saturating_mul(x.into())) + // Standard Error: 26_382 + .saturating_add(Weight::from_parts(603_169, 0).saturating_mul(y.into())) + // Standard Error: 52_716 + .saturating_add(Weight::from_parts(16_264_836, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(x.into()))) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(y.into()))) @@ -301,401 +298,397 @@ impl WeightInfo for SubstrateWeight { .saturating_add(Weight::from_parts(0, 2539).saturating_mul(y.into())) .saturating_add(Weight::from_parts(0, 2603).saturating_mul(z.into())) } - /// Storage: `Alliance::Rule` (r:0 w:1) - /// Proof: `Alliance::Rule` (`max_values`: Some(1), `max_size`: Some(87), added: 582, mode: `MaxEncodedLen`) + /// Storage: Alliance Rule (r:0 w:1) + /// Proof: Alliance Rule (max_values: Some(1), max_size: Some(87), added: 582, mode: MaxEncodedLen) fn set_rule() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_156_000 picoseconds. - Weight::from_parts(6_560_000, 0) + // Minimum execution time: 8_833_000 picoseconds. + Weight::from_parts(9_313_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Alliance::Announcements` (r:1 w:1) - /// Proof: `Alliance::Announcements` (`max_values`: Some(1), `max_size`: Some(8702), added: 9197, mode: `MaxEncodedLen`) + /// Storage: Alliance Announcements (r:1 w:1) + /// Proof: Alliance Announcements (max_values: Some(1), max_size: Some(8702), added: 9197, mode: MaxEncodedLen) fn announce() -> Weight { // Proof Size summary in bytes: - // Measured: `279` + // Measured: `246` // Estimated: `10187` - // Minimum execution time: 8_988_000 picoseconds. - Weight::from_parts(9_476_000, 10187) + // Minimum execution time: 12_231_000 picoseconds. + Weight::from_parts(12_761_000, 10187) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Alliance::Announcements` (r:1 w:1) - /// Proof: `Alliance::Announcements` (`max_values`: Some(1), `max_size`: Some(8702), added: 9197, mode: `MaxEncodedLen`) + /// Storage: Alliance Announcements (r:1 w:1) + /// Proof: Alliance Announcements (max_values: Some(1), max_size: Some(8702), added: 9197, mode: MaxEncodedLen) fn remove_announcement() -> Weight { // Proof Size summary in bytes: - // Measured: `352` + // Measured: `319` // Estimated: `10187` - // Minimum execution time: 10_126_000 picoseconds. - Weight::from_parts(10_755_000, 10187) + // Minimum execution time: 13_079_000 picoseconds. + Weight::from_parts(13_612_000, 10187) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Alliance::Members` (r:3 w:1) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `Alliance::UnscrupulousAccounts` (r:1 w:0) - /// Proof: `Alliance::UnscrupulousAccounts` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Alliance::DepositOf` (r:0 w:1) - /// Proof: `Alliance::DepositOf` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) + /// Storage: Alliance Members (r:3 w:1) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: Alliance UnscrupulousAccounts (r:1 w:0) + /// Proof: Alliance UnscrupulousAccounts (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Alliance DepositOf (r:0 w:1) + /// Proof: Alliance DepositOf (max_values: None, max_size: Some(64), added: 2539, mode: MaxEncodedLen) fn join_alliance() -> Weight { // Proof Size summary in bytes: - // Measured: `501` + // Measured: `468` // Estimated: `18048` - // Minimum execution time: 38_878_000 picoseconds. - Weight::from_parts(40_493_000, 18048) + // Minimum execution time: 44_574_000 picoseconds. + Weight::from_parts(46_157_000, 18048) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Alliance::Members` (r:3 w:1) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `Alliance::UnscrupulousAccounts` (r:1 w:0) - /// Proof: `Alliance::UnscrupulousAccounts` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: Alliance Members (r:3 w:1) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: Alliance UnscrupulousAccounts (r:1 w:0) + /// Proof: Alliance UnscrupulousAccounts (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) fn nominate_ally() -> Weight { // Proof Size summary in bytes: - // Measured: `400` + // Measured: `367` // Estimated: `18048` - // Minimum execution time: 23_265_000 picoseconds. - Weight::from_parts(24_703_000, 18048) + // Minimum execution time: 26_114_000 picoseconds. + Weight::from_parts(27_069_000, 18048) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Alliance::Members` (r:2 w:2) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:0) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Members` (r:0 w:1) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Prime` (r:0 w:1) - /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:2 w:2) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Proposals (r:1 w:0) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Members (r:0 w:1) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Prime (r:0 w:1) + /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) fn elevate_ally() -> Weight { // Proof Size summary in bytes: - // Measured: `476` + // Measured: `443` // Estimated: `12362` - // Minimum execution time: 23_049_000 picoseconds. - Weight::from_parts(23_875_000, 12362) + // Minimum execution time: 25_882_000 picoseconds. + Weight::from_parts(26_923_000, 12362) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `Alliance::Members` (r:4 w:2) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:0) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Members` (r:0 w:1) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Prime` (r:0 w:1) - /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Alliance::RetiringMembers` (r:0 w:1) - /// Proof: `Alliance::RetiringMembers` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: Alliance Members (r:4 w:2) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Proposals (r:1 w:0) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Members (r:0 w:1) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Prime (r:0 w:1) + /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Alliance RetiringMembers (r:0 w:1) + /// Proof: Alliance RetiringMembers (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) fn give_retirement_notice() -> Weight { // Proof Size summary in bytes: - // Measured: `476` + // Measured: `443` // Estimated: `23734` - // Minimum execution time: 29_124_000 picoseconds. - Weight::from_parts(30_369_000, 23734) + // Minimum execution time: 34_112_000 picoseconds. + Weight::from_parts(35_499_000, 23734) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: `Alliance::RetiringMembers` (r:1 w:1) - /// Proof: `Alliance::RetiringMembers` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) - /// Storage: `Alliance::Members` (r:1 w:1) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `Alliance::DepositOf` (r:1 w:1) - /// Proof: `Alliance::DepositOf` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Alliance RetiringMembers (r:1 w:1) + /// Proof: Alliance RetiringMembers (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: Alliance Members (r:1 w:1) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: Alliance DepositOf (r:1 w:1) + /// Proof: Alliance DepositOf (max_values: None, max_size: Some(64), added: 2539, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn retire() -> Weight { // Proof Size summary in bytes: - // Measured: `720` + // Measured: `687` // Estimated: `6676` - // Minimum execution time: 36_376_000 picoseconds. - Weight::from_parts(38_221_000, 6676) + // Minimum execution time: 41_239_000 picoseconds. + Weight::from_parts(42_764_000, 6676) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `Alliance::Members` (r:3 w:1) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:0) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Alliance::DepositOf` (r:1 w:1) - /// Proof: `Alliance::DepositOf` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Members` (r:0 w:1) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Prime` (r:0 w:1) - /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:3 w:1) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Proposals (r:1 w:0) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Alliance DepositOf (r:1 w:1) + /// Proof: Alliance DepositOf (max_values: None, max_size: Some(64), added: 2539, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: AllianceMotion Members (r:0 w:1) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Prime (r:0 w:1) + /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) fn kick_member() -> Weight { // Proof Size summary in bytes: - // Measured: `740` + // Measured: `707` // Estimated: `18048` - // Minimum execution time: 56_560_000 picoseconds. - Weight::from_parts(58_621_000, 18048) + // Minimum execution time: 68_071_000 picoseconds. + Weight::from_parts(71_808_000, 18048) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: `Alliance::UnscrupulousAccounts` (r:1 w:1) - /// Proof: `Alliance::UnscrupulousAccounts` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) - /// Storage: `Alliance::UnscrupulousWebsites` (r:1 w:1) - /// Proof: `Alliance::UnscrupulousWebsites` (`max_values`: Some(1), `max_size`: Some(25702), added: 26197, mode: `MaxEncodedLen`) + /// Storage: Alliance UnscrupulousAccounts (r:1 w:1) + /// Proof: Alliance UnscrupulousAccounts (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: Alliance UnscrupulousWebsites (r:1 w:1) + /// Proof: Alliance UnscrupulousWebsites (max_values: Some(1), max_size: Some(25702), added: 26197, mode: MaxEncodedLen) /// The range of component `n` is `[0, 100]`. /// The range of component `l` is `[0, 255]`. fn add_unscrupulous_items(n: u32, l: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `279` + // Measured: `246` // Estimated: `27187` - // Minimum execution time: 5_191_000 picoseconds. - Weight::from_parts(5_410_000, 27187) - // Standard Error: 3_215 - .saturating_add(Weight::from_parts(1_018_569, 0).saturating_mul(n.into())) - // Standard Error: 1_259 - .saturating_add(Weight::from_parts(68_712, 0).saturating_mul(l.into())) + // Minimum execution time: 7_006_000 picoseconds. + Weight::from_parts(7_253_000, 27187) + // Standard Error: 3_403 + .saturating_add(Weight::from_parts(1_680_082, 0).saturating_mul(n.into())) + // Standard Error: 1_333 + .saturating_add(Weight::from_parts(72_943, 0).saturating_mul(l.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Alliance::UnscrupulousAccounts` (r:1 w:1) - /// Proof: `Alliance::UnscrupulousAccounts` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) - /// Storage: `Alliance::UnscrupulousWebsites` (r:1 w:1) - /// Proof: `Alliance::UnscrupulousWebsites` (`max_values`: Some(1), `max_size`: Some(25702), added: 26197, mode: `MaxEncodedLen`) + /// Storage: Alliance UnscrupulousAccounts (r:1 w:1) + /// Proof: Alliance UnscrupulousAccounts (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: Alliance UnscrupulousWebsites (r:1 w:1) + /// Proof: Alliance UnscrupulousWebsites (max_values: Some(1), max_size: Some(25702), added: 26197, mode: MaxEncodedLen) /// The range of component `n` is `[0, 100]`. /// The range of component `l` is `[0, 255]`. fn remove_unscrupulous_items(n: u32, l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + l * (100 ±0) + n * (289 ±0)` // Estimated: `27187` - // Minimum execution time: 5_361_000 picoseconds. - Weight::from_parts(5_494_000, 27187) - // Standard Error: 181_133 - .saturating_add(Weight::from_parts(16_322_982, 0).saturating_mul(n.into())) - // Standard Error: 70_940 - .saturating_add(Weight::from_parts(343_581, 0).saturating_mul(l.into())) + // Minimum execution time: 7_292_000 picoseconds. + Weight::from_parts(7_629_000, 27187) + // Standard Error: 176_225 + .saturating_add(Weight::from_parts(16_646_429, 0).saturating_mul(n.into())) + // Standard Error: 69_017 + .saturating_add(Weight::from_parts(310_978, 0).saturating_mul(l.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Alliance::Members` (r:3 w:2) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:0) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Members` (r:0 w:1) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Prime` (r:0 w:1) - /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:3 w:2) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Proposals (r:1 w:0) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Members (r:0 w:1) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Prime (r:0 w:1) + /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) fn abdicate_fellow_status() -> Weight { // Proof Size summary in bytes: - // Measured: `476` + // Measured: `443` // Estimated: `18048` - // Minimum execution time: 28_856_000 picoseconds. - Weight::from_parts(29_875_000, 18048) + // Minimum execution time: 31_798_000 picoseconds. + Weight::from_parts(33_463_000, 18048) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Alliance::Members` (r:1 w:0) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::ProposalOf` (r:1 w:1) - /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:1) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::ProposalCount` (r:1 w:1) - /// Proof: `AllianceMotion::ProposalCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Voting` (r:0 w:1) - /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:1 w:0) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion ProposalOf (r:1 w:1) + /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: AllianceMotion Proposals (r:1 w:1) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion ProposalCount (r:1 w:1) + /// Proof Skipped: AllianceMotion ProposalCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Voting (r:0 w:1) + /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) /// The range of component `b` is `[1, 1024]`. /// The range of component `m` is `[2, 100]`. /// The range of component `p` is `[1, 100]`. fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `654 + m * (32 ±0) + p * (36 ±0)` + // Measured: `653 + m * (32 ±0) + p * (35 ±0)` // Estimated: `6676 + m * (32 ±0) + p * (36 ±0)` - // Minimum execution time: 30_801_000 picoseconds. - Weight::from_parts(32_942_969, 6676) - // Standard Error: 112 - .saturating_add(Weight::from_parts(614, 0).saturating_mul(b.into())) - // Standard Error: 1_177 - .saturating_add(Weight::from_parts(45_758, 0).saturating_mul(m.into())) - // Standard Error: 1_162 - .saturating_add(Weight::from_parts(136_600, 0).saturating_mul(p.into())) + // Minimum execution time: 36_908_000 picoseconds. + Weight::from_parts(39_040_304, 6676) + // Standard Error: 131 + .saturating_add(Weight::from_parts(781, 0).saturating_mul(b.into())) + // Standard Error: 1_375 + .saturating_add(Weight::from_parts(48_745, 0).saturating_mul(m.into())) + // Standard Error: 1_358 + .saturating_add(Weight::from_parts(148_047, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: `Alliance::Members` (r:1 w:0) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Voting` (r:1 w:1) - /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:1 w:0) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Voting (r:1 w:1) + /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) /// The range of component `m` is `[5, 100]`. fn vote(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1113 + m * (64 ±0)` + // Measured: `1042 + m * (64 ±0)` // Estimated: `6676 + m * (64 ±0)` - // Minimum execution time: 29_705_000 picoseconds. - Weight::from_parts(30_274_070, 6676) - // Standard Error: 884 - .saturating_add(Weight::from_parts(71_178, 0).saturating_mul(m.into())) + // Minimum execution time: 30_166_000 picoseconds. + Weight::from_parts(32_798_454, 6676) + // Standard Error: 1_432 + .saturating_add(Weight::from_parts(83_001, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: `Alliance::Members` (r:1 w:0) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Voting` (r:1 w:1) - /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Members` (r:1 w:0) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:1) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::ProposalOf` (r:0 w:1) - /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:1 w:0) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Voting (r:1 w:1) + /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: AllianceMotion Members (r:1 w:0) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Proposals (r:1 w:1) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion ProposalOf (r:0 w:1) + /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_early_disapproved(m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `640 + m * (96 ±0) + p * (36 ±0)` + // Measured: `576 + m * (96 ±0) + p * (36 ±0)` // Estimated: `6676 + m * (97 ±0) + p * (36 ±0)` - // Minimum execution time: 38_596_000 picoseconds. - Weight::from_parts(36_445_536, 6676) - // Standard Error: 1_217 - .saturating_add(Weight::from_parts(69_976, 0).saturating_mul(m.into())) - // Standard Error: 1_187 - .saturating_add(Weight::from_parts(149_706, 0).saturating_mul(p.into())) + // Minimum execution time: 45_173_000 picoseconds. + Weight::from_parts(42_192_020, 6676) + // Standard Error: 1_456 + .saturating_add(Weight::from_parts(66_751, 0).saturating_mul(m.into())) + // Standard Error: 1_420 + .saturating_add(Weight::from_parts(158_161, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 97).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: `Alliance::Members` (r:1 w:0) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Voting` (r:1 w:1) - /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Members` (r:1 w:0) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::ProposalOf` (r:1 w:1) - /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:1) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:1 w:0) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Voting (r:1 w:1) + /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: AllianceMotion Members (r:1 w:0) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion ProposalOf (r:1 w:1) + /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: AllianceMotion Proposals (r:1 w:1) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `b` is `[1, 1024]`. /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1220 + m * (96 ±0) + p * (39 ±0)` + // Measured: `1087 + m * (96 ±0) + p * (39 ±0)` // Estimated: `6676 + m * (97 ±0) + p * (40 ±0)` - // Minimum execution time: 57_602_000 picoseconds. - Weight::from_parts(55_147_214, 6676) - // Standard Error: 127 - .saturating_add(Weight::from_parts(1_650, 0).saturating_mul(b.into())) - // Standard Error: 1_346 - .saturating_add(Weight::from_parts(56_056, 0).saturating_mul(m.into())) - // Standard Error: 1_312 - .saturating_add(Weight::from_parts(168_247, 0).saturating_mul(p.into())) - .saturating_add(RocksDbWeight::get().reads(7_u64)) + // Minimum execution time: 58_290_000 picoseconds. + Weight::from_parts(54_924_919, 6676) + // Standard Error: 157 + .saturating_add(Weight::from_parts(464, 0).saturating_mul(b.into())) + // Standard Error: 1_665 + .saturating_add(Weight::from_parts(73_183, 0).saturating_mul(m.into())) + // Standard Error: 1_623 + .saturating_add(Weight::from_parts(168_318, 0).saturating_mul(p.into())) + .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 97).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) } - /// Storage: `Alliance::Members` (r:1 w:0) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Voting` (r:1 w:1) - /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Members` (r:1 w:0) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Prime` (r:1 w:0) - /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:1) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::ProposalOf` (r:0 w:1) - /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:1 w:0) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Voting (r:1 w:1) + /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: AllianceMotion Members (r:1 w:0) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Prime (r:1 w:0) + /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Proposals (r:1 w:1) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion ProposalOf (r:0 w:1) + /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) /// The range of component `m` is `[2, 100]`. /// The range of component `p` is `[1, 100]`. fn close_disapproved(m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `641 + m * (96 ±0) + p * (36 ±0)` + // Measured: `577 + m * (96 ±0) + p * (36 ±0)` // Estimated: `6676 + m * (97 ±0) + p * (36 ±0)` - // Minimum execution time: 40_755_000 picoseconds. - Weight::from_parts(36_953_935, 6676) - // Standard Error: 1_177 - .saturating_add(Weight::from_parts(73_240, 0).saturating_mul(m.into())) - // Standard Error: 1_162 - .saturating_add(Weight::from_parts(149_412, 0).saturating_mul(p.into())) + // Minimum execution time: 46_794_000 picoseconds. + Weight::from_parts(43_092_958, 6676) + // Standard Error: 1_273 + .saturating_add(Weight::from_parts(71_054, 0).saturating_mul(m.into())) + // Standard Error: 1_257 + .saturating_add(Weight::from_parts(152_820, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 97).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: `Alliance::Members` (r:1 w:0) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Voting` (r:1 w:1) - /// Proof: `AllianceMotion::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Members` (r:1 w:0) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Prime` (r:1 w:0) - /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:1) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::ProposalOf` (r:0 w:1) - /// Proof: `AllianceMotion::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:1 w:0) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Voting (r:1 w:1) + /// Proof Skipped: AllianceMotion Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: AllianceMotion Members (r:1 w:0) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Prime (r:1 w:0) + /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Proposals (r:1 w:1) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion ProposalOf (r:0 w:1) + /// Proof Skipped: AllianceMotion ProposalOf (max_values: None, max_size: None, mode: Measured) /// The range of component `b` is `[1, 1024]`. /// The range of component `m` is `[5, 100]`. /// The range of component `p` is `[1, 100]`. fn close_approved(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `694 + m * (96 ±0) + p * (35 ±0)` + // Measured: `684 + m * (96 ±0) + p * (35 ±0)` // Estimated: `6676 + m * (97 ±0) + p * (36 ±0)` - // Minimum execution time: 41_113_000 picoseconds. - Weight::from_parts(36_610_116, 6676) - // Standard Error: 92 - .saturating_add(Weight::from_parts(1_157, 0).saturating_mul(b.into())) - // Standard Error: 984 - .saturating_add(Weight::from_parts(63_050, 0).saturating_mul(m.into())) - // Standard Error: 949 - .saturating_add(Weight::from_parts(150_420, 0).saturating_mul(p.into())) + // Minimum execution time: 47_338_000 picoseconds. + Weight::from_parts(41_257_479, 6676) + // Standard Error: 119 + .saturating_add(Weight::from_parts(1_019, 0).saturating_mul(b.into())) + // Standard Error: 1_277 + .saturating_add(Weight::from_parts(78_453, 0).saturating_mul(m.into())) + // Standard Error: 1_231 + .saturating_add(Weight::from_parts(150_991, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 97).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: `Alliance::Members` (r:2 w:2) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Members` (r:1 w:1) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:2 w:2) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Members (r:1 w:1) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `m` is `[1, 100]`. /// The range of component `z` is `[0, 100]`. fn init_members(m: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `250` + // Measured: `217` // Estimated: `12362` - // Minimum execution time: 30_249_000 picoseconds. - Weight::from_parts(21_364_868, 12362) - // Standard Error: 887 - .saturating_add(Weight::from_parts(131_624, 0).saturating_mul(m.into())) - // Standard Error: 877 - .saturating_add(Weight::from_parts(105_379, 0).saturating_mul(z.into())) + // Minimum execution time: 35_012_000 picoseconds. + Weight::from_parts(24_288_079, 12362) + // Standard Error: 878 + .saturating_add(Weight::from_parts(153_615, 0).saturating_mul(m.into())) + // Standard Error: 867 + .saturating_add(Weight::from_parts(129_307, 0).saturating_mul(z.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Alliance::Members` (r:2 w:2) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:0) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Alliance::DepositOf` (r:200 w:50) - /// Proof: `Alliance::DepositOf` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:50 w:50) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Members` (r:0 w:1) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Prime` (r:0 w:1) - /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:2 w:2) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Proposals (r:1 w:0) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Alliance DepositOf (r:200 w:50) + /// Proof: Alliance DepositOf (max_values: None, max_size: Some(64), added: 2539, mode: MaxEncodedLen) + /// Storage: System Account (r:50 w:50) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: AllianceMotion Members (r:0 w:1) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Prime (r:0 w:1) + /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `x` is `[1, 100]`. /// The range of component `y` is `[0, 100]`. /// The range of component `z` is `[0, 50]`. @@ -703,14 +696,14 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0 + x * (50 ±0) + y * (51 ±0) + z * (251 ±0)` // Estimated: `12362 + x * (2539 ±0) + y * (2539 ±0) + z * (2603 ±1)` - // Minimum execution time: 307_414_000 picoseconds. - Weight::from_parts(309_960_000, 12362) - // Standard Error: 29_278 - .saturating_add(Weight::from_parts(588_774, 0).saturating_mul(x.into())) - // Standard Error: 29_137 - .saturating_add(Weight::from_parts(563_245, 0).saturating_mul(y.into())) - // Standard Error: 58_221 - .saturating_add(Weight::from_parts(13_947_604, 0).saturating_mul(z.into())) + // Minimum execution time: 309_235_000 picoseconds. + Weight::from_parts(311_279_000, 12362) + // Standard Error: 26_510 + .saturating_add(Weight::from_parts(543_475, 0).saturating_mul(x.into())) + // Standard Error: 26_382 + .saturating_add(Weight::from_parts(603_169, 0).saturating_mul(y.into())) + // Standard Error: 52_716 + .saturating_add(Weight::from_parts(16_264_836, 0).saturating_mul(z.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(x.into()))) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(y.into()))) @@ -721,194 +714,194 @@ impl WeightInfo for () { .saturating_add(Weight::from_parts(0, 2539).saturating_mul(y.into())) .saturating_add(Weight::from_parts(0, 2603).saturating_mul(z.into())) } - /// Storage: `Alliance::Rule` (r:0 w:1) - /// Proof: `Alliance::Rule` (`max_values`: Some(1), `max_size`: Some(87), added: 582, mode: `MaxEncodedLen`) + /// Storage: Alliance Rule (r:0 w:1) + /// Proof: Alliance Rule (max_values: Some(1), max_size: Some(87), added: 582, mode: MaxEncodedLen) fn set_rule() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_156_000 picoseconds. - Weight::from_parts(6_560_000, 0) + // Minimum execution time: 8_833_000 picoseconds. + Weight::from_parts(9_313_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Alliance::Announcements` (r:1 w:1) - /// Proof: `Alliance::Announcements` (`max_values`: Some(1), `max_size`: Some(8702), added: 9197, mode: `MaxEncodedLen`) + /// Storage: Alliance Announcements (r:1 w:1) + /// Proof: Alliance Announcements (max_values: Some(1), max_size: Some(8702), added: 9197, mode: MaxEncodedLen) fn announce() -> Weight { // Proof Size summary in bytes: - // Measured: `279` + // Measured: `246` // Estimated: `10187` - // Minimum execution time: 8_988_000 picoseconds. - Weight::from_parts(9_476_000, 10187) + // Minimum execution time: 12_231_000 picoseconds. + Weight::from_parts(12_761_000, 10187) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Alliance::Announcements` (r:1 w:1) - /// Proof: `Alliance::Announcements` (`max_values`: Some(1), `max_size`: Some(8702), added: 9197, mode: `MaxEncodedLen`) + /// Storage: Alliance Announcements (r:1 w:1) + /// Proof: Alliance Announcements (max_values: Some(1), max_size: Some(8702), added: 9197, mode: MaxEncodedLen) fn remove_announcement() -> Weight { // Proof Size summary in bytes: - // Measured: `352` + // Measured: `319` // Estimated: `10187` - // Minimum execution time: 10_126_000 picoseconds. - Weight::from_parts(10_755_000, 10187) + // Minimum execution time: 13_079_000 picoseconds. + Weight::from_parts(13_612_000, 10187) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Alliance::Members` (r:3 w:1) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `Alliance::UnscrupulousAccounts` (r:1 w:0) - /// Proof: `Alliance::UnscrupulousAccounts` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Alliance::DepositOf` (r:0 w:1) - /// Proof: `Alliance::DepositOf` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) + /// Storage: Alliance Members (r:3 w:1) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: Alliance UnscrupulousAccounts (r:1 w:0) + /// Proof: Alliance UnscrupulousAccounts (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Alliance DepositOf (r:0 w:1) + /// Proof: Alliance DepositOf (max_values: None, max_size: Some(64), added: 2539, mode: MaxEncodedLen) fn join_alliance() -> Weight { // Proof Size summary in bytes: - // Measured: `501` + // Measured: `468` // Estimated: `18048` - // Minimum execution time: 38_878_000 picoseconds. - Weight::from_parts(40_493_000, 18048) + // Minimum execution time: 44_574_000 picoseconds. + Weight::from_parts(46_157_000, 18048) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Alliance::Members` (r:3 w:1) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `Alliance::UnscrupulousAccounts` (r:1 w:0) - /// Proof: `Alliance::UnscrupulousAccounts` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) + /// Storage: Alliance Members (r:3 w:1) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: Alliance UnscrupulousAccounts (r:1 w:0) + /// Proof: Alliance UnscrupulousAccounts (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) fn nominate_ally() -> Weight { // Proof Size summary in bytes: - // Measured: `400` + // Measured: `367` // Estimated: `18048` - // Minimum execution time: 23_265_000 picoseconds. - Weight::from_parts(24_703_000, 18048) + // Minimum execution time: 26_114_000 picoseconds. + Weight::from_parts(27_069_000, 18048) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Alliance::Members` (r:2 w:2) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:0) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Members` (r:0 w:1) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Prime` (r:0 w:1) - /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:2 w:2) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Proposals (r:1 w:0) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Members (r:0 w:1) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Prime (r:0 w:1) + /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) fn elevate_ally() -> Weight { // Proof Size summary in bytes: - // Measured: `476` + // Measured: `443` // Estimated: `12362` - // Minimum execution time: 23_049_000 picoseconds. - Weight::from_parts(23_875_000, 12362) + // Minimum execution time: 25_882_000 picoseconds. + Weight::from_parts(26_923_000, 12362) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `Alliance::Members` (r:4 w:2) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:0) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Members` (r:0 w:1) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Prime` (r:0 w:1) - /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Alliance::RetiringMembers` (r:0 w:1) - /// Proof: `Alliance::RetiringMembers` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: Alliance Members (r:4 w:2) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Proposals (r:1 w:0) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Members (r:0 w:1) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Prime (r:0 w:1) + /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Alliance RetiringMembers (r:0 w:1) + /// Proof: Alliance RetiringMembers (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) fn give_retirement_notice() -> Weight { // Proof Size summary in bytes: - // Measured: `476` + // Measured: `443` // Estimated: `23734` - // Minimum execution time: 29_124_000 picoseconds. - Weight::from_parts(30_369_000, 23734) + // Minimum execution time: 34_112_000 picoseconds. + Weight::from_parts(35_499_000, 23734) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: `Alliance::RetiringMembers` (r:1 w:1) - /// Proof: `Alliance::RetiringMembers` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) - /// Storage: `Alliance::Members` (r:1 w:1) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `Alliance::DepositOf` (r:1 w:1) - /// Proof: `Alliance::DepositOf` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Alliance RetiringMembers (r:1 w:1) + /// Proof: Alliance RetiringMembers (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: Alliance Members (r:1 w:1) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: Alliance DepositOf (r:1 w:1) + /// Proof: Alliance DepositOf (max_values: None, max_size: Some(64), added: 2539, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn retire() -> Weight { // Proof Size summary in bytes: - // Measured: `720` + // Measured: `687` // Estimated: `6676` - // Minimum execution time: 36_376_000 picoseconds. - Weight::from_parts(38_221_000, 6676) + // Minimum execution time: 41_239_000 picoseconds. + Weight::from_parts(42_764_000, 6676) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `Alliance::Members` (r:3 w:1) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:0) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Alliance::DepositOf` (r:1 w:1) - /// Proof: `Alliance::DepositOf` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Members` (r:0 w:1) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Prime` (r:0 w:1) - /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:3 w:1) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Proposals (r:1 w:0) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Alliance DepositOf (r:1 w:1) + /// Proof: Alliance DepositOf (max_values: None, max_size: Some(64), added: 2539, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: AllianceMotion Members (r:0 w:1) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Prime (r:0 w:1) + /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) fn kick_member() -> Weight { // Proof Size summary in bytes: - // Measured: `740` + // Measured: `707` // Estimated: `18048` - // Minimum execution time: 56_560_000 picoseconds. - Weight::from_parts(58_621_000, 18048) + // Minimum execution time: 68_071_000 picoseconds. + Weight::from_parts(71_808_000, 18048) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: `Alliance::UnscrupulousAccounts` (r:1 w:1) - /// Proof: `Alliance::UnscrupulousAccounts` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) - /// Storage: `Alliance::UnscrupulousWebsites` (r:1 w:1) - /// Proof: `Alliance::UnscrupulousWebsites` (`max_values`: Some(1), `max_size`: Some(25702), added: 26197, mode: `MaxEncodedLen`) + /// Storage: Alliance UnscrupulousAccounts (r:1 w:1) + /// Proof: Alliance UnscrupulousAccounts (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: Alliance UnscrupulousWebsites (r:1 w:1) + /// Proof: Alliance UnscrupulousWebsites (max_values: Some(1), max_size: Some(25702), added: 26197, mode: MaxEncodedLen) /// The range of component `n` is `[0, 100]`. /// The range of component `l` is `[0, 255]`. fn add_unscrupulous_items(n: u32, l: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `279` + // Measured: `246` // Estimated: `27187` - // Minimum execution time: 5_191_000 picoseconds. - Weight::from_parts(5_410_000, 27187) - // Standard Error: 3_215 - .saturating_add(Weight::from_parts(1_018_569, 0).saturating_mul(n.into())) - // Standard Error: 1_259 - .saturating_add(Weight::from_parts(68_712, 0).saturating_mul(l.into())) + // Minimum execution time: 7_006_000 picoseconds. + Weight::from_parts(7_253_000, 27187) + // Standard Error: 3_403 + .saturating_add(Weight::from_parts(1_680_082, 0).saturating_mul(n.into())) + // Standard Error: 1_333 + .saturating_add(Weight::from_parts(72_943, 0).saturating_mul(l.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Alliance::UnscrupulousAccounts` (r:1 w:1) - /// Proof: `Alliance::UnscrupulousAccounts` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) - /// Storage: `Alliance::UnscrupulousWebsites` (r:1 w:1) - /// Proof: `Alliance::UnscrupulousWebsites` (`max_values`: Some(1), `max_size`: Some(25702), added: 26197, mode: `MaxEncodedLen`) + /// Storage: Alliance UnscrupulousAccounts (r:1 w:1) + /// Proof: Alliance UnscrupulousAccounts (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: Alliance UnscrupulousWebsites (r:1 w:1) + /// Proof: Alliance UnscrupulousWebsites (max_values: Some(1), max_size: Some(25702), added: 26197, mode: MaxEncodedLen) /// The range of component `n` is `[0, 100]`. /// The range of component `l` is `[0, 255]`. fn remove_unscrupulous_items(n: u32, l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + l * (100 ±0) + n * (289 ±0)` // Estimated: `27187` - // Minimum execution time: 5_361_000 picoseconds. - Weight::from_parts(5_494_000, 27187) - // Standard Error: 181_133 - .saturating_add(Weight::from_parts(16_322_982, 0).saturating_mul(n.into())) - // Standard Error: 70_940 - .saturating_add(Weight::from_parts(343_581, 0).saturating_mul(l.into())) + // Minimum execution time: 7_292_000 picoseconds. + Weight::from_parts(7_629_000, 27187) + // Standard Error: 176_225 + .saturating_add(Weight::from_parts(16_646_429, 0).saturating_mul(n.into())) + // Standard Error: 69_017 + .saturating_add(Weight::from_parts(310_978, 0).saturating_mul(l.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Alliance::Members` (r:3 w:2) - /// Proof: `Alliance::Members` (`max_values`: None, `max_size`: Some(3211), added: 5686, mode: `MaxEncodedLen`) - /// Storage: `AllianceMotion::Proposals` (r:1 w:0) - /// Proof: `AllianceMotion::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Members` (r:0 w:1) - /// Proof: `AllianceMotion::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `AllianceMotion::Prime` (r:0 w:1) - /// Proof: `AllianceMotion::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Alliance Members (r:3 w:2) + /// Proof: Alliance Members (max_values: None, max_size: Some(3211), added: 5686, mode: MaxEncodedLen) + /// Storage: AllianceMotion Proposals (r:1 w:0) + /// Proof Skipped: AllianceMotion Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Members (r:0 w:1) + /// Proof Skipped: AllianceMotion Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: AllianceMotion Prime (r:0 w:1) + /// Proof Skipped: AllianceMotion Prime (max_values: Some(1), max_size: None, mode: Measured) fn abdicate_fellow_status() -> Weight { // Proof Size summary in bytes: - // Measured: `476` + // Measured: `443` // Estimated: `18048` - // Minimum execution time: 28_856_000 picoseconds. - Weight::from_parts(29_875_000, 18048) + // Minimum execution time: 31_798_000 picoseconds. + Weight::from_parts(33_463_000, 18048) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } diff --git a/substrate/frame/asset-conversion/src/weights.rs b/substrate/frame/asset-conversion/src/weights.rs index 4eaa115c694..a0e687f7a41 100644 --- a/substrate/frame/asset-conversion/src/weights.rs +++ b/substrate/frame/asset-conversion/src/weights.rs @@ -17,28 +17,24 @@ //! Autogenerated weights for `pallet_asset_conversion` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-10-30, STEPS: `5`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `cob`, CPU: `` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate-node +// ./target/debug/substrate-node // benchmark // pallet // --chain=dev -// --steps=50 -// --repeat=20 -// --pallet=pallet_asset_conversion -// --no-storage-info -// --no-median-slopes -// --no-min-squares +// --steps=5 +// --repeat=2 +// --pallet=pallet-asset-conversion // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 // --output=./substrate/frame/asset-conversion/src/weights.rs -// --header=./substrate/HEADER-APACHE2 // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -63,9 +59,11 @@ pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { /// Storage: `AssetConversion::Pools` (r:1 w:1) /// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) + /// Storage: `System::Account` (r:2 w:2) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:2 w:0) + /// Storage: `Assets::Account` (r:2 w:2) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:2 w:2) /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) /// Storage: `AssetConversion::NextPoolAssetId` (r:1 w:1) /// Proof: `AssetConversion::NextPoolAssetId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -75,12 +73,12 @@ impl WeightInfo for SubstrateWeight { /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn create_pool() -> Weight { // Proof Size summary in bytes: - // Measured: `910` + // Measured: `1081` // Estimated: `6360` - // Minimum execution time: 82_941_000 picoseconds. - Weight::from_parts(85_526_000, 6360) - .saturating_add(T::DbWeight::get().reads(7_u64)) - .saturating_add(T::DbWeight::get().writes(5_u64)) + // Minimum execution time: 1_576_000_000 picoseconds. + Weight::from_parts(1_668_000_000, 6360) + .saturating_add(T::DbWeight::get().reads(10_u64)) + .saturating_add(T::DbWeight::get().writes(10_u64)) } /// Storage: `AssetConversion::Pools` (r:1 w:0) /// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) @@ -88,20 +86,18 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) /// Storage: `Assets::Account` (r:4 w:4) /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `PoolAssets::Asset` (r:1 w:1) /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) /// Storage: `PoolAssets::Account` (r:2 w:2) /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn add_liquidity() -> Weight { // Proof Size summary in bytes: - // Measured: `1507` + // Measured: `1761` // Estimated: `11426` - // Minimum execution time: 138_424_000 picoseconds. - Weight::from_parts(142_083_000, 11426) - .saturating_add(T::DbWeight::get().reads(11_u64)) - .saturating_add(T::DbWeight::get().writes(10_u64)) + // Minimum execution time: 1_636_000_000 picoseconds. + Weight::from_parts(1_894_000_000, 11426) + .saturating_add(T::DbWeight::get().reads(10_u64)) + .saturating_add(T::DbWeight::get().writes(9_u64)) } /// Storage: `AssetConversion::Pools` (r:1 w:0) /// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) @@ -115,10 +111,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn remove_liquidity() -> Weight { // Proof Size summary in bytes: - // Measured: `1650` + // Measured: `1750` // Estimated: `11426` - // Minimum execution time: 122_132_000 picoseconds. - Weight::from_parts(125_143_000, 11426) + // Minimum execution time: 1_507_000_000 picoseconds. + Weight::from_parts(1_524_000_000, 11426) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(8_u64)) } @@ -129,12 +125,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[2, 4]`. fn swap_exact_tokens_for_tokens(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `89 + n * (419 ±0)` + // Measured: `0 + n * (522 ±0)` // Estimated: `990 + n * (5218 ±0)` - // Minimum execution time: 77_183_000 picoseconds. - Weight::from_parts(78_581_000, 990) - // Standard Error: 306_918 - .saturating_add(Weight::from_parts(10_581_054, 0).saturating_mul(n.into())) + // Minimum execution time: 937_000_000 picoseconds. + Weight::from_parts(941_000_000, 990) + // Standard Error: 40_863_477 + .saturating_add(Weight::from_parts(205_862_068, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into()))) .saturating_add(Weight::from_parts(0, 5218).saturating_mul(n.into())) @@ -146,12 +142,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[2, 4]`. fn swap_tokens_for_exact_tokens(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `89 + n * (419 ±0)` + // Measured: `0 + n * (522 ±0)` // Estimated: `990 + n * (5218 ±0)` - // Minimum execution time: 76_962_000 picoseconds. - Weight::from_parts(78_315_000, 990) - // Standard Error: 311_204 - .saturating_add(Weight::from_parts(10_702_400, 0).saturating_mul(n.into())) + // Minimum execution time: 935_000_000 picoseconds. + Weight::from_parts(947_000_000, 990) + // Standard Error: 46_904_620 + .saturating_add(Weight::from_parts(218_275_862, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into()))) .saturating_add(Weight::from_parts(0, 5218).saturating_mul(n.into())) @@ -162,9 +158,11 @@ impl WeightInfo for SubstrateWeight { impl WeightInfo for () { /// Storage: `AssetConversion::Pools` (r:1 w:1) /// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) + /// Storage: `System::Account` (r:2 w:2) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:2 w:0) + /// Storage: `Assets::Account` (r:2 w:2) + /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:2 w:2) /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) /// Storage: `AssetConversion::NextPoolAssetId` (r:1 w:1) /// Proof: `AssetConversion::NextPoolAssetId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -174,12 +172,12 @@ impl WeightInfo for () { /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn create_pool() -> Weight { // Proof Size summary in bytes: - // Measured: `910` + // Measured: `1081` // Estimated: `6360` - // Minimum execution time: 82_941_000 picoseconds. - Weight::from_parts(85_526_000, 6360) - .saturating_add(RocksDbWeight::get().reads(7_u64)) - .saturating_add(RocksDbWeight::get().writes(5_u64)) + // Minimum execution time: 1_576_000_000 picoseconds. + Weight::from_parts(1_668_000_000, 6360) + .saturating_add(RocksDbWeight::get().reads(10_u64)) + .saturating_add(RocksDbWeight::get().writes(10_u64)) } /// Storage: `AssetConversion::Pools` (r:1 w:0) /// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) @@ -187,20 +185,18 @@ impl WeightInfo for () { /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) /// Storage: `Assets::Account` (r:4 w:4) /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `PoolAssets::Asset` (r:1 w:1) /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) /// Storage: `PoolAssets::Account` (r:2 w:2) /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn add_liquidity() -> Weight { // Proof Size summary in bytes: - // Measured: `1507` + // Measured: `1761` // Estimated: `11426` - // Minimum execution time: 138_424_000 picoseconds. - Weight::from_parts(142_083_000, 11426) - .saturating_add(RocksDbWeight::get().reads(11_u64)) - .saturating_add(RocksDbWeight::get().writes(10_u64)) + // Minimum execution time: 1_636_000_000 picoseconds. + Weight::from_parts(1_894_000_000, 11426) + .saturating_add(RocksDbWeight::get().reads(10_u64)) + .saturating_add(RocksDbWeight::get().writes(9_u64)) } /// Storage: `AssetConversion::Pools` (r:1 w:0) /// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) @@ -214,10 +210,10 @@ impl WeightInfo for () { /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) fn remove_liquidity() -> Weight { // Proof Size summary in bytes: - // Measured: `1650` + // Measured: `1750` // Estimated: `11426` - // Minimum execution time: 122_132_000 picoseconds. - Weight::from_parts(125_143_000, 11426) + // Minimum execution time: 1_507_000_000 picoseconds. + Weight::from_parts(1_524_000_000, 11426) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(8_u64)) } @@ -228,12 +224,12 @@ impl WeightInfo for () { /// The range of component `n` is `[2, 4]`. fn swap_exact_tokens_for_tokens(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `89 + n * (419 ±0)` + // Measured: `0 + n * (522 ±0)` // Estimated: `990 + n * (5218 ±0)` - // Minimum execution time: 77_183_000 picoseconds. - Weight::from_parts(78_581_000, 990) - // Standard Error: 306_918 - .saturating_add(Weight::from_parts(10_581_054, 0).saturating_mul(n.into())) + // Minimum execution time: 937_000_000 picoseconds. + Weight::from_parts(941_000_000, 990) + // Standard Error: 40_863_477 + .saturating_add(Weight::from_parts(205_862_068, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(n.into()))) .saturating_add(Weight::from_parts(0, 5218).saturating_mul(n.into())) @@ -245,12 +241,12 @@ impl WeightInfo for () { /// The range of component `n` is `[2, 4]`. fn swap_tokens_for_exact_tokens(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `89 + n * (419 ±0)` + // Measured: `0 + n * (522 ±0)` // Estimated: `990 + n * (5218 ±0)` - // Minimum execution time: 76_962_000 picoseconds. - Weight::from_parts(78_315_000, 990) - // Standard Error: 311_204 - .saturating_add(Weight::from_parts(10_702_400, 0).saturating_mul(n.into())) + // Minimum execution time: 935_000_000 picoseconds. + Weight::from_parts(947_000_000, 990) + // Standard Error: 46_904_620 + .saturating_add(Weight::from_parts(218_275_862, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(n.into()))) .saturating_add(Weight::from_parts(0, 5218).saturating_mul(n.into())) diff --git a/substrate/frame/asset-rate/src/weights.rs b/substrate/frame/asset-rate/src/weights.rs index b8723ee3bed..582e20e56d7 100644 --- a/substrate/frame/asset-rate/src/weights.rs +++ b/substrate/frame/asset-rate/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_asset_rate` +//! Autogenerated weights for pallet_asset_rate //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/asset-rate/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/asset-rate/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,83 +50,83 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_asset_rate`. +/// Weight functions needed for pallet_asset_rate. pub trait WeightInfo { fn create() -> Weight; fn update() -> Weight; fn remove() -> Weight; } -/// Weights for `pallet_asset_rate` using the Substrate node and recommended hardware. +/// Weights for pallet_asset_rate using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1) - /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: AssetRate ConversionRateToNative (r:1 w:1) + /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) fn create() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3501` - // Minimum execution time: 9_447_000 picoseconds. - Weight::from_parts(10_078_000, 3501) + // Minimum execution time: 11_700_000 picoseconds. + Weight::from_parts(12_158_000, 3501) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1) - /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: AssetRate ConversionRateToNative (r:1 w:1) + /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) fn update() -> Weight { // Proof Size summary in bytes: // Measured: `137` // Estimated: `3501` - // Minimum execution time: 9_844_000 picoseconds. - Weight::from_parts(10_240_000, 3501) + // Minimum execution time: 12_119_000 picoseconds. + Weight::from_parts(12_548_000, 3501) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1) - /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: AssetRate ConversionRateToNative (r:1 w:1) + /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) fn remove() -> Weight { // Proof Size summary in bytes: // Measured: `137` // Estimated: `3501` - // Minimum execution time: 10_411_000 picoseconds. - Weight::from_parts(10_686_000, 3501) + // Minimum execution time: 12_541_000 picoseconds. + Weight::from_parts(12_956_000, 3501) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1) - /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: AssetRate ConversionRateToNative (r:1 w:1) + /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) fn create() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3501` - // Minimum execution time: 9_447_000 picoseconds. - Weight::from_parts(10_078_000, 3501) + // Minimum execution time: 11_700_000 picoseconds. + Weight::from_parts(12_158_000, 3501) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1) - /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: AssetRate ConversionRateToNative (r:1 w:1) + /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) fn update() -> Weight { // Proof Size summary in bytes: // Measured: `137` // Estimated: `3501` - // Minimum execution time: 9_844_000 picoseconds. - Weight::from_parts(10_240_000, 3501) + // Minimum execution time: 12_119_000 picoseconds. + Weight::from_parts(12_548_000, 3501) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1) - /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) + /// Storage: AssetRate ConversionRateToNative (r:1 w:1) + /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) fn remove() -> Weight { // Proof Size summary in bytes: // Measured: `137` // Estimated: `3501` - // Minimum execution time: 10_411_000 picoseconds. - Weight::from_parts(10_686_000, 3501) + // Minimum execution time: 12_541_000 picoseconds. + Weight::from_parts(12_956_000, 3501) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/assets/src/weights.rs b/substrate/frame/assets/src/weights.rs index f5199105fe3..f20f7e317cf 100644 --- a/substrate/frame/assets/src/weights.rs +++ b/substrate/frame/assets/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_assets` +//! Autogenerated weights for pallet_assets //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/assets/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/assets/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_assets`. +/// Weight functions needed for pallet_assets. pub trait WeightInfo { fn create() -> Weight; fn force_create() -> Weight; @@ -85,890 +86,882 @@ pub trait WeightInfo { fn block() -> Weight; } -/// Weights for `pallet_assets` using the Substrate node and recommended hardware. +/// Weights for pallet_assets using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn create() -> Weight { // Proof Size summary in bytes: // Measured: `293` // Estimated: `3675` - // Minimum execution time: 24_690_000 picoseconds. - Weight::from_parts(25_878_000, 3675) + // Minimum execution time: 31_340_000 picoseconds. + Weight::from_parts(31_977_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) fn force_create() -> Weight { // Proof Size summary in bytes: // Measured: `153` // Estimated: `3675` - // Minimum execution time: 10_997_000 picoseconds. - Weight::from_parts(11_369_000, 3675) + // Minimum execution time: 13_342_000 picoseconds. + Weight::from_parts(13_782_000, 3675) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) fn start_destroy() -> Weight { // Proof Size summary in bytes: // Measured: `385` // Estimated: `3675` - // Minimum execution time: 11_536_000 picoseconds. - Weight::from_parts(12_309_000, 3675) + // Minimum execution time: 14_437_000 picoseconds. + Weight::from_parts(14_833_000, 3675) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1001 w:1000) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1000 w:1000) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1001 w:1000) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: System Account (r:1000 w:1000) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `c` is `[0, 1000]`. fn destroy_accounts(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + c * (208 ±0)` // Estimated: `3675 + c * (2609 ±0)` - // Minimum execution time: 15_798_000 picoseconds. - Weight::from_parts(16_005_000, 3675) - // Standard Error: 7_818 - .saturating_add(Weight::from_parts(12_826_278, 0).saturating_mul(c.into())) + // Minimum execution time: 18_728_000 picoseconds. + Weight::from_parts(18_982_000, 3675) + // Standard Error: 11_708 + .saturating_add(Weight::from_parts(14_363_570, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(c.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(c.into()))) .saturating_add(Weight::from_parts(0, 2609).saturating_mul(c.into())) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Approvals` (r:1001 w:1000) - /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Approvals (r:1001 w:1000) + /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) /// The range of component `a` is `[0, 1000]`. fn destroy_approvals(a: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `522 + a * (86 ±0)` // Estimated: `3675 + a * (2623 ±0)` - // Minimum execution time: 16_334_000 picoseconds. - Weight::from_parts(16_616_000, 3675) - // Standard Error: 6_402 - .saturating_add(Weight::from_parts(13_502_238, 0).saturating_mul(a.into())) + // Minimum execution time: 18_611_000 picoseconds. + Weight::from_parts(18_970_000, 3675) + // Standard Error: 13_224 + .saturating_add(Weight::from_parts(16_397_299, 0).saturating_mul(a.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(a.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(a.into()))) .saturating_add(Weight::from_parts(0, 2623).saturating_mul(a.into())) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Metadata` (r:1 w:0) - /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Metadata (r:1 w:0) + /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) fn finish_destroy() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 12_278_000 picoseconds. - Weight::from_parts(12_834_000, 3675) + // Minimum execution time: 14_504_000 picoseconds. + Weight::from_parts(14_906_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) fn mint() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 21_793_000 picoseconds. - Weight::from_parts(22_284_000, 3675) + // Minimum execution time: 26_653_000 picoseconds. + Weight::from_parts(27_260_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) fn burn() -> Weight { // Proof Size summary in bytes: // Measured: `459` // Estimated: `3675` - // Minimum execution time: 28_712_000 picoseconds. - Weight::from_parts(29_710_000, 3675) + // Minimum execution time: 33_625_000 picoseconds. + Weight::from_parts(34_474_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:2 w:2) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:2 w:2) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn transfer() -> Weight { // Proof Size summary in bytes: // Measured: `498` // Estimated: `6208` - // Minimum execution time: 41_331_000 picoseconds. - Weight::from_parts(42_362_000, 6208) + // Minimum execution time: 47_609_000 picoseconds. + Weight::from_parts(48_476_000, 6208) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:2 w:2) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:2 w:2) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn transfer_keep_alive() -> Weight { // Proof Size summary in bytes: // Measured: `498` // Estimated: `6208` - // Minimum execution time: 37_316_000 picoseconds. - Weight::from_parts(38_200_000, 6208) + // Minimum execution time: 41_625_000 picoseconds. + Weight::from_parts(43_030_000, 6208) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:2 w:2) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:2 w:2) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn force_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `498` // Estimated: `6208` - // Minimum execution time: 41_347_000 picoseconds. - Weight::from_parts(42_625_000, 6208) + // Minimum execution time: 47_661_000 picoseconds. + Weight::from_parts(48_469_000, 6208) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `Assets::Asset` (r:1 w:0) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:0) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) fn freeze() -> Weight { // Proof Size summary in bytes: // Measured: `459` // Estimated: `3675` - // Minimum execution time: 15_072_000 picoseconds. - Weight::from_parts(15_925_000, 3675) + // Minimum execution time: 17_727_000 picoseconds. + Weight::from_parts(18_384_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:0) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:0) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) fn thaw() -> Weight { // Proof Size summary in bytes: // Measured: `459` // Estimated: `3675` - // Minimum execution time: 14_991_000 picoseconds. - Weight::from_parts(15_987_000, 3675) + // Minimum execution time: 17_657_000 picoseconds. + Weight::from_parts(18_282_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) fn freeze_asset() -> Weight { // Proof Size summary in bytes: // Measured: `385` // Estimated: `3675` - // Minimum execution time: 11_296_000 picoseconds. - Weight::from_parts(12_052_000, 3675) + // Minimum execution time: 13_743_000 picoseconds. + Weight::from_parts(14_193_000, 3675) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) fn thaw_asset() -> Weight { // Proof Size summary in bytes: // Measured: `385` // Estimated: `3675` - // Minimum execution time: 11_446_000 picoseconds. - Weight::from_parts(11_791_000, 3675) + // Minimum execution time: 13_653_000 picoseconds. + Weight::from_parts(14_263_000, 3675) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Metadata` (r:1 w:0) - /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Metadata (r:1 w:0) + /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) fn transfer_ownership() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 13_134_000 picoseconds. - Weight::from_parts(13_401_000, 3675) + // Minimum execution time: 15_328_000 picoseconds. + Weight::from_parts(16_042_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) fn set_team() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 11_395_000 picoseconds. - Weight::from_parts(11_718_000, 3675) + // Minimum execution time: 14_097_000 picoseconds. + Weight::from_parts(14_641_000, 3675) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:0) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Metadata` (r:1 w:1) - /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:0) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Metadata (r:1 w:1) + /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) /// The range of component `n` is `[0, 50]`. /// The range of component `s` is `[0, 50]`. - fn set_metadata(n: u32, _s: u32, ) -> Weight { + fn set_metadata(_n: u32, _s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 25_147_000 picoseconds. - Weight::from_parts(26_614_272, 3675) - // Standard Error: 959 - .saturating_add(Weight::from_parts(2_300, 0).saturating_mul(n.into())) + // Minimum execution time: 29_535_000 picoseconds. + Weight::from_parts(31_456_892, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:0) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Metadata` (r:1 w:1) - /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:0) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Metadata (r:1 w:1) + /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) fn clear_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `515` // Estimated: `3675` - // Minimum execution time: 26_094_000 picoseconds. - Weight::from_parts(27_199_000, 3675) + // Minimum execution time: 30_680_000 picoseconds. + Weight::from_parts(31_930_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:0) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Metadata` (r:1 w:1) - /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:0) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Metadata (r:1 w:1) + /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) /// The range of component `n` is `[0, 50]`. /// The range of component `s` is `[0, 50]`. - fn force_set_metadata(n: u32, s: u32, ) -> Weight { + fn force_set_metadata(_n: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `190` // Estimated: `3675` - // Minimum execution time: 11_977_000 picoseconds. - Weight::from_parts(12_719_933, 3675) - // Standard Error: 429 - .saturating_add(Weight::from_parts(3_239, 0).saturating_mul(n.into())) - // Standard Error: 429 - .saturating_add(Weight::from_parts(3_941, 0).saturating_mul(s.into())) + // Minimum execution time: 14_660_000 picoseconds. + Weight::from_parts(15_718_387, 3675) + // Standard Error: 622 + .saturating_add(Weight::from_parts(2_640, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:0) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Metadata` (r:1 w:1) - /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:0) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Metadata (r:1 w:1) + /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) fn force_clear_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `515` // Estimated: `3675` - // Minimum execution time: 25_859_000 picoseconds. - Weight::from_parts(26_654_000, 3675) + // Minimum execution time: 30_853_000 picoseconds. + Weight::from_parts(31_483_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) fn force_asset_status() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 10_965_000 picoseconds. - Weight::from_parts(11_595_000, 3675) + // Minimum execution time: 13_632_000 picoseconds. + Weight::from_parts(14_077_000, 3675) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Approvals` (r:1 w:1) - /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Approvals (r:1 w:1) + /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) fn approve_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `385` // Estimated: `3675` - // Minimum execution time: 28_427_000 picoseconds. - Weight::from_parts(29_150_000, 3675) + // Minimum execution time: 33_780_000 picoseconds. + Weight::from_parts(34_533_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Approvals` (r:1 w:1) - /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:2 w:2) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Approvals (r:1 w:1) + /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) + /// Storage: Assets Account (r:2 w:2) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn transfer_approved() -> Weight { // Proof Size summary in bytes: // Measured: `668` // Estimated: `6208` - // Minimum execution time: 60_227_000 picoseconds. - Weight::from_parts(61_839_000, 6208) + // Minimum execution time: 67_712_000 picoseconds. + Weight::from_parts(69_946_000, 6208) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Approvals` (r:1 w:1) - /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Approvals (r:1 w:1) + /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) fn cancel_approval() -> Weight { // Proof Size summary in bytes: // Measured: `555` // Estimated: `3675` - // Minimum execution time: 30_738_000 picoseconds. - Weight::from_parts(31_988_000, 3675) + // Minimum execution time: 36_668_000 picoseconds. + Weight::from_parts(37_637_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Approvals` (r:1 w:1) - /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Approvals (r:1 w:1) + /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) fn force_cancel_approval() -> Weight { // Proof Size summary in bytes: // Measured: `555` // Estimated: `3675` - // Minimum execution time: 31_444_000 picoseconds. - Weight::from_parts(32_126_000, 3675) + // Minimum execution time: 36_685_000 picoseconds. + Weight::from_parts(37_950_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) fn set_min_balance() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 11_890_000 picoseconds. - Weight::from_parts(12_462_000, 3675) + // Minimum execution time: 14_466_000 picoseconds. + Weight::from_parts(14_924_000, 3675) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn touch() -> Weight { // Proof Size summary in bytes: // Measured: `453` // Estimated: `3675` - // Minimum execution time: 30_675_000 picoseconds. - Weight::from_parts(31_749_000, 3675) + // Minimum execution time: 34_874_000 picoseconds. + Weight::from_parts(36_330_000, 3675) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) fn touch_other() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 28_290_000 picoseconds. - Weight::from_parts(29_405_000, 3675) + // Minimum execution time: 33_278_000 picoseconds. + Weight::from_parts(34_104_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn refund() -> Weight { // Proof Size summary in bytes: // Measured: `579` // Estimated: `3675` - // Minimum execution time: 30_195_000 picoseconds. - Weight::from_parts(31_105_000, 3675) + // Minimum execution time: 32_898_000 picoseconds. + Weight::from_parts(33_489_000, 3675) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) fn refund_other() -> Weight { // Proof Size summary in bytes: // Measured: `510` // Estimated: `3675` - // Minimum execution time: 27_785_000 picoseconds. - Weight::from_parts(28_783_000, 3675) + // Minimum execution time: 31_243_000 picoseconds. + Weight::from_parts(31_909_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Assets::Asset` (r:1 w:0) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:0) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) fn block() -> Weight { // Proof Size summary in bytes: // Measured: `459` // Estimated: `3675` - // Minimum execution time: 15_318_000 picoseconds. - Weight::from_parts(16_113_000, 3675) + // Minimum execution time: 17_692_000 picoseconds. + Weight::from_parts(18_253_000, 3675) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn create() -> Weight { // Proof Size summary in bytes: // Measured: `293` // Estimated: `3675` - // Minimum execution time: 24_690_000 picoseconds. - Weight::from_parts(25_878_000, 3675) + // Minimum execution time: 31_340_000 picoseconds. + Weight::from_parts(31_977_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) fn force_create() -> Weight { // Proof Size summary in bytes: // Measured: `153` // Estimated: `3675` - // Minimum execution time: 10_997_000 picoseconds. - Weight::from_parts(11_369_000, 3675) + // Minimum execution time: 13_342_000 picoseconds. + Weight::from_parts(13_782_000, 3675) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) fn start_destroy() -> Weight { // Proof Size summary in bytes: // Measured: `385` // Estimated: `3675` - // Minimum execution time: 11_536_000 picoseconds. - Weight::from_parts(12_309_000, 3675) + // Minimum execution time: 14_437_000 picoseconds. + Weight::from_parts(14_833_000, 3675) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1001 w:1000) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1000 w:1000) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1001 w:1000) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: System Account (r:1000 w:1000) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `c` is `[0, 1000]`. fn destroy_accounts(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + c * (208 ±0)` // Estimated: `3675 + c * (2609 ±0)` - // Minimum execution time: 15_798_000 picoseconds. - Weight::from_parts(16_005_000, 3675) - // Standard Error: 7_818 - .saturating_add(Weight::from_parts(12_826_278, 0).saturating_mul(c.into())) + // Minimum execution time: 18_728_000 picoseconds. + Weight::from_parts(18_982_000, 3675) + // Standard Error: 11_708 + .saturating_add(Weight::from_parts(14_363_570, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(c.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(RocksDbWeight::get().writes((2_u64).saturating_mul(c.into()))) .saturating_add(Weight::from_parts(0, 2609).saturating_mul(c.into())) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Approvals` (r:1001 w:1000) - /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Approvals (r:1001 w:1000) + /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) /// The range of component `a` is `[0, 1000]`. fn destroy_approvals(a: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `522 + a * (86 ±0)` // Estimated: `3675 + a * (2623 ±0)` - // Minimum execution time: 16_334_000 picoseconds. - Weight::from_parts(16_616_000, 3675) - // Standard Error: 6_402 - .saturating_add(Weight::from_parts(13_502_238, 0).saturating_mul(a.into())) + // Minimum execution time: 18_611_000 picoseconds. + Weight::from_parts(18_970_000, 3675) + // Standard Error: 13_224 + .saturating_add(Weight::from_parts(16_397_299, 0).saturating_mul(a.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(a.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(a.into()))) .saturating_add(Weight::from_parts(0, 2623).saturating_mul(a.into())) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Metadata` (r:1 w:0) - /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Metadata (r:1 w:0) + /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) fn finish_destroy() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 12_278_000 picoseconds. - Weight::from_parts(12_834_000, 3675) + // Minimum execution time: 14_504_000 picoseconds. + Weight::from_parts(14_906_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) fn mint() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 21_793_000 picoseconds. - Weight::from_parts(22_284_000, 3675) + // Minimum execution time: 26_653_000 picoseconds. + Weight::from_parts(27_260_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) fn burn() -> Weight { // Proof Size summary in bytes: // Measured: `459` // Estimated: `3675` - // Minimum execution time: 28_712_000 picoseconds. - Weight::from_parts(29_710_000, 3675) + // Minimum execution time: 33_625_000 picoseconds. + Weight::from_parts(34_474_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:2 w:2) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:2 w:2) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn transfer() -> Weight { // Proof Size summary in bytes: // Measured: `498` // Estimated: `6208` - // Minimum execution time: 41_331_000 picoseconds. - Weight::from_parts(42_362_000, 6208) + // Minimum execution time: 47_609_000 picoseconds. + Weight::from_parts(48_476_000, 6208) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:2 w:2) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:2 w:2) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn transfer_keep_alive() -> Weight { // Proof Size summary in bytes: // Measured: `498` // Estimated: `6208` - // Minimum execution time: 37_316_000 picoseconds. - Weight::from_parts(38_200_000, 6208) + // Minimum execution time: 41_625_000 picoseconds. + Weight::from_parts(43_030_000, 6208) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:2 w:2) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:2 w:2) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn force_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `498` // Estimated: `6208` - // Minimum execution time: 41_347_000 picoseconds. - Weight::from_parts(42_625_000, 6208) + // Minimum execution time: 47_661_000 picoseconds. + Weight::from_parts(48_469_000, 6208) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `Assets::Asset` (r:1 w:0) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:0) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) fn freeze() -> Weight { // Proof Size summary in bytes: // Measured: `459` // Estimated: `3675` - // Minimum execution time: 15_072_000 picoseconds. - Weight::from_parts(15_925_000, 3675) + // Minimum execution time: 17_727_000 picoseconds. + Weight::from_parts(18_384_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:0) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:0) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) fn thaw() -> Weight { // Proof Size summary in bytes: // Measured: `459` // Estimated: `3675` - // Minimum execution time: 14_991_000 picoseconds. - Weight::from_parts(15_987_000, 3675) + // Minimum execution time: 17_657_000 picoseconds. + Weight::from_parts(18_282_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) fn freeze_asset() -> Weight { // Proof Size summary in bytes: // Measured: `385` // Estimated: `3675` - // Minimum execution time: 11_296_000 picoseconds. - Weight::from_parts(12_052_000, 3675) + // Minimum execution time: 13_743_000 picoseconds. + Weight::from_parts(14_193_000, 3675) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) fn thaw_asset() -> Weight { // Proof Size summary in bytes: // Measured: `385` // Estimated: `3675` - // Minimum execution time: 11_446_000 picoseconds. - Weight::from_parts(11_791_000, 3675) + // Minimum execution time: 13_653_000 picoseconds. + Weight::from_parts(14_263_000, 3675) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Metadata` (r:1 w:0) - /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Metadata (r:1 w:0) + /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) fn transfer_ownership() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 13_134_000 picoseconds. - Weight::from_parts(13_401_000, 3675) + // Minimum execution time: 15_328_000 picoseconds. + Weight::from_parts(16_042_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) fn set_team() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 11_395_000 picoseconds. - Weight::from_parts(11_718_000, 3675) + // Minimum execution time: 14_097_000 picoseconds. + Weight::from_parts(14_641_000, 3675) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:0) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Metadata` (r:1 w:1) - /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:0) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Metadata (r:1 w:1) + /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) /// The range of component `n` is `[0, 50]`. /// The range of component `s` is `[0, 50]`. - fn set_metadata(n: u32, _s: u32, ) -> Weight { + fn set_metadata(_n: u32, _s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 25_147_000 picoseconds. - Weight::from_parts(26_614_272, 3675) - // Standard Error: 959 - .saturating_add(Weight::from_parts(2_300, 0).saturating_mul(n.into())) + // Minimum execution time: 29_535_000 picoseconds. + Weight::from_parts(31_456_892, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:0) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Metadata` (r:1 w:1) - /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:0) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Metadata (r:1 w:1) + /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) fn clear_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `515` // Estimated: `3675` - // Minimum execution time: 26_094_000 picoseconds. - Weight::from_parts(27_199_000, 3675) + // Minimum execution time: 30_680_000 picoseconds. + Weight::from_parts(31_930_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:0) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Metadata` (r:1 w:1) - /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:0) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Metadata (r:1 w:1) + /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) /// The range of component `n` is `[0, 50]`. /// The range of component `s` is `[0, 50]`. - fn force_set_metadata(n: u32, s: u32, ) -> Weight { + fn force_set_metadata(_n: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `190` // Estimated: `3675` - // Minimum execution time: 11_977_000 picoseconds. - Weight::from_parts(12_719_933, 3675) - // Standard Error: 429 - .saturating_add(Weight::from_parts(3_239, 0).saturating_mul(n.into())) - // Standard Error: 429 - .saturating_add(Weight::from_parts(3_941, 0).saturating_mul(s.into())) + // Minimum execution time: 14_660_000 picoseconds. + Weight::from_parts(15_718_387, 3675) + // Standard Error: 622 + .saturating_add(Weight::from_parts(2_640, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:0) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Metadata` (r:1 w:1) - /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:0) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Metadata (r:1 w:1) + /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) fn force_clear_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `515` // Estimated: `3675` - // Minimum execution time: 25_859_000 picoseconds. - Weight::from_parts(26_654_000, 3675) + // Minimum execution time: 30_853_000 picoseconds. + Weight::from_parts(31_483_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) fn force_asset_status() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 10_965_000 picoseconds. - Weight::from_parts(11_595_000, 3675) + // Minimum execution time: 13_632_000 picoseconds. + Weight::from_parts(14_077_000, 3675) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Approvals` (r:1 w:1) - /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Approvals (r:1 w:1) + /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) fn approve_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `385` // Estimated: `3675` - // Minimum execution time: 28_427_000 picoseconds. - Weight::from_parts(29_150_000, 3675) + // Minimum execution time: 33_780_000 picoseconds. + Weight::from_parts(34_533_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Approvals` (r:1 w:1) - /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:2 w:2) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Approvals (r:1 w:1) + /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) + /// Storage: Assets Account (r:2 w:2) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn transfer_approved() -> Weight { // Proof Size summary in bytes: // Measured: `668` // Estimated: `6208` - // Minimum execution time: 60_227_000 picoseconds. - Weight::from_parts(61_839_000, 6208) + // Minimum execution time: 67_712_000 picoseconds. + Weight::from_parts(69_946_000, 6208) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Approvals` (r:1 w:1) - /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Approvals (r:1 w:1) + /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) fn cancel_approval() -> Weight { // Proof Size summary in bytes: // Measured: `555` // Estimated: `3675` - // Minimum execution time: 30_738_000 picoseconds. - Weight::from_parts(31_988_000, 3675) + // Minimum execution time: 36_668_000 picoseconds. + Weight::from_parts(37_637_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Approvals` (r:1 w:1) - /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Approvals (r:1 w:1) + /// Proof: Assets Approvals (max_values: None, max_size: Some(148), added: 2623, mode: MaxEncodedLen) fn force_cancel_approval() -> Weight { // Proof Size summary in bytes: // Measured: `555` // Estimated: `3675` - // Minimum execution time: 31_444_000 picoseconds. - Weight::from_parts(32_126_000, 3675) + // Minimum execution time: 36_685_000 picoseconds. + Weight::from_parts(37_950_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) fn set_min_balance() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 11_890_000 picoseconds. - Weight::from_parts(12_462_000, 3675) + // Minimum execution time: 14_466_000 picoseconds. + Weight::from_parts(14_924_000, 3675) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn touch() -> Weight { // Proof Size summary in bytes: // Measured: `453` // Estimated: `3675` - // Minimum execution time: 30_675_000 picoseconds. - Weight::from_parts(31_749_000, 3675) + // Minimum execution time: 34_874_000 picoseconds. + Weight::from_parts(36_330_000, 3675) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) fn touch_other() -> Weight { // Proof Size summary in bytes: // Measured: `351` // Estimated: `3675` - // Minimum execution time: 28_290_000 picoseconds. - Weight::from_parts(29_405_000, 3675) + // Minimum execution time: 33_278_000 picoseconds. + Weight::from_parts(34_104_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn refund() -> Weight { // Proof Size summary in bytes: // Measured: `579` // Estimated: `3675` - // Minimum execution time: 30_195_000 picoseconds. - Weight::from_parts(31_105_000, 3675) + // Minimum execution time: 32_898_000 picoseconds. + Weight::from_parts(33_489_000, 3675) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) fn refund_other() -> Weight { // Proof Size summary in bytes: // Measured: `510` // Estimated: `3675` - // Minimum execution time: 27_785_000 picoseconds. - Weight::from_parts(28_783_000, 3675) + // Minimum execution time: 31_243_000 picoseconds. + Weight::from_parts(31_909_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Assets::Asset` (r:1 w:0) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: Assets Asset (r:1 w:0) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) fn block() -> Weight { // Proof Size summary in bytes: // Measured: `459` // Estimated: `3675` - // Minimum execution time: 15_318_000 picoseconds. - Weight::from_parts(16_113_000, 3675) + // Minimum execution time: 17_692_000 picoseconds. + Weight::from_parts(18_253_000, 3675) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/babe/src/mock.rs b/substrate/frame/babe/src/mock.rs index 1ba0cdd0cc1..b693f4fce9b 100644 --- a/substrate/frame/babe/src/mock.rs +++ b/substrate/frame/babe/src/mock.rs @@ -37,9 +37,8 @@ use sp_core::{ use sp_io; use sp_runtime::{ curve::PiecewiseLinear, - generic::UncheckedExtrinsic, impl_opaque_keys, - testing::{Digest, DigestItem, Header}, + testing::{Digest, DigestItem, Header, TestXt}, traits::{Header as _, OpaqueKeys}, BuildStorage, Perbill, }; @@ -75,7 +74,7 @@ where RuntimeCall: From, { type OverarchingCall = RuntimeCall; - type Extrinsic = UncheckedExtrinsic; + type Extrinsic = TestXt; } impl_opaque_keys! { diff --git a/substrate/frame/bags-list/src/weights.rs b/substrate/frame/bags-list/src/weights.rs index 804b702cc9a..d929c6bb959 100644 --- a/substrate/frame/bags-list/src/weights.rs +++ b/substrate/frame/bags-list/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_bags_list` +//! Autogenerated weights for pallet_bags_list //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/bags-list/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/bags-list/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,123 +50,123 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_bags_list`. +/// Weight functions needed for pallet_bags_list. pub trait WeightInfo { fn rebag_non_terminal() -> Weight; fn rebag_terminal() -> Weight; fn put_in_front_of() -> Weight; } -/// Weights for `pallet_bags_list` using the Substrate node and recommended hardware. +/// Weights for pallet_bags_list using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Staking::Bonded` (r:1 w:0) - /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::Ledger` (r:1 w:0) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:4 w:4) - /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:1 w:1) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:4 w:4) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) fn rebag_non_terminal() -> Weight { // Proof Size summary in bytes: - // Measured: `1719` + // Measured: `1724` // Estimated: `11506` - // Minimum execution time: 55_856_000 picoseconds. - Weight::from_parts(59_022_000, 11506) + // Minimum execution time: 62_137_000 picoseconds. + Weight::from_parts(64_050_000, 11506) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: `Staking::Bonded` (r:1 w:0) - /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::Ledger` (r:1 w:0) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:3 w:3) - /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:2 w:2) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) fn rebag_terminal() -> Weight { // Proof Size summary in bytes: - // Measured: `1613` + // Measured: `1618` // Estimated: `8877` - // Minimum execution time: 55_418_000 picoseconds. - Weight::from_parts(57_352_000, 8877) + // Minimum execution time: 60_880_000 picoseconds. + Weight::from_parts(62_078_000, 8877) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: `VoterList::ListNodes` (r:4 w:4) - /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `Staking::Bonded` (r:2 w:0) - /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::Ledger` (r:2 w:0) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) - /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:1 w:1) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) + /// Storage: VoterList ListNodes (r:4 w:4) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:2 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:2 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) fn put_in_front_of() -> Weight { // Proof Size summary in bytes: - // Measured: `1925` + // Measured: `1930` // Estimated: `11506` - // Minimum execution time: 63_820_000 picoseconds. - Weight::from_parts(65_530_000, 11506) + // Minimum execution time: 68_911_000 picoseconds. + Weight::from_parts(70_592_000, 11506) .saturating_add(T::DbWeight::get().reads(10_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Staking::Bonded` (r:1 w:0) - /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::Ledger` (r:1 w:0) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:4 w:4) - /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:1 w:1) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:4 w:4) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) fn rebag_non_terminal() -> Weight { // Proof Size summary in bytes: - // Measured: `1719` + // Measured: `1724` // Estimated: `11506` - // Minimum execution time: 55_856_000 picoseconds. - Weight::from_parts(59_022_000, 11506) + // Minimum execution time: 62_137_000 picoseconds. + Weight::from_parts(64_050_000, 11506) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: `Staking::Bonded` (r:1 w:0) - /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::Ledger` (r:1 w:0) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:3 w:3) - /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:2 w:2) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:3 w:3) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:2 w:2) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) fn rebag_terminal() -> Weight { // Proof Size summary in bytes: - // Measured: `1613` + // Measured: `1618` // Estimated: `8877` - // Minimum execution time: 55_418_000 picoseconds. - Weight::from_parts(57_352_000, 8877) + // Minimum execution time: 60_880_000 picoseconds. + Weight::from_parts(62_078_000, 8877) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: `VoterList::ListNodes` (r:4 w:4) - /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `Staking::Bonded` (r:2 w:0) - /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::Ledger` (r:2 w:0) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) - /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:1 w:1) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) + /// Storage: VoterList ListNodes (r:4 w:4) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:2 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:2 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) fn put_in_front_of() -> Weight { // Proof Size summary in bytes: - // Measured: `1925` + // Measured: `1930` // Estimated: `11506` - // Minimum execution time: 63_820_000 picoseconds. - Weight::from_parts(65_530_000, 11506) + // Minimum execution time: 68_911_000 picoseconds. + Weight::from_parts(70_592_000, 11506) .saturating_add(RocksDbWeight::get().reads(10_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } diff --git a/substrate/frame/balances/Cargo.toml b/substrate/frame/balances/Cargo.toml index db114290ed8..64ae90c6757 100644 --- a/substrate/frame/balances/Cargo.toml +++ b/substrate/frame/balances/Cargo.toml @@ -53,7 +53,6 @@ runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "sp-runtime/runtime-benchmarks", ] try-runtime = [ diff --git a/substrate/frame/balances/src/tests/currency_tests.rs b/substrate/frame/balances/src/tests/currency_tests.rs index 10bb79901f8..46a4c4caefc 100644 --- a/substrate/frame/balances/src/tests/currency_tests.rs +++ b/substrate/frame/balances/src/tests/currency_tests.rs @@ -30,7 +30,6 @@ use frame_support::{ StorageNoopGuard, }; use frame_system::Event as SysEvent; -use sp_runtime::traits::DispatchTransaction; const ID_1: LockIdentifier = *b"1 "; const ID_2: LockIdentifier = *b"2 "; @@ -241,17 +240,17 @@ fn lock_should_work_reserve() { TokenError::Frozen ); assert_noop!(Balances::reserve(&1, 1), Error::::LiquidityRestrictions,); - assert!(ChargeTransactionPayment::::validate_and_prepare( + assert!( as SignedExtension>::pre_dispatch( ChargeTransactionPayment::from(1), - Some(1).into(), + &1, CALL, &info_from_weight(Weight::from_parts(1, 0)), 1, ) .is_err()); - assert!(ChargeTransactionPayment::::validate_and_prepare( + assert!( as SignedExtension>::pre_dispatch( ChargeTransactionPayment::from(0), - Some(1).into(), + &1, CALL, &info_from_weight(Weight::from_parts(1, 0)), 1, @@ -272,17 +271,17 @@ fn lock_should_work_tx_fee() { TokenError::Frozen ); assert_noop!(Balances::reserve(&1, 1), Error::::LiquidityRestrictions,); - assert!(ChargeTransactionPayment::::validate_and_prepare( + assert!( as SignedExtension>::pre_dispatch( ChargeTransactionPayment::from(1), - Some(1).into(), + &1, CALL, &info_from_weight(Weight::from_parts(1, 0)), 1, ) .is_err()); - assert!(ChargeTransactionPayment::::validate_and_prepare( + assert!( as SignedExtension>::pre_dispatch( ChargeTransactionPayment::from(0), - Some(1).into(), + &1, CALL, &info_from_weight(Weight::from_parts(1, 0)), 1, diff --git a/substrate/frame/balances/src/tests/mod.rs b/substrate/frame/balances/src/tests/mod.rs index ee076a10fd1..599909fa943 100644 --- a/substrate/frame/balances/src/tests/mod.rs +++ b/substrate/frame/balances/src/tests/mod.rs @@ -37,7 +37,7 @@ use scale_info::TypeInfo; use sp_core::hexdisplay::HexDisplay; use sp_io; use sp_runtime::{ - traits::{BadOrigin, Zero}, + traits::{BadOrigin, SignedExtension, Zero}, ArithmeticError, BuildStorage, DispatchError, DispatchResult, FixedPointNumber, RuntimeDebug, TokenError, }; @@ -96,13 +96,13 @@ impl frame_system::Config for Test { type AccountData = super::AccountData; } -#[derive_impl(pallet_transaction_payment::config_preludes::TestDefaultConfig as pallet_transaction_payment::DefaultConfig)] impl pallet_transaction_payment::Config for Test { type RuntimeEvent = RuntimeEvent; type OnChargeTransaction = CurrencyAdapter, ()>; type OperationalFeeMultiplier = ConstU8<5>; type WeightToFee = IdentityFee; type LengthToFee = IdentityFee; + type FeeMultiplierUpdate = (); } pub(crate) type Balance = u64; diff --git a/substrate/frame/balances/src/weights.rs b/substrate/frame/balances/src/weights.rs index 6bcfe050af7..f875ea189ba 100644 --- a/substrate/frame/balances/src/weights.rs +++ b/substrate/frame/balances/src/weights.rs @@ -17,28 +17,26 @@ //! Autogenerated weights for `pallet_balances` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2024-01-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate-node +// target/production/substrate-node // benchmark // pallet -// --chain=dev // --steps=50 // --repeat=20 -// --pallet=pallet_balances -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/balances/src/weights.rs +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_balances +// --chain=dev // --header=./substrate/HEADER-APACHE2 +// --output=./substrate/frame/balances/src/weights.rs // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -71,8 +69,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 46_407_000 picoseconds. - Weight::from_parts(47_561_000, 3593) + // Minimum execution time: 46_329_000 picoseconds. + Weight::from_parts(47_297_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -82,8 +80,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 36_574_000 picoseconds. - Weight::from_parts(37_682_000, 3593) + // Minimum execution time: 36_187_000 picoseconds. + Weight::from_parts(36_900_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -93,8 +91,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 13_990_000 picoseconds. - Weight::from_parts(14_568_000, 3593) + // Minimum execution time: 13_498_000 picoseconds. + Weight::from_parts(14_143_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -104,8 +102,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 19_594_000 picoseconds. - Weight::from_parts(20_148_000, 3593) + // Minimum execution time: 18_756_000 picoseconds. + Weight::from_parts(19_553_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -115,8 +113,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `103` // Estimated: `6196` - // Minimum execution time: 47_945_000 picoseconds. - Weight::from_parts(49_363_000, 6196) + // Minimum execution time: 47_826_000 picoseconds. + Weight::from_parts(48_834_000, 6196) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -126,8 +124,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 45_205_000 picoseconds. - Weight::from_parts(45_952_000, 3593) + // Minimum execution time: 44_621_000 picoseconds. + Weight::from_parts(45_151_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -137,8 +135,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 16_593_000 picoseconds. - Weight::from_parts(17_123_000, 3593) + // Minimum execution time: 16_194_000 picoseconds. + Weight::from_parts(16_945_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -149,10 +147,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0 + u * (135 ±0)` // Estimated: `990 + u * (2603 ±0)` - // Minimum execution time: 16_182_000 picoseconds. - Weight::from_parts(16_412_000, 990) - // Standard Error: 10_148 - .saturating_add(Weight::from_parts(13_382_459, 0).saturating_mul(u.into())) + // Minimum execution time: 15_782_000 picoseconds. + Weight::from_parts(16_118_000, 990) + // Standard Error: 10_499 + .saturating_add(Weight::from_parts(13_327_660, 0).saturating_mul(u.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into()))) .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) @@ -161,8 +159,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_478_000 picoseconds. - Weight::from_parts(6_830_000, 0) + // Minimum execution time: 6_157_000 picoseconds. + Weight::from_parts(6_507_000, 0) } } @@ -174,8 +172,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 46_407_000 picoseconds. - Weight::from_parts(47_561_000, 3593) + // Minimum execution time: 46_329_000 picoseconds. + Weight::from_parts(47_297_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -185,8 +183,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 36_574_000 picoseconds. - Weight::from_parts(37_682_000, 3593) + // Minimum execution time: 36_187_000 picoseconds. + Weight::from_parts(36_900_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -196,8 +194,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 13_990_000 picoseconds. - Weight::from_parts(14_568_000, 3593) + // Minimum execution time: 13_498_000 picoseconds. + Weight::from_parts(14_143_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -207,8 +205,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 19_594_000 picoseconds. - Weight::from_parts(20_148_000, 3593) + // Minimum execution time: 18_756_000 picoseconds. + Weight::from_parts(19_553_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -218,8 +216,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `103` // Estimated: `6196` - // Minimum execution time: 47_945_000 picoseconds. - Weight::from_parts(49_363_000, 6196) + // Minimum execution time: 47_826_000 picoseconds. + Weight::from_parts(48_834_000, 6196) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -229,8 +227,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 45_205_000 picoseconds. - Weight::from_parts(45_952_000, 3593) + // Minimum execution time: 44_621_000 picoseconds. + Weight::from_parts(45_151_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -240,8 +238,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 16_593_000 picoseconds. - Weight::from_parts(17_123_000, 3593) + // Minimum execution time: 16_194_000 picoseconds. + Weight::from_parts(16_945_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -252,10 +250,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0 + u * (135 ±0)` // Estimated: `990 + u * (2603 ±0)` - // Minimum execution time: 16_182_000 picoseconds. - Weight::from_parts(16_412_000, 990) - // Standard Error: 10_148 - .saturating_add(Weight::from_parts(13_382_459, 0).saturating_mul(u.into())) + // Minimum execution time: 15_782_000 picoseconds. + Weight::from_parts(16_118_000, 990) + // Standard Error: 10_499 + .saturating_add(Weight::from_parts(13_327_660, 0).saturating_mul(u.into())) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(u.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(u.into()))) .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) @@ -264,7 +262,7 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_478_000 picoseconds. - Weight::from_parts(6_830_000, 0) + // Minimum execution time: 6_157_000 picoseconds. + Weight::from_parts(6_507_000, 0) } } diff --git a/substrate/frame/beefy/src/mock.rs b/substrate/frame/beefy/src/mock.rs index 5d963d309a4..9cce479890a 100644 --- a/substrate/frame/beefy/src/mock.rs +++ b/substrate/frame/beefy/src/mock.rs @@ -29,8 +29,8 @@ use pallet_session::historical as pallet_session_historical; use sp_core::{crypto::KeyTypeId, ConstU128}; use sp_io::TestExternalities; use sp_runtime::{ - app_crypto::ecdsa::Public, curve::PiecewiseLinear, generic::UncheckedExtrinsic, - impl_opaque_keys, traits::OpaqueKeys, BuildStorage, Perbill, + app_crypto::ecdsa::Public, curve::PiecewiseLinear, impl_opaque_keys, testing::TestXt, + traits::OpaqueKeys, BuildStorage, Perbill, }; use sp_staking::{EraIndex, SessionIndex}; use sp_state_machine::BasicExternalities; @@ -73,7 +73,7 @@ where RuntimeCall: From, { type OverarchingCall = RuntimeCall; - type Extrinsic = UncheckedExtrinsic; + type Extrinsic = TestXt; } parameter_types! { diff --git a/substrate/frame/benchmarking/src/weights.rs b/substrate/frame/benchmarking/src/weights.rs index 76f9a3fe52b..13d73e420cc 100644 --- a/substrate/frame/benchmarking/src/weights.rs +++ b/substrate/frame/benchmarking/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `frame_benchmarking` +//! Autogenerated weights for frame_benchmarking //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/benchmarking/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/benchmarking/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `frame_benchmarking`. +/// Weight functions needed for frame_benchmarking. pub trait WeightInfo { fn addition(i: u32, ) -> Weight; fn subtraction(i: u32, ) -> Weight; @@ -59,7 +60,7 @@ pub trait WeightInfo { fn sr25519_verification(i: u32, ) -> Weight; } -/// Weights for `frame_benchmarking` using the Substrate node and recommended hardware. +/// Weights for frame_benchmarking using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { /// The range of component `i` is `[0, 1000000]`. @@ -67,101 +68,101 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 150_000 picoseconds. - Weight::from_parts(190_440, 0) + // Minimum execution time: 147_000 picoseconds. + Weight::from_parts(185_656, 0) } /// The range of component `i` is `[0, 1000000]`. fn subtraction(_i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 151_000 picoseconds. - Weight::from_parts(201_397, 0) + // Minimum execution time: 146_000 picoseconds. + Weight::from_parts(189_816, 0) } /// The range of component `i` is `[0, 1000000]`. fn multiplication(_i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 152_000 picoseconds. - Weight::from_parts(187_862, 0) + // Minimum execution time: 148_000 picoseconds. + Weight::from_parts(202_367, 0) } /// The range of component `i` is `[0, 1000000]`. fn division(_i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 146_000 picoseconds. - Weight::from_parts(215_191, 0) + // Minimum execution time: 143_000 picoseconds. + Weight::from_parts(189_693, 0) } fn hashing() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 25_432_823_000 picoseconds. - Weight::from_parts(25_568_846_000, 0) + // Minimum execution time: 24_167_071_000 picoseconds. + Weight::from_parts(24_391_749_000, 0) } /// The range of component `i` is `[0, 100]`. fn sr25519_verification(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 193_000 picoseconds. - Weight::from_parts(3_846_690, 0) - // Standard Error: 6_694 - .saturating_add(Weight::from_parts(40_647_582, 0).saturating_mul(i.into())) + // Minimum execution time: 231_000 picoseconds. + Weight::from_parts(2_998_013, 0) + // Standard Error: 6_256 + .saturating_add(Weight::from_parts(55_456_705, 0).saturating_mul(i.into())) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { /// The range of component `i` is `[0, 1000000]`. fn addition(_i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 150_000 picoseconds. - Weight::from_parts(190_440, 0) + // Minimum execution time: 147_000 picoseconds. + Weight::from_parts(185_656, 0) } /// The range of component `i` is `[0, 1000000]`. fn subtraction(_i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 151_000 picoseconds. - Weight::from_parts(201_397, 0) + // Minimum execution time: 146_000 picoseconds. + Weight::from_parts(189_816, 0) } /// The range of component `i` is `[0, 1000000]`. fn multiplication(_i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 152_000 picoseconds. - Weight::from_parts(187_862, 0) + // Minimum execution time: 148_000 picoseconds. + Weight::from_parts(202_367, 0) } /// The range of component `i` is `[0, 1000000]`. fn division(_i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 146_000 picoseconds. - Weight::from_parts(215_191, 0) + // Minimum execution time: 143_000 picoseconds. + Weight::from_parts(189_693, 0) } fn hashing() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 25_432_823_000 picoseconds. - Weight::from_parts(25_568_846_000, 0) + // Minimum execution time: 24_167_071_000 picoseconds. + Weight::from_parts(24_391_749_000, 0) } /// The range of component `i` is `[0, 100]`. fn sr25519_verification(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 193_000 picoseconds. - Weight::from_parts(3_846_690, 0) - // Standard Error: 6_694 - .saturating_add(Weight::from_parts(40_647_582, 0).saturating_mul(i.into())) + // Minimum execution time: 231_000 picoseconds. + Weight::from_parts(2_998_013, 0) + // Standard Error: 6_256 + .saturating_add(Weight::from_parts(55_456_705, 0).saturating_mul(i.into())) } } diff --git a/substrate/frame/bounties/src/weights.rs b/substrate/frame/bounties/src/weights.rs index 1f0e38b6702..a172d15b56c 100644 --- a/substrate/frame/bounties/src/weights.rs +++ b/substrate/frame/bounties/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_bounties` +//! Autogenerated weights for pallet_bounties //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/bounties/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/bounties/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_bounties`. +/// Weight functions needed for pallet_bounties. pub trait WeightInfo { fn propose_bounty(d: u32, ) -> Weight; fn approve_bounty() -> Weight; @@ -64,169 +65,169 @@ pub trait WeightInfo { fn spend_funds(b: u32, ) -> Weight; } -/// Weights for `pallet_bounties` using the Substrate node and recommended hardware. +/// Weights for pallet_bounties using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Bounties::BountyCount` (r:1 w:1) - /// Proof: `Bounties::BountyCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) - /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) - /// Storage: `Bounties::Bounties` (r:0 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: Bounties BountyCount (r:1 w:1) + /// Proof: Bounties BountyCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) + /// Storage: Bounties Bounties (r:0 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) /// The range of component `d` is `[0, 300]`. fn propose_bounty(d: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `309` + // Measured: `276` // Estimated: `3593` - // Minimum execution time: 24_286_000 picoseconds. - Weight::from_parts(25_657_314, 3593) - // Standard Error: 215 - .saturating_add(Weight::from_parts(1_116, 0).saturating_mul(d.into())) + // Minimum execution time: 29_384_000 picoseconds. + Weight::from_parts(30_820_018, 3593) + // Standard Error: 298 + .saturating_add(Weight::from_parts(2_920, 0).saturating_mul(d.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `Bounties::BountyApprovals` (r:1 w:1) - /// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: Bounties BountyApprovals (r:1 w:1) + /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) fn approve_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `401` + // Measured: `368` // Estimated: `3642` - // Minimum execution time: 12_526_000 picoseconds. - Weight::from_parts(13_373_000, 3642) + // Minimum execution time: 10_873_000 picoseconds. + Weight::from_parts(11_421_000, 3642) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) fn propose_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `421` + // Measured: `388` // Estimated: `3642` - // Minimum execution time: 11_807_000 picoseconds. - Weight::from_parts(12_340_000, 3642) + // Minimum execution time: 9_181_000 picoseconds. + Weight::from_parts(9_726_000, 3642) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn unassign_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `597` + // Measured: `564` // Estimated: `3642` - // Minimum execution time: 27_183_000 picoseconds. - Weight::from_parts(28_250_000, 3642) + // Minimum execution time: 30_257_000 picoseconds. + Weight::from_parts(30_751_000, 3642) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn accept_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `593` + // Measured: `560` // Estimated: `3642` - // Minimum execution time: 26_775_000 picoseconds. - Weight::from_parts(27_667_000, 3642) + // Minimum execution time: 27_850_000 picoseconds. + Weight::from_parts(28_821_000, 3642) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:0) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) fn award_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `605` + // Measured: `572` // Estimated: `3642` - // Minimum execution time: 16_089_000 picoseconds. - Weight::from_parts(16_909_000, 3642) + // Minimum execution time: 19_164_000 picoseconds. + Weight::from_parts(20_136_000, 3642) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:3 w:3) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) - /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) - /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:3 w:3) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) + /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) fn claim_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `969` + // Measured: `936` // Estimated: `8799` - // Minimum execution time: 104_973_000 picoseconds. - Weight::from_parts(107_696_000, 8799) + // Minimum execution time: 120_235_000 picoseconds. + Weight::from_parts(121_673_000, 8799) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) - /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:0) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) fn close_bounty_proposed() -> Weight { // Proof Size summary in bytes: - // Measured: `649` + // Measured: `616` // Estimated: `3642` - // Minimum execution time: 30_702_000 picoseconds. - Weight::from_parts(32_615_000, 3642) + // Minimum execution time: 35_713_000 picoseconds. + Weight::from_parts(37_174_000, 3642) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) - /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:0) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) fn close_bounty_active() -> Weight { // Proof Size summary in bytes: - // Measured: `885` + // Measured: `852` // Estimated: `6196` - // Minimum execution time: 72_055_000 picoseconds. - Weight::from_parts(73_900_000, 6196) + // Minimum execution time: 81_037_000 picoseconds. + Weight::from_parts(83_294_000, 6196) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) fn extend_bounty_expiry() -> Weight { // Proof Size summary in bytes: - // Measured: `457` + // Measured: `424` // Estimated: `3642` - // Minimum execution time: 12_057_000 picoseconds. - Weight::from_parts(12_744_000, 3642) + // Minimum execution time: 15_348_000 picoseconds. + Weight::from_parts(15_776_000, 3642) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Bounties::BountyApprovals` (r:1 w:1) - /// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) - /// Storage: `Bounties::Bounties` (r:100 w:100) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:200 w:200) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Bounties BountyApprovals (r:1 w:1) + /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: Bounties Bounties (r:100 w:100) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:200 w:200) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `b` is `[0, 100]`. fn spend_funds(b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `37 + b * (297 ±0)` + // Measured: `4 + b * (297 ±0)` // Estimated: `1887 + b * (5206 ±0)` - // Minimum execution time: 3_489_000 picoseconds. - Weight::from_parts(8_384_129, 1887) - // Standard Error: 18_066 - .saturating_add(Weight::from_parts(31_612_331, 0).saturating_mul(b.into())) + // Minimum execution time: 5_082_000 picoseconds. + Weight::from_parts(5_126_000, 1887) + // Standard Error: 21_949 + .saturating_add(Weight::from_parts(42_635_308, 0).saturating_mul(b.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(b.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) @@ -235,168 +236,168 @@ impl WeightInfo for SubstrateWeight { } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Bounties::BountyCount` (r:1 w:1) - /// Proof: `Bounties::BountyCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) - /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) - /// Storage: `Bounties::Bounties` (r:0 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: Bounties BountyCount (r:1 w:1) + /// Proof: Bounties BountyCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) + /// Storage: Bounties Bounties (r:0 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) /// The range of component `d` is `[0, 300]`. fn propose_bounty(d: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `309` + // Measured: `276` // Estimated: `3593` - // Minimum execution time: 24_286_000 picoseconds. - Weight::from_parts(25_657_314, 3593) - // Standard Error: 215 - .saturating_add(Weight::from_parts(1_116, 0).saturating_mul(d.into())) + // Minimum execution time: 29_384_000 picoseconds. + Weight::from_parts(30_820_018, 3593) + // Standard Error: 298 + .saturating_add(Weight::from_parts(2_920, 0).saturating_mul(d.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `Bounties::BountyApprovals` (r:1 w:1) - /// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: Bounties BountyApprovals (r:1 w:1) + /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) fn approve_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `401` + // Measured: `368` // Estimated: `3642` - // Minimum execution time: 12_526_000 picoseconds. - Weight::from_parts(13_373_000, 3642) + // Minimum execution time: 10_873_000 picoseconds. + Weight::from_parts(11_421_000, 3642) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) fn propose_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `421` + // Measured: `388` // Estimated: `3642` - // Minimum execution time: 11_807_000 picoseconds. - Weight::from_parts(12_340_000, 3642) + // Minimum execution time: 9_181_000 picoseconds. + Weight::from_parts(9_726_000, 3642) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn unassign_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `597` + // Measured: `564` // Estimated: `3642` - // Minimum execution time: 27_183_000 picoseconds. - Weight::from_parts(28_250_000, 3642) + // Minimum execution time: 30_257_000 picoseconds. + Weight::from_parts(30_751_000, 3642) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn accept_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `593` + // Measured: `560` // Estimated: `3642` - // Minimum execution time: 26_775_000 picoseconds. - Weight::from_parts(27_667_000, 3642) + // Minimum execution time: 27_850_000 picoseconds. + Weight::from_parts(28_821_000, 3642) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:0) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) fn award_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `605` + // Measured: `572` // Estimated: `3642` - // Minimum execution time: 16_089_000 picoseconds. - Weight::from_parts(16_909_000, 3642) + // Minimum execution time: 19_164_000 picoseconds. + Weight::from_parts(20_136_000, 3642) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:3 w:3) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) - /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) - /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:3 w:3) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) + /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) fn claim_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `969` + // Measured: `936` // Estimated: `8799` - // Minimum execution time: 104_973_000 picoseconds. - Weight::from_parts(107_696_000, 8799) + // Minimum execution time: 120_235_000 picoseconds. + Weight::from_parts(121_673_000, 8799) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) - /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:0) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) fn close_bounty_proposed() -> Weight { // Proof Size summary in bytes: - // Measured: `649` + // Measured: `616` // Estimated: `3642` - // Minimum execution time: 30_702_000 picoseconds. - Weight::from_parts(32_615_000, 3642) + // Minimum execution time: 35_713_000 picoseconds. + Weight::from_parts(37_174_000, 3642) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Bounties::BountyDescriptions` (r:0 w:1) - /// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:0) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyDescriptions (r:0 w:1) + /// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) fn close_bounty_active() -> Weight { // Proof Size summary in bytes: - // Measured: `885` + // Measured: `852` // Estimated: `6196` - // Minimum execution time: 72_055_000 picoseconds. - Weight::from_parts(73_900_000, 6196) + // Minimum execution time: 81_037_000 picoseconds. + Weight::from_parts(83_294_000, 6196) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:1) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:1) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) fn extend_bounty_expiry() -> Weight { // Proof Size summary in bytes: - // Measured: `457` + // Measured: `424` // Estimated: `3642` - // Minimum execution time: 12_057_000 picoseconds. - Weight::from_parts(12_744_000, 3642) + // Minimum execution time: 15_348_000 picoseconds. + Weight::from_parts(15_776_000, 3642) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Bounties::BountyApprovals` (r:1 w:1) - /// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) - /// Storage: `Bounties::Bounties` (r:100 w:100) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:200 w:200) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Bounties BountyApprovals (r:1 w:1) + /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: Bounties Bounties (r:100 w:100) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:200 w:200) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `b` is `[0, 100]`. fn spend_funds(b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `37 + b * (297 ±0)` + // Measured: `4 + b * (297 ±0)` // Estimated: `1887 + b * (5206 ±0)` - // Minimum execution time: 3_489_000 picoseconds. - Weight::from_parts(8_384_129, 1887) - // Standard Error: 18_066 - .saturating_add(Weight::from_parts(31_612_331, 0).saturating_mul(b.into())) + // Minimum execution time: 5_082_000 picoseconds. + Weight::from_parts(5_126_000, 1887) + // Standard Error: 21_949 + .saturating_add(Weight::from_parts(42_635_308, 0).saturating_mul(b.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(b.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) diff --git a/substrate/frame/broker/src/weights.rs b/substrate/frame/broker/src/weights.rs index 133ea63e35f..a8f50eeee6e 100644 --- a/substrate/frame/broker/src/weights.rs +++ b/substrate/frame/broker/src/weights.rs @@ -17,28 +17,26 @@ //! Autogenerated weights for `pallet_broker` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-09-04, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-pzhd7p6z-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate-node +// target/production/substrate-node // benchmark // pallet -// --chain=dev // --steps=50 // --repeat=20 -// --pallet=pallet_broker -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/broker/src/weights.rs +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_broker +// --chain=dev // --header=./substrate/HEADER-APACHE2 +// --output=./substrate/frame/broker/src/weights.rs // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -89,8 +87,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_701_000 picoseconds. - Weight::from_parts(2_902_000, 0) + // Minimum execution time: 3_040_000 picoseconds. + Weight::from_parts(3_344_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Broker::Reservations` (r:1 w:1) @@ -99,8 +97,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `5016` // Estimated: `7496` - // Minimum execution time: 18_056_000 picoseconds. - Weight::from_parts(19_093_000, 7496) + // Minimum execution time: 21_259_000 picoseconds. + Weight::from_parts(22_110_000, 7496) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -110,8 +108,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `6218` // Estimated: `7496` - // Minimum execution time: 17_233_000 picoseconds. - Weight::from_parts(17_788_000, 7496) + // Minimum execution time: 20_330_000 picoseconds. + Weight::from_parts(20_826_000, 7496) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -121,8 +119,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `239` // Estimated: `1526` - // Minimum execution time: 9_740_000 picoseconds. - Weight::from_parts(10_504_000, 1526) + // Minimum execution time: 13_411_000 picoseconds. + Weight::from_parts(13_960_000, 1526) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -141,12 +139,14 @@ impl WeightInfo for SubstrateWeight { /// Storage: `Broker::Workplan` (r:0 w:10) /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. - fn start_sales(_n: u32, ) -> Weight { + fn start_sales(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `6330` // Estimated: `8499` - // Minimum execution time: 49_728_000 picoseconds. - Weight::from_parts(52_765_861, 8499) + // Minimum execution time: 57_770_000 picoseconds. + Weight::from_parts(61_047_512, 8499) + // Standard Error: 165 + .saturating_add(Weight::from_parts(3, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(16_u64)) } @@ -162,10 +162,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) fn purchase() -> Weight { // Proof Size summary in bytes: - // Measured: `635` - // Estimated: `2120` - // Minimum execution time: 41_986_000 picoseconds. - Weight::from_parts(43_465_000, 2120) + // Measured: `568` + // Estimated: `2053` + // Minimum execution time: 51_196_000 picoseconds. + Weight::from_parts(52_382_000, 2053) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -185,10 +185,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) fn renew() -> Weight { // Proof Size summary in bytes: - // Measured: `753` + // Measured: `686` // Estimated: `4698` - // Minimum execution time: 61_779_000 picoseconds. - Weight::from_parts(62_563_000, 4698) + // Minimum execution time: 71_636_000 picoseconds. + Weight::from_parts(73_679_000, 4698) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -198,8 +198,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3550` - // Minimum execution time: 16_962_000 picoseconds. - Weight::from_parts(17_733_000, 3550) + // Minimum execution time: 19_182_000 picoseconds. + Weight::from_parts(19_775_000, 3550) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -209,21 +209,21 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3550` - // Minimum execution time: 18_380_000 picoseconds. - Weight::from_parts(19_105_000, 3550) + // Minimum execution time: 20_688_000 picoseconds. + Weight::from_parts(21_557_000, 3550) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Broker::Regions` (r:1 w:3) + /// Storage: `Broker::Regions` (r:1 w:2) /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) fn interlace() -> Weight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3550` - // Minimum execution time: 20_115_000 picoseconds. - Weight::from_parts(20_741_000, 3550) + // Minimum execution time: 21_190_000 picoseconds. + Weight::from_parts(22_215_000, 3550) .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Broker::Configuration` (r:1 w:0) /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) @@ -237,8 +237,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `740` // Estimated: `4681` - // Minimum execution time: 31_339_000 picoseconds. - Weight::from_parts(32_639_000, 4681) + // Minimum execution time: 34_591_000 picoseconds. + Weight::from_parts(36_227_000, 4681) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -256,8 +256,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `775` // Estimated: `5996` - // Minimum execution time: 37_542_000 picoseconds. - Weight::from_parts(38_521_000, 5996) + // Minimum execution time: 40_346_000 picoseconds. + Weight::from_parts(41_951_000, 5996) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } @@ -272,10 +272,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `859` // Estimated: `6196 + m * (2520 ±0)` - // Minimum execution time: 66_176_000 picoseconds. - Weight::from_parts(68_356_745, 6196) - // Standard Error: 68_008 - .saturating_add(Weight::from_parts(1_558_419, 0).saturating_mul(m.into())) + // Minimum execution time: 75_734_000 picoseconds. + Weight::from_parts(78_168_395, 6196) + // Standard Error: 63_180 + .saturating_add(Weight::from_parts(1_076_259, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(m.into()))) .saturating_add(T::DbWeight::get().writes(5_u64)) @@ -287,8 +287,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `103` // Estimated: `3593` - // Minimum execution time: 41_130_000 picoseconds. - Weight::from_parts(41_914_000, 3593) + // Minimum execution time: 46_383_000 picoseconds. + Weight::from_parts(47_405_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -300,8 +300,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `603` // Estimated: `3550` - // Minimum execution time: 31_042_000 picoseconds. - Weight::from_parts(34_087_000, 3550) + // Minimum execution time: 30_994_000 picoseconds. + Weight::from_parts(31_979_000, 3550) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -315,8 +315,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `601` // Estimated: `3533` - // Minimum execution time: 39_116_000 picoseconds. - Weight::from_parts(39_990_000, 3533) + // Minimum execution time: 37_584_000 picoseconds. + Weight::from_parts(44_010_000, 3533) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -330,10 +330,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn drop_history() -> Weight { // Proof Size summary in bytes: - // Measured: `995` + // Measured: `830` // Estimated: `3593` - // Minimum execution time: 47_547_000 picoseconds. - Weight::from_parts(50_274_000, 3593) + // Minimum execution time: 45_266_000 picoseconds. + Weight::from_parts(48_000_000, 3593) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -343,32 +343,34 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Broker::AllowedRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`) fn drop_renewal() -> Weight { // Proof Size summary in bytes: - // Measured: `661` + // Measured: `525` // Estimated: `4698` - // Minimum execution time: 26_707_000 picoseconds. - Weight::from_parts(27_217_000, 4698) + // Minimum execution time: 25_365_000 picoseconds. + Weight::from_parts(26_920_000, 4698) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// The range of component `n` is `[0, 1000]`. - fn request_core_count(_n: u32, ) -> Weight { + fn request_core_count(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_651_000 picoseconds. - Weight::from_parts(5_231_385, 0) + // Minimum execution time: 6_519_000 picoseconds. + Weight::from_parts(7_098_698, 0) + // Standard Error: 20 + .saturating_add(Weight::from_parts(8, 0).saturating_mul(n.into())) } - /// Storage: `Broker::CoreCountInbox` (r:1 w:1) - /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:1) + /// Proof: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:1) /// The range of component `n` is `[0, 1000]`. fn process_core_count(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `404` - // Estimated: `1487` - // Minimum execution time: 6_806_000 picoseconds. - Weight::from_parts(7_264_002, 1487) - // Standard Error: 21 - .saturating_add(Weight::from_parts(31, 0).saturating_mul(n.into())) + // Measured: `98` + // Estimated: `3563` + // Minimum execution time: 7_608_000 picoseconds. + Weight::from_parts(8_157_815, 3563) + // Standard Error: 26 + .saturating_add(Weight::from_parts(48, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -384,10 +386,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn process_revenue() -> Weight { // Proof Size summary in bytes: - // Measured: `972` - // Estimated: `4437` - // Minimum execution time: 48_297_000 picoseconds. - Weight::from_parts(49_613_000, 4437) + // Measured: `905` + // Estimated: `4370` + // Minimum execution time: 59_993_000 picoseconds. + Weight::from_parts(61_752_000, 4370) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -406,10 +408,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `6281` // Estimated: `8499` - // Minimum execution time: 36_715_000 picoseconds. - Weight::from_parts(38_580_380, 8499) - // Standard Error: 91 - .saturating_add(Weight::from_parts(1_163, 0).saturating_mul(n.into())) + // Minimum execution time: 41_863_000 picoseconds. + Weight::from_parts(44_033_031, 8499) + // Standard Error: 116 + .saturating_add(Weight::from_parts(764, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(15_u64)) } @@ -421,8 +423,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `180` // Estimated: `3493` - // Minimum execution time: 7_564_000 picoseconds. - Weight::from_parts(7_932_000, 3493) + // Minimum execution time: 9_588_000 picoseconds. + Weight::from_parts(9_925_000, 3493) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -434,8 +436,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1423` // Estimated: `4681` - // Minimum execution time: 17_082_000 picoseconds. - Weight::from_parts(17_662_000, 4681) + // Minimum execution time: 19_308_000 picoseconds. + Weight::from_parts(20_482_000, 4681) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -443,35 +445,28 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 175_000 picoseconds. - Weight::from_parts(223_000, 0) + // Minimum execution time: 147_000 picoseconds. + Weight::from_parts(184_000, 0) } - /// Storage: `Broker::CoreCountInbox` (r:0 w:1) - /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) fn notify_core_count() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 2_432_000 picoseconds. - Weight::from_parts(2_536_000, 0) - .saturating_add(T::DbWeight::get().writes(1_u64)) + T::DbWeight::get().reads_writes(1, 1) } /// Storage: `Broker::Status` (r:1 w:1) /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) /// Storage: `Broker::Configuration` (r:1 w:0) /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) - /// Storage: `Broker::CoreCountInbox` (r:1 w:0) - /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:1) + /// Proof: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:1) /// Storage: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) /// Proof: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) fn do_tick_base() -> Weight { // Proof Size summary in bytes: - // Measured: `603` - // Estimated: `4068` - // Minimum execution time: 13_080_000 picoseconds. - Weight::from_parts(13_937_000, 4068) + // Measured: `699` + // Estimated: `4164` + // Minimum execution time: 19_824_000 picoseconds. + Weight::from_parts(20_983_000, 4164) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) } } @@ -483,8 +478,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_701_000 picoseconds. - Weight::from_parts(2_902_000, 0) + // Minimum execution time: 3_040_000 picoseconds. + Weight::from_parts(3_344_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Broker::Reservations` (r:1 w:1) @@ -493,8 +488,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `5016` // Estimated: `7496` - // Minimum execution time: 18_056_000 picoseconds. - Weight::from_parts(19_093_000, 7496) + // Minimum execution time: 21_259_000 picoseconds. + Weight::from_parts(22_110_000, 7496) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -504,8 +499,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `6218` // Estimated: `7496` - // Minimum execution time: 17_233_000 picoseconds. - Weight::from_parts(17_788_000, 7496) + // Minimum execution time: 20_330_000 picoseconds. + Weight::from_parts(20_826_000, 7496) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -515,8 +510,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `239` // Estimated: `1526` - // Minimum execution time: 9_740_000 picoseconds. - Weight::from_parts(10_504_000, 1526) + // Minimum execution time: 13_411_000 picoseconds. + Weight::from_parts(13_960_000, 1526) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -535,12 +530,14 @@ impl WeightInfo for () { /// Storage: `Broker::Workplan` (r:0 w:10) /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. - fn start_sales(_n: u32, ) -> Weight { + fn start_sales(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `6330` // Estimated: `8499` - // Minimum execution time: 49_728_000 picoseconds. - Weight::from_parts(52_765_861, 8499) + // Minimum execution time: 57_770_000 picoseconds. + Weight::from_parts(61_047_512, 8499) + // Standard Error: 165 + .saturating_add(Weight::from_parts(3, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(16_u64)) } @@ -556,10 +553,10 @@ impl WeightInfo for () { /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) fn purchase() -> Weight { // Proof Size summary in bytes: - // Measured: `635` - // Estimated: `2120` - // Minimum execution time: 41_986_000 picoseconds. - Weight::from_parts(43_465_000, 2120) + // Measured: `568` + // Estimated: `2053` + // Minimum execution time: 51_196_000 picoseconds. + Weight::from_parts(52_382_000, 2053) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -579,10 +576,10 @@ impl WeightInfo for () { /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) fn renew() -> Weight { // Proof Size summary in bytes: - // Measured: `753` + // Measured: `686` // Estimated: `4698` - // Minimum execution time: 61_779_000 picoseconds. - Weight::from_parts(62_563_000, 4698) + // Minimum execution time: 71_636_000 picoseconds. + Weight::from_parts(73_679_000, 4698) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -592,8 +589,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3550` - // Minimum execution time: 16_962_000 picoseconds. - Weight::from_parts(17_733_000, 3550) + // Minimum execution time: 19_182_000 picoseconds. + Weight::from_parts(19_775_000, 3550) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -603,21 +600,21 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3550` - // Minimum execution time: 18_380_000 picoseconds. - Weight::from_parts(19_105_000, 3550) + // Minimum execution time: 20_688_000 picoseconds. + Weight::from_parts(21_557_000, 3550) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Broker::Regions` (r:1 w:3) + /// Storage: `Broker::Regions` (r:1 w:2) /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) fn interlace() -> Weight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3550` - // Minimum execution time: 20_115_000 picoseconds. - Weight::from_parts(20_741_000, 3550) + // Minimum execution time: 21_190_000 picoseconds. + Weight::from_parts(22_215_000, 3550) .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Broker::Configuration` (r:1 w:0) /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) @@ -631,8 +628,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `740` // Estimated: `4681` - // Minimum execution time: 31_339_000 picoseconds. - Weight::from_parts(32_639_000, 4681) + // Minimum execution time: 34_591_000 picoseconds. + Weight::from_parts(36_227_000, 4681) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -650,8 +647,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `775` // Estimated: `5996` - // Minimum execution time: 37_542_000 picoseconds. - Weight::from_parts(38_521_000, 5996) + // Minimum execution time: 40_346_000 picoseconds. + Weight::from_parts(41_951_000, 5996) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } @@ -666,10 +663,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `859` // Estimated: `6196 + m * (2520 ±0)` - // Minimum execution time: 66_176_000 picoseconds. - Weight::from_parts(68_356_745, 6196) - // Standard Error: 68_008 - .saturating_add(Weight::from_parts(1_558_419, 0).saturating_mul(m.into())) + // Minimum execution time: 75_734_000 picoseconds. + Weight::from_parts(78_168_395, 6196) + // Standard Error: 63_180 + .saturating_add(Weight::from_parts(1_076_259, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(m.into()))) .saturating_add(RocksDbWeight::get().writes(5_u64)) @@ -681,8 +678,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `103` // Estimated: `3593` - // Minimum execution time: 41_130_000 picoseconds. - Weight::from_parts(41_914_000, 3593) + // Minimum execution time: 46_383_000 picoseconds. + Weight::from_parts(47_405_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -694,8 +691,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `603` // Estimated: `3550` - // Minimum execution time: 31_042_000 picoseconds. - Weight::from_parts(34_087_000, 3550) + // Minimum execution time: 30_994_000 picoseconds. + Weight::from_parts(31_979_000, 3550) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -709,8 +706,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `601` // Estimated: `3533` - // Minimum execution time: 39_116_000 picoseconds. - Weight::from_parts(39_990_000, 3533) + // Minimum execution time: 37_584_000 picoseconds. + Weight::from_parts(44_010_000, 3533) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -724,10 +721,10 @@ impl WeightInfo for () { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn drop_history() -> Weight { // Proof Size summary in bytes: - // Measured: `995` + // Measured: `830` // Estimated: `3593` - // Minimum execution time: 47_547_000 picoseconds. - Weight::from_parts(50_274_000, 3593) + // Minimum execution time: 45_266_000 picoseconds. + Weight::from_parts(48_000_000, 3593) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -737,32 +734,34 @@ impl WeightInfo for () { /// Proof: `Broker::AllowedRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`) fn drop_renewal() -> Weight { // Proof Size summary in bytes: - // Measured: `661` + // Measured: `525` // Estimated: `4698` - // Minimum execution time: 26_707_000 picoseconds. - Weight::from_parts(27_217_000, 4698) + // Minimum execution time: 25_365_000 picoseconds. + Weight::from_parts(26_920_000, 4698) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// The range of component `n` is `[0, 1000]`. - fn request_core_count(_n: u32, ) -> Weight { + fn request_core_count(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_651_000 picoseconds. - Weight::from_parts(5_231_385, 0) + // Minimum execution time: 6_519_000 picoseconds. + Weight::from_parts(7_098_698, 0) + // Standard Error: 20 + .saturating_add(Weight::from_parts(8, 0).saturating_mul(n.into())) } - /// Storage: `Broker::CoreCountInbox` (r:1 w:1) - /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:1) + /// Proof: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:1) /// The range of component `n` is `[0, 1000]`. fn process_core_count(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `404` - // Estimated: `1487` - // Minimum execution time: 6_806_000 picoseconds. - Weight::from_parts(7_264_002, 1487) - // Standard Error: 21 - .saturating_add(Weight::from_parts(31, 0).saturating_mul(n.into())) + // Measured: `98` + // Estimated: `3563` + // Minimum execution time: 7_608_000 picoseconds. + Weight::from_parts(8_157_815, 3563) + // Standard Error: 26 + .saturating_add(Weight::from_parts(48, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -778,10 +777,10 @@ impl WeightInfo for () { /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn process_revenue() -> Weight { // Proof Size summary in bytes: - // Measured: `972` - // Estimated: `4437` - // Minimum execution time: 48_297_000 picoseconds. - Weight::from_parts(49_613_000, 4437) + // Measured: `905` + // Estimated: `4370` + // Minimum execution time: 59_993_000 picoseconds. + Weight::from_parts(61_752_000, 4370) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -800,10 +799,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `6281` // Estimated: `8499` - // Minimum execution time: 36_715_000 picoseconds. - Weight::from_parts(38_580_380, 8499) - // Standard Error: 91 - .saturating_add(Weight::from_parts(1_163, 0).saturating_mul(n.into())) + // Minimum execution time: 41_863_000 picoseconds. + Weight::from_parts(44_033_031, 8499) + // Standard Error: 116 + .saturating_add(Weight::from_parts(764, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(15_u64)) } @@ -815,8 +814,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `180` // Estimated: `3493` - // Minimum execution time: 7_564_000 picoseconds. - Weight::from_parts(7_932_000, 3493) + // Minimum execution time: 9_588_000 picoseconds. + Weight::from_parts(9_925_000, 3493) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -828,8 +827,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1423` // Estimated: `4681` - // Minimum execution time: 17_082_000 picoseconds. - Weight::from_parts(17_662_000, 4681) + // Minimum execution time: 19_308_000 picoseconds. + Weight::from_parts(20_482_000, 4681) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -837,34 +836,28 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 175_000 picoseconds. - Weight::from_parts(223_000, 0) + // Minimum execution time: 147_000 picoseconds. + Weight::from_parts(184_000, 0) } - /// Storage: `Broker::CoreCountInbox` (r:0 w:1) - /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) fn notify_core_count() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 2_432_000 picoseconds. - Weight::from_parts(2_536_000, 0) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + RocksDbWeight::get().reads(1) + .saturating_add(RocksDbWeight::get().writes(1)) } /// Storage: `Broker::Status` (r:1 w:1) /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) /// Storage: `Broker::Configuration` (r:1 w:0) /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) - /// Storage: `Broker::CoreCountInbox` (r:1 w:0) - /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:1) + /// Proof: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:1) /// Storage: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) /// Proof: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) fn do_tick_base() -> Weight { // Proof Size summary in bytes: - // Measured: `603` - // Estimated: `4068` - // Minimum execution time: 13_080_000 picoseconds. - Weight::from_parts(13_937_000, 4068) + // Measured: `699` + // Estimated: `4164` + // Minimum execution time: 19_824_000 picoseconds. + Weight::from_parts(20_983_000, 4164) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) } } diff --git a/substrate/frame/child-bounties/src/weights.rs b/substrate/frame/child-bounties/src/weights.rs index 6427517b45b..e4c1f238e88 100644 --- a/substrate/frame/child-bounties/src/weights.rs +++ b/substrate/frame/child-bounties/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_child_bounties` +//! Autogenerated weights for pallet_child_bounties //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/child-bounties/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/child-bounties/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_child_bounties`. +/// Weight functions needed for pallet_child_bounties. pub trait WeightInfo { fn add_child_bounty(d: u32, ) -> Weight; fn propose_curator() -> Weight; @@ -61,288 +62,288 @@ pub trait WeightInfo { fn close_child_bounty_active() -> Weight; } -/// Weights for `pallet_child_bounties` using the Substrate node and recommended hardware. +/// Weights for pallet_child_bounties using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBountyCount` (r:1 w:1) - /// Proof: `ChildBounties::ChildBountyCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) - /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBounties` (r:0 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: ChildBounties ParentChildBounties (r:1 w:1) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyCount (r:1 w:1) + /// Proof: ChildBounties ChildBountyCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) + /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:0 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) /// The range of component `d` is `[0, 300]`. fn add_child_bounty(_d: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `745` + // Measured: `712` // Estimated: `6196` - // Minimum execution time: 60_674_000 picoseconds. - Weight::from_parts(63_477_428, 6196) + // Minimum execution time: 69_805_000 picoseconds. + Weight::from_parts(73_216_717, 6196) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) - /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) + /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) fn propose_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `799` + // Measured: `766` // Estimated: `3642` - // Minimum execution time: 17_754_000 picoseconds. - Weight::from_parts(18_655_000, 3642) + // Minimum execution time: 18_190_000 picoseconds. + Weight::from_parts(18_932_000, 3642) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn accept_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `945` + // Measured: `912` // Estimated: `3642` - // Minimum execution time: 31_580_000 picoseconds. - Weight::from_parts(32_499_000, 3642) + // Minimum execution time: 35_035_000 picoseconds. + Weight::from_parts(35_975_000, 3642) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn unassign_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `945` + // Measured: `912` // Estimated: `3642` - // Minimum execution time: 33_536_000 picoseconds. - Weight::from_parts(34_102_000, 3642) + // Minimum execution time: 37_636_000 picoseconds. + Weight::from_parts(38_610_000, 3642) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) fn award_child_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `842` + // Measured: `809` // Estimated: `3642` - // Minimum execution time: 18_295_000 picoseconds. - Weight::from_parts(19_496_000, 3642) + // Minimum execution time: 22_457_000 picoseconds. + Weight::from_parts(23_691_000, 3642) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:3 w:3) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) - /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: System Account (r:3 w:3) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:1) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) + /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) fn claim_child_bounty() -> Weight { // Proof Size summary in bytes: // Measured: `682` // Estimated: `8799` - // Minimum execution time: 102_367_000 picoseconds. - Weight::from_parts(104_352_000, 8799) + // Minimum execution time: 118_272_000 picoseconds. + Weight::from_parts(121_646_000, 8799) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) - /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) - /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) + /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:1) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) + /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) fn close_child_bounty_added() -> Weight { // Proof Size summary in bytes: - // Measured: `1045` + // Measured: `1012` // Estimated: `6196` - // Minimum execution time: 69_051_000 picoseconds. - Weight::from_parts(71_297_000, 6196) + // Minimum execution time: 75_717_000 picoseconds. + Weight::from_parts(77_837_000, 6196) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:3 w:3) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) - /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) - /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: System Account (r:3 w:3) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) + /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:1) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) + /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) fn close_child_bounty_active() -> Weight { // Proof Size summary in bytes: - // Measured: `1232` + // Measured: `1199` // Estimated: `8799` - // Minimum execution time: 84_053_000 picoseconds. - Weight::from_parts(86_072_000, 8799) + // Minimum execution time: 94_215_000 picoseconds. + Weight::from_parts(97_017_000, 8799) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBountyCount` (r:1 w:1) - /// Proof: `ChildBounties::ChildBountyCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) - /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBounties` (r:0 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: ChildBounties ParentChildBounties (r:1 w:1) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyCount (r:1 w:1) + /// Proof: ChildBounties ChildBountyCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) + /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:0 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) /// The range of component `d` is `[0, 300]`. fn add_child_bounty(_d: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `745` + // Measured: `712` // Estimated: `6196` - // Minimum execution time: 60_674_000 picoseconds. - Weight::from_parts(63_477_428, 6196) + // Minimum execution time: 69_805_000 picoseconds. + Weight::from_parts(73_216_717, 6196) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) - /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) + /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) fn propose_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `799` + // Measured: `766` // Estimated: `3642` - // Minimum execution time: 17_754_000 picoseconds. - Weight::from_parts(18_655_000, 3642) + // Minimum execution time: 18_190_000 picoseconds. + Weight::from_parts(18_932_000, 3642) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn accept_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `945` + // Measured: `912` // Estimated: `3642` - // Minimum execution time: 31_580_000 picoseconds. - Weight::from_parts(32_499_000, 3642) + // Minimum execution time: 35_035_000 picoseconds. + Weight::from_parts(35_975_000, 3642) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn unassign_curator() -> Weight { // Proof Size summary in bytes: - // Measured: `945` + // Measured: `912` // Estimated: `3642` - // Minimum execution time: 33_536_000 picoseconds. - Weight::from_parts(34_102_000, 3642) + // Minimum execution time: 37_636_000 picoseconds. + Weight::from_parts(38_610_000, 3642) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) fn award_child_bounty() -> Weight { // Proof Size summary in bytes: - // Measured: `842` + // Measured: `809` // Estimated: `3642` - // Minimum execution time: 18_295_000 picoseconds. - Weight::from_parts(19_496_000, 3642) + // Minimum execution time: 22_457_000 picoseconds. + Weight::from_parts(23_691_000, 3642) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:3 w:3) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) - /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: System Account (r:3 w:3) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:1) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) + /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) fn claim_child_bounty() -> Weight { // Proof Size summary in bytes: // Measured: `682` // Estimated: `8799` - // Minimum execution time: 102_367_000 picoseconds. - Weight::from_parts(104_352_000, 8799) + // Minimum execution time: 118_272_000 picoseconds. + Weight::from_parts(121_646_000, 8799) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) - /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) - /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) + /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:1) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) + /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) fn close_child_bounty_added() -> Weight { // Proof Size summary in bytes: - // Measured: `1045` + // Measured: `1012` // Estimated: `6196` - // Minimum execution time: 69_051_000 picoseconds. - Weight::from_parts(71_297_000, 6196) + // Minimum execution time: 75_717_000 picoseconds. + Weight::from_parts(77_837_000, 6196) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } - /// Storage: `Bounties::Bounties` (r:1 w:0) - /// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:3 w:3) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1) - /// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1) - /// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1) - /// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(314), added: 2789, mode: `MaxEncodedLen`) + /// Storage: Bounties Bounties (r:1 w:0) + /// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBounties (r:1 w:1) + /// Proof: ChildBounties ChildBounties (max_values: None, max_size: Some(145), added: 2620, mode: MaxEncodedLen) + /// Storage: System Account (r:3 w:3) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildrenCuratorFees (r:1 w:1) + /// Proof: ChildBounties ChildrenCuratorFees (max_values: None, max_size: Some(28), added: 2503, mode: MaxEncodedLen) + /// Storage: ChildBounties ParentChildBounties (r:1 w:1) + /// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: ChildBounties ChildBountyDescriptions (r:0 w:1) + /// Proof: ChildBounties ChildBountyDescriptions (max_values: None, max_size: Some(314), added: 2789, mode: MaxEncodedLen) fn close_child_bounty_active() -> Weight { // Proof Size summary in bytes: - // Measured: `1232` + // Measured: `1199` // Estimated: `8799` - // Minimum execution time: 84_053_000 picoseconds. - Weight::from_parts(86_072_000, 8799) + // Minimum execution time: 94_215_000 picoseconds. + Weight::from_parts(97_017_000, 8799) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } diff --git a/substrate/frame/collective/src/tests.rs b/substrate/frame/collective/src/tests.rs index 92418794c5f..02c3377515c 100644 --- a/substrate/frame/collective/src/tests.rs +++ b/substrate/frame/collective/src/tests.rs @@ -29,7 +29,7 @@ use sp_core::H256; use sp_runtime::{testing::Header, traits::BlakeTwo256, BuildStorage}; pub type Block = sp_runtime::generic::Block; -pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; +pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; frame_support::construct_runtime!( pub enum Test diff --git a/substrate/frame/collective/src/weights.rs b/substrate/frame/collective/src/weights.rs index 85744b4de9d..eece6a006b8 100644 --- a/substrate/frame/collective/src/weights.rs +++ b/substrate/frame/collective/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_collective` +//! Autogenerated weights for pallet_collective //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/collective/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/collective/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_collective`. +/// Weight functions needed for pallet_collective. pub trait WeightInfo { fn set_members(m: u32, n: u32, p: u32, ) -> Weight; fn execute(b: u32, m: u32, ) -> Weight; @@ -63,30 +64,30 @@ pub trait WeightInfo { fn disapprove_proposal(p: u32, ) -> Weight; } -/// Weights for `pallet_collective` using the Substrate node and recommended hardware. +/// Weights for pallet_collective using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Council::Members` (r:1 w:1) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Proposals` (r:1 w:0) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Voting` (r:100 w:100) - /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Council::Prime` (r:0 w:1) - /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Council Members (r:1 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:100 w:100) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Prime (r:0 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `m` is `[0, 100]`. /// The range of component `n` is `[0, 100]`. /// The range of component `p` is `[0, 100]`. fn set_members(m: u32, _n: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + m * (3232 ±0) + p * (3190 ±0)` - // Estimated: `15894 + m * (1967 ±23) + p * (4332 ±23)` - // Minimum execution time: 15_559_000 picoseconds. - Weight::from_parts(15_870_000, 15894) - // Standard Error: 54_310 - .saturating_add(Weight::from_parts(4_117_753, 0).saturating_mul(m.into())) - // Standard Error: 54_310 - .saturating_add(Weight::from_parts(7_677_627, 0).saturating_mul(p.into())) + // Estimated: `15861 + m * (1967 ±24) + p * (4332 ±24)` + // Minimum execution time: 17_506_000 picoseconds. + Weight::from_parts(17_767_000, 15861) + // Standard Error: 60_220 + .saturating_add(Weight::from_parts(4_374_805, 0).saturating_mul(m.into())) + // Standard Error: 60_220 + .saturating_add(Weight::from_parts(8_398_316, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) .saturating_add(T::DbWeight::get().writes(2_u64)) @@ -94,261 +95,245 @@ impl WeightInfo for SubstrateWeight { .saturating_add(Weight::from_parts(0, 1967).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 4332).saturating_mul(p.into())) } - /// Storage: `Council::Members` (r:1 w:0) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[1, 100]`. fn execute(b: u32, m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `380 + m * (32 ±0)` - // Estimated: `3997 + m * (32 ±0)` - // Minimum execution time: 19_024_000 picoseconds. - Weight::from_parts(18_153_872, 3997) - // Standard Error: 46 - .saturating_add(Weight::from_parts(1_933, 0).saturating_mul(b.into())) - // Standard Error: 478 - .saturating_add(Weight::from_parts(18_872, 0).saturating_mul(m.into())) - .saturating_add(T::DbWeight::get().reads(3_u64)) + // Measured: `202 + m * (32 ±0)` + // Estimated: `1688 + m * (32 ±0)` + // Minimum execution time: 16_203_000 picoseconds. + Weight::from_parts(15_348_267, 1688) + // Standard Error: 37 + .saturating_add(Weight::from_parts(1_766, 0).saturating_mul(b.into())) + // Standard Error: 382 + .saturating_add(Weight::from_parts(15_765, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) } - /// Storage: `Council::Members` (r:1 w:0) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::ProposalOf` (r:1 w:0) - /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:0) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[1, 100]`. fn propose_execute(b: u32, m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `380 + m * (32 ±0)` - // Estimated: `3997 + m * (32 ±0)` - // Minimum execution time: 20_895_000 picoseconds. - Weight::from_parts(20_081_761, 3997) - // Standard Error: 57 - .saturating_add(Weight::from_parts(1_982, 0).saturating_mul(b.into())) - // Standard Error: 594 - .saturating_add(Weight::from_parts(32_085, 0).saturating_mul(m.into())) - .saturating_add(T::DbWeight::get().reads(4_u64)) + // Measured: `202 + m * (32 ±0)` + // Estimated: `3668 + m * (32 ±0)` + // Minimum execution time: 18_642_000 picoseconds. + Weight::from_parts(17_708_609, 3668) + // Standard Error: 58 + .saturating_add(Weight::from_parts(2_285, 0).saturating_mul(b.into())) + // Standard Error: 598 + .saturating_add(Weight::from_parts(30_454, 0).saturating_mul(m.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) } - /// Storage: `Council::Members` (r:1 w:0) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::ProposalOf` (r:1 w:1) - /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Council::Proposals` (r:1 w:1) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::ProposalCount` (r:1 w:1) - /// Proof: `Council::ProposalCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Voting` (r:0 w:1) - /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalCount (r:1 w:1) + /// Proof Skipped: Council ProposalCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:0 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[2, 100]`. /// The range of component `p` is `[1, 100]`. fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `525 + m * (32 ±0) + p * (36 ±0)` - // Estimated: `3917 + m * (33 ±0) + p * (36 ±0)` - // Minimum execution time: 22_068_000 picoseconds. - Weight::from_parts(19_639_088, 3917) - // Standard Error: 104 - .saturating_add(Weight::from_parts(3_896, 0).saturating_mul(b.into())) - // Standard Error: 1_095 - .saturating_add(Weight::from_parts(31_634, 0).saturating_mul(m.into())) - // Standard Error: 1_081 - .saturating_add(Weight::from_parts(178_702, 0).saturating_mul(p.into())) + // Measured: `492 + m * (32 ±0) + p * (36 ±0)` + // Estimated: `3884 + m * (33 ±0) + p * (36 ±0)` + // Minimum execution time: 27_067_000 picoseconds. + Weight::from_parts(25_456_964, 3884) + // Standard Error: 112 + .saturating_add(Weight::from_parts(3_773, 0).saturating_mul(b.into())) + // Standard Error: 1_177 + .saturating_add(Weight::from_parts(32_783, 0).saturating_mul(m.into())) + // Standard Error: 1_162 + .saturating_add(Weight::from_parts(194_388, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 33).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: `Council::Members` (r:1 w:0) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Voting` (r:1 w:1) - /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) /// The range of component `m` is `[5, 100]`. fn vote(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `974 + m * (64 ±0)` - // Estimated: `4438 + m * (64 ±0)` - // Minimum execution time: 22_395_000 picoseconds. - Weight::from_parts(23_025_217, 4438) - // Standard Error: 842 - .saturating_add(Weight::from_parts(58_102, 0).saturating_mul(m.into())) + // Measured: `941 + m * (64 ±0)` + // Estimated: `4405 + m * (64 ±0)` + // Minimum execution time: 26_055_000 picoseconds. + Weight::from_parts(27_251_907, 4405) + // Standard Error: 1_008 + .saturating_add(Weight::from_parts(65_947, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: `Council::Voting` (r:1 w:1) - /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Council::Members` (r:1 w:0) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Proposals` (r:1 w:1) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::ProposalOf` (r:0 w:1) - /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:0 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_early_disapproved(m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `563 + m * (64 ±0) + p * (36 ±0)` - // Estimated: `4008 + m * (65 ±0) + p * (36 ±0)` - // Minimum execution time: 24_179_000 picoseconds. - Weight::from_parts(23_846_394, 4008) - // Standard Error: 1_052 - .saturating_add(Weight::from_parts(40_418, 0).saturating_mul(m.into())) - // Standard Error: 1_026 - .saturating_add(Weight::from_parts(171_653, 0).saturating_mul(p.into())) + // Measured: `530 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `3975 + m * (65 ±0) + p * (36 ±0)` + // Minimum execution time: 28_363_000 picoseconds. + Weight::from_parts(28_733_464, 3975) + // Standard Error: 1_275 + .saturating_add(Weight::from_parts(43_236, 0).saturating_mul(m.into())) + // Standard Error: 1_244 + .saturating_add(Weight::from_parts(180_187, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 65).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: `Council::Voting` (r:1 w:1) - /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Council::Members` (r:1 w:0) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::ProposalOf` (r:1 w:1) - /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) - /// Storage: `Council::Proposals` (r:1 w:1) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1010 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` - // Estimated: `4327 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` - // Minimum execution time: 42_129_000 picoseconds. - Weight::from_parts(40_808_957, 4327) - // Standard Error: 134 - .saturating_add(Weight::from_parts(3_579, 0).saturating_mul(b.into())) - // Standard Error: 1_425 - .saturating_add(Weight::from_parts(37_166, 0).saturating_mul(m.into())) - // Standard Error: 1_389 - .saturating_add(Weight::from_parts(200_986, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(6_u64)) + // Measured: `832 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `4149 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` + // Minimum execution time: 40_391_000 picoseconds. + Weight::from_parts(42_695_215, 4149) + // Standard Error: 167 + .saturating_add(Weight::from_parts(3_622, 0).saturating_mul(b.into())) + // Standard Error: 1_772 + .saturating_add(Weight::from_parts(33_830, 0).saturating_mul(m.into())) + // Standard Error: 1_727 + .saturating_add(Weight::from_parts(205_374, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(b.into())) .saturating_add(Weight::from_parts(0, 66).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) } - /// Storage: `Council::Voting` (r:1 w:1) - /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Council::Members` (r:1 w:0) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Prime` (r:1 w:0) - /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Proposals` (r:1 w:1) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::ProposalOf` (r:0 w:1) - /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:0) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:0 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_disapproved(m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `583 + m * (64 ±0) + p * (36 ±0)` - // Estimated: `4028 + m * (65 ±0) + p * (36 ±0)` - // Minimum execution time: 26_385_000 picoseconds. - Weight::from_parts(25_713_839, 4028) - // Standard Error: 1_254 - .saturating_add(Weight::from_parts(36_206, 0).saturating_mul(m.into())) - // Standard Error: 1_223 - .saturating_add(Weight::from_parts(195_114, 0).saturating_mul(p.into())) + // Measured: `550 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `3995 + m * (65 ±0) + p * (36 ±0)` + // Minimum execution time: 31_368_000 picoseconds. + Weight::from_parts(32_141_835, 3995) + // Standard Error: 1_451 + .saturating_add(Weight::from_parts(36_372, 0).saturating_mul(m.into())) + // Standard Error: 1_415 + .saturating_add(Weight::from_parts(210_635, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 65).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: `Council::Voting` (r:1 w:1) - /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Council::Members` (r:1 w:0) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Prime` (r:1 w:0) - /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::ProposalOf` (r:1 w:1) - /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) - /// Storage: `Council::Proposals` (r:1 w:1) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:0) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_approved(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1030 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` - // Estimated: `4347 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` - // Minimum execution time: 42_903_000 picoseconds. - Weight::from_parts(43_152_907, 4347) - // Standard Error: 146 - .saturating_add(Weight::from_parts(3_459, 0).saturating_mul(b.into())) - // Standard Error: 1_548 - .saturating_add(Weight::from_parts(35_321, 0).saturating_mul(m.into())) - // Standard Error: 1_509 - .saturating_add(Weight::from_parts(202_541, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(7_u64)) + // Measured: `852 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `4169 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` + // Minimum execution time: 43_271_000 picoseconds. + Weight::from_parts(45_495_648, 4169) + // Standard Error: 174 + .saturating_add(Weight::from_parts(3_034, 0).saturating_mul(b.into())) + // Standard Error: 1_840 + .saturating_add(Weight::from_parts(42_209, 0).saturating_mul(m.into())) + // Standard Error: 1_793 + .saturating_add(Weight::from_parts(207_525, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(b.into())) .saturating_add(Weight::from_parts(0, 66).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) } - /// Storage: `Council::Proposals` (r:1 w:1) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Voting` (r:0 w:1) - /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Council::ProposalOf` (r:0 w:1) - /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:0 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:0 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) /// The range of component `p` is `[1, 100]`. fn disapprove_proposal(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `392 + p * (32 ±0)` - // Estimated: `1877 + p * (32 ±0)` - // Minimum execution time: 12_656_000 picoseconds. - Weight::from_parts(14_032_951, 1877) - // Standard Error: 1_025 - .saturating_add(Weight::from_parts(159_143, 0).saturating_mul(p.into())) + // Measured: `359 + p * (32 ±0)` + // Estimated: `1844 + p * (32 ±0)` + // Minimum execution time: 15_170_000 picoseconds. + Weight::from_parts(17_567_243, 1844) + // Standard Error: 1_430 + .saturating_add(Weight::from_parts(169_040, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(p.into())) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Council::Members` (r:1 w:1) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Proposals` (r:1 w:0) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Voting` (r:100 w:100) - /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Council::Prime` (r:0 w:1) - /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Council Members (r:1 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:100 w:100) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Prime (r:0 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `m` is `[0, 100]`. /// The range of component `n` is `[0, 100]`. /// The range of component `p` is `[0, 100]`. fn set_members(m: u32, _n: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + m * (3232 ±0) + p * (3190 ±0)` - // Estimated: `15894 + m * (1967 ±23) + p * (4332 ±23)` - // Minimum execution time: 15_559_000 picoseconds. - Weight::from_parts(15_870_000, 15894) - // Standard Error: 54_310 - .saturating_add(Weight::from_parts(4_117_753, 0).saturating_mul(m.into())) - // Standard Error: 54_310 - .saturating_add(Weight::from_parts(7_677_627, 0).saturating_mul(p.into())) + // Estimated: `15861 + m * (1967 ±24) + p * (4332 ±24)` + // Minimum execution time: 17_506_000 picoseconds. + Weight::from_parts(17_767_000, 15861) + // Standard Error: 60_220 + .saturating_add(Weight::from_parts(4_374_805, 0).saturating_mul(m.into())) + // Standard Error: 60_220 + .saturating_add(Weight::from_parts(8_398_316, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(p.into()))) .saturating_add(RocksDbWeight::get().writes(2_u64)) @@ -356,232 +341,216 @@ impl WeightInfo for () { .saturating_add(Weight::from_parts(0, 1967).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 4332).saturating_mul(p.into())) } - /// Storage: `Council::Members` (r:1 w:0) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[1, 100]`. fn execute(b: u32, m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `380 + m * (32 ±0)` - // Estimated: `3997 + m * (32 ±0)` - // Minimum execution time: 19_024_000 picoseconds. - Weight::from_parts(18_153_872, 3997) - // Standard Error: 46 - .saturating_add(Weight::from_parts(1_933, 0).saturating_mul(b.into())) - // Standard Error: 478 - .saturating_add(Weight::from_parts(18_872, 0).saturating_mul(m.into())) - .saturating_add(RocksDbWeight::get().reads(3_u64)) + // Measured: `202 + m * (32 ±0)` + // Estimated: `1688 + m * (32 ±0)` + // Minimum execution time: 16_203_000 picoseconds. + Weight::from_parts(15_348_267, 1688) + // Standard Error: 37 + .saturating_add(Weight::from_parts(1_766, 0).saturating_mul(b.into())) + // Standard Error: 382 + .saturating_add(Weight::from_parts(15_765, 0).saturating_mul(m.into())) + .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) } - /// Storage: `Council::Members` (r:1 w:0) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::ProposalOf` (r:1 w:0) - /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:0) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[1, 100]`. fn propose_execute(b: u32, m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `380 + m * (32 ±0)` - // Estimated: `3997 + m * (32 ±0)` - // Minimum execution time: 20_895_000 picoseconds. - Weight::from_parts(20_081_761, 3997) - // Standard Error: 57 - .saturating_add(Weight::from_parts(1_982, 0).saturating_mul(b.into())) - // Standard Error: 594 - .saturating_add(Weight::from_parts(32_085, 0).saturating_mul(m.into())) - .saturating_add(RocksDbWeight::get().reads(4_u64)) + // Measured: `202 + m * (32 ±0)` + // Estimated: `3668 + m * (32 ±0)` + // Minimum execution time: 18_642_000 picoseconds. + Weight::from_parts(17_708_609, 3668) + // Standard Error: 58 + .saturating_add(Weight::from_parts(2_285, 0).saturating_mul(b.into())) + // Standard Error: 598 + .saturating_add(Weight::from_parts(30_454, 0).saturating_mul(m.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) } - /// Storage: `Council::Members` (r:1 w:0) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::ProposalOf` (r:1 w:1) - /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Council::Proposals` (r:1 w:1) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::ProposalCount` (r:1 w:1) - /// Proof: `Council::ProposalCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Voting` (r:0 w:1) - /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalCount (r:1 w:1) + /// Proof Skipped: Council ProposalCount (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:0 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[2, 100]`. /// The range of component `p` is `[1, 100]`. fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `525 + m * (32 ±0) + p * (36 ±0)` - // Estimated: `3917 + m * (33 ±0) + p * (36 ±0)` - // Minimum execution time: 22_068_000 picoseconds. - Weight::from_parts(19_639_088, 3917) - // Standard Error: 104 - .saturating_add(Weight::from_parts(3_896, 0).saturating_mul(b.into())) - // Standard Error: 1_095 - .saturating_add(Weight::from_parts(31_634, 0).saturating_mul(m.into())) - // Standard Error: 1_081 - .saturating_add(Weight::from_parts(178_702, 0).saturating_mul(p.into())) + // Measured: `492 + m * (32 ±0) + p * (36 ±0)` + // Estimated: `3884 + m * (33 ±0) + p * (36 ±0)` + // Minimum execution time: 27_067_000 picoseconds. + Weight::from_parts(25_456_964, 3884) + // Standard Error: 112 + .saturating_add(Weight::from_parts(3_773, 0).saturating_mul(b.into())) + // Standard Error: 1_177 + .saturating_add(Weight::from_parts(32_783, 0).saturating_mul(m.into())) + // Standard Error: 1_162 + .saturating_add(Weight::from_parts(194_388, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 33).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: `Council::Members` (r:1 w:0) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Voting` (r:1 w:1) - /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) /// The range of component `m` is `[5, 100]`. fn vote(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `974 + m * (64 ±0)` - // Estimated: `4438 + m * (64 ±0)` - // Minimum execution time: 22_395_000 picoseconds. - Weight::from_parts(23_025_217, 4438) - // Standard Error: 842 - .saturating_add(Weight::from_parts(58_102, 0).saturating_mul(m.into())) + // Measured: `941 + m * (64 ±0)` + // Estimated: `4405 + m * (64 ±0)` + // Minimum execution time: 26_055_000 picoseconds. + Weight::from_parts(27_251_907, 4405) + // Standard Error: 1_008 + .saturating_add(Weight::from_parts(65_947, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: `Council::Voting` (r:1 w:1) - /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Council::Members` (r:1 w:0) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Proposals` (r:1 w:1) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::ProposalOf` (r:0 w:1) - /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:0 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_early_disapproved(m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `563 + m * (64 ±0) + p * (36 ±0)` - // Estimated: `4008 + m * (65 ±0) + p * (36 ±0)` - // Minimum execution time: 24_179_000 picoseconds. - Weight::from_parts(23_846_394, 4008) - // Standard Error: 1_052 - .saturating_add(Weight::from_parts(40_418, 0).saturating_mul(m.into())) - // Standard Error: 1_026 - .saturating_add(Weight::from_parts(171_653, 0).saturating_mul(p.into())) + // Measured: `530 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `3975 + m * (65 ±0) + p * (36 ±0)` + // Minimum execution time: 28_363_000 picoseconds. + Weight::from_parts(28_733_464, 3975) + // Standard Error: 1_275 + .saturating_add(Weight::from_parts(43_236, 0).saturating_mul(m.into())) + // Standard Error: 1_244 + .saturating_add(Weight::from_parts(180_187, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 65).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: `Council::Voting` (r:1 w:1) - /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Council::Members` (r:1 w:0) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::ProposalOf` (r:1 w:1) - /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) - /// Storage: `Council::Proposals` (r:1 w:1) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1010 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` - // Estimated: `4327 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` - // Minimum execution time: 42_129_000 picoseconds. - Weight::from_parts(40_808_957, 4327) - // Standard Error: 134 - .saturating_add(Weight::from_parts(3_579, 0).saturating_mul(b.into())) - // Standard Error: 1_425 - .saturating_add(Weight::from_parts(37_166, 0).saturating_mul(m.into())) - // Standard Error: 1_389 - .saturating_add(Weight::from_parts(200_986, 0).saturating_mul(p.into())) - .saturating_add(RocksDbWeight::get().reads(6_u64)) + // Measured: `832 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `4149 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` + // Minimum execution time: 40_391_000 picoseconds. + Weight::from_parts(42_695_215, 4149) + // Standard Error: 167 + .saturating_add(Weight::from_parts(3_622, 0).saturating_mul(b.into())) + // Standard Error: 1_772 + .saturating_add(Weight::from_parts(33_830, 0).saturating_mul(m.into())) + // Standard Error: 1_727 + .saturating_add(Weight::from_parts(205_374, 0).saturating_mul(p.into())) + .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(b.into())) .saturating_add(Weight::from_parts(0, 66).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) } - /// Storage: `Council::Voting` (r:1 w:1) - /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Council::Members` (r:1 w:0) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Prime` (r:1 w:0) - /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Proposals` (r:1 w:1) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::ProposalOf` (r:0 w:1) - /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:0) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:0 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_disapproved(m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `583 + m * (64 ±0) + p * (36 ±0)` - // Estimated: `4028 + m * (65 ±0) + p * (36 ±0)` - // Minimum execution time: 26_385_000 picoseconds. - Weight::from_parts(25_713_839, 4028) - // Standard Error: 1_254 - .saturating_add(Weight::from_parts(36_206, 0).saturating_mul(m.into())) - // Standard Error: 1_223 - .saturating_add(Weight::from_parts(195_114, 0).saturating_mul(p.into())) + // Measured: `550 + m * (64 ±0) + p * (36 ±0)` + // Estimated: `3995 + m * (65 ±0) + p * (36 ±0)` + // Minimum execution time: 31_368_000 picoseconds. + Weight::from_parts(32_141_835, 3995) + // Standard Error: 1_451 + .saturating_add(Weight::from_parts(36_372, 0).saturating_mul(m.into())) + // Standard Error: 1_415 + .saturating_add(Weight::from_parts(210_635, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 65).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 36).saturating_mul(p.into())) } - /// Storage: `Council::Voting` (r:1 w:1) - /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Council::Members` (r:1 w:0) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Prime` (r:1 w:0) - /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::ProposalOf` (r:1 w:1) - /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) - /// Storage: `Council::Proposals` (r:1 w:1) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Council Voting (r:1 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Members (r:1 w:0) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:0) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:1 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `b` is `[2, 1024]`. /// The range of component `m` is `[4, 100]`. /// The range of component `p` is `[1, 100]`. fn close_approved(b: u32, m: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1030 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` - // Estimated: `4347 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` - // Minimum execution time: 42_903_000 picoseconds. - Weight::from_parts(43_152_907, 4347) - // Standard Error: 146 - .saturating_add(Weight::from_parts(3_459, 0).saturating_mul(b.into())) - // Standard Error: 1_548 - .saturating_add(Weight::from_parts(35_321, 0).saturating_mul(m.into())) - // Standard Error: 1_509 - .saturating_add(Weight::from_parts(202_541, 0).saturating_mul(p.into())) - .saturating_add(RocksDbWeight::get().reads(7_u64)) + // Measured: `852 + b * (1 ±0) + m * (64 ±0) + p * (40 ±0)` + // Estimated: `4169 + b * (1 ±0) + m * (66 ±0) + p * (40 ±0)` + // Minimum execution time: 43_271_000 picoseconds. + Weight::from_parts(45_495_648, 4169) + // Standard Error: 174 + .saturating_add(Weight::from_parts(3_034, 0).saturating_mul(b.into())) + // Standard Error: 1_840 + .saturating_add(Weight::from_parts(42_209, 0).saturating_mul(m.into())) + // Standard Error: 1_793 + .saturating_add(Weight::from_parts(207_525, 0).saturating_mul(p.into())) + .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(b.into())) .saturating_add(Weight::from_parts(0, 66).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 40).saturating_mul(p.into())) } - /// Storage: `Council::Proposals` (r:1 w:1) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Voting` (r:0 w:1) - /// Proof: `Council::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Council::ProposalOf` (r:0 w:1) - /// Proof: `Council::ProposalOf` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Council Proposals (r:1 w:1) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Voting (r:0 w:1) + /// Proof Skipped: Council Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council ProposalOf (r:0 w:1) + /// Proof Skipped: Council ProposalOf (max_values: None, max_size: None, mode: Measured) /// The range of component `p` is `[1, 100]`. fn disapprove_proposal(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `392 + p * (32 ±0)` - // Estimated: `1877 + p * (32 ±0)` - // Minimum execution time: 12_656_000 picoseconds. - Weight::from_parts(14_032_951, 1877) - // Standard Error: 1_025 - .saturating_add(Weight::from_parts(159_143, 0).saturating_mul(p.into())) + // Measured: `359 + p * (32 ±0)` + // Estimated: `1844 + p * (32 ±0)` + // Minimum execution time: 15_170_000 picoseconds. + Weight::from_parts(17_567_243, 1844) + // Standard Error: 1_430 + .saturating_add(Weight::from_parts(169_040, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(p.into())) diff --git a/substrate/frame/contracts/src/weights.rs b/substrate/frame/contracts/src/weights.rs index 6e09120c141..99bc4d8d3eb 100644 --- a/substrate/frame/contracts/src/weights.rs +++ b/substrate/frame/contracts/src/weights.rs @@ -25,6 +25,7 @@ // Executed Command: // target/production/substrate-node +// target/production/substrate-node // benchmark // pallet // --steps=50 @@ -35,8 +36,12 @@ // --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json // --pallet=pallet_contracts // --chain=dev +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_contracts +// --chain=dev // --header=./substrate/HEADER-APACHE2 // --output=./substrate/frame/contracts/src/weights.rs +// --output=./substrate/frame/contracts/src/weights.rs // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -213,8 +218,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc553053f13fd319a03c211337c76e0fe776df` (r:2 w:0) /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc553022fca90611ba8b7942f8bdb3b97f6580` (r:1 w:1) /// Proof: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc553022fca90611ba8b7942f8bdb3b97f6580` (r:1 w:1) - /// Storage: `Parameters::Parameters` (r:2 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:0 w:1) @@ -248,7 +251,7 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) fn v14_migration_step() -> Weight { // Proof Size summary in bytes: // Measured: `352` @@ -332,8 +335,6 @@ impl WeightInfo for SubstrateWeight { } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -361,12 +362,10 @@ impl WeightInfo for SubstrateWeight { } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:2 w:2) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `System::EventTopics` (r:3 w:3) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::Nonce` (r:1 w:1) @@ -403,8 +402,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:1 w:0) /// Proof: `Contracts::PristineCode` (`max_values`: None, `max_size`: Some(125988), added: 128463, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::Nonce` (r:1 w:1) /// Proof: `Contracts::Nonce` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) @@ -416,7 +413,7 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::EventTopics` (r:2 w:2) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// The range of component `i` is `[0, 1048576]`. /// The range of component `s` is `[0, 1048576]`. fn instantiate(i: u32, s: u32, ) -> Weight { @@ -434,8 +431,6 @@ impl WeightInfo for SubstrateWeight { } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -459,12 +454,10 @@ impl WeightInfo for SubstrateWeight { } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:2 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `System::EventTopics` (r:1 w:1) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:0 w:1) @@ -510,7 +503,7 @@ impl WeightInfo for SubstrateWeight { /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `System::EventTopics` (r:1 w:1) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:0 w:1) @@ -545,8 +538,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -574,8 +565,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1601 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -604,8 +593,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1601 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -634,8 +621,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -663,8 +648,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -690,8 +673,6 @@ impl WeightInfo for SubstrateWeight { } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -719,8 +700,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -748,8 +727,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -777,8 +754,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:2 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -806,8 +781,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -835,8 +808,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -864,8 +835,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -893,8 +862,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -922,8 +889,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -953,8 +918,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -982,8 +945,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1010,8 +971,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1039,8 +998,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1067,8 +1024,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:3 w:3) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:1 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:2 w:2) @@ -1082,7 +1037,7 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::EventTopics` (r:4 w:4) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `Contracts::DeletionQueue` (r:0 w:1) /// Proof: `Contracts::DeletionQueue` (`max_values`: None, `max_size`: Some(142), added: 2617, mode: `Measured`) /// The range of component `r` is `[0, 1]`. @@ -1098,14 +1053,12 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(T::DbWeight::get().writes((10_u64).saturating_mul(r.into()))) - .saturating_add(Weight::from_parts(0, 5479).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(0, 5266).saturating_mul(r.into())) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1135,8 +1088,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1164,8 +1115,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1198,8 +1147,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1227,8 +1174,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `MaxEncodedLen`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1423,8 +1368,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1602 w:1601) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1454,8 +1397,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:801 w:801) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:2 w:0) @@ -1485,8 +1426,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:736 w:0) @@ -1516,8 +1455,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:3 w:2) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:2 w:2) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:2 w:0) @@ -1550,8 +1487,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:802 w:802) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:801 w:801) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:801 w:800) @@ -1565,7 +1500,7 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::EventTopics` (r:803 w:803) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:800 w:800) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// The range of component `r` is `[1, 800]`. fn seal_instantiate(r: u32, ) -> Weight { // Proof Size summary in bytes: @@ -1585,8 +1520,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:3 w:3) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:2 w:2) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:2 w:1) @@ -1600,7 +1533,7 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::EventTopics` (r:4 w:4) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// The range of component `t` is `[0, 1]`. /// The range of component `i` is `[0, 983040]`. /// The range of component `s` is `[0, 983040]`. @@ -1624,8 +1557,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1653,8 +1584,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1681,8 +1610,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1710,8 +1637,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1738,8 +1663,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1767,8 +1690,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1795,8 +1716,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1824,8 +1743,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1852,8 +1769,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1881,8 +1796,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1910,8 +1823,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1939,8 +1850,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -1968,8 +1877,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1536 w:1536) @@ -1999,8 +1906,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:33 w:32) @@ -2024,14 +1929,12 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) - .saturating_add(Weight::from_parts(0, 2607).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(0, 2606).saturating_mul(r.into())) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `MaxEncodedLen`) /// Storage: `Contracts::CodeInfoOf` (r:33 w:32) @@ -2045,7 +1948,7 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 32]`. fn unlock_delegate_dependency(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `972 + r * (184 ±0)` + // Measured: `969 + r * (183 ±0)` // Estimated: `129453 + r * (2568 ±0)` // Minimum execution time: 270_652_000 picoseconds. Weight::from_parts(293_369_452, 129453) @@ -2061,8 +1964,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2090,8 +1991,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2119,8 +2018,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2237,8 +2134,6 @@ impl WeightInfo for () { /// Proof: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc553053f13fd319a03c211337c76e0fe776df` (r:2 w:0) /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc553022fca90611ba8b7942f8bdb3b97f6580` (r:1 w:1) /// Proof: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc553022fca90611ba8b7942f8bdb3b97f6580` (r:1 w:1) - /// Storage: `Parameters::Parameters` (r:2 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:0 w:1) @@ -2272,7 +2167,7 @@ impl WeightInfo for () { /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) fn v14_migration_step() -> Weight { // Proof Size summary in bytes: // Measured: `352` @@ -2356,8 +2251,6 @@ impl WeightInfo for () { } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2385,12 +2278,10 @@ impl WeightInfo for () { } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:2 w:2) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `System::EventTopics` (r:3 w:3) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::Nonce` (r:1 w:1) @@ -2427,8 +2318,6 @@ impl WeightInfo for () { /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:1 w:0) /// Proof: `Contracts::PristineCode` (`max_values`: None, `max_size`: Some(125988), added: 128463, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::Nonce` (r:1 w:1) /// Proof: `Contracts::Nonce` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) @@ -2440,7 +2329,7 @@ impl WeightInfo for () { /// Storage: `System::EventTopics` (r:2 w:2) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// The range of component `i` is `[0, 1048576]`. /// The range of component `s` is `[0, 1048576]`. fn instantiate(i: u32, s: u32, ) -> Weight { @@ -2458,8 +2347,6 @@ impl WeightInfo for () { } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2483,12 +2370,10 @@ impl WeightInfo for () { } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:2 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `System::EventTopics` (r:1 w:1) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:0 w:1) @@ -2534,7 +2419,7 @@ impl WeightInfo for () { /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `System::EventTopics` (r:1 w:1) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:0 w:1) @@ -2569,8 +2454,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2598,8 +2481,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1601 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2628,8 +2509,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1601 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2658,8 +2537,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2687,8 +2564,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2714,8 +2589,6 @@ impl WeightInfo for () { } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2743,8 +2616,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2772,8 +2643,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2801,8 +2670,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:2 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2830,8 +2697,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2859,8 +2724,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2888,8 +2751,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2917,8 +2778,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2946,8 +2805,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -2977,8 +2834,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3006,8 +2861,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3034,8 +2887,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3063,8 +2914,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3091,8 +2940,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:3 w:3) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:1 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:2 w:2) @@ -3106,7 +2953,7 @@ impl WeightInfo for () { /// Storage: `System::EventTopics` (r:4 w:4) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `Contracts::DeletionQueue` (r:0 w:1) /// Proof: `Contracts::DeletionQueue` (`max_values`: None, `max_size`: Some(142), added: 2617, mode: `Measured`) /// The range of component `r` is `[0, 1]`. @@ -3122,14 +2969,12 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads((5_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(RocksDbWeight::get().writes((10_u64).saturating_mul(r.into()))) - .saturating_add(Weight::from_parts(0, 5479).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(0, 5266).saturating_mul(r.into())) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3159,8 +3004,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3188,8 +3031,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3222,8 +3063,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3251,8 +3090,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `MaxEncodedLen`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3447,8 +3284,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1602 w:1601) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3478,8 +3313,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:801 w:801) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:2 w:0) @@ -3509,8 +3342,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:736 w:0) @@ -3540,8 +3371,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:3 w:2) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:2 w:2) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:2 w:0) @@ -3574,8 +3403,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:802 w:802) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:801 w:801) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:801 w:800) @@ -3589,7 +3416,7 @@ impl WeightInfo for () { /// Storage: `System::EventTopics` (r:803 w:803) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:800 w:800) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// The range of component `r` is `[1, 800]`. fn seal_instantiate(r: u32, ) -> Weight { // Proof Size summary in bytes: @@ -3609,8 +3436,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:3 w:3) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:2 w:2) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:2 w:1) @@ -3624,7 +3449,7 @@ impl WeightInfo for () { /// Storage: `System::EventTopics` (r:4 w:4) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// The range of component `t` is `[0, 1]`. /// The range of component `i` is `[0, 983040]`. /// The range of component `s` is `[0, 983040]`. @@ -3648,8 +3473,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3677,8 +3500,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3705,8 +3526,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3734,8 +3553,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3762,8 +3579,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3791,8 +3606,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3819,8 +3632,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3848,8 +3659,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3876,8 +3685,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3905,8 +3712,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3934,8 +3739,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3963,8 +3766,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -3992,8 +3793,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1536 w:1536) @@ -4023,8 +3822,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:33 w:32) @@ -4048,14 +3845,12 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r.into()))) - .saturating_add(Weight::from_parts(0, 2607).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(0, 2606).saturating_mul(r.into())) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `MaxEncodedLen`) /// Storage: `Contracts::CodeInfoOf` (r:33 w:32) @@ -4069,7 +3864,7 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 32]`. fn unlock_delegate_dependency(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `972 + r * (184 ±0)` + // Measured: `969 + r * (183 ±0)` // Estimated: `129453 + r * (2568 ±0)` // Minimum execution time: 270_652_000 picoseconds. Weight::from_parts(293_369_452, 129453) @@ -4085,8 +3880,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -4114,8 +3907,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) @@ -4143,8 +3934,6 @@ impl WeightInfo for () { /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:3 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:1) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) /// Storage: `Contracts::CodeInfoOf` (r:1 w:0) diff --git a/substrate/frame/conviction-voting/src/weights.rs b/substrate/frame/conviction-voting/src/weights.rs index 75d9e8499ed..225f5c2cadd 100644 --- a/substrate/frame/conviction-voting/src/weights.rs +++ b/substrate/frame/conviction-voting/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_conviction_voting` +//! Autogenerated weights for pallet_conviction_voting //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/conviction-voting/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/conviction-voting/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_conviction_voting`. +/// Weight functions needed for pallet_conviction_voting. pub trait WeightInfo { fn vote_new() -> Weight; fn vote_existing() -> Weight; @@ -60,300 +61,280 @@ pub trait WeightInfo { fn unlock() -> Weight; } -/// Weights for `pallet_conviction_voting` using the Substrate node and recommended hardware. +/// Weights for pallet_conviction_voting using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) - /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(59), added: 2534, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(59), added: 2534, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn vote_new() -> Weight { // Proof Size summary in bytes: - // Measured: `13141` + // Measured: `13074` // Estimated: `219984` - // Minimum execution time: 102_539_000 picoseconds. - Weight::from_parts(105_873_000, 219984) + // Minimum execution time: 112_936_000 picoseconds. + Weight::from_parts(116_972_000, 219984) .saturating_add(T::DbWeight::get().reads(7_u64)) - .saturating_add(T::DbWeight::get().writes(7_u64)) + .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) - /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(59), added: 2534, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(59), added: 2534, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn vote_existing() -> Weight { // Proof Size summary in bytes: - // Measured: `20283` + // Measured: `20216` // Estimated: `219984` - // Minimum execution time: 275_424_000 picoseconds. - Weight::from_parts(283_690_000, 219984) + // Minimum execution time: 291_971_000 picoseconds. + Weight::from_parts(301_738_000, 219984) .saturating_add(T::DbWeight::get().reads(7_u64)) - .saturating_add(T::DbWeight::get().writes(7_u64)) + .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn remove_vote() -> Weight { // Proof Size summary in bytes: - // Measured: `20035` + // Measured: `19968` // Estimated: `219984` - // Minimum execution time: 275_109_000 picoseconds. - Weight::from_parts(281_315_000, 219984) + // Minimum execution time: 262_582_000 picoseconds. + Weight::from_parts(270_955_000, 219984) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(5_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) fn remove_other_vote() -> Weight { // Proof Size summary in bytes: - // Measured: `12742` + // Measured: `12675` // Estimated: `30706` - // Minimum execution time: 49_629_000 picoseconds. - Weight::from_parts(51_300_000, 30706) + // Minimum execution time: 52_909_000 picoseconds. + Weight::from_parts(56_365_000, 30706) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `ConvictionVoting::VotingFor` (r:2 w:2) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) - /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(59), added: 2534, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: ConvictionVoting VotingFor (r:2 w:2) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(59), added: 2534, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) /// The range of component `r` is `[0, 1]`. fn delegate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `306 + r * (1628 ±0)` + // Measured: `240 + r * (1627 ±0)` // Estimated: `109992 + r * (109992 ±0)` - // Minimum execution time: 45_776_000 picoseconds. - Weight::from_parts(47_917_822, 109992) - // Standard Error: 124_174 - .saturating_add(Weight::from_parts(43_171_077, 0).saturating_mul(r.into())) + // Minimum execution time: 54_640_000 picoseconds. + Weight::from_parts(57_185_281, 109992) + // Standard Error: 193_362 + .saturating_add(Weight::from_parts(44_897_418, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) - .saturating_add(T::DbWeight::get().writes((4_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 109992).saturating_mul(r.into())) } - /// Storage: `ConvictionVoting::VotingFor` (r:2 w:2) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: ConvictionVoting VotingFor (r:2 w:2) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) /// The range of component `r` is `[0, 1]`. fn undelegate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `472 + r * (1377 ±0)` + // Measured: `406 + r * (1376 ±0)` // Estimated: `109992 + r * (109992 ±0)` - // Minimum execution time: 23_600_000 picoseconds. - Weight::from_parts(25_001_426, 109992) - // Standard Error: 72_034 - .saturating_add(Weight::from_parts(37_851_873, 0).saturating_mul(r.into())) + // Minimum execution time: 26_514_000 picoseconds. + Weight::from_parts(28_083_732, 109992) + // Standard Error: 104_905 + .saturating_add(Weight::from_parts(40_722_467, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(2_u64)) - .saturating_add(T::DbWeight::get().writes((4_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 109992).saturating_mul(r.into())) } - /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) - /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(59), added: 2534, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(59), added: 2534, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) fn unlock() -> Weight { // Proof Size summary in bytes: - // Measured: `11800` + // Measured: `11734` // Estimated: `30706` - // Minimum execution time: 66_247_000 picoseconds. - Weight::from_parts(67_552_000, 30706) + // Minimum execution time: 71_140_000 picoseconds. + Weight::from_parts(77_388_000, 30706) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) - /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(59), added: 2534, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(59), added: 2534, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn vote_new() -> Weight { // Proof Size summary in bytes: - // Measured: `13141` + // Measured: `13074` // Estimated: `219984` - // Minimum execution time: 102_539_000 picoseconds. - Weight::from_parts(105_873_000, 219984) + // Minimum execution time: 112_936_000 picoseconds. + Weight::from_parts(116_972_000, 219984) .saturating_add(RocksDbWeight::get().reads(7_u64)) - .saturating_add(RocksDbWeight::get().writes(7_u64)) + .saturating_add(RocksDbWeight::get().writes(6_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) - /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(59), added: 2534, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(59), added: 2534, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn vote_existing() -> Weight { // Proof Size summary in bytes: - // Measured: `20283` + // Measured: `20216` // Estimated: `219984` - // Minimum execution time: 275_424_000 picoseconds. - Weight::from_parts(283_690_000, 219984) + // Minimum execution time: 291_971_000 picoseconds. + Weight::from_parts(301_738_000, 219984) .saturating_add(RocksDbWeight::get().reads(7_u64)) - .saturating_add(RocksDbWeight::get().writes(7_u64)) + .saturating_add(RocksDbWeight::get().writes(6_u64)) } - /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn remove_vote() -> Weight { // Proof Size summary in bytes: - // Measured: `20035` + // Measured: `19968` // Estimated: `219984` - // Minimum execution time: 275_109_000 picoseconds. - Weight::from_parts(281_315_000, 219984) + // Minimum execution time: 262_582_000 picoseconds. + Weight::from_parts(270_955_000, 219984) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(5_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) fn remove_other_vote() -> Weight { // Proof Size summary in bytes: - // Measured: `12742` + // Measured: `12675` // Estimated: `30706` - // Minimum execution time: 49_629_000 picoseconds. - Weight::from_parts(51_300_000, 30706) + // Minimum execution time: 52_909_000 picoseconds. + Weight::from_parts(56_365_000, 30706) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `ConvictionVoting::VotingFor` (r:2 w:2) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) - /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(59), added: 2534, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: ConvictionVoting VotingFor (r:2 w:2) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(59), added: 2534, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) /// The range of component `r` is `[0, 1]`. fn delegate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `306 + r * (1628 ±0)` + // Measured: `240 + r * (1627 ±0)` // Estimated: `109992 + r * (109992 ±0)` - // Minimum execution time: 45_776_000 picoseconds. - Weight::from_parts(47_917_822, 109992) - // Standard Error: 124_174 - .saturating_add(Weight::from_parts(43_171_077, 0).saturating_mul(r.into())) + // Minimum execution time: 54_640_000 picoseconds. + Weight::from_parts(57_185_281, 109992) + // Standard Error: 193_362 + .saturating_add(Weight::from_parts(44_897_418, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) - .saturating_add(RocksDbWeight::get().writes((4_u64).saturating_mul(r.into()))) + .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 109992).saturating_mul(r.into())) } - /// Storage: `ConvictionVoting::VotingFor` (r:2 w:2) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: ConvictionVoting VotingFor (r:2 w:2) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) /// The range of component `r` is `[0, 1]`. fn undelegate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `472 + r * (1377 ±0)` + // Measured: `406 + r * (1376 ±0)` // Estimated: `109992 + r * (109992 ±0)` - // Minimum execution time: 23_600_000 picoseconds. - Weight::from_parts(25_001_426, 109992) - // Standard Error: 72_034 - .saturating_add(Weight::from_parts(37_851_873, 0).saturating_mul(r.into())) + // Minimum execution time: 26_514_000 picoseconds. + Weight::from_parts(28_083_732, 109992) + // Standard Error: 104_905 + .saturating_add(Weight::from_parts(40_722_467, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(2_u64)) - .saturating_add(RocksDbWeight::get().writes((4_u64).saturating_mul(r.into()))) + .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 109992).saturating_mul(r.into())) } - /// Storage: `ConvictionVoting::VotingFor` (r:1 w:1) - /// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`) - /// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1) - /// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(59), added: 2534, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: ConvictionVoting VotingFor (r:1 w:1) + /// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen) + /// Storage: ConvictionVoting ClassLocksFor (r:1 w:1) + /// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(59), added: 2534, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) fn unlock() -> Weight { // Proof Size summary in bytes: - // Measured: `11800` + // Measured: `11734` // Estimated: `30706` - // Minimum execution time: 66_247_000 picoseconds. - Weight::from_parts(67_552_000, 30706) + // Minimum execution time: 71_140_000 picoseconds. + Weight::from_parts(77_388_000, 30706) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } diff --git a/substrate/frame/core-fellowship/src/weights.rs b/substrate/frame/core-fellowship/src/weights.rs index fce1d3747a8..8bbfd1a4dd8 100644 --- a/substrate/frame/core-fellowship/src/weights.rs +++ b/substrate/frame/core-fellowship/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_core_fellowship` +//! Autogenerated weights for pallet_core_fellowship //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/core-fellowship/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/core-fellowship/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_core_fellowship`. +/// Weight functions needed for pallet_core_fellowship. pub trait WeightInfo { fn set_params() -> Weight; fn bump_offboard() -> Weight; @@ -63,344 +64,336 @@ pub trait WeightInfo { fn submit_evidence() -> Weight; } -/// Weights for `pallet_core_fellowship` using the Substrate node and recommended hardware. +/// Weights for pallet_core_fellowship using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `CoreFellowship::Params` (r:0 w:1) - /// Proof: `CoreFellowship::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) + /// Storage: CoreFellowship Params (r:0 w:1) + /// Proof: CoreFellowship Params (max_values: Some(1), max_size: Some(364), added: 859, mode: MaxEncodedLen) fn set_params() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_146_000 picoseconds. - Weight::from_parts(7_426_000, 0) + // Minimum execution time: 9_454_000 picoseconds. + Weight::from_parts(9_804_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `CoreFellowship::Member` (r:1 w:1) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::Members` (r:1 w:1) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::Params` (r:1 w:0) - /// Proof: `CoreFellowship::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::MemberCount` (r:1 w:1) - /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:1 w:1) - /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) - /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IndexToId` (r:0 w:1) - /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: CoreFellowship Member (r:1 w:1) + /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: RankedCollective Members (r:1 w:1) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: CoreFellowship Params (r:1 w:0) + /// Proof: CoreFellowship Params (max_values: Some(1), max_size: Some(364), added: 859, mode: MaxEncodedLen) + /// Storage: RankedCollective MemberCount (r:1 w:1) + /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: RankedCollective IdToIndex (r:1 w:0) + /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: CoreFellowship MemberEvidence (r:1 w:1) + /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) fn bump_offboard() -> Weight { // Proof Size summary in bytes: - // Measured: `17274` + // Measured: `16887` // Estimated: `19894` - // Minimum execution time: 54_511_000 picoseconds. - Weight::from_parts(56_995_000, 19894) + // Minimum execution time: 58_489_000 picoseconds. + Weight::from_parts(60_202_000, 19894) .saturating_add(T::DbWeight::get().reads(6_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `CoreFellowship::Member` (r:1 w:1) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::Members` (r:1 w:1) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::Params` (r:1 w:0) - /// Proof: `CoreFellowship::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::MemberCount` (r:1 w:1) - /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:1 w:1) - /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) - /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IndexToId` (r:0 w:1) - /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: CoreFellowship Member (r:1 w:1) + /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: RankedCollective Members (r:1 w:1) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: CoreFellowship Params (r:1 w:0) + /// Proof: CoreFellowship Params (max_values: Some(1), max_size: Some(364), added: 859, mode: MaxEncodedLen) + /// Storage: RankedCollective MemberCount (r:1 w:1) + /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: RankedCollective IdToIndex (r:1 w:0) + /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: CoreFellowship MemberEvidence (r:1 w:1) + /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) fn bump_demote() -> Weight { // Proof Size summary in bytes: - // Measured: `17384` + // Measured: `16997` // Estimated: `19894` - // Minimum execution time: 56_453_000 picoseconds. - Weight::from_parts(59_030_000, 19894) + // Minimum execution time: 60_605_000 picoseconds. + Weight::from_parts(63_957_000, 19894) .saturating_add(T::DbWeight::get().reads(6_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `RankedCollective::Members` (r:1 w:0) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::Member` (r:1 w:1) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:0) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: CoreFellowship Member (r:1 w:1) + /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) fn set_active() -> Weight { // Proof Size summary in bytes: // Measured: `388` // Estimated: `3514` - // Minimum execution time: 15_940_000 picoseconds. - Weight::from_parts(16_381_000, 3514) + // Minimum execution time: 17_816_000 picoseconds. + Weight::from_parts(18_524_000, 3514) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `CoreFellowship::Member` (r:1 w:1) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::Members` (r:1 w:1) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::MemberCount` (r:1 w:1) - /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IndexToId` (r:0 w:1) - /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:0 w:1) - /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: CoreFellowship Member (r:1 w:1) + /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: RankedCollective Members (r:1 w:1) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: RankedCollective MemberCount (r:1 w:1) + /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: RankedCollective IndexToId (r:0 w:1) + /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: RankedCollective IdToIndex (r:0 w:1) + /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) fn induct() -> Weight { // Proof Size summary in bytes: // Measured: `146` // Estimated: `3514` - // Minimum execution time: 24_193_000 picoseconds. - Weight::from_parts(24_963_000, 3514) + // Minimum execution time: 27_249_000 picoseconds. + Weight::from_parts(28_049_000, 3514) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: `RankedCollective::Members` (r:1 w:1) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::Member` (r:1 w:1) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::Params` (r:1 w:0) - /// Proof: `CoreFellowship::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::MemberCount` (r:1 w:1) - /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) - /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IndexToId` (r:0 w:1) - /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:0 w:1) - /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:1) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: CoreFellowship Member (r:1 w:1) + /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: CoreFellowship Params (r:1 w:0) + /// Proof: CoreFellowship Params (max_values: Some(1), max_size: Some(364), added: 859, mode: MaxEncodedLen) + /// Storage: RankedCollective MemberCount (r:1 w:1) + /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: CoreFellowship MemberEvidence (r:1 w:1) + /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) + /// Storage: RankedCollective IndexToId (r:0 w:1) + /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: RankedCollective IdToIndex (r:0 w:1) + /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) fn promote() -> Weight { // Proof Size summary in bytes: // Measured: `16865` // Estimated: `19894` - // Minimum execution time: 48_138_000 picoseconds. - Weight::from_parts(50_007_000, 19894) + // Minimum execution time: 56_642_000 picoseconds. + Weight::from_parts(59_353_000, 19894) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: `RankedCollective::Members` (r:1 w:0) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::Member` (r:1 w:1) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::MemberEvidence` (r:0 w:1) - /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:0) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: CoreFellowship Member (r:1 w:1) + /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: CoreFellowship MemberEvidence (r:0 w:1) + /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) fn offboard() -> Weight { // Proof Size summary in bytes: - // Measured: `293` + // Measured: `359` // Estimated: `3514` - // Minimum execution time: 15_225_000 picoseconds. - Weight::from_parts(15_730_000, 3514) + // Minimum execution time: 17_459_000 picoseconds. + Weight::from_parts(18_033_000, 3514) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `CoreFellowship::Member` (r:1 w:1) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::Members` (r:1 w:0) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: CoreFellowship Member (r:1 w:1) + /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: RankedCollective Members (r:1 w:0) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) fn import() -> Weight { // Proof Size summary in bytes: // Measured: `313` // Estimated: `3514` - // Minimum execution time: 14_507_000 picoseconds. - Weight::from_parts(14_935_000, 3514) + // Minimum execution time: 16_728_000 picoseconds. + Weight::from_parts(17_263_000, 3514) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `RankedCollective::Members` (r:1 w:0) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::Member` (r:1 w:1) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) - /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:0) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: CoreFellowship Member (r:1 w:1) + /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: CoreFellowship MemberEvidence (r:1 w:1) + /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) fn approve() -> Weight { // Proof Size summary in bytes: // Measured: `16843` // Estimated: `19894` - // Minimum execution time: 34_050_000 picoseconds. - Weight::from_parts(36_323_000, 19894) + // Minimum execution time: 41_487_000 picoseconds. + Weight::from_parts(43_459_000, 19894) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `CoreFellowship::Member` (r:1 w:0) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) - /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) + /// Storage: CoreFellowship Member (r:1 w:0) + /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: CoreFellowship MemberEvidence (r:1 w:1) + /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) fn submit_evidence() -> Weight { // Proof Size summary in bytes: // Measured: `79` // Estimated: `19894` - // Minimum execution time: 24_016_000 picoseconds. - Weight::from_parts(24_607_000, 19894) + // Minimum execution time: 26_033_000 picoseconds. + Weight::from_parts(26_612_000, 19894) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `CoreFellowship::Params` (r:0 w:1) - /// Proof: `CoreFellowship::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) + /// Storage: CoreFellowship Params (r:0 w:1) + /// Proof: CoreFellowship Params (max_values: Some(1), max_size: Some(364), added: 859, mode: MaxEncodedLen) fn set_params() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_146_000 picoseconds. - Weight::from_parts(7_426_000, 0) + // Minimum execution time: 9_454_000 picoseconds. + Weight::from_parts(9_804_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `CoreFellowship::Member` (r:1 w:1) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::Members` (r:1 w:1) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::Params` (r:1 w:0) - /// Proof: `CoreFellowship::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::MemberCount` (r:1 w:1) - /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:1 w:1) - /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) - /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IndexToId` (r:0 w:1) - /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: CoreFellowship Member (r:1 w:1) + /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: RankedCollective Members (r:1 w:1) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: CoreFellowship Params (r:1 w:0) + /// Proof: CoreFellowship Params (max_values: Some(1), max_size: Some(364), added: 859, mode: MaxEncodedLen) + /// Storage: RankedCollective MemberCount (r:1 w:1) + /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: RankedCollective IdToIndex (r:1 w:0) + /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: CoreFellowship MemberEvidence (r:1 w:1) + /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) fn bump_offboard() -> Weight { // Proof Size summary in bytes: - // Measured: `17274` + // Measured: `16887` // Estimated: `19894` - // Minimum execution time: 54_511_000 picoseconds. - Weight::from_parts(56_995_000, 19894) + // Minimum execution time: 58_489_000 picoseconds. + Weight::from_parts(60_202_000, 19894) .saturating_add(RocksDbWeight::get().reads(6_u64)) - .saturating_add(RocksDbWeight::get().writes(6_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `CoreFellowship::Member` (r:1 w:1) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::Members` (r:1 w:1) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::Params` (r:1 w:0) - /// Proof: `CoreFellowship::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::MemberCount` (r:1 w:1) - /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:1 w:1) - /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) - /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IndexToId` (r:0 w:1) - /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: CoreFellowship Member (r:1 w:1) + /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: RankedCollective Members (r:1 w:1) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: CoreFellowship Params (r:1 w:0) + /// Proof: CoreFellowship Params (max_values: Some(1), max_size: Some(364), added: 859, mode: MaxEncodedLen) + /// Storage: RankedCollective MemberCount (r:1 w:1) + /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: RankedCollective IdToIndex (r:1 w:0) + /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: CoreFellowship MemberEvidence (r:1 w:1) + /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) fn bump_demote() -> Weight { // Proof Size summary in bytes: - // Measured: `17384` + // Measured: `16997` // Estimated: `19894` - // Minimum execution time: 56_453_000 picoseconds. - Weight::from_parts(59_030_000, 19894) + // Minimum execution time: 60_605_000 picoseconds. + Weight::from_parts(63_957_000, 19894) .saturating_add(RocksDbWeight::get().reads(6_u64)) - .saturating_add(RocksDbWeight::get().writes(6_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `RankedCollective::Members` (r:1 w:0) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::Member` (r:1 w:1) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:0) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: CoreFellowship Member (r:1 w:1) + /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) fn set_active() -> Weight { // Proof Size summary in bytes: // Measured: `388` // Estimated: `3514` - // Minimum execution time: 15_940_000 picoseconds. - Weight::from_parts(16_381_000, 3514) + // Minimum execution time: 17_816_000 picoseconds. + Weight::from_parts(18_524_000, 3514) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `CoreFellowship::Member` (r:1 w:1) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::Members` (r:1 w:1) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::MemberCount` (r:1 w:1) - /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IndexToId` (r:0 w:1) - /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:0 w:1) - /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: CoreFellowship Member (r:1 w:1) + /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: RankedCollective Members (r:1 w:1) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: RankedCollective MemberCount (r:1 w:1) + /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: RankedCollective IndexToId (r:0 w:1) + /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: RankedCollective IdToIndex (r:0 w:1) + /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) fn induct() -> Weight { // Proof Size summary in bytes: // Measured: `146` // Estimated: `3514` - // Minimum execution time: 24_193_000 picoseconds. - Weight::from_parts(24_963_000, 3514) + // Minimum execution time: 27_249_000 picoseconds. + Weight::from_parts(28_049_000, 3514) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: `RankedCollective::Members` (r:1 w:1) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::Member` (r:1 w:1) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::Params` (r:1 w:0) - /// Proof: `CoreFellowship::Params` (`max_values`: Some(1), `max_size`: Some(364), added: 859, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::MemberCount` (r:1 w:1) - /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) - /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IndexToId` (r:0 w:1) - /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:0 w:1) - /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:1) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: CoreFellowship Member (r:1 w:1) + /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: CoreFellowship Params (r:1 w:0) + /// Proof: CoreFellowship Params (max_values: Some(1), max_size: Some(364), added: 859, mode: MaxEncodedLen) + /// Storage: RankedCollective MemberCount (r:1 w:1) + /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: CoreFellowship MemberEvidence (r:1 w:1) + /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) + /// Storage: RankedCollective IndexToId (r:0 w:1) + /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: RankedCollective IdToIndex (r:0 w:1) + /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) fn promote() -> Weight { // Proof Size summary in bytes: // Measured: `16865` // Estimated: `19894` - // Minimum execution time: 48_138_000 picoseconds. - Weight::from_parts(50_007_000, 19894) + // Minimum execution time: 56_642_000 picoseconds. + Weight::from_parts(59_353_000, 19894) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } - /// Storage: `RankedCollective::Members` (r:1 w:0) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::Member` (r:1 w:1) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::MemberEvidence` (r:0 w:1) - /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:0) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: CoreFellowship Member (r:1 w:1) + /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: CoreFellowship MemberEvidence (r:0 w:1) + /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) fn offboard() -> Weight { // Proof Size summary in bytes: - // Measured: `293` + // Measured: `359` // Estimated: `3514` - // Minimum execution time: 15_225_000 picoseconds. - Weight::from_parts(15_730_000, 3514) + // Minimum execution time: 17_459_000 picoseconds. + Weight::from_parts(18_033_000, 3514) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `CoreFellowship::Member` (r:1 w:1) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::Members` (r:1 w:0) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: CoreFellowship Member (r:1 w:1) + /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: RankedCollective Members (r:1 w:0) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) fn import() -> Weight { // Proof Size summary in bytes: // Measured: `313` // Estimated: `3514` - // Minimum execution time: 14_507_000 picoseconds. - Weight::from_parts(14_935_000, 3514) + // Minimum execution time: 16_728_000 picoseconds. + Weight::from_parts(17_263_000, 3514) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `RankedCollective::Members` (r:1 w:0) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::Member` (r:1 w:1) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) - /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:0) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: CoreFellowship Member (r:1 w:1) + /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: CoreFellowship MemberEvidence (r:1 w:1) + /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) fn approve() -> Weight { // Proof Size summary in bytes: // Measured: `16843` // Estimated: `19894` - // Minimum execution time: 34_050_000 picoseconds. - Weight::from_parts(36_323_000, 19894) + // Minimum execution time: 41_487_000 picoseconds. + Weight::from_parts(43_459_000, 19894) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `CoreFellowship::Member` (r:1 w:0) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:1) - /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) + /// Storage: CoreFellowship Member (r:1 w:0) + /// Proof: CoreFellowship Member (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: CoreFellowship MemberEvidence (r:1 w:1) + /// Proof: CoreFellowship MemberEvidence (max_values: None, max_size: Some(16429), added: 18904, mode: MaxEncodedLen) fn submit_evidence() -> Weight { // Proof Size summary in bytes: // Measured: `79` // Estimated: `19894` - // Minimum execution time: 24_016_000 picoseconds. - Weight::from_parts(24_607_000, 19894) + // Minimum execution time: 26_033_000 picoseconds. + Weight::from_parts(26_612_000, 19894) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/democracy/src/weights.rs b/substrate/frame/democracy/src/weights.rs index d6097922a82..241f6c3cb38 100644 --- a/substrate/frame/democracy/src/weights.rs +++ b/substrate/frame/democracy/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_democracy` +//! Autogenerated weights for pallet_democracy //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/democracy/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/democracy/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_democracy`. +/// Weight functions needed for pallet_democracy. pub trait WeightInfo { fn propose() -> Weight; fn second() -> Weight; @@ -81,916 +82,904 @@ pub trait WeightInfo { fn clear_referendum_metadata() -> Weight; } -/// Weights for `pallet_democracy` using the Substrate node and recommended hardware. +/// Weights for pallet_democracy using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Democracy::PublicPropCount` (r:1 w:1) - /// Proof: `Democracy::PublicPropCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Democracy::PublicProps` (r:1 w:1) - /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) - /// Storage: `Democracy::Blacklist` (r:1 w:0) - /// Proof: `Democracy::Blacklist` (`max_values`: None, `max_size`: Some(3238), added: 5713, mode: `MaxEncodedLen`) - /// Storage: `Democracy::DepositOf` (r:0 w:1) - /// Proof: `Democracy::DepositOf` (`max_values`: None, `max_size`: Some(3230), added: 5705, mode: `MaxEncodedLen`) + /// Storage: Democracy PublicPropCount (r:1 w:1) + /// Proof: Democracy PublicPropCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy PublicProps (r:1 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:1 w:0) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + /// Storage: Democracy DepositOf (r:0 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) fn propose() -> Weight { // Proof Size summary in bytes: - // Measured: `4834` + // Measured: `4801` // Estimated: `18187` - // Minimum execution time: 39_930_000 picoseconds. - Weight::from_parts(41_746_000, 18187) + // Minimum execution time: 49_339_000 picoseconds. + Weight::from_parts(50_942_000, 18187) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Democracy::DepositOf` (r:1 w:1) - /// Proof: `Democracy::DepositOf` (`max_values`: None, `max_size`: Some(3230), added: 5705, mode: `MaxEncodedLen`) + /// Storage: Democracy DepositOf (r:1 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) fn second() -> Weight { // Proof Size summary in bytes: - // Measured: `3589` + // Measured: `3556` // Estimated: `6695` - // Minimum execution time: 36_490_000 picoseconds. - Weight::from_parts(37_615_000, 6695) + // Minimum execution time: 43_291_000 picoseconds. + Weight::from_parts(44_856_000, 6695) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) - /// Storage: `Democracy::VotingOf` (r:1 w:1) - /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) fn vote_new() -> Weight { // Proof Size summary in bytes: - // Measured: `3503` + // Measured: `3470` // Estimated: `7260` - // Minimum execution time: 54_257_000 picoseconds. - Weight::from_parts(55_912_000, 7260) + // Minimum execution time: 61_890_000 picoseconds. + Weight::from_parts(63_626_000, 7260) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) - /// Storage: `Democracy::VotingOf` (r:1 w:1) - /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) fn vote_existing() -> Weight { // Proof Size summary in bytes: - // Measured: `3525` + // Measured: `3492` // Estimated: `7260` - // Minimum execution time: 56_878_000 picoseconds. - Weight::from_parts(58_796_000, 7260) + // Minimum execution time: 67_802_000 picoseconds. + Weight::from_parts(69_132_000, 7260) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) - /// Storage: `Democracy::Cancellations` (r:1 w:1) - /// Proof: `Democracy::Cancellations` (`max_values`: None, `max_size`: Some(33), added: 2508, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:1 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy Cancellations (r:1 w:1) + /// Proof: Democracy Cancellations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) fn emergency_cancel() -> Weight { // Proof Size summary in bytes: - // Measured: `399` + // Measured: `366` // Estimated: `3666` - // Minimum execution time: 22_700_000 picoseconds. - Weight::from_parts(23_539_000, 3666) + // Minimum execution time: 25_757_000 picoseconds. + Weight::from_parts(27_226_000, 3666) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Democracy::PublicProps` (r:1 w:1) - /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) - /// Storage: `Democracy::DepositOf` (r:1 w:1) - /// Proof: `Democracy::DepositOf` (`max_values`: None, `max_size`: Some(3230), added: 5705, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:3 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) - /// Storage: `Democracy::NextExternal` (r:1 w:1) - /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) - /// Storage: `Democracy::Blacklist` (r:0 w:1) - /// Proof: `Democracy::Blacklist` (`max_values`: None, `max_size`: Some(3238), added: 5713, mode: `MaxEncodedLen`) + /// Storage: Democracy PublicProps (r:1 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy DepositOf (r:1 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:3 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:0 w:1) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) fn blacklist() -> Weight { // Proof Size summary in bytes: - // Measured: `5943` + // Measured: `5910` // Estimated: `18187` - // Minimum execution time: 95_398_000 picoseconds. - Weight::from_parts(97_261_000, 18187) + // Minimum execution time: 113_060_000 picoseconds. + Weight::from_parts(114_813_000, 18187) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } - /// Storage: `Democracy::NextExternal` (r:1 w:1) - /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) - /// Storage: `Democracy::Blacklist` (r:1 w:0) - /// Proof: `Democracy::Blacklist` (`max_values`: None, `max_size`: Some(3238), added: 5713, mode: `MaxEncodedLen`) + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:1 w:0) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) fn external_propose() -> Weight { // Proof Size summary in bytes: - // Measured: `3449` + // Measured: `3416` // Estimated: `6703` - // Minimum execution time: 11_745_000 picoseconds. - Weight::from_parts(12_304_000, 6703) + // Minimum execution time: 13_413_000 picoseconds. + Weight::from_parts(13_794_000, 6703) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Democracy::NextExternal` (r:0 w:1) - /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) + /// Storage: Democracy NextExternal (r:0 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) fn external_propose_majority() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_710_000 picoseconds. - Weight::from_parts(2_918_000, 0) + // Minimum execution time: 3_213_000 picoseconds. + Weight::from_parts(3_429_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Democracy::NextExternal` (r:0 w:1) - /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) + /// Storage: Democracy NextExternal (r:0 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) fn external_propose_default() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_664_000 picoseconds. - Weight::from_parts(2_776_000, 0) + // Minimum execution time: 3_280_000 picoseconds. + Weight::from_parts(3_389_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Democracy::NextExternal` (r:1 w:1) - /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumCount` (r:1 w:1) - /// Proof: `Democracy::ReferendumCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:1 w:2) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumInfoOf` (r:0 w:1) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumCount (r:1 w:1) + /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:2) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:0 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) fn fast_track() -> Weight { // Proof Size summary in bytes: - // Measured: `319` + // Measured: `286` // Estimated: `3518` - // Minimum execution time: 22_585_000 picoseconds. - Weight::from_parts(23_689_000, 3518) + // Minimum execution time: 28_142_000 picoseconds. + Weight::from_parts(28_862_000, 3518) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: `Democracy::NextExternal` (r:1 w:1) - /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) - /// Storage: `Democracy::Blacklist` (r:1 w:1) - /// Proof: `Democracy::Blacklist` (`max_values`: None, `max_size`: Some(3238), added: 5713, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:1 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:1 w:1) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) fn veto_external() -> Weight { // Proof Size summary in bytes: - // Measured: `3552` + // Measured: `3519` // Estimated: `6703` - // Minimum execution time: 26_391_000 picoseconds. - Weight::from_parts(27_141_000, 6703) + // Minimum execution time: 32_395_000 picoseconds. + Weight::from_parts(33_617_000, 6703) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Democracy::PublicProps` (r:1 w:1) - /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) - /// Storage: `Democracy::DepositOf` (r:1 w:1) - /// Proof: `Democracy::DepositOf` (`max_values`: None, `max_size`: Some(3230), added: 5705, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:1 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: Democracy PublicProps (r:1 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy DepositOf (r:1 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) fn cancel_proposal() -> Weight { // Proof Size summary in bytes: - // Measured: `5854` + // Measured: `5821` // Estimated: `18187` - // Minimum execution time: 77_905_000 picoseconds. - Weight::from_parts(79_628_000, 18187) + // Minimum execution time: 92_255_000 picoseconds. + Weight::from_parts(93_704_000, 18187) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `Democracy::MetadataOf` (r:1 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumInfoOf` (r:0 w:1) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:0 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) fn cancel_referendum() -> Weight { // Proof Size summary in bytes: - // Measured: `304` + // Measured: `271` // Estimated: `3518` - // Minimum execution time: 15_735_000 picoseconds. - Weight::from_parts(16_525_000, 3518) + // Minimum execution time: 19_623_000 picoseconds. + Weight::from_parts(20_545_000, 3518) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Democracy::LowestUnbaked` (r:1 w:1) - /// Proof: `Democracy::LowestUnbaked` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumCount` (r:1 w:0) - /// Proof: `Democracy::ReferendumCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumInfoOf` (r:99 w:0) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: Democracy LowestUnbaked (r:1 w:1) + /// Proof: Democracy LowestUnbaked (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumCount (r:1 w:0) + /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:0) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) /// The range of component `r` is `[0, 99]`. fn on_initialize_base(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `277 + r * (86 ±0)` + // Measured: `244 + r * (86 ±0)` // Estimated: `1489 + r * (2676 ±0)` - // Minimum execution time: 5_274_000 picoseconds. - Weight::from_parts(6_162_399, 1489) - // Standard Error: 6_924 - .saturating_add(Weight::from_parts(3_186_702, 0).saturating_mul(r.into())) + // Minimum execution time: 7_032_000 picoseconds. + Weight::from_parts(7_931_421, 1489) + // Standard Error: 7_395 + .saturating_add(Weight::from_parts(3_236_964, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) } - /// Storage: `Democracy::LowestUnbaked` (r:1 w:1) - /// Proof: `Democracy::LowestUnbaked` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumCount` (r:1 w:0) - /// Proof: `Democracy::ReferendumCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Democracy::LastTabledWasExternal` (r:1 w:0) - /// Proof: `Democracy::LastTabledWasExternal` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) - /// Storage: `Democracy::NextExternal` (r:1 w:0) - /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) - /// Storage: `Democracy::PublicProps` (r:1 w:0) - /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumInfoOf` (r:99 w:0) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: Democracy LowestUnbaked (r:1 w:1) + /// Proof: Democracy LowestUnbaked (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumCount (r:1 w:0) + /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy LastTabledWasExternal (r:1 w:0) + /// Proof: Democracy LastTabledWasExternal (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: Democracy NextExternal (r:1 w:0) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy PublicProps (r:1 w:0) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:0) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) /// The range of component `r` is `[0, 99]`. fn on_initialize_base_with_launch_period(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `277 + r * (86 ±0)` + // Measured: `244 + r * (86 ±0)` // Estimated: `18187 + r * (2676 ±0)` - // Minimum execution time: 7_950_000 picoseconds. - Weight::from_parts(7_381_228, 18187) - // Standard Error: 6_650 - .saturating_add(Weight::from_parts(3_198_515, 0).saturating_mul(r.into())) + // Minimum execution time: 10_524_000 picoseconds. + Weight::from_parts(10_369_064, 18187) + // Standard Error: 8_385 + .saturating_add(Weight::from_parts(3_242_334, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) } - /// Storage: `Democracy::VotingOf` (r:3 w:3) - /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumInfoOf` (r:99 w:99) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: Democracy VotingOf (r:3 w:3) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:99) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) /// The range of component `r` is `[0, 99]`. fn delegate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `863 + r * (108 ±0)` + // Measured: `830 + r * (108 ±0)` // Estimated: `19800 + r * (2676 ±0)` - // Minimum execution time: 40_109_000 picoseconds. - Weight::from_parts(43_164_384, 19800) - // Standard Error: 7_267 - .saturating_add(Weight::from_parts(4_161_526, 0).saturating_mul(r.into())) + // Minimum execution time: 46_106_000 picoseconds. + Weight::from_parts(48_936_654, 19800) + // Standard Error: 8_879 + .saturating_add(Weight::from_parts(4_708_141, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) } - /// Storage: `Democracy::VotingOf` (r:2 w:2) - /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumInfoOf` (r:99 w:99) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: Democracy VotingOf (r:2 w:2) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:99) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) /// The range of component `r` is `[0, 99]`. fn undelegate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `526 + r * (108 ±0)` + // Measured: `493 + r * (108 ±0)` // Estimated: `13530 + r * (2676 ±0)` - // Minimum execution time: 17_466_000 picoseconds. - Weight::from_parts(18_004_456, 13530) - // Standard Error: 6_327 - .saturating_add(Weight::from_parts(4_194_583, 0).saturating_mul(r.into())) + // Minimum execution time: 21_078_000 picoseconds. + Weight::from_parts(22_732_737, 13530) + // Standard Error: 7_969 + .saturating_add(Weight::from_parts(4_626_458, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) } - /// Storage: `Democracy::PublicProps` (r:0 w:1) - /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) + /// Storage: Democracy PublicProps (r:0 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) fn clear_public_proposals() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_824_000 picoseconds. - Weight::from_parts(2_948_000, 0) + // Minimum execution time: 3_229_000 picoseconds. + Weight::from_parts(3_415_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Democracy::VotingOf` (r:1 w:1) - /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `r` is `[0, 99]`. fn unlock_remove(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `596` + // Measured: `563` // Estimated: `7260` - // Minimum execution time: 23_373_000 picoseconds. - Weight::from_parts(34_306_582, 7260) - // Standard Error: 2_849 - .saturating_add(Weight::from_parts(85_027, 0).saturating_mul(r.into())) + // Minimum execution time: 25_735_000 picoseconds. + Weight::from_parts(41_341_468, 7260) + // Standard Error: 3_727 + .saturating_add(Weight::from_parts(94_755, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Democracy::VotingOf` (r:1 w:1) - /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `r` is `[0, 99]`. fn unlock_set(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `597 + r * (22 ±0)` + // Measured: `564 + r * (22 ±0)` // Estimated: `7260` - // Minimum execution time: 31_574_000 picoseconds. - Weight::from_parts(33_906_658, 7260) - // Standard Error: 1_514 - .saturating_add(Weight::from_parts(124_471, 0).saturating_mul(r.into())) + // Minimum execution time: 36_233_000 picoseconds. + Weight::from_parts(39_836_017, 7260) + // Standard Error: 1_791 + .saturating_add(Weight::from_parts(132_158, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) - /// Storage: `Democracy::VotingOf` (r:1 w:1) - /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) /// The range of component `r` is `[1, 100]`. fn remove_vote(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `761 + r * (26 ±0)` + // Measured: `728 + r * (26 ±0)` // Estimated: `7260` - // Minimum execution time: 15_204_000 picoseconds. - Weight::from_parts(18_405_879, 7260) - // Standard Error: 1_851 - .saturating_add(Weight::from_parts(119_018, 0).saturating_mul(r.into())) + // Minimum execution time: 16_081_000 picoseconds. + Weight::from_parts(19_624_101, 7260) + // Standard Error: 1_639 + .saturating_add(Weight::from_parts(133_630, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) - /// Storage: `Democracy::VotingOf` (r:1 w:1) - /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) /// The range of component `r` is `[1, 100]`. fn remove_other_vote(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `761 + r * (26 ±0)` + // Measured: `728 + r * (26 ±0)` // Estimated: `7260` - // Minimum execution time: 15_120_000 picoseconds. - Weight::from_parts(18_282_222, 7260) - // Standard Error: 1_669 - .saturating_add(Weight::from_parts(127_649, 0).saturating_mul(r.into())) + // Minimum execution time: 15_634_000 picoseconds. + Weight::from_parts(19_573_407, 7260) + // Standard Error: 1_790 + .saturating_add(Weight::from_parts(139_707, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Democracy::NextExternal` (r:1 w:0) - /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:0 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: Democracy NextExternal (r:1 w:0) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:0 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) fn set_external_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `456` + // Measured: `356` // Estimated: `3556` - // Minimum execution time: 17_351_000 picoseconds. - Weight::from_parts(17_964_000, 3556) - .saturating_add(T::DbWeight::get().reads(3_u64)) + // Minimum execution time: 18_344_000 picoseconds. + Weight::from_parts(18_727_000, 3556) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Democracy::NextExternal` (r:1 w:0) - /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:1 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: Democracy NextExternal (r:1 w:0) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) fn clear_external_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `319` + // Measured: `286` // Estimated: `3518` - // Minimum execution time: 13_669_000 picoseconds. - Weight::from_parts(14_410_000, 3518) + // Minimum execution time: 16_497_000 picoseconds. + Weight::from_parts(16_892_000, 3518) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Democracy::PublicProps` (r:1 w:0) - /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:0 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: Democracy PublicProps (r:1 w:0) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:0 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) fn set_proposal_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `4988` + // Measured: `4888` // Estimated: `18187` - // Minimum execution time: 39_162_000 picoseconds. - Weight::from_parts(40_109_000, 18187) - .saturating_add(T::DbWeight::get().reads(3_u64)) + // Minimum execution time: 39_517_000 picoseconds. + Weight::from_parts(40_632_000, 18187) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Democracy::PublicProps` (r:1 w:0) - /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:1 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: Democracy PublicProps (r:1 w:0) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) fn clear_proposal_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `4855` + // Measured: `4822` // Estimated: `18187` - // Minimum execution time: 34_141_000 picoseconds. - Weight::from_parts(34_732_000, 18187) + // Minimum execution time: 37_108_000 picoseconds. + Weight::from_parts(37_599_000, 18187) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:0 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:0 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) fn set_referendum_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `211` + // Measured: `144` // Estimated: `3556` - // Minimum execution time: 13_413_000 picoseconds. - Weight::from_parts(14_039_000, 3556) - .saturating_add(T::DbWeight::get().reads(2_u64)) + // Minimum execution time: 13_997_000 picoseconds. + Weight::from_parts(14_298_000, 3556) + .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:0) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:1 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: Democracy ReferendumInfoOf (r:1 w:0) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) fn clear_referendum_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `335` + // Measured: `302` // Estimated: `3666` - // Minimum execution time: 16_010_000 picoseconds. - Weight::from_parts(16_474_000, 3666) + // Minimum execution time: 18_122_000 picoseconds. + Weight::from_parts(18_655_000, 3666) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Democracy::PublicPropCount` (r:1 w:1) - /// Proof: `Democracy::PublicPropCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Democracy::PublicProps` (r:1 w:1) - /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) - /// Storage: `Democracy::Blacklist` (r:1 w:0) - /// Proof: `Democracy::Blacklist` (`max_values`: None, `max_size`: Some(3238), added: 5713, mode: `MaxEncodedLen`) - /// Storage: `Democracy::DepositOf` (r:0 w:1) - /// Proof: `Democracy::DepositOf` (`max_values`: None, `max_size`: Some(3230), added: 5705, mode: `MaxEncodedLen`) + /// Storage: Democracy PublicPropCount (r:1 w:1) + /// Proof: Democracy PublicPropCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy PublicProps (r:1 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:1 w:0) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + /// Storage: Democracy DepositOf (r:0 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) fn propose() -> Weight { // Proof Size summary in bytes: - // Measured: `4834` + // Measured: `4801` // Estimated: `18187` - // Minimum execution time: 39_930_000 picoseconds. - Weight::from_parts(41_746_000, 18187) + // Minimum execution time: 49_339_000 picoseconds. + Weight::from_parts(50_942_000, 18187) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Democracy::DepositOf` (r:1 w:1) - /// Proof: `Democracy::DepositOf` (`max_values`: None, `max_size`: Some(3230), added: 5705, mode: `MaxEncodedLen`) + /// Storage: Democracy DepositOf (r:1 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) fn second() -> Weight { // Proof Size summary in bytes: - // Measured: `3589` + // Measured: `3556` // Estimated: `6695` - // Minimum execution time: 36_490_000 picoseconds. - Weight::from_parts(37_615_000, 6695) + // Minimum execution time: 43_291_000 picoseconds. + Weight::from_parts(44_856_000, 6695) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) - /// Storage: `Democracy::VotingOf` (r:1 w:1) - /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) fn vote_new() -> Weight { // Proof Size summary in bytes: - // Measured: `3503` + // Measured: `3470` // Estimated: `7260` - // Minimum execution time: 54_257_000 picoseconds. - Weight::from_parts(55_912_000, 7260) + // Minimum execution time: 61_890_000 picoseconds. + Weight::from_parts(63_626_000, 7260) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) - /// Storage: `Democracy::VotingOf` (r:1 w:1) - /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) fn vote_existing() -> Weight { // Proof Size summary in bytes: - // Measured: `3525` + // Measured: `3492` // Estimated: `7260` - // Minimum execution time: 56_878_000 picoseconds. - Weight::from_parts(58_796_000, 7260) + // Minimum execution time: 67_802_000 picoseconds. + Weight::from_parts(69_132_000, 7260) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) - /// Storage: `Democracy::Cancellations` (r:1 w:1) - /// Proof: `Democracy::Cancellations` (`max_values`: None, `max_size`: Some(33), added: 2508, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:1 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy Cancellations (r:1 w:1) + /// Proof: Democracy Cancellations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) fn emergency_cancel() -> Weight { // Proof Size summary in bytes: - // Measured: `399` + // Measured: `366` // Estimated: `3666` - // Minimum execution time: 22_700_000 picoseconds. - Weight::from_parts(23_539_000, 3666) + // Minimum execution time: 25_757_000 picoseconds. + Weight::from_parts(27_226_000, 3666) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Democracy::PublicProps` (r:1 w:1) - /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) - /// Storage: `Democracy::DepositOf` (r:1 w:1) - /// Proof: `Democracy::DepositOf` (`max_values`: None, `max_size`: Some(3230), added: 5705, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:3 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) - /// Storage: `Democracy::NextExternal` (r:1 w:1) - /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) - /// Storage: `Democracy::Blacklist` (r:0 w:1) - /// Proof: `Democracy::Blacklist` (`max_values`: None, `max_size`: Some(3238), added: 5713, mode: `MaxEncodedLen`) + /// Storage: Democracy PublicProps (r:1 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy DepositOf (r:1 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:3 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:0 w:1) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) fn blacklist() -> Weight { // Proof Size summary in bytes: - // Measured: `5943` + // Measured: `5910` // Estimated: `18187` - // Minimum execution time: 95_398_000 picoseconds. - Weight::from_parts(97_261_000, 18187) + // Minimum execution time: 113_060_000 picoseconds. + Weight::from_parts(114_813_000, 18187) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } - /// Storage: `Democracy::NextExternal` (r:1 w:1) - /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) - /// Storage: `Democracy::Blacklist` (r:1 w:0) - /// Proof: `Democracy::Blacklist` (`max_values`: None, `max_size`: Some(3238), added: 5713, mode: `MaxEncodedLen`) + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:1 w:0) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) fn external_propose() -> Weight { // Proof Size summary in bytes: - // Measured: `3449` + // Measured: `3416` // Estimated: `6703` - // Minimum execution time: 11_745_000 picoseconds. - Weight::from_parts(12_304_000, 6703) + // Minimum execution time: 13_413_000 picoseconds. + Weight::from_parts(13_794_000, 6703) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Democracy::NextExternal` (r:0 w:1) - /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) + /// Storage: Democracy NextExternal (r:0 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) fn external_propose_majority() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_710_000 picoseconds. - Weight::from_parts(2_918_000, 0) + // Minimum execution time: 3_213_000 picoseconds. + Weight::from_parts(3_429_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Democracy::NextExternal` (r:0 w:1) - /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) + /// Storage: Democracy NextExternal (r:0 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) fn external_propose_default() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_664_000 picoseconds. - Weight::from_parts(2_776_000, 0) + // Minimum execution time: 3_280_000 picoseconds. + Weight::from_parts(3_389_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Democracy::NextExternal` (r:1 w:1) - /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumCount` (r:1 w:1) - /// Proof: `Democracy::ReferendumCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:1 w:2) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumInfoOf` (r:0 w:1) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumCount (r:1 w:1) + /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:2) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:0 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) fn fast_track() -> Weight { // Proof Size summary in bytes: - // Measured: `319` + // Measured: `286` // Estimated: `3518` - // Minimum execution time: 22_585_000 picoseconds. - Weight::from_parts(23_689_000, 3518) + // Minimum execution time: 28_142_000 picoseconds. + Weight::from_parts(28_862_000, 3518) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: `Democracy::NextExternal` (r:1 w:1) - /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) - /// Storage: `Democracy::Blacklist` (r:1 w:1) - /// Proof: `Democracy::Blacklist` (`max_values`: None, `max_size`: Some(3238), added: 5713, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:1 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: Democracy NextExternal (r:1 w:1) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy Blacklist (r:1 w:1) + /// Proof: Democracy Blacklist (max_values: None, max_size: Some(3238), added: 5713, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) fn veto_external() -> Weight { // Proof Size summary in bytes: - // Measured: `3552` + // Measured: `3519` // Estimated: `6703` - // Minimum execution time: 26_391_000 picoseconds. - Weight::from_parts(27_141_000, 6703) + // Minimum execution time: 32_395_000 picoseconds. + Weight::from_parts(33_617_000, 6703) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Democracy::PublicProps` (r:1 w:1) - /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) - /// Storage: `Democracy::DepositOf` (r:1 w:1) - /// Proof: `Democracy::DepositOf` (`max_values`: None, `max_size`: Some(3230), added: 5705, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:1 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: Democracy PublicProps (r:1 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy DepositOf (r:1 w:1) + /// Proof: Democracy DepositOf (max_values: None, max_size: Some(3230), added: 5705, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) fn cancel_proposal() -> Weight { // Proof Size summary in bytes: - // Measured: `5854` + // Measured: `5821` // Estimated: `18187` - // Minimum execution time: 77_905_000 picoseconds. - Weight::from_parts(79_628_000, 18187) + // Minimum execution time: 92_255_000 picoseconds. + Weight::from_parts(93_704_000, 18187) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `Democracy::MetadataOf` (r:1 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumInfoOf` (r:0 w:1) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:0 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) fn cancel_referendum() -> Weight { // Proof Size summary in bytes: - // Measured: `304` + // Measured: `271` // Estimated: `3518` - // Minimum execution time: 15_735_000 picoseconds. - Weight::from_parts(16_525_000, 3518) + // Minimum execution time: 19_623_000 picoseconds. + Weight::from_parts(20_545_000, 3518) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Democracy::LowestUnbaked` (r:1 w:1) - /// Proof: `Democracy::LowestUnbaked` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumCount` (r:1 w:0) - /// Proof: `Democracy::ReferendumCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumInfoOf` (r:99 w:0) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: Democracy LowestUnbaked (r:1 w:1) + /// Proof: Democracy LowestUnbaked (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumCount (r:1 w:0) + /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:0) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) /// The range of component `r` is `[0, 99]`. fn on_initialize_base(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `277 + r * (86 ±0)` + // Measured: `244 + r * (86 ±0)` // Estimated: `1489 + r * (2676 ±0)` - // Minimum execution time: 5_274_000 picoseconds. - Weight::from_parts(6_162_399, 1489) - // Standard Error: 6_924 - .saturating_add(Weight::from_parts(3_186_702, 0).saturating_mul(r.into())) + // Minimum execution time: 7_032_000 picoseconds. + Weight::from_parts(7_931_421, 1489) + // Standard Error: 7_395 + .saturating_add(Weight::from_parts(3_236_964, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) } - /// Storage: `Democracy::LowestUnbaked` (r:1 w:1) - /// Proof: `Democracy::LowestUnbaked` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumCount` (r:1 w:0) - /// Proof: `Democracy::ReferendumCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Democracy::LastTabledWasExternal` (r:1 w:0) - /// Proof: `Democracy::LastTabledWasExternal` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) - /// Storage: `Democracy::NextExternal` (r:1 w:0) - /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) - /// Storage: `Democracy::PublicProps` (r:1 w:0) - /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumInfoOf` (r:99 w:0) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: Democracy LowestUnbaked (r:1 w:1) + /// Proof: Democracy LowestUnbaked (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumCount (r:1 w:0) + /// Proof: Democracy ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Democracy LastTabledWasExternal (r:1 w:0) + /// Proof: Democracy LastTabledWasExternal (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: Democracy NextExternal (r:1 w:0) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy PublicProps (r:1 w:0) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:0) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) /// The range of component `r` is `[0, 99]`. fn on_initialize_base_with_launch_period(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `277 + r * (86 ±0)` + // Measured: `244 + r * (86 ±0)` // Estimated: `18187 + r * (2676 ±0)` - // Minimum execution time: 7_950_000 picoseconds. - Weight::from_parts(7_381_228, 18187) - // Standard Error: 6_650 - .saturating_add(Weight::from_parts(3_198_515, 0).saturating_mul(r.into())) + // Minimum execution time: 10_524_000 picoseconds. + Weight::from_parts(10_369_064, 18187) + // Standard Error: 8_385 + .saturating_add(Weight::from_parts(3_242_334, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) } - /// Storage: `Democracy::VotingOf` (r:3 w:3) - /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumInfoOf` (r:99 w:99) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: Democracy VotingOf (r:3 w:3) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:99) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) /// The range of component `r` is `[0, 99]`. fn delegate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `863 + r * (108 ±0)` + // Measured: `830 + r * (108 ±0)` // Estimated: `19800 + r * (2676 ±0)` - // Minimum execution time: 40_109_000 picoseconds. - Weight::from_parts(43_164_384, 19800) - // Standard Error: 7_267 - .saturating_add(Weight::from_parts(4_161_526, 0).saturating_mul(r.into())) + // Minimum execution time: 46_106_000 picoseconds. + Weight::from_parts(48_936_654, 19800) + // Standard Error: 8_879 + .saturating_add(Weight::from_parts(4_708_141, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) } - /// Storage: `Democracy::VotingOf` (r:2 w:2) - /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) - /// Storage: `Democracy::ReferendumInfoOf` (r:99 w:99) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) + /// Storage: Democracy VotingOf (r:2 w:2) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Democracy ReferendumInfoOf (r:99 w:99) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) /// The range of component `r` is `[0, 99]`. fn undelegate(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `526 + r * (108 ±0)` + // Measured: `493 + r * (108 ±0)` // Estimated: `13530 + r * (2676 ±0)` - // Minimum execution time: 17_466_000 picoseconds. - Weight::from_parts(18_004_456, 13530) - // Standard Error: 6_327 - .saturating_add(Weight::from_parts(4_194_583, 0).saturating_mul(r.into())) + // Minimum execution time: 21_078_000 picoseconds. + Weight::from_parts(22_732_737, 13530) + // Standard Error: 7_969 + .saturating_add(Weight::from_parts(4_626_458, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2676).saturating_mul(r.into())) } - /// Storage: `Democracy::PublicProps` (r:0 w:1) - /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) + /// Storage: Democracy PublicProps (r:0 w:1) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) fn clear_public_proposals() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_824_000 picoseconds. - Weight::from_parts(2_948_000, 0) + // Minimum execution time: 3_229_000 picoseconds. + Weight::from_parts(3_415_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Democracy::VotingOf` (r:1 w:1) - /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `r` is `[0, 99]`. fn unlock_remove(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `596` + // Measured: `563` // Estimated: `7260` - // Minimum execution time: 23_373_000 picoseconds. - Weight::from_parts(34_306_582, 7260) - // Standard Error: 2_849 - .saturating_add(Weight::from_parts(85_027, 0).saturating_mul(r.into())) + // Minimum execution time: 25_735_000 picoseconds. + Weight::from_parts(41_341_468, 7260) + // Standard Error: 3_727 + .saturating_add(Weight::from_parts(94_755, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Democracy::VotingOf` (r:1 w:1) - /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `r` is `[0, 99]`. fn unlock_set(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `597 + r * (22 ±0)` + // Measured: `564 + r * (22 ±0)` // Estimated: `7260` - // Minimum execution time: 31_574_000 picoseconds. - Weight::from_parts(33_906_658, 7260) - // Standard Error: 1_514 - .saturating_add(Weight::from_parts(124_471, 0).saturating_mul(r.into())) + // Minimum execution time: 36_233_000 picoseconds. + Weight::from_parts(39_836_017, 7260) + // Standard Error: 1_791 + .saturating_add(Weight::from_parts(132_158, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) - /// Storage: `Democracy::VotingOf` (r:1 w:1) - /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) /// The range of component `r` is `[1, 100]`. fn remove_vote(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `761 + r * (26 ±0)` + // Measured: `728 + r * (26 ±0)` // Estimated: `7260` - // Minimum execution time: 15_204_000 picoseconds. - Weight::from_parts(18_405_879, 7260) - // Standard Error: 1_851 - .saturating_add(Weight::from_parts(119_018, 0).saturating_mul(r.into())) + // Minimum execution time: 16_081_000 picoseconds. + Weight::from_parts(19_624_101, 7260) + // Standard Error: 1_639 + .saturating_add(Weight::from_parts(133_630, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:1) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) - /// Storage: `Democracy::VotingOf` (r:1 w:1) - /// Proof: `Democracy::VotingOf` (`max_values`: None, `max_size`: Some(3795), added: 6270, mode: `MaxEncodedLen`) + /// Storage: Democracy ReferendumInfoOf (r:1 w:1) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy VotingOf (r:1 w:1) + /// Proof: Democracy VotingOf (max_values: None, max_size: Some(3795), added: 6270, mode: MaxEncodedLen) /// The range of component `r` is `[1, 100]`. fn remove_other_vote(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `761 + r * (26 ±0)` + // Measured: `728 + r * (26 ±0)` // Estimated: `7260` - // Minimum execution time: 15_120_000 picoseconds. - Weight::from_parts(18_282_222, 7260) - // Standard Error: 1_669 - .saturating_add(Weight::from_parts(127_649, 0).saturating_mul(r.into())) + // Minimum execution time: 15_634_000 picoseconds. + Weight::from_parts(19_573_407, 7260) + // Standard Error: 1_790 + .saturating_add(Weight::from_parts(139_707, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Democracy::NextExternal` (r:1 w:0) - /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:0 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: Democracy NextExternal (r:1 w:0) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:0 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) fn set_external_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `456` + // Measured: `356` // Estimated: `3556` - // Minimum execution time: 17_351_000 picoseconds. - Weight::from_parts(17_964_000, 3556) - .saturating_add(RocksDbWeight::get().reads(3_u64)) + // Minimum execution time: 18_344_000 picoseconds. + Weight::from_parts(18_727_000, 3556) + .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Democracy::NextExternal` (r:1 w:0) - /// Proof: `Democracy::NextExternal` (`max_values`: Some(1), `max_size`: Some(132), added: 627, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:1 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: Democracy NextExternal (r:1 w:0) + /// Proof: Democracy NextExternal (max_values: Some(1), max_size: Some(132), added: 627, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) fn clear_external_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `319` + // Measured: `286` // Estimated: `3518` - // Minimum execution time: 13_669_000 picoseconds. - Weight::from_parts(14_410_000, 3518) + // Minimum execution time: 16_497_000 picoseconds. + Weight::from_parts(16_892_000, 3518) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Democracy::PublicProps` (r:1 w:0) - /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:0 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: Democracy PublicProps (r:1 w:0) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:0 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) fn set_proposal_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `4988` + // Measured: `4888` // Estimated: `18187` - // Minimum execution time: 39_162_000 picoseconds. - Weight::from_parts(40_109_000, 18187) - .saturating_add(RocksDbWeight::get().reads(3_u64)) + // Minimum execution time: 39_517_000 picoseconds. + Weight::from_parts(40_632_000, 18187) + .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Democracy::PublicProps` (r:1 w:0) - /// Proof: `Democracy::PublicProps` (`max_values`: Some(1), `max_size`: Some(16702), added: 17197, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:1 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: Democracy PublicProps (r:1 w:0) + /// Proof: Democracy PublicProps (max_values: Some(1), max_size: Some(16702), added: 17197, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) fn clear_proposal_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `4855` + // Measured: `4822` // Estimated: `18187` - // Minimum execution time: 34_141_000 picoseconds. - Weight::from_parts(34_732_000, 18187) + // Minimum execution time: 37_108_000 picoseconds. + Weight::from_parts(37_599_000, 18187) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:0 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:0 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) fn set_referendum_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `211` + // Measured: `144` // Estimated: `3556` - // Minimum execution time: 13_413_000 picoseconds. - Weight::from_parts(14_039_000, 3556) - .saturating_add(RocksDbWeight::get().reads(2_u64)) + // Minimum execution time: 13_997_000 picoseconds. + Weight::from_parts(14_298_000, 3556) + .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Democracy::ReferendumInfoOf` (r:1 w:0) - /// Proof: `Democracy::ReferendumInfoOf` (`max_values`: None, `max_size`: Some(201), added: 2676, mode: `MaxEncodedLen`) - /// Storage: `Democracy::MetadataOf` (r:1 w:1) - /// Proof: `Democracy::MetadataOf` (`max_values`: None, `max_size`: Some(53), added: 2528, mode: `MaxEncodedLen`) + /// Storage: Democracy ReferendumInfoOf (r:1 w:0) + /// Proof: Democracy ReferendumInfoOf (max_values: None, max_size: Some(201), added: 2676, mode: MaxEncodedLen) + /// Storage: Democracy MetadataOf (r:1 w:1) + /// Proof: Democracy MetadataOf (max_values: None, max_size: Some(53), added: 2528, mode: MaxEncodedLen) fn clear_referendum_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `335` + // Measured: `302` // Estimated: `3666` - // Minimum execution time: 16_010_000 picoseconds. - Weight::from_parts(16_474_000, 3666) + // Minimum execution time: 18_122_000 picoseconds. + Weight::from_parts(18_655_000, 3666) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/election-provider-multi-phase/src/mock.rs b/substrate/frame/election-provider-multi-phase/src/mock.rs index 312dc557090..18dcd7061c1 100644 --- a/substrate/frame/election-provider-multi-phase/src/mock.rs +++ b/substrate/frame/election-provider-multi-phase/src/mock.rs @@ -441,7 +441,7 @@ where type Extrinsic = Extrinsic; } -pub type Extrinsic = sp_runtime::generic::UncheckedExtrinsic; +pub type Extrinsic = sp_runtime::testing::TestXt; parameter_types! { pub MaxNominations: u32 = ::LIMIT as u32; diff --git a/substrate/frame/election-provider-multi-phase/src/unsigned.rs b/substrate/frame/election-provider-multi-phase/src/unsigned.rs index 94cfd059b6c..94348181334 100644 --- a/substrate/frame/election-provider-multi-phase/src/unsigned.rs +++ b/substrate/frame/election-provider-multi-phase/src/unsigned.rs @@ -1813,7 +1813,7 @@ mod tests { let encoded = pool.read().transactions[0].clone(); let extrinsic: Extrinsic = codec::Decode::decode(&mut &*encoded).unwrap(); - let call = extrinsic.function; + let call = extrinsic.call; assert!(matches!(call, RuntimeCall::MultiPhase(Call::submit_unsigned { .. }))); }) } @@ -1830,7 +1830,7 @@ mod tests { let encoded = pool.read().transactions[0].clone(); let extrinsic = Extrinsic::decode(&mut &*encoded).unwrap(); - let call = match extrinsic.function { + let call = match extrinsic.call { RuntimeCall::MultiPhase(call @ Call::submit_unsigned { .. }) => call, _ => panic!("bad call: unexpected submission"), }; diff --git a/substrate/frame/election-provider-multi-phase/src/weights.rs b/substrate/frame/election-provider-multi-phase/src/weights.rs index ed3e942716e..be578fac8c4 100644 --- a/substrate/frame/election-provider-multi-phase/src/weights.rs +++ b/substrate/frame/election-provider-multi-phase/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_election_provider_multi_phase` +//! Autogenerated weights for pallet_election_provider_multi_phase //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/election-provider-multi-phase/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/election-provider-multi-phase/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_election_provider_multi_phase`. +/// Weight functions needed for pallet_election_provider_multi_phase. pub trait WeightInfo { fn on_initialize_nothing() -> Weight; fn on_initialize_open_signed() -> Weight; @@ -63,171 +64,169 @@ pub trait WeightInfo { fn feasibility_check(v: u32, t: u32, a: u32, d: u32, ) -> Weight; } -/// Weights for `pallet_election_provider_multi_phase` using the Substrate node and recommended hardware. +/// Weights for pallet_election_provider_multi_phase using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Staking::CurrentEra` (r:1 w:0) - /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::CurrentPlannedSession` (r:1 w:0) - /// Proof: `Staking::CurrentPlannedSession` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::ErasStartSessionIndex` (r:1 w:0) - /// Proof: `Staking::ErasStartSessionIndex` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `Babe::EpochIndex` (r:1 w:0) - /// Proof: `Babe::EpochIndex` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Babe::GenesisSlot` (r:1 w:0) - /// Proof: `Babe::GenesisSlot` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Babe::CurrentSlot` (r:1 w:0) - /// Proof: `Babe::CurrentSlot` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Staking::ForceEra` (r:1 w:0) - /// Proof: `Staking::ForceEra` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) - /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CurrentPlannedSession (r:1 w:0) + /// Proof: Staking CurrentPlannedSession (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:1 w:0) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Babe EpochIndex (r:1 w:0) + /// Proof: Babe EpochIndex (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe GenesisSlot (r:1 w:0) + /// Proof: Babe GenesisSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe CurrentSlot (r:1 w:0) + /// Proof: Babe CurrentSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Staking ForceEra (r:1 w:0) + /// Proof: Staking ForceEra (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) fn on_initialize_nothing() -> Weight { // Proof Size summary in bytes: - // Measured: `1061` + // Measured: `1028` // Estimated: `3481` - // Minimum execution time: 19_340_000 picoseconds. - Weight::from_parts(19_886_000, 3481) + // Minimum execution time: 22_089_000 picoseconds. + Weight::from_parts(22_677_000, 3481) .saturating_add(T::DbWeight::get().reads(8_u64)) } - /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) fn on_initialize_open_signed() -> Weight { // Proof Size summary in bytes: // Measured: `148` // Estimated: `1633` - // Minimum execution time: 8_067_000 picoseconds. - Weight::from_parts(8_508_000, 1633) + // Minimum execution time: 11_986_000 picoseconds. + Weight::from_parts(12_445_000, 1633) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) fn on_initialize_open_unsigned() -> Weight { // Proof Size summary in bytes: // Measured: `148` // Estimated: `1633` - // Minimum execution time: 8_810_000 picoseconds. - Weight::from_parts(9_061_000, 1633) + // Minimum execution time: 12_988_000 picoseconds. + Weight::from_parts(13_281_000, 1633) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ElectionProviderMultiPhase::QueuedSolution` (r:0 w:1) - /// Proof: `ElectionProviderMultiPhase::QueuedSolution` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase QueuedSolution (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) fn finalize_signed_phase_accept_solution() -> Weight { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 24_339_000 picoseconds. - Weight::from_parts(25_322_000, 3593) + // Minimum execution time: 32_659_000 picoseconds. + Weight::from_parts(33_281_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn finalize_signed_phase_reject_solution() -> Weight { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 16_635_000 picoseconds. - Weight::from_parts(17_497_000, 3593) + // Minimum execution time: 22_471_000 picoseconds. + Weight::from_parts(23_046_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `ElectionProviderMultiPhase::SnapshotMetadata` (r:0 w:1) - /// Proof: `ElectionProviderMultiPhase::SnapshotMetadata` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::DesiredTargets` (r:0 w:1) - /// Proof: `ElectionProviderMultiPhase::DesiredTargets` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::Snapshot` (r:0 w:1) - /// Proof: `ElectionProviderMultiPhase::Snapshot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `v` is `[1000, 2000]`. /// The range of component `t` is `[500, 1000]`. fn create_snapshot_internal(v: u32, _t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 170_730_000 picoseconds. - Weight::from_parts(175_009_000, 0) - // Standard Error: 2_010 - .saturating_add(Weight::from_parts(224_974, 0).saturating_mul(v.into())) + // Minimum execution time: 262_360_000 picoseconds. + Weight::from_parts(279_313_000, 0) + // Standard Error: 2_384 + .saturating_add(Weight::from_parts(176_415, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `ElectionProviderMultiPhase::SignedSubmissionIndices` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::SignedSubmissionIndices` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::SignedSubmissionNextIndex` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::SignedSubmissionNextIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::SnapshotMetadata` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::SnapshotMetadata` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::SignedSubmissionsMap` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::SignedSubmissionsMap` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::QueuedSolution` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::QueuedSolution` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::DesiredTargets` (r:0 w:1) - /// Proof: `ElectionProviderMultiPhase::DesiredTargets` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::Snapshot` (r:0 w:1) - /// Proof: `ElectionProviderMultiPhase::Snapshot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: ElectionProviderMultiPhase SignedSubmissionIndices (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionIndices (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionNextIndex (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionNextIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionsMap (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionsMap (max_values: None, max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase QueuedSolution (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Round (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `a` is `[500, 800]`. /// The range of component `d` is `[200, 400]`. fn elect_queued(a: u32, d: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `371 + a * (768 ±0) + d * (48 ±0)` // Estimated: `3923 + a * (768 ±0) + d * (49 ±0)` - // Minimum execution time: 280_705_000 picoseconds. - Weight::from_parts(303_018_000, 3923) - // Standard Error: 4_633 - .saturating_add(Weight::from_parts(307_274, 0).saturating_mul(a.into())) + // Minimum execution time: 301_283_000 picoseconds. + Weight::from_parts(324_586_000, 3923) + // Standard Error: 4_763 + .saturating_add(Weight::from_parts(279_812, 0).saturating_mul(a.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(8_u64)) .saturating_add(Weight::from_parts(0, 768).saturating_mul(a.into())) .saturating_add(Weight::from_parts(0, 49).saturating_mul(d.into())) } - /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::SnapshotMetadata` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::SnapshotMetadata` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::SignedSubmissionIndices` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::SignedSubmissionIndices` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::SignedSubmissionNextIndex` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::SignedSubmissionNextIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `ElectionProviderMultiPhase::SignedSubmissionsMap` (r:0 w:1) - /// Proof: `ElectionProviderMultiPhase::SignedSubmissionsMap` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TransactionPayment NextFeeMultiplier (r:1 w:0) + /// Proof: TransactionPayment NextFeeMultiplier (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase SignedSubmissionIndices (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionIndices (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionNextIndex (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionNextIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionsMap (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionsMap (max_values: None, max_size: None, mode: Measured) fn submit() -> Weight { // Proof Size summary in bytes: // Measured: `927` // Estimated: `2412` - // Minimum execution time: 43_405_000 picoseconds. - Weight::from_parts(45_734_000, 2412) - .saturating_add(T::DbWeight::get().reads(6_u64)) + // Minimum execution time: 52_276_000 picoseconds. + Weight::from_parts(53_846_000, 2412) + .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::DesiredTargets` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::DesiredTargets` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::QueuedSolution` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::QueuedSolution` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::SnapshotMetadata` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::SnapshotMetadata` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::Snapshot` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::Snapshot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::MinimumUntrustedScore` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::MinimumUntrustedScore` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase QueuedSolution (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase MinimumUntrustedScore (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase MinimumUntrustedScore (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `v` is `[1000, 2000]`. /// The range of component `t` is `[500, 1000]`. /// The range of component `a` is `[500, 800]`. @@ -236,25 +235,25 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `253 + t * (32 ±0) + v * (553 ±0)` // Estimated: `1738 + t * (32 ±0) + v * (553 ±0)` - // Minimum execution time: 5_059_092_000 picoseconds. - Weight::from_parts(5_263_076_000, 1738) - // Standard Error: 17_317 - .saturating_add(Weight::from_parts(384_051, 0).saturating_mul(v.into())) - // Standard Error: 51_319 - .saturating_add(Weight::from_parts(4_095_128, 0).saturating_mul(a.into())) + // Minimum execution time: 5_448_459_000 picoseconds. + Weight::from_parts(5_525_622_000, 1738) + // Standard Error: 21_478 + .saturating_add(Weight::from_parts(256_345, 0).saturating_mul(v.into())) + // Standard Error: 63_648 + .saturating_add(Weight::from_parts(5_103_224, 0).saturating_mul(a.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(t.into())) .saturating_add(Weight::from_parts(0, 553).saturating_mul(v.into())) } - /// Storage: `ElectionProviderMultiPhase::DesiredTargets` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::DesiredTargets` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::Snapshot` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::Snapshot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::MinimumUntrustedScore` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::MinimumUntrustedScore` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase MinimumUntrustedScore (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase MinimumUntrustedScore (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `v` is `[1000, 2000]`. /// The range of component `t` is `[500, 1000]`. /// The range of component `a` is `[500, 800]`. @@ -263,182 +262,180 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `228 + t * (32 ±0) + v * (553 ±0)` // Estimated: `1713 + t * (32 ±0) + v * (553 ±0)` - // Minimum execution time: 4_426_416_000 picoseconds. - Weight::from_parts(4_466_923_000, 1713) - // Standard Error: 15_415 - .saturating_add(Weight::from_parts(334_047, 0).saturating_mul(v.into())) - // Standard Error: 45_682 - .saturating_add(Weight::from_parts(3_097_318, 0).saturating_mul(a.into())) + // Minimum execution time: 4_724_399_000 picoseconds. + Weight::from_parts(4_886_472_000, 1713) + // Standard Error: 15_220 + .saturating_add(Weight::from_parts(365_569, 0).saturating_mul(v.into())) + // Standard Error: 45_104 + .saturating_add(Weight::from_parts(3_176_675, 0).saturating_mul(a.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(t.into())) .saturating_add(Weight::from_parts(0, 553).saturating_mul(v.into())) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Staking::CurrentEra` (r:1 w:0) - /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::CurrentPlannedSession` (r:1 w:0) - /// Proof: `Staking::CurrentPlannedSession` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::ErasStartSessionIndex` (r:1 w:0) - /// Proof: `Staking::ErasStartSessionIndex` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) - /// Storage: `Babe::EpochIndex` (r:1 w:0) - /// Proof: `Babe::EpochIndex` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Babe::GenesisSlot` (r:1 w:0) - /// Proof: `Babe::GenesisSlot` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Babe::CurrentSlot` (r:1 w:0) - /// Proof: `Babe::CurrentSlot` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Staking::ForceEra` (r:1 w:0) - /// Proof: `Staking::ForceEra` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) - /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CurrentPlannedSession (r:1 w:0) + /// Proof: Staking CurrentPlannedSession (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ErasStartSessionIndex (r:1 w:0) + /// Proof: Staking ErasStartSessionIndex (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen) + /// Storage: Babe EpochIndex (r:1 w:0) + /// Proof: Babe EpochIndex (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe GenesisSlot (r:1 w:0) + /// Proof: Babe GenesisSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe CurrentSlot (r:1 w:0) + /// Proof: Babe CurrentSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Staking ForceEra (r:1 w:0) + /// Proof: Staking ForceEra (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) fn on_initialize_nothing() -> Weight { // Proof Size summary in bytes: - // Measured: `1061` + // Measured: `1028` // Estimated: `3481` - // Minimum execution time: 19_340_000 picoseconds. - Weight::from_parts(19_886_000, 3481) + // Minimum execution time: 22_089_000 picoseconds. + Weight::from_parts(22_677_000, 3481) .saturating_add(RocksDbWeight::get().reads(8_u64)) } - /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) fn on_initialize_open_signed() -> Weight { // Proof Size summary in bytes: // Measured: `148` // Estimated: `1633` - // Minimum execution time: 8_067_000 picoseconds. - Weight::from_parts(8_508_000, 1633) + // Minimum execution time: 11_986_000 picoseconds. + Weight::from_parts(12_445_000, 1633) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) fn on_initialize_open_unsigned() -> Weight { // Proof Size summary in bytes: // Measured: `148` // Estimated: `1633` - // Minimum execution time: 8_810_000 picoseconds. - Weight::from_parts(9_061_000, 1633) + // Minimum execution time: 12_988_000 picoseconds. + Weight::from_parts(13_281_000, 1633) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ElectionProviderMultiPhase::QueuedSolution` (r:0 w:1) - /// Proof: `ElectionProviderMultiPhase::QueuedSolution` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase QueuedSolution (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) fn finalize_signed_phase_accept_solution() -> Weight { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 24_339_000 picoseconds. - Weight::from_parts(25_322_000, 3593) + // Minimum execution time: 32_659_000 picoseconds. + Weight::from_parts(33_281_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn finalize_signed_phase_reject_solution() -> Weight { // Proof Size summary in bytes: // Measured: `174` // Estimated: `3593` - // Minimum execution time: 16_635_000 picoseconds. - Weight::from_parts(17_497_000, 3593) + // Minimum execution time: 22_471_000 picoseconds. + Weight::from_parts(23_046_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `ElectionProviderMultiPhase::SnapshotMetadata` (r:0 w:1) - /// Proof: `ElectionProviderMultiPhase::SnapshotMetadata` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::DesiredTargets` (r:0 w:1) - /// Proof: `ElectionProviderMultiPhase::DesiredTargets` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::Snapshot` (r:0 w:1) - /// Proof: `ElectionProviderMultiPhase::Snapshot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `v` is `[1000, 2000]`. /// The range of component `t` is `[500, 1000]`. fn create_snapshot_internal(v: u32, _t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 170_730_000 picoseconds. - Weight::from_parts(175_009_000, 0) - // Standard Error: 2_010 - .saturating_add(Weight::from_parts(224_974, 0).saturating_mul(v.into())) + // Minimum execution time: 262_360_000 picoseconds. + Weight::from_parts(279_313_000, 0) + // Standard Error: 2_384 + .saturating_add(Weight::from_parts(176_415, 0).saturating_mul(v.into())) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `ElectionProviderMultiPhase::SignedSubmissionIndices` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::SignedSubmissionIndices` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::SignedSubmissionNextIndex` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::SignedSubmissionNextIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::SnapshotMetadata` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::SnapshotMetadata` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::SignedSubmissionsMap` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::SignedSubmissionsMap` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::QueuedSolution` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::QueuedSolution` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::DesiredTargets` (r:0 w:1) - /// Proof: `ElectionProviderMultiPhase::DesiredTargets` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::Snapshot` (r:0 w:1) - /// Proof: `ElectionProviderMultiPhase::Snapshot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: ElectionProviderMultiPhase SignedSubmissionIndices (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionIndices (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionNextIndex (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionNextIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionsMap (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionsMap (max_values: None, max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase QueuedSolution (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Round (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `a` is `[500, 800]`. /// The range of component `d` is `[200, 400]`. fn elect_queued(a: u32, d: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `371 + a * (768 ±0) + d * (48 ±0)` // Estimated: `3923 + a * (768 ±0) + d * (49 ±0)` - // Minimum execution time: 280_705_000 picoseconds. - Weight::from_parts(303_018_000, 3923) - // Standard Error: 4_633 - .saturating_add(Weight::from_parts(307_274, 0).saturating_mul(a.into())) + // Minimum execution time: 301_283_000 picoseconds. + Weight::from_parts(324_586_000, 3923) + // Standard Error: 4_763 + .saturating_add(Weight::from_parts(279_812, 0).saturating_mul(a.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(8_u64)) .saturating_add(Weight::from_parts(0, 768).saturating_mul(a.into())) .saturating_add(Weight::from_parts(0, 49).saturating_mul(d.into())) } - /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::SnapshotMetadata` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::SnapshotMetadata` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::SignedSubmissionIndices` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::SignedSubmissionIndices` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::SignedSubmissionNextIndex` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::SignedSubmissionNextIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `ElectionProviderMultiPhase::SignedSubmissionsMap` (r:0 w:1) - /// Proof: `ElectionProviderMultiPhase::SignedSubmissionsMap` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TransactionPayment NextFeeMultiplier (r:1 w:0) + /// Proof: TransactionPayment NextFeeMultiplier (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase SignedSubmissionIndices (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionIndices (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionNextIndex (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionNextIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SignedSubmissionsMap (r:0 w:1) + /// Proof Skipped: ElectionProviderMultiPhase SignedSubmissionsMap (max_values: None, max_size: None, mode: Measured) fn submit() -> Weight { // Proof Size summary in bytes: // Measured: `927` // Estimated: `2412` - // Minimum execution time: 43_405_000 picoseconds. - Weight::from_parts(45_734_000, 2412) - .saturating_add(RocksDbWeight::get().reads(6_u64)) + // Minimum execution time: 52_276_000 picoseconds. + Weight::from_parts(53_846_000, 2412) + .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::DesiredTargets` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::DesiredTargets` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::QueuedSolution` (r:1 w:1) - /// Proof: `ElectionProviderMultiPhase::QueuedSolution` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::SnapshotMetadata` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::SnapshotMetadata` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::Snapshot` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::Snapshot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::MinimumUntrustedScore` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::MinimumUntrustedScore` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase QueuedSolution (r:1 w:1) + /// Proof Skipped: ElectionProviderMultiPhase QueuedSolution (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase SnapshotMetadata (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase SnapshotMetadata (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase MinimumUntrustedScore (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase MinimumUntrustedScore (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `v` is `[1000, 2000]`. /// The range of component `t` is `[500, 1000]`. /// The range of component `a` is `[500, 800]`. @@ -447,25 +444,25 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `253 + t * (32 ±0) + v * (553 ±0)` // Estimated: `1738 + t * (32 ±0) + v * (553 ±0)` - // Minimum execution time: 5_059_092_000 picoseconds. - Weight::from_parts(5_263_076_000, 1738) - // Standard Error: 17_317 - .saturating_add(Weight::from_parts(384_051, 0).saturating_mul(v.into())) - // Standard Error: 51_319 - .saturating_add(Weight::from_parts(4_095_128, 0).saturating_mul(a.into())) + // Minimum execution time: 5_448_459_000 picoseconds. + Weight::from_parts(5_525_622_000, 1738) + // Standard Error: 21_478 + .saturating_add(Weight::from_parts(256_345, 0).saturating_mul(v.into())) + // Standard Error: 63_648 + .saturating_add(Weight::from_parts(5_103_224, 0).saturating_mul(a.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(t.into())) .saturating_add(Weight::from_parts(0, 553).saturating_mul(v.into())) } - /// Storage: `ElectionProviderMultiPhase::DesiredTargets` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::DesiredTargets` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::Snapshot` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::Snapshot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::Round` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::Round` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ElectionProviderMultiPhase::MinimumUntrustedScore` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::MinimumUntrustedScore` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: ElectionProviderMultiPhase DesiredTargets (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase DesiredTargets (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Snapshot (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Snapshot (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase Round (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase Round (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ElectionProviderMultiPhase MinimumUntrustedScore (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase MinimumUntrustedScore (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `v` is `[1000, 2000]`. /// The range of component `t` is `[500, 1000]`. /// The range of component `a` is `[500, 800]`. @@ -474,12 +471,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `228 + t * (32 ±0) + v * (553 ±0)` // Estimated: `1713 + t * (32 ±0) + v * (553 ±0)` - // Minimum execution time: 4_426_416_000 picoseconds. - Weight::from_parts(4_466_923_000, 1713) - // Standard Error: 15_415 - .saturating_add(Weight::from_parts(334_047, 0).saturating_mul(v.into())) - // Standard Error: 45_682 - .saturating_add(Weight::from_parts(3_097_318, 0).saturating_mul(a.into())) + // Minimum execution time: 4_724_399_000 picoseconds. + Weight::from_parts(4_886_472_000, 1713) + // Standard Error: 15_220 + .saturating_add(Weight::from_parts(365_569, 0).saturating_mul(v.into())) + // Standard Error: 45_104 + .saturating_add(Weight::from_parts(3_176_675, 0).saturating_mul(a.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(t.into())) .saturating_add(Weight::from_parts(0, 553).saturating_mul(v.into())) diff --git a/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs b/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs index 7fade251e6d..882b894bb22 100644 --- a/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs +++ b/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs @@ -62,7 +62,7 @@ pub const INIT_TIMESTAMP: BlockNumber = 30_000; pub const BLOCK_TIME: BlockNumber = 1000; type Block = frame_system::mocking::MockBlockU32; -type Extrinsic = sp_runtime::generic::UncheckedExtrinsic; +type Extrinsic = testing::TestXt; frame_support::construct_runtime!( pub enum Runtime { @@ -699,7 +699,7 @@ pub fn roll_to_with_ocw(n: BlockNumber, pool: Arc>, delay_solu for encoded in &pool.read().transactions { let extrinsic = Extrinsic::decode(&mut &encoded[..]).unwrap(); - let _ = match extrinsic.function { + let _ = match extrinsic.call { RuntimeCall::ElectionProviderMultiPhase( call @ Call::submit_unsigned { .. }, ) => { diff --git a/substrate/frame/elections-phragmen/src/lib.rs b/substrate/frame/elections-phragmen/src/lib.rs index e08412a6e87..308f2cdc1aa 100644 --- a/substrate/frame/elections-phragmen/src/lib.rs +++ b/substrate/frame/elections-phragmen/src/lib.rs @@ -1422,7 +1422,7 @@ mod tests { pub type Block = sp_runtime::generic::Block; pub type UncheckedExtrinsic = - sp_runtime::generic::UncheckedExtrinsic; + sp_runtime::generic::UncheckedExtrinsic; frame_support::construct_runtime!( pub enum Test diff --git a/substrate/frame/elections-phragmen/src/weights.rs b/substrate/frame/elections-phragmen/src/weights.rs index cd67918e85b..b7ed13dae9f 100644 --- a/substrate/frame/elections-phragmen/src/weights.rs +++ b/substrate/frame/elections-phragmen/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_elections_phragmen` +//! Autogenerated weights for pallet_elections_phragmen //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/elections-phragmen/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/elections-phragmen/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_elections_phragmen`. +/// Weight functions needed for pallet_elections_phragmen. pub trait WeightInfo { fn vote_equal(v: u32, ) -> Weight; fn vote_more(v: u32, ) -> Weight; @@ -65,165 +66,165 @@ pub trait WeightInfo { fn election_phragmen(c: u32, v: u32, e: u32, ) -> Weight; } -/// Weights for `pallet_elections_phragmen` using the Substrate node and recommended hardware. +/// Weights for pallet_elections_phragmen using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Elections::Candidates` (r:1 w:0) - /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Members` (r:1 w:0) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::RunnersUp` (r:1 w:0) - /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Voting` (r:1 w:1) - /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: Elections Candidates (r:1 w:0) + /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Members (r:1 w:0) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections RunnersUp (r:1 w:0) + /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Voting (r:1 w:1) + /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) /// The range of component `v` is `[1, 16]`. fn vote_equal(v: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `403 + v * (80 ±0)` // Estimated: `4764 + v * (80 ±0)` - // Minimum execution time: 29_390_000 picoseconds. - Weight::from_parts(30_525_476, 4764) - // Standard Error: 3_185 - .saturating_add(Weight::from_parts(143_073, 0).saturating_mul(v.into())) + // Minimum execution time: 33_028_000 picoseconds. + Weight::from_parts(34_073_914, 4764) + // Standard Error: 3_474 + .saturating_add(Weight::from_parts(205_252, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 80).saturating_mul(v.into())) } - /// Storage: `Elections::Candidates` (r:1 w:0) - /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Members` (r:1 w:0) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::RunnersUp` (r:1 w:0) - /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Voting` (r:1 w:1) - /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: Elections Candidates (r:1 w:0) + /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Members (r:1 w:0) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections RunnersUp (r:1 w:0) + /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Voting (r:1 w:1) + /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) /// The range of component `v` is `[2, 16]`. fn vote_more(v: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `371 + v * (80 ±0)` // Estimated: `4764 + v * (80 ±0)` - // Minimum execution time: 39_765_000 picoseconds. - Weight::from_parts(41_374_102, 4764) - // Standard Error: 4_310 - .saturating_add(Weight::from_parts(153_015, 0).saturating_mul(v.into())) + // Minimum execution time: 45_725_000 picoseconds. + Weight::from_parts(47_169_586, 4764) + // Standard Error: 5_148 + .saturating_add(Weight::from_parts(213_742, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 80).saturating_mul(v.into())) } - /// Storage: `Elections::Candidates` (r:1 w:0) - /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Members` (r:1 w:0) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::RunnersUp` (r:1 w:0) - /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Voting` (r:1 w:1) - /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: Elections Candidates (r:1 w:0) + /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Members (r:1 w:0) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections RunnersUp (r:1 w:0) + /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Voting (r:1 w:1) + /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) /// The range of component `v` is `[2, 16]`. fn vote_less(v: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `403 + v * (80 ±0)` // Estimated: `4764 + v * (80 ±0)` - // Minimum execution time: 39_647_000 picoseconds. - Weight::from_parts(41_474_523, 4764) - // Standard Error: 5_503 - .saturating_add(Weight::from_parts(149_029, 0).saturating_mul(v.into())) + // Minimum execution time: 45_519_000 picoseconds. + Weight::from_parts(47_339_108, 4764) + // Standard Error: 5_501 + .saturating_add(Weight::from_parts(195_247, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 80).saturating_mul(v.into())) } - /// Storage: `Elections::Voting` (r:1 w:1) - /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: Elections Voting (r:1 w:1) + /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) fn remove_voter() -> Weight { // Proof Size summary in bytes: // Measured: `925` // Estimated: `4764` - // Minimum execution time: 41_882_000 picoseconds. - Weight::from_parts(42_794_000, 4764) + // Minimum execution time: 50_386_000 picoseconds. + Weight::from_parts(51_378_000, 4764) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Elections::Candidates` (r:1 w:1) - /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Members` (r:1 w:0) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::RunnersUp` (r:1 w:0) - /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Elections Candidates (r:1 w:1) + /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Members (r:1 w:0) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections RunnersUp (r:1 w:0) + /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `c` is `[1, 64]`. fn submit_candidacy(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `1570 + c * (48 ±0)` // Estimated: `3055 + c * (48 ±0)` - // Minimum execution time: 33_719_000 picoseconds. - Weight::from_parts(35_017_073, 3055) - // Standard Error: 1_587 - .saturating_add(Weight::from_parts(121_130, 0).saturating_mul(c.into())) + // Minimum execution time: 38_987_000 picoseconds. + Weight::from_parts(41_302_276, 3055) + // Standard Error: 2_047 + .saturating_add(Weight::from_parts(125_200, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 48).saturating_mul(c.into())) } - /// Storage: `Elections::Candidates` (r:1 w:1) - /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Elections Candidates (r:1 w:1) + /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `c` is `[1, 64]`. fn renounce_candidacy_candidate(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `285 + c * (48 ±0)` // Estimated: `1770 + c * (48 ±0)` - // Minimum execution time: 27_263_000 picoseconds. - Weight::from_parts(28_215_666, 1770) - // Standard Error: 1_196 - .saturating_add(Weight::from_parts(86_804, 0).saturating_mul(c.into())) + // Minimum execution time: 33_510_000 picoseconds. + Weight::from_parts(34_947_760, 1770) + // Standard Error: 1_781 + .saturating_add(Weight::from_parts(78_851, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 48).saturating_mul(c.into())) } - /// Storage: `Elections::Members` (r:1 w:1) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::RunnersUp` (r:1 w:1) - /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Prime` (r:1 w:1) - /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Proposals` (r:1 w:0) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Members` (r:0 w:1) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Elections Members (r:1 w:1) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections RunnersUp (r:1 w:1) + /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Members (r:0 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) fn renounce_candidacy_members() -> Weight { // Proof Size summary in bytes: - // Measured: `1933` - // Estimated: `3418` - // Minimum execution time: 41_531_000 picoseconds. - Weight::from_parts(42_937_000, 3418) + // Measured: `1900` + // Estimated: `3385` + // Minimum execution time: 50_603_000 picoseconds. + Weight::from_parts(51_715_000, 3385) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `Elections::RunnersUp` (r:1 w:1) - /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Elections RunnersUp (r:1 w:1) + /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) fn renounce_candidacy_runners_up() -> Weight { // Proof Size summary in bytes: // Measured: `880` // Estimated: `2365` - // Minimum execution time: 27_680_000 picoseconds. - Weight::from_parts(28_810_000, 2365) + // Minimum execution time: 33_441_000 picoseconds. + Weight::from_parts(34_812_000, 2365) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Benchmark::Override` (r:0 w:0) - /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Benchmark Override (r:0 w:0) + /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) fn remove_member_without_replacement() -> Weight { // Proof Size summary in bytes: // Measured: `0` @@ -231,90 +232,87 @@ impl WeightInfo for SubstrateWeight { // Minimum execution time: 2_000_000_000_000 picoseconds. Weight::from_parts(2_000_000_000_000, 0) } - /// Storage: `Elections::Members` (r:1 w:1) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Elections::RunnersUp` (r:1 w:1) - /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Prime` (r:1 w:1) - /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Proposals` (r:1 w:0) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Members` (r:0 w:1) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Elections Members (r:1 w:1) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Elections RunnersUp (r:1 w:1) + /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Members (r:0 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) fn remove_member_with_replacement() -> Weight { // Proof Size summary in bytes: - // Measured: `1933` + // Measured: `1900` // Estimated: `3593` - // Minimum execution time: 45_333_000 picoseconds. - Weight::from_parts(46_523_000, 3593) + // Minimum execution time: 57_289_000 picoseconds. + Weight::from_parts(58_328_000, 3593) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: `Elections::Voting` (r:257 w:256) - /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Members` (r:1 w:0) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::RunnersUp` (r:1 w:0) - /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Candidates` (r:1 w:0) - /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Locks` (r:256 w:256) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:256 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:256 w:256) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Elections Voting (r:513 w:512) + /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Elections Members (r:1 w:0) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections RunnersUp (r:1 w:0) + /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Candidates (r:1 w:0) + /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Balances Locks (r:512 w:512) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:512 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:512 w:512) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `v` is `[256, 512]`. /// The range of component `d` is `[0, 256]`. - fn clean_defunct_voters(v: u32, d: u32, ) -> Weight { + fn clean_defunct_voters(v: u32, _d: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0 + d * (818 ±0) + v * (57 ±0)` - // Estimated: `24906 + d * (3774 ±1) + v * (24 ±0)` - // Minimum execution time: 5_620_000 picoseconds. - Weight::from_parts(5_817_000, 24906) - // Standard Error: 18_357 - .saturating_add(Weight::from_parts(106_164, 0).saturating_mul(v.into())) - // Standard Error: 39_980 - .saturating_add(Weight::from_parts(52_456_337, 0).saturating_mul(d.into())) + // Measured: `1149 + v * (811 ±0)` + // Estimated: `4621 + v * (3774 ±0)` + // Minimum execution time: 18_774_231_000 picoseconds. + Weight::from_parts(18_933_040_000, 4621) + // Standard Error: 301_534 + .saturating_add(Weight::from_parts(44_306_903, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(d.into()))) - .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(d.into()))) - .saturating_add(Weight::from_parts(0, 3774).saturating_mul(d.into())) - .saturating_add(Weight::from_parts(0, 24).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(v.into()))) + .saturating_add(Weight::from_parts(0, 3774).saturating_mul(v.into())) } - /// Storage: `Elections::Candidates` (r:1 w:1) - /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Members` (r:1 w:1) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::RunnersUp` (r:1 w:1) - /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Voting` (r:513 w:0) - /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Council::Proposals` (r:1 w:0) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:44 w:44) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Elections::ElectionRounds` (r:1 w:1) - /// Proof: `Elections::ElectionRounds` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Members` (r:0 w:1) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Prime` (r:0 w:1) - /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Elections Candidates (r:1 w:1) + /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Members (r:1 w:1) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections RunnersUp (r:1 w:1) + /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Voting (r:513 w:0) + /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:44 w:44) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Elections ElectionRounds (r:1 w:1) + /// Proof Skipped: Elections ElectionRounds (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Members (r:0 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:0 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `c` is `[1, 64]`. /// The range of component `v` is `[1, 512]`. /// The range of component `e` is `[512, 8192]`. fn election_phragmen(c: u32, v: u32, e: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + e * (28 ±0) + v * (606 ±0)` - // Estimated: `178920 + c * (2135 ±7) + e * (12 ±0) + v * (2653 ±6)` - // Minimum execution time: 1_082_582_000 picoseconds. - Weight::from_parts(1_084_730_000, 178920) - // Standard Error: 594_096 - .saturating_add(Weight::from_parts(19_096_288, 0).saturating_mul(v.into())) - // Standard Error: 38_118 - .saturating_add(Weight::from_parts(792_945, 0).saturating_mul(e.into())) + // Estimated: `178887 + c * (2135 ±7) + e * (12 ±0) + v * (2653 ±6)` + // Minimum execution time: 1_281_877_000 picoseconds. + Weight::from_parts(1_288_147_000, 178887) + // Standard Error: 528_851 + .saturating_add(Weight::from_parts(17_761_407, 0).saturating_mul(v.into())) + // Standard Error: 33_932 + .saturating_add(Weight::from_parts(698_277, 0).saturating_mul(e.into())) .saturating_add(T::DbWeight::get().reads(21_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into()))) @@ -326,164 +324,164 @@ impl WeightInfo for SubstrateWeight { } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Elections::Candidates` (r:1 w:0) - /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Members` (r:1 w:0) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::RunnersUp` (r:1 w:0) - /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Voting` (r:1 w:1) - /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: Elections Candidates (r:1 w:0) + /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Members (r:1 w:0) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections RunnersUp (r:1 w:0) + /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Voting (r:1 w:1) + /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) /// The range of component `v` is `[1, 16]`. fn vote_equal(v: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `403 + v * (80 ±0)` // Estimated: `4764 + v * (80 ±0)` - // Minimum execution time: 29_390_000 picoseconds. - Weight::from_parts(30_525_476, 4764) - // Standard Error: 3_185 - .saturating_add(Weight::from_parts(143_073, 0).saturating_mul(v.into())) + // Minimum execution time: 33_028_000 picoseconds. + Weight::from_parts(34_073_914, 4764) + // Standard Error: 3_474 + .saturating_add(Weight::from_parts(205_252, 0).saturating_mul(v.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 80).saturating_mul(v.into())) } - /// Storage: `Elections::Candidates` (r:1 w:0) - /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Members` (r:1 w:0) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::RunnersUp` (r:1 w:0) - /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Voting` (r:1 w:1) - /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: Elections Candidates (r:1 w:0) + /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Members (r:1 w:0) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections RunnersUp (r:1 w:0) + /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Voting (r:1 w:1) + /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) /// The range of component `v` is `[2, 16]`. fn vote_more(v: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `371 + v * (80 ±0)` // Estimated: `4764 + v * (80 ±0)` - // Minimum execution time: 39_765_000 picoseconds. - Weight::from_parts(41_374_102, 4764) - // Standard Error: 4_310 - .saturating_add(Weight::from_parts(153_015, 0).saturating_mul(v.into())) + // Minimum execution time: 45_725_000 picoseconds. + Weight::from_parts(47_169_586, 4764) + // Standard Error: 5_148 + .saturating_add(Weight::from_parts(213_742, 0).saturating_mul(v.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 80).saturating_mul(v.into())) } - /// Storage: `Elections::Candidates` (r:1 w:0) - /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Members` (r:1 w:0) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::RunnersUp` (r:1 w:0) - /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Voting` (r:1 w:1) - /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: Elections Candidates (r:1 w:0) + /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Members (r:1 w:0) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections RunnersUp (r:1 w:0) + /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Voting (r:1 w:1) + /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) /// The range of component `v` is `[2, 16]`. fn vote_less(v: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `403 + v * (80 ±0)` // Estimated: `4764 + v * (80 ±0)` - // Minimum execution time: 39_647_000 picoseconds. - Weight::from_parts(41_474_523, 4764) - // Standard Error: 5_503 - .saturating_add(Weight::from_parts(149_029, 0).saturating_mul(v.into())) + // Minimum execution time: 45_519_000 picoseconds. + Weight::from_parts(47_339_108, 4764) + // Standard Error: 5_501 + .saturating_add(Weight::from_parts(195_247, 0).saturating_mul(v.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 80).saturating_mul(v.into())) } - /// Storage: `Elections::Voting` (r:1 w:1) - /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: Elections Voting (r:1 w:1) + /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) fn remove_voter() -> Weight { // Proof Size summary in bytes: // Measured: `925` // Estimated: `4764` - // Minimum execution time: 41_882_000 picoseconds. - Weight::from_parts(42_794_000, 4764) + // Minimum execution time: 50_386_000 picoseconds. + Weight::from_parts(51_378_000, 4764) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Elections::Candidates` (r:1 w:1) - /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Members` (r:1 w:0) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::RunnersUp` (r:1 w:0) - /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Elections Candidates (r:1 w:1) + /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Members (r:1 w:0) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections RunnersUp (r:1 w:0) + /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `c` is `[1, 64]`. fn submit_candidacy(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `1570 + c * (48 ±0)` // Estimated: `3055 + c * (48 ±0)` - // Minimum execution time: 33_719_000 picoseconds. - Weight::from_parts(35_017_073, 3055) - // Standard Error: 1_587 - .saturating_add(Weight::from_parts(121_130, 0).saturating_mul(c.into())) + // Minimum execution time: 38_987_000 picoseconds. + Weight::from_parts(41_302_276, 3055) + // Standard Error: 2_047 + .saturating_add(Weight::from_parts(125_200, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 48).saturating_mul(c.into())) } - /// Storage: `Elections::Candidates` (r:1 w:1) - /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Elections Candidates (r:1 w:1) + /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `c` is `[1, 64]`. fn renounce_candidacy_candidate(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `285 + c * (48 ±0)` // Estimated: `1770 + c * (48 ±0)` - // Minimum execution time: 27_263_000 picoseconds. - Weight::from_parts(28_215_666, 1770) - // Standard Error: 1_196 - .saturating_add(Weight::from_parts(86_804, 0).saturating_mul(c.into())) + // Minimum execution time: 33_510_000 picoseconds. + Weight::from_parts(34_947_760, 1770) + // Standard Error: 1_781 + .saturating_add(Weight::from_parts(78_851, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 48).saturating_mul(c.into())) } - /// Storage: `Elections::Members` (r:1 w:1) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::RunnersUp` (r:1 w:1) - /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Prime` (r:1 w:1) - /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Proposals` (r:1 w:0) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Members` (r:0 w:1) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Elections Members (r:1 w:1) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections RunnersUp (r:1 w:1) + /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Members (r:0 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) fn renounce_candidacy_members() -> Weight { // Proof Size summary in bytes: - // Measured: `1933` - // Estimated: `3418` - // Minimum execution time: 41_531_000 picoseconds. - Weight::from_parts(42_937_000, 3418) + // Measured: `1900` + // Estimated: `3385` + // Minimum execution time: 50_603_000 picoseconds. + Weight::from_parts(51_715_000, 3385) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `Elections::RunnersUp` (r:1 w:1) - /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Elections RunnersUp (r:1 w:1) + /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) fn renounce_candidacy_runners_up() -> Weight { // Proof Size summary in bytes: // Measured: `880` // Estimated: `2365` - // Minimum execution time: 27_680_000 picoseconds. - Weight::from_parts(28_810_000, 2365) + // Minimum execution time: 33_441_000 picoseconds. + Weight::from_parts(34_812_000, 2365) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Benchmark::Override` (r:0 w:0) - /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Benchmark Override (r:0 w:0) + /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) fn remove_member_without_replacement() -> Weight { // Proof Size summary in bytes: // Measured: `0` @@ -491,90 +489,87 @@ impl WeightInfo for () { // Minimum execution time: 2_000_000_000_000 picoseconds. Weight::from_parts(2_000_000_000_000, 0) } - /// Storage: `Elections::Members` (r:1 w:1) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Elections::RunnersUp` (r:1 w:1) - /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Prime` (r:1 w:1) - /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Proposals` (r:1 w:0) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Members` (r:0 w:1) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Elections Members (r:1 w:1) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Elections RunnersUp (r:1 w:1) + /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:1 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Members (r:0 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) fn remove_member_with_replacement() -> Weight { // Proof Size summary in bytes: - // Measured: `1933` + // Measured: `1900` // Estimated: `3593` - // Minimum execution time: 45_333_000 picoseconds. - Weight::from_parts(46_523_000, 3593) + // Minimum execution time: 57_289_000 picoseconds. + Weight::from_parts(58_328_000, 3593) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: `Elections::Voting` (r:257 w:256) - /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Members` (r:1 w:0) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::RunnersUp` (r:1 w:0) - /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Candidates` (r:1 w:0) - /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Locks` (r:256 w:256) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:256 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:256 w:256) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Elections Voting (r:513 w:512) + /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Elections Members (r:1 w:0) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections RunnersUp (r:1 w:0) + /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Candidates (r:1 w:0) + /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Balances Locks (r:512 w:512) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:512 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: System Account (r:512 w:512) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `v` is `[256, 512]`. /// The range of component `d` is `[0, 256]`. - fn clean_defunct_voters(v: u32, d: u32, ) -> Weight { + fn clean_defunct_voters(v: u32, _d: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0 + d * (818 ±0) + v * (57 ±0)` - // Estimated: `24906 + d * (3774 ±1) + v * (24 ±0)` - // Minimum execution time: 5_620_000 picoseconds. - Weight::from_parts(5_817_000, 24906) - // Standard Error: 18_357 - .saturating_add(Weight::from_parts(106_164, 0).saturating_mul(v.into())) - // Standard Error: 39_980 - .saturating_add(Weight::from_parts(52_456_337, 0).saturating_mul(d.into())) + // Measured: `1149 + v * (811 ±0)` + // Estimated: `4621 + v * (3774 ±0)` + // Minimum execution time: 18_774_231_000 picoseconds. + Weight::from_parts(18_933_040_000, 4621) + // Standard Error: 301_534 + .saturating_add(Weight::from_parts(44_306_903, 0).saturating_mul(v.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().reads((4_u64).saturating_mul(d.into()))) - .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(d.into()))) - .saturating_add(Weight::from_parts(0, 3774).saturating_mul(d.into())) - .saturating_add(Weight::from_parts(0, 24).saturating_mul(v.into())) + .saturating_add(RocksDbWeight::get().reads((4_u64).saturating_mul(v.into()))) + .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(v.into()))) + .saturating_add(Weight::from_parts(0, 3774).saturating_mul(v.into())) } - /// Storage: `Elections::Candidates` (r:1 w:1) - /// Proof: `Elections::Candidates` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Members` (r:1 w:1) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::RunnersUp` (r:1 w:1) - /// Proof: `Elections::RunnersUp` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Voting` (r:513 w:0) - /// Proof: `Elections::Voting` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Council::Proposals` (r:1 w:0) - /// Proof: `Council::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:44 w:44) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Elections::ElectionRounds` (r:1 w:1) - /// Proof: `Elections::ElectionRounds` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Members` (r:0 w:1) - /// Proof: `Council::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Council::Prime` (r:0 w:1) - /// Proof: `Council::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Elections Candidates (r:1 w:1) + /// Proof Skipped: Elections Candidates (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Members (r:1 w:1) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections RunnersUp (r:1 w:1) + /// Proof Skipped: Elections RunnersUp (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Elections Voting (r:513 w:0) + /// Proof Skipped: Elections Voting (max_values: None, max_size: None, mode: Measured) + /// Storage: Council Proposals (r:1 w:0) + /// Proof Skipped: Council Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:44 w:44) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Elections ElectionRounds (r:1 w:1) + /// Proof Skipped: Elections ElectionRounds (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Members (r:0 w:1) + /// Proof Skipped: Council Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Council Prime (r:0 w:1) + /// Proof Skipped: Council Prime (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `c` is `[1, 64]`. /// The range of component `v` is `[1, 512]`. /// The range of component `e` is `[512, 8192]`. fn election_phragmen(c: u32, v: u32, e: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + e * (28 ±0) + v * (606 ±0)` - // Estimated: `178920 + c * (2135 ±7) + e * (12 ±0) + v * (2653 ±6)` - // Minimum execution time: 1_082_582_000 picoseconds. - Weight::from_parts(1_084_730_000, 178920) - // Standard Error: 594_096 - .saturating_add(Weight::from_parts(19_096_288, 0).saturating_mul(v.into())) - // Standard Error: 38_118 - .saturating_add(Weight::from_parts(792_945, 0).saturating_mul(e.into())) + // Estimated: `178887 + c * (2135 ±7) + e * (12 ±0) + v * (2653 ±6)` + // Minimum execution time: 1_281_877_000 picoseconds. + Weight::from_parts(1_288_147_000, 178887) + // Standard Error: 528_851 + .saturating_add(Weight::from_parts(17_761_407, 0).saturating_mul(v.into())) + // Standard Error: 33_932 + .saturating_add(Weight::from_parts(698_277, 0).saturating_mul(e.into())) .saturating_add(RocksDbWeight::get().reads(21_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(c.into()))) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(v.into()))) diff --git a/substrate/frame/examples/basic/src/lib.rs b/substrate/frame/examples/basic/src/lib.rs index 94b2f276e00..12cadc969fd 100644 --- a/substrate/frame/examples/basic/src/lib.rs +++ b/substrate/frame/examples/basic/src/lib.rs @@ -46,10 +46,9 @@ //! use the [`Config::WeightInfo`] trait to calculate call weights. This can also be overridden, //! as demonstrated by [`Call::set_dummy`]. //! - A private function that performs a storage update. -//! - A simple transaction extension implementation (see: -//! [`sp_runtime::traits::TransactionExtension`]) which increases the priority of the -//! [`Call::set_dummy`] if it's present and drops any transaction with an encoded length higher -//! than 200 bytes. +//! - A simple signed extension implementation (see: [`sp_runtime::traits::SignedExtension`]) which +//! increases the priority of the [`Call::set_dummy`] if it's present and drops any transaction +//! with an encoded length higher than 200 bytes. // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] @@ -65,12 +64,10 @@ use frame_system::ensure_signed; use log::info; use scale_info::TypeInfo; use sp_runtime::{ - impl_tx_ext_default, - traits::{ - Bounded, DispatchInfoOf, OriginOf, SaturatedConversion, Saturating, TransactionExtension, - TransactionExtensionBase, ValidateResult, + traits::{Bounded, DispatchInfoOf, SaturatedConversion, Saturating, SignedExtension}, + transaction_validity::{ + InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction, }, - transaction_validity::{InvalidTransaction, ValidTransaction}, }; use sp_std::vec::Vec; @@ -443,8 +440,8 @@ impl Pallet { // Similar to other FRAME pallets, your pallet can also define a signed extension and perform some // checks and [pre/post]processing [before/after] the transaction. A signed extension can be any -// decodable type that implements `TransactionExtension`. See the trait definition for the full list -// of bounds. As a convention, you can follow this approach to create an extension for your pallet: +// decodable type that implements `SignedExtension`. See the trait definition for the full list of +// bounds. As a convention, you can follow this approach to create an extension for your pallet: // - If the extension does not carry any data, then use a tuple struct with just a `marker` // (needed for the compiler to accept `T: Config`) will suffice. // - Otherwise, create a tuple struct which contains the external data. Of course, for the entire @@ -458,18 +455,18 @@ impl Pallet { // // Using the extension, you can add some hooks to the life cycle of each transaction. Note that by // default, an extension is applied to all `Call` functions (i.e. all transactions). the `Call` enum -// variant is given to each function of `TransactionExtension`. Hence, you can filter based on -// pallet or a particular call if needed. +// variant is given to each function of `SignedExtension`. Hence, you can filter based on pallet or +// a particular call if needed. // // Some extra information, such as encoded length, some static dispatch info like weight and the // sender of the transaction (if signed) are also provided. // // The full list of hooks that can be added to a signed extension can be found -// [here](https://paritytech.github.io/polkadot-sdk/master/sp_runtime/traits/trait.TransactionExtension.html). +// [here](https://paritytech.github.io/polkadot-sdk/master/sp_runtime/traits/trait.SignedExtension.html). // // The signed extensions are aggregated in the runtime file of a substrate chain. All extensions // should be aggregated in a tuple and passed to the `CheckedExtrinsic` and `UncheckedExtrinsic` -// types defined in the runtime. Lookup `pub type TxExtension = (...)` in `node/runtime` and +// types defined in the runtime. Lookup `pub type SignedExtra = (...)` in `node/runtime` and // `node-template` for an example of this. /// A simple signed extension that checks for the `set_dummy` call. In that case, it increases the @@ -487,45 +484,52 @@ impl core::fmt::Debug for WatchDummy { } } -impl TransactionExtensionBase for WatchDummy { - const IDENTIFIER: &'static str = "WatchDummy"; - type Implicit = (); -} -impl - TransactionExtension<::RuntimeCall, Context> for WatchDummy +impl SignedExtension for WatchDummy where ::RuntimeCall: IsSubType>, { + const IDENTIFIER: &'static str = "WatchDummy"; + type AccountId = T::AccountId; + type Call = ::RuntimeCall; + type AdditionalSigned = (); type Pre = (); - type Val = (); + + fn additional_signed(&self) -> core::result::Result<(), TransactionValidityError> { + Ok(()) + } + + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + self.validate(who, call, info, len).map(|_| ()) + } fn validate( &self, - origin: OriginOf<::RuntimeCall>, - call: &::RuntimeCall, - _info: &DispatchInfoOf<::RuntimeCall>, + _who: &Self::AccountId, + call: &Self::Call, + _info: &DispatchInfoOf, len: usize, - _context: &mut Context, - _self_implicit: Self::Implicit, - _inherited_implication: &impl Encode, - ) -> ValidateResult::RuntimeCall> { + ) -> TransactionValidity { // if the transaction is too big, just drop it. if len > 200 { - return Err(InvalidTransaction::ExhaustsResources.into()) + return InvalidTransaction::ExhaustsResources.into() } // check for `set_dummy` - let validity = match call.is_sub_type() { + match call.is_sub_type() { Some(Call::set_dummy { .. }) => { sp_runtime::print("set_dummy was received."); let valid_tx = ValidTransaction { priority: Bounded::max_value(), ..Default::default() }; - valid_tx + Ok(valid_tx) }, - _ => Default::default(), - }; - Ok((validity, (), origin)) + _ => Ok(Default::default()), + } } - impl_tx_ext_default!(::RuntimeCall; Context; prepare); } diff --git a/substrate/frame/examples/basic/src/tests.rs b/substrate/frame/examples/basic/src/tests.rs index e460ad0992f..207e46e428d 100644 --- a/substrate/frame/examples/basic/src/tests.rs +++ b/substrate/frame/examples/basic/src/tests.rs @@ -27,7 +27,7 @@ use sp_core::H256; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sp_runtime::{ - traits::{BlakeTwo256, DispatchTransaction, IdentityLookup}, + traits::{BlakeTwo256, IdentityLookup}, BuildStorage, }; // Reexport crate as its pallet name for construct_runtime. @@ -158,16 +158,13 @@ fn signed_ext_watch_dummy_works() { assert_eq!( WatchDummy::(PhantomData) - .validate_only(Some(1).into(), &call, &info, 150) + .validate(&1, &call, &info, 150) .unwrap() - .0 .priority, u64::MAX, ); assert_eq!( - WatchDummy::(PhantomData) - .validate_only(Some(1).into(), &call, &info, 250) - .unwrap_err(), + WatchDummy::(PhantomData).validate(&1, &call, &info, 250), InvalidTransaction::ExhaustsResources.into(), ); }) diff --git a/substrate/frame/examples/offchain-worker/src/tests.rs b/substrate/frame/examples/offchain-worker/src/tests.rs index 81f2a40840b..ea37a2da493 100644 --- a/substrate/frame/examples/offchain-worker/src/tests.rs +++ b/substrate/frame/examples/offchain-worker/src/tests.rs @@ -30,7 +30,7 @@ use sp_core::{ use sp_keystore::{testing::MemoryKeystore, Keystore, KeystoreExt}; use sp_runtime::{ - generic::UncheckedExtrinsic, + testing::TestXt, traits::{BlakeTwo256, Extrinsic as ExtrinsicT, IdentifyAccount, IdentityLookup, Verify}, RuntimeAppPublic, }; @@ -73,7 +73,7 @@ impl frame_system::Config for Test { type MaxConsumers = ConstU32<16>; } -type Extrinsic = UncheckedExtrinsic; +type Extrinsic = TestXt; type AccountId = <::Signer as IdentifyAccount>::AccountId; impl frame_system::offchain::SigningTypes for Test { @@ -99,7 +99,7 @@ where _account: AccountId, nonce: u64, ) -> Option<(RuntimeCall, ::SignaturePayload)> { - Some((call, (nonce, (), ()))) + Some((call, (nonce, ()))) } } @@ -219,8 +219,8 @@ fn should_submit_signed_transaction_on_chain() { let tx = pool_state.write().transactions.pop().unwrap(); assert!(pool_state.read().transactions.is_empty()); let tx = Extrinsic::decode(&mut &*tx).unwrap(); - assert!(matches!(tx.preamble, sp_runtime::generic::Preamble::Signed(0, (), ()))); - assert_eq!(tx.function, RuntimeCall::Example(crate::Call::submit_price { price: 15523 })); + assert_eq!(tx.signature.unwrap().0, 0); + assert_eq!(tx.call, RuntimeCall::Example(crate::Call::submit_price { price: 15523 })); }); } @@ -259,11 +259,11 @@ fn should_submit_unsigned_transaction_on_chain_for_any_account() { // then let tx = pool_state.write().transactions.pop().unwrap(); let tx = Extrinsic::decode(&mut &*tx).unwrap(); - assert!(tx.is_inherent()); + assert_eq!(tx.signature, None); if let RuntimeCall::Example(crate::Call::submit_price_unsigned_with_signed_payload { price_payload: body, signature, - }) = tx.function + }) = tx.call { assert_eq!(body, price_payload); @@ -313,11 +313,11 @@ fn should_submit_unsigned_transaction_on_chain_for_all_accounts() { // then let tx = pool_state.write().transactions.pop().unwrap(); let tx = Extrinsic::decode(&mut &*tx).unwrap(); - assert!(tx.is_inherent()); + assert_eq!(tx.signature, None); if let RuntimeCall::Example(crate::Call::submit_price_unsigned_with_signed_payload { price_payload: body, signature, - }) = tx.function + }) = tx.call { assert_eq!(body, price_payload); @@ -353,9 +353,9 @@ fn should_submit_raw_unsigned_transaction_on_chain() { let tx = pool_state.write().transactions.pop().unwrap(); assert!(pool_state.read().transactions.is_empty()); let tx = Extrinsic::decode(&mut &*tx).unwrap(); - assert!(tx.is_inherent()); + assert_eq!(tx.signature, None); assert_eq!( - tx.function, + tx.call, RuntimeCall::Example(crate::Call::submit_price_unsigned { block_number: 1, price: 15523 diff --git a/substrate/frame/examples/tasks/src/weights.rs b/substrate/frame/examples/tasks/src/weights.rs index c9ddea6f9a8..793af6e9622 100644 --- a/substrate/frame/examples/tasks/src/weights.rs +++ b/substrate/frame/examples/tasks/src/weights.rs @@ -15,31 +15,30 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `tasks_example` +//! Autogenerated weights for `pallet_example_tasks` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-02, STEPS: `20`, REPEAT: `10`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `MacBook.local`, CPU: `` +//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/release/node-template // benchmark // pallet -// --chain=dev -// --steps=50 -// --repeat=20 -// --pallet=tasks_example -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --wasm-execution=compiled -// --heap-pages=4096 -// --output=./substrate/frame/examples/tasks/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --chain +// dev +// --pallet +// pallet_example_tasks +// --extrinsic +// * +// --steps +// 20 +// --repeat +// 10 +// --output +// frame/examples/tasks/src/weights.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,42 +48,37 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `tasks_example`. +/// Weight functions needed for pallet_template. pub trait WeightInfo { fn add_number_into_total() -> Weight; } -/// Weights for `tasks_example` using the Substrate node and recommended hardware. +/// Weight functions for `pallet_example_kitchensink`. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `TasksExample::Numbers` (r:1 w:1) - /// Proof: `TasksExample::Numbers` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `TasksExample::Total` (r:1 w:1) - /// Proof: `TasksExample::Total` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Kitchensink OtherFoo (r:0 w:1) + /// Proof Skipped: Kitchensink OtherFoo (max_values: Some(1), max_size: None, mode: Measured) fn add_number_into_total() -> Weight { // Proof Size summary in bytes: - // Measured: `149` - // Estimated: `3614` - // Minimum execution time: 5_776_000 picoseconds. - Weight::from_parts(6_178_000, 3614) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_000_000 picoseconds. + Weight::from_parts(1_000_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) } } -// For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: `TasksExample::Numbers` (r:1 w:1) - /// Proof: `TasksExample::Numbers` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `TasksExample::Total` (r:1 w:1) - /// Proof: `TasksExample::Total` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: Kitchensink OtherFoo (r:0 w:1) + /// Proof Skipped: Kitchensink OtherFoo (max_values: Some(1), max_size: None, mode: Measured) fn add_number_into_total() -> Weight { // Proof Size summary in bytes: - // Measured: `149` - // Estimated: `3614` - // Minimum execution time: 5_776_000 picoseconds. - Weight::from_parts(6_178_000, 3614) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_000_000 picoseconds. + Weight::from_parts(1_000_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(RocksDbWeight::get().writes(1)) } } diff --git a/substrate/frame/executive/src/tests.rs b/substrate/frame/executive/src/tests.rs index a3f70a9fc3c..70b55f6e855 100644 --- a/substrate/frame/executive/src/tests.rs +++ b/substrate/frame/executive/src/tests.rs @@ -327,42 +327,10 @@ impl frame_system::Config for Runtime { type Balance = u64; -pub struct BalancesWeights; -impl pallet_balances::WeightInfo for BalancesWeights { - fn transfer_allow_death() -> Weight { - Weight::from_parts(25, 0) - } - fn transfer_keep_alive() -> Weight { - Weight::zero() - } - fn force_set_balance_creating() -> Weight { - Weight::zero() - } - fn force_set_balance_killing() -> Weight { - Weight::zero() - } - fn force_transfer() -> Weight { - Weight::zero() - } - fn transfer_all() -> Weight { - Weight::zero() - } - fn force_unreserve() -> Weight { - Weight::zero() - } - fn upgrade_accounts(_u: u32) -> Weight { - Weight::zero() - } - fn force_adjust_total_issuance() -> Weight { - Weight::zero() - } -} - #[derive_impl(pallet_balances::config_preludes::TestDefaultConfig as pallet_balances::DefaultConfig)] impl pallet_balances::Config for Runtime { type Balance = Balance; type AccountStore = System; - type WeightInfo = BalancesWeights; } parameter_types! { @@ -375,7 +343,6 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = IdentityFee; type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = (); - type WeightInfo = (); } impl custom::Config for Runtime {} @@ -388,46 +355,19 @@ impl frame_support::traits::Get for RuntimeVersion { } } -#[derive(Clone, Debug, Encode, codec::Decode, PartialEq, Eq, scale_info::TypeInfo)] -pub struct AccountU64(u64); -impl sp_runtime::traits::IdentifyAccount for AccountU64 { - type AccountId = u64; - fn into_account(self) -> u64 { - self.0 - } -} - -impl sp_runtime::traits::Verify for AccountU64 { - type Signer = AccountU64; - fn verify>( - &self, - _msg: L, - _signer: &::AccountId, - ) -> bool { - true - } -} - -impl From for AccountU64 { - fn from(value: u64) -> Self { - Self(value) - } -} - parameter_types! { pub static RuntimeVersionTestValues: sp_version::RuntimeVersion = Default::default(); } -type TxExtension = ( +type SignedExtra = ( frame_system::CheckEra, frame_system::CheckNonce, frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, ); -type UncheckedXt = - sp_runtime::generic::UncheckedExtrinsic; -type TestBlock = Block; +type TestXt = sp_runtime::testing::TestXt; +type TestBlock = Block; // Will contain `true` when the custom runtime logic was called. const CUSTOM_ON_RUNTIME_KEY: &[u8] = b":custom:on_runtime"; @@ -447,7 +387,7 @@ impl OnRuntimeUpgrade for CustomOnRuntimeUpgrade { type Executive = super::Executive< Runtime, - Block, + Block, ChainContext, Runtime, AllPalletsWithSystem, @@ -522,14 +462,17 @@ impl MultiStepMigrator for MockedModeGetter { } } -fn tx_ext(nonce: u64, fee: Balance) -> TxExtension { +fn extra(nonce: u64, fee: Balance) -> SignedExtra { ( frame_system::CheckEra::from(Era::Immortal), frame_system::CheckNonce::from(nonce), frame_system::CheckWeight::new(), pallet_transaction_payment::ChargeTransactionPayment::from(fee), ) - .into() +} + +fn sign_extra(who: u64, nonce: u64, fee: Balance) -> Option<(u64, SignedExtra)> { + Some((who, extra(nonce, fee))) } fn call_transfer(dest: u64, value: u64) -> RuntimeCall { @@ -542,7 +485,7 @@ fn balance_transfer_dispatch_works() { pallet_balances::GenesisConfig:: { balances: vec![(1, 211)] } .assimilate_storage(&mut t) .unwrap(); - let xt = UncheckedXt::new_signed(call_transfer(2, 69), 1, 1.into(), tx_ext(0, 0)); + let xt = TestXt::new(call_transfer(2, 69), sign_extra(1, 0, 0)); let weight = xt.get_dispatch_info().weight + ::BlockWeights::get() .get(DispatchClass::Normal) @@ -653,7 +596,7 @@ fn block_import_of_bad_extrinsic_root_fails() { fn bad_extrinsic_not_inserted() { let mut t = new_test_ext(1); // bad nonce check! - let xt = UncheckedXt::new_signed(call_transfer(33, 69), 1, 1.into(), tx_ext(30, 0)); + let xt = TestXt::new(call_transfer(33, 69), sign_extra(1, 30, 0)); t.execute_with(|| { Executive::initialize_block(&Header::new_from_number(1)); assert_err!( @@ -667,24 +610,27 @@ fn bad_extrinsic_not_inserted() { #[test] fn block_weight_limit_enforced() { let mut t = new_test_ext(10000); - let transfer_weight = - <::WeightInfo as pallet_balances::WeightInfo>::transfer_allow_death(); + // given: TestXt uses the encoded len as fixed Len: + let xt = TestXt::new( + RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), + sign_extra(1, 0, 0), + ); + let encoded = xt.encode(); + let encoded_len = encoded.len() as u64; // on_initialize weight + base block execution weight let block_weights = ::BlockWeights::get(); let base_block_weight = Weight::from_parts(175, 0) + block_weights.base_block; let limit = block_weights.get(DispatchClass::Normal).max_total.unwrap() - base_block_weight; - let num_to_exhaust_block = limit.ref_time() / (transfer_weight.ref_time() + 5); + let num_to_exhaust_block = limit.ref_time() / (encoded_len + 5); t.execute_with(|| { Executive::initialize_block(&Header::new_from_number(1)); // Base block execution weight + `on_initialize` weight from the custom module. assert_eq!(>::block_weight().total(), base_block_weight); for nonce in 0..=num_to_exhaust_block { - let xt = UncheckedXt::new_signed( + let xt = TestXt::new( RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - 1, - 1.into(), - tx_ext(nonce.into(), 0), + sign_extra(1, nonce.into(), 0), ); let res = Executive::apply_extrinsic(xt); if nonce != num_to_exhaust_block { @@ -692,8 +638,7 @@ fn block_weight_limit_enforced() { assert_eq!( >::block_weight().total(), //--------------------- on_initialize + block_execution + extrinsic_base weight - Weight::from_parts((transfer_weight.ref_time() + 5) * (nonce + 1), 0) + - base_block_weight, + Weight::from_parts((encoded_len + 5) * (nonce + 1), 0) + base_block_weight, ); assert_eq!( >::extrinsic_index(), @@ -708,26 +653,19 @@ fn block_weight_limit_enforced() { #[test] fn block_weight_and_size_is_stored_per_tx() { - let xt = UncheckedXt::new_signed( + let xt = TestXt::new( RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - 1, - 1.into(), - tx_ext(0, 0), + sign_extra(1, 0, 0), ); - let x1 = UncheckedXt::new_signed( + let x1 = TestXt::new( RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - 1, - 1.into(), - tx_ext(1, 0), + sign_extra(1, 1, 0), ); - let x2 = UncheckedXt::new_signed( + let x2 = TestXt::new( RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - 1, - 1.into(), - tx_ext(2, 0), + sign_extra(1, 2, 0), ); let len = xt.clone().encode().len() as u32; - let transfer_weight = <::WeightInfo as pallet_balances::WeightInfo>::transfer_allow_death(); let mut t = new_test_ext(1); t.execute_with(|| { // Block execution weight + on_initialize weight from custom module @@ -743,7 +681,8 @@ fn block_weight_and_size_is_stored_per_tx() { assert!(Executive::apply_extrinsic(x1.clone()).unwrap().is_ok()); assert!(Executive::apply_extrinsic(x2.clone()).unwrap().is_ok()); - let extrinsic_weight = transfer_weight + + // default weight for `TestXt` == encoded length. + let extrinsic_weight = Weight::from_parts(len as u64, 0) + ::BlockWeights::get() .get(DispatchClass::Normal) .base_extrinsic; @@ -768,8 +707,8 @@ fn block_weight_and_size_is_stored_per_tx() { #[test] fn validate_unsigned() { - let valid = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::allowed_unsigned {})); - let invalid = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::unallowed_unsigned {})); + let valid = TestXt::new(RuntimeCall::Custom(custom::Call::allowed_unsigned {}), None); + let invalid = TestXt::new(RuntimeCall::Custom(custom::Call::unallowed_unsigned {}), None); let mut t = new_test_ext(1); t.execute_with(|| { @@ -806,11 +745,9 @@ fn can_not_pay_for_tx_fee_on_full_lock() { t.execute_with(|| { as fungible::MutateFreeze>::set_freeze(&(), &1, 110) .unwrap(); - let xt = UncheckedXt::new_signed( + let xt = TestXt::new( RuntimeCall::System(frame_system::Call::remark { remark: vec![1u8] }), - 1, - 1.into(), - tx_ext(0, 0), + sign_extra(1, 0, 0), ); Executive::initialize_block(&Header::new_from_number(1)); @@ -935,11 +872,9 @@ fn event_from_runtime_upgrade_is_included() { /// used through the `ExecuteBlock` trait. #[test] fn custom_runtime_upgrade_is_called_when_using_execute_block_trait() { - let xt = UncheckedXt::new_signed( + let xt = TestXt::new( RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - 1, - 1.into(), - tx_ext(0, 0), + sign_extra(1, 0, 0), ); let header = new_test_ext(1).execute_with(|| { @@ -967,10 +902,7 @@ fn custom_runtime_upgrade_is_called_when_using_execute_block_trait() { *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } }); - >>::execute_block(Block::new( - header, - vec![xt], - )); + >>::execute_block(Block::new(header, vec![xt])); assert_eq!(&sp_io::storage::get(TEST_KEY).unwrap()[..], *b"module"); assert_eq!(sp_io::storage::get(CUSTOM_ON_RUNTIME_KEY).unwrap(), true.encode()); @@ -1036,7 +968,7 @@ fn offchain_worker_works_as_expected() { #[test] fn calculating_storage_root_twice_works() { let call = RuntimeCall::Custom(custom::Call::calculate_storage_root {}); - let xt = UncheckedXt::new_signed(call, 1, 1.into(), tx_ext(0, 0)); + let xt = TestXt::new(call, sign_extra(1, 0, 0)); let header = new_test_ext(1).execute_with(|| { // Let's build some fake block. @@ -1055,13 +987,11 @@ fn calculating_storage_root_twice_works() { #[test] #[should_panic(expected = "Invalid inherent position for extrinsic at index 1")] fn invalid_inherent_position_fail() { - let xt1 = UncheckedXt::new_signed( + let xt1 = TestXt::new( RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - 1, - 1.into(), - tx_ext(0, 0), + sign_extra(1, 0, 0), ); - let xt2 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})); + let xt2 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); let header = new_test_ext(1).execute_with(|| { // Let's build some fake block. @@ -1080,8 +1010,8 @@ fn invalid_inherent_position_fail() { #[test] fn valid_inherents_position_works() { - let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})); - let xt2 = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0)); + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); let header = new_test_ext(1).execute_with(|| { // Let's build some fake block. @@ -1101,12 +1031,7 @@ fn valid_inherents_position_works() { #[test] #[should_panic(expected = "A call was labelled as mandatory, but resulted in an Error.")] fn invalid_inherents_fail_block_execution() { - let xt1 = UncheckedXt::new_signed( - RuntimeCall::Custom(custom::Call::inherent {}), - 1, - 1.into(), - tx_ext(0, 0), - ); + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), sign_extra(1, 0, 0)); new_test_ext(1).execute_with(|| { Executive::execute_block(Block::new( @@ -1119,7 +1044,7 @@ fn invalid_inherents_fail_block_execution() { // Inherents are created by the runtime and don't need to be validated. #[test] fn inherents_fail_validate_block() { - let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})); + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); new_test_ext(1).execute_with(|| { assert_eq!( @@ -1133,7 +1058,7 @@ fn inherents_fail_validate_block() { /// Inherents still work while `initialize_block` forbids transactions. #[test] fn inherents_ok_while_exts_forbidden_works() { - let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})); + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); let header = new_test_ext(1).execute_with(|| { Executive::initialize_block(&Header::new_from_number(1)); @@ -1153,8 +1078,8 @@ fn inherents_ok_while_exts_forbidden_works() { #[test] #[should_panic = "Only inherents are allowed in this block"] fn transactions_in_only_inherents_block_errors() { - let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})); - let xt2 = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0)); + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); let header = new_test_ext(1).execute_with(|| { Executive::initialize_block(&Header::new_from_number(1)); @@ -1174,8 +1099,8 @@ fn transactions_in_only_inherents_block_errors() { /// Same as above but no error. #[test] fn transactions_in_normal_block_works() { - let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})); - let xt2 = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0)); + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); let header = new_test_ext(1).execute_with(|| { Executive::initialize_block(&Header::new_from_number(1)); @@ -1195,8 +1120,8 @@ fn transactions_in_normal_block_works() { #[test] #[cfg(feature = "try-runtime")] fn try_execute_block_works() { - let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})); - let xt2 = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0)); + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); let header = new_test_ext(1).execute_with(|| { Executive::initialize_block(&Header::new_from_number(1)); @@ -1223,8 +1148,8 @@ fn try_execute_block_works() { #[cfg(feature = "try-runtime")] #[should_panic = "Only inherents allowed"] fn try_execute_tx_forbidden_errors() { - let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})); - let xt2 = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0)); + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); let header = new_test_ext(1).execute_with(|| { // Let's build some fake block. @@ -1251,9 +1176,9 @@ fn try_execute_tx_forbidden_errors() { /// Check that `ensure_inherents_are_first` reports the correct indices. #[test] fn ensure_inherents_are_first_works() { - let in1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})); - let in2 = UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::inherent {})); - let xt2 = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0)); + let in1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let in2 = TestXt::new(RuntimeCall::Custom2(custom2::Call::inherent {}), None); + let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); // Mocked empty header: let header = new_test_ext(1).execute_with(|| { @@ -1331,20 +1256,18 @@ fn callbacks_in_block_execution_works_inner(mbms_active: bool) { for i in 0..n_in { let xt = if i % 2 == 0 { - UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {})) + TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None) } else { - UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::optional_inherent {})) + TestXt::new(RuntimeCall::Custom2(custom2::Call::optional_inherent {}), None) }; Executive::apply_extrinsic(xt.clone()).unwrap().unwrap(); extrinsics.push(xt); } for t in 0..n_tx { - let xt = UncheckedXt::new_signed( + let xt = TestXt::new( RuntimeCall::Custom2(custom2::Call::some_call {}), - 1, - 1.into(), - tx_ext(t as u64, 0), + sign_extra(1, t as u64, 0), ); // Extrinsics can be applied even when MBMs are active. Only the `execute_block` // will reject it. @@ -1384,13 +1307,8 @@ fn callbacks_in_block_execution_works_inner(mbms_active: bool) { #[test] fn post_inherent_called_after_all_inherents() { - let in1 = UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::inherent {})); - let xt1 = UncheckedXt::new_signed( - RuntimeCall::Custom2(custom2::Call::some_call {}), - 1, - 1.into(), - tx_ext(0, 0), - ); + let in1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::inherent {}), None); + let xt1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::some_call {}), sign_extra(1, 0, 0)); let header = new_test_ext(1).execute_with(|| { // Let's build some fake block. @@ -1424,13 +1342,8 @@ fn post_inherent_called_after_all_inherents() { /// Regression test for AppSec finding #40. #[test] fn post_inherent_called_after_all_optional_inherents() { - let in1 = UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::optional_inherent {})); - let xt1 = UncheckedXt::new_signed( - RuntimeCall::Custom2(custom2::Call::some_call {}), - 1, - 1.into(), - tx_ext(0, 0), - ); + let in1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::optional_inherent {}), None); + let xt1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::some_call {}), sign_extra(1, 0, 0)); let header = new_test_ext(1).execute_with(|| { // Let's build some fake block. @@ -1463,14 +1376,14 @@ fn post_inherent_called_after_all_optional_inherents() { #[test] fn is_inherent_works() { - let ext = UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::inherent {})); + let ext = TestXt::new(RuntimeCall::Custom2(custom2::Call::inherent {}), None); assert!(Runtime::is_inherent(&ext)); - let ext = UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::optional_inherent {})); + let ext = TestXt::new(RuntimeCall::Custom2(custom2::Call::optional_inherent {}), None); assert!(Runtime::is_inherent(&ext)); - let ext = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0)); + let ext = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); assert!(!Runtime::is_inherent(&ext)); - let ext = UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::allowed_unsigned {})); + let ext = TestXt::new(RuntimeCall::Custom2(custom2::Call::allowed_unsigned {}), None); assert!(!Runtime::is_inherent(&ext), "Unsigned ext are not automatically inherents"); } diff --git a/substrate/frame/fast-unstake/src/weights.rs b/substrate/frame/fast-unstake/src/weights.rs index d783ba921bf..9c25a409f74 100644 --- a/substrate/frame/fast-unstake/src/weights.rs +++ b/substrate/frame/fast-unstake/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_fast_unstake` +//! Autogenerated weights for pallet_fast_unstake //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/fast-unstake/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/fast-unstake/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_fast_unstake`. +/// Weight functions needed for pallet_fast_unstake. pub trait WeightInfo { fn on_idle_unstake(b: u32, ) -> Weight; fn on_idle_check(v: u32, b: u32, ) -> Weight; @@ -58,305 +59,301 @@ pub trait WeightInfo { fn control() -> Weight; } -/// Weights for `pallet_fast_unstake` using the Substrate node and recommended hardware. +/// Weights for pallet_fast_unstake using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0) - /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::ValidatorCount` (r:1 w:0) - /// Proof: `Staking::ValidatorCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::Head` (r:1 w:1) - /// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::CounterForQueue` (r:1 w:0) - /// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Staking::CurrentEra` (r:1 w:0) - /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::SlashingSpans` (r:64 w:0) - /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Staking::Bonded` (r:64 w:64) - /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::Ledger` (r:64 w:64) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:64 w:64) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:64 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:64 w:64) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Staking::Validators` (r:64 w:0) - /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) - /// Storage: `Staking::Nominators` (r:64 w:0) - /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) - /// Storage: `Staking::Payee` (r:0 w:64) - /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ValidatorCount (r:1 w:0) + /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:1) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(5768), added: 6263, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:0) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:64 w:0) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking Bonded (r:64 w:64) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:64 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:64 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: System Account (r:64 w:64) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:64 w:64) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:64 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:0 w:64) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:64) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) /// The range of component `b` is `[1, 64]`. fn on_idle_unstake(b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1475 + b * (452 ±0)` + // Measured: `1378 + b * (343 ±0)` // Estimated: `7253 + b * (3774 ±0)` - // Minimum execution time: 89_005_000 picoseconds. - Weight::from_parts(50_257_055, 7253) - // Standard Error: 68_836 - .saturating_add(Weight::from_parts(57_329_950, 0).saturating_mul(b.into())) + // Minimum execution time: 92_847_000 picoseconds. + Weight::from_parts(42_300_813, 7253) + // Standard Error: 40_514 + .saturating_add(Weight::from_parts(58_412_402, 0).saturating_mul(b.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) - .saturating_add(T::DbWeight::get().reads((8_u64).saturating_mul(b.into()))) + .saturating_add(T::DbWeight::get().reads((7_u64).saturating_mul(b.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(T::DbWeight::get().writes((5_u64).saturating_mul(b.into()))) .saturating_add(Weight::from_parts(0, 3774).saturating_mul(b.into())) } - /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0) - /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::ValidatorCount` (r:1 w:0) - /// Proof: `Staking::ValidatorCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::Head` (r:1 w:1) - /// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::CounterForQueue` (r:1 w:0) - /// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Staking::CurrentEra` (r:1 w:0) - /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::ErasStakers` (r:1 w:0) - /// Proof: `Staking::ErasStakers` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Staking::ErasStakersPaged` (r:257 w:0) - /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ValidatorCount (r:1 w:0) + /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:1) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(5768), added: 6263, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:0) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ErasStakers (r:257 w:0) + /// Proof Skipped: Staking ErasStakers (max_values: None, max_size: None, mode: Measured) /// The range of component `v` is `[1, 256]`. /// The range of component `b` is `[1, 64]`. fn on_idle_check(v: u32, b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1879 + b * (55 ±0) + v * (10055 ±0)` - // Estimated: `7253 + b * (56 ±0) + v * (12531 ±0)` - // Minimum execution time: 1_737_131_000 picoseconds. - Weight::from_parts(1_746_770_000, 7253) - // Standard Error: 13_401_143 - .saturating_add(Weight::from_parts(426_946_450, 0).saturating_mul(v.into())) - // Standard Error: 53_619_501 - .saturating_add(Weight::from_parts(1_664_681_508, 0).saturating_mul(b.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `1546 + b * (48 ±0) + v * (10037 ±0)` + // Estimated: `7253 + b * (49 ±0) + v * (12513 ±0)` + // Minimum execution time: 1_685_784_000 picoseconds. + Weight::from_parts(1_693_370_000, 7253) + // Standard Error: 13_295_842 + .saturating_add(Weight::from_parts(425_349_148, 0).saturating_mul(v.into())) + // Standard Error: 53_198_180 + .saturating_add(Weight::from_parts(1_673_328_444, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) - .saturating_add(Weight::from_parts(0, 56).saturating_mul(b.into())) - .saturating_add(Weight::from_parts(0, 12531).saturating_mul(v.into())) + .saturating_add(Weight::from_parts(0, 49).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 12513).saturating_mul(v.into())) } - /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0) - /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::Ledger` (r:1 w:1) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::Queue` (r:1 w:1) - /// Proof: `FastUnstake::Queue` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::Head` (r:1 w:0) - /// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`) - /// Storage: `Staking::Bonded` (r:1 w:0) - /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::Validators` (r:1 w:0) - /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) - /// Storage: `Staking::Nominators` (r:1 w:1) - /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) - /// Storage: `Staking::CounterForNominators` (r:1 w:1) - /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:1 w:1) - /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:1 w:1) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) - /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) - /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::CurrentEra` (r:1 w:0) - /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::CounterForQueue` (r:1 w:1) - /// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: FastUnstake Queue (r:1 w:1) + /// Proof: FastUnstake Queue (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:0) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(5768), added: 6263, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:1 w:1) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:1) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) fn register_fast_unstake() -> Weight { // Proof Size summary in bytes: - // Measured: `1955` + // Measured: `1964` // Estimated: `7253` - // Minimum execution time: 112_632_000 picoseconds. - Weight::from_parts(117_267_000, 7253) + // Minimum execution time: 125_512_000 picoseconds. + Weight::from_parts(129_562_000, 7253) .saturating_add(T::DbWeight::get().reads(15_u64)) .saturating_add(T::DbWeight::get().writes(9_u64)) } - /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0) - /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::Ledger` (r:1 w:0) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::Queue` (r:1 w:1) - /// Proof: `FastUnstake::Queue` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::Head` (r:1 w:0) - /// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::CounterForQueue` (r:1 w:1) - /// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: FastUnstake Queue (r:1 w:1) + /// Proof: FastUnstake Queue (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:0) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(5768), added: 6263, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:1) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) fn deregister() -> Weight { // Proof Size summary in bytes: - // Measured: `1251` + // Measured: `1223` // Estimated: `7253` - // Minimum execution time: 39_253_000 picoseconds. - Weight::from_parts(40_053_000, 7253) + // Minimum execution time: 43_943_000 picoseconds. + Weight::from_parts(45_842_000, 7253) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:0 w:1) - /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: FastUnstake ErasToCheckPerBlock (r:0 w:1) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) fn control() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_386_000 picoseconds. - Weight::from_parts(2_508_000, 0) + // Minimum execution time: 2_677_000 picoseconds. + Weight::from_parts(2_849_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0) - /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::ValidatorCount` (r:1 w:0) - /// Proof: `Staking::ValidatorCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::Head` (r:1 w:1) - /// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::CounterForQueue` (r:1 w:0) - /// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Staking::CurrentEra` (r:1 w:0) - /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::SlashingSpans` (r:64 w:0) - /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Staking::Bonded` (r:64 w:64) - /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::Ledger` (r:64 w:64) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:64 w:64) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:64 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:64 w:64) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Staking::Validators` (r:64 w:0) - /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) - /// Storage: `Staking::Nominators` (r:64 w:0) - /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) - /// Storage: `Staking::Payee` (r:0 w:64) - /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ValidatorCount (r:1 w:0) + /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:1) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(5768), added: 6263, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:0) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking SlashingSpans (r:64 w:0) + /// Proof Skipped: Staking SlashingSpans (max_values: None, max_size: None, mode: Measured) + /// Storage: Staking Bonded (r:64 w:64) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:64 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:64 w:0) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: System Account (r:64 w:64) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:64 w:64) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:64 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:0 w:64) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Staking Payee (r:0 w:64) + /// Proof: Staking Payee (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) /// The range of component `b` is `[1, 64]`. fn on_idle_unstake(b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1475 + b * (452 ±0)` + // Measured: `1378 + b * (343 ±0)` // Estimated: `7253 + b * (3774 ±0)` - // Minimum execution time: 89_005_000 picoseconds. - Weight::from_parts(50_257_055, 7253) - // Standard Error: 68_836 - .saturating_add(Weight::from_parts(57_329_950, 0).saturating_mul(b.into())) + // Minimum execution time: 92_847_000 picoseconds. + Weight::from_parts(42_300_813, 7253) + // Standard Error: 40_514 + .saturating_add(Weight::from_parts(58_412_402, 0).saturating_mul(b.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) - .saturating_add(RocksDbWeight::get().reads((8_u64).saturating_mul(b.into()))) + .saturating_add(RocksDbWeight::get().reads((7_u64).saturating_mul(b.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(RocksDbWeight::get().writes((5_u64).saturating_mul(b.into()))) .saturating_add(Weight::from_parts(0, 3774).saturating_mul(b.into())) } - /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0) - /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::ValidatorCount` (r:1 w:0) - /// Proof: `Staking::ValidatorCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::Head` (r:1 w:1) - /// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::CounterForQueue` (r:1 w:0) - /// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `ElectionProviderMultiPhase::CurrentPhase` (r:1 w:0) - /// Proof: `ElectionProviderMultiPhase::CurrentPhase` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Staking::CurrentEra` (r:1 w:0) - /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::ErasStakers` (r:1 w:0) - /// Proof: `Staking::ErasStakers` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Staking::ErasStakersPaged` (r:257 w:0) - /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ValidatorCount (r:1 w:0) + /// Proof: Staking ValidatorCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:1) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(5768), added: 6263, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:0) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0) + /// Proof Skipped: ElectionProviderMultiPhase CurrentPhase (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking ErasStakers (r:257 w:0) + /// Proof Skipped: Staking ErasStakers (max_values: None, max_size: None, mode: Measured) /// The range of component `v` is `[1, 256]`. /// The range of component `b` is `[1, 64]`. fn on_idle_check(v: u32, b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1879 + b * (55 ±0) + v * (10055 ±0)` - // Estimated: `7253 + b * (56 ±0) + v * (12531 ±0)` - // Minimum execution time: 1_737_131_000 picoseconds. - Weight::from_parts(1_746_770_000, 7253) - // Standard Error: 13_401_143 - .saturating_add(Weight::from_parts(426_946_450, 0).saturating_mul(v.into())) - // Standard Error: 53_619_501 - .saturating_add(Weight::from_parts(1_664_681_508, 0).saturating_mul(b.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `1546 + b * (48 ±0) + v * (10037 ±0)` + // Estimated: `7253 + b * (49 ±0) + v * (12513 ±0)` + // Minimum execution time: 1_685_784_000 picoseconds. + Weight::from_parts(1_693_370_000, 7253) + // Standard Error: 13_295_842 + .saturating_add(Weight::from_parts(425_349_148, 0).saturating_mul(v.into())) + // Standard Error: 53_198_180 + .saturating_add(Weight::from_parts(1_673_328_444, 0).saturating_mul(b.into())) + .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(v.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) - .saturating_add(Weight::from_parts(0, 56).saturating_mul(b.into())) - .saturating_add(Weight::from_parts(0, 12531).saturating_mul(v.into())) + .saturating_add(Weight::from_parts(0, 49).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 12513).saturating_mul(v.into())) } - /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0) - /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::Ledger` (r:1 w:1) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::Queue` (r:1 w:1) - /// Proof: `FastUnstake::Queue` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::Head` (r:1 w:0) - /// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`) - /// Storage: `Staking::Bonded` (r:1 w:0) - /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::Validators` (r:1 w:0) - /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) - /// Storage: `Staking::Nominators` (r:1 w:1) - /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) - /// Storage: `Staking::CounterForNominators` (r:1 w:1) - /// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListNodes` (r:1 w:1) - /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) - /// Storage: `VoterList::ListBags` (r:1 w:1) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) - /// Storage: `VoterList::CounterForListNodes` (r:1 w:1) - /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::CurrentEra` (r:1 w:0) - /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::CounterForQueue` (r:1 w:1) - /// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:1) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: FastUnstake Queue (r:1 w:1) + /// Proof: FastUnstake Queue (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:0) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(5768), added: 6263, mode: MaxEncodedLen) + /// Storage: Staking Bonded (r:1 w:0) + /// Proof: Staking Bonded (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + /// Storage: Staking Validators (r:1 w:0) + /// Proof: Staking Validators (max_values: None, max_size: Some(45), added: 2520, mode: MaxEncodedLen) + /// Storage: Staking Nominators (r:1 w:1) + /// Proof: Staking Nominators (max_values: None, max_size: Some(558), added: 3033, mode: MaxEncodedLen) + /// Storage: Staking CounterForNominators (r:1 w:1) + /// Proof: Staking CounterForNominators (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: VoterList ListNodes (r:1 w:1) + /// Proof: VoterList ListNodes (max_values: None, max_size: Some(154), added: 2629, mode: MaxEncodedLen) + /// Storage: VoterList ListBags (r:1 w:1) + /// Proof: VoterList ListBags (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) + /// Storage: VoterList CounterForListNodes (r:1 w:1) + /// Proof: VoterList CounterForListNodes (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking CurrentEra (r:1 w:0) + /// Proof: Staking CurrentEra (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Balances Locks (r:1 w:1) + /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) + /// Storage: Balances Freezes (r:1 w:0) + /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:1) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) fn register_fast_unstake() -> Weight { // Proof Size summary in bytes: - // Measured: `1955` + // Measured: `1964` // Estimated: `7253` - // Minimum execution time: 112_632_000 picoseconds. - Weight::from_parts(117_267_000, 7253) + // Minimum execution time: 125_512_000 picoseconds. + Weight::from_parts(129_562_000, 7253) .saturating_add(RocksDbWeight::get().reads(15_u64)) .saturating_add(RocksDbWeight::get().writes(9_u64)) } - /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0) - /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::Ledger` (r:1 w:0) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::Queue` (r:1 w:1) - /// Proof: `FastUnstake::Queue` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::Head` (r:1 w:0) - /// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`) - /// Storage: `FastUnstake::CounterForQueue` (r:1 w:1) - /// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: FastUnstake Queue (r:1 w:1) + /// Proof: FastUnstake Queue (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) + /// Storage: FastUnstake Head (r:1 w:0) + /// Proof: FastUnstake Head (max_values: Some(1), max_size: Some(5768), added: 6263, mode: MaxEncodedLen) + /// Storage: FastUnstake CounterForQueue (r:1 w:1) + /// Proof: FastUnstake CounterForQueue (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) fn deregister() -> Weight { // Proof Size summary in bytes: - // Measured: `1251` + // Measured: `1223` // Estimated: `7253` - // Minimum execution time: 39_253_000 picoseconds. - Weight::from_parts(40_053_000, 7253) + // Minimum execution time: 43_943_000 picoseconds. + Weight::from_parts(45_842_000, 7253) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `FastUnstake::ErasToCheckPerBlock` (r:0 w:1) - /// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: FastUnstake ErasToCheckPerBlock (r:0 w:1) + /// Proof: FastUnstake ErasToCheckPerBlock (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) fn control() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_386_000 picoseconds. - Weight::from_parts(2_508_000, 0) + // Minimum execution time: 2_677_000 picoseconds. + Weight::from_parts(2_849_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } } diff --git a/substrate/frame/glutton/src/weights.rs b/substrate/frame/glutton/src/weights.rs index b2e28dc488a..cbc0fb022f5 100644 --- a/substrate/frame/glutton/src/weights.rs +++ b/substrate/frame/glutton/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_glutton` +//! Autogenerated weights for pallet_glutton //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/glutton/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/glutton/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_glutton`. +/// Weight functions needed for pallet_glutton. pub trait WeightInfo { fn initialize_pallet_grow(n: u32, ) -> Weight; fn initialize_pallet_shrink(n: u32, ) -> Weight; @@ -62,39 +63,39 @@ pub trait WeightInfo { fn set_storage() -> Weight; } -/// Weights for `pallet_glutton` using the Substrate node and recommended hardware. +/// Weights for pallet_glutton using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Glutton::TrashDataCount` (r:1 w:1) - /// Proof: `Glutton::TrashDataCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Glutton::TrashData` (r:0 w:1000) - /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) + /// Storage: Glutton TrashDataCount (r:1 w:1) + /// Proof: Glutton TrashDataCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Glutton TrashData (r:0 w:1000) + /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) /// The range of component `n` is `[0, 1000]`. fn initialize_pallet_grow(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `86` // Estimated: `1489` - // Minimum execution time: 8_443_000 picoseconds. - Weight::from_parts(103_698_651, 1489) - // Standard Error: 21_777 - .saturating_add(Weight::from_parts(9_529_476, 0).saturating_mul(n.into())) + // Minimum execution time: 11_488_000 picoseconds. + Weight::from_parts(93_073_710, 1489) + // Standard Error: 22_390 + .saturating_add(Weight::from_parts(9_572_012, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) } - /// Storage: `Glutton::TrashDataCount` (r:1 w:1) - /// Proof: `Glutton::TrashDataCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Glutton::TrashData` (r:0 w:1000) - /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) + /// Storage: Glutton TrashDataCount (r:1 w:1) + /// Proof: Glutton TrashDataCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Glutton TrashData (r:0 w:1000) + /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) /// The range of component `n` is `[0, 1000]`. fn initialize_pallet_shrink(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `119` // Estimated: `1489` - // Minimum execution time: 8_343_000 picoseconds. - Weight::from_parts(304_498, 1489) - // Standard Error: 1_568 - .saturating_add(Weight::from_parts(1_146_553, 0).saturating_mul(n.into())) + // Minimum execution time: 11_378_000 picoseconds. + Weight::from_parts(5_591_508, 1489) + // Standard Error: 1_592 + .saturating_add(Weight::from_parts(1_163_758, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) @@ -104,119 +105,119 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 656_000 picoseconds. - Weight::from_parts(1_875_128, 0) - // Standard Error: 8 - .saturating_add(Weight::from_parts(103_381, 0).saturating_mul(i.into())) + // Minimum execution time: 669_000 picoseconds. + Weight::from_parts(990_745, 0) + // Standard Error: 10 + .saturating_add(Weight::from_parts(105_224, 0).saturating_mul(i.into())) } - /// Storage: `Glutton::TrashData` (r:5000 w:0) - /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) + /// Storage: Glutton TrashData (r:5000 w:0) + /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) /// The range of component `i` is `[0, 5000]`. fn waste_proof_size_some(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `119114 + i * (1022 ±0)` // Estimated: `990 + i * (3016 ±0)` - // Minimum execution time: 454_000 picoseconds. - Weight::from_parts(521_000, 990) - // Standard Error: 1_940 - .saturating_add(Weight::from_parts(5_729_831, 0).saturating_mul(i.into())) + // Minimum execution time: 435_000 picoseconds. + Weight::from_parts(66_547_542, 990) + // Standard Error: 4_557 + .saturating_add(Weight::from_parts(5_851_324, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 3016).saturating_mul(i.into())) } - /// Storage: `Glutton::Storage` (r:1 w:0) - /// Proof: `Glutton::Storage` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Glutton::Compute` (r:1 w:0) - /// Proof: `Glutton::Compute` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Glutton::TrashData` (r:1737 w:0) - /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) + /// Storage: Glutton Storage (r:1 w:0) + /// Proof: Glutton Storage (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Glutton Compute (r:1 w:0) + /// Proof: Glutton Compute (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Glutton TrashData (r:1737 w:0) + /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) fn on_idle_high_proof_waste() -> Weight { // Proof Size summary in bytes: // Measured: `1900497` // Estimated: `5239782` - // Minimum execution time: 55_403_909_000 picoseconds. - Weight::from_parts(55_472_412_000, 5239782) + // Minimum execution time: 67_699_845_000 picoseconds. + Weight::from_parts(67_893_204_000, 5239782) .saturating_add(T::DbWeight::get().reads(1739_u64)) } - /// Storage: `Glutton::Storage` (r:1 w:0) - /// Proof: `Glutton::Storage` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Glutton::Compute` (r:1 w:0) - /// Proof: `Glutton::Compute` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Glutton::TrashData` (r:5 w:0) - /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) + /// Storage: Glutton Storage (r:1 w:0) + /// Proof: Glutton Storage (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Glutton Compute (r:1 w:0) + /// Proof: Glutton Compute (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Glutton TrashData (r:5 w:0) + /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) fn on_idle_low_proof_waste() -> Weight { // Proof Size summary in bytes: // Measured: `9547` // Estimated: `16070` - // Minimum execution time: 97_959_007_000 picoseconds. - Weight::from_parts(98_030_476_000, 16070) + // Minimum execution time: 122_297_527_000 picoseconds. + Weight::from_parts(122_394_818_000, 16070) .saturating_add(T::DbWeight::get().reads(7_u64)) } - /// Storage: `Glutton::Storage` (r:1 w:0) - /// Proof: `Glutton::Storage` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Glutton::Compute` (r:1 w:0) - /// Proof: `Glutton::Compute` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: Glutton Storage (r:1 w:0) + /// Proof: Glutton Storage (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Glutton Compute (r:1 w:0) + /// Proof: Glutton Compute (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) fn empty_on_idle() -> Weight { // Proof Size summary in bytes: // Measured: `86` // Estimated: `1493` - // Minimum execution time: 5_011_000 picoseconds. - Weight::from_parts(5_183_000, 1493) + // Minimum execution time: 5_882_000 picoseconds. + Weight::from_parts(6_138_000, 1493) .saturating_add(T::DbWeight::get().reads(2_u64)) } - /// Storage: `Glutton::Compute` (r:0 w:1) - /// Proof: `Glutton::Compute` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: Glutton Compute (r:0 w:1) + /// Proof: Glutton Compute (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) fn set_compute() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_591_000 picoseconds. - Weight::from_parts(5_970_000, 0) + // Minimum execution time: 7_830_000 picoseconds. + Weight::from_parts(8_366_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Glutton::Storage` (r:0 w:1) - /// Proof: `Glutton::Storage` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: Glutton Storage (r:0 w:1) + /// Proof: Glutton Storage (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) fn set_storage() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_689_000 picoseconds. - Weight::from_parts(6_038_000, 0) + // Minimum execution time: 7_933_000 picoseconds. + Weight::from_parts(8_213_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Glutton::TrashDataCount` (r:1 w:1) - /// Proof: `Glutton::TrashDataCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Glutton::TrashData` (r:0 w:1000) - /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) + /// Storage: Glutton TrashDataCount (r:1 w:1) + /// Proof: Glutton TrashDataCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Glutton TrashData (r:0 w:1000) + /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) /// The range of component `n` is `[0, 1000]`. fn initialize_pallet_grow(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `86` // Estimated: `1489` - // Minimum execution time: 8_443_000 picoseconds. - Weight::from_parts(103_698_651, 1489) - // Standard Error: 21_777 - .saturating_add(Weight::from_parts(9_529_476, 0).saturating_mul(n.into())) + // Minimum execution time: 11_488_000 picoseconds. + Weight::from_parts(93_073_710, 1489) + // Standard Error: 22_390 + .saturating_add(Weight::from_parts(9_572_012, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into()))) } - /// Storage: `Glutton::TrashDataCount` (r:1 w:1) - /// Proof: `Glutton::TrashDataCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Glutton::TrashData` (r:0 w:1000) - /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) + /// Storage: Glutton TrashDataCount (r:1 w:1) + /// Proof: Glutton TrashDataCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Glutton TrashData (r:0 w:1000) + /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) /// The range of component `n` is `[0, 1000]`. fn initialize_pallet_shrink(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `119` // Estimated: `1489` - // Minimum execution time: 8_343_000 picoseconds. - Weight::from_parts(304_498, 1489) - // Standard Error: 1_568 - .saturating_add(Weight::from_parts(1_146_553, 0).saturating_mul(n.into())) + // Minimum execution time: 11_378_000 picoseconds. + Weight::from_parts(5_591_508, 1489) + // Standard Error: 1_592 + .saturating_add(Weight::from_parts(1_163_758, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into()))) @@ -226,83 +227,83 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 656_000 picoseconds. - Weight::from_parts(1_875_128, 0) - // Standard Error: 8 - .saturating_add(Weight::from_parts(103_381, 0).saturating_mul(i.into())) + // Minimum execution time: 669_000 picoseconds. + Weight::from_parts(990_745, 0) + // Standard Error: 10 + .saturating_add(Weight::from_parts(105_224, 0).saturating_mul(i.into())) } - /// Storage: `Glutton::TrashData` (r:5000 w:0) - /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) + /// Storage: Glutton TrashData (r:5000 w:0) + /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) /// The range of component `i` is `[0, 5000]`. fn waste_proof_size_some(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `119114 + i * (1022 ±0)` // Estimated: `990 + i * (3016 ±0)` - // Minimum execution time: 454_000 picoseconds. - Weight::from_parts(521_000, 990) - // Standard Error: 1_940 - .saturating_add(Weight::from_parts(5_729_831, 0).saturating_mul(i.into())) + // Minimum execution time: 435_000 picoseconds. + Weight::from_parts(66_547_542, 990) + // Standard Error: 4_557 + .saturating_add(Weight::from_parts(5_851_324, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 3016).saturating_mul(i.into())) } - /// Storage: `Glutton::Storage` (r:1 w:0) - /// Proof: `Glutton::Storage` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Glutton::Compute` (r:1 w:0) - /// Proof: `Glutton::Compute` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Glutton::TrashData` (r:1737 w:0) - /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) + /// Storage: Glutton Storage (r:1 w:0) + /// Proof: Glutton Storage (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Glutton Compute (r:1 w:0) + /// Proof: Glutton Compute (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Glutton TrashData (r:1737 w:0) + /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) fn on_idle_high_proof_waste() -> Weight { // Proof Size summary in bytes: // Measured: `1900497` // Estimated: `5239782` - // Minimum execution time: 55_403_909_000 picoseconds. - Weight::from_parts(55_472_412_000, 5239782) + // Minimum execution time: 67_699_845_000 picoseconds. + Weight::from_parts(67_893_204_000, 5239782) .saturating_add(RocksDbWeight::get().reads(1739_u64)) } - /// Storage: `Glutton::Storage` (r:1 w:0) - /// Proof: `Glutton::Storage` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Glutton::Compute` (r:1 w:0) - /// Proof: `Glutton::Compute` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Glutton::TrashData` (r:5 w:0) - /// Proof: `Glutton::TrashData` (`max_values`: Some(65000), `max_size`: Some(1036), added: 3016, mode: `MaxEncodedLen`) + /// Storage: Glutton Storage (r:1 w:0) + /// Proof: Glutton Storage (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Glutton Compute (r:1 w:0) + /// Proof: Glutton Compute (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Glutton TrashData (r:5 w:0) + /// Proof: Glutton TrashData (max_values: Some(65000), max_size: Some(1036), added: 3016, mode: MaxEncodedLen) fn on_idle_low_proof_waste() -> Weight { // Proof Size summary in bytes: // Measured: `9547` // Estimated: `16070` - // Minimum execution time: 97_959_007_000 picoseconds. - Weight::from_parts(98_030_476_000, 16070) + // Minimum execution time: 122_297_527_000 picoseconds. + Weight::from_parts(122_394_818_000, 16070) .saturating_add(RocksDbWeight::get().reads(7_u64)) } - /// Storage: `Glutton::Storage` (r:1 w:0) - /// Proof: `Glutton::Storage` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Glutton::Compute` (r:1 w:0) - /// Proof: `Glutton::Compute` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: Glutton Storage (r:1 w:0) + /// Proof: Glutton Storage (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Glutton Compute (r:1 w:0) + /// Proof: Glutton Compute (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) fn empty_on_idle() -> Weight { // Proof Size summary in bytes: // Measured: `86` // Estimated: `1493` - // Minimum execution time: 5_011_000 picoseconds. - Weight::from_parts(5_183_000, 1493) + // Minimum execution time: 5_882_000 picoseconds. + Weight::from_parts(6_138_000, 1493) .saturating_add(RocksDbWeight::get().reads(2_u64)) } - /// Storage: `Glutton::Compute` (r:0 w:1) - /// Proof: `Glutton::Compute` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: Glutton Compute (r:0 w:1) + /// Proof: Glutton Compute (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) fn set_compute() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_591_000 picoseconds. - Weight::from_parts(5_970_000, 0) + // Minimum execution time: 7_830_000 picoseconds. + Weight::from_parts(8_366_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Glutton::Storage` (r:0 w:1) - /// Proof: `Glutton::Storage` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: Glutton Storage (r:0 w:1) + /// Proof: Glutton Storage (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) fn set_storage() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_689_000 picoseconds. - Weight::from_parts(6_038_000, 0) + // Minimum execution time: 7_933_000 picoseconds. + Weight::from_parts(8_213_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } } diff --git a/substrate/frame/grandpa/src/mock.rs b/substrate/frame/grandpa/src/mock.rs index e1be487dbb7..5d48f974c31 100644 --- a/substrate/frame/grandpa/src/mock.rs +++ b/substrate/frame/grandpa/src/mock.rs @@ -35,8 +35,11 @@ use sp_consensus_grandpa::{RoundNumber, SetId, GRANDPA_ENGINE_ID}; use sp_core::{crypto::KeyTypeId, H256}; use sp_keyring::Ed25519Keyring; use sp_runtime::{ - curve::PiecewiseLinear, generic::UncheckedExtrinsic, impl_opaque_keys, - testing::UintAuthorityId, traits::OpaqueKeys, BuildStorage, DigestItem, Perbill, + curve::PiecewiseLinear, + impl_opaque_keys, + testing::{TestXt, UintAuthorityId}, + traits::OpaqueKeys, + BuildStorage, DigestItem, Perbill, }; use sp_staking::{EraIndex, SessionIndex}; @@ -74,7 +77,7 @@ where RuntimeCall: From, { type OverarchingCall = RuntimeCall; - type Extrinsic = UncheckedExtrinsic; + type Extrinsic = TestXt; } parameter_types! { diff --git a/substrate/frame/identity/src/weights.rs b/substrate/frame/identity/src/weights.rs index 81de520d7f2..1feb8252c84 100644 --- a/substrate/frame/identity/src/weights.rs +++ b/substrate/frame/identity/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_identity` +//! Autogenerated weights for pallet_identity //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/identity/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/identity/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_identity`. +/// Weight functions needed for pallet_identity. pub trait WeightInfo { fn add_registrar(r: u32, ) -> Weight; fn set_identity(r: u32, ) -> Weight; @@ -76,274 +77,278 @@ pub trait WeightInfo { fn remove_dangling_username() -> Weight; } -/// Weights for `pallet_identity` using the Substrate node and recommended hardware. +/// Weights for pallet_identity using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Identity::Registrars` (r:1 w:1) - /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) /// The range of component `r` is `[1, 19]`. fn add_registrar(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `32 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 8_857_000 picoseconds. - Weight::from_parts(9_331_464, 2626) - // Standard Error: 1_745 - .saturating_add(Weight::from_parts(94_096, 0).saturating_mul(r.into())) + // Minimum execution time: 11_683_000 picoseconds. + Weight::from_parts(12_515_830, 2626) + // Standard Error: 2_154 + .saturating_add(Weight::from_parts(147_919, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) /// The range of component `r` is `[1, 20]`. - fn set_identity(_r: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `6978 + r * (5 ±0)` - // Estimated: `11037` - // Minimum execution time: 96_522_000 picoseconds. - Weight::from_parts(102_738_605, 11037) + fn set_identity(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `442 + r * (5 ±0)` + // Estimated: `11003` + // Minimum execution time: 32_949_000 picoseconds. + Weight::from_parts(31_329_634, 11003) + // Standard Error: 4_496 + .saturating_add(Weight::from_parts(203_570, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Identity::IdentityOf` (r:1 w:0) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:100 w:100) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:100 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) /// The range of component `s` is `[0, 100]`. fn set_subs_new(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `101` - // Estimated: `11037 + s * (2589 ±0)` - // Minimum execution time: 9_112_000 picoseconds. - Weight::from_parts(22_676_873, 11037) - // Standard Error: 6_494 - .saturating_add(Weight::from_parts(3_279_196, 0).saturating_mul(s.into())) + // Estimated: `11003 + s * (2589 ±0)` + // Minimum execution time: 9_157_000 picoseconds. + Weight::from_parts(24_917_444, 11003) + // Standard Error: 4_554 + .saturating_add(Weight::from_parts(3_279_868, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(s.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 2589).saturating_mul(s.into())) } - /// Storage: `Identity::IdentityOf` (r:1 w:0) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:0 w:100) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) /// The range of component `p` is `[0, 100]`. fn set_subs_old(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `194 + p * (32 ±0)` - // Estimated: `11037` - // Minimum execution time: 8_902_000 picoseconds. - Weight::from_parts(21_168_031, 11037) - // Standard Error: 3_576 - .saturating_add(Weight::from_parts(1_431_542, 0).saturating_mul(p.into())) + // Estimated: `11003` + // Minimum execution time: 9_240_000 picoseconds. + Weight::from_parts(23_326_035, 11003) + // Standard Error: 3_664 + .saturating_add(Weight::from_parts(1_439_873, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) } - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:0 w:100) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) /// The range of component `r` is `[1, 20]`. /// The range of component `s` is `[0, 100]`. - fn clear_identity(_r: u32, s: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `7070 + r * (5 ±0) + s * (32 ±0)` - // Estimated: `11037` - // Minimum execution time: 52_468_000 picoseconds. - Weight::from_parts(56_065_452, 11037) - // Standard Error: 2_274 - .saturating_add(Weight::from_parts(1_399_051, 0).saturating_mul(s.into())) + fn clear_identity(r: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `469 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 55_687_000 picoseconds. + Weight::from_parts(30_695_182, 11003) + // Standard Error: 9_921 + .saturating_add(Weight::from_parts(162_357, 0).saturating_mul(r.into())) + // Standard Error: 1_937 + .saturating_add(Weight::from_parts(1_427_998, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) } - /// Storage: `Identity::Registrars` (r:1 w:0) - /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: Identity Registrars (r:1 w:0) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) /// The range of component `r` is `[1, 20]`. fn request_judgement(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `6968 + r * (57 ±0)` - // Estimated: `11037` - // Minimum execution time: 67_951_000 picoseconds. - Weight::from_parts(69_591_058, 11037) - // Standard Error: 4_420 - .saturating_add(Weight::from_parts(209_239, 0).saturating_mul(r.into())) + // Measured: `367 + r * (57 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 34_876_000 picoseconds. + Weight::from_parts(32_207_018, 11003) + // Standard Error: 5_247 + .saturating_add(Weight::from_parts(249_156, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) /// The range of component `r` is `[1, 20]`. fn cancel_request(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `6999` - // Estimated: `11037` - // Minimum execution time: 67_818_000 picoseconds. - Weight::from_parts(70_356_319, 11037) - // Standard Error: 5_116 - .saturating_add(Weight::from_parts(4_264, 0).saturating_mul(r.into())) + // Measured: `398 + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 30_689_000 picoseconds. + Weight::from_parts(31_967_170, 11003) + // Standard Error: 5_387 + .saturating_add(Weight::from_parts(42_676, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Identity::Registrars` (r:1 w:1) - /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) /// The range of component `r` is `[1, 19]`. fn set_fee(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `89 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 6_096_000 picoseconds. - Weight::from_parts(6_470_752, 2626) - // Standard Error: 1_328 - .saturating_add(Weight::from_parts(94_764, 0).saturating_mul(r.into())) + // Minimum execution time: 7_357_000 picoseconds. + Weight::from_parts(7_932_950, 2626) + // Standard Error: 1_804 + .saturating_add(Weight::from_parts(132_653, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Identity::Registrars` (r:1 w:1) - /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) /// The range of component `r` is `[1, 19]`. fn set_account_id(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `89 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 6_278_000 picoseconds. - Weight::from_parts(6_678_997, 2626) - // Standard Error: 1_396 - .saturating_add(Weight::from_parts(87_207, 0).saturating_mul(r.into())) + // Minimum execution time: 7_437_000 picoseconds. + Weight::from_parts(8_051_889, 2626) + // Standard Error: 1_997 + .saturating_add(Weight::from_parts(129_592, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Identity::Registrars` (r:1 w:1) - /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) /// The range of component `r` is `[1, 19]`. fn set_fields(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `89 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 6_130_000 picoseconds. - Weight::from_parts(6_516_146, 2626) - // Standard Error: 1_356 - .saturating_add(Weight::from_parts(88_455, 0).saturating_mul(r.into())) + // Minimum execution time: 7_385_000 picoseconds. + Weight::from_parts(7_911_589, 2626) + // Standard Error: 1_791 + .saturating_add(Weight::from_parts(125_788, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Identity::Registrars` (r:1 w:0) - /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: Identity Registrars (r:1 w:0) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) /// The range of component `r` is `[1, 19]`. fn provide_judgement(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `7046 + r * (57 ±0)` - // Estimated: `11037` - // Minimum execution time: 87_100_000 picoseconds. - Weight::from_parts(87_601_945, 11037) - // Standard Error: 22_724 - .saturating_add(Weight::from_parts(458_296, 0).saturating_mul(r.into())) + // Measured: `445 + r * (57 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 24_073_000 picoseconds. + Weight::from_parts(17_817_684, 11003) + // Standard Error: 8_612 + .saturating_add(Weight::from_parts(406_251, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:0 w:100) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) /// The range of component `r` is `[1, 20]`. /// The range of component `s` is `[0, 100]`. fn kill_identity(r: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `7277 + r * (5 ±0) + s * (32 ±0)` - // Estimated: `11037` - // Minimum execution time: 65_925_000 picoseconds. - Weight::from_parts(70_786_250, 11037) - // Standard Error: 19_680 - .saturating_add(Weight::from_parts(29_782, 0).saturating_mul(r.into())) - // Standard Error: 3_839 - .saturating_add(Weight::from_parts(1_377_604, 0).saturating_mul(s.into())) + // Measured: `676 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 73_981_000 picoseconds. + Weight::from_parts(51_684_057, 11003) + // Standard Error: 12_662 + .saturating_add(Weight::from_parts(145_285, 0).saturating_mul(r.into())) + // Standard Error: 2_472 + .saturating_add(Weight::from_parts(1_421_039, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) } - /// Storage: `Identity::IdentityOf` (r:1 w:0) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:1 w:1) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) /// The range of component `s` is `[0, 99]`. fn add_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `475 + s * (36 ±0)` - // Estimated: `11037` - // Minimum execution time: 25_916_000 picoseconds. - Weight::from_parts(29_781_270, 11037) - // Standard Error: 1_326 - .saturating_add(Weight::from_parts(101_515, 0).saturating_mul(s.into())) + // Estimated: `11003` + // Minimum execution time: 29_367_000 picoseconds. + Weight::from_parts(34_214_998, 11003) + // Standard Error: 1_522 + .saturating_add(Weight::from_parts(114_551, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Identity::IdentityOf` (r:1 w:0) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:1 w:1) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) /// The range of component `s` is `[1, 100]`. fn rename_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `591 + s * (3 ±0)` - // Estimated: `11037` - // Minimum execution time: 12_142_000 picoseconds. - Weight::from_parts(14_179_741, 11037) - // Standard Error: 538 - .saturating_add(Weight::from_parts(38_847, 0).saturating_mul(s.into())) + // Estimated: `11003` + // Minimum execution time: 12_384_000 picoseconds. + Weight::from_parts(14_417_903, 11003) + // Standard Error: 539 + .saturating_add(Weight::from_parts(38_371, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Identity::IdentityOf` (r:1 w:0) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:1 w:1) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) /// The range of component `s` is `[1, 100]`. fn remove_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `638 + s * (35 ±0)` - // Estimated: `11037` - // Minimum execution time: 29_327_000 picoseconds. - Weight::from_parts(32_163_402, 11037) - // Standard Error: 1_047 - .saturating_add(Weight::from_parts(87_159, 0).saturating_mul(s.into())) + // Estimated: `11003` + // Minimum execution time: 33_327_000 picoseconds. + Weight::from_parts(36_208_941, 11003) + // Standard Error: 1_240 + .saturating_add(Weight::from_parts(105_805, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Identity::SuperOf` (r:1 w:1) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:0) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `s` is `[0, 99]`. fn quit_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `704 + s * (37 ±0)` // Estimated: `6723` - // Minimum execution time: 22_380_000 picoseconds. - Weight::from_parts(24_557_574, 6723) - // Standard Error: 1_131 - .saturating_add(Weight::from_parts(86_358, 0).saturating_mul(s.into())) + // Minimum execution time: 23_764_000 picoseconds. + Weight::from_parts(26_407_731, 6723) + // Standard Error: 1_025 + .saturating_add(Weight::from_parts(101_112, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -353,359 +358,367 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_791_000 picoseconds. - Weight::from_parts(7_126_000, 0) - .saturating_add(T::DbWeight::get().writes(1_u64)) + // Minimum execution time: 13_873_000 picoseconds. + Weight::from_parts(13_873_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Identity::UsernameAuthorities` (r:1 w:1) + /// Storage: `Identity::UsernameAuthorities` (r:0 w:1) /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn remove_username_authority() -> Weight { // Proof Size summary in bytes: - // Measured: `80` - // Estimated: `3517` - // Minimum execution time: 9_657_000 picoseconds. - Weight::from_parts(9_922_000, 3517) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 10_653_000 picoseconds. + Weight::from_parts(10_653_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Identity::UsernameAuthorities` (r:1 w:1) /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) /// Storage: `Identity::AccountOfUsername` (r:1 w:1) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) - /// Storage: `Identity::PendingUsernames` (r:1 w:0) - /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) fn set_username_for() -> Weight { // Proof Size summary in bytes: // Measured: `80` // Estimated: `11037` - // Minimum execution time: 67_928_000 picoseconds. - Weight::from_parts(69_993_000, 11037) - .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) + // Minimum execution time: 75_928_000 picoseconds. + Weight::from_parts(75_928_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Identity::PendingUsernames` (r:1 w:1) - /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// Storage: `Identity::AccountOfUsername` (r:0 w:1) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn accept_username() -> Weight { // Proof Size summary in bytes: - // Measured: `115` + // Measured: `106` // Estimated: `11037` - // Minimum execution time: 20_496_000 picoseconds. - Weight::from_parts(20_971_000, 11037) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) + // Minimum execution time: 38_157_000 picoseconds. + Weight::from_parts(38_157_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Identity::PendingUsernames` (r:1 w:1) - /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) fn remove_expired_approval() -> Weight { // Proof Size summary in bytes: - // Measured: `115` - // Estimated: `3550` - // Minimum execution time: 13_845_000 picoseconds. - Weight::from_parts(16_201_000, 3550) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + // Measured: `106` + // Estimated: `3542` + // Minimum execution time: 46_821_000 picoseconds. + Weight::from_parts(46_821_000, 0) + .saturating_add(Weight::from_parts(0, 3542)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Identity::AccountOfUsername` (r:1 w:0) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) fn set_primary_username() -> Weight { // Proof Size summary in bytes: - // Measured: `257` + // Measured: `247` // Estimated: `11037` - // Minimum execution time: 15_900_000 picoseconds. - Weight::from_parts(16_716_000, 11037) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + // Minimum execution time: 22_515_000 picoseconds. + Weight::from_parts(22_515_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Identity::AccountOfUsername` (r:1 w:1) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:0) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) fn remove_dangling_username() -> Weight { // Proof Size summary in bytes: - // Measured: `98` + // Measured: `126` // Estimated: `11037` - // Minimum execution time: 11_538_000 picoseconds. - Weight::from_parts(11_898_000, 11037) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + // Minimum execution time: 15_997_000 picoseconds. + Weight::from_parts(15_997_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Identity::Registrars` (r:1 w:1) - /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) /// The range of component `r` is `[1, 19]`. fn add_registrar(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `32 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 8_857_000 picoseconds. - Weight::from_parts(9_331_464, 2626) - // Standard Error: 1_745 - .saturating_add(Weight::from_parts(94_096, 0).saturating_mul(r.into())) + // Minimum execution time: 11_683_000 picoseconds. + Weight::from_parts(12_515_830, 2626) + // Standard Error: 2_154 + .saturating_add(Weight::from_parts(147_919, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) /// The range of component `r` is `[1, 20]`. - fn set_identity(_r: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `6978 + r * (5 ±0)` - // Estimated: `11037` - // Minimum execution time: 96_522_000 picoseconds. - Weight::from_parts(102_738_605, 11037) + fn set_identity(r: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `442 + r * (5 ±0)` + // Estimated: `11003` + // Minimum execution time: 32_949_000 picoseconds. + Weight::from_parts(31_329_634, 11003) + // Standard Error: 4_496 + .saturating_add(Weight::from_parts(203_570, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Identity::IdentityOf` (r:1 w:0) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:100 w:100) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:100 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) /// The range of component `s` is `[0, 100]`. fn set_subs_new(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `101` - // Estimated: `11037 + s * (2589 ±0)` - // Minimum execution time: 9_112_000 picoseconds. - Weight::from_parts(22_676_873, 11037) - // Standard Error: 6_494 - .saturating_add(Weight::from_parts(3_279_196, 0).saturating_mul(s.into())) + // Estimated: `11003 + s * (2589 ±0)` + // Minimum execution time: 9_157_000 picoseconds. + Weight::from_parts(24_917_444, 11003) + // Standard Error: 4_554 + .saturating_add(Weight::from_parts(3_279_868, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(s.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 2589).saturating_mul(s.into())) } - /// Storage: `Identity::IdentityOf` (r:1 w:0) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:0 w:100) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) /// The range of component `p` is `[0, 100]`. fn set_subs_old(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `194 + p * (32 ±0)` - // Estimated: `11037` - // Minimum execution time: 8_902_000 picoseconds. - Weight::from_parts(21_168_031, 11037) - // Standard Error: 3_576 - .saturating_add(Weight::from_parts(1_431_542, 0).saturating_mul(p.into())) + // Estimated: `11003` + // Minimum execution time: 9_240_000 picoseconds. + Weight::from_parts(23_326_035, 11003) + // Standard Error: 3_664 + .saturating_add(Weight::from_parts(1_439_873, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(p.into()))) } - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:0 w:100) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) /// The range of component `r` is `[1, 20]`. /// The range of component `s` is `[0, 100]`. - fn clear_identity(_r: u32, s: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `7070 + r * (5 ±0) + s * (32 ±0)` - // Estimated: `11037` - // Minimum execution time: 52_468_000 picoseconds. - Weight::from_parts(56_065_452, 11037) - // Standard Error: 2_274 - .saturating_add(Weight::from_parts(1_399_051, 0).saturating_mul(s.into())) + fn clear_identity(r: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `469 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 55_687_000 picoseconds. + Weight::from_parts(30_695_182, 11003) + // Standard Error: 9_921 + .saturating_add(Weight::from_parts(162_357, 0).saturating_mul(r.into())) + // Standard Error: 1_937 + .saturating_add(Weight::from_parts(1_427_998, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) } - /// Storage: `Identity::Registrars` (r:1 w:0) - /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: Identity Registrars (r:1 w:0) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) /// The range of component `r` is `[1, 20]`. fn request_judgement(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `6968 + r * (57 ±0)` - // Estimated: `11037` - // Minimum execution time: 67_951_000 picoseconds. - Weight::from_parts(69_591_058, 11037) - // Standard Error: 4_420 - .saturating_add(Weight::from_parts(209_239, 0).saturating_mul(r.into())) + // Measured: `367 + r * (57 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 34_876_000 picoseconds. + Weight::from_parts(32_207_018, 11003) + // Standard Error: 5_247 + .saturating_add(Weight::from_parts(249_156, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) /// The range of component `r` is `[1, 20]`. fn cancel_request(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `6999` - // Estimated: `11037` - // Minimum execution time: 67_818_000 picoseconds. - Weight::from_parts(70_356_319, 11037) - // Standard Error: 5_116 - .saturating_add(Weight::from_parts(4_264, 0).saturating_mul(r.into())) + // Measured: `398 + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 30_689_000 picoseconds. + Weight::from_parts(31_967_170, 11003) + // Standard Error: 5_387 + .saturating_add(Weight::from_parts(42_676, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Identity::Registrars` (r:1 w:1) - /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) /// The range of component `r` is `[1, 19]`. fn set_fee(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `89 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 6_096_000 picoseconds. - Weight::from_parts(6_470_752, 2626) - // Standard Error: 1_328 - .saturating_add(Weight::from_parts(94_764, 0).saturating_mul(r.into())) + // Minimum execution time: 7_357_000 picoseconds. + Weight::from_parts(7_932_950, 2626) + // Standard Error: 1_804 + .saturating_add(Weight::from_parts(132_653, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Identity::Registrars` (r:1 w:1) - /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) /// The range of component `r` is `[1, 19]`. fn set_account_id(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `89 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 6_278_000 picoseconds. - Weight::from_parts(6_678_997, 2626) - // Standard Error: 1_396 - .saturating_add(Weight::from_parts(87_207, 0).saturating_mul(r.into())) + // Minimum execution time: 7_437_000 picoseconds. + Weight::from_parts(8_051_889, 2626) + // Standard Error: 1_997 + .saturating_add(Weight::from_parts(129_592, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Identity::Registrars` (r:1 w:1) - /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) + /// Storage: Identity Registrars (r:1 w:1) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) /// The range of component `r` is `[1, 19]`. fn set_fields(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `89 + r * (57 ±0)` // Estimated: `2626` - // Minimum execution time: 6_130_000 picoseconds. - Weight::from_parts(6_516_146, 2626) - // Standard Error: 1_356 - .saturating_add(Weight::from_parts(88_455, 0).saturating_mul(r.into())) + // Minimum execution time: 7_385_000 picoseconds. + Weight::from_parts(7_911_589, 2626) + // Standard Error: 1_791 + .saturating_add(Weight::from_parts(125_788, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Identity::Registrars` (r:1 w:0) - /// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`) - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) + /// Storage: Identity Registrars (r:1 w:0) + /// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) /// The range of component `r` is `[1, 19]`. fn provide_judgement(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `7046 + r * (57 ±0)` - // Estimated: `11037` - // Minimum execution time: 87_100_000 picoseconds. - Weight::from_parts(87_601_945, 11037) - // Standard Error: 22_724 - .saturating_add(Weight::from_parts(458_296, 0).saturating_mul(r.into())) + // Measured: `445 + r * (57 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 24_073_000 picoseconds. + Weight::from_parts(17_817_684, 11003) + // Standard Error: 8_612 + .saturating_add(Weight::from_parts(406_251, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `Identity::IdentityOf` (r:1 w:1) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:0 w:100) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: Identity IdentityOf (r:1 w:1) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:0 w:100) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) /// The range of component `r` is `[1, 20]`. /// The range of component `s` is `[0, 100]`. fn kill_identity(r: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `7277 + r * (5 ±0) + s * (32 ±0)` - // Estimated: `11037` - // Minimum execution time: 65_925_000 picoseconds. - Weight::from_parts(70_786_250, 11037) - // Standard Error: 19_680 - .saturating_add(Weight::from_parts(29_782, 0).saturating_mul(r.into())) - // Standard Error: 3_839 - .saturating_add(Weight::from_parts(1_377_604, 0).saturating_mul(s.into())) + // Measured: `676 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)` + // Estimated: `11003` + // Minimum execution time: 73_981_000 picoseconds. + Weight::from_parts(51_684_057, 11003) + // Standard Error: 12_662 + .saturating_add(Weight::from_parts(145_285, 0).saturating_mul(r.into())) + // Standard Error: 2_472 + .saturating_add(Weight::from_parts(1_421_039, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) } - /// Storage: `Identity::IdentityOf` (r:1 w:0) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:1 w:1) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) /// The range of component `s` is `[0, 99]`. fn add_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `475 + s * (36 ±0)` - // Estimated: `11037` - // Minimum execution time: 25_916_000 picoseconds. - Weight::from_parts(29_781_270, 11037) - // Standard Error: 1_326 - .saturating_add(Weight::from_parts(101_515, 0).saturating_mul(s.into())) + // Estimated: `11003` + // Minimum execution time: 29_367_000 picoseconds. + Weight::from_parts(34_214_998, 11003) + // Standard Error: 1_522 + .saturating_add(Weight::from_parts(114_551, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Identity::IdentityOf` (r:1 w:0) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:1 w:1) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) /// The range of component `s` is `[1, 100]`. fn rename_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `591 + s * (3 ±0)` - // Estimated: `11037` - // Minimum execution time: 12_142_000 picoseconds. - Weight::from_parts(14_179_741, 11037) - // Standard Error: 538 - .saturating_add(Weight::from_parts(38_847, 0).saturating_mul(s.into())) + // Estimated: `11003` + // Minimum execution time: 12_384_000 picoseconds. + Weight::from_parts(14_417_903, 11003) + // Standard Error: 539 + .saturating_add(Weight::from_parts(38_371, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Identity::IdentityOf` (r:1 w:0) - /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) - /// Storage: `Identity::SuperOf` (r:1 w:1) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) + /// Storage: Identity IdentityOf (r:1 w:0) + /// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) /// The range of component `s` is `[1, 100]`. fn remove_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `638 + s * (35 ±0)` - // Estimated: `11037` - // Minimum execution time: 29_327_000 picoseconds. - Weight::from_parts(32_163_402, 11037) - // Standard Error: 1_047 - .saturating_add(Weight::from_parts(87_159, 0).saturating_mul(s.into())) + // Estimated: `11003` + // Minimum execution time: 33_327_000 picoseconds. + Weight::from_parts(36_208_941, 11003) + // Standard Error: 1_240 + .saturating_add(Weight::from_parts(105_805, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Identity::SuperOf` (r:1 w:1) - /// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) - /// Storage: `Identity::SubsOf` (r:1 w:1) - /// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:0) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Identity SuperOf (r:1 w:1) + /// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: Identity SubsOf (r:1 w:1) + /// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `s` is `[0, 99]`. fn quit_sub(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `704 + s * (37 ±0)` // Estimated: `6723` - // Minimum execution time: 22_380_000 picoseconds. - Weight::from_parts(24_557_574, 6723) - // Standard Error: 1_131 - .saturating_add(Weight::from_parts(86_358, 0).saturating_mul(s.into())) + // Minimum execution time: 23_764_000 picoseconds. + Weight::from_parts(26_407_731, 6723) + // Standard Error: 1_025 + .saturating_add(Weight::from_parts(101_112, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -715,88 +728,92 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_791_000 picoseconds. - Weight::from_parts(7_126_000, 0) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + // Minimum execution time: 13_873_000 picoseconds. + Weight::from_parts(13_873_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(RocksDbWeight::get().writes(1)) } - /// Storage: `Identity::UsernameAuthorities` (r:1 w:1) + /// Storage: `Identity::UsernameAuthorities` (r:0 w:1) /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) fn remove_username_authority() -> Weight { // Proof Size summary in bytes: - // Measured: `80` - // Estimated: `3517` - // Minimum execution time: 9_657_000 picoseconds. - Weight::from_parts(9_922_000, 3517) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 10_653_000 picoseconds. + Weight::from_parts(10_653_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(RocksDbWeight::get().writes(1)) } /// Storage: `Identity::UsernameAuthorities` (r:1 w:1) /// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) /// Storage: `Identity::AccountOfUsername` (r:1 w:1) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) - /// Storage: `Identity::PendingUsernames` (r:1 w:0) - /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) fn set_username_for() -> Weight { // Proof Size summary in bytes: // Measured: `80` // Estimated: `11037` - // Minimum execution time: 67_928_000 picoseconds. - Weight::from_parts(69_993_000, 11037) - .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) + // Minimum execution time: 75_928_000 picoseconds. + Weight::from_parts(75_928_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(3)) } /// Storage: `Identity::PendingUsernames` (r:1 w:1) - /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) /// Storage: `Identity::AccountOfUsername` (r:0 w:1) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn accept_username() -> Weight { // Proof Size summary in bytes: - // Measured: `115` + // Measured: `106` // Estimated: `11037` - // Minimum execution time: 20_496_000 picoseconds. - Weight::from_parts(20_971_000, 11037) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) + // Minimum execution time: 38_157_000 picoseconds. + Weight::from_parts(38_157_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(3)) } /// Storage: `Identity::PendingUsernames` (r:1 w:1) - /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`) fn remove_expired_approval() -> Weight { // Proof Size summary in bytes: - // Measured: `115` - // Estimated: `3550` - // Minimum execution time: 13_845_000 picoseconds. - Weight::from_parts(16_201_000, 3550) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + // Measured: `106` + // Estimated: `3542` + // Minimum execution time: 46_821_000 picoseconds. + Weight::from_parts(46_821_000, 0) + .saturating_add(Weight::from_parts(0, 3542)) + .saturating_add(RocksDbWeight::get().reads(1)) + .saturating_add(RocksDbWeight::get().writes(1)) } /// Storage: `Identity::AccountOfUsername` (r:1 w:0) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:1) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) fn set_primary_username() -> Weight { // Proof Size summary in bytes: - // Measured: `257` + // Measured: `247` // Estimated: `11037` - // Minimum execution time: 15_900_000 picoseconds. - Weight::from_parts(16_716_000, 11037) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + // Minimum execution time: 22_515_000 picoseconds. + Weight::from_parts(22_515_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(1)) } /// Storage: `Identity::AccountOfUsername` (r:1 w:1) - /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `Identity::IdentityOf` (r:1 w:0) /// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`) fn remove_dangling_username() -> Weight { // Proof Size summary in bytes: - // Measured: `98` + // Measured: `126` // Estimated: `11037` - // Minimum execution time: 11_538_000 picoseconds. - Weight::from_parts(11_898_000, 11037) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + // Minimum execution time: 15_997_000 picoseconds. + Weight::from_parts(15_997_000, 0) + .saturating_add(Weight::from_parts(0, 11037)) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(1)) } } diff --git a/substrate/frame/im-online/src/mock.rs b/substrate/frame/im-online/src/mock.rs index c0ba9143e13..9dad148b10f 100644 --- a/substrate/frame/im-online/src/mock.rs +++ b/substrate/frame/im-online/src/mock.rs @@ -27,7 +27,7 @@ use frame_support::{ use pallet_session::historical as pallet_session_historical; use sp_core::H256; use sp_runtime::{ - testing::UintAuthorityId, + testing::{TestXt, UintAuthorityId}, traits::{BlakeTwo256, ConvertInto, IdentityLookup}, BuildStorage, Permill, }; @@ -78,7 +78,7 @@ impl pallet_session::historical::SessionManager for TestSessionManager } /// An extrinsic type used for tests. -pub type Extrinsic = sp_runtime::generic::UncheckedExtrinsic; +pub type Extrinsic = TestXt; type IdentificationTuple = (u64, u64); type Offence = crate::UnresponsivenessOffence; diff --git a/substrate/frame/im-online/src/tests.rs b/substrate/frame/im-online/src/tests.rs index 6f5a14d7e7f..5e5212e1d56 100644 --- a/substrate/frame/im-online/src/tests.rs +++ b/substrate/frame/im-online/src/tests.rs @@ -228,7 +228,7 @@ fn should_generate_heartbeats() { // check stuff about the transaction. let ex: Extrinsic = Decode::decode(&mut &*transaction).unwrap(); - let heartbeat = match ex.function { + let heartbeat = match ex.call { crate::mock::RuntimeCall::ImOnline(crate::Call::heartbeat { heartbeat, .. }) => heartbeat, e => panic!("Unexpected call: {:?}", e), @@ -342,7 +342,7 @@ fn should_not_send_a_report_if_already_online() { assert_eq!(pool_state.read().transactions.len(), 0); // check stuff about the transaction. let ex: Extrinsic = Decode::decode(&mut &*transaction).unwrap(); - let heartbeat = match ex.function { + let heartbeat = match ex.call { crate::mock::RuntimeCall::ImOnline(crate::Call::heartbeat { heartbeat, .. }) => heartbeat, e => panic!("Unexpected call: {:?}", e), diff --git a/substrate/frame/im-online/src/weights.rs b/substrate/frame/im-online/src/weights.rs index 11357b1e7b7..c3db02af257 100644 --- a/substrate/frame/im-online/src/weights.rs +++ b/substrate/frame/im-online/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_im_online` +//! Autogenerated weights for pallet_im_online //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/im-online/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/im-online/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,60 +50,60 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_im_online`. +/// Weight functions needed for pallet_im_online. pub trait WeightInfo { fn validate_unsigned_and_then_heartbeat(k: u32, ) -> Weight; } -/// Weights for `pallet_im_online` using the Substrate node and recommended hardware. +/// Weights for pallet_im_online using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Session::Validators` (r:1 w:0) - /// Proof: `Session::Validators` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Session::CurrentIndex` (r:1 w:0) - /// Proof: `Session::CurrentIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ImOnline::Keys` (r:1 w:0) - /// Proof: `ImOnline::Keys` (`max_values`: Some(1), `max_size`: Some(320002), added: 320497, mode: `MaxEncodedLen`) - /// Storage: `ImOnline::ReceivedHeartbeats` (r:1 w:1) - /// Proof: `ImOnline::ReceivedHeartbeats` (`max_values`: None, `max_size`: Some(25), added: 2500, mode: `MaxEncodedLen`) - /// Storage: `ImOnline::AuthoredBlocks` (r:1 w:0) - /// Proof: `ImOnline::AuthoredBlocks` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `MaxEncodedLen`) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session CurrentIndex (r:1 w:0) + /// Proof Skipped: Session CurrentIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ImOnline Keys (r:1 w:0) + /// Proof: ImOnline Keys (max_values: Some(1), max_size: Some(320002), added: 320497, mode: MaxEncodedLen) + /// Storage: ImOnline ReceivedHeartbeats (r:1 w:1) + /// Proof: ImOnline ReceivedHeartbeats (max_values: None, max_size: Some(25), added: 2500, mode: MaxEncodedLen) + /// Storage: ImOnline AuthoredBlocks (r:1 w:0) + /// Proof: ImOnline AuthoredBlocks (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) /// The range of component `k` is `[1, 1000]`. fn validate_unsigned_and_then_heartbeat(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `327 + k * (32 ±0)` + // Measured: `295 + k * (32 ±0)` // Estimated: `321487 + k * (1761 ±0)` - // Minimum execution time: 65_515_000 picoseconds. - Weight::from_parts(74_765_329, 321487) - // Standard Error: 500 - .saturating_add(Weight::from_parts(39_171, 0).saturating_mul(k.into())) + // Minimum execution time: 80_568_000 picoseconds. + Weight::from_parts(95_175_595, 321487) + // Standard Error: 627 + .saturating_add(Weight::from_parts(39_094, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1761).saturating_mul(k.into())) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Session::Validators` (r:1 w:0) - /// Proof: `Session::Validators` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Session::CurrentIndex` (r:1 w:0) - /// Proof: `Session::CurrentIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `ImOnline::Keys` (r:1 w:0) - /// Proof: `ImOnline::Keys` (`max_values`: Some(1), `max_size`: Some(320002), added: 320497, mode: `MaxEncodedLen`) - /// Storage: `ImOnline::ReceivedHeartbeats` (r:1 w:1) - /// Proof: `ImOnline::ReceivedHeartbeats` (`max_values`: None, `max_size`: Some(25), added: 2500, mode: `MaxEncodedLen`) - /// Storage: `ImOnline::AuthoredBlocks` (r:1 w:0) - /// Proof: `ImOnline::AuthoredBlocks` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `MaxEncodedLen`) + /// Storage: Session Validators (r:1 w:0) + /// Proof Skipped: Session Validators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Session CurrentIndex (r:1 w:0) + /// Proof Skipped: Session CurrentIndex (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ImOnline Keys (r:1 w:0) + /// Proof: ImOnline Keys (max_values: Some(1), max_size: Some(320002), added: 320497, mode: MaxEncodedLen) + /// Storage: ImOnline ReceivedHeartbeats (r:1 w:1) + /// Proof: ImOnline ReceivedHeartbeats (max_values: None, max_size: Some(25), added: 2500, mode: MaxEncodedLen) + /// Storage: ImOnline AuthoredBlocks (r:1 w:0) + /// Proof: ImOnline AuthoredBlocks (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) /// The range of component `k` is `[1, 1000]`. fn validate_unsigned_and_then_heartbeat(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `327 + k * (32 ±0)` + // Measured: `295 + k * (32 ±0)` // Estimated: `321487 + k * (1761 ±0)` - // Minimum execution time: 65_515_000 picoseconds. - Weight::from_parts(74_765_329, 321487) - // Standard Error: 500 - .saturating_add(Weight::from_parts(39_171, 0).saturating_mul(k.into())) + // Minimum execution time: 80_568_000 picoseconds. + Weight::from_parts(95_175_595, 321487) + // Standard Error: 627 + .saturating_add(Weight::from_parts(39_094, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1761).saturating_mul(k.into())) diff --git a/substrate/frame/indices/src/weights.rs b/substrate/frame/indices/src/weights.rs index 6b571164eb6..d081cc738b1 100644 --- a/substrate/frame/indices/src/weights.rs +++ b/substrate/frame/indices/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_indices` +//! Autogenerated weights for pallet_indices //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/indices/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/indices/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_indices`. +/// Weight functions needed for pallet_indices. pub trait WeightInfo { fn claim() -> Weight; fn transfer() -> Weight; @@ -58,128 +59,128 @@ pub trait WeightInfo { fn freeze() -> Weight; } -/// Weights for `pallet_indices` using the Substrate node and recommended hardware. +/// Weights for pallet_indices using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Indices::Accounts` (r:1 w:1) - /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) fn claim() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3534` - // Minimum execution time: 20_825_000 picoseconds. - Weight::from_parts(21_507_000, 3534) + // Minimum execution time: 25_491_000 picoseconds. + Weight::from_parts(26_456_000, 3534) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Indices::Accounts` (r:1 w:1) - /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn transfer() -> Weight { // Proof Size summary in bytes: // Measured: `275` // Estimated: `3593` - // Minimum execution time: 31_091_000 picoseconds. - Weight::from_parts(31_923_000, 3593) + // Minimum execution time: 38_027_000 picoseconds. + Weight::from_parts(38_749_000, 3593) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Indices::Accounts` (r:1 w:1) - /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) fn free() -> Weight { // Proof Size summary in bytes: // Measured: `172` // Estimated: `3534` - // Minimum execution time: 21_832_000 picoseconds. - Weight::from_parts(22_436_000, 3534) + // Minimum execution time: 26_652_000 picoseconds. + Weight::from_parts(27_273_000, 3534) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Indices::Accounts` (r:1 w:1) - /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn force_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `275` // Estimated: `3593` - // Minimum execution time: 23_876_000 picoseconds. - Weight::from_parts(24_954_000, 3593) + // Minimum execution time: 29_464_000 picoseconds. + Weight::from_parts(30_959_000, 3593) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Indices::Accounts` (r:1 w:1) - /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) fn freeze() -> Weight { // Proof Size summary in bytes: // Measured: `172` // Estimated: `3534` - // Minimum execution time: 22_954_000 picoseconds. - Weight::from_parts(23_792_000, 3534) + // Minimum execution time: 29_015_000 picoseconds. + Weight::from_parts(29_714_000, 3534) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Indices::Accounts` (r:1 w:1) - /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) fn claim() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3534` - // Minimum execution time: 20_825_000 picoseconds. - Weight::from_parts(21_507_000, 3534) + // Minimum execution time: 25_491_000 picoseconds. + Weight::from_parts(26_456_000, 3534) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Indices::Accounts` (r:1 w:1) - /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn transfer() -> Weight { // Proof Size summary in bytes: // Measured: `275` // Estimated: `3593` - // Minimum execution time: 31_091_000 picoseconds. - Weight::from_parts(31_923_000, 3593) + // Minimum execution time: 38_027_000 picoseconds. + Weight::from_parts(38_749_000, 3593) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Indices::Accounts` (r:1 w:1) - /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) fn free() -> Weight { // Proof Size summary in bytes: // Measured: `172` // Estimated: `3534` - // Minimum execution time: 21_832_000 picoseconds. - Weight::from_parts(22_436_000, 3534) + // Minimum execution time: 26_652_000 picoseconds. + Weight::from_parts(27_273_000, 3534) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Indices::Accounts` (r:1 w:1) - /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn force_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `275` // Estimated: `3593` - // Minimum execution time: 23_876_000 picoseconds. - Weight::from_parts(24_954_000, 3593) + // Minimum execution time: 29_464_000 picoseconds. + Weight::from_parts(30_959_000, 3593) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Indices::Accounts` (r:1 w:1) - /// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: Indices Accounts (r:1 w:1) + /// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) fn freeze() -> Weight { // Proof Size summary in bytes: // Measured: `172` // Estimated: `3534` - // Minimum execution time: 22_954_000 picoseconds. - Weight::from_parts(23_792_000, 3534) + // Minimum execution time: 29_015_000 picoseconds. + Weight::from_parts(29_714_000, 3534) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/lottery/src/weights.rs b/substrate/frame/lottery/src/weights.rs index 7e56cdf90db..3b4e5623753 100644 --- a/substrate/frame/lottery/src/weights.rs +++ b/substrate/frame/lottery/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_lottery` +//! Autogenerated weights for pallet_lottery //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/lottery/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/lottery/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_lottery`. +/// Weight functions needed for pallet_lottery. pub trait WeightInfo { fn buy_ticket() -> Weight; fn set_calls(n: u32, ) -> Weight; @@ -59,222 +60,214 @@ pub trait WeightInfo { fn on_initialize_repeat() -> Weight; } -/// Weights for `pallet_lottery` using the Substrate node and recommended hardware. +/// Weights for pallet_lottery using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) - /// Storage: `Lottery::Lottery` (r:1 w:0) - /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) - /// Storage: `Lottery::CallIndices` (r:1 w:0) - /// Proof: `Lottery::CallIndices` (`max_values`: Some(1), `max_size`: Some(21), added: 516, mode: `MaxEncodedLen`) - /// Storage: `Lottery::TicketsCount` (r:1 w:1) - /// Proof: `Lottery::TicketsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Lottery::Participants` (r:1 w:1) - /// Proof: `Lottery::Participants` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) - /// Storage: `Lottery::LotteryIndex` (r:1 w:0) - /// Proof: `Lottery::LotteryIndex` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Lottery::Tickets` (r:0 w:1) - /// Proof: `Lottery::Tickets` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + /// Storage: Lottery Lottery (r:1 w:0) + /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) + /// Storage: Lottery CallIndices (r:1 w:0) + /// Proof: Lottery CallIndices (max_values: Some(1), max_size: Some(21), added: 516, mode: MaxEncodedLen) + /// Storage: Lottery TicketsCount (r:1 w:1) + /// Proof: Lottery TicketsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Lottery Participants (r:1 w:1) + /// Proof: Lottery Participants (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: Lottery LotteryIndex (r:1 w:0) + /// Proof: Lottery LotteryIndex (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Lottery Tickets (r:0 w:1) + /// Proof: Lottery Tickets (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) fn buy_ticket() -> Weight { // Proof Size summary in bytes: - // Measured: `492` - // Estimated: `3997` - // Minimum execution time: 57_891_000 picoseconds. - Weight::from_parts(59_508_000, 3997) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `452` + // Estimated: `3593` + // Minimum execution time: 60_298_000 picoseconds. + Weight::from_parts(62_058_000, 3593) + .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `Lottery::CallIndices` (r:0 w:1) - /// Proof: `Lottery::CallIndices` (`max_values`: Some(1), `max_size`: Some(21), added: 516, mode: `MaxEncodedLen`) + /// Storage: Lottery CallIndices (r:0 w:1) + /// Proof: Lottery CallIndices (max_values: Some(1), max_size: Some(21), added: 516, mode: MaxEncodedLen) /// The range of component `n` is `[0, 10]`. fn set_calls(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_026_000 picoseconds. - Weight::from_parts(5_854_666, 0) - // Standard Error: 3_233 - .saturating_add(Weight::from_parts(334_818, 0).saturating_mul(n.into())) + // Minimum execution time: 7_291_000 picoseconds. + Weight::from_parts(8_178_186, 0) + // Standard Error: 3_048 + .saturating_add(Weight::from_parts(330_871, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Lottery::Lottery` (r:1 w:1) - /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) - /// Storage: `Lottery::LotteryIndex` (r:1 w:1) - /// Proof: `Lottery::LotteryIndex` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Lottery Lottery (r:1 w:1) + /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) + /// Storage: Lottery LotteryIndex (r:1 w:1) + /// Proof: Lottery LotteryIndex (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn start_lottery() -> Weight { // Proof Size summary in bytes: - // Measured: `194` + // Measured: `161` // Estimated: `3593` - // Minimum execution time: 26_216_000 picoseconds. - Weight::from_parts(27_216_000, 3593) + // Minimum execution time: 36_741_000 picoseconds. + Weight::from_parts(38_288_000, 3593) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Lottery::Lottery` (r:1 w:1) - /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) + /// Storage: Lottery Lottery (r:1 w:1) + /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) fn stop_repeat() -> Weight { // Proof Size summary in bytes: - // Measured: `252` + // Measured: `219` // Estimated: `1514` - // Minimum execution time: 6_208_000 picoseconds. - Weight::from_parts(6_427_000, 1514) + // Minimum execution time: 7_270_000 picoseconds. + Weight::from_parts(7_578_000, 1514) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `RandomnessCollectiveFlip::RandomMaterial` (r:1 w:0) - /// Proof: `RandomnessCollectiveFlip::RandomMaterial` (`max_values`: Some(1), `max_size`: Some(2594), added: 3089, mode: `MaxEncodedLen`) - /// Storage: `Lottery::Lottery` (r:1 w:1) - /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Lottery::TicketsCount` (r:1 w:1) - /// Proof: `Lottery::TicketsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Lottery::Tickets` (r:1 w:0) - /// Proof: `Lottery::Tickets` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + /// Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) + /// Proof: RandomnessCollectiveFlip RandomMaterial (max_values: Some(1), max_size: Some(2594), added: 3089, mode: MaxEncodedLen) + /// Storage: Lottery Lottery (r:1 w:1) + /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Lottery TicketsCount (r:1 w:1) + /// Proof: Lottery TicketsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Lottery Tickets (r:1 w:0) + /// Proof: Lottery Tickets (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) fn on_initialize_end() -> Weight { // Proof Size summary in bytes: - // Measured: `591` + // Measured: `558` // Estimated: `6196` - // Minimum execution time: 58_660_000 picoseconds. - Weight::from_parts(59_358_000, 6196) + // Minimum execution time: 76_611_000 picoseconds. + Weight::from_parts(78_107_000, 6196) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `RandomnessCollectiveFlip::RandomMaterial` (r:1 w:0) - /// Proof: `RandomnessCollectiveFlip::RandomMaterial` (`max_values`: Some(1), `max_size`: Some(2594), added: 3089, mode: `MaxEncodedLen`) - /// Storage: `Lottery::Lottery` (r:1 w:1) - /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Lottery::TicketsCount` (r:1 w:1) - /// Proof: `Lottery::TicketsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Lottery::Tickets` (r:1 w:0) - /// Proof: `Lottery::Tickets` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - /// Storage: `Lottery::LotteryIndex` (r:1 w:1) - /// Proof: `Lottery::LotteryIndex` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) + /// Proof: RandomnessCollectiveFlip RandomMaterial (max_values: Some(1), max_size: Some(2594), added: 3089, mode: MaxEncodedLen) + /// Storage: Lottery Lottery (r:1 w:1) + /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Lottery TicketsCount (r:1 w:1) + /// Proof: Lottery TicketsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Lottery Tickets (r:1 w:0) + /// Proof: Lottery Tickets (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) + /// Storage: Lottery LotteryIndex (r:1 w:1) + /// Proof: Lottery LotteryIndex (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) fn on_initialize_repeat() -> Weight { // Proof Size summary in bytes: - // Measured: `591` + // Measured: `558` // Estimated: `6196` - // Minimum execution time: 59_376_000 picoseconds. - Weight::from_parts(60_598_000, 6196) + // Minimum execution time: 78_731_000 picoseconds. + Weight::from_parts(80_248_000, 6196) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) - /// Storage: `Lottery::Lottery` (r:1 w:0) - /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) - /// Storage: `Lottery::CallIndices` (r:1 w:0) - /// Proof: `Lottery::CallIndices` (`max_values`: Some(1), `max_size`: Some(21), added: 516, mode: `MaxEncodedLen`) - /// Storage: `Lottery::TicketsCount` (r:1 w:1) - /// Proof: `Lottery::TicketsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Lottery::Participants` (r:1 w:1) - /// Proof: `Lottery::Participants` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) - /// Storage: `Lottery::LotteryIndex` (r:1 w:0) - /// Proof: `Lottery::LotteryIndex` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Lottery::Tickets` (r:0 w:1) - /// Proof: `Lottery::Tickets` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + /// Storage: Lottery Lottery (r:1 w:0) + /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) + /// Storage: Lottery CallIndices (r:1 w:0) + /// Proof: Lottery CallIndices (max_values: Some(1), max_size: Some(21), added: 516, mode: MaxEncodedLen) + /// Storage: Lottery TicketsCount (r:1 w:1) + /// Proof: Lottery TicketsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Lottery Participants (r:1 w:1) + /// Proof: Lottery Participants (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: Lottery LotteryIndex (r:1 w:0) + /// Proof: Lottery LotteryIndex (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Lottery Tickets (r:0 w:1) + /// Proof: Lottery Tickets (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) fn buy_ticket() -> Weight { // Proof Size summary in bytes: - // Measured: `492` - // Estimated: `3997` - // Minimum execution time: 57_891_000 picoseconds. - Weight::from_parts(59_508_000, 3997) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `452` + // Estimated: `3593` + // Minimum execution time: 60_298_000 picoseconds. + Weight::from_parts(62_058_000, 3593) + .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `Lottery::CallIndices` (r:0 w:1) - /// Proof: `Lottery::CallIndices` (`max_values`: Some(1), `max_size`: Some(21), added: 516, mode: `MaxEncodedLen`) + /// Storage: Lottery CallIndices (r:0 w:1) + /// Proof: Lottery CallIndices (max_values: Some(1), max_size: Some(21), added: 516, mode: MaxEncodedLen) /// The range of component `n` is `[0, 10]`. fn set_calls(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_026_000 picoseconds. - Weight::from_parts(5_854_666, 0) - // Standard Error: 3_233 - .saturating_add(Weight::from_parts(334_818, 0).saturating_mul(n.into())) + // Minimum execution time: 7_291_000 picoseconds. + Weight::from_parts(8_178_186, 0) + // Standard Error: 3_048 + .saturating_add(Weight::from_parts(330_871, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Lottery::Lottery` (r:1 w:1) - /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) - /// Storage: `Lottery::LotteryIndex` (r:1 w:1) - /// Proof: `Lottery::LotteryIndex` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Lottery Lottery (r:1 w:1) + /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) + /// Storage: Lottery LotteryIndex (r:1 w:1) + /// Proof: Lottery LotteryIndex (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn start_lottery() -> Weight { // Proof Size summary in bytes: - // Measured: `194` + // Measured: `161` // Estimated: `3593` - // Minimum execution time: 26_216_000 picoseconds. - Weight::from_parts(27_216_000, 3593) + // Minimum execution time: 36_741_000 picoseconds. + Weight::from_parts(38_288_000, 3593) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Lottery::Lottery` (r:1 w:1) - /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) + /// Storage: Lottery Lottery (r:1 w:1) + /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) fn stop_repeat() -> Weight { // Proof Size summary in bytes: - // Measured: `252` + // Measured: `219` // Estimated: `1514` - // Minimum execution time: 6_208_000 picoseconds. - Weight::from_parts(6_427_000, 1514) + // Minimum execution time: 7_270_000 picoseconds. + Weight::from_parts(7_578_000, 1514) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `RandomnessCollectiveFlip::RandomMaterial` (r:1 w:0) - /// Proof: `RandomnessCollectiveFlip::RandomMaterial` (`max_values`: Some(1), `max_size`: Some(2594), added: 3089, mode: `MaxEncodedLen`) - /// Storage: `Lottery::Lottery` (r:1 w:1) - /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Lottery::TicketsCount` (r:1 w:1) - /// Proof: `Lottery::TicketsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Lottery::Tickets` (r:1 w:0) - /// Proof: `Lottery::Tickets` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + /// Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) + /// Proof: RandomnessCollectiveFlip RandomMaterial (max_values: Some(1), max_size: Some(2594), added: 3089, mode: MaxEncodedLen) + /// Storage: Lottery Lottery (r:1 w:1) + /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Lottery TicketsCount (r:1 w:1) + /// Proof: Lottery TicketsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Lottery Tickets (r:1 w:0) + /// Proof: Lottery Tickets (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) fn on_initialize_end() -> Weight { // Proof Size summary in bytes: - // Measured: `591` + // Measured: `558` // Estimated: `6196` - // Minimum execution time: 58_660_000 picoseconds. - Weight::from_parts(59_358_000, 6196) + // Minimum execution time: 76_611_000 picoseconds. + Weight::from_parts(78_107_000, 6196) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `RandomnessCollectiveFlip::RandomMaterial` (r:1 w:0) - /// Proof: `RandomnessCollectiveFlip::RandomMaterial` (`max_values`: Some(1), `max_size`: Some(2594), added: 3089, mode: `MaxEncodedLen`) - /// Storage: `Lottery::Lottery` (r:1 w:1) - /// Proof: `Lottery::Lottery` (`max_values`: Some(1), `max_size`: Some(29), added: 524, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Lottery::TicketsCount` (r:1 w:1) - /// Proof: `Lottery::TicketsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Lottery::Tickets` (r:1 w:0) - /// Proof: `Lottery::Tickets` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - /// Storage: `Lottery::LotteryIndex` (r:1 w:1) - /// Proof: `Lottery::LotteryIndex` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) + /// Proof: RandomnessCollectiveFlip RandomMaterial (max_values: Some(1), max_size: Some(2594), added: 3089, mode: MaxEncodedLen) + /// Storage: Lottery Lottery (r:1 w:1) + /// Proof: Lottery Lottery (max_values: Some(1), max_size: Some(29), added: 524, mode: MaxEncodedLen) + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Lottery TicketsCount (r:1 w:1) + /// Proof: Lottery TicketsCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Lottery Tickets (r:1 w:0) + /// Proof: Lottery Tickets (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen) + /// Storage: Lottery LotteryIndex (r:1 w:1) + /// Proof: Lottery LotteryIndex (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) fn on_initialize_repeat() -> Weight { // Proof Size summary in bytes: - // Measured: `591` + // Measured: `558` // Estimated: `6196` - // Minimum execution time: 59_376_000 picoseconds. - Weight::from_parts(60_598_000, 6196) + // Minimum execution time: 78_731_000 picoseconds. + Weight::from_parts(80_248_000, 6196) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } diff --git a/substrate/frame/membership/src/weights.rs b/substrate/frame/membership/src/weights.rs index f21867d6870..2d18848b89a 100644 --- a/substrate/frame/membership/src/weights.rs +++ b/substrate/frame/membership/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_membership` +//! Autogenerated weights for pallet_membership //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/membership/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/membership/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_membership`. +/// Weight functions needed for pallet_membership. pub trait WeightInfo { fn add_member(m: u32, ) -> Weight; fn remove_member(m: u32, ) -> Weight; @@ -60,299 +61,299 @@ pub trait WeightInfo { fn clear_prime() -> Weight; } -/// Weights for `pallet_membership` using the Substrate node and recommended hardware. +/// Weights for pallet_membership using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `TechnicalMembership::Members` (r:1 w:1) - /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) - /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalCommittee::Members` (r:0 w:1) - /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) - /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `m` is `[1, 99]`. fn add_member(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `207 + m * (64 ±0)` + // Measured: `208 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 12_126_000 picoseconds. - Weight::from_parts(13_085_583, 4687) - // Standard Error: 659 - .saturating_add(Weight::from_parts(36_103, 0).saturating_mul(m.into())) + // Minimum execution time: 17_040_000 picoseconds. + Weight::from_parts(18_344_571, 4687) + // Standard Error: 847 + .saturating_add(Weight::from_parts(50_842, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: `TechnicalMembership::Members` (r:1 w:1) - /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) - /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalMembership::Prime` (r:1 w:0) - /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Members` (r:0 w:1) - /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) - /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:0) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `m` is `[2, 100]`. fn remove_member(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `311 + m * (64 ±0)` + // Measured: `312 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 14_571_000 picoseconds. - Weight::from_parts(15_532_232, 4687) - // Standard Error: 531 - .saturating_add(Weight::from_parts(35_757, 0).saturating_mul(m.into())) + // Minimum execution time: 20_088_000 picoseconds. + Weight::from_parts(21_271_384, 4687) + // Standard Error: 786 + .saturating_add(Weight::from_parts(44_806, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: `TechnicalMembership::Members` (r:1 w:1) - /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) - /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalMembership::Prime` (r:1 w:0) - /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Members` (r:0 w:1) - /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) - /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:0) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `m` is `[2, 100]`. fn swap_member(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `311 + m * (64 ±0)` + // Measured: `312 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 14_833_000 picoseconds. - Weight::from_parts(15_657_084, 4687) - // Standard Error: 650 - .saturating_add(Weight::from_parts(44_467, 0).saturating_mul(m.into())) + // Minimum execution time: 20_308_000 picoseconds. + Weight::from_parts(21_469_843, 4687) + // Standard Error: 782 + .saturating_add(Weight::from_parts(56_893, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: `TechnicalMembership::Members` (r:1 w:1) - /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) - /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalMembership::Prime` (r:1 w:0) - /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Members` (r:0 w:1) - /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) - /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:0) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `m` is `[1, 100]`. fn reset_members(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `311 + m * (64 ±0)` + // Measured: `312 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 14_629_000 picoseconds. - Weight::from_parts(15_578_203, 4687) - // Standard Error: 910 - .saturating_add(Weight::from_parts(145_101, 0).saturating_mul(m.into())) + // Minimum execution time: 19_464_000 picoseconds. + Weight::from_parts(21_223_702, 4687) + // Standard Error: 1_068 + .saturating_add(Weight::from_parts(165_438, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: `TechnicalMembership::Members` (r:1 w:1) - /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) - /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalMembership::Prime` (r:1 w:1) - /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Members` (r:0 w:1) - /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) - /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:1) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `m` is `[1, 100]`. fn change_key(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `311 + m * (64 ±0)` + // Measured: `312 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 15_218_000 picoseconds. - Weight::from_parts(16_388_690, 4687) - // Standard Error: 626 - .saturating_add(Weight::from_parts(46_204, 0).saturating_mul(m.into())) + // Minimum execution time: 20_965_000 picoseconds. + Weight::from_parts(22_551_007, 4687) + // Standard Error: 860 + .saturating_add(Weight::from_parts(52_397, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: `TechnicalMembership::Members` (r:1 w:0) - /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) - /// Storage: `TechnicalMembership::Prime` (r:0 w:1) - /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) - /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: TechnicalMembership Members (r:1 w:0) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalMembership Prime (r:0 w:1) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `m` is `[1, 100]`. fn set_prime(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `31 + m * (32 ±0)` + // Measured: `32 + m * (32 ±0)` // Estimated: `4687 + m * (32 ±0)` - // Minimum execution time: 5_954_000 picoseconds. - Weight::from_parts(6_544_638, 4687) - // Standard Error: 346 - .saturating_add(Weight::from_parts(17_638, 0).saturating_mul(m.into())) + // Minimum execution time: 7_481_000 picoseconds. + Weight::from_parts(7_959_053, 4687) + // Standard Error: 364 + .saturating_add(Weight::from_parts(18_653, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) } - /// Storage: `TechnicalMembership::Prime` (r:0 w:1) - /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) - /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: TechnicalMembership Prime (r:0 w:1) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) fn clear_prime() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_569_000 picoseconds. - Weight::from_parts(2_776_000, 0) + // Minimum execution time: 3_373_000 picoseconds. + Weight::from_parts(3_750_452, 0) .saturating_add(T::DbWeight::get().writes(2_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `TechnicalMembership::Members` (r:1 w:1) - /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) - /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalCommittee::Members` (r:0 w:1) - /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) - /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `m` is `[1, 99]`. fn add_member(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `207 + m * (64 ±0)` + // Measured: `208 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 12_126_000 picoseconds. - Weight::from_parts(13_085_583, 4687) - // Standard Error: 659 - .saturating_add(Weight::from_parts(36_103, 0).saturating_mul(m.into())) + // Minimum execution time: 17_040_000 picoseconds. + Weight::from_parts(18_344_571, 4687) + // Standard Error: 847 + .saturating_add(Weight::from_parts(50_842, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: `TechnicalMembership::Members` (r:1 w:1) - /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) - /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalMembership::Prime` (r:1 w:0) - /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Members` (r:0 w:1) - /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) - /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:0) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `m` is `[2, 100]`. fn remove_member(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `311 + m * (64 ±0)` + // Measured: `312 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 14_571_000 picoseconds. - Weight::from_parts(15_532_232, 4687) - // Standard Error: 531 - .saturating_add(Weight::from_parts(35_757, 0).saturating_mul(m.into())) + // Minimum execution time: 20_088_000 picoseconds. + Weight::from_parts(21_271_384, 4687) + // Standard Error: 786 + .saturating_add(Weight::from_parts(44_806, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: `TechnicalMembership::Members` (r:1 w:1) - /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) - /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalMembership::Prime` (r:1 w:0) - /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Members` (r:0 w:1) - /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) - /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:0) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `m` is `[2, 100]`. fn swap_member(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `311 + m * (64 ±0)` + // Measured: `312 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 14_833_000 picoseconds. - Weight::from_parts(15_657_084, 4687) - // Standard Error: 650 - .saturating_add(Weight::from_parts(44_467, 0).saturating_mul(m.into())) + // Minimum execution time: 20_308_000 picoseconds. + Weight::from_parts(21_469_843, 4687) + // Standard Error: 782 + .saturating_add(Weight::from_parts(56_893, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: `TechnicalMembership::Members` (r:1 w:1) - /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) - /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalMembership::Prime` (r:1 w:0) - /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Members` (r:0 w:1) - /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) - /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:0) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `m` is `[1, 100]`. fn reset_members(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `311 + m * (64 ±0)` + // Measured: `312 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 14_629_000 picoseconds. - Weight::from_parts(15_578_203, 4687) - // Standard Error: 910 - .saturating_add(Weight::from_parts(145_101, 0).saturating_mul(m.into())) + // Minimum execution time: 19_464_000 picoseconds. + Weight::from_parts(21_223_702, 4687) + // Standard Error: 1_068 + .saturating_add(Weight::from_parts(165_438, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: `TechnicalMembership::Members` (r:1 w:1) - /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Proposals` (r:1 w:0) - /// Proof: `TechnicalCommittee::Proposals` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalMembership::Prime` (r:1 w:1) - /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Members` (r:0 w:1) - /// Proof: `TechnicalCommittee::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) - /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: TechnicalMembership Members (r:1 w:1) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Proposals (r:1 w:0) + /// Proof Skipped: TechnicalCommittee Proposals (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalMembership Prime (r:1 w:1) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Members (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `m` is `[1, 100]`. fn change_key(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `311 + m * (64 ±0)` + // Measured: `312 + m * (64 ±0)` // Estimated: `4687 + m * (64 ±0)` - // Minimum execution time: 15_218_000 picoseconds. - Weight::from_parts(16_388_690, 4687) - // Standard Error: 626 - .saturating_add(Weight::from_parts(46_204, 0).saturating_mul(m.into())) + // Minimum execution time: 20_965_000 picoseconds. + Weight::from_parts(22_551_007, 4687) + // Standard Error: 860 + .saturating_add(Weight::from_parts(52_397, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(m.into())) } - /// Storage: `TechnicalMembership::Members` (r:1 w:0) - /// Proof: `TechnicalMembership::Members` (`max_values`: Some(1), `max_size`: Some(3202), added: 3697, mode: `MaxEncodedLen`) - /// Storage: `TechnicalMembership::Prime` (r:0 w:1) - /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) - /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: TechnicalMembership Members (r:1 w:0) + /// Proof: TechnicalMembership Members (max_values: Some(1), max_size: Some(3202), added: 3697, mode: MaxEncodedLen) + /// Storage: TechnicalMembership Prime (r:0 w:1) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) /// The range of component `m` is `[1, 100]`. fn set_prime(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `31 + m * (32 ±0)` + // Measured: `32 + m * (32 ±0)` // Estimated: `4687 + m * (32 ±0)` - // Minimum execution time: 5_954_000 picoseconds. - Weight::from_parts(6_544_638, 4687) - // Standard Error: 346 - .saturating_add(Weight::from_parts(17_638, 0).saturating_mul(m.into())) + // Minimum execution time: 7_481_000 picoseconds. + Weight::from_parts(7_959_053, 4687) + // Standard Error: 364 + .saturating_add(Weight::from_parts(18_653, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(m.into())) } - /// Storage: `TechnicalMembership::Prime` (r:0 w:1) - /// Proof: `TechnicalMembership::Prime` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `TechnicalCommittee::Prime` (r:0 w:1) - /// Proof: `TechnicalCommittee::Prime` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: TechnicalMembership Prime (r:0 w:1) + /// Proof: TechnicalMembership Prime (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TechnicalCommittee Prime (r:0 w:1) + /// Proof Skipped: TechnicalCommittee Prime (max_values: Some(1), max_size: None, mode: Measured) fn clear_prime() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_569_000 picoseconds. - Weight::from_parts(2_776_000, 0) + // Minimum execution time: 3_373_000 picoseconds. + Weight::from_parts(3_750_452, 0) .saturating_add(RocksDbWeight::get().writes(2_u64)) } } diff --git a/substrate/frame/message-queue/src/weights.rs b/substrate/frame/message-queue/src/weights.rs index 001e2834e1c..e86f23e274f 100644 --- a/substrate/frame/message-queue/src/weights.rs +++ b/substrate/frame/message-queue/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_message_queue` +//! Autogenerated weights for pallet_message_queue //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/message-queue/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/message-queue/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_message_queue`. +/// Weight functions needed for pallet_message_queue. pub trait WeightInfo { fn ready_ring_knit() -> Weight; fn ready_ring_unknit() -> Weight; @@ -63,256 +64,246 @@ pub trait WeightInfo { fn execute_overweight_page_updated() -> Weight; } -/// Weights for `pallet_message_queue` using the Substrate node and recommended hardware. +/// Weights for pallet_message_queue using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `MessageQueue::ServiceHead` (r:1 w:0) - /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::BookStateFor` (r:2 w:2) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: MessageQueue ServiceHead (r:1 w:0) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:2 w:2) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) fn ready_ring_knit() -> Weight { // Proof Size summary in bytes: - // Measured: `301` + // Measured: `267` // Estimated: `6038` - // Minimum execution time: 11_563_000 picoseconds. - Weight::from_parts(11_956_000, 6038) + // Minimum execution time: 12_025_000 picoseconds. + Weight::from_parts(12_597_000, 6038) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `MessageQueue::BookStateFor` (r:2 w:2) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::ServiceHead` (r:1 w:1) - /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: MessageQueue BookStateFor (r:2 w:2) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) fn ready_ring_unknit() -> Weight { // Proof Size summary in bytes: - // Measured: `301` + // Measured: `267` // Estimated: `6038` - // Minimum execution time: 10_263_000 picoseconds. - Weight::from_parts(10_638_000, 6038) + // Minimum execution time: 11_563_000 picoseconds. + Weight::from_parts(11_785_000, 6038) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) fn service_queue_base() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3514` - // Minimum execution time: 4_335_000 picoseconds. - Weight::from_parts(4_552_000, 3514) + // Minimum execution time: 4_467_000 picoseconds. + Weight::from_parts(4_655_000, 3514) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `MessageQueue::Pages` (r:1 w:1) - /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) fn service_page_base_completion() -> Weight { // Proof Size summary in bytes: // Measured: `147` // Estimated: `69049` - // Minimum execution time: 6_016_000 picoseconds. - Weight::from_parts(6_224_000, 69049) + // Minimum execution time: 6_103_000 picoseconds. + Weight::from_parts(6_254_000, 69049) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `MessageQueue::Pages` (r:1 w:1) - /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) fn service_page_base_no_completion() -> Weight { // Proof Size summary in bytes: // Measured: `147` // Estimated: `69049` - // Minimum execution time: 6_183_000 picoseconds. - Weight::from_parts(6_348_000, 69049) + // Minimum execution time: 6_320_000 picoseconds. + Weight::from_parts(6_565_000, 69049) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `MessageQueue::BookStateFor` (r:0 w:1) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::Pages` (r:0 w:1) - /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) fn service_page_item() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 112_864_000 picoseconds. - Weight::from_parts(114_269_000, 0) - .saturating_add(T::DbWeight::get().writes(2_u64)) + // Minimum execution time: 66_062_000 picoseconds. + Weight::from_parts(66_371_000, 0) } - /// Storage: `MessageQueue::ServiceHead` (r:1 w:1) - /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::BookStateFor` (r:1 w:0) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:1 w:0) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) fn bump_service_head() -> Weight { // Proof Size summary in bytes: - // Measured: `246` + // Measured: `174` // Estimated: `3514` - // Minimum execution time: 6_665_000 picoseconds. - Weight::from_parts(7_108_000, 3514) + // Minimum execution time: 6_788_000 picoseconds. + Weight::from_parts(7_176_000, 3514) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::Pages` (r:1 w:1) - /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) fn reap_page() -> Weight { // Proof Size summary in bytes: // Measured: `65744` // Estimated: `69049` - // Minimum execution time: 51_420_000 picoseconds. - Weight::from_parts(52_252_000, 69049) + // Minimum execution time: 52_865_000 picoseconds. + Weight::from_parts(54_398_000, 69049) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::Pages` (r:1 w:1) - /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) fn execute_overweight_page_removed() -> Weight { // Proof Size summary in bytes: // Measured: `65744` // Estimated: `69049` - // Minimum execution time: 71_195_000 picoseconds. - Weight::from_parts(72_981_000, 69049) + // Minimum execution time: 69_168_000 picoseconds. + Weight::from_parts(70_560_000, 69049) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::Pages` (r:1 w:1) - /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) fn execute_overweight_page_updated() -> Weight { // Proof Size summary in bytes: // Measured: `65744` // Estimated: `69049` - // Minimum execution time: 83_238_000 picoseconds. - Weight::from_parts(84_422_000, 69049) + // Minimum execution time: 80_947_000 picoseconds. + Weight::from_parts(82_715_000, 69049) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `MessageQueue::ServiceHead` (r:1 w:0) - /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::BookStateFor` (r:2 w:2) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: MessageQueue ServiceHead (r:1 w:0) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:2 w:2) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) fn ready_ring_knit() -> Weight { // Proof Size summary in bytes: - // Measured: `301` + // Measured: `267` // Estimated: `6038` - // Minimum execution time: 11_563_000 picoseconds. - Weight::from_parts(11_956_000, 6038) + // Minimum execution time: 12_025_000 picoseconds. + Weight::from_parts(12_597_000, 6038) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `MessageQueue::BookStateFor` (r:2 w:2) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::ServiceHead` (r:1 w:1) - /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: MessageQueue BookStateFor (r:2 w:2) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) fn ready_ring_unknit() -> Weight { // Proof Size summary in bytes: - // Measured: `301` + // Measured: `267` // Estimated: `6038` - // Minimum execution time: 10_263_000 picoseconds. - Weight::from_parts(10_638_000, 6038) + // Minimum execution time: 11_563_000 picoseconds. + Weight::from_parts(11_785_000, 6038) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) fn service_queue_base() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3514` - // Minimum execution time: 4_335_000 picoseconds. - Weight::from_parts(4_552_000, 3514) + // Minimum execution time: 4_467_000 picoseconds. + Weight::from_parts(4_655_000, 3514) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `MessageQueue::Pages` (r:1 w:1) - /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) fn service_page_base_completion() -> Weight { // Proof Size summary in bytes: // Measured: `147` // Estimated: `69049` - // Minimum execution time: 6_016_000 picoseconds. - Weight::from_parts(6_224_000, 69049) + // Minimum execution time: 6_103_000 picoseconds. + Weight::from_parts(6_254_000, 69049) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `MessageQueue::Pages` (r:1 w:1) - /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) fn service_page_base_no_completion() -> Weight { // Proof Size summary in bytes: // Measured: `147` // Estimated: `69049` - // Minimum execution time: 6_183_000 picoseconds. - Weight::from_parts(6_348_000, 69049) + // Minimum execution time: 6_320_000 picoseconds. + Weight::from_parts(6_565_000, 69049) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `MessageQueue::BookStateFor` (r:0 w:1) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::Pages` (r:0 w:1) - /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) fn service_page_item() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 112_864_000 picoseconds. - Weight::from_parts(114_269_000, 0) - .saturating_add(RocksDbWeight::get().writes(2_u64)) + // Minimum execution time: 66_062_000 picoseconds. + Weight::from_parts(66_371_000, 0) } - /// Storage: `MessageQueue::ServiceHead` (r:1 w:1) - /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::BookStateFor` (r:1 w:0) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) + /// Storage: MessageQueue ServiceHead (r:1 w:1) + /// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: MessageQueue BookStateFor (r:1 w:0) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) fn bump_service_head() -> Weight { // Proof Size summary in bytes: - // Measured: `246` + // Measured: `174` // Estimated: `3514` - // Minimum execution time: 6_665_000 picoseconds. - Weight::from_parts(7_108_000, 3514) + // Minimum execution time: 6_788_000 picoseconds. + Weight::from_parts(7_176_000, 3514) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::Pages` (r:1 w:1) - /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) fn reap_page() -> Weight { // Proof Size summary in bytes: // Measured: `65744` // Estimated: `69049` - // Minimum execution time: 51_420_000 picoseconds. - Weight::from_parts(52_252_000, 69049) + // Minimum execution time: 52_865_000 picoseconds. + Weight::from_parts(54_398_000, 69049) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::Pages` (r:1 w:1) - /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) fn execute_overweight_page_removed() -> Weight { // Proof Size summary in bytes: // Measured: `65744` // Estimated: `69049` - // Minimum execution time: 71_195_000 picoseconds. - Weight::from_parts(72_981_000, 69049) + // Minimum execution time: 69_168_000 picoseconds. + Weight::from_parts(70_560_000, 69049) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) - /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `MessageQueue::Pages` (r:1 w:1) - /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65584), added: 68059, mode: `MaxEncodedLen`) + /// Storage: MessageQueue BookStateFor (r:1 w:1) + /// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + /// Storage: MessageQueue Pages (r:1 w:1) + /// Proof: MessageQueue Pages (max_values: None, max_size: Some(65584), added: 68059, mode: MaxEncodedLen) fn execute_overweight_page_updated() -> Weight { // Proof Size summary in bytes: // Measured: `65744` // Estimated: `69049` - // Minimum execution time: 83_238_000 picoseconds. - Weight::from_parts(84_422_000, 69049) + // Minimum execution time: 80_947_000 picoseconds. + Weight::from_parts(82_715_000, 69049) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } diff --git a/substrate/frame/migrations/src/weights.rs b/substrate/frame/migrations/src/weights.rs index 9eca48ac3fd..c9b63258c44 100644 --- a/substrate/frame/migrations/src/weights.rs +++ b/substrate/frame/migrations/src/weights.rs @@ -17,29 +17,26 @@ //! Autogenerated weights for `pallet_migrations` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-04, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `loud1`, CPU: `AMD EPYC 7282 16-Core Processor` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate-node +// target/release/substrate-node // benchmark // pallet -// --chain=dev -// --steps=50 -// --repeat=20 -// --pallet=pallet_migrations -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --wasm-execution=compiled -// --heap-pages=4096 -// --output=./substrate/frame/migrations/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --chain +// dev +// --pallet +// pallet-migrations +// --extrinsic +// +// --output +// weight.rs +// --template +// ../../polkadot-sdk/substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -74,10 +71,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) fn onboard_new_mbms() -> Weight { // Proof Size summary in bytes: - // Measured: `276` + // Measured: `243` // Estimated: `67035` - // Minimum execution time: 7_932_000 picoseconds. - Weight::from_parts(8_428_000, 67035) + // Minimum execution time: 13_980_000 picoseconds. + Weight::from_parts(14_290_000, 67035) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -85,10 +82,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) fn progress_mbms_none() -> Weight { // Proof Size summary in bytes: - // Measured: `142` + // Measured: `109` // Estimated: `67035` - // Minimum execution time: 2_229_000 picoseconds. - Weight::from_parts(2_329_000, 67035) + // Minimum execution time: 3_770_000 picoseconds. + Weight::from_parts(4_001_000, 67035) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) @@ -99,8 +96,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `134` // Estimated: `3599` - // Minimum execution time: 6_051_000 picoseconds. - Weight::from_parts(6_483_000, 3599) + // Minimum execution time: 10_900_000 picoseconds. + Weight::from_parts(11_251_000, 3599) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -110,10 +107,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) fn exec_migration_skipped_historic() -> Weight { // Proof Size summary in bytes: - // Measured: `330` - // Estimated: `3795` - // Minimum execution time: 10_066_000 picoseconds. - Weight::from_parts(10_713_000, 3795) + // Measured: `297` + // Estimated: `3762` + // Minimum execution time: 17_891_000 picoseconds. + Weight::from_parts(18_501_000, 3762) .saturating_add(T::DbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) @@ -122,10 +119,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) fn exec_migration_advance() -> Weight { // Proof Size summary in bytes: - // Measured: `276` - // Estimated: `3741` - // Minimum execution time: 10_026_000 picoseconds. - Weight::from_parts(10_379_000, 3741) + // Measured: `243` + // Estimated: `3731` + // Minimum execution time: 18_271_000 picoseconds. + Weight::from_parts(18_740_000, 3731) .saturating_add(T::DbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) @@ -134,10 +131,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) fn exec_migration_complete() -> Weight { // Proof Size summary in bytes: - // Measured: `276` - // Estimated: `3741` - // Minimum execution time: 11_680_000 picoseconds. - Weight::from_parts(12_184_000, 3741) + // Measured: `243` + // Estimated: `3731` + // Minimum execution time: 21_241_000 picoseconds. + Weight::from_parts(21_911_000, 3731) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -149,10 +146,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) fn exec_migration_fail() -> Weight { // Proof Size summary in bytes: - // Measured: `276` - // Estimated: `3741` - // Minimum execution time: 12_334_000 picoseconds. - Weight::from_parts(12_899_000, 3741) + // Measured: `243` + // Estimated: `3731` + // Minimum execution time: 22_740_000 picoseconds. + Weight::from_parts(23_231_000, 3731) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -160,8 +157,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 187_000 picoseconds. - Weight::from_parts(209_000, 0) + // Minimum execution time: 440_000 picoseconds. + Weight::from_parts(500_000, 0) } /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) @@ -169,8 +166,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_688_000 picoseconds. - Weight::from_parts(2_874_000, 0) + // Minimum execution time: 5_751_000 picoseconds. + Weight::from_parts(5_950_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) @@ -179,8 +176,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_108_000 picoseconds. - Weight::from_parts(3_263_000, 0) + // Minimum execution time: 6_350_000 picoseconds. + Weight::from_parts(6_560_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) @@ -189,10 +186,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) fn force_onboard_mbms() -> Weight { // Proof Size summary in bytes: - // Measured: `251` + // Measured: `218` // Estimated: `67035` - // Minimum execution time: 5_993_000 picoseconds. - Weight::from_parts(6_359_000, 67035) + // Minimum execution time: 11_121_000 picoseconds. + Weight::from_parts(11_530_000, 67035) .saturating_add(T::DbWeight::get().reads(2_u64)) } /// Storage: `MultiBlockMigrations::Historic` (r:256 w:256) @@ -200,12 +197,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 256]`. fn clear_historic(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1122 + n * (271 ±0)` + // Measured: `1089 + n * (271 ±0)` // Estimated: `3834 + n * (2740 ±0)` - // Minimum execution time: 16_003_000 picoseconds. - Weight::from_parts(14_453_014, 3834) - // Standard Error: 3_305 - .saturating_add(Weight::from_parts(1_325_026, 0).saturating_mul(n.into())) + // Minimum execution time: 21_891_000 picoseconds. + Weight::from_parts(18_572_306, 3834) + // Standard Error: 3_236 + .saturating_add(Weight::from_parts(1_648_429, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) @@ -221,10 +218,10 @@ impl WeightInfo for () { /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) fn onboard_new_mbms() -> Weight { // Proof Size summary in bytes: - // Measured: `276` + // Measured: `243` // Estimated: `67035` - // Minimum execution time: 7_932_000 picoseconds. - Weight::from_parts(8_428_000, 67035) + // Minimum execution time: 13_980_000 picoseconds. + Weight::from_parts(14_290_000, 67035) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -232,10 +229,10 @@ impl WeightInfo for () { /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) fn progress_mbms_none() -> Weight { // Proof Size summary in bytes: - // Measured: `142` + // Measured: `109` // Estimated: `67035` - // Minimum execution time: 2_229_000 picoseconds. - Weight::from_parts(2_329_000, 67035) + // Minimum execution time: 3_770_000 picoseconds. + Weight::from_parts(4_001_000, 67035) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) @@ -246,8 +243,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `134` // Estimated: `3599` - // Minimum execution time: 6_051_000 picoseconds. - Weight::from_parts(6_483_000, 3599) + // Minimum execution time: 10_900_000 picoseconds. + Weight::from_parts(11_251_000, 3599) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -257,10 +254,10 @@ impl WeightInfo for () { /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) fn exec_migration_skipped_historic() -> Weight { // Proof Size summary in bytes: - // Measured: `330` - // Estimated: `3795` - // Minimum execution time: 10_066_000 picoseconds. - Weight::from_parts(10_713_000, 3795) + // Measured: `297` + // Estimated: `3762` + // Minimum execution time: 17_891_000 picoseconds. + Weight::from_parts(18_501_000, 3762) .saturating_add(RocksDbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) @@ -269,10 +266,10 @@ impl WeightInfo for () { /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) fn exec_migration_advance() -> Weight { // Proof Size summary in bytes: - // Measured: `276` - // Estimated: `3741` - // Minimum execution time: 10_026_000 picoseconds. - Weight::from_parts(10_379_000, 3741) + // Measured: `243` + // Estimated: `3731` + // Minimum execution time: 18_271_000 picoseconds. + Weight::from_parts(18_740_000, 3731) .saturating_add(RocksDbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) @@ -281,10 +278,10 @@ impl WeightInfo for () { /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) fn exec_migration_complete() -> Weight { // Proof Size summary in bytes: - // Measured: `276` - // Estimated: `3741` - // Minimum execution time: 11_680_000 picoseconds. - Weight::from_parts(12_184_000, 3741) + // Measured: `243` + // Estimated: `3731` + // Minimum execution time: 21_241_000 picoseconds. + Weight::from_parts(21_911_000, 3731) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -296,10 +293,10 @@ impl WeightInfo for () { /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) fn exec_migration_fail() -> Weight { // Proof Size summary in bytes: - // Measured: `276` - // Estimated: `3741` - // Minimum execution time: 12_334_000 picoseconds. - Weight::from_parts(12_899_000, 3741) + // Measured: `243` + // Estimated: `3731` + // Minimum execution time: 22_740_000 picoseconds. + Weight::from_parts(23_231_000, 3731) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -307,8 +304,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 187_000 picoseconds. - Weight::from_parts(209_000, 0) + // Minimum execution time: 440_000 picoseconds. + Weight::from_parts(500_000, 0) } /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) @@ -316,8 +313,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_688_000 picoseconds. - Weight::from_parts(2_874_000, 0) + // Minimum execution time: 5_751_000 picoseconds. + Weight::from_parts(5_950_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) @@ -326,8 +323,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_108_000 picoseconds. - Weight::from_parts(3_263_000, 0) + // Minimum execution time: 6_350_000 picoseconds. + Weight::from_parts(6_560_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) @@ -336,10 +333,10 @@ impl WeightInfo for () { /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) fn force_onboard_mbms() -> Weight { // Proof Size summary in bytes: - // Measured: `251` + // Measured: `218` // Estimated: `67035` - // Minimum execution time: 5_993_000 picoseconds. - Weight::from_parts(6_359_000, 67035) + // Minimum execution time: 11_121_000 picoseconds. + Weight::from_parts(11_530_000, 67035) .saturating_add(RocksDbWeight::get().reads(2_u64)) } /// Storage: `MultiBlockMigrations::Historic` (r:256 w:256) @@ -347,12 +344,12 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 256]`. fn clear_historic(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1122 + n * (271 ±0)` + // Measured: `1089 + n * (271 ±0)` // Estimated: `3834 + n * (2740 ±0)` - // Minimum execution time: 16_003_000 picoseconds. - Weight::from_parts(14_453_014, 3834) - // Standard Error: 3_305 - .saturating_add(Weight::from_parts(1_325_026, 0).saturating_mul(n.into())) + // Minimum execution time: 21_891_000 picoseconds. + Weight::from_parts(18_572_306, 3834) + // Standard Error: 3_236 + .saturating_add(Weight::from_parts(1_648_429, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into()))) diff --git a/substrate/frame/multisig/src/weights.rs b/substrate/frame/multisig/src/weights.rs index 4cbe7bb03b7..7b87d258d38 100644 --- a/substrate/frame/multisig/src/weights.rs +++ b/substrate/frame/multisig/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_multisig` +//! Autogenerated weights for pallet_multisig //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/multisig/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/multisig/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_multisig`. +/// Weight functions needed for pallet_multisig. pub trait WeightInfo { fn as_multi_threshold_1(z: u32, ) -> Weight; fn as_multi_create(s: u32, z: u32, ) -> Weight; @@ -60,238 +61,220 @@ pub trait WeightInfo { fn cancel_as_multi(s: u32, ) -> Weight; } -/// Weights for `pallet_multisig` using the Substrate node and recommended hardware. +/// Weights for pallet_multisig using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `z` is `[0, 10000]`. fn as_multi_threshold_1(z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `145` - // Estimated: `3997` - // Minimum execution time: 18_893_000 picoseconds. - Weight::from_parts(20_278_307, 3997) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_452_000 picoseconds. + Weight::from_parts(14_425_869, 0) // Standard Error: 4 - .saturating_add(Weight::from_parts(488, 0).saturating_mul(z.into())) - .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(Weight::from_parts(493, 0).saturating_mul(z.into())) } - /// Storage: `Multisig::Multisigs` (r:1 w:1) - /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_create(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `301 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 39_478_000 picoseconds. - Weight::from_parts(29_195_487, 6811) - // Standard Error: 739 - .saturating_add(Weight::from_parts(118_766, 0).saturating_mul(s.into())) - // Standard Error: 7 - .saturating_add(Weight::from_parts(1_511, 0).saturating_mul(z.into())) + // Minimum execution time: 46_012_000 picoseconds. + Weight::from_parts(34_797_344, 6811) + // Standard Error: 833 + .saturating_add(Weight::from_parts(127_671, 0).saturating_mul(s.into())) + // Standard Error: 8 + .saturating_add(Weight::from_parts(1_498, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Multisig::Multisigs` (r:1 w:1) - /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) /// The range of component `s` is `[3, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_approve(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `320` // Estimated: `6811` - // Minimum execution time: 26_401_000 picoseconds. - Weight::from_parts(17_277_296, 6811) - // Standard Error: 492 - .saturating_add(Weight::from_parts(101_763, 0).saturating_mul(s.into())) - // Standard Error: 4 - .saturating_add(Weight::from_parts(1_486, 0).saturating_mul(z.into())) + // Minimum execution time: 29_834_000 picoseconds. + Weight::from_parts(20_189_154, 6811) + // Standard Error: 637 + .saturating_add(Weight::from_parts(110_080, 0).saturating_mul(s.into())) + // Standard Error: 6 + .saturating_add(Weight::from_parts(1_483, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Multisig::Multisigs` (r:1 w:1) - /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_complete(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `571 + s * (33 ±0)` + // Measured: `426 + s * (33 ±0)` // Estimated: `6811` - // Minimum execution time: 52_430_000 picoseconds. - Weight::from_parts(40_585_478, 6811) - // Standard Error: 1_240 - .saturating_add(Weight::from_parts(161_405, 0).saturating_mul(s.into())) + // Minimum execution time: 51_464_000 picoseconds. + Weight::from_parts(39_246_644, 6811) + // Standard Error: 1_251 + .saturating_add(Weight::from_parts(143_313, 0).saturating_mul(s.into())) // Standard Error: 12 - .saturating_add(Weight::from_parts(1_547, 0).saturating_mul(z.into())) - .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(Weight::from_parts(1_523, 0).saturating_mul(z.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Multisig::Multisigs` (r:1 w:1) - /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) /// The range of component `s` is `[2, 100]`. fn approve_as_multi_create(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `301 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 27_797_000 picoseconds. - Weight::from_parts(29_064_584, 6811) - // Standard Error: 817 - .saturating_add(Weight::from_parts(108_179, 0).saturating_mul(s.into())) + // Minimum execution time: 33_275_000 picoseconds. + Weight::from_parts(34_073_221, 6811) + // Standard Error: 1_163 + .saturating_add(Weight::from_parts(124_815, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Multisig::Multisigs` (r:1 w:1) - /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) /// The range of component `s` is `[2, 100]`. fn approve_as_multi_approve(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `320` // Estimated: `6811` - // Minimum execution time: 15_236_000 picoseconds. - Weight::from_parts(16_360_247, 6811) - // Standard Error: 584 - .saturating_add(Weight::from_parts(94_917, 0).saturating_mul(s.into())) + // Minimum execution time: 18_411_000 picoseconds. + Weight::from_parts(19_431_787, 6811) + // Standard Error: 694 + .saturating_add(Weight::from_parts(107_220, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Multisig::Multisigs` (r:1 w:1) - /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) /// The range of component `s` is `[2, 100]`. fn cancel_as_multi(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `492 + s * (1 ±0)` // Estimated: `6811` - // Minimum execution time: 28_730_000 picoseconds. - Weight::from_parts(30_056_661, 6811) - // Standard Error: 792 - .saturating_add(Weight::from_parts(108_212, 0).saturating_mul(s.into())) + // Minimum execution time: 33_985_000 picoseconds. + Weight::from_parts(35_547_970, 6811) + // Standard Error: 1_135 + .saturating_add(Weight::from_parts(116_537, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `z` is `[0, 10000]`. fn as_multi_threshold_1(z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `145` - // Estimated: `3997` - // Minimum execution time: 18_893_000 picoseconds. - Weight::from_parts(20_278_307, 3997) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 13_452_000 picoseconds. + Weight::from_parts(14_425_869, 0) // Standard Error: 4 - .saturating_add(Weight::from_parts(488, 0).saturating_mul(z.into())) - .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(Weight::from_parts(493, 0).saturating_mul(z.into())) } - /// Storage: `Multisig::Multisigs` (r:1 w:1) - /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_create(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `301 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 39_478_000 picoseconds. - Weight::from_parts(29_195_487, 6811) - // Standard Error: 739 - .saturating_add(Weight::from_parts(118_766, 0).saturating_mul(s.into())) - // Standard Error: 7 - .saturating_add(Weight::from_parts(1_511, 0).saturating_mul(z.into())) + // Minimum execution time: 46_012_000 picoseconds. + Weight::from_parts(34_797_344, 6811) + // Standard Error: 833 + .saturating_add(Weight::from_parts(127_671, 0).saturating_mul(s.into())) + // Standard Error: 8 + .saturating_add(Weight::from_parts(1_498, 0).saturating_mul(z.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Multisig::Multisigs` (r:1 w:1) - /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) /// The range of component `s` is `[3, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_approve(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `320` // Estimated: `6811` - // Minimum execution time: 26_401_000 picoseconds. - Weight::from_parts(17_277_296, 6811) - // Standard Error: 492 - .saturating_add(Weight::from_parts(101_763, 0).saturating_mul(s.into())) - // Standard Error: 4 - .saturating_add(Weight::from_parts(1_486, 0).saturating_mul(z.into())) + // Minimum execution time: 29_834_000 picoseconds. + Weight::from_parts(20_189_154, 6811) + // Standard Error: 637 + .saturating_add(Weight::from_parts(110_080, 0).saturating_mul(s.into())) + // Standard Error: 6 + .saturating_add(Weight::from_parts(1_483, 0).saturating_mul(z.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Multisig::Multisigs` (r:1 w:1) - /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. fn as_multi_complete(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `571 + s * (33 ±0)` + // Measured: `426 + s * (33 ±0)` // Estimated: `6811` - // Minimum execution time: 52_430_000 picoseconds. - Weight::from_parts(40_585_478, 6811) - // Standard Error: 1_240 - .saturating_add(Weight::from_parts(161_405, 0).saturating_mul(s.into())) + // Minimum execution time: 51_464_000 picoseconds. + Weight::from_parts(39_246_644, 6811) + // Standard Error: 1_251 + .saturating_add(Weight::from_parts(143_313, 0).saturating_mul(s.into())) // Standard Error: 12 - .saturating_add(Weight::from_parts(1_547, 0).saturating_mul(z.into())) - .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(Weight::from_parts(1_523, 0).saturating_mul(z.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Multisig::Multisigs` (r:1 w:1) - /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) /// The range of component `s` is `[2, 100]`. fn approve_as_multi_create(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `301 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 27_797_000 picoseconds. - Weight::from_parts(29_064_584, 6811) - // Standard Error: 817 - .saturating_add(Weight::from_parts(108_179, 0).saturating_mul(s.into())) + // Minimum execution time: 33_275_000 picoseconds. + Weight::from_parts(34_073_221, 6811) + // Standard Error: 1_163 + .saturating_add(Weight::from_parts(124_815, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Multisig::Multisigs` (r:1 w:1) - /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) /// The range of component `s` is `[2, 100]`. fn approve_as_multi_approve(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `320` // Estimated: `6811` - // Minimum execution time: 15_236_000 picoseconds. - Weight::from_parts(16_360_247, 6811) - // Standard Error: 584 - .saturating_add(Weight::from_parts(94_917, 0).saturating_mul(s.into())) + // Minimum execution time: 18_411_000 picoseconds. + Weight::from_parts(19_431_787, 6811) + // Standard Error: 694 + .saturating_add(Weight::from_parts(107_220, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Multisig::Multisigs` (r:1 w:1) - /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) + /// Storage: Multisig Multisigs (r:1 w:1) + /// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen) /// The range of component `s` is `[2, 100]`. fn cancel_as_multi(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `492 + s * (1 ±0)` // Estimated: `6811` - // Minimum execution time: 28_730_000 picoseconds. - Weight::from_parts(30_056_661, 6811) - // Standard Error: 792 - .saturating_add(Weight::from_parts(108_212, 0).saturating_mul(s.into())) + // Minimum execution time: 33_985_000 picoseconds. + Weight::from_parts(35_547_970, 6811) + // Standard Error: 1_135 + .saturating_add(Weight::from_parts(116_537, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/nft-fractionalization/src/weights.rs b/substrate/frame/nft-fractionalization/src/weights.rs index 07872ebaea9..ebb4aa0fbcf 100644 --- a/substrate/frame/nft-fractionalization/src/weights.rs +++ b/substrate/frame/nft-fractionalization/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_nft_fractionalization` +//! Autogenerated weights for pallet_nft_fractionalization //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/nft-fractionalization/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/nft-fractionalization/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,136 +50,136 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_nft_fractionalization`. +/// Weight functions needed for pallet_nft_fractionalization. pub trait WeightInfo { fn fractionalize() -> Weight; fn unify() -> Weight; } -/// Weights for `pallet_nft_fractionalization` using the Substrate node and recommended hardware. +/// Weights for pallet_nft_fractionalization using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Nfts::Item` (r:1 w:0) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:1 w:1) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Assets::Metadata` (r:1 w:1) - /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) - /// Storage: `NftFractionalization::NftToAsset` (r:0 w:1) - /// Proof: `NftFractionalization::NftToAsset` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) + /// Storage: Nfts Item (r:1 w:0) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:1 w:1) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Assets Metadata (r:1 w:1) + /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: NftFractionalization NftToAsset (r:0 w:1) + /// Proof: NftFractionalization NftToAsset (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) fn fractionalize() -> Weight { // Proof Size summary in bytes: // Measured: `609` // Estimated: `4326` - // Minimum execution time: 164_764_000 picoseconds. - Weight::from_parts(168_243_000, 4326) + // Minimum execution time: 187_416_000 picoseconds. + Weight::from_parts(191_131_000, 4326) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(8_u64)) } - /// Storage: `NftFractionalization::NftToAsset` (r:1 w:1) - /// Proof: `NftFractionalization::NftToAsset` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:1 w:1) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Account` (r:0 w:1) - /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemPriceOf` (r:0 w:1) - /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) - /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) - /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) + /// Storage: NftFractionalization NftToAsset (r:1 w:1) + /// Proof: NftFractionalization NftToAsset (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:1 w:1) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:0) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) + /// Storage: Nfts Account (r:0 w:1) + /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: Nfts ItemPriceOf (r:0 w:1) + /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) + /// Storage: Nfts PendingSwapOf (r:0 w:1) + /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) fn unify() -> Weight { // Proof Size summary in bytes: // Measured: `1422` // Estimated: `4326` - // Minimum execution time: 120_036_000 picoseconds. - Weight::from_parts(123_550_000, 4326) + // Minimum execution time: 134_159_000 picoseconds. + Weight::from_parts(136_621_000, 4326) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(10_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Nfts::Item` (r:1 w:0) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:1 w:1) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Assets::Metadata` (r:1 w:1) - /// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) - /// Storage: `NftFractionalization::NftToAsset` (r:0 w:1) - /// Proof: `NftFractionalization::NftToAsset` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) + /// Storage: Nfts Item (r:1 w:0) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:1 w:1) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Assets Metadata (r:1 w:1) + /// Proof: Assets Metadata (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: NftFractionalization NftToAsset (r:0 w:1) + /// Proof: NftFractionalization NftToAsset (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) fn fractionalize() -> Weight { // Proof Size summary in bytes: // Measured: `609` // Estimated: `4326` - // Minimum execution time: 164_764_000 picoseconds. - Weight::from_parts(168_243_000, 4326) + // Minimum execution time: 187_416_000 picoseconds. + Weight::from_parts(191_131_000, 4326) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(8_u64)) } - /// Storage: `NftFractionalization::NftToAsset` (r:1 w:1) - /// Proof: `NftFractionalization::NftToAsset` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:1 w:1) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Account` (r:0 w:1) - /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemPriceOf` (r:0 w:1) - /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) - /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) - /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) + /// Storage: NftFractionalization NftToAsset (r:1 w:1) + /// Proof: NftFractionalization NftToAsset (max_values: None, max_size: Some(92), added: 2567, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:1 w:1) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:0) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) + /// Storage: Nfts Account (r:0 w:1) + /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: Nfts ItemPriceOf (r:0 w:1) + /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) + /// Storage: Nfts PendingSwapOf (r:0 w:1) + /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) fn unify() -> Weight { // Proof Size summary in bytes: // Measured: `1422` // Estimated: `4326` - // Minimum execution time: 120_036_000 picoseconds. - Weight::from_parts(123_550_000, 4326) + // Minimum execution time: 134_159_000 picoseconds. + Weight::from_parts(136_621_000, 4326) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(10_u64)) } diff --git a/substrate/frame/nfts/src/weights.rs b/substrate/frame/nfts/src/weights.rs index 4fcc1e601f4..6b8c577bb12 100644 --- a/substrate/frame/nfts/src/weights.rs +++ b/substrate/frame/nfts/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_nfts` +//! Autogenerated weights for pallet_nfts //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -37,9 +37,9 @@ // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/nfts/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/nfts/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +49,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_nfts`. +/// Weight functions needed for pallet_nfts. pub trait WeightInfo { fn create() -> Weight; fn force_create() -> Weight; @@ -92,568 +92,564 @@ pub trait WeightInfo { fn set_attributes_pre_signed(n: u32, ) -> Weight; } -/// Weights for `pallet_nfts` using the Substrate node and recommended hardware. +/// Weights for pallet_nfts using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Nfts::NextCollectionId` (r:1 w:1) - /// Proof: `Nfts::NextCollectionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionRoleOf` (r:0 w:1) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:0 w:1) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionAccount` (r:0 w:1) - /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: Nfts NextCollectionId (r:1 w:1) + /// Proof: Nfts NextCollectionId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionRoleOf (r:0 w:1) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:0 w:1) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts CollectionAccount (r:0 w:1) + /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) fn create() -> Weight { // Proof Size summary in bytes: // Measured: `216` // Estimated: `3549` - // Minimum execution time: 34_035_000 picoseconds. - Weight::from_parts(35_228_000, 3549) + // Minimum execution time: 40_489_000 picoseconds. + Weight::from_parts(41_320_000, 3549) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: `Nfts::NextCollectionId` (r:1 w:1) - /// Proof: `Nfts::NextCollectionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionRoleOf` (r:0 w:1) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:0 w:1) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionAccount` (r:0 w:1) - /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: Nfts NextCollectionId (r:1 w:1) + /// Proof: Nfts NextCollectionId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionRoleOf (r:0 w:1) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:0 w:1) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts CollectionAccount (r:0 w:1) + /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) fn force_create() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3549` - // Minimum execution time: 19_430_000 picoseconds. - Weight::from_parts(20_054_000, 3549) + // Minimum execution time: 23_257_000 picoseconds. + Weight::from_parts(23_770_000, 3549) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemMetadataOf` (r:1 w:0) - /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:1) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:1001 w:1000) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1000 w:1000) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionMetadataOf` (r:0 w:1) - /// Proof: `Nfts::CollectionMetadataOf` (`max_values`: None, `max_size`: Some(294), added: 2769, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:0 w:1) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionAccount` (r:0 w:1) - /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts ItemMetadataOf (r:1 w:0) + /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: Nfts CollectionRoleOf (r:1 w:1) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:1001 w:1000) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1000 w:1000) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts CollectionMetadataOf (r:0 w:1) + /// Proof: Nfts CollectionMetadataOf (max_values: None, max_size: Some(87), added: 2562, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:0 w:1) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts CollectionAccount (r:0 w:1) + /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) /// The range of component `m` is `[0, 1000]`. /// The range of component `c` is `[0, 1000]`. /// The range of component `a` is `[0, 1000]`. fn destroy(_m: u32, _c: u32, a: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `32204 + a * (366 ±0)` - // Estimated: `2523990 + a * (2954 ±0)` - // Minimum execution time: 1_249_733_000 picoseconds. - Weight::from_parts(1_293_703_849, 2523990) - // Standard Error: 4_764 - .saturating_add(Weight::from_parts(6_433_523, 0).saturating_mul(a.into())) + // Measured: `32220 + a * (332 ±0)` + // Estimated: `2523990 + a * (2921 ±0)` + // Minimum execution time: 1_310_198_000 picoseconds. + Weight::from_parts(1_479_261_043, 2523990) + // Standard Error: 4_415 + .saturating_add(Weight::from_parts(6_016_212, 0).saturating_mul(a.into())) .saturating_add(T::DbWeight::get().reads(1004_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(a.into()))) .saturating_add(T::DbWeight::get().writes(1005_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(a.into()))) - .saturating_add(Weight::from_parts(0, 2954).saturating_mul(a.into())) - } - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Account` (r:0 w:1) - /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + .saturating_add(Weight::from_parts(0, 2921).saturating_mul(a.into())) + } + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:1) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts Account (r:0 w:1) + /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) fn mint() -> Weight { // Proof Size summary in bytes: // Measured: `455` // Estimated: `4326` - // Minimum execution time: 48_645_000 picoseconds. - Weight::from_parts(50_287_000, 4326) + // Minimum execution time: 51_910_000 picoseconds. + Weight::from_parts(53_441_000, 4326) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Account` (r:0 w:1) - /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:1) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts Account (r:0 w:1) + /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) fn force_mint() -> Weight { // Proof Size summary in bytes: // Measured: `455` // Estimated: `4326` - // Minimum execution time: 46_688_000 picoseconds. - Weight::from_parts(47_680_000, 4326) + // Minimum execution time: 50_168_000 picoseconds. + Weight::from_parts(51_380_000, 4326) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `Nfts::Attribute` (r:1 w:0) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemMetadataOf` (r:1 w:0) - /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Account` (r:0 w:1) - /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemPriceOf` (r:0 w:1) - /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemAttributesApprovalsOf` (r:0 w:1) - /// Proof: `Nfts::ItemAttributesApprovalsOf` (`max_values`: None, `max_size`: Some(681), added: 3156, mode: `MaxEncodedLen`) - /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) - /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) + /// Storage: Nfts ItemConfigOf (r:1 w:1) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts ItemMetadataOf (r:1 w:0) + /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: Nfts Account (r:0 w:1) + /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: Nfts ItemPriceOf (r:0 w:1) + /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) + /// Storage: Nfts ItemAttributesApprovalsOf (r:0 w:1) + /// Proof: Nfts ItemAttributesApprovalsOf (max_values: None, max_size: Some(681), added: 3156, mode: MaxEncodedLen) + /// Storage: Nfts PendingSwapOf (r:0 w:1) + /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) fn burn() -> Weight { // Proof Size summary in bytes: // Measured: `564` // Estimated: `4326` - // Minimum execution time: 51_771_000 picoseconds. - Weight::from_parts(53_492_000, 4326) - .saturating_add(T::DbWeight::get().reads(5_u64)) + // Minimum execution time: 50_738_000 picoseconds. + Weight::from_parts(51_850_000, 4326) + .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } - /// Storage: `Nfts::Collection` (r:1 w:0) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:1 w:0) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Account` (r:0 w:2) - /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemPriceOf` (r:0 w:1) - /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) - /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) - /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) + /// Storage: Nfts Collection (r:1 w:0) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:1 w:0) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:0) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts Account (r:0 w:2) + /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: Nfts ItemPriceOf (r:0 w:1) + /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) + /// Storage: Nfts PendingSwapOf (r:0 w:1) + /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) fn transfer() -> Weight { // Proof Size summary in bytes: // Measured: `593` // Estimated: `4326` - // Minimum execution time: 39_166_000 picoseconds. - Weight::from_parts(40_128_000, 4326) + // Minimum execution time: 41_055_000 picoseconds. + Weight::from_parts(42_336_000, 4326) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: `Nfts::Collection` (r:1 w:0) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Item` (r:5000 w:5000) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: Nfts Collection (r:1 w:0) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts Item (r:5000 w:5000) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) /// The range of component `i` is `[0, 5000]`. fn redeposit(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `763 + i * (108 ±0)` // Estimated: `3549 + i * (3336 ±0)` - // Minimum execution time: 13_804_000 picoseconds. - Weight::from_parts(14_159_000, 3549) - // Standard Error: 13_812 - .saturating_add(Weight::from_parts(14_661_284, 0).saturating_mul(i.into())) + // Minimum execution time: 15_688_000 picoseconds. + Weight::from_parts(15_921_000, 3549) + // Standard Error: 14_827 + .saturating_add(Weight::from_parts(17_105_395, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(i.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 3336).saturating_mul(i.into())) } - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:1) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) fn lock_item_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `435` // Estimated: `3534` - // Minimum execution time: 17_485_000 picoseconds. - Weight::from_parts(18_412_000, 3534) + // Minimum execution time: 19_981_000 picoseconds. + Weight::from_parts(20_676_000, 3534) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:1) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) fn unlock_item_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `435` // Estimated: `3534` - // Minimum execution time: 17_335_000 picoseconds. - Weight::from_parts(18_543_000, 3534) + // Minimum execution time: 19_911_000 picoseconds. + Weight::from_parts(20_612_000, 3534) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::Collection` (r:1 w:0) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:1) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: Nfts Collection (r:1 w:0) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:1) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) fn lock_collection() -> Weight { // Proof Size summary in bytes: // Measured: `340` // Estimated: `3549` - // Minimum execution time: 14_608_000 picoseconds. - Weight::from_parts(15_696_000, 3549) + // Minimum execution time: 16_441_000 picoseconds. + Weight::from_parts(16_890_000, 3549) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::OwnershipAcceptance` (r:1 w:1) - /// Proof: `Nfts::OwnershipAcceptance` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionAccount` (r:0 w:2) - /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: Nfts OwnershipAcceptance (r:1 w:1) + /// Proof: Nfts OwnershipAcceptance (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionAccount (r:0 w:2) + /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) fn transfer_ownership() -> Weight { // Proof Size summary in bytes: - // Measured: `562` - // Estimated: `3593` - // Minimum execution time: 25_686_000 picoseconds. - Weight::from_parts(26_433_000, 3593) - .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(5_u64)) + // Measured: `388` + // Estimated: `3549` + // Minimum execution time: 22_610_000 picoseconds. + Weight::from_parts(23_422_000, 3549) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionRoleOf` (r:2 w:4) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionRoleOf (r:2 w:4) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) fn set_team() -> Weight { // Proof Size summary in bytes: // Measured: `369` // Estimated: `6078` - // Minimum execution time: 37_192_000 picoseconds. - Weight::from_parts(38_561_000, 6078) + // Minimum execution time: 39_739_000 picoseconds. + Weight::from_parts(41_306_000, 6078) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionAccount` (r:0 w:2) - /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionAccount (r:0 w:2) + /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) fn force_collection_owner() -> Weight { // Proof Size summary in bytes: // Measured: `311` // Estimated: `3549` - // Minimum execution time: 15_401_000 picoseconds. - Weight::from_parts(15_826_000, 3549) + // Minimum execution time: 17_685_000 picoseconds. + Weight::from_parts(18_258_000, 3549) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Nfts::Collection` (r:1 w:0) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:0 w:1) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: Nfts Collection (r:1 w:0) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:0 w:1) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) fn force_collection_config() -> Weight { // Proof Size summary in bytes: // Measured: `276` // Estimated: `3549` - // Minimum execution time: 11_683_000 picoseconds. - Weight::from_parts(12_255_000, 3549) + // Minimum execution time: 13_734_000 picoseconds. + Weight::from_parts(14_337_000, 3549) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:1) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) fn lock_item_properties() -> Weight { // Proof Size summary in bytes: // Measured: `435` // Estimated: `3534` - // Minimum execution time: 16_899_000 picoseconds. - Weight::from_parts(17_404_000, 3534) + // Minimum execution time: 19_269_000 picoseconds. + Weight::from_parts(19_859_000, 3534) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:1 w:1) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:0) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:1 w:1) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) fn set_attribute() -> Weight { // Proof Size summary in bytes: // Measured: `539` - // Estimated: `3944` - // Minimum execution time: 46_768_000 picoseconds. - Weight::from_parts(47_834_000, 3944) + // Estimated: `3911` + // Minimum execution time: 51_540_000 picoseconds. + Weight::from_parts(52_663_000, 3911) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:1 w:1) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:1 w:1) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) fn force_set_attribute() -> Weight { // Proof Size summary in bytes: // Measured: `344` - // Estimated: `3944` - // Minimum execution time: 23_356_000 picoseconds. - Weight::from_parts(24_528_000, 3944) + // Estimated: `3911` + // Minimum execution time: 26_529_000 picoseconds. + Weight::from_parts(27_305_000, 3911) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Nfts::Attribute` (r:1 w:1) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: Nfts Attribute (r:1 w:1) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:0) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) fn clear_attribute() -> Weight { // Proof Size summary in bytes: - // Measured: `983` - // Estimated: `3944` - // Minimum execution time: 43_061_000 picoseconds. - Weight::from_parts(44_024_000, 3944) + // Measured: `950` + // Estimated: `3911` + // Minimum execution time: 46_951_000 picoseconds. + Weight::from_parts(48_481_000, 3911) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Nfts::Item` (r:1 w:0) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemAttributesApprovalsOf` (r:1 w:1) - /// Proof: `Nfts::ItemAttributesApprovalsOf` (`max_values`: None, `max_size`: Some(681), added: 3156, mode: `MaxEncodedLen`) + /// Storage: Nfts Item (r:1 w:0) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts ItemAttributesApprovalsOf (r:1 w:1) + /// Proof: Nfts ItemAttributesApprovalsOf (max_values: None, max_size: Some(681), added: 3156, mode: MaxEncodedLen) fn approve_item_attributes() -> Weight { // Proof Size summary in bytes: // Measured: `381` // Estimated: `4326` - // Minimum execution time: 14_929_000 picoseconds. - Weight::from_parts(15_344_000, 4326) + // Minimum execution time: 17_222_000 picoseconds. + Weight::from_parts(17_819_000, 4326) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::Item` (r:1 w:0) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemAttributesApprovalsOf` (r:1 w:1) - /// Proof: `Nfts::ItemAttributesApprovalsOf` (`max_values`: None, `max_size`: Some(681), added: 3156, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:1001 w:1000) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Nfts Item (r:1 w:0) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts ItemAttributesApprovalsOf (r:1 w:1) + /// Proof: Nfts ItemAttributesApprovalsOf (max_values: None, max_size: Some(681), added: 3156, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:1001 w:1000) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `n` is `[0, 1000]`. fn cancel_item_attributes_approval(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `831 + n * (398 ±0)` - // Estimated: `4326 + n * (2954 ±0)` - // Minimum execution time: 23_707_000 picoseconds. - Weight::from_parts(24_688_000, 4326) - // Standard Error: 3_813 - .saturating_add(Weight::from_parts(6_422_256, 0).saturating_mul(n.into())) + // Measured: `837 + n * (364 ±0)` + // Estimated: `4326 + n * (2921 ±0)` + // Minimum execution time: 26_185_000 picoseconds. + Weight::from_parts(27_038_000, 4326) + // Standard Error: 2_378 + .saturating_add(Weight::from_parts(6_067_888, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 2954).saturating_mul(n.into())) - } - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemMetadataOf` (r:1 w:1) - /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) + .saturating_add(Weight::from_parts(0, 2921).saturating_mul(n.into())) + } + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:0) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts ItemMetadataOf (r:1 w:1) + /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) fn set_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `539` - // Estimated: `3812` - // Minimum execution time: 37_882_000 picoseconds. - Weight::from_parts(39_222_000, 3812) + // Estimated: `3605` + // Minimum execution time: 42_120_000 picoseconds. + Weight::from_parts(43_627_000, 3605) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemMetadataOf` (r:1 w:1) - /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts ItemMetadataOf (r:1 w:1) + /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:0) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) fn clear_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `849` - // Estimated: `3812` - // Minimum execution time: 36_629_000 picoseconds. - Weight::from_parts(37_351_000, 3812) + // Measured: `642` + // Estimated: `3605` + // Minimum execution time: 40_732_000 picoseconds. + Weight::from_parts(42_760_000, 3605) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionMetadataOf` (r:1 w:1) - /// Proof: `Nfts::CollectionMetadataOf` (`max_values`: None, `max_size`: Some(294), added: 2769, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionMetadataOf (r:1 w:1) + /// Proof: Nfts CollectionMetadataOf (max_values: None, max_size: Some(87), added: 2562, mode: MaxEncodedLen) fn set_collection_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `398` - // Estimated: `3759` - // Minimum execution time: 34_853_000 picoseconds. - Weight::from_parts(35_914_000, 3759) + // Estimated: `3552` + // Minimum execution time: 39_443_000 picoseconds. + Weight::from_parts(40_482_000, 3552) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:0) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionMetadataOf` (r:1 w:1) - /// Proof: `Nfts::CollectionMetadataOf` (`max_values`: None, `max_size`: Some(294), added: 2769, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:0) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts CollectionMetadataOf (r:1 w:1) + /// Proof: Nfts CollectionMetadataOf (max_values: None, max_size: Some(87), added: 2562, mode: MaxEncodedLen) fn clear_collection_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `716` - // Estimated: `3759` - // Minimum execution time: 33_759_000 picoseconds. - Weight::from_parts(34_729_000, 3759) + // Measured: `509` + // Estimated: `3552` + // Minimum execution time: 37_676_000 picoseconds. + Weight::from_parts(39_527_000, 3552) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) fn approve_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `410` // Estimated: `4326` - // Minimum execution time: 17_583_000 picoseconds. - Weight::from_parts(18_675_000, 4326) + // Minimum execution time: 20_787_000 picoseconds. + Weight::from_parts(21_315_000, 4326) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) fn cancel_approval() -> Weight { // Proof Size summary in bytes: // Measured: `418` // Estimated: `4326` - // Minimum execution time: 15_036_000 picoseconds. - Weight::from_parts(15_995_000, 4326) + // Minimum execution time: 18_200_000 picoseconds. + Weight::from_parts(19_064_000, 4326) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) fn clear_all_transfer_approvals() -> Weight { // Proof Size summary in bytes: // Measured: `418` // Estimated: `4326` - // Minimum execution time: 14_666_000 picoseconds. - Weight::from_parts(15_152_000, 4326) + // Minimum execution time: 17_128_000 picoseconds. + Weight::from_parts(17_952_000, 4326) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::OwnershipAcceptance` (r:1 w:1) - /// Proof: `Nfts::OwnershipAcceptance` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: Nfts OwnershipAcceptance (r:1 w:1) + /// Proof: Nfts OwnershipAcceptance (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) fn set_accept_ownership() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3517` - // Minimum execution time: 12_393_000 picoseconds. - Weight::from_parts(12_895_000, 3517) + // Minimum execution time: 14_667_000 picoseconds. + Weight::from_parts(15_262_000, 3517) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:1) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:0) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionConfigOf (r:1 w:1) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:0) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) fn set_collection_max_supply() -> Weight { // Proof Size summary in bytes: // Measured: `340` // Estimated: `3549` - // Minimum execution time: 16_034_000 picoseconds. - Weight::from_parts(16_617_000, 3549) + // Minimum execution time: 18_435_000 picoseconds. + Weight::from_parts(18_775_000, 3549) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:1) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:1) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) fn update_mint_settings() -> Weight { // Proof Size summary in bytes: // Measured: `323` // Estimated: `3538` - // Minimum execution time: 15_812_000 picoseconds. - Weight::from_parts(16_644_000, 3538) + // Minimum execution time: 18_125_000 picoseconds. + Weight::from_parts(18_415_000, 3538) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::Item` (r:1 w:0) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemPriceOf` (r:0 w:1) - /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) + /// Storage: Nfts Item (r:1 w:0) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:0) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts ItemPriceOf (r:0 w:1) + /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) fn set_price() -> Weight { // Proof Size summary in bytes: // Measured: `518` // Estimated: `4326` - // Minimum execution time: 21_650_000 picoseconds. - Weight::from_parts(22_443_000, 4326) + // Minimum execution time: 23_237_000 picoseconds. + Weight::from_parts(24_128_000, 4326) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemPriceOf` (r:1 w:1) - /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:0) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:1 w:0) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Account` (r:0 w:2) - /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) - /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) - /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts ItemPriceOf (r:1 w:1) + /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:0) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:1 w:0) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:0) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts Account (r:0 w:2) + /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: Nfts PendingSwapOf (r:0 w:1) + /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) fn buy_item() -> Weight { // Proof Size summary in bytes: // Measured: `705` // Estimated: `4326` - // Minimum execution time: 49_463_000 picoseconds. - Weight::from_parts(50_937_000, 4326) + // Minimum execution time: 53_291_000 picoseconds. + Weight::from_parts(54_614_000, 4326) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } @@ -662,685 +658,681 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_029_000 picoseconds. - Weight::from_parts(3_749_829, 0) - // Standard Error: 8_497 - .saturating_add(Weight::from_parts(1_913_514, 0).saturating_mul(n.into())) - } - /// Storage: `Nfts::Item` (r:2 w:0) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) - /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) + // Minimum execution time: 2_192_000 picoseconds. + Weight::from_parts(4_039_901, 0) + // Standard Error: 10_309 + .saturating_add(Weight::from_parts(3_934_017, 0).saturating_mul(n.into())) + } + /// Storage: Nfts Item (r:2 w:0) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts PendingSwapOf (r:0 w:1) + /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) fn create_swap() -> Weight { // Proof Size summary in bytes: // Measured: `494` // Estimated: `7662` - // Minimum execution time: 18_181_000 picoseconds. - Weight::from_parts(18_698_000, 7662) + // Minimum execution time: 21_011_000 picoseconds. + Weight::from_parts(22_065_000, 7662) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::PendingSwapOf` (r:1 w:1) - /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Item` (r:1 w:0) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: Nfts PendingSwapOf (r:1 w:1) + /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) + /// Storage: Nfts Item (r:1 w:0) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) fn cancel_swap() -> Weight { // Proof Size summary in bytes: // Measured: `513` // Estimated: `4326` - // Minimum execution time: 18_228_000 picoseconds. - Weight::from_parts(18_940_000, 4326) + // Minimum execution time: 21_423_000 picoseconds. + Weight::from_parts(21_743_000, 4326) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::Item` (r:2 w:2) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::PendingSwapOf` (r:1 w:2) - /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:0) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:2 w:0) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:2 w:0) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Account` (r:0 w:4) - /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemPriceOf` (r:0 w:2) - /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) + /// Storage: Nfts Item (r:2 w:2) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts PendingSwapOf (r:1 w:2) + /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:0) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:2 w:0) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:2 w:0) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts Account (r:0 w:4) + /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: Nfts ItemPriceOf (r:0 w:2) + /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) fn claim_swap() -> Weight { // Proof Size summary in bytes: // Measured: `834` // Estimated: `7662` - // Minimum execution time: 77_983_000 picoseconds. - Weight::from_parts(79_887_000, 7662) + // Minimum execution time: 86_059_000 picoseconds. + Weight::from_parts(88_401_000, 7662) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(10_u64)) } - /// Storage: `Nfts::CollectionRoleOf` (r:2 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:10 w:10) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemMetadataOf` (r:1 w:1) - /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Account` (r:0 w:1) - /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionRoleOf (r:2 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:1) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:10 w:10) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: Nfts ItemMetadataOf (r:1 w:1) + /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: Nfts Account (r:0 w:1) + /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) /// The range of component `n` is `[0, 10]`. fn mint_pre_signed(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `629` - // Estimated: `6078 + n * (2954 ±0)` - // Minimum execution time: 126_998_000 picoseconds. - Weight::from_parts(134_149_389, 6078) - // Standard Error: 33_180 - .saturating_add(Weight::from_parts(30_711_206, 0).saturating_mul(n.into())) + // Estimated: `6078 + n * (2921 ±0)` + // Minimum execution time: 146_746_000 picoseconds. + Weight::from_parts(152_885_862, 6078) + // Standard Error: 40_442 + .saturating_add(Weight::from_parts(32_887_800, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(6_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 2954).saturating_mul(n.into())) - } - /// Storage: `Nfts::Item` (r:1 w:0) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemAttributesApprovalsOf` (r:1 w:1) - /// Proof: `Nfts::ItemAttributesApprovalsOf` (`max_values`: None, `max_size`: Some(681), added: 3156, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:10 w:10) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + .saturating_add(Weight::from_parts(0, 2921).saturating_mul(n.into())) + } + /// Storage: Nfts Item (r:1 w:0) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts ItemAttributesApprovalsOf (r:1 w:1) + /// Proof: Nfts ItemAttributesApprovalsOf (max_values: None, max_size: Some(681), added: 3156, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:10 w:10) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `n` is `[0, 10]`. fn set_attributes_pre_signed(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `659` - // Estimated: `4326 + n * (2954 ±0)` - // Minimum execution time: 66_213_000 picoseconds. - Weight::from_parts(81_661_819, 4326) - // Standard Error: 87_003 - .saturating_add(Weight::from_parts(29_550_476, 0).saturating_mul(n.into())) + // Estimated: `4326 + n * (2921 ±0)` + // Minimum execution time: 83_960_000 picoseconds. + Weight::from_parts(98_609_885, 4326) + // Standard Error: 85_991 + .saturating_add(Weight::from_parts(32_633_495, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 2954).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 2921).saturating_mul(n.into())) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Nfts::NextCollectionId` (r:1 w:1) - /// Proof: `Nfts::NextCollectionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionRoleOf` (r:0 w:1) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:0 w:1) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionAccount` (r:0 w:1) - /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: Nfts NextCollectionId (r:1 w:1) + /// Proof: Nfts NextCollectionId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionRoleOf (r:0 w:1) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:0 w:1) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts CollectionAccount (r:0 w:1) + /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) fn create() -> Weight { // Proof Size summary in bytes: // Measured: `216` // Estimated: `3549` - // Minimum execution time: 34_035_000 picoseconds. - Weight::from_parts(35_228_000, 3549) + // Minimum execution time: 40_489_000 picoseconds. + Weight::from_parts(41_320_000, 3549) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: `Nfts::NextCollectionId` (r:1 w:1) - /// Proof: `Nfts::NextCollectionId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionRoleOf` (r:0 w:1) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:0 w:1) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionAccount` (r:0 w:1) - /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: Nfts NextCollectionId (r:1 w:1) + /// Proof: Nfts NextCollectionId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionRoleOf (r:0 w:1) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:0 w:1) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts CollectionAccount (r:0 w:1) + /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) fn force_create() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3549` - // Minimum execution time: 19_430_000 picoseconds. - Weight::from_parts(20_054_000, 3549) + // Minimum execution time: 23_257_000 picoseconds. + Weight::from_parts(23_770_000, 3549) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemMetadataOf` (r:1 w:0) - /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:1) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:1001 w:1000) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1000 w:1000) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionMetadataOf` (r:0 w:1) - /// Proof: `Nfts::CollectionMetadataOf` (`max_values`: None, `max_size`: Some(294), added: 2769, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:0 w:1) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionAccount` (r:0 w:1) - /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts ItemMetadataOf (r:1 w:0) + /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: Nfts CollectionRoleOf (r:1 w:1) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:1001 w:1000) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1000 w:1000) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts CollectionMetadataOf (r:0 w:1) + /// Proof: Nfts CollectionMetadataOf (max_values: None, max_size: Some(87), added: 2562, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:0 w:1) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts CollectionAccount (r:0 w:1) + /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) /// The range of component `m` is `[0, 1000]`. /// The range of component `c` is `[0, 1000]`. /// The range of component `a` is `[0, 1000]`. fn destroy(_m: u32, _c: u32, a: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `32204 + a * (366 ±0)` - // Estimated: `2523990 + a * (2954 ±0)` - // Minimum execution time: 1_249_733_000 picoseconds. - Weight::from_parts(1_293_703_849, 2523990) - // Standard Error: 4_764 - .saturating_add(Weight::from_parts(6_433_523, 0).saturating_mul(a.into())) + // Measured: `32220 + a * (332 ±0)` + // Estimated: `2523990 + a * (2921 ±0)` + // Minimum execution time: 1_310_198_000 picoseconds. + Weight::from_parts(1_479_261_043, 2523990) + // Standard Error: 4_415 + .saturating_add(Weight::from_parts(6_016_212, 0).saturating_mul(a.into())) .saturating_add(RocksDbWeight::get().reads(1004_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(a.into()))) .saturating_add(RocksDbWeight::get().writes(1005_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(a.into()))) - .saturating_add(Weight::from_parts(0, 2954).saturating_mul(a.into())) - } - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Account` (r:0 w:1) - /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + .saturating_add(Weight::from_parts(0, 2921).saturating_mul(a.into())) + } + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:1) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts Account (r:0 w:1) + /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) fn mint() -> Weight { // Proof Size summary in bytes: // Measured: `455` // Estimated: `4326` - // Minimum execution time: 48_645_000 picoseconds. - Weight::from_parts(50_287_000, 4326) + // Minimum execution time: 51_910_000 picoseconds. + Weight::from_parts(53_441_000, 4326) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Account` (r:0 w:1) - /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:1) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts Account (r:0 w:1) + /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) fn force_mint() -> Weight { // Proof Size summary in bytes: // Measured: `455` // Estimated: `4326` - // Minimum execution time: 46_688_000 picoseconds. - Weight::from_parts(47_680_000, 4326) + // Minimum execution time: 50_168_000 picoseconds. + Weight::from_parts(51_380_000, 4326) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `Nfts::Attribute` (r:1 w:0) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemMetadataOf` (r:1 w:0) - /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Account` (r:0 w:1) - /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemPriceOf` (r:0 w:1) - /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemAttributesApprovalsOf` (r:0 w:1) - /// Proof: `Nfts::ItemAttributesApprovalsOf` (`max_values`: None, `max_size`: Some(681), added: 3156, mode: `MaxEncodedLen`) - /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) - /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) + /// Storage: Nfts ItemConfigOf (r:1 w:1) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts ItemMetadataOf (r:1 w:0) + /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: Nfts Account (r:0 w:1) + /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: Nfts ItemPriceOf (r:0 w:1) + /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) + /// Storage: Nfts ItemAttributesApprovalsOf (r:0 w:1) + /// Proof: Nfts ItemAttributesApprovalsOf (max_values: None, max_size: Some(681), added: 3156, mode: MaxEncodedLen) + /// Storage: Nfts PendingSwapOf (r:0 w:1) + /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) fn burn() -> Weight { // Proof Size summary in bytes: // Measured: `564` // Estimated: `4326` - // Minimum execution time: 51_771_000 picoseconds. - Weight::from_parts(53_492_000, 4326) - .saturating_add(RocksDbWeight::get().reads(5_u64)) + // Minimum execution time: 50_738_000 picoseconds. + Weight::from_parts(51_850_000, 4326) + .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } - /// Storage: `Nfts::Collection` (r:1 w:0) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:1 w:0) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Account` (r:0 w:2) - /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemPriceOf` (r:0 w:1) - /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) - /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) - /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) + /// Storage: Nfts Collection (r:1 w:0) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:1 w:0) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:0) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts Account (r:0 w:2) + /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: Nfts ItemPriceOf (r:0 w:1) + /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) + /// Storage: Nfts PendingSwapOf (r:0 w:1) + /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) fn transfer() -> Weight { // Proof Size summary in bytes: // Measured: `593` // Estimated: `4326` - // Minimum execution time: 39_166_000 picoseconds. - Weight::from_parts(40_128_000, 4326) + // Minimum execution time: 41_055_000 picoseconds. + Weight::from_parts(42_336_000, 4326) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: `Nfts::Collection` (r:1 w:0) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Item` (r:5000 w:5000) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: Nfts Collection (r:1 w:0) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts Item (r:5000 w:5000) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) /// The range of component `i` is `[0, 5000]`. fn redeposit(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `763 + i * (108 ±0)` // Estimated: `3549 + i * (3336 ±0)` - // Minimum execution time: 13_804_000 picoseconds. - Weight::from_parts(14_159_000, 3549) - // Standard Error: 13_812 - .saturating_add(Weight::from_parts(14_661_284, 0).saturating_mul(i.into())) + // Minimum execution time: 15_688_000 picoseconds. + Weight::from_parts(15_921_000, 3549) + // Standard Error: 14_827 + .saturating_add(Weight::from_parts(17_105_395, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(i.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 3336).saturating_mul(i.into())) } - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:1) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) fn lock_item_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `435` // Estimated: `3534` - // Minimum execution time: 17_485_000 picoseconds. - Weight::from_parts(18_412_000, 3534) + // Minimum execution time: 19_981_000 picoseconds. + Weight::from_parts(20_676_000, 3534) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:1) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) fn unlock_item_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `435` // Estimated: `3534` - // Minimum execution time: 17_335_000 picoseconds. - Weight::from_parts(18_543_000, 3534) + // Minimum execution time: 19_911_000 picoseconds. + Weight::from_parts(20_612_000, 3534) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::Collection` (r:1 w:0) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:1) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: Nfts Collection (r:1 w:0) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:1) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) fn lock_collection() -> Weight { // Proof Size summary in bytes: // Measured: `340` // Estimated: `3549` - // Minimum execution time: 14_608_000 picoseconds. - Weight::from_parts(15_696_000, 3549) + // Minimum execution time: 16_441_000 picoseconds. + Weight::from_parts(16_890_000, 3549) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::OwnershipAcceptance` (r:1 w:1) - /// Proof: `Nfts::OwnershipAcceptance` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionAccount` (r:0 w:2) - /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: Nfts OwnershipAcceptance (r:1 w:1) + /// Proof: Nfts OwnershipAcceptance (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionAccount (r:0 w:2) + /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) fn transfer_ownership() -> Weight { // Proof Size summary in bytes: - // Measured: `562` - // Estimated: `3593` - // Minimum execution time: 25_686_000 picoseconds. - Weight::from_parts(26_433_000, 3593) - .saturating_add(RocksDbWeight::get().reads(3_u64)) - .saturating_add(RocksDbWeight::get().writes(5_u64)) + // Measured: `388` + // Estimated: `3549` + // Minimum execution time: 22_610_000 picoseconds. + Weight::from_parts(23_422_000, 3549) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionRoleOf` (r:2 w:4) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionRoleOf (r:2 w:4) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) fn set_team() -> Weight { // Proof Size summary in bytes: // Measured: `369` // Estimated: `6078` - // Minimum execution time: 37_192_000 picoseconds. - Weight::from_parts(38_561_000, 6078) + // Minimum execution time: 39_739_000 picoseconds. + Weight::from_parts(41_306_000, 6078) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionAccount` (r:0 w:2) - /// Proof: `Nfts::CollectionAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionAccount (r:0 w:2) + /// Proof: Nfts CollectionAccount (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) fn force_collection_owner() -> Weight { // Proof Size summary in bytes: // Measured: `311` // Estimated: `3549` - // Minimum execution time: 15_401_000 picoseconds. - Weight::from_parts(15_826_000, 3549) + // Minimum execution time: 17_685_000 picoseconds. + Weight::from_parts(18_258_000, 3549) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Nfts::Collection` (r:1 w:0) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:0 w:1) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: Nfts Collection (r:1 w:0) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:0 w:1) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) fn force_collection_config() -> Weight { // Proof Size summary in bytes: // Measured: `276` // Estimated: `3549` - // Minimum execution time: 11_683_000 picoseconds. - Weight::from_parts(12_255_000, 3549) + // Minimum execution time: 13_734_000 picoseconds. + Weight::from_parts(14_337_000, 3549) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:1) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) fn lock_item_properties() -> Weight { // Proof Size summary in bytes: // Measured: `435` // Estimated: `3534` - // Minimum execution time: 16_899_000 picoseconds. - Weight::from_parts(17_404_000, 3534) + // Minimum execution time: 19_269_000 picoseconds. + Weight::from_parts(19_859_000, 3534) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:1 w:1) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:0) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:1 w:1) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) fn set_attribute() -> Weight { // Proof Size summary in bytes: // Measured: `539` - // Estimated: `3944` - // Minimum execution time: 46_768_000 picoseconds. - Weight::from_parts(47_834_000, 3944) + // Estimated: `3911` + // Minimum execution time: 51_540_000 picoseconds. + Weight::from_parts(52_663_000, 3911) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:1 w:1) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:1 w:1) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) fn force_set_attribute() -> Weight { // Proof Size summary in bytes: // Measured: `344` - // Estimated: `3944` - // Minimum execution time: 23_356_000 picoseconds. - Weight::from_parts(24_528_000, 3944) + // Estimated: `3911` + // Minimum execution time: 26_529_000 picoseconds. + Weight::from_parts(27_305_000, 3911) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Nfts::Attribute` (r:1 w:1) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: Nfts Attribute (r:1 w:1) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:0) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) fn clear_attribute() -> Weight { // Proof Size summary in bytes: - // Measured: `983` - // Estimated: `3944` - // Minimum execution time: 43_061_000 picoseconds. - Weight::from_parts(44_024_000, 3944) + // Measured: `950` + // Estimated: `3911` + // Minimum execution time: 46_951_000 picoseconds. + Weight::from_parts(48_481_000, 3911) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Nfts::Item` (r:1 w:0) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemAttributesApprovalsOf` (r:1 w:1) - /// Proof: `Nfts::ItemAttributesApprovalsOf` (`max_values`: None, `max_size`: Some(681), added: 3156, mode: `MaxEncodedLen`) + /// Storage: Nfts Item (r:1 w:0) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts ItemAttributesApprovalsOf (r:1 w:1) + /// Proof: Nfts ItemAttributesApprovalsOf (max_values: None, max_size: Some(681), added: 3156, mode: MaxEncodedLen) fn approve_item_attributes() -> Weight { // Proof Size summary in bytes: // Measured: `381` // Estimated: `4326` - // Minimum execution time: 14_929_000 picoseconds. - Weight::from_parts(15_344_000, 4326) + // Minimum execution time: 17_222_000 picoseconds. + Weight::from_parts(17_819_000, 4326) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::Item` (r:1 w:0) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemAttributesApprovalsOf` (r:1 w:1) - /// Proof: `Nfts::ItemAttributesApprovalsOf` (`max_values`: None, `max_size`: Some(681), added: 3156, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:1001 w:1000) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Nfts Item (r:1 w:0) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts ItemAttributesApprovalsOf (r:1 w:1) + /// Proof: Nfts ItemAttributesApprovalsOf (max_values: None, max_size: Some(681), added: 3156, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:1001 w:1000) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `n` is `[0, 1000]`. fn cancel_item_attributes_approval(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `831 + n * (398 ±0)` - // Estimated: `4326 + n * (2954 ±0)` - // Minimum execution time: 23_707_000 picoseconds. - Weight::from_parts(24_688_000, 4326) - // Standard Error: 3_813 - .saturating_add(Weight::from_parts(6_422_256, 0).saturating_mul(n.into())) + // Measured: `837 + n * (364 ±0)` + // Estimated: `4326 + n * (2921 ±0)` + // Minimum execution time: 26_185_000 picoseconds. + Weight::from_parts(27_038_000, 4326) + // Standard Error: 2_378 + .saturating_add(Weight::from_parts(6_067_888, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 2954).saturating_mul(n.into())) - } - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemMetadataOf` (r:1 w:1) - /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) + .saturating_add(Weight::from_parts(0, 2921).saturating_mul(n.into())) + } + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:0) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts ItemMetadataOf (r:1 w:1) + /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) fn set_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `539` - // Estimated: `3812` - // Minimum execution time: 37_882_000 picoseconds. - Weight::from_parts(39_222_000, 3812) + // Estimated: `3605` + // Minimum execution time: 42_120_000 picoseconds. + Weight::from_parts(43_627_000, 3605) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemMetadataOf` (r:1 w:1) - /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts ItemMetadataOf (r:1 w:1) + /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:0) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) fn clear_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `849` - // Estimated: `3812` - // Minimum execution time: 36_629_000 picoseconds. - Weight::from_parts(37_351_000, 3812) + // Measured: `642` + // Estimated: `3605` + // Minimum execution time: 40_732_000 picoseconds. + Weight::from_parts(42_760_000, 3605) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionMetadataOf` (r:1 w:1) - /// Proof: `Nfts::CollectionMetadataOf` (`max_values`: None, `max_size`: Some(294), added: 2769, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionMetadataOf (r:1 w:1) + /// Proof: Nfts CollectionMetadataOf (max_values: None, max_size: Some(87), added: 2562, mode: MaxEncodedLen) fn set_collection_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `398` - // Estimated: `3759` - // Minimum execution time: 34_853_000 picoseconds. - Weight::from_parts(35_914_000, 3759) + // Estimated: `3552` + // Minimum execution time: 39_443_000 picoseconds. + Weight::from_parts(40_482_000, 3552) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:0) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionMetadataOf` (r:1 w:1) - /// Proof: `Nfts::CollectionMetadataOf` (`max_values`: None, `max_size`: Some(294), added: 2769, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:0) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts CollectionMetadataOf (r:1 w:1) + /// Proof: Nfts CollectionMetadataOf (max_values: None, max_size: Some(87), added: 2562, mode: MaxEncodedLen) fn clear_collection_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `716` - // Estimated: `3759` - // Minimum execution time: 33_759_000 picoseconds. - Weight::from_parts(34_729_000, 3759) + // Measured: `509` + // Estimated: `3552` + // Minimum execution time: 37_676_000 picoseconds. + Weight::from_parts(39_527_000, 3552) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) fn approve_transfer() -> Weight { // Proof Size summary in bytes: // Measured: `410` // Estimated: `4326` - // Minimum execution time: 17_583_000 picoseconds. - Weight::from_parts(18_675_000, 4326) + // Minimum execution time: 20_787_000 picoseconds. + Weight::from_parts(21_315_000, 4326) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) fn cancel_approval() -> Weight { // Proof Size summary in bytes: // Measured: `418` // Estimated: `4326` - // Minimum execution time: 15_036_000 picoseconds. - Weight::from_parts(15_995_000, 4326) + // Minimum execution time: 18_200_000 picoseconds. + Weight::from_parts(19_064_000, 4326) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) fn clear_all_transfer_approvals() -> Weight { // Proof Size summary in bytes: // Measured: `418` // Estimated: `4326` - // Minimum execution time: 14_666_000 picoseconds. - Weight::from_parts(15_152_000, 4326) + // Minimum execution time: 17_128_000 picoseconds. + Weight::from_parts(17_952_000, 4326) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::OwnershipAcceptance` (r:1 w:1) - /// Proof: `Nfts::OwnershipAcceptance` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: Nfts OwnershipAcceptance (r:1 w:1) + /// Proof: Nfts OwnershipAcceptance (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) fn set_accept_ownership() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `3517` - // Minimum execution time: 12_393_000 picoseconds. - Weight::from_parts(12_895_000, 3517) + // Minimum execution time: 14_667_000 picoseconds. + Weight::from_parts(15_262_000, 3517) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:1) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:0) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionConfigOf (r:1 w:1) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:0) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) fn set_collection_max_supply() -> Weight { // Proof Size summary in bytes: // Measured: `340` // Estimated: `3549` - // Minimum execution time: 16_034_000 picoseconds. - Weight::from_parts(16_617_000, 3549) + // Minimum execution time: 18_435_000 picoseconds. + Weight::from_parts(18_775_000, 3549) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::CollectionRoleOf` (r:1 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:1) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionRoleOf (r:1 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:1) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) fn update_mint_settings() -> Weight { // Proof Size summary in bytes: // Measured: `323` // Estimated: `3538` - // Minimum execution time: 15_812_000 picoseconds. - Weight::from_parts(16_644_000, 3538) + // Minimum execution time: 18_125_000 picoseconds. + Weight::from_parts(18_415_000, 3538) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::Item` (r:1 w:0) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemPriceOf` (r:0 w:1) - /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) + /// Storage: Nfts Item (r:1 w:0) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:0) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts ItemPriceOf (r:0 w:1) + /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) fn set_price() -> Weight { // Proof Size summary in bytes: // Measured: `518` // Estimated: `4326` - // Minimum execution time: 21_650_000 picoseconds. - Weight::from_parts(22_443_000, 4326) + // Minimum execution time: 23_237_000 picoseconds. + Weight::from_parts(24_128_000, 4326) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemPriceOf` (r:1 w:1) - /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:0) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:1 w:0) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:0) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Account` (r:0 w:2) - /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) - /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) - /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts ItemPriceOf (r:1 w:1) + /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:0) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:1 w:0) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:0) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts Account (r:0 w:2) + /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: Nfts PendingSwapOf (r:0 w:1) + /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) fn buy_item() -> Weight { // Proof Size summary in bytes: // Measured: `705` // Estimated: `4326` - // Minimum execution time: 49_463_000 picoseconds. - Weight::from_parts(50_937_000, 4326) + // Minimum execution time: 53_291_000 picoseconds. + Weight::from_parts(54_614_000, 4326) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } @@ -1349,120 +1341,120 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_029_000 picoseconds. - Weight::from_parts(3_749_829, 0) - // Standard Error: 8_497 - .saturating_add(Weight::from_parts(1_913_514, 0).saturating_mul(n.into())) - } - /// Storage: `Nfts::Item` (r:2 w:0) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::PendingSwapOf` (r:0 w:1) - /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) + // Minimum execution time: 2_192_000 picoseconds. + Weight::from_parts(4_039_901, 0) + // Standard Error: 10_309 + .saturating_add(Weight::from_parts(3_934_017, 0).saturating_mul(n.into())) + } + /// Storage: Nfts Item (r:2 w:0) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts PendingSwapOf (r:0 w:1) + /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) fn create_swap() -> Weight { // Proof Size summary in bytes: // Measured: `494` // Estimated: `7662` - // Minimum execution time: 18_181_000 picoseconds. - Weight::from_parts(18_698_000, 7662) + // Minimum execution time: 21_011_000 picoseconds. + Weight::from_parts(22_065_000, 7662) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::PendingSwapOf` (r:1 w:1) - /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Item` (r:1 w:0) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) + /// Storage: Nfts PendingSwapOf (r:1 w:1) + /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) + /// Storage: Nfts Item (r:1 w:0) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) fn cancel_swap() -> Weight { // Proof Size summary in bytes: // Measured: `513` // Estimated: `4326` - // Minimum execution time: 18_228_000 picoseconds. - Weight::from_parts(18_940_000, 4326) + // Minimum execution time: 21_423_000 picoseconds. + Weight::from_parts(21_743_000, 4326) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Nfts::Item` (r:2 w:2) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::PendingSwapOf` (r:1 w:2) - /// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:0) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:2 w:0) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:2 w:0) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Account` (r:0 w:4) - /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemPriceOf` (r:0 w:2) - /// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`) + /// Storage: Nfts Item (r:2 w:2) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts PendingSwapOf (r:1 w:2) + /// Proof: Nfts PendingSwapOf (max_values: None, max_size: Some(71), added: 2546, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:0) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:2 w:0) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:2 w:0) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: Nfts Account (r:0 w:4) + /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) + /// Storage: Nfts ItemPriceOf (r:0 w:2) + /// Proof: Nfts ItemPriceOf (max_values: None, max_size: Some(89), added: 2564, mode: MaxEncodedLen) fn claim_swap() -> Weight { // Proof Size summary in bytes: // Measured: `834` // Estimated: `7662` - // Minimum execution time: 77_983_000 picoseconds. - Weight::from_parts(79_887_000, 7662) + // Minimum execution time: 86_059_000 picoseconds. + Weight::from_parts(88_401_000, 7662) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(10_u64)) } - /// Storage: `Nfts::CollectionRoleOf` (r:2 w:0) - /// Proof: `Nfts::CollectionRoleOf` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Item` (r:1 w:1) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemConfigOf` (r:1 w:1) - /// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:10 w:10) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemMetadataOf` (r:1 w:1) - /// Proof: `Nfts::ItemMetadataOf` (`max_values`: None, `max_size`: Some(347), added: 2822, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Account` (r:0 w:1) - /// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) + /// Storage: Nfts CollectionRoleOf (r:2 w:0) + /// Proof: Nfts CollectionRoleOf (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts Item (r:1 w:1) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts ItemConfigOf (r:1 w:1) + /// Proof: Nfts ItemConfigOf (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:10 w:10) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: Nfts ItemMetadataOf (r:1 w:1) + /// Proof: Nfts ItemMetadataOf (max_values: None, max_size: Some(140), added: 2615, mode: MaxEncodedLen) + /// Storage: Nfts Account (r:0 w:1) + /// Proof: Nfts Account (max_values: None, max_size: Some(88), added: 2563, mode: MaxEncodedLen) /// The range of component `n` is `[0, 10]`. fn mint_pre_signed(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `629` - // Estimated: `6078 + n * (2954 ±0)` - // Minimum execution time: 126_998_000 picoseconds. - Weight::from_parts(134_149_389, 6078) - // Standard Error: 33_180 - .saturating_add(Weight::from_parts(30_711_206, 0).saturating_mul(n.into())) + // Estimated: `6078 + n * (2921 ±0)` + // Minimum execution time: 146_746_000 picoseconds. + Weight::from_parts(152_885_862, 6078) + // Standard Error: 40_442 + .saturating_add(Weight::from_parts(32_887_800, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes(6_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 2954).saturating_mul(n.into())) - } - /// Storage: `Nfts::Item` (r:1 w:0) - /// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`) - /// Storage: `Nfts::ItemAttributesApprovalsOf` (r:1 w:1) - /// Proof: `Nfts::ItemAttributesApprovalsOf` (`max_values`: None, `max_size`: Some(681), added: 3156, mode: `MaxEncodedLen`) - /// Storage: `Nfts::CollectionConfigOf` (r:1 w:0) - /// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Collection` (r:1 w:1) - /// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`) - /// Storage: `Nfts::Attribute` (r:10 w:10) - /// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + .saturating_add(Weight::from_parts(0, 2921).saturating_mul(n.into())) + } + /// Storage: Nfts Item (r:1 w:0) + /// Proof: Nfts Item (max_values: None, max_size: Some(861), added: 3336, mode: MaxEncodedLen) + /// Storage: Nfts ItemAttributesApprovalsOf (r:1 w:1) + /// Proof: Nfts ItemAttributesApprovalsOf (max_values: None, max_size: Some(681), added: 3156, mode: MaxEncodedLen) + /// Storage: Nfts CollectionConfigOf (r:1 w:0) + /// Proof: Nfts CollectionConfigOf (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + /// Storage: Nfts Collection (r:1 w:1) + /// Proof: Nfts Collection (max_values: None, max_size: Some(84), added: 2559, mode: MaxEncodedLen) + /// Storage: Nfts Attribute (r:10 w:10) + /// Proof: Nfts Attribute (max_values: None, max_size: Some(446), added: 2921, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `n` is `[0, 10]`. fn set_attributes_pre_signed(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `659` - // Estimated: `4326 + n * (2954 ±0)` - // Minimum execution time: 66_213_000 picoseconds. - Weight::from_parts(81_661_819, 4326) - // Standard Error: 87_003 - .saturating_add(Weight::from_parts(29_550_476, 0).saturating_mul(n.into())) + // Estimated: `4326 + n * (2921 ±0)` + // Minimum execution time: 83_960_000 picoseconds. + Weight::from_parts(98_609_885, 4326) + // Standard Error: 85_991 + .saturating_add(Weight::from_parts(32_633_495, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 2954).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 2921).saturating_mul(n.into())) } } diff --git a/substrate/frame/nis/src/weights.rs b/substrate/frame/nis/src/weights.rs index 63908271391..cba2f004905 100644 --- a/substrate/frame/nis/src/weights.rs +++ b/substrate/frame/nis/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_nis` +//! Autogenerated weights for pallet_nis //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/nis/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/nis/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_nis`. +/// Weight functions needed for pallet_nis. pub trait WeightInfo { fn place_bid(l: u32, ) -> Weight; fn place_bid_max() -> Weight; @@ -64,367 +65,367 @@ pub trait WeightInfo { fn process_bid() -> Weight; } -/// Weights for `pallet_nis` using the Substrate node and recommended hardware. +/// Weights for pallet_nis using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Nis::Queues` (r:1 w:1) - /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) - /// Storage: `Nis::QueueTotals` (r:1 w:1) - /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) /// The range of component `l` is `[0, 999]`. fn place_bid(l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `6176 + l * (48 ±0)` // Estimated: `51487` - // Minimum execution time: 47_908_000 picoseconds. - Weight::from_parts(50_096_676, 51487) - // Standard Error: 208 - .saturating_add(Weight::from_parts(41_318, 0).saturating_mul(l.into())) + // Minimum execution time: 49_410_000 picoseconds. + Weight::from_parts(57_832_282, 51487) + // Standard Error: 288 + .saturating_add(Weight::from_parts(51_621, 0).saturating_mul(l.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Nis::Queues` (r:1 w:1) - /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) - /// Storage: `Nis::QueueTotals` (r:1 w:1) - /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) fn place_bid_max() -> Weight { // Proof Size summary in bytes: // Measured: `54178` // Estimated: `51487` - // Minimum execution time: 100_836_000 picoseconds. - Weight::from_parts(102_497_000, 51487) + // Minimum execution time: 119_696_000 picoseconds. + Weight::from_parts(121_838_000, 51487) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Nis::Queues` (r:1 w:1) - /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) - /// Storage: `Nis::QueueTotals` (r:1 w:1) - /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) /// The range of component `l` is `[1, 1000]`. fn retract_bid(l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `6176 + l * (48 ±0)` // Estimated: `51487` - // Minimum execution time: 45_830_000 picoseconds. - Weight::from_parts(46_667_676, 51487) - // Standard Error: 130 - .saturating_add(Weight::from_parts(33_007, 0).saturating_mul(l.into())) + // Minimum execution time: 50_843_000 picoseconds. + Weight::from_parts(54_237_365, 51487) + // Standard Error: 243 + .saturating_add(Weight::from_parts(67_732, 0).saturating_mul(l.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Nis::Summary` (r:1 w:0) - /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Nis Summary (r:1 w:0) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn fund_deficit() -> Weight { // Proof Size summary in bytes: // Measured: `191` // Estimated: `3593` - // Minimum execution time: 30_440_000 picoseconds. - Weight::from_parts(31_240_000, 3593) + // Minimum execution time: 40_752_000 picoseconds. + Weight::from_parts(41_899_000, 3593) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Nis::Receipts` (r:1 w:1) - /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Nis::Summary` (r:1 w:1) - /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) fn communify() -> Weight { // Proof Size summary in bytes: // Measured: `668` // Estimated: `3675` - // Minimum execution time: 71_017_000 picoseconds. - Weight::from_parts(72_504_000, 3675) + // Minimum execution time: 79_779_000 picoseconds. + Weight::from_parts(82_478_000, 3675) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: `Nis::Receipts` (r:1 w:1) - /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) - /// Storage: `Nis::Summary` (r:1 w:1) - /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) fn privatize() -> Weight { // Proof Size summary in bytes: // Measured: `829` // Estimated: `3675` - // Minimum execution time: 89_138_000 picoseconds. - Weight::from_parts(91_290_000, 3675) + // Minimum execution time: 99_588_000 picoseconds. + Weight::from_parts(102_340_000, 3675) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } - /// Storage: `Nis::Receipts` (r:1 w:1) - /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) - /// Storage: `Nis::Summary` (r:1 w:1) - /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:0) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) fn thaw_private() -> Weight { // Proof Size summary in bytes: // Measured: `354` - // Estimated: `3658` - // Minimum execution time: 47_917_000 picoseconds. - Weight::from_parts(49_121_000, 3658) + // Estimated: `3593` + // Minimum execution time: 53_094_000 picoseconds. + Weight::from_parts(54_543_000, 3593) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Nis::Receipts` (r:1 w:1) - /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) - /// Storage: `Nis::Summary` (r:1 w:1) - /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn thaw_communal() -> Weight { // Proof Size summary in bytes: // Measured: `773` // Estimated: `3675` - // Minimum execution time: 91_320_000 picoseconds. - Weight::from_parts(93_080_000, 3675) + // Minimum execution time: 107_248_000 picoseconds. + Weight::from_parts(109_923_000, 3675) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: `Nis::Summary` (r:1 w:1) - /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:0) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Nis::QueueTotals` (r:1 w:1) - /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) fn process_queues() -> Weight { // Proof Size summary in bytes: // Measured: `6624` // Estimated: `7487` - // Minimum execution time: 20_117_000 picoseconds. - Weight::from_parts(20_829_000, 7487) + // Minimum execution time: 27_169_000 picoseconds. + Weight::from_parts(29_201_000, 7487) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Nis::Queues` (r:1 w:1) - /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) fn process_queue() -> Weight { // Proof Size summary in bytes: // Measured: `42` // Estimated: `51487` - // Minimum execution time: 4_460_000 picoseconds. - Weight::from_parts(4_797_000, 51487) + // Minimum execution time: 4_540_000 picoseconds. + Weight::from_parts(4_699_000, 51487) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Nis::Receipts` (r:0 w:1) - /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Storage: Nis Receipts (r:0 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) fn process_bid() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_609_000 picoseconds. - Weight::from_parts(4_834_000, 0) + // Minimum execution time: 7_085_000 picoseconds. + Weight::from_parts(7_336_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Nis::Queues` (r:1 w:1) - /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) - /// Storage: `Nis::QueueTotals` (r:1 w:1) - /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) /// The range of component `l` is `[0, 999]`. fn place_bid(l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `6176 + l * (48 ±0)` // Estimated: `51487` - // Minimum execution time: 47_908_000 picoseconds. - Weight::from_parts(50_096_676, 51487) - // Standard Error: 208 - .saturating_add(Weight::from_parts(41_318, 0).saturating_mul(l.into())) + // Minimum execution time: 49_410_000 picoseconds. + Weight::from_parts(57_832_282, 51487) + // Standard Error: 288 + .saturating_add(Weight::from_parts(51_621, 0).saturating_mul(l.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Nis::Queues` (r:1 w:1) - /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) - /// Storage: `Nis::QueueTotals` (r:1 w:1) - /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) fn place_bid_max() -> Weight { // Proof Size summary in bytes: // Measured: `54178` // Estimated: `51487` - // Minimum execution time: 100_836_000 picoseconds. - Weight::from_parts(102_497_000, 51487) + // Minimum execution time: 119_696_000 picoseconds. + Weight::from_parts(121_838_000, 51487) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Nis::Queues` (r:1 w:1) - /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) - /// Storage: `Nis::QueueTotals` (r:1 w:1) - /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) /// The range of component `l` is `[1, 1000]`. fn retract_bid(l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `6176 + l * (48 ±0)` // Estimated: `51487` - // Minimum execution time: 45_830_000 picoseconds. - Weight::from_parts(46_667_676, 51487) - // Standard Error: 130 - .saturating_add(Weight::from_parts(33_007, 0).saturating_mul(l.into())) + // Minimum execution time: 50_843_000 picoseconds. + Weight::from_parts(54_237_365, 51487) + // Standard Error: 243 + .saturating_add(Weight::from_parts(67_732, 0).saturating_mul(l.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Nis::Summary` (r:1 w:0) - /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Nis Summary (r:1 w:0) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn fund_deficit() -> Weight { // Proof Size summary in bytes: // Measured: `191` // Estimated: `3593` - // Minimum execution time: 30_440_000 picoseconds. - Weight::from_parts(31_240_000, 3593) + // Minimum execution time: 40_752_000 picoseconds. + Weight::from_parts(41_899_000, 3593) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Nis::Receipts` (r:1 w:1) - /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Nis::Summary` (r:1 w:1) - /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) fn communify() -> Weight { // Proof Size summary in bytes: // Measured: `668` // Estimated: `3675` - // Minimum execution time: 71_017_000 picoseconds. - Weight::from_parts(72_504_000, 3675) + // Minimum execution time: 79_779_000 picoseconds. + Weight::from_parts(82_478_000, 3675) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } - /// Storage: `Nis::Receipts` (r:1 w:1) - /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) - /// Storage: `Nis::Summary` (r:1 w:1) - /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) fn privatize() -> Weight { // Proof Size summary in bytes: // Measured: `829` // Estimated: `3675` - // Minimum execution time: 89_138_000 picoseconds. - Weight::from_parts(91_290_000, 3675) + // Minimum execution time: 99_588_000 picoseconds. + Weight::from_parts(102_340_000, 3675) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } - /// Storage: `Nis::Receipts` (r:1 w:1) - /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) - /// Storage: `Nis::Summary` (r:1 w:1) - /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:0) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Balances Holds (r:1 w:1) + /// Proof: Balances Holds (max_values: None, max_size: Some(85), added: 2560, mode: MaxEncodedLen) fn thaw_private() -> Weight { // Proof Size summary in bytes: // Measured: `354` - // Estimated: `3658` - // Minimum execution time: 47_917_000 picoseconds. - Weight::from_parts(49_121_000, 3658) + // Estimated: `3593` + // Minimum execution time: 53_094_000 picoseconds. + Weight::from_parts(54_543_000, 3593) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Nis::Receipts` (r:1 w:1) - /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) - /// Storage: `Nis::Summary` (r:1 w:1) - /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Nis Receipts (r:1 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn thaw_communal() -> Weight { // Proof Size summary in bytes: // Measured: `773` // Estimated: `3675` - // Minimum execution time: 91_320_000 picoseconds. - Weight::from_parts(93_080_000, 3675) + // Minimum execution time: 107_248_000 picoseconds. + Weight::from_parts(109_923_000, 3675) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: `Nis::Summary` (r:1 w:1) - /// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:0) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Nis::QueueTotals` (r:1 w:1) - /// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`) + /// Storage: Nis Summary (r:1 w:1) + /// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:0) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Nis QueueTotals (r:1 w:1) + /// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen) fn process_queues() -> Weight { // Proof Size summary in bytes: // Measured: `6624` // Estimated: `7487` - // Minimum execution time: 20_117_000 picoseconds. - Weight::from_parts(20_829_000, 7487) + // Minimum execution time: 27_169_000 picoseconds. + Weight::from_parts(29_201_000, 7487) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Nis::Queues` (r:1 w:1) - /// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`) + /// Storage: Nis Queues (r:1 w:1) + /// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen) fn process_queue() -> Weight { // Proof Size summary in bytes: // Measured: `42` // Estimated: `51487` - // Minimum execution time: 4_460_000 picoseconds. - Weight::from_parts(4_797_000, 51487) + // Minimum execution time: 4_540_000 picoseconds. + Weight::from_parts(4_699_000, 51487) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Nis::Receipts` (r:0 w:1) - /// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`) + /// Storage: Nis Receipts (r:0 w:1) + /// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) fn process_bid() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_609_000 picoseconds. - Weight::from_parts(4_834_000, 0) + // Minimum execution time: 7_085_000 picoseconds. + Weight::from_parts(7_336_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } } diff --git a/substrate/frame/nomination-pools/src/weights.rs b/substrate/frame/nomination-pools/src/weights.rs index 987ddd71703..0b8c1d22fa1 100644 --- a/substrate/frame/nomination-pools/src/weights.rs +++ b/substrate/frame/nomination-pools/src/weights.rs @@ -25,6 +25,7 @@ // Executed Command: // target/production/substrate-node +// target/production/substrate-node // benchmark // pallet // --steps=50 @@ -35,8 +36,12 @@ // --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json // --pallet=pallet_nomination_pools // --chain=dev +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_nomination_pools +// --chain=dev // --header=./substrate/HEADER-APACHE2 // --output=./substrate/frame/nomination-pools/src/weights.rs +// --output=./substrate/frame/nomination-pools/src/weights.rs // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -259,14 +264,12 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:0) - /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// Storage: `NominationPools::TotalValueLocked` (r:1 w:1) /// Proof: `NominationPools::TotalValueLocked` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. fn pool_withdraw_unbonded(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1848` + // Measured: `1817` // Estimated: `4764` // Minimum execution time: 64_787_000 picoseconds. Weight::from_parts(67_920_914, 4764) @@ -293,8 +296,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:0) - /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// Storage: `NominationPools::TotalValueLocked` (r:1 w:1) /// Proof: `NominationPools::TotalValueLocked` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `NominationPools::CounterForPoolMembers` (r:1 w:1) @@ -304,7 +305,7 @@ impl WeightInfo for SubstrateWeight { /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_update(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2238` + // Measured: `2207` // Estimated: `27847` // Minimum execution time: 124_990_000 picoseconds. Weight::from_parts(129_041_398, 27847) @@ -337,12 +338,12 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:0) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) - /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:1) - /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// Storage: `NominationPools::TotalValueLocked` (r:1 w:1) /// Proof: `NominationPools::TotalValueLocked` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `NominationPools::CounterForPoolMembers` (r:1 w:1) /// Proof: `NominationPools::CounterForPoolMembers` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:1) + /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// Storage: `NominationPools::CounterForReversePoolIdLookup` (r:1 w:1) /// Proof: `NominationPools::CounterForReversePoolIdLookup` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `NominationPools::RewardPools` (r:1 w:1) @@ -849,14 +850,12 @@ impl WeightInfo for () { /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:0) - /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// Storage: `NominationPools::TotalValueLocked` (r:1 w:1) /// Proof: `NominationPools::TotalValueLocked` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. fn pool_withdraw_unbonded(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1848` + // Measured: `1817` // Estimated: `4764` // Minimum execution time: 64_787_000 picoseconds. Weight::from_parts(67_920_914, 4764) @@ -883,8 +882,6 @@ impl WeightInfo for () { /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:0) - /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// Storage: `NominationPools::TotalValueLocked` (r:1 w:1) /// Proof: `NominationPools::TotalValueLocked` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `NominationPools::CounterForPoolMembers` (r:1 w:1) @@ -894,7 +891,7 @@ impl WeightInfo for () { /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_update(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2238` + // Measured: `2207` // Estimated: `27847` // Minimum execution time: 124_990_000 picoseconds. Weight::from_parts(129_041_398, 27847) @@ -927,12 +924,12 @@ impl WeightInfo for () { /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:0) /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`) - /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:1) - /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// Storage: `NominationPools::TotalValueLocked` (r:1 w:1) /// Proof: `NominationPools::TotalValueLocked` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `NominationPools::CounterForPoolMembers` (r:1 w:1) /// Proof: `NominationPools::CounterForPoolMembers` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:1) + /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// Storage: `NominationPools::CounterForReversePoolIdLookup` (r:1 w:1) /// Proof: `NominationPools::CounterForReversePoolIdLookup` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `NominationPools::RewardPools` (r:1 w:1) diff --git a/substrate/frame/offences/benchmarking/src/mock.rs b/substrate/frame/offences/benchmarking/src/mock.rs index b3260f0841f..01ad8d64f10 100644 --- a/substrate/frame/offences/benchmarking/src/mock.rs +++ b/substrate/frame/offences/benchmarking/src/mock.rs @@ -148,7 +148,7 @@ parameter_types! { pub static ElectionsBounds: ElectionBounds = ElectionBoundsBuilder::default().build(); } -pub type Extrinsic = sp_runtime::generic::UncheckedExtrinsic; +pub type Extrinsic = sp_runtime::testing::TestXt; pub struct OnChainSeqPhragmen; impl onchain::Config for OnChainSeqPhragmen { diff --git a/substrate/frame/parameters/src/weights.rs b/substrate/frame/parameters/src/weights.rs index 340eb9e31b7..6746960b1b7 100644 --- a/substrate/frame/parameters/src/weights.rs +++ b/substrate/frame/parameters/src/weights.rs @@ -18,27 +18,25 @@ //! Autogenerated weights for `pallet_parameters` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-02-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate-node +// target/production/substrate-node // benchmark // pallet -// --chain=dev // --steps=50 // --repeat=20 -// --pallet=pallet_parameters -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/parameters/src/weights.rs +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_parameters +// --chain=dev // --header=./substrate/HEADER-APACHE2 +// --output=./substrate/frame/parameters/src/weights.rs // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -57,30 +55,22 @@ pub trait WeightInfo { /// Weights for `pallet_parameters` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Parameters::Parameters` (r:1 w:1) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) fn set_parameter() -> Weight { // Proof Size summary in bytes: - // Measured: `3` - // Estimated: `3501` - // Minimum execution time: 8_400_000 picoseconds. - Weight::from_parts(8_682_000, 3501) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) } } // For backwards compatibility and tests. impl WeightInfo for () { - /// Storage: `Parameters::Parameters` (r:1 w:1) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) fn set_parameter() -> Weight { // Proof Size summary in bytes: - // Measured: `3` - // Estimated: `3501` - // Minimum execution time: 8_400_000 picoseconds. - Weight::from_parts(8_682_000, 3501) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) } } diff --git a/substrate/frame/preimage/src/weights.rs b/substrate/frame/preimage/src/weights.rs index 6167cd53029..c11ab74c1e5 100644 --- a/substrate/frame/preimage/src/weights.rs +++ b/substrate/frame/preimage/src/weights.rs @@ -17,28 +17,26 @@ //! Autogenerated weights for `pallet_preimage` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-09-06, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-mia4uyug-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate-node +// target/production/substrate-node // benchmark // pallet -// --chain=dev // --steps=50 // --repeat=20 -// --pallet=pallet_preimage -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/preimage/src/weights.rs +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_preimage +// --chain=dev // --header=./substrate/HEADER-APACHE2 +// --output=./substrate/frame/preimage/src/weights.rs // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -72,209 +70,200 @@ impl WeightInfo for SubstrateWeight { /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Parameters::Parameters` (r:2 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 4194304]`. fn note_preimage(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `112` - // Estimated: `6012` - // Minimum execution time: 48_893_000 picoseconds. - Weight::from_parts(44_072_327, 6012) - // Standard Error: 2 - .saturating_add(Weight::from_parts(1_684, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(5_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) + // Measured: `42` + // Estimated: `3556` + // Minimum execution time: 15_936_000 picoseconds. + Weight::from_parts(16_271_000, 3556) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_916, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 4194304]`. fn note_requested_preimage(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `173` + // Measured: `106` // Estimated: `3556` - // Minimum execution time: 15_675_000 picoseconds. - Weight::from_parts(4_564_145, 3556) + // Minimum execution time: 16_468_000 picoseconds. + Weight::from_parts(17_031_000, 3556) // Standard Error: 2 - .saturating_add(Weight::from_parts(1_678, 0).saturating_mul(s.into())) + .saturating_add(Weight::from_parts(1_948, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 4194304]`. fn note_no_deposit_preimage(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `173` + // Measured: `106` // Estimated: `3556` - // Minimum execution time: 14_959_000 picoseconds. - Weight::from_parts(15_335_000, 3556) + // Minimum execution time: 16_342_000 picoseconds. + Weight::from_parts(16_535_000, 3556) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_687, 0).saturating_mul(s.into())) + .saturating_add(Weight::from_parts(1_906, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) fn unnote_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `311` - // Estimated: `3658` - // Minimum execution time: 47_378_000 picoseconds. - Weight::from_parts(48_776_000, 3658) - .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) + // Measured: `172` + // Estimated: `3556` + // Minimum execution time: 31_047_000 picoseconds. + Weight::from_parts(34_099_000, 3556) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) fn unnote_no_deposit_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `211` + // Measured: `144` // Estimated: `3556` - // Minimum execution time: 20_939_000 picoseconds. - Weight::from_parts(21_577_000, 3556) + // Minimum execution time: 32_559_000 picoseconds. + Weight::from_parts(36_677_000, 3556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) fn request_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `255` + // Measured: `172` // Estimated: `3556` - // Minimum execution time: 17_945_000 picoseconds. - Weight::from_parts(18_448_000, 3556) + // Minimum execution time: 27_887_000 picoseconds. + Weight::from_parts(30_303_000, 3556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) fn request_no_deposit_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `211` + // Measured: `144` // Estimated: `3556` - // Minimum execution time: 12_132_000 picoseconds. - Weight::from_parts(12_710_000, 3556) + // Minimum execution time: 17_256_000 picoseconds. + Weight::from_parts(19_481_000, 3556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) fn request_unnoted_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `109` + // Measured: `42` // Estimated: `3556` - // Minimum execution time: 13_014_000 picoseconds. - Weight::from_parts(13_726_000, 3556) + // Minimum execution time: 22_344_000 picoseconds. + Weight::from_parts(23_868_000, 3556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) fn request_requested_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `173` + // Measured: `106` // Estimated: `3556` - // Minimum execution time: 9_785_000 picoseconds. - Weight::from_parts(10_266_000, 3556) + // Minimum execution time: 10_542_000 picoseconds. + Weight::from_parts(11_571_000, 3556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) fn unrequest_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `211` + // Measured: `144` // Estimated: `3556` - // Minimum execution time: 18_764_000 picoseconds. - Weight::from_parts(19_635_000, 3556) + // Minimum execution time: 29_054_000 picoseconds. + Weight::from_parts(32_996_000, 3556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) fn unrequest_unnoted_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `173` + // Measured: `106` // Estimated: `3556` - // Minimum execution time: 9_624_000 picoseconds. - Weight::from_parts(10_044_000, 3556) + // Minimum execution time: 10_775_000 picoseconds. + Weight::from_parts(11_937_000, 3556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) fn unrequest_multi_referenced_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `173` + // Measured: `106` // Estimated: `3556` - // Minimum execution time: 9_432_000 picoseconds. - Weight::from_parts(9_991_000, 3556) + // Minimum execution time: 10_696_000 picoseconds. + Weight::from_parts(11_717_000, 3556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Preimage::StatusFor` (r:1023 w:1023) + /// Storage: `Preimage::StatusFor` (r:1024 w:1024) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1023 w:1023) + /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Parameters::Parameters` (r:2 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1023 w:1023) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:0 w:1023) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// The range of component `n` is `[1, 1024]`. + /// Storage: `Preimage::RequestStatusFor` (r:0 w:1024) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// The range of component `n` is `[0, 1024]`. fn ensure_updated(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0 + n * (227 ±0)` - // Estimated: `6012 + n * (2668 ±0)` - // Minimum execution time: 54_056_000 picoseconds. - Weight::from_parts(54_912_000, 6012) - // Standard Error: 42_469 - .saturating_add(Weight::from_parts(50_710_258, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into()))) - .saturating_add(T::DbWeight::get().writes((4_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 2668).saturating_mul(n.into())) + // Measured: `193 + n * (91 ±0)` + // Estimated: `3593 + n * (2566 ±0)` + // Minimum execution time: 2_452_000 picoseconds. + Weight::from_parts(2_641_000, 3593) + // Standard Error: 19_797 + .saturating_add(Weight::from_parts(15_620_946, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes(1_u64)) + .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2566).saturating_mul(n.into())) } } @@ -283,208 +272,199 @@ impl WeightInfo for () { /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Parameters::Parameters` (r:2 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 4194304]`. fn note_preimage(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `112` - // Estimated: `6012` - // Minimum execution time: 48_893_000 picoseconds. - Weight::from_parts(44_072_327, 6012) - // Standard Error: 2 - .saturating_add(Weight::from_parts(1_684, 0).saturating_mul(s.into())) - .saturating_add(RocksDbWeight::get().reads(5_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) + // Measured: `42` + // Estimated: `3556` + // Minimum execution time: 15_936_000 picoseconds. + Weight::from_parts(16_271_000, 3556) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_916, 0).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 4194304]`. fn note_requested_preimage(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `173` + // Measured: `106` // Estimated: `3556` - // Minimum execution time: 15_675_000 picoseconds. - Weight::from_parts(4_564_145, 3556) + // Minimum execution time: 16_468_000 picoseconds. + Weight::from_parts(17_031_000, 3556) // Standard Error: 2 - .saturating_add(Weight::from_parts(1_678, 0).saturating_mul(s.into())) + .saturating_add(Weight::from_parts(1_948, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 4194304]`. fn note_no_deposit_preimage(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `173` + // Measured: `106` // Estimated: `3556` - // Minimum execution time: 14_959_000 picoseconds. - Weight::from_parts(15_335_000, 3556) + // Minimum execution time: 16_342_000 picoseconds. + Weight::from_parts(16_535_000, 3556) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_687, 0).saturating_mul(s.into())) + .saturating_add(Weight::from_parts(1_906, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) fn unnote_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `311` - // Estimated: `3658` - // Minimum execution time: 47_378_000 picoseconds. - Weight::from_parts(48_776_000, 3658) - .saturating_add(RocksDbWeight::get().reads(3_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) + // Measured: `172` + // Estimated: `3556` + // Minimum execution time: 31_047_000 picoseconds. + Weight::from_parts(34_099_000, 3556) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) fn unnote_no_deposit_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `211` + // Measured: `144` // Estimated: `3556` - // Minimum execution time: 20_939_000 picoseconds. - Weight::from_parts(21_577_000, 3556) + // Minimum execution time: 32_559_000 picoseconds. + Weight::from_parts(36_677_000, 3556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) fn request_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `255` + // Measured: `172` // Estimated: `3556` - // Minimum execution time: 17_945_000 picoseconds. - Weight::from_parts(18_448_000, 3556) + // Minimum execution time: 27_887_000 picoseconds. + Weight::from_parts(30_303_000, 3556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) fn request_no_deposit_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `211` + // Measured: `144` // Estimated: `3556` - // Minimum execution time: 12_132_000 picoseconds. - Weight::from_parts(12_710_000, 3556) + // Minimum execution time: 17_256_000 picoseconds. + Weight::from_parts(19_481_000, 3556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) fn request_unnoted_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `109` + // Measured: `42` // Estimated: `3556` - // Minimum execution time: 13_014_000 picoseconds. - Weight::from_parts(13_726_000, 3556) + // Minimum execution time: 22_344_000 picoseconds. + Weight::from_parts(23_868_000, 3556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) fn request_requested_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `173` + // Measured: `106` // Estimated: `3556` - // Minimum execution time: 9_785_000 picoseconds. - Weight::from_parts(10_266_000, 3556) + // Minimum execution time: 10_542_000 picoseconds. + Weight::from_parts(11_571_000, 3556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) /// Storage: `Preimage::PreimageFor` (r:0 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`) fn unrequest_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `211` + // Measured: `144` // Estimated: `3556` - // Minimum execution time: 18_764_000 picoseconds. - Weight::from_parts(19_635_000, 3556) + // Minimum execution time: 29_054_000 picoseconds. + Weight::from_parts(32_996_000, 3556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) fn unrequest_unnoted_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `173` + // Measured: `106` // Estimated: `3556` - // Minimum execution time: 9_624_000 picoseconds. - Weight::from_parts(10_044_000, 3556) + // Minimum execution time: 10_775_000 picoseconds. + Weight::from_parts(11_937_000, 3556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Preimage::StatusFor` (r:1 w:0) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) fn unrequest_multi_referenced_preimage() -> Weight { // Proof Size summary in bytes: - // Measured: `173` + // Measured: `106` // Estimated: `3556` - // Minimum execution time: 9_432_000 picoseconds. - Weight::from_parts(9_991_000, 3556) + // Minimum execution time: 10_696_000 picoseconds. + Weight::from_parts(11_717_000, 3556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Preimage::StatusFor` (r:1023 w:1023) + /// Storage: `Preimage::StatusFor` (r:1024 w:1024) /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1023 w:1023) + /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Parameters::Parameters` (r:2 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1023 w:1023) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:0 w:1023) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// The range of component `n` is `[1, 1024]`. + /// Storage: `Preimage::RequestStatusFor` (r:0 w:1024) + /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(75), added: 2550, mode: `MaxEncodedLen`) + /// The range of component `n` is `[0, 1024]`. fn ensure_updated(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0 + n * (227 ±0)` - // Estimated: `6012 + n * (2668 ±0)` - // Minimum execution time: 54_056_000 picoseconds. - Weight::from_parts(54_912_000, 6012) - // Standard Error: 42_469 - .saturating_add(Weight::from_parts(50_710_258, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(n.into()))) - .saturating_add(RocksDbWeight::get().writes((4_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 2668).saturating_mul(n.into())) + // Measured: `193 + n * (91 ±0)` + // Estimated: `3593 + n * (2566 ±0)` + // Minimum execution time: 2_452_000 picoseconds. + Weight::from_parts(2_641_000, 3593) + // Standard Error: 19_797 + .saturating_add(Weight::from_parts(15_620_946, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + .saturating_add(RocksDbWeight::get().writes((2_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2566).saturating_mul(n.into())) } } diff --git a/substrate/frame/proxy/src/weights.rs b/substrate/frame/proxy/src/weights.rs index 3c37c91d500..f30fe73d27a 100644 --- a/substrate/frame/proxy/src/weights.rs +++ b/substrate/frame/proxy/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_proxy` +//! Autogenerated weights for pallet_proxy //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/proxy/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/proxy/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_proxy`. +/// Weight functions needed for pallet_proxy. pub trait WeightInfo { fn proxy(p: u32, ) -> Weight; fn proxy_announced(a: u32, p: u32, ) -> Weight; @@ -63,352 +64,336 @@ pub trait WeightInfo { fn kill_pure(p: u32, ) -> Weight; } -/// Weights for `pallet_proxy` using the Substrate node and recommended hardware. +/// Weights for pallet_proxy using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Proxy::Proxies` (r:1 w:0) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) /// The range of component `p` is `[1, 31]`. fn proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `306 + p * (37 ±0)` + // Measured: `161 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 18_437_000 picoseconds. - Weight::from_parts(19_610_577, 4706) - // Standard Error: 2_531 - .saturating_add(Weight::from_parts(26_001, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(3_u64)) + // Minimum execution time: 15_182_000 picoseconds. + Weight::from_parts(15_919_146, 4706) + // Standard Error: 1_586 + .saturating_add(Weight::from_parts(31_768, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(1_u64)) } - /// Storage: `Proxy::Proxies` (r:1 w:0) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) - /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn proxy_announced(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `633 + a * (68 ±0) + p * (37 ±0)` + // Measured: `488 + a * (68 ±0) + p * (37 ±0)` // Estimated: `5698` - // Minimum execution time: 40_426_000 picoseconds. - Weight::from_parts(40_200_295, 5698) - // Standard Error: 2_922 - .saturating_add(Weight::from_parts(161_885, 0).saturating_mul(a.into())) - // Standard Error: 3_019 - .saturating_add(Weight::from_parts(69_710, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(5_u64)) + // Minimum execution time: 40_256_000 picoseconds. + Weight::from_parts(40_373_648, 5698) + // Standard Error: 3_978 + .saturating_add(Weight::from_parts(166_936, 0).saturating_mul(a.into())) + // Standard Error: 4_110 + .saturating_add(Weight::from_parts(54_329, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn remove_announcement(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `403 + a * (68 ±0)` // Estimated: `5698` - // Minimum execution time: 21_905_000 picoseconds. - Weight::from_parts(22_717_430, 5698) - // Standard Error: 2_004 - .saturating_add(Weight::from_parts(153_390, 0).saturating_mul(a.into())) - // Standard Error: 2_071 - .saturating_add(Weight::from_parts(5_676, 0).saturating_mul(p.into())) + // Minimum execution time: 25_040_000 picoseconds. + Weight::from_parts(25_112_188, 5698) + // Standard Error: 2_143 + .saturating_add(Weight::from_parts(189_027, 0).saturating_mul(a.into())) + // Standard Error: 2_214 + .saturating_add(Weight::from_parts(26_683, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn reject_announcement(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `403 + a * (68 ±0)` // Estimated: `5698` - // Minimum execution time: 21_974_000 picoseconds. - Weight::from_parts(22_484_324, 5698) - // Standard Error: 1_846 - .saturating_add(Weight::from_parts(153_904, 0).saturating_mul(a.into())) - // Standard Error: 1_907 - .saturating_add(Weight::from_parts(9_616, 0).saturating_mul(p.into())) + // Minimum execution time: 24_884_000 picoseconds. + Weight::from_parts(25_359_291, 5698) + // Standard Error: 2_019 + .saturating_add(Weight::from_parts(181_470, 0).saturating_mul(a.into())) + // Standard Error: 2_086 + .saturating_add(Weight::from_parts(17_725, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Proxy::Proxies` (r:1 w:0) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) - /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn announce(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `420 + a * (68 ±0) + p * (37 ±0)` // Estimated: `5698` - // Minimum execution time: 30_454_000 picoseconds. - Weight::from_parts(32_128_158, 5698) - // Standard Error: 3_778 - .saturating_add(Weight::from_parts(137_366, 0).saturating_mul(a.into())) - // Standard Error: 3_904 - .saturating_add(Weight::from_parts(53_040, 0).saturating_mul(p.into())) + // Minimum execution time: 35_039_000 picoseconds. + Weight::from_parts(36_727_868, 5698) + // Standard Error: 4_463 + .saturating_add(Weight::from_parts(167_060, 0).saturating_mul(a.into())) + // Standard Error: 4_611 + .saturating_add(Weight::from_parts(59_836, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) /// The range of component `p` is `[1, 31]`. fn add_proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `161 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 21_391_000 picoseconds. - Weight::from_parts(22_202_614, 4706) - // Standard Error: 1_750 - .saturating_add(Weight::from_parts(49_639, 0).saturating_mul(p.into())) + // Minimum execution time: 25_697_000 picoseconds. + Weight::from_parts(26_611_090, 4706) + // Standard Error: 2_306 + .saturating_add(Weight::from_parts(85_165, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) /// The range of component `p` is `[1, 31]`. fn remove_proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `161 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 21_375_000 picoseconds. - Weight::from_parts(22_392_601, 4706) - // Standard Error: 2_415 - .saturating_add(Weight::from_parts(40_345, 0).saturating_mul(p.into())) + // Minimum execution time: 25_638_000 picoseconds. + Weight::from_parts(26_904_510, 4706) + // Standard Error: 2_669 + .saturating_add(Weight::from_parts(61_668, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) /// The range of component `p` is `[1, 31]`. fn remove_proxies(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `161 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 19_833_000 picoseconds. - Weight::from_parts(20_839_747, 4706) - // Standard Error: 1_742 - .saturating_add(Weight::from_parts(40_874, 0).saturating_mul(p.into())) + // Minimum execution time: 22_737_000 picoseconds. + Weight::from_parts(23_618_441, 4706) + // Standard Error: 1_729 + .saturating_add(Weight::from_parts(44_009, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) /// The range of component `p` is `[1, 31]`. fn create_pure(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `173` // Estimated: `4706` - // Minimum execution time: 22_231_000 picoseconds. - Weight::from_parts(23_370_995, 4706) - // Standard Error: 1_521 - .saturating_add(Weight::from_parts(4_892, 0).saturating_mul(p.into())) + // Minimum execution time: 27_364_000 picoseconds. + Weight::from_parts(28_632_271, 4706) + // Standard Error: 1_613 + .saturating_add(Weight::from_parts(2_453, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) /// The range of component `p` is `[0, 30]`. fn kill_pure(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `198 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 20_614_000 picoseconds. - Weight::from_parts(21_845_970, 4706) - // Standard Error: 1_636 - .saturating_add(Weight::from_parts(34_480, 0).saturating_mul(p.into())) + // Minimum execution time: 23_552_000 picoseconds. + Weight::from_parts(24_874_553, 4706) + // Standard Error: 1_919 + .saturating_add(Weight::from_parts(38_799, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Proxy::Proxies` (r:1 w:0) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) /// The range of component `p` is `[1, 31]`. fn proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `306 + p * (37 ±0)` + // Measured: `161 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 18_437_000 picoseconds. - Weight::from_parts(19_610_577, 4706) - // Standard Error: 2_531 - .saturating_add(Weight::from_parts(26_001, 0).saturating_mul(p.into())) - .saturating_add(RocksDbWeight::get().reads(3_u64)) + // Minimum execution time: 15_182_000 picoseconds. + Weight::from_parts(15_919_146, 4706) + // Standard Error: 1_586 + .saturating_add(Weight::from_parts(31_768, 0).saturating_mul(p.into())) + .saturating_add(RocksDbWeight::get().reads(1_u64)) } - /// Storage: `Proxy::Proxies` (r:1 w:0) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) - /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn proxy_announced(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `633 + a * (68 ±0) + p * (37 ±0)` + // Measured: `488 + a * (68 ±0) + p * (37 ±0)` // Estimated: `5698` - // Minimum execution time: 40_426_000 picoseconds. - Weight::from_parts(40_200_295, 5698) - // Standard Error: 2_922 - .saturating_add(Weight::from_parts(161_885, 0).saturating_mul(a.into())) - // Standard Error: 3_019 - .saturating_add(Weight::from_parts(69_710, 0).saturating_mul(p.into())) - .saturating_add(RocksDbWeight::get().reads(5_u64)) + // Minimum execution time: 40_256_000 picoseconds. + Weight::from_parts(40_373_648, 5698) + // Standard Error: 3_978 + .saturating_add(Weight::from_parts(166_936, 0).saturating_mul(a.into())) + // Standard Error: 4_110 + .saturating_add(Weight::from_parts(54_329, 0).saturating_mul(p.into())) + .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn remove_announcement(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `403 + a * (68 ±0)` // Estimated: `5698` - // Minimum execution time: 21_905_000 picoseconds. - Weight::from_parts(22_717_430, 5698) - // Standard Error: 2_004 - .saturating_add(Weight::from_parts(153_390, 0).saturating_mul(a.into())) - // Standard Error: 2_071 - .saturating_add(Weight::from_parts(5_676, 0).saturating_mul(p.into())) + // Minimum execution time: 25_040_000 picoseconds. + Weight::from_parts(25_112_188, 5698) + // Standard Error: 2_143 + .saturating_add(Weight::from_parts(189_027, 0).saturating_mul(a.into())) + // Standard Error: 2_214 + .saturating_add(Weight::from_parts(26_683, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn reject_announcement(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `403 + a * (68 ±0)` // Estimated: `5698` - // Minimum execution time: 21_974_000 picoseconds. - Weight::from_parts(22_484_324, 5698) - // Standard Error: 1_846 - .saturating_add(Weight::from_parts(153_904, 0).saturating_mul(a.into())) - // Standard Error: 1_907 - .saturating_add(Weight::from_parts(9_616, 0).saturating_mul(p.into())) + // Minimum execution time: 24_884_000 picoseconds. + Weight::from_parts(25_359_291, 5698) + // Standard Error: 2_019 + .saturating_add(Weight::from_parts(181_470, 0).saturating_mul(a.into())) + // Standard Error: 2_086 + .saturating_add(Weight::from_parts(17_725, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Proxy::Proxies` (r:1 w:0) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) - /// Storage: `Proxy::Announcements` (r:1 w:1) - /// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:0) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) + /// Storage: Proxy Announcements (r:1 w:1) + /// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `a` is `[0, 31]`. /// The range of component `p` is `[1, 31]`. fn announce(a: u32, p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `420 + a * (68 ±0) + p * (37 ±0)` // Estimated: `5698` - // Minimum execution time: 30_454_000 picoseconds. - Weight::from_parts(32_128_158, 5698) - // Standard Error: 3_778 - .saturating_add(Weight::from_parts(137_366, 0).saturating_mul(a.into())) - // Standard Error: 3_904 - .saturating_add(Weight::from_parts(53_040, 0).saturating_mul(p.into())) + // Minimum execution time: 35_039_000 picoseconds. + Weight::from_parts(36_727_868, 5698) + // Standard Error: 4_463 + .saturating_add(Weight::from_parts(167_060, 0).saturating_mul(a.into())) + // Standard Error: 4_611 + .saturating_add(Weight::from_parts(59_836, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) /// The range of component `p` is `[1, 31]`. fn add_proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `161 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 21_391_000 picoseconds. - Weight::from_parts(22_202_614, 4706) - // Standard Error: 1_750 - .saturating_add(Weight::from_parts(49_639, 0).saturating_mul(p.into())) + // Minimum execution time: 25_697_000 picoseconds. + Weight::from_parts(26_611_090, 4706) + // Standard Error: 2_306 + .saturating_add(Weight::from_parts(85_165, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) /// The range of component `p` is `[1, 31]`. fn remove_proxy(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `161 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 21_375_000 picoseconds. - Weight::from_parts(22_392_601, 4706) - // Standard Error: 2_415 - .saturating_add(Weight::from_parts(40_345, 0).saturating_mul(p.into())) + // Minimum execution time: 25_638_000 picoseconds. + Weight::from_parts(26_904_510, 4706) + // Standard Error: 2_669 + .saturating_add(Weight::from_parts(61_668, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) /// The range of component `p` is `[1, 31]`. fn remove_proxies(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `161 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 19_833_000 picoseconds. - Weight::from_parts(20_839_747, 4706) - // Standard Error: 1_742 - .saturating_add(Weight::from_parts(40_874, 0).saturating_mul(p.into())) + // Minimum execution time: 22_737_000 picoseconds. + Weight::from_parts(23_618_441, 4706) + // Standard Error: 1_729 + .saturating_add(Weight::from_parts(44_009, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) /// The range of component `p` is `[1, 31]`. fn create_pure(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `173` // Estimated: `4706` - // Minimum execution time: 22_231_000 picoseconds. - Weight::from_parts(23_370_995, 4706) - // Standard Error: 1_521 - .saturating_add(Weight::from_parts(4_892, 0).saturating_mul(p.into())) + // Minimum execution time: 27_364_000 picoseconds. + Weight::from_parts(28_632_271, 4706) + // Standard Error: 1_613 + .saturating_add(Weight::from_parts(2_453, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Proxy::Proxies` (r:1 w:1) - /// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`) + /// Storage: Proxy Proxies (r:1 w:1) + /// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen) /// The range of component `p` is `[0, 30]`. fn kill_pure(p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `198 + p * (37 ±0)` // Estimated: `4706` - // Minimum execution time: 20_614_000 picoseconds. - Weight::from_parts(21_845_970, 4706) - // Standard Error: 1_636 - .saturating_add(Weight::from_parts(34_480, 0).saturating_mul(p.into())) + // Minimum execution time: 23_552_000 picoseconds. + Weight::from_parts(24_874_553, 4706) + // Standard Error: 1_919 + .saturating_add(Weight::from_parts(38_799, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/ranked-collective/src/weights.rs b/substrate/frame/ranked-collective/src/weights.rs index 5721858f7e2..4ff0c3337d5 100644 --- a/substrate/frame/ranked-collective/src/weights.rs +++ b/substrate/frame/ranked-collective/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_ranked_collective` +//! Autogenerated weights for pallet_ranked_collective //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/ranked-collective/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/ranked-collective/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_ranked_collective`. +/// Weight functions needed for pallet_ranked_collective. pub trait WeightInfo { fn add_member() -> Weight; fn remove_member(r: u32, ) -> Weight; @@ -60,295 +61,283 @@ pub trait WeightInfo { fn exchange_member() -> Weight; } -/// Weights for `pallet_ranked_collective` using the Substrate node and recommended hardware. +/// Weights for pallet_ranked_collective using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `RankedCollective::Members` (r:1 w:1) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::MemberCount` (r:1 w:1) - /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IndexToId` (r:0 w:1) - /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:0 w:1) - /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:1) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: RankedCollective MemberCount (r:1 w:1) + /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: RankedCollective IndexToId (r:0 w:1) + /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: RankedCollective IdToIndex (r:0 w:1) + /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) fn add_member() -> Weight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3507` - // Minimum execution time: 15_389_000 picoseconds. - Weight::from_parts(15_901_000, 3507) + // Minimum execution time: 17_245_000 picoseconds. + Weight::from_parts(17_930_000, 3507) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `RankedCollective::Members` (r:1 w:1) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::MemberCount` (r:11 w:11) - /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:11 w:22) - /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IndexToId` (r:11 w:22) - /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:1) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: RankedCollective MemberCount (r:11 w:11) + /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: RankedCollective IdToIndex (r:11 w:11) + /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: RankedCollective IndexToId (r:11 w:11) + /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) /// The range of component `r` is `[0, 10]`. fn remove_member(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `616 + r * (281 ±0)` // Estimated: `3519 + r * (2529 ±0)` - // Minimum execution time: 29_541_000 picoseconds. - Weight::from_parts(32_239_358, 3519) - // Standard Error: 23_406 - .saturating_add(Weight::from_parts(16_030_191, 0).saturating_mul(r.into())) + // Minimum execution time: 29_534_000 picoseconds. + Weight::from_parts(32_847_495, 3519) + // Standard Error: 24_211 + .saturating_add(Weight::from_parts(13_949_639, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) - .saturating_add(T::DbWeight::get().writes(6_u64)) - .saturating_add(T::DbWeight::get().writes((5_u64).saturating_mul(r.into()))) + .saturating_add(T::DbWeight::get().writes(4_u64)) + .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2529).saturating_mul(r.into())) } - /// Storage: `RankedCollective::Members` (r:1 w:1) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::MemberCount` (r:1 w:1) - /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IndexToId` (r:0 w:1) - /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:0 w:1) - /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:1) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: RankedCollective MemberCount (r:1 w:1) + /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: RankedCollective IndexToId (r:0 w:1) + /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: RankedCollective IdToIndex (r:0 w:1) + /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) /// The range of component `r` is `[0, 10]`. fn promote_member(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `314 + r * (17 ±0)` // Estimated: `3507` - // Minimum execution time: 17_939_000 picoseconds. - Weight::from_parts(19_290_416, 3507) - // Standard Error: 5_710 - .saturating_add(Weight::from_parts(374_399, 0).saturating_mul(r.into())) + // Minimum execution time: 20_333_000 picoseconds. + Weight::from_parts(21_592_224, 3507) + // Standard Error: 6_423 + .saturating_add(Weight::from_parts(321_314, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `RankedCollective::Members` (r:1 w:1) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::MemberCount` (r:1 w:1) - /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:1 w:2) - /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IndexToId` (r:1 w:2) - /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:1) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: RankedCollective MemberCount (r:1 w:1) + /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: RankedCollective IdToIndex (r:1 w:1) + /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: RankedCollective IndexToId (r:1 w:1) + /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) /// The range of component `r` is `[0, 10]`. fn demote_member(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `632 + r * (72 ±0)` // Estimated: `3519` - // Minimum execution time: 29_609_000 picoseconds. - Weight::from_parts(32_686_167, 3519) - // Standard Error: 27_588 - .saturating_add(Weight::from_parts(789_212, 0).saturating_mul(r.into())) + // Minimum execution time: 29_446_000 picoseconds. + Weight::from_parts(32_447_715, 3519) + // Standard Error: 28_791 + .saturating_add(Weight::from_parts(822_890, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `RankedCollective::Members` (r:1 w:0) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `RankedPolls::ReferendumInfoFor` (r:1 w:1) - /// Proof: `RankedPolls::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(330), added: 2805, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::Voting` (r:1 w:1) - /// Proof: `RankedCollective::Voting` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:0) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: RankedPolls ReferendumInfoFor (r:1 w:1) + /// Proof: RankedPolls ReferendumInfoFor (max_values: None, max_size: Some(330), added: 2805, mode: MaxEncodedLen) + /// Storage: RankedCollective Voting (r:1 w:1) + /// Proof: RankedCollective Voting (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn vote() -> Weight { // Proof Size summary in bytes: // Measured: `628` // Estimated: `219984` - // Minimum execution time: 41_151_000 picoseconds. - Weight::from_parts(42_435_000, 219984) + // Minimum execution time: 45_474_000 picoseconds. + Weight::from_parts(47_228_000, 219984) .saturating_add(T::DbWeight::get().reads(5_u64)) - .saturating_add(T::DbWeight::get().writes(5_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `RankedPolls::ReferendumInfoFor` (r:1 w:0) - /// Proof: `RankedPolls::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(330), added: 2805, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::VotingCleanup` (r:1 w:0) - /// Proof: `RankedCollective::VotingCleanup` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::Voting` (r:100 w:100) - /// Proof: `RankedCollective::Voting` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: RankedPolls ReferendumInfoFor (r:1 w:0) + /// Proof: RankedPolls ReferendumInfoFor (max_values: None, max_size: Some(330), added: 2805, mode: MaxEncodedLen) + /// Storage: RankedCollective VotingCleanup (r:1 w:0) + /// Proof: RankedCollective VotingCleanup (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: RankedCollective Voting (r:100 w:100) + /// Proof: RankedCollective Voting (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) /// The range of component `n` is `[0, 100]`. fn cleanup_poll(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `462 + n * (50 ±0)` // Estimated: `3795 + n * (2540 ±0)` - // Minimum execution time: 13_563_000 picoseconds. - Weight::from_parts(17_495_215, 3795) - // Standard Error: 2_294 - .saturating_add(Weight::from_parts(1_207_393, 0).saturating_mul(n.into())) + // Minimum execution time: 13_903_000 picoseconds. + Weight::from_parts(18_209_102, 3795) + // Standard Error: 2_556 + .saturating_add(Weight::from_parts(1_237_454, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) .saturating_add(Weight::from_parts(0, 2540).saturating_mul(n.into())) } + /// Storage: `RankedCollective::Members` (r:2 w:2) /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) /// Storage: `RankedCollective::MemberCount` (r:2 w:2) /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:2 w:4) + /// Storage: `RankedCollective::IdToIndex` (r:2 w:2) /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::Member` (r:2 w:2) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:0) - /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) - /// Storage: `Salary::Claimant` (r:2 w:2) - /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) /// Storage: `RankedCollective::IndexToId` (r:0 w:2) /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn exchange_member() -> Weight { // Proof Size summary in bytes: - // Measured: `625` - // Estimated: `19894` - // Minimum execution time: 70_713_000 picoseconds. - Weight::from_parts(72_831_000, 19894) - .saturating_add(T::DbWeight::get().reads(11_u64)) - .saturating_add(T::DbWeight::get().writes(14_u64)) + // Measured: `437` + // Estimated: `6048` + // Minimum execution time: 138_000_000 picoseconds. + Weight::from_parts(141_000_000, 0) + .saturating_add(Weight::from_parts(0, 6048)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(8)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `RankedCollective::Members` (r:1 w:1) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::MemberCount` (r:1 w:1) - /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IndexToId` (r:0 w:1) - /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:0 w:1) - /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:1) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: RankedCollective MemberCount (r:1 w:1) + /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: RankedCollective IndexToId (r:0 w:1) + /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: RankedCollective IdToIndex (r:0 w:1) + /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) fn add_member() -> Weight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3507` - // Minimum execution time: 15_389_000 picoseconds. - Weight::from_parts(15_901_000, 3507) + // Minimum execution time: 17_245_000 picoseconds. + Weight::from_parts(17_930_000, 3507) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `RankedCollective::Members` (r:1 w:1) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::MemberCount` (r:11 w:11) - /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:11 w:22) - /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IndexToId` (r:11 w:22) - /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:1) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: RankedCollective MemberCount (r:11 w:11) + /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: RankedCollective IdToIndex (r:11 w:11) + /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: RankedCollective IndexToId (r:11 w:11) + /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) /// The range of component `r` is `[0, 10]`. fn remove_member(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `616 + r * (281 ±0)` // Estimated: `3519 + r * (2529 ±0)` - // Minimum execution time: 29_541_000 picoseconds. - Weight::from_parts(32_239_358, 3519) - // Standard Error: 23_406 - .saturating_add(Weight::from_parts(16_030_191, 0).saturating_mul(r.into())) + // Minimum execution time: 29_534_000 picoseconds. + Weight::from_parts(32_847_495, 3519) + // Standard Error: 24_211 + .saturating_add(Weight::from_parts(13_949_639, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) - .saturating_add(RocksDbWeight::get().writes(6_u64)) - .saturating_add(RocksDbWeight::get().writes((5_u64).saturating_mul(r.into()))) + .saturating_add(RocksDbWeight::get().writes(4_u64)) + .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2529).saturating_mul(r.into())) } - /// Storage: `RankedCollective::Members` (r:1 w:1) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::MemberCount` (r:1 w:1) - /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IndexToId` (r:0 w:1) - /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:0 w:1) - /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:1) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: RankedCollective MemberCount (r:1 w:1) + /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: RankedCollective IndexToId (r:0 w:1) + /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: RankedCollective IdToIndex (r:0 w:1) + /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) /// The range of component `r` is `[0, 10]`. fn promote_member(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `314 + r * (17 ±0)` // Estimated: `3507` - // Minimum execution time: 17_939_000 picoseconds. - Weight::from_parts(19_290_416, 3507) - // Standard Error: 5_710 - .saturating_add(Weight::from_parts(374_399, 0).saturating_mul(r.into())) + // Minimum execution time: 20_333_000 picoseconds. + Weight::from_parts(21_592_224, 3507) + // Standard Error: 6_423 + .saturating_add(Weight::from_parts(321_314, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `RankedCollective::Members` (r:1 w:1) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::MemberCount` (r:1 w:1) - /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:1 w:2) - /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IndexToId` (r:1 w:2) - /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:1) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: RankedCollective MemberCount (r:1 w:1) + /// Proof: RankedCollective MemberCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: RankedCollective IdToIndex (r:1 w:1) + /// Proof: RankedCollective IdToIndex (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) + /// Storage: RankedCollective IndexToId (r:1 w:1) + /// Proof: RankedCollective IndexToId (max_values: None, max_size: Some(54), added: 2529, mode: MaxEncodedLen) /// The range of component `r` is `[0, 10]`. fn demote_member(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `632 + r * (72 ±0)` // Estimated: `3519` - // Minimum execution time: 29_609_000 picoseconds. - Weight::from_parts(32_686_167, 3519) - // Standard Error: 27_588 - .saturating_add(Weight::from_parts(789_212, 0).saturating_mul(r.into())) + // Minimum execution time: 29_446_000 picoseconds. + Weight::from_parts(32_447_715, 3519) + // Standard Error: 28_791 + .saturating_add(Weight::from_parts(822_890, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(6_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `RankedCollective::Members` (r:1 w:0) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `RankedPolls::ReferendumInfoFor` (r:1 w:1) - /// Proof: `RankedPolls::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(330), added: 2805, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::Voting` (r:1 w:1) - /// Proof: `RankedCollective::Voting` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:0) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: RankedPolls ReferendumInfoFor (r:1 w:1) + /// Proof: RankedPolls ReferendumInfoFor (max_values: None, max_size: Some(330), added: 2805, mode: MaxEncodedLen) + /// Storage: RankedCollective Voting (r:1 w:1) + /// Proof: RankedCollective Voting (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn vote() -> Weight { // Proof Size summary in bytes: // Measured: `628` // Estimated: `219984` - // Minimum execution time: 41_151_000 picoseconds. - Weight::from_parts(42_435_000, 219984) + // Minimum execution time: 45_474_000 picoseconds. + Weight::from_parts(47_228_000, 219984) .saturating_add(RocksDbWeight::get().reads(5_u64)) - .saturating_add(RocksDbWeight::get().writes(5_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `RankedPolls::ReferendumInfoFor` (r:1 w:0) - /// Proof: `RankedPolls::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(330), added: 2805, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::VotingCleanup` (r:1 w:0) - /// Proof: `RankedCollective::VotingCleanup` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::Voting` (r:100 w:100) - /// Proof: `RankedCollective::Voting` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Storage: RankedPolls ReferendumInfoFor (r:1 w:0) + /// Proof: RankedPolls ReferendumInfoFor (max_values: None, max_size: Some(330), added: 2805, mode: MaxEncodedLen) + /// Storage: RankedCollective VotingCleanup (r:1 w:0) + /// Proof: RankedCollective VotingCleanup (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen) + /// Storage: RankedCollective Voting (r:100 w:100) + /// Proof: RankedCollective Voting (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) /// The range of component `n` is `[0, 100]`. fn cleanup_poll(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `462 + n * (50 ±0)` // Estimated: `3795 + n * (2540 ±0)` - // Minimum execution time: 13_563_000 picoseconds. - Weight::from_parts(17_495_215, 3795) - // Standard Error: 2_294 - .saturating_add(Weight::from_parts(1_207_393, 0).saturating_mul(n.into())) + // Minimum execution time: 13_903_000 picoseconds. + Weight::from_parts(18_209_102, 3795) + // Standard Error: 2_556 + .saturating_add(Weight::from_parts(1_237_454, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into()))) .saturating_add(Weight::from_parts(0, 2540).saturating_mul(n.into())) } + /// Storage: `RankedCollective::Members` (r:2 w:2) /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) /// Storage: `RankedCollective::MemberCount` (r:2 w:2) /// Proof: `RankedCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::IdToIndex` (r:2 w:4) + /// Storage: `RankedCollective::IdToIndex` (r:2 w:2) /// Proof: `RankedCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::Member` (r:2 w:2) - /// Proof: `CoreFellowship::Member` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `CoreFellowship::MemberEvidence` (r:1 w:0) - /// Proof: `CoreFellowship::MemberEvidence` (`max_values`: None, `max_size`: Some(16429), added: 18904, mode: `MaxEncodedLen`) - /// Storage: `Salary::Claimant` (r:2 w:2) - /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) /// Storage: `RankedCollective::IndexToId` (r:0 w:2) /// Proof: `RankedCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) fn exchange_member() -> Weight { // Proof Size summary in bytes: - // Measured: `625` - // Estimated: `19894` - // Minimum execution time: 70_713_000 picoseconds. - Weight::from_parts(72_831_000, 19894) - .saturating_add(RocksDbWeight::get().reads(11_u64)) - .saturating_add(RocksDbWeight::get().writes(14_u64)) + // Measured: `437` + // Estimated: `6048` + // Minimum execution time: 138_000_000 picoseconds. + Weight::from_parts(141_000_000, 0) + .saturating_add(Weight::from_parts(0, 6048)) + .saturating_add(RocksDbWeight::get().reads(6)) + .saturating_add(RocksDbWeight::get().writes(8)) } } diff --git a/substrate/frame/recovery/src/weights.rs b/substrate/frame/recovery/src/weights.rs index fe5dbcfc222..84b19ae694e 100644 --- a/substrate/frame/recovery/src/weights.rs +++ b/substrate/frame/recovery/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_recovery` +//! Autogenerated weights for pallet_recovery //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/recovery/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/recovery/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_recovery`. +/// Weight functions needed for pallet_recovery. pub trait WeightInfo { fn as_recovered() -> Weight; fn set_recovered() -> Weight; @@ -62,266 +63,258 @@ pub trait WeightInfo { fn cancel_recovered() -> Weight; } -/// Weights for `pallet_recovery` using the Substrate node and recommended hardware. +/// Weights for pallet_recovery using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Recovery::Proxy` (r:1 w:0) - /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: Recovery Proxy (r:1 w:0) + /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) fn as_recovered() -> Weight { // Proof Size summary in bytes: - // Measured: `497` - // Estimated: `3997` - // Minimum execution time: 14_898_000 picoseconds. - Weight::from_parts(15_464_000, 3997) - .saturating_add(T::DbWeight::get().reads(3_u64)) + // Measured: `281` + // Estimated: `3545` + // Minimum execution time: 9_360_000 picoseconds. + Weight::from_parts(9_773_000, 3545) + .saturating_add(T::DbWeight::get().reads(1_u64)) } - /// Storage: `Recovery::Proxy` (r:0 w:1) - /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + /// Storage: Recovery Proxy (r:0 w:1) + /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) fn set_recovered() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_424_000 picoseconds. - Weight::from_parts(7_830_000, 0) + // Minimum execution time: 9_146_000 picoseconds. + Weight::from_parts(9_507_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Recovery::Recoverable` (r:1 w:1) - /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) + /// Storage: Recovery Recoverable (r:1 w:1) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) /// The range of component `n` is `[1, 9]`. fn create_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `246` + // Measured: `175` // Estimated: `3816` - // Minimum execution time: 21_968_000 picoseconds. - Weight::from_parts(23_594_232, 3816) - // Standard Error: 5_848 - .saturating_add(Weight::from_parts(24_843, 0).saturating_mul(n.into())) + // Minimum execution time: 26_472_000 picoseconds. + Weight::from_parts(27_917_651, 3816) + // Standard Error: 7_129 + .saturating_add(Weight::from_parts(59_239, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Recovery::Recoverable` (r:1 w:0) - /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) - /// Storage: `Recovery::ActiveRecoveries` (r:1 w:1) - /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) + /// Storage: Recovery Recoverable (r:1 w:0) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// Storage: Recovery ActiveRecoveries (r:1 w:1) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) fn initiate_recovery() -> Weight { // Proof Size summary in bytes: - // Measured: `343` + // Measured: `272` // Estimated: `3854` - // Minimum execution time: 25_494_000 picoseconds. - Weight::from_parts(26_290_000, 3854) + // Minimum execution time: 29_618_000 picoseconds. + Weight::from_parts(30_192_000, 3854) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Recovery::Recoverable` (r:1 w:0) - /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) - /// Storage: `Recovery::ActiveRecoveries` (r:1 w:1) - /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) + /// Storage: Recovery Recoverable (r:1 w:0) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// Storage: Recovery ActiveRecoveries (r:1 w:1) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) /// The range of component `n` is `[1, 9]`. fn vouch_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `431 + n * (64 ±0)` + // Measured: `360 + n * (64 ±0)` // Estimated: `3854` - // Minimum execution time: 17_044_000 picoseconds. - Weight::from_parts(18_299_617, 3854) - // Standard Error: 5_580 - .saturating_add(Weight::from_parts(187_568, 0).saturating_mul(n.into())) + // Minimum execution time: 19_464_000 picoseconds. + Weight::from_parts(20_642_522, 3854) + // Standard Error: 5_974 + .saturating_add(Weight::from_parts(142_308, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Recovery::Recoverable` (r:1 w:0) - /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) - /// Storage: `Recovery::ActiveRecoveries` (r:1 w:0) - /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) - /// Storage: `Recovery::Proxy` (r:1 w:1) - /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + /// Storage: Recovery Recoverable (r:1 w:0) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// Storage: Recovery ActiveRecoveries (r:1 w:0) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + /// Storage: Recovery Proxy (r:1 w:1) + /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) /// The range of component `n` is `[1, 9]`. fn claim_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `463 + n * (64 ±0)` + // Measured: `392 + n * (64 ±0)` // Estimated: `3854` - // Minimum execution time: 22_186_000 picoseconds. - Weight::from_parts(23_476_807, 3854) - // Standard Error: 6_392 - .saturating_add(Weight::from_parts(89_770, 0).saturating_mul(n.into())) + // Minimum execution time: 23_656_000 picoseconds. + Weight::from_parts(24_903_269, 3854) + // Standard Error: 5_771 + .saturating_add(Weight::from_parts(117_343, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Recovery::ActiveRecoveries` (r:1 w:1) - /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Recovery ActiveRecoveries (r:1 w:1) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `n` is `[1, 9]`. fn close_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `584 + n * (32 ±0)` + // Measured: `513 + n * (32 ±0)` // Estimated: `3854` - // Minimum execution time: 31_045_000 picoseconds. - Weight::from_parts(32_623_578, 3854) - // Standard Error: 7_203 - .saturating_add(Weight::from_parts(61_466, 0).saturating_mul(n.into())) + // Minimum execution time: 34_866_000 picoseconds. + Weight::from_parts(36_368_748, 3854) + // Standard Error: 6_600 + .saturating_add(Weight::from_parts(118_610, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Recovery::ActiveRecoveries` (r:1 w:0) - /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) - /// Storage: `Recovery::Recoverable` (r:1 w:1) - /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) + /// Storage: Recovery ActiveRecoveries (r:1 w:0) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + /// Storage: Recovery Recoverable (r:1 w:1) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) /// The range of component `n` is `[1, 9]`. fn remove_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `341 + n * (32 ±0)` + // Measured: `270 + n * (32 ±0)` // Estimated: `3854` - // Minimum execution time: 27_925_000 picoseconds. - Weight::from_parts(29_258_264, 3854) - // Standard Error: 8_192 - .saturating_add(Weight::from_parts(128_124, 0).saturating_mul(n.into())) + // Minimum execution time: 31_405_000 picoseconds. + Weight::from_parts(32_552_838, 3854) + // Standard Error: 8_043 + .saturating_add(Weight::from_parts(171_605, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Recovery::Proxy` (r:1 w:1) - /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + /// Storage: Recovery Proxy (r:1 w:1) + /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) fn cancel_recovered() -> Weight { // Proof Size summary in bytes: - // Measured: `352` + // Measured: `281` // Estimated: `3545` - // Minimum execution time: 11_623_000 picoseconds. - Weight::from_parts(12_043_000, 3545) + // Minimum execution time: 11_530_000 picoseconds. + Weight::from_parts(11_851_000, 3545) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Recovery::Proxy` (r:1 w:0) - /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) + /// Storage: Recovery Proxy (r:1 w:0) + /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) fn as_recovered() -> Weight { // Proof Size summary in bytes: - // Measured: `497` - // Estimated: `3997` - // Minimum execution time: 14_898_000 picoseconds. - Weight::from_parts(15_464_000, 3997) - .saturating_add(RocksDbWeight::get().reads(3_u64)) + // Measured: `281` + // Estimated: `3545` + // Minimum execution time: 9_360_000 picoseconds. + Weight::from_parts(9_773_000, 3545) + .saturating_add(RocksDbWeight::get().reads(1_u64)) } - /// Storage: `Recovery::Proxy` (r:0 w:1) - /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + /// Storage: Recovery Proxy (r:0 w:1) + /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) fn set_recovered() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_424_000 picoseconds. - Weight::from_parts(7_830_000, 0) + // Minimum execution time: 9_146_000 picoseconds. + Weight::from_parts(9_507_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Recovery::Recoverable` (r:1 w:1) - /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) + /// Storage: Recovery Recoverable (r:1 w:1) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) /// The range of component `n` is `[1, 9]`. fn create_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `246` + // Measured: `175` // Estimated: `3816` - // Minimum execution time: 21_968_000 picoseconds. - Weight::from_parts(23_594_232, 3816) - // Standard Error: 5_848 - .saturating_add(Weight::from_parts(24_843, 0).saturating_mul(n.into())) + // Minimum execution time: 26_472_000 picoseconds. + Weight::from_parts(27_917_651, 3816) + // Standard Error: 7_129 + .saturating_add(Weight::from_parts(59_239, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Recovery::Recoverable` (r:1 w:0) - /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) - /// Storage: `Recovery::ActiveRecoveries` (r:1 w:1) - /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) + /// Storage: Recovery Recoverable (r:1 w:0) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// Storage: Recovery ActiveRecoveries (r:1 w:1) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) fn initiate_recovery() -> Weight { // Proof Size summary in bytes: - // Measured: `343` + // Measured: `272` // Estimated: `3854` - // Minimum execution time: 25_494_000 picoseconds. - Weight::from_parts(26_290_000, 3854) + // Minimum execution time: 29_618_000 picoseconds. + Weight::from_parts(30_192_000, 3854) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Recovery::Recoverable` (r:1 w:0) - /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) - /// Storage: `Recovery::ActiveRecoveries` (r:1 w:1) - /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) + /// Storage: Recovery Recoverable (r:1 w:0) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// Storage: Recovery ActiveRecoveries (r:1 w:1) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) /// The range of component `n` is `[1, 9]`. fn vouch_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `431 + n * (64 ±0)` + // Measured: `360 + n * (64 ±0)` // Estimated: `3854` - // Minimum execution time: 17_044_000 picoseconds. - Weight::from_parts(18_299_617, 3854) - // Standard Error: 5_580 - .saturating_add(Weight::from_parts(187_568, 0).saturating_mul(n.into())) + // Minimum execution time: 19_464_000 picoseconds. + Weight::from_parts(20_642_522, 3854) + // Standard Error: 5_974 + .saturating_add(Weight::from_parts(142_308, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Recovery::Recoverable` (r:1 w:0) - /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) - /// Storage: `Recovery::ActiveRecoveries` (r:1 w:0) - /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) - /// Storage: `Recovery::Proxy` (r:1 w:1) - /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + /// Storage: Recovery Recoverable (r:1 w:0) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) + /// Storage: Recovery ActiveRecoveries (r:1 w:0) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + /// Storage: Recovery Proxy (r:1 w:1) + /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) /// The range of component `n` is `[1, 9]`. fn claim_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `463 + n * (64 ±0)` + // Measured: `392 + n * (64 ±0)` // Estimated: `3854` - // Minimum execution time: 22_186_000 picoseconds. - Weight::from_parts(23_476_807, 3854) - // Standard Error: 6_392 - .saturating_add(Weight::from_parts(89_770, 0).saturating_mul(n.into())) + // Minimum execution time: 23_656_000 picoseconds. + Weight::from_parts(24_903_269, 3854) + // Standard Error: 5_771 + .saturating_add(Weight::from_parts(117_343, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Recovery::ActiveRecoveries` (r:1 w:1) - /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Recovery ActiveRecoveries (r:1 w:1) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) /// The range of component `n` is `[1, 9]`. fn close_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `584 + n * (32 ±0)` + // Measured: `513 + n * (32 ±0)` // Estimated: `3854` - // Minimum execution time: 31_045_000 picoseconds. - Weight::from_parts(32_623_578, 3854) - // Standard Error: 7_203 - .saturating_add(Weight::from_parts(61_466, 0).saturating_mul(n.into())) + // Minimum execution time: 34_866_000 picoseconds. + Weight::from_parts(36_368_748, 3854) + // Standard Error: 6_600 + .saturating_add(Weight::from_parts(118_610, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Recovery::ActiveRecoveries` (r:1 w:0) - /// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`) - /// Storage: `Recovery::Recoverable` (r:1 w:1) - /// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`) + /// Storage: Recovery ActiveRecoveries (r:1 w:0) + /// Proof: Recovery ActiveRecoveries (max_values: None, max_size: Some(389), added: 2864, mode: MaxEncodedLen) + /// Storage: Recovery Recoverable (r:1 w:1) + /// Proof: Recovery Recoverable (max_values: None, max_size: Some(351), added: 2826, mode: MaxEncodedLen) /// The range of component `n` is `[1, 9]`. fn remove_recovery(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `341 + n * (32 ±0)` + // Measured: `270 + n * (32 ±0)` // Estimated: `3854` - // Minimum execution time: 27_925_000 picoseconds. - Weight::from_parts(29_258_264, 3854) - // Standard Error: 8_192 - .saturating_add(Weight::from_parts(128_124, 0).saturating_mul(n.into())) + // Minimum execution time: 31_405_000 picoseconds. + Weight::from_parts(32_552_838, 3854) + // Standard Error: 8_043 + .saturating_add(Weight::from_parts(171_605, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Recovery::Proxy` (r:1 w:1) - /// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`) + /// Storage: Recovery Proxy (r:1 w:1) + /// Proof: Recovery Proxy (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) fn cancel_recovered() -> Weight { // Proof Size summary in bytes: - // Measured: `352` + // Measured: `281` // Estimated: `3545` - // Minimum execution time: 11_623_000 picoseconds. - Weight::from_parts(12_043_000, 3545) + // Minimum execution time: 11_530_000 picoseconds. + Weight::from_parts(11_851_000, 3545) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/referenda/src/weights.rs b/substrate/frame/referenda/src/weights.rs index 1f1b69873eb..4b89379b311 100644 --- a/substrate/frame/referenda/src/weights.rs +++ b/substrate/frame/referenda/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_referenda` +//! Autogenerated weights for pallet_referenda //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/referenda/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/referenda/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_referenda`. +/// Weight functions needed for pallet_referenda. pub trait WeightInfo { fn submit() -> Weight; fn place_decision_deposit_preparing() -> Weight; @@ -83,874 +84,842 @@ pub trait WeightInfo { fn clear_metadata() -> Weight; } -/// Weights for `pallet_referenda` using the Substrate node and recommended hardware. +/// Weights for pallet_referenda using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Referenda::ReferendumCount` (r:1 w:1) - /// Proof: `Referenda::ReferendumCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Referenda::ReferendumInfoFor` (r:0 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumCount (r:1 w:1) + /// Proof: Referenda ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:0 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) fn submit() -> Weight { // Proof Size summary in bytes: - // Measured: `286` + // Measured: `220` // Estimated: `110487` - // Minimum execution time: 31_536_000 picoseconds. - Weight::from_parts(32_797_000, 110487) + // Minimum execution time: 40_175_000 picoseconds. + Weight::from_parts(41_107_000, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn place_decision_deposit_preparing() -> Weight { // Proof Size summary in bytes: - // Measured: `539` + // Measured: `473` // Estimated: `219984` - // Minimum execution time: 42_579_000 picoseconds. - Weight::from_parts(43_877_000, 219984) + // Minimum execution time: 50_922_000 picoseconds. + Weight::from_parts(52_179_000, 219984) .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::DecidingCount` (r:1 w:0) - /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Referenda::TrackQueue` (r:1 w:1) - /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:0) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn place_decision_deposit_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3326` + // Measured: `3260` // Estimated: `110487` - // Minimum execution time: 61_439_000 picoseconds. - Weight::from_parts(63_681_000, 110487) + // Minimum execution time: 69_559_000 picoseconds. + Weight::from_parts(72_143_000, 110487) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::DecidingCount` (r:1 w:0) - /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Referenda::TrackQueue` (r:1 w:1) - /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:0) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn place_decision_deposit_not_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3346` + // Measured: `3280` // Estimated: `110487` - // Minimum execution time: 60_136_000 picoseconds. - Weight::from_parts(61_841_000, 110487) + // Minimum execution time: 68_833_000 picoseconds. + Weight::from_parts(70_987_000, 110487) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::DecidingCount` (r:1 w:1) - /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn place_decision_deposit_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `539` + // Measured: `473` // Estimated: `219984` - // Minimum execution time: 49_865_000 picoseconds. - Weight::from_parts(51_347_000, 219984) + // Minimum execution time: 61_794_000 picoseconds. + Weight::from_parts(62_846_000, 219984) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(5_u64)) - } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::DecidingCount` (r:1 w:1) - /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + .saturating_add(T::DbWeight::get().writes(4_u64)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn place_decision_deposit_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `539` + // Measured: `473` // Estimated: `219984` - // Minimum execution time: 47_887_000 picoseconds. - Weight::from_parts(49_927_000, 219984) + // Minimum execution time: 58_664_000 picoseconds. + Weight::from_parts(60_195_000, 219984) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(5_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) fn refund_decision_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `417` + // Measured: `351` // Estimated: `3831` - // Minimum execution time: 25_721_000 picoseconds. - Weight::from_parts(26_922_000, 3831) + // Minimum execution time: 30_850_000 picoseconds. + Weight::from_parts(32_130_000, 3831) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) fn refund_submission_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `407` + // Measured: `341` // Estimated: `3831` - // Minimum execution time: 25_840_000 picoseconds. - Weight::from_parts(26_498_000, 3831) + // Minimum execution time: 30_747_000 picoseconds. + Weight::from_parts(32_196_000, 3831) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn cancel() -> Weight { // Proof Size summary in bytes: - // Measured: `447` + // Measured: `381` // Estimated: `219984` - // Minimum execution time: 30_530_000 picoseconds. - Weight::from_parts(31_547_000, 219984) + // Minimum execution time: 36_139_000 picoseconds. + Weight::from_parts(37_252_000, 219984) .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Referenda::MetadataOf` (r:1 w:0) - /// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: Referenda MetadataOf (r:1 w:0) + /// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) fn kill() -> Weight { // Proof Size summary in bytes: - // Measured: `688` + // Measured: `622` // Estimated: `219984` - // Minimum execution time: 64_011_000 picoseconds. - Weight::from_parts(65_240_000, 219984) + // Minimum execution time: 80_862_000 picoseconds. + Weight::from_parts(83_045_000, 219984) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::TrackQueue` (r:1 w:0) - /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) - /// Storage: `Referenda::DecidingCount` (r:1 w:1) - /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: Referenda TrackQueue (r:1 w:0) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) fn one_fewer_deciding_queue_empty() -> Weight { // Proof Size summary in bytes: - // Measured: `240` + // Measured: `174` // Estimated: `5477` - // Minimum execution time: 9_568_000 picoseconds. - Weight::from_parts(10_004_000, 5477) + // Minimum execution time: 10_136_000 picoseconds. + Weight::from_parts(10_638_000, 5477) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Referenda::TrackQueue` (r:1 w:1) - /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn one_fewer_deciding_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `3216` + // Measured: `3150` // Estimated: `110487` - // Minimum execution time: 43_325_000 picoseconds. - Weight::from_parts(45_335_000, 110487) + // Minimum execution time: 52_022_000 picoseconds. + Weight::from_parts(53_910_000, 110487) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::TrackQueue` (r:1 w:1) - /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn one_fewer_deciding_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `3216` + // Measured: `3150` // Estimated: `110487` - // Minimum execution time: 44_287_000 picoseconds. - Weight::from_parts(45_164_000, 110487) + // Minimum execution time: 53_683_000 picoseconds. + Weight::from_parts(55_707_000, 110487) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::TrackQueue` (r:1 w:1) - /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) fn nudge_referendum_requeued_insertion() -> Weight { // Proof Size summary in bytes: - // Measured: `3077` + // Measured: `3011` // Estimated: `5477` - // Minimum execution time: 21_909_000 picoseconds. - Weight::from_parts(22_641_000, 5477) + // Minimum execution time: 24_043_000 picoseconds. + Weight::from_parts(24_512_000, 5477) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::TrackQueue` (r:1 w:1) - /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) fn nudge_referendum_requeued_slide() -> Weight { // Proof Size summary in bytes: - // Measured: `3077` + // Measured: `3011` // Estimated: `5477` - // Minimum execution time: 21_626_000 picoseconds. - Weight::from_parts(22_338_000, 5477) + // Minimum execution time: 23_588_000 picoseconds. + Weight::from_parts(24_422_000, 5477) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::DecidingCount` (r:1 w:0) - /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Referenda::TrackQueue` (r:1 w:1) - /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:0) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) fn nudge_referendum_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3081` + // Measured: `3015` // Estimated: `5477` - // Minimum execution time: 29_245_000 picoseconds. - Weight::from_parts(30_147_000, 5477) + // Minimum execution time: 31_443_000 picoseconds. + Weight::from_parts(32_725_000, 5477) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::DecidingCount` (r:1 w:0) - /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Referenda::TrackQueue` (r:1 w:1) - /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:0) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) fn nudge_referendum_not_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3101` + // Measured: `3035` // Estimated: `5477` - // Minimum execution time: 28_512_000 picoseconds. - Weight::from_parts(29_781_000, 5477) + // Minimum execution time: 30_319_000 picoseconds. + Weight::from_parts(31_652_000, 5477) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn nudge_referendum_no_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `399` + // Measured: `333` // Estimated: `110487` - // Minimum execution time: 19_208_000 picoseconds. - Weight::from_parts(19_947_000, 110487) + // Minimum execution time: 23_062_000 picoseconds. + Weight::from_parts(23_614_000, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn nudge_referendum_preparing() -> Weight { // Proof Size summary in bytes: - // Measured: `447` + // Measured: `381` // Estimated: `110487` - // Minimum execution time: 19_708_000 picoseconds. - Weight::from_parts(20_783_000, 110487) + // Minimum execution time: 23_537_000 picoseconds. + Weight::from_parts(24_267_000, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) fn nudge_referendum_timed_out() -> Weight { // Proof Size summary in bytes: - // Measured: `344` + // Measured: `278` // Estimated: `3831` - // Minimum execution time: 12_947_000 picoseconds. - Weight::from_parts(13_582_000, 3831) + // Minimum execution time: 16_388_000 picoseconds. + Weight::from_parts(16_676_000, 3831) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::DecidingCount` (r:1 w:1) - /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn nudge_referendum_begin_deciding_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `447` + // Measured: `381` // Estimated: `110487` - // Minimum execution time: 26_699_000 picoseconds. - Weight::from_parts(28_048_000, 110487) + // Minimum execution time: 32_801_000 picoseconds. + Weight::from_parts(34_053_000, 110487) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::DecidingCount` (r:1 w:1) - /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn nudge_referendum_begin_deciding_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `447` + // Measured: `381` // Estimated: `110487` - // Minimum execution time: 28_132_000 picoseconds. - Weight::from_parts(29_520_000, 110487) + // Minimum execution time: 35_704_000 picoseconds. + Weight::from_parts(36_451_000, 110487) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn nudge_referendum_begin_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `500` + // Measured: `434` // Estimated: `110487` - // Minimum execution time: 23_212_000 picoseconds. - Weight::from_parts(24_200_000, 110487) + // Minimum execution time: 29_151_000 picoseconds. + Weight::from_parts(30_055_000, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn nudge_referendum_end_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `483` + // Measured: `417` // Estimated: `110487` - // Minimum execution time: 22_807_000 picoseconds. - Weight::from_parts(23_858_000, 110487) + // Minimum execution time: 29_265_000 picoseconds. + Weight::from_parts(30_213_000, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn nudge_referendum_continue_not_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `500` + // Measured: `434` // Estimated: `110487` - // Minimum execution time: 22_862_000 picoseconds. - Weight::from_parts(23_627_000, 110487) + // Minimum execution time: 27_760_000 picoseconds. + Weight::from_parts(28_381_000, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn nudge_referendum_continue_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `504` + // Measured: `438` // Estimated: `110487` - // Minimum execution time: 21_030_000 picoseconds. - Weight::from_parts(21_710_000, 110487) + // Minimum execution time: 25_464_000 picoseconds. + Weight::from_parts(26_348_000, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Lookup` (r:1 w:1) - /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: Scheduler Lookup (r:1 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) fn nudge_referendum_approved() -> Weight { // Proof Size summary in bytes: - // Measured: `504` + // Measured: `438` // Estimated: `219984` - // Minimum execution time: 33_031_000 picoseconds. - Weight::from_parts(34_518_000, 219984) + // Minimum execution time: 42_629_000 picoseconds. + Weight::from_parts(43_732_000, 219984) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn nudge_referendum_rejected() -> Weight { // Proof Size summary in bytes: - // Measured: `500` + // Measured: `434` // Estimated: `110487` - // Minimum execution time: 23_198_000 picoseconds. - Weight::from_parts(24_238_000, 110487) + // Minimum execution time: 30_015_000 picoseconds. + Weight::from_parts(30_827_000, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Referenda::MetadataOf` (r:0 w:1) - /// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Referenda MetadataOf (r:0 w:1) + /// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) fn set_some_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `555` + // Measured: `422` // Estimated: `3831` - // Minimum execution time: 19_502_000 picoseconds. - Weight::from_parts(20_105_000, 3831) - .saturating_add(T::DbWeight::get().reads(3_u64)) + // Minimum execution time: 19_901_000 picoseconds. + Weight::from_parts(20_681_000, 3831) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::MetadataOf` (r:1 w:1) - /// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda MetadataOf (r:1 w:1) + /// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) fn clear_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `421` + // Measured: `355` // Estimated: `3831` - // Minimum execution time: 15_417_000 picoseconds. - Weight::from_parts(15_916_000, 3831) + // Minimum execution time: 17_323_000 picoseconds. + Weight::from_parts(18_227_000, 3831) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Referenda::ReferendumCount` (r:1 w:1) - /// Proof: `Referenda::ReferendumCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Referenda::ReferendumInfoFor` (r:0 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumCount (r:1 w:1) + /// Proof: Referenda ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:0 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) fn submit() -> Weight { // Proof Size summary in bytes: - // Measured: `286` + // Measured: `220` // Estimated: `110487` - // Minimum execution time: 31_536_000 picoseconds. - Weight::from_parts(32_797_000, 110487) + // Minimum execution time: 40_175_000 picoseconds. + Weight::from_parts(41_107_000, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn place_decision_deposit_preparing() -> Weight { // Proof Size summary in bytes: - // Measured: `539` + // Measured: `473` // Estimated: `219984` - // Minimum execution time: 42_579_000 picoseconds. - Weight::from_parts(43_877_000, 219984) + // Minimum execution time: 50_922_000 picoseconds. + Weight::from_parts(52_179_000, 219984) .saturating_add(RocksDbWeight::get().reads(3_u64)) - .saturating_add(RocksDbWeight::get().writes(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::DecidingCount` (r:1 w:0) - /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Referenda::TrackQueue` (r:1 w:1) - /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:0) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn place_decision_deposit_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3326` + // Measured: `3260` // Estimated: `110487` - // Minimum execution time: 61_439_000 picoseconds. - Weight::from_parts(63_681_000, 110487) + // Minimum execution time: 69_559_000 picoseconds. + Weight::from_parts(72_143_000, 110487) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::DecidingCount` (r:1 w:0) - /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Referenda::TrackQueue` (r:1 w:1) - /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:0) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn place_decision_deposit_not_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3346` + // Measured: `3280` // Estimated: `110487` - // Minimum execution time: 60_136_000 picoseconds. - Weight::from_parts(61_841_000, 110487) + // Minimum execution time: 68_833_000 picoseconds. + Weight::from_parts(70_987_000, 110487) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::DecidingCount` (r:1 w:1) - /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn place_decision_deposit_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `539` + // Measured: `473` // Estimated: `219984` - // Minimum execution time: 49_865_000 picoseconds. - Weight::from_parts(51_347_000, 219984) + // Minimum execution time: 61_794_000 picoseconds. + Weight::from_parts(62_846_000, 219984) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(5_u64)) - } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::DecidingCount` (r:1 w:1) - /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + .saturating_add(RocksDbWeight::get().writes(4_u64)) + } + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn place_decision_deposit_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `539` + // Measured: `473` // Estimated: `219984` - // Minimum execution time: 47_887_000 picoseconds. - Weight::from_parts(49_927_000, 219984) + // Minimum execution time: 58_664_000 picoseconds. + Weight::from_parts(60_195_000, 219984) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(5_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) fn refund_decision_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `417` + // Measured: `351` // Estimated: `3831` - // Minimum execution time: 25_721_000 picoseconds. - Weight::from_parts(26_922_000, 3831) + // Minimum execution time: 30_850_000 picoseconds. + Weight::from_parts(32_130_000, 3831) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) fn refund_submission_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `407` + // Measured: `341` // Estimated: `3831` - // Minimum execution time: 25_840_000 picoseconds. - Weight::from_parts(26_498_000, 3831) + // Minimum execution time: 30_747_000 picoseconds. + Weight::from_parts(32_196_000, 3831) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn cancel() -> Weight { // Proof Size summary in bytes: - // Measured: `447` + // Measured: `381` // Estimated: `219984` - // Minimum execution time: 30_530_000 picoseconds. - Weight::from_parts(31_547_000, 219984) + // Minimum execution time: 36_139_000 picoseconds. + Weight::from_parts(37_252_000, 219984) .saturating_add(RocksDbWeight::get().reads(3_u64)) - .saturating_add(RocksDbWeight::get().writes(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Referenda::MetadataOf` (r:1 w:0) - /// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: Referenda MetadataOf (r:1 w:0) + /// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) fn kill() -> Weight { // Proof Size summary in bytes: - // Measured: `688` + // Measured: `622` // Estimated: `219984` - // Minimum execution time: 64_011_000 picoseconds. - Weight::from_parts(65_240_000, 219984) + // Minimum execution time: 80_862_000 picoseconds. + Weight::from_parts(83_045_000, 219984) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(4_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::TrackQueue` (r:1 w:0) - /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) - /// Storage: `Referenda::DecidingCount` (r:1 w:1) - /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) + /// Storage: Referenda TrackQueue (r:1 w:0) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) fn one_fewer_deciding_queue_empty() -> Weight { // Proof Size summary in bytes: - // Measured: `240` + // Measured: `174` // Estimated: `5477` - // Minimum execution time: 9_568_000 picoseconds. - Weight::from_parts(10_004_000, 5477) + // Minimum execution time: 10_136_000 picoseconds. + Weight::from_parts(10_638_000, 5477) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Referenda::TrackQueue` (r:1 w:1) - /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn one_fewer_deciding_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `3216` + // Measured: `3150` // Estimated: `110487` - // Minimum execution time: 43_325_000 picoseconds. - Weight::from_parts(45_335_000, 110487) + // Minimum execution time: 52_022_000 picoseconds. + Weight::from_parts(53_910_000, 110487) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::TrackQueue` (r:1 w:1) - /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn one_fewer_deciding_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `3216` + // Measured: `3150` // Estimated: `110487` - // Minimum execution time: 44_287_000 picoseconds. - Weight::from_parts(45_164_000, 110487) + // Minimum execution time: 53_683_000 picoseconds. + Weight::from_parts(55_707_000, 110487) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::TrackQueue` (r:1 w:1) - /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) fn nudge_referendum_requeued_insertion() -> Weight { // Proof Size summary in bytes: - // Measured: `3077` + // Measured: `3011` // Estimated: `5477` - // Minimum execution time: 21_909_000 picoseconds. - Weight::from_parts(22_641_000, 5477) + // Minimum execution time: 24_043_000 picoseconds. + Weight::from_parts(24_512_000, 5477) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::TrackQueue` (r:1 w:1) - /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) fn nudge_referendum_requeued_slide() -> Weight { // Proof Size summary in bytes: - // Measured: `3077` + // Measured: `3011` // Estimated: `5477` - // Minimum execution time: 21_626_000 picoseconds. - Weight::from_parts(22_338_000, 5477) + // Minimum execution time: 23_588_000 picoseconds. + Weight::from_parts(24_422_000, 5477) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::DecidingCount` (r:1 w:0) - /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Referenda::TrackQueue` (r:1 w:1) - /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:0) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) fn nudge_referendum_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3081` + // Measured: `3015` // Estimated: `5477` - // Minimum execution time: 29_245_000 picoseconds. - Weight::from_parts(30_147_000, 5477) + // Minimum execution time: 31_443_000 picoseconds. + Weight::from_parts(32_725_000, 5477) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::DecidingCount` (r:1 w:0) - /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Referenda::TrackQueue` (r:1 w:1) - /// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:0) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Referenda TrackQueue (r:1 w:1) + /// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen) fn nudge_referendum_not_queued() -> Weight { // Proof Size summary in bytes: - // Measured: `3101` + // Measured: `3035` // Estimated: `5477` - // Minimum execution time: 28_512_000 picoseconds. - Weight::from_parts(29_781_000, 5477) + // Minimum execution time: 30_319_000 picoseconds. + Weight::from_parts(31_652_000, 5477) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn nudge_referendum_no_deposit() -> Weight { // Proof Size summary in bytes: - // Measured: `399` + // Measured: `333` // Estimated: `110487` - // Minimum execution time: 19_208_000 picoseconds. - Weight::from_parts(19_947_000, 110487) + // Minimum execution time: 23_062_000 picoseconds. + Weight::from_parts(23_614_000, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn nudge_referendum_preparing() -> Weight { // Proof Size summary in bytes: - // Measured: `447` + // Measured: `381` // Estimated: `110487` - // Minimum execution time: 19_708_000 picoseconds. - Weight::from_parts(20_783_000, 110487) + // Minimum execution time: 23_537_000 picoseconds. + Weight::from_parts(24_267_000, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) fn nudge_referendum_timed_out() -> Weight { // Proof Size summary in bytes: - // Measured: `344` + // Measured: `278` // Estimated: `3831` - // Minimum execution time: 12_947_000 picoseconds. - Weight::from_parts(13_582_000, 3831) + // Minimum execution time: 16_388_000 picoseconds. + Weight::from_parts(16_676_000, 3831) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::DecidingCount` (r:1 w:1) - /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn nudge_referendum_begin_deciding_failing() -> Weight { // Proof Size summary in bytes: - // Measured: `447` + // Measured: `381` // Estimated: `110487` - // Minimum execution time: 26_699_000 picoseconds. - Weight::from_parts(28_048_000, 110487) + // Minimum execution time: 32_801_000 picoseconds. + Weight::from_parts(34_053_000, 110487) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::DecidingCount` (r:1 w:1) - /// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda DecidingCount (r:1 w:1) + /// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn nudge_referendum_begin_deciding_passing() -> Weight { // Proof Size summary in bytes: - // Measured: `447` + // Measured: `381` // Estimated: `110487` - // Minimum execution time: 28_132_000 picoseconds. - Weight::from_parts(29_520_000, 110487) + // Minimum execution time: 35_704_000 picoseconds. + Weight::from_parts(36_451_000, 110487) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn nudge_referendum_begin_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `500` + // Measured: `434` // Estimated: `110487` - // Minimum execution time: 23_212_000 picoseconds. - Weight::from_parts(24_200_000, 110487) + // Minimum execution time: 29_151_000 picoseconds. + Weight::from_parts(30_055_000, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn nudge_referendum_end_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `483` + // Measured: `417` // Estimated: `110487` - // Minimum execution time: 22_807_000 picoseconds. - Weight::from_parts(23_858_000, 110487) + // Minimum execution time: 29_265_000 picoseconds. + Weight::from_parts(30_213_000, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn nudge_referendum_continue_not_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `500` + // Measured: `434` // Estimated: `110487` - // Minimum execution time: 22_862_000 picoseconds. - Weight::from_parts(23_627_000, 110487) + // Minimum execution time: 27_760_000 picoseconds. + Weight::from_parts(28_381_000, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn nudge_referendum_continue_confirming() -> Weight { // Proof Size summary in bytes: - // Measured: `504` + // Measured: `438` // Estimated: `110487` - // Minimum execution time: 21_030_000 picoseconds. - Weight::from_parts(21_710_000, 110487) + // Minimum execution time: 25_464_000 picoseconds. + Weight::from_parts(26_348_000, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:2 w:2) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Lookup` (r:1 w:1) - /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:2 w:2) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) + /// Storage: Scheduler Lookup (r:1 w:1) + /// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) fn nudge_referendum_approved() -> Weight { // Proof Size summary in bytes: - // Measured: `504` + // Measured: `438` // Estimated: `219984` - // Minimum execution time: 33_031_000 picoseconds. - Weight::from_parts(34_518_000, 219984) + // Minimum execution time: 42_629_000 picoseconds. + Weight::from_parts(43_732_000, 219984) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Agenda` (r:1 w:1) - /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:1) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Scheduler Agenda (r:1 w:1) + /// Proof: Scheduler Agenda (max_values: None, max_size: Some(107022), added: 109497, mode: MaxEncodedLen) fn nudge_referendum_rejected() -> Weight { // Proof Size summary in bytes: - // Measured: `500` + // Measured: `434` // Estimated: `110487` - // Minimum execution time: 23_198_000 picoseconds. - Weight::from_parts(24_238_000, 110487) + // Minimum execution time: 30_015_000 picoseconds. + Weight::from_parts(30_827_000, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:0) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Referenda::MetadataOf` (r:0 w:1) - /// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:0) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) + /// Storage: Referenda MetadataOf (r:0 w:1) + /// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) fn set_some_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `555` + // Measured: `422` // Estimated: `3831` - // Minimum execution time: 19_502_000 picoseconds. - Weight::from_parts(20_105_000, 3831) - .saturating_add(RocksDbWeight::get().reads(3_u64)) + // Minimum execution time: 19_901_000 picoseconds. + Weight::from_parts(20_681_000, 3831) + .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0) - /// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(366), added: 2841, mode: `MaxEncodedLen`) - /// Storage: `Referenda::MetadataOf` (r:1 w:1) - /// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: Referenda ReferendumInfoFor (r:1 w:0) + /// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(366), added: 2841, mode: MaxEncodedLen) + /// Storage: Referenda MetadataOf (r:1 w:1) + /// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen) fn clear_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `421` + // Measured: `355` // Estimated: `3831` - // Minimum execution time: 15_417_000 picoseconds. - Weight::from_parts(15_916_000, 3831) + // Minimum execution time: 17_323_000 picoseconds. + Weight::from_parts(18_227_000, 3831) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/remark/src/weights.rs b/substrate/frame/remark/src/weights.rs index 61cca5b7d05..46475db163f 100644 --- a/substrate/frame/remark/src/weights.rs +++ b/substrate/frame/remark/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_remark` +//! Autogenerated weights for pallet_remark //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/remark/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/remark/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,12 +50,12 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_remark`. +/// Weight functions needed for pallet_remark. pub trait WeightInfo { fn store(l: u32, ) -> Weight; } -/// Weights for `pallet_remark` using the Substrate node and recommended hardware. +/// Weights for pallet_remark using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { /// The range of component `l` is `[1, 1048576]`. @@ -62,23 +63,23 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_623_000 picoseconds. - Weight::from_parts(6_757_000, 0) + // Minimum execution time: 8_471_000 picoseconds. + Weight::from_parts(8_586_000, 0) // Standard Error: 0 - .saturating_add(Weight::from_parts(1_368, 0).saturating_mul(l.into())) + .saturating_add(Weight::from_parts(1_359, 0).saturating_mul(l.into())) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { /// The range of component `l` is `[1, 1048576]`. fn store(l: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_623_000 picoseconds. - Weight::from_parts(6_757_000, 0) + // Minimum execution time: 8_471_000 picoseconds. + Weight::from_parts(8_586_000, 0) // Standard Error: 0 - .saturating_add(Weight::from_parts(1_368, 0).saturating_mul(l.into())) + .saturating_add(Weight::from_parts(1_359, 0).saturating_mul(l.into())) } } diff --git a/substrate/frame/safe-mode/src/weights.rs b/substrate/frame/safe-mode/src/weights.rs index d326fab0f0f..f72bebcab9a 100644 --- a/substrate/frame/safe-mode/src/weights.rs +++ b/substrate/frame/safe-mode/src/weights.rs @@ -17,29 +17,27 @@ //! Autogenerated weights for `pallet_safe_mode` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-08-24, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-aahe6cbd-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate-node +// target/production/substrate-node // benchmark // pallet -// --chain=dev // --steps=50 // --repeat=20 -// --pallet=pallet_safe_mode -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/safe-mode/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --json-file=/builds/parity/mirrors/substrate/.git/.artifacts/bench.json +// --pallet=pallet_safe_mode +// --chain=dev +// --header=./HEADER-APACHE2 +// --output=./frame/safe-mode/src/weights.rs +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -72,8 +70,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1489` - // Minimum execution time: 2_216_000 picoseconds. - Weight::from_parts(2_309_000, 1489) + // Minimum execution time: 2_500_000 picoseconds. + Weight::from_parts(2_594_000, 1489) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `SafeMode::EnteredUntil` (r:1 w:1) @@ -82,23 +80,23 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `169` // Estimated: `1489` - // Minimum execution time: 6_124_000 picoseconds. - Weight::from_parts(6_601_000, 1489) + // Minimum execution time: 8_868_000 picoseconds. + Weight::from_parts(9_415_000, 1489) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `SafeMode::EnteredUntil` (r:1 w:1) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) /// Storage: `SafeMode::Deposits` (r:0 w:1) /// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn enter() -> Weight { // Proof Size summary in bytes: // Measured: `142` - // Estimated: `3658` - // Minimum execution time: 44_825_000 picoseconds. - Weight::from_parts(45_845_000, 3658) + // Estimated: `3550` + // Minimum execution time: 50_541_000 picoseconds. + Weight::from_parts(51_558_000, 3550) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -108,23 +106,23 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1489` - // Minimum execution time: 7_603_000 picoseconds. - Weight::from_parts(7_954_000, 1489) + // Minimum execution time: 10_489_000 picoseconds. + Weight::from_parts(10_833_000, 1489) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `SafeMode::EnteredUntil` (r:1 w:1) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) /// Storage: `SafeMode::Deposits` (r:0 w:1) /// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn extend() -> Weight { // Proof Size summary in bytes: // Measured: `169` - // Estimated: `3658` - // Minimum execution time: 44_716_000 picoseconds. - Weight::from_parts(46_039_000, 3658) + // Estimated: `3550` + // Minimum execution time: 50_818_000 picoseconds. + Weight::from_parts(51_873_000, 3550) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -134,8 +132,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `169` // Estimated: `1489` - // Minimum execution time: 8_231_000 picoseconds. - Weight::from_parts(8_731_000, 1489) + // Minimum execution time: 10_843_000 picoseconds. + Weight::from_parts(11_314_000, 1489) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -145,8 +143,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `169` // Estimated: `1489` - // Minimum execution time: 8_015_000 picoseconds. - Weight::from_parts(8_247_000, 1489) + // Minimum execution time: 10_382_000 picoseconds. + Weight::from_parts(10_814_000, 1489) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -155,39 +153,39 @@ impl WeightInfo for SubstrateWeight { /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) fn release_deposit() -> Weight { // Proof Size summary in bytes: // Measured: `292` - // Estimated: `3658` - // Minimum execution time: 39_149_000 picoseconds. - Weight::from_parts(40_005_000, 3658) + // Estimated: `3550` + // Minimum execution time: 42_828_000 picoseconds. + Weight::from_parts(43_752_000, 3550) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `SafeMode::Deposits` (r:1 w:1) /// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) fn force_release_deposit() -> Weight { // Proof Size summary in bytes: // Measured: `292` - // Estimated: `3658` - // Minimum execution time: 37_528_000 picoseconds. - Weight::from_parts(38_473_000, 3658) + // Estimated: `3550` + // Minimum execution time: 40_196_000 picoseconds. + Weight::from_parts(41_298_000, 3550) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `SafeMode::Deposits` (r:1 w:1) /// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) fn force_slash_deposit() -> Weight { // Proof Size summary in bytes: // Measured: `292` - // Estimated: `3658` - // Minimum execution time: 29_417_000 picoseconds. - Weight::from_parts(30_195_000, 3658) + // Estimated: `3550` + // Minimum execution time: 33_660_000 picoseconds. + Weight::from_parts(34_426_000, 3550) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -201,8 +199,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1489` - // Minimum execution time: 2_216_000 picoseconds. - Weight::from_parts(2_309_000, 1489) + // Minimum execution time: 2_500_000 picoseconds. + Weight::from_parts(2_594_000, 1489) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `SafeMode::EnteredUntil` (r:1 w:1) @@ -211,23 +209,23 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `169` // Estimated: `1489` - // Minimum execution time: 6_124_000 picoseconds. - Weight::from_parts(6_601_000, 1489) + // Minimum execution time: 8_868_000 picoseconds. + Weight::from_parts(9_415_000, 1489) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `SafeMode::EnteredUntil` (r:1 w:1) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) /// Storage: `SafeMode::Deposits` (r:0 w:1) /// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn enter() -> Weight { // Proof Size summary in bytes: // Measured: `142` - // Estimated: `3658` - // Minimum execution time: 44_825_000 picoseconds. - Weight::from_parts(45_845_000, 3658) + // Estimated: `3550` + // Minimum execution time: 50_541_000 picoseconds. + Weight::from_parts(51_558_000, 3550) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -237,23 +235,23 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1489` - // Minimum execution time: 7_603_000 picoseconds. - Weight::from_parts(7_954_000, 1489) + // Minimum execution time: 10_489_000 picoseconds. + Weight::from_parts(10_833_000, 1489) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `SafeMode::EnteredUntil` (r:1 w:1) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) /// Storage: `SafeMode::Deposits` (r:0 w:1) /// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn extend() -> Weight { // Proof Size summary in bytes: // Measured: `169` - // Estimated: `3658` - // Minimum execution time: 44_716_000 picoseconds. - Weight::from_parts(46_039_000, 3658) + // Estimated: `3550` + // Minimum execution time: 50_818_000 picoseconds. + Weight::from_parts(51_873_000, 3550) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -263,8 +261,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `169` // Estimated: `1489` - // Minimum execution time: 8_231_000 picoseconds. - Weight::from_parts(8_731_000, 1489) + // Minimum execution time: 10_843_000 picoseconds. + Weight::from_parts(11_314_000, 1489) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -274,8 +272,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `169` // Estimated: `1489` - // Minimum execution time: 8_015_000 picoseconds. - Weight::from_parts(8_247_000, 1489) + // Minimum execution time: 10_382_000 picoseconds. + Weight::from_parts(10_814_000, 1489) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -284,39 +282,39 @@ impl WeightInfo for () { /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) fn release_deposit() -> Weight { // Proof Size summary in bytes: // Measured: `292` - // Estimated: `3658` - // Minimum execution time: 39_149_000 picoseconds. - Weight::from_parts(40_005_000, 3658) + // Estimated: `3550` + // Minimum execution time: 42_828_000 picoseconds. + Weight::from_parts(43_752_000, 3550) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `SafeMode::Deposits` (r:1 w:1) /// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) fn force_release_deposit() -> Weight { // Proof Size summary in bytes: // Measured: `292` - // Estimated: `3658` - // Minimum execution time: 37_528_000 picoseconds. - Weight::from_parts(38_473_000, 3658) + // Estimated: `3550` + // Minimum execution time: 40_196_000 picoseconds. + Weight::from_parts(41_298_000, 3550) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `SafeMode::Deposits` (r:1 w:1) /// Proof: `SafeMode::Deposits` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) fn force_slash_deposit() -> Weight { // Proof Size summary in bytes: // Measured: `292` - // Estimated: `3658` - // Minimum execution time: 29_417_000 picoseconds. - Weight::from_parts(30_195_000, 3658) + // Estimated: `3550` + // Minimum execution time: 33_660_000 picoseconds. + Weight::from_parts(34_426_000, 3550) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } diff --git a/substrate/frame/salary/src/weights.rs b/substrate/frame/salary/src/weights.rs index c4f22a027eb..3d3b9e31595 100644 --- a/substrate/frame/salary/src/weights.rs +++ b/substrate/frame/salary/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_salary` +//! Autogenerated weights for pallet_salary //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/salary/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/salary/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_salary`. +/// Weight functions needed for pallet_salary. pub trait WeightInfo { fn init() -> Weight; fn bump() -> Weight; @@ -60,204 +61,204 @@ pub trait WeightInfo { fn check_payment() -> Weight; } -/// Weights for `pallet_salary` using the Substrate node and recommended hardware. +/// Weights for pallet_salary using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Salary::Status` (r:1 w:1) - /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) + /// Storage: Salary Status (r:1 w:1) + /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) fn init() -> Weight { // Proof Size summary in bytes: // Measured: `4` // Estimated: `1541` - // Minimum execution time: 7_421_000 picoseconds. - Weight::from_parts(7_819_000, 1541) + // Minimum execution time: 10_778_000 picoseconds. + Weight::from_parts(11_084_000, 1541) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Salary::Status` (r:1 w:1) - /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) + /// Storage: Salary Status (r:1 w:1) + /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) fn bump() -> Weight { // Proof Size summary in bytes: // Measured: `86` // Estimated: `1541` - // Minimum execution time: 8_651_000 picoseconds. - Weight::from_parts(9_056_000, 1541) + // Minimum execution time: 12_042_000 picoseconds. + Weight::from_parts(12_645_000, 1541) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Salary::Status` (r:1 w:0) - /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::Members` (r:1 w:0) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `Salary::Claimant` (r:1 w:1) - /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) + /// Storage: Salary Status (r:1 w:0) + /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) + /// Storage: RankedCollective Members (r:1 w:0) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: Salary Claimant (r:1 w:1) + /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) fn induct() -> Weight { // Proof Size summary in bytes: // Measured: `395` // Estimated: `3543` - // Minimum execution time: 16_513_000 picoseconds. - Weight::from_parts(17_305_000, 3543) + // Minimum execution time: 18_374_000 picoseconds. + Weight::from_parts(19_200_000, 3543) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `RankedCollective::Members` (r:1 w:0) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `Salary::Status` (r:1 w:1) - /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) - /// Storage: `Salary::Claimant` (r:1 w:1) - /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:0) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: Salary Status (r:1 w:1) + /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) + /// Storage: Salary Claimant (r:1 w:1) + /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) fn register() -> Weight { // Proof Size summary in bytes: // Measured: `462` // Estimated: `3543` - // Minimum execution time: 18_913_000 picoseconds. - Weight::from_parts(19_867_000, 3543) + // Minimum execution time: 22_696_000 picoseconds. + Weight::from_parts(23_275_000, 3543) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Salary::Status` (r:1 w:1) - /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) - /// Storage: `Salary::Claimant` (r:1 w:1) - /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::Members` (r:1 w:0) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: Salary Status (r:1 w:1) + /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) + /// Storage: Salary Claimant (r:1 w:1) + /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) + /// Storage: RankedCollective Members (r:1 w:0) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) fn payout() -> Weight { // Proof Size summary in bytes: // Measured: `462` // Estimated: `3543` - // Minimum execution time: 53_297_000 picoseconds. - Weight::from_parts(55_144_000, 3543) + // Minimum execution time: 63_660_000 picoseconds. + Weight::from_parts(65_006_000, 3543) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Salary::Status` (r:1 w:1) - /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) - /// Storage: `Salary::Claimant` (r:1 w:1) - /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::Members` (r:1 w:0) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Salary Status (r:1 w:1) + /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) + /// Storage: Salary Claimant (r:1 w:1) + /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) + /// Storage: RankedCollective Members (r:1 w:0) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn payout_other() -> Weight { // Proof Size summary in bytes: // Measured: `462` // Estimated: `3593` - // Minimum execution time: 53_638_000 picoseconds. - Weight::from_parts(55_328_000, 3593) + // Minimum execution time: 64_706_000 picoseconds. + Weight::from_parts(65_763_000, 3593) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Salary::Status` (r:1 w:1) - /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) - /// Storage: `Salary::Claimant` (r:1 w:1) - /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) + /// Storage: Salary Status (r:1 w:1) + /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) + /// Storage: Salary Claimant (r:1 w:1) + /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) fn check_payment() -> Weight { // Proof Size summary in bytes: // Measured: `170` // Estimated: `3543` - // Minimum execution time: 10_557_000 picoseconds. - Weight::from_parts(11_145_000, 3543) + // Minimum execution time: 11_838_000 picoseconds. + Weight::from_parts(12_323_000, 3543) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Salary::Status` (r:1 w:1) - /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) + /// Storage: Salary Status (r:1 w:1) + /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) fn init() -> Weight { // Proof Size summary in bytes: // Measured: `4` // Estimated: `1541` - // Minimum execution time: 7_421_000 picoseconds. - Weight::from_parts(7_819_000, 1541) + // Minimum execution time: 10_778_000 picoseconds. + Weight::from_parts(11_084_000, 1541) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Salary::Status` (r:1 w:1) - /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) + /// Storage: Salary Status (r:1 w:1) + /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) fn bump() -> Weight { // Proof Size summary in bytes: // Measured: `86` // Estimated: `1541` - // Minimum execution time: 8_651_000 picoseconds. - Weight::from_parts(9_056_000, 1541) + // Minimum execution time: 12_042_000 picoseconds. + Weight::from_parts(12_645_000, 1541) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Salary::Status` (r:1 w:0) - /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::Members` (r:1 w:0) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `Salary::Claimant` (r:1 w:1) - /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) + /// Storage: Salary Status (r:1 w:0) + /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) + /// Storage: RankedCollective Members (r:1 w:0) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: Salary Claimant (r:1 w:1) + /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) fn induct() -> Weight { // Proof Size summary in bytes: // Measured: `395` // Estimated: `3543` - // Minimum execution time: 16_513_000 picoseconds. - Weight::from_parts(17_305_000, 3543) + // Minimum execution time: 18_374_000 picoseconds. + Weight::from_parts(19_200_000, 3543) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `RankedCollective::Members` (r:1 w:0) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `Salary::Status` (r:1 w:1) - /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) - /// Storage: `Salary::Claimant` (r:1 w:1) - /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) + /// Storage: RankedCollective Members (r:1 w:0) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: Salary Status (r:1 w:1) + /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) + /// Storage: Salary Claimant (r:1 w:1) + /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) fn register() -> Weight { // Proof Size summary in bytes: // Measured: `462` // Estimated: `3543` - // Minimum execution time: 18_913_000 picoseconds. - Weight::from_parts(19_867_000, 3543) + // Minimum execution time: 22_696_000 picoseconds. + Weight::from_parts(23_275_000, 3543) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Salary::Status` (r:1 w:1) - /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) - /// Storage: `Salary::Claimant` (r:1 w:1) - /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::Members` (r:1 w:0) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) + /// Storage: Salary Status (r:1 w:1) + /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) + /// Storage: Salary Claimant (r:1 w:1) + /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) + /// Storage: RankedCollective Members (r:1 w:0) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) fn payout() -> Weight { // Proof Size summary in bytes: // Measured: `462` // Estimated: `3543` - // Minimum execution time: 53_297_000 picoseconds. - Weight::from_parts(55_144_000, 3543) + // Minimum execution time: 63_660_000 picoseconds. + Weight::from_parts(65_006_000, 3543) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Salary::Status` (r:1 w:1) - /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) - /// Storage: `Salary::Claimant` (r:1 w:1) - /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) - /// Storage: `RankedCollective::Members` (r:1 w:0) - /// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Salary Status (r:1 w:1) + /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) + /// Storage: Salary Claimant (r:1 w:1) + /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) + /// Storage: RankedCollective Members (r:1 w:0) + /// Proof: RankedCollective Members (max_values: None, max_size: Some(42), added: 2517, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn payout_other() -> Weight { // Proof Size summary in bytes: // Measured: `462` // Estimated: `3593` - // Minimum execution time: 53_638_000 picoseconds. - Weight::from_parts(55_328_000, 3593) + // Minimum execution time: 64_706_000 picoseconds. + Weight::from_parts(65_763_000, 3593) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Salary::Status` (r:1 w:1) - /// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`) - /// Storage: `Salary::Claimant` (r:1 w:1) - /// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`) + /// Storage: Salary Status (r:1 w:1) + /// Proof: Salary Status (max_values: Some(1), max_size: Some(56), added: 551, mode: MaxEncodedLen) + /// Storage: Salary Claimant (r:1 w:1) + /// Proof: Salary Claimant (max_values: None, max_size: Some(78), added: 2553, mode: MaxEncodedLen) fn check_payment() -> Weight { // Proof Size summary in bytes: // Measured: `170` // Estimated: `3543` - // Minimum execution time: 10_557_000 picoseconds. - Weight::from_parts(11_145_000, 3543) + // Minimum execution time: 11_838_000 picoseconds. + Weight::from_parts(12_323_000, 3543) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } diff --git a/substrate/frame/sassafras/src/mock.rs b/substrate/frame/sassafras/src/mock.rs index 4c6efaa63a9..5e5909fcb0d 100644 --- a/substrate/frame/sassafras/src/mock.rs +++ b/substrate/frame/sassafras/src/mock.rs @@ -34,8 +34,7 @@ use sp_core::{ H256, U256, }; use sp_runtime::{ - generic::UncheckedExtrinsic, - testing::{Digest, DigestItem, Header}, + testing::{Digest, DigestItem, Header, TestXt}, BuildStorage, }; @@ -54,7 +53,7 @@ where RuntimeCall: From, { type OverarchingCall = RuntimeCall; - type Extrinsic = UncheckedExtrinsic; + type Extrinsic = TestXt; } impl pallet_sassafras::Config for Test { diff --git a/substrate/frame/scheduler/src/weights.rs b/substrate/frame/scheduler/src/weights.rs index 6c98145d266..9b7e5405a1b 100644 --- a/substrate/frame/scheduler/src/weights.rs +++ b/substrate/frame/scheduler/src/weights.rs @@ -17,28 +17,26 @@ //! Autogenerated weights for `pallet_scheduler` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2024-01-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-grjcggob-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate-node +// target/production/substrate-node // benchmark // pallet -// --chain=dev // --steps=50 // --repeat=20 -// --pallet=pallet_scheduler -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/scheduler/src/weights.rs +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_scheduler +// --chain=dev // --header=./substrate/HEADER-APACHE2 +// --output=./substrate/frame/scheduler/src/weights.rs // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -79,8 +77,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `31` // Estimated: `1489` - // Minimum execution time: 3_128_000 picoseconds. - Weight::from_parts(3_372_000, 1489) + // Minimum execution time: 3_040_000 picoseconds. + Weight::from_parts(3_202_000, 1489) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -91,10 +89,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `81 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 3_560_000 picoseconds. - Weight::from_parts(6_356_795, 110487) - // Standard Error: 493 - .saturating_add(Weight::from_parts(315_098, 0).saturating_mul(s.into())) + // Minimum execution time: 3_462_000 picoseconds. + Weight::from_parts(6_262_125, 110487) + // Standard Error: 536 + .saturating_add(Weight::from_parts(332_570, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -102,8 +100,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_501_000 picoseconds. - Weight::from_parts(3_722_000, 0) + // Minimum execution time: 3_425_000 picoseconds. + Weight::from_parts(3_680_000, 0) } /// Storage: `Preimage::PreimageFor` (r:1 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `Measured`) @@ -116,10 +114,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `246 + s * (1 ±0)` // Estimated: `3711 + s * (1 ±0)` - // Minimum execution time: 17_976_000 picoseconds. - Weight::from_parts(18_137_000, 3711) - // Standard Error: 0 - .saturating_add(Weight::from_parts(1_173, 0).saturating_mul(s.into())) + // Minimum execution time: 17_564_000 picoseconds. + Weight::from_parts(17_887_000, 3711) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_253, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(s.into())) @@ -130,16 +128,16 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_935_000 picoseconds. - Weight::from_parts(5_133_000, 0) + // Minimum execution time: 4_934_000 picoseconds. + Weight::from_parts(5_275_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } fn service_task_periodic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_467_000 picoseconds. - Weight::from_parts(3_654_000, 0) + // Minimum execution time: 3_348_000 picoseconds. + Weight::from_parts(3_561_000, 0) } /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -149,16 +147,16 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3997` - // Minimum execution time: 6_528_000 picoseconds. - Weight::from_parts(6_820_000, 3997) + // Minimum execution time: 6_395_000 picoseconds. + Weight::from_parts(6_642_000, 3997) .saturating_add(T::DbWeight::get().reads(2_u64)) } fn execute_dispatch_unsigned() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_202_000 picoseconds. - Weight::from_parts(2_360_000, 0) + // Minimum execution time: 2_167_000 picoseconds. + Weight::from_parts(2_266_000, 0) } /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) @@ -167,17 +165,15 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `81 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 10_222_000 picoseconds. - Weight::from_parts(13_654_958, 110487) - // Standard Error: 676 - .saturating_add(Weight::from_parts(338_633, 0).saturating_mul(s.into())) + // Minimum execution time: 10_009_000 picoseconds. + Weight::from_parts(13_565_985, 110487) + // Standard Error: 575 + .saturating_add(Weight::from_parts(354_760, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Lookup` (r:0 w:1) /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 512]`. @@ -185,12 +181,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `81 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 15_517_000 picoseconds. - Weight::from_parts(17_464_075, 110487) - // Standard Error: 952 - .saturating_add(Weight::from_parts(495_806, 0).saturating_mul(s.into())) + // Minimum execution time: 14_048_000 picoseconds. + Weight::from_parts(15_141_696, 110487) + // Standard Error: 1_082 + .saturating_add(Weight::from_parts(533_390, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Scheduler::Lookup` (r:1 w:1) /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) @@ -201,10 +197,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `596 + s * (178 ±0)` // Estimated: `110487` - // Minimum execution time: 13_091_000 picoseconds. - Weight::from_parts(19_101_313, 110487) - // Standard Error: 662 - .saturating_add(Weight::from_parts(342_468, 0).saturating_mul(s.into())) + // Minimum execution time: 12_902_000 picoseconds. + Weight::from_parts(18_957_156, 110487) + // Standard Error: 792 + .saturating_add(Weight::from_parts(361_909, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -212,35 +208,35 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 512]`. fn cancel_named(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `709 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 17_579_000 picoseconds. - Weight::from_parts(20_561_921, 110487) - // Standard Error: 792 - .saturating_add(Weight::from_parts(500_463, 0).saturating_mul(s.into())) + // Minimum execution time: 15_933_000 picoseconds. + Weight::from_parts(18_091_415, 110487) + // Standard Error: 779 + .saturating_add(Weight::from_parts(534_402, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) } + /// Storage: `Scheduler::Retries` (r:1 w:2) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Lookup` (r:0 w:1) + /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 512]`. fn schedule_retry(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `118` + // Measured: `159` // Estimated: `110487` - // Minimum execution time: 8_996_000 picoseconds. - Weight::from_parts(11_393_234, 110487) - // Standard Error: 190 - .saturating_add(Weight::from_parts(6_714, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + // Minimum execution time: 14_155_000 picoseconds. + Weight::from_parts(16_447_031, 110487) + // Standard Error: 233 + .saturating_add(Weight::from_parts(8_424, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) } /// Storage: `Scheduler::Agenda` (r:1 w:0) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) @@ -248,10 +244,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn set_retry() -> Weight { // Proof Size summary in bytes: - // Measured: `90705` + // Measured: `81 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 121_505_000 picoseconds. - Weight::from_parts(124_306_000, 110487) + // Minimum execution time: 8_130_000 picoseconds. + Weight::from_parts(9_047_554, 110487) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -263,10 +259,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn set_retry_named() -> Weight { // Proof Size summary in bytes: - // Measured: `91747` + // Measured: `647 + s * (178 ±0)` // Estimated: `110487` - // Minimum execution time: 128_070_000 picoseconds. - Weight::from_parts(132_683_000, 110487) + // Minimum execution time: 10_838_000 picoseconds. + Weight::from_parts(12_804_076, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -276,10 +272,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn cancel_retry() -> Weight { // Proof Size summary in bytes: - // Measured: `90717` + // Measured: `81 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 118_260_000 picoseconds. - Weight::from_parts(119_722_000, 110487) + // Minimum execution time: 8_130_000 picoseconds. + Weight::from_parts(9_047_554, 110487) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -291,10 +287,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn cancel_retry_named() -> Weight { // Proof Size summary in bytes: - // Measured: `91759` + // Measured: `647 + s * (178 ±0)` // Estimated: `110487` - // Minimum execution time: 129_036_000 picoseconds. - Weight::from_parts(133_975_000, 110487) + // Minimum execution time: 10_838_000 picoseconds. + Weight::from_parts(12_804_076, 110487) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -308,8 +304,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `31` // Estimated: `1489` - // Minimum execution time: 3_128_000 picoseconds. - Weight::from_parts(3_372_000, 1489) + // Minimum execution time: 3_040_000 picoseconds. + Weight::from_parts(3_202_000, 1489) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -320,10 +316,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `81 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 3_560_000 picoseconds. - Weight::from_parts(6_356_795, 110487) - // Standard Error: 493 - .saturating_add(Weight::from_parts(315_098, 0).saturating_mul(s.into())) + // Minimum execution time: 3_462_000 picoseconds. + Weight::from_parts(6_262_125, 110487) + // Standard Error: 536 + .saturating_add(Weight::from_parts(332_570, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -331,8 +327,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_501_000 picoseconds. - Weight::from_parts(3_722_000, 0) + // Minimum execution time: 3_425_000 picoseconds. + Weight::from_parts(3_680_000, 0) } /// Storage: `Preimage::PreimageFor` (r:1 w:1) /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `Measured`) @@ -345,10 +341,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `246 + s * (1 ±0)` // Estimated: `3711 + s * (1 ±0)` - // Minimum execution time: 17_976_000 picoseconds. - Weight::from_parts(18_137_000, 3711) - // Standard Error: 0 - .saturating_add(Weight::from_parts(1_173, 0).saturating_mul(s.into())) + // Minimum execution time: 17_564_000 picoseconds. + Weight::from_parts(17_887_000, 3711) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_253, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(s.into())) @@ -359,16 +355,16 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_935_000 picoseconds. - Weight::from_parts(5_133_000, 0) + // Minimum execution time: 4_934_000 picoseconds. + Weight::from_parts(5_275_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } fn service_task_periodic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_467_000 picoseconds. - Weight::from_parts(3_654_000, 0) + // Minimum execution time: 3_348_000 picoseconds. + Weight::from_parts(3_561_000, 0) } /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -378,16 +374,16 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3997` - // Minimum execution time: 6_528_000 picoseconds. - Weight::from_parts(6_820_000, 3997) + // Minimum execution time: 6_395_000 picoseconds. + Weight::from_parts(6_642_000, 3997) .saturating_add(RocksDbWeight::get().reads(2_u64)) } fn execute_dispatch_unsigned() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_202_000 picoseconds. - Weight::from_parts(2_360_000, 0) + // Minimum execution time: 2_167_000 picoseconds. + Weight::from_parts(2_266_000, 0) } /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) @@ -396,17 +392,15 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `81 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 10_222_000 picoseconds. - Weight::from_parts(13_654_958, 110487) - // Standard Error: 676 - .saturating_add(Weight::from_parts(338_633, 0).saturating_mul(s.into())) + // Minimum execution time: 10_009_000 picoseconds. + Weight::from_parts(13_565_985, 110487) + // Standard Error: 575 + .saturating_add(Weight::from_parts(354_760, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Lookup` (r:0 w:1) /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 512]`. @@ -414,12 +408,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `81 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 15_517_000 picoseconds. - Weight::from_parts(17_464_075, 110487) - // Standard Error: 952 - .saturating_add(Weight::from_parts(495_806, 0).saturating_mul(s.into())) + // Minimum execution time: 14_048_000 picoseconds. + Weight::from_parts(15_141_696, 110487) + // Standard Error: 1_082 + .saturating_add(Weight::from_parts(533_390, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Scheduler::Lookup` (r:1 w:1) /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) @@ -430,10 +424,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `596 + s * (178 ±0)` // Estimated: `110487` - // Minimum execution time: 13_091_000 picoseconds. - Weight::from_parts(19_101_313, 110487) - // Standard Error: 662 - .saturating_add(Weight::from_parts(342_468, 0).saturating_mul(s.into())) + // Minimum execution time: 12_902_000 picoseconds. + Weight::from_parts(18_957_156, 110487) + // Standard Error: 792 + .saturating_add(Weight::from_parts(361_909, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -441,35 +435,35 @@ impl WeightInfo for () { /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 512]`. fn cancel_named(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `709 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 17_579_000 picoseconds. - Weight::from_parts(20_561_921, 110487) - // Standard Error: 792 - .saturating_add(Weight::from_parts(500_463, 0).saturating_mul(s.into())) + // Minimum execution time: 15_933_000 picoseconds. + Weight::from_parts(18_091_415, 110487) + // Standard Error: 779 + .saturating_add(Weight::from_parts(534_402, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } + /// Storage: `Scheduler::Retries` (r:1 w:2) + /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) /// Storage: `Scheduler::Agenda` (r:1 w:1) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) - /// Storage: `Scheduler::Retries` (r:0 w:1) - /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) + /// Storage: `Scheduler::Lookup` (r:0 w:1) + /// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// The range of component `s` is `[1, 512]`. fn schedule_retry(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `118` + // Measured: `159` // Estimated: `110487` - // Minimum execution time: 8_996_000 picoseconds. - Weight::from_parts(11_393_234, 110487) - // Standard Error: 190 - .saturating_add(Weight::from_parts(6_714, 0).saturating_mul(s.into())) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) + // Minimum execution time: 14_155_000 picoseconds. + Weight::from_parts(16_447_031, 110487) + // Standard Error: 233 + .saturating_add(Weight::from_parts(8_424, 0).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) } /// Storage: `Scheduler::Agenda` (r:1 w:0) /// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(107022), added: 109497, mode: `MaxEncodedLen`) @@ -477,10 +471,10 @@ impl WeightInfo for () { /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn set_retry() -> Weight { // Proof Size summary in bytes: - // Measured: `90705` + // Measured: `81 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 121_505_000 picoseconds. - Weight::from_parts(124_306_000, 110487) + // Minimum execution time: 8_130_000 picoseconds. + Weight::from_parts(9_047_554, 110487) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -492,10 +486,10 @@ impl WeightInfo for () { /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn set_retry_named() -> Weight { // Proof Size summary in bytes: - // Measured: `91747` + // Measured: `647 + s * (178 ±0)` // Estimated: `110487` - // Minimum execution time: 128_070_000 picoseconds. - Weight::from_parts(132_683_000, 110487) + // Minimum execution time: 10_838_000 picoseconds. + Weight::from_parts(12_804_076, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -505,10 +499,10 @@ impl WeightInfo for () { /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn cancel_retry() -> Weight { // Proof Size summary in bytes: - // Measured: `90717` + // Measured: `81 + s * (177 ±0)` // Estimated: `110487` - // Minimum execution time: 118_260_000 picoseconds. - Weight::from_parts(119_722_000, 110487) + // Minimum execution time: 8_130_000 picoseconds. + Weight::from_parts(9_047_554, 110487) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -520,10 +514,10 @@ impl WeightInfo for () { /// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`) fn cancel_retry_named() -> Weight { // Proof Size summary in bytes: - // Measured: `91759` + // Measured: `647 + s * (178 ±0)` // Estimated: `110487` - // Minimum execution time: 129_036_000 picoseconds. - Weight::from_parts(133_975_000, 110487) + // Minimum execution time: 10_838_000 picoseconds. + Weight::from_parts(12_804_076, 110487) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/session/src/weights.rs b/substrate/frame/session/src/weights.rs index 09eb665ff3d..dd9848fd2c1 100644 --- a/substrate/frame/session/src/weights.rs +++ b/substrate/frame/session/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_session` +//! Autogenerated weights for pallet_session //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/session/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/session/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,77 +50,77 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_session`. +/// Weight functions needed for pallet_session. pub trait WeightInfo { fn set_keys() -> Weight; fn purge_keys() -> Weight; } -/// Weights for `pallet_session` using the Substrate node and recommended hardware. +/// Weights for pallet_session using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Staking::Ledger` (r:1 w:0) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Session::NextKeys` (r:1 w:1) - /// Proof: `Session::NextKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Session::KeyOwner` (r:6 w:6) - /// Proof: `Session::KeyOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Session NextKeys (r:1 w:1) + /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session KeyOwner (r:4 w:4) + /// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured) fn set_keys() -> Weight { // Proof Size summary in bytes: - // Measured: `1919` - // Estimated: `17759` - // Minimum execution time: 57_921_000 picoseconds. - Weight::from_parts(58_960_000, 17759) - .saturating_add(T::DbWeight::get().reads(8_u64)) - .saturating_add(T::DbWeight::get().writes(7_u64)) + // Measured: `1924` + // Estimated: `12814` + // Minimum execution time: 55_459_000 picoseconds. + Weight::from_parts(56_180_000, 12814) + .saturating_add(T::DbWeight::get().reads(6_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: `Staking::Ledger` (r:1 w:0) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Session::NextKeys` (r:1 w:1) - /// Proof: `Session::NextKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Session::KeyOwner` (r:0 w:6) - /// Proof: `Session::KeyOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Session NextKeys (r:1 w:1) + /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session KeyOwner (r:0 w:4) + /// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured) fn purge_keys() -> Weight { // Proof Size summary in bytes: - // Measured: `1817` - // Estimated: `5282` - // Minimum execution time: 40_983_000 picoseconds. - Weight::from_parts(42_700_000, 5282) + // Measured: `1791` + // Estimated: `5256` + // Minimum execution time: 40_194_000 picoseconds. + Weight::from_parts(41_313_000, 5256) .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(7_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Staking::Ledger` (r:1 w:0) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Session::NextKeys` (r:1 w:1) - /// Proof: `Session::NextKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Session::KeyOwner` (r:6 w:6) - /// Proof: `Session::KeyOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Session NextKeys (r:1 w:1) + /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session KeyOwner (r:4 w:4) + /// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured) fn set_keys() -> Weight { // Proof Size summary in bytes: - // Measured: `1919` - // Estimated: `17759` - // Minimum execution time: 57_921_000 picoseconds. - Weight::from_parts(58_960_000, 17759) - .saturating_add(RocksDbWeight::get().reads(8_u64)) - .saturating_add(RocksDbWeight::get().writes(7_u64)) + // Measured: `1924` + // Estimated: `12814` + // Minimum execution time: 55_459_000 picoseconds. + Weight::from_parts(56_180_000, 12814) + .saturating_add(RocksDbWeight::get().reads(6_u64)) + .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: `Staking::Ledger` (r:1 w:0) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Session::NextKeys` (r:1 w:1) - /// Proof: `Session::NextKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Session::KeyOwner` (r:0 w:6) - /// Proof: `Session::KeyOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Staking Ledger (r:1 w:0) + /// Proof: Staking Ledger (max_values: None, max_size: Some(1091), added: 3566, mode: MaxEncodedLen) + /// Storage: Session NextKeys (r:1 w:1) + /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: Session KeyOwner (r:0 w:4) + /// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured) fn purge_keys() -> Weight { // Proof Size summary in bytes: - // Measured: `1817` - // Estimated: `5282` - // Minimum execution time: 40_983_000 picoseconds. - Weight::from_parts(42_700_000, 5282) + // Measured: `1791` + // Estimated: `5256` + // Minimum execution time: 40_194_000 picoseconds. + Weight::from_parts(41_313_000, 5256) .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(7_u64)) + .saturating_add(RocksDbWeight::get().writes(5_u64)) } } diff --git a/substrate/frame/society/src/weights.rs b/substrate/frame/society/src/weights.rs index 1245f762972..c32c2383ac9 100644 --- a/substrate/frame/society/src/weights.rs +++ b/substrate/frame/society/src/weights.rs @@ -7,7 +7,7 @@ // 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 +// 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, @@ -15,41 +15,35 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_society` +//! Autogenerated weights for pallet_society //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2022-09-13, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev // --steps=50 // --repeat=20 // --pallet=pallet_society -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled -// --heap-pages=4096 -// --output=./substrate/frame/society/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --template=./.maintain/frame-weight-template.hbs +// --header=./HEADER-APACHE2 +// --output=./frame/society/src/weights.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] -#![allow(missing_docs)] use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_society`. +/// Weight functions needed for pallet_society. pub trait WeightInfo { fn bid() -> Weight; fn unbid() -> Weight; @@ -73,739 +67,309 @@ pub trait WeightInfo { fn cleanup_challenge() -> Weight; } -/// Weights for `pallet_society` using the Substrate node and recommended hardware. +/// Weights for pallet_society using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Society::Bids` (r:1 w:1) - /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Candidates` (r:1 w:0) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:1 w:0) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::SuspendedMembers` (r:1 w:0) - /// Proof: `Society::SuspendedMembers` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Parameters` (r:1 w:0) - /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + // Storage: Society Bids (r:1 w:1) + // Storage: Society Candidates (r:1 w:0) + // Storage: Society Members (r:1 w:0) + // Storage: Society SuspendedMembers (r:1 w:0) + // Storage: Society Parameters (r:1 w:0) fn bid() -> Weight { - // Proof Size summary in bytes: - // Measured: `444` - // Estimated: `3909` - // Minimum execution time: 29_905_000 picoseconds. - Weight::from_parts(31_031_000, 3909) - .saturating_add(T::DbWeight::get().reads(5_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } - /// Storage: `Society::Bids` (r:1 w:1) - /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Bids (r:1 w:1) fn unbid() -> Weight { - // Proof Size summary in bytes: - // Measured: `461` - // Estimated: `1946` - // Minimum execution time: 23_038_000 picoseconds. - Weight::from_parts(23_904_000, 1946) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } - /// Storage: `Society::Bids` (r:1 w:1) - /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Candidates` (r:1 w:0) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:2 w:1) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::SuspendedMembers` (r:1 w:0) - /// Proof: `Society::SuspendedMembers` (`max_values`: None, `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Bids (r:1 w:1) + // Storage: Society Candidates (r:1 w:0) + // Storage: Society Members (r:2 w:1) + // Storage: Society SuspendedMembers (r:1 w:0) fn vouch() -> Weight { - // Proof Size summary in bytes: - // Measured: `481` - // Estimated: `6421` - // Minimum execution time: 21_197_000 picoseconds. - Weight::from_parts(22_043_000, 6421) - .saturating_add(T::DbWeight::get().reads(5_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) - } - /// Storage: `Society::Bids` (r:1 w:1) - /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:1 w:1) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Bids (r:1 w:1) + // Storage: Society Members (r:1 w:1) fn unvouch() -> Weight { - // Proof Size summary in bytes: - // Measured: `535` - // Estimated: `4000` - // Minimum execution time: 14_402_000 picoseconds. - Weight::from_parts(15_171_000, 4000) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) - } - /// Storage: `Society::Candidates` (r:1 w:1) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:1 w:0) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Votes` (r:1 w:1) - /// Proof: `Society::Votes` (`max_values`: None, `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Candidates (r:1 w:1) + // Storage: Society Members (r:1 w:0) + // Storage: Society Votes (r:1 w:1) fn vote() -> Weight { - // Proof Size summary in bytes: - // Measured: `569` - // Estimated: `4034` - // Minimum execution time: 21_930_000 picoseconds. - Weight::from_parts(22_666_000, 4034) - .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) - } - /// Storage: `Society::Defending` (r:1 w:1) - /// Proof: `Society::Defending` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:1 w:0) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::ChallengeRoundCount` (r:1 w:0) - /// Proof: `Society::ChallengeRoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::DefenderVotes` (r:1 w:1) - /// Proof: `Society::DefenderVotes` (`max_values`: None, `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Defending (r:1 w:1) + // Storage: Society Members (r:1 w:0) + // Storage: Society ChallengeRoundCount (r:1 w:0) + // Storage: Society DefenderVotes (r:1 w:1) fn defender_vote() -> Weight { - // Proof Size summary in bytes: - // Measured: `561` - // Estimated: `4026` - // Minimum execution time: 18_821_000 picoseconds. - Weight::from_parts(19_633_000, 4026) - .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) - } - /// Storage: `Society::Members` (r:1 w:0) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Payouts` (r:1 w:1) - /// Proof: `Society::Payouts` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + Weight::zero() + } + // Storage: Society Members (r:1 w:0) + // Storage: Society Payouts (r:1 w:1) + // Storage: System Account (r:1 w:1) fn payout() -> Weight { - // Proof Size summary in bytes: - // Measured: `650` - // Estimated: `4115` - // Minimum execution time: 47_262_000 picoseconds. - Weight::from_parts(48_313_000, 4115) - .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) - } - /// Storage: `Society::Members` (r:1 w:1) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Payouts` (r:1 w:1) - /// Proof: `Society::Payouts` (`max_values`: None, `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Members (r:1 w:1) + // Storage: Society Payouts (r:1 w:1) fn waive_repay() -> Weight { - // Proof Size summary in bytes: - // Measured: `547` - // Estimated: `4012` - // Minimum execution time: 18_189_000 picoseconds. - Weight::from_parts(19_038_000, 4012) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) - } - /// Storage: `Society::Head` (r:1 w:1) - /// Proof: `Society::Head` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::MemberCount` (r:1 w:1) - /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::MemberByIndex` (r:0 w:1) - /// Proof: `Society::MemberByIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Founder` (r:0 w:1) - /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Rules` (r:0 w:1) - /// Proof: `Society::Rules` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:0 w:1) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Parameters` (r:0 w:1) - /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Head (r:1 w:1) + // Storage: Society MemberCount (r:1 w:1) + // Storage: Society MemberByIndex (r:0 w:1) + // Storage: Society Founder (r:0 w:1) + // Storage: Society Rules (r:0 w:1) + // Storage: Society Members (r:0 w:1) + // Storage: Society Parameters (r:0 w:1) fn found_society() -> Weight { - // Proof Size summary in bytes: - // Measured: `180` - // Estimated: `1665` - // Minimum execution time: 14_815_000 picoseconds. - Weight::from_parts(15_426_000, 1665) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(7_u64)) - } - /// Storage: `Society::Founder` (r:1 w:1) - /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::MemberCount` (r:1 w:1) - /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:5 w:5) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::MemberByIndex` (r:5 w:5) - /// Proof: `Society::MemberByIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Votes` (r:4 w:4) - /// Proof: `Society::Votes` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Candidates` (r:4 w:4) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Head` (r:0 w:1) - /// Proof: `Society::Head` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Defending` (r:0 w:1) - /// Proof: `Society::Defending` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::ChallengeRoundCount` (r:0 w:1) - /// Proof: `Society::ChallengeRoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Skeptic` (r:0 w:1) - /// Proof: `Society::Skeptic` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Pot` (r:0 w:1) - /// Proof: `Society::Pot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Rules` (r:0 w:1) - /// Proof: `Society::Rules` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::RoundCount` (r:0 w:1) - /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Bids` (r:0 w:1) - /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Parameters` (r:0 w:1) - /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::NextHead` (r:0 w:1) - /// Proof: `Society::NextHead` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Founder (r:1 w:1) + // Storage: Society MemberCount (r:1 w:1) + // Storage: Society Head (r:0 w:1) + // Storage: Society Defending (r:0 w:1) + // Storage: Society ChallengeRoundCount (r:0 w:1) + // Storage: Society MemberByIndex (r:0 w:5) + // Storage: Society Skeptic (r:0 w:1) + // Storage: Society Candidates (r:0 w:4) + // Storage: Society Pot (r:0 w:1) + // Storage: Society Rules (r:0 w:1) + // Storage: Society Votes (r:0 w:4) + // Storage: Society Members (r:0 w:5) + // Storage: Society RoundCount (r:0 w:1) + // Storage: Society Bids (r:0 w:1) + // Storage: Society Parameters (r:0 w:1) + // Storage: Society NextHead (r:0 w:1) fn dissolve() -> Weight { - // Proof Size summary in bytes: - // Measured: `1654` - // Estimated: `15019` - // Minimum execution time: 57_787_000 picoseconds. - Weight::from_parts(59_489_000, 15019) - .saturating_add(T::DbWeight::get().reads(20_u64)) - .saturating_add(T::DbWeight::get().writes(30_u64)) - } - /// Storage: `Society::Founder` (r:1 w:0) - /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::SuspendedMembers` (r:1 w:1) - /// Proof: `Society::SuspendedMembers` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Payouts` (r:1 w:0) - /// Proof: `Society::Payouts` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Pot` (r:1 w:1) - /// Proof: `Society::Pot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Founder (r:1 w:0) + // Storage: Society SuspendedMembers (r:1 w:1) + // Storage: Society Payouts (r:1 w:0) + // Storage: Society Pot (r:1 w:1) fn judge_suspended_member() -> Weight { - // Proof Size summary in bytes: - // Measured: `505` - // Estimated: `3970` - // Minimum execution time: 19_262_000 picoseconds. - Weight::from_parts(19_752_000, 3970) - .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) - } - /// Storage: `Society::Founder` (r:1 w:0) - /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::MemberCount` (r:1 w:0) - /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Parameters` (r:0 w:1) - /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Founder (r:1 w:0) + // Storage: Society MemberCount (r:1 w:0) + // Storage: Society Parameters (r:0 w:1) fn set_parameters() -> Weight { - // Proof Size summary in bytes: - // Measured: `387` - // Estimated: `1872` - // Minimum execution time: 10_656_000 picoseconds. - Weight::from_parts(11_063_000, 1872) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } - /// Storage: `Society::Candidates` (r:1 w:1) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::RoundCount` (r:1 w:0) - /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Skeptic` (r:1 w:0) - /// Proof: `Society::Skeptic` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Votes` (r:1 w:0) - /// Proof: `Society::Votes` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:1 w:1) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Parameters` (r:1 w:0) - /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Candidates (r:1 w:1) + // Storage: Society RoundCount (r:1 w:0) + // Storage: Society Skeptic (r:1 w:0) + // Storage: Society Votes (r:1 w:0) + // Storage: Society Members (r:1 w:1) + // Storage: Society Parameters (r:1 w:0) fn punish_skeptic() -> Weight { - // Proof Size summary in bytes: - // Measured: `636` - // Estimated: `4101` - // Minimum execution time: 22_837_000 picoseconds. - Weight::from_parts(23_738_000, 4101) - .saturating_add(T::DbWeight::get().reads(6_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) - } - /// Storage: `Society::Candidates` (r:1 w:1) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::RoundCount` (r:1 w:0) - /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Parameters` (r:1 w:0) - /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::MemberCount` (r:1 w:1) - /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::NextHead` (r:1 w:1) - /// Proof: `Society::NextHead` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Society::MemberByIndex` (r:0 w:1) - /// Proof: `Society::MemberByIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:0 w:1) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Candidates (r:1 w:1) + // Storage: Society RoundCount (r:1 w:0) + // Storage: Society Parameters (r:1 w:0) + // Storage: Society MemberCount (r:1 w:1) + // Storage: Society NextHead (r:1 w:1) + // Storage: System Account (r:1 w:1) + // Storage: Society MemberByIndex (r:0 w:1) + // Storage: Society Members (r:0 w:1) fn claim_membership() -> Weight { - // Proof Size summary in bytes: - // Measured: `632` - // Estimated: `4097` - // Minimum execution time: 35_142_000 picoseconds. - Weight::from_parts(36_811_000, 4097) - .saturating_add(T::DbWeight::get().reads(6_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) - } - /// Storage: `Society::Founder` (r:1 w:0) - /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Candidates` (r:1 w:1) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::RoundCount` (r:1 w:0) - /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Parameters` (r:1 w:0) - /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::MemberCount` (r:1 w:1) - /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::NextHead` (r:1 w:1) - /// Proof: `Society::NextHead` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Society::MemberByIndex` (r:0 w:1) - /// Proof: `Society::MemberByIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:0 w:1) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Founder (r:1 w:0) + // Storage: Society Candidates (r:1 w:1) + // Storage: Society RoundCount (r:1 w:0) + // Storage: Society Parameters (r:1 w:0) + // Storage: Society MemberCount (r:1 w:1) + // Storage: Society NextHead (r:1 w:1) + // Storage: System Account (r:1 w:1) + // Storage: Society MemberByIndex (r:0 w:1) + // Storage: Society Members (r:0 w:1) fn bestow_membership() -> Weight { - // Proof Size summary in bytes: - // Measured: `650` - // Estimated: `4115` - // Minimum execution time: 37_133_000 picoseconds. - Weight::from_parts(38_366_000, 4115) - .saturating_add(T::DbWeight::get().reads(7_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) - } - /// Storage: `Society::Founder` (r:1 w:0) - /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Candidates` (r:1 w:1) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::RoundCount` (r:1 w:0) - /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + Weight::zero() + } + // Storage: Society Founder (r:1 w:0) + // Storage: Society Candidates (r:1 w:1) + // Storage: Society RoundCount (r:1 w:0) fn kick_candidate() -> Weight { - // Proof Size summary in bytes: - // Measured: `776` - // Estimated: `6196` - // Minimum execution time: 37_033_000 picoseconds. - Weight::from_parts(38_293_000, 6196) - .saturating_add(T::DbWeight::get().reads(5_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) - } - /// Storage: `Society::Candidates` (r:1 w:1) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::RoundCount` (r:1 w:0) - /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + Weight::zero() + } + // Storage: Society Candidates (r:1 w:1) + // Storage: Society RoundCount (r:1 w:0) fn resign_candidacy() -> Weight { - // Proof Size summary in bytes: - // Measured: `746` - // Estimated: `6196` - // Minimum execution time: 35_203_000 picoseconds. - Weight::from_parts(36_252_000, 6196) - .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) - } - /// Storage: `Society::Candidates` (r:1 w:1) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::RoundCount` (r:1 w:0) - /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + Weight::zero() + } + // Storage: Society Candidates (r:1 w:1) + // Storage: Society RoundCount (r:1 w:0) fn drop_candidate() -> Weight { - // Proof Size summary in bytes: - // Measured: `758` - // Estimated: `6196` - // Minimum execution time: 35_518_000 picoseconds. - Weight::from_parts(36_508_000, 6196) - .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) - } - /// Storage: `Society::Candidates` (r:1 w:0) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::VoteClearCursor` (r:1 w:0) - /// Proof: `Society::VoteClearCursor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Votes` (r:2 w:2) - /// Proof: `Society::Votes` (`max_values`: None, `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Candidates (r:1 w:0) + // Storage: Society VoteClearCursor (r:1 w:0) + // Storage: Society Votes (r:0 w:2) fn cleanup_candidacy() -> Weight { - // Proof Size summary in bytes: - // Measured: `552` - // Estimated: `6492` - // Minimum execution time: 17_001_000 picoseconds. - Weight::from_parts(17_845_000, 6492) - .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) - } - /// Storage: `Society::ChallengeRoundCount` (r:1 w:0) - /// Proof: `Society::ChallengeRoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::DefenderVotes` (r:1 w:1) - /// Proof: `Society::DefenderVotes` (`max_values`: None, `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society ChallengeRoundCount (r:1 w:0) + // Storage: Society DefenderVotes (r:0 w:1) fn cleanup_challenge() -> Weight { - // Proof Size summary in bytes: - // Measured: `510` - // Estimated: `3975` - // Minimum execution time: 11_583_000 picoseconds. - Weight::from_parts(12_134_000, 3975) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + Weight::zero() } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Society::Bids` (r:1 w:1) - /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Candidates` (r:1 w:0) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:1 w:0) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::SuspendedMembers` (r:1 w:0) - /// Proof: `Society::SuspendedMembers` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Parameters` (r:1 w:0) - /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + // Storage: Society Bids (r:1 w:1) + // Storage: Society Candidates (r:1 w:0) + // Storage: Society Members (r:1 w:0) + // Storage: Society SuspendedMembers (r:1 w:0) + // Storage: Society Parameters (r:1 w:0) fn bid() -> Weight { - // Proof Size summary in bytes: - // Measured: `444` - // Estimated: `3909` - // Minimum execution time: 29_905_000 picoseconds. - Weight::from_parts(31_031_000, 3909) - .saturating_add(RocksDbWeight::get().reads(5_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - } - /// Storage: `Society::Bids` (r:1 w:1) - /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Bids (r:1 w:1) fn unbid() -> Weight { - // Proof Size summary in bytes: - // Measured: `461` - // Estimated: `1946` - // Minimum execution time: 23_038_000 picoseconds. - Weight::from_parts(23_904_000, 1946) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - } - /// Storage: `Society::Bids` (r:1 w:1) - /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Candidates` (r:1 w:0) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:2 w:1) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::SuspendedMembers` (r:1 w:0) - /// Proof: `Society::SuspendedMembers` (`max_values`: None, `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Bids (r:1 w:1) + // Storage: Society Candidates (r:1 w:0) + // Storage: Society Members (r:2 w:1) + // Storage: Society SuspendedMembers (r:1 w:0) fn vouch() -> Weight { - // Proof Size summary in bytes: - // Measured: `481` - // Estimated: `6421` - // Minimum execution time: 21_197_000 picoseconds. - Weight::from_parts(22_043_000, 6421) - .saturating_add(RocksDbWeight::get().reads(5_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) - } - /// Storage: `Society::Bids` (r:1 w:1) - /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:1 w:1) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Bids (r:1 w:1) + // Storage: Society Members (r:1 w:1) fn unvouch() -> Weight { - // Proof Size summary in bytes: - // Measured: `535` - // Estimated: `4000` - // Minimum execution time: 14_402_000 picoseconds. - Weight::from_parts(15_171_000, 4000) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) - } - /// Storage: `Society::Candidates` (r:1 w:1) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:1 w:0) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Votes` (r:1 w:1) - /// Proof: `Society::Votes` (`max_values`: None, `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Candidates (r:1 w:1) + // Storage: Society Members (r:1 w:0) + // Storage: Society Votes (r:1 w:1) fn vote() -> Weight { - // Proof Size summary in bytes: - // Measured: `569` - // Estimated: `4034` - // Minimum execution time: 21_930_000 picoseconds. - Weight::from_parts(22_666_000, 4034) - .saturating_add(RocksDbWeight::get().reads(3_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) - } - /// Storage: `Society::Defending` (r:1 w:1) - /// Proof: `Society::Defending` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:1 w:0) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::ChallengeRoundCount` (r:1 w:0) - /// Proof: `Society::ChallengeRoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::DefenderVotes` (r:1 w:1) - /// Proof: `Society::DefenderVotes` (`max_values`: None, `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Defending (r:1 w:1) + // Storage: Society Members (r:1 w:0) + // Storage: Society ChallengeRoundCount (r:1 w:0) + // Storage: Society DefenderVotes (r:1 w:1) fn defender_vote() -> Weight { - // Proof Size summary in bytes: - // Measured: `561` - // Estimated: `4026` - // Minimum execution time: 18_821_000 picoseconds. - Weight::from_parts(19_633_000, 4026) - .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) - } - /// Storage: `Society::Members` (r:1 w:0) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Payouts` (r:1 w:1) - /// Proof: `Society::Payouts` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + Weight::zero() + } + // Storage: Society Members (r:1 w:0) + // Storage: Society Payouts (r:1 w:1) + // Storage: System Account (r:1 w:1) fn payout() -> Weight { - // Proof Size summary in bytes: - // Measured: `650` - // Estimated: `4115` - // Minimum execution time: 47_262_000 picoseconds. - Weight::from_parts(48_313_000, 4115) - .saturating_add(RocksDbWeight::get().reads(3_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) - } - /// Storage: `Society::Members` (r:1 w:1) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Payouts` (r:1 w:1) - /// Proof: `Society::Payouts` (`max_values`: None, `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Members (r:1 w:1) + // Storage: Society Payouts (r:1 w:1) fn waive_repay() -> Weight { - // Proof Size summary in bytes: - // Measured: `547` - // Estimated: `4012` - // Minimum execution time: 18_189_000 picoseconds. - Weight::from_parts(19_038_000, 4012) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) - } - /// Storage: `Society::Head` (r:1 w:1) - /// Proof: `Society::Head` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::MemberCount` (r:1 w:1) - /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::MemberByIndex` (r:0 w:1) - /// Proof: `Society::MemberByIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Founder` (r:0 w:1) - /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Rules` (r:0 w:1) - /// Proof: `Society::Rules` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:0 w:1) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Parameters` (r:0 w:1) - /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Head (r:1 w:1) + // Storage: Society MemberCount (r:1 w:1) + // Storage: Society MemberByIndex (r:0 w:1) + // Storage: Society Founder (r:0 w:1) + // Storage: Society Rules (r:0 w:1) + // Storage: Society Members (r:0 w:1) + // Storage: Society Parameters (r:0 w:1) fn found_society() -> Weight { - // Proof Size summary in bytes: - // Measured: `180` - // Estimated: `1665` - // Minimum execution time: 14_815_000 picoseconds. - Weight::from_parts(15_426_000, 1665) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(7_u64)) - } - /// Storage: `Society::Founder` (r:1 w:1) - /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::MemberCount` (r:1 w:1) - /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:5 w:5) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::MemberByIndex` (r:5 w:5) - /// Proof: `Society::MemberByIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Votes` (r:4 w:4) - /// Proof: `Society::Votes` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Candidates` (r:4 w:4) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Head` (r:0 w:1) - /// Proof: `Society::Head` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Defending` (r:0 w:1) - /// Proof: `Society::Defending` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::ChallengeRoundCount` (r:0 w:1) - /// Proof: `Society::ChallengeRoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Skeptic` (r:0 w:1) - /// Proof: `Society::Skeptic` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Pot` (r:0 w:1) - /// Proof: `Society::Pot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Rules` (r:0 w:1) - /// Proof: `Society::Rules` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::RoundCount` (r:0 w:1) - /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Bids` (r:0 w:1) - /// Proof: `Society::Bids` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Parameters` (r:0 w:1) - /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::NextHead` (r:0 w:1) - /// Proof: `Society::NextHead` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Founder (r:1 w:1) + // Storage: Society MemberCount (r:1 w:1) + // Storage: Society Head (r:0 w:1) + // Storage: Society Defending (r:0 w:1) + // Storage: Society ChallengeRoundCount (r:0 w:1) + // Storage: Society MemberByIndex (r:0 w:5) + // Storage: Society Skeptic (r:0 w:1) + // Storage: Society Candidates (r:0 w:4) + // Storage: Society Pot (r:0 w:1) + // Storage: Society Rules (r:0 w:1) + // Storage: Society Votes (r:0 w:4) + // Storage: Society Members (r:0 w:5) + // Storage: Society RoundCount (r:0 w:1) + // Storage: Society Bids (r:0 w:1) + // Storage: Society Parameters (r:0 w:1) + // Storage: Society NextHead (r:0 w:1) fn dissolve() -> Weight { - // Proof Size summary in bytes: - // Measured: `1654` - // Estimated: `15019` - // Minimum execution time: 57_787_000 picoseconds. - Weight::from_parts(59_489_000, 15019) - .saturating_add(RocksDbWeight::get().reads(20_u64)) - .saturating_add(RocksDbWeight::get().writes(30_u64)) - } - /// Storage: `Society::Founder` (r:1 w:0) - /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::SuspendedMembers` (r:1 w:1) - /// Proof: `Society::SuspendedMembers` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Payouts` (r:1 w:0) - /// Proof: `Society::Payouts` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Pot` (r:1 w:1) - /// Proof: `Society::Pot` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Founder (r:1 w:0) + // Storage: Society SuspendedMembers (r:1 w:1) + // Storage: Society Payouts (r:1 w:0) + // Storage: Society Pot (r:1 w:1) fn judge_suspended_member() -> Weight { - // Proof Size summary in bytes: - // Measured: `505` - // Estimated: `3970` - // Minimum execution time: 19_262_000 picoseconds. - Weight::from_parts(19_752_000, 3970) - .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) - } - /// Storage: `Society::Founder` (r:1 w:0) - /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::MemberCount` (r:1 w:0) - /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Parameters` (r:0 w:1) - /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Founder (r:1 w:0) + // Storage: Society MemberCount (r:1 w:0) + // Storage: Society Parameters (r:0 w:1) fn set_parameters() -> Weight { - // Proof Size summary in bytes: - // Measured: `387` - // Estimated: `1872` - // Minimum execution time: 10_656_000 picoseconds. - Weight::from_parts(11_063_000, 1872) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - } - /// Storage: `Society::Candidates` (r:1 w:1) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::RoundCount` (r:1 w:0) - /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Skeptic` (r:1 w:0) - /// Proof: `Society::Skeptic` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Votes` (r:1 w:0) - /// Proof: `Society::Votes` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:1 w:1) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Parameters` (r:1 w:0) - /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Candidates (r:1 w:1) + // Storage: Society RoundCount (r:1 w:0) + // Storage: Society Skeptic (r:1 w:0) + // Storage: Society Votes (r:1 w:0) + // Storage: Society Members (r:1 w:1) + // Storage: Society Parameters (r:1 w:0) fn punish_skeptic() -> Weight { - // Proof Size summary in bytes: - // Measured: `636` - // Estimated: `4101` - // Minimum execution time: 22_837_000 picoseconds. - Weight::from_parts(23_738_000, 4101) - .saturating_add(RocksDbWeight::get().reads(6_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) - } - /// Storage: `Society::Candidates` (r:1 w:1) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::RoundCount` (r:1 w:0) - /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Parameters` (r:1 w:0) - /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::MemberCount` (r:1 w:1) - /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::NextHead` (r:1 w:1) - /// Proof: `Society::NextHead` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Society::MemberByIndex` (r:0 w:1) - /// Proof: `Society::MemberByIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:0 w:1) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Candidates (r:1 w:1) + // Storage: Society RoundCount (r:1 w:0) + // Storage: Society Parameters (r:1 w:0) + // Storage: Society MemberCount (r:1 w:1) + // Storage: Society NextHead (r:1 w:1) + // Storage: System Account (r:1 w:1) + // Storage: Society MemberByIndex (r:0 w:1) + // Storage: Society Members (r:0 w:1) fn claim_membership() -> Weight { - // Proof Size summary in bytes: - // Measured: `632` - // Estimated: `4097` - // Minimum execution time: 35_142_000 picoseconds. - Weight::from_parts(36_811_000, 4097) - .saturating_add(RocksDbWeight::get().reads(6_u64)) - .saturating_add(RocksDbWeight::get().writes(6_u64)) - } - /// Storage: `Society::Founder` (r:1 w:0) - /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Candidates` (r:1 w:1) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::RoundCount` (r:1 w:0) - /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Parameters` (r:1 w:0) - /// Proof: `Society::Parameters` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::MemberCount` (r:1 w:1) - /// Proof: `Society::MemberCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::NextHead` (r:1 w:1) - /// Proof: `Society::NextHead` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Society::MemberByIndex` (r:0 w:1) - /// Proof: `Society::MemberByIndex` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Members` (r:0 w:1) - /// Proof: `Society::Members` (`max_values`: None, `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Founder (r:1 w:0) + // Storage: Society Candidates (r:1 w:1) + // Storage: Society RoundCount (r:1 w:0) + // Storage: Society Parameters (r:1 w:0) + // Storage: Society MemberCount (r:1 w:1) + // Storage: Society NextHead (r:1 w:1) + // Storage: System Account (r:1 w:1) + // Storage: Society MemberByIndex (r:0 w:1) + // Storage: Society Members (r:0 w:1) fn bestow_membership() -> Weight { - // Proof Size summary in bytes: - // Measured: `650` - // Estimated: `4115` - // Minimum execution time: 37_133_000 picoseconds. - Weight::from_parts(38_366_000, 4115) - .saturating_add(RocksDbWeight::get().reads(7_u64)) - .saturating_add(RocksDbWeight::get().writes(6_u64)) - } - /// Storage: `Society::Founder` (r:1 w:0) - /// Proof: `Society::Founder` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::Candidates` (r:1 w:1) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::RoundCount` (r:1 w:0) - /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + Weight::zero() + } + // Storage: Society Founder (r:1 w:0) + // Storage: Society Candidates (r:1 w:1) + // Storage: Society RoundCount (r:1 w:0) fn kick_candidate() -> Weight { - // Proof Size summary in bytes: - // Measured: `776` - // Estimated: `6196` - // Minimum execution time: 37_033_000 picoseconds. - Weight::from_parts(38_293_000, 6196) - .saturating_add(RocksDbWeight::get().reads(5_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) - } - /// Storage: `Society::Candidates` (r:1 w:1) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::RoundCount` (r:1 w:0) - /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + Weight::zero() + } + // Storage: Society Candidates (r:1 w:1) + // Storage: Society RoundCount (r:1 w:0) fn resign_candidacy() -> Weight { - // Proof Size summary in bytes: - // Measured: `746` - // Estimated: `6196` - // Minimum execution time: 35_203_000 picoseconds. - Weight::from_parts(36_252_000, 6196) - .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) - } - /// Storage: `Society::Candidates` (r:1 w:1) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::RoundCount` (r:1 w:0) - /// Proof: `Society::RoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + Weight::zero() + } + // Storage: Society Candidates (r:1 w:1) + // Storage: Society RoundCount (r:1 w:0) fn drop_candidate() -> Weight { - // Proof Size summary in bytes: - // Measured: `758` - // Estimated: `6196` - // Minimum execution time: 35_518_000 picoseconds. - Weight::from_parts(36_508_000, 6196) - .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) - } - /// Storage: `Society::Candidates` (r:1 w:0) - /// Proof: `Society::Candidates` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::VoteClearCursor` (r:1 w:0) - /// Proof: `Society::VoteClearCursor` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Society::Votes` (r:2 w:2) - /// Proof: `Society::Votes` (`max_values`: None, `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society Candidates (r:1 w:0) + // Storage: Society VoteClearCursor (r:1 w:0) + // Storage: Society Votes (r:0 w:2) fn cleanup_candidacy() -> Weight { - // Proof Size summary in bytes: - // Measured: `552` - // Estimated: `6492` - // Minimum execution time: 17_001_000 picoseconds. - Weight::from_parts(17_845_000, 6492) - .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) - } - /// Storage: `Society::ChallengeRoundCount` (r:1 w:0) - /// Proof: `Society::ChallengeRoundCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Society::DefenderVotes` (r:1 w:1) - /// Proof: `Society::DefenderVotes` (`max_values`: None, `max_size`: None, mode: `Measured`) + Weight::zero() + } + // Storage: Society ChallengeRoundCount (r:1 w:0) + // Storage: Society DefenderVotes (r:0 w:1) fn cleanup_challenge() -> Weight { - // Proof Size summary in bytes: - // Measured: `510` - // Estimated: `3975` - // Minimum execution time: 11_583_000 picoseconds. - Weight::from_parts(12_134_000, 3975) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + Weight::zero() } } diff --git a/substrate/frame/src/lib.rs b/substrate/frame/src/lib.rs index 549e177491d..52db7c34bfd 100644 --- a/substrate/frame/src/lib.rs +++ b/substrate/frame/src/lib.rs @@ -249,8 +249,8 @@ pub mod runtime { /// The block type, which should be fed into [`frame_system::Config`]. /// - /// Should be parameterized with `T: frame_system::Config` and a tuple of - /// `TransactionExtension`. When in doubt, use [`SystemTransactionExtensionsOf`]. + /// Should be parameterized with `T: frame_system::Config` and a tuple of `SignedExtension`. + /// When in doubt, use [`SystemSignedExtensionsOf`]. // Note that this cannot be dependent on `T` for block-number because it would lead to a // circular dependency (self-referential generics). pub type BlockOf = generic::Block>; @@ -264,7 +264,7 @@ pub mod runtime { /// Default set of signed extensions exposed from the `frame_system`. /// /// crucially, this does NOT contain any tx-payment extension. - pub type SystemTransactionExtensionsOf = ( + pub type SystemSignedExtensionsOf = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, diff --git a/substrate/frame/staking/src/weights.rs b/substrate/frame/staking/src/weights.rs index 8288591a787..6f729e08ba5 100644 --- a/substrate/frame/staking/src/weights.rs +++ b/substrate/frame/staking/src/weights.rs @@ -17,28 +17,26 @@ //! Autogenerated weights for `pallet_staking` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2024-01-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-q7z7ruxr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate-node +// target/production/substrate-node // benchmark // pallet -// --chain=dev // --steps=50 // --repeat=20 -// --pallet=pallet_staking -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/staking/src/weights.rs +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_staking +// --chain=dev // --header=./substrate/HEADER-APACHE2 +// --output=./substrate/frame/staking/src/weights.rs // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -101,8 +99,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `927` // Estimated: `4764` - // Minimum execution time: 41_318_000 picoseconds. - Weight::from_parts(43_268_000, 4764) + // Minimum execution time: 42_042_000 picoseconds. + Weight::from_parts(43_292_000, 4764) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -122,8 +120,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1990` // Estimated: `8877` - // Minimum execution time: 85_666_000 picoseconds. - Weight::from_parts(88_749_000, 8877) + // Minimum execution time: 85_050_000 picoseconds. + Weight::from_parts(87_567_000, 8877) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } @@ -149,8 +147,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2195` // Estimated: `8877` - // Minimum execution time: 90_282_000 picoseconds. - Weight::from_parts(92_332_000, 8877) + // Minimum execution time: 89_076_000 picoseconds. + Weight::from_parts(92_715_000, 8877) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } @@ -164,18 +162,16 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:0) - /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_update(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1297` + // Measured: `1115` // Estimated: `4764` - // Minimum execution time: 44_626_000 picoseconds. - Weight::from_parts(47_254_657, 4764) - // Standard Error: 1_179 - .saturating_add(Weight::from_parts(57_657, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(6_u64)) + // Minimum execution time: 42_067_000 picoseconds. + Weight::from_parts(43_239_807, 4764) + // Standard Error: 831 + .saturating_add(Weight::from_parts(46_257, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Staking::Ledger` (r:1 w:1) @@ -211,10 +207,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2196 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 86_769_000 picoseconds. - Weight::from_parts(95_212_867, 6248) - // Standard Error: 3_706 - .saturating_add(Weight::from_parts(1_320_752, 0).saturating_mul(s.into())) + // Minimum execution time: 86_490_000 picoseconds. + Weight::from_parts(95_358_751, 6248) + // Standard Error: 3_952 + .saturating_add(Weight::from_parts(1_294_907, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(13_u64)) .saturating_add(T::DbWeight::get().writes(11_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) @@ -246,8 +242,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1372` // Estimated: `4556` - // Minimum execution time: 50_410_000 picoseconds. - Weight::from_parts(52_576_000, 4556) + // Minimum execution time: 50_326_000 picoseconds. + Weight::from_parts(52_253_000, 4556) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } @@ -260,10 +256,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1280 + k * (569 ±0)` // Estimated: `4556 + k * (3033 ±0)` - // Minimum execution time: 29_017_000 picoseconds. - Weight::from_parts(33_019_206, 4556) - // Standard Error: 6_368 - .saturating_add(Weight::from_parts(6_158_681, 0).saturating_mul(k.into())) + // Minimum execution time: 29_305_000 picoseconds. + Weight::from_parts(32_199_604, 4556) + // Standard Error: 7_150 + .saturating_add(Weight::from_parts(6_437_124, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(k.into()))) @@ -296,10 +292,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1866 + n * (102 ±0)` // Estimated: `6248 + n * (2520 ±0)` - // Minimum execution time: 63_452_000 picoseconds. - Weight::from_parts(60_924_066, 6248) - // Standard Error: 14_416 - .saturating_add(Weight::from_parts(3_921_589, 0).saturating_mul(n.into())) + // Minimum execution time: 63_267_000 picoseconds. + Weight::from_parts(61_741_404, 6248) + // Standard Error: 12_955 + .saturating_add(Weight::from_parts(3_811_743, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(6_u64)) @@ -323,8 +319,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1650` // Estimated: `6248` - // Minimum execution time: 54_253_000 picoseconds. - Weight::from_parts(55_286_000, 6248) + // Minimum execution time: 52_862_000 picoseconds. + Weight::from_parts(54_108_000, 6248) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -338,8 +334,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `902` // Estimated: `4556` - // Minimum execution time: 16_812_000 picoseconds. - Weight::from_parts(17_380_000, 4556) + // Minimum execution time: 16_350_000 picoseconds. + Weight::from_parts(16_802_000, 4556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -353,8 +349,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `969` // Estimated: `4556` - // Minimum execution time: 20_590_000 picoseconds. - Weight::from_parts(21_096_000, 4556) + // Minimum execution time: 19_981_000 picoseconds. + Weight::from_parts(20_539_000, 4556) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -366,8 +362,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `902` // Estimated: `4556` - // Minimum execution time: 19_923_000 picoseconds. - Weight::from_parts(20_880_000, 4556) + // Minimum execution time: 19_304_000 picoseconds. + Weight::from_parts(20_000_000, 4556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -377,8 +373,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_599_000 picoseconds. - Weight::from_parts(2_751_000, 0) + // Minimum execution time: 2_568_000 picoseconds. + Weight::from_parts(2_708_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -387,8 +383,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_941_000 picoseconds. - Weight::from_parts(7_288_000, 0) + // Minimum execution time: 7_950_000 picoseconds. + Weight::from_parts(8_348_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -397,8 +393,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_757_000 picoseconds. - Weight::from_parts(7_200_000, 0) + // Minimum execution time: 7_967_000 picoseconds. + Weight::from_parts(8_222_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -407,8 +403,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_028_000 picoseconds. - Weight::from_parts(7_366_000, 0) + // Minimum execution time: 8_006_000 picoseconds. + Weight::from_parts(8_440_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::Invulnerables` (r:0 w:1) @@ -418,10 +414,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_741_000 picoseconds. - Weight::from_parts(3_212_598, 0) - // Standard Error: 68 - .saturating_add(Weight::from_parts(11_695, 0).saturating_mul(v.into())) + // Minimum execution time: 2_524_000 picoseconds. + Weight::from_parts(3_123_608, 0) + // Standard Error: 59 + .saturating_add(Weight::from_parts(11_596, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::Ledger` (r:5900 w:11800) @@ -435,10 +431,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1356 + i * (151 ±0)` // Estimated: `990 + i * (3566 ±0)` - // Minimum execution time: 2_132_000 picoseconds. - Weight::from_parts(2_289_000, 990) - // Standard Error: 34_227 - .saturating_add(Weight::from_parts(17_006_583, 0).saturating_mul(i.into())) + // Minimum execution time: 2_092_000 picoseconds. + Weight::from_parts(2_258_000, 990) + // Standard Error: 32_695 + .saturating_add(Weight::from_parts(16_669_219, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(i.into()))) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 3566).saturating_mul(i.into())) @@ -476,10 +472,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2196 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 85_308_000 picoseconds. - Weight::from_parts(93_689_468, 6248) - // Standard Error: 5_425 - .saturating_add(Weight::from_parts(1_307_604, 0).saturating_mul(s.into())) + // Minimum execution time: 84_275_000 picoseconds. + Weight::from_parts(92_512_416, 6248) + // Standard Error: 3_633 + .saturating_add(Weight::from_parts(1_315_923, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(13_u64)) .saturating_add(T::DbWeight::get().writes(12_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) @@ -492,10 +488,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `66672` // Estimated: `70137` - // Minimum execution time: 103_242_000 picoseconds. - Weight::from_parts(1_162_296_080, 70137) - // Standard Error: 76_741 - .saturating_add(Weight::from_parts(6_487_522, 0).saturating_mul(s.into())) + // Minimum execution time: 101_707_000 picoseconds. + Weight::from_parts(912_819_462, 70137) + // Standard Error: 57_547 + .saturating_add(Weight::from_parts(4_856_799, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -532,10 +528,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `33297 + n * (377 ±0)` // Estimated: `30944 + n * (3774 ±0)` - // Minimum execution time: 140_740_000 picoseconds. - Weight::from_parts(182_886_963, 30944) - // Standard Error: 39_852 - .saturating_add(Weight::from_parts(43_140_752, 0).saturating_mul(n.into())) + // Minimum execution time: 138_657_000 picoseconds. + Weight::from_parts(167_173_445, 30944) + // Standard Error: 25_130 + .saturating_add(Weight::from_parts(44_566_012, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(14_u64)) .saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) @@ -559,10 +555,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1991 + l * (7 ±0)` // Estimated: `8877` - // Minimum execution time: 80_372_000 picoseconds. - Weight::from_parts(83_335_027, 8877) - // Standard Error: 4_780 - .saturating_add(Weight::from_parts(72_180, 0).saturating_mul(l.into())) + // Minimum execution time: 80_061_000 picoseconds. + Weight::from_parts(82_836_434, 8877) + // Standard Error: 4_348 + .saturating_add(Weight::from_parts(75_744, 0).saturating_mul(l.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } @@ -597,10 +593,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2196 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 93_920_000 picoseconds. - Weight::from_parts(98_022_911, 6248) - // Standard Error: 4_096 - .saturating_add(Weight::from_parts(1_287_745, 0).saturating_mul(s.into())) + // Minimum execution time: 92_560_000 picoseconds. + Weight::from_parts(97_684_741, 6248) + // Standard Error: 3_361 + .saturating_add(Weight::from_parts(1_292_732, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(11_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) @@ -646,12 +642,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0 + n * (720 ±0) + v * (3598 ±0)` // Estimated: `512390 + n * (3566 ±0) + v * (3566 ±0)` - // Minimum execution time: 556_012_000 picoseconds. - Weight::from_parts(560_339_000, 512390) - // Standard Error: 2_115_076 - .saturating_add(Weight::from_parts(69_456_497, 0).saturating_mul(v.into())) - // Standard Error: 210_755 - .saturating_add(Weight::from_parts(17_974_873, 0).saturating_mul(n.into())) + // Minimum execution time: 564_963_000 picoseconds. + Weight::from_parts(569_206_000, 512390) + // Standard Error: 2_033_235 + .saturating_add(Weight::from_parts(68_025_841, 0).saturating_mul(v.into())) + // Standard Error: 202_600 + .saturating_add(Weight::from_parts(17_916_770, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(206_u64)) .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into()))) .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) @@ -682,12 +678,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `3175 + n * (911 ±0) + v * (395 ±0)` // Estimated: `512390 + n * (3566 ±0) + v * (3566 ±0)` - // Minimum execution time: 32_792_819_000 picoseconds. - Weight::from_parts(32_986_606_000, 512390) - // Standard Error: 360_905 - .saturating_add(Weight::from_parts(5_260_151, 0).saturating_mul(v.into())) - // Standard Error: 360_905 - .saturating_add(Weight::from_parts(3_599_219, 0).saturating_mul(n.into())) + // Minimum execution time: 32_196_540_000 picoseconds. + Weight::from_parts(32_341_871_000, 512390) + // Standard Error: 354_657 + .saturating_add(Weight::from_parts(5_143_440, 0).saturating_mul(v.into())) + // Standard Error: 354_657 + .saturating_add(Weight::from_parts(3_328_189, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(201_u64)) .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into()))) .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) @@ -704,10 +700,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `979 + v * (50 ±0)` // Estimated: `3510 + v * (2520 ±0)` - // Minimum execution time: 2_434_755_000 picoseconds. - Weight::from_parts(38_574_764, 3510) - // Standard Error: 14_467 - .saturating_add(Weight::from_parts(4_821_702, 0).saturating_mul(v.into())) + // Minimum execution time: 2_381_903_000 picoseconds. + Weight::from_parts(32_693_059, 3510) + // Standard Error: 10_000 + .saturating_add(Weight::from_parts(4_736_173, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into()))) .saturating_add(Weight::from_parts(0, 2520).saturating_mul(v.into())) @@ -718,8 +714,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::MinValidatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxValidatorsCount` (r:0 w:1) /// Proof: `Staking::MaxValidatorsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::MaxStakedRewards` (r:0 w:1) - /// Proof: `Staking::MaxStakedRewards` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) /// Storage: `Staking::ChillThreshold` (r:0 w:1) /// Proof: `Staking::ChillThreshold` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxNominatorsCount` (r:0 w:1) @@ -730,9 +724,9 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_765_000 picoseconds. - Weight::from_parts(6_140_000, 0) - .saturating_add(T::DbWeight::get().writes(7_u64)) + // Minimum execution time: 5_434_000 picoseconds. + Weight::from_parts(5_742_000, 0) + .saturating_add(T::DbWeight::get().writes(6_u64)) } /// Storage: `Staking::MinCommission` (r:0 w:1) /// Proof: `Staking::MinCommission` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -740,8 +734,6 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::MinValidatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxValidatorsCount` (r:0 w:1) /// Proof: `Staking::MaxValidatorsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::MaxStakedRewards` (r:0 w:1) - /// Proof: `Staking::MaxStakedRewards` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) /// Storage: `Staking::ChillThreshold` (r:0 w:1) /// Proof: `Staking::ChillThreshold` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxNominatorsCount` (r:0 w:1) @@ -752,9 +744,9 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_025_000 picoseconds. - Weight::from_parts(5_354_000, 0) - .saturating_add(T::DbWeight::get().writes(7_u64)) + // Minimum execution time: 4_588_000 picoseconds. + Weight::from_parts(4_854_000, 0) + .saturating_add(T::DbWeight::get().writes(6_u64)) } /// Storage: `Staking::Bonded` (r:1 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) @@ -782,8 +774,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1939` // Estimated: `6248` - // Minimum execution time: 69_656_000 picoseconds. - Weight::from_parts(71_574_000, 6248) + // Minimum execution time: 68_780_000 picoseconds. + Weight::from_parts(71_479_000, 6248) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -795,8 +787,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `691` // Estimated: `3510` - // Minimum execution time: 12_523_000 picoseconds. - Weight::from_parts(13_315_000, 3510) + // Minimum execution time: 12_268_000 picoseconds. + Weight::from_parts(12_661_000, 3510) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -806,8 +798,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_125_000 picoseconds. - Weight::from_parts(3_300_000, 0) + // Minimum execution time: 3_071_000 picoseconds. + Weight::from_parts(3_334_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } } @@ -828,8 +820,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `927` // Estimated: `4764` - // Minimum execution time: 41_318_000 picoseconds. - Weight::from_parts(43_268_000, 4764) + // Minimum execution time: 42_042_000 picoseconds. + Weight::from_parts(43_292_000, 4764) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -849,8 +841,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1990` // Estimated: `8877` - // Minimum execution time: 85_666_000 picoseconds. - Weight::from_parts(88_749_000, 8877) + // Minimum execution time: 85_050_000 picoseconds. + Weight::from_parts(87_567_000, 8877) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } @@ -876,8 +868,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2195` // Estimated: `8877` - // Minimum execution time: 90_282_000 picoseconds. - Weight::from_parts(92_332_000, 8877) + // Minimum execution time: 89_076_000 picoseconds. + Weight::from_parts(92_715_000, 8877) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } @@ -891,18 +883,16 @@ impl WeightInfo for () { /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:0) - /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_update(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1297` + // Measured: `1115` // Estimated: `4764` - // Minimum execution time: 44_626_000 picoseconds. - Weight::from_parts(47_254_657, 4764) - // Standard Error: 1_179 - .saturating_add(Weight::from_parts(57_657, 0).saturating_mul(s.into())) - .saturating_add(RocksDbWeight::get().reads(6_u64)) + // Minimum execution time: 42_067_000 picoseconds. + Weight::from_parts(43_239_807, 4764) + // Standard Error: 831 + .saturating_add(Weight::from_parts(46_257, 0).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Staking::Ledger` (r:1 w:1) @@ -938,10 +928,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2196 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 86_769_000 picoseconds. - Weight::from_parts(95_212_867, 6248) - // Standard Error: 3_706 - .saturating_add(Weight::from_parts(1_320_752, 0).saturating_mul(s.into())) + // Minimum execution time: 86_490_000 picoseconds. + Weight::from_parts(95_358_751, 6248) + // Standard Error: 3_952 + .saturating_add(Weight::from_parts(1_294_907, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(13_u64)) .saturating_add(RocksDbWeight::get().writes(11_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) @@ -973,8 +963,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1372` // Estimated: `4556` - // Minimum execution time: 50_410_000 picoseconds. - Weight::from_parts(52_576_000, 4556) + // Minimum execution time: 50_326_000 picoseconds. + Weight::from_parts(52_253_000, 4556) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } @@ -987,10 +977,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1280 + k * (569 ±0)` // Estimated: `4556 + k * (3033 ±0)` - // Minimum execution time: 29_017_000 picoseconds. - Weight::from_parts(33_019_206, 4556) - // Standard Error: 6_368 - .saturating_add(Weight::from_parts(6_158_681, 0).saturating_mul(k.into())) + // Minimum execution time: 29_305_000 picoseconds. + Weight::from_parts(32_199_604, 4556) + // Standard Error: 7_150 + .saturating_add(Weight::from_parts(6_437_124, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(k.into()))) @@ -1023,10 +1013,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1866 + n * (102 ±0)` // Estimated: `6248 + n * (2520 ±0)` - // Minimum execution time: 63_452_000 picoseconds. - Weight::from_parts(60_924_066, 6248) - // Standard Error: 14_416 - .saturating_add(Weight::from_parts(3_921_589, 0).saturating_mul(n.into())) + // Minimum execution time: 63_267_000 picoseconds. + Weight::from_parts(61_741_404, 6248) + // Standard Error: 12_955 + .saturating_add(Weight::from_parts(3_811_743, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes(6_u64)) @@ -1050,8 +1040,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1650` // Estimated: `6248` - // Minimum execution time: 54_253_000 picoseconds. - Weight::from_parts(55_286_000, 6248) + // Minimum execution time: 52_862_000 picoseconds. + Weight::from_parts(54_108_000, 6248) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -1065,8 +1055,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `902` // Estimated: `4556` - // Minimum execution time: 16_812_000 picoseconds. - Weight::from_parts(17_380_000, 4556) + // Minimum execution time: 16_350_000 picoseconds. + Weight::from_parts(16_802_000, 4556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1080,8 +1070,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `969` // Estimated: `4556` - // Minimum execution time: 20_590_000 picoseconds. - Weight::from_parts(21_096_000, 4556) + // Minimum execution time: 19_981_000 picoseconds. + Weight::from_parts(20_539_000, 4556) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1093,8 +1083,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `902` // Estimated: `4556` - // Minimum execution time: 19_923_000 picoseconds. - Weight::from_parts(20_880_000, 4556) + // Minimum execution time: 19_304_000 picoseconds. + Weight::from_parts(20_000_000, 4556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -1104,8 +1094,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_599_000 picoseconds. - Weight::from_parts(2_751_000, 0) + // Minimum execution time: 2_568_000 picoseconds. + Weight::from_parts(2_708_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -1114,8 +1104,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_941_000 picoseconds. - Weight::from_parts(7_288_000, 0) + // Minimum execution time: 7_950_000 picoseconds. + Weight::from_parts(8_348_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -1124,8 +1114,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_757_000 picoseconds. - Weight::from_parts(7_200_000, 0) + // Minimum execution time: 7_967_000 picoseconds. + Weight::from_parts(8_222_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -1134,8 +1124,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_028_000 picoseconds. - Weight::from_parts(7_366_000, 0) + // Minimum execution time: 8_006_000 picoseconds. + Weight::from_parts(8_440_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::Invulnerables` (r:0 w:1) @@ -1145,10 +1135,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_741_000 picoseconds. - Weight::from_parts(3_212_598, 0) - // Standard Error: 68 - .saturating_add(Weight::from_parts(11_695, 0).saturating_mul(v.into())) + // Minimum execution time: 2_524_000 picoseconds. + Weight::from_parts(3_123_608, 0) + // Standard Error: 59 + .saturating_add(Weight::from_parts(11_596, 0).saturating_mul(v.into())) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::Ledger` (r:5900 w:11800) @@ -1162,10 +1152,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1356 + i * (151 ±0)` // Estimated: `990 + i * (3566 ±0)` - // Minimum execution time: 2_132_000 picoseconds. - Weight::from_parts(2_289_000, 990) - // Standard Error: 34_227 - .saturating_add(Weight::from_parts(17_006_583, 0).saturating_mul(i.into())) + // Minimum execution time: 2_092_000 picoseconds. + Weight::from_parts(2_258_000, 990) + // Standard Error: 32_695 + .saturating_add(Weight::from_parts(16_669_219, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(i.into()))) .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 3566).saturating_mul(i.into())) @@ -1203,10 +1193,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2196 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 85_308_000 picoseconds. - Weight::from_parts(93_689_468, 6248) - // Standard Error: 5_425 - .saturating_add(Weight::from_parts(1_307_604, 0).saturating_mul(s.into())) + // Minimum execution time: 84_275_000 picoseconds. + Weight::from_parts(92_512_416, 6248) + // Standard Error: 3_633 + .saturating_add(Weight::from_parts(1_315_923, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(13_u64)) .saturating_add(RocksDbWeight::get().writes(12_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) @@ -1219,10 +1209,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `66672` // Estimated: `70137` - // Minimum execution time: 103_242_000 picoseconds. - Weight::from_parts(1_162_296_080, 70137) - // Standard Error: 76_741 - .saturating_add(Weight::from_parts(6_487_522, 0).saturating_mul(s.into())) + // Minimum execution time: 101_707_000 picoseconds. + Weight::from_parts(912_819_462, 70137) + // Standard Error: 57_547 + .saturating_add(Weight::from_parts(4_856_799, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1259,10 +1249,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `33297 + n * (377 ±0)` // Estimated: `30944 + n * (3774 ±0)` - // Minimum execution time: 140_740_000 picoseconds. - Weight::from_parts(182_886_963, 30944) - // Standard Error: 39_852 - .saturating_add(Weight::from_parts(43_140_752, 0).saturating_mul(n.into())) + // Minimum execution time: 138_657_000 picoseconds. + Weight::from_parts(167_173_445, 30944) + // Standard Error: 25_130 + .saturating_add(Weight::from_parts(44_566_012, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(14_u64)) .saturating_add(RocksDbWeight::get().reads((6_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) @@ -1286,10 +1276,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1991 + l * (7 ±0)` // Estimated: `8877` - // Minimum execution time: 80_372_000 picoseconds. - Weight::from_parts(83_335_027, 8877) - // Standard Error: 4_780 - .saturating_add(Weight::from_parts(72_180, 0).saturating_mul(l.into())) + // Minimum execution time: 80_061_000 picoseconds. + Weight::from_parts(82_836_434, 8877) + // Standard Error: 4_348 + .saturating_add(Weight::from_parts(75_744, 0).saturating_mul(l.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } @@ -1324,10 +1314,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2196 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 93_920_000 picoseconds. - Weight::from_parts(98_022_911, 6248) - // Standard Error: 4_096 - .saturating_add(Weight::from_parts(1_287_745, 0).saturating_mul(s.into())) + // Minimum execution time: 92_560_000 picoseconds. + Weight::from_parts(97_684_741, 6248) + // Standard Error: 3_361 + .saturating_add(Weight::from_parts(1_292_732, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(11_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) @@ -1373,12 +1363,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0 + n * (720 ±0) + v * (3598 ±0)` // Estimated: `512390 + n * (3566 ±0) + v * (3566 ±0)` - // Minimum execution time: 556_012_000 picoseconds. - Weight::from_parts(560_339_000, 512390) - // Standard Error: 2_115_076 - .saturating_add(Weight::from_parts(69_456_497, 0).saturating_mul(v.into())) - // Standard Error: 210_755 - .saturating_add(Weight::from_parts(17_974_873, 0).saturating_mul(n.into())) + // Minimum execution time: 564_963_000 picoseconds. + Weight::from_parts(569_206_000, 512390) + // Standard Error: 2_033_235 + .saturating_add(Weight::from_parts(68_025_841, 0).saturating_mul(v.into())) + // Standard Error: 202_600 + .saturating_add(Weight::from_parts(17_916_770, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(206_u64)) .saturating_add(RocksDbWeight::get().reads((5_u64).saturating_mul(v.into()))) .saturating_add(RocksDbWeight::get().reads((4_u64).saturating_mul(n.into()))) @@ -1409,12 +1399,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `3175 + n * (911 ±0) + v * (395 ±0)` // Estimated: `512390 + n * (3566 ±0) + v * (3566 ±0)` - // Minimum execution time: 32_792_819_000 picoseconds. - Weight::from_parts(32_986_606_000, 512390) - // Standard Error: 360_905 - .saturating_add(Weight::from_parts(5_260_151, 0).saturating_mul(v.into())) - // Standard Error: 360_905 - .saturating_add(Weight::from_parts(3_599_219, 0).saturating_mul(n.into())) + // Minimum execution time: 32_196_540_000 picoseconds. + Weight::from_parts(32_341_871_000, 512390) + // Standard Error: 354_657 + .saturating_add(Weight::from_parts(5_143_440, 0).saturating_mul(v.into())) + // Standard Error: 354_657 + .saturating_add(Weight::from_parts(3_328_189, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(201_u64)) .saturating_add(RocksDbWeight::get().reads((5_u64).saturating_mul(v.into()))) .saturating_add(RocksDbWeight::get().reads((4_u64).saturating_mul(n.into()))) @@ -1431,10 +1421,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `979 + v * (50 ±0)` // Estimated: `3510 + v * (2520 ±0)` - // Minimum execution time: 2_434_755_000 picoseconds. - Weight::from_parts(38_574_764, 3510) - // Standard Error: 14_467 - .saturating_add(Weight::from_parts(4_821_702, 0).saturating_mul(v.into())) + // Minimum execution time: 2_381_903_000 picoseconds. + Weight::from_parts(32_693_059, 3510) + // Standard Error: 10_000 + .saturating_add(Weight::from_parts(4_736_173, 0).saturating_mul(v.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(v.into()))) .saturating_add(Weight::from_parts(0, 2520).saturating_mul(v.into())) @@ -1445,8 +1435,6 @@ impl WeightInfo for () { /// Proof: `Staking::MinValidatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxValidatorsCount` (r:0 w:1) /// Proof: `Staking::MaxValidatorsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::MaxStakedRewards` (r:0 w:1) - /// Proof: `Staking::MaxStakedRewards` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) /// Storage: `Staking::ChillThreshold` (r:0 w:1) /// Proof: `Staking::ChillThreshold` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxNominatorsCount` (r:0 w:1) @@ -1457,9 +1445,9 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_765_000 picoseconds. - Weight::from_parts(6_140_000, 0) - .saturating_add(RocksDbWeight::get().writes(7_u64)) + // Minimum execution time: 5_434_000 picoseconds. + Weight::from_parts(5_742_000, 0) + .saturating_add(RocksDbWeight::get().writes(6_u64)) } /// Storage: `Staking::MinCommission` (r:0 w:1) /// Proof: `Staking::MinCommission` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -1467,8 +1455,6 @@ impl WeightInfo for () { /// Proof: `Staking::MinValidatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxValidatorsCount` (r:0 w:1) /// Proof: `Staking::MaxValidatorsCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::MaxStakedRewards` (r:0 w:1) - /// Proof: `Staking::MaxStakedRewards` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) /// Storage: `Staking::ChillThreshold` (r:0 w:1) /// Proof: `Staking::ChillThreshold` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) /// Storage: `Staking::MaxNominatorsCount` (r:0 w:1) @@ -1479,9 +1465,9 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_025_000 picoseconds. - Weight::from_parts(5_354_000, 0) - .saturating_add(RocksDbWeight::get().writes(7_u64)) + // Minimum execution time: 4_588_000 picoseconds. + Weight::from_parts(4_854_000, 0) + .saturating_add(RocksDbWeight::get().writes(6_u64)) } /// Storage: `Staking::Bonded` (r:1 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) @@ -1509,8 +1495,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1939` // Estimated: `6248` - // Minimum execution time: 69_656_000 picoseconds. - Weight::from_parts(71_574_000, 6248) + // Minimum execution time: 68_780_000 picoseconds. + Weight::from_parts(71_479_000, 6248) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -1522,8 +1508,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `691` // Estimated: `3510` - // Minimum execution time: 12_523_000 picoseconds. - Weight::from_parts(13_315_000, 3510) + // Minimum execution time: 12_268_000 picoseconds. + Weight::from_parts(12_661_000, 3510) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1533,8 +1519,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_125_000 picoseconds. - Weight::from_parts(3_300_000, 0) + // Minimum execution time: 3_071_000 picoseconds. + Weight::from_parts(3_334_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } } diff --git a/substrate/frame/state-trie-migration/src/lib.rs b/substrate/frame/state-trie-migration/src/lib.rs index b89159ef3ec..6b3aa9934e0 100644 --- a/substrate/frame/state-trie-migration/src/lib.rs +++ b/substrate/frame/state-trie-migration/src/lib.rs @@ -1801,7 +1801,7 @@ mod remote_tests_local { use std::env::var as env_var; // we only use the hash type from this, so using the mock should be fine. - type Extrinsic = sp_runtime::generic::UncheckedExtrinsic; + type Extrinsic = sp_runtime::testing::TestXt; type Block = sp_runtime::testing::Block; #[tokio::test] diff --git a/substrate/frame/state-trie-migration/src/weights.rs b/substrate/frame/state-trie-migration/src/weights.rs index 23dad9e3380..8fa80b38957 100644 --- a/substrate/frame/state-trie-migration/src/weights.rs +++ b/substrate/frame/state-trie-migration/src/weights.rs @@ -17,28 +17,26 @@ //! Autogenerated weights for `pallet_state_trie_migration` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2024-01-24, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-grjcggob-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate-node +// target/production/substrate-node // benchmark // pallet -// --chain=dev // --steps=50 // --repeat=20 -// --pallet=pallet_state_trie_migration -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/state-trie-migration/src/weights.rs +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_state_trie_migration +// --chain=dev // --header=./substrate/HEADER-APACHE2 +// --output=./substrate/frame/state-trie-migration/src/weights.rs // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -66,15 +64,15 @@ impl WeightInfo for SubstrateWeight { /// Storage: `StateTrieMigration::SignedMigrationMaxLimits` (r:1 w:0) /// Proof: `StateTrieMigration::SignedMigrationMaxLimits` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) /// Storage: `StateTrieMigration::MigrationProcess` (r:1 w:1) /// Proof: `StateTrieMigration::MigrationProcess` (`max_values`: Some(1), `max_size`: Some(1042), added: 1537, mode: `MaxEncodedLen`) fn continue_migrate() -> Weight { // Proof Size summary in bytes: // Measured: `108` - // Estimated: `3658` - // Minimum execution time: 17_661_000 picoseconds. - Weight::from_parts(18_077_000, 3658) + // Estimated: `3640` + // Minimum execution time: 18_520_000 picoseconds. + Weight::from_parts(19_171_000, 3640) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -84,53 +82,53 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `1493` - // Minimum execution time: 4_036_000 picoseconds. - Weight::from_parts(4_267_000, 1493) + // Minimum execution time: 3_786_000 picoseconds. + Weight::from_parts(4_038_000, 1493) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) fn migrate_custom_top_success() -> Weight { // Proof Size summary in bytes: // Measured: `0` - // Estimated: `3658` - // Minimum execution time: 11_348_000 picoseconds. - Weight::from_parts(11_899_000, 3658) + // Estimated: `3640` + // Minimum execution time: 11_144_000 picoseconds. + Weight::from_parts(11_556_000, 3640) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) /// Storage: UNKNOWN KEY `0x666f6f` (r:1 w:1) /// Proof: UNKNOWN KEY `0x666f6f` (r:1 w:1) fn migrate_custom_top_fail() -> Weight { // Proof Size summary in bytes: // Measured: `113` - // Estimated: `3658` - // Minimum execution time: 59_819_000 picoseconds. - Weight::from_parts(61_066_000, 3658) + // Estimated: `3640` + // Minimum execution time: 59_288_000 picoseconds. + Weight::from_parts(60_276_000, 3640) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) fn migrate_custom_child_success() -> Weight { // Proof Size summary in bytes: // Measured: `0` - // Estimated: `3658` - // Minimum execution time: 11_424_000 picoseconds. - Weight::from_parts(11_765_000, 3658) + // Estimated: `3640` + // Minimum execution time: 11_258_000 picoseconds. + Weight::from_parts(11_626_000, 3640) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) /// Storage: UNKNOWN KEY `0x666f6f` (r:1 w:1) /// Proof: UNKNOWN KEY `0x666f6f` (r:1 w:1) fn migrate_custom_child_fail() -> Weight { // Proof Size summary in bytes: // Measured: `106` - // Estimated: `3658` - // Minimum execution time: 61_086_000 picoseconds. - Weight::from_parts(62_546_000, 3658) + // Estimated: `3640` + // Minimum execution time: 61_575_000 picoseconds. + Weight::from_parts(63_454_000, 3640) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -141,10 +139,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `197 + v * (1 ±0)` // Estimated: `3662 + v * (1 ±0)` - // Minimum execution time: 5_375_000 picoseconds. - Weight::from_parts(5_552_000, 3662) + // Minimum execution time: 5_259_000 picoseconds. + Weight::from_parts(5_433_000, 3662) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_146, 0).saturating_mul(v.into())) + .saturating_add(Weight::from_parts(1_159, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(v.into())) @@ -156,15 +154,15 @@ impl WeightInfo for () { /// Storage: `StateTrieMigration::SignedMigrationMaxLimits` (r:1 w:0) /// Proof: `StateTrieMigration::SignedMigrationMaxLimits` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) /// Storage: `StateTrieMigration::MigrationProcess` (r:1 w:1) /// Proof: `StateTrieMigration::MigrationProcess` (`max_values`: Some(1), `max_size`: Some(1042), added: 1537, mode: `MaxEncodedLen`) fn continue_migrate() -> Weight { // Proof Size summary in bytes: // Measured: `108` - // Estimated: `3658` - // Minimum execution time: 17_661_000 picoseconds. - Weight::from_parts(18_077_000, 3658) + // Estimated: `3640` + // Minimum execution time: 18_520_000 picoseconds. + Weight::from_parts(19_171_000, 3640) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -174,53 +172,53 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `76` // Estimated: `1493` - // Minimum execution time: 4_036_000 picoseconds. - Weight::from_parts(4_267_000, 1493) + // Minimum execution time: 3_786_000 picoseconds. + Weight::from_parts(4_038_000, 1493) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) fn migrate_custom_top_success() -> Weight { // Proof Size summary in bytes: // Measured: `0` - // Estimated: `3658` - // Minimum execution time: 11_348_000 picoseconds. - Weight::from_parts(11_899_000, 3658) + // Estimated: `3640` + // Minimum execution time: 11_144_000 picoseconds. + Weight::from_parts(11_556_000, 3640) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) /// Storage: UNKNOWN KEY `0x666f6f` (r:1 w:1) /// Proof: UNKNOWN KEY `0x666f6f` (r:1 w:1) fn migrate_custom_top_fail() -> Weight { // Proof Size summary in bytes: // Measured: `113` - // Estimated: `3658` - // Minimum execution time: 59_819_000 picoseconds. - Weight::from_parts(61_066_000, 3658) + // Estimated: `3640` + // Minimum execution time: 59_288_000 picoseconds. + Weight::from_parts(60_276_000, 3640) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) fn migrate_custom_child_success() -> Weight { // Proof Size summary in bytes: // Measured: `0` - // Estimated: `3658` - // Minimum execution time: 11_424_000 picoseconds. - Weight::from_parts(11_765_000, 3658) + // Estimated: `3640` + // Minimum execution time: 11_258_000 picoseconds. + Weight::from_parts(11_626_000, 3640) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(175), added: 2650, mode: `MaxEncodedLen`) /// Storage: UNKNOWN KEY `0x666f6f` (r:1 w:1) /// Proof: UNKNOWN KEY `0x666f6f` (r:1 w:1) fn migrate_custom_child_fail() -> Weight { // Proof Size summary in bytes: // Measured: `106` - // Estimated: `3658` - // Minimum execution time: 61_086_000 picoseconds. - Weight::from_parts(62_546_000, 3658) + // Estimated: `3640` + // Minimum execution time: 61_575_000 picoseconds. + Weight::from_parts(63_454_000, 3640) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -231,10 +229,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `197 + v * (1 ±0)` // Estimated: `3662 + v * (1 ±0)` - // Minimum execution time: 5_375_000 picoseconds. - Weight::from_parts(5_552_000, 3662) + // Minimum execution time: 5_259_000 picoseconds. + Weight::from_parts(5_433_000, 3662) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_146, 0).saturating_mul(v.into())) + .saturating_add(Weight::from_parts(1_159, 0).saturating_mul(v.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(v.into())) diff --git a/substrate/frame/sudo/src/benchmarking.rs b/substrate/frame/sudo/src/benchmarking.rs index cdd7d707600..e64233fe748 100644 --- a/substrate/frame/sudo/src/benchmarking.rs +++ b/substrate/frame/sudo/src/benchmarking.rs @@ -20,23 +20,14 @@ use super::*; use crate::Pallet; use frame_benchmarking::v2::*; -use frame_support::dispatch::DispatchInfo; use frame_system::RawOrigin; -use sp_runtime::traits::{AsSystemOriginSigner, DispatchTransaction, Dispatchable}; fn assert_last_event(generic_event: crate::Event) { let re: ::RuntimeEvent = generic_event.into(); frame_system::Pallet::::assert_last_event(re.into()); } -#[benchmarks(where - T: Send + Sync, - ::RuntimeCall: From>, - ::RuntimeCall: Dispatchable, - <::RuntimeCall as Dispatchable>::PostInfo: From<()>, - <::RuntimeCall as Dispatchable>::RuntimeOrigin: - AsSystemOriginSigner + Clone, -)] +#[benchmarks(where ::RuntimeCall: From>)] mod benchmarks { use super::*; @@ -94,23 +85,5 @@ mod benchmarks { assert_last_event::(Event::KeyRemoved {}); } - #[benchmark] - fn check_only_sudo_account() { - let caller: T::AccountId = whitelisted_caller(); - Key::::put(&caller); - - let call = frame_system::Call::remark { remark: vec![] }.into(); - let info = DispatchInfo { ..Default::default() }; - let ext = CheckOnlySudoAccount::::new(); - - #[block] - { - assert!(ext - .test_run(RawOrigin::Signed(caller).into(), &call, &info, 0, |_| Ok(().into())) - .unwrap() - .is_ok()); - } - } - impl_benchmark_test_suite!(Pallet, crate::mock::new_bench_ext(), crate::mock::Test); } diff --git a/substrate/frame/sudo/src/extension.rs b/substrate/frame/sudo/src/extension.rs index 2cd8f945edd..e90286e5a7c 100644 --- a/substrate/frame/sudo/src/extension.rs +++ b/substrate/frame/sudo/src/extension.rs @@ -20,14 +20,10 @@ use codec::{Decode, Encode}; use frame_support::{dispatch::DispatchInfo, ensure}; use scale_info::TypeInfo; use sp_runtime::{ - impl_tx_ext_default, - traits::{ - AsSystemOriginSigner, DispatchInfoOf, Dispatchable, TransactionExtension, - TransactionExtensionBase, - }, + traits::{DispatchInfoOf, Dispatchable, SignedExtension}, transaction_validity::{ - InvalidTransaction, TransactionPriority, TransactionValidityError, UnknownTransaction, - ValidTransaction, + InvalidTransaction, TransactionPriority, TransactionValidity, TransactionValidityError, + UnknownTransaction, ValidTransaction, }, }; use sp_std::{fmt, marker::PhantomData}; @@ -63,61 +59,49 @@ impl fmt::Debug for CheckOnlySudoAccount { } impl CheckOnlySudoAccount { - /// Creates new `TransactionExtension` to check sudo key. + /// Creates new `SignedExtension` to check sudo key. pub fn new() -> Self { Self::default() } } -impl TransactionExtensionBase for CheckOnlySudoAccount { - const IDENTIFIER: &'static str = "CheckOnlySudoAccount"; - type Implicit = (); - - fn weight(&self) -> frame_support::weights::Weight { - use crate::weights::WeightInfo; - T::WeightInfo::check_only_sudo_account() - } -} -impl - TransactionExtension<::RuntimeCall, Context> for CheckOnlySudoAccount +impl SignedExtension for CheckOnlySudoAccount where - ::RuntimeCall: Dispatchable, - <::RuntimeCall as Dispatchable>::RuntimeOrigin: - AsSystemOriginSigner + Clone, + ::RuntimeCall: Dispatchable, { + const IDENTIFIER: &'static str = "CheckOnlySudoAccount"; + type AccountId = T::AccountId; + type Call = ::RuntimeCall; + type AdditionalSigned = (); type Pre = (); - type Val = (); + + fn additional_signed(&self) -> Result { + Ok(()) + } fn validate( &self, - origin: <::RuntimeCall as Dispatchable>::RuntimeOrigin, - _call: &::RuntimeCall, - info: &DispatchInfoOf<::RuntimeCall>, + who: &Self::AccountId, + _call: &Self::Call, + info: &DispatchInfoOf, _len: usize, - _context: &mut Context, - _self_implicit: Self::Implicit, - _inherited_implication: &impl Encode, - ) -> Result< - ( - ValidTransaction, - Self::Val, - <::RuntimeCall as Dispatchable>::RuntimeOrigin, - ), - TransactionValidityError, - > { - let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?; + ) -> TransactionValidity { let sudo_key: T::AccountId = Key::::get().ok_or(UnknownTransaction::CannotLookup)?; ensure!(*who == sudo_key, InvalidTransaction::BadSigner); - Ok(( - ValidTransaction { - priority: info.weight.ref_time() as TransactionPriority, - ..Default::default() - }, - (), - origin, - )) + Ok(ValidTransaction { + priority: info.weight.ref_time() as TransactionPriority, + ..Default::default() + }) } - impl_tx_ext_default!(::RuntimeCall; Context; prepare); + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + self.validate(who, call, info, len).map(|_| ()) + } } diff --git a/substrate/frame/sudo/src/lib.rs b/substrate/frame/sudo/src/lib.rs index 2c953368b22..2ebe4cb0157 100644 --- a/substrate/frame/sudo/src/lib.rs +++ b/substrate/frame/sudo/src/lib.rs @@ -85,8 +85,8 @@ //! meant to be used by constructing runtime calls from outside the runtime. //! //! -//! This pallet also defines a [`TransactionExtension`](sp_runtime::traits::TransactionExtension) -//! called [`CheckOnlySudoAccount`] to ensure that only signed transactions by the sudo account are +//! This pallet also defines a [`SignedExtension`](sp_runtime::traits::SignedExtension) called +//! [`CheckOnlySudoAccount`] to ensure that only signed transactions by the sudo account are //! accepted by the transaction pool. The intended use of this signed extension is to prevent other //! accounts from spamming the transaction pool for the initial phase of a chain, during which //! developers may only want a sudo account to be able to make transactions. diff --git a/substrate/frame/sudo/src/weights.rs b/substrate/frame/sudo/src/weights.rs index aa8f69fd4e6..10d1a9f7a51 100644 --- a/substrate/frame/sudo/src/weights.rs +++ b/substrate/frame/sudo/src/weights.rs @@ -17,28 +17,26 @@ //! Autogenerated weights for `pallet_sudo` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate-node +// target/production/substrate-node // benchmark // pallet -// --chain=dev // --steps=50 // --repeat=20 -// --pallet=pallet_sudo -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/sudo/src/weights.rs +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_sudo +// --chain=dev // --header=./substrate/HEADER-APACHE2 +// --output=./substrate/frame/sudo/src/weights.rs // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -55,7 +53,6 @@ pub trait WeightInfo { fn sudo() -> Weight; fn sudo_as() -> Weight; fn remove_key() -> Weight; - fn check_only_sudo_account() -> Weight; } /// Weights for `pallet_sudo` using the Substrate node and recommended hardware. @@ -67,8 +64,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `165` // Estimated: `1517` - // Minimum execution time: 9_590_000 picoseconds. - Weight::from_parts(9_924_000, 1517) + // Minimum execution time: 9_600_000 picoseconds. + Weight::from_parts(10_076_000, 1517) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -78,8 +75,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `165` // Estimated: `1517` - // Minimum execution time: 9_825_000 picoseconds. - Weight::from_parts(10_373_000, 1517) + // Minimum execution time: 10_453_000 picoseconds. + Weight::from_parts(10_931_000, 1517) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Sudo::Key` (r:1 w:0) @@ -88,8 +85,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `165` // Estimated: `1517` - // Minimum execution time: 10_140_000 picoseconds. - Weight::from_parts(10_382_000, 1517) + // Minimum execution time: 10_202_000 picoseconds. + Weight::from_parts(10_800_000, 1517) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Sudo::Key` (r:1 w:1) @@ -98,21 +95,11 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `165` // Estimated: `1517` - // Minimum execution time: 8_610_000 picoseconds. - Weight::from_parts(8_975_000, 1517) + // Minimum execution time: 8_555_000 picoseconds. + Weight::from_parts(8_846_000, 1517) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Sudo::Key` (r:1 w:0) - /// Proof: `Sudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - fn check_only_sudo_account() -> Weight { - // Proof Size summary in bytes: - // Measured: `165` - // Estimated: `1517` - // Minimum execution time: 3_416_000 picoseconds. - Weight::from_parts(3_645_000, 1517) - .saturating_add(T::DbWeight::get().reads(1_u64)) - } } // For backwards compatibility and tests. @@ -123,8 +110,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `165` // Estimated: `1517` - // Minimum execution time: 9_590_000 picoseconds. - Weight::from_parts(9_924_000, 1517) + // Minimum execution time: 9_600_000 picoseconds. + Weight::from_parts(10_076_000, 1517) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -134,8 +121,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `165` // Estimated: `1517` - // Minimum execution time: 9_825_000 picoseconds. - Weight::from_parts(10_373_000, 1517) + // Minimum execution time: 10_453_000 picoseconds. + Weight::from_parts(10_931_000, 1517) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Sudo::Key` (r:1 w:0) @@ -144,8 +131,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `165` // Estimated: `1517` - // Minimum execution time: 10_140_000 picoseconds. - Weight::from_parts(10_382_000, 1517) + // Minimum execution time: 10_202_000 picoseconds. + Weight::from_parts(10_800_000, 1517) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Sudo::Key` (r:1 w:1) @@ -154,19 +141,9 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `165` // Estimated: `1517` - // Minimum execution time: 8_610_000 picoseconds. - Weight::from_parts(8_975_000, 1517) + // Minimum execution time: 8_555_000 picoseconds. + Weight::from_parts(8_846_000, 1517) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Sudo::Key` (r:1 w:0) - /// Proof: `Sudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - fn check_only_sudo_account() -> Weight { - // Proof Size summary in bytes: - // Measured: `165` - // Estimated: `1517` - // Minimum execution time: 3_416_000 picoseconds. - Weight::from_parts(3_645_000, 1517) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - } } diff --git a/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs b/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs index d21cfef4a92..da483fa6cf0 100644 --- a/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs +++ b/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs @@ -73,9 +73,11 @@ pub fn expand_outer_inherent( #( #pallet_attrs if let Some(inherent) = #pallet_names::create_inherent(self) { - let inherent = <#unchecked_extrinsic as #scrate::sp_runtime::traits::Extrinsic>::new_inherent( + let inherent = <#unchecked_extrinsic as #scrate::sp_runtime::traits::Extrinsic>::new( inherent.into(), - ); + None, + ).expect("Runtime UncheckedExtrinsic is not Opaque, so it has to return \ + `Some`; qed"); inherents.push(inherent); } @@ -121,7 +123,7 @@ pub fn expand_outer_inherent( for xt in block.extrinsics() { // Inherents are before any other extrinsics. // And signed extrinsics are not inherents. - if !(#scrate::sp_runtime::traits::Extrinsic::is_bare(xt)) { + if #scrate::sp_runtime::traits::Extrinsic::is_signed(xt).unwrap_or(false) { break } @@ -159,9 +161,10 @@ pub fn expand_outer_inherent( match #pallet_names::is_inherent_required(self) { Ok(Some(e)) => { let found = block.extrinsics().iter().any(|xt| { - let is_bare = #scrate::sp_runtime::traits::Extrinsic::is_bare(xt); + let is_signed = #scrate::sp_runtime::traits::Extrinsic::is_signed(xt) + .unwrap_or(false); - if is_bare { + if !is_signed { let call = < #unchecked_extrinsic as ExtrinsicCall >::call(xt); @@ -206,9 +209,8 @@ pub fn expand_outer_inherent( use #scrate::inherent::ProvideInherent; use #scrate::traits::{IsSubType, ExtrinsicCall}; - let is_bare = #scrate::sp_runtime::traits::Extrinsic::is_bare(ext); - if !is_bare { - // Signed extrinsics are not inherents. + if #scrate::sp_runtime::traits::Extrinsic::is_signed(ext).unwrap_or(false) { + // Signed extrinsics are never inherents. return false } diff --git a/substrate/frame/support/procedural/src/construct_runtime/expand/metadata.rs b/substrate/frame/support/procedural/src/construct_runtime/expand/metadata.rs index f55ca677d89..0e76f9a9246 100644 --- a/substrate/frame/support/procedural/src/construct_runtime/expand/metadata.rs +++ b/substrate/frame/support/procedural/src/construct_runtime/expand/metadata.rs @@ -119,13 +119,13 @@ pub fn expand_runtime_metadata( call_ty, signature_ty, extra_ty, - extensions: < + signed_extensions: < < #extrinsic as #scrate::sp_runtime::traits::ExtrinsicMetadata - >::Extra as #scrate::sp_runtime::traits::TransactionExtensionBase + >::SignedExtensions as #scrate::sp_runtime::traits::SignedExtension >::metadata() .into_iter() - .map(|meta| #scrate::__private::metadata_ir::TransactionExtensionMetadataIR { + .map(|meta| #scrate::__private::metadata_ir::SignedExtensionMetadataIR { identifier: meta.identifier, ty: meta.ty, additional_signed: meta.additional_signed, diff --git a/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs b/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs index 341621deb09..83049919d01 100644 --- a/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs +++ b/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs @@ -153,10 +153,6 @@ pub fn expand_outer_origin( self.filter = #scrate::__private::sp_std::rc::Rc::new(Box::new(filter)); } - fn set_caller(&mut self, caller: OriginCaller) { - self.caller = caller; - } - fn set_caller_from(&mut self, other: impl Into) { self.caller = other.into().caller; } @@ -305,16 +301,6 @@ pub fn expand_outer_origin( } } - impl #scrate::__private::AsSystemOriginSigner<<#runtime as #system_path::Config>::AccountId> for RuntimeOrigin { - fn as_system_origin_signer(&self) -> Option<&<#runtime as #system_path::Config>::AccountId> { - if let OriginCaller::system(#system_path::Origin::<#runtime>::Signed(ref signed)) = &self.caller { - Some(signed) - } else { - None - } - } - } - #pallet_conversions }) } diff --git a/substrate/frame/support/src/dispatch.rs b/substrate/frame/support/src/dispatch.rs index 61787a74012..4a313551aca 100644 --- a/substrate/frame/support/src/dispatch.rs +++ b/substrate/frame/support/src/dispatch.rs @@ -25,7 +25,7 @@ use scale_info::TypeInfo; use serde::{Deserialize, Serialize}; use sp_runtime::{ generic::{CheckedExtrinsic, UncheckedExtrinsic}, - traits::Dispatchable, + traits::SignedExtension, DispatchError, RuntimeDebug, }; use sp_std::fmt; @@ -268,8 +268,7 @@ pub fn extract_actual_weight(result: &DispatchResultWithPostInfo, info: &Dispatc .calc_actual_weight(info) } -/// Extract the actual pays_fee from a dispatch result if any or fall back to the default -/// weight. +/// Extract the actual pays_fee from a dispatch result if any or fall back to the default weight. pub fn extract_actual_pays_fee(result: &DispatchResultWithPostInfo, info: &DispatchInfo) -> Pays { match result { Ok(post_info) => post_info, @@ -369,10 +368,11 @@ where } /// Implementation for unchecked extrinsic. -impl GetDispatchInfo - for UncheckedExtrinsic +impl GetDispatchInfo + for UncheckedExtrinsic where - Call: GetDispatchInfo + Dispatchable, + Call: GetDispatchInfo, + Extra: SignedExtension, { fn get_dispatch_info(&self) -> DispatchInfo { self.function.get_dispatch_info() @@ -380,7 +380,7 @@ where } /// Implementation for checked extrinsic. -impl GetDispatchInfo for CheckedExtrinsic +impl GetDispatchInfo for CheckedExtrinsic where Call: GetDispatchInfo, { @@ -389,6 +389,21 @@ where } } +/// Implementation for test extrinsic. +#[cfg(feature = "std")] +impl GetDispatchInfo + for sp_runtime::testing::TestXt +{ + fn get_dispatch_info(&self) -> DispatchInfo { + // for testing: weight == size. + DispatchInfo { + weight: Weight::from_parts(self.encode().len() as _, 0), + pays_fee: Pays::Yes, + class: self.call.get_dispatch_info().class, + } + } +} + /// A struct holding value for each `DispatchClass`. #[derive(Clone, Eq, PartialEq, Default, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] pub struct PerDispatchClass { diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs index af8449c9697..4eadd85a9e0 100644 --- a/substrate/frame/support/src/lib.rs +++ b/substrate/frame/support/src/lib.rs @@ -54,8 +54,7 @@ pub mod __private { #[cfg(feature = "std")] pub use sp_runtime::{bounded_btree_map, bounded_vec}; pub use sp_runtime::{ - traits::{AsSystemOriginSigner, Dispatchable}, - DispatchError, RuntimeDebug, StateVersion, TransactionOutcome, + traits::Dispatchable, DispatchError, RuntimeDebug, StateVersion, TransactionOutcome, }; #[cfg(feature = "std")] pub use sp_state_machine::BasicExternalities; @@ -76,7 +75,6 @@ pub mod storage; #[cfg(test)] mod tests; pub mod traits; -pub mod transaction_extensions; pub mod weights; #[doc(hidden)] pub mod unsigned { @@ -1586,8 +1584,8 @@ pub mod pallet_macros { /// [`ValidateUnsigned`](frame_support::pallet_prelude::ValidateUnsigned) for /// type `Pallet`, and some optional where clause. /// - /// NOTE: There is also the [`sp_runtime::traits::TransactionExtension`] trait that can be - /// used to add some specific logic for transaction validation. + /// NOTE: There is also the [`sp_runtime::traits::SignedExtension`] trait that can be used + /// to add some specific logic for transaction validation. /// /// ## Macro expansion /// diff --git a/substrate/frame/support/src/traits/dispatch.rs b/substrate/frame/support/src/traits/dispatch.rs index 212c3080352..de50ce7a26c 100644 --- a/substrate/frame/support/src/traits/dispatch.rs +++ b/substrate/frame/support/src/traits/dispatch.rs @@ -482,7 +482,7 @@ pub trait OriginTrait: Sized { type Call; /// The caller origin, overarching type of all pallets origins. - type PalletsOrigin: Send + Sync + Into + CallerTrait + MaxEncodedLen; + type PalletsOrigin: Into + CallerTrait + MaxEncodedLen; /// The AccountId used across the system. type AccountId; @@ -496,14 +496,6 @@ pub trait OriginTrait: Sized { /// Replace the caller with caller from the other origin fn set_caller_from(&mut self, other: impl Into); - /// Replace the caller with caller from the other origin - fn set_caller(&mut self, caller: Self::PalletsOrigin); - - /// Replace the caller with caller from the other origin - fn set_caller_from_signed(&mut self, caller_account: Self::AccountId) { - self.set_caller(Self::PalletsOrigin::from(RawOrigin::Signed(caller_account))) - } - /// Filter the call if caller is not root, if false is returned then the call must be filtered /// out. /// @@ -552,17 +544,6 @@ pub trait OriginTrait: Sized { fn as_system_ref(&self) -> Option<&RawOrigin> { self.caller().as_system_ref() } - - /// Extract a reference to the sytsem signer, if that's what the caller is. - fn as_system_signer(&self) -> Option<&Self::AccountId> { - self.caller().as_system_ref().and_then(|s| { - if let RawOrigin::Signed(ref who) = s { - Some(who) - } else { - None - } - }) - } } #[cfg(test)] diff --git a/substrate/frame/support/src/traits/misc.rs b/substrate/frame/support/src/traits/misc.rs index fba546ce21b..1f634a64282 100644 --- a/substrate/frame/support/src/traits/misc.rs +++ b/substrate/frame/support/src/traits/misc.rs @@ -919,13 +919,24 @@ pub trait ExtrinsicCall: sp_runtime::traits::Extrinsic { fn call(&self) -> &Self::Call; } +#[cfg(feature = "std")] +impl ExtrinsicCall for sp_runtime::testing::TestXt +where + Call: codec::Codec + Sync + Send + TypeInfo, + Extra: TypeInfo, +{ + fn call(&self) -> &Self::Call { + &self.call + } +} + impl ExtrinsicCall for sp_runtime::generic::UncheckedExtrinsic where Address: TypeInfo, Call: TypeInfo, Signature: TypeInfo, - Extra: TypeInfo, + Extra: sp_runtime::traits::SignedExtension + TypeInfo, { fn call(&self) -> &Self::Call { &self.function diff --git a/substrate/frame/support/src/transaction_extensions.rs b/substrate/frame/support/src/transaction_extensions.rs deleted file mode 100644 index 98d78b9b4e4..00000000000 --- a/substrate/frame/support/src/transaction_extensions.rs +++ /dev/null @@ -1,89 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// 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. - -//! Transaction extensions. - -use crate::{CloneNoBound, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound}; -use codec::{Decode, Encode}; -use scale_info::TypeInfo; -use sp_io::hashing::blake2_256; -use sp_runtime::{ - impl_tx_ext_default, - traits::{ - transaction_extension::{TransactionExtensionBase, TransactionExtensionInterior}, - DispatchInfoOf, Dispatchable, IdentifyAccount, TransactionExtension, Verify, - }, - transaction_validity::{InvalidTransaction, TransactionValidityError, ValidTransaction}, -}; - -#[derive( - CloneNoBound, EqNoBound, PartialEqNoBound, Encode, Decode, RuntimeDebugNoBound, TypeInfo, -)] -#[codec(encode_bound())] -#[codec(decode_bound())] -pub struct VerifyMultiSignature -where - V: TransactionExtensionInterior, - ::AccountId: TransactionExtensionInterior, -{ - signature: V, - account: ::AccountId, -} - -impl TransactionExtensionBase for VerifyMultiSignature -where - V: TransactionExtensionInterior, - ::AccountId: TransactionExtensionInterior, -{ - const IDENTIFIER: &'static str = "VerifyMultiSignature"; - type Implicit = (); -} - -impl TransactionExtension - for VerifyMultiSignature -where - V: TransactionExtensionInterior, - ::AccountId: TransactionExtensionInterior, - ::RuntimeOrigin: From::AccountId>>, -{ - type Val = (); - type Pre = (); - impl_tx_ext_default!(Call; Context; prepare); - - fn validate( - &self, - _origin: ::RuntimeOrigin, - _call: &Call, - _info: &DispatchInfoOf, - _len: usize, - _: &mut Context, - _: (), - inherited_implication: &impl Encode, - ) -> Result< - (ValidTransaction, Self::Val, ::RuntimeOrigin), - TransactionValidityError, - > { - let msg = inherited_implication.using_encoded(blake2_256); - - if !self.signature.verify(&msg[..], &self.account) { - Err(InvalidTransaction::BadProof)? - } - // We clobber the original origin. Maybe we shuld check that it's none? - let origin = Some(self.account.clone()).into(); - Ok((ValidTransaction::default(), (), origin)) - } -} diff --git a/substrate/frame/support/src/weights/block_weights.rs b/substrate/frame/support/src/weights/block_weights.rs index 647b6198357..57a68554755 100644 --- a/substrate/frame/support/src/weights/block_weights.rs +++ b/substrate/frame/support/src/weights/block_weights.rs @@ -15,23 +15,24 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01 (Y/M/D) -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16 (Y/M/D) +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! //! SHORT-NAME: `block`, LONG-NAME: `BlockExecution`, RUNTIME: `Development` //! WARMUPS: `10`, REPEAT: `100` -//! WEIGHT-PATH: `./substrate/frame/support/src/weights/` +//! WEIGHT-PATH: `./frame/support/src/weights/` //! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0` // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // overhead // --chain=dev +// --execution=wasm // --wasm-execution=compiled -// --weight-path=./substrate/frame/support/src/weights/ -// --header=./substrate/HEADER-APACHE2 +// --weight-path=./frame/support/src/weights/ +// --header=./HEADER-APACHE2 // --warmup=10 // --repeat=100 @@ -43,17 +44,17 @@ parameter_types! { /// Calculated by multiplying the *Average* with `1.0` and adding `0`. /// /// Stats nanoseconds: - /// Min, Max: 424_332, 493_017 - /// Average: 437_118 - /// Median: 434_920 - /// Std-Dev: 8798.01 + /// Min, Max: 376_949, 622_462 + /// Average: 390_584 + /// Median: 386_322 + /// Std-Dev: 24792.0 /// /// Percentiles nanoseconds: - /// 99th: 460_074 - /// 95th: 451_580 - /// 75th: 440_307 + /// 99th: 433_299 + /// 95th: 402_688 + /// 75th: 391_645 pub const BlockExecutionWeight: Weight = - Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(437_118), 0); + Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(390_584), 0); } #[cfg(test)] diff --git a/substrate/frame/support/src/weights/extrinsic_weights.rs b/substrate/frame/support/src/weights/extrinsic_weights.rs index 99b392c4369..a304f089ff7 100644 --- a/substrate/frame/support/src/weights/extrinsic_weights.rs +++ b/substrate/frame/support/src/weights/extrinsic_weights.rs @@ -15,23 +15,24 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01 (Y/M/D) -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16 (Y/M/D) +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! //! SHORT-NAME: `extrinsic`, LONG-NAME: `ExtrinsicBase`, RUNTIME: `Development` //! WARMUPS: `10`, REPEAT: `100` -//! WEIGHT-PATH: `./substrate/frame/support/src/weights/` +//! WEIGHT-PATH: `./frame/support/src/weights/` //! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0` // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // overhead // --chain=dev +// --execution=wasm // --wasm-execution=compiled -// --weight-path=./substrate/frame/support/src/weights/ -// --header=./substrate/HEADER-APACHE2 +// --weight-path=./frame/support/src/weights/ +// --header=./HEADER-APACHE2 // --warmup=10 // --repeat=100 @@ -43,17 +44,17 @@ parameter_types! { /// Calculated by multiplying the *Average* with `1.0` and adding `0`. /// /// Stats nanoseconds: - /// Min, Max: 106_053, 107_403 - /// Average: 106_446 - /// Median: 106_415 - /// Std-Dev: 216.17 + /// Min, Max: 123_875, 128_419 + /// Average: 124_414 + /// Median: 124_332 + /// Std-Dev: 497.74 /// /// Percentiles nanoseconds: - /// 99th: 107_042 - /// 95th: 106_841 - /// 75th: 106_544 + /// 99th: 125_245 + /// 95th: 124_989 + /// 75th: 124_498 pub const ExtrinsicBaseWeight: Weight = - Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(106_446), 0); + Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(124_414), 0); } #[cfg(test)] diff --git a/substrate/frame/support/test/tests/construct_runtime_ui/deprecated_where_block.stderr b/substrate/frame/support/test/tests/construct_runtime_ui/deprecated_where_block.stderr index c677ddcd672..09c4d290ef5 100644 --- a/substrate/frame/support/test/tests/construct_runtime_ui/deprecated_where_block.stderr +++ b/substrate/frame/support/test/tests/construct_runtime_ui/deprecated_where_block.stderr @@ -477,7 +477,7 @@ note: required because it appears within the type `RuntimeCall` | ||_- in this macro invocation ... | note: required by a bound in `frame_support::sp_runtime::traits::Dispatchable::Config` - --> $WORKSPACE/substrate/primitives/runtime/src/traits/mod.rs + --> $WORKSPACE/substrate/primitives/runtime/src/traits.rs | | type Config; | ^^^^^^^^^^^^ required by this bound in `Dispatchable::Config` @@ -510,7 +510,7 @@ note: required because it appears within the type `RuntimeCall` | ||_- in this macro invocation ... | note: required by a bound in `frame_support::pallet_prelude::ValidateUnsigned::Call` - --> $WORKSPACE/substrate/primitives/runtime/src/traits/mod.rs + --> $WORKSPACE/substrate/primitives/runtime/src/traits.rs | | type Call; | ^^^^^^^^^^ required by this bound in `ValidateUnsigned::Call` diff --git a/substrate/frame/support/test/tests/pallet.rs b/substrate/frame/support/test/tests/pallet.rs index 4d2737d411e..607f54ccc13 100644 --- a/substrate/frame/support/test/tests/pallet.rs +++ b/substrate/frame/support/test/tests/pallet.rs @@ -743,40 +743,10 @@ impl pallet5::Config for Runtime { type RuntimeOrigin = RuntimeOrigin; } -#[derive(Clone, Debug, codec::Encode, codec::Decode, PartialEq, Eq, scale_info::TypeInfo)] -pub struct AccountU64(u64); -impl sp_runtime::traits::IdentifyAccount for AccountU64 { - type AccountId = u64; - fn into_account(self) -> u64 { - self.0 - } -} - -impl sp_runtime::traits::Verify for AccountU64 { - type Signer = AccountU64; - fn verify>( - &self, - _msg: L, - _signer: &::AccountId, - ) -> bool { - true - } -} - -impl From for AccountU64 { - fn from(value: u64) -> Self { - Self(value) - } -} - pub type Header = sp_runtime::generic::Header; pub type Block = sp_runtime::generic::Block; -pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic< - u64, - RuntimeCall, - AccountU64, - frame_system::CheckNonZeroSender, ->; +pub type UncheckedExtrinsic = + sp_runtime::testing::TestXt>; frame_support::construct_runtime!( pub struct Runtime { @@ -926,8 +896,10 @@ fn inherent_expand() { let inherents = InherentData::new().create_extrinsics(); - let expected = - vec![UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_no_post_info {}))]; + let expected = vec![UncheckedExtrinsic { + call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}), + signature: None, + }]; assert_eq!(expected, inherents); let block = Block::new( @@ -939,11 +911,14 @@ fn inherent_expand() { Digest::default(), ), vec![ - UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_no_post_info {})), - UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo { - foo: 1, - bar: 0, - })), + UncheckedExtrinsic { + call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}), + signature: None, + }, + UncheckedExtrinsic { + call: RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 0 }), + signature: None, + }, ], ); @@ -958,11 +933,14 @@ fn inherent_expand() { Digest::default(), ), vec![ - UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_no_post_info {})), - UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo { - foo: 0, - bar: 0, - })), + UncheckedExtrinsic { + call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}), + signature: None, + }, + UncheckedExtrinsic { + call: RuntimeCall::Example(pallet::Call::foo { foo: 0, bar: 0 }), + signature: None, + }, ], ); @@ -976,9 +954,10 @@ fn inherent_expand() { BlakeTwo256::hash(b"test"), Digest::default(), ), - vec![UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_storage_layer { - foo: 0, - }))], + vec![UncheckedExtrinsic { + call: RuntimeCall::Example(pallet::Call::foo_storage_layer { foo: 0 }), + signature: None, + }], ); let mut inherent = InherentData::new(); @@ -993,12 +972,10 @@ fn inherent_expand() { BlakeTwo256::hash(b"test"), Digest::default(), ), - vec![UncheckedExtrinsic::new_signed( - RuntimeCall::Example(pallet::Call::foo_no_post_info {}), - 1, - 1.into(), - Default::default(), - )], + vec![UncheckedExtrinsic { + call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}), + signature: Some((1, Default::default())), + }], ); let mut inherent = InherentData::new(); @@ -1014,13 +991,14 @@ fn inherent_expand() { Digest::default(), ), vec![ - UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo { - foo: 1, - bar: 1, - })), - UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_storage_layer { - foo: 0, - })), + UncheckedExtrinsic { + call: RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 1 }), + signature: None, + }, + UncheckedExtrinsic { + call: RuntimeCall::Example(pallet::Call::foo_storage_layer { foo: 0 }), + signature: None, + }, ], ); @@ -1035,14 +1013,18 @@ fn inherent_expand() { Digest::default(), ), vec![ - UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo { - foo: 1, - bar: 1, - })), - UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_storage_layer { - foo: 0, - })), - UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_no_post_info {})), + UncheckedExtrinsic { + call: RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 1 }), + signature: None, + }, + UncheckedExtrinsic { + call: RuntimeCall::Example(pallet::Call::foo_storage_layer { foo: 0 }), + signature: None, + }, + UncheckedExtrinsic { + call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}), + signature: None, + }, ], ); @@ -1057,17 +1039,18 @@ fn inherent_expand() { Digest::default(), ), vec![ - UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo { - foo: 1, - bar: 1, - })), - UncheckedExtrinsic::new_signed( - RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 0 }), - 1, - 1.into(), - Default::default(), - ), - UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_no_post_info {})), + UncheckedExtrinsic { + call: RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 1 }), + signature: None, + }, + UncheckedExtrinsic { + call: RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 0 }), + signature: Some((1, Default::default())), + }, + UncheckedExtrinsic { + call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}), + signature: None, + }, ], ); @@ -1950,7 +1933,7 @@ fn extrinsic_metadata_ir_types() { >(), ir.signature_ty ); - assert_eq!(meta_type::(), ir.signature_ty); + assert_eq!(meta_type::<()>(), ir.signature_ty); assert_eq!(meta_type::<<::SignaturePayload as SignaturePayloadT>::SignatureExtra>(), ir.extra_ty); assert_eq!(meta_type::>(), ir.extra_ty); diff --git a/substrate/frame/support/test/tests/pallet_instance.rs b/substrate/frame/support/test/tests/pallet_instance.rs index 505400a7c21..f8cc97623b8 100644 --- a/substrate/frame/support/test/tests/pallet_instance.rs +++ b/substrate/frame/support/test/tests/pallet_instance.rs @@ -943,7 +943,7 @@ fn metadata() { ty: scale_info::meta_type::(), version: 4, signed_extensions: vec![SignedExtensionMetadata { - identifier: "UnitTransactionExtension", + identifier: "UnitSignedExtension", ty: scale_info::meta_type::<()>(), additional_signed: scale_info::meta_type::<()>(), }], diff --git a/substrate/frame/support/test/tests/runtime.rs b/substrate/frame/support/test/tests/runtime.rs index 7e33ee46458..115e3aa4c8a 100644 --- a/substrate/frame/support/test/tests/runtime.rs +++ b/substrate/frame/support/test/tests/runtime.rs @@ -895,7 +895,7 @@ fn test_metadata() { ty: meta_type::(), version: 4, signed_extensions: vec![SignedExtensionMetadata { - identifier: "UnitTransactionExtension", + identifier: "UnitSignedExtension", ty: meta_type::<()>(), additional_signed: meta_type::<()>(), }], diff --git a/substrate/frame/support/test/tests/runtime_legacy_ordering.rs b/substrate/frame/support/test/tests/runtime_legacy_ordering.rs index 38875517018..4c7012dca14 100644 --- a/substrate/frame/support/test/tests/runtime_legacy_ordering.rs +++ b/substrate/frame/support/test/tests/runtime_legacy_ordering.rs @@ -752,7 +752,7 @@ fn test_metadata() { name: "Version", ty: meta_type::(), value: RuntimeVersion::default().encode(), - docs: maybe_docs(vec![ " Get the chain's current version."]), + docs: maybe_docs(vec![ " Get the chain's in-code version."]), }, PalletConstantMetadata { name: "SS58Prefix", @@ -895,7 +895,7 @@ fn test_metadata() { ty: meta_type::(), version: 4, signed_extensions: vec![SignedExtensionMetadata { - identifier: "UnitTransactionExtension", + identifier: "UnitSignedExtension", ty: meta_type::<()>(), additional_signed: meta_type::<()>(), }], diff --git a/substrate/frame/system/benchmarking/src/extensions.rs b/substrate/frame/system/benchmarking/src/extensions.rs deleted file mode 100644 index bfc3b4343a6..00000000000 --- a/substrate/frame/system/benchmarking/src/extensions.rs +++ /dev/null @@ -1,213 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// 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. - -// Benchmarks for System Extensions - -#![cfg(feature = "runtime-benchmarks")] - -use frame_benchmarking::{account, v2::*, BenchmarkError}; -use frame_support::{ - dispatch::{DispatchClass, DispatchInfo, PostDispatchInfo}, - weights::Weight, -}; -use frame_system::{ - pallet_prelude::*, CheckGenesis, CheckMortality, CheckNonZeroSender, CheckNonce, - CheckSpecVersion, CheckTxVersion, CheckWeight, Config, Pallet as System, RawOrigin, -}; -use sp_runtime::{ - generic::Era, - traits::{AsSystemOriginSigner, DispatchTransaction, Dispatchable, Get}, -}; -use sp_std::prelude::*; - -pub struct Pallet(System); - -#[benchmarks(where - T: Send + Sync, - T::RuntimeCall: Dispatchable, - ::RuntimeOrigin: AsSystemOriginSigner + Clone) -] -mod benchmarks { - use super::*; - - #[benchmark] - fn check_genesis() -> Result<(), BenchmarkError> { - let len = 0_usize; - let caller = account("caller", 0, 0); - let info = DispatchInfo { weight: Weight::zero(), ..Default::default() }; - let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into(); - - #[block] - { - CheckGenesis::::new() - .test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(().into())) - .unwrap() - .unwrap(); - } - - Ok(()) - } - - #[benchmark] - fn check_mortality() -> Result<(), BenchmarkError> { - let len = 0_usize; - let ext = CheckMortality::::from(Era::mortal(16, 256)); - let block_number: BlockNumberFor = 17u32.into(); - System::::set_block_number(block_number); - let prev_block: BlockNumberFor = 16u32.into(); - let default_hash: T::Hash = Default::default(); - frame_system::BlockHash::::insert(prev_block, default_hash); - let caller = account("caller", 0, 0); - let info = DispatchInfo { - weight: Weight::from_parts(100, 0), - class: DispatchClass::Normal, - ..Default::default() - }; - let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into(); - - #[block] - { - ext.test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(().into())) - .unwrap() - .unwrap(); - } - Ok(()) - } - - #[benchmark] - fn check_non_zero_sender() -> Result<(), BenchmarkError> { - let len = 0_usize; - let ext = CheckNonZeroSender::::new(); - let caller = account("caller", 0, 0); - let info = DispatchInfo { weight: Weight::zero(), ..Default::default() }; - let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into(); - - #[block] - { - ext.test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(().into())) - .unwrap() - .unwrap(); - } - Ok(()) - } - - #[benchmark] - fn check_nonce() -> Result<(), BenchmarkError> { - let caller: T::AccountId = account("caller", 0, 0); - let mut info = frame_system::AccountInfo::default(); - info.nonce = 1u32.into(); - info.providers = 1; - let expected_nonce = info.nonce + 1u32.into(); - frame_system::Account::::insert(caller.clone(), info); - let len = 0_usize; - let ext = CheckNonce::::from(1u32.into()); - let info = DispatchInfo { weight: Weight::zero(), ..Default::default() }; - let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into(); - - #[block] - { - ext.test_run(RawOrigin::Signed(caller.clone()).into(), &call, &info, len, |_| { - Ok(().into()) - }) - .unwrap() - .unwrap(); - } - - let updated_info = frame_system::Account::::get(caller.clone()); - assert_eq!(updated_info.nonce, expected_nonce); - Ok(()) - } - - #[benchmark] - fn check_spec_version() -> Result<(), BenchmarkError> { - let len = 0_usize; - let caller = account("caller", 0, 0); - let info = DispatchInfo { weight: Weight::zero(), ..Default::default() }; - let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into(); - - #[block] - { - CheckSpecVersion::::new() - .test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(().into())) - .unwrap() - .unwrap(); - } - Ok(()) - } - - #[benchmark] - fn check_tx_version() -> Result<(), BenchmarkError> { - let len = 0_usize; - let caller = account("caller", 0, 0); - let info = DispatchInfo { weight: Weight::zero(), ..Default::default() }; - let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into(); - - #[block] - { - CheckTxVersion::::new() - .test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(().into())) - .unwrap() - .unwrap(); - } - Ok(()) - } - - #[benchmark] - fn check_weight() -> Result<(), BenchmarkError> { - let caller = account("caller", 0, 0); - let base_extrinsic = ::BlockWeights::get() - .get(DispatchClass::Normal) - .base_extrinsic; - let info = DispatchInfo { - weight: Weight::from_parts(base_extrinsic.ref_time() * 5, 0), - class: DispatchClass::Normal, - ..Default::default() - }; - let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into(); - let post_info = PostDispatchInfo { - actual_weight: Some(Weight::from_parts(base_extrinsic.ref_time() * 2, 0)), - pays_fee: Default::default(), - }; - let len = 0_usize; - let base_extrinsic = ::BlockWeights::get() - .get(DispatchClass::Normal) - .base_extrinsic; - - let ext = CheckWeight::::new(); - - let initial_block_weight = Weight::from_parts(base_extrinsic.ref_time() * 2, 0); - frame_system::BlockWeight::::mutate(|current_weight| { - current_weight.set(Weight::zero(), DispatchClass::Mandatory); - current_weight.set(initial_block_weight, DispatchClass::Normal); - }); - - #[block] - { - ext.test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(post_info)) - .unwrap() - .unwrap(); - } - - assert_eq!( - System::::block_weight().total(), - initial_block_weight + base_extrinsic + post_info.actual_weight.unwrap(), - ); - Ok(()) - } - - impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test,); -} diff --git a/substrate/frame/system/benchmarking/src/lib.rs b/substrate/frame/system/benchmarking/src/lib.rs index c9f0869d3bc..29100faa751 100644 --- a/substrate/frame/system/benchmarking/src/lib.rs +++ b/substrate/frame/system/benchmarking/src/lib.rs @@ -28,7 +28,6 @@ use sp_core::storage::well_known_keys; use sp_runtime::traits::Hash; use sp_std::{prelude::*, vec}; -pub mod extensions; mod mock; pub struct Pallet(System); diff --git a/substrate/frame/system/benchmarking/src/mock.rs b/substrate/frame/system/benchmarking/src/mock.rs index 1f84dd53004..edbf74a9a51 100644 --- a/substrate/frame/system/benchmarking/src/mock.rs +++ b/substrate/frame/system/benchmarking/src/mock.rs @@ -57,7 +57,6 @@ impl frame_system::Config for Test { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); - type ExtensionsWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); type MaxConsumers = frame_support::traits::ConstU32<16>; diff --git a/substrate/frame/system/src/extensions/check_genesis.rs b/substrate/frame/system/src/extensions/check_genesis.rs index 3f11f745cd9..76a711a823e 100644 --- a/substrate/frame/system/src/extensions/check_genesis.rs +++ b/substrate/frame/system/src/extensions/check_genesis.rs @@ -19,8 +19,7 @@ use crate::{pallet_prelude::BlockNumberFor, Config, Pallet}; use codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_runtime::{ - impl_tx_ext_default, - traits::{TransactionExtension, TransactionExtensionBase, Zero}, + traits::{DispatchInfoOf, SignedExtension, Zero}, transaction_validity::TransactionValidityError, }; @@ -47,26 +46,30 @@ impl sp_std::fmt::Debug for CheckGenesis { } impl CheckGenesis { - /// Creates new `TransactionExtension` to check genesis hash. + /// Creates new `SignedExtension` to check genesis hash. pub fn new() -> Self { Self(sp_std::marker::PhantomData) } } -impl TransactionExtensionBase for CheckGenesis { +impl SignedExtension for CheckGenesis { + type AccountId = T::AccountId; + type Call = ::RuntimeCall; + type AdditionalSigned = T::Hash; + type Pre = (); const IDENTIFIER: &'static str = "CheckGenesis"; - type Implicit = T::Hash; - fn implicit(&self) -> Result { + + fn additional_signed(&self) -> Result { Ok(>::block_hash(BlockNumberFor::::zero())) } - fn weight(&self) -> sp_weights::Weight { - ::check_genesis() + + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + self.validate(who, call, info, len).map(|_| ()) } } -impl TransactionExtension - for CheckGenesis -{ - type Val = (); - type Pre = (); - impl_tx_ext_default!(T::RuntimeCall; Context; validate prepare); -} diff --git a/substrate/frame/system/src/extensions/check_mortality.rs b/substrate/frame/system/src/extensions/check_mortality.rs index deb44880d64..148dfd4aad4 100644 --- a/substrate/frame/system/src/extensions/check_mortality.rs +++ b/substrate/frame/system/src/extensions/check_mortality.rs @@ -20,12 +20,10 @@ use codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_runtime::{ generic::Era, - impl_tx_ext_default, - traits::{ - DispatchInfoOf, SaturatedConversion, TransactionExtension, TransactionExtensionBase, - ValidateResult, + traits::{DispatchInfoOf, SaturatedConversion, SignedExtension}, + transaction_validity::{ + InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction, }, - transaction_validity::{InvalidTransaction, TransactionValidityError, ValidTransaction}, }; /// Check for transaction mortality. @@ -56,11 +54,29 @@ impl sp_std::fmt::Debug for CheckMortality { } } -impl TransactionExtensionBase for CheckMortality { +impl SignedExtension for CheckMortality { + type AccountId = T::AccountId; + type Call = T::RuntimeCall; + type AdditionalSigned = T::Hash; + type Pre = (); const IDENTIFIER: &'static str = "CheckMortality"; - type Implicit = T::Hash; - fn implicit(&self) -> Result { + fn validate( + &self, + _who: &Self::AccountId, + _call: &Self::Call, + _info: &DispatchInfoOf, + _len: usize, + ) -> TransactionValidity { + let current_u64 = >::block_number().saturated_into::(); + let valid_till = self.0.death(current_u64); + Ok(ValidTransaction { + longevity: valid_till.saturating_sub(current_u64), + ..Default::default() + }) + } + + fn additional_signed(&self) -> Result { let current_u64 = >::block_number().saturated_into::(); let n = self.0.birth(current_u64).saturated_into::>(); if !>::contains_key(n) { @@ -69,38 +85,16 @@ impl TransactionExtensionBase for CheckMortality { Ok(>::block_hash(n)) } } - fn weight(&self) -> sp_weights::Weight { - ::check_mortality() - } -} -impl TransactionExtension - for CheckMortality -{ - type Pre = (); - type Val = (); - fn validate( - &self, - origin: ::RuntimeOrigin, - _call: &T::RuntimeCall, - _info: &DispatchInfoOf, - _len: usize, - _context: &mut Context, - _self_implicit: Self::Implicit, - _inherited_implication: &impl Encode, - ) -> ValidateResult { - let current_u64 = >::block_number().saturated_into::(); - let valid_till = self.0.death(current_u64); - Ok(( - ValidTransaction { - longevity: valid_till.saturating_sub(current_u64), - ..Default::default() - }, - (), - origin, - )) + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + self.validate(who, call, info, len).map(|_| ()) } - impl_tx_ext_default!(T::RuntimeCall; Context; prepare); } #[cfg(test)] @@ -112,21 +106,23 @@ mod tests { weights::Weight, }; use sp_core::H256; - use sp_runtime::traits::DispatchTransaction; #[test] fn signed_ext_check_era_should_work() { new_test_ext().execute_with(|| { // future assert_eq!( - CheckMortality::::from(Era::mortal(4, 2)).implicit().err().unwrap(), + CheckMortality::::from(Era::mortal(4, 2)) + .additional_signed() + .err() + .unwrap(), InvalidTransaction::AncientBirthBlock.into(), ); // correct System::set_block_number(13); >::insert(12, H256::repeat_byte(1)); - assert!(CheckMortality::::from(Era::mortal(4, 12)).implicit().is_ok()); + assert!(CheckMortality::::from(Era::mortal(4, 12)).additional_signed().is_ok()); }) } @@ -146,10 +142,7 @@ mod tests { System::set_block_number(17); >::insert(16, H256::repeat_byte(1)); - assert_eq!( - ext.validate_only(Some(1).into(), CALL, &normal, len).unwrap().0.longevity, - 15 - ); + assert_eq!(ext.validate(&1, CALL, &normal, len).unwrap().longevity, 15); }) } } diff --git a/substrate/frame/system/src/extensions/check_non_zero_sender.rs b/substrate/frame/system/src/extensions/check_non_zero_sender.rs index 115ffac9b03..92eed60fc66 100644 --- a/substrate/frame/system/src/extensions/check_non_zero_sender.rs +++ b/substrate/frame/system/src/extensions/check_non_zero_sender.rs @@ -17,14 +17,13 @@ use crate::Config; use codec::{Decode, Encode}; -use frame_support::{traits::OriginTrait, DefaultNoBound}; +use frame_support::{dispatch::DispatchInfo, DefaultNoBound}; use scale_info::TypeInfo; use sp_runtime::{ - impl_tx_ext_default, - traits::{ - transaction_extension::TransactionExtensionBase, DispatchInfoOf, TransactionExtension, + traits::{DispatchInfoOf, Dispatchable, SignedExtension}, + transaction_validity::{ + InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction, }, - transaction_validity::InvalidTransaction, }; use sp_std::{marker::PhantomData, prelude::*}; @@ -46,82 +45,66 @@ impl sp_std::fmt::Debug for CheckNonZeroSender { } impl CheckNonZeroSender { - /// Create new `TransactionExtension` to check runtime version. + /// Create new `SignedExtension` to check runtime version. pub fn new() -> Self { Self(sp_std::marker::PhantomData) } } -impl TransactionExtensionBase for CheckNonZeroSender { - const IDENTIFIER: &'static str = "CheckNonZeroSender"; - type Implicit = (); - fn weight(&self) -> sp_weights::Weight { - ::check_non_zero_sender() - } -} -impl TransactionExtension - for CheckNonZeroSender +impl SignedExtension for CheckNonZeroSender +where + T::RuntimeCall: Dispatchable, { - type Val = (); + type AccountId = T::AccountId; + type Call = T::RuntimeCall; + type AdditionalSigned = (); type Pre = (); + const IDENTIFIER: &'static str = "CheckNonZeroSender"; + + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { + Ok(()) + } + + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + self.validate(who, call, info, len).map(|_| ()) + } + fn validate( &self, - origin: ::RuntimeOrigin, - _call: &T::RuntimeCall, - _info: &DispatchInfoOf, + who: &Self::AccountId, + _call: &Self::Call, + _info: &DispatchInfoOf, _len: usize, - _context: &mut Context, - _self_implicit: Self::Implicit, - _inherited_implication: &impl Encode, - ) -> sp_runtime::traits::ValidateResult { - if let Some(who) = origin.as_system_signer() { - if who.using_encoded(|d| d.iter().all(|x| *x == 0)) { - return Err(InvalidTransaction::BadSigner.into()) - } + ) -> TransactionValidity { + if who.using_encoded(|d| d.iter().all(|x| *x == 0)) { + return Err(TransactionValidityError::Invalid(InvalidTransaction::BadSigner)) } - Ok((Default::default(), (), origin)) + Ok(ValidTransaction::default()) } - impl_tx_ext_default!(T::RuntimeCall; Context; prepare); } #[cfg(test)] mod tests { use super::*; use crate::mock::{new_test_ext, Test, CALL}; - use frame_support::{assert_ok, dispatch::DispatchInfo}; - use sp_runtime::{traits::DispatchTransaction, TransactionValidityError}; + use frame_support::{assert_noop, assert_ok}; #[test] fn zero_account_ban_works() { new_test_ext().execute_with(|| { let info = DispatchInfo::default(); let len = 0_usize; - assert_eq!( - CheckNonZeroSender::::new() - .validate_only(Some(0).into(), CALL, &info, len) - .unwrap_err(), - TransactionValidityError::from(InvalidTransaction::BadSigner) + assert_noop!( + CheckNonZeroSender::::new().validate(&0, CALL, &info, len), + InvalidTransaction::BadSigner ); - assert_ok!(CheckNonZeroSender::::new().validate_only( - Some(1).into(), - CALL, - &info, - len - )); - }) - } - - #[test] - fn unsigned_origin_works() { - new_test_ext().execute_with(|| { - let info = DispatchInfo::default(); - let len = 0_usize; - assert_ok!(CheckNonZeroSender::::new().validate_only( - None.into(), - CALL, - &info, - len - )); + assert_ok!(CheckNonZeroSender::::new().validate(&1, CALL, &info, len)); }) } } diff --git a/substrate/frame/system/src/extensions/check_nonce.rs b/substrate/frame/system/src/extensions/check_nonce.rs index ead9d9f7c81..7504a814aef 100644 --- a/substrate/frame/system/src/extensions/check_nonce.rs +++ b/substrate/frame/system/src/extensions/check_nonce.rs @@ -15,19 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{AccountInfo, Config}; +use crate::Config; use codec::{Decode, Encode}; use frame_support::dispatch::DispatchInfo; use scale_info::TypeInfo; use sp_runtime::{ - traits::{ - AsSystemOriginSigner, DispatchInfoOf, Dispatchable, One, TransactionExtension, - TransactionExtensionBase, ValidateResult, Zero, - }, + traits::{DispatchInfoOf, Dispatchable, One, SignedExtension, Zero}, transaction_validity::{ - InvalidTransaction, TransactionLongevity, TransactionValidityError, ValidTransaction, + InvalidTransaction, TransactionLongevity, TransactionValidity, TransactionValidityError, + ValidTransaction, }, - Saturating, }; use sp_std::vec; @@ -61,78 +58,75 @@ impl sp_std::fmt::Debug for CheckNonce { } } -impl TransactionExtensionBase for CheckNonce { - const IDENTIFIER: &'static str = "CheckNonce"; - type Implicit = (); - fn weight(&self) -> sp_weights::Weight { - ::check_nonce() - } -} -impl TransactionExtension for CheckNonce +impl SignedExtension for CheckNonce where T::RuntimeCall: Dispatchable, - ::RuntimeOrigin: AsSystemOriginSigner + Clone, { - type Val = Option<(T::AccountId, AccountInfo)>; + type AccountId = T::AccountId; + type Call = T::RuntimeCall; + type AdditionalSigned = (); type Pre = (); + const IDENTIFIER: &'static str = "CheckNonce"; + + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { + Ok(()) + } + + fn pre_dispatch( + self, + who: &Self::AccountId, + _call: &Self::Call, + _info: &DispatchInfoOf, + _len: usize, + ) -> Result<(), TransactionValidityError> { + let mut account = crate::Account::::get(who); + if account.providers.is_zero() && account.sufficients.is_zero() { + // Nonce storage not paid for + return Err(InvalidTransaction::Payment.into()) + } + if self.0 != account.nonce { + return Err(if self.0 < account.nonce { + InvalidTransaction::Stale + } else { + InvalidTransaction::Future + } + .into()) + } + account.nonce += T::Nonce::one(); + crate::Account::::insert(who, account); + Ok(()) + } fn validate( &self, - origin: ::RuntimeOrigin, - _call: &T::RuntimeCall, - _info: &DispatchInfoOf, + who: &Self::AccountId, + _call: &Self::Call, + _info: &DispatchInfoOf, _len: usize, - _context: &mut Context, - _self_implicit: Self::Implicit, - _inherited_implication: &impl Encode, - ) -> ValidateResult { - let Some(who) = origin.as_system_origin_signer() else { - return Ok((Default::default(), None, origin)) - }; + ) -> TransactionValidity { let account = crate::Account::::get(who); if account.providers.is_zero() && account.sufficients.is_zero() { // Nonce storage not paid for - return Err(InvalidTransaction::Payment.into()) + return InvalidTransaction::Payment.into() } if self.0 < account.nonce { - return Err(InvalidTransaction::Stale.into()) + return InvalidTransaction::Stale.into() } - let provides = vec![Encode::encode(&(who.clone(), self.0))]; + let provides = vec![Encode::encode(&(who, self.0))]; let requires = if account.nonce < self.0 { - vec![Encode::encode(&(who.clone(), self.0.saturating_sub(One::one())))] + vec![Encode::encode(&(who, self.0 - One::one()))] } else { vec![] }; - let validity = ValidTransaction { + Ok(ValidTransaction { priority: 0, requires, provides, longevity: TransactionLongevity::max_value(), propagate: true, - }; - - Ok((validity, Some((who.clone(), account)), origin)) - } - - fn prepare( - self, - val: Self::Val, - _origin: &T::RuntimeOrigin, - _call: &T::RuntimeCall, - _info: &DispatchInfoOf, - _len: usize, - _context: &Context, - ) -> Result { - let Some((who, mut account)) = val else { return Ok(()) }; - // `self.0 < account.nonce` already checked in `validate`. - if self.0 > account.nonce { - return Err(InvalidTransaction::Future.into()) - } - account.nonce.saturating_inc(); - crate::Account::::insert(who, account); - Ok(()) + }) } } @@ -140,8 +134,7 @@ where mod tests { use super::*; use crate::mock::{new_test_ext, Test, CALL}; - use frame_support::assert_ok; - use sp_runtime::traits::DispatchTransaction; + use frame_support::{assert_noop, assert_ok}; #[test] fn signed_ext_check_nonce_works() { @@ -159,33 +152,22 @@ mod tests { let info = DispatchInfo::default(); let len = 0_usize; // stale - assert_eq!( - CheckNonce::(0) - .validate_only(Some(1).into(), CALL, &info, len,) - .unwrap_err(), - TransactionValidityError::Invalid(InvalidTransaction::Stale) + assert_noop!( + CheckNonce::(0).validate(&1, CALL, &info, len), + InvalidTransaction::Stale ); - assert_eq!( - CheckNonce::(0) - .validate_and_prepare(Some(1).into(), CALL, &info, len) - .unwrap_err(), - InvalidTransaction::Stale.into() + assert_noop!( + CheckNonce::(0).pre_dispatch(&1, CALL, &info, len), + InvalidTransaction::Stale ); // correct - assert_ok!(CheckNonce::(1).validate_only(Some(1).into(), CALL, &info, len)); - assert_ok!(CheckNonce::(1).validate_and_prepare( - Some(1).into(), - CALL, - &info, - len - )); + assert_ok!(CheckNonce::(1).validate(&1, CALL, &info, len)); + assert_ok!(CheckNonce::(1).pre_dispatch(&1, CALL, &info, len)); // future - assert_ok!(CheckNonce::(5).validate_only(Some(1).into(), CALL, &info, len)); - assert_eq!( - CheckNonce::(5) - .validate_and_prepare(Some(1).into(), CALL, &info, len) - .unwrap_err(), - InvalidTransaction::Future.into() + assert_ok!(CheckNonce::(5).validate(&1, CALL, &info, len)); + assert_noop!( + CheckNonce::(5).pre_dispatch(&1, CALL, &info, len), + InvalidTransaction::Future ); }) } @@ -216,44 +198,20 @@ mod tests { let info = DispatchInfo::default(); let len = 0_usize; // Both providers and sufficients zero - assert_eq!( - CheckNonce::(1) - .validate_only(Some(1).into(), CALL, &info, len) - .unwrap_err(), - TransactionValidityError::Invalid(InvalidTransaction::Payment) + assert_noop!( + CheckNonce::(1).validate(&1, CALL, &info, len), + InvalidTransaction::Payment ); - assert_eq!( - CheckNonce::(1) - .validate_and_prepare(Some(1).into(), CALL, &info, len) - .unwrap_err(), - TransactionValidityError::Invalid(InvalidTransaction::Payment) + assert_noop!( + CheckNonce::(1).pre_dispatch(&1, CALL, &info, len), + InvalidTransaction::Payment ); // Non-zero providers - assert_ok!(CheckNonce::(1).validate_only(Some(2).into(), CALL, &info, len)); - assert_ok!(CheckNonce::(1).validate_and_prepare( - Some(2).into(), - CALL, - &info, - len - )); + assert_ok!(CheckNonce::(1).validate(&2, CALL, &info, len)); + assert_ok!(CheckNonce::(1).pre_dispatch(&2, CALL, &info, len)); // Non-zero sufficients - assert_ok!(CheckNonce::(1).validate_only(Some(3).into(), CALL, &info, len)); - assert_ok!(CheckNonce::(1).validate_and_prepare( - Some(3).into(), - CALL, - &info, - len - )); - }) - } - - #[test] - fn unsigned_check_nonce_works() { - new_test_ext().execute_with(|| { - let info = DispatchInfo::default(); - let len = 0_usize; - assert_ok!(CheckNonce::(1).validate_only(None.into(), CALL, &info, len)); - assert_ok!(CheckNonce::(1).validate_and_prepare(None.into(), CALL, &info, len)); + assert_ok!(CheckNonce::(1).validate(&3, CALL, &info, len)); + assert_ok!(CheckNonce::(1).pre_dispatch(&3, CALL, &info, len)); }) } } diff --git a/substrate/frame/system/src/extensions/check_spec_version.rs b/substrate/frame/system/src/extensions/check_spec_version.rs index 3109708f48e..24d5ef9cafb 100644 --- a/substrate/frame/system/src/extensions/check_spec_version.rs +++ b/substrate/frame/system/src/extensions/check_spec_version.rs @@ -19,8 +19,7 @@ use crate::{Config, Pallet}; use codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_runtime::{ - impl_tx_ext_default, - traits::{transaction_extension::TransactionExtensionBase, TransactionExtension}, + traits::{DispatchInfoOf, SignedExtension}, transaction_validity::TransactionValidityError, }; @@ -47,26 +46,30 @@ impl sp_std::fmt::Debug for CheckSpecVersion { } impl CheckSpecVersion { - /// Create new `TransactionExtension` to check runtime version. + /// Create new `SignedExtension` to check runtime version. pub fn new() -> Self { Self(sp_std::marker::PhantomData) } } -impl TransactionExtensionBase for CheckSpecVersion { +impl SignedExtension for CheckSpecVersion { + type AccountId = T::AccountId; + type Call = ::RuntimeCall; + type AdditionalSigned = u32; + type Pre = (); const IDENTIFIER: &'static str = "CheckSpecVersion"; - type Implicit = u32; - fn implicit(&self) -> Result { + + fn additional_signed(&self) -> Result { Ok(>::runtime_version().spec_version) } - fn weight(&self) -> sp_weights::Weight { - ::check_spec_version() + + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + self.validate(who, call, info, len).map(|_| ()) } } -impl TransactionExtension<::RuntimeCall, Context> - for CheckSpecVersion -{ - type Val = (); - type Pre = (); - impl_tx_ext_default!(::RuntimeCall; Context; validate prepare); -} diff --git a/substrate/frame/system/src/extensions/check_tx_version.rs b/substrate/frame/system/src/extensions/check_tx_version.rs index ee1d507e7bc..3f9d6a1903f 100644 --- a/substrate/frame/system/src/extensions/check_tx_version.rs +++ b/substrate/frame/system/src/extensions/check_tx_version.rs @@ -19,8 +19,7 @@ use crate::{Config, Pallet}; use codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_runtime::{ - impl_tx_ext_default, - traits::{transaction_extension::TransactionExtensionBase, TransactionExtension}, + traits::{DispatchInfoOf, SignedExtension}, transaction_validity::TransactionValidityError, }; @@ -47,26 +46,29 @@ impl sp_std::fmt::Debug for CheckTxVersion { } impl CheckTxVersion { - /// Create new `TransactionExtension` to check transaction version. + /// Create new `SignedExtension` to check transaction version. pub fn new() -> Self { Self(sp_std::marker::PhantomData) } } -impl TransactionExtensionBase for CheckTxVersion { +impl SignedExtension for CheckTxVersion { + type AccountId = T::AccountId; + type Call = ::RuntimeCall; + type AdditionalSigned = u32; + type Pre = (); const IDENTIFIER: &'static str = "CheckTxVersion"; - type Implicit = u32; - fn implicit(&self) -> Result { + + fn additional_signed(&self) -> Result { Ok(>::runtime_version().transaction_version) } - fn weight(&self) -> sp_weights::Weight { - ::check_tx_version() + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + self.validate(who, call, info, len).map(|_| ()) } } -impl TransactionExtension<::RuntimeCall, Context> - for CheckTxVersion -{ - type Val = (); - type Pre = (); - impl_tx_ext_default!(::RuntimeCall; Context; validate prepare); -} diff --git a/substrate/frame/system/src/extensions/check_weight.rs b/substrate/frame/system/src/extensions/check_weight.rs index 5c35acfb3f3..70d1e756332 100644 --- a/substrate/frame/system/src/extensions/check_weight.rs +++ b/substrate/frame/system/src/extensions/check_weight.rs @@ -23,12 +23,9 @@ use frame_support::{ }; use scale_info::TypeInfo; use sp_runtime::{ - traits::{ - DispatchInfoOf, Dispatchable, PostDispatchInfoOf, TransactionExtension, - TransactionExtensionBase, ValidateResult, - }, - transaction_validity::{InvalidTransaction, TransactionValidityError}, - DispatchResult, ValidTransaction, + traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf, SignedExtension}, + transaction_validity::{InvalidTransaction, TransactionValidity, TransactionValidityError}, + DispatchResult, }; use sp_weights::Weight; @@ -103,44 +100,40 @@ where } } - /// Creates new `TransactionExtension` to check weight of the extrinsic. + /// Creates new `SignedExtension` to check weight of the extrinsic. pub fn new() -> Self { Self(Default::default()) } - /// Do the validate checks. This can be applied to both signed and unsigned. - /// - /// It only checks that the block weight and length limit will not exceed. - /// - /// Returns the transaction validity and the next block length, to be used in `prepare`. - pub fn do_validate( - info: &DispatchInfoOf, - len: usize, - ) -> Result<(ValidTransaction, u32), TransactionValidityError> { - // ignore the next length. If they return `Ok`, then it is below the limit. - let next_len = Self::check_block_length(info, len)?; - // during validation we skip block limit check. Since the `validate_transaction` - // call runs on an empty block anyway, by this we prevent `on_initialize` weight - // consumption from causing false negatives. - Self::check_extrinsic_weight(info)?; - - Ok((Default::default(), next_len)) - } - /// Do the pre-dispatch checks. This can be applied to both signed and unsigned. /// /// It checks and notes the new weight and length. - pub fn do_prepare( + pub fn do_pre_dispatch( info: &DispatchInfoOf, - next_len: u32, + len: usize, ) -> Result<(), TransactionValidityError> { + let next_len = Self::check_block_length(info, len)?; let next_weight = Self::check_block_weight(info)?; - // Extrinsic weight already checked in `validate`. + Self::check_extrinsic_weight(info)?; crate::AllExtrinsicsLen::::put(next_len); crate::BlockWeight::::put(next_weight); Ok(()) } + + /// Do the validate checks. This can be applied to both signed and unsigned. + /// + /// It only checks that the block weight and length limit will not exceed. + pub fn do_validate(info: &DispatchInfoOf, len: usize) -> TransactionValidity { + // ignore the next length. If they return `Ok`, then it is below the limit. + let _ = Self::check_block_length(info, len)?; + // during validation we skip block limit check. Since the `validate_transaction` + // call runs on an empty block anyway, by this we prevent `on_initialize` weight + // consumption from causing false negatives. + Self::check_extrinsic_weight(info)?; + + Ok(Default::default()) + } } pub fn calculate_consumed_weight( @@ -208,55 +201,62 @@ where Ok(all_weight) } -impl TransactionExtensionBase for CheckWeight { - const IDENTIFIER: &'static str = "CheckWeight"; - type Implicit = (); - - fn weight(&self) -> Weight { - ::check_weight() - } -} -impl TransactionExtension - for CheckWeight +impl SignedExtension for CheckWeight where T::RuntimeCall: Dispatchable, { + type AccountId = T::AccountId; + type Call = T::RuntimeCall; + type AdditionalSigned = (); type Pre = (); - type Val = u32; /* next block length */ + const IDENTIFIER: &'static str = "CheckWeight"; + + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { + Ok(()) + } + + fn pre_dispatch( + self, + _who: &Self::AccountId, + _call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result<(), TransactionValidityError> { + Self::do_pre_dispatch(info, len) + } fn validate( &self, - origin: T::RuntimeOrigin, - _call: &T::RuntimeCall, - info: &DispatchInfoOf, + _who: &Self::AccountId, + _call: &Self::Call, + info: &DispatchInfoOf, len: usize, - _context: &mut Context, - _self_implicit: Self::Implicit, - _inherited_implication: &impl Encode, - ) -> ValidateResult { - let (validity, next_len) = Self::do_validate(info, len)?; - Ok((validity, next_len, origin)) + ) -> TransactionValidity { + Self::do_validate(info, len) } - fn prepare( - self, - val: Self::Val, - _origin: &T::RuntimeOrigin, - _call: &T::RuntimeCall, - info: &DispatchInfoOf, - _len: usize, - _context: &Context, - ) -> Result { - Self::do_prepare(info, val) + fn pre_dispatch_unsigned( + _call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result<(), TransactionValidityError> { + Self::do_pre_dispatch(info, len) + } + + fn validate_unsigned( + _call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> TransactionValidity { + Self::do_validate(info, len) } fn post_dispatch( - _pre: Self::Pre, - info: &DispatchInfoOf, - post_info: &PostDispatchInfoOf, + _pre: Option, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, _len: usize, _result: &DispatchResult, - _context: &Context, ) -> Result<(), TransactionValidityError> { let unspent = post_info.calc_unspent(info); if unspent.any_gt(Weight::zero()) { @@ -301,7 +301,6 @@ mod tests { AllExtrinsicsLen, BlockWeight, DispatchClass, }; use frame_support::{assert_err, assert_ok, dispatch::Pays, weights::Weight}; - use sp_runtime::traits::DispatchTransaction; use sp_std::marker::PhantomData; fn block_weights() -> crate::limits::BlockWeights { @@ -339,8 +338,7 @@ mod tests { } check(|max, len| { - let next_len = CheckWeight::::check_block_length(max, len).unwrap(); - assert_ok!(CheckWeight::::do_prepare(max, next_len)); + assert_ok!(CheckWeight::::do_pre_dispatch(max, len)); assert_eq!(System::block_weight().total(), Weight::MAX); assert!(System::block_weight().total().ref_time() > block_weight_limit().ref_time()); }); @@ -421,11 +419,9 @@ mod tests { let len = 0_usize; - let next_len = CheckWeight::::check_block_length(&max_normal, len).unwrap(); - assert_ok!(CheckWeight::::do_prepare(&max_normal, next_len)); + assert_ok!(CheckWeight::::do_pre_dispatch(&max_normal, len)); assert_eq!(System::block_weight().total(), Weight::from_parts(768, 0)); - let next_len = CheckWeight::::check_block_length(&rest_operational, len).unwrap(); - assert_ok!(CheckWeight::::do_prepare(&rest_operational, next_len)); + assert_ok!(CheckWeight::::do_pre_dispatch(&rest_operational, len)); assert_eq!(block_weight_limit(), Weight::from_parts(1024, u64::MAX)); assert_eq!(System::block_weight().total(), block_weight_limit().set_proof_size(0)); // Checking single extrinsic should not take current block weight into account. @@ -447,12 +443,10 @@ mod tests { let len = 0_usize; - let next_len = CheckWeight::::check_block_length(&rest_operational, len).unwrap(); - assert_ok!(CheckWeight::::do_prepare(&rest_operational, next_len)); + assert_ok!(CheckWeight::::do_pre_dispatch(&rest_operational, len)); // Extra 20 here from block execution + base extrinsic weight assert_eq!(System::block_weight().total(), Weight::from_parts(266, 0)); - let next_len = CheckWeight::::check_block_length(&max_normal, len).unwrap(); - assert_ok!(CheckWeight::::do_prepare(&max_normal, next_len)); + assert_ok!(CheckWeight::::do_pre_dispatch(&max_normal, len)); assert_eq!(block_weight_limit(), Weight::from_parts(1024, u64::MAX)); assert_eq!(System::block_weight().total(), block_weight_limit().set_proof_size(0)); }); @@ -475,19 +469,16 @@ mod tests { }; let len = 0_usize; - let next_len = CheckWeight::::check_block_length(&dispatch_normal, len).unwrap(); assert_err!( - CheckWeight::::do_prepare(&dispatch_normal, next_len), + CheckWeight::::do_pre_dispatch(&dispatch_normal, len), InvalidTransaction::ExhaustsResources ); - let next_len = - CheckWeight::::check_block_length(&dispatch_operational, len).unwrap(); // Thank goodness we can still do an operational transaction to possibly save the // blockchain. - assert_ok!(CheckWeight::::do_prepare(&dispatch_operational, next_len)); + assert_ok!(CheckWeight::::do_pre_dispatch(&dispatch_operational, len)); // Not too much though assert_err!( - CheckWeight::::do_prepare(&dispatch_operational, next_len), + CheckWeight::::do_pre_dispatch(&dispatch_operational, len), InvalidTransaction::ExhaustsResources ); // Even with full block, validity of single transaction should be correct. @@ -512,35 +503,21 @@ mod tests { current_weight.set(normal_limit, DispatchClass::Normal) }); // will not fit. - assert_eq!( - CheckWeight::(PhantomData) - .validate_and_prepare(Some(1).into(), CALL, &normal, len) - .unwrap_err(), - InvalidTransaction::ExhaustsResources.into() + assert_err!( + CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &normal, len), + InvalidTransaction::ExhaustsResources ); // will fit. - assert_ok!(CheckWeight::(PhantomData).validate_and_prepare( - Some(1).into(), - CALL, - &op, - len - )); + assert_ok!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &op, len)); // likewise for length limit. let len = 100_usize; AllExtrinsicsLen::::put(normal_length_limit()); - assert_eq!( - CheckWeight::(PhantomData) - .validate_and_prepare(Some(1).into(), CALL, &normal, len) - .unwrap_err(), - InvalidTransaction::ExhaustsResources.into() + assert_err!( + CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &normal, len), + InvalidTransaction::ExhaustsResources ); - assert_ok!(CheckWeight::(PhantomData).validate_and_prepare( - Some(1).into(), - CALL, - &op, - len - )); + assert_ok!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &op, len)); }) } @@ -551,12 +528,7 @@ mod tests { let normal_limit = normal_weight_limit().ref_time() as usize; let reset_check_weight = |tx, s, f| { AllExtrinsicsLen::::put(0); - let r = CheckWeight::(PhantomData).validate_and_prepare( - Some(1).into(), - CALL, - tx, - s, - ); + let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, tx, s); if f { assert!(r.is_err()) } else { @@ -599,12 +571,7 @@ mod tests { BlockWeight::::mutate(|current_weight| { current_weight.set(s, DispatchClass::Normal) }); - let r = CheckWeight::(PhantomData).validate_and_prepare( - Some(1).into(), - CALL, - i, - len, - ); + let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, i, len); if f { assert!(r.is_err()) } else { @@ -637,22 +604,18 @@ mod tests { .set(Weight::from_parts(256, 0) - base_extrinsic, DispatchClass::Normal); }); - let pre = CheckWeight::(PhantomData) - .validate_and_prepare(Some(1).into(), CALL, &info, len) - .unwrap() - .0; + let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); assert_eq!( BlockWeight::::get().total(), info.weight + Weight::from_parts(256, 0) ); assert_ok!(CheckWeight::::post_dispatch( - pre, + Some(pre), &info, &post_info, len, - &Ok(()), - &() + &Ok(()) )); assert_eq!( BlockWeight::::get().total(), @@ -676,10 +639,7 @@ mod tests { current_weight.set(Weight::from_parts(128, 0), DispatchClass::Normal); }); - let pre = CheckWeight::(PhantomData) - .validate_and_prepare(Some(1).into(), CALL, &info, len) - .unwrap() - .0; + let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); assert_eq!( BlockWeight::::get().total(), info.weight + @@ -688,12 +648,11 @@ mod tests { ); assert_ok!(CheckWeight::::post_dispatch( - pre, + Some(pre), &info, &post_info, len, - &Ok(()), - &() + &Ok(()) )); assert_eq!( BlockWeight::::get().total(), @@ -713,12 +672,7 @@ mod tests { // Initial weight from `weights.base_block` assert_eq!(System::block_weight().total(), weights.base_block); - assert_ok!(CheckWeight::(PhantomData).validate_and_prepare( - Some(1).into(), - CALL, - &free, - len - )); + assert_ok!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &free, len)); assert_eq!( System::block_weight().total(), weights.get(DispatchClass::Normal).base_extrinsic + weights.base_block @@ -742,11 +696,9 @@ mod tests { let len = 0_usize; - let next_len = CheckWeight::::check_block_length(&max_normal, len).unwrap(); - assert_ok!(CheckWeight::::do_prepare(&max_normal, next_len)); + assert_ok!(CheckWeight::::do_pre_dispatch(&max_normal, len)); assert_eq!(System::block_weight().total(), Weight::from_parts(768, 0)); - let next_len = CheckWeight::::check_block_length(&mandatory, len).unwrap(); - assert_ok!(CheckWeight::::do_prepare(&mandatory, next_len)); + assert_ok!(CheckWeight::::do_pre_dispatch(&mandatory, len)); assert_eq!(block_weight_limit(), Weight::from_parts(1024, u64::MAX)); assert_eq!(System::block_weight().total(), Weight::from_parts(1024 + 768, 0)); assert_eq!(CheckWeight::::check_extrinsic_weight(&mandatory), Ok(())); diff --git a/substrate/frame/system/src/extensions/mod.rs b/substrate/frame/system/src/extensions/mod.rs index d79104d2240..a88c9fbf96e 100644 --- a/substrate/frame/system/src/extensions/mod.rs +++ b/substrate/frame/system/src/extensions/mod.rs @@ -22,6 +22,3 @@ pub mod check_nonce; pub mod check_spec_version; pub mod check_tx_version; pub mod check_weight; -pub mod weights; - -pub use weights::WeightInfo; diff --git a/substrate/frame/system/src/extensions/weights.rs b/substrate/frame/system/src/extensions/weights.rs deleted file mode 100644 index 0d2fcb15ee6..00000000000 --- a/substrate/frame/system/src/extensions/weights.rs +++ /dev/null @@ -1,196 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// 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. - -//! Autogenerated weights for `frame_system_extensions` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` - -// Executed Command: -// ./target/production/substrate-node -// benchmark -// pallet -// --chain=dev -// --steps=50 -// --repeat=20 -// --pallet=frame_system_extensions -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --wasm-execution=compiled -// --heap-pages=4096 -// --output=./substrate/frame/system/src/extensions/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; -use core::marker::PhantomData; - -/// Weight functions needed for `frame_system_extensions`. -pub trait WeightInfo { - fn check_genesis() -> Weight; - fn check_mortality() -> Weight; - fn check_non_zero_sender() -> Weight; - fn check_nonce() -> Weight; - fn check_spec_version() -> Weight; - fn check_tx_version() -> Weight; - fn check_weight() -> Weight; -} - -/// Weights for `frame_system_extensions` using the Substrate node and recommended hardware. -pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_genesis() -> Weight { - // Proof Size summary in bytes: - // Measured: `54` - // Estimated: `3509` - // Minimum execution time: 3_876_000 picoseconds. - Weight::from_parts(4_160_000, 3509) - .saturating_add(T::DbWeight::get().reads(1_u64)) - } - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_mortality() -> Weight { - // Proof Size summary in bytes: - // Measured: `92` - // Estimated: `3509` - // Minimum execution time: 6_296_000 picoseconds. - Weight::from_parts(6_523_000, 3509) - .saturating_add(T::DbWeight::get().reads(1_u64)) - } - fn check_non_zero_sender() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 449_000 picoseconds. - Weight::from_parts(527_000, 0) - } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn check_nonce() -> Weight { - // Proof Size summary in bytes: - // Measured: `101` - // Estimated: `3593` - // Minimum execution time: 5_689_000 picoseconds. - Weight::from_parts(6_000_000, 3593) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } - fn check_spec_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 399_000 picoseconds. - Weight::from_parts(461_000, 0) - } - fn check_tx_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 390_000 picoseconds. - Weight::from_parts(439_000, 0) - } - /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) - /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - fn check_weight() -> Weight { - // Proof Size summary in bytes: - // Measured: `24` - // Estimated: `1489` - // Minimum execution time: 4_375_000 picoseconds. - Weight::from_parts(4_747_000, 1489) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } -} - -// For backwards compatibility and tests. -impl WeightInfo for () { - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_genesis() -> Weight { - // Proof Size summary in bytes: - // Measured: `54` - // Estimated: `3509` - // Minimum execution time: 3_876_000 picoseconds. - Weight::from_parts(4_160_000, 3509) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - } - /// Storage: `System::BlockHash` (r:1 w:0) - /// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - fn check_mortality() -> Weight { - // Proof Size summary in bytes: - // Measured: `92` - // Estimated: `3509` - // Minimum execution time: 6_296_000 picoseconds. - Weight::from_parts(6_523_000, 3509) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - } - fn check_non_zero_sender() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 449_000 picoseconds. - Weight::from_parts(527_000, 0) - } - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - fn check_nonce() -> Weight { - // Proof Size summary in bytes: - // Measured: `101` - // Estimated: `3593` - // Minimum execution time: 5_689_000 picoseconds. - Weight::from_parts(6_000_000, 3593) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - } - fn check_spec_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 399_000 picoseconds. - Weight::from_parts(461_000, 0) - } - fn check_tx_version() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 390_000 picoseconds. - Weight::from_parts(439_000, 0) - } - /// Storage: `System::AllExtrinsicsLen` (r:1 w:1) - /// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - fn check_weight() -> Weight { - // Proof Size summary in bytes: - // Measured: `24` - // Estimated: `1489` - // Minimum execution time: 4_375_000 picoseconds. - Weight::from_parts(4_747_000, 1489) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - } -} diff --git a/substrate/frame/system/src/lib.rs b/substrate/frame/system/src/lib.rs index 0318f77342e..184f27b61ed 100644 --- a/substrate/frame/system/src/lib.rs +++ b/substrate/frame/system/src/lib.rs @@ -166,7 +166,7 @@ pub use extensions::{ check_genesis::CheckGenesis, check_mortality::CheckMortality, check_non_zero_sender::CheckNonZeroSender, check_nonce::CheckNonce, check_spec_version::CheckSpecVersion, check_tx_version::CheckTxVersion, - check_weight::CheckWeight, WeightInfo as ExtensionsWeightInfo, + check_weight::CheckWeight, }; // Backward compatible re-export. pub use extensions::check_mortality::CheckMortality as CheckEra; @@ -284,7 +284,6 @@ pub mod pallet { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); - type ExtensionsWeightInfo = (); type SS58Prefix = (); type Version = (); type BlockWeights = (); @@ -357,9 +356,6 @@ pub mod pallet { /// Weight information for the extrinsics of this pallet. type SystemWeightInfo = (); - /// Weight information for the extensions of this pallet. - type ExtensionsWeightInfo = (); - /// This is used as an identifier of the chain. type SS58Prefix = (); @@ -567,12 +563,8 @@ pub mod pallet { /// All resources should be cleaned up associated with the given account. type OnKilledAccount: OnKilledAccount; - /// Weight information for the extrinsics of this pallet. type SystemWeightInfo: WeightInfo; - /// Weight information for the transaction extensions of this pallet. - type ExtensionsWeightInfo: extensions::WeightInfo; - /// The designated SS58 prefix of this chain. /// /// This replaces the "ss58Format" property declared in the chain spec. Reason is diff --git a/substrate/frame/system/src/offchain.rs b/substrate/frame/system/src/offchain.rs index ee73e33fe31..a019cfd666e 100644 --- a/substrate/frame/system/src/offchain.rs +++ b/substrate/frame/system/src/offchain.rs @@ -79,9 +79,6 @@ pub struct SubmitTransaction, Overarchi _phantom: sp_std::marker::PhantomData<(T, OverarchingCall)>, } -// TODO [#2415]: Avoid splitting call and the totally opaque `signature`; `CreateTransaction` trait -// should provide something which impls `Encode`, which can be sent onwards to -// `sp_io::offchain::submit_transaction`. There's no great need to split things up as in here. impl SubmitTransaction where T: SendTransactionTypes, @@ -91,8 +88,6 @@ where call: >::OverarchingCall, signature: Option<::SignaturePayload>, ) -> Result<(), ()> { - // TODO: Use regular transaction API instead. - #[allow(deprecated)] let xt = T::Extrinsic::new(call, signature).ok_or(())?; sp_io::offchain::submit_transaction(xt.encode()) } @@ -476,7 +471,7 @@ pub trait SendTransactionTypes { /// /// This trait is meant to be implemented by the runtime and is responsible for constructing /// a payload to be signed and contained within the extrinsic. -/// This will most likely include creation of `TxExtension` (a tuple of `TransactionExtension`s). +/// This will most likely include creation of `SignedExtra` (a set of `SignedExtensions`). /// Note that the result can be altered by inspecting the `Call` (for instance adjusting /// fees, or mortality depending on the `pallet` being called). pub trait CreateSignedTransaction: @@ -626,17 +621,14 @@ mod tests { use crate::mock::{RuntimeCall, Test as TestRuntime, CALL}; use codec::Decode; use sp_core::offchain::{testing, TransactionPoolExt}; - use sp_runtime::{ - generic::UncheckedExtrinsic, - testing::{TestSignature, UintAuthorityId}, - }; + use sp_runtime::testing::{TestSignature, TestXt, UintAuthorityId}; impl SigningTypes for TestRuntime { type Public = UintAuthorityId; type Signature = TestSignature; } - type Extrinsic = UncheckedExtrinsic; + type Extrinsic = TestXt; impl SendTransactionTypes for TestRuntime { type Extrinsic = Extrinsic; @@ -701,7 +693,7 @@ mod tests { let _tx3 = pool_state.write().transactions.pop().unwrap(); assert!(pool_state.read().transactions.is_empty()); let tx1 = Extrinsic::decode(&mut &*tx1).unwrap(); - assert!(tx1.is_inherent()); + assert_eq!(tx1.signature, None); }); } @@ -732,7 +724,7 @@ mod tests { let tx1 = pool_state.write().transactions.pop().unwrap(); assert!(pool_state.read().transactions.is_empty()); let tx1 = Extrinsic::decode(&mut &*tx1).unwrap(); - assert!(tx1.is_inherent()); + assert_eq!(tx1.signature, None); }); } @@ -766,7 +758,7 @@ mod tests { let _tx2 = pool_state.write().transactions.pop().unwrap(); assert!(pool_state.read().transactions.is_empty()); let tx1 = Extrinsic::decode(&mut &*tx1).unwrap(); - assert!(tx1.is_inherent()); + assert_eq!(tx1.signature, None); }); } @@ -798,7 +790,7 @@ mod tests { let tx1 = pool_state.write().transactions.pop().unwrap(); assert!(pool_state.read().transactions.is_empty()); let tx1 = Extrinsic::decode(&mut &*tx1).unwrap(); - assert!(tx1.is_inherent()); + assert_eq!(tx1.signature, None); }); } } diff --git a/substrate/frame/system/src/weights.rs b/substrate/frame/system/src/weights.rs index bd64bbf3763..41807dea1c5 100644 --- a/substrate/frame/system/src/weights.rs +++ b/substrate/frame/system/src/weights.rs @@ -15,31 +15,30 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `frame_system` +//! Autogenerated weights for frame_system //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-s7kdgajz-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// target/production/substrate // benchmark // pallet -// --chain=dev // --steps=50 // --repeat=20 -// --pallet=frame_system -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/system/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --json-file=/builds/parity/mirrors/substrate/.git/.artifacts/bench.json +// --pallet=frame-system +// --chain=dev +// --header=./HEADER-APACHE2 +// --output=./frame/system/src/weights.rs +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +48,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `frame_system`. +/// Weight functions needed for frame_system. pub trait WeightInfo { fn remark(b: u32, ) -> Weight; fn remark_with_event(b: u32, ) -> Weight; @@ -62,7 +61,7 @@ pub trait WeightInfo { fn apply_authorized_upgrade() -> Weight; } -/// Weights for `frame_system` using the Substrate node and recommended hardware. +/// Weights for frame_system using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { /// The range of component `b` is `[0, 3932160]`. @@ -70,86 +69,84 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_130_000 picoseconds. - Weight::from_parts(2_976_430, 0) + // Minimum execution time: 2_004_000 picoseconds. + Weight::from_parts(2_119_000, 0) // Standard Error: 0 - .saturating_add(Weight::from_parts(386, 0).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(390, 0).saturating_mul(b.into())) } /// The range of component `b` is `[0, 3932160]`. fn remark_with_event(b: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_690_000 picoseconds. - Weight::from_parts(15_071_416, 0) - // Standard Error: 1 - .saturating_add(Weight::from_parts(1_387, 0).saturating_mul(b.into())) + // Minimum execution time: 8_032_000 picoseconds. + Weight::from_parts(8_097_000, 0) + // Standard Error: 2 + .saturating_add(Weight::from_parts(1_455, 0).saturating_mul(b.into())) } - /// Storage: `System::Digest` (r:1 w:1) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x3a686561707061676573` (r:0 w:1) - /// Proof: UNKNOWN KEY `0x3a686561707061676573` (r:0 w:1) + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a686561707061676573` (r:0 w:1) + /// Proof Skipped: unknown `0x3a686561707061676573` (r:0 w:1) fn set_heap_pages() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `1485` - // Minimum execution time: 3_822_000 picoseconds. - Weight::from_parts(4_099_000, 1485) + // Minimum execution time: 4_446_000 picoseconds. + Weight::from_parts(4_782_000, 1485) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) - /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:1) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) - /// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a636f6465` (r:0 w:1) + /// Proof Skipped: unknown `0x3a636f6465` (r:0 w:1) fn set_code() -> Weight { // Proof Size summary in bytes: - // Measured: `142` - // Estimated: `67035` - // Minimum execution time: 81_512_045_000 picoseconds. - Weight::from_parts(82_321_281_000, 67035) - .saturating_add(T::DbWeight::get().reads(2_u64)) + // Measured: `0` + // Estimated: `1485` + // Minimum execution time: 84_000_503_000 picoseconds. + Weight::from_parts(87_586_619_000, 1485) + .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Skipped::Metadata` (r:0 w:0) - /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) /// The range of component `i` is `[0, 1000]`. fn set_storage(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_074_000 picoseconds. - Weight::from_parts(2_137_000, 0) - // Standard Error: 879 - .saturating_add(Weight::from_parts(797_224, 0).saturating_mul(i.into())) + // Minimum execution time: 2_086_000 picoseconds. + Weight::from_parts(2_175_000, 0) + // Standard Error: 1_056 + .saturating_add(Weight::from_parts(841_511, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) } - /// Storage: `Skipped::Metadata` (r:0 w:0) - /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) /// The range of component `i` is `[0, 1000]`. fn kill_storage(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_122_000 picoseconds. - Weight::from_parts(2_208_000, 0) - // Standard Error: 855 - .saturating_add(Weight::from_parts(594_034, 0).saturating_mul(i.into())) + // Minimum execution time: 2_000_000 picoseconds. + Weight::from_parts(2_255_000, 0) + // Standard Error: 1_425 + .saturating_add(Weight::from_parts(662_473, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) } - /// Storage: `Skipped::Metadata` (r:0 w:0) - /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) /// The range of component `p` is `[0, 1000]`. fn kill_prefix(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `129 + p * (69 ±0)` - // Estimated: `135 + p * (70 ±0)` - // Minimum execution time: 3_992_000 picoseconds. - Weight::from_parts(4_170_000, 135) - // Standard Error: 1_377 - .saturating_add(Weight::from_parts(1_267_892, 0).saturating_mul(p.into())) + // Measured: `115 + p * (69 ±0)` + // Estimated: `128 + p * (70 ±0)` + // Minimum execution time: 4_189_000 picoseconds. + Weight::from_parts(4_270_000, 128) + // Standard Error: 2_296 + .saturating_add(Weight::from_parts(1_389_650, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) .saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into())) @@ -160,116 +157,114 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_872_000 picoseconds. - Weight::from_parts(9_513_000, 0) - .saturating_add(T::DbWeight::get().writes(1_u64)) + // Minimum execution time: 33_027_000 picoseconds. + Weight::from_parts(33_027_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `System::AuthorizedUpgrade` (r:1 w:1) /// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) - /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) - /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) /// Storage: `System::Digest` (r:1 w:1) /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) /// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) fn apply_authorized_upgrade() -> Weight { // Proof Size summary in bytes: - // Measured: `164` - // Estimated: `67035` - // Minimum execution time: 85_037_546_000 picoseconds. - Weight::from_parts(85_819_414_000, 67035) - .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) + // Measured: `22` + // Estimated: `1518` + // Minimum execution time: 118_101_992_000 picoseconds. + Weight::from_parts(118_101_992_000, 0) + .saturating_add(Weight::from_parts(0, 1518)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(3)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { /// The range of component `b` is `[0, 3932160]`. fn remark(b: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_130_000 picoseconds. - Weight::from_parts(2_976_430, 0) + // Minimum execution time: 2_004_000 picoseconds. + Weight::from_parts(2_119_000, 0) // Standard Error: 0 - .saturating_add(Weight::from_parts(386, 0).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(390, 0).saturating_mul(b.into())) } /// The range of component `b` is `[0, 3932160]`. fn remark_with_event(b: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_690_000 picoseconds. - Weight::from_parts(15_071_416, 0) - // Standard Error: 1 - .saturating_add(Weight::from_parts(1_387, 0).saturating_mul(b.into())) + // Minimum execution time: 8_032_000 picoseconds. + Weight::from_parts(8_097_000, 0) + // Standard Error: 2 + .saturating_add(Weight::from_parts(1_455, 0).saturating_mul(b.into())) } - /// Storage: `System::Digest` (r:1 w:1) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x3a686561707061676573` (r:0 w:1) - /// Proof: UNKNOWN KEY `0x3a686561707061676573` (r:0 w:1) + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a686561707061676573` (r:0 w:1) + /// Proof Skipped: unknown `0x3a686561707061676573` (r:0 w:1) fn set_heap_pages() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `1485` - // Minimum execution time: 3_822_000 picoseconds. - Weight::from_parts(4_099_000, 1485) + // Minimum execution time: 4_446_000 picoseconds. + Weight::from_parts(4_782_000, 1485) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) - /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:1) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) - /// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) + /// Storage: System Digest (r:1 w:1) + /// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: unknown `0x3a636f6465` (r:0 w:1) + /// Proof Skipped: unknown `0x3a636f6465` (r:0 w:1) fn set_code() -> Weight { // Proof Size summary in bytes: - // Measured: `142` - // Estimated: `67035` - // Minimum execution time: 81_512_045_000 picoseconds. - Weight::from_parts(82_321_281_000, 67035) - .saturating_add(RocksDbWeight::get().reads(2_u64)) + // Measured: `0` + // Estimated: `1485` + // Minimum execution time: 84_000_503_000 picoseconds. + Weight::from_parts(87_586_619_000, 1485) + .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Skipped::Metadata` (r:0 w:0) - /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) /// The range of component `i` is `[0, 1000]`. fn set_storage(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_074_000 picoseconds. - Weight::from_parts(2_137_000, 0) - // Standard Error: 879 - .saturating_add(Weight::from_parts(797_224, 0).saturating_mul(i.into())) + // Minimum execution time: 2_086_000 picoseconds. + Weight::from_parts(2_175_000, 0) + // Standard Error: 1_056 + .saturating_add(Weight::from_parts(841_511, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(i.into()))) } - /// Storage: `Skipped::Metadata` (r:0 w:0) - /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) /// The range of component `i` is `[0, 1000]`. fn kill_storage(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_122_000 picoseconds. - Weight::from_parts(2_208_000, 0) - // Standard Error: 855 - .saturating_add(Weight::from_parts(594_034, 0).saturating_mul(i.into())) + // Minimum execution time: 2_000_000 picoseconds. + Weight::from_parts(2_255_000, 0) + // Standard Error: 1_425 + .saturating_add(Weight::from_parts(662_473, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(i.into()))) } - /// Storage: `Skipped::Metadata` (r:0 w:0) - /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Skipped Metadata (r:0 w:0) + /// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured) /// The range of component `p` is `[0, 1000]`. fn kill_prefix(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `129 + p * (69 ±0)` - // Estimated: `135 + p * (70 ±0)` - // Minimum execution time: 3_992_000 picoseconds. - Weight::from_parts(4_170_000, 135) - // Standard Error: 1_377 - .saturating_add(Weight::from_parts(1_267_892, 0).saturating_mul(p.into())) + // Measured: `115 + p * (69 ±0)` + // Estimated: `128 + p * (70 ±0)` + // Minimum execution time: 4_189_000 picoseconds. + Weight::from_parts(4_270_000, 128) + // Standard Error: 2_296 + .saturating_add(Weight::from_parts(1_389_650, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(p.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(p.into()))) .saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into())) @@ -280,25 +275,25 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_872_000 picoseconds. - Weight::from_parts(9_513_000, 0) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + // Minimum execution time: 33_027_000 picoseconds. + Weight::from_parts(33_027_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(RocksDbWeight::get().writes(1)) } /// Storage: `System::AuthorizedUpgrade` (r:1 w:1) /// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) - /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) - /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) /// Storage: `System::Digest` (r:1 w:1) /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) /// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) fn apply_authorized_upgrade() -> Weight { // Proof Size summary in bytes: - // Measured: `164` - // Estimated: `67035` - // Minimum execution time: 85_037_546_000 picoseconds. - Weight::from_parts(85_819_414_000, 67035) - .saturating_add(RocksDbWeight::get().reads(3_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) + // Measured: `22` + // Estimated: `1518` + // Minimum execution time: 118_101_992_000 picoseconds. + Weight::from_parts(118_101_992_000, 0) + .saturating_add(Weight::from_parts(0, 1518)) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(3)) } } diff --git a/substrate/frame/timestamp/src/weights.rs b/substrate/frame/timestamp/src/weights.rs index 2df68ba0f1e..46c54473486 100644 --- a/substrate/frame/timestamp/src/weights.rs +++ b/substrate/frame/timestamp/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_timestamp` +//! Autogenerated weights for pallet_timestamp //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/timestamp/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/timestamp/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,57 +50,57 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_timestamp`. +/// Weight functions needed for pallet_timestamp. pub trait WeightInfo { fn set() -> Weight; fn on_finalize() -> Weight; } -/// Weights for `pallet_timestamp` using the Substrate node and recommended hardware. +/// Weights for pallet_timestamp using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Timestamp::Now` (r:1 w:1) - /// Proof: `Timestamp::Now` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Babe::CurrentSlot` (r:1 w:0) - /// Proof: `Babe::CurrentSlot` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: Timestamp Now (r:1 w:1) + /// Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe CurrentSlot (r:1 w:0) + /// Proof: Babe CurrentSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) fn set() -> Weight { // Proof Size summary in bytes: - // Measured: `345` + // Measured: `312` // Estimated: `1493` - // Minimum execution time: 8_417_000 picoseconds. - Weight::from_parts(8_932_000, 1493) + // Minimum execution time: 9_857_000 picoseconds. + Weight::from_parts(10_492_000, 1493) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } fn on_finalize() -> Weight { // Proof Size summary in bytes: - // Measured: `194` + // Measured: `161` // Estimated: `0` - // Minimum execution time: 3_911_000 picoseconds. - Weight::from_parts(4_092_000, 0) + // Minimum execution time: 4_175_000 picoseconds. + Weight::from_parts(4_334_000, 0) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Timestamp::Now` (r:1 w:1) - /// Proof: `Timestamp::Now` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) - /// Storage: `Babe::CurrentSlot` (r:1 w:0) - /// Proof: `Babe::CurrentSlot` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: Timestamp Now (r:1 w:1) + /// Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + /// Storage: Babe CurrentSlot (r:1 w:0) + /// Proof: Babe CurrentSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) fn set() -> Weight { // Proof Size summary in bytes: - // Measured: `345` + // Measured: `312` // Estimated: `1493` - // Minimum execution time: 8_417_000 picoseconds. - Weight::from_parts(8_932_000, 1493) + // Minimum execution time: 9_857_000 picoseconds. + Weight::from_parts(10_492_000, 1493) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } fn on_finalize() -> Weight { // Proof Size summary in bytes: - // Measured: `194` + // Measured: `161` // Estimated: `0` - // Minimum execution time: 3_911_000 picoseconds. - Weight::from_parts(4_092_000, 0) + // Minimum execution time: 4_175_000 picoseconds. + Weight::from_parts(4_334_000, 0) } } diff --git a/substrate/frame/tips/src/weights.rs b/substrate/frame/tips/src/weights.rs index dbe1ed246ff..ec622866715 100644 --- a/substrate/frame/tips/src/weights.rs +++ b/substrate/frame/tips/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_tips` +//! Autogenerated weights for pallet_tips //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/tips/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/tips/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_tips`. +/// Weight functions needed for pallet_tips. pub trait WeightInfo { fn report_awesome(r: u32, ) -> Weight; fn retract_tip() -> Weight; @@ -59,220 +60,220 @@ pub trait WeightInfo { fn slash_tip(t: u32, ) -> Weight; } -/// Weights for `pallet_tips` using the Substrate node and recommended hardware. +/// Weights for pallet_tips using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Tips::Reasons` (r:1 w:1) - /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Tips::Tips` (r:1 w:1) - /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Tips Reasons (r:1 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) /// The range of component `r` is `[0, 300]`. fn report_awesome(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `4` // Estimated: `3469` - // Minimum execution time: 25_145_000 picoseconds. - Weight::from_parts(26_085_800, 3469) - // Standard Error: 216 - .saturating_add(Weight::from_parts(5_121, 0).saturating_mul(r.into())) + // Minimum execution time: 29_576_000 picoseconds. + Weight::from_parts(30_722_650, 3469) + // Standard Error: 192 + .saturating_add(Weight::from_parts(2_601, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Tips::Tips` (r:1 w:1) - /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Tips::Reasons` (r:0 w:1) - /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Reasons (r:0 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) fn retract_tip() -> Weight { // Proof Size summary in bytes: // Measured: `221` // Estimated: `3686` - // Minimum execution time: 25_302_000 picoseconds. - Weight::from_parts(26_229_000, 3686) + // Minimum execution time: 28_522_000 picoseconds. + Weight::from_parts(29_323_000, 3686) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Elections::Members` (r:1 w:0) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Tips::Reasons` (r:1 w:1) - /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Tips::Tips` (r:0 w:1) - /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Elections Members (r:1 w:0) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Tips Reasons (r:1 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Tips (r:0 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) /// The range of component `r` is `[0, 300]`. /// The range of component `t` is `[1, 13]`. fn tip_new(r: u32, t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `526 + t * (64 ±0)` // Estimated: `3991 + t * (64 ±0)` - // Minimum execution time: 16_600_000 picoseconds. - Weight::from_parts(17_071_638, 3991) - // Standard Error: 131 - .saturating_add(Weight::from_parts(1_138, 0).saturating_mul(r.into())) - // Standard Error: 3_125 - .saturating_add(Weight::from_parts(82_996, 0).saturating_mul(t.into())) + // Minimum execution time: 19_650_000 picoseconds. + Weight::from_parts(19_837_982, 3991) + // Standard Error: 151 + .saturating_add(Weight::from_parts(1_746, 0).saturating_mul(r.into())) + // Standard Error: 3_588 + .saturating_add(Weight::from_parts(102_359, 0).saturating_mul(t.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(t.into())) } - /// Storage: `Elections::Members` (r:1 w:0) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Tips::Tips` (r:1 w:1) - /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Elections Members (r:1 w:0) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) /// The range of component `t` is `[1, 13]`. fn tip(t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `747 + t * (112 ±0)` // Estimated: `4212 + t * (112 ±0)` - // Minimum execution time: 13_972_000 picoseconds. - Weight::from_parts(14_269_356, 4212) - // Standard Error: 4_695 - .saturating_add(Weight::from_parts(205_433, 0).saturating_mul(t.into())) + // Minimum execution time: 15_641_000 picoseconds. + Weight::from_parts(15_745_460, 4212) + // Standard Error: 5_106 + .saturating_add(Weight::from_parts(229_475, 0).saturating_mul(t.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(t.into())) } - /// Storage: `Tips::Tips` (r:1 w:1) - /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Members` (r:1 w:0) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Tips::Reasons` (r:0 w:1) - /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: Elections Members (r:1 w:0) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Tips Reasons (r:0 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) /// The range of component `t` is `[1, 13]`. fn close_tip(t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `786 + t * (112 ±0)` // Estimated: `4242 + t * (112 ±0)` - // Minimum execution time: 51_878_000 picoseconds. - Weight::from_parts(54_513_477, 4242) - // Standard Error: 12_281 - .saturating_add(Weight::from_parts(126_605, 0).saturating_mul(t.into())) + // Minimum execution time: 62_059_000 picoseconds. + Weight::from_parts(64_604_554, 4242) + // Standard Error: 11_818 + .saturating_add(Weight::from_parts(116_297, 0).saturating_mul(t.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(t.into())) } - /// Storage: `Tips::Tips` (r:1 w:1) - /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Tips::Reasons` (r:0 w:1) - /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Reasons (r:0 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) /// The range of component `t` is `[1, 13]`. fn slash_tip(t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `269` // Estimated: `3734` - // Minimum execution time: 11_800_000 picoseconds. - Weight::from_parts(12_520_984, 3734) - // Standard Error: 2_360 - .saturating_add(Weight::from_parts(28_777, 0).saturating_mul(t.into())) + // Minimum execution time: 14_133_000 picoseconds. + Weight::from_parts(14_957_547, 3734) + // Standard Error: 2_765 + .saturating_add(Weight::from_parts(22_138, 0).saturating_mul(t.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Tips::Reasons` (r:1 w:1) - /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Tips::Tips` (r:1 w:1) - /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Tips Reasons (r:1 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) /// The range of component `r` is `[0, 300]`. fn report_awesome(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `4` // Estimated: `3469` - // Minimum execution time: 25_145_000 picoseconds. - Weight::from_parts(26_085_800, 3469) - // Standard Error: 216 - .saturating_add(Weight::from_parts(5_121, 0).saturating_mul(r.into())) + // Minimum execution time: 29_576_000 picoseconds. + Weight::from_parts(30_722_650, 3469) + // Standard Error: 192 + .saturating_add(Weight::from_parts(2_601, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Tips::Tips` (r:1 w:1) - /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Tips::Reasons` (r:0 w:1) - /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Reasons (r:0 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) fn retract_tip() -> Weight { // Proof Size summary in bytes: // Measured: `221` // Estimated: `3686` - // Minimum execution time: 25_302_000 picoseconds. - Weight::from_parts(26_229_000, 3686) + // Minimum execution time: 28_522_000 picoseconds. + Weight::from_parts(29_323_000, 3686) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Elections::Members` (r:1 w:0) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Tips::Reasons` (r:1 w:1) - /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Tips::Tips` (r:0 w:1) - /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Elections Members (r:1 w:0) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Tips Reasons (r:1 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Tips (r:0 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) /// The range of component `r` is `[0, 300]`. /// The range of component `t` is `[1, 13]`. fn tip_new(r: u32, t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `526 + t * (64 ±0)` // Estimated: `3991 + t * (64 ±0)` - // Minimum execution time: 16_600_000 picoseconds. - Weight::from_parts(17_071_638, 3991) - // Standard Error: 131 - .saturating_add(Weight::from_parts(1_138, 0).saturating_mul(r.into())) - // Standard Error: 3_125 - .saturating_add(Weight::from_parts(82_996, 0).saturating_mul(t.into())) + // Minimum execution time: 19_650_000 picoseconds. + Weight::from_parts(19_837_982, 3991) + // Standard Error: 151 + .saturating_add(Weight::from_parts(1_746, 0).saturating_mul(r.into())) + // Standard Error: 3_588 + .saturating_add(Weight::from_parts(102_359, 0).saturating_mul(t.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(t.into())) } - /// Storage: `Elections::Members` (r:1 w:0) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Tips::Tips` (r:1 w:1) - /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Elections Members (r:1 w:0) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) /// The range of component `t` is `[1, 13]`. fn tip(t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `747 + t * (112 ±0)` // Estimated: `4212 + t * (112 ±0)` - // Minimum execution time: 13_972_000 picoseconds. - Weight::from_parts(14_269_356, 4212) - // Standard Error: 4_695 - .saturating_add(Weight::from_parts(205_433, 0).saturating_mul(t.into())) + // Minimum execution time: 15_641_000 picoseconds. + Weight::from_parts(15_745_460, 4212) + // Standard Error: 5_106 + .saturating_add(Weight::from_parts(229_475, 0).saturating_mul(t.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(t.into())) } - /// Storage: `Tips::Tips` (r:1 w:1) - /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Elections::Members` (r:1 w:0) - /// Proof: `Elections::Members` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Tips::Reasons` (r:0 w:1) - /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: Elections Members (r:1 w:0) + /// Proof Skipped: Elections Members (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Tips Reasons (r:0 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) /// The range of component `t` is `[1, 13]`. fn close_tip(t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `786 + t * (112 ±0)` // Estimated: `4242 + t * (112 ±0)` - // Minimum execution time: 51_878_000 picoseconds. - Weight::from_parts(54_513_477, 4242) - // Standard Error: 12_281 - .saturating_add(Weight::from_parts(126_605, 0).saturating_mul(t.into())) + // Minimum execution time: 62_059_000 picoseconds. + Weight::from_parts(64_604_554, 4242) + // Standard Error: 11_818 + .saturating_add(Weight::from_parts(116_297, 0).saturating_mul(t.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(t.into())) } - /// Storage: `Tips::Tips` (r:1 w:1) - /// Proof: `Tips::Tips` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Tips::Reasons` (r:0 w:1) - /// Proof: `Tips::Reasons` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: Tips Tips (r:1 w:1) + /// Proof Skipped: Tips Tips (max_values: None, max_size: None, mode: Measured) + /// Storage: Tips Reasons (r:0 w:1) + /// Proof Skipped: Tips Reasons (max_values: None, max_size: None, mode: Measured) /// The range of component `t` is `[1, 13]`. fn slash_tip(t: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `269` // Estimated: `3734` - // Minimum execution time: 11_800_000 picoseconds. - Weight::from_parts(12_520_984, 3734) - // Standard Error: 2_360 - .saturating_add(Weight::from_parts(28_777, 0).saturating_mul(t.into())) + // Minimum execution time: 14_133_000 picoseconds. + Weight::from_parts(14_957_547, 3734) + // Standard Error: 2_765 + .saturating_add(Weight::from_parts(22_138, 0).saturating_mul(t.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } diff --git a/substrate/frame/transaction-payment/Cargo.toml b/substrate/frame/transaction-payment/Cargo.toml index 66e0bef1436..275e1c01f92 100644 --- a/substrate/frame/transaction-payment/Cargo.toml +++ b/substrate/frame/transaction-payment/Cargo.toml @@ -21,7 +21,6 @@ codec = { package = "parity-scale-codec", version = "3.6.1", default-features = ] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } serde = { optional = true, workspace = true, default-features = true } -frame-benchmarking = { path = "../benchmarking", default-features = false, optional = true } frame-support = { path = "../support", default-features = false } frame-system = { path = "../system", default-features = false } sp-core = { path = "../../primitives/core", default-features = false } @@ -37,7 +36,6 @@ pallet-balances = { path = "../balances" } default = ["std"] std = [ "codec/std", - "frame-benchmarking?/std", "frame-support/std", "frame-system/std", "pallet-balances/std", @@ -48,13 +46,6 @@ std = [ "sp-runtime/std", "sp-std/std", ] -runtime-benchmarks = [ - "frame-benchmarking/runtime-benchmarks", - "frame-support/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "pallet-balances/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", -] try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/Cargo.toml b/substrate/frame/transaction-payment/asset-conversion-tx-payment/Cargo.toml index 528f29e8e4a..7640cc815e5 100644 --- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/Cargo.toml +++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/Cargo.toml @@ -19,7 +19,6 @@ targets = ["x86_64-unknown-linux-gnu"] # Substrate dependencies sp-runtime = { path = "../../../primitives/runtime", default-features = false } sp-std = { path = "../../../primitives/std", default-features = false } -frame-benchmarking = { path = "../../benchmarking", default-features = false, optional = true } frame-support = { path = "../../support", default-features = false } frame-system = { path = "../../system", default-features = false } pallet-asset-conversion = { path = "../../asset-conversion", default-features = false } @@ -38,7 +37,6 @@ pallet-balances = { path = "../../balances" } default = ["std"] std = [ "codec/std", - "frame-benchmarking?/std", "frame-support/std", "frame-system/std", "pallet-asset-conversion/std", @@ -52,16 +50,6 @@ std = [ "sp-std/std", "sp-storage/std", ] -runtime-benchmarks = [ - "frame-benchmarking/runtime-benchmarks", - "frame-support/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "pallet-asset-conversion/runtime-benchmarks", - "pallet-assets/runtime-benchmarks", - "pallet-balances/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", -] try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/README.md b/substrate/frame/transaction-payment/asset-conversion-tx-payment/README.md index fcd1527526e..eccba773673 100644 --- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/README.md +++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/README.md @@ -16,6 +16,6 @@ asset. ### Integration This pallet wraps FRAME's transaction payment pallet and functions as a replacement. This means you should include both pallets in your `construct_runtime` macro, but only include this -pallet's [`TransactionExtension`] ([`ChargeAssetTxPayment`]). +pallet's [`SignedExtension`] ([`ChargeAssetTxPayment`]). License: Apache-2.0 diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/benchmarking.rs b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/benchmarking.rs deleted file mode 100644 index 0bffb991e4a..00000000000 --- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/benchmarking.rs +++ /dev/null @@ -1,125 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// 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. - -//! Benchmarks for Asset Conversion Tx Payment Pallet's transaction extension - -use super::*; -use crate::Pallet; -use frame_benchmarking::v2::*; -use frame_support::{ - dispatch::{DispatchInfo, PostDispatchInfo}, - pallet_prelude::*, -}; -use frame_system::RawOrigin; -use sp_runtime::traits::{AsSystemOriginSigner, DispatchTransaction, Dispatchable}; - -#[benchmarks(where - T::RuntimeCall: Dispatchable, - AssetBalanceOf: Send + Sync, - BalanceOf: Send - + Sync - + From - + Into> - + Into> - + From>, - ChargeAssetIdOf: Send + Sync + Default, - ::RuntimeOrigin: AsSystemOriginSigner + Clone, -)] -mod benchmarks { - use super::*; - - #[benchmark] - fn charge_asset_tx_payment_zero() { - let caller: T::AccountId = whitelisted_caller(); - let ext: ChargeAssetTxPayment = ChargeAssetTxPayment::from(0u64.into(), None); - let inner = frame_system::Call::remark { remark: vec![] }; - let call = T::RuntimeCall::from(inner); - let info = DispatchInfo { - weight: Weight::zero(), - class: DispatchClass::Normal, - pays_fee: Pays::No, - }; - let post_info = PostDispatchInfo { actual_weight: None, pays_fee: Pays::No }; - #[block] - { - assert!(ext - .test_run(RawOrigin::Signed(caller).into(), &call, &info, 0, |_| Ok(post_info)) - .unwrap() - .is_ok()); - } - } - - #[benchmark] - fn charge_asset_tx_payment_native() { - let caller: T::AccountId = whitelisted_caller(); - let (fun_asset_id, _) = ::BenchmarkHelper::create_asset_id_parameter(1); - ::BenchmarkHelper::setup_balances_and_pool(fun_asset_id, caller.clone()); - let ext: ChargeAssetTxPayment = ChargeAssetTxPayment::from(10u64.into(), None); - let inner = frame_system::Call::remark { remark: vec![] }; - let call = T::RuntimeCall::from(inner); - let info = DispatchInfo { - weight: Weight::from_parts(10, 0), - class: DispatchClass::Operational, - pays_fee: Pays::Yes, - }; - let post_info = PostDispatchInfo { - actual_weight: Some(Weight::from_parts(10, 0)), - pays_fee: Pays::Yes, - }; - - #[block] - { - assert!(ext - .test_run(RawOrigin::Signed(caller).into(), &call, &info, 0, |_| Ok(post_info)) - .unwrap() - .is_ok()); - } - } - - #[benchmark] - fn charge_asset_tx_payment_asset() { - let caller: T::AccountId = whitelisted_caller(); - let (fun_asset_id, asset_id) = ::BenchmarkHelper::create_asset_id_parameter(1); - ::BenchmarkHelper::setup_balances_and_pool(fun_asset_id, caller.clone()); - - let tip = 10u64.into(); - let ext: ChargeAssetTxPayment = ChargeAssetTxPayment::from(tip, Some(asset_id)); - let inner = frame_system::Call::remark { remark: vec![] }; - let call = T::RuntimeCall::from(inner); - let info = DispatchInfo { - weight: Weight::from_parts(10, 0), - class: DispatchClass::Operational, - pays_fee: Pays::Yes, - }; - let post_info = PostDispatchInfo { - actual_weight: Some(Weight::from_parts(10, 0)), - pays_fee: Pays::Yes, - }; - - #[block] - { - assert!(ext - .test_run(RawOrigin::Signed(caller.clone()).into(), &call, &info, 0, |_| Ok( - post_info - )) - .unwrap() - .is_ok()); - } - } - - impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Runtime); -} diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/lib.rs b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/lib.rs index 8ef7c2ba38e..ed0ed56e6e0 100644 --- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/lib.rs +++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/lib.rs @@ -20,8 +20,8 @@ //! //! ## Overview //! -//! This pallet provides a `TransactionExtension` with an optional `AssetId` that specifies the -//! asset to be used for payment (defaulting to the native token on `None`). It expects an +//! This pallet provides a `SignedExtension` with an optional `AssetId` that specifies the asset +//! to be used for payment (defaulting to the native token on `None`). It expects an //! [`OnChargeAssetTransaction`] implementation analogous to [`pallet-transaction-payment`]. The //! included [`AssetConversionAdapter`] (implementing [`OnChargeAssetTransaction`]) determines the //! fee amount by converting the fee calculated by [`pallet-transaction-payment`] in the native @@ -31,7 +31,7 @@ //! //! This pallet does not have any dispatchable calls or storage. It wraps FRAME's Transaction //! Payment pallet and functions as a replacement. This means you should include both pallets in -//! your `construct_runtime` macro, but only include this pallet's [`TransactionExtension`] +//! your `construct_runtime` macro, but only include this pallet's [`SignedExtension`] //! ([`ChargeAssetTxPayment`]). //! //! ## Terminology @@ -53,29 +53,23 @@ use frame_support::{ }, DefaultNoBound, }; -use pallet_transaction_payment::{ChargeTransactionPayment, OnChargeTransaction}; +use pallet_transaction_payment::OnChargeTransaction; use scale_info::TypeInfo; use sp_runtime::{ - traits::{ - AsSystemOriginSigner, DispatchInfoOf, Dispatchable, PostDispatchInfoOf, - TransactionExtension, TransactionExtensionBase, ValidateResult, Zero, + traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf, SignedExtension, Zero}, + transaction_validity::{ + InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction, }, - transaction_validity::{InvalidTransaction, TransactionValidityError, ValidTransaction}, }; #[cfg(test)] mod mock; #[cfg(test)] mod tests; -pub mod weights; - -#[cfg(feature = "runtime-benchmarks")] -mod benchmarking; mod payment; -use frame_support::{pallet_prelude::Weight, traits::tokens::AssetId}; +use frame_support::traits::tokens::AssetId; pub use payment::*; -pub use weights::WeightInfo; /// Type aliases used for interaction with `OnChargeTransaction`. pub(crate) type OnChargeTransactionOf = @@ -131,30 +125,11 @@ pub mod pallet { type Fungibles: Balanced; /// The actual transaction charging logic that charges the fees. type OnChargeAssetTransaction: OnChargeAssetTransaction; - /// The weight information of this pallet. - type WeightInfo: WeightInfo; - #[cfg(feature = "runtime-benchmarks")] - /// Benchmark helper - type BenchmarkHelper: BenchmarkHelperTrait< - Self::AccountId, - <::Fungibles as Inspect>::AssetId, - <::OnChargeAssetTransaction as OnChargeAssetTransaction>::AssetId, - >; } #[pallet::pallet] pub struct Pallet(_); - #[cfg(feature = "runtime-benchmarks")] - /// Helper trait to benchmark the `ChargeAssetTxPayment` transaction extension. - pub trait BenchmarkHelperTrait { - /// Returns the `AssetId` to be used in the liquidity pool by the benchmarking code. - fn create_asset_id_parameter(id: u32) -> (FunAssetIdParameter, AssetIdParameter); - /// Create a liquidity pool for a given asset and sufficiently endow accounts to benchmark - /// the extension. - fn setup_balances_and_pool(asset_id: FunAssetIdParameter, account: AccountId); - } - #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { @@ -204,8 +179,9 @@ where who: &T::AccountId, call: &T::RuntimeCall, info: &DispatchInfoOf, - fee: BalanceOf, + len: usize, ) -> Result<(BalanceOf, InitialPayment), TransactionValidityError> { + let fee = pallet_transaction_payment::Pallet::::compute_fee(len as u32, info, self.tip); debug_assert!(self.tip <= fee, "tip should be included in the computed fee"); if fee.is_zero() { Ok((fee, InitialPayment::Nothing)) @@ -249,30 +225,7 @@ impl sp_std::fmt::Debug for ChargeAssetTxPayment { } } -impl TransactionExtensionBase for ChargeAssetTxPayment -where - AssetBalanceOf: Send + Sync, - BalanceOf: Send - + Sync - + From - + Into> - + Into> - + From>, - ChargeAssetIdOf: Send + Sync, -{ - const IDENTIFIER: &'static str = "ChargeAssetTxPayment"; - type Implicit = (); - - fn weight(&self) -> Weight { - if self.asset_id.is_some() { - ::WeightInfo::charge_asset_tx_payment_asset() - } else { - ::WeightInfo::charge_asset_tx_payment_native() - } - } -} - -impl TransactionExtension for ChargeAssetTxPayment +impl SignedExtension for ChargeAssetTxPayment where T::RuntimeCall: Dispatchable, AssetBalanceOf: Send + Sync, @@ -283,123 +236,111 @@ where + Into> + From>, ChargeAssetIdOf: Send + Sync, - ::RuntimeOrigin: AsSystemOriginSigner + Clone, { - type Val = ( - // tip - BalanceOf, - // who paid the fee - T::AccountId, - // transaction fee - BalanceOf, - ); + const IDENTIFIER: &'static str = "ChargeAssetTxPayment"; + type AccountId = T::AccountId; + type Call = T::RuntimeCall; + type AdditionalSigned = (); type Pre = ( // tip BalanceOf, // who paid the fee - T::AccountId, + Self::AccountId, // imbalance resulting from withdrawing the fee InitialPayment, // asset_id for the transaction payment Option>, ); + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { + Ok(()) + } + fn validate( &self, - origin: ::RuntimeOrigin, - _call: &T::RuntimeCall, - info: &DispatchInfoOf, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, len: usize, - _context: &mut Context, - _self_implicit: Self::Implicit, - _inherited_implication: &impl Encode, - ) -> ValidateResult { - let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?; - // Non-mutating call of `compute_fee` to calculate the fee used in the transaction priority. - let fee = pallet_transaction_payment::Pallet::::compute_fee(len as u32, info, self.tip); + ) -> TransactionValidity { + use pallet_transaction_payment::ChargeTransactionPayment; + let (fee, _) = self.withdraw_fee(who, call, info, len)?; let priority = ChargeTransactionPayment::::get_priority(info, len, self.tip, fee); - let validity = ValidTransaction { priority, ..Default::default() }; - let val = (self.tip, who.clone(), fee); - Ok((validity, val, origin)) + Ok(ValidTransaction { priority, ..Default::default() }) } - fn prepare( + fn pre_dispatch( self, - val: Self::Val, - _origin: &::RuntimeOrigin, - call: &T::RuntimeCall, - info: &DispatchInfoOf, - _len: usize, - _context: &Context, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, ) -> Result { - let (tip, who, fee) = val; - // Mutating call of `withdraw_fee` to actually charge for the transaction. - let (_fee, initial_payment) = self.withdraw_fee(&who, call, info, fee)?; - Ok((tip, who, initial_payment, self.asset_id.clone())) + let (_fee, initial_payment) = self.withdraw_fee(who, call, info, len)?; + Ok((self.tip, who.clone(), initial_payment, self.asset_id)) } fn post_dispatch( - pre: Self::Pre, - info: &DispatchInfoOf, - post_info: &PostDispatchInfoOf, + pre: Option, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, len: usize, result: &DispatchResult, - _context: &Context, ) -> Result<(), TransactionValidityError> { - let (tip, who, initial_payment, asset_id) = pre; - match initial_payment { - InitialPayment::Native(already_withdrawn) => { - debug_assert!( - asset_id.is_none(), - "For that payment type the `asset_id` should be None" - ); - pallet_transaction_payment::ChargeTransactionPayment::::post_dispatch( - (tip, who, already_withdrawn), - info, - post_info, - len, - result, - &(), - )?; - }, - InitialPayment::Asset(already_withdrawn) => { - debug_assert!( - asset_id.is_some(), - "For that payment type the `asset_id` should be set" - ); - let actual_fee = pallet_transaction_payment::Pallet::::compute_actual_fee( - len as u32, info, post_info, tip, - ); - - if let Some(asset_id) = asset_id { - let (used_for_fee, received_exchanged, asset_consumed) = already_withdrawn; - let converted_fee = T::OnChargeAssetTransaction::correct_and_deposit_fee( - &who, + if let Some((tip, who, initial_payment, asset_id)) = pre { + match initial_payment { + InitialPayment::Native(already_withdrawn) => { + debug_assert!( + asset_id.is_none(), + "For that payment type the `asset_id` should be None" + ); + pallet_transaction_payment::ChargeTransactionPayment::::post_dispatch( + Some((tip, who, already_withdrawn)), info, post_info, - actual_fee.into(), - tip.into(), - used_for_fee.into(), - received_exchanged.into(), - asset_id.clone(), - asset_consumed.into(), + len, + result, )?; + }, + InitialPayment::Asset(already_withdrawn) => { + debug_assert!( + asset_id.is_some(), + "For that payment type the `asset_id` should be set" + ); + let actual_fee = pallet_transaction_payment::Pallet::::compute_actual_fee( + len as u32, info, post_info, tip, + ); + + if let Some(asset_id) = asset_id { + let (used_for_fee, received_exchanged, asset_consumed) = already_withdrawn; + let converted_fee = T::OnChargeAssetTransaction::correct_and_deposit_fee( + &who, + info, + post_info, + actual_fee.into(), + tip.into(), + used_for_fee.into(), + received_exchanged.into(), + asset_id.clone(), + asset_consumed.into(), + )?; - Pallet::::deposit_event(Event::::AssetTxFeePaid { - who, - actual_fee: converted_fee, - tip, - asset_id, - }); - } - }, - InitialPayment::Nothing => { - // `actual_fee` should be zero here for any signed extrinsic. It would be - // non-zero here in case of unsigned extrinsics as they don't pay fees but - // `compute_actual_fee` is not aware of them. In both cases it's fine to just - // move ahead without adjusting the fee, though, so we do nothing. - debug_assert!(tip.is_zero(), "tip should be zero if initial fee was zero."); - }, + Pallet::::deposit_event(Event::::AssetTxFeePaid { + who, + actual_fee: converted_fee, + tip, + asset_id, + }); + } + }, + InitialPayment::Nothing => { + // `actual_fee` should be zero here for any signed extrinsic. It would be + // non-zero here in case of unsigned extrinsics as they don't pay fees but + // `compute_actual_fee` is not aware of them. In both cases it's fine to just + // move ahead without adjusting the fee, though, so we do nothing. + debug_assert!(tip.is_zero(), "tip should be zero if initial fee was zero."); + }, + } } Ok(()) diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs index 853753d41cf..c8bf2eb8f44 100644 --- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs +++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs @@ -168,12 +168,12 @@ impl OnUnbalanced> for DealWithFees } } -#[derive_impl(pallet_transaction_payment::config_preludes::TestDefaultConfig as pallet_transaction_payment::DefaultConfig)] impl pallet_transaction_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; type OnChargeTransaction = CurrencyAdapter; type WeightToFee = WeightToFee; type LengthToFee = TransactionByteFee; + type FeeMultiplierUpdate = (); type OperationalFeeMultiplier = ConstU8<5>; } @@ -269,72 +269,4 @@ impl Config for Runtime { type RuntimeEvent = RuntimeEvent; type Fungibles = Assets; type OnChargeAssetTransaction = AssetConversionAdapter; - type WeightInfo = (); - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = Helper; -} - -#[cfg(feature = "runtime-benchmarks")] -pub fn new_test_ext() -> sp_io::TestExternalities { - let base_weight = 5; - let balance_factor = 100; - crate::tests::ExtBuilder::default() - .balance_factor(balance_factor) - .base_weight(Weight::from_parts(base_weight, 0)) - .build() -} - -#[cfg(feature = "runtime-benchmarks")] -pub struct Helper; - -#[cfg(feature = "runtime-benchmarks")] -impl BenchmarkHelperTrait for Helper { - fn create_asset_id_parameter(id: u32) -> (u32, u32) { - (id, id) - } - - fn setup_balances_and_pool(asset_id: u32, account: u64) { - use frame_support::{assert_ok, traits::fungibles::Mutate}; - use sp_runtime::traits::StaticLookup; - assert_ok!(Assets::force_create( - RuntimeOrigin::root(), - asset_id.into(), - 42, /* owner */ - true, /* is_sufficient */ - 1, - )); - - let lp_provider = 12; - assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), lp_provider, u64::MAX / 2)); - let lp_provider_account = ::Lookup::unlookup(lp_provider); - assert_ok!(Assets::mint_into(asset_id.into(), &lp_provider_account, u64::MAX / 2)); - - let token_1 = Box::new(NativeOrWithId::Native); - let token_2 = Box::new(NativeOrWithId::WithId(asset_id)); - assert_ok!(AssetConversion::create_pool( - RuntimeOrigin::signed(lp_provider), - token_1.clone(), - token_2.clone() - )); - - assert_ok!(AssetConversion::add_liquidity( - RuntimeOrigin::signed(lp_provider), - token_1, - token_2, - (u32::MAX / 8).into(), // 1 desired - u32::MAX.into(), // 2 desired - 1, // 1 min - 1, // 2 min - lp_provider_account, - )); - - use frame_support::traits::Currency; - let _ = Balances::deposit_creating(&account, u32::MAX.into()); - - let beneficiary = ::Lookup::unlookup(account); - let balance = 1000; - - assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance)); - assert_eq!(Assets::balance(asset_id, account), balance); - } } diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/tests.rs b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/tests.rs index 619077c0a5e..62faed269d3 100644 --- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/tests.rs +++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/tests.rs @@ -28,10 +28,7 @@ use frame_support::{ use frame_system as system; use mock::{ExtrinsicBaseWeight, *}; use pallet_balances::Call as BalancesCall; -use sp_runtime::{ - traits::{DispatchTransaction, StaticLookup}, - BuildStorage, -}; +use sp_runtime::{traits::StaticLookup, BuildStorage}; const CALL: &::RuntimeCall = &RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 2, value: 69 }); @@ -163,35 +160,33 @@ fn transaction_payment_in_native_possible() { .build() .execute_with(|| { let len = 10; - let (pre, _) = ChargeAssetTxPayment::::from(0, None) - .validate_and_prepare(Some(1).into(), CALL, &info_from_weight(WEIGHT_5), len) + let pre = ChargeAssetTxPayment::::from(0, None) + .pre_dispatch(&1, CALL, &info_from_weight(WEIGHT_5), len) .unwrap(); let initial_balance = 10 * balance_factor; assert_eq!(Balances::free_balance(1), initial_balance - 5 - 5 - 10); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(WEIGHT_5), &default_post_info(), len, - &Ok(()), - &() + &Ok(()) )); assert_eq!(Balances::free_balance(1), initial_balance - 5 - 5 - 10); - let (pre, _) = ChargeAssetTxPayment::::from(5 /* tipped */, None) - .validate_and_prepare(Some(2).into(), CALL, &info_from_weight(WEIGHT_100), len) + let pre = ChargeAssetTxPayment::::from(5 /* tipped */, None) + .pre_dispatch(&2, CALL, &info_from_weight(WEIGHT_100), len) .unwrap(); let initial_balance_for_2 = 20 * balance_factor; assert_eq!(Balances::free_balance(2), initial_balance_for_2 - 5 - 10 - 100 - 5); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(WEIGHT_100), &post_info_from_weight(WEIGHT_50), len, - &Ok(()), - &() + &Ok(()) )); assert_eq!(Balances::free_balance(2), initial_balance_for_2 - 5 - 10 - 50 - 5); }); @@ -242,8 +237,8 @@ fn transaction_payment_in_asset_possible() { let fee_in_asset = input_quote.unwrap(); assert_eq!(Assets::balance(asset_id, caller), balance); - let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .validate_and_prepare(Some(caller).into(), CALL, &info_from_weight(WEIGHT_5), len) + let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .pre_dispatch(&caller, CALL, &info_from_weight(WEIGHT_5), len) .unwrap(); // assert that native balance is not used assert_eq!(Balances::free_balance(caller), 10 * balance_factor); @@ -252,12 +247,11 @@ fn transaction_payment_in_asset_possible() { assert_eq!(Assets::balance(asset_id, caller), balance - fee_in_asset); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(WEIGHT_5), // estimated tx weight &default_post_info(), // weight actually used == estimated len, - &Ok(()), - &() + &Ok(()) )); assert_eq!(Assets::balance(asset_id, caller), balance - fee_in_asset); @@ -295,8 +289,12 @@ fn transaction_payment_in_asset_fails_if_no_pool_for_that_asset() { assert_eq!(Assets::balance(asset_id, caller), balance); let len = 10; - let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .validate_and_prepare(Some(caller).into(), CALL, &info_from_weight(WEIGHT_5), len); + let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)).pre_dispatch( + &caller, + CALL, + &info_from_weight(WEIGHT_5), + len, + ); // As there is no pool in the dex set up for this asset, conversion should fail. assert!(pre.is_err()); @@ -346,8 +344,8 @@ fn transaction_payment_without_fee() { assert_eq!(input_quote, Some(201)); let fee_in_asset = input_quote.unwrap(); - let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .validate_and_prepare(Some(caller).into(), CALL, &info_from_weight(WEIGHT_5), len) + let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .pre_dispatch(&caller, CALL, &info_from_weight(WEIGHT_5), len) .unwrap(); // assert that native balance is not used @@ -365,12 +363,11 @@ fn transaction_payment_without_fee() { assert_eq!(refund, 199); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(WEIGHT_5), &post_info_from_pays(Pays::No), len, - &Ok(()), - &() + &Ok(()) )); // caller should get refunded @@ -422,8 +419,8 @@ fn asset_transaction_payment_with_tip_and_refund() { assert_eq!(input_quote, Some(1206)); let fee_in_asset = input_quote.unwrap(); - let (pre, _) = ChargeAssetTxPayment::::from(tip, Some(asset_id)) - .validate_and_prepare(Some(caller).into(), CALL, &info_from_weight(WEIGHT_100), len) + let pre = ChargeAssetTxPayment::::from(tip, Some(asset_id)) + .pre_dispatch(&caller, CALL, &info_from_weight(WEIGHT_100), len) .unwrap(); assert_eq!(Assets::balance(asset_id, caller), balance - fee_in_asset); @@ -438,12 +435,11 @@ fn asset_transaction_payment_with_tip_and_refund() { .unwrap(); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(WEIGHT_100), &post_info_from_weight(WEIGHT_50), len, - &Ok(()), - &() + &Ok(()) )); assert_eq!(TipUnbalancedAmount::get(), tip); @@ -504,8 +500,8 @@ fn payment_from_account_with_only_assets() { .unwrap(); assert_eq!(fee_in_asset, 301); - let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .validate_and_prepare(Some(caller).into(), CALL, &info_from_weight(WEIGHT_5), len) + let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .pre_dispatch(&caller, CALL, &info_from_weight(WEIGHT_5), len) .unwrap(); assert_eq!(Balances::free_balance(caller), ed); // check that fee was charged in the given asset @@ -520,12 +516,11 @@ fn payment_from_account_with_only_assets() { .unwrap(); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(WEIGHT_5), &default_post_info(), len, - &Ok(()), - &() + &Ok(()) )); assert_eq!(Assets::balance(asset_id, caller), balance - fee_in_asset + refund); assert_eq!(Balances::free_balance(caller), 0); @@ -570,19 +565,18 @@ fn converted_fee_is_never_zero_if_input_fee_is_not() { // there will be no conversion when the fee is zero { - let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .validate_and_prepare(Some(caller).into(), CALL, &info_from_pays(Pays::No), len) + let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .pre_dispatch(&caller, CALL, &info_from_pays(Pays::No), len) .unwrap(); // `Pays::No` implies there are no fees assert_eq!(Assets::balance(asset_id, caller), balance); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_pays(Pays::No), &post_info_from_pays(Pays::No), len, - &Ok(()), - &() + &Ok(()) )); assert_eq!(Assets::balance(asset_id, caller), balance); } @@ -597,23 +591,17 @@ fn converted_fee_is_never_zero_if_input_fee_is_not() { ) .unwrap(); - let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .validate_and_prepare( - Some(caller).into(), - CALL, - &info_from_weight(Weight::from_parts(weight, 0)), - len, - ) + let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len) .unwrap(); assert_eq!(Assets::balance(asset_id, caller), balance - fee_in_asset); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(Weight::from_parts(weight, 0)), &default_post_info(), len, - &Ok(()), - &() + &Ok(()) )); assert_eq!(Assets::balance(asset_id, caller), balance - fee_in_asset); }); @@ -653,8 +641,8 @@ fn post_dispatch_fee_is_zero_if_pre_dispatch_fee_is_zero() { // calculated fee is greater than 0 assert!(fee > 0); - let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .validate_and_prepare(Some(caller).into(), CALL, &info_from_pays(Pays::No), len) + let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .pre_dispatch(&caller, CALL, &info_from_pays(Pays::No), len) .unwrap(); // `Pays::No` implies no pre-dispatch fees @@ -670,12 +658,62 @@ fn post_dispatch_fee_is_zero_if_pre_dispatch_fee_is_zero() { // `Pays::Yes` on post-dispatch does not mean we pay (we never charge more than the // initial fee) assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_pays(Pays::No), &post_info_from_pays(Pays::Yes), len, - &Ok(()), - &() + &Ok(()) + )); + assert_eq!(Assets::balance(asset_id, caller), balance); + }); +} + +#[test] +fn post_dispatch_fee_is_zero_if_unsigned_pre_dispatch_fee_is_zero() { + let base_weight = 1; + ExtBuilder::default() + .balance_factor(100) + .base_weight(Weight::from_parts(base_weight, 0)) + .build() + .execute_with(|| { + // create the asset + let asset_id = 1; + let min_balance = 100; + assert_ok!(Assets::force_create( + RuntimeOrigin::root(), + asset_id.into(), + 42, /* owner */ + true, /* is_sufficient */ + min_balance + )); + + // mint into the caller account + let caller = 333; + let beneficiary = ::Lookup::unlookup(caller); + let balance = 1000; + + assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance)); + assert_eq!(Assets::balance(asset_id, caller), balance); + + let weight = 1; + let len = 1; + ChargeAssetTxPayment::::pre_dispatch_unsigned( + CALL, + &info_from_weight(Weight::from_parts(weight, 0)), + len, + ) + .unwrap(); + + assert_eq!(Assets::balance(asset_id, caller), balance); + + // `Pays::Yes` on post-dispatch does not mean we pay (we never charge more than the + // initial fee) + assert_ok!(ChargeAssetTxPayment::::post_dispatch( + None, + &info_from_weight(Weight::from_parts(weight, 0)), + &post_info_from_pays(Pays::Yes), + len, + &Ok(()) )); assert_eq!(Assets::balance(asset_id, caller), balance); }); diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/weights.rs b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/weights.rs deleted file mode 100644 index f95e49f8073..00000000000 --- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/weights.rs +++ /dev/null @@ -1,150 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// 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. - -//! Autogenerated weights for `pallet_asset_conversion_tx_payment` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` - -// Executed Command: -// ./target/production/substrate-node -// benchmark -// pallet -// --chain=dev -// --steps=50 -// --repeat=20 -// --pallet=pallet_asset_conversion_tx_payment -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --wasm-execution=compiled -// --heap-pages=4096 -// --output=./substrate/frame/transaction-payment/asset-conversion-tx-payment/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; -use core::marker::PhantomData; - -/// Weight functions needed for `pallet_asset_conversion_tx_payment`. -pub trait WeightInfo { - fn charge_asset_tx_payment_zero() -> Weight; - fn charge_asset_tx_payment_native() -> Weight; - fn charge_asset_tx_payment_asset() -> Weight; -} - -/// Weights for `pallet_asset_conversion_tx_payment` using the Substrate node and recommended hardware. -pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { - fn charge_asset_tx_payment_zero() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 628_000 picoseconds. - Weight::from_parts(694_000, 0) - } - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - fn charge_asset_tx_payment_native() -> Weight { - // Proof Size summary in bytes: - // Measured: `248` - // Estimated: `1733` - // Minimum execution time: 34_410_000 picoseconds. - Weight::from_parts(35_263_000, 1733) - .saturating_add(T::DbWeight::get().reads(3_u64)) - } - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:2 w:2) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - fn charge_asset_tx_payment_asset() -> Weight { - // Proof Size summary in bytes: - // Measured: `888` - // Estimated: `6208` - // Minimum execution time: 112_432_000 picoseconds. - Weight::from_parts(113_992_000, 6208) - .saturating_add(T::DbWeight::get().reads(7_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) - } -} - -// For backwards compatibility and tests. -impl WeightInfo for () { - fn charge_asset_tx_payment_zero() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 628_000 picoseconds. - Weight::from_parts(694_000, 0) - } - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - fn charge_asset_tx_payment_native() -> Weight { - // Proof Size summary in bytes: - // Measured: `248` - // Estimated: `1733` - // Minimum execution time: 34_410_000 picoseconds. - Weight::from_parts(35_263_000, 1733) - .saturating_add(RocksDbWeight::get().reads(3_u64)) - } - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:2 w:2) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - fn charge_asset_tx_payment_asset() -> Weight { - // Proof Size summary in bytes: - // Measured: `888` - // Estimated: `6208` - // Minimum execution time: 112_432_000 picoseconds. - Weight::from_parts(113_992_000, 6208) - .saturating_add(RocksDbWeight::get().reads(7_u64)) - .saturating_add(RocksDbWeight::get().writes(4_u64)) - } -} diff --git a/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml b/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml index 06d9c30792e..1da3237df08 100644 --- a/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml +++ b/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml @@ -66,7 +66,6 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "pallet-assets/runtime-benchmarks", "pallet-balances/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "sp-runtime/runtime-benchmarks", ] try-runtime = [ diff --git a/substrate/frame/transaction-payment/asset-tx-payment/README.md b/substrate/frame/transaction-payment/asset-tx-payment/README.md index 933ce13b0ee..fc860347d85 100644 --- a/substrate/frame/transaction-payment/asset-tx-payment/README.md +++ b/substrate/frame/transaction-payment/asset-tx-payment/README.md @@ -16,6 +16,6 @@ asset. ### Integration This pallet wraps FRAME's transaction payment pallet and functions as a replacement. This means you should include both pallets in your `construct_runtime` macro, but only include this -pallet's [`TransactionExtension`] ([`ChargeAssetTxPayment`]). +pallet's [`SignedExtension`] ([`ChargeAssetTxPayment`]). License: Apache-2.0 diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/benchmarking.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/benchmarking.rs deleted file mode 100644 index 17e96e2b025..00000000000 --- a/substrate/frame/transaction-payment/asset-tx-payment/src/benchmarking.rs +++ /dev/null @@ -1,123 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// 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. - -//! Benchmarks for Asset Tx Payment Pallet's transaction extension - -use super::*; -use crate::Pallet; -use frame_benchmarking::v2::*; -use frame_support::{ - dispatch::{DispatchInfo, PostDispatchInfo}, - pallet_prelude::*, -}; -use frame_system::RawOrigin; -use sp_runtime::traits::{AsSystemOriginSigner, DispatchTransaction, Dispatchable}; - -#[benchmarks(where - T::RuntimeCall: Dispatchable, - AssetBalanceOf: Send + Sync, - BalanceOf: Send + Sync + From + IsType>, - ChargeAssetIdOf: Send + Sync, - ::RuntimeOrigin: AsSystemOriginSigner + Clone, - Credit: IsType>, -)] -mod benchmarks { - use super::*; - - #[benchmark] - fn charge_asset_tx_payment_zero() { - let caller: T::AccountId = whitelisted_caller(); - let ext: ChargeAssetTxPayment = ChargeAssetTxPayment::from(0u32.into(), None); - let inner = frame_system::Call::remark { remark: vec![] }; - let call = T::RuntimeCall::from(inner); - let info = DispatchInfo { - weight: Weight::zero(), - class: DispatchClass::Normal, - pays_fee: Pays::No, - }; - let post_info = PostDispatchInfo { actual_weight: None, pays_fee: Pays::No }; - #[block] - { - assert!(ext - .test_run(RawOrigin::Signed(caller).into(), &call, &info, 0, |_| Ok(post_info)) - .unwrap() - .is_ok()); - } - } - - #[benchmark] - fn charge_asset_tx_payment_native() { - let caller: T::AccountId = whitelisted_caller(); - let (fun_asset_id, _) = ::BenchmarkHelper::create_asset_id_parameter(1); - ::BenchmarkHelper::setup_balances_and_pool(fun_asset_id, caller.clone()); - let ext: ChargeAssetTxPayment = ChargeAssetTxPayment::from(10u32.into(), None); - let inner = frame_system::Call::remark { remark: vec![] }; - let call = T::RuntimeCall::from(inner); - let info = DispatchInfo { - weight: Weight::from_parts(10, 0), - class: DispatchClass::Operational, - pays_fee: Pays::Yes, - }; - let post_info = PostDispatchInfo { - actual_weight: Some(Weight::from_parts(10, 0)), - pays_fee: Pays::Yes, - }; - - #[block] - { - assert!(ext - .test_run(RawOrigin::Signed(caller).into(), &call, &info, 0, |_| Ok(post_info)) - .unwrap() - .is_ok()); - } - } - - #[benchmark] - fn charge_asset_tx_payment_asset() { - let caller: T::AccountId = whitelisted_caller(); - let (fun_asset_id, asset_id) = ::BenchmarkHelper::create_asset_id_parameter(1); - ::BenchmarkHelper::setup_balances_and_pool( - fun_asset_id.clone(), - caller.clone(), - ); - let tip = 10u32.into(); - let ext: ChargeAssetTxPayment = ChargeAssetTxPayment::from(tip, Some(asset_id)); - let inner = frame_system::Call::remark { remark: vec![] }; - let call = T::RuntimeCall::from(inner); - let info = DispatchInfo { - weight: Weight::from_parts(10, 0), - class: DispatchClass::Operational, - pays_fee: Pays::Yes, - }; - let post_info = PostDispatchInfo { - actual_weight: Some(Weight::from_parts(10, 0)), - pays_fee: Pays::Yes, - }; - - #[block] - { - assert!(ext - .test_run(RawOrigin::Signed(caller.clone()).into(), &call, &info, 0, |_| Ok( - post_info - )) - .unwrap() - .is_ok()); - } - } - - impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Runtime); -} diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/lib.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/lib.rs index 991b5f31406..753fae747a3 100644 --- a/substrate/frame/transaction-payment/asset-tx-payment/src/lib.rs +++ b/substrate/frame/transaction-payment/asset-tx-payment/src/lib.rs @@ -31,7 +31,7 @@ //! This pallet wraps FRAME's transaction payment pallet and functions as a replacement. This means //! you should include both pallets in your `construct_runtime` macro, but only include this -//! pallet's [`TransactionExtension`] ([`ChargeAssetTxPayment`]). +//! pallet's [`SignedExtension`] ([`ChargeAssetTxPayment`]). #![cfg_attr(not(feature = "std"), no_std)] @@ -40,7 +40,6 @@ use sp_std::prelude::*; use codec::{Decode, Encode}; use frame_support::{ dispatch::{DispatchInfo, DispatchResult, PostDispatchInfo}, - pallet_prelude::Weight, traits::{ tokens::{ fungibles::{Balanced, Credit, Inspect}, @@ -53,11 +52,10 @@ use frame_support::{ use pallet_transaction_payment::OnChargeTransaction; use scale_info::TypeInfo; use sp_runtime::{ - traits::{ - AsSystemOriginSigner, DispatchInfoOf, Dispatchable, PostDispatchInfoOf, - TransactionExtension, TransactionExtensionBase, Zero, + traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf, SignedExtension, Zero}, + transaction_validity::{ + InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction, }, - transaction_validity::{InvalidTransaction, TransactionValidityError, ValidTransaction}, }; #[cfg(test)] @@ -65,14 +63,8 @@ mod mock; #[cfg(test)] mod tests; -#[cfg(feature = "runtime-benchmarks")] -mod benchmarking; - mod payment; -pub mod weights; - pub use payment::*; -pub use weights::WeightInfo; /// Type aliases used for interaction with `OnChargeTransaction`. pub(crate) type OnChargeTransactionOf = @@ -128,30 +120,11 @@ pub mod pallet { type Fungibles: Balanced; /// The actual transaction charging logic that charges the fees. type OnChargeAssetTransaction: OnChargeAssetTransaction; - /// The weight information of this pallet. - type WeightInfo: WeightInfo; - #[cfg(feature = "runtime-benchmarks")] - /// Benchmark helper - type BenchmarkHelper: BenchmarkHelperTrait< - Self::AccountId, - <::Fungibles as Inspect>::AssetId, - <::OnChargeAssetTransaction as OnChargeAssetTransaction>::AssetId, - >; } #[pallet::pallet] pub struct Pallet(_); - #[cfg(feature = "runtime-benchmarks")] - /// Helper trait to benchmark the `ChargeAssetTxPayment` transaction extension. - pub trait BenchmarkHelperTrait { - /// Returns the `AssetId` to be used in the liquidity pool by the benchmarking code. - fn create_asset_id_parameter(id: u32) -> (FunAssetIdParameter, AssetIdParameter); - /// Create a liquidity pool for a given asset and sufficiently endow accounts to benchmark - /// the extension. - fn setup_balances_and_pool(asset_id: FunAssetIdParameter, account: AccountId); - } - #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { @@ -199,8 +172,9 @@ where who: &T::AccountId, call: &T::RuntimeCall, info: &DispatchInfoOf, - fee: BalanceOf, + len: usize, ) -> Result<(BalanceOf, InitialPayment), TransactionValidityError> { + let fee = pallet_transaction_payment::Pallet::::compute_fee(len as u32, info, self.tip); debug_assert!(self.tip <= fee, "tip should be included in the computed fee"); if fee.is_zero() { Ok((fee, InitialPayment::Nothing)) @@ -235,139 +209,104 @@ impl sp_std::fmt::Debug for ChargeAssetTxPayment { } } -impl TransactionExtensionBase for ChargeAssetTxPayment -where - AssetBalanceOf: Send + Sync, - BalanceOf: Send + Sync + From + IsType>, - ChargeAssetIdOf: Send + Sync, - Credit: IsType>, -{ - const IDENTIFIER: &'static str = "ChargeAssetTxPayment"; - type Implicit = (); - - fn weight(&self) -> Weight { - if self.asset_id.is_some() { - ::WeightInfo::charge_asset_tx_payment_asset() - } else { - ::WeightInfo::charge_asset_tx_payment_native() - } - } -} - -impl TransactionExtension for ChargeAssetTxPayment +impl SignedExtension for ChargeAssetTxPayment where T::RuntimeCall: Dispatchable, AssetBalanceOf: Send + Sync, BalanceOf: Send + Sync + From + IsType>, ChargeAssetIdOf: Send + Sync, Credit: IsType>, - ::RuntimeOrigin: AsSystemOriginSigner + Clone, { - type Val = ( - // tip - BalanceOf, - // who paid the fee - T::AccountId, - // transaction fee - BalanceOf, - ); + const IDENTIFIER: &'static str = "ChargeAssetTxPayment"; + type AccountId = T::AccountId; + type Call = T::RuntimeCall; + type AdditionalSigned = (); type Pre = ( // tip BalanceOf, // who paid the fee - T::AccountId, + Self::AccountId, // imbalance resulting from withdrawing the fee InitialPayment, // asset_id for the transaction payment Option>, ); + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { + Ok(()) + } + fn validate( &self, - origin: ::RuntimeOrigin, - _call: &T::RuntimeCall, - info: &DispatchInfoOf, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, len: usize, - _context: &mut Context, - _self_implicit: Self::Implicit, - _inherited_implication: &impl Encode, - ) -> Result< - (ValidTransaction, Self::Val, ::RuntimeOrigin), - TransactionValidityError, - > { + ) -> TransactionValidity { use pallet_transaction_payment::ChargeTransactionPayment; - let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?; - // Non-mutating call of `compute_fee` to calculate the fee used in the transaction priority. - let fee = pallet_transaction_payment::Pallet::::compute_fee(len as u32, info, self.tip); + let (fee, _) = self.withdraw_fee(who, call, info, len)?; let priority = ChargeTransactionPayment::::get_priority(info, len, self.tip, fee); - let val = (self.tip, who.clone(), fee); - let validity = ValidTransaction { priority, ..Default::default() }; - Ok((validity, val, origin)) + Ok(ValidTransaction { priority, ..Default::default() }) } - fn prepare( + fn pre_dispatch( self, - val: Self::Val, - _origin: &::RuntimeOrigin, - call: &T::RuntimeCall, - info: &DispatchInfoOf, - _len: usize, - _context: &Context, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, ) -> Result { - let (tip, who, fee) = val; - // Mutating call of `withdraw_fee` to actually charge for the transaction. - let (_fee, initial_payment) = self.withdraw_fee(&who, call, info, fee)?; - Ok((tip, who, initial_payment, self.asset_id)) + let (_fee, initial_payment) = self.withdraw_fee(who, call, info, len)?; + Ok((self.tip, who.clone(), initial_payment, self.asset_id)) } fn post_dispatch( - pre: Self::Pre, - info: &DispatchInfoOf, - post_info: &PostDispatchInfoOf, + pre: Option, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, len: usize, result: &DispatchResult, - _context: &Context, ) -> Result<(), TransactionValidityError> { - let (tip, who, initial_payment, asset_id) = pre; - match initial_payment { - InitialPayment::Native(already_withdrawn) => { - pallet_transaction_payment::ChargeTransactionPayment::::post_dispatch( - (tip, who, already_withdrawn), - info, - post_info, - len, - result, - &(), - )?; - }, - InitialPayment::Asset(already_withdrawn) => { - let actual_fee = pallet_transaction_payment::Pallet::::compute_actual_fee( - len as u32, info, post_info, tip, - ); - - let (converted_fee, converted_tip) = - T::OnChargeAssetTransaction::correct_and_deposit_fee( - &who, + if let Some((tip, who, initial_payment, asset_id)) = pre { + match initial_payment { + InitialPayment::Native(already_withdrawn) => { + pallet_transaction_payment::ChargeTransactionPayment::::post_dispatch( + Some((tip, who, already_withdrawn)), info, post_info, - actual_fee.into(), - tip.into(), - already_withdrawn.into(), + len, + result, )?; - Pallet::::deposit_event(Event::::AssetTxFeePaid { - who, - actual_fee: converted_fee, - tip: converted_tip, - asset_id, - }); - }, - InitialPayment::Nothing => { - // `actual_fee` should be zero here for any signed extrinsic. It would be - // non-zero here in case of unsigned extrinsics as they don't pay fees but - // `compute_actual_fee` is not aware of them. In both cases it's fine to just - // move ahead without adjusting the fee, though, so we do nothing. - debug_assert!(tip.is_zero(), "tip should be zero if initial fee was zero."); - }, + }, + InitialPayment::Asset(already_withdrawn) => { + let actual_fee = pallet_transaction_payment::Pallet::::compute_actual_fee( + len as u32, info, post_info, tip, + ); + + let (converted_fee, converted_tip) = + T::OnChargeAssetTransaction::correct_and_deposit_fee( + &who, + info, + post_info, + actual_fee.into(), + tip.into(), + already_withdrawn.into(), + )?; + Pallet::::deposit_event(Event::::AssetTxFeePaid { + who, + actual_fee: converted_fee, + tip: converted_tip, + asset_id, + }); + }, + InitialPayment::Nothing => { + // `actual_fee` should be zero here for any signed extrinsic. It would be + // non-zero here in case of unsigned extrinsics as they don't pay fees but + // `compute_actual_fee` is not aware of them. In both cases it's fine to just + // move ahead without adjusting the fee, though, so we do nothing. + debug_assert!(tip.is_zero(), "tip should be zero if initial fee was zero."); + }, + } } Ok(()) diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs index bb484795e82..1f335b4f6c4 100644 --- a/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs +++ b/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs @@ -136,12 +136,12 @@ impl WeightToFeeT for TransactionByteFee { } } -#[derive_impl(pallet_transaction_payment::config_preludes::TestDefaultConfig as pallet_transaction_payment::DefaultConfig)] impl pallet_transaction_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; type OnChargeTransaction = CurrencyAdapter; type WeightToFee = WeightToFee; type LengthToFee = TransactionByteFee; + type FeeMultiplierUpdate = (); type OperationalFeeMultiplier = ConstU8<5>; } @@ -205,56 +205,4 @@ impl Config for Runtime { pallet_assets::BalanceToAssetBalance, CreditToBlockAuthor, >; - type WeightInfo = (); - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = Helper; -} - -#[cfg(feature = "runtime-benchmarks")] -pub fn new_test_ext() -> sp_io::TestExternalities { - let base_weight = 5; - let balance_factor = 100; - crate::tests::ExtBuilder::default() - .balance_factor(balance_factor) - .base_weight(Weight::from_parts(base_weight, 0)) - .build() -} - -#[cfg(feature = "runtime-benchmarks")] -pub struct Helper; - -#[cfg(feature = "runtime-benchmarks")] -impl BenchmarkHelperTrait for Helper { - fn create_asset_id_parameter(id: u32) -> (u32, u32) { - (id.into(), id.into()) - } - - fn setup_balances_and_pool(asset_id: u32, account: u64) { - use frame_support::{assert_ok, traits::fungibles::Mutate}; - use sp_runtime::traits::StaticLookup; - let min_balance = 1; - assert_ok!(Assets::force_create( - RuntimeOrigin::root(), - asset_id.into(), - 42, /* owner */ - true, /* is_sufficient */ - min_balance - )); - - // mint into the caller account - let caller = 2; - let beneficiary = ::Lookup::unlookup(caller); - let balance = 1000; - assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance)); - assert_eq!(Assets::balance(asset_id, caller), balance); - - use frame_support::traits::Currency; - let _ = Balances::deposit_creating(&account, u32::MAX.into()); - - let beneficiary = ::Lookup::unlookup(account); - let balance = 1000; - - assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance)); - assert_eq!(Assets::balance(asset_id, account), balance); - } } diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs index 42b8f2cf5fa..8df98ceda99 100644 --- a/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs +++ b/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs @@ -25,10 +25,7 @@ use frame_support::{ use frame_system as system; use mock::{ExtrinsicBaseWeight, *}; use pallet_balances::Call as BalancesCall; -use sp_runtime::{ - traits::{DispatchTransaction, StaticLookup}, - BuildStorage, -}; +use sp_runtime::{traits::StaticLookup, BuildStorage}; const CALL: &::RuntimeCall = &RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 2, value: 69 }); @@ -119,45 +116,33 @@ fn transaction_payment_in_native_possible() { .build() .execute_with(|| { let len = 10; - let (pre, _) = ChargeAssetTxPayment::::from(0, None) - .validate_and_prepare( - Some(1).into(), - CALL, - &info_from_weight(Weight::from_parts(5, 0)), - len, - ) + let pre = ChargeAssetTxPayment::::from(0, None) + .pre_dispatch(&1, CALL, &info_from_weight(Weight::from_parts(5, 0)), len) .unwrap(); let initial_balance = 10 * balance_factor; assert_eq!(Balances::free_balance(1), initial_balance - 5 - 5 - 10); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(Weight::from_parts(5, 0)), &default_post_info(), len, - &Ok(()), - &() + &Ok(()) )); assert_eq!(Balances::free_balance(1), initial_balance - 5 - 5 - 10); - let (pre, _) = ChargeAssetTxPayment::::from(5 /* tipped */, None) - .validate_and_prepare( - Some(2).into(), - CALL, - &info_from_weight(Weight::from_parts(100, 0)), - len, - ) + let pre = ChargeAssetTxPayment::::from(5 /* tipped */, None) + .pre_dispatch(&2, CALL, &info_from_weight(Weight::from_parts(100, 0)), len) .unwrap(); let initial_balance_for_2 = 20 * balance_factor; assert_eq!(Balances::free_balance(2), initial_balance_for_2 - 5 - 10 - 100 - 5); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(Weight::from_parts(100, 0)), &post_info_from_weight(Weight::from_parts(50, 0)), len, - &Ok(()), - &() + &Ok(()) )); assert_eq!(Balances::free_balance(2), initial_balance_for_2 - 5 - 10 - 50 - 5); }); @@ -194,13 +179,8 @@ fn transaction_payment_in_asset_possible() { // we convert the from weight to fee based on the ratio between asset min balance and // existential deposit let fee = (base_weight + weight + len as u64) * min_balance / ExistentialDeposit::get(); - let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .validate_and_prepare( - Some(caller).into(), - CALL, - &info_from_weight(Weight::from_parts(weight, 0)), - len, - ) + let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len) .unwrap(); // assert that native balance is not used assert_eq!(Balances::free_balance(caller), 10 * balance_factor); @@ -209,12 +189,11 @@ fn transaction_payment_in_asset_possible() { assert_eq!(Assets::balance(asset_id, BLOCK_AUTHOR), 0); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(Weight::from_parts(weight, 0)), &default_post_info(), len, - &Ok(()), - &() + &Ok(()) )); assert_eq!(Assets::balance(asset_id, caller), balance - fee); // check that the block author gets rewarded @@ -253,13 +232,8 @@ fn transaction_payment_without_fee() { // we convert the from weight to fee based on the ratio between asset min balance and // existential deposit let fee = (base_weight + weight + len as u64) * min_balance / ExistentialDeposit::get(); - let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .validate_and_prepare( - Some(caller).into(), - CALL, - &info_from_weight(Weight::from_parts(weight, 0)), - len, - ) + let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len) .unwrap(); // assert that native balance is not used assert_eq!(Balances::free_balance(caller), 10 * balance_factor); @@ -268,12 +242,11 @@ fn transaction_payment_without_fee() { assert_eq!(Assets::balance(asset_id, BLOCK_AUTHOR), 0); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(Weight::from_parts(weight, 0)), &post_info_from_pays(Pays::No), len, - &Ok(()), - &() + &Ok(()) )); // caller should be refunded assert_eq!(Assets::balance(asset_id, caller), balance); @@ -314,24 +287,18 @@ fn asset_transaction_payment_with_tip_and_refund() { // existential deposit let fee_with_tip = (base_weight + weight + len as u64 + tip) * min_balance / ExistentialDeposit::get(); - let (pre, _) = ChargeAssetTxPayment::::from(tip, Some(asset_id)) - .validate_and_prepare( - Some(caller).into(), - CALL, - &info_from_weight(Weight::from_parts(weight, 0)), - len, - ) + let pre = ChargeAssetTxPayment::::from(tip, Some(asset_id)) + .pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len) .unwrap(); assert_eq!(Assets::balance(asset_id, caller), balance - fee_with_tip); let final_weight = 50; assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(Weight::from_parts(weight, 0)), &post_info_from_weight(Weight::from_parts(final_weight, 0)), len, - &Ok(()), - &() + &Ok(()) )); let final_fee = fee_with_tip - (weight - final_weight) * min_balance / ExistentialDeposit::get(); @@ -372,25 +339,19 @@ fn payment_from_account_with_only_assets() { // we convert the from weight to fee based on the ratio between asset min balance and // existential deposit let fee = (base_weight + weight + len as u64) * min_balance / ExistentialDeposit::get(); - let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .validate_and_prepare( - Some(caller).into(), - CALL, - &info_from_weight(Weight::from_parts(weight, 0)), - len, - ) + let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len) .unwrap(); assert_eq!(Balances::free_balance(caller), 0); // check that fee was charged in the given asset assert_eq!(Assets::balance(asset_id, caller), balance - fee); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(Weight::from_parts(weight, 0)), &default_post_info(), len, - &Ok(()), - &() + &Ok(()) )); assert_eq!(Assets::balance(asset_id, caller), balance - fee); assert_eq!(Balances::free_balance(caller), 0); @@ -411,12 +372,7 @@ fn payment_only_with_existing_sufficient_asset() { let len = 10; // pre_dispatch fails for non-existent asset assert!(ChargeAssetTxPayment::::from(0, Some(asset_id)) - .validate_and_prepare( - Some(caller).into(), - CALL, - &info_from_weight(Weight::from_parts(weight, 0)), - len - ) + .pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len) .is_err()); // create the non-sufficient asset @@ -430,12 +386,7 @@ fn payment_only_with_existing_sufficient_asset() { )); // pre_dispatch fails for non-sufficient asset assert!(ChargeAssetTxPayment::::from(0, Some(asset_id)) - .validate_and_prepare( - Some(caller).into(), - CALL, - &info_from_weight(Weight::from_parts(weight, 0)), - len - ) + .pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len) .is_err()); }); } @@ -473,40 +424,33 @@ fn converted_fee_is_never_zero_if_input_fee_is_not() { // naive fee calculation would round down to zero assert_eq!(fee, 0); { - let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .validate_and_prepare(Some(caller).into(), CALL, &info_from_pays(Pays::No), len) + let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .pre_dispatch(&caller, CALL, &info_from_pays(Pays::No), len) .unwrap(); // `Pays::No` still implies no fees assert_eq!(Assets::balance(asset_id, caller), balance); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_pays(Pays::No), &post_info_from_pays(Pays::No), len, - &Ok(()), - &() + &Ok(()) )); assert_eq!(Assets::balance(asset_id, caller), balance); } - let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .validate_and_prepare( - Some(caller).into(), - CALL, - &info_from_weight(Weight::from_parts(weight, 0)), - len, - ) + let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len) .unwrap(); // check that at least one coin was charged in the given asset assert_eq!(Assets::balance(asset_id, caller), balance - 1); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(Weight::from_parts(weight, 0)), &default_post_info(), len, - &Ok(()), - &() + &Ok(()) )); assert_eq!(Assets::balance(asset_id, caller), balance - 1); }); @@ -544,8 +488,8 @@ fn post_dispatch_fee_is_zero_if_pre_dispatch_fee_is_zero() { let fee = (base_weight + weight + len as u64) * min_balance / ExistentialDeposit::get(); // calculated fee is greater than 0 assert!(fee > 0); - let (pre, _) = ChargeAssetTxPayment::::from(0, Some(asset_id)) - .validate_and_prepare(Some(caller).into(), CALL, &info_from_pays(Pays::No), len) + let pre = ChargeAssetTxPayment::::from(0, Some(asset_id)) + .pre_dispatch(&caller, CALL, &info_from_pays(Pays::No), len) .unwrap(); // `Pays::No` implies no pre-dispatch fees assert_eq!(Assets::balance(asset_id, caller), balance); @@ -559,12 +503,60 @@ fn post_dispatch_fee_is_zero_if_pre_dispatch_fee_is_zero() { // `Pays::Yes` on post-dispatch does not mean we pay (we never charge more than the // initial fee) assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_pays(Pays::No), &post_info_from_pays(Pays::Yes), len, - &Ok(()), - &() + &Ok(()) + )); + assert_eq!(Assets::balance(asset_id, caller), balance); + }); +} + +#[test] +fn post_dispatch_fee_is_zero_if_unsigned_pre_dispatch_fee_is_zero() { + let base_weight = 1; + ExtBuilder::default() + .balance_factor(100) + .base_weight(Weight::from_parts(base_weight, 0)) + .build() + .execute_with(|| { + // create the asset + let asset_id = 1; + let min_balance = 100; + assert_ok!(Assets::force_create( + RuntimeOrigin::root(), + asset_id.into(), + 42, /* owner */ + true, /* is_sufficient */ + min_balance + )); + + // mint into the caller account + let caller = 333; + let beneficiary = ::Lookup::unlookup(caller); + let balance = 100; + assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance)); + assert_eq!(Assets::balance(asset_id, caller), balance); + let weight = 1; + let len = 1; + ChargeAssetTxPayment::::pre_dispatch_unsigned( + CALL, + &info_from_weight(Weight::from_parts(weight, 0)), + len, + ) + .unwrap(); + + assert_eq!(Assets::balance(asset_id, caller), balance); + + // `Pays::Yes` on post-dispatch does not mean we pay (we never charge more than the + // initial fee) + assert_ok!(ChargeAssetTxPayment::::post_dispatch( + None, + &info_from_weight(Weight::from_parts(weight, 0)), + &post_info_from_pays(Pays::Yes), + len, + &Ok(()) )); assert_eq!(Assets::balance(asset_id, caller), balance); }); diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/weights.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/weights.rs deleted file mode 100644 index 1af1c94177d..00000000000 --- a/substrate/frame/transaction-payment/asset-tx-payment/src/weights.rs +++ /dev/null @@ -1,146 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// 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. - -//! Autogenerated weights for `pallet_asset_tx_payment` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` - -// Executed Command: -// ./target/production/substrate-node -// benchmark -// pallet -// --chain=dev -// --steps=50 -// --repeat=20 -// --pallet=pallet_asset_tx_payment -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --wasm-execution=compiled -// --heap-pages=4096 -// --output=./substrate/frame/transaction-payment/asset-tx-payment/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; -use core::marker::PhantomData; - -/// Weight functions needed for `pallet_asset_tx_payment`. -pub trait WeightInfo { - fn charge_asset_tx_payment_zero() -> Weight; - fn charge_asset_tx_payment_native() -> Weight; - fn charge_asset_tx_payment_asset() -> Weight; -} - -/// Weights for `pallet_asset_tx_payment` using the Substrate node and recommended hardware. -pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { - fn charge_asset_tx_payment_zero() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 542_000 picoseconds. - Weight::from_parts(597_000, 0) - } - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - fn charge_asset_tx_payment_native() -> Weight { - // Proof Size summary in bytes: - // Measured: `248` - // Estimated: `1733` - // Minimum execution time: 33_162_000 picoseconds. - Weight::from_parts(34_716_000, 1733) - .saturating_add(T::DbWeight::get().reads(3_u64)) - } - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - fn charge_asset_tx_payment_asset() -> Weight { - // Proof Size summary in bytes: - // Measured: `747` - // Estimated: `3675` - // Minimum execution time: 44_230_000 picoseconds. - Weight::from_parts(45_297_000, 3675) - .saturating_add(T::DbWeight::get().reads(5_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) - } -} - -// For backwards compatibility and tests. -impl WeightInfo for () { - fn charge_asset_tx_payment_zero() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 542_000 picoseconds. - Weight::from_parts(597_000, 0) - } - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - fn charge_asset_tx_payment_native() -> Weight { - // Proof Size summary in bytes: - // Measured: `248` - // Estimated: `1733` - // Minimum execution time: 33_162_000 picoseconds. - Weight::from_parts(34_716_000, 1733) - .saturating_add(RocksDbWeight::get().reads(3_u64)) - } - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:1 w:1) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - fn charge_asset_tx_payment_asset() -> Weight { - // Proof Size summary in bytes: - // Measured: `747` - // Estimated: `3675` - // Minimum execution time: 44_230_000 picoseconds. - Weight::from_parts(45_297_000, 3675) - .saturating_add(RocksDbWeight::get().reads(5_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) - } -} diff --git a/substrate/frame/transaction-payment/skip-feeless-payment/src/lib.rs b/substrate/frame/transaction-payment/skip-feeless-payment/src/lib.rs index 9810ea08c79..6c34c26ce92 100644 --- a/substrate/frame/transaction-payment/skip-feeless-payment/src/lib.rs +++ b/substrate/frame/transaction-payment/skip-feeless-payment/src/lib.rs @@ -21,7 +21,7 @@ //! //! ## Overview //! -//! It does this by wrapping an existing [`TransactionExtension`] implementation (e.g. +//! It does this by wrapping an existing [`SignedExtension`] implementation (e.g. //! [`pallet-transaction-payment`]) and checking if the dispatchable is feeless before applying the //! wrapped extension. If the dispatchable is indeed feeless, the extension is skipped and a custom //! event is emitted instead. Otherwise, the extension is applied as usual. @@ -31,8 +31,7 @@ //! //! This pallet wraps an existing transaction payment pallet. This means you should both pallets //! in your `construct_runtime` macro and include this pallet's -//! [`TransactionExtension`] ([`SkipCheckIfFeeless`]) that would accept the existing one as an -//! argument. +//! [`SignedExtension`] ([`SkipCheckIfFeeless`]) that would accept the existing one as an argument. #![cfg_attr(not(feature = "std"), no_std)] @@ -43,10 +42,7 @@ use frame_support::{ }; use scale_info::{StaticTypeInfo, TypeInfo}; use sp_runtime::{ - traits::{ - DispatchInfoOf, OriginOf, PostDispatchInfoOf, TransactionExtension, - TransactionExtensionBase, ValidateResult, - }, + traits::{DispatchInfoOf, PostDispatchInfoOf, SignedExtension}, transaction_validity::TransactionValidityError, }; @@ -74,11 +70,11 @@ pub mod pallet { #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { /// A transaction fee was skipped. - FeeSkipped { origin: ::PalletsOrigin }, + FeeSkipped { who: T::AccountId }, } } -/// A [`TransactionExtension`] that skips the wrapped extension if the dispatchable is feeless. +/// A [`SignedExtension`] that skips the wrapped extension if the dispatchable is feeless. #[derive(Encode, Decode, Clone, Eq, PartialEq)] pub struct SkipCheckIfFeeless(pub S, sp_std::marker::PhantomData); @@ -107,96 +103,53 @@ impl From for SkipCheckIfFeeless { } } -pub enum Intermediate { - /// The wrapped extension should be applied. - Apply(T), - /// The wrapped extension should be skipped. - Skip(O), -} -use Intermediate::*; - -impl TransactionExtensionBase +impl> SignedExtension for SkipCheckIfFeeless +where + S::Call: CheckIfFeeless>, { + type AccountId = T::AccountId; + type Call = S::Call; + type AdditionalSigned = S::AdditionalSigned; + type Pre = (Self::AccountId, Option<::Pre>); // From the outside this extension should be "invisible", because it just extends the wrapped // extension with an extra check in `pre_dispatch` and `post_dispatch`. Thus, we should forward // the identifier of the wrapped extension to let wallets see this extension as it would only be // the wrapped extension itself. const IDENTIFIER: &'static str = S::IDENTIFIER; - type Implicit = S::Implicit; - - fn implicit(&self) -> Result { - self.0.implicit() - } - fn weight(&self) -> frame_support::weights::Weight { - self.0.weight() + fn additional_signed(&self) -> Result { + self.0.additional_signed() } -} -impl> - TransactionExtension for SkipCheckIfFeeless -where - T::RuntimeCall: CheckIfFeeless>, -{ - type Val = Intermediate as OriginTrait>::PalletsOrigin>; - type Pre = Intermediate as OriginTrait>::PalletsOrigin>; - - fn validate( - &self, - origin: OriginOf, - call: &T::RuntimeCall, - info: &DispatchInfoOf, - len: usize, - context: &mut Context, - self_implicit: S::Implicit, - inherited_implication: &impl Encode, - ) -> ValidateResult { - if call.is_feeless(&origin) { - Ok((Default::default(), Skip(origin.caller().clone()), origin)) - } else { - let (x, y, z) = self.0.validate( - origin, - call, - info, - len, - context, - self_implicit, - inherited_implication, - )?; - Ok((x, Apply(y), z)) - } - } - - fn prepare( + fn pre_dispatch( self, - val: Self::Val, - origin: &OriginOf, - call: &T::RuntimeCall, - info: &DispatchInfoOf, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, len: usize, - context: &Context, ) -> Result { - match val { - Apply(val) => self.0.prepare(val, origin, call, info, len, context).map(Apply), - Skip(origin) => Ok(Skip(origin)), + if call.is_feeless(&::RuntimeOrigin::signed(who.clone())) { + Ok((who.clone(), None)) + } else { + Ok((who.clone(), Some(self.0.pre_dispatch(who, call, info, len)?))) } } fn post_dispatch( - pre: Self::Pre, - info: &DispatchInfoOf, - post_info: &PostDispatchInfoOf, + pre: Option, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, len: usize, result: &DispatchResult, - context: &Context, ) -> Result<(), TransactionValidityError> { - match pre { - Apply(pre) => S::post_dispatch(pre, info, post_info, len, result, context), - Skip(origin) => { - Pallet::::deposit_event(Event::::FeeSkipped { origin }); - Ok(()) - }, + if let Some(pre) = pre { + if let Some(pre) = pre.1 { + S::post_dispatch(Some(pre), info, post_info, len, result)?; + } else { + Pallet::::deposit_event(Event::::FeeSkipped { who: pre.0 }); + } } + Ok(()) } } diff --git a/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs b/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs index 06948de4c3c..17c4c773997 100644 --- a/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs +++ b/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs @@ -18,12 +18,9 @@ use crate as pallet_skip_feeless_payment; use frame_support::{derive_impl, parameter_types}; use frame_system as system; -use sp_runtime::{ - impl_tx_ext_default, - traits::{OriginOf, TransactionExtension}, -}; type Block = frame_system::mocking::MockBlock; +type AccountId = u64; #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Runtime { @@ -41,22 +38,21 @@ parameter_types! { #[derive(Clone, Eq, PartialEq, Debug, Encode, Decode, TypeInfo)] pub struct DummyExtension; -impl TransactionExtensionBase for DummyExtension { - const IDENTIFIER: &'static str = "DummyExtension"; - type Implicit = (); -} -impl TransactionExtension for DummyExtension { - type Val = (); +impl SignedExtension for DummyExtension { + type AccountId = AccountId; + type Call = RuntimeCall; + type AdditionalSigned = (); type Pre = (); - impl_tx_ext_default!(RuntimeCall; C; validate); - fn prepare( + const IDENTIFIER: &'static str = "DummyExtension"; + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { + Ok(()) + } + fn pre_dispatch( self, - _val: Self::Val, - _origin: &OriginOf, - _call: &RuntimeCall, - _info: &DispatchInfoOf, + _who: &Self::AccountId, + _call: &Self::Call, + _info: &DispatchInfoOf, _len: usize, - _context: &C, ) -> Result { PreDispatchCount::mutate(|c| *c += 1); Ok(()) diff --git a/substrate/frame/transaction-payment/skip-feeless-payment/src/tests.rs b/substrate/frame/transaction-payment/skip-feeless-payment/src/tests.rs index 96b4af7e203..4b4dd699741 100644 --- a/substrate/frame/transaction-payment/skip-feeless-payment/src/tests.rs +++ b/substrate/frame/transaction-payment/skip-feeless-payment/src/tests.rs @@ -16,19 +16,18 @@ use super::*; use crate::mock::{pallet_dummy::Call, DummyExtension, PreDispatchCount, Runtime, RuntimeCall}; use frame_support::dispatch::DispatchInfo; -use sp_runtime::traits::DispatchTransaction; #[test] fn skip_feeless_payment_works() { let call = RuntimeCall::DummyPallet(Call::::aux { data: 1 }); SkipCheckIfFeeless::::from(DummyExtension) - .validate_and_prepare(Some(0).into(), &call, &DispatchInfo::default(), 0) + .pre_dispatch(&0, &call, &DispatchInfo::default(), 0) .unwrap(); assert_eq!(PreDispatchCount::get(), 1); let call = RuntimeCall::DummyPallet(Call::::aux { data: 0 }); SkipCheckIfFeeless::::from(DummyExtension) - .validate_and_prepare(Some(0).into(), &call, &DispatchInfo::default(), 0) + .pre_dispatch(&0, &call, &DispatchInfo::default(), 0) .unwrap(); assert_eq!(PreDispatchCount::get(), 1); } diff --git a/substrate/frame/transaction-payment/src/benchmarking.rs b/substrate/frame/transaction-payment/src/benchmarking.rs deleted file mode 100644 index d63c5a7d746..00000000000 --- a/substrate/frame/transaction-payment/src/benchmarking.rs +++ /dev/null @@ -1,81 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// 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. - -//! Benchmarks for Transaction Payment Pallet's transaction extension - -use super::*; -use crate::Pallet; -use frame_benchmarking::v2::*; -use frame_support::dispatch::{DispatchInfo, PostDispatchInfo}; -use frame_system::{EventRecord, RawOrigin}; -use sp_runtime::traits::{DispatchTransaction, Dispatchable}; - -fn assert_last_event(generic_event: ::RuntimeEvent) { - let events = frame_system::Pallet::::events(); - let system_event: ::RuntimeEvent = generic_event.into(); - // compare to the last event record - let EventRecord { event, .. } = &events[events.len() - 1]; - assert_eq!(event, &system_event); -} - -#[benchmarks(where - T: Config, - T::RuntimeCall: Dispatchable, - BalanceOf: Send + Sync + From, -)] -mod benchmarks { - use super::*; - - #[benchmark] - fn charge_transaction_payment() { - let caller: T::AccountId = whitelisted_caller(); - >::endow_account( - &caller, - >::minimum_balance() * 1000.into(), - ); - let tip = >::minimum_balance(); - let ext: ChargeTransactionPayment = ChargeTransactionPayment::from(tip); - let inner = frame_system::Call::remark { remark: vec![] }; - let call = T::RuntimeCall::from(inner); - let info = DispatchInfo { - weight: Weight::from_parts(100, 0), - class: DispatchClass::Operational, - pays_fee: Pays::Yes, - }; - let post_info = PostDispatchInfo { - actual_weight: Some(Weight::from_parts(10, 0)), - pays_fee: Pays::Yes, - }; - - #[block] - { - assert!(ext - .test_run(RawOrigin::Signed(caller.clone()).into(), &call, &info, 10, |_| Ok( - post_info - )) - .unwrap() - .is_ok()); - } - - let actual_fee = Pallet::::compute_actual_fee(10, &info, &post_info, tip); - assert_last_event::( - Event::::TransactionFeePaid { who: caller, actual_fee, tip }.into(), - ); - } - - impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Runtime); -} diff --git a/substrate/frame/transaction-payment/src/lib.rs b/substrate/frame/transaction-payment/src/lib.rs index 6b17616bdc7..efadfd60bdd 100644 --- a/substrate/frame/transaction-payment/src/lib.rs +++ b/substrate/frame/transaction-payment/src/lib.rs @@ -62,28 +62,23 @@ pub use payment::*; use sp_runtime::{ traits::{ Convert, DispatchInfoOf, Dispatchable, One, PostDispatchInfoOf, SaturatedConversion, - Saturating, TransactionExtension, TransactionExtensionBase, Zero, + Saturating, SignedExtension, Zero, }, transaction_validity::{ - InvalidTransaction, TransactionPriority, TransactionValidityError, ValidTransaction, + TransactionPriority, TransactionValidity, TransactionValidityError, ValidTransaction, }, FixedPointNumber, FixedU128, Perbill, Perquintill, RuntimeDebug, }; use sp_std::prelude::*; pub use types::{FeeDetails, InclusionFee, RuntimeDispatchInfo}; -pub use weights::WeightInfo; #[cfg(test)] mod mock; #[cfg(test)] mod tests; -#[cfg(feature = "runtime-benchmarks")] -mod benchmarking; - mod payment; mod types; -pub mod weights; /// Fee multiplier. pub type Multiplier = FixedU128; @@ -340,7 +335,6 @@ pub mod pallet { type RuntimeEvent = (); type FeeMultiplierUpdate = (); type OperationalFeeMultiplier = (); - type WeightInfo = (); } } @@ -393,9 +387,6 @@ pub mod pallet { /// transactions. #[pallet::constant] type OperationalFeeMultiplier: Get; - - /// The weight information of this pallet. - type WeightInfo: WeightInfo; } #[pallet::type_value] @@ -516,11 +507,11 @@ impl Pallet { // a very very little potential gain in the future. let dispatch_info = ::get_dispatch_info(&unchecked_extrinsic); - let partial_fee = if unchecked_extrinsic.is_bare() { - // Bare extrinsics have no partial fee. - 0u32.into() - } else { + let partial_fee = if unchecked_extrinsic.is_signed().unwrap_or(false) { Self::compute_fee(len, &dispatch_info, 0u32.into()) + } else { + // Unsigned extrinsics have no partial fee. + 0u32.into() }; let DispatchInfo { weight, class, .. } = dispatch_info; @@ -540,11 +531,11 @@ impl Pallet { let tip = 0u32.into(); - if unchecked_extrinsic.is_bare() { - // Bare extrinsics have no inclusion fee. - FeeDetails { inclusion_fee: None, tip } - } else { + if unchecked_extrinsic.is_signed().unwrap_or(false) { Self::compute_fee_details(len, &dispatch_info, tip) + } else { + // Unsigned extrinsics have no inclusion fee. + FeeDetails { inclusion_fee: None, tip } } } @@ -723,7 +714,7 @@ where who: &T::AccountId, call: &T::RuntimeCall, info: &DispatchInfoOf, - fee: BalanceOf, + len: usize, ) -> Result< ( BalanceOf, @@ -732,6 +723,7 @@ where TransactionValidityError, > { let tip = self.0; + let fee = Pallet::::compute_fee(len as u32, info, tip); <::OnChargeTransaction as OnChargeTransaction>::withdraw_fee( who, call, info, fee, tip, @@ -739,22 +731,6 @@ where .map(|i| (fee, i)) } - fn can_withdraw_fee( - &self, - who: &T::AccountId, - call: &T::RuntimeCall, - info: &DispatchInfoOf, - len: usize, - ) -> Result, TransactionValidityError> { - let tip = self.0; - let fee = Pallet::::compute_fee(len as u32, info, tip); - - <::OnChargeTransaction as OnChargeTransaction>::can_withdraw_fee( - who, call, info, fee, tip, - )?; - Ok(fee) - } - /// Get an appropriate priority for a transaction with the given `DispatchInfo`, encoded length /// and user-included tip. /// @@ -841,93 +817,67 @@ impl sp_std::fmt::Debug for ChargeTransactionPayment { } } -impl TransactionExtensionBase for ChargeTransactionPayment { - const IDENTIFIER: &'static str = "ChargeTransactionPayment"; - type Implicit = (); - - fn weight(&self) -> Weight { - T::WeightInfo::charge_transaction_payment() - } -} - -impl TransactionExtension - for ChargeTransactionPayment +impl SignedExtension for ChargeTransactionPayment where BalanceOf: Send + Sync + From, T::RuntimeCall: Dispatchable, { - type Val = ( - // tip - BalanceOf, - // who paid the fee - T::AccountId, - // computed fee - BalanceOf, - ); + const IDENTIFIER: &'static str = "ChargeTransactionPayment"; + type AccountId = T::AccountId; + type Call = T::RuntimeCall; + type AdditionalSigned = (); type Pre = ( // tip BalanceOf, - // who paid the fee - T::AccountId, + // who paid the fee - this is an option to allow for a Default impl. + Self::AccountId, // imbalance resulting from withdrawing the fee <::OnChargeTransaction as OnChargeTransaction>::LiquidityInfo, ); + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { + Ok(()) + } fn validate( &self, - origin: ::RuntimeOrigin, - call: &T::RuntimeCall, - info: &DispatchInfoOf, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, len: usize, - _context: &mut Context, - _: (), - _implication: &impl Encode, - ) -> Result< - (ValidTransaction, Self::Val, ::RuntimeOrigin), - TransactionValidityError, - > { - let who = frame_system::ensure_signed(origin.clone()) - .map_err(|_| InvalidTransaction::BadSigner)?; - let final_fee = self.can_withdraw_fee(&who, call, info, len)?; + ) -> TransactionValidity { + let (final_fee, _) = self.withdraw_fee(who, call, info, len)?; let tip = self.0; - Ok(( - ValidTransaction { - priority: Self::get_priority(info, len, tip, final_fee), - ..Default::default() - }, - (self.0, who, final_fee), - origin, - )) + Ok(ValidTransaction { + priority: Self::get_priority(info, len, tip, final_fee), + ..Default::default() + }) } - fn prepare( + fn pre_dispatch( self, - val: Self::Val, - _origin: &::RuntimeOrigin, - call: &T::RuntimeCall, - info: &DispatchInfoOf, - _len: usize, - _context: &Context, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, ) -> Result { - let (tip, who, fee) = val; - // Mutating call to `withdraw_fee` to actually charge for the transaction. - let (_final_fee, imbalance) = self.withdraw_fee(&who, call, info, fee)?; - Ok((tip, who, imbalance)) + let (_fee, imbalance) = self.withdraw_fee(who, call, info, len)?; + Ok((self.0, who.clone(), imbalance)) } fn post_dispatch( - (tip, who, imbalance): Self::Pre, - info: &DispatchInfoOf, - post_info: &PostDispatchInfoOf, + maybe_pre: Option, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, len: usize, _result: &DispatchResult, - _context: &Context, ) -> Result<(), TransactionValidityError> { - let actual_fee = Pallet::::compute_actual_fee(len as u32, info, post_info, tip); - T::OnChargeTransaction::correct_and_deposit_fee( - &who, info, post_info, actual_fee, tip, imbalance, - )?; - Pallet::::deposit_event(Event::::TransactionFeePaid { who, actual_fee, tip }); + if let Some((tip, who, imbalance)) = maybe_pre { + let actual_fee = Pallet::::compute_actual_fee(len as u32, info, post_info, tip); + T::OnChargeTransaction::correct_and_deposit_fee( + &who, info, post_info, actual_fee, tip, imbalance, + )?; + Pallet::::deposit_event(Event::::TransactionFeePaid { who, actual_fee, tip }); + } Ok(()) } } diff --git a/substrate/frame/transaction-payment/src/mock.rs b/substrate/frame/transaction-payment/src/mock.rs index eda234ffcae..1ca2e3d7347 100644 --- a/substrate/frame/transaction-payment/src/mock.rs +++ b/substrate/frame/transaction-payment/src/mock.rs @@ -157,14 +157,4 @@ impl Config for Runtime { type WeightToFee = WeightToFee; type LengthToFee = TransactionByteFee; type FeeMultiplierUpdate = (); - type WeightInfo = (); -} - -#[cfg(feature = "runtime-benchmarks")] -pub fn new_test_ext() -> sp_io::TestExternalities { - crate::tests::ExtBuilder::default() - .base_weight(Weight::from_parts(100, 0)) - .byte_fee(10) - .balance_factor(0) - .build() } diff --git a/substrate/frame/transaction-payment/src/payment.rs b/substrate/frame/transaction-payment/src/payment.rs index a13e73b50b0..886683f2e0b 100644 --- a/substrate/frame/transaction-payment/src/payment.rs +++ b/substrate/frame/transaction-payment/src/payment.rs @@ -20,7 +20,7 @@ use crate::Config; use core::marker::PhantomData; use sp_runtime::{ - traits::{CheckedSub, DispatchInfoOf, PostDispatchInfoOf, Saturating, Zero}, + traits::{DispatchInfoOf, PostDispatchInfoOf, Saturating, Zero}, transaction_validity::InvalidTransaction, }; @@ -51,17 +51,6 @@ pub trait OnChargeTransaction { tip: Self::Balance, ) -> Result; - /// Check if the predicted fee from the transaction origin can be withdrawn. - /// - /// Note: The `fee` already includes the `tip`. - fn can_withdraw_fee( - who: &T::AccountId, - call: &T::RuntimeCall, - dispatch_info: &DispatchInfoOf, - fee: Self::Balance, - tip: Self::Balance, - ) -> Result<(), TransactionValidityError>; - /// After the transaction was executed the actual fee can be calculated. /// This function should refund any overpaid fees and optionally deposit /// the corrected amount. @@ -75,12 +64,6 @@ pub trait OnChargeTransaction { tip: Self::Balance, already_withdrawn: Self::LiquidityInfo, ) -> Result<(), TransactionValidityError>; - - #[cfg(feature = "runtime-benchmarks")] - fn endow_account(who: &T::AccountId, amount: Self::Balance); - - #[cfg(feature = "runtime-benchmarks")] - fn minimum_balance() -> Self::Balance; } /// Implements the transaction payment for a pallet implementing the `Currency` @@ -138,33 +121,6 @@ where } } - /// Check if the predicted fee from the transaction origin can be withdrawn. - /// - /// Note: The `fee` already includes the `tip`. - fn can_withdraw_fee( - who: &T::AccountId, - _call: &T::RuntimeCall, - _info: &DispatchInfoOf, - fee: Self::Balance, - tip: Self::Balance, - ) -> Result<(), TransactionValidityError> { - if fee.is_zero() { - return Ok(()) - } - - let withdraw_reason = if tip.is_zero() { - WithdrawReasons::TRANSACTION_PAYMENT - } else { - WithdrawReasons::TRANSACTION_PAYMENT | WithdrawReasons::TIP - }; - - let new_balance = - C::free_balance(who).checked_sub(&fee).ok_or(InvalidTransaction::Payment)?; - C::ensure_can_withdraw(who, fee, withdraw_reason, new_balance) - .map(|_| ()) - .map_err(|_| InvalidTransaction::Payment.into()) - } - /// Hand the fee and the tip over to the `[OnUnbalanced]` implementation. /// Since the predicted fee might have been too high, parts of the fee may /// be refunded. @@ -197,14 +153,4 @@ where } Ok(()) } - - #[cfg(feature = "runtime-benchmarks")] - fn endow_account(who: &T::AccountId, amount: Self::Balance) { - let _ = C::deposit_creating(who, amount); - } - - #[cfg(feature = "runtime-benchmarks")] - fn minimum_balance() -> Self::Balance { - C::minimum_balance() - } } diff --git a/substrate/frame/transaction-payment/src/tests.rs b/substrate/frame/transaction-payment/src/tests.rs index 7a49f8111e2..d3a1721ccb9 100644 --- a/substrate/frame/transaction-payment/src/tests.rs +++ b/substrate/frame/transaction-payment/src/tests.rs @@ -21,14 +21,11 @@ use crate as pallet_transaction_payment; use codec::Encode; use sp_runtime::{ - generic::UncheckedExtrinsic, - traits::{DispatchTransaction, One}, - transaction_validity::InvalidTransaction, - BuildStorage, + testing::TestXt, traits::One, transaction_validity::InvalidTransaction, BuildStorage, }; use frame_support::{ - assert_ok, + assert_noop, assert_ok, dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, PostDispatchInfo}, traits::Currency, weights::Weight, @@ -131,37 +128,44 @@ fn default_post_info() -> PostDispatchInfo { PostDispatchInfo { actual_weight: None, pays_fee: Default::default() } } -type Ext = ChargeTransactionPayment; - #[test] -fn transaction_extension_transaction_payment_work() { +fn signed_extension_transaction_payment_work() { ExtBuilder::default() .balance_factor(10) .base_weight(Weight::from_parts(5, 0)) .build() .execute_with(|| { - let info = info_from_weight(Weight::from_parts(5, 0)); - Ext::from(0) - .test_run(Some(1).into(), CALL, &info, 10, |_| { - assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10); - Ok(default_post_info()) - }) - .unwrap() + let len = 10; + let pre = ChargeTransactionPayment::::from(0) + .pre_dispatch(&1, CALL, &info_from_weight(Weight::from_parts(5, 0)), len) .unwrap(); assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10); + + assert_ok!(ChargeTransactionPayment::::post_dispatch( + Some(pre), + &info_from_weight(Weight::from_parts(5, 0)), + &default_post_info(), + len, + &Ok(()) + )); + assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10); assert_eq!(FeeUnbalancedAmount::get(), 5 + 5 + 10); assert_eq!(TipUnbalancedAmount::get(), 0); FeeUnbalancedAmount::mutate(|a| *a = 0); - let info = info_from_weight(Weight::from_parts(100, 0)); - Ext::from(5 /* tipped */) - .test_run(Some(2).into(), CALL, &info, 10, |_| { - assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); - Ok(post_info_from_weight(Weight::from_parts(50, 0))) - }) - .unwrap() + let pre = ChargeTransactionPayment::::from(5 /* tipped */) + .pre_dispatch(&2, CALL, &info_from_weight(Weight::from_parts(100, 0)), len) .unwrap(); + assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); + + assert_ok!(ChargeTransactionPayment::::post_dispatch( + Some(pre), + &info_from_weight(Weight::from_parts(100, 0)), + &post_info_from_weight(Weight::from_parts(50, 0)), + len, + &Ok(()) + )); assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 50 - 5); assert_eq!(FeeUnbalancedAmount::get(), 5 + 10 + 50); assert_eq!(TipUnbalancedAmount::get(), 5); @@ -169,37 +173,43 @@ fn transaction_extension_transaction_payment_work() { } #[test] -fn transaction_extension_transaction_payment_multiplied_refund_works() { +fn signed_extension_transaction_payment_multiplied_refund_works() { ExtBuilder::default() .balance_factor(10) .base_weight(Weight::from_parts(5, 0)) .build() .execute_with(|| { + let len = 10; >::put(Multiplier::saturating_from_rational(3, 2)); - let len = 10; - let origin = Some(2).into(); - let info = info_from_weight(Weight::from_parts(100, 0)); - Ext::from(5 /* tipped */) - .test_run(origin, CALL, &info, len, |_| { - // 5 base fee, 10 byte fee, 3/2 * 100 weight fee, 5 tip - assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 150 - 5); - Ok(post_info_from_weight(Weight::from_parts(50, 0))) - }) - .unwrap() + let pre = ChargeTransactionPayment::::from(5 /* tipped */) + .pre_dispatch(&2, CALL, &info_from_weight(Weight::from_parts(100, 0)), len) .unwrap(); - + // 5 base fee, 10 byte fee, 3/2 * 100 weight fee, 5 tip + assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 150 - 5); + + assert_ok!(ChargeTransactionPayment::::post_dispatch( + Some(pre), + &info_from_weight(Weight::from_parts(100, 0)), + &post_info_from_weight(Weight::from_parts(50, 0)), + len, + &Ok(()) + )); // 75 (3/2 of the returned 50 units of weight) is refunded assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 75 - 5); }); } #[test] -fn transaction_extension_transaction_payment_is_bounded() { +fn signed_extension_transaction_payment_is_bounded() { ExtBuilder::default().balance_factor(1000).byte_fee(0).build().execute_with(|| { // maximum weight possible - let info = info_from_weight(Weight::MAX); - assert_ok!(Ext::from(0).validate_and_prepare(Some(1).into(), CALL, &info, 10)); + assert_ok!(ChargeTransactionPayment::::from(0).pre_dispatch( + &1, + CALL, + &info_from_weight(Weight::MAX), + 10 + )); // fee will be proportional to what is the actual maximum weight in the runtime. assert_eq!( Balances::free_balance(&1), @@ -210,7 +220,7 @@ fn transaction_extension_transaction_payment_is_bounded() { } #[test] -fn transaction_extension_allows_free_transactions() { +fn signed_extension_allows_free_transactions() { ExtBuilder::default() .base_weight(Weight::from_parts(100, 0)) .balance_factor(0) @@ -222,28 +232,38 @@ fn transaction_extension_allows_free_transactions() { let len = 100; // This is a completely free (and thus wholly insecure/DoS-ridden) transaction. - let op_tx = DispatchInfo { + let operational_transaction = DispatchInfo { weight: Weight::from_parts(0, 0), class: DispatchClass::Operational, pays_fee: Pays::No, }; - assert_ok!(Ext::from(0).validate_only(Some(1).into(), CALL, &op_tx, len)); + assert_ok!(ChargeTransactionPayment::::from(0).validate( + &1, + CALL, + &operational_transaction, + len + )); // like a InsecureFreeNormal - let free_tx = DispatchInfo { + let free_transaction = DispatchInfo { weight: Weight::from_parts(0, 0), class: DispatchClass::Normal, pays_fee: Pays::Yes, }; - assert_eq!( - Ext::from(0).validate_only(Some(1).into(), CALL, &free_tx, len).unwrap_err(), + assert_noop!( + ChargeTransactionPayment::::from(0).validate( + &1, + CALL, + &free_transaction, + len + ), TransactionValidityError::Invalid(InvalidTransaction::Payment), ); }); } #[test] -fn transaction_ext_length_fee_is_also_updated_per_congestion() { +fn signed_ext_length_fee_is_also_updated_per_congestion() { ExtBuilder::default() .base_weight(Weight::from_parts(5, 0)) .balance_factor(10) @@ -252,15 +272,16 @@ fn transaction_ext_length_fee_is_also_updated_per_congestion() { // all fees should be x1.5 >::put(Multiplier::saturating_from_rational(3, 2)); let len = 10; - let info = &info_from_weight(Weight::from_parts(3, 0)); - assert_ok!(Ext::from(10).validate_and_prepare(Some(1).into(), CALL, info, len)); + + assert_ok!(ChargeTransactionPayment::::from(10) // tipped + .pre_dispatch(&1, CALL, &info_from_weight(Weight::from_parts(3, 0)), len)); assert_eq!( Balances::free_balance(1), 100 // original - - 10 // tip - - 5 // base - - 10 // len - - (3 * 3 / 2) // adjusted weight + - 10 // tip + - 5 // base + - 10 // len + - (3 * 3 / 2) // adjusted weight ); }) } @@ -270,62 +291,62 @@ fn query_info_and_fee_details_works() { let call = RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 2, value: 69 }); let origin = 111111; let extra = (); - let xt = UncheckedExtrinsic::new_signed(call.clone(), origin, (), extra); + let xt = TestXt::new(call.clone(), Some((origin, extra))); let info = xt.get_dispatch_info(); let ext = xt.encode(); let len = ext.len() as u32; - let unsigned_xt = UncheckedExtrinsic::::new_bare(call); + let unsigned_xt = TestXt::<_, ()>::new(call, None); let unsigned_xt_info = unsigned_xt.get_dispatch_info(); ExtBuilder::default() - .base_weight(Weight::from_parts(5, 0)) - .weight_fee(2) - .build() - .execute_with(|| { - // all fees should be x1.5 - >::put(Multiplier::saturating_from_rational(3, 2)); - - assert_eq!( - TransactionPayment::query_info(xt.clone(), len), - RuntimeDispatchInfo { - weight: info.weight, - class: info.class, - partial_fee: 5 * 2 /* base * weight_fee */ - + len as u64 /* len * 1 */ - + info.weight.min(BlockWeights::get().max_block).ref_time() as u64 * 2 * 3 / 2 /* weight */ - }, - ); - - assert_eq!( - TransactionPayment::query_info(unsigned_xt.clone(), len), - RuntimeDispatchInfo { - weight: unsigned_xt_info.weight, - class: unsigned_xt_info.class, - partial_fee: 0, - }, - ); - - assert_eq!( - TransactionPayment::query_fee_details(xt, len), - FeeDetails { - inclusion_fee: Some(InclusionFee { - base_fee: 5 * 2, - len_fee: len as u64, - adjusted_weight_fee: info - .weight - .min(BlockWeights::get().max_block) - .ref_time() as u64 * 2 * 3 / 2 - }), - tip: 0, - }, - ); - - assert_eq!( - TransactionPayment::query_fee_details(unsigned_xt, len), - FeeDetails { inclusion_fee: None, tip: 0 }, - ); - }); + .base_weight(Weight::from_parts(5, 0)) + .weight_fee(2) + .build() + .execute_with(|| { + // all fees should be x1.5 + >::put(Multiplier::saturating_from_rational(3, 2)); + + assert_eq!( + TransactionPayment::query_info(xt.clone(), len), + RuntimeDispatchInfo { + weight: info.weight, + class: info.class, + partial_fee: 5 * 2 /* base * weight_fee */ + + len as u64 /* len * 1 */ + + info.weight.min(BlockWeights::get().max_block).ref_time() as u64 * 2 * 3 / 2 /* weight */ + }, + ); + + assert_eq!( + TransactionPayment::query_info(unsigned_xt.clone(), len), + RuntimeDispatchInfo { + weight: unsigned_xt_info.weight, + class: unsigned_xt_info.class, + partial_fee: 0, + }, + ); + + assert_eq!( + TransactionPayment::query_fee_details(xt, len), + FeeDetails { + inclusion_fee: Some(InclusionFee { + base_fee: 5 * 2, + len_fee: len as u64, + adjusted_weight_fee: info + .weight + .min(BlockWeights::get().max_block) + .ref_time() as u64 * 2 * 3 / 2 + }), + tip: 0, + }, + ); + + assert_eq!( + TransactionPayment::query_fee_details(unsigned_xt, len), + FeeDetails { inclusion_fee: None, tip: 0 }, + ); + }); } #[test] @@ -336,39 +357,39 @@ fn query_call_info_and_fee_details_works() { let len = encoded_call.len() as u32; ExtBuilder::default() - .base_weight(Weight::from_parts(5, 0)) - .weight_fee(2) - .build() - .execute_with(|| { - // all fees should be x1.5 - >::put(Multiplier::saturating_from_rational(3, 2)); - - assert_eq!( - TransactionPayment::query_call_info(call.clone(), len), - RuntimeDispatchInfo { - weight: info.weight, - class: info.class, - partial_fee: 5 * 2 /* base * weight_fee */ - + len as u64 /* len * 1 */ - + info.weight.min(BlockWeights::get().max_block).ref_time() as u64 * 2 * 3 / 2 /* weight */ - }, - ); - - assert_eq!( - TransactionPayment::query_call_fee_details(call, len), - FeeDetails { - inclusion_fee: Some(InclusionFee { - base_fee: 5 * 2, /* base * weight_fee */ - len_fee: len as u64, /* len * 1 */ - adjusted_weight_fee: info - .weight - .min(BlockWeights::get().max_block) - .ref_time() as u64 * 2 * 3 / 2 /* weight * weight_fee * multipler */ - }), - tip: 0, - }, - ); - }); + .base_weight(Weight::from_parts(5, 0)) + .weight_fee(2) + .build() + .execute_with(|| { + // all fees should be x1.5 + >::put(Multiplier::saturating_from_rational(3, 2)); + + assert_eq!( + TransactionPayment::query_call_info(call.clone(), len), + RuntimeDispatchInfo { + weight: info.weight, + class: info.class, + partial_fee: 5 * 2 /* base * weight_fee */ + + len as u64 /* len * 1 */ + + info.weight.min(BlockWeights::get().max_block).ref_time() as u64 * 2 * 3 / 2 /* weight */ + }, + ); + + assert_eq!( + TransactionPayment::query_call_fee_details(call, len), + FeeDetails { + inclusion_fee: Some(InclusionFee { + base_fee: 5 * 2, /* base * weight_fee */ + len_fee: len as u64, /* len * 1 */ + adjusted_weight_fee: info + .weight + .min(BlockWeights::get().max_block) + .ref_time() as u64 * 2 * 3 / 2 /* weight * weight_fee * multipler */ + }), + tip: 0, + }, + ); + }); } #[test] @@ -505,23 +526,27 @@ fn refund_does_not_recreate_account() { .execute_with(|| { // So events are emitted System::set_block_number(10); - let info = info_from_weight(Weight::from_parts(100, 0)); - Ext::from(5 /* tipped */) - .test_run(Some(2).into(), CALL, &info, 10, |origin| { - assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); - - // kill the account between pre and post dispatch - assert_ok!(Balances::transfer_allow_death( - origin, - 3, - Balances::free_balance(2) - )); - assert_eq!(Balances::free_balance(2), 0); - - Ok(post_info_from_weight(Weight::from_parts(50, 0))) - }) - .unwrap() + let len = 10; + let pre = ChargeTransactionPayment::::from(5 /* tipped */) + .pre_dispatch(&2, CALL, &info_from_weight(Weight::from_parts(100, 0)), len) .unwrap(); + assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); + + // kill the account between pre and post dispatch + assert_ok!(Balances::transfer_allow_death( + Some(2).into(), + 3, + Balances::free_balance(2) + )); + assert_eq!(Balances::free_balance(2), 0); + + assert_ok!(ChargeTransactionPayment::::post_dispatch( + Some(pre), + &info_from_weight(Weight::from_parts(100, 0)), + &post_info_from_weight(Weight::from_parts(50, 0)), + len, + &Ok(()) + )); assert_eq!(Balances::free_balance(2), 0); // Transfer Event System::assert_has_event(RuntimeEvent::Balances(pallet_balances::Event::Transfer { @@ -543,15 +568,20 @@ fn actual_weight_higher_than_max_refunds_nothing() { .base_weight(Weight::from_parts(5, 0)) .build() .execute_with(|| { - let info = info_from_weight(Weight::from_parts(100, 0)); - Ext::from(5 /* tipped */) - .test_run(Some(2).into(), CALL, &info, 10, |_| { - assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); - Ok(post_info_from_weight(Weight::from_parts(101, 0))) - }) - .unwrap() + let len = 10; + let pre = ChargeTransactionPayment::::from(5 /* tipped */) + .pre_dispatch(&2, CALL, &info_from_weight(Weight::from_parts(100, 0)), len) .unwrap(); assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); + + assert_ok!(ChargeTransactionPayment::::post_dispatch( + Some(pre), + &info_from_weight(Weight::from_parts(100, 0)), + &post_info_from_weight(Weight::from_parts(101, 0)), + len, + &Ok(()) + )); + assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); }); } @@ -564,20 +594,25 @@ fn zero_transfer_on_free_transaction() { .execute_with(|| { // So events are emitted System::set_block_number(10); - let info = DispatchInfo { + let len = 10; + let dispatch_info = DispatchInfo { weight: Weight::from_parts(100, 0), pays_fee: Pays::No, class: DispatchClass::Normal, }; let user = 69; - Ext::from(0) - .test_run(Some(user).into(), CALL, &info, 10, |_| { - assert_eq!(Balances::total_balance(&user), 0); - Ok(default_post_info()) - }) - .unwrap() + let pre = ChargeTransactionPayment::::from(0) + .pre_dispatch(&user, CALL, &dispatch_info, len) .unwrap(); assert_eq!(Balances::total_balance(&user), 0); + assert_ok!(ChargeTransactionPayment::::post_dispatch( + Some(pre), + &dispatch_info, + &default_post_info(), + len, + &Ok(()) + )); + assert_eq!(Balances::total_balance(&user), 0); // TransactionFeePaid Event System::assert_has_event(RuntimeEvent::TransactionPayment( pallet_transaction_payment::Event::TransactionFeePaid { @@ -604,11 +639,19 @@ fn refund_consistent_with_actual_weight() { >::put(Multiplier::saturating_from_rational(5, 4)); - Ext::from(tip) - .test_run(Some(2).into(), CALL, &info, len, |_| Ok(post_info)) - .unwrap() + let pre = ChargeTransactionPayment::::from(tip) + .pre_dispatch(&2, CALL, &info, len) .unwrap(); + ChargeTransactionPayment::::post_dispatch( + Some(pre), + &info, + &post_info, + len, + &Ok(()), + ) + .unwrap(); + let refund_based_fee = prev_balance - Balances::free_balance(2); let actual_fee = Pallet::::compute_actual_fee(len as u32, &info, &post_info, tip); @@ -630,13 +673,18 @@ fn should_alter_operational_priority() { class: DispatchClass::Normal, pays_fee: Pays::Yes, }; + let priority = ChargeTransactionPayment::(tip) + .validate(&2, CALL, &normal, len) + .unwrap() + .priority; - let ext = Ext::from(tip); - let priority = ext.validate_only(Some(2).into(), CALL, &normal, len).unwrap().0.priority; assert_eq!(priority, 60); - let ext = Ext::from(2 * tip); - let priority = ext.validate_only(Some(2).into(), CALL, &normal, len).unwrap().0.priority; + let priority = ChargeTransactionPayment::(2 * tip) + .validate(&2, CALL, &normal, len) + .unwrap() + .priority; + assert_eq!(priority, 110); }); @@ -646,13 +694,16 @@ fn should_alter_operational_priority() { class: DispatchClass::Operational, pays_fee: Pays::Yes, }; - - let ext = Ext::from(tip); - let priority = ext.validate_only(Some(2).into(), CALL, &op, len).unwrap().0.priority; + let priority = ChargeTransactionPayment::(tip) + .validate(&2, CALL, &op, len) + .unwrap() + .priority; assert_eq!(priority, 5810); - let ext = Ext::from(2 * tip); - let priority = ext.validate_only(Some(2).into(), CALL, &op, len).unwrap().0.priority; + let priority = ChargeTransactionPayment::(2 * tip) + .validate(&2, CALL, &op, len) + .unwrap() + .priority; assert_eq!(priority, 6110); }); } @@ -668,8 +719,11 @@ fn no_tip_has_some_priority() { class: DispatchClass::Normal, pays_fee: Pays::Yes, }; - let ext = Ext::from(tip); - let priority = ext.validate_only(Some(2).into(), CALL, &normal, len).unwrap().0.priority; + let priority = ChargeTransactionPayment::(tip) + .validate(&2, CALL, &normal, len) + .unwrap() + .priority; + assert_eq!(priority, 10); }); @@ -679,8 +733,10 @@ fn no_tip_has_some_priority() { class: DispatchClass::Operational, pays_fee: Pays::Yes, }; - let ext = Ext::from(tip); - let priority = ext.validate_only(Some(2).into(), CALL, &op, len).unwrap().0.priority; + let priority = ChargeTransactionPayment::(tip) + .validate(&2, CALL, &op, len) + .unwrap() + .priority; assert_eq!(priority, 5510); }); } @@ -688,8 +744,8 @@ fn no_tip_has_some_priority() { #[test] fn higher_tip_have_higher_priority() { let get_priorities = |tip: u64| { - let mut pri1 = 0; - let mut pri2 = 0; + let mut priority1 = 0; + let mut priority2 = 0; let len = 10; ExtBuilder::default().balance_factor(100).build().execute_with(|| { let normal = DispatchInfo { @@ -697,8 +753,10 @@ fn higher_tip_have_higher_priority() { class: DispatchClass::Normal, pays_fee: Pays::Yes, }; - let ext = Ext::from(tip); - pri1 = ext.validate_only(Some(2).into(), CALL, &normal, len).unwrap().0.priority; + priority1 = ChargeTransactionPayment::(tip) + .validate(&2, CALL, &normal, len) + .unwrap() + .priority; }); ExtBuilder::default().balance_factor(100).build().execute_with(|| { @@ -707,11 +765,13 @@ fn higher_tip_have_higher_priority() { class: DispatchClass::Operational, pays_fee: Pays::Yes, }; - let ext = Ext::from(tip); - pri2 = ext.validate_only(Some(2).into(), CALL, &op, len).unwrap().0.priority; + priority2 = ChargeTransactionPayment::(tip) + .validate(&2, CALL, &op, len) + .unwrap() + .priority; }); - (pri1, pri2) + (priority1, priority2) }; let mut prev_priorities = get_priorities(0); @@ -739,11 +799,19 @@ fn post_info_can_change_pays_fee() { >::put(Multiplier::saturating_from_rational(5, 4)); - let post_info = ChargeTransactionPayment::::from(tip) - .test_run(Some(2).into(), CALL, &info, len, |_| Ok(post_info)) - .unwrap() + let pre = ChargeTransactionPayment::::from(tip) + .pre_dispatch(&2, CALL, &info, len) .unwrap(); + ChargeTransactionPayment::::post_dispatch( + Some(pre), + &info, + &post_info, + len, + &Ok(()), + ) + .unwrap(); + let refund_based_fee = prev_balance - Balances::free_balance(2); let actual_fee = Pallet::::compute_actual_fee(len as u32, &info, &post_info, tip); diff --git a/substrate/frame/transaction-payment/src/types.rs b/substrate/frame/transaction-payment/src/types.rs index bfb3012fef0..25cecc58a63 100644 --- a/substrate/frame/transaction-payment/src/types.rs +++ b/substrate/frame/transaction-payment/src/types.rs @@ -112,7 +112,7 @@ pub struct RuntimeDispatchInfo /// The inclusion fee of this dispatch. /// /// This does not include a tip or anything else that - /// depends on the signature (i.e. depends on a `TransactionExtension`). + /// depends on the signature (i.e. depends on a `SignedExtension`). #[cfg_attr(feature = "std", serde(with = "serde_balance"))] pub partial_fee: Balance, } diff --git a/substrate/frame/transaction-payment/src/weights.rs b/substrate/frame/transaction-payment/src/weights.rs deleted file mode 100644 index bcffb2eb331..00000000000 --- a/substrate/frame/transaction-payment/src/weights.rs +++ /dev/null @@ -1,92 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// 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. - -//! Autogenerated weights for `pallet_transaction_payment` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` - -// Executed Command: -// ./target/production/substrate-node -// benchmark -// pallet -// --chain=dev -// --steps=50 -// --repeat=20 -// --pallet=pallet_transaction_payment -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* -// --wasm-execution=compiled -// --heap-pages=4096 -// --output=./substrate/frame/transaction-payment/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; -use core::marker::PhantomData; - -/// Weight functions needed for `pallet_transaction_payment`. -pub trait WeightInfo { - fn charge_transaction_payment() -> Weight; -} - -/// Weights for `pallet_transaction_payment` using the Substrate node and recommended hardware. -pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - fn charge_transaction_payment() -> Weight { - // Proof Size summary in bytes: - // Measured: `248` - // Estimated: `1733` - // Minimum execution time: 40_506_000 picoseconds. - Weight::from_parts(41_647_000, 1733) - .saturating_add(T::DbWeight::get().reads(3_u64)) - } -} - -// For backwards compatibility and tests. -impl WeightInfo for () { - /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) - /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Authorship::Author` (r:1 w:0) - /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:0) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - fn charge_transaction_payment() -> Weight { - // Proof Size summary in bytes: - // Measured: `248` - // Estimated: `1733` - // Minimum execution time: 40_506_000 picoseconds. - Weight::from_parts(41_647_000, 1733) - .saturating_add(RocksDbWeight::get().reads(3_u64)) - } -} diff --git a/substrate/frame/transaction-storage/src/weights.rs b/substrate/frame/transaction-storage/src/weights.rs index bfbed62c5a3..519317177c4 100644 --- a/substrate/frame/transaction-storage/src/weights.rs +++ b/substrate/frame/transaction-storage/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_transaction_storage` +//! Autogenerated weights for pallet_transaction_storage //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/transaction-storage/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/transaction-storage/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,133 +50,125 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_transaction_storage`. +/// Weight functions needed for pallet_transaction_storage. pub trait WeightInfo { fn store(l: u32, ) -> Weight; fn renew() -> Weight; fn check_proof_max() -> Weight; } -/// Weights for `pallet_transaction_storage` using the Substrate node and recommended hardware. +/// Weights for pallet_transaction_storage using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `TransactionStorage::ByteFee` (r:1 w:0) - /// Proof: `TransactionStorage::ByteFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `TransactionStorage::EntryFee` (r:1 w:0) - /// Proof: `TransactionStorage::EntryFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) - /// Storage: `TransactionStorage::BlockTransactions` (r:1 w:1) - /// Proof: `TransactionStorage::BlockTransactions` (`max_values`: Some(1), `max_size`: Some(36866), added: 37361, mode: `MaxEncodedLen`) + /// Storage: TransactionStorage ByteFee (r:1 w:0) + /// Proof: TransactionStorage ByteFee (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: TransactionStorage EntryFee (r:1 w:0) + /// Proof: TransactionStorage EntryFee (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: TransactionStorage BlockTransactions (r:1 w:1) + /// Proof: TransactionStorage BlockTransactions (max_values: Some(1), max_size: Some(36866), added: 37361, mode: MaxEncodedLen) /// The range of component `l` is `[1, 8388608]`. fn store(l: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `242` + // Measured: `176` // Estimated: `38351` - // Minimum execution time: 57_912_000 picoseconds. - Weight::from_parts(58_642_000, 38351) + // Minimum execution time: 34_844_000 picoseconds. + Weight::from_parts(35_489_000, 38351) // Standard Error: 11 - .saturating_add(Weight::from_parts(6_778, 0).saturating_mul(l.into())) - .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + .saturating_add(Weight::from_parts(6_912, 0).saturating_mul(l.into())) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `TransactionStorage::Transactions` (r:1 w:0) - /// Proof: `TransactionStorage::Transactions` (`max_values`: None, `max_size`: Some(36886), added: 39361, mode: `MaxEncodedLen`) - /// Storage: `TransactionStorage::ByteFee` (r:1 w:0) - /// Proof: `TransactionStorage::ByteFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `TransactionStorage::EntryFee` (r:1 w:0) - /// Proof: `TransactionStorage::EntryFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) - /// Storage: `TransactionStorage::BlockTransactions` (r:1 w:1) - /// Proof: `TransactionStorage::BlockTransactions` (`max_values`: Some(1), `max_size`: Some(36866), added: 37361, mode: `MaxEncodedLen`) + /// Storage: TransactionStorage Transactions (r:1 w:0) + /// Proof: TransactionStorage Transactions (max_values: None, max_size: Some(36886), added: 39361, mode: MaxEncodedLen) + /// Storage: TransactionStorage ByteFee (r:1 w:0) + /// Proof: TransactionStorage ByteFee (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: TransactionStorage EntryFee (r:1 w:0) + /// Proof: TransactionStorage EntryFee (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: TransactionStorage BlockTransactions (r:1 w:1) + /// Proof: TransactionStorage BlockTransactions (max_values: Some(1), max_size: Some(36866), added: 37361, mode: MaxEncodedLen) fn renew() -> Weight { // Proof Size summary in bytes: - // Measured: `430` + // Measured: `326` // Estimated: `40351` - // Minimum execution time: 72_571_000 picoseconds. - Weight::from_parts(74_832_000, 40351) - .saturating_add(T::DbWeight::get().reads(5_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + // Minimum execution time: 48_244_000 picoseconds. + Weight::from_parts(50_939_000, 40351) + .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `TransactionStorage::ProofChecked` (r:1 w:1) - /// Proof: `TransactionStorage::ProofChecked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) - /// Storage: `TransactionStorage::StoragePeriod` (r:1 w:0) - /// Proof: `TransactionStorage::StoragePeriod` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TransactionStorage::ChunkCount` (r:1 w:0) - /// Proof: `TransactionStorage::ChunkCount` (`max_values`: None, `max_size`: Some(24), added: 2499, mode: `MaxEncodedLen`) - /// Storage: `System::ParentHash` (r:1 w:0) - /// Proof: `System::ParentHash` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `TransactionStorage::Transactions` (r:1 w:0) - /// Proof: `TransactionStorage::Transactions` (`max_values`: None, `max_size`: Some(36886), added: 39361, mode: `MaxEncodedLen`) + /// Storage: TransactionStorage ProofChecked (r:1 w:1) + /// Proof: TransactionStorage ProofChecked (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: TransactionStorage StoragePeriod (r:1 w:0) + /// Proof: TransactionStorage StoragePeriod (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: TransactionStorage ChunkCount (r:1 w:0) + /// Proof: TransactionStorage ChunkCount (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) + /// Storage: System ParentHash (r:1 w:0) + /// Proof: System ParentHash (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TransactionStorage Transactions (r:1 w:0) + /// Proof: TransactionStorage Transactions (max_values: None, max_size: Some(36886), added: 39361, mode: MaxEncodedLen) fn check_proof_max() -> Weight { // Proof Size summary in bytes: - // Measured: `37211` + // Measured: `37145` // Estimated: `40351` - // Minimum execution time: 65_985_000 picoseconds. - Weight::from_parts(72_960_000, 40351) + // Minimum execution time: 80_913_000 picoseconds. + Weight::from_parts(84_812_000, 40351) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `TransactionStorage::ByteFee` (r:1 w:0) - /// Proof: `TransactionStorage::ByteFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `TransactionStorage::EntryFee` (r:1 w:0) - /// Proof: `TransactionStorage::EntryFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) - /// Storage: `TransactionStorage::BlockTransactions` (r:1 w:1) - /// Proof: `TransactionStorage::BlockTransactions` (`max_values`: Some(1), `max_size`: Some(36866), added: 37361, mode: `MaxEncodedLen`) + /// Storage: TransactionStorage ByteFee (r:1 w:0) + /// Proof: TransactionStorage ByteFee (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: TransactionStorage EntryFee (r:1 w:0) + /// Proof: TransactionStorage EntryFee (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: TransactionStorage BlockTransactions (r:1 w:1) + /// Proof: TransactionStorage BlockTransactions (max_values: Some(1), max_size: Some(36866), added: 37361, mode: MaxEncodedLen) /// The range of component `l` is `[1, 8388608]`. fn store(l: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `242` + // Measured: `176` // Estimated: `38351` - // Minimum execution time: 57_912_000 picoseconds. - Weight::from_parts(58_642_000, 38351) + // Minimum execution time: 34_844_000 picoseconds. + Weight::from_parts(35_489_000, 38351) // Standard Error: 11 - .saturating_add(Weight::from_parts(6_778, 0).saturating_mul(l.into())) - .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) + .saturating_add(Weight::from_parts(6_912, 0).saturating_mul(l.into())) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `TransactionStorage::Transactions` (r:1 w:0) - /// Proof: `TransactionStorage::Transactions` (`max_values`: None, `max_size`: Some(36886), added: 39361, mode: `MaxEncodedLen`) - /// Storage: `TransactionStorage::ByteFee` (r:1 w:0) - /// Proof: `TransactionStorage::ByteFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `TransactionStorage::EntryFee` (r:1 w:0) - /// Proof: `TransactionStorage::EntryFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(193), added: 2668, mode: `MaxEncodedLen`) - /// Storage: `TransactionStorage::BlockTransactions` (r:1 w:1) - /// Proof: `TransactionStorage::BlockTransactions` (`max_values`: Some(1), `max_size`: Some(36866), added: 37361, mode: `MaxEncodedLen`) + /// Storage: TransactionStorage Transactions (r:1 w:0) + /// Proof: TransactionStorage Transactions (max_values: None, max_size: Some(36886), added: 39361, mode: MaxEncodedLen) + /// Storage: TransactionStorage ByteFee (r:1 w:0) + /// Proof: TransactionStorage ByteFee (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: TransactionStorage EntryFee (r:1 w:0) + /// Proof: TransactionStorage EntryFee (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: TransactionStorage BlockTransactions (r:1 w:1) + /// Proof: TransactionStorage BlockTransactions (max_values: Some(1), max_size: Some(36866), added: 37361, mode: MaxEncodedLen) fn renew() -> Weight { // Proof Size summary in bytes: - // Measured: `430` + // Measured: `326` // Estimated: `40351` - // Minimum execution time: 72_571_000 picoseconds. - Weight::from_parts(74_832_000, 40351) - .saturating_add(RocksDbWeight::get().reads(5_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) + // Minimum execution time: 48_244_000 picoseconds. + Weight::from_parts(50_939_000, 40351) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `TransactionStorage::ProofChecked` (r:1 w:1) - /// Proof: `TransactionStorage::ProofChecked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) - /// Storage: `TransactionStorage::StoragePeriod` (r:1 w:0) - /// Proof: `TransactionStorage::StoragePeriod` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TransactionStorage::ChunkCount` (r:1 w:0) - /// Proof: `TransactionStorage::ChunkCount` (`max_values`: None, `max_size`: Some(24), added: 2499, mode: `MaxEncodedLen`) - /// Storage: `System::ParentHash` (r:1 w:0) - /// Proof: `System::ParentHash` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `TransactionStorage::Transactions` (r:1 w:0) - /// Proof: `TransactionStorage::Transactions` (`max_values`: None, `max_size`: Some(36886), added: 39361, mode: `MaxEncodedLen`) + /// Storage: TransactionStorage ProofChecked (r:1 w:1) + /// Proof: TransactionStorage ProofChecked (max_values: Some(1), max_size: Some(1), added: 496, mode: MaxEncodedLen) + /// Storage: TransactionStorage StoragePeriod (r:1 w:0) + /// Proof: TransactionStorage StoragePeriod (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: TransactionStorage ChunkCount (r:1 w:0) + /// Proof: TransactionStorage ChunkCount (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) + /// Storage: System ParentHash (r:1 w:0) + /// Proof: System ParentHash (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) + /// Storage: TransactionStorage Transactions (r:1 w:0) + /// Proof: TransactionStorage Transactions (max_values: None, max_size: Some(36886), added: 39361, mode: MaxEncodedLen) fn check_proof_max() -> Weight { // Proof Size summary in bytes: - // Measured: `37211` + // Measured: `37145` // Estimated: `40351` - // Minimum execution time: 65_985_000 picoseconds. - Weight::from_parts(72_960_000, 40351) + // Minimum execution time: 80_913_000 picoseconds. + Weight::from_parts(84_812_000, 40351) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/treasury/src/weights.rs b/substrate/frame/treasury/src/weights.rs index 8ef4f89fd65..030e18980eb 100644 --- a/substrate/frame/treasury/src/weights.rs +++ b/substrate/frame/treasury/src/weights.rs @@ -15,31 +15,27 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_treasury` +//! Autogenerated weights for pallet_treasury //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-07-07, STEPS: `20`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `cob`, CPU: `` +//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/debug/substrate // benchmark // pallet // --chain=dev -// --steps=50 -// --repeat=20 -// --pallet=pallet_treasury -// --no-storage-info -// --no-median-slopes -// --no-min-squares +// --steps=20 +// --repeat=2 +// --pallet=pallet-treasury // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/treasury/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/treasury/src/._weights.rs +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +45,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_treasury`. +/// Weight functions needed for pallet_treasury. pub trait WeightInfo { fn spend_local() -> Weight; fn propose_spend() -> Weight; @@ -63,304 +59,304 @@ pub trait WeightInfo { fn void_spend() -> Weight; } -/// Weights for `pallet_treasury` using the Substrate node and recommended hardware. +/// Weights for pallet_treasury using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Treasury::ProposalCount` (r:1 w:1) - /// Proof: `Treasury::ProposalCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Approvals` (r:1 w:1) - /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Proposals` (r:0 w:1) - /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Storage: Treasury ProposalCount (r:1 w:1) + /// Proof: Treasury ProposalCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: Treasury Proposals (r:0 w:1) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) fn spend_local() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `1887` - // Minimum execution time: 11_686_000 picoseconds. - Weight::from_parts(12_138_000, 1887) + // Minimum execution time: 179_000_000 picoseconds. + Weight::from_parts(190_000_000, 1887) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Treasury::ProposalCount` (r:1 w:1) - /// Proof: `Treasury::ProposalCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Proposals` (r:0 w:1) - /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Storage: Treasury ProposalCount (r:1 w:1) + /// Proof: Treasury ProposalCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Treasury Proposals (r:0 w:1) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) fn propose_spend() -> Weight { // Proof Size summary in bytes: // Measured: `177` // Estimated: `1489` - // Minimum execution time: 23_773_000 picoseconds. - Weight::from_parts(24_801_000, 1489) + // Minimum execution time: 349_000_000 picoseconds. + Weight::from_parts(398_000_000, 1489) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Treasury::Proposals` (r:1 w:1) - /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Treasury Proposals (r:1 w:1) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn reject_proposal() -> Weight { // Proof Size summary in bytes: // Measured: `335` // Estimated: `3593` - // Minimum execution time: 24_533_000 picoseconds. - Weight::from_parts(25_731_000, 3593) + // Minimum execution time: 367_000_000 picoseconds. + Weight::from_parts(388_000_000, 3593) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Treasury::Proposals` (r:1 w:0) - /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Approvals` (r:1 w:1) - /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: Treasury Proposals (r:1 w:0) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) /// The range of component `p` is `[0, 99]`. fn approve_proposal(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `504 + p * (8 ±0)` + // Measured: `483 + p * (9 ±0)` // Estimated: `3573` - // Minimum execution time: 8_245_000 picoseconds. - Weight::from_parts(11_300_222, 3573) - // Standard Error: 1_080 - .saturating_add(Weight::from_parts(71_375, 0).saturating_mul(p.into())) + // Minimum execution time: 111_000_000 picoseconds. + Weight::from_parts(108_813_243, 3573) + // Standard Error: 147_887 + .saturating_add(Weight::from_parts(683_216, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Treasury::Approvals` (r:1 w:1) - /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) fn remove_approval() -> Weight { // Proof Size summary in bytes: // Measured: `161` // Estimated: `1887` - // Minimum execution time: 6_231_000 picoseconds. - Weight::from_parts(6_517_000, 1887) + // Minimum execution time: 71_000_000 picoseconds. + Weight::from_parts(78_000_000, 1887) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Treasury::Deactivated` (r:1 w:1) - /// Proof: `Treasury::Deactivated` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Approvals` (r:1 w:1) - /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Proposals` (r:99 w:99) - /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:198 w:198) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Bounties::BountyApprovals` (r:1 w:1) - /// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: Treasury Deactivated (r:1 w:1) + /// Proof: Treasury Deactivated (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: Treasury Proposals (r:99 w:99) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: System Account (r:198 w:198) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyApprovals (r:1 w:1) + /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) /// The range of component `p` is `[0, 99]`. fn on_initialize_proposals(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `451 + p * (251 ±0)` + // Measured: `427 + p * (251 ±0)` // Estimated: `1887 + p * (5206 ±0)` - // Minimum execution time: 30_729_000 picoseconds. - Weight::from_parts(37_861_389, 1887) - // Standard Error: 18_741 - .saturating_add(Weight::from_parts(31_377_118, 0).saturating_mul(p.into())) + // Minimum execution time: 614_000_000 picoseconds. + Weight::from_parts(498_501_558, 1887) + // Standard Error: 1_070_260 + .saturating_add(Weight::from_parts(599_011_690, 0).saturating_mul(p.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(p.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(p.into()))) .saturating_add(Weight::from_parts(0, 5206).saturating_mul(p.into())) } - /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:0) - /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) - /// Storage: `Treasury::SpendCount` (r:1 w:1) - /// Proof: `Treasury::SpendCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Spends` (r:0 w:1) - /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: AssetRate ConversionRateToNative (r:1 w:0) + /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) + /// Storage: Treasury SpendCount (r:1 w:1) + /// Proof: Treasury SpendCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Treasury Spends (r:0 w:1) + /// Proof: Treasury Spends (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) fn spend() -> Weight { // Proof Size summary in bytes: // Measured: `140` // Estimated: `3501` - // Minimum execution time: 13_700_000 picoseconds. - Weight::from_parts(14_519_000, 3501) + // Minimum execution time: 214_000_000 picoseconds. + Weight::from_parts(216_000_000, 3501) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Treasury::Spends` (r:1 w:1) - /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:2 w:2) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Treasury Spends (r:1 w:1) + /// Proof: Treasury Spends (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:2 w:2) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn payout() -> Weight { // Proof Size summary in bytes: - // Measured: `709` + // Measured: `705` // Estimated: `6208` - // Minimum execution time: 54_888_000 picoseconds. - Weight::from_parts(55_966_000, 6208) + // Minimum execution time: 760_000_000 picoseconds. + Weight::from_parts(822_000_000, 6208) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: `Treasury::Spends` (r:1 w:1) - /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: Treasury Spends (r:1 w:1) + /// Proof: Treasury Spends (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) fn check_status() -> Weight { // Proof Size summary in bytes: - // Measured: `198` - // Estimated: `3538` - // Minimum execution time: 11_802_000 picoseconds. - Weight::from_parts(12_421_000, 3538) + // Measured: `194` + // Estimated: `3534` + // Minimum execution time: 153_000_000 picoseconds. + Weight::from_parts(160_000_000, 3534) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Treasury::Spends` (r:1 w:1) - /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: Treasury Spends (r:1 w:1) + /// Proof: Treasury Spends (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) fn void_spend() -> Weight { // Proof Size summary in bytes: - // Measured: `198` - // Estimated: `3538` - // Minimum execution time: 10_571_000 picoseconds. - Weight::from_parts(11_052_000, 3538) + // Measured: `194` + // Estimated: `3534` + // Minimum execution time: 147_000_000 picoseconds. + Weight::from_parts(181_000_000, 3534) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Treasury::ProposalCount` (r:1 w:1) - /// Proof: `Treasury::ProposalCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Approvals` (r:1 w:1) - /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Proposals` (r:0 w:1) - /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Storage: Treasury ProposalCount (r:1 w:1) + /// Proof: Treasury ProposalCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: Treasury Proposals (r:0 w:1) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) fn spend_local() -> Weight { // Proof Size summary in bytes: // Measured: `76` // Estimated: `1887` - // Minimum execution time: 11_686_000 picoseconds. - Weight::from_parts(12_138_000, 1887) + // Minimum execution time: 179_000_000 picoseconds. + Weight::from_parts(190_000_000, 1887) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Treasury::ProposalCount` (r:1 w:1) - /// Proof: `Treasury::ProposalCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Proposals` (r:0 w:1) - /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Storage: Treasury ProposalCount (r:1 w:1) + /// Proof: Treasury ProposalCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Treasury Proposals (r:0 w:1) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) fn propose_spend() -> Weight { // Proof Size summary in bytes: // Measured: `177` // Estimated: `1489` - // Minimum execution time: 23_773_000 picoseconds. - Weight::from_parts(24_801_000, 1489) + // Minimum execution time: 349_000_000 picoseconds. + Weight::from_parts(398_000_000, 1489) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Treasury::Proposals` (r:1 w:1) - /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Treasury Proposals (r:1 w:1) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn reject_proposal() -> Weight { // Proof Size summary in bytes: // Measured: `335` // Estimated: `3593` - // Minimum execution time: 24_533_000 picoseconds. - Weight::from_parts(25_731_000, 3593) + // Minimum execution time: 367_000_000 picoseconds. + Weight::from_parts(388_000_000, 3593) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Treasury::Proposals` (r:1 w:0) - /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Approvals` (r:1 w:1) - /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: Treasury Proposals (r:1 w:0) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) /// The range of component `p` is `[0, 99]`. fn approve_proposal(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `504 + p * (8 ±0)` + // Measured: `483 + p * (9 ±0)` // Estimated: `3573` - // Minimum execution time: 8_245_000 picoseconds. - Weight::from_parts(11_300_222, 3573) - // Standard Error: 1_080 - .saturating_add(Weight::from_parts(71_375, 0).saturating_mul(p.into())) + // Minimum execution time: 111_000_000 picoseconds. + Weight::from_parts(108_813_243, 3573) + // Standard Error: 147_887 + .saturating_add(Weight::from_parts(683_216, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Treasury::Approvals` (r:1 w:1) - /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) fn remove_approval() -> Weight { // Proof Size summary in bytes: // Measured: `161` // Estimated: `1887` - // Minimum execution time: 6_231_000 picoseconds. - Weight::from_parts(6_517_000, 1887) + // Minimum execution time: 71_000_000 picoseconds. + Weight::from_parts(78_000_000, 1887) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Treasury::Deactivated` (r:1 w:1) - /// Proof: `Treasury::Deactivated` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Approvals` (r:1 w:1) - /// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Proposals` (r:99 w:99) - /// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:198 w:198) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Bounties::BountyApprovals` (r:1 w:1) - /// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`) + /// Storage: Treasury Deactivated (r:1 w:1) + /// Proof: Treasury Deactivated (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen) + /// Storage: Treasury Approvals (r:1 w:1) + /// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) + /// Storage: Treasury Proposals (r:99 w:99) + /// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen) + /// Storage: System Account (r:198 w:198) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: Bounties BountyApprovals (r:1 w:1) + /// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen) /// The range of component `p` is `[0, 99]`. fn on_initialize_proposals(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `451 + p * (251 ±0)` + // Measured: `427 + p * (251 ±0)` // Estimated: `1887 + p * (5206 ±0)` - // Minimum execution time: 30_729_000 picoseconds. - Weight::from_parts(37_861_389, 1887) - // Standard Error: 18_741 - .saturating_add(Weight::from_parts(31_377_118, 0).saturating_mul(p.into())) + // Minimum execution time: 614_000_000 picoseconds. + Weight::from_parts(498_501_558, 1887) + // Standard Error: 1_070_260 + .saturating_add(Weight::from_parts(599_011_690, 0).saturating_mul(p.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(p.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(p.into()))) .saturating_add(Weight::from_parts(0, 5206).saturating_mul(p.into())) } - /// Storage: `AssetRate::ConversionRateToNative` (r:1 w:0) - /// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) - /// Storage: `Treasury::SpendCount` (r:1 w:1) - /// Proof: `Treasury::SpendCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Treasury::Spends` (r:0 w:1) - /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: AssetRate ConversionRateToNative (r:1 w:0) + /// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) + /// Storage: Treasury SpendCount (r:1 w:1) + /// Proof: Treasury SpendCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: Treasury Spends (r:0 w:1) + /// Proof: Treasury Spends (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) fn spend() -> Weight { // Proof Size summary in bytes: // Measured: `140` // Estimated: `3501` - // Minimum execution time: 13_700_000 picoseconds. - Weight::from_parts(14_519_000, 3501) + // Minimum execution time: 214_000_000 picoseconds. + Weight::from_parts(216_000_000, 3501) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Treasury::Spends` (r:1 w:1) - /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:2 w:2) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: Treasury Spends (r:1 w:1) + /// Proof: Treasury Spends (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(210), added: 2685, mode: MaxEncodedLen) + /// Storage: Assets Account (r:2 w:2) + /// Proof: Assets Account (max_values: None, max_size: Some(134), added: 2609, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn payout() -> Weight { // Proof Size summary in bytes: - // Measured: `709` + // Measured: `705` // Estimated: `6208` - // Minimum execution time: 54_888_000 picoseconds. - Weight::from_parts(55_966_000, 6208) + // Minimum execution time: 760_000_000 picoseconds. + Weight::from_parts(822_000_000, 6208) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } - /// Storage: `Treasury::Spends` (r:1 w:1) - /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: Treasury Spends (r:1 w:1) + /// Proof: Treasury Spends (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) fn check_status() -> Weight { // Proof Size summary in bytes: - // Measured: `198` - // Estimated: `3538` - // Minimum execution time: 11_802_000 picoseconds. - Weight::from_parts(12_421_000, 3538) + // Measured: `194` + // Estimated: `3534` + // Minimum execution time: 153_000_000 picoseconds. + Weight::from_parts(160_000_000, 3534) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Treasury::Spends` (r:1 w:1) - /// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: Treasury Spends (r:1 w:1) + /// Proof: Treasury Spends (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen) fn void_spend() -> Weight { // Proof Size summary in bytes: - // Measured: `198` - // Estimated: `3538` - // Minimum execution time: 10_571_000 picoseconds. - Weight::from_parts(11_052_000, 3538) + // Measured: `194` + // Estimated: `3534` + // Minimum execution time: 147_000_000 picoseconds. + Weight::from_parts(181_000_000, 3534) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/tx-pause/src/weights.rs b/substrate/frame/tx-pause/src/weights.rs index 14fead12a8e..b733e64b159 100644 --- a/substrate/frame/tx-pause/src/weights.rs +++ b/substrate/frame/tx-pause/src/weights.rs @@ -17,29 +17,27 @@ //! Autogenerated weights for `pallet_tx_pause` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-08-24, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-aahe6cbd-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate-node +// target/production/substrate-node // benchmark // pallet -// --chain=dev // --steps=50 // --repeat=20 -// --pallet=pallet_tx_pause -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/tx-pause/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --json-file=/builds/parity/mirrors/substrate/.git/.artifacts/bench.json +// --pallet=pallet_tx_pause +// --chain=dev +// --header=./HEADER-APACHE2 +// --output=./frame/tx-pause/src/weights.rs +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -64,8 +62,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `3` // Estimated: `3997` - // Minimum execution time: 12_014_000 picoseconds. - Weight::from_parts(12_980_000, 3997) + // Minimum execution time: 15_096_000 picoseconds. + Weight::from_parts(15_437_000, 3997) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -75,8 +73,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `565` // Estimated: `3997` - // Minimum execution time: 17_955_000 picoseconds. - Weight::from_parts(18_348_000, 3997) + // Minimum execution time: 21_546_000 picoseconds. + Weight::from_parts(22_178_000, 3997) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -90,8 +88,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `3` // Estimated: `3997` - // Minimum execution time: 12_014_000 picoseconds. - Weight::from_parts(12_980_000, 3997) + // Minimum execution time: 15_096_000 picoseconds. + Weight::from_parts(15_437_000, 3997) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -101,8 +99,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `565` // Estimated: `3997` - // Minimum execution time: 17_955_000 picoseconds. - Weight::from_parts(18_348_000, 3997) + // Minimum execution time: 21_546_000 picoseconds. + Weight::from_parts(22_178_000, 3997) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/substrate/frame/uniques/src/weights.rs b/substrate/frame/uniques/src/weights.rs index 6c7b60b82e5..eb80ee550a1 100644 --- a/substrate/frame/uniques/src/weights.rs +++ b/substrate/frame/uniques/src/weights.rs @@ -17,29 +17,27 @@ //! Autogenerated weights for `pallet_uniques` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-07-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-gghbxkbs-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: ``, WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate-node +// target/production/substrate // benchmark // pallet -// --chain=dev // --steps=50 // --repeat=20 -// --pallet=pallet_uniques -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/uniques/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --json-file=/builds/parity/mirrors/substrate/.git/.artifacts/bench.json +// --pallet=pallet_uniques +// --chain=dev +// --header=./HEADER-APACHE2 +// --output=./frame/uniques/src/weights.rs +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -90,8 +88,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `249` // Estimated: `3643` - // Minimum execution time: 27_960_000 picoseconds. - Weight::from_parts(28_781_000, 3643) + // Minimum execution time: 31_393_000 picoseconds. + Weight::from_parts(32_933_000, 3643) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -103,8 +101,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `109` // Estimated: `3643` - // Minimum execution time: 11_970_000 picoseconds. - Weight::from_parts(12_512_000, 3643) + // Minimum execution time: 14_827_000 picoseconds. + Weight::from_parts(15_273_000, 3643) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -113,13 +111,13 @@ impl WeightInfo for SubstrateWeight { /// Storage: `Uniques::Asset` (r:1001 w:1000) /// Proof: `Uniques::Asset` (`max_values`: None, `max_size`: Some(122), added: 2597, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1000 w:1000) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) /// Storage: `Uniques::Attribute` (r:1000 w:1000) - /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(172), added: 2647, mode: `MaxEncodedLen`) + /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassAccount` (r:0 w:1) /// Proof: `Uniques::ClassAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassMetadataOf` (r:0 w:1) - /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(167), added: 2642, mode: `MaxEncodedLen`) + /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) /// Storage: `Uniques::Account` (r:0 w:1000) /// Proof: `Uniques::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) /// Storage: `Uniques::CollectionMaxSupply` (r:0 w:1) @@ -130,15 +128,15 @@ impl WeightInfo for SubstrateWeight { fn destroy(n: u32, m: u32, a: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `418 + a * (107 ±0) + m * (56 ±0) + n * (76 ±0)` - // Estimated: `3643 + a * (2647 ±0) + m * (2662 ±0) + n * (2597 ±0)` - // Minimum execution time: 2_979_858_000 picoseconds. - Weight::from_parts(3_007_268_000, 3643) - // Standard Error: 29_899 - .saturating_add(Weight::from_parts(6_943_612, 0).saturating_mul(n.into())) - // Standard Error: 29_899 - .saturating_add(Weight::from_parts(398_114, 0).saturating_mul(m.into())) - // Standard Error: 29_899 - .saturating_add(Weight::from_parts(369_941, 0).saturating_mul(a.into())) + // Estimated: `3643 + a * (2839 ±0) + m * (2583 ±0) + n * (2597 ±0)` + // Minimum execution time: 3_281_673_000 picoseconds. + Weight::from_parts(3_443_387_000, 3643) + // Standard Error: 41_937 + .saturating_add(Weight::from_parts(7_914_842, 0).saturating_mul(n.into())) + // Standard Error: 41_937 + .saturating_add(Weight::from_parts(519_960, 0).saturating_mul(m.into())) + // Standard Error: 41_937 + .saturating_add(Weight::from_parts(462_690, 0).saturating_mul(a.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(m.into()))) @@ -147,8 +145,8 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(m.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(a.into()))) - .saturating_add(Weight::from_parts(0, 2647).saturating_mul(a.into())) - .saturating_add(Weight::from_parts(0, 2662).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 2839).saturating_mul(a.into())) + .saturating_add(Weight::from_parts(0, 2583).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 2597).saturating_mul(n.into())) } /// Storage: `Uniques::Asset` (r:1 w:1) @@ -163,8 +161,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 32_733_000 picoseconds. - Weight::from_parts(33_487_000, 3643) + // Minimum execution time: 38_122_000 picoseconds. + Weight::from_parts(38_924_000, 3643) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -180,8 +178,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 34_202_000 picoseconds. - Weight::from_parts(35_146_000, 3643) + // Minimum execution time: 38_835_000 picoseconds. + Weight::from_parts(39_754_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -197,8 +195,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 24_285_000 picoseconds. - Weight::from_parts(25_300_000, 3643) + // Minimum execution time: 27_032_000 picoseconds. + Weight::from_parts(27_793_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -211,10 +209,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `805 + i * (76 ±0)` // Estimated: `3643 + i * (2597 ±0)` - // Minimum execution time: 11_641_000 picoseconds. - Weight::from_parts(12_261_000, 3643) - // Standard Error: 18_897 - .saturating_add(Weight::from_parts(15_263_570, 0).saturating_mul(i.into())) + // Minimum execution time: 14_737_000 picoseconds. + Weight::from_parts(15_070_000, 3643) + // Standard Error: 22_500 + .saturating_add(Weight::from_parts(18_855_468, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(i.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) @@ -229,8 +227,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 16_122_000 picoseconds. - Weight::from_parts(16_627_000, 3643) + // Minimum execution time: 18_664_000 picoseconds. + Weight::from_parts(19_455_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -242,8 +240,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 15_824_000 picoseconds. - Weight::from_parts(16_522_000, 3643) + // Minimum execution time: 18_247_000 picoseconds. + Weight::from_parts(18_763_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -253,8 +251,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 10_802_000 picoseconds. - Weight::from_parts(11_206_000, 3643) + // Minimum execution time: 13_219_000 picoseconds. + Weight::from_parts(13_923_000, 3643) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -264,8 +262,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 10_805_000 picoseconds. - Weight::from_parts(11_340_000, 3643) + // Minimum execution time: 13_376_000 picoseconds. + Weight::from_parts(13_904_000, 3643) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -273,18 +271,16 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Uniques::OwnershipAcceptance` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassAccount` (r:0 w:2) /// Proof: `Uniques::ClassAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn transfer_ownership() -> Weight { // Proof Size summary in bytes: - // Measured: `597` + // Measured: `423` // Estimated: `3643` - // Minimum execution time: 24_213_000 picoseconds. - Weight::from_parts(25_547_000, 3643) - .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(5_u64)) + // Minimum execution time: 22_353_000 picoseconds. + Weight::from_parts(23_222_000, 3643) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) @@ -292,8 +288,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 11_256_000 picoseconds. - Weight::from_parts(11_585_000, 3643) + // Minimum execution time: 14_072_000 picoseconds. + Weight::from_parts(14_619_000, 3643) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -305,90 +301,90 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 14_616_000 picoseconds. - Weight::from_parts(15_064_000, 3643) + // Minimum execution time: 17_081_000 picoseconds. + Weight::from_parts(17_698_000, 3643) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1 w:0) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) /// Storage: `Uniques::Attribute` (r:1 w:1) - /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(172), added: 2647, mode: `MaxEncodedLen`) + /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) fn set_attribute() -> Weight { // Proof Size summary in bytes: - // Measured: `626` - // Estimated: `3652` - // Minimum execution time: 35_640_000 picoseconds. - Weight::from_parts(37_007_000, 3652) + // Measured: `547` + // Estimated: `3829` + // Minimum execution time: 41_501_000 picoseconds. + Weight::from_parts(43_101_000, 3829) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1 w:0) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) /// Storage: `Uniques::Attribute` (r:1 w:1) - /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(172), added: 2647, mode: `MaxEncodedLen`) + /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) fn clear_attribute() -> Weight { // Proof Size summary in bytes: - // Measured: `823` - // Estimated: `3652` - // Minimum execution time: 34_410_000 picoseconds. - Weight::from_parts(35_431_000, 3652) + // Measured: `936` + // Estimated: `3829` + // Minimum execution time: 39_722_000 picoseconds. + Weight::from_parts(40_390_000, 3829) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1 w:1) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) fn set_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `415` - // Estimated: `3652` - // Minimum execution time: 26_187_000 picoseconds. - Weight::from_parts(27_837_000, 3652) + // Estimated: `3643` + // Minimum execution time: 30_726_000 picoseconds. + Weight::from_parts(31_557_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1 w:1) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) fn clear_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `626` - // Estimated: `3652` - // Minimum execution time: 26_640_000 picoseconds. - Weight::from_parts(27_688_000, 3652) + // Measured: `547` + // Estimated: `3643` + // Minimum execution time: 31_303_000 picoseconds. + Weight::from_parts(32_389_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassMetadataOf` (r:1 w:1) - /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(167), added: 2642, mode: `MaxEncodedLen`) + /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) fn set_collection_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 26_781_000 picoseconds. - Weight::from_parts(27_628_000, 3643) + // Minimum execution time: 32_155_000 picoseconds. + Weight::from_parts(32_885_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:0) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassMetadataOf` (r:1 w:1) - /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(167), added: 2642, mode: `MaxEncodedLen`) + /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) fn clear_collection_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `540` + // Measured: `461` // Estimated: `3643` - // Minimum execution time: 26_295_000 picoseconds. - Weight::from_parts(26_903_000, 3643) + // Minimum execution time: 30_044_000 picoseconds. + Weight::from_parts(31_405_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -400,8 +396,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 16_678_000 picoseconds. - Weight::from_parts(17_548_000, 3643) + // Minimum execution time: 18_904_000 picoseconds. + Weight::from_parts(19_687_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -413,8 +409,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `528` // Estimated: `3643` - // Minimum execution time: 16_408_000 picoseconds. - Weight::from_parts(16_957_000, 3643) + // Minimum execution time: 19_144_000 picoseconds. + Weight::from_parts(19_706_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -424,8 +420,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `109` // Estimated: `3517` - // Minimum execution time: 12_568_000 picoseconds. - Weight::from_parts(12_960_000, 3517) + // Minimum execution time: 15_339_000 picoseconds. + Weight::from_parts(15_918_000, 3517) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -437,8 +433,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 13_110_000 picoseconds. - Weight::from_parts(13_620_000, 3643) + // Minimum execution time: 15_387_000 picoseconds. + Weight::from_parts(15_726_000, 3643) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -450,8 +446,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `326` // Estimated: `3587` - // Minimum execution time: 13_568_000 picoseconds. - Weight::from_parts(14_211_000, 3587) + // Minimum execution time: 15_873_000 picoseconds. + Weight::from_parts(16_860_000, 3587) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -467,8 +463,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `607` // Estimated: `3643` - // Minimum execution time: 32_660_000 picoseconds. - Weight::from_parts(33_734_000, 3643) + // Minimum execution time: 37_245_000 picoseconds. + Weight::from_parts(38_383_000, 3643) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -484,8 +480,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `249` // Estimated: `3643` - // Minimum execution time: 27_960_000 picoseconds. - Weight::from_parts(28_781_000, 3643) + // Minimum execution time: 31_393_000 picoseconds. + Weight::from_parts(32_933_000, 3643) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -497,8 +493,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `109` // Estimated: `3643` - // Minimum execution time: 11_970_000 picoseconds. - Weight::from_parts(12_512_000, 3643) + // Minimum execution time: 14_827_000 picoseconds. + Weight::from_parts(15_273_000, 3643) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -507,13 +503,13 @@ impl WeightInfo for () { /// Storage: `Uniques::Asset` (r:1001 w:1000) /// Proof: `Uniques::Asset` (`max_values`: None, `max_size`: Some(122), added: 2597, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1000 w:1000) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) /// Storage: `Uniques::Attribute` (r:1000 w:1000) - /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(172), added: 2647, mode: `MaxEncodedLen`) + /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassAccount` (r:0 w:1) /// Proof: `Uniques::ClassAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassMetadataOf` (r:0 w:1) - /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(167), added: 2642, mode: `MaxEncodedLen`) + /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) /// Storage: `Uniques::Account` (r:0 w:1000) /// Proof: `Uniques::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) /// Storage: `Uniques::CollectionMaxSupply` (r:0 w:1) @@ -524,15 +520,15 @@ impl WeightInfo for () { fn destroy(n: u32, m: u32, a: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `418 + a * (107 ±0) + m * (56 ±0) + n * (76 ±0)` - // Estimated: `3643 + a * (2647 ±0) + m * (2662 ±0) + n * (2597 ±0)` - // Minimum execution time: 2_979_858_000 picoseconds. - Weight::from_parts(3_007_268_000, 3643) - // Standard Error: 29_899 - .saturating_add(Weight::from_parts(6_943_612, 0).saturating_mul(n.into())) - // Standard Error: 29_899 - .saturating_add(Weight::from_parts(398_114, 0).saturating_mul(m.into())) - // Standard Error: 29_899 - .saturating_add(Weight::from_parts(369_941, 0).saturating_mul(a.into())) + // Estimated: `3643 + a * (2839 ±0) + m * (2583 ±0) + n * (2597 ±0)` + // Minimum execution time: 3_281_673_000 picoseconds. + Weight::from_parts(3_443_387_000, 3643) + // Standard Error: 41_937 + .saturating_add(Weight::from_parts(7_914_842, 0).saturating_mul(n.into())) + // Standard Error: 41_937 + .saturating_add(Weight::from_parts(519_960, 0).saturating_mul(m.into())) + // Standard Error: 41_937 + .saturating_add(Weight::from_parts(462_690, 0).saturating_mul(a.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(m.into()))) @@ -541,8 +537,8 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().writes((2_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(m.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(a.into()))) - .saturating_add(Weight::from_parts(0, 2647).saturating_mul(a.into())) - .saturating_add(Weight::from_parts(0, 2662).saturating_mul(m.into())) + .saturating_add(Weight::from_parts(0, 2839).saturating_mul(a.into())) + .saturating_add(Weight::from_parts(0, 2583).saturating_mul(m.into())) .saturating_add(Weight::from_parts(0, 2597).saturating_mul(n.into())) } /// Storage: `Uniques::Asset` (r:1 w:1) @@ -557,8 +553,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 32_733_000 picoseconds. - Weight::from_parts(33_487_000, 3643) + // Minimum execution time: 38_122_000 picoseconds. + Weight::from_parts(38_924_000, 3643) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -574,8 +570,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 34_202_000 picoseconds. - Weight::from_parts(35_146_000, 3643) + // Minimum execution time: 38_835_000 picoseconds. + Weight::from_parts(39_754_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -591,8 +587,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 24_285_000 picoseconds. - Weight::from_parts(25_300_000, 3643) + // Minimum execution time: 27_032_000 picoseconds. + Weight::from_parts(27_793_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -605,10 +601,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `805 + i * (76 ±0)` // Estimated: `3643 + i * (2597 ±0)` - // Minimum execution time: 11_641_000 picoseconds. - Weight::from_parts(12_261_000, 3643) - // Standard Error: 18_897 - .saturating_add(Weight::from_parts(15_263_570, 0).saturating_mul(i.into())) + // Minimum execution time: 14_737_000 picoseconds. + Weight::from_parts(15_070_000, 3643) + // Standard Error: 22_500 + .saturating_add(Weight::from_parts(18_855_468, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(i.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) @@ -623,8 +619,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 16_122_000 picoseconds. - Weight::from_parts(16_627_000, 3643) + // Minimum execution time: 18_664_000 picoseconds. + Weight::from_parts(19_455_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -636,8 +632,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 15_824_000 picoseconds. - Weight::from_parts(16_522_000, 3643) + // Minimum execution time: 18_247_000 picoseconds. + Weight::from_parts(18_763_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -647,8 +643,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 10_802_000 picoseconds. - Weight::from_parts(11_206_000, 3643) + // Minimum execution time: 13_219_000 picoseconds. + Weight::from_parts(13_923_000, 3643) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -658,8 +654,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 10_805_000 picoseconds. - Weight::from_parts(11_340_000, 3643) + // Minimum execution time: 13_376_000 picoseconds. + Weight::from_parts(13_904_000, 3643) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -667,18 +663,16 @@ impl WeightInfo for () { /// Proof: `Uniques::OwnershipAcceptance` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassAccount` (r:0 w:2) /// Proof: `Uniques::ClassAccount` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) fn transfer_ownership() -> Weight { // Proof Size summary in bytes: - // Measured: `597` + // Measured: `423` // Estimated: `3643` - // Minimum execution time: 24_213_000 picoseconds. - Weight::from_parts(25_547_000, 3643) - .saturating_add(RocksDbWeight::get().reads(3_u64)) - .saturating_add(RocksDbWeight::get().writes(5_u64)) + // Minimum execution time: 22_353_000 picoseconds. + Weight::from_parts(23_222_000, 3643) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) @@ -686,8 +680,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 11_256_000 picoseconds. - Weight::from_parts(11_585_000, 3643) + // Minimum execution time: 14_072_000 picoseconds. + Weight::from_parts(14_619_000, 3643) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -699,90 +693,90 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 14_616_000 picoseconds. - Weight::from_parts(15_064_000, 3643) + // Minimum execution time: 17_081_000 picoseconds. + Weight::from_parts(17_698_000, 3643) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1 w:0) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) /// Storage: `Uniques::Attribute` (r:1 w:1) - /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(172), added: 2647, mode: `MaxEncodedLen`) + /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) fn set_attribute() -> Weight { // Proof Size summary in bytes: - // Measured: `626` - // Estimated: `3652` - // Minimum execution time: 35_640_000 picoseconds. - Weight::from_parts(37_007_000, 3652) + // Measured: `547` + // Estimated: `3829` + // Minimum execution time: 41_501_000 picoseconds. + Weight::from_parts(43_101_000, 3829) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1 w:0) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) /// Storage: `Uniques::Attribute` (r:1 w:1) - /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(172), added: 2647, mode: `MaxEncodedLen`) + /// Proof: `Uniques::Attribute` (`max_values`: None, `max_size`: Some(364), added: 2839, mode: `MaxEncodedLen`) fn clear_attribute() -> Weight { // Proof Size summary in bytes: - // Measured: `823` - // Estimated: `3652` - // Minimum execution time: 34_410_000 picoseconds. - Weight::from_parts(35_431_000, 3652) + // Measured: `936` + // Estimated: `3829` + // Minimum execution time: 39_722_000 picoseconds. + Weight::from_parts(40_390_000, 3829) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1 w:1) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) fn set_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `415` - // Estimated: `3652` - // Minimum execution time: 26_187_000 picoseconds. - Weight::from_parts(27_837_000, 3652) + // Estimated: `3643` + // Minimum execution time: 30_726_000 picoseconds. + Weight::from_parts(31_557_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::InstanceMetadataOf` (r:1 w:1) - /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(187), added: 2662, mode: `MaxEncodedLen`) + /// Proof: `Uniques::InstanceMetadataOf` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) fn clear_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `626` - // Estimated: `3652` - // Minimum execution time: 26_640_000 picoseconds. - Weight::from_parts(27_688_000, 3652) + // Measured: `547` + // Estimated: `3643` + // Minimum execution time: 31_303_000 picoseconds. + Weight::from_parts(32_389_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:1) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassMetadataOf` (r:1 w:1) - /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(167), added: 2642, mode: `MaxEncodedLen`) + /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) fn set_collection_metadata() -> Weight { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 26_781_000 picoseconds. - Weight::from_parts(27_628_000, 3643) + // Minimum execution time: 32_155_000 picoseconds. + Weight::from_parts(32_885_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Uniques::Class` (r:1 w:0) /// Proof: `Uniques::Class` (`max_values`: None, `max_size`: Some(178), added: 2653, mode: `MaxEncodedLen`) /// Storage: `Uniques::ClassMetadataOf` (r:1 w:1) - /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(167), added: 2642, mode: `MaxEncodedLen`) + /// Proof: `Uniques::ClassMetadataOf` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`) fn clear_collection_metadata() -> Weight { // Proof Size summary in bytes: - // Measured: `540` + // Measured: `461` // Estimated: `3643` - // Minimum execution time: 26_295_000 picoseconds. - Weight::from_parts(26_903_000, 3643) + // Minimum execution time: 30_044_000 picoseconds. + Weight::from_parts(31_405_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -794,8 +788,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3643` - // Minimum execution time: 16_678_000 picoseconds. - Weight::from_parts(17_548_000, 3643) + // Minimum execution time: 18_904_000 picoseconds. + Weight::from_parts(19_687_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -807,8 +801,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `528` // Estimated: `3643` - // Minimum execution time: 16_408_000 picoseconds. - Weight::from_parts(16_957_000, 3643) + // Minimum execution time: 19_144_000 picoseconds. + Weight::from_parts(19_706_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -818,8 +812,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `109` // Estimated: `3517` - // Minimum execution time: 12_568_000 picoseconds. - Weight::from_parts(12_960_000, 3517) + // Minimum execution time: 15_339_000 picoseconds. + Weight::from_parts(15_918_000, 3517) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -831,8 +825,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `349` // Estimated: `3643` - // Minimum execution time: 13_110_000 picoseconds. - Weight::from_parts(13_620_000, 3643) + // Minimum execution time: 15_387_000 picoseconds. + Weight::from_parts(15_726_000, 3643) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -844,8 +838,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `326` // Estimated: `3587` - // Minimum execution time: 13_568_000 picoseconds. - Weight::from_parts(14_211_000, 3587) + // Minimum execution time: 15_873_000 picoseconds. + Weight::from_parts(16_860_000, 3587) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -861,8 +855,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `607` // Estimated: `3643` - // Minimum execution time: 32_660_000 picoseconds. - Weight::from_parts(33_734_000, 3643) + // Minimum execution time: 37_245_000 picoseconds. + Weight::from_parts(38_383_000, 3643) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } diff --git a/substrate/frame/utility/src/weights.rs b/substrate/frame/utility/src/weights.rs index 60b1c48f086..1a3ea6c1f7f 100644 --- a/substrate/frame/utility/src/weights.rs +++ b/substrate/frame/utility/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_utility` +//! Autogenerated weights for pallet_utility //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/utility/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/utility/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_utility`. +/// Weight functions needed for pallet_utility. pub trait WeightInfo { fn batch(c: u32, ) -> Weight; fn as_derivative() -> Weight; @@ -58,139 +59,99 @@ pub trait WeightInfo { fn force_batch(c: u32, ) -> Weight; } -/// Weights for `pallet_utility` using the Substrate node and recommended hardware. +/// Weights for pallet_utility using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `c` is `[0, 1000]`. fn batch(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `145` - // Estimated: `3997` - // Minimum execution time: 5_143_000 picoseconds. - Weight::from_parts(11_552_299, 3997) - // Standard Error: 2_325 - .saturating_add(Weight::from_parts(4_708_951, 0).saturating_mul(c.into())) - .saturating_add(T::DbWeight::get().reads(2_u64)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_763_000 picoseconds. + Weight::from_parts(16_943_157, 0) + // Standard Error: 1_904 + .saturating_add(Weight::from_parts(4_653_855, 0).saturating_mul(c.into())) } - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) fn as_derivative() -> Weight { // Proof Size summary in bytes: - // Measured: `145` - // Estimated: `3997` - // Minimum execution time: 9_103_000 picoseconds. - Weight::from_parts(9_549_000, 3997) - .saturating_add(T::DbWeight::get().reads(2_u64)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_149_000 picoseconds. + Weight::from_parts(5_268_000, 0) } - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `c` is `[0, 1000]`. fn batch_all(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `145` - // Estimated: `3997` - // Minimum execution time: 5_147_000 picoseconds. - Weight::from_parts(15_698_086, 3997) - // Standard Error: 3_066 - .saturating_add(Weight::from_parts(4_809_412, 0).saturating_mul(c.into())) - .saturating_add(T::DbWeight::get().reads(2_u64)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_976_000 picoseconds. + Weight::from_parts(16_448_433, 0) + // Standard Error: 1_834 + .saturating_add(Weight::from_parts(4_796_983, 0).saturating_mul(c.into())) } fn dispatch_as() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_683_000 picoseconds. - Weight::from_parts(7_047_000, 0) + // Minimum execution time: 9_102_000 picoseconds. + Weight::from_parts(9_353_000, 0) } - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `c` is `[0, 1000]`. fn force_batch(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `145` - // Estimated: `3997` - // Minimum execution time: 4_982_000 picoseconds. - Weight::from_parts(14_474_780, 3997) - // Standard Error: 2_291 - .saturating_add(Weight::from_parts(4_632_643, 0).saturating_mul(c.into())) - .saturating_add(T::DbWeight::get().reads(2_u64)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_840_000 picoseconds. + Weight::from_parts(17_748_474, 0) + // Standard Error: 2_059 + .saturating_add(Weight::from_parts(4_630_079, 0).saturating_mul(c.into())) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `c` is `[0, 1000]`. fn batch(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `145` - // Estimated: `3997` - // Minimum execution time: 5_143_000 picoseconds. - Weight::from_parts(11_552_299, 3997) - // Standard Error: 2_325 - .saturating_add(Weight::from_parts(4_708_951, 0).saturating_mul(c.into())) - .saturating_add(RocksDbWeight::get().reads(2_u64)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_763_000 picoseconds. + Weight::from_parts(16_943_157, 0) + // Standard Error: 1_904 + .saturating_add(Weight::from_parts(4_653_855, 0).saturating_mul(c.into())) } - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) fn as_derivative() -> Weight { // Proof Size summary in bytes: - // Measured: `145` - // Estimated: `3997` - // Minimum execution time: 9_103_000 picoseconds. - Weight::from_parts(9_549_000, 3997) - .saturating_add(RocksDbWeight::get().reads(2_u64)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_149_000 picoseconds. + Weight::from_parts(5_268_000, 0) } - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `c` is `[0, 1000]`. fn batch_all(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `145` - // Estimated: `3997` - // Minimum execution time: 5_147_000 picoseconds. - Weight::from_parts(15_698_086, 3997) - // Standard Error: 3_066 - .saturating_add(Weight::from_parts(4_809_412, 0).saturating_mul(c.into())) - .saturating_add(RocksDbWeight::get().reads(2_u64)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_976_000 picoseconds. + Weight::from_parts(16_448_433, 0) + // Standard Error: 1_834 + .saturating_add(Weight::from_parts(4_796_983, 0).saturating_mul(c.into())) } fn dispatch_as() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_683_000 picoseconds. - Weight::from_parts(7_047_000, 0) + // Minimum execution time: 9_102_000 picoseconds. + Weight::from_parts(9_353_000, 0) } - /// Storage: `SafeMode::EnteredUntil` (r:1 w:0) - /// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `TxPause::PausedCalls` (r:1 w:0) - /// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`) /// The range of component `c` is `[0, 1000]`. fn force_batch(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `145` - // Estimated: `3997` - // Minimum execution time: 4_982_000 picoseconds. - Weight::from_parts(14_474_780, 3997) - // Standard Error: 2_291 - .saturating_add(Weight::from_parts(4_632_643, 0).saturating_mul(c.into())) - .saturating_add(RocksDbWeight::get().reads(2_u64)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_840_000 picoseconds. + Weight::from_parts(17_748_474, 0) + // Standard Error: 2_059 + .saturating_add(Weight::from_parts(4_630_079, 0).saturating_mul(c.into())) } } diff --git a/substrate/frame/vesting/src/weights.rs b/substrate/frame/vesting/src/weights.rs index d91c47ae195..ddc7db8fa61 100644 --- a/substrate/frame/vesting/src/weights.rs +++ b/substrate/frame/vesting/src/weights.rs @@ -17,28 +17,26 @@ //! Autogenerated weights for `pallet_vesting` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-10-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-vmdtonbz-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/production/substrate-node +// target/production/substrate-node // benchmark // pallet -// --chain=dev // --steps=50 // --repeat=20 -// --pallet=pallet_vesting -// --no-storage-info -// --no-median-slopes -// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/vesting/src/weights.rs +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_vesting +// --chain=dev // --header=./substrate/HEADER-APACHE2 +// --output=./substrate/frame/vesting/src/weights.rs // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -77,12 +75,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `381 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 31_890_000 picoseconds. - Weight::from_parts(31_128_476, 4764) - // Standard Error: 1_193 - .saturating_add(Weight::from_parts(63_760, 0).saturating_mul(l.into())) - // Standard Error: 2_124 - .saturating_add(Weight::from_parts(57_247, 0).saturating_mul(s.into())) + // Minimum execution time: 32_846_000 picoseconds. + Weight::from_parts(30_974_459, 4764) + // Standard Error: 1_755 + .saturating_add(Weight::from_parts(73_138, 0).saturating_mul(l.into())) + // Standard Error: 3_123 + .saturating_add(Weight::from_parts(82_417, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -98,12 +96,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `381 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 33_958_000 picoseconds. - Weight::from_parts(33_537_005, 4764) - // Standard Error: 1_354 - .saturating_add(Weight::from_parts(60_604, 0).saturating_mul(l.into())) - // Standard Error: 2_410 - .saturating_add(Weight::from_parts(51_378, 0).saturating_mul(s.into())) + // Minimum execution time: 34_360_000 picoseconds. + Weight::from_parts(34_964_080, 4764) + // Standard Error: 1_996 + .saturating_add(Weight::from_parts(48_024, 0).saturating_mul(l.into())) + // Standard Error: 3_552 + .saturating_add(Weight::from_parts(34_411, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -121,12 +119,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `484 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 33_243_000 picoseconds. - Weight::from_parts(32_552_805, 4764) - // Standard Error: 1_413 - .saturating_add(Weight::from_parts(67_137, 0).saturating_mul(l.into())) - // Standard Error: 2_515 - .saturating_add(Weight::from_parts(70_000, 0).saturating_mul(s.into())) + // Minimum execution time: 33_859_000 picoseconds. + Weight::from_parts(32_950_681, 4764) + // Standard Error: 1_745 + .saturating_add(Weight::from_parts(69_323, 0).saturating_mul(l.into())) + // Standard Error: 3_105 + .saturating_add(Weight::from_parts(86_370, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -144,12 +142,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `484 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 35_396_000 picoseconds. - Weight::from_parts(35_774_949, 4764) - // Standard Error: 1_404 - .saturating_add(Weight::from_parts(55_349, 0).saturating_mul(l.into())) - // Standard Error: 2_497 - .saturating_add(Weight::from_parts(39_228, 0).saturating_mul(s.into())) + // Minimum execution time: 36_239_000 picoseconds. + Weight::from_parts(36_459_756, 4764) + // Standard Error: 2_051 + .saturating_add(Weight::from_parts(56_670, 0).saturating_mul(l.into())) + // Standard Error: 3_650 + .saturating_add(Weight::from_parts(49_663, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -167,12 +165,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `555 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 68_441_000 picoseconds. - Weight::from_parts(68_961_970, 4764) - // Standard Error: 2_509 - .saturating_add(Weight::from_parts(83_345, 0).saturating_mul(l.into())) - // Standard Error: 4_464 - .saturating_add(Weight::from_parts(124_158, 0).saturating_mul(s.into())) + // Minimum execution time: 70_330_000 picoseconds. + Weight::from_parts(71_196_328, 4764) + // Standard Error: 2_923 + .saturating_add(Weight::from_parts(67_238, 0).saturating_mul(l.into())) + // Standard Error: 5_201 + .saturating_add(Weight::from_parts(89_102, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -190,12 +188,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `658 + l * (25 ±0) + s * (36 ±0)` // Estimated: `6196` - // Minimum execution time: 70_190_000 picoseconds. - Weight::from_parts(72_355_984, 6196) - // Standard Error: 2_295 - .saturating_add(Weight::from_parts(59_968, 0).saturating_mul(l.into())) - // Standard Error: 4_084 - .saturating_add(Weight::from_parts(87_090, 0).saturating_mul(s.into())) + // Minimum execution time: 70_235_000 picoseconds. + Weight::from_parts(71_960_020, 6196) + // Standard Error: 2_493 + .saturating_add(Weight::from_parts(64_835, 0).saturating_mul(l.into())) + // Standard Error: 4_436 + .saturating_add(Weight::from_parts(102_159, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -213,12 +211,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `482 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 33_911_000 picoseconds. - Weight::from_parts(33_243_006, 4764) - // Standard Error: 1_199 - .saturating_add(Weight::from_parts(70_586, 0).saturating_mul(l.into())) - // Standard Error: 2_214 - .saturating_add(Weight::from_parts(60_985, 0).saturating_mul(s.into())) + // Minimum execution time: 34_352_000 picoseconds. + Weight::from_parts(33_697_027, 4764) + // Standard Error: 2_008 + .saturating_add(Weight::from_parts(79_270, 0).saturating_mul(l.into())) + // Standard Error: 3_710 + .saturating_add(Weight::from_parts(60_691, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -236,12 +234,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `482 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 36_242_000 picoseconds. - Weight::from_parts(35_812_994, 4764) - // Standard Error: 1_351 - .saturating_add(Weight::from_parts(68_256, 0).saturating_mul(l.into())) - // Standard Error: 2_496 - .saturating_add(Weight::from_parts(66_171, 0).saturating_mul(s.into())) + // Minimum execution time: 37_467_000 picoseconds. + Weight::from_parts(36_866_847, 4764) + // Standard Error: 1_692 + .saturating_add(Weight::from_parts(57_882, 0).saturating_mul(l.into())) + // Standard Error: 3_124 + .saturating_add(Weight::from_parts(80_266, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -259,12 +257,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `555 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 37_817_000 picoseconds. - Weight::from_parts(37_397_127, 4764) - // Standard Error: 1_665 - .saturating_add(Weight::from_parts(72_049, 0).saturating_mul(l.into())) - // Standard Error: 3_075 - .saturating_add(Weight::from_parts(60_973, 0).saturating_mul(s.into())) + // Minimum execution time: 41_497_000 picoseconds. + Weight::from_parts(38_763_834, 4764) + // Standard Error: 2_030 + .saturating_add(Weight::from_parts(99_580, 0).saturating_mul(l.into())) + // Standard Error: 3_750 + .saturating_add(Weight::from_parts(132_188, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -284,12 +282,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `381 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 31_890_000 picoseconds. - Weight::from_parts(31_128_476, 4764) - // Standard Error: 1_193 - .saturating_add(Weight::from_parts(63_760, 0).saturating_mul(l.into())) - // Standard Error: 2_124 - .saturating_add(Weight::from_parts(57_247, 0).saturating_mul(s.into())) + // Minimum execution time: 32_846_000 picoseconds. + Weight::from_parts(30_974_459, 4764) + // Standard Error: 1_755 + .saturating_add(Weight::from_parts(73_138, 0).saturating_mul(l.into())) + // Standard Error: 3_123 + .saturating_add(Weight::from_parts(82_417, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -305,12 +303,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `381 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 33_958_000 picoseconds. - Weight::from_parts(33_537_005, 4764) - // Standard Error: 1_354 - .saturating_add(Weight::from_parts(60_604, 0).saturating_mul(l.into())) - // Standard Error: 2_410 - .saturating_add(Weight::from_parts(51_378, 0).saturating_mul(s.into())) + // Minimum execution time: 34_360_000 picoseconds. + Weight::from_parts(34_964_080, 4764) + // Standard Error: 1_996 + .saturating_add(Weight::from_parts(48_024, 0).saturating_mul(l.into())) + // Standard Error: 3_552 + .saturating_add(Weight::from_parts(34_411, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -328,12 +326,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `484 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 33_243_000 picoseconds. - Weight::from_parts(32_552_805, 4764) - // Standard Error: 1_413 - .saturating_add(Weight::from_parts(67_137, 0).saturating_mul(l.into())) - // Standard Error: 2_515 - .saturating_add(Weight::from_parts(70_000, 0).saturating_mul(s.into())) + // Minimum execution time: 33_859_000 picoseconds. + Weight::from_parts(32_950_681, 4764) + // Standard Error: 1_745 + .saturating_add(Weight::from_parts(69_323, 0).saturating_mul(l.into())) + // Standard Error: 3_105 + .saturating_add(Weight::from_parts(86_370, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -351,12 +349,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `484 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 35_396_000 picoseconds. - Weight::from_parts(35_774_949, 4764) - // Standard Error: 1_404 - .saturating_add(Weight::from_parts(55_349, 0).saturating_mul(l.into())) - // Standard Error: 2_497 - .saturating_add(Weight::from_parts(39_228, 0).saturating_mul(s.into())) + // Minimum execution time: 36_239_000 picoseconds. + Weight::from_parts(36_459_756, 4764) + // Standard Error: 2_051 + .saturating_add(Weight::from_parts(56_670, 0).saturating_mul(l.into())) + // Standard Error: 3_650 + .saturating_add(Weight::from_parts(49_663, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -374,12 +372,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `555 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 68_441_000 picoseconds. - Weight::from_parts(68_961_970, 4764) - // Standard Error: 2_509 - .saturating_add(Weight::from_parts(83_345, 0).saturating_mul(l.into())) - // Standard Error: 4_464 - .saturating_add(Weight::from_parts(124_158, 0).saturating_mul(s.into())) + // Minimum execution time: 70_330_000 picoseconds. + Weight::from_parts(71_196_328, 4764) + // Standard Error: 2_923 + .saturating_add(Weight::from_parts(67_238, 0).saturating_mul(l.into())) + // Standard Error: 5_201 + .saturating_add(Weight::from_parts(89_102, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -397,12 +395,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `658 + l * (25 ±0) + s * (36 ±0)` // Estimated: `6196` - // Minimum execution time: 70_190_000 picoseconds. - Weight::from_parts(72_355_984, 6196) - // Standard Error: 2_295 - .saturating_add(Weight::from_parts(59_968, 0).saturating_mul(l.into())) - // Standard Error: 4_084 - .saturating_add(Weight::from_parts(87_090, 0).saturating_mul(s.into())) + // Minimum execution time: 70_235_000 picoseconds. + Weight::from_parts(71_960_020, 6196) + // Standard Error: 2_493 + .saturating_add(Weight::from_parts(64_835, 0).saturating_mul(l.into())) + // Standard Error: 4_436 + .saturating_add(Weight::from_parts(102_159, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -420,12 +418,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `482 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 33_911_000 picoseconds. - Weight::from_parts(33_243_006, 4764) - // Standard Error: 1_199 - .saturating_add(Weight::from_parts(70_586, 0).saturating_mul(l.into())) - // Standard Error: 2_214 - .saturating_add(Weight::from_parts(60_985, 0).saturating_mul(s.into())) + // Minimum execution time: 34_352_000 picoseconds. + Weight::from_parts(33_697_027, 4764) + // Standard Error: 2_008 + .saturating_add(Weight::from_parts(79_270, 0).saturating_mul(l.into())) + // Standard Error: 3_710 + .saturating_add(Weight::from_parts(60_691, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -443,12 +441,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `482 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 36_242_000 picoseconds. - Weight::from_parts(35_812_994, 4764) - // Standard Error: 1_351 - .saturating_add(Weight::from_parts(68_256, 0).saturating_mul(l.into())) - // Standard Error: 2_496 - .saturating_add(Weight::from_parts(66_171, 0).saturating_mul(s.into())) + // Minimum execution time: 37_467_000 picoseconds. + Weight::from_parts(36_866_847, 4764) + // Standard Error: 1_692 + .saturating_add(Weight::from_parts(57_882, 0).saturating_mul(l.into())) + // Standard Error: 3_124 + .saturating_add(Weight::from_parts(80_266, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -466,12 +464,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `555 + l * (25 ±0) + s * (36 ±0)` // Estimated: `4764` - // Minimum execution time: 37_817_000 picoseconds. - Weight::from_parts(37_397_127, 4764) - // Standard Error: 1_665 - .saturating_add(Weight::from_parts(72_049, 0).saturating_mul(l.into())) - // Standard Error: 3_075 - .saturating_add(Weight::from_parts(60_973, 0).saturating_mul(s.into())) + // Minimum execution time: 41_497_000 picoseconds. + Weight::from_parts(38_763_834, 4764) + // Standard Error: 2_030 + .saturating_add(Weight::from_parts(99_580, 0).saturating_mul(l.into())) + // Standard Error: 3_750 + .saturating_add(Weight::from_parts(132_188, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } diff --git a/substrate/frame/whitelist/src/weights.rs b/substrate/frame/whitelist/src/weights.rs index 13b653f6ca7..de42c5a5841 100644 --- a/substrate/frame/whitelist/src/weights.rs +++ b/substrate/frame/whitelist/src/weights.rs @@ -15,16 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet_whitelist` +//! Autogenerated weights for pallet_whitelist //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-16, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` +//! HOSTNAME: `runner-e8ezs4ez-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/substrate-node +// ./target/production/substrate // benchmark // pallet // --chain=dev @@ -35,11 +35,12 @@ // --no-median-slopes // --no-min-squares // --extrinsic=* +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --output=./substrate/frame/whitelist/src/weights.rs -// --header=./substrate/HEADER-APACHE2 -// --template=./substrate/.maintain/frame-weight-template.hbs +// --output=./frame/whitelist/src/weights.rs +// --header=./HEADER-APACHE2 +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -49,7 +50,7 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet_whitelist`. +/// Weight functions needed for pallet_whitelist. pub trait WeightInfo { fn whitelist_call() -> Weight; fn remove_whitelisted_call() -> Weight; @@ -57,149 +58,133 @@ pub trait WeightInfo { fn dispatch_whitelisted_call_with_preimage(n: u32, ) -> Weight; } -/// Weights for `pallet_whitelist` using the Substrate node and recommended hardware. +/// Weights for pallet_whitelist using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) - /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: Whitelist WhitelistedCall (r:1 w:1) + /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) fn whitelist_call() -> Weight { // Proof Size summary in bytes: - // Measured: `317` + // Measured: `217` // Estimated: `3556` - // Minimum execution time: 18_503_000 picoseconds. - Weight::from_parts(19_497_000, 3556) - .saturating_add(T::DbWeight::get().reads(3_u64)) + // Minimum execution time: 19_914_000 picoseconds. + Weight::from_parts(20_892_000, 3556) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) - /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: Whitelist WhitelistedCall (r:1 w:1) + /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) fn remove_whitelisted_call() -> Weight { // Proof Size summary in bytes: - // Measured: `446` + // Measured: `346` // Estimated: `3556` - // Minimum execution time: 17_633_000 picoseconds. - Weight::from_parts(18_196_000, 3556) - .saturating_add(T::DbWeight::get().reads(3_u64)) + // Minimum execution time: 18_142_000 picoseconds. + Weight::from_parts(18_529_000, 3556) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } - /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) - /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Preimage::PreimageFor` (r:1 w:1) - /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `Measured`) - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: Whitelist WhitelistedCall (r:1 w:1) + /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:1 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: Measured) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) /// The range of component `n` is `[1, 4194294]`. fn dispatch_whitelisted_call(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `522 + n * (1 ±0)` - // Estimated: `3986 + n * (1 ±0)` - // Minimum execution time: 28_020_000 picoseconds. - Weight::from_parts(28_991_000, 3986) + // Measured: `422 + n * (1 ±0)` + // Estimated: `3886 + n * (1 ±0)` + // Minimum execution time: 30_671_000 picoseconds. + Weight::from_parts(31_197_000, 3886) // Standard Error: 0 - .saturating_add(Weight::from_parts(1_171, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(Weight::from_parts(1_163, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } - /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) - /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: Whitelist WhitelistedCall (r:1 w:1) + /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) /// The range of component `n` is `[1, 10000]`. fn dispatch_whitelisted_call_with_preimage(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `446` + // Measured: `346` // Estimated: `3556` - // Minimum execution time: 21_916_000 picoseconds. - Weight::from_parts(23_082_065, 3556) - // Standard Error: 6 - .saturating_add(Weight::from_parts(1_388, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(3_u64)) + // Minimum execution time: 22_099_000 picoseconds. + Weight::from_parts(23_145_477, 3556) + // Standard Error: 5 + .saturating_add(Weight::from_parts(1_422, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } } -// For backwards compatibility and tests. +// For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) - /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: Whitelist WhitelistedCall (r:1 w:1) + /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) fn whitelist_call() -> Weight { // Proof Size summary in bytes: - // Measured: `317` + // Measured: `217` // Estimated: `3556` - // Minimum execution time: 18_503_000 picoseconds. - Weight::from_parts(19_497_000, 3556) - .saturating_add(RocksDbWeight::get().reads(3_u64)) + // Minimum execution time: 19_914_000 picoseconds. + Weight::from_parts(20_892_000, 3556) + .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) - /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: Whitelist WhitelistedCall (r:1 w:1) + /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) fn remove_whitelisted_call() -> Weight { // Proof Size summary in bytes: - // Measured: `446` + // Measured: `346` // Estimated: `3556` - // Minimum execution time: 17_633_000 picoseconds. - Weight::from_parts(18_196_000, 3556) - .saturating_add(RocksDbWeight::get().reads(3_u64)) + // Minimum execution time: 18_142_000 picoseconds. + Weight::from_parts(18_529_000, 3556) + .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } - /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) - /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Preimage::PreimageFor` (r:1 w:1) - /// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `Measured`) - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: Whitelist WhitelistedCall (r:1 w:1) + /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + /// Storage: Preimage PreimageFor (r:1 w:1) + /// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: Measured) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) /// The range of component `n` is `[1, 4194294]`. fn dispatch_whitelisted_call(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `522 + n * (1 ±0)` - // Estimated: `3986 + n * (1 ±0)` - // Minimum execution time: 28_020_000 picoseconds. - Weight::from_parts(28_991_000, 3986) + // Measured: `422 + n * (1 ±0)` + // Estimated: `3886 + n * (1 ±0)` + // Minimum execution time: 30_671_000 picoseconds. + Weight::from_parts(31_197_000, 3886) // Standard Error: 0 - .saturating_add(Weight::from_parts(1_171, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(Weight::from_parts(1_163, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } - /// Storage: `Whitelist::WhitelistedCall` (r:1 w:1) - /// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Preimage::StatusFor` (r:1 w:0) - /// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) - /// Storage: `Preimage::RequestStatusFor` (r:1 w:1) - /// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`) + /// Storage: Whitelist WhitelistedCall (r:1 w:1) + /// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + /// Storage: Preimage StatusFor (r:1 w:1) + /// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen) /// The range of component `n` is `[1, 10000]`. fn dispatch_whitelisted_call_with_preimage(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `446` + // Measured: `346` // Estimated: `3556` - // Minimum execution time: 21_916_000 picoseconds. - Weight::from_parts(23_082_065, 3556) - // Standard Error: 6 - .saturating_add(Weight::from_parts(1_388, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(3_u64)) + // Minimum execution time: 22_099_000 picoseconds. + Weight::from_parts(23_145_477, 3556) + // Standard Error: 5 + .saturating_add(Weight::from_parts(1_422, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } } diff --git a/substrate/primitives/inherents/src/lib.rs b/substrate/primitives/inherents/src/lib.rs index 415319a6849..dd7c294f1e2 100644 --- a/substrate/primitives/inherents/src/lib.rs +++ b/substrate/primitives/inherents/src/lib.rs @@ -98,10 +98,10 @@ //! and production. //! //! ``` -//! # use sp_runtime::{generic::UncheckedExtrinsic, testing::MockCallU64}; +//! # use sp_runtime::testing::ExtrinsicWrapper; //! # use sp_inherents::{InherentIdentifier, InherentData}; //! # use futures::FutureExt; -//! # type Block = sp_runtime::testing::Block>; +//! # type Block = sp_runtime::testing::Block>; //! # const INHERENT_IDENTIFIER: InherentIdentifier = *b"testinh0"; //! # struct InherentDataProvider; //! # #[async_trait::async_trait] diff --git a/substrate/primitives/metadata-ir/src/lib.rs b/substrate/primitives/metadata-ir/src/lib.rs index 66aff2c599f..edfa58f8618 100644 --- a/substrate/primitives/metadata-ir/src/lib.rs +++ b/substrate/primitives/metadata-ir/src/lib.rs @@ -84,7 +84,7 @@ mod test { call_ty: meta_type::<()>(), signature_ty: meta_type::<()>(), extra_ty: meta_type::<()>(), - extensions: vec![], + signed_extensions: vec![], }, ty: meta_type::<()>(), apis: vec![], diff --git a/substrate/primitives/metadata-ir/src/types.rs b/substrate/primitives/metadata-ir/src/types.rs index e60881ed6b8..b107d20a8e2 100644 --- a/substrate/primitives/metadata-ir/src/types.rs +++ b/substrate/primitives/metadata-ir/src/types.rs @@ -166,11 +166,10 @@ pub struct ExtrinsicMetadataIR { pub call_ty: T::Type, /// The type of the extrinsic's signature. pub signature_ty: T::Type, - /// The type of the outermost Extra/Extensions enum. - // TODO: metadata-v16: rename this to `extension_ty`. + /// The type of the outermost Extra enum. pub extra_ty: T::Type, - /// The transaction extensions in the order they appear in the extrinsic. - pub extensions: Vec>, + /// The signed extensions in the order they appear in the extrinsic. + pub signed_extensions: Vec>, } impl IntoPortable for ExtrinsicMetadataIR { @@ -184,27 +183,27 @@ impl IntoPortable for ExtrinsicMetadataIR { call_ty: registry.register_type(&self.call_ty), signature_ty: registry.register_type(&self.signature_ty), extra_ty: registry.register_type(&self.extra_ty), - extensions: registry.map_into_portable(self.extensions), + signed_extensions: registry.map_into_portable(self.signed_extensions), } } } /// Metadata of an extrinsic's signed extension. #[derive(Clone, PartialEq, Eq, Encode, Debug)] -pub struct TransactionExtensionMetadataIR { +pub struct SignedExtensionMetadataIR { /// The unique signed extension identifier, which may be different from the type name. pub identifier: T::String, /// The type of the signed extension, with the data to be included in the extrinsic. pub ty: T::Type, - /// The type of the additional signed data, with the data to be included in the signed payload. + /// The type of the additional signed data, with the data to be included in the signed payload pub additional_signed: T::Type, } -impl IntoPortable for TransactionExtensionMetadataIR { - type Output = TransactionExtensionMetadataIR; +impl IntoPortable for SignedExtensionMetadataIR { + type Output = SignedExtensionMetadataIR; fn into_portable(self, registry: &mut Registry) -> Self::Output { - TransactionExtensionMetadataIR { + SignedExtensionMetadataIR { identifier: self.identifier.into_portable(registry), ty: registry.register_type(&self.ty), additional_signed: registry.register_type(&self.additional_signed), diff --git a/substrate/primitives/metadata-ir/src/v14.rs b/substrate/primitives/metadata-ir/src/v14.rs index ec08de34786..e1b7a24f765 100644 --- a/substrate/primitives/metadata-ir/src/v14.rs +++ b/substrate/primitives/metadata-ir/src/v14.rs @@ -20,8 +20,8 @@ use super::types::{ ExtrinsicMetadataIR, MetadataIR, PalletCallMetadataIR, PalletConstantMetadataIR, PalletErrorMetadataIR, PalletEventMetadataIR, PalletMetadataIR, PalletStorageMetadataIR, - StorageEntryMetadataIR, StorageEntryModifierIR, StorageEntryTypeIR, StorageHasherIR, - TransactionExtensionMetadataIR, + SignedExtensionMetadataIR, StorageEntryMetadataIR, StorageEntryModifierIR, StorageEntryTypeIR, + StorageHasherIR, }; use frame_metadata::v14::{ @@ -137,8 +137,8 @@ impl From for PalletErrorMetadata { } } -impl From for SignedExtensionMetadata { - fn from(ir: TransactionExtensionMetadataIR) -> Self { +impl From for SignedExtensionMetadata { + fn from(ir: SignedExtensionMetadataIR) -> Self { SignedExtensionMetadata { identifier: ir.identifier, ty: ir.ty, @@ -152,7 +152,7 @@ impl From for ExtrinsicMetadata { ExtrinsicMetadata { ty: ir.ty, version: ir.version, - signed_extensions: ir.extensions.into_iter().map(Into::into).collect(), + signed_extensions: ir.signed_extensions.into_iter().map(Into::into).collect(), } } } diff --git a/substrate/primitives/metadata-ir/src/v15.rs b/substrate/primitives/metadata-ir/src/v15.rs index dc5ce1c88fd..a942eb73223 100644 --- a/substrate/primitives/metadata-ir/src/v15.rs +++ b/substrate/primitives/metadata-ir/src/v15.rs @@ -21,7 +21,7 @@ use crate::OuterEnumsIR; use super::types::{ ExtrinsicMetadataIR, MetadataIR, PalletMetadataIR, RuntimeApiMetadataIR, - RuntimeApiMethodMetadataIR, RuntimeApiMethodParamMetadataIR, TransactionExtensionMetadataIR, + RuntimeApiMethodMetadataIR, RuntimeApiMethodParamMetadataIR, SignedExtensionMetadataIR, }; use frame_metadata::v15::{ @@ -87,8 +87,8 @@ impl From for PalletMetadata { } } -impl From for SignedExtensionMetadata { - fn from(ir: TransactionExtensionMetadataIR) -> Self { +impl From for SignedExtensionMetadata { + fn from(ir: SignedExtensionMetadataIR) -> Self { SignedExtensionMetadata { identifier: ir.identifier, ty: ir.ty, @@ -105,7 +105,7 @@ impl From for ExtrinsicMetadata { call_ty: ir.call_ty, signature_ty: ir.signature_ty, extra_ty: ir.extra_ty, - signed_extensions: ir.extensions.into_iter().map(Into::into).collect(), + signed_extensions: ir.signed_extensions.into_iter().map(Into::into).collect(), } } } diff --git a/substrate/primitives/runtime/Cargo.toml b/substrate/primitives/runtime/Cargo.toml index 758cd8944fd..cacfc059722 100644 --- a/substrate/primitives/runtime/Cargo.toml +++ b/substrate/primitives/runtime/Cargo.toml @@ -17,7 +17,6 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -tuplex = { version = "0.1.2", default-features = false } codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive", "max-encoded-len"] } either = { version = "1.5", default-features = false } hash256-std-hasher = { version = "0.15.2", default-features = false } @@ -68,7 +67,6 @@ std = [ "sp-std/std", "sp-tracing/std", "sp-weights/std", - "tuplex/std", ] # Serde support without relying on std features. diff --git a/substrate/primitives/runtime/src/generic/checked_extrinsic.rs b/substrate/primitives/runtime/src/generic/checked_extrinsic.rs index e28c8fe424a..44325920bee 100644 --- a/substrate/primitives/runtime/src/generic/checked_extrinsic.rs +++ b/substrate/primitives/runtime/src/generic/checked_extrinsic.rs @@ -18,115 +18,81 @@ //! Generic implementation of an extrinsic that has passed the verification //! stage. -use codec::Encode; - use crate::{ traits::{ - self, transaction_extension::TransactionExtension, DispatchInfoOf, DispatchTransaction, - Dispatchable, MaybeDisplay, Member, PostDispatchInfoOf, ValidateUnsigned, + self, DispatchInfoOf, Dispatchable, MaybeDisplay, Member, PostDispatchInfoOf, + SignedExtension, ValidateUnsigned, }, transaction_validity::{TransactionSource, TransactionValidity}, }; -/// The kind of extrinsic this is, including any fields required of that kind. This is basically -/// the full extrinsic except the `Call`. -#[derive(PartialEq, Eq, Clone, sp_core::RuntimeDebug)] -pub enum ExtrinsicFormat { - /// Extrinsic is bare; it must pass either the bare forms of `TransactionExtension` or - /// `ValidateUnsigned`, both deprecated, or alternatively a `ProvideInherent`. - Bare, - /// Extrinsic has a default `Origin` of `Signed(AccountId)` and must pass all - /// `TransactionExtension`s regular checks and includes all extension data. - Signed(AccountId, Extension), - /// Extrinsic has a default `Origin` of `None` and must pass all `TransactionExtension`s. - /// regular checks and includes all extension data. - General(Extension), -} - -// TODO: Rename ValidateUnsigned to ValidateInherent -// TODO: Consider changing ValidateInherent API to avoid need for duplicating validate -// code into pre_dispatch (rename that to `prepare`). -// TODO: New extrinsic type corresponding to `ExtrinsicFormat::General`, which is -// unsigned but includes extension data. -// TODO: Move usage of `signed` to `format`: -// - Inherent instead of None. -// - Signed(id, extension) instead of Some((id, extra)). -// - Introduce General(extension) for one without a signature. - /// Definition of something that the external world might want to say; its existence implies that it /// has been checked and is good, particularly with regards to the signature. /// /// This is typically passed into [`traits::Applyable::apply`], which should execute /// [`CheckedExtrinsic::function`], alongside all other bits and bobs. #[derive(PartialEq, Eq, Clone, sp_core::RuntimeDebug)] -pub struct CheckedExtrinsic { +pub struct CheckedExtrinsic { /// Who this purports to be from and the number of extrinsics have come before /// from the same signer, if anyone (note this is not a signature). - pub format: ExtrinsicFormat, + pub signed: Option<(AccountId, Extra)>, /// The function that should be called. pub function: Call, } -impl traits::Applyable - for CheckedExtrinsic +impl traits::Applyable + for CheckedExtrinsic where AccountId: Member + MaybeDisplay, - Call: Member + Dispatchable + Encode, - Extension: TransactionExtension, + Call: Member + Dispatchable, + Extra: SignedExtension, RuntimeOrigin: From>, { type Call = Call; - fn validate>( + fn validate>( &self, + // TODO [#5006;ToDr] should source be passed to `SignedExtension`s? + // Perhaps a change for 2.0 to avoid breaking too much APIs? source: TransactionSource, info: &DispatchInfoOf, len: usize, ) -> TransactionValidity { - match self.format { - ExtrinsicFormat::Bare => { - let inherent_validation = I::validate_unsigned(source, &self.function)?; - #[allow(deprecated)] - let legacy_validation = Extension::validate_bare_compat(&self.function, info, len)?; - Ok(legacy_validation.combine_with(inherent_validation)) - }, - ExtrinsicFormat::Signed(ref signer, ref extension) => { - let origin = Some(signer.clone()).into(); - extension.validate_only(origin, &self.function, info, len).map(|x| x.0) - }, - ExtrinsicFormat::General(ref extension) => - extension.validate_only(None.into(), &self.function, info, len).map(|x| x.0), + if let Some((ref id, ref extra)) = self.signed { + Extra::validate(extra, id, &self.function, info, len) + } else { + let valid = Extra::validate_unsigned(&self.function, info, len)?; + let unsigned_validation = U::validate_unsigned(source, &self.function)?; + Ok(valid.combine_with(unsigned_validation)) } } - fn apply>( + fn apply>( self, info: &DispatchInfoOf, len: usize, ) -> crate::ApplyExtrinsicResultWithInfo> { - match self.format { - ExtrinsicFormat::Bare => { - I::pre_dispatch(&self.function)?; - // TODO: Remove below once `pre_dispatch_unsigned` is removed from `LegacyExtension` - // or `LegacyExtension` is removed. - #[allow(deprecated)] - Extension::validate_bare_compat(&self.function, info, len)?; - #[allow(deprecated)] - Extension::pre_dispatch_bare_compat(&self.function, info, len)?; - let res = self.function.dispatch(None.into()); - let post_info = res.unwrap_or_else(|err| err.post_info); - let pd_res = res.map(|_| ()).map_err(|e| e.error); - // TODO: Remove below once `pre_dispatch_unsigned` is removed from `LegacyExtension` - // or `LegacyExtension` is removed. - #[allow(deprecated)] - Extension::post_dispatch_bare_compat(info, &post_info, len, &pd_res)?; - Ok(res) - }, - ExtrinsicFormat::Signed(signer, extension) => - extension.dispatch_transaction(Some(signer).into(), self.function, info, len), - ExtrinsicFormat::General(extension) => - extension.dispatch_transaction(None.into(), self.function, info, len), - } + let (maybe_who, maybe_pre) = if let Some((id, extra)) = self.signed { + let pre = Extra::pre_dispatch(extra, &id, &self.function, info, len)?; + (Some(id), Some(pre)) + } else { + Extra::pre_dispatch_unsigned(&self.function, info, len)?; + U::pre_dispatch(&self.function)?; + (None, None) + }; + let res = self.function.dispatch(RuntimeOrigin::from(maybe_who)); + let post_info = match res { + Ok(info) => info, + Err(err) => err.post_info, + }; + Extra::post_dispatch( + maybe_pre, + info, + &post_info, + len, + &res.map(|_| ()).map_err(|e| e.error), + )?; + Ok(res) } } diff --git a/substrate/primitives/runtime/src/generic/mod.rs b/substrate/primitives/runtime/src/generic/mod.rs index 5713c166b04..3687f7cdb3b 100644 --- a/substrate/primitives/runtime/src/generic/mod.rs +++ b/substrate/primitives/runtime/src/generic/mod.rs @@ -29,9 +29,9 @@ mod unchecked_extrinsic; pub use self::{ block::{Block, BlockId, SignedBlock}, - checked_extrinsic::{CheckedExtrinsic, ExtrinsicFormat}, + checked_extrinsic::CheckedExtrinsic, digest::{Digest, DigestItem, DigestItemRef, OpaqueDigestItemId}, era::{Era, Phase}, header::Header, - unchecked_extrinsic::{Preamble, SignedPayload, UncheckedExtrinsic}, + unchecked_extrinsic::{SignedPayload, UncheckedExtrinsic}, }; diff --git a/substrate/primitives/runtime/src/generic/unchecked_extrinsic.rs b/substrate/primitives/runtime/src/generic/unchecked_extrinsic.rs index 44dfda13d94..5b54caf597b 100644 --- a/substrate/primitives/runtime/src/generic/unchecked_extrinsic.rs +++ b/substrate/primitives/runtime/src/generic/unchecked_extrinsic.rs @@ -18,11 +18,10 @@ //! Generic implementation of an unchecked (pre-verification) extrinsic. use crate::{ - generic::{CheckedExtrinsic, ExtrinsicFormat}, + generic::CheckedExtrinsic, traits::{ - self, transaction_extension::TransactionExtensionBase, Checkable, Dispatchable, Extrinsic, - ExtrinsicMetadata, IdentifyAccount, MaybeDisplay, Member, SignaturePayload, - TransactionExtension, + self, Checkable, Extrinsic, ExtrinsicMetadata, IdentifyAccount, MaybeDisplay, Member, + SignaturePayload, SignedExtension, }, transaction_validity::{InvalidTransaction, TransactionValidityError}, OpaqueExtrinsic, @@ -41,60 +40,8 @@ use sp_std::{fmt, prelude::*}; /// the decoding fails. const EXTRINSIC_FORMAT_VERSION: u8 = 4; -/// The `SignaturePayload` of `UncheckedExtrinsic`. -type UncheckedSignaturePayload = (Address, Signature, Extension); - -impl SignaturePayload - for UncheckedSignaturePayload -{ - type SignatureAddress = Address; - type Signature = Signature; - type SignatureExtra = Extension; -} - -/// A "header" for extrinsics leading up to the call itself. Determines the type of extrinsic and -/// holds any necessary specialized data. -#[derive(Eq, PartialEq, Clone, Encode, Decode)] -pub enum Preamble { - /// An extrinsic without a signature or any extension. This means it's either an inherent or - /// an old-school "Unsigned" (we don't use that terminology any more since it's confusable with - /// the general transaction which is without a signature but does have an extension). - /// - /// NOTE: In the future, once we remove `ValidateUnsigned`, this will only serve Inherent - /// extrinsics and thus can be renamed to `Inherent`. - #[codec(index = 0b00000100)] - Bare, - /// An old-school transaction extrinsic which includes a signature of some hard-coded crypto. - #[codec(index = 0b10000100)] - Signed(Address, Signature, Extension), - /// A new-school transaction extrinsic which does not include a signature. - #[codec(index = 0b01000100)] - General(Extension), -} - -impl Preamble { - /// Returns `Some` if this is a signed extrinsic, together with the relevant inner fields. - pub fn to_signed(self) -> Option<(Address, Signature, Extension)> { - match self { - Self::Signed(a, s, e) => Some((a, s, e)), - _ => None, - } - } -} - -impl fmt::Debug for Preamble -where - Address: fmt::Debug, - Extension: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::Bare => write!(f, "Bare"), - Self::Signed(address, _, tx_ext) => write!(f, "Signed({:?}, {:?})", address, tx_ext), - Self::General(tx_ext) => write!(f, "General({:?})", tx_ext), - } - } -} +/// The `SingaturePayload` of `UncheckedExtrinsic`. +type UncheckedSignaturePayload = (Address, Signature, Extra); /// An extrinsic right from the external world. This is unchecked and so can contain a signature. /// @@ -118,28 +65,41 @@ where /// This can be checked using [`Checkable`], yielding a [`CheckedExtrinsic`], which is the /// counterpart of this type after its signature (and other non-negotiable validity checks) have /// passed. -#[derive(PartialEq, Eq, Clone, Debug)] -pub struct UncheckedExtrinsic { - /// Information regarding the type of extrinsic this is (inherent or transaction) as well as - /// associated extension (`Extension`) data if it's a transaction and a possible signature. - pub preamble: Preamble, +#[derive(PartialEq, Eq, Clone)] +pub struct UncheckedExtrinsic +where + Extra: SignedExtension, +{ + /// The signature, address, number of extrinsics have come before from the same signer and an + /// era describing the longevity of this transaction, if this is a signed extrinsic. + /// + /// `None` if it is unsigned or an inherent. + pub signature: Option>, /// The function that should be called. pub function: Call, } +impl SignaturePayload + for UncheckedSignaturePayload +{ + type SignatureAddress = Address; + type Signature = Signature; + type SignatureExtra = Extra; +} + /// Manual [`TypeInfo`] implementation because of custom encoding. The data is a valid encoded /// `Vec`, but requires some logic to extract the signature and payload. /// /// See [`UncheckedExtrinsic::encode`] and [`UncheckedExtrinsic::decode`]. -impl TypeInfo - for UncheckedExtrinsic +impl TypeInfo + for UncheckedExtrinsic where Address: StaticTypeInfo, Call: StaticTypeInfo, Signature: StaticTypeInfo, - Extension: StaticTypeInfo, + Extra: SignedExtension + StaticTypeInfo, { - type Identity = UncheckedExtrinsic; + type Identity = UncheckedExtrinsic; fn type_info() -> Type { Type::builder() @@ -151,7 +111,7 @@ where TypeParameter::new("Address", Some(meta_type::
())), TypeParameter::new("Call", Some(meta_type::())), TypeParameter::new("Signature", Some(meta_type::())), - TypeParameter::new("Extra", Some(meta_type::())), + TypeParameter::new("Extra", Some(meta_type::())), ]) .docs(&["UncheckedExtrinsic raw bytes, requires custom decoding routine"]) // Because of the custom encoding, we can only accurately describe the encoding as an @@ -161,113 +121,66 @@ where } } -impl UncheckedExtrinsic { - /// New instance of a bare (ne unsigned) extrinsic. This could be used for an inherent or an - /// old-school "unsigned transaction" (which are new being deprecated in favour of general - /// transactions). - #[deprecated = "Use new_bare instead"] - pub fn new_unsigned(function: Call) -> Self { - Self::new_bare(function) - } - - /// Returns `true` if this extrinsic instance is an inherent, `false`` otherwise. - pub fn is_inherent(&self) -> bool { - matches!(self.preamble, Preamble::Bare) - } - - /// Returns `true` if this extrinsic instance is an old-school signed transaction, `false` - /// otherwise. - pub fn is_signed(&self) -> bool { - matches!(self.preamble, Preamble::Signed(..)) - } - - /// Create an `UncheckedExtrinsic` from a `Preamble` and the actual `Call`. - pub fn from_parts(function: Call, preamble: Preamble) -> Self { - Self { preamble, function } - } - - /// New instance of a bare (ne unsigned) extrinsic. - pub fn new_bare(function: Call) -> Self { - Self { preamble: Preamble::Bare, function } - } - - /// New instance of an old-school signed transaction. - pub fn new_signed( - function: Call, - signed: Address, - signature: Signature, - tx_ext: Extension, - ) -> Self { - Self { preamble: Preamble::Signed(signed, signature, tx_ext), function } +impl + UncheckedExtrinsic +{ + /// New instance of a signed extrinsic aka "transaction". + pub fn new_signed(function: Call, signed: Address, signature: Signature, extra: Extra) -> Self { + Self { signature: Some((signed, signature, extra)), function } } - /// New instance of an new-school unsigned transaction. - pub fn new_transaction(function: Call, tx_ext: Extension) -> Self { - Self { preamble: Preamble::General(tx_ext), function } + /// New instance of an unsigned extrinsic aka "inherent". + pub fn new_unsigned(function: Call) -> Self { + Self { signature: None, function } } } -// TODO: We can get rid of this trait and just use UncheckedExtrinsic directly. - -impl Extrinsic - for UncheckedExtrinsic +impl + Extrinsic for UncheckedExtrinsic { type Call = Call; - type SignaturePayload = UncheckedSignaturePayload; - - fn is_bare(&self) -> bool { - matches!(self.preamble, Preamble::Bare) - } + type SignaturePayload = UncheckedSignaturePayload; fn is_signed(&self) -> Option { - Some(matches!(self.preamble, Preamble::Signed(..))) + Some(self.signature.is_some()) } fn new(function: Call, signed_data: Option) -> Option { Some(if let Some((address, signature, extra)) = signed_data { Self::new_signed(function, address, signature, extra) } else { - Self::new_bare(function) + Self::new_unsigned(function) }) } - - fn new_inherent(function: Call) -> Self { - Self::new_bare(function) - } } -impl Checkable - for UncheckedExtrinsic +impl Checkable + for UncheckedExtrinsic where LookupSource: Member + MaybeDisplay, - Call: Encode + Member + Dispatchable, + Call: Encode + Member, Signature: Member + traits::Verify, ::Signer: IdentifyAccount, - Extension: Encode + TransactionExtension, + Extra: SignedExtension, AccountId: Member + MaybeDisplay, Lookup: traits::Lookup, { - type Checked = CheckedExtrinsic; + type Checked = CheckedExtrinsic; fn check(self, lookup: &Lookup) -> Result { - Ok(match self.preamble { - Preamble::Signed(signed, signature, tx_ext) => { + Ok(match self.signature { + Some((signed, signature, extra)) => { let signed = lookup.lookup(signed)?; - // CHECK! Should this not contain implicit? - let raw_payload = SignedPayload::new(self.function, tx_ext)?; + let raw_payload = SignedPayload::new(self.function, extra)?; if !raw_payload.using_encoded(|payload| signature.verify(payload, &signed)) { return Err(InvalidTransaction::BadProof.into()) } - let (function, tx_ext, _) = raw_payload.deconstruct(); - CheckedExtrinsic { format: ExtrinsicFormat::Signed(signed, tx_ext), function } - }, - Preamble::General(tx_ext) => CheckedExtrinsic { - format: ExtrinsicFormat::General(tx_ext), - function: self.function, + + let (function, extra, _) = raw_payload.deconstruct(); + CheckedExtrinsic { signed: Some((signed, extra)), function } }, - Preamble::Bare => - CheckedExtrinsic { format: ExtrinsicFormat::Bare, function: self.function }, + None => CheckedExtrinsic { signed: None, function: self.function }, }) } @@ -276,38 +189,91 @@ where self, lookup: &Lookup, ) -> Result { - Ok(match self.preamble { - Preamble::Signed(signed, _, extra) => { + Ok(match self.signature { + Some((signed, _, extra)) => { let signed = lookup.lookup(signed)?; - CheckedExtrinsic { - format: ExtrinsicFormat::Signed(signed, extra), - function: self.function, - } + let raw_payload = SignedPayload::new(self.function, extra)?; + let (function, extra, _) = raw_payload.deconstruct(); + CheckedExtrinsic { signed: Some((signed, extra)), function } }, - Preamble::General(extra) => CheckedExtrinsic { - format: ExtrinsicFormat::General(extra), - function: self.function, - }, - Preamble::Bare => - CheckedExtrinsic { format: ExtrinsicFormat::Bare, function: self.function }, + None => CheckedExtrinsic { signed: None, function: self.function }, }) } } -impl> - ExtrinsicMetadata for UncheckedExtrinsic +impl ExtrinsicMetadata + for UncheckedExtrinsic +where + Extra: SignedExtension, { const VERSION: u8 = EXTRINSIC_FORMAT_VERSION; - type Extra = Extension; + type SignedExtensions = Extra; +} + +/// A payload that has been signed for an unchecked extrinsics. +/// +/// Note that the payload that we sign to produce unchecked extrinsic signature +/// is going to be different than the `SignaturePayload` - so the thing the extrinsic +/// actually contains. +pub struct SignedPayload((Call, Extra, Extra::AdditionalSigned)); + +impl SignedPayload +where + Call: Encode, + Extra: SignedExtension, +{ + /// Create new `SignedPayload`. + /// + /// This function may fail if `additional_signed` of `Extra` is not available. + pub fn new(call: Call, extra: Extra) -> Result { + let additional_signed = extra.additional_signed()?; + let raw_payload = (call, extra, additional_signed); + Ok(Self(raw_payload)) + } + + /// Create new `SignedPayload` from raw components. + pub fn from_raw(call: Call, extra: Extra, additional_signed: Extra::AdditionalSigned) -> Self { + Self((call, extra, additional_signed)) + } + + /// Deconstruct the payload into it's components. + pub fn deconstruct(self) -> (Call, Extra, Extra::AdditionalSigned) { + self.0 + } } -impl Decode - for UncheckedExtrinsic +impl Encode for SignedPayload +where + Call: Encode, + Extra: SignedExtension, +{ + /// Get an encoded version of this payload. + /// + /// Payloads longer than 256 bytes are going to be `blake2_256`-hashed. + fn using_encoded R>(&self, f: F) -> R { + self.0.using_encoded(|payload| { + if payload.len() > 256 { + f(&blake2_256(payload)[..]) + } else { + f(payload) + } + }) + } +} + +impl EncodeLike for SignedPayload +where + Call: Encode, + Extra: SignedExtension, +{ +} + +impl Decode for UncheckedExtrinsic where Address: Decode, Signature: Decode, Call: Decode, - Extension: Decode, + Extra: SignedExtension, { fn decode(input: &mut I) -> Result { // This is a little more complicated than usual since the binary format must be compatible @@ -316,7 +282,15 @@ where let expected_length: Compact = Decode::decode(input)?; let before_length = input.remaining_len()?; - let preamble = Decode::decode(input)?; + let version = input.read_byte()?; + + let is_signed = version & 0b1000_0000 != 0; + let version = version & 0b0111_1111; + if version != EXTRINSIC_FORMAT_VERSION { + return Err("Invalid transaction version".into()) + } + + let signature = is_signed.then(|| Decode::decode(input)).transpose()?; let function = Decode::decode(input)?; if let Some((before_length, after_length)) = @@ -329,20 +303,31 @@ where } } - Ok(Self { preamble, function }) + Ok(Self { signature, function }) } } #[docify::export(unchecked_extrinsic_encode_impl)] -impl Encode - for UncheckedExtrinsic +impl Encode for UncheckedExtrinsic where - Preamble: Encode, + Address: Encode, + Signature: Encode, Call: Encode, - Extension: Encode, + Extra: SignedExtension, { fn encode(&self) -> Vec { - let mut tmp = self.preamble.encode(); + let mut tmp = Vec::with_capacity(sp_std::mem::size_of::()); + + // 1 byte version id. + match self.signature.as_ref() { + Some(s) => { + tmp.push(EXTRINSIC_FORMAT_VERSION | 0b1000_0000); + s.encode_to(&mut tmp); + }, + None => { + tmp.push(EXTRINSIC_FORMAT_VERSION & 0b0111_1111); + }, + } self.function.encode_to(&mut tmp); let compact_len = codec::Compact::(tmp.len() as u32); @@ -357,19 +342,19 @@ where } } -impl EncodeLike - for UncheckedExtrinsic +impl EncodeLike + for UncheckedExtrinsic where Address: Encode, Signature: Encode, - Call: Encode + Dispatchable, - Extension: TransactionExtension, + Call: Encode, + Extra: SignedExtension, { } #[cfg(feature = "serde")] -impl serde::Serialize - for UncheckedExtrinsic +impl serde::Serialize + for UncheckedExtrinsic { fn serialize(&self, seq: S) -> Result where @@ -380,88 +365,45 @@ impl serde: } #[cfg(feature = "serde")] -impl<'a, Address: Decode, Signature: Decode, Call: Decode, Extension: Decode> serde::Deserialize<'a> - for UncheckedExtrinsic +impl<'a, Address: Decode, Signature: Decode, Call: Decode, Extra: SignedExtension> + serde::Deserialize<'a> for UncheckedExtrinsic { fn deserialize(de: D) -> Result where D: serde::Deserializer<'a>, { let r = sp_core::bytes::deserialize(de)?; - Self::decode(&mut &r[..]) + Decode::decode(&mut &r[..]) .map_err(|e| serde::de::Error::custom(format!("Decode error: {}", e))) } } -/// A payload that has been signed for an unchecked extrinsics. -/// -/// Note that the payload that we sign to produce unchecked extrinsic signature -/// is going to be different than the `SignaturePayload` - so the thing the extrinsic -/// actually contains. -pub struct SignedPayload( - (Call, Extension, Extension::Implicit), -); - -impl SignedPayload -where - Call: Encode + Dispatchable, - Extension: TransactionExtensionBase, -{ - /// Create new `SignedPayload`. - /// - /// This function may fail if `implicit` of `Extension` is not available. - pub fn new(call: Call, tx_ext: Extension) -> Result { - let implicit = Extension::implicit(&tx_ext)?; - let raw_payload = (call, tx_ext, implicit); - Ok(Self(raw_payload)) - } - - /// Create new `SignedPayload` from raw components. - pub fn from_raw(call: Call, tx_ext: Extension, implicit: Extension::Implicit) -> Self { - Self((call, tx_ext, implicit)) - } - - /// Deconstruct the payload into it's components. - pub fn deconstruct(self) -> (Call, Extension, Extension::Implicit) { - self.0 - } -} - -impl Encode for SignedPayload +impl fmt::Debug + for UncheckedExtrinsic where - Call: Encode + Dispatchable, - Extension: TransactionExtensionBase, + Address: fmt::Debug, + Call: fmt::Debug, + Extra: SignedExtension, { - /// Get an encoded version of this payload. - /// - /// Payloads longer than 256 bytes are going to be `blake2_256`-hashed. - fn using_encoded R>(&self, f: F) -> R { - self.0.using_encoded(|payload| { - if payload.len() > 256 { - f(&blake2_256(payload)[..]) - } else { - f(payload) - } - }) + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "UncheckedExtrinsic({:?}, {:?})", + self.signature.as_ref().map(|x| (&x.0, &x.2)), + self.function, + ) } } -impl EncodeLike for SignedPayload -where - Call: Encode + Dispatchable, - Extension: TransactionExtensionBase, -{ -} - -impl - From> for OpaqueExtrinsic +impl From> + for OpaqueExtrinsic where Address: Encode, Signature: Encode, Call: Encode, - Extension: Encode, + Extra: SignedExtension, { - fn from(extrinsic: UncheckedExtrinsic) -> Self { + fn from(extrinsic: UncheckedExtrinsic) -> Self { Self::from_bytes(extrinsic.encode().as_slice()).expect( "both OpaqueExtrinsic and UncheckedExtrinsic have encoding that is compatible with \ raw Vec encoding; qed", @@ -469,198 +411,60 @@ where } } -#[cfg(test)] -mod legacy { - use codec::{Compact, Decode, Encode, EncodeLike, Error, Input}; - use scale_info::{ - build::Fields, meta_type, Path, StaticTypeInfo, Type, TypeInfo, TypeParameter, - }; - - pub type OldUncheckedSignaturePayload = (Address, Signature, Extra); - - #[derive(PartialEq, Eq, Clone, Debug)] - pub struct OldUncheckedExtrinsic { - pub signature: Option>, - pub function: Call, - } - - impl TypeInfo - for OldUncheckedExtrinsic - where - Address: StaticTypeInfo, - Call: StaticTypeInfo, - Signature: StaticTypeInfo, - Extra: StaticTypeInfo, - { - type Identity = OldUncheckedExtrinsic; - - fn type_info() -> Type { - Type::builder() - .path(Path::new("UncheckedExtrinsic", module_path!())) - // Include the type parameter types, even though they are not used directly in any - // of the described fields. These type definitions can be used by downstream - // consumers to help construct the custom decoding from the opaque bytes (see - // below). - .type_params(vec![ - TypeParameter::new("Address", Some(meta_type::
())), - TypeParameter::new("Call", Some(meta_type::())), - TypeParameter::new("Signature", Some(meta_type::())), - TypeParameter::new("Extra", Some(meta_type::())), - ]) - .docs(&["OldUncheckedExtrinsic raw bytes, requires custom decoding routine"]) - // Because of the custom encoding, we can only accurately describe the encoding as - // an opaque `Vec`. Downstream consumers will need to manually implement the - // codec to encode/decode the `signature` and `function` fields. - .composite(Fields::unnamed().field(|f| f.ty::>())) - } - } - - impl OldUncheckedExtrinsic { - pub fn new_signed( - function: Call, - signed: Address, - signature: Signature, - extra: Extra, - ) -> Self { - Self { signature: Some((signed, signature, extra)), function } - } - - pub fn new_unsigned(function: Call) -> Self { - Self { signature: None, function } - } - } - - impl Decode - for OldUncheckedExtrinsic - where - Address: Decode, - Signature: Decode, - Call: Decode, - Extra: Decode, - { - fn decode(input: &mut I) -> Result { - // This is a little more complicated than usual since the binary format must be - // compatible with SCALE's generic `Vec` type. Basically this just means accepting - // that there will be a prefix of vector length. - let expected_length: Compact = Decode::decode(input)?; - let before_length = input.remaining_len()?; - - let version = input.read_byte()?; - - let is_signed = version & 0b1000_0000 != 0; - let version = version & 0b0111_1111; - if version != 4u8 { - return Err("Invalid transaction version".into()) - } - - let signature = is_signed.then(|| Decode::decode(input)).transpose()?; - let function = Decode::decode(input)?; - - if let Some((before_length, after_length)) = - input.remaining_len()?.and_then(|a| before_length.map(|b| (b, a))) - { - let length = before_length.saturating_sub(after_length); - - if length != expected_length.0 as usize { - return Err("Invalid length prefix".into()) - } - } - - Ok(Self { signature, function }) - } - } - - #[docify::export(unchecked_extrinsic_encode_impl)] - impl Encode - for OldUncheckedExtrinsic - where - Address: Encode, - Signature: Encode, - Call: Encode, - Extra: Encode, - { - fn encode(&self) -> Vec { - let mut tmp = Vec::with_capacity(sp_std::mem::size_of::()); - - // 1 byte version id. - match self.signature.as_ref() { - Some(s) => { - tmp.push(4u8 | 0b1000_0000); - s.encode_to(&mut tmp); - }, - None => { - tmp.push(4u8 & 0b0111_1111); - }, - } - self.function.encode_to(&mut tmp); - - let compact_len = codec::Compact::(tmp.len() as u32); - - // Allocate the output buffer with the correct length - let mut output = Vec::with_capacity(compact_len.size_hint() + tmp.len()); - - compact_len.encode_to(&mut output); - output.extend(tmp); - - output - } - } - - impl EncodeLike - for OldUncheckedExtrinsic - where - Address: Encode, - Signature: Encode, - Call: Encode, - Extra: Encode, - { - } -} - #[cfg(test)] mod tests { - use super::{legacy::OldUncheckedExtrinsic, *}; + use super::*; use crate::{ codec::{Decode, Encode}, - impl_tx_ext_default, testing::TestSignature as TestSig, - traits::{FakeDispatchable, IdentityLookup, TransactionExtension}, + traits::{DispatchInfoOf, IdentityLookup, SignedExtension}, }; use sp_io::hashing::blake2_256; type TestContext = IdentityLookup; type TestAccountId = u64; - type TestCall = FakeDispatchable>; + type TestCall = Vec; const TEST_ACCOUNT: TestAccountId = 0; // NOTE: this is demonstration. One can simply use `()` for testing. #[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, Ord, PartialOrd, TypeInfo)] - struct DummyExtension; - impl TransactionExtensionBase for DummyExtension { - const IDENTIFIER: &'static str = "DummyExtension"; - type Implicit = (); - } - impl TransactionExtension for DummyExtension { - type Val = (); + struct TestExtra; + impl SignedExtension for TestExtra { + const IDENTIFIER: &'static str = "TestExtra"; + type AccountId = u64; + type Call = (); + type AdditionalSigned = (); type Pre = (); - impl_tx_ext_default!(TestCall; Context; validate prepare); + + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { + Ok(()) + } + + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + self.validate(who, call, info, len).map(|_| ()) + } } - type Ex = UncheckedExtrinsic; - type CEx = CheckedExtrinsic; + type Ex = UncheckedExtrinsic; + type CEx = CheckedExtrinsic; #[test] fn unsigned_codec_should_work() { - let call: TestCall = vec![0u8; 0].into(); - let ux = Ex::new_inherent(call); + let ux = Ex::new_unsigned(vec![0u8; 0]); let encoded = ux.encode(); assert_eq!(Ex::decode(&mut &encoded[..]), Ok(ux)); } #[test] fn invalid_length_prefix_is_detected() { - let ux = Ex::new_inherent(vec![0u8; 0].into()); + let ux = Ex::new_unsigned(vec![0u8; 0]); let mut encoded = ux.encode(); let length = Compact::::decode(&mut &encoded[..]).unwrap(); @@ -669,20 +473,13 @@ mod tests { assert_eq!(Ex::decode(&mut &encoded[..]), Err("Invalid length prefix".into())); } - #[test] - fn transaction_codec_should_work() { - let ux = Ex::new_transaction(vec![0u8; 0].into(), DummyExtension); - let encoded = ux.encode(); - assert_eq!(Ex::decode(&mut &encoded[..]), Ok(ux)); - } - #[test] fn signed_codec_should_work() { let ux = Ex::new_signed( - vec![0u8; 0].into(), + vec![0u8; 0], TEST_ACCOUNT, - TestSig(TEST_ACCOUNT, (vec![0u8; 0], DummyExtension).encode()), - DummyExtension, + TestSig(TEST_ACCOUNT, (vec![0u8; 0], TestExtra).encode()), + TestExtra, ); let encoded = ux.encode(); assert_eq!(Ex::decode(&mut &encoded[..]), Ok(ux)); @@ -691,13 +488,13 @@ mod tests { #[test] fn large_signed_codec_should_work() { let ux = Ex::new_signed( - vec![0u8; 0].into(), + vec![0u8; 0], TEST_ACCOUNT, TestSig( TEST_ACCOUNT, - (vec![0u8; 257], DummyExtension).using_encoded(blake2_256)[..].to_owned(), + (vec![0u8; 257], TestExtra).using_encoded(blake2_256)[..].to_owned(), ), - DummyExtension, + TestExtra, ); let encoded = ux.encode(); assert_eq!(Ex::decode(&mut &encoded[..]), Ok(ux)); @@ -705,63 +502,44 @@ mod tests { #[test] fn unsigned_check_should_work() { - let ux = Ex::new_inherent(vec![0u8; 0].into()); - assert!(ux.is_inherent()); - assert_eq!( - >::check(ux, &Default::default()), - Ok(CEx { format: ExtrinsicFormat::Bare, function: vec![0u8; 0].into() }), - ); + let ux = Ex::new_unsigned(vec![0u8; 0]); + assert!(!ux.is_signed().unwrap_or(false)); + assert!(>::check(ux, &Default::default()).is_ok()); } #[test] fn badly_signed_check_should_fail() { let ux = Ex::new_signed( - vec![0u8; 0].into(), + vec![0u8; 0], TEST_ACCOUNT, - TestSig(TEST_ACCOUNT, vec![0u8; 0].into()), - DummyExtension, + TestSig(TEST_ACCOUNT, vec![0u8; 0]), + TestExtra, ); - assert!(!ux.is_inherent()); + assert!(ux.is_signed().unwrap_or(false)); assert_eq!( >::check(ux, &Default::default()), Err(InvalidTransaction::BadProof.into()), ); } - #[test] - fn transaction_check_should_work() { - let ux = Ex::new_transaction(vec![0u8; 0].into(), DummyExtension); - assert!(!ux.is_inherent()); - assert_eq!( - >::check(ux, &Default::default()), - Ok(CEx { - format: ExtrinsicFormat::General(DummyExtension), - function: vec![0u8; 0].into() - }), - ); - } - #[test] fn signed_check_should_work() { let ux = Ex::new_signed( - vec![0u8; 0].into(), + vec![0u8; 0], TEST_ACCOUNT, - TestSig(TEST_ACCOUNT, (vec![0u8; 0], DummyExtension).encode()), - DummyExtension, + TestSig(TEST_ACCOUNT, (vec![0u8; 0], TestExtra).encode()), + TestExtra, ); - assert!(!ux.is_inherent()); + assert!(ux.is_signed().unwrap_or(false)); assert_eq!( >::check(ux, &Default::default()), - Ok(CEx { - format: ExtrinsicFormat::Signed(TEST_ACCOUNT, DummyExtension), - function: vec![0u8; 0].into() - }), + Ok(CEx { signed: Some((TEST_ACCOUNT, TestExtra)), function: vec![0u8; 0] }), ); } #[test] fn encoding_matches_vec() { - let ex = Ex::new_inherent(vec![0u8; 0].into()); + let ex = Ex::new_unsigned(vec![0u8; 0]); let encoded = ex.encode(); let decoded = Ex::decode(&mut encoded.as_slice()).unwrap(); assert_eq!(decoded, ex); @@ -771,7 +549,7 @@ mod tests { #[test] fn conversion_to_opaque() { - let ux = Ex::new_inherent(vec![0u8; 0].into()); + let ux = Ex::new_unsigned(vec![0u8; 0]); let encoded = ux.encode(); let opaque: OpaqueExtrinsic = ux.into(); let opaque_encoded = opaque.encode(); @@ -780,62 +558,10 @@ mod tests { #[test] fn large_bad_prefix_should_work() { - let encoded = (Compact::::from(u32::MAX), Preamble::<(), (), ()>::Bare).encode(); - assert!(Ex::decode(&mut &encoded[..]).is_err()); - } - - #[test] - fn legacy_signed_encode_decode() { - let call: TestCall = vec![0u8; 0].into(); - let signed = TEST_ACCOUNT; - let signature = TestSig(TEST_ACCOUNT, (vec![0u8; 0], DummyExtension).encode()); - let extension = DummyExtension; - - let new_ux = Ex::new_signed(call.clone(), signed, signature.clone(), extension.clone()); - let old_ux = - OldUncheckedExtrinsic::::new_signed( - call, signed, signature, extension, - ); - - let encoded_new_ux = new_ux.encode(); - let encoded_old_ux = old_ux.encode(); - - assert_eq!(encoded_new_ux, encoded_old_ux); - - let decoded_new_ux = Ex::decode(&mut &encoded_new_ux[..]).unwrap(); - let decoded_old_ux = - OldUncheckedExtrinsic::::decode( - &mut &encoded_old_ux[..], - ) - .unwrap(); - - assert_eq!(new_ux, decoded_new_ux); - assert_eq!(old_ux, decoded_old_ux); - } - - #[test] - fn legacy_unsigned_encode_decode() { - let call: TestCall = vec![0u8; 0].into(); - - let new_ux = Ex::new_bare(call.clone()); - let old_ux = - OldUncheckedExtrinsic::::new_unsigned( - call, - ); - - let encoded_new_ux = new_ux.encode(); - let encoded_old_ux = old_ux.encode(); - - assert_eq!(encoded_new_ux, encoded_old_ux); - - let decoded_new_ux = Ex::decode(&mut &encoded_new_ux[..]).unwrap(); - let decoded_old_ux = - OldUncheckedExtrinsic::::decode( - &mut &encoded_old_ux[..], - ) - .unwrap(); - - assert_eq!(new_ux, decoded_new_ux); - assert_eq!(old_ux, decoded_old_ux); + let encoded = Compact::::from(u32::MAX).encode(); + assert_eq!( + Ex::decode(&mut &encoded[..]), + Err(Error::from("Not enough data to fill buffer")) + ); } } diff --git a/substrate/primitives/runtime/src/lib.rs b/substrate/primitives/runtime/src/lib.rs index 70605970b4e..44bf3c969e5 100644 --- a/substrate/primitives/runtime/src/lib.rs +++ b/substrate/primitives/runtime/src/lib.rs @@ -125,11 +125,6 @@ pub use sp_arithmetic::{ Perquintill, Rational128, Rounding, UpperOf, }; -pub use transaction_validity::{ - InvalidTransaction, TransactionSource, TransactionValidityError, UnknownTransaction, - ValidTransaction, -}; - pub use either::Either; /// The number of bytes of the module-specific `error` field defined in [`ModuleError`]. @@ -448,21 +443,21 @@ impl std::fmt::Display for MultiSigner { impl Verify for MultiSignature { type Signer = MultiSigner; fn verify>(&self, mut msg: L, signer: &AccountId32) -> bool { - match self { - Self::Ed25519(ref sig) => match ed25519::Public::from_slice(signer.as_ref()) { + match (self, signer) { + (Self::Ed25519(ref sig), who) => match ed25519::Public::from_slice(who.as_ref()) { Ok(signer) => sig.verify(msg, &signer), Err(()) => false, }, - Self::Sr25519(ref sig) => match sr25519::Public::from_slice(signer.as_ref()) { + (Self::Sr25519(ref sig), who) => match sr25519::Public::from_slice(who.as_ref()) { Ok(signer) => sig.verify(msg, &signer), Err(()) => false, }, - Self::Ecdsa(ref sig) => { + (Self::Ecdsa(ref sig), who) => { let m = sp_io::hashing::blake2_256(msg.get()); match sp_io::crypto::secp256k1_ecdsa_recover_compressed(sig.as_ref(), &m) { Ok(pubkey) => &sp_io::hashing::blake2_256(pubkey.as_ref()) == - >::as_ref(signer), + >::as_ref(who), _ => false, } }, @@ -949,13 +944,9 @@ impl<'a> ::serde::Deserialize<'a> for OpaqueExtrinsic { } } -// TODO: OpaqueExtrinsics cannot act like regular extrinsics, right?! impl traits::Extrinsic for OpaqueExtrinsic { type Call = (); type SignaturePayload = (); - fn is_bare(&self) -> bool { - false - } } /// Print something that implements `Printable` from the runtime. diff --git a/substrate/primitives/runtime/src/testing.rs b/substrate/primitives/runtime/src/testing.rs index 3d6e0b5ab8b..5f94c834a8f 100644 --- a/substrate/primitives/runtime/src/testing.rs +++ b/substrate/primitives/runtime/src/testing.rs @@ -21,16 +21,24 @@ use crate::{ codec::{Codec, Decode, Encode, MaxEncodedLen}, generic, scale_info::TypeInfo, - traits::{self, BlakeTwo256, Dispatchable, OpaqueKeys}, - DispatchResultWithInfo, KeyTypeId, + traits::{ + self, Applyable, BlakeTwo256, Checkable, DispatchInfoOf, Dispatchable, OpaqueKeys, + PostDispatchInfoOf, SignaturePayload, SignedExtension, ValidateUnsigned, + }, + transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError}, + ApplyExtrinsicResultWithInfo, KeyTypeId, }; -use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize}; +use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize, Serializer}; use sp_core::{ crypto::{key_types, ByteArray, CryptoType, Dummy}, U256, }; pub use sp_core::{sr25519, H256}; -use std::{cell::RefCell, fmt::Debug}; +use std::{ + cell::RefCell, + fmt::{self, Debug}, + ops::Deref, +}; /// A dummy type which can be used instead of regular cryptographic primitives. /// @@ -190,6 +198,42 @@ impl Header { } } +/// An opaque extrinsic wrapper type. +#[derive(PartialEq, Eq, Clone, Debug, Encode, Decode)] +pub struct ExtrinsicWrapper(Xt); + +impl traits::Extrinsic for ExtrinsicWrapper { + type Call = (); + type SignaturePayload = (); + + fn is_signed(&self) -> Option { + None + } +} + +impl serde::Serialize for ExtrinsicWrapper { + fn serialize(&self, seq: S) -> Result + where + S: ::serde::Serializer, + { + self.using_encoded(|bytes| seq.serialize_bytes(bytes)) + } +} + +impl From for ExtrinsicWrapper { + fn from(xt: Xt) -> Self { + ExtrinsicWrapper(xt) + } +} + +impl Deref for ExtrinsicWrapper { + type Target = Xt; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + /// Testing block #[derive(PartialEq, Eq, Clone, Serialize, Debug, Encode, Decode, TypeInfo)] pub struct Block { @@ -239,22 +283,139 @@ where } } -/// Wrapper over a `u64` that can be used as a `RuntimeCall`. -#[derive(PartialEq, Eq, Debug, Clone, Encode, Decode, TypeInfo)] -pub struct MockCallU64(pub u64); +/// The signature payload of a `TestXt`. +type TxSingaturePayload = (u64, Extra); + +impl SignaturePayload for TxSingaturePayload { + type SignatureAddress = u64; + type Signature = (); + type SignatureExtra = Extra; +} + +/// Test transaction, tuple of (sender, call, signed_extra) +/// with index only used if sender is some. +/// +/// If sender is some then the transaction is signed otherwise it is unsigned. +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo)] +pub struct TestXt { + /// Signature of the extrinsic. + pub signature: Option>, + /// Call of the extrinsic. + pub call: Call, +} + +impl TestXt { + /// Create a new `TextXt`. + pub fn new(call: Call, signature: Option<(u64, Extra)>) -> Self { + Self { call, signature } + } +} + +impl Serialize for TestXt +where + TestXt: Encode, +{ + fn serialize(&self, seq: S) -> Result + where + S: Serializer, + { + self.using_encoded(|bytes| seq.serialize_bytes(bytes)) + } +} -impl Dispatchable for MockCallU64 { - type RuntimeOrigin = u64; - type Config = (); - type Info = (); - type PostInfo = (); - fn dispatch(self, _origin: Self::RuntimeOrigin) -> DispatchResultWithInfo { - Ok(()) +impl Debug for TestXt { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "TestXt({:?}, ...)", self.signature.as_ref().map(|x| &x.0)) } } -impl From for MockCallU64 { - fn from(value: u64) -> Self { - Self(value) +impl Checkable for TestXt { + type Checked = Self; + fn check(self, _: &Context) -> Result { + Ok(self) + } + + #[cfg(feature = "try-runtime")] + fn unchecked_into_checked_i_know_what_i_am_doing( + self, + _: &Context, + ) -> Result { + unreachable!() + } +} + +impl traits::Extrinsic + for TestXt +{ + type Call = Call; + type SignaturePayload = TxSingaturePayload; + + fn is_signed(&self) -> Option { + Some(self.signature.is_some()) + } + + fn new(c: Call, sig: Option) -> Option { + Some(TestXt { signature: sig, call: c }) + } +} + +impl traits::ExtrinsicMetadata for TestXt +where + Call: Codec + Sync + Send, + Extra: SignedExtension, +{ + type SignedExtensions = Extra; + const VERSION: u8 = 0u8; +} + +impl Applyable for TestXt +where + Call: 'static + + Sized + + Send + + Sync + + Clone + + Eq + + Codec + + Debug + + Dispatchable, + Extra: SignedExtension, + Origin: From>, +{ + type Call = Call; + + /// Checks to see if this is a valid *transaction*. It returns information on it if so. + fn validate>( + &self, + source: TransactionSource, + info: &DispatchInfoOf, + len: usize, + ) -> TransactionValidity { + if let Some((ref id, ref extra)) = self.signature { + Extra::validate(extra, id, &self.call, info, len) + } else { + let valid = Extra::validate_unsigned(&self.call, info, len)?; + let unsigned_validation = U::validate_unsigned(source, &self.call)?; + Ok(valid.combine_with(unsigned_validation)) + } + } + + /// Executes all necessary logic needed prior to dispatch and deconstructs into function call, + /// index and sender. + fn apply>( + self, + info: &DispatchInfoOf, + len: usize, + ) -> ApplyExtrinsicResultWithInfo> { + let maybe_who = if let Some((who, extra)) = self.signature { + Extra::pre_dispatch(extra, &who, &self.call, info, len)?; + Some(who) + } else { + Extra::pre_dispatch_unsigned(&self.call, info, len)?; + U::pre_dispatch(&self.call)?; + None + }; + + Ok(self.call.dispatch(maybe_who.into())) } } diff --git a/substrate/primitives/runtime/src/traits/mod.rs b/substrate/primitives/runtime/src/traits.rs similarity index 94% rename from substrate/primitives/runtime/src/traits/mod.rs rename to substrate/primitives/runtime/src/traits.rs index b217166d8de..caede5e2b59 100644 --- a/substrate/primitives/runtime/src/traits/mod.rs +++ b/substrate/primitives/runtime/src/traits.rs @@ -19,7 +19,7 @@ use crate::{ generic::Digest, - scale_info::{StaticTypeInfo, TypeInfo}, + scale_info::{MetaType, StaticTypeInfo, TypeInfo}, transaction_validity::{ TransactionSource, TransactionValidity, TransactionValidityError, UnknownTransaction, ValidTransaction, @@ -52,12 +52,6 @@ use std::fmt::Display; #[cfg(feature = "std")] use std::str::FromStr; -pub mod transaction_extension; -pub use transaction_extension::{ - DispatchTransaction, TransactionExtension, TransactionExtensionBase, - TransactionExtensionInterior, TransactionExtensionMetadata, ValidateResult, -}; - /// A lazy value. pub trait Lazy { /// Get a reference to the underlying value. @@ -1259,7 +1253,7 @@ pub trait Header: // that is then used to define `UncheckedExtrinsic`. // ```ignore // pub type UncheckedExtrinsic = -// generic::UncheckedExtrinsic; +// generic::UncheckedExtrinsic; // ``` // This `UncheckedExtrinsic` is supplied to the `Block`. // ```ignore @@ -1329,31 +1323,19 @@ pub trait Extrinsic: Sized { /// Is this `Extrinsic` signed? /// If no information are available about signed/unsigned, `None` should be returned. - #[deprecated = "Use and implement `!is_bare()` instead"] fn is_signed(&self) -> Option { None } - /// Returns `true` if this `Extrinsic` is bare. - fn is_bare(&self) -> bool { - #[allow(deprecated)] - !self - .is_signed() - .expect("`is_signed` must return `Some` on production extrinsics; qed") - } - - /// Create a new old-school extrinsic, either a bare extrinsic if `_signed_data` is `None` or - /// a signed transaction is it is `Some`. - #[deprecated = "Use `new_inherent` or the `CreateTransaction` trait instead"] + /// Create new instance of the extrinsic. + /// + /// Extrinsics can be split into: + /// 1. Inherents (no signature; created by validators during block production) + /// 2. Unsigned Transactions (no signature; represent "system calls" or other special kinds of + /// calls) 3. Signed Transactions (with signature; a regular transactions with known origin) fn new(_call: Self::Call, _signed_data: Option) -> Option { None } - - /// Create a new inherent extrinsic. - fn new_inherent(function: Self::Call) -> Self { - #[allow(deprecated)] - Self::new(function, None).expect("Extrinsic must provide inherents; qed") - } } /// Something that acts like a [`SignaturePayload`](Extrinsic::SignaturePayload) of an @@ -1389,8 +1371,7 @@ pub trait ExtrinsicMetadata { const VERSION: u8; /// Signed extensions attached to this `Extrinsic`. - // TODO: metadata-v16: rename to `Extension`. - type Extra; + type SignedExtensions: SignedExtension; } /// Extract the hashing type for a block. @@ -1475,8 +1456,6 @@ pub trait Dispatchable { -> crate::DispatchResultWithInfo; } -/// Shortcut to reference the `Origin` type of a `Dispatchable`. -pub type OriginOf = ::RuntimeOrigin; /// Shortcut to reference the `Info` type of a `Dispatchable`. pub type DispatchInfoOf = ::Info; /// Shortcut to reference the `PostInfo` type of a `Dispatchable`. @@ -1495,49 +1474,8 @@ impl Dispatchable for () { } } -/// Dispatchable impl containing an arbitrary value which panics if it actually is dispatched. -#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct FakeDispatchable(pub Inner); -impl From for FakeDispatchable { - fn from(inner: Inner) -> Self { - Self(inner) - } -} -impl FakeDispatchable { - /// Take `self` and return the underlying inner value. - pub fn deconstruct(self) -> Inner { - self.0 - } -} -impl AsRef for FakeDispatchable { - fn as_ref(&self) -> &Inner { - &self.0 - } -} - -impl Dispatchable for FakeDispatchable { - type RuntimeOrigin = (); - type Config = (); - type Info = (); - type PostInfo = (); - fn dispatch( - self, - _origin: Self::RuntimeOrigin, - ) -> crate::DispatchResultWithInfo { - panic!("This implementation should not be used for actual dispatch."); - } -} - -/// Runtime Origin which includes a System Origin variant whose `AccountId` is the parameter. -pub trait AsSystemOriginSigner { - /// Extract a reference of the inner value of the System `Origin::Signed` variant, if self has - /// that variant. - fn as_system_origin_signer(&self) -> Option<&AccountId>; -} - /// Means by which a transaction may be extended. This type embodies both the data and the logic /// that should be additionally associated with the transaction. It should be plain old data. -#[deprecated = "Use `TransactionExtension` instead."] pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq + StaticTypeInfo { @@ -1555,7 +1493,7 @@ pub trait SignedExtension: /// Any additional data that will go into the signed payload. This may be created dynamically /// from the transaction using the `additional_signed` function. - type AdditionalSigned: Codec + TypeInfo; + type AdditionalSigned: Encode + TypeInfo; /// The type that encodes information that can be passed from pre_dispatch to post-dispatch. type Pre; @@ -1594,6 +1532,38 @@ pub trait SignedExtension: len: usize, ) -> Result; + /// Validate an unsigned transaction for the transaction queue. + /// + /// This function can be called frequently by the transaction queue + /// to obtain transaction validity against current state. + /// It should perform all checks that determine a valid unsigned transaction, + /// and quickly eliminate ones that are stale or incorrect. + /// + /// Make sure to perform the same checks in `pre_dispatch_unsigned` function. + fn validate_unsigned( + _call: &Self::Call, + _info: &DispatchInfoOf, + _len: usize, + ) -> TransactionValidity { + Ok(ValidTransaction::default()) + } + + /// Do any pre-flight stuff for a unsigned transaction. + /// + /// Note this function by default delegates to `validate_unsigned`, so that + /// all checks performed for the transaction queue are also performed during + /// the dispatch phase (applying the extrinsic). + /// + /// If you ever override this function, you need to make sure to always + /// perform the same validation as in `validate_unsigned`. + fn pre_dispatch_unsigned( + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result<(), TransactionValidityError> { + Self::validate_unsigned(call, info, len).map(|_| ()).map_err(Into::into) + } + /// Do any post-flight stuff for an extrinsic. /// /// If the transaction is signed, then `_pre` will contain the output of `pre_dispatch`, @@ -1624,47 +1594,126 @@ pub trait SignedExtension: /// /// As a [`SignedExtension`] can be a tuple of [`SignedExtension`]s we need to return a `Vec` /// that holds the metadata of each one. Each individual `SignedExtension` must return - /// *exactly* one [`TransactionExtensionMetadata`]. + /// *exactly* one [`SignedExtensionMetadata`]. /// /// This method provides a default implementation that returns a vec containing a single - /// [`TransactionExtensionMetadata`]. - fn metadata() -> Vec { - sp_std::vec![TransactionExtensionMetadata { + /// [`SignedExtensionMetadata`]. + fn metadata() -> Vec { + sp_std::vec![SignedExtensionMetadata { identifier: Self::IDENTIFIER, ty: scale_info::meta_type::(), additional_signed: scale_info::meta_type::() }] } +} + +/// Information about a [`SignedExtension`] for the runtime metadata. +pub struct SignedExtensionMetadata { + /// The unique identifier of the [`SignedExtension`]. + pub identifier: &'static str, + /// The type of the [`SignedExtension`]. + pub ty: MetaType, + /// The type of the [`SignedExtension`] additional signed data for the payload. + pub additional_signed: MetaType, +} + +#[impl_for_tuples(1, 12)] +impl SignedExtension for Tuple { + for_tuples!( where #( Tuple: SignedExtension )* ); + type AccountId = AccountId; + type Call = Call; + const IDENTIFIER: &'static str = "You should call `identifier()`!"; + for_tuples!( type AdditionalSigned = ( #( Tuple::AdditionalSigned ),* ); ); + for_tuples!( type Pre = ( #( Tuple::Pre ),* ); ); + + fn additional_signed(&self) -> Result { + Ok(for_tuples!( ( #( Tuple.additional_signed()? ),* ) )) + } + + fn validate( + &self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> TransactionValidity { + let valid = ValidTransaction::default(); + for_tuples!( #( let valid = valid.combine_with(Tuple.validate(who, call, info, len)?); )* ); + Ok(valid) + } + + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + Ok(for_tuples!( ( #( Tuple.pre_dispatch(who, call, info, len)? ),* ) )) + } - /// Validate an unsigned transaction for the transaction queue. - /// - /// This function can be called frequently by the transaction queue - /// to obtain transaction validity against current state. - /// It should perform all checks that determine a valid unsigned transaction, - /// and quickly eliminate ones that are stale or incorrect. fn validate_unsigned( - _call: &Self::Call, - _info: &DispatchInfoOf, - _len: usize, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, ) -> TransactionValidity { - Ok(ValidTransaction::default()) + let valid = ValidTransaction::default(); + for_tuples!( #( let valid = valid.combine_with(Tuple::validate_unsigned(call, info, len)?); )* ); + Ok(valid) } - /// Do any pre-flight stuff for an unsigned transaction. - /// - /// Note this function by default delegates to `validate_unsigned`, so that - /// all checks performed for the transaction queue are also performed during - /// the dispatch phase (applying the extrinsic). - /// - /// If you ever override this function, you need not perform the same validation as in - /// `validate_unsigned`. fn pre_dispatch_unsigned( - _call: &Self::Call, - _info: &DispatchInfoOf, - _len: usize, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, ) -> Result<(), TransactionValidityError> { + for_tuples!( #( Tuple::pre_dispatch_unsigned(call, info, len)?; )* ); Ok(()) } + + fn post_dispatch( + pre: Option, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, + len: usize, + result: &DispatchResult, + ) -> Result<(), TransactionValidityError> { + match pre { + Some(x) => { + for_tuples!( #( Tuple::post_dispatch(Some(x.Tuple), info, post_info, len, result)?; )* ); + }, + None => { + for_tuples!( #( Tuple::post_dispatch(None, info, post_info, len, result)?; )* ); + }, + } + Ok(()) + } + + fn metadata() -> Vec { + let mut ids = Vec::new(); + for_tuples!( #( ids.extend(Tuple::metadata()); )* ); + ids + } +} + +impl SignedExtension for () { + type AccountId = u64; + type AdditionalSigned = (); + type Call = (); + type Pre = (); + const IDENTIFIER: &'static str = "UnitSignedExtension"; + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { + Ok(()) + } + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + self.validate(who, call, info, len).map(|_| ()) + } } /// An "executable" piece of information, used by the standard Substrate Executive in order to @@ -1713,7 +1762,6 @@ pub trait GetNodeBlockType { /// function is called right before dispatching the call wrapped by an unsigned extrinsic. The /// [`validate_unsigned`](Self::validate_unsigned) function is mainly being used in the context of /// the transaction pool to check the validity of the call wrapped by an unsigned extrinsic. -// TODO: Rename to ValidateBareTransaction (or just remove). pub trait ValidateUnsigned { /// The call to validate type Call; diff --git a/substrate/primitives/runtime/src/traits/transaction_extension/as_transaction_extension.rs b/substrate/primitives/runtime/src/traits/transaction_extension/as_transaction_extension.rs deleted file mode 100644 index a834e88c0b4..00000000000 --- a/substrate/primitives/runtime/src/traits/transaction_extension/as_transaction_extension.rs +++ /dev/null @@ -1,133 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// 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. - -//! The [AsTransactionExtension] adapter struct for adapting [SignedExtension]s to -//! [TransactionExtension]s. - -#![allow(deprecated)] - -use scale_info::TypeInfo; -use sp_core::RuntimeDebug; - -use crate::{ - traits::{AsSystemOriginSigner, SignedExtension, ValidateResult}, - InvalidTransaction, -}; - -use super::*; - -/// Adapter to use a `SignedExtension` in the place of a `TransactionExtension`. -#[derive(TypeInfo, Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] -#[deprecated = "Convert your SignedExtension to a TransactionExtension."] -pub struct AsTransactionExtension(pub SE); - -impl Default for AsTransactionExtension { - fn default() -> Self { - Self(SE::default()) - } -} - -impl From for AsTransactionExtension { - fn from(value: SE) -> Self { - Self(value) - } -} - -impl TransactionExtensionBase for AsTransactionExtension { - const IDENTIFIER: &'static str = SE::IDENTIFIER; - type Implicit = SE::AdditionalSigned; - - fn implicit(&self) -> Result { - self.0.additional_signed() - } - fn metadata() -> Vec { - SE::metadata() - } -} - -impl TransactionExtension - for AsTransactionExtension -where - ::RuntimeOrigin: AsSystemOriginSigner + Clone, -{ - type Val = (); - type Pre = SE::Pre; - - fn validate( - &self, - origin: ::RuntimeOrigin, - call: &SE::Call, - info: &DispatchInfoOf, - len: usize, - _context: &mut Context, - _self_implicit: Self::Implicit, - _inherited_implication: &impl Encode, - ) -> ValidateResult { - let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?; - let r = self.0.validate(who, call, info, len)?; - Ok((r, (), origin)) - } - - fn prepare( - self, - _: (), - origin: &::RuntimeOrigin, - call: &SE::Call, - info: &DispatchInfoOf, - len: usize, - _context: &Context, - ) -> Result { - let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?; - self.0.pre_dispatch(who, call, info, len) - } - - fn post_dispatch( - pre: Self::Pre, - info: &DispatchInfoOf, - post_info: &PostDispatchInfoOf, - len: usize, - result: &DispatchResult, - _context: &Context, - ) -> Result<(), TransactionValidityError> { - SE::post_dispatch(Some(pre), info, post_info, len, result) - } - - fn validate_bare_compat( - call: &SE::Call, - info: &DispatchInfoOf, - len: usize, - ) -> TransactionValidity { - SE::validate_unsigned(call, info, len) - } - - fn pre_dispatch_bare_compat( - call: &SE::Call, - info: &DispatchInfoOf, - len: usize, - ) -> Result<(), TransactionValidityError> { - SE::pre_dispatch_unsigned(call, info, len) - } - - fn post_dispatch_bare_compat( - info: &DispatchInfoOf, - post_info: &PostDispatchInfoOf, - len: usize, - result: &DispatchResult, - ) -> Result<(), TransactionValidityError> { - SE::post_dispatch(None, info, post_info, len, result) - } -} diff --git a/substrate/primitives/runtime/src/traits/transaction_extension/dispatch_transaction.rs b/substrate/primitives/runtime/src/traits/transaction_extension/dispatch_transaction.rs deleted file mode 100644 index 8efa586aa0e..00000000000 --- a/substrate/primitives/runtime/src/traits/transaction_extension/dispatch_transaction.rs +++ /dev/null @@ -1,141 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// 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. - -//! The [DispatchTransaction] trait. - -use super::*; - -/// Single-function utility trait with a blanket impl over [TransactionExtension] in order to -/// provide transaction dispatching functionality. We avoid implementing this directly on the trait -/// since we never want it to be overriden by the trait implementation. -pub trait DispatchTransaction { - /// The origin type of the transaction. - type Origin; - /// The info type. - type Info; - /// The resultant type. - type Result; - /// The `Val` of the extension. - type Val; - /// The `Pre` of the extension. - type Pre; - /// Just validate a transaction. - /// - /// The is basically the same as [validate](TransactionExtension::validate), except that there - /// is no need to supply the bond data. - fn validate_only( - &self, - origin: Self::Origin, - call: &Call, - info: &Self::Info, - len: usize, - ) -> Result<(ValidTransaction, Self::Val, Self::Origin), TransactionValidityError>; - /// Prepare and validate a transaction, ready for dispatch. - fn validate_and_prepare( - self, - origin: Self::Origin, - call: &Call, - info: &Self::Info, - len: usize, - ) -> Result<(Self::Pre, Self::Origin), TransactionValidityError>; - /// Dispatch a transaction with the given base origin and call. - fn dispatch_transaction( - self, - origin: Self::Origin, - call: Call, - info: &Self::Info, - len: usize, - ) -> Self::Result; - /// Do everything which would be done in a [dispatch_transaction](Self::dispatch_transaction), - /// but instead of executing the call, execute `substitute` instead. Since this doesn't actually - /// dispatch the call, it doesn't need to consume it and so `call` can be passed as a reference. - fn test_run( - self, - origin: Self::Origin, - call: &Call, - info: &Self::Info, - len: usize, - substitute: impl FnOnce( - Self::Origin, - ) -> crate::DispatchResultWithInfo<::PostInfo>, - ) -> Self::Result; -} - -impl, Call: Dispatchable + Encode> DispatchTransaction - for T -{ - type Origin = ::RuntimeOrigin; - type Info = DispatchInfoOf; - type Result = crate::ApplyExtrinsicResultWithInfo>; - type Val = T::Val; - type Pre = T::Pre; - - fn validate_only( - &self, - origin: Self::Origin, - call: &Call, - info: &DispatchInfoOf, - len: usize, - ) -> Result<(ValidTransaction, T::Val, Self::Origin), TransactionValidityError> { - self.validate(origin, call, info, len, &mut (), self.implicit()?, call) - } - fn validate_and_prepare( - self, - origin: Self::Origin, - call: &Call, - info: &DispatchInfoOf, - len: usize, - ) -> Result<(T::Pre, Self::Origin), TransactionValidityError> { - let (_, val, origin) = self.validate_only(origin, call, info, len)?; - let pre = self.prepare(val, &origin, &call, info, len, &())?; - Ok((pre, origin)) - } - fn dispatch_transaction( - self, - origin: ::RuntimeOrigin, - call: Call, - info: &DispatchInfoOf, - len: usize, - ) -> Self::Result { - let (pre, origin) = self.validate_and_prepare(origin, &call, info, len)?; - let res = call.dispatch(origin); - let post_info = res.unwrap_or_else(|err| err.post_info); - let pd_res = res.map(|_| ()).map_err(|e| e.error); - T::post_dispatch(pre, info, &post_info, len, &pd_res, &())?; - Ok(res) - } - fn test_run( - self, - origin: Self::Origin, - call: &Call, - info: &Self::Info, - len: usize, - substitute: impl FnOnce( - Self::Origin, - ) -> crate::DispatchResultWithInfo<::PostInfo>, - ) -> Self::Result { - let (pre, origin) = self.validate_and_prepare(origin, &call, info, len)?; - let res = substitute(origin); - let post_info = match res { - Ok(info) => info, - Err(err) => err.post_info, - }; - let pd_res = res.map(|_| ()).map_err(|e| e.error); - T::post_dispatch(pre, info, &post_info, len, &pd_res, &())?; - Ok(res) - } -} diff --git a/substrate/primitives/runtime/src/traits/transaction_extension/mod.rs b/substrate/primitives/runtime/src/traits/transaction_extension/mod.rs deleted file mode 100644 index 69a0ba18adb..00000000000 --- a/substrate/primitives/runtime/src/traits/transaction_extension/mod.rs +++ /dev/null @@ -1,526 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// 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. - -//! The transaction extension trait. - -use crate::{ - scale_info::{MetaType, StaticTypeInfo}, - transaction_validity::{TransactionValidity, TransactionValidityError, ValidTransaction}, - DispatchResult, -}; -use codec::{Codec, Decode, Encode}; -use impl_trait_for_tuples::impl_for_tuples; -#[doc(hidden)] -pub use sp_std::marker::PhantomData; -use sp_std::{self, fmt::Debug, prelude::*}; -use sp_weights::Weight; -use tuplex::{PopFront, PushBack}; - -use super::{DispatchInfoOf, Dispatchable, OriginOf, PostDispatchInfoOf}; - -mod as_transaction_extension; -mod dispatch_transaction; -#[allow(deprecated)] -pub use as_transaction_extension::AsTransactionExtension; -pub use dispatch_transaction::DispatchTransaction; - -/// Shortcut for the result value of the `validate` function. -pub type ValidateResult = - Result<(ValidTransaction, Val, OriginOf), TransactionValidityError>; - -/// Simple blanket implementation trait to denote the bounds of a type which can be contained within -/// a [`TransactionExtension`]. -pub trait TransactionExtensionInterior: - Codec + Debug + Sync + Send + Clone + Eq + PartialEq + StaticTypeInfo -{ -} -impl - TransactionExtensionInterior for T -{ -} - -/// Base for [TransactionExtension]s; this contains the associated types and does not require any -/// generic parameterization. -pub trait TransactionExtensionBase: TransactionExtensionInterior { - /// Unique identifier of this signed extension. - /// - /// This will be exposed in the metadata to identify the signed extension used in an extrinsic. - const IDENTIFIER: &'static str; - - /// Any additional data which was known at the time of transaction construction and can be - /// useful in authenticating the transaction. This is determined dynamically in part from the - /// on-chain environment using the `implicit` function and not directly contained in the - /// transaction itself and therefore is considered "implicit". - type Implicit: Codec + StaticTypeInfo; - - /// Determine any additional data which was known at the time of transaction construction and - /// can be useful in authenticating the transaction. The expected usage of this is to include in - /// any data which is signed and verified as part of transactiob validation. Also perform any - /// pre-signature-verification checks and return an error if needed. - fn implicit(&self) -> Result { - use crate::InvalidTransaction::IndeterminateImplicit; - Ok(Self::Implicit::decode(&mut &[][..]).map_err(|_| IndeterminateImplicit)?) - } - - /// The weight consumed by executing this extension instance fully during transaction dispatch. - fn weight(&self) -> Weight { - Weight::zero() - } - - /// Returns the metadata for this extension. - /// - /// As a [`TransactionExtension`] can be a tuple of [`TransactionExtension`]s we need to return - /// a `Vec` that holds the metadata of each one. Each individual `TransactionExtension` must - /// return *exactly* one [`TransactionExtensionMetadata`]. - /// - /// This method provides a default implementation that returns a vec containing a single - /// [`TransactionExtensionMetadata`]. - fn metadata() -> Vec { - sp_std::vec![TransactionExtensionMetadata { - identifier: Self::IDENTIFIER, - ty: scale_info::meta_type::(), - // TODO: Metadata-v16: Rename to "implicit" - additional_signed: scale_info::meta_type::() - }] - } -} - -/// Means by which a transaction may be extended. This type embodies both the data and the logic -/// that should be additionally associated with the transaction. It should be plain old data. -/// -/// The simplest transaction extension would be the Unit type (and empty pipeline) `()`. This -/// executes no additional logic and implies a dispatch of the transaction's call using the -/// inherited origin (either `None` or `Signed`, depending on whether this is a signed or general -/// transaction). -/// -/// Transaction extensions are capable of altering certain associated semantics: -/// -/// - They may define the origin with which the transaction's call should be dispatched. -/// - They may define various parameters used by the transction queue to determine under what -/// conditions the transaction should be retained and introduced on-chain. -/// - They may define whether this transaction is acceptable for introduction on-chain at all. -/// -/// Each of these semantics are defined by the `validate` function. -/// -/// **NOTE: Transaction extensions cannot under any circumctances alter the call itself.** -/// -/// Transaction extensions are capable of defining logic which is executed additionally to the -/// dispatch of the call: -/// -/// - They may define logic which must be executed prior to the dispatch of the call. -/// - They may also define logic which must be executed after the dispatch of the call. -/// -/// Each of these semantics are defined by the `prepare` and `post_dispatch` functions respectively. -/// -/// Finally, transaction extensions may define additional data to help define the implications of -/// the logic they introduce. This additional data may be explicitly defined by the transaction -/// author (in which case it is included as part of the transaction body), or it may be implicitly -/// defined by the transaction extension based around the on-chain state (which the transaction -/// author is assumed to know). This data may be utilized by the above logic to alter how a node's -/// transaction queue treats this transaction. -/// -/// ## Default implementations -/// -/// Of the 5 functions in this trait, 3 of them must return a value of an associated type on -/// success, and none of these types implement [Default] or anything like it. This means that -/// default implementations cannot be provided for these functions. However, a macro is provided -/// [impl_tx_ext_default](crate::impl_tx_ext_default) which is capable of generating default -/// implementations for each of these 3 functions. If you do not wish to introduce additional logic -/// into the transaction pipeline, then it is recommended that you use this macro to implement these -/// functions. -/// -/// ## Pipelines, Inherited Implications, and Authorized Origins -/// -/// Requiring a single transaction extension to define all of the above semantics would be -/// cumbersome and would lead to a lot of boilerplate. Instead, transaction extensions are -/// aggregated into pipelines, which are tuples of transaction extensions. Each extension in the -/// pipeline is executed in order, and the output of each extension is aggregated and/or relayed as -/// the input to the next extension in the pipeline. -/// -/// This ordered composition happens with all datatypes ([Val](TransactionExtension::Val), -/// [Pre](TransactionExtension::Pre) and [Implicit](TransactionExtensionBase::Implicit)) as well as -/// all functions. There are important consequences stemming from how the composition affects the -/// meaning of the `origin` and `implication` parameters as well as the results. Whereas the -/// [prepare](TransactionExtension::prepare) and -/// [post_dispatch](TransactionExtension::post_dispatch) functions are clear in their meaning, the -/// [validate](TransactionExtension::validate) function is fairly sophisticated and warrants -/// further explanation. -/// -/// Firstly, the `origin` parameter. The `origin` passed into the first item in a pipeline is simply -/// that passed into the tuple itself. It represents an authority who has authorized the implication -/// of the transaction, as of the extension it has been passed into *and any further extensions it -/// may pass though, all the way to, and including, the transaction's dispatch call itself. Each -/// following item in the pipeline is passed the origin which the previous item returned. The origin -/// returned from the final item in the pipeline is the origin which is returned by the tuple -/// itself. -/// -/// This means that if a constituent extension returns a different origin to the one it was called -/// with, then (assuming no other extension changes it further) *this new origin will be used for -/// all extensions following it in the pipeline, and will be returned from the pipeline to be used -/// as the origin for the call's dispatch*. The call itself as well as all these extensions -/// following may each imply consequence for this origin. We call this the *inherited implication*. -/// -/// The *inherited implication* is the cumulated on-chain effects born by whatever origin is -/// returned. It is expressed to the [validate](TransactionExtension::validate) function only as the -/// `implication` argument which implements the [Encode] trait. A transaction extension may define -/// its own implications through its own fields and the -/// [implicit](TransactionExtensionBase::implicit) function. This is only utilized by extensions -/// which preceed it in a pipeline or, if the transaction is an old-school signed trasnaction, the -/// underlying transaction verification logic. -/// -/// **The inherited implication passed as the `implication` parameter to -/// [validate](TransactionExtension::validate) does not include the extension's inner data itself -/// nor does it include the result of the extension's `implicit` function.** If you both provide an -/// implication and rely on the implication, then you need to manually aggregate your extensions -/// implication with the aggregated implication passed in. -pub trait TransactionExtension: TransactionExtensionBase { - /// The type that encodes information that can be passed from validate to prepare. - type Val; - - /// The type that encodes information that can be passed from prepare to post-dispatch. - type Pre; - - /// Validate a transaction for the transaction queue. - /// - /// This function can be called frequently by the transaction queue to obtain transaction - /// validity against current state. It should perform all checks that determine a valid - /// transaction, that can pay for its execution and quickly eliminate ones that are stale or - /// incorrect. - /// - /// Parameters: - /// - `origin`: The origin of the transaction which this extension inherited; coming from an - /// "old-school" *signed transaction*, this will be a system `RawOrigin::Signed` value. If the - /// transaction is a "new-school" *General Transaction*, then this will be a system - /// `RawOrigin::None` value. If this extension is an item in a composite, then it could be - /// anything which was previously returned as an `origin` value in the result of a `validate` - /// call. - /// - `call`: The `Call` wrapped by this extension. - /// - `info`: Information concerning, and inherent to, the transaction's call. - /// - `len`: The total length of the encoded transaction. - /// - `inherited_implication`: The *implication* which this extension inherits. This is a tuple - /// of the transaction's call and some additional opaque-but-encodable data. Coming directly - /// from a transaction, the latter is [()]. However, if this extension is expressed as part of - /// a composite type, then the latter component is equal to any further implications to which - /// the returned `origin` could potentially apply. See Pipelines, Inherited Implications, and - /// Authorized Origins for more information. - /// - `context`: Some opaque mutable context, as yet unused. - /// - /// Returns a [ValidateResult], which is a [Result] whose success type is a tuple of - /// [ValidTransaction] (defining useful metadata for the transaction queue), the [Self::Val] - /// token of this transaction, which gets passed into [prepare](TransactionExtension::prepare), - /// and the origin of the transaction, which gets passed into - /// [prepare](TransactionExtension::prepare) and is ultimately used for dispatch. - fn validate( - &self, - origin: OriginOf, - call: &Call, - info: &DispatchInfoOf, - len: usize, - context: &mut Context, - self_implicit: Self::Implicit, - inherited_implication: &impl Encode, - ) -> ValidateResult; - - /// Do any pre-flight stuff for a transaction after validation. - /// - /// This is for actions which do not happen in the transaction queue but only immediately prior - /// to the point of dispatch on-chain. This should not return an error, since errors should - /// already have been identified during the [validate](TransactionExtension::validate) call. If - /// an error is returned, the transaction will be considered invalid but no state changes will - /// happen and therefore work done in [validate](TransactionExtension::validate) will not be - /// paid for. - /// - /// Unlike `validate`, this function may consume `self`. - /// - /// Parameters: - /// - `val`: `Self::Val` returned by the result of the `validate` call. - /// - `origin`: The origin returned by the result of the `validate` call. - /// - `call`: The `Call` wrapped by this extension. - /// - `info`: Information concerning, and inherent to, the transaction's call. - /// - `len`: The total length of the encoded transaction. - /// - `context`: Some opaque mutable context, as yet unused. - /// - /// Returns a [Self::Pre] value on success, which gets passed into - /// [post_dispatch](TransactionExtension::post_dispatch) and after the call is dispatched. - /// - /// IMPORTANT: **Checks made in validation need not be repeated here.** - fn prepare( - self, - val: Self::Val, - origin: &OriginOf, - call: &Call, - info: &DispatchInfoOf, - len: usize, - context: &Context, - ) -> Result; - - /// Do any post-flight stuff for an extrinsic. - /// - /// `_pre` contains the output of `prepare`. - /// - /// This gets given the `DispatchResult` `_result` from the extrinsic and can, if desired, - /// introduce a `TransactionValidityError`, causing the block to become invalid for including - /// it. - /// - /// Parameters: - /// - `pre`: `Self::Pre` returned by the result of the `prepare` call prior to dispatch. - /// - `info`: Information concerning, and inherent to, the transaction's call. - /// - `post_info`: Information concerning the dispatch of the transaction's call. - /// - `len`: The total length of the encoded transaction. - /// - `result`: The result of the dispatch. - /// - `context`: Some opaque mutable context, as yet unused. - /// - /// WARNING: It is dangerous to return an error here. To do so will fundamentally invalidate the - /// transaction and any block that it is included in, causing the block author to not be - /// compensated for their work in validating the transaction or producing the block so far. It - /// can only be used safely when you *know* that the transaction is one that would only be - /// introduced by the current block author. - fn post_dispatch( - _pre: Self::Pre, - _info: &DispatchInfoOf, - _post_info: &PostDispatchInfoOf, - _len: usize, - _result: &DispatchResult, - _context: &Context, - ) -> Result<(), TransactionValidityError> { - Ok(()) - } - - /// Compatibility function for supporting the `SignedExtension::validate_unsigned` function. - /// - /// DO NOT USE! THIS MAY BE REMOVED AT ANY TIME! - #[deprecated = "Only for compatibility. DO NOT USE."] - fn validate_bare_compat( - _call: &Call, - _info: &DispatchInfoOf, - _len: usize, - ) -> TransactionValidity { - Ok(ValidTransaction::default()) - } - - /// Compatibility function for supporting the `SignedExtension::pre_dispatch_unsigned` function. - /// - /// DO NOT USE! THIS MAY BE REMOVED AT ANY TIME! - #[deprecated = "Only for compatibility. DO NOT USE."] - fn pre_dispatch_bare_compat( - _call: &Call, - _info: &DispatchInfoOf, - _len: usize, - ) -> Result<(), TransactionValidityError> { - Ok(()) - } - - /// Compatibility function for supporting the `SignedExtension::post_dispatch` function where - /// `pre` is `None`. - /// - /// DO NOT USE! THIS MAY BE REMOVED AT ANY TIME! - #[deprecated = "Only for compatibility. DO NOT USE."] - fn post_dispatch_bare_compat( - _info: &DispatchInfoOf, - _post_info: &PostDispatchInfoOf, - _len: usize, - _result: &DispatchResult, - ) -> Result<(), TransactionValidityError> { - Ok(()) - } -} - -/// Implict -#[macro_export] -macro_rules! impl_tx_ext_default { - ($call:ty ; $context:ty ; , $( $rest:tt )*) => { - impl_tx_ext_default!{$call ; $context ; $( $rest )*} - }; - ($call:ty ; $context:ty ; validate $( $rest:tt )*) => { - fn validate( - &self, - origin: $crate::traits::OriginOf<$call>, - _call: &$call, - _info: &$crate::traits::DispatchInfoOf<$call>, - _len: usize, - _context: &mut $context, - _self_implicit: Self::Implicit, - _inherited_implication: &impl $crate::codec::Encode, - ) -> $crate::traits::ValidateResult { - Ok((Default::default(), Default::default(), origin)) - } - impl_tx_ext_default!{$call ; $context ; $( $rest )*} - }; - ($call:ty ; $context:ty ; prepare $( $rest:tt )*) => { - fn prepare( - self, - _val: Self::Val, - _origin: &$crate::traits::OriginOf<$call>, - _call: &$call, - _info: &$crate::traits::DispatchInfoOf<$call>, - _len: usize, - _context: & $context, - ) -> Result { - Ok(Default::default()) - } - impl_tx_ext_default!{$call ; $context ; $( $rest )*} - }; - ($call:ty ; $context:ty ;) => {}; -} - -/// Information about a [`TransactionExtension`] for the runtime metadata. -pub struct TransactionExtensionMetadata { - /// The unique identifier of the [`TransactionExtension`]. - pub identifier: &'static str, - /// The type of the [`TransactionExtension`]. - pub ty: MetaType, - /// The type of the [`TransactionExtension`] additional signed data for the payload. - // TODO: Rename "implicit" - pub additional_signed: MetaType, -} - -#[impl_for_tuples(1, 12)] -impl TransactionExtensionBase for Tuple { - for_tuples!( where #( Tuple: TransactionExtensionBase )* ); - const IDENTIFIER: &'static str = "Use `metadata()`!"; - for_tuples!( type Implicit = ( #( Tuple::Implicit ),* ); ); - fn implicit(&self) -> Result { - Ok(for_tuples!( ( #( Tuple.implicit()? ),* ) )) - } - fn weight(&self) -> Weight { - let mut weight = Weight::zero(); - for_tuples!( #( weight += Tuple.weight(); )* ); - weight - } - fn metadata() -> Vec { - let mut ids = Vec::new(); - for_tuples!( #( ids.extend(Tuple::metadata()); )* ); - ids - } -} - -#[impl_for_tuples(1, 12)] -impl TransactionExtension for Tuple { - for_tuples!( where #( Tuple: TransactionExtension )* ); - for_tuples!( type Val = ( #( Tuple::Val ),* ); ); - for_tuples!( type Pre = ( #( Tuple::Pre ),* ); ); - - fn validate( - &self, - origin: ::RuntimeOrigin, - call: &Call, - info: &DispatchInfoOf, - len: usize, - context: &mut Context, - self_implicit: Self::Implicit, - inherited_implication: &impl Encode, - ) -> Result< - (ValidTransaction, Self::Val, ::RuntimeOrigin), - TransactionValidityError, - > { - let valid = ValidTransaction::default(); - let val = (); - let following_explicit_implications = for_tuples!( ( #( &self.Tuple ),* ) ); - let following_implicit_implications = self_implicit; - - for_tuples!(#( - // Implication of this pipeline element not relevant for later items, so we pop it. - let (_item, following_explicit_implications) = following_explicit_implications.pop_front(); - let (item_implicit, following_implicit_implications) = following_implicit_implications.pop_front(); - let (item_valid, item_val, origin) = { - let implications = ( - // The first is the implications born of the fact we return the mutated - // origin. - inherited_implication, - // This is the explicitly made implication born of the fact the new origin is - // passed into the next items in this pipeline-tuple. - &following_explicit_implications, - // This is the implicitly made implication born of the fact the new origin is - // passed into the next items in this pipeline-tuple. - &following_implicit_implications, - ); - Tuple.validate(origin, call, info, len, context, item_implicit, &implications)? - }; - let valid = valid.combine_with(item_valid); - let val = val.push_back(item_val); - )* ); - Ok((valid, val, origin)) - } - - fn prepare( - self, - val: Self::Val, - origin: &::RuntimeOrigin, - call: &Call, - info: &DispatchInfoOf, - len: usize, - context: &Context, - ) -> Result { - Ok(for_tuples!( ( #( - Tuple::prepare(self.Tuple, val.Tuple, origin, call, info, len, context)? - ),* ) )) - } - - fn post_dispatch( - pre: Self::Pre, - info: &DispatchInfoOf, - post_info: &PostDispatchInfoOf, - len: usize, - result: &DispatchResult, - context: &Context, - ) -> Result<(), TransactionValidityError> { - for_tuples!( #( Tuple::post_dispatch(pre.Tuple, info, post_info, len, result, context)?; )* ); - Ok(()) - } -} - -impl TransactionExtensionBase for () { - const IDENTIFIER: &'static str = "UnitTransactionExtension"; - type Implicit = (); - fn implicit(&self) -> sp_std::result::Result { - Ok(()) - } - fn weight(&self) -> Weight { - Weight::zero() - } -} - -impl TransactionExtension for () { - type Val = (); - type Pre = (); - fn validate( - &self, - origin: ::RuntimeOrigin, - _call: &Call, - _info: &DispatchInfoOf, - _len: usize, - _context: &mut Context, - _self_implicit: Self::Implicit, - _inherited_implication: &impl Encode, - ) -> Result< - (ValidTransaction, (), ::RuntimeOrigin), - TransactionValidityError, - > { - Ok((ValidTransaction::default(), (), origin)) - } - fn prepare( - self, - _val: (), - _origin: &::RuntimeOrigin, - _call: &Call, - _info: &DispatchInfoOf, - _len: usize, - _context: &Context, - ) -> Result<(), TransactionValidityError> { - Ok(()) - } -} diff --git a/substrate/primitives/runtime/src/transaction_validity.rs b/substrate/primitives/runtime/src/transaction_validity.rs index 24124128083..83694849382 100644 --- a/substrate/primitives/runtime/src/transaction_validity.rs +++ b/substrate/primitives/runtime/src/transaction_validity.rs @@ -82,8 +82,6 @@ pub enum InvalidTransaction { MandatoryValidation, /// The sending address is disabled or known to be invalid. BadSigner, - /// The implicit data was unable to be calculated. - IndeterminateImplicit, } impl InvalidTransaction { @@ -115,8 +113,6 @@ impl From for &'static str { "Transaction dispatch is mandatory; transactions must not be validated.", InvalidTransaction::Custom(_) => "InvalidTransaction custom error", InvalidTransaction::BadSigner => "Invalid signing address", - InvalidTransaction::IndeterminateImplicit => - "The implicit data was unable to be calculated", } } } @@ -342,7 +338,7 @@ pub struct ValidTransactionBuilder { impl ValidTransactionBuilder { /// Set the priority of a transaction. /// - /// Note that the final priority for `FRAME` is combined from all `TransactionExtension`s. + /// Note that the final priority for `FRAME` is combined from all `SignedExtension`s. /// Most likely for unsigned transactions you want the priority to be higher /// than for regular transactions. We recommend exposing a base priority for unsigned /// transactions as a runtime module parameter, so that the runtime can tune inter-module diff --git a/substrate/scripts/run_all_benchmarks.sh b/substrate/scripts/run_all_benchmarks.sh index fe5f89a5b56..6dd7cede319 100755 --- a/substrate/scripts/run_all_benchmarks.sh +++ b/substrate/scripts/run_all_benchmarks.sh @@ -107,19 +107,6 @@ for PALLET in "${PALLETS[@]}"; do FOLDER="$(echo "${PALLET#*_}" | tr '_' '-')"; WEIGHT_FILE="./frame/${FOLDER}/src/weights.rs" - - # Special handling of custom weight paths. - if [ "$PALLET" == "frame_system_extensions" ] || [ "$PALLET" == "frame-system-extensions" ] - then - WEIGHT_FILE="./frame/system/src/extensions/weights.rs" - elif [ "$PALLET" == "pallet_asset_conversion_tx_payment" ] || [ "$PALLET" == "pallet-asset-conversion-tx-payment" ] - then - WEIGHT_FILE="./frame/transaction-payment/asset-conversion-tx-payment/src/weights.rs" - elif [ "$PALLET" == "pallet_asset_tx_payment" ] || [ "$PALLET" == "pallet-asset-tx-payment" ] - then - WEIGHT_FILE="./frame/transaction-payment/asset-tx-payment/src/weights.rs" - fi - echo "[+] Benchmarking $PALLET with weight file $WEIGHT_FILE"; OUTPUT=$( diff --git a/substrate/test-utils/runtime/src/extrinsic.rs b/substrate/test-utils/runtime/src/extrinsic.rs index 7eb1839e97b..05ffb7db5d5 100644 --- a/substrate/test-utils/runtime/src/extrinsic.rs +++ b/substrate/test-utils/runtime/src/extrinsic.rs @@ -25,7 +25,7 @@ use codec::Encode; use frame_system::{CheckNonce, CheckWeight}; use sp_core::crypto::Pair as TraitPair; use sp_keyring::AccountKeyring; -use sp_runtime::{generic::Preamble, transaction_validity::TransactionPriority, Perbill}; +use sp_runtime::{transaction_validity::TransactionPriority, Perbill}; use sp_std::prelude::*; /// Transfer used in test substrate pallet. Extrinsic is created and signed using this data. @@ -66,11 +66,11 @@ impl TryFrom<&Extrinsic> for TransferData { match uxt { Extrinsic { function: RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest, value }), - preamble: Preamble::Signed(from, _, ((CheckNonce(nonce), ..), ..)), + signature: Some((from, _, (CheckNonce(nonce), ..))), } => Ok(TransferData { from: *from, to: *dest, amount: *value, nonce: *nonce }), Extrinsic { function: RuntimeCall::SubstrateTest(PalletCall::bench_call { transfer }), - preamble: Preamble::Bare, + signature: None, } => Ok(transfer.clone()), _ => Err(()), } @@ -190,17 +190,18 @@ impl ExtrinsicBuilder { /// Build `Extrinsic` using embedded parameters pub fn build(self) -> Extrinsic { if let Some(signer) = self.signer { - let tx_ext = ( - (CheckNonce::from(self.nonce.unwrap_or(0)), CheckWeight::new()), + let extra = ( + CheckNonce::from(self.nonce.unwrap_or(0)), + CheckWeight::new(), CheckSubstrateCall {}, ); let raw_payload = - SignedPayload::from_raw(self.function.clone(), tx_ext.clone(), (((), ()), ())); + SignedPayload::from_raw(self.function.clone(), extra.clone(), ((), (), ())); let signature = raw_payload.using_encoded(|e| signer.sign(e)); - Extrinsic::new_signed(self.function, signer.public(), signature, tx_ext) + Extrinsic::new_signed(self.function, signer.public(), signature, extra) } else { - Extrinsic::new_bare(self.function) + Extrinsic::new_unsigned(self.function) } } } diff --git a/substrate/test-utils/runtime/src/lib.rs b/substrate/test-utils/runtime/src/lib.rs index 7ec5f6722c4..63e0aa6e137 100644 --- a/substrate/test-utils/runtime/src/lib.rs +++ b/substrate/test-utils/runtime/src/lib.rs @@ -58,11 +58,9 @@ use sp_api::{decl_runtime_apis, impl_runtime_apis}; pub use sp_core::hash::H256; use sp_inherents::{CheckInherentsResult, InherentData}; use sp_runtime::{ - create_runtime_str, impl_opaque_keys, impl_tx_ext_default, - traits::{BlakeTwo256, Block as BlockT, DispatchInfoOf, Dispatchable, NumberFor, Verify}, - transaction_validity::{ - TransactionSource, TransactionValidity, TransactionValidityError, ValidTransaction, - }, + create_runtime_str, impl_opaque_keys, + traits::{BlakeTwo256, Block as BlockT, DispatchInfoOf, NumberFor, Verify}, + transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError}, ApplyExtrinsicResult, ExtrinsicInclusionMode, Perbill, }; #[cfg(any(feature = "std", test))] @@ -144,14 +142,13 @@ pub type Signature = sr25519::Signature; #[cfg(feature = "std")] pub type Pair = sp_core::sr25519::Pair; -// TODO: Remove after the Checks are migrated to TxExtension. -/// The extension to the basic transaction logic. -pub type TxExtension = ((CheckNonce, CheckWeight), CheckSubstrateCall); +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = (CheckNonce, CheckWeight, CheckSubstrateCall); /// The payload being signed in transactions. -pub type SignedPayload = sp_runtime::generic::SignedPayload; +pub type SignedPayload = sp_runtime::generic::SignedPayload; /// Unchecked extrinsic type as expected by this runtime. pub type Extrinsic = - sp_runtime::generic::UncheckedExtrinsic; + sp_runtime::generic::UncheckedExtrinsic; /// An identifier for an account on this system. pub type AccountId = ::Signer; @@ -246,7 +243,7 @@ impl sp_runtime::traits::Printable for CheckSubstrateCall { } impl sp_runtime::traits::Dispatchable for CheckSubstrateCall { - type RuntimeOrigin = RuntimeOrigin; + type RuntimeOrigin = CheckSubstrateCall; type Config = CheckSubstrateCall; type Info = CheckSubstrateCall; type PostInfo = CheckSubstrateCall; @@ -259,37 +256,42 @@ impl sp_runtime::traits::Dispatchable for CheckSubstrateCall { } } -impl sp_runtime::traits::TransactionExtensionBase for CheckSubstrateCall { - const IDENTIFIER: &'static str = "CheckSubstrateCall"; - type Implicit = (); -} -impl sp_runtime::traits::TransactionExtension - for CheckSubstrateCall -{ +impl sp_runtime::traits::SignedExtension for CheckSubstrateCall { + type AccountId = AccountId; + type Call = RuntimeCall; + type AdditionalSigned = (); type Pre = (); - type Val = (); - impl_tx_ext_default!(RuntimeCall; Context; prepare); + const IDENTIFIER: &'static str = "CheckSubstrateCall"; + + fn additional_signed( + &self, + ) -> sp_std::result::Result { + Ok(()) + } fn validate( &self, - origin: ::RuntimeOrigin, - call: &RuntimeCall, - _info: &DispatchInfoOf, + _who: &Self::AccountId, + call: &Self::Call, + _info: &DispatchInfoOf, _len: usize, - _context: &mut Context, - _self_implicit: Self::Implicit, - _inherited_implication: &impl Encode, - ) -> Result< - (ValidTransaction, Self::Val, ::RuntimeOrigin), - TransactionValidityError, - > { + ) -> TransactionValidity { log::trace!(target: LOG_TARGET, "validate"); - let v = match call { + match call { RuntimeCall::SubstrateTest(ref substrate_test_call) => - substrate_test_pallet::validate_runtime_call(substrate_test_call)?, - _ => Default::default(), - }; - Ok((v, (), origin)) + substrate_test_pallet::validate_runtime_call(substrate_test_call), + _ => Ok(Default::default()), + } + } + + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &sp_runtime::traits::DispatchInfoOf, + len: usize, + ) -> Result { + self.validate(who, call, info, len).map(drop) } } @@ -362,7 +364,6 @@ impl frame_system::pallet::Config for Runtime { type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); - type ExtensionsWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); type MaxConsumers = ConstU32<16>; @@ -671,7 +672,7 @@ impl_runtime_apis! { impl sp_offchain::OffchainWorkerApi for Runtime { fn offchain_worker(header: &::Header) { - let ext = Extrinsic::new_bare( + let ext = Extrinsic::new_unsigned( substrate_test_pallet::pallet::Call::storage_change{ key:b"some_key".encode(), value:Some(header.number.encode()) @@ -1024,7 +1025,7 @@ mod tests { use sp_core::{storage::well_known_keys::HEAP_PAGES, traits::CallContext}; use sp_keyring::AccountKeyring; use sp_runtime::{ - traits::{DispatchTransaction, Hash as _}, + traits::{Hash as _, SignedExtension}, transaction_validity::{InvalidTransaction, ValidTransaction}, }; use substrate_test_runtime_client::{ @@ -1173,33 +1174,31 @@ mod tests { fn check_substrate_check_signed_extension_works() { sp_tracing::try_init_simple(); new_test_ext().execute_with(|| { - let x: AccountId = sp_keyring::AccountKeyring::Alice.into(); + let x = sp_keyring::AccountKeyring::Alice.into(); let info = DispatchInfo::default(); let len = 0_usize; assert_eq!( CheckSubstrateCall {} - .validate_only( - Some(x).into(), + .validate( + &x, &ExtrinsicBuilder::new_call_with_priority(16).build().function, &info, - len, + len ) .unwrap() - .0 .priority, 16 ); assert_eq!( CheckSubstrateCall {} - .validate_only( - Some(x).into(), + .validate( + &x, &ExtrinsicBuilder::new_call_do_not_propagate().build().function, &info, - len, + len ) .unwrap() - .0 .propagate, false ); diff --git a/substrate/utils/frame/benchmarking-cli/src/pallet/template.hbs b/substrate/utils/frame/benchmarking-cli/src/pallet/template.hbs index a044049a0d6..1e5e294acba 100644 --- a/substrate/utils/frame/benchmarking-cli/src/pallet/template.hbs +++ b/substrate/utils/frame/benchmarking-cli/src/pallet/template.hbs @@ -22,11 +22,7 @@ use core::marker::PhantomData; /// Weight functions for `{{pallet}}`. pub struct WeightInfo(PhantomData); -{{#if (eq pallet "frame_system_extensions")}} -impl frame_system::ExtensionsWeightInfo for WeightInfo { -{{else}} impl {{pallet}}::WeightInfo for WeightInfo { -{{/if}} {{#each benchmarks as |benchmark|}} {{#each benchmark.comments as |comment|}} /// {{comment}} diff --git a/substrate/utils/frame/remote-externalities/src/lib.rs b/substrate/utils/frame/remote-externalities/src/lib.rs index d49479d9cda..c7399468da9 100644 --- a/substrate/utils/frame/remote-externalities/src/lib.rs +++ b/substrate/utils/frame/remote-externalities/src/lib.rs @@ -1204,9 +1204,8 @@ where #[cfg(test)] mod test_prelude { pub(crate) use super::*; - pub(crate) use sp_runtime::testing::{Block as RawBlock, MockCallU64}; - pub(crate) type UncheckedXt = sp_runtime::generic::UncheckedExtrinsic; - pub(crate) type Block = RawBlock; + pub(crate) use sp_runtime::testing::{Block as RawBlock, ExtrinsicWrapper, H256 as Hash}; + pub(crate) type Block = RawBlock>; pub(crate) fn init_logger() { sp_tracing::try_init_simple(); diff --git a/substrate/utils/frame/rpc/client/src/lib.rs b/substrate/utils/frame/rpc/client/src/lib.rs index 4f4f4bbef56..221f260b156 100644 --- a/substrate/utils/frame/rpc/client/src/lib.rs +++ b/substrate/utils/frame/rpc/client/src/lib.rs @@ -199,15 +199,11 @@ where #[cfg(test)] mod tests { use super::*; - use sp_runtime::{ - generic::UncheckedExtrinsic, - testing::{Block as TBlock, Header, MockCallU64, H256}, - }; + use sp_runtime::testing::{Block as TBlock, ExtrinsicWrapper, Header, H256}; use std::sync::Arc; use tokio::sync::Mutex; - type UncheckedXt = UncheckedExtrinsic; - type Block = TBlock; + type Block = TBlock>; type BlockNumber = u64; type Hash = H256; diff --git a/templates/minimal/runtime/src/lib.rs b/templates/minimal/runtime/src/lib.rs index 6920511e276..91859cf4a2f 100644 --- a/templates/minimal/runtime/src/lib.rs +++ b/templates/minimal/runtime/src/lib.rs @@ -54,7 +54,7 @@ pub fn native_version() -> NativeVersion { NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } } -type TxExtension = ( +type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -111,7 +111,7 @@ impl pallet_transaction_payment::Config for Runtime { impl pallet_minimal_template::Config for Runtime {} -type Block = frame::runtime::types_common::BlockOf; +type Block = frame::runtime::types_common::BlockOf; type Header = HeaderFor; type RuntimeExecutive = diff --git a/templates/parachain/runtime/Cargo.toml b/templates/parachain/runtime/Cargo.toml index 44e9341b568..9d9da2b4b97 100644 --- a/templates/parachain/runtime/Cargo.toml +++ b/templates/parachain/runtime/Cargo.toml @@ -149,7 +149,6 @@ runtime-benchmarks = [ "cumulus-pallet-session-benchmarking/runtime-benchmarks", "cumulus-pallet-xcmp-queue/runtime-benchmarks", "cumulus-primitives-core/runtime-benchmarks", - "cumulus-primitives-storage-weight-reclaim/runtime-benchmarks", "cumulus-primitives-utility/runtime-benchmarks", "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", @@ -162,7 +161,6 @@ runtime-benchmarks = [ "pallet-parachain-template/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "parachains-common/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", diff --git a/templates/parachain/runtime/src/lib.rs b/templates/parachain/runtime/src/lib.rs index 74ecd751f67..89899d286bb 100644 --- a/templates/parachain/runtime/src/lib.rs +++ b/templates/parachain/runtime/src/lib.rs @@ -97,8 +97,8 @@ pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; -/// The extension to the basic transaction logic. -pub type TxExtension = ( +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -112,7 +112,7 @@ pub type TxExtension = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< @@ -353,7 +353,6 @@ impl pallet_transaction_payment::Config for Runtime { type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; type OperationalFeeMultiplier = ConstU8<5>; - type WeightInfo = (); } impl pallet_sudo::Config for Runtime { @@ -531,7 +530,6 @@ construct_runtime!( mod benches { frame_benchmarking::define_benchmarks!( [frame_system, SystemBench::] - [frame_system_extensions, SystemExtensionsBench::] [pallet_balances, Balances] [pallet_session, SessionBench::] [pallet_timestamp, Timestamp] @@ -715,7 +713,6 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; let mut list = Vec::::new(); @@ -731,7 +728,6 @@ impl_runtime_apis! { use frame_benchmarking::{BenchmarkError, Benchmarking, BenchmarkBatch}; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; impl frame_system_benchmarking::Config for Runtime { fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); diff --git a/templates/solochain/node/Cargo.toml b/templates/solochain/node/Cargo.toml index 5e50e6106c1..48bb511bfd1 100644 --- a/templates/solochain/node/Cargo.toml +++ b/templates/solochain/node/Cargo.toml @@ -76,7 +76,6 @@ default = [] runtime-benchmarks = [ "frame-benchmarking-cli/runtime-benchmarks", "frame-system/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "sc-service/runtime-benchmarks", "solochain-template-runtime/runtime-benchmarks", "sp-runtime/runtime-benchmarks", diff --git a/templates/solochain/node/src/benchmarking.rs b/templates/solochain/node/src/benchmarking.rs index 8710f303e1f..d1d8c2ccaba 100644 --- a/templates/solochain/node/src/benchmarking.rs +++ b/templates/solochain/node/src/benchmarking.rs @@ -109,7 +109,7 @@ pub fn create_benchmark_extrinsic( .checked_next_power_of_two() .map(|c| c / 2) .unwrap_or(2) as u64; - let tx_ext: runtime::TxExtension = ( + let extra: runtime::SignedExtra = ( frame_system::CheckNonZeroSender::::new(), frame_system::CheckSpecVersion::::new(), frame_system::CheckTxVersion::::new(), @@ -121,12 +121,11 @@ pub fn create_benchmark_extrinsic( frame_system::CheckNonce::::from(nonce), frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(0), - ) - .into(); + ); let raw_payload = runtime::SignedPayload::from_raw( call.clone(), - tx_ext.clone(), + extra.clone(), ( (), runtime::VERSION.spec_version, @@ -144,7 +143,7 @@ pub fn create_benchmark_extrinsic( call, sp_runtime::AccountId32::from(sender.public()).into(), runtime::Signature::Sr25519(signature), - tx_ext, + extra, ) } diff --git a/templates/solochain/runtime/Cargo.toml b/templates/solochain/runtime/Cargo.toml index 706ea863d0f..a7fc0519ba2 100644 --- a/templates/solochain/runtime/Cargo.toml +++ b/templates/solochain/runtime/Cargo.toml @@ -130,7 +130,6 @@ runtime-benchmarks = [ "pallet-sudo/runtime-benchmarks", "pallet-template/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", - "pallet-transaction-payment/runtime-benchmarks", "sp-runtime/runtime-benchmarks", ] diff --git a/templates/solochain/runtime/src/lib.rs b/templates/solochain/runtime/src/lib.rs index 303122da564..a8a5b7857e1 100644 --- a/templates/solochain/runtime/src/lib.rs +++ b/templates/solochain/runtime/src/lib.rs @@ -237,7 +237,6 @@ impl pallet_transaction_payment::Config for Runtime { type WeightToFee = IdentityFee; type LengthToFee = IdentityFee; type FeeMultiplierUpdate = ConstFeeMultiplier; - type WeightInfo = pallet_transaction_payment::weights::SubstrateWeight; } impl pallet_sudo::Config for Runtime { @@ -301,8 +300,8 @@ pub type Address = sp_runtime::MultiAddress; pub type Header = generic::Header; /// Block type as expected by this runtime. pub type Block = generic::Block; -/// The extension to the basic transaction logic. -pub type TxExtension = ( +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -321,9 +320,9 @@ type Migrations = (); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; /// The payload being signed in transactions. -pub type SignedPayload = generic::SignedPayload; +pub type SignedPayload = generic::SignedPayload; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, @@ -339,7 +338,6 @@ mod benches { frame_benchmarking::define_benchmarks!( [frame_benchmarking, BaselineBench::] [frame_system, SystemBench::] - [frame_system_extensions, SystemExtensionsBench::] [pallet_balances, Balances] [pallet_timestamp, Timestamp] [pallet_sudo, Sudo] @@ -524,7 +522,6 @@ impl_runtime_apis! { use frame_benchmarking::{baseline, Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use baseline::Pallet as BaselineBench; let mut list = Vec::::new(); @@ -541,7 +538,6 @@ impl_runtime_apis! { use frame_benchmarking::{baseline, Benchmarking, BenchmarkBatch}; use sp_storage::TrackedStorageKey; use frame_system_benchmarking::Pallet as SystemBench; - use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; use baseline::Pallet as BaselineBench; impl frame_system_benchmarking::Config for Runtime {} -- GitLab